aboutsummaryrefslogtreecommitdiff
path: root/thirdparty/nRF5_SDK_15.0.0_a53641a/components
diff options
context:
space:
mode:
Diffstat (limited to 'thirdparty/nRF5_SDK_15.0.0_a53641a/components')
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/802_15_4/api/HAL/hal_atomic.h82
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/802_15_4/api/HAL/hal_clock.h59
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/802_15_4/api/HAL/hal_debug_interface.h113
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/802_15_4/api/HAL/hal_delay.h65
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/802_15_4/api/HAL/hal_led.h54
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/802_15_4/api/HAL/hal_mutex.h89
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/802_15_4/api/HAL/hal_rng.h70
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/802_15_4/api/HAL/hal_sleep.h100
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/802_15_4/api/HAL/hal_task_scheduler.h124
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/802_15_4/api/HAL/hal_timer.h80
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/802_15_4/api/HAL/hal_timer_critical.h82
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/802_15_4/api/HAL/hal_trace_interface.h103
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/802_15_4/api/HAL/hal_uart.h284
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/802_15_4/api/HAL/hal_uart_task_scheduler.h105
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/802_15_4/api/HAL/nrf52_soc/hal_nrf52_exceptions.h90
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/802_15_4/api/HAL/nrf52_soc/hal_nrf52_rtc.h107
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/802_15_4/api/HAL/nrf52_soc/hal_nrf52_timer.h75
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/802_15_4/api/MAC/mac_auto_request.h61
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/802_15_4/api/MAC/mac_common.h467
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/802_15_4/api/MAC/mac_mcps_data.h333
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/802_15_4/api/MAC/mac_mcps_purge.h152
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/802_15_4/api/MAC/mac_mlme_associate.h336
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/802_15_4/api/MAC/mac_mlme_beacon_notify.h175
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/802_15_4/api/MAC/mac_mlme_comm_status.h135
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/802_15_4/api/MAC/mac_mlme_disassociate.h199
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/802_15_4/api/MAC/mac_mlme_gts.h211
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/802_15_4/api/MAC/mac_mlme_orphan.h151
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/802_15_4/api/MAC/mac_mlme_pib.h508
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/802_15_4/api/MAC/mac_mlme_poll.h151
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/802_15_4/api/MAC/mac_mlme_reset.h125
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/802_15_4/api/MAC/mac_mlme_rx_enable.h181
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/802_15_4/api/MAC/mac_mlme_scan.h160
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/802_15_4/api/MAC/mac_mlme_start.h150
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/802_15_4/api/MAC/mac_mlme_sync.h153
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/802_15_4/api/MAC/mac_panid_conflict.h82
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/802_15_4/api/MAC/mac_security.h318
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/802_15_4/api/MAC/mac_task_scheduler.h205
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/802_15_4/api/MAC/mac_time.h151
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/802_15_4/api/PHY/phy_common.h240
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/802_15_4/api/PHY/phy_pd_data.h187
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/802_15_4/api/PHY/phy_plme_cca.h106
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/802_15_4/api/PHY/phy_plme_ed.h110
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/802_15_4/api/PHY/phy_plme_pib.h212
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/802_15_4/api/PHY/phy_plme_trx.h135
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/802_15_4/api/RAL/nrf52_soc/ral_api_spec.h99
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/802_15_4/api/RAL/nrf52_soc/ral_fsm.h96
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/802_15_4/api/RAL/nrf52_soc/ral_fsm_private.h88
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/802_15_4/api/RAL/nrf52_soc/ral_irq_handlers.h65
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/802_15_4/api/RAL/nrf52_soc/ral_rf_init.h69
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/802_15_4/api/RAL/ral_api.h220
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/802_15_4/api/SecAL/sec_aes_ccm.h128
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/802_15_4/api/SecAL/sec_aes_entity.h75
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/802_15_4/api/SysAL/sys_crc.h95
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/802_15_4/api/SysAL/sys_debug.h177
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/802_15_4/api/SysAL/sys_events.h167
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/802_15_4/api/SysAL/sys_fsm.h286
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/802_15_4/api/SysAL/sys_init.h69
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/802_15_4/api/SysAL/sys_list.h248
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/802_15_4/api/SysAL/sys_memory_manager.h92
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/802_15_4/api/SysAL/sys_queue.h290
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/802_15_4/api/SysAL/sys_ringbuffer.h202
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/802_15_4/api/SysAL/sys_slab_allocator.h142
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/802_15_4/api/SysAL/sys_sleep.h155
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/802_15_4/api/SysAL/sys_task_scheduler.h121
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/802_15_4/api/SysAL/sys_time.h180
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/802_15_4/api/SysAL/sys_utils.h541
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/802_15_4/raw/802_15_4_config.h110
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/802_15_4/raw/802_15_4_lib_gcc.abin0 -> 2739244 bytes
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/802_15_4/raw/802_15_4_lib_iar.abin0 -> 3316374 bytes
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/802_15_4/raw/802_15_4_lib_keil.libbin0 -> 69011614 bytes
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/802_15_4/raw/license.txt38
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/802_15_4/secure/802_15_4_config.h111
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/802_15_4/secure/802_15_4_lib_gcc.abin0 -> 2950398 bytes
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/802_15_4/secure/802_15_4_lib_iar.abin0 -> 3471180 bytes
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/802_15_4/secure/802_15_4_lib_keil.libbin0 -> 70209978 bytes
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/802_15_4/secure/license.txt38
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/802_15_4/src/rng_entity.c66
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/802_15_4/src/sec_aes_entity.c62
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/ant/ant_channel_config/ant_channel_config.c86
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/ant/ant_channel_config/ant_channel_config.h98
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/ant/ant_encryption/ant_encrypt_config.c245
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/ant/ant_encryption/ant_encrypt_config.h241
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/ant/ant_encryption/ant_encrypt_negotiation_slave.c185
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/ant/ant_encryption/ant_encrypt_negotiation_slave.h140
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/ant/ant_fs/antfs.c2379
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/ant/ant_fs/antfs.h396
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/ant/ant_fs/crc.c98
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/ant/ant_fs/crc.h94
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/ant/ant_fs/defines.h109
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/ant/ant_key_manager/ant_key_manager.c67
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/ant/ant_key_manager/ant_key_manager.h104
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/ant/ant_key_manager/config/ant_key_manager_config.h69
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/ant/ant_profiles/ant_bpwr/ant_bpwr.c490
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/ant/ant_profiles/ant_bpwr/ant_bpwr.h377
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/ant/ant_profiles/ant_bpwr/ant_bpwr_local.h89
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/ant/ant_profiles/ant_bpwr/pages/ant_bpwr_common_data.c99
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/ant/ant_profiles/ant_bpwr/pages/ant_bpwr_common_data.h99
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/ant/ant_profiles/ant_bpwr/pages/ant_bpwr_page_1.c286
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/ant/ant_profiles/ant_bpwr/pages/ant_bpwr_page_1.h136
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/ant/ant_profiles/ant_bpwr/pages/ant_bpwr_page_16.c117
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/ant/ant_profiles/ant_bpwr/pages/ant_bpwr_page_16.h111
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/ant/ant_profiles/ant_bpwr/pages/ant_bpwr_page_17.c77
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/ant/ant_profiles/ant_bpwr/pages/ant_bpwr_page_17.h89
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/ant/ant_profiles/ant_bpwr/pages/ant_bpwr_page_18.c77
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/ant/ant_profiles/ant_bpwr/pages/ant_bpwr_page_18.h89
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/ant/ant_profiles/ant_bpwr/pages/ant_bpwr_page_torque.c113
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/ant/ant_profiles/ant_bpwr/pages/ant_bpwr_page_torque.h106
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/ant/ant_profiles/ant_bpwr/pages/ant_bpwr_pages.h69
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/ant/ant_profiles/ant_bpwr/simulator/ant_bpwr_simulator.c201
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/ant/ant_profiles/ant_bpwr/simulator/ant_bpwr_simulator.h123
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/ant/ant_profiles/ant_bpwr/simulator/ant_bpwr_simulator_local.h74
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/ant/ant_profiles/ant_bpwr/utils/ant_bpwr_utils.h86
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/ant/ant_profiles/ant_bsc/ant_bsc.c422
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/ant/ant_profiles/ant_bsc/ant_bsc.h359
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/ant/ant_profiles/ant_bsc/ant_bsc_local.h83
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/ant/ant_profiles/ant_bsc/pages/ant_bsc_combined_page_0.c129
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/ant/ant_profiles/ant_bsc/pages/ant_bsc_combined_page_0.h99
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/ant/ant_profiles/ant_bsc/pages/ant_bsc_page_0.c111
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/ant/ant_profiles/ant_bsc/pages/ant_bsc_page_0.h95
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/ant/ant_profiles/ant_bsc/pages/ant_bsc_page_1.c94
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/ant/ant_profiles/ant_bsc/pages/ant_bsc_page_1.h93
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/ant/ant_profiles/ant_bsc/pages/ant_bsc_page_2.c96
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/ant/ant_profiles/ant_bsc/pages/ant_bsc_page_2.h95
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/ant/ant_profiles/ant_bsc/pages/ant_bsc_page_3.c94
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/ant/ant_profiles/ant_bsc/pages/ant_bsc_page_3.h97
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/ant/ant_profiles/ant_bsc/pages/ant_bsc_page_4.c104
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/ant/ant_profiles/ant_bsc/pages/ant_bsc_page_4.h113
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/ant/ant_profiles/ant_bsc/pages/ant_bsc_page_5.c97
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/ant/ant_profiles/ant_bsc/pages/ant_bsc_page_5.h95
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/ant/ant_profiles/ant_bsc/pages/ant_bsc_pages.h69
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/ant/ant_profiles/ant_bsc/simulator/ant_bsc_simulator.c280
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/ant/ant_profiles/ant_bsc/simulator/ant_bsc_simulator.h120
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/ant/ant_profiles/ant_bsc/simulator/ant_bsc_simulator_local.h79
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/ant/ant_profiles/ant_bsc/utils/ant_bsc_utils.h128
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/ant/ant_profiles/ant_common/ant_request_controller/ant_request_controller.c224
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/ant/ant_profiles/ant_common/ant_request_controller/ant_request_controller.h157
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/ant/ant_profiles/ant_common/pages/ant_common_page_70.c141
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/ant/ant_profiles/ant_common/pages/ant_common_page_70.h135
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/ant/ant_profiles/ant_common/pages/ant_common_page_80.c110
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/ant/ant_profiles/ant_common/pages/ant_common_page_80.h120
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/ant/ant_profiles/ant_common/pages/ant_common_page_81.c117
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/ant/ant_profiles/ant_common/pages/ant_common_page_81.h111
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/ant/ant_profiles/ant_hrm/ant_hrm.c346
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/ant/ant_profiles/ant_hrm/ant_hrm.h292
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/ant/ant_profiles/ant_hrm/ant_hrm_local.h75
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/ant/ant_profiles/ant_hrm/pages/ant_hrm_page_0.c116
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/ant/ant_profiles/ant_hrm/pages/ant_hrm_page_0.h99
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/ant/ant_profiles/ant_hrm/pages/ant_hrm_page_1.c102
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/ant/ant_profiles/ant_hrm/pages/ant_hrm_page_1.h95
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/ant/ant_profiles/ant_hrm/pages/ant_hrm_page_2.c106
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/ant/ant_profiles/ant_hrm/pages/ant_hrm_page_2.h97
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/ant/ant_profiles/ant_hrm/pages/ant_hrm_page_3.c103
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/ant/ant_profiles/ant_hrm/pages/ant_hrm_page_3.h99
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/ant/ant_profiles/ant_hrm/pages/ant_hrm_page_4.c107
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/ant/ant_profiles/ant_hrm/pages/ant_hrm_page_4.h97
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/ant/ant_profiles/ant_hrm/pages/ant_hrm_pages.h67
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/ant/ant_profiles/ant_hrm/simulator/ant_hrm_simulator.c148
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/ant/ant_profiles/ant_hrm/simulator/ant_hrm_simulator.h130
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/ant/ant_profiles/ant_hrm/simulator/ant_hrm_simulator_local.h69
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/ant/ant_profiles/ant_hrm/utils/ant_hrm_utils.h111
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/ant/ant_profiles/ant_sdm/ant_sdm.c409
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/ant/ant_profiles/ant_sdm/ant_sdm.h331
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/ant/ant_profiles/ant_sdm/ant_sdm_local.h81
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/ant/ant_profiles/ant_sdm/pages/ant_sdm_common_data.c104
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/ant/ant_profiles/ant_sdm/pages/ant_sdm_common_data.h103
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/ant/ant_profiles/ant_sdm/pages/ant_sdm_page_1.c144
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/ant/ant_profiles/ant_sdm/pages/ant_sdm_page_1.h101
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/ant/ant_profiles/ant_sdm/pages/ant_sdm_page_16.c104
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/ant/ant_profiles/ant_sdm/pages/ant_sdm_page_16.h79
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/ant/ant_profiles/ant_sdm/pages/ant_sdm_page_2.c128
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/ant/ant_profiles/ant_sdm/pages/ant_sdm_page_2.h129
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/ant/ant_profiles/ant_sdm/pages/ant_sdm_page_22.c127
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/ant/ant_profiles/ant_sdm/pages/ant_sdm_page_22.h106
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/ant/ant_profiles/ant_sdm/pages/ant_sdm_page_3.c92
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/ant/ant_profiles/ant_sdm/pages/ant_sdm_page_3.h93
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/ant/ant_profiles/ant_sdm/pages/ant_sdm_pages.h70
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/ant/ant_profiles/ant_sdm/simulator/ant_sdm_simulator.c159
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/ant/ant_profiles/ant_sdm/simulator/ant_sdm_simulator.h139
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/ant/ant_profiles/ant_sdm/simulator/ant_sdm_simulator_local.h71
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/ant/ant_profiles/ant_sdm/utils/ant_sdm_utils.h112
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/ant/ant_search_config/ant_search_config.c77
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/ant/ant_search_config/ant_search_config.h129
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/ant/ant_state_indicator/ant_state_indicator.c145
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/ant/ant_state_indicator/ant_state_indicator.h95
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_advertising/ble_advertising.c790
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_advertising/ble_advertising.h337
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_db_discovery/ble_db_discovery.c986
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_db_discovery/ble_db_discovery.h235
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_dtm/ble_dtm.c957
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_dtm/ble_dtm.h237
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_dtm/ble_dtm_hw.h103
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_dtm/ble_dtm_hw_nrf51.c120
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_dtm/ble_dtm_hw_nrf52.c128
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_lesc/ble_lesc.c443
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_lesc/ble_lesc.h128
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_link_ctx_manager/ble_link_ctx_manager.c79
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_link_ctx_manager/ble_link_ctx_manager.h127
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_racp/ble_racp.c87
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_racp/ble_racp.h136
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_radio_notification/ble_radio_notification.c87
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_radio_notification/ble_radio_notification.h82
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/ble_ancs_c/ancs_app_attr_get.c367
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/ble_ancs_c/ancs_app_attr_get.h66
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/ble_ancs_c/ancs_attr_parser.c392
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/ble_ancs_c/ancs_attr_parser.h77
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/ble_ancs_c/ancs_tx_buffer.c113
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/ble_ancs_c/ancs_tx_buffer.h103
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/ble_ancs_c/nrf_ble_ancs_c.c652
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/ble_ancs_c/nrf_ble_ancs_c.h604
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/ble_ans_c/ble_ans_c.c575
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/ble_ans_c/ble_ans_c.h409
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/ble_bas/ble_bas.c384
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/ble_bas/ble_bas.h194
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/ble_bas_c/ble_bas_c.c405
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/ble_bas_c/ble_bas_c.h274
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/ble_bps/ble_bps.c475
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/ble_bps/ble_bps.h221
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/ble_cscs/ble_cscs.c489
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/ble_cscs/ble_cscs.h218
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/ble_cscs/ble_sc_ctrlpt.c686
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/ble_cscs/ble_sc_ctrlpt.h247
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/ble_cts_c/ble_cts_c.c357
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/ble_cts_c/ble_cts_c.h284
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/ble_dfu/ble_dfu.c337
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/ble_dfu/ble_dfu.h251
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/ble_dfu/ble_dfu_bonded.c407
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/ble_dfu/ble_dfu_unbonded.c325
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/ble_dis/ble_dis.c304
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/ble_dis/ble_dis.h134
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/ble_dis_c/ble_dis_c.c557
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/ble_dis_c/ble_dis_c.h308
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/ble_escs/escs_defs.h133
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/ble_escs/nrf_ble_escs.c675
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/ble_escs/nrf_ble_escs.h259
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/ble_gls/ble_gls.c1314
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/ble_gls/ble_gls.h323
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/ble_gls/ble_gls_db.c143
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/ble_gls/ble_gls_db.h121
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/ble_hids/ble_hids.c1794
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/ble_hids/ble_hids.h430
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/ble_hrs/ble_hrs.c479
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/ble_hrs/ble_hrs.h266
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/ble_hrs_c/ble_hrs_c.c384
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/ble_hrs_c/ble_hrs_c.h295
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/ble_hts/ble_hts.c462
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/ble_hts/ble_hts.h219
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/ble_ias/ble_ias.c242
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/ble_ias/ble_ias.h194
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/ble_ias_c/ble_ias_c.c214
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/ble_ias_c/ble_ias_c.h237
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/ble_ipsp/ble_ipsp.c981
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/ble_ipsp/ble_ipsp.h253
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/ble_lbs/ble_lbs.c235
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/ble_lbs/ble_lbs.h161
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/ble_lbs_c/ble_lbs_c.c394
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/ble_lbs_c/ble_lbs_c.h254
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/ble_lls/ble_lls.c260
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/ble_lls/ble_lls.h175
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/ble_nus/ble_nus.c440
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/ble_nus/ble_nus.h244
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/ble_nus_c/ble_nus_c.c265
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/ble_nus_c/ble_nus_c.h272
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/ble_rscs/ble_rscs.c417
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/ble_rscs/ble_rscs.h201
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/ble_rscs_c/ble_rscs_c.c390
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/ble_rscs_c/ble_rscs_c.h231
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/ble_tps/ble_tps.c170
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/ble_tps/ble_tps.h138
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/eddystone/es.h198
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/eddystone/es_adv.c342
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/eddystone/es_adv.h129
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/eddystone/es_adv_frame.c120
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/eddystone/es_adv_frame.h73
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/eddystone/es_adv_timing.c220
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/eddystone/es_adv_timing.h97
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/eddystone/es_adv_timing_resolver.c145
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/eddystone/es_adv_timing_resolver.h96
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/eddystone/es_battery_voltage.h66
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/eddystone/es_battery_voltage_saadc.c104
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/eddystone/es_flash.c340
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/eddystone/es_flash.h177
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/eddystone/es_gatts.c188
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/eddystone/es_gatts.h109
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/eddystone/es_gatts_read.c246
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/eddystone/es_gatts_read.h73
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/eddystone/es_gatts_write.c254
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/eddystone/es_gatts_write.h71
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/eddystone/es_security.c596
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/eddystone/es_security.h238
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/eddystone/es_slot.c440
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/eddystone/es_slot.h202
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/eddystone/es_slot_reg.c181
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/eddystone/es_slot_reg.h90
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/eddystone/es_stopwatch.c106
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/eddystone/es_stopwatch.h71
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/eddystone/es_tlm.c140
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/eddystone/es_tlm.h76
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/eddystone/es_util.h137
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/eddystone/nrf_ble_es.c438
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/eddystone/nrf_ble_es.h99
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/experimental_ble_lns/ble_ln_common.h94
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/experimental_ble_lns/ble_ln_cp.c821
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/experimental_ble_lns/ble_ln_cp.h255
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/experimental_ble_lns/ble_ln_db.c151
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/experimental_ble_lns/ble_ln_db.h122
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/experimental_ble_lns/ble_lns.c1014
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/experimental_ble_lns/ble_lns.h381
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/experimental_ble_ots/ble_hvx_buffering.c102
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/experimental_ble_ots/ble_hvx_buffering.h104
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/experimental_ble_ots/ble_ots.c249
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/experimental_ble_ots/ble_ots.h472
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/experimental_ble_ots/ble_ots_l2cap.c437
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/experimental_ble_ots/ble_ots_l2cap.h117
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/experimental_ble_ots/ble_ots_oacp.c606
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/experimental_ble_ots/ble_ots_oacp.h90
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/experimental_ble_ots/ble_ots_object.c577
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/experimental_ble_ots/ble_ots_object.h86
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/experimental_gatts_c/nrf_ble_gatts_c.c276
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/experimental_gatts_c/nrf_ble_gatts_c.h229
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/experimental_nrf_ble_cgms/cgms_db.c143
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/experimental_nrf_ble_cgms/cgms_db.h118
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/experimental_nrf_ble_cgms/cgms_meas.c248
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/experimental_nrf_ble_cgms/cgms_meas.h103
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/experimental_nrf_ble_cgms/cgms_racp.c866
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/experimental_nrf_ble_cgms/cgms_racp.h99
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/experimental_nrf_ble_cgms/cgms_socp.c431
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/experimental_nrf_ble_cgms/cgms_socp.h107
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/experimental_nrf_ble_cgms/cgms_sst.c235
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/experimental_nrf_ble_cgms/cgms_sst.h115
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/experimental_nrf_ble_cgms/nrf_ble_cgms.c504
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/experimental_nrf_ble_cgms/nrf_ble_cgms.h453
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/experimental_nrf_ble_ots_c/nrf_ble_ots_c.c374
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/experimental_nrf_ble_ots_c/nrf_ble_ots_c.h320
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/experimental_nrf_ble_ots_c/nrf_ble_ots_c_l2cap.c244
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/experimental_nrf_ble_ots_c/nrf_ble_ots_c_l2cap.h101
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/experimental_nrf_ble_ots_c/nrf_ble_ots_c_oacp.c253
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/experimental_nrf_ble_ots_c/nrf_ble_ots_c_oacp.h126
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/experimental_nrf_ble_ots_c/ots_tx_buffer.c113
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/experimental_nrf_ble_ots_c/ots_tx_buffer.h103
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/nrf_ble_bms/nrf_ble_bms.c622
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/nrf_ble_bms/nrf_ble_bms.h316
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/common/ble_advdata.c827
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/common/ble_advdata.h326
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/common/ble_conn_params.c572
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/common/ble_conn_params.h156
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/common/ble_conn_state.c481
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/common/ble_conn_state.h345
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/common/ble_date_time.h113
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/common/ble_gatt_db.h92
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/common/ble_sensor_location.h76
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/common/ble_srv_common.c237
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/common/ble_srv_common.h409
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/nrf_ble_gatt/nrf_ble_gatt.c550
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/nrf_ble_gatt/nrf_ble_gatt.h242
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/nrf_ble_qwr/nrf_ble_qwr.c488
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/nrf_ble_qwr/nrf_ble_qwr.h246
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/peer_manager/gatt_cache_manager.c578
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/peer_manager/gatt_cache_manager.h113
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/peer_manager/gatts_cache_manager.c347
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/peer_manager/gatts_cache_manager.h163
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/peer_manager/id_manager.c890
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/peer_manager/id_manager.h327
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/peer_manager/peer_data_storage.c678
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/peer_manager/peer_data_storage.h270
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/peer_manager/peer_database.c814
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/peer_manager/peer_database.h309
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/peer_manager/peer_id.c202
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/peer_manager/peer_id.h167
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/peer_manager/peer_manager.c983
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/peer_manager/peer_manager.h781
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/peer_manager/peer_manager_internal.h207
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/peer_manager/peer_manager_types.h354
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/peer_manager/pm_buffer.c151
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/peer_manager/pm_buffer.h159
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/peer_manager/pm_mutex.c144
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/peer_manager/pm_mutex.h125
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/peer_manager/security_dispatcher.c1110
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/peer_manager/security_dispatcher.h166
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/peer_manager/security_manager.c675
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/peer_manager/security_manager.h181
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/boards/arduino_primo.h113
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/boards/boards.c228
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/boards/boards.h355
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/boards/d52_starterkit.h148
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/boards/n5_starterkit.h128
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/boards/nrf6310.h180
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/boards/pca10000.h98
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/boards/pca10001.h165
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/boards/pca10003.h89
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/boards/pca10028.h171
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/boards/pca10031.h88
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/boards/pca10036.h176
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/boards/pca10040.h177
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/boards/pca10056.h163
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/boards/pca10059.h95
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/boards/pca20006.h90
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/boards/pca20020.h126
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/boards/wt51822.h94
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/drivers_ext/adns2080/adns2080.c358
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/drivers_ext/adns2080/adns2080.h317
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/drivers_ext/bh1745/bh1745.c203
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/drivers_ext/bh1745/bh1745.h359
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/drivers_ext/bh1745/bh1745_internal.h180
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/drivers_ext/ccs811/ccs811.c225
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/drivers_ext/ccs811/ccs811.h297
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/drivers_ext/ccs811/ccs811_internal.h259
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/drivers_ext/cherry8x16/cherry8x16.c474
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/drivers_ext/cherry8x16/cherry8x16.h119
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/drivers_ext/ds1624/ds1624.c154
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/drivers_ext/ds1624/ds1624.h113
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/drivers_ext/hts221/hts221.c255
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/drivers_ext/hts221/hts221.h309
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/drivers_ext/hts221/hts221_internal.h235
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/drivers_ext/ili9341/ili9341.c401
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/drivers_ext/lis2dh12/lis2dh12.c173
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/drivers_ext/lis2dh12/lis2dh12.h491
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/drivers_ext/lis2dh12/lis2dh12_internal.h823
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/drivers_ext/lps22hb/lps22hb.c320
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/drivers_ext/lps22hb/lps22hb.h512
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/drivers_ext/lps22hb/lps22hb_internal.h365
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/drivers_ext/max9850/max9850.c71
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/drivers_ext/max9850/max9850.h130
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/drivers_ext/mcp4725/mcp4725.c156
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/drivers_ext/mcp4725/mcp4725.h107
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/drivers_ext/mpu6050/mpu6050.c108
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/drivers_ext/mpu6050/mpu6050.h110
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/drivers_ext/nrf6350/nrf6350.c305
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/drivers_ext/nrf6350/nrf6350.h154
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/drivers_ext/st7735/st7735.c474
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/drivers_ext/sx1509b/sx1509b.c1002
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/drivers_ext/sx1509b/sx1509b.h1238
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/drivers_ext/sx1509b/sx1509b_internal.h232
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/drivers_ext/synaptics_touchpad/synaptics_touchpad.c142
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/drivers_ext/synaptics_touchpad/synaptics_touchpad.h164
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/drivers_ext/uda1380/uda1380.c124
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/drivers_ext/uda1380/uda1380.h140
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/drivers_nrf/nrf_soc_nosd/nrf_error.h95
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/drivers_nrf/nrf_soc_nosd/nrf_nvic.c123
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/drivers_nrf/nrf_soc_nosd/nrf_nvic.h166
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/drivers_nrf/nrf_soc_nosd/nrf_sdm.h56
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/drivers_nrf/nrf_soc_nosd/nrf_soc.c48
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/drivers_nrf/nrf_soc_nosd/nrf_soc.h80
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/drivers_nrf/radio_config/radio_config.c188
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/drivers_nrf/radio_config/radio_config.h58
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/drivers_nrf/sdio/config/sdio_config.h55
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/drivers_nrf/sdio/sdio.c244
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/drivers_nrf/sdio/sdio.h105
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/drivers_nrf/spi_master/spi_5W_master.c629
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/drivers_nrf/spi_master/spi_5W_master.h206
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/drivers_nrf/twi_master/deprecated/config/twi_master_config.h55
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/drivers_nrf/twi_master/deprecated/twi_hw_master.c331
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/drivers_nrf/twi_master/deprecated/twi_master.h137
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/drivers_nrf/twi_master/deprecated/twi_sw_master.c519
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/drivers_nrf/usbd/nrf_drv_usbd.c2333
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/drivers_nrf/usbd/nrf_drv_usbd.h943
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/drivers_nrf/usbd/nrf_drv_usbd_errata.h193
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/background_dfu/background_dfu_block.c456
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/background_dfu/background_dfu_block.h197
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/background_dfu/background_dfu_operation.c141
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/background_dfu/background_dfu_operation.h117
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/background_dfu/background_dfu_state.c835
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/background_dfu/background_dfu_state.h216
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/background_dfu/transport/background_dfu_transport.h91
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/background_dfu/transport/tftp/tftp_dfu.c928
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/background_dfu/transport/tftp/tftp_dfu.h80
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/ble_6lowpan/ble_6lowpan.c1978
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/ble_6lowpan/ble_6lowpan.h168
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/coap/coap.c854
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/coap/coap.h125
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/coap/coap_api.h663
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/coap/coap_block.c203
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/coap/coap_block.h126
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/coap/coap_codes.h115
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/coap/coap_message.c804
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/coap/coap_message.h158
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/coap/coap_observe.c688
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/coap/coap_observe.h248
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/coap/coap_observe_api.h222
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/coap/coap_option.c182
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/coap/coap_option.h161
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/coap/coap_queue.c182
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/coap/coap_queue.h153
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/coap/coap_resource.c274
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/coap/coap_resource.h110
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/coap/coap_transport.h165
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/coap/coap_transport_dtls.c996
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/coap/coap_transport_ipv6.c264
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/coap/coap_transport_lwip.c255
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/coap/coap_transport_socket.c292
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/common/iot_common.h95
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/common/iot_defines.h321
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/common/iot_errors.h290
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/context_manager/iot_context_manager.c561
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/context_manager/iot_context_manager.h155
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/errno/errno.c55
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/errno/errno.h76
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/iot_file/iot_file.c195
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/iot_file/iot_file.h175
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/iot_file/iot_file_port.h147
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/iot_file/static/iot_file_static.c220
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/iot_file/static/iot_file_static.h86
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/iot_timer/iot_timer.c183
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/iot_timer/iot_timer.h175
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/ipv6_parse/ipv6_parse.c167
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/ipv6_parse/ipv6_parse.h75
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/ipv6_stack/dns6/dns6.c903
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/ipv6_stack/icmp6/icmp6.c1355
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/ipv6_stack/icmp6/icmp6.h101
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/ipv6_stack/include/dns6_api.h173
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/ipv6_stack/include/icmp6_api.h253
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/ipv6_stack/include/ipv6_api.h207
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/ipv6_stack/include/udp_api.h255
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/ipv6_stack/ipv6/ipv6.c1088
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/ipv6_stack/pbuffer/iot_pbuffer.c467
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/ipv6_stack/pbuffer/iot_pbuffer.h175
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/ipv6_stack/sntp_client/sntp_client.c607
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/ipv6_stack/sntp_client/sntp_client.h202
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/ipv6_stack/tftp/iot_tftp.c2455
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/ipv6_stack/tftp/iot_tftp.h245
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/ipv6_stack/udp/udp.h98
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/ipv6_stack/udp/udp6.c708
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/ipv6_stack/utils/ipv6_utils.c101
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/ipv6_stack/utils/ipv6_utils.h93
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/lwm2m/ipso_objects.c553
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/lwm2m/ipso_objects.h628
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/lwm2m/ipso_objects_tlv.c143
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/lwm2m/ipso_objects_tlv.h94
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/lwm2m/lwm2m.c885
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/lwm2m/lwm2m.h109
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/lwm2m/lwm2m_api.h426
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/lwm2m/lwm2m_bootstrap.c203
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/lwm2m/lwm2m_bootstrap.h69
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/lwm2m/lwm2m_coap_util.c166
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/lwm2m/lwm2m_objects.c347
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/lwm2m/lwm2m_objects.h443
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/lwm2m/lwm2m_objects_tlv.c498
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/lwm2m/lwm2m_objects_tlv.h124
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/lwm2m/lwm2m_register.c542
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/lwm2m/lwm2m_register.h69
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/lwm2m/lwm2m_tlv.c399
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/lwm2m/lwm2m_tlv.h207
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/medium/ble_ncfgs/ble_ncfgs.c516
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/medium/ble_ncfgs/ble_ncfgs.h194
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/medium/commissioning/commissioning.c1077
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/medium/commissioning/commissioning.h207
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/medium/ipv6_medium.h238
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/medium/ipv6_medium_ble.c689
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/medium/ipv6_medium_ble.h100
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/medium/ipv6_medium_platform_dummy.h54
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/mqtt/mqtt.c821
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/mqtt/mqtt.h506
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/mqtt/mqtt_decoder.c262
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/mqtt/mqtt_encoder.c457
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/mqtt/mqtt_internal.h446
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/mqtt/mqtt_rx.c313
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/mqtt/mqtt_rx.h74
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/mqtt/mqtt_transport.c88
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/mqtt/mqtt_transport.h233
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/mqtt/mqtt_transport_lwip.c349
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/mqtt/mqtt_transport_socket.c319
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/mqtt/mqtt_transport_tls.c185
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/socket/README.md28
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/socket/api/arpa/inet.h45
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/socket/api/netinet/in.h45
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/socket/api/socket_api.h593
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/socket/api/sys/select.h45
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/socket/api/sys/socket.h45
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/socket/api/unistd.h82
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/socket/common/sleep.c53
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/socket/common/socket.c746
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/socket/common/socket_common.h115
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/socket/common/socket_config.h81
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/socket/common/socket_trace.h102
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/socket/common/transport_if.h161
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/socket/config/medium/config_medium.c227
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/socket/config/medium/config_medium.h120
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/socket/libraries/addr_util/inet_pton.c60
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/socket/libraries/fifo/nrf_fifo.c176
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/socket/libraries/fifo/nrf_fifo.h170
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/socket/libraries/mbuf/mbuf.c122
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/socket/libraries/mbuf/mbuf.h146
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/socket/libraries/portdb/portdb.c185
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/socket/libraries/portdb/portdb.h123
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/socket/platform/ble/socket_ble.c50
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/socket/transport/ipv6/transport_handler.c387
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/socket/transport/lwip/transport_handler.c630
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/atomic/nrf_atomic.c447
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/atomic/nrf_atomic.h274
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/atomic/nrf_atomic_internal.h343
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/atomic/nrf_atomic_sanity_check.h153
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/atomic_fifo/nrf_atfifo.c189
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/atomic_fifo/nrf_atfifo.h424
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/atomic_fifo/nrf_atfifo_internal.h577
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/atomic_flags/nrf_atflags.c160
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/atomic_flags/nrf_atflags.h183
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/balloc/nrf_balloc.c399
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/balloc/nrf_balloc.h351
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/block_dev/empty/nrf_block_dev_empty.c210
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/block_dev/empty/nrf_block_dev_empty.h140
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/block_dev/nrf_block_dev.h352
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/block_dev/qspi/nrf_block_dev_qspi.c757
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/block_dev/qspi/nrf_block_dev_qspi.h172
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/block_dev/qspi/nrf_serial_flash_params.c65
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/block_dev/qspi/nrf_serial_flash_params.h83
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/block_dev/ram/nrf_block_dev_ram.c205
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/block_dev/ram/nrf_block_dev_ram.h140
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/block_dev/sdc/nrf_block_dev_sdc.c392
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/block_dev/sdc/nrf_block_dev_sdc.h139
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/ble_dfu/nrf_dfu_ble.c1238
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/ble_dfu/nrf_dfu_ble.h93
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/ble_dfu/nrf_dfu_ble_svci_bond_sharing.h95
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/dfu/dfu-cc.options3
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/dfu/dfu-cc.pb.c116
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/dfu/dfu-cc.pb.h213
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/dfu/dfu-cc.proto66
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/dfu/nrf_dfu.c100
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/dfu/nrf_dfu.h85
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/dfu/nrf_dfu_flash.c167
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/dfu/nrf_dfu_flash.h132
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/dfu/nrf_dfu_handling_error.c61
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/dfu/nrf_dfu_handling_error.h124
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/dfu/nrf_dfu_mbr.c109
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/dfu/nrf_dfu_mbr.h90
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/dfu/nrf_dfu_req_handler.c855
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/dfu/nrf_dfu_req_handler.h345
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/dfu/nrf_dfu_settings.c241
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/dfu/nrf_dfu_settings.h173
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/dfu/nrf_dfu_settings_svci.c185
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/dfu/nrf_dfu_svci.c86
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/dfu/nrf_dfu_svci_handler.c222
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/dfu/nrf_dfu_transport.c91
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/dfu/nrf_dfu_transport.h134
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/dfu/nrf_dfu_trigger_usb.c237
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/dfu/nrf_dfu_trigger_usb.h74
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/dfu/nrf_dfu_types.h302
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/dfu/nrf_dfu_utils.c259
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/dfu/nrf_dfu_utils.h167
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/dfu/nrf_dfu_validation.c745
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/dfu/nrf_dfu_validation.h127
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/dfu/nrf_dfu_ver_validation.c241
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/dfu/nrf_dfu_ver_validation.h58
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/nrf_bootloader.c394
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/nrf_bootloader.h79
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/nrf_bootloader_app_start.c77
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/nrf_bootloader_app_start.h92
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/nrf_bootloader_app_start_final.c256
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/nrf_bootloader_dfu_timers.c126
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/nrf_bootloader_dfu_timers.h87
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/nrf_bootloader_fw_activation.c436
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/nrf_bootloader_fw_activation.h96
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/nrf_bootloader_info.c59
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/nrf_bootloader_info.h188
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/nrf_bootloader_wdt.c134
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/nrf_bootloader_wdt.h79
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/serial_dfu/nrf_dfu_serial.c265
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/serial_dfu/nrf_dfu_serial.h109
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/serial_dfu/nrf_dfu_serial_uart.c235
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/serial_dfu/nrf_dfu_serial_usb.c370
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bsp/bsp.c637
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bsp/bsp.h307
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bsp/bsp_btn_ant.c172
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bsp/bsp_btn_ant.h91
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bsp/bsp_btn_ble.c254
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bsp/bsp_btn_ble.h100
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bsp/bsp_cli.c77
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bsp/bsp_cli.h83
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bsp/bsp_config.h135
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bsp/bsp_nfc.c84
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bsp/bsp_nfc.h107
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/button/app_button.c223
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/button/app_button.h142
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/cli/ble_uart/nrf_cli_ble_uart.c317
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/cli/ble_uart/nrf_cli_ble_uart.h123
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/cli/cdc_acm/nrf_cli_cdc_acm.c242
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/cli/cdc_acm/nrf_cli_cdc_acm.h95
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/cli/cli_utils_cmds.c164
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/cli/libuarte/nrf_cli_libuarte.c247
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/cli/libuarte/nrf_cli_libuarte.h112
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/cli/nrf_cli.c3500
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/cli/nrf_cli.h636
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/cli/nrf_cli_types.h102
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/cli/nrf_cli_vt100.h625
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/cli/rtt/nrf_cli_rtt.c223
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/cli/rtt/nrf_cli_rtt.h100
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/cli/uart/nrf_cli_uart.c308
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/cli/uart/nrf_cli_uart.h115
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crc16/crc16.c61
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crc16/crc16.h80
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crc32/crc32.c61
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crc32/crc32.h79
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/cc310/cc310_backend_aes.c887
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/cc310/cc310_backend_aes.h187
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/cc310/cc310_backend_aes_aead.c366
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/cc310/cc310_backend_aes_aead.h124
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/cc310/cc310_backend_chacha_poly_aead.c214
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/cc310/cc310_backend_chacha_poly_aead.h99
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/cc310/cc310_backend_ecc.c464
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/cc310/cc310_backend_ecc.h548
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/cc310/cc310_backend_ecdh.c131
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/cc310/cc310_backend_ecdh.h182
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/cc310/cc310_backend_ecdsa.c223
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/cc310/cc310_backend_ecdsa.h234
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/cc310/cc310_backend_hash.c311
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/cc310/cc310_backend_hash.h122
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/cc310/cc310_backend_hmac.c273
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/cc310/cc310_backend_hmac.h123
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/cc310/cc310_backend_init.c151
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/cc310/cc310_backend_mutex.c53
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/cc310/cc310_backend_mutex.h111
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/cc310/cc310_backend_rng.c272
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/cc310/cc310_backend_rng.h97
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/cc310/cc310_backend_shared.c115
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/cc310/cc310_backend_shared.h87
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/cc310_bl/cc310_bl_backend_ecc.c165
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/cc310_bl/cc310_bl_backend_ecc.h155
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/cc310_bl/cc310_bl_backend_ecdh.h75
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/cc310_bl/cc310_bl_backend_ecdsa.c267
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/cc310_bl/cc310_bl_backend_ecdsa.h124
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/cc310_bl/cc310_bl_backend_hash.c281
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/cc310_bl/cc310_bl_backend_hash.h97
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/cc310_bl/cc310_bl_backend_init.c115
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/cc310_bl/cc310_bl_backend_shared.c68
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/cc310_bl/cc310_bl_backend_shared.h83
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/cifra/cifra_backend_aes_aead.c205
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/cifra/cifra_backend_aes_aead.h98
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/mbedtls/mbedtls_backend_aes.c1213
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/mbedtls/mbedtls_backend_aes.h227
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/mbedtls/mbedtls_backend_aes_aead.c384
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/mbedtls/mbedtls_backend_aes_aead.h123
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/mbedtls/mbedtls_backend_ecc.c531
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/mbedtls/mbedtls_backend_ecc.h519
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/mbedtls/mbedtls_backend_ecdh.c113
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/mbedtls/mbedtls_backend_ecdh.h169
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/mbedtls/mbedtls_backend_ecdsa.c176
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/mbedtls/mbedtls_backend_ecdsa.h240
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/mbedtls/mbedtls_backend_hash.c196
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/mbedtls/mbedtls_backend_hash.h128
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/mbedtls/mbedtls_backend_hmac.c230
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/mbedtls/mbedtls_backend_hmac.h140
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/mbedtls/mbedtls_backend_init.c106
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/micro_ecc/micro_ecc_backend_ecc.c352
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/micro_ecc/micro_ecc_backend_ecc.h303
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/micro_ecc/micro_ecc_backend_ecdh.c93
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/micro_ecc/micro_ecc_backend_ecdh.h105
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/micro_ecc/micro_ecc_backend_ecdsa.c166
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/micro_ecc/micro_ecc_backend_ecdsa.h124
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/micro_ecc/micro_ecc_backend_shared.h67
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/nrf_hw/nrf_hw_backend_init.c95
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/nrf_hw/nrf_hw_backend_rng.c101
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/nrf_hw/nrf_hw_backend_rng.h104
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/nrf_hw/nrf_hw_backend_rng_mbedtls.c168
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/nrf_hw/nrf_hw_backend_rng_mbedtls.h108
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/nrf_sw/nrf_sw_backend_hash.c149
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/nrf_sw/nrf_sw_backend_hash.h99
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/oberon/oberon_backend_chacha_poly_aead.c153
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/oberon/oberon_backend_chacha_poly_aead.h100
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/oberon/oberon_backend_ecc.c458
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/oberon/oberon_backend_ecc.h314
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/oberon/oberon_backend_ecdh.c114
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/oberon/oberon_backend_ecdh.h108
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/oberon/oberon_backend_ecdsa.c166
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/oberon/oberon_backend_ecdsa.h141
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/oberon/oberon_backend_hash.c184
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/oberon/oberon_backend_hash.h123
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/oberon/oberon_backend_hmac.c169
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/oberon/oberon_backend_hmac.h136
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/nrf_crypto.h77
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/nrf_crypto_aead.c159
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/nrf_crypto_aead.h235
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/nrf_crypto_aead_backend.h100
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/nrf_crypto_aead_shared.h147
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/nrf_crypto_aes.c319
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/nrf_crypto_aes.h481
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/nrf_crypto_aes_backend.h112
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/nrf_crypto_aes_shared.c121
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/nrf_crypto_aes_shared.h218
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/nrf_crypto_ecc.c1314
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/nrf_crypto_ecc.h999
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/nrf_crypto_ecc_backend.h352
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/nrf_crypto_ecc_shared.h229
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/nrf_crypto_ecdh.c286
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/nrf_crypto_ecdh.h207
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/nrf_crypto_ecdh_backend.h184
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/nrf_crypto_ecdh_shared.h79
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/nrf_crypto_ecdsa.c471
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/nrf_crypto_ecdsa.h252
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/nrf_crypto_ecdsa_backend.h262
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/nrf_crypto_ecdsa_shared.h103
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/nrf_crypto_error.c102
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/nrf_crypto_error.h113
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/nrf_crypto_hash.c205
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/nrf_crypto_hash.h268
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/nrf_crypto_hash_backend.h84
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/nrf_crypto_hash_shared.h120
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/nrf_crypto_hkdf.c225
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/nrf_crypto_hkdf.h141
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/nrf_crypto_hmac.c203
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/nrf_crypto_hmac.h226
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/nrf_crypto_hmac_backend.h93
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/nrf_crypto_hmac_shared.h150
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/nrf_crypto_init.c122
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/nrf_crypto_init.h145
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/nrf_crypto_mem.h185
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/nrf_crypto_rng.c430
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/nrf_crypto_rng.h285
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/nrf_crypto_rng_backend.h82
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/nrf_crypto_rng_shared.h142
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/nrf_crypto_shared.c97
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/nrf_crypto_shared.h189
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/nrf_crypto_svc.c93
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/nrf_crypto_types.h113
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/csense/nrf_csense.c662
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/csense/nrf_csense.h344
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/csense/nrf_csense_macros.h359
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/csense_drv/nrf_drv_csense.c633
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/csense_drv/nrf_drv_csense.h150
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/delay/nrf_delay.h80
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/ecc/ecc.c206
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/ecc/ecc.h143
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/experimental_libuarte/nrf_libuarte.c578
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/experimental_libuarte/nrf_libuarte.h153
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/experimental_libuarte/nrf_libuarte_async.c365
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/experimental_libuarte/nrf_libuarte_async.h135
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/experimental_log/nrf_log.h291
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/experimental_log/nrf_log_backend_flash.h129
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/experimental_log/nrf_log_backend_interface.h220
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/experimental_log/nrf_log_backend_rtt.h82
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/experimental_log/nrf_log_backend_uart.h77
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/experimental_log/nrf_log_ctrl.h226
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/experimental_log/nrf_log_default_backends.h81
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/experimental_log/nrf_log_instance.h135
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/experimental_log/nrf_log_str_formatter.h86
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/experimental_log/nrf_log_types.h97
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/experimental_log/src/nrf_log_backend_flash.c739
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/experimental_log/src/nrf_log_backend_rtt.c123
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/experimental_log/src/nrf_log_backend_serial.c115
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/experimental_log/src/nrf_log_backend_serial.h77
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/experimental_log/src/nrf_log_backend_uart.c116
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/experimental_log/src/nrf_log_ctrl_internal.h80
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/experimental_log/src/nrf_log_default_backends.c76
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/experimental_log/src/nrf_log_frontend.c1245
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/experimental_log/src/nrf_log_internal.h529
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/experimental_log/src/nrf_log_str_formatter.c256
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/experimental_memobj/nrf_memobj.c231
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/experimental_memobj/nrf_memobj.h198
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/experimental_mpu/nrf_mpu.c442
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/experimental_mpu/nrf_mpu.h94
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/experimental_ringbuf/nrf_ringbuf.c238
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/experimental_ringbuf/nrf_ringbuf.h206
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/experimental_section_vars/nrf_section.h191
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/experimental_section_vars/nrf_section_iter.c125
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/experimental_section_vars/nrf_section_iter.h206
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/experimental_stack_guard/nrf_stack_guard.c92
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/experimental_stack_guard/nrf_stack_guard.h80
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/experimental_task_manager/task_manager.c543
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/experimental_task_manager/task_manager.h143
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/experimental_task_manager/task_manager_core_armgcc.S89
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/experimental_task_manager/task_manager_core_iar.s83
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/experimental_task_manager/task_manager_core_keil.s85
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/fds/fds.c2164
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/fds/fds.h700
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/fds/fds_internal_defs.h327
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/fifo/app_fifo.c214
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/fifo/app_fifo.h181
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/fstorage/nrf_fstorage.c244
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/fstorage/nrf_fstorage.h341
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/fstorage/nrf_fstorage_nvmc.c217
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/fstorage/nrf_fstorage_nvmc.h75
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/fstorage/nrf_fstorage_sd.c624
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/fstorage/nrf_fstorage_sd.h75
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/gfx/nrf_gfx.c628
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/gfx/nrf_gfx.h320
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/gfx/nrf_lcd.h144
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/gpiote/app_gpiote.c352
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/gpiote/app_gpiote.h266
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/hardfault/hardfault.h96
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/hardfault/hardfault_genhf.h165
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/hardfault/hardfault_implementation.c158
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/hardfault/nrf51/handler/hardfault_handler_gcc.c87
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/hardfault/nrf51/handler/hardfault_handler_iar.c98
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/hardfault/nrf51/handler/hardfault_handler_keil.c88
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/hardfault/nrf52/handler/hardfault_handler_gcc.c100
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/hardfault/nrf52/handler/hardfault_handler_iar.c97
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/hardfault/nrf52/handler/hardfault_handler_keil.c87
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/hci/hci_mem_pool.c264
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/hci/hci_mem_pool.h168
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/hci/hci_slip.c457
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/hci/hci_slip.h165
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/hci/hci_transport.c808
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/hci/hci_transport.h256
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/led_softblink/led_softblink.c232
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/led_softblink/led_softblink.h171
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/low_power_pwm/low_power_pwm.c258
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/low_power_pwm/low_power_pwm.h209
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/mem_manager/mem_manager.c931
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/mem_manager/mem_manager.h175
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/mutex/nrf_mtx.h159
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/pwm/app_pwm.c1009
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/pwm/app_pwm.h338
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/pwr_mgmt/nrf_pwr_mgmt.c465
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/pwr_mgmt/nrf_pwr_mgmt.h150
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/queue/nrf_queue.c547
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/queue/nrf_queue.h429
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/scheduler/app_scheduler.c288
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/scheduler/app_scheduler.h211
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/scheduler/app_scheduler_serconn.c298
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/sdcard/app_sdcard.c1179
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/sdcard/app_sdcard.h209
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/sensorsim/sensorsim.c100
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/sensorsim/sensorsim.h121
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/serial/nrf_serial.c675
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/serial/nrf_serial.h397
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/sha256/sha256.c225
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/sha256/sha256.h127
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/simple_timer/app_simple_timer.c191
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/simple_timer/app_simple_timer.h132
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/slip/slip.c150
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/slip/slip.h117
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/sortlist/nrf_sortlist.c126
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/sortlist/nrf_sortlist.h179
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/spi_mngr/nrf_spi_mngr.c348
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/spi_mngr/nrf_spi_mngr.h310
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/stack_info/nrf_stack_info.h163
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/strerror/nrf_strerror.c161
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/strerror/nrf_strerror.h89
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/svc/nrf_svc_function.h146
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/svc/nrf_svc_handler.c156
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/svc/nrf_svci.h300
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/svc/nrf_svci_async_function.h191
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/svc/nrf_svci_async_handler.h93
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/timer/app_timer.c1075
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/timer/app_timer.h313
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/timer/app_timer_freertos.c241
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/timer/app_timer_rtx.c278
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/timer/experimental/app_timer2.c568
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/timer/experimental/drv_rtc.c330
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/timer/experimental/drv_rtc.h304
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/twi_mngr/nrf_twi_mngr.c366
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/twi_mngr/nrf_twi_mngr.h342
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/twi_sensor/nrf_twi_sensor.c220
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/twi_sensor/nrf_twi_sensor.h314
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/uart/app_uart.c160
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/uart/app_uart.h262
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/uart/app_uart_fifo.c244
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/uart/retarget.c176
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/usbd/app_usbd.c1766
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/usbd/app_usbd.h745
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/usbd/app_usbd_class_base.h1094
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/usbd/app_usbd_core.c1222
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/usbd/app_usbd_core.h206
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/usbd/app_usbd_descriptor.h337
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/usbd/app_usbd_langid.h286
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/usbd/app_usbd_request.h356
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/usbd/app_usbd_serial_num.c87
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/usbd/app_usbd_serial_num.h75
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/usbd/app_usbd_string_desc.c188
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/usbd/app_usbd_string_desc.h119
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/usbd/app_usbd_types.h248
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/usbd/class/audio/app_usbd_audio.c813
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/usbd/class/audio/app_usbd_audio.h329
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/usbd/class/audio/app_usbd_audio_desc.h318
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/usbd/class/audio/app_usbd_audio_internal.h284
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/usbd/class/audio/app_usbd_audio_types.h382
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/usbd/class/cdc/acm/app_usbd_cdc_acm.c1190
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/usbd/class/cdc/acm/app_usbd_cdc_acm.h362
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/usbd/class/cdc/acm/app_usbd_cdc_acm_internal.h268
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/usbd/class/cdc/app_usbd_cdc_desc.h208
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/usbd/class/cdc/app_usbd_cdc_types.h360
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/usbd/class/dummy/app_usbd_dummy.c107
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/usbd/class/dummy/app_usbd_dummy.h138
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/usbd/class/dummy/app_usbd_dummy_internal.h115
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/usbd/class/dummy/app_usbd_dummy_types.h75
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/usbd/class/hid/app_usbd_hid.c508
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/usbd/class/hid/app_usbd_hid.h515
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/usbd/class/hid/app_usbd_hid_types.h281
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/usbd/class/hid/generic/app_usbd_hid_generic.c506
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/usbd/class/hid/generic/app_usbd_hid_generic.h223
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/usbd/class/hid/generic/app_usbd_hid_generic_desc.h96
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/usbd/class/hid/generic/app_usbd_hid_generic_internal.h186
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/usbd/class/hid/kbd/app_usbd_hid_kbd.c557
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/usbd/class/hid/kbd/app_usbd_hid_kbd.h309
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/usbd/class/hid/kbd/app_usbd_hid_kbd_desc.h128
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/usbd/class/hid/kbd/app_usbd_hid_kbd_internal.h174
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/usbd/class/hid/mouse/app_usbd_hid_mouse.c620
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/usbd/class/hid/mouse/app_usbd_hid_mouse.h184
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/usbd/class/hid/mouse/app_usbd_hid_mouse_desc.h117
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/usbd/class/hid/mouse/app_usbd_hid_mouse_internal.h173
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/usbd/class/msc/app_usbd_msc.c2365
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/usbd/class/msc/app_usbd_msc.h193
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/usbd/class/msc/app_usbd_msc_desc.h104
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/usbd/class/msc/app_usbd_msc_internal.h259
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/usbd/class/msc/app_usbd_msc_scsi.h329
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/usbd/class/msc/app_usbd_msc_types.h141
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/usbd/class/nrf_dfu_trigger/app_usbd_nrf_dfu_trigger.c374
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/usbd/class/nrf_dfu_trigger/app_usbd_nrf_dfu_trigger.h166
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/usbd/class/nrf_dfu_trigger/app_usbd_nrf_dfu_trigger_internal.h203
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/usbd/class/nrf_dfu_trigger/app_usbd_nrf_dfu_trigger_types.h145
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/usbd/config/app_usbd_string_config.h131
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/util/app_error.c125
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/util/app_error.h192
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/util/app_error_handler_gcc.c101
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/util/app_error_handler_iar.c101
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/util/app_error_handler_keil.c89
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/util/app_error_weak.c109
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/util/app_error_weak.h87
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/util/app_util.h1204
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/util/app_util_bds.h449
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/util/app_util_platform.c127
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/util/app_util_platform.h279
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/util/nordic_common.h215
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/util/nrf_assert.c54
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/util/nrf_assert.h122
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/util/nrf_bitmask.h147
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/util/sdk_alloca.h85
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/util/sdk_common.h77
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/util/sdk_errors.h167
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/util/sdk_macros.h215
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/util/sdk_mapped_flags.c220
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/util/sdk_mapped_flags.h199
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/util/sdk_os.h76
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/util/sdk_resources.h86
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/ndef/conn_hand_parser/ac_rec_parser/nfc_ac_rec_parser.c205
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/ndef/conn_hand_parser/ac_rec_parser/nfc_ac_rec_parser.h88
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/ndef/conn_hand_parser/ble_oob_advdata_parser/nfc_ble_oob_advdata_parser.c524
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/ndef/conn_hand_parser/ble_oob_advdata_parser/nfc_ble_oob_advdata_parser.h137
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/ndef/conn_hand_parser/le_oob_rec_parser/nfc_le_oob_rec_parser.c104
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/ndef/conn_hand_parser/le_oob_rec_parser/nfc_le_oob_rec_parser.h85
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/ndef/connection_handover/ac_rec/nfc_ac_rec.c164
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/ndef/connection_handover/ac_rec/nfc_ac_rec.h199
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/ndef/connection_handover/ble_oob_advdata/nfc_ble_oob_advdata.c402
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/ndef/connection_handover/ble_oob_advdata/nfc_ble_oob_advdata.h94
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/ndef/connection_handover/ble_pair_lib/nfc_ble_pair_lib.c641
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/ndef/connection_handover/ble_pair_lib/nfc_ble_pair_lib.h137
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/ndef/connection_handover/ble_pair_msg/nfc_ble_pair_msg.c411
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/ndef/connection_handover/ble_pair_msg/nfc_ble_pair_msg.h279
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/ndef/connection_handover/common/nfc_ble_pair_common.c53
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/ndef/connection_handover/common/nfc_ble_pair_common.h106
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/ndef/connection_handover/ep_oob_rec/nfc_ep_oob_rec.c188
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/ndef/connection_handover/ep_oob_rec/nfc_ep_oob_rec.h135
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/ndef/connection_handover/hs_rec/nfc_hs_rec.c107
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/ndef/connection_handover/hs_rec/nfc_hs_rec.h165
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/ndef/connection_handover/le_oob_rec/nfc_le_oob_rec.c106
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/ndef/connection_handover/le_oob_rec/nfc_le_oob_rec.h123
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/ndef/generic/message/nfc_ndef_msg.c183
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/ndef/generic/message/nfc_ndef_msg.h197
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/ndef/generic/record/nfc_ndef_record.c191
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/ndef/generic/record/nfc_ndef_record.h311
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/ndef/launchapp/nfc_launchapp_msg.c97
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/ndef/launchapp/nfc_launchapp_msg.h100
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/ndef/launchapp/nfc_launchapp_rec.c107
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/ndef/launchapp/nfc_launchapp_rec.h205
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/ndef/parser/message/nfc_ndef_msg_parser.c94
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/ndef/parser/message/nfc_ndef_msg_parser.h123
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/ndef/parser/message/nfc_ndef_msg_parser_local.c163
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/ndef/parser/message/nfc_ndef_msg_parser_local.h166
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/ndef/parser/record/nfc_ndef_record_parser.c219
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/ndef/parser/record/nfc_ndef_record_parser.h100
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/ndef/text/nfc_text_rec.c107
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/ndef/text/nfc_text_rec.h161
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/ndef/uri/nfc_uri_msg.c72
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/ndef/uri/nfc_uri_msg.h95
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/ndef/uri/nfc_uri_rec.c87
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/ndef/uri/nfc_uri_rec.h189
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/t2t_lib/hal_t2t/hal_nfc_t2t.c1007
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/t2t_lib/hal_t2t/hal_nfc_t2t.h203
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/t2t_lib/license.txt36
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/t2t_lib/nfc_fixes.h133
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/t2t_lib/nfc_t2t_lib.h275
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/t2t_lib/nfc_t2t_lib_gcc.abin0 -> 94496 bytes
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/t2t_lib/nfc_t2t_lib_gcc_no_fpu.abin0 -> 94492 bytes
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/t2t_lib/nfc_t2t_lib_iar.abin0 -> 11806 bytes
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/t2t_lib/nfc_t2t_lib_keil.libbin0 -> 12192 bytes
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/t2t_parser/nfc_t2t_parser.c679
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/t2t_parser/nfc_t2t_parser.h195
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/t2t_parser/nfc_tlv_block.h102
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/t4t_lib/hal_t4t/hal_nfc_t4t.c1321
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/t4t_lib/hal_t4t/hal_nfc_t4t.h203
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/t4t_lib/license.txt36
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/t4t_lib/nfc_fixes.h132
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/t4t_lib/nfc_t4t_lib.h323
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/t4t_lib/nfc_t4t_lib_gcc.abin0 -> 174458 bytes
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/t4t_lib/nfc_t4t_lib_gcc_no_fpu.abin0 -> 174442 bytes
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/t4t_lib/nfc_t4t_lib_iar.abin0 -> 26160 bytes
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/t4t_lib/nfc_t4t_lib_keil.libbin0 -> 25226 bytes
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/t4t_parser/apdu/nfc_t4t_apdu.c261
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/t4t_parser/apdu/nfc_t4t_apdu.h221
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/t4t_parser/cc_file/nfc_t4t_cc_file.c266
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/t4t_parser/cc_file/nfc_t4t_cc_file.h177
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/t4t_parser/hl_detection_procedure/nfc_t4t_hl_detection_procedures.c401
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/t4t_parser/hl_detection_procedure/nfc_t4t_hl_detection_procedures.h184
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/t4t_parser/tlv/nfc_t4t_tlv_block.c327
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/t4t_parser/tlv/nfc_t4t_tlv_block.h147
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/proprietary_rf/esb/nrf_esb.c1603
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/proprietary_rf/esb/nrf_esb.h609
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/proprietary_rf/esb/nrf_esb_error_codes.h56
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/proprietary_rf/esb/nrf_esb_resources.h72
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/proprietary_rf/gzll/arm/gzll_nrf51_arm.libbin0 -> 162642 bytes
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/proprietary_rf/gzll/arm/gzll_nrf51_sd_resources_arm.libbin0 -> 162838 bytes
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/proprietary_rf/gzll/arm/gzll_nrf52840_arm.libbin0 -> 191998 bytes
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/proprietary_rf/gzll/arm/gzll_nrf52840_sd_resources_arm.libbin0 -> 192194 bytes
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/proprietary_rf/gzll/arm/gzll_nrf52_arm.libbin0 -> 192158 bytes
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/proprietary_rf/gzll/arm/gzll_nrf52_sd_resources_arm.libbin0 -> 192354 bytes
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/proprietary_rf/gzll/arm/license.txt37
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/proprietary_rf/gzll/config/nrf_gzp_config.h168
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/proprietary_rf/gzll/gcc/gzll_nrf51_gcc.abin0 -> 86218 bytes
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/proprietary_rf/gzll/gcc/gzll_nrf51_sd_resources_gcc.abin0 -> 86258 bytes
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/proprietary_rf/gzll/gcc/gzll_nrf52840_gcc.abin0 -> 89436 bytes
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/proprietary_rf/gzll/gcc/gzll_nrf52840_sd_resources_gcc.abin0 -> 89452 bytes
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/proprietary_rf/gzll/gcc/gzll_nrf52_gcc.abin0 -> 89436 bytes
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/proprietary_rf/gzll/gcc/gzll_nrf52_sd_resources_gcc.abin0 -> 89452 bytes
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/proprietary_rf/gzll/gcc/license.txt37
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/proprietary_rf/gzll/iar/gzll_nrf51_iar.abin0 -> 150676 bytes
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/proprietary_rf/gzll/iar/gzll_nrf51_sd_resources_iar.abin0 -> 150276 bytes
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/proprietary_rf/gzll/iar/gzll_nrf52840_iar.abin0 -> 185650 bytes
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/proprietary_rf/gzll/iar/gzll_nrf52840_sd_resources_iar.abin0 -> 185224 bytes
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/proprietary_rf/gzll/iar/gzll_nrf52_iar.abin0 -> 185276 bytes
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/proprietary_rf/gzll/iar/gzll_nrf52_sd_resources_iar.abin0 -> 184858 bytes
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/proprietary_rf/gzll/iar/license.txt37
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/proprietary_rf/gzll/nrf_gzll.h937
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/proprietary_rf/gzll/nrf_gzll_constants.h188
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/proprietary_rf/gzll/nrf_gzll_error.h72
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/proprietary_rf/gzll/nrf_gzll_resources.h66
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/proprietary_rf/gzll/nrf_gzp.c363
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/proprietary_rf/gzll/nrf_gzp.h665
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/proprietary_rf/gzll/nrf_gzp_device.c1146
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/proprietary_rf/gzll/nrf_gzp_host.c821
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/proprietary_rf/gzll/nrf_gzp_host_nrf5x.c74
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/sdk_validation.h305
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/application/codecs/ant/middleware/app_mw_ant.c1868
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/application/codecs/ant/serializers/ant_acknowledge_message_tx.c90
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/application/codecs/ant/serializers/ant_active_search_sharing_cycles_get.c96
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/application/codecs/ant/serializers/ant_active_search_sharing_cycles_set.c78
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/application/codecs/ant/serializers/ant_adv_burst_config_set.c86
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/application/codecs/ant/serializers/ant_app.h1652
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/application/codecs/ant/serializers/ant_broadcast_message_tx.c90
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/application/codecs/ant/serializers/ant_capabilities_get.c93
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/application/codecs/ant/serializers/ant_channel_assign.c83
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/application/codecs/ant/serializers/ant_channel_close.c76
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/application/codecs/ant/serializers/ant_channel_id_get.c103
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/application/codecs/ant/serializers/ant_channel_id_set.c83
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/application/codecs/ant/serializers/ant_channel_low_priority_rx_search_timeout_set.c79
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/application/codecs/ant/serializers/ant_channel_open_with_offset.c79
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/application/codecs/ant/serializers/ant_channel_period_get.c94
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/application/codecs/ant/serializers/ant_channel_period_set.c78
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/application/codecs/ant/serializers/ant_channel_radio_freq_get.c95
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/application/codecs/ant/serializers/ant_channel_radio_freq_set.c78
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/application/codecs/ant/serializers/ant_channel_radio_tx_power_set.c81
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/application/codecs/ant/serializers/ant_channel_rx_search_timeout_set.c79
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/application/codecs/ant/serializers/ant_channel_status_get.c95
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/application/codecs/ant/serializers/ant_channel_unassign.c76
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/application/codecs/ant/serializers/ant_coex_config_get.c130
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/application/codecs/ant/serializers/ant_coex_config_set.c109
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/application/codecs/ant/serializers/ant_crypto_channel_enable.c82
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/application/codecs/ant/serializers/ant_crypto_info_get.c123
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/application/codecs/ant/serializers/ant_crypto_info_set.c90
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/application/codecs/ant/serializers/ant_crypto_key_set.c85
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/application/codecs/ant/serializers/ant_cw_test_mode.c82
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/application/codecs/ant/serializers/ant_cw_test_mode_init.c74
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/application/codecs/ant/serializers/ant_enable.c79
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/application/codecs/ant/serializers/ant_event.c74
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/application/codecs/ant/serializers/ant_event.h81
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/application/codecs/ant/serializers/ant_id_list_add.c91
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/application/codecs/ant/serializers/ant_id_list_config.c81
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/application/codecs/ant/serializers/ant_lib_config_clear.c76
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/application/codecs/ant/serializers/ant_lib_config_get.c93
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/application/codecs/ant/serializers/ant_lib_config_set.c76
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/application/codecs/ant/serializers/ant_network_address_set.c85
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/application/codecs/ant/serializers/ant_prox_search_set.c81
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/application/codecs/ant/serializers/ant_rx_scan_mode_start.c76
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/application/codecs/ant/serializers/ant_search_channel_priority_set.c78
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/application/codecs/ant/serializers/ant_search_waveform_set.c79
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/application/codecs/ant/serializers/ant_stack_reset.c74
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/application/codecs/ant/serializers/ant_version_get.c93
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/application/codecs/ble/middleware/app_mw_ble.c621
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/application/codecs/ble/middleware/app_mw_ble_gap.c2025
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/application/codecs/ble/middleware/app_mw_ble_gattc.c566
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/application/codecs/ble/middleware/app_mw_ble_gatts.c773
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/application/codecs/ble/middleware/app_mw_ble_l2cap.c453
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/application/codecs/ble/middleware/app_mw_nrf_soc.c171
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/application/codecs/ble/serializers/app_ble_gap_sec_keys.c182
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/application/codecs/ble/serializers/app_ble_gap_sec_keys.h151
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/application/codecs/ble/serializers/app_ble_user_mem.c101
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/application/codecs/ble/serializers/app_ble_user_mem.h109
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/application/codecs/ble/serializers/ble_app.c513
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/application/codecs/ble/serializers/ble_app.h523
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/application/codecs/ble/serializers/ble_event.c316
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/application/codecs/ble/serializers/ble_evt_app.c129
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/application/codecs/ble/serializers/ble_evt_app.h157
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/application/codecs/ble/serializers/ble_gap_app.c1019
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/application/codecs/ble/serializers/ble_gap_app.h1667
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/application/codecs/ble/serializers/ble_gap_evt_app.c415
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/application/codecs/ble/serializers/ble_gap_evt_app.h546
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/application/codecs/ble/serializers/ble_gattc_app.c286
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/application/codecs/ble/serializers/ble_gattc_app.h491
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/application/codecs/ble/serializers/ble_gattc_evt_app.c262
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/application/codecs/ble/serializers/ble_gattc_evt_app.h364
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/application/codecs/ble/serializers/ble_gatts_app.c439
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/application/codecs/ble/serializers/ble_gatts_app.h677
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/application/codecs/ble/serializers/ble_gatts_evt_app.c190
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/application/codecs/ble/serializers/ble_gatts_evt_app.h249
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/application/codecs/ble/serializers/ble_l2cap_app.c279
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/application/codecs/ble/serializers/ble_l2cap_app.h242
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/application/codecs/ble/serializers/ble_l2cap_evt_app.c183
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/application/codecs/ble/serializers/ble_l2cap_evt_app.h126
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/application/codecs/ble/serializers/nrf_soc_app.c95
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/application/codecs/ble/serializers/nrf_soc_app.h147
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/application/codecs/common/ble_dtm_app.c100
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/application/codecs/common/ble_dtm_app.h126
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/application/codecs/common/ble_dtm_init.c83
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/application/codecs/common/conn_systemreset.c69
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/application/codecs/common/conn_systemreset.h79
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/application/hal/ser_app_hal.h116
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/application/hal/ser_app_hal_nrf5x.c163
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/application/hal/ser_app_power_system_off.c62
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/application/hal/ser_app_power_system_off.h60
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/application/transport/ser_sd_transport.c325
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/application/transport/ser_sd_transport.h193
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/application/transport/ser_softdevice_handler.c311
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/application/transport/ser_softdevice_handler.h80
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/common/ble_serialization.c549
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/common/ble_serialization.h1097
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/common/cond_field_serialization.c101
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/common/cond_field_serialization.h105
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/common/ser_config.h121
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/common/ser_dbg_sd_str.c320
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/common/ser_dbg_sd_str.h45
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/common/struct_ser/ant/ant_struct_serialization.c159
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/common/struct_ser/ant/ant_struct_serialization.h110
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/common/struct_ser/ble/ble_gap_struct_serialization.c1749
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/common/struct_ser/ble/ble_gap_struct_serialization.h612
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/common/struct_ser/ble/ble_gatt_struct_serialization.c158
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/common/struct_ser/ble/ble_gatt_struct_serialization.h94
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/common/struct_ser/ble/ble_gattc_struct_serialization.c715
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/common/struct_ser/ble/ble_gattc_struct_serialization.h293
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/common/struct_ser/ble/ble_gatts_struct_serialization.c689
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/common/struct_ser/ble/ble_gatts_struct_serialization.h259
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/common/struct_ser/ble/ble_l2cap_struct_serialization.c227
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/common/struct_ser/ble/ble_l2cap_struct_serialization.h119
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/common/struct_ser/ble/ble_struct_serialization.c500
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/common/struct_ser/ble/ble_struct_serialization.h217
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/common/struct_ser/ble/nrf_soc_struct_serialization.c90
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/common/struct_ser/ble/nrf_soc_struct_serialization.h73
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/common/transport/dtm_uart_params.h93
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/common/transport/ser_hal_transport.c503
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/common/transport/ser_hal_transport.h266
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/common/transport/ser_phy/config/ser_config_5W_app.h52
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/common/transport/ser_phy/config/ser_phy_config_app.h106
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/common/transport/ser_phy/config/ser_phy_config_conn.h82
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/common/transport/ser_phy/config/ser_phy_debug_app.h198
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/common/transport/ser_phy/config/ser_phy_debug_conn.h166
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/common/transport/ser_phy/ser_phy.c88
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/common/transport/ser_phy/ser_phy.h308
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/common/transport/ser_phy/ser_phy_hci.c1704
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/common/transport/ser_phy/ser_phy_hci.h183
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/common/transport/ser_phy/ser_phy_hci_slip.c689
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/common/transport/ser_phy/ser_phy_hci_slip_cdc.c720
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/common/transport/ser_phy/ser_phy_nohci.c382
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/common/transport/ser_phy/ser_phy_spi_5W_master.c823
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/common/transport/ser_phy/ser_phy_spi_5W_slave.c644
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/common/transport/ser_phy/ser_phy_spi_master.c804
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/common/transport/ser_phy/ser_phy_spi_slave.c613
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/common/transport/ser_phy/ser_phy_uart.c357
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/common/transport/ser_phy_debug_comm.h203
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/connectivity/codecs/ant/middleware/conn_mw_ant.c1196
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/connectivity/codecs/ant/middleware/conn_mw_ant.h793
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/connectivity/codecs/ant/serializers/ant_acknowledge_message_tx.c84
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/connectivity/codecs/ant/serializers/ant_active_search_sharing_cycles_get.c89
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/connectivity/codecs/ant/serializers/ant_active_search_sharing_cycles_set.c78
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/connectivity/codecs/ant/serializers/ant_adv_burst_config_set.c79
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/connectivity/codecs/ant/serializers/ant_broadcast_message_tx.c84
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/connectivity/codecs/ant/serializers/ant_capabilities_get.c71
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/connectivity/codecs/ant/serializers/ant_channel_assign.c89
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/connectivity/codecs/ant/serializers/ant_channel_close.c73
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/connectivity/codecs/ant/serializers/ant_channel_id_get.c97
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/connectivity/codecs/ant/serializers/ant_channel_id_set.c89
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/connectivity/codecs/ant/serializers/ant_channel_low_priority_rx_search_timout_set.c78
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/connectivity/codecs/ant/serializers/ant_channel_open_with_offset.c78
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/connectivity/codecs/ant/serializers/ant_channel_period_get.c89
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/connectivity/codecs/ant/serializers/ant_channel_period_set.c78
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/connectivity/codecs/ant/serializers/ant_channel_radio_freq_get.c89
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/connectivity/codecs/ant/serializers/ant_channel_radio_freq_set.c78
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/connectivity/codecs/ant/serializers/ant_channel_radio_tx_power_set.c83
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/connectivity/codecs/ant/serializers/ant_channel_rx_search_timeout_set.c78
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/connectivity/codecs/ant/serializers/ant_channel_status_get.c89
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/connectivity/codecs/ant/serializers/ant_channel_unassign.c73
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/connectivity/codecs/ant/serializers/ant_coex_config_get.c107
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/connectivity/codecs/ant/serializers/ant_coex_config_set.c101
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/connectivity/codecs/ant/serializers/ant_conn.h1591
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/connectivity/codecs/ant/serializers/ant_crypto_channel_enable.c88
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/connectivity/codecs/ant/serializers/ant_crypto_info_get.c96
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/connectivity/codecs/ant/serializers/ant_crypto_info_set.c84
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/connectivity/codecs/ant/serializers/ant_crypto_key_set.c79
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/connectivity/codecs/ant/serializers/ant_cw_test_mode.c88
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/connectivity/codecs/ant/serializers/ant_cw_test_mode_init.c55
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/connectivity/codecs/ant/serializers/ant_enable.c75
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/connectivity/codecs/ant/serializers/ant_event.c114
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/connectivity/codecs/ant/serializers/ant_event.h74
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/connectivity/codecs/ant/serializers/ant_event_rx.c70
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/connectivity/codecs/ant/serializers/ant_event_rx.h72
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/connectivity/codecs/ant/serializers/ant_id_list_add.c84
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/connectivity/codecs/ant/serializers/ant_id_list_config.c84
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/connectivity/codecs/ant/serializers/ant_lib_config_clear.c73
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/connectivity/codecs/ant/serializers/ant_lib_config_get.c71
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/connectivity/codecs/ant/serializers/ant_lib_config_set.c73
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/connectivity/codecs/ant/serializers/ant_network_address_set.c79
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/connectivity/codecs/ant/serializers/ant_prox_search_set.c83
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/connectivity/codecs/ant/serializers/ant_rx_scan_mode_start.c73
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/connectivity/codecs/ant/serializers/ant_search_channel_priority_set.c78
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/connectivity/codecs/ant/serializers/ant_search_waveform_set.c78
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/connectivity/codecs/ant/serializers/ant_stack_reset.c55
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/connectivity/codecs/ant/serializers/ant_version_get.c71
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/connectivity/codecs/ble/middleware/conn_mw.h83
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/connectivity/codecs/ble/middleware/conn_mw_ble.c416
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/connectivity/codecs/ble/middleware/conn_mw_ble.h242
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/connectivity/codecs/ble/middleware/conn_mw_ble_gap.c1290
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/connectivity/codecs/ble/middleware/conn_mw_ble_gap.h820
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/connectivity/codecs/ble/middleware/conn_mw_ble_gattc.c389
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/connectivity/codecs/ble/middleware/conn_mw_ble_gattc.h259
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/connectivity/codecs/ble/middleware/conn_mw_ble_gatts.c517
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/connectivity/codecs/ble/middleware/conn_mw_ble_gatts.h314
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/connectivity/codecs/ble/middleware/conn_mw_ble_l2cap.c260
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/connectivity/codecs/ble/middleware/conn_mw_ble_l2cap.h206
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/connectivity/codecs/ble/serializers/ble_conn.c558
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/connectivity/codecs/ble/serializers/ble_conn.h521
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/connectivity/codecs/ble/serializers/ble_event_enc.c295
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/connectivity/codecs/ble/serializers/ble_evt_conn.c108
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/connectivity/codecs/ble/serializers/ble_evt_conn.h138
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/connectivity/codecs/ble/serializers/ble_gap_conn.c1111
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/connectivity/codecs/ble/serializers/ble_gap_conn.h1526
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/connectivity/codecs/ble/serializers/ble_gap_evt_conn.c401
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/connectivity/codecs/ble/serializers/ble_gap_evt_conn.h443
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/connectivity/codecs/ble/serializers/ble_gattc_conn.c299
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/connectivity/codecs/ble/serializers/ble_gattc_conn.h481
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/connectivity/codecs/ble/serializers/ble_gattc_evt_conn.c253
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/connectivity/codecs/ble/serializers/ble_gattc_evt_conn.h300
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/connectivity/codecs/ble/serializers/ble_gatts_conn.c421
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/connectivity/codecs/ble/serializers/ble_gatts_conn.h634
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/connectivity/codecs/ble/serializers/ble_gatts_evt_conn.c178
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/connectivity/codecs/ble/serializers/ble_gatts_evt_conn.h208
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/connectivity/codecs/ble/serializers/ble_l2cap_conn.c323
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/connectivity/codecs/ble/serializers/ble_l2cap_conn.h384
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/connectivity/codecs/ble/serializers/ble_l2cap_evt_conn.c199
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/connectivity/codecs/ble/serializers/ble_l2cap_evt_conn.h121
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/connectivity/codecs/ble/serializers/conn_ble_gap_sec_keys.c155
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/connectivity/codecs/ble/serializers/conn_ble_gap_sec_keys.h128
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/connectivity/codecs/ble/serializers/conn_ble_l2cap_sdu_pool.c84
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/connectivity/codecs/ble/serializers/conn_ble_l2cap_sdu_pool.h53
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/connectivity/codecs/ble/serializers/conn_ble_user_mem.c105
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/connectivity/codecs/ble/serializers/conn_ble_user_mem.h108
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/connectivity/codecs/ble/serializers/nrf_soc_conn.c89
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/connectivity/codecs/ble/serializers/nrf_soc_conn.h148
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/connectivity/codecs/common/ble_dtm_conn.h113
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/connectivity/codecs/common/ble_dtm_init.c83
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/connectivity/codecs/common/conn_mw.c107
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/connectivity/codecs/common/conn_mw.h88
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/connectivity/codecs/common/conn_mw_items.c224
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/connectivity/codecs/common/conn_mw_nrf_soc.c114
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/connectivity/codecs/common/conn_mw_nrf_soc.h118
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/connectivity/hal/dtm_uart.c268
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/connectivity/hal/dtm_uart.h59
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/connectivity/pstorage_platform.h103
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/connectivity/ser_conn_cmd_decoder.c138
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/connectivity/ser_conn_cmd_decoder.h89
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/connectivity/ser_conn_dtm_cmd_decoder.c126
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/connectivity/ser_conn_dtm_cmd_decoder.h98
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/connectivity/ser_conn_error_handling.c138
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/connectivity/ser_conn_event_encoder.c169
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/connectivity/ser_conn_event_encoder.h99
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/connectivity/ser_conn_handlers.c207
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/connectivity/ser_conn_handlers.h162
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/connectivity/ser_conn_pkt_decoder.c124
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/connectivity/ser_conn_pkt_decoder.h90
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/connectivity/ser_conn_reset_cmd_decoder.c47
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/connectivity/ser_conn_reset_cmd_decoder.h81
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/softdevice/common/nrf_sdh.c430
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/softdevice/common/nrf_sdh.h305
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/softdevice/common/nrf_sdh_ant.c162
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/softdevice/common/nrf_sdh_ant.h182
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/softdevice/common/nrf_sdh_ble.c324
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/softdevice/common/nrf_sdh_ble.h184
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/softdevice/common/nrf_sdh_freertos.c109
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/softdevice/common/nrf_sdh_freertos.h72
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/softdevice/common/nrf_sdh_soc.c118
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/softdevice/common/nrf_sdh_soc.h143
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/softdevice/mbr/nrf52810/headers90
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/softdevice/mbr/nrf52810/hex/mbr_nrf52_2.2.2_licence-agreement.txt35
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/softdevice/mbr/nrf52810/hex/mbr_nrf52_2.2.2_mbr.hex154
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/softdevice/mbr/nrf52832/headers/nrf_mbr.h241
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/softdevice/mbr/nrf52832/headers/nrf_svc.h90
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/softdevice/mbr/nrf52832/hex/mbr_nrf52_2.2.2_licence-agreement.txt35
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/softdevice/mbr/nrf52832/hex/mbr_nrf52_2.2.2_mbr.hex154
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/softdevice/mbr/nrf52840/headers/nrf_mbr.h242
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/softdevice/mbr/nrf52840/headers/nrf_svc.h90
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/softdevice/mbr/nrf52840/hex/mbr_nrf52_2.3.0_licence-agreement.txt35
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/softdevice/mbr/nrf52840/hex/mbr_nrf52_2.3.0_mbr.hex165
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/softdevice/s112/doc/s112_nrf52_6.0.0_licence-agreement.txt35
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/softdevice/s112/doc/s112_nrf52_6.0.0_migration-document.pdfbin0 -> 18085 bytes
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/softdevice/s112/doc/s112_nrf52_6.0.0_release-notes.pdfbin0 -> 21906 bytes
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/softdevice/s112/headers/ble.h617
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/softdevice/s112/headers/ble_err.h93
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/softdevice/s112/headers/ble_gap.h2023
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/softdevice/s112/headers/ble_gatt.h228
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/softdevice/s112/headers/ble_gattc.h715
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/softdevice/s112/headers/ble_gatts.h845
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/softdevice/s112/headers/ble_hci.h135
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/softdevice/s112/headers/ble_ranges.h148
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/softdevice/s112/headers/ble_types.h215
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/softdevice/s112/headers/nrf52/nrf_mbr.h241
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/softdevice/s112/headers/nrf_error.h90
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/softdevice/s112/headers/nrf_error_sdm.h70
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/softdevice/s112/headers/nrf_error_soc.h85
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/softdevice/s112/headers/nrf_nvic.h486
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/softdevice/s112/headers/nrf_sd_def.h59
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/softdevice/s112/headers/nrf_sdm.h358
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/softdevice/s112/headers/nrf_soc.h964
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/softdevice/s112/headers/nrf_svc.h90
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/softdevice/s112/hex/s112_nrf52_6.0.0_licence-agreement.txt35
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/softdevice/s112/hex/s112_nrf52_6.0.0_softdevice.hex6143
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/softdevice/s112/toolchain/armgcc/armgcc_s112_nrf52810_xxaa.ld33
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/softdevice/s112/toolchain/iar/iar_s112_nrf52810_xxaa.icf36
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/softdevice/s132/doc/s132_nrf52_6.0.0_licence-agreement.txt35
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/softdevice/s132/doc/s132_nrf52_6.0.0_migration-document.pdfbin0 -> 133032 bytes
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/softdevice/s132/doc/s132_nrf52_6.0.0_release-notes.pdfbin0 -> 50680 bytes
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/softdevice/s132/headers/ble.h622
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/softdevice/s132/headers/ble_err.h93
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/softdevice/s132/headers/ble_gap.h2653
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/softdevice/s132/headers/ble_gatt.h228
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/softdevice/s132/headers/ble_gattc.h715
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/softdevice/s132/headers/ble_gatts.h845
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/softdevice/s132/headers/ble_hci.h135
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/softdevice/s132/headers/ble_l2cap.h506
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/softdevice/s132/headers/ble_ranges.h156
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/softdevice/s132/headers/ble_types.h215
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/softdevice/s132/headers/nrf52/nrf_mbr.h241
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/softdevice/s132/headers/nrf_error.h90
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/softdevice/s132/headers/nrf_error_sdm.h70
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/softdevice/s132/headers/nrf_error_soc.h85
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/softdevice/s132/headers/nrf_nvic.h486
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/softdevice/s132/headers/nrf_sd_def.h59
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/softdevice/s132/headers/nrf_sdm.h358
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/softdevice/s132/headers/nrf_soc.h964
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/softdevice/s132/headers/nrf_svc.h90
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/softdevice/s132/hex/s132_nrf52_6.0.0_licence-agreement.txt35
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/softdevice/s132/hex/s132_nrf52_6.0.0_softdevice.hex9278
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/softdevice/s132/toolchain/armgcc/armgcc_s132_nrf52832_xxaa.ld33
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/softdevice/s132/toolchain/iar/iar_s132_nrf52832_xxaa.icf36
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/softdevice/s140/doc/s140_nrf52_6.0.0_licence-agreement.txt35
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/softdevice/s140/doc/s140_nrf52_6.0.0_migration-document.pdfbin0 -> 71009 bytes
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/softdevice/s140/doc/s140_nrf52_6.0.0_release-notes.pdfbin0 -> 64894 bytes
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/softdevice/s140/headers/ble.h622
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/softdevice/s140/headers/ble_err.h93
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/softdevice/s140/headers/ble_gap.h2669
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/softdevice/s140/headers/ble_gatt.h228
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/softdevice/s140/headers/ble_gattc.h715
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/softdevice/s140/headers/ble_gatts.h845
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/softdevice/s140/headers/ble_hci.h135
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/softdevice/s140/headers/ble_l2cap.h506
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/softdevice/s140/headers/ble_ranges.h156
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/softdevice/s140/headers/ble_types.h215
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/softdevice/s140/headers/nrf52/nrf_mbr.h242
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/softdevice/s140/headers/nrf_error.h90
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/softdevice/s140/headers/nrf_error_sdm.h70
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/softdevice/s140/headers/nrf_error_soc.h85
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/softdevice/s140/headers/nrf_nvic.h486
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/softdevice/s140/headers/nrf_sd_def.h59
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/softdevice/s140/headers/nrf_sdm.h358
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/softdevice/s140/headers/nrf_soc.h1036
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/softdevice/s140/headers/nrf_svc.h90
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/softdevice/s140/hex/s140_nrf52_6.0.0_licence-agreement.txt35
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/softdevice/s140/hex/s140_nrf52_6.0.0_softdevice.hex9443
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/softdevice/s212/headers/Readme.txt1
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/softdevice/s212/toolchain/armgcc/armgcc_s212_nrf52832_xxaa.ld33
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/softdevice/s212/toolchain/iar/iar_s212_nrf52832_xxaa.icf36
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/toolchain/arm/uicr_config.h114
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/toolchain/cmsis/dsp/ARM/arm_cortexM4l_math.libbin0 -> 13787724 bytes
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/toolchain/cmsis/dsp/ARM/arm_cortexM4lf_math.libbin0 -> 13943636 bytes
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/toolchain/cmsis/dsp/GCC/libarm_cortexM4l_math.abin0 -> 3192576 bytes
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/toolchain/cmsis/dsp/GCC/libarm_cortexM4lf_math.abin0 -> 3144804 bytes
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/toolchain/cmsis/dsp/license.txt28
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/toolchain/cmsis/include/arm_common_tables.h136
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/toolchain/cmsis/include/arm_const_structs.h79
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/toolchain/cmsis/include/arm_math.h7030
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/toolchain/cmsis/include/cmsis_armcc.h734
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/toolchain/cmsis/include/cmsis_armcc_V6.h1800
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/toolchain/cmsis/include/cmsis_gcc.h1373
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/toolchain/cmsis/include/core_cm0.h798
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/toolchain/cmsis/include/core_cm0plus.h914
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/toolchain/cmsis/include/core_cm3.h1763
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/toolchain/cmsis/include/core_cm4.h1937
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/toolchain/cmsis/include/core_cm7.h2512
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/toolchain/cmsis/include/core_cmFunc.h86
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/toolchain/cmsis/include/core_cmInstr.h87
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/toolchain/cmsis/include/core_cmSimd.h96
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/toolchain/cmsis/include/core_sc000.h926
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/toolchain/cmsis/include/core_sc300.h1745
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/toolchain/gcc/Makefile.common307
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/toolchain/gcc/Makefile.posix3
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/toolchain/gcc/Makefile.windows3
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/toolchain/gcc/dump.mk2
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/toolchain/gcc/gcc_nrf51_common.ld164
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/toolchain/iar/iar_nrf51_blank_xxaa.icf31
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/toolchain/iar/iar_nrf51_blank_xxac.icf31
1502 files changed, 432181 insertions, 0 deletions
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/802_15_4/api/HAL/hal_atomic.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/802_15_4/api/HAL/hal_atomic.h
new file mode 100644
index 0000000..27264d6
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/802_15_4/api/HAL/hal_atomic.h
@@ -0,0 +1,82 @@
+/**
+ * Copyright (c) 2016 - 2018 Nordic Semiconductor ASA and Luxoft Global Operations Gmbh.
+ *
+ * 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#ifndef HAL_ATOMIC_H_INCLUDED
+#define HAL_ATOMIC_H_INCLUDED
+
+#include <stdint.h>
+
+/** @file
+ * This file contains declarations of the Atomic section routines and necessary types.
+ *
+ * @defgroup hal_atomic HAL Atomic API
+ * @ingroup hal_15_4
+ * @{
+ * @brief Module to declare HAL Atomic API
+ * @details The Atomic module implements atomic section interface. This is made by disabling the global interrupts,
+ * which is a hardware dependent feature. The user may call hal_atomic_start() to open an atomic section
+ * (disable interrupts) and hal_atomic_end() to exit from the section (restore interrupts). The algorithm
+ * supports nesting sections.
+ */
+
+typedef volatile uint32_t atomic_t;
+
+
+/**@brief Enters atomic section.
+ *
+ * @details Disables global interrupts.
+ *
+ * @param[in] p_atomic pointer to buffer to store current value of the status register.
+ */
+void hal_atomic_start(atomic_t * p_atomic);
+
+/**
+ * @brief Exits atomic section
+ *
+ * @details Restores status register
+ *
+ * @param[in] p_atomic pointer to buffer to restore current value of the status register from.
+ */
+void hal_atomic_end(atomic_t * p_atomic);
+
+/** @} */
+
+#endif // HAL_ATOMIC_H_INCLUDED
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/802_15_4/api/HAL/hal_clock.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/802_15_4/api/HAL/hal_clock.h
new file mode 100644
index 0000000..bd22d51
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/802_15_4/api/HAL/hal_clock.h
@@ -0,0 +1,59 @@
+/**
+ * Copyright (c) 2016 - 2018 Nordic Semiconductor ASA and Luxoft Global Operations Gmbh.
+ *
+ * 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#ifndef HAL_CLOCK_H_INCLUDED
+#define HAL_CLOCK_H_INCLUDED
+
+/**
+ * @defgroup hal_clock HAL Clock API
+ * @ingroup hal_15_4
+ * @{
+ * @brief Module to declare HAL Clock library
+ */
+
+/** @brief This function performs initialization and configuration of processor's
+ * clock module.
+ */
+void hal_clock_init(void);
+
+/** @} */
+
+#endif /* HAL_CLOCK_H_INCLUDED */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/802_15_4/api/HAL/hal_debug_interface.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/802_15_4/api/HAL/hal_debug_interface.h
new file mode 100644
index 0000000..df602b2
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/802_15_4/api/HAL/hal_debug_interface.h
@@ -0,0 +1,113 @@
+/**
+ * Copyright (c) 2016 - 2018 Nordic Semiconductor ASA and Luxoft Global Operations Gmbh.
+ *
+ * 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#ifndef HAL_DEBUG_INTERFACE_H_INCLUDED
+#define HAL_DEBUG_INTERFACE_H_INCLUDED
+
+
+#if defined(NRF52) || defined(NRF52840_XXAA)
+
+#include "nrf_assert.h"
+
+#endif // NRF52
+
+/**
+ * @defgroup hal_debug_interface HAL Debug Interface
+ * @ingroup hal_15_4
+ * @{
+ * @brief Module to declare HAL debug interface
+ */
+
+#ifdef CONFIG_DEBUG
+
+#include <stdint.h>
+
+#define HAL_DEBUG_INTERFACE_INIT() hal_debug_init()
+#define HAL_DEBUG_INTERFACE_PUT(c, n) hal_debug_put(c, n)
+#define HAL_DEBUG_INTERFACE_PUTC(c) hal_debug_putc(c)
+#define HAL_DEBUG_INTERFACE_PUTS(s) hal_debug_puts(s)
+
+/**
+ * @brief Debug interface initialization
+ */
+void hal_debug_init(void);
+
+/**
+ * @brief Sends string to the debug interface
+ *
+ * @details send debug data using debug interface
+ *
+ * @param[in] p_data debug string.
+ * @param[in] len string length.
+ */
+void hal_debug_put(const void * p_data, uint8_t len);
+
+/**
+ * @brief Sends char symbol to the debug interface
+ *
+ * @details send debug data using debug interface
+ *
+ * @param[in] data char symbol.
+ */
+void hal_debug_putc(const char data);
+
+/**
+ * @brief Sends a null-terminated string to the debug interface
+ *
+ * @details send debug data using debug interface
+ *
+ * @param[in] p_data null-terminated string.
+ */
+void hal_debug_puts(const char * p_data);
+
+#else
+
+/* If debug is disabled, these macros are just a stub.*/
+#define HAL_DEBUG_INTERFACE_INIT()
+#define HAL_DEBUG_INTERFACE_PUT(c, n)
+#define HAL_DEBUG_INTERFACE_PUTC(c)
+#define HAL_DEBUG_INTERFACE_PUTS(s)
+
+#endif // CONFIG_DEBUG
+
+/** @} */
+
+#endif // HAL_DEBUG_INTERFACE_H_INCLUDED
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/802_15_4/api/HAL/hal_delay.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/802_15_4/api/HAL/hal_delay.h
new file mode 100644
index 0000000..60d59c3
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/802_15_4/api/HAL/hal_delay.h
@@ -0,0 +1,65 @@
+/**
+ * Copyright (c) 2016 - 2018 Nordic Semiconductor ASA and Luxoft Global Operations Gmbh.
+ *
+ * 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#ifndef HAL_DELAY_H_INCLUDED
+#define HAL_DELAY_H_INCLUDED
+
+#include <stdint.h>
+
+/** @file
+ * This file contains declaration of the Hardware Delay routine.
+ *
+ * @defgroup hal_delay HAL Delay API
+ * @ingroup hal_15_4
+ * @{
+ * @brief Module to declare HAL Delay API
+ * @details The Delay module implements the only hal_delay() routine to delay the execution for some microseconds.
+ */
+
+/**@brief Function for delaying execution for number of microseconds.
+ *
+ * @param[in] number_of_us number of microseconds to delay.
+ */
+void hal_delay(uint32_t number_of_us);
+
+/** @} */
+
+#endif // HAL_DELAY_H_INCLUDED
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/802_15_4/api/HAL/hal_led.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/802_15_4/api/HAL/hal_led.h
new file mode 100644
index 0000000..be99ff0
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/802_15_4/api/HAL/hal_led.h
@@ -0,0 +1,54 @@
+/**
+ * Copyright (c) 2016 - 2018 Nordic Semiconductor ASA and Luxoft Global Operations Gmbh.
+ *
+ * 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#ifndef HAL_LED_H_INCLUDED
+#define HAL_LED_H_INCLUDED
+
+#include <stdint.h>
+
+#define HAL_LED_AMOUNT 4
+
+void hal_led_init(uint32_t led_mask);
+void hal_led_on(uint32_t led_mask);
+void hal_led_off(uint32_t led_mask);
+void hal_led_toggle(uint32_t led_mask);
+
+#endif /* HAL_LED_H_INCLUDED */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/802_15_4/api/HAL/hal_mutex.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/802_15_4/api/HAL/hal_mutex.h
new file mode 100644
index 0000000..a8ddd27
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/802_15_4/api/HAL/hal_mutex.h
@@ -0,0 +1,89 @@
+/**
+ * Copyright (c) 2016 - 2018 Nordic Semiconductor ASA and Luxoft Global Operations Gmbh.
+ *
+ * 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#ifndef HAL_MUTEX_H_INCLUDED
+#define HAL_MUTEX_H_INCLUDED
+
+#include "hal_atomic.h"
+
+/** @file
+ * This is a simple mutex interface to be used in System Memory Manager
+ * to make it thread aware.
+ *
+ * @defgroup hal_mutex HAL Mutex API
+ * @ingroup hal_15_4
+ * @{
+ * @details NRF52 implementation is void and PC implementation is identical to atomic.
+ */
+
+
+#if defined ( __GNUC__ )
+#include <signal.h>
+typedef volatile sig_atomic_t mutex_t;
+#else
+#include <stdint.h>
+typedef volatile uint32_t mutex_t;
+#endif
+
+
+/**@brief Configures mutex lock before first usage.
+ *
+ * @param[inout] p_mutex pointer to mutex variable.
+ */
+void hal_mutex_init(mutex_t * p_mutex);
+
+/**@brief Atomically sets mutex. If set is failed, enters spin lock loop.
+ *
+ * @param[in] p_mutex pointer to mutex variable.
+ */
+void hal_mutex_lock(mutex_t * p_mutex);
+
+/**
+ * @brief Atomically clears mutex. Every other thread, spinning at this lock may
+ * try to lock it afterwards.
+ *
+ * @param[in] p_mutex pointer to mutex variable.
+ */
+void hal_mutex_unlock(mutex_t * p_mutex);
+
+/** @} */
+
+#endif /* HAL_MUTEX_H_INCLUDED */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/802_15_4/api/HAL/hal_rng.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/802_15_4/api/HAL/hal_rng.h
new file mode 100644
index 0000000..1aa7268
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/802_15_4/api/HAL/hal_rng.h
@@ -0,0 +1,70 @@
+/**
+ * Copyright (c) 2016 - 2018 Nordic Semiconductor ASA and Luxoft Global Operations Gmbh.
+ *
+ * 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#ifndef HAL_RNG_H_INCLUDED
+#define HAL_RNG_H_INCLUDED
+
+#include <stdint.h>
+
+/** @file
+ * This file contains declaration of the random number generator routine.
+ *
+ * @defgroup hal_rng HAL Random Number Generator API
+ * @ingroup hal_15_4
+ * @{
+ * @brief Module to declare HAL Random Number Generator API
+ * @details The Random number generator module implements the only hal_rand_get() routine to get an unsigned 8-bits
+ * random number generated by hardware.
+ */
+
+/**@brief Initialize hardware random generator.
+ */
+extern void hal_rand_init(void);
+
+/**@brief Generates random number using hardware.
+ *
+ * @return An unsigned 8-bits random number.
+ */
+extern uint8_t hal_rand_get(void);
+
+/** @} */
+
+#endif /* HAL_RNG_H_INCLUDED */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/802_15_4/api/HAL/hal_sleep.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/802_15_4/api/HAL/hal_sleep.h
new file mode 100644
index 0000000..5d2f43f
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/802_15_4/api/HAL/hal_sleep.h
@@ -0,0 +1,100 @@
+/**
+ * Copyright (c) 2016 - 2018 Nordic Semiconductor ASA and Luxoft Global Operations Gmbh.
+ *
+ * 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#ifndef HAL_SLEEP_H_INCLUDED
+#define HAL_SLEEP_H_INCLUDED
+
+#include <stdint.h>
+
+/** @file
+ * This file contains declaration of the HAL sleep interface.
+ *
+ * @defgroup hal_sleep HAL Sleep API
+ * @ingroup hal_15_4
+ * @{
+ * @brief Module to declare HAL Sleep API
+ * @details The Sleep module implements the only hal_sleep() routine to put the hardware to the sleep mode for some
+ * milliseconds. The user can use convenient macros DAYS_TO_MS(), HOURS_TO_MS(), MINS_TO_MS(), and SEC_TO_MS()
+ * to convert different time periods into milliseconds. Please note that this module requires a call to
+ * hal_sleep_init() which is in turn called by sys_init() before using any module routines. This module is
+ * only used to implement the System Sleep interface. The hal_sleep() routine is not assumed to be used by
+ * the user explicitly.
+ */
+
+/**@brief Converts days to milliseconds */
+#define DAYS_TO_MS(d) ((d) * 3600L * 24L * 1000L )
+
+/**@brief Converts hours to milliseconds */
+#define HOURS_TO_MS(h) ((h) * 3600L * 1000L )
+
+/**@brief Converts minutes to milliseconds */
+#define MINS_TO_MS(m) ((m) * 60L * 1000L )
+
+/**@brief Converts seconds to milliseconds */
+#define SEC_TO_MS(s) ((s) * 1000L )
+
+/**@brief Information, provided by the HAL, in order to explain the reason,
+ * which caused the system to wake up.
+ */
+typedef enum
+{
+ UNKNOWN_INTERRUPT, /**< HAL can't define a wake up reason */
+ RTC_CC_INTERRUPT /**< RTC interrupt was the awakening reason */
+} hal_wakeup_reason_t;
+
+
+/**@brief Puts hardware into the sleep mode for some milliseconds.
+ *
+ * @param[in] sleep_time_ms Time to sleep in ms
+ *
+ * @retval wakeup_reason Specifies reason of awakening
+ */
+hal_wakeup_reason_t hal_sleep(uint32_t sleep_time_ms);
+
+
+/**@brief Initialization of the sleep module
+ *
+ */
+void hal_sleep_init(void);
+
+/** @} */
+
+#endif /* HAL_SLEEP_H_INCLUDED */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/802_15_4/api/HAL/hal_task_scheduler.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/802_15_4/api/HAL/hal_task_scheduler.h
new file mode 100644
index 0000000..f7442b3
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/802_15_4/api/HAL/hal_task_scheduler.h
@@ -0,0 +1,124 @@
+/**
+ * Copyright (c) 2016 - 2018 Nordic Semiconductor ASA and Luxoft Global Operations Gmbh.
+ *
+ * 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#ifndef HAL_TASK_H_INCLUDED
+#define HAL_TASK_H_INCLUDED
+
+#include <stdint.h>
+#include "hal_atomic.h"
+#include "sys_utils.h"
+#include "sys_task_scheduler.h"
+
+/**
+ * @defgroup hal_task HAL Tasks
+ * @ingroup hal_15_4
+ * @{
+ * @brief Module to declare HAL tasks library
+ */
+
+/**@brief Identifiers for registered HAL handlers.
+ *
+ * @details enumeration with identifiers of registered HAL handlers.
+ * HAL handlers will be called from the HAL task.
+ */
+typedef enum
+{
+ HAL_TIMER_TASK_ID,
+ HAL_UART_TASK_ID,
+ HAL_TIMER_CRITICAL_MANUAL_TASK,
+ HAL_TASKS_AMOUNT,
+} hal_task_id_t;
+
+
+/**@brief Prototype of a HAL task handler.
+ *
+ * @details Handler which will be called from HAL task.
+ */
+typedef void (* hal_task_handler_t)(void);
+
+
+void hal_task_handler(void);
+void hal_timer_task_handler(void);
+void hal_uart_task_handler(void);
+void hal_timer_critical_manual_handler(void);
+
+/**@brief Pending HAL tasks.
+ *
+ * @details Variable which includes markers of pending HAL tasks.
+ */
+extern volatile uint_fast16_t g_hal_tasks;
+
+
+/**@brief Notify task scheduler to add a HAL task for execution.
+ *
+ * @details The function sets a marker for the HAL task for execution.
+ *
+ * @param[in] hal_task_id HAL task identifier (see \ref hal_task_id_t enumeration).
+ */
+static inline void hal_task_post(hal_task_id_t hal_task_id)
+{
+ atomic_t atomic = 0;
+
+ hal_atomic_start(&atomic);
+ g_hal_tasks |= BIT(hal_task_id);
+ hal_atomic_end(&atomic);
+
+ sys_task_post(HAL_TASK_ID);
+}
+
+/**@brief Removes a task from pending list in HAL task scheduler.
+ *
+ * @details The function removes a marker from the HAL execution list.
+ *
+ * @param[in] hal_task_id HAL task identifier (see \ref hal_task_id_t enumeration).
+ */
+static inline void hal_task_unpost(hal_task_id_t hal_task_id)
+{
+ atomic_t atomic = 0;
+
+ hal_atomic_start(&atomic);
+ g_hal_tasks &= ~BIT(hal_task_id);
+ hal_atomic_end(&atomic);
+}
+
+ /** @} */
+
+#endif // HAL_TASK_H_INCLUDED
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/802_15_4/api/HAL/hal_timer.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/802_15_4/api/HAL/hal_timer.h
new file mode 100644
index 0000000..d34e8a3
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/802_15_4/api/HAL/hal_timer.h
@@ -0,0 +1,80 @@
+/**
+ * Copyright (c) 2016 - 2018 Nordic Semiconductor ASA and Luxoft Global Operations Gmbh.
+ *
+ * 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#ifndef HAL_TIMER_H_INCLUDED
+#define HAL_TIMER_H_INCLUDED
+
+#include "hal_delay.h"
+#include <stdint.h>
+
+/**
+ * @defgroup hal_timer HAL Timer
+ * @ingroup hal_15_4
+ * @{
+ * @brief Module to declare HAL timer interface
+ */
+
+/**@brief Initializes hardware timer.
+ */
+void hal_timer_init(void);
+
+
+/**@brief Starts hardware timer.
+ *
+ * @param[in] interval timer interval in microseconds for timer start.
+ */
+void hal_timer_start(uint64_t interval);
+
+
+/**@brief Stops hardware timer.
+ */
+void hal_timer_stop(void);
+
+
+/**@brief Reads microseconds passed since the device start.
+ *
+ * @return time in microseconds since the device was launched.
+ */
+uint64_t hal_time_get(void);
+
+ /** @} */
+
+#endif /* HAL_TIMER_H_INCLUDED */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/802_15_4/api/HAL/hal_timer_critical.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/802_15_4/api/HAL/hal_timer_critical.h
new file mode 100644
index 0000000..05241cd
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/802_15_4/api/HAL/hal_timer_critical.h
@@ -0,0 +1,82 @@
+/**
+ * Copyright (c) 2016 - 2018 Nordic Semiconductor ASA and Luxoft Global Operations Gmbh.
+ *
+ * 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#ifndef HAL_TIMER_CRITICAL_H_INCLUDED
+#define HAL_TIMER_CRITICAL_H_INCLUDED
+
+#include <stdint.h>
+#include <stdbool.h>
+
+/**
+ * @defgroup hal_timer_critical HAL Hardware Critical Timer
+ * @ingroup hal_15_4
+ * @{
+ * @brief Module to declare HAL hardware critical timer interface
+ */
+
+/**@brief Prototype for critical timer handler.
+ */
+typedef void (* hal_timer_critical_handler_t)(void);
+
+
+/**@brief Starts hardware critical timer.
+ *
+ * @param[in] interval_us timer interval for timer start.
+ * @param[in] handler critical timer event handler.
+ */
+void hal_timer_critical_start(uint32_t interval_us, hal_timer_critical_handler_t handler);
+
+
+/**@brief Stops hardware critical timer.
+ */
+void hal_timer_critical_stop(void);
+
+
+/**@brief Check if critical timer is currently used.
+ *
+ * @retval timer_state true - timer is running now
+ * false - timer in stop mode
+ */
+bool is_critical_timer_started(void);
+
+/** @} */
+
+#endif /* HAL_TIMER_CRITICAL_H_INCLUDED */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/802_15_4/api/HAL/hal_trace_interface.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/802_15_4/api/HAL/hal_trace_interface.h
new file mode 100644
index 0000000..e983098
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/802_15_4/api/HAL/hal_trace_interface.h
@@ -0,0 +1,103 @@
+/**
+ * Copyright (c) 2016 - 2018 Nordic Semiconductor ASA and Luxoft Global Operations Gmbh.
+ *
+ * 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#ifndef HAL_TRACE_INTERFACE_H_INCLUDED
+#define HAL_TRACE_INTERFACE_H_INCLUDED
+
+/**
+ * @defgroup hal_trace_interface HAL Trace Interface
+ * @ingroup hal_15_4
+ * @{
+ * @brief Module to declare HAL Trace Interface
+ */
+
+#ifdef CONFIG_TRACE
+
+#include "hal_uart.h"
+
+
+#define HAL_TRACE_INTERFACE_REUSE(p_uart_desc) hal_trace_reuse(p_uart_desc)
+#define HAL_TRACE_INTERFACE_INIT() hal_trace_init()
+#define HAL_TRACE_INTERFACE_PUTS(s) hal_trace_puts(s)
+#define HAL_TRACE_INTERFACE_FINALIZE() hal_trace_finalize()
+
+/**
+ * @brief Trace interface initialization
+ */
+void hal_trace_init(void);
+
+/**
+ * @brief Initializes trace interface, using already initialized UART.
+ *
+ * @param[in] p_uart_desc UART descriptor, which has been already initialized.
+ */
+void hal_trace_reuse(hal_uart_descriptor_t * p_uart_desc);
+
+/**
+ * @brief Sends a null-terminated string to the debug interface
+ *
+ * @details send debug data using debug interface
+ *
+ * @param[in] p_data null-terminated string.
+ */
+void hal_trace_puts(const char * p_data);
+
+
+/**
+ * @brief Finalizes buffered trace data output to UART,
+ * before commencing non-buffered assertion output
+ */
+void hal_trace_finalize(void);
+
+
+#else
+
+/* If debug is disabled, these macros are just a stub.*/
+#define HAL_TRACE_INTERFACE_REUSE(p_uart_desc)
+#define HAL_TRACE_INTERFACE_INIT()
+#define HAL_TRACE_INTERFACE_PUTS(s)
+#define HAL_TRACE_INTERFACE_FINALIZE()
+
+#endif // CONFIG_DEBUG
+
+/** @} */
+
+#endif // HAL_TRACE_INTERFACE_H_INCLUDED
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/802_15_4/api/HAL/hal_uart.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/802_15_4/api/HAL/hal_uart.h
new file mode 100644
index 0000000..caaf47d
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/802_15_4/api/HAL/hal_uart.h
@@ -0,0 +1,284 @@
+/**
+ * Copyright (c) 2016 - 2018 Nordic Semiconductor ASA and Luxoft Global Operations Gmbh.
+ *
+ * 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#ifndef HAL_UART_H_INCLUDED
+#define HAL_UART_H_INCLUDED
+
+#include <stdint.h>
+#include <stdlib.h>
+#include <limits.h>
+
+/** @file
+ * This file contains declarations of the routines, types and macros to implement the UART protocol.
+ *
+ * @defgroup hal_uart HAL UART protocol
+ * @ingroup hal_15_4
+ * @{
+ * @brief Module to declare HAL UART protocol
+ * @details The UART module implements the standard UART driver API. This includes open/close via hal_uart_open(),
+ * hal_uart_close(), read/write via hal_uart_read(), hal_uart_write() routines, and hal_uart_puts() for
+ * sending a null-terminated string in a non-blocking way. The user also can get some info about the available
+ * bytes for read/write via hal_uart_read_buffer_size_get() and hal_uart_write_buffer_size_get(). This implies
+ * that the user may register read/write buffers to use for buffered input/output and handler routines that
+ * will be called upon read/written characters. Also the most popular settings of the UART driver are supported:
+ * different baudrates, parity checks, flow control, character size, and stop bits.
+ */
+
+/** @brief Maximum size in bytes of input and output buffers. */
+#define MAX_QUEUE_LENGTH 0xffffu
+
+/** @brief Maximum size in bytes of data can be stored in hardware unit output buffer. */
+#define MAX_TX_CHUNK_SIZE UCHAR_MAX
+
+/** @brief UART baudrate. */
+typedef enum
+{
+ HAL_UART_BAUDRATE_38400, /**< 38400 bits per second.*/
+ HAL_UART_BAUDRATE_115200, /**< 115200 bits per second.*/
+ HAL_UART_BAUDRATE_230400 /**< 230400 bits per second.*/
+} hal_uart_baudrate_t;
+
+/** @brief UART parity check. */
+typedef enum
+{
+ HAL_UART_PARITY_NONE, /**< Do not check parity.*/
+ HAL_UART_PARITY_EVEN /**< Check even parity.*/
+} hal_uart_parity_t;
+
+/** @brief UART flow control. */
+typedef enum
+{
+ HAL_UART_FLOW_CONTROL_DISABLED, /**< Flow control is disabled.*/
+ HAL_UART_FLOW_CONTROL_ENABLED, /**< Flow control is enabled.*/
+} hal_uart_flow_control_t;
+
+/** @brief UART character size settings. */
+typedef enum
+{
+ HAL_UART_FIVE_BITS_CHAR = 5, /**< 5 bits character.*/
+ HAL_UART_SIX_BITS_CHAR, /**< 6 bits character.*/
+ HAL_UART_SEVEN_BITS_CHAR, /**< 7 bits character.*/
+ HAL_UART_EIGHT_BITS_CHAR, /**< 8 bits character.*/
+} hal_uart_char_size_t;
+
+/** @brief UART stop bits settings. */
+typedef enum
+{
+ HAL_UART_ONE_STOP_BIT, /**< 1 stop bit.*/
+ HAL_UART_ONEHALF_STOP_BITS, /**< 1.5 stop bits.*/
+ HAL_UART_TWO_STOP_BITS, /**< 2 stop bits.*/
+} hal_uart_stop_bits_t;
+
+/** @brief Represents error source for the UART driver. There might be other values,
+ * representing clearer elaborating of error statuses, if this module is used
+ * with Windows or Linux.
+ */
+typedef enum
+{
+ HAL_UART_ERROR_NONE = 0, /**< Success.*/
+ HAL_UART_ERROR_TX_OVERFLOW = 252, /**< This error happens when amount of elements in
+ the transmitter ring buffer exceeds its size.
+ All the data above limit is not placed into
+ buffer.*/
+ HAL_UART_ERROR_RX_OVERFLOW = 253, /**< This error happens when amount of elements in
+ the receiver ring buffer exceeds its size.
+ All the unread data is overwritten with new
+ received data.*/
+ HAL_UART_ERROR_RX_UNDERFLOW = 254, /**< This error happens when the user-side software
+ tries to read more elements than it is available
+ in the receive buffer.
+ The user-side buffer will be filled with all available
+ characters and then the error handler is started.*/
+ HAL_UART_ERROR_HW_ERROR = 255, /**< There is some unrecoverable error in hardware.*/
+} hal_uart_error_t;
+
+/**
+ * @brief User-side handler of UART read and write events.
+ *
+ * @param[in] channel event channel number.
+ * @param[in] char_count number of characters successfully sent before entering
+ * the callback function.
+ */
+typedef void (*hal_uart_handler_t)(uint32_t channel, size_t char_count);
+
+/**
+ * @brief User-side handler for UART error events.
+ *
+ * @param[in] channel event channel number.
+ * @param[in] error_id call reason.
+ */
+typedef void (*hal_uart_error_handler_t)(uint32_t channel, hal_uart_error_t error_id);
+
+/** @brief HAL UART configuration structure.
+ */
+typedef struct
+{
+ uint32_t module; /**< UART module number. By now zero
+ is the only option.*/
+ uint32_t tx_pin; /**< Number of pin used as TX.*/
+ uint32_t rx_pin; /**< Number of pin used as RX.*/
+ uint32_t cts_pin; /**< Number of pin used as CTS.*/
+ uint32_t rts_pin; /**< Number of pin used as RTS.*/
+ hal_uart_baudrate_t baudrate; /**< Baudrate selector.*/
+ hal_uart_parity_t parity; /**< Parity selector.*/
+ hal_uart_flow_control_t flow_control; /**< Flow control selector.*/
+ hal_uart_char_size_t char_size; /**< Size of char in bits.*/
+ hal_uart_stop_bits_t stop_bits; /**< Stop bits number.*/
+} hal_uart_config_t;
+
+/**
+ * @brief This structure defines the UART module operation.
+ *
+ * If \a write_buffer_ptr is defined as NULL, then sending data will work
+ * in blocking way, that is call for \a hal_uart_write will be completed
+ * only after sending of the last byte passed as input parameter.
+ *
+ * If \a read_buffer_ptr is defined as NULL, then driver will drop every
+ * received byte.
+ */
+typedef struct
+{
+ hal_uart_config_t uart_config; /**< UART settings struct.*/
+ hal_uart_handler_t write_handler; /**< Callback function for write operation.*/
+ void * write_buffer_ptr; /**< User-side buffer for write operation.*/
+ size_t write_buffer_size; /**< Size of write operation buffer.*/
+ hal_uart_handler_t read_handler; /**< Callback function for read operation.*/
+ void * read_buffer_ptr; /**< User-side buffer for read operation.*/
+ size_t read_buffer_size; /**< Size of read operation buffer.*/
+ hal_uart_error_handler_t error_handler; /**< Callback function in case of something
+ goes wrong.*/
+} hal_uart_descriptor_t;
+
+/**
+ * @brief Configures UART interface using input parameter.
+ *
+ * @param[in] config pointer to a config struct.
+ * @param[in] descriptor pointer to a descriptor struct.
+ *
+ * @return Return status of operation.
+ */
+hal_uart_error_t hal_uart_open(const hal_uart_config_t * config,
+ const hal_uart_descriptor_t * descriptor);
+
+/**
+ * @brief Sends data in a non-blocking way.
+ *
+ * @param[in] descriptor pointer to the UART module operation structure.
+ * @param[in] data pointer to the user-side buffer of output data.
+ * @param[in] length number of bytes to transmit.
+ *
+ * If descriptor has a non-null \a write_buffer_ptr then this function will use it
+ * as a temporary buffer and will copy input \a data to it before starting
+ * transmit. If descriptor has the NULL \a write_buffer_ptr, then the user-side code
+ * is responsible to retain \a data until \a write_handler is called.
+ */
+void hal_uart_write(const hal_uart_descriptor_t * descriptor,
+ const uint8_t * data,
+ const size_t length);
+
+/**
+ * @brief Sends a null-terminated C-string in a non-blocking way.
+ *
+ * @param[in] descriptor pointer to the UART module operation structure.
+ * @param[in] s null-terminated string to send.
+ */
+void hal_uart_puts(const hal_uart_descriptor_t * descriptor, const char * s);
+
+/**
+ * @brief Receives data in a non-blocking way.
+ *
+ * @param[in] descriptor pointer to the UART module operation structure.
+ * @param[out] data pointer to the user-side buffer used to receive data.
+ * @param[in] length number of bytes to receive.
+ *
+ * If descriptor has a non-null \a read_buffer_ptr, then this function is used to
+ * copy input characters from it to \a data.
+ * If \a read_buffer_ptr is NULL, then this function ignores all inputs.
+ */
+void hal_uart_read(const hal_uart_descriptor_t * descriptor,
+ uint8_t * data,
+ const size_t length);
+
+/**
+ * @brief Returns number of bytes available to read from the income buffer of the
+ * driver.
+ *
+ * @param[in] descriptor pointer to driver structure.
+ *
+ * @return Number of bytes available to read.
+ */
+size_t hal_uart_read_buffer_size_get(const hal_uart_descriptor_t * descriptor);
+
+/**
+ * @brief Returns number of bytes available to write to the outgoing buffer of the
+ * driver.
+ *
+ * @param[in] descriptor pointer to driver structure.
+ *
+ * @return Number of bytes available to write.
+ */
+size_t hal_uart_write_buffer_size_get(const hal_uart_descriptor_t * descriptor);
+
+/**
+ * @brief This function deallocates resources previously allocated by hal_uart_open.
+ *
+ * @param[in] descriptor pointer to driver structure.
+ *
+ * @return Return status of operation.
+ */
+hal_uart_error_t hal_uart_close(const hal_uart_descriptor_t * descriptor);
+
+
+#if defined(CONFIG_TRACE) && defined(CONFIG_DEBUG)
+
+/**
+ * @brief Finalizes remaining trace data output to UART.
+ *
+ * @details This debugging feature is needed to finalize buffered trace output
+ * to UART before commencing non-buffered assertion output.
+ */
+void hal_uart_trace_finalize(void);
+
+#endif
+
+/** @} */
+
+#endif /* HAL_UART_H_INCLUDED */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/802_15_4/api/HAL/hal_uart_task_scheduler.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/802_15_4/api/HAL/hal_uart_task_scheduler.h
new file mode 100644
index 0000000..9a708cf
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/802_15_4/api/HAL/hal_uart_task_scheduler.h
@@ -0,0 +1,105 @@
+/**
+ * Copyright (c) 2016 - 2018 Nordic Semiconductor ASA and Luxoft Global Operations Gmbh.
+ *
+ * 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#ifndef HAL_UART_TASK_SCHEDULER_H_INCLUDED
+#define HAL_UART_TASK_SCHEDULER_H_INCLUDED
+
+#include <stdint.h>
+#include "hal_atomic.h"
+#include "hal_task_scheduler.h"
+#include "sys_utils.h"
+
+/**
+ * @defgroup hal_uart_task_scheduler HAL UART Task Scheduler
+ * @ingroup hal_15_4
+ * @{
+ * @brief Module to declare HAL UART Task Scheduler interface
+ */
+
+/**@brief Identifiers for registered UART event handlers.
+ *
+ * @details enumeration with identifiers of registered UART event handlers.
+ * UART handlers will be called from the HAL_UART task. */
+typedef enum
+{
+ HAL_UART_RX_TASK_ID,
+ HAL_UART_TX_TASK_ID,
+ HAL_UART_ERROR_TASK_ID,
+ HAL_UART_TASKS_AMOUNT,
+} hal_uart_task_id_t;
+
+/**@brief Prototype of a UART task handler.
+ *
+ * @details Handler which will be called from HAL_UART task. */
+typedef void (* hal_uart_task_handler_t)(uint32_t channel);
+
+void hal_uart_rx_handler(uint32_t channel);
+void hal_uart_tx_handler(uint32_t channel);
+void hal_uart_error_handler(uint32_t channel);
+
+/**@brief UART channels.
+ *
+ * @details Array which includes event id for every channel it happened. */
+extern volatile uint16_t g_hal_uart_modules_tasks[CONFIG_HAL_UART_CHANNELS];
+
+
+/**@brief Notifies HAL task scheduler to add an UART task for execution.
+ *
+ * @details The function sets a marker for the UART event task for execution.
+ * And sets this marker for a channel where event happened.
+ *
+ * @param[in] channel event channel.
+ * @param[in] hal_uart_task_id HAL task identificator. */
+static inline void hal_uart_task_post(uint32_t channel,
+ uint8_t hal_uart_task_id)
+{
+ atomic_t atomic = 0;
+
+ hal_atomic_start(&atomic);
+ g_hal_uart_modules_tasks[channel] |= BIT(hal_uart_task_id);
+ hal_atomic_end(&atomic);
+
+ hal_task_post(HAL_UART_TASK_ID);
+}
+
+/** @} */
+
+#endif /* HAL_UART_TASK_SCHEDULER_H_INCLUDED */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/802_15_4/api/HAL/nrf52_soc/hal_nrf52_exceptions.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/802_15_4/api/HAL/nrf52_soc/hal_nrf52_exceptions.h
new file mode 100644
index 0000000..1599034
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/802_15_4/api/HAL/nrf52_soc/hal_nrf52_exceptions.h
@@ -0,0 +1,90 @@
+/**
+ * Copyright (c) 2016 - 2018 Nordic Semiconductor ASA and Luxoft Global Operations Gmbh.
+ *
+ * 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#ifndef HAL_EXCEPTIONS_H_INCLUDED
+#define HAL_EXCEPTIONS_H_INCLUDED
+
+#include <stdint.h>
+
+/**
+ * @defgroup hal_15_4_nrf52 Chip-specific library interface
+ * @ingroup hal_15_4
+ *
+ * @defgroup hal_nrf52_exceptions HAL exceptions
+ * @ingroup hal_15_4_nrf52
+ * @{
+ */
+
+/** @brief Size of stack dump in 4-byte words.*/
+#define HAL_EXCEPTIONS_DUMP_SIZE 16
+/** @brief Defines where to put a '\n' in stack dump.
+ *
+ * This value defines power of 2 items in one row.
+ * E.g. 3 gives 2 ^ 3 = 8 items in a row.*/
+#define HAL_EXCEPTIONS_ITEMS_IN_LINE 3
+
+/** @brief This structure holds values of fault status registers.*/
+typedef struct
+{
+ uint32_t CFSR; /*!< Configurable Fault Status Register.*/
+ uint32_t HFSR; /*!< HardFault Status Register.*/
+ uint32_t DFSR; /*!< Debug Fault Status Register.*/
+ uint32_t AFSR; /*!< Auxiliary Fault Status Register.*/
+} hal_exceptions_status_registers_t;
+
+/** @brief This structure is put into dump monitor port and holds values of said
+ * registers when exception has happen.*/
+typedef struct
+{
+ uint32_t R0; /**< Register R0 (Argument 1 / word result).*/
+ uint32_t R1; /**< Register R1 (Argument 2 / double-word result).*/
+ uint32_t R2; /**< Register R2 (Argument 3).*/
+ uint32_t R3; /**< Register R3 (Argument 4).*/
+ uint32_t R12; /**< Register R12 (Scratch register (corruptible)).*/
+ uint32_t LR; /**< Link register (R14).*/
+ uint32_t PC; /**< Program counter (R15).*/
+ uint32_t PSR; /**< Combined processor status register.*/
+ uint32_t* FP; /**< Value of register, which may be used as Frame Pointer.*/
+} hal_exceptions_dump_t;
+
+/** @} */
+
+#endif // HAL_EXCEPTIONS_H_INCLUDED
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/802_15_4/api/HAL/nrf52_soc/hal_nrf52_rtc.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/802_15_4/api/HAL/nrf52_soc/hal_nrf52_rtc.h
new file mode 100644
index 0000000..1729834
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/802_15_4/api/HAL/nrf52_soc/hal_nrf52_rtc.h
@@ -0,0 +1,107 @@
+/**
+ * Copyright (c) 2016 - 2018 Nordic Semiconductor ASA and Luxoft Global Operations Gmbh.
+ *
+ * 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#ifndef HAL_NRF52_RTC_H_INCLUDED
+#define HAL_NRF52_RTC_H_INCLUDED
+
+#include "nordic_common.h"
+#include "nrf_drv_config.h"
+#include "nrf_drv_common.h"
+#include "nrf_drv_rtc.h"
+#include "nrf_rtc.h"
+
+/**
+ * @defgroup hal_nrf52_rtc HAL RTC
+ * @ingroup hal_15_4_nrf52
+ * @{
+ */
+
+// RTC counter bitlenght
+#define LAGEST_PRESCALER_VALUE 4096
+// RTC counter bitlenght
+#define RTC_CNT_BITLENGHT 24
+// Longest sleep time, ms
+#define LONGEST_SLEEP_TIME ((( 1UL << RTC_CNT_BITLENGHT ) \
+ /(RTC_INPUT_FREQ/LAGEST_PRESCALER_VALUE)) * 1000UL )
+
+// Shortest sleep time, ms
+#define SHORTEST_SLEEP_TIME 1
+
+/**@brief Function for initialize low frequency clock
+ */
+void rtc_lfclk_start(void);
+
+
+/** @brief Function initialization and configuration of RTC driver instance.
+ *
+ * @param[in] sleep_time_ms after this time compare event will be triggered
+ */
+void rtc_start(uint32_t sleep_time_ms);
+
+/** @brief Stop RTC
+ */
+void rtc_stop(void);
+
+/** @brief Get RTC counter
+ *
+ * @retval uint32_t Contents of RTC counter register.
+ */
+uint32_t rtc_cnt_get(void);
+
+/** @brief Get time elapsed since cnt_ticks
+ *
+ * @param[in] cnt_ticks Number of rtc-ticks
+ *
+ * @retval uint32_t Time since cnt_ticks, ms
+ */
+uint64_t get_rtc_time_since(uint32_t cnt_ticks);
+
+/** @brief Check if rtc compare interrupt was triggered after calling
+ * rtc_start function
+ *
+ * @retval bool true - compare interrupt was triggered
+ * false - it wasn't
+ */
+bool is_rtc_comp_irq_triggerd(void);
+
+/** @} */
+
+#endif /* HAL_NRF52_RTC_H_INCLUDED */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/802_15_4/api/HAL/nrf52_soc/hal_nrf52_timer.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/802_15_4/api/HAL/nrf52_soc/hal_nrf52_timer.h
new file mode 100644
index 0000000..a008244
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/802_15_4/api/HAL/nrf52_soc/hal_nrf52_timer.h
@@ -0,0 +1,75 @@
+/**
+ * Copyright (c) 2016 - 2018 Nordic Semiconductor ASA and Luxoft Global Operations Gmbh.
+ *
+ * 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#ifndef HAL_NRF52_TIMER_INCLUDED
+#define HAL_NRF52_TIMER_INCLUDED
+
+/**
+ * @defgroup hal_nrf52_timer HAL timer - additional features
+ * @ingroup hal_15_4_nrf52
+ * @{
+ */
+
+/**@brief Pause hardware timer.
+ */
+void hal_timer_pause(void);
+
+
+/**@brief Resume hardware timer.
+ */
+void hal_timer_resume(void);
+
+
+/**@brief Set a new system time
+ *
+ * @param[in] time_us time to set.
+ */
+void hal_time_adjust(uint64_t time_us);
+
+
+/**@brief Uninit hardwware timer
+ */
+void hal_timer_uninit(void);
+
+/** @} */
+
+
+#endif /* HAL_NRF52_TIMER_INCLUDED */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/802_15_4/api/MAC/mac_auto_request.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/802_15_4/api/MAC/mac_auto_request.h
new file mode 100644
index 0000000..469f0e0
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/802_15_4/api/MAC/mac_auto_request.h
@@ -0,0 +1,61 @@
+/**
+ * Copyright (c) 2016 - 2018 Nordic Semiconductor ASA and Luxoft Global Operations Gmbh.
+ *
+ * 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#ifndef MAC_AUTO_REQUEST_H_INCLUDED
+#define MAC_AUTO_REQUEST_H_INCLUDED
+
+/** @file
+ *
+ * @defgroup mac_auto_request MAC auto request
+ * @ingroup mac_15_4
+ * @{
+ */
+
+/**
+ * @brief This function is called when a new beacon has been sent.
+ *
+ * @param[in] p_ind - Pointer to beacon indication structure.
+ */
+void mac_auto_request_notify_ind(mac_beacon_ind_t * p_ind);
+
+/** @} */
+
+#endif /* MAC_AUTO_REQUEST_H_INCLUDED_ */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/802_15_4/api/MAC/mac_common.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/802_15_4/api/MAC/mac_common.h
new file mode 100644
index 0000000..7ade0a2
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/802_15_4/api/MAC/mac_common.h
@@ -0,0 +1,467 @@
+/**
+ * Copyright (c) 2016 - 2018 Nordic Semiconductor ASA and Luxoft Global Operations Gmbh.
+ *
+ * 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#ifndef MAC_COMMON_H_INCLUDED
+#define MAC_COMMON_H_INCLUDED
+
+#include <stdint.h>
+#include "phy_common.h"
+
+#if (CONFIG_SECURE == 1)
+#include "mac_security.h"
+#endif
+
+/** @file
+ * Types and declarations common for different MLME transactions listed here.
+ *
+ * @defgroup mac_common MAC Common API
+ * @ingroup mac_15_4
+ * @{
+ * @brief Module for declaring MAC Common API.
+ * @details The Common MAC module contains declarations of commonly used MAC routines and necessary
+ * macros and types.
+ */
+
+/**@brief Maximum interval for acknowledgement frame to arrive in microseconds.
+ *
+ * macAckWaitDuration = aUnitBackoffPeriod(only for beacon enabled PAN) +
+ * aTurnaroundTime +
+ * phySHRDuration + ceil(6 * phySymbolsPerOctet) =
+ * 20 + 12 + 10 + 6 * 2 =
+ * 54 symbols / 62.5 ksymbols/s = 864 us (544 us for beacon disabled PAN)
+ */
+#if (CONFIG_BEACON_ENABLED == 1)
+#define macAckWaitDuration 864
+#else
+#define macAckWaitDuration 544
+#endif
+
+/**@brief The maximum number of octets added by the MAC
+ * sublayer to the MAC payload of a beacon frame.
+ */
+#define aMaxBeaconOverhead 75
+
+/**@brief The number of symbols forming the basic time period
+ * used by the CSMA-CA algorithm.
+ */
+#define aUnitBackoffPeriod 20UL
+
+/**@brief The number of symbols forming a superframe slot
+ * when the superframe order is equal to 0.
+ */
+#define aBaseSlotDuration 60UL
+
+/**@brief The number of slots contained in any superframe. */
+#define aNumSuperframeSlots 16UL
+
+/**@brief The number of symbols forming a superframe when
+ * the superframe order is equal to 0.
+ */
+#define aBaseSuperframeDuration (aBaseSlotDuration * aNumSuperframeSlots)
+
+/**@brief The maximum size, in octets, of a beacon payload. */
+#define aMaxBeaconPayloadLength (aMaxPHYPacketSize - aMaxBeaconOverhead)
+
+/**@brief The maximum number of octets added by the MAC
+ * sublayer to the PSDU without security.
+ */
+#define aMaxMPDUUnsecuredOverhead 25
+
+/**@brief The maximum number of octets that can be transmitted in the MAC Payload
+ * field of an unsecured MAC frame that will be guaranteed not to exceed aMaxPHYPacketSize.
+ */
+#define aMaxMACSafePayloadSize (aMaxPHYPacketSize - aMaxMPDUUnsecuredOverhead)
+
+/**@brief The minimum number of octets added by the MAC sublayer to the PSDU.*/
+#define aMinMPDUOverhead 9
+
+/**@brief The maximum number of octets that can be transmitted in the MAC
+ * Payload field.
+ */
+#define aMaxMACPayloadSize (aMaxPHYPacketSize - aMinMPDUOverhead)
+
+/**@brief The maximum size of an MPDU, in octets, that can be followed by a SIFS period. */
+#define aMaxSIFSFrameSize 18
+
+/**@brief The minimum number of symbols forming the CAP.
+ *
+ * @details This ensures that MAC commands can still be transferred to devices
+ * when GTSs are being used.
+ */
+#define aMinCAPLength 440
+
+/**@brief The number of superframes in which a GTS descriptor exists
+ * in the beacon frame of the PAN coordinator.
+ */
+#define aGTSDescPersistenceTime 4
+
+/**@brief The number of consecutive lost beacons that will cause the MAC sublayer
+ * of a receiving device to declare a loss of synchronization.
+ */
+#define aMaxLostBeacons 4
+
+/**@brief Maximum number of battery life extension periods. */
+#define MAC_MIN_BATT_LIFE_EXT_PERIODS 6
+/**@brief Minimum number of battery life extension periods. */
+#define MAC_MAX_BATT_LIFE_EXT_PERIODS 41
+
+/**@brief Minimum value for macBeaconOrder parameter. */
+#define MAC_MIN_BEACON_ORDER 0
+/**@brief Maximum value for macBeaconOrder parameter. */
+#define MAC_MAX_BEACON_ORDER 15
+
+/**@brief Minimum value for macMaxCSMABackoffs parameter. */
+#define MAC_MIN_MAX_CSMA_BACKOFFS 0
+/**@brief Maximum value for macMaxCSMABackoffs parameter. */
+#define MAC_MAX_MAX_CSMA_BACKOFFS 5
+
+/**@brief Minimum value for macMinBE parameter. */
+#define MAC_MIN_MIN_BE 0
+
+/**@brief Minimum value for macMaxBE parameter. */
+#define MAC_MIN_MAX_BE 3
+/**@brief Maximum value for macMaxBE parameter. */
+#define MAC_MAX_MAX_BE 8
+
+/**@brief Minimum value for macSuperframeOrder parameter. */
+#define MAC_MIN_SUPERFRAME_ORDER 0
+/**@brief Maximum value for macSuperframeOrder parameter. */
+#define MAC_MAX_SUPERFRAME_ORDER 15
+
+/**@brief Minimum value for macMaxFrameRetries parameter. */
+#define MAC_MIN_MAX_FRAME_RETRIES 0
+/**@brief Maximum value for macMaxFrameRetries parameter. */
+#define MAC_MAX_MAX_FRAME_RETRIES 7
+
+/**@brief Minimum value for macResponseWaitTime parameter. */
+#define MAC_MIN_RESPONSE_WAIT_TIME 2
+/**@brief Maximum value for macResponseWaitTime parameter. */
+#define MAC_MAX_RESPONSE_WAIT_TIME 64
+
+/**@brief A handy macro for a never initialized short address. */
+#define MAC_SHORT_ADDRESS_NOT_SET 0xFFFF
+
+/**@brief A handy macro for a never initialized short address. */
+#define MAC_EXTENDED_ADDRESS_NOT_SET 0xFFFFFFFFFFFFFFFFULL
+
+/**@brief A value of MAC beacon order attribute which determines
+ * a state with no periodic beacons.
+ */
+#define MAC_NO_BEACONS 15
+
+/**@brief A handy macro for broadcast address. */
+#define MAC_BROADCAST_SHORT_ADDRESS 0xFFFF
+
+/**@brief A handy macro for unknown PAN ID. */
+#define MAC_BROADCAST_PANID 0xFFFF
+
+/**@brief Short address field value that is used when the device does not
+ * support short addressing mode.
+ */
+#define MAC_EXTENDED_ADDRESS_ONLY 0xFFFE
+
+/**@brief Final CAP slot field value in the beacon for non-beacon enabled PAN. */
+#define MAC_FINAL_CAP_SLOT_NBPAN 15
+
+/**@brief Total amount of slots available in beacon enabled PAN. */
+#define MAC_SLOT_AMOUNT 16
+
+/**@brief This is the value of auto request key index until it has been set. */
+#define MAC_SECURITY_KEY_INDEX_NOT_SET 0xFF
+
+/**@brief Length of short MAC address in bytes. */
+#define MAC_ADDR_SHORT_LEN 2
+
+/**@brief Length of extended MAC address in bytes. */
+#define MAC_ADDR_EXTENDED_LEN 8
+
+/**@brief Length of PAN ID field in bytes. */
+#define MAC_PAN_ID_LEN 2
+
+/**@brief MAC footer (FCS) size. */
+#define MAC_MFR_SIZE 2
+
+/**@brief Maximum auxiliary header length */
+#if (CONFIG_SECURE == 1)
+#define MAC_MAX_AUX_HEADER_SIZE 14
+#else
+#define MAC_MAX_AUX_HEADER_SIZE 0
+#endif
+
+/**@brief Maximum MAC header length */
+#define MAC_MAX_MHR_SIZE (PHY_MAX_HEADER_SIZE + \
+ 2 /* Frame control */ + \
+ 1 /* Data sequence number */ + \
+ 2 * (sizeof(uint16_t) + (sizeof(uint64_t))) /* Two PAN IDs and extended addresses */ + \
+ MAC_MAX_AUX_HEADER_SIZE)
+/**@brief Maximum MAC header length for beacon frame */
+#define MAC_MAX_BCN_MHR_SIZE (PHY_MAX_HEADER_SIZE + \
+ 2 /* Frame control field */ + \
+ 1 /* Beacon sequence number */ + \
+ sizeof(uint16_t) /* PAN ID */ + \
+ sizeof(uint64_t) /* Extended address */ + \
+ MAC_MAX_AUX_HEADER_SIZE)
+
+
+/**@brief Memory which should be reserved for MAC fields */
+#if (CONFIG_SECURE == 1)
+#define MAC_MEMORY_RESERVE (MAC_MAX_MHR_SIZE + MAX_MIC_SIZE + MAC_MFR_SIZE)
+#else
+#define MAC_MEMORY_RESERVE (MAC_MAX_MHR_SIZE + MAC_MFR_SIZE)
+#endif
+
+/**@brief Offset of MAC payload in the frame buffer */
+#define MAC_MAX_MSDU_OFFSET MAC_MAX_MHR_SIZE
+
+/**@brief Possible MAC frame types. */
+typedef enum
+{
+ MAC_BEACON, /**< Frame is a beacon. */
+ MAC_DATA, /**< Frame is a data frame. */
+ MAC_ACK, /**< Frame is a MAC ACKnowledgement. */
+ MAC_COMMAND /**< Frame is a MAC command. */
+} mac_frame_type_t;
+
+/**@brief MAC ADDRESS. */
+typedef union
+{
+ uint16_t short_address; /**< 16-bit short address. */
+ uint64_t long_address; /**< 64-bit long address. */
+} mac_addr_t;
+
+/**@brief MAC ADDR MODE. */
+typedef enum
+{
+ MAC_ADDR_NONE = 0, /**< NO address is used. */
+ MAC_ADDR_SHORT = 2, /**< Short address is used. */
+ MAC_ADDR_LONG = 3 /**< Long address is used. */
+} mac_addr_mode_t;
+
+typedef enum
+{
+ MAC_FRAME_VERSION_2003, /**< IEEE 802.15.4-2003 compliant. */
+ MAC_FRAME_VERSION_2006 /**< IEEE 802.15.4-2006 compliant. */
+} mac_frame_version_t;
+
+/**
+ * @brief MAC status
+ *
+ * In accordance with IEEE Std 802.15.4-2006, section 7.1.17
+ * excluding:
+ * MAC_IS_NOT_AVAILABLE
+ * This status is necessary for synchronous API.
+ */
+typedef enum
+{
+ MAC_SUCCESS = 0x00, /* 0 */ /**< Operation is successful. */
+ MAC_COUNTER_ERROR = 0xDB, /* 219 */ /**< The frame counter purportedly applied
+ by the originator of the received
+ frame is invalid. */
+ MAC_IMPROPER_KEY_TYPE = 0xDC, /* 220 */ /**< The key purportedly applied by the
+ originator of the received frame is
+ not allowed to be used with that
+ frame type according to the key usage
+ policy of the recipient. */
+ MAC_IMPROPER_SECURITY_LEVEL = 0xDD, /* 221 */ /**< The security level purportedly applied
+ by the originator of the received
+ frame does not meet the minimum
+ security level required/expected by
+ the recipient for that frame type. */
+ MAC_UNSUPPORTED_LEGACY = 0xDE, /* 222 */ /**< The received frame was purportedly
+ secured using security based on IEEE
+ Std 802.15.4-2003, and such security
+ is not supported by this standard. */
+ MAC_UNSUPPORTED_SECURITY = 0xDF, /* 223 */ /**< The security purportedly applied by
+ the originator of the received frame
+ is not supported. */
+ MAC_BEACON_LOSS = 0xE0, /* 224 */ /**< The beacon was lost following a
+ synchronization request. */
+ MAC_CHANNEL_ACCESS_FAILURE = 0xE1, /* 225 */ /**< A transmission could not take place
+ due to activity on the channel, i.e.
+ the CSMA-CA mechanism has failed. */
+ MAC_DENIED = 0xE2, /* 226 */ /**< The GTS request has been denied by
+ the PAN coordinator. */
+ MAC_DISABLE_TRX_FAILURE = 0xE3, /* 227 */ /**< The attempt to disable the
+ transceiver has failed. */
+ MAC_SECURITY_ERROR = 0xE4, /* 228 */ /**< Cryptographic processing of the
+ received secured frame failed. */
+ MAC_FRAME_TOO_LONG = 0xE5, /* 229 */ /**< Either a frame resulting from
+ processing has a length that is
+ greater than aMaxPHYPacketSize or
+ a requested transaction is too large
+ to fit in the CAP or GTS. */
+ MAC_INVALID_GTS = 0xE6, /* 230 */ /**< The requested GTS transmission failed
+ because the specified GTS either did
+ not have a transmit GTS direction or
+ was not defined. */
+ MAC_INVALID_HANDLE = 0xE7, /* 231 */ /**< A request to purge an MSDU from the
+ transaction queue was made using an
+ MSDU handle that was not found in
+ the transaction table. */
+ MAC_INVALID_PARAMETER = 0xE8, /* 232 */ /**< A parameter in the primitive is
+ either not supported or is out of
+ the valid range. */
+ MAC_NO_ACK = 0xE9, /* 233 */ /**< No acknowledgment was received after
+ macMaxFrameRetries. */
+ MAC_NO_BEACON = 0xEA, /* 234 */ /**< A scan operation failed to find any
+ network beacons. */
+ MAC_NO_DATA = 0xEB, /* 235 */ /**< No response data was available
+ following a request. */
+ MAC_NO_SHORT_ADDRESS = 0xEC, /* 236 */ /**< The operation failed because a 16-bit
+ short address was not allocated. */
+ MAC_OUT_OF_CAP = 0xED, /* 237 */ /**< A receiver enable request was
+ unsuccessful because it could not be
+ completed within the CAP.
+ @note The enumeration description is
+ not used in this standard, and it is
+ included only to meet the backwards
+ compatibility requirements for
+ IEEE Std 802.15.4-2003. */
+ MAC_PAN_ID_CONFLICT = 0xEE, /* 238 */ /**< A PAN identifier conflict has been
+ detected and communicated to the PAN
+ coordinator. */
+ MAC_REALIGNMENT = 0xEF, /* 239 */ /**< A coordinator realignment command has
+ been received. */
+ MAC_TRANSACTION_EXPIRED = 0xF0, /* 240 */ /**< The transaction has expired and its
+ information was discarded. */
+ MAC_TRANSACTION_OVERFLOW = 0xF1, /* 241 */ /**< There is no capacity to store the
+ transaction. */
+ MAC_TX_ACTIVE = 0xF2, /* 242 */ /**< The transceiver was in the transmitter
+ enabled state when the receiver was
+ requested to be enabled.
+ @note The enumeration description is
+ not used in this standard, and it is
+ included only to meet the backwards
+ compatibility requirements for
+ IEEE Std 802.15.4-2003. */
+ MAC_UNAVAILABLE_KEY = 0xF3, /* 243 */ /**< The key purportedly used by the
+ originator of the received frame is
+ not available or, if available, the
+ originating device is not known or is
+ blacklisted with that particular
+ key. */
+ MAC_UNSUPPORTED_ATTRIBUTE = 0xF4, /* 244 */ /**< A SET/GET request was issued with the
+ identifier of a PIB attribute that is
+ not supported. */
+ MAC_INVALID_ADDRESS = 0xF5, /* 245 */ /**< A request to send data was
+ unsuccessful because neither the source
+ address parameters nor the destination
+ address parameters were present. */
+ MAC_ON_TIME_TOO_LONG = 0xF6, /* 246 */ /**< A receiver enable request was
+ unsuccessful because it specified a
+ number of symbols that was longer than
+ the beacon interval. */
+ MAC_PAST_TIME = 0xF7, /* 247 */ /**< A receiver enable request was
+ unsuccessful because it could not be
+ completed within the current superframe
+ and was not permitted to be deferred
+ until the next superframe. */
+ MAC_TRACKING_OFF = 0xF8, /* 248 */ /**< The device was instructed to start
+ sending beacons based on the timing
+ of the beacon transmissions of its
+ coordinator, but the device is not
+ currently tracking the beacon of its
+ coordinator. */
+ MAC_INVALID_INDEX = 0xF9, /* 249 */ /**< An attempt to write to a MAC PIB
+ attribute that is in a table failed
+ because the specified table index
+ was out of range. */
+ MAC_LIMIT_REACHED = 0xFA, /* 250 */ /**< A scan operation terminated
+ prematurely because the number of
+ PAN descriptors stored reached an
+ implementation specified maximum. */
+ MAC_READ_ONLY = 0xFB, /* 251 */ /**< A SET/GET request was issued with the
+ identifier of an attribute that is
+ read only. */
+ MAC_SCAN_IN_PROGRESS = 0xFC, /* 252 */ /**< A request to perform a scan operation
+ failed because the MLME was in the
+ process of performing a previously
+ initiated scan operation. */
+ MAC_SUPERFRAME_OVERLAP = 0xFD, /* 253 */ /**< The device was instructed to start
+ sending beacons based on the timing
+ of the beacon transmissions of its
+ coordinator, but the instructed start
+ time overlapped the transmission time
+ of the beacon of its coordinator. */
+ /* Statuses out from standard. It is used for synchronous API */
+ MAC_IS_NOT_AVAILABLE = 0xFF /* 255 */ /**< MAC is not available. */
+} mac_status_t;
+
+/**
+ * @brief Payload descriptor.
+ *
+ * @details Not covered by the standard.
+ * Contains information sufficient to allow the next higher layer to clean
+ * the memory allocated for incoming frames.
+ */
+typedef struct
+{
+ /**
+ * Pointer to the set of octets forming the frame payload being indicated by
+ * the MAC sublayer entity.
+ */
+ uint8_t * p_payload;
+ /**
+ * Offset of the payload data relative to the beginning of the frame.
+ * Equal to the MAC header.
+ */
+ uint8_t payload_offset;
+} mac_payload_descriptor_t;
+
+/** @brief Command frame IDs defined by the MAC sublayer that are listed
+ * in Table 82 of the standard.
+ */
+typedef enum
+{
+ MAC_CMD_ASSOC_REQ = 0x01, /**< Association request.*/
+ MAC_CMD_ASSOC_RESP = 0x02, /**< Association response.*/
+ MAC_CMD_DISASSOC_NTF = 0x03, /**< Disassociation notification.*/
+ MAC_CMD_DATA_REQ = 0x04, /**< Data request.*/
+ MAC_CMD_PANID_CONFLICT_NTF = 0x05, /**< PAN ID conflict notification.*/
+ MAC_CMD_ORPHAN_NTF = 0x06, /**< Orphan notification.*/
+ MAC_CMD_BEACON_REQ = 0x07, /**< Beacon request.*/
+ MAC_CMD_COORD_REALIGN = 0x08, /**< Coordinator realignment.*/
+ MAC_CMD_GTS_REQ = 0x09 /**< GTS request.*/
+} mac_command_id_t;
+/** @} */
+
+
+#endif // MAC_COMMON_H_INCLUDED
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/802_15_4/api/MAC/mac_mcps_data.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/802_15_4/api/MAC/mac_mcps_data.h
new file mode 100644
index 0000000..6324ab1
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/802_15_4/api/MAC/mac_mcps_data.h
@@ -0,0 +1,333 @@
+/**
+ * Copyright (c) 2016 - 2018 Nordic Semiconductor ASA and Luxoft Global Operations Gmbh.
+ *
+ * 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#ifndef MAC_MCPS_DATA_H_INCLUDED
+#define MAC_MCPS_DATA_H_INCLUDED
+
+#include <stdint.h>
+#include "mac_common.h"
+#include "mac_task_scheduler.h"
+
+/** @file
+ * The MAC Data module declares the MAC Data transmittion routines and necessary types
+ * according to the MAC specification.
+ *
+ * @defgroup mac_data MAC MCPS Data API
+ * @ingroup mac_15_4
+ * @{
+ * @brief Module to declare MAC MCPS Data API.
+ * @details The MAC MCPS Data module declares the MAC Data transmission routines and necessary types according
+ * to the MAC specification. More specifically, MAC data request mcps_data_req(), and MAC Data
+ * indication mcps_data_ind() primitives are declared. The confirmation callback typedef is
+ * declared as mcps_data_conf_cb_t.
+ */
+
+/**
+ * @brief TX options bit fields.
+ *
+ * In accordance with IEEE Std 802.15.4-2006, section 7.1.1.1.
+ */
+#define TX_ACKNOWLEDGED_BIT (0)
+#define TX_GTS_BIT (1)
+#define TX_INDIRECT_BIT (2)
+
+
+/**
+ * @brief TX options for MAC data transmission.
+ *
+ * @details The three bits (b0, b1, b2) indicate the transmission options for this MSDU.
+ * For b0, 1 = acknowledged transmission, 0 = unacknowledged transmission.
+ * For b1, 1 = GTS transmission, 0 = CAP transmission for a beacon-enabled PAN.
+ * For b2, 1 = indirect transmission, 0 = direct transmission.
+ * For a nonbeacon-enabled PAN, bit b1 should always be set to 0.
+ */
+typedef struct
+{
+ uint8_t ack : 1;
+ uint8_t gts : 1;
+ uint8_t indirect : 1;
+ uint8_t : 5;
+} mac_tx_options_t;
+
+
+/**
+ * @brief MCPS-DATA.confirm.
+ *
+ * @details The MCPS-DATA.confirm primitive reports the results of a request to transfer
+ * a data SPDU (MSDU) from a local SSCS entity to a single peer SSCS entity.
+ *
+ * In accordance with IEEE Std 802.15.4-2006, section 7.1.1.2.
+ */
+typedef struct
+{
+ /** The handle associated with the MSDU being confirmed. */
+ uint8_t msdu_handle;
+
+ /** The status of the last MSDU transmission. */
+ mac_status_t status;
+
+ /**
+ * Optional. The time, in symbols, at which the data was transmitted (see 7.5.4.1).
+ *
+ * The value of this parameter will be considered valid only if the value of the
+ * status parameter is SUCCESS; if the status parameter is not equal to
+ * SUCCESS, the value of the Timestamp parameter will not be used for any other
+ * purpose. The symbol boundary is described by macSyncSymbolOffset (see Table 86 in 7.4.1).
+ *
+ * This is a 24-bit value, and the precision of this value will be a minimum of 20 bits,
+ * with the lowest 4 bits being the least significant.
+ */
+ uint32_t timestamp;
+} mcps_data_conf_t;
+
+
+/**
+ * @brief MCPS-DATA.request.
+ *
+ * @details The MCPS-DATA.request primitive requests the transfer of
+ * a data SPDU (i.e., MSDU) from a local SSCS entity to a single peer SSCS entity.
+ *
+ * In accordance with IEEE Std 802.15.4-2006, section 7.1.1.1.
+ */
+typedef struct
+{
+ /** Do not edit this field. */
+ mac_abstract_req_t service;
+
+ /** Confirm to this request. */
+ mcps_data_conf_t confirm;
+
+ /**
+ * The source addressing mode for this primitive and
+ * subsequent MPDU. This value can take one of the following values:
+ * @ref mac_addr_mode_t
+ * 0x00 = no address (addressing fields omitted, see 7.2.1.1.8).
+ * 0x01 = reserved.
+ * 0x02 = 16-bit short address.
+ * 0x03 = 64-bit extended address.
+ */
+ mac_addr_mode_t src_addr_mode;
+
+ /**
+ * The destination addressing mode for this primitive
+ * and subsequent MPDU.
+ * According to 7.1.1.1.1, Table 41.
+ */
+ mac_addr_mode_t dst_addr_mode;
+
+ /** The 16-bit PAN identifier of the entity to which the MSDU is being transferred. */
+ uint16_t dst_pan_id;
+
+ /** The individual device address of the entity to which the MSDU is being transferred. */
+ mac_addr_t dst_addr;
+
+ /** The number of octets contained in the MSDU to be transmitted by
+ * the MAC sublayer entity.
+ */
+ uint8_t msdu_length;
+
+ /**
+ * The pointer to the set of octets forming the MSDU
+ * to be transmitted by the MAC sublayer entity.
+ *
+ * Caller must provide enough space for MAC and PHY header before this pointer.
+ */
+ uint8_t * msdu;
+
+ /** The handle associated with the MSDU to be transmitted by the MAC sublayer entity. */
+ uint8_t msdu_handle;
+
+ /**
+ * The bits (b0, b1, b2) indicate the transmission options for this MSDU.
+ * For b0, 1 = acknowledged transmission, 0 = unacknowledged transmission.
+ * For b1, 1 = GTS transmission, 0 = CAP transmission for a beacon-enabled PAN.
+ * For b2, 1 = indirect transmission, 0 = direct transmission.
+ * For a nonbeacon-enabled PAN, bit b1 should always be set to 0.
+ */
+ mac_tx_options_t tx_options;
+#if (CONFIG_SECURE == 1)
+ uint8_t security_level; /**< Security level. */
+ uint8_t key_id_mode; /**< Key ID node. */
+ uint64_t key_source; /**< Key source. */
+ uint8_t key_index; /**< Key index. */
+#endif
+} mcps_data_req_t;
+
+/**
+ * @brief Private information passed with MCPS-DATA.indication.
+ * Not covered by the standard.
+ */
+typedef struct
+{
+ /** RSSI value, which corresponds to packet that caused this indication. */
+ int8_t rssi;
+ /** Value of a pending bit from MHR. */
+ uint8_t pending_bit;
+} mcps_data_ind_private_t;
+
+/**
+ * @brief MCPS-DATA.indication
+ *
+ * @details The MCPS-DATA.indication primitive indicates the transfer of
+ * a data SPDU (i.e., MSDU) from the MAC sublayer to the local SSCS entity.
+ *
+ * In accordance with IEEE Std 802.15.4-2006, section 7.1.1.3
+ */
+typedef struct
+{
+ mcps_data_ind_private_t service;
+
+ /**
+ * The source addressing mode for this primitive corresponding to the received MPDU.
+ * According to 7.1.1.1.1, Table 43.
+ */
+ mac_addr_mode_t src_addr_mode;
+
+ /** The 16-bit PAN identifier of the entity from which the MSDU was received. */
+ uint16_t src_pan_id;
+
+ /** The individual device address of the entity from which the MSDU was received. */
+ mac_addr_t src_addr;
+
+ /**
+ * The destination addressing mode for this primitive corresponding to the received MPDU.
+ * According to 7.1.1.1.1, Table 43.
+ */
+ mac_addr_mode_t dst_addr_mode;
+
+ /** The 16-bit PAN identifier of the entity to which the MSDU is being transferred. */
+ uint16_t dst_pan_id;
+
+ /** The individual device address of the entity to which the MSDU is being transferred. */
+ mac_addr_t dst_addr;
+
+ /** The number of octets contained in the MSDU being indicated by the MAC sublayer entity. */
+ uint8_t msdu_length;
+
+ /**
+ * The information that is required for the next higher layer to read incoming message and to
+ * free the memory allocated for this message.
+ */
+ mac_payload_descriptor_t msdu;
+
+ /**
+ * LQI value measured during reception of the MPDU.
+ * Lower values represent lower LQI (see 6.9.8).
+ */
+ uint8_t mpdu_link_quality;
+
+ /** The DSN of the received data frame. */
+ uint8_t dsn;
+
+ /**
+ * Optional. The time, in symbols, at which the data was received (see 7.5.4.1).
+ * The symbol boundary is described by macSyncSymbolOffset (see Table 86 in 7.4.1).
+ *
+ * This is a 24-bit value, and the precision of this value shall be a minimum of 20 bits,
+ * with the lowest 4 bits being the least significant.
+ */
+ uint32_t timestamp;
+#if (CONFIG_SECURE == 1)
+ uint8_t security_level; /**< Security level. */
+ uint8_t key_id_mode; /**< Key ID node. */
+ uint64_t key_source; /**< Key source. */
+ uint8_t key_index; /**< Key index. */
+#endif
+} mcps_data_ind_t;
+
+
+/**
+ * @brief Confirmation function.
+ *
+ * @details The MCPS-DATA.confirm primitive is generated by the MAC sublayer
+ * entity in response to an MCPS-DATA. request primitive. The MCPS-DATA.confirm
+ * primitive returns a status of either SUCCESS, indicating that the request to
+ * transmit was successful, or the appropriate error code.
+ * The status values are fully described in 7.1.1.1.3 and subclauses referenced by 7.1.1.1.3.
+ *
+ * @param Pointer to confirmation primitive.
+ */
+typedef void (* mcps_data_conf_cb_t)(mcps_data_conf_t *);
+
+
+/**
+ * @brief MCPS-DATA.request service
+ *
+ * @details The MCPS-DATA.request primitive is generated by a local SSCS entity
+ * when a data SPDU (i.e., MSDU) is to be transferred to a peer SSCS entity.
+ * After request completion, user callback will be issued with
+ * valid data stored in structure @ref mcps_data_conf_t.
+ *
+ * @param req Pointer to MCPS-DATA request structure.
+ * @param conf_cb Pointer to confirmation function (user callback).
+ *
+ * In accordance with IEEE Std 802.15.4-2006, section 7.1.1.2.
+ */
+void mcps_data_req(mcps_data_req_t * req, mcps_data_conf_cb_t conf_cb);
+
+
+/**
+ * @brief MCPS-DATA.indication handler.
+ *
+ * @details The MCPS-DATA.indication primitive is generated by the MAC sublayer and
+ * issued to the SSCS on receipt of a data frame at the local MAC sublayer entity
+ * that passes the appropriate message filtering operations as described in 7.5.6.2.
+ *
+ * @param ind MCPS-DATA.indication structure.
+ *
+ * In accordance with IEEE Std 802.15.4-2006, section 7.1.1.3.
+ */
+extern void mcps_data_ind(mcps_data_ind_t * ind);
+
+/**
+ * @brief Free memory allocated for incoming message.
+ *
+ * @details The function will be invoked after all manipulations
+ * with MSDU are completed. That is necessary to return the memory allocated by MAC
+ * into the heap.
+ *
+ * @param p_payload_descriptor - Pointer to MSDU descriptor.
+ */
+void mac_mem_msdu_free(mac_payload_descriptor_t * p_payload_descriptor);
+
+/** @} */
+
+#endif // MAC_MCPS_DATA_H_INCLUDED
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/802_15_4/api/MAC/mac_mcps_purge.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/802_15_4/api/MAC/mac_mcps_purge.h
new file mode 100644
index 0000000..e4029ff
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/802_15_4/api/MAC/mac_mcps_purge.h
@@ -0,0 +1,152 @@
+/**
+ * Copyright (c) 2016 - 2018 Nordic Semiconductor ASA and Luxoft Global Operations Gmbh.
+ *
+ * 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#ifndef MAC_MCPS_PURGE_H_INCLUDED
+#define MAC_MCPS_PURGE_H_INCLUDED
+
+#if (CONFIG_PURGE_ENABLED == 1)
+
+#include <stdint.h>
+#include "mac_common.h"
+#include "mac_task_scheduler.h"
+
+/** @file
+ * The MAC Purge module declares the MAC Purge routines and necessary types
+ * according to the MAC specification.
+ *
+ * @defgroup mac_purge MAC MCPS Purge API
+ * @ingroup mac_15_4
+ * @{
+ * @brief Module to declare MAC MCPS Purge API.
+ * @details The MAC MCPS Purge module declares the MAC Purge routines and necessary types according to
+ * the MAC specification. More specifically, MAC purge request mcps_purge_req(), and the
+ * confirmation callback typedef is declared as mcps_purge_conf_cb_t. An additional primitive
+ * not covered by the standard is declared. This is mpcs_purge() which is a synchronous version
+ * of mcps_purge_req().
+ */
+
+/**
+ * @brief MCPS-PURGE.confirm.
+ *
+ * @details The MCPS-PURGE.confirm primitive allows the MAC sublayer to notify the next higher layer
+ * of the success of its request to purge an MSDU from the transaction queue.
+ *
+ * In accordance with IEEE Std 802.15.4-2006, section 7.1.1.5.
+ */
+typedef struct
+{
+ /** The handle of the MSDU to be purged from the transaction queue. */
+ uint8_t msdu_handle;
+
+ /** The status of the request to be purged an MSDU from the transaction queue. */
+ mac_status_t status;
+} mcps_purge_conf_t;
+
+
+/**
+ * @brief MCPS-PURGE.request.
+ *
+ * @details The MCPS-PURGE.request primitive allows the next higher layer
+ * to purge an MSDU from the transaction queue.
+ *
+ * In accordance with IEEE Std 802.15.4-2006, section 7.1.1.4.
+ */
+typedef struct
+{
+ /** Do not edit this field. */
+ mac_abstract_req_t service;
+
+ /** Confirmation to this request. */
+ mcps_purge_conf_t confirm;
+
+ /** The handle of the MSDU to be purged from the transaction queue. */
+ uint8_t msdu_handle;
+} mcps_purge_req_t;
+
+
+/**
+ * @brief Confirmation function.
+ *
+ * @details The MCPS-PURGE.confirm primitive is generated by the MAC sublayer
+ * entity in response to an MCPS-PURGE.request primitive. The MCPS-PURGE.confirm
+ * primitive returns a status of either SUCCESS, indicating that the purge request
+ * was successful, or INVALID_HANDLE, indicating an error.
+ * The status values are fully described in 7.1.1.4.3.
+ *
+ * @param Pointer to confirmation primitive.
+ */
+typedef void (* mcps_purge_conf_cb_t)(mcps_purge_conf_t *);
+
+
+/**
+ * @brief MCPS-PURGE.request service.
+ *
+ * @details The MCPS-PURGE.request primitive is generated by the next higher layer
+ * whenever an MSDU is to be purged from the transaction queue.
+ * After request completion, user callback will be issued with
+ * valid data stored in structure mcps_purge_conf_t.
+ *
+ * @param req Pointer to MCPS-PURGE request structure.
+ * @param conf_cb Pointer to the confirmation function (user callback).
+ *
+ * In accordance with IEEE Std 802.15.4-2006, section 7.1.1.4.
+ */
+void mcps_purge_req(mcps_purge_req_t * req, mcps_purge_conf_cb_t conf_cb);
+
+/**
+ * @brief Performs MCPS-PURGE.request directly (without request - confirm approach).
+ *
+ * @details Optional. Not covered by the standard.
+ *
+ * The MCPS-PURGE.request primitive is generated by the next higher layer
+ * whenever an MSDU is to be purged from the transaction queue.
+ *
+ * @param req Pointer to MCPS-PURGE request structure.
+ *
+ * @return Result of the purge procedure.
+ */
+mac_status_t mcps_purge(mcps_purge_req_t * req);
+
+/** @} */
+
+#endif // (CONFIG_PURGE_ENABLED == 1)
+
+#endif // MAC_MCPS_PURGE_H_INCLUDED
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/802_15_4/api/MAC/mac_mlme_associate.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/802_15_4/api/MAC/mac_mlme_associate.h
new file mode 100644
index 0000000..794935c
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/802_15_4/api/MAC/mac_mlme_associate.h
@@ -0,0 +1,336 @@
+/**
+ * Copyright (c) 2016 - 2018 Nordic Semiconductor ASA and Luxoft Global Operations Gmbh.
+ *
+ * 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#ifndef MAC_MLME_ASSOCIATE_H_INCLUDED
+#define MAC_MLME_ASSOCIATE_H_INCLUDED
+
+#include <stdint.h>
+#include "mac_common.h"
+#include "mac_task_scheduler.h"
+
+/** @file
+ * The MAC Association module declares the MAC Association routines and necessary types/macros
+ * according to the MAC specification.
+ *
+ * @defgroup mac_assoc MAC MLME Association API
+ * @ingroup mac_15_4
+ * @{
+ * @brief Module to declare MAC MLME Association API.
+ * @details The MLME Association module declares Association MAC routines and necessary macros/types according
+ * to the MAC specification. More specifically, MLME Association request aka mlme_associate_req(),
+ * MLME Association confirm callback typedef aka mlme_associate_conf_cb_t, MLME Association indication
+ * as mlme_associate_ind(), and MLME Response aka mlme_associate_resp() primitives are declared.
+ */
+
+/**
+ * @brief Capability information field.
+ *
+ * In accordance with IEEE Std 802.15.4-2006, section 7.3.1.2.
+ */
+#define ALTERNATE_PAN_COORDINATOR_BIT (0)
+#define DEVICE_TYPE_BIT (1)
+#define POWER_SOURCE_BIT (2)
+#define RECEIVER_ON_WHEN_IDLE_BIT (3)
+#define SECURITY_CAPABILITY_BIT (6)
+#define ALLOCATE_ADDRESS_BIT (7)
+
+
+/**
+ * @brief Valid values of the Association Status field
+ *
+ * In accordance with IEEE Std 802.15.4-2006, section 7.3.2.3
+ */
+typedef enum
+{
+ MAC_ASSOCIATION_SUCCESSFUL = 0,
+ MAC_PAN_AT_CAPACITY,
+ MAC_PAN_ACCESS_DENIED
+} mac_association_status_t;
+
+/**
+ * @brief Capability information field
+ *
+ * In accordance with IEEE Std 802.15.4-2006, section 7.3.1.2.
+ */
+typedef struct
+{
+ uint8_t alternate_pan_coordinator : 1;
+ uint8_t device_type : 1;
+ uint8_t power_source : 1;
+ uint8_t rx_on_when_idle : 1;
+ uint8_t reserved : 2;
+ uint8_t security_capability : 1;
+ uint8_t allocate_address : 1;
+} mac_capability_t;
+
+/**@brief The Alternate PAN Coordinator subfield of the Capability Information field. */
+typedef enum
+{
+ MAC_CAP_CANNOT_BE_PAN_COORD = 0, /**< Device is not capable of becoming
+ the PAN coordinator.*/
+ MAC_CAP_CAN_BE_PAN_COORD /**< Device is capable of becoming
+ the PAN coordinator.*/
+} mac_cap_alt_pan_coord_t;
+
+/**@brief The Device Type subfield of the Capability Information field. */
+typedef enum
+{
+ MAC_CAP_RFD_DEVICE = 0, /**< Device is an RFD.*/
+ MAC_CAP_FFD_DEVICE /**< Device is an FFD.*/
+} mac_cap_device_type_t;
+
+/**@brief The Power Source subfield of the Capability Information field. */
+typedef enum
+{
+ MAC_CAP_BATTERY_POWERED = 0, /**< Device is not AC-powered.*/
+ MAC_CAP_MAINS_POWERED /**< Device is receiving power from the
+ alternating current mains.*/
+} mac_cap_power_source_t;
+
+/**@brief The Receiver On When Idle subfield of the Capability Information field. */
+typedef enum
+{
+ MAC_CAP_RX_OFF_WHEN_IDLE = 0, /**< Device conserves power during idle.*/
+ MAC_CAP_RX_ON_WHEN_IDLE /**< Device does not disable its receiver
+ to conserve power during idle periods.*/
+} mac_cap_rx_when_idle_t;
+
+/**@brief The Security Capability subfield of the Capability Information field. */
+typedef enum
+{
+ MAC_CAP_CANNOT_SECURE = 0, /**< Device does not support securing.*/
+ MAC_CAP_CAN_SECURE /**< Device is capable of sending and receiving
+ cryptographically protected MAC frames.*/
+} mac_cap_secure_t;
+
+/**@brief The Allocate Address subfield of the Capability Information field. */
+typedef enum
+{
+ MAC_CAP_SHORT_ADDR_NOT_REQ = 0, /**< The coordinator will not allocate a
+ 16-bit short address as a result of
+ the association procedure.*/
+ MAC_CAP_SHORT_ADDR_REQ /**< The coordinator will allocate a
+ 16-bit short address as a result of
+ the association procedure.*/
+} mac_cap_allocate_addr_t;
+
+#if (CONFIG_ASSOCIATE_REQ_ENABLED == 1)
+
+/**
+ * @brief MLME-ASSOCIATE.confirm
+ *
+ * The MLME-ASSOCIATE.confirm primitive is generated by the initiating MLME and
+ * issued to its next higher layer in response to an MLME-ASSOCIATE.request primitive.
+ *
+ * In accordance with IEEE Std 802.15.4-2006, section 7.1.3.4.
+ */
+typedef struct
+{
+ uint16_t assoc_short_address; /**< Association short 16-bit address. */
+ mac_status_t status; /**< Status of operation. */
+#if (CONFIG_SECURE == 1)
+ uint8_t security_level; /**< Security level. */
+ uint8_t key_id_mode; /**< Key ID mode. */
+ uint64_t key_source; /**< Key source. */
+ uint8_t key_index; /**< Key index. */
+#endif
+} mlme_associate_conf_t;
+
+
+/**
+ * @brief MLME-ASSOCIATE.request.
+ *
+ * @details Allows a device to request an association with a coordinator.
+ *
+ * In accordance with IEEE Std 802.15.4-2006, section 7.1.3.1.
+ */
+typedef struct
+{
+ /** Do not edit this field. */
+ mac_abstract_req_t service;
+
+ /** Confirmation to this request. */
+ mlme_associate_conf_t confirm;
+
+ /**
+ * A total of 27 channels numbered 0 to 26.
+ * are available per channel page (section 6.1.2.1).
+ */
+ uint8_t logical_channel;
+
+ /**
+ * A total of 32 channel pages are available
+ * with channel pages 3 to 31 being reserved
+ * for future use (section 6.1.2.2).
+ */
+#ifdef CONFIG_SUB_GHZ
+ uint8_t channel_page; /**< Channel page. */
+#endif
+ mac_addr_mode_t coord_addr_mode; /**< Coordinator address mode. */
+ uint16_t coord_pan_id; /**< Coordinator PAN ID. */
+ mac_addr_t coord_address; /**< Coordinator address. */
+ mac_capability_t capability_information; /**< Capability information. */
+#if (CONFIG_SECURE == 1)
+ uint8_t security_level; /**< Security level. */
+ uint8_t key_id_mode; /**< Key ID mode. */
+ uint64_t key_source; /**< Key source. */
+ uint8_t key_index; /**< Key index. */
+#endif
+} mlme_associate_req_t;
+
+
+#if (CONFIG_ASSOCIATE_IND_ENABLED == 1)
+/**
+ * @brief MLME-ASSOCIATE.indication.
+ *
+ * @details The MLME-ASSOCIATE.indication primitive is generated by the MLME of
+ * the coordinator and issued to its next higher layer to indicate the reception
+ * of an association request command.
+ *
+ * In accordance with IEEE Std 802.15.4-2006, section 7.1.3.2.
+ */
+typedef struct
+{
+ uint64_t device_address; /**< 64-bit IEEE address. */
+ uint8_t capability_information; /**< Capability information. */
+#if (CONFIG_SECURE == 1)
+ uint8_t security_level; /**< Security level. */
+ uint8_t key_id_mode; /**< Key ID mode. */
+ uint64_t key_source; /**< Key source. */
+ uint8_t key_index; /**< Key index. */
+#endif
+} mlme_associate_ind_t;
+
+
+/**
+ * @brief MLME-ASSOCIATE.response.
+ *
+ * @details Generated by the next higher layer of a coordinator and issued
+ * to its MLME in order to respond to the MLME-ASSOCIATE.indication primitive.
+ *
+ * In accordance with IEEE Std 802.15.4-2006, section 7.1.3.3.
+ */
+typedef struct
+{
+ uint64_t device_address; /**< 64-bit IEEE address. */
+ uint16_t assoc_short_address; /**< Association short 16-bit address. */
+ mac_association_status_t status; /**< Status of operation. */
+#if (CONFIG_SECURE == 1)
+ uint8_t security_level; /**< Security level. */
+ uint8_t key_id_mode; /**< Key ID mode. */
+ uint64_t key_source; /**< Key source. */
+ uint8_t key_index; /**< Key index. */
+#endif
+} mlme_associate_resp_t;
+
+#endif // (CONFIG_ASSOCIATE_IND_ENABLED == 1)
+
+/**
+ * @brief Confirmation function.
+ *
+ * @details The MLME-ASSOCIATE.confirm primitive is generated by the
+ * initiating MLME and issued to its next higher layer in response to
+ * an MLME-ASSOCIATE.request primitive. If the request was successful,
+ * the status parameter will indicate a successful association, as
+ * contained in the Status field of the association response command.
+ * Otherwise, the status parameter indicates either an error code from
+ * the received association response command or the appropriate error
+ * code from Table 50.
+ * The status values are fully described in 7.1.3.1.3 and subclauses referenced by 7.1.3.1.3.
+ *
+ * @param Pointer to confirmation primitive.
+ */
+typedef void (* mlme_associate_conf_cb_t)(mlme_associate_conf_t *);
+
+
+/**
+ * @brief MLME-ASSOCIATE request.
+ *
+ * @details Requests an association with a PAN through a coordinator
+ * After request completion, user callback will be issued with
+ * valid data stored in structure mlme_set_conf_t.
+ *
+ * @param req MLME_ASSOCIATE request structure.
+ * @param conf_cb Pointer to user callback.
+ *
+ * In accordance with IEEE Std 802.15.4-2006, section 7.1.3.5
+ */
+void mlme_associate_req(mlme_associate_req_t * req, mlme_associate_conf_cb_t conf_cb);
+
+
+#if (CONFIG_ASSOCIATE_IND_ENABLED == 1)
+
+/**
+ * @brief MLME-ASSOCIATE indication handler.
+ *
+ * @details Indicates an association with a PAN through a coordinator
+ * next higher layer of a coordinator receives the MLME-ASSOCIATE.indication
+ * primitive to determine whether to accept or reject the unassociated device
+ * using an algorithm outside the scope of standard.
+ *
+ * @param ind MLME ASSOCIATE indication structure.
+ *
+ * In accordance with IEEE Std 802.15.4-2006, section 7.1.3.5.
+ */
+extern void mlme_associate_ind(mlme_associate_ind_t * ind);
+
+
+/**
+ * @brief MLME-ASSOCIATE response.
+ *
+ * @details Respond to an association with a PAN and issue to its MLME in order to
+ * respond to the MLME-ASSOCIATE.indication.
+ * Response structure passed as a parameter to this function must be retained
+ * in memory until the related MLME-COMM-STATUS.indication is received.
+ *
+ * @param resp MLME_ASSOCIATE response structure.
+ *
+ * In accordance with IEEE Std 802.15.4-2006, section 7.1.3.5.
+ */
+void mlme_associate_resp(mlme_associate_resp_t * resp);
+
+#endif // (CONFIG_ASSOCIATE_IND_ENABLED == 1)
+
+#endif // (CONFIG_ASSOCIATE_REQ_ENABLED == 1)
+
+/** @} */
+
+#endif // MAC_MLME_ASSOCIATE_H_INCLUDED
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/802_15_4/api/MAC/mac_mlme_beacon_notify.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/802_15_4/api/MAC/mac_mlme_beacon_notify.h
new file mode 100644
index 0000000..134fbf4
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/802_15_4/api/MAC/mac_mlme_beacon_notify.h
@@ -0,0 +1,175 @@
+/**
+ * Copyright (c) 2016 - 2018 Nordic Semiconductor ASA and Luxoft Global Operations Gmbh.
+ *
+ * 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#ifndef MAC_MLME_BEACON_NOTIFY_H_INCLUDED
+#define MAC_MLME_BEACON_NOTIFY_H_INCLUDED
+
+#include <stdint.h>
+#include <stdbool.h>
+#include "mac_common.h"
+#include "mac_time.h"
+
+/** @file
+ * The MAC Beacon notify module declares the MAC beacon notification routine and necessary
+ * types/macros according to the MAC specification.
+ *
+ * @defgroup mac_beacon_notify MAC MLME Beacon Notify API
+ * @ingroup mac_15_4
+ * @{
+ * @brief Module to declare MAC MLME Beacon Notify API.
+ * @details The MAC Beacon Notify module declares Beacon Notify MLME routines and necessary macros/types
+ * according to the MAC specification. MAC MLME Beacon notify indication is declared as
+ * mlme_beacon_notify_ind().
+ */
+
+/**@brief This constant is defined in 7.2.2.1.7 Address List field
+ *
+ * @details The maximum number of addresses pending shall be limited to seven and may comprise
+ * both short and extended addresses.
+ */
+#define MAC_PENDING_ADDR_MAX 7
+
+/*@brief The maximum length of GTS fields inside beacon in octets.
+ *
+ * @details This definition is used to allocate memory for outgoing beacon.
+ */
+#define MAC_MAX_GTS_FIELD_LEN 23
+
+/**@brief Superframe specification structure.*/
+typedef struct
+{
+ uint16_t beacon_order : 4;
+ uint16_t superframe_order : 4;
+ uint16_t final_cap_slot : 4;
+ uint16_t battery_life_extension : 1;
+ uint16_t reserved : 1;
+ uint16_t pan_coordinator : 1;
+ uint16_t association_permit : 1;
+} mac_superframe_spec_t;
+
+
+/** @brief List of pending addresses
+ * Short addresses are at the top of the table.
+ */
+typedef struct
+{
+ mac_addr_t addr_list[MAC_PENDING_ADDR_MAX];
+ /**< Addresses array. */
+ uint8_t short_addr_number; /**< Number of short addresses in the array. */
+ uint8_t ext_addr_number; /**< Number of long addresses in the array. */
+} mac_pending_addr_list_t;
+
+/**@brief PAN Descriptor structure.
+ *
+ * @details See Table 55-Elements of PANDescriptor.
+ */
+typedef struct
+{
+ mac_addr_mode_t coord_addr_mode; /**< Coordinator addressing mode. */
+ uint16_t coord_pan_id; /**< Coordinator PAN ID. */
+ mac_addr_t coord_address; /**< Coordinator address. */
+ uint8_t logical_channel; /**< Logical channel. */
+#ifdef CONFIG_SUB_GHZ
+ uint8_t channel_page; /**< Channel page. */
+#endif
+ mac_superframe_spec_t superframe_spec; /**< Superframe specification. */
+ bool gts_permit; /**< Is GTS permitted? */
+ uint8_t link_quality; /**< Link quality. */
+ mac_timestamp_t timestamp; /**< Timestamp. */
+#if (CONFIG_SECURE == 1)
+ uint8_t security_failure; /**< Security failure. */
+ uint8_t security_level; /**< Security level. */
+ uint8_t key_id_mode; /**< Key ID mode. */
+ uint64_t key_source; /**< Key source. */
+ uint8_t key_index; /**< Key index. */
+#endif
+} mac_pan_descriptor_t;
+
+
+/**@brief Pending Address Specification
+ *
+ * @details See Figure 51-Format of the Pending Address Specification field.
+ */
+typedef struct
+{
+ uint8_t pending_short : 3;
+ uint8_t : 1;
+ uint8_t pending_extended : 3;
+ uint8_t : 1;
+} mac_pend_addr_spec_t;
+
+
+/**@brief MLME-BEACON-NOTIFY.indication parameters
+ *
+ * @details See 7.1.5.1 MLME-BEACON-NOTIFY.indication
+ */
+typedef struct
+{
+ uint8_t bsn; /**< Beacon sequence number. */
+ mac_pan_descriptor_t pan_descriptor; /**< PAN descriptor. */
+ mac_pend_addr_spec_t pend_addr_spec; /**< Pending address specification. */
+ mac_addr_t addr_list[MAC_PENDING_ADDR_MAX];
+ /**< Addresses array. */
+ uint8_t sdu_length; /**< SDU length. */
+ mac_payload_descriptor_t sdu; /**< SDU. */
+#if (CONFIG_SECURE == 1)
+ uint8_t security_level; /**< Security level. */
+ uint8_t key_id_mode; /**< Key ID mode. */
+ uint64_t key_source; /**< Key source. */
+ uint8_t key_index; /**< Key index. */
+#endif
+} mlme_beacon_notify_ind_t;
+
+
+/**@brief User implemented function, which handles MLME-BEACON-NOTIFY.indication.
+ *
+ * @details The MLME-BEACON-NOTIFY.indication primitive is used to send parameters contained
+ * within a beacon frame received by the MAC sublayer to the next higher layer.
+ * The primitive also sends a measure of the LQI and the time the beacon frame
+ * was received. See 7.1.5.1 MLME-BEACON-NOTIFY.indication.
+ *
+ * @param ind MLME-BEACON-NOTIFY.indication parameters. See @ref mlme_beacon_notify_ind_t.
+ */
+extern void mlme_beacon_notify_ind(mlme_beacon_notify_ind_t * ind);
+
+/** @} */
+
+#endif // MAC_MLME_BEACON_NOTIFY_H_INCLUDED
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/802_15_4/api/MAC/mac_mlme_comm_status.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/802_15_4/api/MAC/mac_mlme_comm_status.h
new file mode 100644
index 0000000..4f8092f
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/802_15_4/api/MAC/mac_mlme_comm_status.h
@@ -0,0 +1,135 @@
+// Terms and conditions of usage are described in detail in NORDIC
+// SEMICONDUCTOR STANDARD SOFTWARE LICENSE AGREEMENT.
+//
+// Licensees are granted free, non-transferable use of the information. NO
+// WARRANTY of ANY KIND is provided. This heading must NOT be removed from
+// the file.
+
+/**
+ * Copyright (c) 2016 - 2018 Nordic Semiconductor ASA and Luxoft Global Operations Gmbh.
+ *
+ * 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#ifndef MAC_MLME_COMM_STATUS_H_INCLUDED
+#define MAC_MLME_COMM_STATUS_H_INCLUDED
+
+#include <stdint.h>
+#include "mac_common.h"
+
+/** @file
+ * The MAC Comm Status module declares the MAC communication status indication routine and
+ * necessary types/macros according to the MAC specification.
+ *
+ * @defgroup mac_comm_status MAC MLME Comm Status API
+ * @ingroup mac_15_4
+ * @{
+ * @brief Module to declare MAC MLME Comm Status API.
+ * @details The MAC Comm Status module declares communication status indication MLME routine and necessary
+ * macros/types according to the MAC specification. MAC MLME Comm Status indication is declared as
+ * mlme_comm_status_ind().
+ */
+
+/**
+ * @brief MLME-COMM-STATUS.indication
+ *
+ * @details The MLME-COMM-STATUS.indication primitive allows the MLME to indicate a
+ * communication status.
+ *
+ * In accordance with IEEE Std 802.15.4-2006, section 7.1.12.1
+ */
+typedef struct
+{
+ /**
+ * The 16-bit PAN identifier of the device from which the frame was received or to
+ * which the frame was being sent.
+ */
+ uint16_t pan_id;
+
+ /**
+ * The source addressing mode for this primitive. This value can take one of the
+ * following values:
+ * @ref mac_addr_mode_t
+ * 0x00 = no address (addressing fields omitted).
+ * 0x01 = reserved.
+ * 0x02 = 16-bit short address.
+ * 0x03 = 64-bit extended address.
+ */
+ mac_addr_mode_t src_addr_mode;
+
+ /**
+ * The individual device address of the entity from which the frame causing the error
+ * originated.
+ */
+ mac_addr_t src_addr;
+
+ /**
+ * The destination addressing mode for this primitive.
+ * According to 7.1.12.1.1, Table 69.
+ */
+ mac_addr_mode_t dst_addr_mode;
+
+ /** The individual device address of the device for which the frame was intended. */
+ mac_addr_t dst_addr;
+
+ /** The communications status. */
+ mac_status_t status;
+
+ uint8_t security_level; /**< Security level. */
+ uint8_t key_id_mode; /**< Key ID mode. */
+ uint64_t key_source; /**< Key source. */
+ uint8_t key_index; /**< Key index. */
+} mlme_comm_status_ind_t;
+
+
+/**
+ * @brief MLME-COMM-STATUS.indication handler
+ *
+ * @details The MLME-COMM-STATUS.indication primitive is generated by the MLME and issued to its next higher
+ * layer either following a transmission instigated through a response primitive or on receipt of a frame that
+ * generates an error in its security processing (see 7.5.8.2.3).
+ *
+ * @param ind MLME-COMM-STATUS.indication structure.
+ *
+ * In accordance with IEEE Std 802.15.4-2006, section 7.1.12.1
+ */
+extern void mlme_comm_status_ind(mlme_comm_status_ind_t * ind);
+
+/** @} */
+
+#endif // MAC_MLME_COMM_STATUS_H_INCLUDED
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/802_15_4/api/MAC/mac_mlme_disassociate.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/802_15_4/api/MAC/mac_mlme_disassociate.h
new file mode 100644
index 0000000..0610308
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/802_15_4/api/MAC/mac_mlme_disassociate.h
@@ -0,0 +1,199 @@
+/**
+ * Copyright (c) 2016 - 2018 Nordic Semiconductor ASA and Luxoft Global Operations Gmbh.
+ *
+ * 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#ifndef MAC_MLME_DISASSOCIATE_H_INCLUDED
+#define MAC_MLME_DISASSOCIATE_H_INCLUDED
+
+#if (CONFIG_DISASSOCIATE_ENABLED == 1)
+
+#include <stdint.h>
+#include <stdbool.h>
+#include "mac_common.h"
+#include "mac_task_scheduler.h"
+
+/** @file
+ * The MAC MLME Disassociate module declares the MAC disassociation routines and
+ * necessary types/macros according to the MAC specification.
+ *
+ * @defgroup mac_diassociate MAC MLME Disassociate API
+ * @ingroup mac_15_4
+ * @{
+ * @brief Module to declare MAC MLME Disassociate API.
+ * @details The MLME Disassociation module declares Disassociation MAC routines and necessary types
+ * according to the MAC specification. More specifically, MLME Disassociation request aka
+ * mlme_disassociate_req(), MLME Disassociation confirm callback typedef aka
+ * mlme_disassociate_conf_cb_t, and MLME Disassociation indication as mlme_disassociate_ind()
+ * primitives are declared.
+ */
+
+/**
+ * @brief MAC Disassociation Reason field
+ *
+ * In accordance with IEEE Std 802.15.4-2006, section 7.3.2.2
+ */
+typedef enum
+{
+ /** The coordinator wishes the device to leave the PAN. */
+ MAC_COORD_REASON = 1,
+ /** The device wishes to leave the PAN. */
+ MAC_DEV_REASON = 2
+} mac_disassociate_reason_t;
+
+
+/**
+ * @brief MLME-DISASSOCIATE.confirm
+ *
+ * @details On receipt of the MLME-DISASSOCIATE.confirm primitive, the next
+ * higher layer of the initiating device is notified of the result of the
+ * disassociation attempt. If the disassociation attempt was successful,
+ * the status parameter will be set to SUCCESS. Otherwise, the status parameter
+ * indicates the error.
+ *
+ * In accordance with IEEE Std 802.15.4-2006, section 7.1.4.3
+ */
+typedef struct
+{
+ mac_status_t status; /**< Status of operation. */
+ mac_addr_mode_t device_addr_mode; /**< Device addressing mode. */
+ uint16_t device_pan_id; /**< Device PAN ID. */
+ mac_addr_t device_address; /**< Device address. */
+} mlme_disassociate_conf_t;
+
+
+/**
+ * @brief MLME-DISASSOCIATE.request
+ *
+ * @details The MLME-DISASSOCIATE.request primitive is generated by the next
+ * higher layer of an associated device and issued to its MLME to request
+ * disassociation from the PAN. It is also generated by the next higher layer
+ * of the coordinator and issued to its MLME to instruct an
+ * associated device to leave the PAN.
+ *
+ * In accordance with IEEE Std 802.15.4-2006, section 7.1.4.1
+ */
+typedef struct
+{
+ /** Do not edit this field. */
+ mac_abstract_req_t service;
+
+ /** Confirm to this request. */
+ mlme_disassociate_conf_t confirm;
+
+ mac_addr_mode_t device_addr_mode; /**< Device addressing mode. */
+ uint16_t device_pan_id; /**< Device PAN ID. */
+ mac_addr_t device_address; /**< Device address. */
+ mac_disassociate_reason_t disassociate_reason; /**< Disassociation reason. */
+ bool tx_indirect; /**< Is TX indirect? */
+#if (CONFIG_SECURE == 1)
+ uint8_t security_level; /**< Security level. */
+ uint8_t key_id_mode; /**< Key ID mode. */
+ uint64_t key_source; /**< Key source. */
+ uint8_t key_index; /**< Key index. */
+#endif
+} mlme_disassociate_req_t;
+
+
+/**
+ * @brief MLME-DISASSOCIATE.indication
+ *
+ * @details Is generated by the MLME and issued to its next higher
+ * layer on receipt of a disassociation notification command.
+ *
+ * In accordance with IEEE Std 802.15.4-2006, section 7.1.4.2
+ */
+typedef struct
+{
+ uint64_t device_address; /**< Device address. */
+ mac_disassociate_reason_t disassociate_reason; /**< Disassociation reason. */
+#if (CONFIG_SECURE == 1)
+ uint8_t security_level; /**< Security level. */
+ uint8_t key_id_mode; /**< Key ID mode. */
+ uint64_t key_source; /**< Key source. */
+ uint8_t key_index; /**< Key index. */
+#endif
+} mlme_disassociate_ind_t;
+
+
+/**
+ * @brief Customer's function of confirmation
+ *
+ * @details The MLME-DISASSOCIATE.confirm primitive is generated by the initiating
+ * MLME and issued to its next higher layer in response to an MLME-DISASSOCIATE.request
+ * primitive. This primitive returns a status of either SUCCESS, indicating that the
+ * disassociation request was successful, or the appropriate error code.
+ * The status values are fully described in 7.1.4.1.3 and subclauses referenced by 7.1.4.1.3.
+ *
+ * @param pointer to confirmation primitive
+ */
+typedef void (* mlme_disassociate_conf_cb_t)(mlme_disassociate_conf_t *);
+
+
+/**
+ * @brief MLME-DISASSOCIATE request
+ *
+ * @details Request disassociation with a PAN
+ * After request completion, user callback will be issued with
+ * valid data stored in structure @ref mlme_disassociate_conf_t.
+ *
+ * @param req MLME_DISASSOCIATE request structure.
+ * @param conf_cb pointer to user callback.
+ *
+ * In accordance with IEEE Std 802.15.4-2006, section 7.1.4.4
+ */
+void mlme_disassociate_req(mlme_disassociate_req_t * req, mlme_disassociate_conf_cb_t conf_cb);
+
+
+/**
+ * @brief MLME-DISASSOCIATE indication handler
+ *
+ * @details Indicates an disassociation with a PAN
+ *
+ * @param ind MLME_DISASSOCIATE indication structure.
+ *
+ * In accordance with IEEE Std 802.15.4-2006, section 7.1.4.4
+ */
+extern void mlme_disassociate_ind(mlme_disassociate_ind_t * ind);
+
+/** @} */
+
+#endif // (CONFIG_DISASSOCIATE_ENABLED == 1)
+
+#endif // MAC_MLME_DISASSOCIATE_H_INCLUDED
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/802_15_4/api/MAC/mac_mlme_gts.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/802_15_4/api/MAC/mac_mlme_gts.h
new file mode 100644
index 0000000..42d6f0b
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/802_15_4/api/MAC/mac_mlme_gts.h
@@ -0,0 +1,211 @@
+/**
+ * Copyright (c) 2016 - 2018 Nordic Semiconductor ASA and Luxoft Global Operations Gmbh.
+ *
+ * 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#ifndef MAC_MLME_GTS_H_INCLUDED
+#define MAC_MLME_GTS_H_INCLUDED
+
+#if (CONFIG_GTS_ENABLED == 1)
+
+#include <stdint.h>
+#include "mac_common.h"
+#include "mac_task_scheduler.h"
+
+/** @file
+ * The MAC MLME GTS module declares the MAC Guaranteed time slots routines and
+ * necessary types/macros according to the MAC specification.
+ *
+ * @defgroup mac_gts MAC MLME GTS API
+ * @ingroup mac_15_4
+ * @{
+ * @brief Module to declare MAC MLME GTS API.
+ * @details The MAC GTS module declares MAC Guaranteed Time Slots routines and necessary types according to
+ * the MAC specification. More specifically, MLME GTS request aka mlme_gts_req(), MLME GTS indicaton
+ * aka mlme_gts_ind(), and MLME GTS confirm callback typedef aka mlme_gts_conf_cb_t primitives are
+ * declared.
+ */
+
+/**@brief GTS directions, from device side. */
+typedef enum
+{
+ MAC_GTS_DIR_TXONLY = 0, /**< TX only direction. */
+ MAC_GTS_DIR_RXONLY = 1 /**< RX only direction. */
+} mac_gts_direction_t;
+
+
+/**@brief GTS characteristics type. */
+typedef enum
+{
+ MAC_GTS_DEALLOC = 0, /**< GTS Dealloc. */
+ MAC_GTS_ALLOC = 1 /**< GTS Alloc. */
+} mac_gts_characteristics_type_t;
+
+
+/**@brief MAC GTS characteristics (not packed)
+ *
+ * @details See Section 7.3.9.2
+ */
+typedef union
+{
+ struct
+ {
+ uint8_t gts_length : 4;
+ uint8_t gts_direction : 1;
+ uint8_t characterictics_type : 1;
+ uint8_t : 2;
+ } bit;
+ uint8_t all;
+} mac_gts_characteristics_t;
+
+/**
+ * @brief MLME-GTS.confirm
+ *
+ * @details The MLME-GTS.confirm primitive reports the results of a
+ * request to allocate a new GTS or deallocate an existing GTS.
+ *
+ * In accordance with IEEE Std 802.15.4-2006, section 7.1.7.2
+ */
+typedef struct
+{
+ mac_gts_characteristics_t gts_characteristics; /**< GTS characteristics. */
+ mac_status_t status; /**< Status of operation. */
+} mlme_gts_conf_t;
+
+
+/**
+ * @brief MLME-GTS.request
+ *
+ * @details The MLME-GTS.request primitive allows a device to send a request
+ * to the PAN coordinator to allocate a new GTS or to deallocate an existing GTS.
+ * This primitive is also used by the PAN coordinator to initiate a GTS deallocation.
+ *
+ * In accordance with IEEE Std 802.15.4-2006, section 7.1.7.1
+ */
+typedef struct
+{
+ /** Do not edit this field. */
+ mac_abstract_req_t service;
+
+ /** Confirm to this request. */
+ mlme_gts_conf_t confirm;
+
+ mac_gts_characteristics_t gts_characteristics; /**< GTS characteristics. */
+#if (CONFIG_SECURE == 1)
+ uint8_t security_level; /**< Security level. */
+ uint8_t key_id_mode; /**< Key ID mode. */
+ uint64_t key_source; /**< Key source. */
+ uint8_t key_index; /**< Key index. */
+#endif
+} mlme_gts_req_t;
+
+
+/**
+ * @brief MLME-GTS.indication
+ *
+ * @details The MLME-GTS.indication primitive indicates that a
+ * GTS has been allocated or that a previously allocated GTS
+ * has been deallocated.
+ *
+ * In accordance with IEEE Std 802.15.4-2006, section 7.1.7.3
+ */
+typedef struct
+{
+ uint16_t device_address; /**< Device address. */
+ mac_gts_characteristics_t gts_characteristics; /**< GTS characteristics. */
+#if (CONFIG_SECURE == 1)
+ uint8_t security_level; /**< Security level. */
+ uint8_t key_id_mode; /**< Key ID mode. */
+ uint64_t key_source; /**< Key source. */
+ uint8_t key_index; /**< Key index. */
+#endif
+} mlme_gts_ind_t;
+
+
+/**
+ * @brief MLME-GTS confirm callback
+ *
+ * @details The MLME-GTS.confirm primitive is generated by the MLME and
+ * issued to its next higher layer in response to a previously
+ * issued MLME-GTS.request primitive.
+ *
+ * @param MLME_GTS callback structure.
+ *
+ * In accordance with IEEE Std 802.15.4-2006, section 7.1.7.4
+ */
+typedef void (* mlme_gts_conf_cb_t)(mlme_gts_conf_t *);
+
+
+/**
+ * @brief MLME-GTS request
+ *
+ * @details The MLME-GTS.request primitive is generated by the next higher
+ * layer of a device and issued to its MLME to request the allocation of a
+ * new GTS or to request the deallocation of an existing GTS. It is also
+ * generated by the next higher layer of the PAN coordinator and issued to
+ * its MLME to request the deallocation of an existing GTS.
+ *
+ * @param req MLME_GTS request structure.
+ * @param conf_cb pointer to user callback.
+ *
+ * In accordance with IEEE Std 802.15.4-2006, section 7.1.7.4
+ */
+void mlme_gts_req(mlme_gts_req_t * req, mlme_gts_conf_cb_t conf_cb);
+
+
+/**
+ * @brief MLME-GTS indication handler
+ *
+ * @details The MLME-GTS.indication primitive is generated by the MLME of
+ * the PAN coordinator to its next higher layer whenever a GTS is allocated
+ * or deallocated following the reception of a GTS request command (see 7.3.9)
+ * by the MLME. The MLME of the PAN coordinator also generates this primitive when a GTS
+ * deallocation is initiated by the PAN coordinator itself.
+ *
+ * @param ind MLME_GTS indication structure.
+ *
+ * In accordance with IEEE Std 802.15.4-2006, section 7.1.7.4
+ */
+extern void mlme_gts_ind(mlme_gts_ind_t * ind);
+
+/** @} */
+
+#endif // (CONFIG_GTS_ENABLED == 1)
+
+#endif // MAC_MLME_GTS_H_INCLUDED
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/802_15_4/api/MAC/mac_mlme_orphan.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/802_15_4/api/MAC/mac_mlme_orphan.h
new file mode 100644
index 0000000..28bf492
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/802_15_4/api/MAC/mac_mlme_orphan.h
@@ -0,0 +1,151 @@
+/**
+ * Copyright (c) 2016 - 2018 Nordic Semiconductor ASA and Luxoft Global Operations Gmbh.
+ *
+ * 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#ifndef MAC_MLME_ORPHAN_H_INCLUDED
+#define MAC_MLME_ORPHAN_H_INCLUDED
+
+#if (CONFIG_ORPHAN_ENABLED == 1)
+
+#include <stdint.h>
+#include <stdbool.h>
+#include "mac_common.h"
+
+/** @file
+ * The MAC MLME Orphan module declares the MAC Orphan routines and
+ * necessary types/macros according to the MAC specification.
+ *
+ * @defgroup mac_orphan MAC MLME Orphan API
+ * @ingroup mac_15_4
+ * @{
+ * @brief Module to declare MAC MLME Orphan API.
+ * @details The MAC Orphan module declares routines and necessary types to deal with the Orphan devices
+ * according to the MAC specification. More specifically, MAC MLME Orphan indication aka
+ * mlme_orphan_ind(), MAC MLME Orphan response aka mlme_orphan_resp() primitives are declared.
+ */
+
+/**
+ * @brief MLME-ORPHAN.indication
+ *
+ * @details The MLME-ORPHAN.indication primitive allows the MLME of a coordinator
+ * to notify the next higher layer of the presence of an orphaned device.
+ *
+ * In accordance with IEEE Std 802.15.4-2006, section 7.1.8.1
+ */
+typedef struct
+{
+ /** The address of the orphaned device. */
+ uint64_t orphan_address;
+#if (CONFIG_SECURE == 1)
+ uint8_t security_level; /**< Security level. */
+ uint8_t key_id_mode; /**< Key ID mode. */
+ uint64_t key_source; /**< Key source. */
+ uint8_t key_index; /**< Key index. */
+#endif
+} mlme_orphan_ind_t;
+
+
+/**
+ * @brief MLME-ORPHAN.response
+ *
+ * @details The MLME-ORPHAN.response primitive allows the next higher layer of a coordinator
+ * to respond to the MLME-ORPHAN.indication primitive.
+ *
+ * In accordance with IEEE Std 802.15.4-2006, section 7.1.8.2
+ */
+typedef struct
+{
+ /** Do not edit this field. */
+ mac_abstract_req_t service;
+
+ /** The address of the orphaned device. */
+ uint64_t orphan_address;
+
+ /**
+ * The 16-bit short address allocated to the orphaned device if it is associated with this
+ * coordinator. The special short address 0xfffe indicates that no short address was
+ * allocated, and the device will use its 64-bit extended address in all communications.
+ * If the device was not associated with this coordinator, this field will contain the
+ * value 0xffff and be ignored on receipt.
+ */
+ uint16_t short_address;
+
+ /** TRUE if the orphaned device is associated with this coordinator or FALSE otherwise. */
+ bool associated_member;
+#if (CONFIG_SECURE == 1)
+ uint8_t security_level; /**< Security level. */
+ uint8_t key_id_mode; /**< Key ID mode. */
+ uint64_t key_source; /**< Key source. */
+ uint8_t key_index; /**< Key index. */
+#endif
+} mlme_orphan_resp_t;
+
+
+/**
+ * @brief MLME-ORPHAN.indication handler
+ *
+ * @details The MLME-ORPHAN.indication primitive is generated by the MLME of a coordinator
+ * and issued to its next higher layer on receipt of an orphan notification command (see 7.3.6).
+ *
+ * @param ind MLME-ORPHAN.indication structure.
+ *
+ * In accordance with IEEE Std 802.15.4-2006, section 7.1.8.1
+ */
+extern void mlme_orphan_ind(mlme_orphan_ind_t * ind);
+
+
+/**
+ * @brief MLME-ORPHAN.response handler
+ *
+ * @details The MLME-ORPHAN.response primitive is generated by the next higher layer and issued to its MLME
+ * when it reaches a decision about whether the orphaned device indicated in the MLME-ORPHAN.indication
+ * primitive is associated.
+ *
+ * @param resp MLME-ORPHAN.response structure.
+ *
+ * In accordance with IEEE Std 802.15.4-2006, section 7.1.8.2
+ */
+void mlme_orphan_resp(mlme_orphan_resp_t * resp);
+
+/** @} */
+
+#endif // (CONFIG_ORPHAN_ENABLED == 1)
+
+#endif // MAC_MLME_ORPHAN_H_INCLUDED
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/802_15_4/api/MAC/mac_mlme_pib.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/802_15_4/api/MAC/mac_mlme_pib.h
new file mode 100644
index 0000000..fd7ce17
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/802_15_4/api/MAC/mac_mlme_pib.h
@@ -0,0 +1,508 @@
+/**
+ * Copyright (c) 2016 - 2018 Nordic Semiconductor ASA and Luxoft Global Operations Gmbh.
+ *
+ * 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#ifndef MAC_MLME_PIB_H_INCLUDED
+#define MAC_MLME_PIB_H_INCLUDED
+
+#include <stdint.h>
+#include "mac_common.h"
+#include "phy_plme_pib.h"
+#include "mac_task_scheduler.h"
+#include "mac_security.h"
+#include "sys_debug.h"
+
+/** @file
+ * The MAC MLME PIB module declares the MAC PHY Information Base routines and
+ * necessary types/macros according to the MAC specification.
+ *
+ * @defgroup mac_pib MAC MLME PIB API
+ * @ingroup mac_15_4
+ * @{
+ * @brief Module to declare MAC MLME PIB API.
+ * @details The MAC PIB module declares routines and necessary types to deal with the PHY Information Base
+ * functionality related to MAC. More specifically, MLME PIB Get request aka mlme_get_req(), MLME
+ * PIB Set request aka mlme_set_req(), MLME PIB confirmation callbacks aka mlme_get_conf_cb_t, and
+ * mlme_set_conf_cb_t primitives are declared. Two additional primitives not covered by the
+ * standard are declared. These are mlme_get() and mlme_set() which are synchronous versions of
+ * mlme_get_req() and mlme_set_req() accordingly. There is one helper informational routine
+ * mlme_pib_attr_size_calc() to count MLME attribute size in bytes. Refer to the
+ * mac_pib_param_test application for detailed samples of implementation of these primitives.
+ * This module also defines the MAC Table API. The tables can be used to deal with MAC attributes.
+ * A special initialization routine mac_table_init() should be called before using of any other MAC
+ * table API. The mac_table_reset() routine is used to clean up an existing (initialized) table.
+ * mac_table_idx_get() searches through a MAC table to find the item with requested idx. The
+ * mac_table_item_set() routine is needed to substitute a table item with a new value. The
+ * mac_table_item_remove() routine removes the item with the given index from the table and
+ * frees all resources associated with the item. mac_table_item_front() and mac_table_item_next()
+ * return the first and next item from the table. The mac_table_size_get() routine returns the
+ * number of items in the table, while mac_table_is_empty() checks if the table is empty.
+ */
+
+/**
+ * @brief MAC PIB attribute identifiers
+ *
+ * In accordance with IEEE Std 802.15.4-2006, section 7.4.2
+ */
+typedef enum
+{
+ MAC_ACK_WAIT_DURATION = 0x40,
+ MAC_ASSOCIATION_PERMIT,
+ MAC_AUTO_REQUEST,
+ MAC_BATT_LIFE_EXT,
+ MAC_BATT_LIFE_EXT_PERIODS,
+ MAC_BEACON_PAYLOAD, /* 0x45 */
+ MAC_BEACON_PAYLOAD_LENGTH,
+ MAC_BEACON_ORDER, /**< Specification of how often the
+ coordinator transmits its
+ beacon. If BO = 15, the
+ coordinator will not transmit
+ a periodic beacon.*/
+ MAC_BEACON_TX_TIME,
+ MAC_BSN,
+ MAC_COORD_EXTENDED_ADDRESS, /* 0x4A */
+ MAC_COORD_SHORT_ADDRESS,
+ MAC_DSN,
+ MAC_GTS_PERMIT,
+ MAC_MAX_CSMA_BACKOFFS,
+ MAC_MIN_BE,
+ MAC_PAN_ID, /**< PAN Identifier.*/
+ /* 0x50 */
+ MAC_PROMISCUOUS_MODE,
+ MAC_RX_ON_WHEN_IDLE,
+ MAC_SHORT_ADDRESS, /**< MAC Short Address.*/
+ MAC_SUPERFRAME_ORDER,
+ MAC_TRANSACTION_PERSISTENCE_TIME, /* 0x55 */
+ MAC_ASSOCIATED_PAN_COORD,
+ MAC_MAX_BE,
+ MAC_MAX_FRAME_TOTAL_WAIT_TIME,
+ MAC_MAX_FRAME_RETRIES,
+ MAC_RESPONSE_WAIT_TIME, /* 0x5A */
+ MAC_SYNC_SYMBOL_OFFSET,
+ MAC_TIMESTAMP_SUPPORTED,
+ MAC_SECURITY_ENABLED,
+ MAC_MIN_LIFS_PERIOD, /* 0x5E No attribute id in Table 86.*/
+ MAC_MIN_SIFS_PERIOD, /* 0x5F No attribute id in Table 86.*/
+ MAC_EXTENDED_ADDRESS, /**< MAC Extended Address.*/
+ /* 0x60 Not covered by standard.*/
+ MAC_IS_PAN_COORD,
+
+#if (CONFIG_SECURE == 1)
+ MAC_KEY_TABLE = 0x71,
+ MAC_KEY_TABLE_ENTRIES,
+ MAC_DEVICE_TABLE,
+ MAC_DEVICE_TABLE_ENTRIES,
+ MAC_SECURITY_LEVEL_TABLE, /* 0x75 */
+ MAC_SECURITY_LEVEL_TABLE_ENTRIES,
+ MAC_FRAME_COUNTER,
+ MAC_AUTO_REQUEST_SECURITY_LEVEL,
+ MAC_AUTO_REQUEST_KEY_ID_MODE,
+ MAC_AUTO_REQUEST_KEY_SOURCE, /* 0x7A */
+ MAC_AUTO_REQUEST_KEY_INDEX,
+ MAC_DEFAULT_KEY_SOURCE,
+ MAC_PAN_COORD_EXTENDED_ADDRESS,
+ MAC_PAN_COORD_SHORT_ADDRESS,
+
+ /* Items below do not covered by the standard */
+
+ // these three IDs are used to make access to the root of security tables
+ MAC_KEY_TABLE_POINTER,
+ MAC_DEVICE_TABLE_POINTER,
+ MAC_SECURITY_LEVEL_TABLE_POINTER,
+
+ // these three IDs are stored inside PIB base and
+ // used to get table item sizes
+ MAC_KEY_ID_LOOKUP_LIST,
+ MAC_KEY_DEVICE_LIST,
+ MAC_KEY_USAGE_LIST,
+#endif
+} mlme_pib_attr_id_t;
+
+
+/**
+ * @brief United PIB attribute identifiers
+ *
+ * To unite access to MAC and PHY PIB by one API
+ */
+typedef union
+{
+ mlme_pib_attr_id_t mlme_id; /**< PIB is MAC-based. */
+ plme_pib_attr_id_t plme_id; /**< PIB is PHY-based. */
+} pib_id_t;
+
+
+/**
+ * @brief MLME-GET.confirm
+ *
+ * @details structure for confirming information about a given PIB attribute.
+ *
+ * In accordance with IEEE Std 802.15.4-2006, section 7.1.6.2
+ */
+typedef struct
+{
+ mac_status_t status; /**< Status of operation. */
+ pib_id_t pib_attribute; /**< PIB Attribute. */
+ uint8_t pib_attribute_idx; /**< PIB Attribute index. */
+ /** value size is calculated with 'mlme_pib_attr_size_calc' */
+ uint8_t * value; /**< Attribute value. */
+} mlme_get_conf_t;
+
+
+/**
+ * @brief MLME-GET.request
+ *
+ * @details structure for requesting information about a given PIB attribute.
+ *
+ * In accordance with IEEE Std 802.15.4-2006, section 7.1.6.1
+ */
+typedef struct
+{
+ /** Do not edit this field. */
+ mac_abstract_req_t service;
+
+ /** Confirm to this request. */
+ mlme_get_conf_t confirm;
+
+ pib_id_t pib_attribute; /**< PIB Attribute. */
+ uint8_t pib_attribute_idx; /**< PIB Attribute index. */
+} mlme_get_req_t;
+
+
+/**
+ * @brief MLME-SET.confirm
+ *
+ * @details structure for reporting the results of an attempt to write a value
+ * to a PIB attribute.
+ *
+ * In accordance with IEEE Std 802.15.4-2006, section 7.1.13.2
+ */
+typedef struct
+{
+ mac_status_t status; /**< Status of operation. */
+ pib_id_t pib_attribute; /**< PIB Attribute. */
+ uint8_t pib_attribute_idx; /**< PIB Attribute index. */
+} mlme_set_conf_t;
+
+
+/**
+ * @brief MLME-SET.request
+ *
+ * @details structure for setting a PIB attribute.
+ *
+ * In accordance with IEEE Std 802.15.4-2006, section 7.1.13.1
+ */
+typedef struct
+{
+ /** Do not edit this field. */
+ mac_abstract_req_t service;
+
+ /** Confirm to this request. */
+ mlme_set_conf_t confirm;
+
+ pib_id_t pib_attribute; /**< PIB Attribute. */
+ uint8_t pib_attribute_idx; /**< PIB Attribute index. */
+ uint8_t * value; /**< Attribute value. The value size is calculated
+ with mlme_pib_attr_size_calc. */
+} mlme_set_req_t;
+
+
+/**
+ * @brief Customer's function of confirmation
+ *
+ * @details The MLME-GET.confirm primitive is generated by the MLME and issued
+ * to its next higher layer in response to an MLME-GET.request primitive.
+ * This primitive returns a status of either SUCCESS, indicating that the request
+ * to read a PIB attribute was successful, or an error code of UNSUPPORTED_ATTRIBUTE.
+ * When an error code of UNSUPPORTED_ATTRIBUTE is returned, the PIBAttribute value
+ * parameter will be set to length zero. The status values are fully described in 7.1.6.1.3.
+ *
+ * @param pointer to confirmation primitive
+ */
+typedef void (* mlme_get_conf_cb_t)(mlme_get_conf_t *);
+
+
+/**
+ * @brief Customer's function of confirmation
+ *
+ * @details The MLME-SET.confirm primitive is generated by the MLME and issued to its
+ * next higher layer in response to an MLME-SET.request primitive. The MLME-SET.confirm
+ * primitive returns a status of either SUCCESS, indicating that the requested value was
+ * written to the indicated PIB attribute, or the appropriate error code.
+ * The status values are fully described in 7.1.13.1.3.
+ *
+ * @param pointer to confirmation primitive
+ */
+typedef void (* mlme_set_conf_cb_t)(mlme_set_conf_t *);
+
+
+/**
+ * @brief MLME-GET request
+ *
+ * @details Request information about a given PIB attribute.
+ *
+ * @param[in] req pointer to request structure.
+ * @param[in] conf_cb pointer to user callback.
+ *
+ * In accordance with IEEE Std 802.15.4-2006, section 7.1.6.
+ * See \a mlme_get() for more details.
+ */
+void mlme_get_req(mlme_get_req_t * req, mlme_get_conf_cb_t conf_cb);
+
+
+/**
+ * @brief MLME-SET request
+ *
+ * @details Request to set a PIB attribute.
+ * After request completion, user callback will be issued with
+ * valid data stored in structure @ref mlme_set_conf_t.
+ *
+ * See \a mlme_set() for more details.
+ *
+ * In accordance with IEEE Std 802.15.4-2006, section 7.1.13
+ *
+ * @param[in] req MLME_SET request structure.
+ * @param[in] conf_cb pointer to user callback.
+ */
+void mlme_set_req(mlme_set_req_t * req, mlme_set_conf_cb_t conf_cb);
+
+
+/**
+ * @brief Counts MLME attribute size
+ *
+ * @details This is an implementation-specific function not covered by the standard.
+ *
+ * @param[in] id attribute id.
+ * @param[in] idx index inside the table in case the attribute is a table.
+ *
+ * @return size of attribute in bytes.
+ */
+size_t mlme_pib_attr_size_calc(pib_id_t id, uint8_t idx);
+
+
+/**
+ * @brief Gets parameters from PIB directly (without request - confirm approach)
+ *
+ * @details Optional. Not covered by a standard.
+ *
+ * For non-tabled attributes this function will return value to location
+ * passed to the last argument.
+ *
+ * For tabled attributes this function will return pointer to
+ * a descriptor structure of corresponding table.
+ *
+ * @param[in] id attribute id.
+ * @param[in] idx index inside the table in case the attribute is a table.
+ * @param[out] mem either pointer to memory where attribute value is returned
+ * (for all attributes except MAC_KEY_TABLE, MAC_DEVICE_TABLE,
+ * MAC_SECURITY_LEVEL_TABLE), or pointer to memory where pointer
+ * to attribute storage place is returned.
+ *
+ * @return status of operation
+ */
+mac_status_t mlme_get(pib_id_t id, uint8_t idx, void * mem);
+
+
+/**
+ * @brief Sets parameters to PIB directly (without request - confirm approach)
+ *
+ * @details Optional. Not covered by a standard.
+ *
+ * This function performs copying or replacement of some attribute value
+ * into the PIB base memory.
+ *
+ * Note, that all security tables are copied into dynamic memory, that
+ * mlme_set is responsible to allocate. For nested tables copying is done
+ * in a shallow manner (in Python sense). It means that passed \a mac_key_descr_t
+ * is copied as-is, without creating copies of internal tables.
+ * Caller must allocate and prepare all nested tables such as
+ * #MAC_KEY_DEVICE_LIST, #MAC_KEY_ID_LOOKUP_LIST and #MAC_KEY_USAGE_LIST
+ * before calling this function.
+ *
+ * Passed attribute value will replace the current one, if the item with such
+ * \a id and \a idx already exists. This function is responsible for
+ * freeing all items during destruction of existing objects.
+ *
+ * @note Nested tables may be expanded and reduced with \a mac_table_item_set()
+ * and other similar functions.
+ *
+ * @param[in] id attribute id.
+ * @param[in] idx index inside the table in case the attribute is a table.
+ * @param[out] mem pointer to memory for parameter storing.
+ *
+ * @return status of operation
+ */
+mac_status_t mlme_set(pib_id_t id, uint8_t idx, void * mem);
+
+
+#if (CONFIG_SECURE == 1)
+/**
+ * @brief Initializes a table. This function MUST be called before accessing
+ * to a newly allocated table.
+ *
+ * @param[out] p_table Pointer to a fresh table.
+ */
+void mac_table_init(mac_table_t * p_table);
+
+/**
+ * @brief Resets a table, freeing all its elements.
+ *
+ * @param[in] p_table Pointer to the table to reset.
+ * @param[in] id One of #MAC_KEY_TABLE, #MAC_DEVICE_TABLE, #MAC_SECURITY_LEVEL_TABLE,
+ * #MAC_KEY_ID_LOOKUP_LIST, #MAC_KEY_DEVICE_LIST, #MAC_KEY_USAGE_LIST to let
+ * function know about the size of p_item.
+ */
+void mac_table_reset(mac_table_t * p_table, mlme_pib_attr_id_t id);
+
+/**
+ * @brief Searches through mac_table_t and finds the item with requested idx.
+ *
+ * @param[in] p_table Table to search through.
+ * @param[in] idx Item idx to match.
+ *
+ * @return Pointer to mac_table_item_t with requested idx or NULL if such
+ * an item cannot be found.
+ */
+mac_table_item_t * mac_table_idx_get(const mac_table_t * p_table, uint8_t idx);
+
+/**
+ * @brief Sets new value item for mac_table_t.
+ *
+ * @param[out] p_table Pointer to the table to add item to.
+ * @param[in] p_item Pointer to a new item. This item must include appropriate idx
+ * (less than the maximum table size).
+ * @param[in] id One of #MAC_KEY_TABLE, #MAC_DEVICE_TABLE, #MAC_SECURITY_LEVEL_TABLE,
+ * #MAC_KEY_ID_LOOKUP_LIST, #MAC_KEY_DEVICE_LIST, #MAC_KEY_USAGE_LIST to let
+ * function know about the size of p_item.
+ * @param[in] idx Item index inside the selected table.
+ *
+ * @details This function performs a "deep copy" of passed table item to conform with
+ * mlme_set behavior. New copy resides in the heap memory. If an item with requested
+ * idx has been already set earlier, this function frees the old item and pushes
+ * a new one instead.
+ *
+ * @retval #MAC_INVALID_INDEX if idx exceeds allowed maximum number of items in
+ * the table.
+ * @retval #MAC_LIMIT_REACHED if there is no enough dynamic memory to put this item
+ * into the security table.
+ * @retval #MAC_SUCCESS if insertion has been performed successfully.
+ */
+mac_status_t mac_table_item_set(mac_table_t * p_table,
+ const mac_table_item_t * p_item,
+ mlme_pib_attr_id_t id,
+ uint8_t idx);
+
+/**
+ * @brief Removes an item from a mac_table_t instance and frees all resources,
+ * associated with this item.
+ *
+ * @param[out] p_table Pointer to the table to remove item from.
+ * @param[in] id One of #MAC_KEY_TABLE, #MAC_DEVICE_TABLE, #MAC_SECURITY_LEVEL_TABLE,
+ * #MAC_KEY_ID_LOOKUP_LIST, #MAC_KEY_DEVICE_LIST, #MAC_KEY_USAGE_LIST to let
+ * function perform down-casting correctly.
+ * @param[in] idx Item index inside of selected table.
+ *
+ * @retval #MAC_INVALID_INDEX if passed index is not found in the table or exceeds
+ * the allowed maximum.
+ * @retval #MAC_SUCCESS if no errors happen during removing.
+ */
+mac_status_t mac_table_item_remove(mac_table_t * p_table,
+ mlme_pib_attr_id_t id,
+ uint8_t idx);
+
+/**
+ * @brief Gets first available item from a table.
+ *
+ * @details This function might be used along with \a mac_table_item_next to
+ * search through some table.
+ *
+ * @param[in] p_table Pointer to a MAC table.
+ *
+ * @return Pointer to the first table item or NULL if the table is empty.
+ */
+mac_table_item_t * mac_table_item_front(const mac_table_t * p_table);
+
+/**
+ * @brief Returns the next available item in table.
+ *
+ * @details MAC tables are stored unsorted in memory, so there is no guarantee that
+ * index of the next item is always greater or smaller than the current one.
+ * Items are not stored in chronological order either.
+ *
+ * @param[in] p_table Pointer to a table to select item from.
+ * @param[in] p_current_item Pointer to the current item.
+ *
+ * @return Pointer to the next item in table or NULL, if the item is the last one.
+ */
+mac_table_item_t * mac_table_item_next(const mac_table_t * p_table,
+ const mac_table_item_t * p_current_item);
+
+/**
+ * @brief Gets number of items used inside mac_table_t.
+ *
+ * @param[in] p_table Pointer to interested table.
+ *
+ * @return 8-bit integer equal to number of items inside the table that have
+ * been set at least once.
+ */
+static inline uint8_t mac_table_size_get(const mac_table_t * p_table)
+{
+ ASSERT(p_table != NULL);
+
+ return p_table->size;
+}
+
+/**
+ * @brief This function checks if a MAC table is empty.
+ *
+ * @param[in] p_table Pointer to a MAC table.
+ *
+ * @return true if there are no items inside table, false otherwise.
+ */
+static inline bool mac_table_is_empty(const mac_table_t * p_table)
+{
+ ASSERT(p_table != NULL);
+
+ return sys_queue_is_empty(&p_table->queue);
+}
+#endif
+
+/** @} */
+
+#endif // MAC_MLME_PIB_H_INCLUDED
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/802_15_4/api/MAC/mac_mlme_poll.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/802_15_4/api/MAC/mac_mlme_poll.h
new file mode 100644
index 0000000..7377169
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/802_15_4/api/MAC/mac_mlme_poll.h
@@ -0,0 +1,151 @@
+/**
+ * Copyright (c) 2016 - 2018 Nordic Semiconductor ASA and Luxoft Global Operations Gmbh.
+ *
+ * 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#ifndef MAC_MLME_POLL_H_INCLUDED
+#define MAC_MLME_POLL_H_INCLUDED
+
+#include <stdint.h>
+#include "mac_common.h"
+#include "mac_task_scheduler.h"
+
+/** @file
+ * The MAC MLME Poll module declares the MAC Poll primitives and necessary types
+ * according to the MAC specification.
+ *
+ * @defgroup mac_poll MAC MLME Poll API
+ * @ingroup mac_15_4
+ * @{
+ * @brief Module to declare MAC MLME Poll API.
+ * @details The MAC Poll module declares MLME Poll primitives and necessary types according to
+ * the MAC specification. More specifically, MLME Poll request aka mlme_poll_req(), MLME Poll
+ * indicaton aka mlme_poll_ind(), and MLME Poll confirm callback typedef aka mlme_poll_conf_cb_t
+ * primitives are declared.
+ */
+
+/**@brief MLME-POLL.confirm
+ *
+ * @details The MLME-POLL.confirm primitive reports the results of a request
+ * to poll the coordinator for data.
+ *
+ * In accordance with IEEE Std 802.15.4-2006, section 7.1.16.2
+ */
+typedef struct
+{
+ mac_status_t status; /**< Status of operation. */
+} mlme_poll_conf_t;
+
+
+/**@brief MLME-POLL.request
+ *
+ * @details The MLME-POLL.request primitive prompts the device
+ * to request data from the coordinator.
+ *
+ * In accordance with IEEE Std 802.15.4-2006, section 7.1.16.1
+ */
+typedef struct
+{
+ /** Do not edit this field. */
+ mac_abstract_req_t service;
+
+ /** Confirm to this request. */
+ mlme_poll_conf_t confirm;
+
+ mac_addr_mode_t coord_addr_mode; /**< Coordinator address mode. */
+ uint16_t coord_pan_id; /**< Coordinator PAN ID. */
+ mac_addr_t coord_address; /**< Coordinator address. */
+#if (CONFIG_SECURE == 1)
+ uint8_t security_level; /**< Security level. */
+ uint8_t key_id_mode; /**< Key ID mode. */
+ uint64_t key_source; /**< Key source. */
+ uint8_t key_index; /**< Key index. */
+#endif
+} mlme_poll_req_t;
+
+/** @brief MLME-Poll.indication
+ *
+ * @details The MLME-POLL.indication primitive indicates the reception
+ * of a Data request command frame by the MAC sub-layer and issued to
+ * the local SSCS (service specific convergence sublayer).
+ */
+typedef struct
+{
+ mac_addr_mode_t src_addr_mode; /**< Source address mode. */
+ mac_addr_t src_address; /**< Source address. */
+} mlme_poll_ind_t;
+
+
+/**@brief Prototype of the user-implemented MLME-POLL.confirm callback function.
+ *
+ * @details The MLME-POLL.confirm primitive is generated by the MLME and issued
+ * to its next higher layer in response to an MLME-POLL.request primitive.
+ * If the request was successful, the status parameter will be equal to SUCCESS,
+ * indicating a successful poll for data. Otherwise, the status parameter indicates the
+ * appropriate error code. The status values are fully described in 7.1.16.1.3 and
+ * the subclauses referenced by 7.1.16.1.3.
+ *
+ * @param pointer to a confirmation primitive.
+ */
+typedef void (* mlme_poll_conf_cb_t)(mlme_poll_conf_t *);
+
+
+/**@brief MLME-POLL.request
+ *
+ * @details The MLME-POLL.request primitive is generated by the next higher layer and
+ * issued to its MLME when data are to be requested from a coordinator.
+ *
+ * @param[in] req MLME-POLL.request parameters
+ * @param[in] conf_cb User-implemented callback function, which will be
+ * called by MLME in order to pass MLME-POLL.confirm to the user.
+ */
+void mlme_poll_req(mlme_poll_req_t * req, mlme_poll_conf_cb_t conf_cb);
+
+/**@brief MLME-POLL.indication
+ *
+ * @details The MLME-Poll.indication primitive notifies the next higher level that
+ * a request for data has been received.
+ *
+ * @param[in] p_ind pointer to a poll indication structure
+ */
+extern void mlme_poll_ind(mlme_poll_ind_t * p_ind);
+
+/** @} */
+
+#endif // MAC_MLME_POLL_H_INCLUDED
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/802_15_4/api/MAC/mac_mlme_reset.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/802_15_4/api/MAC/mac_mlme_reset.h
new file mode 100644
index 0000000..fdaf8d7
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/802_15_4/api/MAC/mac_mlme_reset.h
@@ -0,0 +1,125 @@
+/**
+ * Copyright (c) 2016 - 2018 Nordic Semiconductor ASA and Luxoft Global Operations Gmbh.
+ *
+ * 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#ifndef MAC_MLME_RESET_H_INCLUDED
+#define MAC_MLME_RESET_H_INCLUDED
+
+#include <stdint.h>
+#include <stdbool.h>
+#include "mac_common.h"
+#include "mac_task_scheduler.h"
+
+/** @file
+ * The MAC MLME Reset module declares the MAC Reset primitives and necessary types
+ * according to the MAC specification.
+ *
+ * @defgroup mac_reset MAC MLME Reset API
+ * @ingroup mac_15_4
+ * @{
+ * @brief Module to declare MAC MLME Reset API.
+ * @details The MAC Reset module declares MLME Reset primitives and necessary types according to
+ * the MAC specification. More specifically, MLME Reset request aka mlme_reset_req(), and MLME
+ * Reset confirm callback typedef aka mlme_reset_conf_cb_t primitives are declared.
+ */
+
+/**@brief MLME-Reset.confirm
+ *
+ * @details The MLME-Reset.confirm primitive reports the results of a request
+ * to reset MAC layer of the device.
+ *
+ * In accordance with IEEE Std 802.15.4-2006, section 7.1.9.2
+ */
+typedef struct
+{
+ mac_status_t status; /**< Status of operation. */
+} mlme_reset_conf_t;
+
+/**@brief MLME-RESET.request
+ *
+ * @details The MLME-RESET.request primitive allows the next
+ * higher layer to request that the MLME performs a reset operation.
+ *
+ * In accordance with IEEE Std 802.15.4-2006, section 7.1.9.1
+ */
+typedef struct
+{
+ /** Do not edit this field. */
+ mac_abstract_req_t service;
+
+ /** Confirm to this request. */
+ mlme_reset_conf_t confirm;
+
+ bool set_default_pib; /**< Set the default PIB. */
+} mlme_reset_req_t;
+
+
+/**
+ * @brief MLME-RESET confirm callback
+ *
+ * @details The MLME-RESET.confirm primitive is generated by the MLME and
+ * issued to its next higher layer in response to an MLME-RESET.request primitive and
+ * following the receipt of the PLME-SET-TRXSTATE.confirm primitive.
+ *
+ * @param reset status (@c MAC_SUCCESS only).
+ *
+ * In accordance with IEEE Std 802.15.4-2006, section 7.1.9.2
+ */
+typedef void (* mlme_reset_conf_cb_t)(mlme_reset_conf_t *);
+
+
+/**
+ * @brief MLME-RESET request
+ *
+ * @details The MLME-RESET.request primitive is generated by the next higher layer and
+ * issued to the MLME to request a reset of the MAC sublayer to its initial conditions.
+ * The MLME-RESET.request primitive is issued prior to the use of the MLME-START.request
+ * or the MLME-ASSOCIATE.request primitives.
+ *
+ * @param[in] req pointer to MCPS-RESET.request structure.
+ * @param[in] conf_cb pointer to user callback.
+ *
+ * In accordance with IEEE Std 802.15.4-2006, section 7.1.9.1
+ */
+void mlme_reset_req(mlme_reset_req_t * req, mlme_reset_conf_cb_t conf_cb);
+
+/** @} */
+
+#endif // MAC_MLME_RESET_H_INCLUDED
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/802_15_4/api/MAC/mac_mlme_rx_enable.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/802_15_4/api/MAC/mac_mlme_rx_enable.h
new file mode 100644
index 0000000..ab674d6
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/802_15_4/api/MAC/mac_mlme_rx_enable.h
@@ -0,0 +1,181 @@
+/**
+ * Copyright (c) 2016 - 2018 Nordic Semiconductor ASA and Luxoft Global Operations Gmbh.
+ *
+ * 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#ifndef MAC_MLME_RX_ENABLE_H_INCLUDED
+#define MAC_MLME_RX_ENABLE_H_INCLUDED
+
+#if (CONFIG_RXE_ENABLED == 1)
+
+#include <stdint.h>
+#include <stdbool.h>
+#include "mac_common.h"
+#include "mac_task_scheduler.h"
+
+/** @file
+ * The MAC MLME RX-Enable module declares the MAC RX-Enable primitives and necessary types
+ * according to the MAC specification.
+ *
+ * @defgroup mac_rx_enable MAC MLME RX-Enable API
+ * @ingroup mac_15_4
+ * @{
+ * @brief Module to declare MAC MLME RX-Enable API.
+ * @details The MAC RX-Enable module declares MLME RX-Enable primitives and necessary types according to
+ * the MAC specification. More specifically, MLME RX-Enable request aka mlme_rx_enable_req(),
+ * and MLME RX-Enable confirm callback typedef aka mlme_rx_enable_conf_cb_t primitives are
+ * declared. One additional primitive not covered by the standard is declared. This is
+ * mlme_rx_enable() which is synchronous (i.e. does not require confirmation) version of
+ * mlme_rx_enable_req().
+ */
+
+/**
+ * @brief MLME-RX-ENABLE.confirm
+ *
+ * @details The MLME-RX-ENABLE.confirm primitive reports the results of an attempt
+ * to enable or disable the receiver.
+ *
+ * In accordance with IEEE Std 802.15.4-2006, section 7.1.10.2
+ */
+typedef struct
+{
+ mac_status_t status; /**< Status of operation. */
+} mlme_rx_enable_conf_t;
+
+
+/**
+ * @brief MLME-RX-ENABLE.request
+ *
+ * @details The MLME-RX-ENABLE.request primitive allows the next higher layer
+ * to request that the receiver is either enabled for a finite period of time or disabled.
+ *
+ * In accordance with IEEE Std 802.15.4-2006, section 7.1.10.1
+ */
+typedef struct
+{
+ /** Do not edit this field. */
+ mac_abstract_req_t service;
+
+ /** Confirm to this request. */
+ mlme_rx_enable_conf_t confirm;
+
+ /**
+ * @details
+ * TRUE if the requested operation can be deferred until the next superframe
+ * if the requested time has already passed.
+ * FALSE if the requested operation is only to be attempted in the current superframe.
+ *
+ * If the issuing device is the PAN coordinator, the term superframe refers to its own
+ * superframe. Otherwise, the term refers to the superframe of the coordinator through
+ * which the issuing device is associated.
+ *
+ * @note This parameter is ignored for nonbeacon-enabled PANs.
+ */
+ bool defer_permit;
+
+ /**
+ * @details
+ * The number of symbols measured from the start of the superframe before the receiver is
+ * to be enabled or disabled.
+ * This is a 24-bit value, and the precision of this value shall be a minimum of 20 bits,
+ * with the lowest 4 bits being the least significant.
+ *
+ * If the issuing device is the PAN coordinator, the term superframe refers to its own
+ * superframe. Otherwise, the term refers to the superframe of the coordinator through
+ * which the issuing device is associated.
+ *
+ * @note This parameter is ignored for nonbeacon-enabled PANs.
+ */
+ uint32_t rx_on_time;
+
+ /**
+ * The number of symbols the receiver is to be enabled for.
+ *
+ * If this parameter is equal to 0x000000, the receiver is to be disabled.
+ */
+ uint32_t rx_on_duration;
+} mlme_rx_enable_req_t;
+
+
+/**
+ * @brief Customer's function of confirmation.
+ *
+ * @details The MLME-RX-ENABLE.confirm primitive is generated by the MLME and issued to
+ * its next higher layer in response to an MLME-RX-ENABLE.request primitive.
+ *
+ * @param pointer to a confirmation primitive.
+ */
+typedef void (* mlme_rx_enable_conf_cb_t)(mlme_rx_enable_conf_t *);
+
+/**
+ * @brief MLME-RX-ENABLE.request service
+ *
+ * @details The MLME-RX-ENABLE.request primitive is generated by the next higher layer and
+ * issued to the MLME to enable the receiver for a fixed duration, at a time relative to the
+ * start of the current or next superframe on a beacon-enabled PAN or immediately on a
+ * nonbeacon-enabled PAN. This primitive may also be generated to cancel a previously generated
+ * request to enable the receiver. After request completion, user callback will be issued with
+ * valid data stored in structure mlme_rx_enable_conf_t.
+ *
+ * @note The receiver is enabled or disabled exactly once per primitive request.
+ *
+ * @param[in] req pointer to MLME-RX-ENABLE request structure.
+ * @param[in] conf_cb - pointer to confirm function (user callback).
+ *
+ * In accordance with IEEE Std 802.15.4-2006, section 7.1.10.1
+ */
+void mlme_rx_enable_req(mlme_rx_enable_req_t * req, mlme_rx_enable_conf_cb_t conf_cb);
+
+
+/**
+ * @brief Enables permission for receiving.
+ *
+ * @details Optional. Not covered by a standard.
+ *
+ * @param[in] req pointer to MLME-RX-ENABLE request structure.
+ *
+ * @return status of operation.
+ */
+mac_status_t mlme_rx_enable(mlme_rx_enable_req_t * req);
+
+/** @} */
+
+#endif // (CONFIG_RXE_ENABLED == 1)
+
+#endif // MAC_MLME_RX_ENABLE_H_INCLUDED
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/802_15_4/api/MAC/mac_mlme_scan.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/802_15_4/api/MAC/mac_mlme_scan.h
new file mode 100644
index 0000000..c51ae94
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/802_15_4/api/MAC/mac_mlme_scan.h
@@ -0,0 +1,160 @@
+/**
+ * Copyright (c) 2016 - 2018 Nordic Semiconductor ASA and Luxoft Global Operations Gmbh.
+ *
+ * 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#ifndef MAC_MLME_SCAN_H_INCLUDED
+#define MAC_MLME_SCAN_H_INCLUDED
+
+#include <stdint.h>
+#include "mac_common.h"
+#include "mac_mlme_beacon_notify.h"
+#include "mac_task_scheduler.h"
+
+/** @file
+ * The MAC MLME Scan module declares the MAC Scan primitives and necessary types
+ * according to the MAC specification.
+ *
+ * @defgroup mac_scan MAC MLME Scan API
+ * @ingroup mac_15_4
+ * @{
+ * @brief Module to declare MAC MLME Scan API.
+ * @details The MAC Scan module declares MLME Scan primitives and necessary types according to
+ * the MAC specification. More specifically, MLME Scan request aka mlme_scan_req(), and MLME
+ * Scan confirm callback typedef aka mlme_scan_conf_cb_t primitives are declared.
+ */
+
+/**@brief Type of scan. */
+typedef enum
+{
+ ED_SCAN = 0, /**< Energy detection scan. */
+ ACTIVE_SCAN, /**< Active scan. */
+ PASSIVE_SCAN, /**< Passive scan. */
+ ORPHAN_SCAN /**< Orphan scan. */
+} mac_scan_type_t;
+
+/**
+ * @brief MLME-SCAN.confirm
+ *
+ * @details The MLME-SCAN.confirm reports the result of the channel scan request.
+ *
+ * In accordance with IEEE Std 802.15.4-2006, section 7.1.11.2
+ */
+typedef struct
+{
+ mac_status_t status; /**< Status of operation. */
+ mac_scan_type_t scan_type; /**< Scan type. */
+#ifdef CONFIG_SUB_GHZ
+ uint8_t channel_page; /**< Channel page. */
+#endif
+ uint32_t unscanned_channels; /**< Unscanned channels. */
+ uint8_t result_list_size; /**< Result list size. */
+ uint8_t * energy_detect_list; /**< Energy detection list. */
+ mac_pan_descriptor_t * pan_descriptor_list; /**< PAN descriptor list. */
+} mlme_scan_conf_t;
+
+/**
+ * @brief MLME-SCAN.request
+ *
+ * @details The MLME-SCAN.request primitive is used to initiate a channel
+ * scan over a given list of channels.
+ *
+ * In accordance with IEEE Std 802.15.4-2006, section 7.1.11.1
+ */
+typedef struct
+{
+ /** Do not edit this field. */
+ mac_abstract_req_t service;
+
+ /** Confirm to this request. */
+ mlme_scan_conf_t confirm;
+
+ mac_scan_type_t scan_type; /**< Scan type. */
+ uint32_t scan_channels; /**< Scan channels. */
+ uint8_t scan_duration; /**< Scan duration. */
+
+ uint8_t pan_descriptors_buf_size; /**< PAN descriptor buffer size. */
+ mac_pan_descriptor_t * pan_descriptors_buf; /**< PAN descriptor buffer. */
+
+ uint8_t energy_detect_buf_size; /**< Energy detection buffer size. */
+ uint8_t * energy_detect_buf; /**< Energy detection buffer. */
+
+#ifdef CONFIG_SUB_GHZ
+ uint8_t channel_page; /**< Channel page. */
+#endif
+#if (CONFIG_SECURE == 1)
+ uint8_t security_level; /**< Security level. */
+ uint8_t key_id_mode; /**< Key ID mode. */
+ uint64_t key_source; /**< Key source. */
+ uint8_t key_index; /**< Key index. */
+#endif
+} mlme_scan_req_t;
+
+
+/**
+ * @brief User callback to scan request.
+ *
+ * @details The MLME-SCAN.confirm primitive is generated by the MLME and issued to
+ * its next higher layer when the channel scan initiated with
+ * the MLME-SCAN.request primitive has completed.
+ *
+ * In accordance with IEEE Std 802.15.4-2006, section 7.1.11.2
+ */
+typedef void (* mlme_scan_conf_cb_t)(mlme_scan_conf_t *);
+
+
+/**
+ * @brief MLME-SCAN request
+ *
+ * @details The MLME-SCAN.request primitive is generated by the next higher layer and
+ * issued to its MLME to initiate a channel scan to search for activity within the POS
+ * of the device. This primitive can be used to perform an ED scan to determine channel
+ * usage, an active or passive scan to locate beacon frames containing any PAN identifier,
+ * or an orphan scan to locate a PAN to which the device is currently associated.
+ *
+ * @param[in] req MLME-SCAN request structure.
+ * @param[in] conf_cb pointer to user callback.
+ *
+ * In accordance with IEEE Std 802.15.4-2006, section 7.1.11.1
+ */
+void mlme_scan_req(mlme_scan_req_t * req, mlme_scan_conf_cb_t conf_cb);
+
+/** @} */
+
+#endif // MAC_MLME_SCAN_H_INCLUDED
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/802_15_4/api/MAC/mac_mlme_start.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/802_15_4/api/MAC/mac_mlme_start.h
new file mode 100644
index 0000000..711ba3e
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/802_15_4/api/MAC/mac_mlme_start.h
@@ -0,0 +1,150 @@
+/**
+ * Copyright (c) 2016 - 2018 Nordic Semiconductor ASA and Luxoft Global Operations Gmbh.
+ *
+ * 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#ifndef MAC_MLME_START_H_INCLUDED
+#define MAC_MLME_START_H_INCLUDED
+
+#if (CONFIG_START_ENABLED == 1)
+
+#include <stdint.h>
+#include "mac_common.h"
+#include "sys_utils.h"
+#include "mac_task_scheduler.h"
+
+/** @file
+ * The MAC MLME Start module declares the MAC Start primitives and necessary types
+ * according to the MAC specification.
+ *
+ * @defgroup mac_start MAC MLME Start API
+ * @ingroup mac_15_4
+ * @{
+ * @brief Module to declare MAC MLME Start API.
+ * @details The MAC Start module declares MLME Start primitives and necessary types according to
+ * the MAC specification. More specifically, MLME Start request aka mlme_start_req(), and MLME
+ * Start confirm callback typedef aka mlme_start_conf_cb_t primitives are declared.
+ */
+
+/**@brief MLME-Start.confirm
+ *
+ * @details The MLME-Start.confirm primitive reports the results of a request
+ * to start the device.
+ *
+ * In accordance with IEEE Std 802.15.4-2006, section 7.1.14.1.2
+ */
+typedef struct
+{
+ mac_status_t status; /**< Status of operation. */
+} mlme_start_conf_t;
+
+/**
+ * @brief MLME-START.request
+ *
+ * @details The MLME-START.request primitive allows the PAN coordinator
+ * to initiate a new PAN or to start using a new superframe configuration.
+ * This primitive may also be used by a device already associated with an
+ * existing PAN to start using a new superframe configuration.
+ *
+ * In accordance with IEEE Std 802.15.4-2006, section 7.1.14.1.1
+ */
+typedef struct
+{
+ /** Do not edit this field. */
+ mac_abstract_req_t service;
+
+ /** Confirm to this request. */
+ mlme_start_conf_t confirm;
+
+ uint16_t pan_id; /**< PAN ID. */
+ uint8_t logical_channel; /**< Logical channel. */
+#ifdef CONFIG_SUB_GHZ
+ uint8_t channel_page; /**< Channel page. */
+#endif
+ uint32_t start_time; /**< Start time. */
+ uint8_t beacon_order; /**< Beacon order. */
+ uint8_t superframe_order; /**< Superframe order. */
+ bool pan_coordinator; /**< Is PAN Coordinator? */
+ bool battery_life_extension; /**< Is battery life long? */
+ bool coord_realignment; /**< Is coordinator realignment? */
+#if (CONFIG_SECURE == 1)
+ /* The security parameters for the coordinator realignment are declared below. */
+ uint8_t coord_realign_security_level; /**< Security level. */
+ uint8_t coord_realign_key_id_mode; /**< Key ID mode. */
+ uint64_t coord_realign_key_source; /**< Key source. */
+ uint8_t coord_realign_key_index; /**< Key index. */
+
+ /* The security parameters for the beacon are declared below. */
+ uint8_t beacon_security_level; /**< Security level. */
+ uint8_t beacon_key_id_mode; /**< Key ID mode. */
+ uint64_t beacon_key_source; /**< Key source. */
+ uint8_t beacon_key_index; /**< Key index. */
+#endif
+} mlme_start_req_t;
+
+
+/**
+ * @brief Callback to the next higher layer.
+ *
+ * @details After request completion, passed callback
+ * will be issued with status provided as a parameter.
+ *
+ * In accordance with IEEE Std 802.15.4-2006, section 7.1.14.2.2
+ */
+typedef void (* mlme_start_conf_cb_t)(mlme_start_conf_t *);
+
+
+/**
+ * @brief MLME-START request.
+ *
+ * @details Generated by the next higher layer and issued to its MLME to
+ * request that a device starts using a new superframe configuration.
+ *
+ * @param[in] req MLME-START request structure.
+ * @param[in] conf_cb pointer to user callback.
+ *
+ * In accordance with IEEE Std 802.15.4-2006, section 7.1.14.1.2
+ */
+void mlme_start_req(mlme_start_req_t * req, mlme_start_conf_cb_t conf_cb);
+
+/** @} */
+
+#endif // (CONFIG_START_ENABLED == 1)
+
+#endif // MAC_MLME_START_H_INCLUDED
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/802_15_4/api/MAC/mac_mlme_sync.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/802_15_4/api/MAC/mac_mlme_sync.h
new file mode 100644
index 0000000..f3d6a90
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/802_15_4/api/MAC/mac_mlme_sync.h
@@ -0,0 +1,153 @@
+/**
+ * Copyright (c) 2016 - 2018 Nordic Semiconductor ASA and Luxoft Global Operations Gmbh.
+ *
+ * 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#ifndef MAC_MLME_SYNC_H_INCLUDED
+#define MAC_MLME_SYNC_H_INCLUDED
+
+#if (CONFIG_SYNC_ENABLED == 1)
+
+#include <stdint.h>
+#include "mac_common.h"
+#include "mac_task_scheduler.h"
+
+/** @file
+ * The MAC MLME Sync module declares the MAC Sync primitives and necessary types
+ * according to the MAC specification.
+ *
+ * @defgroup mac_sync MAC MLME Sync API
+ * @ingroup mac_15_4
+ * @{
+ * @brief Module to declare MAC MLME Sync API.
+ * @details The MAC Sync module declares MLME Sync and sync loss primitives and necessary types according to
+ * the MAC specification. More specifically, MLME Sync request aka mlme_sync_req(), and MLME
+ * Sync Loss indication aka mlme_sync_loss_ind() primitives are declared.
+ */
+
+/**@brief Sync Loss reason enumeration. */
+typedef enum
+{
+ MAC_SYNC_BEACON_LOST, /**< Beacon lost. */
+ MAC_SYNC_REALIGNMENT, /**< Realignment. */
+ MAC_SYNC_PAN_ID_CONFLICT /**< PAN ID Conflict. */
+} mlme_sync_loss_reason_t;
+
+/**
+ * @brief MLME-SYNC-LOSS.indication
+ *
+ * @details On receipt of the MLME-SYNC-LOSS.indication primitive, the next
+ * higher layer is notified of a loss of synchronization.
+ *
+ * In accordance with IEEE Std 802.15.4-2006, section 7.1.15.2
+ */
+typedef struct
+{
+ mlme_sync_loss_reason_t loss_reason; /**< Loss reason. */
+ uint16_t pan_id; /**< PAN ID. */
+ uint8_t logical_channel; /**< Logical channel. */
+#ifdef CONFIG_SUB_GHZ
+ uint8_t channel_page; /**< Channel page. */
+#endif
+#if (CONFIG_SECURE == 1)
+ uint8_t security_level; /**< Security level. */
+ uint8_t key_id_mode; /**< Key ID mode. */
+ uint64_t key_source; /**< Key source. */
+ uint8_t key_index; /**< Key index. */
+#endif
+} mlme_sync_loss_ind_t;
+
+
+#if (CONFIG_SYNC_REQ_ENABLED == 1)
+/**
+ * @brief MLME-SYNC.request
+ *
+ * @details The MLME-SYNC.request primitive is generated by the next higher
+ * layer of a device on a beacon-enabled PAN and issued to its MLME to
+ * synchronize with the coordinator.
+ *
+ * In accordance with IEEE Std 802.15.4-2006, section 7.1.15.1
+ */
+typedef struct
+{
+ /** Do not edit this field. */
+ mac_abstract_req_t service;
+
+ uint8_t logical_channel; /**< Logical channel. */
+#ifdef CONFIG_SUB_GHZ
+ uint8_t channel_page; /**< Channel page. */
+#endif
+ bool track_beacon; /**< Track beacon? */
+} mlme_sync_req_t;
+
+/**
+ * @brief MLME-SYNC-LOSS indication.
+ *
+ * @details Generated by the MLME of a device and issued to its next
+ * higher layer in the event of a loss of synchronization with the
+ * coordinator. It is also generated by the MLME of the PAN coordinator
+ * and issued to its next higher layer in the event of a PAN ID conflict.
+ *
+ * @param[in] ind MLME-SYNC-LOSS indication structure.
+ *
+ * In accordance with IEEE Std 802.15.4-2006, section 7.1.7.4
+ */
+extern void mlme_sync_loss_ind(mlme_sync_loss_ind_t * ind);
+
+
+/**
+ * @brief MLME-SYNC request.
+ *
+ * @details Generated by the next higher layer of a device on a
+ * beacon-enabled PAN and issued to its MLME to synchronize with
+ * the coordinator.
+ *
+ * @param[in] req MLME_SYNC request structure.
+ *
+ * In accordance with IEEE Std 802.15.4-2006, section 7.1.15.1
+ */
+void mlme_sync_req(mlme_sync_req_t * req);
+
+#endif // (CONFIG_SYNC_REQ_ENABLED == 1)
+
+/** @} */
+
+#endif // (CONFIG_SYNC_ENABLED == 1)
+
+#endif // MAC_MLME_SYNC_H_INCLUDED
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/802_15_4/api/MAC/mac_panid_conflict.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/802_15_4/api/MAC/mac_panid_conflict.h
new file mode 100644
index 0000000..a504e4c
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/802_15_4/api/MAC/mac_panid_conflict.h
@@ -0,0 +1,82 @@
+/**
+ * Copyright (c) 2016 - 2018 Nordic Semiconductor ASA and Luxoft Global Operations Gmbh.
+ *
+ * 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#ifndef MAC_PANID_CONFLICT_H_INCLUDED
+#define MAC_PANID_CONFLICT_H_INCLUDED
+
+#if (CONFIG_PANID_CONFLICT_ENABLED == 1)
+
+#include "mac_common.h"
+
+/** @file
+ * @defgroup mac_pan_id PAN ID Conflict API
+ * @ingroup mac_15_4
+ * @{
+ * @brief Module for handling PAN ID conflicts.
+ */
+
+/**
+ * @brief A callback function used to notify Pan ID conflict detection algorithm about
+ * a new beacon frame.
+ *
+ * @param p_beacon - pointer to beacon descriptor struct.
+ */
+void mac_panid_conflict_beacon_notify_ind(const mac_beacon_ind_t * p_beacon);
+
+#if (CONFIG_PANID_CONFLICT_RESOLUTION_ENABLED == 1)
+/**@brief Callback function which handles end of Pan ID conflict cmd TX,
+ * called by FP
+ * @param[in] status Confirmation status to be raised
+ */
+void mac_panid_conflict_cb(mac_status_t status);
+#endif
+
+/**@brief Indicates whether the pan id conflict was detected
+ *
+ * @return Result of pan id conflict detection
+ */
+bool mac_panid_conflict_detected(void);
+
+/** @} */
+
+#endif
+
+#endif /* MAC_PANID_CONFLICT_H_INCLUDED */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/802_15_4/api/MAC/mac_security.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/802_15_4/api/MAC/mac_security.h
new file mode 100644
index 0000000..295d387
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/802_15_4/api/MAC/mac_security.h
@@ -0,0 +1,318 @@
+/**
+ * Copyright (c) 2016 - 2018 Nordic Semiconductor ASA and Luxoft Global Operations Gmbh.
+ *
+ * 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#ifndef MAC_SECURITY_H_INCLUDED
+#define MAC_SECURITY_H_INCLUDED
+
+#include "sys_queue.h"
+#include "sec_aes_ccm.h"
+
+/** @file
+ * The MAC MLME Security module declares the MAC Security types
+ * according to the MAC specification.
+ *
+ * @defgroup mac_security MAC MLME Security API
+ * @ingroup mac_15_4
+ * @{
+ * @brief Module to declare MAC MLME Security API.
+ * @details The MAC Security module declares types/macros needed to implement and use the MAC security
+ * engine according to the MAC specification. No routines or callbacks are declared here.
+ */
+
+/**
+ * @brief MAC sublayer security levels.
+ *
+ * In accordance with IEEE Std 802.15.4-2006, section 7.6.2.2.1
+ */
+typedef enum
+{
+ MAC_SEC_OFF = 0, /**< Security is OFF. */
+ MAC_SEC_MIC32, /**< MIC32 security. */
+ MAC_SEC_MIC64, /**< MIC64 security. */
+ MAC_SEC_MIC128, /**< MIC128 security. */
+ MAC_SEC_ENC, /**< ENC security. */
+ MAC_SEC_ENC_MIC32, /**< ENC/MIC32 security. */
+ MAC_SEC_ENC_MIC64, /**< ENC/MIC64 security. */
+ MAC_SEC_ENC_MIC128 /**< ENC/MIC128 security. */
+} mac_security_level_t;
+
+
+/**
+ * @brief MAC key identifier mode.
+ *
+ * In accordance with IEEE Std 802.15.4-2006, section 7.6.2.2.2
+ */
+typedef enum
+{
+ MAC_KEY_ID_IMPL = 0, /**< Impl. */
+ MAC_KEY_ID_ONE_OCTET, /**< One octet. */
+ MAC_KEY_ID_FOUR_OCTET, /**< 4 octets. */
+ MAC_KEY_ID_EIGHT_OCTET /**< 8 octets. */
+} mac_key_id_mode_t;
+
+/**@brief Size (in bytes) of short security look up item. This size is
+ * set when lookup size equals to 0.
+ */
+#define MAC_LOOKUP_DATA_SIZE_SHORT 5
+
+/**@brief Size (in bytes) of long security Key look up item. This size is
+ * set when lookup size equals to 1.
+ */
+#define MAC_KEY_LOOKUP_DATA_SIZE_LONG 9
+
+/**@brief Size (in bytes) of long security Data look up item. This size is
+ * set when lookup size equals to 1.
+ */
+#define MAC_DATA_LOOKUP_DATA_SIZE_LONG 8
+
+/**@brief Length of \a mac_key_source_t. Equals to extended address length. */
+#define MAC_KEY_SOURCE_SIZE 8
+
+/**@brief This bit-mask is used to get UniqueDevice field value of
+ * \a mac_key_device_descr_t.
+ */
+#define MAC_KEY_DEVICE_FLAG_UNIQUE 0x01
+
+/**@brief This bit-mask is used to get BlackListed field value of
+ * \a mac_key_device_descr_t.
+ */
+#define MAC_KEY_DEVICE_FLAG_BLACKLISTED 0x02
+
+/**@brief Length of key. */
+#define MAC_SECURITY_KEY_SIZE 16
+
+/**@brief Length of nonce for aes-ccm algorithm .*/
+#define MAC_SECURITY_NONCE_SIZE 13
+
+/**@brief Maximum MIC size .*/
+#define MAX_MIC_SIZE 16
+
+/**@brief This type is used to store security key .*/
+typedef uint8_t mac_key_t[MAC_SECURITY_KEY_SIZE];
+
+/**@brief This type is used to store security key lookup data .*/
+typedef uint8_t mac_key_lookup_data_t[MAC_KEY_LOOKUP_DATA_SIZE_LONG];
+
+/**@brief This type is used to store security data lookup data .*/
+typedef uint8_t mac_data_lookup_data_t[MAC_DATA_LOOKUP_DATA_SIZE_LONG];
+
+/**@brief This type is used to store security key source address .*/
+typedef uint64_t mac_key_source_t;
+
+/**@brief This type represents key LookupDataSize according to Table 94 .*/
+typedef enum
+{
+ KEY_LOOKUP_SIZE_FIVE = 0, /**< Size is 5. */
+ KEY_LOOKUP_SIZE_NINE = 1 /**< Size is 9. */
+} mac_key_lookup_size_t;
+
+/**@brief This type represents real size of key LookupData .*/
+typedef enum
+{
+ KEY_LOOKUP_SIZE_FIVE_VAL = 5, /**< Size is 5. */
+ KEY_LOOKUP_SIZE_NINE_VAL = 9 /**< Size is 9. */
+} mac_key_lookup_size_val_t;
+
+/**@brief This type represents data LookupDataSize .*/
+typedef enum
+{
+ DATA_LOOKUP_SIZE_FOUR_VAL = 4, /**< Size is 4. */
+ DATA_LOOKUP_SIZE_EIGHT_VAL = 8 /**< Size is 8. */
+} mac_data_lookup_size_val_t;
+
+/**@brief Abstract type to work with growing tables such as some of MAC
+ * security attributes.
+ */
+typedef struct
+{
+ sys_queue_t queue; /**< Service field .*/
+ uint8_t size; /**< Number of currently allocated
+ items inside the table .*/
+} mac_table_t;
+
+/**@brief Due to processing algorithm this field MUST be the first inside a
+ * table or list.
+ */
+typedef struct
+{
+ sys_queue_item_t item; /**< Service field .*/
+ uint8_t idx; /**< Index inside table .*/
+} mac_table_item_t;
+
+/**@brief KeyIdLookupDescriptor as described in Table 94 .*/
+typedef struct
+{
+ mac_table_item_t table_service; /**< Service field .*/
+ mac_key_lookup_data_t data; /**< Set of 5 or 9 bytes.
+ Data used to identify the key .*/
+ mac_key_lookup_size_t size; /**< A value of LOOKUP_SIZE_FIVE indicates a set
+ of 5 bytes; a value of LOOKUP_SIZE_NINE
+ indicates a set of 9 bytes .*/
+} mac_key_id_lookup_descr_t;
+
+
+/**@brief KeyIdLookupLis as described in Table 89 .*/
+typedef mac_table_t mac_key_id_lookup_list_t;
+
+
+/**@brief DeviceDescriptor as described in Table 93 .*/
+typedef struct
+{
+ mac_table_item_t table_service; /**< Service field .*/
+ uint16_t pan_id; /**< The 16-bit PAN identifier of the device in
+ this DeviceDescriptor .*/
+ uint16_t short_address; /**< The 16-bit short address of the device in
+ this DeviceDescriptor. A value of
+ #MAC_EXTENDED_ADDRESS_ONLY
+ indicates that this device is using only its
+ extended address. A value of
+ #MAC_BROADCAST_SHORT_ADDRESS
+ indicates that this value is unknown .*/
+ uint64_t extended_address; /**< The 64-bit IEEE extended address of the
+ device in this DeviceDescriptor. This
+ element is also used in unsecuring
+ operations on incoming frames .*/
+ uint32_t frame_counter; /**< The incoming frame counter of the device
+ in this DeviceDescriptor. This value is used
+ to ensure sequential freshness of frames .*/
+ bool exempt; /**< Indication of whether the device may
+ override the minimum security level
+ settings defined in \a mac_security_level_table_t .*/
+} mac_device_descr_t;
+
+
+/**@brief DeviceTable as described in Table 93 .*/
+typedef mac_table_t mac_device_table_t;
+
+
+/**@brief KeyDeviceDescriptor as described in Table 91 .*/
+typedef struct
+{
+ mac_table_item_t table_service; /**< Service field .*/
+ uint8_t device_handle; /**< Handle to the DeviceDescriptor
+ corresponding to the device (see
+ \a mac_device_descr_t).
+ The value is an index of the device descriptor
+ instance from device table .*/
+ uint8_t unique_device : 1; /**< Indication of whether the device indicated
+ by DeviceDescriptorHandle is uniquely
+ associated with the KeyDescriptor, i.e., it
+ is a link key as opposed to a group key .*/
+ uint8_t blacklisted : 1; /**< Indication of whether the device indicated
+ by DeviceDescriptorHandle previously
+ communicated with this key prior to the
+ exhaustion of the frame counter. If TRUE,
+ this indicates that the device shall not use
+ this key further because it exhausted its
+ use of the frame counter used with this
+ key .*/
+} mac_key_device_descr_t;
+
+
+/**@brief KeyDeviceList as described in Table 89 .*/
+typedef mac_table_t mac_key_device_list_t;
+
+
+/**@brief KeyUsageDescriptor as described in Table 90 .*/
+typedef struct
+{
+ mac_table_item_t table_service; /**< Service field .*/
+
+ uint8_t frame_type : 3; /**< See \a mac_frame_type_t .*/
+ uint8_t cmd_frame_id : 4; /**< See \a mac_command_id_t .*/
+} mac_key_usage_descr_t;
+
+
+/**@brief KeyUsageList as described in Table 89 .*/
+typedef mac_table_t mac_key_usage_list_t;
+
+
+/**@brief KeyDescriptor as described in Table 89 .*/
+typedef struct
+{
+ mac_table_item_t table_service; /**< Service field .*/
+ mac_key_id_lookup_list_t id_lookup_list; /**< A list of KeyIdLookupDescriptor entries
+ used to identify this KeyDescriptor .*/
+ mac_key_device_list_t key_device_list; /**< A list of KeyDeviceDescriptor entries
+ indicating which devices are currently
+ using this key, including their blacklist
+ status .*/
+ mac_key_usage_list_t key_usage_list; /**< A list of KeyUsageDescriptor entries
+ indicating which frame types this key may
+ be used with .*/
+ mac_key_t key; /**< The actual value of the key .*/
+} mac_key_descr_t;
+
+
+/**@brief KeyTable as described in Table 88 .*/
+typedef mac_table_t mac_key_table_t;
+
+
+/**@brief SecurityLevelDescriptor as described in Table 93 .*/
+typedef struct
+{
+ mac_table_item_t table_service; /**< Service field. */
+
+ uint16_t frame_type : 3; /**< See \a mac_frame_type_t .*/
+ uint16_t cmd_frame_id : 4; /**< See \a mac_command_id_t .*/
+ uint16_t security_min : 3; /**< The minimal required/expected security
+ level for incoming MAC frames with the
+ indicated frame type and, if present,
+ command frame type (see
+ \a mac_security_level_t) .*/
+ uint16_t override_min : 1; /**< Indication of whether originating devices
+ for which the Exempt flag is set may
+ override the minimum security level
+ indicated by the SecurityMinimum
+ element. If TRUE, this indicates that for
+ originating devices with Exempt status,
+ the incoming security level zero is
+ acceptable, in addition to the incoming
+ security levels meeting the minimum
+ expected security level indicated by the
+ SecurityMinimum element .*/
+} mac_security_level_descr_t;
+
+typedef mac_table_t mac_security_level_table_t;
+
+/** @} */
+
+#endif // MAC_SECURITY_H_INCLUDED
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/802_15_4/api/MAC/mac_task_scheduler.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/802_15_4/api/MAC/mac_task_scheduler.h
new file mode 100644
index 0000000..639c070
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/802_15_4/api/MAC/mac_task_scheduler.h
@@ -0,0 +1,205 @@
+/**
+ * Copyright (c) 2016 - 2018 Nordic Semiconductor ASA and Luxoft Global Operations Gmbh.
+ *
+ * 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#ifndef MAC_TASK_SCHEDULER_H_INCLUDED
+#define MAC_TASK_SCHEDULER_H_INCLUDED
+
+#include <stdint.h>
+#include "sys_queue.h"
+#include "sys_time.h"
+
+/** @file
+ *
+ * @defgroup mac_task_scheduler MAC task scheduler
+ * @ingroup mac_15_4
+ * @{
+ * @brief Module for MAC task scheduling.
+ */
+
+/**@brief Identifiers for external requests.
+ */
+typedef enum
+{
+#if (CONFIG_PURGE_ENABLED == 1)
+ MAC_PURGE_REQ_ID,
+#endif
+#if (CONFIG_ASSOCIATE_REQ_ENABLED == 1)
+ MAC_ASSOCIATE_REQ_ID,
+#endif
+#if (CONFIG_DISASSOCIATE_ENABLED == 1)
+ MAC_DISASSOCIATE_REQ_ID,
+#endif
+ MAC_GET_REQ_ID,
+#if (CONFIG_GTS_ENABLED == 1)
+ MAC_GTS_REQ_ID,
+#endif
+ MAC_RESET_REQ_ID,
+#if (CONFIG_RXE_ENABLED == 1)
+ MAC_RX_ENABLE_REQ_ID,
+#endif
+ MAC_SCAN_REQ_ID,
+ MAC_SET_REQ_ID,
+#if (CONFIG_SYNC_REQ_ENABLED == 1)
+ MAC_SYNC_REQ_ID,
+#endif
+ MAC_POLL_REQ_ID,
+#if (CONFIG_START_ENABLED == 1)
+ MAC_START_REQ_ID,
+#endif
+ MAC_DATA_REQ_ID,
+#if (CONFIG_ORPHAN_ENABLED == 1)
+ MAC_ORPHAN_RESP_ID,
+#endif
+ MAC_REQS_AMOUNT
+} mac_req_id_t;
+
+
+/**@brief Identifiers for internal handlers.
+ *
+ * These handlers are used for private MAC task scheduling.
+ */
+typedef enum
+{
+#if (CONFIG_FFD_DEVICE == 1) && (CONFIG_BEACON_ENABLED == 1)
+ MAC_SUPERFRAME_OUT_TASK_ID,
+#endif
+ MAC_CSMA_CA_TASK_ID,
+#if (CONFIG_START_ENABLED == 1)
+ MAC_START_TASK_ID,
+#endif
+ MAC_FP_TX_TASK_ID,
+ MAC_DATA_DIR_CONF_ID,
+#if (CONFIG_INDIRECT_ENGINE_ENABLED == 1)
+ MAC_INDIR_ENGINE_REQ_ID,
+#endif
+ MAC_FP_RX_TASK_ID,
+#if (CONFIG_ORPHAN_ENABLED == 1)
+ MAC_ORPHAN_IND_ID,
+#endif
+#if (CONFIG_DISASSOCIATE_ENABLED == 1)
+ MAC_DISASSOC_IND_ID,
+#endif
+#if (CONFIG_SYNC_ENABLED == 1)
+ MAC_SYNC_LOSS_IND_ID,
+#endif
+ MAC_GET_CONF_ID,
+ MAC_SET_CONF_ID,
+ MAC_REQ_QUEUE_TASK_ID,
+ MAC_POLL_TASK_ID,
+ MAC_SCAN_CONF_ID,
+ MAC_MEM_ALLOCATOR_TASK_ID,
+ MAC_TASKS_AMOUNT
+} mac_task_id_t;
+
+
+/**@brief MAC request descriptor.
+ */
+typedef struct
+{
+ sys_queue_item_t item;
+ mac_req_id_t id;
+ void * p_conf_cb; //pointer to confirmation primitive
+} mac_abstract_req_t;
+
+/**@brief scheduler memory.
+ */
+typedef struct
+{
+ sys_queue_t outer_req_queue;
+ volatile uint32_t pending_tasks;
+ bool mac_scheduler_busy;
+} mac_scheduler_mem_t;
+
+/**@brief MAC task handler prototype.
+ *
+ * @details Handler which will be called by the MAC scheduler.
+ */
+typedef void (* mac_task_handler_t)(void);
+
+/**@brief MAC external requests queue task handler prototype.
+ *
+ * @details Handler which will be called by the MAC scheduler inside
+ * corresponding task handler.
+ */
+typedef void (* mac_req_handler_t)(mac_abstract_req_t *);
+
+/**@brief Initialize MAC scheduler.
+ *
+ * @details Clean up MAC request's queue.
+ */
+void mac_init(void);
+
+/**@brief MAC task handler.
+ *
+ * @details Handler invokes a MAC primitives routine for a request according to
+ * the requests identification.
+ */
+void mac_task_handler(void);
+
+/**@brief Scheduler request from some MAC primitive.
+ *
+ * @details Place request to MAC scheduler queue for a further handling.
+ *
+ * @param[in] p_req Pointer to a request structure.
+ */
+void mac_request_schedule(mac_abstract_req_t * p_req);
+
+/**@brief Internal function of MAC API.
+ *
+ * This function is used to post tasks between MAC primitives.
+ *
+ * @param[in] id MAC task ID.
+ *
+ */
+void mac_internal_task_post(mac_task_id_t id);
+
+/**@brief Internal function of MAC API.
+ *
+ * Notifies mac scheduler that incoming request has been completely
+ * served and may be safely removed from MAC task queue.
+ *
+ * @param[in] p_req Pointer to a request structure.
+ */
+void mac_close_request(mac_abstract_req_t * p_req);
+
+/** @} */
+
+#endif // MAC_TASK_SCHEDULER_H_INCLUDED
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/802_15_4/api/MAC/mac_time.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/802_15_4/api/MAC/mac_time.h
new file mode 100644
index 0000000..671fc57
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/802_15_4/api/MAC/mac_time.h
@@ -0,0 +1,151 @@
+/**
+ * Copyright (c) 2016 - 2018 Nordic Semiconductor ASA and Luxoft Global Operations Gmbh.
+ *
+ * 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#ifndef MAC_TIME_H_INCLUDED
+#define MAC_TIME_H_INCLUDED
+
+#include <stdint.h>
+#include "sys_time.h"
+#include "hal_timer.h"
+#include "hal_timer_critical.h"
+#include "sys_debug.h"
+
+/** @file
+ * The MAC Time module declares some useful macros/types and routines that deal with the MAC
+ * timer.
+ *
+ * @defgroup mac_time MAC Time API
+ * @ingroup mac_15_4
+ * @{
+ * @brief Module to declare MAC Time API.
+ * @details The MAC Time module declares some useful macros/types and routines that deal with the MAC
+ * timer. More specifically, some convertion routines such as mac_timestamp_from_systime(),
+ * mac_time_from_us(), and mac_time_to_us() are declared here.
+ */
+
+/**@brief This mask shall always be used after any mathematical operation on
+ * mac_time_t to avoid overflow.
+ */
+#define MAC_TIME_MASK 0xFFFFFFULL
+
+/**@brief Type of MAC time in symbols. */
+typedef uint32_t mac_time_t;
+
+/**@brief Type is used to save timestamps with microsecond precision. */
+typedef uint32_t mac_timestamp_t;
+
+
+/**@brief Gets timestamp from system time.
+ *
+ * @param[in] time_us System time.
+ *
+ * @return Time in us but smaller type size.
+ */
+static inline mac_timestamp_t mac_timestamp_from_systime(sys_time_t time_us)
+{
+ return (mac_timestamp_t)time_us;
+}
+
+/**@brief Converts microseconds to symbol time.
+ *
+ * @details Symbol time is measured in PHY Symbol Periods (16 us).
+ *
+ * @param[in] time_us Time in microseconds.
+ *
+ * @return Time in PHY Symbol Periods (16 us).
+ */
+static inline mac_time_t mac_time_from_us(sys_time_t time_us)
+{
+ return (mac_time_t)((time_us >> 4ull) & MAC_TIME_MASK);
+}
+
+
+/**@brief Converts symbol time to microseconds.
+ *
+ * @details Symbol time is measured in PHY Symbol Periods (16 us).
+ *
+ * @param[in] time_symbol Time in PHY Symbol Periods (16 us).
+ *
+ * @return Time in microseconds.
+ */
+static inline sys_time_t mac_time_to_us(mac_time_t time_symbol)
+{
+ return time_symbol << 4u;
+}
+
+
+/**@brief Starts the critical MAC timer.
+ *
+ * @details The callback function of the critical MAC timer will be called from
+ * the timer's interrupt routine. Only one critical MAC timer can run
+ * at the same time.
+ *
+ * @warning This is internal MAC functionality, needed for the realtime channel access.
+ * This function must not be used by other modules.
+ *
+ * @param[in] interval_us Interval in microseconds, after which the callback
+ * function will be called.
+ * @param[in] callback Callback function to be called after the specified inteval.
+ */
+static inline void mac_timer_critical_start(sys_time_t interval_us, void (* callback)(void))
+{
+ // Make sure interval_us fits into 32 bits, since hardware critical timer is 32 bit.
+ ASSERT(interval_us < (1ULL << 32));
+
+ hal_timer_critical_start((uint32_t)interval_us, callback);
+}
+
+
+/**@brief Stops the critical MAC timer.
+ *
+ * @details After critical MAC timer is stopped with this function, its callback will not be called.
+ *
+ * @warning This is internal MAC functionality, needed for the realtime channel access.
+ * This function must not be used by other modules.
+ */
+static inline void mac_timer_critical_stop(void)
+{
+ hal_timer_critical_stop();
+}
+
+/** @} */
+
+#endif // MAC_TIME_H_INCLUDED
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/802_15_4/api/PHY/phy_common.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/802_15_4/api/PHY/phy_common.h
new file mode 100644
index 0000000..227d1ba
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/802_15_4/api/PHY/phy_common.h
@@ -0,0 +1,240 @@
+/**
+ * Copyright (c) 2016 - 2018 Nordic Semiconductor ASA and Luxoft Global Operations Gmbh.
+ *
+ * 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#ifndef PHY_COMMON_H_INCLUDED
+#define PHY_COMMON_H_INCLUDED
+
+/** @file
+ * This file contains declarations of commonly used PHY routines and necessary macros/types.
+ *
+ * @defgroup phy_common PHY Common API
+ * @ingroup phy_15_4
+ * @{
+ * @brief Module to declare Common PHY API
+ * @details The Common PHY module contains declarations of commonly used PHY routines and necessary macros/types.
+ */
+
+/**@brief The maximum PSDU size (in octets) the PHY shall be able to receive (aMaxPHYPacketSize).
+ *
+ * @details See Table 22 - PHY constants.
+ */
+#define PHY_MAX_PACKET_SIZE 127
+
+
+/**@brief The maximum PHR size (in octets).
+ *
+ * @details See 6.3 PPDU format.
+ */
+#define PHY_MAX_HEADER_SIZE 1
+
+/**@brief Maximum PPDU size */
+#define PHY_MAX_PPDU_SIZE (PHY_MAX_HEADER_SIZE + PHY_MAX_PACKET_SIZE)
+
+/**@brief Position of PHY header related to income PPDU start pointer.*/
+#define PHY_HEADER_POS (-1)
+
+/**@brief Size of PHY header in bytes.*/
+#define PHY_HEADER_SIZE 1
+
+/**@brief Maximum channel number.*/
+#define PHY_MAX_CHANNEL_NUM 0x1Au
+
+/**@brief Minimum channel number.*/
+#define PHY_MIN_CHANNEL_NUM 0x0Bu
+
+// for 2400 MHz O-QPSK 1 octet = 2 symbols 1 symbol = 32bits chip
+#define aMaxPHYPacketSize PHY_MAX_PACKET_SIZE // in octets
+#define aTurnaroundTime 12 // in symbols
+
+#define aTurnaroundTimeUs 192 // in us
+
+
+// Read only parameters
+#define PHY_CURRENT_PAGE 0x0u
+#define PHY_CHANNEL_SUPPORTED 0x07FFF800ul
+#define PHY_SHR_DURATION 10u
+#define PHY_MAX_FRAME_DURATION (PHY_SHR_DURATION + (int)((aMaxPHYPacketSize + 1) * PHY_SYMBOLS_PER_OCTET))
+#define PHY_SYMBOLS_PER_OCTET 2u
+
+// CCA values
+#define PHY_TRX_CCA_MODE0 0
+#define PHY_TRX_CCA_MODE1 1
+#define PHY_TRX_CCA_MODE2 2
+#define PHY_TRX_CCA_MODE3 3
+
+
+/** @brief Minimum value that can be used to set radio transmit power. Equals
+ * to -32 dBm.
+ *
+ * This is a combination of digits which includes:
+ * 2 MSBs represent the tolerance on the transmit power
+ * 6 LSBs which may be written to, represent a signed integer in twos-complement format,
+ * corresponding to the nominal transmit power of the device in decibels relative to 1 mW.
+ * All combinations less than 0xBF are valid.
+ */
+#define PHY_MIN_TX_POWER 0x20
+
+/** @brief Internal parameter of the PHY layer.
+ *
+ * @details Position of the sign bit inside transmit power attribute.*/
+#define PHY_TRANSMIT_POWER_SIGN_BIT_POS 5
+
+/** @brief Internal parameter of the PHY layer.
+ *
+ * @details This mask hides transmit power from transmit power attribute value,
+ * but leaves precision bitfield.
+ */
+#define PHY_TRANSMIT_POWER_MASK 0xC0
+
+/** @brief Internal parameter of the PHY layer.
+ *
+ * @details This mask hides precision bitfield from transmit power attribute value,
+ * leaving transmit power unchanged.
+ */
+#define PHY_TRANSMIT_POWER_MASK_INV 0x3F
+
+// Possible transmit power
+#define DBM_11 ( 11 & PHY_TRANSMIT_POWER_MASK_INV)
+#define DBM_10 ( 10 & PHY_TRANSMIT_POWER_MASK_INV)
+#define DBM_9 ( 9 & PHY_TRANSMIT_POWER_MASK_INV)
+#define DBM_8 ( 8 & PHY_TRANSMIT_POWER_MASK_INV)
+#define DBM_7 ( 7 & PHY_TRANSMIT_POWER_MASK_INV)
+#define DBM_6 ( 6 & PHY_TRANSMIT_POWER_MASK_INV)
+#define DBM_5 ( 5 & PHY_TRANSMIT_POWER_MASK_INV)
+#define DBM_4 ( 4 & PHY_TRANSMIT_POWER_MASK_INV)
+#define DBM_3 ( 3 & PHY_TRANSMIT_POWER_MASK_INV)
+#define DBM_2 ( 2 & PHY_TRANSMIT_POWER_MASK_INV)
+#define DBM_1 ( 1 & PHY_TRANSMIT_POWER_MASK_INV)
+#define DBM_0 ( 0 & PHY_TRANSMIT_POWER_MASK_INV)
+#define DBM_MIN_1 (( -1) & PHY_TRANSMIT_POWER_MASK_INV)
+#define DBM_MIN_2 (( -2) & PHY_TRANSMIT_POWER_MASK_INV)
+#define DBM_MIN_3 (( -3) & PHY_TRANSMIT_POWER_MASK_INV)
+#define DBM_MIN_4 (( -4) & PHY_TRANSMIT_POWER_MASK_INV)
+#define DBM_MIN_5 (( -5) & PHY_TRANSMIT_POWER_MASK_INV)
+#define DBM_MIN_6 (( -6) & PHY_TRANSMIT_POWER_MASK_INV)
+#define DBM_MIN_7 (( -7) & PHY_TRANSMIT_POWER_MASK_INV)
+#define DBM_MIN_8 (( -8) & PHY_TRANSMIT_POWER_MASK_INV)
+#define DBM_MIN_9 (( -9) & PHY_TRANSMIT_POWER_MASK_INV)
+#define DBM_MIN_10 ((-10) & PHY_TRANSMIT_POWER_MASK_INV)
+#define DBM_MIN_11 ((-11) & PHY_TRANSMIT_POWER_MASK_INV)
+#define DBM_MIN_12 ((-12) & PHY_TRANSMIT_POWER_MASK_INV)
+#define DBM_MIN_13 ((-13) & PHY_TRANSMIT_POWER_MASK_INV)
+#define DBM_MIN_14 ((-14) & PHY_TRANSMIT_POWER_MASK_INV)
+#define DBM_MIN_15 ((-15) & PHY_TRANSMIT_POWER_MASK_INV)
+#define DBM_MIN_16 ((-16) & PHY_TRANSMIT_POWER_MASK_INV)
+#define DBM_MIN_17 ((-17) & PHY_TRANSMIT_POWER_MASK_INV)
+#define DBM_MIN_18 ((-18) & PHY_TRANSMIT_POWER_MASK_INV)
+#define DBM_MIN_19 ((-19) & PHY_TRANSMIT_POWER_MASK_INV)
+#define DBM_MIN_20 ((-20) & PHY_TRANSMIT_POWER_MASK_INV)
+#define DBM_MIN_21 ((-21) & PHY_TRANSMIT_POWER_MASK_INV)
+#define DBM_MIN_22 ((-22) & PHY_TRANSMIT_POWER_MASK_INV)
+#define DBM_MIN_23 ((-23) & PHY_TRANSMIT_POWER_MASK_INV)
+#define DBM_MIN_24 ((-24) & PHY_TRANSMIT_POWER_MASK_INV)
+#define DBM_MIN_25 ((-25) & PHY_TRANSMIT_POWER_MASK_INV)
+#define DBM_MIN_26 ((-26) & PHY_TRANSMIT_POWER_MASK_INV)
+#define DBM_MIN_27 ((-27) & PHY_TRANSMIT_POWER_MASK_INV)
+
+
+/**@brief Common PHY enumerations description used in various PHY primitives.
+ *
+ * @details See Table 18-PHY enumerations description for detailed info on the statuses up to PHY_READ_ONLY.
+ * The statuses with higher numbers are implementation specific and used for synchronous API only.
+ */
+typedef enum
+{
+ /** The CCA attempt has detected a busy channel. */
+ PHY_BUSY = 0x00,
+
+ /** The transceiver is asked to change its state while receiving. */
+ PHY_BUSY_RX = 0x01,
+
+ /** The transceiver is asked to change its state while transmitting. */
+ PHY_BUSY_TX = 0x02,
+
+ /** The transceiver is to be switched off immediately. */
+ PHY_FORCE_TRX_OFF = 0x03,
+
+ /** The CCA attempt has detected an idle channel. */
+ PHY_IDLE = 0x04,
+
+ /** A SET/GET request was issued with a parameter in the primitive that is
+ out of the valid range. */
+ PHY_INVALID_PARAMETER = 0x05,
+
+ /** The transceiver is in or is to be configured into the receiver enabled state. */
+ PHY_RX_ON = 0x06,
+
+ /** A SET/GET, an ED operation, or a transceiver state change was successful. */
+ PHY_SUCCESS = 0x07,
+
+ /** The transceiver is in or is to be configured into the transceiver disabled state. */
+ PHY_TRX_OFF = 0x08,
+
+ /** The transceiver is in or is to be configured into the transmitter enabled state. */
+ PHY_TX_ON = 0x09,
+
+ /** A SET/GET request was issued with the identifier of an attribute that is not supported. */
+ PHY_UNSUPPORTED_ATTRIBUTE = 0x0A,
+
+ /** A SET/GET request was issued with the identifier of an attribute that is read-only.*/
+ PHY_READ_ONLY = 0x0B,
+
+
+ /* Statuses out of the standard. They are used for synchronous API */
+ /** Transceiver is forced to change it's state to PHY_TX_ON (potential packet drop). */
+ PHY_FORCE_TX_ON = 0xFC,
+
+ /** Data cannot be sent due to failed CCA results.*/
+ PHY_CHANNEL_ACCESS_FAILURE = 0xFD,
+
+ /** Data had been sent but ACK frame hasn't been received.*/
+ PHY_NO_ACK = 0xFE,
+
+ /** PHY is not available for synchronous access */
+ PHY_IS_NOT_AVAILABLE = 0xFF
+} phy_enum_t;
+
+/**@brief PHY status type.*/
+typedef phy_enum_t phy_status_t;
+
+/** @} */
+
+#endif // PHY_COMMON_H_INCLUDED
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/802_15_4/api/PHY/phy_pd_data.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/802_15_4/api/PHY/phy_pd_data.h
new file mode 100644
index 0000000..1009dc2
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/802_15_4/api/PHY/phy_pd_data.h
@@ -0,0 +1,187 @@
+/**
+ * Copyright (c) 2016 - 2018 Nordic Semiconductor ASA and Luxoft Global Operations Gmbh.
+ *
+ * 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#ifndef PHY_PD_DATA_H_INCLUDED
+#define PHY_PD_DATA_H_INCLUDED
+
+
+#include <stdint.h>
+#include <stdbool.h>
+#include "sys_utils.h"
+#include "sys_time.h"
+#include "phy_common.h"
+#include "mac_time.h"
+#include "sys_queue.h"
+
+/** @file
+ * This file contains declarations of PHY Data transmission routines and necessary types.
+ *
+ * @defgroup phy_data PHY Data API
+ * @ingroup phy_15_4
+ * @{
+ * @brief Module to declare PHY Data API
+ * @details The PHY Data module declares the PHY Data transmission routines and necessary types according to
+ * the PHY specification. More specifically, PHY data request pd_data_req(), PHY data confirm
+ * pd_data_conf(), and PHY Data indication pd_data_ind() primitives are declared.
+ */
+
+/**@brief PD-DATA.request parameters.
+ *
+ * @details See 6.2.1.1 PD-DATA.request.
+ * See Table 6 - PD-DATA.request parameters.
+ */
+typedef struct
+{
+ /** The set of octets forming the PSDU to be transmitted by the PHY entity. */
+ uint8_t * psdu;
+
+ /** The number of octets contained in the PSDU to be transmitted by the PHY entity.
+ Valid range: less or equal to @ref PHY_MAX_PACKET_SIZE. */
+ uint8_t psdu_length;
+} pd_data_req_t;
+
+/**@brief Private information which is passed with PD-DATA.confirm.
+ * Not covered by standard.
+ */
+typedef struct
+{
+ /** pending value to store pending bit value if frame was acknowledged. */
+ bool pending;
+} pd_data_conf_private_t;
+
+/**@brief PD-DATA.confirm parameters.
+ *
+ * @details See 6.2.1.2 PD-DATA.confirm.
+ * See Table 7 - PD-DATA.confirm parameters.
+ */
+typedef struct
+{
+ /** Service field. */
+ pd_data_conf_private_t service;
+
+ /** The result of the request to transmit a packet.
+ * Valid range: PHY_SUCCESS, PHY_RX_ON, PHY_TRX_OFF, PHY_BUSY_TX.
+ * See @ref phy_enum_t.
+ *
+ * When radio chip successfully transmits data, but cannot receive
+ * ACK in FAST_ACK mode, the result is PHY_TX_ON.
+ */
+ phy_enum_t status;
+} pd_data_conf_t;
+
+/**@brief Private information which is passed with PD-DATA.indication.
+ * Not covered by standard.
+ */
+typedef struct
+{
+ /** RSSI value, which corresponds to packet that caused this indication. */
+ int8_t rssi;
+
+ /** Buffer to store incoming frame. */
+ uint8_t frame_buffer[PHY_MAX_PACKET_SIZE + PHY_MAX_HEADER_SIZE];
+
+ /** Timestamp of the moment when PHY header octet reception has been started. */
+ mac_timestamp_t timestamp;
+
+ /** This field allows storing instances of this structure in a queue. */
+ sys_queue_item_t queue_item;
+#ifdef CONFIG_PHY_CERT_CRC_HOOK
+ bool crc_status;
+#endif
+} pd_data_ind_private_t;
+
+/**@brief PD-DATA.indication parameters.
+ *
+ * @details See 6.2.1.3 PD-DATA.indication.
+ * See Table 8 - PD-DATA.indication parameters.
+ */
+typedef struct
+{
+ /** Service field. */
+ pd_data_ind_private_t service;
+
+ /** The set of octets forming the PSDU received by the PHY entity. */
+ uint8_t * psdu;
+
+ /** The number of octets contained in the PSDU received by the PHY entity.
+ Valid range: less or equal to @ref PHY_MAX_PACKET_SIZE. */
+ uint8_t psdu_length;
+
+ /** Link quality (LQI) value measured during reception of the PPDU (see 6.9.8).
+ Valid range: 0x00 - 0xFF. */
+ uint8_t ppdu_link_quality;
+} pd_data_ind_t;
+
+/**@brief PD-DATA.request primitive.
+ *
+ * @details The PD-DATA.request primitive requests the transfer of an MPDU (i.e., PSDU)
+ * from the MAC sublayer to the local PHY entity.
+ * See 6.2.1.1 PD-DATA.request.
+ *
+ * @param[in] req Pointer to PD-DATA.request parameters. See @ref pd_data_req_t.
+ */
+void pd_data_req(pd_data_req_t * req);
+
+/**@brief PD-DATA.confirm primitive.
+ *
+ * @details Callback function, implemented by the next higher layer,
+ * which handles the PD-DATA.confirm primitive.
+ * See 6.2.1.2 PD-DATA.confirm.
+ *
+ * @param[out] conf Pointer to PD-DATA.confirm parameters. See @ref pd_data_conf_t.
+ */
+void pd_data_conf(pd_data_conf_t * conf);
+
+/**@brief PD-DATA.indication primitive.
+ *
+ * @details The PD-DATA.indication primitive indicates the transfer of an MPDU (i.e., PSDU)
+ * from the PHY to the local MAC sublayer entity.
+ * See 6.2.1.3 PD-DATA.indication.
+ * This function must be implemented by the next higher layer.
+ *
+ * @param[out] ind Pointer to PD-DATA.indication parameters. See @ref pd_data_ind_t.
+ * Data are valid until next fully received packet.
+ */
+void pd_data_ind(pd_data_ind_t * ind);
+
+/** @} */
+
+#endif // PHY_PD_DATA_H_INCLUDED
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/802_15_4/api/PHY/phy_plme_cca.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/802_15_4/api/PHY/phy_plme_cca.h
new file mode 100644
index 0000000..2779ff1
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/802_15_4/api/PHY/phy_plme_cca.h
@@ -0,0 +1,106 @@
+/**
+ * Copyright (c) 2016 - 2018 Nordic Semiconductor ASA and Luxoft Global Operations Gmbh.
+ *
+ * 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#ifndef PHY_PLME_CCA_H_INCLUDED
+#define PHY_PLME_CCA_H_INCLUDED
+
+#include <stdint.h>
+#include "phy_common.h"
+
+/** @file
+ * This file contains declarations of Clear Channel Assessment PHY routines and necessary types.
+ *
+ * @defgroup phy_cca PHY CCA API
+ * @ingroup phy_15_4
+ * @{
+ * @brief Module to declare PHY Clear Channel Assessment API
+ * @details The PHY CCA module declares Clear Channel Assessment PHY routines and necessary types according to
+ * the PHY specification. More specifically, PHY CCA request plme_cca_req(), PHY CCA confirm
+ * plme_cca_conf() primitives are declared. An additional primitive not covered by the standard is declared.
+ * This is plme_cca() which is a synchronous version of plme_cca_req().
+ */
+
+/**@brief PLME-CCA.confirm parameters
+ *
+ * @details The PLME-CCA.confirm primitive is generated by
+ * the initiating PLME and issued to its next higher layer
+ * in response to an PLME-CCA.request primitive.
+ * In accordance with IEEE Std 802.15.4-2006, section 6.2.2.2.1
+ */
+typedef struct
+{
+ /** One of PHY_TRX_OFF, PHY_BUSY or PHY_IDLE. */
+ phy_enum_t status;
+} plme_cca_conf_t;
+
+
+/**@brief PLME-CCA.request
+ *
+ * @details Request for clear channel assessment.
+ * In accordance with IEEE Std 802.15.4-2006, section 6.2.2.1
+ */
+void plme_cca_req(void);
+
+
+/**@brief PLME-CCA.confirm callback function, implemented by the next higher layer.
+ *
+ * @details The PLME-CCA.confirm primitive is generated by the PLME and issued
+ * to its next higher layer in response to an PLME-CCA.request primitive.
+ * In accordance with IEEE Std 802.15.4-2006, section 6.2.2.2
+ *
+ * @param[out] conf Pointer to PLME-CCA.confirm parameters
+ */
+void plme_cca_conf(plme_cca_conf_t * conf);
+
+
+/**@brief Direct (synchronous) PLME-CCA.request
+ *
+ * @details Optional. Not covered by a standard.
+ *
+ * @return One of PHY_TRX_OFF, PHY_BUSY or PHY_IDLE,
+ * or implementation defined error code in case of
+ * unavailability of access to system resources.
+ */
+phy_enum_t plme_cca(void);
+
+/** @} */
+
+#endif // PHY_PLME_CCA_H_INCLUDED
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/802_15_4/api/PHY/phy_plme_ed.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/802_15_4/api/PHY/phy_plme_ed.h
new file mode 100644
index 0000000..7517bae
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/802_15_4/api/PHY/phy_plme_ed.h
@@ -0,0 +1,110 @@
+/**
+ * Copyright (c) 2016 - 2018 Nordic Semiconductor ASA and Luxoft Global Operations Gmbh.
+ *
+ * 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#ifndef PHY_PLME_ED_H_INCLUDED
+#define PHY_PLME_ED_H_INCLUDED
+
+#include <stdint.h>
+#include "phy_common.h"
+
+/** @file
+ * This file contains declarations of Energy Detection PHY routines and necessary types.
+ *
+ * @defgroup phy_ed PHY ED API
+ * @ingroup phy_15_4
+ * @{
+ * @brief Module to declare PHY Energy Detection API
+ * @details The PHY ED module declares Energy Detection PHY routines and necessary types according to
+ * the PHY specification. More specifically, PHY ED request plme_ed_req(), PHY ED confirm
+ * plme_ed_conf() primitives are declared.
+ */
+
+/**@brief Describes the current state of the ED algorithm. */
+typedef enum
+{
+ PHY_PLME_ED_STATE_IDLE, /**< Algorithm is idle. */
+ PHY_PLME_ED_STATE_BUSY /**< Currently performing ED. */
+} phy_plme_ed_state_t;
+
+/**@brief This structure holds static data of this module. */
+typedef struct
+{
+ phy_plme_ed_state_t state;
+} phy_plme_ed_mem_t;
+
+/**@brief PLME-ED.confirm parameters.
+ *
+ * @details The PLME-ED.confirm primitive is generated by the PLME and issued
+ * to its next higher layer in response to an PLME-ED.request primitive.
+ *
+ * In accordance with IEEE Std 802.15.4-2006, section 6.2.2.4.1.
+ */
+typedef struct
+{
+ /** One of PHY_SUCCESS, PHY_TRX_OFF or PHY_TX_ON. */
+ phy_enum_t status;
+
+ /** Energy level for the current channel, if status is SUCCESS. */
+ uint8_t energy_level;
+} plme_ed_conf_t;
+
+
+/**@brief PLME-ED.request.
+ *
+ * @details Request ED measurement for the current channel.
+ * In accordance with IEEE Std 802.15.4-2006, section 6.2.2.3.
+ */
+void plme_ed_req(void);
+
+
+/**@brief The PLME-ED.confirm callback function, implemented by the next higher layer.
+ *
+ * @details The PLME-ED.confirm primitive is generated by the PLME and issued
+ * to its next higher layer in response to an PLME-ED.request primitive.
+ * In accordance with IEEE Std 802.15.4-2006, section 6.2.2.4.
+ *
+ * @param[out] conf Pointer to PLME-ED.confirm parameters
+ */
+void plme_ed_conf(plme_ed_conf_t * conf);
+
+/** @} */
+
+#endif // PHY_PLME_ED_H_INCLUDED
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/802_15_4/api/PHY/phy_plme_pib.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/802_15_4/api/PHY/phy_plme_pib.h
new file mode 100644
index 0000000..7a1f6f6
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/802_15_4/api/PHY/phy_plme_pib.h
@@ -0,0 +1,212 @@
+/**
+ * Copyright (c) 2016 - 2018 Nordic Semiconductor ASA and Luxoft Global Operations Gmbh.
+ *
+ * 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#ifndef PHY_PLME_PIB_H_INCLUDED
+#define PHY_PLME_PIB_H_INCLUDED
+
+#include <stdint.h>
+#include <stddef.h>
+#include "phy_common.h"
+
+/** @file
+ * This file contains declarations of PHY Information Base routines and necessary types.
+ *
+ * @defgroup phy_pib PHY PIB API
+ * @ingroup phy_15_4
+ * @{
+ * @brief Module to declare PHY Information Base API
+ * @details The PHY PIB module declares PHY Information Base routines and necessary types according to
+ * the PHY specification. More specifically, PHY PIB Get request plme_get_req(), PHY PIB Set request
+ * plme_set_req(), PHY PIB Get confirm plme_get_conf(), and PHY PIB Set confirm plme_set_conf()
+ * primitives are declared. Two additional primitives not covered by the standard are declared. These are
+ * plme_get() and plme_set() which are synchronous versions of plme_get_req() and plme_set_req() accordingly.
+ */
+
+#define PHY_TX_POWER_TOLERANCE_1DB 0x00
+#define PHY_TX_POWER_TOLERANCE_3DB 0x40
+#define PHY_TX_POWER_TOLERANCE_6DB 0x80
+#define PHY_TX_POWER_TOLERANCE_MASK 0xC0
+
+/**
+ * @brief PHY PIB attribute identificators.
+ *
+ * @details In accordance with IEEE Std 802.15.4-2006, section 6.4.2.
+ */
+typedef enum
+{
+ PHY_CURRENT_CHANNEL_ID = 0x00, /**< Current channel. */
+ PHY_CHANNELS_SUPPORTED_ID = 0x01, /**< Supported channels. @note read only. */
+ PHY_TRANSMIT_POWER_ID = 0x02, /**< Transmit power. */
+ PHY_CCA_MODE_ID = 0x03, /**< CCA mode. */
+ PHY_CURRENT_PAGE_ID = 0x04, /**< Current page. */
+ PHY_MAX_FRAME_DURATION_ID = 0X05, /**< MAX Frame duration. @note read only. */
+ PHY_SHR_DURATION_ID = 0x06, /**< SHR Duration. @note read only. */
+ PHY_SYMBOLS_PER_OCTET_ID = 0x07, /**< Symbols per octet. @note read only. */
+} plme_pib_attr_id_t;
+
+
+/**
+ * @brief PHY PIB attribute type sizes.
+ *
+ * @details In accordance with IEEE Std 802.15.4-2006, Table 23.
+ */
+typedef union
+{
+ uint8_t phy_current_channel; /**< Current channel. */
+ uint32_t phy_channels_supported; /**< Supported channels. */
+ int8_t phy_transmit_power; /**< Returns one of the DBM_xxx macro values. */
+ uint8_t phy_cca_mode; /**< CCA mode. */
+ uint8_t phy_current_page; /**< Current page. */
+ uint16_t phy_max_frame_duration; /**< MAX Frame duration. */
+ uint8_t phy_shr_duration; /**< SHR Duration. */
+ uint16_t phy_symbols_per_octet; /**< Symbols per octet. */
+} phy_pib_item_t;
+
+
+/**@brief PLME-GET.request parameters.
+ *
+ * @details In accordance with IEEE Std 802.15.4-2006, section 6.2.2.5.
+ */
+typedef struct
+{
+ plme_pib_attr_id_t pib_attribute; /**< PIB attribute. */
+} plme_get_req_t;
+
+
+/**@brief PLME-GET.confirm parameters.
+ *
+ * @details In accordance with IEEE Std 802.15.4-2006, section 6.2.2.6.
+ */
+typedef struct
+{
+ phy_status_t status; /**< Status of operation. */
+ plme_pib_attr_id_t pib_attribute; /**< PIB attribute. */
+ phy_pib_item_t pib_attribute_value; /**< Attribute value. */
+} plme_get_conf_t;
+
+
+/**@brief PLME-SET.request parameters.
+ *
+ * @details In accordance with IEEE Std 802.15.4-2006, section 6.2.2.9.
+ */
+typedef struct
+{
+ plme_pib_attr_id_t pib_attribute; /**< PIB attribute. */
+ phy_pib_item_t pib_attribute_value; /**< Attribute value. */
+} plme_set_req_t;
+
+
+/**@brief PLME-SET.confirm parameters.
+ *
+ * @details In accordance with IEEE Std 802.15.4-2006, section 6.2.2.10.
+ */
+typedef struct
+{
+ phy_status_t status; /**< Status of operation. */
+ plme_pib_attr_id_t pib_attribute; /**< PIB attribute. */
+} plme_set_conf_t;
+
+
+/**@brief PLME-GET.request.
+ *
+ * @details In accordance with IEEE Std 802.15.4-2006, section 6.2.2.5.
+ *
+ * @param[in] req Pointer to PLME-GET.request parameters. See @ref plme_get_req_t.
+ */
+void plme_get_req(plme_get_req_t * req);
+
+
+/**@brief PLME-GET.confirm callback function, implemented by the next higher layer.
+ *
+ * @details The PLME-GET.confirm primitive is generated by the PLME and issued
+ * to its next higher layer in response to an PLME-GET.request primitive.
+ * In accordance with IEEE Std 802.15.4-2006, section 6.2.2.6.
+ *
+ * @param[out] conf Pointer to PLME-GET.confirm parameters. See @ref plme_get_conf_t.
+ */
+void plme_get_conf(plme_get_conf_t * conf);
+
+
+/**@brief PLME-SET.request.
+ *
+ * @details In accordance with IEEE Std 802.15.4-2006, section 6.2.2.9.
+ *
+ * @param[in] req Pointer to PLME-SET.request parameters. See @ref plme_set_req_t.
+ */
+void plme_set_req(plme_set_req_t * req);
+
+
+/**@brief PLME-SET.confirm callback function, implemented by the next higher layer.
+ *
+ * @details In accordance with IEEE Std 802.15.4-2006, section 6.2.2.10.
+ *
+ * @param[out] conf Pointer to PLME-SET.confirm parameters. See @ref plme_set_conf_t.
+ */
+void plme_set_conf(plme_set_conf_t * conf);
+
+/**
+ * @brief Getting parameters from PIB directly (without request - confirm approach)
+ *
+ * @details Optional. Not covered by a standard.
+ *
+ * @param[in] id attribute id.
+ * @param[out] mem pointer to memory for parameter storing.
+ *
+ * @return status of operation.
+ */
+phy_status_t plme_get(plme_pib_attr_id_t id, void * mem);
+
+
+/**
+ * @brief Setting parameters to PIB directly (without request - confirm approach)
+ *
+ * @details Optional. Not covered by a standard.
+ *
+ * @param[in] id attribute id.
+ * @param[out] mem pointer to memory for parameter storing.
+ *
+ * @return status of operation.
+ */
+phy_status_t plme_set(plme_pib_attr_id_t id, void * mem);
+
+/** @} */
+
+#endif // PHY_PLME_PIB_H_INCLUDED
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/802_15_4/api/PHY/phy_plme_trx.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/802_15_4/api/PHY/phy_plme_trx.h
new file mode 100644
index 0000000..075f178
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/802_15_4/api/PHY/phy_plme_trx.h
@@ -0,0 +1,135 @@
+/**
+ * Copyright (c) 2016 - 2018 Nordic Semiconductor ASA and Luxoft Global Operations Gmbh.
+ *
+ * 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#ifndef PHY_PLME_TRX_H_INCLUDED
+#define PHY_PLME_TRX_H_INCLUDED
+
+#include <stdint.h>
+#include "phy_common.h"
+
+/** @file
+ * This file contains declarations of PHY TRX routines and necessary types.
+ *
+ * @defgroup phy_trx PHY TRX API
+ * @ingroup phy_15_4
+ * @{
+ * @brief Module to declare PHY Transceiver State API
+ * @details The PHY TRX module declares Transceiver state change PHY routines and necessary types according to
+ * the PHY specification. More specifically, PHY set TRX state request plme_set_trx_state_req(),
+ * PHY TRX state change confirm plme_set_trx_state_conf() primitives are declared. An additional
+ * primitive not covered by the standard is declared. This is plme_set_trx_state() which is a synchronous
+ * version of plme_set_trx_state_req().
+ */
+
+/**
+ * @brief PLME-SET_TRX_STATE.request parameters.
+ *
+ * @details The PLME-SET_TRX_STATE.request primitive is generated
+ * by the next higher layer of a device and issued to its PLME to
+ * set transmitter status.
+ *
+ * In accordance with IEEE Std 802.15.4-2006, section 6.2.2.7.1
+ */
+typedef struct
+{
+ /** One of PHY_RX_ON, PHY_TRX_OFF, PHY_FORCE_TRX_OFF, PHY_TX_ON or PHY_FORCE_TX_ON. */
+ phy_enum_t state;
+} plme_trx_req_t;
+
+
+/**
+ * @brief PLME-TRX.confirm parameters.
+ *
+ * @details The PLME-TRX.confirm primitive is generated by
+ * PLME and issued to its next higher layer in response to
+ * an PLME-SET_TRX_STATE.request primitive.
+ *
+ * In accordance with IEEE Std 802.15.4-2006, section 6.2.2.8.1
+ */
+typedef struct
+{
+ /** Holds result of trx state change request.
+ *
+ * @details Equals to PHY_SUCCESS if state changed successfully
+ * or current PHY state in either case.
+ */
+ phy_enum_t status;
+} plme_trx_conf_t;
+
+
+/**@brief PLME-SET_TRX_STATE request.
+ *
+ * @details Request PHY to change internal operating state.
+ * In accordance with IEEE Std 802.15.4-2006, section 6.2.2.7
+ *
+ * @param[in] req Pointer to PLME-SET_TRX_STATE.request parameters.
+ * See @ref plme_trx_req_t.
+ */
+void plme_set_trx_state_req(plme_trx_req_t * req);
+
+
+/**@brief PLME-SET_TRX_STATE.confirm callback function, implemented by the next higher layer.
+ *
+ * @details The PLME-SET_TRX_STATE.confirm primitive is generated
+ * by the PLME and issued to its next higher layer in response to
+ * an PLME-SET_TRX_STATE.request primitive.
+ *
+ * In accordance with IEEE Std 802.15.4-2006, section 6.2.2.8
+ *
+ * @param[out] conf Pointer to PLME-TRX.confirm parameters. See @ref plme_trx_conf_t.
+ */
+void plme_set_trx_state_conf(plme_trx_conf_t * conf);
+
+
+/**@brief Direct (synchronous) PLME-SET_TRX_STATE access.
+ *
+ * @details Optional. Not covered by the standard.
+
+ * @param[in] state One of PHY_RX_ON, PHY_TRX_OFF, PHY_FORCE_TRX_OFF or PHY_TX_ON.
+ *
+ * @return PHY_SUCCESS if state changed successfully or current PHY state
+ * in either case.
+ */
+phy_enum_t plme_set_trx_state(phy_enum_t state);
+
+/** @} */
+
+#endif // PHY_PLME_TRX_H_INCLUDED
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/802_15_4/api/RAL/nrf52_soc/ral_api_spec.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/802_15_4/api/RAL/nrf52_soc/ral_api_spec.h
new file mode 100644
index 0000000..188d955
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/802_15_4/api/RAL/nrf52_soc/ral_api_spec.h
@@ -0,0 +1,99 @@
+/**
+ * Copyright (c) 2016 - 2018 Nordic Semiconductor ASA and Luxoft Global Operations Gmbh.
+ *
+ * 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#ifndef RAL_API_SPEC_H_INCLUDED
+#define RAL_API_SPEC_H_INCLUDED
+
+#include <stdbool.h>
+
+/**
+ * @defgroup ral_api_spec RAL Special API
+ * @ingroup ral_api
+ * @{
+ */
+
+/**@brief Specific CCA MODE for FPGA RAL
+ */
+#define RAL_TRX_CCA_MODE4 4
+
+/**@brief Maximum available value of CCA MODE for FPGA RAL
+ */
+#define RAL_TRX_CCA_MODE_MAX RAL_TRX_CCA_MODE4
+
+/**@brief Maximum duration of CCA algorithm including a task scheduling
+ */
+#define RAL_LONGEST_CCA_DURATION_US 500
+
+/**@brief Maximum transmit power in dBm
+ */
+#define RAL_MAXIMUM_TX_POWER 9
+
+/**@brief Maximum tolerance of transmit power in dBm
+ */
+#define RAL_TX_POWER_TOLERANCE PHY_TX_POWER_TOLERANCE_6DB
+
+/**@brief Value of RF signal power (in dBm) for RSSI equals zero.
+ */
+#define RSSI_BASE_VAL 90
+
+/**@brief Values above this shouldn't appear in RSSI register result.*/
+#define RSSI_REG_MAX_VAL 20
+
+
+/**@brief Controls whether radio module will automatically calculate Frame
+ * Control Sequence field.
+ *
+ * @param auto_fcs_enabled if set to true, automatically generated FCS will
+ * replace the last two bytes of PHY service data unit.
+ */
+void ral_auto_fcs_set(bool auto_fcs_enabled);
+
+/**@brief Controls whether radio module will enter channel jamming mode.
+ *
+ * @param jamming_enabled if set to true, radio will perform jamming on current
+ * channel and energy. No data transmission can be done
+ * while jamming is enabled.
+ */
+void ral_jam_control_set(bool jamming_enabled);
+
+/** @} */
+
+#endif// RAL_API_SPEC_H_INCLUDED
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/802_15_4/api/RAL/nrf52_soc/ral_fsm.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/802_15_4/api/RAL/nrf52_soc/ral_fsm.h
new file mode 100644
index 0000000..e78c628
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/802_15_4/api/RAL/nrf52_soc/ral_fsm.h
@@ -0,0 +1,96 @@
+/**
+ * Copyright (c) 2016 - 2018 Nordic Semiconductor ASA and Luxoft Global Operations Gmbh.
+ *
+ * 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#ifndef RAL_FSM_H_INCLUDED
+#define RAL_FSM_H_INCLUDED
+
+#include "sys_fsm.h"
+
+/**
+ * @defgroup ral_api_fsm RAL FSM API
+ * @ingroup ral_api
+ * @{
+ */
+
+// list of possible events
+typedef enum
+{
+ E_RESET,
+ E_TRX_END, /**< Radio signals that TX or RX is complete.*/
+ E_TX_REQ, /**< Initiates upload of a frame into radio memory and
+ transmission of it into air.*/
+ E_TRX_OFF,
+ E_TX_ON,
+ E_FORCE_TX_ON,
+ E_RX_ON,
+} ral_fsm_events_t;
+
+// states
+typedef enum
+{
+/* State symbol for short FSM debug mode */
+/* I */ S_TRX_OFF,
+/* J */ S_TX_ON,
+/* */ S_BUSY_TX,
+/* G */ S_RX_ON,
+/* B */ S_BUSY_RX,
+} ral_fsm_states_t;
+
+/**@brief Reads current state of RAL state machine.
+ *
+ * @return Current state.
+ */
+ral_fsm_states_t ral_fsm_current_state_get(void);
+
+/**@brief Initializes finite state machine of radio chip.*/
+void ral_fsm_init(void);
+
+/**@brief Sends new event to radio FSM. This function is used for
+ * changing radio state.
+ *
+ * @param event - event id for FSM.
+ * @param p_data - pointer to event specific data (expects pointer to ral_mem_t).
+ */
+void ral_fsm_event_post(ral_fsm_events_t event, void * p_data);
+
+/** @} */
+
+#endif /* RAL_FSM_H_INCLUDED */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/802_15_4/api/RAL/nrf52_soc/ral_fsm_private.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/802_15_4/api/RAL/nrf52_soc/ral_fsm_private.h
new file mode 100644
index 0000000..d4198fe
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/802_15_4/api/RAL/nrf52_soc/ral_fsm_private.h
@@ -0,0 +1,88 @@
+/**
+ * Copyright (c) 2016 - 2018 Nordic Semiconductor ASA and Luxoft Global Operations Gmbh.
+ *
+ * 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#ifndef RAL_FSM_PRIVATE_H_INCLUDED
+#define RAL_FSM_PRIVATE_H_INCLUDED
+
+#include "nrf52840.h"
+#include "nrf52840_bitfields.h"
+
+/**
+ * @defgroup ral_api_fsm_private RAL FSM private API
+ * @ingroup ral_api
+ * @{
+ */
+
+/** @brief Private RAL function. Sets radio module into TRX_OFF mode if
+ * it was in RX or TX mode. */
+void ral_fsm_a_trx_off(void * p_data);
+
+/** @brief Private RAL function. Sets radio module into TRX_OFF mode if
+ * it was in BUSY_RX or BUSY_TX mode. */
+void ral_fsm_a_force_trx_off(void * p_data);
+
+/** @brief Private RAL function. Switches radio module from TRX_OFF
+ * to TX_ON mode. */
+void ral_fsm_a_tx_on(void * p_data);
+
+/** @brief Private RAL function. Switches radio module from TRX_OFF
+ * to RX_ON mode. */
+void ral_fsm_a_rx_on(void * p_data);
+
+/** @brief Private RAL function. Switches radio module from TX_ON
+ * to RX_ON mode. */
+void ral_fsm_a_tx_to_rx(void * p_data);
+
+/** @brief Private RAL function. Switches radio module from RX_ON
+ * to TX_ON mode. */
+void ral_fsm_a_rx_to_tx(void * p_data);
+
+/** @brief Private RAL function. Switches radio module from TRX_OFF
+ * to channel jamming mode. */
+void ral_jamming_on(void);
+
+/** @brief Private RAL function. Switches radio module from channel jamming
+ * mode to TRX_OFF state. */
+void ral_jamming_off(void);
+
+/** @} */
+
+#endif /* RAL_FSM_PRIVATE_H_INCLUDED */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/802_15_4/api/RAL/nrf52_soc/ral_irq_handlers.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/802_15_4/api/RAL/nrf52_soc/ral_irq_handlers.h
new file mode 100644
index 0000000..87de14d
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/802_15_4/api/RAL/nrf52_soc/ral_irq_handlers.h
@@ -0,0 +1,65 @@
+/**
+ * Copyright (c) 2016 - 2018 Nordic Semiconductor ASA and Luxoft Global Operations Gmbh.
+ *
+ * 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#ifndef RAL_IRQ_HANDLERS_H_INCLUDED
+#define RAL_IRQ_HANDLERS_H_INCLUDED
+
+#define RAL_NRF_BCC_COMPARE_VALUE 32
+#define RAL_NRF_BCC_COMPARE_NONE (RAL_NRF_BCC_COMPARE_VALUE + 16)
+#define RAL_NRF_BCC_COMPARE_SHORT (RAL_NRF_BCC_COMPARE_VALUE + 32)
+#define RAL_NRF_BCC_COMPARE_LONG (RAL_NRF_BCC_COMPARE_VALUE + 80)
+
+/**
+ * @defgroup ral_api_irq_handlers RAL auxiliary functions
+ * @ingroup ral_api
+ * @{
+ */
+
+/**@brief RAL IRQ handler symbol importer (dummy function).
+ *
+ * @details This function is only used to correctly import
+ * RADIO_IRQHandler symbol.
+ */
+void ral_irq_handler_import(void);
+
+/** @} */
+
+#endif// RAL_IRQ_HANDLERS_H_INCLUDED
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/802_15_4/api/RAL/nrf52_soc/ral_rf_init.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/802_15_4/api/RAL/nrf52_soc/ral_rf_init.h
new file mode 100644
index 0000000..735cc85
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/802_15_4/api/RAL/nrf52_soc/ral_rf_init.h
@@ -0,0 +1,69 @@
+/**
+ * Copyright (c) 2016 - 2018 Nordic Semiconductor ASA and Luxoft Global Operations Gmbh.
+ *
+ * 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#ifndef RAL_INIT_H_INCLUDED
+#define RAL_INIT_H_INCLUDED
+
+/**
+ * @defgroup ral_api_init RAL RF initialization API
+ * @ingroup ral_api
+ * @{
+ */
+
+/**@brief Initializes radio transceiver.
+ */
+void ral_rf_init(void);
+
+/**@brief Channel number setting.
+ *
+ * @param channel_num - channel number
+ */
+void ral_rf_channel_set(uint8_t channel_num);
+
+/**@brief Channel number getting.
+ *
+ * @return channel number
+ */
+uint8_t ral_rf_channel_get(void);
+
+/** @} */
+
+#endif /* RAL_INIT_H_INCLUDED */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/802_15_4/api/RAL/ral_api.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/802_15_4/api/RAL/ral_api.h
new file mode 100644
index 0000000..8aba803
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/802_15_4/api/RAL/ral_api.h
@@ -0,0 +1,220 @@
+/**
+ * Copyright (c) 2016 - 2018 Nordic Semiconductor ASA and Luxoft Global Operations Gmbh.
+ *
+ * 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#ifndef RAL_API_H_INCLUDED
+#define RAL_API_H_INCLUDED
+
+#include "ral_api_spec.h"
+#include "sys_time.h"
+#include "phy_common.h"
+#include "phy_pd_data.h"
+#include "mac_common.h"
+#include "mac_mlme_pib.h"
+#include "mac_time.h"
+#include <stdint.h>
+#include <stdbool.h>
+
+/**@file ral_api.h
+ *
+ * @defgroup ral_api Radio Abstraction Layer common API
+ * @ingroup ral_15_4
+ * @{
+ *
+ * @brief Radio abstraction layer common interface.
+ *
+ * @details These are requirements for the implementation code:
+ *
+ * - no frames must be received between new frame indication and
+ * a call to ral_data_ind_read.
+ */
+
+// various constants to use with MAC/PHY header parsing
+#define PHR_POS 0
+#define PHR_SIZE 1
+#define CRC_SIZE 2
+#define MAC_FRAME_CTRL_POS 0
+#define MAC_FRAME_CTRL_SIZE 2
+#define ACK_REQUEST_MASK 0x20
+#define SEQ_NUM_POS (MAC_FRAME_CTRL_POS + MAC_FRAME_CTRL_SIZE)
+#define ACK_PD_BIT_MASK 0x0010
+
+#define FRAME_TYPE_MASK 0x0007
+#define FRAME_TYPE_BEACON 0x0000
+#define FRAME_TYPE_DATA 0x0001
+#define FRAME_TYPE_ACK 0x0002
+#define FRAME_TYPE_COMMAND 0x0003
+
+#define FRAME_PENDING_MASK 0x0010
+
+/**@brief RAL atomic section */
+typedef volatile uint8_t ral_atomic_t;
+
+// private RAL data
+typedef struct
+{
+ volatile uint8_t tx_seq_num;
+ volatile bool ack_needed;
+ volatile bool waiting_for_ack;
+ volatile ral_atomic_t ral_atomic;
+ volatile mac_timestamp_t received_frame_timestamp;
+ volatile bool spi_transfer;
+ volatile bool cca_performing;
+#if defined(AT86RF231)
+ volatile int8_t ed_value;
+ volatile bool unread_frame; /** This flag is used to deny transmission if incoming frame
+ has not been read from radio buffer.
+ todo: remove this deny to accelerate data exchange.
+ */
+ volatile bool is_promiscuous_mode; /**< Set to true if promiscuous mode is enabled.*/
+#elif (defined(NRF52_SERIES) || defined(NRF52))
+ // pointer to free memory for rx DMA
+ volatile uint8_t * p_buffer;
+ volatile sys_time_t calibr_value;
+ volatile uint8_t bcc_part;
+#endif
+} ral_mem_t;
+
+
+/**@brief Initializes radio abstraction layer.
+ */
+void ral_init(void);
+
+/**@brief Resets radio abstraction layer.
+ */
+void ral_reset(void);
+
+/**@brief Performs synchronous ED measurement.
+ */
+uint8_t ral_ed_perform(void);
+
+/**@brief Sends request to change radio state.
+ *
+ * @param state - New radio state. One of...
+ *
+ * @return PHY_SUCCESS, if state has been successfully achieved;
+ * current state, if state cannot be reached.*/
+phy_enum_t ral_state_set(const phy_enum_t state);
+
+/**@brief Returns current state of radio.
+ */
+phy_enum_t ral_state_get(void);
+
+/**@brief Puts radio into sleep mode
+ */
+void ral_sleep(void);
+
+ /**@brief Awakes a radio
+ */
+void ral_wakeup(void);
+
+/**@brief Performs synchronous cca.
+ */
+phy_status_t ral_cca_perform(void);
+
+/**@brief Sends PHY frame.
+ *
+ * @param[in] pd_data - full data frame to be send.
+ *
+ * @details RAL automatically adds header and FCS control bytes
+ * to \a pd_data. Caller must reserve 1 byte before \a psdu
+ * pointer and may leave last two bytes of payload (i.e. FCS
+ * control field) uninitialized.
+ *
+ * RF chip or RAL code is responsible to receive an ACK frame.
+ * After ACK is handled, device should be restored to the TX state.*/
+void ral_data_req(pd_data_req_t * pd_data);
+
+/**@brief Reads indication frame from radio.
+ *
+ * @retval Pointer on the structure of a PHY data indication
+ * with received frame.
+ */
+pd_data_ind_t * ral_data_ind_read(void);
+
+/**@brief Enable data flow from radio hardware after it was disabled
+ * by ral_data_flow_disable().
+ */
+void ral_data_flow_enable(void);
+
+
+/**@brief Disable data flow from radio hardware
+ */
+void ral_data_flow_disable(void);
+
+
+/**@brief This function is used to set attribute from MAC or PHY layer
+ * without checking of its boundaries.
+ *
+ * @param id - one of #MAC_SHORT_ADDRESS, #MAC_EXTENDED_ADDRESS, #MAC_PAN_ID
+ * and some other values.
+ * @param p_value - pointer to new value.
+ */
+void ral_attribute_set(uint8_t id, const void * p_value);
+
+
+/**@brief This function is used to get a copy of attribute value stored inside
+ * radio module.
+ *
+ * @param[in] id - one of #PHY_CURRENT_CHANNEL_ID, #PHY_TRANSMIT_POWER_ID or
+ * #PHY_CCA_MODE_ID. Other attributes are not supported.
+ * @param[out] p_attr_value - pointer to value to get.
+ */
+void ral_attribute_get(uint8_t id, void * p_attr_value);
+
+/**@brief This function is used to define frame start time by it's size
+ * and the timestamp, when RX IRQ has been received.
+ *
+ * @param irq_time - moment when IRQ has been received.
+ * @param frame_size - size of received frame in bytes.
+ *
+ * @retval MAC timestamp when PHY header has been started to receive.
+ */
+mac_timestamp_t ral_rx_start_time(mac_timestamp_t irq_time, uint8_t frame_size);
+
+/**@brief This function performs RSSI.
+ *
+ * @retval RSSI sample value.
+ */
+uint8_t ral_rssi_get(void);
+
+/** @} */
+
+#endif /* RAL_API_H_INCLUDED */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/802_15_4/api/SecAL/sec_aes_ccm.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/802_15_4/api/SecAL/sec_aes_ccm.h
new file mode 100644
index 0000000..ec0ed50
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/802_15_4/api/SecAL/sec_aes_ccm.h
@@ -0,0 +1,128 @@
+/**
+ * Copyright (c) 2016 - 2018 Nordic Semiconductor ASA and Luxoft Global Operations Gmbh.
+ *
+ * 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#ifndef SEC_AES_CCM_H_INCLUDED
+#define SEC_AES_CCM_H_INCLUDED
+
+#include <stdint.h>
+
+/** @file
+ * This file contains declarations of the AES CCM encryption/decryption routines and necessary types.
+ * It also contains the declaration of the Security Abstract library initialization routine.
+ *
+ * @defgroup sec_aes_ccm Security AES CCM declarations
+ * @ingroup sec_15_4
+ * @{
+ * @brief Module to declare Security AES CCM API
+ */
+
+/**
+ * @brief AES CCM Status enumeration.
+ */
+typedef enum
+{
+ AES_CCM_OK, /**< AES CCM operation succeeded. */
+ AES_ENGINE_FAIL, /**< AES engine failed. */
+ AES_CCM_FAIL, /**< CCM algorithm failed. */
+ AES_CCM_AUTH_FAIL /**< CCM authentication failed. */
+} sec_aes_ccm_status_t;
+
+/**
+ * @brief AES CCM request.
+ *
+ * @details The AES CCM request primitive is issued by the AES user.
+ * There are two use cases for the request:
+ * The first one is to encrypt the user text with some given key.
+ * The second one is to decrypt the cipher text against the key.
+ * The encrypted or decrypted data is stored in text_data.
+ */
+typedef struct
+{
+ /** Counted authentication tag. */
+ uint8_t * mic;
+ /** Security level identifier. */
+ uint8_t level;
+ /** A 128-bit-long string to be used as a key. Each entity must have evidence that access
+ * to this key is restricted to the entity itself and its intended key sharing group member(s). */
+ uint8_t * key;
+ /** A nonce N of 15 - L octets. Within the scope of any encryption key, the nonce value must be unique. */
+ uint8_t * nonce;
+ /** An octet string representing plain text data in case of encryption and cipher text data
+ * in case of decryption. */
+ uint8_t * text_data;
+ /** Text data length. */
+ uint8_t text_data_len;
+ /** Octet string representing input data to perform authentication. */
+ uint8_t * auth_data;
+ /** Auth data length. */
+ uint8_t auth_data_len;
+} sec_aes_ccm_req_t;
+
+
+/**
+ * @brief Function for initializing the security abstraction layer.
+ */
+void sec_init(void);
+
+/**
+ * @brief AES CCM encryption transformation.
+ *
+ * @details Performs synchronous encryption of data.
+ *
+ * @param req Encryption request structure.
+ * @return AES_CCM_OK on success, otherwise an implementation defined error.
+ */
+sec_aes_ccm_status_t sec_aes_ccm_enc(sec_aes_ccm_req_t * req);
+
+
+/**
+ * @brief AES CCM decryption transformation.
+ *
+ * @details Performs synchronous decryption of a cipher.
+ *
+ * @param req Decryption request structure.
+ * @return AES_CCM_OK on success, otherwise an implementation defined error.
+ */
+sec_aes_ccm_status_t sec_aes_ccm_dec(sec_aes_ccm_req_t * req);
+
+/** @} */
+
+#endif /* SEC_AES_CCM_H_INCLUDED */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/802_15_4/api/SecAL/sec_aes_entity.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/802_15_4/api/SecAL/sec_aes_entity.h
new file mode 100644
index 0000000..527b666
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/802_15_4/api/SecAL/sec_aes_entity.h
@@ -0,0 +1,75 @@
+/**
+ * Copyright (c) 2016 - 2018 Nordic Semiconductor ASA and Luxoft Global Operations Gmbh.
+ *
+ * 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#ifndef SEC_AES_ENTITY_H_INCLUDED
+#define SEC_AES_ENTITY_H_INCLUDED
+
+#include <stdint.h>
+
+/** @file
+ * This file contains declaration of the AES encryption routine.
+ * It also contains the declaration of the AES entity initialization routine.
+ *
+ * @defgroup aes_entity Security AES entity declarations
+ * @ingroup sec_15_4
+ * @{
+ * @brief Module to declare AES entity API.
+ */
+
+/**
+ * @brief Function for initializing the AES ECB module.
+ */
+void aes_entity_init(void);
+
+/**
+ * @brief AES encryption.
+ *
+ * @details Performs synchronous encryption of text against the key.
+ * Encrypted data is stored to text memory.
+ *
+ * @param key Pointer to a 128-bit key.
+ * @param text Pointer to a 128-bit plain text data.
+ */
+void aes_handle(uint8_t * key, uint8_t * text);
+
+/** @} */
+
+#endif /* SEC_AES_ENTITY_H_INCLUDED */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/802_15_4/api/SysAL/sys_crc.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/802_15_4/api/SysAL/sys_crc.h
new file mode 100644
index 0000000..f85430b
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/802_15_4/api/SysAL/sys_crc.h
@@ -0,0 +1,95 @@
+/**
+ * Copyright (c) 2016 - 2018 Nordic Semiconductor ASA and Luxoft Global Operations Gmbh.
+ *
+ * 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#ifndef SYS_CRC_H_INCLUDED
+#define SYS_CRC_H_INCLUDED
+
+#include <stdint.h>
+#include <stddef.h>
+
+/** @file
+ * This file contains declarations of the CRC computing routines and necessary macros/types.
+ *
+ * @defgroup sys_crc System CRC API
+ * @ingroup sys_15_4
+ * @{
+ * @brief Module to declare System CRC API.
+ * @details The CRC module implements a set of routines to compute the 16-bit CRC value for octet arrays.
+ */
+
+/**
+ * @brief Defines an initial value for the CRC sum.
+ */
+#define SYS_CRC_INIT 0
+
+/**
+ * @brief CRC value type. This module uses 16-bit CRC.
+ */
+typedef uint16_t sys_crc_t;
+
+/**
+ * @brief Function for computing CRC value for given data.
+ *
+ * @param[in] p_data Pointer to data to compute.
+ * @param[in] length Length of data.
+ *
+ * @return Returns the CRC value for input data.
+ */
+sys_crc_t sys_crc_calc(const uint8_t * p_data, size_t length);
+
+/**
+ * @brief Function for updating the CRC value taking into the account the previously counted value.
+ *
+ * @details This function is used when input data is represented by several pieces.
+ * Consequently, a call to this function for each piece will give a correct
+ * total CRC value.
+ *
+ * @param[in] current_crc Previously counted CRC value. Should be SYS_CRC_INIT for the first piece.
+ * @param[in] p_data Pointer to the current piece of data.
+ * @param[in] length Length of the current piece of data.
+ *
+ * @return Returns the updated CRC value.
+ */
+sys_crc_t sys_crc_continue(sys_crc_t current_crc, const uint8_t * p_data, size_t length);
+
+/** @} */
+
+#endif /* SYS_CRC_H_INCLUDED */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/802_15_4/api/SysAL/sys_debug.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/802_15_4/api/SysAL/sys_debug.h
new file mode 100644
index 0000000..c9943de
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/802_15_4/api/SysAL/sys_debug.h
@@ -0,0 +1,177 @@
+/**
+ * Copyright (c) 2016 - 2018 Nordic Semiconductor ASA and Luxoft Global Operations Gmbh.
+ *
+ * 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#ifndef SYS_DEBUG_H_INCLUDED
+#define SYS_DEBUG_H_INCLUDED
+
+
+#include "hal_debug_interface.h"
+#include "hal_trace_interface.h"
+#include <stdbool.h>
+#include <stdarg.h>
+
+/* This header file contains macros for debugging. */
+
+#ifndef ASSERT
+ #ifdef CONFIG_DEBUG
+ #define ASSERT(CONDITION_STATEMENT) \
+ do \
+ { \
+ bool LOCAL_CONDITION_CHECK = (CONDITION_STATEMENT); \
+ if (LOCAL_CONDITION_CHECK != true) \
+ { \
+ sys_assert_handler((#CONDITION_STATEMENT), __LINE__, __FILE__); \
+ } \
+ } while (0)
+ #else
+
+ #define ASSERT(CONDITION_STATEMENT)
+
+ #endif // CONFIG_DEBUG
+#endif // ASSERT
+
+#ifndef ASSERT_INFO
+ #ifdef CONFIG_DEBUG
+ #define ASSERT_INFO(CONDITION_STATEMENT, INFO_FMT, ...) \
+ do \
+ { \
+ bool LOCAL_CONDITION_CHECK = (CONDITION_STATEMENT); \
+ if (LOCAL_CONDITION_CHECK != true) \
+ { \
+ sys_assert_info_handler((#CONDITION_STATEMENT), __LINE__, __FILE__, \
+ INFO_FMT, __VA_ARGS__); \
+ } \
+ } while (0)
+
+ #else
+
+ #define ASSERT_INFO(CONDITION_STATEMENT, INFO_FMT, ...)
+
+ #endif // CONFIG_DEBUG
+#endif // ASSERT_INFO
+
+#ifndef ASSERT_STATIC
+ #ifdef CONFIG_DEBUG
+ #define ASSERT_STATIC(e) do { enum {SA = 1/(e)}; } while (0)
+ #else
+ #define ASSERT_STATIC(e)
+ #endif // CONFIG_DEBUG
+#endif // ASSERT_STATIC
+
+/**
+ * @defgroup sys_debug Debugging macros
+ * @ingroup sys_15_4
+ * @{
+ * @brief Functions used for debugging.
+ */
+
+
+/**@brief System assertion fault handler.
+ *
+ * @details This macro should be used whenever an assertion fault is detected.
+ *
+ * @param[in] CONDITION_STRING Assertion condition string, which occurred to be not true.
+ */
+#define SYS_ASSERT_HANDLER(CONDITION_STRING) \
+ do \
+ { \
+ sys_assert_handler(CONDITION_STRING, __LINE__, __FILE__); \
+ } while (0)
+
+
+#ifndef TRACE_PUTS
+ #ifdef CONFIG_TRACE
+ #define TRACE_PUTS(s) HAL_TRACE_INTERFACE_PUTS(s)
+ #else
+ #define TRACE_PUTS(s)
+ #endif //CONFIG_TRACE
+#endif //TRACE_PUTS
+
+
+#ifndef TRACE
+ #ifdef CONFIG_TRACE
+ #define TRACE(INFO_FMT, ...) sys_trace_handler(INFO_FMT, __VA_ARGS__)
+ #else
+ #define TRACE(INFO_FMT, ...)
+ #endif // CONFIG_DEBUG
+#endif // TRACE
+
+
+/**@brief System assertion fault handler function.
+ *
+ * @param[in] condition Assertion condition string, which was expected to be true.
+ *
+ * @param[in] line Line number.
+ *
+ * @param[in] file File name.
+ */
+extern void sys_assert_handler(
+ const char * condition, const int line, const char * file);
+
+
+/**@brief System assertion fault handler function with additional assertion information.
+ *
+ * @param[in] condition Assertion condition string, which was expected to be true.
+ *
+ * @param[in] line Line number.
+ *
+ * @param[in] file File name.
+ *
+ * @param[in] info_fmt Format string for additional assert information.
+ *
+ * @param[in] ... Arguments list corresponding to the format string.
+ */
+extern void sys_assert_info_handler(
+ const char * condition, const int line, const char * file,
+ const char * info_fmt, ...);
+
+
+/**@brief System trace output handler function.
+ *
+ * @param[in] fmt Format string for trace output.
+ *
+ * @param[in] ... Arguments list corresponding to the format string.
+ */
+extern void sys_trace_handler(const char * fmt, ...);
+
+/** @} */
+
+#endif // SYS_DEBUG_H_INCLUDED
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/802_15_4/api/SysAL/sys_events.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/802_15_4/api/SysAL/sys_events.h
new file mode 100644
index 0000000..554f892
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/802_15_4/api/SysAL/sys_events.h
@@ -0,0 +1,167 @@
+/**
+ * Copyright (c) 2016 - 2018 Nordic Semiconductor ASA and Luxoft Global Operations Gmbh.
+ *
+ * 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#ifndef SYS_EVENTS_H_INCLUDED
+#define SYS_EVENTS_H_INCLUDED
+
+#include <stddef.h>
+#include "sys_queue.h"
+
+/** @file
+ * This file contains declarations of the Events API and necessary types. The Events feature is implemented
+ * using the Queue functionality.
+ *
+ * @defgroup sys_events System events API
+ * @ingroup sys_15_4
+ * @{
+ * @brief Module for declaring system events API.
+ * @details The Events module defines some routines to subscribe/unsubscribe to/from system events. The events pool
+ * can be extended by adding new events to the sys_event_id_t enumeration. The registered callbacks
+ * can be called for an array of events. The callbacks can be called implicitly via posting the event by the
+ * sys_event_post() routine.
+ */
+
+/**@brief IDs of globally available events.
+ *
+ * @details Event IDs are system extension points that allow the user to implement
+ * specific processing of predefined set of events, occurring in different modules.
+ */
+typedef enum
+{
+ SYS_EVENT_FALLING_ASLEEP, /**< Falling asleep event. */
+ SYS_EVENT_WAKE_UP, /**< Waking up event. */
+ SYS_EVENT_OUT_OF_MEMORY, /**< Out of memory event. */
+ SYS_EVENT_MEMORY_FREED, /**< Memory was freed up event. */
+
+ /** \note The list of system events can be extended during the implementation phase. */
+
+ /* The following event IDs are used only for unit testing */
+ TST_EVENT_0, /**< Test event #0. */
+ TST_EVENT_1, /**< Test event #1. */
+ TST_EVENT_2, /**< Test event #2. */
+
+#if (CONFIG_USE_SYS_TASK_NOTIFIER == 1)
+ /** This event is posted when there are unhandled events available in
+ * any of the schedulers.
+ */
+ SYS_EVENT_NEW_TASK,
+#endif
+
+ SYS_EVENTS_AMOUNT
+} sys_event_id_t;
+
+
+/**@brief Prototype of user-implemented callback for processing an event.
+ *
+ * @details This callback is registered for the given event by a *_subscribe routine,
+ * and is then called by the system events engine, when this event occurs.
+ *
+ * @param[in] p_data Pointer to the data, specific for this event.
+ */
+typedef void (* sys_event_callback_t)(const void * p_data);
+
+
+/**@brief Event descriptor.
+ *
+ * @details This descriptor is used to subscribe/unsubscribe to/from the event.
+ */
+typedef struct
+{
+ /** Service field. */
+ sys_queue_item_t queue_item;
+
+ /** ID of the event to which this callback is to be subscribed. */
+ sys_event_id_t event_id;
+
+ /** Callback function which is to be called when this event occurs. */
+ sys_event_callback_t callback;
+} sys_event_desc_t;
+
+
+/**@brief Function for initializing the global events infrastructure.
+ */
+void sys_events_init(void);
+
+
+/**@brief Function for subscribing to a system event.
+ *
+ * @param[in] p_event_desc Pointer to the event descriptor.
+ */
+void sys_event_subscribe(sys_event_desc_t * p_event_desc);
+
+
+/**@brief Function for unsubscribing from a system event event.
+ *
+ * @param[in] p_event_desc Pointer to the event descriptor.
+ */
+void sys_event_unsubscribe(sys_event_desc_t * p_event_desc);
+
+
+/**@brief Function for subscribing to a group of events.
+ *
+ * @param[in] p_desc_array Pointer to the array of event descriptors.
+ * @param[in] desc_amount Amount of event descriptors in the array.
+ */
+void sys_events_array_subscribe(sys_event_desc_t * p_desc_array, size_t desc_amount);
+
+
+/**@brief Function for unsubscribing from the group of events.
+ *
+ *
+ * @param[in] p_desc_array Pointer to the array of event descriptors.
+ * @param[in] desc_amount Amount of the event descriptors in the array.
+ */
+void sys_events_array_unsubscribe(sys_event_desc_t * p_desc_array, size_t desc_amount);
+
+
+/**@brief Function for posting an event.
+ *
+ * @details This function is used to notify all the subscribers of the given events via
+ * their callbacks, when the given event occurs.
+ *
+ * @param[in] event_id ID of the event to be posted.
+ * @param[in] p_data Pointer to be passed to the event handlers' callbacks.
+ */
+void sys_event_post(sys_event_id_t event_id, const void * p_data);
+
+/** @} */
+
+#endif // SYS_EVENTS_H_INCLUDED
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/802_15_4/api/SysAL/sys_fsm.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/802_15_4/api/SysAL/sys_fsm.h
new file mode 100644
index 0000000..51a3ee2
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/802_15_4/api/SysAL/sys_fsm.h
@@ -0,0 +1,286 @@
+/**
+ * Copyright (c) 2016 - 2018 Nordic Semiconductor ASA and Luxoft Global Operations Gmbh.
+ *
+ * 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#ifndef SYS_FSM_H_INCLUDED
+#define SYS_FSM_H_INCLUDED
+
+#include <stdint.h>
+#include <stdbool.h>
+
+/** @file
+ * This file contains declarations of the Finite State Machine (FSM) primitives and necessary types.
+ *
+ * @defgroup sys_fsm Finite State Machine API
+ * @ingroup sys_15_4
+ * @{
+ * @brief Module to declare Finite State Machine API
+ * @details The FSM module implements the Finite State Machine abstraction. The user is intended to implement a transition
+ * table of states with guards and actions in order to represent some event-driven subject. When a table is
+ * implemented, call sys_fsm_init() to initialize the FSM. After that, the only routine to
+ * work with FSM is sys_fsm_event_post().
+ */
+
+/**@brief Fixed-size type for FSM state ID.
+ */
+typedef uint8_t sys_fsm_state_id_t;
+
+
+/**@brief Fixed-size type for FSM event ID.
+ */
+typedef uint8_t sys_fsm_event_id_t;
+
+
+/**@brief Fixed-size type for FSM guard condition ID.
+ */
+typedef uint8_t sys_fsm_guard_id_t;
+
+
+/**@brief Fixed-size type for FSM action ID.
+ */
+typedef uint8_t sys_fsm_action_id_t;
+
+
+/**@brief FSM transition description (item of FSM transition table).
+ *
+ * @details When an event with given event_id occurs, the guard condition with guard_id
+ * is checked, and if it returns true, the action with action_id is performed,
+ * and state machine is switched to the state with new_state_id.
+ */
+typedef struct
+{
+ sys_fsm_event_id_t event_id; /**< FSM event ID. */
+ sys_fsm_guard_id_t guard_id; /**< FSM guard ID. */
+ sys_fsm_action_id_t action_id; /**< FSM action ID. */
+ sys_fsm_state_id_t new_state_id; /**< New state ID. */
+#if defined(CONFIG_FSM_DEBUG)
+ const char * debug_string;
+#endif
+} sys_fsm_transition_t;
+
+
+/**@brief FSM transition declaration (item of FSM transition table).
+ */
+#if defined(CONFIG_FSM_DEBUG)
+# define SYS_FSM_TRANSITION(event_id, guard_id, action_id, new_state_id) \
+ {(event_id), (guard_id), (action_id), (new_state_id), \
+ "(" #event_id ", " #guard_id ", " #action_id " -> " #new_state_id ")"}
+#else
+# define SYS_FSM_TRANSITION(event_id, guard_id, action_id, new_state_id) \
+ {(event_id), (guard_id), (action_id), (new_state_id)}
+#endif
+
+
+/**@brief FSM state declaration.
+ *
+ * @details The state is an aggregator item of the FSM transition table, aggregating
+ * the transitions, declared immediately after this state declaration.
+ * All transition declaration items, following the state declaration item,
+ * will be aggregated in this state, until the next state declaration item,
+ * or the "end of table" item.
+ */
+#define SYS_FSM_STATE(state_id) \
+ {(state_id) | SYS_FSM_STATE_FLAG, 0, 0, 0}
+
+
+/**@brief Empty guard condition ID.
+ *
+ * @details Special value of the guard_id field. If it is used in transition declaration,
+ * guard check will be omitted.
+ */
+#define SYS_FSM_NO_GUARD 0xFF
+
+
+/**@brief Empty guard condition ID (useful synonym).
+ *
+ * @details Special value of the guard_id field. If it is used in transition declaration,
+ * guard check will be omitted.
+ */
+#define SYS_FSM_OTHERWISE 0xFF
+
+
+/**@brief Empty guard condition ID (useful synonym).
+ *
+ * @details Special value of the guard_id field. If it is used in transition declaration,
+ * guard check will be omitted.
+ */
+#define SYS_FSM_ALWAYS 0xFF
+
+
+/**@brief Empty action ID.
+ *
+ * @details Special value of the action_id field. If it is used in transition declaration,
+ * no action will be performed during the transition.
+ */
+#define SYS_FSM_NO_ACTION 0xFF
+
+
+/**@brief Same state ID.
+ *
+ * @details Special value of the next_state_id field. If it is used in transition
+ * declaration, the current state will not be changed.
+ */
+#define SYS_FSM_SAME_STATE 0xFF
+
+
+/**@brief Any state ID.
+ *
+ * @details Special value of the event_id field. If it is used in transition
+ * declaration table, then the transitions listed in this state will be applied
+ * in case they have not been listed in the transition table for the
+ * current FSM state.
+ * Only one SYS_FSM_STATE(SYS_FSM_ANY_STATE) can be present in the transition table.
+ */
+#define SYS_FSM_ANY_STATE 0xFF
+
+
+/**@brief State declaration flag.
+ *
+ * @details Special flag of the event_id field. This flag is used to distinguish
+ * between state declaration and transition declaration.
+ */
+#define SYS_FSM_STATE_FLAG 0x80
+
+
+/**@brief Prototype of a user-defined FSM guard condition function.
+ *
+ * @details You must implement a single FSM guard condition function which will
+ * use an ID of the needed guard check as a parameter.
+ *
+ * @param[in] guard_id Guard condition ID to be checked.
+ * @param[in] p_data Additional FSM specific data.
+ *
+ * @retval true Transition is allowed, false otherwise.
+ */
+typedef bool (* sys_fsm_guard_t)(sys_fsm_guard_id_t guard_id, void * p_data);
+
+
+/**@brief Prototype of a user-defined FSM action function.
+ *
+ * @details You must implement a single FSM action function which will
+ * use an ID of the needed action as a parameter.
+ *
+ * @param[in] action_id Action ID to be performed.
+ * @param[in] p_data Additional FSM specific data.
+ */
+typedef void (* sys_fsm_action_t)(sys_fsm_action_id_t action_id, void * p_data);
+
+
+/**@brief Constant FSM descriptor which can reside in read-only memory.
+ */
+typedef struct
+{
+#if defined(CONFIG_FSM_DEBUG)
+ const char * debug_fsm_name;
+#endif
+ /** Pointer to the transition table.
+ */
+ const sys_fsm_transition_t * transition_table;
+
+ /** Number of transitions in the transition table.
+ */
+ uint8_t transitions_amount;
+
+ /** Initial state ID.
+ */
+ sys_fsm_state_id_t initial_state;
+
+ /** Pointer to the guard condition function.
+ */
+ sys_fsm_guard_t guard;
+
+ /** Pointer to the action function.
+ */
+ sys_fsm_action_t action;
+} sys_fsm_const_descriptor_t;
+
+
+/**@brief FSM dynamic descriptor, holding the current state of the FSM.
+*/
+typedef struct
+{
+ /** Pointer to the constant FSM descriptor which can reside in read-only memory.
+ */
+ const sys_fsm_const_descriptor_t * fsm_const_desc;
+
+ /** Index of the "any state transitions" block.
+ */
+ uint8_t any_state_transitions_index;
+
+ /** Current state ID.
+ */
+ volatile sys_fsm_state_id_t current_state;
+
+ /** Recursion protection.
+ */
+ volatile uint8_t recursion_protection;
+} sys_fsm_t;
+
+
+#if defined(CONFIG_FSM_DEBUG)
+ #define FSM_DEBUG_NAME(name_string) .debug_fsm_name = name_string,
+#else
+ #define FSM_DEBUG_NAME(name_string)
+#endif
+
+
+/**@brief Function for initializing a specific FSM.
+ *
+ * @param[in] p_fsm Pointer to FSM descriptor to initialize.
+ * @param[in] p_fsm_const Pointer to constant FSM descriptor with transition table, etc.
+ */
+void sys_fsm_init(sys_fsm_t * p_fsm, const sys_fsm_const_descriptor_t * p_fsm_const);
+
+
+/**@brief Function for posting an event to FSM.
+ *
+ * @details This function causes FSM transition from the current state to the new state,
+ * according to the transition table of this FSM.
+ * The corresponding guard check and action is performed.
+ *
+ * @param[in] p_fsm Pointer to FSM descriptor.
+ * @param[in] event_id Event ID to post.
+ * @param[in] p_data Pointer to the FSM-specific data.
+ */
+void sys_fsm_event_post(sys_fsm_t * p_fsm, sys_fsm_event_id_t event_id, void * p_data);
+
+/** @} */
+
+#endif // SYS_FSM_H_INCLUDED
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/802_15_4/api/SysAL/sys_init.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/802_15_4/api/SysAL/sys_init.h
new file mode 100644
index 0000000..8efeaf6
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/802_15_4/api/SysAL/sys_init.h
@@ -0,0 +1,69 @@
+/**
+ * Copyright (c) 2016 - 2018 Nordic Semiconductor ASA and Luxoft Global Operations Gmbh.
+ *
+ * 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#ifndef SYS_INIT_H_INCLUDED
+#define SYS_INIT_H_INCLUDED
+
+#include <stddef.h>
+
+/**
+ * @defgroup sys_15_4_init Initialization API
+ * @ingroup sys_15_4
+ * @{
+ * @brief API for initizalizing the system abstraction library.
+ */
+
+/** @brief Initializes every component of this stack.
+ *
+ * This function must be called before using any of the components.
+ *
+ * @param[in] p_start Pool start address.
+ * @param[in] size Size of the pool in bytes.
+ *
+ * @details The pool start address must be aligned on the ALIGN_VALUE boundary, which is
+ * defined in @c sys_utils.h.
+ * The pool size should be multiple of an ALIGN_VALUE, which is defined in @c sys_utils.h.
+ */
+void sys_init(void * p_start, size_t size);
+
+/** @} */
+
+#endif /* SYS_INIT_H_INCLUDED */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/802_15_4/api/SysAL/sys_list.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/802_15_4/api/SysAL/sys_list.h
new file mode 100644
index 0000000..533ee6f
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/802_15_4/api/SysAL/sys_list.h
@@ -0,0 +1,248 @@
+/**
+ * Copyright (c) 2016 - 2018 Nordic Semiconductor ASA and Luxoft Global Operations Gmbh.
+ *
+ * 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#ifndef SYS_LIST_H_INCLUDED
+#define SYS_LIST_H_INCLUDED
+
+/** @file
+ * This file contains declarations of the doubly linked list primitives and necessary types.
+ * This implementation is Linux-proven and used in the memory management module.
+ *
+ * @defgroup sys_list Doubly linked list API.
+ * @ingroup sys_15_4
+ * @{
+ * @brief Module to declare the doubly linked list API.
+ */
+
+/**
+ * Internal list "head" struct.
+ */
+struct sys_list_head
+{
+ struct sys_list_head * next;
+ struct sys_list_head * prev;
+};
+
+typedef struct sys_list_head sys_list_head_t;
+
+
+/**
+ * @brief Initializes a list by variable name.
+ * @warning this macro assumes that a list "head" (sys_list_head_t) variable
+ * with name \a name is already created.
+ *
+ * @param[inout] name The "head" struct name.
+ */
+#define LIST_HEAD_INIT(name) { &(name), &(name) }
+
+/**
+ * @brief Defines and initializes a new list.
+ * @details A call to this macro creates a new variable with the given name and
+ * initializes it as a list "head".
+ *
+ * @param[inout] name The "head" struct name.
+ */
+#define LIST_HEAD(name) sys_list_head_t name = { &(name), &(name) }
+
+
+/**
+ * @brief Initializes a list by pointer.
+ *
+ * @param[inout] ptr Pointer to a list.
+ */
+#define INIT_LIST_HEAD(ptr) \
+ do \
+ { \
+ (ptr)->prev = (ptr); \
+ (ptr)->next = (ptr); \
+ } while (0)
+
+
+/**
+ * @brief Checks if a list is empty.
+ *
+ * @param[in] sys_list_head Pointer to a list.
+ * @return 0 if not empty, non-zero otherwise.
+ */
+#define IS_EMPTY(sys_list_head) (sys_list_head)->next == (sys_list_head)
+
+
+/**
+ * @brief Adds a new item to the list between \a l_prev and \a l_next elements.
+ * @warning This routine assumes that \a l_next is next to \a l_prev in the list.
+ * @note This is an internal helper routine which is not intended to be used by the user.
+ *
+ * @param[in] l_prev Pointer to the previous element.
+ * @param[in] l_next Pointer to the next element.
+ * @param[in] l_new Pointer to a new element.
+ */
+static inline void sys_ll_list_add(sys_list_head_t * l_prev,
+ sys_list_head_t * l_next,
+ sys_list_head_t * l_new)
+{
+ l_new->prev = l_prev;
+ l_prev->next = l_new;
+ l_next->prev = l_new;
+ l_new->next = l_next;
+}
+
+/**
+ * @brief Deletes an element between \a l_prev and \a l_next elements.
+ * @warning This macro assumes that \a l_next is next to \a l_prev in the list.
+ * @note This is an internal helper routine which is not intended to be used by the user.
+ *
+ * @param[in] l_prev Pointer to the previous element.
+ * @param[in] l_next Pointer to the next element.
+ */
+static inline void sys_ll_list_del(sys_list_head_t * l_next,
+ sys_list_head_t * l_prev)
+{
+ l_next->prev = l_prev;
+ l_prev->next = l_next;
+}
+
+/**
+ * @brief Function for adding a new item to the head of the list.
+ *
+ * @param[in] new Pointer to a new element.
+ * @param[in] head Pointer to the list head.
+ */
+static inline void sys_list_add(sys_list_head_t * new, sys_list_head_t * head)
+{
+ sys_ll_list_add(head, head->next, new);
+}
+
+
+/**
+ * @brief Function for adding a new item to the tail of the list.
+ *
+ * @param[in] new Pointer to a new element.
+ * @param[in] head Pointer to the list head.
+ */
+static inline void sys_list_add_tail(sys_list_head_t * new, sys_list_head_t * head)
+{
+ sys_ll_list_add(head->prev, head, new);
+}
+
+
+/**
+ * @brief Function for deleting an entry from list.
+ *
+ * @param[in] entry The element to delete from the list.
+ */
+static inline void sys_list_del(sys_list_head_t * entry)
+{
+ sys_ll_list_del(entry->next, entry->prev);
+}
+
+
+/**
+ * @brief Function for deleting an entry from the list and reinitializing it.
+ *
+ * @param[in] entry The element to delete from the list.
+ */
+static inline void sys_list_del_init(sys_list_head_t * entry)
+{
+ sys_ll_list_del(entry->next, entry->prev);
+ INIT_LIST_HEAD(entry);
+}
+
+
+/**
+ * @brief Function for testing if a list is empty.
+
+ * @param[in] head The list to test.
+ * @return 0 if not empty, non-zero otherwise.
+ */
+static inline unsigned int sys_list_empty(sys_list_head_t * head)
+{
+ return IS_EMPTY(head);
+}
+
+
+/**
+ * @brief Sets a pointer to a variable to the parent structure pointer using a
+ * pointer to a field in this structure.
+ *
+ * @note This is a version of @ref GET_PARENT_BY_FIELD() extended by setting to a variable.
+ *
+ * @param[out] ll_ret_var Variable pointer name to return.
+ * @param[in] ll_ptr Pointer to the structure field.
+ * @param[in] ll_type Name of the parent structure.
+ * @param[in] ll_member Name of the structure field.
+ */
+#define SYS_LIST_ENTRY(ll_ret_var, ll_ptr, ll_type, ll_member) \
+ do \
+ { \
+ size_t p = (size_t) ll_ptr; \
+ size_t off = offsetof(ll_type, ll_member); \
+ ll_ret_var = (ll_type *) (p - off); \
+ } while (0)
+
+
+/**
+ * @brief Iterates through the list.
+ * @note Use @ref SYS_LIST_FOR_EACH_SAFE() for thread-safe cases.
+ *
+ * @param[out] pos Iterator variable.
+ * @param[in] head Pointer to the list head.
+ */
+#define SYS_LIST_FOR_EACH(pos, head) \
+ for (pos = ((head)->next); \
+ ((pos) != (head)); \
+ pos = (pos)->next)
+
+
+/**
+ * @brief Thread-safe version of @ref SYS_LIST_FOR_EACH().
+ *
+ * @param[out] ll_pos Iterator variable.
+ * @param[out] ll_pos_n Temporary iterator variable (next entry).
+ * @param[in] ll_head Pointer to the list head.
+ */
+#define SYS_LIST_FOR_EACH_SAFE(ll_pos, ll_pos_n, ll_head) \
+ for (ll_pos = (ll_head)->next, ll_pos_n = (ll_head)->next->next; \
+ (ll_pos) != (ll_head); \
+ ll_pos = ll_pos_n, ll_pos_n = ll_pos->next)
+
+/** @} */
+
+#endif /* SYS_LIST_H_INCLUDED */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/802_15_4/api/SysAL/sys_memory_manager.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/802_15_4/api/SysAL/sys_memory_manager.h
new file mode 100644
index 0000000..c05849b
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/802_15_4/api/SysAL/sys_memory_manager.h
@@ -0,0 +1,92 @@
+/**
+ * Copyright (c) 2016 - 2018 Nordic Semiconductor ASA and Luxoft Global Operations Gmbh.
+ *
+ * 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#ifndef SYS_MEMORY_MANAGER_H_INCLUDED
+#define SYS_MEMORY_MANAGER_H_INCLUDED
+
+#include <stddef.h>
+#include <stdint.h>
+
+/** @file
+ * This file contains declarations of the Memory manager API.
+ *
+ * @defgroup sys_memory_manager Memory Manager API
+ * @ingroup sys_15_4
+ * @{
+ * @brief Module to declare Memory Manager API.
+ * @details The Memory Manager module implements the standard API for allocating/freeing memory chunks. The module must
+ * be initialized by sys_mm_init() before a call to any alloc/free routines. The memory can be allocated by a
+ * call to sys_mm_alloc() and freed by a call to sys_mm_free(). Minimal chunk of memory to allocate is one byte,
+ * however the sys_mm_alloc() routine will allocate the number of bytes aligned to the length of the
+ * machine word (e.g. 4 bytes for 32-bit architectures). The module is implemented using the doubly linked
+ * lists API.
+ */
+
+/**@brief Function for initializing the memory manager.
+ * @details Initialize the memory manager pool of the 'size' bytes length at 'p_start' address.
+ *
+ * @param p_start Pool start address.
+ * @param size Size of the pool in bytes.
+ */
+void sys_mm_init(void * p_start, size_t size);
+
+
+/**@brief Function for allocating memory in the pool.
+ * @details Search and allocate free memory resources.
+ *
+ * @param[in] size Size of the requested memory.
+ *
+ * @retval Pointer to allocated memory,
+ * NULL in case of error.
+ */
+void * sys_mm_alloc(size_t size);
+
+
+/**@brief Function for freeing the allocated memory.
+ *
+ * @param[in] p_addr Pointer to the memory to free.
+ *
+ */
+void sys_mm_free(void * p_addr);
+
+/** @} */
+
+#endif // SYS_MEMORY_MANAGER_H_INCLUDED
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/802_15_4/api/SysAL/sys_queue.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/802_15_4/api/SysAL/sys_queue.h
new file mode 100644
index 0000000..8f817c0
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/802_15_4/api/SysAL/sys_queue.h
@@ -0,0 +1,290 @@
+/**
+ * Copyright (c) 2016 - 2018 Nordic Semiconductor ASA and Luxoft Global Operations Gmbh.
+ *
+ * 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#ifndef SYS_QUEUE_H_INCLUDED
+#define SYS_QUEUE_H_INCLUDED
+
+#include <stdbool.h>
+#include <stdint.h>
+
+/** @file
+ * This file contains declarations of the primitives to work with queues and necessary types.
+ *
+ * @defgroup sys_queues Queue API
+ * @ingroup sys_15_4
+ * @{
+ * @brief Module to declare the queue API.
+ * @details The queue module implements a set of routines to deal with queues. Before
+ * any calls to its API are issued, a queue must be initialized using sys_queue_init(). The following routines
+ * return queue items from different parts of an initialized queue without removing it from the queue:
+ * sys_queue_front(), sys_queue_back(), sys_queue_next(), and sys_queue_at().
+ * The following routines insert elements to the queue: sys_queue_push_front(),
+ * sys_queue_push_back(), sys_queue_push_predicated(), sys_queue_push_predicated_force(), and sys_queue_insert().
+ * The following routines remove elements from the queue: sys_queue_pop_front(), sys_queue_remove(),
+ * sys_queue_remove_after(). These helper routines get information about a queue: sys_queue_size() and
+ * sys_queue_is_empty(). The module also supports an iterator macro implemented by SYS_QUEUE_FOR_EACH().
+ */
+
+/**@brief Queue item descriptor.
+ *
+ * @details In order to store any user data struct in a queue, the user struct should contain
+ * a field of type 'sys_queue_item_t'. This field may be at any offset.
+ * The user data item can be cast from the queue item,
+ * by the \ref GET_PARENT_BY_FIELD() macro from sys_utils.h.
+ */
+typedef struct sys_queue_item_s
+{
+ struct sys_queue_item_s * next;
+} sys_queue_item_t;
+
+/**@brief Queue descriptor.
+ */
+typedef sys_queue_item_t sys_queue_t;
+
+/**@brief Prototype of a predicate function for pushing an item into the queue.
+ *
+ * @details As a user of the queue library, implement the predicate function and pass it
+ * as a parameter to \ref sys_queue_push_predicated(). You can choose
+ * whether insertion of a new item should be done before the given existing item of
+ * the queue, or not.
+ *
+ * @param[in] p_before_item Pointer to the existing item before which a new item
+ * should be inserted.
+ * @param[in] p_new_item Pointer to the item to be inserted into the queue.
+ *
+ * @retval true Insertion is to be done before the given item, false otherwise.
+ */
+typedef bool (* sys_queue_push_predicate_t)(
+ sys_queue_item_t * p_before_item,
+ sys_queue_item_t * p_new_item);
+
+
+/**@brief Function for initializing the queue before any other usage of the queue.
+ *
+ * @details Initialize (reset) the queue to its initial state. The queue becomes empty.
+ *
+ * @param[in] p_queue Queue to be initialized.
+ */
+void sys_queue_init(sys_queue_t * p_queue);
+
+
+/**@brief Function for getting the front (head) item of the queue without removing it.
+ *
+ * @details Return a pointer to the item from the head of the queue but leave it in the queue.
+ *
+ * @param[in] p_queue Queue to get the item from.
+ *
+ * @retval Pointer to the head item of the queue, or NULL if the queue is empty.
+ */
+sys_queue_item_t * sys_queue_front(const sys_queue_t * p_queue);
+
+
+/**@brief Function for getting the back (tail) item of the queue without removing it.
+ *
+ * @details Return a pointer to the item from the tail of the queue but leave it in the queue.
+ *
+ * @param[in] p_queue Queue to get the item from.
+ *
+ * @retval Pointer to the tail item of the queue, or NULL if the queue is empty.
+ */
+sys_queue_item_t * sys_queue_back(const sys_queue_t * p_queue);
+
+
+/**@brief Function for getting the item, next to the given item of the queue.
+ *
+ * @details Return a pointer to the next item after the given one, or NULL if the
+ * given item is the last item of the queue.
+ *
+ * @param[in] p_queue Pointer to the queue.
+ * @param[in] p_item Pointer to the item.
+ *
+ * @retval Pointer to the next item after the given one, or NULL if the
+ * given item is the last item of the queue.
+ */
+sys_queue_item_t * sys_queue_next(const sys_queue_t * p_queue, const sys_queue_item_t * p_item);
+
+
+/**@brief Function for pushing an item to the front (head) of the queue.
+ *
+ * @details This function inserts an item to the head of the queue.
+ *
+ * @param[in] p_queue Queue to push the item to.
+ * @param[in] p_item Item to insert to the front of the queue.
+ */
+void sys_queue_push_front(sys_queue_t * p_queue, sys_queue_item_t * p_item);
+
+
+/**@brief Function for pushing an item to the back (tail) of the queue.
+ *
+ * @details This function inserts an item to the tail of the queue.
+ *
+ * @param[in] p_queue Queue to push the item to.
+ * @param[in] p_item Item to insert to the tail of the queue.
+ */
+void sys_queue_push_back(sys_queue_t * p_queue, sys_queue_item_t * p_item);
+
+
+/**@brief Function for pushing an item to the queue with a predicate.
+ *
+ * @details Conditionally push an item to the queue using the given predicate that tries to determine
+ * the insertion position.
+ *
+ * @param[in] p_queue Queue to push the item to.
+ * @param[in] p_item Item to be pushed.
+ * @param[in] predicate Predicate to be used to find the insertion position.
+ *
+ * @retval true The item was inserted into the queue, false otherwise.
+ */
+bool sys_queue_push_predicated(
+ sys_queue_t * p_queue,
+ sys_queue_item_t * p_item,
+ sys_queue_push_predicate_t predicate);
+
+
+/**@brief Function for pushing an item to the queue with a predicate forcing insertion to the tail if the predicate
+ * fails.
+ *
+ * @details Unconditionally push an item to the queue using the given predicate that tries to
+ * determine the insertion position.
+ * If predicate returns false, then force the insertion to the tail of the queue.
+ *
+ * @param[in] p_queue Queue to push item to.
+ * @param[in] p_item Item to be pushed.
+ * @param[in] predicate Predicate to be used to find the insertion position.
+ */
+void sys_queue_push_predicated_force(
+ sys_queue_t * p_queue,
+ sys_queue_item_t * p_item,
+ sys_queue_push_predicate_t predicate);
+
+
+/**@brief Function for getting and removing the front (head) item from the queue.
+ *
+ * @details Get an item from the head of the queue and remove it from the queue.
+ *
+ * @param[in] p_queue Queue to get and remove the head item from.
+ *
+ * @retval Pointer to the head item of queue or NULL if the queue is empty.
+ */
+sys_queue_item_t * sys_queue_pop_front(sys_queue_t * p_queue);
+
+
+/**@brief Function for removing an item from the queue.
+ *
+ * @details The given item will be removed from the queue.
+ *
+ * @note The complexity of this function is O(n). Use function \ref sys_queue_remove_after()
+ * whenever the previous item of the queue is known.
+ *
+ * @param[in] p_queue Queue to remove the item from.
+ * @param[in] p_item Item to remove from the queue.
+ */
+void sys_queue_remove(sys_queue_t * p_queue, sys_queue_item_t * p_item);
+
+
+/**@brief Function for removing the item after the given item from the queue.
+ *
+ * @details The item next to the given one will be removed from the queue.
+ *
+ * @param[in] p_queue Queue to remove the item from.
+ * @param[in] p_after_item Next to this item will be removed.
+ */
+void sys_queue_remove_after(sys_queue_t * p_queue, sys_queue_item_t * p_after_item);
+
+
+/**@brief Function for returning the current size of a queue, i.e. number of elements inside it.
+ *
+ * @details This function goes through the whole queue, so it is relatively slow.
+ *
+ * @param[in] p_queue Queue to work with.
+ *
+ * @retval Number of items currently inserted into the queue.
+ */
+uint8_t sys_queue_size(const sys_queue_t * p_queue);
+
+
+/**@brief Function for returning a pointer to the item inside a queue represented by an index.
+ *
+ * @details This function searches through the whole queue, so it is relatively slow.
+ *
+ * @param[in] p_queue Queue to work with.
+ * @param[in] index Requested index.
+ *
+ * @retval Pointer to the requested item or NULL if the queue size is less
+ * than \a index.
+ */
+sys_queue_item_t * sys_queue_at(const sys_queue_t * p_queue, const uint8_t index);
+
+
+/**@brief Function for inserting an item at the specified position represented by an index in the queue.
+ * If this position is too big, it is inserted to the tail of the queue.
+ *
+ * @details This function searches through the whole queue, so it is relatively slow.
+ *
+ * @param[in] p_queue Queue to insert to.
+ * @param[in] p_item Item to be inserted.
+ * @param[in] pos Position inside the queue (0 is the front).
+ */
+void sys_queue_insert(sys_queue_t * p_queue, sys_queue_item_t * p_item, const uint8_t pos);
+
+
+/**@brief Function for determining if a queue is empty.
+ *
+ * @param[in] p_queue Queue to be checked.
+ *
+ * @retval True if queue is empty, false otherwise.
+ */
+bool sys_queue_is_empty(const sys_queue_t * p_queue);
+
+
+/**@brief Macro for iterating through all items in the queue.
+ *
+ * @param[in] p_queue Pointer to the queue (sys_queue_t *).
+ * @param[in] p_iterator Variable to be used as an iterator (sys_queue_item_t *).
+ */
+#define SYS_QUEUE_FOR_EACH(p_queue, p_iterator) \
+ for (sys_queue_item_t * p_iterator = sys_queue_front(p_queue); \
+ p_iterator != NULL; \
+ p_iterator = sys_queue_next(p_queue, p_iterator))
+
+/** @} */
+
+#endif // SYS_QUEUE_H_INCLUDED
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/802_15_4/api/SysAL/sys_ringbuffer.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/802_15_4/api/SysAL/sys_ringbuffer.h
new file mode 100644
index 0000000..fcd8277
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/802_15_4/api/SysAL/sys_ringbuffer.h
@@ -0,0 +1,202 @@
+/**
+ * Copyright (c) 2016 - 2018 Nordic Semiconductor ASA and Luxoft Global Operations Gmbh.
+ *
+ * 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#ifndef SYS_RINGBUFFER_H_INCLUDED
+#define SYS_RINGBUFFER_H_INCLUDED
+
+#include <stdint.h>
+#include <stdlib.h>
+#include <stdbool.h>
+
+/** @file
+ * This file contains declarations of the Ring buffer routines and necessary types. Please note that
+ * each ring buffer element should have size of 1 byte.
+ *
+ * @defgroup sys_ringbuffer System Ring buffer API
+ * @ingroup sys_15_4
+ * @{
+ * @brief Module for declaring System Ring buffer API.
+ * @details The Ring Buffer module implements routines to deal with the ring buffer. The following routines are supported:
+ * sys_ringbuffer_insert(), sys_ringbuffer_remove() to operate with single element. The
+ * sys_ringbuffer_remove_multiple() can be used to remove (read) several elements at once. The
+ * sys_ringbuffer_clear(), sys_ringbuffer_init(), and sys_ringbuffer_init_over() functions are used to clean up and
+ * initialize the ring buffer. Some information about the initialized ring buffer is available via the
+ * following routines: sys_ringbuffer_size_get() to get the number of used elements, sys_ringbuffer_chunk_get()
+ * to return the biggest, available to read, continuous chunk of elements, sys_ringbuffer_is_empty() and
+ * sys_ringbuffer_is_full() to check if the ring buffer is empty/full, and sys_ringbuffer_max_size_get() to get
+ * the ring buffer capacity. One of the samples for ring buffer usage is the UART implementation.
+ */
+
+/** This structure holds all necessary information about a ring buffer. It is intentionally left undocumented
+ * by Doxygen.
+ *
+ * All these fields are private and must NOT be changed by the user.
+ */
+typedef struct
+{
+ size_t write_index;
+ size_t read_index;
+ uint8_t * array;
+ size_t size;
+ bool is_full;
+} sys_ringbuffer_t;
+
+/** @brief Function for initializing an empty ring buffer over passed memory.
+ *
+ * @param[inout] buffer Instance of sys_ringbuffer_t that will be initialized.
+ * @param[in] memory Start address of the memory region used as a ring buffer.
+ * @param[in] length Size in bytes of the memory region used as a ring buffer.
+ */
+void sys_ringbuffer_init(sys_ringbuffer_t * buffer,
+ const void * memory,
+ const size_t length);
+
+/** @brief Function for initializing a ring buffer over passed memory and marking all
+ * pre_init_length elements as inserted.
+ *
+ * @details This function may be used to initialize a buffer with some
+ * pre-initialized data in it. Passed memory region is interpreted by this function
+ * as an already filled (partly or fully) ring buffer so that \a pre_init_length
+ * elements are marked as inserted.
+ *
+ * @param[inout] buffer Instance of sys_ringbuffer_t that will be initialized.
+ * @param[in] memory Start address of the memory region used as a ring buffer.
+ * @param[in] pre_init_length Number of elements (bytes) that had already been in \a memory.
+ * They would be inserted into the newly-initialized ring buffer in a FIFO manner.
+ * @param[in] length Size of the memory region used as a ring buffer.
+ */
+void sys_ringbuffer_init_over(sys_ringbuffer_t * buffer,
+ const void * memory,
+ const size_t pre_init_length,
+ const size_t length);
+
+/** @brief Function for removing an element from a ring buffer and returning it.
+ *
+ * @param[inout] buf Instance of @c sys_ringbuffer_t.
+ *
+ * @return Value of the removed element.
+ *
+ * @warning This buffer has no underflow control except assert.
+ */
+uint8_t sys_ringbuffer_remove(sys_ringbuffer_t * buf);
+
+/** @brief Function for quickly removing up to chunk_size elements from a ring buffer
+ * and marking those elements as available in the ring buffer.
+ *
+ * @param[inout] buffer Instance of @c sys_ringbuffer_t.
+ * @param[in] chunk_size Number of elements to release.
+ */
+void sys_ringbuffer_remove_multiple(sys_ringbuffer_t * buffer,
+ const size_t chunk_size);
+
+/** @brief Function for inserting a new element into a ring buffer.
+ *
+ * @param[inout] buffer Instance of @c sys_ringbuffer_t.
+ * @param[in] data Element value to insert.
+ *
+ * @warning In case of overflow, this buffer will overwrite the oldest
+ * element and the number of available elements will remain unchanged.
+ */
+void sys_ringbuffer_insert(sys_ringbuffer_t * buffer, const uint8_t data);
+
+/** @brief Function for clearing an instance of \a sys_ringbuffer_t, making it empty.
+ *
+ * @param[inout] buffer Instance of @c sys_ringbuffer_t.
+ */
+void sys_ringbuffer_clear(sys_ringbuffer_t * buffer);
+
+/** @brief Function for returning the number of used elements in a ring buffer instance.
+ *
+ * @param[inout] buf Instance of sys_ringbuffer_t.
+ *
+ * @return Number of elements.
+ */
+size_t sys_ringbuffer_size_get(const sys_ringbuffer_t * buf);
+
+/** @brief Function for returning the biggest, available to read, continuous chunk from a ring buffer array.
+ *
+ * @param[inout] buffer Instance of @c sys_ringbuffer_t.
+ * @param[out] chunk Pointer to a memory chunk removed from the ring buffer.
+ * @param[out] chunk_size Size of the removed chunk.
+ *
+ * @warning The returned chunk is still part of the ring buffer. To make the chunk elements available
+ * for write, call @c sys_ringbuffer_remove_multiple() after the chunk is processed.
+ */
+void sys_ringbuffer_chunk_get(sys_ringbuffer_t * buffer,
+ void ** chunk,
+ size_t * chunk_size);
+
+/** @brief Function for checking whether a ring buffer is empty.
+ *
+ * @param[inout] buf Instance of @c sys_ringbuffer_t.
+ *
+ * @return True if the ring buffer is empty.
+ */
+static inline bool sys_ringbuffer_is_empty(const sys_ringbuffer_t * buf)
+{
+ return ((buf->write_index == buf->read_index) && (!buf->is_full));
+}
+
+/** @brief Function for checking whether a ring buffer is full.
+ *
+ * @param[inout] buf Instance of @c sys_ringbuffer_t.
+ *
+ * @return True if number of items in the buffer equals to (length - 1).
+ */
+static inline bool sys_ringbuffer_is_full(const sys_ringbuffer_t * buf)
+{
+ return buf->is_full;
+}
+
+/** @brief Function for returning number of elements that can be potentially put into the buffer.
+ *
+ * @param[inout] buf Instance of @c sys_ringbuffer_t.
+ *
+ * @return Number of elements.
+ */
+static inline size_t sys_ringbuffer_max_size_get(const sys_ringbuffer_t * buf)
+{
+ return buf->size;
+}
+
+/** @} */
+
+#endif /* SYS_RINGBUFFER_H_INCLUDED */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/802_15_4/api/SysAL/sys_slab_allocator.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/802_15_4/api/SysAL/sys_slab_allocator.h
new file mode 100644
index 0000000..006f7d2
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/802_15_4/api/SysAL/sys_slab_allocator.h
@@ -0,0 +1,142 @@
+/**
+ * Copyright (c) 2016 - 2018 Nordic Semiconductor ASA and Luxoft Global Operations Gmbh.
+ *
+ * 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#ifndef SYS_SLAB_ALLOCATOR_H_INCLUDED
+#define SYS_SLAB_ALLOCATOR_H_INCLUDED
+
+#include "phy_pd_data.h"
+
+#ifndef CONFIG_SLAB_FRAME_POOL_SIZE
+#define CONFIG_SLAB_FRAME_POOL_SIZE 4
+#warning "CONFIG_SLAB_FRAME_POOL_SIZE not set in .config, using default"
+#endif
+
+/** @file
+ * This file contains declarations of the SLAB allocator API.
+ *
+ * @defgroup sys_slab_allocator SLAB Allocator API
+ * @ingroup sys_15_4
+ * @{
+ * @brief Module for declaring the SLAB Allocator API
+ */
+
+/**@brief The SLAB allocator buffer type (free or busy buffer).
+ */
+typedef enum
+{
+ SYS_SLAB_FREE_BUFFER, /**< The buffer is free */
+ SYS_SLAB_BUSY_BUFFER, /**< The buffer is busy */
+} sys_slab_buffer_type_t;
+
+/**@brief Initializes the SLAB allocator.
+ *
+ * @details Preallocates the frame pool
+ */
+void sys_sa_init(void);
+
+/**@brief Resets the SLAB allocator.
+ *
+ * @details Clear allocated the frame pools
+ */
+void sys_sa_reset(void);
+
+/**@brief Inserts item into one of the queues of the SLAB allocator.
+ *
+ * @details This function is used to put the item into the SLAB allocator
+ * queue. Type of buffer shall be chosen.
+ *
+ * @param[in] type Type of an inserted buffer (free or busy).
+ * @param[in] p_item Pointer to an inserted buffer.
+ */
+void sys_sa_buffer_put(sys_slab_buffer_type_t type, pd_data_ind_t * p_item);
+
+/**@brief Gets item from one of the queues of the SLAB allocator.
+ *
+ * @details This function is used to get the item from the SLAB allocator
+ * queues. Type of buffer shall be chosen. The buffer is deleted
+ * from the SLAB allocator
+ *
+ * @param[in] type Type of a gotten buffer (free or busy).
+ *
+ * @retval Pointer to a gotten buffer in case of success. NULL otherwise.
+ */
+pd_data_ind_t * sys_sa_buffer_get(sys_slab_buffer_type_t type);
+
+/**@brief Deletes an allocated item from the heap.
+ *
+ * @details This function is used to delete allocated by SLAB allocator buffer
+ * from the heap. Pointer to a frame memory of an allocated item shall be used.
+ *
+ * @param[in] p_frame Pointer to a frame memory of an allocated item.
+ */
+void sys_sa_buffer_free(uint8_t * p_frame);
+
+/**@brief Returns buffer back to queue of free buffers.
+ *
+ * @details This function is used to return allocated buffer back to the queue
+ * without allocation and deallocation.
+ *
+ * @param[in] p_item Pointer to an allocated item.
+ */
+void sys_sa_buffer_release(pd_data_ind_t * p_item);
+
+/**@brief Allocates memory for the queue of free buffers.
+ *
+ * @details This function is used to allocate buffer from heap
+ * and put them into the queue
+ *
+ * @retval True in case of success. False otherwise.
+ */
+bool sys_sa_memory_allocate(void);
+
+/**@brief Checks if there are any buffers in the SLAB allocator queue or not.
+ *
+ * @details Type of checked buffers shall be passed.
+ *
+ * @param[in] type Type of an checked buffers (free or busy).
+ *
+ * @retval True in case of absence of buffers. False otherwise.
+ */
+bool sys_sa_is_empty(sys_slab_buffer_type_t type);
+
+/** @} */
+
+#endif /* SYS_SLAB_ALLOCATOR_H_INCLUDED */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/802_15_4/api/SysAL/sys_sleep.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/802_15_4/api/SysAL/sys_sleep.h
new file mode 100644
index 0000000..0174ac4
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/802_15_4/api/SysAL/sys_sleep.h
@@ -0,0 +1,155 @@
+/**
+ * Copyright (c) 2016 - 2018 Nordic Semiconductor ASA and Luxoft Global Operations Gmbh.
+ *
+ * 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#ifndef SYS_SLEEP_H_INCLUDED
+#define SYS_SLEEP_H_INCLUDED
+
+#include <stdint.h>
+#include "sys_events.h"
+#include "hal_sleep.h"
+
+
+/** @file
+ *
+ * @defgroup sys_sleep Falling Asleep API
+ * @ingroup sys_15_4
+ * @{
+ * @brief Module for declaring the Falling Asleep API.
+ * @details Because additional preparation may be required to be done by user modules,
+ * prior to putting hardware into the sleep mode, a notification and approval mechanism
+ * is provided to the user.
+ * Each module that wants to be notified about the "falling asleep" event, has to subscribe
+ * to the HAL_EVENT_FALLING_ASLEEP event, using sys_sleep_approver_register(), and to
+ * get the unique approver's ID value.
+ * In the handler of the HAL_EVENT_FALLING_ASLEEP event, the module is able to perform
+ * the required preparation before falling asleep, and to approve the falling asleep request,
+ * using the module unique approver ID, after all preparation to sleep is finished.
+ * The hardware will fall asleep only after all the registered approvers
+ * approve the fall asleep request.
+ */
+
+/**@brief Approver ID typedef.
+ */
+typedef uint8_t sys_sleep_approver_id_t;
+
+
+/* Sanity check for CONFIG_MAX_SLEEP_APPROVERS
+ */
+#if (!defined(CONFIG_MAX_SLEEP_APPROVERS))
+# error "CONFIG_MAX_SLEEP_APPROVERS must be defined in config file"
+#elif (CONFIG_MAX_SLEEP_APPROVERS >= 256)
+# error "CONFIG_MAX_SLEEP_APPROVERS must be less than 256"
+#endif
+
+
+/**@brief Function for initializing the system sleep module.
+ *
+ * @details This function must be called before any usage of the System Sleep module.
+ */
+void sys_sleep_init(void);
+
+
+/**@brief Function for registering the approver of the system sleep request.
+ *
+ * @details After the sleep approver is registered with this function, the hardware will
+ * not fall asleep without its approval.
+ *
+ * @param[in] p_event_falling_asleep Event descriptor, which will handle
+ * the SYS_EVENT_FALLING_ASLEEP event.
+ * @param[in] p_event_wake_up Event descriptor, which will handle
+ * the SYS_EVENT_WAKE_UP event.
+ *
+ * @retval The unique approver ID, reserved for this newly-registered approver.
+ * This ID will be required to approve system sleep requests by this approver module.
+ */
+sys_sleep_approver_id_t sys_sleep_approver_register(
+ sys_event_desc_t * p_event_falling_asleep,
+ sys_event_desc_t * p_event_wake_up);
+
+
+/**@brief Function for unregistering the approver of the system sleep request.
+ *
+ * @details After the approver is unregistered, its approval will not be
+ * required to put the system into sleep mode.
+ *
+ * @param[in] approver_id The unique approver ID to be unregistered.
+ * @param[in] p_event_falling_asleep Event descriptor to unsubscribe from
+ * the SYS_EVENT_FALLING_ASLEEP event.
+ * @param[in] p_event_wake_up Event descriptor to unsubscribe from
+ * the SYS_EVENT_WAKE_UP event.
+ */
+void sys_sleep_approver_unregister(
+ sys_sleep_approver_id_t approver_id,
+ sys_event_desc_t * p_event_falling_asleep,
+ sys_event_desc_t * p_event_wake_up);
+
+
+/**@brief Function for approving the system sleep request.
+ *
+ * @details This function is to be called by the registered approver
+ * in order to approve putting the system into the sleep mode.
+ *
+ * @param[in] approver_id The unique approver ID.
+ */
+void sys_sleep_approve(sys_sleep_approver_id_t approver_id);
+
+
+/**@brief Function for requesting the system to safely enter into sleep mode.
+ *
+ * @details This function notifies all the registered sleep approvers with the
+ * HAL_EVENT_FALLING_ASLEEP event, allowing them to perform all the needed preparation
+ * before the hardware falls asleep. The hardware will enter sleep mode only after
+ * all registered approvers approve the fall asleep request.
+ *
+ * @param[in] sleep_time_ms Defines sleep time in ms.
+ */
+void sys_sleep_request_ms(uint32_t sleep_time_ms);
+
+
+/**@brief Function for getting information about the wakeup reason.
+ *
+ * @retval hal_wakeup_reason Interrupt source which was the wakeup reason.
+ */
+hal_wakeup_reason_t sys_sleep_wakeup_reason(void);
+
+/** @} */
+
+#endif // SYS_SLEEP_H_INCLUDED
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/802_15_4/api/SysAL/sys_task_scheduler.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/802_15_4/api/SysAL/sys_task_scheduler.h
new file mode 100644
index 0000000..201b931
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/802_15_4/api/SysAL/sys_task_scheduler.h
@@ -0,0 +1,121 @@
+/**
+ * Copyright (c) 2016 - 2018 Nordic Semiconductor ASA and Luxoft Global Operations Gmbh.
+ *
+ * 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#ifndef SYS_TASK_SCHEDULER_H_INCLUDED
+#define SYS_TASK_SCHEDULER_H_INCLUDED
+
+#include <stdint.h>
+#include <stdbool.h>
+#include "sys_utils.h"
+#include "hal_atomic.h"
+#include "sys_events.h"
+
+/** @file
+ * @defgroup sys_task_scheduler Task scheduler
+ * @ingroup sys_15_4
+ * @{
+ * @brief Module for task scheduling.
+ */
+
+/**@brief Identificators for registered handlers.
+ *
+ * Handlers will be called from the task scheduler.
+ */
+typedef enum
+{
+ PHY_TASK_ID,
+ HAL_TASK_ID,
+#if (CONFIG_HIGHEST_LAYER_PHY == 0)
+ MAC_TASK_ID,
+#endif
+ APP_TASK_ID,
+ SYS_TASK_ID,
+ SYS_TASKS_AMOUNT
+} sys_task_ids_t;
+
+/**@brief Prototype of a task handler.
+ *
+ * @details Handler which will be called by the scheduler.
+ */
+typedef void (* sys_task_handler_t)(void);
+
+/**@brief Pending tasks.
+ *
+ * @details Variable which includes markers of pending tasks.
+ */
+extern volatile uint_fast16_t g_tasks;
+
+/**@brief Notify task scheduler to add a task for execution.
+ *
+ * @details The function sets a marker for the task for execution.
+ * The task handler implements a tree architecture.
+ * Task handler of each layer includes handlers of the layer's components.
+ *
+ * @param[in] task_id Task identificator.
+ */
+static inline void sys_task_post(sys_task_ids_t task_id)
+{
+ atomic_t atomic = 0;
+
+ hal_atomic_start(&atomic);
+ g_tasks |= BIT(task_id);
+#if (CONFIG_USE_SYS_TASK_NOTIFIER == 1)
+ sys_event_post(SYS_EVENT_NEW_TASK, NULL);
+#endif
+ hal_atomic_end(&atomic);
+}
+
+/**@brief Returns true, if there are any event flags awaiting in the system scheduler.
+ */
+static inline bool sys_tasks_pending(void)
+{
+ return g_tasks != 0;
+}
+
+/**@brief Handle tasks in the main function.
+ *
+ * @details Handle tasks in the main function.
+ */
+void sys_task_run(void);
+
+/** @} */
+
+#endif // SYS_TASK_SCHEDULER_H_INCLUDED
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/802_15_4/api/SysAL/sys_time.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/802_15_4/api/SysAL/sys_time.h
new file mode 100644
index 0000000..00155b3
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/802_15_4/api/SysAL/sys_time.h
@@ -0,0 +1,180 @@
+/**
+ * Copyright (c) 2016 - 2018 Nordic Semiconductor ASA and Luxoft Global Operations Gmbh.
+ *
+ * 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#ifndef SYS_TIME_H_INCLUDED
+#define SYS_TIME_H_INCLUDED
+
+#include <stdint.h>
+#include "sys_queue.h"
+
+/** @file
+ * This file contains declarations of the primitives to work with Time (timers) and necessary types.
+ *
+ * @defgroup sys_time Time API
+ * @ingroup sys_15_4
+ * @{
+ * @brief Module for declaring Time API.
+ * @details The system time module implements some routines to deal with time (timers). The timer can be started by
+ * sys_timer_start(), stopped by sys_timer_stop(), and adjusted after sleep by sys_timer_adjust(). Some
+ * information can be acquired by sys_timer_is_started() and sys_time_get(). The correct API for implementing hardware
+ * delays is sys_time_delay_us(). Note that the module must be initialized by sys_timers_init() which
+ * is done by sys_init().
+ */
+
+/**@brief Unsigned type of system time.
+ */
+typedef uint64_t sys_time_t;
+
+/**@brief Signed type of system time.
+ */
+typedef int64_t sys_signed_time_t;
+
+/**@brief Prototype of the user-defined timer callback.
+ *
+ * @param p_data Pointer to the data, specific for this callback.
+ */
+typedef void (* sys_timer_callback_t)(void * p_data);
+
+
+/**@brief System timer type (one-shot or periodic timer).
+ */
+typedef enum
+{
+ SYS_TIMER_ONESHOT, /**< The timer is Oneshot */
+ SYS_TIMER_PERIODIC /**< The timer is Periodic */
+} sys_timer_type_t;
+
+
+/**@brief Timer descriptor.
+ */
+typedef struct
+{
+ /** Service field. */
+ sys_queue_item_t item;
+
+ /** Service field. */
+ sys_time_t absolute_time;
+
+ /** Relevant time moment, at which this timer is programmed to be triggered,
+ * measured in microseconds.
+ */
+ sys_time_t interval;
+
+ /** Periodic or one-shot timer.
+ *
+ * @details If type is set to SYS_TIMER_PERIODIC, the timer will restart automatically
+ * with the same period.
+ */
+ sys_timer_type_t type;
+
+ /** Timer callback function.
+ *
+ * @details This function is to be called, when this timer triggers.
+ */
+ sys_timer_callback_t callback;
+
+ /** Timer callback parameter.
+ *
+ * @details This pointer is to be passed to the timer callback function.
+ */
+ void * p_data;
+} sys_timer_t;
+
+
+/**@brief Function for initializing the timers module.
+ */
+void sys_timers_init(void);
+
+
+/**@brief Function for starting the timer.
+ *
+ * @details See the description of \ref sys_timer_t fields for the details
+ * on how to program the timer.
+ *
+ * @param[in] p_timer Pointer to a valid timer descriptor, which is filled by the user,
+ * according to \ref sys_timer_t fields description.
+ */
+void sys_timer_start(sys_timer_t * p_timer);
+
+
+/**@brief Function for stopping the timer.
+ *
+ * @details This function is used to stop the timer, which was started earlier.
+ * After this function is called, the timer will not fire.
+ *
+ * @param[in] p_timer Pointer to a valid timer descriptor.
+ */
+void sys_timer_stop(sys_timer_t * p_timer);
+
+
+/**@brief Function for checking if input timer has been started.
+ *
+ * @param[in] p_timer Pointer to a timer.
+ *
+ * @retval true p_timer has been started and has not been stopped yet.
+ * @retval false p_timer has never been started or already timed out.
+ */
+bool sys_timer_is_started(sys_timer_t * p_timer);
+
+
+/**@brief Function for getting the current system time.
+ *
+ * @retval The current system timer counter value in microseconds.
+ */
+sys_time_t sys_time_get(void);
+
+
+/**@brief Function for implementing a delay for short hardware delays.
+ *
+ * @warning Interrupts are NOT disabled inside this function.
+ *
+ * @param[in] delay_us Number of microseconds to delay.
+ */
+void sys_time_delay_us(uint32_t delay_us);
+
+
+/**@brief Function for executing expired timers after sleep.
+ */
+void sys_timer_adjust(void);
+
+/** @} */
+
+#endif // SYS_TIME_H_INCLUDED
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/802_15_4/api/SysAL/sys_utils.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/802_15_4/api/SysAL/sys_utils.h
new file mode 100644
index 0000000..d577292
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/802_15_4/api/SysAL/sys_utils.h
@@ -0,0 +1,541 @@
+/**
+ * Copyright (c) 2016 - 2018 Nordic Semiconductor ASA and Luxoft Global Operations Gmbh.
+ *
+ * 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#ifndef SYS_UTILS_H_INCLUDED
+#define SYS_UTILS_H_INCLUDED
+
+#include <stdint.h>
+#include <stddef.h>
+#include <string.h>
+#if (defined(__GNUC__) && !defined(__SES_ARM))
+#include <strings.h>
+#endif
+#ifdef __MINGW32__
+#define ffs __builtin_ffs
+#endif
+
+/** @file
+ * This file contains definitions of useful macros and types.
+ *
+ * @defgroup sys_utils System Utilities API
+ * @ingroup sys_15_4
+ * @{
+ * @brief Module to declare System Utilities API.
+ * @details The System Utilities module implements multiple useful macros and inlines for the whole stack. Including
+ * this header you will get access to GET_PARENT_BY_FIELD(), FIELD_SIZE() to work with complex structures,
+ * ARRAY_SIZE() for arrays, mathematics macros like IMP(), LL_MIN(), LL_MAX(), CEIL(), ROUND(), Bitmap helpers
+ * and many others. The variable arguments support macros are also defined here. Some SWAP routines are implemented
+ * by this module as well.
+ */
+
+/**@brief Returns the pointer to the data structure
+ *
+ * @param[in] struct_type name of the parent structure
+ * @param[in] field_name name of the structure field
+ * @param[in] field_pointer pointer to the structure field
+ *
+ * @retval Pointer to the parent structure which includes the field.
+ */
+#define GET_PARENT_BY_FIELD(struct_type, field_name, field_pointer) \
+ ((struct_type*)(void*)(((uint8_t*)field_pointer) - offsetof(struct_type, field_name)))
+
+
+/**@brief Returns the implication of two given expressions x and y.
+ * @details The implication means: if X==TRUE then Y==TRUE.
+ * The formula is: (X imp Y) = ((not X) or Y)
+ */
+#define IMP(x, y) ( !(x) || (y) )
+
+
+/**@brief Returns the minimum of two given expressions x and y.
+ */
+#define LL_MIN(x, y) ( ((x) < (y)) ? (x) : (y) )
+
+
+/**@brief Returns the maximum of two given expressions x and y.
+ */
+#define LL_MAX(x, y) ( ((x) > (y)) ? (x) : (y) )
+
+
+/**@brief Returns the quotient of a divided by b rounded upwards to the nearest
+ * integer.
+ */
+#define CEIL(a, b) ((a) ? (((a) - 1U) / (b) + 1U) : 0U)
+
+
+/**@brief Returns the quotient of a divided by b rounded to the nearest integer
+ * according to the standard arithmetic rules: if the fractional part of (a/b) is greater
+ * or equal to 0.5 then the result is rounded upwards; if the fractional part of (a/b) is
+ * less then 0.5 the result is rounded downwards.
+ *
+ * @note Use this formula only for unsigned arguments. The formula is not compatible with
+ * the signed arguments: when a and b have different signs it gives incorrect result.
+ */
+#define ROUND(a, b) ( ((a) + ((b) >> 1)) / (b) )
+
+
+/**@brief Declares a long bitmap named name of size bits. The size is rounded
+ * upwards to come a multiple of 8.
+ */
+#define BITMAP_DECLARE(name, size) uint8_t name[CEIL(size, 8)]
+
+/**@brief Clears all bits in given bitmap.
+ */
+#define BITMAP_RESET(name) memset((name), 0U, sizeof(name))
+
+/**@brief Returns the value of a bit at position bit in the long bitmap named name.
+ */
+#define BITMAP_ISSET(name, bit) ( 0 != ((name)[(bit) >> 3] & (1 << ((bit) & 0x7))) )
+
+/**@brief Sets the bit at position bit in the long bitmap named name.
+ */
+#define BITMAP_SET(name, bit) (name)[(bit) >> 3] |= (1 << ((bit) & 0x7))
+
+/**@brief Clears the bit at position bit in the long bitmap named name.
+ */
+#define BITMAP_CLR(name, bit) (name)[(bit) >> 3] &= ~(1 << ((bit) & 0x7))
+
+/**@brief Assigns the given bitmap with the second bitmap.
+ */
+#define BITMAP_ASSIGN(nameDst, nameSrc) memcpy((nameDst), (nameSrc), sizeof(nameDst))
+
+/**@brief Compares two bitmaps and returns zero if they are equal.
+ */
+#define BITMAP_EQUAL(name1, name2) ((sizeof(name1) == sizeof(name2)) && \
+ (memcmp((name1), (name2), sizeof(name1)) == 0))
+
+/**@brief Checks number. Return true if number is power of two.
+ */
+#define LL_IS_POWER_OF_TWO(name) ((0 != (name)) && (0 == ((name)&(name - 1))))
+
+/**@brief Return True if mask is fully included into a given set and False otherwise
+ */
+#define IS_SUBSET_OF(mask, set) ((mask) == ((set) & (mask)))
+
+/**@brief Creates a bit mask with single set bit on the specified position.
+ */
+#define BIT(pos) (1UL << (pos))
+
+/**@brief Gets the given bit in the given value
+ */
+#define BIT_GET(val, pos) ((((uint32_t)val) & BIT(pos)) != 0)
+
+/**@brief Sets or clears the given bit in the given value
+ */
+#define BIT_SET(val, pos, bit) { \
+ if (bit) \
+ { \
+ val |= BIT(pos); \
+ } \
+ else \
+ { \
+ val &= ~BIT(pos); \
+ } \
+ }
+
+/**@brief Returns two to the income power.*/
+#define POWER2(n) (1ULL << (n))
+
+/**@brief Creates a bit mask of specified length.
+ */
+#define BIT_MASK(len) (BIT(len) - 1UL)
+
+/**@brief Creates a bit field mask of specified length and start position.
+ */
+#define BIT_FIELD_MASK(start, len) (BIT_MASK(len) << (start))
+
+/**@brief Creates a bit field mask of specified length, start position and value.
+ */
+#define BIT_FIELD_VALUE(value, start, len) (((value) & BIT_MASK(len)) << (start))
+
+/**@brief Extracts a bit field value of specified start position and length.
+ */
+#define GET_BITFIELD_VALUE(bitmask, start, len) (((bitmask) >> (start)) & BIT_MASK(len))
+
+/**@brief Inserts a bit field value with specified start position and length.
+ */
+#define SET_BITFIELD_VALUE(bitmask, start, len, value) \
+ (bitmask = (bitmask & ~BIT_FIELD_MASK(start, len)) | BIT_FIELD_VALUE(value, start, len))
+
+/**@brief Extracts a mask from a BITMAP.
+ * BITMAP MUST be aligned and mask length MUST be one of 2, 4, 8, 16, 32.
+ */
+#define BITMAP_MASK_GET(bitmap, bit, len) \
+ GET_BITFIELD_VALUE(((uint32_t*)(bitmap))[(bit) >> 5], (bit) & 0x1F, len)
+
+/**@brief Sets up a mask to a BITMAP.
+ * BITMAP MUST be aligned and mask length MUST be one of 2, 4, 8, 16, 32.
+ */
+#define BITMAP_MASK_SET(bitmap, bit, len, value) \
+ SET_BITFIELD_VALUE(((uint32_t*)(bitmap))[(bit) >> 5], (bit) & 0x1F, len, value)
+
+/**@brief Gets amount of the arguments.
+ */
+#define VA_NARGS(...) VA_NARGS_EVAL(__VA_ARGS__)
+#define VA_NARGS_EVAL(...) VA_NARGS_IMPL(__VA_ARGS__, \
+ /* 255, 254, */ 253, 252, 251, 250, 249, 248, 247, 246, 245, 244, 243, 242, 241, 240, \
+ 239, 238, 237, 236, 235, 234, 233, 232, 231, 230, 229, 228, 227, 226, 225, 224, \
+ 223, 222, 221, 220, 219, 218, 217, 216, 215, 214, 213, 212, 211, 210, 209, 208, \
+ 207, 206, 205, 204, 203, 202, 201, 200, 199, 198, 197, 196, 195, 194, 193, 192, \
+ 191, 190, 189, 188, 187, 186, 185, 184, 183, 182, 181, 180, 179, 178, 177, 176, \
+ 175, 174, 173, 172, 171, 170, 169, 168, 167, 166, 165, 164, 163, 162, 161, 160, \
+ 159, 158, 157, 156, 155, 154, 153, 152, 151, 150, 149, 148, 147, 146, 145, 144, \
+ 143, 142, 141, 140, 139, 138, 137, 136, 135, 134, 133, 132, 131, 130, 129, 128, \
+ 127, 126, 125, 124, 123, 122, 121, 120, 119, 118, 117, 116, 115, 114, 113, 112, \
+ 111, 110, 109, 108, 107, 106, 105, 104, 103, 102, 101, 100, 99, 98, 97, 96, \
+ 095, 94, 93, 92, 91, 90, 89, 88, 87, 86, 85, 84, 83, 82, 81, 80, \
+ 079, 78, 77, 76, 75, 74, 73, 72, 71, 70, 69, 68, 67, 66, 65, 64, \
+ 063, 62, 61, 60, 59, 58, 57, 56, 55, 54, 53, 52, 51, 50, 49, 48, \
+ 047, 46, 45, 44, 43, 42, 41, 40, 39, 38, 37, 36, 35, 34, 33, 32, \
+ 031, 30, 29, 28, 27, 26, 25, 24, 23, 22, 21, 20, 19, 18, 17, 16, \
+ 015, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0)
+
+/**@brief Helper macro. Gets amount of the arguments.
+ */
+#define VA_NARGS_IMPL(_________1, _2, _3, _4, _5, _6, _7, \
+ _8, _9, _10, _11, _12, _13, _14, _15, \
+ __16, _17, _18, _19, _20, _21, _22, _23, \
+ _24, _25, _26, _27, _28, _29, _30, _31, \
+ __32, _33, _34, _35, _36, _37, _38, _39, \
+ _40, _41, _42, _43, _44, _45, _46, _47, \
+ __48, _49, _50, _51, _52, _53, _54, _55, \
+ _56, _57, _58, _59, _60, _61, _62, _63, \
+ __64, _65, _66, _67, _68, _69, _70, _71, \
+ _72, _73, _74, _75, _76, _77, _78, _79, \
+ __80, _81, _82, _83, _84, _85, _86, _87, \
+ _88, _89, _90, _91, _92, _93, _94, _95, \
+ __96, _97, _98, _99, _100, _101, _102, _103, \
+ _104, _105, _106, _107, _108, _109, _110, _111, \
+ _112, _113, _114, _115, _116, _117, _118, _119, \
+ _120, _121, _122, _123, _124, _125, _126, _127, \
+ _128, _129, _130, _131, _132, _133, _134, _135, \
+ _136, _137, _138, _139, _140, _141, _142, _143, \
+ _144, _145, _146, _147, _148, _149, _150, _151, \
+ _152, _153, _154, _155, _156, _157, _158, _159, \
+ _160, _161, _162, _163, _164, _165, _166, _167, \
+ _168, _169, _170, _171, _172, _173, _174, _175, \
+ _176, _177, _178, _179, _180, _181, _182, _183, \
+ _184, _185, _186, _187, _188, _189, _190, _191, \
+ _192, _193, _194, _195, _196, _197, _198, _199, \
+ _200, _201, _202, _203, _204, _205, _206, _207, \
+ _208, _209, _210, _211, _212, _213, _214, _215, \
+ _216, _217, _218, _219, _220, _221, _222, _223, \
+ _224, _225, _226, _227, _228, _229, _230, _231, \
+ _232, _233, _234, _235, _236, _237, _238, _239, \
+ _240, _241, _242, _243, _244, _245, _246, _247, \
+ _248, _249, _250, _251, _252, _253, /* _254, _255, */\
+ N, ...) N
+
+/**@brief Gets amount of the arguments. Execute by compiler.
+ */
+#define VA_NARGS_COMPILE_TIME(...) ((uint8_t)(sizeof((uint8_t[]){ __VA_ARGS__ })/sizeof(uint8_t)))
+
+/**@brief Swaps values.
+ */
+#define SWAP_XOR(a, b) \
+ do \
+ { \
+ (((b) ^= (a) ^= (b), (a) ^= (b))); \
+ } while(0);
+
+/**@brief Compare two number and take care of overflow threshold limit.
+ */
+#define COMPARE_WITH_THRESHOLD(a, b, threshold) \
+ (((LL_MAX((a), (b)) - LL_MIN((a), (b))) < (threshold)) ? ((a) >= (b) ? 1 : 0) : ((a) > (b) ? 0 : 1))
+
+
+#define ROUND_MASK(a) ((a) - 1)
+#define ROUND_UP(x, a) (((x) + ROUND_MASK(a)) & ~ROUND_MASK(a))
+#define ROUND_DOWN(x, a) ((x) & ~ROUND_MASK(a))
+
+/**@brief Dereferences input pointer \a y as a type \a x.
+ *
+ * @param[in] x type name.
+ * @param[in] y pointer name.
+ */
+#define DEREF_VOID_PTR_AS(x, y) (*(x *)y)
+
+/**@brief Extends some bit value to the left extending 2's complement value
+ * to 8-bit length.
+ *
+ * @param[out] result variable, where result is store to.
+ * @param[in] x input value.
+ * @param[in] sign_pos an integer in range 2..6 specifying bit position of sign bit.
+ */
+#define SIGN_EXTENSION(result, x, sign_pos) \
+ do \
+ { \
+ result = x & (1 << sign_pos) ? \
+ x | (~((1 << (sign_pos + 1)) - 1)) : \
+ x & ((1 << (sign_pos + 1)) - 1); \
+ } while (0)
+
+/**@brief Clears some most significant bits of integer value reducing it precision.
+ * Name and interface of the macro emphasizes complementary action to #SIGN_EXTENSION.
+ *
+ * @param[out] result variable, where result is store to.
+ * @param[in] x input value.
+ * @param[in] sign_pos an integer in range 2..6 specifying bit position of sign bit.
+ */
+#define SIGN_COMPRESSION(result, x, sign_pos) \
+ do \
+ { \
+ result = x & ((1 << (sign_pos + 1)) - 1); \
+ } while (0)
+
+/************************* PROTOTYPES **************************************************/
+/**@brief Swaps values of two bytes.
+ *
+ */
+static inline void SWAP8(uint8_t * const x, uint8_t * const y)
+{
+ uint8_t _x = *x;
+ *x = *y;
+ *y = _x;
+}
+
+/**@brief Swaps values of two double words (DWORD).
+ *
+ */
+static inline void SWAP32(uint32_t * const x, uint32_t * const y)
+{
+ uint32_t _x = *x;
+ *x = *y;
+ *y = _x;
+}
+
+/**@brief Swaps values of two arrays.
+ *
+ * @param[inout] x array pointer
+ * @param[inout] y array pointer
+ * @param[in] length amount of bytes to swap
+ */
+static inline void SWAP_ARRAYS(void * x, void * y, uint32_t length)
+{
+ uint8_t *_x = (uint8_t *)(void *)x;
+ uint8_t *_y = (uint8_t *)(void *)y;
+ if (0x0 == ((((size_t)_x) | ((size_t)_y)) & 0x3))
+ {
+ size_t len4 = length / sizeof(uint32_t);
+ for (size_t i = 0; i < len4; i++)
+ {
+ SWAP32((uint32_t*)_x, (uint32_t*)_y);
+ _x += sizeof(uint32_t);
+ _y += sizeof(uint32_t);
+ }
+ length &= 0x3;
+ }
+
+ for (size_t i = 0; i < length; i++)
+ {
+ SWAP8(_x, _y);
+ _x++;
+ _y++;
+ }
+}
+
+
+/**@brief Find the first bit of the bitmap with the given value
+ * (one or zero, as specified).
+ *
+ * @param[in] p_bitmap Pointer to bitmap.
+ * @param[in] bitmap_size Number of bits in the bitmap.
+ * @param[in] bit_value The bit value to find (one or zero).
+ *
+ * @retval Bit position of the bit with specified value, or bitmap_size if no such bit
+ * was found.
+ */
+static inline size_t bitmap_find_bit(uint8_t * p_bitmap, size_t bitmap_size, uint8_t bit_value)
+{
+#if (defined(__GNUC__) && !defined(__SES_ARM))
+ if (bitmap_size <= 32)
+ {
+ uint32_t bitmap;
+ memcpy(&bitmap, p_bitmap, sizeof(uint32_t));
+ if (!bit_value)
+ {
+ bitmap ^= 0xFFFFFFFF;
+ }
+ size_t result = ffs(bitmap);
+ if (result == 0 || result > bitmap_size)
+ {
+ return bitmap_size;
+ }
+ // built-in ffs implementation gives ffs(1) = 1, not 0
+ return result - 1;
+ }
+ else
+#endif
+ {
+ for (size_t i = 0; i < bitmap_size; i++)
+ {
+ if (BITMAP_ISSET(p_bitmap, i) == bit_value)
+ {
+ return i;
+ }
+ }
+ return bitmap_size;
+ }
+}
+
+/**@brief Reverse the elements of array
+ *
+ * @param[in] ptr Pointer to array.
+ * @param[in] len Length of array.
+ */
+static inline void array_reverse(uint8_t * ptr, size_t len)
+{
+ for (size_t i = 0; i < len/2; i++)
+ {
+ SWAP_XOR(ptr[i], ptr[len - 1 - i]);
+ }
+}
+
+/**@brief Returns least significant byte of word.
+ */
+#define LSB_WORD(x) ((uint8_t)(x & 0xFF))
+
+/**@brief Returns least significant byte of halfword.
+ */
+#define LSB_HWORD(x) LSB_WORD(x)
+
+/**@brief Returns most significant byte of halfword.
+ */
+#define MSB_HWORD(x) ((uint8_t)(x >> 8))
+
+#define ALIGN_VALUE (sizeof(size_t))
+
+/**@brief Compiler-independent definitions.
+ */
+#if defined ( __CC_ARM )
+
+ #ifndef __WEAK
+ #define __WEAK __weak
+ #endif
+
+ #ifndef PACK
+ #define PACK __attribute__ ((packed))
+ #endif
+
+ #ifndef BEGIN_PACK
+ #define BEGIN_PACK
+ #endif
+
+ #ifndef END_PACK
+ #define END_PACK
+ #endif
+
+#ifndef __ALIGN
+ #define __ALIGN(n) __align(n)
+#endif
+
+#elif defined ( __ICCARM__ )
+
+ #ifndef __WEAK
+ #define __WEAK __weak
+ #endif
+
+ #ifndef PACK
+ #define PACK
+ #endif
+
+ #ifndef BEGIN_PACK
+ #define BEGIN_PACK _Pragma("pack(push, 1)")
+ #endif
+
+ #ifndef END_PACK
+ #define END_PACK _Pragma("pack(pop)")
+ #endif
+
+#ifndef __ALIGN
+ #define __ALIGN(n)
+#endif
+
+#elif defined ( __GNUC__ )
+
+ #ifndef __WEAK
+ #define __WEAK __attribute__((weak))
+ #endif
+
+ #ifndef PACK
+ #define PACK __attribute__ ((packed))
+ #endif
+
+ #ifndef BEGIN_PACK
+ #define BEGIN_PACK _Pragma("pack(push,1)")
+
+ #endif
+
+ #ifndef END_PACK
+ #define END_PACK _Pragma("pack(pop)")
+ #endif
+
+#ifndef __ALIGN
+ #define __ALIGN(n) __attribute__((aligned(n)))
+#endif
+
+#elif defined ( __TASKING__ )
+
+ #ifndef __WEAK
+ #define __WEAK __attribute__((weak))
+ #endif
+
+ #ifndef PACK
+ #define PACK __attribute__ ((packed))
+ #endif
+
+ #ifndef BEGIN_PACK
+ #define BEGIN_PACK
+ #endif
+
+ #ifndef END_PACK
+ #define END_PACK
+ #endif
+
+#ifndef __ALIGN
+ #define __ALIGN(n) __align(n)
+#endif
+
+#endif
+
+/** @} */
+
+#endif /* SYS_UTILS_H_INCLUDED */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/802_15_4/raw/802_15_4_config.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/802_15_4/raw/802_15_4_config.h
new file mode 100644
index 0000000..30970d1
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/802_15_4/raw/802_15_4_config.h
@@ -0,0 +1,110 @@
+/**
+ * Copyright (c) 2016 - 2018 Nordic Semiconductor ASA and Luxoft Global Operations Gmbh.
+ *
+ * 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#ifndef STACK_802_15_4_CONFIG_H__
+#define STACK_802_15_4_CONFIG_H__
+
+#define CONFIG_DEBUG 1
+#define CONFIG_MM_DEBUG 1
+#define CONFIG_TEST_CHANNEL 15
+#define CONFIG_TEST_CHANNEL_MASK (1 << CONFIG_TEST_CHANNEL)
+#define CONFIG_BEACON_ENABLED 1
+#define CONFIG_FFD_DEVICE 1
+#define CONFIG_RXE_ENABLED 1
+#define CONFIG_GTS_ENABLED 1
+#define CONFIG_SYNC_REQ_ENABLED 1
+#define CONFIG_ASSOCIATE_IND_ENABLED 1
+#define CONFIG_ORPHAN_ENABLED 1
+#define CONFIG_START_ENABLED 1
+#define CONFIG_ED_SCAN_ENABLED 1
+#define CONFIG_ACTIVE_SCAN_ENABLED 1
+#define CONFIG_PURGE_ENABLED 1
+#define CONFIG_PANID_CONFLICT_RESOLUTION_ENABLED 1
+#define CONFIG_ASSOCIATION_REQ_CMD_RX_ENABLED 1
+#define CONFIG_ASSOCIATION_REQ_CMD_TX_ENABLED 1
+#define CONFIG_ASSOCIATION_RESP_CMD_RX_ENABLED 1
+#define CONFIG_ASSOCIATION_RESP_CMD_TX_ENABLED 1
+#define CONFIG_DISASSOCIATION_NTF_CMD_RX_ENABLED 1
+#define CONFIG_DISASSOCIATION_NTF_CMD_TX_ENABLED 1
+#define CONFIG_DATA_REQ_CMD_RX_ENABLED 1
+#define CONFIG_DATA_REQ_CMD_TX_ENABLED 1
+#define CONFIG_PAN_CONFLICT_NTF_CMD_RX_ENABLED 1
+#define CONFIG_PAN_CONFLICT_NTF_CMD_TX_ENABLED 1
+#define CONFIG_ORPHAN_NTF_CMD_RX_ENABLED 1
+#define CONFIG_ORPHAN_NTF_CMD_TX_ENABLED 1
+#define CONFIG_BEACON_REQ_CMD_RX_ENABLED 1
+#define CONFIG_BEACON_REQ_CMD_TX_ENABLED 1
+#define CONFIG_COORD_REALIGN_CMD_RX_ENABLED 1
+#define CONFIG_COORD_REALIGN_CMD_TX_ENABLED 1
+#define CONFIG_GTS_REQ_CMD_RX_ENABLED 1
+#define CONFIG_GTS_REQ_CMD_TX_ENABLED 1
+#define CONFIG_INDIRECT_ENGINE_ENABLED 1
+#define CONFIG_ASSOCIATE_REQ_ENABLED 1
+#define CONFIG_DISASSOCIATE_ENABLED 1
+#define CONFIG_PANID_CONFLICT_ENABLED 1
+#define CONFIG_SYNC_ENABLED 1
+#define CONFIG_NONE_ADDR_SUPPORT_ENABLED 1
+#define CONFIG_PASSIVE_ORPHAN_SCAN_ENABLED 1
+#define CONFIG_PROMISCUOUS_MODE_ENABLED 1
+#define CONFIG_USE_SYS_TASK_NOTIFIER 1
+#define CONFIG_POOL_SIZE 0x2000
+#define CONFIG_SLAB_FRAME_POOL_SIZE 4
+#define CONFIG_MEMORY_POLLING_INTERVAL_MS 10
+#define CONFIG_MAX_SLEEP_APPROVERS 32
+#define CONFIG_HAL_UART_CHANNELS 1
+#define CONFIG_MAC_KEY_TABLE_SIZE 8
+#define CONFIG_MAC_DEVICE_TABLE_SIZE 8
+#define CONFIG_MAC_SECURITY_LEVEL_TABLE_SIZE 8
+#define CONFIG_MAC_KEY_ID_LOOKUP_LIST_SIZE 8
+#define CONFIG_MAC_KEY_DEVICE_LIST_SIZE 8
+#define CONFIG_MAC_KEY_USAGE_LIST_SIZE 8
+#define CONFIG_IEEE_ADDRESS 0x0123456789ABCDEFULL
+#define CONFIG_BEACON_RX_TIME 5000
+#define CONFIG_TEST_SUBTREE_MAC 1
+#define CONFIG_TEST_SUBTREE_TST 1
+#define CONFIG_COAP_TICK_INTERVAL_US 500000
+#define CONFIG_COAP_MM_SMALL_BLOCK_COUNT 32
+#define CONFIG_COAP_MM_MEDIUM_BLOCK_COUNT 32
+#define CONFIG_COAP_MM_LARGE_BLOCK_COUNT 32
+#define CONFIG_COAP_MESSAGE_QUEUE_SIZE 32
+
+#endif // STACK_802_15_4_CONFIG_H__
+
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/802_15_4/raw/802_15_4_lib_gcc.a b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/802_15_4/raw/802_15_4_lib_gcc.a
new file mode 100644
index 0000000..9198fa1
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/802_15_4/raw/802_15_4_lib_gcc.a
Binary files differ
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/802_15_4/raw/802_15_4_lib_iar.a b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/802_15_4/raw/802_15_4_lib_iar.a
new file mode 100644
index 0000000..91be285
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/802_15_4/raw/802_15_4_lib_iar.a
Binary files differ
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/802_15_4/raw/802_15_4_lib_keil.lib b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/802_15_4/raw/802_15_4_lib_keil.lib
new file mode 100644
index 0000000..6d42628
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/802_15_4/raw/802_15_4_lib_keil.lib
Binary files differ
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/802_15_4/raw/license.txt b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/802_15_4/raw/license.txt
new file mode 100644
index 0000000..eb796cd
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/802_15_4/raw/license.txt
@@ -0,0 +1,38 @@
+Copyright (c) 2016 - 2018 Nordic Semiconductor ASA and Luxoft Global Operations Gmbh.
+
+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, except as embedded into a Nordic
+ Semiconductor ASA integrated circuit in a product or a software update for
+ such product, 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.
+
+4. This software, with or without modification, must only be used with a
+ Nordic Semiconductor ASA integrated circuit.
+
+5. Any software provided in binary form under this license must not be reverse
+ engineered, decompiled, modified and/or disassembled.
+
+
+THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/802_15_4/secure/802_15_4_config.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/802_15_4/secure/802_15_4_config.h
new file mode 100644
index 0000000..0842164
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/802_15_4/secure/802_15_4_config.h
@@ -0,0 +1,111 @@
+/**
+ * Copyright (c) 2016 - 2018 Nordic Semiconductor ASA and Luxoft Global Operations Gmbh.
+ *
+ * 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#ifndef STACK_802_15_4_CONFIG_H__
+#define STACK_802_15_4_CONFIG_H__
+
+#define CONFIG_DEBUG 1
+#define CONFIG_MM_DEBUG 1
+#define CONFIG_TEST_CHANNEL 15
+#define CONFIG_TEST_CHANNEL_MASK (1 << CONFIG_TEST_CHANNEL)
+#define CONFIG_BEACON_ENABLED 1
+#define CONFIG_SECURE 1
+#define CONFIG_FFD_DEVICE 1
+#define CONFIG_RXE_ENABLED 1
+#define CONFIG_GTS_ENABLED 1
+#define CONFIG_SYNC_REQ_ENABLED 1
+#define CONFIG_ASSOCIATE_IND_ENABLED 1
+#define CONFIG_ORPHAN_ENABLED 1
+#define CONFIG_START_ENABLED 1
+#define CONFIG_ED_SCAN_ENABLED 1
+#define CONFIG_ACTIVE_SCAN_ENABLED 1
+#define CONFIG_PURGE_ENABLED 1
+#define CONFIG_PANID_CONFLICT_RESOLUTION_ENABLED 1
+#define CONFIG_ASSOCIATION_REQ_CMD_RX_ENABLED 1
+#define CONFIG_ASSOCIATION_REQ_CMD_TX_ENABLED 1
+#define CONFIG_ASSOCIATION_RESP_CMD_RX_ENABLED 1
+#define CONFIG_ASSOCIATION_RESP_CMD_TX_ENABLED 1
+#define CONFIG_DISASSOCIATION_NTF_CMD_RX_ENABLED 1
+#define CONFIG_DISASSOCIATION_NTF_CMD_TX_ENABLED 1
+#define CONFIG_DATA_REQ_CMD_RX_ENABLED 1
+#define CONFIG_DATA_REQ_CMD_TX_ENABLED 1
+#define CONFIG_PAN_CONFLICT_NTF_CMD_RX_ENABLED 1
+#define CONFIG_PAN_CONFLICT_NTF_CMD_TX_ENABLED 1
+#define CONFIG_ORPHAN_NTF_CMD_RX_ENABLED 1
+#define CONFIG_ORPHAN_NTF_CMD_TX_ENABLED 1
+#define CONFIG_BEACON_REQ_CMD_RX_ENABLED 1
+#define CONFIG_BEACON_REQ_CMD_TX_ENABLED 1
+#define CONFIG_COORD_REALIGN_CMD_RX_ENABLED 1
+#define CONFIG_COORD_REALIGN_CMD_TX_ENABLED 1
+#define CONFIG_GTS_REQ_CMD_RX_ENABLED 1
+#define CONFIG_GTS_REQ_CMD_TX_ENABLED 1
+#define CONFIG_INDIRECT_ENGINE_ENABLED 1
+#define CONFIG_ASSOCIATE_REQ_ENABLED 1
+#define CONFIG_DISASSOCIATE_ENABLED 1
+#define CONFIG_PANID_CONFLICT_ENABLED 1
+#define CONFIG_SYNC_ENABLED 1
+#define CONFIG_NONE_ADDR_SUPPORT_ENABLED 1
+#define CONFIG_PASSIVE_ORPHAN_SCAN_ENABLED 1
+#define CONFIG_PROMISCUOUS_MODE_ENABLED 1
+#define CONFIG_USE_SYS_TASK_NOTIFIER 1
+#define CONFIG_POOL_SIZE 0x2000
+#define CONFIG_SLAB_FRAME_POOL_SIZE 4
+#define CONFIG_MEMORY_POLLING_INTERVAL_MS 10
+#define CONFIG_MAX_SLEEP_APPROVERS 32
+#define CONFIG_HAL_UART_CHANNELS 1
+#define CONFIG_MAC_KEY_TABLE_SIZE 8
+#define CONFIG_MAC_DEVICE_TABLE_SIZE 8
+#define CONFIG_MAC_SECURITY_LEVEL_TABLE_SIZE 8
+#define CONFIG_MAC_KEY_ID_LOOKUP_LIST_SIZE 8
+#define CONFIG_MAC_KEY_DEVICE_LIST_SIZE 8
+#define CONFIG_MAC_KEY_USAGE_LIST_SIZE 8
+#define CONFIG_IEEE_ADDRESS 0x0123456789ABCDEFULL
+#define CONFIG_BEACON_RX_TIME 5000
+#define CONFIG_TEST_SUBTREE_MAC 1
+#define CONFIG_TEST_SUBTREE_TST 1
+#define CONFIG_COAP_TICK_INTERVAL_US 500000
+#define CONFIG_COAP_MM_SMALL_BLOCK_COUNT 32
+#define CONFIG_COAP_MM_MEDIUM_BLOCK_COUNT 32
+#define CONFIG_COAP_MM_LARGE_BLOCK_COUNT 32
+#define CONFIG_COAP_MESSAGE_QUEUE_SIZE 32
+
+#endif // STACK_802_15_4_CONFIG_H__
+
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/802_15_4/secure/802_15_4_lib_gcc.a b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/802_15_4/secure/802_15_4_lib_gcc.a
new file mode 100644
index 0000000..1ec48c5
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/802_15_4/secure/802_15_4_lib_gcc.a
Binary files differ
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/802_15_4/secure/802_15_4_lib_iar.a b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/802_15_4/secure/802_15_4_lib_iar.a
new file mode 100644
index 0000000..adb29cd
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/802_15_4/secure/802_15_4_lib_iar.a
Binary files differ
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/802_15_4/secure/802_15_4_lib_keil.lib b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/802_15_4/secure/802_15_4_lib_keil.lib
new file mode 100644
index 0000000..11f135a
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/802_15_4/secure/802_15_4_lib_keil.lib
Binary files differ
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/802_15_4/secure/license.txt b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/802_15_4/secure/license.txt
new file mode 100644
index 0000000..eb796cd
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/802_15_4/secure/license.txt
@@ -0,0 +1,38 @@
+Copyright (c) 2016 - 2018 Nordic Semiconductor ASA and Luxoft Global Operations Gmbh.
+
+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, except as embedded into a Nordic
+ Semiconductor ASA integrated circuit in a product or a software update for
+ such product, 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.
+
+4. This software, with or without modification, must only be used with a
+ Nordic Semiconductor ASA integrated circuit.
+
+5. Any software provided in binary form under this license must not be reverse
+ engineered, decompiled, modified and/or disassembled.
+
+
+THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/802_15_4/src/rng_entity.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/802_15_4/src/rng_entity.c
new file mode 100644
index 0000000..394069c
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/802_15_4/src/rng_entity.c
@@ -0,0 +1,66 @@
+/**
+ * Copyright (c) 2016 - 2018 Nordic Semiconductor ASA and Luxoft Global Operations Gmbh.
+ *
+ * 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#include <stdbool.h>
+#include "nrf_rng.h"
+#include "hal_rng.h"
+#include "sys_utils.h"
+
+/**@brief Initialize hardware random generator.
+ */
+void hal_rand_init(void)
+{
+ /** For future use */
+}
+
+/**@brief Generates random number using hardware.
+ *
+ * @details The process takes about 150 us.*/
+uint8_t hal_rand_get(void)
+{
+ nrf_rng_task_trigger(NRF_RNG_TASK_START);
+ while(!nrf_rng_event_get(NRF_RNG_EVENT_VALRDY));
+ nrf_rng_task_trigger(NRF_RNG_TASK_STOP);
+ nrf_rng_event_clear(NRF_RNG_EVENT_VALRDY);
+
+ return nrf_rng_random_value_get();
+}
+
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/802_15_4/src/sec_aes_entity.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/802_15_4/src/sec_aes_entity.c
new file mode 100644
index 0000000..2924251
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/802_15_4/src/sec_aes_entity.c
@@ -0,0 +1,62 @@
+/**
+ * Copyright (c) 2016 - 2018 Nordic Semiconductor ASA and Luxoft Global Operations Gmbh.
+ *
+ * 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#include <stdbool.h>
+#include "nrf_ecb.h"
+#include "sec_aes_entity.h"
+#include "sec_aes_ccm.h"
+#include "sys_debug.h"
+#include "sys_utils.h"
+
+void aes_entity_init(void)
+{
+ bool is_successful = nrf_ecb_init();
+ ASSERT(is_successful);
+ (void)is_successful;
+}
+
+void aes_handle(uint8_t * key, uint8_t * text)
+{
+ nrf_ecb_set_key(key);
+ bool is_successful = nrf_ecb_crypt(text, text);
+ ASSERT(is_successful);
+ (void)is_successful;
+}
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ant/ant_channel_config/ant_channel_config.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ant/ant_channel_config/ant_channel_config.c
new file mode 100644
index 0000000..41c2a5c
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ant/ant_channel_config/ant_channel_config.c
@@ -0,0 +1,86 @@
+/**
+ * Copyright (c) 2015 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#include "sdk_common.h"
+#if NRF_MODULE_ENABLED(ANT_CHANNEL_CONFIG)
+#include "nrf_error.h"
+#include "ant_channel_config.h"
+#include "ant_interface.h"
+#include "ant_parameters.h"
+
+uint32_t ant_channel_init(ant_channel_config_t const * p_config)
+{
+ uint32_t err_code;
+ // Set Channel Number.
+ err_code = sd_ant_channel_assign(p_config->channel_number,
+ p_config->channel_type,
+ p_config->network_number,
+ p_config->ext_assign);
+
+ VERIFY_SUCCESS(err_code);
+
+ // Set Channel ID.
+ err_code = sd_ant_channel_id_set(p_config->channel_number,
+ p_config->device_number,
+ p_config->device_type,
+ p_config->transmission_type);
+
+ VERIFY_SUCCESS(err_code);
+
+ // Set Channel RF frequency.
+ err_code = sd_ant_channel_radio_freq_set(p_config->channel_number, p_config->rf_freq);
+ VERIFY_SUCCESS(err_code);
+
+ // Set Channel period.
+ if (!(p_config->ext_assign & EXT_PARAM_ALWAYS_SEARCH) && (p_config->channel_period != 0))
+ {
+ err_code = sd_ant_channel_period_set(p_config->channel_number, p_config->channel_period);
+ }
+
+
+#if NRF_SDH_ANT_ENCRYPTED_CHANNELS > 0
+ VERIFY_SUCCESS(err_code);
+
+ err_code = ant_channel_encrypt_config(p_config->channel_type , p_config->channel_number, p_config->p_crypto_settings);
+#endif
+
+ return err_code;
+}
+
+#endif // NRF_MODULE_ENABLED(ANT_CHANNEL_CONFIG)
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ant/ant_channel_config/ant_channel_config.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ant/ant_channel_config/ant_channel_config.h
new file mode 100644
index 0000000..fea25c8
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ant/ant_channel_config/ant_channel_config.h
@@ -0,0 +1,98 @@
+/**
+ * Copyright (c) 2015 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#ifndef ANT_CHANNEL_CONFIG_H__
+#define ANT_CHANNEL_CONFIG_H__
+
+/** @file
+ *
+ * @defgroup ant_channel_config ANT channel configuration
+ * @{
+ * @ingroup ant_sdk_utils
+ * @brief ANT channel configuration module.
+ */
+
+#include <stdint.h>
+#include "sdk_config.h"
+
+
+#ifndef NRF_SDH_ANT_ENCRYPTED_CHANNELS
+ #error Undefined NRF_SDH_ANT_ENCRYPTED_CHANNELS. It should be defined in sdk_config.h file.
+#elif NRF_SDH_ANT_ENCRYPTED_CHANNELS > 0
+ #include "ant_encrypt_config.h"
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**@brief ANT channel configuration structure. */
+typedef struct
+{
+ uint8_t channel_number; ///< Assigned channel number.
+ uint8_t channel_type; ///< Channel type (see Assign Channel Parameters in ant_parameters.h: @ref ant_parameters).
+ uint8_t ext_assign; ///< Extended assign (see Ext. Assign Channel Parameters in ant_parameters.h: @ref ant_parameters).
+ uint8_t rf_freq; ///< Radio frequency offset from 2400 MHz (for example, 2466 MHz, rf_freq = 66).
+ uint8_t transmission_type; ///< Transmission type.
+ uint8_t device_type; ///< Device type.
+ uint16_t device_number; ///< Device number.
+ uint16_t channel_period; ///< The period in 32 kHz counts.
+ uint8_t network_number; ///< Network number denoting the network key.
+
+#if NRF_SDH_ANT_ENCRYPTED_CHANNELS > 0
+ ant_encrypt_channel_settings_t * p_crypto_settings; ///< Pointer to cryptographic settings, NULL if this configuration have to be omitted.
+#endif
+
+} ant_channel_config_t;
+
+/**@brief Function for configuring the ANT channel.
+ *
+ * @param[in] p_config Pointer to the channel configuration structure.
+ *
+ * @retval NRF_SUCCESS If the channel was successfully configured. Otherwise, an error code is returned.
+ */
+uint32_t ant_channel_init(ant_channel_config_t const * p_config);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // ANT_CHANNEL_CONFIG_H__
+/** @} */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ant/ant_encryption/ant_encrypt_config.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ant/ant_encryption/ant_encrypt_config.c
new file mode 100644
index 0000000..45e5614
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ant/ant_encryption/ant_encrypt_config.c
@@ -0,0 +1,245 @@
+/**
+ * Copyright (c) 2015 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#include "sdk_common.h"
+#if NRF_MODULE_ENABLED(ANT_ENCRYPT_CONFIG)
+#include <stdlib.h>
+#include "ant_encrypt_config.h"
+#include "ant_interface.h"
+#include "ant_parameters.h"
+
+#ifdef ANT_ENCRYPT_NEGOTIATION_SLAVE_ENABLED
+ #include "ant_encrypt_negotiation_slave.h"
+#endif
+
+ /*lint -e551 -save*/
+/** Flag for checking if stack was configured for encryption. */
+static bool m_stack_encryption_configured = false;
+ /*lint -restore */
+
+ /** Pointer to handler of module's events. */
+static ant_encryp_user_handler_t m_ant_enc_evt_handler = NULL;
+
+static ret_code_t ant_enc_advance_burs_config_apply(
+ ant_encrypt_adv_burst_settings_t const * const p_adv_burst_set);
+
+ret_code_t ant_stack_encryption_config(ant_encrypt_stack_settings_t const * const p_crypto_set)
+{
+ ret_code_t err_code;
+
+ for ( uint32_t i = 0; i < p_crypto_set->key_number; i++)
+ {
+ err_code = sd_ant_crypto_key_set(i, p_crypto_set->pp_key[i]);
+ VERIFY_SUCCESS(err_code);
+ }
+
+ if (p_crypto_set->p_adv_burst_config != NULL)
+ {
+ err_code = ant_enc_advance_burs_config_apply(p_crypto_set->p_adv_burst_config);
+ VERIFY_SUCCESS(err_code);
+ }
+
+ // subcomands LUT for @ref sd_ant_crypto_info_set calls
+ const uint8_t set_enc_info_param_lut[] =
+ {
+ ENCRYPTION_INFO_SET_CRYPTO_ID,
+ ENCRYPTION_INFO_SET_CUSTOM_USER_DATA,
+ ENCRYPTION_INFO_SET_RNG_SEED
+ };
+
+ for ( uint32_t i = 0; i < sizeof(set_enc_info_param_lut); i++)
+ {
+ if ( p_crypto_set->info.pp_array[i] != NULL)
+ {
+ err_code = sd_ant_crypto_info_set(set_enc_info_param_lut[i],
+ p_crypto_set->info.pp_array[i]);
+
+ VERIFY_SUCCESS(err_code);
+ }
+ }
+
+ #ifdef ANT_ENCRYPT_NEGOTIATION_SLAVE_ENABLED
+ // all ANT channels have unsupported slave encryption tracking (even master's channel)
+ ant_channel_encryp_negotiation_slave_init();
+ #endif
+
+ m_ant_enc_evt_handler = NULL;
+
+ m_stack_encryption_configured = true;
+
+ return NRF_SUCCESS;
+}
+
+
+/**
+ * @brief Function for configuring advanced burst settings according to encryption requirements.
+ *
+ * @param p_adv_burst_set Pointer to ANT advanced burst settings.
+ *
+ * @retval Value returned by @ref sd_ant_adv_burst_config_set.
+ */
+static ret_code_t ant_enc_advance_burs_config_apply(
+ ant_encrypt_adv_burst_settings_t const * const p_adv_burst_set)
+{
+ uint8_t adv_burst_conf_str[ADV_BURST_CFG_MIN_SIZE] =
+ { ADV_BURST_MODE_ENABLE, 0, 0, 0, 0, 0, 0, 0 };
+
+ adv_burst_conf_str[ADV_BURST_CFG_PACKET_SIZE_INDEX] = p_adv_burst_set->packet_length;
+ adv_burst_conf_str[ADV_BURST_CFG_REQUIRED_FEATURES] = p_adv_burst_set->required_feature;
+ adv_burst_conf_str[ADV_BURST_CFG_OPTIONAL_FEATURES] = p_adv_burst_set->optional_feature;
+
+ return sd_ant_adv_burst_config_set(adv_burst_conf_str, sizeof(adv_burst_conf_str));
+}
+
+
+ret_code_t ant_channel_encrypt_config_perform(uint8_t channel_number,
+ ant_encrypt_channel_settings_t * p_crypto_config)
+{
+ return sd_ant_crypto_channel_enable(channel_number,
+ p_crypto_config->mode,
+ p_crypto_config->key_index,
+ p_crypto_config->decimation_rate);
+}
+
+
+ret_code_t ant_channel_encrypt_config(uint8_t channel_type,
+ uint8_t channel_number,
+ ant_encrypt_channel_settings_t * p_crypto_config)
+{
+ ret_code_t err_code;
+
+ if (p_crypto_config != NULL)
+ {
+ // encryption of the stack should be initialized previously
+ if (m_stack_encryption_configured == false)
+ {
+ return NRF_ERROR_MODULE_NOT_INITIALIZED;
+ }
+
+ switch (channel_type)
+ {
+ case CHANNEL_TYPE_MASTER:
+ err_code = ant_channel_encrypt_config_perform(channel_number, p_crypto_config);
+#ifdef ANT_ENCRYPT_NEGOTIATION_SLAVE_ENABLED
+ ant_channel_encryp_tracking_state_set(channel_number,
+ ANT_ENC_CHANNEL_STAT_TRACKING_UNSUPPORTED);
+#endif
+ break;
+
+#ifdef ANT_ENCRYPT_NEGOTIATION_SLAVE_ENABLED
+ case CHANNEL_TYPE_SLAVE:
+ ant_slave_channel_encrypt_config(channel_number, p_crypto_config);
+
+ if (p_crypto_config->mode == ENCRYPTION_DISABLED_MODE)
+ {
+ err_code = ant_channel_encrypt_config_perform(channel_number, p_crypto_config);
+ ant_channel_encryp_tracking_state_set(channel_number,
+ ANT_ENC_CHANNEL_STAT_TRACKING_UNSUPPORTED);
+ }
+ else
+ {
+ ant_channel_encryp_tracking_state_set(channel_number,
+ ANT_ENC_CHANNEL_STAT_NOT_TRACKING);
+ err_code = NRF_SUCCESS;
+ }
+ break;
+#endif
+
+ default:
+ err_code = NRF_ERROR_INVALID_PARAM;
+ break;
+ }
+ }
+ else
+ {
+#ifdef ANT_ENCRYPT_NEGOTIATION_SLAVE_ENABLED
+ ant_channel_encryp_tracking_state_set(channel_number,
+ ANT_ENC_CHANNEL_STAT_TRACKING_UNSUPPORTED);
+#endif
+ err_code = NRF_SUCCESS;
+ }
+
+ return err_code;
+}
+
+/** @brief Function for calling the handler of module events.*/
+static void ant_encrypt_user_handler_try_to_run(uint8_t ant_channel, ant_encrypt_user_evt_t event)
+{
+ if (m_ant_enc_evt_handler != NULL)
+ {
+ m_ant_enc_evt_handler(ant_channel, event);
+ }
+}
+
+/**@brief Function for handling an ANT stack event.
+ * @param[in] p_ant_evt ANT stack event.
+ * @param[in] p_context Context.
+ */
+static void ant_evt_handler(ant_evt_t * p_ant_evt, void * p_context)
+{
+ uint8_t const ant_channel = p_ant_evt->channel;
+
+#ifdef ANT_ENCRYPT_NEGOTIATION_SLAVE_ENABLED
+ ant_slave_encrypt_negotiation(p_ant_evt);
+#endif
+
+ switch (p_ant_evt->event)
+ {
+ case EVENT_RX_FAIL_GO_TO_SEARCH:
+ ant_encrypt_user_handler_try_to_run(ant_channel, ANT_ENC_EVT_CHANNEL_LOST);
+ break;
+
+ case EVENT_ENCRYPT_NEGOTIATION_SUCCESS:
+ ant_encrypt_user_handler_try_to_run(ant_channel, ANT_ENC_EVT_NEGOTIATION_SUCCESS);
+ break;
+
+ case EVENT_ENCRYPT_NEGOTIATION_FAIL:
+ ant_encrypt_user_handler_try_to_run(ant_channel, ANT_ENC_EVT_NEGOTIATION_FAIL);
+ break;
+ }
+}
+
+NRF_SDH_ANT_OBSERVER(m_ant_observer, ANT_ENCRYPT_ANT_OBSERVER_PRIO, ant_evt_handler, NULL);
+
+void ant_enc_event_handler_register(ant_encryp_user_handler_t user_handler_func)
+{
+ m_ant_enc_evt_handler = user_handler_func;
+}
+
+#endif // NRF_MODULE_ENABLED(ANT_ENCRYPT_CONFIG)
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ant/ant_encryption/ant_encrypt_config.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ant/ant_encryption/ant_encrypt_config.h
new file mode 100644
index 0000000..53f0a8f
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ant/ant_encryption/ant_encrypt_config.h
@@ -0,0 +1,241 @@
+/**
+ * Copyright (c) 2015 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#ifndef ANT_ENCRYPT_CONFIG__
+#define ANT_ENCRYPT_CONFIG__
+
+/**@file
+ *
+ * @defgroup ant_encrypt_config ANT encryption configuration
+ * @{
+ * @ingroup ant_sdk_utils
+ *
+ * @brief Encryption configuration for the ANT stack and channels.
+ *
+ */
+
+#include <stdint.h>
+
+#include "sdk_errors.h"
+#include "nrf_sdh_ant.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** @name Advanced burst configuration for encryption modules
+ * @{
+ */
+#define ADV_BURST_CFG_MIN_SIZE 8 ///< Minimum size of the advance burst configuration data.
+#define ADV_BURST_CFG_PACKET_SIZE_INDEX 1 ///< Index of the packet size field in the configuration data.
+#define ADV_BURST_CFG_REQUIRED_FEATURES 2 ///< Index of the required features field in the configuration data.
+#define ADV_BURST_CFG_OPTIONAL_FEATURES 5 ///< Index of the optional features field in the configuration data.
+/**@} */
+
+/** @brief ANT channel cryptographic configuration. */
+typedef struct
+{
+ uint8_t mode; ///< Encryption mode. See the encrypted channel defines in ant_parameters.h.
+ uint8_t key_index; ///< Index of encryption key.
+ uint8_t decimation_rate; ///< Division of the master channel rate by the slave’s tracking channel rate.
+} ant_encrypt_channel_settings_t;
+
+/** @brief ANT encryption information. */
+typedef union
+{
+ uint8_t * pp_array[3]; // For array access support.
+ struct
+ {
+ uint8_t * p_encryption_id; ///< Pointer to the encryption ID of the device (4 bytes).
+ uint8_t * p_user_info; ///< Pointer to the user information string (19 bytes).
+ uint8_t * p_random_num_seed; ///< Pointer to the random number seed (16 bytes).
+ } items;
+} ant_encrypt_info_settings_t;
+
+/** @brief Advanced burst settings used by the encrypted channel. */
+typedef struct
+{
+ uint8_t packet_length; ///< RF payload size. See the advanced burst configuration defines in ant_parameters.h.
+ uint8_t required_feature; ///< Required advanced burst modes. See the advanced burst configuration defines in ant_parameters.h.
+ uint8_t optional_feature; ///< Optional advanced burst modes. See the advanced burst configuration defines in ant_parameters.h.
+} ant_encrypt_adv_burst_settings_t;
+
+/**@brief ANT stack cryptographic configuration. */
+typedef struct
+{
+ ant_encrypt_info_settings_t info; ///< Pointer to the encryption information structure.
+ uint8_t * * pp_key; ///< Pointer to an array for pointers to encryption keys. Each key must have a length of 16 bytes.
+ uint8_t key_number; ///< Number of encryption keys.
+ ant_encrypt_adv_burst_settings_t * p_adv_burst_config; ///< Advanced burst configuration. If NULL, the advanced burst must be configured externally.
+} ant_encrypt_stack_settings_t;
+
+/**
+ * @brief ANT encryption negotiation events.
+ */
+typedef enum
+{
+ ANT_ENC_EVT_NEGOTIATION_SUCCESS, ///< Negotiation success.
+ ANT_ENC_EVT_NEGOTIATION_FAIL, ///< Negotiation failure.
+ ANT_ENC_EVT_CHANNEL_LOST ///< Lost a channel. It's relevant only for slave channels.
+} ant_encrypt_user_evt_t;
+
+/**
+ * @brief Event handler for ANT encryption user events.
+ */
+typedef void (* ant_encryp_user_handler_t)(uint8_t channel, ant_encrypt_user_evt_t event);
+
+/**
+ * @brief Macro for initializing an ANT encryption information structure.
+ *
+ * @param[in] P_ENC_ID Pointer to the encryption ID of the device (4 bytes).
+ * @param[in] P_USER_INFO Pointer to the user information string (19 bytes).
+ * @param[in] P_RAND_NUM_SEED Pointer to the random number seed (16 bytes).
+ */
+#define ANT_CRYPTO_INFO_SETTINGS_INIT(P_ENC_ID, P_USER_INFO, P_RAND_NUM_SEED) \
+ { \
+ .items = \
+ { \
+ .p_encryption_id = P_ENC_ID, \
+ .p_user_info = P_USER_INFO, \
+ .p_random_num_seed = P_RAND_NUM_SEED \
+ } \
+ }
+
+/**
+ * @brief Macro for declaring the basic cryptographic configuration for the ANT stack.
+ *
+ * This macro configures the following settings:
+ * - Cryptographic key
+ * - Encryption ID
+ * - Advanced burst mode with the maximum RF payload size
+ *
+ * Use @ref ANT_ENCRYPT_STACK_SETTINGS_BASE to access the created configuration instance.
+ *
+ * @param[in] NAME Name for the created data instance.
+ * @param[in] P_KEY Pointer to the cryptographic key (16 bytes).
+ * @param[in] P_ENC_ID Pointer to the encryption ID (4 bytes).
+ */
+#define ANT_ENCRYPT_STACK_SETTINGS_BASE_DEF(NAME, P_KEY, P_ENC_ID) \
+ ant_encrypt_adv_burst_settings_t NAME##_ant_enc_adv_burst_set = \
+ { \
+ .packet_length = ADV_BURST_MODES_MAX_SIZE, \
+ .required_feature = 0, \
+ .optional_feature = 0 \
+ }; \
+ uint8_t * pp_##NAME##_key[1] = {P_KEY}; \
+ ant_encrypt_stack_settings_t NAME ## _ant_crypto_settings = \
+ { \
+ .info = ANT_CRYPTO_INFO_SETTINGS_INIT(P_ENC_ID, NULL, NULL), \
+ .pp_key = pp_##NAME##_key, \
+ .key_number = 1, \
+ .p_adv_burst_config = &NAME##_ant_enc_adv_burst_set \
+ }
+
+
+/** @brief Macro for accessing the configuration instance created
+ * by @ref ANT_ENCRYPT_STACK_SETTINGS_BASE_DEF.
+ *
+ * @param[in] NAME Name of the settings instance.
+ */
+#define ANT_ENCRYPT_STACK_SETTINGS_BASE(NAME) (NAME##_ant_crypto_settings)
+
+/**
+ * @brief Function for applying an encryption configuration to a slave channel.
+ *
+ * This function enables encryption on a channel.
+ *
+ * This function should be used by the @ref ant_encrypt_negotiation_slave module and this module.
+ *
+ * @param[in] channel_number ANT channel number.
+ * @param[in] p_crypto_config Pointer to the encryption configuration.
+ *
+ * @return Value returned by @ref sd_ant_crypto_channel_enable (for example, NRF_SUCCESS if
+ * the configuration was successful).
+ */
+ret_code_t ant_channel_encrypt_config_perform(uint8_t channel_number,
+ ant_encrypt_channel_settings_t * p_crypto_config);
+
+/**
+ * @brief Function for applying an encryption configuration to a master or slave channel.
+ *
+ * When called for a master channel, this function enables encryption
+ * for that channel. When called for a slave channel, it saves
+ * the encryption configuration for future use.
+ *
+ * This function should be used by the @ref ant_channel_config module.
+ *
+ * @param[in] channel_type ANT channel type: CHANNEL_TYPE_SLAVE or CHANNEL_TYPE_MASTER.
+ * @param[in] channel_num ANT channel number.
+ * @param[in] p_crypto_config Pointer to the encryption configuration.
+ *
+ * @retval NRF_SUCCESS If the function completed successfully.
+ * @retval NRF_ERROR_INVALID_PARAM If the channel type is invalid.
+ * @retval NRF_ERROR_MODULE_NOT_INITIALIZED If the stack is not configured for encryption.
+ * @retval Other Otherwise, the error value returned by the @ref
+ * ant_channel_encrypt_config_perform function is returned.
+ */
+ret_code_t ant_channel_encrypt_config(uint8_t channel_type,
+ uint8_t channel_num,
+ ant_encrypt_channel_settings_t * p_crypto_config);
+
+/**
+ * @brief Function for configuring the cryptographic settings of the ANT stack.
+ *
+ * @param[in] p_crypto_info_set Pointer to the settings.
+ */
+ret_code_t ant_stack_encryption_config(ant_encrypt_stack_settings_t const * const p_crypto_info_set);
+
+/**
+ * @brief Function for registering an event handler for ANT encryption events.
+ *
+ * The event handler should support all of the events in @ref ant_encrypt_user_evt_t.
+ *
+ * @param[in] p_handler Pointer to a handler function.
+ */
+void ant_enc_event_handler_register(ant_encryp_user_handler_t p_handler);
+
+/**
+ * @}
+ */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // ANT_ENCRYPT_CONFIG__
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ant/ant_encryption/ant_encrypt_negotiation_slave.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ant/ant_encryption/ant_encrypt_negotiation_slave.c
new file mode 100644
index 0000000..715fe14
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ant/ant_encryption/ant_encrypt_negotiation_slave.c
@@ -0,0 +1,185 @@
+/**
+ * Copyright (c) 2015 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#include "sdk_common.h"
+#if NRF_MODULE_ENABLED(ANT_ENCRYPT_NEGOTIATION_SLAVE)
+#include <stdlib.h>
+#include <string.h>
+#include "ant_encrypt_config.h"
+#include "ant_interface.h"
+#include "ant_parameters.h"
+#include "nrf_error.h"
+#include "app_error.h"
+
+#include "ant_encrypt_negotiation_slave.h"
+
+/** Number of supported channels. */
+#define NUMBER_OF_CHANNELS (NRF_SDH_ANT_TOTAL_CHANNELS_ALLOCATED)
+
+/** Flag to block other channels from attempting to enable encryption while
+ * another encryption is in the process.
+ */
+static volatile bool m_can_enable_crypto = true;
+
+/** Array to keep track of which channels are currently tracking. */
+static ant_encrypt_tracking_state_t m_encrypt_channel_states[NUMBER_OF_CHANNELS];
+
+/** Array for the slave channels' encryption settings. */
+static ant_encrypt_channel_settings_t m_slave_channel_conf[MAX_ANT_CHANNELS];
+
+
+
+void ant_channel_encryp_tracking_state_set(uint8_t channel_number,
+ ant_encrypt_tracking_state_t state)
+{
+ m_encrypt_channel_states[channel_number] = state;
+}
+
+
+void ant_channel_encryp_negotiation_slave_init(void)
+{
+ for (uint32_t channel = 0; channel < NUMBER_OF_CHANNELS; channel++)
+ {
+ ant_channel_encryp_tracking_state_set(channel, ANT_ENC_CHANNEL_STAT_TRACKING_UNSUPPORTED);
+ }
+
+ m_can_enable_crypto = true;
+}
+
+
+ant_encrypt_tracking_state_t ant_channel_encryp_tracking_state_get(uint8_t channel_number)
+{
+ return m_encrypt_channel_states[channel_number];
+}
+
+
+void ant_slave_channel_encrypt_config(uint8_t channel_number,
+ ant_encrypt_channel_settings_t const * const p_crypto_config)
+{
+ memcpy(&m_slave_channel_conf[channel_number], p_crypto_config,
+ sizeof(ant_encrypt_channel_settings_t));
+}
+
+
+/**@brief Function for handling ANT RX channel events.
+ *
+ * @param[in] p_event_message_buffer The ANT event message buffer.
+ */
+static void ant_slave_encrypt_try_enable(uint8_t ant_channel,
+ uint8_t ant_message_id)
+{
+ uint32_t err_code;
+ ant_encrypt_tracking_state_t track_stat;
+
+
+ switch (ant_message_id)
+ {
+ // Broadcast data received.
+ case MESG_BROADCAST_DATA_ID:
+
+ track_stat = ant_channel_encryp_tracking_state_get(ant_channel);
+ // If the encryption has not yet been negotiated for this channel and another channel
+ // is not currently trying to enable encryption, enable encryption
+ if ((track_stat != ANT_ENC_CHANNEL_STAT_TRACKING_DECRYPTED)
+ && (track_stat != ANT_ENC_CHANNEL_STAT_NEGOTIATING)
+ && m_can_enable_crypto)
+ {
+ // Block other channels from trying to enable encryption until this channel
+ // is finished
+ m_can_enable_crypto = false;
+ ant_channel_encryp_tracking_state_set(ant_channel,
+ ANT_ENC_CHANNEL_STAT_NEGOTIATING);
+
+ // Enable encryption on ant_channel
+ err_code =
+ ant_channel_encrypt_config_perform(ant_channel,
+ &m_slave_channel_conf[ant_channel]);
+ APP_ERROR_CHECK(err_code);
+ }
+ break;
+
+ default:
+ break;
+ }
+}
+
+
+void ant_slave_encrypt_negotiation(ant_evt_t * p_ant_evt)
+{
+ ant_encrypt_tracking_state_t track_state =
+ ant_channel_encryp_tracking_state_get(p_ant_evt->channel);
+
+ if (track_state == ANT_ENC_CHANNEL_STAT_TRACKING_UNSUPPORTED)
+ return;
+
+ switch (p_ant_evt->event)
+ {
+ case EVENT_RX_FAIL_GO_TO_SEARCH:
+ if (track_state == ANT_ENC_CHANNEL_STAT_NEGOTIATING)
+ {
+ m_can_enable_crypto = true;
+ }
+
+ ant_channel_encryp_tracking_state_set(p_ant_evt->channel,
+ ANT_ENC_CHANNEL_STAT_NOT_TRACKING);
+ break;
+
+ case EVENT_RX:
+ ant_slave_encrypt_try_enable(p_ant_evt->channel,
+ p_ant_evt->message.ANT_MESSAGE_ucMesgID);
+ break;
+
+ case EVENT_ENCRYPT_NEGOTIATION_SUCCESS:
+ m_can_enable_crypto = true;
+ ant_channel_encryp_tracking_state_set(p_ant_evt->channel,
+ ANT_ENC_CHANNEL_STAT_TRACKING_DECRYPTED);
+ break;
+
+ case EVENT_ENCRYPT_NEGOTIATION_FAIL:
+ m_can_enable_crypto = true;
+ ant_channel_encryp_tracking_state_set(p_ant_evt->channel,
+ ANT_ENC_CHANNEL_STAT_TRACKING_ENCRYPTED);
+ break;
+
+ default:
+ break;
+ }
+}
+
+#endif // NRF_MODULE_ENABLED(ANT_ENCRYPT_NEGOTIATION_SLAVE)
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ant/ant_encryption/ant_encrypt_negotiation_slave.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ant/ant_encryption/ant_encrypt_negotiation_slave.h
new file mode 100644
index 0000000..253517d
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ant/ant_encryption/ant_encrypt_negotiation_slave.h
@@ -0,0 +1,140 @@
+/**
+ * Copyright (c) 2015 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#ifndef ANT_ENCRYPT_NEGOTIATION_SLAVE_H__
+#define ANT_ENCRYPT_NEGOTIATION_SLAVE_H__
+
+/**@file
+ *
+ * @defgroup ant_encrypt_negotiation_slave ANT encryption negotiation
+ * @{
+ * @ingroup ant_sdk_utils
+ *
+ * @brief Encryption negotiation for encrypted ANT slave channels.
+ *
+ * After pairing, the slave starts negotiating the encryption with the master. After
+ * successful negotiation, the slave can decrypt messages from the master, and all
+ * future messages are sent encrypted.
+ *
+ */
+
+#include <stdint.h>
+#include "nrf_sdh_ant.h"
+#include "ant_encrypt_config.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Encryption negotiation states for a slave channel. */
+typedef enum
+{
+ ANT_ENC_CHANNEL_STAT_NOT_TRACKING, ///< Not tracking the master.
+ ANT_ENC_CHANNEL_STAT_TRACKING_ENCRYPTED, ///< Tracking the master, but cannot decrypt messages.
+ ANT_ENC_CHANNEL_STAT_NEGOTIATING, ///< Encryption has been enabled and negotiation is in progress.
+ ANT_ENC_CHANNEL_STAT_TRACKING_DECRYPTED, ///< Tracking the master and can decrypt messages.
+ ANT_ENC_CHANNEL_STAT_TRACKING_UNSUPPORTED ///< Tracking unsupported on this channel.
+} ant_encrypt_tracking_state_t;
+
+
+/**
+ * @brief Function for setting the encryption negotiation state of a slave ANT channel.
+ *
+ * This function should be used by the @ref ant_encrypt_config module.
+ *
+ * @param[in] channel_number ANT channel number.
+ * @param[in] state State to set.
+ */
+void ant_channel_encryp_tracking_state_set(uint8_t channel_number,
+ ant_encrypt_tracking_state_t state);
+
+/**
+ * @brief Function for getting the encryption negotiation state of a slave ANT channel.
+ *
+ * @param[in] channel_number ANT channel number.
+ */
+ant_encrypt_tracking_state_t ant_channel_encryp_tracking_state_get(uint8_t channel_number);
+
+/**
+ * @brief Function for initializing the module.
+ *
+ * This function initializes internal states of the module. It should
+ * only be used by the @ref ant_encrypt_config module.
+ *
+ */
+void ant_channel_encryp_negotiation_slave_init(void);
+
+/**
+ * @brief Function for setting the configuration for the slave channel.
+ *
+ * This function saves the channel's encryption configuration to a lookup table (LUT) for
+ * future usage. The configuration can then be used to enable encryption.
+ *
+ * This function is intended to be used by the @ref ant_encrypt_config module.
+ *
+ * @param[in] channel_number ANT channel number.
+ * @param[in] p_crypto_config Pointer to the encryption configuration.
+ */
+void ant_slave_channel_encrypt_config(uint8_t channel_number,
+ ant_encrypt_channel_settings_t const * const p_crypto_config);
+
+
+/**
+ * @brief Function for handling ANT encryption negotiation on slave nodes.
+ *
+ * This function should be used directly in the ANT event dispatching process. It
+ * tries to enable slave channel encryption for all slave channels that are declared
+ * as encrypted channels (if appropriate master channels are found).
+ *
+ * This function should be used by the @ref ant_encrypt_config module.
+ *
+ * @param[in] p_ant_evt Pointer to the ANT stack event message structure.
+ */
+void ant_slave_encrypt_negotiation(ant_evt_t * p_ant_evt);
+
+
+/**
+ * @}
+ */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // ANT_ENCRYPT_NEGOTIATION_SLAVE_H__
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ant/ant_fs/antfs.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ant/ant_fs/antfs.c
new file mode 100644
index 0000000..6c46f32
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ant/ant_fs/antfs.c
@@ -0,0 +1,2379 @@
+/**
+ * This software is subject to the ANT+ Shared Source License
+ * www.thisisant.com/swlicenses
+ * Copyright (c) Dynastream Innovations, Inc. 2012
+ * 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 Dynastream nor the names of its
+ * contributors may be used to endorse or promote products
+ * derived from this software without specific prior
+ * written permission.
+ *
+ * The following actions are prohibited:
+ * 1) Redistribution of source code containing the ANT+ Network
+ * Key. The ANT+ Network Key is available to ANT+ Adopters.
+ * Please refer to http://thisisant.com to become an ANT+
+ * Adopter and access the key.
+ *
+ * 2) Reverse engineering, decompilation, and/or disassembly of
+ * software provided in binary form under this license.
+ *
+ * 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 HEREBY
+ * 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; DAMAGE TO ANY DEVICE, 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. SOME STATES DO NOT ALLOW
+ * THE EXCLUSION OF INCIDENTAL OR CONSEQUENTIAL DAMAGES, SO THE
+ * ABOVE LIMITATIONS MAY NOT APPLY TO YOU.
+ *
+ */
+#include "sdk_common.h"
+#if NRF_MODULE_ENABLED(ANTFS)
+
+#include "antfs.h"
+#include <string.h>
+#include "defines.h"
+#include "app_error.h"
+#include "app_timer.h"
+#include "ant_error.h"
+#include "ant_parameters.h"
+#include "ant_interface.h"
+#include "ant_key_manager.h"
+#include "crc.h"
+
+#if ANTFS_CONFIG_DEBUG_LED_ENABLED
+ #include "bsp.h"
+#endif // ANTFS_CONFIG_DEBUG_LED_ENABLED
+
+#define BURST_PACKET_SIZE 8u /**< The burst packet size. */
+
+#define ANTFS_CONNECTION_TYPE_OFFSET 0x00u /**< The connection type offset within ANT-FS message. */
+#define ANTFS_COMMAND_OFFSET 0x01u /**< The command offset within ANT-FS message. */
+#define ANTFS_RESPONSE_OFFSET 0x01u /**< The response offset within ANT-FS message. */
+
+#define ANTFS_CONTROL_OFFSET 0x02u /**< The control offset within ANT-FS message. */
+#define ANTFS_DATA_OFFSET 0x03u /**< The data offset within ANT-FS message. */
+
+#define ANTFS_BEACON_ID 0x43u /**< The ANT-FS beacon ID. */
+#define ANTFS_COMMAND_ID 0x44u /**< The ANT-FS command ID. */
+
+// Beacon definitions.
+#define STATUS1_OFFSET 0x01u /**< The beacon status1 field offset. */
+#define STATUS2_OFFSET 0x02u /**< The beacon status2 field offset. */
+ #define DEVICE_STATE_SHIFT 0x00u /**< Shift value for device state bitfield. */
+ #define DEVICE_STATE_MASK (0x0Fu << DEVICE_STATE_SHIFT) /**< Device state bitmask. */
+ #define DEVICE_STATE_LINK (0x00u << DEVICE_STATE_SHIFT) /**< Device is in link state. */
+ #define DEVICE_STATE_AUTHENTICATE (0x01u << DEVICE_STATE_SHIFT) /**< Device is in authenticate state. */
+ #define DEVICE_STATE_TRANSPORT (0x02u << DEVICE_STATE_SHIFT) /**< Device is in transport state. */
+ #define DEVICE_STATE_BUSY (0x03u << DEVICE_STATE_SHIFT) /**< Device is in busy state. */
+
+#define DEVICE_DESCRIPTOR_OFFSET_0 0x04u /**< Beacon ANT-FS device descriptor LSB position. */
+#define DEVICE_DESCRIPTOR_OFFSET_1 0x05u /**< Beacon ANT-FS device descriptor LSB + 1 position. */
+#define DEVICE_DESCRIPTOR_OFFSET_2 0x06u /**< Beacon ANT-FS device descriptor LSB + 2 position. */
+#define DEVICE_DESCRIPTOR_OFFSET_3 0x07u /**< Beacon ANT-FS device descriptor MSB position. */
+
+// Commands.
+#define ANTFS_CMD_NONE 0x00u /**< Used to identify that no ANT-FS command is in progress. */
+#define ANTFS_CMD_LINK_ID 0x02u /**< ANT-FS link command ID. */
+#define ANTFS_CMD_DISCONNECT_ID 0x03u /**< ANT-FS disconnect command ID. */
+#define ANTFS_CMD_AUTHENTICATE_ID 0x04u /**< ANT-FS authenticate command ID. */
+#define ANTFS_CMD_PING_ID 0x05u /**< ANT-FS ping command ID. */
+#define ANTFS_CMD_DOWNLOAD_ID 0x09u /**< ANT-FS download request command ID. */
+#define ANTFS_CMD_UPLOAD_REQUEST_ID 0x0Au /**< ANT-FS upload request command ID. */
+#define ANTFS_CMD_ERASE_ID 0x0Bu /**< ANT-FS erase request command ID. */
+#define ANTFS_CMD_UPLOAD_DATA_ID 0x0Cu /**< ANT-FS upload command ID. */
+
+// Responses.
+#define ANTFS_RSP_AUTHENTICATE_ID 0x84u /**< ANT-FS authenticate response command ID. */
+#define ANTFS_RSP_DOWNLOAD_ID 0x89u /**< ANT-FS download request response command ID. */
+#define ANTFS_RSP_UPLOAD_REQ_ID 0x8Au /**< ANT-FS upload request response command ID. */
+#define ANTFS_RSP_ERASE_ID 0x8Bu /**< ANT-FS erase response command ID. */
+#define ANTFS_RSP_UPLOAD_DATA_ID 0x8Cu /**< ANT-FS upload data response command ID. */
+
+// Link command.
+#define TRANSPORT_CHANNEL_FREQUENCY_OFFSET 0x02u /**< Channel frequency field offset within link command. */
+#define TRANSPORT_MESSAGE_PERIOD_OFFSET 0x03u /**< Channel period field offset within link command. */
+#define HOST_ID_OFFSET_0 0x04u /**< Host serial number period field LSB offset within link command. */
+#define HOST_ID_OFFSET_1 0x05u /**< Host serial number period field LSB + 1 offset within link command. */
+#define HOST_ID_OFFSET_2 0x06u /**< Host serial number period field LSB + 2 offset within link command. */
+#define HOST_ID_OFFSET_3 0x07u /**< Host serial number period field MSB offset within link command. */
+
+// Authenticate command.
+#define COMMAND_TYPE_OFFSET 0x02u /**< Command type field offset within authenticate command. */
+ #define COMMAND_TYPE_PROCEED 0x00u /**< Command type proceed to transport in the authenticate command. */
+ #define COMMAND_TYPE_REQUEST_SERIAL 0x01u /**< Command type request client device serial number in the authenticate command. */
+ #define COMMAND_TYPE_REQUEST_PAIR 0x02u /**< Command type request pairing in the authenticate command. */
+ #define COMMAND_TYPE_REQUEST_PASSKEY 0x03u /**< Command type request passkey exchange in the authenticate command. */
+
+// Authenticate response.
+#define RESPONSE_TYPE_OFFSET 0x02u /**< Command type field offset within authenticate response command. */
+ #define AUTH_RESPONSE_N_A 0x00u /**< Command response type N/A (response for client serial number request). */
+ #define AUTH_RESPONSE_ACCEPT 0x01u /**< Command response type accept. */
+ #define AUTH_RESPONSE_REJECT 0x02u /**< Command response type reject. */
+
+// Authenticate command/response.
+#define AUTH_STRING_LENGTH_OFFSET 0x03u /**< Authenticate Command/Response authentication string length offset. */
+#define SERIAL_NUMBER_OFFSET_0 0x04u /**< Authenticate Command/Response client/host serial number LSB offset. */
+#define SERIAL_NUMBER_OFFSET_1 0x05u /**< Authenticate Command/Response client/host serial number LSB + 1 offset. */
+#define SERIAL_NUMBER_OFFSET_2 0x06u /**< Authenticate Command/Response client/host serial number LSB + 2 offset. */
+#define SERIAL_NUMBER_OFFSET_3 0x07u /**< Authenticate Command/Response client/host serial number MSB offset. */
+
+// Download/Upload/Erase commands.
+#define INITIAL_REQUEST_OFFSET 0x01u /**< Download/Upload/Erase command initial request command offset. */
+#define DATA_INDEX_OFFSET_LOW 0x02u /**< Download/Upload/Erase command offset index low. */
+#define DATA_INDEX_OFFSET_HIGH 0x03u /**< Download/Upload/Erase command offset index high. */
+
+#define ADDRESS_PARAMETER_OFFSET_0 0x04u /**< Download/Upload command parameter LSB offset. */
+#define ADDRESS_PARAMETER_OFFSET_1 0x05u /**< Download/Upload command parameter LSB + 1 offset. */
+#define ADDRESS_PARAMETER_OFFSET_2 0x06u /**< Download/Upload command parameter LSB + 2 offset. */
+#define ADDRESS_PARAMETER_OFFSET_3 0x07u /**< Download/Upload command parameter MSB offset. */
+#define UPLOAD_CRC_OFFSET_LOW 0x06u /**< Upload data CRC offset low. */
+#define UPLOAD_CRC_OFFSET_HIGH 0x07u /**< Upload data CRC offset high. */
+
+// Authentication type. The highest level of authentication available is included in the beacon.
+#if ANTFS_CONFIG_AUTH_TYPE_PASSKEY_ENABLED
+ #define AUTHENTICATION_TYPE COMMAND_TYPE_REQUEST_PASSKEY /**< Passkey and pairing only mode set as authentication type in beacon. */
+#elif ANTFS_CONFIG_AUTH_TYPE_PAIRING_ENABLED
+ #define AUTHENTICATION_TYPE COMMAND_TYPE_REQUEST_PAIR /**< Pairing only mode set as authentication type in beacon. */
+#elif ANTFS_CONFIG_AUTH_TYPE_PASSTHROUGH_ENABLED
+ #define AUTHENTICATION_TYPE COMMAND_TYPE_PROCEED /**< Pass-through mode set as authentication type in beacon. */
+#else
+ #error "No valid auth type defined"
+#endif
+
+#define AUTHENTICATION_RETRIES 0x05u /**< Max number of retries for authentication responses */
+
+#define ANTFS_EVENT_QUEUE_SIZE 0x04u /**< ANT-FS event queue size. */
+#define SAVE_DISTANCE 256u /**< Save distance required because of nRF buffer to line up data offset on retry. */
+
+// Buffer Indices.
+#define BUFFER_INDEX_MESG_SIZE 0x00u /**< ANT message buffer index length offset. */
+#define BUFFER_INDEX_MESG_ID 0x01u /**< ANT message buffer index ID offset. */
+#define BUFFER_INDEX_CHANNEL_NUM 0x02u /**< ANT message buffer index channel number offset. */
+#define BUFFER_INDEX_MESG_DATA 0x03u /**< ANT message buffer index begin of data offset. */
+#define BUFFER_INDEX_RESPONSE_CODE 0x04u /**< ANT message buffer index response code offset. */
+
+typedef struct
+{
+ char friendly_name[ANTFS_FRIENDLY_NAME_MAX]; /**< Friendly Name. */
+ bool is_name_set; /**< Is the name set. */
+ uint32_t index; /**< Current index (for reading the friendly name). */
+ uint32_t friendly_name_size; /**< Friendly name size. */
+} friendly_name_t;
+
+typedef union
+{
+ antfs_link_substate_t link_sub_state; /**< Sub-state (Link layer). */
+ antfs_authenticate_substate_t auth_sub_state; /**< Sub-state (Authentication layer). */
+ antfs_transport_substate_t trans_sub_state; /**< Sub-state (Transport layer). */
+} antfs_substate_t;
+
+typedef struct
+{
+ antfs_state_t state; /**< ANT-FS state. */
+ antfs_substate_t sub_state; /**< ANT-FS sub-state. */
+} antfs_states_t;
+
+typedef struct
+{
+ antfs_event_return_t * p_queue; /**< ANT-FS event queue. */
+ uint32_t head; /**< ANT-FS event queue head index. */
+ uint32_t tail; /**< ANT-FS event queue tail index. */
+} antfs_event_queue_t;
+
+static antfs_params_t m_initial_parameters; /**< Initial parameters. */
+static antfs_beacon_status_byte1_t m_active_beacon_status1_field; /**< Status 1 field in beacon. */
+static uint32_t m_active_beacon_frequency; /**< Active beacon frequency. */
+static antfs_states_t m_current_state; /**< Current state. */
+static friendly_name_t m_friendly_name; /**< Host's friendly name. */
+static ulong_union_t m_link_host_serial_number; /**< Host's serial number. */
+static uint32_t m_link_command_in_progress; /**< ANT-FS command in progress. */
+static uint32_t m_authenticate_command_type; /**< Authenticate command type in progress. */
+static volatile uint8_t m_burst_wait; /**< Polling status flag for data unlock on burst handler input. */
+static uint8_t m_retry; /**< Retry counter */
+APP_TIMER_DEF(m_timer_id); /**< Timer ID used with the timer module. */
+
+#if ANTFS_CONFIG_AUTH_TYPE_PASSKEY_ENABLED
+ static uint32_t m_passkey_index; /**< Current location of Tx block (auth string). */
+#endif // ANTFS_CONFIG_AUTH_TYPE_PASSKEY_ENABLED
+
+// Download/upload.
+static bool m_is_data_request_pending; /**< Requested data pending. */
+static bool m_is_crc_pending; /**< CRC for data packets pending. */
+static ushort_union_t m_file_index; /**< File index of current upload/download. */
+static ulong_union_t m_file_size; /**< File size of current upload/download (bytes). */
+static ulong_union_t m_max_block_size; /**< Maximum number of bytes expected to be downloaded in a single burst block of data (set by host). */
+static ulong_union_t m_link_burst_index; /**< Current location of Tx block (bytes). */
+static ulong_union_t m_bytes_remaining; /**< Total remaining data length (bytes). */
+static ulong_union_t m_max_transfer_index; /**< Upper limit of the current Tx burst block (bytes). */
+static uint32_t m_bytes_to_write; /**< Number of bytes to write to file (upload). */
+static const uint8_t * mp_upload_data; /**< Address of begin of the buffer that holds data received from upload. */
+#if ANTFS_CONFIG_UPLOAD_ENABLED
+ static ulong_union_t m_block_size; /**< Number of bytes the client can receive in a single burst. */
+#endif // ANTFS_CONFIG_UPLOAD_ENABLED
+
+// CRC verification.
+static uint32_t m_saved_crc_offset; /**< CRC data offset (bytes) saved at last CRC update (save point). */
+static uint32_t m_saved_buffer_crc_offset; /**< Data offset to track how much data has been buffered into nRF */
+static uint32_t m_temp_crc_offset; /**< Temporary CRC data offset used in CRC calculation. */
+static uint16_t m_compared_crc; /**< 16-bit CRC for all data packets in the block (provided by download request). */
+static uint16_t m_transfer_crc; /**< 16-bit CRC for all data packets in the block (calculated by client). */
+static uint16_t m_saved_transfer_crc; /**< 16-bit CRC saved at last CRC update (save point). */
+static uint16_t m_saved_buffer_crc; /**< 16-bit CRC saved at last CRC update (save point) for buffering the nRF */
+
+// ANT-FS event handling.
+static antfs_event_return_t m_event_queue_buffer[ANTFS_EVENT_QUEUE_SIZE]; /**< Event queue storage. */
+static antfs_event_queue_t m_event_queue; /**< Event queue. */
+
+static antfs_burst_wait_handler_t m_burst_wait_handler = NULL; /**< Burst wait handler */
+
+
+const char * antfs_hostname_get(void)
+{
+ if (m_friendly_name.is_name_set)
+ {
+ return (m_friendly_name.friendly_name);
+ }
+
+ return NULL;
+}
+
+
+/**@brief Function for waiting for the burst transmission request to complete.
+ */
+static void wait_burst_request_to_complete(void)
+{
+ while (m_burst_wait != 0)
+ {
+ if (m_burst_wait_handler != NULL)
+ {
+ m_burst_wait_handler();
+ }
+ };
+}
+
+
+/**@brief Function for stopping ANT-FS timeout, which is possibly currently running.
+ */
+static void timeout_disable(void)
+{
+ m_link_command_in_progress = ANTFS_CMD_NONE;
+
+ const uint32_t err_code = app_timer_stop(m_timer_id);
+ APP_ERROR_CHECK(err_code);
+}
+
+
+/**@brief Function for transmitting a beacon.
+ *
+ * Transmits a beacon either using a broadcast or burst transmission mode.
+ *
+ * @param[in] message_type Defines the used transmission mode.
+ */
+static void beacon_transmit(uint32_t message_type)
+{
+ uint8_t beacon_status_byte2;
+
+ // Set beacon status byte 2.
+
+ if (m_link_command_in_progress == ANTFS_CMD_NONE)
+ {
+ switch (m_current_state.state)
+ {
+ case ANTFS_STATE_AUTH:
+ beacon_status_byte2 = DEVICE_STATE_AUTHENTICATE;
+ break;
+
+ case ANTFS_STATE_TRANS:
+ beacon_status_byte2 = DEVICE_STATE_TRANSPORT;
+ break;
+
+ default:
+ beacon_status_byte2 = DEVICE_STATE_LINK;
+ break;
+ }
+ }
+ else
+ {
+ beacon_status_byte2 = DEVICE_STATE_BUSY;
+ }
+
+ // Set remaining beacon fields.
+
+ uint8_t tx_buffer[BURST_PACKET_SIZE];
+
+ tx_buffer[0] = ANTFS_BEACON_ID;
+ tx_buffer[1] = m_active_beacon_status1_field.status;
+ tx_buffer[2] = beacon_status_byte2;
+ tx_buffer[3] = AUTHENTICATION_TYPE;
+
+ if ((m_current_state.state == ANTFS_STATE_AUTH) ||
+ (m_current_state.state == ANTFS_STATE_TRANS))
+ {
+ tx_buffer[4] = m_link_host_serial_number.bytes.byte0;
+ tx_buffer[5] = m_link_host_serial_number.bytes.byte1;
+ tx_buffer[6] = m_link_host_serial_number.bytes.byte2;
+ tx_buffer[7] = m_link_host_serial_number.bytes.byte3;
+ }
+ else
+ {
+ tx_buffer[4] = m_initial_parameters.beacon_device_type;
+ tx_buffer[5] = (m_initial_parameters.beacon_device_type >> 8u);
+ tx_buffer[6] = m_initial_parameters.beacon_device_manufacturing_id;
+ tx_buffer[7] = (m_initial_parameters.beacon_device_manufacturing_id >> 8u);
+ }
+
+ if (message_type == MESG_BROADCAST_DATA_ID)
+ {
+ if (sd_ant_broadcast_message_tx(ANTFS_CONFIG_CHANNEL_NUMBER, sizeof(tx_buffer), tx_buffer) != NRF_SUCCESS)
+ {
+ // @note: No implementation needed, as it is a valid and accepted use case for this call
+ // to fail. This call can fail if we are in middle of bursting.
+ }
+ }
+ else if (message_type == MESG_BURST_DATA_ID)
+ {
+ // Send as the first packet of a burst.
+ const uint32_t err_code = sd_ant_burst_handler_request(ANTFS_CONFIG_CHANNEL_NUMBER,
+ sizeof(tx_buffer),
+ tx_buffer,
+ BURST_SEGMENT_START);
+ APP_ERROR_CHECK(err_code);
+
+ wait_burst_request_to_complete();
+
+ // This is the first packet of a burst response, disable command timeout while bursting.
+ timeout_disable();
+ }
+ else
+ {
+ // This should not happen.
+ APP_ERROR_HANDLER(message_type);
+ }
+}
+
+
+/**@brief Function for transmitting a authenticate response message.
+ *
+ * @param[in] response_type Authenticate response code.
+ * @param[in] password_length Length of authentication string.
+ * @param[in] p_password Authentication string transmitted.
+ */
+static void authenticate_response_transmit(uint8_t response_type,
+ uint32_t password_length,
+ const uint8_t * p_password)
+{
+ ulong_union_t serial_number;
+
+ serial_number.data = m_initial_parameters.client_serial_number;
+
+ // First packet is beacon.
+ beacon_transmit(MESG_BURST_DATA_ID);
+
+ uint8_t tx_buffer[BURST_PACKET_SIZE];
+
+ tx_buffer[ANTFS_CONNECTION_TYPE_OFFSET] = ANTFS_COMMAND_ID;
+ tx_buffer[ANTFS_RESPONSE_OFFSET] = ANTFS_RSP_AUTHENTICATE_ID;
+ tx_buffer[RESPONSE_TYPE_OFFSET] = response_type;
+ tx_buffer[AUTH_STRING_LENGTH_OFFSET] = password_length;
+ tx_buffer[SERIAL_NUMBER_OFFSET_0] = serial_number.bytes.byte0;
+ tx_buffer[SERIAL_NUMBER_OFFSET_1] = serial_number.bytes.byte1;
+ tx_buffer[SERIAL_NUMBER_OFFSET_2] = serial_number.bytes.byte2;
+ tx_buffer[SERIAL_NUMBER_OFFSET_3] = serial_number.bytes.byte3;
+
+ uint32_t err_code;
+ if ((m_current_state.state == ANTFS_STATE_AUTH) &&
+ (
+ (response_type != AUTH_RESPONSE_REJECT) &&
+ password_length &&
+ (password_length <= ANTFS_AUTH_STRING_MAX)
+ )
+ )
+ {
+ // Send second packet (auth response).
+ err_code = sd_ant_burst_handler_request(ANTFS_CONFIG_CHANNEL_NUMBER,
+ sizeof(tx_buffer),
+ tx_buffer,
+ BURST_SEGMENT_CONTINUE);
+ APP_ERROR_CHECK(err_code);
+
+ wait_burst_request_to_complete();
+
+ // Round size to a multiple of 8 bytes.
+ uint8_t tx_buffer_authenticate[ANTFS_AUTH_STRING_MAX + 1u];
+
+ memset(tx_buffer_authenticate, 0, ANTFS_AUTH_STRING_MAX + 1u);
+ memcpy(tx_buffer_authenticate, p_password, password_length);
+
+ // Round up total number bytes to a multiple of 8 to be sent to burst handler.
+ if (password_length & (BURST_PACKET_SIZE - 1u))
+ {
+ password_length &= ~(BURST_PACKET_SIZE - 1u);
+ password_length += BURST_PACKET_SIZE;
+ }
+
+ // Send auth string (last packets of the burst).
+ err_code = sd_ant_burst_handler_request(ANTFS_CONFIG_CHANNEL_NUMBER,
+ password_length,
+ tx_buffer_authenticate,
+ BURST_SEGMENT_END);
+ APP_ERROR_CHECK(err_code);
+
+ wait_burst_request_to_complete();
+
+ m_link_command_in_progress = ANTFS_RSP_AUTHENTICATE_ID;
+ }
+ else
+ {
+ // If the authorization is rejected or there is no valid password, the auth response is the
+ // last packet.
+
+ err_code = sd_ant_burst_handler_request(ANTFS_CONFIG_CHANNEL_NUMBER,
+ sizeof(tx_buffer),
+ tx_buffer,
+ BURST_SEGMENT_END);
+ APP_ERROR_CHECK(err_code);
+
+ wait_burst_request_to_complete();
+ }
+
+ // Switch to appropiate state.
+ if (response_type == AUTH_RESPONSE_REJECT)
+ {
+ m_current_state.sub_state.auth_sub_state = ANTFS_AUTH_SUBSTATE_REJECT;
+ }
+ else if (response_type == AUTH_RESPONSE_ACCEPT)
+ {
+ m_current_state.sub_state.auth_sub_state = ANTFS_AUTH_SUBSTATE_ACCEPT;
+ }
+ else
+ {
+ // No implementation needed.
+ }
+}
+
+
+bool antfs_pairing_resp_transmit(bool accept)
+{
+#if ANTFS_CONFIG_AUTH_TYPE_PAIRING_ENABLED
+ // This function should only be called when ANT-FS is in PAIRING mode.
+ if ((m_current_state.state != ANTFS_STATE_AUTH) ||
+ (m_current_state.sub_state.auth_sub_state != ANTFS_AUTH_SUBSTATE_PAIR))
+ {
+ return false;
+ }
+
+ m_link_command_in_progress = ANTFS_CMD_AUTHENTICATE_ID;
+
+ if (accept)
+ {
+ // Accept request and send passkey if authentication passed.
+ authenticate_response_transmit(AUTH_RESPONSE_ACCEPT,
+ ANTFS_PASSKEY_SIZE,
+ m_initial_parameters.p_pass_key);
+ }
+ else
+ {
+ // Reject authentication request.
+ authenticate_response_transmit(AUTH_RESPONSE_REJECT, 0, NULL);
+ }
+
+ return true;
+#else
+ return false;
+#endif // ANTFS_CONFIG_AUTH_TYPE_PAIRING_ENABLED
+}
+
+
+/**@brief Function for adding an ANT-FS event to the event queue.
+ *
+ * @param[in] event_code The event to be added.
+ */
+static void event_queue_write(antfs_event_t event_code)
+{
+ antfs_event_return_t * p_event = NULL;
+#if ANTFS_CONFIG_DEBUG_LED_ENABLED
+ uint32_t err_code;
+#endif // ANTFS_CONFIG_DEBUG_LED_ENABLED
+
+ // Check if there is room in the queue for a new event.
+ if (((m_event_queue.head + 1u) & (ANTFS_EVENT_QUEUE_SIZE - 1u)) != m_event_queue.tail)
+ {
+ p_event = &(m_event_queue.p_queue[m_event_queue.head]);
+ }
+
+ if (p_event != NULL)
+ {
+ // Initialize event parameters.
+ p_event->event = event_code;
+
+ // Set parameters depending on event type.
+ switch (event_code)
+ {
+ case ANTFS_EVENT_ERASE_REQUEST:
+ p_event->file_index = m_file_index.data;
+ p_event->offset = 0;
+ p_event->bytes = 0;
+ p_event->crc = 0;
+ break;
+
+ case ANTFS_EVENT_DOWNLOAD_REQUEST:
+ p_event->file_index = m_file_index.data;
+ // Requested offset for the download.
+ p_event->offset = m_link_burst_index.data;
+ p_event->bytes = 0;
+ p_event->crc = 0;
+ break;
+
+ case ANTFS_EVENT_DOWNLOAD_REQUEST_DATA:
+ p_event->file_index = m_file_index.data;
+ // Current offset.
+ p_event->offset = m_link_burst_index.data;
+
+ if (m_bytes_remaining.data > (ANTFS_BURST_BLOCK_SIZE * BURST_PACKET_SIZE))
+ {
+ // If remaining bytes > burst block size then grab one block at a time.
+ p_event->bytes = ANTFS_BURST_BLOCK_SIZE * BURST_PACKET_SIZE;
+ }
+ else
+ {
+ p_event->bytes = m_bytes_remaining.data;
+ }
+
+ p_event->crc = 0;
+ break;
+
+ case ANTFS_EVENT_UPLOAD_REQUEST:
+ p_event->file_index = m_file_index.data;
+ // Requested offset for the upload.
+ p_event->offset = m_link_burst_index.data;
+ // Upper limit of the download (offset + remaining bytes).
+ p_event->bytes = m_max_transfer_index.data;
+ // CRC Seed (from last save point if resuming).
+ p_event->crc = m_transfer_crc;
+ break;
+
+ case ANTFS_EVENT_UPLOAD_DATA:
+ p_event->file_index = m_file_index.data;
+ // Current offset.
+ p_event->offset = m_link_burst_index.data;
+ // Current CRC.
+ p_event->crc = m_transfer_crc;
+ // Number of bytes to write.
+ p_event->bytes = m_bytes_to_write;
+ // Upload to appication data buffer.
+ memcpy(p_event->data, mp_upload_data, m_bytes_to_write);
+ break;
+
+ case ANTFS_EVENT_PAIRING_REQUEST:
+#if ANTFS_CONFIG_DEBUG_LED_ENABLED
+ err_code = bsp_indication_set(BSP_INDICATE_BONDING);
+ APP_ERROR_CHECK(err_code);
+#endif // ANTFS_CONFIG_DEBUG_LED_ENABLED
+ break;
+
+ default:
+ // No parameters need to be set.
+
+ p_event->file_index = 0;
+ p_event->offset = 0;
+ p_event->bytes = 0;
+ p_event->crc = 0;
+ break;
+ }
+
+ // Put the event in the queue.
+ m_event_queue.head = ((m_event_queue.head + 1u) & (ANTFS_EVENT_QUEUE_SIZE - 1u));
+ }
+ else
+ {
+ // No free space left in the queue.
+ APP_ERROR_HANDLER(0);
+ }
+}
+
+
+/**@brief Function for transmitting download request response message.
+ *
+ * @param[in] response Download response code.
+ */
+static void download_request_response_transmit(uint8_t response)
+{
+ // First burst packet is beacon.
+ beacon_transmit(MESG_BURST_DATA_ID);
+
+ uint8_t tx_buffer[BURST_PACKET_SIZE];
+
+ // Next send the first part of the download response.
+ tx_buffer[0] = ANTFS_COMMAND_ID;
+ tx_buffer[1] = ANTFS_RSP_DOWNLOAD_ID;
+ tx_buffer[2] = response;
+ tx_buffer[3] = 0;
+ // Total number of bytes remaining in the data block.
+ tx_buffer[4] = m_bytes_remaining.bytes.byte0;
+ tx_buffer[5] = m_bytes_remaining.bytes.byte1;
+ tx_buffer[6] = m_bytes_remaining.bytes.byte2;
+ tx_buffer[7] = m_bytes_remaining.bytes.byte3;
+
+ uint32_t err_code = sd_ant_burst_handler_request(ANTFS_CONFIG_CHANNEL_NUMBER,
+ sizeof(tx_buffer),
+ tx_buffer,
+ BURST_SEGMENT_CONTINUE);
+ APP_ERROR_CHECK(err_code);
+
+ wait_burst_request_to_complete();
+
+ // Second part of the download response.
+
+ // The offset the data will start from in this block.
+ tx_buffer[0] = m_link_burst_index.bytes.byte0;
+ tx_buffer[1] = m_link_burst_index.bytes.byte1;
+ tx_buffer[2] = m_link_burst_index.bytes.byte2;
+ tx_buffer[3] = m_link_burst_index.bytes.byte3;
+ // The file size in the client device.
+ tx_buffer[4] = m_file_size.bytes.byte0;
+ tx_buffer[5] = m_file_size.bytes.byte1;
+ tx_buffer[6] = m_file_size.bytes.byte2;
+ tx_buffer[7] = m_file_size.bytes.byte3;
+
+ if (response || (m_bytes_remaining.data == 0))
+ {
+ // If the download was rejected or there is no data to send.
+
+ // Set response to end since we're not downloading any data.
+ err_code = sd_ant_burst_handler_request(ANTFS_CONFIG_CHANNEL_NUMBER,
+ sizeof(tx_buffer),
+ tx_buffer,
+ BURST_SEGMENT_END);
+ APP_ERROR_CHECK(err_code);
+
+ wait_burst_request_to_complete();
+ }
+ else
+ {
+ // Response will continue (data packets + CRC footer to follow).
+ err_code = sd_ant_burst_handler_request(ANTFS_CONFIG_CHANNEL_NUMBER,
+ sizeof(tx_buffer),
+ tx_buffer,
+ BURST_SEGMENT_CONTINUE);
+ APP_ERROR_CHECK(err_code);
+
+ wait_burst_request_to_complete();
+ }
+
+ m_link_command_in_progress = ANTFS_CMD_DOWNLOAD_ID;
+
+ if (response == 0)
+ {
+ // If we are going to download (response OK), enter the downloading substate.
+ m_current_state.sub_state.trans_sub_state = ANTFS_TRANS_SUBSTATE_DOWNLOADING;
+ event_queue_write(ANTFS_EVENT_DOWNLOAD_START);
+ }
+ else
+ {
+ // Download rejected.
+ event_queue_write(ANTFS_EVENT_DOWNLOAD_FAIL);
+ }
+}
+
+
+void antfs_download_req_resp_prepare(uint8_t response,
+ const antfs_request_info_t * const p_request_info)
+{
+ // This function should only be called after receiving a download request.
+ APP_ERROR_CHECK_BOOL((m_current_state.state == ANTFS_STATE_TRANS) &&
+ (m_link_command_in_progress == ANTFS_CMD_DOWNLOAD_ID));
+
+ if (response == 0)
+ {
+ // Download request OK.
+
+ // File size of the requested download.
+ m_file_size.data = p_request_info->file_size.data;
+
+ if (m_link_burst_index.data > m_file_size.data)
+ {
+ // Offset should not exceed file size.
+ m_link_burst_index.data = m_file_size.data;
+ }
+
+ // If the host is not limiting download size or the file size does not exceed the host's
+ // download size limit.
+ if ((m_max_block_size.data == 0) || (m_file_size.data < m_max_block_size.data))
+ {
+ // Number of bytes remaining to be downloaded in this block is the file size.
+ m_bytes_remaining.data = m_file_size.data;
+ }
+
+ if ((m_file_size.data - m_link_burst_index.data) < m_bytes_remaining.data)
+ {
+ // Calculate number of remaining bytes in this block based on the offset.
+ m_bytes_remaining.data = m_file_size.data - m_link_burst_index.data;
+ }
+
+ // If the application is limiting the Tx block size.
+ if (m_bytes_remaining.data > p_request_info->max_burst_block_size.data)
+ {
+ // Number of remaining bytes in this block is the application defined block size.
+ m_bytes_remaining.data = p_request_info->max_burst_block_size.data;
+ }
+
+ // Find upper limit of the burst Tx.
+ m_max_transfer_index.data = m_link_burst_index.data + m_bytes_remaining.data;
+
+ if (m_saved_crc_offset == ANTFS_MAX_FILE_SIZE)
+ {
+ // CRC checking was set as invalid. An invalid download was requested, so reject it.
+ response = RESPONSE_INVALID_OPERATION;
+ }
+ }
+
+ if ((response != 0) || (m_file_size.data == 0))
+ {
+ // Send the response right away if the download request was rejected or there is no data to
+ // send.
+ download_request_response_transmit(response);
+ }
+ else
+ {
+ // Proceed to download data.
+ if (m_link_burst_index.data != m_saved_crc_offset)
+ {
+ uint32_t temp;
+
+ // If requesting to resume exactly where we left off, we can start from the same block.
+ if (m_link_burst_index.data == m_temp_crc_offset)
+ {
+ // Move last save point to end of last block sent.
+ m_saved_crc_offset = m_link_burst_index.data;
+ m_saved_transfer_crc = m_transfer_crc;
+ }
+
+ // To resume the download, request a block of data starting from the last save point.
+ // Update the remaining number of bytes per the last save point.
+ m_bytes_remaining.data += (m_link_burst_index.data - m_saved_crc_offset);
+
+ // Swap the current burst Tx index with the saved CRC index, to make sure we do not
+ // start updating the CRC until we get to the requested index.
+ temp = m_link_burst_index.data;
+ m_link_burst_index.data = m_saved_crc_offset;
+ m_saved_crc_offset = temp;
+
+ // Set CRC to previous save point, to check the CRC provided by the host.
+ m_transfer_crc = m_saved_transfer_crc;
+ }
+
+ m_temp_crc_offset = m_saved_crc_offset;
+
+ m_is_data_request_pending = true;
+
+ // Request data from application.
+ event_queue_write(ANTFS_EVENT_DOWNLOAD_REQUEST_DATA);
+
+ m_current_state.sub_state.trans_sub_state = ANTFS_TRANS_SUBSTATE_VERIFY_CRC;
+ }
+}
+
+
+uint32_t antfs_input_data_download(uint16_t index,
+ uint32_t offset,
+ uint32_t num_bytes,
+ const uint8_t * const p_message)
+{
+ // Verify that this is the requested data.
+ APP_ERROR_CHECK_BOOL((offset == m_link_burst_index.data) && (index == m_file_index.data));
+
+ // If file offset is greater than the upper limit, this is not data we need.
+ APP_ERROR_CHECK_BOOL(offset <= m_max_transfer_index.data);
+
+ if ((m_current_state.state == ANTFS_STATE_TRANS) &&
+ (
+ (m_current_state.sub_state.trans_sub_state == ANTFS_TRANS_SUBSTATE_VERIFY_CRC) ||
+ // Only send data if we were processing a download request.
+ (m_current_state.sub_state.trans_sub_state == ANTFS_TRANS_SUBSTATE_DOWNLOADING)
+ )
+ )
+ {
+ uint32_t block_offset = 0;
+
+ if (m_current_state.sub_state.trans_sub_state == ANTFS_TRANS_SUBSTATE_VERIFY_CRC)
+ {
+ // Make sure download_request_response_transmit defaults to RESPONSE_INVALID_CRC.
+ uint32_t response = RESPONSE_MESSAGE_OK;
+
+ // Check CRC.
+ if (m_link_burst_index.data == m_saved_crc_offset)
+ {
+ // If indexes match, we can compare CRC directly.
+ if (m_transfer_crc != m_compared_crc)
+ {
+ response = RESPONSE_INVALID_CRC;
+ }
+ else
+ {
+ // Set up the save point
+ m_temp_crc_offset = m_link_burst_index.data; // Reset save point counter
+ m_saved_crc_offset = m_link_burst_index.data;
+ m_saved_buffer_crc_offset = m_link_burst_index.data;
+
+ // Set up the CRC save points
+ m_saved_transfer_crc = m_compared_crc;
+ m_saved_buffer_crc = m_compared_crc;
+ m_is_crc_pending = true;
+ }
+ // Start bursting beacon and the download response (3 burst packets).
+ download_request_response_transmit(response);
+ }
+ // If the data is in this block, advance to the requested offset
+ else if ((m_link_burst_index.data < m_saved_crc_offset) &&
+ ((m_saved_crc_offset - m_link_burst_index.data) < num_bytes))
+ {
+ // Update the offset within this block for the requested transmission.
+ block_offset = m_saved_crc_offset - m_link_burst_index.data;
+ // Update the number of bytes that will actually be transmitted.
+ num_bytes -= block_offset;
+
+ // Update CRC calculation up to requested index.
+ m_transfer_crc = crc_crc16_update(m_transfer_crc, p_message, block_offset);
+ // Update the remaining number of bytes.
+ m_bytes_remaining.data -= block_offset;
+
+ // Check CRC
+ if (m_transfer_crc != m_compared_crc)
+ {
+ response = RESPONSE_INVALID_CRC;
+ }
+ else
+ {
+ // Move index back to point where transmission will resume.
+ m_link_burst_index.data = m_saved_crc_offset;
+
+ // Set up the save point
+ m_temp_crc_offset = m_link_burst_index.data; // Reset save point counter
+ m_saved_buffer_crc_offset = m_link_burst_index.data;
+
+ // Set up the CRC save points
+ m_saved_transfer_crc = m_compared_crc;
+ m_saved_buffer_crc = m_compared_crc;
+
+ m_is_crc_pending = true;
+ }
+ download_request_response_transmit(response);
+ }
+ // Data index has gone too far and it is not possible to check CRC, fail and let host retry
+ else if (m_link_burst_index.data > m_saved_crc_offset)
+ {
+ response = RESPONSE_INVALID_CRC;
+ download_request_response_transmit(response);
+ }
+ // Keep getting data and recalculate the CRC until the indexes match
+ else
+ {
+ m_is_data_request_pending = false;
+
+ // Update the current burst index and bytes remaining
+ m_link_burst_index.data += num_bytes;
+ m_bytes_remaining.data -= num_bytes;
+
+ // Update CRC
+ m_transfer_crc = crc_crc16_update(m_transfer_crc, p_message, num_bytes);
+
+ // Request more data.
+ event_queue_write(ANTFS_EVENT_DOWNLOAD_REQUEST_DATA);
+ }
+ }
+
+ // Append data.
+ if (m_current_state.sub_state.trans_sub_state == ANTFS_TRANS_SUBSTATE_DOWNLOADING)
+ {
+ uint32_t num_of_bytes_to_burst = num_bytes;
+
+ if (num_of_bytes_to_burst & (BURST_PACKET_SIZE - 1u))
+ {
+ // Round up total number bytes to a multiple of BURST_PACKET_SIZE to be sent to
+ // burst handler.
+ num_of_bytes_to_burst &= ~(BURST_PACKET_SIZE - 1u);
+ num_of_bytes_to_burst += BURST_PACKET_SIZE;
+ }
+
+ uint32_t err_code = sd_ant_burst_handler_request(ANTFS_CONFIG_CHANNEL_NUMBER,
+ num_of_bytes_to_burst,
+ (uint8_t*)&(p_message[block_offset]),
+ BURST_SEGMENT_CONTINUE);
+ if (err_code != NRF_ANT_ERROR_TRANSFER_SEQUENCE_NUMBER_ERROR)
+ {
+ // If burst failed before we are able to catch it, we will get a TRANSFER_SEQUENCE_NUMBER_ERROR
+ // The message processing will send client back to correct state
+ APP_ERROR_CHECK(err_code);
+ }
+
+ wait_burst_request_to_complete();
+
+ // Update current burst index.
+ m_link_burst_index.data += num_bytes;
+ // Update remaining bytes.
+ m_bytes_remaining.data -= num_bytes;
+
+ m_is_data_request_pending = false;
+
+ m_transfer_crc = crc_crc16_update(m_transfer_crc,
+ &(p_message[block_offset]),
+ num_bytes);
+
+ if ((m_link_burst_index.data - m_temp_crc_offset) > SAVE_DISTANCE)
+ {
+ // Set CRC save point
+ m_saved_transfer_crc = m_saved_buffer_crc; // Set CRC at buffer save point (will always be one behind to account for buffering)
+ m_saved_buffer_crc = m_transfer_crc; // Set CRC at save point
+
+ // Set offset save point
+ m_saved_crc_offset = m_saved_buffer_crc_offset; // Set offset at buffer save point (will always be one behind to account for buffering)
+ m_saved_buffer_crc_offset = m_link_burst_index.data; // Set buffer offset to current data offset
+
+ // Reset save counter offset
+ m_temp_crc_offset = m_link_burst_index.data; // Set to current location; next save point will take place after SAVE_DISTANCE bytes
+ }
+
+ if (!m_is_data_request_pending && (m_link_burst_index.data < m_max_transfer_index.data))
+ {
+ // If we have not finished the download.
+
+ // Request more data.
+ event_queue_write(ANTFS_EVENT_DOWNLOAD_REQUEST_DATA);
+
+ m_is_data_request_pending = true;
+ }
+ else if (m_link_burst_index.data >= m_max_transfer_index.data && m_is_crc_pending)
+ {
+ // We are done, send CRC footer.
+
+ uint8_t tx_buffer[BURST_PACKET_SIZE];
+
+ tx_buffer[0] = 0;
+ tx_buffer[1] = 0;
+ tx_buffer[2] = 0;
+ tx_buffer[3] = 0;
+ tx_buffer[4] = 0;
+ tx_buffer[5] = 0;
+ tx_buffer[6] = (uint8_t)m_transfer_crc;
+ tx_buffer[7] = (uint8_t)(m_transfer_crc >> 8u);
+
+ err_code = sd_ant_burst_handler_request(ANTFS_CONFIG_CHANNEL_NUMBER,
+ sizeof(tx_buffer),
+ tx_buffer,
+ BURST_SEGMENT_END);
+ if (err_code != NRF_ANT_ERROR_TRANSFER_SEQUENCE_NUMBER_ERROR)
+ {
+ // If burst failed before we are able to catch it, we will get a TRANSFER_SEQUENCE_NUMBER_ERROR
+ // The message processing will send client back to correct state
+ APP_ERROR_CHECK(err_code);
+ }
+
+ wait_burst_request_to_complete();
+
+ m_is_crc_pending = false;
+ m_max_transfer_index.data = 0;
+ }
+
+ // Return the number of bytes we accepted.
+ return num_bytes;
+ }
+ }
+
+ // No bytes were accepted.
+ return 0;
+}
+
+
+bool antfs_upload_req_resp_transmit(uint8_t response,
+ const antfs_request_info_t * const p_request_info)
+{
+#if ANTFS_CONFIG_UPLOAD_ENABLED
+ if (m_current_state.state != ANTFS_STATE_TRANS ||
+ // Only send the response if we were processing an upload request.
+ (m_link_command_in_progress != ANTFS_CMD_UPLOAD_REQUEST_ID))
+ {
+ return false;
+ }
+
+ // If the application is sending a response for a different file than requested, the upload
+ // will fail.
+ if (p_request_info->file_index.data != m_file_index.data)
+ {
+ event_queue_write(ANTFS_EVENT_UPLOAD_FAIL);
+
+ return false;
+ }
+
+ ulong_union_t max_mem_size;
+ // Set maximum number of bytes that can be written to the file.
+ max_mem_size.data = p_request_info->max_file_size;
+
+ if (p_request_info->max_burst_block_size.data != 0)
+ {
+ // If the client is limiting the block size set the block size requested by the client.
+ m_block_size.data = p_request_info->max_burst_block_size.data;
+ }
+ else
+ {
+ // Try to get the entire file in a single block.
+ m_block_size.data = max_mem_size.data;
+ }
+
+ if (response == 0)
+ {
+ if (m_max_transfer_index.data > max_mem_size.data)
+ {
+ // Not enough space to write file, reject download.
+ response = RESPONSE_MESSAGE_NOT_ENOUGH_SPACE;
+ }
+ }
+
+ // Get last valid CRC and last valid offset.
+ m_transfer_crc = p_request_info->file_crc;
+ m_link_burst_index.data = p_request_info->file_size.data;
+
+ // First packet to transmit is the beacon.
+ beacon_transmit(MESG_BURST_DATA_ID);
+
+ // Second packet.
+
+ uint8_t tx_buffer[BURST_PACKET_SIZE];
+
+ tx_buffer[0] = ANTFS_COMMAND_ID;
+ tx_buffer[1] = ANTFS_RSP_UPLOAD_REQ_ID;
+ tx_buffer[2] = response;
+ tx_buffer[3] = 0;
+ // Last valid data offset written to the file.
+ tx_buffer[4] = m_link_burst_index.bytes.byte0;
+ tx_buffer[5] = m_link_burst_index.bytes.byte1;
+ tx_buffer[6] = m_link_burst_index.bytes.byte2;
+ tx_buffer[7] = m_link_burst_index.bytes.byte3;
+
+
+ uint32_t err_code = sd_ant_burst_handler_request(ANTFS_CONFIG_CHANNEL_NUMBER,
+ sizeof(tx_buffer),
+ tx_buffer,
+ BURST_SEGMENT_CONTINUE);
+ APP_ERROR_CHECK(err_code);
+
+ wait_burst_request_to_complete();
+
+ // Third packet.
+
+ // Maximum number of bytes that can be written to the file.
+ tx_buffer[0] = max_mem_size.bytes.byte0;
+ tx_buffer[1] = max_mem_size.bytes.byte1;
+ tx_buffer[2] = max_mem_size.bytes.byte2;
+ tx_buffer[3] = max_mem_size.bytes.byte3;
+ // Maximum upload block size.
+ tx_buffer[4] = m_block_size.bytes.byte0;
+ tx_buffer[5] = m_block_size.bytes.byte1;
+ tx_buffer[6] = m_block_size.bytes.byte2;
+ tx_buffer[7] = m_block_size.bytes.byte3;
+
+ err_code = sd_ant_burst_handler_request(ANTFS_CONFIG_CHANNEL_NUMBER,
+ sizeof(tx_buffer),
+ tx_buffer,
+ BURST_SEGMENT_CONTINUE);
+ APP_ERROR_CHECK(err_code);
+
+ wait_burst_request_to_complete();
+
+ // Fourth packet.
+
+ tx_buffer[0] = 0;
+ tx_buffer[1] = 0;
+ tx_buffer[2] = 0;
+ tx_buffer[3] = 0;
+ tx_buffer[4] = 0;
+ tx_buffer[5] = 0;
+ // Value of CRC at last data offset.
+ tx_buffer[6] = (uint8_t) m_transfer_crc;
+ tx_buffer[7] = (uint8_t)(m_transfer_crc >> 8);
+
+ err_code = sd_ant_burst_handler_request(ANTFS_CONFIG_CHANNEL_NUMBER,
+ sizeof(tx_buffer),
+ tx_buffer,
+ BURST_SEGMENT_END);
+ APP_ERROR_CHECK(err_code);
+
+ wait_burst_request_to_complete();
+
+ m_link_command_in_progress = ANTFS_CMD_UPLOAD_REQUEST_ID;
+
+ if (response != 0)
+ {
+ // Failed upload request. Reset max transfer index to 0 (do not accept any data if the host
+ // sends it anyway).
+ m_max_transfer_index.data = 0;
+ }
+ else
+ {
+ // Wait for upload data request.
+ m_current_state.sub_state.trans_sub_state = ANTFS_TRANS_SUBSTATE_UPLOAD_WAIT_FOR_DATA;
+ }
+
+ return true;
+#else
+ return false;
+#endif // ANTFS_CONFIG_UPLOAD_ENABLED
+}
+
+
+bool antfs_upload_data_resp_transmit(bool data_upload_success)
+{
+#if ANTFS_CONFIG_UPLOAD_ENABLED
+ // Should be in TRANSPORT layer to send this response.
+ if (m_current_state.state != ANTFS_STATE_TRANS)
+ {
+ return false;
+ }
+
+ uint8_t tx_buffer[BURST_PACKET_SIZE];
+
+ // Response.
+ tx_buffer[0] = ANTFS_COMMAND_ID;
+ tx_buffer[1] = ANTFS_RSP_UPLOAD_DATA_ID;
+ tx_buffer[2] = (data_upload_success) ? RESPONSE_MESSAGE_OK : RESPONSE_MESSAGE_FAIL;
+ tx_buffer[3] = 0;
+ tx_buffer[4] = 0;
+ tx_buffer[5] = 0;
+ tx_buffer[6] = 0;
+ tx_buffer[7] = 0;
+
+ // First packet is beacon.
+ beacon_transmit(MESG_BURST_DATA_ID);
+
+ // Send last packet.
+ uint32_t err_code = sd_ant_burst_handler_request(ANTFS_CONFIG_CHANNEL_NUMBER,
+ sizeof(tx_buffer),
+ tx_buffer,
+ BURST_SEGMENT_END);
+ APP_ERROR_CHECK(err_code);
+
+ wait_burst_request_to_complete();
+
+ m_link_command_in_progress = ANTFS_CMD_UPLOAD_REQUEST_ID;
+
+ // Reset maximum index.
+ m_max_transfer_index.data = 0;
+
+ return true;
+#else
+ return false;
+#endif // ANTFS_CONFIG_UPLOAD_ENABLED
+}
+
+
+void antfs_erase_req_resp_transmit(uint8_t response)
+{
+ // This function should only be called after receiving an erase request.
+ APP_ERROR_CHECK_BOOL((m_current_state.state == ANTFS_STATE_TRANS) &&
+ (m_link_command_in_progress == ANTFS_CMD_ERASE_ID));
+
+ beacon_transmit(MESG_BURST_DATA_ID);
+
+ uint8_t tx_buffer[BURST_PACKET_SIZE];
+
+ // Erase response.
+ tx_buffer[0] = ANTFS_COMMAND_ID;
+ tx_buffer[1] = ANTFS_RSP_ERASE_ID;
+ tx_buffer[2] = response;
+ tx_buffer[3] = 0;
+ tx_buffer[4] = 0;
+ tx_buffer[5] = 0;
+ tx_buffer[6] = 0;
+ tx_buffer[7] = 0;
+
+ uint32_t err_code = sd_ant_burst_handler_request(ANTFS_CONFIG_CHANNEL_NUMBER,
+ sizeof(tx_buffer),
+ tx_buffer,
+ BURST_SEGMENT_END);
+ APP_ERROR_CHECK(err_code);
+
+ wait_burst_request_to_complete();
+}
+
+
+bool antfs_event_extract(antfs_event_return_t * const p_event)
+{
+ bool return_value = false;
+
+ if (m_event_queue.head != m_event_queue.tail)
+ {
+ // Pending events exist. Copy event parameters into return event.
+ p_event->event = m_event_queue.p_queue[m_event_queue.tail].event;
+ p_event->file_index = m_event_queue.p_queue[m_event_queue.tail].file_index;
+ p_event->offset = m_event_queue.p_queue[m_event_queue.tail].offset;
+ p_event->bytes = m_event_queue.p_queue[m_event_queue.tail].bytes;
+ p_event->crc = m_event_queue.p_queue[m_event_queue.tail].crc;
+ memcpy(p_event->data,
+ m_event_queue.p_queue[m_event_queue.tail].data,
+ sizeof(p_event->data));
+
+ // Release the event queue.
+ m_event_queue.tail = ((m_event_queue.tail + 1u) & (ANTFS_EVENT_QUEUE_SIZE - 1u));
+
+ return_value = true;
+ }
+
+ return return_value;
+}
+
+
+/**@brief Function for setting the channel period.
+ *
+ * Sets the channel period. The only allowed frequencies are 0.5, 1, 2, 4 and 8 Hz.
+ *
+ * @param[in] link_period Link period for the beacon transmission.
+ */
+static void channel_period_set(uint32_t link_period)
+{
+ uint32_t period;
+
+ switch (link_period)
+ {
+ default:
+ // Shouldn't happen, but just in case default to 0,5Hz.
+ case BEACON_PERIOD_0_5_HZ:
+ period = 65535u;
+ break;
+
+ case BEACON_PERIOD_1_HZ:
+ period = 32768u;
+ break;
+
+ case BEACON_PERIOD_2_HZ:
+ period = 16384u;
+ break;
+
+ case BEACON_PERIOD_4_HZ:
+ period = 8192u;
+ break;
+
+ case BEACON_PERIOD_8_HZ:
+ period = 4096u;
+ break;
+ }
+
+ const uint32_t err_code = sd_ant_channel_period_set(ANTFS_CONFIG_CHANNEL_NUMBER, period);
+ APP_ERROR_CHECK(err_code);
+}
+
+
+/**@brief Function for starting ANT-FS timeout.
+ *
+ * @param[in] timeout_in_secs Timeout requested in unit of seconds.
+ */
+static void timeout_start(uint32_t timeout_in_secs)
+{
+ uint32_t err_code = app_timer_stop(m_timer_id);
+ APP_ERROR_CHECK(err_code);
+
+ err_code = app_timer_start(m_timer_id,
+ APP_TIMER_TICKS((uint32_t)(timeout_in_secs * 1000u)),
+ NULL);
+ APP_ERROR_CHECK(err_code);
+}
+
+
+/**@brief Function for switching to authentication layer.
+ */
+static void authenticate_layer_transit(void)
+{
+ if (m_current_state.state != ANTFS_STATE_OFF)
+ {
+ m_current_state.state = ANTFS_STATE_AUTH;
+ m_current_state.sub_state.auth_sub_state = ANTFS_AUTH_SUBSTATE_NONE;
+ m_link_command_in_progress = ANTFS_CMD_NONE;
+
+ timeout_start(ANTFS_CONFIG_LINK_COMMAND_TIMEOUT);
+
+ uint32_t err_code = sd_ant_channel_radio_freq_set(ANTFS_CONFIG_CHANNEL_NUMBER, m_active_beacon_frequency);
+ APP_ERROR_CHECK(err_code);
+
+ event_queue_write(ANTFS_EVENT_AUTH);
+ }
+}
+
+
+/**@brief Function for decoding an ANT-FS command received at the link layer.
+ *
+ * @param[in] p_command_buffer The ANT-FS command buffer.
+ */
+static void link_layer_cmd_decode(const uint8_t * p_command_buffer)
+{
+ if (p_command_buffer[ANTFS_CONNECTION_TYPE_OFFSET] != ANTFS_COMMAND_ID)
+ {
+ return;
+ }
+
+ switch (p_command_buffer[ANTFS_COMMAND_OFFSET])
+ {
+ case ANTFS_CMD_LINK_ID:
+ // Channel frequency.
+ m_active_beacon_frequency =
+ p_command_buffer[TRANSPORT_CHANNEL_FREQUENCY_OFFSET];
+ // Channel message period.
+ m_active_beacon_status1_field.parameters.link_period =
+ p_command_buffer[TRANSPORT_MESSAGE_PERIOD_OFFSET];
+ // Host serial Number.
+ m_link_host_serial_number.bytes.byte0 =
+ p_command_buffer[HOST_ID_OFFSET_0];
+ m_link_host_serial_number.bytes.byte1 =
+ p_command_buffer[HOST_ID_OFFSET_1];
+ m_link_host_serial_number.bytes.byte2 =
+ p_command_buffer[HOST_ID_OFFSET_2];
+ m_link_host_serial_number.bytes.byte3 =
+ p_command_buffer[HOST_ID_OFFSET_3];
+
+ // Move to the channel period issued by the host.
+ channel_period_set(m_active_beacon_status1_field.parameters.link_period);
+
+ authenticate_layer_transit();
+ break;
+
+ default:
+ break;
+ }
+}
+
+
+/**@brief Function for switching to link layer.
+ */
+static void link_layer_transit(void)
+{
+ if (m_current_state.state != ANTFS_STATE_OFF)
+ {
+ uint32_t err_code;
+#if ANTFS_CONFIG_DEBUG_LED_ENABLED
+ err_code = bsp_indication_set(BSP_INDICATE_IDLE);
+ APP_ERROR_CHECK(err_code);
+#endif // ANTFS_CONFIG_DEBUG_LED_ENABLED
+
+ m_current_state.state = ANTFS_STATE_LINK;
+ m_current_state.sub_state.link_sub_state = ANTFS_LINK_SUBSTATE_NONE;
+ m_link_command_in_progress = ANTFS_CMD_NONE;
+ m_active_beacon_status1_field = m_initial_parameters.beacon_status_byte1;
+ m_active_beacon_frequency = m_initial_parameters.beacon_frequency;
+
+ timeout_disable();
+
+ err_code = sd_ant_channel_radio_freq_set(ANTFS_CONFIG_CHANNEL_NUMBER, m_active_beacon_frequency);
+ APP_ERROR_CHECK(err_code);
+
+ event_queue_write(ANTFS_EVENT_LINK);
+ }
+}
+
+
+/**@brief Function for decoding an ANT-FS command received at the authenticate layer.
+ *
+ * @param[in] control_byte The command control byte.
+ * @param[in] p_command_buffer The ANT-FS command buffer.
+ */
+static void authenticate_layer_cmd_decode(uint8_t control_byte,
+ const uint8_t * p_command_buffer)
+{
+ // @note: Response variable must have a static storage allocation as it keeps track of the
+ // passkey authentication progress between multiple burst packets.
+#if ANTFS_CONFIG_AUTH_TYPE_PASSKEY_ENABLED
+ static uint32_t response;
+#endif // ANTFS_CONFIG_AUTH_TYPE_PASSKEY_ENABLED
+
+ if ((control_byte & ~SEQUENCE_LAST_MESSAGE) == 0 && m_link_command_in_progress != ANTFS_CMD_NONE)
+ {
+ // This is something new, and we're busy processing something already, so don't respond
+ return;
+ }
+
+ if (p_command_buffer[ANTFS_CONNECTION_TYPE_OFFSET] == ANTFS_COMMAND_ID &&
+ m_link_command_in_progress == ANTFS_CMD_NONE)
+ {
+ if (p_command_buffer[ANTFS_COMMAND_OFFSET] == ANTFS_CMD_AUTHENTICATE_ID)
+ {
+ // Make sure it is the correct host
+ if (m_link_host_serial_number.bytes.byte0 != p_command_buffer[HOST_ID_OFFSET_0] ||
+ m_link_host_serial_number.bytes.byte1 != p_command_buffer[HOST_ID_OFFSET_1] ||
+ m_link_host_serial_number.bytes.byte2 != p_command_buffer[HOST_ID_OFFSET_2] ||
+ m_link_host_serial_number.bytes.byte3 != p_command_buffer[HOST_ID_OFFSET_3])
+ return;
+
+ m_link_command_in_progress = ANTFS_CMD_AUTHENTICATE_ID;
+ m_authenticate_command_type = p_command_buffer[COMMAND_TYPE_OFFSET];
+ m_retry = AUTHENTICATION_RETRIES;
+ }
+ }
+
+ if (m_link_command_in_progress == ANTFS_CMD_AUTHENTICATE_ID)
+ {
+ switch (m_authenticate_command_type)
+ {
+ case COMMAND_TYPE_REQUEST_SERIAL:
+ if (control_byte & SEQUENCE_LAST_MESSAGE)
+ {
+ // Don't do anything before the burst completes (last burst message received).
+ timeout_start(ANTFS_CONFIG_LINK_COMMAND_TIMEOUT);
+ authenticate_response_transmit(AUTH_RESPONSE_N_A,
+ ANTFS_REMOTE_FRIENDLY_NAME_MAX,
+ // Send device friendly name if it exists.
+ m_initial_parameters.p_remote_friendly_name);
+ }
+ break;
+
+#if ANTFS_CONFIG_AUTH_TYPE_PASSTHROUGH_ENABLED
+ case COMMAND_TYPE_PROCEED:
+ if (control_byte & SEQUENCE_LAST_MESSAGE)
+ {
+ // Don't do anything before the burst completes (last burst message received).
+ timeout_start(ANTFS_CONFIG_LINK_COMMAND_TIMEOUT);
+ // Proceed directly to transport layer (no authentication required).
+ authenticate_response_transmit(AUTH_RESPONSE_ACCEPT, 0, NULL);
+ }
+ break;
+
+#endif // ANTFS_CONFIG_AUTH_TYPE_PASSTHROUGH_ENABLED
+#if ANTFS_CONFIG_AUTH_TYPE_PAIRING_ENABLED
+ case COMMAND_TYPE_REQUEST_PAIR:
+ if ((control_byte & SEQUENCE_NUMBER_ROLLOVER) == 0)
+ {
+ // First burst packet.
+
+ // Friendly name length.
+ m_friendly_name.friendly_name_size =
+ p_command_buffer[AUTH_STRING_LENGTH_OFFSET];
+
+ if (m_friendly_name.friendly_name_size > 0)
+ {
+ if (m_friendly_name.friendly_name_size > ANTFS_FRIENDLY_NAME_MAX)
+ {
+ m_friendly_name.friendly_name_size = ANTFS_FRIENDLY_NAME_MAX;
+ }
+
+ m_friendly_name.index = 0;
+ }
+ }
+ else
+ {
+ // Next burst packets: read host friendly name.
+
+ if (m_friendly_name.index < ANTFS_FRIENDLY_NAME_MAX)
+ {
+ uint32_t num_of_bytes = ANTFS_FRIENDLY_NAME_MAX - m_friendly_name.index;
+ if (num_of_bytes > 8u)
+ {
+ num_of_bytes = 8u;
+ }
+ memcpy((uint8_t*)&m_friendly_name.friendly_name[m_friendly_name.index],
+ p_command_buffer,
+ num_of_bytes);
+ m_friendly_name.index += num_of_bytes;
+ }
+ }
+
+ if (control_byte & SEQUENCE_LAST_MESSAGE)
+ {
+ // Last burst packet.
+
+ timeout_start(ANTFS_CONFIG_PAIRING_TIMEOUT);
+ if (m_friendly_name.friendly_name_size > 0)
+ {
+ m_friendly_name.is_name_set = true;
+ }
+
+ m_current_state.sub_state.auth_sub_state = ANTFS_AUTH_SUBSTATE_PAIR;
+ // If pairing is supported, send request to UI.
+ event_queue_write(ANTFS_EVENT_PAIRING_REQUEST);
+ }
+ break;
+
+#endif // ANTFS_CONFIG_AUTH_TYPE_PAIRING_ENABLED
+#if ANTFS_CONFIG_AUTH_TYPE_PASSKEY_ENABLED
+ case COMMAND_TYPE_REQUEST_PASSKEY:
+ if ((control_byte & SEQUENCE_NUMBER_ROLLOVER) == 0)
+ {
+ // First burst packet.
+
+ // Passkey length.
+ const uint32_t passkey_size = p_command_buffer[AUTH_STRING_LENGTH_OFFSET];
+
+ // Default the algorithm to accept.
+ response = AUTH_RESPONSE_ACCEPT;
+
+ // Check if the passkey length is valid.
+ if (passkey_size == ANTFS_PASSKEY_SIZE)
+ {
+ m_passkey_index = 0;
+ }
+ else
+ {
+ // Invalid lenght supplied - the authentication will be rejected.
+ response = AUTH_RESPONSE_REJECT;
+ }
+ }
+ else
+ {
+ // Next burst packets: read host friendly name.
+
+ if ((response == AUTH_RESPONSE_ACCEPT) &&
+ // Prevent buffer overrun.
+ (m_passkey_index != ANTFS_PASSKEY_SIZE))
+ {
+ // Passkey length was valid and the host supplied key matches so far.
+ uint32_t idx = 0;
+
+ // Check the current received burst packet for passkey match.
+ do
+ {
+ if (m_initial_parameters.p_pass_key[m_passkey_index++] !=
+ p_command_buffer[idx])
+ {
+ // Reject the authentication request and further processing of
+ // passkey matching if a mismatch is found.
+ response = AUTH_RESPONSE_REJECT;
+ break;
+ }
+
+ ++idx;
+ }
+ while (idx < BURST_PACKET_SIZE);
+ }
+ }
+
+ if (control_byte & SEQUENCE_LAST_MESSAGE)
+ {
+ // Last burst packet.
+
+ if (m_passkey_index < ANTFS_PASSKEY_SIZE)
+ {
+ // We did not get the complete passkey, reject authentication request.
+ response = AUTH_RESPONSE_REJECT;
+ }
+
+ timeout_start(ANTFS_CONFIG_LINK_COMMAND_TIMEOUT);
+ m_current_state.sub_state.auth_sub_state = ANTFS_AUTH_SUBSTATE_PASSKEY;
+ authenticate_response_transmit(response, 0, NULL);
+ }
+ break;
+
+#endif // ANTFS_CONFIG_AUTH_TYPE_PASSKEY_ENABLED
+ default:
+ break;
+ }
+ }
+ else if (p_command_buffer[ANTFS_COMMAND_OFFSET] == ANTFS_CMD_DISCONNECT_ID)
+ {
+ if (control_byte & SEQUENCE_LAST_MESSAGE)
+ {
+ // Don't do anything before the burst completes (last burst message received).
+ link_layer_transit();
+ }
+ }
+ else if (p_command_buffer[ANTFS_COMMAND_OFFSET] == ANTFS_CMD_PING_ID)
+ {
+ // Reset timeout.
+ timeout_start(ANTFS_CONFIG_LINK_COMMAND_TIMEOUT);
+ m_link_command_in_progress = ANTFS_CMD_NONE;
+ }
+ else
+ {
+ // No implementation needed.
+ }
+}
+
+
+/**@brief Function for decoding an ANT-FS command received at the transport layer.
+ *
+ * @param[in] control_byte The command control byte.
+ * @param[in] p_command_buffer The ANT-FS command buffer.
+ */
+static void transport_layer_cmd_decode(uint8_t control_byte, const uint8_t * p_command_buffer)
+{
+ ulong_union_t host_serial_number = {0};
+
+ if (p_command_buffer[ANTFS_CONNECTION_TYPE_OFFSET] == ANTFS_COMMAND_ID)
+ {
+ m_link_command_in_progress = p_command_buffer[ANTFS_COMMAND_OFFSET];
+ }
+
+ switch (m_link_command_in_progress)
+ {
+ case ANTFS_CMD_PING_ID:
+ // Reset timeout.
+ timeout_start(ANTFS_CONFIG_LINK_COMMAND_TIMEOUT);
+ m_link_command_in_progress = ANTFS_CMD_NONE;
+ break;
+
+ case ANTFS_CMD_DISCONNECT_ID:
+ if (control_byte & SEQUENCE_LAST_MESSAGE)
+ {
+ // Don't do anything before the burst completes (last burst message received).
+ link_layer_transit();
+ }
+ break;
+
+ case ANTFS_CMD_ERASE_ID:
+ if (control_byte & SEQUENCE_LAST_MESSAGE)
+ {
+ // Don't do anything before the burst completes (last burst message received).
+
+ // Requested index.
+ m_file_index.bytes.low = p_command_buffer[DATA_INDEX_OFFSET_LOW];
+ m_file_index.bytes.high = p_command_buffer[DATA_INDEX_OFFSET_HIGH];
+
+ // Send erase request to the application.
+ event_queue_write(ANTFS_EVENT_ERASE_REQUEST);
+ timeout_start(ANTFS_CONFIG_LINK_COMMAND_TIMEOUT);
+ m_link_command_in_progress = ANTFS_CMD_ERASE_ID;
+ }
+ break;
+
+ case ANTFS_CMD_DOWNLOAD_ID:
+ if (m_current_state.sub_state.trans_sub_state != ANTFS_TRANS_SUBSTATE_NONE)
+ {
+ // Ignore the command if we are busy.
+ break;
+ }
+
+ if ((control_byte & ~SEQUENCE_LAST_MESSAGE) == 0x00)
+ {
+ // First burst packet.
+
+ if ((m_file_index.bytes.low != p_command_buffer[DATA_INDEX_OFFSET_LOW]) ||
+ (m_file_index.bytes.high != p_command_buffer[DATA_INDEX_OFFSET_HIGH]))
+ {
+ // This is a new index, so we can not check the CRC against the previous saved
+ // CRC.
+
+ // CRC seed checking is made invalid by setting the last saved offset to the
+ // maximum file size.
+ m_saved_crc_offset = ANTFS_MAX_FILE_SIZE;
+ }
+
+ // Requested data file index.
+ m_file_index.bytes.low = p_command_buffer[DATA_INDEX_OFFSET_LOW];
+ m_file_index.bytes.high = p_command_buffer[DATA_INDEX_OFFSET_HIGH];
+
+ // Initialize current position in the TX burst to the requested offset.
+ m_link_burst_index.bytes.byte0 = p_command_buffer[ADDRESS_PARAMETER_OFFSET_0];
+ m_link_burst_index.bytes.byte1 = p_command_buffer[ADDRESS_PARAMETER_OFFSET_1];
+ m_link_burst_index.bytes.byte2 = p_command_buffer[ADDRESS_PARAMETER_OFFSET_2];
+ m_link_burst_index.bytes.byte3 = p_command_buffer[ADDRESS_PARAMETER_OFFSET_3];
+ }
+ else if (control_byte & SEQUENCE_LAST_MESSAGE)
+ {
+ // Last burst packet (download command should be two packets long).
+
+ // Get CRC seed from host.
+ m_compared_crc = (uint16_t)p_command_buffer[DATA_INDEX_OFFSET_LOW];
+ m_compared_crc |= ((uint16_t)p_command_buffer[DATA_INDEX_OFFSET_HIGH] << 8u);
+
+ // Maximum block size allowed by host.
+ m_max_block_size.bytes.byte0 = p_command_buffer[ADDRESS_PARAMETER_OFFSET_0];
+ m_max_block_size.bytes.byte1 = p_command_buffer[ADDRESS_PARAMETER_OFFSET_1];
+ m_max_block_size.bytes.byte2 = p_command_buffer[ADDRESS_PARAMETER_OFFSET_2];
+ m_max_block_size.bytes.byte3 = p_command_buffer[ADDRESS_PARAMETER_OFFSET_3];
+
+ // Initialize number of remaining bytes for this block to the maximum block size.
+ m_bytes_remaining.data = m_max_block_size.data;
+
+ if (p_command_buffer[INITIAL_REQUEST_OFFSET])
+ {
+ // This request is the start of a new transfer.
+
+ // Initialize data offset for CRC calculation to the requested data offset.
+ m_saved_crc_offset = m_link_burst_index.data;
+ m_saved_buffer_crc_offset = m_link_burst_index.data;
+
+ // Use CRC seed provided by host for CRC checking of the data.
+ m_transfer_crc = m_compared_crc;
+ m_saved_transfer_crc = m_compared_crc;
+ m_saved_buffer_crc = m_compared_crc;
+ m_current_state.sub_state.trans_sub_state = ANTFS_TRANS_SUBSTATE_VERIFY_CRC;
+ }
+ else
+ {
+ // This is a request to resume a partially completed transfer.
+
+ if (m_saved_crc_offset > m_link_burst_index.data)
+ {
+ // We can not check the received CRC seed as the requested offset is before
+ // our last save point.
+
+ // Set CRC checking as invalid.
+ m_saved_crc_offset = ANTFS_MAX_FILE_SIZE;
+ }
+ else
+ {
+ m_current_state.sub_state.trans_sub_state = ANTFS_TRANS_SUBSTATE_VERIFY_CRC;
+ }
+ }
+
+ m_is_data_request_pending = false;
+
+ // Send download request to the application for further handling.
+ event_queue_write(ANTFS_EVENT_DOWNLOAD_REQUEST);
+
+ timeout_start(ANTFS_CONFIG_LINK_COMMAND_TIMEOUT);
+ m_link_command_in_progress = ANTFS_CMD_DOWNLOAD_ID;
+ }
+ break;
+
+ case ANTFS_CMD_UPLOAD_REQUEST_ID:
+#if ANTFS_CONFIG_UPLOAD_ENABLED
+ if ((control_byte & ~SEQUENCE_LAST_MESSAGE) == 0x00)
+ {
+ // First burst packet.
+
+ if ((m_file_index.bytes.low != p_command_buffer[DATA_INDEX_OFFSET_LOW]) ||
+ (
+ (m_file_index.bytes.high != p_command_buffer[DATA_INDEX_OFFSET_HIGH]) ||
+ (m_current_state.sub_state.trans_sub_state == ANTFS_TRANS_SUBSTATE_NONE)
+ )
+ )
+ {
+ // If it is a new index or we completed the last upload.
+
+ // Get the file index.
+ m_file_index.bytes.low = p_command_buffer[DATA_INDEX_OFFSET_LOW];
+ m_file_index.bytes.high = p_command_buffer[DATA_INDEX_OFFSET_HIGH];
+
+ // As this is a new upload, reset save point to the beginning of the file.
+
+ // Set CRC to zero.
+ m_saved_crc_offset = 0;
+ m_saved_transfer_crc = 0;
+ }
+
+ // Get the upper limit of upload from request message.
+ m_max_transfer_index.bytes.byte0 = p_command_buffer[ADDRESS_PARAMETER_OFFSET_0];
+ m_max_transfer_index.bytes.byte1 = p_command_buffer[ADDRESS_PARAMETER_OFFSET_1];
+ m_max_transfer_index.bytes.byte2 = p_command_buffer[ADDRESS_PARAMETER_OFFSET_2];
+ m_max_transfer_index.bytes.byte3 = p_command_buffer[ADDRESS_PARAMETER_OFFSET_3];
+ }
+ else if (control_byte & SEQUENCE_LAST_MESSAGE)
+ {
+ // Last burst (second) packet.
+
+ // Get data offset the requested upload will start at.
+ m_link_burst_index.bytes.byte0 = p_command_buffer[ADDRESS_PARAMETER_OFFSET_0];
+ m_link_burst_index.bytes.byte1 = p_command_buffer[ADDRESS_PARAMETER_OFFSET_1];
+ m_link_burst_index.bytes.byte2 = p_command_buffer[ADDRESS_PARAMETER_OFFSET_2];
+ m_link_burst_index.bytes.byte3 = p_command_buffer[ADDRESS_PARAMETER_OFFSET_3];
+
+ if (m_link_burst_index.data != ANTFS_MAX_FILE_SIZE)
+ {
+ // If this is a new upload.
+
+ // The data offset specified in the upload request will be used.
+ m_saved_crc_offset = m_link_burst_index.data;
+
+ m_saved_transfer_crc = 0;
+ }
+
+ m_transfer_crc = m_saved_transfer_crc;
+
+ // Send upload request to the application for further handling.
+ event_queue_write(ANTFS_EVENT_UPLOAD_REQUEST);
+
+ timeout_start(ANTFS_CONFIG_LINK_COMMAND_TIMEOUT);
+ m_link_command_in_progress = ANTFS_CMD_UPLOAD_REQUEST_ID;
+ }
+#endif // ANTFS_CONFIG_UPLOAD_ENABLED
+ break;
+
+ case ANTFS_CMD_UPLOAD_DATA_ID:
+#if ANTFS_CONFIG_UPLOAD_ENABLED
+ if ((control_byte & ~SEQUENCE_LAST_MESSAGE) == 0x00)
+ {
+ // First burst packet.
+
+ if (m_current_state.sub_state.trans_sub_state ==
+ ANTFS_TRANS_SUBSTATE_UPLOAD_WAIT_FOR_DATA)
+ {
+ antfs_event_t event;
+
+ // Get CRC Seed from host.
+ m_compared_crc = (uint16_t)p_command_buffer[DATA_INDEX_OFFSET_LOW];
+ m_compared_crc |= ((uint16_t)p_command_buffer[DATA_INDEX_OFFSET_HIGH] << 8u);
+
+ // Set download offset.
+ m_link_burst_index.bytes.byte0 = p_command_buffer[ADDRESS_PARAMETER_OFFSET_0];
+ m_link_burst_index.bytes.byte1 = p_command_buffer[ADDRESS_PARAMETER_OFFSET_1];
+ m_link_burst_index.bytes.byte2 = p_command_buffer[ADDRESS_PARAMETER_OFFSET_2];
+ m_link_burst_index.bytes.byte3 = p_command_buffer[ADDRESS_PARAMETER_OFFSET_3];
+
+ if ((m_link_burst_index.data + m_block_size.data) < m_max_transfer_index.data)
+ {
+ // Adjust block size as set by client.
+ m_max_transfer_index.data = m_link_burst_index.data + m_block_size.data;
+ }
+
+ if (m_compared_crc != m_transfer_crc)
+ {
+ // Check that the request matches the CRC sent on the upload response.
+
+ // Do not accept any data.
+ m_max_transfer_index.data = 0;
+
+ // Failure will be reported when upload is done.
+ event = (antfs_event_t)0;
+ }
+
+ // Set ready to receive a file.
+ m_current_state.sub_state.trans_sub_state = ANTFS_TRANS_SUBSTATE_UPLOADING;
+
+ event = ANTFS_EVENT_UPLOAD_START;
+ m_transfer_crc = m_compared_crc;
+
+ if (m_link_burst_index.data > m_max_transfer_index.data)
+ {
+ // If the requested offset is too high.
+
+ // Clear the max transfer index, so we'll report fail when the transfer
+ // finishes.
+ m_max_transfer_index.data = 0;
+ // Clear the event because we normally would not send an event at this point
+ // in this case.
+ event = (antfs_event_t)0;
+ }
+
+ if (control_byte & SEQUENCE_LAST_MESSAGE)
+ {
+ // If this upload contains no data.
+
+ // Leave the upload state.
+ m_current_state.sub_state.trans_sub_state = ANTFS_TRANS_SUBSTATE_NONE;
+
+ // if it was a valid index, report it as a successful upload, otherwise
+ // report it as a failure.
+ if (event == 0)
+ {
+ event = ANTFS_EVENT_UPLOAD_FAIL;
+ }
+ else
+ {
+ event = ANTFS_EVENT_UPLOAD_COMPLETE;
+ }
+ }
+
+ if (event != 0)
+ {
+ event_queue_write(event);
+ }
+ }
+ }
+#endif // ANTFS_CONFIG_UPLOAD_ENABLED
+ break;
+
+ case ANTFS_CMD_LINK_ID:
+ host_serial_number.bytes.byte0 = p_command_buffer[HOST_ID_OFFSET_0];
+ host_serial_number.bytes.byte1 = p_command_buffer[HOST_ID_OFFSET_1];
+ host_serial_number.bytes.byte2 = p_command_buffer[HOST_ID_OFFSET_2];
+ host_serial_number.bytes.byte3 = p_command_buffer[HOST_ID_OFFSET_3];
+
+ if (m_link_host_serial_number.data == host_serial_number.data)
+ {
+ m_active_beacon_frequency = p_command_buffer[TRANSPORT_CHANNEL_FREQUENCY_OFFSET];
+ m_active_beacon_status1_field.parameters.link_period =
+ p_command_buffer[TRANSPORT_MESSAGE_PERIOD_OFFSET];
+
+ const uint32_t err_code = sd_ant_channel_radio_freq_set(ANTFS_CONFIG_CHANNEL_NUMBER,
+ m_active_beacon_frequency);
+ APP_ERROR_CHECK(err_code);
+
+ channel_period_set(m_active_beacon_status1_field.parameters.link_period);
+ }
+
+ m_link_command_in_progress = 0;
+ break;
+
+ default:
+ // Don't do anything, this is an invalid message.
+ m_link_command_in_progress = 0;
+ break;
+ }
+}
+
+
+/**@brief Function for handling data upload.
+ *
+ * @param[in] control_byte The command control byte.
+ * @param[in] p_buffer The data buffer.
+ */
+static void upload_data_process(uint8_t control_byte, const uint8_t * p_buffer)
+{
+#if ANTFS_CONFIG_UPLOAD_ENABLED
+ if (control_byte & SEQUENCE_LAST_MESSAGE)
+ {
+ // Last burst packet: upload complete.
+
+ m_current_state.sub_state.trans_sub_state = ANTFS_TRANS_SUBSTATE_NONE;
+
+ // CRC for data packets contained in this upload block.
+ m_compared_crc = p_buffer[UPLOAD_CRC_OFFSET_LOW ];
+ m_compared_crc |= (p_buffer[UPLOAD_CRC_OFFSET_HIGH] << 8u);
+
+ if (m_max_transfer_index.data && (m_compared_crc == m_transfer_crc))
+ {
+ // CRC OK, upload was completed successfully.
+ event_queue_write(ANTFS_EVENT_UPLOAD_COMPLETE);
+ }
+ else
+ {
+ // CRC mismatch, upload failed.
+ event_queue_write(ANTFS_EVENT_UPLOAD_FAIL);
+ }
+
+ m_max_transfer_index.data = 0;
+ }
+ else
+ {
+ // Not the last burst packet: upload not complete.
+
+ // Set initial number of bytes to 8 (size of burst packet).
+ m_bytes_to_write = BURST_PACKET_SIZE;
+ timeout_start(ANTFS_CONFIG_LINK_COMMAND_TIMEOUT);
+
+ if (m_link_burst_index.data > m_max_transfer_index.data)
+ {
+ // We are past the main index, we do not need to write any more data.
+ m_bytes_to_write = 0;
+ }
+ else
+ {
+ if ((m_bytes_to_write + m_link_burst_index.data) > m_max_transfer_index.data)
+ {
+ // if we're less than 8 bytes away from the end, adjust the number of bytes to write
+ // in this block.
+ m_bytes_to_write = m_max_transfer_index.data - m_link_burst_index.data;
+ }
+ }
+
+ if (m_bytes_to_write != 0)
+ {
+ APP_ERROR_CHECK_BOOL(m_bytes_to_write <= BURST_PACKET_SIZE);
+
+ // Store begin of upload data.
+ mp_upload_data = p_buffer;
+
+ m_transfer_crc = crc_crc16_update(m_transfer_crc, p_buffer, m_bytes_to_write);
+
+ // Send data to application.
+ event_queue_write(ANTFS_EVENT_UPLOAD_DATA);
+
+ // Update current offset.
+ m_link_burst_index.data += m_bytes_to_write;
+
+ // Store save point.
+ m_saved_crc_offset = m_link_burst_index.data;
+ m_saved_transfer_crc = m_transfer_crc;
+ }
+ }
+#endif // ANTFS_CONFIG_UPLOAD_ENABLED
+}
+
+
+/**@brief Function for switching to transport layer.
+ */
+static void transport_layer_transit(void)
+{
+ if (m_current_state.state != ANTFS_STATE_OFF)
+ {
+#if ANTFS_CONFIG_DEBUG_LED_ENABLED
+ uint32_t err_code = bsp_indication_set(BSP_INDICATE_IDLE);
+ APP_ERROR_CHECK(err_code);
+#endif // ANTFS_CONFIG_DEBUG_LED_ENABLED
+ m_current_state.state = ANTFS_STATE_TRANS;
+ m_current_state.sub_state.trans_sub_state = ANTFS_TRANS_SUBSTATE_NONE;
+
+ timeout_start(ANTFS_CONFIG_LINK_COMMAND_TIMEOUT);
+
+ beacon_transmit(MESG_BROADCAST_DATA_ID);
+
+ event_queue_write(ANTFS_EVENT_TRANS);
+ }
+}
+
+
+void antfs_message_process(uint8_t * p_message)
+{
+#if ANTFS_CONFIG_DEBUG_LED_ENABLED
+ uint32_t err_code;
+#endif // ANTFS_CONFIG_DEBUG_LED_ENABLED
+
+ if (p_message != NULL)
+ {
+ if ((p_message[BUFFER_INDEX_CHANNEL_NUM] & CHANNEL_NUMBER_MASK) != ANTFS_CONFIG_CHANNEL_NUMBER)
+ {
+ // Only process messages corresponding to the ANT-FS channel here.
+ return;
+ }
+
+ if ((m_current_state.state == ANTFS_STATE_OFF) &&
+ (
+ !(
+ (p_message[BUFFER_INDEX_MESG_ID] == MESG_RESPONSE_EVENT_ID) &&
+ (p_message[BUFFER_INDEX_RESPONSE_CODE] == NO_EVENT)
+ )
+ )
+ )
+ {
+ return;
+ }
+
+ switch (p_message[BUFFER_INDEX_MESG_ID])
+ {
+ case MESG_BROADCAST_DATA_ID:
+ // We are not going to process broadcast messages or pass them to the app to handle.
+ break;
+
+ case MESG_ACKNOWLEDGED_DATA_ID:
+ // Mark it as being the last message if it's an ack message.
+ p_message[ANTFS_CONTROL_OFFSET] |= SEQUENCE_LAST_MESSAGE;
+
+ /* fall-through */
+ case MESG_BURST_DATA_ID:
+ switch (m_current_state.state)
+ {
+ case ANTFS_STATE_LINK:
+ link_layer_cmd_decode(&p_message[ANTFS_DATA_OFFSET]);
+ break;
+
+ case ANTFS_STATE_AUTH:
+ authenticate_layer_cmd_decode(p_message[ANTFS_CONTROL_OFFSET],
+ &p_message[ANTFS_DATA_OFFSET]);
+ break;
+
+ case ANTFS_STATE_TRANS:
+ if (m_current_state.sub_state.trans_sub_state !=
+ ANTFS_TRANS_SUBSTATE_UPLOADING)
+ {
+ transport_layer_cmd_decode(p_message[ANTFS_CONTROL_OFFSET],
+ &p_message[ANTFS_DATA_OFFSET]);
+ }
+ else
+ {
+ upload_data_process(p_message[ANTFS_CONTROL_OFFSET],
+ &p_message[ANTFS_DATA_OFFSET]);
+ }
+ break;
+
+ default:
+ // If in any other state or sub-state, do nothing.
+ break;
+ }
+ break;
+
+ case MESG_RESPONSE_EVENT_ID:
+ // Branch on event ID.
+ switch (p_message[BUFFER_INDEX_RESPONSE_CODE])
+ {
+ case EVENT_TRANSFER_TX_FAILED:
+ m_link_command_in_progress = ANTFS_CMD_NONE;
+ // Switch into the appropriate state after the failure. Must be ready for
+ // the host to do a retry.
+ switch (m_current_state.state)
+ {
+ case ANTFS_STATE_LINK:
+ link_layer_transit();
+ break;
+
+ case ANTFS_STATE_AUTH:
+ // Burst failed, retry sending the response
+ if (!m_retry)
+ {
+ authenticate_layer_transit(); // Reload beacon
+ }
+ else
+ {
+ if (m_current_state.sub_state.auth_sub_state == ANTFS_AUTH_SUBSTATE_ACCEPT)
+ {
+ if (m_authenticate_command_type == COMMAND_TYPE_REQUEST_PAIR)
+ {
+ authenticate_response_transmit(AUTH_RESPONSE_ACCEPT, ANTFS_PASSKEY_SIZE,
+ m_initial_parameters.p_pass_key);
+ }
+ else
+ {
+ authenticate_response_transmit(AUTH_RESPONSE_ACCEPT, 0, NULL);
+ }
+ }
+ else if (m_current_state.sub_state.auth_sub_state == ANTFS_AUTH_SUBSTATE_REJECT)
+ {
+ authenticate_response_transmit(AUTH_RESPONSE_REJECT, 0, NULL);
+ }
+ else if (m_authenticate_command_type == COMMAND_TYPE_REQUEST_SERIAL)
+ {
+ authenticate_response_transmit(AUTH_RESPONSE_N_A,
+ ANTFS_REMOTE_FRIENDLY_NAME_MAX,
+ // Send device friendly name if it exists.
+ m_initial_parameters.p_remote_friendly_name);
+ }
+ else
+ {
+ // No implementation needed
+ }
+
+ m_retry--;
+ }
+
+ break;
+
+ case ANTFS_STATE_TRANS:
+ if (m_current_state.sub_state.trans_sub_state ==
+ ANTFS_TRANS_SUBSTATE_DOWNLOADING)
+ {
+ event_queue_write(ANTFS_EVENT_DOWNLOAD_FAIL);
+ }
+ transport_layer_transit();
+ break;
+
+ default:
+ // No implementation needed.
+ break;
+ }
+ break;
+
+ case EVENT_TRANSFER_RX_FAILED:
+ m_link_command_in_progress = ANTFS_CMD_NONE;
+
+ if (m_current_state.sub_state.trans_sub_state ==
+ ANTFS_TRANS_SUBSTATE_UPLOADING)
+ {
+ event_queue_write(ANTFS_EVENT_UPLOAD_FAIL);
+
+ m_current_state.sub_state.trans_sub_state =
+ ANTFS_TRANS_SUBSTATE_UPLOAD_RESUME;
+ }
+ else
+ {
+ // No implementation needed
+ }
+
+ break;
+
+ case EVENT_TRANSFER_TX_COMPLETED:
+ m_link_command_in_progress = ANTFS_CMD_NONE;
+
+ // Switch into appropiate state after successful command.
+ switch (m_current_state.state)
+ {
+ case ANTFS_STATE_AUTH:
+ if (m_current_state.sub_state.auth_sub_state ==
+ ANTFS_AUTH_SUBSTATE_ACCEPT)
+ {
+ // We passed authentication, so go to transport state.
+ transport_layer_transit();
+ }
+ else if (m_current_state.sub_state.auth_sub_state ==
+ ANTFS_AUTH_SUBSTATE_REJECT)
+ {
+ // We failed authentication, so go to link state.
+ link_layer_transit();
+ }
+ else
+ {
+ // Reload beacon.
+ authenticate_layer_transit();
+ }
+ break;
+
+ case ANTFS_STATE_TRANS:
+ if (m_current_state.sub_state.trans_sub_state ==
+ ANTFS_TRANS_SUBSTATE_DOWNLOADING)
+ {
+ event_queue_write(ANTFS_EVENT_DOWNLOAD_COMPLETE);
+ }
+ if (m_current_state.sub_state.trans_sub_state !=
+ ANTFS_TRANS_SUBSTATE_UPLOAD_WAIT_FOR_DATA)
+ {
+ transport_layer_transit(); // Reload beacon.
+ }
+ break;
+
+ default:
+ link_layer_transit(); // Reload beacon.
+ break;
+ }
+ break;
+
+ case EVENT_TX:
+#if ANTFS_CONFIG_DEBUG_LED_ENABLED
+ err_code = bsp_indication_set(BSP_INDICATE_SENT_OK);
+ APP_ERROR_CHECK(err_code);
+#endif // ANTFS_CONFIG_DEBUG_LED_ENABLED
+ // Load beacon.
+ beacon_transmit(MESG_BROADCAST_DATA_ID);
+ break;
+
+ case EVENT_CHANNEL_CLOSED:
+ event_queue_write(ANTFS_EVENT_CLOSE_COMPLETE);
+ break;
+
+ case NO_EVENT:
+ // This shouldn't happen... command responses should not occur.
+ APP_ERROR_HANDLER(p_message[BUFFER_INDEX_RESPONSE_CODE]);
+ break;
+
+ default:
+ // No implementation needed.
+ return;
+ }
+ break;
+
+ default:
+ // No implementation needed.
+ return;
+ }
+ }
+}
+
+
+void antfs_channel_setup(void)
+{
+ // Start channel configuration.
+ uint32_t err_code = ant_fs_key_set(ANTFS_CONFIG_NETWORK_NUMBER);
+ APP_ERROR_CHECK(err_code);
+
+ err_code = sd_ant_channel_assign(ANTFS_CONFIG_CHANNEL_NUMBER,
+ ANTFS_CHANNEL_TYPE,
+ ANTFS_CONFIG_NETWORK_NUMBER,
+ 0);
+ APP_ERROR_CHECK(err_code);
+
+ // Use the lower 2 bytes of the ESN for device number.
+ uint16_t device_number = (uint16_t)(m_initial_parameters.client_serial_number & 0x0000FFFFu);
+ if (device_number == 0)
+ {
+ // Device number of 0 is not allowed.
+ device_number = 2;
+ }
+
+ err_code = sd_ant_channel_id_set(ANTFS_CONFIG_CHANNEL_NUMBER,
+ device_number,
+ ANTFS_CONFIG_DEVICE_TYPE,
+ ANTFS_CONFIG_TRANS_TYPE);
+ APP_ERROR_CHECK(err_code);
+
+ // Remain in initialization state until channel is open.
+ m_current_state.state = ANTFS_STATE_INIT;
+ // @note: Channel frequency is set by function below.
+ link_layer_transit();
+ m_current_state.state = ANTFS_STATE_INIT;
+
+ channel_period_set(m_active_beacon_status1_field.parameters.link_period);
+
+ err_code = sd_ant_channel_open(ANTFS_CONFIG_CHANNEL_NUMBER);
+ APP_ERROR_CHECK(err_code);
+
+ err_code = sd_ant_channel_radio_tx_power_set(ANTFS_CONFIG_CHANNEL_NUMBER,
+ ANTFS_CONFIG_TRANSMIT_POWER,
+ ANTFS_CONFIG_CUSTOM_TRANSMIT_POWER);
+ APP_ERROR_CHECK(err_code);
+
+ m_current_state.state = ANTFS_STATE_LINK;
+ m_current_state.sub_state.link_sub_state = ANTFS_LINK_SUBSTATE_NONE;
+
+ event_queue_write(ANTFS_EVENT_OPEN_COMPLETE);
+
+ // Start beacon broadcast.
+ beacon_transmit(MESG_BROADCAST_DATA_ID);
+}
+
+
+/**@brief Function for resetting the ANT-FS state machine.
+ */
+static void state_machine_reset(void)
+{
+ m_current_state.state = ANTFS_STATE_OFF;
+ m_link_command_in_progress = ANTFS_CMD_NONE;
+
+ timeout_disable();
+
+ // Reset the ANT-FS event queue.
+ m_event_queue.p_queue = m_event_queue_buffer;
+ m_event_queue.head = 0;
+ m_event_queue.tail = 0;
+
+ // Set as invalid.
+ m_authenticate_command_type = 0xFFu;
+ m_retry = 0;
+
+ m_saved_crc_offset = 0xFFFFFFFFu;
+ m_max_transfer_index.data = 0;
+ m_is_crc_pending = false;
+ m_is_data_request_pending = false;
+
+ m_friendly_name.is_name_set = false;
+ m_friendly_name.index = 0;
+
+ memset(m_friendly_name.friendly_name, 0, ANTFS_FRIENDLY_NAME_MAX);
+}
+
+
+/**@brief Function for ANT-FS timer event.
+ *
+ * Handles pairing and command timeouts.
+ *
+ * @param[in] p_context The callback context.
+ */
+static void timeout_handle(void * p_context)
+{
+ if (m_current_state.state == ANTFS_STATE_OFF)
+ {
+ return;
+ }
+
+ if ((m_current_state.state == ANTFS_STATE_AUTH) &&
+ // Pairing timeout.
+ (m_current_state.sub_state.auth_sub_state == ANTFS_AUTH_SUBSTATE_PAIR))
+ {
+ // Reject authentication request and send pairing timeout event.
+ authenticate_response_transmit(AUTH_RESPONSE_REJECT, 0, NULL);
+ event_queue_write(ANTFS_EVENT_PAIRING_TIMEOUT);
+ }
+
+ // Fall back to link layer when an ANT-FS event times out.
+ link_layer_transit();
+}
+
+
+void antfs_init(const antfs_params_t * const p_params,
+ antfs_burst_wait_handler_t burst_wait_handler)
+{
+ m_initial_parameters = *p_params;
+ m_burst_wait_handler = burst_wait_handler;
+ m_active_beacon_status1_field = m_initial_parameters.beacon_status_byte1;
+
+ uint32_t err_code = app_timer_create(&m_timer_id, APP_TIMER_MODE_SINGLE_SHOT, timeout_handle);
+ APP_ERROR_CHECK(err_code);
+
+ state_machine_reset();
+
+ err_code = sd_ant_burst_handler_wait_flag_enable((uint8_t *)(&m_burst_wait));
+ APP_ERROR_CHECK(err_code);
+}
+#endif // NRF_MODULE_ENABLED(ANTFS)
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ant/ant_fs/antfs.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ant/ant_fs/antfs.h
new file mode 100644
index 0000000..b040a62
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ant/ant_fs/antfs.h
@@ -0,0 +1,396 @@
+/**
+ * This software is subject to the ANT+ Shared Source License
+ * www.thisisant.com/swlicenses
+ * Copyright (c) Dynastream Innovations, Inc. 2012
+ * 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 Dynastream nor the names of its
+ * contributors may be used to endorse or promote products
+ * derived from this software without specific prior
+ * written permission.
+ *
+ * The following actions are prohibited:
+ * 1) Redistribution of source code containing the ANT+ Network
+ * Key. The ANT+ Network Key is available to ANT+ Adopters.
+ * Please refer to http://thisisant.com to become an ANT+
+ * Adopter and access the key.
+ *
+ * 2) Reverse engineering, decompilation, and/or disassembly of
+ * software provided in binary form under this license.
+ *
+ * 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 HEREBY
+ * 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; DAMAGE TO ANY DEVICE, 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. SOME STATES DO NOT ALLOW
+ * THE EXCLUSION OF INCIDENTAL OR CONSEQUENTIAL DAMAGES, SO THE
+ * ABOVE LIMITATIONS MAY NOT APPLY TO YOU.
+ *
+ */
+/**@file
+ * @brief The ANT-FS client protocol interface.
+ * This file is based on implementation originally made by Dynastream Innovations Inc. - August 2012
+ * @defgroup ant_fs ANT-FS client device simulator
+ * @{
+ * @ingroup ant_sdk_utils
+ *
+ * @brief The ANT-FS client device simulator.
+ *
+ * @note The ANT-FS Network Key is available for ANT+ Adopters. Please refer to http://thisisant.com to become an ANT+ Adopter and access the key.
+ */
+
+#ifndef ANTFS_H__
+#define ANTFS_H__
+
+#include <stdint.h>
+#include <stdbool.h>
+#include "defines.h"
+#include "sdk_config.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define ANTFS_VERSION_MAJOR 1u /**< Version major number. */
+#define ANTFS_VERSION_MINOR 0 /**< Version minor number. */
+#define ANTFS_VERSION_ITERATION 0 /**< Version iteration. */
+#define ANTFS_VERSION_TYPE 'R' /**< Version type is release. */
+#define ANTFS_VERSION_SPEC '0.AK' /**< Version of the ANT-FS Technology Specification. */
+#define ANTFS_DIR_STRUCT_VERSION 1u /**< Version of the directory file structure. */
+#define ANTFS_VERSION_DATE 20090522u /**< Version date. */
+
+// ANT-FS options.
+#define ANTFS_LINK_FREQ 50u /**< RF Frequency (+2400MHz). */
+#define ANTFS_CHANNEL_TYPE CHANNEL_TYPE_MASTER /**< ANT-FS Client Channel Type. */
+#define ANTFS_AUTH_STRING_MAX 255u /**< Maximum size of authentication strings (passkey/friendly name). */
+#define ANTFS_PASSKEY_SIZE 16u /**< Passkey size. */
+#define ANTFS_FRIENDLY_NAME_MAX 16u /**< Maximum size of friendly name received from host. */
+#define ANTFS_REMOTE_FRIENDLY_NAME_MAX 16u /**< Maximum size of client's friendly name. */
+
+// Beacon definitions.
+#define BEACON_PERIOD_SHIFT 0x00 /**< Shift value for masking out beacon period. */
+#define BEACON_PERIOD_MASK (0x07u << BEACON_PERIOD_SHIFT) /**< Beacon period bitmask. */
+#define BEACON_PERIOD_0_5_HZ (0x00 << BEACON_PERIOD_SHIFT) /**< Value for 0,5Hz beacon period. */
+#define BEACON_PERIOD_1_HZ (0x01u << BEACON_PERIOD_SHIFT) /**< Value for 1Hz beacon period. */
+#define BEACON_PERIOD_2_HZ (0x02u << BEACON_PERIOD_SHIFT) /**< Value for 2Hz beacon period. */
+#define BEACON_PERIOD_4_HZ (0x03u << BEACON_PERIOD_SHIFT) /**< Value for 4Hz beacon period. */
+#define BEACON_PERIOD_8_HZ (0x04u << BEACON_PERIOD_SHIFT) /**< Value for 8Hz beacon period. */
+#define PAIRING_AVAILABLE_FLAG_SHIFT 0x03u /**< Shift value for masking out pairing enabled bit. */
+#define PAIRING_AVAILABLE_FLAG_MASK (0x01u << PAIRING_AVAILABLE_FLAG_SHIFT) /**< Pairing enabled bitmask. */
+#define UPLOAD_ENABLED_FLAG_SHIFT 0x04u /**< Shift value for masking out upload enabled bit. */
+#define UPLOAD_ENABLED_FLAG_MASK (0x01u << UPLOAD_ENABLED_FLAG_SHIFT) /**< Upload enabled bitmask. */
+#define DATA_AVAILABLE_FLAG_SHIFT 0x05u /**< Shift value for masking out data available bit. */
+#define DATA_AVAILABLE_FLAG_MASK (0x01u << DATA_AVAILABLE_FLAG_SHIFT) /**< Data available bitmask. */
+
+#if ANTFS_ENABLED
+// Build the default beacon settings.
+#if ANTFS_CONFIG_AUTH_TYPE_PAIRING_ENABLED
+ #define ANTFS_PAIRING_BIT PAIRING_AVAILABLE_FLAG_MASK /**< Build pairing enabled default beacon setting. */
+#else
+ #define ANTFS_PAIRING_BIT 0x00u /**< Build pairing disabled default beacon setting. */
+#endif // ANTFS_CONFIG_AUTH_TYPE_PAIRING_ENABLED
+#if ANTFS_CONFIG_UPLOAD_ENABLED
+ #define ANTFS_UPLOAD_BIT UPLOAD_ENABLED_FLAG_MASK /**< Build upload enabled default beacon setting. */
+#else
+ #define ANTFS_UPLOAD_BIT 0x00u /**< Build upload disabled default beacon setting. */
+#endif // ANTFS_CONFIG_UPLOAD_ENABLED
+
+#define ANTFS_DEFAULT_BEACON (ANTFS_CONFIG_BEACON_STATUS_PERIOD | ANTFS_UPLOAD_BIT | ANTFS_PAIRING_BIT | DATA_AVAILABLE_FLAG_MASK) /**< Define the default beacon setting. */
+#endif // ANTFS_ENABLED
+
+// Download/Upload responses.
+#define RESPONSE_MESSAGE_OK 0x00u /**< Download request ok. */
+#define RESPONSE_MESSAGE_NOT_EXIST 0x01u /**< File does not exist. */
+#define RESPONSE_MESSAGE_NOT_AVAILABLE 0x02u /**< File can not be read/written to (download/upload respectively). */
+#define RESPONSE_INVALID_OPERATION 0x04u /**< Request invalid. */
+// Download responses.
+#define RESPONSE_MESSAGE_NOT_READY 0x03u /**< Not ready to download. */
+#define RESPONSE_INVALID_CRC 0x05u /**< CRC incorrect. */
+// Upload responses.
+#define RESPONSE_MESSAGE_NOT_ENOUGH_SPACE 0x03u /**< Not enough space to to complete write. */
+#define RESPONSE_MESSAGE_UPLOAD_NOT_READY 0x05u /**< Not ready to upload */
+// Upload/Erase responses.
+#define RESPONSE_MESSAGE_FAIL 0x01u /**< Data File Index does not exist / Erase failed. */
+
+// Directory general file flags.
+#define ANTFS_DIR_READ_MASK 0x80u /**< Read (can download). */
+#define ANTFS_DIR_WRITE_MASK 0x40u /**< Write (can upload). */
+#define ANTFS_DIR_ERASE_MASK 0x20u /**< Erase (can erase). */
+#define ANTFS_DIR_ARCHIVE_MASK 0x10u /**< Archive (has been downloaded). */
+#define ANTFS_DIR_APPEND_MASK 0x08u /**< Append (can append to file only). */
+
+#define ANTFS_MAX_FILE_SIZE 0xFFFFFFFFu /**< Maximum file size, as specified by directory structure. */
+#define ANTFS_BURST_BLOCK_SIZE 16u /**< Size of each block of burst data that the client attempts to send when it processes a data request event. */
+
+/**@brief ANT-FS beacon status. */
+typedef union
+{
+ uint32_t status; /**< Beacon status byte 1. */
+
+ struct
+ {
+ uint8_t link_period : 3; /**< Beacon period (0.5 - 8 Hz). */
+ bool is_pairing_enabled : 1; /**< Pairing is enabled/disabled. */
+ bool is_upload_enabled : 1; /**< Upload is enabled/disabled. */
+ bool is_data_available : 1; /**< Data is available for download / no data available. */
+ uint8_t reserved : 2; /**< Reserved. */
+ } parameters;
+} antfs_beacon_status_byte1_t;
+
+// ANT-FS states.
+typedef enum
+{
+ ANTFS_STATE_OFF, /**< Off state. */
+ ANTFS_STATE_INIT, /**< Init state. */
+ ANTFS_STATE_LINK, /**< Link state. */
+ ANTFS_STATE_AUTH, /**< Authenticate state. */
+ ANTFS_STATE_TRANS /**< Transport state. */
+} antfs_state_t;
+
+// ANT-FS link layer substates.
+typedef enum
+{
+ ANTFS_LINK_SUBSTATE_NONE /**< None state. */
+} antfs_link_substate_t;
+
+// ANT-FS authenticate layer substates. */
+typedef enum
+{
+ ANTFS_AUTH_SUBSTATE_NONE, /**< None state. */
+ ANTFS_AUTH_SUBSTATE_PAIR, /**< Pairing state. */
+ ANTFS_AUTH_SUBSTATE_PASSKEY, /**< Passkey state. */
+ ANTFS_AUTH_SUBSTATE_ACCEPT, /**< Authenticate accept state. */
+ ANTFS_AUTH_SUBSTATE_REJECT /**< Authenticate reject state. */
+} antfs_authenticate_substate_t;
+
+// ANT-FS transport layer substates. */
+typedef enum
+{
+ ANTFS_TRANS_SUBSTATE_NONE, /**< None state. */
+ ANTFS_TRANS_SUBSTATE_VERIFY_CRC, /**< Verify CRC state. */
+ ANTFS_TRANS_SUBSTATE_DOWNLOADING, /**< Downloading state. */
+ ANTFS_TRANS_SUBSTATE_UPLOAD_WAIT_FOR_DATA, /**< Wait for upload data request state. */
+ ANTFS_TRANS_SUBSTATE_UPLOADING, /**< Ready / receiving upload data state. */
+ ANTFS_TRANS_SUBSTATE_UPLOAD_RESUME /**< RX failure upon receiving upload data state. */
+} antfs_transport_substate_t;
+
+// ANT-FS Events.
+typedef enum
+{
+ ANTFS_EVENT_PAIRING_REQUEST = 0xB0, /**< Pairing request event. */
+ ANTFS_EVENT_PAIRING_TIMEOUT = 0xB1, /**< Pairing timeout event. */
+ ANTFS_EVENT_OPEN_COMPLETE = 0xB2, /**< Channel setup complete event. */
+ ANTFS_EVENT_CLOSE_COMPLETE = 0xB4, /**< Channel closed event. */
+ ANTFS_EVENT_LINK = 0xB6, /**< Enter link layer event. */
+ ANTFS_EVENT_AUTH = 0xB7, /**< Enter authenticate layer event. */
+ ANTFS_EVENT_TRANS = 0xB8, /**< Enter transport layer event. */
+ ANTFS_EVENT_DOWNLOAD_REQUEST = 0xB9, /**< Download request event. */
+ ANTFS_EVENT_DOWNLOAD_REQUEST_DATA = 0xBA, /**< Download request data event. */
+ ANTFS_EVENT_DOWNLOAD_START = 0xBB, /**< Download started event. */
+ ANTFS_EVENT_DOWNLOAD_COMPLETE = 0xBC, /**< Download completed event. */
+ ANTFS_EVENT_DOWNLOAD_FAIL = 0xBD, /**< Download failed event. */
+ ANTFS_EVENT_UPLOAD_REQUEST = 0xBE, /**< Upload request event. */
+ ANTFS_EVENT_UPLOAD_DATA = 0xBF, /**< Upload data available for read event. */
+ ANTFS_EVENT_UPLOAD_START = 0xC0, /**< Upload begin event. */
+ ANTFS_EVENT_UPLOAD_COMPLETE = 0xC1, /**< Upload completed event. */
+ ANTFS_EVENT_UPLOAD_FAIL = 0xC2, /**< Upload process failed event. */
+ ANTFS_EVENT_ERASE_REQUEST = 0xC3 /**< Erase request event. */
+} antfs_event_t;
+
+/**@brief ANT-FS <-> application event communication object. */
+typedef struct
+{
+ antfs_event_t event; /**< ANT-FS event. */
+ uint16_t file_index; /**< File index (download/upload/erase). */
+ uint32_t offset; /**< Current offset (download/upload). */
+ uint32_t bytes; /**< Number of bytes in block (download/upload). */
+ uint16_t crc; /**< Current CRC (upload). */
+ uint8_t data[8]; /**< Block of data (upload). */
+} antfs_event_return_t;
+
+/**@brief ANT-FS parameters. */
+typedef struct
+{
+ uint32_t client_serial_number; /**< Client serial number. */
+ uint16_t beacon_device_type; /**< Client device type. */
+ uint16_t beacon_device_manufacturing_id; /**< Client manufacturing ID. */
+ uint8_t beacon_frequency; /**< Beacon RF Frequency. */
+ antfs_beacon_status_byte1_t beacon_status_byte1; /**< Beacon status byte 1. */
+ const uint8_t * p_pass_key; /**< Pass Key. */
+ const uint8_t * p_remote_friendly_name; /**< Friendly Name. */
+} antfs_params_t;
+
+/**@brief ANT-FS directory header. */
+typedef struct
+{
+ uint8_t version; /**< Version of the directory file structure. */
+ uint8_t length; /**< Length of each structure, in bytes. */
+ uint8_t time_format; /**< Defines how system keeps track of date/time stamps. */
+ uint8_t reserved01;
+ uint8_t reserved02;
+ uint8_t reserved03;
+ uint8_t reserved04;
+ uint8_t reserved05;
+ uint32_t system_time; /**< Number of seconds elapsed since system power up. */
+ uint32_t date; /**< Number of seconds elapsed since 00:00 hrs Dec 31, 1989. If system time is unknown, used as counter. */
+} antfs_dir_header_t;
+
+/**@brief ANT-FS directory entry. */
+typedef struct
+{
+ uint16_t data_file_index; /**< Data file index. */
+ uint8_t file_data_type; /**< File data type. */
+ uint8_t user_defined1; /**< Identifier, first byte (structure defined by data type). */
+ uint16_t user_defined2; /**< Identifier, last two bytes (structure defined by data type). */
+ uint8_t user_flags; /**< File data type specific flags (bits defined by data type). */
+ uint8_t general_flags; /**< Bit mapped flags of flag permissions. */
+ uint32_t file_size_in_bytes; /**< File size, in bytes. */
+ uint32_t date; /**< Number of seconds elapsed since 00:00 hrs Dec 31, 1980, if supported. */
+} antfs_dir_struct_t;
+
+/**@brief ANT-FS download/upload request context. */
+typedef struct
+{
+ ulong_union_t file_size; /**< Size of a file to download when reading, or the size of a partially completed upload when writing. */
+ uint32_t max_file_size; /**< The maximum size of the file specified, this is the file size when reading, and the maximum allowed file size when writing. */
+ ulong_union_t max_burst_block_size; /**< Maximum burst block size. */
+ ushort_union_t file_index; /**< File index. */
+ uint16_t file_crc; /**< CRC (uploads). */
+} antfs_request_info_t;
+
+/**@brief The burst wait handler can be configured by the application to customize the code that is
+ * executed while waiting for the burst busy flag. */
+typedef void(*antfs_burst_wait_handler_t)(void);
+
+/**@brief Function for setting initial ANT-FS configuration parameters.
+ *
+ * @param[in] p_params The initial ANT-FS configuration parameters.
+ * @param[in] burst_wait_handler Burst wait handler.
+ */
+void antfs_init(const antfs_params_t * const p_params,
+ antfs_burst_wait_handler_t burst_wait_handler);
+
+/**@brief Function for getting host name if received.
+ *
+ * @return Pointer to host name buffer if a host name was recieved, NULL otherwise.
+ */
+const char * antfs_hostname_get(void);
+
+/**@brief Function for transmitting a response to a pairing request issued by ANT-FS host.
+ *
+ * @param[in] accept The pairing response, true if pairing accepted.
+ *
+ * @retval true Operation success. Response to a pairing request was transmitted.
+ * @retval false Operation failure. Not in pairing mode or pairing not supported by the
+ * implementation.
+ */
+bool antfs_pairing_resp_transmit(bool accept);
+
+/**@brief Function for doing calculations prior downloading the data to the ANT-FS host.
+ *
+ * Function does the necessary pre processing calculations, which are required prior downloading the
+ * data, and also transmits the download request response right away in case of the download request
+ * was rejected or there is no data to send.
+ *
+ * @param[in] response The download request response code.
+ * @param[in] p_request_info ANT-FS request info structure.
+ */
+void antfs_download_req_resp_prepare(uint8_t response,
+ const antfs_request_info_t * const p_request_info);
+
+/**@brief Function for downloading requested data.
+ *
+ * @param[in] index Index of the current file downloaded.
+ * @param[in] offset Offset specified by client.
+ * @param[in] num_bytes Number of bytes requested to be transmitted from the buffer.
+ * @param[in] p_message Data buffer to be transmitted.
+ *
+ * @return Number of data bytes transmitted.
+ */
+uint32_t antfs_input_data_download(uint16_t index,
+ uint32_t offset,
+ uint32_t num_bytes,
+ const uint8_t * const p_message);
+
+/**@brief Function for transmitting upload request response to a upload request command by ANT-FS
+ * host.
+ *
+ * @param[in] response The upload response code.
+ * @param[in] p_request_info ANT-FS request info structure.
+ *
+ * @retval true Operation success. Response to upload request command was transmitted.
+ * @retval false Operation failure. Upload not supported by the implementation or not in correct
+ * state or application is sending a response for a different file
+ * than requested.
+ */
+bool antfs_upload_req_resp_transmit(uint8_t response,
+ const antfs_request_info_t * const p_request_info);
+
+/**@brief Function for transmitting upload data response to a upload data command by ANT-FS host.
+ *
+ * @param[in] data_upload_success The upload response code, true for success.
+ *
+ * @retval true Operation success. Response to upload data command was transmitted.
+ * @retval false Operation failure. Upload not supported by the implementation or not in correct
+ * state.
+ */
+bool antfs_upload_data_resp_transmit(bool data_upload_success);
+
+/**@brief Function for transmitting erase response to a erase request.
+ *
+ * @param[in] response The erase response code.
+ */
+void antfs_erase_req_resp_transmit(uint8_t response);
+
+/**@brief Function for extracting possible pending ANT-FS event.
+ *
+ * @param[out] p_event The output event structure.
+ *
+ * @retval true Operation success. Pending ANT-FS event available and it was copied to the output
+ * event structure.
+ * @retval false Operation failure. No pending ANT-FS event available.
+ */
+bool antfs_event_extract(antfs_event_return_t * const p_event);
+
+/**@brief Function for processing ANT events and data received from the ANT-FS channel.
+ *
+ * @param[in] p_message The message buffer containing the message received from the ANT-FS
+ * channel.
+ */
+void antfs_message_process(uint8_t * p_message);
+
+/**@brief Function for setting up the ANT-FS channel.
+ */
+void antfs_channel_setup(void);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // ANTFS_H__
+
+/**
+ *@}
+ **/
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ant/ant_fs/crc.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ant/ant_fs/crc.c
new file mode 100644
index 0000000..ee26d88
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ant/ant_fs/crc.c
@@ -0,0 +1,98 @@
+/**
+ * This software is subject to the ANT+ Shared Source License
+ * www.thisisant.com/swlicenses
+ * Copyright (c) Dynastream Innovations, Inc. 2012
+ * 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 Dynastream nor the names of its
+ * contributors may be used to endorse or promote products
+ * derived from this software without specific prior
+ * written permission.
+ *
+ * The following actions are prohibited:
+ * 1) Redistribution of source code containing the ANT+ Network
+ * Key. The ANT+ Network Key is available to ANT+ Adopters.
+ * Please refer to http://thisisant.com to become an ANT+
+ * Adopter and access the key.
+ *
+ * 2) Reverse engineering, decompilation, and/or disassembly of
+ * software provided in binary form under this license.
+ *
+ * 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 HEREBY
+ * 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; DAMAGE TO ANY DEVICE, 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. SOME STATES DO NOT ALLOW
+ * THE EXCLUSION OF INCIDENTAL OR CONSEQUENTIAL DAMAGES, SO THE
+ * ABOVE LIMITATIONS MAY NOT APPLY TO YOU.
+ *
+ */
+#include "crc.h"
+#include "compiler_abstraction.h"
+
+
+/**@brief Function for updating the current CRC-16 value for a single byte input.
+ *
+ * @param[in] current_crc The current calculated CRC-16 value.
+ * @param[in] byte The input data byte for the computation.
+ *
+ * @return The updated CRC-16 value, based on the input supplied.
+ */
+static __INLINE uint16_t crc16_get(uint16_t current_crc, uint8_t byte)
+{
+ static const uint16_t crc16_table[16] =
+ {
+ 0x0000, 0xCC01, 0xD801, 0x1400, 0xF001, 0x3C00, 0x2800, 0xE401,
+ 0xA001, 0x6C00, 0x7800, 0xB401, 0x5000, 0x9C01, 0x8801, 0x4400
+ };
+
+ uint16_t temp;
+
+ // Compute checksum of lower four bits of a byte.
+ temp = crc16_table[current_crc & 0xF];
+ current_crc = (current_crc >> 4u) & 0x0FFFu;
+ current_crc = current_crc ^ temp ^ crc16_table[byte & 0xF];
+
+ // Now compute checksum of upper four bits of a byte.
+ temp = crc16_table[current_crc & 0xF];
+ current_crc = (current_crc >> 4u) & 0x0FFFu;
+ current_crc = current_crc ^ temp ^ crc16_table[(byte >> 4u) & 0xF];
+
+ return current_crc;
+}
+
+
+uint16_t crc_crc16_update(uint16_t current_crc, const volatile void * p_data, uint32_t size)
+{
+ uint8_t * p_block = (uint8_t *)p_data;
+
+ while (size != 0)
+ {
+ current_crc = crc16_get(current_crc, *p_block);
+ p_block++;
+ size--;
+ }
+
+ return current_crc;
+}
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ant/ant_fs/crc.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ant/ant_fs/crc.h
new file mode 100644
index 0000000..dffa5ad
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ant/ant_fs/crc.h
@@ -0,0 +1,94 @@
+/**
+ * This software is subject to the ANT+ Shared Source License
+ * www.thisisant.com/swlicenses
+ * Copyright (c) Dynastream Innovations, Inc. 2012
+ * 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 Dynastream nor the names of its
+ * contributors may be used to endorse or promote products
+ * derived from this software without specific prior
+ * written permission.
+ *
+ * The following actions are prohibited:
+ * 1) Redistribution of source code containing the ANT+ Network
+ * Key. The ANT+ Network Key is available to ANT+ Adopters.
+ * Please refer to http://thisisant.com to become an ANT+
+ * Adopter and access the key.
+ *
+ * 2) Reverse engineering, decompilation, and/or disassembly of
+ * software provided in binary form under this license.
+ *
+ * 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 HEREBY
+ * 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; DAMAGE TO ANY DEVICE, 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. SOME STATES DO NOT ALLOW
+ * THE EXCLUSION OF INCIDENTAL OR CONSEQUENTIAL DAMAGES, SO THE
+ * ABOVE LIMITATIONS MAY NOT APPLY TO YOU.
+ *
+ */
+/** @file
+ * @brief The CRC-16 interface.
+ * This file is based on implementation originally made by Dynastream Innovations Inc. - August 2012
+ * @defgroup ant_fs_client_main ANT-FS client device simulator
+ * @{
+ * @ingroup ant_fs
+ *
+ * @brief The ANT-FS client device simulator.
+ *
+ */
+
+#ifndef CRC_H__
+#define CRC_H__
+
+#include <stdint.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**@brief Function for calculating CRC-16 in blocks.
+ *
+ * Feed each consecutive data block into this function, along with the current value of current_crc
+ * as returned by the previous call of this function. The first call of this function should pass
+ * the initial value (usually 0) of the crc in current_crc.
+
+ * @param[in] current_crc The current calculated CRC-16 value.
+ * @param[in] p_data The input data block for computation.
+ * @param[in] size The size of the input data block in bytes.
+ *
+ * @return The updated CRC-16 value, based on the input supplied.
+ */
+uint16_t crc_crc16_update(uint16_t current_crc, const volatile void * p_data, uint32_t size);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // CRC_H__
+
+/**
+ *@}
+ **/
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ant/ant_fs/defines.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ant/ant_fs/defines.h
new file mode 100644
index 0000000..266de5c
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ant/ant_fs/defines.h
@@ -0,0 +1,109 @@
+/**
+ * This software is subject to the ANT+ Shared Source License
+ * www.thisisant.com/swlicenses
+ * Copyright (c) Dynastream Innovations, Inc. 2012
+ * 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 Dynastream nor the names of its
+ * contributors may be used to endorse or promote products
+ * derived from this software without specific prior
+ * written permission.
+ *
+ * The following actions are prohibited:
+ * 1) Redistribution of source code containing the ANT+ Network
+ * Key. The ANT+ Network Key is available to ANT+ Adopters.
+ * Please refer to http://thisisant.com to become an ANT+
+ * Adopter and access the key.
+ *
+ * 2) Reverse engineering, decompilation, and/or disassembly of
+ * software provided in binary form under this license.
+ *
+ * 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 HEREBY
+ * 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; DAMAGE TO ANY DEVICE, 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. SOME STATES DO NOT ALLOW
+ * THE EXCLUSION OF INCIDENTAL OR CONSEQUENTIAL DAMAGES, SO THE
+ * ABOVE LIMITATIONS MAY NOT APPLY TO YOU.
+ *
+ */
+/**@file
+ * @brief Definitions.
+ * This file is based on implementation originally made by Dynastream Innovations Inc. - August 2012
+ * @defgroup ant_fs_client_main ANT-FS client device simulator
+ * @{
+ * @ingroup nrf_ant_fs_client
+ *
+ * @brief The ANT-FS client device simulator.
+ *
+ */
+
+#ifndef DEFINES_H__
+#define DEFINES_H__
+
+#include <stdint.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define MAX_ULONG 0xFFFFFFFFu /**< The Max value for the type. */
+
+/**@brief uint16_t type presentation as an union. */
+typedef union
+{
+ uint16_t data; /**< The data content. */
+
+ struct
+ {
+ uint8_t low; /**< The low byte of the data content. */
+ uint8_t high; /**< The high byte of the data content. */
+ } bytes;
+} ushort_union_t;
+
+/**@brief uint32_t type presentation as an union. */
+typedef union
+{
+ uint32_t data; /**< The data content as a single variable. */
+ uint8_t data_bytes[sizeof(uint32_t)]; /**< The data content as a byte array. */
+
+ struct
+ {
+ // The least significant byte of the uint32_t in this structure is referenced by byte0.
+ uint8_t byte0; /**< Byte 0 of the data content. */
+ uint8_t byte1; /**< Byte 1 of the data content. */
+ uint8_t byte2; /**< Byte 2 of the data content. */
+ uint8_t byte3; /**< Byte 3 of the data content. */
+ } bytes;
+} ulong_union_t;
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // DEFINES_H__
+
+/**
+ *@}
+ **/
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ant/ant_key_manager/ant_key_manager.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ant/ant_key_manager/ant_key_manager.c
new file mode 100644
index 0000000..d9543b3
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ant/ant_key_manager/ant_key_manager.c
@@ -0,0 +1,67 @@
+/**
+ * Copyright (c) 2015 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#include "sdk_common.h"
+#if NRF_MODULE_ENABLED(ANT_KEY_MANAGER)
+#include <stdio.h>
+#include "ant_key_manager.h"
+#include "ant_key_manager_config.h"
+#include "ant_interface.h"
+#include "nrf_assert.h"
+
+static uint8_t m_ant_plus_network_key[] = ANT_PLUS_NETWORK_KEY;
+static uint8_t m_ant_fs_network_key[] = ANT_FS_NETWORK_KEY;
+
+uint32_t ant_custom_key_set(uint8_t network_number, uint8_t * network_key)
+{
+ ASSERT(network_key != NULL);
+ return sd_ant_network_address_set(network_number, network_key);
+}
+
+uint32_t ant_plus_key_set(uint8_t network_number)
+{
+ return sd_ant_network_address_set(network_number, m_ant_plus_network_key);
+}
+
+uint32_t ant_fs_key_set(uint8_t network_number)
+{
+ return sd_ant_network_address_set(network_number, m_ant_fs_network_key);
+}
+
+#endif // NRF_MODULE_ENABLED(ANT_KEY_MANAGER)
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ant/ant_key_manager/ant_key_manager.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ant/ant_key_manager/ant_key_manager.h
new file mode 100644
index 0000000..2971de9
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ant/ant_key_manager/ant_key_manager.h
@@ -0,0 +1,104 @@
+/**
+ * Copyright (c) 2015 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#ifndef ANT_KEY_MANAGER_H__
+#define ANT_KEY_MANAGER_H__
+
+#include <stdint.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @file
+ */
+/**
+ * @defgroup ant_key_manager ANT key manager
+ * @{
+ * @ingroup ant_sdk_utils
+ * @brief Module for registering common and custom ANT network keys.
+ */
+
+/**@brief Function for registering a custom network key.
+ *
+ * @param[in] network_number Network key number.
+ * @param[in] p_network_key Pointer to the custom ANT network key.
+ *
+ * @return A SoftDevice error code.
+ */
+uint32_t ant_custom_key_set(uint8_t network_number, uint8_t * p_network_key);
+
+/**@brief Function for registering an ANT+ network key.
+ *
+ * The key must be defined by @ref ANT_PLUS_NETWORK_KEY.
+ *
+ * @note The ANT+ Network Key is available for ANT+ Adopters. Go to http://thisisant.com
+ * to become an ANT+ Adopter and access the key.
+ *
+ * @param[in] network_number Network key number.
+ *
+ * @return A SoftDevice error code.
+ */
+uint32_t ant_plus_key_set(uint8_t network_number);
+
+/**@brief Function for registering an ANT-FS network key.
+ *
+ * The key must be defined by @ref ANT_FS_NETWORK_KEY.
+ *
+ * @note The ANT+ Network Key is available for ANT+ Adopters. Go to http://thisisant.com
+ * to become an ANT+ Adopter and access the key.
+ *
+ * @param[in] network_number Network key number.
+ *
+ * @return A SoftDevice error code.
+ */
+uint32_t ant_fs_key_set(uint8_t network_number);
+
+
+/**
+ * @}
+ */
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // ANT_KEY_MANAGER_H__
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ant/ant_key_manager/config/ant_key_manager_config.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ant/ant_key_manager/config/ant_key_manager_config.h
new file mode 100644
index 0000000..97d42ed
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ant/ant_key_manager/config/ant_key_manager_config.h
@@ -0,0 +1,69 @@
+/**
+ * Copyright (c) 2015 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#ifndef ANT_KEY_MANAGER_CONFIG_H__
+#define ANT_KEY_MANAGER_CONFIG_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @addtogroup ant_key_manager
+ * @{
+ */
+
+#ifndef ANT_PLUS_NETWORK_KEY
+ #define ANT_PLUS_NETWORK_KEY {0, 0, 0, 0, 0, 0, 0, 0} /**< The ANT+ network key. */
+#endif //ANT_PLUS_NETWORK_KEY
+
+#ifndef ANT_FS_NETWORK_KEY
+ #define ANT_FS_NETWORK_KEY {0, 0, 0, 0, 0, 0, 0, 0} /**< The ANT-FS network key. */
+#endif // ANT_FS_NETWORK_KEY
+
+/**
+ * @}
+ */
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // ANT_KEY_MANAGER_CONFIG_H__
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ant/ant_profiles/ant_bpwr/ant_bpwr.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ant/ant_profiles/ant_bpwr/ant_bpwr.c
new file mode 100644
index 0000000..3241ecd
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ant/ant_profiles/ant_bpwr/ant_bpwr.c
@@ -0,0 +1,490 @@
+/**
+ * Copyright (c) 2015 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#include "sdk_common.h"
+#if NRF_MODULE_ENABLED(ANT_BPWR)
+
+#include "nrf_assert.h"
+#include "app_error.h"
+#include "ant_interface.h"
+#include "ant_bpwr.h"
+
+#define NRF_LOG_MODULE_NAME ant_bpwr
+#if ANT_BPWR_LOG_ENABLED
+#define NRF_LOG_LEVEL ANT_BPWR_LOG_LEVEL
+#define NRF_LOG_INFO_COLOR ANT_BPWR_INFO_COLOR
+#else // ANT_BPWR_LOG_ENABLED
+#define NRF_LOG_LEVEL 0
+#endif // ANT_BPWR_LOG_ENABLED
+#include "nrf_log.h"
+NRF_LOG_MODULE_REGISTER();
+
+#define BPWR_CALIB_INT_TIMEOUT ((ANT_CLOCK_FREQUENCY * BPWR_CALIBRATION_TIMOUT_S) / BPWR_MSG_PERIOD) // calibration timeout in ant message period's unit
+
+// for torque sensor Minimum: Interleave every 9th message
+#define BPWR_PAGE_16_INTERVAL 5 // Preferred: Interleave every 5th message
+#define BPWR_PAGE_16_INTERVAL_OFS 2 // Permissible offset
+#define COMMON_PAGE_80_INTERVAL 119 // Minimum: Interleave every 121 messages
+#define COMMON_PAGE_81_INTERVAL 120 // Minimum: Interleave every 121 messages
+#define AUTO_ZERO_SUPPORT_INTERVAL 120 // Minimum: Interleave every 121 messages
+
+/**@brief Bicycle power message data layout structure. */
+typedef struct
+{
+ uint8_t page_number;
+ uint8_t page_payload[7];
+} ant_bpwr_message_layout_t;
+
+
+/**@brief Function for initializing the ANT Bicycle Power Profile instance.
+ *
+ * @param[in] p_profile Pointer to the profile instance.
+ * @param[in] p_channel_config Pointer to the ANT channel configuration structure.
+ *
+ * @retval NRF_SUCCESS If initialization was successful. Otherwise, an error code is returned.
+ */
+static ret_code_t ant_bpwr_init(ant_bpwr_profile_t * p_profile,
+ ant_channel_config_t const * p_channel_config)
+{
+ p_profile->channel_number = p_channel_config->channel_number;
+
+ p_profile->page_1 = DEFAULT_ANT_BPWR_PAGE1();
+ p_profile->page_16 = DEFAULT_ANT_BPWR_PAGE16();
+ p_profile->page_17 = DEFAULT_ANT_BPWR_PAGE17();
+ p_profile->page_18 = DEFAULT_ANT_BPWR_PAGE18();
+ p_profile->page_80 = DEFAULT_ANT_COMMON_page80();
+ p_profile->page_81 = DEFAULT_ANT_COMMON_page81();
+
+ NRF_LOG_INFO("ANT B-PWR channel %u init", p_profile->channel_number);
+ return ant_channel_init(p_channel_config);
+}
+
+
+ret_code_t ant_bpwr_disp_init(ant_bpwr_profile_t * p_profile,
+ ant_channel_config_t const * p_channel_config,
+ ant_bpwr_disp_config_t const * p_disp_config)
+{
+ ASSERT(p_profile != NULL);
+ ASSERT(p_channel_config != NULL);
+ ASSERT(p_disp_config != NULL);
+ ASSERT(p_disp_config->evt_handler != NULL);
+ ASSERT(p_disp_config->p_cb != NULL);
+
+ p_profile->evt_handler = p_disp_config->evt_handler;
+ p_profile->_cb.p_disp_cb = p_disp_config->p_cb;
+
+ p_profile->_cb.p_disp_cb ->calib_timeout = 0;
+ p_profile->_cb.p_disp_cb ->calib_stat = BPWR_DISP_CALIB_NONE;
+
+ return ant_bpwr_init(p_profile, p_channel_config);
+}
+
+
+ret_code_t ant_bpwr_sens_init(ant_bpwr_profile_t * p_profile,
+ ant_channel_config_t const * p_channel_config,
+ ant_bpwr_sens_config_t const * p_sens_config)
+{
+ ASSERT(p_profile != NULL);
+ ASSERT(p_channel_config != NULL);
+ ASSERT(p_sens_config != NULL);
+ ASSERT(p_sens_config->p_cb != NULL);
+ ASSERT(p_sens_config->evt_handler != NULL);
+ ASSERT(p_sens_config->calib_handler != NULL);
+
+ p_profile->evt_handler = p_sens_config->evt_handler;
+ p_profile->_cb.p_sens_cb = p_sens_config->p_cb;
+
+ p_profile->_cb.p_sens_cb->torque_use = p_sens_config->torque_use;
+ p_profile->_cb.p_sens_cb->calib_handler = p_sens_config->calib_handler;
+ p_profile->_cb.p_sens_cb->calib_stat = BPWR_SENS_CALIB_NONE;
+ p_profile->_cb.p_sens_cb->message_counter = 0;
+
+ return ant_bpwr_init(p_profile, p_channel_config);
+}
+
+
+
+/**@brief Function for getting next page number to send.
+ *
+ * @param[in] p_profile Pointer to the profile instance.
+ *
+ * @return Next page number.
+ */
+static ant_bpwr_page_t next_page_number_get(ant_bpwr_profile_t * p_profile)
+{
+ ant_bpwr_sens_cb_t * p_bpwr_cb = p_profile->_cb.p_sens_cb;
+ ant_bpwr_page_t page_number;
+
+ if (p_bpwr_cb->calib_stat == BPWR_SENS_CALIB_READY)
+ {
+ page_number = ANT_BPWR_PAGE_1;
+ p_bpwr_cb->calib_stat = BPWR_SENS_CALIB_NONE; // mark event as processed
+ }
+ else if ((p_profile->BPWR_PROFILE_auto_zero_status != ANT_BPWR_AUTO_ZERO_NOT_SUPPORTED)
+ && (p_bpwr_cb->message_counter == AUTO_ZERO_SUPPORT_INTERVAL))
+ {
+ page_number = ANT_BPWR_PAGE_1;
+ p_profile->BPWR_PROFILE_calibration_id = ANT_BPWR_CALIB_ID_AUTO_SUPPORT;
+ p_bpwr_cb->message_counter++;
+ }
+ else if (p_bpwr_cb->message_counter >= COMMON_PAGE_81_INTERVAL)
+ {
+ page_number = ANT_BPWR_PAGE_81;
+ p_bpwr_cb->message_counter = 0;
+ }
+ else
+ {
+ if (p_bpwr_cb->message_counter == COMMON_PAGE_80_INTERVAL)
+ {
+ page_number = ANT_BPWR_PAGE_80;
+ }
+ else
+ {
+ if ( p_bpwr_cb->torque_use == TORQUE_NONE)
+ {
+ page_number = ANT_BPWR_PAGE_16;
+ }
+ else if ((p_bpwr_cb->message_counter % BPWR_PAGE_16_INTERVAL)
+ == BPWR_PAGE_16_INTERVAL_OFS)
+ {
+ page_number = ANT_BPWR_PAGE_16;
+ }
+ else if ( p_bpwr_cb->torque_use == TORQUE_WHEEL)
+ {
+ page_number = ANT_BPWR_PAGE_17;
+ }
+ else // assumed TORQUE_CRANK
+ {
+ page_number = ANT_BPWR_PAGE_18;
+ }
+ }
+ p_bpwr_cb->message_counter++;
+ }
+
+ return page_number;
+}
+
+
+/**@brief Function for encoding Bicycle Power Sensor message.
+ *
+ * @note Assume to be call each time when Tx window will occur.
+ */
+static void sens_message_encode(ant_bpwr_profile_t * p_profile, uint8_t * p_message_payload)
+{
+ ant_bpwr_message_layout_t * p_bpwr_message_payload =
+ (ant_bpwr_message_layout_t *)p_message_payload;
+
+ p_bpwr_message_payload->page_number = next_page_number_get(p_profile);
+
+ NRF_LOG_INFO("B-PWR tx page: %u", p_bpwr_message_payload->page_number);
+
+ switch (p_bpwr_message_payload->page_number)
+ {
+ case ANT_BPWR_PAGE_1:
+ ant_bpwr_page_1_encode(p_bpwr_message_payload->page_payload, &(p_profile->page_1));
+ break;
+
+ case ANT_BPWR_PAGE_16:
+ ant_bpwr_page_16_encode(p_bpwr_message_payload->page_payload, &(p_profile->page_16));
+ ant_bpwr_cadence_encode(p_bpwr_message_payload->page_payload, &(p_profile->common));
+ break;
+
+ case ANT_BPWR_PAGE_17:
+ ant_bpwr_page_17_encode(p_bpwr_message_payload->page_payload, &(p_profile->page_17));
+ ant_bpwr_cadence_encode(p_bpwr_message_payload->page_payload, &(p_profile->common));
+ break;
+
+ case ANT_BPWR_PAGE_18:
+ ant_bpwr_page_18_encode(p_bpwr_message_payload->page_payload, &(p_profile->page_18));
+ ant_bpwr_cadence_encode(p_bpwr_message_payload->page_payload, &(p_profile->common));
+ break;
+
+ case ANT_COMMON_PAGE_80:
+ ant_common_page_80_encode(p_bpwr_message_payload->page_payload, &(p_profile->page_80));
+ break;
+
+ case ANT_COMMON_PAGE_81:
+ ant_common_page_81_encode(p_bpwr_message_payload->page_payload, &(p_profile->page_81));
+ break;
+
+ default:
+ return;
+ }
+
+ p_profile->evt_handler(p_profile, (ant_bpwr_evt_t)p_bpwr_message_payload->page_number);
+
+}
+
+
+/**@brief Function for decoding messages received by Bicycle Power sensor message.
+ *
+ * @note Assume to be call each time when Rx window will occur.
+ */
+static void sens_message_decode(ant_bpwr_profile_t * p_profile, uint8_t * p_message_payload)
+{
+ const ant_bpwr_message_layout_t * p_bpwr_message_payload =
+ (ant_bpwr_message_layout_t *)p_message_payload;
+ ant_bpwr_page1_data_t page1;
+
+ switch (p_bpwr_message_payload->page_number)
+ {
+ case ANT_BPWR_PAGE_1:
+ ant_bpwr_page_1_decode(p_bpwr_message_payload->page_payload, &page1);
+ p_profile->_cb.p_sens_cb->calib_stat = BPWR_SENS_CALIB_REQUESTED;
+ p_profile->_cb.p_sens_cb->calib_handler(p_profile, &page1);
+ break;
+
+ default:
+ break;
+ }
+}
+
+
+/**@brief Function for decoding messages received by Bicycle Power display message.
+ *
+ * @note Assume to be call each time when Rx window will occur.
+ */
+static void disp_message_decode(ant_bpwr_profile_t * p_profile, uint8_t * p_message_payload)
+{
+ const ant_bpwr_message_layout_t * p_bpwr_message_payload =
+ (ant_bpwr_message_layout_t *)p_message_payload;
+
+ NRF_LOG_INFO("B-PWR rx page: %u", p_bpwr_message_payload->page_number);
+
+ switch (p_bpwr_message_payload->page_number)
+ {
+ case ANT_BPWR_PAGE_1:
+ ant_bpwr_page_1_decode(p_bpwr_message_payload->page_payload, &(p_profile->page_1));
+ p_profile->_cb.p_disp_cb->calib_stat = BPWR_DISP_CALIB_NONE;
+ break;
+
+ case ANT_BPWR_PAGE_16:
+ ant_bpwr_page_16_decode(p_bpwr_message_payload->page_payload, &(p_profile->page_16));
+ ant_bpwr_cadence_decode(p_bpwr_message_payload->page_payload, &(p_profile->common));
+ break;
+
+ case ANT_BPWR_PAGE_17:
+ ant_bpwr_page_17_decode(p_bpwr_message_payload->page_payload, &(p_profile->page_17));
+ ant_bpwr_cadence_decode(p_bpwr_message_payload->page_payload, &(p_profile->common));
+ break;
+
+ case ANT_BPWR_PAGE_18:
+ ant_bpwr_page_18_decode(p_bpwr_message_payload->page_payload, &(p_profile->page_18));
+ ant_bpwr_cadence_decode(p_bpwr_message_payload->page_payload, &(p_profile->common));
+ break;
+
+ case ANT_COMMON_PAGE_80:
+ ant_common_page_80_decode(p_bpwr_message_payload->page_payload, &(p_profile->page_80));
+ break;
+
+ case ANT_COMMON_PAGE_81:
+ ant_common_page_81_decode(p_bpwr_message_payload->page_payload, &(p_profile->page_81));
+ break;
+
+ default:
+ return;
+ }
+
+ p_profile->evt_handler(p_profile, (ant_bpwr_evt_t)p_bpwr_message_payload->page_number);
+}
+
+
+ret_code_t ant_bpwr_calib_request(ant_bpwr_profile_t * p_profile, ant_bpwr_page1_data_t * p_page_1)
+{
+ ant_bpwr_message_layout_t bpwr_message_payload;
+
+ if (p_profile->_cb.p_disp_cb->calib_stat == BPWR_DISP_CALIB_REQUESTED)
+ {
+ return NRF_SUCCESS; // calibration in progress, so omit this request
+ }
+
+ bpwr_message_payload.page_number = ANT_BPWR_PAGE_1;
+ ant_bpwr_page_1_encode(bpwr_message_payload.page_payload, p_page_1);
+
+ uint32_t err_code = sd_ant_acknowledge_message_tx(p_profile->channel_number,
+ sizeof (bpwr_message_payload),
+ (uint8_t *) &bpwr_message_payload);
+
+ if (err_code == NRF_SUCCESS)
+ {
+ p_profile->_cb.p_disp_cb->calib_timeout = BPWR_CALIB_INT_TIMEOUT; // initialize watch on calibration's time-out
+ p_profile->_cb.p_disp_cb->calib_stat = BPWR_DISP_CALIB_REQUESTED;
+ NRF_LOG_INFO("Start calibration process");
+ }
+ return err_code;
+}
+
+
+void ant_bpwr_calib_response(ant_bpwr_profile_t * p_profile)
+{
+ if (p_profile->_cb.p_sens_cb->calib_stat != BPWR_SENS_CALIB_READY) // abort if callback request is in progress
+ {
+ p_profile->_cb.p_sens_cb->calib_stat = BPWR_SENS_CALIB_READY; // calibration respond
+ }
+}
+
+
+/**@brief Function for hangling calibration events.
+ */
+static void service_calib(ant_bpwr_profile_t * p_profile, uint8_t event)
+{
+ ant_bpwr_evt_t bpwr_event;
+
+ if (p_profile->_cb.p_disp_cb->calib_stat == BPWR_DISP_CALIB_REQUESTED)
+ {
+ switch (event)
+ {
+ case EVENT_RX:
+ /* fall through */
+ case EVENT_RX_FAIL:
+
+ if (p_profile->_cb.p_disp_cb->calib_timeout-- == 0)
+ {
+ bpwr_event = ANT_BPWR_CALIB_TIMEOUT;
+ break;
+ }
+ else
+ {
+ return;
+ }
+
+ case EVENT_TRANSFER_TX_FAILED:
+ bpwr_event = ANT_BPWR_CALIB_REQUEST_TX_FAILED;
+ break;
+
+ case EVENT_RX_SEARCH_TIMEOUT:
+ bpwr_event = ANT_BPWR_CALIB_TIMEOUT;
+ break;
+
+ default:
+ return;
+ }
+
+ NRF_LOG_INFO("End calibration process");
+ p_profile->_cb.p_disp_cb->calib_stat = BPWR_DISP_CALIB_NONE;
+
+ p_profile->evt_handler(p_profile, bpwr_event);
+ }
+}
+
+
+static void ant_message_send(ant_bpwr_profile_t * p_profile)
+{
+ uint32_t err_code;
+ uint8_t p_message_payload[ANT_STANDARD_DATA_PAYLOAD_SIZE];
+
+ sens_message_encode(p_profile, p_message_payload);
+ err_code =
+ sd_ant_broadcast_message_tx(p_profile->channel_number,
+ sizeof (p_message_payload),
+ p_message_payload);
+ APP_ERROR_CHECK(err_code);
+}
+
+
+ret_code_t ant_bpwr_disp_open(ant_bpwr_profile_t * p_profile)
+{
+ NRF_LOG_INFO("ANT B-PWR %u open", p_profile->channel_number);
+ return sd_ant_channel_open(p_profile->channel_number);
+}
+
+
+ret_code_t ant_bpwr_sens_open(ant_bpwr_profile_t * p_profile)
+{
+ // Fill tx buffer for the first frame
+ ant_message_send(p_profile);
+
+ NRF_LOG_INFO("ANT B-PWR %u open", p_profile->channel_number);
+ return sd_ant_channel_open(p_profile->channel_number);
+}
+
+
+void ant_bpwr_sens_evt_handler(ant_evt_t * p_ant_event, void * p_context)
+{
+ ant_bpwr_profile_t * p_profile = ( ant_bpwr_profile_t *)p_context;
+
+ if (p_ant_event->channel == p_profile->channel_number)
+ {
+ switch (p_ant_event->event)
+ {
+ case EVENT_TX:
+ ant_message_send(p_profile);
+ break;
+
+ case EVENT_RX:
+ if (p_ant_event->message.ANT_MESSAGE_ucMesgID == MESG_ACKNOWLEDGED_DATA_ID)
+ {
+ sens_message_decode(p_profile, p_ant_event->message.ANT_MESSAGE_aucPayload);
+ }
+ break;
+
+ default:
+ // No implementation needed
+ break;
+ }
+ }
+}
+
+
+void ant_bpwr_disp_evt_handler(ant_evt_t * p_ant_event, void * p_context)
+{
+ ant_bpwr_profile_t * p_profile = ( ant_bpwr_profile_t *)p_context;
+
+ if (p_ant_event->channel == p_profile->channel_number)
+ {
+ switch (p_ant_event->event)
+ {
+ case EVENT_RX:
+
+ if (p_ant_event->message.ANT_MESSAGE_ucMesgID == MESG_BROADCAST_DATA_ID
+ || p_ant_event->message.ANT_MESSAGE_ucMesgID == MESG_ACKNOWLEDGED_DATA_ID
+ || p_ant_event->message.ANT_MESSAGE_ucMesgID == MESG_BURST_DATA_ID)
+ {
+ disp_message_decode(p_profile, p_ant_event->message.ANT_MESSAGE_aucPayload);
+ }
+ break;
+
+ default:
+ break;
+ }
+ service_calib(p_profile, p_ant_event->event);
+ }
+}
+
+#endif // NRF_MODULE_ENABLED(ANT_BPWR)
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ant/ant_profiles/ant_bpwr/ant_bpwr.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ant/ant_profiles/ant_bpwr/ant_bpwr.h
new file mode 100644
index 0000000..a9fd093
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ant/ant_profiles/ant_bpwr/ant_bpwr.h
@@ -0,0 +1,377 @@
+/**
+ * Copyright (c) 2015 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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
+ * @defgroup ant_bpwr Bicycle Power profile
+ * @{
+ * @ingroup ant_sdk_profiles
+ * @brief This module implements the Bicycle Power profile.
+ *
+ */
+
+ #ifndef ANT_BICYCLE_POWER_H__
+ #define ANT_BICYCLE_POWER_H__
+
+#include <stdint.h>
+#include <stdbool.h>
+#include "ant_parameters.h"
+#include "nrf_sdh_ant.h"
+#include "ant_channel_config.h"
+#include "ant_bpwr_pages.h"
+#include "sdk_errors.h"
+
+#define BPWR_DEVICE_TYPE 0x0Bu ///< Device type reserved for ANT+ Bicycle Power.
+#define BPWR_ANTPLUS_RF_FREQ 0x39u ///< Frequency, decimal 57 (2457 MHz).
+#define BPWR_MSG_PERIOD 8182u ///< Message period, decimal 8182 (4.0049 Hz).
+
+#define BPWR_EXT_ASSIGN 0x00 ///< ANT ext assign (see Ext. Assign Channel Parameters in ant_parameters.h: @ref ant_parameters).
+#define BPWR_DISP_CHANNEL_TYPE CHANNEL_TYPE_SLAVE ///< Display Bicycle Power channel type.
+#define BPWR_SENS_CHANNEL_TYPE CHANNEL_TYPE_MASTER ///< Sensor Bicycle Power channel type.
+
+#define BPWR_CALIBRATION_TIMOUT_S 5u ///< Time-out for responding to calibration callback (s).
+
+
+/**@brief Initialize an ANT channel configuration structure for the Bicycle Power profile (Display).
+ *
+ * @param[in] NAME Name of related instance.
+ * @param[in] CHANNEL_NUMBER Number of the channel assigned to the profile instance.
+ * @param[in] TRANSMISSION_TYPE Type of transmission assigned to the profile instance.
+ * @param[in] DEVICE_NUMBER Number of the device assigned to the profile instance.
+ * @param[in] NETWORK_NUMBER Number of the network assigned to the profile instance.
+ */
+#define BPWR_DISP_CHANNEL_CONFIG_DEF(NAME, \
+ CHANNEL_NUMBER, \
+ TRANSMISSION_TYPE, \
+ DEVICE_NUMBER, \
+ NETWORK_NUMBER) \
+static const ant_channel_config_t CONCAT_2(NAME, _channel_bpwr_disp_config) = \
+ { \
+ .channel_number = (CHANNEL_NUMBER), \
+ .channel_type = BPWR_DISP_CHANNEL_TYPE, \
+ .ext_assign = BPWR_EXT_ASSIGN, \
+ .rf_freq = BPWR_ANTPLUS_RF_FREQ, \
+ .transmission_type = (TRANSMISSION_TYPE), \
+ .device_type = BPWR_DEVICE_TYPE, \
+ .device_number = (DEVICE_NUMBER), \
+ .channel_period = BPWR_MSG_PERIOD, \
+ .network_number = (NETWORK_NUMBER), \
+ }
+#define BPWR_DISP_CHANNEL_CONFIG(NAME) &CONCAT_2(NAME, _channel_bpwr_disp_config)
+
+/**@brief Initialize an ANT channel configuration structure for the Bicycle Power profile (Sensor).
+ *
+ * @param[in] NAME Name of related instance.
+ * @param[in] CHANNEL_NUMBER Number of the channel assigned to the profile instance.
+ * @param[in] TRANSMISSION_TYPE Type of transmission assigned to the profile instance.
+ * @param[in] DEVICE_NUMBER Number of the device assigned to the profile instance.
+ * @param[in] NETWORK_NUMBER Number of the network assigned to the profile instance.
+ */
+#define BPWR_SENS_CHANNEL_CONFIG_DEF(NAME, \
+ CHANNEL_NUMBER, \
+ TRANSMISSION_TYPE, \
+ DEVICE_NUMBER, \
+ NETWORK_NUMBER) \
+static const ant_channel_config_t CONCAT_2(NAME, _channel_bpwr_sens_config) = \
+ { \
+ .channel_number = (CHANNEL_NUMBER), \
+ .channel_type = BPWR_SENS_CHANNEL_TYPE, \
+ .ext_assign = BPWR_EXT_ASSIGN, \
+ .rf_freq = BPWR_ANTPLUS_RF_FREQ, \
+ .transmission_type = (TRANSMISSION_TYPE), \
+ .device_type = BPWR_DEVICE_TYPE, \
+ .device_number = (DEVICE_NUMBER), \
+ .channel_period = BPWR_MSG_PERIOD, \
+ .network_number = (NETWORK_NUMBER), \
+ }
+#define BPWR_SENS_CHANNEL_CONFIG(NAME) &CONCAT_2(NAME, _channel_bpwr_sens_config)
+
+/**@brief Initialize an ANT profile configuration structure for the BPWR profile (Display).
+ *
+ * @param[in] NAME Name of related instance.
+ * @param[in] EVT_HANDLER Event handler to be called for handling events in the BPWR profile.
+ */
+#define BPWR_DISP_PROFILE_CONFIG_DEF(NAME, \
+ EVT_HANDLER) \
+static ant_bpwr_disp_cb_t CONCAT_2(NAME, _bpwr_disp_cb); \
+static const ant_bpwr_disp_config_t CONCAT_2(NAME, _profile_bpwr_disp_config) = \
+ { \
+ .p_cb = &CONCAT_2(NAME, _bpwr_disp_cb), \
+ .evt_handler = (EVT_HANDLER), \
+ }
+#define BPWR_DISP_PROFILE_CONFIG(NAME) &CONCAT_2(NAME, _profile_bpwr_disp_config)
+
+
+/**@brief Initialize an ANT profile configuration structure for the BPWR profile (Sensor).
+ *
+ * @param[in] NAME Name of related instance.
+ * @param[in] TORQUE_USED Determines whether the torque page is included.
+ * @param[in] CALIB_HANDLER Event handler to be called for handling calibration requests.
+ * @param[in] EVT_HANDLER Event handler to be called for handling events in the BPWR profile.
+ */
+#define BPWR_SENS_PROFILE_CONFIG_DEF(NAME, \
+ TORQUE_USED, \
+ CALIB_HANDLER, \
+ EVT_HANDLER) \
+static ant_bpwr_sens_cb_t CONCAT_2(NAME, _bpwr_sens_cb); \
+static const ant_bpwr_sens_config_t CONCAT_2(NAME, _profile_bpwr_sens_config) = \
+ { \
+ .torque_use = (TORQUE_USED), \
+ .calib_handler = (CALIB_HANDLER), \
+ .p_cb = &CONCAT_2(NAME, _bpwr_sens_cb), \
+ .evt_handler = (EVT_HANDLER), \
+ }
+#define BPWR_SENS_PROFILE_CONFIG(NAME) &NAME##_profile_bpwr_sens_config
+
+
+/**@brief Configuration values for the Bicycle Power torque page. */
+typedef enum
+{
+ TORQUE_NONE = 0,
+ TORQUE_WHEEL = 1,
+ TORQUE_CRANK = 2,
+} ant_bpwr_torque_t;
+
+/**@brief Bicycle Power page number type. */
+typedef enum
+{
+ ANT_BPWR_PAGE_1 = 1, ///< Calibration data page.
+ ANT_BPWR_PAGE_16 = 16, ///< Standard power-only main data page.
+ ANT_BPWR_PAGE_17 = 17, ///< Standard wheel torque main data page.
+ ANT_BPWR_PAGE_18 = 18, ///< Standard crank torque main data page.
+ ANT_BPWR_PAGE_80 = ANT_COMMON_PAGE_80,
+ ANT_BPWR_PAGE_81 = ANT_COMMON_PAGE_81
+} ant_bpwr_page_t;
+
+/**@brief BPWR profile event type. */
+typedef enum
+{
+ ANT_BPWR_PAGE_1_UPDATED = ANT_BPWR_PAGE_1, ///< Data page 1 and speed have been updated (Display) or sent (Sensor).
+ ANT_BPWR_PAGE_16_UPDATED = ANT_BPWR_PAGE_16, ///< Data page 16 and speed have been updated (Display) or sent (Sensor).
+ ANT_BPWR_PAGE_17_UPDATED = ANT_BPWR_PAGE_17, ///< Data page 17 and speed have been updated (Display) or sent (Sensor).
+ ANT_BPWR_PAGE_18_UPDATED = ANT_BPWR_PAGE_18, ///< Data page 18 has been updated (Display) or sent (Sensor).
+ ANT_BPWR_PAGE_80_UPDATED = ANT_BPWR_PAGE_80, ///< Data page 80 has been updated (Display) or sent (Sensor).
+ ANT_BPWR_PAGE_81_UPDATED = ANT_BPWR_PAGE_81, ///< Data page 81 has been updated (Display) or sent (Sensor).
+ ANT_BPWR_CALIB_TIMEOUT, ///< Request of calibration time-out occurred (Display).
+ ANT_BPWR_CALIB_REQUEST_TX_FAILED, ///< Calibration request did not reach the destination (Display).
+} ant_bpwr_evt_t;
+
+// Forward declaration of the ant_bpwr_profile_t type.
+typedef struct ant_bpwr_profile_s ant_bpwr_profile_t;
+
+/**@brief BPWR event handler type. */
+typedef void (* ant_bpwr_evt_handler_t) (ant_bpwr_profile_t *, ant_bpwr_evt_t);
+
+/**@brief BPWR Sensor calibration request handler type. */
+typedef void (* ant_bpwr_calib_handler_t) (ant_bpwr_profile_t *, ant_bpwr_page1_data_t *);
+
+#include "ant_bpwr_local.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**@brief Bicycle Power Sensor configuration structure. */
+typedef struct
+{
+ ant_bpwr_torque_t torque_use; ///< Determines whether the torque page is included.
+ ant_bpwr_sens_cb_t * p_cb; ///< Pointer to the data buffer for internal use.
+ ant_bpwr_evt_handler_t evt_handler; ///< Event handler to be called for handling events in the BPWR profile.
+ ant_bpwr_calib_handler_t calib_handler; ///< Event handler to be called for handling calibration requests.
+} ant_bpwr_sens_config_t;
+
+/**@brief Bicycle Power Display configuration structure. */
+typedef struct
+{
+ ant_bpwr_disp_cb_t * p_cb; ///< Pointer to the data buffer for internal use.
+ ant_bpwr_evt_handler_t evt_handler; ///< Event handler to be called for handling events in the BPWR profile.
+} ant_bpwr_disp_config_t;
+
+/**@brief Bicycle Power profile structure. */
+struct ant_bpwr_profile_s
+{
+ uint8_t channel_number; ///< Channel number assigned to the profile.
+ union {
+ ant_bpwr_disp_cb_t * p_disp_cb;
+ ant_bpwr_sens_cb_t * p_sens_cb;
+ } _cb; ///< Pointer to internal control block.
+ ant_bpwr_evt_handler_t evt_handler; ///< Event handler to be called for handling events in the BPWR profile.
+ ant_bpwr_page1_data_t page_1; ///< Page 1.
+ ant_bpwr_page16_data_t page_16; ///< Page 16.
+ ant_bpwr_page17_data_t page_17; ///< Page 17.
+ ant_bpwr_page18_data_t page_18; ///< Page 18.
+ ant_common_page80_data_t page_80; ///< Page 80.
+ ant_common_page81_data_t page_81; ///< Page 81.
+ ant_bpwr_common_data_t common; ///< BPWR common data.
+};
+
+/** @name Defines for accessing ant_bpwr_profile_t member variables
+ @{ */
+#define BPWR_PROFILE_calibration_id page_1.calibration_id
+#define BPWR_PROFILE_auto_zero_status page_1.auto_zero_status
+#define BPWR_PROFILE_general_calib_data page_1.data.general_calib
+#define BPWR_PROFILE_custom_calib_data page_1.data.custom_calib
+#define BPWR_PROFILE_instantaneous_cadence common.instantaneous_cadence
+#define BPWR_PROFILE_pedal_power page_16.pedal_power.items
+#define BPWR_PROFILE_power_update_event_count page_16.update_event_count
+#define BPWR_PROFILE_accumulated_power page_16.accumulated_power
+#define BPWR_PROFILE_instantaneous_power page_16.instantaneous_power
+#define BPWR_PROFILE_wheel_update_event_count page_17.update_event_count
+#define BPWR_PROFILE_wheel_tick page_17.tick
+#define BPWR_PROFILE_wheel_period page_17.period
+#define BPWR_PROFILE_wheel_accumulated_torque page_17.accumulated_torque
+#define BPWR_PROFILE_crank_update_event_count page_18.update_event_count
+#define BPWR_PROFILE_crank_tick page_18.tick
+#define BPWR_PROFILE_crank_period page_18.period
+#define BPWR_PROFILE_crank_accumulated_torque page_18.accumulated_torque
+#define BPWR_PROFILE_manuf_id page_80.manuf_id
+#define BPWR_PROFILE_hw_revision page_80.hw_revision
+#define BPWR_PROFILE_manufacturer_id page_80.manufacturer_id
+#define BPWR_PROFILE_model_number page_80.model_number
+#define BPWR_PROFILE_sw_revision_minor page_81.sw_revision_minor
+#define BPWR_PROFILE_sw_revision_major page_81.sw_revision_major
+#define BPWR_PROFILE_serial_number page_81.serial_number
+/** @} */
+
+/**@brief Function for initializing the ANT Bicycle Power Display profile instance.
+ *
+ * @param[in] p_profile Pointer to the profile instance.
+ * @param[in] p_channel_config Pointer to the ANT channel configuration structure.
+ * @param[in] p_disp_config Pointer to the Bicycle Power Display configuration structure.
+ *
+ * @retval NRF_SUCCESS If initialization was successful. Otherwise, an error code is returned.
+ */
+ret_code_t ant_bpwr_disp_init(ant_bpwr_profile_t * p_profile,
+ ant_channel_config_t const * p_channel_config,
+ ant_bpwr_disp_config_t const * p_disp_config);
+
+/**@brief Function for initializing the ANT Bicycle Power Sensor profile instance.
+ *
+ * @param[in] p_profile Pointer to the profile instance.
+ * @param[in] p_channel_config Pointer to the ANT channel configuration structure.
+ * @param[in] p_sens_config Pointer to the Bicycle Power Sensor configuration structure.
+ *
+ * @retval NRF_SUCCESS If initialization was successful. Otherwise, an error code is returned.
+ */
+ret_code_t ant_bpwr_sens_init(ant_bpwr_profile_t * p_profile,
+ ant_channel_config_t const * p_channel_config,
+ ant_bpwr_sens_config_t const * p_sens_config);
+
+/**@brief Function for opening the profile instance channel for ANT BPWR Display.
+ *
+ * Before calling this function, pages should be configured.
+ *
+ * @param[in] p_profile Pointer to the profile instance.
+ *
+ * @retval NRF_SUCCESS If the channel was successfully opened. Otherwise, an error code is returned.
+ */
+ret_code_t ant_bpwr_disp_open(ant_bpwr_profile_t * p_profile);
+
+/**@brief Function for opening the profile instance channel for ANT BPWR Sensor.
+ *
+ * Before calling this function, pages should be configured.
+ *
+ * @param[in] p_profile Pointer to the profile instance.
+ *
+ * @retval NRF_SUCCESS If the channel was successfully opened. Otherwise, an error code is returned.
+ */
+ret_code_t ant_bpwr_sens_open(ant_bpwr_profile_t * p_profile);
+
+/** @name Functions: Sensor calibration API
+ * @{
+ */
+
+/** @brief Function for initializing the response for a calibration request.
+ *
+ * This function should be used to signal the status of the calibration procedure to the ANT profile layer .
+ *
+ * @param[in] p_profile Pointer to the profile instance.
+ */
+void ant_bpwr_calib_response(ant_bpwr_profile_t * p_profile);
+/** @} */
+
+
+/**@brief Function for handling the Sensor ANT events.
+ *
+ * @details This function handles all events from the ANT stack that are of interest to the Bicycle Power Display profile.
+ *
+ * @param[in] p_ant_evt Event received from the ANT stack.
+ * @param[in] p_context Pointer to the profile instance.
+ */
+void ant_bpwr_sens_evt_handler(ant_evt_t * p_ant_evt, void * p_context);
+
+/**@brief Function for handling the Display ANT events.
+ *
+ * @details This function handles all events from the ANT stack that are of interest to the Bicycle Power Display profile.
+ *
+ * @param[in] p_ant_evt Event received from the ANT stack.
+ * @param[in] p_context Pointer to the profile instance.
+ */
+void ant_bpwr_disp_evt_handler(ant_evt_t * p_ant_evt, void * p_context);
+
+/** @name Functions: Display calibration API
+ * @{
+ */
+
+/**@brief Function for initializing the calibration request process from the Bicycle Power Display side.
+ *
+ * @details This function requests a transfer to the Sensor and starts watching for the calibration response.
+ * If a calibration response has already been requested, the function ignores the new request and returns NRF_SUCCESS.
+ *
+ * @param [in] p_profile Pointer to the profile instance.
+ * @param [in] p_page_1 Pointer to the prepared page 1.
+ *
+ * @return Values returned by the @ref sd_ant_acknowledge_message_tx SVC callback.
+ */
+uint32_t ant_bpwr_calib_request(ant_bpwr_profile_t * p_profile, ant_bpwr_page1_data_t * p_page_1);
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // ANT_BICYCLE_POWER_H__
+
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ant/ant_profiles/ant_bpwr/ant_bpwr_local.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ant/ant_profiles/ant_bpwr/ant_bpwr_local.h
new file mode 100644
index 0000000..eb151f1
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ant/ant_profiles/ant_bpwr/ant_bpwr_local.h
@@ -0,0 +1,89 @@
+/**
+ * Copyright (c) 2015 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#ifndef ANT_BPWR_LOCAL_H__
+#define ANT_BPWR_LOCAL_H__
+
+#include <stdint.h>
+#include <stdbool.h>
+#include "ant_bpwr.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @addtogroup ant_bpwr
+ * @{
+ */
+
+/** @brief Bicycle Power Sensor control block. */
+typedef struct
+{
+ uint8_t message_counter;
+ ant_bpwr_torque_t torque_use;
+ enum
+ {
+ BPWR_SENS_CALIB_NONE, ///< Idle state.
+ BPWR_SENS_CALIB_REQUESTED, ///< Received request for general calibration result message by the sensor.
+ BPWR_SENS_CALIB_READY, ///< Calibration response message is ready to be transmitted.
+ } calib_stat;
+ ant_bpwr_calib_handler_t calib_handler;
+} ant_bpwr_sens_cb_t;
+
+/**@brief Bicycle Power Sensor RX control block. */
+typedef struct
+{
+ uint8_t calib_timeout;
+ enum
+ {
+ BPWR_DISP_CALIB_NONE, ///< Idle state.
+ BPWR_DISP_CALIB_REQUESTED, ///< Calibration requested.
+ } calib_stat;
+} ant_bpwr_disp_cb_t;
+
+/**
+ * @}
+ */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // ANT_BPWR_LOCAL_H__
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ant/ant_profiles/ant_bpwr/pages/ant_bpwr_common_data.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ant/ant_profiles/ant_bpwr/pages/ant_bpwr_common_data.c
new file mode 100644
index 0000000..8312873
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ant/ant_profiles/ant_bpwr/pages/ant_bpwr_common_data.c
@@ -0,0 +1,99 @@
+/**
+ * Copyright (c) 2015 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#include "sdk_common.h"
+#if NRF_MODULE_ENABLED(ANT_BPWR)
+
+#include "ant_bpwr_common_data.h"
+#include "ant_bpwr_utils.h"
+
+#define NRF_LOG_MODULE_NAME ant_bpwr_common
+#if ANT_BPWR_COMMON_LOG_ENABLED
+#define NRF_LOG_LEVEL ANT_BPWR_COMMON_LOG_LEVEL
+#define NRF_LOG_INFO_COLOR ANT_BPWR_COMMON_INFO_COLOR
+#else // ANT_BPWR_COMMON_LOG_ENABLED
+#define NRF_LOG_LEVEL 0
+#endif // ANT_BPWR_COMMON_LOG_ENABLED
+#include "nrf_log.h"
+NRF_LOG_MODULE_REGISTER();
+
+/**@brief BPWR common page data layout structure. */
+typedef struct
+{
+ uint8_t reserved0[2];
+ uint8_t instantaneous_cadence;
+ uint8_t reserved1[4];
+}ant_bpwr_cadence_data_layout_t;
+
+/**@brief Function for tracing common data.
+ *
+ * @param[in] p_common_data Pointer to the common data.
+ */
+static void cadence_data_log(ant_bpwr_common_data_t const * p_common_data)
+{
+ if (p_common_data->instantaneous_cadence == 0xFF)
+ {
+ NRF_LOG_INFO("instantaneous cadence: -- rpm\r\n\n");
+ }
+ else
+ {
+ NRF_LOG_INFO("instantaneous cadence: %u rpm\r\n\n",
+ p_common_data->instantaneous_cadence);
+ }
+}
+
+void ant_bpwr_cadence_encode(uint8_t * p_page_buffer,
+ ant_bpwr_common_data_t const * p_common_data)
+{
+ ant_bpwr_cadence_data_layout_t * p_outcoming_data = (ant_bpwr_cadence_data_layout_t *)p_page_buffer;
+ p_outcoming_data->instantaneous_cadence = p_common_data->instantaneous_cadence;
+
+ cadence_data_log(p_common_data);
+}
+
+void ant_bpwr_cadence_decode(uint8_t const * p_page_buffer,
+ ant_bpwr_common_data_t * p_common_data)
+{
+ ant_bpwr_cadence_data_layout_t const * p_incoming_data = (ant_bpwr_cadence_data_layout_t *)p_page_buffer;
+ p_common_data->instantaneous_cadence = p_incoming_data->instantaneous_cadence;
+
+ cadence_data_log(p_common_data);
+}
+
+#endif // NRF_MODULE_ENABLED(ANT_BPWR)
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ant/ant_profiles/ant_bpwr/pages/ant_bpwr_common_data.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ant/ant_profiles/ant_bpwr/pages/ant_bpwr_common_data.h
new file mode 100644
index 0000000..7da410b
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ant/ant_profiles/ant_bpwr/pages/ant_bpwr_common_data.h
@@ -0,0 +1,99 @@
+/**
+ * Copyright (c) 2015 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#ifndef ANT_BPWR_COMMON_DATA_H__
+#define ANT_BPWR_COMMON_DATA_H__
+
+/** @file
+ *
+ * @defgroup ant_sdk_profiles_bpwr_common_data_page Stride Based Speed and Distance Monitor profile common data
+ * @{
+ * @ingroup ant_sdk_profiles_bpwr_pages
+ */
+
+#include <stdint.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**@brief Data structure for BPWR common data.
+ *
+ * @details This structure stores data that is not associated with a particular page.
+ */
+typedef struct
+{
+ uint8_t instantaneous_cadence; ///< Crank cadence (rpm, 0 - 254, 255-> invalid).
+} ant_bpwr_common_data_t;
+
+/**@brief Initialize common data.
+ */
+#define DEFAULT_ANT_BPWR_COMMON_DATA() \
+ (ant_bpwr_common_data_t) \
+ { \
+ .instantaneous_cadence = 0, \
+ }
+
+/**@brief Function for encoding speed.
+ *
+ * This function can be used for pages 16, 17, and 18.
+ *
+ * @param[in] p_common_data Pointer to the common data.
+ * @param[out] p_page_buffer Pointer to the data buffer.
+ */
+void ant_bpwr_cadence_encode(uint8_t * p_page_buffer,
+ ant_bpwr_common_data_t const * p_common_data);
+
+/**@brief Function for decoding speed.
+ *
+ * This function can be used for pages 16, 17, and 18.
+ *
+ * @param[in] p_page_buffer Pointer to the data buffer.
+ * @param[out] p_common_data Pointer to the common data.
+ */
+void ant_bpwr_cadence_decode(uint8_t const * p_page_buffer,
+ ant_bpwr_common_data_t * p_common_data);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // ANT_BPWR_COMMON_DATA_H__
+/** @} */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ant/ant_profiles/ant_bpwr/pages/ant_bpwr_page_1.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ant/ant_profiles/ant_bpwr/pages/ant_bpwr_page_1.c
new file mode 100644
index 0000000..3efe554
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ant/ant_profiles/ant_bpwr/pages/ant_bpwr_page_1.c
@@ -0,0 +1,286 @@
+/**
+ * Copyright (c) 2015 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#include "sdk_common.h"
+#if NRF_MODULE_ENABLED(ANT_BPWR)
+
+#include <string.h>
+#include "ant_bpwr_page_1.h"
+
+#define NRF_LOG_MODULE_NAME ant_bpwr_page_1
+#if ANT_BPWR_PAGE_1_LOG_ENABLED
+#define NRF_LOG_LEVEL ANT_BPWR_PAGE_1_LOG_LEVEL
+#define NRF_LOG_INFO_COLOR ANT_BPWR_PAGE_1_INFO_COLOR
+#else // ANT_BPWR_PAGE_1_LOG_ENABLED
+#define NRF_LOG_LEVEL 0
+#endif // ANT_BPWR_PAGE_1_LOG_ENABLED
+#include "nrf_log.h"
+NRF_LOG_MODULE_REGISTER();
+
+/**@brief bicycle power page 1 data layout structure. */
+typedef struct
+{
+ uint8_t calibration_id; ///< Calibration request type
+ union
+ {
+ struct
+ {
+ uint8_t reserved[6]; ///< Unused, fill by 0xFF.
+ } general_calib_request;
+ struct
+ {
+ uint8_t auto_zero_status; ///< Status of automatic zero feature of power sensor.
+ uint8_t reserved[5]; ///< Unused, fill by 0xFF.
+ } auto_zero_config;
+ struct
+ {
+ uint8_t auto_zero_status; ///< Status of automatic zero feature of power sensor.
+ uint8_t reserved[3]; ///< Unused, fill by 0xFF.
+ uint8_t data[2]; ///< Calibration Data.
+ } general_calib_response;
+ struct
+ {
+ uint8_t enable : 1;
+ uint8_t status : 1;
+ uint8_t reserved0 : 6; ///< Unused, fill by 0x00.
+ uint8_t reserved1[5]; ///< Unused, fill by 0xFF.
+ } auto_zero_support;
+ struct
+ {
+ uint8_t manufac_spec[6]; ///< Manufacture Specyfic Data.
+ } custom_calib;
+ } data;
+} ant_bpwr_page1_data_layout_t;
+
+
+static void page1_data_log(ant_bpwr_page1_data_t const * p_page_data)
+{
+ NRF_LOG_INFO("Calibration id: %u", p_page_data->calibration_id);
+
+ switch (p_page_data->calibration_id)
+ {
+ case ANT_BPWR_CALIB_ID_MANUAL:
+ // No implementation needed
+ break;
+
+ case ANT_BPWR_CALIB_ID_MANUAL_SUCCESS:
+ /* fall through */
+ case ANT_BPWR_CALIB_ID_FAILED:
+ NRF_LOG_INFO("General calibration data: %u",
+ p_page_data->data.general_calib);
+ /* fall through */
+ case ANT_BPWR_CALIB_ID_AUTO:
+ /* fall through */
+ case ANT_BPWR_CALIB_ID_AUTO_SUPPORT:
+
+ switch (p_page_data->auto_zero_status)
+ {
+ case ANT_BPWR_AUTO_ZERO_NOT_SUPPORTED:
+ NRF_LOG_INFO("Auto zero not supported\r\n\n");
+ break;
+
+ case ANT_BPWR_AUTO_ZERO_OFF:
+ NRF_LOG_INFO("Auto zero off\r\n\n");
+ break;
+
+ case ANT_BPWR_AUTO_ZERO_ON:
+ NRF_LOG_INFO("Auto zero on\r\n\n");
+ break;
+ }
+ break;
+
+ case ANT_BPWR_CALIB_ID_CTF:
+ NRF_LOG_INFO("Not supported\r\n\n");
+ break;
+
+ case ANT_BPWR_CALIB_ID_CUSTOM_REQ:
+ /* fall through */
+ case ANT_BPWR_CALIB_ID_CUSTOM_REQ_SUCCESS:
+ /* fall through */
+ case ANT_BPWR_CALIB_ID_CUSTOM_UPDATE:
+ /* fall through */
+ case ANT_BPWR_CALIB_ID_CUSTOM_UPDATE_SUCCESS:
+ NRF_LOG_INFO("Manufacture specyfic: ");
+ NRF_LOG_HEXDUMP_INFO((uint8_t*)p_page_data->data.custom_calib,
+ sizeof (p_page_data->data.custom_calib));
+ break;
+
+ default: // shouldn't occur
+ NRF_LOG_INFO("Unsupported calibration ID\r\n\n");
+ break;
+ }
+}
+
+
+void ant_bpwr_page_1_encode(uint8_t * p_page_buffer,
+ ant_bpwr_page1_data_t const * p_page_data)
+{
+ ant_bpwr_page1_data_layout_t * p_outcoming_data = (ant_bpwr_page1_data_layout_t *)p_page_buffer;
+
+ page1_data_log(p_page_data);
+
+ p_outcoming_data->calibration_id = p_page_data->calibration_id;
+
+ switch (p_page_data->calibration_id)
+ {
+ case ANT_BPWR_CALIB_ID_MANUAL:
+ memset(p_outcoming_data->data.general_calib_request.reserved, 0xFF,
+ sizeof (p_outcoming_data->data.general_calib_request.reserved));
+ break;
+
+ case ANT_BPWR_CALIB_ID_AUTO:
+ memset(p_outcoming_data->data.auto_zero_config.reserved, 0xFF,
+ sizeof (p_outcoming_data->data.auto_zero_config.reserved));
+ p_outcoming_data->data.auto_zero_config.auto_zero_status =
+ p_page_data->auto_zero_status;
+ break;
+
+ case ANT_BPWR_CALIB_ID_MANUAL_SUCCESS:
+ /* fall through */
+ case ANT_BPWR_CALIB_ID_FAILED:
+ memset(p_outcoming_data->data.general_calib_response.reserved, 0xFF,
+ sizeof (p_outcoming_data->data.general_calib_response.reserved));
+ p_outcoming_data->data.general_calib_response.auto_zero_status =
+ p_page_data->auto_zero_status;
+ UNUSED_PARAMETER(uint16_encode(p_page_data->data.general_calib,
+ p_outcoming_data->data.general_calib_response.data));
+ break;
+
+ case ANT_BPWR_CALIB_ID_CTF:
+ NRF_LOG_INFO("Not supported");
+ break;
+
+ case ANT_BPWR_CALIB_ID_AUTO_SUPPORT:
+ memset(p_outcoming_data->data.auto_zero_support.reserved1, 0xFF,
+ sizeof (p_outcoming_data->data.auto_zero_support.reserved1));
+ p_outcoming_data->data.auto_zero_support.reserved0 = 0x00;
+ p_outcoming_data->data.auto_zero_support.enable =
+ (p_page_data->auto_zero_status == ANT_BPWR_AUTO_ZERO_NOT_SUPPORTED) ? false : true;
+ p_outcoming_data->data.auto_zero_support.status =
+ (p_page_data->auto_zero_status == ANT_BPWR_AUTO_ZERO_ON) ? true : false;
+ break;
+
+ case ANT_BPWR_CALIB_ID_CUSTOM_REQ:
+ /* fall through */
+ case ANT_BPWR_CALIB_ID_CUSTOM_REQ_SUCCESS:
+ /* fall through */
+ case ANT_BPWR_CALIB_ID_CUSTOM_UPDATE:
+ /* fall through */
+ case ANT_BPWR_CALIB_ID_CUSTOM_UPDATE_SUCCESS:
+ memcpy(p_outcoming_data->data.custom_calib.manufac_spec,
+ (void *)p_page_data->data.custom_calib,
+ sizeof (p_page_data->data.custom_calib));
+ break;
+
+ default: // shouldn't occur
+ break;
+ }
+}
+
+
+void ant_bpwr_page_1_decode(uint8_t const * p_page_buffer,
+ ant_bpwr_page1_data_t * p_page_data)
+{
+ ant_bpwr_page1_data_layout_t const * p_incoming_data =
+ (ant_bpwr_page1_data_layout_t *)p_page_buffer;
+
+ p_page_data->calibration_id = (ant_bpwr_calib_id_t)p_incoming_data->calibration_id;
+
+ switch (p_incoming_data->calibration_id)
+ {
+ case ANT_BPWR_CALIB_ID_MANUAL:
+ // No implementation needed
+ break;
+
+ case ANT_BPWR_CALIB_ID_AUTO:
+ /* fall through */
+ p_page_data->auto_zero_status =
+ (ant_bpwr_auto_zero_status_t)p_incoming_data->data.auto_zero_config.auto_zero_status;
+ break;
+
+ case ANT_BPWR_CALIB_ID_MANUAL_SUCCESS:
+ /* fall through */
+ case ANT_BPWR_CALIB_ID_FAILED:
+ p_page_data->auto_zero_status =
+ (ant_bpwr_auto_zero_status_t)p_incoming_data->data.general_calib_response.
+ auto_zero_status;
+ p_page_data->data.general_calib = uint16_decode(
+ p_incoming_data->data.general_calib_response.data);
+ break;
+
+ case ANT_BPWR_CALIB_ID_CTF:
+ NRF_LOG_INFO("Not supported");
+ break;
+
+ case ANT_BPWR_CALIB_ID_AUTO_SUPPORT:
+
+ if (p_incoming_data->data.auto_zero_support.enable == false)
+ {
+ p_page_data->auto_zero_status = ANT_BPWR_AUTO_ZERO_NOT_SUPPORTED;
+ }
+ else if (p_incoming_data->data.auto_zero_support.status)
+ {
+ p_page_data->auto_zero_status = ANT_BPWR_AUTO_ZERO_ON;
+ }
+ else
+ {
+ p_page_data->auto_zero_status = ANT_BPWR_AUTO_ZERO_OFF;
+ }
+ break;
+
+ case ANT_BPWR_CALIB_ID_CUSTOM_REQ:
+ /* fall through */
+ case ANT_BPWR_CALIB_ID_CUSTOM_REQ_SUCCESS:
+ /* fall through */
+ case ANT_BPWR_CALIB_ID_CUSTOM_UPDATE:
+ /* fall through */
+ case ANT_BPWR_CALIB_ID_CUSTOM_UPDATE_SUCCESS:
+ memcpy((void *)p_page_data->data.custom_calib,
+ p_incoming_data->data.custom_calib.manufac_spec,
+ sizeof (p_page_data->data.custom_calib));
+ break;
+
+ default: // shouldn't occur
+ break;
+ }
+
+ page1_data_log(p_page_data);
+}
+
+#endif // NRF_MODULE_ENABLED(ANT_BPWR)
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ant/ant_profiles/ant_bpwr/pages/ant_bpwr_page_1.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ant/ant_profiles/ant_bpwr/pages/ant_bpwr_page_1.h
new file mode 100644
index 0000000..24604a7
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ant/ant_profiles/ant_bpwr/pages/ant_bpwr_page_1.h
@@ -0,0 +1,136 @@
+/**
+ * Copyright (c) 2015 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#ifndef ANT_BPWR_PAGE_1_H__
+#define ANT_BPWR_PAGE_1_H__
+
+/** @file
+ *
+ * @defgroup ant_sdk_profiles_bpwr_page1 Bicycle Power profile page 1
+ * @{
+ * @ingroup ant_sdk_profiles_bpwr_pages
+ */
+
+#include <stdint.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**@brief BPWR Calibration ID.
+ */
+typedef enum
+{
+ ANT_BPWR_CALIB_ID_NONE = 0x00,
+ ANT_BPWR_CALIB_ID_MANUAL = 0xAA, ///< Calibration Request: Manual Zero.
+ ANT_BPWR_CALIB_ID_AUTO = 0xAB, ///< Calibration Request: Auto Zero Configuration.
+ ANT_BPWR_CALIB_ID_MANUAL_SUCCESS = 0xAC, ///< Calibration Response: Manual Zero Successful.
+ ANT_BPWR_CALIB_ID_FAILED = 0xAF, ///< Calibration Response: Failed.
+ ANT_BPWR_CALIB_ID_CTF = 0x10, ///< Crank Torque Frequency (CTF) Power sensor Defined Message.
+ ANT_BPWR_CALIB_ID_AUTO_SUPPORT = 0x12, ///< Auto Zero Support.
+ ANT_BPWR_CALIB_ID_CUSTOM_REQ = 0xBA, ///< Custom Calibration Parameter Request.
+ ANT_BPWR_CALIB_ID_CUSTOM_REQ_SUCCESS = 0xBB, ///< Custom Calibration Parameter Response.
+ ANT_BPWR_CALIB_ID_CUSTOM_UPDATE = 0xBC, ///< Custom Calibration Parameter Update.
+ ANT_BPWR_CALIB_ID_CUSTOM_UPDATE_SUCCESS = 0xBD, ///< Custom Calibration Parameter Update Response.
+} ant_bpwr_calib_id_t;
+
+/**@brief BPWR Calibration Auto Zero Status.
+ */
+typedef enum
+{
+ ANT_BPWR_AUTO_ZERO_NOT_SUPPORTED = 0xFF, ///< Auto Zero Not Supported.
+ ANT_BPWR_AUTO_ZERO_OFF = 0x00, ///< Auto Zero OFF.
+ ANT_BPWR_AUTO_ZERO_ON = 0x01, ///< Auto Zero ON.
+} ant_bpwr_auto_zero_status_t;
+
+/**@brief Data structure for Bicycle Power data page 1.
+ */
+typedef struct
+{
+ ant_bpwr_calib_id_t calibration_id; ///< Calibration request type.
+ ant_bpwr_auto_zero_status_t auto_zero_status; ///< Status of automatic zero feature of power sensor.
+ union
+ {
+ int16_t general_calib;
+ uint8_t custom_calib[6];
+ } data;
+} ant_bpwr_page1_data_t;
+
+/**@brief Initialize page 1.
+ */
+#define DEFAULT_ANT_BPWR_PAGE1() \
+ (ant_bpwr_page1_data_t) \
+ { \
+ .calibration_id = ANT_BPWR_CALIB_ID_NONE, \
+ .auto_zero_status = ANT_BPWR_AUTO_ZERO_NOT_SUPPORTED, \
+ .data.general_calib = 0x00, \
+ }
+
+/**@brief Initialize page 1 with the general request.
+ */
+#define ANT_BPWR_GENERAL_CALIB_REQUEST() \
+ (ant_bpwr_page1_data_t) \
+ { \
+ .calibration_id = ANT_BPWR_CALIB_ID_MANUAL, \
+ }
+
+/**@brief Function for encoding page 1.
+ *
+ * @param[in] p_page_data Pointer to the page data.
+ * @param[out] p_page_buffer Pointer to the data buffer.
+ */
+void ant_bpwr_page_1_encode(uint8_t * p_page_buffer,
+ ant_bpwr_page1_data_t const * p_page_data);
+
+/**@brief Function for decoding page 1.
+ *
+ * @param[in] p_page_buffer Pointer to the data buffer.
+ * @param[out] p_page_data Pointer to the page data.
+ */
+void ant_bpwr_page_1_decode(uint8_t const * p_page_buffer,
+ ant_bpwr_page1_data_t * p_page_data);
+
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // ANT_BPWR_PAGE_1_H__
+/** @} */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ant/ant_profiles/ant_bpwr/pages/ant_bpwr_page_16.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ant/ant_profiles/ant_bpwr/pages/ant_bpwr_page_16.c
new file mode 100644
index 0000000..71a2370
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ant/ant_profiles/ant_bpwr/pages/ant_bpwr_page_16.c
@@ -0,0 +1,117 @@
+/**
+ * Copyright (c) 2015 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#include "sdk_common.h"
+#if NRF_MODULE_ENABLED(ANT_BPWR)
+
+#include "ant_bpwr_page_16.h"
+
+#define NRF_LOG_MODULE_NAME ant_bpwr_page_16
+#if ANT_BPWR_PAGE_16_LOG_ENABLED
+#define NRF_LOG_LEVEL ANT_BPWR_PAGE_16_LOG_LEVEL
+#define NRF_LOG_INFO_COLOR ANT_BPWR_PAGE_16_INFO_COLOR
+#else // ANT_BPWR_PAGE_16_LOG_ENABLED
+#define NRF_LOG_LEVEL 0
+#endif // ANT_BPWR_PAGE_16_LOG_ENABLED
+#include "nrf_log.h"
+NRF_LOG_MODULE_REGISTER();
+
+/**@brief bicycle power page 16 data layout structure. */
+typedef struct
+{
+ uint8_t update_event_count;
+ uint8_t pedal_power;
+ uint8_t reserved;
+ uint8_t accumulated_power[2];
+ uint8_t instantaneous_power[2];
+}ant_bpwr_page16_data_layout_t;
+
+
+static void page16_data_log(ant_bpwr_page16_data_t const * p_page_data)
+{
+ NRF_LOG_INFO("event count: %u", p_page_data->update_event_count);
+
+ if (p_page_data->pedal_power.byte != 0xFF)
+ {
+ NRF_LOG_INFO("pedal power: %u %%",
+ p_page_data->pedal_power.items.distribution);
+ }
+ else
+ {
+ NRF_LOG_INFO("pedal power: --");
+ }
+
+ NRF_LOG_INFO("accumulated power: %u W", p_page_data->accumulated_power);
+ NRF_LOG_INFO("instantaneous power: %u W", p_page_data->instantaneous_power);
+}
+
+
+void ant_bpwr_page_16_encode(uint8_t * p_page_buffer,
+ ant_bpwr_page16_data_t const * p_page_data)
+{
+ ant_bpwr_page16_data_layout_t * p_outcoming_data =
+ (ant_bpwr_page16_data_layout_t *)p_page_buffer;
+
+ p_outcoming_data->update_event_count = p_page_data->update_event_count;
+ p_outcoming_data->pedal_power = p_page_data->pedal_power.byte;
+
+ UNUSED_PARAMETER(uint16_encode(p_page_data->accumulated_power,
+ p_outcoming_data->accumulated_power));
+ UNUSED_PARAMETER(uint16_encode(p_page_data->instantaneous_power,
+ p_outcoming_data->instantaneous_power));
+
+ page16_data_log(p_page_data);
+}
+
+
+void ant_bpwr_page_16_decode(uint8_t const * p_page_buffer,
+ ant_bpwr_page16_data_t * p_page_data)
+{
+ ant_bpwr_page16_data_layout_t const * p_incoming_data =
+ (ant_bpwr_page16_data_layout_t *)p_page_buffer;
+
+ p_page_data->update_event_count = p_incoming_data->update_event_count;
+ p_page_data->pedal_power.byte = p_incoming_data->pedal_power;
+ p_page_data->accumulated_power = uint16_decode(p_incoming_data->accumulated_power);
+ p_page_data->instantaneous_power = uint16_decode(p_incoming_data->instantaneous_power);
+
+ page16_data_log(p_page_data);
+}
+
+#endif // NRF_MODULE_ENABLED(ANT_BPWR)
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ant/ant_profiles/ant_bpwr/pages/ant_bpwr_page_16.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ant/ant_profiles/ant_bpwr/pages/ant_bpwr_page_16.h
new file mode 100644
index 0000000..6e8ce94
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ant/ant_profiles/ant_bpwr/pages/ant_bpwr_page_16.h
@@ -0,0 +1,111 @@
+/**
+ * Copyright (c) 2015 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#ifndef ANT_BPWR_PAGE_16_H__
+#define ANT_BPWR_PAGE_16_H__
+
+/** @file
+ *
+ * @defgroup ant_sdk_profiles_bpwr_page16 Bicycle Power profile page 16
+ * @{
+ * @ingroup ant_sdk_profiles_bpwr_pages
+ */
+
+#include <stdint.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**@brief Data structure for Bicycle Power data page 16.
+ *
+ * @note This structure implements only page 16 specific data.
+ */
+typedef struct
+{
+ union
+ {
+ struct
+ {
+ uint8_t distribution : 7; ///< Pedal power distribution (%).
+ uint8_t differentiation : 1; ///< Pedal differentiation: 1 -> right, 0 -> unknown.
+ } items;
+ uint8_t byte;
+ } pedal_power;
+
+ uint8_t update_event_count; ///< Power event count.
+ uint16_t accumulated_power; ///< Accumulated power (W).
+ uint16_t instantaneous_power; ///< Instantaneous power (W).
+} ant_bpwr_page16_data_t;
+
+/**@brief Initialize page 16.
+ */
+#define DEFAULT_ANT_BPWR_PAGE16() \
+ (ant_bpwr_page16_data_t) \
+ { \
+ .update_event_count = 0, \
+ .pedal_power.items.distribution = 0, \
+ .pedal_power.items.differentiation = 0, \
+ .accumulated_power = 0, \
+ .instantaneous_power = 0, \
+ }
+
+/**@brief Function for encoding page 16.
+ *
+ * @param[in] p_page_data Pointer to the page data.
+ * @param[out] p_page_buffer Pointer to the data buffer.
+ */
+void ant_bpwr_page_16_encode(uint8_t * p_page_buffer,
+ ant_bpwr_page16_data_t const * p_page_data);
+
+/**@brief Function for decoding page 16.
+ *
+ * @param[in] p_page_buffer Pointer to the data buffer.
+ * @param[out] p_page_data Pointer to the page data.
+ */
+void ant_bpwr_page_16_decode(uint8_t const * p_page_buffer,
+ ant_bpwr_page16_data_t * p_page_data);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // ANT_BPWR_PAGE_16_H__
+/** @} */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ant/ant_profiles/ant_bpwr/pages/ant_bpwr_page_17.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ant/ant_profiles/ant_bpwr/pages/ant_bpwr_page_17.c
new file mode 100644
index 0000000..3586f92
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ant/ant_profiles/ant_bpwr/pages/ant_bpwr_page_17.c
@@ -0,0 +1,77 @@
+/**
+ * Copyright (c) 2015 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#include "sdk_common.h"
+#if NRF_MODULE_ENABLED(ANT_BPWR)
+
+#include "ant_bpwr_page_17.h"
+
+#define NRF_LOG_MODULE_NAME ant_bpwr_page_17
+#if ANT_BPWR_PAGE_17_LOG_ENABLED
+#define NRF_LOG_LEVEL ANT_BPWR_PAGE_17_LOG_LEVEL
+#define NRF_LOG_INFO_COLOR ANT_BPWR_PAGE_17_INFO_COLOR
+#else // ANT_BPWR_PAGE_17_LOG_ENABLED
+#define NRF_LOG_LEVEL 0
+#endif // ANT_BPWR_PAGE_17_LOG_ENABLED
+#include "nrf_log.h"
+NRF_LOG_MODULE_REGISTER();
+
+static void page17_data_log(ant_bpwr_page17_data_t const * p_page_data)
+{
+ NRF_LOG_INFO("Wheel:");
+ ant_bpwr_page_torque_log((ant_bpwr_page_torque_data_t *) p_page_data);
+}
+
+
+void ant_bpwr_page_17_encode(uint8_t * p_page_buffer,
+ ant_bpwr_page17_data_t const * p_page_data)
+{
+ ant_bpwr_page_torque_encode(p_page_buffer, (ant_bpwr_page_torque_data_t *)p_page_data);
+ page17_data_log(p_page_data);
+}
+
+
+void ant_bpwr_page_17_decode(uint8_t const * p_page_buffer,
+ ant_bpwr_page17_data_t * p_page_data)
+{
+ ant_bpwr_page_torque_decode(p_page_buffer, (ant_bpwr_page_torque_data_t *) p_page_data);
+ page17_data_log(p_page_data);
+}
+
+#endif // NRF_MODULE_ENABLED(ANT_BPWR)
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ant/ant_profiles/ant_bpwr/pages/ant_bpwr_page_17.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ant/ant_profiles/ant_bpwr/pages/ant_bpwr_page_17.h
new file mode 100644
index 0000000..ef86067
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ant/ant_profiles/ant_bpwr/pages/ant_bpwr_page_17.h
@@ -0,0 +1,89 @@
+/**
+ * Copyright (c) 2015 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#ifndef ANT_BPWR_PAGE_17_H__
+#define ANT_BPWR_PAGE_17_H__
+
+/** @file
+ *
+ * @defgroup ant_sdk_profiles_bpwr_page17 Bicycle Power profile page 17
+ * @{
+ * @ingroup ant_sdk_profiles_bpwr_pages
+ */
+
+#include <stdint.h>
+#include "ant_bpwr_page_torque.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**@brief Data structure for Bicycle Power data page 17.
+ *
+ * @note This structure implements only page 17 specific data.
+ */
+typedef ant_bpwr_page_torque_data_t ant_bpwr_page17_data_t;
+
+/**@brief Initialize page 17.
+ */
+#define DEFAULT_ANT_BPWR_PAGE17() (ant_bpwr_page17_data_t) DEFAULT_ANT_BPWR_PAGE_TORQUE(0, 0, 0, 0)
+
+/**@brief Function for encoding page 17.
+ *
+ * @param[in] p_page_data Pointer to the page data.
+ * @param[out] p_page_buffer Pointer to the data buffer.
+ */
+void ant_bpwr_page_17_encode(uint8_t * p_page_buffer,
+ ant_bpwr_page17_data_t const * p_page_data);
+
+/**@brief Function for decoding page 17.
+ *
+ * @param[in] p_page_buffer Pointer to the data buffer.
+ * @param[out] p_page_data Pointer to the page data.
+ */
+void ant_bpwr_page_17_decode(uint8_t const * p_page_buffer,
+ ant_bpwr_page17_data_t * p_page_data);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // ANT_BPWR_PAGE_17_H__
+/** @} */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ant/ant_profiles/ant_bpwr/pages/ant_bpwr_page_18.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ant/ant_profiles/ant_bpwr/pages/ant_bpwr_page_18.c
new file mode 100644
index 0000000..55a3148
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ant/ant_profiles/ant_bpwr/pages/ant_bpwr_page_18.c
@@ -0,0 +1,77 @@
+/**
+ * Copyright (c) 2015 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#include "sdk_common.h"
+#if NRF_MODULE_ENABLED(ANT_BPWR)
+
+#include "ant_bpwr_page_18.h"
+
+#define NRF_LOG_MODULE_NAME ant_bpwr_page_18
+#if ANT_BPWR_PAGE_18_LOG_ENABLED
+#define NRF_LOG_LEVEL ANT_BPWR_PAGE_18_LOG_LEVEL
+#define NRF_LOG_INFO_COLOR ANT_BPWR_PAGE_18_INFO_COLOR
+#else // ANT_BPWR_PAGE_18_LOG_ENABLED
+#define NRF_LOG_LEVEL 0
+#endif // ANT_BPWR_PAGE_18_LOG_ENABLED
+#include "nrf_log.h"
+NRF_LOG_MODULE_REGISTER();
+
+static void page18_data_log(ant_bpwr_page18_data_t const * p_page_data)
+{
+ NRF_LOG_INFO("Crank:");
+ ant_bpwr_page_torque_log((ant_bpwr_page_torque_data_t *) p_page_data);
+}
+
+
+void ant_bpwr_page_18_encode(uint8_t * p_page_buffer,
+ ant_bpwr_page18_data_t const * p_page_data)
+{
+ ant_bpwr_page_torque_encode(p_page_buffer, (ant_bpwr_page_torque_data_t *)p_page_data);
+ page18_data_log(p_page_data);
+}
+
+
+void ant_bpwr_page_18_decode(uint8_t const * p_page_buffer,
+ ant_bpwr_page18_data_t * p_page_data)
+{
+ ant_bpwr_page_torque_decode(p_page_buffer, (ant_bpwr_page_torque_data_t *) p_page_data);
+ page18_data_log(p_page_data);
+}
+
+#endif // NRF_MODULE_ENABLED(ANT_BPWR)
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ant/ant_profiles/ant_bpwr/pages/ant_bpwr_page_18.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ant/ant_profiles/ant_bpwr/pages/ant_bpwr_page_18.h
new file mode 100644
index 0000000..712ae2f
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ant/ant_profiles/ant_bpwr/pages/ant_bpwr_page_18.h
@@ -0,0 +1,89 @@
+/**
+ * Copyright (c) 2011 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#ifndef ANT_BPWR_PAGE_18_H__
+#define ANT_BPWR_PAGE_18_H__
+
+/** @file
+ *
+ * @defgroup ant_sdk_profiles_bpwr_page18 Bicycle Power profile page 18
+ * @{
+ * @ingroup ant_sdk_profiles_bpwr_pages
+ */
+
+#include <stdint.h>
+#include "ant_bpwr_page_torque.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**@brief Data structure for Bicycle Power data page 18.
+ *
+ * @note This structure implements only page 18 specific data.
+ */
+typedef ant_bpwr_page_torque_data_t ant_bpwr_page18_data_t;
+
+/**@brief Initialize page 18.
+ */
+#define DEFAULT_ANT_BPWR_PAGE18() (ant_bpwr_page18_data_t) DEFAULT_ANT_BPWR_PAGE_TORQUE(0, 0, 0, 0)
+
+/**@brief Function for encoding page 18.
+ *
+ * @param[in] p_page_data Pointer to the page data.
+ * @param[out] p_page_buffer Pointer to the data buffer.
+ */
+void ant_bpwr_page_18_encode(uint8_t * p_page_buffer,
+ ant_bpwr_page18_data_t const * p_page_data);
+
+/**@brief Function for decoding page 18.
+ *
+ * @param[in] p_page_buffer Pointer to the data buffer.
+ * @param[out] p_page_data Pointer to the page data.
+ */
+void ant_bpwr_page_18_decode(uint8_t const * p_page_buffer,
+ ant_bpwr_page18_data_t * p_page_data);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // ANT_BPWR_PAGE_18_H__
+/** @} */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ant/ant_profiles/ant_bpwr/pages/ant_bpwr_page_torque.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ant/ant_profiles/ant_bpwr/pages/ant_bpwr_page_torque.c
new file mode 100644
index 0000000..e657f94
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ant/ant_profiles/ant_bpwr/pages/ant_bpwr_page_torque.c
@@ -0,0 +1,113 @@
+/**
+ * Copyright (c) 2015 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#include "sdk_common.h"
+#if NRF_MODULE_ENABLED(ANT_BPWR)
+
+#include <stdio.h>
+#include "ant_bpwr_page_torque.h"
+#include "ant_bpwr_utils.h"
+
+#define NRF_LOG_MODULE_NAME ant_bpwr_page_torque
+#if ANT_BPWR_PAGE_TORQUE_LOG_ENABLED
+#define NRF_LOG_LEVEL ANT_BPWR_PAGE_TORQUE_LOG_LEVEL
+#define NRF_LOG_INFO_COLOR ANT_BPWR_PAGE_TORQUE_INFO_COLOR
+#else // ANT_BPWR_PAGE_TORQUE_LOG_ENABLED
+#define NRF_LOG_LEVEL 0
+#endif // ANT_BPWR_PAGE_TORQUE_LOG_ENABLED
+#include "nrf_log.h"
+NRF_LOG_MODULE_REGISTER();
+
+/**@brief bicycle power page torque data layout structure. */
+typedef struct
+{
+ uint8_t update_event_count;
+ uint8_t tick;
+ uint8_t reserved;
+ uint8_t period[2];
+ uint8_t accumulated_torque[2];
+}ant_bpwr_page_torque_data_layout_t;
+
+STATIC_ASSERT(ANT_BPWR_TORQUE_PERIOD_DISP_PRECISION == 1000); ///< Display format need to be updated
+STATIC_ASSERT(ANT_BPWR_ACC_TORQUE_DISP_PRECISION == 10); ///< Display format need to be updated
+
+void ant_bpwr_page_torque_log(ant_bpwr_page_torque_data_t const * p_page_data)
+{
+ uint16_t period = ANT_BPWR_TORQUE_PERIOD_RESCALE(p_page_data->period);
+ uint32_t acc_torque = ANT_BPWR_ACC_TORQUE_RESCALE(p_page_data->accumulated_torque);
+
+ NRF_LOG_INFO("event count: %u", p_page_data->update_event_count);
+ NRF_LOG_INFO("tick: %u", p_page_data->tick);
+ NRF_LOG_INFO("period: %u.%03us",
+ (unsigned int)(period / ANT_BPWR_TORQUE_PERIOD_DISP_PRECISION),
+ (unsigned int)(period % ANT_BPWR_TORQUE_PERIOD_DISP_PRECISION));
+ NRF_LOG_INFO("accumulated torque: %u.%01uNm",
+ (unsigned int)(acc_torque / ANT_BPWR_ACC_TORQUE_DISP_PRECISION),
+ (unsigned int)(acc_torque % ANT_BPWR_ACC_TORQUE_DISP_PRECISION));
+}
+
+
+void ant_bpwr_page_torque_encode(uint8_t * p_page_buffer,
+ ant_bpwr_page_torque_data_t const * p_page_data)
+{
+ ant_bpwr_page_torque_data_layout_t * p_outcoming_data =
+ (ant_bpwr_page_torque_data_layout_t *)p_page_buffer;
+
+ p_outcoming_data->update_event_count = p_page_data->update_event_count;
+ p_outcoming_data->tick = p_page_data->tick;
+
+ UNUSED_PARAMETER(uint16_encode(p_page_data->period, p_outcoming_data->period));
+ UNUSED_PARAMETER(uint16_encode(p_page_data->accumulated_torque,
+ p_outcoming_data->accumulated_torque));
+}
+
+
+void ant_bpwr_page_torque_decode(uint8_t const * p_page_buffer,
+ ant_bpwr_page_torque_data_t * p_page_data)
+{
+ ant_bpwr_page_torque_data_layout_t const * p_incoming_data =
+ (ant_bpwr_page_torque_data_layout_t *)p_page_buffer;
+
+ p_page_data->update_event_count = p_incoming_data->update_event_count;
+ p_page_data->tick = p_incoming_data->tick;
+ p_page_data->period = uint16_decode(p_incoming_data->period);
+ p_page_data->accumulated_torque = uint16_decode(p_incoming_data->accumulated_torque);
+}
+
+#endif // NRF_MODULE_ENABLED(ANT_BPWR)
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ant/ant_profiles/ant_bpwr/pages/ant_bpwr_page_torque.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ant/ant_profiles/ant_bpwr/pages/ant_bpwr_page_torque.h
new file mode 100644
index 0000000..8eee44d
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ant/ant_profiles/ant_bpwr/pages/ant_bpwr_page_torque.h
@@ -0,0 +1,106 @@
+/**
+ * Copyright (c) 2015 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#ifndef ANT_BPWR_PAGE_TORQUE_COMMON_H__
+#define ANT_BPWR_PAGE_TORQUE_COMMON_H__
+
+/** @file
+ *
+ * @defgroup ant_sdk_profiles_bicycle_p_page_torque Bicycle Power profile pages 17, 18 (commons)
+ * @{
+ * @ingroup ant_sdk_profiles_bpwr_pages
+ */
+
+#include <stdint.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**@brief Common data structure for Bicycle Power data pages 17, 18.
+ *
+ * @note This structure implements specific data that is common for pages 17, 18.
+ */
+typedef struct
+{
+ uint8_t update_event_count; ///< Power event count.
+ uint8_t tick; ///< Wheel/crank revolutions counter.
+ uint16_t period; ///< Accumulated wheel/crank period (1/2048 s).
+ uint16_t accumulated_torque; ///< Accumulated wheel/torque (1/32 Nm).
+} ant_bpwr_page_torque_data_t;
+
+/**@brief Initialize page torque.
+ */
+#define DEFAULT_ANT_BPWR_PAGE_TORQUE(up_evt_cnt, def_tick, def_period, acc_torque) \
+ { \
+ .update_event_count = (up_evt_cnt), \
+ .tick = (def_tick), \
+ .period = (def_period), \
+ .accumulated_torque = (acc_torque) \
+ }
+
+/**@brief Function for encoding pages 17, 18.
+ *
+ * @param[in] p_page_data Pointer to the page data.
+ * @param[out] p_page_buffer Pointer to the data buffer.
+ */
+void ant_bpwr_page_torque_encode(uint8_t * p_page_buffer,
+ ant_bpwr_page_torque_data_t const * p_page_data);
+
+/**@brief Function for decoding pages 17, 18.
+ *
+ * @param[in] p_page_buffer Pointer to the data buffer.
+ * @param[out] p_page_data Pointer to the page data.
+ */
+void ant_bpwr_page_torque_decode(uint8_t const * p_page_buffer,
+ ant_bpwr_page_torque_data_t * p_page_data);
+
+/**@brief Function for logging pages 17, 18.
+ *
+ * @param[in] p_page_data Pointer to the page data.
+ */
+void ant_bpwr_page_torque_log(ant_bpwr_page_torque_data_t const * p_page_data);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // ANT_BPWR_PAGE_TORQUE_COMMON_H__
+/** @} */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ant/ant_profiles/ant_bpwr/pages/ant_bpwr_pages.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ant/ant_profiles/ant_bpwr/pages/ant_bpwr_pages.h
new file mode 100644
index 0000000..8f5098f
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ant/ant_profiles/ant_bpwr/pages/ant_bpwr_pages.h
@@ -0,0 +1,69 @@
+/**
+ * Copyright (c) 2015 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#ifndef ANT_BPWR_PAGES_H__
+#define ANT_BPWR_PAGES_H__
+
+/** @file
+ *
+ * @defgroup ant_sdk_profiles_bpwr_pages Bicycle Power profile pages
+ * @{
+ * @ingroup ant_bpwr
+ * @brief This module implements functions for the BPWR data pages.
+ */
+
+#include "ant_bpwr_page_1.h" // Calibration message main data page.
+#include "ant_bpwr_page_16.h" // Standard power-only page.
+#include "ant_bpwr_page_17.h" // Wheel Torque main data page.
+#include "ant_bpwr_page_18.h" // Crank Torque main data page.
+#include "ant_bpwr_common_data.h" // Instantaneous cadence data.
+#include "ant_common_page_80.h" // Manufacturer's information data page.
+#include "ant_common_page_81.h" // Product information data page.
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // ANT_BPWR_PAGES_H__
+/** @} */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ant/ant_profiles/ant_bpwr/simulator/ant_bpwr_simulator.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ant/ant_profiles/ant_bpwr/simulator/ant_bpwr_simulator.c
new file mode 100644
index 0000000..6d2ec14
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ant/ant_profiles/ant_bpwr/simulator/ant_bpwr_simulator.c
@@ -0,0 +1,201 @@
+/**
+ * Copyright (c) 2015 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#include "ant_bpwr_simulator.h"
+#include "app_util.h"
+#include "nordic_common.h"
+
+#define POWER_MIN 0
+#define POWER_MAX 2000
+#define POWER_INCR 10
+
+#define CADENCE_MIN 0
+#define CADENCE_MAX (UINT8_MAX - 1)
+#define CADENCE_INCR 1
+
+#define PEDAL_MIN 0
+#define PEDAL_MAX 100
+#define PEDAL_INCR 1
+
+#define TORQUE_PERIOD 774
+#define SIMULATOR_TIME_INCREMENT BPWR_MSG_PERIOD
+
+#define TORQUE_INCR 10
+
+
+void ant_bpwr_simulator_init(ant_bpwr_simulator_t * p_simulator,
+ ant_bpwr_simulator_cfg_t const * p_config,
+ bool auto_change)
+{
+ p_simulator->p_profile = p_config->p_profile;
+ p_simulator->_cb.auto_change = auto_change;
+ p_simulator->_cb.tick_incr = 0;
+
+ p_simulator->_cb.power_sensorsim_cfg.min = POWER_MIN;
+ p_simulator->_cb.power_sensorsim_cfg.max = POWER_MAX;
+ p_simulator->_cb.power_sensorsim_cfg.incr = POWER_INCR;
+ p_simulator->_cb.power_sensorsim_cfg.start_at_max = false;
+
+ p_simulator->_cb.cadence_sensorsim_cfg.min = CADENCE_MIN;
+ p_simulator->_cb.cadence_sensorsim_cfg.max = CADENCE_MAX;
+ p_simulator->_cb.cadence_sensorsim_cfg.incr = CADENCE_INCR;
+ p_simulator->_cb.cadence_sensorsim_cfg.start_at_max = false;
+
+ p_simulator->_cb.pedal_sensorsim_cfg.min = PEDAL_MIN;
+ p_simulator->_cb.pedal_sensorsim_cfg.max = PEDAL_MAX;
+ p_simulator->_cb.pedal_sensorsim_cfg.incr = PEDAL_INCR;
+ p_simulator->_cb.pedal_sensorsim_cfg.start_at_max = false;
+
+ p_simulator->p_profile->BPWR_PROFILE_pedal_power.differentiation = 0x01; // right
+
+ sensorsim_init(&(p_simulator->_cb.power_sensorsim_state),
+ &(p_simulator->_cb.power_sensorsim_cfg));
+ sensorsim_init(&(p_simulator->_cb.cadence_sensorsim_state),
+ &(p_simulator->_cb.cadence_sensorsim_cfg));
+ sensorsim_init(&(p_simulator->_cb.pedal_sensorsim_state),
+ &(p_simulator->_cb.pedal_sensorsim_cfg));
+}
+
+
+void ant_bpwr_simulator_one_iteration(ant_bpwr_simulator_t * p_simulator, ant_bpwr_evt_t event)
+{
+ switch (event)
+ {
+ case ANT_BPWR_PAGE_16_UPDATED:
+
+ if (p_simulator->_cb.auto_change)
+ {
+ UNUSED_PARAMETER(sensorsim_measure(&(p_simulator->_cb.power_sensorsim_state),
+ &(p_simulator->_cb.power_sensorsim_cfg)));
+ UNUSED_PARAMETER(sensorsim_measure(&(p_simulator->_cb.cadence_sensorsim_state),
+ &(p_simulator->_cb.cadence_sensorsim_cfg)));
+ UNUSED_PARAMETER(sensorsim_measure(&(p_simulator->_cb.pedal_sensorsim_state),
+ &(p_simulator->_cb.pedal_sensorsim_cfg)));
+ }
+
+ p_simulator->p_profile->BPWR_PROFILE_instantaneous_power =
+ p_simulator->_cb.power_sensorsim_state.current_val;
+ p_simulator->p_profile->BPWR_PROFILE_accumulated_power +=
+ p_simulator->_cb.power_sensorsim_state.current_val;
+
+ if (p_simulator->p_profile->BPWR_PROFILE_accumulated_power == UINT16_MAX)
+ {
+ p_simulator->p_profile->BPWR_PROFILE_accumulated_power = 0;
+ }
+ p_simulator->p_profile->BPWR_PROFILE_instantaneous_cadence =
+ p_simulator->_cb.cadence_sensorsim_state.current_val;
+ p_simulator->p_profile->BPWR_PROFILE_pedal_power.distribution =
+ p_simulator->_cb.pedal_sensorsim_state.current_val;
+ p_simulator->p_profile->BPWR_PROFILE_power_update_event_count++;
+ break;
+
+ case ANT_BPWR_PAGE_17_UPDATED:
+
+ if (p_simulator->_cb.auto_change)
+ {
+ UNUSED_PARAMETER(sensorsim_measure(&(p_simulator->_cb.cadence_sensorsim_state),
+ &(p_simulator->_cb.cadence_sensorsim_cfg)));
+ }
+ p_simulator->p_profile->BPWR_PROFILE_instantaneous_cadence =
+ p_simulator->_cb.cadence_sensorsim_state.current_val;
+ p_simulator->p_profile->BPWR_PROFILE_wheel_period += TORQUE_PERIOD;
+ p_simulator->_cb.tick_incr +=
+ SIMULATOR_TIME_INCREMENT;
+ p_simulator->p_profile->BPWR_PROFILE_wheel_tick +=
+ p_simulator->_cb.tick_incr / (TORQUE_PERIOD * 16);
+ p_simulator->_cb.tick_incr =
+ p_simulator->_cb.tick_incr % (TORQUE_PERIOD * 16);
+ p_simulator->p_profile->BPWR_PROFILE_wheel_accumulated_torque += TORQUE_INCR;
+ p_simulator->p_profile->BPWR_PROFILE_wheel_update_event_count++;
+ break;
+
+ case ANT_BPWR_PAGE_18_UPDATED:
+
+ if (p_simulator->_cb.auto_change)
+ {
+ UNUSED_PARAMETER(sensorsim_measure(&(p_simulator->_cb.cadence_sensorsim_state),
+ &(p_simulator->_cb.cadence_sensorsim_cfg)));
+ }
+ p_simulator->p_profile->BPWR_PROFILE_instantaneous_cadence =
+ p_simulator->_cb.cadence_sensorsim_state.current_val;
+ p_simulator->p_profile->BPWR_PROFILE_crank_period = TORQUE_PERIOD;
+ p_simulator->_cb.tick_incr +=
+ SIMULATOR_TIME_INCREMENT;
+ p_simulator->p_profile->BPWR_PROFILE_crank_tick +=
+ p_simulator->_cb.tick_incr / (TORQUE_PERIOD * 16);
+ p_simulator->_cb.tick_incr =
+ p_simulator->_cb.tick_incr % (TORQUE_PERIOD * 16);
+ p_simulator->p_profile->BPWR_PROFILE_crank_accumulated_torque += TORQUE_INCR;
+ p_simulator->p_profile->BPWR_PROFILE_crank_update_event_count++;
+ break;
+
+ default:
+ break;
+ }
+}
+
+
+void ant_bpwr_simulator_increment(ant_bpwr_simulator_t * p_simulator)
+{
+ if (!p_simulator->_cb.auto_change)
+ {
+ sensorsim_increment(&(p_simulator->_cb.power_sensorsim_state),
+ &(p_simulator->_cb.power_sensorsim_cfg));
+ sensorsim_increment(&(p_simulator->_cb.cadence_sensorsim_state),
+ &(p_simulator->_cb.cadence_sensorsim_cfg));
+ sensorsim_increment(&(p_simulator->_cb.pedal_sensorsim_state),
+ &(p_simulator->_cb.pedal_sensorsim_cfg));
+ }
+}
+
+
+void ant_bpwr_simulator_decrement(ant_bpwr_simulator_t * p_simulator)
+{
+ if (!p_simulator->_cb.auto_change)
+ {
+ sensorsim_decrement(&(p_simulator->_cb.power_sensorsim_state),
+ &(p_simulator->_cb.power_sensorsim_cfg));
+ sensorsim_decrement(&(p_simulator->_cb.cadence_sensorsim_state),
+ &(p_simulator->_cb.cadence_sensorsim_cfg));
+ sensorsim_decrement(&(p_simulator->_cb.pedal_sensorsim_state),
+ &(p_simulator->_cb.pedal_sensorsim_cfg));
+ }
+}
+
+
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ant/ant_profiles/ant_bpwr/simulator/ant_bpwr_simulator.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ant/ant_profiles/ant_bpwr/simulator/ant_bpwr_simulator.h
new file mode 100644
index 0000000..b7894ba
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ant/ant_profiles/ant_bpwr/simulator/ant_bpwr_simulator.h
@@ -0,0 +1,123 @@
+/**
+ * Copyright (c) 2015 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#ifndef ANT_BPWR_SIMULATOR_H__
+#define ANT_BPWR_SIMULATOR_H__
+
+/** @file
+ *
+ * @defgroup ant_sdk_simulators ANT simulators
+ * @ingroup ant_sdk_utils
+ * @brief Modules that simulate sensors.
+ *
+ * @defgroup ant_sdk_bpwr_simulator ANT BPWR simulator
+ * @{
+ * @ingroup ant_sdk_simulators
+ * @brief ANT BPWR simulator module.
+ *
+ * @details This module simulates power for the ANT BPWR profile. The module calculates
+ * abstract values, which are handled by the BPWR pages data model to ensure that they are
+ * compatible. It provides a handler for changing the power value manually and functionality
+ * for changing the power automatically.
+ *
+ */
+
+#include <stdint.h>
+#include <stdbool.h>
+#include "bsp.h"
+#include "ant_bpwr.h"
+#include "sensorsim.h"
+#include "ant_bpwr_simulator_local.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**@brief BPWR simulator configuration structure. */
+typedef struct
+{
+ ant_bpwr_profile_t * p_profile; ///< Related profile.
+ ant_bpwr_torque_t sensor_type; ///< Type of related sensor.
+} ant_bpwr_simulator_cfg_t;
+
+/**@brief BPWR simulator structure. */
+typedef struct
+{
+ ant_bpwr_profile_t * p_profile; ///< Related profile.
+ ant_bpwr_simulator_cb_t _cb; ///< Internal control block.
+} ant_bpwr_simulator_t;
+
+
+/**@brief Function for initializing the ANT BPWR simulator instance.
+ *
+ * @param[in] p_simulator Pointer to the simulator instance.
+ * @param[in] p_config Pointer to the simulator configuration structure.
+ * @param[in] auto_change Enable or disable automatic changes of the power.
+ */
+void ant_bpwr_simulator_init(ant_bpwr_simulator_t * p_simulator,
+ ant_bpwr_simulator_cfg_t const * p_config,
+ bool auto_change);
+
+/**@brief Function for simulating a device event.
+ *
+ * @details Based on this event, the transmitter data is simulated.
+ *
+ * This function should be called in the BPWR TX event handler.
+ */
+void ant_bpwr_simulator_one_iteration(ant_bpwr_simulator_t * p_simulator, ant_bpwr_evt_t event);
+
+/**@brief Function for incrementing the power value.
+ *
+ * @param[in] p_simulator Pointer to the simulator instance.
+ */
+void ant_bpwr_simulator_increment(ant_bpwr_simulator_t * p_simulator);
+
+/**@brief Function for decrementing the power value.
+ *
+ * @param[in] p_simulator Pointer to the simulator instance.
+ */
+void ant_bpwr_simulator_decrement(ant_bpwr_simulator_t * p_simulator);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // ANT_BPWR_SIMULATOR_H__
+/** @} */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ant/ant_profiles/ant_bpwr/simulator/ant_bpwr_simulator_local.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ant/ant_profiles/ant_bpwr/simulator/ant_bpwr_simulator_local.h
new file mode 100644
index 0000000..7b2c949
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ant/ant_profiles/ant_bpwr/simulator/ant_bpwr_simulator_local.h
@@ -0,0 +1,74 @@
+/**
+ * Copyright (c) 2015 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#ifndef ANT_BPWR_SIMULATOR_LOCAL_H__
+#define ANT_BPWR_SIMULATOR_LOCAL_H__
+
+#include <stdint.h>
+#include <stdbool.h>
+#include "bsp.h"
+#include "ant_bpwr.h"
+#include "sensorsim.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @ingroup ant_sdk_bpwr_simulator
+ * @brief BPWR simulator control block structure. */
+typedef struct
+{
+ bool auto_change; ///< Power will change automatically (if auto_change is set) or manually.
+ uint32_t tick_incr; ///< Fractional part of tick increment.
+ sensorsim_state_t power_sensorsim_state; ///< Power state of the simulated sensor.
+ sensorsim_cfg_t power_sensorsim_cfg; ///< Power configuration of the simulated sensor.
+ sensorsim_state_t cadence_sensorsim_state; ///< Cadence stated of the simulated sensor.
+ sensorsim_cfg_t cadence_sensorsim_cfg; ///< Cadence configuration of the simulated sensor.
+ sensorsim_state_t pedal_sensorsim_state; ///< Pedal state of the simulated sensor.
+ sensorsim_cfg_t pedal_sensorsim_cfg; ///< Pedal configuration of the simulated sensor.
+}ant_bpwr_simulator_cb_t;
+
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // ANT_BPWR_SIMULATOR_LOCAL_H__
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ant/ant_profiles/ant_bpwr/utils/ant_bpwr_utils.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ant/ant_profiles/ant_bpwr/utils/ant_bpwr_utils.h
new file mode 100644
index 0000000..100e059
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ant/ant_profiles/ant_bpwr/utils/ant_bpwr_utils.h
@@ -0,0 +1,86 @@
+/**
+ * Copyright (c) 2015 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#ifndef ANT_BPWR_UTILS_H__
+#define ANT_BPWR_UTILS_H__
+
+#include "app_util.h"
+#include "nrf_assert.h"
+#include "nrf.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** @file
+ *
+ * @defgroup ant_sdk_profiles_bpwr_utils Bicycle Power profile utilities
+ * @{
+ * @ingroup ant_bpwr
+ * @brief This module implements utilities for the Bicycle Power profile.
+ *
+ */
+
+/*@brief A reversal of torque period unit.
+ *
+ * @details According to the ANT BPWR specification, the torque period unit is 1/2048 of a second.
+ */
+#define ANT_BPWR_TORQUE_PERIOD_UNIT_REVERSAL 2048
+#define ANT_BPWR_TORQUE_PERIOD_DISP_PRECISION 1000
+#define ANT_BPWR_TORQUE_PERIOD_RESCALE(VALUE) value_rescale((VALUE), ANT_BPWR_TORQUE_PERIOD_UNIT_REVERSAL, \
+ ANT_BPWR_TORQUE_PERIOD_DISP_PRECISION)
+
+/*@brief A reversal of accumulated torque unit.
+ *
+ * @details According to the ANT BPWR specification, the accumulated torque unit is 1/32 of a Nm.
+ */
+#define ANT_BPWR_ACC_TORQUE_UNIT_REVERSAL 32
+#define ANT_BPWR_ACC_TORQUE_DISP_PRECISION 10
+#define ANT_BPWR_ACC_TORQUE_RESCALE(VALUE) value_rescale((VALUE), ANT_BPWR_ACC_TORQUE_UNIT_REVERSAL, \
+ ANT_BPWR_ACC_TORQUE_DISP_PRECISION)
+
+/** @} */
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // ANT_BPWR_UTILS_H__
+
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ant/ant_profiles/ant_bsc/ant_bsc.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ant/ant_profiles/ant_bsc/ant_bsc.c
new file mode 100644
index 0000000..1f356c5
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ant/ant_profiles/ant_bsc/ant_bsc.c
@@ -0,0 +1,422 @@
+/**
+ * Copyright (c) 2015 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#include "sdk_common.h"
+#if NRF_MODULE_ENABLED(ANT_BSC)
+
+#include "nrf_assert.h"
+#include "nrf_error.h"
+#include "app_error.h"
+#include "ant_interface.h"
+#include "ant_bsc.h"
+#include "ant_bsc_utils.h"
+
+#define NRF_LOG_MODULE_NAME ant_bsc
+#if ANT_BSC_LOG_ENABLED
+#define NRF_LOG_LEVEL ANT_BSC_LOG_LEVEL
+#define NRF_LOG_INFO_COLOR ANT_BSC_INFO_COLOR
+#else // ANT_BSC_LOG_ENABLED
+#define NRF_LOG_LEVEL 0
+#endif // ANT_BSC_LOG_ENABLED
+#include "nrf_log.h"
+NRF_LOG_MODULE_REGISTER();
+
+#define MAIN_DATA_INTERVAL 4 /**< The number of background data pages sent between main data pages.*/
+#define BACKGROUND_DATA_INTERVAL 64 /**< The number of main data pages sent between background data page.
+ Background data page is sent every 65th message. */
+#define TX_TOGGLE_DIVISOR 4 /**< The number of messages between changing state of toggle bit. */
+
+/**@brief BSC message data layout structure. */
+typedef struct
+{
+ ant_bsc_page_t page_number : 7;
+ uint8_t toggle_bit : 1;
+ uint8_t page_payload[7];
+}ant_bsc_single_message_layout_t;
+
+typedef struct
+{
+ uint8_t page_payload[8];
+}ant_bsc_combined_message_layout_t;
+
+typedef union
+{
+ ant_bsc_single_message_layout_t speed_or_cadence;
+ ant_bsc_combined_message_layout_t combined;
+}ant_bsc_message_layout_t;
+
+
+/**@brief Function for initializing the ANT BSC profile instance.
+ *
+ * @param[in] p_profile Pointer to the profile instance.
+ * @param[in] p_channel_config Pointer to the ANT channel configuration structure.
+ *
+ * @retval NRF_SUCCESS If initialization was successful. Otherwise, an error code is returned.
+ */
+static ret_code_t ant_bsc_init(ant_bsc_profile_t * p_profile,
+ ant_channel_config_t const * p_channel_config)
+{
+ p_profile->channel_number = p_channel_config->channel_number;
+
+ p_profile->page_0 = DEFAULT_ANT_BSC_PAGE0();
+ p_profile->page_1 = DEFAULT_ANT_BSC_PAGE1();
+ p_profile->page_2 = DEFAULT_ANT_BSC_PAGE2();
+ p_profile->page_3 = DEFAULT_ANT_BSC_PAGE3();
+ p_profile->page_4 = DEFAULT_ANT_BSC_PAGE4();
+ p_profile->page_5 = DEFAULT_ANT_BSC_PAGE5();
+ p_profile->page_comb_0 = DEFAULT_ANT_BSC_COMBINED_PAGE0();
+
+ NRF_LOG_INFO("ANT BSC channel %u init", p_profile->channel_number);
+ return ant_channel_init(p_channel_config);
+}
+
+ret_code_t ant_bsc_disp_init(ant_bsc_profile_t * p_profile,
+ ant_channel_config_t const * p_channel_config,
+ ant_bsc_disp_config_t const * p_disp_config)
+{
+ ASSERT(p_profile != NULL);
+ ASSERT(p_channel_config != NULL);
+ ASSERT(p_disp_config->evt_handler != NULL);
+
+ p_profile->evt_handler = p_disp_config->evt_handler;
+ p_profile->_cb.p_disp_cb = p_disp_config->p_cb;
+
+ p_profile->_cb.p_disp_cb->device_type = p_channel_config->device_type;
+
+ return ant_bsc_init(p_profile, p_channel_config);
+}
+
+ret_code_t ant_bsc_sens_init(ant_bsc_profile_t * p_profile,
+ ant_channel_config_t const * p_channel_config,
+ ant_bsc_sens_config_t const * p_sens_config)
+{
+ ASSERT(p_profile != NULL);
+ ASSERT(p_channel_config != NULL);
+ ASSERT(p_sens_config != NULL);
+ ASSERT(p_sens_config->p_cb != NULL);
+ ASSERT(p_sens_config->evt_handler != NULL);
+
+ ASSERT((p_sens_config->main_page_number == ANT_BSC_PAGE_0)
+ || (p_sens_config->main_page_number == ANT_BSC_PAGE_5)
+ || (p_sens_config->main_page_number == ANT_BSC_COMB_PAGE_0));
+
+ p_profile->evt_handler = p_sens_config->evt_handler;
+ p_profile->_cb.p_sens_cb = p_sens_config->p_cb;
+
+ p_profile->_cb.p_sens_cb->page_1_present = p_sens_config->page_1_present;
+ p_profile->_cb.p_sens_cb->page_4_present = p_sens_config->page_4_present;
+ p_profile->_cb.p_sens_cb->main_page_number = p_sens_config->main_page_number;
+ p_profile->_cb.p_sens_cb->bkgd_page_number =
+ p_sens_config->page_1_present ? ANT_BSC_PAGE_1 : ANT_BSC_PAGE_2;
+ p_profile->_cb.p_sens_cb->message_counter = 0;
+ p_profile->_cb.p_sens_cb->toggle_bit = true;
+ p_profile->_cb.p_sens_cb->device_type = p_channel_config->device_type; /* Device type is set up in channel config */
+
+ return ant_bsc_init(p_profile, p_channel_config);
+}
+
+/**@brief Function for setting the next background page number.
+ *
+ * @param[in] p_profile Pointer to the profile instance.
+ *
+ */
+__STATIC_INLINE void next_bkgd_page_number_set(ant_bsc_profile_t * p_profile)
+{
+ /* Determine the last background page*/
+ ant_bsc_page_t last_bkgd_page =
+ p_profile->_cb.p_sens_cb->page_4_present ? ANT_BSC_PAGE_4 : ANT_BSC_PAGE_3;
+
+ /* Switch the background page according to user settings */
+ ++(p_profile->_cb.p_sens_cb->bkgd_page_number);
+ if (p_profile->_cb.p_sens_cb->bkgd_page_number > last_bkgd_page)
+ {
+ p_profile->_cb.p_sens_cb->bkgd_page_number =
+ p_profile->_cb.p_sens_cb->page_1_present ? ANT_BSC_PAGE_1 : ANT_BSC_PAGE_2;
+ }
+}
+
+/**@brief Function for getting next page number to send.
+ *
+ * @param[in] p_profile Pointer to the profile instance.
+ *
+ * @return Next page number.
+ */
+static ant_bsc_page_t next_page_number_get(ant_bsc_profile_t * p_profile)
+{
+ ant_bsc_page_t page_number;
+
+ /* This is a single speed or cadence sensor - switch data page */
+ if (p_profile->_cb.p_sens_cb->message_counter < (BACKGROUND_DATA_INTERVAL))
+ {
+ /* Return main page */
+ page_number = p_profile->_cb.p_sens_cb->main_page_number;
+ }
+ else
+ {
+ /* Return background page */
+ page_number = p_profile->_cb.p_sens_cb->bkgd_page_number;
+ }
+
+ /* Set page toggle bit */
+ if ((p_profile->_cb.p_sens_cb->message_counter % TX_TOGGLE_DIVISOR) == 0)
+ {
+ p_profile->_cb.p_sens_cb->toggle_bit ^= 1;
+ }
+
+ /* Update message counter, wrap when counter equals 64 + 4 */
+ ++(p_profile->_cb.p_sens_cb->message_counter);
+ if (p_profile->_cb.p_sens_cb->message_counter == (BACKGROUND_DATA_INTERVAL + MAIN_DATA_INTERVAL))
+ {
+ p_profile->_cb.p_sens_cb->message_counter = 0;
+ /* Set new background data page number */
+ next_bkgd_page_number_set(p_profile);
+ }
+
+ return page_number;
+}
+
+/**@brief Function for encoding BSC message.
+ *
+ * @param[in] p_profile Pointer to the profile instance.
+ * @param[out] p_message_payload Pointer to the message payload structure.
+ *
+ * @note Assume to be called each time when Tx window will occur.
+ */
+static void sens_message_encode(ant_bsc_profile_t * p_profile, uint8_t * p_message_payload)
+{
+ ant_bsc_message_layout_t * p_bsc_message_payload = (ant_bsc_message_layout_t *)p_message_payload;
+ ant_bsc_evt_t bsc_sens_event;
+
+ if (p_profile->_cb.p_sens_cb->device_type == BSC_COMBINED_DEVICE_TYPE)
+ {
+ NRF_LOG_INFO("BSC TX Page: \"Combined Speed & Cadence Page\"");
+ ant_bsc_combined_page_0_encode(p_bsc_message_payload->combined.page_payload,
+ &(p_profile->page_comb_0));
+ bsc_sens_event = (ant_bsc_evt_t) ANT_BSC_COMB_PAGE_0_UPDATED;
+ }
+ else
+ {
+ p_bsc_message_payload->speed_or_cadence.page_number = next_page_number_get(p_profile);
+ p_bsc_message_payload->speed_or_cadence.toggle_bit = p_profile->_cb.p_sens_cb->toggle_bit;
+ NRF_LOG_INFO("BSC TX Page number: %u",
+ p_bsc_message_payload->speed_or_cadence.page_number);
+
+ ant_bsc_page_0_encode(p_bsc_message_payload->speed_or_cadence.page_payload,
+ &(p_profile->page_0));
+ bsc_sens_event = (ant_bsc_evt_t) p_bsc_message_payload->speed_or_cadence.page_number;
+
+ switch (p_bsc_message_payload->speed_or_cadence.page_number)
+ {
+ case ANT_BSC_PAGE_0:
+ // No implementation needed
+ break;
+ case ANT_BSC_PAGE_1:
+ ant_bsc_page_1_encode(p_bsc_message_payload->speed_or_cadence.page_payload,
+ &(p_profile->page_1));
+ break;
+ case ANT_BSC_PAGE_2:
+ ant_bsc_page_2_encode(p_bsc_message_payload->speed_or_cadence.page_payload,
+ &(p_profile->page_2));
+ break;
+ case ANT_BSC_PAGE_3:
+ ant_bsc_page_3_encode(p_bsc_message_payload->speed_or_cadence.page_payload,
+ &(p_profile->page_3));
+ break;
+ case ANT_BSC_PAGE_4:
+ ant_bsc_page_4_encode(p_bsc_message_payload->speed_or_cadence.page_payload,
+ &(p_profile->page_4));
+ break;
+ case ANT_BSC_PAGE_5:
+ ant_bsc_page_5_encode(p_bsc_message_payload->speed_or_cadence.page_payload,
+ &(p_profile->page_5));
+ break;
+ default:
+ // No implementation needed
+ break;
+ }
+ }
+
+ p_profile->evt_handler(p_profile, bsc_sens_event);
+}
+
+/**@brief Function for setting payload for ANT message and sending it.
+ *
+ * @param[in] p_profile Pointer to the profile instance.
+ */
+static void ant_message_send(ant_bsc_profile_t * p_profile)
+{
+ uint8_t p_message_payload[ANT_STANDARD_DATA_PAYLOAD_SIZE];
+ uint32_t err_code;
+
+ sens_message_encode(p_profile, p_message_payload);
+ err_code = sd_ant_broadcast_message_tx(p_profile->channel_number,
+ sizeof(p_message_payload),
+ p_message_payload);
+ APP_ERROR_CHECK(err_code);
+}
+
+void ant_bsc_sens_evt_handler(ant_evt_t * p_ant_evt, void * p_context)
+{
+ ant_bsc_profile_t * p_profile = (ant_bsc_profile_t *)p_context;
+
+ if (p_ant_evt->channel == p_profile->channel_number)
+ {
+ switch (p_ant_evt->event)
+ {
+ case EVENT_TX:
+ ant_message_send(p_profile);
+ break;
+
+ default:
+ break;
+ }
+ }
+}
+
+ret_code_t ant_bsc_disp_open(ant_bsc_profile_t * p_profile)
+{
+ ASSERT(p_profile != NULL);
+
+ NRF_LOG_INFO("ANT BSC channel %u open", p_profile->channel_number);
+ return sd_ant_channel_open(p_profile->channel_number);
+}
+
+ret_code_t ant_bsc_sens_open(ant_bsc_profile_t * p_profile)
+{
+ ASSERT(p_profile != NULL);
+
+ // Fill tx buffer for the first frame
+ ant_message_send(p_profile);
+
+ NRF_LOG_INFO("ANT BSC channel %u open", p_profile->channel_number);
+ return sd_ant_channel_open(p_profile->channel_number);
+}
+
+/**@brief Function for decoding BSC message.
+ *
+ * @param[in,out] p_profile Pointer to the profile instance.
+ * @param[in] p_message_payload Pointer to the message payload structure.
+ *
+ * @note Assume to be call each time when Rx window will occur.
+ */
+static void disp_message_decode(ant_bsc_profile_t * p_profile, uint8_t * p_message_payload)
+{
+ const ant_bsc_message_layout_t * p_bsc_message_payload =
+ (ant_bsc_message_layout_t *)p_message_payload;
+ ant_bsc_evt_t bsc_disp_event;
+
+ if (p_profile->_cb.p_disp_cb->device_type == BSC_COMBINED_DEVICE_TYPE)
+ {
+ NRF_LOG_INFO("BSC RX Page Number: \"Combined Speed & Cadence Page\"");
+ ant_bsc_combined_page_0_decode(p_bsc_message_payload->combined.page_payload,
+ &(p_profile->page_comb_0));
+ bsc_disp_event = (ant_bsc_evt_t) ANT_BSC_COMB_PAGE_0_UPDATED;
+ }
+ else
+ {
+ NRF_LOG_INFO("BSC RX Page Number: %u",
+ p_bsc_message_payload->speed_or_cadence.page_number);
+ ant_bsc_page_0_decode(p_bsc_message_payload->speed_or_cadence.page_payload,
+ &(p_profile->page_0)); // Page 0 is present in each message
+ bsc_disp_event = (ant_bsc_evt_t) p_bsc_message_payload->speed_or_cadence.page_number;
+
+ switch (p_bsc_message_payload->speed_or_cadence.page_number)
+ {
+ case ANT_BSC_PAGE_0:
+ // No implementation needed
+ break;
+
+ case ANT_BSC_PAGE_1:
+ ant_bsc_page_1_decode(p_bsc_message_payload->speed_or_cadence.page_payload,
+ &(p_profile->page_1));
+ break;
+
+ case ANT_BSC_PAGE_2:
+ ant_bsc_page_2_decode(p_bsc_message_payload->speed_or_cadence.page_payload,
+ &(p_profile->page_2));
+ break;
+
+ case ANT_BSC_PAGE_3:
+ ant_bsc_page_3_decode(p_bsc_message_payload->speed_or_cadence.page_payload,
+ &(p_profile->page_3));
+ break;
+
+ case ANT_BSC_PAGE_4:
+ ant_bsc_page_4_decode(p_bsc_message_payload->speed_or_cadence.page_payload,
+ &(p_profile->page_4));
+ break;
+
+ case ANT_BSC_PAGE_5:
+ ant_bsc_page_5_decode(p_bsc_message_payload->speed_or_cadence.page_payload,
+ &(p_profile->page_5));
+ break;
+
+ default:
+ // No implementation needed
+ break;
+ }
+ }
+
+ p_profile->evt_handler(p_profile, bsc_disp_event);
+}
+
+void ant_bsc_disp_evt_handler(ant_evt_t * p_ant_evt, void * p_context)
+{
+ ant_bsc_profile_t * p_profile = (ant_bsc_profile_t *)p_context;
+
+ if (p_ant_evt->channel == p_profile->channel_number)
+ {
+ switch (p_ant_evt->event)
+ {
+ case EVENT_RX:
+
+ if (p_ant_evt->message.ANT_MESSAGE_ucMesgID == MESG_BROADCAST_DATA_ID
+ || p_ant_evt->message.ANT_MESSAGE_ucMesgID == MESG_ACKNOWLEDGED_DATA_ID
+ || p_ant_evt->message.ANT_MESSAGE_ucMesgID == MESG_BURST_DATA_ID)
+ {
+ disp_message_decode(p_profile, p_ant_evt->message.ANT_MESSAGE_aucPayload);
+ }
+ break;
+ default:
+ break;
+ }
+ }
+}
+
+#endif // NRF_MODULE_ENABLED(ANT_BSC)
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ant/ant_profiles/ant_bsc/ant_bsc.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ant/ant_profiles/ant_bsc/ant_bsc.h
new file mode 100644
index 0000000..26f053d
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ant/ant_profiles/ant_bsc/ant_bsc.h
@@ -0,0 +1,359 @@
+/**
+ * Copyright (c) 2015 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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
+ *
+ * @defgroup ant_bsc Bicycle Speed and Cadence profile
+ * @{
+ * @ingroup ant_sdk_profiles
+ * @brief This module implements the Bicycle Speed and Cadence profile.
+ *
+ */
+
+#ifndef ANT_BSC_H__
+#define ANT_BSC_H__
+
+#include <stdint.h>
+#include <stdbool.h>
+#include "sdk_errors.h"
+#include "ant_parameters.h"
+#include "nrf_sdh_ant.h"
+#include "ant_channel_config.h"
+#include "ant_bsc_pages.h"
+
+#define BSC_ANTPLUS_RF_FREQ 0x39u ///< Frequency, decimal 57 (2457 MHz).
+
+#define BSC_SPEED_DEVICE_TYPE 0x7B ///< Device type reserved for ANT+ bike speed sensor.
+#define BSC_CADENCE_DEVICE_TYPE 0x7A ///< Device type reserved for ANT+ bike cadence sensor.
+#define BSC_COMBINED_DEVICE_TYPE 0x79 ///< Device type reserved for ANT+ bike combined speed and cadence sensor.
+
+#define BSC_MSG_PERIOD_4Hz 1u ///< Message period, 4 Hz (in basic period counts, where basic period time = 0.25 s).
+#define BSC_MSG_PERIOD_2Hz 2u ///< Message period, 2 Hz (in basic period counts).
+#define BSC_MSG_PERIOD_1Hz 4u ///< Message period, 1 Hz (in basic period counts).
+#define BSC_MSG_PERIOD_SPEED 0x1FB6u ///< Message period in ticks, decimal 8118 (4.04 Hz).
+#define BSC_MSG_PERIOD_CADENCE 0x1FA6u ///< Message period in ticks, decimal 8102 (4.04 Hz).
+#define BSC_MSG_PERIOD_COMBINED 0x1F96u ///< Message period in ticks, decimal 8086 (4.05 Hz).
+
+#define BSC_EXT_ASSIGN 0x00 ///< ANT ext assign (see Ext. Assign Channel Parameters in ant_parameters.h: @ref ant_parameters).
+#define BSC_DISP_CHANNEL_TYPE CHANNEL_TYPE_SLAVE_RX_ONLY ///< Display BSC channel type.
+#define BSC_SENS_CHANNEL_TYPE CHANNEL_TYPE_MASTER ///< Sensor BSC channel type.
+
+/**@brief Select the basic ANT channel period (in ticks) for the BSC profile depending on the device type.
+ *
+ * @param[in] DEVICE_TYPE Type of device. Supported types: @ref BSC_SPEED_DEVICE_TYPE, @ref BSC_CADENCE_DEVICE_TYPE,
+ * @ref BSC_COMBINED_DEVICE_TYPE.
+ */
+#define BSC_DEVICE_TICKS(DEVICE_TYPE) \
+ ((DEVICE_TYPE) == (BSC_SPEED_DEVICE_TYPE) ? (BSC_MSG_PERIOD_SPEED) : \
+ ((DEVICE_TYPE) == (BSC_CADENCE_DEVICE_TYPE) ? (BSC_MSG_PERIOD_CADENCE) : \
+ ((DEVICE_TYPE) == (BSC_COMBINED_DEVICE_TYPE) ? (BSC_MSG_PERIOD_COMBINED) : 0u)))
+
+/**@brief Calculate the channel period (in ticks) depending on the device type and the chosen message frequency.
+ *
+ * @param[in] DEVICE_TYPE Type of device. Supported types: @ref BSC_SPEED_DEVICE_TYPE, @ref BSC_CADENCE_DEVICE_TYPE,
+ * @ref BSC_COMBINED_DEVICE_TYPE.
+ * @param[in] BSC_MSG_PERIOD Channel data period. The BSC profile supports only the following periods:
+ * @ref BSC_MSG_PERIOD_4Hz, @ref BSC_MSG_PERIOD_2Hz, @ref BSC_MSG_PERIOD_1Hz.
+ */
+#define BSC_PERIOD_TICKS(DEVICE_TYPE, BSC_MSG_PERIOD) \
+ ((BSC_DEVICE_TICKS(DEVICE_TYPE)) * (BSC_MSG_PERIOD))
+
+/**@brief Initialize an ANT channel configuration structure for the BSC profile (Display).
+ *
+ * @param[in] NAME Name of related instance.
+ * @param[in] CHANNEL_NUMBER Number of the channel assigned to the profile instance.
+ * @param[in] TRANSMISSION_TYPE Type of transmission assigned to the profile instance.
+ * @param[in] DEVICE_TYPE Type of device. Supported types: @ref BSC_SPEED_DEVICE_TYPE, @ref BSC_CADENCE_DEVICE_TYPE,
+ * @ref BSC_COMBINED_DEVICE_TYPE.
+ * @param[in] DEVICE_NUMBER Number of the device assigned to the profile instance.
+ * @param[in] NETWORK_NUMBER Number of the network assigned to the profile instance.
+ * @param[in] BSC_MSG_PERIOD Channel data frequency in Hz. The BSC profile supports only the following frequencies:
+ * @ref BSC_MSG_PERIOD_4Hz, @ref BSC_MSG_PERIOD_2Hz, @ref BSC_MSG_PERIOD_1Hz.
+ */
+#define BSC_DISP_CHANNEL_CONFIG_DEF(NAME, \
+ CHANNEL_NUMBER, \
+ TRANSMISSION_TYPE, \
+ DEVICE_TYPE, \
+ DEVICE_NUMBER, \
+ NETWORK_NUMBER, \
+ BSC_MSG_PERIOD) \
+static const ant_channel_config_t CONCAT_2(NAME, _channel_bsc_disp_config) = \
+ { \
+ .channel_number = (CHANNEL_NUMBER), \
+ .channel_type = BSC_DISP_CHANNEL_TYPE, \
+ .ext_assign = BSC_EXT_ASSIGN, \
+ .rf_freq = BSC_ANTPLUS_RF_FREQ, \
+ .transmission_type = (TRANSMISSION_TYPE), \
+ .device_type = (DEVICE_TYPE), \
+ .device_number = (DEVICE_NUMBER), \
+ .channel_period = BSC_PERIOD_TICKS(DEVICE_TYPE, BSC_MSG_PERIOD), \
+ .network_number = (NETWORK_NUMBER), \
+ }
+#define BSC_DISP_CHANNEL_CONFIG(NAME) &CONCAT_2(NAME, _channel_bsc_disp_config)
+
+/**@brief Initialize an ANT channel configuration structure for the BSC profile (Transmitter).
+ *
+ * @param[in] NAME Name of related instance.
+ * @param[in] CHANNEL_NUMBER Number of the channel assigned to the profile instance.
+ * @param[in] TRANSMISSION_TYPE Type of transmission assigned to the profile instance.
+ * @param[in] DEVICE_TYPE Type of device. Supported types: @ref BSC_SPEED_DEVICE_TYPE, @ref BSC_CADENCE_DEVICE_TYPE,
+ * @ref BSC_COMBINED_DEVICE_TYPE.
+ * @param[in] DEVICE_NUMBER Number of the device assigned to the profile instance.
+ * @param[in] NETWORK_NUMBER Number of the network assigned to the profile instance.
+ */
+#define BSC_SENS_CHANNEL_CONFIG_DEF(NAME, \
+ CHANNEL_NUMBER, \
+ TRANSMISSION_TYPE, \
+ DEVICE_TYPE, \
+ DEVICE_NUMBER, \
+ NETWORK_NUMBER) \
+static const ant_channel_config_t NAME##_channel_bsc_sens_config = \
+ { \
+ .channel_number = (CHANNEL_NUMBER), \
+ .channel_type = BSC_SENS_CHANNEL_TYPE, \
+ .ext_assign = BSC_EXT_ASSIGN, \
+ .rf_freq = BSC_ANTPLUS_RF_FREQ, \
+ .transmission_type = (TRANSMISSION_TYPE), \
+ .device_type = (DEVICE_TYPE), \
+ .device_number = (DEVICE_NUMBER), \
+ .channel_period = BSC_PERIOD_TICKS(DEVICE_TYPE, BSC_MSG_PERIOD_4Hz), \
+ .network_number = (NETWORK_NUMBER), \
+ }
+#define BSC_SENS_CHANNEL_CONFIG(NAME) &NAME##_channel_bsc_sens_config
+
+/**@brief Initialize an ANT profile configuration structure for the BSC profile (Display).
+ *
+ * @param[in] NAME Name of related instance.
+ * @param[in] EVT_HANDLER Event handler to be called for handling events in the BSC profile.
+ */
+#define BSC_DISP_PROFILE_CONFIG_DEF(NAME, \
+ EVT_HANDLER) \
+static ant_bsc_disp_cb_t CONCAT_2(NAME, _bsc_disp_cb); \
+static const ant_bsc_disp_config_t CONCAT_2(NAME, _profile_bsc_disp_config) = \
+ { \
+ .p_cb = &CONCAT_2(NAME, _bsc_disp_cb), \
+ .evt_handler = (EVT_HANDLER), \
+ }
+#define BSC_DISP_PROFILE_CONFIG(NAME) &CONCAT_2(NAME, _profile_bsc_disp_config)
+
+
+/**@brief Initialize an ANT profile configuration structure for the BSC profile (Sensor).
+ *
+ * @param[in] NAME Name of related instance.
+ * @param[in] PAGE_1_PRESENT Determines whether page 1 is included.
+ * @param[in] PAGE_4_PRESENT Determines whether page 4 is included.
+ * @param[in] MAIN_PAGE_NUMBER Determines the main data page (@ref ANT_BSC_PAGE_0 or @ref ANT_BSC_PAGE_5 or @ref ANT_BSC_COMB_PAGE_0).
+ * @param[in] EVT_HANDLER Event handler to be called for handling events in the BSC profile.
+ */
+#define BSC_SENS_PROFILE_CONFIG_DEF(NAME, \
+ PAGE_1_PRESENT, \
+ PAGE_4_PRESENT, \
+ MAIN_PAGE_NUMBER, \
+ EVT_HANDLER) \
+static ant_bsc_sens_cb_t CONCAT_2(NAME, _bsc_sens_cb); \
+static const ant_bsc_sens_config_t CONCAT_2(NAME, _profile_bsc_sens_config) = \
+ { \
+ .page_1_present = (PAGE_1_PRESENT), \
+ .page_4_present = (PAGE_4_PRESENT), \
+ .main_page_number = (MAIN_PAGE_NUMBER), \
+ .p_cb = &CONCAT_2(NAME, _bsc_sens_cb), \
+ .evt_handler = (EVT_HANDLER), \
+ }
+#define BSC_SENS_PROFILE_CONFIG(NAME) &CONCAT_2(NAME, _profile_bsc_sens_config)
+
+
+/**@brief BSC page number type. */
+typedef enum{
+ ANT_BSC_PAGE_0, ///< Main data page number 0.
+ ANT_BSC_PAGE_1, ///< Background data page number 1. This page is optional.
+ ANT_BSC_PAGE_2, ///< Background data page number 2.
+ ANT_BSC_PAGE_3, ///< Background data page number 3.
+ ANT_BSC_PAGE_4, ///< Background data page number 4. This page is optional.
+ ANT_BSC_PAGE_5, ///< Main data page number 5. This page is optional.
+ ANT_BSC_COMB_PAGE_0 ///< Main data page number 0 for combined speed and cadence sensor.
+} ant_bsc_page_t;
+
+/**@brief BSC profile event type. */
+typedef enum{
+ ANT_BSC_PAGE_0_UPDATED = ANT_BSC_PAGE_0, ///< Data page 0 has been updated (Display) or sent (Sensor).
+ ANT_BSC_PAGE_1_UPDATED = ANT_BSC_PAGE_1, ///< Data page 0 and page 1 have been updated (Display) or sent (Sensor).
+ ANT_BSC_PAGE_2_UPDATED = ANT_BSC_PAGE_2, ///< Data page 0 and page 2 have been updated (Display) or sent (Sensor).
+ ANT_BSC_PAGE_3_UPDATED = ANT_BSC_PAGE_3, ///< Data page 0 and page 3 have been updated (Display) or sent (Sensor).
+ ANT_BSC_PAGE_4_UPDATED = ANT_BSC_PAGE_4, ///< Data page 0 and page 4 have been updated (Display) or sent (Sensor).
+ ANT_BSC_PAGE_5_UPDATED = ANT_BSC_PAGE_5, ///< Data page 0 and page 5 have been updated (Display) or sent (Sensor).
+ ANT_BSC_COMB_PAGE_0_UPDATED = ANT_BSC_COMB_PAGE_0, ///< Combined Speed and cadence data page has been updated (Display) or sent (Sensor).
+} ant_bsc_evt_t;
+
+// Forward declaration of the ant_bsc_profile_t type.
+typedef struct ant_bsc_profile_s ant_bsc_profile_t;
+
+/**@brief BSC event handler type. */
+typedef void (* ant_bsc_evt_handler_t) (ant_bsc_profile_t *, ant_bsc_evt_t);
+
+#include "ant_bsc_local.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**@brief BSC Display configuration structure. */
+typedef struct
+{
+ ant_bsc_disp_cb_t * p_cb; ///< Pointer to the data buffer for internal use.
+ ant_bsc_evt_handler_t evt_handler; ///< Event handler to be called for handling events in the BSC profile.
+} ant_bsc_disp_config_t;
+
+/**@brief BSC Sensor configuration structure. */
+typedef struct
+{
+ bool page_1_present; ///< Determines whether page 1 is included.
+ bool page_4_present; ///< Determines whether page 4 is included.
+ ant_bsc_page_t main_page_number; ///< Determines the main data page (@ref ANT_BSC_PAGE_0 or @ref ANT_BSC_PAGE_5 or @ref ANT_BSC_COMB_PAGE_0).
+ ant_bsc_sens_cb_t * p_cb; ///< Pointer to the data buffer for internal use.
+ ant_bsc_evt_handler_t evt_handler; ///< Event handler to be called for handling events in the BSC profile.
+} ant_bsc_sens_config_t;
+
+/**@brief BSC profile structure. */
+struct ant_bsc_profile_s
+{
+ uint8_t channel_number; ///< Channel number assigned to the profile.
+ union {
+ ant_bsc_disp_cb_t * p_disp_cb;
+ ant_bsc_sens_cb_t * p_sens_cb;
+ } _cb; ///< Pointer to internal control block.
+ ant_bsc_evt_handler_t evt_handler; ///< Event handler to be called for handling events in the BSC profile.
+ ant_bsc_page0_data_t page_0; ///< Page 0.
+ ant_bsc_page1_data_t page_1; ///< Page 1.
+ ant_bsc_page2_data_t page_2; ///< Page 2.
+ ant_bsc_page3_data_t page_3; ///< Page 3.
+ ant_bsc_page4_data_t page_4; ///< Page 4.
+ ant_bsc_page5_data_t page_5; ///< Page 5.
+ ant_bsc_combined_page0_data_t page_comb_0; ///< Page 0 for combined speed and cadence sensor.
+};
+
+/** @name Defines for accessing ant_bsc_profile_t member variables
+@{ */
+#define BSC_PROFILE_event_time page_0.event_time
+#define BSC_PROFILE_rev_count page_0.rev_count
+#define BSC_PROFILE_operating_time page_1.operating_time
+#define BSC_PROFILE_manuf_id page_2.manuf_id
+#define BSC_PROFILE_serial_num page_2.serial_num
+#define BSC_PROFILE_hw_version page_3.hw_version
+#define BSC_PROFILE_sw_version page_3.sw_version
+#define BSC_PROFILE_model_num page_3.model_num
+#define BSC_PROFILE_fract_bat_volt page_4.fract_bat_volt
+#define BSC_PROFILE_coarse_bat_volt page_4.coarse_bat_volt
+#define BSC_PROFILE_bat_status page_4.bat_status
+#define BSC_PROFILE_stop_indicator page_5.stop_indicator
+#define BSC_PROFILE_cadence_event_time page_comb_0.cadence_event_time
+#define BSC_PROFILE_cadence_rev_count page_comb_0.cadence_rev_count
+#define BSC_PROFILE_speed_event_time page_comb_0.speed_event_time
+#define BSC_PROFILE_speed_rev_count page_comb_0.speed_rev_count
+/** @} */
+
+/**@brief Function for initializing the ANT BSC profile instance.
+ *
+ * @param[in] p_profile Pointer to the profile instance.
+ * @param[in] p_channel_config Pointer to the ANT channel configuration structure.
+ * @param[in] p_disp_config Pointer to the BSC display configuration structure.
+ *
+ * @retval NRF_SUCCESS If initialization was successful. Otherwise, an error code is returned.
+ */
+ret_code_t ant_bsc_disp_init(ant_bsc_profile_t * p_profile,
+ ant_channel_config_t const * p_channel_config,
+ ant_bsc_disp_config_t const * p_disp_config);
+
+/**@brief Function for initializing the ANT BSC profile instance.
+ *
+ * @param[in] p_profile Pointer to the profile instance.
+ * @param[in] p_channel_config Pointer to the ANT channel configuration structure.
+ * @param[in] p_sens_config Pointer to the BSC sensor configuration structure.
+ *
+ * @retval NRF_SUCCESS If initialization was successful. Otherwise, an error code is returned.
+ */
+ret_code_t ant_bsc_sens_init(ant_bsc_profile_t * p_profile,
+ ant_channel_config_t const * p_channel_config,
+ ant_bsc_sens_config_t const * p_sens_config);
+
+/**@brief Function for opening the profile instance channel for the ANT BSC Display.
+ *
+ * Before calling this function, pages should be configured.
+ *
+ * @param[in] p_profile Pointer to the profile instance.
+ *
+ * @retval NRF_SUCCESS If the channel was successfully opened. Otherwise, an error code is returned.
+ */
+ret_code_t ant_bsc_disp_open(ant_bsc_profile_t * p_profile);
+
+/**@brief Function for opening the profile instance channel for the ANT BSC Sensor.
+ *
+ * Before calling this function, pages should be configured.
+ *
+ * @param[in] p_profile Pointer to the profile instance.
+ *
+ * @retval NRF_SUCCESS If the channel was successfully opened. Otherwise, an error code is returned.
+ */
+ret_code_t ant_bsc_sens_open(ant_bsc_profile_t * p_profile);
+
+/**@brief Function for handling the Sensor ANT events.
+ *
+ * @details This function handles all events from the ANT stack that are of interest to the Bicycle Speed and Cadence Sensor profile.
+ *
+ * @param[in] p_ant_evt Event received from the ANT stack.
+ * @param[in] p_context Pointer to the profile instance.
+ */
+void ant_bsc_sens_evt_handler(ant_evt_t * p_ant_evt, void * p_context);
+
+/**@brief Function for handling the Display ANT events.
+ *
+ * @details This function handles all events from the ANT stack that are of interest to the Bicycle Speed and Cadence Display profile.
+ *
+ * @param[in] p_ant_evt Event received from the ANT stack.
+ * @param[in] p_context Pointer to the profile instance.
+ */
+void ant_bsc_disp_evt_handler(ant_evt_t * p_ant_evt, void * p_context);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // ANT_BSC_H__
+/** @} */
+
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ant/ant_profiles/ant_bsc/ant_bsc_local.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ant/ant_profiles/ant_bsc/ant_bsc_local.h
new file mode 100644
index 0000000..44c64cc
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ant/ant_profiles/ant_bsc/ant_bsc_local.h
@@ -0,0 +1,83 @@
+/**
+ * Copyright (c) 2015 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#ifndef ANT_BSC_LOCAL_H__
+#define ANT_BSC_LOCAL_H__
+
+#include <stdint.h>
+#include <stdbool.h>
+#include "ant_bsc.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @addtogroup ant_bsc
+ * @{
+ */
+
+/**@brief BSC Sensor control block. */
+typedef struct
+{
+ uint8_t device_type;
+ uint8_t toggle_bit : 1;
+ ant_bsc_page_t main_page_number : 7;
+ uint8_t page_1_present : 1;
+ uint8_t page_4_present : 1;
+ ant_bsc_page_t bkgd_page_number : 6;
+ uint8_t message_counter;
+}ant_bsc_sens_cb_t;
+
+/**@brief BSC Display control block. */
+typedef struct
+{
+ uint8_t device_type;
+}ant_bsc_disp_cb_t;
+
+/**
+ * @}
+ */
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // ANT_BSC_LOCAL_H__
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ant/ant_profiles/ant_bsc/pages/ant_bsc_combined_page_0.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ant/ant_profiles/ant_bsc/pages/ant_bsc_combined_page_0.c
new file mode 100644
index 0000000..4ac5c62
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ant/ant_profiles/ant_bsc/pages/ant_bsc_combined_page_0.c
@@ -0,0 +1,129 @@
+/**
+ * Copyright (c) 2015 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#include "sdk_common.h"
+#if NRF_MODULE_ENABLED(ANT_BSC)
+
+#include "ant_bsc_combined_page_0.h"
+#include "ant_bsc_utils.h"
+
+#define NRF_LOG_MODULE_NAME ant_bcs_combined_page_0
+#if ANT_BSC_COMBINED_PAGE_0_LOG_ENABLED
+#define NRF_LOG_LEVEL ANT_BSC_COMBINED_PAGE_0_LOG_LEVEL
+#define NRF_LOG_INFO_COLOR ANT_BSC_COMBINED_PAGE_0_INFO_COLOR
+#else // ANT_BSC_COMBINED_PAGE_0_LOG_ENABLED
+#define NRF_LOG_LEVEL 0
+#endif // ANT_BSC_COMBINED_PAGE_0_LOG_ENABLED
+#include "nrf_log.h"
+NRF_LOG_MODULE_REGISTER();
+
+/**@brief BSC page 0 data layout structure. */
+typedef struct
+{
+ uint8_t cadence_evt_time_LSB;
+ uint8_t cadence_evt_time_MSB;
+ uint8_t cadence_rev_count_LSB;
+ uint8_t cadence_rev_count_MSB;
+ uint8_t speed_evt_time_LSB;
+ uint8_t speed_evt_time_MSB;
+ uint8_t speed_rev_count_LSB;
+ uint8_t speed_rev_count_MSB;
+}ant_bsc_combined_page0_data_layout_t;
+
+/**@brief Function for printing combined speed and cadence page0 data. */
+static void comb_page0_data_log(ant_bsc_combined_page0_data_t const * p_page_data)
+{
+ NRF_LOG_INFO("Cadence Revolution count: %u",
+ (unsigned int)p_page_data->cadence_rev_count);
+
+ NRF_LOG_INFO("Cadence event time: %u.%03us",
+ (unsigned int)ANT_BSC_EVENT_TIME_SEC(p_page_data->cadence_event_time),
+ (unsigned int)ANT_BSC_EVENT_TIME_MSEC(p_page_data->cadence_event_time));
+
+ NRF_LOG_INFO("Speed Revolution count: %u",
+ (unsigned int)p_page_data->speed_rev_count);
+
+ NRF_LOG_INFO("Speed event time: %u.%03us\r\n\n",
+ (unsigned int)ANT_BSC_EVENT_TIME_SEC(p_page_data->speed_event_time),
+ (unsigned int)ANT_BSC_EVENT_TIME_MSEC(p_page_data->speed_event_time));
+}
+
+void ant_bsc_combined_page_0_encode(uint8_t * p_page_buffer, ant_bsc_combined_page0_data_t const * p_page_data)
+{
+ ant_bsc_combined_page0_data_layout_t * p_outcoming_data = (ant_bsc_combined_page0_data_layout_t *) p_page_buffer;
+
+ uint16_t cadence_event_time = p_page_data->cadence_event_time;
+ uint16_t cadence_rev_count = p_page_data->cadence_rev_count;
+ uint16_t speed_event_time = p_page_data->speed_event_time;
+ uint16_t speed_rev_count = p_page_data->speed_rev_count;
+
+ p_outcoming_data->cadence_evt_time_LSB = (uint8_t)(cadence_event_time & UINT8_MAX);
+ p_outcoming_data->cadence_evt_time_MSB = (uint8_t)((cadence_event_time >> 8) & UINT8_MAX);
+ p_outcoming_data->cadence_rev_count_LSB = (uint8_t)(cadence_rev_count & UINT8_MAX);
+ p_outcoming_data->cadence_rev_count_MSB = (uint8_t)((cadence_rev_count >> 8) & UINT8_MAX);
+ p_outcoming_data->speed_evt_time_LSB = (uint8_t)(speed_event_time & UINT8_MAX);
+ p_outcoming_data->speed_evt_time_MSB = (uint8_t)((speed_event_time >> 8) & UINT8_MAX);
+ p_outcoming_data->speed_rev_count_LSB = (uint8_t)(speed_rev_count & UINT8_MAX);
+ p_outcoming_data->speed_rev_count_MSB = (uint8_t)((speed_rev_count >> 8) & UINT8_MAX);
+
+ comb_page0_data_log(p_page_data);
+}
+
+void ant_bsc_combined_page_0_decode(uint8_t const * p_page_buffer, ant_bsc_combined_page0_data_t * p_page_data)
+{
+ ant_bsc_combined_page0_data_layout_t const * p_incoming_data = (ant_bsc_combined_page0_data_layout_t *)p_page_buffer;
+
+ uint16_t cadence_event_time = (uint16_t)((p_incoming_data->cadence_evt_time_MSB << 8)
+ + p_incoming_data->cadence_evt_time_LSB);
+ uint16_t cadence_revolution_count = (uint16_t) ((p_incoming_data->cadence_rev_count_MSB << 8)
+ + p_incoming_data->cadence_rev_count_LSB);
+ uint16_t speed_event_time = (uint16_t)((p_incoming_data->speed_evt_time_MSB << 8)
+ + p_incoming_data->speed_evt_time_LSB);
+ uint16_t speed_revolution_count = (uint16_t) ((p_incoming_data->speed_rev_count_MSB << 8)
+ + p_incoming_data->speed_rev_count_LSB);
+
+ p_page_data->cadence_event_time = cadence_event_time;
+ p_page_data->cadence_rev_count = cadence_revolution_count;
+ p_page_data->speed_event_time = speed_event_time;
+ p_page_data->speed_rev_count = speed_revolution_count;
+
+ comb_page0_data_log(p_page_data);
+}
+
+#endif // NRF_MODULE_ENABLED(ANT_BSC)
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ant/ant_profiles/ant_bsc/pages/ant_bsc_combined_page_0.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ant/ant_profiles/ant_bsc/pages/ant_bsc_combined_page_0.h
new file mode 100644
index 0000000..b1e5fef
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ant/ant_profiles/ant_bsc/pages/ant_bsc_combined_page_0.h
@@ -0,0 +1,99 @@
+/**
+ * Copyright (c) 2015 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#ifndef ANT_BSC_COMBINED_PAGE_0_H__
+#define ANT_BSC_COMBINED_PAGE_0_H__
+
+/** @file
+ *
+ * @defgroup ant_sdk_profiles_bsc_combined_page0 BSC profile page 0 (combined speed & cadence)
+ * @{
+ * @ingroup ant_sdk_profiles_bsc_pages
+ */
+
+#include <stdint.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**@brief Data structure for Bicycle Combined Speed and Cadence data page 0.
+ *
+ * This structure is used as a common page.
+ */
+typedef struct
+{
+ uint16_t cadence_event_time; ///< Cadence event time.
+ uint16_t cadence_rev_count; ///< Cadence revolution count.
+ uint16_t speed_event_time; ///< Speed event time.
+ uint16_t speed_rev_count; ///< Speed revolution count.
+} ant_bsc_combined_page0_data_t;
+
+/**@brief Initialize page 0.
+ */
+#define DEFAULT_ANT_BSC_COMBINED_PAGE0() \
+ (ant_bsc_combined_page0_data_t) \
+ { \
+ .cadence_event_time = 0, \
+ .cadence_rev_count = 0, \
+ .speed_event_time = 0, \
+ .speed_rev_count = 0, \
+ }
+
+/**@brief Function for encoding page 0.
+ *
+ * @param[in] p_page_data Pointer to the page data.
+ * @param[out] p_page_buffer Pointer to the data buffer.
+ */
+void ant_bsc_combined_page_0_encode(uint8_t * p_page_buffer, ant_bsc_combined_page0_data_t const * p_page_data);
+
+/**@brief Function for decoding page 0.
+ *
+ * @param[in] p_page_buffer Pointer to the data buffer.
+ * @param[out] p_page_data Pointer to the page data.
+ */
+void ant_bsc_combined_page_0_decode(uint8_t const * p_page_buffer, ant_bsc_combined_page0_data_t * p_page_data);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // ANT_BSC_COMBINED_PAGE_0_H__
+/** @} */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ant/ant_profiles/ant_bsc/pages/ant_bsc_page_0.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ant/ant_profiles/ant_bsc/pages/ant_bsc_page_0.c
new file mode 100644
index 0000000..3122336
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ant/ant_profiles/ant_bsc/pages/ant_bsc_page_0.c
@@ -0,0 +1,111 @@
+/**
+ * Copyright (c) 2015 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#include "sdk_common.h"
+#if NRF_MODULE_ENABLED(ANT_BSC)
+
+#include "ant_bsc_page_0.h"
+#include "ant_bsc_utils.h"
+
+#define NRF_LOG_MODULE_NAME ant_bcs_page_0
+#if ANT_BSC_PAGE_0_LOG_ENABLED
+#define NRF_LOG_LEVEL ANT_BSC_PAGE_0_LOG_LEVEL
+#define NRF_LOG_INFO_COLOR ANT_BSC_PAGE_0_INFO_COLOR
+#else // ANT_BSC_PAGE_0_LOG_ENABLED
+#define NRF_LOG_LEVEL 0
+#endif // ANT_BSC_PAGE_0_LOG_ENABLED
+#include "nrf_log.h"
+NRF_LOG_MODULE_REGISTER();
+
+/**@brief BSC page 0 data layout structure. */
+typedef struct
+{
+ uint8_t reserved[3];
+ uint8_t bsc_evt_time_LSB;
+ uint8_t bsc_evt_time_MSB;
+ uint8_t bsc_rev_count_LSB;
+ uint8_t bsc_rev_count_MSB;
+}ant_bsc_page0_data_layout_t;
+
+/**@brief Function for printing speed or cadence page0 data. */
+static void page0_data_log(ant_bsc_page0_data_t const * p_page_data)
+{
+ NRF_LOG_INFO("Revolution count: %u", (unsigned int)p_page_data->rev_count);
+
+ NRF_LOG_INFO("BSC event time: %u.%03us",
+ (unsigned int)ANT_BSC_EVENT_TIME_SEC(p_page_data->event_time),
+ (unsigned int)ANT_BSC_EVENT_TIME_MSEC(p_page_data->event_time));
+
+// NRF_LOG_INFO("%03us", (unsigned int)ANT_BSC_EVENT_TIME_MSEC(p_page_data->event_time));
+}
+
+void ant_bsc_page_0_encode(uint8_t * p_page_buffer, ant_bsc_page0_data_t const * p_page_data)
+{
+ ant_bsc_page0_data_layout_t * p_outcoming_data = (ant_bsc_page0_data_layout_t *) p_page_buffer;
+ uint16_t event_time = p_page_data->event_time;
+ uint16_t rev_count = p_page_data->rev_count;
+
+ p_outcoming_data->reserved[0] = UINT8_MAX;
+ p_outcoming_data->reserved[1] = UINT8_MAX;
+ p_outcoming_data->reserved[2] = UINT8_MAX;
+ p_outcoming_data->bsc_evt_time_LSB = (uint8_t)(event_time & UINT8_MAX);
+ p_outcoming_data->bsc_evt_time_MSB = (uint8_t)((event_time >> 8) & UINT8_MAX);
+ p_outcoming_data->bsc_rev_count_LSB = (uint8_t)(rev_count & UINT8_MAX);
+ p_outcoming_data->bsc_rev_count_MSB = (uint8_t)((rev_count >> 8) & UINT8_MAX);
+
+ page0_data_log(p_page_data);
+}
+
+void ant_bsc_page_0_decode(uint8_t const * p_page_buffer, ant_bsc_page0_data_t * p_page_data)
+{
+ ant_bsc_page0_data_layout_t const * p_incoming_data = (ant_bsc_page0_data_layout_t *)p_page_buffer;
+
+ uint16_t event_time = (uint16_t)((p_incoming_data->bsc_evt_time_MSB << 8)
+ + p_incoming_data->bsc_evt_time_LSB);
+
+ uint16_t revolution_count = (uint16_t) ((p_incoming_data->bsc_rev_count_MSB << 8)
+ + p_incoming_data->bsc_rev_count_LSB);
+
+ p_page_data->event_time = event_time;
+ p_page_data->rev_count = revolution_count;
+
+ page0_data_log(p_page_data);
+}
+
+#endif // NRF_MODULE_ENABLED(ANT_BSC)
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ant/ant_profiles/ant_bsc/pages/ant_bsc_page_0.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ant/ant_profiles/ant_bsc/pages/ant_bsc_page_0.h
new file mode 100644
index 0000000..bce264f
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ant/ant_profiles/ant_bsc/pages/ant_bsc_page_0.h
@@ -0,0 +1,95 @@
+/**
+ * Copyright (c) 2015 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#ifndef ANT_BSC_PAGE_0_H__
+#define ANT_BSC_PAGE_0_H__
+
+/** @file
+ *
+ * @defgroup ant_sdk_profiles_bsc_page0 BSC profile page 0
+ * @{
+ * @ingroup ant_sdk_profiles_bsc_pages
+ */
+
+#include <stdint.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**@brief Data structure for BSC data page 0.
+ *
+ * This structure is used as a common page.
+ */
+typedef struct
+{
+ uint16_t event_time; ///< Speed or cadence event time.
+ uint16_t rev_count; ///< Speed or cadence revolution count.
+} ant_bsc_page0_data_t;
+
+/**@brief Initialize page 0.
+ */
+#define DEFAULT_ANT_BSC_PAGE0() \
+ (ant_bsc_page0_data_t) \
+ { \
+ .event_time = 0, \
+ .rev_count = 0 \
+ }
+
+/**@brief Function for encoding page 0.
+ *
+ * @param[in] p_page_data Pointer to the page data.
+ * @param[out] p_page_buffer Pointer to the data buffer.
+ */
+void ant_bsc_page_0_encode(uint8_t * p_page_buffer, ant_bsc_page0_data_t const * p_page_data);
+
+/**@brief Function for decoding page 0.
+ *
+ * @param[in] p_page_buffer Pointer to the data buffer.
+ * @param[out] p_page_data Pointer to the page data.
+ */
+void ant_bsc_page_0_decode(uint8_t const * p_page_buffer, ant_bsc_page0_data_t * p_page_data);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // ANT_BSC_PAGE_0_H__
+/** @} */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ant/ant_profiles/ant_bsc/pages/ant_bsc_page_1.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ant/ant_profiles/ant_bsc/pages/ant_bsc_page_1.c
new file mode 100644
index 0000000..929b655
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ant/ant_profiles/ant_bsc/pages/ant_bsc_page_1.c
@@ -0,0 +1,94 @@
+/**
+ * Copyright (c) 2015 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#include "sdk_common.h"
+#if NRF_MODULE_ENABLED(ANT_BSC)
+
+#include "ant_bsc_page_1.h"
+#include "ant_bsc_utils.h"
+#include "app_util.h"
+#include "nordic_common.h"
+
+#define NRF_LOG_MODULE_NAME ant_bcs_page_1
+#if ANT_BSC_PAGE_1_LOG_ENABLED
+#define NRF_LOG_LEVEL ANT_BSC_PAGE_1_LOG_LEVEL
+#define NRF_LOG_INFO_COLOR ANT_BSC_PAGE_1_INFO_COLOR
+#else // ANT_BSC_PAGE_1_LOG_ENABLED
+#define NRF_LOG_LEVEL 0
+#endif // ANT_BSC_PAGE_1_LOG_ENABLED
+#include "nrf_log.h"
+NRF_LOG_MODULE_REGISTER();
+
+/**@brief BSC page 1 data layout structure. */
+typedef struct
+{
+ uint8_t cumulative_operating_time[3];
+ uint8_t reserved[4];
+}ant_bsc_page1_data_layout_t;
+
+/**@brief Function for printing speed or cadence page1 data. */
+static void page1_data_log(ant_bsc_page1_data_t const * p_page_data)
+{
+ NRF_LOG_INFO("Cumulative operating time: %ud %uh %um %us",
+ (unsigned int)ANT_BSC_OPERATING_DAYS(p_page_data->operating_time),
+ (unsigned int)ANT_BSC_OPERATING_HOURS(p_page_data->operating_time),
+ (unsigned int)ANT_BSC_OPERATING_MINUTES(p_page_data->operating_time),
+ (unsigned int)ANT_BSC_OPERATING_SECONDS(p_page_data->operating_time));
+}
+
+void ant_bsc_page_1_encode(uint8_t * p_page_buffer, ant_bsc_page1_data_t const * p_page_data)
+{
+ ant_bsc_page1_data_layout_t * p_outcoming_data = (ant_bsc_page1_data_layout_t *)p_page_buffer;
+
+ UNUSED_PARAMETER(uint24_encode(p_page_data->operating_time,
+ p_outcoming_data->cumulative_operating_time));
+ page1_data_log( p_page_data);
+}
+
+void ant_bsc_page_1_decode(uint8_t const * p_page_buffer, ant_bsc_page1_data_t * p_page_data)
+{
+ ant_bsc_page1_data_layout_t const * p_incoming_data = (ant_bsc_page1_data_layout_t *)p_page_buffer;
+
+ p_page_data->operating_time = uint24_decode(p_incoming_data->cumulative_operating_time);
+
+ page1_data_log( p_page_data);
+}
+
+#endif // NRF_MODULE_ENABLED(ANT_BSC)
+
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ant/ant_profiles/ant_bsc/pages/ant_bsc_page_1.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ant/ant_profiles/ant_bsc/pages/ant_bsc_page_1.h
new file mode 100644
index 0000000..3739da6
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ant/ant_profiles/ant_bsc/pages/ant_bsc_page_1.h
@@ -0,0 +1,93 @@
+/**
+ * Copyright (c) 2015 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#ifndef ANT_BSC_PAGE_1_H__
+#define ANT_BSC_PAGE_1_H__
+
+/** @file
+ *
+ * @defgroup ant_sdk_profiles_bsc_page1 BSC profile page 1
+ * @{
+ * @ingroup ant_sdk_profiles_bsc_pages
+ */
+
+#include <stdint.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**@brief Data structure for BSC data page 1.
+ *
+ * This structure implements only page 1 specific data.
+ */
+typedef struct
+{
+ uint32_t operating_time; ///< Operating time.
+} ant_bsc_page1_data_t;
+
+/**@brief Initialize page 1.
+ */
+#define DEFAULT_ANT_BSC_PAGE1() \
+ (ant_bsc_page1_data_t) \
+ { \
+ .operating_time = 0, \
+ }
+
+/**@brief Function for encoding page 1.
+ *
+ * @param[in] p_page_data Pointer to the page data.
+ * @param[out] p_page_buffer Pointer to the data buffer.
+ */
+void ant_bsc_page_1_encode(uint8_t * p_page_buffer, ant_bsc_page1_data_t const * p_page_data);
+
+/**@brief Function for decoding page 1.
+ *
+ * @param[in] p_page_buffer Pointer to the data buffer.
+ * @param[out] p_page_data Pointer to the page data.
+ */
+void ant_bsc_page_1_decode(uint8_t const * p_page_buffer, ant_bsc_page1_data_t * p_page_data);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // ANT_BSC_PAGE_1_H__
+/** @} */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ant/ant_profiles/ant_bsc/pages/ant_bsc_page_2.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ant/ant_profiles/ant_bsc/pages/ant_bsc_page_2.c
new file mode 100644
index 0000000..4fb01d2
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ant/ant_profiles/ant_bsc/pages/ant_bsc_page_2.c
@@ -0,0 +1,96 @@
+/**
+ * Copyright (c) 2015 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#include "sdk_common.h"
+#if NRF_MODULE_ENABLED(ANT_BSC)
+
+#include "ant_bsc_page_2.h"
+
+#define NRF_LOG_MODULE_NAME ant_bcs_page_2
+#if ANT_BSC_PAGE_2_LOG_ENABLED
+#define NRF_LOG_LEVEL ANT_BSC_PAGE_2_LOG_LEVEL
+#define NRF_LOG_INFO_COLOR ANT_BSC_PAGE_2_INFO_COLOR
+#else // ANT_BSC_PAGE_2_LOG_ENABLED
+#define NRF_LOG_LEVEL 0
+#endif // ANT_BSC_PAGE_2_LOG_ENABLED
+#include "nrf_log.h"
+NRF_LOG_MODULE_REGISTER();
+
+/**@brief BSC page 2 data layout structure. */
+typedef struct
+{
+ uint8_t manuf_id;
+ uint8_t serial_num_LSB;
+ uint8_t serial_num_MSB;
+ uint8_t reserved[4];
+}ant_bsc_page2_data_layout_t;
+
+/**@brief Function for printing speed or cadence page2 data. */
+static void page2_data_log(ant_bsc_page2_data_t const * p_page_data)
+{
+ NRF_LOG_INFO("Manufacturer ID: %u", (unsigned int)p_page_data->manuf_id);
+ NRF_LOG_INFO("Serial No (upper 16-bits): 0x%X",
+ (unsigned int)p_page_data->serial_num);
+}
+
+void ant_bsc_page_2_encode(uint8_t * p_page_buffer, ant_bsc_page2_data_t const * p_page_data)
+{
+ ant_bsc_page2_data_layout_t * p_outcoming_data = (ant_bsc_page2_data_layout_t *)p_page_buffer;
+ uint32_t serial_num = p_page_data->serial_num;
+
+ p_outcoming_data->manuf_id = (uint8_t)p_page_data->manuf_id;
+ p_outcoming_data->serial_num_LSB = (uint8_t)(serial_num & UINT8_MAX);
+ p_outcoming_data->serial_num_MSB = (uint8_t)((serial_num >> 8) & UINT8_MAX);
+
+ page2_data_log( p_page_data);
+}
+
+void ant_bsc_page_2_decode(uint8_t const * p_page_buffer, ant_bsc_page2_data_t * p_page_data)
+{
+ ant_bsc_page2_data_layout_t const * p_incoming_data = (ant_bsc_page2_data_layout_t *)p_page_buffer;
+ uint32_t serial_num = (uint32_t)((p_incoming_data->serial_num_MSB << 8)
+ + p_incoming_data->serial_num_LSB);
+
+ p_page_data->manuf_id = (uint32_t)p_incoming_data->manuf_id;
+ p_page_data->serial_num = serial_num;
+
+ page2_data_log( p_page_data);
+}
+
+#endif // NRF_MODULE_ENABLED(ANT_BSC)
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ant/ant_profiles/ant_bsc/pages/ant_bsc_page_2.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ant/ant_profiles/ant_bsc/pages/ant_bsc_page_2.h
new file mode 100644
index 0000000..55d9793
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ant/ant_profiles/ant_bsc/pages/ant_bsc_page_2.h
@@ -0,0 +1,95 @@
+/**
+ * Copyright (c) 2015 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#ifndef ANT_BSC_PAGE_2_H__
+#define ANT_BSC_PAGE_2_H__
+
+/** @file
+ *
+ * @defgroup ant_sdk_profiles_bsc_page2 BSC profile page 2
+ * @{
+ * @ingroup ant_sdk_profiles_bsc_pages
+ */
+
+#include <stdint.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**@brief Data structure for BSC data page 2.
+ *
+ * This structure implements only page 2 specific data.
+ */
+typedef struct
+{
+ uint8_t manuf_id; ///< Manufacturer ID.
+ uint16_t serial_num; ///< Serial number.
+} ant_bsc_page2_data_t;
+
+/**@brief Initialize page 2.
+ */
+#define DEFAULT_ANT_BSC_PAGE2() \
+ (ant_bsc_page2_data_t) \
+ { \
+ .manuf_id = 0, \
+ .serial_num = 0, \
+ }
+
+/**@brief Function for encoding page 2.
+ *
+ * @param[in] p_page_data Pointer to the page data.
+ * @param[out] p_page_buffer Pointer to the data buffer.
+ */
+void ant_bsc_page_2_encode(uint8_t * p_page_buffer, ant_bsc_page2_data_t const * p_page_data);
+
+/**@brief Function for decoding page 2.
+ *
+ * @param[in] p_page_buffer Pointer to the data buffer.
+ * @param[out] p_page_data Pointer to the page data.
+ */
+void ant_bsc_page_2_decode(uint8_t const * p_page_buffer, ant_bsc_page2_data_t * p_page_data);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // ANT_BSC_PAGE_2_H__
+/** @} */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ant/ant_profiles/ant_bsc/pages/ant_bsc_page_3.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ant/ant_profiles/ant_bsc/pages/ant_bsc_page_3.c
new file mode 100644
index 0000000..ab52197
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ant/ant_profiles/ant_bsc/pages/ant_bsc_page_3.c
@@ -0,0 +1,94 @@
+/**
+ * Copyright (c) 2015 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#include "sdk_common.h"
+#if NRF_MODULE_ENABLED(ANT_BSC)
+
+#include "ant_bsc_page_3.h"
+
+#define NRF_LOG_MODULE_NAME ant_bcs_page_3
+#if ANT_BSC_PAGE_3_LOG_ENABLED
+#define NRF_LOG_LEVEL ANT_BSC_PAGE_3_LOG_LEVEL
+#define NRF_LOG_INFO_COLOR ANT_BSC_PAGE_3_INFO_COLOR
+#else // ANT_BSC_PAGE_3_LOG_ENABLED
+#define NRF_LOG_LEVEL 0
+#endif // ANT_BSC_PAGE_3_LOG_ENABLED
+#include "nrf_log.h"
+NRF_LOG_MODULE_REGISTER();
+
+/**@brief BSC page 3 data layout structure. */
+typedef struct
+{
+ uint8_t hw_version;
+ uint8_t sw_version;
+ uint8_t model_num;
+ uint8_t reserved[4];
+}ant_bsc_page3_data_layout_t;
+
+/**@brief Function for printing speed or cadence page3 data. */
+static void page3_data_log(ant_bsc_page3_data_t const * p_page_data)
+{
+ NRF_LOG_INFO("Hardware Rev ID: %u", (unsigned int)p_page_data->hw_version);
+ NRF_LOG_INFO("Model Number: %u", (unsigned int)p_page_data->model_num);
+ NRF_LOG_INFO("Software Ver ID: %u", (unsigned int)p_page_data->sw_version);
+}
+
+void ant_bsc_page_3_encode(uint8_t * p_page_buffer, ant_bsc_page3_data_t const * p_page_data)
+{
+ ant_bsc_page3_data_layout_t * p_outcoming_data = (ant_bsc_page3_data_layout_t *)p_page_buffer;
+
+ p_outcoming_data->hw_version = (uint8_t)p_page_data->hw_version;
+ p_outcoming_data->sw_version = (uint8_t)p_page_data->sw_version;
+ p_outcoming_data->model_num = (uint8_t)p_page_data->model_num;
+
+ page3_data_log( p_page_data);
+}
+
+void ant_bsc_page_3_decode(uint8_t const * p_page_buffer, ant_bsc_page3_data_t * p_page_data)
+{
+ ant_bsc_page3_data_layout_t const * p_incoming_data = (ant_bsc_page3_data_layout_t *)p_page_buffer;
+
+ p_page_data->hw_version = (uint32_t)p_incoming_data->hw_version;
+ p_page_data->sw_version = (uint32_t)p_incoming_data->sw_version;
+ p_page_data->model_num = (uint32_t)p_incoming_data->model_num;
+
+ page3_data_log( p_page_data);
+}
+
+#endif // NRF_MODULE_ENABLED(ANT_BSC)
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ant/ant_profiles/ant_bsc/pages/ant_bsc_page_3.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ant/ant_profiles/ant_bsc/pages/ant_bsc_page_3.h
new file mode 100644
index 0000000..6aa663e
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ant/ant_profiles/ant_bsc/pages/ant_bsc_page_3.h
@@ -0,0 +1,97 @@
+/**
+ * Copyright (c) 2015 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#ifndef ANT_BSC_PAGE_3_H__
+#define ANT_BSC_PAGE_3_H__
+
+/** @file
+ *
+ * @defgroup ant_sdk_profiles_bsc_page3 BSC profile page 3
+ * @{
+ * @ingroup ant_sdk_profiles_bsc_pages
+ */
+
+#include <stdint.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**@brief Data structure for BSC data page 3.
+ *
+ * This structure implements only page 3 specific data.
+ */
+typedef struct
+{
+ uint8_t hw_version; ///< Hardware version.
+ uint8_t sw_version; ///< Software version.
+ uint8_t model_num; ///< Model number.
+} ant_bsc_page3_data_t;
+
+/**@brief Initialize page 3.
+ */
+#define DEFAULT_ANT_BSC_PAGE3() \
+ (ant_bsc_page3_data_t) \
+ { \
+ .hw_version = 0, \
+ .sw_version = 0, \
+ .model_num = 0, \
+ }
+
+/**@brief Function for encoding page 3.
+ *
+ * @param[in] p_page_data Pointer to the page data.
+ * @param[out] p_page_buffer Pointer to the data buffer.
+ */
+void ant_bsc_page_3_encode(uint8_t * p_page_buffer, ant_bsc_page3_data_t const * p_page_data);
+
+/**@brief Function for decoding page 3.
+ *
+ * @param[in] p_page_buffer Pointer to the data buffer.
+ * @param[out] p_page_data Pointer to the page data.
+ */
+void ant_bsc_page_3_decode(uint8_t const * p_page_buffer, ant_bsc_page3_data_t * p_page_data);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // ANT_BSC_PAGE_3_H__
+/** @} */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ant/ant_profiles/ant_bsc/pages/ant_bsc_page_4.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ant/ant_profiles/ant_bsc/pages/ant_bsc_page_4.c
new file mode 100644
index 0000000..a8f83f2
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ant/ant_profiles/ant_bsc/pages/ant_bsc_page_4.c
@@ -0,0 +1,104 @@
+/**
+ * Copyright (c) 2015 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#include "sdk_common.h"
+#if NRF_MODULE_ENABLED(ANT_BSC)
+
+#include "ant_bsc_page_4.h"
+#include "ant_bsc_utils.h"
+#include "app_util.h"
+
+#define NRF_LOG_MODULE_NAME ant_bcs_page_4
+#if ANT_BSC_PAGE_4_LOG_ENABLED
+#define NRF_LOG_LEVEL ANT_BSC_PAGE_4_LOG_LEVEL
+#define NRF_LOG_INFO_COLOR ANT_BSC_PAGE_4_INFO_COLOR
+#else // ANT_BSC_PAGE_4_LOG_ENABLED
+#define NRF_LOG_LEVEL 0
+#endif // ANT_BSC_PAGE_4_LOG_ENABLED
+#include "nrf_log.h"
+NRF_LOG_MODULE_REGISTER();
+
+/**@brief BSC page 4 data layout structure. */
+typedef struct
+{
+ uint8_t reserved_byte;
+ uint8_t fract_bat_volt;
+ uint8_t coarse_bat_volt : 4;
+ uint8_t bat_status : 3;
+ uint8_t bitfield_reserved : 1;
+ uint8_t reserved[4];
+}ant_bsc_page4_data_layout_t;
+
+/* Display precission must be updated. */
+STATIC_ASSERT(ANT_BSC_BAT_VOLTAGE_PRECISION == 1000);
+
+/**@brief Function for printing speed or cadence page4 data. */
+static void page4_data_log( ant_bsc_page4_data_t const * p_page_data)
+{
+ NRF_LOG_INFO("Battery voltage: %u.%03uV",
+ (unsigned int)p_page_data->coarse_bat_volt,
+ (unsigned int)ANT_BSC_BAT_VOLTAGE_FRACTION_MV(p_page_data->fract_bat_volt));
+ NRF_LOG_INFO("Battery status: %u", (unsigned int)p_page_data->bat_status);
+}
+
+void ant_bsc_page_4_encode(uint8_t * p_page_buffer, ant_bsc_page4_data_t const * p_page_data)
+{
+ ant_bsc_page4_data_layout_t * p_outcoming_data = (ant_bsc_page4_data_layout_t *)p_page_buffer;
+
+ p_outcoming_data->reserved_byte = UINT8_MAX;
+ p_outcoming_data->fract_bat_volt = p_page_data->fract_bat_volt;
+ p_outcoming_data->coarse_bat_volt = p_page_data->coarse_bat_volt;
+ p_outcoming_data->bat_status = p_page_data->bat_status;
+ p_outcoming_data->bitfield_reserved = 0;
+
+ page4_data_log( p_page_data);
+}
+
+void ant_bsc_page_4_decode(uint8_t const * p_page_buffer, ant_bsc_page4_data_t * p_page_data)
+{
+ ant_bsc_page4_data_layout_t const * p_incoming_data = (ant_bsc_page4_data_layout_t *)p_page_buffer;
+
+ p_page_data->fract_bat_volt = p_incoming_data->fract_bat_volt;
+ p_page_data->coarse_bat_volt = p_incoming_data->coarse_bat_volt;
+ p_page_data->bat_status = p_incoming_data->bat_status;
+
+ page4_data_log( p_page_data);
+}
+
+#endif // NRF_MODULE_ENABLED(ANT_BSC)
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ant/ant_profiles/ant_bsc/pages/ant_bsc_page_4.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ant/ant_profiles/ant_bsc/pages/ant_bsc_page_4.h
new file mode 100644
index 0000000..093ef57
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ant/ant_profiles/ant_bsc/pages/ant_bsc_page_4.h
@@ -0,0 +1,113 @@
+/**
+ * Copyright (c) 2015 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#ifndef ANT_BSC_PAGE_4_H__
+#define ANT_BSC_PAGE_4_H__
+
+/** @file
+ *
+ * @defgroup ant_sdk_profiles_bsc_page4 BSC profile page 4
+ * @{
+ * @ingroup ant_sdk_profiles_bsc_pages
+ */
+
+#include <stdint.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**@brief BSC profile battery status.
+ *
+ * This enum represents possible battery status values for the ANT BSC profile.
+ */
+typedef enum
+{
+ RESERVED0 = 0, ///< Reserved.
+ BSC_BAT_STATUS_NEW = 1, ///< Battery status: new.
+ BSC_BAT_STATUS_GOOD = 2, ///< Battery status: good.
+ BSC_BAT_STATUS_OK = 3, ///< Battery status: ok.
+ BSC_BAT_STATUS_LOW = 4, ///< Battery status: low.
+ BSC_BAT_STATUS_CRITICAL = 5, ///< Battery status: critical.
+ RESERVED1 = 6, ///< Reserved.
+ BSC_BAT_STATUS_INVALID = 7 ///< Invalid battery status.
+} ant_bsc_bat_status_t;
+
+/**@brief Data structure for BSC data page 4.
+ *
+ * This structure implements only page 4 specific data.
+ */
+typedef struct
+{
+ uint8_t fract_bat_volt; ///< Fractional battery voltage.
+ uint8_t coarse_bat_volt : 4; ///< Coarse battery voltage.
+ uint8_t bat_status : 3; ///< Battery status.
+} ant_bsc_page4_data_t;
+
+/**@brief Initialize page 4.
+ */
+#define DEFAULT_ANT_BSC_PAGE4() \
+ (ant_bsc_page4_data_t) \
+ { \
+ .fract_bat_volt = 0, \
+ .coarse_bat_volt = 0, \
+ .bat_status = BSC_BAT_STATUS_INVALID \
+ }
+
+/**@brief Function for encoding page 4.
+ *
+ * @param[in] p_page_data Pointer to the page data.
+ * @param[out] p_page_buffer Pointer to the data buffer.
+ */
+void ant_bsc_page_4_encode(uint8_t * p_page_buffer, ant_bsc_page4_data_t const * p_page_data);
+
+/**@brief Function for decoding page 4.
+ *
+ * @param[in] p_page_buffer Pointer to the data buffer.
+ * @param[out] p_page_data Pointer to the page data.
+ */
+void ant_bsc_page_4_decode(uint8_t const * p_page_buffer, ant_bsc_page4_data_t * p_page_data);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // ANT_BSC_PAGE_4_H__
+/** @} */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ant/ant_profiles/ant_bsc/pages/ant_bsc_page_5.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ant/ant_profiles/ant_bsc/pages/ant_bsc_page_5.c
new file mode 100644
index 0000000..c861143
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ant/ant_profiles/ant_bsc/pages/ant_bsc_page_5.c
@@ -0,0 +1,97 @@
+/**
+ * Copyright (c) 2015 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#include "sdk_common.h"
+#if NRF_MODULE_ENABLED(ANT_BSC)
+
+#include "ant_bsc_page_5.h"
+#include "ant_bsc_utils.h"
+
+#define NRF_LOG_MODULE_NAME ant_bcs_page_5
+#if ANT_BSC_PAGE_5_LOG_ENABLED
+#define NRF_LOG_LEVEL ANT_BSC_PAGE_5_LOG_LEVEL
+#define NRF_LOG_INFO_COLOR ANT_BSC_PAGE_5_INFO_COLOR
+#else // ANT_BSC_PAGE_5_LOG_ENABLED
+#define NRF_LOG_LEVEL 0
+#endif // ANT_BSC_PAGE_5_LOG_ENABLED
+#include "nrf_log.h"
+NRF_LOG_MODULE_REGISTER();
+
+/**@brief BSC profile page 5 bitfields definitions. */
+#define ANT_BSC_STOP_IND_MASK 0x01
+
+/**@brief BSC page 5 data layout structure. */
+typedef struct
+{
+ uint8_t flags;
+ uint8_t reserved[6];
+}ant_bsc_page5_data_layout_t;
+
+/**@brief Function for printing speed or cadence page5 data. */
+static void page5_data_log(ant_bsc_page5_data_t const * p_page_data)
+{
+ if (p_page_data->stop_indicator)
+ {
+ NRF_LOG_INFO("Bicycle stopped.");
+ }
+ else
+ {
+ NRF_LOG_INFO("Bicycle moving.");
+ }
+}
+
+void ant_bsc_page_5_encode(uint8_t * p_page_buffer, ant_bsc_page5_data_t const * p_page_data)
+{
+ ant_bsc_page5_data_layout_t * p_outcoming_data = (ant_bsc_page5_data_layout_t *)p_page_buffer;
+
+ p_outcoming_data->flags = (uint8_t)p_page_data->stop_indicator;
+
+ page5_data_log( p_page_data);
+}
+
+void ant_bsc_page_5_decode(uint8_t const * p_page_buffer, ant_bsc_page5_data_t * p_page_data)
+{
+ ant_bsc_page5_data_layout_t const * p_incoming_data = (ant_bsc_page5_data_layout_t *)p_page_buffer;
+
+ p_page_data->stop_indicator = (p_incoming_data->flags) & ANT_BSC_STOP_IND_MASK;
+
+ page5_data_log( p_page_data);
+}
+
+#endif // NRF_MODULE_ENABLED(ANT_BSC)
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ant/ant_profiles/ant_bsc/pages/ant_bsc_page_5.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ant/ant_profiles/ant_bsc/pages/ant_bsc_page_5.h
new file mode 100644
index 0000000..64cd241
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ant/ant_profiles/ant_bsc/pages/ant_bsc_page_5.h
@@ -0,0 +1,95 @@
+/**
+ * Copyright (c) 2015 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#ifndef ANT_BSC_PAGE_5_H__
+#define ANT_BSC_PAGE_5_H__
+
+/** @file
+ *
+ * @defgroup ant_sdk_profiles_bsc_page5 BSC profile page 5
+ * @{
+ * @ingroup ant_sdk_profiles_bsc_pages
+ */
+
+#include <stdint.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**@brief Data structure for BSC data page 5.
+ *
+ * This structure implements only page 5 specific data.
+ */
+typedef struct
+{
+ uint8_t stop_indicator:1; ///< Stop indication bit.
+ uint8_t reserved:7; ///< Reserved.
+} ant_bsc_page5_data_t;
+
+/**@brief Initialize page 5.
+ */
+#define DEFAULT_ANT_BSC_PAGE5() \
+ (ant_bsc_page5_data_t) \
+ { \
+ .stop_indicator = 0, \
+ .reserved = 0, \
+ }
+
+/**@brief Function for encoding page 5.
+ *
+ * @param[in] p_page_data Pointer to the page data.
+ * @param[out] p_page_buffer Pointer to the data buffer.
+ */
+void ant_bsc_page_5_encode(uint8_t * p_page_buffer, ant_bsc_page5_data_t const * p_page_data);
+
+/**@brief Function for decoding page 5.
+ *
+ * @param[in] p_page_buffer Pointer to the data buffer.
+ * @param[out] p_page_data Pointer to the page data.
+ */
+void ant_bsc_page_5_decode(uint8_t const * p_page_buffer, ant_bsc_page5_data_t * p_page_data);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // ANT_BSC_PAGE_5_H__
+/** @} */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ant/ant_profiles/ant_bsc/pages/ant_bsc_pages.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ant/ant_profiles/ant_bsc/pages/ant_bsc_pages.h
new file mode 100644
index 0000000..f725e66
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ant/ant_profiles/ant_bsc/pages/ant_bsc_pages.h
@@ -0,0 +1,69 @@
+/**
+ * Copyright (c) 2015 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#ifndef __ANT_BSC_PAGES_H
+#define __ANT_BSC_PAGES_H
+
+/** @file
+ *
+ * @defgroup ant_sdk_profiles_bsc_pages Bicycle Speed and Cadence profile pages
+ * @{
+ * @ingroup ant_bsc
+ * @brief This module implements functions for the BSC data pages.
+ */
+
+#include "ant_bsc_page_0.h"
+#include "ant_bsc_page_1.h"
+#include "ant_bsc_page_2.h"
+#include "ant_bsc_page_3.h"
+#include "ant_bsc_page_4.h"
+#include "ant_bsc_page_5.h"
+#include "ant_bsc_combined_page_0.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // __ANT_BSC_PAGES_H
+/** @} */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ant/ant_profiles/ant_bsc/simulator/ant_bsc_simulator.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ant/ant_profiles/ant_bsc/simulator/ant_bsc_simulator.c
new file mode 100644
index 0000000..c3499cc
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ant/ant_profiles/ant_bsc/simulator/ant_bsc_simulator.c
@@ -0,0 +1,280 @@
+/**
+ * Copyright (c) 2015 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#include "ant_bsc_simulator.h"
+#include "ant_bsc_utils.h"
+#include "app_util.h"
+
+#define ITERATION_ANT_CYCLES(DEVICE_TYPE) \
+ (BSC_PERIOD_TICKS(DEVICE_TYPE, BSC_MSG_PERIOD_4Hz)) ///< period of calculation [1/32678 s], defined in ANT device profile
+ // use the same DEVICE TYPE as in profile definition
+#define ITERATION_PERIOD(DEVICE_TYPE) \
+ ((ITERATION_ANT_CYCLES(DEVICE_TYPE)) * 1024 / ANT_CLOCK_FREQUENCY) ///< integer part of calculation's period [1/1024 s]
+#define ITERATION_FRACTION(DEVICE_TYPE) \
+ ((ITERATION_ANT_CYCLES(DEVICE_TYPE)) * 1024 % ANT_CLOCK_FREQUENCY) ///< fractional part of calculation's period [1/32678 s]
+
+#define SPEED_SIM_MIN_VAL 0u ///< speed simulation minimum value [m/s]
+#define SPEED_SIM_MAX_VAL 16u ///< speed simulation maximum value [m/s]
+#define SPEED_SIM_INCREMENT 1u ///< speed simulation value increment [m/s]
+#define CADENCE_SIM_MIN_VAL 70u ///< cadence simulation minimum value [rpm]
+#define CADENCE_SIM_MAX_VAL 120u ///< cadence simulation maximum value [rpm]
+#define CADENCE_SIM_INCREMENT 1u ///< cadence simulation value increment [rpm]
+#define WHEEL_CIRCUMFERENCE 1766u ///< bike wheel circumference [mm]
+#define MM_TO_METERS(MM_VAL) ((MM_VAL) / 1000u)
+#define TWO_SEC_TO_TICKS 2048 ///< number of [1/1024s] ticks in 2 sec period
+#define CUMULATIVE_TIME_UNIT 2 ///< cumulative time unit
+
+void ant_bsc_simulator_init(ant_bsc_simulator_t * p_simulator,
+ ant_bsc_simulator_cfg_t const * p_config,
+ bool auto_change)
+{
+ p_simulator->p_profile = p_config->p_profile;
+ p_simulator->_cb.auto_change = auto_change;
+ p_simulator->_cb.speed_sim_val = SPEED_SIM_MIN_VAL;
+ p_simulator->_cb.cadence_sim_val = CADENCE_SIM_MIN_VAL;
+ p_simulator->_cb.time_since_last_s_evt = 0;
+ p_simulator->_cb.fraction_since_last_s_evt = 0;
+ p_simulator->_cb.time_since_last_c_evt = 0;
+ p_simulator->_cb.fraction_since_last_c_evt = 0;
+ p_simulator->_cb.device_type = p_config->device_type;
+
+ p_simulator->_cb.sensorsim_s_cfg.min = SPEED_SIM_MIN_VAL;
+ p_simulator->_cb.sensorsim_s_cfg.max = SPEED_SIM_MAX_VAL;
+ p_simulator->_cb.sensorsim_s_cfg.incr = SPEED_SIM_INCREMENT;
+ p_simulator->_cb.sensorsim_s_cfg.start_at_max = false;
+ sensorsim_init(&(p_simulator->_cb.sensorsim_s_state),
+ &(p_simulator->_cb.sensorsim_s_cfg));
+ p_simulator->_cb.sensorsim_c_cfg.min = CADENCE_SIM_MIN_VAL;
+ p_simulator->_cb.sensorsim_c_cfg.max = CADENCE_SIM_MAX_VAL;
+ p_simulator->_cb.sensorsim_c_cfg.incr = CADENCE_SIM_INCREMENT;
+ p_simulator->_cb.sensorsim_c_cfg.start_at_max = false;
+ p_simulator->_cb.stop_cnt = 0;
+ sensorsim_init(&(p_simulator->_cb.sensorsim_c_state),
+ &(p_simulator->_cb.sensorsim_c_cfg));
+}
+
+
+void ant_bsc_simulator_one_iteration(ant_bsc_simulator_t * p_simulator)
+{
+
+ // Set constant battery voltage
+ p_simulator->p_profile->BSC_PROFILE_coarse_bat_volt = 2;
+ p_simulator->p_profile->BSC_PROFILE_fract_bat_volt = 200;
+ p_simulator->p_profile->BSC_PROFILE_bat_status = BSC_BAT_STATUS_GOOD;
+
+ // Calculate speed and cadence values
+ if (p_simulator->_cb.auto_change)
+ {
+ p_simulator->_cb.speed_sim_val = sensorsim_measure(&(p_simulator->_cb.sensorsim_s_state),
+ &(p_simulator->_cb.sensorsim_s_cfg));
+ p_simulator->_cb.cadence_sim_val = sensorsim_measure(&(p_simulator->_cb.sensorsim_c_state),
+ &(p_simulator->_cb.sensorsim_c_cfg));
+ }
+ else
+ {
+ p_simulator->_cb.speed_sim_val = p_simulator->_cb.sensorsim_s_state.current_val;
+ p_simulator->_cb.cadence_sim_val = p_simulator->_cb.sensorsim_c_state.current_val;
+ }
+
+ // Simulate bicycle stopped for around 10s and go for around 5s only in auto-simulation
+ if (p_simulator->_cb.auto_change)
+ {
+ if ((p_simulator->p_profile->_cb.p_sens_cb->main_page_number == ANT_BSC_PAGE_5) &&
+ (p_simulator->_cb.stop_cnt++ < 40))
+ {
+ p_simulator->_cb.speed_sim_val = 0;
+ p_simulator->_cb.cadence_sim_val = 0;
+ }
+ else
+ {
+ if (p_simulator->_cb.stop_cnt == 60)
+ {
+ p_simulator->_cb.stop_cnt = 0;
+ }
+ }
+ }
+ if (p_simulator->_cb.speed_sim_val == 0)
+ {
+ p_simulator->p_profile->BSC_PROFILE_stop_indicator = 1;
+ }
+ else
+ {
+ p_simulator->p_profile->BSC_PROFILE_stop_indicator = 0;
+ }
+
+ // @note: Take a local copy within scope in order to assist the compiler in variable register
+ // allocation.
+ const uint32_t computed_speed = p_simulator->_cb.speed_sim_val;
+ const uint32_t computed_cadence = p_simulator->_cb.cadence_sim_val;
+
+ // @note: This implementation assumes that the current instantaneous speed/cadence can vary and this
+ // function is called with static frequency.
+ // value and the speed/cadence pulse interval is derived from it. The computation is based on 60
+ // seconds in a minute and the used time base is 1/1024 seconds.
+ const uint32_t current_speed_pulse_interval =
+ MM_TO_METERS((WHEEL_CIRCUMFERENCE * 1024u) / computed_speed);
+ const uint32_t current_cadence_pulse_interval = (60u * 1024u) / computed_cadence;
+
+ //update time from last evt detected
+ p_simulator->_cb.time_since_last_s_evt += ITERATION_PERIOD(p_simulator->_cb.device_type);
+ p_simulator->_cb.time_since_last_c_evt += ITERATION_PERIOD(p_simulator->_cb.device_type);
+
+ // extended calculation by fraction make calculating accurate in long time perspective
+ p_simulator->_cb.fraction_since_last_s_evt += ITERATION_FRACTION(p_simulator->_cb.device_type);
+ p_simulator->_cb.fraction_since_last_c_evt += ITERATION_FRACTION(p_simulator->_cb.device_type);
+
+ uint32_t add_period = p_simulator->_cb.fraction_since_last_s_evt / ANT_CLOCK_FREQUENCY;
+ if (add_period > 0)
+ {
+ p_simulator->_cb.time_since_last_s_evt++;
+ p_simulator->_cb.fraction_since_last_s_evt %= ANT_CLOCK_FREQUENCY;
+ }
+
+ add_period = p_simulator->_cb.fraction_since_last_c_evt / ANT_CLOCK_FREQUENCY;
+ if (add_period > 0)
+ {
+ p_simulator->_cb.time_since_last_c_evt++;
+ p_simulator->_cb.fraction_since_last_c_evt %= ANT_CLOCK_FREQUENCY;
+ }
+
+ // Calculate cumulative time based on time since last event (from profile data) in [1/1024] ticks
+ int16_t diff = p_simulator->p_profile->BSC_PROFILE_event_time -
+ p_simulator->_cb.prev_time_since_evt;
+ p_simulator->_cb.prev_time_since_evt = p_simulator->p_profile->BSC_PROFILE_event_time;
+
+ if (diff >= 0) // Check for time count overflow
+ {
+ // No overflow
+ p_simulator->_cb.cumulative_time += diff / TWO_SEC_TO_TICKS;
+ p_simulator->_cb.cumulative_time_frac += diff % TWO_SEC_TO_TICKS;
+ }
+ else
+ {
+ p_simulator->_cb.cumulative_time += (UINT16_MAX + diff) / TWO_SEC_TO_TICKS;
+ p_simulator->_cb.cumulative_time_frac += (UINT16_MAX + diff) % TWO_SEC_TO_TICKS;
+ }
+ // Check fraction
+ if ((p_simulator->_cb.cumulative_time_frac / TWO_SEC_TO_TICKS) > 0)
+ {
+ p_simulator->_cb.cumulative_time += p_simulator->_cb.cumulative_time_frac / TWO_SEC_TO_TICKS;
+ p_simulator->_cb.cumulative_time_frac %= TWO_SEC_TO_TICKS;
+ }
+ // Update page data if necessary
+ if (p_simulator->_cb.cumulative_time != p_simulator->p_profile->BSC_PROFILE_operating_time)
+ {
+ p_simulator->p_profile->BSC_PROFILE_operating_time = p_simulator->_cb.cumulative_time;
+ }
+
+ //calc number of events as will fill
+ uint32_t new_s_events = p_simulator->_cb.time_since_last_s_evt /
+ current_speed_pulse_interval;
+ uint32_t add_speed_event_time = new_s_events * current_speed_pulse_interval;
+ if ((new_s_events > 0) && ((p_simulator->_cb.device_type == BSC_SPEED_DEVICE_TYPE) ||
+ (p_simulator->_cb.device_type == BSC_COMBINED_DEVICE_TYPE)))
+ {
+ p_simulator->p_profile->BSC_PROFILE_rev_count += new_s_events;
+ p_simulator->p_profile->BSC_PROFILE_speed_rev_count += new_s_events;
+
+ // Current speed event time is the previous event time plus the current speed
+ // pulse interval.
+ uint32_t current_speed_event_time = p_simulator->p_profile->BSC_PROFILE_event_time +
+ add_speed_event_time;
+ // Set current event time.
+ p_simulator->p_profile->BSC_PROFILE_event_time = current_speed_event_time; // <- B<4,5> <-
+
+ current_speed_event_time = p_simulator->p_profile->BSC_PROFILE_speed_event_time +
+ add_speed_event_time;
+ // Set current event time for combined device.
+ p_simulator->p_profile->BSC_PROFILE_speed_event_time = current_speed_event_time;
+
+ p_simulator->_cb.time_since_last_s_evt -= add_speed_event_time;
+ }
+
+ uint32_t new_c_events = p_simulator->_cb.time_since_last_c_evt /
+ current_cadence_pulse_interval;
+ uint32_t add_cadence_event_time = new_c_events * current_cadence_pulse_interval;
+ if ((new_c_events > 0) && ((p_simulator->_cb.device_type == BSC_CADENCE_DEVICE_TYPE) ||
+ (p_simulator->_cb.device_type == BSC_COMBINED_DEVICE_TYPE)))
+ {
+ p_simulator->p_profile->BSC_PROFILE_rev_count += new_c_events;
+ p_simulator->p_profile->BSC_PROFILE_cadence_rev_count += new_c_events;
+
+ // Current speed event time is the previous event time plus the current speed
+ // pulse interval.
+ uint32_t current_cadence_event_time = p_simulator->p_profile->BSC_PROFILE_event_time +
+ add_cadence_event_time;
+ // Set current event time.
+ p_simulator->p_profile->BSC_PROFILE_event_time = current_cadence_event_time; //<- B<4,5> <-
+
+ current_cadence_event_time = p_simulator->p_profile->BSC_PROFILE_cadence_event_time +
+ add_cadence_event_time;
+ // Set current event time for combined device.
+ p_simulator->p_profile->BSC_PROFILE_cadence_event_time = current_cadence_event_time;
+
+ p_simulator->_cb.time_since_last_c_evt -= add_cadence_event_time;
+ }
+}
+
+
+void ant_bsc_simulator_increment(ant_bsc_simulator_t * p_simulator)
+{
+ if (!p_simulator->_cb.auto_change)
+ {
+ // Speed
+ sensorsim_increment(&(p_simulator->_cb.sensorsim_s_state),
+ &(p_simulator->_cb.sensorsim_s_cfg));
+ // Cadence
+ sensorsim_increment(&(p_simulator->_cb.sensorsim_c_state),
+ &(p_simulator->_cb.sensorsim_c_cfg));
+ }
+}
+
+
+void ant_bsc_simulator_decrement(ant_bsc_simulator_t * p_simulator)
+{
+ if (!p_simulator->_cb.auto_change)
+ {
+ // Speed
+ sensorsim_decrement(&(p_simulator->_cb.sensorsim_s_state),
+ &(p_simulator->_cb.sensorsim_s_cfg));
+ // Cadence
+ sensorsim_decrement(&(p_simulator->_cb.sensorsim_c_state),
+ &(p_simulator->_cb.sensorsim_c_cfg));
+ }
+}
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ant/ant_profiles/ant_bsc/simulator/ant_bsc_simulator.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ant/ant_profiles/ant_bsc/simulator/ant_bsc_simulator.h
new file mode 100644
index 0000000..98e1fc4
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ant/ant_profiles/ant_bsc/simulator/ant_bsc_simulator.h
@@ -0,0 +1,120 @@
+/**
+ * Copyright (c) 2015 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#ifndef ANT_BSC_SIMULATOR_H__
+#define ANT_BSC_SIMULATOR_H__
+
+/** @file
+ *
+ * @defgroup ant_sdk_bsc_simulator ANT BSC simulator
+ * @{
+ * @ingroup ant_sdk_simulators
+ * @brief ANT BSC simulator module.
+ *
+ * @details This module simulates a pulse for the ANT Bicycle Speed and Cadence profile. The module
+ * calculates abstract values, which are handled by the BSC pages data model to ensure that
+ * they are compatible. It provides a handler for changing the cadence and speed values manually
+ * as well as functionality to change the values automatically.
+ *
+ */
+
+#include <stdint.h>
+#include <stdbool.h>
+#include "ant_bsc.h"
+#include "ant_bsc_utils.h"
+#include "sensorsim.h"
+#include "ant_bsc_simulator_local.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**@brief BSC simulator configuration structure. */
+typedef struct
+{
+ ant_bsc_profile_t * p_profile; ///< Related profile.
+ uint8_t device_type; ///< BSC device type (must be consistent with the type chosen for the profile). Supported types:
+ // @ref BSC_SPEED_DEVICE_TYPE, @ref BSC_CADENCE_DEVICE_TYPE, @ref BSC_COMBINED_DEVICE_TYPE.
+} ant_bsc_simulator_cfg_t;
+
+/**@brief BSC simulator structure. */
+typedef struct
+{
+ ant_bsc_profile_t * p_profile; ///< Related profile.
+ ant_bsc_simulator_cb_t _cb; ///< Internal control block.
+} ant_bsc_simulator_t;
+
+
+/**@brief Function for initializing the ANT BSC simulator instance.
+ *
+ * @param[in] p_simulator Pointer to the simulator instance.
+ * @param[in] p_config Pointer to the simulator configuration structure.
+ * @param[in] auto_change Enable or disable automatic changes of speed or cadence.
+ */
+void ant_bsc_simulator_init(ant_bsc_simulator_t * p_simulator,
+ ant_bsc_simulator_cfg_t const * p_config,
+ bool auto_change);
+
+/**@brief Function for simulating a device event.
+ *
+ * @details Based on this event, the transmitter data is simulated.
+ *
+ * This function should be called in the BSC Sensor event handler.
+ */
+void ant_bsc_simulator_one_iteration(ant_bsc_simulator_t * p_simulator);
+
+/**@brief Function for incrementing the cadence value.
+ *
+ * @param[in] p_simulator Pointer to the simulator instance.
+ */
+void ant_bsc_simulator_increment(ant_bsc_simulator_t * p_simulator);
+
+/**@brief Function for decrementing the cadence value.
+ *
+ * @param[in] p_simulator Pointer to the simulator instance.
+ */
+void ant_bsc_simulator_decrement(ant_bsc_simulator_t * p_simulator);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // ANT_BSC_SIMULATOR_H__
+/** @} */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ant/ant_profiles/ant_bsc/simulator/ant_bsc_simulator_local.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ant/ant_profiles/ant_bsc/simulator/ant_bsc_simulator_local.h
new file mode 100644
index 0000000..cb1aec6
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ant/ant_profiles/ant_bsc/simulator/ant_bsc_simulator_local.h
@@ -0,0 +1,79 @@
+/**
+ * Copyright (c) 2015 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#ifndef ANT_BSC_SIMULATOR_LOCAL_H__
+#define ANT_BSC_SIMULATOR_LOCAL_H__
+
+#include <stdint.h>
+#include <stdbool.h>
+#include "ant_bsc.h"
+#include "sensorsim.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+/**@brief BSC simulator control block structure. */
+typedef struct
+{
+ uint8_t device_type;
+ bool auto_change; ///< Cadence will change automatically (if auto_change is set) or manually.
+ uint16_t speed_sim_val; ///< Instantaneous speed value.
+ uint16_t cadence_sim_val; ///< Instantaneous cadence value.
+ uint32_t time_since_last_s_evt; ///< Time since last speed event occurred (integer part).
+ uint64_t fraction_since_last_s_evt; ///< Time since last speed event occurred (fractional part).
+ uint32_t time_since_last_c_evt; ///< Time since last cadence event occurred (integer part).
+ uint64_t fraction_since_last_c_evt; ///< Time since last cadence event occurred (fractional part).
+ sensorsim_state_t sensorsim_s_state; ///< State of the simulated speed sensor.
+ sensorsim_cfg_t sensorsim_s_cfg; ///< Configuration of the simulated speed sensor.
+ sensorsim_state_t sensorsim_c_state; ///< State of the simulated cadence sensor.
+ sensorsim_cfg_t sensorsim_c_cfg; ///< Configuration of the simulated cadence sensor.
+ uint16_t prev_time_since_evt; ///< Previous value of time since the last event.
+ uint32_t cumulative_time; ///< Cumulative time in 2 s ticks used for updating the cumulative time.
+ uint32_t cumulative_time_frac; ///< Cumulative time in 2 s ticks (fractional part), used for updating the cumulative time.
+ uint8_t stop_cnt; ///< Counter used for simulating bicycle stopped state.
+} ant_bsc_simulator_cb_t;
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // ANT_BSC_SIMULATOR_LOCAL_H__
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ant/ant_profiles/ant_bsc/utils/ant_bsc_utils.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ant/ant_profiles/ant_bsc/utils/ant_bsc_utils.h
new file mode 100644
index 0000000..7126ebf
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ant/ant_profiles/ant_bsc/utils/ant_bsc_utils.h
@@ -0,0 +1,128 @@
+/**
+ * Copyright (c) 2015 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#ifndef ANT_BSC_UTILS_H__
+#define ANT_BSC_UTILS_H__
+
+#include "nrf.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** @file
+ *
+ * @defgroup ant_sdk_profiles_bsc_utils Bicycle Speed and Cadence profile utilities
+ * @{
+ * @ingroup ant_bsc
+ * @brief This module implements utilities for the Bicycle Speed and Cadence profile.
+ *
+ */
+
+/**@brief Unit for BSC operating time.
+ *
+ * @details According to the ANT BSC specification, the operating time unit is 2 seconds.
+ */
+#define ANT_BSC_OPERATING_TIME_UNIT 2u
+
+/**@brief This macro should be used to get the seconds part of the operating time.
+ */
+#define ANT_BSC_OPERATING_SECONDS(OPERATING_TIME) (((OPERATING_TIME) * ANT_BSC_OPERATING_TIME_UNIT) % 60)
+
+/**@brief This macro should be used to get the minutes part of the operating time.
+ */
+#define ANT_BSC_OPERATING_MINUTES(OPERATING_TIME) ((((OPERATING_TIME) * ANT_BSC_OPERATING_TIME_UNIT) / 60) % 60)
+
+/**@brief This macro should be used to get the hours part of the operating time.
+ */
+#define ANT_BSC_OPERATING_HOURS(OPERATING_TIME) ((((OPERATING_TIME) * ANT_BSC_OPERATING_TIME_UNIT) / (60 * 60)) % 24)
+
+/**@brief This macro should be used to get the days part of the operating time.
+ */
+#define ANT_BSC_OPERATING_DAYS(OPERATING_TIME) ((((OPERATING_TIME) * ANT_BSC_OPERATING_TIME_UNIT) / (60 * 60)) / 24)
+
+/**@brief Number of Bicycle Speed or Cadence event time counts per second.
+ *
+ * @details According to the ANT BSC specification, the speed or cadence event time unit is 1/1024 of a second.
+ */
+#define ANT_BSC_EVENT_TIME_COUNTS_PER_SEC 1024u
+
+/**@brief BSC event time display required precision.
+ *
+ * @details This value is used to decode the number of milliseconds.
+ */
+#define ANT_BSC_EVENT_TIME_PRECISION 1000u
+
+/**@brief This macro should be used to get the seconds part of the BSC event time.
+ */
+#define ANT_BSC_EVENT_TIME_SEC(EVENT_TIME) ((EVENT_TIME) / ANT_BSC_EVENT_TIME_COUNTS_PER_SEC)
+
+/**@brief This macro should be used to get the milliseconds part of the BSC event time.
+ */
+#define ANT_BSC_EVENT_TIME_MSEC(EVENT_TIME) (((((EVENT_TIME) % ANT_BSC_EVENT_TIME_COUNTS_PER_SEC) * ANT_BSC_EVENT_TIME_PRECISION) \
+ + ANT_BSC_EVENT_TIME_COUNTS_PER_SEC / 2) \
+ / ANT_BSC_EVENT_TIME_COUNTS_PER_SEC)
+
+/**@brief Battery voltage display required precision.
+ *
+ * @details This value is used to decode the number of mV.
+ */
+#define ANT_BSC_BAT_VOLTAGE_PRECISION 1000u
+
+/**@brief Bike Speed and Cadence profile, unit divisor of the fractional part of the battery voltage.
+ *
+ * @details According to the ANT BSC specification, the battery voltage fraction unit is (1/256) V.
+ */
+#define ANT_BSC_BAT_VOLTAGE_FRACTION_PER_VOLT 256u
+
+/**@brief This macro should be used to get the mV part of the BSC battery voltage.
+ */
+#define ANT_BSC_BAT_VOLTAGE_FRACTION_MV(VOLT_FRACT) ((((VOLT_FRACT) * ANT_BSC_BAT_VOLTAGE_PRECISION) \
+ + ANT_BSC_BAT_VOLTAGE_FRACTION_PER_VOLT / 2) \
+ / ANT_BSC_BAT_VOLTAGE_FRACTION_PER_VOLT)
+
+/** @} */
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // ANT_BSC_UTILS_H__
+
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ant/ant_profiles/ant_common/ant_request_controller/ant_request_controller.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ant/ant_profiles/ant_common/ant_request_controller/ant_request_controller.c
new file mode 100644
index 0000000..c5cd45f
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ant/ant_profiles/ant_common/ant_request_controller/ant_request_controller.c
@@ -0,0 +1,224 @@
+/**
+ * Copyright (c) 2015 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#include "sdk_common.h"
+#if NRF_MODULE_ENABLED(ANT_REQUEST_CONTROLLER)
+#include "ant_request_controller.h"
+#include "ant_interface.h"
+#include "ant_parameters.h"
+#include "app_error.h"
+#include "nrf_assert.h"
+#include "nrf.h"
+
+/**@brief Common message data layout structure. */
+typedef struct
+{
+ uint8_t page_number; ///< Page number.
+ uint8_t page_payload[7]; ///< Page payload.
+}ant_common_message_layout_t;
+
+
+void ant_request_controller_init(ant_request_controller_t * p_controller)
+{
+ ASSERT(p_controller != NULL);
+
+ p_controller->state = ANT_REQUEST_CONTROLLER_IDLE;
+ p_controller->page_70 = DEFAULT_ANT_COMMON_PAGE70();
+}
+
+
+uint32_t ant_request_controller_request(ant_request_controller_t * p_controller,
+ uint8_t channel_number,
+ ant_common_page70_data_t * p_page_70)
+{
+ ASSERT(p_controller != NULL);
+ ASSERT(p_page_70 != NULL);
+
+ ant_common_message_layout_t message;
+ message.page_number = ANT_COMMON_PAGE_70;
+
+ ant_common_page_70_encode(message.page_payload, p_page_70);
+
+ p_controller->state = ANT_REQUEST_CONTROLLER_SENDED;
+
+ return sd_ant_acknowledge_message_tx(channel_number, sizeof (message), (uint8_t *)&message);
+}
+
+
+bool ant_request_controller_pending_get(ant_request_controller_t * p_controller,
+ uint8_t * p_page_number)
+{
+ ASSERT(p_controller != NULL);
+ ASSERT(p_page_number != NULL);
+
+ if ((p_controller->state == ANT_REQUEST_CONTROLLER_ACK_UNTIL_SUCCESS_REQUESTED)
+ || (p_controller->state == ANT_REQUEST_CONTROLLER_ACK_REQUESTED)
+ || (p_controller->state == ANT_REQUEST_CONTROLLER_BROADCAST_REQUESTED))
+ {
+ *p_page_number = p_controller->page_70.page_number;
+ return true;
+ }
+ return false;
+}
+
+
+bool ant_request_controller_ack_needed(ant_request_controller_t * p_controller)
+{
+ ASSERT(p_controller != NULL);
+ return ((p_controller->state == ANT_REQUEST_CONTROLLER_ACK_UNTIL_SUCCESS_REQUESTED)
+ || (p_controller->state == ANT_REQUEST_CONTROLLER_ACK_REQUESTED));
+}
+
+
+ant_request_controller_evt_t ant_request_controller_disp_evt_handler(
+ ant_request_controller_t * p_controller,
+ ant_evt_t * p_ant_evt)
+{
+ ASSERT(p_controller != NULL);
+ ASSERT(p_ant_evt != NULL);
+
+ if ( p_controller->state == ANT_REQUEST_CONTROLLER_SENDED)
+ {
+ switch (p_ant_evt->event)
+ {
+ case EVENT_TRANSFER_TX_FAILED:
+ p_controller->state = ANT_REQUEST_CONTROLLER_IDLE;
+ return ANT_REQUEST_CONTROLLER_FAILED;
+
+ case EVENT_TRANSFER_TX_COMPLETED:
+ p_controller->state = ANT_REQUEST_CONTROLLER_IDLE;
+ return ANT_REQUEST_CONTROLLER_SUCCESS;
+
+ default:
+ break;
+ }
+ }
+
+ return ANT_REQUEST_CONTROLLER_NONE;
+}
+
+
+/**@brief Function for confirmation of page sending.
+ *
+ * @param[in] p_controller Pointer to the controller instance.
+ */
+__STATIC_INLINE void page_sended(ant_request_controller_t * p_controller)
+{
+ if (!((p_controller->page_70.transmission_response.items.transmit_count)--))
+ {
+ p_controller->state = ANT_REQUEST_CONTROLLER_IDLE;
+ }
+}
+
+
+/**@brief Function for handling page request.
+ *
+ * @param[in] p_controller Pointer to the controller instance.
+ * @param[in] p_message_payload Pointer to the message payload.
+ */
+__STATIC_INLINE void page_requested(ant_request_controller_t * p_controller,
+ ant_common_message_layout_t * p_message_payload)
+{
+ ant_common_page_70_decode(p_message_payload->page_payload, &(p_controller->page_70));
+
+ if ((p_controller->page_70.command_type == ANT_PAGE70_COMMAND_PAGE_DATA_REQUEST)
+ && (p_controller->page_70.transmission_response.specyfic != ANT_PAGE70_RESPONSE_INVALID))
+ {
+ if (p_controller->page_70.transmission_response.items.ack_resposne)
+ {
+ if (p_controller->page_70.transmission_response.specyfic ==
+ ANT_PAGE70_RESPONSE_TRANSMIT_UNTIL_SUCCESS)
+ {
+ p_controller->state = ANT_REQUEST_CONTROLLER_ACK_UNTIL_SUCCESS_REQUESTED;
+ }
+ else
+ {
+ p_controller->state = ANT_REQUEST_CONTROLLER_ACK_REQUESTED;
+ }
+ }
+ else
+ {
+ p_controller->state = ANT_REQUEST_CONTROLLER_BROADCAST_REQUESTED;
+ }
+ }
+}
+
+
+void ant_request_controller_sens_evt_handler(ant_request_controller_t * p_controller,
+ ant_evt_t * p_ant_evt)
+{
+ ASSERT(p_controller != NULL);
+ ASSERT(p_ant_evt != NULL);
+
+ ant_common_message_layout_t * p_message_payload =
+ (ant_common_message_layout_t *)p_ant_evt->message.ANT_MESSAGE_aucPayload;
+
+ switch (p_ant_evt->event)
+ {
+ case EVENT_RX:
+
+ if (p_message_payload->page_number == ANT_COMMON_PAGE_70)
+ {
+ page_requested(p_controller, p_message_payload);
+ }
+ break;
+
+ case EVENT_TRANSFER_TX_COMPLETED:
+
+ if (p_controller->state == ANT_REQUEST_CONTROLLER_ACK_UNTIL_SUCCESS_REQUESTED)
+ {
+ p_controller->state = ANT_REQUEST_CONTROLLER_IDLE;
+ }
+ /* fall through */
+
+ case EVENT_TX:
+
+ if (p_controller->state == ANT_REQUEST_CONTROLLER_BROADCAST_REQUESTED
+ || p_controller->state == ANT_REQUEST_CONTROLLER_ACK_REQUESTED)
+ {
+ page_sended(p_controller);
+ }
+ break;
+
+ default:
+ break;
+ }
+}
+
+#endif // NRF_MODULE_ENABLED(ANT_REQUEST_CONTROLLER)
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ant/ant_profiles/ant_common/ant_request_controller/ant_request_controller.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ant/ant_profiles/ant_common/ant_request_controller/ant_request_controller.h
new file mode 100644
index 0000000..4c99b9c
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ant/ant_profiles/ant_common/ant_request_controller/ant_request_controller.h
@@ -0,0 +1,157 @@
+/**
+ * Copyright (c) 2015 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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
+ *
+ * @defgroup ant_request_controller ANT request controller
+ * @{
+ * @ingroup ant_sdk_utils
+ *
+ * @brief Module for handling page requests related to page 70.
+ */
+
+#ifndef ANT_REQUEST_CONTROLLER_H__
+#define ANT_REQUEST_CONTROLLER_H__
+#include <stdbool.h>
+#include "ant_common_page_70.h"
+#include "nrf_sdh_ant.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**@brief Request controller events types. */
+typedef enum
+{
+ ANT_REQUEST_CONTROLLER_NONE, ///< No event.
+ ANT_REQUEST_CONTROLLER_SUCCESS, ///< Page request successful.
+ ANT_REQUEST_CONTROLLER_FAILED, ///< Page request failed.
+} ant_request_controller_evt_t;
+
+/**@brief Request controller states. */
+typedef enum
+{
+ ANT_REQUEST_CONTROLLER_IDLE, ///< Module is in idle state.
+ ANT_REQUEST_CONTROLLER_SENDED, ///< Module waits for acknowledgment of its request.
+ ANT_REQUEST_CONTROLLER_BROADCAST_REQUESTED, ///< Module is requested to send page n times using broadcast.
+ ANT_REQUEST_CONTROLLER_ACK_REQUESTED, ///< Module is requested to send page n times using acknowledgment.
+ ANT_REQUEST_CONTROLLER_ACK_UNTIL_SUCCESS_REQUESTED, ///< Module is requested to send page until success using acknowledgment.
+} ant_request_controller_state_t;
+
+/**@brief ANT request controller structure. */
+typedef struct
+{
+ ant_request_controller_state_t state; ///< Actual module state.
+ ant_common_page70_data_t page_70; ///< Page 70.
+} ant_request_controller_t;
+
+/**@brief Function for initializing the ANT request controller instance.
+ *
+ * @param[in] p_controller Pointer to the controller instance.
+ */
+void ant_request_controller_init(ant_request_controller_t * p_controller);
+
+/**@brief Function for sending a request.
+ *
+ * @param[in] p_controller Pointer to the controller instance.
+ * @param[in] channel_number Channel number.
+ * @param[in] p_page_70 Pointer to the prepared page 70.
+ *
+ * @return Error code returned by @ref sd_ant_acknowledge_message_tx().
+ */
+uint32_t ant_request_controller_request(ant_request_controller_t * p_controller,
+ uint8_t channel_number,
+ ant_common_page70_data_t * p_page_70);
+
+/**@brief Function for getting pending page number.
+ *
+ * @details This function checks whether a page number was requested.
+ *
+ * @param[in] p_controller Pointer to the controller instance.
+ * @param[out] p_page_number Pending page number (valid if true was returned).
+ *
+ * @retval TRUE If there was a pending page.
+ * @retval FALSE If no page was pending.
+ */
+bool ant_request_controller_pending_get(ant_request_controller_t * p_controller,
+ uint8_t * p_page_number);
+
+/**@brief Function for checking whether the next page must be sent with acknowledgment.
+ *
+ * @param[in] p_controller Pointer to the controller instance.
+ *
+ * @retval TRUE If the next transmission needs acknowledgment.
+ * @retval FALSE If the next transmission does not need acknowledgment.
+ */
+bool ant_request_controller_ack_needed(ant_request_controller_t * p_controller);
+
+/**
+ * @brief Function for handling ANT events on display side.
+ *
+ * @details All events from the ANT stack that are related to the appropriate channel number
+ * should be propagated.
+ *
+ * @param[in] p_controller Pointer to the controller instance.
+ * @param[in] p_ant_evt Event received from the ANT stack.
+ */
+ant_request_controller_evt_t ant_request_controller_disp_evt_handler(
+ ant_request_controller_t * p_controller,
+ ant_evt_t * p_ant_evt);
+
+/**
+ * @brief Function for handling ANT events on sensor side.
+ *
+ * @details All events from the ANT stack that are related to the appropriate channel number
+ * should be propagated.
+ *
+ * @param[in] p_controller Pointer to the controller instance.
+ * @param[in] p_ant_evt Event received from the ANT stack.
+ * @retval TRUE If there was a pending page.
+ */
+void ant_request_controller_sens_evt_handler(ant_request_controller_t * p_controller,
+ ant_evt_t * p_ant_evt);
+
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // ANT_REQUEST_CONTROLLER_H__
+/** @} */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ant/ant_profiles/ant_common/pages/ant_common_page_70.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ant/ant_profiles/ant_common/pages/ant_common_page_70.c
new file mode 100644
index 0000000..0026fe5
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ant/ant_profiles/ant_common/pages/ant_common_page_70.c
@@ -0,0 +1,141 @@
+/**
+ * Copyright (c) 2015 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#include "sdk_common.h"
+#if NRF_MODULE_ENABLED(ANT_COMMON_PAGE_70)
+
+#include <string.h>
+#include "ant_common_page_70.h"
+
+#define NRF_LOG_MODULE_NAME ant_common_page_70
+#if ANT_COMMON_PAGE_70_LOG_ENABLED
+#define NRF_LOG_LEVEL ANT_COMMON_PAGE_70_LOG_LEVEL
+#define NRF_LOG_INFO_COLOR ANT_COMMON_PAGE_70_INFO_COLOR
+#else // ANT_COMMON_PAGE_70_LOG_ENABLED
+#define NRF_LOG_LEVEL 0
+#endif // ANT_COMMON_PAGE_70_LOG_ENABLED
+#include "nrf_log.h"
+NRF_LOG_MODULE_REGISTER();
+
+/**@brief ANT+ common page 70 data layout structure. */
+typedef struct
+{
+ uint8_t reserved[2];
+ uint8_t descriptor[2];
+ uint8_t req_trans_response;
+ uint8_t req_page_number;
+ uint8_t command_type;
+}ant_common_page70_data_layout_t;
+
+/**@brief Function for tracing page 70 data.
+ *
+ * @param[in] p_page_data Pointer to the page 70 data.
+ */
+static void page70_data_log(volatile ant_common_page70_data_t const * p_page_data)
+{
+ NRF_LOG_INFO("Page %d request", p_page_data->page_number);
+
+ switch (p_page_data->transmission_response.specyfic)
+ {
+ case ANT_PAGE70_RESPONSE_TRANSMIT_UNTIL_SUCCESS:
+ NRF_LOG_INFO("Try to send until ACK");
+ break;
+
+ case ANT_PAGE70_RESPONSE_INVALID:
+ NRF_LOG_INFO("Invalid requested transmission response");
+ break;
+
+ default:
+
+ if (p_page_data->transmission_response.items.ack_resposne)
+ {
+ NRF_LOG_INFO("Answer with acknowledged messages");
+ }
+ NRF_LOG_INFO("Requested number of transmissions: %d",
+ p_page_data->transmission_response.items.transmit_count);
+ }
+
+ switch (p_page_data->command_type)
+ {
+ case ANT_PAGE70_COMMAND_PAGE_DATA_REQUEST:
+ NRF_LOG_INFO("Request Data Page");
+ break;
+
+ case ANT_PAGE70_COMMAND_ANT_FS_SESSION_REQUEST:
+ NRF_LOG_INFO("Request ANT-FS Session");
+ break;
+
+ default:
+ NRF_LOG_INFO("Invalid request");
+ }
+ NRF_LOG_INFO("Descriptor %x\r\n\n", p_page_data->descriptor);
+}
+
+
+void ant_common_page_70_encode(uint8_t * p_page_buffer,
+ volatile ant_common_page70_data_t const * p_page_data)
+{
+ ant_common_page70_data_layout_t * p_outcoming_data =
+ (ant_common_page70_data_layout_t *)p_page_buffer;
+
+ memset(p_outcoming_data->reserved, UINT8_MAX, sizeof (p_outcoming_data->reserved));
+ UNUSED_PARAMETER(uint16_encode(p_page_data->descriptor, p_outcoming_data->descriptor));
+ p_outcoming_data->req_trans_response = p_page_data->transmission_response.byte;
+ p_outcoming_data->req_page_number = p_page_data->page_number;
+ p_outcoming_data->command_type = p_page_data->command_type;
+
+ page70_data_log(p_page_data);
+}
+
+
+void ant_common_page_70_decode(uint8_t const * p_page_buffer,
+ volatile ant_common_page70_data_t * p_page_data)
+{
+ ant_common_page70_data_layout_t const * p_incoming_data =
+ (ant_common_page70_data_layout_t *)p_page_buffer;
+
+ p_page_data->descriptor = uint16_decode(p_incoming_data->descriptor);
+ p_page_data->transmission_response.byte = p_incoming_data->req_trans_response;
+ p_page_data->page_number = p_incoming_data->req_page_number;
+ p_page_data->command_type = (ant_page70_command_t)p_incoming_data->command_type;
+
+ page70_data_log(p_page_data);
+}
+
+#endif // NRF_MODULE_ENABLED(ANT_COMMON_PAGE_70)
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ant/ant_profiles/ant_common/pages/ant_common_page_70.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ant/ant_profiles/ant_common/pages/ant_common_page_70.h
new file mode 100644
index 0000000..20e5351
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ant/ant_profiles/ant_common/pages/ant_common_page_70.h
@@ -0,0 +1,135 @@
+/**
+ * Copyright (c) 2015 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#ifndef ANT_COMMON_PAGE_70_H__
+#define ANT_COMMON_PAGE_70_H__
+
+/** @file
+ *
+ * @defgroup ant_common_page_70 ANT+ common page 70
+ * @{
+ * @ingroup ant_sdk_common_pages
+ */
+
+#include <stdint.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define ANT_COMMON_PAGE_70 (70) ///< @brief ID value of common page 70.
+#define ANT_PAGE70_INVALID_DESCRIPTOR UINT16_MAX ///< Invalid descriptor.
+
+/**@brief Command type.
+ */
+typedef enum
+{
+ ANT_PAGE70_COMMAND_PAGE_DATA_REQUEST = 0x01, ///< Page request.
+ ANT_PAGE70_COMMAND_ANT_FS_SESSION_REQUEST = 0x02, ///< ANT FS session request.
+} ant_page70_command_t;
+
+
+/**@brief Data structure for ANT+ common data page 70.
+ */
+typedef struct
+{
+ uint8_t page_number; ///< Requested page number.
+ uint16_t descriptor; ///< Descriptor.
+ ant_page70_command_t command_type; ///< Command type.
+ union
+ {
+ enum
+ {
+ ANT_PAGE70_RESPONSE_INVALID = 0x00, ///< Invalid response type.
+ ANT_PAGE70_RESPONSE_TRANSMIT_UNTIL_SUCCESS = 0x80, ///< Transmit until a successful acknowledge is received.
+ } specyfic;
+ struct
+ {
+ uint8_t transmit_count :7; ///< Number of re-transmissions.
+ uint8_t ack_resposne :1; ///< Acknowledge transmission is required.
+ } items;
+ uint8_t byte;
+ } transmission_response;
+} ant_common_page70_data_t;
+
+/**@brief Initialize page 70 with default values.
+ */
+#define DEFAULT_ANT_COMMON_PAGE70() \
+ (ant_common_page70_data_t) \
+ { \
+ .page_number = 0x00, \
+ .command_type = (ant_page70_command_t)0x00, \
+ .transmission_response.specyfic = ANT_PAGE70_RESPONSE_INVALID, \
+ .descriptor = ANT_PAGE70_INVALID_DESCRIPTOR, \
+ }
+
+/**@brief Initialize page 70 with the page request.
+ */
+#define ANT_COMMON_PAGE_DATA_REQUEST(PAGE_NUMBER) \
+ (ant_common_page70_data_t) \
+ { \
+ .page_number = (PAGE_NUMBER), \
+ .command_type = ANT_PAGE70_COMMAND_PAGE_DATA_REQUEST, \
+ .transmission_response.specyfic = ANT_PAGE70_RESPONSE_TRANSMIT_UNTIL_SUCCESS, \
+ .descriptor = ANT_PAGE70_INVALID_DESCRIPTOR, \
+ }
+
+/**@brief Function for encoding page 70.
+ *
+ * @param[in] p_page_data Pointer to the page data.
+ * @param[out] p_page_buffer Pointer to the data buffer.
+ */
+void ant_common_page_70_encode(uint8_t * p_page_buffer,
+ volatile ant_common_page70_data_t const * p_page_data);
+
+/**@brief Function for decoding page 70.
+ *
+ * @param[in] p_page_buffer Pointer to the data buffer.
+ * @param[out] p_page_data Pointer to the page data.
+ */
+void ant_common_page_70_decode(uint8_t const * p_page_buffer,
+ volatile ant_common_page70_data_t * p_page_data);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // ANT_COMMON_PAGE_70_H__
+/** @} */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ant/ant_profiles/ant_common/pages/ant_common_page_80.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ant/ant_profiles/ant_common/pages/ant_common_page_80.c
new file mode 100644
index 0000000..b60e859
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ant/ant_profiles/ant_common/pages/ant_common_page_80.c
@@ -0,0 +1,110 @@
+/**
+ * Copyright (c) 2015 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#include "sdk_common.h"
+#if NRF_MODULE_ENABLED(ANT_COMMON_PAGE_80)
+
+#include <string.h>
+#include "ant_common_page_80.h"
+
+#define NRF_LOG_MODULE_NAME ant_common_page_80
+#if ANT_COMMON_PAGE_80_LOG_ENABLED
+#define NRF_LOG_LEVEL ANT_COMMON_PAGE_80_LOG_LEVEL
+#define NRF_LOG_INFO_COLOR ANT_COMMON_PAGE_80_INFO_COLOR
+#else // ANT_COMMON_PAGE_80_LOG_ENABLED
+#define NRF_LOG_LEVEL 0
+#endif // ANT_COMMON_PAGE_80_LOG_ENABLED
+#include "nrf_log.h"
+NRF_LOG_MODULE_REGISTER();
+
+/**@brief ant+ common page 80 data layout structure. */
+typedef struct
+{
+ uint8_t reserved[2]; ///< unused, fill by 0xFF
+ uint8_t hw_revision;
+ uint8_t manufacturer_id[2];
+ uint8_t model_number[2];
+}ant_common_page80_data_layout_t;
+
+
+/**@brief Function for tracing page 80 data.
+ *
+ * @param[in] p_page_data Pointer to the page 80 data.
+ */
+static void page80_data_log(volatile ant_common_page80_data_t const * p_page_data)
+{
+ NRF_LOG_INFO("hw revision: %u", p_page_data->hw_revision);
+ NRF_LOG_INFO("manufacturer id: %u", p_page_data->manufacturer_id);
+ NRF_LOG_INFO("model number: %u\r\n\n", p_page_data->model_number);
+}
+
+
+void ant_common_page_80_encode(uint8_t * p_page_buffer,
+ volatile ant_common_page80_data_t const * p_page_data)
+{
+ ant_common_page80_data_layout_t * p_outcoming_data =
+ (ant_common_page80_data_layout_t *)p_page_buffer;
+
+ memset(p_page_buffer, UINT8_MAX, sizeof (p_outcoming_data->reserved));
+
+ p_outcoming_data->hw_revision = p_page_data->hw_revision;
+
+ UNUSED_PARAMETER(uint16_encode(p_page_data->manufacturer_id,
+ p_outcoming_data->manufacturer_id));
+ UNUSED_PARAMETER(uint16_encode(p_page_data->model_number, p_outcoming_data->model_number));
+
+ page80_data_log(p_page_data);
+}
+
+
+void ant_common_page_80_decode(uint8_t const * p_page_buffer,
+ volatile ant_common_page80_data_t * p_page_data)
+{
+ ant_common_page80_data_layout_t const * p_incoming_data =
+ (ant_common_page80_data_layout_t *)p_page_buffer;
+
+ p_page_data->hw_revision = p_incoming_data->hw_revision;
+
+ p_page_data->manufacturer_id = uint16_decode(p_incoming_data->manufacturer_id);
+ p_page_data->model_number = uint16_decode(p_incoming_data->model_number);
+
+ page80_data_log(p_page_data);
+}
+
+#endif // NRF_MODULE_ENABLED(ANT_COMMON_PAGE_80)
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ant/ant_profiles/ant_common/pages/ant_common_page_80.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ant/ant_profiles/ant_common/pages/ant_common_page_80.h
new file mode 100644
index 0000000..15a971c
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ant/ant_profiles/ant_common/pages/ant_common_page_80.h
@@ -0,0 +1,120 @@
+/**
+ * Copyright (c) 2015 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#ifndef ANT_COMMON_PAGE_80_H__
+#define ANT_COMMON_PAGE_80_H__
+
+/** @file
+ *
+ * @defgroup ant_sdk_common_pages ANT+ common pages
+ * @{
+ * @ingroup ant_sdk_profiles
+ * @brief This module implements functions for the ANT+ common pages.
+ * @details ANT+ common data pages define common data formats that can be used by any device on any ANT network. The ability to send and receive these common pages is defined by the transmission type of the ANT channel parameter.
+ *
+ * Note that all unused pages in this section are not defined and therefore cannot be used.
+ * @}
+ *
+ * @defgroup ant_common_page_80 ANT+ common page 80
+ * @{
+ * @ingroup ant_sdk_common_pages
+ */
+
+#include <stdint.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define ANT_COMMON_PAGE_80 (80) ///< @brief ID value of common page 80.
+
+/**@brief Data structure for ANT+ common data page 80.
+ *
+ * @note This structure implements only page 80 specific data.
+ */
+typedef struct
+{
+ uint8_t hw_revision; ///< Hardware revision.
+ uint16_t manufacturer_id; ///< Manufacturer ID.
+ uint16_t model_number; ///< Model number.
+} ant_common_page80_data_t;
+
+/**@brief Initialize page 80.
+ */
+#define DEFAULT_ANT_COMMON_page80() \
+ (ant_common_page80_data_t) \
+ { \
+ .hw_revision = 0x00, \
+ .manufacturer_id = UINT8_MAX, \
+ .model_number = 0x00, \
+ }
+
+/**@brief Initialize page 80.
+ */
+#define ANT_COMMON_page80(hw_rev, man_id, mod_num) \
+ (ant_common_page80_data_t) \
+ { \
+ .hw_revision = (hw_rev), \
+ .manufacturer_id = (man_id), \
+ .model_number = (mod_num), \
+ }
+
+/**@brief Function for encoding page 80.
+ *
+ * @param[in] p_page_data Pointer to the page data.
+ * @param[out] p_page_buffer Pointer to the data buffer.
+ */
+void ant_common_page_80_encode(uint8_t * p_page_buffer,
+ volatile ant_common_page80_data_t const * p_page_data);
+
+/**@brief Function for decoding page 80.
+ *
+ * @param[in] p_page_buffer Pointer to the data buffer.
+ * @param[out] p_page_data Pointer to the page data.
+ */
+void ant_common_page_80_decode(uint8_t const * p_page_buffer,
+ volatile ant_common_page80_data_t * p_page_data);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // ANT_COMMON_PAGE_80_H__
+/** @} */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ant/ant_profiles/ant_common/pages/ant_common_page_81.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ant/ant_profiles/ant_common/pages/ant_common_page_81.c
new file mode 100644
index 0000000..3e5582e
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ant/ant_profiles/ant_common/pages/ant_common_page_81.c
@@ -0,0 +1,117 @@
+/**
+ * Copyright (c) 2015 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#include "sdk_common.h"
+#if NRF_MODULE_ENABLED(ANT_COMMON_PAGE_81)
+
+#include "ant_common_page_81.h"
+
+#define NRF_LOG_MODULE_NAME ant_common_page_81
+#if ANT_COMMON_PAGE_81_LOG_ENABLED
+#define NRF_LOG_LEVEL ANT_COMMON_PAGE_81_LOG_LEVEL
+#define NRF_LOG_INFO_COLOR ANT_COMMON_PAGE_81_INFO_COLOR
+#else // ANT_COMMON_PAGE_81_LOG_ENABLED
+#define NRF_LOG_LEVEL 0
+#endif // ANT_COMMON_PAGE_81_LOG_ENABLED
+#include "nrf_log.h"
+NRF_LOG_MODULE_REGISTER();
+
+/**@brief ant+ common page 81 data layout structure. */
+typedef struct
+{
+ uint8_t reserved; ///< unused, fill by 0xFF
+ uint8_t sw_revision_minor;
+ uint8_t sw_revision_major;
+ uint8_t serial_number[4];
+}ant_common_page81_data_layout_t;
+
+
+/**@brief Function for tracing page 80 data.
+ *
+ * @param[in] p_page_data Pointer to the page 80 data.
+ */
+static void page81_data_log(volatile ant_common_page81_data_t const * p_page_data)
+{
+ if (p_page_data->sw_revision_minor != UINT8_MAX)
+ {
+ NRF_LOG_INFO("sw revision: %u.%u",
+ ((ant_common_page81_data_t const *) p_page_data)->sw_revision_major,
+ ((ant_common_page81_data_t const *) p_page_data)->sw_revision_minor);
+ }
+ else
+ {
+ NRF_LOG_INFO("sw revision: %u", p_page_data->sw_revision_major);
+ }
+
+ NRF_LOG_INFO("serial number: %u\r\n\n", (unsigned int) p_page_data->serial_number);
+}
+
+
+void ant_common_page_81_encode(uint8_t * p_page_buffer,
+ volatile ant_common_page81_data_t const * p_page_data)
+{
+ ant_common_page81_data_layout_t * p_outcoming_data =
+ (ant_common_page81_data_layout_t *)p_page_buffer;
+
+ p_outcoming_data->reserved = UINT8_MAX;
+
+ p_outcoming_data->sw_revision_minor = p_page_data->sw_revision_minor;
+ p_outcoming_data->sw_revision_major = p_page_data->sw_revision_major;
+
+ UNUSED_PARAMETER(uint32_encode(p_page_data->serial_number, p_outcoming_data->serial_number));
+
+ page81_data_log(p_page_data);
+}
+
+
+void ant_common_page_81_decode(uint8_t const * p_page_buffer,
+ volatile ant_common_page81_data_t * p_page_data)
+{
+ ant_common_page81_data_layout_t const * p_incoming_data =
+ (ant_common_page81_data_layout_t *)p_page_buffer;
+
+ p_page_data->sw_revision_minor = p_incoming_data->sw_revision_minor;
+ p_page_data->sw_revision_major = p_incoming_data->sw_revision_major;
+
+ p_page_data->serial_number = uint32_decode(p_incoming_data->serial_number);
+
+ page81_data_log(p_page_data);
+}
+
+#endif // NRF_MODULE_ENABLED(ANT_COMMON_PAGE_81)
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ant/ant_profiles/ant_common/pages/ant_common_page_81.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ant/ant_profiles/ant_common/pages/ant_common_page_81.h
new file mode 100644
index 0000000..4299850
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ant/ant_profiles/ant_common/pages/ant_common_page_81.h
@@ -0,0 +1,111 @@
+/**
+ * Copyright (c) 2015 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#ifndef ANT_COMMON_PAGE_81_H__
+#define ANT_COMMON_PAGE_81_H__
+
+/** @file
+ *
+ * @defgroup ant_common_page_81 ANT+ common page 81
+ * @{
+ * @ingroup ant_sdk_common_pages
+ */
+
+#include <stdint.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define ANT_COMMON_PAGE_81 (81) ///< @brief ID value of common page 81.
+
+/**@brief Data structure for ANT+ common data page 81.
+ *
+ * @note This structure implements only page 81 specific data.
+ */
+typedef struct
+{
+ uint8_t sw_revision_minor; ///< Supplemental, fill by 0xFF if unused.
+ uint8_t sw_revision_major; ///< Main software version.
+ uint32_t serial_number; ///< Lowest 32 b of serial number, fill by 0xFFFFFFFFF if unused.
+} ant_common_page81_data_t;
+
+/**@brief Initialize page 81.
+ */
+#define DEFAULT_ANT_COMMON_page81() \
+ (ant_common_page81_data_t) \
+ { \
+ .sw_revision_minor = UINT8_MAX, \
+ .sw_revision_major = UINT8_MAX, \
+ .serial_number = UINT32_MAX, \
+ }
+
+/**@brief Initialize page 81.
+ */
+#define ANT_COMMON_page81(sw_major_rev, sw_minor_rev, seril_no) \
+ (ant_common_page81_data_t) \
+ { \
+ .sw_revision_minor = (sw_minor_rev), \
+ .sw_revision_major = (sw_major_rev), \
+ .serial_number = (seril_no), \
+ }
+
+/**@brief Function for encoding page 81.
+ *
+ * @param[in] p_page_data Pointer to the page data.
+ * @param[out] p_page_buffer Pointer to the data buffer.
+ */
+void ant_common_page_81_encode(uint8_t * p_page_buffer,
+ volatile ant_common_page81_data_t const * p_page_data);
+
+/**@brief Function for decoding page 81.
+ *
+ * @param[in] p_page_buffer Pointer to the data buffer.
+ * @param[out] p_page_data Pointer to the page data.
+ */
+void ant_common_page_81_decode(uint8_t const * p_page_buffer,
+ volatile ant_common_page81_data_t * p_page_data);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // ANT_COMMON_PAGE_81_H__
+/** @} */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ant/ant_profiles/ant_hrm/ant_hrm.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ant/ant_profiles/ant_hrm/ant_hrm.c
new file mode 100644
index 0000000..6c868d8
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ant/ant_profiles/ant_hrm/ant_hrm.c
@@ -0,0 +1,346 @@
+/**
+ * Copyright (c) 2015 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#include "sdk_config.h"
+#if ANT_HRM_ENABLED
+
+#include "nrf_assert.h"
+#include "app_error.h"
+#include "ant_interface.h"
+#include "app_util.h"
+#include "ant_hrm.h"
+#include "ant_hrm_utils.h"
+#include "app_error.h"
+
+#define NRF_LOG_MODULE_NAME ant_hrm
+#if ANT_HRM_LOG_ENABLED
+#define NRF_LOG_LEVEL ANT_HRM_LOG_LEVEL
+#define NRF_LOG_INFO_COLOR ANT_HRM_INFO_COLOR
+#else // ANT_HRM_LOG_ENABLED
+#define NRF_LOG_LEVEL 0
+#endif // ANT_HRM_LOG_ENABLED
+#include "nrf_log.h"
+NRF_LOG_MODULE_REGISTER();
+
+#define BACKGROUND_DATA_INTERVAL 64 /**< The number of main data pages sent between background data page.
+ Background data page is sent every 65th message. */
+#define TX_TOGGLE_DIVISOR 4 /**< The number of messages between changing state of toggle bit. */
+
+/**@brief HRM message data layout structure. */
+typedef struct
+{
+ ant_hrm_page_t page_number : 7;
+ uint8_t toggle_bit : 1;
+ uint8_t page_payload[7];
+} ant_hrm_message_layout_t;
+
+/**@brief Function for initializing the ANT HRM profile instance.
+ *
+ * @param[in] p_profile Pointer to the profile instance.
+ * @param[in] p_channel_config Pointer to the ANT channel configuration structure.
+ *
+ * @retval NRF_SUCCESS If initialization was successful. Otherwise, an error code is returned.
+ */
+static ret_code_t ant_hrm_init(ant_hrm_profile_t * p_profile,
+ ant_channel_config_t const * p_channel_config)
+{
+ p_profile->channel_number = p_channel_config->channel_number;
+
+ p_profile->page_0 = DEFAULT_ANT_HRM_PAGE0();
+ p_profile->page_1 = DEFAULT_ANT_HRM_PAGE1();
+ p_profile->page_2 = DEFAULT_ANT_HRM_PAGE2();
+ p_profile->page_3 = DEFAULT_ANT_HRM_PAGE3();
+ p_profile->page_4 = DEFAULT_ANT_HRM_PAGE4();
+
+ NRF_LOG_INFO("ANT HRM channel %u init", p_profile->channel_number);
+ return ant_channel_init(p_channel_config);
+}
+
+
+ret_code_t ant_hrm_disp_init(ant_hrm_profile_t * p_profile,
+ ant_channel_config_t const * p_channel_config,
+ ant_hrm_evt_handler_t evt_handler)
+{
+ ASSERT(p_profile != NULL);
+ ASSERT(p_channel_config != NULL);
+ ASSERT(evt_handler != NULL);
+
+ p_profile->evt_handler = evt_handler;
+
+ return ant_hrm_init(p_profile, p_channel_config);
+}
+
+
+ret_code_t ant_hrm_sens_init(ant_hrm_profile_t * p_profile,
+ ant_channel_config_t const * p_channel_config,
+ ant_hrm_sens_config_t const * p_sens_config)
+{
+ ASSERT(p_profile != NULL);
+ ASSERT(p_channel_config != NULL);
+ ASSERT(p_sens_config != NULL);
+ ASSERT(p_sens_config->p_cb != NULL);
+ ASSERT(p_sens_config->evt_handler != NULL);
+
+ ASSERT((p_sens_config->main_page_number == ANT_HRM_PAGE_0)
+ || (p_sens_config->main_page_number == ANT_HRM_PAGE_4));
+
+ p_profile->evt_handler = p_sens_config->evt_handler;
+ p_profile->_cb.p_sens_cb = p_sens_config->p_cb;
+
+ ant_hrm_sens_cb_t * p_hrm_cb = p_profile->_cb.p_sens_cb;
+ p_hrm_cb->page_1_present = p_sens_config->page_1_present;
+ p_hrm_cb->main_page_number = p_sens_config->main_page_number;
+ p_hrm_cb->ext_page_number = p_hrm_cb->page_1_present ? ANT_HRM_PAGE_1 : ANT_HRM_PAGE_2;
+ p_hrm_cb->message_counter = 0;
+ p_hrm_cb->toggle_bit = true;
+
+ return ant_hrm_init(p_profile, p_channel_config);
+}
+
+
+/**@brief Function for getting next page number to send.
+ *
+ * @param[in] p_profile Pointer to the profile instance.
+ *
+ * @return Next page number.
+ */
+static ant_hrm_page_t next_page_number_get(ant_hrm_profile_t * p_profile)
+{
+ ant_hrm_sens_cb_t * p_hrm_cb = p_profile->_cb.p_sens_cb;
+ ant_hrm_page_t page_number;
+
+ if (p_hrm_cb->message_counter == (BACKGROUND_DATA_INTERVAL))
+ {
+ page_number = p_hrm_cb->ext_page_number;
+
+ p_hrm_cb->message_counter = 0;
+
+ p_hrm_cb->ext_page_number++;
+
+ if (p_hrm_cb->ext_page_number > ANT_HRM_PAGE_3)
+ {
+ p_hrm_cb->ext_page_number = p_hrm_cb->page_1_present ? ANT_HRM_PAGE_1 : ANT_HRM_PAGE_2;
+ }
+ }
+ else
+ {
+ page_number = p_hrm_cb->main_page_number;
+ }
+
+ if (p_hrm_cb->message_counter % TX_TOGGLE_DIVISOR == 0)
+ {
+ p_hrm_cb->toggle_bit ^= 1;
+ }
+
+ p_hrm_cb->message_counter++;
+
+ return page_number;
+}
+
+
+/**@brief Function for encoding HRM message.
+ *
+ * @note Assume to be call each time when Tx window will occur.
+ */
+static void sens_message_encode(ant_hrm_profile_t * p_profile, uint8_t * p_message_payload)
+{
+ ant_hrm_message_layout_t * p_hrm_message_payload =
+ (ant_hrm_message_layout_t *)p_message_payload;
+ ant_hrm_sens_cb_t * p_hrm_cb = p_profile->_cb.p_sens_cb;
+
+ p_hrm_message_payload->page_number = next_page_number_get(p_profile);
+ p_hrm_message_payload->toggle_bit = p_hrm_cb->toggle_bit;
+
+ NRF_LOG_INFO("HRM TX Page number: %u", p_hrm_message_payload->page_number);
+
+ ant_hrm_page_0_encode(p_hrm_message_payload->page_payload, &(p_profile->page_0)); // Page 0 is present in each message
+
+ switch (p_hrm_message_payload->page_number)
+ {
+ case ANT_HRM_PAGE_0:
+ // No implementation needed
+ break;
+
+ case ANT_HRM_PAGE_1:
+ ant_hrm_page_1_encode(p_hrm_message_payload->page_payload, &(p_profile->page_1));
+ break;
+
+ case ANT_HRM_PAGE_2:
+ ant_hrm_page_2_encode(p_hrm_message_payload->page_payload, &(p_profile->page_2));
+ break;
+
+ case ANT_HRM_PAGE_3:
+ ant_hrm_page_3_encode(p_hrm_message_payload->page_payload, &(p_profile->page_3));
+ break;
+
+ case ANT_HRM_PAGE_4:
+ ant_hrm_page_4_encode(p_hrm_message_payload->page_payload, &(p_profile->page_4));
+ break;
+
+ default:
+ return;
+ }
+
+ p_profile->evt_handler(p_profile, (ant_hrm_evt_t)p_hrm_message_payload->page_number);
+}
+
+
+/**@brief Function for setting payload for ANT message and sending it.
+ *
+ * @param[in] p_profile Pointer to the profile instance.
+ */
+static void ant_message_send(ant_hrm_profile_t * p_profile)
+{
+ uint32_t err_code;
+ uint8_t p_message_payload[ANT_STANDARD_DATA_PAYLOAD_SIZE];
+
+ sens_message_encode(p_profile, p_message_payload);
+ err_code =
+ sd_ant_broadcast_message_tx(p_profile->channel_number,
+ sizeof (p_message_payload),
+ p_message_payload);
+ APP_ERROR_CHECK(err_code);
+}
+
+
+void ant_hrm_sens_evt_handler(ant_evt_t * p_ant_evt, void * p_context)
+{
+ ant_hrm_profile_t * p_profile = (ant_hrm_profile_t *)p_context;
+ if (p_ant_evt->channel == p_profile->channel_number)
+ {
+ switch (p_ant_evt->event)
+ {
+ case EVENT_TX:
+ ant_message_send(p_profile);
+ break;
+
+ default:
+ break;
+ }
+ }
+}
+
+
+ret_code_t ant_hrm_disp_open(ant_hrm_profile_t * p_profile)
+{
+ ASSERT(p_profile != NULL);
+
+ NRF_LOG_INFO("ANT HRM channel %u open", p_profile->channel_number);
+ return sd_ant_channel_open(p_profile->channel_number);
+}
+
+
+ret_code_t ant_hrm_sens_open(ant_hrm_profile_t * p_profile)
+{
+ ASSERT(p_profile != NULL);
+
+ // Fill tx buffer for the first frame
+ ant_message_send(p_profile);
+
+ NRF_LOG_INFO("ANT HRM channel %u open", p_profile->channel_number);
+ return sd_ant_channel_open(p_profile->channel_number);
+}
+
+
+/**@brief Function for decoding HRM message.
+ *
+ * @note Assume to be call each time when Rx window will occur.
+ */
+static void disp_message_decode(ant_hrm_profile_t * p_profile, uint8_t * p_message_payload)
+{
+ const ant_hrm_message_layout_t * p_hrm_message_payload =
+ (ant_hrm_message_layout_t *)p_message_payload;
+
+ NRF_LOG_INFO("HRM RX Page Number: %u", p_hrm_message_payload->page_number);
+
+ ant_hrm_page_0_decode(p_hrm_message_payload->page_payload, &(p_profile->page_0)); // Page 0 is present in each message
+
+ switch (p_hrm_message_payload->page_number)
+ {
+ case ANT_HRM_PAGE_0:
+ // No implementation needed
+ break;
+
+ case ANT_HRM_PAGE_1:
+ ant_hrm_page_1_decode(p_hrm_message_payload->page_payload, &(p_profile->page_1));
+ break;
+
+ case ANT_HRM_PAGE_2:
+ ant_hrm_page_2_decode(p_hrm_message_payload->page_payload, &(p_profile->page_2));
+ break;
+
+ case ANT_HRM_PAGE_3:
+ ant_hrm_page_3_decode(p_hrm_message_payload->page_payload, &(p_profile->page_3));
+ break;
+
+ case ANT_HRM_PAGE_4:
+ ant_hrm_page_4_decode(p_hrm_message_payload->page_payload, &(p_profile->page_4));
+ break;
+
+ default:
+ return;
+ }
+
+ p_profile->evt_handler(p_profile, (ant_hrm_evt_t)p_hrm_message_payload->page_number);
+}
+
+
+void ant_hrm_disp_evt_handler(ant_evt_t * p_ant_evt, void * p_context)
+{
+ ant_hrm_profile_t * p_profile = ( ant_hrm_profile_t *)p_context;
+ if (p_ant_evt->channel == p_profile->channel_number)
+ {
+ switch (p_ant_evt->event)
+ {
+ case EVENT_RX:
+ if (p_ant_evt->message.ANT_MESSAGE_ucMesgID == MESG_BROADCAST_DATA_ID
+ || p_ant_evt->message.ANT_MESSAGE_ucMesgID == MESG_ACKNOWLEDGED_DATA_ID
+ || p_ant_evt->message.ANT_MESSAGE_ucMesgID == MESG_BURST_DATA_ID)
+ {
+ disp_message_decode(p_profile, p_ant_evt->message.ANT_MESSAGE_aucPayload);
+ }
+ break;
+
+ default:
+ break;
+ }
+ }
+}
+
+#endif // ANT_HRM_ENABLED
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ant/ant_profiles/ant_hrm/ant_hrm.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ant/ant_profiles/ant_hrm/ant_hrm.h
new file mode 100644
index 0000000..fd6372c
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ant/ant_profiles/ant_hrm/ant_hrm.h
@@ -0,0 +1,292 @@
+/**
+ * Copyright (c) 2015 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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
+ *
+ * @defgroup ant_hrm Heart Rate Monitor profile
+ * @{
+ * @ingroup ant_sdk_profiles
+ * @brief This module implements the Heart Rate Monitor profile.
+ *
+ */
+
+#ifndef ANT_HRM_H__
+#define ANT_HRM_H__
+
+#include <stdint.h>
+#include <stdbool.h>
+#include "app_util.h"
+#include "ant_parameters.h"
+#include "nrf_sdh_ant.h"
+#include "ant_channel_config.h"
+#include "ant_hrm_pages.h"
+#include "sdk_errors.h"
+
+#define HRM_DEVICE_TYPE 0x78u ///< Device type reserved for ANT+ heart rate monitor.
+#define HRM_ANTPLUS_RF_FREQ 0x39u ///< Frequency, decimal 57 (2457 MHz).
+
+#define HRM_MSG_PERIOD_4Hz 0x1F86u ///< Message period, decimal 8070 (4.06 Hz).
+#define HRM_MSG_PERIOD_2Hz 0x3F0Cu ///< Message period, decimal 16140 (2.03 Hz).
+#define HRM_MSG_PERIOD_1Hz 0x7E18u ///< Message period, decimal 32280 (1.02 Hz).
+
+#define HRM_EXT_ASSIGN 0x00 ///< ANT ext assign.
+#define HRM_DISP_CHANNEL_TYPE CHANNEL_TYPE_SLAVE ///< Display HRM channel type.
+#define HRM_SENS_CHANNEL_TYPE CHANNEL_TYPE_MASTER ///< Sensor HRM channel type.
+
+/**@brief Initialize an ANT channel configuration structure for the HRM profile (Display).
+ *
+ * @param[in] NAME Name of related instance.
+ * @param[in] CHANNEL_NUMBER Number of the channel assigned to the profile instance.
+ * @param[in] TRANSMISSION_TYPE Type of transmission assigned to the profile instance.
+ * @param[in] DEVICE_NUMBER Number of the device assigned to the profile instance.
+ * @param[in] NETWORK_NUMBER Number of the network assigned to the profile instance.
+ * @param[in] HRM_MSG_PERIOD Channel period in 32 kHz counts. The HRM profile supports only the following periods:
+ * @ref HRM_MSG_PERIOD_4Hz, @ref HRM_MSG_PERIOD_2Hz, @ref HRM_MSG_PERIOD_1Hz.
+ */
+#define HRM_DISP_CHANNEL_CONFIG_DEF(NAME, \
+ CHANNEL_NUMBER, \
+ TRANSMISSION_TYPE, \
+ DEVICE_NUMBER, \
+ NETWORK_NUMBER, \
+ HRM_MSG_PERIOD) \
+static const ant_channel_config_t CONCAT_2(NAME,_channel_hrm_disp_config) = \
+ { \
+ .channel_number = (CHANNEL_NUMBER), \
+ .channel_type = HRM_DISP_CHANNEL_TYPE, \
+ .ext_assign = HRM_EXT_ASSIGN, \
+ .rf_freq = HRM_ANTPLUS_RF_FREQ, \
+ .transmission_type = (TRANSMISSION_TYPE), \
+ .device_type = HRM_DEVICE_TYPE, \
+ .device_number = (DEVICE_NUMBER), \
+ .channel_period = (HRM_MSG_PERIOD), \
+ .network_number = (NETWORK_NUMBER), \
+ }
+#define HRM_DISP_CHANNEL_CONFIG(NAME) &CONCAT_2(NAME,_channel_hrm_disp_config)
+
+
+/**@brief Initialize an ANT channel configuration structure for the HRM profile (Sensor).
+ *
+ * @param[in] NAME Name of related instance.
+ * @param[in] CHANNEL_NUMBER Number of the channel assigned to the profile instance.
+ * @param[in] TRANSMISSION_TYPE Type of transmission assigned to the profile instance.
+ * @param[in] DEVICE_NUMBER Number of the device assigned to the profile instance.
+ * @param[in] NETWORK_NUMBER Number of the network assigned to the profile instance.
+ */
+#define HRM_SENS_CHANNEL_CONFIG_DEF(NAME, \
+ CHANNEL_NUMBER, \
+ TRANSMISSION_TYPE, \
+ DEVICE_NUMBER, \
+ NETWORK_NUMBER) \
+static const ant_channel_config_t CONCAT_2(NAME,_channel_hrm_sens_config) = \
+ { \
+ .channel_number = (CHANNEL_NUMBER), \
+ .channel_type = HRM_SENS_CHANNEL_TYPE, \
+ .ext_assign = HRM_EXT_ASSIGN, \
+ .rf_freq = HRM_ANTPLUS_RF_FREQ, \
+ .transmission_type = (TRANSMISSION_TYPE), \
+ .device_type = HRM_DEVICE_TYPE, \
+ .device_number = (DEVICE_NUMBER), \
+ .channel_period = HRM_MSG_PERIOD_4Hz, \
+ .network_number = (NETWORK_NUMBER), \
+ }
+#define HRM_SENS_CHANNEL_CONFIG(NAME) &CONCAT_2(NAME,_channel_hrm_sens_config)
+
+/**@brief Initialize an ANT profile configuration structure for the HRM profile (Sensor).
+ *
+ * @param[in] NAME Name of related instance.
+ * @param[in] PAGE_1_PRESENT Determines whether page 1 is included.
+ * @param[in] MAIN_PAGE_NUMBER Determines the main data page (@ref ANT_HRM_PAGE_0 or @ref ANT_HRM_PAGE_4).
+ * @param[in] EVT_HANDLER Event handler to be called for handling events in the HRM profile.
+ */
+#define HRM_SENS_PROFILE_CONFIG_DEF(NAME, \
+ PAGE_1_PRESENT, \
+ MAIN_PAGE_NUMBER, \
+ EVT_HANDLER) \
+static ant_hrm_sens_cb_t CONCAT_2(NAME,_hrm_sens_cb); \
+static const ant_hrm_sens_config_t CONCAT_2(NAME,_profile_hrm_sens_config) = \
+ { \
+ .page_1_present = (PAGE_1_PRESENT), \
+ .main_page_number = (MAIN_PAGE_NUMBER), \
+ .p_cb = &CONCAT_2(NAME,_hrm_sens_cb), \
+ .evt_handler = (EVT_HANDLER), \
+ }
+#define HRM_SENS_PROFILE_CONFIG(NAME) &CONCAT_2(NAME,_profile_hrm_sens_config)
+
+
+/**@brief HRM page number type. */
+typedef enum
+{
+ ANT_HRM_PAGE_0, ///< Main data page number 0.
+ ANT_HRM_PAGE_1, ///< Background data page number 1. This page is optional.
+ ANT_HRM_PAGE_2, ///< Background data page number 2.
+ ANT_HRM_PAGE_3, ///< Background data page number 3.
+ ANT_HRM_PAGE_4 ///< Main data page number 4.
+} ant_hrm_page_t;
+
+/**@brief HRM profile event type. */
+typedef enum
+{
+ ANT_HRM_PAGE_0_UPDATED = ANT_HRM_PAGE_0, ///< Data page 0 has been updated (Display) or sent (Sensor).
+ ANT_HRM_PAGE_1_UPDATED = ANT_HRM_PAGE_1, ///< Data page 0 and page 1 have been updated (Display) or sent (Sensor).
+ ANT_HRM_PAGE_2_UPDATED = ANT_HRM_PAGE_2, ///< Data page 0 and page 2 have been updated (Display) or sent (Sensor).
+ ANT_HRM_PAGE_3_UPDATED = ANT_HRM_PAGE_3, ///< Data page 0 and page 3 have been updated (Display) or sent (Sensor).
+ ANT_HRM_PAGE_4_UPDATED = ANT_HRM_PAGE_4, ///< Data page 0 and page 4 have been updated (Display) or sent (Sensor).
+} ant_hrm_evt_t;
+
+// Forward declaration of the ant_hrm_profile_t type.
+typedef struct ant_hrm_profile_s ant_hrm_profile_t;
+
+/**@brief HRM event handler type. */
+typedef void (* ant_hrm_evt_handler_t) (ant_hrm_profile_t *, ant_hrm_evt_t);
+
+#include "ant_hrm_local.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**@brief HRM sensor configuration structure. */
+typedef struct
+{
+ bool page_1_present; ///< Determines whether page 1 is included.
+ ant_hrm_page_t main_page_number; ///< Determines the main data page (@ref ANT_HRM_PAGE_0 or @ref ANT_HRM_PAGE_4).
+ ant_hrm_sens_cb_t * p_cb; ///< Pointer to the data buffer for internal use.
+ ant_hrm_evt_handler_t evt_handler; ///< Event handler to be called for handling events in the HRM profile.
+} ant_hrm_sens_config_t;
+
+/**@brief HRM profile structure. */
+struct ant_hrm_profile_s
+{
+ uint8_t channel_number; ///< Channel number assigned to the profile.
+ union {
+ void * p_none;
+ ant_hrm_sens_cb_t * p_sens_cb;
+ } _cb; ///< Pointer to internal control block.
+ ant_hrm_evt_handler_t evt_handler; ///< Event handler to be called for handling events in the HRM profile.
+ ant_hrm_page0_data_t page_0; ///< Page 0.
+ ant_hrm_page1_data_t page_1; ///< Page 1.
+ ant_hrm_page2_data_t page_2; ///< Page 2.
+ ant_hrm_page3_data_t page_3; ///< Page 3.
+ ant_hrm_page4_data_t page_4; ///< Page 4.
+};
+
+/** @name Defines for accessing ant_hrm_profile_t member variables
+ @{ */
+#define HRM_PROFILE_beat_count page_0.beat_count
+#define HRM_PROFILE_computed_heart_rate page_0.computed_heart_rate
+#define HRM_PROFILE_beat_time page_0.beat_time
+#define HRM_PROFILE_operating_time page_1.operating_time
+#define HRM_PROFILE_manuf_id page_2.manuf_id
+#define HRM_PROFILE_serial_num page_2.serial_num
+#define HRM_PROFILE_hw_version page_3.hw_version
+#define HRM_PROFILE_sw_version page_3.sw_version
+#define HRM_PROFILE_model_num page_3.model_num
+#define HRM_PROFILE_manuf_spec page_4.manuf_spec
+#define HRM_PROFILE_prev_beat page_4.prev_beat
+/** @} */
+
+/**@brief Function for initializing the ANT HRM Display profile instance.
+ *
+ * @param[in] p_profile Pointer to the profile instance.
+ * @param[in] p_channel_config Pointer to the ANT channel configuration structure.
+ * @param[in] evt_handler Event handler to be called for handling events in the HRM profile.
+ *
+ * @retval NRF_SUCCESS If initialization was successful. Otherwise, an error code is returned.
+ */
+ret_code_t ant_hrm_disp_init(ant_hrm_profile_t * p_profile,
+ ant_channel_config_t const * p_channel_config,
+ ant_hrm_evt_handler_t evt_handler);
+
+/**@brief Function for initializing the ANT HRM Sensor profile instance.
+ *
+ * @param[in] p_profile Pointer to the profile instance.
+ * @param[in] p_channel_config Pointer to the ANT channel configuration structure.
+ * @param[in] p_sens_config Pointer to the HRM sensor configuration structure.
+ *
+ * @retval NRF_SUCCESS If initialization was successful. Otherwise, an error code is returned.
+ */
+ret_code_t ant_hrm_sens_init(ant_hrm_profile_t * p_profile,
+ ant_channel_config_t const * p_channel_config,
+ ant_hrm_sens_config_t const * p_sens_config);
+
+/**@brief Function for opening the profile instance channel for ANT HRM Display.
+ *
+ * Before calling this function, pages should be configured.
+ *
+ * @param[in] p_profile Pointer to the profile instance.
+ *
+ * @retval NRF_SUCCESS If the channel was successfully opened. Otherwise, an error code is returned.
+ */
+ret_code_t ant_hrm_disp_open(ant_hrm_profile_t * p_profile);
+
+/**@brief Function for opening the profile instance channel for ANT HRM Sensor.
+ *
+ * Before calling this function, pages should be configured.
+ *
+ * @param[in] p_profile Pointer to the profile instance.
+ *
+ * @retval NRF_SUCCESS If the channel was successfully opened. Otherwise, an error code is returned.
+ */
+ret_code_t ant_hrm_sens_open(ant_hrm_profile_t * p_profile);
+
+/**@brief Function for handling the sensor ANT events.
+ *
+ * @details This function handles all events from the ANT stack that are of interest to the Heart Rate Monitor Sensor profile.
+ *
+ * @param[in] p_ant_evt Event received from the ANT stack.
+ * @param[in] p_context Pointer to the profile instance.
+ */
+void ant_hrm_sens_evt_handler(ant_evt_t * p_ant_evt, void * p_context);
+
+/**@brief Function for handling the display ANT events.
+ *
+ * @details This function handles all events from the ANT stack that are of interest to the Heart Rate Monitor Display profile.
+ *
+ * @param[in] p_ant_evt Event received from the ANT stack.
+ * @param[in] p_context Pointer to the profile instance.
+ */
+void ant_hrm_disp_evt_handler(ant_evt_t * p_ant_evt, void * p_context);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // ANT_HRM_H__
+/** @} */
+
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ant/ant_profiles/ant_hrm/ant_hrm_local.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ant/ant_profiles/ant_hrm/ant_hrm_local.h
new file mode 100644
index 0000000..fdffdc7
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ant/ant_profiles/ant_hrm/ant_hrm_local.h
@@ -0,0 +1,75 @@
+/**
+ * Copyright (c) 2015 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#ifndef ANT_HRM_LOCAL_H__
+#define ANT_HRM_LOCAL_H__
+
+#include <stdint.h>
+#include <stdbool.h>
+#include "ant_hrm.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @addtogroup ant_hrm
+ * @{
+ */
+
+/** @brief HRM Sensor control block. */
+typedef struct
+{
+ uint8_t toggle_bit;
+ ant_hrm_page_t main_page_number;
+ uint8_t page_1_present;
+ ant_hrm_page_t ext_page_number;
+ uint8_t message_counter;
+} ant_hrm_sens_cb_t;
+
+/**
+ * @}
+ */
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // ANT_HRM_LOCAL_H__
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ant/ant_profiles/ant_hrm/pages/ant_hrm_page_0.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ant/ant_profiles/ant_hrm/pages/ant_hrm_page_0.c
new file mode 100644
index 0000000..4f383a1
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ant/ant_profiles/ant_hrm/pages/ant_hrm_page_0.c
@@ -0,0 +1,116 @@
+/**
+ * Copyright (c) 2015 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#include "sdk_common.h"
+#if NRF_MODULE_ENABLED(ANT_HRM)
+
+#include "ant_hrm_page_0.h"
+#include "ant_hrm_utils.h"
+
+#define NRF_LOG_MODULE_NAME ant_hrm_page_0
+#if ANT_HRM_PAGE_0_LOG_ENABLED
+#define NRF_LOG_LEVEL ANT_HRM_PAGE_0_LOG_LEVEL
+#define NRF_LOG_INFO_COLOR ANT_HRM_PAGE_0_INFO_COLOR
+#else // ANT_HRM_PAGE_0_LOG_ENABLED
+#define NRF_LOG_LEVEL 0
+#endif // ANT_HRM_PAGE_0_LOG_ENABLED
+#include "nrf_log.h"
+NRF_LOG_MODULE_REGISTER();
+
+/**@brief HRM page 0 data layout structure. */
+typedef struct
+{
+ uint8_t reserved[3];
+ uint8_t heart_beat_evt_time_LSB;
+ uint8_t heart_beat_evt_time_MSB;
+ uint8_t heart_beat_count;
+ uint8_t computed_heart_rate;
+}ant_hrm_page0_data_layout_t;
+
+/**@brief Function for tracing page 0 and common data.
+ *
+ * @param[in] p_common_data Pointer to the common data.
+ * @param[in] p_page_data Pointer to the page 0 data.
+ */
+static void page0_data_log(ant_hrm_page0_data_t const * p_page_data)
+{
+ NRF_LOG_INFO("Heart beat count: %u", (unsigned int)p_page_data->beat_count);
+ NRF_LOG_INFO("Computed heart rate: %u",
+ (unsigned int) p_page_data->computed_heart_rate);
+ NRF_LOG_INFO("Heart beat event time: %u.%03us\r\n\n",
+ (unsigned int) ANT_HRM_BEAT_TIME_SEC(p_page_data->beat_time),
+ (unsigned int) ANT_HRM_BEAT_TIME_MSEC(p_page_data->beat_time));
+}
+
+
+void ant_hrm_page_0_encode(uint8_t * p_page_buffer,
+ ant_hrm_page0_data_t const * p_page_data)
+{
+ ant_hrm_page0_data_layout_t * p_outcoming_data = (ant_hrm_page0_data_layout_t *)p_page_buffer;
+ uint32_t beat_time = p_page_data->beat_time;
+
+ p_outcoming_data->reserved[0] = UINT8_MAX;
+ p_outcoming_data->reserved[1] = UINT8_MAX;
+ p_outcoming_data->reserved[2] = UINT8_MAX;
+ p_outcoming_data->heart_beat_evt_time_LSB = (uint8_t)(beat_time & UINT8_MAX);
+ p_outcoming_data->heart_beat_evt_time_MSB = (uint8_t)((beat_time >> 8) & UINT8_MAX);
+ p_outcoming_data->heart_beat_count = (uint8_t)p_page_data->beat_count;
+ p_outcoming_data->computed_heart_rate = (uint8_t)p_page_data->computed_heart_rate;
+
+ page0_data_log(p_page_data);
+}
+
+
+void ant_hrm_page_0_decode(uint8_t const * p_page_buffer,
+ ant_hrm_page0_data_t * p_page_data)
+{
+ ant_hrm_page0_data_layout_t const * p_incoming_data =
+ (ant_hrm_page0_data_layout_t *)p_page_buffer;
+
+ uint32_t beat_time = (uint32_t)((p_incoming_data->heart_beat_evt_time_MSB << 8)
+ + p_incoming_data->heart_beat_evt_time_LSB);
+
+ p_page_data->beat_count = (uint32_t)p_incoming_data->heart_beat_count;
+ p_page_data->computed_heart_rate = (uint32_t)p_incoming_data->computed_heart_rate;
+ p_page_data->beat_time = beat_time;
+
+ page0_data_log(p_page_data);
+}
+
+#endif // NRF_MODULE_ENABLED(ANT_HRM)
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ant/ant_profiles/ant_hrm/pages/ant_hrm_page_0.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ant/ant_profiles/ant_hrm/pages/ant_hrm_page_0.h
new file mode 100644
index 0000000..1b06e9a
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ant/ant_profiles/ant_hrm/pages/ant_hrm_page_0.h
@@ -0,0 +1,99 @@
+/**
+ * Copyright (c) 2015 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#ifndef ANT_HRM_PAGE_0_H__
+#define ANT_HRM_PAGE_0_H__
+
+/** @file
+ *
+ * @defgroup ant_sdk_profiles_hrm_page0 HRM profile page 0
+ * @{
+ * @ingroup ant_sdk_profiles_hrm_pages
+ */
+
+#include <stdint.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**@brief Data structure for HRM data page 0.
+ *
+ * This structure is used as a common page.
+ */
+typedef struct
+{
+ uint8_t beat_count; ///< Beat count.
+ uint8_t computed_heart_rate; ///< Computed heart rate.
+ uint16_t beat_time; ///< Beat time.
+} ant_hrm_page0_data_t;
+
+/**@brief Initialize page 0.
+ */
+#define DEFAULT_ANT_HRM_PAGE0() \
+ (ant_hrm_page0_data_t) \
+ { \
+ .beat_count = 0, \
+ .computed_heart_rate = 0, \
+ .beat_time = 0, \
+ }
+
+/**@brief Function for encoding page 0.
+ *
+ * @param[in] p_page_data Pointer to the page data.
+ * @param[out] p_page_buffer Pointer to the data buffer.
+ */
+void ant_hrm_page_0_encode(uint8_t * p_page_buffer,
+ ant_hrm_page0_data_t const * p_page_data);
+
+/**@brief Function for decoding page 0.
+ *
+ * @param[in] p_page_buffer Pointer to the data buffer.
+ * @param[out] p_page_data Pointer to the page data.
+ */
+void ant_hrm_page_0_decode(uint8_t const * p_page_buffer,
+ ant_hrm_page0_data_t * p_page_data);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // ANT_HRM_PAGE_0_H__
+/** @} */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ant/ant_profiles/ant_hrm/pages/ant_hrm_page_1.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ant/ant_profiles/ant_hrm/pages/ant_hrm_page_1.c
new file mode 100644
index 0000000..90eee6f
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ant/ant_profiles/ant_hrm/pages/ant_hrm_page_1.c
@@ -0,0 +1,102 @@
+/**
+ * Copyright (c) 2015 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#include "sdk_common.h"
+#if NRF_MODULE_ENABLED(ANT_HRM)
+
+#include "ant_hrm_page_1.h"
+#include "ant_hrm_utils.h"
+
+#define NRF_LOG_MODULE_NAME ant_hrm_page_1
+#if ANT_HRM_PAGE_1_LOG_ENABLED
+#define NRF_LOG_LEVEL ANT_HRM_PAGE_1_LOG_LEVEL
+#define NRF_LOG_INFO_COLOR ANT_HRM_PAGE_1_INFO_COLOR
+#else // ANT_HRM_PAGE_1_LOG_ENABLED
+#define NRF_LOG_LEVEL 0
+#endif // ANT_HRM_PAGE_1_LOG_ENABLED
+#include "nrf_log.h"
+NRF_LOG_MODULE_REGISTER();
+
+/**@brief HRM page 1 data layout structure. */
+typedef struct
+{
+ uint8_t cumulative_operating_time[3];
+ uint8_t reserved[4];
+}ant_hrm_page1_data_layout_t;
+
+/**@brief Function for tracing page 1 and common data.
+ *
+ * @param[in] p_common_data Pointer to the common data.
+ * @param[in] p_page_data Pointer to the page 1 data.
+ */
+static void page1_data_log(ant_hrm_page1_data_t const * p_page_data)
+{
+ NRF_LOG_INFO("Cumulative operating time: %ud %uh %um %us\r\n\n",
+ (unsigned int) ANT_HRM_OPERATING_DAYS(p_page_data->operating_time),
+ (unsigned int) ANT_HRM_OPERATING_HOURS(p_page_data->operating_time),
+ (unsigned int) ANT_HRM_OPERATING_MINUTES(p_page_data->operating_time),
+ (unsigned int) ANT_HRM_OPERATING_SECONDS(p_page_data->operating_time));
+}
+
+
+void ant_hrm_page_1_encode(uint8_t * p_page_buffer,
+ ant_hrm_page1_data_t const * p_page_data)
+{
+ ant_hrm_page1_data_layout_t * p_outcoming_data = (ant_hrm_page1_data_layout_t *)p_page_buffer;
+ uint32_t operating_time = p_page_data->operating_time;
+
+ UNUSED_PARAMETER(uint24_encode(operating_time, p_outcoming_data->cumulative_operating_time));
+ page1_data_log(p_page_data);
+}
+
+
+void ant_hrm_page_1_decode(uint8_t const * p_page_buffer,
+ ant_hrm_page1_data_t * p_page_data)
+{
+ ant_hrm_page1_data_layout_t const * p_incoming_data =
+ (ant_hrm_page1_data_layout_t *)p_page_buffer;
+
+ uint32_t operating_time = uint24_decode(p_incoming_data->cumulative_operating_time);
+
+ p_page_data->operating_time = operating_time;
+
+ page1_data_log(p_page_data);
+}
+
+#endif // NRF_MODULE_ENABLED(ANT_HRM)
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ant/ant_profiles/ant_hrm/pages/ant_hrm_page_1.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ant/ant_profiles/ant_hrm/pages/ant_hrm_page_1.h
new file mode 100644
index 0000000..5162025
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ant/ant_profiles/ant_hrm/pages/ant_hrm_page_1.h
@@ -0,0 +1,95 @@
+/**
+ * Copyright (c) 2015 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#ifndef ANT_HRM_PAGE_1_H__
+#define ANT_HRM_PAGE_1_H__
+
+/** @file
+ *
+ * @defgroup ant_sdk_profiles_hrm_page1 HRM profile page 1
+ * @{
+ * @ingroup ant_sdk_profiles_hrm_pages
+ */
+
+#include <stdint.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**@brief Data structure for HRM data page 1.
+ *
+ * This structure implements only page 1 specific data.
+ */
+typedef struct
+{
+ uint32_t operating_time; ///< Operating time.
+} ant_hrm_page1_data_t;
+
+/**@brief Initialize page 1.
+ */
+#define DEFAULT_ANT_HRM_PAGE1() \
+ (ant_hrm_page1_data_t) \
+ { \
+ .operating_time = 0, \
+ }
+
+/**@brief Function for encoding page 1.
+ *
+ * @param[in] p_page_data Pointer to the page data.
+ * @param[out] p_page_buffer Pointer to the data buffer.
+ */
+void ant_hrm_page_1_encode(uint8_t * p_page_buffer,
+ ant_hrm_page1_data_t const * p_page_data);
+
+/**@brief Function for decoding page 1.
+ *
+ * @param[in] p_page_buffer Pointer to the data buffer.
+ * @param[out] p_page_data Pointer to the page data.
+ */
+void ant_hrm_page_1_decode(uint8_t const * p_page_buffer,
+ ant_hrm_page1_data_t * p_page_data);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // ANT_HRM_PAGE_1_H__
+/** @} */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ant/ant_profiles/ant_hrm/pages/ant_hrm_page_2.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ant/ant_profiles/ant_hrm/pages/ant_hrm_page_2.c
new file mode 100644
index 0000000..1873b93
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ant/ant_profiles/ant_hrm/pages/ant_hrm_page_2.c
@@ -0,0 +1,106 @@
+/**
+ * Copyright (c) 2015 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#include "sdk_common.h"
+#if NRF_MODULE_ENABLED(ANT_HRM)
+
+#include "ant_hrm_page_2.h"
+
+#define NRF_LOG_MODULE_NAME ant_hrm_page_2
+#if ANT_HRM_PAGE_2_LOG_ENABLED
+#define NRF_LOG_LEVEL ANT_HRM_PAGE_2_LOG_LEVEL
+#define NRF_LOG_INFO_COLOR ANT_HRM_PAGE_2_INFO_COLOR
+#else // ANT_HRM_PAGE_2_LOG_ENABLED
+#define NRF_LOG_LEVEL 0
+#endif // ANT_HRM_PAGE_2_LOG_ENABLED
+#include "nrf_log.h"
+NRF_LOG_MODULE_REGISTER();
+
+/**@brief HRM page 2 data layout structure. */
+typedef struct
+{
+ uint8_t manuf_id;
+ uint8_t serial_num_LSB;
+ uint8_t serial_num_MSB;
+ uint8_t reserved[4];
+}ant_hrm_page2_data_layout_t;
+
+/**@brief Function for tracing page 2 and common data.
+ *
+ * @param[in] p_common_data Pointer to the common data.
+ * @param[in] p_page_data Pointer to the page 2 data.
+ */
+static void page2_data_log(ant_hrm_page2_data_t const * p_page_data)
+{
+ NRF_LOG_INFO("Manufacturer ID: %u", (unsigned int)p_page_data->manuf_id);
+ NRF_LOG_INFO("Serial No (upper 16-bits): 0x%X\r\n\n", (unsigned int)p_page_data->serial_num);
+}
+
+
+void ant_hrm_page_2_encode(uint8_t * p_page_buffer,
+ ant_hrm_page2_data_t const * p_page_data)
+{
+ ant_hrm_page2_data_layout_t * p_outcoming_data = (ant_hrm_page2_data_layout_t *)p_page_buffer;
+ uint32_t serial_num = p_page_data->serial_num;
+
+ p_outcoming_data->manuf_id = (uint8_t)p_page_data->manuf_id;
+ p_outcoming_data->serial_num_LSB = (uint8_t)(serial_num & UINT8_MAX);
+ p_outcoming_data->serial_num_MSB = (uint8_t)((serial_num >> 8) & UINT8_MAX);
+
+ page2_data_log(p_page_data);
+}
+
+
+void ant_hrm_page_2_decode(uint8_t const * p_page_buffer,
+ ant_hrm_page2_data_t * p_page_data)
+{
+ ant_hrm_page2_data_layout_t const * p_incoming_data =
+ (ant_hrm_page2_data_layout_t *)p_page_buffer;
+ uint32_t serial_num =
+ (uint32_t)((p_incoming_data->serial_num_MSB << 8)
+ + p_incoming_data->
+ serial_num_LSB);
+
+ p_page_data->manuf_id = (uint32_t)p_incoming_data->manuf_id;
+ p_page_data->serial_num = serial_num;
+
+ page2_data_log(p_page_data);
+}
+
+#endif // NRF_MODULE_ENABLED(ANT_HRM)
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ant/ant_profiles/ant_hrm/pages/ant_hrm_page_2.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ant/ant_profiles/ant_hrm/pages/ant_hrm_page_2.h
new file mode 100644
index 0000000..4460373
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ant/ant_profiles/ant_hrm/pages/ant_hrm_page_2.h
@@ -0,0 +1,97 @@
+/**
+ * Copyright (c) 2015 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#ifndef ANT_HRM_PAGE_2_H__
+#define ANT_HRM_PAGE_2_H__
+
+/** @file
+ *
+ * @defgroup ant_sdk_profiles_hrm_page2 HRM profile page 2
+ * @{
+ * @ingroup ant_sdk_profiles_hrm_pages
+ */
+
+#include <stdint.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**@brief Data structure for HRM data page 2.
+ *
+ * This structure implements only page 2 specific data.
+ */
+typedef struct
+{
+ uint8_t manuf_id; ///< Manufacturer ID.
+ uint16_t serial_num; ///< Serial number.
+} ant_hrm_page2_data_t;
+
+/**@brief Initialize page 2.
+ */
+#define DEFAULT_ANT_HRM_PAGE2() \
+ (ant_hrm_page2_data_t) \
+ { \
+ .manuf_id = 0, \
+ .serial_num = 0, \
+ }
+
+/**@brief Function for encoding page 2.
+ *
+ * @param[in] p_page_data Pointer to the page data.
+ * @param[out] p_page_buffer Pointer to the data buffer.
+ */
+void ant_hrm_page_2_encode(uint8_t * p_page_buffer,
+ ant_hrm_page2_data_t const * p_page_data);
+
+/**@brief Function for decoding page 2.
+ *
+ * @param[in] p_page_buffer Pointer to the data buffer.
+ * @param[out] p_page_data Pointer to the page data.
+ */
+void ant_hrm_page_2_decode(uint8_t const * p_page_buffer,
+ ant_hrm_page2_data_t * p_page_data);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // ANT_HRM_PAGE_2_H__
+/** @} */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ant/ant_profiles/ant_hrm/pages/ant_hrm_page_3.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ant/ant_profiles/ant_hrm/pages/ant_hrm_page_3.c
new file mode 100644
index 0000000..aa1ec7e
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ant/ant_profiles/ant_hrm/pages/ant_hrm_page_3.c
@@ -0,0 +1,103 @@
+/**
+ * Copyright (c) 2015 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#include "sdk_common.h"
+#if NRF_MODULE_ENABLED(ANT_HRM)
+
+#include "ant_hrm_page_3.h"
+
+#define NRF_LOG_MODULE_NAME ant_hrm_page_3
+#if ANT_HRM_PAGE_3_LOG_ENABLED
+#define NRF_LOG_LEVEL ANT_HRM_PAGE_3_LOG_LEVEL
+#define NRF_LOG_INFO_COLOR ANT_HRM_PAGE_3_INFO_COLOR
+#else // ANT_HRM_PAGE_3_LOG_ENABLED
+#define NRF_LOG_LEVEL 0
+#endif // ANT_HRM_PAGE_3_LOG_ENABLED
+#include "nrf_log.h"
+NRF_LOG_MODULE_REGISTER();
+
+/**@brief HRM page 3 data layout structure. */
+typedef struct
+{
+ uint8_t hw_version;
+ uint8_t sw_version;
+ uint8_t model_num;
+ uint8_t reserved[4];
+}ant_hrm_page3_data_layout_t;
+
+/**@brief Function for tracing page 3 and common data.
+ *
+ * @param[in] p_common_data Pointer to the common data.
+ * @param[in] p_page_data Pointer to the page 3 data.
+ */
+static void page3_data_log(ant_hrm_page3_data_t const * p_page_data)
+{
+ NRF_LOG_INFO("Hardware Rev ID %u", (unsigned int)p_page_data->hw_version);
+ NRF_LOG_INFO("Model %u", (unsigned int)p_page_data->model_num);
+ NRF_LOG_INFO("Software Ver ID %u\r\n\n", (unsigned int)p_page_data->sw_version);
+}
+
+
+void ant_hrm_page_3_encode(uint8_t * p_page_buffer,
+ ant_hrm_page3_data_t const * p_page_data)
+{
+ ant_hrm_page3_data_layout_t * p_outcoming_data = (ant_hrm_page3_data_layout_t *)p_page_buffer;
+
+ p_outcoming_data->hw_version = (uint8_t)p_page_data->hw_version;
+ p_outcoming_data->sw_version = (uint8_t)p_page_data->sw_version;
+ p_outcoming_data->model_num = (uint8_t)p_page_data->model_num;
+
+ page3_data_log(p_page_data);
+}
+
+
+void ant_hrm_page_3_decode(uint8_t const * p_page_buffer,
+ ant_hrm_page3_data_t * p_page_data)
+{
+ ant_hrm_page3_data_layout_t const * p_incoming_data =
+ (ant_hrm_page3_data_layout_t *)p_page_buffer;
+
+ p_page_data->hw_version = (uint32_t)p_incoming_data->hw_version;
+ p_page_data->sw_version = (uint32_t)p_incoming_data->sw_version;
+ p_page_data->model_num = (uint32_t)p_incoming_data->model_num;
+
+ page3_data_log(p_page_data);
+}
+
+#endif // NRF_MODULE_ENABLED(ANT_HRM)
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ant/ant_profiles/ant_hrm/pages/ant_hrm_page_3.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ant/ant_profiles/ant_hrm/pages/ant_hrm_page_3.h
new file mode 100644
index 0000000..1fed280
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ant/ant_profiles/ant_hrm/pages/ant_hrm_page_3.h
@@ -0,0 +1,99 @@
+/**
+ * Copyright (c) 2015 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#ifndef ANT_HRM_PAGE_3_H__
+#define ANT_HRM_PAGE_3_H__
+
+/** @file
+ *
+ * @defgroup ant_sdk_profiles_hrm_page3 HRM profile page 3
+ * @{
+ * @ingroup ant_sdk_profiles_hrm_pages
+ */
+
+#include <stdint.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**@brief Data structure for HRM data page 3.
+ *
+ * This structure implements only page 3 specific data.
+ */
+typedef struct
+{
+ uint8_t hw_version; ///< Hardware version.
+ uint8_t sw_version; ///< Software version.
+ uint8_t model_num; ///< Model number.
+} ant_hrm_page3_data_t;
+
+/**@brief Initialize page 3.
+ */
+#define DEFAULT_ANT_HRM_PAGE3() \
+ (ant_hrm_page3_data_t) \
+ { \
+ .hw_version = 0, \
+ .sw_version = 0, \
+ .model_num = 0, \
+ }
+
+/**@brief Function for encoding page 3.
+ *
+ * @param[in] p_page_data Pointer to the page data.
+ * @param[out] p_page_buffer Pointer to the data buffer.
+ */
+void ant_hrm_page_3_encode(uint8_t * p_page_buffer,
+ ant_hrm_page3_data_t const * p_page_data);
+
+/**@brief Function for decoding page 3.
+ *
+ * @param[in] p_page_buffer Pointer to the data buffer.
+ * @param[out] p_page_data Pointer to the page data.
+ */
+void ant_hrm_page_3_decode(uint8_t const * p_page_buffer,
+ ant_hrm_page3_data_t * p_page_data);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // ANT_HRM_PAGE_3_H__
+/** @} */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ant/ant_profiles/ant_hrm/pages/ant_hrm_page_4.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ant/ant_profiles/ant_hrm/pages/ant_hrm_page_4.c
new file mode 100644
index 0000000..62bd683
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ant/ant_profiles/ant_hrm/pages/ant_hrm_page_4.c
@@ -0,0 +1,107 @@
+/**
+ * Copyright (c) 2015 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#include "sdk_common.h"
+#if NRF_MODULE_ENABLED(ANT_HRM)
+
+#include "ant_hrm_page_4.h"
+#include "ant_hrm_utils.h"
+
+#define NRF_LOG_MODULE_NAME ant_hrm_page_4
+#if ANT_HRM_PAGE_4_LOG_ENABLED
+#define NRF_LOG_LEVEL ANT_HRM_PAGE_4_LOG_LEVEL
+#define NRF_LOG_INFO_COLOR ANT_HRM_PAGE_4_INFO_COLOR
+#else // ANT_HRM_PAGE_4_LOG_ENABLED
+#define NRF_LOG_LEVEL 0
+#endif // ANT_HRM_PAGE_4_LOG_ENABLED
+#include "nrf_log.h"
+NRF_LOG_MODULE_REGISTER();
+
+/**@brief HRM page 4 data layout structure. */
+typedef struct
+{
+ uint8_t manuf_spec;
+ uint8_t prev_beat_LSB;
+ uint8_t prev_beat_MSB;
+ uint8_t reserved[4];
+}ant_hrm_page4_data_layout_t;
+
+/**@brief Function for tracing page 4 and common data.
+ *
+ * @param[in] p_common_data Pointer to the common data.
+ * @param[in] p_page_data Pointer to the page 4 data.
+ */
+static void page4_data_log(ant_hrm_page4_data_t const * p_page_data)
+{
+ NRF_LOG_INFO("Previous heart beat event time: %u.%03us\r\n\n",
+ (unsigned int)ANT_HRM_BEAT_TIME_SEC(p_page_data->prev_beat),
+ (unsigned int)ANT_HRM_BEAT_TIME_MSEC(p_page_data->prev_beat));
+}
+
+
+void ant_hrm_page_4_encode(uint8_t * p_page_buffer,
+ ant_hrm_page4_data_t const * p_page_data)
+{
+ ant_hrm_page4_data_layout_t * p_outcoming_data = (ant_hrm_page4_data_layout_t *)p_page_buffer;
+ uint32_t prev_beat = p_page_data->prev_beat;
+
+ p_outcoming_data->manuf_spec = p_page_data->manuf_spec;
+ p_outcoming_data->prev_beat_LSB = (uint8_t)(prev_beat & UINT8_MAX);
+ p_outcoming_data->prev_beat_MSB = (uint8_t)((prev_beat >> 8) & UINT8_MAX);
+
+ page4_data_log(p_page_data);
+}
+
+
+void ant_hrm_page_4_decode(uint8_t const * p_page_buffer,
+ ant_hrm_page4_data_t * p_page_data)
+{
+ ant_hrm_page4_data_layout_t const * p_incoming_data =
+ (ant_hrm_page4_data_layout_t *)p_page_buffer;
+
+ uint32_t prev_beat = (uint32_t)((p_incoming_data->prev_beat_MSB << 8)
+ + p_incoming_data->prev_beat_LSB);
+
+ p_page_data->manuf_spec = p_incoming_data->manuf_spec;
+ p_page_data->prev_beat = prev_beat;
+
+ page4_data_log(p_page_data);
+}
+
+#endif // NRF_MODULE_ENABLED(ANT_HRM)
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ant/ant_profiles/ant_hrm/pages/ant_hrm_page_4.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ant/ant_profiles/ant_hrm/pages/ant_hrm_page_4.h
new file mode 100644
index 0000000..f59cdde
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ant/ant_profiles/ant_hrm/pages/ant_hrm_page_4.h
@@ -0,0 +1,97 @@
+/**
+ * Copyright (c) 2015 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#ifndef ANT_HRM_PAGE_4_H__
+#define ANT_HRM_PAGE_4_H__
+
+/** @file
+ *
+ * @defgroup ant_sdk_profiles_hrm_page4 HRM profile page 4
+ * @{
+ * @ingroup ant_sdk_profiles_hrm_pages
+ */
+
+#include <stdint.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**@brief Data structure for HRM data page 4.
+ *
+ * This structure implements only page 4 specific data.
+ */
+typedef struct
+{
+ uint8_t manuf_spec; ///< Manufacturer specific byte.
+ uint16_t prev_beat; ///< Previous beat.
+} ant_hrm_page4_data_t;
+
+/**@brief Initialize page 4.
+ */
+#define DEFAULT_ANT_HRM_PAGE4() \
+ (ant_hrm_page4_data_t) \
+ { \
+ .manuf_spec = 0, \
+ .prev_beat = 0, \
+ }
+
+/**@brief Function for encoding page 4.
+ *
+ * @param[in] p_page_data Pointer to the page data.
+ * @param[out] p_page_buffer Pointer to the data buffer.
+ */
+void ant_hrm_page_4_encode(uint8_t * p_page_buffer,
+ ant_hrm_page4_data_t const * p_page_data);
+
+/**@brief Function for decoding page 4.
+ *
+ * @param[in] p_page_buffer Pointer to the data buffer.
+ * @param[out] p_page_data Pointer to the page data.
+ */
+void ant_hrm_page_4_decode(uint8_t const * p_page_buffer,
+ ant_hrm_page4_data_t * p_page_data);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // ANT_HRM_PAGE_3_H__
+/** @} */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ant/ant_profiles/ant_hrm/pages/ant_hrm_pages.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ant/ant_profiles/ant_hrm/pages/ant_hrm_pages.h
new file mode 100644
index 0000000..c1e328e
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ant/ant_profiles/ant_hrm/pages/ant_hrm_pages.h
@@ -0,0 +1,67 @@
+/**
+ * Copyright (c) 2015 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#ifndef __ANT_HRM_PAGES_H
+#define __ANT_HRM_PAGES_H
+
+/** @file
+ *
+ * @defgroup ant_sdk_profiles_hrm_pages Heart Rate Monitor profile pages
+ * @{
+ * @ingroup ant_hrm
+ * @brief This module implements functions for the HRM data pages.
+ */
+
+#include "ant_hrm_page_0.h"
+#include "ant_hrm_page_1.h"
+#include "ant_hrm_page_2.h"
+#include "ant_hrm_page_3.h"
+#include "ant_hrm_page_4.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // __ANT_HRM_PAGES_H
+/** @} */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ant/ant_profiles/ant_hrm/simulator/ant_hrm_simulator.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ant/ant_profiles/ant_hrm/simulator/ant_hrm_simulator.c
new file mode 100644
index 0000000..e06c7a0
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ant/ant_profiles/ant_hrm/simulator/ant_hrm_simulator.c
@@ -0,0 +1,148 @@
+/**
+ * Copyright (c) 2015 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#include "sdk_config.h"
+#if ANT_HRM_ENABLED
+
+#include "ant_hrm_simulator.h"
+#include "ant_hrm_utils.h"
+#include "nordic_common.h"
+
+#define ITERATION_ANT_CYCLES HRM_MSG_PERIOD_4Hz ///< period of calculation [1/32678 s], defined in ANT device profile
+#define ITERATION_PERIOD (ITERATION_ANT_CYCLES * 1024 / ANT_CLOCK_FREQUENCY) ///< integer part of calculation's period [1/1024 s]
+#define ITERATION_FRACTION (ITERATION_ANT_CYCLES * 1024 % ANT_CLOCK_FREQUENCY) ///< fractional part of calculation's period [1/32678 s]
+
+void ant_hrm_simulator_init(ant_hrm_simulator_t * p_simulator,
+ ant_hrm_simulator_cfg_t const * p_config,
+ bool auto_change)
+{
+
+ p_simulator->p_profile = p_config->p_profile;
+ p_simulator->_cb.sensorsim_cfg = p_config->sensorsim_cfg;
+ p_simulator->_cb.auto_change = auto_change;
+ p_simulator->_cb.sensorsim_state.current_val = p_simulator->_cb.sensorsim_cfg.min;
+ p_simulator->_cb.time_since_last_hb = 0;
+ p_simulator->_cb.fraction_since_last_hb = 0;
+
+ sensorsim_init(&(p_simulator->_cb.sensorsim_state), &(p_simulator->_cb.sensorsim_cfg));
+}
+
+
+void ant_hrm_simulator_one_iteration(ant_hrm_simulator_t * p_simulator)
+{
+
+ if (p_simulator->_cb.auto_change)
+ {
+ UNUSED_PARAMETER(sensorsim_measure(&(p_simulator->_cb.sensorsim_state),
+ &(p_simulator->_cb.sensorsim_cfg)));
+ }
+
+ // @note: Take a local copy within scope in order to assist the compiler in variable register
+ // allocation.
+ const uint32_t computed_heart_rate_value = p_simulator->_cb.sensorsim_state.current_val;
+
+ // @note: This implementation assumes that the current instantaneous heart can vary and this
+ // function is called with static frequency.
+ // value and the heart rate pulse interval is derived from it. The computation is based on 60
+ // seconds in a minute and the used time base is 1/1024 seconds.
+ const uint32_t current_hb_pulse_interval = (60u * 1024u) / computed_heart_rate_value;
+
+ // update time from last hb detected
+ p_simulator->_cb.time_since_last_hb += ITERATION_PERIOD;
+
+ // extended celculadion by fraction make calculating accurat in long time perspective
+ p_simulator->_cb.fraction_since_last_hb += ITERATION_FRACTION;
+ uint32_t add_period = p_simulator->_cb.fraction_since_last_hb / ANT_CLOCK_FREQUENCY;
+
+ if (add_period > 0)
+ {
+ p_simulator->_cb.time_since_last_hb++;
+ p_simulator->_cb.fraction_since_last_hb %= ANT_CLOCK_FREQUENCY;
+ }
+
+ // calc number of hb as will fill
+ uint32_t new_beats = p_simulator->_cb.time_since_last_hb / current_hb_pulse_interval;
+ uint32_t add_event_time = new_beats * current_hb_pulse_interval;
+
+ if (new_beats > 0)
+ {
+ p_simulator->p_profile->HRM_PROFILE_computed_heart_rate =
+ (uint8_t)computed_heart_rate_value;
+
+ // Current heart beat event time is the previous event time added with the current heart rate
+ // pulse interval.
+ uint32_t current_heart_beat_event_time = p_simulator->p_profile->HRM_PROFILE_beat_time +
+ add_event_time;
+
+ // Set current event time.
+ p_simulator->p_profile->HRM_PROFILE_beat_time = current_heart_beat_event_time; // <- B<4,5> <-
+
+ // Set previous event time. // p4.B<2,3> <- B<4,5>
+ p_simulator->p_profile->HRM_PROFILE_prev_beat =
+ p_simulator->p_profile->HRM_PROFILE_beat_time - current_hb_pulse_interval;
+
+ // Event count.
+ p_simulator->p_profile->HRM_PROFILE_beat_count += new_beats; // B<6>
+
+ p_simulator->_cb.time_since_last_hb -= add_event_time;
+ }
+}
+
+
+void ant_hrm_simulator_increment(ant_hrm_simulator_t * p_simulator)
+{
+ if (!p_simulator->_cb.auto_change)
+ {
+ sensorsim_increment(&(p_simulator->_cb.sensorsim_state),
+ &(p_simulator->_cb.sensorsim_cfg));
+ }
+}
+
+
+void ant_hrm_simulator_decrement(ant_hrm_simulator_t * p_simulator)
+{
+ if (!p_simulator->_cb.auto_change)
+ {
+ sensorsim_decrement(&(p_simulator->_cb.sensorsim_state),
+ &(p_simulator->_cb.sensorsim_cfg));
+ }
+}
+
+
+#endif // ANT_HRM_ENABLED
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ant/ant_profiles/ant_hrm/simulator/ant_hrm_simulator.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ant/ant_profiles/ant_hrm/simulator/ant_hrm_simulator.h
new file mode 100644
index 0000000..0d5b84e
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ant/ant_profiles/ant_hrm/simulator/ant_hrm_simulator.h
@@ -0,0 +1,130 @@
+/**
+ * Copyright (c) 2015 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#ifndef ANT_HRM_SIMULATOR_H__
+#define ANT_HRM_SIMULATOR_H__
+
+/** @file
+ *
+ * @defgroup ant_sdk_hrm_simulator ANT HRM simulator
+ * @{
+ * @ingroup ant_sdk_simulators
+ * @brief ANT HRM simulator module.
+ *
+ * @details This module simulates a pulse for the ANT HRM profile. The module calculates abstract values, which are handled
+ * by the HRM pages data model to ensure that they are compatible. It provides a handler for changing the heart rate
+ * value manually and functionality to change the heart rate value automatically.
+ *
+ */
+
+#include <stdint.h>
+#include <stdbool.h>
+#include "ant_hrm.h"
+#include "ant_hrm_utils.h"
+#include "sensorsim.h"
+#include "ant_hrm_simulator_local.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+/**@brief HRM simulator configuration structure. */
+typedef struct
+{
+ ant_hrm_profile_t * p_profile; ///< Related profile.
+ sensorsim_cfg_t sensorsim_cfg; ///< Sensorsim configuration.
+} ant_hrm_simulator_cfg_t;
+
+/**@brief Initialize @ref ant_hrm_simulator_cfg_t.
+ */
+#define DEFAULT_ANT_HRM_SIMULATOR_CFG(P_PROFILE, MIN_HEART_RATE, MAX_HEART_RATE, INCREMENT) \
+ { \
+ .p_profile = (P_PROFILE), \
+ .sensorsim_cfg.min = (MIN_HEART_RATE), \
+ .sensorsim_cfg.max = (MAX_HEART_RATE), \
+ .sensorsim_cfg.incr = (INCREMENT), \
+ .sensorsim_cfg.start_at_max = false, \
+ }
+
+/**@brief HRM simulator structure. */
+typedef struct
+{
+ ant_hrm_profile_t * p_profile; ///< Related profile.
+ ant_hrm_simulator_cb_t _cb; ///< Internal control block.
+} ant_hrm_simulator_t;
+
+
+/**@brief Function for initializing the ANT HRM simulator instance.
+ *
+ * @param[in] p_simulator Pointer to the simulator instance.
+ * @param[in] p_config Pointer to the simulator configuration structure.
+ * @param[in] auto_change Enable or disable automatic changes of the cadence.
+ */
+void ant_hrm_simulator_init(ant_hrm_simulator_t * p_simulator,
+ ant_hrm_simulator_cfg_t const * p_config,
+ bool auto_change);
+
+/**@brief Function for simulating a device event.
+ *
+ * @details Based on this event, the transmitter data is simulated.
+ *
+ * This function should be called in the HRM TX event handler.
+ */
+void ant_hrm_simulator_one_iteration(ant_hrm_simulator_t * p_simulator);
+
+/**@brief Function for incrementing the cadence value.
+ *
+ * @param[in] p_simulator Pointer to the simulator instance.
+ */
+void ant_hrm_simulator_increment(ant_hrm_simulator_t * p_simulator);
+
+/**@brief Function for decrementing the cadence value.
+ *
+ * @param[in] p_simulator Pointer to the simulator instance.
+ */
+void ant_hrm_simulator_decrement(ant_hrm_simulator_t * p_simulator);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // ANT_HRM_SIMULATOR_H__
+/** @} */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ant/ant_profiles/ant_hrm/simulator/ant_hrm_simulator_local.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ant/ant_profiles/ant_hrm/simulator/ant_hrm_simulator_local.h
new file mode 100644
index 0000000..be16be6
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ant/ant_profiles/ant_hrm/simulator/ant_hrm_simulator_local.h
@@ -0,0 +1,69 @@
+/**
+ * Copyright (c) 2015 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#ifndef ANT_HRM_SIMULATOR_LOCAL_H__
+#define ANT_HRM_SIMULATOR_LOCAL_H__
+
+#include <stdint.h>
+#include <stdbool.h>
+#include "ant_hrm.h"
+#include "sensorsim.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @ingroup ant_sdk_hrm_simulator
+ * @brief HRM simulator control block structure. */
+typedef struct
+{
+ bool auto_change; ///< Cadence will change automatically (if auto_change is set) or manually.
+ uint32_t time_since_last_hb; ///< Time since last heart beat occurred (integer part).
+ uint64_t fraction_since_last_hb; ///< Time since last heart beat occurred (fractional part).
+ sensorsim_state_t sensorsim_state; ///< State of the simulated sensor.
+ sensorsim_cfg_t sensorsim_cfg; ///< Configuration of the simulated sensor.
+} ant_hrm_simulator_cb_t;
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // ANT_HRM_SIMULATOR_LOCAL_H__
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ant/ant_profiles/ant_hrm/utils/ant_hrm_utils.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ant/ant_profiles/ant_hrm/utils/ant_hrm_utils.h
new file mode 100644
index 0000000..a6849ac
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ant/ant_profiles/ant_hrm/utils/ant_hrm_utils.h
@@ -0,0 +1,111 @@
+/**
+ * Copyright (c) 2015 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#ifndef ANT_HRM_UTILS_H__
+#define ANT_HRM_UTILS_H__
+
+#include "app_util.h"
+#include "nrf_assert.h"
+#include "nrf.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** @file
+ *
+ * @defgroup ant_sdk_profiles_hrm_utils Heart Rate Monitor profile utilities
+ * @{
+ * @ingroup ant_hrm
+ * @brief This module implements utilities for the Heart Rate Monitor profile.
+ *
+ */
+
+/**@brief Unit for HRM operating time.
+ *
+ * @details According to the ANT HRM specification, the operating time unit is 2 seconds.
+ */
+#define ANT_HRM_OPERATING_TIME_UNIT 2u
+
+/**@brief This macro should be used to get the seconds part of the operating time.
+ */
+#define ANT_HRM_OPERATING_SECONDS(OPERATING_TIME) (((OPERATING_TIME) * ANT_HRM_OPERATING_TIME_UNIT) % 60)
+
+/**@brief This macro should be used to get the minutes part of the operating time.
+ */
+#define ANT_HRM_OPERATING_MINUTES(OPERATING_TIME) ((((OPERATING_TIME) * ANT_HRM_OPERATING_TIME_UNIT) / 60) % 60)
+
+/**@brief This macro should be used to get the hours part of the operating time.
+ */
+#define ANT_HRM_OPERATING_HOURS(OPERATING_TIME) ((((OPERATING_TIME) * ANT_HRM_OPERATING_TIME_UNIT) / (60 * 60)) % 24)
+
+/**@brief This macro should be used to get the days part of the operating time.
+ */
+#define ANT_HRM_OPERATING_DAYS(OPERATING_TIME) ((((OPERATING_TIME) * ANT_HRM_OPERATING_TIME_UNIT) / (60 * 60)) / 24)
+
+/**@brief Number of HRM beat time counts per second.
+ *
+ * @details According to the ANT HRM specification, the beat time unit is 1/1024 of a second.
+ */
+#define ANT_HRM_BEAT_TIME_COUNTS_PER_SEC 1024u
+
+/**@brief Beat time display required precision.
+ *
+ * @details This value is used to decode the number of milliseconds.
+ */
+#define ANT_HRM_BEAT_TIME_PRECISION 1000u
+
+/**@brief This macro should be used to get the seconds part of the HRM beat time.
+ */
+#define ANT_HRM_BEAT_TIME_SEC(BEAT_TIME) ((BEAT_TIME) / ANT_HRM_BEAT_TIME_COUNTS_PER_SEC)
+
+/**@brief This macro should be used to get the milliseconds part of the HRM beat time.
+ */
+#define ANT_HRM_BEAT_TIME_MSEC(BEAT_TIME) (((((BEAT_TIME) % ANT_HRM_BEAT_TIME_COUNTS_PER_SEC) * ANT_HRM_BEAT_TIME_PRECISION) \
+ + (ANT_HRM_BEAT_TIME_COUNTS_PER_SEC / 2)) \
+ / ANT_HRM_BEAT_TIME_COUNTS_PER_SEC)
+/** @} */
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // ANT_HRM_UTILS_H__
+
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ant/ant_profiles/ant_sdm/ant_sdm.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ant/ant_profiles/ant_sdm/ant_sdm.c
new file mode 100644
index 0000000..ed1ea44
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ant/ant_profiles/ant_sdm/ant_sdm.c
@@ -0,0 +1,409 @@
+/**
+ * Copyright (c) 2015 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#include "sdk_common.h"
+#if NRF_MODULE_ENABLED(ANT_SDM)
+
+#include "nrf_assert.h"
+#include "app_error.h"
+#include "ant_interface.h"
+#include "ant_sdm.h"
+#include "app_error.h"
+#include "ant_sdm_utils.h"
+
+#define NRF_LOG_MODULE_NAME ant_sdm
+#if ANT_SDM_LOG_ENABLED
+#define NRF_LOG_LEVEL ANT_SDM_LOG_LEVEL
+#define NRF_LOG_INFO_COLOR ANT_SDM_INFO_COLOR
+#else // ANT_SDM_LOG_ENABLED
+#define NRF_LOG_LEVEL 0
+#endif // ANT_SDM_LOG_ENABLED
+#include "nrf_log.h"
+NRF_LOG_MODULE_REGISTER();
+
+#define COMMON_DATA_INTERVAL 64 /**< Common data page is sent every 65th message. */
+
+/**@brief SDM message data layout structure. */
+typedef struct
+{
+ ant_sdm_page_t page_number;
+ uint8_t page_payload[7];
+}ant_sdm_message_layout_t;
+
+/**@brief Function for initializing the ANT SDM profile instance.
+ *
+ * @param[in] p_profile Pointer to the profile instance.
+ * @param[in] p_channel_config Pointer to the ANT channel configuration structure.
+ *
+ * @retval NRF_SUCCESS Successful initialization.
+ * Error code when initialization failed.
+ */
+static ret_code_t ant_sdm_init(ant_sdm_profile_t * p_profile,
+ ant_channel_config_t const * p_channel_config)
+{
+ p_profile->channel_number = p_channel_config->channel_number;
+
+ p_profile->page_1 = DEFAULT_ANT_SDM_PAGE1();
+ p_profile->page_2 = DEFAULT_ANT_SDM_PAGE2();
+ p_profile->page_3 = DEFAULT_ANT_SDM_PAGE3();
+ p_profile->page_22 = DEFAULT_ANT_SDM_PAGE22();
+ p_profile->common = DEFAULT_ANT_SDM_COMMON_DATA();
+ p_profile->page_80 = DEFAULT_ANT_COMMON_page80();
+ p_profile->page_81 = DEFAULT_ANT_COMMON_page81();
+
+ NRF_LOG_INFO("ANT SDM channel %u init", p_profile->channel_number);
+ return ant_channel_init(p_channel_config);
+}
+
+ret_code_t ant_sdm_disp_init(ant_sdm_profile_t * p_profile,
+ ant_channel_config_t const * p_channel_config,
+ ant_sdm_disp_config_t const * p_disp_config)
+{
+ ASSERT(p_profile != NULL);
+ ASSERT(p_channel_config != NULL);
+ ASSERT(p_disp_config != NULL);
+ ASSERT(p_disp_config->p_cb != NULL);
+ ASSERT(p_disp_config->evt_handler != NULL);
+
+ p_profile->evt_handler = p_disp_config->evt_handler;
+ p_profile->_cb.p_disp_cb = p_disp_config->p_cb;
+ ant_request_controller_init(&(p_profile->_cb.p_disp_cb->req_controller));
+
+ return ant_sdm_init(p_profile, p_channel_config);
+}
+
+ret_code_t ant_sdm_sens_init(ant_sdm_profile_t * p_profile,
+ ant_channel_config_t const * p_channel_config,
+ ant_sdm_sens_config_t const * p_sens_config)
+{
+ ASSERT(p_profile != NULL);
+ ASSERT(p_channel_config != NULL);
+ ASSERT(p_sens_config != NULL);
+ ASSERT(p_sens_config->p_cb != NULL);
+ ASSERT(p_sens_config->evt_handler != NULL);
+ ASSERT(p_sens_config->supplementary_page_number == ANT_SDM_PAGE_1
+ || p_sens_config->supplementary_page_number == ANT_SDM_PAGE_2
+ || p_sens_config->supplementary_page_number == ANT_SDM_PAGE_3);
+
+ p_profile->evt_handler = p_sens_config->evt_handler;
+ p_profile->_cb.p_sens_cb = p_sens_config->p_cb;
+ ant_request_controller_init(&(p_profile->_cb.p_sens_cb->req_controller));
+
+ p_profile->_cb.p_sens_cb->message_counter = 0;
+ p_profile->_cb.p_sens_cb->supp_page_control = 0;
+ p_profile->_cb.p_sens_cb->supp_page_number = p_sens_config->supplementary_page_number;
+ p_profile->_cb.p_sens_cb->common_page_number = ANT_SDM_PAGE_80;
+
+ return ant_sdm_init(p_profile, p_channel_config);
+}
+
+ret_code_t ant_sdm_page_request(ant_sdm_profile_t * p_profile, ant_common_page70_data_t * p_page_70)
+{
+ ASSERT(p_profile != NULL);
+ ASSERT(p_page_70 != NULL);
+
+ uint32_t err_code = ant_request_controller_request(&(p_profile->_cb.p_disp_cb->req_controller),
+ p_profile->channel_number, p_page_70);
+ NRF_LOG_INFO("");
+
+ return err_code;
+}
+
+/**@brief Function for getting next page number to send.
+ *
+ * @param[in] p_profile Pointer to the profile instance.
+ *
+ * @return Next page number.
+ */
+static ant_sdm_page_t next_page_number_get(ant_sdm_profile_t * p_profile)
+{
+ ant_sdm_sens_cb_t * p_sdm_cb = p_profile->_cb.p_sens_cb;
+ ant_sdm_page_t page_number;
+
+ if (ant_request_controller_pending_get(&(p_sdm_cb->req_controller), (uint8_t *)&page_number))
+ {
+ // No implementation needed
+ }
+ else if (p_sdm_cb->message_counter == (COMMON_DATA_INTERVAL))
+ {
+ page_number = p_sdm_cb->common_page_number;
+ p_sdm_cb->message_counter++;
+ }
+ else if (p_sdm_cb->message_counter == (COMMON_DATA_INTERVAL + 1))
+ {
+ page_number = p_sdm_cb->common_page_number;
+ p_sdm_cb->common_page_number = (p_sdm_cb->common_page_number == ANT_SDM_PAGE_80)
+ ? ANT_SDM_PAGE_81 : ANT_SDM_PAGE_80;
+ p_sdm_cb->message_counter = 0;
+ }
+ else
+ {
+ if (p_sdm_cb->supp_page_control)
+ {
+ page_number = p_sdm_cb->supp_page_number;
+ }
+ else
+ {
+ page_number = ANT_SDM_PAGE_1;
+ }
+
+ if ((p_sdm_cb->message_counter % 2) == 1)
+ {
+ p_sdm_cb->supp_page_control = !p_sdm_cb->supp_page_control;
+ }
+ p_sdm_cb->message_counter++;
+ }
+ return page_number;
+}
+
+/**@brief Function for encoding SDM message.
+ *
+ * @param[in] p_profile Pointer to the profile instance.
+ * @param[in] p_message_payload Pointer to the message payload.
+ *
+ * @note Assume to be call each time when Tx window will occur.
+ */
+static void sens_message_encode(ant_sdm_profile_t * p_profile, uint8_t * p_message_payload)
+{
+ ant_sdm_message_layout_t * p_sdm_message_payload =
+ (ant_sdm_message_layout_t *)p_message_payload;
+
+ p_sdm_message_payload->page_number = next_page_number_get(p_profile);
+
+ NRF_LOG_INFO("SDM Page number: %u", p_sdm_message_payload->page_number);
+
+ switch (p_sdm_message_payload->page_number)
+ {
+ case ANT_SDM_PAGE_1:
+ ant_sdm_page_1_encode(p_sdm_message_payload->page_payload, &(p_profile->page_1),
+ &(p_profile->common));
+ ant_sdm_speed_encode(p_sdm_message_payload->page_payload, &(p_profile->common));
+ break;
+
+ case ANT_SDM_PAGE_2:
+ ant_sdm_page_2_encode(p_sdm_message_payload->page_payload, &(p_profile->page_2));
+ ant_sdm_speed_encode(p_sdm_message_payload->page_payload, &(p_profile->common));
+ break;
+
+ case ANT_SDM_PAGE_3:
+ ant_sdm_page_2_encode(p_sdm_message_payload->page_payload, &(p_profile->page_2));
+ ant_sdm_page_3_encode(p_sdm_message_payload->page_payload, &(p_profile->page_3));
+ ant_sdm_speed_encode(p_sdm_message_payload->page_payload, &(p_profile->common));
+ break;
+
+ case ANT_SDM_PAGE_16:
+ ant_sdm_page_16_encode(p_sdm_message_payload->page_payload, &(p_profile->common));
+ break;
+
+ case ANT_SDM_PAGE_22:
+ ant_sdm_page_22_encode(p_sdm_message_payload->page_payload, &(p_profile->page_22));
+ break;
+
+ case ANT_SDM_PAGE_80:
+ ant_common_page_80_encode(p_sdm_message_payload->page_payload, &(p_profile->page_80));
+ break;
+
+ case ANT_SDM_PAGE_81:
+ ant_common_page_81_encode(p_sdm_message_payload->page_payload, &(p_profile->page_81));
+ break;
+
+ default:
+ return;
+ }
+
+ p_profile->evt_handler(p_profile, (ant_sdm_evt_t)p_sdm_message_payload->page_number);
+}
+
+void ant_sdm_sens_evt_handler(ant_evt_t * p_ant_evt, void * p_context)
+{
+ ASSERT(p_context != NULL);
+ ASSERT(p_ant_evt != NULL);
+ ant_sdm_profile_t * p_profile = (ant_sdm_profile_t *)p_context;
+
+ if (p_ant_evt->channel == p_profile->channel_number)
+ {
+ uint32_t err_code;
+ uint8_t p_message_payload[ANT_STANDARD_DATA_PAYLOAD_SIZE];
+ ant_sdm_sens_cb_t * p_sdm_cb = p_profile->_cb.p_sens_cb;
+ ant_request_controller_sens_evt_handler(&(p_sdm_cb->req_controller), p_ant_evt);
+
+ switch (p_ant_evt->event)
+ {
+ case EVENT_TX:
+ case EVENT_TRANSFER_TX_FAILED:
+ case EVENT_TRANSFER_TX_COMPLETED:
+ sens_message_encode(p_profile, p_message_payload);
+ if (ant_request_controller_ack_needed(&(p_sdm_cb->req_controller)))
+ {
+ err_code = sd_ant_acknowledge_message_tx(p_profile->channel_number,
+ sizeof(p_message_payload),
+ p_message_payload);
+ }
+ else
+ {
+ err_code = sd_ant_broadcast_message_tx(p_profile->channel_number,
+ sizeof(p_message_payload),
+ p_message_payload);
+ }
+ APP_ERROR_CHECK(err_code);
+ break;
+ default:
+ break;
+ }
+ }
+}
+
+ret_code_t ant_sdm_disp_open(ant_sdm_profile_t * p_profile)
+{
+ ASSERT(p_profile != NULL);
+
+ NRF_LOG_INFO("ANT SDM channel %u open", p_profile->channel_number);
+ return sd_ant_channel_open(p_profile->channel_number);
+}
+
+ret_code_t ant_sdm_sens_open(ant_sdm_profile_t * p_profile)
+{
+ ASSERT(p_profile != NULL);
+
+ // Fill tx buffer for the first frame
+ uint32_t err_code;
+ uint8_t p_message_payload[ANT_STANDARD_DATA_PAYLOAD_SIZE];
+
+ sens_message_encode(p_profile, p_message_payload);
+ err_code =
+ sd_ant_broadcast_message_tx(p_profile->channel_number,
+ sizeof(p_message_payload),
+ p_message_payload);
+ APP_ERROR_CHECK(err_code);
+
+ NRF_LOG_INFO("ANT SDM channel %u open", p_profile->channel_number);
+ return sd_ant_channel_open(p_profile->channel_number);
+}
+
+
+/**@brief Function for decoding SDM message.
+ *
+ * @note Assume to be call each time when Rx window will occur.
+ */
+static void disp_message_decode(ant_sdm_profile_t * p_profile, uint8_t * p_message_payload)
+{
+ const ant_sdm_message_layout_t * p_sdm_message_payload =
+ (ant_sdm_message_layout_t *)p_message_payload;
+
+ NRF_LOG_INFO("SDM Page number: %u", p_sdm_message_payload->page_number);
+
+ switch (p_sdm_message_payload->page_number)
+ {
+ case ANT_SDM_PAGE_1:
+ ant_sdm_page_1_decode(p_sdm_message_payload->page_payload,
+ &(p_profile->page_1),
+ &(p_profile->common));
+ ant_sdm_speed_decode(p_sdm_message_payload->page_payload, &(p_profile->common));
+ break;
+
+ case ANT_SDM_PAGE_3:
+ ant_sdm_page_3_decode(p_sdm_message_payload->page_payload, &(p_profile->page_3));
+ /* fall through */
+ case ANT_SDM_PAGE_2:
+ ant_sdm_page_2_decode(p_sdm_message_payload->page_payload, &(p_profile->page_2));
+ ant_sdm_speed_decode(p_sdm_message_payload->page_payload, &(p_profile->common));
+ break;
+
+ case ANT_SDM_PAGE_16:
+ ant_sdm_page_16_decode(p_sdm_message_payload->page_payload, &(p_profile->common));
+ break;
+
+ case ANT_SDM_PAGE_22:
+ ant_sdm_page_22_decode(p_sdm_message_payload->page_payload, &(p_profile->page_22));
+ break;
+
+ case ANT_SDM_PAGE_80:
+ ant_common_page_80_decode(p_sdm_message_payload->page_payload, &(p_profile->page_80));
+ break;
+
+ case ANT_SDM_PAGE_81:
+ ant_common_page_81_decode(p_sdm_message_payload->page_payload, &(p_profile->page_81));
+ break;
+
+ default:
+ return;
+ }
+
+ p_profile->evt_handler(p_profile, (ant_sdm_evt_t)p_sdm_message_payload->page_number);
+}
+
+void ant_sdm_disp_evt_handler(ant_evt_t * p_ant_evt, void * p_context)
+{
+ ASSERT(p_context != NULL);
+ ASSERT(p_ant_evt != NULL);
+ ant_sdm_profile_t * p_profile = ( ant_sdm_profile_t *)p_context;
+
+ if (p_ant_evt->channel == p_profile->channel_number)
+ {
+ ant_sdm_disp_cb_t * p_sdm_cb = p_profile->_cb.p_disp_cb;
+
+ switch (ant_request_controller_disp_evt_handler(&(p_sdm_cb->req_controller), p_ant_evt))
+ {
+ case ANT_REQUEST_CONTROLLER_SUCCESS:
+ p_profile->evt_handler(p_profile, ANT_SDM_PAGE_REQUEST_SUCCESS);
+ break;
+ case ANT_REQUEST_CONTROLLER_FAILED:
+ p_profile->evt_handler(p_profile, ANT_SDM_PAGE_REQUEST_FAILED);
+ break;
+ default:
+ break;
+ }
+
+ switch (p_ant_evt->event)
+ {
+ case EVENT_RX:
+ if (p_ant_evt->message.ANT_MESSAGE_ucMesgID == MESG_BROADCAST_DATA_ID
+ || p_ant_evt->message.ANT_MESSAGE_ucMesgID == MESG_ACKNOWLEDGED_DATA_ID
+ || p_ant_evt->message.ANT_MESSAGE_ucMesgID == MESG_BURST_DATA_ID)
+ {
+ disp_message_decode(p_profile, p_ant_evt->message.ANT_MESSAGE_aucPayload);
+ }
+ break;
+ default:
+ break;
+ }
+ }
+}
+
+#endif // NRF_MODULE_ENABLED(ANT_SDM)
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ant/ant_profiles/ant_sdm/ant_sdm.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ant/ant_profiles/ant_sdm/ant_sdm.h
new file mode 100644
index 0000000..c71591c
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ant/ant_profiles/ant_sdm/ant_sdm.h
@@ -0,0 +1,331 @@
+/**
+ * Copyright (c) 2015 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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
+ *
+ * @defgroup ant_sdm Stride Based Speed and Distance Monitor profile
+ * @{
+ * @ingroup ant_sdk_profiles
+ * @brief This module implements the Stride Based Speed and Distance Monitor profile.
+ *
+ */
+
+#ifndef ANT_SDM_H__
+#define ANT_SDM_H__
+
+#include <stdint.h>
+#include <stdbool.h>
+#include "ant_parameters.h"
+#include "nrf_sdh_ant.h"
+#include "ant_channel_config.h"
+#include "ant_request_controller.h"
+#include "ant_sdm_pages.h"
+#include "sdk_errors.h"
+
+#define SDM_DEVICE_TYPE 0x7Cu ///< Device type reserved for ANT+ SDM.
+#define SDM_ANTPLUS_RF_FREQ 0x39u ///< Frequency, decimal 57 (2457 MHz).
+
+#define SDM_MSG_PERIOD_4Hz 0x1FC6u ///< Message period, decimal 8134 (4.03 Hz).
+#define SDM_MSG_PERIOD_2Hz 0x3F8Cu ///< Message period, decimal 16268 (2.01 Hz).
+
+#define SDM_EXT_ASSIGN 0x00 ///< ANT ext assign (see Ext. Assign Channel Parameters in ant_parameters.h: @ref ant_parameters).
+#define SDM_DISP_CHANNEL_TYPE CHANNEL_TYPE_SLAVE ///< RX SDM channel type.
+#define SDM_SENS_CHANNEL_TYPE CHANNEL_TYPE_MASTER ///< TX SDM channel type.
+
+/**@brief Initialize an ANT channel configuration structure for the SDM profile (Display).
+ *
+ * @param[in] NAME Name of related instance.
+ * @param[in] CHANNEL_NUMBER Number of the channel assigned to the profile instance.
+ * @param[in] TRANSMISSION_TYPE Type of transmission assigned to the profile instance.
+ * @param[in] DEVICE_NUMBER Number of the device assigned to the profile instance.
+ * @param[in] NETWORK_NUMBER Number of the network assigned to the profile instance.
+ * @param[in] SDM_MSG_PERIOD Channel period in 32 kHz counts. The SDM profile supports only the following periods:
+ * @ref SDM_MSG_PERIOD_4Hz, @ref SDM_MSG_PERIOD_2Hz.
+ */
+#define SDM_DISP_CHANNEL_CONFIG_DEF(NAME, \
+ CHANNEL_NUMBER, \
+ TRANSMISSION_TYPE, \
+ DEVICE_NUMBER, \
+ NETWORK_NUMBER, \
+ SDM_MSG_PERIOD) \
+static const ant_channel_config_t CONCAT_2(NAME,_channel_sdm_disp_config) = \
+ { \
+ .channel_number = (CHANNEL_NUMBER), \
+ .channel_type = SDM_DISP_CHANNEL_TYPE, \
+ .ext_assign = SDM_EXT_ASSIGN, \
+ .rf_freq = SDM_ANTPLUS_RF_FREQ, \
+ .transmission_type = (TRANSMISSION_TYPE), \
+ .device_type = SDM_DEVICE_TYPE, \
+ .device_number = (DEVICE_NUMBER), \
+ .channel_period = (SDM_MSG_PERIOD), \
+ .network_number = (NETWORK_NUMBER), \
+ }
+#define SDM_DISP_CHANNEL_CONFIG(NAME) &CONCAT_2(NAME,_channel_sdm_disp_config)
+
+/**@brief Initialize an ANT channel configuration structure for the SDM profile (Sensor).
+ *
+ * @param[in] NAME Name of related instance.
+ * @param[in] CHANNEL_NUMBER Number of the channel assigned to the profile instance.
+ * @param[in] TRANSMISSION_TYPE Type of transmission assigned to the profile instance.
+ * @param[in] DEVICE_NUMBER Number of the device assigned to the profile instance.
+ * @param[in] NETWORK_NUMBER Number of the network assigned to the profile instance.
+ */
+#define SDM_SENS_CHANNEL_CONFIG_DEF(NAME, \
+ CHANNEL_NUMBER, \
+ TRANSMISSION_TYPE, \
+ DEVICE_NUMBER, \
+ NETWORK_NUMBER) \
+static const ant_channel_config_t CONCAT_2(NAME,_channel_sdm_sens_config) = \
+ { \
+ .channel_number = (CHANNEL_NUMBER), \
+ .channel_type = SDM_SENS_CHANNEL_TYPE, \
+ .ext_assign = SDM_EXT_ASSIGN, \
+ .rf_freq = SDM_ANTPLUS_RF_FREQ, \
+ .transmission_type = (TRANSMISSION_TYPE), \
+ .device_type = SDM_DEVICE_TYPE, \
+ .device_number = (DEVICE_NUMBER), \
+ .channel_period = SDM_MSG_PERIOD_4Hz, \
+ .network_number = (NETWORK_NUMBER), \
+ }
+#define SDM_SENS_CHANNEL_CONFIG(NAME) &CONCAT_2(NAME,_channel_sdm_sens_config)
+
+/**@brief Initialize an ANT profile configuration structure for the SDM profile (Display).
+ *
+ * @param[in] NAME Name of related instance.
+ * @param[in] EVT_HANDLER Event handler to be called for handling events in the SDM profile.
+ */
+#define SDM_DISP_PROFILE_CONFIG_DEF(NAME, \
+ EVT_HANDLER) \
+static ant_sdm_disp_cb_t CONCAT_2(NAME,_sdm_disp_cb); \
+static const ant_sdm_disp_config_t CONCAT_2(NAME,_profile_sdm_disp_config) = \
+ { \
+ .p_cb = &CONCAT_2(NAME,_sdm_disp_cb), \
+ .evt_handler = (EVT_HANDLER), \
+ }
+#define SDM_DISP_PROFILE_CONFIG(NAME) &CONCAT_2(NAME,_profile_sdm_disp_config)
+
+
+/**@brief Initialize an ANT profile configuration structure for the SDM profile (Sensor).
+ *
+ * @param[in] NAME Name of related instance.
+ * @param[in] SUPPLEMENTARY_PAGE_NUMBER Supplementary data page (ANT_SDM_PAGE_2 or ANT_SDM_PAGE_3). Use ANT_SDM_PAGE_1 to disable.
+ * @param[in] EVT_HANDLER Event handler to be called for handling events in the SDM profile.
+ */
+#define SDM_SENS_PROFILE_CONFIG_DEF(NAME, \
+ SUPPLEMENTARY_PAGE_NUMBER, \
+ EVT_HANDLER) \
+static ant_sdm_sens_cb_t CONCAT_2(NAME,_sdm_sens_cb); \
+static const ant_sdm_sens_config_t CONCAT_2(NAME,_profile_sdm_sens_config) = \
+ { \
+ .supplementary_page_number = (SUPPLEMENTARY_PAGE_NUMBER), \
+ .p_cb = &CONCAT_2(NAME,_sdm_sens_cb), \
+ .evt_handler = (EVT_HANDLER), \
+ }
+#define SDM_SENS_PROFILE_CONFIG(NAME) &CONCAT_2(NAME,_profile_sdm_sens_config)
+
+
+/**@brief SDM page number type. */
+typedef enum{
+ ANT_SDM_PAGE_1 = 1, ///< Required data page 1.
+ ANT_SDM_PAGE_2 = 2, ///< Supplementary data page 2.
+ ANT_SDM_PAGE_3 = 3, ///< Supplementary data page 3.
+ ANT_SDM_PAGE_16 = 16, ///< Page 16 (sent on request).
+ ANT_SDM_PAGE_22 = 22, ///< Page 22 (sent on request).
+ ANT_SDM_PAGE_70 = ANT_COMMON_PAGE_70,
+ ANT_SDM_PAGE_80 = ANT_COMMON_PAGE_80,
+ ANT_SDM_PAGE_81 = ANT_COMMON_PAGE_81,
+} ant_sdm_page_t;
+
+/**@brief SDM profile event type. */
+typedef enum{
+ ANT_SDM_PAGE_1_UPDATED = ANT_SDM_PAGE_1, ///< Data page 1 and speed have been updated (Display) or sent (Sensor).
+ ANT_SDM_PAGE_2_UPDATED = ANT_SDM_PAGE_2, ///< Data page 2 and speed have been updated (Display) or sent (Sensor).
+ ANT_SDM_PAGE_3_UPDATED = ANT_SDM_PAGE_3, ///< Data page 3 and speed have been updated (Display) or sent (Sensor).
+ ANT_SDM_PAGE_16_UPDATED = ANT_SDM_PAGE_16, ///< Data page 16 has been updated (Display) or sent (Sensor).
+ ANT_SDM_PAGE_22_UPDATED = ANT_SDM_PAGE_22, ///< Data page 22 has been updated (Display) or sent (Sensor).
+ ANT_SDM_PAGE_80_UPDATED = ANT_SDM_PAGE_80, ///< Data page 80 has been updated (Display) or sent (Sensor).
+ ANT_SDM_PAGE_81_UPDATED = ANT_SDM_PAGE_81, ///< Data page 81 has been updated (Display) or sent (Sensor).
+ ANT_SDM_PAGE_REQUEST_SUCCESS, ///< Data page request reached the destination.
+ ANT_SDM_PAGE_REQUEST_FAILED, ///< Data page request did not reach the destination.
+} ant_sdm_evt_t;
+
+// Forward declaration of the ant_sdm_profile_t type.
+typedef struct ant_sdm_profile_s ant_sdm_profile_t;
+
+/**@brief SDM event handler type. */
+typedef void (* ant_sdm_evt_handler_t) (ant_sdm_profile_t *, ant_sdm_evt_t);
+
+#include "ant_sdm_local.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**@brief SDM Sensor configuration structure. */
+typedef struct
+{
+ ant_sdm_page_t supplementary_page_number; ///< Supplementary data page (ANT_SDM_PAGE_2 or ANT_SDM_PAGE_3). Use ANT_SDM_PAGE_1 to disable.
+ ant_sdm_sens_cb_t * p_cb; ///< Pointer to the data buffer for internal use.
+ ant_sdm_evt_handler_t evt_handler; ///< Event handler to be called for handling events in the SDM profile.
+} ant_sdm_sens_config_t;
+
+/**@brief SDM Display configuration structure. */
+typedef struct
+{
+ ant_sdm_disp_cb_t * p_cb; ///< Pointer to the data buffer for internal use.
+ ant_sdm_evt_handler_t evt_handler; ///< Event handler to be called for handling events in the SDM profile.
+} ant_sdm_disp_config_t;
+
+/**@brief SDM profile structure. */
+struct ant_sdm_profile_s
+{
+ uint8_t channel_number; ///< Channel number assigned to the profile.
+ union {
+ ant_sdm_disp_cb_t * p_disp_cb;
+ ant_sdm_sens_cb_t * p_sens_cb;
+ } _cb; ///< Pointer to internal control block.
+ ant_sdm_evt_handler_t evt_handler; ///< Event handler to be called for handling events in the SDM profile.
+ ant_sdm_page1_data_t page_1; ///< Page 1.
+ ant_sdm_page2_data_t page_2; ///< Page 2.
+ ant_sdm_page3_data_t page_3; ///< Page 3.
+ ant_sdm_page22_data_t page_22; ///< Page 22.
+ ant_common_page80_data_t page_80; ///< Page 80.
+ ant_common_page81_data_t page_81; ///< Page 81.
+ ant_sdm_common_data_t common; ///< SDM common data.
+};
+
+/** @name Defines for accessing ant_sdm_profile_t members variables
+@{ */
+#define SDM_PROFILE_update_latency page_1.update_latency
+#define SDM_PROFILE_time page_1.time
+#define SDM_PROFILE_status page_2.status.items
+#define SDM_PROFILE_cadence page_2.cadence
+#define SDM_PROFILE_calories page_3.calories
+#define SDM_PROFILE_capabilities page_22.capabilities.items
+#define SDM_PROFILE_speed common.speed
+#define SDM_PROFILE_distance common.distance
+#define SDM_PROFILE_strides common.strides
+#define SDM_PROFILE_hw_revision page_80.hw_revision
+#define SDM_PROFILE_manufacturer_id page_80.manufacturer_id
+#define SDM_PROFILE_model_number page_80.model_number
+#define SDM_PROFILE_sw_revision_minor page_81.sw_revision_minor
+#define SDM_PROFILE_sw_revision_major page_81.sw_revision_major
+#define SDM_PROFILE_serial_number page_81.serial_number
+/** @} */
+
+/**@brief Function for initializing the ANT SDM RX profile instance.
+ *
+ * @param[in] p_profile Pointer to the profile instance.
+ * @param[in] p_channel_config Pointer to the ANT channel configuration structure.
+ * @param[in] p_disp_config Pointer to the SDM Display configuration structure.
+ *
+ * @retval NRF_SUCCESS If initialization was successful. Otherwise, an error code is returned.
+ */
+ret_code_t ant_sdm_disp_init(ant_sdm_profile_t * p_profile,
+ ant_channel_config_t const * p_channel_config,
+ ant_sdm_disp_config_t const * p_disp_config);
+
+/**@brief Function for initializing the ANT SDM TX profile instance.
+ *
+ * @param[in] p_profile Pointer to the profile instance.
+ * @param[in] p_channel_config Pointer to the ANT channel configuration structure.
+ * @param[in] p_sens_config Pointer to the SDM Sensor configuration structure.
+ *
+ * @retval NRF_SUCCESS If initialization was successful. Otherwise, an error code is returned.
+ */
+ret_code_t ant_sdm_sens_init(ant_sdm_profile_t * p_profile,
+ ant_channel_config_t const * p_channel_config,
+ ant_sdm_sens_config_t const * p_sens_config);
+
+/**@brief Function for opening the profile instance channel for ANT SDM Display.
+ *
+ * Before calling this function, pages should be configured.
+ *
+ * @param[in] p_profile Pointer to the profile instance.
+ *
+ * @retval NRF_SUCCESS If the channel was successfully opened. Otherwise, an error code is returned.
+ */
+ret_code_t ant_sdm_disp_open(ant_sdm_profile_t * p_profile);
+
+/**@brief Function for opening the profile instance channel for ANT SDM Sensor.
+ *
+ * Before calling this function, pages should be configured.
+ *
+ * @param[in] p_profile Pointer to the profile instance.
+ *
+ * @retval NRF_SUCCESS If the channel was successfully opened. Otherwise, an error code is returned.
+ */
+ret_code_t ant_sdm_sens_open(ant_sdm_profile_t * p_profile);
+
+/**@brief Function for sending a data page request.
+ *
+ * This function can be called only on the display side.
+ *
+ * @param[in] p_profile Pointer to the profile instance.
+ * @param[in] p_page_70 Pointer to the prepared page 70.
+ *
+ * @retval NRF_SUCCESS If the request has been sent. Otherwise, an error code is returned.
+ */
+ret_code_t ant_sdm_page_request(ant_sdm_profile_t * p_profile, ant_common_page70_data_t * p_page_70);
+
+/**@brief Function for handling the Sensor ANT events.
+ *
+ * @details This function handles all events from the ANT stack that are of interest to the SDM Sensor profile.
+ *
+ * @param[in] p_ant_evt Event received from the ANT stack.
+ * @param[in] p_context Pointer to the profile instance.
+ */
+void ant_sdm_sens_evt_handler(ant_evt_t * p_ant_evt, void * p_context);
+
+/**@brief Function for handling the Display ANT events.
+ *
+ * @details This function handles all events from the ANT stack that are of interest to the SDM Display profile.
+ *
+ * @param[in] p_ant_evt Event received from the ANT stack.
+ * @param[in] p_context Pointer to the profile instance.
+ */
+void ant_sdm_disp_evt_handler(ant_evt_t * p_ant_evt, void * p_context);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // ANT_SDM_H__
+/** @} */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ant/ant_profiles/ant_sdm/ant_sdm_local.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ant/ant_profiles/ant_sdm/ant_sdm_local.h
new file mode 100644
index 0000000..910aa5d
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ant/ant_profiles/ant_sdm/ant_sdm_local.h
@@ -0,0 +1,81 @@
+/**
+ * Copyright (c) 2015 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#ifndef ANT_SDM_LOCAL_H__
+#define ANT_SDM_LOCAL_H__
+
+#include <stdint.h>
+#include <stdbool.h>
+#include "ant_sdm.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @addtogroup ant_sdm
+ * @{
+ */
+
+/** @brief SDM Display control block. */
+typedef struct
+{
+ ant_request_controller_t req_controller;
+}ant_sdm_disp_cb_t;
+
+/**@brief SDM Sensor control block. */
+typedef struct
+{
+ uint8_t supp_page_control;
+ ant_sdm_page_t supp_page_number;
+ ant_sdm_page_t common_page_number;
+ uint8_t message_counter;
+ ant_request_controller_t req_controller;
+}ant_sdm_sens_cb_t;
+
+/**
+ * @}
+ */
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // ANT_SDM_LOCAL_H__
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ant/ant_profiles/ant_sdm/pages/ant_sdm_common_data.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ant/ant_profiles/ant_sdm/pages/ant_sdm_common_data.c
new file mode 100644
index 0000000..8378d31
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ant/ant_profiles/ant_sdm/pages/ant_sdm_common_data.c
@@ -0,0 +1,104 @@
+/**
+ * Copyright (c) 2015 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#include "sdk_common.h"
+#if NRF_MODULE_ENABLED(ANT_SDM)
+
+#include "ant_sdm_common_data.h"
+#include "ant_sdm_utils.h"
+
+#define NRF_LOG_MODULE_NAME ant_sdm
+#if ANT_SDM_LOG_ENABLED
+#define NRF_LOG_LEVEL ANT_SDM_LOG_LEVEL
+#define NRF_LOG_INFO_COLOR ANT_SDM_INFO_COLOR
+#else // ANT_SDM_LOG_ENABLED
+#define NRF_LOG_LEVEL 0
+#endif // ANT_SDM_LOG_ENABLED
+#include "nrf_log.h"
+
+/**@brief SDM common page data layout structure. */
+typedef struct
+{
+ uint8_t reserved0[3];
+ uint8_t speed_integer :4;
+ uint8_t reserved1 :4;
+ uint8_t speed_fractional;
+ uint8_t reserved2[2];
+}ant_sdm_speed_data_layout_t;
+
+/**@brief Function for tracing common data.
+ *
+ * @param[in] p_common_data Pointer to the common data.
+ */
+static void speed_data_log(ant_sdm_common_data_t const * p_common_data)
+{
+ uint32_t speed = ANT_SDM_SPEED_RESCALE(p_common_data->speed);
+ UNUSED_VARIABLE(speed);
+
+ NRF_LOG_INFO("Speed %u.%02u m/s\r\n\n",
+ (unsigned int)(speed / ANT_SDM_SPEED_DISP_PRECISION),
+ (unsigned int)(speed % ANT_SDM_SPEED_DISP_PRECISION));
+}
+
+void ant_sdm_speed_encode(uint8_t * p_page_buffer,
+ ant_sdm_common_data_t const * p_common_data)
+{
+ ant_sdm_speed_data_layout_t * p_outcoming_data = (ant_sdm_speed_data_layout_t *)p_page_buffer;
+ uint16_t speed = p_common_data->speed;
+
+ p_outcoming_data->speed_integer = speed / ANT_SDM_SPEED_UNIT_REVERSAL;
+ p_outcoming_data->speed_fractional = speed % ANT_SDM_SPEED_UNIT_REVERSAL;
+
+ speed_data_log(p_common_data);
+}
+
+void ant_sdm_speed_decode(uint8_t const * p_page_buffer,
+ ant_sdm_common_data_t * p_common_data)
+{
+ ant_sdm_speed_data_layout_t const * p_incoming_data = (ant_sdm_speed_data_layout_t *)p_page_buffer;
+ uint16_t speed = (p_incoming_data->speed_integer
+ * ANT_SDM_SPEED_UNIT_REVERSAL)
+ + p_incoming_data->speed_fractional;
+
+ p_common_data->speed = speed;
+
+ speed_data_log(p_common_data);
+}
+
+#endif // NRF_MODULE_ENABLED(ANT_SDM)
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ant/ant_profiles/ant_sdm/pages/ant_sdm_common_data.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ant/ant_profiles/ant_sdm/pages/ant_sdm_common_data.h
new file mode 100644
index 0000000..d22c491
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ant/ant_profiles/ant_sdm/pages/ant_sdm_common_data.h
@@ -0,0 +1,103 @@
+/**
+ * Copyright (c) 2015 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#ifndef ANT_SDM_COMMON_DATA_H__
+#define ANT_SDM_COMMON_DATA_H__
+
+/** @file
+ *
+ * @defgroup ant_sdk_profiles_sdm_common_data_page Stride Based Speed and Distance Monitor profile common data
+ * @{
+ * @ingroup ant_sdk_profiles_sdm_pages
+ */
+
+#include <stdint.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**@brief Data structure for SDM common data.
+ *
+ * @details This structure stores data that is not associated with a particular page.
+ */
+typedef struct
+{
+ uint16_t speed; ///< Actual speed.
+ uint32_t distance; ///< Accumulated distance.
+ uint32_t strides; ///< Accumulated strides.
+} ant_sdm_common_data_t;
+
+/**@brief Initialize common data.
+ */
+#define DEFAULT_ANT_SDM_COMMON_DATA() \
+ (ant_sdm_common_data_t) \
+ { \
+ .speed = 0, \
+ .distance = 0, \
+ .strides = 0, \
+ }
+
+/**@brief Function for encoding speed.
+ *
+ * This function can be used for pages 2 and 3.
+ *
+ * @param[in] p_common_data Pointer to the common data.
+ * @param[out] p_page_buffer Pointer to the data buffer.
+ */
+void ant_sdm_speed_encode(uint8_t * p_page_buffer,
+ ant_sdm_common_data_t const * p_common_data);
+
+/**@brief Function for decoding speed.
+ *
+ * This function can be used for pages 2 and 3.
+ *
+ * @param[in] p_page_buffer Pointer to the data buffer.
+ * @param[out] p_common_data Pointer to the common data.
+ */
+void ant_sdm_speed_decode(uint8_t const * p_page_buffer,
+ ant_sdm_common_data_t * p_common_data);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // ANT_SDM_COMMON_DATA_H__
+/** @} */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ant/ant_profiles/ant_sdm/pages/ant_sdm_page_1.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ant/ant_profiles/ant_sdm/pages/ant_sdm_page_1.c
new file mode 100644
index 0000000..b2e4eed
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ant/ant_profiles/ant_sdm/pages/ant_sdm_page_1.c
@@ -0,0 +1,144 @@
+/**
+ * Copyright (c) 2015 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#include "sdk_common.h"
+#if NRF_MODULE_ENABLED(ANT_SDM)
+
+#include "ant_sdm_page_1.h"
+#include "ant_sdm_utils.h"
+
+#define NRF_LOG_MODULE_NAME ant_sdm
+#if ANT_SDM_LOG_ENABLED
+#define NRF_LOG_LEVEL ANT_SDM_LOG_LEVEL
+#define NRF_LOG_INFO_COLOR ANT_SDM_INFO_COLOR
+#else // ANT_SDM_LOG_ENABLED
+#define NRF_LOG_LEVEL 0
+#endif // ANT_SDM_LOG_ENABLED
+#include "nrf_log.h"
+
+/**@brief SDM page 1 data layout structure. */
+typedef struct
+{
+ uint8_t time_fractional;
+ uint8_t time_integer;
+ uint8_t distance_integer;
+ uint8_t reserved0 : 4;
+ uint8_t distance_fractional : 4;
+ uint8_t reserved1;
+ uint8_t strides;
+ uint8_t update_latency;
+}ant_sdm_page1_data_layout_t;
+
+STATIC_ASSERT(ANT_SDM_UPDATE_LATENCY_DISP_PRECISION == 1000); ///< Display format need to be updated
+STATIC_ASSERT(ANT_SDM_TIME_DISP_PRECISION == 1000); ///< Display format need to be updated
+STATIC_ASSERT(ANT_SDM_DISTANCE_DISP_PRECISION == 10); ///< Display format need to be updated
+
+/**@brief Function for tracing page 1 and common data.
+ *
+ * @param[in] p_common_data Pointer to the common data.
+ * @param[in] p_page_data Pointer to the page 1 data.
+ */
+static void page_1_data_log(ant_sdm_page1_data_t const * p_page_data,
+ ant_sdm_common_data_t const * p_common_data)
+{
+ uint32_t strides = p_common_data->strides;
+ uint64_t distance = ANT_SDM_DISTANCE_RESCALE(p_common_data->distance);
+ uint16_t update_latency = ANT_SDM_UPDATE_LATENCY_RESCALE(p_page_data->update_latency);
+ uint32_t time = ANT_SDM_TIME_RESCALE(p_page_data->time);
+
+ NRF_LOG_INFO("Update latency %u.%03u s",
+ update_latency / ANT_SDM_UPDATE_LATENCY_DISP_PRECISION,
+ update_latency % ANT_SDM_UPDATE_LATENCY_DISP_PRECISION);
+ NRF_LOG_INFO("Time %u.%03u s",
+ (unsigned int)(time / ANT_SDM_TIME_DISP_PRECISION),
+ (unsigned int)(time % ANT_SDM_TIME_DISP_PRECISION));
+ NRF_LOG_INFO("Distance %u.%01um ",
+ (unsigned int)(distance / ANT_SDM_DISTANCE_DISP_PRECISION),
+ (unsigned int)(distance % ANT_SDM_DISTANCE_DISP_PRECISION));
+ NRF_LOG_INFO("Strides %u", (unsigned int)strides);
+}
+
+
+void ant_sdm_page_1_encode(uint8_t * p_page_buffer,
+ ant_sdm_page1_data_t const * p_page_data,
+ ant_sdm_common_data_t const * p_common_data)
+{
+ ant_sdm_page1_data_layout_t * p_outcoming_data = (ant_sdm_page1_data_layout_t *)p_page_buffer;
+ uint32_t distance = p_common_data->distance;
+ uint16_t time = p_page_data->time;
+
+ p_outcoming_data->time_fractional = time % ANT_SDM_TIME_UNIT_REVERSAL;
+ p_outcoming_data->time_integer = time / ANT_SDM_TIME_UNIT_REVERSAL;
+ p_outcoming_data->distance_integer =
+ (UINT8_MAX & (distance / ANT_SDM_DISTANCE_UNIT_REVERSAL)); // Only LSB
+ p_outcoming_data->distance_fractional = distance % ANT_SDM_DISTANCE_UNIT_REVERSAL;
+ p_outcoming_data->strides = (UINT8_MAX & p_common_data->strides); // Only LSB
+ p_outcoming_data->update_latency = p_page_data->update_latency;
+
+ page_1_data_log(p_page_data, p_common_data);
+}
+
+
+void ant_sdm_page_1_decode(uint8_t const * p_page_buffer,
+ ant_sdm_page1_data_t * p_page_data,
+ ant_sdm_common_data_t * p_common_data)
+{
+ ant_sdm_page1_data_layout_t const * p_incoming_data =
+ (ant_sdm_page1_data_layout_t *)p_page_buffer;
+
+ uint16_t distance = p_incoming_data->distance_integer * ANT_SDM_DISTANCE_UNIT_REVERSAL
+ + p_incoming_data->distance_fractional;
+ uint16_t time = p_incoming_data->time_integer * ANT_SDM_TIME_UNIT_REVERSAL
+ + p_incoming_data->time_fractional;
+
+ uint8_t prev_strides = p_common_data->strides;
+
+ p_common_data->strides += ((p_incoming_data->strides - prev_strides) & UINT8_MAX);
+
+ uint16_t prev_distance = p_common_data->distance;
+ p_common_data->distance += ((distance - prev_distance) & 0xFFF);
+
+ p_page_data->update_latency = p_incoming_data->update_latency;
+ p_page_data->time = time;
+ p_page_data->strides = p_incoming_data->strides;
+
+ page_1_data_log(p_page_data, p_common_data);
+}
+
+#endif // NRF_MODULE_ENABLED(ANT_SDM)
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ant/ant_profiles/ant_sdm/pages/ant_sdm_page_1.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ant/ant_profiles/ant_sdm/pages/ant_sdm_page_1.h
new file mode 100644
index 0000000..e9afca3
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ant/ant_profiles/ant_sdm/pages/ant_sdm_page_1.h
@@ -0,0 +1,101 @@
+/**
+ * Copyright (c) 2015 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#ifndef ANT_SDM_PAGE_1_H__
+#define ANT_SDM_PAGE_1_H__
+
+/** @file
+ *
+ * @defgroup ant_sdk_profiles_sdm_page1 Stride Based Speed and Distance Monitor profile page 1
+ * @{
+ * @ingroup ant_sdk_profiles_sdm_pages
+ */
+
+#include <stdint.h>
+#include "ant_sdm_common_data.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**@brief Data structure for SDM data page 1.
+ */
+typedef struct
+{
+ uint8_t update_latency; ///< Update latency.
+ uint8_t strides; ///< Strides (writing to this field has no effect).
+ uint16_t time; ///< Time.
+} ant_sdm_page1_data_t;
+
+/**@brief Initialize page 1.
+ */
+#define DEFAULT_ANT_SDM_PAGE1() \
+ (ant_sdm_page1_data_t) \
+ { \
+ .update_latency = 0, \
+ .time = 0, \
+ }
+
+/**@brief Function for encoding page 1.
+ *
+ * @param[in] p_page_data Pointer to the page data.
+ * @param[in] p_common_data Pointer to the common data.
+ * @param[out] p_page_buffer Pointer to the data buffer.
+ */
+void ant_sdm_page_1_encode(uint8_t * p_page_buffer,
+ ant_sdm_page1_data_t const * p_page_data,
+ ant_sdm_common_data_t const * p_common_data);
+
+/**@brief Function for decoding page 1.
+ *
+ * @param[in] p_page_buffer Pointer to the data buffer.
+ * @param[out] p_page_data Pointer to the page data.
+ * @param[out] p_common_data Pointer to the common data.
+ */
+void ant_sdm_page_1_decode(uint8_t const * p_page_buffer,
+ ant_sdm_page1_data_t * p_page_data,
+ ant_sdm_common_data_t * p_common_data);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // ANT_SDM_PAGE_1_H__
+/** @} */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ant/ant_profiles/ant_sdm/pages/ant_sdm_page_16.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ant/ant_profiles/ant_sdm/pages/ant_sdm_page_16.c
new file mode 100644
index 0000000..f557db6
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ant/ant_profiles/ant_sdm/pages/ant_sdm_page_16.c
@@ -0,0 +1,104 @@
+/**
+ * Copyright (c) 2015 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#include "sdk_common.h"
+#if NRF_MODULE_ENABLED(ANT_SDM)
+
+#include "ant_sdm_page_16.h"
+#include "ant_sdm_utils.h"
+
+#define NRF_LOG_MODULE_NAME ant_sdm
+#if ANT_SDM_LOG_ENABLED
+#define NRF_LOG_LEVEL ANT_SDM_LOG_LEVEL
+#define NRF_LOG_INFO_COLOR ANT_SDM_INFO_COLOR
+#else // ANT_SDM_LOG_ENABLED
+#define NRF_LOG_LEVEL 0
+#endif // ANT_SDM_LOG_ENABLED
+#include "nrf_log.h"
+
+/**@brief SDM page 16 data layout structure. */
+typedef struct
+{
+ uint8_t strides[3];
+ uint8_t distance[4];
+}ant_sdm_page16_data_layout_t;
+
+STATIC_ASSERT(ANT_SDM_DISTANCE_DISP_PRECISION == 10); ///< Display format need to be updated
+
+/**@brief Function for tracing common data.
+ *
+ * @param[in] p_common_data Pointer to the common data.
+ */
+static void page_16_data_log(ant_sdm_common_data_t const * p_common_data)
+{
+ uint64_t distance = ANT_SDM_DISTANCE_RESCALE(p_common_data->distance);
+
+ NRF_LOG_INFO("Distance %u.%01u m",
+ (unsigned int)(distance / ANT_SDM_DISTANCE_DISP_PRECISION),
+ (unsigned int)(distance % ANT_SDM_DISTANCE_DISP_PRECISION));
+ NRF_LOG_INFO("Strides %u\r\n\n",
+ (unsigned int)p_common_data->strides);
+}
+
+
+void ant_sdm_page_16_encode(uint8_t * p_page_buffer,
+ ant_sdm_common_data_t const * p_common_data)
+{
+ ant_sdm_page16_data_layout_t * p_outcoming_data = (ant_sdm_page16_data_layout_t *)p_page_buffer;
+
+ UNUSED_PARAMETER(uint24_encode(p_common_data->strides, p_outcoming_data->strides));
+ UNUSED_PARAMETER(uint32_encode(p_common_data->distance << 4, p_outcoming_data->distance));
+
+ page_16_data_log(p_common_data);
+}
+
+
+void ant_sdm_page_16_decode(uint8_t const * p_page_buffer,
+ ant_sdm_common_data_t * p_common_data)
+{
+ ant_sdm_page16_data_layout_t const * p_incoming_data =
+ (ant_sdm_page16_data_layout_t *)p_page_buffer;
+
+ p_common_data->strides = uint24_decode(p_incoming_data->strides);
+ p_common_data->distance = uint32_decode(p_incoming_data->distance) >> 4;
+
+ page_16_data_log(p_common_data);
+}
+
+#endif // NRF_MODULE_ENABLED(ANT_SDM)
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ant/ant_profiles/ant_sdm/pages/ant_sdm_page_16.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ant/ant_profiles/ant_sdm/pages/ant_sdm_page_16.h
new file mode 100644
index 0000000..7bb80ee
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ant/ant_profiles/ant_sdm/pages/ant_sdm_page_16.h
@@ -0,0 +1,79 @@
+/**
+ * Copyright (c) 2015 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#ifndef ANT_SDM_PAGE_16_H__
+#define ANT_SDM_PAGE_16_H__
+
+/** @file
+ *
+ * @defgroup ant_sdk_profiles_sdm_page16 Stride Based Speed and Distance Monitor profile page 16
+ * @{
+ * @ingroup ant_sdk_profiles_sdm_pages
+ */
+
+#include <stdint.h>
+#include "ant_sdm_common_data.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**@brief Function for encoding page 16.
+ *
+ * @param[in] p_common_data Pointer to the page data.
+ * @param[out] p_page_buffer Pointer to the data buffer.
+ */
+void ant_sdm_page_16_encode(uint8_t * p_page_buffer,
+ ant_sdm_common_data_t const * p_common_data);
+
+/**@brief Function for decoding page 16.
+ *
+ * @param[in] p_page_buffer Pointer to the data buffer.
+ * @param[out] p_common_data Pointer to the page data.
+ */
+void ant_sdm_page_16_decode(uint8_t const * p_page_buffer,
+ ant_sdm_common_data_t * p_common_data);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // ANT_SDM_PAGE_16_H__
+/** @} */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ant/ant_profiles/ant_sdm/pages/ant_sdm_page_2.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ant/ant_profiles/ant_sdm/pages/ant_sdm_page_2.c
new file mode 100644
index 0000000..5302827
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ant/ant_profiles/ant_sdm/pages/ant_sdm_page_2.c
@@ -0,0 +1,128 @@
+/**
+ * Copyright (c) 2015 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#include "sdk_common.h"
+#if NRF_MODULE_ENABLED(ANT_SDM)
+
+#include "ant_sdm_page_2.h"
+#include "ant_sdm_utils.h"
+
+#define NRF_LOG_MODULE_NAME ant_sdm
+#if ANT_SDM_LOG_ENABLED
+#define NRF_LOG_LEVEL ANT_SDM_LOG_LEVEL
+#define NRF_LOG_INFO_COLOR ANT_SDM_INFO_COLOR
+#else // ANT_SDM_LOG_ENABLED
+#define NRF_LOG_LEVEL 0
+#endif // ANT_SDM_LOG_ENABLED
+#include "nrf_log.h"
+
+/**@brief SDM page 2 data layout structure. */
+typedef struct
+{
+ uint8_t reserved0[2];
+ uint8_t cadence_integer;
+ uint8_t reserved1 : 4;
+ uint8_t cadence_fractional : 4;
+ uint8_t reserved2;
+ uint8_t reserved3;
+ uint8_t status;
+}ant_sdm_page2_data_layout_t;
+
+/**@brief Function for page 2 data.
+ *
+ * @param[in] p_common_data Pointer to the page 2 data.
+ */
+static void page_2_data_log(ant_sdm_page2_data_t const * p_page_data)
+{
+ static const char * p_location[4] = {"Laces", "Midsole", "Other", "Ankle"};
+ static const char * p_battery[4] = {"New", "Good", "OK", "Low"};
+ static const char * p_health[4] = {"OK", "Error", "Warning", ""};
+ static const char * p_state[4] = {"Inactive", "Active", "", ""};
+
+ uint16_t cadence = ANT_SDM_CADENCE_RESCALE(p_page_data->cadence);
+
+ NRF_LOG_INFO("Status:");
+ NRF_LOG_INFO("state: %s",
+ (uint32_t)p_state[p_page_data->status.items.state]);
+ NRF_LOG_INFO("health: %s",
+ (uint32_t)p_health[p_page_data->status.items.health]);
+ NRF_LOG_INFO("battery: %s",
+ (uint32_t)p_battery[p_page_data->status.items.battery]);
+ NRF_LOG_INFO("location: %s",
+ (uint32_t)p_location[p_page_data->status.items.location]);
+ NRF_LOG_INFO("Cadence %u.%01u strides/min",
+ cadence / ANT_SDM_CADENCE_DISP_PRECISION,
+ cadence % ANT_SDM_CADENCE_DISP_PRECISION);
+}
+
+
+void ant_sdm_page_2_encode(uint8_t * p_page_buffer,
+ ant_sdm_page2_data_t const * p_page_data)
+{
+ ant_sdm_page2_data_layout_t * p_outcoming_data = (ant_sdm_page2_data_layout_t *)p_page_buffer;
+ uint8_t status = p_page_data->status.byte;
+ uint16_t cadence = p_page_data->cadence;
+
+ p_outcoming_data->reserved0[0] = UINT8_MAX;
+ p_outcoming_data->reserved0[1] = UINT8_MAX;
+ p_outcoming_data->cadence_integer = cadence / ANT_SDM_CADENCE_UNIT_REVERSAL;
+ p_outcoming_data->cadence_fractional = cadence % ANT_SDM_CADENCE_UNIT_REVERSAL;
+ p_outcoming_data->reserved3 = UINT8_MAX;
+ p_outcoming_data->status = status;
+ page_2_data_log(p_page_data);
+}
+
+
+void ant_sdm_page_2_decode(uint8_t const * p_page_buffer,
+ ant_sdm_page2_data_t * p_page_data)
+{
+ ant_sdm_page2_data_layout_t const * p_incoming_data =
+ (ant_sdm_page2_data_layout_t *)p_page_buffer;
+
+ uint8_t status = p_incoming_data->status;
+ uint16_t cadence = p_incoming_data->cadence_integer * ANT_SDM_CADENCE_UNIT_REVERSAL
+ + p_incoming_data->cadence_fractional;
+
+ p_page_data->cadence = cadence;
+ p_page_data->status.byte = status;
+
+ page_2_data_log(p_page_data);
+}
+
+#endif // NRF_MODULE_ENABLED(ANT_SDM)
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ant/ant_profiles/ant_sdm/pages/ant_sdm_page_2.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ant/ant_profiles/ant_sdm/pages/ant_sdm_page_2.h
new file mode 100644
index 0000000..6243be0
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ant/ant_profiles/ant_sdm/pages/ant_sdm_page_2.h
@@ -0,0 +1,129 @@
+/**
+ * Copyright (c) 2015 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#ifndef ANT_SDM_PAGE_2_H__
+#define ANT_SDM_PAGE_2_H__
+
+/** @file
+ *
+ * @defgroup ant_sdk_profiles_sdm_page2 Stride Based Speed and Distance Monitor profile page 2
+ * @{
+ * @ingroup ant_sdk_profiles_sdm_pages
+ */
+
+#include <stdint.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**@brief Data structure for SDM data page 2.
+ */
+typedef struct
+{
+ union
+ {
+ struct
+ {
+ enum
+ {
+ ANT_SDM_USE_STATE_INACTIVE = 0x00,
+ ANT_SDM_USE_STATE_ACTIVE = 0x01,
+ ANT_SDM_STATE_RESERVED0 = 0x02,
+ ANT_SDM_STATE_RESERVED1 = 0x03,
+ } state : 2; ///< Use state.
+ enum
+ {
+ ANT_SDM_HEALTH_OK = 0x00,
+ ANT_SDM_HEALTH_ERROR = 0x01,
+ ANT_SDM_HEALTH_WARNING = 0x02,
+ ANT_SDM_HEALTH_RESERVED = 0x03,
+ } health : 2; ///< SDM health.
+ enum
+ {
+ ANT_SDM_BATTERY_STATUS_NEW = 0x00,
+ ANT_SDM_BATTERY_STATUS_GOOD = 0x01,
+ ANT_SDM_BATTERY_STATUS_OK = 0x02,
+ ANT_SDM_BATTERY_STATUS_LOW = 0x03,
+ } battery : 2; ///< Battery status.
+ enum
+ {
+ ANT_SDM_LOCATION_LACES = 0x00,
+ ANT_SDM_LOCATION_MIDSOLE = 0x01,
+ ANT_SDM_LOCATION_OTHER = 0x02,
+ ANT_SDM_LOCATION_ANKLE = 0x03,
+ } location : 2; ///< Location of the SDM sensor.
+ } items;
+ uint8_t byte;
+ } status; ///< Actual status.
+ uint16_t cadence; ///< Actual cadence.
+} ant_sdm_page2_data_t;
+
+/**@brief Initialize page 2.
+ */
+#define DEFAULT_ANT_SDM_PAGE2() \
+ (ant_sdm_page2_data_t) \
+ { \
+ .status.byte = 0, \
+ .cadence = 0, \
+ }
+
+/**@brief Function for encoding page 2.
+ *
+ * @param[in] p_page_data Pointer to the page data.
+ * @param[out] p_page_buffer Pointer to the data buffer.
+ */
+void ant_sdm_page_2_encode(uint8_t * p_page_buffer,
+ ant_sdm_page2_data_t const * p_page_data);
+
+/**@brief Function for decoding page 2.
+ *
+ * @param[in] p_page_buffer Pointer to the data buffer.
+ * @param[out] p_page_data Pointer to the page data.
+ */
+void ant_sdm_page_2_decode(uint8_t const * p_page_buffer,
+ ant_sdm_page2_data_t * p_page_data);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // ANT_SDM_PAGE_2_H__
+/** @} */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ant/ant_profiles/ant_sdm/pages/ant_sdm_page_22.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ant/ant_profiles/ant_sdm/pages/ant_sdm_page_22.c
new file mode 100644
index 0000000..4f489e5
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ant/ant_profiles/ant_sdm/pages/ant_sdm_page_22.c
@@ -0,0 +1,127 @@
+/**
+ * Copyright (c) 2015 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#include "sdk_common.h"
+#if NRF_MODULE_ENABLED(ANT_SDM)
+
+#include <string.h>
+#include "ant_sdm_page_22.h"
+#include "ant_sdm_utils.h"
+
+#define NRF_LOG_MODULE_NAME ant_sdm
+#if ANT_SDM_LOG_ENABLED
+#define NRF_LOG_LEVEL ANT_SDM_LOG_LEVEL
+#define NRF_LOG_INFO_COLOR ANT_SDM_INFO_COLOR
+#else // ANT_SDM_LOG_ENABLED
+#define NRF_LOG_LEVEL 0
+#endif // ANT_SDM_LOG_ENABLED
+#include "nrf_log.h"
+
+/**@brief SDM page 22 data layout structure. */
+typedef struct
+{
+ uint8_t capabilities;
+ uint8_t reserved[6];
+}ant_sdm_page22_data_layout_t;
+
+/**@brief Function for tracing page 22 data.
+ *
+ * @param[in] p_page_data Pointer to the page 22 data.
+ */
+static void page_22_data_log(ant_sdm_page22_data_t const * p_page_data)
+{
+ NRF_LOG_INFO("Capabilities: ");
+
+ if (p_page_data->capabilities.items.time_is_valid)
+ {
+ NRF_LOG_RAW_INFO(" time");
+ }
+
+ if (p_page_data->capabilities.items.distance_is_valid)
+ {
+ NRF_LOG_RAW_INFO(" distance");
+ }
+
+ if (p_page_data->capabilities.items.speed_is_valid)
+ {
+ NRF_LOG_RAW_INFO(" speed");
+ }
+
+ if (p_page_data->capabilities.items.latency_is_valid)
+ {
+ NRF_LOG_RAW_INFO(" latency");
+ }
+
+ if (p_page_data->capabilities.items.cadency_is_valid)
+ {
+ NRF_LOG_RAW_INFO(" cadence");
+ }
+
+ if (p_page_data->capabilities.items.calorie_is_valid)
+ {
+ NRF_LOG_RAW_INFO(" calories");
+ }
+ NRF_LOG_RAW_INFO("\r\n\n");
+}
+
+
+void ant_sdm_page_22_encode(uint8_t * p_page_buffer,
+ ant_sdm_page22_data_t const * p_page_data)
+{
+ ant_sdm_page22_data_layout_t * p_outcoming_data = (ant_sdm_page22_data_layout_t *)p_page_buffer;
+
+ p_outcoming_data->capabilities = p_page_data->capabilities.byte;
+ memset(p_outcoming_data->reserved, UINT8_MAX, sizeof (p_outcoming_data->reserved));
+
+ page_22_data_log(p_page_data);
+}
+
+
+void ant_sdm_page_22_decode(uint8_t const * p_page_buffer,
+ ant_sdm_page22_data_t * p_page_data)
+{
+ ant_sdm_page22_data_layout_t const * p_incoming_data =
+ (ant_sdm_page22_data_layout_t *)p_page_buffer;
+
+ p_page_data->capabilities.byte = p_incoming_data->capabilities;
+
+ page_22_data_log(p_page_data);
+}
+
+#endif // NRF_MODULE_ENABLED(ANT_SDM)
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ant/ant_profiles/ant_sdm/pages/ant_sdm_page_22.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ant/ant_profiles/ant_sdm/pages/ant_sdm_page_22.h
new file mode 100644
index 0000000..42e2697
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ant/ant_profiles/ant_sdm/pages/ant_sdm_page_22.h
@@ -0,0 +1,106 @@
+/**
+ * Copyright (c) 2015 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#ifndef ANT_SDM_PAGE_22_H__
+#define ANT_SDM_PAGE_22_H__
+
+/** @file
+ *
+ * @defgroup ant_sdk_profiles_sdm_page22 Stride Based Speed and Distance Monitor profile page 22
+ * @{
+ * @ingroup ant_sdk_profiles_sdm_pages
+ */
+
+#include <stdint.h>
+#include <stdbool.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**@brief Data structure for SDM data page 22.
+ */
+typedef struct
+{
+ union
+ {
+ struct
+ {
+ bool time_is_valid : 1; ///< Transmitted time is valid.
+ bool distance_is_valid : 1; ///< Transmitted distance is valid.
+ bool speed_is_valid : 1; ///< Transmitted speed is valid.
+ bool latency_is_valid : 1; ///< Transmitted latency is valid.
+ bool cadency_is_valid : 1; ///< Transmitted cadency is valid.
+ bool calorie_is_valid : 1; ///< Transmitted calorie is valid.
+ } items;
+ uint8_t byte;
+ } capabilities;
+} ant_sdm_page22_data_t;
+
+/**@brief Initialize page 2.
+ */
+#define DEFAULT_ANT_SDM_PAGE22() \
+ (ant_sdm_page22_data_t) \
+ { \
+ .capabilities.byte = 0, \
+ }
+
+/**@brief Function for encoding page 22.
+ *
+ * @param[in] p_page_data Pointer to the page data.
+ * @param[out] p_page_buffer Pointer to the data buffer.
+ */
+void ant_sdm_page_22_encode(uint8_t * p_page_buffer,
+ ant_sdm_page22_data_t const * p_page_data);
+
+/**@brief Function for decoding page 22.
+ *
+ * @param[in] p_page_buffer Pointer to the data buffer.
+ * @param[out] p_page_data Pointer to the page data.
+ */
+void ant_sdm_page_22_decode(uint8_t const * p_page_buffer,
+ ant_sdm_page22_data_t * p_page_data);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // ANT_SDM_PAGE_22_H__
+/** @} */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ant/ant_profiles/ant_sdm/pages/ant_sdm_page_3.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ant/ant_profiles/ant_sdm/pages/ant_sdm_page_3.c
new file mode 100644
index 0000000..7a3e092
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ant/ant_profiles/ant_sdm/pages/ant_sdm_page_3.c
@@ -0,0 +1,92 @@
+/**
+ * Copyright (c) 2015 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#include "sdk_common.h"
+#if NRF_MODULE_ENABLED(ANT_SDM)
+
+#include "ant_sdm_page_3.h"
+#include "ant_sdm_utils.h"
+
+#define NRF_LOG_MODULE_NAME ant_sdm
+#if ANT_SDM_LOG_ENABLED
+#define NRF_LOG_LEVEL ANT_SDM_LOG_LEVEL
+#define NRF_LOG_INFO_COLOR ANT_SDM_INFO_COLOR
+#else // ANT_SDM_LOG_ENABLED
+#define NRF_LOG_LEVEL 0
+#endif // ANT_SDM_LOG_ENABLED
+#include "nrf_log.h"
+
+/**@brief SDM page 3 data layout structure. */
+typedef struct
+{
+ uint8_t reserved0[5];
+ uint8_t calories;
+ uint8_t reserved1;
+}ant_sdm_page3_data_layout_t;
+
+static void page_3_data_log(ant_sdm_page3_data_t const * p_page_data)
+{
+ NRF_LOG_INFO("Calories: %u\r\n\n", p_page_data->calories);
+}
+
+
+void ant_sdm_page_3_encode(uint8_t * p_page_buffer,
+ ant_sdm_page3_data_t const * p_page_data)
+{
+ ant_sdm_page3_data_layout_t * p_outcoming_data = (ant_sdm_page3_data_layout_t *)p_page_buffer;
+
+ p_outcoming_data->calories = p_page_data->calories;
+ page_3_data_log(p_page_data);
+}
+
+
+void ant_sdm_page_3_decode(uint8_t const * p_page_buffer,
+ ant_sdm_page3_data_t * p_page_data)
+{
+ ant_sdm_page3_data_layout_t const * p_incoming_data =
+ (ant_sdm_page3_data_layout_t *)p_page_buffer;
+
+ uint8_t prev_calories = (uint8_t) p_page_data->calories;
+
+ p_page_data->calories += ((p_incoming_data->calories - prev_calories) & UINT8_MAX);
+
+ page_3_data_log(p_page_data);
+}
+
+#endif // NRF_MODULE_ENABLED(ANT_SDM)
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ant/ant_profiles/ant_sdm/pages/ant_sdm_page_3.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ant/ant_profiles/ant_sdm/pages/ant_sdm_page_3.h
new file mode 100644
index 0000000..0321ee1
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ant/ant_profiles/ant_sdm/pages/ant_sdm_page_3.h
@@ -0,0 +1,93 @@
+/**
+ * Copyright (c) 2015 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#ifndef ANT_SDM_PAGE_3_H__
+#define ANT_SDM_PAGE_3_H__
+
+/** @file
+ *
+ * @defgroup ant_sdk_profiles_sdm_page3 Stride Based Speed and Distance Monitor profile page 3
+ * @{
+ * @ingroup ant_sdk_profiles_sdm_pages
+ */
+
+#include <stdint.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**@brief Data structure for SDM data page 3.
+ */
+typedef struct
+{
+ uint32_t calories; ///< Calories.
+} ant_sdm_page3_data_t;
+
+/**@brief Initialize page 3.
+ */
+#define DEFAULT_ANT_SDM_PAGE3() \
+ (ant_sdm_page3_data_t) \
+ { \
+ .calories = 0, \
+ }
+
+/**@brief Function for encoding page 3.
+ *
+ * @param[in] p_page_data Pointer to the page data.
+ * @param[out] p_page_buffer Pointer to the data buffer.
+ */
+void ant_sdm_page_3_encode(uint8_t * p_page_buffer,
+ ant_sdm_page3_data_t const * p_page_data);
+
+/**@brief Function for decoding page 3.
+ *
+ * @param[in] p_page_buffer Pointer to the data buffer.
+ * @param[out] p_page_data Pointer to the page data.
+ */
+void ant_sdm_page_3_decode(uint8_t const * p_page_buffer,
+ ant_sdm_page3_data_t * p_page_data);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // ANT_SDM_PAGE_3_H__
+/** @} */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ant/ant_profiles/ant_sdm/pages/ant_sdm_pages.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ant/ant_profiles/ant_sdm/pages/ant_sdm_pages.h
new file mode 100644
index 0000000..55a8643
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ant/ant_profiles/ant_sdm/pages/ant_sdm_pages.h
@@ -0,0 +1,70 @@
+/**
+ * Copyright (c) 2015 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#ifndef __ANT_SDM_PAGES_H
+#define __ANT_SDM_PAGES_H
+
+/** @file
+ *
+ * @defgroup ant_sdk_profiles_sdm_pages Stride Based Speed and Distance Monitor profile pages
+ * @{
+ * @ingroup ant_sdm
+ * @brief This module implements functions for the SDM data pages.
+ */
+
+#include "ant_sdm_page_1.h"
+#include "ant_sdm_page_2.h"
+#include "ant_sdm_page_3.h"
+#include "ant_sdm_page_16.h"
+#include "ant_sdm_page_22.h"
+#include "ant_sdm_common_data.h"
+#include "ant_common_page_70.h"
+#include "ant_common_page_80.h"
+#include "ant_common_page_81.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // __ANT_SDM_PAGES_H
+/** @} */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ant/ant_profiles/ant_sdm/simulator/ant_sdm_simulator.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ant/ant_profiles/ant_sdm/simulator/ant_sdm_simulator.c
new file mode 100644
index 0000000..5dbfe80
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ant/ant_profiles/ant_sdm/simulator/ant_sdm_simulator.c
@@ -0,0 +1,159 @@
+/**
+ * Copyright (c) 2015 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#include "sdk_common.h"
+#if NRF_MODULE_ENABLED(ANT_SDM)
+
+#include "ant_sdm_simulator.h"
+#include "ant_sdm_utils.h"
+
+#define SIMULATOR_STRIDE_LENGTH_UNIT_REVERSAL 100 ///< Stride length unit is cm.
+#define SIMULATOR_BURN_RATE_UNIT 1000 ///< Burn rate uinit is kcal per km.
+#define SIMULATOR_TIME_INCREMENT SDM_MSG_PERIOD_4Hz ///< Ticks between two cycles.
+#define SIMULATOR_TIME_UNIT_REVERSAL ANT_CLOCK_FREQUENCY ///< Simulation time frequency.
+#define SEC_PER_MIN 60 ///< Number of seconds per minute.
+#define SIMULATOR_STRIDE_UNIT_REVERSAL (SIMULATOR_TIME_UNIT_REVERSAL * \
+ ANT_SDM_CADENCE_UNIT_REVERSAL * SEC_PER_MIN)
+
+
+void ant_sdm_simulator_init(ant_sdm_simulator_t * p_simulator,
+ ant_sdm_simulator_cfg_t const * p_config,
+ bool auto_change)
+{
+ p_simulator->p_profile = p_config->p_profile;
+ p_simulator->_cb.stride_length = p_config->stride_length;
+ p_simulator->_cb.burn_rate = p_config->burn_rate;
+ p_simulator->_cb.sensorsim_cfg = p_config->sensorsim_cfg;
+ p_simulator->_cb.auto_change = auto_change;
+ p_simulator->_cb.sensorsim_state.current_val = p_simulator->_cb.sensorsim_cfg.min;
+ p_simulator->_cb.stride_incr = 0;
+ p_simulator->_cb.time = 0;
+
+
+ sensorsim_init(&(p_simulator->_cb.sensorsim_state), &(p_simulator->_cb.sensorsim_cfg));
+}
+
+
+void ant_sdm_simulator_one_iteration(ant_sdm_simulator_t * p_simulator)
+{
+ if (p_simulator->_cb.auto_change)
+ {
+ UNUSED_PARAMETER(sensorsim_measure(&(p_simulator->_cb.sensorsim_state),
+ &(p_simulator->_cb.sensorsim_cfg)));
+ }
+
+ p_simulator->_cb.time += SIMULATOR_TIME_INCREMENT;
+
+ p_simulator->_cb.stride_incr += p_simulator->_cb.sensorsim_state.current_val *
+ SIMULATOR_TIME_INCREMENT;
+ p_simulator->p_profile->SDM_PROFILE_strides += p_simulator->_cb.stride_incr /
+ SIMULATOR_STRIDE_UNIT_REVERSAL;
+ p_simulator->_cb.stride_incr = p_simulator->_cb.stride_incr %
+ SIMULATOR_STRIDE_UNIT_REVERSAL;
+
+
+ uint32_t distance = value_rescale(
+ p_simulator->p_profile->SDM_PROFILE_strides * p_simulator->_cb.stride_length,
+ SIMULATOR_STRIDE_LENGTH_UNIT_REVERSAL,
+ ANT_SDM_DISTANCE_UNIT_REVERSAL);
+
+ if (p_simulator->p_profile->SDM_PROFILE_capabilities.cadency_is_valid)
+ {
+ p_simulator->p_profile->SDM_PROFILE_cadence = p_simulator->_cb.sensorsim_state.current_val;
+ }
+
+ if (p_simulator->p_profile->SDM_PROFILE_capabilities.speed_is_valid)
+ {
+ p_simulator->p_profile->SDM_PROFILE_speed = value_rescale(
+ p_simulator->_cb.sensorsim_state.current_val * p_simulator->_cb.stride_length,
+ ANT_SDM_CADENCE_UNIT_REVERSAL * SIMULATOR_STRIDE_LENGTH_UNIT_REVERSAL * SEC_PER_MIN,
+ ANT_SDM_SPEED_UNIT_REVERSAL);
+ }
+
+ if (p_simulator->p_profile->SDM_PROFILE_capabilities.distance_is_valid)
+ {
+ p_simulator->p_profile->SDM_PROFILE_distance = distance;
+ }
+
+ if (p_simulator->p_profile->SDM_PROFILE_capabilities.calorie_is_valid)
+ {
+ p_simulator->p_profile->SDM_PROFILE_calories = value_rescale(distance,
+ SIMULATOR_BURN_RATE_UNIT
+ * ANT_SDM_DISTANCE_UNIT_REVERSAL,
+ p_simulator->_cb.burn_rate);
+ }
+
+ if (p_simulator->p_profile->SDM_PROFILE_capabilities.time_is_valid)
+ {
+ p_simulator->p_profile->SDM_PROFILE_time = value_rescale(p_simulator->_cb.time,
+ SIMULATOR_TIME_UNIT_REVERSAL,
+ ANT_SDM_TIME_UNIT_REVERSAL);
+ }
+
+ if (p_simulator->p_profile->SDM_PROFILE_capabilities.latency_is_valid)
+ {
+ p_simulator->p_profile->SDM_PROFILE_update_latency =
+ ROUNDED_DIV(((uint64_t)p_simulator->_cb.stride_incr *
+ ANT_SDM_UPDATE_LATENCY_UNIT_REVERSAL),
+ (uint64_t)SIMULATOR_TIME_UNIT_REVERSAL *
+ p_simulator->_cb.sensorsim_state.current_val);
+ }
+}
+
+
+void ant_sdm_simulator_increment(ant_sdm_simulator_t * p_simulator)
+{
+ if (!p_simulator->_cb.auto_change)
+ {
+ sensorsim_increment(&(p_simulator->_cb.sensorsim_state),
+ &(p_simulator->_cb.sensorsim_cfg));
+ }
+}
+
+
+void ant_sdm_simulator_decrement(ant_sdm_simulator_t * p_simulator)
+{
+ if (!p_simulator->_cb.auto_change)
+ {
+ sensorsim_decrement(&(p_simulator->_cb.sensorsim_state),
+ &(p_simulator->_cb.sensorsim_cfg));
+ }
+}
+
+#endif // NRF_MODULE_ENABLED(ANT_SDM)
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ant/ant_profiles/ant_sdm/simulator/ant_sdm_simulator.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ant/ant_profiles/ant_sdm/simulator/ant_sdm_simulator.h
new file mode 100644
index 0000000..e18cd48
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ant/ant_profiles/ant_sdm/simulator/ant_sdm_simulator.h
@@ -0,0 +1,139 @@
+/**
+ * Copyright (c) 2015 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#ifndef ANT_SDM_SIMULATOR_H__
+#define ANT_SDM_SIMULATOR_H__
+
+/** @file
+ *
+ * @defgroup ant_sdk_sdm_simulator ANT SDM simulator
+ * @{
+ * @ingroup ant_sdk_simulators
+ * @brief ANT SDM simulator module.
+ *
+ * @details This module simulates strides for the ANT SDM profile. The module calculates
+ * abstract values, which are handled by the SDM pages data model to ensure that they are
+ * compatible. It provides a handler for changing the cadence value manually and functionality
+ * for changing the cadence automatically.
+ *
+ */
+
+#include <stdint.h>
+#include <stdbool.h>
+#include "ant_sdm.h"
+#include "ant_sdm_utils.h"
+#include "sensorsim.h"
+#include "ant_sdm_simulator_local.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**@brief SDM simulator configuration structure. */
+typedef struct
+{
+ ant_sdm_profile_t * p_profile; ///< Related profile.
+ uint32_t stride_length; ///< Length of a stride in cm.
+ uint32_t burn_rate; ///< Kcal per kilometer.
+ sensorsim_cfg_t sensorsim_cfg; ///< Sensorsim configuration.
+} ant_sdm_simulator_cfg_t;
+
+/**@brief Initialize @ref ant_sdm_simulator_cfg_t.
+ */
+#define DEFAULT_ANT_SDM_SIMULATOR_CFG(P_PROFILE, \
+ STRIDE_LEN, \
+ BURN_RATE, \
+ MIN_CADENCE, \
+ MAX_CADENCE, \
+ INCREMENT) \
+ { \
+ .p_profile = (P_PROFILE), \
+ .stride_length = (STRIDE_LEN), \
+ .burn_rate = (BURN_RATE), \
+ .sensorsim_cfg.min = (MIN_CADENCE) *(ANT_SDM_CADENCE_UNIT_REVERSAL), \
+ .sensorsim_cfg.max = (MAX_CADENCE) *(ANT_SDM_CADENCE_UNIT_REVERSAL), \
+ .sensorsim_cfg.incr = (INCREMENT) *(ANT_SDM_CADENCE_UNIT_REVERSAL), \
+ .sensorsim_cfg.start_at_max = false, \
+ }
+
+/**@brief SDM simulator structure. */
+typedef struct
+{
+ ant_sdm_profile_t * p_profile; ///< Related profile.
+ ant_sdm_simulator_cb_t _cb; ///< Internal control block.
+} ant_sdm_simulator_t;
+
+
+/**@brief Function for initializing the ANT SDM simulator instance.
+ *
+ * @param[in] p_simulator Pointer to the simulator instance.
+ * @param[in] p_config Pointer to the simulator configuration structure.
+ * @param[in] auto_change Enable or disable automatic changes of the cadence.
+ */
+void ant_sdm_simulator_init(ant_sdm_simulator_t * p_simulator,
+ ant_sdm_simulator_cfg_t const * p_config,
+ bool auto_change);
+
+/**@brief Function for simulating a device event.
+ *
+ * @details Based on this event, the transmitter data is simulated.
+ *
+ * This function should be called in the SDM TX event handler.
+ */
+void ant_sdm_simulator_one_iteration(ant_sdm_simulator_t * p_simulator);
+
+/**@brief Function for incrementing the cadence value.
+ *
+ * @param[in] p_simulator Pointer to the simulator instance.
+ */
+void ant_sdm_simulator_increment(ant_sdm_simulator_t * p_simulator);
+
+/**@brief Function for decrementing the cadence value.
+ *
+ * @param[in] p_simulator Pointer to the simulator instance.
+ */
+void ant_sdm_simulator_decrement(ant_sdm_simulator_t * p_simulator);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // ANT_SDM_SIMULATOR_H__
+/** @} */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ant/ant_profiles/ant_sdm/simulator/ant_sdm_simulator_local.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ant/ant_profiles/ant_sdm/simulator/ant_sdm_simulator_local.h
new file mode 100644
index 0000000..732e98e
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ant/ant_profiles/ant_sdm/simulator/ant_sdm_simulator_local.h
@@ -0,0 +1,71 @@
+/**
+ * Copyright (c) 2015 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#ifndef ANT_SDM_SIMULATOR_LOCAL_H__
+#define ANT_SDM_SIMULATOR_LOCAL_H__
+
+#include <stdint.h>
+#include <stdbool.h>
+#include "ant_sdm.h"
+#include "sensorsim.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @ingroup ant_sdk_sdm_simulator
+ * @brief SDM simulator control block structure. */
+typedef struct
+{
+ bool auto_change; ///< Cadence will change automatically (if auto_change is set) or manually.
+ uint8_t stride_length; ///< Length of a stride (in cm).
+ uint8_t burn_rate; ///< Kcal per kilometer.
+ uint32_t stride_incr; ///< Fractional part of stride increment.
+ uint64_t time; ///< Simulation time.
+ sensorsim_state_t sensorsim_state; ///< State of the simulated sensor.
+ sensorsim_cfg_t sensorsim_cfg; ///< Configuration of the simulated sensor.
+}ant_sdm_simulator_cb_t;
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // ANT_SDM_SIMULATOR_LOCAL_H__
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ant/ant_profiles/ant_sdm/utils/ant_sdm_utils.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ant/ant_profiles/ant_sdm/utils/ant_sdm_utils.h
new file mode 100644
index 0000000..a68a8d0
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ant/ant_profiles/ant_sdm/utils/ant_sdm_utils.h
@@ -0,0 +1,112 @@
+/**
+ * Copyright (c) 2015 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#ifndef ANT_SDM_UTILS_H__
+#define ANT_SDM_UTILS_H__
+
+#include "nrf_assert.h"
+#include "nrf.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** @file
+ *
+ * @defgroup ant_sdk_profiles_sdm_utils Stride Based Speed and Distance Monitor profile utilities
+ * @{
+ * @ingroup ant_sdm
+ * @brief This module implements utilities for the Stride Based Speed and Distance Monitor profile.
+ *
+ */
+
+/*@brief A reversal of time unit.
+ *
+ * @details According to the ANT SDM specification, the time unit (fractional part) is 1/200 of a second.
+ */
+#define ANT_SDM_TIME_UNIT_REVERSAL 200
+#define ANT_SDM_TIME_DISP_PRECISION 1000
+#define ANT_SDM_TIME_RESCALE(VALUE) value_rescale((VALUE), ANT_SDM_TIME_UNIT_REVERSAL, \
+ ANT_SDM_TIME_DISP_PRECISION)
+
+/*@brief A reversal of distance unit.
+ *
+ * @details According to the ANT SDM specification, the distance unit (page 1 - fractional part) is 1/16 of a meter.
+ */
+#define ANT_SDM_DISTANCE_UNIT_REVERSAL 16
+#define ANT_SDM_DISTANCE_DISP_PRECISION 10
+#define ANT_SDM_DISTANCE_RESCALE(VALUE) value_rescale((VALUE), ANT_SDM_DISTANCE_UNIT_REVERSAL, \
+ ANT_SDM_DISTANCE_DISP_PRECISION)
+
+/*@brief A reversal of speed unit.
+ *
+ * @details According to the ANT SDM specification, the speed unit (fractional part) is 1/256 of m/s.
+ */
+#define ANT_SDM_SPEED_UNIT_REVERSAL 256
+#define ANT_SDM_SPEED_DISP_PRECISION 100
+#define ANT_SDM_SPEED_RESCALE(VALUE) value_rescale((VALUE), ANT_SDM_SPEED_UNIT_REVERSAL, \
+ ANT_SDM_SPEED_DISP_PRECISION)
+
+/*@brief A reversal of update latency unit.
+ *
+ * @details According to the ANT SDM specification, the update latency unit (fractional part) is 1/32 of a second.
+ */
+#define ANT_SDM_UPDATE_LATENCY_UNIT_REVERSAL 32
+#define ANT_SDM_UPDATE_LATENCY_DISP_PRECISION 1000
+#define ANT_SDM_UPDATE_LATENCY_RESCALE(VALUE) value_rescale((VALUE), ANT_SDM_UPDATE_LATENCY_UNIT_REVERSAL, \
+ ANT_SDM_UPDATE_LATENCY_DISP_PRECISION)
+
+/*@brief A reversal of cadence unit.
+ *
+ * @details According to the ANT SDM specification, the cadence unit (fractional part) is 1/16 of strides/minute.
+ */
+#define ANT_SDM_CADENCE_UNIT_REVERSAL 16
+#define ANT_SDM_CADENCE_DISP_PRECISION 10
+#define ANT_SDM_CADENCE_RESCALE(VALUE) value_rescale((VALUE), ANT_SDM_CADENCE_UNIT_REVERSAL, \
+ ANT_SDM_CADENCE_DISP_PRECISION)
+
+/** @} */
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // ANT_SDM_UTILS_H__
+
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ant/ant_search_config/ant_search_config.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ant/ant_search_config/ant_search_config.c
new file mode 100644
index 0000000..3314b81
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ant/ant_search_config/ant_search_config.c
@@ -0,0 +1,77 @@
+/**
+ * Copyright (c) 2015 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#include "sdk_common.h"
+#if NRF_MODULE_ENABLED(ANT_SEARCH_CONFIG)
+
+#include "ant_search_config.h"
+#include "ant_interface.h"
+
+uint32_t ant_search_init(ant_search_config_t const * p_config)
+{
+ uint32_t err_code;
+
+ if (p_config->low_priority_timeout == ANT_LOW_PRIORITY_SEARCH_DISABLE
+ && p_config->high_priority_timeout == ANT_HIGH_PRIORITY_SEARCH_DISABLE)
+ {
+ return NRF_ERROR_INVALID_PARAM;
+ }
+
+ err_code = sd_ant_search_channel_priority_set(p_config->channel_number,
+ p_config->search_priority);
+ VERIFY_SUCCESS(err_code);
+
+ err_code = sd_ant_search_waveform_set(p_config->channel_number,
+ p_config->waveform);
+ VERIFY_SUCCESS(err_code);
+
+ err_code = sd_ant_channel_rx_search_timeout_set(p_config->channel_number,
+ p_config->high_priority_timeout);
+ VERIFY_SUCCESS(err_code);
+
+ err_code = sd_ant_channel_low_priority_rx_search_timeout_set(p_config->channel_number,
+ p_config->low_priority_timeout);
+ VERIFY_SUCCESS(err_code);
+
+ err_code = sd_ant_active_search_sharing_cycles_set(p_config->channel_number,
+ p_config->search_sharing_cycles);
+ return err_code;
+}
+
+#endif // NRF_MODULE_ENABLED(ANT_SEARCH_CONFIG)
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ant/ant_search_config/ant_search_config.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ant/ant_search_config/ant_search_config.h
new file mode 100644
index 0000000..72395e3
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ant/ant_search_config/ant_search_config.h
@@ -0,0 +1,129 @@
+/**
+ * Copyright (c) 2015 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#ifndef ANT_SEARCH_CONFIG_H__
+#define ANT_SEARCH_CONFIG_H__
+
+/** @file
+ *
+ * @defgroup ant_search_config ANT search configuration
+ * @{
+ * @ingroup ant_sdk_utils
+ * @brief ANT channel search configuration module.
+ */
+
+#include <stdint.h>
+#include "ant_parameters.h"
+#include "sdk_config.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define ANT_SEARCH_SHARING_CYCLES_DISABLE 0x00 ///< Disable search sharing.
+
+#define ANT_LOW_PRIORITY_SEARCH_DISABLE 0x00 ///< Disable low priority search.
+#define ANT_LOW_PRIORITY_TIMEOUT_DISABLE 0xFF ///< Disable low priority search time-out.
+
+#define ANT_HIGH_PRIORITY_SEARCH_DISABLE 0x00 ///< Disable high priority search.
+#define ANT_HIGH_PRIORITY_TIMEOUT_DISABLE 0xFF ///< Disable high priority search time-out.
+
+/**@brief Search priority. */
+typedef enum
+{
+ ANT_SEARCH_PRIORITY_DEFAULT = 0, ///< Default search priority level.
+ ANT_SEARCH_PRIORITY_LOWEST = ANT_SEARCH_PRIORITY_DEFAULT, ///< Lowest search priority level.
+ ANT_SEARCH_PRIORITY_0 = ANT_SEARCH_PRIORITY_LOWEST,
+ ANT_SEARCH_PRIORITY_1 = 1,
+ ANT_SEARCH_PRIORITY_2 = 2,
+ ANT_SEARCH_PRIORITY_3 = 3,
+ ANT_SEARCH_PRIORITY_4 = 4,
+ ANT_SEARCH_PRIORITY_5 = 5,
+ ANT_SEARCH_PRIORITY_6 = 6,
+ ANT_SEARCH_PRIORITY_7 = 7,
+ ANT_SEARCH_PRIORITY_HIGHEST = ANT_SEARCH_PRIORITY_7, ///< Highest search priority level.
+} ant_search_priority_t;
+
+/**@brief ANT search waveform. */
+typedef enum
+{
+ ANT_WAVEFORM_DEFAULT = 316, ///< Standard search waveform value.
+ ANT_WAVEFORM_FAST = 97, ///< Accelerated search waveform value.
+} ant_waveform_t;
+
+/**@brief ANT search configuration structure. */
+typedef struct
+{
+ uint8_t channel_number; ///< Assigned channel number.
+ uint8_t low_priority_timeout; ///< Low priority time-out (in 2.5 second increments).
+ uint8_t high_priority_timeout; ///< High priority time-out (in 2.5 second increments).
+ uint8_t search_sharing_cycles; ///< Number of search cycles to run before alternating searches. Search sharing can be disabled by @ref ANT_SEARCH_SHARING_CYCLES_DISABLE.
+ ant_search_priority_t search_priority; ///< Search priority.
+ ant_waveform_t waveform; ///< Search waveform. Do not use custom values.
+} ant_search_config_t;
+
+/**@brief Initializes the default ANT search configuration structure.
+ *
+ * @param[in] CHANNEL_NUMBER Number of the channel.
+ */
+#define DEFAULT_ANT_SEARCH_CONFIG(CHANNEL_NUMBER) \
+{ \
+ .channel_number = CHANNEL_NUMBER, \
+ .low_priority_timeout = ANT_DEFAULT_LOW_PRIORITY_TIMEOUT, \
+ .high_priority_timeout = ANT_DEFAULT_HIGH_PRIORITY_TIMEOUT, \
+ .search_sharing_cycles = ANT_SEARCH_SHARING_CYCLES_DISABLE, \
+ .search_priority = ANT_SEARCH_PRIORITY_DEFAULT, \
+ .waveform = ANT_WAVEFORM_DEFAULT, \
+}
+
+/**@brief Function for configuring the ANT channel search.
+ *
+ * @param[in] p_config Pointer to the search configuration structure.
+ *
+ * @retval NRF_SUCCESS If the channel was successfully configured. Otherwise, an error code is returned.
+ */
+uint32_t ant_search_init(ant_search_config_t const * p_config);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // ANT_SEARCH_CONFIG_H__
+/** @} */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ant/ant_state_indicator/ant_state_indicator.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ant/ant_state_indicator/ant_state_indicator.c
new file mode 100644
index 0000000..1b4b2c5
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ant/ant_state_indicator/ant_state_indicator.c
@@ -0,0 +1,145 @@
+/**
+ * Copyright (c) 2015 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#include "sdk_common.h"
+#if NRF_MODULE_ENABLED(ANT_STATE_INDICATOR)
+#include "ant_state_indicator.h"
+#include "bsp.h"
+#include "app_error.h"
+#include "nrf_sdh.h"
+#include "nrf_sdh_ant.h"
+#include "nrf_pwr_mgmt.h"
+
+static uint8_t m_channel = UINT8_MAX; /**< ANT channel number linked to indication. */
+static uint8_t m_channel_type; /**< Type of linked ANT channel. */
+
+ret_code_t ant_state_indicator_init( uint8_t channel, uint8_t channel_type)
+{
+ m_channel = channel;
+ m_channel_type = channel_type;
+
+ return bsp_indication_set(BSP_INDICATE_IDLE);
+}
+
+ret_code_t ant_state_indicator_channel_opened(void)
+{
+ ret_code_t err_code = NRF_SUCCESS;
+
+ switch (m_channel_type)
+ {
+ case CHANNEL_TYPE_SLAVE:
+ /* fall through */
+ case CHANNEL_TYPE_SLAVE_RX_ONLY:
+ err_code = bsp_indication_set(BSP_INDICATE_SCANNING);
+ break;
+
+ case CHANNEL_TYPE_MASTER:
+ err_code = bsp_indication_set(BSP_INDICATE_ADVERTISING);
+ break;
+ }
+
+ return err_code;
+}
+
+/**
+ * @brief Function for handling ANT events.
+ *
+ * @param[in] p_ant_evt Event received from the ANT stack.
+ * @param[in] p_context Context.
+ */
+static void ant_evt_handler(ant_evt_t * p_ant_evt, void * p_context)
+{
+ ret_code_t err_code = NRF_SUCCESS;
+
+ if (m_channel != p_ant_evt->channel)
+ {
+ return;
+ }
+
+ switch (m_channel_type)
+ {
+ case CHANNEL_TYPE_SLAVE:
+ /* fall through */
+ case CHANNEL_TYPE_SLAVE_RX_ONLY:
+ switch (p_ant_evt->event)
+ {
+ case EVENT_RX:
+ err_code = bsp_indication_set(BSP_INDICATE_CONNECTED);
+ break;
+
+ case EVENT_RX_FAIL:
+ err_code = bsp_indication_set(BSP_INDICATE_RCV_ERROR);
+ break;
+
+ case EVENT_RX_FAIL_GO_TO_SEARCH:
+ err_code = bsp_indication_set(BSP_INDICATE_SCANNING);
+ break;
+
+ case EVENT_CHANNEL_CLOSED:
+ nrf_pwr_mgmt_shutdown(NRF_PWR_MGMT_SHUTDOWN_GOTO_SYSOFF);
+ break;
+
+ case EVENT_RX_SEARCH_TIMEOUT:
+ err_code = bsp_indication_set(BSP_INDICATE_IDLE);
+ break;
+ }
+ break;
+ }
+ APP_ERROR_CHECK(err_code);
+}
+
+NRF_SDH_ANT_OBSERVER(m_ant_observer, ANT_STATE_INDICATOR_ANT_OBSERVER_PRIO, ant_evt_handler, NULL);
+
+/**
+ * @brief Function for shutdown events.
+ *
+ * @param[in] event Shutdown type.
+ */
+static bool m_shutdown_handler(nrf_pwr_mgmt_evt_t event)
+{
+ ret_code_t err_code = bsp_indication_set(BSP_INDICATE_IDLE);
+ APP_ERROR_CHECK(err_code);
+
+ return true;
+}
+
+
+NRF_PWR_MGMT_HANDLER_REGISTER(m_shutdown_handler, ANT_STATE_INDICATOR_CONFIG_SHUTDOWN_HANDLER_PRIORITY);
+
+#endif // NRF_MODULE_ENABLED(ANT_STATE_INDICATOR)
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ant/ant_state_indicator/ant_state_indicator.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ant/ant_state_indicator/ant_state_indicator.h
new file mode 100644
index 0000000..a1745f5
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ant/ant_state_indicator/ant_state_indicator.h
@@ -0,0 +1,95 @@
+/**
+ * Copyright (c) 2015 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#ifndef __ANT_STATE_INDICATOR_H
+#define __ANT_STATE_INDICATOR_H
+
+/** @file
+ *
+ * @defgroup ant_state_indicator ANT channel state indicator
+ * @{
+ * @ingroup ant_sdk_utils
+ * @brief ANT channel state indicator module.
+ *
+ * @details This module provides functionality for indicating the ANT channel state.
+ */
+
+#include <stdint.h>
+#include "sdk_errors.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @brief Function for initializing the ANT channel state indicator.
+ *
+ * @details This function links the signaling procedure with a specific ANT channel.
+ *
+ * Before calling this function, you must initiate the @ref lib_bsp to be able to use the LEDs.
+ *
+ * @param[in] channel ANT channel number.
+ * @param[in] channel_type ANT channel type (see Assign Channel Parameters in ant_parameters.h: @ref ant_parameters).
+ *
+ * @retval NRF_SUCCESS If the module was initialized successfully. Otherwise, a propagated error
+ * code is returned.
+ */
+ret_code_t ant_state_indicator_init(uint8_t channel, uint8_t channel_type);
+
+/**
+ * @brief Function for indicating the channel opening.
+ *
+ * @details This function should be called after the opening of the channel.
+ *
+ * @retval NRF_SUCCESS If the state was successfully indicated.
+ * @retval NRF_ERROR_NO_MEM If the internal timer operations queue was full.
+ * @retval NRF_ERROR_INVALID_STATE If the application timer module has not been initialized
+ * or the internal timer has not been created.
+ *
+ * @retval NRF_SUCCESS If the state was indicated successfully. Otherwise, a propagated error
+ * code is returned.
+ */
+ret_code_t ant_state_indicator_channel_opened(void);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // ANT_STATE_INDICATOR_H__
+/** @} */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_advertising/ble_advertising.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_advertising/ble_advertising.c
new file mode 100644
index 0000000..e09c2dd
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_advertising/ble_advertising.c
@@ -0,0 +1,790 @@
+/**
+ * Copyright (c) 2015 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#include "sdk_common.h"
+#if NRF_MODULE_ENABLED(BLE_ADVERTISING)
+#include "ble_advdata.h"
+#include "ble_advertising.h"
+#include "nrf_soc.h"
+#include "nrf_log.h"
+#include "nrf_fstorage.h"
+#include "sdk_errors.h"
+#include "nrf_sdh_ble.h"
+#include "nrf_sdh_soc.h"
+
+#define BLE_ADV_MODES (5) /**< Total number of possible advertising modes. */
+
+
+/**@brief Function for checking if the whitelist is in use.
+ *
+ * @param[in] p_advertising Advertising module instance.
+ */
+static bool whitelist_has_entries(ble_advertising_t * const p_advertising)
+{
+ return p_advertising->whitelist_in_use;
+}
+
+
+/**@brief Function for checking if an address is valid.
+ *
+ * @param[in] p_addr Pointer to a bluetooth address.
+ */
+static bool addr_is_valid(uint8_t const * const p_addr)
+{
+ for (uint32_t i = 0; i < BLE_GAP_ADDR_LEN; i++)
+ {
+ if (p_addr[i] != 0)
+ {
+ return true;
+ }
+ }
+ return false;
+}
+
+
+/**@brief Function for checking the next advertising mode.
+ *
+ * @param[in] adv_mode Current advertising mode.
+ */
+static ble_adv_mode_t adv_mode_next_get(ble_adv_mode_t adv_mode)
+{
+ return (ble_adv_mode_t)((adv_mode + 1) % BLE_ADV_MODES);
+}
+
+
+/**@brief Function for handling the Connected event.
+ *
+ * @param[in] p_ble_evt Event received from the BLE stack.
+ */
+static void on_connected(ble_advertising_t * const p_advertising, ble_evt_t const * p_ble_evt)
+{
+ if (p_ble_evt->evt.gap_evt.params.connected.role == BLE_GAP_ROLE_PERIPH)
+ {
+ p_advertising->current_slave_link_conn_handle = p_ble_evt->evt.gap_evt.conn_handle;
+ }
+}
+
+
+/**@brief Function for handling the Disconnected event.
+ *
+ * @param[in] p_advertising Advertising module instance.
+ * @param[in] p_ble_evt Event received from the BLE stack.
+ */
+static void on_disconnected(ble_advertising_t * const p_advertising, ble_evt_t const * p_ble_evt)
+{
+ uint32_t ret;
+
+ p_advertising->whitelist_temporarily_disabled = false;
+
+ if (p_ble_evt->evt.gap_evt.conn_handle == p_advertising->current_slave_link_conn_handle &&
+ p_advertising->adv_modes_config.ble_adv_on_disconnect_disabled == false)
+ {
+ ret = ble_advertising_start(p_advertising, BLE_ADV_MODE_DIRECTED_HIGH_DUTY);
+ if ((ret != NRF_SUCCESS) && (p_advertising->error_handler != NULL))
+ {
+ p_advertising->error_handler(ret);
+ }
+ }
+}
+
+
+/**@brief Function for handling the Timeout event.
+ *
+ * @param[in] p_advertising Advertising module instance.
+ * @param[in] p_ble_evt Event received from the BLE stack.
+ */
+static void on_terminated(ble_advertising_t * const p_advertising, ble_evt_t const * p_ble_evt)
+{
+ ret_code_t ret;
+
+ if (p_ble_evt->header.evt_id != BLE_GAP_EVT_ADV_SET_TERMINATED)
+ {
+ // Nothing to do.
+ return;
+ }
+
+ if ( p_ble_evt->evt.gap_evt.params.adv_set_terminated.reason == BLE_GAP_EVT_ADV_SET_TERMINATED_REASON_TIMEOUT
+ ||p_ble_evt->evt.gap_evt.params.adv_set_terminated.reason == BLE_GAP_EVT_ADV_SET_TERMINATED_REASON_LIMIT_REACHED)
+ {
+ // Start advertising in the next mode.
+ ret = ble_advertising_start(p_advertising, adv_mode_next_get(p_advertising->adv_mode_current));
+
+ if ((ret != NRF_SUCCESS) && (p_advertising->error_handler != NULL))
+ {
+ p_advertising->error_handler(ret);
+ }
+ }
+}
+
+
+/** @brief Function to determine if a flash write operation in in progress.
+ *
+ * @return true if a flash operation is in progress, false if not.
+ */
+static bool flash_access_in_progress()
+{
+ return nrf_fstorage_is_busy(NULL);
+}
+
+
+/**@brief Get the next available advertising mode.
+ *
+ * @param[in] p_advertising Advertising module instance.
+ * @param[in] adv_mode Requested advertising mode.
+ *
+ * @returns adv_mode if possible, or the best available mode if not.
+ */
+static ble_adv_mode_t adv_mode_next_avail_get(ble_advertising_t * const p_advertising,
+ ble_adv_mode_t adv_mode)
+{
+ bool peer_addr_is_valid = addr_is_valid(p_advertising->peer_address.addr);
+
+ // If a mode is disabled, continue to the next mode.
+
+ switch (adv_mode)
+ {
+ case BLE_ADV_MODE_DIRECTED_HIGH_DUTY:
+ if ( (p_advertising->adv_modes_config.ble_adv_directed_high_duty_enabled)
+ && (!p_advertising->adv_modes_config.ble_adv_extended_enabled)
+ && (peer_addr_is_valid))
+ {
+ return BLE_ADV_MODE_DIRECTED_HIGH_DUTY;
+ }
+ // Fallthrough.
+
+ case BLE_ADV_MODE_DIRECTED:
+ if ((p_advertising->adv_modes_config.ble_adv_directed_enabled) && peer_addr_is_valid)
+ {
+ return BLE_ADV_MODE_DIRECTED;
+ }
+ // Fallthrough.
+
+ case BLE_ADV_MODE_FAST:
+ if (p_advertising->adv_modes_config.ble_adv_fast_enabled)
+ {
+ return BLE_ADV_MODE_FAST;
+ }
+ // Fallthrough.
+
+ case BLE_ADV_MODE_SLOW:
+ if (p_advertising->adv_modes_config.ble_adv_slow_enabled)
+ {
+ return BLE_ADV_MODE_SLOW;
+ }
+ // Fallthrough.
+
+ default:
+ return BLE_ADV_MODE_IDLE;
+ }
+}
+
+
+/**@brief Function for starting high duty directed advertising.
+ *
+ * @param[in] p_advertising Advertising instance.
+ * @param[out] p_adv_params Advertising parameters.
+ *
+ * @return NRF_SUCCESS
+ */
+static ret_code_t set_adv_mode_directed_high_duty(ble_advertising_t * const p_advertising,
+ ble_gap_adv_params_t * p_adv_params)
+{
+ p_advertising->adv_evt = BLE_ADV_EVT_DIRECTED_HIGH_DUTY;
+ p_advertising->p_adv_data = NULL;
+
+ p_adv_params->p_peer_addr = &(p_advertising->peer_address);
+ p_adv_params->interval = 0;
+ p_adv_params->properties.type = BLE_GAP_ADV_TYPE_CONNECTABLE_NONSCANNABLE_DIRECTED_HIGH_DUTY_CYCLE;
+ p_adv_params->duration = BLE_GAP_ADV_TIMEOUT_HIGH_DUTY_MAX;
+
+ return NRF_SUCCESS;
+}
+
+
+/**@brief Function for starting directed slow advertising.
+ *
+ * @param[in] p_advertising Advertising module instance.
+ * @param[out] p_adv_params Advertising parameters.
+ *
+ * @return NRF_SUCCESS
+ */
+static ret_code_t set_adv_mode_directed(ble_advertising_t * const p_advertising,
+ ble_gap_adv_params_t * p_adv_params)
+{
+ p_advertising->adv_evt = BLE_ADV_EVT_DIRECTED;
+#if !defined (S112)
+ if (p_advertising->adv_modes_config.ble_adv_extended_enabled)
+ {
+ p_adv_params->properties.type = BLE_GAP_ADV_TYPE_EXTENDED_CONNECTABLE_NONSCANNABLE_DIRECTED;
+ }
+ else
+ {
+#endif // !defined (S112)
+ p_adv_params->properties.type = BLE_GAP_ADV_TYPE_CONNECTABLE_NONSCANNABLE_DIRECTED;
+#if !defined (S112)
+ }
+#endif // !defined (S112)
+ p_adv_params->duration = p_advertising->adv_modes_config.ble_adv_directed_timeout;
+
+ p_advertising->p_adv_data = NULL;
+
+ p_adv_params->p_peer_addr = &p_advertising->peer_address;
+ p_adv_params->interval = p_advertising->adv_modes_config.ble_adv_directed_interval;
+
+ return NRF_SUCCESS;
+}
+
+
+/**@brief Function for indicating whether to use whitelist for advertising.
+ *
+ * @param[in] p_advertising Advertising module instance.
+ *
+ * @return Whether to use whitelist.
+ */
+static bool use_whitelist(ble_advertising_t * const p_advertising)
+{
+ return((p_advertising->adv_modes_config.ble_adv_whitelist_enabled) &&
+ (!p_advertising->whitelist_temporarily_disabled) &&
+ (whitelist_has_entries(p_advertising)));
+}
+
+
+/**@brief Function for setting new advertising flags in the advertising parameters.
+ *
+ * @param[in] p_advertising Advertising module instance.
+ * @param[in] flags New flags.
+ *
+ * @return Any error from @ref sd_ble_gap_adv_set_configure.
+ */
+static ret_code_t flags_set(ble_advertising_t * const p_advertising, uint8_t flags)
+{
+ uint8_t * p_flags = ble_advdata_parse(p_advertising->adv_data.adv_data.p_data,
+ p_advertising->adv_data.adv_data.len,
+ BLE_GAP_AD_TYPE_FLAGS);
+
+ if (p_flags != NULL)
+ {
+ *p_flags = flags;
+ }
+
+ return sd_ble_gap_adv_set_configure(&p_advertising->adv_handle, &p_advertising->adv_data, &p_advertising->adv_params);
+}
+
+
+/**@brief Function for starting fast advertising.
+ *
+ * @param[in] p_advertising Advertising module instance.
+ * @param[out] p_adv_params Advertising parameters.
+ *
+ * @return NRF_SUCCESS or an error from @ref flags_set().
+ */
+static ret_code_t set_adv_mode_fast(ble_advertising_t * const p_advertising,
+ ble_gap_adv_params_t * p_adv_params)
+{
+ ret_code_t ret;
+
+ p_adv_params->interval = p_advertising->adv_modes_config.ble_adv_fast_interval;
+ p_adv_params->duration = p_advertising->adv_modes_config.ble_adv_fast_timeout;
+
+#if !defined (S112)
+ if (p_advertising->adv_modes_config.ble_adv_extended_enabled)
+ {
+ p_advertising->adv_params.properties.type = BLE_GAP_ADV_TYPE_EXTENDED_CONNECTABLE_NONSCANNABLE_UNDIRECTED;
+ }
+ else
+ {
+#endif // !defined (S112)
+ p_advertising->adv_params.properties.type = BLE_GAP_ADV_TYPE_CONNECTABLE_SCANNABLE_UNDIRECTED;
+#if !defined (S112)
+ }
+#endif // !defined (S112)
+
+ if (use_whitelist(p_advertising))
+ {
+ p_adv_params->filter_policy = BLE_GAP_ADV_FP_FILTER_CONNREQ;
+
+ // Set correct flags.
+ ret = flags_set(p_advertising, BLE_GAP_ADV_FLAG_BR_EDR_NOT_SUPPORTED);
+ VERIFY_SUCCESS(ret);
+
+ p_advertising->adv_evt = BLE_ADV_EVT_FAST_WHITELIST;
+ }
+ else
+ {
+ p_advertising->adv_evt = BLE_ADV_EVT_FAST;
+ }
+ p_advertising->p_adv_data = &(p_advertising->adv_data);
+ return NRF_SUCCESS;
+}
+
+
+/**@brief Function for starting slow advertising.
+ *
+ * @param[in] p_advertising Advertising module instance.
+ * @param[out] p_adv_params Advertising parameters.
+ *
+ * @return NRF_SUCCESS or an error from @ref flags_set().
+ */
+static ret_code_t set_adv_mode_slow(ble_advertising_t * const p_advertising,
+ ble_gap_adv_params_t * p_adv_params)
+{
+ ret_code_t ret;
+
+ p_adv_params->interval = p_advertising->adv_modes_config.ble_adv_slow_interval;
+ p_adv_params->duration = p_advertising->adv_modes_config.ble_adv_slow_timeout;
+
+#if !defined (S112)
+ if (p_advertising->adv_modes_config.ble_adv_extended_enabled)
+ {
+ p_advertising->adv_params.properties.type = BLE_GAP_ADV_TYPE_EXTENDED_CONNECTABLE_NONSCANNABLE_UNDIRECTED;
+ }
+ else
+ {
+#endif // !defined (S112)
+ p_advertising->adv_params.properties.type = BLE_GAP_ADV_TYPE_CONNECTABLE_SCANNABLE_UNDIRECTED;
+#if !defined (S112)
+ }
+#endif // !defined (S112)
+
+ if (use_whitelist(p_advertising))
+ {
+ p_adv_params->filter_policy = BLE_GAP_ADV_FP_FILTER_CONNREQ;
+
+ // Set correct flags.
+ ret = flags_set(p_advertising, BLE_GAP_ADV_FLAG_BR_EDR_NOT_SUPPORTED);
+ VERIFY_SUCCESS(ret);
+
+ p_advertising->adv_evt = BLE_ADV_EVT_SLOW_WHITELIST;
+ }
+ else
+ {
+ p_advertising->adv_evt = BLE_ADV_EVT_SLOW;
+ }
+ p_advertising->p_adv_data = &(p_advertising->adv_data);
+ return NRF_SUCCESS;
+}
+
+
+/**@brief Function for checking if an advertising module configuration is legal.
+ *
+ * @details Advertising module can not be initialized if high duty directed advertising is used
+ * together with extended advertising.
+ *
+ * @param[in] p_config Pointer to the configuration.
+ *
+ * @return True If the configuration is valid.
+ * @return False If the configuration is invalid.
+ */
+static bool config_is_valid(ble_adv_modes_config_t const * const p_config)
+{
+ if ((p_config->ble_adv_directed_high_duty_enabled == true) &&
+ (p_config->ble_adv_extended_enabled == true))
+ {
+ return false;
+ }
+#if !defined (S140)
+ else if ( p_config->ble_adv_primary_phy == BLE_GAP_PHY_CODED ||
+ p_config->ble_adv_secondary_phy == BLE_GAP_PHY_CODED)
+ {
+ return false;
+ }
+#endif // !defined (S140)
+ else
+ {
+ return true;
+ }
+}
+
+
+void ble_advertising_conn_cfg_tag_set(ble_advertising_t * const p_advertising,
+ uint8_t ble_cfg_tag)
+{
+ p_advertising->conn_cfg_tag = ble_cfg_tag;
+}
+
+
+uint32_t ble_advertising_init(ble_advertising_t * const p_advertising,
+ ble_advertising_init_t const * const p_init)
+{
+ uint32_t ret;
+ if ((p_init == NULL) || (p_advertising == NULL))
+ {
+ return NRF_ERROR_NULL;
+ }
+ if (!config_is_valid(&p_init->config))
+ {
+ return NRF_ERROR_INVALID_PARAM;
+ }
+
+ p_advertising->adv_mode_current = BLE_ADV_MODE_IDLE;
+ p_advertising->adv_modes_config = p_init->config;
+ p_advertising->conn_cfg_tag = BLE_CONN_CFG_TAG_DEFAULT;
+ p_advertising->evt_handler = p_init->evt_handler;
+ p_advertising->error_handler = p_init->error_handler;
+ p_advertising->current_slave_link_conn_handle = BLE_CONN_HANDLE_INVALID;
+ p_advertising->p_adv_data = &p_advertising->adv_data;
+
+ memset(&p_advertising->peer_address, 0, sizeof(p_advertising->peer_address));
+
+ // Copy advertising data.
+ if (!p_advertising->initialized)
+ {
+ p_advertising->adv_handle = BLE_GAP_ADV_SET_HANDLE_NOT_SET;
+ }
+ p_advertising->adv_data.adv_data.p_data = p_advertising->enc_advdata;
+ p_advertising->adv_data.adv_data.len = BLE_GAP_ADV_SET_DATA_SIZE_MAX;
+
+ ret = ble_advdata_encode(&p_init->advdata, p_advertising->enc_advdata, &p_advertising->adv_data.adv_data.len);
+ VERIFY_SUCCESS(ret);
+
+ if (&p_init->srdata != NULL)
+ {
+ p_advertising->adv_data.scan_rsp_data.p_data = p_advertising->enc_scan_rsp_data;
+ p_advertising->adv_data.scan_rsp_data.len = BLE_GAP_ADV_SET_DATA_SIZE_MAX;
+
+ ret = ble_advdata_encode(&p_init->srdata,
+ p_advertising->adv_data.scan_rsp_data.p_data,
+ &p_advertising->adv_data.scan_rsp_data.len);
+ VERIFY_SUCCESS(ret);
+ }
+ else
+ {
+ p_advertising->adv_data.scan_rsp_data.p_data = NULL;
+ p_advertising->adv_data.scan_rsp_data.len = 0;
+ }
+
+ // Configure a initial advertising configuration. The advertising data and and advertising
+ // parameters will be changed later when we call @ref ble_advertising_start, but must be set
+ // to legal values here to define an advertising handle.
+ p_advertising->adv_params.primary_phy = BLE_GAP_PHY_1MBPS;
+ p_advertising->adv_params.duration = p_advertising->adv_modes_config.ble_adv_fast_timeout;
+ p_advertising->adv_params.properties.type = BLE_GAP_ADV_TYPE_CONNECTABLE_SCANNABLE_UNDIRECTED;
+ p_advertising->adv_params.p_peer_addr = NULL;
+ p_advertising->adv_params.filter_policy = BLE_GAP_ADV_FP_ANY;
+ p_advertising->adv_params.interval = p_advertising->adv_modes_config.ble_adv_fast_interval;
+
+ ret = sd_ble_gap_adv_set_configure(&p_advertising->adv_handle, NULL, &p_advertising->adv_params);
+ VERIFY_SUCCESS(ret);
+
+ p_advertising->initialized = true;
+ return ret;
+}
+
+
+/**@brief Function for checking that a phy define value matches one of the valid phys from the SD.
+ *
+ * @param[in] PHY to be validated.
+ *
+ * @retval true If the PHY value is valid (1mbit, 2mbit, coded).
+ * @retval false If the PHY value is invalid.
+ */
+static bool phy_is_valid(uint32_t const * const p_phy)
+{
+ if ((*p_phy) == BLE_GAP_PHY_1MBPS ||
+ (*p_phy) == BLE_GAP_PHY_2MBPS
+#if defined (S140)
+ || (*p_phy) == BLE_GAP_PHY_CODED
+#endif // !defined (S140)
+ )
+ {
+ return true;
+ }
+ else
+ {
+ return false;
+ }
+}
+
+
+uint32_t ble_advertising_start(ble_advertising_t * const p_advertising,
+ ble_adv_mode_t advertising_mode)
+{
+ uint32_t ret;
+
+ if (p_advertising->initialized == false)
+ {
+ return NRF_ERROR_INVALID_STATE;
+ }
+
+ p_advertising->adv_mode_current = advertising_mode;
+
+ // Delay starting advertising until the flash operations are complete.
+ if (flash_access_in_progress())
+ {
+ p_advertising->advertising_start_pending = true;
+ return NRF_SUCCESS;
+ }
+
+ memset(&p_advertising->peer_address, 0, sizeof(p_advertising->peer_address));
+
+ if ( ((p_advertising->adv_modes_config.ble_adv_directed_high_duty_enabled) && (p_advertising->adv_mode_current == BLE_ADV_MODE_DIRECTED_HIGH_DUTY))
+ ||((p_advertising->adv_modes_config.ble_adv_directed_enabled) && (p_advertising->adv_mode_current == BLE_ADV_MODE_DIRECTED_HIGH_DUTY))
+ ||((p_advertising->adv_modes_config.ble_adv_directed_enabled) && (p_advertising->adv_mode_current == BLE_ADV_MODE_DIRECTED))
+ )
+ {
+ if (p_advertising->evt_handler != NULL)
+ {
+ p_advertising->peer_addr_reply_expected = true;
+ p_advertising->evt_handler(BLE_ADV_EVT_PEER_ADDR_REQUEST);
+ }
+ else
+ {
+ p_advertising->peer_addr_reply_expected = false;
+ }
+ }
+
+ p_advertising->adv_mode_current = adv_mode_next_avail_get(p_advertising, advertising_mode);
+
+ // Fetch the whitelist.
+ if ((p_advertising->evt_handler != NULL) &&
+ (p_advertising->adv_mode_current == BLE_ADV_MODE_FAST || p_advertising->adv_mode_current == BLE_ADV_MODE_SLOW) &&
+ (p_advertising->adv_modes_config.ble_adv_whitelist_enabled) &&
+ (!p_advertising->whitelist_temporarily_disabled))
+ {
+ p_advertising->whitelist_in_use = false;
+ p_advertising->whitelist_reply_expected = true;
+ p_advertising->evt_handler(BLE_ADV_EVT_WHITELIST_REQUEST);
+ }
+ else
+ {
+ p_advertising->whitelist_reply_expected = false;
+ }
+
+ // Initialize advertising parameters with default values.
+ memset(&p_advertising->adv_params, 0, sizeof(p_advertising->adv_params));
+
+ p_advertising->adv_params.properties.type = BLE_GAP_ADV_TYPE_CONNECTABLE_SCANNABLE_UNDIRECTED;
+
+ // Use 1MBIT as primary phy if no phy was selected.
+ if (phy_is_valid(&p_advertising->adv_modes_config.ble_adv_primary_phy))
+ {
+ p_advertising->adv_params.primary_phy = p_advertising->adv_modes_config.ble_adv_primary_phy;
+ }
+ else
+ {
+ p_advertising->adv_params.primary_phy = BLE_GAP_PHY_1MBPS;
+ }
+
+ if (p_advertising->adv_modes_config.ble_adv_extended_enabled)
+ {
+ // Use 1MBIT as secondary phy if no phy was selected.
+ if (phy_is_valid(&p_advertising->adv_modes_config.ble_adv_primary_phy))
+ {
+ p_advertising->adv_params.secondary_phy = p_advertising->adv_modes_config.ble_adv_secondary_phy;
+ }
+ else
+ {
+ p_advertising->adv_params.secondary_phy = BLE_GAP_PHY_1MBPS;
+ }
+ }
+ p_advertising->adv_params.filter_policy = BLE_GAP_ADV_FP_ANY;
+
+ // Set advertising parameters and events according to selected advertising mode.
+ switch (p_advertising->adv_mode_current)
+ {
+ case BLE_ADV_MODE_DIRECTED_HIGH_DUTY:
+ ret = set_adv_mode_directed_high_duty(p_advertising, &p_advertising->adv_params);
+ break;
+
+ case BLE_ADV_MODE_DIRECTED:
+ ret = set_adv_mode_directed(p_advertising, &p_advertising->adv_params);
+ break;
+
+ case BLE_ADV_MODE_FAST:
+ ret = set_adv_mode_fast(p_advertising, &p_advertising->adv_params);
+ break;
+
+ case BLE_ADV_MODE_SLOW:
+ ret = set_adv_mode_slow(p_advertising, &p_advertising->adv_params);
+ break;
+
+ case BLE_ADV_MODE_IDLE:
+ p_advertising->adv_evt = BLE_ADV_EVT_IDLE;
+ break;
+
+ default:
+ break;
+ }
+
+ if (p_advertising->adv_mode_current != BLE_ADV_MODE_IDLE)
+ {
+
+ ret = sd_ble_gap_adv_set_configure(&p_advertising->adv_handle, p_advertising->p_adv_data, &p_advertising->adv_params);
+ if (ret != NRF_SUCCESS)
+ {
+ return ret;
+ }
+ ret = sd_ble_gap_adv_start(p_advertising->adv_handle, p_advertising->conn_cfg_tag);
+
+ if (ret != NRF_SUCCESS)
+ {
+ return ret;
+ }
+ }
+
+ if (p_advertising->evt_handler != NULL)
+ {
+ p_advertising->evt_handler(p_advertising->adv_evt);
+ }
+
+ return NRF_SUCCESS;
+}
+
+
+void ble_advertising_on_ble_evt(ble_evt_t const * p_ble_evt, void * p_context)
+{
+ ble_advertising_t * p_advertising = (ble_advertising_t *)p_context;
+
+ switch (p_ble_evt->header.evt_id)
+ {
+ case BLE_GAP_EVT_CONNECTED:
+ on_connected(p_advertising, p_ble_evt);
+ break;
+
+ // Upon disconnection, whitelist will be activated and direct advertising is started.
+ case BLE_GAP_EVT_DISCONNECTED:
+ on_disconnected(p_advertising, p_ble_evt);
+ break;
+
+ // Upon terminated advertising (time-out), the next advertising mode is started.
+ case BLE_GAP_EVT_ADV_SET_TERMINATED:
+ on_terminated(p_advertising, p_ble_evt);
+ break;
+
+ default:
+ break;
+ }
+}
+
+
+void ble_advertising_on_sys_evt(uint32_t evt_id, void * p_context)
+{
+ ble_advertising_t * p_advertising = (ble_advertising_t *)p_context;
+
+ switch (evt_id)
+ {
+ //When a flash operation finishes, re-attempt to start advertising operations.
+ case NRF_EVT_FLASH_OPERATION_SUCCESS:
+ case NRF_EVT_FLASH_OPERATION_ERROR:
+ {
+ if (p_advertising->advertising_start_pending)
+ {
+ p_advertising->advertising_start_pending = false;
+ ret_code_t ret = ble_advertising_start(p_advertising,
+ p_advertising->adv_mode_current);
+
+ if ((ret != NRF_SUCCESS) && (p_advertising->error_handler != NULL))
+ {
+ p_advertising->error_handler(ret);
+ }
+ }
+ } break;
+
+ default:
+ // No implementation needed.
+ break;
+ }
+}
+
+
+uint32_t ble_advertising_peer_addr_reply(ble_advertising_t * const p_advertising,
+ ble_gap_addr_t * p_peer_address)
+{
+ if (!p_advertising->peer_addr_reply_expected)
+ {
+ return NRF_ERROR_INVALID_STATE;
+ }
+
+ p_advertising->peer_addr_reply_expected = false;
+
+ memcpy(&p_advertising->peer_address, p_peer_address, sizeof(p_advertising->peer_address));
+
+ return NRF_SUCCESS;
+}
+
+
+uint32_t ble_advertising_whitelist_reply(ble_advertising_t * const p_advertising,
+ ble_gap_addr_t const * p_gap_addrs,
+ uint32_t addr_cnt,
+ ble_gap_irk_t const * p_gap_irks,
+ uint32_t irk_cnt)
+{
+ if (!p_advertising->whitelist_reply_expected)
+ {
+ return NRF_ERROR_INVALID_STATE;
+ }
+
+ p_advertising->whitelist_reply_expected = false;
+ p_advertising->whitelist_in_use = ((addr_cnt > 0) || (irk_cnt > 0));
+
+ return NRF_SUCCESS;
+}
+
+
+uint32_t ble_advertising_restart_without_whitelist(ble_advertising_t * const p_advertising)
+{
+ ret_code_t ret;
+
+ (void) sd_ble_gap_adv_stop(p_advertising->adv_handle);
+
+ p_advertising->whitelist_temporarily_disabled = true;
+ p_advertising->whitelist_in_use = false;
+ p_advertising->adv_params.filter_policy = BLE_GAP_ADV_FP_ANY;
+ // Set correct flags.
+ ret = flags_set(p_advertising, BLE_GAP_ADV_FLAGS_LE_ONLY_GENERAL_DISC_MODE);
+ VERIFY_SUCCESS(ret);
+
+ ret = ble_advertising_start(p_advertising, p_advertising->adv_mode_current);
+ if ((ret != NRF_SUCCESS) && (p_advertising->error_handler != NULL))
+ {
+ p_advertising->error_handler(ret);
+ }
+
+ return NRF_SUCCESS;
+}
+
+
+void ble_advertising_modes_config_set(ble_advertising_t * const p_advertising,
+ ble_adv_modes_config_t const * const p_adv_modes_config)
+{
+ p_advertising->adv_modes_config = *p_adv_modes_config;
+}
+
+
+#endif // NRF_MODULE_ENABLED(BLE_ADVERTISING)
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_advertising/ble_advertising.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_advertising/ble_advertising.h
new file mode 100644
index 0000000..8840821
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_advertising/ble_advertising.h
@@ -0,0 +1,337 @@
+/**
+ * Copyright (c) 2015 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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
+ *
+ * @defgroup ble_advertising Advertising Module
+ * @{
+ * @ingroup ble_sdk_lib
+ * @brief Module for handling connectable BLE advertising.
+ *
+ * @details The Advertising Module handles connectable advertising for your application. It can
+ * be configured with advertising modes to suit most typical use cases.
+ * Your main application can react to changes in advertising modes
+ * if an event handler is provided.
+ *
+ * @note The Advertising Module supports only applications with a single peripheral link.
+ *
+ */
+
+#ifndef BLE_ADVERTISING_H__
+#define BLE_ADVERTISING_H__
+
+#include <stdint.h>
+#include "nrf_error.h"
+#include "ble.h"
+#include "ble_gattc.h"
+#include "ble_advdata.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**@brief Macro for defining a ble_advertising instance.
+ *
+ * @param _name Name of the instance.
+ * @hideinitializer
+ */
+#define BLE_ADVERTISING_DEF(_name) \
+static ble_advertising_t _name; \
+NRF_SDH_BLE_OBSERVER(_name ## _ble_obs, \
+ BLE_ADV_BLE_OBSERVER_PRIO, \
+ ble_advertising_on_ble_evt, &_name); \
+NRF_SDH_SOC_OBSERVER(_name ## _soc_obs, \
+ BLE_ADV_SOC_OBSERVER_PRIO, \
+ ble_advertising_on_sys_evt, &_name)
+
+
+/**@brief Advertising modes. */
+typedef enum
+{
+ BLE_ADV_MODE_IDLE, /**< Idle; no connectable advertising is ongoing. */
+ BLE_ADV_MODE_DIRECTED_HIGH_DUTY, /**< Directed advertising (high duty cycle) attempts to connect to the most recently disconnected peer. */
+ BLE_ADV_MODE_DIRECTED, /**< Directed advertising (low duty cycle) attempts to connect to the most recently disconnected peer. */
+ BLE_ADV_MODE_FAST, /**< Fast advertising will connect to any peer device, or filter with a whitelist if one exists. */
+ BLE_ADV_MODE_SLOW, /**< Slow advertising is similar to fast advertising. By default, it uses a longer advertising interval and time-out than fast advertising. However, these options are defined by the user. */
+} ble_adv_mode_t;
+
+/**@brief Advertising events.
+ *
+ * @details These events are propagated to the main application if a handler was provided during
+ * initialization of the Advertising Module. Events for modes that are not used can be
+ * ignored. Similarly, BLE_ADV_EVT_WHITELIST_REQUEST and BLE_ADV_EVT_PEER_ADDR_REQUEST
+ * can be ignored if whitelist and direct advertising is not used.
+ */
+typedef enum
+{
+ BLE_ADV_EVT_IDLE, /**< Idle; no connectable advertising is ongoing.*/
+ BLE_ADV_EVT_DIRECTED_HIGH_DUTY, /**< Direct advertising mode has started. */
+ BLE_ADV_EVT_DIRECTED, /**< Directed advertising (low duty cycle) has started. */
+ BLE_ADV_EVT_FAST, /**< Fast advertising mode has started. */
+ BLE_ADV_EVT_SLOW, /**< Slow advertising mode has started. */
+ BLE_ADV_EVT_FAST_WHITELIST, /**< Fast advertising mode using the whitelist has started. */
+ BLE_ADV_EVT_SLOW_WHITELIST, /**< Slow advertising mode using the whitelist has started. */
+ BLE_ADV_EVT_WHITELIST_REQUEST, /**< Request a whitelist from the main application. For whitelist advertising to work, the whitelist must be set when this event occurs. */
+ BLE_ADV_EVT_PEER_ADDR_REQUEST /**< Request a peer address from the main application. For directed advertising to work, the peer address must be set when this event occurs. */
+} ble_adv_evt_t;
+
+/**@brief Options for the different advertisement modes.
+ *
+ * @details This structure is used to enable or disable advertising modes and to configure time-out
+ * periods and advertising intervals.
+ */
+typedef struct
+{
+ bool ble_adv_on_disconnect_disabled; /**< Enable or disable automatic return to advertising upon disconnecting.*/
+ bool ble_adv_whitelist_enabled; /**< Enable or disable use of the whitelist. */
+ bool ble_adv_directed_high_duty_enabled; /**< Enable or disable direct advertising mode. can only be used if ble_adv_legacy_enabled is true. */
+ bool ble_adv_directed_enabled; /**< Enable or disable direct advertising mode. */
+ bool ble_adv_fast_enabled; /**< Enable or disable fast advertising mode. */
+ bool ble_adv_slow_enabled; /**< Enable or disable slow advertising mode. */
+ uint32_t ble_adv_directed_interval; /**< Advertising interval for directed advertising. */
+ uint32_t ble_adv_directed_timeout; /**< Time-out (number of tries) for direct advertising. */
+ uint32_t ble_adv_fast_interval; /**< Advertising interval for fast advertising. */
+ uint32_t ble_adv_fast_timeout; /**< Time-out (in seconds) for fast advertising. */
+ uint32_t ble_adv_slow_interval; /**< Advertising interval for slow advertising. */
+ uint32_t ble_adv_slow_timeout; /**< Time-out (in seconds) for slow advertising. */
+ bool ble_adv_extended_enabled; /**< Enable or disable extended advertising. */
+ uint32_t ble_adv_secondary_phy; /**< PHY for the secondary (extended) advertising @ref BLE_GAP_PHYS (BLE_GAP_PHY_1MBPS, BLE_GAP_PHY_2MBPS or BLE_GAP_PHY_CODED). */
+ uint32_t ble_adv_primary_phy; /**< PHY for the primary advertising. @ref BLE_GAP_PHYS (BLE_GAP_PHY_1MBPS, BLE_GAP_PHY_2MBPS or BLE_GAP_PHY_CODED). */
+} ble_adv_modes_config_t;
+
+/**@brief BLE advertising event handler type. */
+typedef void (*ble_adv_evt_handler_t) (ble_adv_evt_t const adv_evt);
+
+/**@brief BLE advertising error handler type. */
+typedef void (*ble_adv_error_handler_t) (uint32_t nrf_error);
+
+typedef struct
+{
+ bool initialized;
+ bool advertising_start_pending; /**< Flag to keep track of ongoing operations in flash. */
+ ble_adv_mode_t adv_mode_current; /**< Variable to keep track of the current advertising mode. */
+ ble_adv_modes_config_t adv_modes_config; /**< Struct to keep track of disabled and enabled advertising modes, as well as time-outs and intervals.*/
+ uint8_t conn_cfg_tag; /**< Variable to keep track of what connection settings will be used if the advertising results in a connection. */
+
+ ble_adv_evt_t adv_evt; /**< Advertising event propogated to the main application. The event is either a transaction to a new advertising mode, or a request for whitelist or peer address. */
+ ble_adv_evt_handler_t evt_handler; /**< Handler for the advertising events. Can be initialized as NULL if no handling is implemented on in the main application. */
+ ble_adv_error_handler_t error_handler; /**< Handler for the advertising error events. */
+
+ ble_gap_adv_params_t adv_params; /**< GAP advertising parameters. */
+ uint8_t adv_handle; /**< Handle for the advertising set. */
+ uint8_t enc_advdata[BLE_GAP_ADV_SET_DATA_SIZE_MAX]; /**< Current advertising data in encoded form. */
+ uint8_t enc_scan_rsp_data[BLE_GAP_ADV_SET_DATA_SIZE_MAX]; /**< Current scan response data in encoded form. */
+ ble_gap_adv_data_t adv_data; /**< Advertising data. */
+ ble_gap_adv_data_t *p_adv_data; /**< Will be set to point to @ref ble_advertising_t::adv_data for undirected advertising, and will be set to NULL for directed advertising. */
+
+ uint16_t current_slave_link_conn_handle; /**< Connection handle for the active link. */
+ ble_gap_addr_t peer_address; /**< Address of the most recently connected peer, used for direct advertising. */
+ bool peer_addr_reply_expected; /**< Flag to verify that peer address is only set when requested. */
+ bool whitelist_temporarily_disabled; /**< Flag to keep track of temporary disabling of the whitelist. */
+ bool whitelist_reply_expected; /**< Flag to verify that the whitelist is only set when requested. */
+ bool whitelist_in_use; /**< This module needs to be aware of whether or not a whitelist has been set (e.g. using the Peer Manager) in order to start advertising with the proper advertising params (filter policy). */
+} ble_advertising_t;
+
+typedef struct
+{
+ uint32_t interval;
+ uint32_t timeout;
+ bool enabled;
+} ble_adv_mode_config_t;
+
+/**@brief Initialization parameters for the Advertising Module.
+ * @details This structure is used to pass advertising options, advertising data,
+ * and an event handler to the Advertising Module during initialization.
+ */
+typedef struct
+{
+ ble_advdata_t advdata; /**< Advertising data: name, appearance, discovery flags, and more. */
+ ble_advdata_t srdata; /**< Scan response data: Supplement to advertising data. */
+ ble_adv_modes_config_t config; /**< Select which advertising modes and intervals will be utilized.*/
+ ble_adv_evt_handler_t evt_handler; /**< Event handler that will be called upon advertising events. */
+ ble_adv_error_handler_t error_handler; /**< Error handler that will propogate internal errors to the main applications. */
+} ble_advertising_init_t;
+
+
+/**@brief Function for handling BLE events.
+ *
+ * @details This function must be called from the BLE stack event dispatcher for
+ * the module to handle BLE events that are relevant for the Advertising Module.
+ *
+ * @param[in] p_ble_evt BLE stack event.
+ * @param[in] p_adv Advertising module instance.
+ */
+void ble_advertising_on_ble_evt(ble_evt_t const * p_ble_evt, void * p_adv);
+
+
+/**@brief Function for handling system events.
+ *
+ * @details This function must be called to handle system events that are relevant
+ * for the Advertising Module. Specifically, the advertising module can not use the
+ * softdevice as long as there are pending writes to the flash memory. This
+ * event handler is designed to delay advertising until there is no flash operation.
+ *
+ * @param[in] sys_evt System event.
+ * @param[in] p_adv Advertising module instance.
+ */
+void ble_advertising_on_sys_evt(uint32_t sys_evt, void * p_adv);
+
+
+/**@brief Function for initializing the Advertising Module.
+ *
+ * @details Encodes the required advertising data and passes it to the stack.
+ * Also builds a structure to be passed to the stack when starting advertising.
+ * The supplied advertising data is copied to a local structure and is manipulated
+ * depending on what advertising modes are started in @ref ble_advertising_start.
+ *
+ * @param[out] p_advertising Advertising module instance. This structure must be supplied by
+ * the application. It is initialized by this function and will later
+ * be used to identify this particular module instance.
+ * @param[in] p_init Information needed to initialize the module.
+ *
+ * @retval NRF_SUCCESS If initialization was successful.
+ * @retval NRF_ERROR_INVALID_PARAM If the advertising configuration in \p p_init is invalid.
+ * @return If functions from other modules return errors to this function, the @ref nrf_error are propagated.
+ */
+uint32_t ble_advertising_init(ble_advertising_t * const p_advertising,
+ ble_advertising_init_t const * const p_init);
+
+
+ /**@brief Function for changing the connection settings tag that will be used for upcoming connections.
+ *
+ * @details See @ref sd_ble_cfg_set for more details about changing connection settings. If this
+ * function is never called, @ref BLE_CONN_CFG_TAG_DEFAULT will be used.
+ *
+ * @param[in] p_advertising Advertising module instance.
+ * @param[in] ble_cfg_tag Configuration for the connection settings (see @ref sd_ble_cfg_set).
+ */
+void ble_advertising_conn_cfg_tag_set(ble_advertising_t * const p_advertising, uint8_t ble_cfg_tag);
+
+/**@brief Function for starting advertising.
+ *
+ * @details You can start advertising in any of the advertising modes that you enabled
+ * during initialization.
+ *
+ * @param[in] p_advertising Advertising module instance.
+ * @param[in] advertising_mode Advertising mode.
+ *
+ * @retval @ref NRF_SUCCESS On success, else an error code indicating reason for failure.
+ * @retval @ref NRF_ERROR_INVALID_STATE If the module is not initialized.
+ */
+uint32_t ble_advertising_start(ble_advertising_t * const p_advertising,
+ ble_adv_mode_t advertising_mode);
+
+
+/**@brief Function for setting the peer address.
+ *
+ * @details The peer address must be set by the application upon receiving a
+ * @ref BLE_ADV_EVT_PEER_ADDR_REQUEST event. Without the peer address, the directed
+ * advertising mode will not be run.
+ *
+ * @param[in] p_advertising Advertising module instance.
+ * @param[in] p_peer_addr Pointer to a peer address.
+ *
+ * @retval @ref NRF_SUCCESS Successfully stored the peer address pointer in the advertising module.
+ * @retval @ref NRF_ERROR_INVALID_STATE If a reply was not expected.
+ */
+uint32_t ble_advertising_peer_addr_reply(ble_advertising_t * const p_advertising,
+ ble_gap_addr_t * p_peer_addr);
+
+
+/**@brief Function for setting a whitelist.
+ *
+ * @details The whitelist must be set by the application upon receiving a
+ * @ref BLE_ADV_EVT_WHITELIST_REQUEST event. Without the whitelist, the whitelist
+ * advertising for fast and slow modes will not be run.
+ *
+ * @param[in] p_advertising Advertising module instance.
+ * @param[in] p_gap_addrs The list of GAP addresses to whitelist.
+ * @param[in] addr_cnt The number of GAP addresses to whitelist.
+ * @param[in] p_gap_irks The list of peer IRK to whitelist.
+ * @param[in] irk_cnt The number of peer IRK to whitelist.
+ *
+ * @retval @ref NRF_SUCCESS If the operation was successful.
+ * @retval @ref NRF_ERROR_INVALID_STATE If a call to this function was made without a
+ * BLE_ADV_EVT_WHITELIST_REQUEST event being received.
+ */
+uint32_t ble_advertising_whitelist_reply(ble_advertising_t * const p_advertising,
+ ble_gap_addr_t const * p_gap_addrs,
+ uint32_t addr_cnt,
+ ble_gap_irk_t const * p_gap_irks,
+ uint32_t irk_cnt);
+
+
+/**@brief Function for disabling whitelist advertising.
+ *
+ * @details This function temporarily disables whitelist advertising.
+ * Calling this function resets the current time-out countdown.
+ *
+ * @param[in] p_advertising Advertising module instance.
+ *
+ * @retval @ref NRF_SUCCESS On success, else an error message propogated from the Softdevice.
+ */
+uint32_t ble_advertising_restart_without_whitelist(ble_advertising_t * const p_advertising);
+
+
+/**@brief Function for changing advertising modes configuration.
+ *
+ * @details This function can be called if you wish to reconfigure the advertising modes that the
+ * advertising module will cycle through. Enable or disable modes as listed in
+ * @ref ble_adv_mode_t; or change the duration of the advertising and use of whitelist.
+ *
+ * Keep in mind that @ref ble_adv_modes_config_t is also supplied when calling
+ * @ref ble_advertising_init. Calling @ref ble_advertising_modes_config_set
+ * is only necessary if your application requires this behaviour to change.
+ *
+ * @param[in] p_advertising Advertising module instance.
+ * @param[in] p_adv_modes_config Struct to keep track of disabled and enabled advertising modes,
+ * as well as time-outs and intervals.
+ */
+void ble_advertising_modes_config_set(ble_advertising_t * const p_advertising,
+ ble_adv_modes_config_t const * const p_adv_modes_config);
+/** @} */
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // BLE_ADVERTISING_H__
+
+/** @} */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_db_discovery/ble_db_discovery.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_db_discovery/ble_db_discovery.c
new file mode 100644
index 0000000..5ae6e20
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_db_discovery/ble_db_discovery.c
@@ -0,0 +1,986 @@
+/**
+ * Copyright (c) 2013 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+
+#include "sdk_common.h"
+
+#if NRF_MODULE_ENABLED(BLE_DB_DISCOVERY)
+#include "ble_db_discovery.h"
+#include <stdlib.h>
+#include "ble_srv_common.h"
+#define NRF_LOG_MODULE_NAME ble_db_disc
+#include "nrf_log.h"
+NRF_LOG_MODULE_REGISTER();
+
+#define SRV_DISC_START_HANDLE 0x0001 /**< The start handle value used during service discovery. */
+#define DB_DISCOVERY_MAX_USERS BLE_DB_DISCOVERY_MAX_SRV /**< The maximum number of users/registrations allowed by this module. */
+#define MODULE_INITIALIZED (m_initialized == true) /**< Macro designating whether the module has been initialized properly. */
+
+
+/**@brief Array of structures containing information about the registered application modules. */
+static ble_uuid_t m_registered_handlers[DB_DISCOVERY_MAX_USERS];
+
+
+/**@brief Array of structures containing pending events to be sent to the application modules.
+ *
+ * @details Whenever a discovery related event is to be raised to a user module, it will be stored
+ * in this array first. When all services needed to be discovered have been
+ * discovered, all pending events will be sent to the corresponding user modules.
+ **/
+static struct
+{
+ ble_db_discovery_evt_t evt; /**< The pending event. */
+ ble_db_discovery_evt_handler_t evt_handler; /**< The event handler which should be called to raise this event. */
+} m_pending_user_evts[DB_DISCOVERY_MAX_USERS];
+
+static ble_db_discovery_evt_handler_t m_evt_handler;
+static uint32_t m_pending_usr_evt_index; /**< The index to the pending user event array, pointing to the last added pending user event. */
+static uint32_t m_num_of_handlers_reg; /**< The number of handlers registered with the DB Discovery module. */
+static bool m_initialized = false; /**< This variable Indicates if the module is initialized or not. */
+
+/**@brief Function for fetching the event handler provided by a registered application module.
+ *
+ * @param[in] srv_uuid UUID of the service.
+ *
+ * @retval evt_handler Event handler of the module, registered for the given service UUID.
+ * @retval NULL If no event handler is found.
+ */
+static ble_db_discovery_evt_handler_t registered_handler_get(ble_uuid_t const * p_srv_uuid)
+{
+ for (uint32_t i = 0; i < m_num_of_handlers_reg; i++)
+ {
+ if (BLE_UUID_EQ(&(m_registered_handlers[i]), p_srv_uuid))
+ {
+ return (m_evt_handler);
+ }
+ }
+
+ return NULL;
+}
+
+
+/**@brief Function for storing the event handler provided by a registered application module.
+ *
+ * @param[in] p_srv_uuid The UUID of the service.
+ * @param[in] p_evt_handler The event handler provided by the application.
+ *
+ * @retval NRF_SUCCESS If the handler was stored or already present in the list.
+ * @retval NRF_ERROR_NO_MEM If there is no space left to store the handler.
+ */
+static uint32_t registered_handler_set(ble_uuid_t const * p_srv_uuid,
+ ble_db_discovery_evt_handler_t p_evt_handler)
+{
+ if (registered_handler_get(p_srv_uuid) != NULL)
+ {
+ return NRF_SUCCESS;
+ }
+
+ if (m_num_of_handlers_reg < DB_DISCOVERY_MAX_USERS)
+ {
+ m_registered_handlers[m_num_of_handlers_reg] = *p_srv_uuid;
+ m_num_of_handlers_reg++;
+
+ return NRF_SUCCESS;
+ }
+ else
+ {
+ return NRF_ERROR_NO_MEM;
+ }
+}
+
+
+/**@brief Function for sending all pending discovery events to the corresponding user modules.
+ */
+static void pending_user_evts_send(void)
+{
+ for (uint32_t i = 0; i < m_num_of_handlers_reg; i++)
+ {
+ // Pass the event to the corresponding event handler.
+ m_pending_user_evts[i].evt_handler(&(m_pending_user_evts[i].evt));
+ }
+
+ m_pending_usr_evt_index = 0;
+}
+
+
+/**@brief Function for indicating error to the application.
+ *
+ * @details This function will fetch the event handler based on the UUID of the service being
+ * discovered. (The event handler is registered by the application beforehand).
+ * The error code is added to the pending events together with the event handler.
+ * If no event handler was found, then this function will do nothing.
+ *
+ * @param[in] p_db_discovery Pointer to the DB discovery structure.
+ * @param[in] err_code Error code that should be provided to the application.
+ * @param[in] conn_handle Connection Handle.
+ *
+ */
+static void discovery_error_evt_trigger(ble_db_discovery_t * p_db_discovery,
+ uint32_t err_code,
+ uint16_t conn_handle)
+{
+ ble_db_discovery_evt_handler_t p_evt_handler;
+ ble_gatt_db_srv_t * p_srv_being_discovered;
+
+ p_srv_being_discovered = &(p_db_discovery->services[p_db_discovery->curr_srv_ind]);
+
+ p_evt_handler = registered_handler_get(&(p_srv_being_discovered->srv_uuid));
+
+ if (p_evt_handler != NULL)
+ {
+ ble_db_discovery_evt_t evt =
+ {
+ .conn_handle = conn_handle,
+ .evt_type = BLE_DB_DISCOVERY_ERROR,
+ .params.err_code = err_code,
+ };
+
+ p_evt_handler(&evt);
+ }
+}
+
+
+/**@brief Function for triggering a Discovery Complete or Service Not Found event to the
+ * application.
+ *
+ * @details This function will fetch the event handler based on the UUID of the service being
+ * discovered. (The event handler is registered by the application beforehand).
+ * It then triggers an event indicating the completion of the service discovery.
+ * If no event handler was found, then this function will do nothing.
+ *
+ * @param[in] p_db_discovery Pointer to the DB discovery structure.
+ * @param[in] is_srv_found Variable to indicate if the service was found at the peer.
+ * @param[in] conn_handle Connection Handle.
+ */
+static void discovery_complete_evt_trigger(ble_db_discovery_t * p_db_discovery,
+ bool is_srv_found,
+ uint16_t conn_handle)
+{
+ ble_db_discovery_evt_handler_t p_evt_handler;
+ ble_gatt_db_srv_t * p_srv_being_discovered;
+
+ p_srv_being_discovered = &(p_db_discovery->services[p_db_discovery->curr_srv_ind]);
+
+ p_evt_handler = registered_handler_get(&(p_srv_being_discovered->srv_uuid));
+
+ if (p_evt_handler != NULL)
+ {
+ if (m_pending_usr_evt_index < DB_DISCOVERY_MAX_USERS)
+ {
+ // Insert an event into the pending event list.
+ m_pending_user_evts[m_pending_usr_evt_index].evt.conn_handle = conn_handle;
+ m_pending_user_evts[m_pending_usr_evt_index].evt.params.discovered_db =
+ *p_srv_being_discovered;
+
+ if (is_srv_found)
+ {
+ m_pending_user_evts[m_pending_usr_evt_index].evt.evt_type =
+ BLE_DB_DISCOVERY_COMPLETE;
+ }
+ else
+ {
+ m_pending_user_evts[m_pending_usr_evt_index].evt.evt_type =
+ BLE_DB_DISCOVERY_SRV_NOT_FOUND;
+ }
+
+ m_pending_user_evts[m_pending_usr_evt_index].evt_handler = p_evt_handler;
+ m_pending_usr_evt_index++;
+
+ if (m_pending_usr_evt_index == m_num_of_handlers_reg)
+ {
+ // All registered modules have pending events. Send all pending events to the user
+ // modules.
+ pending_user_evts_send();
+ }
+ else
+ {
+ // Too many events pending. Do nothing. (Ideally this should not happen.)
+ }
+ }
+ }
+}
+
+
+/**@brief Function for handling service discovery completion.
+ *
+ * @details This function will be used to determine if there are more services to be discovered,
+ * and if so, initiate the discovery of the next service.
+ *
+ * @param[in] p_db_discovery Pointer to the DB Discovery Structure.
+ * @param[in] conn_handle Connection Handle.
+ */
+static void on_srv_disc_completion(ble_db_discovery_t * p_db_discovery,
+ uint16_t conn_handle)
+{
+ p_db_discovery->discoveries_count++;
+
+ // Check if more services need to be discovered.
+ if (p_db_discovery->discoveries_count < m_num_of_handlers_reg)
+ {
+ // Reset the current characteristic index since a new service discovery is about to start.
+ p_db_discovery->curr_char_ind = 0;
+
+ // Initiate discovery of the next service.
+ p_db_discovery->curr_srv_ind++;
+
+ ble_gatt_db_srv_t * p_srv_being_discovered;
+
+ p_srv_being_discovered = &(p_db_discovery->services[p_db_discovery->curr_srv_ind]);
+
+ p_srv_being_discovered->srv_uuid = m_registered_handlers[p_db_discovery->curr_srv_ind];
+
+ // Reset the characteristic count in the current service to zero since a new service
+ // discovery is about to start.
+ p_srv_being_discovered->char_count = 0;
+
+ NRF_LOG_DEBUG("Starting discovery of service with UUID 0x%x on connection handle 0x%x.",
+ p_srv_being_discovered->srv_uuid.uuid, conn_handle);
+
+ uint32_t err_code;
+
+ err_code = sd_ble_gattc_primary_services_discover(conn_handle,
+ SRV_DISC_START_HANDLE,
+ &(p_srv_being_discovered->srv_uuid));
+
+ if (err_code != NRF_SUCCESS)
+ {
+ p_db_discovery->discovery_in_progress = false;
+
+ // Error with discovering the service.
+ // Indicate the error to the registered user application.
+ discovery_error_evt_trigger(p_db_discovery, err_code, conn_handle);
+
+ m_pending_user_evts[0].evt.evt_type = BLE_DB_DISCOVERY_AVAILABLE;
+ m_pending_user_evts[0].evt.conn_handle = conn_handle;
+
+ return;
+ }
+ }
+ else
+ {
+ // No more service discovery is needed.
+ p_db_discovery->discovery_in_progress = false;
+ m_pending_user_evts[0].evt.evt_type = BLE_DB_DISCOVERY_AVAILABLE;
+ m_pending_user_evts[0].evt.conn_handle = conn_handle;
+ }
+}
+
+
+/**@brief Function for finding out if a characteristic discovery should be performed after the
+ * last discovered characteristic.
+ *
+ * @details This function is used during the time of database discovery to find out if there is
+ * a need to do more characteristic discoveries. The value handles of the
+ * last discovered characteristic is compared with the end handle of the service.
+ * If the service handle is greater than one of the former characteristic handles,
+ * it means that a characteristic discovery is required.
+ *
+ * @param[in] p_db_discovery The pointer to the DB Discovery structure.
+ * @param[in] p_after_char The pointer to the last discovered characteristic.
+ *
+ * @retval True if a characteristic discovery is required.
+ * @retval False if a characteristic discovery is NOT required.
+ */
+static bool is_char_discovery_reqd(ble_db_discovery_t * p_db_discovery,
+ ble_gattc_char_t * p_after_char)
+{
+ if (p_after_char->handle_value <
+ p_db_discovery->services[p_db_discovery->curr_srv_ind].handle_range.end_handle)
+ {
+ // Handle value of the characteristic being discovered is less than the end handle of
+ // the service being discovered. There is a possibility of more characteristics being
+ // present. Hence a characteristic discovery is required.
+ return true;
+ }
+
+ return false;
+}
+
+
+/**@brief Function to find out if a descriptor discovery is required.
+ *
+ * @details This function finds out if there is a possibility of existence of descriptors between
+ * current characteristic and the next characteristic. If so, this function will compute
+ * the handle range on which the descriptors may be present and will return it.
+ * If the current characteristic is the last known characteristic, then this function
+ * will use the service end handle to find out if the current characteristic can have
+ * descriptors.
+ *
+ * @param[in] p_db_discovery Pointer to the DB Discovery structure.
+ * @param[in] p_curr_char Pointer to the current characteristic.
+ * @param[in] p_next_char Pointer to the next characteristic. This should be NULL if the
+ * caller knows that there is no characteristic after the current
+ * characteristic at the peer.
+ * @param[out] p_handle_range Pointer to the handle range in which descriptors may exist at the
+ * the peer.
+ *
+ * @retval True If a descriptor discovery is required.
+ * @retval False If a descriptor discovery is NOT required.
+ */
+static bool is_desc_discovery_reqd(ble_db_discovery_t * p_db_discovery,
+ ble_gatt_db_char_t * p_curr_char,
+ ble_gatt_db_char_t * p_next_char,
+ ble_gattc_handle_range_t * p_handle_range)
+{
+ if (p_next_char == NULL)
+ {
+ // Current characteristic is the last characteristic in the service. Check if the value
+ // handle of the current characteristic is equal to the service end handle.
+ if (
+ p_curr_char->characteristic.handle_value ==
+ p_db_discovery->services[p_db_discovery->curr_srv_ind].handle_range.end_handle
+ )
+ {
+ // No descriptors can be present for the current characteristic. p_curr_char is the last
+ // characteristic with no descriptors.
+ return false;
+ }
+
+ p_handle_range->start_handle = p_curr_char->characteristic.handle_value + 1;
+
+ // Since the current characteristic is the last characteristic in the service, the end
+ // handle should be the end handle of the service.
+ p_handle_range->end_handle =
+ p_db_discovery->services[p_db_discovery->curr_srv_ind].handle_range.end_handle;
+
+ return true;
+ }
+
+ // p_next_char != NULL. Check for existence of descriptors between the current and the next
+ // characteristic.
+ if ((p_curr_char->characteristic.handle_value + 1) == p_next_char->characteristic.handle_decl)
+ {
+ // No descriptors can exist between the two characteristic.
+ return false;
+ }
+
+ p_handle_range->start_handle = p_curr_char->characteristic.handle_value + 1;
+ p_handle_range->end_handle = p_next_char->characteristic.handle_decl - 1;
+
+ return true;
+}
+
+
+/**@brief Function for performing characteristic discovery.
+ *
+ * @param[in] p_db_discovery Pointer to the DB Discovery structure.
+ * @param[in] conn_handle Connection Handle.
+ *
+ * @return NRF_SUCCESS if the SoftDevice was successfully requested to perform the characteristic
+ * discovery. Otherwise an error code. This function returns the error code returned
+ * by the SoftDevice API @ref sd_ble_gattc_characteristics_discover.
+ */
+static uint32_t characteristics_discover(ble_db_discovery_t * p_db_discovery,
+ uint16_t conn_handle)
+{
+ ble_gatt_db_srv_t * p_srv_being_discovered;
+ ble_gattc_handle_range_t handle_range;
+
+ p_srv_being_discovered = &(p_db_discovery->services[p_db_discovery->curr_srv_ind]);
+
+ if (p_db_discovery->curr_char_ind != 0)
+ {
+ // This is not the first characteristic being discovered. Hence the 'start handle' to be
+ // used must be computed using the handle_value of the previous characteristic.
+ ble_gattc_char_t * p_prev_char;
+ uint8_t prev_char_ind = p_db_discovery->curr_char_ind - 1;
+
+ p_srv_being_discovered = &(p_db_discovery->services[p_db_discovery->curr_srv_ind]);
+
+ p_prev_char = &(p_srv_being_discovered->charateristics[prev_char_ind].characteristic);
+
+ handle_range.start_handle = p_prev_char->handle_value + 1;
+ }
+ else
+ {
+ // This is the first characteristic of this service being discovered.
+ handle_range.start_handle = p_srv_being_discovered->handle_range.start_handle;
+ }
+
+ handle_range.end_handle = p_srv_being_discovered->handle_range.end_handle;
+
+ return sd_ble_gattc_characteristics_discover(conn_handle, &handle_range);
+}
+
+
+/**@brief Function for performing descriptor discovery, if required.
+ *
+ * @details This function will check if descriptor discovery is required and then perform it if
+ * needed. If no more descriptor discovery is required for the service, then the output
+ * parameter p_raise_discov_complete is set to true, indicating to the caller that a
+ * discovery complete event can be triggered to the application.
+ *
+ * @param[in] p_db_discovery Pointer to the DB Discovery structure.
+ * @param[out] p_raise_discov_complete The value pointed to by this pointer will be set to true if
+ * the Discovery Complete event can be triggered to the
+ * application.
+ * @param[in] conn_handle Connection Handle.
+ *
+ * @return NRF_SUCCESS if the SoftDevice was successfully requested to perform the descriptor
+ * discovery, or if no more descriptor discovery is required. Otherwise an error code.
+ * This function returns the error code returned by the SoftDevice API @ref
+ * sd_ble_gattc_descriptors_discover.
+ */
+static uint32_t descriptors_discover(ble_db_discovery_t * p_db_discovery,
+ bool * p_raise_discov_complete,
+ uint16_t conn_handle)
+{
+ ble_gattc_handle_range_t handle_range;
+ ble_gatt_db_char_t * p_curr_char_being_discovered;
+ ble_gatt_db_srv_t * p_srv_being_discovered;
+ bool is_discovery_reqd = false;
+
+ p_srv_being_discovered = &(p_db_discovery->services[p_db_discovery->curr_srv_ind]);
+
+ p_curr_char_being_discovered =
+ &(p_srv_being_discovered->charateristics[p_db_discovery->curr_char_ind]);
+
+ if ((p_db_discovery->curr_char_ind + 1) == p_srv_being_discovered->char_count)
+ {
+ // This is the last characteristic of this service.
+ is_discovery_reqd = is_desc_discovery_reqd(p_db_discovery,
+ p_curr_char_being_discovered,
+ NULL,
+ &handle_range);
+ }
+ else
+ {
+ uint8_t i;
+ ble_gatt_db_char_t * p_next_char;
+
+ for (i = p_db_discovery->curr_char_ind; i < p_srv_being_discovered->char_count; i++)
+ {
+ if (i == (p_srv_being_discovered->char_count - 1))
+ {
+ // The current characteristic is the last characteristic in the service.
+ p_next_char = NULL;
+ }
+ else
+ {
+ p_next_char = &(p_srv_being_discovered->charateristics[i + 1]);
+ }
+
+ // Check if it is possible for the current characteristic to have a descriptor.
+ if (is_desc_discovery_reqd(p_db_discovery,
+ p_curr_char_being_discovered,
+ p_next_char,
+ &handle_range))
+ {
+ is_discovery_reqd = true;
+ break;
+ }
+ else
+ {
+ // No descriptors can exist.
+ p_curr_char_being_discovered = p_next_char;
+ p_db_discovery->curr_char_ind++;
+ }
+ }
+ }
+
+ if (!is_discovery_reqd)
+ {
+ // No more descriptor discovery required. Discovery is complete.
+ // This informs the caller that a discovery complete event can be triggered.
+ *p_raise_discov_complete = true;
+
+ return NRF_SUCCESS;
+ }
+
+ *p_raise_discov_complete = false;
+
+ return sd_ble_gattc_descriptors_discover(conn_handle, &handle_range);
+}
+
+
+/**@brief Function for handling primary service discovery response.
+ *
+ * @details This function will handle the primary service discovery response and start the
+ * discovery of characteristics within that service.
+ *
+ * @param[in] p_db_discovery Pointer to the DB Discovery structure.
+ * @param[in] p_ble_gattc_evt Pointer to the GATT Client event.
+ */
+static void on_primary_srv_discovery_rsp(ble_db_discovery_t * p_db_discovery,
+ ble_gattc_evt_t const * p_ble_gattc_evt)
+{
+ ble_gatt_db_srv_t * p_srv_being_discovered;
+
+ p_srv_being_discovered = &(p_db_discovery->services[p_db_discovery->curr_srv_ind]);
+
+ if (p_ble_gattc_evt->conn_handle != p_db_discovery->conn_handle)
+ {
+ return;
+ }
+
+ if (p_ble_gattc_evt->gatt_status == BLE_GATT_STATUS_SUCCESS)
+ {
+ uint32_t err_code;
+ ble_gattc_evt_prim_srvc_disc_rsp_t const * p_prim_srvc_disc_rsp_evt;
+
+ NRF_LOG_DEBUG("Found service UUID 0x%x.", p_srv_being_discovered->srv_uuid.uuid);
+
+ p_prim_srvc_disc_rsp_evt = &(p_ble_gattc_evt->params.prim_srvc_disc_rsp);
+
+ p_srv_being_discovered->srv_uuid = p_prim_srvc_disc_rsp_evt->services[0].uuid;
+ p_srv_being_discovered->handle_range = p_prim_srvc_disc_rsp_evt->services[0].handle_range;
+
+ err_code = characteristics_discover(p_db_discovery, p_ble_gattc_evt->conn_handle);
+
+ if (err_code != NRF_SUCCESS)
+ {
+ p_db_discovery->discovery_in_progress = false;
+
+ // Error with discovering the service.
+ // Indicate the error to the registered user application.
+ discovery_error_evt_trigger(p_db_discovery, err_code, p_ble_gattc_evt->conn_handle);
+
+ m_pending_user_evts[0].evt.evt_type = BLE_DB_DISCOVERY_AVAILABLE;
+ m_pending_user_evts[0].evt.conn_handle = p_ble_gattc_evt->conn_handle;
+ }
+ }
+ else
+ {
+ NRF_LOG_DEBUG("Service UUID 0x%x not found.", p_srv_being_discovered->srv_uuid.uuid);
+ // Trigger Service Not Found event to the application.
+ discovery_complete_evt_trigger(p_db_discovery, false, p_ble_gattc_evt->conn_handle);
+ on_srv_disc_completion(p_db_discovery, p_ble_gattc_evt->conn_handle);
+ }
+}
+
+
+/**@brief Function for handling characteristic discovery response.
+ *
+ * @param[in] p_db_discovery Pointer to the DB Discovery structure.
+ * @param[in] p_ble_gattc_evt Pointer to the GATT Client event.
+ */
+static void on_characteristic_discovery_rsp(ble_db_discovery_t * p_db_discovery,
+ ble_gattc_evt_t const * p_ble_gattc_evt)
+{
+ uint32_t err_code;
+ ble_gatt_db_srv_t * p_srv_being_discovered;
+ bool perform_desc_discov = false;
+
+ if (p_ble_gattc_evt->conn_handle != p_db_discovery->conn_handle)
+ {
+ return;
+ }
+
+ p_srv_being_discovered = &(p_db_discovery->services[p_db_discovery->curr_srv_ind]);
+
+ if (p_ble_gattc_evt->gatt_status == BLE_GATT_STATUS_SUCCESS)
+ {
+ ble_gattc_evt_char_disc_rsp_t const * p_char_disc_rsp_evt;
+
+ p_char_disc_rsp_evt = &(p_ble_gattc_evt->params.char_disc_rsp);
+
+ // Find out the number of characteristics that were previously discovered (in earlier
+ // characteristic discovery responses, if any).
+ uint8_t num_chars_prev_disc = p_srv_being_discovered->char_count;
+
+ // Find out the number of characteristics that are currently discovered (in the
+ // characteristic discovery response being handled).
+ uint8_t num_chars_curr_disc = p_char_disc_rsp_evt->count;
+
+ // Check if the total number of discovered characteristics are supported by this module.
+ if ((num_chars_prev_disc + num_chars_curr_disc) <= BLE_GATT_DB_MAX_CHARS)
+ {
+ // Update the characteristics count.
+ p_srv_being_discovered->char_count += num_chars_curr_disc;
+ }
+ else
+ {
+ // The number of characteristics discovered at the peer is more than the supported
+ // maximum. This module will store only the characteristics found up to this point.
+ p_srv_being_discovered->char_count = BLE_GATT_DB_MAX_CHARS;
+ }
+
+ uint32_t i;
+ uint32_t j;
+
+ for (i = num_chars_prev_disc, j = 0; i < p_srv_being_discovered->char_count; i++, j++)
+ {
+ p_srv_being_discovered->charateristics[i].characteristic =
+ p_char_disc_rsp_evt->chars[j];
+
+ p_srv_being_discovered->charateristics[i].cccd_handle = BLE_GATT_HANDLE_INVALID;
+ p_srv_being_discovered->charateristics[i].ext_prop_handle = BLE_GATT_HANDLE_INVALID;
+ p_srv_being_discovered->charateristics[i].user_desc_handle = BLE_GATT_HANDLE_INVALID;
+ p_srv_being_discovered->charateristics[i].report_ref_handle = BLE_GATT_HANDLE_INVALID;
+ }
+
+ ble_gattc_char_t * p_last_known_char;
+
+ p_last_known_char = &(p_srv_being_discovered->charateristics[i - 1].characteristic);
+
+ // If no more characteristic discovery is required, or if the maximum number of supported
+ // characteristic per service has been reached, descriptor discovery will be performed.
+ if ( !is_char_discovery_reqd(p_db_discovery, p_last_known_char)
+ || (p_srv_being_discovered->char_count == BLE_GATT_DB_MAX_CHARS))
+ {
+ perform_desc_discov = true;
+ }
+ else
+ {
+ // Update the current characteristic index.
+ p_db_discovery->curr_char_ind = p_srv_being_discovered->char_count;
+
+ // Perform another round of characteristic discovery.
+ err_code = characteristics_discover(p_db_discovery, p_ble_gattc_evt->conn_handle);
+
+ if (err_code != NRF_SUCCESS)
+ {
+ p_db_discovery->discovery_in_progress = false;
+
+ discovery_error_evt_trigger(p_db_discovery, err_code, p_ble_gattc_evt->conn_handle);
+
+ m_pending_user_evts[0].evt.evt_type = BLE_DB_DISCOVERY_AVAILABLE;
+ m_pending_user_evts[0].evt.conn_handle = p_ble_gattc_evt->conn_handle;
+
+ return;
+ }
+ }
+ }
+ else
+ {
+ // The previous characteristic discovery resulted in no characteristics.
+ // descriptor discovery should be performed.
+ perform_desc_discov = true;
+ }
+
+ if (perform_desc_discov)
+ {
+ bool raise_discov_complete;
+
+ p_db_discovery->curr_char_ind = 0;
+
+ err_code = descriptors_discover(p_db_discovery,
+ &raise_discov_complete,
+ p_ble_gattc_evt->conn_handle);
+
+ if (err_code != NRF_SUCCESS)
+ {
+ p_db_discovery->discovery_in_progress = false;
+
+ discovery_error_evt_trigger(p_db_discovery, err_code, p_ble_gattc_evt->conn_handle);
+
+ m_pending_user_evts[0].evt.evt_type = BLE_DB_DISCOVERY_AVAILABLE;
+ m_pending_user_evts[0].evt.conn_handle = p_ble_gattc_evt->conn_handle;
+
+ return;
+ }
+ if (raise_discov_complete)
+ {
+ // No more characteristics and descriptors need to be discovered. Discovery is complete.
+ // Send a discovery complete event to the user application.
+ NRF_LOG_DEBUG("Discovery of service with UUID 0x%x completed with success"
+ " on connection handle 0x%x.",
+ p_srv_being_discovered->srv_uuid.uuid,
+ p_ble_gattc_evt->conn_handle);
+
+ discovery_complete_evt_trigger(p_db_discovery, true, p_ble_gattc_evt->conn_handle);
+ on_srv_disc_completion(p_db_discovery, p_ble_gattc_evt->conn_handle);
+ }
+ }
+}
+
+
+/**@brief Function for handling descriptor discovery response.
+ *
+ * @param[in] p_db_discovery Pointer to the DB Discovery structure.
+ * @param[in] p_ble_gattc_evt Pointer to the GATT Client event.
+ */
+static void on_descriptor_discovery_rsp(ble_db_discovery_t * const p_db_discovery,
+ const ble_gattc_evt_t * const p_ble_gattc_evt)
+{
+ const ble_gattc_evt_desc_disc_rsp_t * p_desc_disc_rsp_evt;
+ ble_gatt_db_srv_t * p_srv_being_discovered;
+
+ if (p_ble_gattc_evt->conn_handle != p_db_discovery->conn_handle)
+ {
+ return;
+ }
+
+ p_srv_being_discovered = &(p_db_discovery->services[p_db_discovery->curr_srv_ind]);
+
+ p_desc_disc_rsp_evt = &(p_ble_gattc_evt->params.desc_disc_rsp);
+
+ ble_gatt_db_char_t * p_char_being_discovered =
+ &(p_srv_being_discovered->charateristics[p_db_discovery->curr_char_ind]);
+
+ if (p_ble_gattc_evt->gatt_status == BLE_GATT_STATUS_SUCCESS)
+ {
+ // The descriptor was found at the peer.
+ // Iterate through and collect CCCD, Extended Properties,
+ // User Description & Report Reference descriptor handles.
+ for (uint32_t i = 0; i < p_desc_disc_rsp_evt->count; i++)
+ {
+ switch (p_desc_disc_rsp_evt->descs[i].uuid.uuid)
+ {
+ case BLE_UUID_DESCRIPTOR_CLIENT_CHAR_CONFIG:
+ p_char_being_discovered->cccd_handle =
+ p_desc_disc_rsp_evt->descs[i].handle;
+ break;
+
+ case BLE_UUID_DESCRIPTOR_CHAR_EXT_PROP:
+ p_char_being_discovered->ext_prop_handle =
+ p_desc_disc_rsp_evt->descs[i].handle;
+ break;
+
+ case BLE_UUID_DESCRIPTOR_CHAR_USER_DESC:
+ p_char_being_discovered->user_desc_handle =
+ p_desc_disc_rsp_evt->descs[i].handle;
+ break;
+
+ case BLE_UUID_REPORT_REF_DESCR:
+ p_char_being_discovered->report_ref_handle =
+ p_desc_disc_rsp_evt->descs[i].handle;
+ break;
+ }
+
+ /* Break if we've found all the descriptors we are looking for. */
+ if (p_char_being_discovered->cccd_handle != BLE_GATT_HANDLE_INVALID &&
+ p_char_being_discovered->ext_prop_handle != BLE_GATT_HANDLE_INVALID &&
+ p_char_being_discovered->user_desc_handle != BLE_GATT_HANDLE_INVALID &&
+ p_char_being_discovered->report_ref_handle != BLE_GATT_HANDLE_INVALID)
+ {
+ break;
+ }
+ }
+ }
+
+ bool raise_discov_complete = false;
+
+ if ((p_db_discovery->curr_char_ind + 1) == p_srv_being_discovered->char_count)
+ {
+ // No more characteristics and descriptors need to be discovered. Discovery is complete.
+ // Send a discovery complete event to the user application.
+
+ raise_discov_complete = true;
+ }
+ else
+ {
+ // Begin discovery of descriptors for the next characteristic.
+ uint32_t err_code;
+
+ p_db_discovery->curr_char_ind++;
+
+ err_code = descriptors_discover(p_db_discovery,
+ &raise_discov_complete,
+ p_ble_gattc_evt->conn_handle);
+
+ if (err_code != NRF_SUCCESS)
+ {
+ p_db_discovery->discovery_in_progress = false;
+
+ // Error with discovering the service.
+ // Indicate the error to the registered user application.
+ discovery_error_evt_trigger(p_db_discovery, err_code, p_ble_gattc_evt->conn_handle);
+
+ m_pending_user_evts[0].evt.evt_type = BLE_DB_DISCOVERY_AVAILABLE;
+ m_pending_user_evts[0].evt.conn_handle = p_ble_gattc_evt->conn_handle;
+
+ return;
+ }
+ }
+
+ if (raise_discov_complete)
+ {
+ NRF_LOG_DEBUG("Discovery of service with UUID 0x%x completed with success"
+ " on connection handle 0x%x.",
+ p_srv_being_discovered->srv_uuid.uuid,
+ p_ble_gattc_evt->conn_handle);
+
+ discovery_complete_evt_trigger(p_db_discovery, true, p_ble_gattc_evt->conn_handle);
+ on_srv_disc_completion(p_db_discovery, p_ble_gattc_evt->conn_handle);
+ }
+}
+
+
+uint32_t ble_db_discovery_init(const ble_db_discovery_evt_handler_t evt_handler)
+{
+ uint32_t err_code = NRF_SUCCESS;
+ VERIFY_PARAM_NOT_NULL(evt_handler);
+
+ m_num_of_handlers_reg = 0;
+ m_initialized = true;
+ m_pending_usr_evt_index = 0;
+ m_evt_handler = evt_handler;
+
+ return err_code;
+
+}
+
+
+uint32_t ble_db_discovery_close()
+{
+ m_num_of_handlers_reg = 0;
+ m_initialized = false;
+ m_pending_usr_evt_index = 0;
+
+ return NRF_SUCCESS;
+}
+
+
+uint32_t ble_db_discovery_evt_register(ble_uuid_t const * p_uuid)
+{
+ VERIFY_PARAM_NOT_NULL(p_uuid);
+ VERIFY_MODULE_INITIALIZED();
+
+ return registered_handler_set(p_uuid, m_evt_handler);
+}
+
+
+static uint32_t discovery_start(ble_db_discovery_t * const p_db_discovery, uint16_t conn_handle)
+{
+ uint32_t err_code;
+ ble_gatt_db_srv_t * p_srv_being_discovered;
+
+ memset(p_db_discovery, 0x00, sizeof(ble_db_discovery_t));
+
+ p_db_discovery->conn_handle = conn_handle;
+
+ m_pending_usr_evt_index = 0;
+
+ p_db_discovery->discoveries_count = 0;
+ p_db_discovery->curr_srv_ind = 0;
+ p_db_discovery->curr_char_ind = 0;
+
+ p_srv_being_discovered = &(p_db_discovery->services[p_db_discovery->curr_srv_ind]);
+ p_srv_being_discovered->srv_uuid = m_registered_handlers[p_db_discovery->curr_srv_ind];
+
+ NRF_LOG_DEBUG("Starting discovery of service with UUID 0x%x on connection handle 0x%x.",
+ p_srv_being_discovered->srv_uuid.uuid, conn_handle);
+
+ err_code = sd_ble_gattc_primary_services_discover(conn_handle,
+ SRV_DISC_START_HANDLE,
+ &(p_srv_being_discovered->srv_uuid));
+ if (err_code != NRF_ERROR_BUSY)
+ {
+ VERIFY_SUCCESS(err_code);
+ p_db_discovery->discovery_in_progress = true;
+ p_db_discovery->discovery_pending = false;
+ }
+ else
+ {
+ p_db_discovery->discovery_in_progress = true;
+ p_db_discovery->discovery_pending = true;
+ }
+
+ return NRF_SUCCESS;
+}
+
+
+uint32_t ble_db_discovery_start(ble_db_discovery_t * const p_db_discovery, uint16_t conn_handle)
+{
+ VERIFY_PARAM_NOT_NULL(p_db_discovery);
+ VERIFY_MODULE_INITIALIZED();
+
+ if (m_num_of_handlers_reg == 0)
+ {
+ // No user modules were registered. There are no services to discover.
+ return NRF_ERROR_INVALID_STATE;
+ }
+
+ if (p_db_discovery->discovery_in_progress)
+ {
+ return NRF_ERROR_BUSY;
+ }
+
+ return discovery_start(p_db_discovery, conn_handle);
+}
+
+
+/**@brief Function for handling disconnected event.
+ *
+ * @param[in] p_db_discovery Pointer to the DB Discovery structure.
+ * @param[in] p_ble_gattc_evt Pointer to the GAP event.
+ */
+static void on_disconnected(ble_db_discovery_t * p_db_discovery,
+ ble_gap_evt_t const * p_evt)
+{
+ if (p_evt->conn_handle == p_db_discovery->conn_handle)
+ {
+ p_db_discovery->discovery_in_progress = false;
+ p_db_discovery->discovery_pending = false;
+ p_db_discovery->conn_handle = BLE_CONN_HANDLE_INVALID;
+ }
+}
+
+
+void ble_db_discovery_on_ble_evt(ble_evt_t const * p_ble_evt,
+ void * p_context)
+{
+ VERIFY_PARAM_NOT_NULL_VOID(p_ble_evt);
+ VERIFY_PARAM_NOT_NULL_VOID(p_context);
+ VERIFY_MODULE_INITIALIZED_VOID();
+
+ ble_db_discovery_t * p_db_discovery = (ble_db_discovery_t *)p_context;
+
+ switch (p_ble_evt->header.evt_id)
+ {
+ case BLE_GATTC_EVT_PRIM_SRVC_DISC_RSP:
+ on_primary_srv_discovery_rsp(p_db_discovery, &(p_ble_evt->evt.gattc_evt));
+ break;
+
+ case BLE_GATTC_EVT_CHAR_DISC_RSP:
+ on_characteristic_discovery_rsp(p_db_discovery, &(p_ble_evt->evt.gattc_evt));
+ break;
+
+ case BLE_GATTC_EVT_DESC_DISC_RSP:
+ on_descriptor_discovery_rsp(p_db_discovery, &(p_ble_evt->evt.gattc_evt));
+ break;
+
+ case BLE_GAP_EVT_DISCONNECTED:
+ on_disconnected(p_db_discovery, &(p_ble_evt->evt.gap_evt));
+ break;
+
+ default:
+ break;
+ }
+
+ if ( (p_db_discovery->discovery_pending)
+ && (p_ble_evt->header.evt_id >= BLE_GATTC_EVT_BASE)
+ && (p_ble_evt->header.evt_id <= BLE_GATTC_EVT_LAST)
+ && (p_ble_evt->evt.gattc_evt.conn_handle == p_db_discovery->conn_handle))
+ {
+ (void)discovery_start(p_db_discovery, p_db_discovery->conn_handle);
+ }
+}
+#endif // NRF_MODULE_ENABLED(BLE_DB_DISCOVERY)
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_db_discovery/ble_db_discovery.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_db_discovery/ble_db_discovery.h
new file mode 100644
index 0000000..a2094c9
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_db_discovery/ble_db_discovery.h
@@ -0,0 +1,235 @@
+/**
+ * Copyright (c) 2013 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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
+ *
+ * @defgroup ble_db_discovery Database Discovery
+ * @{
+ * @ingroup ble_sdk_lib
+ * @brief Database discovery module.
+ *
+ * @details This module contains the APIs and types exposed by the DB Discovery module. These APIs
+ * and types can be used by the application to perform discovery of a service and its
+ * characteristics at the peer server. This module can also be used to discover the
+ * desired services in multiple remote devices.
+ *
+ * @warning The maximum number of characteristics per service that can be discovered by this module
+ * is determined by the number of characteristics in the service structure defined in
+ * db_disc_config.h. If the peer has more than the supported number of characteristics, then
+ * the first found will be discovered and any further characteristics will be ignored. Only the
+ * following descriptors will be searched for at the peer: Client Characteristic Configuration,
+ * Characteristic Extended Properties, Characteristic User Description, and Report Reference.
+ *
+ * @note Presently only one instance of a Primary Service can be discovered by this module. If
+ * there are multiple instances of the service at the peer, only the first instance
+ * of it at the peer is fetched and returned to the application.
+ *
+ * @note The application must propagate BLE stack events to this module by calling
+ * ble_db_discovery_on_ble_evt().
+ *
+ */
+
+#ifndef BLE_DB_DISCOVERY_H__
+#define BLE_DB_DISCOVERY_H__
+
+#include <stdint.h>
+#include <stdbool.h>
+#include "nrf_error.h"
+#include "ble.h"
+#include "ble_gattc.h"
+#include "ble_gatt_db.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**@brief Macro for defining a ble_db_discovery instance.
+ *
+ * @param _name Name of the instance.
+ * @hideinitializer
+ */
+#define BLE_DB_DISCOVERY_DEF(_name) \
+static ble_db_discovery_t _name = {.discovery_in_progress = 0, \
+ .discovery_pending = 0, \
+ .conn_handle = BLE_CONN_HANDLE_INVALID}; \
+NRF_SDH_BLE_OBSERVER(_name ## _obs, \
+ BLE_DB_DISC_BLE_OBSERVER_PRIO, \
+ ble_db_discovery_on_ble_evt, &_name)
+
+/** @brief Macro for defining multiple ble_db_discovery instances.
+ *
+ * @param _name Name of the array of instances.
+ * @param _cnt Number of instances to define.
+ */
+#define BLE_DB_DISCOVERY_ARRAY_DEF(_name, _cnt) \
+static ble_db_discovery_t _name[_cnt] = {{.discovery_in_progress = 0, \
+ .discovery_pending = 0, \
+ .conn_handle = BLE_CONN_HANDLE_INVALID}}; \
+NRF_SDH_BLE_OBSERVERS(_name ## _obs, \
+ BLE_DB_DISC_BLE_OBSERVER_PRIO, \
+ ble_db_discovery_on_ble_evt, &_name, _cnt)
+
+#define BLE_DB_DISCOVERY_MAX_SRV 6 /**< Maximum number of services supported by this module. This also indicates the maximum number of users allowed to be registered to this module (one user per service). */
+
+
+/**@brief DB Discovery event type. */
+typedef enum
+{
+ BLE_DB_DISCOVERY_COMPLETE, /**< Event indicating that the discovery of one service is complete. */
+ BLE_DB_DISCOVERY_ERROR, /**< Event indicating that an internal error has occurred in the DB Discovery module. This could typically be because of the SoftDevice API returning an error code during the DB discover.*/
+ BLE_DB_DISCOVERY_SRV_NOT_FOUND, /**< Event indicating that the service was not found at the peer.*/
+ BLE_DB_DISCOVERY_AVAILABLE /**< Event indicating that the DB discovery instance is available.*/
+} ble_db_discovery_evt_type_t;
+
+/**@brief Structure for holding the information related to the GATT database at the server.
+ *
+ * @details This module identifies a remote database. Use one instance of this structure per
+ * connection.
+ *
+ * @warning This structure must be zero-initialized.
+ */
+typedef struct
+{
+ ble_gatt_db_srv_t services[BLE_DB_DISCOVERY_MAX_SRV]; /**< Information related to the current service being discovered. This is intended for internal use during service discovery.*/
+ uint8_t srv_count; /**< Number of services at the peers GATT database.*/
+ uint8_t curr_char_ind; /**< Index of the current characteristic being discovered. This is intended for internal use during service discovery.*/
+ uint8_t curr_srv_ind; /**< Index of the current service being discovered. This is intended for internal use during service discovery.*/
+ bool discovery_in_progress; /**< Variable to indicate if there is a service discovery in progress. */
+ bool discovery_pending; /**< Discovery was requested, but could not start because the SoftDevice was busy. */
+ uint8_t discoveries_count; /**< Number of service discoveries made, both successful and unsuccessful. */
+ uint16_t conn_handle; /**< Connection handle on which the discovery is started*/
+} ble_db_discovery_t;
+
+/**@brief Structure containing the event from the DB discovery module to the application. */
+typedef struct
+{
+ ble_db_discovery_evt_type_t evt_type; /**< Type of event. */
+ uint16_t conn_handle; /**< Handle of the connection for which this event has occurred. */
+ union
+ {
+ ble_gatt_db_srv_t discovered_db; /**< Structure containing the information about the GATT Database at the server. This will be filled when the event type is @ref BLE_DB_DISCOVERY_COMPLETE. The UUID field of this will be filled when the event type is @ref BLE_DB_DISCOVERY_SRV_NOT_FOUND. */
+ uint32_t err_code; /**< nRF Error code indicating the type of error which occurred in the DB Discovery module. This will be filled when the event type is @ref BLE_DB_DISCOVERY_ERROR. */
+ } params;
+} ble_db_discovery_evt_t;
+
+/**@brief DB Discovery event handler type. */
+typedef void (* ble_db_discovery_evt_handler_t)(ble_db_discovery_evt_t * p_evt);
+
+
+/**@brief Function for initializing the DB Discovery module.
+ *
+ * @param[in] evt_handler Event handler to be called by the DB discovery module when any event
+ * related to discovery of the registered service occurs.
+ *
+ * @retval NRF_SUCCESS On successful initialization.
+ * @retval NRF_ERROR_NULL If the handler was NULL.
+ */
+uint32_t ble_db_discovery_init(ble_db_discovery_evt_handler_t evt_handler);
+
+
+/**@brief Function for closing the DB Discovery module.
+ *
+ * @details This function will clear up any internal variables and states maintained by the
+ * module. To re-use the module after calling this function, the function @ref
+ * ble_db_discovery_init must be called again.
+ *
+ * @retval NRF_SUCCESS Operation success.
+ */
+uint32_t ble_db_discovery_close(void);
+
+
+/**@brief Function for registering with the DB Discovery module.
+ *
+ * @details The application can use this function to inform which service it is interested in
+ * discovering at the server.
+ *
+ * @param[in] p_uuid Pointer to the UUID of the service to be discovered at the server.
+ *
+ * @note The total number of services that can be discovered by this module is @ref
+ * BLE_DB_DISCOVERY_MAX_SRV. This effectively means that the maximum number of
+ * registrations possible is equal to the @ref BLE_DB_DISCOVERY_MAX_SRV.
+ *
+ * @retval NRF_SUCCESS Operation success.
+ * @retval NRF_ERROR_NULL When a NULL pointer is passed as input.
+ * @retval NRF_ERROR_INVALID_STATE If this function is called without calling the
+ * @ref ble_db_discovery_init.
+ * @retval NRF_ERROR_NO_MEM The maximum number of registrations allowed by this module
+ * has been reached.
+ */
+uint32_t ble_db_discovery_evt_register(const ble_uuid_t * const p_uuid);
+
+
+/**@brief Function for starting the discovery of the GATT database at the server.
+ *
+ * @param[out] p_db_discovery Pointer to the DB Discovery structure.
+ * @param[in] conn_handle The handle of the connection for which the discovery should be
+ * started.
+ *
+ * @retval NRF_SUCCESS Operation success.
+ * @retval NRF_ERROR_NULL When a NULL pointer is passed as input.
+ * @retval NRF_ERROR_INVALID_STATE If this function is called without calling the
+ * @ref ble_db_discovery_init, or without calling
+ * @ref ble_db_discovery_evt_register.
+ * @retval NRF_ERROR_BUSY If a discovery is already in progress using
+ * @p p_db_discovery. Use a different @ref ble_db_discovery_t
+ * structure, or wait for a DB Discovery event before retrying.
+ *
+ * @return This API propagates the error code returned by the
+ * SoftDevice API @ref sd_ble_gattc_primary_services_discover.
+ */
+uint32_t ble_db_discovery_start(ble_db_discovery_t * p_db_discovery,
+ uint16_t conn_handle);
+
+
+/**@brief Function for handling the Application's BLE Stack events.
+ *
+ * @param[in] p_ble_evt Pointer to the BLE event received.
+ * @param[in,out] p_context Pointer to the DB Discovery structure.
+ */
+void ble_db_discovery_on_ble_evt(ble_evt_t const * p_ble_evt,
+ void * p_context);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // BLE_DB_DISCOVERY_H__
+
+/** @} */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_dtm/ble_dtm.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_dtm/ble_dtm.c
new file mode 100644
index 0000000..f73c030
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_dtm/ble_dtm.c
@@ -0,0 +1,957 @@
+/**
+ * Copyright (c) 2012 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#include "sdk_common.h"
+#if NRF_MODULE_ENABLED(BLE_DTM)
+#include "ble_dtm.h"
+#include "ble_dtm_hw.h"
+#include <stdbool.h>
+#include <string.h>
+#include "nrf.h"
+
+#define DTM_HEADER_OFFSET 0 /**< Index where the header of the pdu is located. */
+#define DTM_HEADER_SIZE 2 /**< Size of PDU header. */
+#define DTM_PAYLOAD_MAX_SIZE 255 /**< Maximum payload size allowed during dtm execution. */
+#define DTM_LENGTH_OFFSET (DTM_HEADER_OFFSET + 1) /**< Index where the length of the payload is encoded. */
+#define DTM_PDU_MAX_MEMORY_SIZE (DTM_HEADER_SIZE + DTM_PAYLOAD_MAX_SIZE) /**< Maximum PDU size allowed during dtm execution. */
+#define DTM_ON_AIR_OVERHEAD_SIZE 10 /**< Size of the packet on air without the payload (preamble + sync word + type + RFU + length + CRC). */
+
+#define RX_MODE true /**< Constant defining RX mode for radio during dtm test. */
+#define TX_MODE false /**< Constant defining TX mode for radio during dtm test. */
+
+#define PHYS_CH_MAX 39 /**< Maximum number of valid channels in BLE. */
+
+// Values that for now are "constants" - they could be configured by a function setting them,
+// but most of these are set by the BLE DTM standard, so changing them is not relevant.
+#define RFPHY_TEST_0X0F_REF_PATTERN 0x0f /**< RF-PHY test packet patterns, for the repeated octet packets. */
+#define RFPHY_TEST_0X55_REF_PATTERN 0x55 /**< RF-PHY test packet patterns, for the repeated octet packets. */
+#define RFPHY_TEST_0XFF_REF_PATTERN 0xFF /**< RF-PHY test packet patterns, for the repeated octet packets. */
+
+#define PRBS9_CONTENT {0xFF, 0xC1, 0xFB, 0xE8, 0x4C, 0x90, 0x72, 0x8B, \
+ 0xE7, 0xB3, 0x51, 0x89, 0x63, 0xAB, 0x23, 0x23, \
+ 0x02, 0x84, 0x18, 0x72, 0xAA, 0x61, 0x2F, 0x3B, \
+ 0x51, 0xA8, 0xE5, 0x37, 0x49, 0xFB, 0xC9, 0xCA, \
+ 0x0C, 0x18, 0x53, 0x2C, 0xFD, 0x45, 0xE3, 0x9A, \
+ 0xE6, 0xF1, 0x5D, 0xB0, 0xB6, 0x1B, 0xB4, 0xBE, \
+ 0x2A, 0x50, 0xEA, 0xE9, 0x0E, 0x9C, 0x4B, 0x5E, \
+ 0x57, 0x24, 0xCC, 0xA1, 0xB7, 0x59, 0xB8, 0x87, \
+ 0xFF, 0xE0, 0x7D, 0x74, 0x26, 0x48, 0xB9, 0xC5, \
+ 0xF3, 0xD9, 0xA8, 0xC4, 0xB1, 0xD5, 0x91, 0x11, \
+ 0x01, 0x42, 0x0C, 0x39, 0xD5, 0xB0, 0x97, 0x9D, \
+ 0x28, 0xD4, 0xF2, 0x9B, 0xA4, 0xFD, 0x64, 0x65, \
+ 0x06, 0x8C, 0x29, 0x96, 0xFE, 0xA2, 0x71, 0x4D, \
+ 0xF3, 0xF8, 0x2E, 0x58, 0xDB, 0x0D, 0x5A, 0x5F, \
+ 0x15, 0x28, 0xF5, 0x74, 0x07, 0xCE, 0x25, 0xAF, \
+ 0x2B, 0x12, 0xE6, 0xD0, 0xDB, 0x2C, 0xDC, 0xC3, \
+ 0x7F, 0xF0, 0x3E, 0x3A, 0x13, 0xA4, 0xDC, 0xE2, \
+ 0xF9, 0x6C, 0x54, 0xE2, 0xD8, 0xEA, 0xC8, 0x88, \
+ 0x00, 0x21, 0x86, 0x9C, 0x6A, 0xD8, 0xCB, 0x4E, \
+ 0x14, 0x6A, 0xF9, 0x4D, 0xD2, 0x7E, 0xB2, 0x32, \
+ 0x03, 0xC6, 0x14, 0x4B, 0x7F, 0xD1, 0xB8, 0xA6, \
+ 0x79, 0x7C, 0x17, 0xAC, 0xED, 0x06, 0xAD, 0xAF, \
+ 0x0A, 0x94, 0x7A, 0xBA, 0x03, 0xE7, 0x92, 0xD7, \
+ 0x15, 0x09, 0x73, 0xE8, 0x6D, 0x16, 0xEE, 0xE1, \
+ 0x3F, 0x78, 0x1F, 0x9D, 0x09, 0x52, 0x6E, 0xF1, \
+ 0x7C, 0x36, 0x2A, 0x71, 0x6C, 0x75, 0x64, 0x44, \
+ 0x80, 0x10, 0x43, 0x4E, 0x35, 0xEC, 0x65, 0x27, \
+ 0x0A, 0xB5, 0xFC, 0x26, 0x69, 0x3F, 0x59, 0x99, \
+ 0x01, 0x63, 0x8A, 0xA5, 0xBF, 0x68, 0x5C, 0xD3, \
+ 0x3C, 0xBE, 0x0B, 0xD6, 0x76, 0x83, 0xD6, 0x57, \
+ 0x05, 0x4A, 0x3D, 0xDD, 0x81, 0x73, 0xC9, 0xEB, \
+ 0x8A, 0x84, 0x39, 0xF4, 0x36, 0x0B, 0xF7} /**< The PRBS9 sequence used as packet payload.
+ The bytes in the sequence is in the right order, but the bits of each byte in the array is reverse.
+ of that found by running the PRBS9 algorithm. This is because of the endianess of the nRF5 radio. */
+
+/**@brief Structure holding the PDU used for transmitting/receiving a PDU.
+ */
+typedef struct
+{
+ uint8_t content[DTM_HEADER_SIZE + DTM_PAYLOAD_MAX_SIZE]; /**< PDU packet content. */
+} pdu_type_t;
+
+/**@brief States used for the DTM test implementation.
+ */
+typedef enum
+{
+ STATE_UNINITIALIZED, /**< The DTM is uninitialized. */
+ STATE_IDLE, /**< State when system has just initialized, or current test has completed. */
+ STATE_TRANSMITTER_TEST, /**< State used when a DTM Transmission test is running. */
+ STATE_CARRIER_TEST, /**< State used when a DTM Carrier test is running (Vendor specific test). */
+ STATE_RECEIVER_TEST /**< State used when a DTM Receive test is running. */
+} state_t;
+
+
+// Internal variables set as side effects of commands or events.
+static state_t m_state = STATE_UNINITIALIZED; /**< Current machine state. */
+static uint16_t m_rx_pkt_count; /**< Number of valid packets received. */
+static pdu_type_t m_pdu; /**< PDU to be sent. */
+static uint16_t m_event; /**< current command status - initially "ok", may be set if error detected, or to packet count. */
+static bool m_new_event; /**< Command has been processed - number of not yet reported event bytes. */
+static uint32_t m_packet_length; /**< Payload length of transmitted PDU, bits 2:7 of 16-bit dtm command. */
+static dtm_pkt_type_t m_packet_type; /**< Bits 0..1 of 16-bit transmit command, or 0xFFFFFFFF. */
+static dtm_freq_t m_phys_ch; /**< 0..39 physical channel number (base 2402 MHz, Interval 2 MHz), bits 8:13 of 16-bit dtm command. */
+static uint32_t m_current_time = 0; /**< Counter for interrupts from timer to ensure that the 2 bytes forming a DTM command are received within the time window. */
+
+// Nordic specific configuration values (not defined by BLE standard).
+// Definition of initial values found in ble_dtm.h
+static int32_t m_tx_power = DEFAULT_TX_POWER; /**< TX power for transmission test, default to maximum value (+4 dBm). */
+static NRF_TIMER_Type * mp_timer = DEFAULT_TIMER; /**< Timer to be used. */
+static IRQn_Type m_timer_irq = DEFAULT_TIMER_IRQn; /**< which interrupt line to clear on every timeout */
+
+static uint8_t const m_prbs_content[] = PRBS9_CONTENT; /**< Pseudo-random bit sequence defined by the BLE standard. */
+static uint8_t m_packetHeaderLFlen = 8; /**< Length of length field in packet Header (in bits). */
+static uint8_t m_packetHeaderS0len = 1; /**< Length of S0 field in packet Header (in bytes). */
+static uint8_t m_packetHeaderS1len = 0; /**< Length of S1 field in packet Header (in bits). */
+static uint8_t m_packetHeaderPlen = RADIO_PCNF0_PLEN_8bit; /**< Length of the preamble. */
+
+static uint8_t m_crcConfSkipAddr = 1; /**< Leave packet address field out of CRC calculation. */
+static uint8_t m_static_length = 0; /**< Number of bytes sent in addition to the var.length payload. */
+static uint32_t m_balen = 3; /**< Base address length in bytes. */
+static uint32_t m_endian = RADIO_PCNF1_ENDIAN_Little; /**< On air endianess of packet, this applies to the S0, LENGTH, S1 and the PAYLOAD fields. */
+static uint32_t m_whitening = RADIO_PCNF1_WHITEEN_Disabled; /**< Whitening disabled. */
+static uint8_t m_crcLength = RADIO_CRCCNF_LEN_Three; /**< CRC Length (in bytes). */
+static uint32_t m_address = 0x71764129; /**< Address. */
+static uint32_t m_crc_poly = 0x0000065B; /**< CRC polynomial. */
+static uint32_t m_crc_init = 0x00555555; /**< Initial value for CRC calculation. */
+static uint8_t m_radio_mode = RADIO_MODE_MODE_Ble_1Mbit; /**< nRF51 specific radio mode value. */
+static uint32_t m_txIntervaluS = 2500; /**< Time between start of Tx packets (in uS). */
+
+
+/**@brief Function for verifying that a received PDU has the expected structure and content.
+ */
+static bool check_pdu(void)
+{
+ uint8_t k; // Byte pointer for running through PDU payload
+ uint8_t pattern; // Repeating octet value in payload
+ dtm_pkt_type_t pdu_packet_type; // Note: PDU packet type is a 4-bit field in HCI, but 2 bits in BLE DTM
+ uint32_t length = 0;
+
+ pdu_packet_type = (dtm_pkt_type_t)(m_pdu.content[DTM_HEADER_OFFSET] & 0x0F);
+ length = m_pdu.content[DTM_LENGTH_OFFSET];
+
+ // Check that the length is valid.
+ if (length > DTM_PAYLOAD_MAX_SIZE)
+ {
+ return false;
+ }
+
+ // If the 1Mbit or 2Mbit radio mode is active, check that one of the three valid uncoded DTM packet types are selected.
+ if ((m_radio_mode == RADIO_MODE_MODE_Ble_1Mbit || m_radio_mode == RADIO_MODE_MODE_Ble_2Mbit) && (pdu_packet_type > (dtm_pkt_type_t)DTM_PKT_0X55))
+ {
+ return false;
+ }
+
+#ifdef NRF52840_XXAA
+ // If a long range radio mode is active, check that one of the four valid coded DTM packet types are selected.
+ if ((m_radio_mode == RADIO_MODE_MODE_Ble_LR500Kbit || m_radio_mode == RADIO_MODE_MODE_Ble_LR125Kbit) && (pdu_packet_type > (dtm_pkt_type_t)DTM_PKT_0XFF))
+ {
+ return false;
+ }
+#endif
+
+ if (pdu_packet_type == DTM_PKT_PRBS9)
+ {
+ // Payload does not consist of one repeated octet; must compare ir with entire block into
+ return (memcmp(m_pdu.content + DTM_HEADER_SIZE, m_prbs_content, length) == 0);
+ }
+
+ if (pdu_packet_type == DTM_PKT_0X0F)
+ {
+ pattern = RFPHY_TEST_0X0F_REF_PATTERN;
+ }
+ else if (pdu_packet_type == DTM_PKT_0X55)
+ {
+ pattern = RFPHY_TEST_0X55_REF_PATTERN;
+ }
+ else if (pdu_packet_type == DTM_PKT_0XFF)
+ {
+ pattern = RFPHY_TEST_0XFF_REF_PATTERN;
+ }
+ else
+ {
+ // No valid packet type set.
+ return false;
+ }
+
+ for (k = 0; k < length; k++)
+ {
+ // Check repeated pattern filling the PDU payload
+ if (m_pdu.content[k + 2] != pattern)
+ {
+ return false;
+ }
+ }
+ return true;
+}
+
+
+/**@brief Function for turning off the radio after a test.
+ * Also called after test done, to be ready for next test.
+ */
+static void radio_reset(void)
+{
+ NRF_PPI->CHENCLR = PPI_CHENCLR_CH0_Msk | PPI_CHENCLR_CH1_Msk;
+
+ NRF_RADIO->SHORTS = 0;
+ NRF_RADIO->EVENTS_DISABLED = 0;
+ NRF_RADIO->TASKS_DISABLE = 1;
+
+ while (NRF_RADIO->EVENTS_DISABLED == 0)
+ {
+ // Do nothing
+ }
+
+ NRF_RADIO->EVENTS_DISABLED = 0;
+ NRF_RADIO->TASKS_RXEN = 0;
+ NRF_RADIO->TASKS_TXEN = 0;
+
+ m_rx_pkt_count = 0;
+}
+
+
+/**@brief Function for initializing the radio for DTM.
+ */
+static uint32_t radio_init(void)
+{
+ if (dtm_radio_validate(m_tx_power, m_radio_mode) != DTM_SUCCESS)
+ {
+ m_event = LE_TEST_STATUS_EVENT_ERROR;
+ return DTM_ERROR_ILLEGAL_CONFIGURATION;
+ }
+
+ // Turn off radio before configuring it
+ radio_reset();
+
+ NRF_RADIO->TXPOWER = m_tx_power;
+ NRF_RADIO->MODE = m_radio_mode << RADIO_MODE_MODE_Pos;
+
+ // Set the access address, address0/prefix0 used for both Rx and Tx address
+ NRF_RADIO->PREFIX0 &= ~RADIO_PREFIX0_AP0_Msk;
+ NRF_RADIO->PREFIX0 |= (m_address >> 24) & RADIO_PREFIX0_AP0_Msk;
+ NRF_RADIO->BASE0 = m_address << 8;
+ NRF_RADIO->RXADDRESSES = RADIO_RXADDRESSES_ADDR0_Enabled << RADIO_RXADDRESSES_ADDR0_Pos;
+ NRF_RADIO->TXADDRESS = (0x00 << RADIO_TXADDRESS_TXADDRESS_Pos) & RADIO_TXADDRESS_TXADDRESS_Msk;
+
+ // Configure CRC calculation
+ NRF_RADIO->CRCCNF = (m_crcConfSkipAddr << RADIO_CRCCNF_SKIP_ADDR_Pos) |
+ (m_crcLength << RADIO_CRCCNF_LEN_Pos);
+
+ if (m_radio_mode == RADIO_MODE_MODE_Ble_1Mbit || m_radio_mode == RADIO_MODE_MODE_Ble_2Mbit)
+ {
+ // Non-coded PHY
+ NRF_RADIO->PCNF0 = (m_packetHeaderS1len << RADIO_PCNF0_S1LEN_Pos) |
+ (m_packetHeaderS0len << RADIO_PCNF0_S0LEN_Pos) |
+ (m_packetHeaderLFlen << RADIO_PCNF0_LFLEN_Pos) |
+ (m_packetHeaderPlen << RADIO_PCNF0_PLEN_Pos);
+ }
+#ifdef NRF52840_XXAA
+ else
+ {
+ // Coded PHY (Long range)
+ NRF_RADIO->PCNF0 = (m_packetHeaderS1len << RADIO_PCNF0_S1LEN_Pos) |
+ (m_packetHeaderS0len << RADIO_PCNF0_S0LEN_Pos) |
+ (m_packetHeaderLFlen << RADIO_PCNF0_LFLEN_Pos) |
+ (3 << RADIO_PCNF0_TERMLEN_Pos) |
+ (2 << RADIO_PCNF0_CILEN_Pos) |
+ (m_packetHeaderPlen << RADIO_PCNF0_PLEN_Pos);
+ }
+#endif
+
+ NRF_RADIO->PCNF1 = (m_whitening << RADIO_PCNF1_WHITEEN_Pos) |
+ (m_endian << RADIO_PCNF1_ENDIAN_Pos) |
+ (m_balen << RADIO_PCNF1_BALEN_Pos) |
+ (m_static_length << RADIO_PCNF1_STATLEN_Pos) |
+ (DTM_PAYLOAD_MAX_SIZE << RADIO_PCNF1_MAXLEN_Pos);
+
+ return DTM_SUCCESS;
+}
+
+
+/**@brief Function for preparing the radio. At start of each test: Turn off RF, clear interrupt flags of RF, initialize the radio
+ * at given RF channel.
+ *
+ *@param[in] rx boolean indicating if radio should be prepared in rx mode (true) or tx mode.
+ */
+static void radio_prepare(bool rx)
+{
+ dtm_turn_off_test();
+ NRF_RADIO->CRCPOLY = m_crc_poly;
+ NRF_RADIO->CRCINIT = m_crc_init;
+ NRF_RADIO->FREQUENCY = (m_phys_ch << 1) + 2; // Actual frequency (MHz): 2400 + register value
+ NRF_RADIO->PACKETPTR = (uint32_t)&m_pdu; // Setting packet pointer will start the radio
+ NRF_RADIO->EVENTS_READY = 0;
+ NRF_RADIO->SHORTS = (1 << RADIO_SHORTS_READY_START_Pos) | // Shortcut between READY event and START task
+ (1 << RADIO_SHORTS_END_DISABLE_Pos); // Shortcut between END event and DISABLE task
+
+ if (rx)
+ {
+ NRF_RADIO->EVENTS_END = 0;
+ NRF_RADIO->TASKS_RXEN = 1; // shorts will start radio in RX mode when it is ready
+ }
+ else // tx
+ {
+ NRF_RADIO->TXPOWER = m_tx_power;
+ }
+}
+
+
+/**@brief Function for terminating the ongoing test (if any) and closing down the radio.
+ */
+static void dtm_test_done(void)
+{
+ dtm_turn_off_test();
+ NRF_PPI->CHENCLR = 0x01;
+ NRF_PPI->CH[0].EEP = 0; // Break connection from timer to radio to stop transmit loop
+ NRF_PPI->CH[0].TEP = 0;
+
+ radio_reset();
+ m_state = STATE_IDLE;
+}
+
+
+/**@brief Function for configuring the timer for 625us cycle time.
+ */
+static uint32_t timer_init(void)
+{
+ // Use 16MHz from external crystal
+ // This could be customized for RC/Xtal, or even to use a 32 kHz crystal
+ NRF_CLOCK->EVENTS_HFCLKSTARTED = 0;
+ NRF_CLOCK->TASKS_HFCLKSTART = 1;
+
+ while (NRF_CLOCK->EVENTS_HFCLKSTARTED == 0)
+ {
+ // Do nothing while waiting for the clock to start
+ }
+
+ mp_timer->TASKS_STOP = 1; // Stop timer, if it was running
+ mp_timer->TASKS_CLEAR = 1;
+ mp_timer->MODE = TIMER_MODE_MODE_Timer; // Timer mode (not counter)
+ mp_timer->EVENTS_COMPARE[0] = 0; // clean up possible old events
+ mp_timer->EVENTS_COMPARE[1] = 0;
+ mp_timer->EVENTS_COMPARE[2] = 0;
+ mp_timer->EVENTS_COMPARE[3] = 0;
+
+ // Timer is polled, but enable the compare0 interrupt in order to wakeup from CPU sleep
+ mp_timer->INTENSET = TIMER_INTENSET_COMPARE0_Msk;
+ mp_timer->SHORTS = 1 << TIMER_SHORTS_COMPARE0_CLEAR_Pos; // Clear the count every time timer reaches the CCREG0 count
+ mp_timer->PRESCALER = 4; // Input clock is 16MHz, timer clock = 2 ^ prescale -> interval 1us
+ mp_timer->CC[0] = m_txIntervaluS; // 625uS with 1MHz clock to the timer
+ mp_timer->CC[1] = UART_POLL_CYCLE; // Depends on the baud rate of the UART. Default baud rate of 19200 will result in a 260uS time with 1MHz clock to the timer
+ mp_timer->TASKS_START = 1; // Start the timer - it will be running continuously
+ m_current_time = 0;
+ return DTM_SUCCESS;
+}
+
+
+/**@brief Function for handling vendor specific commands.
+ * Used when packet type is set to Vendor specific.
+ * The length field is used for encoding vendor specific command.
+ * The frequency field is used for encoding vendor specific options to the command.
+ *
+ * @param[in] vendor_cmd Vendor specific command to be executed.
+ * @param[in] vendor_option Vendor specific option to the vendor command.
+ *
+ * @return DTM_SUCCESS or one of the DTM_ERROR_ values
+ */
+static uint32_t dtm_vendor_specific_pkt(uint32_t vendor_cmd, dtm_freq_t vendor_option)
+{
+ switch (vendor_cmd)
+ {
+ // nRFgo Studio uses CARRIER_TEST_STUDIO to indicate a continuous carrier without
+ // a modulated signal.
+ case CARRIER_TEST:
+ case CARRIER_TEST_STUDIO:
+ // Not a packet type, but used to indicate that a continuous carrier signal
+ // should be transmitted by the radio.
+ radio_prepare(TX_MODE);
+
+ dtm_constant_carrier();
+
+ // Shortcut between READY event and START task
+ NRF_RADIO->SHORTS = 1 << RADIO_SHORTS_READY_START_Pos;
+
+ // Shortcut will start radio in Tx mode when it is ready
+ NRF_RADIO->TASKS_TXEN = 1;
+ m_state = STATE_CARRIER_TEST;
+ break;
+
+ case SET_TX_POWER:
+ if (!dtm_set_txpower(vendor_option))
+ {
+ m_event = LE_TEST_STATUS_EVENT_ERROR;
+ return DTM_ERROR_ILLEGAL_CONFIGURATION;
+ }
+ break;
+
+ case SELECT_TIMER:
+ if (!dtm_set_timer(vendor_option))
+ {
+ m_event = LE_TEST_STATUS_EVENT_ERROR;
+ return DTM_ERROR_ILLEGAL_CONFIGURATION;
+ }
+ break;
+ }
+ // Event code is unchanged, successful
+ return DTM_SUCCESS;
+}
+
+
+static uint32_t dtm_packet_interval_calculate(uint32_t test_payload_length, uint32_t mode)
+{
+ uint32_t test_packet_length = 0; // [us] NOTE: bits are us at 1Mbit
+ uint32_t packet_interval = 0; // us
+ uint32_t overhead_bits = 0; // bits
+
+ /* packet overhead
+ * see BLE [Vol 6, Part F] page 213
+ * 4.1 LE TEST PACKET FORMAT */
+ if (mode == RADIO_MODE_MODE_Ble_2Mbit)
+ {
+ // 16 preamble
+ // 32 sync word
+ // 8 PDU header, actually packetHeaderS0len * 8
+ // 8 PDU length, actually packetHeaderLFlen
+ // 24 CRC
+ overhead_bits = 88; // 11 bytes
+ }
+ else if (mode == RADIO_MODE_MODE_Ble_1Mbit)
+ {
+ // 8 preamble
+ // 32 sync word
+ // 8 PDU header, actually packetHeaderS0len * 8
+ // 8 PDU length, actually packetHeaderLFlen
+ // 24 CRC
+ overhead_bits = 80; // 10 bytes
+ }
+#ifdef NRF52840_XXAA
+ else if (mode == RADIO_MODE_MODE_Ble_LR125Kbit)
+ {
+ // 80 preamble
+ // 32 * 8 sync word coding=8
+ // 2 * 8 Coding indicator, coding=8
+ // 3 * 8 TERM1 coding=8
+ // 8 * 8 PDU header, actually packetHeaderS0len * 8 coding=8
+ // 8 * 8 PDU length, actually packetHeaderLFlen coding=8
+ // 24 * 8 CRC coding=8
+ // 3 * 8 TERM2 coding=8
+ overhead_bits = 720; // 90 bytes
+ }
+ else if (mode == RADIO_MODE_MODE_Ble_LR500Kbit)
+ {
+ // 80 preamble
+ // 32 * 8 sync word coding=8
+ // 2 * 8 Coding indicator, coding=8
+ // 3 * 8 TERM 1 coding=8
+ // 8 * 2 PDU header, actually packetHeaderS0len * 8 coding=2
+ // 8 * 2 PDU length, actually packetHeaderLFlen coding=2
+ // 24 * 2 CRC coding=2
+ // 3 * 2 TERM2 coding=2
+ // NOTE: this makes us clock out 46 bits for CI + TERM1 + TERM2
+ // assumption the radio will handle this
+ overhead_bits = 462; // 57.75 bytes
+ }
+#endif
+ /* add PDU payload test_payload length */
+ test_packet_length = (test_payload_length * 8); // in bits
+#ifdef NRF52840_XXAA
+ // account for the encoding of PDU
+ if (mode == RADIO_MODE_MODE_Ble_LR125Kbit)
+ {
+ test_packet_length *= 8; // 1 to 8 encoding
+ }
+ if (mode == RADIO_MODE_MODE_Ble_LR500Kbit)
+ {
+ test_packet_length *= 2; // 1 to 2 encoding
+ }
+#endif
+ // add overhead calculated above
+ test_packet_length += overhead_bits;
+ // we remember this bits are us in 1Mbit
+ if (mode == RADIO_MODE_MODE_Ble_2Mbit)
+ {
+ test_packet_length /= 2; // double speed
+ }
+
+ /*
+ * packet_interval = ceil((test_packet_length+249)/625)*625
+ * NOTE: To avoid floating point an equivalent calculation is used.
+ */
+ uint32_t i = 0;
+ uint32_t timeout = 0;
+ do
+ {
+ i++;
+ timeout = i * 625;
+ } while (test_packet_length + 249 > timeout);
+ packet_interval = i * 625;
+
+ return packet_interval;
+}
+
+
+uint32_t dtm_init(void)
+{
+ if ((timer_init() != DTM_SUCCESS) || (radio_init() != DTM_SUCCESS))
+ {
+ return DTM_ERROR_ILLEGAL_CONFIGURATION;
+ }
+ m_new_event = false;
+ m_state = STATE_IDLE;
+ m_packet_length = 0;
+
+ // Enable wake-up on event
+ SCB->SCR |= SCB_SCR_SEVONPEND_Msk;
+
+ return DTM_SUCCESS;
+}
+
+
+uint32_t dtm_wait(void)
+{
+ // Enable wake-up on event
+ SCB->SCR |= SCB_SCR_SEVONPEND_Msk;
+
+ for (;;)
+ {
+ // Event may be the reception of a packet -
+ // handle radio first, to give it highest priority:
+ if (NRF_RADIO->EVENTS_END != 0)
+ {
+ NRF_RADIO->EVENTS_END = 0;
+ NVIC_ClearPendingIRQ(RADIO_IRQn);
+
+ if (m_state == STATE_RECEIVER_TEST)
+ {
+ NRF_RADIO->TASKS_RXEN = 1;
+ if ((NRF_RADIO->CRCSTATUS == 1) && check_pdu())
+ {
+ // Count the number of successfully received packets
+ m_rx_pkt_count++;
+ }
+ // Note that failing packets are simply ignored (CRC or contents error).
+
+ // Zero fill all pdu fields to avoid stray data
+ memset(&m_pdu, 0, DTM_PDU_MAX_MEMORY_SIZE);
+ }
+ // If no RECEIVER_TEST is running, ignore incoming packets (but do clear IRQ!)
+ }
+
+ // Check for timeouts:
+ if (mp_timer->EVENTS_COMPARE[0] != 0)
+ {
+ mp_timer->EVENTS_COMPARE[0] = 0;
+ }
+ else if (mp_timer->EVENTS_COMPARE[1] != 0)
+ {
+ // Reset timeout event flag for next iteration.
+ mp_timer->EVENTS_COMPARE[1] = 0;
+ NVIC_ClearPendingIRQ(m_timer_irq);
+ return ++m_current_time;
+ }
+
+ // Other events: No processing
+ }
+}
+
+uint32_t dtm_cmd(dtm_cmd_t cmd, dtm_freq_t freq, uint32_t length, dtm_pkt_type_t payload)
+{
+ // Save specified packet in static variable for tx/rx functions to use.
+ // Note that BLE conformance testers always use full length packets.
+ m_packet_length = (m_packet_length & 0xC0) | ((uint8_t)length & 0x3F);
+ m_packet_type = payload;
+ m_phys_ch = freq;
+
+ // If 1 Mbit or 2 Mbit radio mode is in use check for Vendor Specific payload.
+ if ((m_radio_mode == RADIO_MODE_MODE_Ble_1Mbit || m_radio_mode == RADIO_MODE_MODE_Ble_2Mbit) && payload == DTM_PKT_VENDORSPECIFIC)
+ {
+ /* Note that in a HCI adaption layer, as well as in the DTM PDU format,
+ the value 0x03 is a distinct bit pattern (PRBS15). Even though BLE does not
+ support PRBS15, this implementation re-maps 0x03 to DTM_PKT_VENDORSPECIFIC,
+ to avoid the risk of confusion, should the code be extended to greater coverage.
+ */
+ m_packet_type = DTM_PKT_TYPE_VENDORSPECIFIC;
+ }
+
+ // Clean out any non-retrieved event that might linger from an earlier test
+ m_new_event = true;
+
+ // Set default event; any error will set it to LE_TEST_STATUS_EVENT_ERROR
+ m_event = LE_TEST_STATUS_EVENT_SUCCESS;
+
+ if (m_state == STATE_UNINITIALIZED)
+ {
+ // Application has not explicitly initialized DTM,
+ return DTM_ERROR_UNINITIALIZED;
+ }
+
+ if (cmd == LE_TEST_SETUP)
+ {
+ // Note that timer will continue running after a reset
+ dtm_test_done();
+ if (freq == LE_TEST_SETUP_RESET)
+ {
+ if (length != 0x00)
+ {
+ m_event = LE_TEST_STATUS_EVENT_ERROR;
+ return DTM_ERROR_ILLEGAL_CONFIGURATION;
+ }
+ // Reset the packet length upper bits.
+ m_packet_length = 0;
+
+ // Reset the selected PHY to 1Mbit
+ m_radio_mode = RADIO_MODE_MODE_Ble_1Mbit;
+ m_packetHeaderPlen = RADIO_PCNF0_PLEN_8bit;
+
+#ifdef NRF52840_XXAA
+ // Workaround for Errata ID 164
+ *(volatile uint32_t *)0x4000173C &= ~0x80000000;
+
+ // Workaround for Errata ID 191
+ *(volatile uint32_t *) 0x40001740 = ((*((volatile uint32_t *) 0x40001740)) & 0x7FFFFFFF);
+#endif
+ }
+ else if (freq == LE_TEST_SETUP_SET_UPPER)
+ {
+ if (length > 0x03)
+ {
+ m_event = LE_TEST_STATUS_EVENT_ERROR;
+ return DTM_ERROR_ILLEGAL_CONFIGURATION;
+ }
+ m_packet_length = length << 6;
+ }
+ else if (freq == LE_TEST_SETUP_SET_PHY)
+ {
+ switch (length)
+ {
+ case LE_PHY_1M:
+ m_radio_mode = RADIO_MODE_MODE_Ble_1Mbit;
+ m_packetHeaderPlen = RADIO_PCNF0_PLEN_8bit;
+
+#ifdef NRF52840_XXAA
+ // Workaround for Errata ID 164
+ *(volatile uint32_t *)0x4000173C &= ~0x80000000;
+
+ // Workaround for Errata ID 191
+ *(volatile uint32_t *) 0x40001740 = ((*((volatile uint32_t *) 0x40001740)) & 0x7FFFFFFF);
+#endif
+
+ return radio_init();
+
+ case LE_PHY_2M:
+ m_radio_mode = RADIO_MODE_MODE_Ble_2Mbit;
+ m_packetHeaderPlen = RADIO_PCNF0_PLEN_16bit;
+
+#ifdef NRF52840_XXAA
+ // Workaround for Errata ID 164
+ *(volatile uint32_t *)0x4000173C &= ~0x80000000;
+
+ // Workaround for Errata ID 191
+ *(volatile uint32_t *) 0x40001740 = ((*((volatile uint32_t *) 0x40001740)) & 0x7FFFFFFF);
+#endif
+
+ return radio_init();
+
+ case LE_PHY_LE_CODED_S8:
+#ifdef NRF52840_XXAA
+ m_radio_mode = RADIO_MODE_MODE_Ble_LR125Kbit;
+ m_packetHeaderPlen = RADIO_PCNF0_PLEN_LongRange;
+
+ // Workaround for Errata ID 164
+ *(volatile uint32_t *)0x4000173C |= 0x80000000;
+ *(volatile uint32_t *)0x4000173C = ((*(volatile uint32_t *)0x4000173C & 0xFFFFFF00) | 0x5C);
+
+ // Workaround for Errata ID 191
+ *(volatile uint32_t *) 0x40001740 = ((*((volatile uint32_t *) 0x40001740)) & 0x7FFF00FF) | 0x80000000 | (((uint32_t)(196)) << 8);
+
+ return radio_init();
+#else
+ m_event = LE_TEST_STATUS_EVENT_ERROR;
+ return DTM_ERROR_ILLEGAL_CONFIGURATION;
+#endif // NRF52840_XXAA
+ case LE_PHY_LE_CODED_S2:
+#ifdef NRF52840_XXAA
+ m_radio_mode = RADIO_MODE_MODE_Ble_LR500Kbit;
+ m_packetHeaderPlen = RADIO_PCNF0_PLEN_LongRange;
+
+ // Workaround for Errata ID 164
+ *(volatile uint32_t *)0x4000173C |= 0x80000000;
+ *(volatile uint32_t *)0x4000173C = ((*(volatile uint32_t *)0x4000173C & 0xFFFFFF00) | 0x5C);
+
+ // Workaround for Errata ID 191
+ *(volatile uint32_t *) 0x40001740 = ((*((volatile uint32_t *) 0x40001740)) & 0x7FFF00FF) | 0x80000000 | (((uint32_t)(196)) << 8);
+
+ return radio_init();
+#else
+ m_event = LE_TEST_STATUS_EVENT_ERROR;
+ return DTM_ERROR_ILLEGAL_CONFIGURATION;
+#endif
+ default:
+ m_event = LE_TEST_STATUS_EVENT_ERROR;
+ return DTM_ERROR_ILLEGAL_CONFIGURATION;
+ }
+ }
+ else if(freq == LE_TEST_SETUP_SELECT_MODULATION)
+ {
+ if (length > 0x01)
+ {
+ m_event = LE_TEST_STATUS_EVENT_ERROR;
+ return DTM_ERROR_ILLEGAL_CONFIGURATION;
+ }
+ // Only standard modulation is supported.
+ }
+ else if (freq == LE_TEST_SETUP_READ_SUPPORTED)
+ {
+ if (length != 0x00)
+ {
+ m_event = LE_TEST_STATUS_EVENT_ERROR;
+ return DTM_ERROR_ILLEGAL_CONFIGURATION;
+ }
+ // 0XXXXXXXXXXX0110 indicate that 2Mbit and DLE is supported and stable modulation is not supported (No nRF5 device supports this).
+ m_event = 0x0006;
+ }
+ else if (freq == LE_TEST_SETUP_READ_MAX)
+ {
+ // Read max supported value.
+ switch (length)
+ {
+ case 0x00:
+ // Read supportedMaxTxOctets
+ m_event = 0x01FE;
+ break;
+
+ case 0x01:
+ // Read supportedMaxTxTime
+ m_event = 0x4290;
+ break;
+
+ case 0x02:
+ // Read supportedMaxRxOctets
+ m_event = 0x01FE;
+ break;
+
+ case 0x03:
+ // Read supportedMaxRxTime
+ m_event = 0x4290;
+ break;
+
+ default:
+ m_event = LE_TEST_STATUS_EVENT_ERROR;
+ return DTM_ERROR_ILLEGAL_CONFIGURATION;
+ }
+ }
+ else
+ {
+ m_event = LE_TEST_STATUS_EVENT_ERROR;
+ return DTM_ERROR_ILLEGAL_CONFIGURATION;
+ }
+ return DTM_SUCCESS;
+ }
+
+ if (cmd == LE_TEST_END)
+ {
+ if (m_state == STATE_IDLE)
+ {
+ // Sequencing error - only rx or tx test may be ended!
+ m_event = LE_TEST_STATUS_EVENT_ERROR;
+ return DTM_ERROR_INVALID_STATE;
+ }
+ m_event = LE_PACKET_REPORTING_EVENT | m_rx_pkt_count;
+ dtm_test_done();
+ return DTM_SUCCESS;
+ }
+
+ if (m_state != STATE_IDLE)
+ {
+ // Sequencing error - only TEST_END/RESET are legal while test is running
+ // Note: State is unchanged; ongoing test not affected
+ m_event = LE_TEST_STATUS_EVENT_ERROR;
+ return DTM_ERROR_INVALID_STATE;
+ }
+
+ // Check for illegal values of m_phys_ch. Skip the check if the packet is vendor spesific.
+ if (payload != DTM_PKT_VENDORSPECIFIC && m_phys_ch > PHYS_CH_MAX)
+ {
+ // Parameter error
+ // Note: State is unchanged; ongoing test not affected
+ m_event = LE_TEST_STATUS_EVENT_ERROR;
+
+ return DTM_ERROR_ILLEGAL_CHANNEL;
+ }
+
+ m_rx_pkt_count = 0;
+
+ if (cmd == LE_RECEIVER_TEST)
+ {
+ // Zero fill all pdu fields to avoid stray data from earlier test run
+ memset(&m_pdu, 0, DTM_PDU_MAX_MEMORY_SIZE);
+ radio_prepare(RX_MODE); // Reinitialize "everything"; RF interrupts OFF
+ m_state = STATE_RECEIVER_TEST;
+ return DTM_SUCCESS;
+ }
+
+ if (cmd == LE_TRANSMITTER_TEST)
+ {
+ // Check for illegal values of m_packet_length. Skip the check if the packet is vendor spesific.
+ if (m_packet_type != DTM_PKT_TYPE_VENDORSPECIFIC && m_packet_length > DTM_PAYLOAD_MAX_SIZE)
+ {
+ // Parameter error
+ m_event = LE_TEST_STATUS_EVENT_ERROR;
+ return DTM_ERROR_ILLEGAL_LENGTH;
+ }
+
+
+ m_pdu.content[DTM_LENGTH_OFFSET] = m_packet_length;
+ // Note that PDU uses 4 bits even though BLE DTM uses only 2 (the HCI SDU uses all 4)
+ switch (m_packet_type)
+ {
+ case DTM_PKT_PRBS9:
+ m_pdu.content[DTM_HEADER_OFFSET] = DTM_PDU_TYPE_PRBS9;
+ // Non-repeated, must copy entire pattern to PDU
+ memcpy(m_pdu.content + DTM_HEADER_SIZE, m_prbs_content, m_packet_length);
+ break;
+
+ case DTM_PKT_0X0F:
+ m_pdu.content[DTM_HEADER_OFFSET] = DTM_PDU_TYPE_0X0F;
+ // Bit pattern 00001111 repeated
+ memset(m_pdu.content + DTM_HEADER_SIZE, RFPHY_TEST_0X0F_REF_PATTERN, m_packet_length);
+ break;
+
+ case DTM_PKT_0X55:
+ m_pdu.content[DTM_HEADER_OFFSET] = DTM_PDU_TYPE_0X55;
+ // Bit pattern 01010101 repeated
+ memset(m_pdu.content + DTM_HEADER_SIZE, RFPHY_TEST_0X55_REF_PATTERN, m_packet_length);
+ break;
+
+ case DTM_PKT_0XFF:
+ m_pdu.content[DTM_HEADER_OFFSET] = DTM_PDU_TYPE_0XFF;
+ // Bit pattern 11111111 repeated. Only available in coded PHY (Long range).
+ memset(m_pdu.content + DTM_HEADER_SIZE, RFPHY_TEST_0XFF_REF_PATTERN, m_packet_length);
+ break;
+
+ case DTM_PKT_TYPE_VENDORSPECIFIC:
+ // The length field is for indicating the vendor specific command to execute.
+ // The frequency field is used for vendor specific options to the command.
+ return dtm_vendor_specific_pkt(length, freq);
+
+ default:
+ // Parameter error
+ m_event = LE_TEST_STATUS_EVENT_ERROR;
+ return DTM_ERROR_ILLEGAL_CONFIGURATION;
+ }
+
+ // Initialize CRC value, set channel:
+ radio_prepare(TX_MODE);
+
+ // Set the timer to the correct period. The delay between each packet is described in the
+ // Bluetooth Core Spsification version 4.2 Vol. 6 Part F Section 4.1.6.
+ mp_timer->CC[0] = dtm_packet_interval_calculate(m_packet_length, m_radio_mode);
+
+ // Configure PPI so that timer will activate radio every 625 us
+ NRF_PPI->CH[0].EEP = (uint32_t)&mp_timer->EVENTS_COMPARE[0];
+ NRF_PPI->CH[0].TEP = (uint32_t)&NRF_RADIO->TASKS_TXEN;
+ NRF_PPI->CHENSET = 0x01;
+ m_state = STATE_TRANSMITTER_TEST;
+ }
+ return DTM_SUCCESS;
+}
+
+
+bool dtm_event_get(dtm_event_t *p_dtm_event)
+{
+ bool was_new = m_new_event;
+ // mark the current event as retrieved
+ m_new_event = false;
+ *p_dtm_event = m_event;
+ // return value indicates whether this value was already retrieved.
+ return was_new;
+}
+
+
+// =================================================================================================
+// Configuration functions (only for parameters not definitely determined by the BLE DTM standard).
+// These functions return true if successful, false if value could not be set
+
+
+/**@brief Function for configuring the output power for transmitter test.
+ This function may be called directly, or through dtm_cmd() specifying
+ DTM_PKT_VENDORSPECIFIC as payload, SET_TX_POWER as length, and the dBm value as frequency.
+ */
+bool dtm_set_txpower(uint32_t new_tx_power)
+{
+ // radio->TXPOWER register is 32 bits, low octet a signed value, upper 24 bits zeroed
+ int8_t new_power8 = (int8_t)(new_tx_power & 0xFF);
+
+ // The two most significant bits are not sent in the 6 bit field of the DTM command.
+ // These two bits are 1's if and only if the tx_power is a negative number.
+ // All valid negative values have the fourth most significant bit as 1.
+ // All valid positive values have the fourth most significant bit as 0.
+ // By checking this bit, the two most significant bits can be determined.
+ new_power8 = (new_power8 & 0x30) != 0 ? (new_power8 | 0xC0) : new_power8;
+
+ if (m_state > STATE_IDLE)
+ {
+ // radio must be idle to change the tx power
+ return false;
+ }
+
+ m_tx_power = new_power8;
+
+ return true;
+}
+
+
+/**@brief Function for selecting a timer resource.
+ * This function may be called directly, or through dtm_cmd() specifying
+ * DTM_PKT_VENDORSPECIFIC as payload, SELECT_TIMER as length, and the timer as freq
+ *
+ * @param[in] new_timer Timer id for the timer to use: 0, 1, or 2.
+ *
+ * @return true if the timer was successfully changed, false otherwise.
+ */
+bool dtm_set_timer(uint32_t new_timer)
+{
+ if (m_state > STATE_IDLE)
+ {
+ return false;
+ }
+ return dtm_hw_set_timer(&mp_timer, &m_timer_irq, new_timer);
+}
+
+/// @}
+#endif // NRF_MODULE_ENABLED(BLE_DTM)
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_dtm/ble_dtm.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_dtm/ble_dtm.h
new file mode 100644
index 0000000..61f92c5
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_dtm/ble_dtm.h
@@ -0,0 +1,237 @@
+/**
+ * Copyright (c) 2012 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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
+ *
+ * @defgroup ble_dtm DTM - Direct Test Mode
+ * @{
+ * @ingroup ble_sdk_lib
+ * @brief Module for testing RF/PHY using DTM commands.
+ */
+
+#ifndef BLE_DTM_H__
+#define BLE_DTM_H__
+
+#include <stdint.h>
+#include <stdbool.h>
+#include "nrf.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+/**@brief Configuration parameters. */
+#define DTM_BITRATE UARTE_BAUDRATE_BAUDRATE_Baud19200 /**< Serial bitrate on the UART */
+#define DEFAULT_TX_POWER RADIO_TXPOWER_TXPOWER_0dBm /**< Default Transmission power using in the DTM module. */
+#define DEFAULT_TIMER NRF_TIMER0 /**< Default timer used for timing. */
+#define DEFAULT_TIMER_IRQn TIMER0_IRQn /**< IRQ used for timer. NOTE: MUST correspond to DEFAULT_TIMER. */
+
+/**@brief BLE DTM command codes. */
+typedef uint32_t dtm_cmd_t; /**< DTM command type. */
+
+#define LE_TEST_SETUP 0 /**< DTM command: Set PHY or modulation, configure upper two bits of length,
+ request matrix of supported features or request max values of parameters. */
+#define LE_RECEIVER_TEST 1 /**< DTM command: Start receive test. */
+#define LE_TRANSMITTER_TEST 2 /**< DTM command: Start transmission test. */
+#define LE_TEST_END 3 /**< DTM command: End test and send packet report. */
+
+#define LE_TEST_SETUP_RESET 0 /**< DTM command parameter: Stop TX/RX, reset the packet length upper bits and set the PHY to 1Mbit. */
+#define LE_TEST_SETUP_SET_UPPER 1 /**< DTM command parameter: Set the upper two bits of the length field. */
+#define LE_TEST_SETUP_SET_PHY 2 /**< DTM command parameter: Select the PHY to be used for packets. */
+#define LE_TEST_SETUP_SELECT_MODULATION 3 /**< DTM command parameter: Select standard or stable modulation index. Stable modulation index is not supported. */
+#define LE_TEST_SETUP_READ_SUPPORTED 4 /**< DTM command parameter: Read the supported test case features. */
+#define LE_TEST_SETUP_READ_MAX 5 /**< DTM command parameter: Read the max supported time and length for packets. */
+
+#define LE_PHY_1M 1 /**< DTM command parameter: Set PHY for future packets to use 1MBit PHY. */
+#define LE_PHY_2M 2 /**< DTM command parameter: Set PHY for future packets to use 2MBit PHY. */
+#define LE_PHY_LE_CODED_S8 3 /**< DTM command parameter: Set PHY for future packets to use coded PHY with S=8. */
+#define LE_PHY_LE_CODED_S2 4 /**< DTM command parameter: Set PHY for future packets to use coded PHY with S=2 */
+
+// Configuration options used as parameter 2
+// when cmd == LE_TRANSMITTER_TEST and payload == DTM_PKT_VENDORSPECIFIC
+// Configuration value, if any, is supplied in parameter 3
+
+#define CARRIER_TEST 0 /**< Length=0 indicates a constant, unmodulated carrier until LE_TEST_END or LE_RESET */
+#define CARRIER_TEST_STUDIO 1 /**< nRFgo Studio uses value 1 in length field, to indicate a constant, unmodulated carrier until LE_TEST_END or LE_RESET */
+#define SET_TX_POWER 2 /**< Set transmission power, value -40..+4 dBm in steps of 4 */
+#define SELECT_TIMER 3 /**< Select on of the 16 MHz timers 0, 1 or 2 */
+
+#define LE_PACKET_REPORTING_EVENT 0x8000 /**< DTM Packet reporting event, returned by the device to the tester. */
+#define LE_TEST_STATUS_EVENT_SUCCESS 0x0000 /**< DTM Status event, indicating success. */
+#define LE_TEST_STATUS_EVENT_ERROR 0x0001 /**< DTM Status event, indicating an error. */
+
+#define DTM_PKT_PRBS9 0x00 /**< Bit pattern PRBS9. */
+#define DTM_PKT_0X0F 0x01 /**< Bit pattern 11110000 (LSB is the leftmost bit). */
+#define DTM_PKT_0X55 0x02 /**< Bit pattern 10101010 (LSB is the leftmost bit). */
+#define DTM_PKT_0XFF 0x03 /**< Bit pattern 11111111 (Used only for coded PHY). */
+#define DTM_PKT_VENDORSPECIFIC 0x03 /**< Vendor specific PKT field value. Nordic: Continuous carrier test, or configuration. */
+#define DTM_PKT_TYPE_VENDORSPECIFIC 0xFF /**< Vendor specific packet type for internal use. */
+
+// The pdu payload type for each bit pattern. Identical to the PKT value except pattern 0xFF which is 0x04.
+#define DTM_PDU_TYPE_PRBS9 0x00 /**< PDU payload type for bit pattern PRBS9. */
+#define DTM_PDU_TYPE_0X0F 0x01 /**< PDU payload type for bit pattern 11110000 (LSB is the leftmost bit). */
+#define DTM_PDU_TYPE_0X55 0x02 /**< PDU payload type for bit pattern 10101010 (LSB is the leftmost bit). */
+#define DTM_PDU_TYPE_0XFF 0x04 /**< PDU payload type for bit pattern 11111111 (Used only for coded PHY). */
+
+/**@brief Return codes from dtm_cmd(). */
+#define DTM_SUCCESS 0x00 /**< Indicate that the DTM function completed with success. */
+#define DTM_ERROR_ILLEGAL_CHANNEL 0x01 /**< Physical channel number must be in the range 0..39. */
+#define DTM_ERROR_INVALID_STATE 0x02 /**< Sequencing error: Command is not valid now. */
+#define DTM_ERROR_ILLEGAL_LENGTH 0x03 /**< Payload size must be in the range 0..37. */
+#define DTM_ERROR_ILLEGAL_CONFIGURATION 0x04 /**< Parameter out of range (legal range is function dependent). */
+#define DTM_ERROR_UNINITIALIZED 0x05 /**< DTM module has not been initialized by the application. */
+
+/**@details The UART poll cycle in micro seconds.
+ * A baud rate of e.g. 19200 bits / second, and 8 data bits, 1 start/stop bit, no flow control,
+ * give the time to transmit a byte: 10 bits * 1/19200 = approx: 520 us.
+ * To ensure no loss of bytes, the UART should be polled every 260 us.
+ */
+#if DTM_BITRATE == UARTE_BAUDRATE_BAUDRATE_Baud9600
+#define UART_POLL_CYCLE ((uint32_t)(10*1e6/9600/2))
+#elif DTM_BITRATE == UARTE_BAUDRATE_BAUDRATE_Baud14400
+#define UART_POLL_CYCLE ((uint32_t)(10*1e6/14400/2))
+#elif DTM_BITRATE == UARTE_BAUDRATE_BAUDRATE_Baud19200
+#define UART_POLL_CYCLE ((uint32_t)(10*1e6/19200/2))
+#elif DTM_BITRATE == UARTE_BAUDRATE_BAUDRATE_Baud28800
+#define UART_POLL_CYCLE ((uint32_t)(10*1e6/28800/2))
+#elif DTM_BITRATE == UARTE_BAUDRATE_BAUDRATE_Baud38400
+#define UART_POLL_CYCLE ((uint32_t)(10*1e6/38400/2))
+#elif DTM_BITRATE == UARTE_BAUDRATE_BAUDRATE_Baud57600
+#define UART_POLL_CYCLE ((uint32_t)(10*1e6/57600/2))
+#elif DTM_BITRATE == UARTE_BAUDRATE_BAUDRATE_Baud76800
+#define UART_POLL_CYCLE ((uint32_t)(10*1e6/768000/2))
+#elif DTM_BITRATE == UARTE_BAUDRATE_BAUDRATE_Baud115200
+#define UART_POLL_CYCLE ((uint32_t)(10*1e6/115200/2))
+#elif DTM_BITRATE == UARTE_BAUDRATE_BAUDRATE_Baud230400
+#define UART_POLL_CYCLE ((uint32_t)(10*1e6/230400/2))
+#elif DTM_BITRATE == UARTE_BAUDRATE_BAUDRATE_Baud250000
+#define UART_POLL_CYCLE ((uint32_t)(10*1e6/250000/2))
+#elif DTM_BITRATE == UARTE_BAUDRATE_BAUDRATE_Baud460800
+#define UART_POLL_CYCLE ((uint32_t)(10*1e6/460800/2))
+#elif DTM_BITRATE == UARTE_BAUDRATE_BAUDRATE_Baud921600
+#define UART_POLL_CYCLE ((uint32_t)(10*1e6/921600/2))
+#elif DTM_BITRATE == UARTE_BAUDRATE_BAUDRATE_Baud1M
+#define UART_POLL_CYCLE ((uint32_t)(10*1e6/1e6/2))
+#else
+// It is possible to find values that work for other baud rates, but the formula above is not
+// guaranteed to work for all values. Suitable values may have to be found by trial and error.
+#error "Unsupported baud rate set."
+#endif
+
+// Note: DTM_PKT_VENDORSPECIFIC, is not a packet type
+#define PACKET_TYPE_MAX DTM_PKT_0XFF /**< Highest value allowed as DTM Packet type. */
+
+/** @brief BLE DTM event type. */
+typedef uint32_t dtm_event_t; /**< Type for handling DTM event. */
+
+/** @brief BLE DTM frequency type. */
+typedef uint32_t dtm_freq_t; /**< Physical channel, valid range: 0..39. */
+
+/**@brief BLE DTM packet types. */
+typedef uint32_t dtm_pkt_type_t; /**< Type for holding the requested DTM payload type.*/
+
+
+/**@brief Function for initializing or re-initializing DTM module
+ *
+ * @return DTM_SUCCESS on successful initialization of the DTM module.
+*/
+uint32_t dtm_init(void);
+
+
+/**@brief Function for giving control to dtmlib for handling timer and radio events.
+ * Will return to caller at 625us intervals or whenever another event than radio occurs
+ * (such as UART input). Function will put MCU to sleep between events.
+ *
+ * @return Time counter, incremented every 625 us.
+ */
+uint32_t dtm_wait(void);
+
+
+/**@brief Function for calling when a complete command has been prepared by the Tester.
+ *
+ * @param[in] cmd One of the DTM_CMD values (bits 14:15 in the 16-bit UART format).
+ * @param[in] freq Phys. channel no - actual frequency = (2402 + freq * 2) MHz (bits 8:13 in
+ * the 16-bit UART format).
+ * @param[in] length Payload length, 0..37 (bits 2:7 in the 16-bit UART format).
+ * @param[in] payload One of the DTM_PKT values (bits 0:1 in the 16-bit UART format).
+ *
+ * @return DTM_SUCCESS or one of the DTM_ERROR_ values
+ */
+uint32_t dtm_cmd(dtm_cmd_t cmd, dtm_freq_t freq, uint32_t length, dtm_pkt_type_t payload);
+
+
+/**@brief Function for reading the result of a DTM command
+ *
+ * @param[out] p_dtm_event Pointer to buffer for 16 bit event code according to DTM standard.
+ *
+ * @return true: new event, false: no event since last call, this event has been read earlier
+ */
+bool dtm_event_get(dtm_event_t * p_dtm_event);
+
+
+/**@brief Function for configuring the timer to use.
+ *
+ * @note Must be called when no DTM test is running.
+ *
+ * @param[in] new_timer Index (0..2) of timer to be used by the DTM library
+ *
+ * @return true: success, new timer was selected, false: parameter error
+ */
+bool dtm_set_timer(uint32_t new_timer);
+
+
+/**@brief Function for configuring the transmit power.
+ *
+ * @note Must be called when no DTM test is running.
+ *
+ * @param[in] new_tx_power New output level, +4..-40, in steps of 4.
+ *
+ * @return true: tx power setting changed, false: parameter error
+ */
+bool dtm_set_txpower(uint32_t new_tx_power);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // BLE_DTM_H__
+
+/** @} */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_dtm/ble_dtm_hw.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_dtm/ble_dtm_hw.h
new file mode 100644
index 0000000..944cf33
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_dtm/ble_dtm_hw.h
@@ -0,0 +1,103 @@
+/**
+ * Copyright (c) 2016 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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
+ *
+ * @defgroup ble_dtm_hw Direct Test Mode HW
+ * @{
+ * @ingroup ble_sdk_lib
+ * @brief Module contains hardware related function for testing RF/PHY using DTM commands.
+ */
+
+#ifndef BLE_DTM_HW_H__
+#define BLE_DTM_HW_H__
+
+#include <stdint.h>
+#include <stdbool.h>
+#include "nrf.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+/**@brief Function for selecting a timer resource.
+ * This function may be called directly, or through dtm_cmd() specifying
+ * DTM_PKT_VENDORSPECIFIC as payload, SELECT_TIMER as length, and the timer as freq
+ *
+ * @param[out] mp_timer Pointer to timer instance used in dtm source file.
+ * @param[out] m_timer_irq Pointer to timer interrupt related to mp_timer.
+ * @param[in] new_timer Timer id for the timer to use.
+ *
+ * @retval true if the timer was successfully changed.
+ * @retval false if the error occurs.
+ */
+
+bool dtm_hw_set_timer(NRF_TIMER_Type ** mp_timer, IRQn_Type * m_timer_irq, uint32_t new_timer);
+
+
+/**@brief Function for turning off radio test.
+ * This function is platform depending. For now only nRF51 requieres this special function.
+ */
+void dtm_turn_off_test(void);
+
+
+/**@brief Function for setting constant carrier in radio settings.
+ * This function is used to handle vendor specific command testing continous carrier without
+ * a modulated signal.
+ */
+void dtm_constant_carrier(void);
+
+
+/**@brief Function for validating tx power and radio move settings.
+ * @param[in] m_tx_power TX power for transmission test.
+ * @param[in] m_radio_mode Radio mode value.
+ *
+ * @retval DTM_SUCCESS if input parameters values are correct.
+ * @retval DTM_ERROR_ILLEGAL_CONFIGURATION if input parameters values are not correct.
+ */
+uint32_t dtm_radio_validate(int32_t m_tx_power, uint8_t m_radio_mode);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // BLE_DTM_HW_H__
+
+/** @} */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_dtm/ble_dtm_hw_nrf51.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_dtm/ble_dtm_hw_nrf51.c
new file mode 100644
index 0000000..1e6acca
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_dtm/ble_dtm_hw_nrf51.c
@@ -0,0 +1,120 @@
+/**
+ * Copyright (c) 2016 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#include "ble_dtm_hw.h"
+#include "ble_dtm.h"
+#include <stdbool.h>
+#include <string.h>
+#include "nrf.h"
+
+
+void dtm_turn_off_test()
+{
+ NRF_RADIO->TEST = 0;
+}
+
+
+void dtm_constant_carrier()
+{
+ NRF_RADIO->TEST = (RADIO_TEST_PLL_LOCK_Enabled << RADIO_TEST_PLL_LOCK_Pos) |
+ (RADIO_TEST_CONST_CARRIER_Enabled << RADIO_TEST_CONST_CARRIER_Pos);
+}
+
+
+uint32_t dtm_radio_validate(int32_t m_tx_power, uint8_t m_radio_mode)
+{
+ // Handle BLE Radio tuning parameters from production for DTM if required.
+ // Only needed for DTM without SoftDevice, as the SoftDevice normally handles this.
+ // PCN-083.
+ if ( ((NRF_FICR->OVERRIDEEN) & FICR_OVERRIDEEN_BLE_1MBIT_Msk) == FICR_OVERRIDEEN_BLE_1MBIT_Override)
+ {
+ NRF_RADIO->OVERRIDE0 = NRF_FICR->BLE_1MBIT[0];
+ NRF_RADIO->OVERRIDE1 = NRF_FICR->BLE_1MBIT[1];
+ NRF_RADIO->OVERRIDE2 = NRF_FICR->BLE_1MBIT[2];
+ NRF_RADIO->OVERRIDE3 = NRF_FICR->BLE_1MBIT[3];
+ NRF_RADIO->OVERRIDE4 = NRF_FICR->BLE_1MBIT[4];
+ }
+
+ // Initializing code below is quite generic - for BLE, the values are fixed, and expressions
+ // are constant. Non-constant values are essentially set in radio_prepare().
+ if (!(m_tx_power == RADIO_TXPOWER_TXPOWER_0dBm ||
+ m_tx_power == RADIO_TXPOWER_TXPOWER_Pos4dBm ||
+ m_tx_power == RADIO_TXPOWER_TXPOWER_Neg30dBm ||
+ m_tx_power == RADIO_TXPOWER_TXPOWER_Neg20dBm ||
+ m_tx_power == RADIO_TXPOWER_TXPOWER_Neg16dBm ||
+ m_tx_power == RADIO_TXPOWER_TXPOWER_Neg12dBm ||
+ m_tx_power == RADIO_TXPOWER_TXPOWER_Neg8dBm ||
+ m_tx_power == RADIO_TXPOWER_TXPOWER_Neg4dBm
+ ) ||
+ (m_radio_mode > RADIO_MODE_MODE_Ble_1Mbit) // Values 0 - 2: Proprietary mode, 3 (last valid): BLE
+ )
+ {
+ return DTM_ERROR_ILLEGAL_CONFIGURATION;
+ }
+
+ return DTM_SUCCESS;
+}
+
+
+bool dtm_hw_set_timer(NRF_TIMER_Type ** mp_timer, IRQn_Type * m_timer_irq, uint32_t new_timer)
+{
+ if (new_timer == 0)
+ {
+ *mp_timer = NRF_TIMER0;
+ *m_timer_irq = TIMER0_IRQn;
+ }
+ else if (new_timer == 1)
+ {
+ *mp_timer = NRF_TIMER1;
+ *m_timer_irq = TIMER1_IRQn;
+ }
+ else if (new_timer == 2)
+ {
+ *mp_timer = NRF_TIMER2;
+ *m_timer_irq = TIMER2_IRQn;
+ }
+ else
+ {
+ // Parameter error: Only TIMER 0, 1, 2 provided by nRF51
+ return false;
+ }
+ // New timer has been selected:
+ return true;
+}
+
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_dtm/ble_dtm_hw_nrf52.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_dtm/ble_dtm_hw_nrf52.c
new file mode 100644
index 0000000..4dcfa96
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_dtm/ble_dtm_hw_nrf52.c
@@ -0,0 +1,128 @@
+/**
+ * Copyright (c) 2016 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#include "ble_dtm_hw.h"
+#include "ble_dtm.h"
+#include <stdbool.h>
+#include <string.h>
+#include "nrf.h"
+
+
+void dtm_turn_off_test()
+{
+}
+
+
+void dtm_constant_carrier()
+{
+NRF_RADIO->MODECNF0 = (RADIO_MODECNF0_RU_Default << RADIO_MODECNF0_RU_Pos) |
+ (RADIO_MODECNF0_DTX_Center << RADIO_MODECNF0_DTX_Pos);
+}
+
+
+uint32_t dtm_radio_validate(int32_t m_tx_power, uint8_t m_radio_mode)
+{
+ // Initializing code below is quite generic - for BLE, the values are fixed, and expressions
+ // are constant. Non-constant values are essentially set in radio_prepare().
+ if (!(m_tx_power == RADIO_TXPOWER_TXPOWER_0dBm ||
+ m_tx_power == RADIO_TXPOWER_TXPOWER_Pos4dBm ||
+ m_tx_power == RADIO_TXPOWER_TXPOWER_Neg30dBm ||
+ m_tx_power == RADIO_TXPOWER_TXPOWER_Neg20dBm ||
+ m_tx_power == RADIO_TXPOWER_TXPOWER_Neg16dBm ||
+ m_tx_power == RADIO_TXPOWER_TXPOWER_Neg12dBm ||
+ m_tx_power == RADIO_TXPOWER_TXPOWER_Neg8dBm ||
+ m_tx_power == RADIO_TXPOWER_TXPOWER_Neg4dBm ||
+ m_tx_power == RADIO_TXPOWER_TXPOWER_Pos3dBm ||
+ m_tx_power == RADIO_TXPOWER_TXPOWER_Neg40dBm
+ ) ||
+
+ !(
+#ifdef NRF52840_XXAA
+ m_radio_mode == RADIO_MODE_MODE_Ble_LR125Kbit ||
+ m_radio_mode == RADIO_MODE_MODE_Ble_LR500Kbit ||
+#endif //NRF52840_XXAA
+ m_radio_mode == RADIO_MODE_MODE_Ble_1Mbit ||
+ m_radio_mode == RADIO_MODE_MODE_Ble_2Mbit
+ )
+ )
+ {
+ return DTM_ERROR_ILLEGAL_CONFIGURATION;
+ }
+
+ return DTM_SUCCESS;
+}
+
+
+bool dtm_hw_set_timer(NRF_TIMER_Type ** mp_timer, IRQn_Type * m_timer_irq, uint32_t new_timer)
+{
+ if (new_timer == 0)
+ {
+ *mp_timer = NRF_TIMER0;
+ *m_timer_irq = TIMER0_IRQn;
+ }
+ else if (new_timer == 1)
+ {
+ *mp_timer = NRF_TIMER1;
+ *m_timer_irq = TIMER1_IRQn;
+ }
+ else if (new_timer == 2)
+ {
+ *mp_timer = NRF_TIMER2;
+ *m_timer_irq = TIMER2_IRQn;
+ }
+#ifndef NRF52810_XXAA
+ else if (new_timer == 3)
+ {
+ *mp_timer = NRF_TIMER3;
+ *m_timer_irq = TIMER3_IRQn;
+ }
+ else if (new_timer == 4)
+ {
+ *mp_timer = NRF_TIMER4;
+ *m_timer_irq = TIMER4_IRQn;
+ }
+#endif //NRF52810_XXAA
+ else
+ {
+ // Parameter error: Only TIMER 0, 1, 2, 3 and 4 provided by nRF52
+ return false;
+ }
+ // New timer has been selected:
+ return true;
+}
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_lesc/ble_lesc.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_lesc/ble_lesc.c
new file mode 100644
index 0000000..a3d808d
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_lesc/ble_lesc.c
@@ -0,0 +1,443 @@
+/**
+ * Copyright (c) 2018 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#include "sdk_common.h"
+#if NRF_MODULE_ENABLED(BLE_LESC)
+
+#include "sdk_common.h"
+#include "ble_gap.h"
+#include "ble_lesc.h"
+#include "nrf_crypto.h"
+#include "nrf_crypto_mem.h"
+#include "peer_manager.h"
+#include "nrf_sdh_ble.h"
+#include "ble_conn_state.h"
+#define NRF_LOG_MODULE_NAME ble_lesc
+#include "nrf_log.h"
+NRF_LOG_MODULE_REGISTER();
+
+/**@brief Structure holding a ECDH public key, connection handle and valid state */
+typedef struct
+{
+ nrf_crypto_ecc_public_key_t public_key; /**< Public key used in either central or peripheral link. */
+ volatile uint16_t conn_handle; /**< Connection handle for connection that received the public key. */
+ volatile bool is_valid; /**< Flag indicating that the public key was valid. */
+} ble_lesc_public_key_t;
+
+/**@brief Context to generate an ECC private/public key pair
+ */
+static nrf_crypto_ecc_key_pair_generate_context_t m_ecc_keygen_context;
+
+
+/**@brief Context to do the LESC ECDH calculation.
+ */
+static nrf_crypto_ecdh_context_t m_ecdh_context;
+
+
+/**@brief Private key to use for LESC ECDH calculations
+ */
+static nrf_crypto_ecc_private_key_t m_local_private_key;
+
+
+/**@brief Public key to use for LESC ECDH calculation
+ */
+static ble_lesc_public_key_t m_local_public_key;
+
+
+/**@brief Structure holding peer central LESC ECC public key and valid state
+ */
+static ble_lesc_public_key_t m_peer_public_key_central =
+{
+ .conn_handle = BLE_CONN_HANDLE_INVALID,
+ .is_valid = false
+};
+
+
+/**@brief Structure holding peer peripheral LESC ECC public key and valid state
+ */
+static ble_lesc_public_key_t m_peer_public_key_peripheral =
+{
+ .conn_handle = BLE_CONN_HANDLE_INVALID,
+ .is_valid = false
+};
+
+/**@brief LESC ECC public key in a format usable by SoftDevice APIs.
+ *
+ * @note The BLE specification requires this key to be in little-endian format.
+ */
+static ble_gap_lesc_p256_pk_t m_lesc_public_key;
+
+
+/**@brief LESC ECDH key in a format usable by SoftDevice APIs.
+ *
+ * @note The BLE specification requires this key to be in little-endian format.
+ */
+static ble_gap_lesc_dhkey_t m_lesc_ecdh_key;
+
+
+static bool m_ble_lesc_invalid_state = false;
+static bool m_keypair_generated = false; /**< Flag indicating that the local ECDH key pair was generated. */
+
+
+static void ble_evt_handler(ble_evt_t const * p_ble_evt, void * p_context);
+NRF_SDH_BLE_OBSERVER(m_ble_evt_observer, BLE_LESC_OBSERVER_PRIO, ble_evt_handler, NULL);
+
+
+/**@brief Function to calculate LESC ECDH and set it using SoftDevice API
+ *
+ * @details This function calculates a LESC ECDH key (also know as a shared secret)
+ * sets it using a call to @ref sd_ble_gap_lesc_dhkey_reply.
+ *
+ * @note This function will only work if there is a generated local ECC key pair (private and
+ * public key pair) and a valid ECC public key received from the peer on either a peripheral
+ * or central link. If the ECC public key from the peer is invalid, a random shared secret
+ * is generated and set using the @ref sd_ble_gap_lesc_dhkey_reply call.
+ *
+ * @warning This function must be run in a low interrupt priority, like the main
+ * application context. Running this in a high priority interrupt level
+ * may disrupt time critical operations like radio communications.
+ *
+ * @retval
+ */
+static ret_code_t ble_lesc_dhkey_calculate_and_set(ble_lesc_public_key_t * const p_peer_public_key)
+{
+ ret_code_t err_code = NRF_ERROR_INVALID_STATE;
+ size_t shared_secret_size = BLE_GAP_LESC_DHKEY_LEN;
+
+ uint8_t * p_shared_secret = m_lesc_ecdh_key.key;
+
+ // Check if there is a valid generated and set local ECDH public key
+ if (!m_keypair_generated)
+ {
+ return NRF_ERROR_INVALID_STATE;
+ }
+
+ // Check if the public_key is valid
+ if (p_peer_public_key->is_valid)
+ {
+ err_code = nrf_crypto_ecdh_compute(&m_ecdh_context,
+ &m_local_private_key,
+ &p_peer_public_key->public_key,
+ p_shared_secret,
+ &shared_secret_size);
+ }
+
+ if(err_code == NRF_SUCCESS)
+ {
+ err_code = nrf_crypto_ecc_byte_order_invert(&g_nrf_crypto_ecc_secp256r1_curve_info,
+ p_shared_secret,
+ p_shared_secret,
+ BLE_GAP_LESC_DHKEY_LEN);
+ VERIFY_SUCCESS(err_code);
+ }
+ else
+ {
+ NRF_LOG_WARNING("Creating invalid shared secret to make LESC fail.");
+ err_code = nrf_crypto_rng_vector_generate(p_shared_secret, BLE_GAP_LESC_DHKEY_LEN);
+ VERIFY_SUCCESS(err_code);
+ }
+
+ NRF_LOG_DEBUG("Calling sd_ble_gap_lesc_dhkey_reply on conn_handle: %d", p_peer_public_key->conn_handle);
+ err_code = sd_ble_gap_lesc_dhkey_reply(p_peer_public_key->conn_handle, &m_lesc_ecdh_key);
+
+ return err_code;
+}
+
+
+/**@brief Function to set the peer ECC public key for a peripheral link
+ *
+ * @details This call should be made to
+ *
+ * @param[in] conn_handle The connection handle to the peripheral connection.
+ * @param[in] p_public_key Pointer to structure holding the public key received from the peer.
+ *
+ * @retval
+ */
+static ret_code_t ble_lesc_peer_peripheral_public_key_set(
+ uint16_t conn_handle,
+ ble_gap_lesc_p256_pk_t const * const p_public_key)
+{
+ ret_code_t err_code;
+
+ uint8_t public_raw[BLE_GAP_LESC_P256_PK_LEN];
+ size_t public_raw_len = BLE_GAP_LESC_P256_PK_LEN;
+
+ VERIFY_TRUE(conn_handle != BLE_CONN_HANDLE_INVALID, NRF_ERROR_INVALID_PARAM);
+ VERIFY_PARAM_NOT_NULL(p_public_key);
+
+ memcpy(public_raw, p_public_key->pk, BLE_GAP_LESC_P256_PK_LEN);
+
+ err_code = nrf_crypto_ecc_byte_order_invert(&g_nrf_crypto_ecc_secp256r1_curve_info,
+ public_raw,
+ public_raw,
+ NRF_CRYPTO_ECC_SECP256R1_RAW_PUBLIC_KEY_SIZE);
+ VERIFY_SUCCESS(err_code);
+
+
+ err_code = nrf_crypto_ecc_public_key_from_raw(&g_nrf_crypto_ecc_secp256r1_curve_info,
+ &m_peer_public_key_peripheral.public_key,
+ public_raw,
+ public_raw_len);
+
+ if (err_code == NRF_SUCCESS)
+ {
+ m_peer_public_key_peripheral.is_valid = true;
+ }
+ else
+ {
+ m_peer_public_key_peripheral.is_valid = false;
+ }
+
+ m_peer_public_key_peripheral.conn_handle = conn_handle;
+
+ return NRF_SUCCESS;
+}
+
+/**@brief Function to set peer ECC public key for a central link
+ *
+ * @details Setting the peer ECC public key will start a
+ *
+ * @param[in] conn_handle The connection handle to the peripheral connection.
+ * @param[in] p_public_key Pointer to structure holding the public key received from the peer.
+ *
+ * @retval
+ */
+static ret_code_t ble_lesc_peer_central_public_key_set(
+ uint16_t conn_handle,
+ ble_gap_lesc_p256_pk_t const * const p_public_key)
+{
+ ret_code_t err_code;
+
+ uint8_t public_raw[BLE_GAP_LESC_P256_PK_LEN];
+ size_t public_raw_len = BLE_GAP_LESC_P256_PK_LEN;
+
+ VERIFY_TRUE(conn_handle != BLE_CONN_HANDLE_INVALID, NRF_ERROR_INVALID_PARAM);
+ VERIFY_PARAM_NOT_NULL(p_public_key);
+
+ memcpy(public_raw, p_public_key->pk, BLE_GAP_LESC_P256_PK_LEN);
+
+ err_code = nrf_crypto_ecc_byte_order_invert(&g_nrf_crypto_ecc_secp256r1_curve_info,
+ public_raw,
+ public_raw,
+ NRF_CRYPTO_ECC_SECP256R1_RAW_PUBLIC_KEY_SIZE);
+ VERIFY_SUCCESS(err_code);
+
+ err_code = nrf_crypto_ecc_public_key_from_raw(&g_nrf_crypto_ecc_secp256r1_curve_info,
+ &m_peer_public_key_central.public_key,
+ public_raw,
+ public_raw_len);
+
+ if (err_code == NRF_SUCCESS)
+ {
+ m_peer_public_key_central.is_valid = true;
+ }
+ else
+ {
+ m_peer_public_key_central.is_valid = false;
+ }
+
+ m_peer_public_key_central.conn_handle = conn_handle;
+
+ return NRF_SUCCESS;
+}
+
+
+/**@brief BLE event handler for LESC DHKEY requests
+ */
+static void ble_evt_handler(ble_evt_t const * p_ble_evt, void * p_context)
+{
+ ret_code_t err_code = NRF_SUCCESS;
+ uint16_t conn_handle = p_ble_evt->evt.gap_evt.conn_handle;
+ uint16_t role = ble_conn_state_role(conn_handle);
+
+ switch (p_ble_evt->header.evt_id)
+ {
+ case BLE_GAP_EVT_LESC_DHKEY_REQUEST:
+ {
+ NRF_LOG_DEBUG("Handling BLE_GAP_EVT_LESC_DHKEY_REQUEST");
+
+ ble_gap_lesc_p256_pk_t const * p_pk_peer =
+ p_ble_evt->evt.gap_evt.params.lesc_dhkey_request.p_pk_peer;
+
+ if (role == BLE_GAP_ROLE_CENTRAL)
+ {
+ err_code = ble_lesc_peer_central_public_key_set(conn_handle,
+ p_pk_peer);
+ }
+ else if (role == BLE_GAP_ROLE_PERIPH)
+ {
+ err_code = ble_lesc_peer_peripheral_public_key_set(conn_handle,
+ p_pk_peer);
+ }
+
+ if (err_code != NRF_SUCCESS)
+ {
+ // Set the state to invalid
+ m_ble_lesc_invalid_state = true;
+ }
+
+ break;
+ }
+
+ default:
+ break;
+ }
+}
+
+
+ret_code_t ble_lesc_init(void)
+{
+ ret_code_t err_code;
+
+#if NRF_CRYPTO_ALLOCATOR == NRF_CRYPTO_ALLOCATOR_NRF_MALLOC
+
+ // Initialize mem_manager if used by nrf_crypto
+ err_code = nrf_mem_init();
+ VERIFY_SUCCESS(err_code);
+
+#endif
+
+ // Ensure that nrf_crypto has been initialized
+ err_code = nrf_crypto_init();
+ VERIFY_SUCCESS(err_code);
+
+#if defined(NRF_CRYPTO_RNG_AUTO_INIT_ENABLED) && (NRF_CRYPTO_RNG_AUTO_INIT_ENABLED == 1)
+
+ // Do nothing. RNG is initialized with nrf_crypto_init call.
+
+#elif defined((NRF_CRYPTO_RNG_AUTO_INIT_ENABLED) && (NRF_CRYPTO_RNG_AUTO_INIT_ENABLED == 0)
+
+ // Initialize the RNG
+ err_code = nrf_crypto_rng_init(NULL, NULL);
+ VERIFY_SUCCESS(err_code);
+
+#else
+
+ #error Invalid sdk_config.h (does not contain NRF_CRYPTO_RNG_AUTO_INIT_ENABLED)
+
+#endif // defined(NRF_CRYPTO_RNG_AUTO_INIT_ENABLED) && (NRF_CRYPTO_RNG_AUTO_INIT_ENABLED == 1)
+
+ return err_code;
+}
+
+
+ret_code_t ble_lesc_ecc_keypair_generate_and_set(void)
+{
+ ret_code_t err_code;
+
+ size_t public_len = BLE_GAP_LESC_P256_PK_LEN;
+
+ // Update flag to indicate that there is no valid private key
+ m_keypair_generated = false;
+
+ err_code = nrf_crypto_ecc_key_pair_generate(&m_ecc_keygen_context,
+ &g_nrf_crypto_ecc_secp256r1_curve_info,
+ &m_local_private_key,
+ &m_local_public_key.public_key);
+ VERIFY_SUCCESS(err_code);
+
+ // Converting public key to raw format.
+ err_code = nrf_crypto_ecc_public_key_to_raw(&m_local_public_key.public_key,
+ (uint8_t *)m_lesc_public_key.pk,
+ &public_len);
+ VERIFY_SUCCESS(err_code);
+
+ // Convert the raw public key to little-endian (required for BLE)
+ err_code = nrf_crypto_ecc_byte_order_invert(&g_nrf_crypto_ecc_secp256r1_curve_info,
+ m_lesc_public_key.pk,
+ m_lesc_public_key.pk,
+ NRF_CRYPTO_ECC_SECP256R1_RAW_PUBLIC_KEY_SIZE);
+ VERIFY_SUCCESS(err_code);
+
+ // Set the local public key used for all LESC pairing procedures.
+ err_code = pm_lesc_public_key_set(&m_lesc_public_key);
+
+ if(err_code == NRF_SUCCESS)
+ {
+ // Set the flag to indicate that there is a valid ECDH key pair generated
+ m_keypair_generated = true;
+ }
+
+ return err_code;
+}
+
+
+ret_code_t ble_lesc_ecc_local_public_key_get(ble_gap_lesc_p256_pk_t const ** pp_lesc_public_key)
+{
+ VERIFY_PARAM_NOT_NULL(pp_lesc_public_key);
+ VERIFY_TRUE(m_keypair_generated, NRF_ERROR_INVALID_STATE);
+
+ (*pp_lesc_public_key) = &m_lesc_public_key;
+ return NRF_SUCCESS;
+}
+
+
+ret_code_t ble_lesc_service_request_handler(void)
+{
+ ret_code_t err_code = NRF_SUCCESS;
+
+ // If the LESC module is in an invalid state restart is required
+ if (m_ble_lesc_invalid_state)
+ {
+ return NRF_ERROR_INVALID_STATE;
+ }
+
+ if (m_peer_public_key_central.conn_handle != BLE_CONN_HANDLE_INVALID)
+ {
+ // The central link has received a DHKEY_REQUEST.
+ err_code = ble_lesc_dhkey_calculate_and_set(&m_peer_public_key_central);
+
+ m_peer_public_key_central.conn_handle = BLE_CONN_HANDLE_INVALID;
+ }
+ else if (m_peer_public_key_peripheral.conn_handle != BLE_CONN_HANDLE_INVALID)
+ {
+ // The peripheral link has received a DHKEY_REQUEST.
+ err_code = ble_lesc_dhkey_calculate_and_set(&m_peer_public_key_peripheral);
+
+ m_peer_public_key_peripheral.conn_handle = BLE_CONN_HANDLE_INVALID;
+ }
+ else
+ {
+ // Do nothing
+ }
+
+ return err_code;
+}
+
+#endif // NRF_MODULE_ENABLED(BLE_LESC)
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_lesc/ble_lesc.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_lesc/ble_lesc.h
new file mode 100644
index 0000000..b3ef35d
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_lesc/ble_lesc.h
@@ -0,0 +1,128 @@
+/**
+ * Copyright (c) 2018 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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
+ *
+ * @defgroup ble_lesc BLE LESC module
+ * @{
+ * @ingroup ble_sdk_lib
+ *
+ * @brief Module for handling LESC DHKey requests.
+ */
+#ifndef BLE_LESC_H__
+#define BLE_LESC_H__
+
+#include "sdk_common.h"
+#include "ble_gap.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**@brief Function to initialize the ble_lesc module.
+ *
+ * @details This function initializes the nrf_crypto for key
+ * generation and ECDH calculations.
+ *
+ * @retval NRF_SUCCESS Initalization was successful.
+ * @return Any error code reported by @ref nrf_crypto_init.
+ * @return Any error code reported by @ref nrf_crypto_rng_init.
+ */
+ret_code_t ble_lesc_init(void);
+
+
+/**@brief Function to generate a ECC key pair to use in LESC
+ *
+ * @details This function initializes the crypto system by calling nrf_crypto_init
+ * and nrf_crypto_rng_init before calling the required functions to generate
+ * the ECC key pair. If the key generation was successful this function sets
+ * the LESC local public key in peer manager by calling
+ * @ref pm_lesc_public_key_set.
+ *
+ * @note Run @ref ble_lesc_init before calling this API.
+ *
+ * @retval NRF_SUCCESS Generating ECC key pair was successful.
+ * @return Any error code form @ref nrf_crypto_ecc_key_pair_generate.
+ * @return Any error code from @ref nrf_crypto_ecc_public_key_to_raw.
+ * @return Any error code from @ref nrf_crypto_ecc_byte_order_invert.
+ * @return Any error code reported by @ref pm_lesc_public_key_set.
+ */
+ret_code_t ble_lesc_ecc_keypair_generate_and_set(void);
+
+
+/**@brief Function to get the current LESC ECC local public key
+ *
+ * @details This function gets the current ECC local public key used LESC pairing procedure
+ * the format of this key is in a type usable by peer manager, NFC (OOB) and SoftDevice.
+ *
+ * @note Run @ref ble_lesc_ecc_keypair_generate_and_set before calling this function.
+ *
+ * @retval NRF_SUCCESS Getting the local public key was successful.
+ * @retval NRF_ERROR_NULL pp_lesc_public_key was NULL.
+ * @retval NRF_ERROR_INVALID_STATE No ECC keypair was generated prior to this call
+ */
+ret_code_t ble_lesc_ecc_local_public_key_get(ble_gap_lesc_p256_pk_t const ** pp_lesc_public_key);
+
+
+/**@brief Function to service LESC ECDH calculations
+ *
+ * @details This function will calculate a LESC ECDH key (also known as shared secret) as long as
+ * @ref BLE_GAP_EVT_LESC_DHKEY_REQUEST event has been received from SoftDevice.
+ *
+ * @note This function should be run in a low interrupt priority like an idle-loop in the main
+ * application context.
+ *
+ * @warning Any error code reported by this function that is not @ref NRF_SUCCESS is critical and should be
+ * handled by aborting all ongoing BLE operations and resetting the device.
+ * Failure to do is a security risk.
+ *
+ * @retval NRF_SUCCESS Service operation was successful.
+ * @return Any other error code than NRF_SUCCESS which indicates that the device is in a critical state
+ * and must be restarted.
+ */
+ret_code_t ble_lesc_service_request_handler(void);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // BLE_LESC_H__
+
+/** @} */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_link_ctx_manager/ble_link_ctx_manager.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_link_ctx_manager/ble_link_ctx_manager.c
new file mode 100644
index 0000000..ea60e6d
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_link_ctx_manager/ble_link_ctx_manager.c
@@ -0,0 +1,79 @@
+/**
+ * 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#include "ble_link_ctx_manager.h"
+#include "sdk_common.h"
+
+
+ret_code_t blcm_link_ctx_get(blcm_link_ctx_storage_t const * const p_link_ctx_storage,
+ uint16_t const conn_handle,
+ void ** const pp_ctx_data)
+{
+ uint8_t conn_id;
+
+ if (pp_ctx_data == NULL)
+ {
+ return NRF_ERROR_NULL;
+ }
+ else
+ {
+ *pp_ctx_data = NULL;
+ }
+
+ VERIFY_PARAM_NOT_NULL(p_link_ctx_storage);
+ VERIFY_PARAM_NOT_NULL(p_link_ctx_storage->p_ctx_data_pool);
+ VERIFY_TRUE((p_link_ctx_storage->link_ctx_size % BYTES_PER_WORD) == 0, NRF_ERROR_INVALID_PARAM);
+
+ conn_id = ble_conn_state_conn_idx(conn_handle);
+
+ if (conn_id == BLE_CONN_STATE_MAX_CONNECTIONS)
+ {
+ return NRF_ERROR_NOT_FOUND;
+ }
+
+ if (conn_id >= p_link_ctx_storage->max_links_cnt)
+ {
+ return NRF_ERROR_NO_MEM;
+ }
+
+ *pp_ctx_data = (void *) ((uint8_t *) p_link_ctx_storage->p_ctx_data_pool +
+ conn_id * p_link_ctx_storage->link_ctx_size);
+ return NRF_SUCCESS;
+}
+
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_link_ctx_manager/ble_link_ctx_manager.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_link_ctx_manager/ble_link_ctx_manager.h
new file mode 100644
index 0000000..2ac3693
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_link_ctx_manager/ble_link_ctx_manager.h
@@ -0,0 +1,127 @@
+/**
+ * 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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
+ *
+ * @defgroup ble_link_ctx_manager BLE Link Context Manager
+ * @{
+ * @ingroup ble_sdk_lib
+ * @brief Storage for link-related data.
+ *
+ * @details BLE Link Context Manager can be used as a simple storage for link-related data.
+ * Each link context data is uniquely identified within the storage by its connection
+ * handle and can be retrieved from it by using this handle.
+ *
+ */
+#ifndef BLE_LINK_CTX_MANAGER_H__
+#define BLE_LINK_CTX_MANAGER_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <stdint.h>
+#include "ble_conn_state.h"
+#include "sdk_errors.h"
+
+
+/**@brief Macro for defining a blcm_link_ctx_storage instance.
+ *
+ * @param[in] _name Name of the instance.
+ * @param[in] _max_clients Maximum number of clients connected at a time.
+ * @param[in] _link_ctx_size Context size in bytes for a single link.
+ */
+#define BLE_LINK_CTX_MANAGER_DEF(_name, _max_clients, _link_ctx_size) \
+ STATIC_ASSERT((_max_clients) < BLE_CONN_STATE_MAX_CONNECTIONS); \
+ static uint32_t CONCAT_2(_name, _ctx_data_pool)[(_max_clients)*BYTES_TO_WORDS(_link_ctx_size)]; \
+ static blcm_link_ctx_storage_t _name = \
+ { \
+ .p_ctx_data_pool = CONCAT_2(_name, _ctx_data_pool), \
+ .max_links_cnt = (_max_clients), \
+ .link_ctx_size = sizeof(CONCAT_2(_name, _ctx_data_pool))/(_max_clients) \
+ }
+
+
+/**
+ * @brief Type of description that is used for registry of all current connections.
+ */
+typedef struct
+{
+ void * const p_ctx_data_pool; /**< Pointer to links context memory pool. */
+ uint8_t const max_links_cnt; /**< Maximum number of concurrent links. */
+ uint16_t const link_ctx_size; /**< Context size in bytes for a single link (word-aligned). */
+} blcm_link_ctx_storage_t;
+
+
+/**
+ * @brief Function for getting the link context from the link registry.
+ *
+ * This function finds the link context in the registry. The link to find is identified by the
+ * connection handle within the registry.
+ *
+ * The context is preserved for the lifetime of the connection. When a new connection occurs, the
+ * value of its context is undefined, and should be initialized.
+ *
+ * @param[in] p_link_ctx_storage Pointer to the link storage descriptor.
+ * @param[in] conn_handle Connection whose context to find.
+ * @param[out] pp_ctx_data Pointer to data with context for the connection.
+ *
+ * @retval NRF_ERROR_NULL If \p p_link_ctx_storage is NULL or contains a NULL pointer, or if
+ * \p pp_ctx_data is NULL.
+ * @retval NRF_ERROR_INVALID_PARAM If \p p_link_ctx_storage::link_ctx_size is not multiple of word
+ * size.
+ * @retval NRF_ERROR_NOT_FOUND If \p conn_handle does not refer to an active or recently
+ * disconnected link.
+ * @retval NRF_ERROR_NO_MEM If there is not enough memory to store context for the given
+ * connection handle. This can happen if the number of links is
+ * greater than \p p_link_ctx_storage::max_links_cnt.
+ * @retval NRF_SUCCESS If the operation was successful.
+ */
+ret_code_t blcm_link_ctx_get(blcm_link_ctx_storage_t const * const p_link_ctx_storage,
+ uint16_t const conn_handle,
+ void ** const pp_ctx_data);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // BLE_LINK_CTX_MANAGER_H__
+
+/** @} */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_racp/ble_racp.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_racp/ble_racp.c
new file mode 100644
index 0000000..88b50b0
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_racp/ble_racp.c
@@ -0,0 +1,87 @@
+/**
+ * Copyright (c) 2012 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#include "sdk_common.h"
+#if NRF_MODULE_ENABLED(BLE_RACP)
+#include "ble_racp.h"
+#include <stdlib.h>
+
+
+void ble_racp_decode(uint8_t data_len, uint8_t const * p_data, ble_racp_value_t * p_racp_val)
+{
+ p_racp_val->opcode = 0xFF;
+ p_racp_val->operator = 0xFF;
+ p_racp_val->operand_len = 0;
+ p_racp_val->p_operand = NULL;
+
+ if (data_len > 0)
+ {
+ p_racp_val->opcode = p_data[0];
+ }
+ if (data_len > 1)
+ {
+ p_racp_val->operator = p_data[1]; //lint !e415
+ }
+ if (data_len > 2)
+ {
+ p_racp_val->operand_len = data_len - 2;
+ p_racp_val->p_operand = (uint8_t*)&p_data[2]; //lint !e416
+ }
+}
+
+
+uint8_t ble_racp_encode(const ble_racp_value_t * p_racp_val, uint8_t * p_data)
+{
+ uint8_t len = 0;
+ int i;
+
+ if (p_data != NULL)
+ {
+ p_data[len++] = p_racp_val->opcode;
+ p_data[len++] = p_racp_val->operator;
+
+ for (i = 0; i < p_racp_val->operand_len; i++)
+ {
+ p_data[len++] = p_racp_val->p_operand[i];
+ }
+ }
+
+ return len;
+}
+#endif // NRF_MODULE_ENABLED(BLE_RACP)
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_racp/ble_racp.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_racp/ble_racp.h
new file mode 100644
index 0000000..1280ad1
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_racp/ble_racp.h
@@ -0,0 +1,136 @@
+/**
+ * Copyright (c) 2012 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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
+ *
+ * @defgroup ble_racp Record Access Control Point
+ * @{
+ * @ingroup ble_sdk_lib
+ * @brief Record Access Control Point library.
+ */
+
+#ifndef BLE_RACP_H__
+#define BLE_RACP_H__
+
+#include <stdint.h>
+#include <stdbool.h>
+#include "ble.h"
+#include "ble_types.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**@brief Record Access Control Point opcodes. */
+#define RACP_OPCODE_RESERVED 0 /**< Record Access Control Point opcode - Reserved for future use. */
+#define RACP_OPCODE_REPORT_RECS 1 /**< Record Access Control Point opcode - Report stored records. */
+#define RACP_OPCODE_DELETE_RECS 2 /**< Record Access Control Point opcode - Delete stored records. */
+#define RACP_OPCODE_ABORT_OPERATION 3 /**< Record Access Control Point opcode - Abort operation. */
+#define RACP_OPCODE_REPORT_NUM_RECS 4 /**< Record Access Control Point opcode - Report number of stored records. */
+#define RACP_OPCODE_NUM_RECS_RESPONSE 5 /**< Record Access Control Point opcode - Number of stored records response. */
+#define RACP_OPCODE_RESPONSE_CODE 6 /**< Record Access Control Point opcode - Response code. */
+
+/**@brief Record Access Control Point operators. */
+#define RACP_OPERATOR_NULL 0 /**< Record Access Control Point operator - Null. */
+#define RACP_OPERATOR_ALL 1 /**< Record Access Control Point operator - All records. */
+#define RACP_OPERATOR_LESS_OR_EQUAL 2 /**< Record Access Control Point operator - Less than or equal to. */
+#define RACP_OPERATOR_GREATER_OR_EQUAL 3 /**< Record Access Control Point operator - Greater than or equal to. */
+#define RACP_OPERATOR_RANGE 4 /**< Record Access Control Point operator - Within range of (inclusive). */
+#define RACP_OPERATOR_FIRST 5 /**< Record Access Control Point operator - First record (i.e. oldest record). */
+#define RACP_OPERATOR_LAST 6 /**< Record Access Control Point operator - Last record (i.e. most recent record). */
+#define RACP_OPERATOR_RFU_START 7 /**< Record Access Control Point operator - Start of Reserved for Future Use area. */
+
+/**@brief Record Access Control Point Operand Filter Type Value. */
+#define RACP_OPERAND_FILTER_TYPE_TIME_OFFSET 1 /**< Record Access Control Point Operand Filter Type Value - Time Offset. */
+#define RACP_OPERAND_FILTER_TYPE_FACING_TIME 2 /**< Record Access Control Point Operand Filter Type Value - User Facing Time. */
+
+/**@brief Record Access Control Point response codes. */
+#define RACP_RESPONSE_RESERVED 0 /**< Record Access Control Point response code - Reserved for future use. */
+#define RACP_RESPONSE_SUCCESS 1 /**< Record Access Control Point response code - Successful operation. */
+#define RACP_RESPONSE_OPCODE_UNSUPPORTED 2 /**< Record Access Control Point response code - Unsupported op code received. */
+#define RACP_RESPONSE_INVALID_OPERATOR 3 /**< Record Access Control Point response code - Operator not valid for service. */
+#define RACP_RESPONSE_OPERATOR_UNSUPPORTED 4 /**< Record Access Control Point response code - Unsupported operator. */
+#define RACP_RESPONSE_INVALID_OPERAND 5 /**< Record Access Control Point response code - Operand not valid for service. */
+#define RACP_RESPONSE_NO_RECORDS_FOUND 6 /**< Record Access Control Point response code - No matching records found. */
+#define RACP_RESPONSE_ABORT_FAILED 7 /**< Record Access Control Point response code - Abort could not be completed. */
+#define RACP_RESPONSE_PROCEDURE_NOT_DONE 8 /**< Record Access Control Point response code - Procedure could not be completed. */
+#define RACP_RESPONSE_OPERAND_UNSUPPORTED 9 /**< Record Access Control Point response code - Unsupported operand. */
+
+/**@brief Record Access Control Point value structure. */
+typedef struct
+{
+ uint8_t opcode; /**< Op Code. */
+ uint8_t operator; /**< Operator. */
+ uint8_t operand_len; /**< Length of the operand. */
+ uint8_t * p_operand; /**< Pointer to the operand. */
+} ble_racp_value_t;
+
+/**@brief Function for decoding a Record Access Control Point write.
+ *
+ * @details This call decodes a write to the Record Access Control Point.
+ *
+ * @param[in] data_len Length of data in received write.
+ * @param[in] p_data Pointer to received data.
+ * @param[out] p_racp_val Pointer to decoded Record Access Control Point write.
+ * @note This does not do a data copy. It assumes the data pointed to by
+ * p_data is persistant until no longer needed.
+ */
+void ble_racp_decode(uint8_t data_len, uint8_t const * p_data, ble_racp_value_t * p_racp_val);
+
+/**@brief Function for encoding a Record Access Control Point response.
+ *
+ * @details This call encodes a response from the Record Access Control Point response.
+ *
+ * @param[in] p_racp_val Pointer to Record Access Control Point to encode.
+ * @param[out] p_data Pointer to where encoded data is written.
+ * NOTE! It is calling routines respsonsibility to make sure.
+ *
+ * @return Length of encoded data.
+ */
+uint8_t ble_racp_encode(const ble_racp_value_t * p_racp_val, uint8_t * p_data);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // BLE_RACP_H__
+
+/** @} */
+
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_radio_notification/ble_radio_notification.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_radio_notification/ble_radio_notification.c
new file mode 100644
index 0000000..44b2bf9
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_radio_notification/ble_radio_notification.c
@@ -0,0 +1,87 @@
+/**
+ * Copyright (c) 2012 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#include "ble_radio_notification.h"
+#include <stdlib.h>
+
+
+static bool m_radio_active = false; /**< Current radio state. */
+static ble_radio_notification_evt_handler_t m_evt_handler = NULL; /**< Application event handler for handling Radio Notification events. */
+
+
+void SWI1_IRQHandler(void)
+{
+ m_radio_active = !m_radio_active;
+ if (m_evt_handler != NULL)
+ {
+ m_evt_handler(m_radio_active);
+ }
+}
+
+
+uint32_t ble_radio_notification_init(uint32_t irq_priority,
+ uint8_t distance,
+ ble_radio_notification_evt_handler_t evt_handler)
+{
+ uint32_t err_code;
+
+ m_evt_handler = evt_handler;
+
+ // Initialize Radio Notification software interrupt
+ err_code = sd_nvic_ClearPendingIRQ(SWI1_IRQn);
+ if (err_code != NRF_SUCCESS)
+ {
+ return err_code;
+ }
+
+ err_code = sd_nvic_SetPriority(SWI1_IRQn, irq_priority);
+ if (err_code != NRF_SUCCESS)
+ {
+ return err_code;
+ }
+
+ err_code = sd_nvic_EnableIRQ(SWI1_IRQn);
+ if (err_code != NRF_SUCCESS)
+ {
+ return err_code;
+ }
+
+ // Configure the event
+ return sd_radio_notification_cfg_set(NRF_RADIO_NOTIFICATION_TYPE_INT_ON_BOTH, distance);
+}
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_radio_notification/ble_radio_notification.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_radio_notification/ble_radio_notification.h
new file mode 100644
index 0000000..0f89b2f
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_radio_notification/ble_radio_notification.h
@@ -0,0 +1,82 @@
+/**
+ * Copyright (c) 2012 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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
+ *
+ * @defgroup ble_radio_notification Radio Notification Event Handler
+ * @{
+ * @ingroup ble_sdk_lib
+ * @brief Module for propagating Radio Notification events to the application.
+ */
+
+#ifndef BLE_RADIO_NOTIFICATION_H__
+#define BLE_RADIO_NOTIFICATION_H__
+
+#include <stdint.h>
+#include <stdbool.h>
+#include "nrf_soc.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**@brief Application radio notification event handler type. */
+typedef void (*ble_radio_notification_evt_handler_t) (bool radio_active);
+
+/**@brief Function for initializing the Radio Notification module.
+ *
+ * @param[in] irq_priority Interrupt priority for the Radio Notification interrupt handler.
+ * @param[in] distance The time from an Active event until the radio is activated.
+ * @param[in] evt_handler Handler to be executed when a radio notification event has been
+ * received.
+ *
+ * @return NRF_SUCCESS on successful initialization, otherwise an error code.
+ */
+uint32_t ble_radio_notification_init(uint32_t irq_priority,
+ uint8_t distance,
+ ble_radio_notification_evt_handler_t evt_handler);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // BLE_RADIO_NOTIFICATION_H__
+
+/** @} */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/ble_ancs_c/ancs_app_attr_get.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/ble_ancs_c/ancs_app_attr_get.c
new file mode 100644
index 0000000..38ed510
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/ble_ancs_c/ancs_app_attr_get.c
@@ -0,0 +1,367 @@
+/**
+ * Copyright (c) 2016 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+/* Disclaimer: This client implementation of the Apple Notification Center Service can and will be changed at any time by Nordic Semiconductor ASA.
+ * Server implementations such as the ones found in iOS can be changed at any time by Apple and may cause this client implementation to stop working.
+ */
+
+#include "ancs_app_attr_get.h"
+#include "nrf_ble_ancs_c.h"
+#include "ancs_tx_buffer.h"
+#include "sdk_macros.h"
+#include "nrf_log.h"
+#include "string.h"
+
+#define GATTC_OPCODE_SIZE 1 /**< Size of the GATTC OPCODE. */
+#define GATTC_ATTR_HANDLE_SIZE 4 /**< Size of the Attribute handle Size. */
+
+
+#define ANCS_GATTC_WRITE_PAYLOAD_LEN_MAX (BLE_GATT_ATT_MTU_DEFAULT - GATTC_OPCODE_SIZE - GATTC_ATTR_HANDLE_SIZE) /**< Maximum Length of the data we can send in one write. */
+
+
+/**@brief Enum to keep track of the state based encoding while requesting App attributes. */
+typedef enum
+{
+ APP_ATTR_COMMAND_ID, /**< Currently encoding the Command ID. */
+ APP_ATTR_APP_ID, /**< Currently encoding the App ID. */
+ APP_ATTR_ATTR_ID, /**< Currently encoding the Attribute ID. */
+ APP_ATTR_DONE /**< Encoding done. */
+}encode_app_attr_t;
+
+
+/**@brief Function for determening if an attribute is desired to get.
+ *
+ * @param[in] p_ancs iOS notification structure. This structure must be supplied by
+ * the application. It identifies the particular client instance to use.
+ *
+ * @return True If it is requested
+ * @return False If it is not be requested.
+*/
+static bool app_attr_is_requested(ble_ancs_c_t * p_ancs, uint32_t attr_id)
+{
+ if (p_ancs->ancs_app_attr_list[attr_id].get == true)
+ {
+ return true;
+ }
+ return false;
+}
+
+/**@brief Function for counting the number of attributes that will be requested upon a Get App Attribute.
+ *
+ * @param[in] p_ancs iOS notification structure. This structure must be supplied by
+ * the application. It identifies the particular client instance to use.
+ *
+ * @return Number of attributes that will be requested upon a Get App Attribute.
+*/
+static uint32_t app_attr_nb_to_get(ble_ancs_c_t * p_ancs)
+{
+ uint32_t attr_nb_to_get = 0;
+ for (uint32_t i = 0; i < (sizeof(p_ancs->ancs_app_attr_list)/sizeof(ble_ancs_c_attr_list_t)); i++)
+ {
+ if (app_attr_is_requested(p_ancs,i))
+ {
+ attr_nb_to_get++;
+ }
+ }
+ return attr_nb_to_get;
+}
+
+
+/**@brief Function for encoding the Command ID as part of assembling a "Get App Attributes" command.
+ *
+ * @param[in] conn_handle Connection handle for where the prepared write will be executed.
+ * @param[in] handle_value The handle that will receive the execute command.
+ * @param[in] p_offset Pointer to the offset for the write.
+ * @param[in] p_index Pointer to the length encoded so far for the current write.
+ * @param[in,out] p_msg Pointer to the tx message that has been filled out and will be added to
+ * tx queue in this function.
+ */
+static void queued_write_tx_message(uint16_t conn_handle,
+ uint16_t handle_value,
+ uint16_t * p_offset,
+ uint32_t * p_index,
+ tx_message_t * p_msg)
+{
+ NRF_LOG_DEBUG("Starting new TX message.");
+
+ p_msg->conn_handle = conn_handle;
+ p_msg->type = WRITE_REQ;
+ p_msg->req.write_req.gattc_params.len = *p_index;
+ p_msg->req.write_req.gattc_params.handle = handle_value;
+ p_msg->req.write_req.gattc_params.p_value = p_msg->req.write_req.gattc_value;
+
+ p_msg->req.write_req.gattc_params.offset = *p_offset;
+
+ p_msg->req.write_req.gattc_params.write_op = BLE_GATT_OP_PREP_WRITE_REQ;
+
+ tx_buffer_insert(p_msg);
+}
+
+
+/**@brief Function for encoding the Command ID as part of assembling a "Get App Attributes" command.
+ *
+ * @param[in] p_ancs iOS notification structure. This structure must be supplied by
+ * the application. It identifies the particular client instance to use.
+ * @param[in] p_index Pointer to the length encoded so far for the current write.
+ * @param[in] p_offset Pointer to the accumulated offset for the next write.
+ * @param[in,out] p_msg Pointer to the tx message that will be filled out in this function.
+ */
+static encode_app_attr_t app_attr_encode_cmd_id(ble_ancs_c_t * p_ancs,
+ uint32_t * index,
+ tx_message_t * p_msg)
+{
+ NRF_LOG_DEBUG("Encoding Command ID");
+
+ // Encode Command ID.
+ p_msg->req.write_req.gattc_value[(*index)++] = BLE_ANCS_COMMAND_ID_GET_APP_ATTRIBUTES;
+ return APP_ATTR_APP_ID;
+}
+
+/**@brief Function for encoding the App Identifier as part of assembling a "Get App Attributes" command.
+ *
+ * @param[in] p_ancs iOS notification structure. This structure must be supplied by
+ * the application. It identifies the particular client instance to use.
+ * @param[in] p_app_id The App ID for the App which we will request App Attributes for.
+ * @param[in] app_id_len Length of the App ID.
+ * @param[in] p_index Pointer to the length encoded so far for the current write.
+ * @param[in] p_offset Pointer to the accumulated offset for the next write.
+ * @param[in] p_app_id_bytes_encoded_count Variable to keep count of the encoded APP ID bytes.
+ * As long as it is lower than the length of the App ID,
+ * parsing will continue.
+ */
+static encode_app_attr_t app_attr_encode_app_id(ble_ancs_c_t * p_ancs,
+ uint32_t * p_index,
+ uint16_t * p_offset,
+ tx_message_t * p_msg,
+ const uint8_t * p_app_id,
+ const uint32_t app_id_len,
+ uint32_t * p_app_id_bytes_encoded_count)
+{
+ NRF_LOG_DEBUG("Encoding APP ID");
+ if (*p_index >= ANCS_GATTC_WRITE_PAYLOAD_LEN_MAX)
+ {
+ queued_write_tx_message(p_ancs->conn_handle, p_ancs->service.control_point_char.handle_value, p_offset, p_index, p_msg);
+ *(p_offset) += *p_index;
+ *p_index = 0;
+ }
+
+ //Encode App Identifier.
+ if (*p_app_id_bytes_encoded_count == app_id_len)
+ {
+ p_msg->req.write_req.gattc_value[(*p_index)++] = '\0';
+ (*p_app_id_bytes_encoded_count)++;
+ }
+ NRF_LOG_DEBUG("%c", p_app_id[(*p_app_id_bytes_encoded_count)]);
+ if (*p_app_id_bytes_encoded_count < app_id_len)
+ {
+ p_msg->req.write_req.gattc_value[(*p_index)++] = p_app_id[(*p_app_id_bytes_encoded_count)++];
+ }
+ if (*p_app_id_bytes_encoded_count > app_id_len)
+ {
+ return APP_ATTR_ATTR_ID;
+ }
+ return APP_ATTR_APP_ID;
+}
+
+/**@brief Function for encoding the Attribute ID as part of assembling a "Get App Attributes" command.
+ *
+ * @param[in] p_ancs iOS notification structure. This structure must be supplied by
+ *
+ * @param[in] p_index Pointer to the length encoded so far for the current write.
+ * @param[in] p_offset Pointer to the accumulated offset for the next write.
+ * @param[in,out] p_msg Pointer to the tx message that will be filled out in this function.
+ * @param[in] p_attr_count Pointer to a variable that iterates the possible App Attributes.
+ */
+static encode_app_attr_t app_attr_encode_attr_id(ble_ancs_c_t * p_ancs,
+ uint32_t * p_index,
+ uint16_t * p_offset,
+ tx_message_t * p_msg,
+ uint32_t * p_attr_count,
+ uint32_t * attr_get_total_nb)
+{
+ NRF_LOG_DEBUG("Encoding Attribute ID");
+ if ((*p_index) >= ANCS_GATTC_WRITE_PAYLOAD_LEN_MAX)
+ {
+ queued_write_tx_message(p_ancs->conn_handle,
+ p_ancs->service.control_point_char.handle_value,
+ p_offset, p_index, p_msg);
+ *(p_offset) += *p_index;
+ *p_index = 0;
+ }
+ //Encode Attribute ID.
+ if (*p_attr_count < BLE_ANCS_NB_OF_APP_ATTR)
+ {
+ if (app_attr_is_requested(p_ancs, *p_attr_count))
+ {
+ p_msg->req.write_req.gattc_value[(*p_index)] = *p_attr_count;
+ p_ancs->number_of_requested_attr++;
+ (*p_index)++;
+ NRF_LOG_DEBUG("offset %i", *p_offset);
+ }
+ (*p_attr_count)++;
+ }
+ if (*p_attr_count == BLE_ANCS_NB_OF_APP_ATTR)
+ {
+ return APP_ATTR_DONE;
+ }
+ return APP_ATTR_APP_ID;
+}
+
+/**@brief Function for writing the execute write command to a handle for a given connection.
+ *
+ * @param[in] conn_handle Connection handle for where the prepared write will be executed.
+ * @param[in] handle_value The handle that will receive the execute command.
+ * @param[in] p_msg Pointer to the message that will be filled out in this function and then
+ * added to the tx queue.
+ */
+static void app_attr_execute_write(uint16_t conn_handle, uint16_t handle_value, tx_message_t * p_msg)
+{
+ NRF_LOG_DEBUG("Sending Execute Write.");
+ memset(p_msg,0,sizeof(tx_message_t));
+
+ p_msg->req.write_req.gattc_params.handle = handle_value;
+ p_msg->req.write_req.gattc_params.p_value = p_msg->req.write_req.gattc_value;
+ p_msg->req.write_req.gattc_params.offset = 0;
+ p_msg->req.write_req.gattc_params.write_op = BLE_GATT_OP_EXEC_WRITE_REQ;
+ p_msg->req.write_req.gattc_params.flags = BLE_GATT_EXEC_WRITE_FLAG_PREPARED_WRITE;
+
+ p_msg->req.write_req.gattc_params.len = 0;
+ p_msg->conn_handle = conn_handle;
+ p_msg->type = WRITE_REQ;
+
+ tx_buffer_insert(p_msg);
+}
+
+
+/**@brief Function for sending a get App Attributes request.
+ *
+ * @details Since the APP id may not fit in a single write, we use long write
+ * with a state machine to encode the Get App Attribute request.
+ *
+ * @param[in] p_ancs iOS notification structure. This structure must be supplied by
+ * the application. It identifies the particular client instance to use.
+ * @param[in] p_app_id The App ID for the App which we will request App Attributes for.
+ * @param[in] app_id_len Length of the App ID.
+ *
+*/
+static uint32_t app_attr_get(ble_ancs_c_t * p_ancs,
+ const uint8_t * p_app_id,
+ uint32_t app_id_len)
+{
+ uint32_t index = 0;
+ uint32_t attr_bytes_encoded_count = 0;
+ uint16_t offset = 0;
+ uint32_t app_id_bytes_encoded_count = 0;
+ encode_app_attr_t state = APP_ATTR_COMMAND_ID;
+ p_ancs->number_of_requested_attr = 0;
+
+ uint32_t attr_get_total_nb = app_attr_nb_to_get(p_ancs);
+ tx_message_t p_msg;
+
+ memset(&p_msg, 0, sizeof(tx_message_t));
+
+ while (state != APP_ATTR_DONE)
+ {
+ switch (state)
+ {
+ case APP_ATTR_COMMAND_ID:
+ state = app_attr_encode_cmd_id(p_ancs,
+ &index,
+ &p_msg);
+ break;
+ case APP_ATTR_APP_ID:
+ state = app_attr_encode_app_id(p_ancs,
+ &index,
+ &offset,
+ &p_msg,
+ p_app_id,
+ app_id_len,
+ &app_id_bytes_encoded_count);
+ break;
+ case APP_ATTR_ATTR_ID:
+ state = app_attr_encode_attr_id(p_ancs,
+ &index,
+ &offset,
+ &p_msg,
+ &attr_bytes_encoded_count,
+ &attr_get_total_nb);
+ break;
+ case APP_ATTR_DONE:
+ break;
+ default:
+ break;
+ }
+ }
+ queued_write_tx_message(p_ancs->conn_handle,
+ p_ancs->service.control_point_char.handle_value,
+ &offset,
+ &index,
+ &p_msg);
+
+ app_attr_execute_write(p_ancs->conn_handle,
+ p_ancs->service.control_point_char.handle_value,
+ &p_msg);
+
+ p_ancs->parse_info.expected_number_of_attrs = p_ancs->number_of_requested_attr;
+
+ tx_buffer_process();
+ return NRF_SUCCESS;
+}
+
+
+uint32_t ancs_c_app_attr_request(ble_ancs_c_t * p_ancs,
+ const uint8_t * p_app_id,
+ uint32_t len)
+{
+ uint32_t err_code;
+
+ if (len == 0)
+ {
+ return NRF_ERROR_DATA_SIZE;
+ }
+ if (p_app_id[len] != '\0') // App id to be requestes must be NULL terminated
+ {
+ return NRF_ERROR_INVALID_PARAM;
+ }
+
+ p_ancs->parse_info.parse_state = COMMAND_ID;
+ err_code = app_attr_get(p_ancs, p_app_id, len);
+ VERIFY_SUCCESS(err_code);
+ return NRF_SUCCESS;
+}
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/ble_ancs_c/ancs_app_attr_get.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/ble_ancs_c/ancs_app_attr_get.h
new file mode 100644
index 0000000..c942f73
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/ble_ancs_c/ancs_app_attr_get.h
@@ -0,0 +1,66 @@
+/**
+ * Copyright (c) 2012 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#ifndef ANCS_APP_ATTR_GET_H__
+#define ANCS_APP_ATTR_GET_H__
+
+#include "nrf_ble_ancs_c.h"
+/** @file
+ *
+ * @addtogroup ble_ancs_c
+ * @{
+ */
+
+/**@brief Function for requesting attributes for an app.
+ *
+ * @param[in] p_ancs iOS notification structure. This structure must be supplied by
+ * the application. It identifies the particular client instance to use.
+ * @param[in] app_id App identifier of the app for which to request app attributes.
+ * @param[in] len Length of the app identifier.
+ *
+ * @retval NRF_SUCCESS If all operations were successful. Otherwise, an error code is returned.
+ */
+uint32_t ancs_c_app_attr_request(ble_ancs_c_t * p_ancs,
+ const uint8_t * app_id,
+ uint32_t len);
+
+/** @} */
+
+#endif // ANCS_APP_ATTR_GET_H__
+
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/ble_ancs_c/ancs_attr_parser.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/ble_ancs_c/ancs_attr_parser.c
new file mode 100644
index 0000000..60f18e0
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/ble_ancs_c/ancs_attr_parser.c
@@ -0,0 +1,392 @@
+/**
+ * Copyright (c) 2016 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+/* Disclaimer: This client implementation of the Apple Notification Center Service can and will be changed at any time by Nordic Semiconductor ASA.
+ * Server implementations such as the ones found in iOS can be changed at any time by Apple and may cause this client implementation to stop working.
+ */
+
+ #include "nrf_ble_ancs_c.h"
+ #include "ancs_attr_parser.h"
+ #include "nrf_log.h"
+
+
+static bool all_req_attrs_parsed(ble_ancs_c_t * p_ancs)
+{
+ if (p_ancs->parse_info.expected_number_of_attrs == 0)
+ {
+ return true;
+ }
+ return false;
+}
+
+static bool attr_is_requested(ble_ancs_c_t * p_ancs, ble_ancs_c_attr_t attr)
+{
+ if (p_ancs->parse_info.p_attr_list[attr.attr_id].get == true)
+ {
+ return true;
+ }
+ return false;
+}
+
+
+/**@brief Function for parsing command id and notification id.
+ * Used in the @ref parse_get_notif_attrs_response state machine.
+ *
+ * @details UID and command ID will be received only once at the beginning of the first
+ * GATTC notification of a new attribute request for a given iOS notification.
+ *
+ * @param[in] p_ancs Pointer to an ANCS instance to which the event belongs.
+ * @param[in] p_data_src Pointer to data that was received from the Notification Provider.
+ * @param[in] index Pointer to an index that helps us keep track of the current data to be parsed.
+ *
+ * @return The next parse state.
+ */
+static ble_ancs_c_parse_state_t command_id_parse(ble_ancs_c_t * p_ancs,
+ const uint8_t * p_data_src,
+ uint32_t * index)
+{
+ ble_ancs_c_parse_state_t parse_state;
+
+ p_ancs->parse_info.command_id = (ble_ancs_c_cmd_id_val_t) p_data_src[(*index)++];
+
+ switch (p_ancs->parse_info.command_id)
+ {
+ case BLE_ANCS_COMMAND_ID_GET_NOTIF_ATTRIBUTES:
+ p_ancs->evt.evt_type = BLE_ANCS_C_EVT_NOTIF_ATTRIBUTE;
+ p_ancs->parse_info.p_attr_list = p_ancs->ancs_notif_attr_list;
+ p_ancs->parse_info.nb_of_attr = BLE_ANCS_NB_OF_NOTIF_ATTR;
+ parse_state = NOTIF_UID;
+ break;
+
+ case BLE_ANCS_COMMAND_ID_GET_APP_ATTRIBUTES:
+ p_ancs->evt.evt_type = BLE_ANCS_C_EVT_APP_ATTRIBUTE;
+ p_ancs->parse_info.p_attr_list = p_ancs->ancs_app_attr_list;
+ p_ancs->parse_info.nb_of_attr = BLE_ANCS_NB_OF_APP_ATTR;
+ parse_state = APP_ID;
+ break;
+
+ default:
+ //no valid command_id, abort the rest of the parsing procedure.
+ NRF_LOG_DEBUG("Invalid Command ID");
+ parse_state = DONE;
+ break;
+ }
+ return parse_state;
+}
+
+
+static ble_ancs_c_parse_state_t notif_uid_parse(ble_ancs_c_t * p_ancs,
+ const uint8_t * p_data_src,
+ uint32_t * index)
+{
+ p_ancs->evt.notif_uid = uint32_decode(&p_data_src[*index]);
+ *index += sizeof(uint32_t);
+ return ATTR_ID;
+}
+
+static ble_ancs_c_parse_state_t app_id_parse(ble_ancs_c_t * p_ancs,
+ const uint8_t * p_data_src,
+ uint32_t * index)
+{
+ p_ancs->evt.app_id[p_ancs->parse_info.current_app_id_index] = p_data_src[(*index)++];
+
+ if (p_ancs->evt.app_id[p_ancs->parse_info.current_app_id_index] != '\0')
+ {
+ p_ancs->parse_info.current_app_id_index++;
+ return APP_ID;
+ }
+ else
+ {
+ return ATTR_ID;
+ }
+}
+
+/**@brief Function for parsing the id of an iOS attribute.
+ * Used in the @ref parse_get_notif_attrs_response state machine.
+ *
+ * @details We only request attributes that are registered with @ref ble_ancs_c_attr_add
+ * once they have been reveiced we stop parsing.
+ *
+ * @param[in] p_ancs Pointer to an ANCS instance to which the event belongs.
+ * @param[in] p_data_src Pointer to data that was received from the Notification Provider.
+ * @param[in] index Pointer to an index that helps us keep track of the current data to be parsed.
+ *
+ * @return The next parse state.
+ */
+static ble_ancs_c_parse_state_t attr_id_parse(ble_ancs_c_t * p_ancs,
+ const uint8_t * p_data_src,
+ uint32_t * index)
+{
+ p_ancs->evt.attr.attr_id = p_data_src[(*index)++];
+
+ if (p_ancs->evt.attr.attr_id >= p_ancs->parse_info.nb_of_attr)
+ {
+ NRF_LOG_DEBUG("Attribute ID Invalid.");
+ return DONE;
+ }
+ p_ancs->evt.attr.p_attr_data = p_ancs->parse_info.p_attr_list[p_ancs->evt.attr.attr_id].p_attr_data;
+
+ if (all_req_attrs_parsed(p_ancs))
+ {
+ NRF_LOG_DEBUG("All requested attributes received. ");
+ return DONE;
+ }
+ else
+ {
+ if (attr_is_requested(p_ancs, p_ancs->evt.attr))
+ {
+ p_ancs->parse_info.expected_number_of_attrs--;
+ }
+ NRF_LOG_DEBUG("Attribute ID %i ", p_ancs->evt.attr.attr_id);
+ return ATTR_LEN1;
+ }
+}
+
+
+/**@brief Function for parsing the length of an iOS attribute.
+ * Used in the @ref parse_get_notif_attrs_response state machine.
+ *
+ * @details The Length is 2 bytes. Since there is a chance we reveice the bytes in two different
+ * GATTC notifications, we parse only the first byte here and then set the state machine
+ * ready to parse the next byte.
+ *
+ * @param[in] p_ancs Pointer to an ANCS instance to which the event belongs.
+ * @param[in] p_data_src Pointer to data that was received from the Notification Provider.
+ * @param[in] index Pointer to an index that helps us keep track of the current data to be parsed.
+ *
+ * @return The next parse state.
+ */
+static ble_ancs_c_parse_state_t attr_len1_parse(ble_ancs_c_t * p_ancs, const uint8_t * p_data_src, uint32_t * index)
+{
+ p_ancs->evt.attr.attr_len = p_data_src[(*index)++];
+ return ATTR_LEN2;
+}
+
+/**@brief Function for parsing the length of an iOS attribute.
+ * Used in the @ref parse_get_notif_attrs_response state machine.
+ *
+ * @details Second byte of the length field. If the length is zero, it means that the attribute is not
+ * present and the state machine is set to parse the next attribute.
+ *
+ * @param[in] p_ancs Pointer to an ANCS instance to which the event belongs.
+ * @param[in] p_data_src Pointer to data that was received from the Notification Provider.
+ * @param[in] index Pointer to an index that helps us keep track of the current data to be parsed.
+ *
+ * @return The next parse state.
+ */
+static ble_ancs_c_parse_state_t attr_len2_parse(ble_ancs_c_t * p_ancs, const uint8_t * p_data_src, uint32_t * index)
+{
+ p_ancs->evt.attr.attr_len |= (p_data_src[(*index)++] << 8);
+ p_ancs->parse_info.current_attr_index = 0;
+
+ if (p_ancs->evt.attr.attr_len != 0)
+ {
+ //If the attribute has a length but there is no allocated space for this attribute
+ if ((p_ancs->parse_info.p_attr_list[p_ancs->evt.attr.attr_id].attr_len == 0) ||
+ (p_ancs->parse_info.p_attr_list[p_ancs->evt.attr.attr_id].p_attr_data == NULL))
+ {
+ return ATTR_SKIP;
+ }
+ else
+ {
+ return ATTR_DATA;
+ }
+ }
+ else
+ {
+
+ NRF_LOG_DEBUG("Attribute LEN %i ", p_ancs->evt.attr.attr_len);
+ if (attr_is_requested(p_ancs, p_ancs->evt.attr))
+ {
+ p_ancs->evt_handler(&p_ancs->evt);
+ }
+ if (all_req_attrs_parsed(p_ancs))
+ {
+ return DONE;
+ }
+ else
+ {
+ return ATTR_ID;
+ }
+ }
+}
+
+
+/**@brief Function for parsing the data of an iOS attribute.
+ * Used in the @ref parse_get_notif_attrs_response state machine.
+ *
+ * @details Read the data of the attribute into our local buffer.
+ *
+ * @param[in] p_ancs Pointer to an ANCS instance to which the event belongs.
+ * @param[in] p_data_src Pointer to data that was received from the Notification Provider.
+ * @param[in] index Pointer to an index that helps us keep track of the current data to be parsed.
+ *
+ * @return The next parse state.
+ */
+static ble_ancs_c_parse_state_t attr_data_parse(ble_ancs_c_t * p_ancs,
+ const uint8_t * p_data_src,
+ uint32_t * index)
+{
+ // We have not reached the end of the attribute, nor our max allocated internal size.
+ // Proceed with copying data over to our buffer.
+ if ( (p_ancs->parse_info.current_attr_index < p_ancs->parse_info.p_attr_list[p_ancs->evt.attr.attr_id].attr_len)
+ && (p_ancs->parse_info.current_attr_index < p_ancs->evt.attr.attr_len))
+ {
+ //NRF_LOG_DEBUG("Byte copied to buffer: %c", p_data_src[(*index)]); // Un-comment this line to see every byte of an attribute as it is parsed. Commented out by default since it can overflow the uart buffer.
+ p_ancs->evt.attr.p_attr_data[p_ancs->parse_info.current_attr_index++] = p_data_src[(*index)++];
+ }
+
+ // We have reached the end of the attribute, or our max allocated internal size.
+ // Stop copying data over to our buffer. NUL-terminate at the current index.
+ if ( (p_ancs->parse_info.current_attr_index == p_ancs->evt.attr.attr_len) ||
+ (p_ancs->parse_info.current_attr_index == p_ancs->parse_info.p_attr_list[p_ancs->evt.attr.attr_id].attr_len - 1))
+ {
+ if (attr_is_requested(p_ancs, p_ancs->evt.attr))
+ {
+ p_ancs->evt.attr.p_attr_data[p_ancs->parse_info.current_attr_index] = '\0';
+ }
+
+ // If our max buffer size is smaller than the remaining attribute data, we must
+ // increase index to skip the data until the start of the next attribute.
+ if (p_ancs->parse_info.current_attr_index < p_ancs->evt.attr.attr_len)
+ {
+ return ATTR_SKIP;
+ }
+ NRF_LOG_DEBUG("Attribute finished!");
+ if (attr_is_requested(p_ancs, p_ancs->evt.attr))
+ {
+ p_ancs->evt_handler(&p_ancs->evt);
+ }
+ if (all_req_attrs_parsed(p_ancs))
+ {
+ return DONE;
+ }
+ else
+ {
+ return ATTR_ID;
+ }
+ }
+ return ATTR_DATA;
+}
+
+
+static ble_ancs_c_parse_state_t attr_skip(ble_ancs_c_t * p_ancs, const uint8_t * p_data_src, uint32_t * index)
+{
+ // We have not reached the end of the attribute, nor our max allocated internal size.
+ // Proceed with copying data over to our buffer.
+ if (p_ancs->parse_info.current_attr_index < p_ancs->evt.attr.attr_len)
+ {
+ p_ancs->parse_info.current_attr_index++;
+ (*index)++;
+ }
+ // At the end of the attribute, determine if it should be passed to event handler and
+ // continue parsing the next attribute ID if we are not done with all the attributes.
+ if (p_ancs->parse_info.current_attr_index == p_ancs->evt.attr.attr_len)
+ {
+ if (attr_is_requested(p_ancs, p_ancs->evt.attr))
+ {
+ p_ancs->evt_handler(&p_ancs->evt);
+ }
+ if (all_req_attrs_parsed(p_ancs))
+ {
+ return DONE;
+ }
+ else
+ {
+ return ATTR_ID;
+ }
+ }
+ return ATTR_SKIP;
+}
+
+
+void ancs_parse_get_attrs_response(ble_ancs_c_t * p_ancs,
+ const uint8_t * p_data_src,
+ const uint16_t hvx_data_len)
+{
+ uint32_t index;
+
+ for (index = 0; index < hvx_data_len;)
+ {
+ switch (p_ancs->parse_info.parse_state)
+ {
+ case COMMAND_ID:
+ p_ancs->parse_info.parse_state = command_id_parse(p_ancs, p_data_src, &index);
+ break;
+
+ case NOTIF_UID:
+ p_ancs->parse_info.parse_state = notif_uid_parse(p_ancs, p_data_src, &index);
+ break;
+
+ case APP_ID:
+ p_ancs->parse_info.parse_state = app_id_parse(p_ancs, p_data_src, &index);
+ break;
+
+ case ATTR_ID:
+ p_ancs->parse_info.parse_state = attr_id_parse(p_ancs, p_data_src, &index);
+ break;
+
+ case ATTR_LEN1:
+ p_ancs->parse_info.parse_state = attr_len1_parse(p_ancs, p_data_src, &index);
+ break;
+
+ case ATTR_LEN2:
+ p_ancs->parse_info.parse_state = attr_len2_parse(p_ancs, p_data_src, &index);
+ break;
+
+ case ATTR_DATA:
+ p_ancs->parse_info.parse_state = attr_data_parse(p_ancs, p_data_src, &index);
+ break;
+
+ case ATTR_SKIP:
+ p_ancs->parse_info.parse_state = attr_skip(p_ancs, p_data_src, &index);
+ break;
+
+ case DONE:
+ NRF_LOG_DEBUG("Parse state: Done ");
+ index = hvx_data_len;
+ break;
+
+ default:
+ // Default case will never trigger intentionally. Go to the DONE state to minimize the consequences.
+ p_ancs->parse_info.parse_state = DONE;
+ break;
+ }
+ }
+}
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/ble_ancs_c/ancs_attr_parser.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/ble_ancs_c/ancs_attr_parser.h
new file mode 100644
index 0000000..92cea55
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/ble_ancs_c/ancs_attr_parser.h
@@ -0,0 +1,77 @@
+/**
+ * Copyright (c) 2012 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#ifndef BLE_ANCS_ATTR_PARSER_H__
+#define BLE_ANCS_ATTR_PARSER_H__
+
+#include "nrf_ble_ancs_c.h"
+
+/** @file
+ *
+ * @addtogroup ble_ancs_c
+ * @{
+ */
+
+/**@brief Function for parsing notification or app attribute response data.
+ *
+ * @details The data that comes from the Notification Provider can be much longer than what
+ * would fit in a single GATTC notification. Therefore, this function relies on a
+ * state-oriented switch case.
+ * UID and command ID will be received only once at the beginning of the first
+ * GATTC notification of a new attribute request for a given iOS notification.
+ * After this, we can loop several ATTR_ID > LENGTH > DATA > ATTR_ID > LENGTH > DATA until
+ * we have received all attributes we wanted as a Notification Consumer.
+ * The Notification Provider can also simply stop sending attributes.
+ *
+ * 1 byte | 4 bytes |1 byte |2 bytes |... X bytes ... |1 bytes| 2 bytes| ... X bytes ...
+ * --------|-------------|-------|--------|----------------|-------|--------|----------------
+ * CMD_ID | NOTIF_UID |ATTR_ID| LENGTH | DATA |ATTR_ID| LENGTH | DATA
+ *
+ * @param[in] p_ancs Pointer to an ANCS instance to which the event belongs.
+ * @param[in] p_data_src Pointer to data that was received from the Notification Provider.
+ * @param[in] hvx_data_len Length of the data that was received from the Notification Provider.
+ */
+void ancs_parse_get_attrs_response(ble_ancs_c_t * p_ancs,
+ const uint8_t * p_data_src,
+ const uint16_t hvx_data_len);
+
+/** @} */
+
+#endif // BLE_ANCS_ATTR_PARSER_H__
+
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/ble_ancs_c/ancs_tx_buffer.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/ble_ancs_c/ancs_tx_buffer.c
new file mode 100644
index 0000000..91e6886
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/ble_ancs_c/ancs_tx_buffer.c
@@ -0,0 +1,113 @@
+/**
+ * Copyright (c) 2016 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+/* Disclaimer: This client implementation of the Apple Notification Center Service can and will be changed at any time by Nordic Semiconductor ASA.
+ * Server implementations such as the ones found in iOS can be changed at any time by Apple and may cause this client implementation to stop working.
+ */
+
+ #include "nrf_ble_ancs_c.h"
+ #include "ancs_tx_buffer.h"
+ #include "sdk_macros.h"
+ #include "nrf_log.h"
+ #include "string.h"
+
+
+static tx_message_t m_tx_buffer[TX_BUFFER_SIZE]; /**< Transmit buffer for messages to be transmitted to the Notification Provider. */
+static uint32_t m_tx_insert_index = 0; /**< Current index in the transmit buffer where the next message should be inserted. */
+static uint32_t m_tx_index = 0; /**< Current index in the transmit buffer from where the next message to be transmitted resides. */
+
+
+void tx_buffer_init(void)
+{
+ memset(m_tx_buffer, 0, sizeof(m_tx_buffer));
+}
+
+
+void tx_buffer_insert(tx_message_t * p_msg)
+{
+
+ memset(&(m_tx_buffer[m_tx_insert_index]), 0, sizeof(m_tx_buffer)/sizeof(tx_message_t));
+
+ m_tx_buffer[m_tx_insert_index].conn_handle = p_msg->conn_handle;
+ m_tx_buffer[m_tx_insert_index].type = p_msg->type;
+
+ m_tx_buffer[m_tx_insert_index].req.write_req.gattc_params.handle = p_msg->req.write_req.gattc_params.handle;
+ m_tx_buffer[m_tx_insert_index].req.write_req.gattc_params.len = p_msg->req.write_req.gattc_params.len;
+ m_tx_buffer[m_tx_insert_index].req.write_req.gattc_params.write_op = p_msg->req.write_req.gattc_params.write_op;
+ m_tx_buffer[m_tx_insert_index].req.write_req.gattc_params.flags = p_msg->req.write_req.gattc_params.flags;
+ m_tx_buffer[m_tx_insert_index].req.write_req.gattc_params.p_value = m_tx_buffer[m_tx_insert_index].req.write_req.gattc_value;
+ m_tx_buffer[m_tx_insert_index].req.write_req.gattc_params.offset = p_msg->req.write_req.gattc_params.offset;
+
+ if (p_msg->type == WRITE_REQ)
+ {
+ memcpy(m_tx_buffer[m_tx_insert_index].req.write_req.gattc_value,
+ p_msg->req.write_req.gattc_value,
+ WRITE_MESSAGE_LENGTH);
+ }
+
+ m_tx_insert_index++;
+ m_tx_insert_index &= TX_BUFFER_MASK;
+}
+
+
+
+void tx_buffer_process(void)
+{
+ if (m_tx_index != m_tx_insert_index)
+ {
+ uint32_t err_code;
+
+ if (m_tx_buffer[m_tx_index].type == READ_REQ)
+ {
+ err_code = sd_ble_gattc_read(m_tx_buffer[m_tx_index].conn_handle,
+ m_tx_buffer[m_tx_index].req.read_handle,
+ 0);
+ }
+ else
+ {
+ err_code = sd_ble_gattc_write(m_tx_buffer[m_tx_index].conn_handle,
+ &m_tx_buffer[m_tx_index].req.write_req.gattc_params);
+ }
+ if (err_code == NRF_SUCCESS)
+ {
+ ++m_tx_index;
+ m_tx_index &= TX_BUFFER_MASK;
+ }
+ }
+}
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/ble_ancs_c/ancs_tx_buffer.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/ble_ancs_c/ancs_tx_buffer.h
new file mode 100644
index 0000000..6953438
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/ble_ancs_c/ancs_tx_buffer.h
@@ -0,0 +1,103 @@
+/**
+ * Copyright (c) 2012 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#ifndef ANCS_TX_BUFFER_H__
+#define ANCS_TX_BUFFER_H__
+
+#include "nrf_ble_ancs_c.h"
+
+/** @file
+ *
+ * @addtogroup ble_ancs_c
+ * @{
+ */
+
+#define TX_BUFFER_MASK 0x07 //!< TX buffer mask. Must be a mask of contiguous zeroes followed by a contiguous sequence of ones: 000...111.
+#define TX_BUFFER_SIZE (TX_BUFFER_MASK + 1) //!< Size of the send buffer, which is 1 bigger than the mask.
+#define WRITE_MESSAGE_LENGTH 20 //!< Length of the write message for the CCCD/control point.
+
+/**@brief ANCS request types.
+ */
+typedef enum
+{
+ READ_REQ = 1, /**< Type identifying that this TX message is a read request. */
+ WRITE_REQ /**< Type identifying that this TX message is a write request. */
+} tx_request_t;
+
+
+/**@brief Structure for writing a message to the central, thus the Control Point or CCCD.
+ */
+typedef struct
+{
+ uint8_t gattc_value[WRITE_MESSAGE_LENGTH]; //!< The message to write.
+ ble_gattc_write_params_t gattc_params; //!< GATTC parameters for this message.
+} write_params_t;
+
+
+/**@brief Data to be transmitted to the connected master.
+ */
+typedef struct
+{
+ uint16_t conn_handle; //!< Connection handle to be used when transmitting this message.
+ tx_request_t type; //!< Type of this message (read or write message).
+ union
+ {
+ uint16_t read_handle; //!< Read request message.
+ write_params_t write_req; //!< Write request message.
+ } req;
+} tx_message_t;
+
+/**@brief Function for clearing the TX buffer.
+ *
+ * @details Always call this function before using the TX buffer.
+*/
+void tx_buffer_init(void);
+
+/**@brief Function for moving the pointer of the ring buffer to the next element.
+*/
+void tx_buffer_insert(tx_message_t * p_msg);
+
+/**@brief Function for passing any pending request from the buffer to the stack.
+*/
+void tx_buffer_process(void);
+
+/** @} */
+
+#endif // ANCS_TX_BUFFER_H__
+
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/ble_ancs_c/nrf_ble_ancs_c.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/ble_ancs_c/nrf_ble_ancs_c.c
new file mode 100644
index 0000000..0ba177f
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/ble_ancs_c/nrf_ble_ancs_c.c
@@ -0,0 +1,652 @@
+/**
+ * Copyright (c) 2012 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+/* Disclaimer: This client implementation of the Apple Notification Center Service can and will be changed at any time by Nordic Semiconductor ASA.
+ * Server implementations such as the ones found in iOS can be changed at any time by Apple and may cause this client implementation to stop working.
+ */
+#include "sdk_common.h"
+#if NRF_MODULE_ENABLED(BLE_ANCS_C)
+#include "nrf_ble_ancs_c.h"
+#include "ancs_tx_buffer.h"
+#include "ancs_attr_parser.h"
+#include "ancs_app_attr_get.h"
+#include "ble_err.h"
+#include "ble_srv_common.h"
+#include "ble_db_discovery.h"
+#include "app_error.h"
+#define NRF_LOG_MODULE_NAME ble_ancs_c
+#include "nrf_log.h"
+NRF_LOG_MODULE_REGISTER();
+
+#define BLE_ANCS_NOTIF_EVT_ID_INDEX 0 /**< Index of the Event ID field when parsing notifications. */
+#define BLE_ANCS_NOTIF_FLAGS_INDEX 1 /**< Index of the Flags field when parsing notifications. */
+#define BLE_ANCS_NOTIF_CATEGORY_ID_INDEX 2 /**< Index of the Category ID field when parsing notifications. */
+#define BLE_ANCS_NOTIF_CATEGORY_CNT_INDEX 3 /**< Index of the Category Count field when parsing notifications. */
+#define BLE_ANCS_NOTIF_NOTIF_UID 4 /**< Index of the Notification UID field when patsin notifications. */
+
+#define BLE_CCCD_NOTIFY_BIT_MASK 0x0001 /**< Enable notification bit. */
+
+#define TIME_STRING_LEN 15 /**< Unicode Technical Standard (UTS) #35 date format pattern "yyyyMMdd'T'HHmmSS" + "'\0'". */
+
+
+/**@brief 128-bit service UUID for the Apple Notification Center Service. */
+ble_uuid128_t const ble_ancs_base_uuid128 =
+{
+ {
+ // 7905F431-B5CE-4E99-A40F-4B1E122D00D0
+ 0xd0, 0x00, 0x2d, 0x12, 0x1e, 0x4b, 0x0f, 0xa4,
+ 0x99, 0x4e, 0xce, 0xb5, 0x31, 0xf4, 0x05, 0x79
+ }
+};
+
+
+/**@brief 128-bit control point UUID. */
+ble_uuid128_t const ble_ancs_cp_base_uuid128 =
+{
+ {
+ // 69d1d8f3-45e1-49a8-9821-9BBDFDAAD9D9
+ 0xd9, 0xd9, 0xaa, 0xfd, 0xbd, 0x9b, 0x21, 0x98,
+ 0xa8, 0x49, 0xe1, 0x45, 0xf3, 0xd8, 0xd1, 0x69
+ }
+};
+
+/**@brief 128-bit notification source UUID. */
+ble_uuid128_t const ble_ancs_ns_base_uuid128 =
+{
+ {
+ // 9FBF120D-6301-42D9-8C58-25E699A21DBD
+ 0xbd, 0x1d, 0xa2, 0x99, 0xe6, 0x25, 0x58, 0x8c,
+ 0xd9, 0x42, 0x01, 0x63, 0x0d, 0x12, 0xbf, 0x9f
+
+ }
+};
+
+/**@brief 128-bit data source UUID. */
+ble_uuid128_t const ble_ancs_ds_base_uuid128 =
+{
+ {
+ // 22EAC6E9-24D6-4BB5-BE44-B36ACE7C7BFB
+ 0xfb, 0x7b, 0x7c, 0xce, 0x6a, 0xb3, 0x44, 0xbe,
+ 0xb5, 0x4b, 0xd6, 0x24, 0xe9, 0xc6, 0xea, 0x22
+ }
+};
+
+
+/**@brief Function for handling Disconnected event received from the SoftDevice.
+ *
+ * @details This function check if the disconnect event is happening on the link
+ * associated with the current instance of the module, if so it will set its
+ * conn_handle to invalid.
+ *
+ * @param[in] p_ancs Pointer to the ANCS client structure.
+ * @param[in] p_ble_evt Pointer to the BLE event received.
+ */
+static void on_disconnected(ble_ancs_c_t * p_ancs, ble_evt_t const * p_ble_evt)
+{
+ if (p_ancs->conn_handle == p_ble_evt->evt.gap_evt.conn_handle)
+ {
+ p_ancs->conn_handle = BLE_CONN_HANDLE_INVALID;
+ }
+}
+
+
+void ble_ancs_c_on_db_disc_evt(ble_ancs_c_t * p_ancs, ble_db_discovery_evt_t * p_evt)
+{
+ NRF_LOG_DEBUG("Database Discovery handler called with event 0x%x", p_evt->evt_type);
+
+ ble_ancs_c_evt_t evt;
+ ble_gatt_db_char_t * p_chars;
+
+ p_chars = p_evt->params.discovered_db.charateristics;
+
+ // Check if the ANCS Service was discovered.
+ if ( (p_evt->evt_type == BLE_DB_DISCOVERY_COMPLETE)
+ && (p_evt->params.discovered_db.srv_uuid.uuid == ANCS_UUID_SERVICE)
+ && (p_evt->params.discovered_db.srv_uuid.type == p_ancs->service.service.uuid.type))
+ {
+ // Find the handles of the ANCS characteristic.
+ for (uint32_t i = 0; i < p_evt->params.discovered_db.char_count; i++)
+ {
+ switch (p_chars[i].characteristic.uuid.uuid)
+ {
+ case ANCS_UUID_CHAR_CONTROL_POINT:
+ NRF_LOG_INFO("Control Point Characteristic found.");
+ memcpy(&evt.service.control_point_char,
+ &p_chars[i].characteristic,
+ sizeof(ble_gattc_char_t));
+ break;
+
+ case ANCS_UUID_CHAR_DATA_SOURCE:
+ NRF_LOG_INFO("Data Source Characteristic found.");
+ memcpy(&evt.service.data_source_char,
+ &p_chars[i].characteristic,
+ sizeof(ble_gattc_char_t));
+ evt.service.data_source_cccd.handle = p_chars[i].cccd_handle;
+ break;
+
+ case ANCS_UUID_CHAR_NOTIFICATION_SOURCE:
+ NRF_LOG_INFO("Notification point Characteristic found.");
+ memcpy(&evt.service.notif_source_char,
+ &p_chars[i].characteristic,
+ sizeof(ble_gattc_char_t));
+ evt.service.notif_source_cccd.handle = p_chars[i].cccd_handle;
+ break;
+
+ default:
+ break;
+ }
+ }
+ evt.evt_type = BLE_ANCS_C_EVT_DISCOVERY_COMPLETE;
+ evt.conn_handle = p_evt->conn_handle;
+ p_ancs->evt_handler(&evt);
+ }
+ else
+ {
+ evt.evt_type = BLE_ANCS_C_EVT_DISCOVERY_FAILED;
+ p_ancs->evt_handler(&evt);
+ }
+}
+
+
+/**@brief Function for checking if data in an iOS notification is out of bounds.
+ *
+ * @param[in] notif An iOS notification.
+ *
+ * @retval NRF_SUCCESS If the notification is within bounds.
+ * @retval NRF_ERROR_INVALID_PARAM If the notification is out of bounds.
+ */
+static uint32_t ble_ancs_verify_notification_format(ble_ancs_c_evt_notif_t const * notif)
+{
+ if ( (notif->evt_id >= BLE_ANCS_NB_OF_EVT_ID)
+ || (notif->category_id >= BLE_ANCS_NB_OF_CATEGORY_ID))
+ {
+ return NRF_ERROR_INVALID_PARAM;
+ }
+ return NRF_SUCCESS;
+}
+
+/**@brief Function for receiving and validating notifications received from the Notification Provider.
+ *
+ * @param[in] p_ancs Pointer to an ANCS instance to which the event belongs.
+ * @param[in] p_data_src Pointer to data that was received from the Notification Provider.
+ * @param[in] hvx_len Length of the data that was received by the Notification Provider.
+ */
+static void parse_notif(ble_ancs_c_t const * p_ancs,
+ uint8_t const * p_data_src,
+ uint16_t const hvx_data_len)
+{
+ ble_ancs_c_evt_t ancs_evt;
+ uint32_t err_code;
+ if (hvx_data_len != BLE_ANCS_NOTIFICATION_DATA_LENGTH)
+ {
+ ancs_evt.evt_type = BLE_ANCS_C_EVT_INVALID_NOTIF;
+ p_ancs->evt_handler(&ancs_evt);
+ }
+
+ /*lint --e{415} --e{416} -save suppress Warning 415: possible access out of bond */
+ ancs_evt.notif.evt_id =
+ (ble_ancs_c_evt_id_values_t) p_data_src[BLE_ANCS_NOTIF_EVT_ID_INDEX];
+
+ ancs_evt.notif.evt_flags.silent =
+ (p_data_src[BLE_ANCS_NOTIF_FLAGS_INDEX] >> BLE_ANCS_EVENT_FLAG_SILENT) & 0x01;
+
+ ancs_evt.notif.evt_flags.important =
+ (p_data_src[BLE_ANCS_NOTIF_FLAGS_INDEX] >> BLE_ANCS_EVENT_FLAG_IMPORTANT) & 0x01;
+
+ ancs_evt.notif.evt_flags.pre_existing =
+ (p_data_src[BLE_ANCS_NOTIF_FLAGS_INDEX] >> BLE_ANCS_EVENT_FLAG_PREEXISTING) & 0x01;
+
+ ancs_evt.notif.evt_flags.positive_action =
+ (p_data_src[BLE_ANCS_NOTIF_FLAGS_INDEX] >> BLE_ANCS_EVENT_FLAG_POSITIVE_ACTION) & 0x01;
+
+ ancs_evt.notif.evt_flags.negative_action =
+ (p_data_src[BLE_ANCS_NOTIF_FLAGS_INDEX] >> BLE_ANCS_EVENT_FLAG_NEGATIVE_ACTION) & 0x01;
+
+ ancs_evt.notif.category_id =
+ (ble_ancs_c_category_id_val_t) p_data_src[BLE_ANCS_NOTIF_CATEGORY_ID_INDEX];
+
+ ancs_evt.notif.category_count = p_data_src[BLE_ANCS_NOTIF_CATEGORY_CNT_INDEX];
+ ancs_evt.notif.notif_uid = uint32_decode(&p_data_src[BLE_ANCS_NOTIF_NOTIF_UID]);
+ /*lint -restore*/
+
+ err_code = ble_ancs_verify_notification_format(&ancs_evt.notif);
+ if (err_code == NRF_SUCCESS)
+ {
+ ancs_evt.evt_type = BLE_ANCS_C_EVT_NOTIF;
+ }
+ else
+ {
+ ancs_evt.evt_type = BLE_ANCS_C_EVT_INVALID_NOTIF;
+ }
+
+ p_ancs->evt_handler(&ancs_evt);
+}
+
+
+ret_code_t nrf_ble_ancs_c_app_attr_request(ble_ancs_c_t * p_ancs,
+ uint8_t const * p_app_id,
+ uint32_t len)
+{
+ return ancs_c_app_attr_request(p_ancs, p_app_id, len);
+}
+
+
+/**@brief Function for receiving and validating notifications received from the Notification Provider.
+ *
+ * @param[in] p_ancs Pointer to an ANCS instance to which the event belongs.
+ * @param[in] p_ble_evt Bluetooth stack event.
+ */
+static void on_evt_gattc_notif(ble_ancs_c_t * p_ancs, ble_evt_t const * p_ble_evt)
+{
+ ble_gattc_evt_hvx_t const * p_notif = &p_ble_evt->evt.gattc_evt.params.hvx;
+
+ if (p_ble_evt->evt.gattc_evt.conn_handle != p_ancs->conn_handle)
+ {
+ return;
+ }
+
+ if (p_notif->handle == p_ancs->service.notif_source_char.handle_value)
+ {
+ parse_notif(p_ancs, p_notif->data, p_notif->len);
+ }
+ else if (p_notif->handle == p_ancs->service.data_source_char.handle_value)
+ {
+ ancs_parse_get_attrs_response(p_ancs, p_notif->data, p_notif->len);
+ }
+ else
+ {
+ // No applicable action.
+ }
+}
+
+/**@brief Function for handling error response events.
+ *
+ * @param[in] p_ancs_c Pointer to the Battery Service Client Structure.
+ * @param[in] p_ble_evt Pointer to the SoftDevice event.
+ */
+static void on_ctrlpt_error_rsp(ble_ancs_c_t * p_ancs, ble_evt_t const * p_ble_evt)
+{
+ ble_ancs_c_evt_t ancs_evt;
+
+ ancs_evt.evt_type = BLE_ANCS_C_EVT_NP_ERROR;
+ ancs_evt.err_code_np = p_ble_evt->evt.gattc_evt.gatt_status;
+
+ p_ancs->evt_handler(&ancs_evt);
+}
+
+/**@brief Function for handling write response events.
+ *
+ * @param[in] p_ancs_c Pointer to the Battery Service Client Structure.
+ * @param[in] p_ble_evt Pointer to the SoftDevice event.
+ */
+static void on_write_rsp(ble_ancs_c_t * p_ancs, ble_evt_t const* p_ble_evt)
+{
+ // Check if the event if on the link for this instance
+ if (p_ancs->conn_handle != p_ble_evt->evt.gattc_evt.conn_handle)
+ {
+ return;
+ }
+ if ((p_ble_evt->evt.gattc_evt.error_handle != BLE_GATT_HANDLE_INVALID)
+ && (p_ble_evt->evt.gattc_evt.error_handle == p_ancs->service.control_point_char.handle_value))
+ {
+ on_ctrlpt_error_rsp(p_ancs,p_ble_evt);
+ }
+ // Check if there is any message to be sent across to the peer and send it.
+ tx_buffer_process();
+}
+
+
+void ble_ancs_c_on_ble_evt(ble_evt_t const * p_ble_evt, void * p_context)
+{
+ ble_ancs_c_t * p_ancs = (ble_ancs_c_t *)p_context;
+ uint16_t evt = p_ble_evt->header.evt_id;
+
+ switch (evt)
+ {
+ case BLE_GATTC_EVT_WRITE_RSP:
+ on_write_rsp(p_ancs, p_ble_evt);
+ break;
+
+ case BLE_GATTC_EVT_HVX:
+ on_evt_gattc_notif(p_ancs, p_ble_evt);
+ break;
+
+ case BLE_GAP_EVT_DISCONNECTED:
+ on_disconnected(p_ancs, p_ble_evt);
+ break;
+
+ default:
+ break;
+ }
+}
+
+
+ret_code_t ble_ancs_c_init(ble_ancs_c_t * p_ancs, ble_ancs_c_init_t const * p_ancs_init)
+{
+ uint32_t err_code;
+
+ //Verify that the parameters needed for to initialize this instance of ANCS are not NULL.
+ VERIFY_PARAM_NOT_NULL(p_ancs);
+ VERIFY_PARAM_NOT_NULL(p_ancs_init);
+ VERIFY_PARAM_NOT_NULL(p_ancs_init->evt_handler);
+
+ //Initialize state for the attribute parsing state machine.
+ p_ancs->parse_info.parse_state = COMMAND_ID;
+ p_ancs->parse_info.p_data_dest = NULL;
+ p_ancs->parse_info.current_attr_index = 0;
+ p_ancs->parse_info.current_app_id_index = 0;
+
+ p_ancs->evt_handler = p_ancs_init->evt_handler;
+ p_ancs->error_handler = p_ancs_init->error_handler;
+ p_ancs->conn_handle = BLE_CONN_HANDLE_INVALID;
+
+ p_ancs->service.data_source_cccd.uuid.uuid = BLE_UUID_DESCRIPTOR_CLIENT_CHAR_CONFIG;
+ p_ancs->service.notif_source_cccd.uuid.uuid = BLE_UUID_DESCRIPTOR_CLIENT_CHAR_CONFIG;
+
+ // Make sure instance of service is clear. GATT handles inside the service and characteristics are set to @ref BLE_GATT_HANDLE_INVALID.
+ memset(&p_ancs->service, 0, sizeof(ble_ancs_c_service_t));
+ tx_buffer_init();
+
+ // Assign UUID types.
+ err_code = sd_ble_uuid_vs_add(&ble_ancs_base_uuid128, &p_ancs->service.service.uuid.type);
+ VERIFY_SUCCESS(err_code);
+
+ err_code = sd_ble_uuid_vs_add(&ble_ancs_cp_base_uuid128, &p_ancs->service.control_point_char.uuid.type);
+ VERIFY_SUCCESS(err_code);
+
+ err_code = sd_ble_uuid_vs_add(&ble_ancs_ns_base_uuid128, &p_ancs->service.notif_source_char.uuid.type);
+ VERIFY_SUCCESS(err_code);
+
+ err_code = sd_ble_uuid_vs_add(&ble_ancs_ds_base_uuid128, &p_ancs->service.data_source_char.uuid.type);
+ VERIFY_SUCCESS(err_code);
+
+ // Assign UUID to the service.
+ p_ancs->service.service.uuid.uuid = ANCS_UUID_SERVICE;
+ p_ancs->service.service.uuid.type = p_ancs->service.service.uuid.type;
+
+ return ble_db_discovery_evt_register(&p_ancs->service.service.uuid);
+}
+
+
+/**@brief Function for creating a TX message for writing a CCCD.
+ *
+ * @param[in] conn_handle Connection handle on which to perform the configuration.
+ * @param[in] handle_cccd Handle of the CCCD.
+ * @param[in] enable Enable or disable GATTC notifications.
+ *
+ * @retval NRF_SUCCESS If the message was created successfully.
+ * @retval NRF_ERROR_INVALID_PARAM If one of the input parameters was invalid.
+ */
+static uint32_t cccd_configure(const uint16_t conn_handle, const uint16_t handle_cccd, bool enable)
+{
+ tx_message_t p_msg;
+ memset(&p_msg, 0, sizeof(tx_message_t));
+ uint16_t cccd_val = enable ? BLE_CCCD_NOTIFY_BIT_MASK : 0;
+
+ p_msg.req.write_req.gattc_params.handle = handle_cccd;
+ p_msg.req.write_req.gattc_params.len = 2;
+ p_msg.req.write_req.gattc_params.p_value = p_msg.req.write_req.gattc_value;
+ p_msg.req.write_req.gattc_params.offset = 0;
+ p_msg.req.write_req.gattc_params.write_op = BLE_GATT_OP_WRITE_REQ;
+ p_msg.req.write_req.gattc_value[0] = LSB_16(cccd_val);
+ p_msg.req.write_req.gattc_value[1] = MSB_16(cccd_val);
+ p_msg.conn_handle = conn_handle;
+ p_msg.type = WRITE_REQ;
+
+ tx_buffer_insert(&p_msg);
+
+ tx_buffer_process();
+ return NRF_SUCCESS;
+}
+
+
+ret_code_t ble_ancs_c_notif_source_notif_enable(ble_ancs_c_t const * p_ancs)
+{
+ NRF_LOG_INFO("Enable Notification Source notifications. writing to handle: %i ",
+ p_ancs->service.notif_source_cccd.handle);
+ return cccd_configure(p_ancs->conn_handle, p_ancs->service.notif_source_cccd.handle, true);
+}
+
+
+ret_code_t ble_ancs_c_notif_source_notif_disable(ble_ancs_c_t const * p_ancs)
+{
+ return cccd_configure(p_ancs->conn_handle, p_ancs->service.notif_source_cccd.handle, false);
+}
+
+
+ret_code_t ble_ancs_c_data_source_notif_enable(ble_ancs_c_t const * p_ancs)
+{
+ NRF_LOG_INFO("Enable Data Source notifications. Writing to handle: %i ",
+ p_ancs->service.data_source_cccd.handle);
+ return cccd_configure(p_ancs->conn_handle, p_ancs->service.data_source_cccd.handle, true);
+}
+
+
+ret_code_t ble_ancs_c_data_source_notif_disable(ble_ancs_c_t const * p_ancs)
+{
+ return cccd_configure(p_ancs->conn_handle, p_ancs->service.data_source_cccd.handle, false);
+}
+
+
+uint32_t ble_ancs_get_notif_attrs(ble_ancs_c_t * p_ancs,
+ uint32_t const p_uid)
+{
+ tx_message_t p_msg;
+ memset(&p_msg, 0, sizeof(tx_message_t));
+
+ uint32_t index = 0;
+ p_ancs->number_of_requested_attr = 0;
+
+
+ p_msg.req.write_req.gattc_params.handle = p_ancs->service.control_point_char.handle_value;
+ p_msg.req.write_req.gattc_params.p_value = p_msg.req.write_req.gattc_value;
+ p_msg.req.write_req.gattc_params.offset = 0;
+ p_msg.req.write_req.gattc_params.write_op = BLE_GATT_OP_WRITE_REQ;
+
+ //Encode Command ID.
+ p_msg.req.write_req.gattc_value[index++] = BLE_ANCS_COMMAND_ID_GET_NOTIF_ATTRIBUTES;
+
+ //Encode Notification UID.
+ index += uint32_encode(p_uid, &(p_msg.req.write_req.gattc_value[index]));
+
+ //Encode Attribute ID.
+ for (uint32_t attr = 0; attr < BLE_ANCS_NB_OF_NOTIF_ATTR; attr++)
+ {
+ if (p_ancs->ancs_notif_attr_list[attr].get == true)
+ {
+ p_msg.req.write_req.gattc_value[index++] = attr;
+ if ((attr == BLE_ANCS_NOTIF_ATTR_ID_TITLE) ||
+ (attr == BLE_ANCS_NOTIF_ATTR_ID_SUBTITLE) ||
+ (attr == BLE_ANCS_NOTIF_ATTR_ID_MESSAGE))
+ {
+ //Encode Length field, only applicable for Title, Subtitle and Message
+ index += uint16_encode(p_ancs->ancs_notif_attr_list[attr].attr_len,
+ &(p_msg.req.write_req.gattc_value[index]));
+ }
+ p_ancs->number_of_requested_attr++;
+ }
+ }
+ p_msg.req.write_req.gattc_params.len = index;
+ p_msg.conn_handle = p_ancs->conn_handle;
+ p_msg.type = WRITE_REQ;
+ p_ancs->parse_info.expected_number_of_attrs = p_ancs->number_of_requested_attr;
+
+ tx_buffer_insert(&p_msg);
+ tx_buffer_process();
+
+ return NRF_SUCCESS;
+}
+
+
+ret_code_t nrf_ble_ancs_c_attr_add(ble_ancs_c_t * p_ancs,
+ ble_ancs_c_notif_attr_id_val_t const id,
+ uint8_t * p_data,
+ uint16_t const len)
+{
+ VERIFY_PARAM_NOT_NULL(p_data);
+
+ if ((len == 0) || (len > BLE_ANCS_ATTR_DATA_MAX))
+ {
+ return NRF_ERROR_INVALID_LENGTH;
+ }
+
+ p_ancs->ancs_notif_attr_list[id].get = true;
+ p_ancs->ancs_notif_attr_list[id].attr_len = len;
+ p_ancs->ancs_notif_attr_list[id].p_attr_data = p_data;
+
+ return NRF_SUCCESS;
+}
+
+
+ret_code_t nrf_ble_ancs_c_app_attr_add(ble_ancs_c_t * p_ancs,
+ ble_ancs_c_app_attr_id_val_t const id,
+ uint8_t * p_data,
+ uint16_t const len)
+{
+ VERIFY_PARAM_NOT_NULL(p_ancs);
+ VERIFY_PARAM_NOT_NULL(p_data);
+
+ if ((len == 0) || (len > BLE_ANCS_ATTR_DATA_MAX))
+ {
+ return NRF_ERROR_INVALID_LENGTH;
+ }
+
+ p_ancs->ancs_app_attr_list[id].get = true;
+ p_ancs->ancs_app_attr_list[id].attr_len = len;
+ p_ancs->ancs_app_attr_list[id].p_attr_data = p_data;
+
+ return NRF_SUCCESS;
+}
+
+ret_code_t ble_ancs_c_app_attr_remove(ble_ancs_c_t * p_ancs,
+ ble_ancs_c_app_attr_id_val_t const id)
+{
+ p_ancs->ancs_app_attr_list[id].get = false;
+ p_ancs->ancs_app_attr_list[id].attr_len = 0;
+ p_ancs->ancs_app_attr_list[id].p_attr_data = NULL;
+ return NRF_SUCCESS;
+}
+
+ret_code_t ble_ancs_c_notif_attr_remove(ble_ancs_c_t * p_ancs,
+ ble_ancs_c_notif_attr_id_val_t const id)
+{
+ p_ancs->ancs_notif_attr_list[id].get = false;
+ p_ancs->ancs_notif_attr_list[id].attr_len = 0;
+ p_ancs->ancs_notif_attr_list[id].p_attr_data = NULL;
+ return NRF_SUCCESS;
+}
+
+ret_code_t nrf_ble_ancs_c_attr_req_clear_all(ble_ancs_c_t * p_ancs)
+{
+ memset(p_ancs->ancs_notif_attr_list, 0 , sizeof(p_ancs->ancs_notif_attr_list));
+ memset(p_ancs->ancs_app_attr_list, 0 , sizeof(p_ancs->ancs_app_attr_list));
+ return NRF_SUCCESS;
+}
+
+
+ret_code_t nrf_ble_ancs_c_request_attrs(ble_ancs_c_t * p_ancs,
+ ble_ancs_c_evt_notif_t const * p_notif)
+{
+ uint32_t err_code;
+ err_code = ble_ancs_verify_notification_format(p_notif);
+ VERIFY_SUCCESS(err_code);
+
+ err_code = ble_ancs_get_notif_attrs(p_ancs, p_notif->notif_uid);
+ p_ancs->parse_info.parse_state = COMMAND_ID;
+ VERIFY_SUCCESS(err_code);
+
+ return NRF_SUCCESS;
+}
+
+static uint16_t encode_notif_action(uint8_t * p_encoded_data, uint32_t uid, ble_ancs_c_action_id_values_t action_id)
+{
+ uint8_t index = 0;
+
+ p_encoded_data[index++] = BLE_ANCS_COMMAND_ID_GET_PERFORM_NOTIF_ACTION;
+ index += uint32_encode(uid, &p_encoded_data[index]);
+ p_encoded_data[index++] = (uint8_t)action_id;
+
+ return index;
+}
+
+ret_code_t nrf_ancs_perform_notif_action(ble_ancs_c_t * p_ancs, uint32_t uid, ble_ancs_c_action_id_values_t action_id)
+{
+ VERIFY_PARAM_NOT_NULL(p_ancs);
+
+ tx_message_t msg;
+ memset(&msg, 0, sizeof(tx_message_t));
+
+ uint16_t len = encode_notif_action(msg.req.write_req.gattc_value, uid, action_id);
+
+ msg.req.write_req.gattc_params.handle = p_ancs->service.control_point_char.handle_value;
+ msg.req.write_req.gattc_params.p_value = msg.req.write_req.gattc_value;
+ msg.req.write_req.gattc_params.offset = 0;
+ msg.req.write_req.gattc_params.write_op = BLE_GATT_OP_WRITE_REQ;
+
+ msg.req.write_req.gattc_params.len = len;
+ msg.conn_handle = p_ancs->conn_handle;
+ msg.type = WRITE_REQ;
+
+ tx_buffer_insert(&msg);
+ tx_buffer_process();
+
+ return NRF_SUCCESS;
+}
+
+ret_code_t nrf_ble_ancs_c_handles_assign(ble_ancs_c_t * p_ancs,
+ uint16_t const conn_handle,
+ ble_ancs_c_service_t const * p_peer_handles)
+{
+ VERIFY_PARAM_NOT_NULL(p_ancs);
+
+ p_ancs->conn_handle = conn_handle;
+
+ if (p_peer_handles != NULL)
+ {
+ p_ancs->service.control_point_char.handle_value = p_peer_handles->control_point_char.handle_value;
+ p_ancs->service.data_source_cccd.handle = p_peer_handles->data_source_cccd.handle;
+ p_ancs->service.data_source_char.handle_value = p_peer_handles->data_source_char.handle_value;
+ p_ancs->service.notif_source_cccd.handle = p_peer_handles->notif_source_cccd.handle;
+ p_ancs->service.notif_source_char.handle_value = p_peer_handles->notif_source_char.handle_value;
+ }
+
+ return NRF_SUCCESS;
+}
+
+#endif// NRF_MODULE_ENABLED(BLE_ANCS_C)
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/ble_ancs_c/nrf_ble_ancs_c.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/ble_ancs_c/nrf_ble_ancs_c.h
new file mode 100644
index 0000000..550583e
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/ble_ancs_c/nrf_ble_ancs_c.h
@@ -0,0 +1,604 @@
+/**
+ * Copyright (c) 2012 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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
+ *
+ * @defgroup ble_ancs_c Apple Notification Service client
+ * @{
+ * @ingroup ble_sdk_srv
+ *
+ * @brief Apple Notification Center Service Client Module.
+ *
+ * @details Disclaimer: This client implementation of the Apple Notification Center Service can
+ * be changed at any time by Nordic Semiconductor ASA. Server implementations such as the
+ * ones found in iOS can be changed at any time by Apple and may cause this client
+ * implementation to stop working.
+ *
+ * This module implements the Apple Notification Center Service (ANCS) client.
+ * This client can be used as a Notification Consumer (NC) that receives data
+ * notifications from a Notification Provider (NP). The NP is typically an iOS
+ * device acting as a server. For terminology and up-to-date specs, see
+ * http://developer.apple.com.
+ *
+ * The term "notification" is used in two different meanings:
+ * - An <i>iOS notification</i> is the data received from the Notification Provider.
+ * - A <i>GATTC notification</i> is a way to transfer data with <i>Bluetooth</i> Smart.
+ * In this module, we receive iOS notifications using GATTC notifications.
+ * We use the full term (iOS notification or GATTC notification) where required to avoid confusion.
+ *
+ * Upon initializing the module, you must add the different iOS notification attributes you
+ * would like to receive for iOS notifications (see @ref nrf_ble_ancs_c_attr_add).
+ *
+ * Once a connection is established with a central device, the module does a service discovery to
+ * discover the ANCS server handles. If this succeeds (@ref BLE_ANCS_C_EVT_DISCOVERY_COMPLETE),
+ * the handles for the ANCS server are part of the @ref ble_ancs_c_evt_t structure and must be
+ * assigned to an ANCS_C instance using the @ref nrf_ble_ancs_c_handles_assign function. For more
+ * information about service discovery, see the @ref lib_ble_db_discovery documentation.
+ *
+ * The application can now subscribe to iOS notifications using
+ * @ref ble_ancs_c_notif_source_notif_enable. They arrive in the @ref BLE_ANCS_C_EVT_NOTIF event.
+ * @ref nrf_ble_ancs_c_request_attrs can be used to request attributes for the notifications. They
+ * arrive in the @ref BLE_ANCS_C_EVT_NOTIF_ATTRIBUTE event.
+ * @ref nrf_ble_ancs_c_app_attr_request can be used to request attributes of the app that issued
+ * the notifications. They arrive in the @ref BLE_ANCS_C_EVT_APP_ATTRIBUTE event.
+ * @ref nrf_ancs_perform_notif_action can be used to make the Notification Provider perform an
+ * action based on the provided notification.
+ *
+ * @msc
+ * hscale = "1.5";
+ * Application, ANCS_C;
+ * |||;
+ * Application=>ANCS_C [label = "ble_ancs_c_attr_add(attribute)"];
+ * Application=>ANCS_C [label = "ble_ancs_c_init(ancs_instance, event_handler)"];
+ * ...;
+ * Application<<=ANCS_C [label = "BLE_ANCS_C_EVT_DISCOVERY_COMPLETE"];
+ * Application=>ANCS_C [label = "ble_ancs_c_handles_assign(ancs_instance, conn_handle, service_handles)"];
+ * Application=>ANCS_C [label = "ble_ancs_c_notif_source_notif_enable(ancs_instance)"];
+ * Application=>ANCS_C [label = "ble_ancs_c_data_source_notif_enable(ancs_instance)"];
+ * |||;
+ * ...;
+ * |||;
+ * Application<<=ANCS_C [label = "BLE_ANCS_C_EVT_NOTIF"];
+ * |||;
+ * ...;
+ * |||;
+ * Application=>ANCS_C [label = "ble_ancs_c_request_attrs(attr_id, buffer)"];
+ * Application<<=ANCS_C [label = "BLE_ANCS_C_EVT_NOTIF_ATTRIBUTE"];
+ * |||;
+ * @endmsc
+ *
+ * @note The application must register this module as BLE event observer using the
+ * NRF_SDH_BLE_OBSERVER macro. Example:
+ * @code
+ * ble_ancs_c_t instance;
+ * NRF_SDH_BLE_OBSERVER(anything, BLE_ANCS_C_BLE_OBSERVER_PRIO,
+ * ble_ancs_c_on_ble_evt, &instance);
+ * @endcode
+ */
+#ifndef BLE_ANCS_C_H__
+#define BLE_ANCS_C_H__
+
+#include "ble_types.h"
+#include "ble_srv_common.h"
+#include "sdk_errors.h"
+#include "ble_db_discovery.h"
+#include "nrf_sdh_ble.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**@brief Macro for defining a ble_ancs_c instance.
+ *
+ * @param _name Name of the instance.
+ * @hideinitializer
+ */
+#define BLE_ANCS_C_DEF(_name) \
+static ble_ancs_c_t _name; \
+NRF_SDH_BLE_OBSERVER(_name ## _obs, \
+ BLE_ANCS_C_BLE_OBSERVER_PRIO, \
+ ble_ancs_c_on_ble_evt, &_name)
+
+/** @brief Macro for defining multiple ble_ancs_c instances.
+ *
+ * @param _name Name of the array of instances.
+ * @param _cnt Number of instances to define.
+ * @hideinitializer
+ */
+#define BLE_ANCS_C_ARRAY_DEF(_name, _cnt) \
+sstatic ble_ancs_c_t _name[_cnt]; \
+NRF_SDH_BLE_OBSERVERS(_name ## _obs, \
+ BLE_ANCS_C_BLE_OBSERVER_PRIO, \
+ ble_ancs_c_on_ble_evt, &_name, _cnt)
+
+#define BLE_ANCS_ATTR_DATA_MAX 32 //!< Maximum data length of an iOS notification attribute.
+#define BLE_ANCS_NB_OF_CATEGORY_ID 12 //!< Number of iOS notification categories: Other, Incoming Call, Missed Call, Voice Mail, Social, Schedule, Email, News, Health And Fitness, Business And Finance, Location, Entertainment.
+#define BLE_ANCS_NB_OF_NOTIF_ATTR 8 //!< Number of iOS notification attributes: AppIdentifier, Title, Subtitle, Message, MessageSize, Date, PositiveActionLabel, NegativeActionLabel.
+#define BLE_ANCS_NB_OF_APP_ATTR 1 //!< Number of iOS application attributes: DisplayName.
+#define BLE_ANCS_NB_OF_EVT_ID 3 //!< Number of iOS notification events: Added, Modified, Removed.
+
+/** @brief Length of the iOS notification data.
+ *
+ * @details 8 bytes:
+ * Event ID |Event flags |Category ID |Category count|Notification UID
+ * ---------|------------|------------|--------------|----------------
+ * 1 byte | 1 byte | 1 byte | 1 byte | 4 bytes
+ */
+#define BLE_ANCS_NOTIFICATION_DATA_LENGTH 8
+
+#define ANCS_UUID_SERVICE 0xF431 //!< 16-bit service UUID for the Apple Notification Center Service.
+#define ANCS_UUID_CHAR_CONTROL_POINT 0xD8F3 //!< 16-bit control point UUID.
+#define ANCS_UUID_CHAR_DATA_SOURCE 0xC6E9 //!< 16-bit data source UUID.
+#define ANCS_UUID_CHAR_NOTIFICATION_SOURCE 0x120D //!< 16-bit notification source UUID.
+
+#define BLE_ANCS_EVENT_FLAG_SILENT 0 //!< 0b.......1 Silent: First (LSB) bit is set. All flags can be active at the same time.
+#define BLE_ANCS_EVENT_FLAG_IMPORTANT 1 //!< 0b......1. Important: Second (LSB) bit is set. All flags can be active at the same time.
+#define BLE_ANCS_EVENT_FLAG_PREEXISTING 2 //!< 0b.....1.. Pre-existing: Third (LSB) bit is set. All flags can be active at the same time.
+#define BLE_ANCS_EVENT_FLAG_POSITIVE_ACTION 3 //!< 0b....1... Positive action: Fourth (LSB) bit is set. All flags can be active at the same time.
+#define BLE_ANCS_EVENT_FLAG_NEGATIVE_ACTION 4 //!< 0b...1.... Negative action: Fifth (LSB) bit is set. All flags can be active at the same time.
+
+/** @defgroup BLE_ANCS_NP_ERROR_CODES Notification Provider (iOS) Error Codes
+ * @{ */
+#define BLE_ANCS_NP_UNKNOWN_COMMAND 0x01A0 //!< The command ID is unknown to the NP.
+#define BLE_ANCS_NP_INVALID_COMMAND 0x01A1 //!< The command format is invalid.
+#define BLE_ANCS_NP_INVALID_PARAMETER 0x01A2 //!< One or more parameters does not exist in the NP.
+#define BLE_ANCS_NP_ACTION_FAILED 0x01A3 //!< The action failed to be performed by the NP.
+/** @} */
+
+
+/**@brief Event types that are passed from client to application on an event. */
+typedef enum
+{
+ BLE_ANCS_C_EVT_DISCOVERY_COMPLETE, /**< A successful connection has been established and the service was found on the connected peer. */
+ BLE_ANCS_C_EVT_DISCOVERY_FAILED, /**< It was not possible to discover the service or characteristics of the connected peer. */
+ BLE_ANCS_C_EVT_NOTIF, /**< An iOS notification was received on the notification source control point. */
+ BLE_ANCS_C_EVT_INVALID_NOTIF, /**< An iOS notification was received on the notification source control point, but the format is invalid. */
+ BLE_ANCS_C_EVT_NOTIF_ATTRIBUTE, /**< A received iOS notification attribute has been parsed. */
+ BLE_ANCS_C_EVT_APP_ATTRIBUTE, /**< An iOS app attribute has been parsed. */
+ BLE_ANCS_C_EVT_NP_ERROR, /**< An error has been sent on the ANCS Control Point from the iOS Notification Provider. */
+} ble_ancs_c_evt_type_t;
+
+/**@brief Category IDs for iOS notifications. */
+typedef enum
+{
+ BLE_ANCS_CATEGORY_ID_OTHER, /**< The iOS notification belongs to the "other" category. */
+ BLE_ANCS_CATEGORY_ID_INCOMING_CALL, /**< The iOS notification belongs to the "Incoming Call" category. */
+ BLE_ANCS_CATEGORY_ID_MISSED_CALL, /**< The iOS notification belongs to the "Missed Call" category. */
+ BLE_ANCS_CATEGORY_ID_VOICE_MAIL, /**< The iOS notification belongs to the "Voice Mail" category. */
+ BLE_ANCS_CATEGORY_ID_SOCIAL, /**< The iOS notification belongs to the "Social" category. */
+ BLE_ANCS_CATEGORY_ID_SCHEDULE, /**< The iOS notification belongs to the "Schedule" category. */
+ BLE_ANCS_CATEGORY_ID_EMAIL, /**< The iOS notification belongs to the "E-mail" category. */
+ BLE_ANCS_CATEGORY_ID_NEWS, /**< The iOS notification belongs to the "News" category. */
+ BLE_ANCS_CATEGORY_ID_HEALTH_AND_FITNESS, /**< The iOS notification belongs to the "Health and Fitness" category. */
+ BLE_ANCS_CATEGORY_ID_BUSINESS_AND_FINANCE, /**< The iOS notification belongs to the "Buisness and Finance" category. */
+ BLE_ANCS_CATEGORY_ID_LOCATION, /**< The iOS notification belongs to the "Location" category. */
+ BLE_ANCS_CATEGORY_ID_ENTERTAINMENT /**< The iOS notification belongs to the "Entertainment" category. */
+} ble_ancs_c_category_id_val_t;
+
+/**@brief Event IDs for iOS notifications. */
+typedef enum
+{
+ BLE_ANCS_EVENT_ID_NOTIFICATION_ADDED, /**< The iOS notification was added. */
+ BLE_ANCS_EVENT_ID_NOTIFICATION_MODIFIED, /**< The iOS notification was modified. */
+ BLE_ANCS_EVENT_ID_NOTIFICATION_REMOVED /**< The iOS notification was removed. */
+} ble_ancs_c_evt_id_values_t;
+
+/**@brief Control point command IDs that the Notification Consumer can send to the Notification Provider. */
+typedef enum
+{
+ BLE_ANCS_COMMAND_ID_GET_NOTIF_ATTRIBUTES, /**< Requests attributes to be sent from the NP to the NC for a given notification. */
+ BLE_ANCS_COMMAND_ID_GET_APP_ATTRIBUTES, /**< Requests attributes to be sent from the NP to the NC for a given iOS app. */
+ BLE_ANCS_COMMAND_ID_GET_PERFORM_NOTIF_ACTION, /**< Requests an action to be performed on a given notification, for example, dismiss an alarm. */
+} ble_ancs_c_cmd_id_val_t;
+
+/**@brief IDs for actions that can be performed for iOS notifications. */
+typedef enum
+{
+ ACTION_ID_POSITIVE = 0, /**< Positive action. */
+ ACTION_ID_NEGATIVE /**< Negative action. */
+} ble_ancs_c_action_id_values_t;
+
+/**@brief App attribute ID values.
+ * @details Currently, only one value is defined. However, the number of app
+ * attributes might increase. Therefore, they are stored in an enumeration.
+ */
+typedef enum
+{
+ BLE_ANCS_APP_ATTR_ID_DISPLAY_NAME = 0 /**< Command used to get the display name for an app identifier. */
+} ble_ancs_c_app_attr_id_val_t;
+
+/**@brief IDs for iOS notification attributes. */
+typedef enum
+{
+ BLE_ANCS_NOTIF_ATTR_ID_APP_IDENTIFIER = 0, /**< Identifies that the attribute data is of an "App Identifier" type. */
+ BLE_ANCS_NOTIF_ATTR_ID_TITLE, /**< Identifies that the attribute data is a "Title". */
+ BLE_ANCS_NOTIF_ATTR_ID_SUBTITLE, /**< Identifies that the attribute data is a "Subtitle". */
+ BLE_ANCS_NOTIF_ATTR_ID_MESSAGE, /**< Identifies that the attribute data is a "Message". */
+ BLE_ANCS_NOTIF_ATTR_ID_MESSAGE_SIZE, /**< Identifies that the attribute data is a "Message Size". */
+ BLE_ANCS_NOTIF_ATTR_ID_DATE, /**< Identifies that the attribute data is a "Date". */
+ BLE_ANCS_NOTIF_ATTR_ID_POSITIVE_ACTION_LABEL, /**< The notification has a "Positive action" that can be executed associated with it. */
+ BLE_ANCS_NOTIF_ATTR_ID_NEGATIVE_ACTION_LABEL, /**< The notification has a "Negative action" that can be executed associated with it. */
+} ble_ancs_c_notif_attr_id_val_t;
+
+/**@brief Flags for iOS notifications. */
+typedef struct
+{
+ uint8_t silent : 1; //!< If this flag is set, the notification has a low priority.
+ uint8_t important : 1; //!< If this flag is set, the notification has a high priority.
+ uint8_t pre_existing : 1; //!< If this flag is set, the notification is pre-existing.
+ uint8_t positive_action : 1; //!< If this flag is set, the notification has a positive action that can be taken.
+ uint8_t negative_action : 1; //!< If this flag is set, the notification has a negative action that can be taken.
+} ble_ancs_c_notif_flags_t;
+
+/**@brief Parsing states for received iOS notification and app attributes. */
+typedef enum
+{
+ COMMAND_ID, /**< Parsing the command ID. */
+ NOTIF_UID, /**< Parsing the notification UID. */
+ APP_ID, /**< Parsing app ID. */
+ ATTR_ID, /**< Parsing attribute ID. */
+ ATTR_LEN1, /**< Parsing the LSB of the attribute length. */
+ ATTR_LEN2, /**< Parsing the MSB of the attribute length. */
+ ATTR_DATA, /**< Parsing the attribute data. */
+ ATTR_SKIP, /**< Parsing is skipped for the rest (or entire) of an attribute. */
+ DONE, /**< Parsing for one attribute is done. */
+} ble_ancs_c_parse_state_t;
+
+/**@brief iOS notification structure. */
+typedef struct
+{
+ uint32_t notif_uid; //!< Notification UID.
+ ble_ancs_c_evt_id_values_t evt_id; //!< Whether the notification was added, removed, or modified.
+ ble_ancs_c_notif_flags_t evt_flags; //!< Bitmask to signal if a special condition applies to the notification, for example, "Silent" or "Important".
+ ble_ancs_c_category_id_val_t category_id; //!< Classification of the notification type, for example, email or location.
+ uint8_t category_count; //!< Current number of active notifications for this category ID.
+} ble_ancs_c_evt_notif_t;
+
+/**@brief iOS attribute structure. This type is used for both notification attributes and app attributes. */
+typedef struct
+{
+ uint16_t attr_len; //!< Length of the received attribute data.
+ uint32_t attr_id; //!< Classification of the attribute type, for example, title or date.
+ uint8_t * p_attr_data; //!< Pointer to where the memory is allocated for storing incoming attributes.
+} ble_ancs_c_attr_t;
+
+/**@brief iOS notification attribute structure for incoming attributes. */
+typedef struct
+{
+ uint32_t notif_uid; //!< UID of the notification that the attribute belongs to.
+ ble_ancs_c_attr_t attrs; //!< A received attribute.
+} ble_ancs_c_evt_attr_t;
+
+typedef struct
+{
+ uint16_t attr_len; //!< Length of the received attribute data.
+ uint32_t attr_id; //!< Classification of the attribute type, for example, title or date.
+ uint8_t * p_attr_data; //!< Pointer to where the memory is allocated for storing incoming attributes.
+} ble_ancs_c_evt_app_attr_t;
+
+/**@brief iOS notification attribute content wanted by our application. */
+typedef struct
+{
+ bool get; //!< Boolean to determine if this attribute will be requested from the Notification Provider.
+ uint32_t attr_id; //!< Attribute ID: AppIdentifier(0), Title(1), Subtitle(2), Message(3), MessageSize(4), Date(5), PositiveActionLabel(6), NegativeActionLabel(7).
+ uint16_t attr_len; //!< Length of the attribute. If more data is received from the Notification Provider, all data beyond this length is discarded.
+ uint8_t * p_attr_data; //!< Pointer to where the memory is allocated for storing incoming attributes.
+} ble_ancs_c_attr_list_t;
+
+/**@brief Structure used for holding the Apple Notification Center Service found during the
+ discovery process.
+ */
+typedef struct
+{
+ ble_gattc_service_t service; //!< The GATT Service holding the discovered Apple Notification Center Service. (0xF431).
+ ble_gattc_char_t control_point_char; //!< ANCS Control Point Characteristic. Allows interaction with the peer (0xD8F3).
+ ble_gattc_char_t notif_source_char; //!< ANCS Notification Source Characteristic. Keeps track of arrival, modification, and removal of notifications (0x120D).
+ ble_gattc_desc_t notif_source_cccd; //!< ANCS Notification Source Characteristic Descriptor. Enables or disables GATT notifications.
+ ble_gattc_char_t data_source_char; //!< ANCS Data Source Characteristic, where attribute data for the notifications is received from peer (0xC6E9).
+ ble_gattc_desc_t data_source_cccd; //!< ANCS Data Source Characteristic Descriptor. Enables or disables GATT notifications.
+} ble_ancs_c_service_t;
+
+/**@brief ANCS client module event structure.
+ *
+ * @details The structure contains the event that should be handled by the main application.
+ */
+typedef struct
+{
+ ble_ancs_c_evt_type_t evt_type; //!< Type of event.
+ uint16_t conn_handle; //!< Connection handle on which the ANCS service was discovered on the peer device. This field will be filled if the @p evt_type is @ref BLE_ANCS_C_EVT_DISCOVERY_COMPLETE.
+ ble_ancs_c_evt_notif_t notif; //!< iOS notification. This field will be filled if @p evt_type is @ref BLE_ANCS_C_EVT_NOTIF.
+ uint16_t err_code_np; //!< An error coming from the Notification Provider. This field will be filled with @ref BLE_ANCS_NP_ERROR_CODES if @p evt_type is @ref BLE_ANCS_C_EVT_NP_ERROR.
+ ble_ancs_c_attr_t attr; //!< iOS notification attribute or app attribute, depending on the event type.
+ uint32_t notif_uid; //!< Notification UID.
+ uint8_t app_id[BLE_ANCS_ATTR_DATA_MAX]; //!< App identifier.
+ ble_ancs_c_service_t service; //!< Information on the discovered Alert Notification Service. This field will be filled if the @p evt_type is @ref BLE_ANCS_C_EVT_DISCOVERY_COMPLETE.
+} ble_ancs_c_evt_t;
+
+/**@brief iOS notification event handler type. */
+typedef void (*ble_ancs_c_evt_handler_t) (ble_ancs_c_evt_t * p_evt);
+
+typedef struct
+{
+ ble_ancs_c_attr_list_t * p_attr_list; //!< The current list of attributes being parsed. This field will point to either @ref ble_ancs_c_t::ancs_notif_attr_list or @ref ble_ancs_c_t::ancs_app_attr_list.
+ uint32_t nb_of_attr; //!< Number of possible attributes. When parsing begins, it is set to either @ref BLE_ANCS_NB_OF_NOTIF_ATTR or @ref BLE_ANCS_NB_OF_APP_ATTR.
+ uint32_t expected_number_of_attrs; //!< The number of attributes expected upon receiving attributes. Keeps track of when to stop reading incoming attributes.
+ ble_ancs_c_parse_state_t parse_state; //!< ANCS notification attribute parsing state.
+ ble_ancs_c_cmd_id_val_t command_id; //!< Variable to keep track of what command type we are currently parsing ( @ref BLE_ANCS_COMMAND_ID_GET_NOTIF_ATTRIBUTES or @ref BLE_ANCS_COMMAND_ID_GET_APP_ATTRIBUTES.
+ uint8_t * p_data_dest; //!< Attribute that the parsed data will be copied into.
+ uint16_t current_attr_index; //!< Variable to keep track of how much (for a given attribute) we are done parsing.
+ uint32_t current_app_id_index; //!< Variable to keep track of how much (for a given app identifier) we are done parsing.
+} ble_ancs_parse_sm_t;
+
+/**@brief iOS notification structure, which contains various status information for the client. */
+typedef struct
+{
+ ble_ancs_c_evt_handler_t evt_handler; //!< Event handler to be called for handling events in the Apple Notification client application.
+ ble_srv_error_handler_t error_handler; //!< Function to be called in case of an error.
+ uint16_t conn_handle; //!< Handle of the current connection. Set with @ref nrf_ble_ancs_c_handles_assign when connected.
+ ble_ancs_c_service_t service; //!< Structure to store the different handles and UUIDs related to the service.
+ ble_ancs_c_attr_list_t ancs_notif_attr_list[BLE_ANCS_NB_OF_NOTIF_ATTR]; //!< For all attributes; contains whether they should be requested upon attribute request and the length and buffer of where to store attribute data.
+ ble_ancs_c_attr_list_t ancs_app_attr_list[BLE_ANCS_NB_OF_APP_ATTR]; //!< For all app attributes; contains whether they should be requested upon attribute request and the length and buffer of where to store attribute data.
+ uint32_t number_of_requested_attr; //!< The number of attributes that will be requested when an iOS notification attribute request is made.
+ ble_ancs_parse_sm_t parse_info; //!< Structure containing different information used to parse incoming attributes (from data_source characteristic) correctly.
+ ble_ancs_c_evt_t evt; //!< The event is filled with several iterations of the @ref ancs_parse_get_attrs_response function when requesting iOS notification attributes. So we must allocate memory for it here.
+} ble_ancs_c_t;
+
+/**@brief Apple Notification client init structure, which contains all options and data needed for
+ * initialization of the client. */
+typedef struct
+{
+ ble_ancs_c_evt_handler_t evt_handler; //!< Event handler to be called for handling events in the Battery Service.
+ ble_srv_error_handler_t error_handler; //!< Function to be called in case of an error.
+} ble_ancs_c_init_t;
+
+
+/**@brief Apple Notification Center Service UUIDs. */
+extern const ble_uuid128_t ble_ancs_base_uuid128; //!< Service UUID.
+extern const ble_uuid128_t ble_ancs_cp_base_uuid128; //!< Control point UUID.
+extern const ble_uuid128_t ble_ancs_ns_base_uuid128; //!< Notification source UUID.
+extern const ble_uuid128_t ble_ancs_ds_base_uuid128; //!< Data source UUID.
+
+
+/**@brief Function for handling the application's BLE stack events.
+ *
+ * @details Handles all events from the BLE stack that are of interest to the ANCS client.
+ *
+ * @param[in] p_ble_evt Event received from the BLE stack.
+ * @param[in] p_context ANCS client structure.
+ */
+void ble_ancs_c_on_ble_evt(ble_evt_t const * p_ble_evt, void * p_context);
+
+
+/**@brief Function for handling events from the database discovery module.
+ *
+ * @details This function will handle an event from the database discovery module and determine
+ * if it relates to the discovery of ANCS at the peer. If so, it will
+ * call the application's event handler indicating that ANCS has been
+ * discovered at the peer. It also populates the event with the service related
+ * information before providing it to the application.
+ *
+ * @param[in] p_ancs Pointer to the ANCS client structure.
+ * @param[in] p_evt Pointer to the event received from the database discovery module.
+ */
+ void ble_ancs_c_on_db_disc_evt(ble_ancs_c_t * p_ancs, ble_db_discovery_evt_t * p_evt);
+
+
+/**@brief Function for initializing the ANCS client.
+ *
+ * @param[out] p_ancs ANCS client structure. This structure must be
+ * supplied by the application. It is initialized by this function
+ * and will later be used to identify this particular client instance.
+ * @param[in] p_ancs_init Information needed to initialize the client.
+ *
+ * @retval NRF_SUCCESS If the client was initialized successfully. Otherwise, an error code is returned.
+ */
+ret_code_t ble_ancs_c_init(ble_ancs_c_t * p_ancs, ble_ancs_c_init_t const * p_ancs_init);
+
+
+/**@brief Function for writing to the CCCD to enable notifications from the Apple Notification Service.
+ *
+ * @param[in] p_ancs iOS notification structure. This structure must be supplied by
+ * the application. It identifies the particular client instance to use.
+ *
+ * @retval NRF_SUCCESS If writing to the CCCD was successful. Otherwise, an error code is returned.
+ */
+ret_code_t ble_ancs_c_notif_source_notif_enable(ble_ancs_c_t const * p_ancs);
+
+
+/**@brief Function for writing to the CCCD to enable data source notifications from the ANCS.
+ *
+ * @param[in] p_ancs iOS notification structure. This structure must be supplied by
+ * the application. It identifies the particular client instance to use.
+ *
+ * @retval NRF_SUCCESS If writing to the CCCD was successful. Otherwise, an error code is returned.
+ */
+ret_code_t ble_ancs_c_data_source_notif_enable(ble_ancs_c_t const * p_ancs);
+
+
+/**@brief Function for writing to the CCCD to disable notifications from the ANCS.
+ *
+ * @param[in] p_ancs iOS notification structure. This structure must be supplied by
+ * the application. It identifies the particular client instance to use.
+ *
+ * @retval NRF_SUCCESS If writing to the CCCD was successful. Otherwise, an error code is returned.
+ */
+ret_code_t ble_ancs_c_notif_source_notif_disable(ble_ancs_c_t const * p_ancs);
+
+
+/**@brief Function for writing to the CCCD to disable data source notifications from the ANCS.
+ *
+ * @param[in] p_ancs iOS notification structure. This structure must be supplied by
+ * the application. It identifies the particular client instance to use.
+ *
+ * @retval NRF_SUCCESS If writing to the CCCD was successful. Otherwise, an error code is returned.
+ */
+ret_code_t ble_ancs_c_data_source_notif_disable(ble_ancs_c_t const * p_ancs);
+
+
+/**@brief Function for registering attributes that will be requested when @ref nrf_ble_ancs_c_request_attrs
+ * is called.
+ *
+ * @param[in] p_ancs ANCS client instance on which the attribute will be registered.
+ * @param[in] id ID of the attribute that will be added.
+ * @param[in] p_data Pointer to a buffer where the data of the attribute can be stored.
+ * @param[in] len Length of the buffer where the data of the attribute can be stored.
+
+ * @retval NRF_SUCCESS If all operations were successful. Otherwise, an error code is returned.
+ */
+ret_code_t nrf_ble_ancs_c_attr_add(ble_ancs_c_t * p_ancs,
+ ble_ancs_c_notif_attr_id_val_t const id,
+ uint8_t * p_data,
+ uint16_t const len);
+
+
+/**@brief Function for removing attributes so that they will no longer be requested when
+ * @ref nrf_ble_ancs_c_request_attrs is called.
+ *
+ * @param[in] p_ancs ANCS client instance on which the attribute will be removed.
+ * @param[in] id ID of the attribute that will be removed.
+ *
+ * @retval NRF_SUCCESS If all operations were successful. Otherwise, an error code is returned.
+ */
+ret_code_t nrf_ble_ancs_c_attr_remove(ble_ancs_c_t * p_ancs,
+ ble_ancs_c_notif_attr_id_val_t const id);
+
+/**@brief Function for removing attributes so that they will no longer be requested when
+ * @ref nrf_ble_ancs_c_app_attr_request is called.
+ *
+ * @param[in] p_ancs ANCS client instance on which the attribute will be removed.
+ * @param[in] id ID of the attribute that will be removed.
+ *
+ * @retval NRF_SUCCESS If all operations were successful. Otherwise, an error code is returned.
+ */
+ret_code_t nrf_ble_ancs_c_app_attr_remove(ble_ancs_c_t * p_ancs,
+ ble_ancs_c_app_attr_id_val_t const id);
+
+
+/**@brief Function for registering attributes that will be requested when @ref nrf_ble_ancs_c_app_attr_request
+ * is called.
+ *
+ * @param[in] p_ancs ANCS client instance on which the attribute will be registered.
+ * @param[in] id ID of the attribute that will be added.
+ * @param[in] p_data Pointer to a buffer where the data of the attribute can be stored.
+ * @param[in] len Length of the buffer where the data of the attribute can be stored.
+ *
+ * @retval NRF_SUCCESS If all operations were successful. Otherwise, an error code is returned.
+ */
+ret_code_t nrf_ble_ancs_c_app_attr_add(ble_ancs_c_t * p_ancs,
+ ble_ancs_c_app_attr_id_val_t const id,
+ uint8_t * p_data,
+ uint16_t const len);
+
+/**@brief Function for clearing the list of notification attributes and app attributes that
+ * would be requested from NP.
+ *
+ * @param[in] p_ancs iOS notification structure. This structure must be supplied by
+ * the application. It identifies the particular client instance to use.
+**/
+ret_code_t nrf_ble_ancs_c_attr_req_clear_all(ble_ancs_c_t * p_ancs);
+
+/**@brief Function for requesting attributes for a notification.
+ *
+ * @param[in] p_ancs iOS notification structure. This structure must be supplied by
+ * the application. It identifies the particular client instance to use.
+ * @param[in] p_notif Pointer to the notification whose attributes will be requested from
+ * the Notification Provider.
+ *
+ * @retval NRF_SUCCESS If all operations were successful. Otherwise, an error code is returned.
+ */
+ret_code_t nrf_ble_ancs_c_request_attrs(ble_ancs_c_t * p_ancs,
+ ble_ancs_c_evt_notif_t const * p_notif);
+
+/**@brief Function for requesting attributes for a given app.
+ *
+ * @param[in] p_ancs iOS notification structure. This structure must be supplied by
+ * the application. It identifies the particular client instance to use.
+ * @param[in] p_app_id App identifier of the app for which the app attributes are requested.
+ * @param[in] len Length of the app identifier.
+ *
+ * @retval NRF_SUCCESS If all operations were successful. Otherwise, an error code is returned.
+ */
+ret_code_t nrf_ble_ancs_c_app_attr_request(ble_ancs_c_t * p_ancs,
+ uint8_t const * p_app_id,
+ uint32_t len);
+
+
+/**@brief Function for performing a notification action.
+ *
+ * @param[in] p_ancs iOS notification structure. This structure must be supplied by
+ * the application. It identifies the particular client instance to use.
+ * @param[in] uuid The UUID of the notification for which to perform the action.
+ * @param[in] action_id Perform a positive or negative action.
+ *
+ * @retval NRF_SUCCESS If the operation was successful.
+ * @retval NRF_ERROR_NULL If @p p_ancs was a NULL pointer.
+ */
+ret_code_t nrf_ancs_perform_notif_action(ble_ancs_c_t * p_ancs,
+ uint32_t uuid,
+ ble_ancs_c_action_id_values_t action_id);
+
+/**@brief Function for assigning a handle to this instance of ancs_c.
+ *
+ * @details Call this function when a link has been established with a peer to
+ * associate this link to this instance of the module. This makes it
+ * possible to handle several link and associate each link to a particular
+ * instance of this module. The connection handle and attribute handles will be
+ * provided from the discovery event @ref BLE_ANCS_C_EVT_DISCOVERY_COMPLETE.
+ *
+ * @param[in] p_ancs Pointer to the ANCS client structure instance to associate with these
+ * handles.
+ * @param[in] conn_handle Connection handle to associate with the given ANCS instance.
+ * @param[in] p_service Attribute handles on the ANCS server that you want this ANCS client to
+ * interact with.
+ *
+ * @retval NRF_SUCCESS If the operation was successful.
+ * @retval NRF_ERROR_NULL If @p p_ancs was a NULL pointer.
+ */
+ret_code_t nrf_ble_ancs_c_handles_assign(ble_ancs_c_t * p_ancs,
+ uint16_t const conn_handle,
+ ble_ancs_c_service_t const * p_service);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // BLE_ANCS_C_H__
+
+/** @} */
+
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/ble_ans_c/ble_ans_c.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/ble_ans_c/ble_ans_c.c
new file mode 100644
index 0000000..9fc8ad6
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/ble_ans_c/ble_ans_c.c
@@ -0,0 +1,575 @@
+/**
+ * Copyright (c) 2012 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+/* Attention!
+ * To maintain compliance with Nordic Semiconductor ASA's Bluetooth profile
+ * qualification listings, this section of source code must not be modified.
+ */
+#include "sdk_common.h"
+#if NRF_MODULE_ENABLED(BLE_ANS_C)
+#include "ble_ans_c.h"
+#include <string.h>
+#include <stdbool.h>
+#include "ble_err.h"
+#include "nrf_assert.h"
+#include "ble_db_discovery.h"
+#define NRF_LOG_MODULE_NAME ble_ans_c
+#include "nrf_log.h"
+NRF_LOG_MODULE_REGISTER();
+
+#define NOTIFICATION_DATA_LENGTH 2 /**< The mandatory length of notification data. After the mandatory data, the optional message is located. */
+#define READ_DATA_LENGTH_MIN 1 /**< Minimum data length in a valid Alert Notification Read Response message. */
+
+#define TX_BUFFER_MASK 0x07 /**< TX Buffer mask, must be a mask of contiguous zeroes, followed by contiguous sequence of ones: 000...111. */
+#define TX_BUFFER_SIZE (TX_BUFFER_MASK + 1) /**< Size of send buffer, which is 1 higher than the mask. */
+#define WRITE_MESSAGE_LENGTH 2 /**< Length of the write message for CCCD/control point. */
+
+
+typedef enum
+{
+ READ_REQ = 1, /**< Type identifying that this tx_message is a read request. */
+ WRITE_REQ /**< Type identifying that this tx_message is a write request. */
+} ans_tx_request_t;
+
+
+/**@brief Structure for writing a message to the central, i.e. Control Point or CCCD.
+ */
+typedef struct
+{
+ uint8_t gattc_value[WRITE_MESSAGE_LENGTH]; /**< The message to write. */
+ ble_gattc_write_params_t gattc_params; /**< GATTC parameters for this message. */
+} ans_write_params_t;
+
+/**@brief Structure for holding data to be transmitted to the connected central.
+ */
+typedef struct
+{
+ uint16_t conn_handle; /**< Connection handle to be used when transmitting this message. */
+ ans_tx_request_t type; /**< Type of this message, i.e. read or write message. */
+ union
+ {
+ uint16_t read_handle; /**< Read request message. */
+ ans_write_params_t write_req; /**< Write request message. */
+ } req;
+} ans_tx_message_t;
+
+static ans_tx_message_t m_tx_buffer[TX_BUFFER_SIZE]; /**< Transmit buffer for messages to be transmitted to the central. */
+static uint32_t m_tx_insert_index = 0; /**< Current index in the transmit buffer where next message should be inserted. */
+static uint32_t m_tx_index = 0; /**< Current index in the transmit buffer from where the next message to be transmitted resides. */
+
+
+/**@brief Function for passing any pending request from the buffer to the stack.
+ */
+static void tx_buffer_process(void)
+{
+ if (m_tx_index != m_tx_insert_index)
+ {
+ uint32_t err_code;
+
+ if (m_tx_buffer[m_tx_index].type == READ_REQ)
+ {
+ err_code = sd_ble_gattc_read(m_tx_buffer[m_tx_index].conn_handle,
+ m_tx_buffer[m_tx_index].req.read_handle,
+ 0);
+ }
+ else
+ {
+ err_code = sd_ble_gattc_write(m_tx_buffer[m_tx_index].conn_handle,
+ &m_tx_buffer[m_tx_index].req.write_req.gattc_params);
+ }
+ if (err_code == NRF_SUCCESS)
+ {
+ ++m_tx_index;
+ m_tx_index &= TX_BUFFER_MASK;
+ }
+ }
+}
+
+
+/** @brief Function for copying a characteristic.
+ */
+static void char_set(ble_gattc_char_t * p_dest_char, ble_gattc_char_t const * p_source_char)
+{
+ memcpy(p_dest_char, p_source_char, sizeof(ble_gattc_char_t));
+}
+
+static void char_cccd_set(ble_gattc_desc_t * p_cccd, uint16_t cccd_handle)
+{
+ p_cccd->handle = cccd_handle;
+}
+
+/** @brief Function to check that all handles required by the client to use the server are present.
+ */
+static bool is_valid_ans_srv_discovered(ble_ans_c_service_t const * p_srv)
+{
+ if ((p_srv->alert_notif_ctrl_point.handle_value == BLE_GATT_HANDLE_INVALID) ||
+ (p_srv->suported_new_alert_cat.handle_value == BLE_GATT_HANDLE_INVALID) ||
+ (p_srv->suported_unread_alert_cat.handle_value == BLE_GATT_HANDLE_INVALID) ||
+ (p_srv->new_alert.handle_value == BLE_GATT_HANDLE_INVALID) ||
+ (p_srv->unread_alert_status.handle_value == BLE_GATT_HANDLE_INVALID) ||
+ (p_srv->new_alert_cccd.handle == BLE_GATT_HANDLE_INVALID) ||
+ (p_srv->unread_alert_cccd.handle == BLE_GATT_HANDLE_INVALID)
+ )
+ {
+ // At least one required characteristic is missing on the server side.
+ return false;
+ }
+ return true;
+}
+
+
+void ble_ans_c_on_db_disc_evt(ble_ans_c_t * p_ans, ble_db_discovery_evt_t const * p_evt)
+{
+ ble_ans_c_evt_t evt;
+
+ memset(&evt, 0, sizeof(ble_ans_c_evt_t));
+ evt.conn_handle = p_evt->conn_handle;
+ evt.evt_type = BLE_ANS_C_EVT_DISCOVERY_FAILED;
+
+ // Check if the Alert Notification Service was discovered.
+ if (p_evt->evt_type == BLE_DB_DISCOVERY_COMPLETE
+ &&
+ p_evt->params.discovered_db.srv_uuid.uuid == BLE_UUID_ALERT_NOTIFICATION_SERVICE
+ &&
+ p_evt->params.discovered_db.srv_uuid.type == BLE_UUID_TYPE_BLE)
+ {
+ // Find the characteristics inside the service.
+ for (uint8_t i = 0; i < p_evt->params.discovered_db.char_count; i++)
+ {
+ ble_gatt_db_char_t const * p_char = &(p_evt->params.discovered_db.charateristics[i]);
+
+ switch (p_char->characteristic.uuid.uuid)
+ {
+ case BLE_UUID_ALERT_NOTIFICATION_CONTROL_POINT_CHAR:
+ NRF_LOG_DEBUG("Found Ctrlpt \r\n\r");
+ char_set(&evt.data.service.alert_notif_ctrl_point, &p_char->characteristic);
+ break;
+
+ case BLE_UUID_UNREAD_ALERT_CHAR:
+ NRF_LOG_DEBUG("Found Unread Alert \r\n\r");
+ char_set(&evt.data.service.unread_alert_status, &p_char->characteristic);
+ char_cccd_set(&evt.data.service.unread_alert_cccd,
+ p_char->cccd_handle);
+ break;
+
+ case BLE_UUID_NEW_ALERT_CHAR:
+ NRF_LOG_DEBUG("Found New Alert \r\n\r");
+ char_set(&evt.data.service.new_alert, &p_char->characteristic);
+ char_cccd_set(&evt.data.service.new_alert_cccd,
+ p_char->cccd_handle);
+ break;
+
+ case BLE_UUID_SUPPORTED_UNREAD_ALERT_CATEGORY_CHAR:
+ NRF_LOG_DEBUG("Found supported unread alert category \r\n\r");
+ char_set(&evt.data.service.suported_unread_alert_cat, &p_char->characteristic);
+ break;
+
+ case BLE_UUID_SUPPORTED_NEW_ALERT_CATEGORY_CHAR:
+ NRF_LOG_DEBUG("Found supported new alert category \r\n\r");
+ char_set(&evt.data.service.suported_new_alert_cat, &p_char->characteristic);
+ break;
+
+ default:
+ // No implementation needed.
+ break;
+ }
+ }
+ if (is_valid_ans_srv_discovered(&evt.data.service))
+ {
+ evt.evt_type = BLE_ANS_C_EVT_DISCOVERY_COMPLETE;
+ }
+ }
+ p_ans->evt_handler(&evt);
+}
+
+
+/**@brief Function for receiving and validating notifications received from the central.
+ */
+static void event_notify(ble_ans_c_t * p_ans, ble_evt_t const * p_ble_evt)
+{
+ uint32_t message_length;
+ ble_ans_c_evt_t event;
+ ble_ans_alert_notification_t * p_alert = &event.data.alert;
+ ble_gattc_evt_hvx_t const * p_notification = &p_ble_evt->evt.gattc_evt.params.hvx;
+
+ // Message is not valid -> ignore.
+ event.evt_type = BLE_ANS_C_EVT_NOTIFICATION;
+ if (p_notification->len < NOTIFICATION_DATA_LENGTH)
+ {
+ return;
+ }
+ message_length = p_notification->len - NOTIFICATION_DATA_LENGTH;
+
+ if (p_notification->handle == p_ans->service.new_alert.handle_value)
+ {
+ BLE_UUID_COPY_INST(event.uuid, p_ans->service.new_alert.uuid);
+ }
+ else if (p_notification->handle == p_ans->service.unread_alert_status.handle_value)
+ {
+ BLE_UUID_COPY_INST(event.uuid, p_ans->service.unread_alert_status.uuid);
+ }
+ else
+ {
+ // Nothing to process.
+ return;
+ }
+
+ p_alert->alert_category = p_notification->data[0];
+ p_alert->alert_category_count = p_notification->data[1]; //lint !e415
+ p_alert->alert_msg_length = (message_length > p_ans->message_buffer_size)
+ ? p_ans->message_buffer_size
+ : message_length;
+ p_alert->p_alert_msg_buf = p_ans->p_message_buffer;
+
+ memcpy(p_alert->p_alert_msg_buf,
+ &p_notification->data[NOTIFICATION_DATA_LENGTH],
+ p_alert->alert_msg_length); //lint !e416
+
+ p_ans->evt_handler(&event);
+}
+
+
+/**@brief Function for handling write response events.
+ */
+static void event_write_rsp(ble_ans_c_t * p_ans, ble_evt_t const * p_ble_evt)
+{
+ tx_buffer_process();
+}
+
+
+/**@brief Function for validating and passing the response to the application,
+ * when a read response is received.
+ */
+static void event_read_rsp(ble_ans_c_t * p_ans, ble_evt_t const * p_ble_evt)
+{
+ ble_ans_c_evt_t event;
+ ble_gattc_evt_read_rsp_t const * p_response;
+
+ p_response = &p_ble_evt->evt.gattc_evt.params.read_rsp;
+ event.evt_type = BLE_ANS_C_EVT_READ_RESP;
+
+ if (p_response->len < READ_DATA_LENGTH_MIN)
+ {
+ tx_buffer_process();
+ return;
+ }
+
+ if (p_response->handle == p_ans->service.suported_new_alert_cat.handle_value)
+ {
+ BLE_UUID_COPY_INST(event.uuid, p_ans->service.suported_new_alert_cat.uuid);
+ }
+ else if (p_response->handle == p_ans->service.suported_unread_alert_cat.handle_value)
+ {
+ BLE_UUID_COPY_INST(event.uuid, p_ans->service.suported_unread_alert_cat.uuid);
+ }
+ else
+ {
+ // Bad response, ignore.
+ tx_buffer_process();
+ return;
+ }
+
+ event.data.settings = *(ble_ans_alert_settings_t *)(p_response->data);
+
+ if (p_response->len == READ_DATA_LENGTH_MIN)
+ {
+ // Those must default to 0, if they are not returned by central.
+ event.data.settings.ans_high_prioritized_alert_support = 0;
+ event.data.settings.ans_instant_message_support = 0;
+ }
+
+ p_ans->evt_handler(&event);
+
+ tx_buffer_process();
+}
+
+
+/**@brief Function for disconnecting and cleaning the current service.
+ */
+static void event_disconnect(ble_ans_c_t * p_ans, ble_evt_t const * p_ble_evt)
+{
+ if (p_ans->conn_handle == p_ble_evt->evt.gap_evt.conn_handle)
+ {
+ p_ans->conn_handle = BLE_CONN_HANDLE_INVALID;
+
+ // Clearing all data for the service will also set all handle values to @ref BLE_GATT_HANDLE_INVALID
+ memset(&p_ans->service, 0, sizeof(ble_ans_c_service_t));
+
+ // There was a valid instance of IAS on the peer. Send an event to the
+ // application, so that it can do any clean up related to this module.
+ ble_ans_c_evt_t evt;
+
+ evt.evt_type = BLE_ANS_C_EVT_DISCONN_COMPLETE;
+ p_ans->evt_handler(&evt);
+ }
+}
+
+
+/**@brief Function for handling of BLE stack events. */
+void ble_ans_c_on_ble_evt(ble_evt_t const * p_ble_evt, void * p_context)
+{
+ ble_ans_c_t * p_ans = (ble_ans_c_t *)p_context;
+
+ switch (p_ble_evt->header.evt_id)
+ {
+ case BLE_GATTC_EVT_HVX:
+ event_notify(p_ans, p_ble_evt);
+ break;
+
+ case BLE_GATTC_EVT_WRITE_RSP:
+ event_write_rsp(p_ans, p_ble_evt);
+ break;
+
+ case BLE_GATTC_EVT_READ_RSP:
+ event_read_rsp(p_ans, p_ble_evt);
+ break;
+
+ case BLE_GAP_EVT_DISCONNECTED:
+ event_disconnect(p_ans, p_ble_evt);
+ break;
+ }
+}
+
+
+uint32_t ble_ans_c_init(ble_ans_c_t * p_ans, ble_ans_c_init_t const * p_ans_init)
+{
+ VERIFY_PARAM_NOT_NULL(p_ans);
+ VERIFY_PARAM_NOT_NULL(p_ans_init);
+ VERIFY_PARAM_NOT_NULL(p_ans_init->evt_handler);
+
+ // clear all handles
+ memset(p_ans, 0, sizeof(ble_ans_c_t));
+ memset(m_tx_buffer, 0, TX_BUFFER_SIZE);
+ p_ans->conn_handle = BLE_CONN_HANDLE_INVALID;
+
+ p_ans->evt_handler = p_ans_init->evt_handler;
+ p_ans->error_handler = p_ans_init->error_handler;
+ p_ans->message_buffer_size = p_ans_init->message_buffer_size;
+ p_ans->p_message_buffer = p_ans_init->p_message_buffer;
+
+ BLE_UUID_BLE_ASSIGN(p_ans->service.service.uuid, BLE_UUID_ALERT_NOTIFICATION_SERVICE);
+ BLE_UUID_BLE_ASSIGN(p_ans->service.new_alert.uuid, BLE_UUID_NEW_ALERT_CHAR);
+ BLE_UUID_BLE_ASSIGN(p_ans->service.alert_notif_ctrl_point.uuid,
+ BLE_UUID_ALERT_NOTIFICATION_CONTROL_POINT_CHAR);
+ BLE_UUID_BLE_ASSIGN(p_ans->service.unread_alert_status.uuid, BLE_UUID_UNREAD_ALERT_CHAR);
+ BLE_UUID_BLE_ASSIGN(p_ans->service.suported_new_alert_cat.uuid,
+ BLE_UUID_SUPPORTED_NEW_ALERT_CATEGORY_CHAR);
+ BLE_UUID_BLE_ASSIGN(p_ans->service.suported_unread_alert_cat.uuid,
+ BLE_UUID_SUPPORTED_UNREAD_ALERT_CATEGORY_CHAR);
+
+ BLE_UUID_BLE_ASSIGN(p_ans->service.new_alert_cccd.uuid, BLE_UUID_DESCRIPTOR_CLIENT_CHAR_CONFIG);
+ BLE_UUID_BLE_ASSIGN(p_ans->service.unread_alert_cccd.uuid,
+ BLE_UUID_DESCRIPTOR_CLIENT_CHAR_CONFIG);
+
+ return ble_db_discovery_evt_register(&p_ans->service.service.uuid);
+}
+
+
+/**@brief Function for creating a TX message for writing a CCCD.
+ */
+static uint32_t cccd_configure(uint16_t conn_handle, uint16_t handle_cccd, bool enable)
+{
+ ans_tx_message_t * p_msg;
+ uint16_t cccd_val = enable ? BLE_GATT_HVX_NOTIFICATION : 0;
+
+ p_msg = &m_tx_buffer[m_tx_insert_index++];
+ m_tx_insert_index &= TX_BUFFER_MASK;
+
+ p_msg->req.write_req.gattc_params.handle = handle_cccd;
+ p_msg->req.write_req.gattc_params.len = WRITE_MESSAGE_LENGTH;
+ p_msg->req.write_req.gattc_params.p_value = p_msg->req.write_req.gattc_value;
+ p_msg->req.write_req.gattc_params.offset = 0;
+ p_msg->req.write_req.gattc_params.write_op = BLE_GATT_OP_WRITE_REQ;
+ p_msg->req.write_req.gattc_value[0] = LSB_16(cccd_val);
+ p_msg->req.write_req.gattc_value[1] = MSB_16(cccd_val);
+ p_msg->conn_handle = conn_handle;
+ p_msg->type = WRITE_REQ;
+
+ tx_buffer_process();
+ return NRF_SUCCESS;
+}
+
+
+uint32_t ble_ans_c_enable_notif_new_alert(ble_ans_c_t const * p_ans)
+{
+ if (p_ans->conn_handle == BLE_CONN_HANDLE_INVALID)
+ {
+ return NRF_ERROR_INVALID_STATE;
+ }
+ else
+ {
+ return cccd_configure(p_ans->conn_handle,
+ p_ans->service.new_alert_cccd.handle,
+ true);
+ }
+}
+
+
+uint32_t ble_ans_c_disable_notif_new_alert(ble_ans_c_t const * p_ans)
+{
+ return cccd_configure(p_ans->conn_handle,
+ p_ans->service.new_alert_cccd.handle,
+ false);
+}
+
+
+uint32_t ble_ans_c_enable_notif_unread_alert(ble_ans_c_t const * p_ans)
+{
+ if ( p_ans->conn_handle == BLE_CONN_HANDLE_INVALID)
+ {
+ return NRF_ERROR_INVALID_STATE;
+ }
+ return cccd_configure(p_ans->conn_handle,
+ p_ans->service.unread_alert_cccd.handle,
+ true);
+}
+
+
+uint32_t ble_ans_c_disable_notif_unread_alert(ble_ans_c_t const * p_ans)
+{
+ return cccd_configure(p_ans->conn_handle,
+ p_ans->service.unread_alert_cccd.handle,
+ false);
+}
+
+
+uint32_t ble_ans_c_control_point_write(ble_ans_c_t const * p_ans,
+ ble_ans_control_point_t const * p_control_point)
+{
+ ans_tx_message_t * p_msg;
+
+ p_msg = &m_tx_buffer[m_tx_insert_index++];
+ m_tx_insert_index &= TX_BUFFER_MASK;
+
+ p_msg->req.write_req.gattc_params.handle = p_ans->service.alert_notif_ctrl_point.handle_value;
+ p_msg->req.write_req.gattc_params.len = WRITE_MESSAGE_LENGTH;
+ p_msg->req.write_req.gattc_params.p_value = p_msg->req.write_req.gattc_value;
+ p_msg->req.write_req.gattc_params.offset = 0;
+ p_msg->req.write_req.gattc_params.write_op = BLE_GATT_OP_WRITE_REQ;
+ p_msg->req.write_req.gattc_value[0] = p_control_point->command;
+ p_msg->req.write_req.gattc_value[1] = p_control_point->category;
+ p_msg->conn_handle = p_ans->conn_handle;
+ p_msg->type = WRITE_REQ;
+
+ tx_buffer_process();
+ return NRF_SUCCESS;
+}
+
+
+uint32_t ble_ans_c_new_alert_read(ble_ans_c_t const * p_ans)
+{
+ ans_tx_message_t * msg;
+
+ msg = &m_tx_buffer[m_tx_insert_index++];
+ m_tx_insert_index &= TX_BUFFER_MASK;
+
+ msg->req.read_handle = p_ans->service.suported_new_alert_cat.handle_value;
+ msg->conn_handle = p_ans->conn_handle;
+ msg->type = READ_REQ;
+
+ tx_buffer_process();
+ return NRF_SUCCESS;
+}
+
+
+uint32_t ble_ans_c_unread_alert_read(ble_ans_c_t const * p_ans)
+{
+ ans_tx_message_t * msg;
+
+ msg = &m_tx_buffer[m_tx_insert_index++];
+ m_tx_insert_index &= TX_BUFFER_MASK;
+
+ msg->req.read_handle = p_ans->service.suported_unread_alert_cat.handle_value;
+ msg->conn_handle = p_ans->conn_handle;
+ msg->type = READ_REQ;
+
+ tx_buffer_process();
+ return NRF_SUCCESS;
+}
+
+
+uint32_t ble_ans_c_new_alert_notify(ble_ans_c_t const * p_ans, ble_ans_category_id_t category_id)
+{
+ ble_ans_control_point_t control_point;
+
+ control_point.command = ANS_NOTIFY_NEW_INCOMING_ALERT_IMMEDIATELY;
+ control_point.category = category_id;
+
+ return ble_ans_c_control_point_write(p_ans, &control_point);
+}
+
+
+uint32_t ble_ans_c_unread_alert_notify(ble_ans_c_t const * p_ans, ble_ans_category_id_t category_id)
+{
+ ble_ans_control_point_t control_point;
+
+ control_point.command = ANS_NOTIFY_UNREAD_CATEGORY_STATUS_IMMEDIATELY;
+ control_point.category = category_id;
+
+ return ble_ans_c_control_point_write(p_ans, &control_point);
+}
+
+
+uint32_t ble_ans_c_handles_assign(ble_ans_c_t * p_ans,
+ uint16_t conn_handle,
+ ble_ans_c_service_t const * p_peer_handles)
+{
+ VERIFY_PARAM_NOT_NULL(p_ans);
+
+ if (!is_valid_ans_srv_discovered(p_peer_handles))
+ {
+ return NRF_ERROR_INVALID_PARAM;
+ }
+ p_ans->conn_handle = conn_handle;
+
+ if (p_peer_handles != NULL)
+ {
+ // Copy the handles from the discovered characteristics over to the provided client instance.
+ char_set(&p_ans->service.alert_notif_ctrl_point, &p_peer_handles->alert_notif_ctrl_point);
+ char_set(&p_ans->service.suported_new_alert_cat, &p_peer_handles->suported_new_alert_cat);
+ char_set(&p_ans->service.suported_unread_alert_cat, &p_peer_handles->suported_unread_alert_cat);
+ char_set(&p_ans->service.new_alert, &p_peer_handles->new_alert);
+ char_cccd_set(&p_ans->service.new_alert_cccd, p_peer_handles->new_alert_cccd.handle);
+ char_set(&p_ans->service.unread_alert_status, &p_peer_handles->unread_alert_status);
+ char_cccd_set(&p_ans->service.unread_alert_cccd, p_peer_handles->unread_alert_cccd.handle);
+ }
+
+ return NRF_SUCCESS;
+}
+#endif // NRF_MODULE_ENABLED(BLE_ANS_C)
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/ble_ans_c/ble_ans_c.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/ble_ans_c/ble_ans_c.h
new file mode 100644
index 0000000..642cffd
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/ble_ans_c/ble_ans_c.h
@@ -0,0 +1,409 @@
+/**
+ * Copyright (c) 2012 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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
+ *
+ * @defgroup ble_ans_c Alert Notification Service Client
+ * @{
+ * @ingroup ble_sdk_srv
+ * @brief Alert Notification module.
+ *
+ * @details This module implements the Alert Notification Client according to the
+ * Alert Notification Profile.
+ *
+ * @note The application must register this module as BLE event observer using the
+ * NRF_SDH_BLE_OBSERVER macro. Example:
+ * @code
+ * ble_ans_c_t instance;
+ * NRF_SDH_BLE_OBSERVER(anything, BLE_ANS_C_BLE_OBSERVER_PRIO,
+ * ble_ans_c_on_ble_evt, &instance);
+ * @endcode
+ *
+ * @note Attention!
+ * To maintain compliance with Nordic Semiconductor ASA Bluetooth profile
+ * qualification listings, this section of source code must not be modified.
+ */
+#ifndef BLE_ANS_C_H__
+#define BLE_ANS_C_H__
+
+#include "ble.h"
+#include "ble_gatts.h"
+#include "ble_types.h"
+#include "sdk_common.h"
+#include "ble_srv_common.h"
+#include "ble_db_discovery.h"
+#include "nrf_sdh_ble.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**@brief Macro for defining a ble_ans_c instance.
+ *
+ * @param _name Name of the instance.
+ * @hideinitializer
+ */
+#define BLE_ANS_C_DEF(_name) \
+static ble_ans_c_t _name; \
+NRF_SDH_BLE_OBSERVER(_name ## _obs, \
+ BLE_ANS_C_BLE_OBSERVER_PRIO, \
+ ble_ans_c_on_ble_evt, &_name)
+
+/** @brief Macro for defining multiple ble_ans_c instances.
+ *
+ * @param _name Name of the array of instances.
+ * @param _cnt Number of instances to define.
+ * @hideinitializer
+ */
+#define BLE_ANS_C_ARRAY_DEF(_name, _cnt) \
+static ble_ans_c_t _name[_cnt]; \
+NRF_SDH_BLE_OBSERVERS(_name ## _obs, \
+ BLE_ANS_C_BLE_OBSERVER_PRIO, \
+ ble_ans_c_on_ble_evt, &_name, _cnt)
+
+// Forward declaration of the ble_ans_c_t type.
+typedef struct ble_ans_c_s ble_ans_c_t;
+
+/** Alerts types as defined in the alert category id; UUID: 0x2A43. */
+typedef enum
+{
+ ANS_TYPE_SIMPLE_ALERT = 0, /**< General text alert or non-text alert.*/
+ ANS_TYPE_EMAIL = 1, /**< Alert when email messages arrives.*/
+ ANS_TYPE_NEWS = 2, /**< News feeds such as RSS, Atom.*/
+ ANS_TYPE_NOTIFICATION_CALL = 3, /**< Incoming call.*/
+ ANS_TYPE_MISSED_CALL = 4, /**< Missed call.*/
+ ANS_TYPE_SMS_MMS = 5, /**< SMS/MMS message arrives.*/
+ ANS_TYPE_VOICE_MAIL = 6, /**< Voice mail.*/
+ ANS_TYPE_SCHEDULE = 7, /**< Alert occurred on calendar, planner.*/
+ ANS_TYPE_HIGH_PRIORITIZED_ALERT = 8, /**< Alert that should be handled as high priority.*/
+ ANS_TYPE_INSTANT_MESSAGE = 9, /**< Alert for incoming instant messages.*/
+ ANS_TYPE_ALL_ALERTS = 0xFF /**< Identifies All Alerts. */
+} ble_ans_category_id_t;
+
+/** Alerts notification control point commands as defined in the Alert Notification Specification;
+ * UUID: 0x2A44.
+ */
+typedef enum
+{
+ ANS_ENABLE_NEW_INCOMING_ALERT_NOTIFICATION = 0, /**< Enable New Incoming Alert Notification.*/
+ ANS_ENABLE_UNREAD_CATEGORY_STATUS_NOTIFICATION = 1, /**< Enable Unread Category Status Notification.*/
+ ANS_DISABLE_NEW_INCOMING_ALERT_NOTIFICATION = 2, /**< Disable New Incoming Alert Notification.*/
+ ANS_DISABLE_UNREAD_CATEGORY_STATUS_NOTIFICATION = 3, /**< Disable Unread Category Status Notification.*/
+ ANS_NOTIFY_NEW_INCOMING_ALERT_IMMEDIATELY = 4, /**< Notify New Incoming Alert immediately.*/
+ ANS_NOTIFY_UNREAD_CATEGORY_STATUS_IMMEDIATELY = 5, /**< Notify Unread Category Status immediately.*/
+} ble_ans_command_id_t;
+
+/**@brief Alert Notification Event types that are passed from client to application on an event. */
+typedef enum
+{
+ BLE_ANS_C_EVT_DISCOVERY_COMPLETE, /**< A successful connection has been established and the characteristics of the server has been fetched. */
+ BLE_ANS_C_EVT_DISCOVERY_FAILED, /**< It was not possible to discover service or characteristics of the connected peer. */
+ BLE_ANS_C_EVT_DISCONN_COMPLETE, /**< The connection has been taken down. */
+ BLE_ANS_C_EVT_NOTIFICATION, /**< A valid Alert Notification has been received from the server.*/
+ BLE_ANS_C_EVT_READ_RESP, /**< A read response has been received from the server.*/
+ BLE_ANS_C_EVT_WRITE_RESP /**< A write response has been received from the server.*/
+} ble_ans_c_evt_type_t;
+
+/**@brief Alert Notification Control Point structure. */
+typedef struct
+{
+ ble_ans_command_id_t command; /**< The command to be written to the control point, see @ref ble_ans_command_id_t. */
+ ble_ans_category_id_t category; /**< The category for the control point for which the command applies, see @ref ble_ans_category_id_t. */
+} ble_ans_control_point_t;
+
+/**@brief Alert Notification Setting structure containing the supported alerts in the service.
+ *
+ *@details
+ * The structure contains bit fields describing which alerts that are supported:
+ * 0 = Unsupported
+ * 1 = Supported
+ */
+typedef struct
+{
+ uint8_t ans_simple_alert_support : 1; /**< Support for General text alert or non-text alert.*/
+ uint8_t ans_email_support : 1; /**< Support for Alert when email messages arrives.*/
+ uint8_t ans_news_support : 1; /**< Support for News feeds such as RSS, Atom.*/
+ uint8_t ans_notification_call_support : 1; /**< Support for Incoming call.*/
+ uint8_t ans_missed_call_support : 1; /**< Support for Missed call.*/
+ uint8_t ans_sms_mms_support : 1; /**< Support for SMS/MMS message arrives.*/
+ uint8_t ans_voice_mail_support : 1; /**< Support for Voice mail.*/
+ uint8_t ans_schedule_support : 1; /**< Support for Alert occurred on calendar, planner.*/
+ uint8_t ans_high_prioritized_alert_support : 1; /**< Support for Alert that should be handled as high priority.*/
+ uint8_t ans_instant_message_support : 1; /**< Support for Alert for incoming instant messages.*/
+ uint8_t reserved : 6; /**< Reserved for future use. */
+} ble_ans_alert_settings_t;
+
+/**@brief Alert Notification structure
+ */
+typedef struct
+{
+ uint8_t alert_category; /**< Alert category to which this alert belongs.*/
+ uint8_t alert_category_count; /**< Number of alerts in the category. */
+ uint32_t alert_msg_length; /**< Length of optional text message send by the server. */
+ uint8_t * p_alert_msg_buf; /**< Pointer to buffer containing the optional text message. */
+} ble_ans_alert_notification_t;
+
+/**@brief Struct to hold information on the Alert Notification Service if found on the server. */
+typedef struct
+{
+ ble_gattc_service_t service; /**< The GATT service holding the discovered Alert Notification Service. */
+ ble_gattc_char_t alert_notif_ctrl_point; /**< Characteristic for the Alert Notification Control Point. @ref BLE_UUID_ALERT_NOTIFICATION_CONTROL_POINT_CHAR */
+ ble_gattc_char_t suported_new_alert_cat; /**< Characteristic for the Supported New Alert category. @ref BLE_UUID_SUPPORTED_NEW_ALERT_CATEGORY_CHAR */
+ ble_gattc_char_t suported_unread_alert_cat; /**< Characteristic for the Unread Alert category. @ref BLE_UUID_SUPPORTED_UNREAD_ALERT_CATEGORY_CHAR */
+ ble_gattc_char_t new_alert; /**< Characteristic for the New Alert Notification. @ref BLE_UUID_NEW_ALERT_CHAR */
+ ble_gattc_desc_t new_alert_cccd; /**< Characteristic Descriptor for New Alert Category. Enables or Disables GATT notifications */
+ ble_gattc_char_t unread_alert_status; /**< Characteristic for the Unread Alert Notification. @ref BLE_UUID_UNREAD_ALERT_CHAR */
+ ble_gattc_desc_t unread_alert_cccd; /**< Characteristic Descriptor for Unread Alert Category. Enables or Disables GATT notifications */
+} ble_ans_c_service_t;
+
+/**@brief Alert Notification Event structure
+ *
+ * @details The structure contains the event that should be handled, as well as
+ * additional information.
+ */
+typedef struct
+{
+ ble_ans_c_evt_type_t evt_type; /**< Type of event. */
+ uint16_t conn_handle; /**< Connection handle on which the ANS service was discovered on the peer device. This will be filled if the evt_type is @ref BLE_ANS_C_EVT_DISCOVERY_COMPLETE.*/
+ ble_uuid_t uuid; /**< UUID of the event in case of an alert or notification. */
+ union
+ {
+ ble_ans_alert_settings_t settings; /**< Setting returned from server on read request. */
+ ble_ans_alert_notification_t alert; /**< Alert Notification data sent by the server. */
+ uint32_t error_code; /**< Additional status/error code if the event was caused by a stack error or gatt status, e.g. during service discovery. */
+ ble_ans_c_service_t service; /**< Info on the discovered Alert Notification Service discovered. This will be filled if the evt_type is @ref BLE_ANS_C_EVT_DISCOVERY_COMPLETE.*/
+ } data;
+} ble_ans_c_evt_t;
+
+/**@brief Alert Notification event handler type. */
+typedef void (*ble_ans_c_evt_handler_t) (ble_ans_c_evt_t * p_evt);
+
+/**@brief Alert Notification structure. This contains various status information for the client. */
+struct ble_ans_c_s
+{
+ ble_ans_c_evt_handler_t evt_handler; /**< Event handler to be called for handling events in the Alert Notification Client Application. */
+ ble_srv_error_handler_t error_handler; /**< Function to be called in case of an error. */
+ uint16_t conn_handle; /**< Handle of the current connection (as provided by the BLE stack, is BLE_CONN_HANDLE_INVALID if not in a connection). */
+ uint8_t central_handle; /**< Handle for the currently connected central if peer is bonded. */
+ uint8_t service_handle; /**< Handle to the service in the database to use for this instance. */
+ uint32_t message_buffer_size; /**< Size of message buffer to hold the additional text messages received on notifications. */
+ uint8_t * p_message_buffer; /**< Pointer to the buffer to be used for additional text message handling. */
+ ble_ans_c_service_t service; /**< Struct to store the different handles and UUIDs related to the service. */
+};
+
+/**@brief Alert Notification init structure. This contains all options and data needed for
+ * initialization of the client.*/
+typedef struct
+{
+ ble_ans_c_evt_handler_t evt_handler; /**< Event handler to be called for handling events in the Battery Service. */
+ ble_srv_error_handler_t error_handler; /**< Function to be called in case of an error. */
+ uint32_t message_buffer_size; /**< Size of buffer to handle messages. */
+ uint8_t * p_message_buffer; /**< Pointer to buffer for passing messages. */
+} ble_ans_c_init_t;
+
+
+/**@brief Function for handling events from the database discovery module.
+ *
+ * @details Call this function when getting a callback event from the DB discovery modue.
+ * This function will handle an event from the database discovery module, and determine
+ * if it relates to the discovery of heart rate service at the peer. If so, it will
+ * call the application's event handler indicating that the heart rate service has been
+ * discovered at the peer. It also populates the event with the service related
+ * information before providing it to the application.
+ *
+ * @param[in] p_ans Pointer to the Alert Notification client structure instance that will handle
+ * the discovery.
+ * @param[in] p_evt Pointer to the event received from the database discovery module.
+ */
+void ble_ans_c_on_db_disc_evt(ble_ans_c_t * p_ans, ble_db_discovery_evt_t const * p_evt);
+
+
+/**@brief Function for handling the Application's BLE Stack events.
+ *
+ * @details Handles all events from the BLE stack of interest to the Alert Notification Client.
+ *
+ * @param[in] p_ble_evt Event received from the BLE stack.
+ * @param[in] p_context Alert Notification Client structure.
+ */
+void ble_ans_c_on_ble_evt(ble_evt_t const * p_ble_evt, void * p_context);
+
+
+/**@brief Function for initializing the Alert Notification Client.
+ *
+ * @param[out] p_ans Alert Notification Client structure. This structure will have to be
+ * supplied by the application. It will be initialized by this function,
+ * and will later be used to identify this particular client instance.
+ * @param[in] p_ans_init Information needed to initialize the client.
+ *
+ * @return NRF_SUCCESS on successful initialization of client, otherwise an error code.
+ */
+uint32_t ble_ans_c_init(ble_ans_c_t * p_ans, ble_ans_c_init_t const * p_ans_init);
+
+
+/**@brief Function for writing the to CCCD to enable new alert notifications from the Alert Notification Service.
+ *
+ * @param[in] p_ans Alert Notification structure. This structure will have to be supplied by
+ * the application. It identifies the particular client instance to use.
+ *
+ * @return NRF_SUCCESS on successful writing of the CCCD, otherwise an error code.
+ */
+uint32_t ble_ans_c_enable_notif_new_alert(ble_ans_c_t const * p_ans);
+
+
+/**@brief Function for writing to the CCCD to enable unread alert notifications from the Alert Notification Service.
+ *
+ * @param[in] p_ans Alert Notification structure. This structure will have to be supplied by
+ * the application. It identifies the particular client instance to use.
+ *
+ * @return NRF_SUCCESS on successful writing of the CCCD, otherwise an error code.
+ */
+uint32_t ble_ans_c_enable_notif_unread_alert(ble_ans_c_t const * p_ans);
+
+
+/**@brief Function for writing to the CCCD to disable new alert notifications from the Alert Notification Service.
+ *
+ * @param[in] p_ans Alert Notification structure. This structure will have to be supplied by
+ * the application. It identifies the particular client instance to use.
+ *
+ * @return NRF_SUCCESS on successful writing of the CCCD, otherwise an error code.
+ */
+uint32_t ble_ans_c_disable_notif_new_alert(ble_ans_c_t const * p_ans);
+
+
+/**@brief Function for writing to the CCCD to disable unread alert notifications from the Alert Notification Service.
+ *
+ * @param[in] p_ans Alert Notification structure. This structure will have to be supplied by
+ * the application. It identifies the particular client instance to use.
+ *
+ * @return NRF_SUCCESS on successful writing of the CCCD, otherwise an error code.
+ */
+uint32_t ble_ans_c_disable_notif_unread_alert(ble_ans_c_t const * p_ans);
+
+
+/**@brief Function for writing to the Alert Notification Control Point to specify alert notification behavior in the
+ * Alert Notification Service on the Central.
+ *
+ * @param[in] p_ans Alert Notification structure. This structure will have to be
+ * supplied by the application. It identifies the particular client
+ * instance to use.
+ * @param[in] p_control_point Alert Notification Control Point structure. This structure
+ * specifies the values to write to the Alert Notification Control
+ * Point, UUID 0x2A44.
+ *
+ * @return NRF_SUCCESS on successful writing of the Control Point, otherwise an error code.
+ */
+uint32_t ble_ans_c_control_point_write(ble_ans_c_t const * p_ans,
+ ble_ans_control_point_t const * p_control_point);
+
+
+/**@brief Function for reading the Supported New Alert characteristic value of the service.
+ * The value describes the alerts supported in the central.
+ *
+ * @param[in] p_ans Alert Notification structure. This structure will have to be supplied by
+ * the application. It identifies the particular client instance to use.
+ *
+ * @return NRF_SUCCESS on successful transmission of the read request, otherwise an error code.
+ */
+uint32_t ble_ans_c_new_alert_read(ble_ans_c_t const * p_ans);
+
+
+/**@brief Function for reading the Supported Unread Alert characteristic value of the service.
+ * The value describes the alerts supported in the central.
+ *
+ * @param[in] p_ans Alert Notification structure. This structure will have to be supplied by
+ * the application. It identifies the particular client instance to use.
+ *
+ * @return NRF_SUCCESS on successful transmission of the read request, otherwise an error code.
+ */
+uint32_t ble_ans_c_unread_alert_read(ble_ans_c_t const * p_ans);
+
+
+/**@brief Function for requesting the peer to notify the New Alert characteristics immediately.
+ *
+ * @param[in] p_ans Alert Notification structure. This structure will have to be supplied by
+ * the application. It identifies the particular client instance to use.
+ * @param[in] category The category ID for which the peer should notify the client.
+ *
+ * @return NRF_SUCCESS on successful transmission of the read request, otherwise an error code.
+ */
+uint32_t ble_ans_c_new_alert_notify(ble_ans_c_t const * p_ans, ble_ans_category_id_t category);
+
+
+/**@brief Function for requesting the peer to notify the Unread Alert characteristics immediately.
+ *
+ * @param[in] p_ans Alert Notification structure. This structure will have to be supplied by
+ * the application. It identifies the particular client instance to use.
+ * @param[in] category The category ID for which the peer should notify the client.
+ *
+ * @return NRF_SUCCESS on successful transmission of the read request, otherwise an error code.
+ */
+uint32_t ble_ans_c_unread_alert_notify(ble_ans_c_t const * p_ans, ble_ans_category_id_t category);
+
+
+/**@brief Function for assigning a handles to a an instance of ans_c.
+ *
+ * @details Call this function when a link has been established with a peer to
+ * associate this link to an instance of the module. This makes it
+ * possible to handle several link and associate each link to a particular
+ * instance of the ans_c module. The connection handle and attribute handles will be
+ * provided from the discovery event @ref BLE_ANS_C_EVT_DISCOVERY_COMPLETE.
+ *
+ * @param[in] p_ans Pointer to the Alert Notification client structure instance to
+ * associate with the handles.
+ * @param[in] conn_handle Connection handle to associated with the given Alert Notification Client
+ * Instance.
+ * @param[in] p_peer_handles Attribute handles on the ANS server that you want this ANS client to
+ * interact with.
+ *
+ */
+uint32_t ble_ans_c_handles_assign(ble_ans_c_t * p_ans,
+ uint16_t const conn_handle,
+ ble_ans_c_service_t const * p_peer_handles);
+
+
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // BLE_ANS_C_H__
+
+/** @} */
+
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/ble_bas/ble_bas.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/ble_bas/ble_bas.c
new file mode 100644
index 0000000..4c7d174
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/ble_bas/ble_bas.c
@@ -0,0 +1,384 @@
+/**
+ * Copyright (c) 2012 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+/* Attention!
+ * To maintain compliance with Nordic Semiconductor ASA's Bluetooth profile
+ * qualification listings, this section of source code must not be modified.
+ */
+#include "sdk_common.h"
+#if NRF_MODULE_ENABLED(BLE_BAS)
+#include "ble_bas.h"
+#include <string.h>
+#include "ble_srv_common.h"
+#include "ble_conn_state.h"
+
+#define NRF_LOG_MODULE_NAME ble_bas
+#if BLE_BAS_CONFIG_LOG_ENABLED
+#define NRF_LOG_LEVEL BLE_BAS_CONFIG_LOG_LEVEL
+#define NRF_LOG_INFO_COLOR BLE_BAS_CONFIG_INFO_COLOR
+#define NRF_LOG_DEBUG_COLOR BLE_BAS_CONFIG_DEBUG_COLOR
+#else // BLE_BAS_CONFIG_LOG_ENABLED
+#define NRF_LOG_LEVEL 0
+#endif // BLE_BAS_CONFIG_LOG_ENABLED
+#include "nrf_log.h"
+NRF_LOG_MODULE_REGISTER();
+
+
+#define INVALID_BATTERY_LEVEL 255
+
+
+/**@brief Function for handling the Write event.
+ *
+ * @param[in] p_bas Battery Service structure.
+ * @param[in] p_ble_evt Event received from the BLE stack.
+ */
+static void on_write(ble_bas_t * p_bas, ble_evt_t const * p_ble_evt)
+{
+ if (!p_bas->is_notification_supported)
+ {
+ return;
+ }
+
+ ble_gatts_evt_write_t const * p_evt_write = &p_ble_evt->evt.gatts_evt.params.write;
+
+ if ( (p_evt_write->handle == p_bas->battery_level_handles.cccd_handle)
+ && (p_evt_write->len == 2))
+ {
+ if (p_bas->evt_handler == NULL)
+ {
+ return;
+ }
+
+ ble_bas_evt_t evt;
+
+ if (ble_srv_is_notification_enabled(p_evt_write->data))
+ {
+ evt.evt_type = BLE_BAS_EVT_NOTIFICATION_ENABLED;
+ }
+ else
+ {
+ evt.evt_type = BLE_BAS_EVT_NOTIFICATION_DISABLED;
+ }
+ evt.conn_handle = p_ble_evt->evt.gatts_evt.conn_handle;
+
+ // CCCD written, call application event handler.
+ p_bas->evt_handler(p_bas, &evt);
+ }
+}
+
+
+void ble_bas_on_ble_evt(ble_evt_t const * p_ble_evt, void * p_context)
+{
+ if ((p_context == NULL) || (p_ble_evt == NULL))
+ {
+ return;
+ }
+
+ ble_bas_t * p_bas = (ble_bas_t *)p_context;
+
+ switch (p_ble_evt->header.evt_id)
+ {
+ case BLE_GATTS_EVT_WRITE:
+ on_write(p_bas, p_ble_evt);
+ break;
+
+ default:
+ // No implementation needed.
+ break;
+ }
+}
+
+
+/**@brief Function for adding the Battery Level characteristic.
+ *
+ * @param[in] p_bas Battery Service structure.
+ * @param[in] p_bas_init Information needed to initialize the service.
+ *
+ * @return NRF_SUCCESS on success, otherwise an error code.
+ */
+static ret_code_t battery_level_char_add(ble_bas_t * p_bas, const ble_bas_init_t * p_bas_init)
+{
+ ret_code_t err_code;
+ ble_gatts_char_md_t char_md;
+ ble_gatts_attr_md_t cccd_md;
+ ble_gatts_attr_t attr_char_value;
+ ble_uuid_t ble_uuid;
+ ble_gatts_attr_md_t attr_md;
+ uint8_t initial_battery_level;
+ uint8_t encoded_report_ref[BLE_SRV_ENCODED_REPORT_REF_LEN];
+ uint8_t init_len;
+
+ // Add Battery Level characteristic
+ if (p_bas->is_notification_supported)
+ {
+ memset(&cccd_md, 0, sizeof(cccd_md));
+
+ // According to BAS_SPEC_V10, the read operation on cccd should be possible without
+ // authentication.
+ BLE_GAP_CONN_SEC_MODE_SET_OPEN(&cccd_md.read_perm);
+ cccd_md.write_perm = p_bas_init->battery_level_char_attr_md.cccd_write_perm;
+ cccd_md.vloc = BLE_GATTS_VLOC_STACK;
+ }
+
+ memset(&char_md, 0, sizeof(char_md));
+
+ char_md.char_props.read = 1;
+ char_md.char_props.notify = (p_bas->is_notification_supported) ? 1 : 0;
+ char_md.p_char_user_desc = NULL;
+ char_md.p_char_pf = NULL;
+ char_md.p_user_desc_md = NULL;
+ char_md.p_cccd_md = (p_bas->is_notification_supported) ? &cccd_md : NULL;
+ char_md.p_sccd_md = NULL;
+
+ BLE_UUID_BLE_ASSIGN(ble_uuid, BLE_UUID_BATTERY_LEVEL_CHAR);
+
+ memset(&attr_md, 0, sizeof(attr_md));
+
+ attr_md.read_perm = p_bas_init->battery_level_char_attr_md.read_perm;
+ attr_md.write_perm = p_bas_init->battery_level_char_attr_md.write_perm;
+ attr_md.vloc = BLE_GATTS_VLOC_STACK;
+ attr_md.rd_auth = 0;
+ attr_md.wr_auth = 0;
+ attr_md.vlen = 0;
+
+ initial_battery_level = p_bas_init->initial_batt_level;
+
+ memset(&attr_char_value, 0, sizeof(attr_char_value));
+
+ attr_char_value.p_uuid = &ble_uuid;
+ attr_char_value.p_attr_md = &attr_md;
+ attr_char_value.init_len = sizeof(uint8_t);
+ attr_char_value.init_offs = 0;
+ attr_char_value.max_len = sizeof(uint8_t);
+ attr_char_value.p_value = &initial_battery_level;
+
+ err_code = sd_ble_gatts_characteristic_add(p_bas->service_handle, &char_md,
+ &attr_char_value,
+ &p_bas->battery_level_handles);
+ if (err_code != NRF_SUCCESS)
+ {
+ return err_code;
+ }
+
+ if (p_bas_init->p_report_ref != NULL)
+ {
+ // Add Report Reference descriptor
+ BLE_UUID_BLE_ASSIGN(ble_uuid, BLE_UUID_REPORT_REF_DESCR);
+
+ memset(&attr_md, 0, sizeof(attr_md));
+
+ attr_md.read_perm = p_bas_init->battery_level_report_read_perm;
+ BLE_GAP_CONN_SEC_MODE_SET_NO_ACCESS(&attr_md.write_perm);
+
+ attr_md.vloc = BLE_GATTS_VLOC_STACK;
+ attr_md.rd_auth = 0;
+ attr_md.wr_auth = 0;
+ attr_md.vlen = 0;
+
+ init_len = ble_srv_report_ref_encode(encoded_report_ref, p_bas_init->p_report_ref);
+
+ memset(&attr_char_value, 0, sizeof(attr_char_value));
+
+ attr_char_value.p_uuid = &ble_uuid;
+ attr_char_value.p_attr_md = &attr_md;
+ attr_char_value.init_len = init_len;
+ attr_char_value.init_offs = 0;
+ attr_char_value.max_len = attr_char_value.init_len;
+ attr_char_value.p_value = encoded_report_ref;
+
+ err_code = sd_ble_gatts_descriptor_add(p_bas->battery_level_handles.value_handle,
+ &attr_char_value,
+ &p_bas->report_ref_handle);
+ if (err_code != NRF_SUCCESS)
+ {
+ return err_code;
+ }
+ }
+ else
+ {
+ p_bas->report_ref_handle = BLE_GATT_HANDLE_INVALID;
+ }
+
+ return NRF_SUCCESS;
+}
+
+
+ret_code_t ble_bas_init(ble_bas_t * p_bas, const ble_bas_init_t * p_bas_init)
+{
+ if (p_bas == NULL || p_bas_init == NULL)
+ {
+ return NRF_ERROR_NULL;
+ }
+
+ ret_code_t err_code;
+ ble_uuid_t ble_uuid;
+
+ // Initialize service structure
+ p_bas->evt_handler = p_bas_init->evt_handler;
+ p_bas->is_notification_supported = p_bas_init->support_notification;
+ p_bas->battery_level_last = INVALID_BATTERY_LEVEL;
+
+ // Add service
+ BLE_UUID_BLE_ASSIGN(ble_uuid, BLE_UUID_BATTERY_SERVICE);
+
+ err_code = sd_ble_gatts_service_add(BLE_GATTS_SRVC_TYPE_PRIMARY, &ble_uuid, &p_bas->service_handle);
+ VERIFY_SUCCESS(err_code);
+
+ // Add battery level characteristic
+ err_code = battery_level_char_add(p_bas, p_bas_init);
+ return err_code;
+}
+
+
+/**@brief Function for sending notifications with the Battery Level characteristic.
+ *
+ * @param[in] p_hvx_params Pointer to structure with notification data.
+ * @param[in] conn_handle Connection handle.
+ *
+ * @return NRF_SUCCESS on success, otherwise an error code.
+ */
+static ret_code_t battery_notification_send(ble_gatts_hvx_params_t * const p_hvx_params,
+ uint16_t conn_handle)
+{
+ ret_code_t err_code = sd_ble_gatts_hvx(conn_handle, p_hvx_params);
+ if (err_code == NRF_SUCCESS)
+ {
+ NRF_LOG_INFO("Battery notification has been sent using conn_handle: 0x%04X", conn_handle);
+ }
+ else
+ {
+ NRF_LOG_DEBUG("Error: 0x%08X while sending notification with conn_handle: 0x%04X",
+ err_code,
+ conn_handle);
+ }
+ return err_code;
+}
+
+
+ret_code_t ble_bas_battery_level_update(ble_bas_t * p_bas,
+ uint8_t battery_level,
+ uint16_t conn_handle)
+{
+ if (p_bas == NULL)
+ {
+ return NRF_ERROR_NULL;
+ }
+
+ ret_code_t err_code = NRF_SUCCESS;
+ ble_gatts_value_t gatts_value;
+
+ if (battery_level != p_bas->battery_level_last)
+ {
+ // Initialize value struct.
+ memset(&gatts_value, 0, sizeof(gatts_value));
+
+ gatts_value.len = sizeof(uint8_t);
+ gatts_value.offset = 0;
+ gatts_value.p_value = &battery_level;
+
+ // Update database.
+ err_code = sd_ble_gatts_value_set(BLE_CONN_HANDLE_INVALID,
+ p_bas->battery_level_handles.value_handle,
+ &gatts_value);
+ if (err_code == NRF_SUCCESS)
+ {
+ NRF_LOG_INFO("Battery level has been updated: %d%%", battery_level)
+
+ // Save new battery value.
+ p_bas->battery_level_last = battery_level;
+ }
+ else
+ {
+ NRF_LOG_DEBUG("Error during battery level update: 0x%08X", err_code)
+
+ return err_code;
+ }
+
+ // Send value if connected and notifying.
+ if (p_bas->is_notification_supported)
+ {
+ ble_gatts_hvx_params_t hvx_params;
+
+ memset(&hvx_params, 0, sizeof(hvx_params));
+
+ hvx_params.handle = p_bas->battery_level_handles.value_handle;
+ hvx_params.type = BLE_GATT_HVX_NOTIFICATION;
+ hvx_params.offset = gatts_value.offset;
+ hvx_params.p_len = &gatts_value.len;
+ hvx_params.p_data = gatts_value.p_value;
+
+ if (conn_handle == BLE_CONN_HANDLE_ALL)
+ {
+ ble_conn_state_conn_handle_list_t conn_handles = ble_conn_state_conn_handles();
+
+ // Try sending notifications to all valid connection handles.
+ for (uint32_t i = 0; i < conn_handles.len; i++)
+ {
+ if (ble_conn_state_status(conn_handles.conn_handles[i]) == BLE_CONN_STATUS_CONNECTED)
+ {
+ if (err_code == NRF_SUCCESS)
+ {
+ err_code = battery_notification_send(&hvx_params,
+ conn_handles.conn_handles[i]);
+ }
+ else
+ {
+ // Preserve the first non-zero error code
+ UNUSED_RETURN_VALUE(battery_notification_send(&hvx_params,
+ conn_handles.conn_handles[i]));
+ }
+ }
+ }
+ }
+ else
+ {
+ err_code = battery_notification_send(&hvx_params, conn_handle);
+ }
+ }
+ else
+ {
+ err_code = NRF_ERROR_INVALID_STATE;
+ }
+ }
+
+ return err_code;
+}
+
+
+#endif // NRF_MODULE_ENABLED(BLE_BAS)
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/ble_bas/ble_bas.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/ble_bas/ble_bas.h
new file mode 100644
index 0000000..bf11ca6
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/ble_bas/ble_bas.h
@@ -0,0 +1,194 @@
+/**
+ * Copyright (c) 2012 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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
+ *
+ * @defgroup ble_bas Battery Service
+ * @{
+ * @ingroup ble_sdk_srv
+ * @brief Battery Service module.
+ *
+ * @details This module implements the Battery Service with the Battery Level characteristic.
+ * During initialization it adds the Battery Service and Battery Level characteristic
+ * to the BLE stack database. Optionally it can also add a Report Reference descriptor
+ * to the Battery Level characteristic (used when including the Battery Service in
+ * the HID service).
+ *
+ * If specified, the module will support notification of the Battery Level characteristic
+ * through the ble_bas_battery_level_update() function.
+ * If an event handler is supplied by the application, the Battery Service will
+ * generate Battery Service events to the application.
+ *
+ * @note The application must register this module as BLE event observer using the
+ * NRF_SDH_BLE_OBSERVER macro. Example:
+ * @code
+ * ble_bas_t instance;
+ * NRF_SDH_BLE_OBSERVER(anything, BLE_BAS_BLE_OBSERVER_PRIO,
+ * ble_bas_on_ble_evt, &instance);
+ * @endcode
+ *
+ * @note Attention!
+ * To maintain compliance with Nordic Semiconductor ASA Bluetooth profile
+ * qualification listings, this section of source code must not be modified.
+ */
+#ifndef BLE_BAS_H__
+#define BLE_BAS_H__
+
+#include <stdint.h>
+#include <stdbool.h>
+#include "ble.h"
+#include "ble_srv_common.h"
+#include "nrf_sdh_ble.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**@brief Macro for defining a ble_bas instance.
+ *
+ * @param _name Name of the instance.
+ * @hideinitializer
+ */
+#define BLE_BAS_DEF(_name) \
+ static ble_bas_t _name; \
+ NRF_SDH_BLE_OBSERVER(_name ## _obs, \
+ BLE_BAS_BLE_OBSERVER_PRIO, \
+ ble_bas_on_ble_evt, \
+ &_name)
+
+/**@brief Battery Service event type. */
+typedef enum
+{
+ BLE_BAS_EVT_NOTIFICATION_ENABLED, /**< Battery value notification enabled event. */
+ BLE_BAS_EVT_NOTIFICATION_DISABLED /**< Battery value notification disabled event. */
+} ble_bas_evt_type_t;
+
+/**@brief Battery Service event. */
+typedef struct
+{
+ ble_bas_evt_type_t evt_type; /**< Type of event. */
+ uint16_t conn_handle; /**< Connection handle. */
+} ble_bas_evt_t;
+
+// Forward declaration of the ble_bas_t type.
+typedef struct ble_bas_s ble_bas_t;
+
+/**@brief Battery Service event handler type. */
+typedef void (* ble_bas_evt_handler_t) (ble_bas_t * p_bas, ble_bas_evt_t * p_evt);
+
+/**@brief Battery Service init structure. This contains all options and data needed for
+ * initialization of the service.*/
+typedef struct
+{
+ ble_bas_evt_handler_t evt_handler; /**< Event handler to be called for handling events in the Battery Service. */
+ bool support_notification; /**< TRUE if notification of Battery Level measurement is supported. */
+ ble_srv_report_ref_t * p_report_ref; /**< If not NULL, a Report Reference descriptor with the specified value will be added to the Battery Level characteristic */
+ uint8_t initial_batt_level; /**< Initial battery level */
+ ble_srv_cccd_security_mode_t battery_level_char_attr_md; /**< Initial security level for battery characteristics attribute */
+ ble_gap_conn_sec_mode_t battery_level_report_read_perm; /**< Initial security level for battery report read attribute */
+} ble_bas_init_t;
+
+/**@brief Battery Service structure. This contains various status information for the service. */
+struct ble_bas_s
+{
+ ble_bas_evt_handler_t evt_handler; /**< Event handler to be called for handling events in the Battery Service. */
+ uint16_t service_handle; /**< Handle of Battery Service (as provided by the BLE stack). */
+ ble_gatts_char_handles_t battery_level_handles; /**< Handles related to the Battery Level characteristic. */
+ uint16_t report_ref_handle; /**< Handle of the Report Reference descriptor. */
+ uint8_t battery_level_last; /**< Last Battery Level measurement passed to the Battery Service. */
+ bool is_notification_supported; /**< TRUE if notification of Battery Level is supported. */
+};
+
+
+/**@brief Function for initializing the Battery Service.
+ *
+ * @param[out] p_bas Battery Service structure. This structure will have to be supplied by
+ * the application. It will be initialized by this function, and will later
+ * be used to identify this particular service instance.
+ * @param[in] p_bas_init Information needed to initialize the service.
+ *
+ * @return NRF_SUCCESS on successful initialization of service, otherwise an error code.
+ */
+ret_code_t ble_bas_init(ble_bas_t * p_bas, const ble_bas_init_t * p_bas_init);
+
+
+/**@brief Function for handling the Application's BLE Stack events.
+ *
+ * @details Handles all events from the BLE stack of interest to the Battery Service.
+ *
+ * @note For the requirements in the BAS specification to be fulfilled,
+ * ble_bas_battery_level_update() must be called upon reconnection if the
+ * battery level has changed while the service has been disconnected from a bonded
+ * client.
+ *
+ * @param[in] p_ble_evt Event received from the BLE stack.
+ * @param[in] p_context Battery Service structure.
+ */
+void ble_bas_on_ble_evt(ble_evt_t const * p_ble_evt, void * p_context);
+
+
+/**@brief Function for updating the battery level.
+ *
+ * @details The application calls this function after having performed a battery measurement.
+ * The battery level characteristic will only be sent to the clients which have
+ * enabled notifications. \ref BLE_CONN_HANDLE_ALL can be used as a connection handle
+ * to send notifications to all connected devices.
+ *
+ * @note For the requirements in the BAS specification to be fulfilled,
+ * this function must be called upon reconnection if the battery level has changed
+ * while the service has been disconnected from a bonded client.
+ *
+ * @param[in] p_bas Battery Service structure.
+ * @param[in] battery_level New battery measurement value (in percent of full capacity).
+ * @param[in] conn_handle Connection handle.
+ *
+ * @return NRF_SUCCESS on success, otherwise an error code.
+ */
+ret_code_t ble_bas_battery_level_update(ble_bas_t * p_bas,
+ uint8_t battery_level,
+ uint16_t conn_handle);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // BLE_BAS_H__
+
+/** @} */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/ble_bas_c/ble_bas_c.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/ble_bas_c/ble_bas_c.c
new file mode 100644
index 0000000..f9a494e
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/ble_bas_c/ble_bas_c.c
@@ -0,0 +1,405 @@
+/**
+ * Copyright (c) 2012 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#include "sdk_common.h"
+#if NRF_MODULE_ENABLED(BLE_BAS_C)
+#include "ble_bas_c.h"
+#include "ble_types.h"
+#include "ble_db_discovery.h"
+#include "ble_srv_common.h"
+#include "ble_gattc.h"
+#define NRF_LOG_MODULE_NAME ble_bas_c
+#include "nrf_log.h"
+NRF_LOG_MODULE_REGISTER();
+
+#define TX_BUFFER_MASK 0x07 /**< TX Buffer mask, must be a mask of contiguous zeroes, followed by contiguous sequence of ones: 000...111. */
+#define TX_BUFFER_SIZE (TX_BUFFER_MASK + 1) /**< Size of the send buffer, which is 1 higher than the mask. */
+#define WRITE_MESSAGE_LENGTH BLE_CCCD_VALUE_LEN /**< Length of the write message for CCCD. */
+
+typedef enum
+{
+ READ_REQ, /**< Type identifying that this tx_message is a read request. */
+ WRITE_REQ /**< Type identifying that this tx_message is a write request. */
+} tx_request_t;
+
+/**@brief Structure for writing a message to the peer, i.e. CCCD.
+ */
+typedef struct
+{
+ uint8_t gattc_value[WRITE_MESSAGE_LENGTH]; /**< The message to write. */
+ ble_gattc_write_params_t gattc_params; /**< The GATTC parameters for this message. */
+} write_params_t;
+
+/**@brief Structure for holding the data that will be transmitted to the connected central.
+ */
+typedef struct
+{
+ uint16_t conn_handle; /**< Connection handle to be used when transmitting this message. */
+ tx_request_t type; /**< Type of message. (read or write). */
+ union
+ {
+ uint16_t read_handle; /**< Read request handle. */
+ write_params_t write_req; /**< Write request message. */
+ } req;
+} tx_message_t;
+
+
+static tx_message_t m_tx_buffer[TX_BUFFER_SIZE]; /**< Transmit buffer for the messages that will be transmitted to the central. */
+static uint32_t m_tx_insert_index = 0; /**< Current index in the transmit buffer where the next message should be inserted. */
+static uint32_t m_tx_index = 0; /**< Current index in the transmit buffer containing the next message to be transmitted. */
+
+/**@brief Function for passing any pending request from the buffer to the stack.
+ */
+static void tx_buffer_process(void)
+{
+ if (m_tx_index != m_tx_insert_index)
+ {
+ uint32_t err_code;
+
+ if (m_tx_buffer[m_tx_index].type == READ_REQ)
+ {
+ err_code = sd_ble_gattc_read(m_tx_buffer[m_tx_index].conn_handle,
+ m_tx_buffer[m_tx_index].req.read_handle,
+ 0);
+ }
+ else
+ {
+ err_code = sd_ble_gattc_write(m_tx_buffer[m_tx_index].conn_handle,
+ &m_tx_buffer[m_tx_index].req.write_req.gattc_params);
+ }
+ if (err_code == NRF_SUCCESS)
+ {
+ NRF_LOG_DEBUG("SD Read/Write API returns Success..");
+ m_tx_index++;
+ m_tx_index &= TX_BUFFER_MASK;
+ }
+ else
+ {
+ NRF_LOG_DEBUG("SD Read/Write API returns error. This message sending will be "
+ "attempted again..");
+ }
+ }
+}
+
+
+/**@brief Function for handling write response events.
+ *
+ * @param[in] p_bas_c Pointer to the Battery Service Client Structure.
+ * @param[in] p_ble_evt Pointer to the SoftDevice event.
+ */
+static void on_write_rsp(ble_bas_c_t * p_bas_c, ble_evt_t const * p_ble_evt)
+{
+ // Check if the event if on the link for this instance
+ if (p_bas_c->conn_handle != p_ble_evt->evt.gattc_evt.conn_handle)
+ {
+ return;
+ }
+ // Check if there is any message to be sent across to the peer and send it.
+ tx_buffer_process();
+}
+
+
+/**@brief Function for handling read response events.
+ *
+ * @details This function will validate the read response and raise the appropriate
+ * event to the application.
+ *
+ * @param[in] p_bas_c Pointer to the Battery Service Client Structure.
+ * @param[in] p_ble_evt Pointer to the SoftDevice event.
+ */
+static void on_read_rsp(ble_bas_c_t * p_bas_c, ble_evt_t const * p_ble_evt)
+{
+ const ble_gattc_evt_read_rsp_t * p_response;
+
+ // Check if the event if on the link for this instance
+ if (p_bas_c->conn_handle != p_ble_evt->evt.gattc_evt.conn_handle)
+ {
+ return;
+ }
+
+ p_response = &p_ble_evt->evt.gattc_evt.params.read_rsp;
+
+ if (p_response->handle == p_bas_c->peer_bas_db.bl_handle)
+ {
+ ble_bas_c_evt_t evt;
+
+ evt.conn_handle = p_ble_evt->evt.gattc_evt.conn_handle;
+ evt.evt_type = BLE_BAS_C_EVT_BATT_READ_RESP;
+
+ evt.params.battery_level = p_response->data[0];
+
+ p_bas_c->evt_handler(p_bas_c, &evt);
+ }
+ // Check if there is any buffered transmissions and send them.
+ tx_buffer_process();
+}
+
+
+/**@brief Function for handling Handle Value Notification received from the SoftDevice.
+ *
+ * @details This function will handle the Handle Value Notification received from the SoftDevice
+ * and checks if it is a notification of the Battery Level measurement from the peer. If
+ * so, this function will decode the battery level measurement and send it to the
+ * application.
+ *
+ * @param[in] p_ble_bas_c Pointer to the Battery Service Client structure.
+ * @param[in] p_ble_evt Pointer to the BLE event received.
+ */
+static void on_hvx(ble_bas_c_t * p_ble_bas_c, ble_evt_t const * p_ble_evt)
+{
+ // Check if the event if on the link for this instance
+ if (p_ble_bas_c->conn_handle != p_ble_evt->evt.gattc_evt.conn_handle)
+ {
+ return;
+ }
+ // Check if this notification is a battery level notification.
+ if (p_ble_evt->evt.gattc_evt.params.hvx.handle == p_ble_bas_c->peer_bas_db.bl_handle)
+ {
+ if (p_ble_evt->evt.gattc_evt.params.hvx.len == 1)
+ {
+ ble_bas_c_evt_t ble_bas_c_evt;
+ ble_bas_c_evt.conn_handle = p_ble_evt->evt.gattc_evt.conn_handle;
+ ble_bas_c_evt.evt_type = BLE_BAS_C_EVT_BATT_NOTIFICATION;
+
+ ble_bas_c_evt.params.battery_level = p_ble_evt->evt.gattc_evt.params.hvx.data[0];
+
+ p_ble_bas_c->evt_handler(p_ble_bas_c, &ble_bas_c_evt);
+ }
+ }
+}
+
+
+void ble_bas_on_db_disc_evt(ble_bas_c_t * p_ble_bas_c, const ble_db_discovery_evt_t * p_evt)
+{
+ // Check if the Battery Service was discovered.
+ if (p_evt->evt_type == BLE_DB_DISCOVERY_COMPLETE
+ &&
+ p_evt->params.discovered_db.srv_uuid.uuid == BLE_UUID_BATTERY_SERVICE
+ &&
+ p_evt->params.discovered_db.srv_uuid.type == BLE_UUID_TYPE_BLE)
+ {
+ // Find the CCCD Handle of the Battery Level characteristic.
+ uint8_t i;
+
+ ble_bas_c_evt_t evt;
+ evt.evt_type = BLE_BAS_C_EVT_DISCOVERY_COMPLETE;
+ evt.conn_handle = p_evt->conn_handle;
+ for (i = 0; i < p_evt->params.discovered_db.char_count; i++)
+ {
+ if (p_evt->params.discovered_db.charateristics[i].characteristic.uuid.uuid ==
+ BLE_UUID_BATTERY_LEVEL_CHAR)
+ {
+ // Found Battery Level characteristic. Store CCCD handle and break.
+ evt.params.bas_db.bl_cccd_handle =
+ p_evt->params.discovered_db.charateristics[i].cccd_handle;
+ evt.params.bas_db.bl_handle =
+ p_evt->params.discovered_db.charateristics[i].characteristic.handle_value;
+ break;
+ }
+ }
+
+ NRF_LOG_DEBUG("Battery Service discovered at peer.");
+
+ //If the instance has been assigned prior to db_discovery, assign the db_handles
+ if (p_ble_bas_c->conn_handle != BLE_CONN_HANDLE_INVALID)
+ {
+ if ((p_ble_bas_c->peer_bas_db.bl_cccd_handle == BLE_GATT_HANDLE_INVALID)&&
+ (p_ble_bas_c->peer_bas_db.bl_handle == BLE_GATT_HANDLE_INVALID))
+ {
+ p_ble_bas_c->peer_bas_db = evt.params.bas_db;
+ }
+ }
+ p_ble_bas_c->evt_handler(p_ble_bas_c, &evt);
+ }
+ else
+ {
+ NRF_LOG_DEBUG("Battery Service discovery failure at peer. ");
+ }
+}
+
+
+/**@brief Function for creating a message for writing to the CCCD.
+ */
+static uint32_t cccd_configure(uint16_t conn_handle, uint16_t handle_cccd, bool notification_enable)
+{
+ NRF_LOG_DEBUG("Configuring CCCD. CCCD Handle = %d, Connection Handle = %d",
+ handle_cccd,conn_handle);
+
+ tx_message_t * p_msg;
+ uint16_t cccd_val = notification_enable ? BLE_GATT_HVX_NOTIFICATION : 0;
+
+ p_msg = &m_tx_buffer[m_tx_insert_index++];
+ m_tx_insert_index &= TX_BUFFER_MASK;
+
+ p_msg->req.write_req.gattc_params.handle = handle_cccd;
+ p_msg->req.write_req.gattc_params.len = WRITE_MESSAGE_LENGTH;
+ p_msg->req.write_req.gattc_params.p_value = p_msg->req.write_req.gattc_value;
+ p_msg->req.write_req.gattc_params.offset = 0;
+ p_msg->req.write_req.gattc_params.write_op = BLE_GATT_OP_WRITE_REQ;
+ p_msg->req.write_req.gattc_value[0] = LSB_16(cccd_val);
+ p_msg->req.write_req.gattc_value[1] = MSB_16(cccd_val);
+ p_msg->conn_handle = conn_handle;
+ p_msg->type = WRITE_REQ;
+
+ tx_buffer_process();
+ return NRF_SUCCESS;
+}
+
+
+uint32_t ble_bas_c_init(ble_bas_c_t * p_ble_bas_c, ble_bas_c_init_t * p_ble_bas_c_init)
+{
+ VERIFY_PARAM_NOT_NULL(p_ble_bas_c);
+ VERIFY_PARAM_NOT_NULL(p_ble_bas_c_init);
+
+ ble_uuid_t bas_uuid;
+
+ bas_uuid.type = BLE_UUID_TYPE_BLE;
+ bas_uuid.uuid = BLE_UUID_BATTERY_SERVICE;
+
+ p_ble_bas_c->conn_handle = BLE_CONN_HANDLE_INVALID;
+ p_ble_bas_c->peer_bas_db.bl_cccd_handle = BLE_GATT_HANDLE_INVALID;
+ p_ble_bas_c->peer_bas_db.bl_handle = BLE_GATT_HANDLE_INVALID;
+ p_ble_bas_c->evt_handler = p_ble_bas_c_init->evt_handler;
+
+ return ble_db_discovery_evt_register(&bas_uuid);
+}
+
+
+/**@brief Function for handling Disconnected event received from the SoftDevice.
+ *
+ * @details This function check if the disconnect event is happening on the link
+ * associated with the current instance of the module, if so it will set its
+ * conn_handle to invalid.
+ *
+ * @param[in] p_ble_bas_c Pointer to the Battery Service Client structure.
+ * @param[in] p_ble_evt Pointer to the BLE event received.
+ */
+static void on_disconnected(ble_bas_c_t * p_ble_bas_c, const ble_evt_t * p_ble_evt)
+{
+ if (p_ble_bas_c->conn_handle == p_ble_evt->evt.gap_evt.conn_handle)
+ {
+ p_ble_bas_c->conn_handle = BLE_CONN_HANDLE_INVALID;
+ p_ble_bas_c->peer_bas_db.bl_cccd_handle = BLE_GATT_HANDLE_INVALID;
+ p_ble_bas_c->peer_bas_db.bl_handle = BLE_GATT_HANDLE_INVALID;
+ }
+}
+
+
+void ble_bas_c_on_ble_evt(ble_evt_t const * p_ble_evt, void * p_context)
+{
+ if ((p_ble_evt == NULL) || (p_context == NULL))
+ {
+ return;
+ }
+
+ ble_bas_c_t * p_ble_bas_c = (ble_bas_c_t *)p_context;
+
+ switch (p_ble_evt->header.evt_id)
+ {
+ case BLE_GATTC_EVT_HVX:
+ on_hvx(p_ble_bas_c, p_ble_evt);
+ break;
+
+ case BLE_GATTC_EVT_WRITE_RSP:
+ on_write_rsp(p_ble_bas_c, p_ble_evt);
+ break;
+
+ case BLE_GATTC_EVT_READ_RSP:
+ on_read_rsp(p_ble_bas_c, p_ble_evt);
+ break;
+
+ case BLE_GAP_EVT_DISCONNECTED:
+ on_disconnected(p_ble_bas_c, p_ble_evt);
+ break;
+
+ default:
+ break;
+ }
+}
+
+
+uint32_t ble_bas_c_bl_notif_enable(ble_bas_c_t * p_ble_bas_c)
+{
+ VERIFY_PARAM_NOT_NULL(p_ble_bas_c);
+
+ if (p_ble_bas_c->conn_handle == BLE_CONN_HANDLE_INVALID)
+ {
+ return NRF_ERROR_INVALID_STATE;
+ }
+
+ return cccd_configure(p_ble_bas_c->conn_handle, p_ble_bas_c->peer_bas_db.bl_cccd_handle, true);
+}
+
+
+uint32_t ble_bas_c_bl_read(ble_bas_c_t * p_ble_bas_c)
+{
+ VERIFY_PARAM_NOT_NULL(p_ble_bas_c);
+ if (p_ble_bas_c->conn_handle == BLE_CONN_HANDLE_INVALID)
+ {
+ return NRF_ERROR_INVALID_STATE;
+ }
+
+ tx_message_t * msg;
+
+ msg = &m_tx_buffer[m_tx_insert_index++];
+ m_tx_insert_index &= TX_BUFFER_MASK;
+
+ msg->req.read_handle = p_ble_bas_c->peer_bas_db.bl_handle;
+ msg->conn_handle = p_ble_bas_c->conn_handle;
+ msg->type = READ_REQ;
+
+ tx_buffer_process();
+ return NRF_SUCCESS;
+}
+
+
+uint32_t ble_bas_c_handles_assign(ble_bas_c_t * p_ble_bas_c,
+ uint16_t conn_handle,
+ ble_bas_c_db_t * p_peer_handles)
+{
+ VERIFY_PARAM_NOT_NULL(p_ble_bas_c);
+
+ p_ble_bas_c->conn_handle = conn_handle;
+ if (p_peer_handles != NULL)
+ {
+ p_ble_bas_c->peer_bas_db = *p_peer_handles;
+ }
+ return NRF_SUCCESS;
+}
+#endif // NRF_MODULE_ENABLED(BLE_BAS_C)
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/ble_bas_c/ble_bas_c.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/ble_bas_c/ble_bas_c.h
new file mode 100644
index 0000000..10eb126
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/ble_bas_c/ble_bas_c.h
@@ -0,0 +1,274 @@
+/**
+ * Copyright (c) 2012 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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
+ *
+ * @defgroup ble_bas_c Battery Service Client
+ * @{
+ * @ingroup ble_sdk_srv
+ * @brief Battery Service Client module.
+ *
+ * @details This module contains APIs to read and interact with the Battery Service of a remote
+ * device.
+ *
+ * @note The application must register this module as BLE event observer using the
+ * NRF_SDH_BLE_OBSERVER macro. Example:
+ * @code
+ * ble_bas_c_t instance;
+ * NRF_SDH_BLE_OBSERVER(anything, BLE_BAS_C_BLE_OBSERVER_PRIO,
+ * ble_bas_c_on_ble_evt, &instance);
+ * @endcode
+ */
+
+#ifndef BLE_BAS_C_H__
+#define BLE_BAS_C_H__
+
+#include <stdint.h>
+#include "ble.h"
+#include "ble_db_discovery.h"
+#include "nrf_sdh_ble.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**@brief Macro for defining a ble_bas_c instance.
+ *
+ * @param _name Name of the instance.
+ * @hideinitializer
+ */
+#define BLE_BAS_C_DEF(_name) \
+static ble_bas_c_t _name; \
+NRF_SDH_BLE_OBSERVER(_name ## _obs, \
+ BLE_BAS_C_BLE_OBSERVER_PRIO, \
+ ble_bas_c_on_ble_evt, &_name)
+
+/** @brief Macro for defining multiple ble_bas_c instances.
+ *
+ * @param _name Name of the array of instances.
+ * @param _cnt Number of instances to define.
+ * @hideinitializer
+ */
+#define BLE_BAS_C_ARRAY_DEF(_name, _cnt) \
+static ble_bas_c_t _name[_cnt]; \
+NRF_SDH_BLE_OBSERVERS(_name ## _obs, \
+ BLE_BAS_C_BLE_OBSERVER_PRIO, \
+ ble_bas_c_on_ble_evt, &_name, _cnt)
+
+/**
+ * @defgroup bas_c_enums Enumerations
+ * @{
+ */
+
+/**@brief Battery Service Client event type. */
+typedef enum
+{
+ BLE_BAS_C_EVT_DISCOVERY_COMPLETE, /**< Event indicating that the Battery Service has been discovered at the peer. */
+ BLE_BAS_C_EVT_BATT_NOTIFICATION, /**< Event indicating that a notification of the Battery Level characteristic has been received from the peer. */
+ BLE_BAS_C_EVT_BATT_READ_RESP /**< Event indicating that a read response on Battery Level characteristic has been received from peer. */
+} ble_bas_c_evt_type_t;
+
+/** @} */
+
+/**
+ * @defgroup bas_c_structs Structures
+ * @{
+ */
+
+/**@brief Structure containing the handles related to the Battery Service found on the peer. */
+typedef struct
+{
+ uint16_t bl_cccd_handle; /**< Handle of the CCCD of the Battery Level characteristic. */
+ uint16_t bl_handle; /**< Handle of the Battery Level characteristic as provided by the SoftDevice. */
+} ble_bas_c_db_t;
+
+/**@brief Battery Service Client Event structure. */
+typedef struct
+{
+ ble_bas_c_evt_type_t evt_type; /**< Event Type. */
+ uint16_t conn_handle; /**< Connection handle relevent to this event.*/
+ union
+ {
+ ble_bas_c_db_t bas_db; /**< Battery Service related handles found on the peer device. This will be filled if the evt_type is @ref BLE_BAS_C_EVT_DISCOVERY_COMPLETE.*/
+ uint8_t battery_level; /**< Battery level received from peer. This field will be used for the events @ref BLE_BAS_C_EVT_BATT_NOTIFICATION and @ref BLE_BAS_C_EVT_BATT_READ_RESP.*/
+ } params;
+} ble_bas_c_evt_t;
+
+/** @} */
+
+/**
+ * @defgroup bas_c_types Types
+ * @{
+ */
+
+// Forward declaration of the ble_bas_t type.
+typedef struct ble_bas_c_s ble_bas_c_t;
+
+/**@brief Event handler type.
+ *
+ * @details This is the type of the event handler that should be provided by the application
+ * of this module in order to receive events.
+ */
+typedef void (* ble_bas_c_evt_handler_t) (ble_bas_c_t * p_bas_bas_c, ble_bas_c_evt_t * p_evt);
+
+/** @} */
+
+/**
+ * @addtogroup bas_c_structs
+ * @{
+ */
+
+/**@brief Battery Service Client structure. */
+struct ble_bas_c_s
+{
+ uint16_t conn_handle; /**< Connection handle as provided by the SoftDevice. */
+ ble_bas_c_db_t peer_bas_db; /**< Handles related to BAS on the peer*/
+ ble_bas_c_evt_handler_t evt_handler; /**< Application event handler to be called when there is an event related to the Battery service. */
+};
+
+/**@brief Battery Service Client initialization structure. */
+typedef struct
+{
+ ble_bas_c_evt_handler_t evt_handler; /**< Event handler to be called by the Battery Service Client module whenever there is an event related to the Battery Service. */
+} ble_bas_c_init_t;
+
+/** @} */
+
+/**
+ * @defgroup bas_c_functions Functions
+ * @{
+ */
+
+/**@brief Function for initializing the Battery Service Client module.
+ *
+ * @details This function will initialize the module and set up Database Discovery to discover
+ * the Battery Service. After calling this function, call @ref ble_db_discovery_start
+ * to start discovery once a link with a peer has been established.
+ *
+ * @param[out] p_ble_bas_c Pointer to the Battery Service client structure.
+ * @param[in] p_ble_bas_c_init Pointer to the Battery Service initialization structure containing
+ * the initialization information.
+ *
+ * @retval NRF_SUCCESS Operation success.
+ * @retval NRF_ERROR_NULL A parameter is NULL.
+ * Otherwise, an error code returned by @ref ble_db_discovery_evt_register.
+ */
+uint32_t ble_bas_c_init(ble_bas_c_t * p_ble_bas_c, ble_bas_c_init_t * p_ble_bas_c_init);
+
+
+/**@brief Function for handling BLE events from the SoftDevice.
+ *
+ * @details This function will handle the BLE events received from the SoftDevice. If the BLE
+ * event is relevant for the Battery Service Client module, then it is used to update
+ * interval variables and, if necessary, send events to the application.
+ *
+ * @note This function must be called by the application.
+ *
+ * @param[in] p_ble_evt Pointer to the BLE event.
+ * @param[in] p_context Pointer to the Battery Service client structure.
+ */
+void ble_bas_c_on_ble_evt(ble_evt_t const * p_ble_evt, void * p_context);
+
+
+/**@brief Function for enabling notifications on the Battery Level characteristic.
+ *
+ * @details This function will enable to notification of the Battery Level characteristic at the
+ * peer by writing to the CCCD of the Battery Level Characteristic.
+ *
+ * @param p_ble_bas_c Pointer to the Battery Service client structure.
+ *
+ * @retval NRF_SUCCESS If the SoftDevice has been requested to write to the CCCD of the peer.
+ * NRF_ERROR_NULL Parameter is NULL.
+ * Otherwise, an error code returned by the SoftDevice API @ref
+ * sd_ble_gattc_write.
+ */
+uint32_t ble_bas_c_bl_notif_enable(ble_bas_c_t * p_ble_bas_c);
+
+
+/**@brief Function for reading the Battery Level characteristic.
+ *
+ * @param p_ble_bas_c Pointer to the Battery Service client structure.
+ *
+ * @retval NRF_SUCCESS If the read request was successfully queued to be sent to peer.
+ */
+uint32_t ble_bas_c_bl_read(ble_bas_c_t * p_ble_bas_c);
+
+
+/**@brief Function for handling events from the database discovery module.
+ *
+ * @details Call this function when getting a callback event from the DB discovery modue.
+ * This function will handle an event from the database discovery module, and determine
+ * if it relates to the discovery of Battery service at the peer. If so, it will
+ * call the application's event handler indicating that the Battery service has been
+ * discovered at the peer. It also populates the event with the service related
+ * information before providing it to the application.
+ *
+ * @param p_ble_bas_c Pointer to the Battery Service client structure.
+ * @param[in] p_evt Pointer to the event received from the database discovery module.
+ *
+ */
+void ble_bas_on_db_disc_evt(ble_bas_c_t * p_ble_bas_c, ble_db_discovery_evt_t const * p_evt);
+
+
+/**@brief Function for assigning handles to a this instance of bas_c.
+ *
+ * @details Call this function when a link has been established with a peer to
+ * associate this link to this instance of the module. This makes it
+ * possible to handle several link and associate each link to a particular
+ * instance of this module. The connection handle and attribute handles will be
+ * provided from the discovery event @ref BLE_BAS_C_EVT_DISCOVERY_COMPLETE.
+ *
+ * @param[in] p_ble_bas_c Pointer to the Battery client structure instance to associate.
+ * @param[in] conn_handle Connection handle to associated with the given Battery Client Instance.
+ * @param[in] p_peer_handles Attribute handles on the BAS server you want this BAS client to
+ * interact with.
+ */
+uint32_t ble_bas_c_handles_assign(ble_bas_c_t * p_ble_bas_c,
+ uint16_t conn_handle,
+ ble_bas_c_db_t * p_peer_handles);
+
+/** @} */ // End tag for Function group.
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // BLE_BAS_C_H__
+
+/** @} */ // End tag for the file.
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/ble_bps/ble_bps.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/ble_bps/ble_bps.c
new file mode 100644
index 0000000..c96bad1
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/ble_bps/ble_bps.c
@@ -0,0 +1,475 @@
+/**
+ * Copyright (c) 2012 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+/* Attention!
+ * To maintain compliance with Nordic Semiconductor ASA's Bluetooth profile
+ * qualification listings, this section of source code must not be modified.
+ */
+#include "sdk_common.h"
+#if NRF_MODULE_ENABLED(BLE_BPS)
+#include "ble_bps.h"
+#include "ble_err.h"
+#include <string.h>
+#include "nordic_common.h"
+#include "ble_srv_common.h"
+
+
+#define OPCODE_LENGTH 1 /**< Length of opcode inside Blood Pressure Measurement packet. */
+#define HANDLE_LENGTH 2 /**< Length of handle inside Blood Pressure Measurement packet. */
+#define MAX_BPM_LEN (BLE_GATT_ATT_MTU_DEFAULT - OPCODE_LENGTH - HANDLE_LENGTH) /**< Maximum size of a transmitted Blood Pressure Measurement. */
+
+// Blood Pressure Measurement Flags bits
+#define BPS_MEAS_BLOOD_PRESSURE_UNITS_FLAG_BIT (0x01 << 0) /**< Blood Pressure Units Flag bit. */
+#define BPS_MEAS_TIME_STAMP_FLAG_BIT (0x01 << 1) /**< Time Stamp Flag bit. */
+#define BPS_MEAS_PULSE_RATE_FLAG_BIT (0x01 << 2) /**< Pulse Rate Flag bit. */
+#define BPS_MEAS_USER_ID_FLAG_BIT (0x01 << 3) /**< User ID Flag bit. */
+#define BPS_MEAS_MEASUREMENT_STATUS_FLAG_BIT (0x01 << 4) /**< Measurement Status Flag bit. */
+
+
+/**@brief Function for handling the Connect event.
+ *
+ * @param[in] p_bps Blood Pressure Service structure.
+ * @param[in] p_ble_evt Event received from the BLE stack.
+ */
+static void on_connect(ble_bps_t * p_bps, ble_evt_t const * p_ble_evt)
+{
+ p_bps->conn_handle = p_ble_evt->evt.gatts_evt.conn_handle;
+}
+
+
+/**@brief Function for handling the Disconnect event.
+ *
+ * @param[in] p_bps Blood Pressure Service structure.
+ * @param[in] p_ble_evt Event received from the BLE stack.
+ */
+static void on_disconnect(ble_bps_t * p_bps, ble_evt_t const * p_ble_evt)
+{
+ UNUSED_PARAMETER(p_ble_evt);
+ p_bps->conn_handle = BLE_CONN_HANDLE_INVALID;
+}
+
+
+/**@brief Function for handling the write events to the Blood Pressure Measurement characteristic.
+ *
+ * @param[in] p_bps Blood Pressure Service structure.
+ * @param[in] p_evt_write Write event received from the BLE stack.
+ */
+static void on_cccd_write(ble_bps_t * p_bps, ble_gatts_evt_write_t const * p_evt_write)
+{
+ if (p_evt_write->len == 2)
+ {
+ // CCCD written, update indication state
+ if (p_bps->evt_handler != NULL)
+ {
+ ble_bps_evt_t evt;
+
+ if (ble_srv_is_indication_enabled(p_evt_write->data))
+ {
+ evt.evt_type = BLE_BPS_EVT_INDICATION_ENABLED;
+ }
+ else
+ {
+ evt.evt_type = BLE_BPS_EVT_INDICATION_DISABLED;
+ }
+
+ p_bps->evt_handler(p_bps, &evt);
+ }
+ }
+}
+
+
+/**@brief Function for handling the Write event.
+ *
+ * @param[in] p_bps Blood Pressure Service structure.
+ * @param[in] p_ble_evt Event received from the BLE stack.
+ */
+static void on_write(ble_bps_t * p_bps, ble_evt_t const * p_ble_evt)
+{
+ ble_gatts_evt_write_t const * p_evt_write = &p_ble_evt->evt.gatts_evt.params.write;
+
+ if (p_evt_write->handle == p_bps->meas_handles.cccd_handle)
+ {
+ on_cccd_write(p_bps, p_evt_write);
+ }
+}
+
+
+/**@brief Function for handling the HVC event.
+ *
+ * @details Handles HVC events from the BLE stack.
+ *
+ * @param[in] p_bps Blood Pressure Service structure.
+ * @param[in] p_ble_evt Event received from the BLE stack.
+ */
+static void on_hvc(ble_bps_t * p_bps, ble_evt_t const * p_ble_evt)
+{
+ ble_gatts_evt_hvc_t const * p_hvc = &p_ble_evt->evt.gatts_evt.params.hvc;
+
+ if (p_hvc->handle == p_bps->meas_handles.value_handle)
+ {
+ ble_bps_evt_t evt;
+
+ evt.evt_type = BLE_BPS_EVT_INDICATION_CONFIRMED;
+ p_bps->evt_handler(p_bps, &evt);
+ }
+}
+
+
+void ble_bps_on_ble_evt(ble_evt_t const * p_ble_evt, void * p_context)
+{
+ ble_bps_t * p_bps = (ble_bps_t *)p_context;
+
+ switch (p_ble_evt->header.evt_id)
+ {
+ case BLE_GAP_EVT_CONNECTED:
+ on_connect(p_bps, p_ble_evt);
+ break;
+
+ case BLE_GAP_EVT_DISCONNECTED:
+ on_disconnect(p_bps, p_ble_evt);
+ break;
+
+ case BLE_GATTS_EVT_WRITE:
+ on_write(p_bps, p_ble_evt);
+ break;
+
+ case BLE_GATTS_EVT_HVC:
+ on_hvc(p_bps, p_ble_evt);
+ break;
+
+ default:
+ // No implementation needed.
+ break;
+ }
+}
+
+
+/**@brief Function for encoding a Blood Pressure Measurement.
+ *
+ * @param[in] p_bps Blood Pressure Service structure.
+ * @param[in] p_bps_meas Measurement to be encoded.
+ * @param[out] p_encoded_buffer Buffer where the encoded data will be written.
+ *
+ * @return Size of encoded data.
+ */
+static uint8_t bps_measurement_encode(ble_bps_t * p_bps,
+ ble_bps_meas_t * p_bps_meas,
+ uint8_t * p_encoded_buffer)
+{
+ uint8_t flags = 0;
+ uint8_t len = 1;
+ uint16_t encoded_sfloat;
+
+ // Set measurement units flag
+ if (p_bps_meas->blood_pressure_units_in_kpa)
+ {
+ flags |= BPS_MEAS_BLOOD_PRESSURE_UNITS_FLAG_BIT;
+ }
+
+ // Blood Pressure Measurement - Systolic
+ encoded_sfloat = ((p_bps_meas->blood_pressure_systolic.exponent << 12) & 0xF000) |
+ ((p_bps_meas->blood_pressure_systolic.mantissa << 0) & 0x0FFF);
+ len += uint16_encode(encoded_sfloat, &p_encoded_buffer[len]);
+
+ // Blood Pressure Measurement - Diastolic
+ encoded_sfloat = ((p_bps_meas->blood_pressure_diastolic.exponent << 12) & 0xF000) |
+ ((p_bps_meas->blood_pressure_diastolic.mantissa << 0) & 0x0FFF);
+ len += uint16_encode(encoded_sfloat, &p_encoded_buffer[len]);
+
+ // Blood Pressure Measurement - Mean Arterial Pressure
+ encoded_sfloat = ((p_bps_meas->mean_arterial_pressure.exponent << 12) & 0xF000) |
+ ((p_bps_meas->mean_arterial_pressure.mantissa << 0) & 0x0FFF);
+ len += uint16_encode(encoded_sfloat, &p_encoded_buffer[len]);
+
+ // Time Stamp field
+ if (p_bps_meas->time_stamp_present)
+ {
+ flags |= BPS_MEAS_TIME_STAMP_FLAG_BIT;
+ len += ble_date_time_encode(&p_bps_meas->time_stamp, &p_encoded_buffer[len]);
+ }
+
+ // Pulse Rate
+ if (p_bps_meas->pulse_rate_present)
+ {
+ flags |= BPS_MEAS_PULSE_RATE_FLAG_BIT;
+
+ encoded_sfloat = ((p_bps_meas->pulse_rate.exponent << 12) & 0xF000) |
+ ((p_bps_meas->pulse_rate.mantissa << 0) & 0x0FFF);
+ len += uint16_encode(encoded_sfloat, &p_encoded_buffer[len]);
+ }
+
+ // User ID
+ if (p_bps_meas->user_id_present)
+ {
+ flags |= BPS_MEAS_USER_ID_FLAG_BIT;
+ p_encoded_buffer[len++] = p_bps_meas->user_id;
+ }
+
+ // Measurement Status
+ if (p_bps_meas->measurement_status_present)
+ {
+ flags |= BPS_MEAS_MEASUREMENT_STATUS_FLAG_BIT;
+ len += uint16_encode(p_bps_meas->measurement_status, &p_encoded_buffer[len]);
+ }
+
+ // Flags field
+ p_encoded_buffer[0] = flags;
+
+ return len;
+}
+
+
+/**@brief Function for adding Blood Pressure Measurement characteristics.
+ *
+ * @param[in] p_bps Blood Pressure Service structure.
+ * @param[in] p_bps_init Information needed to initialize the service.
+ *
+ * @return NRF_SUCCESS on success, otherwise an error code.
+ */
+static uint32_t bps_measurement_char_add(ble_bps_t * p_bps, ble_bps_init_t const * p_bps_init)
+{
+ ble_gatts_char_md_t char_md;
+ ble_gatts_attr_md_t cccd_md;
+ ble_gatts_attr_t attr_char_value;
+ ble_uuid_t ble_uuid;
+ ble_gatts_attr_md_t attr_md;
+ ble_bps_meas_t initial_bpm;
+ uint8_t encoded_bpm[MAX_BPM_LEN];
+
+ memset(&cccd_md, 0, sizeof(cccd_md));
+
+ BLE_GAP_CONN_SEC_MODE_SET_OPEN(&cccd_md.read_perm);
+ cccd_md.vloc = BLE_GATTS_VLOC_STACK;
+ cccd_md.write_perm = p_bps_init->bps_meas_attr_md.cccd_write_perm;
+
+ memset(&char_md, 0, sizeof(char_md));
+
+ char_md.char_props.indicate = 1;
+ char_md.p_char_user_desc = NULL;
+ char_md.p_char_pf = NULL;
+ char_md.p_user_desc_md = NULL;
+ char_md.p_cccd_md = &cccd_md;
+ char_md.p_sccd_md = NULL;
+
+ BLE_UUID_BLE_ASSIGN(ble_uuid, BLE_UUID_BLOOD_PRESSURE_MEASUREMENT_CHAR);
+
+ memset(&attr_md, 0, sizeof(attr_md));
+
+ attr_md.vloc = BLE_GATTS_VLOC_STACK;
+ attr_md.read_perm = p_bps_init->bps_meas_attr_md.read_perm;
+ attr_md.write_perm = p_bps_init->bps_meas_attr_md.write_perm;
+ attr_md.rd_auth = 0;
+ attr_md.wr_auth = 0;
+ attr_md.vlen = 1;
+
+ memset(&attr_char_value, 0, sizeof(attr_char_value));
+ memset(&initial_bpm, 0, sizeof(initial_bpm));
+
+ attr_char_value.p_uuid = &ble_uuid;
+ attr_char_value.p_attr_md = &attr_md;
+ attr_char_value.init_len = bps_measurement_encode(p_bps, &initial_bpm, encoded_bpm);
+ attr_char_value.init_offs = 0;
+ attr_char_value.max_len = MAX_BPM_LEN;
+ attr_char_value.p_value = encoded_bpm;
+
+ return sd_ble_gatts_characteristic_add(p_bps->service_handle,
+ &char_md,
+ &attr_char_value,
+ &p_bps->meas_handles);
+}
+
+
+/**@brief Function for adding Blood Pressure Feature characteristics.
+ *
+ * @param[in] p_bps Blood Pressure Service structure.
+ * @param[in] p_bps_init Information needed to initialize the service.
+ *
+ * @return NRF_SUCCESS on success, otherwise an error code.
+ */
+static uint32_t bps_feature_char_add(ble_bps_t * p_bps, ble_bps_init_t const * p_bps_init)
+{
+ ble_gatts_char_md_t char_md;
+ ble_gatts_attr_t attr_char_value;
+ ble_uuid_t ble_uuid;
+ ble_gatts_attr_md_t attr_md;
+ uint8_t init_value_encoded[2];
+ uint8_t init_value_len;
+
+ memset(&char_md, 0, sizeof(char_md));
+
+ char_md.char_props.read = 1;
+ char_md.p_char_user_desc = NULL;
+ char_md.p_char_pf = NULL;
+ char_md.p_user_desc_md = NULL;
+ char_md.p_cccd_md = NULL;
+ char_md.p_sccd_md = NULL;
+
+ BLE_UUID_BLE_ASSIGN(ble_uuid, BLE_UUID_BLOOD_PRESSURE_FEATURE_CHAR);
+
+ memset(&attr_md, 0, sizeof(attr_md));
+
+ attr_md.vloc = BLE_GATTS_VLOC_STACK;
+ attr_md.read_perm = p_bps_init->bps_feature_attr_md.read_perm;
+ attr_md.write_perm = p_bps_init->bps_feature_attr_md.write_perm;
+ attr_md.rd_auth = 0;
+ attr_md.wr_auth = 0;
+ attr_md.vlen = 0;
+
+ memset(&attr_char_value, 0, sizeof(attr_char_value));
+
+ init_value_len = uint16_encode(p_bps_init->feature, init_value_encoded);
+
+ attr_char_value.p_uuid = &ble_uuid;
+ attr_char_value.p_attr_md = &attr_md;
+ attr_char_value.init_len = init_value_len;
+ attr_char_value.init_offs = 0;
+ attr_char_value.max_len = init_value_len;
+ attr_char_value.p_value = init_value_encoded;
+
+ return sd_ble_gatts_characteristic_add(p_bps->service_handle,
+ &char_md,
+ &attr_char_value,
+ &p_bps->feature_handles);
+}
+
+
+uint32_t ble_bps_init(ble_bps_t * p_bps, ble_bps_init_t const * p_bps_init)
+{
+ uint32_t err_code;
+ ble_uuid_t ble_uuid;
+
+ // Initialize service structure
+ p_bps->evt_handler = p_bps_init->evt_handler;
+ p_bps->conn_handle = BLE_CONN_HANDLE_INVALID;
+ p_bps->feature = p_bps_init->feature;
+
+ // Add service
+ BLE_UUID_BLE_ASSIGN(ble_uuid, BLE_UUID_BLOOD_PRESSURE_SERVICE);
+
+ err_code = sd_ble_gatts_service_add(BLE_GATTS_SRVC_TYPE_PRIMARY, &ble_uuid, &p_bps->service_handle);
+ if (err_code != NRF_SUCCESS)
+ {
+ return err_code;
+ }
+
+ // Add measurement characteristic
+ err_code = bps_measurement_char_add(p_bps, p_bps_init);
+ if (err_code != NRF_SUCCESS)
+ {
+ return err_code;
+ }
+
+ // Add feature characteristic
+ err_code = bps_feature_char_add(p_bps, p_bps_init);
+ if (err_code != NRF_SUCCESS)
+ {
+ return err_code;
+ }
+
+ return NRF_SUCCESS;
+}
+
+
+uint32_t ble_bps_measurement_send(ble_bps_t * p_bps, ble_bps_meas_t * p_bps_meas)
+{
+ uint32_t err_code;
+
+ // Send value if connected
+ if (p_bps->conn_handle != BLE_CONN_HANDLE_INVALID)
+ {
+ uint8_t encoded_bps_meas[MAX_BPM_LEN];
+ uint16_t len;
+ uint16_t hvx_len;
+ ble_gatts_hvx_params_t hvx_params;
+
+ len = bps_measurement_encode(p_bps, p_bps_meas, encoded_bps_meas);
+ hvx_len = len;
+
+ memset(&hvx_params, 0, sizeof(hvx_params));
+
+ hvx_params.handle = p_bps->meas_handles.value_handle;
+ hvx_params.type = BLE_GATT_HVX_INDICATION;
+ hvx_params.offset = 0;
+ hvx_params.p_len = &hvx_len;
+ hvx_params.p_data = encoded_bps_meas;
+
+ err_code = sd_ble_gatts_hvx(p_bps->conn_handle, &hvx_params);
+ if ((err_code == NRF_SUCCESS) && (hvx_len != len))
+ {
+ err_code = NRF_ERROR_DATA_SIZE;
+ }
+ }
+ else
+ {
+ err_code = NRF_ERROR_INVALID_STATE;
+ }
+
+ return err_code;
+}
+
+
+uint32_t ble_bps_is_indication_enabled(ble_bps_t * p_bps, bool * p_indication_enabled)
+{
+ uint32_t err_code;
+ uint8_t cccd_value_buf[BLE_CCCD_VALUE_LEN];
+ ble_gatts_value_t gatts_value;
+
+ // Initialize value struct.
+ memset(&gatts_value, 0, sizeof(gatts_value));
+
+ gatts_value.len = BLE_CCCD_VALUE_LEN;
+ gatts_value.offset = 0;
+ gatts_value.p_value = cccd_value_buf;
+
+ err_code = sd_ble_gatts_value_get(p_bps->conn_handle,
+ p_bps->meas_handles.cccd_handle,
+ &gatts_value);
+
+ if (err_code == NRF_SUCCESS)
+ {
+ *p_indication_enabled = ble_srv_is_indication_enabled(cccd_value_buf);
+ }
+ if (err_code == BLE_ERROR_GATTS_SYS_ATTR_MISSING)
+ {
+ *p_indication_enabled = false;
+ return NRF_SUCCESS;
+ }
+ return err_code;
+}
+#endif // NRF_MODULE_ENABLED(BLE_BPS)
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/ble_bps/ble_bps.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/ble_bps/ble_bps.h
new file mode 100644
index 0000000..b0cb4ad
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/ble_bps/ble_bps.h
@@ -0,0 +1,221 @@
+/**
+ * Copyright (c) 2012 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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
+ *
+ * @defgroup ble_bps Blood Pressure Service
+ * @{
+ * @ingroup ble_sdk_srv
+ * @brief Blood Pressure Service module.
+ *
+ * @details This module implements the Blood Pressure Service.
+ *
+ * If an event handler is supplied by the application, the Blood Pressure
+ * Service will generate Blood Pressure Service events to the application.
+ *
+ * @note The application must register this module as BLE event observer using the
+ * NRF_SDH_BLE_OBSERVER macro. Example:
+ * @code
+ * ble_bps_t instance;
+ * NRF_SDH_BLE_OBSERVER(anything, BLE_BPS_BLE_OBSERVER_PRIO,
+ * ble_bps_on_ble_evt, &instance);
+ * @endcode
+ *
+ * @note Attention!
+ * To maintain compliance with Nordic Semiconductor ASA Bluetooth profile
+ * qualification listings, this section of source code must not be modified.
+ */
+
+#ifndef BLE_BPS_H__
+#define BLE_BPS_H__
+
+#include <stdint.h>
+#include <stdbool.h>
+#include "ble.h"
+#include "ble_srv_common.h"
+#include "ble_date_time.h"
+#include "nrf_sdh_ble.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**@brief Macro for defining a ble_bps instance.
+ *
+ * @param _name Name of the instance.
+ * @hideinitializer
+ */
+#define BLE_BPS_DEF(_name) \
+static ble_bps_t _name; \
+NRF_SDH_BLE_OBSERVER(_name ## _obs, \
+ BLE_BPS_BLE_OBSERVER_PRIO, \
+ ble_bps_on_ble_evt, &_name)
+
+
+// Blood Pressure Feature bits
+#define BLE_BPS_FEATURE_BODY_MOVEMENT_BIT (0x01 << 0) /**< Body Movement Detection Support bit. */
+#define BLE_BPS_FEATURE_CUFF_FIT_BIT (0x01 << 1) /**< Cuff Fit Detection Support bit. */
+#define BLE_BPS_FEATURE_IRREGULAR_PULSE_BIT (0x01 << 2) /**< Irregular Pulse Detection Support bit. */
+#define BLE_BPS_FEATURE_PULSE_RATE_RANGE_BIT (0x01 << 3) /**< Pulse Rate Range Detection Support bit. */
+#define BLE_BPS_FEATURE_MEASUREMENT_POSITION_BIT (0x01 << 4) /**< Measurement Position Detection Support bit. */
+#define BLE_BPS_FEATURE_MULTIPLE_BOND_BIT (0x01 << 5) /**< Multiple Bond Support bit. */
+
+
+/**@brief Blood Pressure Service event type. */
+typedef enum
+{
+ BLE_BPS_EVT_INDICATION_ENABLED, /**< Blood Pressure value indication enabled event. */
+ BLE_BPS_EVT_INDICATION_DISABLED, /**< Blood Pressure value indication disabled event. */
+ BLE_BPS_EVT_INDICATION_CONFIRMED /**< Confirmation of a blood pressure measurement indication has been received. */
+} ble_bps_evt_type_t;
+
+/**@brief Blood Pressure Service event. */
+typedef struct
+{
+ ble_bps_evt_type_t evt_type; /**< Type of event. */
+} ble_bps_evt_t;
+
+// Forward declaration of the ble_bps_t type.
+typedef struct ble_bps_s ble_bps_t;
+
+/**@brief Blood Pressure Service event handler type. */
+typedef void (*ble_bps_evt_handler_t) (ble_bps_t * p_bps, ble_bps_evt_t * p_evt);
+
+/**@brief SFLOAT format (IEEE-11073 16-bit FLOAT, defined as a 16-bit vlue with 12-bit mantissa and
+ * 4-bit exponent. */
+typedef struct
+{
+ int8_t exponent; /**< Base 10 exponent, only 4 bits */
+ int16_t mantissa; /**< Mantissa, only 12 bits */
+} ieee_float16_t;
+
+/**@brief Blood Pressure Service init structure. This contains all options and data
+ * needed for initialization of the service. */
+typedef struct
+{
+ ble_bps_evt_handler_t evt_handler; /**< Event handler to be called for handling events in the Blood Pressure Service. */
+ ble_srv_cccd_security_mode_t bps_meas_attr_md; /**< Initial security level for blood pressure measurement attribute */
+ ble_srv_security_mode_t bps_feature_attr_md; /**< Initial security level for blood pressure feature attribute */
+ uint16_t feature; /**< Initial value for blood pressure feature */
+} ble_bps_init_t;
+
+/**@brief Blood Pressure Service structure. This contains various status information for
+ * the service. */
+struct ble_bps_s
+{
+ ble_bps_evt_handler_t evt_handler; /**< Event handler to be called for handling events in the Blood Pressure Service. */
+ uint16_t service_handle; /**< Handle of Blood Pressure Service (as provided by the BLE stack). */
+ ble_gatts_char_handles_t meas_handles; /**< Handles related to the Blood Pressure Measurement characteristic. */
+ ble_gatts_char_handles_t feature_handles; /**< Handles related to the Blood Pressure Feature characteristic. */
+ uint16_t conn_handle; /**< Handle of the current connection (as provided by the BLE stack, is BLE_CONN_HANDLE_INVALID if not in a connection). */
+ uint16_t feature; /**< Value of Blood Pressure feature. */
+};
+
+/**@brief Blood Pressure Service measurement structure. This contains a Blood Pressure
+ * measurement. */
+typedef struct ble_bps_meas_s
+{
+ bool blood_pressure_units_in_kpa; /**< Blood Pressure Units Flag, 0=mmHg, 1=kPa */
+ bool time_stamp_present; /**< Time Stamp Flag, 0=not present, 1=present. */
+ bool pulse_rate_present; /**< Pulse Rate Flag, 0=not present, 1=present. */
+ bool user_id_present; /**< User ID Flag, 0=not present, 1=present. */
+ bool measurement_status_present; /**< Measurement Status Flag, 0=not present, 1=present. */
+ ieee_float16_t blood_pressure_systolic; /**< Blood Pressure Measurement Compound Value - Systolic. */
+ ieee_float16_t blood_pressure_diastolic; /**< Blood Pressure Measurement Compound Value - Diastolic . */
+ ieee_float16_t mean_arterial_pressure; /**< Blood Pressure Measurement Compound Value - Mean Arterial Pressure. */
+ ble_date_time_t time_stamp; /**< Time Stamp. */
+ ieee_float16_t pulse_rate; /**< Pulse Rate. */
+ uint8_t user_id; /**< User ID. */
+ uint16_t measurement_status; /**< Measurement Status. */
+} ble_bps_meas_t;
+
+
+/**@brief Function for initializing the Blood Pressure Service.
+ *
+ * @param[out] p_bps Blood Pressure Service structure. This structure will have to
+ * be supplied by the application. It will be initialized by this function,
+ * and will later be used to identify this particular service instance.
+ * @param[in] p_bps_init Information needed to initialize the service.
+ *
+ * @return NRF_SUCCESS on successful initialization of service, otherwise an error code.
+ */
+uint32_t ble_bps_init(ble_bps_t * p_bps, ble_bps_init_t const * p_bps_init);
+
+
+/**@brief Function for handling the Application's BLE Stack events.
+ *
+ * @details Handles all events from the BLE stack of interest to the Blood Pressure Service.
+ *
+ * @param[in] p_ble_evt Event received from the BLE stack.
+ * @param[in] p_context Blood Pressure Service structure.
+ */
+void ble_bps_on_ble_evt(ble_evt_t const * p_ble_evt, void * p_context);
+
+
+/**@brief Function for sending blood pressure measurement if indication has been enabled.
+ *
+ * @details The application calls this function after having performed a Blood Pressure
+ * measurement. If indication has been enabled, the measurement data is encoded and
+ * sent to the client.
+ *
+ * @param[in] p_bps Blood Pressure Service structure.
+ * @param[in] p_bps_meas Pointer to new blood pressure measurement.
+ *
+ * @return NRF_SUCCESS on success, otherwise an error code.
+ */
+uint32_t ble_bps_measurement_send(ble_bps_t * p_bps, ble_bps_meas_t * p_bps_meas);
+
+
+/**@brief Function for checking if indication of Blood Pressure Measurement is currently enabled.
+ *
+ * @param[in] p_bps Blood Pressure Service structure.
+ * @param[out] p_indication_enabled TRUE if indication is enabled, FALSE otherwise.
+ *
+ * @return NRF_SUCCESS on success, otherwise an error code.
+ */
+uint32_t ble_bps_is_indication_enabled(ble_bps_t * p_bps, bool * p_indication_enabled);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // BLE_BPS_H__
+
+/** @} */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/ble_cscs/ble_cscs.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/ble_cscs/ble_cscs.c
new file mode 100644
index 0000000..6e45d0f
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/ble_cscs/ble_cscs.c
@@ -0,0 +1,489 @@
+/**
+ * Copyright (c) 2012 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+/* Attention!
+ * To maintain compliance with Nordic Semiconductor ASA's Bluetooth profile
+ * qualification listings, this section of source code must not be modified.
+ */
+
+#include "ble_cscs.h"
+#include <string.h>
+#include "nordic_common.h"
+#include "ble.h"
+#include "ble_err.h"
+#include "ble_srv_common.h"
+#include "app_util.h"
+
+#define OPCODE_LENGTH 1 /**< Length of opcode inside Cycling Speed and Cadence Measurement packet. */
+#define HANDLE_LENGTH 2 /**< Length of handle inside Cycling Speed and Cadence Measurement packet. */
+#define MAX_CSCM_LEN (BLE_GATT_ATT_MTU_DEFAULT - OPCODE_LENGTH - HANDLE_LENGTH) /**< Maximum size of a transmitted Cycling Speed and Cadence Measurement. */
+
+// Cycling Speed and Cadence Measurement flag bits
+#define CSC_MEAS_FLAG_MASK_WHEEL_REV_DATA_PRESENT (0x01 << 0) /**< Wheel revolution data present flag bit. */
+#define CSC_MEAS_FLAG_MASK_CRANK_REV_DATA_PRESENT (0x01 << 1) /**< Crank revolution data present flag bit. */
+
+
+/**@brief Function for handling the Connect event.
+ *
+ * @param[in] p_cscs Cycling Speed and Cadence Service structure.
+ * @param[in] p_ble_evt Event received from the BLE stack.
+ */
+static void on_connect(ble_cscs_t * p_cscs, ble_evt_t const * p_ble_evt)
+{
+ p_cscs->conn_handle = p_ble_evt->evt.gap_evt.conn_handle;
+}
+
+
+/**@brief Function for handling the Disconnect event.
+ *
+ * @param[in] p_cscs Cycling Speed and Cadence Service structure.
+ * @param[in] p_ble_evt Event received from the BLE stack.
+ */
+static void on_disconnect(ble_cscs_t * p_cscs, ble_evt_t const * p_ble_evt)
+{
+ UNUSED_PARAMETER(p_ble_evt);
+ p_cscs->conn_handle = BLE_CONN_HANDLE_INVALID;
+}
+
+
+/**@brief Function for handling write events to the CSCS Measurement characteristic.
+ *
+ * @param[in] p_cscs Cycling Speed and Cadence Service structure.
+ * @param[in] p_evt_write Write event received from the BLE stack.
+ */
+static void on_meas_cccd_write(ble_cscs_t * p_cscs, ble_gatts_evt_write_t const * p_evt_write)
+{
+ if (p_evt_write->len == 2)
+ {
+ // CCCD written, update notification state
+ if (p_cscs->evt_handler != NULL)
+ {
+ ble_cscs_evt_t evt;
+
+ if (ble_srv_is_notification_enabled(p_evt_write->data))
+ {
+ evt.evt_type = BLE_CSCS_EVT_NOTIFICATION_ENABLED;
+ }
+ else
+ {
+ evt.evt_type = BLE_CSCS_EVT_NOTIFICATION_DISABLED;
+ }
+
+ p_cscs->evt_handler(p_cscs, &evt);
+ }
+ }
+}
+
+
+/**@brief Function for handling the Write event.
+ *
+ * @param[in] p_cscs Cycling Speed and Cadence Service structure.
+ * @param[in] p_ble_evt Event received from the BLE stack.
+ */
+static void on_write(ble_cscs_t * p_cscs, ble_evt_t const * p_ble_evt)
+{
+ ble_gatts_evt_write_t const * p_evt_write = &p_ble_evt->evt.gatts_evt.params.write;
+
+ if (p_evt_write->handle == p_cscs->meas_handles.cccd_handle)
+ {
+ on_meas_cccd_write(p_cscs, p_evt_write);
+ }
+}
+
+
+void ble_cscs_on_ble_evt(ble_evt_t const * p_ble_evt, void * p_context)
+{
+ ble_cscs_t * p_cscs = (ble_cscs_t *)p_context;
+
+ if (p_cscs == NULL || p_ble_evt == NULL)
+ {
+ return;
+ }
+
+
+ ble_sc_ctrlpt_on_ble_evt(&(p_cscs->ctrl_pt), p_ble_evt);
+
+ switch (p_ble_evt->header.evt_id)
+ {
+ case BLE_GAP_EVT_CONNECTED:
+ on_connect(p_cscs, p_ble_evt);
+ break;
+
+ case BLE_GAP_EVT_DISCONNECTED:
+ on_disconnect(p_cscs, p_ble_evt);
+ break;
+
+ case BLE_GATTS_EVT_WRITE:
+ on_write(p_cscs, p_ble_evt);
+ break;
+
+ default:
+ // No implementation needed.
+ break;
+ }
+}
+
+
+/**@brief Function for encoding a CSCS Measurement.
+ *
+ * @param[in] p_cscs Cycling Speed and Cadence Service structure.
+ * @param[in] p_csc_measurement Measurement to be encoded.
+ * @param[out] p_encoded_buffer Buffer where the encoded data will be written.
+ *
+ * @return Size of encoded data.
+ */
+static uint8_t csc_measurement_encode(ble_cscs_t * p_cscs,
+ ble_cscs_meas_t * p_csc_measurement,
+ uint8_t * p_encoded_buffer)
+{
+ uint8_t flags = 0;
+ uint8_t len = 1;
+
+ // Cumulative Wheel Revolutions and Last Wheel Event Time Fields
+ if (p_cscs->feature & BLE_CSCS_FEATURE_WHEEL_REV_BIT)
+ {
+ if (p_csc_measurement->is_wheel_rev_data_present)
+ {
+ flags |= CSC_MEAS_FLAG_MASK_WHEEL_REV_DATA_PRESENT;
+ len += uint32_encode(p_csc_measurement->cumulative_wheel_revs, &p_encoded_buffer[len]);
+ len += uint16_encode(p_csc_measurement->last_wheel_event_time, &p_encoded_buffer[len]);
+ }
+ }
+
+ // Cumulative Crank Revolutions and Last Crank Event Time Fields
+ if (p_cscs->feature & BLE_CSCS_FEATURE_CRANK_REV_BIT)
+ {
+ if (p_csc_measurement->is_crank_rev_data_present)
+ {
+ flags |= CSC_MEAS_FLAG_MASK_CRANK_REV_DATA_PRESENT;
+ len += uint16_encode(p_csc_measurement->cumulative_crank_revs, &p_encoded_buffer[len]);
+ len += uint16_encode(p_csc_measurement->last_crank_event_time, &p_encoded_buffer[len]);
+ }
+ }
+
+ // Flags Field
+ p_encoded_buffer[0] = flags;
+
+ return len;
+}
+
+
+/**@brief Function for adding CSC Measurement characteristics.
+ *
+ * @param[in] p_cscs Cycling Speed and Cadence Service structure.
+ * @param[in] p_cscs_init Information needed to initialize the service.
+ *
+ * @return NRF_SUCCESS on success, otherwise an error code.
+ */
+static uint32_t csc_measurement_char_add(ble_cscs_t * p_cscs, ble_cscs_init_t const * p_cscs_init)
+{
+ ble_gatts_char_md_t char_md;
+ ble_gatts_attr_md_t cccd_md;
+ ble_gatts_attr_t attr_char_value;
+ ble_uuid_t ble_uuid;
+ ble_gatts_attr_md_t attr_md;
+ ble_cscs_meas_t initial_scm = {0};
+ uint8_t encoded_scm[MAX_CSCM_LEN];
+ memset(&cccd_md, 0, sizeof(cccd_md));
+
+ BLE_GAP_CONN_SEC_MODE_SET_OPEN(&cccd_md.read_perm);
+ cccd_md.write_perm = p_cscs_init->csc_meas_attr_md.cccd_write_perm;
+ cccd_md.vloc = BLE_GATTS_VLOC_STACK;
+
+ memset(&char_md, 0, sizeof(char_md));
+
+ char_md.char_props.notify = 1;
+ char_md.p_char_user_desc = NULL;
+ char_md.p_char_pf = NULL;
+ char_md.p_user_desc_md = NULL;
+ char_md.p_cccd_md = &cccd_md;
+ char_md.p_sccd_md = NULL;
+
+ BLE_UUID_BLE_ASSIGN(ble_uuid, BLE_UUID_CSC_MEASUREMENT_CHAR);
+
+ memset(&attr_md, 0, sizeof(attr_md));
+
+ BLE_GAP_CONN_SEC_MODE_SET_NO_ACCESS(&attr_md.read_perm );
+
+ BLE_GAP_CONN_SEC_MODE_SET_NO_ACCESS(&attr_md.write_perm);
+ attr_md.vloc = BLE_GATTS_VLOC_STACK;
+ attr_md.rd_auth = 0;
+ attr_md.wr_auth = 0;
+ attr_md.vlen = 1;
+
+ memset(&attr_char_value, 0, sizeof(attr_char_value));
+
+ attr_char_value.p_uuid = &ble_uuid;
+ attr_char_value.p_attr_md = &attr_md;
+ attr_char_value.init_len = csc_measurement_encode(p_cscs, &initial_scm, encoded_scm);
+ attr_char_value.init_offs = 0;
+ attr_char_value.max_len = MAX_CSCM_LEN;
+ attr_char_value.p_value = encoded_scm;
+
+ return sd_ble_gatts_characteristic_add(p_cscs->service_handle,
+ &char_md,
+ &attr_char_value,
+ &p_cscs->meas_handles);
+}
+
+
+/**@brief Function for adding CSC Feature characteristics.
+ *
+ * @param[in] p_cscs Cycling Speed and Cadence Service structure.
+ * @param[in] p_cscs_init Information needed to initialize the service.
+ *
+ * @return NRF_SUCCESS on success, otherwise an error code.
+ */
+static uint32_t csc_feature_char_add(ble_cscs_t * p_cscs, ble_cscs_init_t const * p_cscs_init)
+{
+ ble_gatts_char_md_t char_md;
+ ble_gatts_attr_t attr_char_value;
+ ble_uuid_t ble_uuid;
+ ble_gatts_attr_md_t attr_md;
+ uint8_t init_value_encoded[2];
+ uint8_t init_value_len;
+
+ memset(&char_md, 0, sizeof(char_md));
+
+ char_md.char_props.read = 1;
+ char_md.p_char_user_desc = NULL;
+ char_md.p_char_pf = NULL;
+ char_md.p_user_desc_md = NULL;
+ char_md.p_cccd_md = NULL;
+ char_md.p_sccd_md = NULL;
+
+ BLE_UUID_BLE_ASSIGN(ble_uuid, BLE_UUID_CSC_FEATURE_CHAR);
+
+ memset(&attr_md, 0, sizeof(attr_md));
+
+ attr_md.read_perm = p_cscs_init->csc_feature_attr_md.read_perm;
+
+ BLE_GAP_CONN_SEC_MODE_SET_NO_ACCESS(&attr_md.write_perm);
+ attr_md.vloc = BLE_GATTS_VLOC_STACK;
+ attr_md.rd_auth = 0;
+ attr_md.wr_auth = 0;
+ attr_md.vlen = 0;
+
+ memset(&attr_char_value, 0, sizeof(attr_char_value));
+
+ init_value_len = uint16_encode(p_cscs_init->feature, &init_value_encoded[0]);
+
+ attr_char_value.p_uuid = &ble_uuid;
+ attr_char_value.p_attr_md = &attr_md;
+ attr_char_value.init_len = init_value_len;
+ attr_char_value.init_offs = 0;
+ attr_char_value.max_len = init_value_len;
+ attr_char_value.p_value = init_value_encoded;
+
+ return sd_ble_gatts_characteristic_add(p_cscs->service_handle,
+ &char_md,
+ &attr_char_value,
+ &p_cscs->feature_handles);
+}
+
+
+/**@brief Function for adding CSC Sensor Location characteristic.
+ *
+ * @param[in] p_cscs Cycling Speed and Cadence Service structure.
+ * @param[in] p_cscs_init Information needed to initialize the service.
+ *
+ * @return NRF_SUCCESS on success, otherwise an error code.
+ */
+static uint32_t csc_sensor_loc_char_add(ble_cscs_t * p_cscs, ble_cscs_init_t const * p_cscs_init)
+{
+ ble_gatts_char_md_t char_md;
+ ble_gatts_attr_t attr_char_value;
+ ble_uuid_t ble_uuid;
+ ble_gatts_attr_md_t attr_md;
+ uint8_t init_value_len;
+ uint8_t encoded_init_value[1];
+
+ memset(&char_md, 0, sizeof(char_md));
+
+ char_md.char_props.read = 1;
+ char_md.p_char_user_desc = NULL;
+ char_md.p_char_pf = NULL;
+ char_md.p_user_desc_md = NULL;
+ char_md.p_cccd_md = NULL;
+ char_md.p_sccd_md = NULL;
+
+ BLE_UUID_BLE_ASSIGN(ble_uuid, BLE_UUID_SENSOR_LOCATION_CHAR);
+
+ memset(&attr_md, 0, sizeof(attr_md));
+
+ attr_md.read_perm = p_cscs_init->csc_sensor_loc_attr_md.read_perm;
+ BLE_GAP_CONN_SEC_MODE_SET_NO_ACCESS(&attr_md.write_perm);
+ attr_md.vloc = BLE_GATTS_VLOC_STACK;
+ attr_md.rd_auth = 0;
+ attr_md.wr_auth = 0;
+ attr_md.vlen = 0;
+
+ memset(&attr_char_value, 0, sizeof(attr_char_value));
+
+ init_value_len = sizeof(uint8_t);
+ if (p_cscs_init->sensor_location != NULL)
+ {
+ encoded_init_value[0] = *p_cscs_init->sensor_location;
+ }
+
+ attr_char_value.p_uuid = &ble_uuid;
+ attr_char_value.p_attr_md = &attr_md;
+ attr_char_value.init_len = init_value_len;
+ attr_char_value.init_offs = 0;
+ attr_char_value.max_len = init_value_len;
+ attr_char_value.p_value = encoded_init_value;
+
+ return sd_ble_gatts_characteristic_add(p_cscs->service_handle,
+ &char_md,
+ &attr_char_value,
+ &p_cscs->sensor_loc_handles);
+}
+
+
+uint32_t ble_cscs_init(ble_cscs_t * p_cscs, ble_cscs_init_t const * p_cscs_init)
+{
+ if (p_cscs == NULL || p_cscs_init == NULL)
+ {
+ return NRF_ERROR_NULL;
+ }
+
+ uint32_t err_code;
+ ble_uuid_t ble_uuid;
+ ble_cs_ctrlpt_init_t sc_ctrlpt_init;
+
+ // Initialize service structure
+ p_cscs->evt_handler = p_cscs_init->evt_handler;
+ p_cscs->conn_handle = BLE_CONN_HANDLE_INVALID;
+ p_cscs->feature = p_cscs_init->feature;
+
+ // Add service
+ BLE_UUID_BLE_ASSIGN(ble_uuid, BLE_UUID_CYCLING_SPEED_AND_CADENCE);
+
+ err_code = sd_ble_gatts_service_add(BLE_GATTS_SRVC_TYPE_PRIMARY,
+ &ble_uuid,
+ &p_cscs->service_handle);
+
+ if (err_code != NRF_SUCCESS)
+ {
+ return err_code;
+ }
+
+ // Add cycling speed and cadence measurement characteristic
+ err_code = csc_measurement_char_add(p_cscs, p_cscs_init);
+
+ if (err_code != NRF_SUCCESS)
+ {
+ return err_code;
+ }
+
+ // Add cycling speed and cadence feature characteristic
+ err_code = csc_feature_char_add(p_cscs, p_cscs_init);
+
+ if (err_code != NRF_SUCCESS)
+ {
+ return err_code;
+ }
+
+ // Add Sensor Location characteristic (optional)
+ if (p_cscs_init->sensor_location != NULL)
+ {
+ err_code = csc_sensor_loc_char_add(p_cscs, p_cscs_init);
+
+ if (err_code != NRF_SUCCESS)
+ {
+ return err_code;
+ }
+ }
+
+
+ // Add speed and cadence control point characteristic
+ sc_ctrlpt_init.error_handler = p_cscs_init->error_handler;
+ sc_ctrlpt_init.size_list_supported_locations = p_cscs_init->size_list_supported_locations;
+ sc_ctrlpt_init.supported_functions = p_cscs_init->ctrplt_supported_functions;
+ sc_ctrlpt_init.evt_handler = p_cscs_init->ctrlpt_evt_handler;
+ sc_ctrlpt_init.list_supported_locations = p_cscs_init->list_supported_locations;
+ sc_ctrlpt_init.sc_ctrlpt_attr_md = p_cscs_init->csc_ctrlpt_attr_md;
+ sc_ctrlpt_init.sensor_location_handle = p_cscs->sensor_loc_handles.value_handle;
+ sc_ctrlpt_init.service_handle = p_cscs->service_handle;
+
+ return ble_sc_ctrlpt_init(&p_cscs->ctrl_pt, &sc_ctrlpt_init);
+}
+
+
+uint32_t ble_cscs_measurement_send(ble_cscs_t * p_cscs, ble_cscs_meas_t * p_measurement)
+{
+ if (p_cscs == NULL || p_measurement == NULL)
+ {
+ return NRF_ERROR_NULL;
+ }
+
+ uint32_t err_code;
+
+ // Send value if connected and notifying
+ if (p_cscs->conn_handle != BLE_CONN_HANDLE_INVALID)
+ {
+ uint8_t encoded_csc_meas[MAX_CSCM_LEN];
+ uint16_t len;
+ uint16_t hvx_len;
+ ble_gatts_hvx_params_t hvx_params;
+
+ len = csc_measurement_encode(p_cscs, p_measurement, encoded_csc_meas);
+ hvx_len = len;
+
+ memset(&hvx_params, 0, sizeof(hvx_params));
+
+ hvx_params.handle = p_cscs->meas_handles.value_handle;
+ hvx_params.type = BLE_GATT_HVX_NOTIFICATION;
+ hvx_params.offset = 0;
+ hvx_params.p_len = &hvx_len;
+ hvx_params.p_data = encoded_csc_meas;
+
+ err_code = sd_ble_gatts_hvx(p_cscs->conn_handle, &hvx_params);
+ if ((err_code == NRF_SUCCESS) && (hvx_len != len))
+ {
+ err_code = NRF_ERROR_DATA_SIZE;
+ }
+ }
+ else
+ {
+ err_code = NRF_ERROR_INVALID_STATE;
+ }
+
+ return err_code;
+}
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/ble_cscs/ble_cscs.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/ble_cscs/ble_cscs.h
new file mode 100644
index 0000000..c62d09c
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/ble_cscs/ble_cscs.h
@@ -0,0 +1,218 @@
+/**
+ * Copyright (c) 2012 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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
+ *
+ * @defgroup ble_cscs Cycling Speed and Cadence Service
+ * @{
+ * @ingroup ble_sdk_srv
+ * @brief Cycling Speed and Cadence Service module.
+ *
+ * @details This module implements the Cycling Speed and Cadence Service. If enabled, notification
+ * of the Cycling Speead and Candence Measurement is performed when the application
+ * calls ble_cscs_measurement_send().
+ *
+ * To use this service, you need to provide the the supported features (@ref BLE_CSCS_FEATURES).
+ * If you choose to support Wheel revolution data (feature bit @ref BLE_CSCS_FEATURE_WHEEL_REV_BIT),
+ * you then need to support the 'setting of cumulative value' operation by the supporting the
+ * Speed and Cadence Control Point (@ref ble_sdk_srv_sc_ctrlpt) by setting the @ref BLE_SRV_SC_CTRLPT_CUM_VAL_OP_SUPPORTED
+ * bit of the ctrplt_supported_functions in the @ref ble_cscs_init_t structure.
+ * If you want to support the 'start autocalibration' control point feature, you need, after the @ref BLE_SC_CTRLPT_EVT_START_CALIBRATION
+ * has been received and the auto calibration is finished, to call the @ref ble_sc_ctrlpt_rsp_send to indicate that the operation is finished
+ * and thus be able to receive new control point operations.
+ * If you want to support the 'sensor location' related operation, you need to provide a list of supported location in the
+ * @ref ble_cscs_init_t structure.
+ *
+ *
+ * @note The application must register this module as BLE event observer using the
+ * NRF_SDH_BLE_OBSERVER macro. Example:
+ * @code
+ * ble_cscs_t instance;
+ * NRF_SDH_BLE_OBSERVER(anything, BLE_CSCS_BLE_OBSERVER_PRIO,
+ * ble_cscs_on_ble_evt, &instance);
+ * @endcode
+ *
+ * @note Attention!
+ * To maintain compliance with Nordic Semiconductor ASA Bluetooth profile
+ * qualification listings, this section of source code must not be modified.
+ */
+
+#ifndef BLE_CSCS_H__
+#define BLE_CSCS_H__
+
+#include <stdint.h>
+#include <stdbool.h>
+#include "ble.h"
+#include "ble_srv_common.h"
+#include "ble_sc_ctrlpt.h"
+#include "ble_sensor_location.h"
+#include "nrf_sdh_ble.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**@brief Macro for defining a ble_cscs instance.
+ *
+ * @param _name Name of the instance.
+ * @hideinitializer
+ */
+#define BLE_CSCS_DEF(_name) \
+static ble_cscs_t _name; \
+NRF_SDH_BLE_OBSERVER(_name ## _obs, \
+ BLE_CSCS_BLE_OBSERVER_PRIO, \
+ ble_cscs_on_ble_evt, &_name)
+
+
+/** @defgroup BLE_CSCS_FEATURES Cycling Speed and Cadence Service feature bits
+ * @{ */
+#define BLE_CSCS_FEATURE_WHEEL_REV_BIT (0x01 << 0) /**< Wheel Revolution Data Supported bit. */
+#define BLE_CSCS_FEATURE_CRANK_REV_BIT (0x01 << 1) /**< Crank Revolution Data Supported bit. */
+#define BLE_CSCS_FEATURE_MULTIPLE_SENSORS_BIT (0x01 << 2) /**< Multiple Sensor Locations Supported bit. */
+/** @} */
+
+
+/**@brief Cycling Speed and Cadence Service event type. */
+typedef enum
+{
+ BLE_CSCS_EVT_NOTIFICATION_ENABLED, /**< Cycling Speed and Cadence value notification enabled event. */
+ BLE_CSCS_EVT_NOTIFICATION_DISABLED /**< Cycling Speed and Cadence value notification disabled event. */
+} ble_cscs_evt_type_t;
+
+/**@brief Cycling Speed and Cadence Service event. */
+typedef struct
+{
+ ble_cscs_evt_type_t evt_type; /**< Type of event. */
+} ble_cscs_evt_t;
+
+// Forward declaration of the ble_csc_t type.
+typedef struct ble_cscs_s ble_cscs_t;
+
+/**@brief Cycling Speed and Cadence Service event handler type. */
+typedef void (*ble_cscs_evt_handler_t) (ble_cscs_t * p_cscs, ble_cscs_evt_t * p_evt);
+
+/**@brief Cycling Speed and Cadence Service init structure. This contains all options and data
+* needed for initialization of the service. */
+typedef struct
+{
+ ble_cscs_evt_handler_t evt_handler; /**< Event handler to be called for handling events in the Cycling Speed and Cadence Service. */
+ ble_srv_cccd_security_mode_t csc_meas_attr_md; /**< Initial security level for cycling speed and cadence measurement attribute */
+ ble_srv_cccd_security_mode_t csc_ctrlpt_attr_md; /**< Initial security level for cycling speed and cadence control point attribute */
+ ble_srv_security_mode_t csc_feature_attr_md; /**< Initial security level for feature attribute */
+ uint16_t feature; /**< Initial value for features of sensor @ref BLE_CSCS_FEATURES. */
+ uint8_t ctrplt_supported_functions; /**< Supported control point functionalities see @ref BLE_SRV_SC_CTRLPT_SUPP_FUNC. */
+ ble_sc_ctrlpt_evt_handler_t ctrlpt_evt_handler; /**< Event handler */
+ ble_sensor_location_t *list_supported_locations; /**< List of supported sensor locations.*/
+ uint8_t size_list_supported_locations; /**< Number of supported sensor locations in the list.*/
+ ble_srv_error_handler_t error_handler; /**< Function to be called in case of an error. */
+ ble_sensor_location_t *sensor_location; /**< Initial Sensor Location, if NULL, sensor_location characteristic is not added*/
+ ble_srv_cccd_security_mode_t csc_sensor_loc_attr_md; /**< Initial security level for sensor location attribute */
+} ble_cscs_init_t;
+
+/**@brief Cycling Speed and Cadence Service structure. This contains various status information for
+ * the service. */
+struct ble_cscs_s
+{
+ ble_cscs_evt_handler_t evt_handler; /**< Event handler to be called for handling events in the Cycling Speed and Cadence Service. */
+ uint16_t service_handle; /**< Handle of Cycling Speed and Cadence Service (as provided by the BLE stack). */
+ ble_gatts_char_handles_t meas_handles; /**< Handles related to the Cycling Speed and Cadence Measurement characteristic. */
+ ble_gatts_char_handles_t feature_handles; /**< Handles related to the Cycling Speed and Cadence feature characteristic. */
+ ble_gatts_char_handles_t sensor_loc_handles; /**< Handles related to the Cycling Speed and Cadence Sensor Location characteristic. */
+ uint16_t conn_handle; /**< Handle of the current connection (as provided by the BLE stack, is BLE_CONN_HANDLE_INVALID if not in a connection). */
+ uint16_t feature; /**< Bit mask of features available on sensor. */
+ ble_sc_ctrlpt_t ctrl_pt; /**< data for speed and cadence control point */
+};
+
+/**@brief Cycling Speed and Cadence Service measurement structure. This contains a Cycling Speed and
+ * Cadence Service measurement. */
+typedef struct ble_cscs_meas_s
+{
+ bool is_wheel_rev_data_present; /**< True if Wheel Revolution Data is present in the measurement. */
+ bool is_crank_rev_data_present; /**< True if Crank Revolution Data is present in the measurement. */
+ uint32_t cumulative_wheel_revs; /**< Cumulative Wheel Revolutions. */
+ uint16_t last_wheel_event_time; /**< Last Wheel Event Time. */
+ uint16_t cumulative_crank_revs; /**< Cumulative Crank Revolutions. */
+ uint16_t last_crank_event_time; /**< Last Crank Event Time. */
+} ble_cscs_meas_t;
+
+
+/**@brief Function for initializing the Cycling Speed and Cadence Service.
+ *
+ * @param[out] p_cscs Cycling Speed and Cadence Service structure. This structure will have to
+ * be supplied by the application. It will be initialized by this function,
+ * and will later be used to identify this particular service instance.
+ * @param[in] p_cscs_init Information needed to initialize the service.
+ *
+ * @return NRF_SUCCESS on successful initialization of service, otherwise an error code.
+ */
+uint32_t ble_cscs_init(ble_cscs_t * p_cscs, ble_cscs_init_t const * p_cscs_init);
+
+
+/**@brief Function for handling the Application's BLE Stack events.
+ *
+ * @details Handles all events from the BLE stack of interest to the Cycling Speed and Cadence
+ * Service.
+ *
+ * @param[in] p_ble_evt Event received from the BLE stack.
+ * @param[in] p_context Cycling Speed and Cadence Service structure.
+ */
+void ble_cscs_on_ble_evt(ble_evt_t const * p_ble_evt, void * p_context);
+
+
+/**@brief Function for sending cycling speed and cadence measurement if notification has been enabled.
+ *
+ * @details The application calls this function after having performed a Cycling Speed and Cadence
+ * Service measurement. If notification has been enabled, the measurement data is encoded
+ * and sent to the client.
+ *
+ * @param[in] p_cscs Cycling Speed and Cadence Service structure.
+ * @param[in] p_measurement Pointer to new cycling speed and cadence measurement.
+ *
+ * @return NRF_SUCCESS on success, otherwise an error code.
+ */
+uint32_t ble_cscs_measurement_send(ble_cscs_t * p_cscs, ble_cscs_meas_t * p_measurement);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // BLE_CSCS_H__
+
+/** @} */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/ble_cscs/ble_sc_ctrlpt.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/ble_cscs/ble_sc_ctrlpt.c
new file mode 100644
index 0000000..faef930
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/ble_cscs/ble_sc_ctrlpt.c
@@ -0,0 +1,686 @@
+/**
+ * Copyright (c) 2013 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+/* Attention!
+ * To maintain compliance with Nordic Semiconductor ASA's Bluetooth profile
+ * qualification listings, this section of source code must not be modified.
+ */
+
+#include "ble_sc_ctrlpt.h"
+#include <string.h>
+#include "nordic_common.h"
+#include "ble.h"
+#include "ble_err.h"
+#include "ble_srv_common.h"
+#include "app_util.h"
+
+#define SC_CTRLPT_NACK_PROC_ALREADY_IN_PROGRESS (BLE_GATT_STATUS_ATTERR_APP_BEGIN + 0)
+#define SC_CTRLPT_NACK_CCCD_IMPROPERLY_CONFIGURED (BLE_GATT_STATUS_ATTERR_APP_BEGIN + 1)
+
+uint32_t ble_sc_ctrlpt_init(ble_sc_ctrlpt_t * p_sc_ctrlpt,
+ const ble_cs_ctrlpt_init_t * p_sc_ctrlpt_init)
+{
+ if (p_sc_ctrlpt == NULL || p_sc_ctrlpt_init == NULL)
+ {
+ return NRF_ERROR_NULL;
+ }
+
+ ble_gatts_char_md_t char_md;
+ ble_gatts_attr_md_t cccd_md;
+ ble_gatts_attr_t attr_char_value;
+ ble_uuid_t ble_uuid;
+ ble_gatts_attr_md_t attr_md;
+
+ p_sc_ctrlpt->conn_handle = BLE_CONN_HANDLE_INVALID;
+ p_sc_ctrlpt->procedure_status = BLE_SCPT_NO_PROC_IN_PROGRESS;
+
+ p_sc_ctrlpt->size_list_supported_locations = p_sc_ctrlpt_init->size_list_supported_locations;
+
+ if ((p_sc_ctrlpt_init->size_list_supported_locations != 0) &&
+ (p_sc_ctrlpt_init->list_supported_locations != NULL))
+ {
+ memcpy(p_sc_ctrlpt->list_supported_locations,
+ p_sc_ctrlpt_init->list_supported_locations,
+ p_sc_ctrlpt->size_list_supported_locations * sizeof(ble_sensor_location_t));
+ }
+
+ p_sc_ctrlpt->service_handle = p_sc_ctrlpt_init->service_handle;
+ p_sc_ctrlpt->evt_handler = p_sc_ctrlpt_init->evt_handler;
+ p_sc_ctrlpt->supported_functions = p_sc_ctrlpt_init->supported_functions;
+ p_sc_ctrlpt->sensor_location_handle = p_sc_ctrlpt_init->sensor_location_handle;
+ p_sc_ctrlpt->error_handler = p_sc_ctrlpt_init->error_handler;
+
+ memset(&cccd_md, 0, sizeof(cccd_md));
+
+ BLE_GAP_CONN_SEC_MODE_SET_OPEN(&cccd_md.read_perm);
+ cccd_md.write_perm = p_sc_ctrlpt_init->sc_ctrlpt_attr_md.cccd_write_perm;
+ cccd_md.vloc = BLE_GATTS_VLOC_STACK;
+
+ memset(&char_md, 0, sizeof(char_md));
+
+ char_md.char_props.indicate = 1;
+ char_md.char_props.write = 1;
+ char_md.p_char_user_desc = NULL;
+ char_md.p_char_pf = NULL;
+ char_md.p_user_desc_md = NULL;
+ char_md.p_cccd_md = &cccd_md;
+ char_md.p_sccd_md = NULL;
+
+ BLE_UUID_BLE_ASSIGN(ble_uuid, BLE_UUID_SC_CTRLPT_CHAR);
+
+ memset(&attr_md, 0, sizeof(attr_md));
+
+ BLE_GAP_CONN_SEC_MODE_SET_NO_ACCESS(&attr_md.read_perm);
+ attr_md.write_perm = p_sc_ctrlpt_init->sc_ctrlpt_attr_md.write_perm;
+ attr_md.vloc = BLE_GATTS_VLOC_STACK;
+ attr_md.rd_auth = 0;
+ attr_md.wr_auth = 1;
+ attr_md.vlen = 1;
+
+ memset(&attr_char_value, 0, sizeof(attr_char_value));
+
+ attr_char_value.p_uuid = &ble_uuid;
+ attr_char_value.p_attr_md = &attr_md;
+ attr_char_value.init_len = 0;
+ attr_char_value.init_offs = 0;
+ attr_char_value.max_len = BLE_SC_CTRLPT_MAX_LEN;
+ attr_char_value.p_value = 0;
+
+ return sd_ble_gatts_characteristic_add(p_sc_ctrlpt->service_handle,
+ &char_md,
+ &attr_char_value,
+ &p_sc_ctrlpt->sc_ctrlpt_handles);
+}
+
+
+/**@brief Decode an incoming control point write.
+ *
+ * @param[in] rcvd_val received write value
+ * @param[in] len value length
+ * @param[out] decoded_ctrlpt decoded control point structure
+ */
+static uint32_t sc_ctrlpt_decode(uint8_t const * p_rcvd_val,
+ uint8_t len,
+ ble_sc_ctrlpt_val_t * p_write_val)
+{
+ int pos = 0;
+
+ if (len < BLE_SC_CTRLPT_MIN_LEN)
+ {
+ return NRF_ERROR_INVALID_PARAM;
+ }
+
+ p_write_val->opcode = (ble_scpt_operator_t) p_rcvd_val[pos++];
+
+ switch (p_write_val->opcode)
+ {
+ case BLE_SCPT_REQUEST_SUPPORTED_SENSOR_LOCATIONS:
+ break;
+
+ case BLE_SCPT_START_AUTOMATIC_CALIBRATION:
+ break;
+
+ case BLE_SCPT_UPDATE_SENSOR_LOCATION:
+ p_write_val->location = (ble_sensor_location_t)p_rcvd_val[pos];
+ break;
+
+ case BLE_SCPT_SET_CUMULATIVE_VALUE:
+ p_write_val->cumulative_value = uint32_decode(&(p_rcvd_val[pos]));
+ break;
+
+ default:
+ return NRF_ERROR_INVALID_PARAM;
+ }
+ return NRF_SUCCESS;
+}
+
+
+/**@brief encode a control point response indication.
+ *
+ * @param[in] p_sc_ctrlpt SC Ctrlpt structure.
+ * @param[in] p_ctrlpt_rsp structure containing response data to be encoded
+ * @param[out] p_data pointer where data needs to be written
+ * @return size of encoded data
+ */
+static int ctrlpt_rsp_encode(ble_sc_ctrlpt_t * p_sc_ctrlpt,
+ ble_sc_ctrlpt_rsp_t * p_ctrlpt_rsp,
+ uint8_t * p_data)
+{
+ int len = 0;
+
+ p_data[len++] = BLE_SCPT_RESPONSE_CODE;
+ p_data[len++] = p_ctrlpt_rsp->opcode;
+ p_data[len++] = p_ctrlpt_rsp->status;
+
+ if (p_ctrlpt_rsp->status == BLE_SCPT_SUCCESS)
+ {
+ switch (p_ctrlpt_rsp->opcode)
+ {
+ case BLE_SCPT_REQUEST_SUPPORTED_SENSOR_LOCATIONS:
+ {
+ int i;
+ for (i = 0; i < p_sc_ctrlpt->size_list_supported_locations; i++)
+ {
+ p_data[len++] = p_sc_ctrlpt->list_supported_locations[i];
+ }
+ break;
+ }
+
+ default:
+ // No implementation needed.
+ break;
+ }
+ }
+ return len;
+}
+
+
+/**@brief check if a given sensor location is supported or not.
+ *
+ * @param[in] p_sc_ctrlpt SC Ctrlpt structure.
+ * @param[in] location sensor location to check.
+ * @return true if the given location is found in the list of supported locations, false otherwise.
+ */
+static bool is_location_supported(ble_sc_ctrlpt_t * p_sc_ctrlpt, ble_sensor_location_t location)
+{
+ int i;
+
+ for (i = 0; i < p_sc_ctrlpt->size_list_supported_locations; i++)
+ {
+ if (p_sc_ctrlpt->list_supported_locations[i] == location)
+ {
+ return true;
+ }
+ }
+ return false;
+}
+
+
+/**@brief check if the cccd is configured
+ *
+ * @param[in] p_sc_ctrlpt SC Ctrlpt structure.
+ * @return true if the sc_control point's cccd is correctly configured, false otherwise.
+ */
+static bool is_cccd_configured(ble_sc_ctrlpt_t * p_sc_ctrlpt)
+{
+ uint32_t err_code;
+ uint8_t cccd_value_buf[BLE_CCCD_VALUE_LEN];
+ bool is_sccp_indic_enabled = false;
+ ble_gatts_value_t gatts_value;
+
+ // Initialize value struct.
+ memset(&gatts_value, 0, sizeof(gatts_value));
+
+ gatts_value.len = BLE_CCCD_VALUE_LEN;
+ gatts_value.offset = 0;
+ gatts_value.p_value = cccd_value_buf;
+
+ err_code = sd_ble_gatts_value_get(p_sc_ctrlpt->conn_handle,
+ p_sc_ctrlpt->sc_ctrlpt_handles.cccd_handle,
+ &gatts_value);
+ if (err_code != NRF_SUCCESS)
+ {
+ // Report error to application
+ if (p_sc_ctrlpt->error_handler != NULL)
+ {
+ p_sc_ctrlpt->error_handler(err_code);
+ }
+ }
+
+ is_sccp_indic_enabled = ble_srv_is_indication_enabled(cccd_value_buf);
+
+ return is_sccp_indic_enabled;
+}
+
+
+/**@brief sends a control point indication.
+ *
+ * @param[in] p_sc_ctrlpt SC Ctrlpt structure.
+ */
+static void sc_ctrlpt_resp_send(ble_sc_ctrlpt_t * p_sc_ctrlpt)
+{
+ uint16_t hvx_len;
+ ble_gatts_hvx_params_t hvx_params;
+ uint32_t err_code;
+
+ if (p_sc_ctrlpt->procedure_status == BLE_SCPT_INDICATION_PENDING)
+ {
+ hvx_len = p_sc_ctrlpt->response.len;
+ memset(&hvx_params, 0, sizeof(hvx_params));
+
+ hvx_params.handle = p_sc_ctrlpt->sc_ctrlpt_handles.value_handle;
+ hvx_params.type = BLE_GATT_HVX_INDICATION;
+ hvx_params.offset = 0;
+ hvx_params.p_len = &hvx_len;
+ hvx_params.p_data = p_sc_ctrlpt->response.encoded_ctrl_rsp;
+
+ err_code = sd_ble_gatts_hvx(p_sc_ctrlpt->conn_handle, &hvx_params);
+
+ // Error handling
+ if ((err_code == NRF_SUCCESS) && (hvx_len != p_sc_ctrlpt->response.len))
+ {
+ err_code = NRF_ERROR_DATA_SIZE;
+ }
+
+ switch (err_code)
+ {
+ case NRF_SUCCESS:
+ p_sc_ctrlpt->procedure_status = BLE_SCPT_IND_CONFIRM_PENDING;
+ // Wait for HVC event
+ break;
+
+ case NRF_ERROR_RESOURCES:
+ // Wait for TX_COMPLETE event to retry transmission.
+ p_sc_ctrlpt->procedure_status = BLE_SCPT_INDICATION_PENDING;
+ break;
+
+ default:
+ // Report error to application.
+ p_sc_ctrlpt->procedure_status = BLE_SCPT_NO_PROC_IN_PROGRESS;
+ if (p_sc_ctrlpt->error_handler != NULL)
+ {
+ p_sc_ctrlpt->error_handler(err_code);
+ }
+ break;
+ }
+ }
+}
+
+
+/**@brief Handle a write event to the Speed and Cadence Control Point.
+ *
+ * @param[in] p_sc_ctrlpt SC Ctrlpt structure.
+ * @param[in] p_evt_write WRITE event to be handled.
+ */
+static void on_ctrlpt_write(ble_sc_ctrlpt_t * p_sc_ctrlpt,
+ ble_gatts_evt_write_t const * p_evt_write)
+{
+ ble_sc_ctrlpt_val_t rcvd_ctrlpt =
+ { BLE_SCPT_RESPONSE_CODE , 0, BLE_SENSOR_LOCATION_OTHER };
+
+ ble_sc_ctrlpt_rsp_t rsp;
+ uint32_t err_code;
+ ble_gatts_rw_authorize_reply_params_t auth_reply;
+ ble_sc_ctrlpt_evt_t evt;
+
+ auth_reply.type = BLE_GATTS_AUTHORIZE_TYPE_WRITE;
+ auth_reply.params.write.offset = 0;
+ auth_reply.params.write.len = 0;
+ auth_reply.params.write.p_data = NULL;
+ auth_reply.params.write.gatt_status = BLE_GATT_STATUS_SUCCESS;
+ auth_reply.params.write.update = 1;
+
+ if (is_cccd_configured(p_sc_ctrlpt))
+ {
+ if (p_sc_ctrlpt->procedure_status == BLE_SCPT_NO_PROC_IN_PROGRESS)
+ {
+ auth_reply.params.write.gatt_status = BLE_GATT_STATUS_SUCCESS;
+ }
+ else
+ {
+ auth_reply.params.write.gatt_status = SC_CTRLPT_NACK_PROC_ALREADY_IN_PROGRESS;
+ }
+ }
+ else
+ {
+ auth_reply.params.write.gatt_status = SC_CTRLPT_NACK_CCCD_IMPROPERLY_CONFIGURED;
+ }
+
+ err_code = sd_ble_gatts_rw_authorize_reply(p_sc_ctrlpt->conn_handle, &auth_reply);
+ if (err_code != NRF_SUCCESS)
+ {
+ // Report error to application.
+ if (p_sc_ctrlpt->error_handler != NULL)
+ {
+ p_sc_ctrlpt->error_handler(err_code);
+ }
+ }
+
+ if (auth_reply.params.write.gatt_status != BLE_GATT_STATUS_SUCCESS)
+ {
+ return;
+ }
+
+ p_sc_ctrlpt->procedure_status = BLE_SCPT_INDICATION_PENDING;
+ rsp.status = BLE_SCPT_OP_CODE_NOT_SUPPORTED;
+
+ err_code = sc_ctrlpt_decode(p_evt_write->data, p_evt_write->len, &rcvd_ctrlpt);
+ if (err_code != NRF_SUCCESS)
+ {
+ rsp.opcode = rcvd_ctrlpt.opcode;
+ rsp.status = BLE_SCPT_OP_CODE_NOT_SUPPORTED;
+ }
+ else
+ {
+ rsp.opcode = rcvd_ctrlpt.opcode;
+
+ switch (rcvd_ctrlpt.opcode)
+ {
+ case BLE_SCPT_REQUEST_SUPPORTED_SENSOR_LOCATIONS:
+ if ((p_sc_ctrlpt->supported_functions &
+ BLE_SRV_SC_CTRLPT_SENSOR_LOCATIONS_OP_SUPPORTED) ==
+ BLE_SRV_SC_CTRLPT_SENSOR_LOCATIONS_OP_SUPPORTED)
+ {
+ rsp.status = BLE_SCPT_SUCCESS;
+ }
+ else
+ {
+ rsp.status = BLE_SCPT_OP_CODE_NOT_SUPPORTED;
+ }
+ break;
+
+ case BLE_SCPT_UPDATE_SENSOR_LOCATION:
+ if ((p_sc_ctrlpt->supported_functions &
+ BLE_SRV_SC_CTRLPT_SENSOR_LOCATIONS_OP_SUPPORTED) ==
+ BLE_SRV_SC_CTRLPT_SENSOR_LOCATIONS_OP_SUPPORTED)
+ {
+ if (is_location_supported(p_sc_ctrlpt, rcvd_ctrlpt.location))
+ {
+ ble_gatts_value_t gatts_value;
+ uint8_t rcvd_location = (uint8_t)rcvd_ctrlpt.location;
+ rsp.status = BLE_SCPT_SUCCESS;
+
+ // Initialize value struct.
+ memset(&gatts_value, 0, sizeof(gatts_value));
+
+ gatts_value.len = sizeof(uint8_t);
+ gatts_value.offset = 0;
+ gatts_value.p_value = &rcvd_location;
+
+ evt.evt_type = BLE_SC_CTRLPT_EVT_UPDATE_LOCATION;
+ evt.params.update_location = rcvd_ctrlpt.location;
+ if (p_sc_ctrlpt->evt_handler != NULL)
+ {
+ rsp.status = p_sc_ctrlpt->evt_handler(p_sc_ctrlpt, &evt);
+ }
+ if (rsp.status == BLE_SCPT_SUCCESS)
+ {
+ err_code = sd_ble_gatts_value_set(p_sc_ctrlpt->conn_handle,
+ p_sc_ctrlpt->sensor_location_handle,
+ &gatts_value);
+ if (err_code != NRF_SUCCESS)
+ {
+ // Report error to application
+ if (p_sc_ctrlpt->error_handler != NULL)
+ {
+ p_sc_ctrlpt->error_handler(err_code);
+ }
+ rsp.status = BLE_SCPT_OPERATION_FAILED;
+ }
+ }
+ }
+ else
+ {
+ rsp.status = BLE_SCPT_INVALID_PARAMETER;
+ }
+ }
+ else
+ {
+ rsp.status = BLE_SCPT_OP_CODE_NOT_SUPPORTED;
+ }
+ break;
+
+ case BLE_SCPT_SET_CUMULATIVE_VALUE:
+ if ((p_sc_ctrlpt->supported_functions &
+ BLE_SRV_SC_CTRLPT_CUM_VAL_OP_SUPPORTED) ==
+ BLE_SRV_SC_CTRLPT_CUM_VAL_OP_SUPPORTED)
+ {
+ rsp.status = BLE_SCPT_SUCCESS;
+
+ evt.evt_type = BLE_SC_CTRLPT_EVT_SET_CUMUL_VALUE;
+ evt.params.cumulative_value = rcvd_ctrlpt.cumulative_value;
+ if (p_sc_ctrlpt->evt_handler != NULL)
+ {
+ rsp.status = p_sc_ctrlpt->evt_handler(p_sc_ctrlpt, &evt);
+ }
+ }
+ else
+ {
+ rsp.status = BLE_SCPT_OP_CODE_NOT_SUPPORTED;
+ }
+ break;
+
+ case BLE_SCPT_START_AUTOMATIC_CALIBRATION:
+ if ((p_sc_ctrlpt->supported_functions &
+ BLE_SRV_SC_CTRLPT_START_CALIB_OP_SUPPORTED) ==
+ BLE_SRV_SC_CTRLPT_START_CALIB_OP_SUPPORTED)
+ {
+ p_sc_ctrlpt->procedure_status = BLE_SCPT_AUTOMATIC_CALIB_IN_PROGRESS;
+ evt.evt_type = BLE_SC_CTRLPT_EVT_START_CALIBRATION;
+ if (p_sc_ctrlpt->evt_handler != NULL)
+ {
+ rsp.status = p_sc_ctrlpt->evt_handler(p_sc_ctrlpt, &evt);
+ if (rsp.status != BLE_SCPT_SUCCESS)
+ {
+ // If the application returns an error, the response is to be sent
+ // right away and the calibration is considered as not started.
+ p_sc_ctrlpt->procedure_status = BLE_SCPT_INDICATION_PENDING;
+ }
+ }
+ }
+ else
+ {
+ rsp.status = BLE_SCPT_OP_CODE_NOT_SUPPORTED;
+ }
+ break;
+
+ default:
+ rsp.status = BLE_SCPT_OP_CODE_NOT_SUPPORTED;
+ break;
+ }
+
+ }
+
+ p_sc_ctrlpt->response.len = ctrlpt_rsp_encode(p_sc_ctrlpt, &rsp,
+ p_sc_ctrlpt->response.encoded_ctrl_rsp);
+
+
+ if (p_sc_ctrlpt->procedure_status == BLE_SCPT_INDICATION_PENDING)
+ {
+ sc_ctrlpt_resp_send(p_sc_ctrlpt);
+ }
+}
+
+
+/**@brief Authorize WRITE request event handler.
+ *
+ * @details Handles WRITE events from the BLE stack.
+ *
+ * @param[in] p_sc_ctrlpt SC Ctrlpt structure.
+ * @param[in] p_gatts_evt GATTS Event received from the BLE stack.
+ *
+ */
+static void on_rw_authorize_request(ble_sc_ctrlpt_t * p_sc_ctrlpt,
+ ble_gatts_evt_t const * p_gatts_evt)
+{
+ ble_gatts_evt_rw_authorize_request_t const * p_auth_req =
+ &p_gatts_evt->params.authorize_request;
+
+ if (p_auth_req->type == BLE_GATTS_AUTHORIZE_TYPE_WRITE)
+ {
+ if ( (p_gatts_evt->params.authorize_request.request.write.op
+ != BLE_GATTS_OP_PREP_WRITE_REQ)
+ && (p_gatts_evt->params.authorize_request.request.write.op
+ != BLE_GATTS_OP_EXEC_WRITE_REQ_NOW)
+ && (p_gatts_evt->params.authorize_request.request.write.op
+ != BLE_GATTS_OP_EXEC_WRITE_REQ_CANCEL)
+ )
+ {
+ if (p_auth_req->request.write.handle == p_sc_ctrlpt->sc_ctrlpt_handles.value_handle)
+ {
+ on_ctrlpt_write(p_sc_ctrlpt, &p_auth_req->request.write);
+ }
+ }
+ }
+}
+
+
+/**@brief Tx Complete event handler.
+ *
+ * @details Tx Complete event handler.
+ * Handles WRITE events from the BLE stack and if an indication was pending try sending it
+ * again.
+ *
+ * @param[in] p_sc_ctrlpt SC Ctrlpt structure.
+ *
+ */
+static void on_tx_complete(ble_sc_ctrlpt_t * p_sc_ctrlpt)
+{
+ if (p_sc_ctrlpt->procedure_status == BLE_SCPT_INDICATION_PENDING)
+ {
+ sc_ctrlpt_resp_send(p_sc_ctrlpt);
+ }
+}
+
+
+/**@brief Function for handling the Connect event.
+ *
+ * @param[in] p_sc_ctrlpt SC Ctrlpt structure.
+ * @param[in] p_ble_evt Event received from the BLE stack.
+ */
+static void on_connect(ble_sc_ctrlpt_t * p_sc_ctrlpt, ble_evt_t const * p_ble_evt)
+{
+ p_sc_ctrlpt->conn_handle = p_ble_evt->evt.gap_evt.conn_handle;
+ p_sc_ctrlpt->procedure_status = BLE_SCPT_NO_PROC_IN_PROGRESS;
+}
+
+
+/**@brief Function for handling the Disconnect event.
+ *
+ * @param[in] p_sc_ctrlpt SC Ctrlpt structure.
+ * @param[in] p_ble_evt Event received from the BLE stack.
+ */
+static void on_disconnect(ble_sc_ctrlpt_t * p_sc_ctrlpt, ble_evt_t const * p_ble_evt)
+{
+ UNUSED_PARAMETER(p_ble_evt);
+ p_sc_ctrlpt->conn_handle = BLE_CONN_HANDLE_INVALID;
+ p_sc_ctrlpt->procedure_status = BLE_SCPT_NO_PROC_IN_PROGRESS;
+}
+
+
+/**@brief Function for handling the BLE_GATTS_EVT_HVC event.
+ *
+ * @param[in] p_sc_ctrlpt SC Ctrlpt structure.
+ * @param[in] p_ble_evt Event received from the BLE stack.
+ */
+static void on_sc_hvc_confirm(ble_sc_ctrlpt_t * p_sc_ctrlpt, ble_evt_t const * p_ble_evt)
+{
+ if (p_ble_evt->evt.gatts_evt.params.hvc.handle == p_sc_ctrlpt->sc_ctrlpt_handles.value_handle)
+ {
+ if (p_sc_ctrlpt->procedure_status == BLE_SCPT_IND_CONFIRM_PENDING)
+ {
+ p_sc_ctrlpt->procedure_status = BLE_SCPT_NO_PROC_IN_PROGRESS;
+ }
+ }
+}
+
+
+void ble_sc_ctrlpt_on_ble_evt(ble_sc_ctrlpt_t * p_sc_ctrlpt, ble_evt_t const * p_ble_evt)
+{
+ if (p_sc_ctrlpt == NULL || p_ble_evt == NULL)
+ {
+ return;
+ }
+
+ switch (p_ble_evt->header.evt_id)
+ {
+ case BLE_GAP_EVT_CONNECTED:
+ on_connect(p_sc_ctrlpt, p_ble_evt);
+ break;
+
+ case BLE_GAP_EVT_DISCONNECTED:
+ on_disconnect(p_sc_ctrlpt, p_ble_evt);
+ break;
+
+ case BLE_GATTS_EVT_RW_AUTHORIZE_REQUEST:
+ on_rw_authorize_request(p_sc_ctrlpt, &p_ble_evt->evt.gatts_evt);
+ break;
+
+ case BLE_GATTS_EVT_HVC:
+ on_sc_hvc_confirm(p_sc_ctrlpt, p_ble_evt);
+ break;
+
+ case BLE_GATTS_EVT_HVN_TX_COMPLETE:
+ on_tx_complete(p_sc_ctrlpt);
+ break;
+
+ default:
+ break;
+ }
+}
+
+
+uint32_t ble_sc_ctrlpt_rsp_send(ble_sc_ctrlpt_t * p_sc_ctrlpt, ble_scpt_response_t response_status)
+{
+ if (p_sc_ctrlpt == NULL)
+ {
+ return NRF_ERROR_NULL;
+ }
+
+ uint32_t err_code = NRF_SUCCESS;
+ ble_sc_ctrlpt_rsp_t rsp;
+ uint8_t encoded_ctrl_rsp[BLE_SC_CTRLPT_MAX_LEN];
+ uint16_t hvx_len;
+ ble_gatts_hvx_params_t hvx_params;
+
+ if (p_sc_ctrlpt->procedure_status != BLE_SCPT_AUTOMATIC_CALIB_IN_PROGRESS)
+ {
+ return NRF_ERROR_INVALID_STATE;
+ }
+ rsp.status = response_status;
+ rsp.opcode = BLE_SCPT_START_AUTOMATIC_CALIBRATION;
+ hvx_len = ctrlpt_rsp_encode(p_sc_ctrlpt, &rsp, encoded_ctrl_rsp);
+
+ // Send indication
+ memset(&hvx_params, 0, sizeof(hvx_params));
+
+ hvx_params.handle = p_sc_ctrlpt->sc_ctrlpt_handles.value_handle;
+ hvx_params.type = BLE_GATT_HVX_INDICATION;
+ hvx_params.offset = 0;
+ hvx_params.p_len = &hvx_len;
+ hvx_params.p_data = encoded_ctrl_rsp;
+
+ err_code = sd_ble_gatts_hvx(p_sc_ctrlpt->conn_handle, &hvx_params);
+
+ if (err_code == NRF_SUCCESS)
+ {
+ p_sc_ctrlpt->procedure_status = BLE_SCPT_NO_PROC_IN_PROGRESS;
+ }
+ return err_code;
+}
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/ble_cscs/ble_sc_ctrlpt.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/ble_cscs/ble_sc_ctrlpt.h
new file mode 100644
index 0000000..05a701d
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/ble_cscs/ble_sc_ctrlpt.h
@@ -0,0 +1,247 @@
+/**
+ * Copyright (c) 2013 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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
+ *
+ * @defgroup ble_sdk_srv_sc_ctrlpt Speed and Cadence Control Point
+ * @{
+ * @ingroup ble_sdk_srv
+ * @brief Speed and Cadence Control Point module.
+ *
+ * @details This module implements the Speed and Cadence control point behavior. It is used
+ * by the @ref ble_cscs module and the ble_sdk_srv_rsc module for control point
+ * mechanisms like setting a cumulative value, Start an automatic calibration,
+ * Update the sensor location or request the supported locations.
+ *
+ * @note Attention!
+ * To maintain compliance with Nordic Semiconductor ASA Bluetooth profile
+ * qualification listings, this section of source code must not be modified.
+ */
+
+#ifndef BLE_SC_CTRLPT_H__
+#define BLE_SC_CTRLPT_H__
+
+#include <stdint.h>
+#include <stdbool.h>
+#include "ble.h"
+#include "ble_srv_common.h"
+#include "ble_sensor_location.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define BLE_SC_CTRLPT_MAX_LEN 19 /**< maximum lenght for Speed and cadence control point characteristic value. */
+#define BLE_SC_CTRLPT_MIN_LEN 1 /**< minimum length for Speed and cadence control point characteristic value. */
+
+// Forward declaration of the ble_sc_ctrlpt_t type.
+typedef struct ble_sc_ctrlpt_s ble_sc_ctrlpt_t;
+
+
+/**@brief Speed and Cadence Control Point event type. */
+typedef enum
+{
+ BLE_SC_CTRLPT_EVT_UPDATE_LOCATION, /**< rcvd update location opcode (the control point handles the change of location automatically, the event just informs the application in case it needs to adjust its algorithm). */
+ BLE_SC_CTRLPT_EVT_SET_CUMUL_VALUE, /**< rcvd set cumulative value opcode, it is then up to the application to use the new cumulative value. */
+ BLE_SC_CTRLPT_EVT_START_CALIBRATION, /**< rcvd start calibration opcode, the application needs, at the end ot the calibration to call ble_sc_ctrlpt_send_rsp. */
+} ble_sc_ctrlpt_evt_type_t;
+
+
+/**@brief Speed and Cadence Control point event. */
+typedef struct
+{
+ ble_sc_ctrlpt_evt_type_t evt_type; /**< Type of event. */
+ union
+ {
+ ble_sensor_location_t update_location;
+ uint32_t cumulative_value;
+ }params;
+} ble_sc_ctrlpt_evt_t;
+
+
+/** Speed and Cadence Control Point operator code (see RSC service specification)*/
+typedef enum {
+ BLE_SCPT_SET_CUMULATIVE_VALUE = 0x01, /**< Operator to set a given cumulative value. */
+ BLE_SCPT_START_AUTOMATIC_CALIBRATION = 0x02, /**< Operator to start automatic calibration. */
+ BLE_SCPT_UPDATE_SENSOR_LOCATION = 0x03, /**< Operator to update the sensor location. */
+ BLE_SCPT_REQUEST_SUPPORTED_SENSOR_LOCATIONS = 0x04, /**< Operator to request the supported sensor locations. */
+ BLE_SCPT_RESPONSE_CODE = 0x10, /**< Response Code. */
+} ble_scpt_operator_t;
+
+
+/** Speed and Cadence Control Point response parameter (see RSC service specification)*/
+typedef enum {
+ BLE_SCPT_SUCCESS = 0x01, /**< Sucess Response. */
+ BLE_SCPT_OP_CODE_NOT_SUPPORTED = 0x02, /**< Error Response received opcode not supported. */
+ BLE_SCPT_INVALID_PARAMETER = 0x03, /**< Error Response received parameter invalid. */
+ BLE_SCPT_OPERATION_FAILED = 0x04, /**< Error Response operation failed. */
+} ble_scpt_response_t;
+
+
+/** Speed and Cadence Control Point procedure status (indicates is a procedure is in progress or not and which procedure is in progress*/
+typedef enum {
+ BLE_SCPT_NO_PROC_IN_PROGRESS = 0x00, /**< No procedure in progress. */
+ BLE_SCPT_AUTOMATIC_CALIB_IN_PROGRESS = 0x01, /**< Automatic Calibration is in progress. */
+ BLE_SCPT_INDICATION_PENDING = 0x02, /**< Control Point Indication is pending. */
+ BLE_SCPT_IND_CONFIRM_PENDING = 0x03, /**< Waiting for the indication confirmation. */
+}ble_scpt_procedure_status_t;
+
+/**@brief Speed and Cadence Control point event handler type. */
+typedef ble_scpt_response_t (*ble_sc_ctrlpt_evt_handler_t) (ble_sc_ctrlpt_t * p_sc_ctrlpt,
+ ble_sc_ctrlpt_evt_t * p_evt);
+
+
+typedef struct{
+ ble_scpt_operator_t opcode;
+ uint32_t cumulative_value;
+ ble_sensor_location_t location;
+}ble_sc_ctrlpt_val_t;
+
+
+typedef struct{
+ ble_scpt_operator_t opcode;
+ ble_scpt_response_t status;
+ ble_sensor_location_t location_list[BLE_NB_MAX_SENSOR_LOCATIONS];
+}ble_sc_ctrlpt_rsp_t;
+
+
+/**
+ * \defgroup BLE_SRV_SC_CTRLPT_SUPP_FUNC Control point functionalities.
+ *@{
+ */
+#define BLE_SRV_SC_CTRLPT_SENSOR_LOCATIONS_OP_SUPPORTED 0x01 /**< Support for sensor location related operations */
+#define BLE_SRV_SC_CTRLPT_CUM_VAL_OP_SUPPORTED 0x02 /**< Support for setting cumulative value related operations */
+#define BLE_SRV_SC_CTRLPT_START_CALIB_OP_SUPPORTED 0x04 /**< Support for starting calibration related operations */
+/**
+ *@}
+ */
+
+/**@brief Speed and Cadence Control Point init structure. This contains all options and data
+* needed for initialization of the Speed and Cadence Control Point module. */
+typedef struct
+{
+ ble_srv_cccd_security_mode_t sc_ctrlpt_attr_md; /**< Initial security level for cycling speed and cadence control point attribute */
+ uint8_t supported_functions; /**< supported control point functionalities see @ref BLE_SRV_SC_CTRLPT_SUPP_FUNC. */
+ uint16_t service_handle; /**< Handle of the parent service (as provided by the BLE stack). */
+ ble_sc_ctrlpt_evt_handler_t evt_handler; /**< event handler */
+ ble_sensor_location_t *list_supported_locations; /**< list of supported sensor locations.*/
+ uint8_t size_list_supported_locations; /**< number of supported sensor locations in the list.*/
+ uint16_t sensor_location_handle; /**< handle for the sensor location characteristic (if sensor_location related operation are supported).*/
+ ble_srv_error_handler_t error_handler; /**< Function to be called in case of an error. */
+} ble_cs_ctrlpt_init_t;
+
+
+/**@brief Speed and Cadence Control Point response indication structure. */
+typedef struct
+{
+ ble_scpt_response_t status; /**< control point response status .*/
+ uint8_t len; /**< control point response length .*/
+ uint8_t encoded_ctrl_rsp[BLE_SC_CTRLPT_MAX_LEN]; /**< control point encoded response.*/
+}ble_sc_ctrlpt_resp_t;
+
+
+/**@brief Speed and Cadence Control Point structure. This contains various status information for
+ * the Speed and Cadence Control Point behavior. */
+struct ble_sc_ctrlpt_s
+{
+ uint8_t supported_functions; /**< supported control point functionalities see @ref BLE_SRV_SC_CTRLPT_SUPP_FUNC. */
+ uint16_t service_handle; /**< Handle of the parent service (as provided by the BLE stack). */
+ ble_gatts_char_handles_t sc_ctrlpt_handles; /**< Handles related to the Speed and Cadence Control Point characteristic. */
+ uint16_t conn_handle; /**< Handle of the current connection (as provided by the BLE stack, is BLE_CONN_HANDLE_INVALID if not in a connection). */
+ ble_sensor_location_t list_supported_locations[BLE_NB_MAX_SENSOR_LOCATIONS]; /**< list of supported sensor locations.*/
+ uint8_t size_list_supported_locations; /**< number of supported sensor locations in the list.*/
+ ble_sc_ctrlpt_evt_handler_t evt_handler; /**< Handle of the parent service (as provided by the BLE stack). */
+ uint16_t sensor_location_handle; /**< handle for the sensor location characteristic (if sensor_location related operation are supported).*/
+ ble_scpt_procedure_status_t procedure_status; /**< status of possible procedure*/
+ ble_srv_error_handler_t error_handler; /**< Function to be called in case of an error. */
+ ble_sc_ctrlpt_resp_t response; /**< pending response data.*/
+};
+
+#define SCPT_OPCODE_POS 0 /**< Request opcode position. */
+#define SCPT_PARAMETER_POS 1 /**< Request parameter position. */
+
+#define SCPT_RESPONSE_REQUEST_OPCODE_POS 1 /**< Response position of requested opcode. */
+#define SCPT_RESPONSE_CODE_POS 2 /**< Response position of response code. */
+#define SCPT_RESPONSE_PARAMETER 3 /**< Response position of response parameter. */
+
+#define SCPT_MIN_RESPONSE_SIZE 3 /**< Minimum size for control point response. */
+#define SCPT_MAX_RESPONSE_SIZE (SCPT_MIN_RESPONSE_SIZE + NB_MAX_SENSOR_LOCATIONS) /**< Maximum size for control point response. */
+
+
+/**@brief Function for Initializing the Speed and Cadence Control Point.
+ *
+ * @details Function for Initializing the Speed and Cadence Control Point.
+ * @param[in] p_sc_ctrlpt Speed and Cadence Control Point structure.
+ * @param[in] p_sc_ctrlpt_init Information needed to initialize the control point behavior.
+ *
+ * @return NRF_SUCCESS on successful initialization of service, otherwise an error code.
+ */
+uint32_t ble_sc_ctrlpt_init(ble_sc_ctrlpt_t * p_sc_ctrlpt,
+ ble_cs_ctrlpt_init_t const * p_sc_ctrlpt_init);
+
+
+/**@brief Function for sending a control point response.
+ *
+ * @details Function for sending a control point response when the control point received was
+ * BLE_SCPT_START_AUTOMATIC_CALIBRATION. To be called after the calibration procedure is finished.
+ *
+ * @param[in] p_sc_ctrlpt Speed and Cadence Control Point structure.
+ * @param[in] response_status status to include in the control point response.
+ */
+uint32_t ble_sc_ctrlpt_rsp_send(ble_sc_ctrlpt_t * p_sc_ctrlpt, ble_scpt_response_t response_status);
+
+
+/**@brief Speed and Cadence Control Point BLE stack event handler.
+ *
+ * @details Handles all events from the BLE stack of interest to the Speed and Cadence Control Point.
+ *
+ * @param[in] p_sc_ctrlpt Speed and Cadence Control Point structure.
+ * @param[in] p_ble_evt Event received from the BLE stack.
+ */
+void ble_sc_ctrlpt_on_ble_evt(ble_sc_ctrlpt_t * p_sc_ctrlpt, ble_evt_t const * p_ble_evt);
+
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // BLE_SC_CTRLPT_H__
+
+/** @} */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/ble_cts_c/ble_cts_c.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/ble_cts_c/ble_cts_c.c
new file mode 100644
index 0000000..09d4d7d
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/ble_cts_c/ble_cts_c.c
@@ -0,0 +1,357 @@
+/**
+ * Copyright (c) 2012 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#include "sdk_common.h"
+#if NRF_MODULE_ENABLED(BLE_CTS_C)
+#include <string.h>
+#include "ble.h"
+#include "ble_srv_common.h"
+#include "ble_gattc.h"
+#include "ble_cts_c.h"
+#include "ble_date_time.h"
+#include "ble_db_discovery.h"
+#define NRF_LOG_MODULE_NAME ble_cts_c
+#include "nrf_log.h"
+NRF_LOG_MODULE_REGISTER();
+
+#define CTS_YEAR_MIN 1582 /**< The lowest valid Current Time year is the year when the western calendar was introduced. */
+#define CTS_YEAR_MAX 9999 /**< The highest possible Current Time. */
+
+#define CTS_C_CURRENT_TIME_EXPECTED_LENGTH 10 /**< | Year |Month |Day |Hours |Minutes |Seconds |Weekday |Fraction|Reason |
+ | 2 bytes |1 byte |1 byte |1 byte |1 byte |1 byte |1 byte |1 byte |1 byte | = 10 bytes. */
+
+
+/**@brief Function for handling events from the database discovery module.
+ *
+ * @details This function will handle an event from the database discovery module, and determine
+ * if it relates to the discovery of Current Time Service at the peer. If so, it will
+ * call the application's event handler indicating that the Current Time Service has been
+ * discovered at the peer. It also populates the event with the service related
+ * information before providing it to the application.
+ *
+ * @param[in] p_evt Pointer to the event received from the database discovery module.
+ *
+ */
+void ble_cts_c_on_db_disc_evt(ble_cts_c_t * p_cts, ble_db_discovery_evt_t * p_evt)
+{
+ NRF_LOG_DEBUG("Database Discovery handler called with event 0x%x", p_evt->evt_type);
+
+ ble_cts_c_evt_t evt;
+ const ble_gatt_db_char_t * p_chars = p_evt->params.discovered_db.charateristics;
+
+ evt.evt_type = BLE_CTS_C_EVT_DISCOVERY_FAILED;
+ evt.conn_handle = p_evt->conn_handle;
+
+ // Check if the Current Time Service was discovered.
+ if ( (p_evt->evt_type == BLE_DB_DISCOVERY_COMPLETE)
+ && (p_evt->params.discovered_db.srv_uuid.uuid == BLE_UUID_CURRENT_TIME_SERVICE)
+ && (p_evt->params.discovered_db.srv_uuid.type == BLE_UUID_TYPE_BLE))
+ {
+ // Find the handles of the Current Time characteristic.
+ for (uint32_t i = 0; i < p_evt->params.discovered_db.char_count; i++)
+ {
+ if (p_evt->params.discovered_db.charateristics[i].characteristic.uuid.uuid ==
+ BLE_UUID_CURRENT_TIME_CHAR)
+ {
+ // Found Current Time characteristic. Store CCCD and value handle and break.
+ evt.params.char_handles.cts_handle = p_chars->characteristic.handle_value;
+ evt.params.char_handles.cts_cccd_handle = p_chars->cccd_handle;
+ break;
+ }
+ }
+
+ NRF_LOG_INFO("Current Time Service discovered at peer.");
+
+ evt.evt_type = BLE_CTS_C_EVT_DISCOVERY_COMPLETE;
+ }
+ p_cts->evt_handler(p_cts, &evt);
+}
+
+
+uint32_t ble_cts_c_init(ble_cts_c_t * p_cts, ble_cts_c_init_t const * p_cts_init)
+{
+ //Verify that the parameters needed for to initialize this instance of CTS are not NULL.
+ VERIFY_PARAM_NOT_NULL(p_cts);
+ VERIFY_PARAM_NOT_NULL(p_cts_init);
+ VERIFY_PARAM_NOT_NULL(p_cts_init->error_handler);
+ VERIFY_PARAM_NOT_NULL(p_cts_init->evt_handler);
+
+ static ble_uuid_t cts_uuid;
+
+ BLE_UUID_BLE_ASSIGN(cts_uuid, BLE_UUID_CURRENT_TIME_SERVICE);
+
+ p_cts->evt_handler = p_cts_init->evt_handler;
+ p_cts->error_handler = p_cts_init->error_handler;
+ p_cts->conn_handle = BLE_CONN_HANDLE_INVALID;
+ p_cts->char_handles.cts_handle = BLE_GATT_HANDLE_INVALID;
+ p_cts->char_handles.cts_cccd_handle = BLE_GATT_HANDLE_INVALID;
+
+ return ble_db_discovery_evt_register(&cts_uuid);
+}
+
+
+/**@brief Function for decoding a read from the current time characteristic.
+ *
+ * @param[in] p_time Current Time structure.
+ * @param[in] p_data Pointer to the buffer containing the current time.
+ * @param[in] length length of the buffer containing the current time.
+ *
+ * @return NRF_SUCCESS if the time struct is valid.
+ * @return NRF_ERROR_DATA_SIZE if length does not match the expected size of the data.
+ */
+static uint32_t current_time_decode(current_time_char_t * p_time,
+ uint8_t const * p_data,
+ uint32_t const length)
+{
+ //lint -save -e415 -e416 "Access of out of bounds pointer" "Creation of out of bounds pointer"
+
+ if (length != CTS_C_CURRENT_TIME_EXPECTED_LENGTH)
+ {
+ // Return to prevent accessing out of bounds data.
+ return NRF_ERROR_DATA_SIZE;
+ }
+
+ NRF_LOG_DEBUG("Current Time read response data:");
+ NRF_LOG_HEXDUMP_DEBUG(p_data, 10);
+
+ uint32_t index = 0;
+
+ // Date.
+ index += ble_date_time_decode(&p_time->exact_time_256.day_date_time.date_time, p_data);
+
+ // Day of week.
+ p_time->exact_time_256.day_date_time.day_of_week = p_data[index++];
+
+ // Fractions of a second.
+ p_time->exact_time_256.fractions256 = p_data[index++];
+
+ // Reason for updating the time.
+ p_time->adjust_reason.manual_time_update = (p_data[index] >> 0) & 0x01;
+ p_time->adjust_reason.external_reference_time_update = (p_data[index] >> 1) & 0x01;
+ p_time->adjust_reason.change_of_time_zone = (p_data[index] >> 2) & 0x01;
+ p_time->adjust_reason.change_of_daylight_savings_time = (p_data[index] >> 3) & 0x01;
+
+ //lint -restore
+ return NRF_SUCCESS;
+}
+
+
+/**@brief Function for decoding a read from the current time characteristic.
+ *
+ * @param[in] p_time Current Time struct.
+ *
+ * @return NRF_SUCCESS if the time struct is valid.
+ * @return NRF_ERROR_INVALID_DATA if the time is out of bounds.
+ */
+static uint32_t current_time_validate(current_time_char_t * p_time)
+{
+ // Year.
+ if ( (p_time->exact_time_256.day_date_time.date_time.year > CTS_YEAR_MAX)
+ || ((p_time->exact_time_256.day_date_time.date_time.year < CTS_YEAR_MIN)
+ && (p_time->exact_time_256.day_date_time.date_time.year != 0)))
+ {
+ return NRF_ERROR_INVALID_DATA;
+ }
+
+ // Month.
+ if (p_time->exact_time_256.day_date_time.date_time.month > 12)
+ {
+ return NRF_ERROR_INVALID_DATA;
+ }
+
+ // Day.
+ if (p_time->exact_time_256.day_date_time.date_time.day > 31)
+ {
+ return NRF_ERROR_INVALID_DATA;
+ }
+
+ // Hours.
+ if (p_time->exact_time_256.day_date_time.date_time.hours > 23)
+ {
+ return NRF_ERROR_INVALID_DATA;
+ }
+
+ // Minutes.
+ if (p_time->exact_time_256.day_date_time.date_time.minutes > 59)
+ {
+ return NRF_ERROR_INVALID_DATA;
+ }
+
+ // Seconds.
+ if (p_time->exact_time_256.day_date_time.date_time.seconds > 59)
+ {
+ return NRF_ERROR_INVALID_DATA;
+ }
+
+ // Day of week.
+ if (p_time->exact_time_256.day_date_time.day_of_week > 7)
+ {
+ return NRF_ERROR_INVALID_DATA;
+ }
+
+ return NRF_SUCCESS;
+}
+
+
+/**@brief Function for reading the current time. The time is decoded, then it is validated.
+ * Depending on the outcome the cts event handler will be called with
+ * the current time event or an invalid time event.
+ *
+ * @param[in] p_cts Current Time Service client structure.
+ * @param[in] p_ble_evt Event received from the BLE stack.
+ */
+static void current_time_read(ble_cts_c_t * p_cts, ble_evt_t const * p_ble_evt)
+{
+ ble_cts_c_evt_t evt;
+ uint32_t err_code = NRF_SUCCESS;
+
+ // Check if the event is on the same connection as this cts instance
+ if (p_cts->conn_handle != p_ble_evt->evt.gattc_evt.conn_handle)
+ {
+ return;
+ }
+
+ if (p_ble_evt->evt.gattc_evt.gatt_status == BLE_GATT_STATUS_SUCCESS)
+ {
+ err_code = current_time_decode(&evt.params.current_time,
+ p_ble_evt->evt.gattc_evt.params.read_rsp.data,
+ p_ble_evt->evt.gattc_evt.params.read_rsp.len);
+
+ if (err_code != NRF_SUCCESS)
+ {
+ // The data length was invalid, decoding was not completed.
+ evt.evt_type = BLE_CTS_C_EVT_INVALID_TIME;
+ }
+ else
+ {
+ // Verify That the time is valid.
+ err_code = current_time_validate(&evt.params.current_time);
+
+ if (err_code != NRF_SUCCESS)
+ {
+ // Invalid time received.
+ evt.evt_type = BLE_CTS_C_EVT_INVALID_TIME;
+ }
+ else
+ {
+ // Valid time reveiced.
+ evt.evt_type = BLE_CTS_C_EVT_CURRENT_TIME;
+ }
+ }
+ p_cts->evt_handler(p_cts, &evt);
+ }
+}
+
+
+/**@brief Function for handling the Disconnect event.
+ *
+ * @param[in] p_cts Current Time Service client structure.
+ * @param[in] p_ble_evt Event received from the BLE stack.
+ */
+static void on_disconnect(ble_cts_c_t * p_cts, ble_evt_t const * p_ble_evt)
+{
+ if (p_cts->conn_handle == p_ble_evt->evt.gap_evt.conn_handle)
+ {
+ p_cts->conn_handle = BLE_CONN_HANDLE_INVALID;
+ }
+
+ if (ble_cts_c_is_cts_discovered(p_cts))
+ {
+ // There was a valid instance of cts on the peer. Send an event to the
+ // application, so that it can do any clean up related to this module.
+ ble_cts_c_evt_t evt;
+
+ evt.evt_type = BLE_CTS_C_EVT_DISCONN_COMPLETE;
+
+ p_cts->evt_handler(p_cts, &evt);
+ p_cts->char_handles.cts_handle = BLE_GATT_HANDLE_INVALID;
+ p_cts->char_handles.cts_cccd_handle = BLE_GATT_HANDLE_INVALID;
+ }
+}
+
+
+void ble_cts_c_on_ble_evt(ble_evt_t const * p_ble_evt, void * p_context)
+{
+ ble_cts_c_t * p_cts = (ble_cts_c_t *)p_context;
+ NRF_LOG_DEBUG("BLE event handler called with event 0x%x", p_ble_evt->header.evt_id);
+
+ switch (p_ble_evt->header.evt_id)
+ {
+ case BLE_GATTC_EVT_READ_RSP:
+ current_time_read(p_cts, p_ble_evt);
+ break;
+
+ case BLE_GAP_EVT_DISCONNECTED:
+ on_disconnect(p_cts, p_ble_evt);
+ break;
+
+ default:
+ // No implementation needed.
+ break;
+ }
+}
+
+
+uint32_t ble_cts_c_current_time_read(ble_cts_c_t const * p_cts)
+{
+ if (!ble_cts_c_is_cts_discovered(p_cts))
+ {
+ return NRF_ERROR_NOT_FOUND;
+ }
+
+ return sd_ble_gattc_read(p_cts->conn_handle, p_cts->char_handles.cts_handle, 0);
+}
+
+
+uint32_t ble_cts_c_handles_assign(ble_cts_c_t * p_cts,
+ const uint16_t conn_handle,
+ const ble_cts_c_handles_t * p_peer_handles)
+{
+ VERIFY_PARAM_NOT_NULL(p_cts);
+
+ p_cts->conn_handle = conn_handle;
+ if (p_peer_handles != NULL)
+ {
+ p_cts->char_handles.cts_cccd_handle = p_peer_handles->cts_cccd_handle;
+ p_cts->char_handles.cts_handle = p_peer_handles->cts_handle;
+ }
+
+ return NRF_SUCCESS;
+}
+#endif // NRF_MODULE_ENABLED(BLE_CTS_C)
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/ble_cts_c/ble_cts_c.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/ble_cts_c/ble_cts_c.h
new file mode 100644
index 0000000..1abdf9c
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/ble_cts_c/ble_cts_c.h
@@ -0,0 +1,284 @@
+/**
+ * Copyright (c) 2014 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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
+ *
+ * @defgroup ble_cts_c Current Time Service client
+ * @{
+ * @ingroup ble_sdk_srv
+ * @brief Current Time Service client module.
+ *
+ * @details This module implements the Current Time Service (CTS) client-peripheral role of
+ * the Time Profile. After security is established, the module tries to discover the
+ * Current Time Service and Characteristic on the central side. If this succeeds,
+ * the application can trigger a read of the current time from the connected server.
+ *
+ * The module informs the application about a successful discovery using the
+ * @ref BLE_CTS_C_EVT_DISCOVERY_COMPLETE event. The handles for the CTS server is now
+ * available in the @ref ble_cts_c_evt_t structure. These handles must be assigned to an
+ * instance of CTS_C, using @ref ble_cts_c_handles_assign. For more information about
+ * service discovery, see the ble_discovery module documentation @ref lib_ble_db_discovery.
+ *
+ * The application can then use the function @ref ble_cts_c_current_time_read to read the
+ * current time. If the read succeeds, it will trigger either a
+ * @ref BLE_CTS_C_EVT_CURRENT_TIME event or a @ref BLE_CTS_C_EVT_INVALID_TIME event
+ * (depending on if the data that was read was actually a valid time), which is then sent
+ * to the application. The current time is then available in the params field of the
+ * passed @ref ble_cts_c_evt_t structure.
+ *
+ * @note The application must register this module as BLE event observer using the
+ * NRF_SDH_BLE_OBSERVER macro. Example:
+ * @code
+ * ble_cts_c_t instance;
+ * NRF_SDH_BLE_OBSERVER(anything, BLE_CTS_C_BLE_OBSERVER_PRIO,
+ * ble_cts_c_on_ble_evt, &instance);
+ * @endcode
+ */
+
+#ifndef BLE_CTS_C_H__
+#define BLE_CTS_C_H__
+
+#include "ble_srv_common.h"
+#include "ble_gattc.h"
+#include "ble.h"
+#include "ble_date_time.h"
+#include "ble_db_discovery.h"
+#include "nrf_sdh_ble.h"
+#include <stdint.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**@brief Macro for defining a ble_bps instance.
+ *
+ * @param _name Name of the instance.
+ * @hideinitializer
+ */
+#define BLE_CTS_C_DEF(_name) \
+static ble_cts_c_t _name; \
+NRF_SDH_BLE_OBSERVER(_name ## _obs, \
+ BLE_CTS_C_BLE_OBSERVER_PRIO, \
+ ble_cts_c_on_ble_evt, &_name)
+
+/** @brief Macro for defining multiple ble_cts_c instances.
+ *
+ * @param _name Name of the array of instances.
+ * @param _cnt Number of instances to define.
+ * @hideinitializer
+ */
+#define BLE_CTS_C_ARRAY_DEF(_name, _cnt) \
+static ble_cts_c_t _name[_cnt]; \
+NRF_SDH_BLE_OBSERVERS(_name ## _obs, \
+ BLE_CTS_C_BLE_OBSERVER_PRIO, \
+ ble_cts_c_on_ble_evt, &_name, _cnt)
+
+
+/**@brief "Day Date Time" field of the "Exact Time 256" field of the Current Time Characteristic. */
+typedef struct
+{
+ ble_date_time_t date_time;
+ uint8_t day_of_week;
+} day_date_time_t;
+
+/**@brief "Exact Time 256" field of the Current Time Characteristic. */
+typedef struct
+{
+ day_date_time_t day_date_time;
+ uint8_t fractions256;
+} exact_time_256_t;
+
+/**@brief "Adjust Reason" field of the Current Time Characteristic. */
+typedef struct
+{
+ uint8_t manual_time_update : 1;
+ uint8_t external_reference_time_update : 1;
+ uint8_t change_of_time_zone : 1;
+ uint8_t change_of_daylight_savings_time : 1;
+} adjust_reason_t;
+
+/**@brief Data structure for the Current Time Characteristic. */
+typedef struct
+{
+ exact_time_256_t exact_time_256;
+ adjust_reason_t adjust_reason;
+} current_time_char_t;
+
+// Forward declaration of the ble_cts_c_t type.
+typedef struct ble_cts_c_s ble_cts_c_t;
+
+/**@brief Current Time Service client event type. */
+typedef enum
+{
+ BLE_CTS_C_EVT_DISCOVERY_COMPLETE, /**< The Current Time Service was found at the peer. */
+ BLE_CTS_C_EVT_DISCOVERY_FAILED, /**< The Current Time Service was not found at the peer. */
+ BLE_CTS_C_EVT_DISCONN_COMPLETE, /**< Event indicating that the Current Time Service client module has finished processing the BLE_GAP_EVT_DISCONNECTED event. This event is raised only if a valid instance of the Current Time Service was found at the server. The event can be used by the application to do clean up related to the Current Time Service client.*/
+ BLE_CTS_C_EVT_CURRENT_TIME, /**< A new current time reading has been received. */
+ BLE_CTS_C_EVT_INVALID_TIME /**< The current time value received from the peer is invalid.*/
+} ble_cts_c_evt_type_t;
+
+/**@brief Structure containing the handles related to the Heart Rate Service found on the peer. */
+typedef struct
+{
+ uint16_t cts_handle; /**< Handle of the Current Time characteristic as provided by the SoftDevice. */
+ uint16_t cts_cccd_handle; /**< Handle of the CCCD of the Current Time characteristic. */
+} ble_cts_c_handles_t;
+
+/**@brief Current Time Service client event. */
+typedef struct
+{
+ ble_cts_c_evt_type_t evt_type; /**< Type of event. */
+ uint16_t conn_handle; /**< Connection handle on which the CTS service was discovered on the peer device. This will be filled if the evt_type is @ref BLE_CTS_C_EVT_DISCOVERY_COMPLETE.*/
+ union
+ {
+ current_time_char_t current_time; /**< Current Time Characteristic data. This will be filled when the evt_type is @ref BLE_CTS_C_EVT_CURRENT_TIME. */
+ ble_cts_c_handles_t char_handles; /**< Current Time related handles found on the peer device. This will be filled when the evt_type is @ref BLE_HRS_C_EVT_DISCOVERY_COMPLETE.*/
+ } params;
+} ble_cts_c_evt_t;
+
+/**@brief Current Time Service client event handler type. */
+typedef void (* ble_cts_c_evt_handler_t) (ble_cts_c_t * p_cts, ble_cts_c_evt_t * p_evt);
+
+
+/**@brief Current Time Service client structure. This structure contains status information for the client. */
+struct ble_cts_c_s
+{
+ ble_cts_c_evt_handler_t evt_handler; /**< Event handler to be called for handling events from the Current Time Service client. */
+ ble_srv_error_handler_t error_handler; /**< Function to be called if an error occurs. */
+ ble_cts_c_handles_t char_handles; /**< Handles of Current Time Characteristic at the peer (handles are provided by the BLE stack through the DB Discovery module). */
+ uint16_t conn_handle; /**< Handle of the current connection. BLE_CONN_HANDLE_INVALID if not in a connection. */
+};
+
+/**@brief Current Time Service client init structure. This structure contains all options and data needed for initialization of the client.*/
+typedef struct
+{
+ ble_cts_c_evt_handler_t evt_handler; /**< Event handler to be called for handling events from the Current Time Service client. */
+ ble_srv_error_handler_t error_handler; /**< Function to be called if an error occurs. */
+} ble_cts_c_init_t;
+
+
+/**@brief Function for initializing the Current Time Service client.
+ *
+ * @details This function must be used by the application to initialize the Current Time Service client.
+ *
+ * @param[out] p_cts Current Time Service client structure. This structure must
+ * be supplied by the application. It is initialized by this
+ * function and can later be used to identify this particular client
+ * instance.
+ * @param[in] p_cts_init Information needed to initialize the Current Time Service client.
+ *
+ * @retval NRF_SUCCESS If the service was initialized successfully.
+ */
+uint32_t ble_cts_c_init(ble_cts_c_t * p_cts, const ble_cts_c_init_t * p_cts_init);
+
+
+/**@brief Function for handling events from the database discovery module.
+ *
+ * @details This function will handle an event from the database discovery module, and determine
+ * if it relates to the discovery of CTS at the peer. If so, it will
+ * call the application's event handler indicating that CTS has been
+ * discovered. It also populates the event with the service related
+ * information before providing it to the application.
+ *
+ * @param[in] p_cts Pointer to the CTS client structure.
+ * @param[in] p_evt Pointer to the event received from the database discovery module.
+ */
+ void ble_cts_c_on_db_disc_evt(ble_cts_c_t * p_cts, ble_db_discovery_evt_t * p_evt);
+
+
+/**@brief Function for handling the application's BLE stack events.
+ *
+ * @details This function handles all events from the BLE stack that are of interest to the
+ * Current Time Service client. This is a callback function that must be dispatched
+ * from main application context.
+ *
+ * @param[in] p_ble_evt Event received from the BLE stack.
+ * @param[in] p_context Current Time Service client structure.
+ */
+void ble_cts_c_on_ble_evt(ble_evt_t const * p_ble_evt, void * p_context);
+
+
+/**@brief Function for checking whether the peer's Current Time Service instance and the Current Time
+ * Characteristic have been discovered.
+ *
+ * @param[in] p_cts Current Time Service client structure.
+ */
+static __INLINE bool ble_cts_c_is_cts_discovered(const ble_cts_c_t * p_cts)
+{
+ return (p_cts->char_handles.cts_handle != BLE_GATT_HANDLE_INVALID);
+}
+
+
+/**@brief Function for reading the peer's Current Time Service Current Time Characteristic.
+ *
+ * @param[in] p_cts Current Time Service client structure.
+ *
+ * @retval NRF_SUCCESS If the operation is successful. Otherwise, an error code is returned.
+ */
+uint32_t ble_cts_c_current_time_read(ble_cts_c_t const * p_cts);
+
+
+/**@brief Function for assigning handles to a this instance of cts_c.
+ *
+ * @details Call this function when a link has been established with a peer to
+ * associate the link to this instance of the module. This makes it
+ * possible to handle several links and associate each link to a particular
+ * instance of this module. The connection handle and attribute handles will be
+ * provided from the discovery event @ref BLE_CTS_C_EVT_DISCOVERY_COMPLETE.
+ *
+ * @param[in] p_cts Pointer to the CTS client structure instance to associate.
+ * @param[in] conn_handle Connection handle to associated with the given CTS instance.
+ * @param[in] p_peer_handles Attribute handles for the CTS server you want this CTS client to
+ * interact with.
+ *
+ * @retval NRF_SUCCESS If the operation was successful.
+ * @retval NRF_ERROR_NULL If a p_cts was a NULL pointer.
+ */
+uint32_t ble_cts_c_handles_assign(ble_cts_c_t * p_cts,
+ const uint16_t conn_handle,
+ const ble_cts_c_handles_t * p_peer_handles);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // BLE_CTS_C_H__
+
+/** @} */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/ble_dfu/ble_dfu.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/ble_dfu/ble_dfu.c
new file mode 100644
index 0000000..18961ef
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/ble_dfu/ble_dfu.c
@@ -0,0 +1,337 @@
+/**
+ * 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+/* Attention!
+ * To maintain compliance with Nordic Semiconductor ASA's Bluetooth profile
+ * qualification listings, this section of source code must not be modified.
+ */
+
+#include "ble_dfu.h"
+#include <string.h>
+#include "ble_hci.h"
+#include "sdk_macros.h"
+#include "ble_srv_common.h"
+#include "nrf_nvic.h"
+#include "nrf_sdm.h"
+#include "nrf_soc.h"
+#include "nrf_log.h"
+#include "nrf_dfu_ble_svci_bond_sharing.h"
+#include "nrf_bootloader_info.h"
+#include "nrf_svci_async_function.h"
+#include "nrf_pwr_mgmt.h"
+#include "peer_manager.h"
+#include "gatts_cache_manager.h"
+#include "peer_id.h"
+
+#define MAX_CTRL_POINT_RESP_PARAM_LEN 3 /**< Max length of the responses. */
+
+#define BLE_DFU_SERVICE_UUID 0xFE59 /**< The 16-bit UUID of the Secure DFU Service. */
+
+static ble_dfu_buttonless_t m_dfu; /**< Structure holding information about the Buttonless Secure DFU Service. */
+
+NRF_SDH_BLE_OBSERVER(m_dfus_obs, BLE_DFU_BLE_OBSERVER_PRIO, ble_dfu_buttonless_on_ble_evt, &m_dfu);
+
+/**@brief Function for handling write events to the Buttonless Secure DFU Service Service Control Point characteristic.
+ *
+ * @param[in] p_evt_write Write event received from the BLE stack.
+ */
+static void on_ctrlpt_write(ble_gatts_evt_write_t const * p_evt_write)
+{
+ uint32_t err_code;
+
+
+ ble_gatts_rw_authorize_reply_params_t write_authorize_reply;
+ memset(&write_authorize_reply, 0, sizeof(write_authorize_reply));
+
+ write_authorize_reply.type = BLE_GATTS_AUTHORIZE_TYPE_WRITE;
+
+ if (m_dfu.is_ctrlpt_indication_enabled)
+ {
+ write_authorize_reply.params.write.update = 1;
+ write_authorize_reply.params.write.gatt_status = BLE_GATT_STATUS_SUCCESS;
+ }
+ else
+ {
+ write_authorize_reply.params.write.gatt_status = DFU_RSP_CCCD_CONFIG_IMPROPER;
+ }
+
+ // Authorize the write request
+ do {
+ err_code = sd_ble_gatts_rw_authorize_reply(m_dfu.conn_handle, &write_authorize_reply);
+ } while (err_code == NRF_ERROR_BUSY);
+
+
+ if (write_authorize_reply.params.write.gatt_status != BLE_GATT_STATUS_SUCCESS)
+ {
+ return;
+ }
+
+ // Forward the write event to the Buttonless DFU module.
+ ble_dfu_buttonless_on_ctrl_pt_write(p_evt_write);
+}
+
+
+/**@brief Write authorization request event handler.
+ *
+ * @details The write authorization request event handler is called when writing to the control point.
+ *
+ * @param[in] p_ble_evt Event received from the BLE stack.
+ */
+static void on_rw_authorize_req(ble_evt_t const * p_ble_evt)
+{
+ if (p_ble_evt->evt.gatts_evt.conn_handle != m_dfu.conn_handle)
+ {
+ return;
+ }
+
+ const ble_gatts_evt_rw_authorize_request_t * p_auth_req =
+ &p_ble_evt->evt.gatts_evt.params.authorize_request;
+
+ if (
+ (p_auth_req->type == BLE_GATTS_AUTHORIZE_TYPE_WRITE) &&
+ (p_auth_req->request.write.handle == m_dfu.control_point_char.value_handle) &&
+ (p_auth_req->request.write.op != BLE_GATTS_OP_PREP_WRITE_REQ) &&
+ (p_auth_req->request.write.op != BLE_GATTS_OP_EXEC_WRITE_REQ_NOW) &&
+ (p_auth_req->request.write.op != BLE_GATTS_OP_EXEC_WRITE_REQ_CANCEL)
+ )
+ {
+ on_ctrlpt_write(&p_auth_req->request.write);
+ }
+}
+
+
+/**@brief Connect event handler.
+ *
+ * @param[in] p_ble_evt Event received from the BLE stack.
+ */
+static void on_connect(ble_evt_t const * p_ble_evt)
+{
+ m_dfu.conn_handle = p_ble_evt->evt.gap_evt.conn_handle;
+}
+
+
+/**@brief Disconnect event handler.
+ *
+ * @param[in] p_ble_evt Event received from the BLE stack.
+ */
+static void on_disconnect(ble_evt_t const * p_ble_evt)
+{
+ if (m_dfu.conn_handle != p_ble_evt->evt.gatts_evt.conn_handle)
+ {
+ return;
+ }
+
+ m_dfu.conn_handle = BLE_CONN_HANDLE_INVALID;
+}
+
+
+/**@brief Write event handler.
+ *
+ * @param[in] p_ble_evt Event received from the BLE stack.
+ */
+static void on_write(ble_evt_t const * p_ble_evt)
+{
+ const ble_gatts_evt_write_t * p_evt_write = &p_ble_evt->evt.gatts_evt.params.write;
+
+ if (p_evt_write->handle != m_dfu.control_point_char.cccd_handle)
+ {
+ return;
+ }
+
+ if (p_evt_write->len == BLE_CCCD_VALUE_LEN)
+ {
+ // CCCD written, update indications state
+ m_dfu.is_ctrlpt_indication_enabled = ble_srv_is_indication_enabled(p_evt_write->data);
+
+ NRF_LOG_INFO("Received indication state %d",
+ m_dfu.is_ctrlpt_indication_enabled);
+ }
+}
+
+
+/**@brief Function for handling the HVC events.
+ *
+ * @details Handles HVC events from the BLE stack.
+ *
+ * @param[in] p_ble_evt Event received from the BLE stack.
+ */
+static void on_hvc(ble_evt_t const * p_ble_evt)
+{
+ uint32_t err_code;
+ ble_gatts_evt_hvc_t const * p_hvc = &p_ble_evt->evt.gatts_evt.params.hvc;
+
+ if (p_hvc->handle == m_dfu.control_point_char.value_handle)
+ {
+ // Enter bootloader if we were waiting for reset after hvc indication confimation.
+ if (m_dfu.is_waiting_for_reset)
+ {
+ err_code = ble_dfu_buttonless_bootloader_start_prepare();
+ if (err_code != NRF_SUCCESS)
+ {
+ m_dfu.evt_handler(BLE_DFU_EVT_BOOTLOADER_ENTER_FAILED);
+ }
+ }
+ }
+}
+
+
+void ble_dfu_buttonless_on_ble_evt(ble_evt_t const * p_ble_evt, void * p_context)
+{
+ VERIFY_PARAM_NOT_NULL_VOID(p_ble_evt);
+
+ switch (p_ble_evt->header.evt_id)
+ {
+ case BLE_GAP_EVT_CONNECTED:
+ on_connect(p_ble_evt);
+ break;
+
+ case BLE_GAP_EVT_DISCONNECTED:
+ on_disconnect(p_ble_evt);
+ break;
+
+ case BLE_GATTS_EVT_RW_AUTHORIZE_REQUEST:
+ on_rw_authorize_req(p_ble_evt);
+ break;
+
+ case BLE_GATTS_EVT_WRITE:
+ on_write(p_ble_evt);
+ break;
+
+ case BLE_GATTS_EVT_HVC:
+ on_hvc(p_ble_evt);
+ break;
+
+ default:
+ // no implementation
+ break;
+ }
+}
+
+
+uint32_t ble_dfu_buttonless_resp_send(ble_dfu_buttonless_op_code_t op_code, ble_dfu_buttonless_rsp_code_t rsp_code)
+{
+ // Send notification
+ uint32_t err_code;
+ const uint16_t len = 3;
+ uint16_t hvx_len;
+ uint8_t hvx_data[MAX_CTRL_POINT_RESP_PARAM_LEN];
+ ble_gatts_hvx_params_t hvx_params;
+
+ memset(&hvx_params, 0, sizeof(hvx_params));
+
+ hvx_len = len;
+ hvx_data[0] = DFU_OP_RESPONSE_CODE;
+ hvx_data[1] = (uint8_t)op_code;
+ hvx_data[2] = (uint8_t)rsp_code;
+
+ hvx_params.handle = m_dfu.control_point_char.value_handle;
+ hvx_params.type = BLE_GATT_HVX_INDICATION;
+ hvx_params.offset = 0;
+ hvx_params.p_len = &hvx_len;
+ hvx_params.p_data = hvx_data;
+
+
+ err_code = sd_ble_gatts_hvx(m_dfu.conn_handle, &hvx_params);
+ if ((err_code == NRF_SUCCESS) && (hvx_len != len))
+ {
+ err_code = NRF_ERROR_DATA_SIZE;
+ }
+
+ return err_code;
+}
+
+
+uint32_t ble_dfu_buttonless_bootloader_start_finalize(void)
+{
+ uint32_t err_code;
+
+ NRF_LOG_DEBUG("In ble_dfu_buttonless_bootloader_start_finalize\r\n");
+
+ err_code = sd_power_gpregret_clr(0, 0xffffffff);
+ VERIFY_SUCCESS(err_code);
+
+ err_code = sd_power_gpregret_set(0, BOOTLOADER_DFU_START);
+ VERIFY_SUCCESS(err_code);
+
+ // Indicate that the Secure DFU bootloader will be entered
+ m_dfu.evt_handler(BLE_DFU_EVT_BOOTLOADER_ENTER);
+
+ // Signal that DFU mode is to be enter to the power management module
+ nrf_pwr_mgmt_shutdown(NRF_PWR_MGMT_SHUTDOWN_GOTO_DFU);
+
+ return NRF_SUCCESS;
+}
+
+
+uint32_t ble_dfu_buttonless_init(const ble_dfu_buttonless_init_t * p_dfu_init)
+{
+ uint32_t err_code;
+ ble_uuid_t service_uuid;
+ ble_uuid128_t nordic_base_uuid = BLE_NORDIC_VENDOR_BASE_UUID;
+
+ VERIFY_PARAM_NOT_NULL(p_dfu_init);
+
+ // Initialize the service structure.
+ m_dfu.conn_handle = BLE_CONN_HANDLE_INVALID;
+ m_dfu.evt_handler = p_dfu_init->evt_handler;
+ m_dfu.is_waiting_for_reset = false;
+ m_dfu.is_ctrlpt_indication_enabled = false;
+
+ err_code = ble_dfu_buttonless_backend_init(&m_dfu);
+ VERIFY_SUCCESS(err_code);
+
+ BLE_UUID_BLE_ASSIGN(service_uuid, BLE_DFU_SERVICE_UUID);
+
+ // Add the DFU service declaration.
+ err_code = sd_ble_gatts_service_add(BLE_GATTS_SRVC_TYPE_PRIMARY,
+ &service_uuid,
+ &(m_dfu.service_handle));
+
+ VERIFY_SUCCESS(err_code);
+
+ // Add vendor specific base UUID to use with the Buttonless DFU characteristic.
+ err_code = sd_ble_uuid_vs_add(&nordic_base_uuid, &m_dfu.uuid_type);
+ VERIFY_SUCCESS(err_code);
+
+ // Add the Buttonless DFU Characteristic (with bonds/without bonds).
+ err_code = ble_dfu_buttonless_char_add(&m_dfu);
+ VERIFY_SUCCESS(err_code);
+
+ return NRF_SUCCESS;
+}
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/ble_dfu/ble_dfu.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/ble_dfu/ble_dfu.h
new file mode 100644
index 0000000..c348362
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/ble_dfu/ble_dfu.h
@@ -0,0 +1,251 @@
+/**
+ * Copyright (c) 2012 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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
+ *
+ * @defgroup ble_dfu Buttonless DFU Service
+ * @{
+ * @ingroup ble_sdk_srv
+ * @brief Buttonless DFU Service module.
+ *
+ * @details This module implements a proprietary Buttonless Secure DFU Service. The service can
+ * be configured to support bonds or not. The bond support configuration must correspond to the
+ * requirement of Secure DFU bootloader.
+ *
+ * @note Attention!
+ * To maintain compliance with Nordic Semiconductor ASA Bluetooth profile
+ * qualification listings, this section of source code must not be modified.
+ */
+
+#ifndef BLE_DFU_H__
+#define BLE_DFU_H__
+
+#include <stdint.h>
+#include "ble_srv_common.h"
+#include "nrf_sdh_ble.h"
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+/**@brief SoC observer priority.
+ * @details Priority of this module's SoC event handler.
+ */
+#define BLE_DFU_SOC_OBSERVER_PRIO 1
+
+#define BLE_DFU_BUTTONLESS_CHAR_UUID (0x0003) /**< Value combined with vendor-specific base to create Unbonded Buttonless characteristic UUID. */
+#define BLE_DFU_BUTTONLESS_BONDED_CHAR_UUID (0x0004) /**< Value combined with vendor-specific base to create Bonded Buttonless characteristic UUID. */
+
+
+/**@brief Nordic vendor-specific base UUID.
+ */
+#define BLE_NORDIC_VENDOR_BASE_UUID \
+{{ \
+ 0x50, 0xEA, 0xDA, 0x30, 0x88, 0x83, 0xB8, 0x9F, \
+ 0x60, 0x4F, 0x15, 0xF3, 0x00, 0x00, 0xC9, 0x8E \
+}}
+
+
+/**@brief Nordic Buttonless DFU Service event type .
+ */
+typedef enum
+{
+ BLE_DFU_EVT_BOOTLOADER_ENTER_PREPARE, /**< Event indicating that the device is preparing to enter bootloader.*/
+ BLE_DFU_EVT_BOOTLOADER_ENTER, /**< Event indicating that the bootloader will be entered after return of this event.*/
+ BLE_DFU_EVT_BOOTLOADER_ENTER_FAILED, /**< Failure to enter bootloader mode.*/
+ BLE_DFU_EVT_RESPONSE_SEND_ERROR, /**< Failure to send response.*/
+} ble_dfu_buttonless_evt_type_t;
+
+
+/**@brief Nordic Buttonless DFU Service event handler type.
+ */
+typedef void (*ble_dfu_buttonless_evt_handler_t) (ble_dfu_buttonless_evt_type_t p_evt);
+/**@brief Enumeration of Bootloader DFU response codes.
+ */
+typedef enum
+{
+ DFU_RSP_INVALID = 0x00, /**< Invalid op code. */
+ DFU_RSP_SUCCESS = 0x01, /**< Success. */
+ DFU_RSP_OP_CODE_NOT_SUPPORTED = 0x02, /**< Op code not supported. */
+ DFU_RSP_OPERATION_FAILED = 0x04, /**< Operation failed. */
+ DFU_RSP_ADV_NAME_INVALID = 0x05, /**< Requested advertisement name is too short or too long. */
+ DFU_RSP_BUSY = 0x06, /**< Ongoing async operation. */
+ DFU_RSP_NOT_BONDED = 0x07, /**< Buttonless unavailable due to device not bonded. */
+ DFU_RSP_CCCD_CONFIG_IMPROPER = BLE_GATT_STATUS_ATTERR_CPS_CCCD_CONFIG_ERROR /**< CCCD is improperly configured. */
+} ble_dfu_buttonless_rsp_code_t;
+
+
+/**@brief Enumeration of Bootloader DFU Operation codes.
+ */
+typedef enum
+{
+ DFU_OP_RESERVED = 0x00, /**< Reserved for future use. */
+ DFU_OP_ENTER_BOOTLOADER = 0x01, /**< Enter bootloader. */
+ DFU_OP_SET_ADV_NAME = 0x02, /**< Set advertisement name to use in DFU mode. */
+ DFU_OP_RESPONSE_CODE = 0x20 /**< Response code. */
+} ble_dfu_buttonless_op_code_t;
+
+
+/**@brief Type holding memory used by Secure DFU Buttonless Service.
+ */
+typedef struct
+{
+ uint8_t uuid_type; /**< UUID type for DFU UUID. */
+ uint16_t service_handle; /**< Service Handle of DFU (as provided by the SoftDevice). */
+ uint16_t conn_handle; /**< Connection handle for the current peer. */
+ ble_gatts_char_handles_t control_point_char; /**< Handles related to the DFU Control Point characteristic. */
+ uint32_t peers_count; /**< Counter to see how many persistently stored peers must be updated for Service Changed indication. This value will be counted down when comparing write requests. */
+ ble_dfu_buttonless_evt_handler_t evt_handler; /**< Event handler that is called upon Buttonless DFU events. See @ref ble_dfu_buttonless_evt_type_t. */
+ bool is_ctrlpt_indication_enabled; /**< Flag indicating that indication is enabled for the control point. */
+ bool is_waiting_for_reset; /**< Flag indicating that the device will enter bootloader. */
+ bool is_waiting_for_svci; /**< Flag indicating that the device is waiting for async SVCI operation */
+} ble_dfu_buttonless_t;
+
+
+/**@brief Type used to initialize the Secure DFU Buttonless Service.
+ */
+typedef struct
+{
+ ble_dfu_buttonless_evt_handler_t evt_handler; /**< Bootloader event handler. */
+} ble_dfu_buttonless_init_t;
+
+
+/**@brief Function for initializing the Device Firmware Update module.
+ *
+ * @param[in] p_dfu_init Structure containing the values of characteristics needed by the
+ * service.
+ * @retval NRF_SUCCESS on successful initialization of the service.
+ */
+uint32_t ble_dfu_buttonless_init(const ble_dfu_buttonless_init_t * p_dfu_init);
+
+
+/**@brief Function for initializing the async SVCI interface.
+ *
+ * @warning Ensure that no interrupts are triggered when calling this functions as
+ * interrupts and exceptions are forwarded to the bootloader for the period
+ * of the call and may be lost.
+ *
+ * @details This configures the async interface for calling to the
+ * bootloader through SVCI interface.
+ *
+ * @retval NRF_SUCCESS on success, otherwise an error code.
+ */
+uint32_t ble_dfu_buttonless_async_svci_init(void);
+
+
+/**@brief Function to initialize the backend Secure DFU Buttonless service which is either
+ * supports bonds or not.
+ *
+ * @note Do not call this function directly. It is called internally by @ref ble_dfu_buttonless_init.
+ *
+ * @param[in] p_dfu Nordic DFU Service structure.
+ *
+ * @return NRF_SUCCESS On sucessfully initializing, otherwise an error code.
+ */
+uint32_t ble_dfu_buttonless_backend_init(ble_dfu_buttonless_t * p_dfu);
+
+
+
+/**@brief Function for adding the buttonless characteristic.
+ *
+ * @note This will be implemented differently on bonded/unbonded Buttonless DFU service.
+ *
+ * @param[in] p_dfu Nordic DFU Service structure.
+ *
+ * @return NRF_SUCCESS on success, otherwise an error code.
+ */
+uint32_t ble_dfu_buttonless_char_add(ble_dfu_buttonless_t * p_dfu);
+
+
+/**@brief Function for sending a response back to the client.
+ *
+ * @param[in] op_code Operation code to send the response for.
+ * @param[in] rsp_code Response code for the operation.
+ *
+ * @retval NRF_SUCCESS on success, otherwise an error code.
+ */
+uint32_t ble_dfu_buttonless_resp_send(ble_dfu_buttonless_op_code_t op_code, ble_dfu_buttonless_rsp_code_t rsp_code);
+
+
+/**@brief Function for handling the application's BLE stack events.
+ *
+ * @details Handles all events from the BLE stack of interest to the DFU buttonless service.
+ *
+ * @param[in] p_ble_evt Event received from the BLE stack.
+ * @param[in] p_context BLE context structure.
+ */
+void ble_dfu_buttonless_on_ble_evt(ble_evt_t const * p_ble_evt, void * p_context);
+
+
+/**@brief Function for handling control point write requests.
+ *
+ * @details Handles write requests to the control point in
+ * DFU with bonds or without bonds.
+ *
+ * @param[in] p_evt_write GATTS write event.
+ */
+void ble_dfu_buttonless_on_ctrl_pt_write(ble_gatts_evt_write_t const * p_evt_write);
+
+
+/**@brief Function for preparing to enter the bootloader.
+ *
+ * @warning This function is called directly. (It is called internally).
+ *
+ * @retval Any error code from calling @ref sd_ble_gap_disconnect.
+ */
+uint32_t ble_dfu_buttonless_bootloader_start_prepare(void);
+
+
+/**@brief Function for finalizing entering the bootloader.
+ *
+ * @warning This function is not to be called. (It is called internally).
+ *
+ * @retval NRF_SUCCESS Finalize was started correctly.
+ */
+uint32_t ble_dfu_buttonless_bootloader_start_finalize(void);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // BLE_DIS_H__
+
+/** @} */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/ble_dfu/ble_dfu_bonded.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/ble_dfu/ble_dfu_bonded.c
new file mode 100644
index 0000000..3189896
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/ble_dfu/ble_dfu_bonded.c
@@ -0,0 +1,407 @@
+/**
+ * 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+
+#include <stdint.h>
+#include <stdbool.h>
+#include <stddef.h>
+#include "nrf_dfu_ble_svci_bond_sharing.h"
+#include "nordic_common.h"
+#include "nrf_error.h"
+#include "ble_dfu.h"
+#include "nrf_log.h"
+#include "peer_manager.h"
+#include "gatts_cache_manager.h"
+#include "peer_id.h"
+#include "nrf_sdh_soc.h"
+#include "nrf_strerror.h"
+
+#if (NRF_DFU_BLE_BUTTONLESS_SUPPORTS_BONDS)
+
+
+void ble_dfu_buttonless_on_sys_evt(uint32_t, void * );
+uint32_t nrf_dfu_svci_vector_table_set(void);
+uint32_t nrf_dfu_svci_vector_table_unset(void);
+
+/**@brief Define function for async interface to set peer data. */
+NRF_SVCI_ASYNC_FUNC_DEFINE(NRF_DFU_SVCI_SET_PEER_DATA, nrf_dfu_set_peer_data, nrf_dfu_peer_data_t);
+
+// Register SoC observer for the Buttonless Secure DFU service
+NRF_SDH_SOC_OBSERVER(m_dfu_buttonless_soc_obs, BLE_DFU_SOC_OBSERVER_PRIO, ble_dfu_buttonless_on_sys_evt, NULL);
+
+ble_dfu_buttonless_t * mp_dfu;
+static nrf_dfu_peer_data_t m_peer_data;
+
+
+/**@brief Function for handling Peer Manager events.
+ *
+ * @param[in] p_evt Peer Manager event.
+ */
+static void pm_evt_handler(pm_evt_t const * p_evt)
+{
+ uint32_t ret;
+
+ if (mp_dfu == NULL)
+ {
+ return;
+ }
+
+ // Only handle this when we are waiting to reset into DFU mode
+ if (!mp_dfu->is_waiting_for_reset)
+ {
+ return;
+ }
+
+ switch(p_evt->evt_id)
+ {
+ case PM_EVT_PEER_DATA_UPDATE_SUCCEEDED:
+ if (p_evt->params.peer_data_update_succeeded.data_id == PM_PEER_DATA_ID_SERVICE_CHANGED_PENDING)
+ {
+ mp_dfu->peers_count--;
+ NRF_LOG_DEBUG("Updating Service Changed indication for peers, %d left", mp_dfu->peers_count);
+ if (mp_dfu->peers_count == 0)
+ {
+ NRF_LOG_DEBUG("Finished updating Service Changed indication for peers");
+ // We have updated Service Changed Indication for all devices.
+ ret = ble_dfu_buttonless_bootloader_start_finalize();
+ if (ret != NRF_SUCCESS)
+ {
+ mp_dfu->evt_handler(BLE_DFU_EVT_BOOTLOADER_ENTER_FAILED);
+ }
+ }
+ }
+ break;
+
+ case PM_EVT_PEER_DATA_UPDATE_FAILED:
+ // Failure to update data. Service Changed cannot be sent but DFU mode is still possible
+ ret = ble_dfu_buttonless_bootloader_start_finalize();
+ if (ret != NRF_SUCCESS)
+ {
+ mp_dfu->evt_handler(BLE_DFU_EVT_BOOTLOADER_ENTER_FAILED);
+ }
+ break;
+
+ default:
+ break;
+ }
+}
+
+
+static uint32_t retrieve_peer_data(void)
+{
+ ret_code_t ret;
+ pm_peer_data_bonding_t bonding_data = {0};
+ pm_peer_id_t peer_id;
+
+ ret = pm_peer_id_get(mp_dfu->conn_handle, &peer_id);
+ VERIFY_SUCCESS(ret);
+
+ if (peer_id == PM_PEER_ID_INVALID)
+ {
+ return NRF_ERROR_FORBIDDEN;
+ }
+
+ ret = pm_peer_data_bonding_load(peer_id, &bonding_data);
+ VERIFY_SUCCESS(ret);
+
+ memcpy(&m_peer_data.ble_id, &bonding_data.peer_ble_id, sizeof(ble_gap_id_key_t));
+ memcpy(&m_peer_data.enc_key, &bonding_data.own_ltk, sizeof(ble_gap_enc_key_t));
+
+ uint16_t len = SYSTEM_SERVICE_ATT_SIZE;
+ ret = sd_ble_gatts_sys_attr_get(mp_dfu->conn_handle,
+ m_peer_data.sys_serv_attr,
+ &len,
+ BLE_GATTS_SYS_ATTR_FLAG_SYS_SRVCS);
+
+ NRF_LOG_DEBUG("system attribute table len: %d", len);
+
+ return ret;
+}
+
+
+/**@brief Function for entering the bootloader.
+ *
+ * @details This starts forwarding peer data to the Secure DFU bootloader.
+ */
+static uint32_t enter_bootloader(void)
+{
+ uint32_t ret;
+
+ NRF_LOG_INFO("Writing peer data to the bootloader...");
+
+ if (mp_dfu->is_waiting_for_svci)
+ {
+ return ble_dfu_buttonless_resp_send(DFU_OP_ENTER_BOOTLOADER, DFU_RSP_BUSY);
+ }
+
+ // If retrieve_peer_data returns NRF_ERROR_FORBIDDEN, then the device was not bonded.
+ ret = retrieve_peer_data();
+ VERIFY_SUCCESS(ret);
+
+ ret = nrf_dfu_set_peer_data(&m_peer_data);
+ if (ret == NRF_SUCCESS)
+ {
+ // The request was accepted. Waiting for sys events to progress.
+ mp_dfu->is_waiting_for_svci = true;
+ }
+ else if (ret == NRF_ERROR_FORBIDDEN)
+ {
+ NRF_LOG_ERROR("The bootloader has write protected its settings page. This prohibits setting the peer data. "\
+ "The bootloader must be compiled with NRF_BL_SETTINGS_PAGE_PROTECT=0 to allow setting the peer data.");
+ }
+
+ return ret;
+}
+
+
+uint32_t ble_dfu_buttonless_backend_init(ble_dfu_buttonless_t * p_dfu)
+{
+ VERIFY_PARAM_NOT_NULL(p_dfu);
+
+ // Set the memory used by the backend.
+ mp_dfu = p_dfu;
+
+ // Initialize the Peer manager handler.
+ return pm_register(&pm_evt_handler);
+}
+
+
+uint32_t ble_dfu_buttonless_async_svci_init(void)
+{
+ uint32_t ret;
+
+ // Set the vector table base address to the bootloader.
+ ret = nrf_dfu_svci_vector_table_set();
+ NRF_LOG_DEBUG("nrf_dfu_svci_vector_table_set() -> %s",
+ (ret == NRF_SUCCESS) ? "success" : nrf_strerror_get(ret));
+ VERIFY_SUCCESS(ret);
+
+ // Initialize the asynchronous SuperVisor interface to set peer data in Secure DFU bootloader.
+ ret = nrf_dfu_set_peer_data_init();
+ NRF_LOG_DEBUG("nrf_dfu_set_peer_data_init() -> %s",
+ (ret == NRF_SUCCESS) ? "success" : nrf_strerror_get(ret));
+ VERIFY_SUCCESS(ret);
+
+ // Set the vector table base address back to main application.
+ ret = nrf_dfu_svci_vector_table_unset();
+ NRF_LOG_DEBUG("nrf_dfu_svci_vector_table_unset() -> %s",
+ (ret == NRF_SUCCESS) ? "success" : nrf_strerror_get(ret));
+
+ return ret;
+}
+
+
+void ble_dfu_buttonless_on_sys_evt(uint32_t sys_evt, void * p_context)
+{
+ uint32_t ret;
+
+ if (!nrf_dfu_set_peer_data_is_initialized())
+ {
+ return;
+ }
+
+ ret = nrf_dfu_set_peer_data_on_sys_evt(sys_evt);
+ if (ret == NRF_ERROR_INVALID_STATE)
+ {
+ // The system event is not from an operation started by buttonless DFU.
+ // No action is taken, and nothing is reported.
+ }
+ else if (ret == NRF_SUCCESS)
+ {
+ // Peer data was successfully forwarded to the Secure DFU bootloader.
+ // Set the flag indicating that we are waiting for indication response
+ // to activate the reset.
+ mp_dfu->is_waiting_for_reset = true;
+ mp_dfu->is_waiting_for_svci = false;
+
+ // Report back the positive response
+ ret = ble_dfu_buttonless_resp_send(DFU_OP_ENTER_BOOTLOADER, DFU_RSP_SUCCESS);
+ if (ret != NRF_SUCCESS)
+ {
+ mp_dfu->evt_handler(BLE_DFU_EVT_RESPONSE_SEND_ERROR);
+ mp_dfu->is_waiting_for_reset = false;
+ }
+ }
+ else
+ {
+ // Failed to set peer data. Report this.
+ mp_dfu->is_waiting_for_reset = false;
+ mp_dfu->is_waiting_for_svci = false;
+ ret = ble_dfu_buttonless_resp_send(DFU_OP_ENTER_BOOTLOADER, DFU_RSP_BUSY);
+
+ // Report the failure to send the response to the client
+ if (ret != NRF_SUCCESS)
+ {
+ mp_dfu->evt_handler(BLE_DFU_EVT_RESPONSE_SEND_ERROR);
+ }
+
+ // Report the failure to enter DFU mode
+ mp_dfu->evt_handler(BLE_DFU_EVT_BOOTLOADER_ENTER_FAILED);
+ }
+}
+
+
+uint32_t ble_dfu_buttonless_char_add(ble_dfu_buttonless_t * p_dfu)
+{
+ ble_gatts_char_md_t char_md = {{0}};
+ ble_gatts_attr_md_t cccd_md = {{0}};
+ ble_gatts_attr_t attr_char_value = {0};
+ ble_gatts_attr_md_t attr_md = {{0}};
+ ble_uuid_t char_uuid;
+
+ BLE_GAP_CONN_SEC_MODE_SET_OPEN(&cccd_md.read_perm);
+ BLE_GAP_CONN_SEC_MODE_SET_ENC_NO_MITM(&cccd_md.write_perm);
+
+ cccd_md.vloc = BLE_GATTS_VLOC_STACK;
+
+ char_md.char_props.indicate = 1;
+ char_md.char_props.write = 1;
+ char_md.p_char_user_desc = NULL;
+ char_md.p_char_pf = NULL;
+ char_md.p_user_desc_md = NULL;
+ char_md.p_cccd_md = &cccd_md;
+ char_md.p_sccd_md = NULL;
+
+ char_uuid.type = p_dfu->uuid_type;
+ char_uuid.uuid = BLE_DFU_BUTTONLESS_BONDED_CHAR_UUID;
+
+ BLE_GAP_CONN_SEC_MODE_SET_OPEN(&attr_md.read_perm);
+ BLE_GAP_CONN_SEC_MODE_SET_ENC_NO_MITM(&attr_md.write_perm);
+
+ attr_md.vloc = BLE_GATTS_VLOC_STACK;
+ attr_md.rd_auth = 0;
+ attr_md.wr_auth = 1;
+ attr_md.vlen = 1;
+
+ attr_char_value.p_uuid = &char_uuid;
+ attr_char_value.p_attr_md = &attr_md;
+ attr_char_value.init_len = 0;
+ attr_char_value.init_offs = 0;
+ attr_char_value.max_len = BLE_GATT_ATT_MTU_DEFAULT;
+ attr_char_value.p_value = 0;
+
+ return sd_ble_gatts_characteristic_add(p_dfu->service_handle,
+ &char_md,
+ &attr_char_value,
+ &p_dfu->control_point_char);
+}
+
+
+void ble_dfu_buttonless_on_ctrl_pt_write(ble_gatts_evt_write_t const * p_evt_write)
+{
+ uint32_t ret;
+ ble_dfu_buttonless_rsp_code_t rsp_code = DFU_RSP_OPERATION_FAILED;
+
+ // Start executing the control point write action
+ switch (p_evt_write->data[0])
+ {
+ case DFU_OP_ENTER_BOOTLOADER:
+ ret = enter_bootloader();
+ if (ret == NRF_SUCCESS)
+ {
+ rsp_code = DFU_RSP_SUCCESS;
+ }
+ else if (ret == NRF_ERROR_BUSY)
+ {
+ rsp_code = DFU_RSP_BUSY;
+ }
+ else if (ret == NRF_ERROR_FORBIDDEN)
+ {
+ rsp_code = DFU_RSP_NOT_BONDED;
+ }
+ break;
+
+ default:
+ rsp_code = DFU_RSP_OP_CODE_NOT_SUPPORTED;
+ break;
+ }
+
+ // Report back in case of error
+ if (rsp_code != DFU_RSP_SUCCESS)
+ {
+ ret = ble_dfu_buttonless_resp_send((ble_dfu_buttonless_op_code_t)p_evt_write->data[0],
+ rsp_code);
+
+ if (ret != NRF_SUCCESS)
+ {
+ mp_dfu->evt_handler(BLE_DFU_EVT_RESPONSE_SEND_ERROR);
+ }
+
+ // Report the error to the main application
+ mp_dfu->evt_handler(BLE_DFU_EVT_BOOTLOADER_ENTER_FAILED);
+ }
+}
+
+
+uint32_t ble_dfu_buttonless_bootloader_start_prepare(void)
+{
+ uint32_t ret;
+
+ NRF_LOG_DEBUG("In ble_dfu_buttonless_bootloader_start_prepare");
+
+ // Indicate to main app that DFU mode is starting.
+ // This event can be used to let the device take down any connection to
+ // bonded devices.
+ mp_dfu->evt_handler(BLE_DFU_EVT_BOOTLOADER_ENTER_PREPARE);
+
+ // Disconnect from the device to enable Service Changed on next connection.
+ // (Stored in Peer Manager persistent storage for next bootup).
+ ret = sd_ble_gap_disconnect(mp_dfu->conn_handle, BLE_HCI_REMOTE_USER_TERMINATED_CONNECTION);
+ if (ret != NRF_SUCCESS)
+ {
+ NRF_LOG_ERROR("Failed to disconnect GAP connection");
+ return ret;
+ }
+ else
+ {
+ NRF_LOG_DEBUG("Disconnected peer");
+ }
+
+ // Store the number of peers for which Peer Manager is expected to successfully write events.
+ mp_dfu->peers_count = peer_id_n_ids();
+
+ // Set local database changed to get Service Changed indication for all bonded peers
+ // on next bootup (either because of a successful or aborted DFU).
+ gscm_local_database_has_changed();
+
+ return ret;
+}
+
+#endif // NRF_DFU_BLE_BUTTONLESS_SUPPORTS_BONDS
+
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/ble_dfu/ble_dfu_unbonded.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/ble_dfu/ble_dfu_unbonded.c
new file mode 100644
index 0000000..e6301bc
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/ble_dfu/ble_dfu_unbonded.c
@@ -0,0 +1,325 @@
+/**
+ * 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+
+#include <stdint.h>
+#include <stdbool.h>
+#include <stddef.h>
+#include "nrf_dfu_ble_svci_bond_sharing.h"
+#include "nordic_common.h"
+#include "nrf_error.h"
+#include "ble_dfu.h"
+#include "nrf_log.h"
+#include "nrf_sdh_soc.h"
+
+#if (!NRF_DFU_BLE_BUTTONLESS_SUPPORTS_BONDS)
+
+#define NRF_DFU_ADV_NAME_MAX_LENGTH (20)
+
+
+void ble_dfu_buttonless_on_sys_evt(uint32_t, void * );
+uint32_t nrf_dfu_svci_vector_table_set(void);
+uint32_t nrf_dfu_svci_vector_table_unset(void);
+
+/**@brief Define functions for async interface to set new advertisement name for DFU mode. */
+NRF_SVCI_ASYNC_FUNC_DEFINE(NRF_DFU_SVCI_SET_ADV_NAME, nrf_dfu_set_adv_name, nrf_dfu_adv_name_t);
+
+// Register SoC observer for the Buttonless Secure DFU service
+NRF_SDH_SOC_OBSERVER(m_dfu_buttonless_soc_obs, BLE_DFU_SOC_OBSERVER_PRIO, ble_dfu_buttonless_on_sys_evt, NULL);
+
+ble_dfu_buttonless_t * mp_dfu = NULL;
+static nrf_dfu_adv_name_t m_adv_name;
+
+
+/**@brief Function for setting an advertisement name.
+ *
+ * @param[in] adv_name The new advertisement name.
+ *
+ * @retval NRF_SUCCESS Advertisement name was successfully set.
+ * @retval DFU_RSP_BUSY Advertisement name was not set because of an ongoing operation.
+ * @retval Any other errors from the SVCI interface call.
+ */
+static uint32_t set_adv_name(nrf_dfu_adv_name_t * p_adv_name)
+{
+ uint32_t err_code;
+
+ if (mp_dfu->is_waiting_for_svci)
+ {
+ return DFU_RSP_BUSY;
+ }
+
+ err_code = nrf_dfu_set_adv_name(p_adv_name);
+ if (err_code == NRF_SUCCESS)
+ {
+ // The request was accepted.
+ mp_dfu->is_waiting_for_svci = true;
+ }
+ else if (err_code == NRF_ERROR_FORBIDDEN)
+ {
+ NRF_LOG_ERROR("The bootloader has write protected its settings page. This prohibits setting the advertising name. "\
+ "The bootloader must be compiled with NRF_BL_SETTINGS_PAGE_PROTECT=0 to allow setting the advertising name.");
+ }
+
+ return err_code;
+}
+
+
+/**@brief Function for entering the bootloader.
+ */
+static uint32_t enter_bootloader()
+{
+ uint32_t err_code;
+
+ if (mp_dfu->is_waiting_for_svci)
+ {
+ // We have an ongoing async operation. Entering bootloader mode is not possible at this time.
+ err_code = ble_dfu_buttonless_resp_send(DFU_OP_ENTER_BOOTLOADER, DFU_RSP_BUSY);
+ if (err_code != NRF_SUCCESS)
+ {
+ mp_dfu->evt_handler(BLE_DFU_EVT_RESPONSE_SEND_ERROR);
+ }
+ return NRF_SUCCESS;
+ }
+
+ // Set the flag indicating that we expect DFU mode.
+ // This will be handled on acknowledgement of the characteristic indication.
+ mp_dfu->is_waiting_for_reset = true;
+
+ err_code = ble_dfu_buttonless_resp_send(DFU_OP_ENTER_BOOTLOADER, DFU_RSP_SUCCESS);
+ if (err_code != NRF_SUCCESS)
+ {
+ mp_dfu->is_waiting_for_reset = false;
+ }
+
+ return err_code;
+}
+
+
+uint32_t ble_dfu_buttonless_backend_init(ble_dfu_buttonless_t * p_dfu)
+{
+ VERIFY_PARAM_NOT_NULL(p_dfu);
+
+ mp_dfu = p_dfu;
+
+ return NRF_SUCCESS;
+}
+
+
+uint32_t ble_dfu_buttonless_async_svci_init(void)
+{
+ uint32_t ret_val;
+
+ ret_val = nrf_dfu_svci_vector_table_set();
+ VERIFY_SUCCESS(ret_val);
+
+ ret_val = nrf_dfu_set_adv_name_init();
+ VERIFY_SUCCESS(ret_val);
+
+ ret_val = nrf_dfu_svci_vector_table_unset();
+
+ return ret_val;
+}
+
+
+void ble_dfu_buttonless_on_sys_evt(uint32_t sys_evt, void * p_context)
+{
+ uint32_t err_code;
+
+ if (!nrf_dfu_set_adv_name_is_initialized())
+ {
+ return;
+ }
+
+ err_code = nrf_dfu_set_adv_name_on_sys_evt(sys_evt);
+ if (err_code == NRF_ERROR_INVALID_STATE)
+ {
+ // The system event is not from an operation started by buttonless DFU.
+ // No action is taken, and nothing is reported.
+ }
+ else if (err_code == NRF_SUCCESS)
+ {
+ // The async operation is finished.
+ // Set the flag indicating that we are waiting for indication response
+ // to activate the reset.
+ mp_dfu->is_waiting_for_svci = false;
+
+ // Report back the positive response
+ err_code = ble_dfu_buttonless_resp_send(DFU_OP_SET_ADV_NAME, DFU_RSP_SUCCESS);
+ if (err_code != NRF_SUCCESS)
+ {
+ mp_dfu->evt_handler(BLE_DFU_EVT_RESPONSE_SEND_ERROR);
+ }
+ }
+ else
+ {
+ // Invalid error code reported back.
+ mp_dfu->is_waiting_for_svci = false;
+
+ err_code = ble_dfu_buttonless_resp_send(DFU_OP_SET_ADV_NAME, DFU_RSP_BUSY);
+ if (err_code != NRF_SUCCESS)
+ {
+ mp_dfu->evt_handler(BLE_DFU_EVT_RESPONSE_SEND_ERROR);
+ }
+
+ // Report the failure to enter DFU mode
+ mp_dfu->evt_handler(BLE_DFU_EVT_BOOTLOADER_ENTER_FAILED);
+ }
+}
+
+
+uint32_t ble_dfu_buttonless_char_add(ble_dfu_buttonless_t * p_dfu)
+{
+ ble_gatts_char_md_t char_md = {{0}};
+ ble_gatts_attr_md_t cccd_md = {{0}};
+ ble_gatts_attr_t attr_char_value = {0};
+ ble_gatts_attr_md_t attr_md = {{0}};
+ ble_uuid_t char_uuid;
+
+
+ BLE_GAP_CONN_SEC_MODE_SET_OPEN(&cccd_md.read_perm);
+ BLE_GAP_CONN_SEC_MODE_SET_OPEN(&cccd_md.write_perm);
+
+ cccd_md.vloc = BLE_GATTS_VLOC_STACK;
+
+ char_md.char_props.indicate = 1;
+ char_md.char_props.write = 1;
+ char_md.p_char_user_desc = NULL;
+ char_md.p_char_pf = NULL;
+ char_md.p_user_desc_md = NULL;
+ char_md.p_cccd_md = &cccd_md;
+ char_md.p_sccd_md = NULL;
+
+ char_uuid.type = p_dfu->uuid_type;
+ char_uuid.uuid = BLE_DFU_BUTTONLESS_CHAR_UUID;
+
+ BLE_GAP_CONN_SEC_MODE_SET_OPEN(&attr_md.read_perm);
+ BLE_GAP_CONN_SEC_MODE_SET_OPEN(&attr_md.write_perm);
+
+ attr_md.vloc = BLE_GATTS_VLOC_STACK;
+ attr_md.rd_auth = 0;
+ attr_md.wr_auth = 1;
+ attr_md.vlen = 1;
+
+ attr_char_value.p_uuid = &char_uuid;
+ attr_char_value.p_attr_md = &attr_md;
+ attr_char_value.init_len = 0;
+ attr_char_value.init_offs = 0;
+ attr_char_value.max_len = BLE_GATT_ATT_MTU_DEFAULT;
+ attr_char_value.p_value = 0;
+
+ return sd_ble_gatts_characteristic_add(p_dfu->service_handle,
+ &char_md,
+ &attr_char_value,
+ &p_dfu->control_point_char);
+}
+
+
+void ble_dfu_buttonless_on_ctrl_pt_write(ble_gatts_evt_write_t const * p_evt_write)
+{
+ uint32_t err_code;
+ ble_dfu_buttonless_rsp_code_t rsp_code = DFU_RSP_OPERATION_FAILED;
+
+ // Start executing the control point write operation
+ /*lint -e415 -e416 -save "Out of bounds access"*/
+ switch (p_evt_write->data[0])
+ {
+ case DFU_OP_ENTER_BOOTLOADER:
+ err_code = enter_bootloader();
+ if (err_code == NRF_SUCCESS)
+ {
+ rsp_code = DFU_RSP_SUCCESS;
+ }
+ else if (err_code == NRF_ERROR_BUSY)
+ {
+ rsp_code = DFU_RSP_BUSY;
+ }
+ break;
+
+ case DFU_OP_SET_ADV_NAME:
+ if( (p_evt_write->data[1] > NRF_DFU_ADV_NAME_MAX_LENGTH)
+ || (p_evt_write->data[1] == 0))
+ {
+ // New advertisement name too short or too long.
+ rsp_code = DFU_RSP_ADV_NAME_INVALID;
+ }
+ else
+ {
+ memcpy(m_adv_name.name, &p_evt_write->data[2], p_evt_write->data[1]);
+ m_adv_name.len = p_evt_write->data[1];
+ err_code = set_adv_name(&m_adv_name);
+ if (err_code == NRF_SUCCESS)
+ {
+ rsp_code = DFU_RSP_SUCCESS;
+ }
+ }
+ break;
+
+ default:
+ rsp_code = DFU_RSP_OP_CODE_NOT_SUPPORTED;
+ break;
+ }
+ /*lint -restore*/
+
+
+ // Report back in case of error
+ if (rsp_code != DFU_RSP_SUCCESS)
+ {
+ err_code = ble_dfu_buttonless_resp_send((ble_dfu_buttonless_op_code_t)p_evt_write->data[0], rsp_code);
+ if (err_code != NRF_SUCCESS)
+ {
+ mp_dfu->evt_handler(BLE_DFU_EVT_RESPONSE_SEND_ERROR);
+
+ }
+ // Report the error to the main application
+ mp_dfu->evt_handler(BLE_DFU_EVT_BOOTLOADER_ENTER_FAILED);
+ }
+}
+
+uint32_t ble_dfu_buttonless_bootloader_start_prepare(void)
+{
+ uint32_t err_code;
+
+ // Indicate to main app that DFU mode is starting.
+ mp_dfu->evt_handler(BLE_DFU_EVT_BOOTLOADER_ENTER_PREPARE);
+
+ err_code = ble_dfu_buttonless_bootloader_start_finalize();
+ return err_code;
+}
+
+#endif // NRF_DFU_BOTTONLESS_SUPPORT_BOND
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/ble_dis/ble_dis.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/ble_dis/ble_dis.c
new file mode 100644
index 0000000..0b8da92
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/ble_dis/ble_dis.c
@@ -0,0 +1,304 @@
+/**
+ * Copyright (c) 2012 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+/* Attention!
+ * To maintain compliance with Nordic Semiconductor ASA's Bluetooth profile
+ * qualification listings, this section of source code must not be modified.
+ */
+#include "sdk_common.h"
+#if NRF_MODULE_ENABLED(BLE_DIS)
+#include "ble_dis.h"
+
+#include <stdlib.h>
+#include <string.h>
+#include "app_error.h"
+#include "ble_gatts.h"
+#include "ble_srv_common.h"
+
+
+#define BLE_DIS_SYS_ID_LEN 8 /**< Length of System ID Characteristic Value. */
+#define BLE_DIS_PNP_ID_LEN 7 /**< Length of Pnp ID Characteristic Value. */
+
+static uint16_t service_handle;
+static ble_gatts_char_handles_t manufact_name_handles;
+static ble_gatts_char_handles_t model_num_handles;
+static ble_gatts_char_handles_t serial_num_handles;
+static ble_gatts_char_handles_t hw_rev_handles;
+static ble_gatts_char_handles_t fw_rev_handles;
+static ble_gatts_char_handles_t sw_rev_handles;
+static ble_gatts_char_handles_t sys_id_handles;
+static ble_gatts_char_handles_t reg_cert_data_list_handles;
+static ble_gatts_char_handles_t pnp_id_handles;
+
+
+/**@brief Function for encoding a System ID.
+ *
+ * @param[out] p_encoded_buffer Buffer where the encoded data will be written.
+ * @param[in] p_sys_id System ID to be encoded.
+ */
+static void sys_id_encode(uint8_t * p_encoded_buffer, ble_dis_sys_id_t const * p_sys_id)
+{
+ APP_ERROR_CHECK_BOOL(p_sys_id != NULL);
+ APP_ERROR_CHECK_BOOL(p_encoded_buffer != NULL);
+
+ p_encoded_buffer[0] = (p_sys_id->manufacturer_id & 0x00000000FF);
+ p_encoded_buffer[1] = (p_sys_id->manufacturer_id & 0x000000FF00) >> 8;
+ p_encoded_buffer[2] = (p_sys_id->manufacturer_id & 0x0000FF0000) >> 16;
+ p_encoded_buffer[3] = (p_sys_id->manufacturer_id & 0x00FF000000) >> 24;
+ p_encoded_buffer[4] = (p_sys_id->manufacturer_id & 0xFF00000000) >> 32;
+
+ p_encoded_buffer[5] = (p_sys_id->organizationally_unique_id & 0x0000FF);
+ p_encoded_buffer[6] = (p_sys_id->organizationally_unique_id & 0x00FF00) >> 8;
+ p_encoded_buffer[7] = (p_sys_id->organizationally_unique_id & 0xFF0000) >> 16;
+}
+
+
+/**@brief Function for encoding a PnP ID.
+ *
+ * @param[out] p_encoded_buffer Buffer where the encoded data will be written.
+ * @param[in] p_pnp_id PnP ID to be encoded.
+ */
+static void pnp_id_encode(uint8_t * p_encoded_buffer, ble_dis_pnp_id_t const * p_pnp_id)
+{
+ uint8_t len = 0;
+
+ APP_ERROR_CHECK_BOOL(p_pnp_id != NULL);
+ APP_ERROR_CHECK_BOOL(p_encoded_buffer != NULL);
+
+ p_encoded_buffer[len++] = p_pnp_id->vendor_id_source;
+
+ len += uint16_encode(p_pnp_id->vendor_id, &p_encoded_buffer[len]);
+ len += uint16_encode(p_pnp_id->product_id, &p_encoded_buffer[len]);
+ len += uint16_encode(p_pnp_id->product_version, &p_encoded_buffer[len]);
+
+ APP_ERROR_CHECK_BOOL(len == BLE_DIS_PNP_ID_LEN);
+}
+
+
+/**@brief Function for adding the Characteristic.
+ *
+ * @param[in] uuid UUID of characteristic to be added.
+ * @param[in] p_char_value Initial value of characteristic to be added.
+ * @param[in] char_len Length of initial value. This will also be the maximum value.
+ * @param[in] dis_attr_md Security settings of characteristic to be added.
+ * @param[out] p_handles Handles of new characteristic.
+ *
+ * @return NRF_SUCCESS on success, otherwise an error code.
+ */
+static uint32_t char_add(uint16_t uuid,
+ uint8_t * p_char_value,
+ uint16_t char_len,
+ ble_srv_security_mode_t const * dis_attr_md,
+ ble_gatts_char_handles_t * p_handles)
+{
+ ble_uuid_t ble_uuid;
+ ble_gatts_char_md_t char_md;
+ ble_gatts_attr_t attr_char_value;
+ ble_gatts_attr_md_t attr_md;
+
+ APP_ERROR_CHECK_BOOL(p_char_value != NULL);
+ APP_ERROR_CHECK_BOOL(char_len > 0);
+
+ // The ble_gatts_char_md_t structure uses bit fields. So we reset the memory to zero.
+ memset(&char_md, 0, sizeof(char_md));
+
+ char_md.char_props.read = 1;
+ char_md.p_char_user_desc = NULL;
+ char_md.p_char_pf = NULL;
+ char_md.p_user_desc_md = NULL;
+ char_md.p_cccd_md = NULL;
+ char_md.p_sccd_md = NULL;
+
+ BLE_UUID_BLE_ASSIGN(ble_uuid, uuid);
+
+ memset(&attr_md, 0, sizeof(attr_md));
+
+ attr_md.read_perm = dis_attr_md->read_perm;
+ attr_md.write_perm = dis_attr_md->write_perm;
+ attr_md.vloc = BLE_GATTS_VLOC_STACK;
+ attr_md.rd_auth = 0;
+ attr_md.wr_auth = 0;
+ attr_md.vlen = 0;
+
+ memset(&attr_char_value, 0, sizeof(attr_char_value));
+
+ attr_char_value.p_uuid = &ble_uuid;
+ attr_char_value.p_attr_md = &attr_md;
+ attr_char_value.init_len = char_len;
+ attr_char_value.init_offs = 0;
+ attr_char_value.max_len = char_len;
+ attr_char_value.p_value = p_char_value;
+
+ return sd_ble_gatts_characteristic_add(service_handle, &char_md, &attr_char_value, p_handles);
+}
+
+
+uint32_t ble_dis_init(ble_dis_init_t const * p_dis_init)
+{
+ uint32_t err_code;
+ ble_uuid_t ble_uuid;
+
+ // Add service
+ BLE_UUID_BLE_ASSIGN(ble_uuid, BLE_UUID_DEVICE_INFORMATION_SERVICE);
+
+ err_code = sd_ble_gatts_service_add(BLE_GATTS_SRVC_TYPE_PRIMARY, &ble_uuid, &service_handle);
+ if (err_code != NRF_SUCCESS)
+ {
+ return err_code;
+ }
+
+ // Add characteristics
+ if (p_dis_init->manufact_name_str.length > 0)
+ {
+ err_code = char_add(BLE_UUID_MANUFACTURER_NAME_STRING_CHAR,
+ p_dis_init->manufact_name_str.p_str,
+ p_dis_init->manufact_name_str.length,
+ &p_dis_init->dis_attr_md,
+ &manufact_name_handles);
+ if (err_code != NRF_SUCCESS)
+ {
+ return err_code;
+ }
+ }
+ if (p_dis_init->model_num_str.length > 0)
+ {
+ err_code = char_add(BLE_UUID_MODEL_NUMBER_STRING_CHAR,
+ p_dis_init->model_num_str.p_str,
+ p_dis_init->model_num_str.length,
+ &p_dis_init->dis_attr_md,
+ &model_num_handles);
+ if (err_code != NRF_SUCCESS)
+ {
+ return err_code;
+ }
+ }
+ if (p_dis_init->serial_num_str.length > 0)
+ {
+ err_code = char_add(BLE_UUID_SERIAL_NUMBER_STRING_CHAR,
+ p_dis_init->serial_num_str.p_str,
+ p_dis_init->serial_num_str.length,
+ &p_dis_init->dis_attr_md,
+ &serial_num_handles);
+ if (err_code != NRF_SUCCESS)
+ {
+ return err_code;
+ }
+ }
+ if (p_dis_init->hw_rev_str.length > 0)
+ {
+ err_code = char_add(BLE_UUID_HARDWARE_REVISION_STRING_CHAR,
+ p_dis_init->hw_rev_str.p_str,
+ p_dis_init->hw_rev_str.length,
+ &p_dis_init->dis_attr_md,
+ &hw_rev_handles);
+ if (err_code != NRF_SUCCESS)
+ {
+ return err_code;
+ }
+ }
+ if (p_dis_init->fw_rev_str.length > 0)
+ {
+ err_code = char_add(BLE_UUID_FIRMWARE_REVISION_STRING_CHAR,
+ p_dis_init->fw_rev_str.p_str,
+ p_dis_init->fw_rev_str.length,
+ &p_dis_init->dis_attr_md,
+ &fw_rev_handles);
+ if (err_code != NRF_SUCCESS)
+ {
+ return err_code;
+ }
+ }
+ if (p_dis_init->sw_rev_str.length > 0)
+ {
+ err_code = char_add(BLE_UUID_SOFTWARE_REVISION_STRING_CHAR,
+ p_dis_init->sw_rev_str.p_str,
+ p_dis_init->sw_rev_str.length,
+ &p_dis_init->dis_attr_md,
+ &sw_rev_handles);
+ if (err_code != NRF_SUCCESS)
+ {
+ return err_code;
+ }
+ }
+ if (p_dis_init->p_sys_id != NULL)
+ {
+ uint8_t encoded_sys_id[BLE_DIS_SYS_ID_LEN];
+
+ sys_id_encode(encoded_sys_id, p_dis_init->p_sys_id);
+ err_code = char_add(BLE_UUID_SYSTEM_ID_CHAR,
+ encoded_sys_id,
+ BLE_DIS_SYS_ID_LEN,
+ &p_dis_init->dis_attr_md,
+ &sys_id_handles);
+ if (err_code != NRF_SUCCESS)
+ {
+ return err_code;
+ }
+ }
+ if (p_dis_init->p_reg_cert_data_list != NULL)
+ {
+ err_code = char_add(BLE_UUID_IEEE_REGULATORY_CERTIFICATION_DATA_LIST_CHAR,
+ p_dis_init->p_reg_cert_data_list->p_list,
+ p_dis_init->p_reg_cert_data_list->list_len,
+ &p_dis_init->dis_attr_md,
+ &reg_cert_data_list_handles);
+ if (err_code != NRF_SUCCESS)
+ {
+ return err_code;
+ }
+ }
+ if (p_dis_init->p_pnp_id != NULL)
+ {
+ uint8_t encoded_pnp_id[BLE_DIS_PNP_ID_LEN];
+
+ pnp_id_encode(encoded_pnp_id, p_dis_init->p_pnp_id);
+ err_code = char_add(BLE_UUID_PNP_ID_CHAR,
+ encoded_pnp_id,
+ BLE_DIS_PNP_ID_LEN,
+ &p_dis_init->dis_attr_md,
+ &pnp_id_handles);
+ if (err_code != NRF_SUCCESS)
+ {
+ return err_code;
+ }
+ }
+
+ return NRF_SUCCESS;
+}
+#endif // NRF_MODULE_ENABLED(BLE_DIS)
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/ble_dis/ble_dis.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/ble_dis/ble_dis.h
new file mode 100644
index 0000000..7c8cb9f
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/ble_dis/ble_dis.h
@@ -0,0 +1,134 @@
+/**
+ * Copyright (c) 2012 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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
+ *
+ * @defgroup ble_dis Device Information Service
+ * @{
+ * @ingroup ble_sdk_srv
+ * @brief Device Information Service module.
+ *
+ * @details This module implements the Device Information Service.
+ * During initialization it adds the Device Information Service to the BLE stack database.
+ * It then encodes the supplied information, and adds the corresponding characteristics.
+ *
+ * @note Attention!
+ * To maintain compliance with Nordic Semiconductor ASA Bluetooth profile
+ * qualification listings, this section of source code must not be modified.
+ */
+
+#ifndef BLE_DIS_H__
+#define BLE_DIS_H__
+
+#include <stdint.h>
+#include "ble_srv_common.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** @defgroup DIS_VENDOR_ID_SRC_VALUES Vendor ID Source values
+ * @{
+ */
+#define BLE_DIS_VENDOR_ID_SRC_BLUETOOTH_SIG 1 /**< Vendor ID assigned by Bluetooth SIG. */
+#define BLE_DIS_VENDOR_ID_SRC_USB_IMPL_FORUM 2 /**< Vendor ID assigned by USB Implementer's Forum. */
+/** @} */
+
+/**@brief System ID parameters */
+typedef struct
+{
+ uint64_t manufacturer_id; /**< Manufacturer ID. Only 5 LSOs shall be used. */
+ uint32_t organizationally_unique_id; /**< Organizationally unique ID. Only 3 LSOs shall be used. */
+} ble_dis_sys_id_t;
+
+/**@brief IEEE 11073-20601 Regulatory Certification Data List Structure */
+typedef struct
+{
+ uint8_t * p_list; /**< Pointer the byte array containing the encoded opaque structure based on IEEE 11073-20601 specification. */
+ uint8_t list_len; /**< Length of the byte array. */
+} ble_dis_reg_cert_data_list_t;
+
+/**@brief PnP ID parameters */
+typedef struct
+{
+ uint8_t vendor_id_source; /**< Vendor ID Source. see @ref DIS_VENDOR_ID_SRC_VALUES. */
+ uint16_t vendor_id; /**< Vendor ID. */
+ uint16_t product_id; /**< Product ID. */
+ uint16_t product_version; /**< Product Version. */
+} ble_dis_pnp_id_t;
+
+/**@brief Device Information Service init structure. This contains all possible characteristics
+ * needed for initialization of the service.
+ */
+typedef struct
+{
+ ble_srv_utf8_str_t manufact_name_str; /**< Manufacturer Name String. */
+ ble_srv_utf8_str_t model_num_str; /**< Model Number String. */
+ ble_srv_utf8_str_t serial_num_str; /**< Serial Number String. */
+ ble_srv_utf8_str_t hw_rev_str; /**< Hardware Revision String. */
+ ble_srv_utf8_str_t fw_rev_str; /**< Firmware Revision String. */
+ ble_srv_utf8_str_t sw_rev_str; /**< Software Revision String. */
+ ble_dis_sys_id_t * p_sys_id; /**< System ID. */
+ ble_dis_reg_cert_data_list_t * p_reg_cert_data_list; /**< IEEE 11073-20601 Regulatory Certification Data List. */
+ ble_dis_pnp_id_t * p_pnp_id; /**< PnP ID. */
+ ble_srv_security_mode_t dis_attr_md; /**< Initial Security Setting for Device Information Characteristics. */
+} ble_dis_init_t;
+
+/**@brief Function for initializing the Device Information Service.
+ *
+ * @details This call allows the application to initialize the device information service.
+ * It adds the DIS service and DIS characteristics to the database, using the initial
+ * values supplied through the p_dis_init parameter. Characteristics which are not to be
+ * added, shall be set to NULL in p_dis_init.
+ *
+ * @param[in] p_dis_init The structure containing the values of characteristics needed by the
+ * service.
+ *
+ * @return NRF_SUCCESS on successful initialization of service.
+ */
+uint32_t ble_dis_init(ble_dis_init_t const * p_dis_init);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // BLE_DIS_H__
+
+/** @} */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/ble_dis_c/ble_dis_c.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/ble_dis_c/ble_dis_c.c
new file mode 100644
index 0000000..deebdf8
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/ble_dis_c/ble_dis_c.c
@@ -0,0 +1,557 @@
+/**
+ * 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+
+#include "sdk_common.h"
+#if NRF_MODULE_ENABLED(BLE_DIS_C)
+#include <stdlib.h>
+
+#include "ble.h"
+#include "ble_dis_c.h"
+#include "ble_gattc.h"
+#include "nrf_bitmask.h"
+#include "nrf_queue.h"
+#include "app_error.h"
+
+#define NRF_LOG_MODULE_NAME ble_dis
+#include "nrf_log.h"
+NRF_LOG_MODULE_REGISTER();
+
+
+// Value Field lengths for System ID characteristic.
+#define BLE_DIS_C_MANUF_ID_LEN 5 /**< Length of Manufacturer ID field inside System ID characteristic. */
+#define BLE_DIS_C_OU_ID_LEN 3 /**< Length of Organizationally Unique ID field inside System ID characteristic. */
+
+// Value Field lengths for PnP ID characteristic.
+#define BLE_DIS_C_VENDOR_ID_SRC_LEN 1 /**< Length of Vendor ID Source field inside PnP ID characteristic. */
+#define BLE_DIS_C_VENDOR_ID_LEN 2 /**< Length of Vendor ID field inside PnP ID characteristic. */
+#define BLE_DIS_C_PRODUCT_ID_LEN 2 /**< Length of Product ID field inside PnP ID characteristic. */
+#define BLE_DIS_C_PRODUCT_VER_LEN 2 /**< Length of Product Version field inside PnP ID characteristic. */
+
+#define BLE_DIS_C_ALL_CHARS_DISABLED_MASK 0x0000 /**< All DIS characteristics should be disabled. */
+#define BLE_DIS_C_ALL_CHARS_ENABLED_MASK 0xFFFF /**< All DIS characteristics should be enabled. */
+
+
+/**@brief Structure for describing Client read request.
+ */
+typedef struct
+{
+ uint16_t conn_handle; /**< Connection handle for the read request. */
+ uint16_t att_handle; /**< Attribute handle for the read request. */
+} ble_dis_c_req_t;
+
+/**@brief Queue for holding Client read requests.
+ */
+NRF_QUEUE_DEF(ble_dis_c_req_t, m_ble_dis_c_queue, BLE_DIS_C_QUEUE_SIZE, NRF_QUEUE_MODE_NO_OVERFLOW);
+NRF_QUEUE_INTERFACE_DEC(ble_dis_c_req_t, ble_dis_c_queue);
+NRF_QUEUE_INTERFACE_DEF(ble_dis_c_req_t, ble_dis_c_queue, &m_ble_dis_c_queue);
+
+
+/**@brief Function for decoding System ID characteristic value.
+ *
+ * @param[in] p_data Pointer to System ID characteristic data.
+ * @param[in] len Length of the System ID characteristic data.
+ * @param[out] p_sys_id Decoded System ID characteristic.
+ *
+ * @retval NRF_SUCCESS If the characteristic was initialized successfully.
+ * @retval NRF_ERROR_INVALID_LENGTH Any parameter is NULL.
+ */
+static ret_code_t system_id_decode(uint8_t const * p_data,
+ uint16_t len,
+ ble_dis_sys_id_t * const p_sys_id)
+{
+ uint16_t const expected_len = (BLE_DIS_C_MANUF_ID_LEN + BLE_DIS_C_OU_ID_LEN);
+
+ // Validate response length.
+ if (expected_len != len)
+ {
+ NRF_LOG_ERROR("System ID characteristic data cannot be decoded.");
+ NRF_LOG_ERROR("Expected data length != Received data length: %d != %d", expected_len, len);
+ return NRF_ERROR_INVALID_LENGTH;
+ }
+
+ // Decode Manufacturer ID.
+ p_sys_id->manufacturer_id = uint40_decode(p_data);
+ p_data += BLE_DIS_C_MANUF_ID_LEN;
+
+ // Decode Organizationally unique ID.
+ p_sys_id->organizationally_unique_id = uint24_decode(p_data);
+
+ return NRF_SUCCESS;
+}
+
+
+/**@brief Function for decoding PnP ID characteristic value.
+ *
+ * @param[in] p_data Pointer to PnP ID characteristic data.
+ * @param[in] len Length of the PnP ID characteristic data.
+ * @param[out] p_pnp_id Decoded PnP ID characteristic.
+ *
+ * @retval NRF_SUCCESS If the characteristic was initialized successfully.
+ * @retval NRF_ERROR_INVALID_LENGTH Any parameter is NULL.
+ */
+static ret_code_t pnp_id_decode(uint8_t const * p_data,
+ uint16_t len,
+ ble_dis_pnp_id_t * const p_pnp_id)
+{
+ uint16_t const expected_len = (BLE_DIS_C_VENDOR_ID_SRC_LEN + BLE_DIS_C_VENDOR_ID_LEN +
+ BLE_DIS_C_PRODUCT_ID_LEN + BLE_DIS_C_PRODUCT_VER_LEN);
+
+ // Validate response length.
+ if (expected_len != len)
+ {
+ NRF_LOG_ERROR("PnP ID characteristic data cannot be decoded.");
+ NRF_LOG_ERROR("Expected data length != Received data length: %d != %d", expected_len, len);
+ return NRF_ERROR_INVALID_LENGTH;
+ }
+
+ // Decode Vendor ID Source.
+ p_pnp_id->vendor_id_source = p_data[0];
+ p_data += BLE_DIS_C_VENDOR_ID_SRC_LEN;
+
+ // Decode Vendor ID.
+ p_pnp_id->vendor_id = uint16_decode(p_data);
+ p_data += BLE_DIS_C_VENDOR_ID_LEN;
+
+ // Decode Product ID.
+ p_pnp_id->product_id = uint16_decode(p_data);
+ p_data += BLE_DIS_C_PRODUCT_ID_LEN;
+
+ // Decode Product Version.
+ p_pnp_id->product_version = uint16_decode(p_data);
+
+ return NRF_SUCCESS;
+}
+
+
+/**@brief Function for matching DIS Client characteristic type with the provided response handle.
+ *
+ * @param[in] p_ble_dis_c Pointer to the Device Information Client Structure.
+ * @param[in] response_handle Attribute handle from the response event.
+ */
+static ble_dis_c_char_type_t char_type_get(ble_dis_c_t * p_ble_dis_c, uint16_t response_handle)
+{
+ for (ble_dis_c_char_type_t char_type = (ble_dis_c_char_type_t) 0;
+ char_type < BLE_DIS_C_CHAR_TYPES_NUM;
+ char_type++)
+ {
+ if (response_handle == p_ble_dis_c->handles[char_type])
+ {
+ return char_type;
+ }
+ }
+ return BLE_DIS_C_CHAR_TYPES_NUM;
+}
+
+
+/**@brief Function for passing any pending request from the queue to the stack.
+ *
+ * @param[in] p_ble_dis_c Pointer to the Device Information Client Structure.
+ */
+static void queue_process(ble_dis_c_t * p_ble_dis_c)
+{
+ ret_code_t err_code;
+ ble_dis_c_req_t dis_c_req;
+
+ err_code = ble_dis_c_queue_peek(&dis_c_req);
+ if (err_code == NRF_SUCCESS) // Queue is not empty
+ {
+ err_code = sd_ble_gattc_read(dis_c_req.conn_handle,
+ dis_c_req.att_handle,
+ 0);
+ if (err_code == NRF_ERROR_BUSY) // SoftDevice is processing another Client procedure
+ {
+ NRF_LOG_DEBUG("SD is currently busy. This request for Client Read procedure will be \
+ attempted again.",
+ err_code);
+ }
+ else
+ {
+ UNUSED_RETURN_VALUE(ble_dis_c_queue_pop(&dis_c_req));
+ if (err_code == NRF_SUCCESS)
+ {
+ NRF_LOG_DEBUG("SD Read/Write API returns Success.");
+ }
+ else
+ {
+ NRF_LOG_ERROR("SD Read API returns error: 0x%08X.", err_code);
+ if (p_ble_dis_c->error_handler != NULL)
+ {
+ p_ble_dis_c->error_handler(err_code);
+ }
+ }
+ }
+ }
+}
+
+
+/**@brief Function for handling read response events.
+ *
+ * @details This function will validate the read response and raise the appropriate
+ * event to the application.
+ *
+ * @param[in] p_ble_dis_c Pointer to the Device Information Client Structure.
+ * @param[in] p_ble_evt Pointer to the SoftDevice event.
+ */
+static void on_read_rsp(ble_dis_c_t * p_ble_dis_c, ble_evt_t const * p_ble_evt)
+{
+ ret_code_t err_code;
+ ble_gattc_evt_read_rsp_t const * p_response = &p_ble_evt->evt.gattc_evt.params.read_rsp;
+ ble_dis_c_evt_t ble_dis_c_evt;
+ ble_dis_c_char_type_t char_type;
+
+ // Check if the event is on the link for this instance and the event handler is present.
+ if ((p_ble_dis_c->evt_handler == NULL) ||
+ (p_ble_dis_c->conn_handle != p_ble_evt->evt.gattc_evt.conn_handle))
+ {
+ return;
+ }
+
+ char_type = char_type_get(p_ble_dis_c, p_response->handle);
+ if (char_type < BLE_DIS_C_CHAR_TYPES_NUM) // Characteristic type is valid.
+ {
+ memset(&ble_dis_c_evt, 0, sizeof(ble_dis_c_evt_t));
+
+ ble_dis_c_evt.conn_handle = p_ble_evt->evt.gattc_evt.conn_handle;
+
+ if (p_ble_evt->evt.gattc_evt.gatt_status == BLE_GATT_STATUS_SUCCESS)
+ {
+ ble_dis_c_evt_read_rsp_t * const p_dis_rsp = &ble_dis_c_evt.params.read_rsp;
+
+ ble_dis_c_evt.evt_type = BLE_DIS_C_EVT_DIS_C_READ_RSP;
+
+ p_dis_rsp->char_type = char_type;
+ p_dis_rsp->handle = p_response->handle;
+
+ // Decode characteristic value.
+ switch (char_type)
+ {
+ case BLE_DIS_C_MANUF_NAME:
+ case BLE_DIS_C_MODEL_NUM:
+ case BLE_DIS_C_SERIAL_NUM:
+ case BLE_DIS_C_HW_REV:
+ case BLE_DIS_C_FW_REV:
+ case BLE_DIS_C_SW_REV:
+ p_dis_rsp->content.string.p_data = (uint8_t *) p_response->data;
+ p_dis_rsp->content.string.len = p_response->len;
+ break;
+
+ case BLE_DIS_C_SYS_ID:
+ err_code = system_id_decode(p_response->data,
+ p_response->len,
+ &p_dis_rsp->content.sys_id);
+ if ((p_ble_dis_c->error_handler != NULL) && (err_code != NRF_SUCCESS))
+ {
+ p_ble_dis_c->error_handler(err_code);
+ }
+ break;
+
+ case BLE_DIS_C_CERT_LIST:
+ p_dis_rsp->content.cert_list.p_list = (uint8_t *) p_response->data;
+ p_dis_rsp->content.cert_list.list_len = p_response->len;
+ break;
+
+ case BLE_DIS_C_PNP_ID:
+ err_code = pnp_id_decode(p_response->data,
+ p_response->len,
+ &p_dis_rsp->content.pnp_id);
+ if ((p_ble_dis_c->error_handler != NULL) && (err_code != NRF_SUCCESS))
+ {
+ p_ble_dis_c->error_handler(err_code);
+ }
+ break;
+
+ default:
+ break;
+ }
+
+ p_ble_dis_c->evt_handler(p_ble_dis_c, &ble_dis_c_evt);
+ NRF_LOG_DEBUG("Received correct read response.");
+ }
+ else // Generate error event.
+ {
+ ble_dis_c_evt.evt_type = BLE_DIS_C_EVT_DIS_C_READ_RSP_ERROR;
+
+ ble_dis_c_evt.params.read_rsp_err.char_type = char_type;
+ ble_dis_c_evt.params.read_rsp_err.err_handle = p_ble_evt->evt.gattc_evt.error_handle;
+ ble_dis_c_evt.params.read_rsp_err.gatt_status = p_ble_evt->evt.gattc_evt.gatt_status;
+
+ p_ble_dis_c->evt_handler(p_ble_dis_c, &ble_dis_c_evt);
+ NRF_LOG_ERROR("Read request failed: 0x%04X.", p_ble_evt->evt.gattc_evt.gatt_status);
+ }
+ }
+}
+
+
+/**@brief Function for handling Disconnected event received from the SoftDevice.
+ *
+ * @details This function checks if the disconnect event is happening on the link
+ * associated with the current instance of the module. If so, it will set its
+ * conn_handle to invalid.
+ *
+ * @param[in] p_ble_dis_c Pointer to the Device Information Client Structure.
+ * @param[in] p_ble_evt Pointer to the BLE event received.
+ */
+static void on_disconnected(ble_dis_c_t * p_ble_dis_c, const ble_evt_t * p_ble_evt)
+{
+ if (p_ble_dis_c->conn_handle == p_ble_evt->evt.gap_evt.conn_handle)
+ {
+ p_ble_dis_c->conn_handle = BLE_CONN_HANDLE_INVALID;
+
+ if (p_ble_dis_c->evt_handler != NULL)
+ {
+ ble_dis_c_evt_t dis_c_evt =
+ {
+ .evt_type = BLE_DIS_C_EVT_DISCONNECTED,
+ .conn_handle = p_ble_evt->evt.gap_evt.conn_handle
+ };
+
+ p_ble_dis_c->evt_handler(p_ble_dis_c, &dis_c_evt);
+ }
+ }
+}
+
+
+ret_code_t ble_dis_c_init(ble_dis_c_t * p_ble_dis_c, ble_dis_c_init_t * p_ble_dis_c_init)
+{
+ ble_uuid_t dis_uuid;
+
+ VERIFY_PARAM_NOT_NULL(p_ble_dis_c);
+ VERIFY_PARAM_NOT_NULL(p_ble_dis_c_init);
+
+ dis_uuid.type = BLE_UUID_TYPE_BLE;
+ dis_uuid.uuid = BLE_UUID_DEVICE_INFORMATION_SERVICE;
+
+ p_ble_dis_c->conn_handle = BLE_CONN_HANDLE_INVALID;
+ p_ble_dis_c->evt_handler = p_ble_dis_c_init->evt_handler;
+ p_ble_dis_c->error_handler = p_ble_dis_c_init->error_handler;
+ memset(p_ble_dis_c->handles, BLE_GATT_HANDLE_INVALID, sizeof(p_ble_dis_c->handles));
+
+ // Enable only selected characteristics if characteristic group is defined.
+ if (p_ble_dis_c_init->char_group.p_char_type != NULL)
+ {
+ p_ble_dis_c->char_mask = BLE_DIS_C_ALL_CHARS_DISABLED_MASK;
+
+ for (uint8_t i = 0; i < p_ble_dis_c_init->char_group.size; i++)
+ {
+ nrf_bitmask_bit_set(p_ble_dis_c_init->char_group.p_char_type[i],
+ &p_ble_dis_c->char_mask);
+ }
+ }
+ else
+ {
+ p_ble_dis_c->char_mask = BLE_DIS_C_ALL_CHARS_ENABLED_MASK;
+ }
+
+ return ble_db_discovery_evt_register(&dis_uuid);
+}
+
+
+void ble_dis_c_on_db_disc_evt(ble_dis_c_t * p_ble_dis_c, ble_db_discovery_evt_t * p_evt)
+{
+ ble_gatt_db_char_t * p_chars = p_evt->params.discovered_db.charateristics;
+ ble_dis_c_evt_t ble_dis_c_evt;
+
+ // Check if the service discovery is necessary for the link and if the event handler is present.
+ if ((p_ble_dis_c->evt_handler == NULL) ||
+ (p_ble_dis_c->conn_handle == p_evt->conn_handle))
+ {
+ return;
+ }
+
+ // Check if the DIS was discovered.
+ if ((p_evt->evt_type == BLE_DB_DISCOVERY_COMPLETE) &&
+ (p_evt->params.discovered_db.srv_uuid.uuid == BLE_UUID_DEVICE_INFORMATION_SERVICE) &&
+ (p_evt->params.discovered_db.srv_uuid.type == BLE_UUID_TYPE_BLE))
+ {
+ memset(&ble_dis_c_evt, 0, sizeof(ble_dis_c_evt_t));
+ ble_dis_c_evt.evt_type = BLE_DIS_C_EVT_DISCOVERY_COMPLETE;
+ ble_dis_c_evt.conn_handle = p_evt->conn_handle;
+
+ for (uint32_t i = 0; i < p_evt->params.discovered_db.char_count; i++)
+ {
+ switch (p_chars[i].characteristic.uuid.uuid)
+ {
+ case BLE_UUID_MANUFACTURER_NAME_STRING_CHAR:
+ ble_dis_c_evt.params.disc_complete.handles[BLE_DIS_C_MANUF_NAME] =
+ p_chars[i].characteristic.handle_value;
+ break;
+
+ case BLE_UUID_MODEL_NUMBER_STRING_CHAR:
+ ble_dis_c_evt.params.disc_complete.handles[BLE_DIS_C_MODEL_NUM] =
+ p_chars[i].characteristic.handle_value;
+ break;
+
+ case BLE_UUID_SERIAL_NUMBER_STRING_CHAR:
+ ble_dis_c_evt.params.disc_complete.handles[BLE_DIS_C_SERIAL_NUM] =
+ p_chars[i].characteristic.handle_value;
+ break;
+
+ case BLE_UUID_HARDWARE_REVISION_STRING_CHAR:
+ ble_dis_c_evt.params.disc_complete.handles[BLE_DIS_C_HW_REV] =
+ p_chars[i].characteristic.handle_value;
+ break;
+
+ case BLE_UUID_FIRMWARE_REVISION_STRING_CHAR:
+ ble_dis_c_evt.params.disc_complete.handles[BLE_DIS_C_FW_REV] =
+ p_chars[i].characteristic.handle_value;
+ break;
+
+ case BLE_UUID_SOFTWARE_REVISION_STRING_CHAR:
+ ble_dis_c_evt.params.disc_complete.handles[BLE_DIS_C_SW_REV] =
+ p_chars[i].characteristic.handle_value;
+ break;
+
+ case BLE_UUID_SYSTEM_ID_CHAR:
+ ble_dis_c_evt.params.disc_complete.handles[BLE_DIS_C_SYS_ID] =
+ p_chars[i].characteristic.handle_value;
+ break;
+
+ case BLE_UUID_IEEE_REGULATORY_CERTIFICATION_DATA_LIST_CHAR:
+ ble_dis_c_evt.params.disc_complete.handles[BLE_DIS_C_CERT_LIST] =
+ p_chars[i].characteristic.handle_value;
+ break;
+
+ case BLE_UUID_PNP_ID_CHAR:
+ ble_dis_c_evt.params.disc_complete.handles[BLE_DIS_C_PNP_ID] =
+ p_chars[i].characteristic.handle_value;
+ break;
+
+ default:
+ break;
+ }
+ }
+
+ // Forget handle values for disabled characteristics
+ for (ble_dis_c_char_type_t char_type = (ble_dis_c_char_type_t) 0;
+ char_type < BLE_DIS_C_CHAR_TYPES_NUM;
+ char_type++)
+ {
+ if (!nrf_bitmask_bit_is_set(char_type, &p_ble_dis_c->char_mask))
+ {
+ ble_dis_c_evt.params.disc_complete.handles[char_type] = BLE_GATT_HANDLE_INVALID;
+ }
+ }
+
+ p_ble_dis_c->evt_handler(p_ble_dis_c, &ble_dis_c_evt);
+ }
+}
+
+
+void ble_dis_c_on_ble_evt(ble_evt_t const * p_ble_evt, void * p_context)
+{
+ ble_dis_c_t * p_ble_dis_c = (ble_dis_c_t *) p_context;
+
+ if ((p_ble_dis_c == NULL) || (p_ble_evt == NULL))
+ {
+ return;
+ }
+
+ if (p_ble_dis_c->conn_handle == BLE_CONN_HANDLE_INVALID)
+ {
+ return;
+ }
+
+ switch (p_ble_evt->header.evt_id)
+ {
+ case BLE_GATTC_EVT_READ_RSP:
+ on_read_rsp(p_ble_dis_c, p_ble_evt);
+ break;
+
+ case BLE_GAP_EVT_DISCONNECTED:
+ on_disconnected(p_ble_dis_c, p_ble_evt);
+ break;
+
+ default:
+ // No implementation needed.
+ break;
+ }
+
+ // Process any DIS Client read requests that are pending.
+ queue_process(p_ble_dis_c);
+}
+
+
+ret_code_t ble_dis_c_read(ble_dis_c_t * p_ble_dis_c, ble_dis_c_char_type_t char_type)
+{
+ ret_code_t err_code;
+ ble_dis_c_req_t dis_c_req;
+
+ VERIFY_PARAM_NOT_NULL(p_ble_dis_c);
+ VERIFY_TRUE(char_type < BLE_DIS_C_CHAR_TYPES_NUM, NRF_ERROR_INVALID_PARAM);
+
+ if ((p_ble_dis_c->conn_handle == BLE_CONN_HANDLE_INVALID) ||
+ (p_ble_dis_c->handles[char_type] == BLE_GATT_HANDLE_INVALID))
+ {
+ return NRF_ERROR_INVALID_STATE;
+ }
+
+ dis_c_req.conn_handle = p_ble_dis_c->conn_handle;
+ dis_c_req.att_handle = p_ble_dis_c->handles[char_type];
+
+ err_code = ble_dis_c_queue_push(&dis_c_req);
+ VERIFY_SUCCESS(err_code);
+
+ queue_process(p_ble_dis_c);
+ return err_code;
+}
+
+
+ret_code_t ble_dis_c_handles_assign(ble_dis_c_t * p_ble_dis_c,
+ uint16_t conn_handle,
+ ble_dis_c_handle_t const * p_peer_handles)
+{
+ VERIFY_PARAM_NOT_NULL(p_ble_dis_c);
+
+ p_ble_dis_c->conn_handle = conn_handle;
+ ble_dis_c_queue_reset();
+ if (p_peer_handles != NULL)
+ {
+ memcpy(p_ble_dis_c->handles, p_peer_handles, sizeof(p_ble_dis_c->handles));
+ }
+ else
+ {
+ memset(p_ble_dis_c->handles, BLE_GATT_HANDLE_INVALID, sizeof(p_ble_dis_c->handles));
+ }
+ return NRF_SUCCESS;
+}
+
+
+#endif // NRF_MODULE_ENABLED(BLE_DIS_C)
+
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/ble_dis_c/ble_dis_c.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/ble_dis_c/ble_dis_c.h
new file mode 100644
index 0000000..ce243d8
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/ble_dis_c/ble_dis_c.h
@@ -0,0 +1,308 @@
+/**
+ * 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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
+ *
+ * @defgroup ble_dis_c Device Information Service Client
+ * @{
+ * @ingroup ble_sdk_srv
+ * @brief Device information Service Client module.
+ *
+ * @details This module contains the APIs and types exposed by the Device information Service Client
+ * module. These APIs and types can be used by the application to perform discovery of
+ * the Device information Service at the peer and interact with it.
+ *
+ * @note The application must register this module as BLE event observer using the
+ * NRF_SDH_BLE_OBSERVER macro. Example:
+ * @code
+ * ble_dis_c_t instance;
+ * NRF_SDH_BLE_OBSERVER(anything, BLE_DIS_C_BLE_OBSERVER_PRIO,
+ * ble_dis_c_on_ble_evt, &instance);
+ * @endcode
+ *
+ */
+
+
+#ifndef BLE_DIS_C_H__
+#define BLE_DIS_C_H__
+
+#include <stdint.h>
+#include <stdbool.h>
+#include "ble.h"
+#include "ble_gatt.h"
+#include "ble_db_discovery.h"
+#include "ble_srv_common.h"
+#include "ble_dis.h"
+#include "nrf_sdh_ble.h"
+
+#include "sdk_config.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**@brief Macro for defining a ble_dis_c instance.
+ *
+ * @param _name Name of the instance.
+ * @hideinitializer
+ */
+#define BLE_DIS_C_DEF(_name) \
+ static ble_dis_c_t _name; \
+ NRF_SDH_BLE_OBSERVER(_name ## _obs, \
+ BLE_DIS_C_BLE_OBSERVER_PRIO, \
+ ble_dis_c_on_ble_evt, &_name)
+
+/** @brief Macro for defining multiple ble_dis_c instances.
+ *
+ * @param _name Name of the array of instances.
+ * @param _cnt Number of instances to define.
+ * @hideinitializer
+ */
+#define BLE_DIS_C_ARRAY_DEF(_name, _cnt) \
+ static ble_dis_c_t _name[_cnt]; \
+ NRF_SDH_BLE_OBSERVERS(_name ## _obs, \
+ BLE_DIS_C_BLE_OBSERVER_PRIO, \
+ ble_dis_c_on_ble_evt, &_name, _cnt)
+
+
+/**@brief DIS Client event type. */
+typedef enum
+{
+ BLE_DIS_C_EVT_DISCOVERY_COMPLETE, /**< Event indicating that the DIS and its characteristics were discovered. See @ref ble_dis_c_evt_disc_complete_t. */
+ BLE_DIS_C_EVT_DIS_C_READ_RSP, /**< Event indicating that the client has received a read response from a peer. See @ref ble_dis_c_evt_read_rsp_t. */
+ BLE_DIS_C_EVT_DIS_C_READ_RSP_ERROR, /**< Event indicating that the client's read request has failed. See @ref ble_dis_c_evt_read_rsp_err_t. */
+ BLE_DIS_C_EVT_DISCONNECTED /**< Event indicating that the DIS server has disconnected. */
+} ble_dis_c_evt_type_t;
+
+/**@brief DIS Client characteristic type. */
+typedef enum
+{
+ BLE_DIS_C_MANUF_NAME, /**< Manufacturer Name String characteristic. */
+ BLE_DIS_C_MODEL_NUM, /**< Model Number String characteristic. */
+ BLE_DIS_C_SERIAL_NUM, /**< Serial Number String characteristic. */
+ BLE_DIS_C_HW_REV, /**< Hardware Revision String characteristic. */
+ BLE_DIS_C_FW_REV, /**< Firmware Revision String characteristic. */
+ BLE_DIS_C_SW_REV, /**< Software Revision String characteristic. */
+ BLE_DIS_C_SYS_ID, /**< System ID characteristic. */
+ BLE_DIS_C_CERT_LIST, /**< IEEE 11073-20601 Regulatory Certification Data List characteristic. */
+ BLE_DIS_C_PNP_ID, /**< PnP ID characteristic. */
+ BLE_DIS_C_CHAR_TYPES_NUM /**< Number of all possible characteristic types. */
+} ble_dis_c_char_type_t;
+
+/**@brief Attribute handle pointing to DIS characteristics on the connected peer device. */
+typedef uint16_t ble_dis_c_handle_t;
+
+/**@brief Event structure for @ref BLE_DIS_C_EVT_DISCOVERY_COMPLETE. */
+typedef struct
+{
+ ble_dis_c_handle_t handles[BLE_DIS_C_CHAR_TYPES_NUM]; /**< Handles on the connected peer device needed to interact with it. */
+} ble_dis_c_evt_disc_complete_t;
+
+/**@brief Response data for string-based DIS characteristics. */
+typedef struct
+{
+ uint8_t * p_data; /**< Pointer to response data. */
+ uint8_t len; /**< Response data length. */
+} ble_dis_c_string_t;
+
+/**@brief Event structure for @ref BLE_DIS_C_EVT_DIS_C_READ_RSP. */
+typedef struct
+{
+ ble_dis_c_char_type_t char_type; /**< Characteristic type. */
+ ble_dis_c_handle_t handle; /**< Attribute handle from the response event. */
+ union
+ {
+ ble_dis_c_string_t string; /**< String-based characteristics response data. Filled when char_type is in the following range: @ref BLE_DIS_C_MANUF_NAME - @ref BLE_DIS_C_SW_REV (inclusive). */
+ ble_dis_sys_id_t sys_id; /**< System ID characteristic response data. Filled when char_type is @ref BLE_DIS_C_SYS_ID. */
+ ble_dis_reg_cert_data_list_t cert_list; /**< IEEE 11073-20601 Regulatory Certification Data List characteristic response data. Filled when char_type is @ref BLE_DIS_C_CERT_LIST. */
+ ble_dis_pnp_id_t pnp_id; /**< PnP ID characteristic response data. Filled when char_type is @ref BLE_DIS_C_PNP_ID. */
+ } content;
+} ble_dis_c_evt_read_rsp_t;
+
+/**@brief Event structure for @ref BLE_DIS_C_EVT_DIS_C_READ_RSP_ERROR. */
+typedef struct
+{
+ ble_dis_c_char_type_t char_type; /**< Characteristic type. */
+ ble_dis_c_handle_t err_handle; /**< Attribute handle from the response event. */
+ uint16_t gatt_status; /**< GATT status code for the read operation, see @ref BLE_GATT_STATUS_CODES. */
+} ble_dis_c_evt_read_rsp_err_t;
+
+/**@brief Structure containing the DIS event data received from the peer. */
+typedef struct
+{
+ ble_dis_c_evt_type_t evt_type; /**< Type of the event. */
+ uint16_t conn_handle; /**< Connection handle on which the @ref ble_dis_c_evt_t event occurred.*/
+ union
+ {
+ ble_dis_c_evt_disc_complete_t disc_complete; /**< Discovery Complete Event Parameters. Filled when evt_type is @ref BLE_DIS_C_EVT_DISCOVERY_COMPLETE. */
+ ble_dis_c_evt_read_rsp_t read_rsp; /**< Read Response Event Parameters. Filled when evt_type is @ref BLE_DIS_C_EVT_DIS_C_READ_RSP. */
+ ble_dis_c_evt_read_rsp_err_t read_rsp_err; /**< Read Response Error Event Parameters. Filled when evt_type is @ref BLE_DIS_C_EVT_DIS_C_READ_RSP_ERROR. */
+ } params;
+} ble_dis_c_evt_t;
+
+// Forward declaration of the ble_dis_t type.
+typedef struct ble_dis_c_s ble_dis_c_t;
+
+/**@brief Event handler type.
+ *
+ * @details This is the type of the event handler that should be provided by the application
+ * of this module to receive events.
+ */
+typedef void (* ble_dis_c_evt_handler_t)(ble_dis_c_t * p_ble_dis_c, ble_dis_c_evt_t const * p_evt);
+
+/**@brief DIS Client structure. */
+struct ble_dis_c_s
+{
+ uint16_t conn_handle; /**< Handle of the current connection. Set with @ref ble_dis_c_handles_assign when connected. */
+ uint16_t char_mask; /**< Mask with enabled DIS characteristics.*/
+ ble_dis_c_handle_t handles[BLE_DIS_C_CHAR_TYPES_NUM]; /**< Handles on the connected peer device needed to interact with it. */
+ ble_srv_error_handler_t error_handler; /**< Application error handler to be called in case of an error. */
+ ble_dis_c_evt_handler_t evt_handler; /**< Application event handler to be called when there is an event related to the DIS. */
+};
+
+/**@brief Structure describing the group of DIS characteristics with which this module can interact. */
+typedef struct
+{
+ ble_dis_c_char_type_t * p_char_type; /**< Pointer to array with selected characteristics. */
+ uint8_t size; /**< Group size. */
+} ble_dis_c_char_group_t;
+
+/**@brief DIS Client initialization structure. */
+typedef struct
+{
+ ble_dis_c_char_group_t char_group; /**< Group of DIS characteristics that should be enabled for this module instance. */
+ ble_srv_error_handler_t error_handler; /**< Application error handler to be called in case of an error. */
+ ble_dis_c_evt_handler_t evt_handler; /**< Application event handler to be called when there is an event related to the Device Information service. */
+} ble_dis_c_init_t;
+
+
+/**@brief Function for initializing the Device Information service client module.
+ *
+ * @details This function registers with the Database Discovery module
+ * for the DIS. Doing so will make the Database Discovery
+ * module look for the presence of a DIS instance at the peer when a
+ * discovery is started.
+ *
+ * @param[in] p_ble_dis_c Pointer to the DIS client structure.
+ * @param[in] p_ble_dis_c_init Pointer to the DIS initialization structure containing the
+ * initialization information.
+ *
+ * @retval NRF_SUCCESS If the module was initialized successfully.
+ * @retval NRF_ERROR_NULL Any parameter is NULL.
+ * @return If functions from other modules return errors to this function
+ * (@ref ble_db_discovery_evt_register), the @ref nrf_error are propagated.
+ */
+ret_code_t ble_dis_c_init(ble_dis_c_t * p_ble_dis_c, ble_dis_c_init_t * p_ble_dis_c_init);
+
+
+/**@brief Function for handling events from the database discovery module.
+ *
+ * @details This function will handle an event from the database discovery module, and determine
+ * if it relates to the discovery of DIS at the peer. If so, it will
+ * call the application's event handler indicating that DIS has been
+ * discovered at the peer. It also populates the event with the service related
+ * information before providing it to the application.
+ *
+ * @param[in] p_ble_dis_c Pointer to the DIS client structure.
+ * @param[in] p_evt Pointer to the event received from the database discovery module.
+ */
+void ble_dis_c_on_db_disc_evt(ble_dis_c_t * p_ble_dis_c, ble_db_discovery_evt_t * p_evt);
+
+
+/**@brief Function for handling BLE events from the SoftDevice.
+ *
+ * @details This function handles the BLE events received from the SoftDevice. If a BLE
+ * event is relevant to the DIS module, it is used to update internal variables
+ * and, if necessary, send events to the application.
+ *
+ * @param[in] p_ble_evt Pointer to the BLE event.
+ * @param[in] p_context Pointer to the DIS client structure.
+ */
+void ble_dis_c_on_ble_evt(ble_evt_t const * p_ble_evt, void * p_context);
+
+
+/**@brief Function for reading different characteristics from DIS.
+ *
+ * @details This function can be used to read different characteristics that are available
+ * inside DIS. The response data will be provided from the response event
+ * @ref BLE_DIS_C_EVT_DIS_C_READ_RSP. The @ref BLE_DIS_C_EVT_DIS_C_READ_RSP_ERROR
+ * event can be generated if the read operation is unsuccessful.
+ *
+ * @param[in] p_ble_dis_c Pointer to the DIS client structure.
+ * @param[in] char_type Type of characteristic to read.
+ *
+ * @retval NRF_SUCCESS If the operation was successful.
+ * @retval NRF_ERROR_NULL If a \p p_ble_dis_c was a NULL pointer.
+ * @retval NRF_ERROR_INVALID_PARAM If a \p char_type is not valid.
+ * @retval NRF_ERROR_INVALID_STATE If connection handle or attribute handle is invalid.
+ * @retval NRF_ERROR_NO_MEM If the client request queue is full.
+ */
+ret_code_t ble_dis_c_read(ble_dis_c_t * p_ble_dis_c, ble_dis_c_char_type_t char_type);
+
+
+/**@brief Function for assigning handles to this instance of dis_c.
+ *
+ * @details Call this function when a link has been established with a peer to
+ * associate this link to this instance of the module. This makes it
+ * possible to handle several links and associate each link to a particular
+ * instance of this module. The connection handle and attribute handles will be
+ * provided from the discovery event @ref BLE_DIS_C_EVT_DISCOVERY_COMPLETE.
+ *
+ * @param[in] p_ble_dis_c Pointer to the DIS client structure instance to associate with these
+ * handles.
+ * @param[in] conn_handle Connection handle associated with the given DIS Instance.
+ * @param[in] p_peer_handles Attribute handles on the DIS server that you want this DIS client to
+ * interact with.
+ *
+ * @retval NRF_SUCCESS If the operation was successful.
+ * @retval NRF_ERROR_NULL If a \p p_ble_dis_c was a NULL pointer.
+ */
+ret_code_t ble_dis_c_handles_assign(ble_dis_c_t * p_ble_dis_c,
+ uint16_t conn_handle,
+ ble_dis_c_handle_t const * p_peer_handles);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // BLE_DIS_C_H__
+
+/** @} */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/ble_escs/escs_defs.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/ble_escs/escs_defs.h
new file mode 100644
index 0000000..0498939
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/ble_escs/escs_defs.h
@@ -0,0 +1,133 @@
+/**
+ * Copyright (c) 2016 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#ifndef ESCS_DEFS_H__
+#define ESCS_DEFS_H__
+
+#include "es.h"
+
+/*@file Contains definitions specific to the Eddystone Configuration Service */
+
+#define ESCS_LOCK_STATE_NEW_LOCK_CODE_WRITE_LENGTH 17
+
+#define ESCS_UID_READ_LENGTH (ES_UID_LENGTH)
+#define ESCS_UID_WRITE_LENGTH (ES_UID_NAMESPACE_LENGTH + \
+ ES_UID_INSTANCE_LENGTH + ES_FRAME_TYPE_LENGTH)
+
+#define ESCS_TLM_READ_LENGTH (ESCS_TLM_READ_LENGTH)
+#define ESCS_TLM_WRITE_LENGTH (ES_FRAME_TYPE_LENGTH)
+
+#define ESCS_EID_READ_LENGTH (14)
+#define ESCS_EID_WRITE_ECDH_LENGTH (34)
+#define ESCS_EID_WRITE_PUB_KEY_INDEX (1)
+#define ESCS_EID_WRITE_ENC_ID_KEY_INDEX (1)
+#define ESCS_EID_WRITE_IDK_LENGTH (18)
+
+#define ESCS_URL_MIN_WRITE_LENGTH (4)
+#define ESCS_URL_WRITE_LENGTH (19)
+
+#ifdef NRF52_SERIES
+#define ESCS_NUM_OF_SUPPORTED_TX_POWER (9)
+/**@brief TX power levels, based on nRF52 specifications. */
+#define ESCS_SUPPORTED_TX_POWER {-40, -20, -16, -12, -8, -4, 0, 3, 4}
+#elif NRF51
+/**@brief TX power levels, based on nRF51 specifications. */
+#define ESCS_NUM_OF_SUPPORTED_TX_POWER (8)
+#define ESCS_SUPPORTED_TX_POWER {-30, -20, -16, -12, -8, -4, 0, 4}
+#else
+#error MISSING TX POWER
+#endif
+
+// Defined in Eddystone Specifications
+#define ESCS_AES_KEY_SIZE (16)
+#define ESCS_ECDH_KEY_SIZE (32)
+
+#define ESCS_ADV_SLOT_CHAR_LENGTH_MAX (34) // Corresponds to when the slots is configured as an EID slot
+
+// Characteristic: Broadcast Capabilities
+
+// Field: nrf_ble_escs_init_params_t.broadcast_cap.cap_bitfield
+#define ESCS_BROADCAST_VAR_ADV_SUPPORTED_Yes (1) // Set if the beacon supports individual per-slot adv intervals
+#define ESCS_BROADCAST_VAR_ADV_SUPPORTED_No (0)
+#define ESCS_BROADCAST_VAR_ADV_SUPPORTED_Pos (0)
+#define ESCS_BROADCAST_VAR_ADV_SUPPORTED_Msk (1 << ESCS_BROADCAST_VAR_ADV_SUPPORTED_Pos)
+#define ESCS_BROADCAST_VAR_TX_POWER_SUPPORTED_Yes (1) // Set if the beacon supports individual per-slot TX intervals
+#define ESCS_BROADCAST_VAR_TX_POWER_SUPPORTED_No (0)
+#define ESCS_BROADCAST_VAR_TX_POWER_SUPPORTED_Pos (1)
+#define ESCS_BROADCAST_VAR_TX_POWER_SUPPORTED_Msk (1 << ESCS_BROADCAST_VAR_TX_POWER_SUPPORTED_Pos)
+#define ESCS_BROADCAST_VAR_RFU_MASK (0x03) // AND Mask to guarantee that bits 0x04 to 0x80 (RFU) are cleared
+
+// Field: nrf_ble_escs_init_params_t.broadcast_cap.supp_frame_types
+#define ESCS_FRAME_TYPE_UID_SUPPORTED_Yes (1)
+#define ESCS_FRAME_TYPE_UID_SUPPORTED_No (0)
+#define ESCS_FRAME_TYPE_UID_SUPPORTED_Pos (0)
+#define ESCS_FRAME_TYPE_UID_SUPPORTED_Msk (1 << ESCS_FRAME_TYPE_UID_SUPPORTED_Pos)
+
+#define ESCS_FRAME_TYPE_URL_SUPPORTED_Yes (1)
+#define ESCS_FRAME_TYPE_URL_SUPPORTED_No (0)
+#define ESCS_FRAME_TYPE_URL_SUPPORTED_Pos (1)
+#define ESCS_FRAME_TYPE_URL_SUPPORTED_Msk (1 << ESCS_FRAME_TYPE_URL_SUPPORTED_Pos)
+
+#define ESCS_FRAME_TYPE_TLM_SUPPORTED_Yes (1)
+#define ESCS_FRAME_TYPE_TLM_SUPPORTED_No (0)
+#define ESCS_FRAME_TYPE_TLM_SUPPORTED_Pos (2)
+#define ESCS_FRAME_TYPE_TLM_SUPPORTED_Msk (1 << ESCS_FRAME_TYPE_TLM_SUPPORTED_Pos)
+
+#define ESCS_FRAME_TYPE_EID_SUPPORTED_Yes (1)
+#define ESCS_FRAME_TYPE_EID_SUPPORTED_No (0)
+#define ESCS_FRAME_TYPE_EID_SUPPORTED_Pos (3)
+#define ESCS_FRAME_TYPE_EID_SUPPORTED_Msk (1 << ESCS_FRAME_TYPE_EID_SUPPORTED_Pos)
+
+#define ESCS_FRAME_TYPE_RFU_MASK (0x000F) // AND Mask to guarantee that bits 0x0010 to 0x8000 (RFU) are cleared
+
+// Characteristic: Lock State: Lock State (READ)
+#define ESCS_LOCK_STATE_LOCKED (0x00)
+#define ESCS_LOCK_STATE_UNLOCKED (0x01)
+#define ESCS_LOCK_STATE_UNLOCKED_AUTO_RELOCK_DISABLED (0x02)
+
+// Characteristic: Lock State: Lock Byte (WRITE)
+#define ESCS_LOCK_BYTE_LOCK (0x00)
+#define ESCS_LOCK_BYTE_DISABLE_AUTO_RELOCK (0x02)
+
+
+// Charcteristic: Remain Connectable
+#define ESCS_FUNCT_REMAIN_CONNECTABLE_SUPPORTED_Yes (0x01)
+#define ESCS_FUNCT_REMAIN_CONNECTABLE_SUPPORTED_No (0x00)
+
+#endif // ESCS_DEFS_H__
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/ble_escs/nrf_ble_escs.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/ble_escs/nrf_ble_escs.c
new file mode 100644
index 0000000..d841c4a
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/ble_escs/nrf_ble_escs.c
@@ -0,0 +1,675 @@
+/**
+ * Copyright (c) 2016 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#include "nrf_ble_escs.h"
+#include <string.h>
+#include "es_app_config.h"
+
+#ifdef BLE_HANDLER_DEBUG
+ #include "SEGGER_RTT.h"
+ #define DEBUG_PRINTF SEGGER_RTT_printf
+#else
+ #define DEBUG_PRINTF(...)
+#endif
+
+#define EID_BUFF_SIZE 64
+
+typedef struct
+{
+ uint16_t uuid;
+ uint8_t read:1;
+ uint8_t write:1;
+ uint8_t rd_auth:1;
+ uint8_t wr_auth:1;
+ uint8_t vlen:1;
+ uint8_t vloc:2;
+ uint8_t init_len;
+ uint8_t max_len;
+} char_init_t;
+
+typedef struct
+{
+ uint16_t val_handle;
+ uint16_t uuid;
+} val_handle_to_uuid_t;
+
+static const char_init_t BROADCAST_CAP_CHAR_INIT =
+{
+ .uuid = BLE_UUID_ESCS_BROADCAST_CAP_CHAR,
+ .read = 1,
+ .write = 0,
+ .rd_auth = 1,
+ .wr_auth = 0,
+ .vlen = 1,
+ .vloc = BLE_GATTS_VLOC_STACK,
+ .init_len = NRF_BLE_ESCS_BROADCAST_CAP_LEN,
+ .max_len = NRF_BLE_ESCS_BROADCAST_CAP_LEN
+};
+
+static const char_init_t ACTIVE_SLOT_CHAR_INIT =
+{
+ .uuid = BLE_UUID_ESCS_ACTIVE_SLOT_CHAR,
+ .read = 1,
+ .write = 1,
+ .rd_auth = 1,
+ .wr_auth = 1,
+ .vlen = 0,
+ .vloc = BLE_GATTS_VLOC_USER,
+ .init_len = sizeof(nrf_ble_escs_active_slot_t),
+ .max_len = sizeof(nrf_ble_escs_active_slot_t)
+};
+
+static const char_init_t ADV_INTERVAL_CHAR_INIT =
+{
+ .uuid = BLE_UUID_ESCS_ADV_INTERVAL_CHAR,
+ .read = 1,
+ .write = 1,
+ .rd_auth = 1,
+ .wr_auth = 1,
+ .vlen = 0,
+ .vloc = BLE_GATTS_VLOC_STACK,
+ .init_len = sizeof(nrf_ble_escs_adv_interval_t),
+ .max_len = sizeof(nrf_ble_escs_adv_interval_t)
+};
+
+static const char_init_t RADIO_TX_PWR_CHAR_INIT =
+{
+ .uuid = BLE_UUID_ESCS_RADIO_TX_PWR_CHAR,
+ .read = 1,
+ .write = 1,
+ .rd_auth = 1,
+ .wr_auth = 1,
+ .vlen = 0,
+ .vloc = BLE_GATTS_VLOC_STACK,
+ .init_len = sizeof(nrf_ble_escs_radio_tx_pwr_t),
+ .max_len = sizeof(nrf_ble_escs_radio_tx_pwr_t)
+};
+
+static const char_init_t ADV_TX_PWR_CHAR_INIT =
+{
+ .uuid = BLE_UUID_ESCS_ADV_TX_PWR_CHAR,
+ .read = 1,
+ .write = 1,
+ .rd_auth = 1,
+ .wr_auth = 1,
+ .vlen = 0,
+ .vloc = BLE_GATTS_VLOC_STACK,
+ .init_len = sizeof(nrf_ble_escs_adv_tx_pwr_t),
+ .max_len = sizeof(nrf_ble_escs_adv_tx_pwr_t)
+};
+
+static const char_init_t LOCK_STATE_CHAR_INIT =
+{
+ .uuid = BLE_UUID_ESCS_LOCK_STATE_CHAR,
+ .read = 1,
+ .write = 1,
+ .rd_auth = 1,
+ .wr_auth = 1,
+ .vlen = 1,
+ .vloc = BLE_GATTS_VLOC_USER,
+ .init_len = 1,
+ .max_len = 17
+};
+
+static const char_init_t UNLOCK_CHAR_INIT =
+{
+ .uuid = BLE_UUID_ESCS_UNLOCK_CHAR,
+ .read = 1,
+ .write = 1,
+ .rd_auth = 1,
+ .wr_auth = 1,
+ .vlen = 0,
+ .vloc = BLE_GATTS_VLOC_STACK,
+ .init_len = 1,
+ .max_len = ESCS_AES_KEY_SIZE
+};
+
+static const char_init_t PUBLIC_ECDH_KEY_CHAR_INIT =
+{
+ .uuid = BLE_UUID_ESCS_PUBLIC_ECDH_KEY_CHAR,
+ .read = 1,
+ .write = 0,
+ .rd_auth = 1,
+ .wr_auth = 0,
+ .vlen = 1,
+ .init_len = 1,
+ .vloc = BLE_GATTS_VLOC_STACK,
+ .max_len = ESCS_ECDH_KEY_SIZE
+};
+
+static const char_init_t EID_ID_KEY_CHAR_INIT =
+{
+ .uuid = BLE_UUID_ESCS_EID_ID_KEY_CHAR,
+ .read = 1,
+ .write = 0,
+ .rd_auth = 1,
+ .wr_auth = 0,
+ .vlen = 1,
+ .vloc = BLE_GATTS_VLOC_STACK,
+ .init_len = 1,
+ .max_len = ESCS_AES_KEY_SIZE
+};
+
+static const char_init_t RW_ADV_SLOT_CHAR_INIT =
+{
+ .uuid = BLE_UUID_ESCS_RW_ADV_SLOT_CHAR,
+ .read = 1,
+ .write = 1,
+ .rd_auth = 1,
+ .wr_auth = 1,
+ .vlen = 1,
+ .vloc = BLE_GATTS_VLOC_STACK,
+ .init_len = 0,
+ .max_len = ESCS_ADV_SLOT_CHAR_LENGTH_MAX
+};
+
+static const char_init_t FACTORY_RESET_CHAR_INIT =
+{
+ .uuid = BLE_UUID_ESCS_FACTORY_RESET_CHAR,
+ .read = 0,
+ .write = 1,
+ .rd_auth = 0,
+ .wr_auth = 1,
+ .vlen = 0,
+ .vloc = BLE_GATTS_VLOC_STACK,
+ .init_len = sizeof(nrf_ble_escs_factory_reset_t),
+ .max_len = sizeof(nrf_ble_escs_factory_reset_t)
+};
+
+static const char_init_t REMAIN_CONNECTABLE_CHAR_INIT =
+{
+ .uuid = BLE_UUID_ESCS_REMAIN_CONNECTABLE_CHAR,
+ .read = 1,
+ .write = 1,
+ .rd_auth = 1,
+ .wr_auth = 1,
+ .vlen = 0,
+ .vloc = BLE_GATTS_VLOC_STACK,
+ .init_len = 1,
+ .max_len = 1
+};
+
+static val_handle_to_uuid_t m_handle_to_uuid_map[BLE_ESCS_NUMBER_OF_CHARACTERISTICS]; //!< Map from handle to UUID.
+static uint8_t m_handle_to_uuid_map_idx = 0; //!< Index of map from handle to UUID.
+static uint8_t m_eid_mem[EID_BUFF_SIZE] = {0}; //!< Memory buffer used for EID writes.
+static ble_user_mem_block_t m_eid_mem_block =
+{
+ .p_mem = m_eid_mem,
+ .len = EID_BUFF_SIZE
+}; //!< Memory block used for EID writes.
+
+
+
+/**@brief Function for adding characteristic to Eddystone service.
+ *
+ * @param[in] p_escs Eddystone Configuration Service structure.
+ * @param[in] p_escs_init Information needed to initialize the service.
+ * @param[in] p_char_init Information needed to initialize the characteristic.
+ *
+ * @return NRF_SUCCESS on success, otherwise an error code.
+ */
+static uint32_t char_add(const char_init_t * p_char_init,
+ nrf_ble_escs_t * p_escs,
+ void * p_value,
+ ble_gatts_char_handles_t * p_handles)
+{
+ uint32_t err_code;
+ ble_gatts_char_md_t char_md;
+ ble_gatts_attr_t attr_char_value;
+ ble_uuid_t ble_uuid;
+ ble_gatts_attr_md_t attr_md;
+
+ VERIFY_PARAM_NOT_NULL(p_char_init);
+ VERIFY_PARAM_NOT_NULL(p_escs);
+ VERIFY_PARAM_NOT_NULL(p_value);
+ VERIFY_PARAM_NOT_NULL(p_handles);
+
+ memset(&char_md, 0, sizeof(char_md));
+ memset(&attr_char_value, 0, sizeof(attr_char_value));
+ memset(&ble_uuid, 0, sizeof(ble_uuid));
+ memset(&attr_md, 0, sizeof(attr_md));
+
+ if (p_char_init->read)
+ {
+ char_md.char_props.read = 1;
+ BLE_GAP_CONN_SEC_MODE_SET_OPEN(&attr_md.read_perm);
+ }
+
+ else
+ {
+ BLE_GAP_CONN_SEC_MODE_SET_NO_ACCESS(&attr_md.read_perm);
+ }
+
+ if (p_char_init->write)
+ {
+ BLE_GAP_CONN_SEC_MODE_SET_OPEN(&attr_md.write_perm);
+ char_md.char_props.write = 1;
+ }
+
+ else
+ {
+ BLE_GAP_CONN_SEC_MODE_SET_NO_ACCESS(&attr_md.write_perm);
+ }
+
+ ble_uuid.type = p_escs->uuid_type;
+ ble_uuid.uuid = p_char_init->uuid;
+
+ attr_md.vloc = p_char_init->vloc;
+ attr_md.rd_auth = p_char_init->rd_auth;
+ attr_md.wr_auth = p_char_init->wr_auth;
+ attr_md.vlen = p_char_init->vlen;
+
+ attr_char_value.p_uuid = &ble_uuid;
+ attr_char_value.p_attr_md = &attr_md;
+ attr_char_value.init_len = p_char_init->init_len;
+ attr_char_value.p_value = p_value;
+ attr_char_value.max_len = p_char_init->max_len;
+
+ err_code = sd_ble_gatts_characteristic_add(p_escs->service_handle,
+ &char_md,
+ &attr_char_value,
+ p_handles);
+
+ if (err_code == NRF_SUCCESS)
+ {
+ ASSERT(m_handle_to_uuid_map_idx < BLE_ESCS_NUMBER_OF_CHARACTERISTICS);
+ m_handle_to_uuid_map[m_handle_to_uuid_map_idx].val_handle = p_handles->value_handle;
+ m_handle_to_uuid_map[m_handle_to_uuid_map_idx].uuid = p_char_init->uuid;
+ m_handle_to_uuid_map_idx++;
+ }
+
+ return err_code;
+}
+
+
+/**@brief Function for handling the @ref BLE_GAP_EVT_CONNECTED event from the SoftDevice.
+ *
+ * @param[in] p_escs Eddystone Configuration Service structure.
+ * @param[in] p_ble_evt Pointer to the event received from BLE stack.
+ */
+static void on_connect(nrf_ble_escs_t * p_escs, ble_evt_t const * p_ble_evt)
+{
+ VERIFY_PARAM_NOT_NULL_VOID(p_escs);
+ p_escs->conn_handle = p_ble_evt->evt.gap_evt.conn_handle;
+}
+
+
+/**@brief Function for handling the @ref BLE_GAP_EVT_DISCONNECTED event from the SoftDevice.
+ *
+ * @param[in] p_escs Eddystone Configuration Service structure.
+ * @param[in] p_ble_evt Pointer to the event received from BLE stack.
+ */
+static void on_disconnect(nrf_ble_escs_t * p_escs, ble_evt_t const * p_ble_evt)
+{
+ VERIFY_PARAM_NOT_NULL_VOID(p_escs);
+ UNUSED_PARAMETER(p_ble_evt);
+ p_escs->conn_handle = BLE_CONN_HANDLE_INVALID;
+}
+
+
+static uint32_t get_evt_type_for_handle(uint16_t handle, uint16_t * p_uuid)
+{
+ VERIFY_PARAM_NOT_NULL(p_uuid);
+
+ for (uint8_t i = 0; i < BLE_ESCS_NUMBER_OF_CHARACTERISTICS; ++i)
+ {
+ if (m_handle_to_uuid_map[i].val_handle == handle)
+ {
+ *p_uuid = m_handle_to_uuid_map[i].uuid;
+ return NRF_SUCCESS;
+ }
+ }
+
+ return NRF_ERROR_NOT_FOUND;
+}
+
+/**@brief Function for handling the @ref BLE_GATTS_EVT_RW_AUTHORIZE_REQUEST: BLE_GATTS_AUTHORIZE_TYPE_WRITE event from the SoftDevice.
+ *
+ * @param[in] p_escs Eddystone Configuration Service structure.
+ * @param[in] p_ble_evt Pointer to the event received from BLE stack.
+ */
+static ret_code_t on_write(nrf_ble_escs_t * p_escs, ble_evt_t const * p_ble_evt)
+{
+ uint32_t err_code;
+ uint16_t write_evt_uuid = 0;
+
+ VERIFY_PARAM_NOT_NULL(p_escs);
+ VERIFY_PARAM_NOT_NULL(p_ble_evt);
+
+ ble_gatts_evt_write_t const * p_evt_write =
+ &p_ble_evt->evt.gatts_evt.params.authorize_request.request.write;
+
+ err_code = get_evt_type_for_handle(p_evt_write->handle, &write_evt_uuid);
+ RETURN_IF_ERROR(err_code);
+
+ p_escs->write_evt_handler(p_escs,
+ write_evt_uuid,
+ p_evt_write->handle,
+ p_evt_write->data,
+ p_evt_write->len);
+
+ return NRF_SUCCESS;
+}
+
+
+/**@brief Function for handling the @ref BLE_GATTS_EVT_RW_AUTHORIZE_REQUEST: BLE_GATTS_AUTHORIZE_TYPE_WRITE: event from the SoftDevice.
+ *
+ * @param[in] p_escs Eddystone Configuration Service structure.
+ * @param[in] p_ble_evt Pointer to the event received from BLE stack.
+ */
+static void on_long_write(nrf_ble_escs_t * p_escs, ble_evt_t const * p_ble_evt)
+{
+ static uint16_t write_evt_uuid;
+ static bool write_evt_uuid_set = false;
+ uint32_t err_code;
+
+ VERIFY_PARAM_NOT_NULL_VOID(p_escs);
+ VERIFY_PARAM_NOT_NULL_VOID(p_ble_evt);
+
+ ble_gatts_evt_write_t const * p_evt_write =
+ &p_ble_evt->evt.gatts_evt.params.authorize_request.request.write;
+
+ ble_gatts_rw_authorize_reply_params_t reply = {0};
+
+ if (p_evt_write->op == BLE_GATTS_OP_PREP_WRITE_REQ)
+ {
+ err_code = get_evt_type_for_handle(p_evt_write->handle, &write_evt_uuid);
+ APP_ERROR_CHECK(err_code);
+
+ write_evt_uuid_set = true;
+
+ reply.type = BLE_GATTS_AUTHORIZE_TYPE_WRITE;
+ reply.params.write.gatt_status = BLE_GATT_STATUS_SUCCESS;
+ reply.params.write.update = 0;
+ reply.params.write.offset = 0;
+ reply.params.write.len = p_evt_write->len;
+ reply.params.write.p_data = NULL;
+
+ err_code = sd_ble_gatts_rw_authorize_reply(p_escs->conn_handle, &reply);
+ APP_ERROR_CHECK(err_code);
+ }
+
+ else if (p_evt_write->op == BLE_GATTS_OP_EXEC_WRITE_REQ_NOW)
+ {
+ uint8_t value_buffer[ESCS_ADV_SLOT_CHAR_LENGTH_MAX] = {0};
+ ble_gatts_value_t value =
+ {
+ .len = sizeof(value_buffer),
+ .offset = 0,
+ .p_value = &(value_buffer[0])
+ };
+
+ ASSERT(write_evt_uuid_set);
+ write_evt_uuid_set = false;
+
+ reply.type = BLE_GATTS_AUTHORIZE_TYPE_WRITE;
+ reply.params.write.gatt_status = BLE_GATT_STATUS_SUCCESS;
+ reply.params.write.update = 0;
+ reply.params.write.offset = 0;
+ reply.params.write.len = p_evt_write->len;
+ reply.params.write.p_data = NULL;
+
+ err_code = sd_ble_gatts_rw_authorize_reply(p_escs->conn_handle, &reply);
+ APP_ERROR_CHECK(err_code);
+
+ // Now that the value has been accepted using 'sd_ble_gatts_rw_authorize_reply', it can be found in the database.
+ err_code = sd_ble_gatts_value_get( p_escs->conn_handle,
+ p_escs->rw_adv_slot_handles.value_handle,
+ &value);
+ APP_ERROR_CHECK(err_code);
+
+ p_escs->write_evt_handler(p_escs,
+ write_evt_uuid,
+ p_evt_write->handle,
+ value.p_value,
+ value.len);
+ }
+ else
+ {
+ }
+}
+
+
+/**@brief Function for handling events from the SoftDevice related to long writes.
+ *
+ * @param[in] p_escs Eddystone Configuration Service structure.
+ * @param[in] p_ble_evt Pointer to the event received from BLE stack.
+ */
+static ret_code_t on_read(nrf_ble_escs_t * p_escs, ble_evt_t const * p_ble_evt)
+{
+ VERIFY_PARAM_NOT_NULL(p_escs);
+ VERIFY_PARAM_NOT_NULL(p_ble_evt);
+ ret_code_t err_code;
+ uint16_t read_evt_uuid = 0;
+ uint16_t val_handle = p_ble_evt->evt.gatts_evt.params.authorize_request.request.read.handle;
+ err_code = get_evt_type_for_handle(val_handle, &read_evt_uuid);
+ RETURN_IF_ERROR(err_code);
+
+ p_escs->read_evt_handler(p_escs, read_evt_uuid, val_handle);
+
+ return NRF_SUCCESS;
+}
+
+
+static ret_code_t on_rw_authorize_req(nrf_ble_escs_t * p_escs, ble_evt_t const * p_ble_evt)
+{
+ ret_code_t err_code;
+ VERIFY_PARAM_NOT_NULL(p_escs);
+ VERIFY_PARAM_NOT_NULL(p_ble_evt);
+
+ ble_gatts_evt_rw_authorize_request_t const * ar =
+ &p_ble_evt->evt.gatts_evt.params.authorize_request;
+
+ if (ar->type == BLE_GATTS_AUTHORIZE_TYPE_READ)
+ {
+ err_code = on_read(p_escs, p_ble_evt);
+ RETURN_IF_ERROR(err_code);
+ }
+ else if (ar->type == BLE_GATTS_AUTHORIZE_TYPE_WRITE)
+ {
+ if (ar->request.write.op == BLE_GATTS_OP_WRITE_REQ
+ || ar->request.write.op == BLE_GATTS_OP_WRITE_CMD)
+ {
+ err_code = on_write(p_escs, p_ble_evt);
+ RETURN_IF_ERROR(err_code);
+ }
+
+ else if (ar->request.write.op == BLE_GATTS_OP_PREP_WRITE_REQ
+ || ar->request.write.op == BLE_GATTS_OP_EXEC_WRITE_REQ_NOW)
+ {
+ on_long_write(p_escs, p_ble_evt);
+ }
+ else if (ar->request.write.op == BLE_GATTS_OP_EXEC_WRITE_REQ_CANCEL)
+ {
+ ble_gatts_rw_authorize_reply_params_t auth_reply;
+ memset(&auth_reply, 0, sizeof(auth_reply));
+
+ auth_reply.type = BLE_GATTS_AUTHORIZE_TYPE_WRITE;
+ auth_reply.params.write.gatt_status = BLE_GATT_STATUS_SUCCESS;
+
+ err_code = sd_ble_gatts_rw_authorize_reply(p_ble_evt->evt.gatts_evt.conn_handle, &auth_reply);
+ VERIFY_SUCCESS(err_code);
+ }
+ else
+ {
+ }
+ }
+ else
+ {
+ return NRF_ERROR_INVALID_STATE;
+ }
+
+ return NRF_SUCCESS;
+}
+
+
+
+ret_code_t nrf_ble_escs_on_ble_evt(nrf_ble_escs_t * p_escs, ble_evt_t const * p_ble_evt)
+{
+ ret_code_t err_code;
+
+ VERIFY_PARAM_NOT_NULL(p_escs);
+ VERIFY_PARAM_NOT_NULL(p_ble_evt);
+
+ switch (p_ble_evt->header.evt_id)
+ {
+ case BLE_GAP_EVT_CONNECTED:
+ on_connect(p_escs, p_ble_evt);
+
+ break;
+
+ case BLE_GAP_EVT_DISCONNECTED:
+ on_disconnect(p_escs, p_ble_evt);
+ break;
+
+ case BLE_GATTS_EVT_RW_AUTHORIZE_REQUEST:
+ err_code = on_rw_authorize_req(p_escs, p_ble_evt);
+ VERIFY_SUCCESS(err_code);
+ break;
+
+ // BLE_EVT_USER_MEM_REQUEST & BLE_EVT_USER_MEM_RELEASE are for long writes to the RW ADV slot characteristic
+ case BLE_EVT_USER_MEM_REQUEST:
+ err_code = sd_ble_user_mem_reply(p_escs->conn_handle, &m_eid_mem_block);
+ VERIFY_SUCCESS(err_code);
+ break;
+
+ case BLE_EVT_USER_MEM_RELEASE:
+ break;
+
+ default:
+ // No implementation needed.
+ break;
+ }
+
+ return NRF_SUCCESS;
+}
+
+
+ret_code_t nrf_ble_escs_init(nrf_ble_escs_t * p_escs, const nrf_ble_escs_init_t * p_escs_init)
+{
+ uint32_t err_code;
+ ble_uuid_t ble_uuid;
+ ble_uuid128_t ecs_base_uuid = ESCS_BASE_UUID;
+ uint8_t zero_val = 0;
+
+ VERIFY_PARAM_NOT_NULL(p_escs);
+ VERIFY_PARAM_NOT_NULL(p_escs_init);
+
+ // Initialize the service structure.
+ p_escs->conn_handle = BLE_CONN_HANDLE_INVALID;
+ p_escs->write_evt_handler = p_escs_init->write_evt_handler;
+ p_escs->read_evt_handler = p_escs_init->read_evt_handler;
+
+ // Add a custom base UUID.
+ err_code = sd_ble_uuid_vs_add(&ecs_base_uuid, &p_escs->uuid_type);
+ VERIFY_SUCCESS(err_code);
+
+ ble_uuid.type = p_escs->uuid_type;
+ ble_uuid.uuid = BLE_UUID_ESCS_SERVICE;
+
+ // Add the service.
+ err_code = sd_ble_gatts_service_add(BLE_GATTS_SRVC_TYPE_PRIMARY,
+ &ble_uuid,
+ &p_escs->service_handle);
+ VERIFY_SUCCESS(err_code);
+
+ m_handle_to_uuid_map_idx = 0;
+
+ // Set up initial values for characteristics
+
+ // Eddystone spec requires big endian
+ nrf_ble_escs_broadcast_cap_t temp = p_escs_init->p_init_vals->broadcast_cap;
+ temp.supp_frame_types = BYTES_SWAP_16BIT(temp.supp_frame_types);
+
+ nrf_ble_escs_adv_interval_t temp_interval = p_escs_init->p_init_vals->adv_interval;
+ temp_interval = BYTES_SWAP_16BIT(temp_interval);
+
+ // Adding chracteristics
+
+ err_code = char_add(&BROADCAST_CAP_CHAR_INIT, p_escs,
+ &temp, &p_escs->broadcast_cap_handles);
+ VERIFY_SUCCESS(err_code);
+
+ err_code = char_add(&ACTIVE_SLOT_CHAR_INIT, p_escs,
+ p_escs->p_active_slot, &p_escs->active_slot_handles);
+ VERIFY_SUCCESS(err_code);
+
+ err_code = char_add(&ADV_INTERVAL_CHAR_INIT, p_escs,
+ &temp_interval, &p_escs->adv_interval_handles);
+ VERIFY_SUCCESS(err_code);
+
+ err_code = char_add(&RADIO_TX_PWR_CHAR_INIT, p_escs,
+ &(p_escs_init->p_init_vals->radio_tx_pwr), &p_escs->radio_tx_pwr_handles);
+ VERIFY_SUCCESS(err_code);
+
+ err_code = char_add(&ADV_TX_PWR_CHAR_INIT, p_escs,
+ &(p_escs_init->p_init_vals->adv_tx_pwr), &p_escs->adv_tx_pwr_handles);
+ VERIFY_SUCCESS(err_code);
+
+ err_code = char_add(&LOCK_STATE_CHAR_INIT, p_escs,
+ p_escs->p_lock_state, &p_escs->lock_state_handles);
+ VERIFY_SUCCESS(err_code);
+
+ err_code = char_add(&UNLOCK_CHAR_INIT, p_escs,
+ &zero_val, &p_escs->unlock_handles);
+ VERIFY_SUCCESS(err_code);
+
+ err_code = char_add(&PUBLIC_ECDH_KEY_CHAR_INIT, p_escs,
+ &zero_val, &p_escs->pub_ecdh_key_handles);
+ VERIFY_SUCCESS(err_code);
+
+ err_code = char_add(&EID_ID_KEY_CHAR_INIT, p_escs,
+ &zero_val, &p_escs->eid_id_key_handles);
+ VERIFY_SUCCESS(err_code);
+
+ err_code = char_add(&RW_ADV_SLOT_CHAR_INIT, p_escs,
+ &zero_val, &p_escs->rw_adv_slot_handles);
+ VERIFY_SUCCESS(err_code);
+
+ err_code = char_add(&FACTORY_RESET_CHAR_INIT, p_escs,
+ &(p_escs_init->p_init_vals->factory_reset), &p_escs->factory_reset_handles);
+ VERIFY_SUCCESS(err_code);
+
+ err_code = char_add(&REMAIN_CONNECTABLE_CHAR_INIT, p_escs,
+ &(p_escs_init->p_init_vals->remain_connectable.r_is_non_connectable_supported),
+ &p_escs->remain_connectable_handles);
+ VERIFY_SUCCESS(err_code);
+
+ return NRF_SUCCESS;
+}
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/ble_escs/nrf_ble_escs.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/ble_escs/nrf_ble_escs.h
new file mode 100644
index 0000000..77bb5ae
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/ble_escs/nrf_ble_escs.h
@@ -0,0 +1,259 @@
+/**
+ * Copyright (c) 2016 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#ifndef NRF_BLE_ESCS_H__
+#define NRF_BLE_ESCS_H__
+
+#include "ble.h"
+#include "ble_srv_common.h"
+#include "app_util_platform.h"
+#include "sdk_common.h"
+#include "escs_defs.h"
+#include <stdint.h>
+#include <stdbool.h>
+
+
+/**
+ * @file
+ * @defgroup nrf_ble_escs Eddystone Configuration Service
+ * @brief Eddystone Configuration Service module.
+ * @ingroup ble_sdk_srv
+ * @{
+ */
+
+#define BLE_ESCS_NUMBER_OF_CHARACTERISTICS 13 //!< Number of characteristics contained in the Eddystone Configuration Service.
+
+#define BLE_UUID_ESCS_SERVICE 0x7500 //!< UUID of the Eddystone Configuration Service.
+
+// ECS UUIDs
+#define BLE_UUID_ESCS_BROADCAST_CAP_CHAR 0x7501
+#define BLE_UUID_ESCS_ACTIVE_SLOT_CHAR 0x7502
+#define BLE_UUID_ESCS_ADV_INTERVAL_CHAR 0x7503
+#define BLE_UUID_ESCS_RADIO_TX_PWR_CHAR 0x7504
+#define BLE_UUID_ESCS_ADV_TX_PWR_CHAR 0x7505
+#define BLE_UUID_ESCS_LOCK_STATE_CHAR 0x7506
+#define BLE_UUID_ESCS_UNLOCK_CHAR 0x7507
+#define BLE_UUID_ESCS_PUBLIC_ECDH_KEY_CHAR 0x7508
+#define BLE_UUID_ESCS_EID_ID_KEY_CHAR 0x7509
+#define BLE_UUID_ESCS_RW_ADV_SLOT_CHAR 0x750A
+#define BLE_UUID_ESCS_FACTORY_RESET_CHAR 0x750B
+#define BLE_UUID_ESCS_REMAIN_CONNECTABLE_CHAR 0x750C
+
+#define ESCS_BASE_UUID \
+ {{0x95, 0xE2, 0xED, 0xEB, 0x1B, 0xA0, 0x39, 0x8A, 0xDF, 0x4B, 0xD3, 0x8E, 0x00, 0x00, 0xC8, \
+ 0xA3}}
+// A3C8XXXX-8ED3-4BDF-8A39-A01BEBEDE295
+
+#define NRF_BLE_ESCS_BROADCAST_CAP_LEN (ESCS_NUM_OF_SUPPORTED_TX_POWER + 6) // According to the eddystone spec, there are 6 bytes of data in addition to the supported_radio_tx_power array
+
+
+/**@brief Data fields in the Broadcast Capabilities characteristic.
+ * @note This is a packed structure. Therefore, you should not change it.
+ */
+typedef PACKED_STRUCT
+{
+ int8_t vers_byte;
+ int8_t max_supp_total_slots;
+ int8_t max_supp_eid_slots;
+ int8_t cap_bitfield;
+ int16_t supp_frame_types;
+ int8_t supp_radio_tx_power[ESCS_NUM_OF_SUPPORTED_TX_POWER];
+} nrf_ble_escs_broadcast_cap_t;
+
+typedef uint8_t nrf_ble_escs_active_slot_t;
+typedef uint16_t nrf_ble_escs_adv_interval_t;
+typedef int8_t nrf_ble_escs_radio_tx_pwr_t;
+typedef int8_t nrf_ble_escs_adv_tx_pwr_t;
+
+/**@brief Read states of the Lock State characteristic. */
+typedef enum
+{
+ NRF_BLE_ESCS_LOCK_STATE_LOCKED = ESCS_LOCK_STATE_LOCKED,
+ NRF_BLE_ESCS_LOCK_STATE_UNLOCKED = ESCS_LOCK_STATE_UNLOCKED,
+ NRF_BLE_ESCS_LOCK_STATE_UNLOCKED_AUTO_RELOCK_DISABLED =
+ ESCS_LOCK_STATE_UNLOCKED_AUTO_RELOCK_DISABLED
+} nrf_ble_escs_lock_state_read_t;
+
+/**@brief Write bytes of the Lock State characteristic. */
+typedef enum
+{
+ NRF_BLE_ESCS_LOCK_BYTE_LOCK = ESCS_LOCK_BYTE_LOCK,
+ NRF_BLE_ESCS_LOCK_BYTE_DISABLE_AUTO_RELOCK = ESCS_LOCK_BYTE_DISABLE_AUTO_RELOCK
+} nrf_ble_escs_lock_byte_t;
+
+/**@brief Write data fields of the Lock State characteristic.
+ * @note This is a packed structure. Therefore, you should not change it.
+*/
+typedef PACKED_STRUCT
+{
+ nrf_ble_escs_lock_byte_t lock_byte;
+ int8_t encrypted_key[ESCS_AES_KEY_SIZE];
+} nrf_ble_escs_lock_state_write_t;
+
+/**@brief Lock State characteristic. */
+typedef union
+{
+ nrf_ble_escs_lock_state_read_t read;
+ nrf_ble_escs_lock_state_write_t write;
+} nrf_ble_escs_lock_state_t;
+
+/**@brief Unlock characteristic (read/write). */
+typedef union
+{
+ int8_t r_challenge[ESCS_AES_KEY_SIZE];
+ int8_t w_unlock_token[ESCS_AES_KEY_SIZE];
+} nrf_ble_escs_unlock_t;
+
+/**@brief Public ECDH Key characteristic.
+ * @note This is a packed structure. Therefore, you should not change it.
+*/
+typedef PACKED_STRUCT
+{
+ int8_t key[ESCS_ECDH_KEY_SIZE];
+} nrf_ble_escs_public_ecdh_key_t;
+
+/**@brief EID Identity Key characteristic.
+ * @note This is a packed structure. Therefore, you should not change it.
+*/
+typedef PACKED_STRUCT
+{
+ int8_t key[ESCS_AES_KEY_SIZE];
+} nrf_ble_escs_eid_id_key_t;
+
+
+typedef uint8_t nrf_ble_escs_factory_reset_t;
+
+/**@brief Unlock characteristic (read/write). */
+typedef union
+{
+ uint8_t r_is_non_connectable_supported;
+ uint8_t w_remain_connectable_boolean;
+} nrf_ble_escs_remain_conntbl_t;
+
+/**@brief Eddystone Configuration Service initialization parameters (corresponding to required characteristics). */
+typedef struct
+{
+ nrf_ble_escs_broadcast_cap_t broadcast_cap;
+ nrf_ble_escs_adv_interval_t adv_interval;
+ nrf_ble_escs_radio_tx_pwr_t radio_tx_pwr;
+ nrf_ble_escs_adv_tx_pwr_t adv_tx_pwr;
+ nrf_ble_escs_factory_reset_t factory_reset;
+ nrf_ble_escs_remain_conntbl_t remain_connectable;
+} nrf_ble_escs_init_params_t;
+
+// Forward Declaration of nrf_ble_escs_t type.
+typedef struct nrf_ble_escs_s nrf_ble_escs_t;
+
+typedef void (*nrf_ble_escs_write_evt_handler_t)(nrf_ble_escs_t * p_escs,
+ uint16_t uuid,
+ uint16_t value_handle,
+ uint8_t const * p_data,
+ uint16_t length);
+
+typedef void (*nrf_ble_escs_read_evt_handler_t)(nrf_ble_escs_t * p_escs,
+ uint16_t uuid,
+ uint16_t value_handle);
+
+/**@brief Eddystone Configuration Service initialization structure.
+ *
+ * @details This structure contains the initialization information for the service. The application
+ * must fill this structure and pass it to the service using the @ref nrf_ble_escs_init
+ * function.
+ */
+typedef struct
+{
+ nrf_ble_escs_init_params_t * p_init_vals; //!< Initialization parameters for the service.
+ nrf_ble_escs_write_evt_handler_t write_evt_handler; //!< Event handler to be called for authorizing write requests.
+ nrf_ble_escs_read_evt_handler_t read_evt_handler; //!< Event handler to be called for authorizing read requests.
+} nrf_ble_escs_init_t;
+
+struct nrf_ble_escs_s
+{
+ uint8_t uuid_type; //!< UUID type for the Eddystone Configuration Service Base UUID.
+ uint16_t service_handle; //!< Handle of the Eddystone Configuration Service (as provided by the SoftDevice).
+ ble_gatts_char_handles_t broadcast_cap_handles; //!< Handles related to the Capabilities characteristic (as provided by the SoftDevice).
+ ble_gatts_char_handles_t active_slot_handles; //!< Handles related to the Active Slot characteristic (as provided by the SoftDevice).
+ ble_gatts_char_handles_t adv_interval_handles; //!< Handles related to the Advertising Interval characteristic (as provided by the SoftDevice).
+ ble_gatts_char_handles_t radio_tx_pwr_handles; //!< Handles related to the Radio Tx Power characteristic (as provided by the SoftDevice).
+ ble_gatts_char_handles_t adv_tx_pwr_handles; //!< Handles related to the (Advanced) Advertised Tx Power characteristic (as provided by the SoftDevice).
+ ble_gatts_char_handles_t lock_state_handles; //!< Handles related to the Lock State characteristic (as provided by the SoftDevice).
+ ble_gatts_char_handles_t unlock_handles; //!< Handles related to the Unlock characteristic (as provided by the SoftDevice).
+ ble_gatts_char_handles_t pub_ecdh_key_handles; //!< Handles related to the Public ECDH Key characteristic (as provided by the SoftDevice).
+ ble_gatts_char_handles_t eid_id_key_handles; //!< Handles related to the EID Identity Key characteristic (as provided by the SoftDevice).
+ ble_gatts_char_handles_t rw_adv_slot_handles; //!< Handles related to the ADV Slot Data characteristic (as provided by the SoftDevice).
+ ble_gatts_char_handles_t factory_reset_handles; //!< Handles related to the (Advanced) Factory reset characteristic (as provided by the SoftDevice).
+ ble_gatts_char_handles_t remain_connectable_handles; //!< Handles related to the (Advanced) Remain Connectable characteristic (as provided by the SoftDevice).
+ uint16_t conn_handle; //!< Handle of the current connection (as provided by the SoftDevice). @ref BLE_CONN_HANDLE_INVALID if not in a connection.
+ nrf_ble_escs_write_evt_handler_t write_evt_handler; //!< Event handler to be called for handling write attempts.
+ nrf_ble_escs_read_evt_handler_t read_evt_handler; //!< Event handler to be called for handling read attempts.
+ uint8_t * p_active_slot;
+ nrf_ble_escs_lock_state_read_t * p_lock_state;
+};
+
+
+/**@brief Function for initializing the Eddystone Configuration Service.
+ *
+ * @param[out] p_escs Eddystone Configuration Service structure. This structure must be supplied
+ * by the application. It is initialized by this function and will
+ * later be used to identify this particular service instance.
+ * @param[in] p_ecs_init Information needed to initialize the service.
+ *
+ * @retval NRF_SUCCESS If the service was successfully initialized. Otherwise, an error code is returned.
+ * @retval NRF_ERROR_NULL If either of the pointers @p p_escs or @p p_ecs_init is NULL.
+ */
+ret_code_t nrf_ble_escs_init(nrf_ble_escs_t * p_escs, const nrf_ble_escs_init_t * p_ecs_init);
+
+/**@brief Function for handling the Eddystone Configuration Service's BLE events.
+ *
+ * @details The Eddystone Configuration Service expects the application to call this function each time an
+ * event is received from the SoftDevice. This function processes the event if it
+ * is relevant and calls the Eddystone Configuration Service event handler of the
+ * application if necessary.
+ *
+ * @param[in] p_escs Eddystone Configuration Service structure.
+ * @param[in] p_ble_evt Event received from the SoftDevice.
+ *
+ * @retval NRF_ERROR_NULL If any of the arguments given are NULL.
+ * @retval NRF_SUCCESS otherwise.
+ */
+ret_code_t nrf_ble_escs_on_ble_evt(nrf_ble_escs_t * p_escs, ble_evt_t const * p_ble_evt);
+
+/** @} */
+
+#endif // NRF_BLE_ESCS_H__
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/ble_gls/ble_gls.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/ble_gls/ble_gls.c
new file mode 100644
index 0000000..2fe5f70
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/ble_gls/ble_gls.c
@@ -0,0 +1,1314 @@
+/**
+ * Copyright (c) 2012 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+/* Attention!
+ * To maintain compliance with Nordic Semiconductor ASA's Bluetooth profile
+ * qualification listings, this section of source code must not be modified.
+ */
+
+#include "sdk_common.h"
+
+#if NRF_MODULE_ENABLED(BLE_GLS)
+
+#include "ble_gls.h"
+#include <string.h>
+#include "ble_gls_db.h"
+#include "ble_racp.h"
+#include "ble_srv_common.h"
+
+
+#define OPERAND_FILTER_TYPE_SEQ_NUM 0x01 /**< Filter data using Sequence Number criteria. */
+#define OPERAND_FILTER_TYPE_FACING_TIME 0x02 /**< Filter data using User Facing Time criteria. */
+#define OPERAND_FILTER_TYPE_RFU_START 0x07 /**< Start of filter types reserved For Future Use range */
+#define OPERAND_FILTER_TYPE_RFU_END 0xFF /**< End of filter types reserved For Future Use range */
+
+#define OPCODE_LENGTH 1 /**< Length of opcode inside Glucose Measurement packet. */
+#define HANDLE_LENGTH 2 /**< Length of handle inside Glucose Measurement packet. */
+#define MAX_GLM_LEN (BLE_GATT_ATT_MTU_DEFAULT - OPCODE_LENGTH - HANDLE_LENGTH) /**< Maximum size of a transmitted Glucose Measurement. */
+
+#define GLS_NACK_PROC_ALREADY_IN_PROGRESS BLE_GATT_STATUS_ATTERR_APP_BEGIN + 0 /**< Reply when a requested procedure is already in progress. */
+#define GLS_NACK_CCCD_IMPROPERLY_CONFIGURED BLE_GATT_STATUS_ATTERR_APP_BEGIN + 1 /**< Reply when the a s CCCD is improperly configured. */
+
+/**@brief Glucose Service communication state. */
+typedef enum
+{
+ STATE_NO_COMM, /**< The service is not in a communicating state. */
+ STATE_RACP_PROC_ACTIVE, /**< Processing requested data. */
+ STATE_RACP_RESPONSE_PENDING, /**< There is a RACP indication waiting to be sent. */
+ STATE_RACP_RESPONSE_IND_VERIF /**< Waiting for a verification of a RACP indication. */
+} gls_state_t;
+
+static gls_state_t m_gls_state; /**< Current communication state. */
+static uint16_t m_next_seq_num; /**< Sequence number of the next database record. */
+static uint8_t m_racp_proc_operator; /**< Operator of current request. */
+static uint16_t m_racp_proc_seq_num; /**< Sequence number of current request. */
+static uint8_t m_racp_proc_record_ndx; /**< Current record index. */
+static uint8_t m_racp_proc_records_reported; /**< Number of reported records. */
+static uint8_t m_racp_proc_records_reported_since_txcomplete; /**< Number of reported records since last TX_COMPLETE event. */
+static ble_racp_value_t m_pending_racp_response; /**< RACP response to be sent. */
+static uint8_t m_pending_racp_response_operand[2]; /**< Operand of RACP response to be sent. */
+
+
+/**@brief Function for setting the GLS communication state.
+ *
+ * @param[in] new_state New communication state.
+ */
+static void state_set(gls_state_t new_state)
+{
+ m_gls_state = new_state;
+}
+
+
+/**@brief Function for setting the next sequence number by reading the last record in the data base.
+ *
+ * @return NRF_SUCCESS on successful initialization of service, otherwise an error code.
+ */
+static uint32_t next_sequence_number_set(void)
+{
+ uint16_t num_records;
+ ble_gls_rec_t rec;
+
+ num_records = ble_gls_db_num_records_get();
+ if (num_records > 0)
+ {
+ // Get last record
+ uint32_t err_code = ble_gls_db_record_get(num_records - 1, &rec);
+ if (err_code != NRF_SUCCESS)
+ {
+ return err_code;
+ }
+ m_next_seq_num = rec.meas.sequence_number + 1;
+ }
+ else
+ {
+ m_next_seq_num = 0;
+ }
+
+ return NRF_SUCCESS;
+}
+
+
+/**@brief Function for encoding a Glucose measurement.
+ *
+ * @param[in] p_meas Measurement to be encoded.
+ * @param[out] p_encoded_buffer Pointer to buffer where the encoded measurement is to be stored.
+ *
+ * @return Size of encoded measurement.
+ */
+static uint8_t gls_meas_encode(const ble_gls_meas_t * p_meas, uint8_t * p_encoded_buffer)
+{
+ uint8_t len = 0;
+
+ p_encoded_buffer[len++] = p_meas->flags;
+
+ len += uint16_encode(p_meas->sequence_number, &p_encoded_buffer[len]);
+ len += ble_date_time_encode(&p_meas->base_time, &p_encoded_buffer[len]);
+
+ if (p_meas->flags & BLE_GLS_MEAS_FLAG_TIME_OFFSET)
+ {
+ len += uint16_encode(p_meas->time_offset, &p_encoded_buffer[len]);
+ }
+
+ if (p_meas->flags & BLE_GLS_MEAS_FLAG_CONC_TYPE_LOC)
+ {
+ uint16_t encoded_concentration;
+
+ encoded_concentration = ((p_meas->glucose_concentration.exponent << 12) & 0xF000) |
+ ((p_meas->glucose_concentration.mantissa << 0) & 0x0FFF);
+
+ p_encoded_buffer[len++] = (uint8_t)(encoded_concentration);
+ p_encoded_buffer[len++] = (uint8_t)(encoded_concentration >> 8);
+ p_encoded_buffer[len++] = (p_meas->sample_location << 4) | (p_meas->type & 0x0F);
+ }
+
+ if (p_meas->flags & BLE_GLS_MEAS_FLAG_SENSOR_STATUS)
+ {
+ len += uint16_encode(p_meas->sensor_status_annunciation, &p_encoded_buffer[len]);
+ }
+
+ return len;
+}
+
+
+/**@brief Function for adding the characteristic for a glucose measurement.
+ *
+ * @param[in] p_gls Service instance.
+ *
+ * @return NRF_SUCCESS if characteristic was successfully added, otherwise an error code.
+ */
+static uint32_t glucose_measurement_char_add(ble_gls_t * p_gls)
+{
+ ble_gatts_char_md_t char_md;
+ ble_gatts_attr_md_t cccd_md;
+ ble_gatts_attr_t attr_char_value;
+ ble_uuid_t ble_uuid;
+ ble_gatts_attr_md_t attr_md;
+ ble_gls_rec_t initial_gls_rec_value;
+ uint8_t encoded_gls_meas[MAX_GLM_LEN];
+ uint8_t num_recs;
+ memset(&cccd_md, 0, sizeof(cccd_md));
+
+ BLE_GAP_CONN_SEC_MODE_SET_OPEN(&cccd_md.read_perm);
+ BLE_GAP_CONN_SEC_MODE_SET_ENC_NO_MITM(&cccd_md.write_perm);
+ cccd_md.vloc = BLE_GATTS_VLOC_STACK;
+
+ memset(&char_md, 0, sizeof(char_md));
+
+ char_md.char_props.notify = 1;
+ char_md.p_char_user_desc = NULL;
+ char_md.p_char_pf = NULL;
+ char_md.p_user_desc_md = NULL;
+ char_md.p_cccd_md = &cccd_md;
+ char_md.p_sccd_md = NULL;
+
+ BLE_UUID_BLE_ASSIGN(ble_uuid, BLE_UUID_GLUCOSE_MEASUREMENT_CHAR);
+ memset(&attr_md, 0, sizeof(attr_md));
+
+ BLE_GAP_CONN_SEC_MODE_SET_NO_ACCESS(&attr_md.read_perm);
+ BLE_GAP_CONN_SEC_MODE_SET_NO_ACCESS(&attr_md.write_perm);
+
+ attr_md.vloc = BLE_GATTS_VLOC_STACK;
+ attr_md.rd_auth = 0;
+ attr_md.wr_auth = 0;
+ attr_md.vlen = 1;
+
+ memset(&attr_char_value, 0, sizeof(attr_char_value));
+ memset(&initial_gls_rec_value, 0, sizeof(initial_gls_rec_value));
+
+ num_recs = ble_gls_db_num_records_get();
+ if (num_recs > 0)
+ {
+ uint32_t err_code = ble_gls_db_record_get(num_recs - 1, &initial_gls_rec_value);
+ if (err_code != NRF_SUCCESS)
+ {
+ return err_code;
+ }
+ }
+
+ attr_char_value.p_uuid = &ble_uuid;
+ attr_char_value.p_attr_md = &attr_md;
+ attr_char_value.init_len = gls_meas_encode(&initial_gls_rec_value.meas, encoded_gls_meas);
+ attr_char_value.init_offs = 0;
+ attr_char_value.max_len = MAX_GLM_LEN;
+ attr_char_value.p_value = encoded_gls_meas;
+
+ return sd_ble_gatts_characteristic_add(p_gls->service_handle,
+ &char_md,
+ &attr_char_value,
+ &p_gls->glm_handles);
+}
+
+
+/**@brief Function for adding the characteristic for a glucose feature.
+ *
+ * @param[in] p_gls Service instance.
+ *
+ * @return NRF_SUCCESS if characteristic was successfully added, otherwise an error code.
+ */
+static uint32_t glucose_feature_char_add(ble_gls_t * p_gls)
+{
+ ble_gatts_char_md_t char_md;
+ ble_gatts_attr_t attr_char_value;
+ ble_uuid_t ble_uuid;
+ ble_gatts_attr_md_t attr_md;
+ uint8_t encoded_initial_feature[2];
+
+ memset(&char_md, 0, sizeof(char_md));
+
+ char_md.char_props.read = 1;
+ char_md.p_char_user_desc = NULL;
+ char_md.p_char_pf = NULL;
+ char_md.p_user_desc_md = NULL;
+ char_md.p_cccd_md = NULL;
+ char_md.p_sccd_md = NULL;
+
+ BLE_UUID_BLE_ASSIGN(ble_uuid, BLE_UUID_GLUCOSE_FEATURE_CHAR);
+
+ memset(&attr_md, 0, sizeof(attr_md));
+
+ BLE_GAP_CONN_SEC_MODE_SET_ENC_NO_MITM(&attr_md.read_perm);
+ BLE_GAP_CONN_SEC_MODE_SET_NO_ACCESS(&attr_md.write_perm);
+
+ attr_md.vloc = BLE_GATTS_VLOC_STACK;
+ attr_md.rd_auth = 0;
+ attr_md.wr_auth = 0;
+ attr_md.vlen = 0;
+
+ memset(&attr_char_value, 0, sizeof(attr_char_value));
+
+ encoded_initial_feature[0] = (uint8_t)(p_gls->feature);
+ encoded_initial_feature[1] = (uint8_t)((p_gls->feature) >> 8);
+
+ attr_char_value.p_uuid = &ble_uuid;
+ attr_char_value.p_attr_md = &attr_md;
+ attr_char_value.init_len = sizeof (uint16_t);
+ attr_char_value.init_offs = 0;
+ attr_char_value.max_len = sizeof (uint16_t);
+ attr_char_value.p_value = encoded_initial_feature;
+
+ return sd_ble_gatts_characteristic_add(p_gls->service_handle,
+ &char_md,
+ &attr_char_value,
+ &p_gls->glf_handles);
+}
+
+
+/**@brief Function for adding the characteristic for a record access control point.
+ *
+ * @param[in] p_gls Service instance.
+ *
+ * @return NRF_SUCCESS if characteristic was successfully added, otherwise an error code.
+ */
+static uint32_t record_access_control_point_char_add(ble_gls_t * p_gls)
+{
+ ble_gatts_char_md_t char_md;
+ ble_gatts_attr_md_t cccd_md;
+ ble_gatts_attr_t attr_char_value;
+ ble_uuid_t ble_uuid;
+ ble_gatts_attr_md_t attr_md;
+
+ memset(&cccd_md, 0, sizeof(cccd_md));
+
+ BLE_GAP_CONN_SEC_MODE_SET_OPEN(&cccd_md.read_perm);
+ BLE_GAP_CONN_SEC_MODE_SET_ENC_NO_MITM(&cccd_md.write_perm);
+ cccd_md.vloc = BLE_GATTS_VLOC_STACK;
+
+ memset(&char_md, 0, sizeof(char_md));
+
+ char_md.char_props.indicate = 1;
+ char_md.char_props.write = 1;
+ char_md.p_char_user_desc = NULL;
+ char_md.p_char_pf = NULL;
+ char_md.p_user_desc_md = NULL;
+ char_md.p_cccd_md = &cccd_md;
+ char_md.p_sccd_md = NULL;
+
+ BLE_UUID_BLE_ASSIGN(ble_uuid, BLE_UUID_RECORD_ACCESS_CONTROL_POINT_CHAR);
+
+ memset(&attr_md, 0, sizeof(attr_md));
+
+ BLE_GAP_CONN_SEC_MODE_SET_NO_ACCESS(&attr_md.read_perm);
+ BLE_GAP_CONN_SEC_MODE_SET_ENC_NO_MITM(&attr_md.write_perm);
+
+ attr_md.vloc = BLE_GATTS_VLOC_STACK;
+ attr_md.rd_auth = 0;
+ attr_md.wr_auth = 1;
+ attr_md.vlen = 1;
+
+ memset(&attr_char_value, 0, sizeof(attr_char_value));
+
+ attr_char_value.p_uuid = &ble_uuid;
+ attr_char_value.p_attr_md = &attr_md;
+ attr_char_value.init_len = 0;
+ attr_char_value.init_offs = 0;
+ attr_char_value.max_len = BLE_GATT_ATT_MTU_DEFAULT;
+ attr_char_value.p_value = 0;
+
+ return sd_ble_gatts_characteristic_add(p_gls->service_handle,
+ &char_md,
+ &attr_char_value,
+ &p_gls->racp_handles);
+}
+
+
+uint32_t ble_gls_init(ble_gls_t * p_gls, const ble_gls_init_t * p_gls_init)
+{
+ uint32_t err_code;
+ ble_uuid_t ble_uuid;
+
+ // Initialize data base
+ err_code = ble_gls_db_init();
+ if (err_code != NRF_SUCCESS)
+ {
+ return err_code;
+ }
+
+ err_code = next_sequence_number_set();
+ if (err_code != NRF_SUCCESS)
+ {
+ return err_code;
+ }
+
+ // Initialize service structure
+ p_gls->evt_handler = p_gls_init->evt_handler;
+ p_gls->error_handler = p_gls_init->error_handler;
+ p_gls->feature = p_gls_init->feature;
+ p_gls->is_context_supported = p_gls_init->is_context_supported;
+ p_gls->conn_handle = BLE_CONN_HANDLE_INVALID;
+
+
+ // Initialize global variables
+ state_set(STATE_NO_COMM);
+ m_racp_proc_records_reported_since_txcomplete = 0;
+
+ // Add service
+ BLE_UUID_BLE_ASSIGN(ble_uuid, BLE_UUID_GLUCOSE_SERVICE);
+
+ err_code = sd_ble_gatts_service_add(BLE_GATTS_SRVC_TYPE_PRIMARY, &ble_uuid, &p_gls->service_handle);
+ if (err_code != NRF_SUCCESS)
+ {
+ return err_code;
+ }
+
+ // Add glucose measurement characteristic
+ err_code = glucose_measurement_char_add(p_gls);
+ if (err_code != NRF_SUCCESS)
+ {
+ return err_code;
+ }
+
+ // Add glucose measurement feature characteristic
+ err_code = glucose_feature_char_add(p_gls);
+ if (err_code != NRF_SUCCESS)
+ {
+ return err_code;
+ }
+
+ // Add record control access point characteristic
+ err_code = record_access_control_point_char_add(p_gls);
+ if (err_code != NRF_SUCCESS)
+ {
+ return err_code;
+ }
+
+ return NRF_SUCCESS;
+}
+
+
+/**@brief Function for sending a response from the Record Access Control Point.
+ *
+ * @param[in] p_gls Service instance.
+ * @param[in] p_racp_val RACP value to be sent.
+ */
+static void racp_send(ble_gls_t * p_gls, ble_racp_value_t * p_racp_val)
+{
+ uint32_t err_code;
+ uint8_t encoded_resp[25];
+ uint8_t len;
+ uint16_t hvx_len;
+ ble_gatts_hvx_params_t hvx_params;
+
+ if (
+ (m_gls_state != STATE_RACP_RESPONSE_PENDING)
+ &&
+ (m_racp_proc_records_reported_since_txcomplete > 0)
+ )
+ {
+ state_set(STATE_RACP_RESPONSE_PENDING);
+ return;
+ }
+
+ // Send indication
+ len = ble_racp_encode(p_racp_val, encoded_resp);
+ hvx_len = len;
+
+ memset(&hvx_params, 0, sizeof(hvx_params));
+
+ hvx_params.handle = p_gls->racp_handles.value_handle;
+ hvx_params.type = BLE_GATT_HVX_INDICATION;
+ hvx_params.offset = 0;
+ hvx_params.p_len = &hvx_len;
+ hvx_params.p_data = encoded_resp;
+
+ err_code = sd_ble_gatts_hvx(p_gls->conn_handle, &hvx_params);
+
+ // Error handling
+ if ((err_code == NRF_SUCCESS) && (hvx_len != len))
+ {
+ err_code = NRF_ERROR_DATA_SIZE;
+ }
+ switch (err_code)
+ {
+ case NRF_SUCCESS:
+ // Wait for HVC event
+ state_set(STATE_RACP_RESPONSE_IND_VERIF);
+ break;
+
+ case NRF_ERROR_BUSY:
+ // Wait for BLE_GATTS_EVT_HVC event to retry transmission
+ state_set(STATE_RACP_RESPONSE_PENDING);
+ break;
+
+ case NRF_ERROR_INVALID_STATE:
+ // Make sure state machine returns to the default state
+ state_set(STATE_NO_COMM);
+ break;
+
+ default:
+ // Report error to application
+ if (p_gls->error_handler != NULL)
+ {
+ p_gls->error_handler(err_code);
+ }
+
+ // Make sure state machine returns to the default state
+ state_set(STATE_NO_COMM);
+ break;
+ }
+}
+
+
+/**@brief Function for sending a RACP response containing a Response Code Op Code and a Response Code Value.
+ *
+ * @param[in] p_gls Service instance.
+ * @param[in] opcode RACP Op Code.
+ * @param[in] value RACP Response Code Value.
+ */
+static void racp_response_code_send(ble_gls_t * p_gls, uint8_t opcode, uint8_t value)
+{
+ m_pending_racp_response.opcode = RACP_OPCODE_RESPONSE_CODE;
+ m_pending_racp_response.operator = RACP_OPERATOR_NULL;
+ m_pending_racp_response.operand_len = 2;
+ m_pending_racp_response.p_operand = m_pending_racp_response_operand;
+
+ m_pending_racp_response_operand[0] = opcode;
+ m_pending_racp_response_operand[1] = value;
+
+ racp_send(p_gls, &m_pending_racp_response);
+}
+
+
+/**@brief Function for sending a glucose measurement/context.
+ *
+ * @param[in] p_gls Service instance.
+ * @param[in] p_rec Measurement to be sent.
+ *
+ * @return NRF_SUCCESS on success, otherwise an error code.
+ */
+static uint32_t glucose_meas_send(ble_gls_t * p_gls, ble_gls_rec_t * p_rec)
+{
+ uint32_t err_code;
+ uint8_t encoded_glm[MAX_GLM_LEN];
+ uint16_t len;
+ uint16_t hvx_len;
+ ble_gatts_hvx_params_t hvx_params;
+
+ len = gls_meas_encode(&p_rec->meas, encoded_glm);
+ hvx_len = len;
+
+ memset(&hvx_params, 0, sizeof (hvx_params));
+
+ hvx_params.handle = p_gls->glm_handles.value_handle;
+ hvx_params.type = BLE_GATT_HVX_NOTIFICATION;
+ hvx_params.offset = 0;
+ hvx_params.p_len = &hvx_len;
+ hvx_params.p_data = encoded_glm;
+
+ err_code = sd_ble_gatts_hvx(p_gls->conn_handle, &hvx_params);
+ if (err_code == NRF_SUCCESS)
+ {
+ if (hvx_len != len)
+ {
+ err_code = NRF_ERROR_DATA_SIZE;
+ }
+ else
+ {
+ // Measurement successfully sent
+ m_racp_proc_records_reported++;
+ m_racp_proc_records_reported_since_txcomplete++;
+ }
+ }
+
+ return err_code;
+}
+
+
+/**@brief Function for responding to the ALL operation.
+ *
+ * @param[in] p_gls Service instance.
+ *
+ * @return NRF_SUCCESS on success, otherwise an error code.
+ */
+static uint32_t racp_report_records_all(ble_gls_t * p_gls)
+{
+ uint16_t total_records = ble_gls_db_num_records_get();
+
+ if (m_racp_proc_record_ndx >= total_records)
+ {
+ state_set(STATE_NO_COMM);
+ }
+ else
+ {
+ uint32_t err_code;
+ ble_gls_rec_t rec;
+
+ err_code = ble_gls_db_record_get(m_racp_proc_record_ndx, &rec);
+ if (err_code != NRF_SUCCESS)
+ {
+ return err_code;
+ }
+
+ err_code = glucose_meas_send(p_gls, &rec);
+ if (err_code != NRF_SUCCESS)
+ {
+ return err_code;
+ }
+ }
+
+ return NRF_SUCCESS;
+}
+
+
+/**@brief Function for responding to the FIRST or the LAST operation.
+ *
+ * @param[in] p_gls Service instance.
+ *
+ * @return NRF_SUCCESS on success, otherwise an error code.
+ */
+static uint32_t racp_report_records_first_last(ble_gls_t * p_gls)
+{
+ uint32_t err_code;
+ ble_gls_rec_t rec;
+ uint16_t total_records;
+
+ total_records = ble_gls_db_num_records_get();
+
+ if ((m_racp_proc_records_reported != 0) || (total_records == 0))
+ {
+ state_set(STATE_NO_COMM);
+ }
+ else
+ {
+ if (m_racp_proc_operator == RACP_OPERATOR_FIRST)
+ {
+ err_code = ble_gls_db_record_get(0, &rec);
+ if (err_code != NRF_SUCCESS)
+ {
+ return err_code;
+ }
+ }
+ else if (m_racp_proc_operator == RACP_OPERATOR_LAST)
+ {
+ err_code = ble_gls_db_record_get(total_records - 1, &rec);
+ if (err_code != NRF_SUCCESS)
+ {
+ return err_code;
+ }
+ }
+
+ err_code = glucose_meas_send(p_gls, &rec);
+ if (err_code != NRF_SUCCESS)
+ {
+ return err_code;
+ }
+ }
+
+ return NRF_SUCCESS;
+}
+
+
+/**@brief Function for responding to the GREATER_OR_EQUAL operation.
+ *
+ * @param[in] p_gls Service instance.
+ *
+ * @return NRF_SUCCESS on success, otherwise an error code.
+ */
+static uint32_t racp_report_records_greater_or_equal(ble_gls_t * p_gls)
+{
+ uint16_t total_records = ble_gls_db_num_records_get();
+
+ while (m_racp_proc_record_ndx < total_records)
+ {
+ uint32_t err_code;
+ ble_gls_rec_t rec;
+
+ err_code = ble_gls_db_record_get(m_racp_proc_record_ndx, &rec);
+ if (err_code != NRF_SUCCESS)
+ {
+ return err_code;
+ }
+
+ if (rec.meas.sequence_number >= m_racp_proc_seq_num)
+ {
+ err_code = glucose_meas_send(p_gls, &rec);
+ if (err_code != NRF_SUCCESS)
+ {
+ return err_code;
+ }
+ break;
+ }
+ m_racp_proc_record_ndx++;
+ }
+ if (m_racp_proc_record_ndx == total_records)
+ {
+ state_set(STATE_NO_COMM);
+ }
+
+ return NRF_SUCCESS;
+}
+
+
+/**@brief Function for informing that the REPORT RECORDS procedure is completed.
+ *
+ * @param[in] p_gls Service instance.
+ */
+static void racp_report_records_completed(ble_gls_t * p_gls)
+{
+ uint8_t resp_code_value;
+
+ if (m_racp_proc_records_reported > 0)
+ {
+ resp_code_value = RACP_RESPONSE_SUCCESS;
+ }
+ else
+ {
+ resp_code_value = RACP_RESPONSE_NO_RECORDS_FOUND;
+ }
+
+ racp_response_code_send(p_gls, RACP_OPCODE_REPORT_RECS, resp_code_value);
+}
+
+
+/**@brief Function for the RACP report records procedure.
+ *
+ * @param[in] p_gls Service instance.
+ */
+static void racp_report_records_procedure(ble_gls_t * p_gls)
+{
+ uint32_t err_code;
+
+ while (m_gls_state == STATE_RACP_PROC_ACTIVE)
+ {
+ // Execute requested procedure
+ switch (m_racp_proc_operator)
+ {
+ case RACP_OPERATOR_ALL:
+ err_code = racp_report_records_all(p_gls);
+ break;
+
+ case RACP_OPERATOR_FIRST:
+ case RACP_OPERATOR_LAST:
+ err_code = racp_report_records_first_last(p_gls);
+ break;
+
+ case RACP_OPERATOR_GREATER_OR_EQUAL:
+ err_code = racp_report_records_greater_or_equal(p_gls);
+ break;
+
+ default:
+ // Report error to application
+ if (p_gls->error_handler != NULL)
+ {
+ p_gls->error_handler(NRF_ERROR_INTERNAL);
+ }
+
+ // Make sure state machine returns to the default state
+ state_set(STATE_NO_COMM);
+ return;
+ }
+
+ // Error handling
+ switch (err_code)
+ {
+ case NRF_SUCCESS:
+ if (m_gls_state == STATE_RACP_PROC_ACTIVE)
+ {
+ m_racp_proc_record_ndx++;
+ }
+ else
+ {
+ racp_report_records_completed(p_gls);
+ }
+ break;
+
+ case NRF_ERROR_RESOURCES:
+ // Wait for TX_COMPLETE event to resume transmission
+ return;
+
+ case NRF_ERROR_INVALID_STATE:
+ // Notification is probably not enabled. Ignore request.
+ state_set(STATE_NO_COMM);
+ return;
+
+ default:
+ // Report error to application
+ if (p_gls->error_handler != NULL)
+ {
+ p_gls->error_handler(err_code);
+ }
+
+ // Make sure state machine returns to the default state
+ state_set(STATE_NO_COMM);
+ return;
+ }
+ }
+}
+
+
+/**@brief Function for testing if the received request is to be executed.
+ *
+ * @param[in] p_racp_request Request to be checked.
+ * @param[out] p_response_code Response code to be sent in case the request is rejected.
+ * RACP_RESPONSE_RESERVED is returned if the received message is
+ * to be rejected without sending a response.
+ *
+ * @return TRUE if the request is to be executed, FALSE if it is to be rejected.
+ * If it is to be rejected, p_response_code will contain the response code to be
+ * returned to the central.
+ */
+static bool is_request_to_be_executed(ble_racp_value_t const * p_racp_request,
+ uint8_t * p_response_code)
+{
+ *p_response_code = RACP_RESPONSE_RESERVED;
+
+ if (p_racp_request->opcode == RACP_OPCODE_ABORT_OPERATION)
+ {
+ if (m_gls_state == STATE_RACP_PROC_ACTIVE)
+ {
+ if (p_racp_request->operator != RACP_OPERATOR_NULL)
+ {
+ *p_response_code = RACP_RESPONSE_INVALID_OPERATOR;
+ }
+ else if (p_racp_request->operand_len != 0)
+ {
+ *p_response_code = RACP_RESPONSE_INVALID_OPERAND;
+ }
+ else
+ {
+ *p_response_code = RACP_RESPONSE_SUCCESS;
+ }
+ }
+ else
+ {
+ *p_response_code = RACP_RESPONSE_ABORT_FAILED;
+ }
+ }
+ else if (m_gls_state != STATE_NO_COMM)
+ {
+ return false;
+ }
+ // Supported opcodes.
+ else if ((p_racp_request->opcode == RACP_OPCODE_REPORT_RECS) ||
+ (p_racp_request->opcode == RACP_OPCODE_REPORT_NUM_RECS))
+ {
+ switch (p_racp_request->operator)
+ {
+ // Operators WITHOUT a filter.
+ case RACP_OPERATOR_ALL:
+ case RACP_OPERATOR_FIRST:
+ case RACP_OPERATOR_LAST:
+ if (p_racp_request->operand_len != 0)
+ {
+ *p_response_code = RACP_RESPONSE_INVALID_OPERAND;
+ }
+ break;
+
+ // Operators WITH a filter.
+ case RACP_OPERATOR_GREATER_OR_EQUAL:
+ if (p_racp_request->p_operand[0] == OPERAND_FILTER_TYPE_SEQ_NUM)
+ {
+ if (p_racp_request->operand_len != 3)
+ {
+ *p_response_code = RACP_RESPONSE_INVALID_OPERAND;
+ }
+ }
+ else if (p_racp_request->p_operand[0] == OPERAND_FILTER_TYPE_FACING_TIME)
+ {
+ *p_response_code = RACP_RESPONSE_OPERAND_UNSUPPORTED;
+ }
+ else if (p_racp_request->p_operand[0] >= OPERAND_FILTER_TYPE_RFU_START)
+ {
+ *p_response_code = RACP_RESPONSE_OPERAND_UNSUPPORTED;
+ }
+ else
+ {
+ *p_response_code = RACP_RESPONSE_INVALID_OPERAND;
+ }
+ break;
+
+ // Unsupported operators.
+ case RACP_OPERATOR_LESS_OR_EQUAL:
+ case RACP_OPERATOR_RANGE:
+ *p_response_code = RACP_RESPONSE_OPERATOR_UNSUPPORTED;
+ break;
+
+ // Invalid operators.
+ case RACP_OPERATOR_NULL:
+ default:
+ if (p_racp_request->operator >= RACP_OPERATOR_RFU_START)
+ {
+ *p_response_code = RACP_RESPONSE_OPERATOR_UNSUPPORTED;
+ }
+ else
+ {
+ *p_response_code = RACP_RESPONSE_INVALID_OPERATOR;
+ }
+ break;
+ }
+ }
+ // Unsupported opcodes,
+ else if (p_racp_request->opcode == RACP_OPCODE_DELETE_RECS)
+ {
+ *p_response_code = RACP_RESPONSE_OPCODE_UNSUPPORTED;
+ }
+ // Unknown opcodes.
+ else
+ {
+ *p_response_code = RACP_RESPONSE_OPCODE_UNSUPPORTED;
+ }
+
+ // NOTE: The computation of the return value will change slightly when deferred write has been
+ // implemented in the stack.
+ return (*p_response_code == RACP_RESPONSE_RESERVED);
+}
+
+
+/**@brief Function for processing a REPORT RECORDS request.
+ *
+ * @param[in] p_gls Service instance.
+ * @param[in] p_racp_request Request to be executed.
+ */
+static void report_records_request_execute(ble_gls_t * p_gls, ble_racp_value_t * p_racp_request)
+{
+ uint16_t seq_num = (p_racp_request->p_operand[2] << 8) | p_racp_request->p_operand[1];
+
+ state_set(STATE_RACP_PROC_ACTIVE);
+
+ m_racp_proc_record_ndx = 0;
+ m_racp_proc_operator = p_racp_request->operator;
+ m_racp_proc_records_reported = 0;
+ m_racp_proc_seq_num = seq_num;
+
+ racp_report_records_procedure(p_gls);
+}
+
+
+/**@brief Function for processing a REPORT NUM RECORDS request.
+ *
+ * @param[in] p_gls Service instance.
+ * @param[in] p_racp_request Request to be executed.
+ */
+static void report_num_records_request_execute(ble_gls_t * p_gls, ble_racp_value_t * p_racp_request)
+{
+ uint16_t total_records;
+ uint16_t num_records;
+
+ total_records = ble_gls_db_num_records_get();
+ num_records = 0;
+
+ if (p_racp_request->operator == RACP_OPERATOR_ALL)
+ {
+ num_records = total_records;
+ }
+ else if (p_racp_request->operator == RACP_OPERATOR_GREATER_OR_EQUAL)
+ {
+ uint16_t seq_num;
+ uint16_t i;
+
+ seq_num = (p_racp_request->p_operand[2] << 8) | p_racp_request->p_operand[1];
+
+ for (i = 0; i < total_records; i++)
+ {
+ uint32_t err_code;
+ ble_gls_rec_t rec;
+
+ err_code = ble_gls_db_record_get(i, &rec);
+ if (err_code != NRF_SUCCESS)
+ {
+ if (p_gls->error_handler != NULL)
+ {
+ p_gls->error_handler(err_code);
+ }
+ return;
+ }
+
+ if (rec.meas.sequence_number >= seq_num)
+ {
+ num_records++;
+ }
+ }
+ }
+ else if ((p_racp_request->operator == RACP_OPERATOR_FIRST) ||
+ (p_racp_request->operator == RACP_OPERATOR_LAST))
+ {
+ if (total_records > 0)
+ {
+ num_records = 1;
+ }
+ }
+
+ m_pending_racp_response.opcode = RACP_OPCODE_NUM_RECS_RESPONSE;
+ m_pending_racp_response.operator = RACP_OPERATOR_NULL;
+ m_pending_racp_response.operand_len = sizeof(uint16_t);
+ m_pending_racp_response.p_operand = m_pending_racp_response_operand;
+
+ m_pending_racp_response_operand[0] = num_records & 0xFF;
+ m_pending_racp_response_operand[1] = num_records >> 8;
+
+ racp_send(p_gls, &m_pending_racp_response);
+}
+
+
+/**@brief Function for checking if the CCCDs are configured.
+ *
+ * @param[in] p_gls Service instance.
+ * @param[in] p_are_cccd_configured boolean indicating if both cccds are configured
+ */
+uint32_t ble_gls_are_cccd_configured(ble_gls_t * p_gls, bool * p_are_cccd_configured)
+{
+ uint32_t err_code;
+ uint8_t cccd_value_buf[BLE_CCCD_VALUE_LEN];
+ bool is_glm_notif_enabled = false;
+ bool is_racp_indic_enabled = false;
+ ble_gatts_value_t gatts_value;
+
+ // Initialize value struct.
+ memset(&gatts_value, 0, sizeof(gatts_value));
+
+ gatts_value.len = BLE_CCCD_VALUE_LEN;
+ gatts_value.offset = 0;
+ gatts_value.p_value = cccd_value_buf;
+
+ err_code = sd_ble_gatts_value_get(p_gls->conn_handle,
+ p_gls->glm_handles.cccd_handle,
+ &gatts_value);
+ if (err_code != NRF_SUCCESS)
+ {
+ return err_code;
+ }
+ is_glm_notif_enabled = ble_srv_is_notification_enabled(cccd_value_buf);
+
+ err_code = sd_ble_gatts_value_get(p_gls->conn_handle,
+ p_gls->racp_handles.cccd_handle,
+ &gatts_value);
+ if (err_code != NRF_SUCCESS)
+ {
+ return err_code;
+ }
+ is_racp_indic_enabled = ble_srv_is_indication_enabled(cccd_value_buf);
+ if (is_racp_indic_enabled & is_glm_notif_enabled)
+ {
+ *p_are_cccd_configured = true;
+ }
+ else
+ {
+ *p_are_cccd_configured = false;
+ }
+ return NRF_SUCCESS;
+}
+
+
+/**@brief Function for handling a write event to the Record Access Control Point.
+ *
+ * @param[in] p_gls Service instance.
+ * @param[in] p_evt_write WRITE event to be handled.
+ */
+static void on_racp_value_write(ble_gls_t * p_gls, ble_gatts_evt_write_t const * p_evt_write)
+{
+ ble_racp_value_t racp_request;
+ uint8_t response_code;
+ ble_gatts_rw_authorize_reply_params_t auth_reply;
+ bool are_cccd_configured;
+ uint32_t err_code;
+
+ auth_reply.type = BLE_GATTS_AUTHORIZE_TYPE_WRITE;
+ auth_reply.params.write.offset = 0;
+ auth_reply.params.write.len = 0;
+ auth_reply.params.write.p_data = NULL;
+
+ err_code = ble_gls_are_cccd_configured(p_gls, &are_cccd_configured);
+ if (err_code != NRF_SUCCESS)
+ {
+ if (p_gls->error_handler != NULL)
+ {
+ p_gls->error_handler(err_code);
+ }
+ return;
+ }
+
+ if (!are_cccd_configured)
+ {
+ auth_reply.params.write.gatt_status = GLS_NACK_CCCD_IMPROPERLY_CONFIGURED;
+ err_code = sd_ble_gatts_rw_authorize_reply(p_gls->conn_handle,
+ &auth_reply);
+
+ if (err_code != NRF_SUCCESS)
+ {
+ if (p_gls->error_handler != NULL)
+ {
+ p_gls->error_handler(err_code);
+ }
+ }
+ return;
+ }
+
+ // Decode request.
+ ble_racp_decode(p_evt_write->len, (uint8_t*)p_evt_write->data, &racp_request);
+
+ // Check if request is to be executed.
+ if (is_request_to_be_executed(&racp_request, &response_code))
+ {
+ auth_reply.params.write.gatt_status = BLE_GATT_STATUS_SUCCESS;
+ auth_reply.params.write.update = 1;
+
+ err_code = sd_ble_gatts_rw_authorize_reply(p_gls->conn_handle,
+ &auth_reply);
+
+ if (err_code != NRF_SUCCESS)
+ {
+ if (p_gls->error_handler != NULL)
+ {
+ p_gls->error_handler(err_code);
+ }
+ return;
+ }
+ // Execute request.
+ if (racp_request.opcode == RACP_OPCODE_REPORT_RECS)
+ {
+ report_records_request_execute(p_gls, &racp_request);
+ }
+ else if (racp_request.opcode == RACP_OPCODE_REPORT_NUM_RECS)
+ {
+ report_num_records_request_execute(p_gls, &racp_request);
+ }
+ }
+ else if (response_code != RACP_RESPONSE_RESERVED)
+ {
+ auth_reply.params.write.gatt_status = BLE_GATT_STATUS_SUCCESS;
+ auth_reply.params.write.update = 1;
+ err_code = sd_ble_gatts_rw_authorize_reply(p_gls->conn_handle,
+ &auth_reply);
+
+ if (err_code != NRF_SUCCESS)
+ {
+ if (p_gls->error_handler != NULL)
+ {
+ p_gls->error_handler(err_code);
+ }
+ return;
+ }
+
+ // Abort any running procedure.
+ state_set(STATE_NO_COMM);
+
+ // Respond with error code.
+ racp_response_code_send(p_gls, racp_request.opcode, response_code);
+ }
+ else
+ {
+ auth_reply.params.write.gatt_status = GLS_NACK_PROC_ALREADY_IN_PROGRESS;
+ err_code = sd_ble_gatts_rw_authorize_reply(p_gls->conn_handle,
+ &auth_reply);
+
+ if (err_code != NRF_SUCCESS)
+ {
+ if (p_gls->error_handler != NULL)
+ {
+ p_gls->error_handler(err_code);
+ }
+ return;
+ }
+ }
+}
+
+
+/**@brief Function for handling the Glucose measurement CCCD write event.
+ *
+ * @param[in] p_gls Service instance.
+ * @param[in] p_evt_write WRITE event to be handled.
+ */
+static void on_glm_cccd_write(ble_gls_t * p_gls, ble_gatts_evt_write_t const * p_evt_write)
+{
+ if (p_evt_write->len == 2)
+ {
+ // CCCD written, update notification state
+ ble_gls_evt_t evt;
+
+ if (ble_srv_is_notification_enabled(p_evt_write->data))
+ {
+ evt.evt_type = BLE_GLS_EVT_NOTIFICATION_ENABLED;
+ }
+ else
+ {
+ evt.evt_type = BLE_GLS_EVT_NOTIFICATION_DISABLED;
+ }
+
+ if (p_gls->evt_handler != NULL)
+ {
+ p_gls->evt_handler(p_gls, &evt);
+ }
+ }
+}
+
+
+/**@brief Function for handling the WRITE event.
+ *
+ * @details Handles WRITE events from the BLE stack.
+ *
+ * @param[in] p_gls Glucose Service structure.
+ * @param[in] p_ble_evt Event received from the BLE stack.
+ */
+static void on_write(ble_gls_t * p_gls, ble_evt_t const * p_ble_evt)
+{
+ ble_gatts_evt_write_t const * p_evt_write = &p_ble_evt->evt.gatts_evt.params.write;
+
+ if (p_evt_write->handle == p_gls->glm_handles.cccd_handle)
+ {
+ on_glm_cccd_write(p_gls, p_evt_write);
+ }
+ else if (p_evt_write->handle == p_gls->racp_handles.value_handle)
+ {
+ on_racp_value_write(p_gls, p_evt_write);
+ }
+}
+
+
+/**@brief Function for handling the TX_COMPLETE event.
+ *
+ * @details Handles TX_COMPLETE events from the BLE stack.
+ *
+ * @param[in] p_gls Glucose Service structure.
+ * @param[in] p_ble_evt Event received from the BLE stack.
+ */
+static void on_tx_complete(ble_gls_t * p_gls, ble_evt_t const * p_ble_evt)
+{
+ m_racp_proc_records_reported_since_txcomplete = 0;
+
+ if (m_gls_state == STATE_RACP_RESPONSE_PENDING)
+ {
+ racp_send(p_gls, &m_pending_racp_response);
+ }
+ else if (m_gls_state == STATE_RACP_PROC_ACTIVE)
+ {
+ racp_report_records_procedure(p_gls);
+ }
+}
+
+
+/**@brief Function for handling the HVC event.
+ *
+ * @details Handles HVC events from the BLE stack.
+ *
+ * @param[in] p_gls Glucose Service structure.
+ * @param[in] p_ble_evt Event received from the BLE stack.
+ */
+static void on_hvc(ble_gls_t * p_gls, ble_evt_t const * p_ble_evt)
+{
+ ble_gatts_evt_hvc_t const * p_hvc = &p_ble_evt->evt.gatts_evt.params.hvc;
+
+ if (p_hvc->handle == p_gls->racp_handles.value_handle)
+ {
+ if (m_gls_state == STATE_RACP_RESPONSE_IND_VERIF)
+ {
+ // Indication has been acknowledged. Return to default state.
+ state_set(STATE_NO_COMM);
+ }
+ else if (m_gls_state == STATE_RACP_RESPONSE_PENDING)
+ {
+ racp_send(p_gls, &m_pending_racp_response);
+ }
+ else
+ {
+ // We did not expect this event in this state. Report error to application.
+ if (p_gls->error_handler != NULL)
+ {
+ p_gls->error_handler(NRF_ERROR_INVALID_STATE);
+ }
+ }
+ }
+}
+
+
+static void on_rw_authorize_request(ble_gls_t * p_gls, ble_gatts_evt_t const * p_gatts_evt)
+{
+ ble_gatts_evt_rw_authorize_request_t const * p_auth_req =
+ &p_gatts_evt->params.authorize_request;
+
+ if (p_auth_req->type == BLE_GATTS_AUTHORIZE_TYPE_WRITE)
+ {
+ if ( (p_gatts_evt->params.authorize_request.request.write.op
+ != BLE_GATTS_OP_PREP_WRITE_REQ)
+ && (p_gatts_evt->params.authorize_request.request.write.op
+ != BLE_GATTS_OP_EXEC_WRITE_REQ_NOW)
+ && (p_gatts_evt->params.authorize_request.request.write.op
+ != BLE_GATTS_OP_EXEC_WRITE_REQ_CANCEL)
+ )
+ {
+ if (p_auth_req->request.write.handle == p_gls->racp_handles.value_handle)
+ {
+ on_racp_value_write(p_gls, &p_auth_req->request.write);
+ }
+ }
+ }
+}
+
+void ble_gls_on_ble_evt(ble_evt_t const * p_ble_evt, void * p_context)
+{
+ ble_gls_t * p_gls = (ble_gls_t *)p_context;
+
+ switch (p_ble_evt->header.evt_id)
+ {
+ case BLE_GAP_EVT_CONNECTED:
+ p_gls->conn_handle = p_ble_evt->evt.gap_evt.conn_handle;
+ state_set(STATE_NO_COMM);
+ break;
+
+ case BLE_GAP_EVT_DISCONNECTED:
+ p_gls->conn_handle = BLE_CONN_HANDLE_INVALID;
+ break;
+
+ case BLE_GATTS_EVT_WRITE:
+ on_write(p_gls, p_ble_evt);
+ break;
+
+ case BLE_GATTS_EVT_HVN_TX_COMPLETE:
+ on_tx_complete(p_gls, p_ble_evt);
+ break;
+
+ case BLE_GATTS_EVT_RW_AUTHORIZE_REQUEST:
+ on_rw_authorize_request(p_gls, &p_ble_evt->evt.gatts_evt);
+ break;
+
+ case BLE_GATTS_EVT_HVC:
+ on_hvc(p_gls, p_ble_evt);
+ break;
+
+ default:
+ // No implementation needed.
+ break;
+ }
+}
+
+
+uint32_t ble_gls_glucose_new_meas(ble_gls_t * p_gls, ble_gls_rec_t * p_rec)
+{
+ p_rec->meas.sequence_number = m_next_seq_num++;
+ return ble_gls_db_record_add(p_rec);
+}
+#endif // NRF_MODULE_ENABLED(BLE_GLS)
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/ble_gls/ble_gls.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/ble_gls/ble_gls.h
new file mode 100644
index 0000000..374d3a3
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/ble_gls/ble_gls.h
@@ -0,0 +1,323 @@
+/**
+ * Copyright (c) 2012 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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
+ *
+ * @defgroup ble_gls Glucose Service
+ * @{
+ * @ingroup ble_sdk_srv
+ * @brief Glucose Service module.
+ *
+ * @details This module implements the Glucose Service.
+ *
+ * @note The application must register this module as BLE event observer using the
+ * NRF_SDH_BLE_OBSERVER macro. Example:
+ * @code
+ * ble_gls_t instance;
+ * NRF_SDH_BLE_OBSERVER(anything, BLE_GLS_BLE_OBSERVER_PRIO,
+ * ble_gls_on_ble_evt, &instance);
+ * @endcode
+ *
+ * @note Attention!
+ * To maintain compliance with Nordic Semiconductor ASA Bluetooth profile
+ * qualification listings, this section of source code must not be modified.
+ */
+
+#ifndef BLE_GLS_H__
+#define BLE_GLS_H__
+
+#include <stdint.h>
+#include <stdbool.h>
+#include "ble.h"
+#include "ble_srv_common.h"
+#include "ble_date_time.h"
+#include "nrf_sdh_ble.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**@brief Macro for defining a ble_gls instance.
+ *
+ * @param _name Name of the instance.
+ * @hideinitializer
+ */
+#define BLE_GLS_DEF(_name) \
+static ble_gls_t _name; \
+NRF_SDH_BLE_OBSERVER(_name ## _obs, \
+ BLE_GLS_BLE_OBSERVER_PRIO, \
+ ble_gls_on_ble_evt, &_name)
+
+
+/**@brief Glucose feature */
+#define BLE_GLS_FEATURE_LOW_BATT 0x0001 /**< Low Battery Detection During Measurement Supported */
+#define BLE_GLS_FEATURE_MALFUNC 0x0002 /**< Sensor Malfunction Detection Supported */
+#define BLE_GLS_FEATURE_SAMPLE_SIZE 0x0004 /**< Sensor Sample Size Supported */
+#define BLE_GLS_FEATURE_INSERT_ERR 0x0008 /**< Sensor Strip Insertion Error Detection Supported */
+#define BLE_GLS_FEATURE_TYPE_ERR 0x0010 /**< Sensor Strip Type Error Detection Supported */
+#define BLE_GLS_FEATURE_RES_HIGH_LOW 0x0020 /**< Sensor Result High-Low Detection Supported */
+#define BLE_GLS_FEATURE_TEMP_HIGH_LOW 0x0040 /**< Sensor Temperature High-Low Detection Supported */
+#define BLE_GLS_FEATURE_READ_INT 0x0080 /**< Sensor Read Interrupt Detection Supported */
+#define BLE_GLS_FEATURE_GENERAL_FAULT 0x0100 /**< General Device Fault Supported */
+#define BLE_GLS_FEATURE_TIME_FAULT 0x0200 /**< Time Fault Supported */
+#define BLE_GLS_FEATURE_MULTI_BOND 0x0400 /**< Multiple Bond Supported */
+
+/**@brief Glucose measurement flags */
+#define BLE_GLS_MEAS_FLAG_TIME_OFFSET 0x01 /**< Time Offset Present */
+#define BLE_GLS_MEAS_FLAG_CONC_TYPE_LOC 0x02 /**< Glucose Concentration, Type, and Sample Location Present */
+#define BLE_GLS_MEAS_FLAG_UNITS_KG_L 0x00 /**< Glucose Concentration Units kg/L */
+#define BLE_GLS_MEAS_FLAG_UNITS_MOL_L 0x04 /**< Glucose Concentration Units mol/L */
+#define BLE_GLS_MEAS_FLAG_SENSOR_STATUS 0x08 /**< Sensor Status Annunciation Present */
+#define BLE_GLS_MEAS_FLAG_CONTEXT_INFO 0x10 /**< Context Information Follows */
+
+/**@brief Glucose measurement type */
+#define BLE_GLS_MEAS_TYPE_CAP_BLOOD 1 /**< Capillary whole blood */
+#define BLE_GLS_MEAS_TYPE_CAP_PLASMA 2 /**< Capillary plasma */
+#define BLE_GLS_MEAS_TYPE_VEN_BLOOD 3 /**< Venous whole blood */
+#define BLE_GLS_MEAS_TYPE_VEN_PLASMA 4 /**< Venous plasma */
+#define BLE_GLS_MEAS_TYPE_ART_BLOOD 5 /**< Arterial whole blood */
+#define BLE_GLS_MEAS_TYPE_ART_PLASMA 6 /**< Arterial plasma */
+#define BLE_GLS_MEAS_TYPE_UNDET_BLOOD 7 /**< Undetermined whole blood */
+#define BLE_GLS_MEAS_TYPE_UNDET_PLASMA 8 /**< Undetermined plasma */
+#define BLE_GLS_MEAS_TYPE_FLUID 9 /**< Interstitial fluid (ISF) */
+#define BLE_GLS_MEAS_TYPE_CONTROL 10 /**< Control solution */
+
+/**@brief Glucose measurement location */
+#define BLE_GLS_MEAS_LOC_FINGER 1 /**< Finger */
+#define BLE_GLS_MEAS_LOC_AST 2 /**< Alternate Site Test (AST) */
+#define BLE_GLS_MEAS_LOC_EAR 3 /**< Earlobe */
+#define BLE_GLS_MEAS_LOC_CONTROL 4 /**< Control solution */
+#define BLE_GLS_MEAS_LOC_NOT_AVAIL 15 /**< Sample Location value not available */
+
+/**@brief Glucose sensor status annunciation */
+#define BLE_GLS_MEAS_STATUS_BATT_LOW 0x0001 /**< Device battery low at time of measurement */
+#define BLE_GLS_MEAS_STATUS_SENSOR_FAULT 0x0002 /**< Sensor malfunction or faulting at time of measurement */
+#define BLE_GLS_MEAS_STATUS_SAMPLE_SIZE 0x0004 /**< Sample size for blood or control solution insufficient at time of measurement */
+#define BLE_GLS_MEAS_STATUS_STRIP_INSERT 0x0008 /**< Strip insertion error */
+#define BLE_GLS_MEAS_STATUS_STRIP_TYPE 0x0010 /**< Strip type incorrect for device */
+#define BLE_GLS_MEAS_STATUS_RESULT_HIGH 0x0020 /**< Sensor result higher than the device can process */
+#define BLE_GLS_MEAS_STATUS_RESULT_LOW 0x0040 /**< Sensor result lower than the device can process */
+#define BLE_GLS_MEAS_STATUS_TEMP_HIGH 0x0080 /**< Sensor temperature too high for valid test/result at time of measurement */
+#define BLE_GLS_MEAS_STATUS_TEMP_LOW 0x0100 /**< Sensor temperature too low for valid test/result at time of measurement */
+#define BLE_GLS_MEAS_STATUS_STRIP_PULL 0x0200 /**< Sensor read interrupted because strip was pulled too soon at time of measurement */
+#define BLE_GLS_MEAS_STATUS_GENERAL_FAULT 0x0400 /**< General device fault has occurred in the sensor */
+#define BLE_GLS_MEAS_STATUS_TIME_FAULT 0x0800 /**< Time fault has occurred in the sensor and time may be inaccurate */
+
+/**@brief Glucose measurement context flags */
+#define BLE_GLS_CONTEXT_FLAG_CARB 0x01 /**< Carbohydrate id and carbohydrate present */
+#define BLE_GLS_CONTEXT_FLAG_MEAL 0x02 /**< Meal present */
+#define BLE_GLS_CONTEXT_FLAG_TESTER 0x04 /**< Tester-health present */
+#define BLE_GLS_CONTEXT_FLAG_EXERCISE 0x08 /**< Exercise duration and exercise intensity present */
+#define BLE_GLS_CONTEXT_FLAG_MED 0x10 /**< Medication ID and medication present */
+#define BLE_GLS_CONTEXT_FLAG_MED_KG 0x00 /**< Medication value units, kilograms */
+#define BLE_GLS_CONTEXT_FLAG_MED_L 0x20 /**< Medication value units, liters */
+#define BLE_GLS_CONTEXT_FLAG_HBA1C 0x40 /**< Hba1c present */
+#define BLE_GLS_CONTEXT_FLAG_EXT 0x80 /**< Extended flags present */
+
+/**@brief Glucose measurement context carbohydrate ID */
+#define BLE_GLS_CONTEXT_CARB_BREAKFAST 1 /**< Breakfast */
+#define BLE_GLS_CONTEXT_CARB_LUNCH 2 /**< Lunch */
+#define BLE_GLS_CONTEXT_CARB_DINNER 3 /**< Dinner */
+#define BLE_GLS_CONTEXT_CARB_SNACK 4 /**< Snack */
+#define BLE_GLS_CONTEXT_CARB_DRINK 5 /**< Drink */
+#define BLE_GLS_CONTEXT_CARB_SUPPER 6 /**< Supper */
+#define BLE_GLS_CONTEXT_CARB_BRUNCH 7 /**< Brunch */
+
+/**@brief Glucose measurement context meal */
+#define BLE_GLS_CONTEXT_MEAL_PREPRANDIAL 1 /**< Preprandial (before meal) */
+#define BLE_GLS_CONTEXT_MEAL_POSTPRANDIAL 2 /**< Postprandial (after meal) */
+#define BLE_GLS_CONTEXT_MEAL_FASTING 3 /**< Fasting */
+#define BLE_GLS_CONTEXT_MEAL_CASUAL 4 /**< Casual (snacks, drinks, etc.) */
+#define BLE_GLS_CONTEXT_MEAL_BEDTIME 5 /**< Bedtime */
+
+/**@brief Glucose measurement context tester */
+#define BLE_GLS_CONTEXT_TESTER_SELF 1 /**< Self */
+#define BLE_GLS_CONTEXT_TESTER_PRO 2 /**< Health care professional */
+#define BLE_GLS_CONTEXT_TESTER_LAB 3 /**< Lab test */
+#define BLE_GLS_CONTEXT_TESTER_NOT_AVAIL 15 /**< Tester value not available */
+
+/**@brief Glucose measurement context health */
+#define BLE_GLS_CONTEXT_HEALTH_MINOR 1 /**< Minor health issues */
+#define BLE_GLS_CONTEXT_HEALTH_MAJOR 2 /**< Major health issues */
+#define BLE_GLS_CONTEXT_HEALTH_MENSES 3 /**< During menses */
+#define BLE_GLS_CONTEXT_HEALTH_STRESS 4 /**< Under stress */
+#define BLE_GLS_CONTEXT_HEALTH_NONE 5 /**< No health issues */
+#define BLE_GLS_CONTEXT_HEALTH_NOT_AVAIL 15 /**< Health value not available */
+
+/**@brief Glucose measurement context medication ID */
+#define BLE_GLS_CONTEXT_MED_RAPID 1 /**< Rapid acting insulin */
+#define BLE_GLS_CONTEXT_MED_SHORT 2 /**< Short acting insulin */
+#define BLE_GLS_CONTEXT_MED_INTERMED 3 /**< Intermediate acting insulin */
+#define BLE_GLS_CONTEXT_MED_LONG 4 /**< Long acting insulin */
+#define BLE_GLS_CONTEXT_MED_PREMIX 5 /**< Pre-mixed insulin */
+
+
+/**@brief SFLOAT format (IEEE-11073 16-bit FLOAT, meaning 4 bits for exponent (base 10) and 12 bits mantissa) */
+typedef struct
+{
+ int8_t exponent; /**< Base 10 exponent, should be using only 4 bits */
+ int16_t mantissa; /**< Mantissa, should be using only 12 bits */
+} sfloat_t;
+
+/**@brief Glucose Service event type. */
+typedef enum
+{
+ BLE_GLS_EVT_NOTIFICATION_ENABLED, /**< Glucose value notification enabled event. */
+ BLE_GLS_EVT_NOTIFICATION_DISABLED /**< Glucose value notification disabled event. */
+} ble_gls_evt_type_t;
+
+/**@brief Glucose Service event. */
+typedef struct
+{
+ ble_gls_evt_type_t evt_type; /**< Type of event. */
+} ble_gls_evt_t;
+
+// Forward declaration of the ble_gls_t type.
+typedef struct ble_gls_s ble_gls_t;
+
+/**@brief Glucose Service event handler type. */
+typedef void (*ble_gls_evt_handler_t) (ble_gls_t * p_gls, ble_gls_evt_t * p_evt);
+
+/**@brief Glucose Measurement structure. This contains glucose measurement value. */
+typedef struct
+{
+ uint8_t flags; /**< Flags */
+ uint16_t sequence_number; /**< Sequence number */
+ ble_date_time_t base_time; /**< Time stamp */
+ int16_t time_offset; /**< Time offset */
+ sfloat_t glucose_concentration; /**< Glucose concentration */
+ uint8_t type; /**< Type */
+ uint8_t sample_location; /**< Sample location */
+ uint16_t sensor_status_annunciation; /**< Sensor status annunciation */
+} ble_gls_meas_t;
+
+/**@brief Glucose measurement context structure */
+typedef struct
+{
+ uint8_t flags; /**< Flags */
+ uint8_t extended_flags; /**< Extended Flags */
+ uint8_t carbohydrate_id; /**< Carbohydrate ID */
+ sfloat_t carbohydrate; /**< Carbohydrate */
+ uint8_t meal; /**< Meal */
+ uint8_t tester_and_health; /**< Tester and health */
+ uint16_t exercise_duration; /**< Exercise Duration */
+ uint8_t exercise_intensity; /**< Exercise Intensity */
+ uint8_t medication_id; /**< Medication ID */
+ sfloat_t medication; /**< Medication */
+ uint16_t hba1c; /**< HbA1c */
+} ble_gls_meas_context_t;
+
+/**@brief Glucose measurement record */
+typedef struct
+{
+ ble_gls_meas_t meas; /**< Glucose measurement */
+ ble_gls_meas_context_t context; /**< Glucose measurement context */
+} ble_gls_rec_t;
+
+/**@brief Glucose Service init structure. This contains all options and data needed for
+ * initialization of the service. */
+typedef struct
+{
+ ble_gls_evt_handler_t evt_handler; /**< Event handler to be called for handling events in the Glucose Service. */
+ ble_srv_error_handler_t error_handler; /**< Function to be called in case of an error. */
+ uint16_t feature; /**< Glucose Feature value indicating supported features. */
+ bool is_context_supported; /**< Determines if optional Glucose Measurement Context is to be supported. */
+} ble_gls_init_t;
+
+/**@brief Glucose Service structure. This contains various status information for the service. */
+struct ble_gls_s
+{
+ ble_gls_evt_handler_t evt_handler; /**< Event handler to be called for handling events in the Glucose Service. */
+ ble_srv_error_handler_t error_handler; /**< Function to be called in case of an error. */
+ uint16_t service_handle; /**< Handle of Glucose Service (as provided by the BLE stack). */
+ ble_gatts_char_handles_t glm_handles; /**< Handles related to the Glucose Measurement characteristic. */
+ ble_gatts_char_handles_t glm_context_handles; /**< Handles related to the Glucose Measurement Context characteristic. */
+ ble_gatts_char_handles_t glf_handles; /**< Handles related to the Glucose Feature characteristic. */
+ ble_gatts_char_handles_t racp_handles; /**< Handles related to the Record Access Control Point characteristic. */
+ uint16_t conn_handle; /**< Handle of the current connection (as provided by the BLE stack, is BLE_CONN_HANDLE_INVALID if not in a connection). */
+ uint16_t feature;
+ bool is_context_supported;
+};
+
+
+/**@brief Function for initializing the Glucose Service.
+ *
+ * @details This call allows the application to initialize the Glucose Service.
+ *
+ * @param[out] p_gls Glucose Service structure. This structure will have to be supplied by
+ * the application. It will be initialized by this function, and will later
+ * be used to identify this particular service instance.
+ * @param[in] p_gls_init Information needed to initialize the service.
+ *
+ * @return NRF_SUCCESS on successful initialization of service, otherwise an error code.
+ */
+uint32_t ble_gls_init(ble_gls_t * p_gls, ble_gls_init_t const * p_gls_init);
+
+
+/**@brief Function for handling the Application's BLE Stack events.
+ *
+ * @details Handles all events from the BLE stack of interest to the Glucose Service.
+ *
+ * @param[in] p_ble_evt Event received from the BLE stack.
+ * @param[in] p_context Glucose Service structure.
+ */
+void ble_gls_on_ble_evt(ble_evt_t const * p_ble_evt, void * p_context);
+
+
+/**@brief Function for reporting a new glucose measurement to the glucose service module.
+ *
+ * @details The application calls this function after having performed a new glucose measurement.
+ * The new measurement is recorded in the RACP database.
+ *
+ * @param[in] p_gls Glucose Service structure.
+ * @param[in] p_rec Pointer to glucose record (measurement plus context).
+ *
+ * @return NRF_SUCCESS on success, otherwise an error code.
+ */
+uint32_t ble_gls_glucose_new_meas(ble_gls_t * p_gls, ble_gls_rec_t * p_rec);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // BLE_GLS_H__
+
+/** @} */
+
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/ble_gls/ble_gls_db.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/ble_gls/ble_gls_db.c
new file mode 100644
index 0000000..679a359
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/ble_gls/ble_gls_db.c
@@ -0,0 +1,143 @@
+/**
+ * Copyright (c) 2012 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#include "sdk_common.h"
+#if NRF_MODULE_ENABLED(BLE_GLS)
+#include "ble_gls_db.h"
+
+
+typedef struct
+{
+ bool in_use_flag;
+ ble_gls_rec_t record;
+} database_entry_t;
+
+static database_entry_t m_database[BLE_GLS_DB_MAX_RECORDS];
+static uint8_t m_database_crossref[BLE_GLS_DB_MAX_RECORDS];
+static uint16_t m_num_records;
+
+
+uint32_t ble_gls_db_init(void)
+{
+ int i;
+
+ for (i = 0; i < BLE_GLS_DB_MAX_RECORDS; i++)
+ {
+ m_database[i].in_use_flag = false;
+ m_database_crossref[i] = 0xFF;
+ }
+
+ m_num_records = 0;
+
+ return NRF_SUCCESS;
+}
+
+
+uint16_t ble_gls_db_num_records_get(void)
+{
+ return m_num_records;
+}
+
+
+uint32_t ble_gls_db_record_get(uint8_t rec_ndx, ble_gls_rec_t * p_rec)
+{
+ if (rec_ndx >= m_num_records)
+ {
+ return NRF_ERROR_INVALID_PARAM;
+ }
+
+ // copy record to the specified memory
+ *p_rec = m_database[m_database_crossref[rec_ndx]].record;
+
+ return NRF_SUCCESS;
+}
+
+
+uint32_t ble_gls_db_record_add(ble_gls_rec_t * p_rec)
+{
+ int i;
+
+ if (m_num_records == BLE_GLS_DB_MAX_RECORDS)
+ {
+ return NRF_ERROR_NO_MEM;
+ }
+
+ // find next available database entry
+ for (i = 0; i < BLE_GLS_DB_MAX_RECORDS; i++)
+ {
+ if (!m_database[i].in_use_flag)
+ {
+ m_database[i].in_use_flag = true;
+ m_database[i].record = *p_rec;
+
+ m_database_crossref[m_num_records] = i;
+ m_num_records++;
+
+ return NRF_SUCCESS;
+ }
+ }
+
+ return NRF_ERROR_NO_MEM;
+}
+
+
+uint32_t ble_gls_db_record_delete(uint8_t rec_ndx)
+{
+ int i;
+
+ if (rec_ndx >= m_num_records)
+ {
+ return NRF_ERROR_NOT_FOUND;
+ }
+
+ // free entry
+ m_database[m_database_crossref[rec_ndx]].in_use_flag = false;
+
+ // decrease number of records
+ m_num_records--;
+
+ // remove cross reference index
+ for (i = rec_ndx; i < m_num_records; i++)
+ {
+ m_database_crossref[i] = m_database_crossref[i + 1];
+ }
+
+ return NRF_SUCCESS;
+}
+#endif // NRF_MODULE_ENABLED(BLE_GLS)
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/ble_gls/ble_gls_db.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/ble_gls/ble_gls_db.h
new file mode 100644
index 0000000..98465f0
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/ble_gls/ble_gls_db.h
@@ -0,0 +1,121 @@
+/**
+ * Copyright (c) 2012 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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
+ *
+ * @defgroup ble_sdk_srv_gls_db Glucose Database Service
+ * @{
+ * @ingroup ble_sdk_srv
+ * @brief Glucose Service module.
+ *
+ * @details This module implements at database of stored glucose measurement values.
+ *
+ * @note Attention!
+ * To maintain compliance with Nordic Semiconductor ASA Bluetooth profile
+ * qualification listings, These APIs must not be modified. However, the corresponding
+ * functions' implementations can be modified.
+ */
+
+#ifndef BLE_GLS_DB_H__
+#define BLE_GLS_DB_H__
+
+#include <stdint.h>
+#include "ble_gls.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define BLE_GLS_DB_MAX_RECORDS 20
+
+/**@brief Function for initializing the glucose record database.
+ *
+ * @details This call initializes the database holding glucose records.
+ *
+ * @return NRF_SUCCESS on success.
+ */
+uint32_t ble_gls_db_init(void);
+
+/**@brief Function for getting the number of records in the database.
+ *
+ * @details This call returns the number of records in the database.
+ *
+ * @return Number of records in the database.
+ */
+uint16_t ble_gls_db_num_records_get(void);
+
+/**@brief Function for getting a record from the database.
+ *
+ * @details This call returns a specified record from the database.
+ *
+ * @param[in] record_num Index of the record to retrieve.
+ * @param[out] p_rec Pointer to record structure where retrieved record is copied to.
+ *
+ * @return NRF_SUCCESS on success.
+ */
+uint32_t ble_gls_db_record_get(uint8_t record_num, ble_gls_rec_t * p_rec);
+
+/**@brief Function for adding a record at the end of the database.
+ *
+ * @details This call adds a record as the last record in the database.
+ *
+ * @param[in] p_rec Pointer to record to add to database.
+ *
+ * @return NRF_SUCCESS on success.
+ */
+uint32_t ble_gls_db_record_add(ble_gls_rec_t * p_rec);
+
+/**@brief Function for deleting a database entry.
+ *
+ * @details This call deletes an record from the database.
+ *
+ * @param[in] record_num Index of record to delete.
+ *
+ * @return NRF_SUCCESS on success.
+ */
+uint32_t ble_gls_db_record_delete(uint8_t record_num);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // BLE_GLS_DB_H__
+
+/** @} */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/ble_hids/ble_hids.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/ble_hids/ble_hids.c
new file mode 100644
index 0000000..1bf0b38
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/ble_hids/ble_hids.c
@@ -0,0 +1,1794 @@
+/**
+ * Copyright (c) 2012 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+/* Attention!
+ * To maintain compliance with Nordic Semiconductor ASA's Bluetooth profile
+ * qualification listings, this section of source code must not be modified.
+ */
+#include "sdk_common.h"
+#if NRF_MODULE_ENABLED(BLE_HIDS)
+#include "ble_hids.h"
+#include <string.h>
+#include "app_error.h"
+#include "ble_srv_common.h"
+
+
+// Protocol Mode values
+#define PROTOCOL_MODE_BOOT 0x00 /**< Boot Protocol Mode. */
+#define PROTOCOL_MODE_REPORT 0x01 /**< Report Protocol Mode. */
+
+// HID Control Point values
+#define HIDS_CONTROL_POINT_SUSPEND 0 /**< Suspend command. */
+#define HIDS_CONTROL_POINT_EXIT_SUSPEND 1 /**< Exit Suspend command. */
+
+#define DEFAULT_PROTOCOL_MODE PROTOCOL_MODE_REPORT /**< Default value for the Protocol Mode characteristic. */
+#define INITIAL_VALUE_HID_CONTROL_POINT HIDS_CONTROL_POINT_SUSPEND /**< Initial value for the HID Control Point characteristic. */
+
+#define ENCODED_HID_INFORMATION_LEN 4 /**< Maximum size of an encoded HID Information characteristic. */
+
+/**@brief Handles errors for HID service module.
+ *
+ * @param[in] _p_hids HID Service structure.
+ * @param[in] _err_code Maximum number of HID hosts connected at a time.
+ *
+ */
+#define BLE_HIDS_ERROR_HANDLE(_p_hids, _err_code) \
+ do \
+ { \
+ if (((_err_code) != NRF_SUCCESS) && ((_p_hids)->error_handler != NULL)) \
+ { \
+ (_p_hids)->error_handler((_err_code)); \
+ } \
+ } while (0)
+
+
+/**@brief Function for calculating the link context size for the HID service.
+ *
+ * @param[in] p_hids HID Service structure.
+ *
+ * @return Link context size.
+ */
+static size_t ble_hids_client_context_size_calc(ble_hids_t * p_hids)
+{
+ size_t client_size = sizeof(ble_hids_client_context_t) + (BOOT_KB_INPUT_REPORT_MAX_SIZE) +
+ (BOOT_KB_OUTPUT_REPORT_MAX_SIZE) + (BOOT_MOUSE_INPUT_REPORT_MAX_SIZE);
+
+ if (p_hids->p_inp_rep_init_array != NULL)
+ {
+ for (uint32_t i = 0; i < p_hids->inp_rep_count; i++)
+ {
+ client_size += p_hids->p_inp_rep_init_array[i].max_len;
+ }
+ }
+ if (p_hids->p_outp_rep_init_array != NULL)
+ {
+ for (uint32_t i = 0; i < p_hids->outp_rep_count; i++)
+ {
+ client_size += p_hids->p_outp_rep_init_array[i].max_len;
+ }
+ }
+ if (p_hids->p_feature_rep_init_array != NULL)
+ {
+ for (uint32_t i = 0; i < p_hids->feature_rep_count; i++)
+ {
+ client_size += p_hids->p_feature_rep_init_array[i].max_len;
+ }
+ }
+
+ return client_size;
+}
+
+
+/**@brief Function for making a HID Service characteristic id.
+ *
+ * @param[in] uuid UUID of characteristic.
+ * @param[in] rep_type Type of report.
+ * @param[in] rep_index Index of the characteristic.
+ *
+ * @return HID Service characteristic id structure.
+ */
+static ble_hids_char_id_t make_char_id(uint16_t uuid, uint8_t rep_type, uint8_t rep_index)
+{
+ ble_hids_char_id_t char_id = {0};
+
+ char_id.uuid = uuid;
+ char_id.rep_type = rep_type;
+ char_id.rep_index = rep_index;
+
+ return char_id;
+}
+
+
+/**@brief Function for handling the Connect event.
+ *
+ * @param[in] p_hids HID Service structure.
+ * @param[in] p_ble_evt Event received from the BLE stack.
+ */
+static void on_connect(ble_hids_t * p_hids, ble_evt_t const * p_ble_evt)
+{
+ uint32_t err_code;
+ ble_gatts_value_t gatts_value;
+ ble_hids_client_context_t * p_client = NULL;
+
+ err_code = blcm_link_ctx_get(p_hids->p_link_ctx_storage,
+ p_ble_evt->evt.gap_evt.conn_handle,
+ (void *) &p_client);
+ BLE_HIDS_ERROR_HANDLE(p_hids, err_code);
+
+ if (p_client == NULL)
+ {
+ return;
+ }
+
+ memset(p_client, 0, ble_hids_client_context_size_calc(p_hids));
+
+ if (p_hids->protocol_mode_handles.value_handle)
+ {
+ // Set Protocol Mode characteristic value to default value
+ p_client->protocol_mode = DEFAULT_PROTOCOL_MODE;
+
+ // Initialize value struct.
+ memset(&gatts_value, 0, sizeof(gatts_value));
+
+ gatts_value.len = sizeof(uint8_t);
+ gatts_value.offset = 0;
+ gatts_value.p_value = &p_client->protocol_mode;
+
+ err_code = sd_ble_gatts_value_set(p_ble_evt->evt.gap_evt.conn_handle,
+ p_hids->protocol_mode_handles.value_handle,
+ &gatts_value);
+ BLE_HIDS_ERROR_HANDLE(p_hids, err_code);
+ }
+}
+
+
+/**@brief Function for handling write events to the HID Control Point value.
+ *
+ * @param[in] p_hids HID Service structure.
+ * @param[in] p_evt_write Write event received from the BLE stack.
+ */
+static void on_control_point_write(ble_hids_t * p_hids, ble_evt_t const * p_ble_evt)
+{
+ ret_code_t err_code;
+ ble_hids_client_context_t * p_host;
+ ble_gatts_evt_write_t const * p_evt_write = &p_ble_evt->evt.gatts_evt.params.write;
+
+ err_code = blcm_link_ctx_get(p_hids->p_link_ctx_storage,
+ p_ble_evt->evt.gatts_evt.conn_handle,
+ (void *) &p_host);
+ BLE_HIDS_ERROR_HANDLE(p_hids, err_code);
+
+ if (p_host == NULL)
+ {
+ return;
+ }
+
+ if (p_evt_write->len == 1)
+ {
+ ble_hids_evt_t evt;
+
+ switch (p_evt_write->data[0])
+ {
+ case HIDS_CONTROL_POINT_SUSPEND:
+ evt.evt_type = BLE_HIDS_EVT_HOST_SUSP;
+ break;
+
+ case HIDS_CONTROL_POINT_EXIT_SUSPEND:
+ evt.evt_type = BLE_HIDS_EVT_HOST_EXIT_SUSP;
+ break;
+
+ default:
+ // Illegal Control Point value, ignore
+ return;
+ }
+
+ // Store the new Control Point value for the host
+ p_host->ctrl_pt = p_evt_write->data[0];
+
+ // HID Control Point written, propagate event to application
+ if (p_hids->evt_handler != NULL)
+ {
+ evt.p_ble_evt = p_ble_evt;
+ p_hids->evt_handler(p_hids, &evt);
+ }
+ }
+}
+
+
+/**@brief Function for handling write events to the Protocol Mode value.
+ *
+ * @param[in] p_hids HID Service structure.
+ * @param[in] p_ble_evt BLE event received from the BLE stack.
+ */
+static void on_protocol_mode_write(ble_hids_t * p_hids, ble_evt_t const * p_ble_evt)
+{
+ ret_code_t err_code;
+ ble_hids_client_context_t * p_host;
+ ble_gatts_evt_write_t const * p_evt_write = &p_ble_evt->evt.gatts_evt.params.write;
+
+ err_code = blcm_link_ctx_get(p_hids->p_link_ctx_storage,
+ p_ble_evt->evt.gatts_evt.conn_handle,
+ (void *) &p_host);
+ BLE_HIDS_ERROR_HANDLE(p_hids, err_code);
+
+
+ if (p_host == NULL)
+ {
+ return;
+ }
+
+ if (p_evt_write->len == 1)
+ {
+ ble_hids_evt_t evt;
+
+ switch (p_evt_write->data[0])
+ {
+ case PROTOCOL_MODE_BOOT:
+ evt.evt_type = BLE_HIDS_EVT_BOOT_MODE_ENTERED;
+ break;
+
+ case PROTOCOL_MODE_REPORT:
+ evt.evt_type = BLE_HIDS_EVT_REPORT_MODE_ENTERED;
+ break;
+
+ default:
+ // Illegal Protocol Mode value, ignore
+ return;
+ }
+
+ // Store Protocol Mode of the host
+ p_host->protocol_mode = p_evt_write->data[0];
+
+ // HID Protocol Mode written, propagate event to application
+ if (p_hids->evt_handler != NULL)
+ {
+ evt.p_ble_evt = p_ble_evt;
+ p_hids->evt_handler(p_hids, &evt);
+ }
+ }
+}
+
+
+/**@brief Function for handling authorize read events to the Protocol Mode value.
+ *
+ * @param[in] p_hids HID Service structure.
+ * @param[in] p_ble_evt BLE event received from the BLE stack.
+ */
+void on_protocol_mode_read_auth(ble_hids_t * p_hids, ble_evt_t const * p_ble_evt)
+{
+ ret_code_t err_code;
+ ble_gatts_rw_authorize_reply_params_t auth_read_params;
+ ble_hids_client_context_t * p_host;
+ ble_gatts_evt_rw_authorize_request_t const * p_read_auth =
+ &p_ble_evt->evt.gatts_evt.params.authorize_request;
+
+ err_code = blcm_link_ctx_get(p_hids->p_link_ctx_storage,
+ p_ble_evt->evt.gatts_evt.conn_handle,
+ (void *) &p_host);
+ BLE_HIDS_ERROR_HANDLE(p_hids, err_code);
+
+ // Update GATTS table with this host's Protocol Mode value and authorize Read
+ if (p_host != NULL)
+ {
+ memset(&auth_read_params, 0, sizeof(auth_read_params));
+
+ auth_read_params.type = BLE_GATTS_AUTHORIZE_TYPE_READ;
+ auth_read_params.params.read.gatt_status = BLE_GATT_STATUS_SUCCESS;
+ auth_read_params.params.read.offset = p_read_auth->request.read.offset;
+ auth_read_params.params.read.len = sizeof(uint8_t);
+ auth_read_params.params.read.p_data = &p_host->protocol_mode;
+ auth_read_params.params.read.update = 1;
+
+ err_code = sd_ble_gatts_rw_authorize_reply(p_ble_evt->evt.gap_evt.conn_handle,
+ &auth_read_params);
+ BLE_HIDS_ERROR_HANDLE(p_hids, err_code);
+ }
+}
+
+
+/**@brief Function for handling write events to a report CCCD.
+ *
+ * @param[in] p_hids HID Service structure.
+ * @param[in] p_char_id Id of report characteristic.
+ * @param[in] p_ble_evt BLE event received from the BLE stack.
+ */
+static void on_report_cccd_write(ble_hids_t * p_hids,
+ ble_hids_char_id_t * p_char_id,
+ ble_evt_t const * p_ble_evt)
+{
+ ble_gatts_evt_write_t const * p_evt_write = &p_ble_evt->evt.gatts_evt.params.write;
+
+ if (p_evt_write->len == 2)
+ {
+ // CCCD written, update notification state
+ if (p_hids->evt_handler != NULL)
+ {
+ ble_hids_evt_t evt;
+
+ if (ble_srv_is_notification_enabled(p_evt_write->data))
+ {
+ evt.evt_type = BLE_HIDS_EVT_NOTIF_ENABLED;
+ }
+ else
+ {
+ evt.evt_type = BLE_HIDS_EVT_NOTIF_DISABLED;
+ }
+ evt.params.notification.char_id = *p_char_id;
+ evt.p_ble_evt = p_ble_evt;
+
+ p_hids->evt_handler(p_hids, &evt);
+ }
+ }
+}
+
+
+/**@brief Function for handling write events to a report value.
+ *
+ * @param[in] p_hids HID Service structure.
+ * @param[in] p_ble_evt Pointer to BLE event structure.
+ * @param[in] p_char_id Id of report characteristic.
+ * @param[in] rep_offset Offset to the affected HID report data.
+ * @param[in] rep_max_len Maximum HID report length.
+ */
+static void on_report_value_write(ble_hids_t * p_hids,
+ ble_evt_t const * p_ble_evt,
+ ble_hids_char_id_t * p_char_id,
+ uint16_t rep_offset,
+ uint16_t rep_max_len)
+{
+ // Update host's Output Report data
+ ret_code_t err_code;
+ uint8_t * p_report;
+ ble_hids_client_context_t * p_host;
+ ble_gatts_evt_write_t const * p_write = &p_ble_evt->evt.gatts_evt.params.write;
+
+ err_code = blcm_link_ctx_get(p_hids->p_link_ctx_storage,
+ p_ble_evt->evt.gatts_evt.conn_handle,
+ (void *) &p_host);
+ BLE_HIDS_ERROR_HANDLE(p_hids, err_code);
+
+ // Store the written values in host's report data
+ if ((p_host != NULL) && (p_write->len + p_write->offset <= rep_max_len))
+ {
+ p_report = (uint8_t *) p_host + rep_offset;
+ memcpy(p_report, p_write->data, p_write->len);
+ }
+ else
+ {
+ return;
+ }
+
+ // Notify the applicartion
+ if (p_hids->evt_handler != NULL)
+ {
+ ble_hids_evt_t evt;
+
+ evt.evt_type = BLE_HIDS_EVT_REP_CHAR_WRITE;
+ evt.params.char_write.char_id = *p_char_id;
+ evt.params.char_write.offset = p_ble_evt->evt.gatts_evt.params.write.offset;
+ evt.params.char_write.len = p_ble_evt->evt.gatts_evt.params.write.len;
+ evt.params.char_write.data = p_ble_evt->evt.gatts_evt.params.write.data;
+ evt.p_ble_evt = p_ble_evt;
+
+ p_hids->evt_handler(p_hids, &evt);
+ }
+}
+
+
+/**@brief Handle authorize read events to a report value.
+ *
+ * @param[in] p_hids HID Service structure.
+ * @param[in] p_char_id Id of report characteristic.
+ * @param[in] p_ble_evt Pointer to BLE event structure.
+ * @param[in] rep_offset Report data offset.
+ * @param[in] rep_max_len Report maximum length.
+ */
+static void on_report_value_read_auth(ble_hids_t * p_hids,
+ ble_hids_char_id_t * p_char_id,
+ ble_evt_t const * p_ble_evt,
+ uint16_t rep_offset,
+ uint16_t rep_max_len)
+{
+ ble_gatts_rw_authorize_reply_params_t auth_read_params;
+ ble_hids_client_context_t * p_host;
+ uint8_t * p_report;
+ uint16_t read_offset;
+ uint32_t err_code = NRF_SUCCESS;
+
+ err_code = blcm_link_ctx_get(p_hids->p_link_ctx_storage,
+ p_ble_evt->evt.gatts_evt.conn_handle,
+ (void *) &p_host);
+ BLE_HIDS_ERROR_HANDLE(p_hids, err_code);
+
+ // Update Report GATTS table with host's current report data
+ if (p_host != NULL)
+ {
+ read_offset = p_ble_evt->evt.gatts_evt.params.authorize_request.request.read.offset;
+ p_report = (uint8_t *) p_host + rep_offset;
+ memset(&auth_read_params, 0, sizeof(auth_read_params));
+
+ auth_read_params.type = BLE_GATTS_AUTHORIZE_TYPE_READ;
+ auth_read_params.params.read.gatt_status = BLE_GATT_STATUS_SUCCESS;
+ auth_read_params.params.read.offset = read_offset;
+ auth_read_params.params.read.len = rep_max_len - read_offset;
+ auth_read_params.params.read.p_data = p_report + read_offset;
+ auth_read_params.params.read.update = 1;
+
+ err_code = sd_ble_gatts_rw_authorize_reply(p_ble_evt->evt.gap_evt.conn_handle,
+ &auth_read_params);
+
+ BLE_HIDS_ERROR_HANDLE(p_hids, err_code);
+ }
+ else
+ {
+ return;
+ }
+
+ if (p_hids->evt_handler != NULL)
+ {
+ ble_hids_evt_t evt;
+
+ evt.evt_type = BLE_HIDS_EVT_REPORT_READ;
+ evt.params.char_auth_read.char_id = *p_char_id;
+ evt.p_ble_evt = p_ble_evt;
+
+ p_hids->evt_handler(p_hids, &evt);
+ }
+}
+
+
+/**@brief Function for finding the Characteristic Id of a characteristic corresponding to a CCCD handle.
+ *
+ * @param[in] p_hids HID Service structure.
+ * @param[in] handle Handle to search for.
+ * @param[out] p_char_id Id of report characteristic.
+ *
+ * @return TRUE if CCCD handle was found, FALSE otherwise.
+ */
+static bool inp_rep_cccd_identify(ble_hids_t * p_hids,
+ uint16_t handle,
+ ble_hids_char_id_t * p_char_id)
+{
+ uint8_t i;
+
+ for (i = 0; i < p_hids->inp_rep_count; i++)
+ {
+ if (handle == p_hids->inp_rep_array[i].char_handles.cccd_handle)
+ {
+ *p_char_id = make_char_id(BLE_UUID_REPORT_CHAR, BLE_HIDS_REP_TYPE_INPUT, i);
+ return true;
+ }
+ }
+
+ return false;
+}
+
+
+/**@brief Function for finding the Characteristic Id of a characteristic corresponding to a value handle.
+ *
+ * @param[in] p_hids HID Service structure.
+ * @param[in] handle Handle to search for.
+ * @param[out] p_char_id Id of report characteristic.
+ * @param[out] p_context_offset Pointer to offset to the report data within the host data.
+ * @param[out] p_rep_max_len Pointer to maximum report length.
+ *
+ * @return TRUE if value handle was found, FALSE otherwise.
+ */
+static bool rep_value_identify(ble_hids_t * p_hids,
+ uint16_t handle,
+ ble_hids_char_id_t * p_char_id,
+ uint16_t * p_context_offset,
+ uint16_t * p_rep_max_len)
+{
+ uint8_t i;
+
+ /* Initialize the offset with size of non-report-related data */
+ *p_context_offset = sizeof(ble_hids_client_context_t) + BOOT_KB_INPUT_REPORT_MAX_SIZE +
+ BOOT_KB_OUTPUT_REPORT_MAX_SIZE + BOOT_MOUSE_INPUT_REPORT_MAX_SIZE;
+
+ if (p_hids->p_inp_rep_init_array != NULL)
+ {
+ for (i = 0; i < p_hids->inp_rep_count; i++)
+ {
+ if (handle == p_hids->inp_rep_array[i].char_handles.value_handle)
+ {
+ *p_char_id = make_char_id(BLE_UUID_REPORT_CHAR, BLE_HIDS_REP_TYPE_INPUT, i);
+ *p_rep_max_len = p_hids->p_inp_rep_init_array[i].max_len;
+ return true;
+ }
+ *p_context_offset += p_hids->p_inp_rep_init_array[i].max_len;
+ }
+ }
+ if (p_hids->p_outp_rep_init_array != NULL)
+ {
+ for (i = 0; i < p_hids->outp_rep_count; i++)
+ {
+ if (handle == p_hids->outp_rep_array[i].char_handles.value_handle)
+ {
+ *p_char_id = make_char_id(BLE_UUID_REPORT_CHAR, BLE_HIDS_REP_TYPE_OUTPUT, i);
+ *p_rep_max_len = p_hids->p_outp_rep_init_array[i].max_len;
+ return true;
+ }
+ *p_context_offset += p_hids->p_outp_rep_init_array[i].max_len;
+ }
+ }
+ if (p_hids->p_feature_rep_init_array != NULL)
+ {
+ for (i = 0; i < p_hids->feature_rep_count; i++)
+ {
+ if (handle == p_hids->feature_rep_array[i].char_handles.value_handle)
+ {
+ *p_char_id = make_char_id(BLE_UUID_REPORT_CHAR, BLE_HIDS_REP_TYPE_FEATURE, i);
+ *p_rep_max_len = p_hids->p_feature_rep_init_array[i].max_len;
+ return true;
+ }
+ *p_context_offset += p_hids->p_feature_rep_init_array[i].max_len;
+ }
+ }
+
+ return false;
+}
+
+
+/**@brief Function for handling the Write event.
+ *
+ * @param[in] p_hids HID Service structure.
+ * @param[in] p_ble_evt Event received from the BLE stack.
+ */
+static void on_write(ble_hids_t * p_hids, ble_evt_t const * p_ble_evt)
+{
+ ble_hids_char_id_t char_id;
+ ble_gatts_evt_write_t const * p_evt_write = &p_ble_evt->evt.gatts_evt.params.write;
+ uint16_t rep_data_offset = sizeof(ble_hids_client_context_t);
+ uint16_t max_rep_len = 0;
+
+ if (p_evt_write->handle == p_hids->hid_control_point_handles.value_handle)
+ {
+ on_control_point_write(p_hids, p_ble_evt);
+ }
+ else if (p_evt_write->handle == p_hids->protocol_mode_handles.value_handle)
+ {
+ on_protocol_mode_write(p_hids, p_ble_evt);
+ }
+ else if (p_evt_write->handle == p_hids->boot_kb_inp_rep_handles.cccd_handle)
+ {
+ char_id = make_char_id(BLE_UUID_BOOT_KEYBOARD_INPUT_REPORT_CHAR, 0, 0);
+ on_report_cccd_write(p_hids, &char_id, p_ble_evt);
+ }
+ else if (p_evt_write->handle == p_hids->boot_kb_inp_rep_handles.value_handle)
+ {
+ char_id = make_char_id(BLE_UUID_BOOT_KEYBOARD_INPUT_REPORT_CHAR, 0, 0);
+ max_rep_len = BOOT_KB_INPUT_REPORT_MAX_SIZE;
+ on_report_value_write(p_hids, p_ble_evt, &char_id, rep_data_offset, max_rep_len);
+ }
+ else if (p_evt_write->handle == p_hids->boot_kb_outp_rep_handles.value_handle)
+ {
+ char_id = make_char_id(BLE_UUID_BOOT_KEYBOARD_OUTPUT_REPORT_CHAR, 0, 0);
+ rep_data_offset += BOOT_KB_INPUT_REPORT_MAX_SIZE;
+ max_rep_len = BOOT_KB_OUTPUT_REPORT_MAX_SIZE;
+ on_report_value_write(p_hids, p_ble_evt, &char_id, rep_data_offset, max_rep_len);
+ }
+ else if (p_evt_write->handle == p_hids->boot_mouse_inp_rep_handles.cccd_handle)
+ {
+ char_id = make_char_id(BLE_UUID_BOOT_MOUSE_INPUT_REPORT_CHAR, 0, 0);
+ on_report_cccd_write(p_hids, &char_id, p_ble_evt);
+ }
+ else if (p_evt_write->handle == p_hids->boot_mouse_inp_rep_handles.value_handle)
+ {
+ char_id = make_char_id(BLE_UUID_BOOT_MOUSE_INPUT_REPORT_CHAR, 0, 0);
+ rep_data_offset += BOOT_KB_INPUT_REPORT_MAX_SIZE + BOOT_KB_OUTPUT_REPORT_MAX_SIZE;
+ max_rep_len = BOOT_MOUSE_INPUT_REPORT_MAX_SIZE;
+ on_report_value_write(p_hids, p_ble_evt, &char_id, rep_data_offset, max_rep_len);
+ }
+ else if (inp_rep_cccd_identify(p_hids, p_evt_write->handle, &char_id))
+ {
+ on_report_cccd_write(p_hids, &char_id, p_ble_evt);
+ }
+ else if (rep_value_identify(p_hids,
+ p_evt_write->handle,
+ &char_id,
+ &rep_data_offset,
+ &max_rep_len))
+ {
+ on_report_value_write(p_hids, p_ble_evt, &char_id, rep_data_offset, max_rep_len);
+ }
+ else
+ {
+ // No implementation needed.
+ }
+}
+
+
+/**@brief Read/write authorize request event handler.
+ *
+ * @param[in] p_hids HID Service structure.
+ * @param[in] p_ble_evt Event received from the BLE stack.
+ */
+static void on_rw_authorize_request(ble_hids_t * p_hids, ble_evt_t const * p_ble_evt)
+{
+ ble_gatts_evt_rw_authorize_request_t const * evt_rw_auth =
+ &p_ble_evt->evt.gatts_evt.params.authorize_request;
+
+ ble_hids_char_id_t char_id;
+ uint16_t rep_data_offset = sizeof(ble_hids_client_context_t);
+ uint16_t max_rep_len = 0;
+
+ if (evt_rw_auth->type != BLE_GATTS_AUTHORIZE_TYPE_READ)
+ {
+ // Unexpected operation
+ return;
+ }
+
+ /* Update SD GATTS values of appropriate host before SD sends the Read Response */
+ if (evt_rw_auth->request.read.handle == p_hids->protocol_mode_handles.value_handle)
+ {
+ on_protocol_mode_read_auth(p_hids, p_ble_evt);
+ }
+ else if (evt_rw_auth->request.read.handle == p_hids->boot_kb_inp_rep_handles.value_handle)
+ {
+ char_id = make_char_id(BLE_UUID_BOOT_KEYBOARD_INPUT_REPORT_CHAR, 0, 0);
+ max_rep_len = BOOT_KB_INPUT_REPORT_MAX_SIZE;
+ on_report_value_read_auth(p_hids, &char_id, p_ble_evt, rep_data_offset, max_rep_len);
+ }
+ else if (evt_rw_auth->request.read.handle == p_hids->boot_kb_outp_rep_handles.value_handle)
+ {
+ char_id = make_char_id(BLE_UUID_BOOT_KEYBOARD_OUTPUT_REPORT_CHAR, 0, 0);
+ rep_data_offset += BOOT_KB_INPUT_REPORT_MAX_SIZE;
+ max_rep_len = BOOT_KB_OUTPUT_REPORT_MAX_SIZE;
+ on_report_value_read_auth(p_hids, &char_id, p_ble_evt, rep_data_offset, max_rep_len);
+ }
+ else if (evt_rw_auth->request.read.handle == p_hids->boot_mouse_inp_rep_handles.value_handle)
+ {
+ char_id = make_char_id(BLE_UUID_BOOT_MOUSE_INPUT_REPORT_CHAR, 0, 0);
+ rep_data_offset += BOOT_KB_INPUT_REPORT_MAX_SIZE + BOOT_KB_OUTPUT_REPORT_MAX_SIZE;
+ max_rep_len = BOOT_MOUSE_INPUT_REPORT_MAX_SIZE;
+ on_report_value_read_auth(p_hids, &char_id, p_ble_evt, rep_data_offset, max_rep_len);
+ }
+ else if (rep_value_identify(p_hids,
+ evt_rw_auth->request.read.handle,
+ &char_id,
+ &rep_data_offset,
+ &max_rep_len))
+ {
+ on_report_value_read_auth(p_hids, &char_id, p_ble_evt, rep_data_offset, max_rep_len);
+ }
+}
+
+
+void ble_hids_on_ble_evt(ble_evt_t const * p_ble_evt, void * p_context)
+{
+ ble_hids_t * p_hids = (ble_hids_t *) p_context;
+
+ switch (p_ble_evt->header.evt_id)
+ {
+ case BLE_GAP_EVT_CONNECTED:
+ on_connect(p_hids, p_ble_evt);
+ break;
+
+ case BLE_GATTS_EVT_WRITE:
+ on_write(p_hids, p_ble_evt);
+ break;
+
+ case BLE_GATTS_EVT_RW_AUTHORIZE_REQUEST:
+ on_rw_authorize_request(p_hids, p_ble_evt);
+ break;
+
+ default:
+ // No implementation needed.
+ break;
+ }
+}
+
+
+/**@brief Function for adding Protocol Mode characteristics.
+ *
+ * @param[in] p_hids HID Service structure.
+ * @param[in] p_sec_mode Characteristic security settings.
+ *
+ * @return NRF_SUCCESS on success, otherwise an error code.
+ */
+static uint32_t protocol_mode_char_add(ble_hids_t * p_hids,
+ const ble_srv_security_mode_t * p_sec_mode)
+{
+ ble_gatts_char_md_t char_md;
+ ble_gatts_attr_t attr_char_value;
+ ble_uuid_t ble_uuid;
+ ble_gatts_attr_md_t attr_md;
+ uint8_t initial_protocol_mode;
+
+ memset(&char_md, 0, sizeof(char_md));
+
+ char_md.char_props.read = 1;
+ char_md.char_props.write_wo_resp = 1;
+ char_md.p_char_user_desc = NULL;
+ char_md.p_char_pf = NULL;
+ char_md.p_user_desc_md = NULL;
+ char_md.p_cccd_md = NULL;
+ char_md.p_sccd_md = NULL;
+
+ BLE_UUID_BLE_ASSIGN(ble_uuid, BLE_UUID_PROTOCOL_MODE_CHAR);
+
+ memset(&attr_md, 0, sizeof(attr_md));
+
+ attr_md.read_perm = p_sec_mode->read_perm;
+ attr_md.write_perm = p_sec_mode->write_perm;
+ attr_md.vloc = BLE_GATTS_VLOC_STACK;
+ attr_md.rd_auth = 1;
+ attr_md.wr_auth = 0;
+ attr_md.vlen = 0;
+
+ memset(&attr_char_value, 0, sizeof(attr_char_value));
+
+ initial_protocol_mode = DEFAULT_PROTOCOL_MODE;
+
+ attr_char_value.p_uuid = &ble_uuid;
+ attr_char_value.p_attr_md = &attr_md;
+ attr_char_value.init_len = sizeof(uint8_t);
+ attr_char_value.init_offs = 0;
+ attr_char_value.max_len = sizeof(uint8_t);
+ attr_char_value.p_value = &initial_protocol_mode;
+
+ return sd_ble_gatts_characteristic_add(p_hids->service_handle,
+ &char_md,
+ &attr_char_value,
+ &p_hids->protocol_mode_handles);
+}
+
+
+/**@brief Function for adding report characteristics.
+ *
+ * @param[in] p_hids HID Service structure.
+ * @param[in] p_properties Report characteristic properties.
+ * @param[in] max_len Maximum length of report value.
+ * @param[in] p_rep_ref Report Reference descriptor.
+ * @param[in] p_rep_ref_attr_md Characteristic security settings.
+ * @param[in] is_read_resp Characteristic read authorization.
+ * @param[out] p_rep_char Handles of new characteristic.
+ *
+ * @return NRF_SUCCESS on success, otherwise an error code.
+ */
+static uint32_t rep_char_add(ble_hids_t * p_hids,
+ ble_gatt_char_props_t * p_properties,
+ uint16_t max_len,
+ ble_srv_report_ref_t const * p_rep_ref,
+ ble_srv_cccd_security_mode_t const * p_rep_ref_attr_md,
+ bool is_read_resp,
+ ble_hids_rep_char_t * p_rep_char)
+{
+ uint32_t err_code;
+ ble_gatts_char_md_t char_md;
+ ble_gatts_attr_md_t cccd_md;
+ ble_gatts_attr_t attr_char_value;
+ ble_uuid_t ble_uuid;
+ ble_gatts_attr_md_t attr_md;
+ uint8_t encoded_rep_ref[BLE_SRV_ENCODED_REPORT_REF_LEN];
+
+ // Add Report characteristic
+ if (p_properties->notify)
+ {
+ memset(&cccd_md, 0, sizeof(cccd_md));
+ BLE_GAP_CONN_SEC_MODE_SET_OPEN(&cccd_md.read_perm);
+ cccd_md.write_perm = p_rep_ref_attr_md->cccd_write_perm;
+ cccd_md.vloc = BLE_GATTS_VLOC_STACK;
+ }
+
+ memset(&char_md, 0, sizeof(char_md));
+
+ char_md.char_props = *p_properties;
+ char_md.p_char_user_desc = NULL;
+ char_md.p_char_pf = NULL;
+ char_md.p_user_desc_md = NULL;
+ char_md.p_cccd_md = (p_properties->notify) ? &cccd_md : NULL;
+ char_md.p_sccd_md = NULL;
+
+ BLE_UUID_BLE_ASSIGN(ble_uuid, BLE_UUID_REPORT_CHAR);
+
+ memset(&attr_md, 0, sizeof(attr_md));
+
+ attr_md.read_perm = p_rep_ref_attr_md->read_perm;
+ attr_md.write_perm = p_rep_ref_attr_md->write_perm;
+ attr_md.vloc = BLE_GATTS_VLOC_STACK;
+ attr_md.rd_auth = is_read_resp ? 1 : 0;
+ attr_md.wr_auth = 0;
+ attr_md.vlen = 1;
+
+ memset(&attr_char_value, 0, sizeof(attr_char_value));
+
+ attr_char_value.p_uuid = &ble_uuid;
+ attr_char_value.p_attr_md = &attr_md;
+ attr_char_value.init_len = 0;
+ attr_char_value.init_offs = 0;
+ attr_char_value.max_len = max_len;
+ attr_char_value.p_value = NULL;
+
+ err_code = sd_ble_gatts_characteristic_add(p_hids->service_handle,
+ &char_md,
+ &attr_char_value,
+ &p_rep_char->char_handles);
+ if (err_code != NRF_SUCCESS)
+ {
+ return err_code;
+ }
+
+ // Add Report Reference descriptor
+ BLE_UUID_BLE_ASSIGN(ble_uuid, BLE_UUID_REPORT_REF_DESCR);
+
+ memset(&attr_md, 0, sizeof(attr_md));
+
+ attr_md.read_perm = p_rep_ref_attr_md->read_perm;
+ attr_md.write_perm = p_rep_ref_attr_md->write_perm;
+ attr_md.vloc = BLE_GATTS_VLOC_STACK;
+ attr_md.rd_auth = 0;
+ attr_md.wr_auth = 0;
+ attr_md.vlen = 0;
+
+ memset(&attr_char_value, 0, sizeof(attr_char_value));
+
+ attr_char_value.p_uuid = &ble_uuid;
+ attr_char_value.p_attr_md = &attr_md;
+ attr_char_value.init_len = ble_srv_report_ref_encode(encoded_rep_ref, p_rep_ref);
+ attr_char_value.init_offs = 0;
+ attr_char_value.max_len = attr_char_value.init_len;
+ attr_char_value.p_value = encoded_rep_ref;
+
+ return sd_ble_gatts_descriptor_add(p_rep_char->char_handles.value_handle,
+ &attr_char_value,
+ &p_rep_char->ref_handle);
+}
+
+
+/**@brief Function for adding Report Map characteristics.
+ *
+ * @param[in] p_hids HID Service structure.
+ * @param[in] p_hids_init Service initialization structure.
+ *
+ * @return NRF_SUCCESS on success, otherwise an error code.
+ */
+static uint32_t rep_map_char_add(ble_hids_t * p_hids, const ble_hids_init_t * p_hids_init)
+{
+ uint32_t err_code;
+ ble_gatts_char_md_t char_md;
+ ble_gatts_attr_t attr_char_value;
+ ble_uuid_t ble_uuid;
+ ble_gatts_attr_md_t attr_md;
+
+ // Add Report Map characteristic
+ memset(&char_md, 0, sizeof(char_md));
+
+ char_md.char_props.read = 1;
+ char_md.p_char_user_desc = NULL;
+ char_md.p_char_pf = NULL;
+ char_md.p_user_desc_md = NULL;
+ char_md.p_cccd_md = NULL;
+ char_md.p_sccd_md = NULL;
+
+ BLE_UUID_BLE_ASSIGN(ble_uuid, BLE_UUID_REPORT_MAP_CHAR);
+
+ memset(&attr_md, 0, sizeof(attr_md));
+
+ attr_md.read_perm = p_hids_init->rep_map.security_mode.read_perm;
+ attr_md.write_perm = p_hids_init->rep_map.security_mode.write_perm;
+ attr_md.vloc = BLE_GATTS_VLOC_STACK;
+ attr_md.rd_auth = 0;
+ attr_md.wr_auth = 0;
+ attr_md.vlen = 1;
+
+ memset(&attr_char_value, 0, sizeof(attr_char_value));
+
+ attr_char_value.p_uuid = &ble_uuid;
+ attr_char_value.p_attr_md = &attr_md;
+ attr_char_value.init_len = p_hids_init->rep_map.data_len;
+ attr_char_value.init_offs = 0;
+ attr_char_value.max_len = p_hids_init->rep_map.data_len;
+ attr_char_value.p_value = p_hids_init->rep_map.p_data;
+
+ err_code = sd_ble_gatts_characteristic_add(p_hids->service_handle,
+ &char_md,
+ &attr_char_value,
+ &p_hids->rep_map_handles);
+ if (err_code != NRF_SUCCESS)
+ {
+ return err_code;
+ }
+
+ if (p_hids_init->rep_map.ext_rep_ref_num != 0 && p_hids_init->rep_map.p_ext_rep_ref == NULL)
+ {
+ return NRF_ERROR_INVALID_PARAM;
+ }
+
+ for (int i = 0; i < p_hids_init->rep_map.ext_rep_ref_num; ++i)
+ {
+ uint8_t encoded_rep_ref[sizeof(ble_uuid128_t)];
+ uint8_t encoded_rep_ref_len;
+
+ // Add External Report Reference descriptor
+ BLE_UUID_BLE_ASSIGN(ble_uuid, BLE_UUID_EXTERNAL_REPORT_REF_DESCR);
+
+ memset(&attr_md, 0, sizeof(attr_md));
+
+ BLE_GAP_CONN_SEC_MODE_SET_ENC_NO_MITM(&attr_md.read_perm);
+ BLE_GAP_CONN_SEC_MODE_SET_NO_ACCESS(&attr_md.write_perm);
+
+ attr_md.vloc = BLE_GATTS_VLOC_STACK;
+ attr_md.rd_auth = 0;
+ attr_md.wr_auth = 0;
+ attr_md.vlen = 0;
+
+ err_code = sd_ble_uuid_encode(&p_hids_init->rep_map.p_ext_rep_ref[i],
+ &encoded_rep_ref_len,
+ encoded_rep_ref);
+ if (err_code != NRF_SUCCESS)
+ {
+ return err_code;
+ }
+
+ memset(&attr_char_value, 0, sizeof(attr_char_value));
+
+ attr_char_value.p_uuid = &ble_uuid;
+ attr_char_value.p_attr_md = &attr_md;
+ attr_char_value.init_len = encoded_rep_ref_len;
+ attr_char_value.init_offs = 0;
+ attr_char_value.max_len = attr_char_value.init_len;
+ attr_char_value.p_value = encoded_rep_ref;
+
+ err_code = sd_ble_gatts_descriptor_add(p_hids->rep_map_handles.value_handle,
+ &attr_char_value,
+ &p_hids->rep_map_ext_rep_ref_handle);
+ if (err_code != NRF_SUCCESS)
+ {
+ return err_code;
+ }
+ }
+
+ return NRF_SUCCESS;
+}
+
+
+/**@brief Function for adding Input Report characteristics.
+ *
+ * @param[in] p_hids HID Service structure.
+ * @param[in] uuid UUID of report characteristic to be added.
+ * @param[in] max_data_len Maximum length of report value.
+ * @param[in] p_sec_mode Characteristic security settings.
+ * @param[out] p_char_handles Handles of new characteristic.
+ *
+ * @return NRF_SUCCESS on success, otherwise an error code.
+ */
+static uint32_t boot_inp_rep_char_add(ble_hids_t * p_hids,
+ uint16_t uuid,
+ uint16_t max_data_len,
+ const ble_srv_cccd_security_mode_t * p_sec_mode,
+ ble_gatts_char_handles_t * p_char_handles)
+{
+ ble_gatts_char_md_t char_md;
+ ble_gatts_attr_md_t cccd_md;
+ ble_gatts_attr_t attr_char_value;
+ ble_uuid_t ble_uuid;
+ ble_gatts_attr_md_t attr_md;
+
+ memset(&cccd_md, 0, sizeof(cccd_md));
+
+ BLE_GAP_CONN_SEC_MODE_SET_OPEN(&cccd_md.read_perm);
+ cccd_md.write_perm = p_sec_mode->cccd_write_perm;
+ cccd_md.vloc = BLE_GATTS_VLOC_STACK;
+
+ memset(&char_md, 0, sizeof(char_md));
+
+ char_md.char_props.read = 1;
+ char_md.char_props.write = (p_sec_mode->write_perm.sm) ? 1 : 0;
+ char_md.char_props.notify = 1;
+ char_md.p_char_user_desc = NULL;
+ char_md.p_char_pf = NULL;
+ char_md.p_user_desc_md = NULL;
+ char_md.p_cccd_md = &cccd_md;
+ char_md.p_sccd_md = NULL;
+
+ BLE_UUID_BLE_ASSIGN(ble_uuid, uuid);
+
+ memset(&attr_md, 0, sizeof(attr_md));
+
+ attr_md.read_perm = p_sec_mode->read_perm;
+ attr_md.write_perm = p_sec_mode->write_perm;
+ attr_md.vloc = BLE_GATTS_VLOC_STACK;
+ attr_md.rd_auth = 1;
+ attr_md.wr_auth = 0;
+ attr_md.vlen = 0;
+
+ memset(&attr_char_value, 0, sizeof(attr_char_value));
+
+ attr_char_value.p_uuid = &ble_uuid;
+ attr_char_value.p_attr_md = &attr_md;
+ attr_char_value.init_len = 0;
+ attr_char_value.init_offs = 0;
+ attr_char_value.max_len = max_data_len;
+ attr_char_value.p_value = NULL;
+
+ return sd_ble_gatts_characteristic_add(p_hids->service_handle,
+ &char_md,
+ &attr_char_value,
+ p_char_handles);
+}
+
+
+/**@brief Function for adding Boot Keyboard Output Report characteristics.
+ *
+ * @param[in] p_hids HID Service structure.
+ * @param[in] p_hids_init Service initialization structure.
+ *
+ * @return NRF_SUCCESS on success, otherwise an error code.
+ */
+static uint32_t boot_kb_outp_rep_char_add(ble_hids_t * p_hids, const ble_hids_init_t * p_hids_init)
+{
+ ble_gatts_char_md_t char_md;
+ ble_gatts_attr_t attr_char_value;
+ ble_uuid_t ble_uuid;
+ ble_gatts_attr_md_t attr_md;
+
+ memset(&char_md, 0, sizeof(char_md));
+
+ char_md.char_props.read = 1;
+ char_md.char_props.write = 1;
+ char_md.char_props.write_wo_resp = 1;
+ char_md.p_char_user_desc = NULL;
+ char_md.p_char_pf = NULL;
+ char_md.p_user_desc_md = NULL;
+ char_md.p_cccd_md = NULL;
+ char_md.p_sccd_md = NULL;
+
+ BLE_UUID_BLE_ASSIGN(ble_uuid, BLE_UUID_BOOT_KEYBOARD_OUTPUT_REPORT_CHAR);
+
+ memset(&attr_md, 0, sizeof(attr_md));
+
+ attr_md.read_perm = p_hids_init->security_mode_boot_kb_outp_rep.read_perm;
+ attr_md.write_perm = p_hids_init->security_mode_boot_kb_outp_rep.write_perm;
+ attr_md.vloc = BLE_GATTS_VLOC_STACK;
+ attr_md.rd_auth = 1;
+ attr_md.wr_auth = 0;
+ attr_md.vlen = 0;
+
+ memset(&attr_char_value, 0, sizeof(attr_char_value));
+
+ attr_char_value.p_uuid = &ble_uuid;
+ attr_char_value.p_attr_md = &attr_md;
+ attr_char_value.init_len = 0;
+ attr_char_value.init_offs = 0;
+ attr_char_value.max_len = BOOT_KB_OUTPUT_REPORT_MAX_SIZE;
+ attr_char_value.p_value = NULL;
+
+ return sd_ble_gatts_characteristic_add(p_hids->service_handle, &char_md, &attr_char_value,
+ &p_hids->boot_kb_outp_rep_handles);
+}
+
+
+/**@brief Function for encoding a HID Information characteristic value.
+ *
+ * @param[out] p_encoded_buffer Buffer where the encoded data will be written.
+ * @param[in] p_hid_information Measurement to be encoded.
+ *
+ * @return Size of encoded data.
+ */
+static uint8_t encode_hid_information(uint8_t * p_encoded_buffer,
+ const ble_hids_hid_information_t * p_hid_information)
+{
+ uint8_t len = uint16_encode(p_hid_information->bcd_hid, p_encoded_buffer);
+
+ p_encoded_buffer[len++] = p_hid_information->b_country_code;
+ p_encoded_buffer[len++] = p_hid_information->flags;
+
+ APP_ERROR_CHECK_BOOL(len == ENCODED_HID_INFORMATION_LEN);
+
+ return len;
+}
+
+
+/**@brief Function for adding HID Information characteristics.
+ *
+ * @param[in] p_hids HID Service structure.
+ * @param[in] p_hids_init Service initialization structure.
+ *
+ * @return NRF_SUCCESS on success, otherwise an error code.
+ */
+static uint32_t hid_information_char_add(ble_hids_t * p_hids, const ble_hids_init_t * p_hids_init)
+{
+ ble_gatts_char_md_t char_md;
+ ble_gatts_attr_t attr_char_value;
+ ble_uuid_t ble_uuid;
+ ble_gatts_attr_md_t attr_md;
+ uint8_t encoded_hid_information[ENCODED_HID_INFORMATION_LEN];
+ uint8_t hid_info_len;
+
+ memset(&char_md, 0, sizeof(char_md));
+
+ char_md.char_props.read = 1;
+ char_md.p_char_user_desc = NULL;
+ char_md.p_char_pf = NULL;
+ char_md.p_user_desc_md = NULL;
+ char_md.p_cccd_md = NULL;
+ char_md.p_sccd_md = NULL;
+
+ BLE_UUID_BLE_ASSIGN(ble_uuid, BLE_UUID_HID_INFORMATION_CHAR);
+
+ memset(&attr_md, 0, sizeof(attr_md));
+
+ attr_md.read_perm = p_hids_init->hid_information.security_mode.read_perm;
+ attr_md.write_perm = p_hids_init->hid_information.security_mode.write_perm;
+ attr_md.vloc = BLE_GATTS_VLOC_STACK;
+ attr_md.rd_auth = 0;
+ attr_md.wr_auth = 0;
+ attr_md.vlen = 0;
+
+ hid_info_len = encode_hid_information(encoded_hid_information, &p_hids_init->hid_information);
+
+ memset(&attr_char_value, 0, sizeof(attr_char_value));
+
+ attr_char_value.p_uuid = &ble_uuid;
+ attr_char_value.p_attr_md = &attr_md;
+ attr_char_value.init_len = hid_info_len;
+ attr_char_value.init_offs = 0;
+ attr_char_value.max_len = attr_char_value.init_len;
+ attr_char_value.p_value = encoded_hid_information;
+
+ return sd_ble_gatts_characteristic_add(p_hids->service_handle, &char_md,
+ &attr_char_value,
+ &p_hids->hid_information_handles);
+}
+
+
+/**@brief Function for adding HID Control Point characteristics.
+ *
+ * @param[in] p_hids HID Service structure.
+ * @param[in] p_sec_mode Characteristic security settings.
+ *
+ * @return NRF_SUCCESS on success, otherwise an error code.
+ */
+static uint32_t hid_control_point_char_add(ble_hids_t * p_hids,
+ const ble_srv_security_mode_t * p_sec_mode)
+{
+ ble_gatts_char_md_t char_md;
+ ble_gatts_attr_t attr_char_value;
+ ble_uuid_t ble_uuid;
+ ble_gatts_attr_md_t attr_md;
+ uint8_t initial_hid_control_point;
+
+ memset(&char_md, 0, sizeof(char_md));
+
+ char_md.char_props.write_wo_resp = 1;
+ char_md.p_char_user_desc = NULL;
+ char_md.p_char_pf = NULL;
+ char_md.p_user_desc_md = NULL;
+ char_md.p_cccd_md = NULL;
+ char_md.p_sccd_md = NULL;
+
+ BLE_UUID_BLE_ASSIGN(ble_uuid, BLE_UUID_HID_CONTROL_POINT_CHAR);
+
+ memset(&attr_md, 0, sizeof(attr_md));
+
+ attr_md.read_perm = p_sec_mode->read_perm;
+ attr_md.write_perm = p_sec_mode->write_perm;
+ attr_md.vloc = BLE_GATTS_VLOC_STACK;
+ attr_md.rd_auth = 0;
+ attr_md.wr_auth = 0;
+ attr_md.vlen = 0;
+
+ initial_hid_control_point = INITIAL_VALUE_HID_CONTROL_POINT;
+
+ memset(&attr_char_value, 0, sizeof(attr_char_value));
+
+ attr_char_value.p_uuid = &ble_uuid;
+ attr_char_value.p_attr_md = &attr_md;
+ attr_char_value.init_len = sizeof(uint8_t);
+ attr_char_value.init_offs = 0;
+ attr_char_value.max_len = sizeof(uint8_t);
+ attr_char_value.p_value = &initial_hid_control_point;
+
+ return sd_ble_gatts_characteristic_add(p_hids->service_handle, &char_md,
+ &attr_char_value,
+ &p_hids->hid_control_point_handles);
+}
+
+
+/**@brief Function for adding input report characteristics.
+ *
+ * @param[in] p_hids HID Service structure.
+ * @param[in] p_hids_init Service initialization structure.
+ *
+ * @return NRF_SUCCESS on success, otherwise an error code.
+ */
+static uint32_t inp_rep_characteristics_add(ble_hids_t * p_hids,
+ const ble_hids_init_t * p_hids_init)
+{
+ if ((p_hids_init->inp_rep_count != 0) && (p_hids_init->p_inp_rep_array != NULL))
+ {
+ uint8_t i;
+
+ for (i = 0; i < p_hids_init->inp_rep_count; i++)
+ {
+ uint32_t err_code;
+ ble_hids_inp_rep_init_t const * p_rep_init = &p_hids_init->p_inp_rep_array[i];
+ ble_gatt_char_props_t properties;
+
+ memset(&properties, 0, sizeof(properties));
+
+ properties.read = true;
+ properties.write = p_rep_init->security_mode.write_perm.sm ? 1 : 0;
+ properties.notify = true;
+
+ err_code = rep_char_add(p_hids,
+ &properties,
+ p_rep_init->max_len,
+ &p_rep_init->rep_ref,
+ &p_rep_init->security_mode,
+ 1,
+ &p_hids->inp_rep_array[i]);
+ if (err_code != NRF_SUCCESS)
+ {
+ return err_code;
+ }
+ }
+ }
+
+ return NRF_SUCCESS;
+}
+
+
+/**@brief Function for adding output report characteristics.
+ *
+ * @param[in] p_hids HID Service structure.
+ * @param[in] p_hids_init Service initialization structure.
+ *
+ * @return NRF_SUCCESS on success, otherwise an error code.
+ */
+static uint32_t outp_rep_characteristics_add(ble_hids_t * p_hids,
+ const ble_hids_init_t * p_hids_init)
+{
+ if ((p_hids_init->outp_rep_count != 0) && (p_hids_init->p_outp_rep_array != NULL))
+ {
+ uint8_t i;
+
+ for (i = 0; i < p_hids_init->outp_rep_count; i++)
+ {
+ uint32_t err_code;
+ ble_hids_outp_rep_init_t const * p_rep_init = &p_hids_init->p_outp_rep_array[i];
+ ble_gatt_char_props_t properties;
+
+ memset(&properties, 0, sizeof(properties));
+
+ properties.read = true;
+ properties.write = true;
+ properties.write_wo_resp = true;
+
+ err_code = rep_char_add(p_hids,
+ &properties,
+ p_rep_init->max_len,
+ &p_rep_init->rep_ref,
+ &p_rep_init->security_mode,
+ 1,
+ &p_hids->outp_rep_array[i]);
+ if (err_code != NRF_SUCCESS)
+ {
+ return err_code;
+ }
+ }
+ }
+
+ return NRF_SUCCESS;
+}
+
+
+/**@brief Function for adding feature report characteristics.
+ *
+ * @param[in] p_hids HID Service structure.
+ * @param[in] p_hids_init Service initialization structure.
+ *
+ * @return NRF_SUCCESS on success, otherwise an error code.
+ */
+static uint32_t feature_rep_characteristics_add(ble_hids_t * p_hids,
+ const ble_hids_init_t * p_hids_init)
+{
+ if ((p_hids_init->feature_rep_count != 0) && (p_hids_init->p_feature_rep_array != NULL))
+ {
+ uint8_t i;
+
+ for (i = 0; i < p_hids_init->feature_rep_count; i++)
+ {
+ uint32_t err_code;
+ ble_hids_feature_rep_init_t const * p_rep_init = &p_hids_init->p_feature_rep_array[i];
+ ble_gatt_char_props_t properties;
+
+ memset(&properties, 0, sizeof(properties));
+
+ properties.read = true;
+ properties.write = true;
+
+ err_code = rep_char_add(p_hids,
+ &properties,
+ p_rep_init->max_len,
+ &p_rep_init->rep_ref,
+ &p_rep_init->security_mode,
+ 1,
+ &p_hids->feature_rep_array[i]);
+ if (err_code != NRF_SUCCESS)
+ {
+ return err_code;
+ }
+ }
+ }
+
+ return NRF_SUCCESS;
+}
+
+
+/**@brief Function for adding included services.
+ *
+ * @param[in] p_hids HID Service structure.
+ * @param[in] p_hids_init Service initialization structure.
+ *
+ * @return NRF_SUCCESS on success, otherwise an error code.
+ */
+static uint32_t includes_add(ble_hids_t * p_hids, const ble_hids_init_t * p_hids_init)
+{
+ uint32_t err_code;
+ uint8_t i;
+ uint16_t unused_include_handle;
+
+ for (i = 0; i < p_hids_init->included_services_count; i++)
+ {
+ err_code = sd_ble_gatts_include_add(p_hids->service_handle,
+ p_hids_init->p_included_services_array[i],
+ &unused_include_handle);
+ if (err_code != NRF_SUCCESS)
+ {
+ return err_code;
+ }
+ }
+
+ return NRF_SUCCESS;
+}
+
+
+uint32_t ble_hids_init(ble_hids_t * p_hids, const ble_hids_init_t * p_hids_init)
+{
+ uint32_t err_code;
+ ble_uuid_t ble_uuid;
+
+ if ((p_hids_init->inp_rep_count > BLE_HIDS_MAX_INPUT_REP) ||
+ (p_hids_init->outp_rep_count > BLE_HIDS_MAX_OUTPUT_REP) ||
+ (p_hids_init->feature_rep_count > BLE_HIDS_MAX_FEATURE_REP)
+ )
+ {
+ return NRF_ERROR_INVALID_PARAM;
+ }
+
+ // Initialize service structure.
+ p_hids->evt_handler = p_hids_init->evt_handler;
+ p_hids->error_handler = p_hids_init->error_handler;
+ p_hids->inp_rep_count = p_hids_init->inp_rep_count;
+ p_hids->outp_rep_count = p_hids_init->outp_rep_count;
+ p_hids->feature_rep_count = p_hids_init->feature_rep_count;
+
+ // Add service.
+ BLE_UUID_BLE_ASSIGN(ble_uuid, BLE_UUID_HUMAN_INTERFACE_DEVICE_SERVICE);
+
+ err_code = sd_ble_gatts_service_add(BLE_GATTS_SRVC_TYPE_PRIMARY,
+ &ble_uuid,
+ &p_hids->service_handle);
+ if (err_code != NRF_SUCCESS)
+ {
+ return err_code;
+ }
+
+ // Add includes.
+ err_code = includes_add(p_hids, p_hids_init);
+ if (err_code != NRF_SUCCESS)
+ {
+ return err_code;
+ }
+
+ if (p_hids_init->is_kb || p_hids_init->is_mouse)
+ {
+ // Add Protocol Mode characteristic.
+ err_code = protocol_mode_char_add(p_hids, &p_hids_init->security_mode_protocol);
+ if (err_code != NRF_SUCCESS)
+ {
+ return err_code;
+ }
+ }
+
+ // Add Input Report characteristics (if any).
+ err_code = inp_rep_characteristics_add(p_hids, p_hids_init);
+ if (err_code != NRF_SUCCESS)
+ {
+ return err_code;
+ }
+
+ // Add Output Report characteristics (if any).
+ err_code = outp_rep_characteristics_add(p_hids, p_hids_init);
+ if (err_code != NRF_SUCCESS)
+ {
+ return err_code;
+ }
+
+ // Add Feature Report characteristic (if any).
+ err_code = feature_rep_characteristics_add(p_hids, p_hids_init);
+ if (err_code != NRF_SUCCESS)
+ {
+ return err_code;
+ }
+
+ // Add Report Map characteristic.
+ err_code = rep_map_char_add(p_hids, p_hids_init);
+ if (err_code != NRF_SUCCESS)
+ {
+ return err_code;
+ }
+
+ if (p_hids_init->is_kb)
+ {
+ // Add Boot Keyboard Input Report characteristic.
+ err_code = boot_inp_rep_char_add(p_hids,
+ BLE_UUID_BOOT_KEYBOARD_INPUT_REPORT_CHAR,
+ BOOT_KB_INPUT_REPORT_MAX_SIZE,
+ &p_hids_init->security_mode_boot_kb_inp_rep,
+ &p_hids->boot_kb_inp_rep_handles);
+ if (err_code != NRF_SUCCESS)
+ {
+ return err_code;
+ }
+
+ // Add Boot Keyboard Output Report characteristic.
+ err_code = boot_kb_outp_rep_char_add(p_hids, p_hids_init);
+ if (err_code != NRF_SUCCESS)
+ {
+ return err_code;
+ }
+ }
+
+ if (p_hids_init->is_mouse)
+ {
+ // Add Boot Mouse Input Report characteristic.
+ err_code = boot_inp_rep_char_add(p_hids,
+ BLE_UUID_BOOT_MOUSE_INPUT_REPORT_CHAR,
+ BOOT_MOUSE_INPUT_REPORT_MAX_SIZE,
+ &p_hids_init->security_mode_boot_mouse_inp_rep,
+ &p_hids->boot_mouse_inp_rep_handles);
+ if (err_code != NRF_SUCCESS)
+ {
+ return err_code;
+ }
+ }
+
+ // Add HID Information characteristic.
+ err_code = hid_information_char_add(p_hids, p_hids_init);
+ if (err_code != NRF_SUCCESS)
+ {
+ return err_code;
+ }
+
+ // Add HID Control Point characteristic.
+ err_code = hid_control_point_char_add(p_hids, &p_hids_init->security_mode_ctrl_point);
+ if (err_code != NRF_SUCCESS)
+ {
+ return err_code;
+ }
+
+ // Set pointers to user-defined report arrays
+ p_hids->p_inp_rep_init_array = p_hids_init->p_inp_rep_array;
+ p_hids->p_outp_rep_init_array = p_hids_init->p_outp_rep_array;
+ p_hids->p_feature_rep_init_array = p_hids_init->p_feature_rep_array;
+
+ return err_code;
+}
+
+
+uint32_t ble_hids_inp_rep_send(ble_hids_t * p_hids,
+ uint8_t rep_index,
+ uint16_t len,
+ uint8_t * p_data,
+ uint16_t conn_handle)
+{
+ uint32_t err_code;
+
+ if (rep_index < p_hids->inp_rep_count)
+ {
+ ble_hids_rep_char_t * p_rep_char = &p_hids->inp_rep_array[rep_index];
+
+ if (conn_handle != BLE_CONN_HANDLE_INVALID)
+ {
+ ble_gatts_hvx_params_t hvx_params;
+ uint8_t index = 0;
+ uint16_t hvx_len = len;
+ uint8_t * p_host_rep_data;
+
+ err_code = blcm_link_ctx_get(p_hids->p_link_ctx_storage,
+ conn_handle,
+ (void *) &p_host_rep_data);
+ VERIFY_SUCCESS(err_code);
+
+ if (p_host_rep_data != NULL)
+ {
+ p_host_rep_data += sizeof(ble_hids_client_context_t) + BOOT_KB_INPUT_REPORT_MAX_SIZE +
+ BOOT_KB_OUTPUT_REPORT_MAX_SIZE + BOOT_MOUSE_INPUT_REPORT_MAX_SIZE;
+ }
+ else
+ {
+ return NRF_ERROR_NOT_FOUND;
+ }
+
+ // Store the new report data in host's context
+ while (index < rep_index)
+ {
+ p_host_rep_data += p_hids->p_inp_rep_init_array[index].max_len;
+ ++index;
+ }
+
+ if (len <= p_hids->p_inp_rep_init_array[rep_index].max_len)
+ {
+ memcpy(p_host_rep_data, p_data, len);
+ }
+ else
+ {
+ return NRF_ERROR_DATA_SIZE;
+ }
+
+ // Notify host
+ memset(&hvx_params, 0, sizeof(hvx_params));
+
+ hvx_params.handle = p_rep_char->char_handles.value_handle;
+ hvx_params.type = BLE_GATT_HVX_NOTIFICATION;
+ hvx_params.offset = 0;
+ hvx_params.p_len = &hvx_len;
+ hvx_params.p_data = p_data;
+
+ err_code = sd_ble_gatts_hvx(conn_handle, &hvx_params);
+ if ((err_code == NRF_SUCCESS) && (hvx_len != len))
+ {
+ err_code = NRF_ERROR_DATA_SIZE;
+ }
+ }
+ else
+ {
+ err_code = NRF_ERROR_INVALID_STATE;
+ }
+ }
+ else
+ {
+ err_code = NRF_ERROR_INVALID_PARAM;
+ }
+
+ return err_code;
+}
+
+
+uint32_t ble_hids_boot_kb_inp_rep_send(ble_hids_t * p_hids,
+ uint16_t len,
+ uint8_t * p_data,
+ uint16_t conn_handle)
+{
+ uint32_t err_code;
+
+ if (conn_handle != BLE_CONN_HANDLE_INVALID)
+ {
+ ble_gatts_hvx_params_t hvx_params;
+ uint16_t hvx_len = len;
+ uint8_t * p_host_rep_data;
+
+ err_code = blcm_link_ctx_get(p_hids->p_link_ctx_storage,
+ conn_handle,
+ (void *) &p_host_rep_data);
+ VERIFY_SUCCESS(err_code);
+
+ if (p_host_rep_data != NULL)
+ {
+ p_host_rep_data += sizeof(ble_hids_client_context_t);
+ }
+ else
+ {
+ return NRF_ERROR_NOT_FOUND;
+ }
+
+ // Store the new value in the host's context
+ if (len <= BOOT_KB_INPUT_REPORT_MAX_SIZE)
+ {
+ memcpy(p_host_rep_data, p_data, len);
+ }
+
+ // Notify host
+ memset(&hvx_params, 0, sizeof(hvx_params));
+
+ hvx_params.handle = p_hids->boot_kb_inp_rep_handles.value_handle;
+ hvx_params.type = BLE_GATT_HVX_NOTIFICATION;
+ hvx_params.offset = 0;
+ hvx_params.p_len = &hvx_len;
+ hvx_params.p_data = p_data;
+
+ err_code = sd_ble_gatts_hvx(conn_handle, &hvx_params);
+ if ((err_code == NRF_SUCCESS) && (hvx_len != len))
+ {
+ err_code = NRF_ERROR_DATA_SIZE;
+ }
+ }
+ else
+ {
+ err_code = NRF_ERROR_INVALID_STATE;
+ }
+
+ return err_code;
+}
+
+
+uint32_t ble_hids_boot_mouse_inp_rep_send(ble_hids_t * p_hids,
+ uint8_t buttons,
+ int8_t x_delta,
+ int8_t y_delta,
+ uint16_t optional_data_len,
+ uint8_t * p_optional_data,
+ uint16_t conn_handle)
+{
+ uint32_t err_code;
+
+ if (conn_handle != BLE_CONN_HANDLE_INVALID)
+ {
+ uint16_t hvx_len = BOOT_MOUSE_INPUT_REPORT_MIN_SIZE + optional_data_len;
+
+ if (hvx_len <= BOOT_MOUSE_INPUT_REPORT_MAX_SIZE)
+ {
+ uint8_t buffer[BOOT_MOUSE_INPUT_REPORT_MAX_SIZE];
+ ble_gatts_hvx_params_t hvx_params;
+ uint8_t * p_host_rep_data;
+
+ err_code = blcm_link_ctx_get(p_hids->p_link_ctx_storage,
+ conn_handle,
+ (void *) &p_host_rep_data);
+ VERIFY_SUCCESS(err_code);
+
+ if (p_host_rep_data != NULL)
+ {
+ p_host_rep_data += sizeof(ble_hids_client_context_t) + BOOT_KB_INPUT_REPORT_MAX_SIZE +
+ BOOT_KB_OUTPUT_REPORT_MAX_SIZE;
+ }
+ else
+ {
+ return NRF_ERROR_NOT_FOUND;
+ }
+
+ APP_ERROR_CHECK_BOOL(BOOT_MOUSE_INPUT_REPORT_MIN_SIZE == 3);
+
+ // Build buffer
+ buffer[0] = buttons;
+ buffer[1] = (uint8_t)x_delta;
+ buffer[2] = (uint8_t)y_delta;
+
+ if (optional_data_len > 0)
+ {
+ memcpy(&buffer[3], p_optional_data, optional_data_len);
+ }
+
+ // Store the new value in the host's context
+ memcpy(p_host_rep_data, buffer, hvx_len);
+
+ // Pass buffer to stack
+ memset(&hvx_params, 0, sizeof(hvx_params));
+
+ hvx_params.handle = p_hids->boot_mouse_inp_rep_handles.value_handle;
+ hvx_params.type = BLE_GATT_HVX_NOTIFICATION;
+ hvx_params.offset = 0;
+ hvx_params.p_len = &hvx_len;
+ hvx_params.p_data = buffer;
+
+ err_code = sd_ble_gatts_hvx(conn_handle, &hvx_params);
+ if ((err_code == NRF_SUCCESS) &&
+ (hvx_len != BOOT_MOUSE_INPUT_REPORT_MIN_SIZE + optional_data_len)
+ )
+ {
+ err_code = NRF_ERROR_DATA_SIZE;
+ }
+ }
+ else
+ {
+ err_code = NRF_ERROR_DATA_SIZE;
+ }
+ }
+ else
+ {
+ err_code = NRF_ERROR_INVALID_STATE;
+ }
+
+ return err_code;
+}
+
+
+uint32_t ble_hids_outp_rep_get(ble_hids_t * p_hids,
+ uint8_t rep_index,
+ uint16_t len,
+ uint8_t offset,
+ uint16_t conn_handle,
+ uint8_t * p_outp_rep)
+{
+ ret_code_t err_code;
+ uint8_t * p_rep_data;
+
+ if (rep_index > p_hids->outp_rep_count)
+ {
+ return NRF_ERROR_INVALID_PARAM;
+ }
+
+ err_code = blcm_link_ctx_get(p_hids->p_link_ctx_storage,
+ conn_handle,
+ (void *) &p_rep_data);
+ VERIFY_SUCCESS(err_code);
+
+ if (p_rep_data != NULL)
+ {
+ uint8_t index;
+ p_rep_data += sizeof(ble_hids_client_context_t) + BOOT_KB_INPUT_REPORT_MAX_SIZE +
+ BOOT_KB_OUTPUT_REPORT_MAX_SIZE + BOOT_MOUSE_INPUT_REPORT_MAX_SIZE;
+
+ for (index = 0; index < p_hids->inp_rep_count; index++)
+ {
+ p_rep_data += p_hids->p_inp_rep_init_array[index].max_len;
+ }
+
+ for (index = 0; index < rep_index; index++)
+ {
+ p_rep_data += p_hids->p_outp_rep_init_array[index].max_len;
+ }
+ }
+ else
+ {
+ return NRF_ERROR_NOT_FOUND;
+ }
+
+ // Copy the requested output report data
+ if (len + offset <= p_hids->p_outp_rep_init_array[rep_index].max_len)
+ {
+ memcpy(p_outp_rep, p_rep_data + offset, len);
+ }
+ else
+ {
+ return NRF_ERROR_INVALID_LENGTH;
+ }
+
+ return NRF_SUCCESS;
+}
+
+
+/**
+ @}
+ */
+#endif // NRF_MODULE_ENABLED(BLE_HIDS)
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/ble_hids/ble_hids.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/ble_hids/ble_hids.h
new file mode 100644
index 0000000..d53de82
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/ble_hids/ble_hids.h
@@ -0,0 +1,430 @@
+/**
+ * Copyright (c) 2012 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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
+ *
+ * @defgroup ble_hids Human Interface Device Service
+ * @{
+ * @ingroup ble_sdk_srv
+ * @brief Human Interface Device Service module.
+ *
+ * @details This module implements the Human Interface Device Service with the corresponding set of
+ * characteristics. During initialization it adds the Human Interface Device Service and
+ * a set of characteristics as per the Human Interface Device Service specification and
+ * the user requirements to the BLE stack database.
+ *
+ * If enabled, notification of Input Report characteristics is performed when the
+ * application calls the corresponding ble_hids_xx_input_report_send() function.
+ *
+ * If an event handler is supplied by the application, the Human Interface Device Service
+ * will generate Human Interface Device Service events to the application.
+ *
+ * @note The application must register this module as BLE event observer using the
+ * NRF_SDH_BLE_OBSERVER macro. Example:
+ * @code
+ * ble_hids_t instance;
+ * NRF_SDH_BLE_OBSERVER(anything, BLE_HIDS_BLE_OBSERVER_PRIO,
+ * ble_hids_on_ble_evt, &instance);
+ * @endcode
+ *
+ * @note Attention!
+ * To maintain compliance with Nordic Semiconductor ASA Bluetooth profile
+ * qualification listings, this section of source code must not be modified.
+ */
+
+#ifndef BLE_HIDS_H__
+#define BLE_HIDS_H__
+
+#include <stdint.h>
+#include <stdbool.h>
+#include "ble.h"
+#include "ble_srv_common.h"
+#include "ble_link_ctx_manager.h"
+#include "nrf_sdh_ble.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**@brief Allocate static data for keeping host connection contexts.
+ *
+ * @param _name Name of BLE HIDS instance.
+ * @param[in] _hids_max_clients Maximum number of HIDS clients connected at a time.
+ * @param[in] ... Lengths of HIDS reports.
+ *
+ * @details
+ * Mapping of HIDS reports in the HIDS report context:
+ * - Structure of type @ref ble_hids_client_context_t
+ * - Boot keyboard input report
+ * - Boot keyboard output report
+ * - Boot mouse input report
+ * - Input reports
+ * - Output reports
+ * - Feature reports
+ * @hideinitializer
+ */
+#define BLE_HIDS_DEF(_name, \
+ _hids_max_clients, \
+ ...) \
+ BLE_LINK_CTX_MANAGER_DEF(CONCAT_2(_name, _link_ctx_storage), \
+ (_hids_max_clients), \
+ BLE_HIDS_LINK_CTX_SIZE_CALC(__VA_ARGS__)); \
+ static ble_hids_t _name = \
+ { \
+ .p_link_ctx_storage = &CONCAT_2(_name, _link_ctx_storage) \
+ }; \
+ NRF_SDH_BLE_OBSERVER(_name ## _obs, \
+ BLE_HIDS_BLE_OBSERVER_PRIO, \
+ ble_hids_on_ble_evt, \
+ &_name)
+
+/**@brief Helping macro for @ref BLE_HIDS_DEF, that calculates the link context size for BLE HIDS
+ * instance.
+ *
+ * @param[in] ... Lengths of HIDS reports
+ * @hideinitializer
+ */
+#define BLE_HIDS_LINK_CTX_SIZE_CALC(...) \
+ (sizeof(ble_hids_client_context_t) + \
+ MACRO_MAP_REC(BLE_HIDS_REPORT_ADD, __VA_ARGS__) \
+ (BOOT_KB_INPUT_REPORT_MAX_SIZE) + \
+ (BOOT_KB_OUTPUT_REPORT_MAX_SIZE) + \
+ (BOOT_MOUSE_INPUT_REPORT_MAX_SIZE)) \
+
+/**@brief Helping macro for @ref BLE_HIDS_LINK_CTX_SIZE_CALC, that adds Input/Output/Feature report
+ * lengths.
+ *
+ * @param[in] _report_size Length of the specific report.
+ * @hideinitializer
+ */
+#define BLE_HIDS_REPORT_ADD(_report_size) (_report_size) +
+
+/** @name Report Type values
+ * @anchor BLE_HIDS_REPORT_TYPE @{
+ */
+// Report Type values
+#define BLE_HIDS_REP_TYPE_INPUT 1
+#define BLE_HIDS_REP_TYPE_OUTPUT 2
+#define BLE_HIDS_REP_TYPE_FEATURE 3
+/** @} */
+
+// Maximum number of the various Report Types
+#define BLE_HIDS_MAX_INPUT_REP 10
+#define BLE_HIDS_MAX_OUTPUT_REP 10
+#define BLE_HIDS_MAX_FEATURE_REP 10
+
+// Information Flags
+#define HID_INFO_FLAG_REMOTE_WAKE_MSK 0x01
+#define HID_INFO_FLAG_NORMALLY_CONNECTABLE_MSK 0x02
+
+#define BOOT_KB_INPUT_REPORT_MAX_SIZE 8 /**< Maximum size of a Boot Keyboard Input Report (as per Appendix B in Device Class Definition for Human Interface Devices (HID), Version 1.11). */
+#define BOOT_KB_OUTPUT_REPORT_MAX_SIZE 1 /**< Maximum size of a Boot Keyboard Output Report (as per Appendix B in Device Class Definition for Human Interface Devices (HID), Version 1.11). */
+#define BOOT_MOUSE_INPUT_REPORT_MIN_SIZE 3 /**< Minimum size of a Boot Mouse Input Report (as per Appendix B in Device Class Definition for Human Interface Devices (HID), Version 1.11). */
+#define BOOT_MOUSE_INPUT_REPORT_MAX_SIZE 8 /**< Maximum size of a Boot Mouse Input Report (as per Appendix B in Device Class Definition for Human Interface Devices (HID), Version 1.11). */
+
+/**@brief HID Service characteristic id. */
+typedef struct
+{
+ uint16_t uuid; /**< UUID of characteristic. */
+ uint8_t rep_type; /**< Type of report (only used for BLE_UUID_REPORT_CHAR, see @ref BLE_HIDS_REPORT_TYPE). */
+ uint8_t rep_index; /**< Index of the characteristic (only used for BLE_UUID_REPORT_CHAR). */
+} ble_hids_char_id_t;
+
+/**@brief HID Service event type. */
+typedef enum
+{
+ BLE_HIDS_EVT_HOST_SUSP, /**< Suspend command received. */
+ BLE_HIDS_EVT_HOST_EXIT_SUSP, /**< Exit suspend command received. */
+ BLE_HIDS_EVT_NOTIF_ENABLED, /**< Notification enabled event. */
+ BLE_HIDS_EVT_NOTIF_DISABLED, /**< Notification disabled event. */
+ BLE_HIDS_EVT_REP_CHAR_WRITE, /**< A new value has been written to an Report characteristic. */
+ BLE_HIDS_EVT_BOOT_MODE_ENTERED, /**< Boot mode entered. */
+ BLE_HIDS_EVT_REPORT_MODE_ENTERED, /**< Report mode entered. */
+ BLE_HIDS_EVT_REPORT_READ /**< Read with response */
+} ble_hids_evt_type_t;
+
+/**@brief HID Service event. */
+typedef struct
+{
+ ble_hids_evt_type_t evt_type; /**< Type of event. */
+ union
+ {
+ struct
+ {
+ ble_hids_char_id_t char_id; /**< Id of characteristic for which notification has been started. */
+ } notification;
+ struct
+ {
+ ble_hids_char_id_t char_id; /**< Id of characteristic having been written. */
+ uint16_t offset; /**< Offset for the write operation. */
+ uint16_t len; /**< Length of the incoming data. */
+ uint8_t const * data; /**< Incoming data, variable length */
+ } char_write;
+ struct
+ {
+ ble_hids_char_id_t char_id; /**< Id of characteristic being read. */
+ } char_auth_read;
+ } params;
+ ble_evt_t const * p_ble_evt; /**< corresponding received ble event, NULL if not relevant */
+} ble_hids_evt_t;
+
+// Forward declaration of the ble_hids_t type.
+typedef struct ble_hids_s ble_hids_t;
+
+/**@brief HID Service event handler type. */
+typedef void (*ble_hids_evt_handler_t) (ble_hids_t * p_hids, ble_hids_evt_t * p_evt);
+
+/**@brief HID Information characteristic value. */
+typedef struct
+{
+ uint16_t bcd_hid; /**< 16-bit unsigned integer representing version number of base USB HID Specification implemented by HID Device */
+ uint8_t b_country_code; /**< Identifies which country the hardware is localized for. Most hardware is not localized and thus this value would be zero (0). */
+ uint8_t flags; /**< See http://developer.bluetooth.org/gatt/characteristics/Pages/CharacteristicViewer.aspx?u=org.bluetooth.characteristic.hid_information.xml */
+ ble_srv_security_mode_t security_mode; /**< Security mode for the HID Information characteristic. */
+} ble_hids_hid_information_t;
+
+/**@brief HID Service Input Report characteristic init structure. This contains all options and
+ * data needed for initialization of one Input Report characteristic. */
+typedef struct
+{
+ uint16_t max_len; /**< Maximum length of characteristic value. */
+ ble_srv_report_ref_t rep_ref; /**< Value of the Report Reference descriptor. */
+ ble_srv_cccd_security_mode_t security_mode; /**< Security mode for the HID Input Report characteristic, including cccd. */
+} ble_hids_inp_rep_init_t;
+
+/**@brief HID Service Output Report characteristic init structure. This contains all options and
+ * data needed for initialization of one Output Report characteristic. */
+typedef struct
+{
+ uint16_t max_len; /**< Maximum length of characteristic value. */
+ ble_srv_report_ref_t rep_ref; /**< Value of the Report Reference descriptor. */
+ ble_srv_cccd_security_mode_t security_mode; /**< Security mode for the HID Output Report characteristic, including cccd. */
+} ble_hids_outp_rep_init_t;
+
+/**@brief HID Service Feature Report characteristic init structure. This contains all options and
+ * data needed for initialization of one Feature Report characteristic. */
+typedef struct
+{
+ uint16_t max_len; /**< Maximum length of characteristic value. */
+ ble_srv_report_ref_t rep_ref; /**< Value of the Report Reference descriptor. */
+ ble_srv_cccd_security_mode_t security_mode; /**< Security mode for the HID Service Feature Report characteristic, including cccd. */
+} ble_hids_feature_rep_init_t;
+
+/**@brief HID Service Report Map characteristic init structure. This contains all options and data
+ * needed for initialization of the Report Map characteristic. */
+typedef struct
+{
+ uint8_t * p_data; /**< Report map data. */
+ uint16_t data_len; /**< Length of report map data. */
+ uint8_t ext_rep_ref_num; /**< Number of Optional External Report Reference descriptors. */
+ ble_uuid_t const * p_ext_rep_ref; /**< Optional External Report Reference descriptor (will be added if != NULL). */
+ ble_srv_security_mode_t security_mode; /**< Security mode for the HID Service Report Map characteristic. */
+} ble_hids_rep_map_init_t;
+
+/**@brief HID Report characteristic structure. */
+typedef struct
+{
+ ble_gatts_char_handles_t char_handles; /**< Handles related to the Report characteristic. */
+ uint16_t ref_handle; /**< Handle of the Report Reference descriptor. */
+} ble_hids_rep_char_t;
+
+/**@brief HID Host context structure. It keeps information relevant to a single host. */
+typedef struct
+{
+ uint8_t protocol_mode; /**< Protocol mode. */
+ uint8_t ctrl_pt; /**< HID Control Point. */
+} ble_hids_client_context_t;
+
+/**@brief HID Service init structure. This contains all options and data needed for initialization
+ * of the service. */
+typedef struct
+{
+ ble_hids_evt_handler_t evt_handler; /**< Event handler to be called for handling events in the HID Service. */
+ ble_srv_error_handler_t error_handler; /**< Function to be called in case of an error. */
+ bool is_kb; /**< TRUE if device is operating as a keyboard, FALSE if it is not. */
+ bool is_mouse; /**< TRUE if device is operating as a mouse, FALSE if it is not. */
+ uint8_t inp_rep_count; /**< Number of Input Report characteristics. */
+ ble_hids_inp_rep_init_t const * p_inp_rep_array; /**< Information about the Input Report characteristics. */
+ uint8_t outp_rep_count; /**< Number of Output Report characteristics. */
+ ble_hids_outp_rep_init_t const * p_outp_rep_array; /**< Information about the Output Report characteristics. */
+ uint8_t feature_rep_count; /**< Number of Feature Report characteristics. */
+ ble_hids_feature_rep_init_t const * p_feature_rep_array; /**< Information about the Feature Report characteristics. */
+ ble_hids_rep_map_init_t rep_map; /**< Information nedeed for initialization of the Report Map characteristic. */
+ ble_hids_hid_information_t hid_information; /**< Value of the HID Information characteristic. */
+ uint8_t included_services_count; /**< Number of services to include in HID service. */
+ uint16_t * p_included_services_array; /**< Array of services to include in HID service. */
+ ble_srv_security_mode_t security_mode_protocol; /**< Security settings for HID service protocol attribute */
+ ble_srv_security_mode_t security_mode_ctrl_point; /**< Security settings for HID service Control Point attribute */
+ ble_srv_cccd_security_mode_t security_mode_boot_mouse_inp_rep; /**< Security settings for HID service Mouse input report attribute */
+ ble_srv_cccd_security_mode_t security_mode_boot_kb_inp_rep; /**< Security settings for HID service Keyboard input report attribute */
+ ble_srv_security_mode_t security_mode_boot_kb_outp_rep; /**< Security settings for HID service Keyboard output report attribute */
+} ble_hids_init_t;
+
+/**@brief HID Service structure. This contains various status information for the service. */
+struct ble_hids_s
+{
+ ble_hids_evt_handler_t evt_handler; /**< Event handler to be called for handling events in the HID Service. */
+ ble_srv_error_handler_t error_handler; /**< Function to be called in case of an error. */
+ uint16_t service_handle; /**< Handle of HID Service (as provided by the BLE stack). */
+ ble_gatts_char_handles_t protocol_mode_handles; /**< Handles related to the Protocol Mode characteristic (will only be created if ble_hids_init_t.is_kb or ble_hids_init_t.is_mouse is set). */
+ uint8_t inp_rep_count; /**< Number of Input Report characteristics. */
+ ble_hids_rep_char_t inp_rep_array[BLE_HIDS_MAX_INPUT_REP]; /**< Information about the Input Report characteristics. */
+ uint8_t outp_rep_count; /**< Number of Output Report characteristics. */
+ ble_hids_rep_char_t outp_rep_array[BLE_HIDS_MAX_OUTPUT_REP]; /**< Information about the Output Report characteristics. */
+ uint8_t feature_rep_count; /**< Number of Feature Report characteristics. */
+ ble_hids_rep_char_t feature_rep_array[BLE_HIDS_MAX_FEATURE_REP]; /**< Information about the Feature Report characteristics. */
+ ble_gatts_char_handles_t rep_map_handles; /**< Handles related to the Report Map characteristic. */
+ uint16_t rep_map_ext_rep_ref_handle; /**< Handle of the Report Map External Report Reference descriptor. */
+ ble_gatts_char_handles_t boot_kb_inp_rep_handles; /**< Handles related to the Boot Keyboard Input Report characteristic (will only be created if ble_hids_init_t.is_kb is set). */
+ ble_gatts_char_handles_t boot_kb_outp_rep_handles; /**< Handles related to the Boot Keyboard Output Report characteristic (will only be created if ble_hids_init_t.is_kb is set). */
+ ble_gatts_char_handles_t boot_mouse_inp_rep_handles; /**< Handles related to the Boot Mouse Input Report characteristic (will only be created if ble_hids_init_t.is_mouse is set). */
+ ble_gatts_char_handles_t hid_information_handles; /**< Handles related to the Report Map characteristic. */
+ ble_gatts_char_handles_t hid_control_point_handles; /**< Handles related to the Report Map characteristic. */
+ blcm_link_ctx_storage_t * const p_link_ctx_storage; /**< Link context storage with handles of all current connections and its data context. */
+ ble_hids_inp_rep_init_t const * p_inp_rep_init_array; /**< Pointer to information about the Input Report characteristics. */
+ ble_hids_outp_rep_init_t const * p_outp_rep_init_array; /**< Pointer to information about the Output Report characteristics. */
+ ble_hids_feature_rep_init_t const * p_feature_rep_init_array; /**< Pointer to information about the Feature Report characteristics. */
+};
+
+/**@brief Function for initializing the HID Service.
+ *
+ * @param[out] p_hids HID Service structure. This structure will have to be supplied by the
+ * application. It will be initialized by this function, and will later be
+ * used to identify this particular service instance.
+ * @param[in] p_hids_init Information needed to initialize the service.
+ *
+ * @return NRF_SUCCESS on successful initialization of service, otherwise an error code.
+ */
+uint32_t ble_hids_init(ble_hids_t * p_hids, const ble_hids_init_t * p_hids_init);
+
+/**@brief Function for handling the Application's BLE Stack events.
+ *
+ * @details Handles all events from the BLE stack of interest to the HID Service.
+ *
+ * @param[in] p_ble_evt Event received from the BLE stack.
+ * @param[in] p_context HID Service structure.
+ */
+void ble_hids_on_ble_evt(ble_evt_t const * p_ble_evt, void * p_context);
+
+/**@brief Function for sending Input Report.
+ *
+ * @details Sends data on an Input Report characteristic.
+ *
+ * @param[in] p_hids HID Service structure.
+ * @param[in] rep_index Index of the characteristic (corresponding to the index in
+ * ble_hids_t.inp_rep_array as passed to ble_hids_init()).
+ * @param[in] len Length of data to be sent.
+ * @param[in] p_data Pointer to data to be sent.
+ * @param[in] conn_handle Connection handle, where the notification will be sent.
+ *
+ * @return NRF_SUCCESS on successful sending of input report, otherwise an error code.
+ */
+uint32_t ble_hids_inp_rep_send(ble_hids_t * p_hids,
+ uint8_t rep_index,
+ uint16_t len,
+ uint8_t * p_data,
+ uint16_t conn_handle);
+
+/**@brief Function for sending Boot Keyboard Input Report.
+ *
+ * @details Sends data on an Boot Keyboard Input Report characteristic.
+ *
+ * @param[in] p_hids HID Service structure.
+ * @param[in] len Length of data to be sent.
+ * @param[in] p_data Pointer to data to be sent.
+ * @param[in] conn_handle Connection handle, where the notification will be sent.
+ *
+ * @return NRF_SUCCESS on successful sending of the report, otherwise an error code.
+ */
+uint32_t ble_hids_boot_kb_inp_rep_send(ble_hids_t * p_hids,
+ uint16_t len,
+ uint8_t * p_data,
+ uint16_t conn_handle);
+
+/**@brief Function for sending Boot Mouse Input Report.
+ *
+ * @details Sends data on an Boot Mouse Input Report characteristic.
+ *
+ * @param[in] p_hids HID Service structure.
+ * @param[in] buttons State of mouse buttons.
+ * @param[in] x_delta Horizontal movement.
+ * @param[in] y_delta Vertical movement.
+ * @param[in] optional_data_len Length of optional part of Boot Mouse Input Report.
+ * @param[in] p_optional_data Optional part of Boot Mouse Input Report.
+ * @param[in] conn_handle Connection handle.
+ *
+ * @return NRF_SUCCESS on successful sending of the report, otherwise an error code.
+ */
+uint32_t ble_hids_boot_mouse_inp_rep_send(ble_hids_t * p_hids,
+ uint8_t buttons,
+ int8_t x_delta,
+ int8_t y_delta,
+ uint16_t optional_data_len,
+ uint8_t * p_optional_data,
+ uint16_t conn_handle);
+
+/**@brief Function for getting the current value of Output Report from the stack.
+ *
+ * @details Fetches the current value of the output report characteristic from the stack.
+ *
+ * @param[in] p_hids HID Service structure.
+ * @param[in] rep_index Index of the characteristic (corresponding to the index in
+ * ble_hids_t.outp_rep_array as passed to ble_hids_init()).
+ * @param[in] len Length of output report needed.
+ * @param[in] offset Offset in bytes to read from.
+ * @param[in] conn_handle Connection handle.
+ * @param[out] p_outp_rep Pointer to the output report.
+ *
+ * @return NRF_SUCCESS on successful read of the report, otherwise an error code.
+ */
+uint32_t ble_hids_outp_rep_get(ble_hids_t * p_hids,
+ uint8_t rep_index,
+ uint16_t len,
+ uint8_t offset,
+ uint16_t conn_handle,
+ uint8_t * p_outp_rep);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // BLE_HIDS_H__
+
+/** @} */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/ble_hrs/ble_hrs.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/ble_hrs/ble_hrs.c
new file mode 100644
index 0000000..58aa657
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/ble_hrs/ble_hrs.c
@@ -0,0 +1,479 @@
+/**
+ * Copyright (c) 2012 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+/* Attention!
+ * To maintain compliance with Nordic Semiconductor ASA's Bluetooth profile
+ * qualification listings, this section of source code must not be modified.
+ */
+#include "sdk_common.h"
+#if NRF_MODULE_ENABLED(BLE_HRS)
+#include "ble_hrs.h"
+#include <string.h>
+#include "ble_srv_common.h"
+
+
+#define OPCODE_LENGTH 1 /**< Length of opcode inside Heart Rate Measurement packet. */
+#define HANDLE_LENGTH 2 /**< Length of handle inside Heart Rate Measurement packet. */
+#define MAX_HRM_LEN (NRF_SDH_BLE_GATT_MAX_MTU_SIZE - OPCODE_LENGTH - HANDLE_LENGTH) /**< Maximum size of a transmitted Heart Rate Measurement. */
+
+#define INITIAL_VALUE_HRM 0 /**< Initial Heart Rate Measurement value. */
+
+// Heart Rate Measurement flag bits
+#define HRM_FLAG_MASK_HR_VALUE_16BIT (0x01 << 0) /**< Heart Rate Value Format bit. */
+#define HRM_FLAG_MASK_SENSOR_CONTACT_DETECTED (0x01 << 1) /**< Sensor Contact Detected bit. */
+#define HRM_FLAG_MASK_SENSOR_CONTACT_SUPPORTED (0x01 << 2) /**< Sensor Contact Supported bit. */
+#define HRM_FLAG_MASK_EXPENDED_ENERGY_INCLUDED (0x01 << 3) /**< Energy Expended Status bit. Feature Not Supported */
+#define HRM_FLAG_MASK_RR_INTERVAL_INCLUDED (0x01 << 4) /**< RR-Interval bit. */
+
+
+/**@brief Function for handling the Connect event.
+ *
+ * @param[in] p_hrs Heart Rate Service structure.
+ * @param[in] p_ble_evt Event received from the BLE stack.
+ */
+static void on_connect(ble_hrs_t * p_hrs, ble_evt_t const * p_ble_evt)
+{
+ p_hrs->conn_handle = p_ble_evt->evt.gap_evt.conn_handle;
+}
+
+
+/**@brief Function for handling the Disconnect event.
+ *
+ * @param[in] p_hrs Heart Rate Service structure.
+ * @param[in] p_ble_evt Event received from the BLE stack.
+ */
+static void on_disconnect(ble_hrs_t * p_hrs, ble_evt_t const * p_ble_evt)
+{
+ UNUSED_PARAMETER(p_ble_evt);
+ p_hrs->conn_handle = BLE_CONN_HANDLE_INVALID;
+}
+
+
+/**@brief Function for handling write events to the Heart Rate Measurement characteristic.
+ *
+ * @param[in] p_hrs Heart Rate Service structure.
+ * @param[in] p_evt_write Write event received from the BLE stack.
+ */
+static void on_hrm_cccd_write(ble_hrs_t * p_hrs, ble_gatts_evt_write_t const * p_evt_write)
+{
+ if (p_evt_write->len == 2)
+ {
+ // CCCD written, update notification state
+ if (p_hrs->evt_handler != NULL)
+ {
+ ble_hrs_evt_t evt;
+
+ if (ble_srv_is_notification_enabled(p_evt_write->data))
+ {
+ evt.evt_type = BLE_HRS_EVT_NOTIFICATION_ENABLED;
+ }
+ else
+ {
+ evt.evt_type = BLE_HRS_EVT_NOTIFICATION_DISABLED;
+ }
+
+ p_hrs->evt_handler(p_hrs, &evt);
+ }
+ }
+}
+
+
+/**@brief Function for handling the Write event.
+ *
+ * @param[in] p_hrs Heart Rate Service structure.
+ * @param[in] p_ble_evt Event received from the BLE stack.
+ */
+static void on_write(ble_hrs_t * p_hrs, ble_evt_t const * p_ble_evt)
+{
+ ble_gatts_evt_write_t const * p_evt_write = &p_ble_evt->evt.gatts_evt.params.write;
+
+ if (p_evt_write->handle == p_hrs->hrm_handles.cccd_handle)
+ {
+ on_hrm_cccd_write(p_hrs, p_evt_write);
+ }
+}
+
+
+void ble_hrs_on_ble_evt(ble_evt_t const * p_ble_evt, void * p_context)
+{
+ ble_hrs_t * p_hrs = (ble_hrs_t *) p_context;
+
+ switch (p_ble_evt->header.evt_id)
+ {
+ case BLE_GAP_EVT_CONNECTED:
+ on_connect(p_hrs, p_ble_evt);
+ break;
+
+ case BLE_GAP_EVT_DISCONNECTED:
+ on_disconnect(p_hrs, p_ble_evt);
+ break;
+
+ case BLE_GATTS_EVT_WRITE:
+ on_write(p_hrs, p_ble_evt);
+ break;
+
+ default:
+ // No implementation needed.
+ break;
+ }
+}
+
+
+/**@brief Function for encoding a Heart Rate Measurement.
+ *
+ * @param[in] p_hrs Heart Rate Service structure.
+ * @param[in] heart_rate Measurement to be encoded.
+ * @param[out] p_encoded_buffer Buffer where the encoded data will be written.
+ *
+ * @return Size of encoded data.
+ */
+static uint8_t hrm_encode(ble_hrs_t * p_hrs, uint16_t heart_rate, uint8_t * p_encoded_buffer)
+{
+ uint8_t flags = 0;
+ uint8_t len = 1;
+ int i;
+
+ // Set sensor contact related flags
+ if (p_hrs->is_sensor_contact_supported)
+ {
+ flags |= HRM_FLAG_MASK_SENSOR_CONTACT_SUPPORTED;
+ }
+ if (p_hrs->is_sensor_contact_detected)
+ {
+ flags |= HRM_FLAG_MASK_SENSOR_CONTACT_DETECTED;
+ }
+
+ // Encode heart rate measurement
+ if (heart_rate > 0xff)
+ {
+ flags |= HRM_FLAG_MASK_HR_VALUE_16BIT;
+ len += uint16_encode(heart_rate, &p_encoded_buffer[len]);
+ }
+ else
+ {
+ p_encoded_buffer[len++] = (uint8_t)heart_rate;
+ }
+
+ // Encode rr_interval values
+ if (p_hrs->rr_interval_count > 0)
+ {
+ flags |= HRM_FLAG_MASK_RR_INTERVAL_INCLUDED;
+ }
+ for (i = 0; i < p_hrs->rr_interval_count; i++)
+ {
+ if (len + sizeof(uint16_t) > p_hrs->max_hrm_len)
+ {
+ // Not all stored rr_interval values can fit into the encoded hrm,
+ // move the remaining values to the start of the buffer.
+ memmove(&p_hrs->rr_interval[0],
+ &p_hrs->rr_interval[i],
+ (p_hrs->rr_interval_count - i) * sizeof(uint16_t));
+ break;
+ }
+ len += uint16_encode(p_hrs->rr_interval[i], &p_encoded_buffer[len]);
+ }
+ p_hrs->rr_interval_count -= i;
+
+ // Add flags
+ p_encoded_buffer[0] = flags;
+
+ return len;
+}
+
+
+/**@brief Function for adding the Heart Rate Measurement characteristic.
+ *
+ * @param[in] p_hrs Heart Rate Service structure.
+ * @param[in] p_hrs_init Information needed to initialize the service.
+ *
+ * @return NRF_SUCCESS on success, otherwise an error code.
+ */
+static uint32_t heart_rate_measurement_char_add(ble_hrs_t * p_hrs,
+ const ble_hrs_init_t * p_hrs_init)
+{
+ ble_gatts_char_md_t char_md;
+ ble_gatts_attr_md_t cccd_md;
+ ble_gatts_attr_t attr_char_value;
+ ble_uuid_t ble_uuid;
+ ble_gatts_attr_md_t attr_md;
+ uint8_t encoded_initial_hrm[MAX_HRM_LEN];
+
+ memset(&cccd_md, 0, sizeof(cccd_md));
+
+ BLE_GAP_CONN_SEC_MODE_SET_OPEN(&cccd_md.read_perm);
+ cccd_md.write_perm = p_hrs_init->hrs_hrm_attr_md.cccd_write_perm;
+ cccd_md.vloc = BLE_GATTS_VLOC_STACK;
+
+ memset(&char_md, 0, sizeof(char_md));
+
+ char_md.char_props.notify = 1;
+ char_md.p_char_user_desc = NULL;
+ char_md.p_char_pf = NULL;
+ char_md.p_user_desc_md = NULL;
+ char_md.p_cccd_md = &cccd_md;
+ char_md.p_sccd_md = NULL;
+
+ BLE_UUID_BLE_ASSIGN(ble_uuid, BLE_UUID_HEART_RATE_MEASUREMENT_CHAR);
+
+ memset(&attr_md, 0, sizeof(attr_md));
+
+ attr_md.read_perm = p_hrs_init->hrs_hrm_attr_md.read_perm;
+ attr_md.write_perm = p_hrs_init->hrs_hrm_attr_md.write_perm;
+ attr_md.vloc = BLE_GATTS_VLOC_STACK;
+ attr_md.rd_auth = 0;
+ attr_md.wr_auth = 0;
+ attr_md.vlen = 1;
+
+ memset(&attr_char_value, 0, sizeof(attr_char_value));
+
+ attr_char_value.p_uuid = &ble_uuid;
+ attr_char_value.p_attr_md = &attr_md;
+ attr_char_value.init_len = hrm_encode(p_hrs, INITIAL_VALUE_HRM, encoded_initial_hrm);
+ attr_char_value.init_offs = 0;
+ attr_char_value.max_len = MAX_HRM_LEN;
+ attr_char_value.p_value = encoded_initial_hrm;
+
+ return sd_ble_gatts_characteristic_add(p_hrs->service_handle,
+ &char_md,
+ &attr_char_value,
+ &p_hrs->hrm_handles);
+}
+
+
+/**@brief Function for adding the Body Sensor Location characteristic.
+ *
+ * @param[in] p_hrs Heart Rate Service structure.
+ * @param[in] p_hrs_init Information needed to initialize the service.
+ *
+ * @return NRF_SUCCESS on success, otherwise an error code.
+ */
+static uint32_t body_sensor_location_char_add(ble_hrs_t * p_hrs, const ble_hrs_init_t * p_hrs_init)
+{
+ ble_gatts_char_md_t char_md;
+ ble_gatts_attr_t attr_char_value;
+ ble_uuid_t ble_uuid;
+ ble_gatts_attr_md_t attr_md;
+
+ memset(&char_md, 0, sizeof(char_md));
+
+ char_md.char_props.read = 1;
+ char_md.p_char_user_desc = NULL;
+ char_md.p_char_pf = NULL;
+ char_md.p_user_desc_md = NULL;
+ char_md.p_cccd_md = NULL;
+ char_md.p_sccd_md = NULL;
+
+ BLE_UUID_BLE_ASSIGN(ble_uuid, BLE_UUID_BODY_SENSOR_LOCATION_CHAR);
+
+ memset(&attr_md, 0, sizeof(attr_md));
+
+ attr_md.read_perm = p_hrs_init->hrs_bsl_attr_md.read_perm;
+ attr_md.write_perm = p_hrs_init->hrs_bsl_attr_md.write_perm;
+ attr_md.vloc = BLE_GATTS_VLOC_STACK;
+ attr_md.rd_auth = 0;
+ attr_md.wr_auth = 0;
+ attr_md.vlen = 0;
+
+ memset(&attr_char_value, 0, sizeof(attr_char_value));
+
+ attr_char_value.p_uuid = &ble_uuid;
+ attr_char_value.p_attr_md = &attr_md;
+ attr_char_value.init_len = sizeof (uint8_t);
+ attr_char_value.init_offs = 0;
+ attr_char_value.max_len = sizeof (uint8_t);
+ attr_char_value.p_value = p_hrs_init->p_body_sensor_location;
+
+ return sd_ble_gatts_characteristic_add(p_hrs->service_handle,
+ &char_md,
+ &attr_char_value,
+ &p_hrs->bsl_handles);
+}
+
+
+uint32_t ble_hrs_init(ble_hrs_t * p_hrs, const ble_hrs_init_t * p_hrs_init)
+{
+ uint32_t err_code;
+ ble_uuid_t ble_uuid;
+
+ // Initialize service structure
+ p_hrs->evt_handler = p_hrs_init->evt_handler;
+ p_hrs->is_sensor_contact_supported = p_hrs_init->is_sensor_contact_supported;
+ p_hrs->conn_handle = BLE_CONN_HANDLE_INVALID;
+ p_hrs->is_sensor_contact_detected = false;
+ p_hrs->rr_interval_count = 0;
+ p_hrs->max_hrm_len = MAX_HRM_LEN;
+
+ // Add service
+ BLE_UUID_BLE_ASSIGN(ble_uuid, BLE_UUID_HEART_RATE_SERVICE);
+
+ err_code = sd_ble_gatts_service_add(BLE_GATTS_SRVC_TYPE_PRIMARY,
+ &ble_uuid,
+ &p_hrs->service_handle);
+
+ if (err_code != NRF_SUCCESS)
+ {
+ return err_code;
+ }
+
+ // Add heart rate measurement characteristic
+ err_code = heart_rate_measurement_char_add(p_hrs, p_hrs_init);
+ if (err_code != NRF_SUCCESS)
+ {
+ return err_code;
+ }
+
+ if (p_hrs_init->p_body_sensor_location != NULL)
+ {
+ // Add body sensor location characteristic
+ err_code = body_sensor_location_char_add(p_hrs, p_hrs_init);
+ if (err_code != NRF_SUCCESS)
+ {
+ return err_code;
+ }
+ }
+
+ return NRF_SUCCESS;
+}
+
+
+uint32_t ble_hrs_heart_rate_measurement_send(ble_hrs_t * p_hrs, uint16_t heart_rate)
+{
+ uint32_t err_code;
+
+ // Send value if connected and notifying
+ if (p_hrs->conn_handle != BLE_CONN_HANDLE_INVALID)
+ {
+ uint8_t encoded_hrm[MAX_HRM_LEN];
+ uint16_t len;
+ uint16_t hvx_len;
+ ble_gatts_hvx_params_t hvx_params;
+
+ len = hrm_encode(p_hrs, heart_rate, encoded_hrm);
+ hvx_len = len;
+
+ memset(&hvx_params, 0, sizeof(hvx_params));
+
+ hvx_params.handle = p_hrs->hrm_handles.value_handle;
+ hvx_params.type = BLE_GATT_HVX_NOTIFICATION;
+ hvx_params.offset = 0;
+ hvx_params.p_len = &hvx_len;
+ hvx_params.p_data = encoded_hrm;
+
+ err_code = sd_ble_gatts_hvx(p_hrs->conn_handle, &hvx_params);
+ if ((err_code == NRF_SUCCESS) && (hvx_len != len))
+ {
+ err_code = NRF_ERROR_DATA_SIZE;
+ }
+ }
+ else
+ {
+ err_code = NRF_ERROR_INVALID_STATE;
+ }
+
+ return err_code;
+}
+
+
+void ble_hrs_rr_interval_add(ble_hrs_t * p_hrs, uint16_t rr_interval)
+{
+ if (p_hrs->rr_interval_count == BLE_HRS_MAX_BUFFERED_RR_INTERVALS)
+ {
+ // The rr_interval buffer is full, delete the oldest value
+ memmove(&p_hrs->rr_interval[0],
+ &p_hrs->rr_interval[1],
+ (BLE_HRS_MAX_BUFFERED_RR_INTERVALS - 1) * sizeof(uint16_t));
+ p_hrs->rr_interval_count--;
+ }
+
+ // Add new value
+ p_hrs->rr_interval[p_hrs->rr_interval_count++] = rr_interval;
+}
+
+
+bool ble_hrs_rr_interval_buffer_is_full(ble_hrs_t * p_hrs)
+{
+ return (p_hrs->rr_interval_count == BLE_HRS_MAX_BUFFERED_RR_INTERVALS);
+}
+
+
+uint32_t ble_hrs_sensor_contact_supported_set(ble_hrs_t * p_hrs, bool is_sensor_contact_supported)
+{
+ // Check if we are connected to peer
+ if (p_hrs->conn_handle == BLE_CONN_HANDLE_INVALID)
+ {
+ p_hrs->is_sensor_contact_supported = is_sensor_contact_supported;
+ return NRF_SUCCESS;
+ }
+ else
+ {
+ return NRF_ERROR_INVALID_STATE;
+ }
+}
+
+
+void ble_hrs_sensor_contact_detected_update(ble_hrs_t * p_hrs, bool is_sensor_contact_detected)
+{
+ p_hrs->is_sensor_contact_detected = is_sensor_contact_detected;
+}
+
+
+uint32_t ble_hrs_body_sensor_location_set(ble_hrs_t * p_hrs, uint8_t body_sensor_location)
+{
+ ble_gatts_value_t gatts_value;
+
+ // Initialize value struct.
+ memset(&gatts_value, 0, sizeof(gatts_value));
+
+ gatts_value.len = sizeof(uint8_t);
+ gatts_value.offset = 0;
+ gatts_value.p_value = &body_sensor_location;
+
+ return sd_ble_gatts_value_set(p_hrs->conn_handle, p_hrs->bsl_handles.value_handle, &gatts_value);
+}
+
+
+void ble_hrs_on_gatt_evt(ble_hrs_t * p_hrs, nrf_ble_gatt_evt_t const * p_gatt_evt)
+{
+ if ( (p_hrs->conn_handle == p_gatt_evt->conn_handle)
+ && (p_gatt_evt->evt_id == NRF_BLE_GATT_EVT_ATT_MTU_UPDATED))
+ {
+ p_hrs->max_hrm_len = p_gatt_evt->params.att_mtu_effective - OPCODE_LENGTH - HANDLE_LENGTH;
+ }
+}
+#endif // NRF_MODULE_ENABLED(BLE_HRS)
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/ble_hrs/ble_hrs.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/ble_hrs/ble_hrs.h
new file mode 100644
index 0000000..afc6c0a
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/ble_hrs/ble_hrs.h
@@ -0,0 +1,266 @@
+/**
+ * Copyright (c) 2012 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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
+ *
+ * @defgroup ble_hrs Heart Rate Service
+ * @{
+ * @ingroup ble_sdk_srv
+ * @brief Heart Rate Service module.
+ *
+ * @details This module implements the Heart Rate Service with the Heart Rate Measurement,
+ * Body Sensor Location and Heart Rate Control Point characteristics.
+ * During initialization it adds the Heart Rate Service and Heart Rate Measurement
+ * characteristic to the BLE stack database. Optionally it also adds the
+ * Body Sensor Location and Heart Rate Control Point characteristics.
+ *
+ * If enabled, notification of the Heart Rate Measurement characteristic is performed
+ * when the application calls ble_hrs_heart_rate_measurement_send().
+ *
+ * The Heart Rate Service also provides a set of functions for manipulating the
+ * various fields in the Heart Rate Measurement characteristic, as well as setting
+ * the Body Sensor Location characteristic value.
+ *
+ * If an event handler is supplied by the application, the Heart Rate Service will
+ * generate Heart Rate Service events to the application.
+ *
+ * @note The application must register this module as BLE event observer using the
+ * NRF_SDH_BLE_OBSERVER macro. Example:
+ * @code
+ * ble_hrs_t instance;
+ * NRF_SDH_BLE_OBSERVER(anything, BLE_HRS_BLE_OBSERVER_PRIO,
+ * ble_hrs_on_ble_evt, &instance);
+ * @endcode
+ *
+ * @note Attention!
+ * To maintain compliance with Nordic Semiconductor ASA Bluetooth profile
+ * qualification listings, this section of source code must not be modified.
+ */
+
+#ifndef BLE_HRS_H__
+#define BLE_HRS_H__
+
+#include <stdint.h>
+#include <stdbool.h>
+#include "ble.h"
+#include "ble_srv_common.h"
+#include "nrf_sdh_ble.h"
+#include "nrf_ble_gatt.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**@brief Macro for defining a ble_hrs instance.
+ *
+ * @param _name Name of the instance.
+ * @hideinitializer
+ */
+#define BLE_HRS_DEF(_name) \
+static ble_hrs_t _name; \
+NRF_SDH_BLE_OBSERVER(_name ## _obs, \
+ BLE_HRS_BLE_OBSERVER_PRIO, \
+ ble_hrs_on_ble_evt, &_name)
+
+// Body Sensor Location values
+#define BLE_HRS_BODY_SENSOR_LOCATION_OTHER 0
+#define BLE_HRS_BODY_SENSOR_LOCATION_CHEST 1
+#define BLE_HRS_BODY_SENSOR_LOCATION_WRIST 2
+#define BLE_HRS_BODY_SENSOR_LOCATION_FINGER 3
+#define BLE_HRS_BODY_SENSOR_LOCATION_HAND 4
+#define BLE_HRS_BODY_SENSOR_LOCATION_EAR_LOBE 5
+#define BLE_HRS_BODY_SENSOR_LOCATION_FOOT 6
+
+#define BLE_HRS_MAX_BUFFERED_RR_INTERVALS 20 /**< Size of RR Interval buffer inside service. */
+
+
+/**@brief Heart Rate Service event type. */
+typedef enum
+{
+ BLE_HRS_EVT_NOTIFICATION_ENABLED, /**< Heart Rate value notification enabled event. */
+ BLE_HRS_EVT_NOTIFICATION_DISABLED /**< Heart Rate value notification disabled event. */
+} ble_hrs_evt_type_t;
+
+/**@brief Heart Rate Service event. */
+typedef struct
+{
+ ble_hrs_evt_type_t evt_type; /**< Type of event. */
+} ble_hrs_evt_t;
+
+// Forward declaration of the ble_hrs_t type.
+typedef struct ble_hrs_s ble_hrs_t;
+
+/**@brief Heart Rate Service event handler type. */
+typedef void (*ble_hrs_evt_handler_t) (ble_hrs_t * p_hrs, ble_hrs_evt_t * p_evt);
+
+/**@brief Heart Rate Service init structure. This contains all options and data needed for
+ * initialization of the service. */
+typedef struct
+{
+ ble_hrs_evt_handler_t evt_handler; /**< Event handler to be called for handling events in the Heart Rate Service. */
+ bool is_sensor_contact_supported; /**< Determines if sensor contact detection is to be supported. */
+ uint8_t * p_body_sensor_location; /**< If not NULL, initial value of the Body Sensor Location characteristic. */
+ ble_srv_cccd_security_mode_t hrs_hrm_attr_md; /**< Initial security level for heart rate service measurement attribute */
+ ble_srv_security_mode_t hrs_bsl_attr_md; /**< Initial security level for body sensor location attribute */
+} ble_hrs_init_t;
+
+/**@brief Heart Rate Service structure. This contains various status information for the service. */
+struct ble_hrs_s
+{
+ ble_hrs_evt_handler_t evt_handler; /**< Event handler to be called for handling events in the Heart Rate Service. */
+ bool is_expended_energy_supported; /**< TRUE if Expended Energy measurement is supported. */
+ bool is_sensor_contact_supported; /**< TRUE if sensor contact detection is supported. */
+ uint16_t service_handle; /**< Handle of Heart Rate Service (as provided by the BLE stack). */
+ ble_gatts_char_handles_t hrm_handles; /**< Handles related to the Heart Rate Measurement characteristic. */
+ ble_gatts_char_handles_t bsl_handles; /**< Handles related to the Body Sensor Location characteristic. */
+ ble_gatts_char_handles_t hrcp_handles; /**< Handles related to the Heart Rate Control Point characteristic. */
+ uint16_t conn_handle; /**< Handle of the current connection (as provided by the BLE stack, is BLE_CONN_HANDLE_INVALID if not in a connection). */
+ bool is_sensor_contact_detected; /**< TRUE if sensor contact has been detected. */
+ uint16_t rr_interval[BLE_HRS_MAX_BUFFERED_RR_INTERVALS]; /**< Set of RR Interval measurements since the last Heart Rate Measurement transmission. */
+ uint16_t rr_interval_count; /**< Number of RR Interval measurements since the last Heart Rate Measurement transmission. */
+ uint8_t max_hrm_len; /**< Current maximum HR measurement length, adjusted according to the current ATT MTU. */
+};
+
+
+/**@brief Function for initializing the Heart Rate Service.
+ *
+ * @param[out] p_hrs Heart Rate Service structure. This structure will have to be supplied by
+ * the application. It will be initialized by this function, and will later
+ * be used to identify this particular service instance.
+ * @param[in] p_hrs_init Information needed to initialize the service.
+ *
+ * @return NRF_SUCCESS on successful initialization of service, otherwise an error code.
+ */
+uint32_t ble_hrs_init(ble_hrs_t * p_hrs, ble_hrs_init_t const * p_hrs_init);
+
+
+/**@brief Function for handling the GATT module's events.
+ *
+ * @details Handles all events from the GATT module of interest to the Heart Rate Service.
+ *
+ * @param[in] p_hrs Heart Rate Service structure.
+ * @param[in] p_gatt_evt Event received from the GATT module.
+ */
+void ble_hrs_on_gatt_evt(ble_hrs_t * p_hrs, nrf_ble_gatt_evt_t const * p_gatt_evt);
+
+
+/**@brief Function for handling the Application's BLE Stack events.
+ *
+ * @details Handles all events from the BLE stack of interest to the Heart Rate Service.
+ *
+ * @param[in] p_ble_evt Event received from the BLE stack.
+ * @param[in] p_context Heart Rate Service structure.
+ */
+void ble_hrs_on_ble_evt(ble_evt_t const * p_ble_evt, void * p_context);
+
+
+/**@brief Function for sending heart rate measurement if notification has been enabled.
+ *
+ * @details The application calls this function after having performed a heart rate measurement.
+ * If notification has been enabled, the heart rate measurement data is encoded and sent to
+ * the client.
+ *
+ * @param[in] p_hrs Heart Rate Service structure.
+ * @param[in] heart_rate New heart rate measurement.
+ *
+ * @return NRF_SUCCESS on success, otherwise an error code.
+ */
+uint32_t ble_hrs_heart_rate_measurement_send(ble_hrs_t * p_hrs, uint16_t heart_rate);
+
+
+/**@brief Function for adding a RR Interval measurement to the RR Interval buffer.
+ *
+ * @details All buffered RR Interval measurements will be included in the next heart rate
+ * measurement message, up to the maximum number of measurements that will fit into the
+ * message. If the buffer is full, the oldest measurement in the buffer will be deleted.
+ *
+ * @param[in] p_hrs Heart Rate Service structure.
+ * @param[in] rr_interval New RR Interval measurement (will be buffered until the next
+ * transmission of Heart Rate Measurement).
+ */
+void ble_hrs_rr_interval_add(ble_hrs_t * p_hrs, uint16_t rr_interval);
+
+
+/**@brief Function for checking if RR Interval buffer is full.
+ *
+ * @param[in] p_hrs Heart Rate Service structure.
+ *
+ * @return true if RR Interval buffer is full, false otherwise.
+ */
+bool ble_hrs_rr_interval_buffer_is_full(ble_hrs_t * p_hrs);
+
+
+/**@brief Function for setting the state of the Sensor Contact Supported bit.
+ *
+ * @param[in] p_hrs Heart Rate Service structure.
+ * @param[in] is_sensor_contact_supported New state of the Sensor Contact Supported bit.
+ *
+ * @return NRF_SUCCESS on success, otherwise an error code.
+ */
+uint32_t ble_hrs_sensor_contact_supported_set(ble_hrs_t * p_hrs, bool is_sensor_contact_supported);
+
+
+/**@brief Function for setting the state of the Sensor Contact Detected bit.
+ *
+ * @param[in] p_hrs Heart Rate Service structure.
+ * @param[in] is_sensor_contact_detected TRUE if sensor contact is detected, FALSE otherwise.
+ */
+void ble_hrs_sensor_contact_detected_update(ble_hrs_t * p_hrs, bool is_sensor_contact_detected);
+
+
+/**@brief Function for setting the Body Sensor Location.
+ *
+ * @details Sets a new value of the Body Sensor Location characteristic. The new value will be sent
+ * to the client the next time the client reads the Body Sensor Location characteristic.
+ *
+ * @param[in] p_hrs Heart Rate Service structure.
+ * @param[in] body_sensor_location New Body Sensor Location.
+ *
+ * @return NRF_SUCCESS on success, otherwise an error code.
+ */
+uint32_t ble_hrs_body_sensor_location_set(ble_hrs_t * p_hrs, uint8_t body_sensor_location);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // BLE_HRS_H__
+
+/** @} */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/ble_hrs_c/ble_hrs_c.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/ble_hrs_c/ble_hrs_c.c
new file mode 100644
index 0000000..6517d71
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/ble_hrs_c/ble_hrs_c.c
@@ -0,0 +1,384 @@
+/**
+ * Copyright (c) 2012 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+/**@cond To Make Doxygen skip documentation generation for this file.
+ * @{
+ */
+#include "sdk_common.h"
+#if NRF_MODULE_ENABLED(BLE_HRS_C)
+#include "ble_hrs_c.h"
+#include "ble_db_discovery.h"
+#include "ble_types.h"
+#include "ble_srv_common.h"
+#include "ble_gattc.h"
+
+#define NRF_LOG_MODULE_NAME ble_hrs_c
+#include "nrf_log.h"
+NRF_LOG_MODULE_REGISTER();
+
+#define HRM_FLAG_MASK_HR_16BIT (0x01 << 0) /**< Bit mask used to extract the type of heart rate value. This is used to find if the received heart rate is a 16 bit value or an 8 bit value. */
+#define HRM_FLAG_MASK_HR_RR_INT (0x01 << 4) /**< Bit mask used to extract the presence of RR_INTERVALS. This is used to find if the received measurement includes RR_INTERVALS. */
+
+#define TX_BUFFER_MASK 0x07 /**< TX Buffer mask, must be a mask of continuous zeroes, followed by continuous sequence of ones: 000...111. */
+#define TX_BUFFER_SIZE (TX_BUFFER_MASK + 1) /**< Size of send buffer, which is 1 higher than the mask. */
+
+#define WRITE_MESSAGE_LENGTH BLE_CCCD_VALUE_LEN /**< Length of the write message for CCCD. */
+#define WRITE_MESSAGE_LENGTH BLE_CCCD_VALUE_LEN /**< Length of the write message for CCCD. */
+
+typedef enum
+{
+ READ_REQ, /**< Type identifying that this tx_message is a read request. */
+ WRITE_REQ /**< Type identifying that this tx_message is a write request. */
+} tx_request_t;
+
+/**@brief Structure for writing a message to the peer, i.e. CCCD.
+ */
+typedef struct
+{
+ uint8_t gattc_value[WRITE_MESSAGE_LENGTH]; /**< The message to write. */
+ ble_gattc_write_params_t gattc_params; /**< GATTC parameters for this message. */
+} write_params_t;
+
+/**@brief Structure for holding data to be transmitted to the connected central.
+ */
+typedef struct
+{
+ uint16_t conn_handle; /**< Connection handle to be used when transmitting this message. */
+ tx_request_t type; /**< Type of this message, i.e. read or write message. */
+ union
+ {
+ uint16_t read_handle; /**< Read request message. */
+ write_params_t write_req; /**< Write request message. */
+ } req;
+} tx_message_t;
+
+
+static tx_message_t m_tx_buffer[TX_BUFFER_SIZE]; /**< Transmit buffer for messages to be transmitted to the central. */
+static uint32_t m_tx_insert_index = 0; /**< Current index in the transmit buffer where the next message should be inserted. */
+static uint32_t m_tx_index = 0; /**< Current index in the transmit buffer from where the next message to be transmitted resides. */
+
+
+/**@brief Function for passing any pending request from the buffer to the stack.
+ */
+static void tx_buffer_process(void)
+{
+ if (m_tx_index != m_tx_insert_index)
+ {
+ uint32_t err_code;
+
+ if (m_tx_buffer[m_tx_index].type == READ_REQ)
+ {
+ err_code = sd_ble_gattc_read(m_tx_buffer[m_tx_index].conn_handle,
+ m_tx_buffer[m_tx_index].req.read_handle,
+ 0);
+ }
+ else
+ {
+ err_code = sd_ble_gattc_write(m_tx_buffer[m_tx_index].conn_handle,
+ &m_tx_buffer[m_tx_index].req.write_req.gattc_params);
+ }
+ if (err_code == NRF_SUCCESS)
+ {
+ m_tx_index++;
+ m_tx_index &= TX_BUFFER_MASK;
+ }
+ else
+ {
+ NRF_LOG_DEBUG("SD Read/Write API returns error. This message sending will be "
+ "attempted again..");
+ }
+ }
+}
+
+
+/**@brief Function for handling write response events.
+ *
+ * @param[in] p_ble_hrs_c Pointer to the Heart Rate Client structure.
+ * @param[in] p_ble_evt Pointer to the BLE event received.
+ */
+static void on_write_rsp(ble_hrs_c_t * p_ble_hrs_c, const ble_evt_t * p_ble_evt)
+{
+ // Check if the event if on the link for this instance
+ if (p_ble_hrs_c->conn_handle != p_ble_evt->evt.gattc_evt.conn_handle)
+ {
+ return;
+ }
+ // Check if there is any message to be sent across to the peer and send it.
+ tx_buffer_process();
+}
+
+
+/**@brief Function for handling Handle Value Notification received from the SoftDevice.
+ *
+ * @details This function will uses the Handle Value Notification received from the SoftDevice
+ * and checks if it is a notification of the heart rate measurement from the peer. If
+ * it is, this function will decode the heart rate measurement and send it to the
+ * application.
+ *
+ * @param[in] p_ble_hrs_c Pointer to the Heart Rate Client structure.
+ * @param[in] p_ble_evt Pointer to the BLE event received.
+ */
+static void on_hvx(ble_hrs_c_t * p_ble_hrs_c, const ble_evt_t * p_ble_evt)
+{
+ // Check if the event is on the link for this instance
+ if (p_ble_hrs_c->conn_handle != p_ble_evt->evt.gattc_evt.conn_handle)
+ {
+ NRF_LOG_DEBUG("Received HVX on link 0x%x, not associated to this instance, ignore",
+ p_ble_evt->evt.gattc_evt.conn_handle);
+ return;
+ }
+
+ NRF_LOG_DEBUG("Received HVX on link 0x%x, hrm_handle 0x%x",
+ p_ble_evt->evt.gattc_evt.params.hvx.handle,
+ p_ble_hrs_c->peer_hrs_db.hrm_handle);
+
+ // Check if this is a heart rate notification.
+ if (p_ble_evt->evt.gattc_evt.params.hvx.handle == p_ble_hrs_c->peer_hrs_db.hrm_handle)
+ {
+ ble_hrs_c_evt_t ble_hrs_c_evt;
+ uint32_t index = 0;
+
+ ble_hrs_c_evt.evt_type = BLE_HRS_C_EVT_HRM_NOTIFICATION;
+ ble_hrs_c_evt.conn_handle = p_ble_hrs_c->conn_handle;
+ ble_hrs_c_evt.params.hrm.rr_intervals_cnt = 0;
+
+ if (!(p_ble_evt->evt.gattc_evt.params.hvx.data[index++] & HRM_FLAG_MASK_HR_16BIT))
+ {
+ // 8 Bit heart rate value received.
+ ble_hrs_c_evt.params.hrm.hr_value = p_ble_evt->evt.gattc_evt.params.hvx.data[index++]; //lint !e415 suppress Lint Warning 415: Likely access out of bond
+ }
+ else
+ {
+ // 16 bit heart rate value received.
+ ble_hrs_c_evt.params.hrm.hr_value =
+ uint16_decode(&(p_ble_evt->evt.gattc_evt.params.hvx.data[index]));
+ index += sizeof(uint16_t);
+ }
+
+ if ((p_ble_evt->evt.gattc_evt.params.hvx.data[0] & HRM_FLAG_MASK_HR_RR_INT))
+ {
+ uint32_t i;
+ /*lint --e{415} --e{416} --e{662} --e{661} -save suppress Warning 415: possible access out of bond */
+ for (i = 0; i < BLE_HRS_C_RR_INTERVALS_MAX_CNT; i ++)
+ {
+ if (index >= p_ble_evt->evt.gattc_evt.params.hvx.len)
+ {
+ break;
+ }
+ ble_hrs_c_evt.params.hrm.rr_intervals[i] =
+ uint16_decode(&(p_ble_evt->evt.gattc_evt.params.hvx.data[index]));
+ index += sizeof(uint16_t);
+ }
+ /*lint -restore*/
+ ble_hrs_c_evt.params.hrm.rr_intervals_cnt = (uint8_t)i;
+ }
+ p_ble_hrs_c->evt_handler(p_ble_hrs_c, &ble_hrs_c_evt);
+ }
+}
+
+
+/**@brief Function for handling Disconnected event received from the SoftDevice.
+ *
+ * @details This function check if the disconnect event is happening on the link
+ * associated with the current instance of the module, if so it will set its
+ * conn_handle to invalid.
+ *
+ * @param[in] p_ble_hrs_c Pointer to the Heart Rate Client structure.
+ * @param[in] p_ble_evt Pointer to the BLE event received.
+ */
+static void on_disconnected(ble_hrs_c_t * p_ble_hrs_c, const ble_evt_t * p_ble_evt)
+{
+ if (p_ble_hrs_c->conn_handle == p_ble_evt->evt.gap_evt.conn_handle)
+ {
+ p_ble_hrs_c->conn_handle = BLE_CONN_HANDLE_INVALID;
+ p_ble_hrs_c->peer_hrs_db.hrm_cccd_handle = BLE_GATT_HANDLE_INVALID;
+ p_ble_hrs_c->peer_hrs_db.hrm_handle = BLE_GATT_HANDLE_INVALID;
+ }
+}
+
+
+void ble_hrs_on_db_disc_evt(ble_hrs_c_t * p_ble_hrs_c, const ble_db_discovery_evt_t * p_evt)
+{
+ // Check if the Heart Rate Service was discovered.
+ if (p_evt->evt_type == BLE_DB_DISCOVERY_COMPLETE &&
+ p_evt->params.discovered_db.srv_uuid.uuid == BLE_UUID_HEART_RATE_SERVICE &&
+ p_evt->params.discovered_db.srv_uuid.type == BLE_UUID_TYPE_BLE)
+ {
+ // Find the CCCD Handle of the Heart Rate Measurement characteristic.
+ uint32_t i;
+
+ ble_hrs_c_evt_t evt;
+
+ evt.evt_type = BLE_HRS_C_EVT_DISCOVERY_COMPLETE;
+ evt.conn_handle = p_evt->conn_handle;
+
+ for (i = 0; i < p_evt->params.discovered_db.char_count; i++)
+ {
+ if (p_evt->params.discovered_db.charateristics[i].characteristic.uuid.uuid ==
+ BLE_UUID_HEART_RATE_MEASUREMENT_CHAR)
+ {
+ // Found Heart Rate characteristic. Store CCCD handle and break.
+ evt.params.peer_db.hrm_cccd_handle =
+ p_evt->params.discovered_db.charateristics[i].cccd_handle;
+ evt.params.peer_db.hrm_handle =
+ p_evt->params.discovered_db.charateristics[i].characteristic.handle_value;
+ break;
+ }
+ }
+
+ NRF_LOG_DEBUG("Heart Rate Service discovered at peer.");
+ //If the instance has been assigned prior to db_discovery, assign the db_handles
+ if (p_ble_hrs_c->conn_handle != BLE_CONN_HANDLE_INVALID)
+ {
+ if ((p_ble_hrs_c->peer_hrs_db.hrm_cccd_handle == BLE_GATT_HANDLE_INVALID)&&
+ (p_ble_hrs_c->peer_hrs_db.hrm_handle == BLE_GATT_HANDLE_INVALID))
+ {
+ p_ble_hrs_c->peer_hrs_db = evt.params.peer_db;
+ }
+ }
+
+
+ p_ble_hrs_c->evt_handler(p_ble_hrs_c, &evt);
+ }
+}
+
+
+uint32_t ble_hrs_c_init(ble_hrs_c_t * p_ble_hrs_c, ble_hrs_c_init_t * p_ble_hrs_c_init)
+{
+ VERIFY_PARAM_NOT_NULL(p_ble_hrs_c);
+ VERIFY_PARAM_NOT_NULL(p_ble_hrs_c_init);
+
+ ble_uuid_t hrs_uuid;
+
+ hrs_uuid.type = BLE_UUID_TYPE_BLE;
+ hrs_uuid.uuid = BLE_UUID_HEART_RATE_SERVICE;
+
+
+ p_ble_hrs_c->evt_handler = p_ble_hrs_c_init->evt_handler;
+ p_ble_hrs_c->conn_handle = BLE_CONN_HANDLE_INVALID;
+ p_ble_hrs_c->peer_hrs_db.hrm_cccd_handle = BLE_GATT_HANDLE_INVALID;
+ p_ble_hrs_c->peer_hrs_db.hrm_handle = BLE_GATT_HANDLE_INVALID;
+
+ return ble_db_discovery_evt_register(&hrs_uuid);
+}
+
+void ble_hrs_c_on_ble_evt(ble_evt_t const * p_ble_evt, void * p_context)
+{
+ ble_hrs_c_t * p_ble_hrs_c = (ble_hrs_c_t *)p_context;
+
+ if ((p_ble_hrs_c == NULL) || (p_ble_evt == NULL))
+ {
+ return;
+ }
+
+ switch (p_ble_evt->header.evt_id)
+ {
+ case BLE_GATTC_EVT_HVX:
+ on_hvx(p_ble_hrs_c, p_ble_evt);
+ break;
+
+ case BLE_GATTC_EVT_WRITE_RSP:
+ on_write_rsp(p_ble_hrs_c, p_ble_evt);
+ break;
+
+ case BLE_GAP_EVT_DISCONNECTED:
+ on_disconnected(p_ble_hrs_c, p_ble_evt);
+ break;
+
+ default:
+ break;
+ }
+}
+
+
+/**@brief Function for creating a message for writing to the CCCD.
+ */
+static uint32_t cccd_configure(uint16_t conn_handle, uint16_t handle_cccd, bool enable)
+{
+ NRF_LOG_DEBUG("Configuring CCCD. CCCD Handle = %d, Connection Handle = %d",
+ handle_cccd,conn_handle);
+
+ tx_message_t * p_msg;
+ uint16_t cccd_val = enable ? BLE_GATT_HVX_NOTIFICATION : 0;
+
+ p_msg = &m_tx_buffer[m_tx_insert_index++];
+ m_tx_insert_index &= TX_BUFFER_MASK;
+
+ p_msg->req.write_req.gattc_params.handle = handle_cccd;
+ p_msg->req.write_req.gattc_params.len = WRITE_MESSAGE_LENGTH;
+ p_msg->req.write_req.gattc_params.p_value = p_msg->req.write_req.gattc_value;
+ p_msg->req.write_req.gattc_params.offset = 0;
+ p_msg->req.write_req.gattc_params.write_op = BLE_GATT_OP_WRITE_REQ;
+ p_msg->req.write_req.gattc_value[0] = LSB_16(cccd_val);
+ p_msg->req.write_req.gattc_value[1] = MSB_16(cccd_val);
+ p_msg->conn_handle = conn_handle;
+ p_msg->type = WRITE_REQ;
+
+ tx_buffer_process();
+ return NRF_SUCCESS;
+}
+
+
+uint32_t ble_hrs_c_hrm_notif_enable(ble_hrs_c_t * p_ble_hrs_c)
+{
+ VERIFY_PARAM_NOT_NULL(p_ble_hrs_c);
+
+ return cccd_configure(p_ble_hrs_c->conn_handle,
+ p_ble_hrs_c->peer_hrs_db.hrm_cccd_handle,
+ true);
+}
+
+
+uint32_t ble_hrs_c_handles_assign(ble_hrs_c_t * p_ble_hrs_c,
+ uint16_t conn_handle,
+ const hrs_db_t * p_peer_hrs_handles)
+{
+ VERIFY_PARAM_NOT_NULL(p_ble_hrs_c);
+
+ p_ble_hrs_c->conn_handle = conn_handle;
+ if (p_peer_hrs_handles != NULL)
+ {
+ p_ble_hrs_c->peer_hrs_db = *p_peer_hrs_handles;
+ }
+ return NRF_SUCCESS;
+}
+/** @}
+ * @endcond
+ */
+#endif // NRF_MODULE_ENABLED(BLE_HRS_C)
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/ble_hrs_c/ble_hrs_c.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/ble_hrs_c/ble_hrs_c.h
new file mode 100644
index 0000000..0dea00f
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/ble_hrs_c/ble_hrs_c.h
@@ -0,0 +1,295 @@
+/**
+ * Copyright (c) 2012 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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
+ *
+ * @defgroup ble_hrs_c Heart Rate Service Client
+ * @{
+ * @ingroup ble_sdk_srv
+ * @brief Heart Rate Service Client module.
+ *
+ * @details This module contains the APIs and types exposed by the Heart Rate Service Client
+ * module. These APIs and types can be used by the application to perform discovery of
+ * Heart Rate Service at the peer and interact with it.
+ *
+ * @warning Currently this module only has support for Heart Rate Measurement characteristic. This
+ * means that it will be able to enable notification of the characteristic at the peer and
+ * be able to receive Heart Rate Measurement notifications from the peer. It does not
+ * support the Body Sensor Location and the Heart Rate Control Point characteristics.
+ * When a Heart Rate Measurement is received, this module will decode only the
+ * Heart Rate Measurement Value (both 8 bit and 16 bit) field from it and provide it to
+ * the application.
+ *
+ * @note The application must register this module as BLE event observer using the
+ * NRF_SDH_BLE_OBSERVER macro. Example:
+ * @code
+ * ble_hrs_c_t instance;
+ * NRF_SDH_BLE_OBSERVER(anything, BLE_HRS_C_BLE_OBSERVER_PRIO,
+ * ble_hrs_c_on_ble_evt, &instance);
+ * @endcode
+ */
+
+#ifndef BLE_HRS_C_H__
+#define BLE_HRS_C_H__
+
+#include <stdint.h>
+#include "ble.h"
+#include "ble_db_discovery.h"
+#include "sdk_config.h"
+#include "nrf_sdh_ble.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**@brief Macro for defining a ble_hrs_c instance.
+ *
+ * @param _name Name of the instance.
+ * @hideinitializer
+ */
+#define BLE_HRS_C_DEF(_name) \
+static ble_hrs_c_t _name; \
+NRF_SDH_BLE_OBSERVER(_name ## _obs, \
+ BLE_HRS_C_BLE_OBSERVER_PRIO, \
+ ble_hrs_c_on_ble_evt, &_name)
+
+/** @brief Macro for defining multiple ble_hrs_c instances.
+ *
+ * @param _name Name of the array of instances.
+ * @param _cnt Number of instances to define.
+ * @hideinitializer
+ */
+#define BLE_HRS_C_ARRAY_DEF(_name, _cnt) \
+static ble_hrs_c_t _name[_cnt]; \
+NRF_SDH_BLE_OBSERVERS(_name ## _obs, \
+ BLE_HRS_C_BLE_OBSERVER_PRIO, \
+ ble_hrs_c_on_ble_evt, &_name, _cnt)
+
+
+/** @brief Maximum number of RR intervals to be decoded for each HRM notifications (any extra RR intervals will be ignored).
+ *
+ * This define should be defined in the sdk_config.h file to override the default.
+ */
+#ifndef BLE_HRS_C_RR_INTERVALS_MAX_CNT
+#define BLE_HRS_C_RR_INTERVALS_MAX_CNT 20
+#endif
+
+
+/**
+ * @defgroup hrs_c_enums Enumerations
+ * @{
+ */
+
+/**@brief HRS Client event type. */
+typedef enum
+{
+ BLE_HRS_C_EVT_DISCOVERY_COMPLETE = 1, /**< Event indicating that the Heart Rate Service has been discovered at the peer. */
+ BLE_HRS_C_EVT_HRM_NOTIFICATION /**< Event indicating that a notification of the Heart Rate Measurement characteristic has been received from the peer. */
+} ble_hrs_c_evt_type_t;
+
+/** @} */
+
+/**
+ * @defgroup hrs_c_structs Structures
+ * @{
+ */
+
+/**@brief Structure containing the heart rate measurement received from the peer. */
+typedef struct
+{
+ uint16_t hr_value; /**< Heart Rate Value. */
+ uint8_t rr_intervals_cnt; /**< Number of RR intervals. */
+ uint16_t rr_intervals[BLE_HRS_C_RR_INTERVALS_MAX_CNT]; /**< RR intervals. */
+} ble_hrm_t;
+
+/**@brief Structure containing the handles related to the Heart Rate Service found on the peer. */
+typedef struct
+{
+ uint16_t hrm_cccd_handle; /**< Handle of the CCCD of the Heart Rate Measurement characteristic. */
+ uint16_t hrm_handle; /**< Handle of the Heart Rate Measurement characteristic as provided by the SoftDevice. */
+} hrs_db_t;
+
+/**@brief Heart Rate Event structure. */
+typedef struct
+{
+ ble_hrs_c_evt_type_t evt_type; /**< Type of the event. */
+ uint16_t conn_handle; /**< Connection handle on which the Heart Rate service was discovered on the peer device..*/
+ union
+ {
+ hrs_db_t peer_db; /**< Heart Rate related handles found on the peer device.. This will be filled if the evt_type is @ref BLE_HRS_C_EVT_DISCOVERY_COMPLETE.*/
+ ble_hrm_t hrm; /**< Heart rate measurement received. This will be filled if the evt_type is @ref BLE_HRS_C_EVT_HRM_NOTIFICATION. */
+ } params;
+} ble_hrs_c_evt_t;
+
+/** @} */
+
+/**
+ * @defgroup hrs_c_types Types
+ * @{
+ */
+
+// Forward declaration of the ble_bas_t type.
+typedef struct ble_hrs_c_s ble_hrs_c_t;
+
+/**@brief Event handler type.
+ *
+ * @details This is the type of the event handler that should be provided by the application
+ * of this module in order to receive events.
+ */
+typedef void (* ble_hrs_c_evt_handler_t) (ble_hrs_c_t * p_ble_hrs_c, ble_hrs_c_evt_t * p_evt);
+
+/** @} */
+
+/**
+ * @addtogroup hrs_c_structs
+ * @{
+ */
+
+/**@brief Heart Rate Client structure.
+ */
+struct ble_hrs_c_s
+{
+ uint16_t conn_handle; /**< Connection handle as provided by the SoftDevice. */
+ hrs_db_t peer_hrs_db; /**< Handles related to HRS on the peer*/
+ ble_hrs_c_evt_handler_t evt_handler; /**< Application event handler to be called when there is an event related to the heart rate service. */
+};
+
+/**@brief Heart Rate Client initialization structure.
+ */
+typedef struct
+{
+ ble_hrs_c_evt_handler_t evt_handler; /**< Event handler to be called by the Heart Rate Client module whenever there is an event related to the Heart Rate Service. */
+} ble_hrs_c_init_t;
+
+/** @} */
+
+
+/**
+ * @defgroup hrs_c_functions Functions
+ * @{
+ */
+
+/**@brief Function for initializing the heart rate client module.
+ *
+ * @details This function will register with the DB Discovery module. There it
+ * registers for the Heart Rate Service. Doing so will make the DB Discovery
+ * module look for the presence of a Heart Rate Service instance at the peer when a
+ * discovery is started.
+ *
+ * @param[in] p_ble_hrs_c Pointer to the heart rate client structure.
+ * @param[in] p_ble_hrs_c_init Pointer to the heart rate initialization structure containing the
+ * initialization information.
+ *
+ * @retval NRF_SUCCESS On successful initialization. Otherwise an error code. This function
+ * propagates the error code returned by the Database Discovery module API
+ * @ref ble_db_discovery_evt_register.
+ */
+uint32_t ble_hrs_c_init(ble_hrs_c_t * p_ble_hrs_c, ble_hrs_c_init_t * p_ble_hrs_c_init);
+
+
+/**@brief Function for handling BLE events from the SoftDevice.
+ *
+ * @details This function will handle the BLE events received from the SoftDevice. If a BLE
+ * event is relevant to the Heart Rate Client module, then it uses it to update
+ * interval variables and, if necessary, send events to the application.
+ *
+ * @param[in] p_ble_evt Pointer to the BLE event.
+ * @param[in] p_context Pointer to the heart rate client structure.
+ */
+void ble_hrs_c_on_ble_evt(ble_evt_t const * p_ble_evt, void * p_context);
+
+
+/**@brief Function for requesting the peer to start sending notification of Heart Rate
+ * Measurement.
+ *
+ * @details This function will enable to notification of the Heart Rate Measurement at the peer
+ * by writing to the CCCD of the Heart Rate Measurement Characteristic.
+ *
+ * @param p_ble_hrs_c Pointer to the heart rate client structure.
+ *
+ * @retval NRF_SUCCESS If the SoftDevice has been requested to write to the CCCD of the peer.
+ * Otherwise, an error code. This function propagates the error code returned
+ * by the SoftDevice API @ref sd_ble_gattc_write.
+ */
+uint32_t ble_hrs_c_hrm_notif_enable(ble_hrs_c_t * p_ble_hrs_c);
+
+
+/**@brief Function for handling events from the database discovery module.
+ *
+ * @details Call this function when getting a callback event from the DB discovery modue.
+ * This function will handle an event from the database discovery module, and determine
+ * if it relates to the discovery of heart rate service at the peer. If so, it will
+ * call the application's event handler indicating that the heart rate service has been
+ * discovered at the peer. It also populates the event with the service related
+ * information before providing it to the application.
+ *
+ * @param[in] p_ble_hrs_c Pointer to the heart rate client structure instance to associate.
+ * @param[in] p_evt Pointer to the event received from the database discovery module.
+ *
+ */
+void ble_hrs_on_db_disc_evt(ble_hrs_c_t * p_ble_hrs_c, const ble_db_discovery_evt_t * p_evt);
+
+
+/**@brief Function for assigning a handles to a this instance of hrs_c.
+ *
+ * @details Call this function when a link has been established with a peer to
+ * associate this link to this instance of the module. This makes it
+ * possible to handle several link and associate each link to a particular
+ * instance of this module.The connection handle and attribute handles will be
+ * provided from the discovery event @ref BLE_HRS_C_EVT_DISCOVERY_COMPLETE.
+ *
+ * @param[in] p_ble_hrs_c Pointer to the heart rate client structure instance to associate.
+ * @param[in] conn_handle Connection handle to associated with the given Heart Rate Client Instance.
+ * @param[in] p_peer_hrs_handles Attribute handles for the HRS server you want this HRS_C client to
+ * interact with.
+ */
+uint32_t ble_hrs_c_handles_assign(ble_hrs_c_t * p_ble_hrs_c,
+ uint16_t conn_handle,
+ const hrs_db_t * p_peer_hrs_handles);
+
+/** @} */ // End tag for Function group.
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // BLE_HRS_C_H__
+
+/** @} */ // End tag for the file.
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/ble_hts/ble_hts.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/ble_hts/ble_hts.c
new file mode 100644
index 0000000..25afa01
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/ble_hts/ble_hts.c
@@ -0,0 +1,462 @@
+/**
+ * Copyright (c) 2012 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+/* Attention!
+ * To maintain compliance with Nordic Semiconductor ASA's Bluetooth profile
+ * qualification listings, this section of source code must not be modified.
+ */
+#include "sdk_common.h"
+#if NRF_MODULE_ENABLED(BLE_HTS)
+#include "ble_err.h"
+#include "ble_hts.h"
+#include <string.h>
+#include "ble_srv_common.h"
+
+
+#define OPCODE_LENGTH 1 /**< Length of opcode inside Health Thermometer Measurement packet. */
+#define HANDLE_LENGTH 2 /**< Length of handle inside Health Thermometer Measurement packet. */
+#define MAX_HTM_LEN (BLE_GATT_ATT_MTU_DEFAULT - OPCODE_LENGTH - HANDLE_LENGTH) /**< Maximum size of a transmitted Health Thermometer Measurement. */
+
+// Health Thermometer Measurement flag bits
+#define HTS_MEAS_FLAG_TEMP_UNITS_BIT (0x01 << 0) /**< Temperature Units flag. */
+#define HTS_MEAS_FLAG_TIME_STAMP_BIT (0x01 << 1) /**< Time Stamp flag. */
+#define HTS_MEAS_FLAG_TEMP_TYPE_BIT (0x01 << 2) /**< Temperature Type flag. */
+
+
+/**@brief Function for handling the Connect event.
+ *
+ * @param[in] p_hts Health Thermometer Service structure.
+ * @param[in] p_ble_evt Event received from the BLE stack.
+ */
+static void on_connect(ble_hts_t * p_hts, ble_evt_t const * p_ble_evt)
+{
+ p_hts->conn_handle = p_ble_evt->evt.gatts_evt.conn_handle;
+}
+
+
+/**@brief Function for handling the Disconnect event.
+ *
+ * @param[in] p_hts Health Thermometer Service structure.
+ * @param[in] p_ble_evt Event received from the BLE stack.
+ */
+static void on_disconnect(ble_hts_t * p_hts, ble_evt_t const * p_ble_evt)
+{
+ UNUSED_PARAMETER(p_ble_evt);
+ p_hts->conn_handle = BLE_CONN_HANDLE_INVALID;
+}
+
+
+/**@brief Function for handling write events to the Blood Pressure Measurement characteristic.
+ *
+ * @param[in] p_hts Health Thermometer Service structure.
+ * @param[in] p_evt_write Write event received from the BLE stack.
+ */
+static void on_cccd_write(ble_hts_t * p_hts, ble_gatts_evt_write_t const * p_evt_write)
+{
+ if (p_evt_write->len == 2)
+ {
+ // CCCD written, update indication state
+ if (p_hts->evt_handler != NULL)
+ {
+ ble_hts_evt_t evt;
+
+ if (ble_srv_is_indication_enabled(p_evt_write->data))
+ {
+ evt.evt_type = BLE_HTS_EVT_INDICATION_ENABLED;
+ }
+ else
+ {
+ evt.evt_type = BLE_HTS_EVT_INDICATION_DISABLED;
+ }
+
+ p_hts->evt_handler(p_hts, &evt);
+ }
+ }
+}
+
+
+/**@brief Function for handling the Write event.
+ *
+ * @param[in] p_hts Health Thermometer Service structure.
+ * @param[in] p_ble_evt Event received from the BLE stack.
+ */
+static void on_write(ble_hts_t * p_hts, ble_evt_t const * p_ble_evt)
+{
+ ble_gatts_evt_write_t const * p_evt_write = &p_ble_evt->evt.gatts_evt.params.write;
+
+ if (p_evt_write->handle == p_hts->meas_handles.cccd_handle)
+ {
+ on_cccd_write(p_hts, p_evt_write);
+ }
+}
+
+
+/**@brief Function for handling the HVC event.
+ *
+ * @details Handles HVC events from the BLE stack.
+ *
+ * @param[in] p_hts Health Thermometer Service structure.
+ * @param[in] p_ble_evt Event received from the BLE stack.
+ */
+static void on_hvc(ble_hts_t * p_hts, ble_evt_t const * p_ble_evt)
+{
+ ble_gatts_evt_hvc_t const * p_hvc = &p_ble_evt->evt.gatts_evt.params.hvc;
+
+ if (p_hvc->handle == p_hts->meas_handles.value_handle)
+ {
+ ble_hts_evt_t evt;
+
+ evt.evt_type = BLE_HTS_EVT_INDICATION_CONFIRMED;
+ p_hts->evt_handler(p_hts, &evt);
+ }
+}
+
+
+void ble_hts_on_ble_evt(ble_evt_t const * p_ble_evt, void * p_context)
+{
+ ble_hts_t * p_hts = (ble_hts_t *)p_context;
+
+ switch (p_ble_evt->header.evt_id)
+ {
+ case BLE_GAP_EVT_CONNECTED:
+ on_connect(p_hts, p_ble_evt);
+ break;
+
+ case BLE_GAP_EVT_DISCONNECTED:
+ on_disconnect(p_hts, p_ble_evt);
+ break;
+
+ case BLE_GATTS_EVT_WRITE:
+ on_write(p_hts, p_ble_evt);
+ break;
+
+ case BLE_GATTS_EVT_HVC:
+ on_hvc(p_hts, p_ble_evt);
+ break;
+
+ default:
+ // No implementation needed.
+ break;
+ }
+}
+
+
+/**@brief Function for encoding a Health Thermometer Measurement.
+ *
+ * @param[in] p_hts Health Thermometer Service structure.
+ * @param[in] p_hts_meas Measurement to be encoded.
+ * @param[out] p_encoded_buffer Buffer where the encoded data will be written.
+ *
+ * @return Size of encoded data.
+ */
+static uint8_t hts_measurement_encode(ble_hts_t * p_hts,
+ ble_hts_meas_t * p_hts_meas,
+ uint8_t * p_encoded_buffer)
+{
+ uint8_t flags = 0;
+ uint8_t len = 1;
+ uint32_t encoded_temp;
+
+ // Flags field
+ if (p_hts_meas->temp_in_fahr_units)
+ {
+ flags |= HTS_MEAS_FLAG_TEMP_UNITS_BIT;
+ }
+ if (p_hts_meas->time_stamp_present)
+ {
+ flags |= HTS_MEAS_FLAG_TIME_STAMP_BIT;
+ }
+
+ // Temperature Measurement Value field
+ if (p_hts_meas->temp_in_fahr_units)
+ {
+ flags |= HTS_MEAS_FLAG_TEMP_UNITS_BIT;
+
+ encoded_temp = ((p_hts_meas->temp_in_fahr.exponent << 24) & 0xFF000000) |
+ ((p_hts_meas->temp_in_fahr.mantissa << 0) & 0x00FFFFFF);
+ }
+ else
+ {
+ encoded_temp = ((p_hts_meas->temp_in_celcius.exponent << 24) & 0xFF000000) |
+ ((p_hts_meas->temp_in_celcius.mantissa << 0) & 0x00FFFFFF);
+ }
+ len += uint32_encode(encoded_temp, &p_encoded_buffer[len]);
+
+ // Time Stamp field
+ if (p_hts_meas->time_stamp_present)
+ {
+ flags |= HTS_MEAS_FLAG_TIME_STAMP_BIT;
+ len += ble_date_time_encode(&p_hts_meas->time_stamp, &p_encoded_buffer[len]);
+ }
+
+ // Temperature Type field
+ if (p_hts_meas->temp_type_present)
+ {
+ flags |= HTS_MEAS_FLAG_TEMP_TYPE_BIT;
+ p_encoded_buffer[len++] = p_hts_meas->temp_type;
+ }
+
+ // Flags field
+ p_encoded_buffer[0] = flags;
+
+ return len;
+}
+
+
+/**@brief Function for adding Health Thermometer Measurement characteristics.
+ *
+ * @param[in] p_hts Health Thermometer Service structure.
+ * @param[in] p_hts_init Information needed to initialize the service.
+ *
+ * @return NRF_SUCCESS on success, otherwise an error code.
+ */
+static uint32_t hts_measurement_char_add(ble_hts_t * p_hts, ble_hts_init_t const * p_hts_init)
+{
+ ble_gatts_char_md_t char_md;
+ ble_gatts_attr_md_t cccd_md;
+ ble_gatts_attr_t attr_char_value;
+ ble_uuid_t ble_uuid;
+ ble_gatts_attr_md_t attr_md;
+ ble_hts_meas_t initial_htm;
+ uint8_t encoded_htm[MAX_HTM_LEN];
+
+ memset(&cccd_md, 0, sizeof(cccd_md));
+
+ BLE_GAP_CONN_SEC_MODE_SET_OPEN(&cccd_md.read_perm);
+ cccd_md.vloc = BLE_GATTS_VLOC_STACK;
+ cccd_md.write_perm = p_hts_init->hts_meas_attr_md.cccd_write_perm;
+
+ memset(&char_md, 0, sizeof(char_md));
+
+ char_md.char_props.indicate = 1;
+ char_md.p_char_user_desc = NULL;
+ char_md.p_char_pf = NULL;
+ char_md.p_user_desc_md = NULL;
+ char_md.p_cccd_md = &cccd_md;
+ char_md.p_sccd_md = NULL;
+
+ BLE_UUID_BLE_ASSIGN(ble_uuid, BLE_UUID_TEMPERATURE_MEASUREMENT_CHAR);
+
+ memset(&attr_md, 0, sizeof(attr_md));
+
+ attr_md.vloc = BLE_GATTS_VLOC_STACK;
+ attr_md.read_perm = p_hts_init->hts_meas_attr_md.read_perm;
+ attr_md.write_perm = p_hts_init->hts_meas_attr_md.write_perm;
+ attr_md.rd_auth = 0;
+ attr_md.wr_auth = 0;
+ attr_md.vlen = 1;
+
+ memset(&attr_char_value, 0, sizeof(attr_char_value));
+ memset(&initial_htm, 0, sizeof(initial_htm));
+
+ attr_char_value.p_uuid = &ble_uuid;
+ attr_char_value.p_attr_md = &attr_md;
+ attr_char_value.init_len = hts_measurement_encode(p_hts, &initial_htm, encoded_htm);
+ attr_char_value.init_offs = 0;
+ attr_char_value.max_len = MAX_HTM_LEN;
+ attr_char_value.p_value = encoded_htm;
+
+ return sd_ble_gatts_characteristic_add(p_hts->service_handle,
+ &char_md,
+ &attr_char_value,
+ &p_hts->meas_handles);
+}
+
+
+/**@brief Function for adding Temperature Type characteristics.
+ *
+ * @param[in] p_hts Health Thermometer Service structure.
+ * @param[in] p_hts_init Information needed to initialize the service.
+ *
+ * @return NRF_SUCCESS on success, otherwise an error code.
+ */
+static uint32_t hts_temp_type_char_add(ble_hts_t * p_hts, ble_hts_init_t const * p_hts_init)
+{
+ ble_gatts_char_md_t char_md;
+ ble_gatts_attr_t attr_char_value;
+ ble_uuid_t ble_uuid;
+ ble_gatts_attr_md_t attr_md;
+ uint8_t init_value_temp_type;
+ uint8_t init_value_encoded[1];
+
+ memset(&char_md, 0, sizeof(char_md));
+
+ char_md.char_props.read = 1;
+ char_md.p_char_user_desc = NULL;
+ char_md.p_char_pf = NULL;
+ char_md.p_user_desc_md = NULL;
+ char_md.p_cccd_md = NULL;
+ char_md.p_sccd_md = NULL;
+
+ BLE_UUID_BLE_ASSIGN(ble_uuid, BLE_UUID_TEMPERATURE_TYPE_CHAR);
+
+ memset(&attr_md, 0, sizeof(attr_md));
+
+ attr_md.vloc = BLE_GATTS_VLOC_STACK;
+ attr_md.read_perm = p_hts_init->hts_temp_type_attr_md.read_perm;
+ attr_md.write_perm = p_hts_init->hts_temp_type_attr_md.write_perm;
+ attr_md.rd_auth = 0;
+ attr_md.wr_auth = 0;
+ attr_md.vlen = 0;
+
+ memset(&attr_char_value, 0, sizeof(attr_char_value));
+
+ init_value_temp_type = p_hts_init->temp_type;
+ init_value_encoded[0] = init_value_temp_type;
+
+ attr_char_value.p_uuid = &ble_uuid;
+ attr_char_value.p_attr_md = &attr_md;
+ attr_char_value.init_len = sizeof (uint8_t);
+ attr_char_value.init_offs = 0;
+ attr_char_value.max_len = sizeof (uint8_t);
+ attr_char_value.p_value = init_value_encoded;
+
+ return sd_ble_gatts_characteristic_add(p_hts->service_handle,
+ &char_md,
+ &attr_char_value,
+ &p_hts->temp_type_handles);
+}
+
+
+uint32_t ble_hts_init(ble_hts_t * p_hts, ble_hts_init_t const * p_hts_init)
+{
+ uint32_t err_code;
+ ble_uuid_t ble_uuid;
+
+ // Initialize service structure
+ p_hts->evt_handler = p_hts_init->evt_handler;
+ p_hts->conn_handle = BLE_CONN_HANDLE_INVALID;
+ p_hts->temp_type = p_hts_init->temp_type;
+
+ // Add service
+ BLE_UUID_BLE_ASSIGN(ble_uuid, BLE_UUID_HEALTH_THERMOMETER_SERVICE);
+
+ err_code = sd_ble_gatts_service_add(BLE_GATTS_SRVC_TYPE_PRIMARY, &ble_uuid, &p_hts->service_handle);
+ if (err_code != NRF_SUCCESS)
+ {
+ return err_code;
+ }
+
+ // Add measurement characteristic
+ err_code = hts_measurement_char_add(p_hts, p_hts_init);
+ if (err_code != NRF_SUCCESS)
+ {
+ return err_code;
+ }
+
+ // Add temperature type characteristic
+ if (p_hts_init->temp_type_as_characteristic)
+ {
+ err_code = hts_temp_type_char_add(p_hts, p_hts_init);
+ if (err_code != NRF_SUCCESS)
+ {
+ return err_code;
+ }
+ }
+
+ return NRF_SUCCESS;
+}
+
+
+uint32_t ble_hts_measurement_send(ble_hts_t * p_hts, ble_hts_meas_t * p_hts_meas)
+{
+ uint32_t err_code;
+
+ // Send value if connected
+ if (p_hts->conn_handle != BLE_CONN_HANDLE_INVALID)
+ {
+ uint8_t encoded_hts_meas[MAX_HTM_LEN];
+ uint16_t len;
+ uint16_t hvx_len;
+ ble_gatts_hvx_params_t hvx_params;
+
+ len = hts_measurement_encode(p_hts, p_hts_meas, encoded_hts_meas);
+ hvx_len = len;
+
+ memset(&hvx_params, 0, sizeof(hvx_params));
+
+ hvx_params.handle = p_hts->meas_handles.value_handle;
+ hvx_params.type = BLE_GATT_HVX_INDICATION;
+ hvx_params.offset = 0;
+ hvx_params.p_len = &hvx_len;
+ hvx_params.p_data = encoded_hts_meas;
+
+ err_code = sd_ble_gatts_hvx(p_hts->conn_handle, &hvx_params);
+ if ((err_code == NRF_SUCCESS) && (hvx_len != len))
+ {
+ err_code = NRF_ERROR_DATA_SIZE;
+ }
+ }
+ else
+ {
+ err_code = NRF_ERROR_INVALID_STATE;
+ }
+
+ return err_code;
+}
+
+
+uint32_t ble_hts_is_indication_enabled(ble_hts_t * p_hts, bool * p_indication_enabled)
+{
+ uint32_t err_code;
+ uint8_t cccd_value_buf[BLE_CCCD_VALUE_LEN];
+ ble_gatts_value_t gatts_value;
+
+ // Initialize value struct.
+ memset(&gatts_value, 0, sizeof(gatts_value));
+
+ gatts_value.len = BLE_CCCD_VALUE_LEN;
+ gatts_value.offset = 0;
+ gatts_value.p_value = cccd_value_buf;
+
+ err_code = sd_ble_gatts_value_get(p_hts->conn_handle,
+ p_hts->meas_handles.cccd_handle,
+ &gatts_value);
+ if (err_code == NRF_SUCCESS)
+ {
+ *p_indication_enabled = ble_srv_is_indication_enabled(cccd_value_buf);
+ }
+ if (err_code == BLE_ERROR_GATTS_SYS_ATTR_MISSING)
+ {
+ *p_indication_enabled = false;
+ return NRF_SUCCESS;
+ }
+ return err_code;
+}
+#endif // NRF_MODULE_ENABLED(BLE_HTS)
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/ble_hts/ble_hts.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/ble_hts/ble_hts.h
new file mode 100644
index 0000000..a9f76cd
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/ble_hts/ble_hts.h
@@ -0,0 +1,219 @@
+/**
+ * Copyright (c) 2012 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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
+ *
+ * @defgroup ble_hts Health Thermometer Service
+ * @{
+ * @ingroup ble_sdk_srv
+ * @brief Health Thermometer Service module.
+ *
+ * @details This module implements the Health Thermometer Service.
+ *
+ * If an event handler is supplied by the application, the Health Thermometer
+ * Service will generate Health Thermometer Service events to the application.
+ *
+ * @note The application must register this module as BLE event observer using the
+ * NRF_SDH_BLE_OBSERVER macro. Example:
+ * @code
+ * ble_hts_t instance;
+ * NRF_SDH_BLE_OBSERVER(anything, BLE_HTS_BLE_OBSERVER_PRIO,
+ * ble_hts_on_ble_evt, &instance);
+ * @endcode
+ *
+ * @note Attention!
+ * To maintain compliance with Nordic Semiconductor ASA Bluetooth profile
+ * qualification listings, this section of source code must not be modified.
+ */
+
+#ifndef BLE_HTS_H__
+#define BLE_HTS_H__
+
+#include <stdint.h>
+#include <stdbool.h>
+#include "ble.h"
+#include "ble_srv_common.h"
+#include "ble_date_time.h"
+#include "nrf_sdh_ble.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**@brief Macro for defining a ble_hts instance.
+ *
+ * @param _name Name of the instance.
+ * @hideinitializer
+ */
+#define BLE_HTS_DEF(_name) \
+static ble_hts_t _name; \
+NRF_SDH_BLE_OBSERVER(_name ## _obs, \
+ BLE_HTS_BLE_OBSERVER_PRIO, \
+ ble_hts_on_ble_evt, &_name)
+
+// Temperature Type measurement locations
+#define BLE_HTS_TEMP_TYPE_ARMPIT 1
+#define BLE_HTS_TEMP_TYPE_BODY 2
+#define BLE_HTS_TEMP_TYPE_EAR 3
+#define BLE_HTS_TEMP_TYPE_FINGER 4
+#define BLE_HTS_TEMP_TYPE_GI_TRACT 5
+#define BLE_HTS_TEMP_TYPE_MOUTH 6
+#define BLE_HTS_TEMP_TYPE_RECTUM 7
+#define BLE_HTS_TEMP_TYPE_TOE 8
+#define BLE_HTS_TEMP_TYPE_EAR_DRUM 9
+
+
+/**@brief Health Thermometer Service event type. */
+typedef enum
+{
+ BLE_HTS_EVT_INDICATION_ENABLED, /**< Health Thermometer value indication enabled event. */
+ BLE_HTS_EVT_INDICATION_DISABLED, /**< Health Thermometer value indication disabled event. */
+ BLE_HTS_EVT_INDICATION_CONFIRMED /**< Confirmation of a temperature measurement indication has been received. */
+} ble_hts_evt_type_t;
+
+/**@brief Health Thermometer Service event. */
+typedef struct
+{
+ ble_hts_evt_type_t evt_type; /**< Type of event. */
+} ble_hts_evt_t;
+
+// Forward declaration of the ble_hts_t type.
+typedef struct ble_hts_s ble_hts_t;
+
+/**@brief Health Thermometer Service event handler type. */
+typedef void (*ble_hts_evt_handler_t) (ble_hts_t * p_hts, ble_hts_evt_t * p_evt);
+
+/**@brief FLOAT format (IEEE-11073 32-bit FLOAT, defined as a 32-bit value with a 24-bit mantissa
+ * and an 8-bit exponent. */
+typedef struct
+{
+ int8_t exponent; /**< Base 10 exponent */
+ int32_t mantissa; /**< Mantissa, should be using only 24 bits */
+} ieee_float32_t;
+
+/**@brief Health Thermometer Service init structure. This contains all options and data
+ * needed for initialization of the service. */
+typedef struct
+{
+ ble_hts_evt_handler_t evt_handler; /**< Event handler to be called for handling events in the Health Thermometer Service. */
+ ble_srv_cccd_security_mode_t hts_meas_attr_md; /**< Initial security level for health thermometer measurement attribute */
+ ble_srv_security_mode_t hts_temp_type_attr_md; /**< Initial security level for health thermometer tempearture type attribute */
+ uint8_t temp_type_as_characteristic; /**< Set non-zero if temp type given as characteristic */
+ uint8_t temp_type; /**< Temperature type if temperature characteristic is used */
+} ble_hts_init_t;
+
+/**@brief Health Thermometer Service structure. This contains various status information for
+ * the service. */
+struct ble_hts_s
+{
+ ble_hts_evt_handler_t evt_handler; /**< Event handler to be called for handling events in the Health Thermometer Service. */
+ uint16_t service_handle; /**< Handle of Health Thermometer Service (as provided by the BLE stack). */
+ ble_gatts_char_handles_t meas_handles; /**< Handles related to the Health Thermometer Measurement characteristic. */
+ ble_gatts_char_handles_t temp_type_handles; /**< Handles related to the Health Thermometer Temperature Type characteristic. */
+ uint16_t conn_handle; /**< Handle of the current connection (as provided by the BLE stack, is BLE_CONN_HANDLE_INVALID if not in a connection). */
+ uint8_t temp_type; /**< Temperature type indicates where the measurement was taken. */
+};
+
+/**@brief Health Thermometer Service measurement structure. This contains a Health Thermometer
+ * measurement. */
+typedef struct ble_hts_meas_s
+{
+ bool temp_in_fahr_units; /**< True if Temperature is in Fahrenheit units, Celcius otherwise. */
+ bool time_stamp_present; /**< True if Time Stamp is present. */
+ bool temp_type_present; /**< True if Temperature Type is present. */
+ ieee_float32_t temp_in_celcius; /**< Temperature Measurement Value (Celcius). */
+ ieee_float32_t temp_in_fahr; /**< Temperature Measurement Value (Fahrenheit). */
+ ble_date_time_t time_stamp; /**< Time Stamp. */
+ uint8_t temp_type; /**< Temperature Type. */
+} ble_hts_meas_t;
+
+
+/**@brief Function for initializing the Health Thermometer Service.
+ *
+ * @param[out] p_hts Health Thermometer Service structure. This structure will have to
+ * be supplied by the application. It will be initialized by this function,
+ * and will later be used to identify this particular service instance.
+ * @param[in] p_hts_init Information needed to initialize the service.
+ *
+ * @return NRF_SUCCESS on successful initialization of service, otherwise an error code.
+ */
+uint32_t ble_hts_init(ble_hts_t * p_hts, const ble_hts_init_t * p_hts_init);
+
+
+/**@brief Function for handling the Application's BLE Stack events.
+ *
+ * @details Handles all events from the BLE stack of interest to the Health Thermometer Service.
+ *
+ * @param[in] p_ble_evt Event received from the BLE stack.
+ * @param[in] p_context Health Thermometer Service structure.
+ */
+void ble_hts_on_ble_evt(ble_evt_t const * p_ble_evt, void * p_context);
+
+
+/**@brief Function for sending health thermometer measurement if indication has been enabled.
+ *
+ * @details The application calls this function after having performed a Health Thermometer
+ * measurement. If indication has been enabled, the measurement data is encoded and
+ * sent to the client.
+ *
+ * @param[in] p_hts Health Thermometer Service structure.
+ * @param[in] p_hts_meas Pointer to new health thermometer measurement.
+ *
+ * @return NRF_SUCCESS on success, otherwise an error code.
+ */
+uint32_t ble_hts_measurement_send(ble_hts_t * p_hts, ble_hts_meas_t * p_hts_meas);
+
+
+/**@brief Function for checking if indication of Temperature Measurement is currently enabled.
+ *
+ * @param[in] p_hts Health Thermometer Service structure.
+ * @param[out] p_indication_enabled TRUE if indication is enabled, FALSE otherwise.
+ *
+ * @return NRF_SUCCESS on success, otherwise an error code.
+ */
+uint32_t ble_hts_is_indication_enabled(ble_hts_t * p_hts, bool * p_indication_enabled);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // BLE_HTS_H__
+
+/** @} */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/ble_ias/ble_ias.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/ble_ias/ble_ias.c
new file mode 100644
index 0000000..55a0b20
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/ble_ias/ble_ias.c
@@ -0,0 +1,242 @@
+/**
+ * Copyright (c) 2012 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+/* Attention!
+ * To maintain compliance with Nordic Semiconductor ASA's Bluetooth profile
+ * qualification listings, this section of source code must not be modified.
+ */
+#include "sdk_common.h"
+#if NRF_MODULE_ENABLED(BLE_IAS)
+#include "ble_ias.h"
+#include <string.h>
+#include "ble_srv_common.h"
+
+#define NRF_LOG_MODULE_NAME ble_ias
+#if BLE_IAS_CONFIG_LOG_ENABLED
+#define NRF_LOG_LEVEL BLE_IAS_CONFIG_LOG_LEVEL
+#define NRF_LOG_INFO_COLOR BLE_IAS_CONFIG_INFO_COLOR
+#define NRF_LOG_DEBUG_COLOR BLE_IAS_CONFIG_DEBUG_COLOR
+#else // BLE_IAS_CONFIG_LOG_ENABLED
+#define NRF_LOG_LEVEL 0
+#endif // BLE_IAS_CONFIG_LOG_ENABLED
+#include "nrf_log.h"
+NRF_LOG_MODULE_REGISTER();
+
+
+#define INITIAL_ALERT_LEVEL BLE_CHAR_ALERT_LEVEL_NO_ALERT
+
+
+/**@brief Function for handling the Connect event.
+ *
+ * @param[in] p_ias Immediate Alert Service structure.
+ * @param[in] p_ble_evt Event received from the BLE stack.
+ */
+static void on_connect(ble_ias_t * p_ias, ble_evt_t const * p_ble_evt)
+{
+ ret_code_t err_code;
+ ble_ias_client_context_t * p_client = NULL;
+
+ err_code = blcm_link_ctx_get(p_ias->p_link_ctx_storage,
+ p_ble_evt->evt.gap_evt.conn_handle,
+ (void *) &p_client);
+ if (err_code != NRF_SUCCESS)
+ {
+ NRF_LOG_ERROR("Link context for 0x%02X connection handle could not be fetched.",
+ p_ble_evt->evt.gap_evt.conn_handle);
+ }
+ else
+ {
+ p_client->alert_level = INITIAL_ALERT_LEVEL;
+ }
+}
+
+
+/**@brief Function for handling the Write event.
+ *
+ * @param[in] p_ias Immediate Alert Service structure.
+ * @param[in] p_ble_evt Event received from the BLE stack.
+ */
+static void on_write(ble_ias_t * p_ias, ble_evt_t const * p_ble_evt)
+{
+ ble_gatts_evt_write_t const * p_evt_write = &p_ble_evt->evt.gatts_evt.params.write;
+
+ if ((p_evt_write->handle == p_ias->alert_level_handles.value_handle) && (p_evt_write->len == 1))
+ {
+ // Alert level written, call application event handler
+ ret_code_t err_code;
+ ble_ias_evt_t evt;
+ ble_ias_client_context_t * p_client;
+
+ err_code = blcm_link_ctx_get(p_ias->p_link_ctx_storage,
+ p_ble_evt->evt.gatts_evt.conn_handle,
+ (void *) &p_client);
+ if (err_code != NRF_SUCCESS)
+ {
+ NRF_LOG_ERROR("Link context for 0x%02X connection handle could not be fetched.",
+ p_ble_evt->evt.gatts_evt.conn_handle);
+ }
+ else
+ {
+ p_client->alert_level = p_evt_write->data[0];
+ }
+
+ evt.evt_type = BLE_IAS_EVT_ALERT_LEVEL_UPDATED;
+ evt.conn_handle = p_ble_evt->evt.gatts_evt.conn_handle;
+ evt.p_link_ctx = p_client;
+
+ p_ias->evt_handler(p_ias, &evt);
+ }
+}
+
+
+void ble_ias_on_ble_evt(ble_evt_t const * p_ble_evt, void * p_context)
+{
+ ble_ias_t * p_ias = (ble_ias_t *)p_context;
+
+ switch (p_ble_evt->header.evt_id)
+ {
+ case BLE_GAP_EVT_CONNECTED:
+ on_connect(p_ias, p_ble_evt);
+ break;
+
+ case BLE_GATTS_EVT_WRITE:
+ on_write(p_ias, p_ble_evt);
+ break;
+
+ default:
+ // No implementation needed.
+ break;
+ }
+}
+
+
+/**@brief Function for adding Alert Level characteristics.
+ *
+ * @param[in] p_ias Immediate Alert Service structure.
+ * @param[in] p_ias_init Information needed to initialize the service.
+ *
+ * @return NRF_SUCCESS on success, otherwise an error code.
+ */
+static uint32_t alert_level_char_add(ble_ias_t * p_ias)
+{
+ ble_gatts_char_md_t char_md;
+ ble_gatts_attr_t attr_char_value;
+ ble_uuid_t ble_uuid;
+ ble_gatts_attr_md_t attr_md;
+ uint8_t initial_alert_level;
+
+ memset(&char_md, 0, sizeof(char_md));
+
+ char_md.char_props.write_wo_resp = 1;
+ char_md.p_char_user_desc = NULL;
+ char_md.p_char_pf = NULL;
+ char_md.p_user_desc_md = NULL;
+ char_md.p_cccd_md = NULL;
+ char_md.p_sccd_md = NULL;
+
+ BLE_UUID_BLE_ASSIGN(ble_uuid, BLE_UUID_ALERT_LEVEL_CHAR);
+
+ memset(&attr_md, 0, sizeof(attr_md));
+
+ BLE_GAP_CONN_SEC_MODE_SET_NO_ACCESS(&attr_md.read_perm);
+ BLE_GAP_CONN_SEC_MODE_SET_ENC_NO_MITM(&attr_md.write_perm);
+
+ attr_md.vloc = BLE_GATTS_VLOC_STACK;
+ attr_md.rd_auth = 0;
+ attr_md.wr_auth = 0;
+ attr_md.vlen = 0;
+
+ memset(&attr_char_value, 0, sizeof(attr_char_value));
+ initial_alert_level = INITIAL_ALERT_LEVEL;
+
+ attr_char_value.p_uuid = &ble_uuid;
+ attr_char_value.p_attr_md = &attr_md;
+ attr_char_value.init_len = sizeof (uint8_t);
+ attr_char_value.init_offs = 0;
+ attr_char_value.max_len = sizeof (uint8_t);
+ attr_char_value.p_value = &initial_alert_level;
+
+ return sd_ble_gatts_characteristic_add(p_ias->service_handle,
+ &char_md,
+ &attr_char_value,
+ &p_ias->alert_level_handles);
+}
+
+
+uint32_t ble_ias_init(ble_ias_t * p_ias, const ble_ias_init_t * p_ias_init)
+{
+ uint32_t err_code;
+ ble_uuid_t ble_uuid;
+
+ // Initialize service structure
+ if (p_ias_init->evt_handler == NULL)
+ {
+ return NRF_ERROR_INVALID_PARAM;
+ }
+ p_ias->evt_handler = p_ias_init->evt_handler;
+
+ // Add service
+ BLE_UUID_BLE_ASSIGN(ble_uuid, BLE_UUID_IMMEDIATE_ALERT_SERVICE);
+
+ err_code = sd_ble_gatts_service_add(BLE_GATTS_SRVC_TYPE_PRIMARY,
+ &ble_uuid,
+ &p_ias->service_handle);
+ VERIFY_SUCCESS(err_code);
+
+ // Add alert level characteristic
+ err_code = alert_level_char_add(p_ias);
+ VERIFY_SUCCESS(err_code);
+
+ return err_code;
+}
+
+
+uint32_t ble_ias_alert_level_get(ble_ias_t * p_ias, uint16_t conn_handle, uint8_t * p_alert_level)
+{
+ ret_code_t err_code;
+ ble_ias_client_context_t * p_client;
+
+ err_code = blcm_link_ctx_get(p_ias->p_link_ctx_storage, conn_handle, (void *) &p_client);
+ VERIFY_SUCCESS(err_code);
+
+ *p_alert_level = p_client->alert_level;
+ return NRF_SUCCESS;
+}
+
+#endif // NRF_MODULE_ENABLED(BLE_IAS)
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/ble_ias/ble_ias.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/ble_ias/ble_ias.h
new file mode 100644
index 0000000..985ecdb
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/ble_ias/ble_ias.h
@@ -0,0 +1,194 @@
+/**
+ * Copyright (c) 2012 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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
+ *
+ * @defgroup ble_ias Immediate Alert Service
+ * @{
+ * @ingroup ble_sdk_srv
+ * @brief Immediate Alert Service module.
+ *
+ * @details This module implements the Immediate Alert Service with the Alert Level characteristic.
+ * During initialization it adds the Immediate Alert Service and Alert Level characteristic
+ * to the BLE stack database.
+ *
+ * The application must supply an event handler for receiving Immediate Alert Service
+ * events. Using this handler, the service will notify the application when the
+ * Alert Level characteristic value changes.
+ *
+ * The service also provides a function for letting the application poll the current
+ * value of the Alert Level characteristic.
+ *
+ * @note The application must register this module as BLE event observer using the
+ * NRF_SDH_BLE_OBSERVER macro. Example:
+ * @code
+ * ble_ias_t instance;
+ * NRF_SDH_BLE_OBSERVER(anything, BLE_IAS_BLE_OBSERVER_PRIO,
+ * ble_ias_on_ble_evt, &instance);
+ * @endcode
+ *
+ * @note Attention!
+ * To maintain compliance with Nordic Semiconductor ASA Bluetooth profile
+ * qualification listings, this section of source code must not be modified.
+*/
+
+#ifndef BLE_IAS_H__
+#define BLE_IAS_H__
+
+#include <stdint.h>
+#include "ble.h"
+#include "nrf_sdh_ble.h"
+#include "ble_link_ctx_manager.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+/**@brief Macro for defining a ble_ias instance.
+ *
+ * @param _name Name of the instance.
+ * @param[in] _ias_max_clients Maximum number of IAS clients connected at a time.
+ * @hideinitializer
+ */
+#define BLE_IAS_DEF(_name, _ias_max_clients) \
+ BLE_LINK_CTX_MANAGER_DEF(CONCAT_2(_name, _link_ctx_storage), \
+ (_ias_max_clients), \
+ sizeof(ble_ias_client_context_t)); \
+ static ble_ias_t _name = \
+ { \
+ .p_link_ctx_storage = &CONCAT_2(_name, _link_ctx_storage) \
+ }; \
+ NRF_SDH_BLE_OBSERVER(_name ## _obs, \
+ BLE_IAS_BLE_OBSERVER_PRIO, \
+ ble_ias_on_ble_evt, \
+ &_name)
+
+
+/**@brief Immediate Alert Service event type. */
+typedef enum
+{
+ BLE_IAS_EVT_ALERT_LEVEL_UPDATED /**< Alert Level Updated event. */
+} ble_ias_evt_type_t;
+
+
+/**@brief Immediate Alert Service client context structure.
+ *
+ * @details This structure contains state context related to hosts.
+ */
+typedef struct
+{
+ uint8_t alert_level; /**< New Alert Level value. */
+} ble_ias_client_context_t;
+
+
+/**@brief Immediate Alert Service event. */
+typedef struct
+{
+ ble_ias_evt_type_t evt_type; /**< Type of event. */
+ uint16_t conn_handle; /**< Connection handle. */
+ ble_ias_client_context_t * p_link_ctx; /**< A pointer to the link context. */
+} ble_ias_evt_t;
+
+
+// Forward declaration of the ble_ias_t type.
+typedef struct ble_ias_s ble_ias_t;
+
+
+/**@brief Immediate Alert Service event handler type. */
+typedef void (*ble_ias_evt_handler_t) (ble_ias_t * p_ias, ble_ias_evt_t * p_evt);
+
+
+/**@brief Immediate Alert Service init structure. This contains all options and data needed for
+ * initialization of the service. */
+typedef struct
+{
+ ble_ias_evt_handler_t evt_handler; /**< Event handler to be called for handling events in the Immediate Alert Service. */
+} ble_ias_init_t;
+
+
+/**@brief Immediate Alert Service structure. This contains various status information for the
+ * service. */
+struct ble_ias_s
+{
+ ble_ias_evt_handler_t evt_handler; /**< Event handler to be called for handling events in the Immediate Alert Service. */
+ uint16_t service_handle; /**< Handle of Immediate Alert Service (as provided by the BLE stack). */
+ ble_gatts_char_handles_t alert_level_handles; /**< Handles related to the Alert Level characteristic. */
+ blcm_link_ctx_storage_t * const p_link_ctx_storage; /**< Pointer to link context storage with handles of all current connections and its context. */
+};
+
+
+/**@brief Function for initializing the Immediate Alert Service.
+ *
+ * @param[out] p_ias Immediate Alert Service structure. This structure will have to be
+ * supplied by the application. It will be initialized by this function,
+ * and will later be used to identify this particular service instance.
+ * @param[in] p_ias_init Information needed to initialize the service.
+ *
+ * @return NRF_SUCCESS on successful initialization of service, otherwise an error code.
+ */
+uint32_t ble_ias_init(ble_ias_t * p_ias, const ble_ias_init_t * p_ias_init);
+
+
+/**@brief Function for handling the Application's BLE Stack events.
+ *
+ * @details Handles all events from the BLE stack of interest to the Immediate Alert Service.
+ *
+ * @param[in] p_ble_evt Event received from the BLE stack.
+ * @param[in] p_context Immediate Alert Service structure.
+ */
+void ble_ias_on_ble_evt(ble_evt_t const * p_ble_evt, void * p_context);
+
+
+/**@brief Function for getting value of the Alert Level characteristic.
+ *
+ * @param[in] p_ias Immediate Alert Service structure.
+ * @param[in] conn_handle Connection handle of the destination client.
+ * @param[out] p_alert_level Alert Level value which has been set by the specific client.
+ */
+uint32_t ble_ias_alert_level_get(ble_ias_t * p_ias, uint16_t conn_handle, uint8_t * p_alert_level);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // BLE_IAS_H__
+
+/** @} */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/ble_ias_c/ble_ias_c.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/ble_ias_c/ble_ias_c.c
new file mode 100644
index 0000000..c303cd6
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/ble_ias_c/ble_ias_c.c
@@ -0,0 +1,214 @@
+/**
+ * Copyright (c) 2012 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#include "sdk_common.h"
+#if NRF_MODULE_ENABLED(BLE_IAS_C)
+#include "ble_ias_c.h"
+
+#include <string.h>
+#include "ble.h"
+#include "ble_srv_common.h"
+#include "ble_gattc.h"
+#include "ble_db_discovery.h"
+
+
+void ble_ias_c_on_db_disc_evt(ble_ias_c_t * p_ias_c, ble_db_discovery_evt_t const * p_evt)
+{
+ ble_ias_c_evt_t evt;
+
+ memset(&evt, 0, sizeof(ble_ias_c_evt_t));
+ evt.evt_type = BLE_IAS_C_EVT_DISCOVERY_FAILED;
+ evt.conn_handle = p_evt->conn_handle;
+
+ ble_gatt_db_char_t const * p_chars = p_evt->params.discovered_db.charateristics;
+
+ // Check if the Immediate Alert Service was discovered.
+ if ( (p_evt->evt_type == BLE_DB_DISCOVERY_COMPLETE)
+ && (p_evt->params.discovered_db.srv_uuid.uuid == BLE_UUID_IMMEDIATE_ALERT_SERVICE)
+ && (p_evt->params.discovered_db.srv_uuid.type == BLE_UUID_TYPE_BLE))
+ {
+ for (uint32_t i = 0; i < p_evt->params.discovered_db.char_count; i++)
+ {
+ // The Alert Level characteristic in the Immediate Alert Service instance is found
+ // on peer. Check if it has the correct property 'Write without response'.
+ switch (p_chars[i].characteristic.uuid.uuid)
+ {
+ case BLE_UUID_ALERT_LEVEL_CHAR:
+ if (p_chars[i].characteristic.char_props.write_wo_resp)
+ {
+ // Found Alert Level characteristic inside the Immediate Alert Service.
+ memcpy(&evt.alert_level,
+ &p_chars[i].characteristic,
+ sizeof(ble_gattc_char_t));
+ }
+ break;
+
+ default:
+ break;
+ }
+ }
+ }
+ if (evt.alert_level.handle_value != BLE_GATT_HANDLE_INVALID)
+ {
+ evt.evt_type = BLE_IAS_C_EVT_DISCOVERY_COMPLETE;
+ }
+
+ p_ias_c->evt_handler(p_ias_c, &evt);
+}
+
+
+uint32_t ble_ias_c_init(ble_ias_c_t * p_ias_c, ble_ias_c_init_t const * p_ias_c_init)
+{
+ VERIFY_PARAM_NOT_NULL(p_ias_c);
+ VERIFY_PARAM_NOT_NULL(p_ias_c_init->evt_handler);
+ VERIFY_PARAM_NOT_NULL(p_ias_c_init);
+
+ p_ias_c->evt_handler = p_ias_c_init->evt_handler;
+ p_ias_c->error_handler = p_ias_c_init->error_handler;
+ p_ias_c->conn_handle = BLE_CONN_HANDLE_INVALID;
+ p_ias_c->alert_level_char.handle_value = BLE_GATT_HANDLE_INVALID;
+
+ BLE_UUID_BLE_ASSIGN(p_ias_c->alert_level_char.uuid, BLE_UUID_ALERT_LEVEL_CHAR);
+ BLE_UUID_BLE_ASSIGN(p_ias_c->service_uuid, BLE_UUID_IMMEDIATE_ALERT_SERVICE);
+
+ return ble_db_discovery_evt_register(&p_ias_c->service_uuid);
+}
+
+
+
+/**@brief Function for handling the Disconnect event.
+ *
+ * @param[in] p_ias_c Immediate Alert Service client structure.
+ * @param[in] p_ble_evt Event received from the BLE stack.
+ */
+static void on_disconnect(ble_ias_c_t * p_ias_c, ble_evt_t const * p_ble_evt)
+{
+ // The following values will be re-initialized when a new connection is made.
+ p_ias_c->conn_handle = BLE_CONN_HANDLE_INVALID;
+
+ if (ble_ias_c_is_discovered(p_ias_c))
+ {
+ // There was a valid instance of IAS on the peer. Send an event to the
+ // application, so that it can do any clean up related to this module.
+ ble_ias_c_evt_t evt;
+
+ evt.evt_type = BLE_IAS_C_EVT_DISCONN_COMPLETE;
+
+ p_ias_c->evt_handler(p_ias_c, &evt);
+ p_ias_c->alert_level_char.handle_value = BLE_GATT_HANDLE_INVALID;
+ }
+}
+
+
+void ble_ias_c_on_ble_evt(ble_evt_t const * p_ble_evt, void * p_context)
+{
+ uint32_t err_code = NRF_SUCCESS;
+ ble_ias_c_t * p_ias_c = (ble_ias_c_t *)p_context;
+
+ switch (p_ble_evt->header.evt_id)
+ {
+ case BLE_GAP_EVT_DISCONNECTED:
+ on_disconnect(p_ias_c, p_ble_evt);
+ break;
+
+ default:
+ // No implementation needed.
+ break;
+ }
+
+ if ((err_code != NRF_SUCCESS) && (p_ias_c->error_handler != NULL))
+ {
+ p_ias_c->error_handler(err_code);
+ }
+}
+
+
+/**@brief Function for performing a Write procedure.
+ *
+ * @param[in] conn_handle Handle of the connection on which to perform the write operation.
+ * @param[in] write_handle Handle of the attribute to be written.
+ * @param[in] length Length of data to be written.
+ * @param[in] p_value Data to be written.
+ *
+ * @return NRF_SUCCESS on success, otherwise an error code.
+ */
+static uint32_t write_characteristic_value(uint16_t conn_handle,
+ uint16_t write_handle,
+ uint16_t length,
+ uint8_t * p_value)
+{
+ ble_gattc_write_params_t write_params;
+
+ memset(&write_params, 0, sizeof(write_params));
+
+ write_params.handle = write_handle;
+ write_params.write_op = BLE_GATT_OP_WRITE_CMD;
+ write_params.offset = 0;
+ write_params.len = length;
+ write_params.p_value = p_value;
+
+ return sd_ble_gattc_write(conn_handle, &write_params);
+}
+
+
+uint32_t ble_ias_c_send_alert_level(ble_ias_c_t const * p_ias_c, uint8_t alert_level)
+{
+ if (!ble_ias_c_is_discovered(p_ias_c))
+ {
+ return NRF_ERROR_NOT_FOUND;
+ }
+
+ return write_characteristic_value(p_ias_c->conn_handle,
+ p_ias_c->alert_level_char.handle_value,
+ sizeof(uint8_t),
+ &alert_level);
+}
+
+
+uint32_t ble_ias_c_handles_assign(ble_ias_c_t * p_ias_c,
+ const uint16_t conn_handle,
+ const uint16_t alert_level_handle)
+{
+ VERIFY_PARAM_NOT_NULL(p_ias_c);
+
+ p_ias_c->conn_handle = conn_handle;
+ p_ias_c->alert_level_char.handle_value = alert_level_handle;
+ return NRF_SUCCESS;
+}
+#endif //NRF_MODULE_ENABLED(BLE_IAS_C)
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/ble_ias_c/ble_ias_c.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/ble_ias_c/ble_ias_c.h
new file mode 100644
index 0000000..5d46d93
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/ble_ias_c/ble_ias_c.h
@@ -0,0 +1,237 @@
+/**
+ * Copyright (c) 2012 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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
+ *
+ * @defgroup ble_ias_c Immediate Alert Service Client
+ * @{
+ * @ingroup ble_sdk_srv
+ * @brief Immediate Alert Service Client module
+ *
+ * @details This module implements the Immediate Alert Service client - locator role of the Find Me
+ * profile. On @ref BLE_GAP_EVT_CONNECTED event, this module starts discovery of the
+ * Immediate Alert Service with Alert Level characteristic at the peer. This module will
+ * indicate the application about a successful service & characteristic discovery using
+ * @ref BLE_IAS_C_EVT_DISCOVERY_COMPLETE event. The application can use @ref
+ * ble_ias_c_send_alert_level function to signal alerts to the peer.
+ *
+ * @note The application must register this module as BLE event observer using the
+ * NRF_SDH_BLE_OBSERVER macro. Example:
+ * @code
+ * ble_ias_c_t instance;
+ * NRF_SDH_BLE_OBSERVER(anything, BLE_IAS_C_BLE_OBSERVER_PRIO,
+ * ble_ias_c_on_ble_evt, &instance);
+ * @endcode
+ */
+
+#ifndef BLE_IAS_C_H__
+#define BLE_IAS_C_H__
+
+#include <stdint.h>
+#include "ble_srv_common.h"
+#include "ble_gattc.h"
+#include "ble.h"
+#include "ble_db_discovery.h"
+#include "nrf_sdh_ble.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**@brief Macro for defining a ble_ias_c instance.
+ *
+ * @param _name Name of the instance.
+ * @hideinitializer
+ */
+#define BLE_IAS_C_DEF(_name) \
+static ble_ias_c_t _name; \
+NRF_SDH_BLE_OBSERVER(_name ## _obs, \
+ BLE_IAS_C_BLE_OBSERVER_PRIO, \
+ ble_ias_c_on_ble_evt, &_name)
+
+/** @brief Macro for defining multiple ble_ias_c instances.
+ *
+ * @param _name Name of the array of instances.
+ * @param _cnt Number of instances to define.
+ * @hideinitializer
+ */
+#define BLE_IAS_C_ARRAY_DEF(_name, _cnt) \
+static ble_ias_c_t _name[_cnt]; \
+NRF_SDH_BLE_OBSERVERS(_name ## _obs, \
+ BLE_IAS_C_BLE_OBSERVER_PRIO, \
+ ble_ias_c_on_ble_evt, &_name, _cnt)
+
+
+// Forward declaration of the ble_ias_c_t type.
+typedef struct ble_ias_c_s ble_ias_c_t;
+
+/**@brief Immediate Alert Service client event type. */
+typedef enum
+{
+ BLE_IAS_C_EVT_DISCOVERY_COMPLETE, /**< Event indicating that the Immediate Alert Service is found at the peer. */
+ BLE_IAS_C_EVT_DISCOVERY_FAILED, /**< Event indicating that the Immediate Alert Service is not found at the peer. */
+ BLE_IAS_C_EVT_DISCONN_COMPLETE /**< Event indicating that the Immediate Alert Service client module has completed the processing of BLE_GAP_EVT_DISCONNECTED event. This event is raised only if a valid instance of IAS was found at the peer during the discovery phase. This event can be used the application to do clean up related to the IAS Client.*/
+} ble_ias_c_evt_type_t;
+
+/**@brief Immediate Alert Service client event. */
+typedef struct
+{
+ ble_ias_c_evt_type_t evt_type; /**< Type of event. */
+ uint16_t conn_handle; /**< Connection handle on which the IAS service was discovered on the peer device. This will be filled if the evt_type is @ref BLE_IAS_C_EVT_DISCOVERY_COMPLETE.*/
+ ble_gattc_char_t alert_level; /**< Info on the discovered Alert Level characteristic discovered. This will be filled if the evt_type is @ref BLE_IAS_C_EVT_DISCOVERY_COMPLETE.*/
+} ble_ias_c_evt_t;
+
+/**@brief Immediate Alert Service client event handler type. */
+typedef void (*ble_ias_c_evt_handler_t) (ble_ias_c_t * p_ias_c, ble_ias_c_evt_t * p_evt);
+
+/**@brief IAS Client structure. This contains various status information for the client. */
+struct ble_ias_c_s
+{
+ ble_ias_c_evt_handler_t evt_handler; /**< Event handler to be called for handling events in the Immediate Alert Service client. */
+ ble_srv_error_handler_t error_handler; /**< Function to be called in case of an error. */
+ uint16_t conn_handle; /**< Handle of the current connection. Set with @ref ble_ias_c_handles_assign when connected. */
+ ble_uuid_t service_uuid; /**< The GATT Service holding the discovered Immediate Service. */
+ ble_gattc_char_t alert_level_char; /**< IAS Alert Level Characteristic. Stores data about the alert characteristic found on the peer. */
+};
+
+/**@brief IAS Client init structure. This contains all options and data needed for initialization of
+ * the client.*/
+typedef struct
+{
+ ble_ias_c_evt_handler_t evt_handler; /**< Event handler to be called for handling events from the Immediate Alert Service client. */
+ ble_srv_error_handler_t error_handler; /**< Function to be called in case of an error. */
+} ble_ias_c_init_t;
+
+
+/**@brief Function for initializing the Immediate Alert Service client.
+ *
+ * @details This call allows the application to initialize the Immediate Alert Service client.
+ *
+ * @param[out] p_ias_c Immediate Alert Service client structure. This structure will have to
+ * be supplied by the application. It will be initialized by this
+ * function, and will later be used to identify this particular client
+ * instance.
+ * @param[in] p_ias_c_init Information needed to initialize the Immediate Alert Service client.
+ *
+ * @return NRF_SUCCESS on successful initialization of service.
+ */
+uint32_t ble_ias_c_init(ble_ias_c_t * p_ias_c, ble_ias_c_init_t const * p_ias_c_init);
+
+
+/**@brief Function for sending alert level to the peer.
+ *
+ * @details This function allows the application to send an alert to the peer.
+ *
+ * @param[in] p_ias_c Immediate Alert Service client structure.
+ * @param[in] alert_level Required alert level to be sent to the peer.
+ *
+ * @return NRF_SUCCESS on success, otherwise an error code.
+ */
+uint32_t ble_ias_c_send_alert_level(ble_ias_c_t const * p_ias_c, uint8_t alert_level);
+
+
+/**@brief Function for handling the Application's BLE Stack events for Immediate Alert Service client.
+ *
+ * @details Handles all events from the BLE stack of interest to the Immediate Alert Service client.
+ *
+ * @param[in] p_ble_evt Event received from the BLE stack.
+ * @param[in] p_context Immediate Alert Service client structure.
+ */
+void ble_ias_c_on_ble_evt(ble_evt_t const * p_ble_evt, void * p_context);
+
+
+/**@brief Function for checking whether the peer's Immediate Alert Service instance and the alert level
+ * characteristic have been discovered.
+ *
+ * @param[in] p_ias_c Immediate Alert Service client structure.
+ *
+ * @return TRUE if a handle has been assigned to alert_level_handle, meaning it must have been
+ * discovered. FALSE if the handle is invalid.
+ */
+static __INLINE bool ble_ias_c_is_discovered(ble_ias_c_t const * p_ias_c)
+{
+ return (p_ias_c->alert_level_char.handle_value != BLE_GATT_HANDLE_INVALID);
+}
+
+
+/**@brief Function for handling events from the database discovery module.
+ *
+ * @details Call this function when getting a callback event from the DB discovery modue.
+ * This function will handle an event from the database discovery module, and determine
+ * if it relates to the discovery of heart rate service at the peer. If so, it will
+ * call the application's event handler indicating that the heart rate service has been
+ * discovered at the peer. It also populates the event with the service related
+ * information before providing it to the application.
+ *
+ * @param[in] p_ias_c Pointer to the immediate alert client structure instance that will handle
+ * the discovery.
+ * @param[in] p_evt Pointer to the event received from the database discovery module.
+ *
+ */
+void ble_ias_c_on_db_disc_evt(ble_ias_c_t * p_ias_c, ble_db_discovery_evt_t const * p_evt);
+
+
+/**@brief Function for assigning handles to an instance of ias_c.
+ *
+ * @details Call this function when a link has been established with a peer to
+ * associate this link to this instance of the module. This makes it
+ * possible to handle several links and associate each link to a particular
+ * instance of this module. The connection handle and attribute handles will be
+ * provided from the discovery event @ref BLE_IAS_C_EVT_DISCOVERY_COMPLETE.
+ *
+ * @param[in] p_ias_c Pointer to the IAS client structure instance to associate.
+ * @param[in] conn_handle Connection handle to associated with the given IAS Instance.
+ * @param[in] alert_level_handle Attribute handle on the IAS server that you want this IAS_C client to
+ * interact with.
+ *
+ * @retval NRF_SUCCESS If the operation was successful.
+ * @retval NRF_ERROR_NULL If a p_ias_c was a NULL pointer.
+ */
+uint32_t ble_ias_c_handles_assign(ble_ias_c_t * p_ias_c,
+ uint16_t conn_handle,
+ uint16_t alert_level_handle);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // BLE_IAS_C_H__
+
+/** @} */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/ble_ipsp/ble_ipsp.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/ble_ipsp/ble_ipsp.c
new file mode 100644
index 0000000..291b536
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/ble_ipsp/ble_ipsp.c
@@ -0,0 +1,981 @@
+/**
+ * Copyright (c) 2014 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+/* Attention!
+ * To maintain compliance with Nordic Semiconductor ASA's Bluetooth profile
+ * qualification listings, this section of source code must not be modified.
+ */
+#include <stdbool.h>
+#include <string.h>
+#include "nordic_common.h"
+#include "sdk_errors.h"
+#include "nrf.h"
+#include "sdk_config.h"
+#include "ble_ipsp.h"
+#include "ble_srv_common.h"
+#include "sdk_os.h"
+
+
+/**
+ * @defgroup ble_ipsp_log Module's Log Macros
+ * @details Macros used for creating module logs which can be useful in understanding handling
+ * of events or actions on API requests. These are intended for debugging purposes and
+ * can be enabled by defining the IOT_BLE_IPSP_CONFIG_LOG_ENABLED to 1.
+ * @note If NRF_LOG_ENABLED is disabled, having IOT_BLE_IPSP_CONFIG_LOG_ENABLED
+ * has no effect.
+ * @{
+ */
+
+#if IOT_BLE_IPSP_CONFIG_LOG_ENABLED
+
+#define NRF_LOG_MODULE_NAME ipsp
+
+#define NRF_LOG_LEVEL IOT_BLE_IPSP_CONFIG_LOG_LEVEL
+#define NRF_LOG_INFO_COLOR IOT_BLE_IPSP_CONFIG_INFO_COLOR
+#define NRF_LOG_DEBUG_COLOR IOT_BLE_IPSP_CONFIG_DEBUG_COLOR
+
+#include "nrf_log.h"
+NRF_LOG_MODULE_REGISTER();
+
+#define BLE_IPSP_TRC NRF_LOG_DEBUG /**< Used for getting trace of execution in the module. */
+#define BLE_IPSP_ERR NRF_LOG_ERROR /**< Used for logging errors in the module. */
+#define BLE_IPSP_DUMP NRF_LOG_HEXDUMP_DEBUG /**< Used for dumping octet information to get details of bond information etc. */
+
+#define BLE_IPSP_ENTRY() BLE_IPSP_TRC(">> %s", __func__)
+#define BLE_IPSP_EXIT() BLE_IPSP_TRC("<< %s", __func__)
+#define BLE_IPSP_EXIT_WITH_RESULT(result) BLE_IPSP_TRC("<< %s, result 0x%08lX", __func__, result)
+
+#else // IOT_BLE_IPSP_CONFIG_LOG_ENABLED
+
+#define BLE_IPSP_TRC(...) /**< Disables traces. */
+#define BLE_IPSP_DUMP(...) /**< Disables dumping of octet streams. */
+#define BLE_IPSP_ERR(...) /**< Disables error logs. */
+
+#define BLE_IPSP_ENTRY(...)
+#define BLE_IPSP_EXIT(...)
+#define BLE_IPSP_EXIT_WITH_RESULT(...)
+
+#endif // IOT_BLE_IPSP_CONFIG_LOG_ENABLED
+
+#define IPSP_ANY_CID 0xFFFE /**< Identifier for any channel. Usage: Search for existing channel on a connection handle. */
+
+/**
+ * @defgroup api_param_check API Parameters check macros.
+ *
+ * @details Macros that verify parameters passed to the module in the APIs. These macros
+ * could be mapped to nothing in final versions of code to save execution and size.
+ * BLE_HPS_DISABLE_API_PARAM_CHECK should be defined to disable these checks.
+ *
+ * @{
+ */
+#if (BLE_IPSP_DISABLE_API_PARAM_CHECK == 0)
+
+/**@brief Macro to check is module is initialized before requesting one of the module procedures. */
+#define VERIFY_MODULE_IS_INITIALIZED() \
+ if (m_evt_handler == NULL) \
+ { \
+ return (NRF_ERROR_MODULE_NOT_INITIALIZED + NRF_ERROR_BLE_IPSP_ERR_BASE); \
+ }
+
+/**@brief Macro to check is module is initialized before requesting one of the module
+ procedures but does not use any return code. */
+#define VERIFY_MODULE_IS_INITIALIZED_VOID() \
+ if (m_evt_handler == NULL) \
+ { \
+ return; \
+ }
+
+/**@brief Verify NULL parameters are not passed to API by application. */
+#define NULL_PARAM_CHECK(PARAM) \
+ if ((PARAM) == NULL) \
+ { \
+ return (NRF_ERROR_NULL + NRF_ERROR_BLE_IPSP_ERR_BASE); \
+ }
+
+/**@brief Verify the connection handle passed to the API. */
+#define VERIFY_CON_HANDLE(CON_HANDLE) \
+ if ((CON_HANDLE) == BLE_CONN_HANDLE_INVALID) \
+ { \
+ return (NRF_ERROR_INVALID_PARAM + NRF_ERROR_BLE_IPSP_ERR_BASE); \
+ }
+
+#else // BLE_IPSP_DISABLE_API_PARAM_CHECK
+
+#define VERIFY_MODULE_IS_INITIALIZED()
+#define VERIFY_MODULE_IS_INITIALIZED_VOID()
+#define NULL_PARAM_CHECK(PARAM)
+#define VERIFY_CON_HANDLE(CON_HANDLE)
+
+#endif //BLE_IPSP_DISABLE_API_PARAM_CHECK
+
+/**
+ * @defgroup ble_ipsp_mutex_lock_unlock Module's Mutex Lock/Unlock Macros.
+ *
+ * @details Macros used to lock and unlock modules. Currently, SDK does not use mutexes but
+ * framework is provided in case the need to use an alternative architecture arises.
+ * @{
+ */
+#define BLE_IPSP_MUTEX_LOCK() SDK_MUTEX_LOCK(m_ipsp_mutex) /**< Lock module using mutex */
+#define BLE_IPSP_MUTEX_UNLOCK() SDK_MUTEX_UNLOCK(m_ipsp_mutex) /**< Unlock module using mutex */
+/** @} */
+
+#define IPSP_MAX_CONNECTED_DEVICES BLE_IPSP_MAX_CHANNELS /**< Table for maximum number of connected devices the module will keep track of. */
+#define RX_BUFFER_TOTAL_SIZE (BLE_IPSP_RX_BUFFER_SIZE * BLE_IPSP_RX_BUFFER_COUNT) /**< Total receive buffer size reserved for each IPSP channel. */
+#define MAX_L2CAP_RX_BUFFER (RX_BUFFER_TOTAL_SIZE * BLE_IPSP_MAX_CHANNELS) /**< Total receive buffer received for all channels. */
+#define INVALID_CHANNEL_INSTANCE 0xFF /**< Indicates channel instance is invalid. */
+
+
+/**@brief IPSP Channel States. */
+typedef enum
+{
+ CHANNEL_IDLE, /**< Indicates the channel is free and not in use. */
+ CHANNEL_CONNECTING, /**< Indicates the channel creation is requested and is awaiting a response. */
+ CHANNEL_CONNECTED, /**< Indicates the channel is connected and ready for data exchange. */
+ CHANNEL_DISCONNECTING /**< Indicates the channel is in the process of being disconnected. */
+} channel_state_t;
+
+
+/**@brief Possible response actions for an incoming channel. Default is to accept. */
+typedef enum
+{
+ INCOMING_CHANNEL_ACCEPT, /**< Indicates that the incoming channel should be accepted if all other criteria are met. */
+ INCOMING_CHANNEL_REJECT /**< Indicates that the incoming channel for IPSP PSM should be rejected regardless of the other criteria. */
+} incoming_channel_action_t;
+
+/**@brief Data type for book keeping connected devices.
+ *
+ * @note Not all connected devices establish an L2CAP connection.
+ */
+typedef struct
+{
+ volatile incoming_channel_action_t response; /**< Indicator if the incoming channel should be accepted or rejected. */
+ ble_gap_addr_t ble_addr; /**< Bluetooth device address of the peer. */
+ uint16_t conn_handle; /**< Connection handle identifying the link with the peer. */
+} peer_connection_t;
+
+
+/**@brief IPSP Channel Information. */
+typedef struct
+{
+ uint16_t conn_handle; /**< Identifies the BLE link on which channel is established. BLE_CONN_HANDLE_INVALID if channel is unassigned. */
+ uint16_t cid; /**< L2CAP channel identifier needed to manage the channel once established. BLE_L2CAP_CID_INVALID if channel is unassigned. */
+ uint16_t rx_buffer_status; /**< Usage status of RX buffers. */
+ uint8_t state; /**< State information for the channel. See @ref channel_state_t for details. */
+ uint8_t * p_rx_buffer; /**< Receive buffer for the channel. */
+} channel_t;
+
+
+static ble_ipsp_evt_handler_t m_evt_handler = NULL; /**< Asynchronous event notification callback registered with the module. */
+static channel_t m_channel[BLE_IPSP_MAX_CHANNELS]; /**< Table of channels managed by the module. */
+static uint8_t m_rx_buffer[MAX_L2CAP_RX_BUFFER]; /**< Receive buffer reserved for all channels to receive data on the L2CAP IPSP channel. */
+static peer_connection_t m_connected_device[IPSP_MAX_CONNECTED_DEVICES]; /**< Table maintaining list of peer devices and the connection handle.
+ \n This information is needed for the 6lowpan compression and decompression.
+ \n And no interface exists to query the softdevice. */
+SDK_MUTEX_DEFINE(m_ipsp_mutex) /**< Mutex variable. Currently unused, this declaration does not occupy any space in RAM. */
+
+
+/**@brief Initialize the peer connected device in the list.
+ *
+ * @param[in] index Identifies the list element to be initialized.
+ */
+static __INLINE void connected_device_init(uint32_t index)
+{
+ memset (&m_connected_device[index].ble_addr, 0, sizeof(ble_gap_addr_t));
+ m_connected_device[index].conn_handle = BLE_CONN_HANDLE_INVALID;
+ m_connected_device[index].response = INCOMING_CHANNEL_ACCEPT;
+}
+
+
+/**@brief Allocate an entry for the peer connected device in the list.
+ *
+ * @param[in] p_peer_addr Pointer to peer's device address.
+ * @param[in] conn_handle Connection handle identifying the link with the peer.
+ */
+static __INLINE void connected_device_allocate(ble_gap_addr_t const * p_peer_addr,
+ uint16_t conn_handle)
+{
+ for (uint32_t index = 0; index < IPSP_MAX_CONNECTED_DEVICES; index++)
+ {
+ if (m_connected_device[index].conn_handle == BLE_CONN_HANDLE_INVALID)
+ {
+ m_connected_device[index].conn_handle = conn_handle;
+ memcpy(m_connected_device[index].ble_addr.addr, p_peer_addr->addr, BLE_GAP_ADDR_LEN);
+ break;
+ }
+ }
+}
+
+
+/**@brief Search for an entry for the peer connected device in the list.
+ *
+ * @param[in] conn_handle Connection handle identifying the link with the peer.
+ *
+ * @retval A valid device index in the list if found, else,
+ * IPSP_MAX_CONNECTED_DEVICES indicating the search failed.
+ */
+static __INLINE uint32_t connected_device_search(uint16_t conn_handle)
+{
+ for (uint32_t index = 0; index < IPSP_MAX_CONNECTED_DEVICES; index++)
+ {
+ if (m_connected_device[index].conn_handle == conn_handle)
+ {
+ return index;
+ }
+ }
+ return IPSP_MAX_CONNECTED_DEVICES;
+}
+
+
+/**@brief Initialize channel.
+ *
+ * @param[in] ch_id Identifies the IPSP channel on which the procedure is requested.
+ */
+static __INLINE void channel_init(uint8_t ch_id)
+{
+ m_channel[ch_id].conn_handle = BLE_CONN_HANDLE_INVALID;
+ m_channel[ch_id].cid = BLE_L2CAP_CID_INVALID;
+ m_channel[ch_id].rx_buffer_status = 0;
+ m_channel[ch_id].state = CHANNEL_IDLE;
+ m_channel[ch_id].p_rx_buffer = &m_rx_buffer[ch_id*RX_BUFFER_TOTAL_SIZE];
+}
+
+
+/**@brief Free channel.
+ *
+ * @param[in] ch_id Identifies the IPSP channel on which the procedure is requested.
+ */
+static __INLINE void channel_free(uint8_t ch_id)
+{
+ BLE_IPSP_TRC("[Index 0x%02X]:[Conn Handle 0x%04X]:[CID 0x%04X]: Freeing channel",
+ ch_id, m_channel[ch_id].conn_handle, m_channel[ch_id].cid);
+
+ channel_init(ch_id);
+}
+
+
+/**@brief Searches the IPSP channel based on connection handle and local L2CAP channel identifier.
+ *
+ * @param[in] conn_handle The connection handle, identifying the peer device.
+ * @param[in] l2cap_cid The local L2CAP channel identifier, identifying the L2CAP channel.
+ * @param[out] p_ch_id The IPSP channel identifier, if the search succeeded, else,
+ * BLE_IPSP_MAX_CHANNELS indicating no IPSP channel was found.
+ */
+static __INLINE uint32_t channel_search(uint16_t conn_handle, uint16_t l2cap_cid, uint8_t * p_ch_id)
+{
+ BLE_IPSP_TRC("[Conn Handle 0x%04X]:[CID 0x%04X]: channel_search",
+ conn_handle, l2cap_cid);
+
+ for (int i = 0; i < BLE_IPSP_MAX_CHANNELS; i++)
+ {
+ BLE_IPSP_TRC("[@ Index 0x%02X] ==> Conn Handle: 0x%04X"
+ " CID : 0x%04X",
+ i, m_channel[i].conn_handle, m_channel[i].cid);
+
+ if (m_channel[i].conn_handle == conn_handle)
+ {
+ if ((l2cap_cid == IPSP_ANY_CID) || (m_channel[i].cid == l2cap_cid))
+ {
+ BLE_IPSP_TRC("channel_search succeeded, index 0x%04X", i);
+
+ *p_ch_id = (uint8_t)i;
+ return NRF_SUCCESS;
+ }
+ }
+ }
+
+ BLE_IPSP_TRC("No matching channel found!");
+ return (NRF_ERROR_BLE_IPSP_ERR_BASE + NRF_ERROR_NOT_FOUND);
+}
+
+
+/**@brief Notify application of an event.
+ *
+ * @param[in] Identifies the IPSP instance for which the event is notified.
+ * @param[in] Describes the notified event and its parameters, if any.
+ */
+static __INLINE void app_notify(ble_ipsp_handle_t * p_handle, ble_ipsp_evt_t * p_event)
+{
+ BLE_IPSP_MUTEX_UNLOCK();
+
+ BLE_IPSP_TRC("[Conn Handle 0x%04X]:[CID 0x%04X]: Notifying application of event 0x%04X",
+ p_handle->conn_handle, p_handle->cid, p_event->evt_id);
+
+ UNUSED_VARIABLE(m_evt_handler(p_handle, p_event));
+
+ BLE_IPSP_MUTEX_LOCK();
+}
+
+
+/**@brief Verifies if the buffer is TX buffer on the channel or not.
+ *
+ * @param[in] ch_id Identifies the IPSP channel for which the procedure is requested.
+ * @param[in] p_buffer Address of the buffer being verified to be TX or not.
+ */
+static __INLINE bool is_tx_buffer(uint32_t ch_id, const uint8_t * p_buffer)
+{
+ // If the buffer is in the RX buffer list, then it is not TX!
+ if ((p_buffer >= (uint8_t *)&m_channel[ch_id].p_rx_buffer) &&
+ (p_buffer < (uint8_t *)&m_channel[ch_id].p_rx_buffer[RX_BUFFER_TOTAL_SIZE]))
+ {
+ return false;
+ }
+
+ return true;
+}
+
+
+/**@brief Submit receive buffers to the softdevice for a channel.
+ *
+ * @param[in] ch_id Identifies the IPSP channel for which the procedure is requested.
+ */
+static __INLINE void rx_buffers_submit(uint32_t ch_id)
+{
+ uint32_t retval;
+
+ for (uint32_t buffer_index = 0; buffer_index < BLE_IPSP_RX_BUFFER_COUNT; buffer_index++)
+ {
+ const ble_data_t sdu_buf =
+ {
+ .p_data = (uint8_t *)&m_channel[ch_id].p_rx_buffer[buffer_index * BLE_IPSP_MTU],
+ .len = BLE_IPSP_MTU
+ };
+
+ if (IS_SET(m_channel[ch_id].rx_buffer_status, buffer_index) == 0)
+ {
+ retval = sd_ble_l2cap_ch_rx(m_channel[ch_id].conn_handle,
+ m_channel[ch_id].cid,
+ &sdu_buf);
+ if (retval == NRF_SUCCESS)
+ {
+ SET_BIT(m_channel[ch_id].rx_buffer_status, buffer_index);
+ }
+ }
+ }
+}
+
+
+/**@brief Mark a receive buffer as not in use for a particular channel.
+ *
+ * @param[in] ch_id Identifies the IPSP channel for which the procedure is requested.
+ * @param[in] p_buffer The buffer to be marked as unused.
+ *
+ * @note This is a temporary state for the receive buffer before it is resubmitted to the SoftDevice.
+ */
+static __INLINE void rx_buffer_mark_unused(uint32_t ch_id, uint8_t * p_buffer)
+{
+ for (uint32_t buffer_index = 0; buffer_index < BLE_IPSP_RX_BUFFER_COUNT; buffer_index++)
+ {
+ if (&m_channel[ch_id].p_rx_buffer[buffer_index * BLE_IPSP_MTU] == p_buffer)
+ {
+ CLR_BIT(m_channel[ch_id].rx_buffer_status, buffer_index);
+ }
+ }
+}
+
+
+void ble_ipsp_evt_handler(ble_evt_t const * p_evt)
+{
+ VERIFY_MODULE_IS_INITIALIZED_VOID();
+
+ ble_ipsp_handle_t handle;
+ ble_ipsp_evt_t ipsp_event;
+ uint32_t retval;
+ uint8_t ch_id;
+ bool notify_event;
+ bool submit_rx_buffer;
+
+ ch_id = INVALID_CHANNEL_INSTANCE;
+ notify_event = false;
+ submit_rx_buffer = false;
+ retval = NRF_SUCCESS;
+ ipsp_event.evt_result = NRF_SUCCESS;
+ handle.conn_handle = BLE_CONN_HANDLE_INVALID;
+ handle.cid = BLE_L2CAP_CID_INVALID;
+
+ BLE_IPSP_TRC("Received BLE Event 0x%04X",p_evt->header.evt_id);
+
+ BLE_IPSP_MUTEX_LOCK();
+
+ switch (p_evt->header.evt_id)
+ {
+ case BLE_GAP_EVT_CONNECTED:
+ {
+ // Create an entry in the connected devices table.
+ // This is needed to be able to fetch the peer address on IPSP channel establishment.
+ connected_device_allocate(&p_evt->evt.gap_evt.params.connected.peer_addr,
+ p_evt->evt.gap_evt.conn_handle);
+ break;
+ }
+ case BLE_L2CAP_EVT_CH_SETUP_REQUEST:
+ {
+ // This event is generated for the acceptor role and indicates an channel establishment
+ // request from the peer.
+ ble_l2cap_ch_setup_params_t reply_param;
+ uint16_t local_cid;
+
+ memset(&reply_param, 0, sizeof(ble_l2cap_ch_setup_params_t));
+
+ reply_param.le_psm = p_evt->evt.l2cap_evt.params.ch_setup_request.le_psm;
+ reply_param.rx_params.rx_mtu = BLE_IPSP_MTU;
+ reply_param.rx_params.rx_mps = BLE_IPSP_RX_MPS;
+
+ // Check if a channel already exists with the peer.
+ retval = channel_search(p_evt->evt.l2cap_evt.conn_handle,
+ IPSP_ANY_CID,
+ &ch_id);
+
+ BLE_IPSP_TRC("Exiting channel_search result 0x%08X", ch_id);
+
+ if (retval == NRF_SUCCESS)
+ {
+ BLE_IPSP_TRC("Rejecting channel, as IPSP channel already exists "
+ "0x%08X in state 0x%08X", ch_id, m_channel[ch_id].state);
+
+ reply_param.status = BLE_L2CAP_CH_STATUS_CODE_NO_RESOURCES;
+
+ // Reinitialize ch_id to invalid so that existing channel is not impacted.
+ ch_id = INVALID_CHANNEL_INSTANCE;
+ }
+ else
+ {
+ uint32_t peer_device_index = connected_device_search(p_evt->evt.l2cap_evt.conn_handle);
+ local_cid = p_evt->evt.l2cap_evt.local_cid;
+
+ if (p_evt->evt.l2cap_evt.params.ch_setup_request.le_psm != BLE_IPSP_PSM)
+ {
+ reply_param.status = BLE_L2CAP_CH_STATUS_CODE_LE_PSM_NOT_SUPPORTED;
+ BLE_IPSP_TRC("Rejecting L2CAP Channel, unknown PSM %04X!",
+ p_evt->evt.l2cap_evt.params.ch_setup_request.le_psm);
+ }
+ else if ((peer_device_index != IPSP_MAX_CONNECTED_DEVICES) &&
+ (m_connected_device[peer_device_index].response == INCOMING_CHANNEL_REJECT))
+ {
+ reply_param.status = BLE_L2CAP_CH_STATUS_CODE_NO_RESOURCES;
+ BLE_IPSP_ERR("Barred incoming requests by the application. "
+ "Rejecting L2CAP Channel %04X!",
+ p_evt->evt.l2cap_evt.params.ch_setup_request.le_psm);
+ }
+ else if (p_evt->evt.l2cap_evt.params.ch_setup_request.tx_params.tx_mtu < BLE_IPSP_MTU)
+ {
+ reply_param.status = BLE_L2CAP_CH_STATUS_CODE_UNACCEPTABLE_PARAMS;
+ BLE_IPSP_TRC("Rejecting L2CAP Channel, unacceptable TX parameters!");
+ }
+ else
+ {
+ // Peer request acceptable, look for a free channel.
+ retval = channel_search(BLE_CONN_HANDLE_INVALID, BLE_L2CAP_CID_INVALID, &ch_id);
+ BLE_IPSP_TRC("Free channel search result 0x%08X", ch_id);
+
+ if (retval != NRF_SUCCESS)
+ {
+ BLE_IPSP_TRC("Rejecting L2CAP Channel, no resources!");
+ reply_param.status = BLE_L2CAP_CH_STATUS_CODE_NO_RESOURCES;
+ }
+ else
+ {
+ BLE_IPSP_TRC("Accepting L2CAP Channel");
+ reply_param.rx_params.sdu_buf.p_data = NULL;
+ reply_param.rx_params.sdu_buf.len = 0;
+ reply_param.status = BLE_L2CAP_CH_STATUS_CODE_SUCCESS;
+ }
+ }
+ }
+
+ retval = sd_ble_l2cap_ch_setup(p_evt->evt.l2cap_evt.conn_handle,
+ &local_cid,
+ &reply_param);
+
+ BLE_IPSP_TRC("sd_ble_l2cap_ch_setup result = 0x%08lX", retval);
+
+ if ((retval == NRF_SUCCESS) &&
+ (reply_param.status == BLE_L2CAP_CH_STATUS_CODE_SUCCESS) &&
+ (ch_id != INVALID_CHANNEL_INSTANCE))
+ {
+ BLE_IPSP_TRC("[0x%04X][0x%04X]: Channel Connected. Rx MPS = 0x%04X",
+ p_evt->evt.l2cap_evt.conn_handle,
+ p_evt->evt.l2cap_evt.local_cid,
+ reply_param.rx_params.rx_mps);
+
+ ipsp_event.evt_id = BLE_IPSP_EVT_CHANNEL_CONNECTED;
+ ipsp_event.evt_result = NRF_SUCCESS;
+
+ // Channel is assigned to this link.
+ m_channel[ch_id].state = CHANNEL_CONNECTING;
+ m_channel[ch_id].conn_handle = p_evt->evt.l2cap_evt.conn_handle;
+ m_channel[ch_id].cid = local_cid;
+ }
+ else if (ch_id != INVALID_CHANNEL_INSTANCE)
+ {
+ // Free the allocated channel.
+ channel_init(ch_id);
+ }
+ break;
+ }
+ case BLE_L2CAP_EVT_CH_SETUP:
+ {
+ // This event is generated for both initiator and acceptor roles.
+ // This event indicates that the IPSP channel is successfully established.
+ retval = channel_search(p_evt->evt.l2cap_evt.conn_handle,
+ p_evt->evt.l2cap_evt.local_cid,
+ &ch_id);
+
+ if (retval != NRF_SUCCESS)
+ {
+ BLE_IPSP_TRC("Reply on unknown channel, dropping the event.");
+ }
+ else
+ {
+ if (m_channel[ch_id].state == CHANNEL_CONNECTING)
+ {
+ // Channel created successfully.
+
+ // Initialize IPSP handle.
+ handle.conn_handle = p_evt->evt.l2cap_evt.conn_handle;
+ handle.cid = p_evt->evt.l2cap_evt.local_cid;
+
+ // Initialize the event.
+ ipsp_event.evt_id = BLE_IPSP_EVT_CHANNEL_CONNECTED;
+ ipsp_event.evt_result = NRF_SUCCESS;
+
+ // Set the channel state appropriately.
+ m_channel[ch_id].state = CHANNEL_CONNECTED;
+
+ // Set the flag to trigger submission of the receive buffers to the softdevice.
+ submit_rx_buffer = true;
+
+ // Notify the event to the application.
+ notify_event = true;
+ }
+ }
+ break;
+ }
+ case BLE_L2CAP_EVT_CH_SETUP_REFUSED:
+ {
+ // This event is generated for both initiator and acceptor roles.
+ // This event indicates that the IPSP channel establishment failed.
+ retval = channel_search(p_evt->evt.l2cap_evt.conn_handle,
+ p_evt->evt.l2cap_evt.local_cid,
+ &ch_id);
+
+ if (retval != NRF_SUCCESS)
+ {
+ BLE_IPSP_TRC("Reply on unknown channel, dropping the event.");
+ }
+ else
+ {
+ if (m_channel[ch_id].state == CHANNEL_CONNECTING)
+ {
+ // Channel creation failed as peer rejected the connection.
+
+ // Initialize the event.
+ ipsp_event.evt_id = BLE_IPSP_EVT_CHANNEL_CONNECTED;
+ ipsp_event.evt_result = NRF_ERROR_BLE_IPSP_PEER_REJECTED;
+
+ BLE_IPSP_ERR("Peer rejected channel creation request, reason %d",
+ p_evt->evt.l2cap_evt.params.ch_setup_refused.status);
+
+ // Free the channel.
+ channel_free(ch_id);
+
+ // Notify the event to the application.
+ notify_event = true;
+ }
+ }
+ break;
+ }
+ case BLE_L2CAP_EVT_CH_RELEASED:
+ {
+ BLE_IPSP_TRC("L2CAP Channel disconnected.");
+
+ ipsp_event.evt_id = BLE_IPSP_EVT_CHANNEL_DISCONNECTED;
+
+ retval = channel_search(p_evt->evt.l2cap_evt.conn_handle,
+ p_evt->evt.l2cap_evt.local_cid,
+ &ch_id);
+
+ // Notify application of disconnection.
+ if (retval == NRF_SUCCESS)
+ {
+ handle.conn_handle = p_evt->evt.l2cap_evt.conn_handle;
+ handle.cid = p_evt->evt.l2cap_evt.local_cid;
+
+ channel_free(ch_id);
+
+ // Notify the event to the application.
+ notify_event = true;
+ }
+ break;
+ }
+ case BLE_L2CAP_EVT_CH_RX:
+ {
+ ipsp_event.evt_id = BLE_IPSP_EVT_CHANNEL_DATA_RX;
+
+ retval = channel_search(p_evt->evt.l2cap_evt.conn_handle,
+ p_evt->evt.l2cap_evt.local_cid,
+ &ch_id);
+
+ if (retval == NRF_SUCCESS)
+ {
+ handle.conn_handle = p_evt->evt.l2cap_evt.conn_handle;
+ handle.cid = p_evt->evt.l2cap_evt.local_cid;
+
+ rx_buffer_mark_unused(ch_id, p_evt->evt.l2cap_evt.params.rx.sdu_buf.p_data);
+
+ // Set the flag to trigger submission of the receive buffers to the softdevice.
+ submit_rx_buffer = true;
+
+ // Notify the event to the application.
+ notify_event = true;
+ }
+ break;
+ }
+ case BLE_L2CAP_EVT_CH_TX:
+ {
+ BLE_IPSP_TRC("BLE_L2CAP_EVT_CH_TX --> p_sdu_buf = %p, p_sdu_buf.p_data = %p",
+ &p_evt->evt.l2cap_evt.params.tx.sdu_buf, p_evt->evt.l2cap_evt.params.tx.sdu_buf.p_data);
+
+ retval = channel_search(p_evt->evt.l2cap_evt.conn_handle,
+ p_evt->evt.l2cap_evt.local_cid,
+ &ch_id);
+
+ if ((ch_id != INVALID_CHANNEL_INSTANCE) &&
+ p_evt->evt.l2cap_evt.local_cid == m_channel[ch_id].cid)
+ {
+ // Initialize the event.
+ ipsp_event.evt_id = BLE_IPSP_EVT_CHANNEL_DATA_TX_COMPLETE;
+
+ // Initialize the handle.
+ handle.conn_handle = m_channel[ch_id].conn_handle;
+ handle.cid = m_channel[ch_id].cid;
+
+ // Notify the event to the application.
+ notify_event = true;
+ }
+ break;
+ }
+ case BLE_L2CAP_EVT_CH_SDU_BUF_RELEASED:
+ {
+ BLE_IPSP_TRC("BLE_L2CAP_EVT_CH_SDU_BUF_RELEASED --> p_sdu_buf = %p, p_sdu_buf.p_data = %p",
+ &p_evt->evt.l2cap_evt.params.ch_sdu_buf_released.sdu_buf,
+ p_evt->evt.l2cap_evt.params.ch_sdu_buf_released.sdu_buf.p_data);
+
+ retval = channel_search(p_evt->evt.l2cap_evt.conn_handle,
+ p_evt->evt.l2cap_evt.local_cid,
+ &ch_id);
+
+ if ((ch_id != INVALID_CHANNEL_INSTANCE) &&
+ (p_evt->evt.l2cap_evt.local_cid == m_channel[ch_id].cid) &&
+ (is_tx_buffer(ch_id, p_evt->evt.l2cap_evt.params.ch_sdu_buf_released.sdu_buf.p_data)))
+ {
+ // Initialize the event.
+ ipsp_event.evt_id = BLE_IPSP_EVT_CHANNEL_DATA_TX_COMPLETE;
+ ipsp_event.evt_result = NRF_ERROR_BLE_IPSP_LINK_DISCONNECTED;
+
+ // Initialize the handle.
+ handle.conn_handle = m_channel[ch_id].conn_handle;
+ handle.cid = m_channel[ch_id].cid;
+
+ // Notify the event to the application.
+ notify_event = true;
+ }
+ break;
+ }
+ case BLE_GAP_EVT_DISCONNECTED:
+ {
+ uint32_t peer_device_index = connected_device_search(handle.conn_handle);
+ if (peer_device_index < IPSP_MAX_CONNECTED_DEVICES)
+ {
+ connected_device_init(peer_device_index);
+ }
+ break;
+ }
+ default:
+ break;
+ }
+
+ if (notify_event)
+ {
+ ble_ipsp_event_param_t event_param;
+ uint32_t peer_device_index;
+
+ peer_device_index = connected_device_search(handle.conn_handle);
+
+ if (peer_device_index < IPSP_MAX_CONNECTED_DEVICES)
+ {
+ event_param.p_peer = &m_connected_device[peer_device_index].ble_addr;
+ BLE_IPSP_TRC("Found peer device. Address type = 0x%02x",
+ event_param.p_peer->addr_type);
+ BLE_IPSP_DUMP((uint8_t *)event_param.p_peer->addr, 6);
+ }
+ else
+ {
+ event_param.p_peer = NULL;
+ }
+
+ event_param.p_l2cap_evt = &p_evt->evt.l2cap_evt;
+ ipsp_event.p_evt_param = &event_param;
+
+ app_notify(&handle, &ipsp_event);
+ }
+
+ // Trigger submission of the receive buffers to the softdevice.
+ if (submit_rx_buffer)
+ {
+ rx_buffers_submit(ch_id);
+ }
+
+ BLE_IPSP_MUTEX_UNLOCK();
+ UNUSED_VARIABLE(retval);
+}
+
+
+uint32_t ble_ipsp_init(const ble_ipsp_init_t * p_init)
+{
+ BLE_IPSP_ENTRY();
+
+ ble_uuid_t ble_uuid;
+ uint32_t err_code;
+ uint16_t handle;
+
+ NULL_PARAM_CHECK(p_init);
+ NULL_PARAM_CHECK(p_init->evt_handler);
+
+ SDK_MUTEX_INIT(m_ipsp_mutex);
+
+ BLE_IPSP_MUTEX_LOCK();
+
+ // Add service to indicate IPSP support.
+ BLE_UUID_BLE_ASSIGN(ble_uuid, BLE_UUID_IPSP_SERVICE);
+
+ err_code = sd_ble_gatts_service_add(BLE_GATTS_SRVC_TYPE_PRIMARY, &ble_uuid, &handle);
+ if (err_code != NRF_SUCCESS)
+ {
+ return err_code;
+ }
+
+ m_evt_handler = p_init->evt_handler;
+
+ // Initialize the channel.
+ for (int i = 0; i < BLE_IPSP_MAX_CHANNELS; i++)
+ {
+ channel_init(i);
+ }
+
+ // Initialize the connected peer device table.
+ for (int i = 0; i < IPSP_MAX_CONNECTED_DEVICES; i++)
+ {
+ connected_device_init(i);
+ }
+ BLE_IPSP_MUTEX_UNLOCK();
+
+ BLE_IPSP_EXIT();
+
+ return NRF_SUCCESS;
+}
+
+
+uint32_t ble_ipsp_connect(const ble_ipsp_handle_t * p_handle)
+{
+ VERIFY_MODULE_IS_INITIALIZED();
+ NULL_PARAM_CHECK(p_handle);
+ VERIFY_CON_HANDLE(p_handle->conn_handle);
+
+ uint32_t err_code;
+ uint8_t ch_id = INVALID_CHANNEL_INSTANCE;
+
+ BLE_IPSP_TRC("[Conn Handle 0x%04X]: >> ble_ipsp_connect",
+ p_handle->conn_handle);
+
+ BLE_IPSP_MUTEX_LOCK();
+
+ // Check if channel already exists with the peer.
+ err_code = channel_search(p_handle->conn_handle, IPSP_ANY_CID, &ch_id);
+
+ if (err_code == NRF_SUCCESS)
+ {
+ // IPSP channel already exists.
+ err_code = NRF_ERROR_BLE_IPSP_CHANNEL_ALREADY_EXISTS;
+ }
+ else
+ {
+ // Search for a free channel.
+ err_code = channel_search(BLE_CONN_HANDLE_INVALID, BLE_L2CAP_CID_INVALID, &ch_id);
+ BLE_IPSP_TRC("2 channel_search result %08X", err_code);
+
+ if (err_code == NRF_SUCCESS)
+ {
+ m_channel[ch_id].state = CHANNEL_CONNECTING;
+
+ ble_l2cap_ch_setup_params_t param =
+ {
+ .le_psm = BLE_IPSP_PSM,
+ .rx_params = {
+ .rx_mtu = BLE_IPSP_MTU,
+ .rx_mps = BLE_IPSP_RX_MPS,
+ .sdu_buf =
+ {
+ .p_data = NULL,
+ .len = 0
+ }
+ }
+ };
+ BLE_IPSP_TRC("Requesting sd_ble_l2cap_ch_setup");
+
+ err_code = sd_ble_l2cap_ch_setup(p_handle->conn_handle,
+ &m_channel[ch_id].cid,
+ &param);
+
+ if (err_code != NRF_SUCCESS)
+ {
+ BLE_IPSP_ERR("sd_ble_l2cap_ch_conn_request failed, reason %08lX", err_code);
+ channel_free(ch_id);
+ }
+ else
+ {
+ BLE_IPSP_TRC("Local channel id from SD %04X.", m_channel[ch_id].cid);
+ m_channel[ch_id].conn_handle = p_handle->conn_handle;
+ }
+ }
+ else
+ {
+ err_code = (NRF_ERROR_BLE_IPSP_ERR_BASE + NRF_ERROR_NO_MEM);
+ }
+ }
+
+ BLE_IPSP_MUTEX_UNLOCK();
+
+ BLE_IPSP_EXIT_WITH_RESULT(err_code);
+
+ return err_code;
+}
+
+
+uint32_t ble_ipsp_send(ble_ipsp_handle_t const * p_handle,
+ uint8_t const * p_data,
+ uint16_t data_len)
+{
+ BLE_IPSP_ENTRY();
+
+ VERIFY_MODULE_IS_INITIALIZED();
+ NULL_PARAM_CHECK(p_handle);
+ NULL_PARAM_CHECK(p_data);
+ VERIFY_CON_HANDLE(p_handle->conn_handle);
+
+ uint32_t err_code;
+ uint8_t ch_id;
+
+ BLE_IPSP_MUTEX_LOCK();
+
+ err_code = channel_search(p_handle->conn_handle, p_handle->cid, &ch_id);
+
+ if (err_code == NRF_SUCCESS)
+ {
+ const ble_data_t p_sdu_buf =
+ {
+ .p_data = (uint8_t *)p_data,
+ .len = data_len
+ };
+
+ BLE_IPSP_TRC("p_sdu_buf = %p, p_sdu_buf.p_data = %p",
+ &p_sdu_buf, p_data);
+
+ err_code = sd_ble_l2cap_ch_tx(p_handle->conn_handle,
+ p_handle->cid,
+ &p_sdu_buf);
+ }
+
+ BLE_IPSP_MUTEX_UNLOCK();
+
+ BLE_IPSP_EXIT_WITH_RESULT(err_code);
+
+ return err_code;
+}
+
+
+uint32_t ble_ipsp_disconnect(ble_ipsp_handle_t const * p_handle)
+{
+ BLE_IPSP_ENTRY();
+
+ VERIFY_MODULE_IS_INITIALIZED();
+ NULL_PARAM_CHECK(p_handle);
+ VERIFY_CON_HANDLE(p_handle->conn_handle);
+
+ uint32_t err_code;
+ uint8_t ch_id;
+
+ BLE_IPSP_MUTEX_LOCK();
+
+ err_code = channel_search(p_handle->conn_handle, p_handle->cid, &ch_id);
+
+ if (err_code == NRF_SUCCESS)
+ {
+ m_channel[ch_id].state = CHANNEL_DISCONNECTING;
+
+ err_code = sd_ble_l2cap_ch_release(p_handle->conn_handle,
+ p_handle->cid);
+ }
+
+ BLE_IPSP_MUTEX_UNLOCK();
+
+ BLE_IPSP_EXIT_WITH_RESULT(err_code);
+
+ return err_code;
+}
+
+
+void ble_ipsp_incoming_channel_reject(uint16_t conn_handle)
+{
+ uint32_t peer_device_index = connected_device_search(conn_handle);
+
+ if (peer_device_index != IPSP_MAX_CONNECTED_DEVICES)
+ {
+ m_connected_device[peer_device_index].response = INCOMING_CHANNEL_REJECT;
+ }
+}
+
+
+void ble_ipsp_incoming_channel_accept(uint16_t conn_handle)
+{
+ uint32_t peer_device_index = connected_device_search(conn_handle);
+
+ if (peer_device_index != IPSP_MAX_CONNECTED_DEVICES)
+ {
+ m_connected_device[peer_device_index].response = INCOMING_CHANNEL_ACCEPT;
+ }
+}
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/ble_ipsp/ble_ipsp.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/ble_ipsp/ble_ipsp.h
new file mode 100644
index 0000000..d8edcbd
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/ble_ipsp/ble_ipsp.h
@@ -0,0 +1,253 @@
+/**
+ * Copyright (c) 2014 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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
+ *
+ * @defgroup ble_ipsp Internet Protocol Support Profile
+ * @{
+ * @ingroup iot_sdk_6lowpan
+ * @brief Internet Protocol Support Profile.
+ *
+ * @details This module implements the Internet Protocol Support Profile creating and managing
+ * transport for 6lowpan.
+ * GATT is used to discover if IPSP is supported or not, but no IP data is exchanged
+ * over GATT. To exchange data, LE L2CAP Credit Mode is used. The PSM used for the channel
+ * is BLE_IPSP_PSM and is defined by the specification. The MTU mandated by the
+ * specification is 1280 bytes.
+ *
+ * @note Attention!
+ * To maintain compliance with Nordic Semiconductor ASA's Bluetooth profile
+ * qualification listings, this section of source code must not be modified.
+ */
+
+#ifndef BLE_IPSP_H__
+#define BLE_IPSP_H__
+
+#include <stdint.h>
+#include "ble.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**@brief Maximum IPSP channels required to be supported. */
+#define BLE_IPSP_MAX_CHANNELS 1
+
+/**@brief Maximum Transmit Unit on IPSP channel. */
+#define BLE_IPSP_MTU 1280
+
+/**@brief Receive MPS used by IPSP. */
+#define BLE_IPSP_RX_MPS 50
+
+/**@brief Transmission MPS used by IPSP.
+ *
+ * @note The actual MPS used is minimum of this value and the one requested by
+ * the peer during the channel setup. Here, the value used is
+ * (23 + 27 * 7).
+ */
+#define BLE_IPSP_TX_MPS 212
+
+/**@brief Maximum data size that can be received.
+ *
+ * @details Maximum data size that can be received on the IPSP channel.
+ * Modify this values to intentionally set a receive size less
+ * than the MTU set on the channel.
+ */
+#define BLE_IPSP_RX_BUFFER_SIZE 1280
+
+/**@brief Maximum number of receive buffers.
+ *
+ * @details Maximum number of receive buffers to be used per IPSP channel.
+ * Each receive buffer is of size @ref BLE_IPSP_RX_BUFFER_SIZE.
+ * This configuration has implications on the number of SDUs that can
+ * be received while an SDU is being consumed by the application
+ * (6LoWPAN/IP Stack).
+ */
+#define BLE_IPSP_RX_BUFFER_COUNT 4
+
+/**@brief L2CAP Protocol Service Multiplexers number. */
+#define BLE_IPSP_PSM 0x0023
+
+
+/**@brief IPSP event identifier type. */
+typedef enum
+{
+ BLE_IPSP_EVT_CHANNEL_CONNECTED, /**< Channel connection event. */
+ BLE_IPSP_EVT_CHANNEL_DISCONNECTED, /**< Channel disconnection event. */
+ BLE_IPSP_EVT_CHANNEL_DATA_RX, /**< Data received on channel event. */
+ BLE_IPSP_EVT_CHANNEL_DATA_TX_COMPLETE /**< Requested data transmission complete on channel event. */
+} ble_ipsp_evt_type_t;
+
+
+/**@brief IPSP event parameter. */
+typedef struct
+{
+ ble_l2cap_evt_t const * p_l2cap_evt; /**< L2CAP event parameters. */
+ ble_gap_addr_t const * p_peer; /**< Peer device address. */
+} ble_ipsp_event_param_t;
+
+
+/**@brief IPSP event and associated parameter type. */
+typedef struct
+{
+ ble_ipsp_evt_type_t evt_id; /**< Identifier event type. */
+ ble_ipsp_event_param_t * p_evt_param; /**< Parameters associated with the event. */
+ uint32_t evt_result; /**< Result of the event.
+ \n The event result is SDK_ERR_RX_PKT_TRUNCATED for @ref BLE_IPSP_EVT_CHANNEL_DATA_RX,
+ \n implies that an incomplete SDU was received due to insufficient RX buffer size.
+ \n The size determined by @ref BLE_IPSP_RX_BUFFER_SIZE. */
+} ble_ipsp_evt_t;
+
+
+/**@brief IPSP handle. */
+typedef struct
+{
+ uint16_t conn_handle; /**< Identifies the link on which the IPSP channel is established. */
+ uint16_t cid; /**< Identifies the IPSP logical channel. */
+} ble_ipsp_handle_t;
+
+
+/**@brief Profile event handler type.
+ *
+ * @param[in] p_handle Identifies the connection and channel on which the event occurred.
+ * @param[in] p_evt Event and related parameters (if any).
+ *
+ * @returns Provision for the application to indicate if the event was successfully processed or
+ * not. Currently not used.
+ */
+typedef uint32_t (*ble_ipsp_evt_handler_t) (ble_ipsp_handle_t const * p_handle,
+ ble_ipsp_evt_t const * p_evt);
+
+
+/**@brief IPSP initialization structure.
+ *
+ * @details IPSP initialization structure containing all options and data needed to
+ * initialize the profile.
+ */
+typedef struct
+{
+ ble_ipsp_evt_handler_t evt_handler; /**< Event notification callback registered with the module to receive asynchronous events. */
+} ble_ipsp_init_t;
+
+
+/**@brief Function for initializing the Internet Protocol Support Profile.
+ *
+ * @param[in] p_init Information needed to initialize the service.
+ *
+ * @retval NRF_SUCCESS If initialization of the service was successful, else,
+ * an error code indicating reason for failure.
+ */
+uint32_t ble_ipsp_init(ble_ipsp_init_t const * p_init);
+
+
+/**@brief Function for requesting a channel creation for the Internet Protocol Support Profile.
+ *
+ * @details Channel creation for Internet Protocol Support Profile (IPSP) is requested using this
+ * API. Connection handle provided in p_handle parameter identifies the peer with which
+ * the IPSP channel is being requested.
+ * NRF_SUCCESS return value by the API is only indicative of request procedure having
+ * succeeded. Result of channel establishment is known when the
+ * @ref BLE_IPSP_EVT_CHANNEL_CONNECTED event is notified.
+ * Therefore, the application must wait for @ref BLE_IPSP_EVT_CHANNEL_CONNECTED event on
+ * successful return of this API.
+ *
+ * @param[in] p_handle Indicates the connection handle on which IPSP channel is to be created.
+ *
+ * @retval NRF_SUCCESS If initialization of the service was successful, else,
+ * an error code indicating reason for failure.
+ */
+uint32_t ble_ipsp_connect(ble_ipsp_handle_t const * p_handle);
+
+
+/**@brief Function for sending IP data to peer.
+ *
+ * @param[in] p_handle Instance of the logical channel and peer for which the data is intended.
+ * @param[in] p_data Pointer to memory containing the data to be transmitted.
+ * @note This memory must be resident and should not be freed unless
+ * @ref BLE_IPSP_EVT_CHANNEL_DATA_TX_COMPLETE event is notified.
+ * @param[in] data_len Length/size of data to be transferred.
+ *
+ * @retval NRF_SUCCESS If initialization of the service was successful, else,
+ * an error code indicating reason for failure.
+ */
+uint32_t ble_ipsp_send(ble_ipsp_handle_t const * p_handle,
+ uint8_t const * p_data,
+ uint16_t data_len);
+
+
+/**@brief Function for disconnecting IP transport.
+ *
+ * @param[in] p_handle Identifies IPSP transport.
+ *
+ * @retval NRF_SUCCESS If initialization of the service was successful, else,
+ * an error code indicating reason for failure.
+ */
+uint32_t ble_ipsp_disconnect(ble_ipsp_handle_t const * p_handle);
+
+
+/**@brief Function to accept incoming connections from a peer.
+ *
+ * @param[in] conn_handle Identifies the link with the peer.
+ */
+void ble_ipsp_incoming_channel_accept(uint16_t conn_handle);
+
+
+/**@brief Function to reject incoming connections from a peer.
+ *
+ * @param[in] conn_handle Identifies the link with the peer.
+ */
+void ble_ipsp_incoming_channel_reject(uint16_t conn_handle);
+
+
+/**@brief BLE event handler of the module.
+ *
+ * @param[in] p_evt BLE event to be handled.
+ *
+ * @retval NRF_SUCCESS If initialization of the service was successful, else,
+ * an error code indicating reason for failure.
+ */
+void ble_ipsp_evt_handler(ble_evt_t const * p_evt);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // BLE_IPSP_H__
+
+/** @} */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/ble_lbs/ble_lbs.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/ble_lbs/ble_lbs.c
new file mode 100644
index 0000000..09adc92
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/ble_lbs/ble_lbs.c
@@ -0,0 +1,235 @@
+/**
+ * Copyright (c) 2013 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#include "sdk_common.h"
+#if NRF_MODULE_ENABLED(BLE_LBS)
+#include "ble_lbs.h"
+#include "ble_srv_common.h"
+
+
+/**@brief Function for handling the Write event.
+ *
+ * @param[in] p_lbs LED Button Service structure.
+ * @param[in] p_ble_evt Event received from the BLE stack.
+ */
+static void on_write(ble_lbs_t * p_lbs, ble_evt_t const * p_ble_evt)
+{
+ ble_gatts_evt_write_t const * p_evt_write = &p_ble_evt->evt.gatts_evt.params.write;
+
+ if ( (p_evt_write->handle == p_lbs->led_char_handles.value_handle)
+ && (p_evt_write->len == 1)
+ && (p_lbs->led_write_handler != NULL))
+ {
+ p_lbs->led_write_handler(p_ble_evt->evt.gap_evt.conn_handle, p_lbs, p_evt_write->data[0]);
+ }
+}
+
+
+void ble_lbs_on_ble_evt(ble_evt_t const * p_ble_evt, void * p_context)
+{
+ ble_lbs_t * p_lbs = (ble_lbs_t *)p_context;
+
+ switch (p_ble_evt->header.evt_id)
+ {
+ case BLE_GATTS_EVT_WRITE:
+ on_write(p_lbs, p_ble_evt);
+ break;
+
+ default:
+ // No implementation needed.
+ break;
+ }
+}
+
+
+/**@brief Function for adding the LED Characteristic.
+ *
+ * @param[in] p_lbs LED Button Service structure.
+ * @param[in] p_lbs_init LED Button Service initialization structure.
+ *
+ * @retval NRF_SUCCESS on success, else an error value from the SoftDevice
+ */
+static uint32_t led_char_add(ble_lbs_t * p_lbs, const ble_lbs_init_t * p_lbs_init)
+{
+ ble_gatts_char_md_t char_md;
+ ble_gatts_attr_t attr_char_value;
+ ble_uuid_t ble_uuid;
+ ble_gatts_attr_md_t attr_md;
+
+ memset(&char_md, 0, sizeof(char_md));
+
+ char_md.char_props.read = 1;
+ char_md.char_props.write = 1;
+ char_md.p_char_user_desc = NULL;
+ char_md.p_char_pf = NULL;
+ char_md.p_user_desc_md = NULL;
+ char_md.p_cccd_md = NULL;
+ char_md.p_sccd_md = NULL;
+
+ ble_uuid.type = p_lbs->uuid_type;
+ ble_uuid.uuid = LBS_UUID_LED_CHAR;
+
+ memset(&attr_md, 0, sizeof(attr_md));
+
+ BLE_GAP_CONN_SEC_MODE_SET_OPEN(&attr_md.read_perm);
+ BLE_GAP_CONN_SEC_MODE_SET_OPEN(&attr_md.write_perm);
+ attr_md.vloc = BLE_GATTS_VLOC_STACK;
+ attr_md.rd_auth = 0;
+ attr_md.wr_auth = 0;
+ attr_md.vlen = 0;
+
+ memset(&attr_char_value, 0, sizeof(attr_char_value));
+
+ attr_char_value.p_uuid = &ble_uuid;
+ attr_char_value.p_attr_md = &attr_md;
+ attr_char_value.init_len = sizeof(uint8_t);
+ attr_char_value.init_offs = 0;
+ attr_char_value.max_len = sizeof(uint8_t);
+ attr_char_value.p_value = NULL;
+
+ return sd_ble_gatts_characteristic_add(p_lbs->service_handle,
+ &char_md,
+ &attr_char_value,
+ &p_lbs->led_char_handles);
+}
+
+
+/**@brief Function for adding the Button Characteristic.
+ *
+ * @param[in] p_lbs LED Button Service structure.
+ * @param[in] p_lbs_init LED Button Service initialization structure.
+ *
+ * @retval NRF_SUCCESS on success, else an error value from the SoftDevice
+ */
+static uint32_t button_char_add(ble_lbs_t * p_lbs, const ble_lbs_init_t * p_lbs_init)
+{
+ ble_gatts_char_md_t char_md;
+ ble_gatts_attr_md_t cccd_md;
+ ble_gatts_attr_t attr_char_value;
+ ble_uuid_t ble_uuid;
+ ble_gatts_attr_md_t attr_md;
+
+ memset(&cccd_md, 0, sizeof(cccd_md));
+
+ BLE_GAP_CONN_SEC_MODE_SET_OPEN(&cccd_md.read_perm);
+ BLE_GAP_CONN_SEC_MODE_SET_OPEN(&cccd_md.write_perm);
+ cccd_md.vloc = BLE_GATTS_VLOC_STACK;
+
+ memset(&char_md, 0, sizeof(char_md));
+
+ char_md.char_props.read = 1;
+ char_md.char_props.notify = 1;
+ char_md.p_char_user_desc = NULL;
+ char_md.p_char_pf = NULL;
+ char_md.p_user_desc_md = NULL;
+ char_md.p_cccd_md = &cccd_md;
+ char_md.p_sccd_md = NULL;
+
+ ble_uuid.type = p_lbs->uuid_type;
+ ble_uuid.uuid = LBS_UUID_BUTTON_CHAR;
+
+ memset(&attr_md, 0, sizeof(attr_md));
+
+ BLE_GAP_CONN_SEC_MODE_SET_OPEN(&attr_md.read_perm);
+ BLE_GAP_CONN_SEC_MODE_SET_NO_ACCESS(&attr_md.write_perm);
+ attr_md.vloc = BLE_GATTS_VLOC_STACK;
+ attr_md.rd_auth = 0;
+ attr_md.wr_auth = 0;
+ attr_md.vlen = 0;
+
+ memset(&attr_char_value, 0, sizeof(attr_char_value));
+
+ attr_char_value.p_uuid = &ble_uuid;
+ attr_char_value.p_attr_md = &attr_md;
+ attr_char_value.init_len = sizeof(uint8_t);
+ attr_char_value.init_offs = 0;
+ attr_char_value.max_len = sizeof(uint8_t);
+ attr_char_value.p_value = NULL;
+
+ return sd_ble_gatts_characteristic_add(p_lbs->service_handle,
+ &char_md,
+ &attr_char_value,
+ &p_lbs->button_char_handles);
+}
+
+
+uint32_t ble_lbs_init(ble_lbs_t * p_lbs, const ble_lbs_init_t * p_lbs_init)
+{
+ uint32_t err_code;
+ ble_uuid_t ble_uuid;
+
+ // Initialize service structure.
+ p_lbs->led_write_handler = p_lbs_init->led_write_handler;
+
+ // Add service.
+ ble_uuid128_t base_uuid = {LBS_UUID_BASE};
+ err_code = sd_ble_uuid_vs_add(&base_uuid, &p_lbs->uuid_type);
+ VERIFY_SUCCESS(err_code);
+
+ ble_uuid.type = p_lbs->uuid_type;
+ ble_uuid.uuid = LBS_UUID_SERVICE;
+
+ err_code = sd_ble_gatts_service_add(BLE_GATTS_SRVC_TYPE_PRIMARY, &ble_uuid, &p_lbs->service_handle);
+ VERIFY_SUCCESS(err_code);
+
+ // Add characteristics.
+ err_code = button_char_add(p_lbs, p_lbs_init);
+ VERIFY_SUCCESS(err_code);
+
+ err_code = led_char_add(p_lbs, p_lbs_init);
+ VERIFY_SUCCESS(err_code);
+
+ return NRF_SUCCESS;
+}
+
+
+uint32_t ble_lbs_on_button_change(uint16_t conn_handle, ble_lbs_t * p_lbs, uint8_t button_state)
+{
+ ble_gatts_hvx_params_t params;
+ uint16_t len = sizeof(button_state);
+
+ memset(&params, 0, sizeof(params));
+ params.type = BLE_GATT_HVX_NOTIFICATION;
+ params.handle = p_lbs->button_char_handles.value_handle;
+ params.p_data = &button_state;
+ params.p_len = &len;
+
+ return sd_ble_gatts_hvx(conn_handle, &params);
+}
+#endif // NRF_MODULE_ENABLED(BLE_LBS)
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/ble_lbs/ble_lbs.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/ble_lbs/ble_lbs.h
new file mode 100644
index 0000000..5791698
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/ble_lbs/ble_lbs.h
@@ -0,0 +1,161 @@
+/**
+ * Copyright (c) 2015 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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
+ *
+ * @defgroup ble_lbs LED Button Service Server
+ * @{
+ * @ingroup ble_sdk_srv
+ *
+ * @brief LED Button Service Server module.
+ *
+ * @details This module implements a custom LED Button Service with an LED and Button Characteristics.
+ * During initialization, the module adds the LED Button Service and Characteristics
+ * to the BLE stack database.
+ *
+ * The application must supply an event handler for receiving LED Button Service
+ * events. Using this handler, the service notifies the application when the
+ * LED value changes.
+ *
+ * The service also provides a function for letting the application notify
+ * the state of the Button Characteristic to connected peers.
+ *
+ * @note The application must register this module as BLE event observer using the
+ * NRF_SDH_BLE_OBSERVER macro. Example:
+ * @code
+ * ble_hids_t instance;
+ * NRF_SDH_BLE_OBSERVER(anything, BLE_HIDS_BLE_OBSERVER_PRIO,
+ * ble_hids_on_ble_evt, &instance);
+ * @endcode
+ */
+
+#ifndef BLE_LBS_H__
+#define BLE_LBS_H__
+
+#include <stdint.h>
+#include <stdbool.h>
+#include "ble.h"
+#include "ble_srv_common.h"
+#include "nrf_sdh_ble.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**@brief Macro for defining a ble_lbs instance.
+ *
+ * @param _name Name of the instance.
+ * @hideinitializer
+ */
+#define BLE_LBS_DEF(_name) \
+static ble_lbs_t _name; \
+NRF_SDH_BLE_OBSERVER(_name ## _obs, \
+ BLE_LBS_BLE_OBSERVER_PRIO, \
+ ble_lbs_on_ble_evt, &_name)
+
+#define LBS_UUID_BASE {0x23, 0xD1, 0xBC, 0xEA, 0x5F, 0x78, 0x23, 0x15, \
+ 0xDE, 0xEF, 0x12, 0x12, 0x00, 0x00, 0x00, 0x00}
+#define LBS_UUID_SERVICE 0x1523
+#define LBS_UUID_BUTTON_CHAR 0x1524
+#define LBS_UUID_LED_CHAR 0x1525
+
+
+// Forward declaration of the ble_lbs_t type.
+typedef struct ble_lbs_s ble_lbs_t;
+
+typedef void (*ble_lbs_led_write_handler_t) (uint16_t conn_handle, ble_lbs_t * p_lbs, uint8_t new_state);
+
+/** @brief LED Button Service init structure. This structure contains all options and data needed for
+ * initialization of the service.*/
+typedef struct
+{
+ ble_lbs_led_write_handler_t led_write_handler; /**< Event handler to be called when the LED Characteristic is written. */
+} ble_lbs_init_t;
+
+/**@brief LED Button Service structure. This structure contains various status information for the service. */
+struct ble_lbs_s
+{
+ uint16_t service_handle; /**< Handle of LED Button Service (as provided by the BLE stack). */
+ ble_gatts_char_handles_t led_char_handles; /**< Handles related to the LED Characteristic. */
+ ble_gatts_char_handles_t button_char_handles; /**< Handles related to the Button Characteristic. */
+ uint8_t uuid_type; /**< UUID type for the LED Button Service. */
+ ble_lbs_led_write_handler_t led_write_handler; /**< Event handler to be called when the LED Characteristic is written. */
+};
+
+
+/**@brief Function for initializing the LED Button Service.
+ *
+ * @param[out] p_lbs LED Button Service structure. This structure must be supplied by
+ * the application. It is initialized by this function and will later
+ * be used to identify this particular service instance.
+ * @param[in] p_lbs_init Information needed to initialize the service.
+ *
+ * @retval NRF_SUCCESS If the service was initialized successfully. Otherwise, an error code is returned.
+ */
+uint32_t ble_lbs_init(ble_lbs_t * p_lbs, const ble_lbs_init_t * p_lbs_init);
+
+
+/**@brief Function for handling the application's BLE stack events.
+ *
+ * @details This function handles all events from the BLE stack that are of interest to the LED Button Service.
+ *
+ * @param[in] p_ble_evt Event received from the BLE stack.
+ * @param[in] p_context LED Button Service structure.
+ */
+void ble_lbs_on_ble_evt(ble_evt_t const * p_ble_evt, void * p_context);
+
+
+/**@brief Function for sending a button state notification.
+ *
+ ' @param[in] conn_handle Handle of the peripheral connection to which the button state notification will be sent.
+ * @param[in] p_lbs LED Button Service structure.
+ * @param[in] button_state New button state.
+ *
+ * @retval NRF_SUCCESS If the notification was sent successfully. Otherwise, an error code is returned.
+ */
+uint32_t ble_lbs_on_button_change(uint16_t conn_handle, ble_lbs_t * p_lbs, uint8_t button_state);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // BLE_LBS_H__
+
+/** @} */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/ble_lbs_c/ble_lbs_c.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/ble_lbs_c/ble_lbs_c.c
new file mode 100644
index 0000000..10d8dc6
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/ble_lbs_c/ble_lbs_c.c
@@ -0,0 +1,394 @@
+/**
+ * Copyright (c) 2012 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#include "sdk_common.h"
+#if NRF_MODULE_ENABLED(BLE_LBS_C)
+
+#include "ble_lbs_c.h"
+#include "ble_db_discovery.h"
+#include "ble_types.h"
+#include "ble_srv_common.h"
+#include "ble_gattc.h"
+#define NRF_LOG_MODULE_NAME ble_lbs_c
+#include "nrf_log.h"
+NRF_LOG_MODULE_REGISTER();
+
+#define TX_BUFFER_MASK 0x07 /**< TX Buffer mask, must be a mask of continuous zeroes, followed by continuous sequence of ones: 000...111. */
+#define TX_BUFFER_SIZE (TX_BUFFER_MASK + 1) /**< Size of send buffer, which is 1 higher than the mask. */
+
+#define WRITE_MESSAGE_LENGTH BLE_CCCD_VALUE_LEN /**< Length of the write message for CCCD. */
+#define WRITE_MESSAGE_LENGTH BLE_CCCD_VALUE_LEN /**< Length of the write message for CCCD. */
+
+typedef enum
+{
+ READ_REQ, /**< Type identifying that this tx_message is a read request. */
+ WRITE_REQ /**< Type identifying that this tx_message is a write request. */
+} tx_request_t;
+
+/**@brief Structure for writing a message to the peer, i.e. CCCD.
+ */
+typedef struct
+{
+ uint8_t gattc_value[WRITE_MESSAGE_LENGTH]; /**< The message to write. */
+ ble_gattc_write_params_t gattc_params; /**< GATTC parameters for this message. */
+} write_params_t;
+
+/**@brief Structure for holding data to be transmitted to the connected central.
+ */
+typedef struct
+{
+ uint16_t conn_handle; /**< Connection handle to be used when transmitting this message. */
+ tx_request_t type; /**< Type of this message, i.e. read or write message. */
+ union
+ {
+ uint16_t read_handle; /**< Read request message. */
+ write_params_t write_req; /**< Write request message. */
+ } req;
+} tx_message_t;
+
+
+static tx_message_t m_tx_buffer[TX_BUFFER_SIZE]; /**< Transmit buffer for messages to be transmitted to the central. */
+static uint32_t m_tx_insert_index = 0; /**< Current index in the transmit buffer where the next message should be inserted. */
+static uint32_t m_tx_index = 0; /**< Current index in the transmit buffer from where the next message to be transmitted resides. */
+
+
+/**@brief Function for passing any pending request from the buffer to the stack.
+ */
+static void tx_buffer_process(void)
+{
+ if (m_tx_index != m_tx_insert_index)
+ {
+ uint32_t err_code;
+
+ if (m_tx_buffer[m_tx_index].type == READ_REQ)
+ {
+ err_code = sd_ble_gattc_read(m_tx_buffer[m_tx_index].conn_handle,
+ m_tx_buffer[m_tx_index].req.read_handle,
+ 0);
+ }
+ else
+ {
+ err_code = sd_ble_gattc_write(m_tx_buffer[m_tx_index].conn_handle,
+ &m_tx_buffer[m_tx_index].req.write_req.gattc_params);
+ }
+ if (err_code == NRF_SUCCESS)
+ {
+ NRF_LOG_DEBUG("SD Read/Write API returns Success..");
+ m_tx_index++;
+ m_tx_index &= TX_BUFFER_MASK;
+ }
+ else
+ {
+ NRF_LOG_DEBUG("SD Read/Write API returns error. This message sending will be "
+ "attempted again..");
+ }
+ }
+}
+
+
+/**@brief Function for handling write response events.
+ *
+ * @param[in] p_ble_lbs_c Pointer to the Led Button Client structure.
+ * @param[in] p_ble_evt Pointer to the BLE event received.
+ */
+static void on_write_rsp(ble_lbs_c_t * p_ble_lbs_c, ble_evt_t const * p_ble_evt)
+{
+ // Check if the event if on the link for this instance
+ if (p_ble_lbs_c->conn_handle != p_ble_evt->evt.gattc_evt.conn_handle)
+ {
+ return;
+ }
+ // Check if there is any message to be sent across to the peer and send it.
+ tx_buffer_process();
+}
+
+
+/**@brief Function for handling Handle Value Notification received from the SoftDevice.
+ *
+ * @details This function will uses the Handle Value Notification received from the SoftDevice
+ * and checks if it is a notification of Button state from the peer. If
+ * it is, this function will decode the state of the button and send it to the
+ * application.
+ *
+ * @param[in] p_ble_lbs_c Pointer to the Led Button Client structure.
+ * @param[in] p_ble_evt Pointer to the BLE event received.
+ */
+static void on_hvx(ble_lbs_c_t * p_ble_lbs_c, ble_evt_t const * p_ble_evt)
+{
+ // Check if the event is on the link for this instance
+ if (p_ble_lbs_c->conn_handle != p_ble_evt->evt.gattc_evt.conn_handle)
+ {
+ return;
+ }
+ // Check if this is a Button notification.
+ if (p_ble_evt->evt.gattc_evt.params.hvx.handle == p_ble_lbs_c->peer_lbs_db.button_handle)
+ {
+ if (p_ble_evt->evt.gattc_evt.params.hvx.len == 1)
+ {
+ ble_lbs_c_evt_t ble_lbs_c_evt;
+
+ ble_lbs_c_evt.evt_type = BLE_LBS_C_EVT_BUTTON_NOTIFICATION;
+ ble_lbs_c_evt.conn_handle = p_ble_lbs_c->conn_handle;
+ ble_lbs_c_evt.params.button.button_state = p_ble_evt->evt.gattc_evt.params.hvx.data[0];
+ p_ble_lbs_c->evt_handler(p_ble_lbs_c, &ble_lbs_c_evt);
+ }
+ }
+}
+
+
+/**@brief Function for handling Disconnected event received from the SoftDevice.
+ *
+ * @details This function check if the disconnect event is happening on the link
+ * associated with the current instance of the module, if so it will set its
+ * conn_handle to invalid.
+ *
+ * @param[in] p_ble_lbs_c Pointer to the Led Button Client structure.
+ * @param[in] p_ble_evt Pointer to the BLE event received.
+ */
+static void on_disconnected(ble_lbs_c_t * p_ble_lbs_c, ble_evt_t const * p_ble_evt)
+{
+ if (p_ble_lbs_c->conn_handle == p_ble_evt->evt.gap_evt.conn_handle)
+ {
+ p_ble_lbs_c->conn_handle = BLE_CONN_HANDLE_INVALID;
+ p_ble_lbs_c->peer_lbs_db.button_cccd_handle = BLE_GATT_HANDLE_INVALID;
+ p_ble_lbs_c->peer_lbs_db.button_handle = BLE_GATT_HANDLE_INVALID;
+ p_ble_lbs_c->peer_lbs_db.led_handle = BLE_GATT_HANDLE_INVALID;
+ }
+}
+
+
+void ble_lbs_on_db_disc_evt(ble_lbs_c_t * p_ble_lbs_c, ble_db_discovery_evt_t const * p_evt)
+{
+ // Check if the Led Button Service was discovered.
+ if (p_evt->evt_type == BLE_DB_DISCOVERY_COMPLETE &&
+ p_evt->params.discovered_db.srv_uuid.uuid == LBS_UUID_SERVICE &&
+ p_evt->params.discovered_db.srv_uuid.type == p_ble_lbs_c->uuid_type)
+ {
+ ble_lbs_c_evt_t evt;
+
+ evt.evt_type = BLE_LBS_C_EVT_DISCOVERY_COMPLETE;
+ evt.conn_handle = p_evt->conn_handle;
+
+ for (uint32_t i = 0; i < p_evt->params.discovered_db.char_count; i++)
+ {
+ const ble_gatt_db_char_t * p_char = &(p_evt->params.discovered_db.charateristics[i]);
+ switch (p_char->characteristic.uuid.uuid)
+ {
+ case LBS_UUID_LED_CHAR:
+ evt.params.peer_db.led_handle = p_char->characteristic.handle_value;
+ break;
+ case LBS_UUID_BUTTON_CHAR:
+ evt.params.peer_db.button_handle = p_char->characteristic.handle_value;
+ evt.params.peer_db.button_cccd_handle = p_char->cccd_handle;
+ break;
+
+ default:
+ break;
+ }
+ }
+
+ NRF_LOG_DEBUG("Led Button Service discovered at peer.");
+ //If the instance has been assigned prior to db_discovery, assign the db_handles
+ if (p_ble_lbs_c->conn_handle != BLE_CONN_HANDLE_INVALID)
+ {
+ if ((p_ble_lbs_c->peer_lbs_db.led_handle == BLE_GATT_HANDLE_INVALID)&&
+ (p_ble_lbs_c->peer_lbs_db.button_handle == BLE_GATT_HANDLE_INVALID)&&
+ (p_ble_lbs_c->peer_lbs_db.button_cccd_handle == BLE_GATT_HANDLE_INVALID))
+ {
+ p_ble_lbs_c->peer_lbs_db = evt.params.peer_db;
+ }
+ }
+
+ p_ble_lbs_c->evt_handler(p_ble_lbs_c, &evt);
+
+ }
+}
+
+
+uint32_t ble_lbs_c_init(ble_lbs_c_t * p_ble_lbs_c, ble_lbs_c_init_t * p_ble_lbs_c_init)
+{
+ uint32_t err_code;
+ ble_uuid_t lbs_uuid;
+ ble_uuid128_t lbs_base_uuid = {LBS_UUID_BASE};
+
+ VERIFY_PARAM_NOT_NULL(p_ble_lbs_c);
+ VERIFY_PARAM_NOT_NULL(p_ble_lbs_c_init);
+ VERIFY_PARAM_NOT_NULL(p_ble_lbs_c_init->evt_handler);
+
+ p_ble_lbs_c->peer_lbs_db.button_cccd_handle = BLE_GATT_HANDLE_INVALID;
+ p_ble_lbs_c->peer_lbs_db.button_handle = BLE_GATT_HANDLE_INVALID;
+ p_ble_lbs_c->peer_lbs_db.led_handle = BLE_GATT_HANDLE_INVALID;
+ p_ble_lbs_c->conn_handle = BLE_CONN_HANDLE_INVALID;
+ p_ble_lbs_c->evt_handler = p_ble_lbs_c_init->evt_handler;
+
+ err_code = sd_ble_uuid_vs_add(&lbs_base_uuid, &p_ble_lbs_c->uuid_type);
+ if (err_code != NRF_SUCCESS)
+ {
+ return err_code;
+ }
+ VERIFY_SUCCESS(err_code);
+
+ lbs_uuid.type = p_ble_lbs_c->uuid_type;
+ lbs_uuid.uuid = LBS_UUID_SERVICE;
+
+ return ble_db_discovery_evt_register(&lbs_uuid);
+}
+
+void ble_lbs_c_on_ble_evt(ble_evt_t const * p_ble_evt, void * p_context)
+{
+ if ((p_context == NULL) || (p_ble_evt == NULL))
+ {
+ return;
+ }
+
+ ble_lbs_c_t * p_ble_lbs_c = (ble_lbs_c_t *)p_context;
+
+ switch (p_ble_evt->header.evt_id)
+ {
+ case BLE_GATTC_EVT_HVX:
+ on_hvx(p_ble_lbs_c, p_ble_evt);
+ break;
+
+ case BLE_GATTC_EVT_WRITE_RSP:
+ on_write_rsp(p_ble_lbs_c, p_ble_evt);
+ break;
+
+ case BLE_GAP_EVT_DISCONNECTED:
+ on_disconnected(p_ble_lbs_c, p_ble_evt);
+ break;
+
+ default:
+ break;
+ }
+}
+
+
+/**@brief Function for configuring the CCCD.
+ *
+ * @param[in] conn_handle The connection handle on which to configure the CCCD.
+ * @param[in] handle_cccd The handle of the CCCD to be configured.
+ * @param[in] enable Whether to enable or disable the CCCD.
+ *
+ * @return NRF_SUCCESS if the CCCD configure was successfully sent to the peer.
+ */
+static uint32_t cccd_configure(uint16_t conn_handle, uint16_t handle_cccd, bool enable)
+{
+ NRF_LOG_DEBUG("Configuring CCCD. CCCD Handle = %d, Connection Handle = %d",
+ handle_cccd,conn_handle);
+
+ tx_message_t * p_msg;
+ uint16_t cccd_val = enable ? BLE_GATT_HVX_NOTIFICATION : 0;
+
+ p_msg = &m_tx_buffer[m_tx_insert_index++];
+ m_tx_insert_index &= TX_BUFFER_MASK;
+
+ p_msg->req.write_req.gattc_params.handle = handle_cccd;
+ p_msg->req.write_req.gattc_params.len = WRITE_MESSAGE_LENGTH;
+ p_msg->req.write_req.gattc_params.p_value = p_msg->req.write_req.gattc_value;
+ p_msg->req.write_req.gattc_params.offset = 0;
+ p_msg->req.write_req.gattc_params.write_op = BLE_GATT_OP_WRITE_REQ;
+ p_msg->req.write_req.gattc_value[0] = LSB_16(cccd_val);
+ p_msg->req.write_req.gattc_value[1] = MSB_16(cccd_val);
+ p_msg->conn_handle = conn_handle;
+ p_msg->type = WRITE_REQ;
+
+ tx_buffer_process();
+ return NRF_SUCCESS;
+}
+
+
+uint32_t ble_lbs_c_button_notif_enable(ble_lbs_c_t * p_ble_lbs_c)
+{
+ VERIFY_PARAM_NOT_NULL(p_ble_lbs_c);
+
+ if (p_ble_lbs_c->conn_handle == BLE_CONN_HANDLE_INVALID)
+ {
+ return NRF_ERROR_INVALID_STATE;
+ }
+
+ return cccd_configure(p_ble_lbs_c->conn_handle,
+ p_ble_lbs_c->peer_lbs_db.button_cccd_handle,
+ true);
+}
+
+
+uint32_t ble_lbs_led_status_send(ble_lbs_c_t * p_ble_lbs_c, uint8_t status)
+{
+ VERIFY_PARAM_NOT_NULL(p_ble_lbs_c);
+
+ if (p_ble_lbs_c->conn_handle == BLE_CONN_HANDLE_INVALID)
+ {
+ return NRF_ERROR_INVALID_STATE;
+ }
+
+ NRF_LOG_DEBUG("writing LED status 0x%x", status);
+
+ tx_message_t * p_msg;
+
+ p_msg = &m_tx_buffer[m_tx_insert_index++];
+ m_tx_insert_index &= TX_BUFFER_MASK;
+
+ p_msg->req.write_req.gattc_params.handle = p_ble_lbs_c->peer_lbs_db.led_handle;
+ p_msg->req.write_req.gattc_params.len = sizeof(status);
+ p_msg->req.write_req.gattc_params.p_value = p_msg->req.write_req.gattc_value;
+ p_msg->req.write_req.gattc_params.offset = 0;
+ p_msg->req.write_req.gattc_params.write_op = BLE_GATT_OP_WRITE_CMD;
+ p_msg->req.write_req.gattc_value[0] = status;
+ p_msg->conn_handle = p_ble_lbs_c->conn_handle;
+ p_msg->type = WRITE_REQ;
+
+ tx_buffer_process();
+ return NRF_SUCCESS;
+}
+
+uint32_t ble_lbs_c_handles_assign(ble_lbs_c_t * p_ble_lbs_c,
+ uint16_t conn_handle,
+ const lbs_db_t * p_peer_handles)
+{
+ VERIFY_PARAM_NOT_NULL(p_ble_lbs_c);
+
+ p_ble_lbs_c->conn_handle = conn_handle;
+ if (p_peer_handles != NULL)
+ {
+ p_ble_lbs_c->peer_lbs_db = *p_peer_handles;
+ }
+ return NRF_SUCCESS;
+}
+
+#endif // NRF_MODULE_ENABLED(BLE_LBS_C)
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/ble_lbs_c/ble_lbs_c.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/ble_lbs_c/ble_lbs_c.h
new file mode 100644
index 0000000..a3b19d6
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/ble_lbs_c/ble_lbs_c.h
@@ -0,0 +1,254 @@
+/**
+ * Copyright (c) 2016 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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
+ *
+ * @defgroup ble_lbs_c LED Button Service Client
+ * @{
+ * @ingroup ble_sdk_srv
+ * @brief The LED Button Service client can be used to set a LED, and read a button state on a
+ * LED button service server.
+ *
+ * @details This module contains the APIs and types exposed by the LED Button Service Client
+ * module. These APIs and types can be used by the application to perform discovery of
+ * LED Button Service at the peer and interact with it.
+ *
+ * @note The application must register this module as BLE event observer using the
+ * NRF_SDH_BLE_OBSERVER macro. Example:
+ * @code
+ * ble_lbs_c_t instance;
+ * NRF_SDH_BLE_OBSERVER(anything, BLE_LBS_C_BLE_OBSERVER_PRIO,
+ * ble_lbs_c_on_ble_evt, &instance);
+ * @endcode
+ */
+
+#ifndef BLE_LBS_C_H__
+#define BLE_LBS_C_H__
+
+#include <stdint.h>
+#include "ble.h"
+#include "ble_db_discovery.h"
+#include "nrf_sdh_ble.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**@brief Macro for defining a ble_lbs_c instance.
+ *
+ * @param _name Name of the instance.
+ * @hideinitializer
+ */
+#define BLE_LBS_C_DEF(_name) \
+static ble_lbs_c_t _name; \
+NRF_SDH_BLE_OBSERVER(_name ## _obs, \
+ BLE_LBS_C_BLE_OBSERVER_PRIO, \
+ ble_lbs_c_on_ble_evt, &_name)
+
+/**@brief Macro for defining multiple ble_lbs_c instances.
+ *
+ * @param _name Name of the array of instances.
+ * @param _cnt Number of instances to define.
+ */
+#define BLE_LBS_C_ARRAY_DEF(_name, _cnt) \
+static ble_lbs_c_t _name[_cnt]; \
+NRF_SDH_BLE_OBSERVERS(_name ## _obs, \
+ BLE_LBS_C_BLE_OBSERVER_PRIO, \
+ ble_lbs_c_on_ble_evt, &_name, _cnt)
+
+
+#define LBS_UUID_BASE {0x23, 0xD1, 0xBC, 0xEA, 0x5F, 0x78, 0x23, 0x15, \
+ 0xDE, 0xEF, 0x12, 0x12, 0x00, 0x00, 0x00, 0x00}
+#define LBS_UUID_SERVICE 0x1523
+#define LBS_UUID_BUTTON_CHAR 0x1524
+#define LBS_UUID_LED_CHAR 0x1525
+
+/**@brief LBS Client event type. */
+typedef enum
+{
+ BLE_LBS_C_EVT_DISCOVERY_COMPLETE = 1, /**< Event indicating that the LED Button Service has been discovered at the peer. */
+ BLE_LBS_C_EVT_BUTTON_NOTIFICATION /**< Event indicating that a notification of the LED Button Button characteristic has been received from the peer. */
+} ble_lbs_c_evt_type_t;
+
+/**@brief Structure containing the Button value received from the peer. */
+typedef struct
+{
+ uint8_t button_state; /**< Button Value. */
+} ble_button_t;
+
+/**@brief Structure containing the handles related to the LED Button Service found on the peer. */
+typedef struct
+{
+ uint16_t button_cccd_handle; /**< Handle of the CCCD of the Button characteristic. */
+ uint16_t button_handle; /**< Handle of the Button characteristic as provided by the SoftDevice. */
+ uint16_t led_handle; /**< Handle of the LED characteristic as provided by the SoftDevice. */
+} lbs_db_t;
+
+/**@brief LED Button Event structure. */
+typedef struct
+{
+ ble_lbs_c_evt_type_t evt_type; /**< Type of the event. */
+ uint16_t conn_handle; /**< Connection handle on which the event occured.*/
+ union
+ {
+ ble_button_t button; /**< Button Value received. This will be filled if the evt_type is @ref BLE_LBS_C_EVT_BUTTON_NOTIFICATION. */
+ lbs_db_t peer_db; /**< LED Button Service related handles found on the peer device. This will be filled if the evt_type is @ref BLE_LBS_C_EVT_DISCOVERY_COMPLETE.*/
+ } params;
+} ble_lbs_c_evt_t;
+
+// Forward declaration of the ble_lbs_c_t type.
+typedef struct ble_lbs_c_s ble_lbs_c_t;
+
+/**@brief Event handler type.
+ *
+ * @details This is the type of the event handler that should be provided by the application
+ * of this module in order to receive events.
+ */
+typedef void (* ble_lbs_c_evt_handler_t) (ble_lbs_c_t * p_ble_lbs_c, ble_lbs_c_evt_t * p_evt);
+
+/**@brief LED Button Client structure. */
+struct ble_lbs_c_s
+{
+ uint16_t conn_handle; /**< Connection handle as provided by the SoftDevice. */
+ lbs_db_t peer_lbs_db; /**< Handles related to LBS on the peer*/
+ ble_lbs_c_evt_handler_t evt_handler; /**< Application event handler to be called when there is an event related to the LED Button service. */
+ uint8_t uuid_type; /**< UUID type. */
+};
+
+/**@brief LED Button Client initialization structure. */
+typedef struct
+{
+ ble_lbs_c_evt_handler_t evt_handler; /**< Event handler to be called by the LED Button Client module whenever there is an event related to the LED Button Service. */
+} ble_lbs_c_init_t;
+
+
+/**@brief Function for initializing the LED Button client module.
+ *
+ * @details This function will register with the DB Discovery module. There it registers for the
+ * LED Button Service. Doing so will make the DB Discovery module look for the presence
+ * of a LED Button Service instance at the peer when a discovery is started.
+ *
+ * @param[in] p_ble_lbs_c Pointer to the LED Button client structure.
+ * @param[in] p_ble_lbs_c_init Pointer to the LED Button initialization structure containing the
+ * initialization information.
+ *
+ * @retval NRF_SUCCESS On successful initialization. Otherwise an error code. This function
+ * propagates the error code returned by the Database Discovery module API
+ * @ref ble_db_discovery_evt_register.
+ */
+uint32_t ble_lbs_c_init(ble_lbs_c_t * p_ble_lbs_c, ble_lbs_c_init_t * p_ble_lbs_c_init);
+
+
+/**@brief Function for handling BLE events from the SoftDevice.
+ *
+ * @details This function will handle the BLE events received from the SoftDevice. If a BLE event
+ * is relevant to the LED Button Client module, then it uses it to update interval
+ * variables and, if necessary, send events to the application.
+ *
+ * @param[in] p_ble_evt Pointer to the BLE event.
+ * @param[in] p_context Pointer to the LED button client structure.
+ */
+void ble_lbs_c_on_ble_evt(ble_evt_t const * p_ble_evt, void * p_context);
+
+
+/**@brief Function for requesting the peer to start sending notification of the Button
+ * Characteristic.
+ *
+ * @details This function will enable to notification of the Button at the peer
+ * by writing to the CCCD of the Button Characteristic.
+ *
+ * @param[in] p_ble_lbs_c Pointer to the LED Button Client structure.
+ *
+ * @retval NRF_SUCCESS If the SoftDevice has been requested to write to the CCCD of the peer.
+ * Otherwise, an error code. This function propagates the error code returned
+ * by the SoftDevice API @ref sd_ble_gattc_write.
+ * NRF_ERROR_INVALID_STATE if no connection handle has been assigned (@ref ble_lbs_c_handles_assign)
+ * NRF_ERROR_NULL if the given parameter is NULL
+ */
+uint32_t ble_lbs_c_button_notif_enable(ble_lbs_c_t * p_ble_lbs_c);
+
+
+/**@brief Function for handling events from the database discovery module.
+ *
+ * @details Call this function when getting a callback event from the DB discovery module. This
+ * function will handle an event from the database discovery module, and determine if it
+ * relates to the discovery of LED Button service at the peer. If so, it will call the
+ * application's event handler indicating that the LED Button service has been discovered
+ * at the peer. It also populates the event with the service related information before
+ * providing it to the application.
+ *
+ * @param[in] p_ble_lbs_c Pointer to the LED Button client structure.
+ * @param[in] p_evt Pointer to the event received from the database discovery module.
+ */
+void ble_lbs_on_db_disc_evt(ble_lbs_c_t * p_ble_lbs_c, const ble_db_discovery_evt_t * p_evt);
+
+
+/**@brief Function for assigning a Handles to this instance of lbs_c.
+ *
+ * @details Call this function when a link has been established with a peer to associate this link
+ * to this instance of the module. This makes it possible to handle several links and
+ * associate each link to a particular instance of this module.
+ *
+ * @param[in] p_ble_lbs_c Pointer to the LED Button client structure instance to associate.
+ * @param[in] conn_handle Connection handle to associate with the given LED Button Client Instance.
+ * @param[in] p_peer_handles LED Button Service handles found on the peer (from @ref BLE_LBS_C_EVT_DISCOVERY_COMPLETE event).
+ *
+ */
+uint32_t ble_lbs_c_handles_assign(ble_lbs_c_t * p_ble_lbs_c,
+ uint16_t conn_handle,
+ const lbs_db_t * p_peer_handles);
+
+
+/**@brief Function for writing the LED status to the connected server.
+ *
+ * @param[in] p_ble_lbs_c Pointer to the LED Button client structure.
+ * @param[in] status LED status to send.
+ *
+ * @retval NRF_SUCCESS If the staus was sent successfully. Otherwise, an error code is returned.
+ */
+uint32_t ble_lbs_led_status_send(ble_lbs_c_t * p_ble_lbs_c, uint8_t status);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // BLE_LBS_C_H__
+
+/** @} */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/ble_lls/ble_lls.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/ble_lls/ble_lls.c
new file mode 100644
index 0000000..ceb3102
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/ble_lls/ble_lls.c
@@ -0,0 +1,260 @@
+/**
+ * Copyright (c) 2012 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+/* Attention!
+ * To maintain compliance with Nordic Semiconductor ASA's Bluetooth profile
+ * qualification listings, this section of source code must not be modified.
+ */
+#include "sdk_common.h"
+#if NRF_MODULE_ENABLED(BLE_LLS)
+#include "ble_lls.h"
+#include <string.h>
+#include "ble_hci.h"
+#include "ble_srv_common.h"
+
+
+/**@brief Function for handling the Connect event.
+ *
+ * @param[in] p_lls Link Loss Service structure.
+ * @param[in] p_ble_evt Event received from the BLE stack.
+ */
+static void on_connect(ble_lls_t * p_lls, ble_evt_t const * p_ble_evt)
+{
+ // Link reconnected, notify application with a no_alert event
+ ble_lls_evt_t evt;
+
+ p_lls->conn_handle = p_ble_evt->evt.gap_evt.conn_handle;
+
+ evt.evt_type = BLE_LLS_EVT_LINK_LOSS_ALERT;
+ evt.params.alert_level = BLE_CHAR_ALERT_LEVEL_NO_ALERT;
+ p_lls->evt_handler(p_lls, &evt);
+}
+
+
+/**@brief Function for handling the Disconnect event.
+ *
+ * @param[in] p_lls Link Loss Service structure.
+ * @param[in] p_ble_evt Event received from the BLE stack.
+ */
+static void on_disconnect(ble_lls_t * p_lls, ble_evt_t const * p_ble_evt)
+{
+ uint8_t reason = p_ble_evt->evt.gap_evt.params.disconnected.reason;
+
+ if (reason == BLE_HCI_CONNECTION_TIMEOUT)
+ {
+ // Link loss detected, notify application
+ uint32_t err_code;
+ ble_lls_evt_t evt;
+
+ evt.evt_type = BLE_LLS_EVT_LINK_LOSS_ALERT;
+
+ err_code = ble_lls_alert_level_get(p_lls, &evt.params.alert_level);
+ if (err_code == NRF_SUCCESS)
+ {
+ p_lls->evt_handler(p_lls, &evt);
+ }
+ else
+ {
+ if (p_lls->error_handler != NULL)
+ {
+ p_lls->error_handler(err_code);
+ }
+ }
+ }
+}
+
+
+/**@brief Function for handling the Authentication Status event.
+ *
+ * @param[in] p_lls Link Loss Service structure.
+ * @param[in] p_ble_evt Event received from the BLE stack.
+ */
+static void on_auth_status(ble_lls_t * p_lls, ble_evt_t const * p_ble_evt)
+{
+ if (p_ble_evt->evt.gap_evt.params.auth_status.auth_status == BLE_GAP_SEC_STATUS_SUCCESS)
+ {
+ ble_lls_evt_t evt;
+
+ evt.evt_type = BLE_LLS_EVT_LINK_LOSS_ALERT;
+ evt.params.alert_level = BLE_CHAR_ALERT_LEVEL_NO_ALERT;
+
+ p_lls->evt_handler(p_lls, &evt);
+ }
+}
+
+
+void ble_lls_on_ble_evt(ble_evt_t const * p_ble_evt, void * p_context)
+{
+ ble_lls_t * p_lls = (ble_lls_t *)p_context;
+
+ if (p_lls == NULL || p_ble_evt == NULL)
+ {
+ return;
+ }
+
+ switch (p_ble_evt->header.evt_id)
+ {
+ case BLE_GAP_EVT_CONNECTED:
+ on_connect(p_lls, p_ble_evt);
+ break;
+
+ case BLE_GAP_EVT_DISCONNECTED:
+ on_disconnect(p_lls, p_ble_evt);
+ break;
+
+ case BLE_GAP_EVT_AUTH_STATUS:
+ on_auth_status(p_lls, p_ble_evt);
+ break;
+
+ default:
+ // No implementation needed.
+ break;
+ }
+}
+
+
+/**@brief Function for adding Alert Level characteristics.
+ *
+ * @param[in] p_lls Link Loss Service structure.
+ * @param[in] p_lls_init Information needed to initialize the service.
+ *
+ * @return NRF_SUCCESS on success, otherwise an error code.
+ */
+static uint32_t alert_level_char_add(ble_lls_t * p_lls, const ble_lls_init_t * p_lls_init)
+{
+ ble_gatts_char_md_t char_md;
+ ble_gatts_attr_t attr_char_value;
+ ble_uuid_t ble_uuid;
+ ble_gatts_attr_md_t attr_md;
+ uint8_t initial_alert_level;
+
+ memset(&char_md, 0, sizeof(char_md));
+
+ char_md.char_props.read = 1;
+ char_md.char_props.write = 1;
+ char_md.p_char_user_desc = NULL;
+ char_md.p_char_pf = NULL;
+ char_md.p_user_desc_md = NULL;
+ char_md.p_cccd_md = NULL;
+ char_md.p_sccd_md = NULL;
+
+ BLE_UUID_BLE_ASSIGN(ble_uuid, BLE_UUID_ALERT_LEVEL_CHAR);
+ memset(&attr_md, 0, sizeof(attr_md));
+
+ attr_md.read_perm = p_lls_init->lls_attr_md.read_perm;
+ attr_md.write_perm = p_lls_init->lls_attr_md.write_perm;
+ attr_md.vloc = BLE_GATTS_VLOC_STACK;
+ attr_md.rd_auth = 0;
+ attr_md.wr_auth = 0;
+ attr_md.vlen = 0;
+
+ memset(&attr_char_value, 0, sizeof(attr_char_value));
+ initial_alert_level = p_lls_init->initial_alert_level;
+
+ attr_char_value.p_uuid = &ble_uuid;
+ attr_char_value.p_attr_md = &attr_md;
+ attr_char_value.init_len = sizeof (uint8_t);
+ attr_char_value.init_offs = 0;
+ attr_char_value.max_len = sizeof (uint8_t);
+ attr_char_value.p_value = &initial_alert_level;
+
+ return sd_ble_gatts_characteristic_add(p_lls->service_handle,
+ &char_md,
+ &attr_char_value,
+ &p_lls->alert_level_handles);
+}
+
+
+uint32_t ble_lls_init(ble_lls_t * p_lls, const ble_lls_init_t * p_lls_init)
+{
+ uint32_t err_code;
+ ble_uuid_t ble_uuid;
+
+ if (p_lls == NULL || p_lls_init == NULL)
+ {
+ return NRF_ERROR_NULL;
+ }
+
+ if (p_lls_init->evt_handler == NULL)
+ {
+ return NRF_ERROR_INVALID_PARAM;
+ }
+
+ // Initialize service structure
+ p_lls->evt_handler = p_lls_init->evt_handler;
+ p_lls->error_handler = p_lls_init->error_handler;
+
+ // Add service
+ BLE_UUID_BLE_ASSIGN(ble_uuid, BLE_UUID_LINK_LOSS_SERVICE);
+
+ err_code = sd_ble_gatts_service_add(BLE_GATTS_SRVC_TYPE_PRIMARY,
+ &ble_uuid,
+ &p_lls->service_handle);
+
+ if (err_code != NRF_SUCCESS)
+ {
+ return err_code;
+ }
+
+ // Add alert level characteristic
+ return alert_level_char_add(p_lls, p_lls_init);
+}
+
+
+uint32_t ble_lls_alert_level_get(ble_lls_t * p_lls, uint8_t * p_alert_level)
+{
+ ble_gatts_value_t gatts_value;
+
+ if (p_lls == NULL || p_alert_level == NULL)
+ {
+ return NRF_ERROR_NULL;
+ }
+
+ // Initialize value struct.
+ memset(&gatts_value, 0, sizeof(gatts_value));
+
+ gatts_value.len = sizeof(uint8_t);
+ gatts_value.offset = 0;
+ gatts_value.p_value = p_alert_level;
+
+ return sd_ble_gatts_value_get(p_lls->conn_handle,
+ p_lls->alert_level_handles.value_handle,
+ &gatts_value);
+}
+#endif // NRF_MODULE_ENABLED(BLE_LLS)
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/ble_lls/ble_lls.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/ble_lls/ble_lls.h
new file mode 100644
index 0000000..22ea716
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/ble_lls/ble_lls.h
@@ -0,0 +1,175 @@
+/**
+ * Copyright (c) 2012 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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
+ *
+ * @defgroup ble_lls Link Loss Service
+ * @{
+ * @ingroup ble_sdk_srv
+ * @brief Link Loss Service module.
+ *
+ * @details This module implements the Link Loss Service with the Alert Level characteristic.
+ * During initialization it adds the Link Loss Service and Alert Level characteristic
+ * to the BLE stack database.
+ *
+ * The application must supply an event handler for receiving Link Loss Service
+ * events. Using this handler, the service will notify the application when the
+ * link has been lost, and which Alert Level has been set.
+ *
+ * The service also provides a function for letting the application poll the current
+ * value of the Alert Level characteristic.
+ *
+ * @note The application must register this module as BLE event observer using the
+ * NRF_SDH_BLE_OBSERVER macro. Example:
+ * @code
+ * ble_lls_t instance;
+ * NRF_SDH_BLE_OBSERVER(anything, BLE_LLS_BLE_OBSERVER_PRIO,
+ * ble_lls_on_ble_evt, &instance);
+ * @endcode
+ *
+ * @note Attention!
+ * To maintain compliance with Nordic Semiconductor ASA Bluetooth profile
+ * qualification listings, this section of source code must not be modified.
+*/
+
+#ifndef BLE_LLS_H__
+#define BLE_LLS_H__
+
+#include <stdint.h>
+#include "ble.h"
+#include "ble_srv_common.h"
+#include "nrf_sdh_ble.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**@brief Macro for defining a ble_lls instance.
+ *
+ * @param _name Name of the instance.
+ * @hideinitializer
+ */
+#define BLE_LLS_DEF(_name) \
+static ble_lls_t _name; \
+NRF_SDH_BLE_OBSERVER(_name ## _obs, \
+ BLE_LLS_BLE_OBSERVER_PRIO, \
+ ble_lls_on_ble_evt, &_name)
+
+
+/**@brief Link Loss Service event type. */
+typedef enum
+{
+ BLE_LLS_EVT_LINK_LOSS_ALERT /**< Alert Level Updated event. */
+} ble_lls_evt_type_t;
+
+/**@brief Link Loss Service event. */
+typedef struct
+{
+ ble_lls_evt_type_t evt_type; /**< Type of event. */
+ union
+ {
+ uint8_t alert_level; /**< New Alert Level value. */
+ } params;
+} ble_lls_evt_t;
+
+// Forward declaration of the ble_lls_t type.
+typedef struct ble_lls_s ble_lls_t;
+
+/**@brief Link Loss Service event handler type. */
+typedef void (*ble_lls_evt_handler_t) (ble_lls_t * p_lls, ble_lls_evt_t * p_evt);
+
+/**@brief Link Loss Service init structure. This contains all options and data needed for initialization of the service. */
+typedef struct
+{
+ ble_lls_evt_handler_t evt_handler; /**< Event handler to be called for handling events in the Link Loss Service. */
+ ble_srv_error_handler_t error_handler; /**< Function to be called in case of an error. */
+ uint8_t initial_alert_level; /**< Initial value of the Alert Level characteristic. */
+ ble_srv_security_mode_t lls_attr_md; /**< Initial Security Setting for Link Loss Service Characteristics. */
+} ble_lls_init_t;
+
+/**@brief Link Loss Service structure. This contains various status information for the service. */
+struct ble_lls_s
+{
+ ble_lls_evt_handler_t evt_handler; /**< Event handler to be called for handling events in the Link Loss Service. */
+ ble_srv_error_handler_t error_handler; /**< Function to be called in case of an error. */
+ uint16_t service_handle; /**< Handle of Link Loss Service (as provided by the BLE stack). */
+ ble_gatts_char_handles_t alert_level_handles; /**< Handles related to the Alert Level characteristic. */
+ uint16_t conn_handle; /**< Handle of the current connection (as provided by the BLE stack, is BLE_CONN_HANDLE_INVALID if not in a connection). */
+};
+
+
+/**@brief Function for initializing the Link Loss Service.
+ *
+ * @param[out] p_lls Link Loss Service structure. This structure will have to be supplied by
+ * the application. It will be initialized by this function, and will later
+ * be used to identify this particular service instance.
+ * @param[in] p_lls_init Information needed to initialize the service.
+ *
+ * @return NRF_SUCCESS on successful initialization of service, otherwise an error code.
+ */
+uint32_t ble_lls_init(ble_lls_t * p_lls, const ble_lls_init_t * p_lls_init);
+
+
+/**@brief Function for handling the Application's BLE Stack events.
+ *
+ * @details Handles all events from the BLE stack of interest to the Link Loss Service.
+ *
+ * @param[in] p_ble_evt Event received from the BLE stack.
+ * @param[in] p_context Link Loss Service structure.
+ */
+void ble_lls_on_ble_evt(ble_evt_t const * p_ble_evt, void * p_context);
+
+
+/**@brief Function for getting current value of the Alert Level characteristic.
+ *
+ * @param[in] p_lls Link Loss Service structure.
+ * @param[out] p_alert_level Current Alert Level value.
+ *
+ * @return NRF_SUCCESS on success, otherwise an error code.
+ */
+uint32_t ble_lls_alert_level_get(ble_lls_t * p_lls, uint8_t * p_alert_level);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // BLE_LLS_H__
+
+/** @} */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/ble_nus/ble_nus.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/ble_nus/ble_nus.c
new file mode 100644
index 0000000..738b6d6
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/ble_nus/ble_nus.c
@@ -0,0 +1,440 @@
+/**
+ * Copyright (c) 2012 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#include "sdk_common.h"
+#if NRF_MODULE_ENABLED(BLE_NUS)
+#include "ble.h"
+#include "ble_nus.h"
+#include "ble_srv_common.h"
+
+#define NRF_LOG_MODULE_NAME ble_nus
+#if BLE_NUS_CONFIG_LOG_ENABLED
+#define NRF_LOG_LEVEL BLE_NUS_CONFIG_LOG_LEVEL
+#define NRF_LOG_INFO_COLOR BLE_NUS_CONFIG_INFO_COLOR
+#define NRF_LOG_DEBUG_COLOR BLE_NUS_CONFIG_DEBUG_COLOR
+#else // BLE_NUS_CONFIG_LOG_ENABLED
+#define NRF_LOG_LEVEL 0
+#endif // BLE_NUS_CONFIG_LOG_ENABLED
+#include "nrf_log.h"
+NRF_LOG_MODULE_REGISTER();
+
+
+#define BLE_UUID_NUS_TX_CHARACTERISTIC 0x0003 /**< The UUID of the TX Characteristic. */
+#define BLE_UUID_NUS_RX_CHARACTERISTIC 0x0002 /**< The UUID of the RX Characteristic. */
+
+#define BLE_NUS_MAX_RX_CHAR_LEN BLE_NUS_MAX_DATA_LEN /**< Maximum length of the RX Characteristic (in bytes). */
+#define BLE_NUS_MAX_TX_CHAR_LEN BLE_NUS_MAX_DATA_LEN /**< Maximum length of the TX Characteristic (in bytes). */
+
+#define NUS_BASE_UUID {{0x9E, 0xCA, 0xDC, 0x24, 0x0E, 0xE5, 0xA9, 0xE0, 0x93, 0xF3, 0xA3, 0xB5, 0x00, 0x00, 0x40, 0x6E}} /**< Used vendor specific UUID. */
+
+
+/**@brief Function for handling the @ref BLE_GAP_EVT_CONNECTED event from the SoftDevice.
+ *
+ * @param[in] p_nus Nordic UART Service structure.
+ * @param[in] p_ble_evt Pointer to the event received from BLE stack.
+ */
+static void on_connect(ble_nus_t * p_nus, ble_evt_t const * p_ble_evt)
+{
+ ret_code_t err_code;
+ ble_nus_evt_t evt;
+ ble_gatts_value_t gatts_val;
+ uint8_t cccd_value[2];
+ ble_nus_client_context_t * p_client = NULL;
+
+ err_code = blcm_link_ctx_get(p_nus->p_link_ctx_storage,
+ p_ble_evt->evt.gap_evt.conn_handle,
+ (void *) &p_client);
+ if (err_code != NRF_SUCCESS)
+ {
+ NRF_LOG_ERROR("Link context for 0x%02X connection handle could not be fetched.",
+ p_ble_evt->evt.gap_evt.conn_handle);
+ }
+
+ /* Check the hosts CCCD value to inform of readiness to send data using the RX characteristic */
+ memset(&gatts_val, 0, sizeof(ble_gatts_value_t));
+ gatts_val.p_value = cccd_value;
+ gatts_val.len = sizeof(cccd_value);
+ gatts_val.offset = 0;
+
+ err_code = sd_ble_gatts_value_get(p_ble_evt->evt.gap_evt.conn_handle,
+ p_nus->rx_handles.cccd_handle,
+ &gatts_val);
+
+ if ((err_code == NRF_SUCCESS) &&
+ (p_nus->data_handler != NULL) &&
+ ble_srv_is_notification_enabled(gatts_val.p_value))
+ {
+ if (p_client != NULL)
+ {
+ p_client->is_notification_enabled = true;
+ }
+
+ memset(&evt, 0, sizeof(ble_nus_evt_t));
+ evt.type = BLE_NUS_EVT_COMM_STARTED;
+ evt.p_nus = p_nus;
+ evt.conn_handle = p_ble_evt->evt.gap_evt.conn_handle;
+ evt.p_link_ctx = p_client;
+
+ p_nus->data_handler(&evt);
+ }
+}
+
+
+/**@brief Function for handling the @ref BLE_GATTS_EVT_WRITE event from the SoftDevice.
+ *
+ * @param[in] p_nus Nordic UART Service structure.
+ * @param[in] p_ble_evt Pointer to the event received from BLE stack.
+ */
+static void on_write(ble_nus_t * p_nus, ble_evt_t const * p_ble_evt)
+{
+ ret_code_t err_code;
+ ble_nus_evt_t evt;
+ ble_nus_client_context_t * p_client;
+ ble_gatts_evt_write_t const * p_evt_write = &p_ble_evt->evt.gatts_evt.params.write;
+
+ err_code = blcm_link_ctx_get(p_nus->p_link_ctx_storage,
+ p_ble_evt->evt.gatts_evt.conn_handle,
+ (void *) &p_client);
+ if (err_code != NRF_SUCCESS)
+ {
+ NRF_LOG_ERROR("Link context for 0x%02X connection handle could not be fetched.",
+ p_ble_evt->evt.gatts_evt.conn_handle);
+ }
+
+ memset(&evt, 0, sizeof(ble_nus_evt_t));
+ evt.p_nus = p_nus;
+ evt.conn_handle = p_ble_evt->evt.gatts_evt.conn_handle;
+ evt.p_link_ctx = p_client;
+
+ if ((p_evt_write->handle == p_nus->tx_handles.cccd_handle) &&
+ (p_evt_write->len == 2))
+ {
+ if (p_client != NULL)
+ {
+ if (ble_srv_is_notification_enabled(p_evt_write->data))
+ {
+ p_client->is_notification_enabled = true;
+ evt.type = BLE_NUS_EVT_COMM_STARTED;
+ }
+ else
+ {
+ p_client->is_notification_enabled = false;
+ evt.type = BLE_NUS_EVT_COMM_STOPPED;
+ }
+
+ if (p_nus->data_handler != NULL)
+ {
+ p_nus->data_handler(&evt);
+ }
+
+ }
+ }
+ else if ((p_evt_write->handle == p_nus->rx_handles.value_handle) &&
+ (p_nus->data_handler != NULL))
+ {
+ evt.type = BLE_NUS_EVT_RX_DATA;
+ evt.params.rx_data.p_data = p_evt_write->data;
+ evt.params.rx_data.length = p_evt_write->len;
+
+ p_nus->data_handler(&evt);
+ }
+ else
+ {
+ // Do Nothing. This event is not relevant for this service.
+ }
+}
+
+
+/**@brief Function for handling the @ref BLE_GATTS_EVT_HVN_TX_COMPLETE event from the SoftDevice.
+ *
+ * @param[in] p_nus Nordic UART Service structure.
+ * @param[in] p_ble_evt Pointer to the event received from BLE stack.
+ */
+static void on_hvx_tx_complete(ble_nus_t * p_nus, ble_evt_t const * p_ble_evt)
+{
+ ret_code_t err_code;
+ ble_nus_evt_t evt;
+ ble_nus_client_context_t * p_client;
+
+ err_code = blcm_link_ctx_get(p_nus->p_link_ctx_storage,
+ p_ble_evt->evt.gatts_evt.conn_handle,
+ (void *) &p_client);
+ if (err_code != NRF_SUCCESS)
+ {
+ NRF_LOG_ERROR("Link context for 0x%02X connection handle could not be fetched.",
+ p_ble_evt->evt.gatts_evt.conn_handle);
+ return;
+ }
+
+ if (p_client->is_notification_enabled)
+ {
+ memset(&evt, 0, sizeof(ble_nus_evt_t));
+ evt.type = BLE_NUS_EVT_TX_RDY;
+ evt.p_nus = p_nus;
+ evt.conn_handle = p_ble_evt->evt.gatts_evt.conn_handle;
+ evt.p_link_ctx = p_client;
+
+ p_nus->data_handler(&evt);
+ }
+}
+
+
+/**@brief Function for adding TX characteristic.
+ *
+ * @param[in] p_nus Nordic UART Service structure.
+ * @param[in] p_nus_init Information needed to initialize the service.
+ *
+ * @return NRF_SUCCESS on success, otherwise an error code.
+ */
+static uint32_t tx_char_add(ble_nus_t * p_nus, ble_nus_init_t const * p_nus_init)
+{
+ /**@snippet [Adding proprietary characteristic to the SoftDevice] */
+ ble_gatts_char_md_t char_md;
+ ble_gatts_attr_md_t cccd_md;
+ ble_gatts_attr_t attr_char_value;
+ ble_uuid_t ble_uuid;
+ ble_gatts_attr_md_t attr_md;
+
+ memset(&cccd_md, 0, sizeof(cccd_md));
+
+ BLE_GAP_CONN_SEC_MODE_SET_OPEN(&cccd_md.read_perm);
+ BLE_GAP_CONN_SEC_MODE_SET_OPEN(&cccd_md.write_perm);
+
+ cccd_md.vloc = BLE_GATTS_VLOC_STACK;
+
+ memset(&char_md, 0, sizeof(char_md));
+
+ char_md.char_props.notify = 1;
+ char_md.p_char_user_desc = NULL;
+ char_md.p_char_pf = NULL;
+ char_md.p_user_desc_md = NULL;
+ char_md.p_cccd_md = &cccd_md;
+ char_md.p_sccd_md = NULL;
+
+ ble_uuid.type = p_nus->uuid_type;
+ ble_uuid.uuid = BLE_UUID_NUS_TX_CHARACTERISTIC;
+
+ memset(&attr_md, 0, sizeof(attr_md));
+
+ BLE_GAP_CONN_SEC_MODE_SET_OPEN(&attr_md.read_perm);
+ BLE_GAP_CONN_SEC_MODE_SET_OPEN(&attr_md.write_perm);
+
+ attr_md.vloc = BLE_GATTS_VLOC_STACK;
+ attr_md.rd_auth = 0;
+ attr_md.wr_auth = 0;
+ attr_md.vlen = 1;
+
+ memset(&attr_char_value, 0, sizeof(attr_char_value));
+
+ attr_char_value.p_uuid = &ble_uuid;
+ attr_char_value.p_attr_md = &attr_md;
+ attr_char_value.init_len = sizeof(uint8_t);
+ attr_char_value.init_offs = 0;
+ attr_char_value.max_len = BLE_NUS_MAX_TX_CHAR_LEN;
+
+ return sd_ble_gatts_characteristic_add(p_nus->service_handle,
+ &char_md,
+ &attr_char_value,
+ &p_nus->tx_handles);
+ /**@snippet [Adding proprietary characteristic to the SoftDevice] */
+}
+
+
+/**@brief Function for adding RX characteristic.
+ *
+ * @param[in] p_nus Nordic UART Service structure.
+ * @param[in] p_nus_init Information needed to initialize the service.
+ *
+ * @return NRF_SUCCESS on success, otherwise an error code.
+ */
+static uint32_t rx_char_add(ble_nus_t * p_nus, const ble_nus_init_t * p_nus_init)
+{
+ ble_gatts_char_md_t char_md;
+ ble_gatts_attr_t attr_char_value;
+ ble_uuid_t ble_uuid;
+ ble_gatts_attr_md_t attr_md;
+
+ memset(&char_md, 0, sizeof(char_md));
+
+ char_md.char_props.write = 1;
+ char_md.char_props.write_wo_resp = 1;
+ char_md.p_char_user_desc = NULL;
+ char_md.p_char_pf = NULL;
+ char_md.p_user_desc_md = NULL;
+ char_md.p_cccd_md = NULL;
+ char_md.p_sccd_md = NULL;
+
+ ble_uuid.type = p_nus->uuid_type;
+ ble_uuid.uuid = BLE_UUID_NUS_RX_CHARACTERISTIC;
+
+ memset(&attr_md, 0, sizeof(attr_md));
+
+ BLE_GAP_CONN_SEC_MODE_SET_OPEN(&attr_md.read_perm);
+ BLE_GAP_CONN_SEC_MODE_SET_OPEN(&attr_md.write_perm);
+
+ attr_md.vloc = BLE_GATTS_VLOC_STACK;
+ attr_md.rd_auth = 0;
+ attr_md.wr_auth = 0;
+ attr_md.vlen = 1;
+
+ memset(&attr_char_value, 0, sizeof(attr_char_value));
+
+ attr_char_value.p_uuid = &ble_uuid;
+ attr_char_value.p_attr_md = &attr_md;
+ attr_char_value.init_len = 1;
+ attr_char_value.init_offs = 0;
+ attr_char_value.max_len = BLE_NUS_MAX_RX_CHAR_LEN;
+
+ return sd_ble_gatts_characteristic_add(p_nus->service_handle,
+ &char_md,
+ &attr_char_value,
+ &p_nus->rx_handles);
+}
+
+
+void ble_nus_on_ble_evt(ble_evt_t const * p_ble_evt, void * p_context)
+{
+ if ((p_context == NULL) || (p_ble_evt == NULL))
+ {
+ return;
+ }
+
+ ble_nus_t * p_nus = (ble_nus_t *)p_context;
+
+ switch (p_ble_evt->header.evt_id)
+ {
+ case BLE_GAP_EVT_CONNECTED:
+ on_connect(p_nus, p_ble_evt);
+ break;
+
+ case BLE_GATTS_EVT_WRITE:
+ on_write(p_nus, p_ble_evt);
+ break;
+
+ case BLE_GATTS_EVT_HVN_TX_COMPLETE:
+ on_hvx_tx_complete(p_nus, p_ble_evt);
+ break;
+
+ default:
+ // No implementation needed.
+ break;
+ }
+}
+
+
+uint32_t ble_nus_init(ble_nus_t * p_nus, ble_nus_init_t const * p_nus_init)
+{
+ ret_code_t err_code;
+ ble_uuid_t ble_uuid;
+ ble_uuid128_t nus_base_uuid = NUS_BASE_UUID;
+
+ VERIFY_PARAM_NOT_NULL(p_nus);
+ VERIFY_PARAM_NOT_NULL(p_nus_init);
+
+ // Initialize the service structure.
+ p_nus->data_handler = p_nus_init->data_handler;
+
+ /**@snippet [Adding proprietary Service to the SoftDevice] */
+ // Add a custom base UUID.
+ err_code = sd_ble_uuid_vs_add(&nus_base_uuid, &p_nus->uuid_type);
+ VERIFY_SUCCESS(err_code);
+
+ ble_uuid.type = p_nus->uuid_type;
+ ble_uuid.uuid = BLE_UUID_NUS_SERVICE;
+
+ // Add the service.
+ err_code = sd_ble_gatts_service_add(BLE_GATTS_SRVC_TYPE_PRIMARY,
+ &ble_uuid,
+ &p_nus->service_handle);
+ /**@snippet [Adding proprietary Service to the SoftDevice] */
+ VERIFY_SUCCESS(err_code);
+
+ // Add the RX Characteristic.
+ err_code = rx_char_add(p_nus, p_nus_init);
+ VERIFY_SUCCESS(err_code);
+
+ // Add the TX Characteristic.
+ err_code = tx_char_add(p_nus, p_nus_init);
+ VERIFY_SUCCESS(err_code);
+
+ return NRF_SUCCESS;
+}
+
+
+uint32_t ble_nus_data_send(ble_nus_t * p_nus,
+ uint8_t * p_data,
+ uint16_t * p_length,
+ uint16_t conn_handle)
+{
+ ret_code_t err_code;
+ ble_gatts_hvx_params_t hvx_params;
+ ble_nus_client_context_t * p_client;
+
+ VERIFY_PARAM_NOT_NULL(p_nus);
+
+ err_code = blcm_link_ctx_get(p_nus->p_link_ctx_storage, conn_handle, (void *) &p_client);
+ VERIFY_SUCCESS(err_code);
+
+ if ((conn_handle == BLE_CONN_HANDLE_INVALID) || (p_client == NULL))
+ {
+ return NRF_ERROR_NOT_FOUND;
+ }
+
+ if (!p_client->is_notification_enabled)
+ {
+ return NRF_ERROR_INVALID_STATE;
+ }
+
+ if (*p_length > BLE_NUS_MAX_DATA_LEN)
+ {
+ return NRF_ERROR_INVALID_PARAM;
+ }
+
+ memset(&hvx_params, 0, sizeof(hvx_params));
+
+ hvx_params.handle = p_nus->tx_handles.value_handle;
+ hvx_params.p_data = p_data;
+ hvx_params.p_len = p_length;
+ hvx_params.type = BLE_GATT_HVX_NOTIFICATION;
+
+ return sd_ble_gatts_hvx(conn_handle, &hvx_params);
+}
+
+
+#endif // NRF_MODULE_ENABLED(BLE_NUS)
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/ble_nus/ble_nus.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/ble_nus/ble_nus.h
new file mode 100644
index 0000000..5f17ac8
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/ble_nus/ble_nus.h
@@ -0,0 +1,244 @@
+ /**
+ * Copyright (c) 2012 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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
+ *
+ * @defgroup ble_nus Nordic UART Service
+ * @{
+ * @ingroup ble_sdk_srv
+ * @brief Nordic UART Service implementation.
+ *
+ * @details The Nordic UART Service is a simple GATT-based service with TX and RX characteristics.
+ * Data received from the peer is passed to the application, and the data received
+ * from the application of this service is sent to the peer as Handle Value
+ * Notifications. This module demonstrates how to implement a custom GATT-based
+ * service and characteristics using the SoftDevice. The service
+ * is used by the application to send and receive ASCII text strings to and from the
+ * peer.
+ *
+ * @note The application must register this module as BLE event observer using the
+ * NRF_SDH_BLE_OBSERVER macro. Example:
+ * @code
+ * ble_nus_t instance;
+ * NRF_SDH_BLE_OBSERVER(anything, BLE_NUS_BLE_OBSERVER_PRIO,
+ * ble_nus_on_ble_evt, &instance);
+ * @endcode
+ */
+#ifndef BLE_NUS_H__
+#define BLE_NUS_H__
+
+#include <stdint.h>
+#include <stdbool.h>
+#include "sdk_config.h"
+#include "ble.h"
+#include "ble_srv_common.h"
+#include "nrf_sdh_ble.h"
+#include "ble_link_ctx_manager.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**@brief Macro for defining a ble_nus instance.
+ *
+ * @param _name Name of the instance.
+ * @param[in] _nus_max_clients Maximum number of NUS clients connected at a time.
+ * @hideinitializer
+ */
+#define BLE_NUS_DEF(_name, _nus_max_clients) \
+ BLE_LINK_CTX_MANAGER_DEF(CONCAT_2(_name, _link_ctx_storage), \
+ (_nus_max_clients), \
+ sizeof(ble_nus_client_context_t)); \
+ static ble_nus_t _name = \
+ { \
+ .p_link_ctx_storage = &CONCAT_2(_name, _link_ctx_storage) \
+ }; \
+ NRF_SDH_BLE_OBSERVER(_name ## _obs, \
+ BLE_NUS_BLE_OBSERVER_PRIO, \
+ ble_nus_on_ble_evt, \
+ &_name)
+
+#define BLE_UUID_NUS_SERVICE 0x0001 /**< The UUID of the Nordic UART Service. */
+
+#define OPCODE_LENGTH 1
+#define HANDLE_LENGTH 2
+
+/**@brief Maximum length of data (in bytes) that can be transmitted to the peer by the Nordic UART service module. */
+#if defined(NRF_SDH_BLE_GATT_MAX_MTU_SIZE) && (NRF_SDH_BLE_GATT_MAX_MTU_SIZE != 0)
+ #define BLE_NUS_MAX_DATA_LEN (NRF_SDH_BLE_GATT_MAX_MTU_SIZE - OPCODE_LENGTH - HANDLE_LENGTH)
+#else
+ #define BLE_NUS_MAX_DATA_LEN (BLE_GATT_MTU_SIZE_DEFAULT - OPCODE_LENGTH - HANDLE_LENGTH)
+ #warning NRF_SDH_BLE_GATT_MAX_MTU_SIZE is not defined.
+#endif
+
+
+/**@brief Nordic UART Service event types. */
+typedef enum
+{
+ BLE_NUS_EVT_RX_DATA, /**< Data received. */
+ BLE_NUS_EVT_TX_RDY, /**< Service is ready to accept new data to be transmitted. */
+ BLE_NUS_EVT_COMM_STARTED, /**< Notification has been enabled. */
+ BLE_NUS_EVT_COMM_STOPPED, /**< Notification has been disabled. */
+} ble_nus_evt_type_t;
+
+
+/* Forward declaration of the ble_nus_t type. */
+typedef struct ble_nus_s ble_nus_t;
+
+
+/**@brief Nordic UART Service @ref BLE_NUS_EVT_RX_DATA event data.
+ *
+ * @details This structure is passed to an event when @ref BLE_NUS_EVT_RX_DATA occurs.
+ */
+typedef struct
+{
+ uint8_t const * p_data; /**< A pointer to the buffer with received data. */
+ uint16_t length; /**< Length of received data. */
+} ble_nus_evt_rx_data_t;
+
+
+/**@brief Nordic UART Service client context structure.
+ *
+ * @details This structure contains state context related to hosts.
+ */
+typedef struct
+{
+ bool is_notification_enabled; /**< Variable to indicate if the peer has enabled notification of the RX characteristic.*/
+} ble_nus_client_context_t;
+
+
+/**@brief Nordic UART Service event structure.
+ *
+ * @details This structure is passed to an event coming from service.
+ */
+typedef struct
+{
+ ble_nus_evt_type_t type; /**< Event type. */
+ ble_nus_t * p_nus; /**< A pointer to the instance. */
+ uint16_t conn_handle; /**< Connection handle. */
+ ble_nus_client_context_t * p_link_ctx; /**< A pointer to the link context. */
+ union
+ {
+ ble_nus_evt_rx_data_t rx_data; /**< @ref BLE_NUS_EVT_RX_DATA event data. */
+ } params;
+} ble_nus_evt_t;
+
+
+/**@brief Nordic UART Service event handler type. */
+typedef void (* ble_nus_data_handler_t) (ble_nus_evt_t * p_evt);
+
+
+/**@brief Nordic UART Service initialization structure.
+ *
+ * @details This structure contains the initialization information for the service. The application
+ * must fill this structure and pass it to the service using the @ref ble_nus_init
+ * function.
+ */
+typedef struct
+{
+ ble_nus_data_handler_t data_handler; /**< Event handler to be called for handling received data. */
+} ble_nus_init_t;
+
+
+/**@brief Nordic UART Service structure.
+ *
+ * @details This structure contains status information related to the service.
+ */
+struct ble_nus_s
+{
+ uint8_t uuid_type; /**< UUID type for Nordic UART Service Base UUID. */
+ uint16_t service_handle; /**< Handle of Nordic UART Service (as provided by the SoftDevice). */
+ ble_gatts_char_handles_t tx_handles; /**< Handles related to the TX characteristic (as provided by the SoftDevice). */
+ ble_gatts_char_handles_t rx_handles; /**< Handles related to the RX characteristic (as provided by the SoftDevice). */
+ blcm_link_ctx_storage_t * const p_link_ctx_storage; /**< Pointer to link context storage with handles of all current connections and its context. */
+ ble_nus_data_handler_t data_handler; /**< Event handler to be called for handling received data. */
+};
+
+
+/**@brief Function for initializing the Nordic UART Service.
+ *
+ * @param[out] p_nus Nordic UART Service structure. This structure must be supplied
+ * by the application. It is initialized by this function and will
+ * later be used to identify this particular service instance.
+ * @param[in] p_nus_init Information needed to initialize the service.
+ *
+ * @retval NRF_SUCCESS If the service was successfully initialized. Otherwise, an error code is returned.
+ * @retval NRF_ERROR_NULL If either of the pointers p_nus or p_nus_init is NULL.
+ */
+uint32_t ble_nus_init(ble_nus_t * p_nus, ble_nus_init_t const * p_nus_init);
+
+
+/**@brief Function for handling the Nordic UART Service's BLE events.
+ *
+ * @details The Nordic UART Service expects the application to call this function each time an
+ * event is received from the SoftDevice. This function processes the event if it
+ * is relevant and calls the Nordic UART Service event handler of the
+ * application if necessary.
+ *
+ * @param[in] p_ble_evt Event received from the SoftDevice.
+ * @param[in] p_context Nordic UART Service structure.
+ */
+void ble_nus_on_ble_evt(ble_evt_t const * p_ble_evt, void * p_context);
+
+
+/**@brief Function for sending a data to the peer.
+ *
+ * @details This function sends the input string as an RX characteristic notification to the
+ * peer.
+ *
+ * @param[in] p_nus Pointer to the Nordic UART Service structure.
+ * @param[in] p_data String to be sent.
+ * @param[in,out] p_length Pointer Length of the string. Amount of sent bytes.
+ * @param[in] conn_handle Connection Handle of the destination client.
+ *
+ * @retval NRF_SUCCESS If the string was sent successfully. Otherwise, an error code is returned.
+ */
+uint32_t ble_nus_data_send(ble_nus_t * p_nus,
+ uint8_t * p_data,
+ uint16_t * p_length,
+ uint16_t conn_handle);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // BLE_NUS_H__
+
+/** @} */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/ble_nus_c/ble_nus_c.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/ble_nus_c/ble_nus_c.c
new file mode 100644
index 0000000..ac27af7
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/ble_nus_c/ble_nus_c.c
@@ -0,0 +1,265 @@
+/**
+ * Copyright (c) 2012 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+
+#include "sdk_common.h"
+#if NRF_MODULE_ENABLED(BLE_NUS_C)
+#include <stdlib.h>
+
+#include "ble.h"
+#include "ble_nus_c.h"
+#include "ble_gattc.h"
+#include "ble_srv_common.h"
+#include "app_error.h"
+
+#define NRF_LOG_MODULE_NAME ble_nus
+#include "nrf_log.h"
+NRF_LOG_MODULE_REGISTER();
+
+void ble_nus_c_on_db_disc_evt(ble_nus_c_t * p_ble_nus_c, ble_db_discovery_evt_t * p_evt)
+{
+ ble_nus_c_evt_t nus_c_evt;
+ memset(&nus_c_evt,0,sizeof(ble_nus_c_evt_t));
+
+ ble_gatt_db_char_t * p_chars = p_evt->params.discovered_db.charateristics;
+
+ // Check if the NUS was discovered.
+ if ( (p_evt->evt_type == BLE_DB_DISCOVERY_COMPLETE)
+ && (p_evt->params.discovered_db.srv_uuid.uuid == BLE_UUID_NUS_SERVICE)
+ && (p_evt->params.discovered_db.srv_uuid.type == p_ble_nus_c->uuid_type))
+ {
+ for (uint32_t i = 0; i < p_evt->params.discovered_db.char_count; i++)
+ {
+ switch (p_chars[i].characteristic.uuid.uuid)
+ {
+ case BLE_UUID_NUS_RX_CHARACTERISTIC:
+ nus_c_evt.handles.nus_rx_handle = p_chars[i].characteristic.handle_value;
+ break;
+
+ case BLE_UUID_NUS_TX_CHARACTERISTIC:
+ nus_c_evt.handles.nus_tx_handle = p_chars[i].characteristic.handle_value;
+ nus_c_evt.handles.nus_tx_cccd_handle = p_chars[i].cccd_handle;
+ break;
+
+ default:
+ break;
+ }
+ }
+ if (p_ble_nus_c->evt_handler != NULL)
+ {
+ nus_c_evt.conn_handle = p_evt->conn_handle;
+ nus_c_evt.evt_type = BLE_NUS_C_EVT_DISCOVERY_COMPLETE;
+ p_ble_nus_c->evt_handler(p_ble_nus_c, &nus_c_evt);
+ }
+ }
+}
+
+/**@brief Function for handling Handle Value Notification received from the SoftDevice.
+ *
+ * @details This function will uses the Handle Value Notification received from the SoftDevice
+ * and checks if it is a notification of the NUS TX characteristic from the peer. If
+ * it is, this function will decode the data and send it to the
+ * application.
+ *
+ * @param[in] p_ble_nus_c Pointer to the NUS Client structure.
+ * @param[in] p_ble_evt Pointer to the BLE event received.
+ */
+static void on_hvx(ble_nus_c_t * p_ble_nus_c, ble_evt_t const * p_ble_evt)
+{
+ // HVX can only occur from client sending.
+ if ( (p_ble_nus_c->handles.nus_tx_handle != BLE_GATT_HANDLE_INVALID)
+ && (p_ble_evt->evt.gattc_evt.params.hvx.handle == p_ble_nus_c->handles.nus_tx_handle)
+ && (p_ble_nus_c->evt_handler != NULL))
+ {
+ ble_nus_c_evt_t ble_nus_c_evt;
+
+ ble_nus_c_evt.evt_type = BLE_NUS_C_EVT_NUS_TX_EVT;
+ ble_nus_c_evt.p_data = (uint8_t *)p_ble_evt->evt.gattc_evt.params.hvx.data;
+ ble_nus_c_evt.data_len = p_ble_evt->evt.gattc_evt.params.hvx.len;
+
+ p_ble_nus_c->evt_handler(p_ble_nus_c, &ble_nus_c_evt);
+ NRF_LOG_DEBUG("Client sending data.");
+ }
+}
+
+uint32_t ble_nus_c_init(ble_nus_c_t * p_ble_nus_c, ble_nus_c_init_t * p_ble_nus_c_init)
+{
+ uint32_t err_code;
+ ble_uuid_t uart_uuid;
+ ble_uuid128_t nus_base_uuid = NUS_BASE_UUID;
+
+ VERIFY_PARAM_NOT_NULL(p_ble_nus_c);
+ VERIFY_PARAM_NOT_NULL(p_ble_nus_c_init);
+
+ err_code = sd_ble_uuid_vs_add(&nus_base_uuid, &p_ble_nus_c->uuid_type);
+ VERIFY_SUCCESS(err_code);
+
+ uart_uuid.type = p_ble_nus_c->uuid_type;
+ uart_uuid.uuid = BLE_UUID_NUS_SERVICE;
+
+ p_ble_nus_c->conn_handle = BLE_CONN_HANDLE_INVALID;
+ p_ble_nus_c->evt_handler = p_ble_nus_c_init->evt_handler;
+ p_ble_nus_c->handles.nus_tx_handle = BLE_GATT_HANDLE_INVALID;
+ p_ble_nus_c->handles.nus_rx_handle = BLE_GATT_HANDLE_INVALID;
+
+ return ble_db_discovery_evt_register(&uart_uuid);
+}
+
+void ble_nus_c_on_ble_evt(ble_evt_t const * p_ble_evt, void * p_context)
+{
+ ble_nus_c_t * p_ble_nus_c = (ble_nus_c_t *)p_context;
+
+ if ((p_ble_nus_c == NULL) || (p_ble_evt == NULL))
+ {
+ return;
+ }
+
+ if ( (p_ble_nus_c->conn_handle != BLE_CONN_HANDLE_INVALID)
+ &&(p_ble_nus_c->conn_handle != p_ble_evt->evt.gap_evt.conn_handle)
+ )
+ {
+ return;
+ }
+
+ switch (p_ble_evt->header.evt_id)
+ {
+ case BLE_GATTC_EVT_HVX:
+ on_hvx(p_ble_nus_c, p_ble_evt);
+ break;
+
+ case BLE_GAP_EVT_DISCONNECTED:
+ if (p_ble_evt->evt.gap_evt.conn_handle == p_ble_nus_c->conn_handle
+ && p_ble_nus_c->evt_handler != NULL)
+ {
+ ble_nus_c_evt_t nus_c_evt;
+
+ nus_c_evt.evt_type = BLE_NUS_C_EVT_DISCONNECTED;
+
+ p_ble_nus_c->conn_handle = BLE_CONN_HANDLE_INVALID;
+ p_ble_nus_c->evt_handler(p_ble_nus_c, &nus_c_evt);
+ }
+ break;
+
+ default:
+ // No implementation needed.
+ break;
+ }
+}
+
+/**@brief Function for creating a message for writing to the CCCD. */
+static uint32_t cccd_configure(uint16_t conn_handle, uint16_t cccd_handle, bool enable)
+{
+ uint8_t buf[BLE_CCCD_VALUE_LEN];
+
+ buf[0] = enable ? BLE_GATT_HVX_NOTIFICATION : 0;
+ buf[1] = 0;
+
+ ble_gattc_write_params_t const write_params =
+ {
+ .write_op = BLE_GATT_OP_WRITE_REQ,
+ .flags = BLE_GATT_EXEC_WRITE_FLAG_PREPARED_WRITE,
+ .handle = cccd_handle,
+ .offset = 0,
+ .len = sizeof(buf),
+ .p_value = buf
+ };
+
+ return sd_ble_gattc_write(conn_handle, &write_params);
+}
+
+
+uint32_t ble_nus_c_tx_notif_enable(ble_nus_c_t * p_ble_nus_c)
+{
+ VERIFY_PARAM_NOT_NULL(p_ble_nus_c);
+
+ if ( (p_ble_nus_c->conn_handle == BLE_CONN_HANDLE_INVALID)
+ ||(p_ble_nus_c->handles.nus_tx_cccd_handle == BLE_GATT_HANDLE_INVALID)
+ )
+ {
+ return NRF_ERROR_INVALID_STATE;
+ }
+ return cccd_configure(p_ble_nus_c->conn_handle,p_ble_nus_c->handles.nus_tx_cccd_handle, true);
+}
+
+
+uint32_t ble_nus_c_string_send(ble_nus_c_t * p_ble_nus_c, uint8_t * p_string, uint16_t length)
+{
+ VERIFY_PARAM_NOT_NULL(p_ble_nus_c);
+
+ if (length > BLE_NUS_MAX_DATA_LEN)
+ {
+ NRF_LOG_WARNING("Content too long.");
+ return NRF_ERROR_INVALID_PARAM;
+ }
+ if (p_ble_nus_c->conn_handle == BLE_CONN_HANDLE_INVALID)
+ {
+ NRF_LOG_WARNING("Connection handle invalid.");
+ return NRF_ERROR_INVALID_STATE;
+ }
+
+ ble_gattc_write_params_t const write_params =
+ {
+ .write_op = BLE_GATT_OP_WRITE_CMD,
+ .flags = BLE_GATT_EXEC_WRITE_FLAG_PREPARED_WRITE,
+ .handle = p_ble_nus_c->handles.nus_rx_handle,
+ .offset = 0,
+ .len = length,
+ .p_value = p_string
+ };
+
+ return sd_ble_gattc_write(p_ble_nus_c->conn_handle, &write_params);
+}
+
+
+uint32_t ble_nus_c_handles_assign(ble_nus_c_t * p_ble_nus,
+ uint16_t conn_handle,
+ ble_nus_c_handles_t const * p_peer_handles)
+{
+ VERIFY_PARAM_NOT_NULL(p_ble_nus);
+
+ p_ble_nus->conn_handle = conn_handle;
+ if (p_peer_handles != NULL)
+ {
+ p_ble_nus->handles.nus_tx_cccd_handle = p_peer_handles->nus_tx_cccd_handle;
+ p_ble_nus->handles.nus_tx_handle = p_peer_handles->nus_tx_handle;
+ p_ble_nus->handles.nus_rx_handle = p_peer_handles->nus_rx_handle;
+ }
+ return NRF_SUCCESS;
+}
+#endif // NRF_MODULE_ENABLED(BLE_NUS_C)
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/ble_nus_c/ble_nus_c.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/ble_nus_c/ble_nus_c.h
new file mode 100644
index 0000000..1bdc182
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/ble_nus_c/ble_nus_c.h
@@ -0,0 +1,272 @@
+/**
+ * Copyright (c) 2012 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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
+ *
+ * @defgroup ble_nus_c Nordic UART Service Client
+ * @{
+ * @ingroup ble_sdk_srv
+ * @brief Nordic UART Service Client module.
+ *
+ * @details This module contains the APIs and types exposed by the Nordic UART Service Client
+ * module. These APIs and types can be used by the application to perform discovery of
+ * the Nordic UART Service at the peer and interact with it.
+ *
+ * @note The application must register this module as BLE event observer using the
+ * NRF_SDH_BLE_OBSERVER macro. Example:
+ * @code
+ * ble_nus_c_t instance;
+ * NRF_SDH_BLE_OBSERVER(anything, BLE_NUS_C_BLE_OBSERVER_PRIO,
+ * ble_nus_c_on_ble_evt, &instance);
+ * @endcode
+ *
+ */
+
+
+#ifndef BLE_NUS_C_H__
+#define BLE_NUS_C_H__
+
+#include <stdint.h>
+#include <stdbool.h>
+#include "ble.h"
+#include "ble_gatt.h"
+#include "ble_db_discovery.h"
+#include "nrf_sdh_ble.h"
+
+#include "sdk_config.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**@brief Macro for defining a ble_nus_c instance.
+ *
+ * @param _name Name of the instance.
+ * @hideinitializer
+ */
+#define BLE_NUS_C_DEF(_name) \
+static ble_nus_c_t _name; \
+NRF_SDH_BLE_OBSERVER(_name ## _obs, \
+ BLE_NUS_C_BLE_OBSERVER_PRIO, \
+ ble_nus_c_on_ble_evt, &_name)
+
+/** @brief Macro for defining multiple ble_nus_c instances.
+ *
+ * @param _name Name of the array of instances.
+ * @param _cnt Number of instances to define.
+ * @hideinitializer
+ */
+#define BLE_NUS_C_ARRAY_DEF(_name, _cnt) \
+static ble_nus_c_t _name[_cnt]; \
+NRF_SDH_BLE_OBSERVERS(_name ## _obs, \
+ BLE_NUS_C_BLE_OBSERVER_PRIO, \
+ ble_nus_c_on_ble_evt, &_name, _cnt)
+
+#define NUS_BASE_UUID {{0x9E, 0xCA, 0xDC, 0x24, 0x0E, 0xE5, 0xA9, 0xE0, 0x93, 0xF3, 0xA3, 0xB5, 0x00, 0x00, 0x40, 0x6E}} /**< Used vendor specific UUID. */
+
+#define BLE_UUID_NUS_SERVICE 0x0001 /**< The UUID of the Nordic UART Service. */
+#define BLE_UUID_NUS_RX_CHARACTERISTIC 0x0002 /**< The UUID of the RX Characteristic. */
+#define BLE_UUID_NUS_TX_CHARACTERISTIC 0x0003 /**< The UUID of the TX Characteristic. */
+
+#define OPCODE_LENGTH 1
+#define HANDLE_LENGTH 2
+
+/**@brief Maximum length of data (in bytes) that can be transmitted to the peer by the Nordic UART service module. */
+#if defined(NRF_SDH_BLE_GATT_MAX_MTU_SIZE) && (NRF_SDH_BLE_GATT_MAX_MTU_SIZE != 0)
+ #define BLE_NUS_MAX_DATA_LEN (NRF_SDH_BLE_GATT_MAX_MTU_SIZE - OPCODE_LENGTH - HANDLE_LENGTH)
+#else
+ #define BLE_NUS_MAX_DATA_LEN (BLE_GATT_MTU_SIZE_DEFAULT - OPCODE_LENGTH - HANDLE_LENGTH)
+ #warning NRF_SDH_BLE_GATT_MAX_MTU_SIZE is not defined.
+#endif
+
+
+/**@brief NUS Client event type. */
+typedef enum
+{
+ BLE_NUS_C_EVT_DISCOVERY_COMPLETE, /**< Event indicating that the NUS service and its characteristics was found. */
+ BLE_NUS_C_EVT_NUS_TX_EVT, /**< Event indicating that the central has received something from a peer. */
+ BLE_NUS_C_EVT_DISCONNECTED /**< Event indicating that the NUS server has disconnected. */
+} ble_nus_c_evt_type_t;
+
+/**@brief Handles on the connected peer device needed to interact with it. */
+typedef struct
+{
+ uint16_t nus_tx_handle; /**< Handle of the NUS TX characteristic as provided by a discovery. */
+ uint16_t nus_tx_cccd_handle; /**< Handle of the CCCD of the NUS TX characteristic as provided by a discovery. */
+ uint16_t nus_rx_handle; /**< Handle of the NUS RX characteristic as provided by a discovery. */
+} ble_nus_c_handles_t;
+
+/**@brief Structure containing the NUS event data received from the peer. */
+typedef struct
+{
+ ble_nus_c_evt_type_t evt_type;
+ uint16_t conn_handle;
+ uint16_t max_data_len;
+ uint8_t * p_data;
+ uint8_t data_len;
+ ble_nus_c_handles_t handles; /**< Handles on which the Nordic Uart service characteristics was discovered on the peer device. This will be filled if the evt_type is @ref BLE_NUS_C_EVT_DISCOVERY_COMPLETE.*/
+} ble_nus_c_evt_t;
+
+// Forward declaration of the ble_nus_t type.
+typedef struct ble_nus_c_s ble_nus_c_t;
+
+/**@brief Event handler type.
+ *
+ * @details This is the type of the event handler that should be provided by the application
+ * of this module to receive events.
+ */
+typedef void (* ble_nus_c_evt_handler_t)(ble_nus_c_t * p_ble_nus_c, ble_nus_c_evt_t const * p_evt);
+
+/**@brief NUS Client structure. */
+struct ble_nus_c_s
+{
+ uint8_t uuid_type; /**< UUID type. */
+ uint16_t conn_handle; /**< Handle of the current connection. Set with @ref ble_nus_c_handles_assign when connected. */
+ ble_nus_c_handles_t handles; /**< Handles on the connected peer device needed to interact with it. */
+ ble_nus_c_evt_handler_t evt_handler; /**< Application event handler to be called when there is an event related to the NUS. */
+};
+
+/**@brief NUS Client initialization structure. */
+typedef struct
+{
+ ble_nus_c_evt_handler_t evt_handler;
+} ble_nus_c_init_t;
+
+
+/**@brief Function for initializing the Nordic UART client module.
+ *
+ * @details This function registers with the Database Discovery module
+ * for the NUS. Doing so will make the Database Discovery
+ * module look for the presence of a NUS instance at the peer when a
+ * discovery is started.
+ *
+ * @param[in] p_ble_nus_c Pointer to the NUS client structure.
+ * @param[in] p_ble_nus_c_init Pointer to the NUS initialization structure containing the
+ * initialization information.
+ *
+ * @retval NRF_SUCCESS If the module was initialized successfully. Otherwise, an error
+ * code is returned. This function
+ * propagates the error code returned by the Database Discovery module API
+ * @ref ble_db_discovery_evt_register.
+ */
+uint32_t ble_nus_c_init(ble_nus_c_t * p_ble_nus_c, ble_nus_c_init_t * p_ble_nus_c_init);
+
+
+/**@brief Function for handling events from the database discovery module.
+ *
+ * @details This function will handle an event from the database discovery module, and determine
+ * if it relates to the discovery of NUS at the peer. If so, it will
+ * call the application's event handler indicating that NUS has been
+ * discovered at the peer. It also populates the event with the service related
+ * information before providing it to the application.
+ *
+ * @param[in] p_ble_nus_c Pointer to the NUS client structure.
+ * @param[in] p_evt Pointer to the event received from the database discovery module.
+ */
+ void ble_nus_c_on_db_disc_evt(ble_nus_c_t * p_ble_nus_c, ble_db_discovery_evt_t * p_evt);
+
+
+/**@brief Function for handling BLE events from the SoftDevice.
+ *
+ * @details This function handles the BLE events received from the SoftDevice. If a BLE
+ * event is relevant to the NUS module, it is used to update
+ * internal variables and, if necessary, send events to the application.
+ *
+ * @param[in] p_ble_evt Pointer to the BLE event.
+ * @param[in] p_context Pointer to the NUS client structure.
+ */
+void ble_nus_c_on_ble_evt(ble_evt_t const * p_ble_evt, void * p_context);
+
+
+/**@brief Function for requesting the peer to start sending notification of TX characteristic.
+ *
+ * @details This function enables notifications of the NUS TX characteristic at the peer
+ * by writing to the CCCD of the NUS TX characteristic.
+ *
+ * @param p_ble_nus_c Pointer to the NUS client structure.
+ *
+ * @retval NRF_SUCCESS If the SoftDevice has been requested to write to the CCCD of the peer.
+ * Otherwise, an error code is returned. This function propagates the error
+ * code returned by the SoftDevice API @ref sd_ble_gattc_write.
+ */
+uint32_t ble_nus_c_tx_notif_enable(ble_nus_c_t * p_ble_nus_c);
+
+
+/**@brief Function for sending a string to the server.
+ *
+ * @details This function writes the RX characteristic of the server.
+ *
+ * @param[in] p_ble_nus_c Pointer to the NUS client structure.
+ * @param[in] p_string String to be sent.
+ * @param[in] length Length of the string.
+ *
+ * @retval NRF_SUCCESS If the string was sent successfully. Otherwise, an error code is returned.
+ */
+uint32_t ble_nus_c_string_send(ble_nus_c_t * p_ble_nus_c, uint8_t * p_string, uint16_t length);
+
+
+/**@brief Function for assigning handles to a this instance of nus_c.
+ *
+ * @details Call this function when a link has been established with a peer to
+ * associate this link to this instance of the module. This makes it
+ * possible to handle several link and associate each link to a particular
+ * instance of this module. The connection handle and attribute handles will be
+ * provided from the discovery event @ref BLE_NUS_C_EVT_DISCOVERY_COMPLETE.
+ *
+ * @param[in] p_ble_nus_c Pointer to the NUS client structure instance to associate with these
+ * handles.
+ * @param[in] conn_handle Connection handle to associated with the given NUS Instance.
+ * @param[in] p_peer_handles Attribute handles on the NUS server that you want this NUS client to
+ * interact with.
+ *
+ * @retval NRF_SUCCESS If the operation was successful.
+ * @retval NRF_ERROR_NULL If a p_nus was a NULL pointer.
+ */
+uint32_t ble_nus_c_handles_assign(ble_nus_c_t * p_ble_nus_c,
+ uint16_t conn_handle,
+ ble_nus_c_handles_t const * p_peer_handles);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // BLE_NUS_C_H__
+
+/** @} */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/ble_rscs/ble_rscs.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/ble_rscs/ble_rscs.c
new file mode 100644
index 0000000..59fed13
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/ble_rscs/ble_rscs.c
@@ -0,0 +1,417 @@
+/**
+ * Copyright (c) 2012 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+/* Attention!
+ * To maintain compliance with Nordic Semiconductor ASA's Bluetooth profile
+ * qualification listings, this section of source code must not be modified.
+ */
+
+#include "sdk_common.h"
+
+#if NRF_MODULE_ENABLED(BLE_RSCS)
+
+#include "ble_rscs.h"
+#include <string.h>
+#include "ble.h"
+#include "ble_srv_common.h"
+
+#define OPCODE_LENGTH 1 /**< Length of opcode inside Running Speed and Cadence Measurement packet. */
+#define HANDLE_LENGTH 2 /**< Length of handle inside Running Speed and Cadence Measurement packet. */
+#define MAX_RSCM_LEN (BLE_GATT_ATT_MTU_DEFAULT - OPCODE_LENGTH - HANDLE_LENGTH) /**< Maximum size of a transmitted Running Speed and Cadence Measurement. */
+
+// Running Speed and Cadence Measurement flag bits
+#define RSC_MEAS_FLAG_INSTANT_STRIDE_LEN_PRESENT (0x01 << 0) /**< Instantaneous Stride Length Present flag bit. */
+#define RSC_MEAS_FLAG_TOTAL_DISTANCE_PRESENT (0x01 << 1) /**< Total Distance Present flag bit. */
+#define RSC_MEAS_FLAG_WALKING_OR_RUNNING_BIT (0x01 << 2) /**< Walking or Running Status flag bit. */
+
+
+/**@brief Function for handling the Connect event.
+ *
+ * @param[in] p_rscs Running Speed and Cadence Service structure.
+ * @param[in] p_ble_evt Event received from the BLE stack.
+ */
+static void on_connect(ble_rscs_t * p_rscs, ble_evt_t const * p_ble_evt)
+{
+ p_rscs->conn_handle = p_ble_evt->evt.gap_evt.conn_handle;
+}
+
+
+/**@brief Function for handling the Disconnect event.
+ *
+ * @param[in] p_rscs Running Speed and Cadence Service structure.
+ * @param[in] p_ble_evt Event received from the BLE stack.
+ */
+static void on_disconnect(ble_rscs_t * p_rscs, ble_evt_t const * p_ble_evt)
+{
+ UNUSED_PARAMETER(p_ble_evt);
+ p_rscs->conn_handle = BLE_CONN_HANDLE_INVALID;
+}
+
+
+/**@brief Function for handling the write events to the RSCS Measurement characteristic.
+ *
+ * @param[in] p_rscs Running Speed and Cadence Service structure.
+ * @param[in] p_evt_write Write event received from the BLE stack.
+ */
+static void on_meas_cccd_write(ble_rscs_t * p_rscs, ble_gatts_evt_write_t const * p_evt_write)
+{
+ if (p_evt_write->len == 2)
+ {
+ // CCCD written, update notification state
+ if (p_rscs->evt_handler != NULL)
+ {
+ ble_rscs_evt_t evt;
+
+ if (ble_srv_is_notification_enabled(p_evt_write->data))
+ {
+ evt.evt_type = BLE_RSCS_EVT_NOTIFICATION_ENABLED;
+ }
+ else
+ {
+ evt.evt_type = BLE_RSCS_EVT_NOTIFICATION_DISABLED;
+ }
+
+ p_rscs->evt_handler(p_rscs, &evt);
+ }
+ }
+}
+
+
+/**@brief Function for handling the Write event.
+ *
+ * @param[in] p_rscs Running Speed and Cadence Service structure.
+ * @param[in] p_ble_evt Event received from the BLE stack.
+ */
+static void on_write(ble_rscs_t * p_rscs, ble_evt_t const * p_ble_evt)
+{
+ ble_gatts_evt_write_t const * p_evt_write = &p_ble_evt->evt.gatts_evt.params.write;
+
+ if (p_evt_write->handle == p_rscs->meas_handles.cccd_handle)
+ {
+ on_meas_cccd_write(p_rscs, p_evt_write);
+ }
+}
+
+
+void ble_rscs_on_ble_evt(ble_evt_t const * p_ble_evt, void * p_context)
+{
+ if ((p_context == NULL) || (p_ble_evt == NULL))
+ {
+ return;
+ }
+
+ ble_rscs_t * p_rscs = (ble_rscs_t *)p_context;
+
+ switch (p_ble_evt->header.evt_id)
+ {
+ case BLE_GAP_EVT_CONNECTED:
+ on_connect(p_rscs, p_ble_evt);
+ break;
+
+ case BLE_GAP_EVT_DISCONNECTED:
+ on_disconnect(p_rscs, p_ble_evt);
+ break;
+
+ case BLE_GATTS_EVT_WRITE:
+ on_write(p_rscs, p_ble_evt);
+ break;
+
+ default:
+ // No implementation needed.
+ break;
+ }
+}
+
+
+/**@brief Function for encoding a RSCS Measurement.
+ *
+ * @param[in] p_rscs Running Speed and Cadence Service structure.
+ * @param[in] p_rsc_measurement Measurement to be encoded.
+ * @param[out] p_encoded_buffer Buffer where the encoded data will be written.
+ *
+ * @return Size of encoded data.
+ */
+static uint8_t rsc_measurement_encode(const ble_rscs_t * p_rscs,
+ const ble_rscs_meas_t * p_rsc_measurement,
+ uint8_t * p_encoded_buffer)
+{
+ uint8_t flags = 0;
+ uint8_t len = 1;
+
+ // Instantaneous speed field
+ len += uint16_encode(p_rsc_measurement->inst_speed, &p_encoded_buffer[len]);
+
+ // Instantaneous cadence field
+ p_encoded_buffer[len++] = p_rsc_measurement->inst_cadence;
+
+ // Instantaneous stride length field
+ if (p_rscs->feature & BLE_RSCS_FEATURE_INSTANT_STRIDE_LEN_BIT)
+ {
+ if (p_rsc_measurement->is_inst_stride_len_present)
+ {
+ flags |= RSC_MEAS_FLAG_INSTANT_STRIDE_LEN_PRESENT;
+ len += uint16_encode(p_rsc_measurement->inst_stride_length,
+ &p_encoded_buffer[len]);
+ }
+ }
+
+ // Total distance field
+ if (p_rscs->feature & BLE_RSCS_FEATURE_TOTAL_DISTANCE_BIT)
+ {
+ if (p_rsc_measurement->is_total_distance_present)
+ {
+ flags |= RSC_MEAS_FLAG_TOTAL_DISTANCE_PRESENT;
+ len += uint32_encode(p_rsc_measurement->total_distance, &p_encoded_buffer[len]);
+ }
+ }
+
+ // Flags field
+ if (p_rscs->feature & BLE_RSCS_FEATURE_WALKING_OR_RUNNING_STATUS_BIT)
+ {
+ if (p_rsc_measurement->is_running)
+ {
+ flags |= RSC_MEAS_FLAG_WALKING_OR_RUNNING_BIT;
+ }
+ }
+ p_encoded_buffer[0] = flags;
+
+ return len;
+}
+
+
+/**@brief Function for adding RSC Measurement characteristics.
+ *
+ * @param[in] p_rscs Running Speed and Cadence Service structure.
+ * @param[in] p_rscs_init Information needed to initialize the service.
+ *
+ * @return NRF_SUCCESS on success, otherwise an error code.
+ */
+static uint32_t rsc_measurement_char_add(ble_rscs_t * p_rscs, const ble_rscs_init_t * p_rscs_init)
+{
+ ble_gatts_char_md_t char_md;
+ ble_gatts_attr_md_t cccd_md;
+ ble_gatts_attr_t attr_char_value;
+ ble_uuid_t ble_uuid;
+ ble_gatts_attr_md_t attr_md;
+ uint8_t encoded_rcm[MAX_RSCM_LEN];
+
+ memset(&cccd_md, 0, sizeof(cccd_md));
+
+ BLE_GAP_CONN_SEC_MODE_SET_OPEN(&cccd_md.read_perm);
+ cccd_md.write_perm = p_rscs_init->rsc_meas_attr_md.cccd_write_perm;
+ cccd_md.vloc = BLE_GATTS_VLOC_STACK;
+
+ memset(&char_md, 0, sizeof(char_md));
+
+ char_md.char_props.notify = 1;
+ char_md.p_char_user_desc = NULL;
+ char_md.p_char_pf = NULL;
+ char_md.p_user_desc_md = NULL;
+ char_md.p_cccd_md = &cccd_md;
+ char_md.p_sccd_md = NULL;
+
+ BLE_UUID_BLE_ASSIGN(ble_uuid, BLE_UUID_RSC_MEASUREMENT_CHAR);
+ memset(&attr_md, 0, sizeof(attr_md));
+
+ attr_md.read_perm = p_rscs_init->rsc_meas_attr_md.read_perm;
+ attr_md.write_perm = p_rscs_init->rsc_meas_attr_md.write_perm;
+ attr_md.vloc = BLE_GATTS_VLOC_STACK;
+ attr_md.rd_auth = 0;
+ attr_md.wr_auth = 0;
+ attr_md.vlen = 1;
+
+ memset(&attr_char_value, 0, sizeof(attr_char_value));
+
+ attr_char_value.p_uuid = &ble_uuid;
+ attr_char_value.p_attr_md = &attr_md;
+ attr_char_value.init_len = rsc_measurement_encode(p_rscs, &p_rscs_init->initial_rcm, encoded_rcm);
+ attr_char_value.init_offs = 0;
+ attr_char_value.max_len = MAX_RSCM_LEN;
+ attr_char_value.p_value = encoded_rcm;
+
+ return sd_ble_gatts_characteristic_add(p_rscs->service_handle,
+ &char_md,
+ &attr_char_value,
+ &p_rscs->meas_handles);
+}
+
+
+/**@brief Function for adding RSC Feature characteristics.
+ *
+ * @param[in] p_rscs Running Speed and Cadence Service structure.
+ * @param[in] p_rscs_init Information needed to initialize the service.
+ *
+ * @return NRF_SUCCESS on success, otherwise an error code.
+ */
+static uint32_t rsc_feature_char_add(ble_rscs_t * p_rscs, const ble_rscs_init_t * p_rscs_init)
+{
+ ble_gatts_char_md_t char_md;
+ ble_gatts_attr_t attr_char_value;
+ ble_uuid_t ble_uuid;
+ ble_gatts_attr_md_t attr_md;
+ uint16_t init_value_feature;
+ uint8_t init_value_encoded[2];
+
+ memset(&char_md, 0, sizeof(char_md));
+
+ char_md.char_props.read = 1;
+ char_md.p_char_user_desc = NULL;
+ char_md.p_char_pf = NULL;
+ char_md.p_user_desc_md = NULL;
+ char_md.p_cccd_md = NULL;
+ char_md.p_sccd_md = NULL;
+
+ BLE_UUID_BLE_ASSIGN(ble_uuid, BLE_UUID_RSC_FEATURE_CHAR);
+
+ memset(&attr_md, 0, sizeof(attr_md));
+
+ attr_md.read_perm = p_rscs_init->rsc_feature_attr_md.read_perm;
+ attr_md.write_perm = p_rscs_init->rsc_feature_attr_md.write_perm;
+ attr_md.vloc = BLE_GATTS_VLOC_STACK;
+ attr_md.rd_auth = 0;
+ attr_md.wr_auth = 0;
+ attr_md.vlen = 0;
+
+ memset(&attr_char_value, 0, sizeof(attr_char_value));
+
+ init_value_feature = p_rscs_init->feature;
+ init_value_encoded[0] = init_value_feature & 0xFF;
+ init_value_encoded[1] = (init_value_feature >> 8) & 0xFF;
+
+ attr_char_value.p_uuid = &ble_uuid;
+ attr_char_value.p_attr_md = &attr_md;
+ attr_char_value.init_len = sizeof (uint16_t);
+ attr_char_value.init_offs = 0;
+ attr_char_value.max_len = sizeof (uint16_t);
+ attr_char_value.p_value = init_value_encoded;
+
+ return sd_ble_gatts_characteristic_add(p_rscs->service_handle,
+ &char_md,
+ &attr_char_value,
+ &p_rscs->feature_handles);
+}
+
+
+uint32_t ble_rscs_init(ble_rscs_t * p_rscs, const ble_rscs_init_t * p_rscs_init)
+{
+ if (p_rscs == NULL || p_rscs_init == NULL)
+ {
+ return NRF_ERROR_NULL;
+ }
+
+ uint32_t err_code;
+ ble_uuid_t ble_uuid;
+
+ // Initialize service structure
+ p_rscs->evt_handler = p_rscs_init->evt_handler;
+ p_rscs->conn_handle = BLE_CONN_HANDLE_INVALID;
+ p_rscs->feature = p_rscs_init->feature;
+
+ // Add service
+ BLE_UUID_BLE_ASSIGN(ble_uuid, BLE_UUID_RUNNING_SPEED_AND_CADENCE);
+
+ err_code = sd_ble_gatts_service_add(BLE_GATTS_SRVC_TYPE_PRIMARY,
+ &ble_uuid,
+ &p_rscs->service_handle);
+
+ if (err_code != NRF_SUCCESS)
+ {
+ return err_code;
+ }
+
+ // Add measurement characteristic
+ err_code = rsc_measurement_char_add(p_rscs, p_rscs_init);
+ if (err_code != NRF_SUCCESS)
+ {
+ return err_code;
+ }
+
+ // Add feature characteristic
+ err_code = rsc_feature_char_add(p_rscs, p_rscs_init);
+ if (err_code != NRF_SUCCESS)
+ {
+ return err_code;
+ }
+
+ return NRF_SUCCESS;
+}
+
+
+uint32_t ble_rscs_measurement_send(ble_rscs_t * p_rscs, ble_rscs_meas_t * p_measurement)
+{
+ if (p_rscs == NULL || p_measurement == NULL)
+ {
+ return NRF_ERROR_NULL;
+ }
+
+ uint32_t err_code;
+
+ // Send value if connected and notifying
+ if (p_rscs->conn_handle != BLE_CONN_HANDLE_INVALID)
+ {
+ uint8_t encoded_rsc_meas[MAX_RSCM_LEN];
+ uint16_t len;
+ uint16_t hvx_len;
+ ble_gatts_hvx_params_t hvx_params;
+
+ len = rsc_measurement_encode(p_rscs, p_measurement, encoded_rsc_meas);
+ hvx_len = len;
+
+ memset(&hvx_params, 0, sizeof(hvx_params));
+
+ hvx_params.handle = p_rscs->meas_handles.value_handle;
+ hvx_params.type = BLE_GATT_HVX_NOTIFICATION;
+ hvx_params.offset = 0;
+ hvx_params.p_len = &hvx_len;
+ hvx_params.p_data = encoded_rsc_meas;
+
+ err_code = sd_ble_gatts_hvx(p_rscs->conn_handle, &hvx_params);
+ if ((err_code == NRF_SUCCESS) && (hvx_len != len))
+ {
+ err_code = NRF_ERROR_DATA_SIZE;
+ }
+ }
+ else
+ {
+ err_code = NRF_ERROR_INVALID_STATE;
+ }
+
+ return err_code;
+}
+#endif // NRF_MODULE_ENABLED(BLE_RSCS)
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/ble_rscs/ble_rscs.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/ble_rscs/ble_rscs.h
new file mode 100644
index 0000000..18ca265
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/ble_rscs/ble_rscs.h
@@ -0,0 +1,201 @@
+/**
+ * Copyright (c) 2012 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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
+ *
+ * @defgroup ble_rscs Running Speed and Cadence Service
+ * @{
+ * @ingroup ble_sdk_srv
+ * @brief Running Speed and Cadence Service module.
+ *
+ * @details This module implements the Running Speed and Cadence Service. If enabled, notification
+ * of the Running Speead and Candence Measurement is performed when the application
+ * calls ble_rscs_measurement_send().
+ *
+ * If an event handler is supplied by the application, the Running Speed and Cadence
+ * Service will generate Running Speed and Cadence Service events to the application.
+ *
+ * @note The application must register this module as BLE event observer using the
+ * NRF_SDH_BLE_OBSERVER macro. Example:
+ * @code
+ * ble_rscs_t instance;
+ * NRF_SDH_BLE_OBSERVER(anything, BLE_RSCS_BLE_OBSERVER_PRIO,
+ * ble_rscs_on_ble_evt, &instance);
+ * @endcode
+ *
+ * @note Attention!
+ * To maintain compliance with Nordic Semiconductor ASA Bluetooth profile
+ * qualification listings, this section of source code must not be modified.
+ */
+
+#ifndef BLE_RSCS_H__
+#define BLE_RSCS_H__
+
+#include <stdint.h>
+#include <stdbool.h>
+#include "ble_srv_common.h"
+#include "nrf_sdh_ble.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**@brief Macro for defining a ble_rscs instance.
+ *
+ * @param _name Name of the instance.
+ * @hideinitializer
+ */
+#define BLE_RSCS_DEF(_name) \
+static ble_rscs_t _name; \
+NRF_SDH_BLE_OBSERVER(_name ## _obs, \
+ BLE_RSCS_BLE_OBSERVER_PRIO, \
+ ble_rscs_on_ble_evt, &_name)
+
+/**@brief Running Speed and Cadence Service feature bits. */
+#define BLE_RSCS_FEATURE_INSTANT_STRIDE_LEN_BIT (0x01 << 0) /**< Instantaneous Stride Length Measurement Supported bit. */
+#define BLE_RSCS_FEATURE_TOTAL_DISTANCE_BIT (0x01 << 1) /**< Total Distance Measurement Supported bit. */
+#define BLE_RSCS_FEATURE_WALKING_OR_RUNNING_STATUS_BIT (0x01 << 2) /**< Walking or Running Status Supported bit. */
+#define BLE_RSCS_FEATURE_CALIBRATION_PROCEDURE_BIT (0x01 << 3) /**< Calibration Procedure Supported bit. */
+#define BLE_RSCS_FEATURE_MULTIPLE_SENSORS_BIT (0x01 << 4) /**< Multiple Sensor Locations Supported bit. */
+
+
+/**@brief Running Speed and Cadence Service event type. */
+typedef enum
+{
+ BLE_RSCS_EVT_NOTIFICATION_ENABLED, /**< Running Speed and Cadence value notification enabled event. */
+ BLE_RSCS_EVT_NOTIFICATION_DISABLED /**< Running Speed and Cadence value notification disabled event. */
+} ble_rscs_evt_type_t;
+
+/**@brief Running Speed and Cadence Service event. */
+typedef struct
+{
+ ble_rscs_evt_type_t evt_type; /**< Type of event. */
+} ble_rscs_evt_t;
+
+// Forward declaration of the ble_rsc types.
+typedef struct ble_rscs_s ble_rscs_t;
+typedef struct ble_rscs_meas_s ble_rscs_meas_t;
+
+/**@brief Running Speed and Cadence Service event handler type. */
+typedef void (*ble_rscs_evt_handler_t) (ble_rscs_t * p_rscs, ble_rscs_evt_t * p_evt);
+
+/**@brief Running Speed and Cadence Service measurement structure. This contains a Running Speed and
+ * Cadence measurement.
+ */
+struct ble_rscs_meas_s
+{
+ bool is_inst_stride_len_present; /**< True if Instantaneous Stride Length is present in the measurement. */
+ bool is_total_distance_present; /**< True if Total Distance is present in the measurement. */
+ bool is_running; /**< True if running, False if walking. */
+ uint16_t inst_speed; /**< Instantaneous Speed. */
+ uint8_t inst_cadence; /**< Instantaneous Cadence. */
+ uint16_t inst_stride_length; /**< Instantaneous Stride Length. */
+ uint32_t total_distance; /**< Total Distance. */
+};
+
+/**@brief Running Speed and Cadence Service init structure. This contains all options and data
+ * needed for initialization of the service.
+ */
+typedef struct
+{
+ ble_rscs_evt_handler_t evt_handler; /**< Event handler to be called for handling events in the Running Speed and Cadence Service. */
+ ble_srv_cccd_security_mode_t rsc_meas_attr_md; /**< Initial security level for running speed and cadence measurement attribute */
+ ble_srv_security_mode_t rsc_feature_attr_md; /**< Initial security level for feature attribute */
+ uint16_t feature; /**< Initial value for features of sensor. */
+ ble_rscs_meas_t initial_rcm; /**< Initial Running Speed Cadence Measurement.*/
+} ble_rscs_init_t;
+
+/**@brief Running Speed and Cadence Service structure. This contains various status information for
+ * the service.
+ */
+struct ble_rscs_s
+{
+ ble_rscs_evt_handler_t evt_handler; /**< Event handler to be called for handling events in the Running Speed and Cadence Service. */
+ uint16_t service_handle; /**< Handle of Running Speed and Cadence Service (as provided by the BLE stack). */
+ ble_gatts_char_handles_t meas_handles; /**< Handles related to the Running Speed and Cadence Measurement characteristic. */
+ ble_gatts_char_handles_t feature_handles; /**< Handles related to the Running Speed and Cadence feature characteristic. */
+ uint16_t conn_handle; /**< Handle of the current connection (as provided by the BLE stack, is BLE_CONN_HANDLE_INVALID if not in a connection). */
+ uint16_t feature; /**< Bit mask of features available on sensor. */
+};
+
+
+/**@brief Function for initializing the Running Speed and Cadence Service.
+ *
+ * @param[out] p_rscs Running Speed and Cadence Service structure. This structure will have to
+ * be supplied by the application. It will be initialized by this function,
+ * and will later be used to identify this particular service instance.
+ * @param[in] p_rscs_init Information needed to initialize the service.
+ *
+ * @return NRF_SUCCESS on successful initialization of service, otherwise an error code.
+ */
+uint32_t ble_rscs_init(ble_rscs_t * p_rscs, const ble_rscs_init_t * p_rscs_init);
+
+
+/**@brief Function for handling the Application's BLE Stack events.
+ *
+ * @details Handles all events from the BLE stack of interest to the Running Speed and Cadence
+ * Service.
+ *
+ * @param[in] p_ble_evt Event received from the BLE stack.
+ * @param[in] p_context Running Speed and Cadence Service structure.
+ */
+void ble_rscs_on_ble_evt(ble_evt_t const * p_ble_evt, void * p_context);
+
+
+/**@brief Function for sending running speed and cadence measurement if notification has been enabled.
+ *
+ * @details The application calls this function after having performed a Running Speed and Cadence
+ * measurement. If notification has been enabled, the measurement data is encoded and sent
+ * to the client.
+ *
+ * @param[in] p_rscs Running Speed and Cadence Service structure.
+ * @param[in] p_measurement Pointer to new running speed and cadence measurement.
+ *
+ * @return NRF_SUCCESS on success, otherwise an error code.
+ */
+uint32_t ble_rscs_measurement_send(ble_rscs_t * p_rscs, ble_rscs_meas_t * p_measurement);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // BLE_RSCS_H__
+
+/** @} */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/ble_rscs_c/ble_rscs_c.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/ble_rscs_c/ble_rscs_c.c
new file mode 100644
index 0000000..f9c16ad
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/ble_rscs_c/ble_rscs_c.c
@@ -0,0 +1,390 @@
+/**
+ * Copyright (c) 2012 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+/**@cond To Make Doxygen skip documentation generation for this file.
+ * @{
+ */
+#include "sdk_common.h"
+#if NRF_MODULE_ENABLED(BLE_RSCS_C)
+#include "ble_rscs_c.h"
+#include "ble_db_discovery.h"
+#include "ble_types.h"
+#include "ble_srv_common.h"
+#include "ble_gattc.h"
+
+#define NRF_LOG_MODULE_NAME ble_rscs_c
+#include "nrf_log.h"
+NRF_LOG_MODULE_REGISTER();
+
+#define TX_BUFFER_MASK 0x07 /**< TX Buffer mask, must be a mask of continuous zeroes, followed by continuous sequence of ones: 000...111. */
+#define TX_BUFFER_SIZE (TX_BUFFER_MASK + 1) /**< Size of send buffer, which is 1 higher than the mask. */
+
+#define WRITE_MESSAGE_LENGTH BLE_CCCD_VALUE_LEN /**< Length of the write message for CCCD. */
+
+typedef enum
+{
+ READ_REQ, /**< Type identifying that this tx_message is a read request. */
+ WRITE_REQ /**< Type identifying that this tx_message is a write request. */
+} tx_request_t;
+
+/**@brief Structure for writing a message to the peer, i.e. CCCD.
+ */
+typedef struct
+{
+ uint8_t gattc_value[WRITE_MESSAGE_LENGTH]; /**< The message to write. */
+ ble_gattc_write_params_t gattc_params; /**< GATTC parameters for this message. */
+} write_params_t;
+
+/**@brief Structure for holding data to be transmitted to the connected central.
+ */
+typedef struct
+{
+ uint16_t conn_handle; /**< Connection handle to be used when transmitting this message. */
+ tx_request_t type; /**< Type of this message, i.e. read or write message. */
+ union
+ {
+ uint16_t read_handle; /**< Read request message. */
+ write_params_t write_req; /**< Write request message. */
+ } req;
+} tx_message_t;
+
+
+static tx_message_t m_tx_buffer[TX_BUFFER_SIZE]; /**< Transmit buffer for messages to be transmitted to the central. */
+static uint32_t m_tx_insert_index = 0; /**< Current index in the transmit buffer where the next message should be inserted. */
+static uint32_t m_tx_index = 0; /**< Current index in the transmit buffer from where the next message to be transmitted resides. */
+
+
+/**@brief Function for passing any pending request from the buffer to the stack.
+ */
+static void tx_buffer_process(void)
+{
+ if (m_tx_index != m_tx_insert_index)
+ {
+ uint32_t err_code;
+
+ if (m_tx_buffer[m_tx_index].type == READ_REQ)
+ {
+ err_code = sd_ble_gattc_read(m_tx_buffer[m_tx_index].conn_handle,
+ m_tx_buffer[m_tx_index].req.read_handle,
+ 0);
+ }
+ else
+ {
+ err_code = sd_ble_gattc_write(m_tx_buffer[m_tx_index].conn_handle,
+ &m_tx_buffer[m_tx_index].req.write_req.gattc_params);
+ }
+ if (err_code == NRF_SUCCESS)
+ {
+ NRF_LOG_DEBUG("SD Read/Write API returns Success.");
+ m_tx_index++;
+ m_tx_index &= TX_BUFFER_MASK;
+ }
+ else
+ {
+ NRF_LOG_DEBUG("SD Read/Write API returns error. This message sending will be "
+ "attempted again..");
+ }
+ }
+}
+
+
+/**@brief Function for handling write response events.
+ *
+ * @param[in] p_ble_rscs_c Pointer to the Running Speed and Cadence Client structure.
+ * @param[in] p_ble_evt Pointer to the BLE event received.
+ */
+static void on_write_rsp(ble_rscs_c_t * p_ble_rscs_c, const ble_evt_t * p_ble_evt)
+{
+ // Check if the event if on the link for this instance
+ if (p_ble_rscs_c->conn_handle != p_ble_evt->evt.gattc_evt.conn_handle)
+ {
+ return;
+ }
+ // Check if there is any message to be sent across to the peer and send it.
+ tx_buffer_process();
+}
+
+
+/**@brief Function for handling Handle Value Notification received from the SoftDevice.
+ *
+ * @details This function will uses the Handle Value Notification received from the SoftDevice
+ * and checks if it is a notification of the Running Speed and Cadence measurement from
+ * the peer. If it is, this function will decode the Running Speed measurement and send it
+ * to the application.
+ *
+ * @param[in] p_ble_rscs_c Pointer to the Running Speed and Cadence Client structure.
+ * @param[in] p_ble_evt Pointer to the BLE event received.
+ */
+static void on_hvx(ble_rscs_c_t * p_ble_rscs_c, const ble_evt_t * p_ble_evt)
+{
+ const ble_gattc_evt_hvx_t * p_notif = &p_ble_evt->evt.gattc_evt.params.hvx;
+
+ // Check if the event if on the link for this instance
+ if (p_ble_rscs_c->conn_handle != p_ble_evt->evt.gattc_evt.conn_handle)
+ {
+ return;
+ }
+
+ // Check if this is a Running Speed and Cadence notification.
+ if (p_ble_evt->evt.gattc_evt.params.hvx.handle == p_ble_rscs_c->peer_db.rsc_handle)
+ {
+ uint32_t index = 0;
+ ble_rscs_c_evt_t ble_rscs_c_evt;
+ ble_rscs_c_evt.evt_type = BLE_RSCS_C_EVT_RSC_NOTIFICATION;
+ ble_rscs_c_evt.conn_handle = p_ble_evt->evt.gattc_evt.conn_handle;
+
+ //lint -save -e415 -e416 -e662 "Access of out of bounds pointer" "Creation of out of bounds pointer"
+
+ // Flags field
+ ble_rscs_c_evt.params.rsc.is_inst_stride_len_present = p_notif->data[index] >> BLE_RSCS_INSTANT_STRIDE_LEN_PRESENT & 0x01;
+ ble_rscs_c_evt.params.rsc.is_total_distance_present = p_notif->data[index] >> BLE_RSCS_TOTAL_DISTANCE_PRESENT & 0x01;
+ ble_rscs_c_evt.params.rsc.is_running = p_notif->data[index] >> BLE_RSCS_WALKING_OR_RUNNING_STATUS_BIT & 0x01;
+ index++;
+
+ // Instantaneous Speed
+ ble_rscs_c_evt.params.rsc.inst_speed = uint16_decode(&p_notif->data[index]);
+ index += sizeof(uint16_t);
+
+ // Instantaneous Cadence
+ ble_rscs_c_evt.params.rsc.inst_cadence = p_notif->data[index];
+ index++;
+
+ // Instantaneous Stride Length
+ if (ble_rscs_c_evt.params.rsc.is_inst_stride_len_present == true)
+ {
+ ble_rscs_c_evt.params.rsc.inst_stride_length = uint16_decode(&p_notif->data[index]);
+ index += sizeof(uint16_t);
+ }
+
+ // Total distance field
+ if (ble_rscs_c_evt.params.rsc.is_total_distance_present == true)
+ {
+ ble_rscs_c_evt.params.rsc.total_distance = uint32_decode(&p_notif->data[index]);
+ //index += sizeof(uint32_t);
+ }
+
+ p_ble_rscs_c->evt_handler(p_ble_rscs_c, &ble_rscs_c_evt);
+
+ //lint -restore
+ }
+}
+
+
+/**@brief Function for handling events from the database discovery module.
+ *
+ * @details This function will handle an event from the database discovery module, and determine
+ * if it relates to the discovery of heart rate service at the peer. If so, it will
+ * call the application's event handler indicating that the Running Speed and Cadence
+ * service has been discovered at the peer. It also populates the event with the service
+ * related information before providing it to the application.
+ *
+ * @param[in] p_evt Pointer to the event received from the database discovery module.
+ *
+ */
+void ble_rscs_on_db_disc_evt(ble_rscs_c_t * p_ble_rscs_c, const ble_db_discovery_evt_t * p_evt)
+{
+ // Check if the Heart Rate Service was discovered.
+ if (p_evt->evt_type == BLE_DB_DISCOVERY_COMPLETE &&
+ p_evt->params.discovered_db.srv_uuid.uuid == BLE_UUID_RUNNING_SPEED_AND_CADENCE &&
+ p_evt->params.discovered_db.srv_uuid.type == BLE_UUID_TYPE_BLE)
+ {
+ ble_rscs_c_evt_t evt;
+ evt.conn_handle = p_evt->conn_handle;
+
+ // Find the CCCD Handle of the Running Speed and Cadence characteristic.
+ for (uint32_t i = 0; i < p_evt->params.discovered_db.char_count; i++)
+ {
+ if (p_evt->params.discovered_db.charateristics[i].characteristic.uuid.uuid ==
+ BLE_UUID_RSC_MEASUREMENT_CHAR)
+ {
+ // Found Running Speed and Cadence characteristic. Store CCCD handle and break.
+ evt.params.rscs_db.rsc_cccd_handle =
+ p_evt->params.discovered_db.charateristics[i].cccd_handle;
+ evt.params.rscs_db.rsc_handle =
+ p_evt->params.discovered_db.charateristics[i].characteristic.handle_value;
+ break;
+ }
+ }
+
+ NRF_LOG_DEBUG("Running Speed and Cadence Service discovered at peer.");
+
+ //If the instance has been assigned prior to db_discovery, assign the db_handles
+ if (p_ble_rscs_c->conn_handle != BLE_CONN_HANDLE_INVALID)
+ {
+ if ((p_ble_rscs_c->peer_db.rsc_cccd_handle == BLE_GATT_HANDLE_INVALID)&&
+ (p_ble_rscs_c->peer_db.rsc_handle == BLE_GATT_HANDLE_INVALID))
+ {
+ p_ble_rscs_c->peer_db = evt.params.rscs_db;
+ }
+ }
+
+ evt.evt_type = BLE_RSCS_C_EVT_DISCOVERY_COMPLETE;
+
+ p_ble_rscs_c->evt_handler(p_ble_rscs_c, &evt);
+ }
+}
+
+
+uint32_t ble_rscs_c_init(ble_rscs_c_t * p_ble_rscs_c, ble_rscs_c_init_t * p_ble_rscs_c_init)
+{
+ VERIFY_PARAM_NOT_NULL(p_ble_rscs_c);
+ VERIFY_PARAM_NOT_NULL(p_ble_rscs_c_init);
+
+ ble_uuid_t rscs_uuid;
+
+ rscs_uuid.type = BLE_UUID_TYPE_BLE;
+ rscs_uuid.uuid = BLE_UUID_RUNNING_SPEED_AND_CADENCE;
+
+ p_ble_rscs_c->evt_handler = p_ble_rscs_c_init->evt_handler;
+ p_ble_rscs_c->conn_handle = BLE_CONN_HANDLE_INVALID;
+ p_ble_rscs_c->peer_db.rsc_cccd_handle = BLE_GATT_HANDLE_INVALID;
+ p_ble_rscs_c->peer_db.rsc_handle = BLE_GATT_HANDLE_INVALID;
+
+ return ble_db_discovery_evt_register(&rscs_uuid);
+}
+
+
+uint32_t ble_rscs_c_handles_assign(ble_rscs_c_t * p_ble_rscs_c,
+ uint16_t conn_handle,
+ ble_rscs_c_db_t * p_peer_handles)
+{
+ VERIFY_PARAM_NOT_NULL(p_ble_rscs_c);
+ p_ble_rscs_c->conn_handle = conn_handle;
+ if (p_peer_handles != NULL)
+ {
+ p_ble_rscs_c->peer_db = *p_peer_handles;
+ }
+
+ return NRF_SUCCESS;
+}
+
+
+/**@brief Function for handling Disconnected event received from the SoftDevice.
+ *
+ * @details This function check if the disconnect event is happening on the link
+ * associated with the current instance of the module, if so it will set its
+ * conn_handle to invalid.
+ *
+ * @param[in] p_ble_rscs_c Pointer to the RSC Client structure.
+ * @param[in] p_ble_evt Pointer to the BLE event received.
+ */
+static void on_disconnected(ble_rscs_c_t * p_ble_rscs_c, const ble_evt_t * p_ble_evt)
+{
+ if (p_ble_rscs_c->conn_handle == p_ble_evt->evt.gap_evt.conn_handle)
+ {
+ p_ble_rscs_c->conn_handle = BLE_CONN_HANDLE_INVALID;
+ p_ble_rscs_c->peer_db.rsc_cccd_handle = BLE_GATT_HANDLE_INVALID;
+ p_ble_rscs_c->peer_db.rsc_handle = BLE_GATT_HANDLE_INVALID;
+ }
+}
+
+
+void ble_rscs_c_on_ble_evt(ble_evt_t const * p_ble_evt, void * p_context)
+{
+ if ((p_context == NULL) || (p_ble_evt == NULL))
+ {
+ return;
+ }
+
+ ble_rscs_c_t * p_ble_rscs_c = (ble_rscs_c_t *)p_context;
+
+ switch (p_ble_evt->header.evt_id)
+ {
+ case BLE_GATTC_EVT_HVX:
+ on_hvx(p_ble_rscs_c, p_ble_evt);
+ break;
+
+ case BLE_GATTC_EVT_WRITE_RSP:
+ on_write_rsp(p_ble_rscs_c, p_ble_evt);
+ break;
+
+ case BLE_GAP_EVT_DISCONNECTED:
+ on_disconnected(p_ble_rscs_c, p_ble_evt);
+ break;
+
+ default:
+ break;
+ }
+}
+
+
+/**@brief Function for creating a message for writing to the CCCD.
+ */
+static uint32_t cccd_configure(uint16_t conn_handle, uint16_t handle_cccd, bool enable)
+{
+ NRF_LOG_DEBUG("Configuring CCCD. CCCD Handle = %d, Connection Handle = %d",
+ handle_cccd, conn_handle);
+
+ tx_message_t * p_msg;
+ uint16_t cccd_val = enable ? BLE_GATT_HVX_NOTIFICATION : 0;
+
+ p_msg = &m_tx_buffer[m_tx_insert_index++];
+ m_tx_insert_index &= TX_BUFFER_MASK;
+
+ p_msg->req.write_req.gattc_params.handle = handle_cccd;
+ p_msg->req.write_req.gattc_params.len = WRITE_MESSAGE_LENGTH;
+ p_msg->req.write_req.gattc_params.p_value = p_msg->req.write_req.gattc_value;
+ p_msg->req.write_req.gattc_params.offset = 0;
+ p_msg->req.write_req.gattc_params.write_op = BLE_GATT_OP_WRITE_REQ;
+ p_msg->req.write_req.gattc_value[0] = LSB_16(cccd_val);
+ p_msg->req.write_req.gattc_value[1] = MSB_16(cccd_val);
+ p_msg->conn_handle = conn_handle;
+ p_msg->type = WRITE_REQ;
+
+ tx_buffer_process();
+ return NRF_SUCCESS;
+}
+
+
+uint32_t ble_rscs_c_rsc_notif_enable(ble_rscs_c_t * p_ble_rscs_c)
+{
+ VERIFY_PARAM_NOT_NULL(p_ble_rscs_c);
+
+ if (p_ble_rscs_c->conn_handle == BLE_CONN_HANDLE_INVALID)
+ {
+ return NRF_ERROR_INVALID_STATE;
+ }
+
+ return cccd_configure(p_ble_rscs_c->conn_handle, p_ble_rscs_c->peer_db.rsc_cccd_handle, true);
+}
+
+/** @}
+ * @endcond
+ */
+#endif // NRF_MODULE_ENABLED(BLE_RSCS_C)
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/ble_rscs_c/ble_rscs_c.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/ble_rscs_c/ble_rscs_c.h
new file mode 100644
index 0000000..664d03b
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/ble_rscs_c/ble_rscs_c.h
@@ -0,0 +1,231 @@
+/**
+ * Copyright (c) 2012 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+/**
+ * @defgroup ble_rscs_c Running Speed and Cadence Service Client
+ * @{
+ * @ingroup ble_sdk_srv
+ *
+ * @details This module contains the APIs and types exposed by the Running Speed and Cadence
+ * Service Client module. These APIs and types can be used by the application to perform
+ * discovery of Running Speed and Cadence Service at the peer and interact with it.
+ *
+ * @note The application must register this module as BLE event observer using the
+ * NRF_SDH_BLE_OBSERVER macro. Example:
+ * @code
+ * ble_rscs_c_t instance;
+ * NRF_SDH_BLE_OBSERVER(anything, BLE_RSCS_C_BLE_OBSERVER_PRIO,
+ * ble_rscs_c_on_ble_evt, &instance);
+ * @endcode
+ */
+#ifndef BLE_RSCS_C_H__
+#define BLE_RSCS_C_H__
+
+#include <stdint.h>
+#include <stdbool.h>
+#include "ble.h"
+#include "ble_db_discovery.h"
+#include "nrf_sdh_ble.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**@brief Macro for defining a ble_rscs_c instance.
+ *
+ * @param _name Name of the instance.
+ * @hideinitializer
+ */
+#define BLE_RSCS_C_DEF(_name) \
+static ble_rscs_c_t _name; \
+NRF_SDH_BLE_OBSERVER(_name ## _obs, \
+ BLE_RSCS_C_BLE_OBSERVER_PRIO, \
+ ble_rscs_c_on_ble_evt, &_name)
+
+/** @brief Macro for defining multiple ble_rscs_c instances.
+ *
+ * @param _name Name of the array of instances.
+ * @param _cnt Number of instances to define.
+ * @hideinitializer
+ */
+#define BLE_RSCS_C_ARRAY_DEF(_name, _cnt) \
+static ble_rscs_c_t _name[_cnt]; \
+NRF_SDH_BLE_OBSERVERS(_name ## _obs, \
+ BLE_RSCS_C_BLE_OBSERVER_PRIO, \
+ ble_rscs_c_on_ble_evt, &_name, _cnt)
+
+#define BLE_RSCS_INSTANT_STRIDE_LEN_PRESENT 0x00 /**< Instantaneous Stride Length Measurement Supported bit. */
+#define BLE_RSCS_TOTAL_DISTANCE_PRESENT 0x01 /**< Total Distance Measurement Supported bit. */
+#define BLE_RSCS_WALKING_OR_RUNNING_STATUS_BIT 0x02 /**< Walking or Running Status Supported bit. */
+
+
+/**@brief Structure containing the handles related to the Running Speed and Cadence Service found on the peer. */
+typedef struct
+{
+ uint16_t rsc_cccd_handle; /**< Handle of the CCCD of the Running Speed and Cadence characteristic. */
+ uint16_t rsc_handle; /**< Handle of the Running Speed and Cadence characteristic as provided by the SoftDevice. */
+} ble_rscs_c_db_t;
+
+/**@brief RSCS Client event type. */
+typedef enum
+{
+ BLE_RSCS_C_EVT_DISCOVERY_COMPLETE = 1, /**< Event indicating that the Running Speed and Cadence Service has been discovered at the peer. */
+ BLE_RSCS_C_EVT_RSC_NOTIFICATION /**< Event indicating that a notification of the Running Speed and Cadence measurement characteristic has been received from the peer. */
+} ble_rscs_c_evt_type_t;
+
+/**@brief Structure containing the Running Speed and Cadence measurement received from the peer. */
+typedef struct
+{
+ bool is_inst_stride_len_present; /**< True if Instantaneous Stride Length is present in the measurement. */
+ bool is_total_distance_present; /**< True if Total Distance is present in the measurement. */
+ bool is_running; /**< True if running, False if walking. */
+ uint16_t inst_speed; /**< Instantaneous Speed. */
+ uint8_t inst_cadence; /**< Instantaneous Cadence. */
+ uint16_t inst_stride_length; /**< Instantaneous Stride Length. */
+ uint32_t total_distance; /**< Total Distance. */
+} ble_rsc_t;
+
+/**@brief Running Speed and Cadence Event structure. */
+typedef struct
+{
+ ble_rscs_c_evt_type_t evt_type; /**< Type of the event. */
+ uint16_t conn_handle; /**< Connection handle on which the rscs_c event occured.*/
+ union
+ {
+ ble_rscs_c_db_t rscs_db; /**< Running Speed and Cadence Service related handles found on the peer device. This will be filled if the evt_type is @ref BLE_RSCS_C_EVT_DISCOVERY_COMPLETE.*/
+ ble_rsc_t rsc; /**< Running Speed and Cadence measurement received. This will be filled if the evt_type is @ref BLE_RSCS_C_EVT_RSC_NOTIFICATION. */
+ } params;
+} ble_rscs_c_evt_t;
+
+// Forward declaration of the ble_rscs_c_t type.
+typedef struct ble_rscs_c_s ble_rscs_c_t;
+
+/**@brief Event handler type.
+ *
+ * @details This is the type of the event handler that should be provided by the application
+ * of this module in order to receive events.
+ */
+typedef void (* ble_rscs_c_evt_handler_t) (ble_rscs_c_t * p_ble_rscs_c, ble_rscs_c_evt_t * p_evt);
+
+/**@brief Running Speed and Cadence client structure. */
+struct ble_rscs_c_s
+{
+ uint16_t conn_handle; /**< Connection handle as provided by the SoftDevice. */
+ ble_rscs_c_db_t peer_db; /**< Handles related to RSCS on the peer*/
+ ble_rscs_c_evt_handler_t evt_handler; /**< Application event handler to be called when there is an event related to the Running Speed and Cadence service. */
+};
+
+/**@brief Running Speed and Cadence client initialization structure. */
+typedef struct
+{
+ ble_rscs_c_evt_handler_t evt_handler; /**< Event handler to be called by the Running Speed and Cadence Client module whenever there is an event related to the Running Speed and Cadence Service. */
+} ble_rscs_c_init_t;
+
+
+/**@brief Function for initializing the Running Speed and Cadence Service Client module.
+ *
+ * @details This function will initialize the module and set up Database Discovery to discover
+ * the Running Speed and Cadence Service. After calling this function, call @ref ble_db_discovery_start
+ * to start discovery once a link with a peer has been established.
+ *
+ * @param[out] p_ble_rscs_c Pointer to the RSC Service client structure.
+ * @param[in] p_ble_rscs_c_init Pointer to the RSC Service initialization structure containing
+ * the initialization information.
+ *
+ * @retval NRF_SUCCESS Operation success.
+ * @retval NRF_ERROR_NULL A parameter is NULL.
+ * Otherwise, an error code returned by @ref ble_db_discovery_evt_register.
+ */
+uint32_t ble_rscs_c_init(ble_rscs_c_t * p_ble_rscs_c, ble_rscs_c_init_t * p_ble_rscs_c_init);
+
+
+/**@brief Function for handling the Application's BLE Stack events.
+ *
+ * @details Handles all events from the BLE stack of interest to the Running Speed and Cadence
+ * Service client.
+ *
+ * @param[in] p_ble_evt Event received from the BLE stack.
+ * @param[in] p_context Running Speed and Cadence Service client structure.
+ */
+void ble_rscs_c_on_ble_evt(ble_evt_t const * p_ble_evt, void * p_context);
+
+
+uint32_t ble_rscs_c_rsc_notif_enable(ble_rscs_c_t * p_ble_rscs_c);
+
+
+/**@brief Function for handling events from the database discovery module.
+ *
+ * @details Call this function when getting a callback event from the DB discovery modue.
+ * This function will handle an event from the database discovery module, and determine
+ * if it relates to the discovery of Running Speed and Cadence service at the peer.
+ * If so, it will call the application's event handler indicating that the RSC service has
+ * been discovered at the peer. It also populates the event with the service related
+ * information before providing it to the application.
+ *
+ * @param p_ble_rscs_c Pointer to the Runnind Speed and Cadence Service client structure.
+ * @param[in] p_evt Pointer to the event received from the database discovery module.
+ */
+void ble_rscs_on_db_disc_evt(ble_rscs_c_t * p_ble_rscs_c, ble_db_discovery_evt_t const * p_evt);
+
+
+/**@brief Function for assigning handles to a this instance of rscs_c.
+ *
+ * @details Call this function when a link has been established with a peer to
+ * associate this link to this instance of the module. This makes it
+ * possible to handle several link and associate each link to a particular
+ * instance of this module. The connection handle and attribute handles will be
+ * provided from the discovery event @ref BLE_RSCS_C_EVT_DISCOVERY_COMPLETE.
+ *
+ * @param[in] p_ble_rscs_c Pointer to the RSC client structure instance to associate.
+ * @param[in] conn_handle Connection handle to associated with the given RSCS Client Instance.
+ * @param[in] p_peer_handles Attribute handles on the RSCS server that you want this RSCS client
+ * to interact with.
+ */
+uint32_t ble_rscs_c_handles_assign(ble_rscs_c_t * p_ble_rscs_c,
+ uint16_t conn_handle,
+ ble_rscs_c_db_t * p_peer_handles);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // BLE_RSCS_C_H__
+
+/** @} */ // End tag for the file.
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/ble_tps/ble_tps.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/ble_tps/ble_tps.c
new file mode 100644
index 0000000..9f49541
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/ble_tps/ble_tps.c
@@ -0,0 +1,170 @@
+/**
+ * Copyright (c) 2012 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+/* Attention!
+ * To maintain compliance with Nordic Semiconductor ASA's Bluetooth profile
+ * qualification listings, this section of source code must not be modified.
+ */
+#include "sdk_common.h"
+#if NRF_MODULE_ENABLED(BLE_TPS)
+#include "ble_tps.h"
+#include <string.h>
+#include "ble_srv_common.h"
+
+
+/**@brief Function for handling the Connect event.
+ *
+ * @param[in] p_tps TX Power Service structure.
+ * @param[in] p_ble_evt Event received from the BLE stack.
+ */
+static void on_connect(ble_tps_t * p_tps, ble_evt_t const * p_ble_evt)
+{
+ p_tps->conn_handle = p_ble_evt->evt.gap_evt.conn_handle;
+}
+
+
+void ble_tps_on_ble_evt(ble_evt_t const * p_ble_evt, void * p_context)
+{
+ ble_tps_t * p_tps = (ble_tps_t *)p_context;
+
+ switch (p_ble_evt->header.evt_id)
+ {
+ case BLE_GAP_EVT_CONNECTED:
+ on_connect(p_tps, p_ble_evt);
+ break;
+
+ default:
+ // No implementation needed.
+ break;
+ }
+}
+
+
+/**@brief Function for adding TX Power Level characteristics.
+ *
+ * @param[in] p_tps TX Power Service structure.
+ * @param[in] p_tps_init Information needed to initialize the service.
+ *
+ * @return NRF_SUCCESS on success, otherwise an error code.
+ */
+static uint32_t tx_power_level_char_add(ble_tps_t * p_tps,
+ const ble_tps_init_t * p_tps_init)
+{
+ ble_gatts_char_md_t char_md;
+ ble_gatts_attr_t attr_char_value;
+ ble_uuid_t ble_uuid;
+ ble_gatts_attr_md_t attr_md;
+
+ memset(&char_md, 0, sizeof(char_md));
+
+ char_md.char_props.read = 1;
+ char_md.p_char_user_desc = NULL;
+ char_md.p_char_pf = NULL;
+ char_md.p_user_desc_md = NULL;
+ char_md.p_cccd_md = NULL;
+ char_md.p_sccd_md = NULL;
+
+ BLE_UUID_BLE_ASSIGN(ble_uuid, BLE_UUID_TX_POWER_LEVEL_CHAR);
+
+ memset(&attr_md, 0, sizeof(attr_md));
+
+ attr_md.read_perm = p_tps_init->tps_attr_md.read_perm;
+ attr_md.write_perm = p_tps_init->tps_attr_md.write_perm;
+ attr_md.vloc = BLE_GATTS_VLOC_STACK;
+ attr_md.rd_auth = 0;
+ attr_md.wr_auth = 0;
+ attr_md.vlen = 0;
+
+ memset(&attr_char_value, 0, sizeof(attr_char_value));
+
+ memset(&attr_char_value, 0, sizeof (attr_char_value));
+
+ attr_char_value.p_uuid = &ble_uuid;
+ attr_char_value.p_attr_md = &attr_md;
+ attr_char_value.init_len = sizeof (int8_t);
+ attr_char_value.init_offs = 0;
+ attr_char_value.max_len = sizeof (uint8_t);
+ attr_char_value.p_value = (uint8_t*)&p_tps_init->initial_tx_power_level;
+
+ return sd_ble_gatts_characteristic_add(p_tps->service_handle,
+ &char_md,
+ &attr_char_value,
+ &p_tps->tx_power_level_handles);
+}
+
+
+uint32_t ble_tps_init(ble_tps_t * p_tps, const ble_tps_init_t * p_tps_init)
+{
+ uint32_t err_code;
+ ble_uuid_t ble_uuid;
+
+ // Add service
+ BLE_UUID_BLE_ASSIGN(ble_uuid, BLE_UUID_TX_POWER_SERVICE);
+
+ err_code = sd_ble_gatts_service_add(BLE_GATTS_SRVC_TYPE_PRIMARY,
+ &ble_uuid,
+ &p_tps->service_handle);
+
+ if (err_code != NRF_SUCCESS)
+ {
+ return err_code;
+ }
+
+ // Add TX Power Level characteristic
+ return tx_power_level_char_add(p_tps, p_tps_init);
+}
+
+
+uint32_t ble_tps_tx_power_level_set(ble_tps_t * p_tps, int8_t tx_power_level)
+{
+ ble_gatts_value_t gatts_value;
+
+ // Initialize value struct.
+ memset(&gatts_value, 0, sizeof(gatts_value));
+
+ gatts_value.len = sizeof(uint8_t);
+ gatts_value.offset = 0;
+ gatts_value.p_value = (uint8_t*)&tx_power_level;
+
+ // Update database
+ return sd_ble_gatts_value_set(p_tps->conn_handle,
+ p_tps->tx_power_level_handles.value_handle,
+ &gatts_value);
+}
+#endif // NRF_MODULE_ENABLED(BLE_TPS)
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/ble_tps/ble_tps.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/ble_tps/ble_tps.h
new file mode 100644
index 0000000..1912179
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/ble_tps/ble_tps.h
@@ -0,0 +1,138 @@
+/**
+ * Copyright (c) 2012 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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
+ *
+ * @defgroup ble_tps TX Power Service
+ * @{
+ * @ingroup ble_sdk_srv
+ * @brief TX Power Service module.
+ *
+ * @details This module implements the TX Power Service with the TX Power Level characteristic.
+ * During initialization it adds the TX Power Service and TX Power Level characteristic
+ * with the specified initial value to the BLE stack database.
+ *
+ * It provides a function for letting the application update the TX Power Level
+ * characteristic.
+ *
+ * @note Attention!
+ * To maintain compliance with Nordic Semiconductor ASA Bluetooth profile
+ * qualification listings, this section of source code must not be modified.
+ */
+
+#ifndef BLE_TPS_H__
+#define BLE_TPS_H__
+
+#include <stdint.h>
+#include "ble.h"
+#include "ble_srv_common.h"
+#include "nrf_sdh_ble.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**@brief Macro for defining a ble_tps instance.
+ *
+ * @param _name Name of the instance.
+ * @hideinitializer
+ */
+#define BLE_TPS_DEF(_name) \
+static ble_tps_t _name; \
+NRF_SDH_BLE_OBSERVER(_name ## _obs, \
+ BLE_TPS_BLE_OBSERVER_PRIO, \
+ ble_tps_on_ble_evt, &_name)
+
+
+/**@brief TX Power Service init structure. This contains all options and data needed for
+ * initialization of the service. */
+typedef struct
+{
+ int8_t initial_tx_power_level; /**< Initial value of the TX Power Level characteristic (in dBm). */
+ ble_srv_security_mode_t tps_attr_md; /**< Initial Security Setting for TX Power Service Characteristics. */
+} ble_tps_init_t;
+
+/**@brief TX Power Service structure. This contains various status information for the service. */
+typedef struct
+{
+ uint16_t service_handle; /**< Handle of TX Power Service (as provided by the BLE stack). */
+ ble_gatts_char_handles_t tx_power_level_handles; /**< Handles related to the TX Power Level characteristic. */
+ uint16_t conn_handle; /**< Handle of the current connection (as provided by the BLE stack, is BLE_CONN_HANDLE_INVALID if not in a connection). */
+} ble_tps_t;
+
+
+/**@brief Function for initializing the TX Power Service.
+ *
+ * @param[out] p_hrs TX Power Service structure. This structure will have to be supplied by
+ * the application. It will be initialized by this function, and will later
+ * be used to identify this particular service instance.
+ * @param[in] p_tps_init Information needed to initialize the service.
+ *
+ * @return NRF_SUCCESS on successful initialization of service, otherwise an error code.
+ */
+uint32_t ble_tps_init(ble_tps_t * p_hrs, const ble_tps_init_t * p_tps_init);
+
+
+/**@brief Function for handling the Application's BLE Stack events.
+ *
+ * @details Handles all events from the BLE stack of interest to the TX Power Service.
+ *
+ * @param[in] p_ble_evt Event received from the BLE stack.
+ * @param[in] p_context TX Power Service structure.
+ */
+void ble_tps_on_ble_evt(ble_evt_t const * p_ble_evt, void * p_context);
+
+
+/**@brief Function for setting the value of the TX Power Level characteristic.
+ *
+ * @param[in] p_tps TX Power Service structure.
+ * @param[in] tx_power_level New TX Power Level (unit dBm, range -100 to 20).
+ *
+ * @return NRF_SUCCESS on success, otherwise an error code.
+ */
+uint32_t ble_tps_tx_power_level_set(ble_tps_t * p_tps, int8_t tx_power_level);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // BLE_TPS_H__
+
+/** @} */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/eddystone/es.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/eddystone/es.h
new file mode 100644
index 0000000..ce4221d
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/eddystone/es.h
@@ -0,0 +1,198 @@
+/**
+ * Copyright (c) 2016 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#ifndef ES_H__
+#define ES_H__
+
+#include <stdint.h>
+#include "app_util_platform.h"
+
+/**
+ * @file
+ *
+ * @defgroup eddystone_types Frame types and data formats
+ * @brief Definitions specific to Eddystone frame types and data formats.
+ * @ingroup eddystone
+ * @{
+ */
+
+/** @brief Swap 2 bytes.
+ */
+#define BYTES_SWAP_16BIT(x) (x << 8 | x >> 8)
+
+/** @brief Reverse 4 bytes.
+ */
+#define BYTES_REVERSE_32BIT(x) \
+ ((x << 24 | ((x << 8) & 0x00FF0000)) | (((x >> 8) & 0x0000FF00) | x >> 24))
+
+/** @brief Check if the error code is equal to NRF_SUCCESS. If it is not, return the error code.
+ */
+#define RETURN_IF_ERROR(PARAM) \
+ if ((PARAM) != NRF_SUCCESS) \
+ { \
+ return (PARAM); \
+ }
+
+#define ES_UUID 0xFEAA //!< UUID for Eddystone beacons according to specification.
+
+#define ES_UID_FRAME_TYPE 0x00 //!< UID frame type (fixed at 0x00).
+#define ES_UID_RFU 0x00, 0x00 //!< Reserved for future use according to specification.
+
+#define ES_URL_FRAME_TYPE 0x10 //!< URL frame type (fixed at 0x10).
+#define ES_URL_SCHEME 0x00 //!< URL prefix scheme according to specification (0x00 = "http://www").
+
+#define ES_TLM_FRAME_TYPE 0x20 //!< TLM frame type (fixed at 0x20).
+#define ES_EID_FRAME_TYPE 0x30 //!< EID frame type (fixed at 0x30).
+
+#define ES_FRAME_TYPE_LENGTH (1) //!< Length of a frame type field.
+
+#define ES_UID_LENGTH (20) //!< Length of a UID frame.
+#define ES_UID_NAMESPACE_LENGTH (10) //!< Length of a UID frame namespace field.
+#define ES_UID_INSTANCE_LENGTH (6) //!< Length of a UID frame instance field.
+#define ES_UID_RFU_LENGTH (2) //!< Length of a UID frame RFU field.
+
+#define ES_URL_LENGTH (20) //!< Length of a URL frame.
+#define ES_URL_URL_SCHEME_LENGTH (1) //!< Length of a URL frame URL scheme field.
+#define ES_URL_ENCODED_URL_LENGTH (17) //!< Maximum length of a URL frame encoded URL field.
+
+#define ES_TLM_LENGTH (14) //!< Length of a TLM frame.
+#define ES_TLM_VBATT_LENGTH (2) //!< Length of a TLM frame VBATT field.
+#define ES_TLM_TEMP_LENGTH (2) //!< Length of a TLM frame TEMP field.
+#define ES_TLM_ADV_CNT_LENGTH (4) //!< Length of a TLM frame ADV count field.
+#define ES_TLM_SEC_CNT_LENGTH (4) //!< Length of a TLM frame seconds field.
+
+#define ES_EID_LENGTH (10) //!< Length of an EID frame.
+#define ES_EID_ID_LENGTH (8) //!< Length of an EID frame ephemeral ID field.
+#define ES_EID_GATTS_READ_LENGTH (14)
+#define ES_EID_GATTS_READ_FRAME_TYPE_IDX (0)
+#define ES_EID_GATTS_READ_EXPONENT_IDX (1)
+#define ES_EID_GATTS_READ_CLCK_VALUE_IDX (2)
+#define ES_EID_GATTS_READ_EID_IDX (6)
+
+#define ES_ETLM_LENGTH (18) //!< Length of an eTLM frame.
+#define ES_ETLM_ECRYPTED_LENGTH (ES_TLM_VBATT_LENGTH + \
+ ES_TLM_TEMP_LENGTH + \
+ ES_TLM_ADV_CNT_LENGTH + \
+ ES_TLM_SEC_CNT_LENGTH) //!< Length of an eTLM frame encrypted TLM field.
+
+#define ES_ETLM_RFU (0x00) //!< eTLM frame RFU field value.
+#define ES_SPEC_VERSION_BYTE (0x00) //!< eTLM frame specification version field value.
+
+/** @brief Eddystone frame type values. These values are advertised as frame types. */
+typedef enum
+{
+ ES_FRAME_TYPE_UID = ES_UID_FRAME_TYPE, /**< UID frame type. */
+ ES_FRAME_TYPE_URL = ES_URL_FRAME_TYPE, /**< URL frame type. */
+ ES_FRAME_TYPE_TLM = ES_TLM_FRAME_TYPE, /**< TLM frame type. */
+ ES_FRAME_TYPE_EID = ES_EID_FRAME_TYPE /**< EID frame type. */
+} es_frame_type_t;
+
+/** @brief TLM version values. */
+typedef enum
+{
+ ES_TLM_VERSION_TLM = 0x00, /**< TLM. */
+ ES_TLM_VERSION_ETLM = 0x01 /**< Encrypted TLM (eTLM). */
+} es_tlm_version_t;
+
+/** @brief UID frame data representation.
+ * @note This is a packed structure. Therefore, you should not change it.
+ */
+typedef PACKED_STRUCT
+{
+ es_frame_type_t frame_type; //!< Frame type (see @ref es_frame_type_t).
+ int8_t ranging_data; //!< Calibrated TX power at 0 m.
+ int8_t namespace[ES_UID_NAMESPACE_LENGTH]; //!< UID namespace.
+ int8_t instance[ES_UID_INSTANCE_LENGTH]; //!< UID instance.
+ int8_t rfu[ES_UID_RFU_LENGTH]; //!< RFU.
+} es_uid_frame_t;
+
+
+/** @brief URL frame data representation.
+ * @note This is a packed structure. Therefore, you should not change it.
+*/
+typedef PACKED_STRUCT
+{
+ es_frame_type_t frame_type; //!< Frame type (see @ref es_frame_type_t).
+ int8_t ranging_data; //!< Calibrated TX power at 0 m.
+ uint8_t url_scheme; //!< URL scheme.
+ uint8_t encoded_url[ES_URL_ENCODED_URL_LENGTH]; //!< Encoded URL (variable length).
+} es_url_frame_t;
+
+
+/** @brief TLM frame data representation.
+ * @note This is a packed structure. Therefore, you should not change it.
+*/
+typedef PACKED_STRUCT
+{
+ es_frame_type_t frame_type; //!< Frame type (see @ref es_frame_type_t).
+ es_tlm_version_t version; //!< TLM version (see @ref es_tlm_version_t).
+ int8_t vbatt[ES_TLM_VBATT_LENGTH]; //!< Battery voltage (in 1 mV units).
+ int8_t temp[ES_TLM_TEMP_LENGTH]; //!< Beacon temperature.
+ int8_t adv_cnt[ES_TLM_ADV_CNT_LENGTH]; //!< Advertising PDU count.
+ int8_t sec_cnt[ES_TLM_SEC_CNT_LENGTH]; //!< Time since power-on or reboot.
+} es_tlm_frame_t;
+
+/** @brief EID frame data representation.
+ * @note This is a packed structure. Therefore, you should not change it.
+*/
+typedef PACKED_STRUCT
+{
+ es_frame_type_t frame_type; //!< Frame type (see @ref es_frame_type_t).
+ int8_t ranging_data; //!< Calibrated TX power at 0 m.
+ int8_t eid[ES_EID_ID_LENGTH]; //!< 8-byte ephemeral identifier.
+} es_eid_frame_t;
+
+
+/** @brief eTLM frame data representation.
+ * @note This is a packed structure. Therefore, you should not change it.
+*/
+typedef PACKED_STRUCT
+{
+ es_frame_type_t frame_type; //!< Frame type (see @ref es_frame_type_t).
+ es_tlm_version_t version; //!< TLM version (see @ref es_tlm_version_t).
+ int8_t encrypted_tlm[ES_ETLM_ECRYPTED_LENGTH]; //!< Encrypted TLM data.
+ int16_t random_salt; //!< Salt
+ int16_t msg_integrity_check; //!< Message integrity check.
+} es_etlm_frame_t;
+
+/**
+ * @}
+ */
+
+#endif // ES_H__
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/eddystone/es_adv.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/eddystone/es_adv.c
new file mode 100644
index 0000000..bf6913f
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/eddystone/es_adv.c
@@ -0,0 +1,342 @@
+/**
+ * Copyright (c) 2016 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#include "es_adv.h"
+#include "app_error.h"
+#include "es_adv_frame.h"
+#include "es_adv_timing.h"
+#include "es_tlm.h"
+#include "es_slot.h"
+
+static es_adv_evt_handler_t m_adv_evt_handler; //!< Eddystone advertisement event handler.
+static bool m_is_connected = false; //!< Is the Eddystone beacon in a connected state.
+static bool m_remain_connectable = false; //!< Should the Eddystone beacon remain connectable.
+static uint8_t m_ecs_uuid_type = 0; //!< UUID type of the Eddystone Configuration Service.
+static uint16_t m_adv_interval = APP_CFG_NON_CONN_ADV_INTERVAL_MS; //!< Current advertisement interval.
+
+static uint8_t m_enc_advdata[BLE_GAP_ADV_SET_DATA_SIZE_MAX]; //!< Buffer for storing an encoded advertising set.
+static uint8_t m_enc_scan_response_data[BLE_GAP_ADV_SET_DATA_SIZE_MAX]; //!< Buffer for storing an encoded scan data.
+static uint8_t *mp_adv_handle; //!< Pointer to the advertising handle.
+
+/**@brief Struct that contains pointers to the encoded advertising data. */
+static ble_gap_adv_data_t m_adv_data =
+{
+ .adv_data =
+ {
+ .p_data = m_enc_advdata,
+ .len = BLE_GAP_ADV_SET_DATA_SIZE_MAX
+ },
+ .scan_rsp_data =
+ {
+ .p_data = m_enc_scan_response_data,
+ .len = BLE_GAP_ADV_SET_DATA_SIZE_MAX
+
+ }
+};
+
+/**@brief Function for invoking registered callback.
+ *
+ * @param[in] evt Event to issue to callback.
+ */
+static void invoke_callback(es_adv_evt_t evt)
+{
+ if (m_adv_evt_handler != NULL)
+ {
+ m_adv_evt_handler(evt);
+ }
+}
+
+/**@brief Starting advertising.
+ * @param[in] p_adv_params Advertisement parameters to use.
+ */
+static void adv_start(ble_gap_adv_params_t * p_adv_params)
+{
+ ret_code_t err_code = NRF_SUCCESS;
+
+ es_tlm_adv_cnt_inc();
+
+ err_code = sd_ble_gap_adv_set_configure(mp_adv_handle, &m_adv_data, p_adv_params);
+ APP_ERROR_CHECK(err_code);
+
+ err_code = sd_ble_gap_adv_start(*mp_adv_handle, BLE_CONN_CFG_TAG_DEFAULT);
+
+ if (err_code != NRF_ERROR_BUSY && err_code != NRF_SUCCESS)
+ {
+ APP_ERROR_CHECK(err_code);
+ }
+}
+
+
+/**@brief Given state of Eddystone beacon, get advertisement parameters. */
+static void get_adv_params(ble_gap_adv_params_t * p_adv_params,
+ bool non_connectable,
+ bool remain_connectable)
+{
+ // Initialize advertising parameters (used when starting advertising).
+ memset(p_adv_params, 0, sizeof(ble_gap_adv_params_t));
+
+ // Non-connectable
+ p_adv_params->properties.type = non_connectable
+ ? BLE_GAP_ADV_TYPE_NONCONNECTABLE_NONSCANNABLE_UNDIRECTED
+ : BLE_GAP_ADV_TYPE_CONNECTABLE_SCANNABLE_UNDIRECTED;
+ p_adv_params->p_peer_addr = NULL; // Undirected advertisement.
+ p_adv_params->filter_policy = BLE_GAP_ADV_FP_ANY;
+ p_adv_params->interval = non_connectable ? BLE_GAP_ADV_INTERVAL_MAX : 1000;
+ p_adv_params->duration = non_connectable
+ ? APP_CFG_NON_CONN_ADV_TIMEOUT
+ : (remain_connectable ? 0 : APP_CFG_CONNECTABLE_ADV_TIMEOUT);
+ p_adv_params->primary_phy = BLE_GAP_PHY_1MBPS;
+}
+
+
+/**@brief Update advertisement data and start connectable advertisements. */
+static void connectable_adv_start(void)
+{
+ ble_gap_adv_params_t connectable_adv_params;
+ ble_advdata_t scrsp_data;
+ ble_uuid_t scrp_uuids[] = {{BLE_UUID_ESCS_SERVICE, m_ecs_uuid_type}};
+
+ memset(&scrsp_data, 0, sizeof(scrsp_data));
+ scrsp_data.name_type = BLE_ADVDATA_FULL_NAME;
+ scrsp_data.include_appearance = false;
+ scrsp_data.uuids_complete.uuid_cnt = sizeof(scrp_uuids) / sizeof(scrp_uuids[0]);
+ scrsp_data.uuids_complete.p_uuids = scrp_uuids;
+
+ m_adv_data.scan_rsp_data.p_data = m_enc_scan_response_data;
+ m_adv_data.scan_rsp_data.len = BLE_GAP_ADV_SET_DATA_SIZE_MAX;
+
+ // As the data to be written does not depend on the slot_no, we can safely send
+ es_adv_frame_fill_connectable_adv_data(&scrsp_data, &m_adv_data);
+
+ get_adv_params(&connectable_adv_params, false, m_remain_connectable);
+ adv_start(&connectable_adv_params);
+
+ invoke_callback(ES_ADV_EVT_CONNECTABLE_ADV_STARTED);
+}
+
+
+static void adv_stop(void)
+{
+ ret_code_t err_code;
+
+ err_code = sd_ble_gap_adv_stop(*mp_adv_handle);
+ if (err_code != NRF_ERROR_INVALID_STATE)
+ {
+ APP_ERROR_CHECK(err_code);
+ }
+
+ es_adv_timing_stop();
+}
+
+
+static void adv_restart(void)
+{
+ if (!m_remain_connectable)
+ {
+ es_adv_start_non_connctable_adv();
+ }
+
+ else
+ {
+ connectable_adv_start();
+ }
+}
+
+
+/**@brief Function handling events from @ref es_adv_timing.c.
+ *
+ * @param[in] p_evt Advertisement timing event.
+ */
+static void adv_timing_callback(const es_adv_timing_evt_t * p_evt)
+{
+ ret_code_t err_code;
+ ble_gap_adv_params_t non_connectable_adv_params;
+ const es_slot_reg_t * p_reg = es_slot_get_registry();
+
+ // As new advertisement data will be loaded, stop advertising.
+ err_code = sd_ble_gap_adv_stop(*mp_adv_handle);
+ if (err_code != NRF_ERROR_INVALID_STATE && err_code != BLE_ERROR_INVALID_ADV_HANDLE)
+ {
+ APP_ERROR_CHECK(err_code);
+ }
+
+ // If a non-eTLM frame is to be advertised.
+ if (p_evt->evt_id == ES_ADV_TIMING_EVT_ADV_SLOT)
+ {
+ err_code = sd_ble_gap_tx_power_set(BLE_GAP_TX_POWER_ROLE_ADV, 0, p_reg->slots[p_evt->slot_no].radio_tx_pwr);
+ if (err_code != BLE_ERROR_INVALID_ADV_HANDLE)
+ {
+ APP_ERROR_CHECK(err_code);
+ }
+ es_adv_frame_fill_non_connectable_adv_data(p_evt->slot_no, false, &m_adv_data);
+ }
+
+ // If an eTLM frame is to be advertised
+ else if (p_evt->evt_id == ES_ADV_TIMING_EVT_ADV_ETLM)
+ {
+ err_code = sd_ble_gap_tx_power_set(BLE_GAP_TX_POWER_ROLE_ADV, 0, p_reg->slots[p_reg->tlm_slot].radio_tx_pwr);
+ APP_ERROR_CHECK(err_code);
+
+ es_adv_frame_fill_non_connectable_adv_data(p_evt->slot_no, true, &m_adv_data);
+ }
+
+ invoke_callback(ES_ADV_EVT_NON_CONN_ADV);
+
+ get_adv_params(&non_connectable_adv_params, true, m_remain_connectable);
+ adv_start(&non_connectable_adv_params);
+}
+
+
+void es_adv_start_connectable_adv(void)
+{
+ if (!m_is_connected)
+ {
+ adv_stop();
+
+ connectable_adv_start();
+ }
+}
+
+
+void es_adv_start_non_connctable_adv(void)
+{
+ es_adv_timing_start(m_adv_interval);
+}
+
+
+void es_adv_remain_connectable_set(bool remain_connectable)
+{
+ m_remain_connectable = remain_connectable;
+}
+
+
+bool es_adv_remain_connectable_get(void)
+{
+ return m_remain_connectable;
+}
+
+
+void es_adv_on_ble_evt(ble_evt_t const * p_ble_evt)
+{
+ switch (p_ble_evt->header.evt_id)
+ {
+ case BLE_GAP_EVT_CONNECTED:
+ m_is_connected = true;
+
+ // The beacon must provide these advertisements for the client to see updated values
+ // during the connection.
+ es_adv_start_non_connctable_adv();
+ break;
+
+ case BLE_GAP_EVT_DISCONNECTED:
+ m_is_connected = false;
+
+ // Stop all advertising to give some time for writing to flash.
+ adv_stop();
+ adv_restart();
+ break;
+
+ case BLE_GAP_EVT_ADV_SET_TERMINATED:
+ if (p_ble_evt->evt.gap_evt.params.adv_set_terminated.reason == BLE_GAP_EVT_ADV_SET_TERMINATED_REASON_TIMEOUT &&
+ !m_is_connected)
+ {
+ invoke_callback(ES_ADV_EVT_CONNECTABLE_ADV_STOPPED);
+
+ adv_restart();
+ }
+ break;
+
+ default:
+ break;
+ }
+}
+
+
+void es_adv_interval_set(nrf_ble_escs_adv_interval_t interval)
+{
+ const es_slot_reg_t * p_reg = es_slot_get_registry();
+ uint16_t min_valid_adv_interval;
+
+ bool eTLM_required = (p_reg->num_configured_eid_slots > 0) && (p_reg->tlm_configured);
+
+ min_valid_adv_interval = eTLM_required ? \
+ p_reg->num_configured_slots * (APP_CONFIG_ADV_FRAME_SPACING_MS_MIN + \
+ APP_CONFIG_ADV_FRAME_ETLM_SPACING_MS) \
+ : \
+ p_reg->num_configured_slots * APP_CONFIG_ADV_FRAME_SPACING_MS_MIN;
+
+ m_adv_interval = (interval > min_valid_adv_interval) ? interval : min_valid_adv_interval;
+
+#ifdef APP_CONFIG_ADV_INTERVAL_MS_MAX
+ if (m_adv_interval > APP_CONFIG_ADV_INTERVAL_MS_MAX)
+ {
+ m_adv_interval = APP_CONFIG_ADV_INTERVAL_MS_MAX;
+ }
+#endif // APP_CONFIG_ADV_INTERVAL_MS_MAX
+}
+
+
+nrf_ble_escs_adv_interval_t es_adv_interval_get(void)
+{
+ return m_adv_interval;
+}
+
+
+void es_adv_init(uint8_t ecs_uuid_type,
+ es_adv_evt_handler_t adv_event_handler,
+ nrf_ble_escs_adv_interval_t adv_interval,
+ bool remain_connectable,
+ uint8_t * const p_adv_handle)
+{
+ m_ecs_uuid_type = ecs_uuid_type;
+ m_adv_evt_handler = adv_event_handler;
+ m_is_connected = false;
+ m_remain_connectable = remain_connectable;
+ m_adv_interval = adv_interval;
+ mp_adv_handle = p_adv_handle;
+
+ es_tlm_init();
+
+ es_adv_timing_init(adv_timing_callback);
+}
+
+void es_adv_timers_init(void)
+{
+ es_adv_timing_timers_init();
+}
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/eddystone/es_adv.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/eddystone/es_adv.h
new file mode 100644
index 0000000..bb0177c
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/eddystone/es_adv.h
@@ -0,0 +1,129 @@
+/**
+ * Copyright (c) 2016 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#ifndef ES_ADV_H__
+#define ES_ADV_H__
+
+#include "nrf_ble_escs.h"
+
+/**
+ * @file
+ * @defgroup eddystone_adv Eddystone advertising module
+ * @brief Types and functions for handling advertising in Eddystone beacons.
+ * @ingroup eddystone
+ * @{
+ */
+
+/** @brief Eddystone Advertiser events. */
+typedef enum
+{
+ ES_ADV_EVT_NON_CONN_ADV,
+ ES_ADV_EVT_CONNECTABLE_ADV_STARTED,
+ ES_ADV_EVT_CONNECTABLE_ADV_STOPPED,
+} es_adv_evt_t;
+
+/** @brief Eddystone Advertiser event handler. */
+typedef void (*es_adv_evt_handler_t)(es_adv_evt_t evt);
+
+/** @brief Function for initializing the module.
+ *
+ * @param[in] ecs_uuid_type ECS UUID type used for advertising the Eddystone Configuration Service UUID.
+ * @param[in] adv_event_handler Eddystone advertiser event handler.
+ * @param[in] adv_interval Advertisement interval to use.
+ * @param[in] remain_connectable Flag that specifies if advertisements should remain connectable.
+ * @param[in] p_adv_handle Pointer to the advertising handle used to start and stop advertising.
+ */
+void es_adv_init(uint8_t ecs_uuid_type,
+ es_adv_evt_handler_t adv_event_handler,
+ nrf_ble_escs_adv_interval_t adv_interval,
+ bool remain_connectable,
+ uint8_t * const p_adv_handle);
+
+/** @brief Function for passing BLE events to this module.
+ *
+ * @param[in] p_ble_evt Pointer to the BLE evt.
+ */
+void es_adv_on_ble_evt(ble_evt_t const * p_ble_evt);
+
+/** @brief Function for starting the advertisements.
+ */
+void es_adv_start_non_connctable_adv(void);
+
+/** @brief Function for specifying if the beacon should remain connectable.
+ *
+ * @param[in] remain_connectable Value to be set.
+ */
+void es_adv_remain_connectable_set(bool remain_connectable);
+
+/** @brief Function for starting connectable advertisements.
+ */
+void es_adv_start_connectable_adv(void);
+
+/** @brief Function for setting the base advertisement interval for non-connectable advertisements.
+ *
+ * The minimum allowed advertisement interval is calculated based on the configured minimum advertisement
+ * frame spacings and the number of configured slots. If eTLM slots are configured a separate minimum
+ * advertisement frame spacing is used for those. If @p interval is outside of range, the closest valid value
+ * is set.
+ *
+ * @param interval The new advertisement interval.
+ */
+void es_adv_interval_set(nrf_ble_escs_adv_interval_t interval);
+
+/** @brief Function for getting a pointer to the current advertisement interval.
+ *
+ * @retval Pointer to the current advertisement interval.
+ */
+nrf_ble_escs_adv_interval_t es_adv_interval_get(void);
+
+/** @brief Function for getting the value of the 'remain_connectable' field.
+ *
+ * @retval Value of 'remain_connectable'.
+ */
+bool es_adv_remain_connectable_get(void);
+
+/** @brief Function for initializing the Eddystone advertisement timers.
+ */
+void es_adv_timers_init(void);
+
+/**
+ * @}
+ */
+
+#endif // ES_ADV_H__
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/eddystone/es_adv_frame.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/eddystone/es_adv_frame.c
new file mode 100644
index 0000000..0333c43
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/eddystone/es_adv_frame.c
@@ -0,0 +1,120 @@
+/**
+ * Copyright (c) 2016 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#include "es_adv_frame.h"
+#include "es_slot.h"
+
+
+/**@brief Function for setting advertisement data, using 'ble_advdata_encode'.
+ *
+ * @param[in] p_scrsp_data Scan response data.
+ * @param[in] p_es_data_array Eddystone service data array.
+ */
+static void fill_adv_data(ble_advdata_t * p_scrsp_data, uint8_array_t * p_es_data_array, ble_gap_adv_data_t * const p_adv_data)
+{
+ ble_advdata_t adv_data;
+ ret_code_t err_code;
+ ble_uuid_t adv_uuids[] = {{ES_UUID, BLE_UUID_TYPE_BLE}};
+ uint8_array_t es_data_array = {0};
+
+ ble_advdata_service_data_t service_data; // Structure to hold Service Data.
+
+ service_data.service_uuid = APP_ES_UUID; // Eddystone UUID to allow discoverability on iOS devices.
+
+ service_data.data = (p_es_data_array != NULL) ? *p_es_data_array : es_data_array;
+
+ // Build and set advertising data.
+ memset(&adv_data, 0, sizeof(ble_advdata_t));
+
+ adv_data.name_type = BLE_ADVDATA_NO_NAME;
+ adv_data.flags = BLE_GAP_ADV_FLAGS_LE_ONLY_GENERAL_DISC_MODE;
+ adv_data.uuids_complete.uuid_cnt = sizeof(adv_uuids) / sizeof(adv_uuids[0]);
+ adv_data.uuids_complete.p_uuids = adv_uuids;
+ adv_data.p_service_data_array = &service_data;
+ adv_data.service_data_count = (p_es_data_array != NULL) ? 1 : 0;
+
+ err_code = ble_advdata_encode(&adv_data,
+ p_adv_data->adv_data.p_data,
+ &p_adv_data->adv_data.len);
+ APP_ERROR_CHECK(err_code);
+ if (p_scrsp_data != NULL)
+ {
+ err_code = ble_advdata_encode(p_scrsp_data,
+ p_adv_data->scan_rsp_data.p_data,
+ &p_adv_data->scan_rsp_data.len);
+ APP_ERROR_CHECK(err_code);
+ }
+ else
+ {
+ p_adv_data->scan_rsp_data.p_data = NULL;
+ p_adv_data->scan_rsp_data.len = 0;
+ }
+}
+
+
+void es_adv_frame_fill_connectable_adv_data(ble_advdata_t * p_scrsp_data, ble_gap_adv_data_t * const p_adv_data)
+{
+ fill_adv_data(p_scrsp_data, NULL, p_adv_data);
+}
+
+
+void es_adv_frame_fill_non_connectable_adv_data(uint8_t slot_no, bool etlm, ble_gap_adv_data_t * const p_adv_data)
+{
+ uint8_array_t es_data_array = {0};
+ const es_slot_reg_t * p_reg = es_slot_get_registry();
+
+ if (etlm)
+ {
+ es_slot_etlm_update(slot_no);
+
+ // If eTLM, the incoming slot_no points to the corresponding EID slot, update to point to TLM slot.
+ slot_no = p_reg->tlm_slot;
+ }
+
+ // If TLM, update the TLM data.
+ else if (p_reg->slots[slot_no].adv_frame.type == ES_FRAME_TYPE_TLM)
+ {
+ es_slot_tlm_update();
+ }
+
+ es_data_array.p_data = (uint8_t *)&p_reg->slots[slot_no].adv_frame.frame;
+ es_data_array.size = p_reg->slots[slot_no].adv_frame.length;
+
+ fill_adv_data(NULL, &es_data_array, p_adv_data);
+}
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/eddystone/es_adv_frame.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/eddystone/es_adv_frame.h
new file mode 100644
index 0000000..0facf5d
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/eddystone/es_adv_frame.h
@@ -0,0 +1,73 @@
+/**
+ * Copyright (c) 2016 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#ifndef ES_ADV_FRAME_H__
+#define ES_ADV_FRAME_H__
+
+#include <stdint.h>
+#include "ble_advdata.h"
+
+/**
+ * @file
+ * @addtogroup eddystone_adv
+ * @{
+ */
+
+/**@brief Function for setting up connectable advertisement data using @ref
+ * ble_advdata_encode.
+ *
+ * @param[in] p_scrsp_data Pointer to the scan response data that will be encoded.
+ * @param[in,out] p_adv_data Pointer to the encoded advertising data (including scan response).
+ */
+void es_adv_frame_fill_connectable_adv_data(ble_advdata_t * p_scrsp_data, ble_gap_adv_data_t * const p_adv_data);
+
+/**@brief Function for setting up non-connectable advertisement data using @ref
+ * ble_advdata_encode.
+ *
+ * @param[in] slot_no Slot to fill in data for.
+ * @param[in] etlm Flag that specifies if Eddystone-TLM is required.
+ * @param[in,out] p_adv_data Pointer to the encoded advertising data (including scan response).
+ */
+void es_adv_frame_fill_non_connectable_adv_data(uint8_t slot_no, bool etlm, ble_gap_adv_data_t * const p_adv_data);
+
+/**
+ * @}
+ */
+
+#endif // ES_ADV_FRAME_H__
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/eddystone/es_adv_timing.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/eddystone/es_adv_timing.c
new file mode 100644
index 0000000..d575ba8
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/eddystone/es_adv_timing.c
@@ -0,0 +1,220 @@
+/**
+ * Copyright (c) 2016 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#include "app_timer.h"
+#include "es_adv_timing.h"
+#include "es_adv_timing_resolver.h"
+#include "es_slot.h"
+
+
+APP_TIMER_DEF(m_es_adv_interval_timer); //!< Timer for advertising the set of slots.
+APP_TIMER_DEF(m_es_slot_timer); //!< Timer for advertising individual slots.
+
+static nrf_ble_escs_adv_interval_t m_current_adv_interval; //!< Current advertisement interval.
+static es_adv_timing_callback_t m_timing_mgr_callback; //!< Registered callback.
+static es_adv_timing_resolver_result_t m_adv_timing_result; //!< Current advertising timing result.
+static bool m_non_conn_adv_active; //!< Is the beacon advertising non-conn advertisements?
+
+/**@brief Function for invoking registered callback.
+ *
+ * @param[in] p_evt Event to issue to callback.
+ */
+static void invoke_callback(const es_adv_timing_evt_t * p_evt)
+{
+ if (m_timing_mgr_callback != NULL && m_non_conn_adv_active)
+ {
+ m_timing_mgr_callback(p_evt);
+ }
+}
+
+
+#if APP_CONFIG_TLM_ADV_INTERLEAVE_RATIO > 1
+static bool frame_to_adv_is_tlm(const es_adv_timing_evt_t * p_evt)
+{
+ const es_slot_reg_t * p_reg = es_slot_get_registry();
+
+ return (p_reg->tlm_configured &&
+ (p_evt->slot_no == p_reg->tlm_slot || p_evt->evt_id == ES_ADV_TIMING_EVT_ADV_ETLM));
+}
+
+
+static bool tlm_should_be_advertised(uint32_t adv_event_cnt)
+{
+ return (adv_event_cnt % APP_CONFIG_TLM_ADV_INTERLEAVE_RATIO) == 0;
+}
+#endif // APP_CONFIG_TLM_ADV_INTERLEAVE_RATIO > 1
+
+
+/**@brief Timeout handler for the advertisement slot timer. */
+static void adv_slot_timeout(void * p_context)
+{
+
+ ret_code_t err_code;
+ uint32_t active_slot_index = (uint32_t)p_context;
+
+ es_adv_timing_evt_t evt;
+
+ evt.slot_no = m_adv_timing_result.timing_results[active_slot_index].slot_no;
+
+ evt.evt_id = m_adv_timing_result.timing_results[active_slot_index].is_etlm
+ ? ES_ADV_TIMING_EVT_ADV_ETLM
+ : ES_ADV_TIMING_EVT_ADV_SLOT;
+
+ // Trigger an event for the next slot if this slot is not the last to be advertised in this event.
+ // Note: since we check 'm_adv_timing_result.len_timing_results > 1' we can safely cast the result of
+ // the subtraction to a uint32.
+ if (m_non_conn_adv_active && \
+ m_adv_timing_result.len_timing_results > 1 && \
+ active_slot_index < (uint32_t)(m_adv_timing_result.len_timing_results - 1))
+ {
+ err_code = app_timer_start( m_es_slot_timer,
+ APP_TIMER_TICKS(m_adv_timing_result.timing_results[active_slot_index].delay_ms),
+ (void*)(active_slot_index + 1));
+ APP_ERROR_CHECK(err_code);
+ }
+
+#if APP_CONFIG_TLM_ADV_INTERLEAVE_RATIO > 1
+ static uint32_t adv_event_cnt = 0;
+
+ if (active_slot_index == 0)
+ {
+ adv_event_cnt++;
+ }
+
+ if (frame_to_adv_is_tlm(&evt) && !tlm_should_be_advertised(adv_event_cnt))
+ {
+ return;
+ }
+#endif // APP_CONFIG_TLM_ADV_INTERLEAVE_RATIO > 1
+
+ invoke_callback(&evt);
+}
+
+
+/**@brief Timeout handler for the advertisement interval timer. */
+static void adv_interval_timeout(void * p_context)
+{
+ if (es_slot_get_registry()->num_configured_slots > 0)
+ {
+ // Trigger slot timeout for advertising the first slot.
+ // Note: The slot number is not the index in the slot registry, it is the index of the active slots.
+ adv_slot_timeout(NULL);
+ }
+
+ if (m_non_conn_adv_active)
+ {
+ uint32_t err_code = app_timer_start(m_es_adv_interval_timer,
+ APP_TIMER_TICKS(m_current_adv_interval),
+ NULL);
+ APP_ERROR_CHECK(err_code);
+ }
+}
+
+
+void es_adv_timing_timers_init(void)
+{
+ ret_code_t err_code;
+
+ err_code = app_timer_create(&m_es_adv_interval_timer,
+ APP_TIMER_MODE_SINGLE_SHOT,
+ adv_interval_timeout);
+ APP_ERROR_CHECK(err_code);
+
+ err_code = app_timer_create(&m_es_slot_timer,
+ APP_TIMER_MODE_SINGLE_SHOT,
+ adv_slot_timeout);
+ APP_ERROR_CHECK(err_code);
+}
+
+
+/**@brief Function for finding and setting advertisement timing configuration. */
+static void adv_timing_set(void)
+{
+ ret_code_t err_code;
+ const es_slot_reg_t * p_reg = es_slot_get_registry();
+
+ es_adv_timing_resolver_input_t resolver_input = {
+ .adv_interval = m_current_adv_interval,
+ .p_result = &m_adv_timing_result,
+ .num_slots_configured = p_reg->num_configured_slots,
+ .p_slots_configured = p_reg->slots_configured,
+ .num_eid_slots_configured = p_reg->num_configured_eid_slots,
+ .p_eid_slots_configured = p_reg->eid_slots_configured,
+ .tlm_configured = p_reg->tlm_configured,
+ .tlm_slot = p_reg->tlm_slot};
+
+ err_code = es_adv_timing_resolve(&resolver_input);
+ APP_ERROR_CHECK(err_code);
+}
+
+
+void es_adv_timing_start(uint16_t adv_interval)
+{
+ ret_code_t err_code;
+
+ const es_slot_reg_t * p_reg = es_slot_get_registry();
+
+ m_non_conn_adv_active = true;
+
+ if (p_reg->num_configured_slots > 0)
+ {
+ m_current_adv_interval = adv_interval;
+
+ err_code = app_timer_start(m_es_adv_interval_timer,
+ APP_TIMER_TICKS(m_current_adv_interval),
+ NULL);
+ APP_ERROR_CHECK(err_code);
+
+ adv_timing_set();
+ }
+}
+
+
+void es_adv_timing_stop(void)
+{
+ m_non_conn_adv_active = false; // Stops timers from being re-fired.
+}
+
+
+void es_adv_timing_init(es_adv_timing_callback_t p_handler)
+{
+ m_non_conn_adv_active = false;
+ m_timing_mgr_callback = p_handler;
+ memset(&m_adv_timing_result, 0, sizeof(m_adv_timing_result));
+}
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/eddystone/es_adv_timing.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/eddystone/es_adv_timing.h
new file mode 100644
index 0000000..6728de5
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/eddystone/es_adv_timing.h
@@ -0,0 +1,97 @@
+/**
+ * Copyright (c) 2016 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#ifndef ES_ADV_TIMING_H__
+#define ES_ADV_TIMING_H__
+
+#include <stdint.h>
+
+/**
+ * @file
+ * @defgroup eddystone_adv_timing Timing
+ * @brief Events and functions for advertisement timing.
+ * @ingroup eddystone_adv
+ * @{
+ */
+
+/**@brief Eddystone advertisement timing event types. */
+typedef enum
+{
+ ES_ADV_TIMING_EVT_ADV_SLOT, //!< Advertising non-eTLM slot.
+ ES_ADV_TIMING_EVT_ADV_ETLM //!< Advertising eTLM slot.
+} es_adv_timing_evt_id_t;
+
+/**@brief Eddystone advertisement timing event. */
+typedef struct
+{
+ es_adv_timing_evt_id_t evt_id; //!< Event type ID.
+ uint8_t slot_no; /**< @brief Slot number.
+ * @details For non-eTLM events: The slot number to advertise.
+ *
+ * For eTLM events: The slot number of the corresponding EID slot. */
+} es_adv_timing_evt_t;
+
+/**@brief Eddystone advertisement timing event callback.
+ *
+ * @param[in] p_evt Pointer to the Eddystone advertisement timing event.
+ */
+typedef void (*es_adv_timing_callback_t)(const es_adv_timing_evt_t * p_evt);
+
+/**@brief Function for starting Eddystone advertisement timing event generation. */
+void es_adv_timing_start(uint16_t adv_interval);
+
+
+/**@brief Function for stopping Eddystone advertisement timing event generation. */
+void es_adv_timing_stop(void);
+
+/**@brief Function for initializing the Eddystone advertisement timers.
+ */
+void es_adv_timing_timers_init(void);
+
+/**@brief Function for initializing the Eddystone advertisement timing module.
+ *
+ * @param[in] handler Eddystone advertisement timing event handler to register.
+ */
+void es_adv_timing_init(es_adv_timing_callback_t handler);
+
+/**
+ * @}
+ */
+
+#endif // ES_ADV_TIMING_H__
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/eddystone/es_adv_timing_resolver.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/eddystone/es_adv_timing_resolver.c
new file mode 100644
index 0000000..35c29c9
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/eddystone/es_adv_timing_resolver.c
@@ -0,0 +1,145 @@
+/**
+ * Copyright (c) 2016 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+
+#include "es_adv_timing_resolver.h"
+#include "sdk_macros.h"
+
+/**@brief Function for finding delay to use after each non-eTLM advertisement.
+ *
+ * @param[in] adv_interval Configured advertisement interval.
+ * @param[in] num_slots_configured Number of configured slots.
+ * @param[in] eTLM_required Is there an eTLM slot.
+ */
+static uint16_t get_adv_delay(uint16_t adv_interval,
+ uint8_t num_slots_configured,
+ bool eTLM_required)
+{
+ // If eTLM is required, don't count this when calculating delay.
+ return adv_interval / (num_slots_configured - (eTLM_required ? 1 : 0));
+}
+
+
+/**@brief Function for checking if given slot_no is an EID slot.
+ *
+ * @param[in] slot_no Slot number to check.
+ * @param[in] p_eid_slots_configured Pointer to list of configured EID slots.
+ * @param[in] num_eid_slots_configured Number of EID slots configured.
+ */
+static bool is_eid(uint8_t slot_no, const uint8_t * p_eid_slots_configured, uint8_t num_eid_slots_configured)
+{
+ for (uint32_t i = 0; i < num_eid_slots_configured; ++i)
+ {
+ if (slot_no == p_eid_slots_configured[i])
+ {
+ return true;
+ }
+ }
+
+ return false;
+}
+
+ret_code_t es_adv_timing_resolve(es_adv_timing_resolver_input_t * p_input)
+{
+ VERIFY_PARAM_NOT_NULL(p_input);
+
+ uint8_t result_index = 0;
+ bool eTLM_required = p_input->tlm_configured && p_input->num_eid_slots_configured > 0;
+ uint16_t base_delay;
+
+ if (p_input->num_slots_configured == 0)
+ {
+ return NRF_ERROR_INVALID_PARAM;
+ }
+
+ base_delay = get_adv_delay(p_input->adv_interval, p_input->num_slots_configured, eTLM_required);
+
+ for (uint32_t i = 0; i < p_input->num_slots_configured; ++i)
+ {
+ uint8_t slot_no = p_input->p_slots_configured[i];
+
+ if (!(eTLM_required && slot_no == p_input->tlm_slot))
+ {
+ es_adv_timing_resolver_adv_timing_t * p_current_result = &p_input->p_result->timing_results[result_index];
+ p_current_result->slot_no = slot_no;
+ p_current_result->is_etlm = false;
+
+ // If an eTLM is to be advertised for this frame, this value will be changed.
+ p_current_result->delay_ms = base_delay;
+
+ result_index++;
+
+ if (eTLM_required &&
+ is_eid(slot_no, p_input->p_eid_slots_configured, p_input->num_eid_slots_configured))
+ {
+ es_adv_timing_resolver_adv_timing_t * p_eTLM_timing_result =
+ &p_input->p_result->timing_results[result_index];
+
+ p_current_result->delay_ms = APP_CONFIG_ADV_FRAME_ETLM_SPACING_MS; // Update delay from EID to eTLM frame.
+
+ p_eTLM_timing_result->slot_no = slot_no; // Point to EID slot-no, as this will be
+ // used for finding the correct EIK.
+ p_eTLM_timing_result->is_etlm = true; // Configure as eTLM frame.
+
+ if (base_delay > APP_CONFIG_ADV_FRAME_ETLM_SPACING_MS)
+ {
+ p_eTLM_timing_result->delay_ms =
+ base_delay -
+ APP_CONFIG_ADV_FRAME_ETLM_SPACING_MS; // Set delay of eTLM frame.
+ }
+
+ else
+ {
+ p_eTLM_timing_result->delay_ms = APP_CONFIG_ADV_FRAME_SPACING_MS_MIN;
+ }
+
+ result_index++;
+ }
+ }
+ }
+
+ p_input->p_result->len_timing_results = result_index; // Note: index has been increased to equal length of result.
+
+ if (p_input->p_result->len_timing_results > 0)
+ {
+ p_input->p_result->timing_results[p_input->p_result->len_timing_results - 1].delay_ms = 0; // Last Slot does not need delay.
+ }
+
+ return NRF_SUCCESS;
+}
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/eddystone/es_adv_timing_resolver.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/eddystone/es_adv_timing_resolver.h
new file mode 100644
index 0000000..303ec53
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/eddystone/es_adv_timing_resolver.h
@@ -0,0 +1,96 @@
+/**
+ * Copyright (c) 2016 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#ifndef ES_ADV_TIMING_RESOLVER_H__
+#define ES_ADV_TIMING_RESOLVER_H__
+
+#include <stdbool.h>
+#include <stdint.h>
+#include "es_app_config.h"
+
+/**
+ * @file
+ * @addtogroup eddystone_adv_timing
+ * @{
+ */
+
+/** @brief Timing parameters for a single slot. */
+typedef struct
+{
+ bool is_etlm; //!< Flag that specifies if the slot is an eTLM.
+ uint8_t slot_no; /**< @brief Slot number. @details
+ * For non-eTLM slots: The slot number of the given frame.
+ *
+ * For eTLM slots: The slot number of the corresponding EID frame. */
+ uint16_t delay_ms; //!< Delay from this frame to the next.
+} es_adv_timing_resolver_adv_timing_t;
+
+/**@brief Results of calculating advertisement delays. */
+typedef struct
+{
+ es_adv_timing_resolver_adv_timing_t timing_results[APP_MAX_ADV_SLOTS - APP_MAX_EID_SLOTS +
+ (APP_MAX_EID_SLOTS * 2)]; //!< List of timing results.
+ uint8_t len_timing_results; //!< Length of results.
+} es_adv_timing_resolver_result_t;
+
+/**@brief Input to the timing resolver. */
+typedef struct
+{
+ uint16_t adv_interval; //!< Global advertisement interval.
+ uint8_t num_slots_configured; //!< Number of configured slots.
+ const uint8_t * p_slots_configured; //!< Pointer to the list of configured slots.
+ uint8_t num_eid_slots_configured; //!< Number of configured EID slots.
+ const uint8_t * p_eid_slots_configured; //!< Pointer to the list of configured EID slots.
+ bool tlm_configured; //!< Flag that specifies if TLM slot is configured.
+ uint8_t tlm_slot; //!< Slot number of the TLM slot (if @p tlm_configured is true).
+ es_adv_timing_resolver_result_t * p_result; //!< Output result.
+} es_adv_timing_resolver_input_t;
+
+/**@brief Function for getting the input for advertisement interval calculation.
+ *
+ * @param[in,out] p_input Input to advertisement interval calculation (see @ref es_adv_timing_resolver_input_t).
+ * @retval NRF_SUCCESS If the operation was successful. Otherwise, an error code is returned.
+ */
+ret_code_t es_adv_timing_resolve(es_adv_timing_resolver_input_t * p_input);
+
+/**
+ * @}
+ */
+
+#endif // ES_ADV_TIMING_RESOLVER_H__
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/eddystone/es_battery_voltage.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/eddystone/es_battery_voltage.h
new file mode 100644
index 0000000..2125f00
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/eddystone/es_battery_voltage.h
@@ -0,0 +1,66 @@
+/**
+ * Copyright (c) 2016 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#ifndef ES_BATTERY_VOLTAGE_H__
+#define ES_BATTERY_VOLTAGE_H__
+
+#include <stdint.h>
+
+/**
+ * @file
+ *
+ * @addtogroup eddystone_tlm
+ * @{
+ */
+
+/**@brief Function for initializing the battery voltage module.
+ */
+void es_battery_voltage_init(void);
+
+/**@brief Function for reading the battery voltage.
+ *
+ * @param[out] p_vbatt Pointer to the battery voltage value.
+ */
+void es_battery_voltage_get(uint16_t * p_vbatt);
+
+/**
+ * @}
+ */
+
+#endif // ES_BATTERY_VOLTAGE_H__
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/eddystone/es_battery_voltage_saadc.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/eddystone/es_battery_voltage_saadc.c
new file mode 100644
index 0000000..71502da
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/eddystone/es_battery_voltage_saadc.c
@@ -0,0 +1,104 @@
+/**
+ * Copyright (c) 2016 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#include "es_battery_voltage.h"
+#include "nrf_drv_saadc.h"
+#include "sdk_macros.h"
+
+#define ADC_REF_VOLTAGE_IN_MILLIVOLTS 600 //!< Reference voltage (in milli volts) used by ADC while doing conversion.
+#define DIODE_FWD_VOLT_DROP_MILLIVOLTS 270 //!< Typical forward voltage drop of the diode (Part no: SD103ATW-7-F) that is connected in series with the voltage supply. This is the voltage drop when the forward current is 1mA. Source: Data sheet of 'SURFACE MOUNT SCHOTTKY BARRIER DIODE ARRAY' available at www.diodes.com.
+#define ADC_RES_10BIT 1024 //!< Maximum digital value for 10-bit ADC conversion.
+#define ADC_PRE_SCALING_COMPENSATION 6 //!< The ADC is configured to use VDD with 1/3 prescaling as input. And hence the result of conversion is to be multiplied by 3 to get the actual value of the battery voltage.
+#define ADC_RESULT_IN_MILLI_VOLTS(ADC_VALUE) \
+ ((((ADC_VALUE) *ADC_REF_VOLTAGE_IN_MILLIVOLTS) / ADC_RES_10BIT) * ADC_PRE_SCALING_COMPENSATION)
+
+static nrf_saadc_value_t adc_buf; //!< Buffer used for storing ADC value.
+static uint16_t m_batt_lvl_in_milli_volts; //!< Current battery level.
+
+/**@brief Function handling events from 'nrf_drv_saadc.c'.
+ *
+ * @param[in] p_evt SAADC event.
+ */
+static void saadc_event_handler(nrf_drv_saadc_evt_t const * p_evt)
+{
+ if (p_evt->type == NRF_DRV_SAADC_EVT_DONE)
+ {
+ nrf_saadc_value_t adc_result;
+
+ adc_result = p_evt->data.done.p_buffer[0];
+
+ m_batt_lvl_in_milli_volts =
+ ADC_RESULT_IN_MILLI_VOLTS(adc_result) + DIODE_FWD_VOLT_DROP_MILLIVOLTS;
+ }
+}
+
+
+void es_battery_voltage_init(void)
+{
+ ret_code_t err_code = nrf_drv_saadc_init(NULL, saadc_event_handler);
+
+ APP_ERROR_CHECK(err_code);
+
+ nrf_saadc_channel_config_t config =
+ NRF_DRV_SAADC_DEFAULT_CHANNEL_CONFIG_SE(NRF_SAADC_INPUT_VDD);
+ err_code = nrf_drv_saadc_channel_init(0, &config);
+ APP_ERROR_CHECK(err_code);
+
+ err_code = nrf_drv_saadc_buffer_convert(&adc_buf, 1);
+ APP_ERROR_CHECK(err_code);
+
+ err_code = nrf_drv_saadc_sample();
+ APP_ERROR_CHECK(err_code);
+}
+
+
+void es_battery_voltage_get(uint16_t * p_vbatt)
+{
+ VERIFY_PARAM_NOT_NULL_VOID(p_vbatt);
+
+ *p_vbatt = m_batt_lvl_in_milli_volts;
+ if (!nrf_drv_saadc_is_busy())
+ {
+ ret_code_t err_code = nrf_drv_saadc_buffer_convert(&adc_buf, 1);
+ APP_ERROR_CHECK(err_code);
+
+ err_code = nrf_drv_saadc_sample();
+ APP_ERROR_CHECK(err_code);
+ }
+}
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/eddystone/es_flash.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/eddystone/es_flash.c
new file mode 100644
index 0000000..2e408bb
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/eddystone/es_flash.c
@@ -0,0 +1,340 @@
+/**
+ * Copyright (c) 2016 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#include <string.h>
+#include "es_flash.h"
+#include "es_util.h"
+#include "app_scheduler.h"
+#include "ble_hci.h"
+#include "fds.h"
+#include "nrf_nvic.h"
+
+#define SIZE_OF_PRIV_KEY ESCS_ECDH_KEY_SIZE //!< Size of ECDH private key.
+#define SIZE_OF_PUB_KEY ESCS_ECDH_KEY_SIZE //!< Size of ECDH public key.
+#define SIZE_OF_LOCK_KEY ESCS_AES_KEY_SIZE //!< Size of lock key.
+#define FILE_ID_ES_FLASH 0x1337 //!< File ID used for all flash access EXCEPT lock code.
+#define FILE_ID_ES_FLASH_LOCK_KEY 0x1338 //!< File ID used for lock code flash access.
+#define RECORD_KEY_FLAGS 0x1 //!< File record for flash flags.
+#define RECORD_KEY_PRIV_KEY 0x2 //!< File record for private key.
+#define RECORD_KEY_PUB_KEY 0x3 //!< File record for public key.
+#define RECORD_KEY_LOCK_KEY 0x4 //!< File record for lock key.
+#define RECORD_KEY_BEACON_CONFIG 0x5 //!< File record for lock key.
+
+static uint16_t RECORD_KEY_SLOTS[5] = {0x6, 0x7, 0x8, 0x9, 0xa}; //!< File record for slots.
+
+/**@brief Structure used for invoking flash access function. */
+typedef struct
+{
+ uint16_t record_key;
+ uint16_t file_id;
+ uint8_t * p_data_buf;
+ uint8_t * p_data;
+ uint16_t size_bytes;
+ es_flash_access_t access_type;
+} flash_access_params_t;
+
+static volatile uint32_t m_num_pending_ops; //!< Current number of outstanding FDS operations.
+static volatile bool m_factory_reset; //!< Should factory reset be performed.
+static uint16_t m_conn_handle = BLE_CONN_HANDLE_INVALID; //!< Current connection handle.
+
+
+#if APP_MAX_ADV_SLOTS > 32
+#error "APP_MAX_ADV_SLOTS must be <= 32"
+#endif
+
+#define SLOT_DECL(i, _) __ALIGN(4) static uint8_t slot## i ##_buf[sizeof(es_slot_t)];
+EVAL(REPEAT(APP_MAX_ADV_SLOTS, SLOT_DECL, ~))
+
+__ALIGN(4) static uint8_t lock_key_buf[SIZE_OF_LOCK_KEY]; //!< Buffer for lock key flash access.
+
+#define SLOT(i, _) slot## i ##_buf,
+static uint8_t * slots_buf_p[APP_MAX_ADV_SLOTS] = {
+ EVAL(REPEAT(APP_MAX_ADV_SLOTS, SLOT, ~))
+};
+
+__ALIGN(4) static uint8_t flash_flags_buf[sizeof(es_flash_flags_t)]; //!< Buffer for flash flags flash access.
+__ALIGN(4) static uint8_t beacon_config_buf[sizeof(es_flash_beacon_config_t)]; //!< Buffer for beacon config flash access.
+
+/**@brief Function handling scheduled FDS garbage collection. */
+static void fds_gc_event(void * p_event_data, uint16_t event_size)
+{
+ ret_code_t fds_err_code;
+
+ fds_err_code = fds_gc();
+ if (fds_err_code != FDS_SUCCESS)
+ APP_ERROR_CHECK_BOOL(NRF_ERROR_INTERNAL);
+ m_num_pending_ops++;
+}
+
+
+/**@brief Function handling FDS events.
+ *
+ * @param[in] p_evt FDS event.
+ */
+static void fds_cb(fds_evt_t const * const p_evt)
+{
+ ret_code_t err_code;
+
+ switch (p_evt->id)
+ {
+ case FDS_EVT_INIT:
+ m_num_pending_ops = 0;
+ break;
+
+ case FDS_EVT_DEL_FILE:
+ case FDS_EVT_DEL_RECORD:
+ // Schedule garbage collection
+ err_code = app_sched_event_put(NULL, 0, fds_gc_event);
+ APP_ERROR_CHECK(err_code);
+ break;
+
+ case FDS_EVT_GC:
+ if (m_factory_reset && m_conn_handle != BLE_CONN_HANDLE_INVALID)
+ {
+ err_code =
+ sd_ble_gap_disconnect(m_conn_handle, BLE_HCI_REMOTE_USER_TERMINATED_CONNECTION);
+ APP_ERROR_CHECK(err_code);
+ }
+
+ // Fall through:
+ case FDS_EVT_UPDATE:
+ case FDS_EVT_WRITE:
+ if (m_num_pending_ops > 0)
+ {
+ m_num_pending_ops--;
+ }
+ break;
+ }
+}
+
+
+/**@brief Function performing flash access (read/write/clear).
+ *
+ * @param[in] p_params Flash access parameters.
+ */
+static ret_code_t access_flash_data(const flash_access_params_t * p_params)
+{
+ ret_code_t err_code;
+ fds_flash_record_t record = {0};
+ fds_record_desc_t desc = {0};
+ fds_find_token_t ft = {0};
+ fds_record_t record_to_write =
+ {
+ .data.p_data = p_params->p_data_buf,
+ .file_id = p_params->file_id
+ };
+
+ err_code = fds_record_find_by_key(p_params->record_key, &desc, &ft);
+
+ // If its a read or clear, we can not accept errors on lookup
+ if (p_params->access_type == ES_FLASH_ACCESS_READ)
+ {
+ RETURN_IF_ERROR(err_code);
+ }
+
+ if (p_params->access_type == ES_FLASH_ACCESS_CLEAR && err_code == FDS_ERR_NOT_FOUND)
+ {
+ return NRF_SUCCESS;
+ }
+
+ switch (p_params->access_type)
+ {
+ case ES_FLASH_ACCESS_READ:
+ err_code = fds_record_open(&desc, &record);
+ RETURN_IF_ERROR(err_code);
+
+ memcpy(p_params->p_data, record.p_data, p_params->size_bytes);
+
+ err_code = fds_record_close(&desc);
+ RETURN_IF_ERROR(err_code);
+
+ break;
+
+ case ES_FLASH_ACCESS_WRITE:
+ memcpy(p_params->p_data_buf, p_params->p_data, p_params->size_bytes);
+
+ record_to_write.data.length_words = (p_params->size_bytes +3) / 4;
+ record_to_write.key = p_params->record_key;
+
+ if (err_code == FDS_ERR_NOT_FOUND)
+ {
+ err_code = fds_record_write(&desc, &record_to_write);
+ }
+
+ else
+ {
+ err_code = fds_record_update(&desc, &record_to_write);
+ }
+
+ RETURN_IF_ERROR(err_code);
+ m_num_pending_ops++;
+ break;
+
+ case ES_FLASH_ACCESS_CLEAR:
+ err_code = fds_record_delete(&desc);
+ RETURN_IF_ERROR(err_code);
+ m_num_pending_ops++;
+ break;
+
+ default:
+ break;
+ }
+ return NRF_SUCCESS;
+}
+
+
+ret_code_t es_flash_access_lock_key(uint8_t * p_lock_key, es_flash_access_t access_type)
+{
+ flash_access_params_t params = {.record_key = RECORD_KEY_LOCK_KEY,
+ .file_id = FILE_ID_ES_FLASH_LOCK_KEY,
+ .p_data_buf = lock_key_buf,
+ .p_data = (uint8_t *)p_lock_key,
+ .size_bytes = SIZE_OF_LOCK_KEY,
+ .access_type = access_type};
+
+ return access_flash_data(&params);
+}
+
+
+ret_code_t es_flash_access_beacon_config(es_flash_beacon_config_t * p_config,
+ es_flash_access_t access_type)
+{
+ ret_code_t err_code;
+
+ flash_access_params_t params = {.record_key = RECORD_KEY_BEACON_CONFIG,
+ .file_id = FILE_ID_ES_FLASH,
+ .p_data_buf = beacon_config_buf,
+ .p_data = (uint8_t *)p_config,
+ .size_bytes = sizeof(es_flash_beacon_config_t),
+ .access_type = access_type};
+
+ err_code = access_flash_data(&params);
+
+ return err_code;
+}
+
+
+ret_code_t es_flash_access_slot_configs(uint8_t slot_no,
+ es_slot_t * p_slot,
+ es_flash_access_t access_type)
+{
+ if (slot_no >= APP_MAX_ADV_SLOTS)
+ {
+ return NRF_ERROR_INVALID_PARAM;
+ }
+
+ flash_access_params_t params = {.record_key = RECORD_KEY_SLOTS[slot_no],
+ .file_id = FILE_ID_ES_FLASH,
+ .p_data_buf = slots_buf_p[slot_no],
+ .p_data = (uint8_t *)p_slot,
+ .size_bytes = sizeof(es_slot_t),
+ .access_type = access_type};
+
+ return access_flash_data(&params);
+}
+
+
+ret_code_t es_flash_access_flags(es_flash_flags_t * p_flags, es_flash_access_t access_type)
+{
+ flash_access_params_t params = {.record_key = RECORD_KEY_FLAGS,
+ .file_id = FILE_ID_ES_FLASH,
+ .p_data_buf = flash_flags_buf,
+ .p_data = (uint8_t *)p_flags,
+ .size_bytes = sizeof(es_flash_flags_t),
+ .access_type = access_type};
+
+ return access_flash_data(&params);
+}
+
+
+ret_code_t es_flash_factory_reset(void)
+{
+ // Delete everything except the lock key:
+ ret_code_t ret_code = fds_file_delete(FILE_ID_ES_FLASH);
+
+ if (ret_code == FDS_SUCCESS)
+ m_factory_reset = true;
+ return ret_code;
+}
+
+
+uint32_t es_flash_num_pending_ops(void)
+{
+ return m_num_pending_ops;
+}
+
+
+void es_flash_on_ble_evt(ble_evt_t const * p_evt)
+{
+ switch (p_evt->header.evt_id)
+ {
+ case BLE_GAP_EVT_CONNECTED:
+ m_conn_handle = p_evt->evt.common_evt.conn_handle;
+ break;
+
+ case BLE_GAP_EVT_DISCONNECTED:
+ m_conn_handle = BLE_CONN_HANDLE_INVALID;
+ if (m_factory_reset)
+ {
+ (void)sd_nvic_SystemReset();
+ }
+ break;
+ }
+}
+
+
+ret_code_t es_flash_init(void)
+{
+ ret_code_t err_code;
+
+ m_num_pending_ops = 1; // Will be set to 0 when getting FDS_EVT_INIT event
+
+ m_conn_handle = BLE_CONN_HANDLE_INVALID;
+
+ m_factory_reset = false;
+
+ err_code = fds_register(fds_cb);
+ RETURN_IF_ERROR(err_code);
+
+ err_code = fds_init();
+ RETURN_IF_ERROR(err_code);
+
+ return NRF_SUCCESS;
+}
+
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/eddystone/es_flash.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/eddystone/es_flash.h
new file mode 100644
index 0000000..d896669
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/eddystone/es_flash.h
@@ -0,0 +1,177 @@
+/**
+ * Copyright (c) 2016 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#ifndef ES_FLASH_H__
+#define ES_FLASH_H__
+
+#include <stdbool.h>
+#include <stdint.h>
+#include "es_slot.h"
+
+
+/**
+ * @file
+ * @defgroup eddystone_flash Flash access
+ * @brief Types and functions to access the flash of the Eddystone beacon.
+ * @ingroup eddystone
+ * @{
+ */
+
+#define WORD_SIZE 4
+
+#define FLASH_ACCES_ERROR_CHECK_ALLOW_NOT_FOUND(err_code) \
+ if (err_code != (FDS_ERR_NOT_FOUND)) \
+ APP_ERROR_CHECK(err_code);
+
+#define FLASH_OP_WAIT() \
+ uint32_t pending_ops = es_flash_num_pending_ops(); \
+ while (pending_ops != 0) \
+ { \
+ pending_ops = es_flash_num_pending_ops(); \
+ }
+
+/**@brief Beacon configuration. */
+typedef struct
+{
+ nrf_ble_escs_adv_interval_t adv_interval; //!< Advertising interval.
+ bool remain_connectable; //!< Flag that specifies if the beacon should remain connectable.
+} es_flash_beacon_config_t;
+
+/**@brief Structure for keeping track of which slot has a configuration that must be restored upon reboot.
+ * @details The size of this structure must be word aligned and match the flash block size of 32 bytes.
+ */
+typedef struct
+{
+ bool slot_is_empty[APP_MAX_ADV_SLOTS]; //!< Flag that indicates whether the slot is empty.
+ uint8_t padding[WORD_SIZE - ((APP_MAX_ADV_SLOTS + 1) % WORD_SIZE)]; //!< Padding used to ensure word alignment.
+} es_flash_flags_t;
+
+/**@brief Flash access types.
+ */
+typedef enum
+{
+ ES_FLASH_ACCESS_READ, //!< Read data.
+ ES_FLASH_ACCESS_WRITE, //!< Write data.
+ ES_FLASH_ACCESS_CLEAR //!< Clear data.
+} es_flash_access_t;
+
+/**@brief Function for accessing beacon configurations.
+ *
+ * @param[out,in] p_config Pointer to the beacon configuration buffer.
+ * @param[in] access_type Access type (see @ref es_flash_access_t).
+ * @return For possible return values, see:
+ * - @ref fds_record_find_by_key
+ * - @ref fds_record_open
+ * - @ref fds_record_close
+ * - @ref fds_record_write
+ * - @ref fds_record_update
+ * - @ref fds_record_delete
+ */
+ret_code_t es_flash_access_beacon_config(es_flash_beacon_config_t * p_config,
+ es_flash_access_t access_type);
+
+/**@brief Function for accessing slot configuration from flash.
+ *
+ * @param[in] slot_no Slot index.
+ * @param[out,in] p_slot Pointer to the slot configuration buffer.
+ * @param[in] access_type Access type (see @ref es_flash_access_t).
+ * @return For possible return values, see:
+ * - @ref fds_record_find_by_key
+ * - @ref fds_record_open
+ * - @ref fds_record_close
+ * - @ref fds_record_write
+ * - @ref fds_record_update
+ * - @ref fds_record_delete
+ */
+ret_code_t es_flash_access_slot_configs(uint8_t slot_no,
+ es_slot_t * p_slot,
+ es_flash_access_t access_type);
+
+
+/**@brief Function for accessing the beacon lock key from flash.
+ *
+ * @param[out,in] p_lock_key Pointer to the lock key buffer.
+ * @param[in] access_type Access type (see @ref es_flash_access_t).
+ * @return For possible return values, see:
+ * - @ref fds_record_find_by_key
+ * - @ref fds_record_open
+ * - @ref fds_record_close
+ * - @ref fds_record_write
+ * - @ref fds_record_update
+ * - @ref fds_record_delete
+ */
+ret_code_t es_flash_access_lock_key(uint8_t * p_lock_key, es_flash_access_t access_type);
+
+/**@brief Function for accessing the flash configuration flag from flash.
+ *
+ * @param[out,in] p_flags Pointer to the flag buffer.
+ * @param[in] access_type Access type (see @ref es_flash_access_t).
+ * @return For possible return values, see:
+ * - @ref fds_record_find_by_key
+ * - @ref fds_record_open
+ * - @ref fds_record_close
+ * - @ref fds_record_write
+ * - @ref fds_record_update
+ * - @ref fds_record_delete
+ */
+ret_code_t es_flash_access_flags(es_flash_flags_t * p_flags, es_flash_access_t access_type);
+
+/**@brief Function for retrieving the number of queued operations.
+ * @return The number of operations that are queued.
+ */
+uint32_t es_flash_num_pending_ops(void);
+
+/**@brief Function for performing a factory reset.
+ * @return FDS return code.
+ */
+ret_code_t es_flash_factory_reset(void);
+
+void es_flash_on_ble_evt(ble_evt_t const * p_evt);
+
+/**@brief Function for initializing the flash module.
+ *
+ * @return See @ref fds_init for possible return values.
+ */
+ret_code_t es_flash_init(void);
+
+/**
+ * @}
+ */
+
+#endif // ES_FLASH_H__
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/eddystone/es_gatts.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/eddystone/es_gatts.c
new file mode 100644
index 0000000..c6280e2
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/eddystone/es_gatts.c
@@ -0,0 +1,188 @@
+/**
+ * Copyright (c) 2016 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+
+#include "es_gatts.h"
+#include "es_gatts_read.h"
+#include "es_gatts_write.h"
+#include "es_slot.h"
+
+static nrf_ble_escs_lock_state_read_t m_lock_state;
+static uint8_t m_active_slot;
+
+/**@brief Function checking if beacon is unlocked.
+ *
+ * @param[in] p_escs Pointer to Eddystone Configuration Service.
+ *
+ * @retval true If beacon is unlocked.
+ * @retval false If beacon is locked.
+ */
+static bool is_beacon_unlocked(const nrf_ble_escs_t * p_escs)
+{
+ return m_lock_state != NRF_BLE_ESCS_LOCK_STATE_LOCKED;
+}
+
+
+ret_code_t es_gatts_send_reply(nrf_ble_escs_t * p_escs,
+ ble_gatts_rw_authorize_reply_params_t * p_reply)
+{
+ VERIFY_PARAM_NOT_NULL(p_escs);
+ VERIFY_PARAM_NOT_NULL(p_reply);
+
+ if (p_escs->conn_handle != BLE_CONN_HANDLE_INVALID)
+ {
+ return sd_ble_gatts_rw_authorize_reply(p_escs->conn_handle, p_reply);
+ }
+
+ return NRF_ERROR_INVALID_STATE;
+}
+
+
+ret_code_t es_gatts_send_op_not_permitted(nrf_ble_escs_t * p_escs, bool read)
+{
+ ble_gatts_rw_authorize_reply_params_t reply = {0};
+
+ VERIFY_PARAM_NOT_NULL(p_escs);
+
+ if (read)
+ {
+ reply.type = BLE_GATTS_AUTHORIZE_TYPE_READ;
+ reply.params.read.gatt_status = BLE_GATT_STATUS_ATTERR_READ_NOT_PERMITTED;
+ }
+
+ else
+ {
+ reply.type = BLE_GATTS_AUTHORIZE_TYPE_WRITE;
+ reply.params.write.gatt_status = BLE_GATT_STATUS_ATTERR_WRITE_NOT_PERMITTED;
+ }
+
+ return es_gatts_send_reply(p_escs, &reply);
+}
+
+
+
+void es_gatts_handle_write(nrf_ble_escs_t * p_escs,
+ uint16_t uuid,
+ uint16_t val_handle,
+ uint8_t const * p_data,
+ uint16_t length)
+{
+ ret_code_t err_code;
+
+ if (is_beacon_unlocked(p_escs))
+ {
+ if (uuid == BLE_UUID_ESCS_UNLOCK_CHAR)
+ {
+ err_code = es_gatts_send_op_not_permitted(p_escs, false);
+ APP_ERROR_CHECK(err_code);
+ }
+
+ else
+ {
+ err_code = es_gatts_write_handle_unlocked_write(
+ p_escs, uuid, val_handle, p_data, length, m_active_slot);
+ APP_ERROR_CHECK(err_code);
+ }
+ }
+
+ else
+ {
+ if (uuid == BLE_UUID_ESCS_UNLOCK_CHAR)
+ {
+ err_code = es_gatts_write_handle_unlock(p_escs, p_data, length, val_handle);
+ APP_ERROR_CHECK(err_code);
+ }
+
+ else
+ {
+ err_code = es_gatts_send_op_not_permitted(p_escs, false);
+ APP_ERROR_CHECK(err_code);
+ }
+ }
+}
+
+
+void es_gatts_handle_read(nrf_ble_escs_t * p_escs, uint16_t uuid, uint16_t val_handle)
+{
+ ret_code_t err_code;
+
+ if (is_beacon_unlocked(p_escs))
+ {
+ if (uuid == BLE_UUID_ESCS_UNLOCK_CHAR)
+ {
+ err_code = es_gatts_send_op_not_permitted(p_escs, true);
+ APP_ERROR_CHECK(err_code);
+ }
+
+ else
+ {
+ err_code = es_gatts_read_handle_unlocked_read(p_escs, uuid, val_handle, m_active_slot, m_lock_state);
+ APP_ERROR_CHECK(err_code);
+ }
+ }
+
+ else // Beacon is locked.
+ {
+ if (uuid == BLE_UUID_ESCS_UNLOCK_CHAR)
+ {
+ err_code = es_gatts_read_handle_unlock(p_escs);
+ APP_ERROR_CHECK(err_code);
+ }
+
+ else
+ {
+ err_code = es_gatts_read_handle_locked_read(p_escs, uuid, m_lock_state);
+ APP_ERROR_CHECK(err_code);
+ }
+ }
+}
+
+
+ret_code_t es_gatts_init(nrf_ble_escs_t * p_ble_escs)
+{
+ VERIFY_PARAM_NOT_NULL(p_ble_escs);
+
+ m_active_slot = 0;
+ m_lock_state = NRF_BLE_ESCS_LOCK_STATE_LOCKED;
+
+ p_ble_escs->p_active_slot = &m_active_slot;
+ p_ble_escs->p_lock_state = &m_lock_state;
+
+ return NRF_SUCCESS;
+}
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/eddystone/es_gatts.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/eddystone/es_gatts.h
new file mode 100644
index 0000000..b5da232
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/eddystone/es_gatts.h
@@ -0,0 +1,109 @@
+/**
+ * Copyright (c) 2016 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+
+#ifndef ES_GATTS_H__
+#define ES_GATTS_H__
+
+#include <stdint.h>
+#include "nrf_ble_escs.h"
+
+/**
+ * @file
+ * @defgroup eddystone_gatts GATTS
+ * @brief Functions for handling GATTS write and read requests.
+ * @ingroup eddystone
+ * @{
+ */
+
+ret_code_t es_gatts_init(nrf_ble_escs_t * p_ble_escs);
+
+/**@brief Function for handling all write requests from the Central.
+ *
+ * @param[in] p_escs Pointer to the Eddystone Configuration Service.
+ * @param[in] uuid The UUID of the characteristic that is being written to.
+ * @param[in] val_handle Value handle field of the characteristic handle of the characteristic that is being written to.
+ * @param[in] p_data Pointer to the data to be written.
+ * @param[in] length Length of the data to be written.
+ *
+ */
+void es_gatts_handle_write(nrf_ble_escs_t * p_escs,
+ uint16_t uuid,
+ uint16_t val_handle,
+ uint8_t const * p_data,
+ uint16_t length);
+
+
+/**@brief Function for handling all read requests from the Central.
+ *
+ * @param[in] p_escs Pointer to the Eddystone Configuration Service.
+ * @param[in] uuid The UUID of the characteristic that is being read from.
+ * @param[in] val_handle Value handle field of the characteristic handle of the characteristic that is being read from.
+ *
+ */
+void es_gatts_handle_read(nrf_ble_escs_t * p_escs, uint16_t uuid, uint16_t val_handle);
+
+/**@brief Function for sending an RW-authorization reply.
+ *
+ * @param[in] p_escs Pointer to the Eddystone Configuration Service.
+ * @param[in] p_reply Pointer to the reply to send.
+ *
+ * @retval NRF_SUCCESS If the reply was successfully issued to the SoftDevice.
+ * @retval NRF_ERROR_NULL If either of the pointers @p p_escs or @p p_reply is NULL.
+ * @retval NRF_ERROR_INVALID_STATE If the connection handle of @p p_escs is invalid.
+ * @return Otherwise, an error code from sd_ble_gatts_rw_authorize_reply() is returned.
+ */
+ret_code_t es_gatts_send_reply(nrf_ble_escs_t * p_escs, ble_gatts_rw_authorize_reply_params_t * p_reply);
+
+/**@brief Function for sending an RW-authorization reply with status 'Operation not permitted'.
+ *
+ * @param[in] p_escs Pointer to the Eddystone Configuration Service.
+ * @param[in] op_is_read Flag that specifies if the operation being responded to is a 'read' operation.
+ If false, a 'write' operation is assumed.
+ *
+ * @retval NRF_ERROR_NULL If @p p_escs is NULL.
+ * @return Otherwise, the error code from es_gatts_send_reply() is returned.
+ */
+ret_code_t es_gatts_send_op_not_permitted(nrf_ble_escs_t * p_escs, bool op_is_read);
+
+/**
+ * @}
+ */
+
+#endif // ES_GATTS_H__
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/eddystone/es_gatts_read.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/eddystone/es_gatts_read.c
new file mode 100644
index 0000000..6ab51de
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/eddystone/es_gatts_read.c
@@ -0,0 +1,246 @@
+/**
+ * Copyright (c) 2016 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+
+#include "es_gatts_read.h"
+#include "es_adv.h"
+#include "es_gatts.h"
+#include "es_security.h"
+#include "es_slot.h"
+
+static ret_code_t send_read_reply(nrf_ble_escs_t * p_escs, ble_gatts_rw_authorize_reply_params_t * p_reply)
+{
+ VERIFY_PARAM_NOT_NULL(p_escs);
+ VERIFY_PARAM_NOT_NULL(p_reply);
+
+ p_reply->type = BLE_GATTS_AUTHORIZE_TYPE_READ;
+ p_reply->params.read.update = 1;
+ p_reply->params.read.offset = 0;
+
+ return es_gatts_send_reply(p_escs, p_reply);
+}
+
+
+static ret_code_t read_value(nrf_ble_escs_t * p_escs, uint8_t length, const void * p_value)
+{
+ VERIFY_PARAM_NOT_NULL(p_escs);
+ VERIFY_PARAM_NOT_NULL(p_value);
+
+ ble_gatts_rw_authorize_reply_params_t reply = {0};
+ reply.params.read.len = length;
+ reply.params.read.p_data = p_value;
+ reply.params.read.gatt_status = BLE_GATT_STATUS_SUCCESS;
+
+ return send_read_reply(p_escs, &reply);
+}
+
+
+static ret_code_t read_from_gattdb(nrf_ble_escs_t * p_escs, uint16_t val_handle)
+{
+ VERIFY_PARAM_NOT_NULL(p_escs);
+
+ ret_code_t err_code;
+
+ // Go straight to the characteristic
+ uint8_t value_buffer[ESCS_ADV_SLOT_CHAR_LENGTH_MAX] = {0};
+ ble_gatts_value_t value = {.len = sizeof(value_buffer),
+ .offset = 0,
+ .p_value = &(value_buffer[0])};
+
+ err_code = sd_ble_gatts_value_get(p_escs->conn_handle, val_handle, &value);
+ RETURN_IF_ERROR(err_code);
+
+ return read_value(p_escs, value.len, value.p_value);
+}
+
+
+static ret_code_t read_adv_slot(nrf_ble_escs_t * p_escs, uint8_t active_slot, const es_slot_reg_t * p_reg)
+{
+ VERIFY_PARAM_NOT_NULL(p_escs);
+
+ ble_gatts_rw_authorize_reply_params_t reply = {0};
+ uint8_t eid_buf[14];
+
+ // If an EID slot is read, load scaler, clock value and ephemeral ID.
+ if (p_reg->slots[active_slot].adv_frame.type == ES_FRAME_TYPE_EID)
+ {
+ /*lint -save -e666 */
+ uint32_t clock_value = es_security_clock_get(active_slot);
+ clock_value = BYTES_REVERSE_32BIT(clock_value);
+ /*lint -restore */
+
+ reply.params.read.len = ES_EID_GATTS_READ_LENGTH;
+
+ // Fill EID buffer with data
+ eid_buf[ES_EID_GATTS_READ_FRAME_TYPE_IDX] = ES_FRAME_TYPE_EID;
+ eid_buf[ES_EID_GATTS_READ_EXPONENT_IDX] = es_security_scaler_get(active_slot);
+
+ memcpy(&eid_buf[ES_EID_GATTS_READ_CLCK_VALUE_IDX], &clock_value, sizeof(clock_value));
+ /*lint -save -e545 */
+ memcpy(&eid_buf[ES_EID_GATTS_READ_EID_IDX],
+ &p_reg->slots[active_slot].adv_frame.frame.eid.eid,
+ ES_EID_ID_LENGTH);
+ /*lint -restore */
+ reply.params.read.p_data = eid_buf;
+ }
+
+ // Otherwise, simply load the contents of the frame.
+ else
+ {
+ // Check if slot being read is an eTLM slot.
+ if ((p_reg->num_configured_eid_slots > 0) && p_reg->tlm_configured && (p_reg->tlm_slot == active_slot))
+ {
+ // Fill eTLM slot using EID key from first EID slot.
+ es_slot_etlm_update(p_reg->eid_slots_configured[0]);
+ }
+ reply.params.read.len = p_reg->slots[active_slot].adv_frame.length;
+ reply.params.read.p_data = (uint8_t *)&p_reg->slots[active_slot].adv_frame.frame;
+ }
+
+ reply.params.read.gatt_status = BLE_GATT_STATUS_SUCCESS;
+
+ return send_read_reply(p_escs, &reply);
+}
+
+
+ret_code_t es_gatts_read_handle_locked_read(nrf_ble_escs_t * p_escs, uint16_t uuid, uint8_t lock_state)
+{
+ VERIFY_PARAM_NOT_NULL(p_escs);
+
+ if (uuid == BLE_UUID_ESCS_REMAIN_CONNECTABLE_CHAR)
+ {
+ uint8_t retval = APP_IS_REMAIN_CONNECTABLE_SUPPORTED;
+ return read_value(p_escs, sizeof(retval), &retval);
+ }
+
+ else if (uuid == BLE_UUID_ESCS_LOCK_STATE_CHAR)
+ {
+ return read_value(p_escs, sizeof(lock_state), &lock_state);
+ }
+
+ else
+ {
+ return es_gatts_send_op_not_permitted(p_escs, true);
+ }
+}
+
+
+ret_code_t es_gatts_read_handle_unlock(nrf_ble_escs_t * p_escs)
+{
+ VERIFY_PARAM_NOT_NULL(p_escs);
+
+ ret_code_t err_code;
+ uint8_t key_buff[ESCS_AES_KEY_SIZE];
+
+ err_code = es_security_random_challenge_generate(key_buff);
+ RETURN_IF_ERROR(err_code);
+
+ es_security_unlock_prepare(key_buff);
+
+ return read_value(p_escs, ESCS_AES_KEY_SIZE, key_buff);
+}
+
+
+ret_code_t es_gatts_read_handle_unlocked_read(nrf_ble_escs_t * p_escs,
+ uint16_t uuid,
+ uint16_t val_handle,
+ uint8_t active_slot,
+ uint8_t lock_state)
+{
+ VERIFY_PARAM_NOT_NULL(p_escs);
+
+ const es_slot_reg_t * p_reg = es_slot_get_registry();
+
+ switch (uuid)
+ {
+ case BLE_UUID_ESCS_BROADCAST_CAP_CHAR:
+ case BLE_UUID_ESCS_UNLOCK_CHAR:
+ case BLE_UUID_ESCS_PUBLIC_ECDH_KEY_CHAR:
+ case BLE_UUID_ESCS_ACTIVE_SLOT_CHAR:
+ return read_from_gattdb(p_escs, val_handle);
+
+ case BLE_UUID_ESCS_LOCK_STATE_CHAR:
+ return read_value(p_escs, sizeof(lock_state), &lock_state);
+
+ case BLE_UUID_ESCS_ADV_INTERVAL_CHAR:
+ {
+ nrf_ble_escs_adv_interval_t adv_interval = es_adv_interval_get();
+ adv_interval = BYTES_SWAP_16BIT(adv_interval);
+ return read_value(p_escs, sizeof(adv_interval), &adv_interval);
+ }
+
+ case BLE_UUID_ESCS_RADIO_TX_PWR_CHAR:
+ return read_value(p_escs,
+ sizeof(nrf_ble_escs_radio_tx_pwr_t),
+ &p_reg->slots[active_slot].radio_tx_pwr);
+
+ case BLE_UUID_ESCS_ADV_TX_PWR_CHAR:
+ return read_value(p_escs,
+ sizeof(nrf_ble_escs_radio_tx_pwr_t),
+ p_reg->slots[active_slot].adv_custom_tx_power
+ ? (uint8_t *)(&p_reg->slots[active_slot].custom_tx_power)
+ : (uint8_t *)(&p_reg->slots[active_slot].radio_tx_pwr));
+
+ case BLE_UUID_ESCS_REMAIN_CONNECTABLE_CHAR:
+ {
+ uint8_t retval = APP_IS_REMAIN_CONNECTABLE_SUPPORTED;
+ return read_value(p_escs, sizeof(retval), &retval);
+ }
+
+ case BLE_UUID_ESCS_EID_ID_KEY_CHAR:
+ if (p_reg->slots[active_slot].configured &&
+ (p_reg->slots[active_slot].adv_frame.type == ES_FRAME_TYPE_EID))
+ {
+ return read_value(p_escs,
+ sizeof(nrf_ble_escs_eid_id_key_t),
+ &p_reg->slots[active_slot].encrypted_eid_id_key);
+ }
+
+ else
+ {
+ return es_gatts_send_op_not_permitted(p_escs, true);
+ }
+
+ case BLE_UUID_ESCS_RW_ADV_SLOT_CHAR:
+ return read_adv_slot(p_escs, active_slot, p_reg);
+
+ default:
+ return NRF_ERROR_INVALID_PARAM;
+ }
+}
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/eddystone/es_gatts_read.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/eddystone/es_gatts_read.h
new file mode 100644
index 0000000..32cc818
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/eddystone/es_gatts_read.h
@@ -0,0 +1,73 @@
+/**
+ * Copyright (c) 2016 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+
+#ifndef ES_GATTS_READ_H__
+#define ES_GATTS_READ_H__
+
+#include <stdint.h>
+#include "nrf_ble_escs.h"
+
+/**
+ * @file
+ * @defgroup eddystone_gatts_read GATTS read
+ * @brief Functions for handling GATTS read requests.
+ * @ingroup eddystone_gatts
+ * @{
+ */
+
+ret_code_t es_gatts_read_send_not_permitted(nrf_ble_escs_t * p_escs);
+
+ret_code_t es_gatts_read_handle_unlocked_read(nrf_ble_escs_t * p_escs,
+ uint16_t uuid,
+ uint16_t val_handle,
+ uint8_t active_slot,
+ uint8_t lock_state);
+
+ret_code_t es_gatts_read_handle_unlock(nrf_ble_escs_t * p_escs);
+
+ret_code_t es_gatts_read_handle_locked_read(nrf_ble_escs_t * p_escs,
+ uint16_t uuid,
+ uint8_t lock_state);
+
+/**
+ * @}
+ */
+
+#endif // ES_GATTS_READ_H__
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/eddystone/es_gatts_write.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/eddystone/es_gatts_write.c
new file mode 100644
index 0000000..8a66493
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/eddystone/es_gatts_write.c
@@ -0,0 +1,254 @@
+/**
+ * Copyright (c) 2016 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+
+#include "es_gatts_write.h"
+#include "es_adv.h"
+#include "es_flash.h"
+#include "es_gatts.h"
+#include "es_security.h"
+
+
+static ret_code_t send_write_reply(nrf_ble_escs_t * p_escs, ble_gatts_rw_authorize_reply_params_t * p_reply)
+{
+ VERIFY_PARAM_NOT_NULL(p_escs);
+ VERIFY_PARAM_NOT_NULL(p_reply);
+
+ p_reply->type = BLE_GATTS_AUTHORIZE_TYPE_WRITE;
+ p_reply->params.write.update = 1;
+ p_reply->params.write.offset = 0;
+
+ return es_gatts_send_reply(p_escs, p_reply);
+}
+
+
+/**@brief Function checking if length of event is correct, given the frame data.
+ *
+ * @param[in] p_data Written ADV Slot data.
+ * @param[in] length Written length.
+ *
+ * @retval true If length is valid.
+ * @retval false If length is not valid.
+ */
+static bool length_is_valid(uint8_t const * p_data, uint8_t length)
+{
+ if (length == 0 || (length == 1 && p_data[0] == 0))
+ {
+ return true;
+ }
+
+ else
+ {
+ switch ((es_frame_type_t)p_data[0])
+ {
+ case ES_FRAME_TYPE_UID:
+ return length == ESCS_UID_WRITE_LENGTH;
+
+ case ES_FRAME_TYPE_URL:
+ return ((length >= ESCS_URL_MIN_WRITE_LENGTH) && (length <= ESCS_URL_WRITE_LENGTH));
+
+ case ES_FRAME_TYPE_TLM:
+ return (length == ESCS_TLM_WRITE_LENGTH);
+
+ case ES_FRAME_TYPE_EID:
+ return ((length == ESCS_EID_WRITE_ECDH_LENGTH) ||
+ (length == ESCS_EID_WRITE_IDK_LENGTH));
+
+ default:
+ return false;
+ }
+ }
+}
+
+
+ret_code_t es_gatts_write_handle_unlocked_write(nrf_ble_escs_t * p_escs,
+ uint16_t uuid,
+ uint16_t val_handle,
+ uint8_t const * p_data,
+ uint16_t length,
+ uint8_t active_slot)
+{
+ VERIFY_PARAM_NOT_NULL(p_escs);
+ VERIFY_PARAM_NOT_NULL(p_data);
+
+ ret_code_t err_code;
+ ble_gatts_rw_authorize_reply_params_t reply = {0};
+ bool long_write = false;
+
+ reply.params.write.gatt_status = BLE_GATT_STATUS_SUCCESS;
+
+ switch (uuid)
+ {
+ case BLE_UUID_ESCS_ACTIVE_SLOT_CHAR:
+ if (*p_data > APP_MAX_ADV_SLOTS - 1)
+ {
+ // Invalid Attribute Length: for an attempt to write illegal values.
+ // The beacon will list the total number of available slots in the
+ // max_supported_total_slots field in the Capabilities characteristic.
+ reply.params.write.gatt_status = BLE_GATT_STATUS_ATTERR_INVALID_ATT_VAL_LENGTH;
+ length = 0;
+ }
+ break;
+
+ case BLE_UUID_ESCS_ADV_INTERVAL_CHAR:
+ es_adv_interval_set(BYTES_SWAP_16BIT(*(nrf_ble_escs_adv_interval_t *)p_data));
+ break;
+
+ case BLE_UUID_ESCS_RADIO_TX_PWR_CHAR:
+ es_slot_radio_tx_pwr_set(active_slot, *(nrf_ble_escs_radio_tx_pwr_t *)(p_data));
+ break;
+
+ case BLE_UUID_ESCS_ADV_TX_PWR_CHAR:
+ // Update slot info so that ADV data will only be read from what is written by client.
+ es_slot_set_adv_custom_tx_power(active_slot, *(nrf_ble_escs_radio_tx_pwr_t *)(p_data));
+ break;
+
+ case BLE_UUID_ESCS_LOCK_STATE_CHAR:
+ if (length == 1 && (*p_data == NRF_BLE_ESCS_LOCK_BYTE_LOCK ||
+ *p_data == NRF_BLE_ESCS_LOCK_BYTE_DISABLE_AUTO_RELOCK))
+ {
+ // Do nothing special, allow the write.
+ }
+ else if (length == ESCS_LOCK_STATE_NEW_LOCK_CODE_WRITE_LENGTH &&
+ *p_data == NRF_BLE_ESCS_LOCK_BYTE_LOCK)
+ {
+ // 0x00 + key[16] : transition to lock state and update the lock code.
+ err_code = es_security_lock_code_update((uint8_t*)(p_data) + 1);
+ RETURN_IF_ERROR(err_code);
+
+ // Only write the lock byte (0x00) to the characteristic, so set length to 1.
+ length = 1;
+ }
+ else
+ {
+ // Any invalid values locks the characteristic by default.
+ (*(uint8_t*)p_data) = NRF_BLE_ESCS_LOCK_BYTE_LOCK;
+ length = 1;
+ }
+ break;
+
+ case BLE_UUID_ESCS_RW_ADV_SLOT_CHAR:
+ if (length > 20)
+ {
+ long_write = true;
+ }
+ reply.params.write.gatt_status = length_is_valid(p_data, length)
+ ? BLE_GATT_STATUS_SUCCESS
+ : BLE_GATT_STATUS_ATTERR_INVALID_ATT_VAL_LENGTH;
+
+ if (reply.params.write.gatt_status == BLE_GATT_STATUS_SUCCESS)
+ {
+ es_slot_on_write(active_slot, length, p_data);
+ es_adv_interval_set(es_adv_interval_get()); // Ensure that valid advertisement interval is used.
+ }
+ break;
+
+ case BLE_UUID_ESCS_FACTORY_RESET_CHAR:
+ if (*p_data == 0x0B)
+ {
+ err_code = es_flash_factory_reset();
+ RETURN_IF_ERROR(err_code);
+ }
+ break;
+
+ case BLE_UUID_ESCS_REMAIN_CONNECTABLE_CHAR:
+#if APP_IS_REMAIN_CONNECTABLE_SUPPORTED == ESCS_FUNCT_REMAIN_CONNECTABLE_SUPPORTED_Yes
+ if (*p_data != 0)
+ {
+ es_adv_remain_connectable_set(true);
+ }
+
+ else
+ {
+ es_adv_remain_connectable_set(false);
+ }
+#endif
+ break;
+
+ default:
+ break;
+ }
+ reply.params.write.len = length;
+ reply.params.write.p_data = p_data;
+
+ if (!long_write)
+ {
+ return send_write_reply(p_escs, &reply);
+ }
+
+ else
+ {
+ return NRF_SUCCESS;
+ }
+}
+
+
+ret_code_t es_gatts_write_handle_unlock(nrf_ble_escs_t * p_escs,
+ uint8_t const * p_data,
+ uint16_t length,
+ uint16_t val_handle)
+{
+ VERIFY_PARAM_NOT_NULL(p_escs);
+ VERIFY_PARAM_NOT_NULL(p_data);
+
+ ret_code_t err_code;
+ ble_gatts_rw_authorize_reply_params_t reply = {0};
+ ble_gatts_value_t value = {.len = length, .offset = 0, .p_value = (uint8_t*)p_data};
+
+ if (length == ESCS_AES_KEY_SIZE)
+ {
+ err_code = sd_ble_gatts_value_set(p_escs->conn_handle, val_handle, &value);
+
+ if (err_code == NRF_SUCCESS)
+ {
+ reply.params.write.gatt_status = BLE_GATT_STATUS_SUCCESS;
+ es_security_unlock_verify((value.p_value));
+ }
+
+ else
+ {
+ reply.params.write.gatt_status = BLE_GATT_STATUS_ATTERR_WRITE_NOT_PERMITTED;
+ }
+ }
+
+ reply.params.write.len = length;
+ reply.params.write.p_data = (const uint8_t *)value.p_value;
+
+ return send_write_reply(p_escs, &reply);
+}
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/eddystone/es_gatts_write.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/eddystone/es_gatts_write.h
new file mode 100644
index 0000000..2bcbce1
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/eddystone/es_gatts_write.h
@@ -0,0 +1,71 @@
+/**
+ * Copyright (c) 2016 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+
+#ifndef ES_GATTS_WRITE_H__
+#define ES_GATTS_WRITE_H__
+
+#include <stdint.h>
+#include "nrf_ble_escs.h"
+
+/**
+ * @file
+ * @defgroup eddystone_gatts_write GATTS write
+ * @brief Functions for handling GATTS write requests.
+ * @ingroup eddystone_gatts
+ * @{
+ */
+
+ret_code_t es_gatts_write_handle_unlocked_write(nrf_ble_escs_t * p_escs,
+ uint16_t uuid,
+ uint16_t val_handle,
+ uint8_t const * p_data,
+ uint16_t length,
+ uint8_t active_slot);
+
+ret_code_t es_gatts_write_handle_unlock(nrf_ble_escs_t * p_escs,
+ uint8_t const * p_data,
+ uint16_t length,
+ uint16_t val_handle);
+
+/**
+ * @}
+ */
+
+#endif // ES_GATTS_WRITE_H__
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/eddystone/es_security.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/eddystone/es_security.c
new file mode 100644
index 0000000..303556a
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/eddystone/es_security.c
@@ -0,0 +1,596 @@
+/**
+ * Copyright (c) 2016 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#include <stdbool.h>
+#include <stdint.h>
+#include "es_security.h"
+#include "app_timer.h"
+#include "es_flash.h"
+#include "es_stopwatch.h"
+#include "fds.h"
+#include "modes.h"
+#include "nrf_crypto.h"
+
+#define TK_ROLLOVER 0x10000
+
+#define NONCE_SIZE (6)
+#define TAG_SIZE (2)
+#define SALT_SIZE (2)
+#define TLM_DATA_SIZE (ES_TLM_LENGTH - 2)
+#define EIK_SIZE (ESCS_AES_KEY_SIZE)
+#define AES_ECB_CIPHERTEXT_LENGTH (16)
+#define AES_ECB_CLEARTEXT_LENGTH (16)
+
+/**@brief Timing structure. */
+typedef struct
+{
+ uint32_t time_counter;
+ uint8_t k_scaler;
+} es_security_timing_t;
+
+/**@brief Security slot structure. */
+typedef struct
+{
+ nrf_ecb_hal_data_t aes_ecb_ik;
+ nrf_ecb_hal_data_t aes_ecb_tk;
+ uint8_t eid[ES_EID_ID_LENGTH];
+ es_security_timing_t timing;
+ bool is_occupied;
+} es_security_slot_t;
+
+/**@brief Key pair structure. */
+typedef struct
+{
+ nrf_crypto_ecc_private_key_t private;
+ nrf_crypto_ecc_public_key_t public;
+} ecdh_key_pair_t;
+
+/**@brief ECDH structure. */
+typedef struct
+{
+ ecdh_key_pair_t ecdh_key_pair;
+} es_security_ecdh_t;
+
+static nrf_ecb_hal_data_t m_aes_ecb_lk;
+static es_security_slot_t m_security_slot[APP_MAX_EID_SLOTS];
+static es_security_ecdh_t m_ecdh;
+static es_security_msg_cb_t m_security_callback;
+static es_stopwatch_id_t m_seconds_passed_sw_id;
+
+// Use static context variables to avoid stack allocation.
+static nrf_crypto_aes_context_t m_aes_context;
+static nrf_crypto_hmac_context_t m_hmac_context;
+static nrf_crypto_aead_context_t m_aead_context;
+static nrf_crypto_ecc_key_pair_generate_context_t ecc_key_pair_generate_context;
+static nrf_crypto_ecdh_context_t ecdh_context;
+
+/**@brief Generates a EID with the Temporary Key*/
+static void eid_generate(uint8_t slot_no)
+{
+ ret_code_t err_code;
+ size_t ciphertext_size = AES_ECB_CIPHERTEXT_LENGTH;
+
+ memset(m_security_slot[slot_no].aes_ecb_tk.cleartext, 0, ESCS_AES_KEY_SIZE);
+ m_security_slot[slot_no].aes_ecb_tk.cleartext[11] = m_security_slot[slot_no].timing.k_scaler;
+
+ uint32_t k_bits_cleared_time =
+ (m_security_slot[slot_no].timing.time_counter >> m_security_slot[slot_no].timing.k_scaler)
+ << m_security_slot[slot_no].timing.k_scaler;
+
+ m_security_slot[slot_no].aes_ecb_tk.cleartext[12] =
+ (uint8_t)((k_bits_cleared_time >> 24) & 0xff);
+ m_security_slot[slot_no].aes_ecb_tk.cleartext[13] =
+ (uint8_t)((k_bits_cleared_time >> 16) & 0xff);
+ m_security_slot[slot_no].aes_ecb_tk.cleartext[14] = (uint8_t)((k_bits_cleared_time >> 8) & 0xff);
+ m_security_slot[slot_no].aes_ecb_tk.cleartext[15] = (uint8_t)((k_bits_cleared_time) & 0xff);
+
+ err_code = nrf_crypto_aes_crypt(&m_aes_context,
+ &g_nrf_crypto_aes_ecb_128_info,
+ NRF_CRYPTO_ENCRYPT, // Operation
+ m_security_slot[slot_no].aes_ecb_tk.key, // Key
+ NULL, // IV
+ m_security_slot[slot_no].aes_ecb_tk.cleartext, // Data in
+ AES_ECB_CLEARTEXT_LENGTH, // Data in size
+ m_security_slot[slot_no].aes_ecb_tk.ciphertext, // Data out
+ &ciphertext_size); // Data out size
+
+ APP_ERROR_CHECK(err_code);
+
+ memcpy(m_security_slot[slot_no].eid,
+ m_security_slot[slot_no].aes_ecb_tk.ciphertext,
+ ES_EID_ID_LENGTH);
+
+ m_security_callback(slot_no, ES_SECURITY_MSG_EID);
+}
+
+
+/**@brief Generates a temporary key with the Identity key. */
+static void temp_key_generate(uint8_t slot_no)
+{
+ ret_code_t err_code;
+ size_t ciphertext_size = AES_ECB_CIPHERTEXT_LENGTH;
+
+ memset(m_security_slot[slot_no].aes_ecb_ik.cleartext, 0, ESCS_AES_KEY_SIZE);
+ m_security_slot[slot_no].aes_ecb_ik.cleartext[11] = 0xFF;
+ m_security_slot[slot_no].aes_ecb_ik.cleartext[14] =
+ (uint8_t)((m_security_slot[slot_no].timing.time_counter >> 24) & 0xff);
+ m_security_slot[slot_no].aes_ecb_ik.cleartext[15] =
+ (uint8_t)((m_security_slot[slot_no].timing.time_counter >> 16) & 0xff);
+
+ err_code = nrf_crypto_aes_crypt(&m_aes_context,
+ &g_nrf_crypto_aes_ecb_128_info,
+ NRF_CRYPTO_ENCRYPT, // Operation
+ m_security_slot[slot_no].aes_ecb_ik.key, // Key
+ NULL, // IV
+ m_security_slot[slot_no].aes_ecb_ik.cleartext, // Data in
+ AES_ECB_CLEARTEXT_LENGTH, // Data in size
+ m_security_slot[slot_no].aes_ecb_ik.ciphertext, // Data out
+ &ciphertext_size); // Data out size
+
+ APP_ERROR_CHECK(err_code);
+
+ memcpy(m_security_slot[slot_no].aes_ecb_tk.key,
+ m_security_slot[slot_no].aes_ecb_ik.ciphertext,
+ ESCS_AES_KEY_SIZE);
+}
+
+
+static void check_rollovers_and_update_eid(uint8_t slot_no)
+{
+ if (m_security_slot[slot_no].timing.time_counter % TK_ROLLOVER == 0)
+ {
+ temp_key_generate(slot_no);
+ }
+ /*lint -save -e573 */
+ if ((m_security_slot[slot_no].timing.time_counter %
+ (2 << (m_security_slot[slot_no].timing.k_scaler - 1))) == 0)
+ {
+ eid_generate(slot_no);
+ }
+ /*lint -restore */
+}
+
+
+/**@brief Initialize lock code from flash. If it does not exist, copy from APP_CONFIG_LOCK_CODE.
+ */
+static void lock_code_init(uint8_t * p_lock_buff)
+{
+ ret_code_t err_code;
+
+ err_code = es_flash_access_lock_key(p_lock_buff, ES_FLASH_ACCESS_READ);
+ FLASH_ACCES_ERROR_CHECK_ALLOW_NOT_FOUND(err_code);
+
+ // If no lock keys exist, then generate one and copy it to buffer.
+ if (err_code == FDS_ERR_NOT_FOUND)
+ {
+ uint8_t lock_code[16] = APP_CONFIG_LOCK_CODE;
+
+ memcpy(p_lock_buff, lock_code, sizeof(lock_code));
+
+ err_code = es_flash_access_lock_key(p_lock_buff, ES_FLASH_ACCESS_WRITE);
+ APP_ERROR_CHECK(err_code);
+ }
+}
+
+
+void es_security_update_time(void)
+{
+ static uint32_t timer_persist;
+ uint32_t second_since_last_invocation = es_stopwatch_check(m_seconds_passed_sw_id);
+
+ if (second_since_last_invocation > 0)
+ {
+ for (uint32_t i = 0; i < APP_MAX_EID_SLOTS; ++i)
+ {
+ if (m_security_slot[i].is_occupied)
+ {
+ m_security_slot[i].timing.time_counter += second_since_last_invocation;
+ check_rollovers_and_update_eid(i);
+ }
+ }
+
+ // Every 24 hr, write the new EID timer to flash.
+ timer_persist += second_since_last_invocation;
+ const uint32_t TWENTY_FOUR_HOURS = 60 * 60 * 24;
+ if (timer_persist >= TWENTY_FOUR_HOURS)
+ {
+ for (uint32_t i = 0; i < APP_MAX_EID_SLOTS; ++i)
+ {
+ if (m_security_slot[i].is_occupied)
+ {
+ m_security_callback(i, ES_SECURITY_MSG_STORE_TIME);
+ }
+ }
+ timer_persist = 0;
+ }
+ }
+}
+
+
+void es_security_eid_slots_restore(uint8_t slot_no,
+ uint8_t k_scaler,
+ uint32_t time_counter,
+ const uint8_t * p_ik)
+{
+ m_security_slot[slot_no].timing.k_scaler = k_scaler;
+ m_security_slot[slot_no].timing.time_counter = time_counter;
+ memcpy(m_security_slot[slot_no].aes_ecb_ik.key, p_ik, ESCS_AES_KEY_SIZE);
+ m_security_slot[slot_no].is_occupied = true;
+ m_security_callback(slot_no, ES_SECURITY_MSG_IK);
+ temp_key_generate(slot_no);
+ eid_generate(slot_no);
+}
+
+
+ret_code_t es_security_lock_code_update(uint8_t * p_ecrypted_key)
+{
+ ret_code_t err_code;
+ uint8_t temp_buff[ESCS_AES_KEY_SIZE] = {0};
+ size_t temp_buff_size = sizeof(temp_buff);
+
+ err_code = nrf_crypto_aes_crypt(&m_aes_context,
+ &g_nrf_crypto_aes_ecb_128_info,
+ NRF_CRYPTO_DECRYPT, // Operation
+ m_aes_ecb_lk.key, // Key
+ NULL, // IV
+ p_ecrypted_key, // Data in
+ 16, // Data in size
+ temp_buff, // Data out
+ &temp_buff_size); // Data out size
+
+ VERIFY_SUCCESS(err_code);
+
+ memcpy(m_aes_ecb_lk.key, temp_buff, ESCS_AES_KEY_SIZE);
+ return es_flash_access_lock_key(m_aes_ecb_lk.key, ES_FLASH_ACCESS_WRITE);
+}
+
+
+void es_security_unlock_prepare(uint8_t * p_challenge)
+{
+ ret_code_t err_code;
+ size_t ciphertext_size = AES_ECB_CIPHERTEXT_LENGTH;
+
+ memcpy(m_aes_ecb_lk.cleartext, p_challenge, ESCS_AES_KEY_SIZE);
+
+ err_code = nrf_crypto_aes_crypt(&m_aes_context,
+ &g_nrf_crypto_aes_ecb_128_info,
+ NRF_CRYPTO_ENCRYPT, // Operation
+ m_aes_ecb_lk.key, // Key
+ NULL, // IV
+ m_aes_ecb_lk.cleartext, // Data in
+ AES_ECB_CLEARTEXT_LENGTH, // Data in size
+ m_aes_ecb_lk.ciphertext, // Data out
+ &ciphertext_size); // Data out size
+
+ APP_ERROR_CHECK(err_code);
+}
+
+
+void es_security_unlock_verify(uint8_t * p_unlock_token)
+{
+ if (memcmp(p_unlock_token, m_aes_ecb_lk.ciphertext, ESCS_AES_KEY_SIZE) == 0)
+ {
+ m_security_callback(0, ES_SECURITY_MSG_UNLOCKED);
+ }
+}
+
+
+ret_code_t es_security_random_challenge_generate(uint8_t * p_rand_chlg_buff)
+{
+ return nrf_crypto_rng_vector_generate(p_rand_chlg_buff, ESCS_AES_KEY_SIZE);
+}
+
+
+void es_security_shared_ik_receive(uint8_t slot_no, uint8_t * p_encrypted_ik, uint8_t scaler_k)
+{
+ ret_code_t err_code;
+ size_t cleartext_size = AES_ECB_CLEARTEXT_LENGTH;
+
+ m_security_slot[slot_no].is_occupied = true;
+ m_security_slot[slot_no].timing.k_scaler = scaler_k;
+ m_security_slot[slot_no].timing.time_counter = APP_CONFIG_TIMING_INIT_VALUE;
+
+ err_code = nrf_crypto_aes_crypt(&m_aes_context,
+ &g_nrf_crypto_aes_ecb_128_info,
+ NRF_CRYPTO_DECRYPT, // Operation
+ m_aes_ecb_lk.key, // Key
+ NULL, // IV
+ p_encrypted_ik, // Data in
+ 16, // Data in size
+ m_security_slot[slot_no].aes_ecb_ik.key, // Data out
+ &cleartext_size); // Data out size
+
+ APP_ERROR_CHECK(err_code);
+
+ temp_key_generate(slot_no);
+ eid_generate(slot_no);
+
+ m_security_callback(slot_no, ES_SECURITY_MSG_IK);
+}
+
+
+void es_security_client_pub_ecdh_receive(uint8_t slot_no, uint8_t * p_pub_ecdh, uint8_t scaler_k)
+{
+ ret_code_t err_code;
+ nrf_crypto_ecc_public_key_t phone_public; // Phone public ECDH key
+ uint8_t beacon_public[ESCS_ECDH_KEY_SIZE]; // Beacon public ECDH key
+ uint8_t shared[ESCS_ECDH_KEY_SIZE]; // Shared secret ECDH key
+ uint8_t public_keys[64]; // Buffer for concatenated public keys
+ uint8_t key_material[64]; // Buffer for holding key material
+ uint8_t empty_check[ESCS_ECDH_KEY_SIZE] = {0};
+ size_t beacon_public_size = sizeof(beacon_public);
+ size_t shared_size = sizeof(shared);
+ size_t key_material_size = sizeof(key_material);
+
+ m_security_slot[slot_no].is_occupied = true;
+ m_security_slot[slot_no].timing.k_scaler = scaler_k;
+ m_security_slot[slot_no].timing.time_counter = APP_CONFIG_TIMING_INIT_VALUE;
+
+ // Get public 32-byte service ECDH key from phone.
+ err_code = nrf_crypto_ecc_public_key_from_raw(&g_nrf_crypto_ecc_curve25519_curve_info,
+ &phone_public,
+ p_pub_ecdh,
+ ESCS_ECDH_KEY_SIZE);
+
+ APP_ERROR_CHECK(err_code);
+
+ // Generate key pair.
+ err_code = nrf_crypto_ecc_key_pair_generate(&ecc_key_pair_generate_context,
+ &g_nrf_crypto_ecc_curve25519_curve_info,
+ &m_ecdh.ecdh_key_pair.private,
+ &m_ecdh.ecdh_key_pair.public);
+
+ APP_ERROR_CHECK(err_code);
+
+ // Generate shared 32-byte ECDH secret from beacon private service ECDH key and phone public ECDH key.
+ err_code = nrf_crypto_ecdh_compute(&ecdh_context,
+ &m_ecdh.ecdh_key_pair.private,
+ &phone_public,
+ shared,
+ &shared_size);
+
+ APP_ERROR_CHECK(err_code);
+
+ // Verify that the shared secret is not zero at this point, and report an error/reset if it is.
+ if (memcmp(empty_check, shared, ESCS_ECDH_KEY_SIZE) == 0)
+ {
+ APP_ERROR_CHECK(NRF_ERROR_INTERNAL);
+ }
+
+ // Concatenate the resolver's public key and beacon's public key
+ err_code = nrf_crypto_ecc_public_key_to_raw(&m_ecdh.ecdh_key_pair.public,
+ beacon_public,
+ &beacon_public_size);
+
+ APP_ERROR_CHECK(err_code);
+
+ memcpy(public_keys, p_pub_ecdh, 32);
+ memcpy(public_keys + 32, beacon_public, 32);
+
+ // Convert the shared secret to key material using HKDF-SHA256. HKDF is used with the salt set
+ // to a concatenation of the resolver's public key and beacon's public key
+ err_code = nrf_crypto_hkdf_calculate(&m_hmac_context,
+ &g_nrf_crypto_hmac_sha256_info,
+ key_material, // Output key
+ &key_material_size, // Output key size
+ shared, // Input key
+ sizeof(shared), // Input key size
+ public_keys, // Salt
+ sizeof(public_keys), // Salt size
+ NULL, // Additional info
+ 0, // Additional info size
+ NRF_CRYPTO_HKDF_EXTRACT_AND_EXPAND); // Mode
+
+ APP_ERROR_CHECK(err_code);
+
+ // Truncate the key material to 128 bits to convert it to an AES-128 secret key (Identity key).
+ memcpy(m_security_slot[slot_no].aes_ecb_ik.key, key_material, ESCS_AES_KEY_SIZE);
+
+ temp_key_generate(slot_no);
+ eid_generate(slot_no);
+
+ m_security_callback(slot_no, ES_SECURITY_MSG_ECDH);
+ m_security_callback(slot_no, ES_SECURITY_MSG_IK);
+}
+
+
+void es_security_pub_ecdh_get(uint8_t slot_no, uint8_t * p_edch_buffer)
+{
+ ret_code_t err_code;
+ size_t buffer_size = ESCS_ECDH_KEY_SIZE;
+
+ err_code = nrf_crypto_ecc_public_key_to_raw(&m_ecdh.ecdh_key_pair.public,
+ p_edch_buffer,
+ &buffer_size);
+
+ APP_ERROR_CHECK(err_code);
+}
+
+
+uint32_t es_security_clock_get(uint8_t slot_no)
+{
+ return m_security_slot[slot_no].timing.time_counter;
+}
+
+
+void es_security_eid_slot_destroy(uint8_t slot_no)
+{
+ memset(&m_security_slot[slot_no], 0, sizeof(es_security_slot_t));
+}
+
+
+uint8_t es_security_scaler_get(uint8_t slot_no)
+{
+ return m_security_slot[slot_no].timing.k_scaler;
+}
+
+
+void es_security_eid_get(uint8_t slot_no, uint8_t * p_eid_buffer)
+{
+ memcpy(p_eid_buffer, m_security_slot[slot_no].eid, ES_EID_ID_LENGTH);
+}
+
+
+void es_security_encrypted_eid_id_key_get(uint8_t slot_no, uint8_t * p_key_buffer)
+{
+ ret_code_t err_code;
+ size_t ciphertext_size = AES_ECB_CIPHERTEXT_LENGTH;
+
+ memcpy(m_aes_ecb_lk.cleartext, m_security_slot[slot_no].aes_ecb_ik.key, ESCS_AES_KEY_SIZE);
+
+ err_code = nrf_crypto_aes_crypt(&m_aes_context,
+ &g_nrf_crypto_aes_ecb_128_info,
+ NRF_CRYPTO_ENCRYPT, // Operation
+ m_aes_ecb_lk.key, // Key
+ NULL, // IV
+ m_aes_ecb_lk.cleartext, // Data in
+ AES_ECB_CLEARTEXT_LENGTH, // Data in size
+ m_aes_ecb_lk.ciphertext, // Data out
+ &ciphertext_size); // Data out size
+
+ APP_ERROR_CHECK(err_code);
+
+ memcpy(p_key_buffer, m_aes_ecb_lk.ciphertext, ESCS_AES_KEY_SIZE);
+}
+
+
+void es_security_plain_eid_id_key_get(uint8_t slot_no, uint8_t * p_key_buffer)
+{
+ memcpy(p_key_buffer, m_security_slot[slot_no].aes_ecb_ik.key, ESCS_AES_KEY_SIZE);
+}
+
+
+void es_security_tlm_to_etlm(uint8_t ik_slot_no, es_tlm_frame_t * p_tlm, es_etlm_frame_t * p_etlm)
+{
+ ret_code_t err_code;
+ uint8_t plain[TLM_DATA_SIZE] = {0}; // Plaintext tlm, without the frame byte and version.
+ size_t nplain = TLM_DATA_SIZE; // Length of message plaintext.
+
+ /*lint -save -e420 */
+ memcpy(plain, &p_tlm->vbatt[0], sizeof(plain));
+
+ uint8_t key[EIK_SIZE] = {0}; // Encryption/decryption key: EIK.
+
+ memcpy(key, &m_security_slot[ik_slot_no].aes_ecb_ik.key[0], EIK_SIZE);
+ /*lint -restore */
+
+ uint8_t nonce[NONCE_SIZE] = {0}; // Nonce. This must not repeat for a given key.
+ size_t nnonce = NONCE_SIZE; // Length of nonce.First 4 bytes are beacon time base with k-bits cleared.
+ // Last two bits are randomly generated
+
+ // Take the current timestamp and clear the lowest K bits, use it as nonce.
+ uint32_t k_bits_cleared_time = (m_security_slot[ik_slot_no].timing.time_counter
+ >> m_security_slot[ik_slot_no].timing.k_scaler)
+ << m_security_slot[ik_slot_no].timing.k_scaler;
+
+ nonce[0] = (uint8_t)((k_bits_cleared_time >> 24) & 0xff);
+ nonce[1] = (uint8_t)((k_bits_cleared_time >> 16) & 0xff);
+ nonce[2] = (uint8_t)((k_bits_cleared_time >> 8) & 0xff);
+ nonce[3] = (uint8_t)((k_bits_cleared_time) & 0xff);
+
+ // Generate random salt.
+ uint8_t salt[SALT_SIZE] = {0};
+ err_code = nrf_crypto_rng_vector_generate(salt, SALT_SIZE);
+ APP_ERROR_CHECK(err_code);
+ memcpy(&nonce[4], salt, SALT_SIZE);
+
+ uint8_t cipher[ES_ETLM_ECRYPTED_LENGTH]; // Ciphertext output. nplain bytes are written.
+ uint8_t tag[TAG_SIZE] = {0}; // Authentication tag. ntag bytes are written.
+ size_t ntag = TAG_SIZE; // Length of authentication tag.
+
+ // Encryption
+ // --------------------------------------------------------------------------
+ err_code = nrf_crypto_aead_init(&m_aead_context, &g_nrf_crypto_aes_eax_128_info, key);
+ APP_ERROR_CHECK(err_code);
+
+ err_code = nrf_crypto_aead_crypt(&m_aead_context,
+ NRF_CRYPTO_ENCRYPT, // Operation
+ nonce, // Nonce
+ nnonce, // Nonce size
+ NULL, // Additional authenticated data (adata)
+ 0, // Additional authenticated data size
+ plain, // Input data
+ nplain, // Input data size
+ cipher, // Output data
+ tag, // MAC result output
+ ntag); // MAC size
+
+ APP_ERROR_CHECK(err_code);
+
+ err_code = nrf_crypto_aead_uninit(&m_aead_context);
+ APP_ERROR_CHECK(err_code);
+
+ // Construct the eTLM.
+ // --------------------------------------------------------------------------
+ p_etlm->frame_type = p_tlm->frame_type;
+ p_etlm->version = ES_TLM_VERSION_ETLM;
+ memcpy(p_etlm->encrypted_tlm, cipher, ES_ETLM_ECRYPTED_LENGTH);
+ memcpy((uint8_t *)&p_etlm->random_salt, salt, SALT_SIZE);
+ memcpy((uint8_t *)&p_etlm->msg_integrity_check, tag, TAG_SIZE);
+}
+
+
+ret_code_t es_security_init(es_security_msg_cb_t security_callback)
+{
+ ret_code_t err_code;
+
+ if (security_callback == NULL)
+ {
+ return NRF_ERROR_INVALID_PARAM;
+ }
+
+ // Get lock code from 'es_app_config.h', or fetch it from flash if exists.
+ lock_code_init(m_aes_ecb_lk.key);
+
+ m_security_callback = security_callback;
+
+ memset(&m_ecdh, 0, sizeof(es_security_ecdh_t));
+
+ for (uint32_t i = 0; i < APP_MAX_EID_SLOTS; ++i)
+ {
+ m_security_slot[i].timing.time_counter = APP_CONFIG_TIMING_INIT_VALUE;
+ }
+ err_code = es_stopwatch_create(&m_seconds_passed_sw_id, APP_TIMER_TICKS(1000));
+ APP_ERROR_CHECK(err_code);
+
+ err_code = nrf_crypto_init();
+ APP_ERROR_CHECK(err_code);
+
+ return NRF_SUCCESS;
+}
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/eddystone/es_security.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/eddystone/es_security.h
new file mode 100644
index 0000000..e518ebe
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/eddystone/es_security.h
@@ -0,0 +1,238 @@
+/**
+ * Copyright (c) 2016 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#ifndef ES_SECURITY_H__
+#define ES_SECURITY_H__
+
+#include "app_error.h"
+#include "nrf_ble_escs.h"
+
+/**
+ * @file
+ * @defgroup eddystone_security Security
+ * @brief Types and functions for dealing with security of Eddystone beacons.
+ * @ingroup eddystone
+ * @{
+ */
+
+/**@brief Security events.
+ */
+typedef enum
+{
+ ES_SECURITY_MSG_UNLOCKED, //!< Beacon is unlocked.
+ ES_SECURITY_MSG_EID, //!< EID has been generated.
+ ES_SECURITY_MSG_IK, //!< IK has been generated.
+ ES_SECURITY_MSG_ECDH, //!< Public ECDH has been generated.
+ ES_SECURITY_MSG_STORE_TIME //!< EID slot time must be stored.
+} es_security_msg_t;
+
+/* @brief Callback for security events. */
+typedef void (*es_security_msg_cb_t)(uint8_t slot_no, es_security_msg_t msg_type);
+
+/**@brief EID configuration.
+ *
+ * @details This structure is used to preserve or restore an EID slot.
+ *
+ * @note This is a packed structure. Therefore, you should not change it.
+*/
+typedef PACKED_STRUCT
+{
+ es_frame_type_t frame_type;
+ uint8_t k_scaler;
+ uint32_t time_counter;
+ uint8_t ik[ESCS_AES_KEY_SIZE];
+} es_eid_config_t;
+
+/**@brief Eddystone beacon lock state.
+ */
+typedef nrf_ble_escs_lock_state_read_t es_security_lock_state_t;
+
+/**@brief Function for initializing the security module.
+ *
+ * @param[in] msg_cb Callback function.
+ *
+ * @return See @ref app_timer_start for possible return values.
+ */
+ret_code_t es_security_init(es_security_msg_cb_t msg_cb);
+
+/**@brief Function for updating the lock code and storing it to flash.
+ *
+ * @param[in] p_encrypted_key Pointer to the new lock code.
+ *
+ * @return See @ref es_flash_access_lock_key for possible return values.
+ */
+ret_code_t es_security_lock_code_update(uint8_t * p_encrypted_key);
+
+/**@brief Function for reading the challenge and encrypting it with AES_ECB.
+ *
+ * @details The result of the encryption is compared with the provided unlock token
+ * in @ref es_security_unlock_verify.
+ *
+ * @param[in] p_challenge Pointer to the challenge buffer.
+ *
+ * @return See @ref sd_ecb_block_encrypt for possible return values.
+ */
+void es_security_unlock_prepare(uint8_t * p_challenge);
+
+/**@brief Function for unlocking the beacon.
+ *
+ * @details This function compares the result from @ref es_security_unlock_prepare to the input
+ * unlock token and unlocks the beacon if matching.
+ *
+ * @param[in] p_unlock_token The unlock token written by the client.
+ */
+void es_security_unlock_verify(uint8_t * p_unlock_token);
+
+/**@brief Function for generating a random challenge for the unlock characteristic.
+ *
+ * @param[out] p_rand_chlg_buff Pointer to a buffer to which the random challenge is copied.
+ *
+ * @return See @ref sd_rand_application_vector_get for possible return values.
+ */
+ret_code_t es_security_random_challenge_generate(uint8_t * p_rand_chlg_buff);
+
+/**@brief Function for storing the public ECDH key from the client in the beacon registration process.
+ *
+ * @details This function starts a series of cryptographic activities, including the generation of temporary keys and EIDs.
+ *
+ * @param[in] slot_no The index of the slot whose public ECDH key is retrieved.
+ * @param[in] p_pub_ecdh Pointer to the public ECDH.
+ * @param[in] scaler_k K rotation scaler.
+ */
+void es_security_client_pub_ecdh_receive(uint8_t slot_no, uint8_t * p_pub_ecdh, uint8_t scaler_k);
+
+
+/**@brief Function for storing the shared IK from the client in the beacon registration process.
+ *
+ * @details This function starts a series of cryptographic activities, including the generation of temporary keys and EIDs.
+ *
+ * @param[in] slot_no The index of the slot whose public ECDH key is retrieved.
+ * @param[in] p_encrypted_ik Pointer to the received IK.
+ * @param[in] scaler_k K rotation scaler.
+ */
+void es_security_shared_ik_receive(uint8_t slot_no, uint8_t * p_encrypted_ik, uint8_t scaler_k);
+
+/**@brief Function for copying the 32-byte ECDH key into the provided buffer.
+ *
+ * @param[in] slot_no The index of the slot whose public ECDH key is retrieved.
+ * @param[out] p_edch_buffer Pointer to the buffer.
+ */
+void es_security_pub_ecdh_get(uint8_t slot_no, uint8_t * p_edch_buffer);
+
+/**@brief Function for returning the beacon clock value (in little endian).
+ *
+ * @param[in] slot_no The index of the slot.
+ *
+ * @return 32-bit clock value.
+ */
+uint32_t es_security_clock_get(uint8_t slot_no);
+
+/**@brief Function for updating the beacon time counter.
+ *
+ * @details This function checks how much time has passed since the last
+ * invocation and, if required, updates the EID, the temporary key, or both.
+ * The function generates an @ref ES_SECURITY_MSG_STORE_TIME event
+ * for each active security slot every 24 hours.
+ */
+void es_security_update_time(void);
+
+/**@brief Function for returning the rotation exponent scaler value.
+ *
+ * @param[in] slot_no The index of the slot.
+ *
+ * @return K rotation scaler.
+ */
+uint8_t es_security_scaler_get(uint8_t slot_no);
+
+/**@brief Function for copying the 8-byte EID into the provided buffer.
+ *
+ * @param[in] slot_no The index of the slot whose EID is retrieved.
+ * @param[out] p_eid_buffer Pointer to the buffer.
+ */
+void es_security_eid_get(uint8_t slot_no, uint8_t * p_eid_buffer);
+
+/**@brief Function for restoring an EID slot.
+ *
+ * @param[in] slot_no The index of the slot to restore.
+ * @param[in] k_scaler K rotation scaler.
+ * @param[in] time_counter EID slot time counter value (in seconds).
+ * @param[in] p_ik Pointer to the identity key of the specified slot.
+ */
+void es_security_eid_slots_restore(uint8_t slot_no,
+ uint8_t k_scaler,
+ uint32_t time_counter,
+ const uint8_t * p_ik);
+
+/**@brief Function for destroying stored EID states.
+ *
+ * @details This function should be called when the slot is either overwritten as another slot or
+ * cleared by writing an empty byte or a single 0.
+ *
+ * @param[in] slot_no The index of the slot to destroy.
+ */
+void es_security_eid_slot_destroy(uint8_t slot_no);
+
+/**@brief Function for copying the 16-byte EID ID key into the provided buffer.
+ *
+ * @param[in] slot_no The index of the EID slot whose IK is retrieved.
+ * @param[out] p_key_buffer Buffer for the key.
+ */
+void es_security_plain_eid_id_key_get(uint8_t slot_no, uint8_t * p_key_buffer);
+
+/**@brief Function for copying the 16-byte LK encrypted EID ID key into the provided buffer.
+ *
+ * @param[in] slot_no The index of the EID slot whose encrypted IK is retrieved.
+ * @param[out] p_key_buffer Buffer for the key.
+ */
+void es_security_encrypted_eid_id_key_get(uint8_t slot_no, uint8_t * p_key_buffer);
+
+
+/**@brief Function for converting a TLM frame into an eTLM frame using the EIK of the specified slot.
+ *
+ * @param[in] ik_slot_no The index of the EID slot whose IK is paired with the eTLM.
+ * @param[in] p_tlm Pointer to the TLM frame buffer.
+ * @param[out] p_etlm Pointer to the eTLM frame buffer.
+ */
+void es_security_tlm_to_etlm(uint8_t ik_slot_no, es_tlm_frame_t * p_tlm, es_etlm_frame_t * p_etlm);
+
+/**
+ * @}
+ */
+
+#endif // ES_SECURITY_H__
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/eddystone/es_slot.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/eddystone/es_slot.c
new file mode 100644
index 0000000..55590a7
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/eddystone/es_slot.c
@@ -0,0 +1,440 @@
+/**
+ * Copyright (c) 2016 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#include <stdint.h>
+#include <string.h>
+#include "es_slot.h"
+#include "es_flash.h"
+#include "es_security.h"
+#include "es_slot_reg.h"
+#include "es_tlm.h"
+#include "fds.h"
+
+static es_slot_reg_t m_reg; //!< Slot registry.
+static bool m_eid_loaded_from_flash; //!< Set to true if EID slot has been loaded from flash.
+
+#define RANGING_DATA_INDEX (1) //!< Index of ranging data within frames that contain ranging data.
+#define RANGING_DATA_LENGTH (1) //!< Length of ranging data.
+
+/**@brief Enforce legal slot number.
+ *
+ * @param[in] p_slot Pointer to the slot number variable to check.
+ */
+static void slot_boundary_check(uint8_t * p_slot)
+{
+ if (*p_slot > (APP_MAX_ADV_SLOTS - 1))
+ {
+ *p_slot = (APP_MAX_ADV_SLOTS - 1);
+ }
+}
+
+
+/**@brief Function loading slot data from flash.
+ *
+ * @param[in] slot_no Slot number to be used.
+ */
+static void load_slot_from_flash(uint8_t slot_no)
+{
+ ret_code_t err_code;
+
+ err_code = es_flash_access_slot_configs(slot_no, &m_reg.slots[slot_no], ES_FLASH_ACCESS_READ);
+ if (err_code != FDS_ERR_NOT_FOUND)
+ {
+ APP_ERROR_CHECK(err_code);
+
+ if (m_reg.slots[slot_no].adv_frame.type == ES_FRAME_TYPE_EID)
+ {
+ m_eid_loaded_from_flash = true;
+
+ es_security_eid_slots_restore(slot_no,
+ m_reg.slots[slot_no].k_scaler,
+ m_reg.slots[slot_no].seconds,
+ (const uint8_t *)m_reg.slots[slot_no].ik);
+ }
+
+ else
+ {
+ // If a non-EID slot has been loaded, update the state of m_reg immediately.
+ es_slot_reg_update_slot_list_info_on_add(&m_reg, slot_no, m_reg.slots[slot_no].adv_frame.type, true);
+ }
+ }
+}
+
+
+/**@brief Function for setting the ranging data field to be broadcast in the frame.
+ *
+ * @param[in] slot_no The slot index.
+ * @param[in] tx_power The radio tx power to be calibrated to ranging data.
+ */
+static void set_ranging_data_for_slot(uint8_t slot_no, nrf_ble_escs_radio_tx_pwr_t tx_power)
+{
+ int8_t ranging_data_array[ESCS_NUM_OF_SUPPORTED_TX_POWER] = APP_CONFIG_CALIBRATED_RANGING_DATA;
+ nrf_ble_escs_radio_tx_pwr_t supported_tx[ESCS_NUM_OF_SUPPORTED_TX_POWER] =
+ ESCS_SUPPORTED_TX_POWER;
+
+ int8_t ranging_data = 0;
+
+ if (m_reg.slots[slot_no].adv_custom_tx_power)
+ {
+ ranging_data = m_reg.slots[slot_no].custom_tx_power;
+ }
+
+ else
+ {
+ for (uint32_t i = 0; i < ESCS_NUM_OF_SUPPORTED_TX_POWER; ++i)
+ {
+ if (supported_tx[i] >= tx_power)
+ {
+ ranging_data = ranging_data_array[i];
+ break;
+ }
+ }
+ }
+ es_adv_frame_t * frame = &m_reg.slots[slot_no].adv_frame;
+ switch (frame->type)
+ {
+ case ES_FRAME_TYPE_UID:
+ {
+ es_uid_frame_t * uid = &frame->frame.uid;
+ uid->ranging_data = ranging_data;
+ break;
+ }
+
+ case ES_FRAME_TYPE_URL:
+ {
+ es_url_frame_t * url = &frame->frame.url;
+ url->ranging_data = ranging_data;
+ break;
+ }
+
+ case ES_FRAME_TYPE_EID:
+ {
+ es_eid_frame_t * eid = &frame->frame.eid;
+ eid->ranging_data = ranging_data;
+ break;
+ }
+
+ case ES_FRAME_TYPE_TLM:
+ APP_ERROR_CHECK(NRF_ERROR_INVALID_PARAM);
+ break;
+ }
+}
+
+
+/**@brief Function configuring a non-EID slot.
+ *
+ * @param[in] slot_no Slot number to be used.
+ * @param[in] length Length of write operation.
+ * @param[in] p_frame_data Pointer to written data.
+ */
+static void configure_slot(uint8_t slot_no, uint8_t length, uint8_t const * p_frame_data)
+{
+ // If a TLM slot is being configured and there already exists a TLM.
+ if ((es_frame_type_t)p_frame_data[0] == ES_FRAME_TYPE_TLM && m_reg.tlm_configured)
+ {
+ return; // Silently ignore any attempts to create more than one TLM slot as there is no point.
+ }
+
+ es_slot_reg_update_slot_list_info_on_add(&m_reg, slot_no, (es_frame_type_t)p_frame_data[0], false);
+
+ // For convenience, frame_type is stored in two places, set both.
+ m_reg.slots[slot_no].adv_frame.type = (es_frame_type_t)p_frame_data[0];
+ memcpy(&m_reg.slots[slot_no].adv_frame.frame, &m_reg.slots[slot_no].adv_frame.type, 1);
+
+ uint8_t * p_data_after_ranging_data = ((uint8_t *)(&m_reg.slots[slot_no].adv_frame.frame) +
+ RANGING_DATA_INDEX + RANGING_DATA_LENGTH);
+
+ switch (m_reg.slots[slot_no].adv_frame.type)
+ {
+ case ES_FRAME_TYPE_UID:
+ // Fall through.
+ case ES_FRAME_TYPE_URL:
+ memcpy(p_data_after_ranging_data, &p_frame_data[1], length - 1);
+ set_ranging_data_for_slot(slot_no, APP_CFG_DEFAULT_RADIO_TX_POWER);
+ m_reg.slots[slot_no].adv_frame.length = length + 1; // + 1 for ranging data
+ break;
+
+ case ES_FRAME_TYPE_TLM:
+ es_tlm_tlm_get(&m_reg.slots[slot_no].adv_frame.frame.tlm);
+ m_reg.slots[slot_no].adv_frame.length = ES_TLM_LENGTH;
+ break;
+
+ default:
+ break;
+ }
+}
+
+
+/**@brief Function configuring an EID slot.
+ *
+ * @param[in] slot_no Slot number to be used.
+ * @param[in] length Length of write operation.
+ * @param[in] p_frame_data Pointer to written data.
+ */
+static void configure_eid_slot(uint8_t slot_no, uint8_t length, uint8_t const * p_frame_data)
+{
+ bool clear_eid_slot = false;
+
+ // Do not update slot count, as this will be done when in the callback invoked when the EID data
+ // is ready.
+ // As it takes a while to do the calculation, temporarily remove the slot being overwritten.
+ // The slot will be re-added in the callback invoked when the EID data is ready.
+ clear_eid_slot = es_slot_reg_clear_slot(&m_reg, slot_no);
+
+ if (clear_eid_slot)
+ {
+ es_security_eid_slot_destroy(slot_no);
+ }
+
+ if (p_frame_data[0] != ES_FRAME_TYPE_EID)
+ {
+ APP_ERROR_CHECK(NRF_ERROR_INVALID_STATE);
+ }
+
+ if (length == ESCS_EID_WRITE_ECDH_LENGTH)
+ {
+ es_security_client_pub_ecdh_receive(slot_no,
+ (uint8_t*)&p_frame_data[ESCS_EID_WRITE_PUB_KEY_INDEX],
+ p_frame_data[ESCS_EID_WRITE_ECDH_LENGTH -1]);
+ }
+
+ else if (length == ESCS_EID_WRITE_IDK_LENGTH)
+ {
+ es_security_shared_ik_receive(slot_no,
+ (uint8_t*)&p_frame_data[ESCS_EID_WRITE_ENC_ID_KEY_INDEX],
+ p_frame_data[ESCS_EID_WRITE_IDK_LENGTH - 1]);
+ }
+
+ else
+ {
+ // Invalid length being written.
+ APP_ERROR_CHECK(NRF_ERROR_INVALID_PARAM);
+ }
+}
+
+
+ret_code_t es_slot_write_to_flash(uint8_t slot_no)
+{
+ if (m_reg.slots[slot_no].configured)
+ {
+ // If its an EID, we need to store some metadata in order to re-initialize the EID.
+ if (m_reg.slots[slot_no].adv_frame.type == ES_FRAME_TYPE_EID)
+ {
+ m_reg.slots[slot_no].seconds = es_security_clock_get(slot_no);
+ m_reg.slots[slot_no].k_scaler = es_security_scaler_get(slot_no);
+ es_security_plain_eid_id_key_get(slot_no, m_reg.slots[slot_no].ik);
+ }
+ return es_flash_access_slot_configs(slot_no, &m_reg.slots[slot_no], ES_FLASH_ACCESS_WRITE);
+ }
+
+ else
+ {
+ return es_flash_access_slot_configs(slot_no, NULL, ES_FLASH_ACCESS_CLEAR);
+ }
+}
+
+
+void es_slot_radio_tx_pwr_set(uint8_t slot_no, nrf_ble_escs_radio_tx_pwr_t radio_tx_pwr)
+{
+ slot_boundary_check(&slot_no);
+
+ m_reg.slots[slot_no].radio_tx_pwr = radio_tx_pwr;
+
+ if (!m_reg.slots[slot_no].adv_custom_tx_power) // Only update TX power in ADV if custom TX power is not set
+ {
+ set_ranging_data_for_slot(slot_no, radio_tx_pwr);
+ }
+}
+
+
+void es_slot_set_adv_custom_tx_power(uint8_t slot_no, nrf_ble_escs_adv_tx_pwr_t tx_pwr)
+{
+ slot_boundary_check(&slot_no);
+
+ m_reg.slots[slot_no].adv_custom_tx_power = true;
+ m_reg.slots[slot_no].custom_tx_power = tx_pwr;
+ set_ranging_data_for_slot(slot_no, tx_pwr);
+}
+
+
+void es_slot_on_write(uint8_t slot_no, uint8_t length, uint8_t const * p_frame_data)
+{
+ slot_boundary_check(&slot_no);
+
+ if (p_frame_data == NULL)
+ {
+ APP_ERROR_CHECK(NRF_ERROR_NULL);
+ }
+
+ // Cleared
+ if (length == 0 || (length == 1 && p_frame_data[0] == 0))
+ {
+ (void)es_slot_reg_clear_slot(&m_reg, slot_no);
+ }
+ // EID slot being configured
+ else if (p_frame_data[0] == ES_FRAME_TYPE_EID &&
+ (length == ESCS_EID_WRITE_ECDH_LENGTH || length == ESCS_EID_WRITE_IDK_LENGTH))
+ {
+ if (m_reg.slots[slot_no].configured)
+ (void)es_slot_reg_clear_slot(&m_reg, slot_no);
+ configure_eid_slot(slot_no, length, p_frame_data);
+ }
+ // Non-EID slot configured.
+ else
+ {
+ if (m_reg.slots[slot_no].configured)
+ (void)es_slot_reg_clear_slot(&m_reg, slot_no);
+ configure_slot(slot_no, length, p_frame_data);
+ }
+}
+
+
+void es_slot_encrypted_eid_id_key_set(uint8_t slot_no, nrf_ble_escs_eid_id_key_t * p_eid_id_key)
+{
+ slot_boundary_check(&slot_no);
+ if (p_eid_id_key != NULL)
+ {
+ memcpy(&(m_reg.slots[slot_no].encrypted_eid_id_key), p_eid_id_key,
+ sizeof(nrf_ble_escs_eid_id_key_t));
+ }
+}
+
+
+void es_slot_eid_ready(uint8_t slot_no)
+{
+ m_reg.slots[slot_no].adv_frame.type = ES_FRAME_TYPE_EID;
+ m_reg.slots[slot_no].adv_frame.length = ES_EID_LENGTH;
+ es_security_eid_get(slot_no, (uint8_t *)m_reg.slots[slot_no].adv_frame.frame.eid.eid);
+ m_reg.slots[slot_no].adv_frame.frame.eid.frame_type = ES_FRAME_TYPE_EID;
+ set_ranging_data_for_slot(slot_no, m_reg.slots[slot_no].radio_tx_pwr);
+
+ if (m_eid_loaded_from_flash)
+ {
+ es_slot_reg_update_slot_list_info_on_add(&m_reg, slot_no, ES_FRAME_TYPE_EID, true);
+ m_eid_loaded_from_flash = false;
+ }
+
+ else
+ {
+ es_slot_reg_update_slot_list_info_on_add(&m_reg, slot_no, ES_FRAME_TYPE_EID, false);
+ }
+}
+
+
+static bool slot_is_eid(uint8_t eid_slot_no)
+{
+ for (uint32_t i = 0; i < m_reg.num_configured_eid_slots; ++i)
+ {
+ if (m_reg.eid_slots_configured[i] == eid_slot_no)
+ {
+ return true;
+ }
+ }
+
+ return false;
+}
+
+
+void es_slot_tlm_update(void)
+{
+ if (m_reg.tlm_configured)
+ {
+ es_tlm_tlm_get(&m_reg.slots[m_reg.tlm_slot].adv_frame.frame.tlm);
+ }
+}
+
+
+void es_slot_etlm_update(uint8_t eid_slot_no)
+{
+ es_tlm_frame_t tlm;
+ es_etlm_frame_t etlm;
+
+ // Ignore the request if eTLM is not required or slot no does not correspond to an EID slot.
+ if (!es_slot_reg_etlm_required(&m_reg) || !slot_is_eid(eid_slot_no))
+ {
+ return;
+ }
+
+ es_tlm_tlm_get(&tlm);
+
+ es_security_tlm_to_etlm(eid_slot_no, &tlm, &etlm);
+
+ memcpy(&m_reg.slots[m_reg.tlm_slot].adv_frame.frame.etlm, &etlm, sizeof(es_etlm_frame_t));
+ m_reg.slots[m_reg.tlm_slot].adv_frame.length = sizeof(es_etlm_frame_t);
+}
+
+
+const es_slot_reg_t * es_slot_get_registry(void)
+{
+ return (const es_slot_reg_t *)&m_reg;
+}
+
+
+void es_slots_init(const es_slot_t * p_default_slot)
+{
+ ret_code_t err_code;
+ es_flash_flags_t flash_flags = {{0}};
+
+ es_slot_reg_init(&m_reg);
+
+ m_eid_loaded_from_flash = false;
+
+ // Read the flash flags to see if there are any previously stored slot configs
+ err_code = es_flash_access_flags(&flash_flags, ES_FLASH_ACCESS_READ);
+
+ if (err_code == FDS_ERR_NOT_FOUND)
+ {
+ // Factory reset or initial boot, load default data
+ memcpy(&m_reg.slots[0], p_default_slot, sizeof(*p_default_slot));
+ es_slot_reg_update_slot_list_info_on_add(&m_reg, 0, p_default_slot->adv_frame.type, true);
+ }
+
+ else
+ {
+ APP_ERROR_CHECK(err_code);
+
+ for (uint32_t i = 0; i < APP_MAX_ADV_SLOTS; ++i)
+ {
+ if (!flash_flags.slot_is_empty[i])
+ {
+ load_slot_from_flash(i);
+ }
+ }
+ }
+}
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/eddystone/es_slot.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/eddystone/es_slot.h
new file mode 100644
index 0000000..5b7482e
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/eddystone/es_slot.h
@@ -0,0 +1,202 @@
+/**
+ * Copyright (c) 2016 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#ifndef ES_SLOT_H__
+#define ES_SLOT_H__
+
+#include <stdint.h>
+#include "es_app_config.h"
+#include "nrf_ble_escs.h"
+
+/**
+ * @file
+ * @defgroup eddystone_slot Slots
+ * @brief Types and functions for handling Eddystone slots.
+ * @ingroup eddystone
+ * @{
+ */
+
+/**@brief Advertisable frame types that can be passed in to the advertising
+ * data during non-connectable slot advertising. */
+
+typedef struct
+{
+ union
+ {
+ es_uid_frame_t uid; //!< UID frame.
+ es_url_frame_t url; //!< URL frame.
+ es_tlm_frame_t tlm; //!< TLM frame.
+ es_eid_frame_t eid; //!< EID frame.
+ es_etlm_frame_t etlm; //!< eTLM frame.
+ } frame;
+ es_frame_type_t type; //!< Type defined twice for convenience (because the other one is inside a union).
+ uint8_t length;
+}es_adv_frame_t;
+
+/**@brief Slot. */
+typedef struct
+{
+ uint8_t slot_no; //!< Identifier for the slot, indexed at 0.
+ nrf_ble_escs_radio_tx_pwr_t radio_tx_pwr; //!< Radio TX power (in dB).
+ nrf_ble_escs_eid_id_key_t encrypted_eid_id_key; //!< EID key for the slot.
+ es_adv_frame_t adv_frame; //!< Frame structure to be passed in for advertising data.
+ bool adv_custom_tx_power; //!< Flag that specifies if the client has written to the 'Advertised TX Power' field of this slot.
+ nrf_ble_escs_radio_tx_pwr_t custom_tx_power; //!< Custom TX power to advertise (only if @ref adv_custom_tx_power is true).
+ bool configured; //!< Is this slot configured and active.
+ uint8_t k_scaler;
+ uint32_t seconds;
+ uint8_t ik[ESCS_AES_KEY_SIZE];
+} es_slot_t;
+
+/**@brief Slot registry. */
+typedef struct
+{
+ es_slot_t slots[APP_MAX_ADV_SLOTS];
+ uint8_t num_configured_slots;
+ uint8_t num_configured_eid_slots;
+ uint8_t slots_configured[APP_MAX_ADV_SLOTS];
+ uint8_t eid_slots_configured[APP_MAX_EID_SLOTS];
+ uint8_t tlm_slot;
+ bool tlm_configured;
+ uint8_t scaler_k;
+ uint8_t enc_key[ESCS_AES_KEY_SIZE];
+} es_slot_reg_t;
+
+/**@brief Function for initializing the Eddystone slots with default values.
+ *
+ * @details This function synchronizes all slots with the initial values.
+ *
+ * @param[in] p_default_slot Pointer to the default parameters for a slot.
+ */
+void es_slots_init(const es_slot_t * p_default_slot);
+
+/**@brief Function for setting the advertising interval of the specified slot.
+ *
+ * For compatibility with the Eddystone specifications, @p p_adv_interval must point to
+ * a 16-bit big endian value (coming from the characteristic write request),
+ * which is then converted to a little endian value inside the function before
+ * it is written into the variable in the slot.
+ *
+ * @parameternoteslot
+ * @parameternoteadv
+ *
+ * @param[in] slot_no The index of the slot.
+ * @param[in,out] p_adv_interval Pointer to the advertisement interval (in ms) to set.
+ * @param[in] global Flag that should be set if the beacon does not support variable advertising intervals.
+ */
+void es_slot_adv_interval_set(uint8_t slot_no,
+ nrf_ble_escs_adv_interval_t * p_adv_interval,
+ bool global);
+
+/**@brief Function for setting the TX power of the specified slot.
+ *
+ * @parameternoteslot
+ * @parameternotetxpower
+ *
+ * @param[in] slot_no The index of the slot.
+ * @param[in,out] radio_tx_pwr TX power value to set.
+ */
+void es_slot_radio_tx_pwr_set(uint8_t slot_no, nrf_ble_escs_radio_tx_pwr_t radio_tx_pwr);
+
+/**@brief Function for setting the R/W ADV of the specified slot.
+ *
+ * @parameternoteslot
+ *
+ * @param[in] slot_no The index of the slot.
+ * @param[in,out] length The length of the data written or read.
+ * @param[in,out] p_frame_data Pointer to the data.
+ *
+ */
+void es_slot_on_write(uint8_t slot_no, uint8_t length, uint8_t const * p_frame_data);
+
+/**@brief Function for writing the slot's configuration to flash.
+ *
+ * @param[in] slot_no The index of the slot.
+ */
+ret_code_t es_slot_write_to_flash(uint8_t slot_no);
+
+/**@brief Function for setting the slot's encrypted EID Identity Key to be displayed in the EID Identity Key characteristic.
+ *
+ * @parameternoteslot
+ *
+ * @param[in] slot_no The index of the slot.
+ * @param[in,out] p_eid_id_key Pointer to a @ref nrf_ble_escs_eid_id_key_t structure from where the key will be written.
+ */
+void es_slot_encrypted_eid_id_key_set(uint8_t slot_no, nrf_ble_escs_eid_id_key_t * p_eid_id_key);
+
+/**@brief Function for marking an EID slot as ready for populating.
+ *
+ * @details Call this function when an EID has been generated and the advertisement frame can be populated with the EID.
+ *
+ * @param[in] slot_no The index of the slot.
+ */
+void es_slot_eid_ready(uint8_t slot_no);
+
+/**@brief Function for updating the TLM slot with updated data. */
+void es_slot_tlm_update(void);
+
+/**@brief Function for updating the TLM slot with eTLM data.
+ *
+ * @details This function uses the EID identity key from the given EID slot number to update the TLM slot.
+ *
+ * @param[in] eid_slot_no EID slot to get EID identity key from.
+ */
+void es_slot_etlm_update(uint8_t eid_slot_no);
+
+/**@brief Function for getting a pointer to the slot registry.
+ *
+ * @return A pointer to the slot registry.
+ */
+const es_slot_reg_t * es_slot_get_registry(void);
+
+/**@brief Function for setting a custom advertisement TX power for a given slot.
+ *
+ * @parameternoteslot
+ * @parameternotetxpower
+ *
+ * @param[in] slot_no The index of the slot.
+ * @param[in] tx_pwr Advertised TX power to be set.
+ */
+void es_slot_set_adv_custom_tx_power(uint8_t slot_no, nrf_ble_escs_adv_tx_pwr_t tx_pwr);
+
+/**
+ * @}
+ */
+
+#endif // ES_SLOT_H__
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/eddystone/es_slot_reg.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/eddystone/es_slot_reg.c
new file mode 100644
index 0000000..f789e6b
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/eddystone/es_slot_reg.c
@@ -0,0 +1,181 @@
+/**
+ * Copyright (c) 2016 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#include "es_slot_reg.h"
+
+#define ES_SLOT_NOT_CONFIGURED 0xab /** Value set in configured lists to indicate not configured slot. */
+
+/**@brief Function updating 'tlm_configured' property of slot registry when slot is being cleared.
+ *
+ * @param[in] p_reg Pointer to slot registry.
+ * @param[in] slot_no Slot number to be used.
+ */
+static void update_tlm_configured_on_clearing(es_slot_reg_t * p_reg, uint8_t slot_no)
+{
+ if (p_reg->tlm_configured && slot_no == p_reg->tlm_slot)
+ {
+ p_reg->tlm_configured = false;
+ }
+}
+
+
+/**@brief Function updating 'num_configured_slots' and 'slots_configured' properties of slot registry when slot is being cleared.
+ *
+ * @param[in] p_configured Pointer to list of configured slots.
+ * @param[in] p_num_configured_slots Pointer to number of configured slots.
+ * @param[in] slot_no Slot number to clear.
+ */
+static void configured_slots_on_clear_update(uint8_t * p_configured, uint8_t * p_num_configured_slots, uint8_t slot_no)
+{
+ uint8_t index_of_last_configured_slot = *p_num_configured_slots - 1;
+
+ for (uint32_t i = 0; i < APP_MAX_ADV_SLOTS; ++i)
+ {
+ if (p_configured[i] == slot_no)
+ {
+ // Copy all values 'to the right' of the cleared slot one step to the left.
+ if (i < index_of_last_configured_slot)
+ {
+ for (uint32_t j = i; j < index_of_last_configured_slot; ++j)
+ {
+ p_configured[j] = p_configured[j + 1];
+ }
+ // Write ES_SLOT_NOT_CONFIGURED to all rightmost not configured indexes.
+ memset(&p_configured[index_of_last_configured_slot],
+ ES_SLOT_NOT_CONFIGURED,
+ APP_MAX_ADV_SLOTS - index_of_last_configured_slot);
+ }
+
+ else
+ {
+ // There are no values 'to the right', simply overwrite with ES_SLOT_NOT_CONFIGURED
+ p_configured[i] = ES_SLOT_NOT_CONFIGURED;
+ }
+
+ *p_num_configured_slots -= 1;
+
+ return;
+ }
+ }
+}
+
+
+bool es_slot_reg_etlm_required(const es_slot_reg_t * p_reg)
+{
+ return (p_reg->num_configured_eid_slots > 0 && p_reg->tlm_configured);
+}
+
+
+bool es_slot_reg_clear_slot(es_slot_reg_t * p_reg, uint8_t slot_no)
+{
+ bool eid_has_been_cleared = false;
+
+ if (p_reg->slots[slot_no].configured)
+ {
+ update_tlm_configured_on_clearing(p_reg, slot_no);
+
+ configured_slots_on_clear_update(p_reg->slots_configured,
+ &p_reg->num_configured_slots,
+ slot_no);
+
+ if (p_reg->slots[slot_no].adv_frame.type == ES_FRAME_TYPE_EID)
+ {
+ configured_slots_on_clear_update(p_reg->eid_slots_configured,
+ &p_reg->num_configured_eid_slots,
+ slot_no);
+
+ eid_has_been_cleared = true;
+ }
+
+ p_reg->slots[slot_no].configured = false;
+ }
+
+ memset(&p_reg->slots[slot_no], 0, sizeof(p_reg->slots[slot_no]));
+
+ return eid_has_been_cleared;
+}
+
+
+void es_slot_reg_update_slot_list_info_on_add(es_slot_reg_t * p_reg,
+ uint8_t slot_no,
+ es_frame_type_t frame_type,
+ bool init)
+{
+ if (frame_type == ES_FRAME_TYPE_TLM)
+ {
+ p_reg->tlm_configured = true;
+ p_reg->tlm_slot = slot_no;
+ }
+
+ if (!p_reg->slots[slot_no].configured || init)
+ {
+ p_reg->slots[slot_no].configured = true;
+
+ // Note, we use 'num_configured_slots' before incrementing it, so it is pointing to the correct index.
+ p_reg->slots_configured[p_reg->num_configured_slots] = slot_no;
+
+ p_reg->num_configured_slots++;
+
+ if (frame_type == ES_FRAME_TYPE_EID)
+ {
+ p_reg->eid_slots_configured[p_reg->num_configured_eid_slots] = slot_no;
+
+ p_reg->num_configured_eid_slots++;
+ }
+ }
+
+ // If an already configured slot has changed from anything TO an EID slot.
+ else if (frame_type == ES_FRAME_TYPE_EID &&
+ p_reg->slots[slot_no].adv_frame.type != ES_FRAME_TYPE_EID)
+ {
+ p_reg->eid_slots_configured[p_reg->num_configured_eid_slots] = slot_no;
+
+ p_reg->num_configured_eid_slots++;
+ }
+}
+
+
+void es_slot_reg_init(es_slot_reg_t * p_reg)
+{
+ p_reg->tlm_configured = false;
+ memset(p_reg->slots_configured, ES_SLOT_NOT_CONFIGURED, APP_MAX_ADV_SLOTS);
+ memset(p_reg->eid_slots_configured, ES_SLOT_NOT_CONFIGURED, APP_MAX_EID_SLOTS);
+ p_reg->num_configured_eid_slots = 0;
+ p_reg->num_configured_slots = 0;
+}
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/eddystone/es_slot_reg.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/eddystone/es_slot_reg.h
new file mode 100644
index 0000000..5f34d55
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/eddystone/es_slot_reg.h
@@ -0,0 +1,90 @@
+/**
+ * Copyright (c) 2016 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#ifndef ES_SLOT_REG_H__
+#define ES_SLOT_REG_H__
+
+#include <stdint.h>
+#include "es_slot.h"
+
+/**
+ * @file
+ * @addtogroup eddystone_slot
+ * @{
+ */
+
+/** @brief Function for checking if an eTLM frame is required.
+ *
+ * @param[in] p_reg Pointer to the slot registry.
+ *
+ * @retval true If an eTLM frame is required.
+ * @retval false Otherwise.
+ */
+bool es_slot_reg_etlm_required(const es_slot_reg_t * p_reg);
+
+/** @brief Function for clearing a slot.
+ *
+ * @param[in] p_reg Pointer to the slot registry.
+ * @param[in] slot_no The slot number to clear.
+ *
+ * @retval true If an EID slot was cleared.
+ */
+bool es_slot_reg_clear_slot(es_slot_reg_t * p_reg, uint8_t slot_no);
+
+/** @brief Function for updating the state of the slot registry after adding a slot.
+ *
+ * @param[in] p_reg Pointer to the slot registry.
+ * @param[in] slot_no The slot number that was added.
+ * @param[in] frame_type The frame type that was added.
+ * @param[in] init Information if the data is loaded during initialization. Set this
+ * parameter to false if the call is a result of a write to the Eddystone Configuration Service.
+ */
+void es_slot_reg_update_slot_list_info_on_add(es_slot_reg_t * p_reg, uint8_t slot_no, es_frame_type_t frame_type, bool init);
+
+/** @brief Function for initializing the slot registry.
+ *
+ * @param[in] p_reg Pointer to the slot registry to initialize.
+ */
+void es_slot_reg_init(es_slot_reg_t * p_reg);
+
+/**
+ * @}
+ */
+
+#endif // ES_SLOT_REG_H__
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/eddystone/es_stopwatch.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/eddystone/es_stopwatch.c
new file mode 100644
index 0000000..0f022bf
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/eddystone/es_stopwatch.c
@@ -0,0 +1,106 @@
+/**
+ * Copyright (c) 2016 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+
+#include <stdbool.h>
+#include <stdint.h>
+#include <string.h>
+#include "es_stopwatch.h"
+#include "sdk_macros.h"
+#include "app_timer.h"
+#include "es_app_config.h"
+
+static uint32_t m_ticks_last_returned[ES_STOPWATCH_MAX_USERS];
+static uint32_t m_ids_ticks_wrap[ES_STOPWATCH_MAX_USERS];
+static uint8_t m_nof_ids = 0;
+static bool m_initialized = false;
+
+uint32_t es_stopwatch_check(es_stopwatch_id_t id)
+{
+ uint32_t ticks_current = app_timer_cnt_get();
+ uint32_t ticks_diff;
+
+ if (m_ids_ticks_wrap[id] == 0)
+ {
+ APP_ERROR_CHECK(NRF_ERROR_INVALID_STATE);
+ }
+
+ ticks_diff = app_timer_cnt_diff_compute(ticks_current, m_ticks_last_returned[id]);
+
+ if (ticks_diff >= m_ids_ticks_wrap[id])
+ {
+ m_ticks_last_returned[id] = (ticks_current / m_ids_ticks_wrap[id]) * m_ids_ticks_wrap[id];
+
+ return ticks_diff / m_ids_ticks_wrap[id];
+ }
+
+ return 0;
+}
+
+ret_code_t es_stopwatch_create(es_stopwatch_id_t * p_sw_id, uint32_t ticks_wrap)
+{
+ VERIFY_PARAM_NOT_NULL(p_sw_id);
+
+ if (m_nof_ids == ES_STOPWATCH_MAX_USERS)
+ {
+ return NRF_ERROR_INVALID_STATE;
+ }
+
+ if (!m_initialized)
+ {
+ return NRF_ERROR_MODULE_NOT_INITIALIZED;
+ }
+
+ *p_sw_id = m_nof_ids;
+
+ m_ids_ticks_wrap[m_nof_ids] = ticks_wrap;
+
+ m_nof_ids++;
+
+ return NRF_SUCCESS;
+}
+
+
+void es_stopwatch_init(void)
+{
+ m_nof_ids = 0;
+ memset(m_ticks_last_returned, 0, sizeof(m_ticks_last_returned));
+ memset(m_ids_ticks_wrap, 0, sizeof(m_ids_ticks_wrap));
+ m_initialized = true;
+}
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/eddystone/es_stopwatch.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/eddystone/es_stopwatch.h
new file mode 100644
index 0000000..1318861
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/eddystone/es_stopwatch.h
@@ -0,0 +1,71 @@
+/**
+ * Copyright (c) 2016 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#ifndef ES_SECURITY_TIMING_H__
+#define ES_SECURITY_TIMING_H__
+
+#include <stdint.h>
+#include "app_error.h"
+
+/**
+ * @file
+ * @addtogroup eddystone_security
+ * @{
+ */
+
+typedef uint8_t es_stopwatch_id_t;
+
+/**@brief Function for getting the number of seconds passed since the last invocation.
+ * @details If the function returns zero, the 'last time called' state is not updated. If a non-zero value
+ * is returned, the 'last time called' state will point to the last whole second.
+ * @return Number of seconds passed since the last invocation.
+ */
+uint32_t es_stopwatch_check(es_stopwatch_id_t id);
+
+ret_code_t es_stopwatch_create(es_stopwatch_id_t * p_sw_id, uint32_t ticks_wrap);
+
+/**@brief Function for initializing the security timing module.
+ */
+void es_stopwatch_init(void);
+
+/**
+ * @}
+ */
+
+#endif // ES_SECURITY_TIMING_H__
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/eddystone/es_tlm.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/eddystone/es_tlm.c
new file mode 100644
index 0000000..dec4b6e
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/eddystone/es_tlm.c
@@ -0,0 +1,140 @@
+/**
+ * Copyright (c) 2016 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+
+#include <string.h>
+#include "app_timer.h"
+#include "es_tlm.h"
+#include "es_app_config.h"
+#include "es_battery_voltage.h"
+#include "es_stopwatch.h"
+#include "nrf_soc.h"
+
+#define TICKS_100_MS APP_TIMER_TICKS(100) //!< Tick count for 100ms.
+
+static es_tlm_frame_t m_tlm;
+static uint32_t m_le_adv_cnt;
+static es_stopwatch_id_t m_time_sec_sw_id;
+static es_stopwatch_id_t m_tlm_refresh_sw_id;
+
+/**@brief Function for updating the ADV_SEC field of TLM*/
+static void update_time(void)
+{
+ static uint32_t time_total_100_ms = 0;
+ uint32_t be_time_100_ms; // Big endian version of 0.1 second counter.
+
+ time_total_100_ms += es_stopwatch_check(m_time_sec_sw_id);
+
+ be_time_100_ms = BYTES_REVERSE_32BIT(time_total_100_ms);
+
+ memcpy(m_tlm.sec_cnt, &be_time_100_ms, ES_TLM_SEC_CNT_LENGTH);
+}
+
+
+/**@brief Function for updating the TEMP field of TLM*/
+static void update_temp(void)
+{
+ int32_t temp; // variable to hold temp reading
+ (void)sd_temp_get(&temp); // get new temperature
+ int16_t temp_new = (int16_t) temp; // convert from int32_t to int16_t
+ m_tlm.temp[0] = (uint8_t)((temp_new >> 2) & 0xFFUL); // Right-shift by two to remove decimal part
+ m_tlm.temp[1] = (uint8_t)((temp_new << 6) & 0xFFUL); // Left-shift 6 to get fractional part with 0.25 degrees C resolution
+}
+
+
+/**@brief Function for updating the VBATT field of TLM*/
+static void update_vbatt(void)
+{
+ uint16_t vbatt; // Variable to hold voltage reading
+ es_battery_voltage_get(&vbatt); // Get new battery voltage
+ m_tlm.vbatt[0] = (uint8_t)(vbatt >> 8);
+ m_tlm.vbatt[1] = (uint8_t)vbatt;
+}
+
+
+static void update_adv_cnt(void)
+{
+ uint32_t be_adv_cnt = BYTES_REVERSE_32BIT(m_le_adv_cnt);
+ memcpy(m_tlm.adv_cnt, (uint8_t *)(&be_adv_cnt), ES_TLM_ADV_CNT_LENGTH);
+}
+
+
+void es_tlm_tlm_get(es_tlm_frame_t * p_tlm_frame)
+{
+ // Note that frame type and TLM version fields are set in initialization.
+ update_time();
+ update_adv_cnt();
+
+ if (es_stopwatch_check(m_tlm_refresh_sw_id) > 0)
+ {
+ update_temp();
+ update_vbatt();
+ }
+
+ memcpy(p_tlm_frame, &m_tlm, sizeof(es_tlm_frame_t));
+}
+
+
+void es_tlm_adv_cnt_inc(void)
+{
+ m_le_adv_cnt++;
+}
+
+
+void es_tlm_init(void)
+{
+ ret_code_t err_code;
+
+ memset(&m_tlm, 0, sizeof(m_tlm));
+ m_tlm.frame_type = ES_FRAME_TYPE_TLM;
+ m_tlm.version = ES_TLM_VERSION_TLM;
+ m_le_adv_cnt = 0;
+
+ update_time();
+ update_vbatt();
+ update_temp();
+
+ err_code = es_stopwatch_create(&m_time_sec_sw_id, APP_TIMER_TICKS(100));
+ APP_ERROR_CHECK(err_code);
+
+ err_code = es_stopwatch_create(
+ &m_tlm_refresh_sw_id,
+ APP_TIMER_TICKS(APP_CONFIG_TLM_TEMP_VBATT_UPDATE_INTERVAL_SECONDS * 1000));
+ APP_ERROR_CHECK(err_code);
+}
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/eddystone/es_tlm.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/eddystone/es_tlm.h
new file mode 100644
index 0000000..055d22b
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/eddystone/es_tlm.h
@@ -0,0 +1,76 @@
+/**
+ * Copyright (c) 2016 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#ifndef ES_TLM_H__
+#define ES_TLM_H__
+
+#include "es.h"
+
+/**
+ * @file
+ * @defgroup eddystone_tlm TLM
+ * @brief Functions for the Eddystone telemetry (TLM) manager.
+ * @ingroup eddystone_adv
+ * @{
+ */
+
+/**@brief Function for initializing the TLM manager.
+ *
+ * @return See @ref app_timer_start for possible return values.
+ */
+void es_tlm_init(void);
+
+/**@brief Function for getting the current TLM.
+ *
+ * @param[in] p_tlm_frame Pointer to the TLM frame to which the frame is retrieved.
+ */
+void es_tlm_tlm_get(es_tlm_frame_t * p_tlm_frame);
+
+/**@brief Function for incrementing the ADV_CNT field of the TLM frame.
+ *
+ * @details This function should be called every time a frame is advertised.
+ *
+ */
+void es_tlm_adv_cnt_inc(void);
+
+/**
+ * @}
+ */
+
+#endif // ES_TLM_H__
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/eddystone/es_util.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/eddystone/es_util.h
new file mode 100644
index 0000000..36e33d9
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/eddystone/es_util.h
@@ -0,0 +1,137 @@
+/**
+ * Copyright (c) 2016 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+
+// See https://github.com/pfultz2/Cloak/wiki/C-Preprocessor-tricks,-tips,-and-idioms
+
+#ifndef ES_UTIL_H__
+#define ES_UTIL_H__
+
+#define BOOL(x) COMPL(NOT(x))
+#define IF(c) IIF(BOOL(c))
+
+#define CHECK_N(x, n, ...) n
+#define CHECK(...) CHECK_N(__VA_ARGS__, 0,)
+#define PROBE(x) x, 1,
+
+#define EAT(...)
+#define EXPAND(...) __VA_ARGS__
+#define WHEN(c) IF(c)(EXPAND, EAT)
+
+#define NOT(x) CHECK(PRIMITIVE_CAT(NOT_, x))
+#define NOT_0 PROBE(~)
+
+#define COMPL(b) PRIMITIVE_CAT(COMPL_, b)
+#define COMPL_0 1
+#define COMPL_1 0
+
+#define CAT(a, ...) PRIMITIVE_CAT(a, __VA_ARGS__)
+#define PRIMITIVE_CAT(a, ...) a ## __VA_ARGS__
+
+#define IIF(c) PRIMITIVE_CAT(IIF_, c)
+#define IIF_0(t, ...) __VA_ARGS__
+#define IIF_1(t, ...) t
+
+#define DEC(x) PRIMITIVE_CAT(DEC_, x)
+#define DEC_0 0
+#define DEC_1 0
+#define DEC_2 1
+#define DEC_3 2
+#define DEC_4 3
+#define DEC_5 4
+#define DEC_6 5
+#define DEC_7 6
+#define DEC_8 7
+#define DEC_9 8
+#define DEC_10 9
+#define DEC_11 10
+#define DEC_12 11
+#define DEC_13 12
+#define DEC_14 13
+#define DEC_15 14
+#define DEC_16 15
+#define DEC_17 16
+#define DEC_18 17
+#define DEC_19 18
+#define DEC_20 19
+#define DEC_21 20
+#define DEC_22 21
+#define DEC_23 22
+#define DEC_24 23
+#define DEC_25 24
+#define DEC_26 25
+#define DEC_27 26
+#define DEC_28 27
+#define DEC_29 28
+#define DEC_30 29
+#define DEC_31 30
+#define DEC_32 31
+
+#define EMPTY()
+#define DEFER(id) id EMPTY()
+#define OBSTRUCT(...) __VA_ARGS__ DEFER(EMPTY)()
+#define EXPAND(...) __VA_ARGS__
+
+#define EVAL(...) EVAL1(EVAL1(EVAL1(__VA_ARGS__)))
+#define EVAL1(...) EVAL2(EVAL2(EVAL2(__VA_ARGS__)))
+#define EVAL2(...) EVAL3(EVAL3(EVAL3(__VA_ARGS__)))
+#define EVAL3(...) EVAL4(EVAL4(EVAL4(__VA_ARGS__)))
+#define EVAL4(...) EVAL5(EVAL5(EVAL5(__VA_ARGS__)))
+#define EVAL5(...) __VA_ARGS__
+
+#define REPEAT(count, macro, ...) \
+ WHEN(count) \
+ ( \
+ OBSTRUCT(REPEAT_INDIRECT) () \
+ ( \
+ DEC(count), macro, __VA_ARGS__ \
+ ) \
+ OBSTRUCT(macro) \
+ ( \
+ DEC(count), __VA_ARGS__ \
+ ) \
+ )
+#define REPEAT_INDIRECT() REPEAT
+
+
+/**
+ * @}
+ */
+
+#endif // ES_UTIL_H__
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/eddystone/nrf_ble_es.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/eddystone/nrf_ble_es.c
new file mode 100644
index 0000000..67fdb3f
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/eddystone/nrf_ble_es.c
@@ -0,0 +1,438 @@
+/**
+ * Copyright (c) 2016 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+
+#include <string.h>
+#include "nrf_ble_es.h"
+#include "app_error.h"
+#include "fds.h"
+#include "es_adv.h"
+#include "es_battery_voltage.h"
+#include "es_flash.h"
+#include "es_gatts.h"
+#include "es_security.h"
+#include "es_slot.h"
+#include "es_stopwatch.h"
+#include "escs_defs.h"
+#include "nrf_sdh_ble.h"
+
+static uint16_t m_conn_handle = BLE_CONN_HANDLE_INVALID; //!< Connection handle.
+static nrf_ble_escs_t m_ble_ecs; //!< Struct identifying the Eddystone Config Service.
+static nrf_ble_es_evt_handler_t m_evt_handler; //!< Event handler.
+
+uint8_t m_adv_handle = BLE_GAP_ADV_SET_HANDLE_NOT_SET; //!< Advertising handle used to identify an advertising set.
+
+/**@brief Function for invoking registered callback.
+ *
+ * @param[in] evt Event to issue to callback.
+ */
+static void handle_evt(nrf_ble_es_evt_t evt)
+{
+ if (m_evt_handler != NULL)
+ {
+ m_evt_handler(evt);
+ }
+}
+
+
+/**@brief Function resetting MAC address. Will resume advertisement. */
+static void new_address_set(void)
+{
+
+ ret_code_t err_code;
+ uint8_t bytes_available;
+ ble_gap_addr_t new_address;
+
+ new_address.addr_type = BLE_GAP_ADDR_TYPE_PUBLIC;
+
+ // Randomize the MAC address on every EID generation
+ (void)sd_rand_application_bytes_available_get(&bytes_available);
+
+ while (bytes_available < BLE_GAP_ADDR_LEN)
+ {
+ // wait for SD to acquire enough RNs
+ (void)sd_rand_application_bytes_available_get(&bytes_available);
+ }
+
+ (void)sd_rand_application_vector_get(new_address.addr, BLE_GAP_ADDR_LEN);
+
+ // Stop advertising to ensure that it is possible to change the address.
+ (void)sd_ble_gap_adv_stop(m_adv_handle);
+
+ do
+ {
+ err_code = sd_ble_gap_addr_set(&new_address);
+ } while (err_code == NRF_ERROR_INVALID_STATE);
+
+ APP_ERROR_CHECK(err_code);
+
+ if (es_adv_remain_connectable_get())
+ {
+ es_adv_start_connectable_adv();
+ }
+ else
+ {
+ es_adv_start_non_connctable_adv();
+ }
+}
+
+
+/**@brief Function updating MAC address if required.
+ *
+ * @param[in] demand_new_mac If 'true', mac address will be updated on next invocation when not connected.
+ * If 'false', simply check if we have an outstanding demand for new MAC and update if not connected.
+ */
+static void check_and_update_mac_address(bool demand_new_mac)
+{
+ static bool reset_mac_address = false;
+
+ if (demand_new_mac)
+ {
+ reset_mac_address = true;
+ }
+
+ // Not possible to update MAC address while in a connection
+ if (m_conn_handle != BLE_CONN_HANDLE_INVALID)
+ {
+ return;
+ }
+
+ else if (reset_mac_address)
+ {
+ reset_mac_address = false;
+
+ new_address_set();
+ }
+}
+
+
+/**@brief Function to lock the beacon (change lock state characteristic to LOCKED)
+ */
+static void lock_beacon(void)
+{
+ *(m_ble_ecs.p_lock_state) = NRF_BLE_ESCS_LOCK_STATE_LOCKED;
+}
+
+
+/**@brief Function for handling BLE event from the SoftDevice.
+ *
+ * @param[in] p_ble_evt Pointer to BLE event.
+ */
+static void on_ble_evt(ble_evt_t const * p_ble_evt)
+{
+ ret_code_t err_code;
+ es_flash_flags_t flash_flag = {{0}};
+ const es_slot_reg_t * p_reg = es_slot_get_registry();
+
+ switch (p_ble_evt->header.evt_id)
+ {
+ case BLE_GAP_EVT_CONNECTED:
+ m_conn_handle = p_ble_evt->evt.common_evt.conn_handle;
+ *(m_ble_ecs.p_active_slot) = 0;
+ break;
+
+ case BLE_GAP_EVT_DISCONNECTED:
+ m_conn_handle = BLE_CONN_HANDLE_INVALID;
+
+ for (uint32_t i = 0; i < APP_MAX_ADV_SLOTS; ++i)
+ {
+ err_code = es_slot_write_to_flash(i);
+ APP_ERROR_CHECK(err_code);
+
+ flash_flag.slot_is_empty[i] = !p_reg->slots[i].configured;
+ }
+
+ err_code = es_flash_access_flags(&flash_flag, ES_FLASH_ACCESS_WRITE);
+ APP_ERROR_CHECK(err_code);
+
+ es_flash_beacon_config_t beacon_config;
+ beacon_config.adv_interval = es_adv_interval_get();
+ beacon_config.remain_connectable = es_adv_remain_connectable_get();
+
+ err_code = es_flash_access_beacon_config(&beacon_config, ES_FLASH_ACCESS_WRITE);
+ APP_ERROR_CHECK(err_code);
+
+ if (*m_ble_ecs.p_lock_state == NRF_BLE_ESCS_LOCK_STATE_UNLOCKED)
+ {
+ lock_beacon();
+ }
+
+ check_and_update_mac_address(false);
+
+ break;
+
+ default:
+ // No implementation needed.
+ break;
+ }
+}
+
+
+/**@brief Callback function to receive messages from the security module
+ *
+ * @details Need to be passed in during es_security_init(). The security
+ * module will callback anytime a particular security process is completed
+ *
+ * @params[in] slot_no Index of the slot
+ * @params[in] msg_type Message type corersponding to different security components
+ */
+static void nrf_ble_escs_security_cb(uint8_t slot_no, es_security_msg_t msg_type)
+{
+ nrf_ble_escs_eid_id_key_t encrypted_id_key;
+ nrf_ble_escs_public_ecdh_key_t pub_ecdh_key;
+
+ ret_code_t err_code;
+ static ble_gatts_value_t value;
+
+ switch (msg_type)
+ {
+ case ES_SECURITY_MSG_UNLOCKED:
+ *(m_ble_ecs.p_lock_state) = NRF_BLE_ESCS_LOCK_STATE_UNLOCKED;
+ break;
+
+ case ES_SECURITY_MSG_EID:
+ es_slot_eid_ready(slot_no);
+#ifdef MAC_RANDOMIZED
+ check_and_update_mac_address(true);
+#endif // MAC_RANDOMIZED
+ break;
+
+ case ES_SECURITY_MSG_IK:
+ es_security_encrypted_eid_id_key_get(slot_no, (uint8_t *)encrypted_id_key.key);
+ // Set the EID ID key in the slot so it can be exposed in the characteristic
+ es_slot_encrypted_eid_id_key_set(slot_no, &encrypted_id_key);
+ break;
+
+ case ES_SECURITY_MSG_ECDH:
+ es_security_pub_ecdh_get(slot_no, (uint8_t *)pub_ecdh_key.key);
+
+ // Set the characteristic to the ECDH key value
+ value.len = sizeof(nrf_ble_escs_public_ecdh_key_t);
+ value.offset = 0;
+ value.p_value = (uint8_t *)pub_ecdh_key.key;
+
+ if (m_conn_handle != BLE_CONN_HANDLE_INVALID)
+ {
+ err_code = sd_ble_gatts_value_set(m_ble_ecs.conn_handle,
+ m_ble_ecs.pub_ecdh_key_handles.value_handle,
+ &value);
+ if (err_code != NRF_SUCCESS)
+ {
+ APP_ERROR_CHECK(err_code);
+ }
+ }
+ break;
+
+ case ES_SECURITY_MSG_STORE_TIME:
+ // Every 24 hours any EID slots time is stored to flash to allow for power lock_state_handles
+ // recovery. Only time needs to be stored, but just store the entire slot anyway for API simplicity.
+ err_code = es_slot_write_to_flash(slot_no);
+ APP_ERROR_CHECK(err_code);
+
+ break;
+
+ default:
+ APP_ERROR_CHECK(NRF_ERROR_INVALID_PARAM); // Should never happen
+ break;
+ }
+}
+
+
+/**@brief Function for handling advertisement events from 'es_adv'.
+ *
+ * @param[in] evt Advertisement event to handle.
+ */
+static void adv_evt_handler(es_adv_evt_t evt)
+{
+ switch (evt)
+ {
+ case ES_ADV_EVT_NON_CONN_ADV:
+ handle_evt(NRF_BLE_ES_EVT_ADVERTISEMENT_SENT);
+ es_security_update_time();
+ break;
+
+ case ES_ADV_EVT_CONNECTABLE_ADV_STARTED:
+ handle_evt(NRF_BLE_ES_EVT_CONNECTABLE_ADV_STARTED);
+ break;
+
+ case ES_ADV_EVT_CONNECTABLE_ADV_STOPPED:
+ handle_evt(NRF_BLE_ES_EVT_CONNECTABLE_ADV_STOPPED);
+ break;
+
+ default:
+ break;
+ }
+}
+
+
+/**@brief Initialize the ECS with initial values for the characteristics and other necessary modules */
+static void ble_escs_init(void)
+{
+ ret_code_t err_code;
+ nrf_ble_escs_init_t ecs_init;
+ nrf_ble_escs_init_params_t init_params;
+ int8_t tx_powers[ESCS_NUM_OF_SUPPORTED_TX_POWER] = ESCS_SUPPORTED_TX_POWER;
+
+ /*Init the broadcast capabilities characteristic*/
+ memset(&init_params.broadcast_cap, 0, sizeof(init_params.broadcast_cap));
+ init_params.broadcast_cap.vers_byte = ES_SPEC_VERSION_BYTE;
+ init_params.broadcast_cap.max_supp_total_slots = APP_MAX_ADV_SLOTS;
+ init_params.broadcast_cap.max_supp_eid_slots = APP_MAX_EID_SLOTS;
+ init_params.broadcast_cap.cap_bitfield = ( (APP_IS_VARIABLE_ADV_SUPPORTED << ESCS_BROADCAST_VAR_ADV_SUPPORTED_Pos)
+ | (APP_IS_VARIABLE_TX_POWER_SUPPORTED << ESCS_BROADCAST_VAR_TX_POWER_SUPPORTED_Pos))
+ & (ESCS_BROADCAST_VAR_RFU_MASK);
+ init_params.broadcast_cap.supp_frame_types = ( (APP_IS_URL_SUPPORTED << ESCS_FRAME_TYPE_URL_SUPPORTED_Pos)
+ | (APP_IS_UID_SUPPORTED << ESCS_FRAME_TYPE_UID_SUPPORTED_Pos)
+ | (APP_IS_TLM_SUPPORTED << ESCS_FRAME_TYPE_TLM_SUPPORTED_Pos)
+ | (APP_IS_EID_SUPPORTED << ESCS_FRAME_TYPE_EID_SUPPORTED_Pos))
+ & (ESCS_FRAME_TYPE_RFU_MASK);
+ memcpy(init_params.broadcast_cap.supp_radio_tx_power, tx_powers, ESCS_NUM_OF_SUPPORTED_TX_POWER);
+
+ init_params.adv_interval = APP_CFG_NON_CONN_ADV_INTERVAL_MS;
+ init_params.adv_tx_pwr = APP_CFG_DEFAULT_RADIO_TX_POWER;
+ init_params.radio_tx_pwr = 0x00;
+ init_params.factory_reset = 0;
+ init_params.remain_connectable.r_is_non_connectable_supported = APP_IS_REMAIN_CONNECTABLE_SUPPORTED;
+
+ // Initialize evt handlers and the service
+ memset(&ecs_init, 0, sizeof(ecs_init));
+ ecs_init.write_evt_handler = es_gatts_handle_write;
+ ecs_init.read_evt_handler = es_gatts_handle_read;
+ ecs_init.p_init_vals = &(init_params);
+
+ err_code = nrf_ble_escs_init(&m_ble_ecs, &ecs_init);
+ APP_ERROR_CHECK(err_code);
+}
+
+
+/**@brief Function for initializing 'es_adv' module. */
+static void adv_init(void)
+{
+ ret_code_t err_code;
+ es_flash_beacon_config_t beacon_config;
+
+ err_code = es_flash_access_beacon_config(&beacon_config, ES_FLASH_ACCESS_READ);
+
+ if (err_code == FDS_ERR_NOT_FOUND)
+ {
+ beacon_config.adv_interval = APP_CFG_NON_CONN_ADV_INTERVAL_MS;
+ beacon_config.remain_connectable = false;
+ }
+
+ else
+ {
+ APP_ERROR_CHECK(err_code);
+ }
+
+ es_adv_init(m_ble_ecs.uuid_type,
+ adv_evt_handler,
+ beacon_config.adv_interval,
+ beacon_config.remain_connectable,
+ &m_adv_handle);
+}
+
+
+/**@brief Function for initializing es_slots module. */
+static void adv_slots_init(void)
+{
+ uint8_t default_frame_data[DEFAULT_FRAME_LENGTH] = DEFAULT_FRAME_DATA;
+
+ es_slot_t default_adv_slot = {.slot_no = 0,
+ .radio_tx_pwr = 0,
+ .adv_frame.type = DEFAULT_FRAME_TYPE,
+ .adv_frame.length = DEFAULT_FRAME_LENGTH,
+ .adv_custom_tx_power = false,
+ .configured = true};
+
+ memcpy(&default_adv_slot.adv_frame.frame, default_frame_data, DEFAULT_FRAME_LENGTH);
+
+ es_slots_init(&default_adv_slot);
+}
+
+
+void nrf_ble_es_on_ble_evt(ble_evt_t const * p_ble_evt, void * p_context)
+{
+ ret_code_t err_code;
+
+ es_adv_on_ble_evt(p_ble_evt);
+ err_code = nrf_ble_escs_on_ble_evt(&m_ble_ecs, p_ble_evt);
+ APP_ERROR_CHECK(err_code);
+ on_ble_evt(p_ble_evt);
+ es_flash_on_ble_evt(p_ble_evt);
+}
+
+NRF_SDH_BLE_OBSERVER(m_es_observer, NRF_BLE_ES_BLE_OBSERVER_PRIO, nrf_ble_es_on_ble_evt, NULL);
+
+
+void nrf_ble_es_on_start_connectable_advertising(void)
+{
+ es_adv_start_connectable_adv();
+}
+
+
+void nrf_ble_es_init(nrf_ble_es_evt_handler_t evt_handler)
+{
+ ret_code_t err_code;
+
+ m_evt_handler = evt_handler;
+ m_conn_handle = BLE_CONN_HANDLE_INVALID;
+
+ es_stopwatch_init();
+
+ err_code = es_gatts_init(&m_ble_ecs);
+ APP_ERROR_CHECK(err_code);
+
+ err_code = es_flash_init();
+ APP_ERROR_CHECK(err_code);
+
+ while (es_flash_num_pending_ops() > 0)
+ {
+ ; // Busy wait while initialization of FDS module completes
+ }
+
+ err_code = es_security_init(nrf_ble_escs_security_cb);
+ APP_ERROR_CHECK(err_code);
+
+ es_adv_timers_init();
+ ble_escs_init();
+ adv_slots_init();
+ es_battery_voltage_init();
+ adv_init();
+ es_adv_start_non_connctable_adv();
+}
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/eddystone/nrf_ble_es.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/eddystone/nrf_ble_es.h
new file mode 100644
index 0000000..3262136
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/eddystone/nrf_ble_es.h
@@ -0,0 +1,99 @@
+/**
+ * Copyright (c) 2016 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+
+#ifndef NRF_ES_H__
+#define NRF_ES_H__
+
+#include <stdint.h>
+#include "ble.h"
+
+/**
+ * @file
+ * @defgroup eddystone Eddystone library
+ * @ingroup app_common
+ * @{
+ *
+ * @brief Library for Eddystone beacons. This library is used in the @ref ble_sdk_app_es.
+ *
+ * @note The API documentation is provided for reference only. You should
+ * not modify this library, and you should not use any functions
+ * except for the main level functions defined in @c nrf_ble_es.h
+ * in different contexts.
+ */
+
+/** @brief Eddystone event types. */
+typedef enum
+{
+ NRF_BLE_ES_EVT_ADVERTISEMENT_SENT, //!< A non-connectable Eddystone frame advertisement was sent.
+ NRF_BLE_ES_EVT_CONNECTABLE_ADV_STARTED, //!< Advertising in connectable mode was started.
+ NRF_BLE_ES_EVT_CONNECTABLE_ADV_STOPPED, //!< Advertising in connectable mode was stopped.
+} nrf_ble_es_evt_t;
+
+/**@brief Eddystone event handler type. */
+typedef void (*nrf_ble_es_evt_handler_t)(nrf_ble_es_evt_t evt);
+
+/**@brief Function for handling the application's BLE stack events.
+ *
+ * @details This function handles all events from the BLE stack that are of
+ * interest to the Eddystone library.
+ *
+ * @param[in] p_ble_evt Event received from the BLE stack.
+ * @param[in] p_context User parameter.
+ */
+void nrf_ble_es_on_ble_evt(ble_evt_t const * p_ble_evt, void * p_context);
+
+/**@brief Function for putting the beacon in connectable mode.
+ *
+ * @details This function makes the beacon advertise connectable advertisements.
+ * If the beacon is in a connected state, the request is ignored.
+ */
+void nrf_ble_es_on_start_connectable_advertising(void);
+
+/** @brief Function for initializing the Eddystone library.
+ *
+ * @param[in] evt_handler Event handler to be called for handling BLE events.
+ */
+void nrf_ble_es_init(nrf_ble_es_evt_handler_t evt_handler);
+
+/**
+ * @}
+ */
+
+#endif
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/experimental_ble_lns/ble_ln_common.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/experimental_ble_lns/ble_ln_common.h
new file mode 100644
index 0000000..54cb080
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/experimental_ble_lns/ble_ln_common.h
@@ -0,0 +1,94 @@
+/**
+ * Copyright (c) 2015 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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
+ *
+ * @defgroup ble_sdk_srv_ln_common Location and Navigation common defines
+ * @{
+ * @ingroup ble_sdk_srv
+ * @brief Location and Navigation common defines
+ *
+ * @details This module contains define values common to LNS and LNCP
+ */
+
+#ifndef BLE_LNS_COMMON_H__
+#define BLE_LNS_COMMON_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define BLE_LNS_INVALID_ROUTE 0xFFFF
+#define BLE_LNS_NO_FIX 0xFF
+
+#define BLE_LNS_MAX_NUM_ROUTES 10 /**< The maximum number of routes. This affects memory usage only. */
+#define BLE_LNS_MAX_ROUTE_NAME_LEN BLE_GATT_ATT_MTU_DEFAULT - 5 /**< The maximum length of length of a route name. */
+#define MAX_CTRL_POINT_RESP_PARAM_LEN BLE_LNS_MAX_ROUTE_NAME_LEN + 3 /**< Maximum length of a control point response. */
+
+// Location and Navigation Service feature bits
+#define BLE_LNS_FEATURE_INSTANT_SPEED_SUPPORTED (0x01 << 0) /**< Instaneous Speed Supported bit. */
+#define BLE_LNS_FEATURE_TOTAL_DISTANCE_SUPPORTED (0x01 << 1) /**< Total Distance Supported bit. */
+#define BLE_LNS_FEATURE_LOCATION_SUPPORTED (0x01 << 2) /**< Location Supported bit. */
+#define BLE_LNS_FEATURE_ELEVATION_SUPPORTED (0x01 << 3) /**< Elevation Supported bit. */
+#define BLE_LNS_FEATURE_HEADING_SUPPORTED (0x01 << 4) /**< Heading Supported bit. */
+#define BLE_LNS_FEATURE_ROLLING_TIME_SUPPORTED (0x01 << 5) /**< Rolling Time Supported bit. */
+#define BLE_LNS_FEATURE_UTC_TIME_SUPPORTED (0x01 << 6) /**< UTC Time Supported bit. */
+#define BLE_LNS_FEATURE_REMAINING_DISTANCE_SUPPORTED (0x01 << 7) /**< Remaining Distance Supported bit. */
+#define BLE_LNS_FEATURE_REMAINING_VERT_DISTANCE_SUPPORTED (0x01 << 8) /**< Remaining Vertical Distance Supported bit. */
+#define BLE_LNS_FEATURE_EST_TIME_OF_ARRIVAL_SUPPORTED (0x01 << 9) /**< Estimated Time of Arrival Supported bit. */
+#define BLE_LNS_FEATURE_NUM_SATS_IN_SOLUTION_SUPPORTED (0x01 << 10) /**< Number of Satellites in Solution Supported bit. */
+#define BLE_LNS_FEATURE_NUM_SATS_IN_VIEW_SUPPORTED (0x01 << 11) /**< Number of Satellites in View Supported bit. */
+#define BLE_LNS_FEATURE_TIME_TO_FIRST_FIX_SUPPORTED (0x01 << 12) /**< Time to First Fix Supported bit. */
+#define BLE_LNS_FEATURE_EST_HORZ_POS_ERROR_SUPPORTED (0x01 << 13) /**< Estimated Horizontal Position Error Supported bit. */
+#define BLE_LNS_FEATURE_EST_VERT_POS_ERROR_SUPPORTED (0x01 << 14) /**< Estimated Vertical Position Error Supported bit. */
+#define BLE_LNS_FEATURE_HORZ_DILUTION_OF_PRECISION_SUPPORTED (0x01 << 15) /**< Horizontal Dilution of Precision Supported bit. */
+#define BLE_LNS_FEATURE_VERT_DILUTION_OF_PRECISION_SUPPORTED (0x01 << 16) /**< Vertical Dilution of Precision Supported bit. */
+#define BLE_LNS_FEATURE_LOC_AND_SPEED_CONTENT_MASKING_SUPPORTED (0x01 << 17) /**< Location and Speed Characteristic Content Masking Supported bit. */
+#define BLE_LNS_FEATURE_FIX_RATE_SETTING_SUPPORTED (0x01 << 18) /**< Fix Rate Setting Supported bit. */
+#define BLE_LNS_FEATURE_ELEVATION_SETTING_SUPPORTED (0x01 << 19) /**< Elevation Setting Supported bit. */
+#define BLE_LNS_FEATURE_POSITION_STATUS_SUPPORTED (0x01 << 20) /**< Position Status Supported bit. */
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* BLE_LNS_COMMON_H__ */
+
+/** @} */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/experimental_ble_lns/ble_ln_cp.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/experimental_ble_lns/ble_ln_cp.c
new file mode 100644
index 0000000..97eb3d9
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/experimental_ble_lns/ble_ln_cp.c
@@ -0,0 +1,821 @@
+/**
+ * Copyright (c) 2015 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#include "ble_ln_cp.h"
+#include "ble_ln_db.h"
+#include "ble_ln_common.h"
+#include "sdk_common.h"
+
+#define NRF_LOG_MODULE_NAME ble_ln_cp
+#include "nrf_log.h"
+NRF_LOG_MODULE_REGISTER();
+
+// Feature Mask bits
+#define FEATURE_MASK_INSTANTANEOUS_SPEED (0x01 << 0) /**< Instantaneous Speed mask bit. */
+#define FEATURE_MASK_TOTAL_DISTANCE (0x01 << 1) /**< Total Distance mask bit. */
+#define FEATURE_MASK_LOCATION (0x01 << 2) /**< Location mask bit. */
+#define FEATURE_MASK_ELEVATION (0x01 << 3) /**< Elevation mask bit. */
+#define FEATURE_MASK_HEADING (0x01 << 4) /**< Heading mask bit. */
+#define FEATURE_MASK_ROLLING_TIME (0x01 << 5) /**< Rolling Time mask bit. */
+#define FEATURE_MASK_UTC_TIME (0x01 << 6) /**< UTC Time mask bit. */
+
+// Data Control point parameter type lengths.
+#define INT8_LEN 1
+#define INT16_LEN 2
+#define INT24_LEN 3
+#define INT32_LEN 4
+
+#define OPCODE_LENGTH 1 /**< Length of opcode inside Location and Navigation Measurement packet. */
+#define HANDLE_LENGTH 2 /**< Length of handle inside Location and Navigation Measurement packet. */
+
+static ble_lncp_rsp_code_t notify_app(ble_lncp_t const * p_lncp, ble_lncp_evt_t const * p_evt)
+{
+ ble_lncp_rsp_code_t rsp = LNCP_RSP_SUCCESS;
+
+ if (p_lncp->evt_handler != NULL)
+ {
+ rsp = p_lncp->evt_handler(p_lncp, p_evt);
+ }
+
+ return rsp;
+}
+
+
+static void resp_send(ble_lncp_t * p_lncp)
+{
+ // Send indication
+ uint16_t hvx_len;
+ uint8_t hvx_data[MAX_CTRL_POINT_RESP_PARAM_LEN];
+ ble_gatts_hvx_params_t hvx_params;
+ uint32_t err_code;
+
+ memset(&hvx_params, 0, sizeof(hvx_params));
+
+ hvx_len = 3 + p_lncp->pending_rsp.rsp_param_len;
+ hvx_data[0] = LNCP_OP_RESPONSE_CODE;
+ hvx_data[1] = p_lncp->pending_rsp.op_code;
+ hvx_data[2] = p_lncp->pending_rsp.rsp_code;
+
+ memcpy(&hvx_data[3], &p_lncp->pending_rsp.rsp_param[0], p_lncp->pending_rsp.rsp_param_len);
+
+ hvx_params.handle = p_lncp->ctrlpt_handles.value_handle;
+ hvx_params.type = BLE_GATT_HVX_INDICATION;
+ hvx_params.offset = 0;
+ hvx_params.p_len = &hvx_len;
+ hvx_params.p_data = hvx_data;
+
+ err_code = sd_ble_gatts_hvx(p_lncp->conn_handle, &hvx_params);
+
+ // Error handling
+ if ((err_code == NRF_SUCCESS) && (hvx_len != p_lncp->pending_rsp.rsp_param_len + 3))
+ {
+ err_code = NRF_ERROR_DATA_SIZE;
+ }
+
+ switch (err_code)
+ {
+ case NRF_SUCCESS:
+ p_lncp->procedure_status = LNCP_STATE_CONFIRMATION_PENDING;
+ // Wait for HVC event
+ break;
+
+ case NRF_ERROR_RESOURCES:
+ // Wait for TX_COMPLETE event to retry transmission
+ p_lncp->procedure_status = LNCP_STATE_INDICATION_PENDING;
+ break;
+
+ default:
+ p_lncp->procedure_status = LNCP_STATE_INDICATION_PENDING;
+ // error
+ if (p_lncp->error_handler != NULL)
+ {
+ p_lncp->error_handler(err_code);
+ }
+ break;
+ }
+}
+
+
+static void on_connect(ble_lncp_t * p_lncp, ble_evt_t const * p_ble_evt)
+{
+ memset(&p_lncp->mask, 0, sizeof(ble_lncp_mask_t));
+ p_lncp->conn_handle = p_ble_evt->evt.gap_evt.conn_handle;
+ p_lncp->procedure_status = LNCP_STATE_NO_PROC_IN_PROGRESS;
+}
+
+
+static void on_disconnect(ble_lncp_t * p_lncp, ble_evt_t const * p_ble_evt)
+{
+ UNUSED_PARAMETER(p_ble_evt);
+ p_lncp->conn_handle = BLE_CONN_HANDLE_INVALID;
+ p_lncp->procedure_status = LNCP_STATE_NO_PROC_IN_PROGRESS;
+}
+
+
+static void on_hvc_confirm(ble_lncp_t * p_lncp, ble_evt_t const * p_ble_evt)
+{
+ if (p_ble_evt->evt.gatts_evt.params.hvc.handle == p_lncp->ctrlpt_handles.value_handle)
+ {
+ if (p_lncp->procedure_status == LNCP_STATE_CONFIRMATION_PENDING)
+ {
+ p_lncp->procedure_status = LNCP_STATE_NO_PROC_IN_PROGRESS;
+ }
+ else
+ {
+ if (p_lncp->error_handler != NULL)
+ {
+ p_lncp->error_handler(NRF_ERROR_INVALID_STATE);
+ }
+ }
+ }
+}
+
+
+static void on_tx_complete(ble_lncp_t * p_lncp)
+{
+ if (p_lncp->procedure_status == LNCP_STATE_INDICATION_PENDING)
+ {
+ resp_send(p_lncp);
+ }
+}
+
+
+/**@brief Handle write events to the control point cccd.
+ *
+ * @param[in] p_lncp Location and Navigation Service structure.
+ * @param[in] p_evt_write Write event received from the BLE stack.
+ */
+static void on_lncp_cccd_write(ble_lncp_t * p_lncp, ble_gatts_evt_write_t const * p_evt_write)
+{
+ if (p_evt_write->len == BLE_CCCD_VALUE_LEN)
+ {
+ // CCCD written, update indications state
+ p_lncp->is_ctrlpt_indication_enabled = ble_srv_is_indication_enabled(p_evt_write->data);
+ }
+}
+
+
+/**@brief Handle write events to the navigation cccd.
+ *
+ * @param[in] p_lncp Location and Navigation Service structure.
+ * @param[in] p_evt_write Write event received from the BLE stack.
+ */
+static void on_nav_cccd_write(ble_lncp_t * p_lncp, ble_gatts_evt_write_t const * p_evt_write)
+{
+ if (p_evt_write->len == BLE_CCCD_VALUE_LEN)
+ {
+ // CCCD written, update notification state
+ p_lncp->is_nav_notification_enabled = ble_srv_is_notification_enabled(p_evt_write->data);
+ }
+}
+
+
+/**@brief Event handler for control point write.
+ *
+ * @param[in] p_lncp Location and Navigation Service structure.
+ * @param[in] p_ble_evt Event received from the BLE stack.
+ */
+static void on_set_cumulative_value(ble_lncp_t * p_lncp, ble_gatts_evt_write_t const * p_evt_write)
+{
+ if ( !(p_lncp->available_features & BLE_LNS_FEATURE_TOTAL_DISTANCE_SUPPORTED) )
+ {
+ p_lncp->pending_rsp.rsp_code = LNCP_RSP_OP_CODE_NOT_SUPPORTED;
+ return;
+ }
+
+ if (p_evt_write->len != OPCODE_LENGTH + INT24_LEN)
+ {
+ p_lncp->pending_rsp.rsp_code = LNCP_RSP_INVALID_PARAMETER;
+ return;
+ }
+
+ const uint32_t total_distance = uint24_decode(&p_evt_write->data[1]);
+
+ const ble_lncp_evt_t evt = {
+ .evt_type = LNCP_EVT_TOTAL_DISTANCE_SET,
+ .params.total_distance = total_distance
+ };
+ p_lncp->pending_rsp.rsp_code = notify_app(p_lncp, &evt);
+
+ if (p_lncp->pending_rsp.rsp_code == LNCP_RSP_SUCCESS)
+ {
+ p_lncp->total_distance = total_distance;
+ }
+
+}
+
+
+/**@brief Event handler for control point write.
+ *
+ * @param[in] p_lncp Location and Navigation Service structure.
+ * @param[in] p_ble_evt Event received from the BLE stack.
+ */
+static void on_mask_loc_speed_content(ble_lncp_t * p_lncp, ble_gatts_evt_write_t const * p_evt_write)
+{
+ if ( !(p_lncp->available_features & BLE_LNS_FEATURE_LOC_AND_SPEED_CONTENT_MASKING_SUPPORTED) )
+ {
+ p_lncp->pending_rsp.rsp_code = LNCP_RSP_OP_CODE_NOT_SUPPORTED;
+ return;
+ }
+
+ if (p_evt_write->len != OPCODE_LENGTH + INT16_LEN)
+ {
+ p_lncp->pending_rsp.rsp_code = LNCP_RSP_INVALID_PARAMETER;
+ return;
+ }
+
+ uint16_t rcvd_mask = uint16_decode(&p_evt_write->data[1]);
+
+ if (rcvd_mask > 0x7F)
+ {
+ p_lncp->pending_rsp.rsp_code = LNCP_RSP_INVALID_PARAMETER;
+ return;
+ }
+
+ const ble_lncp_evt_t evt = {
+ .evt_type = LNCP_EVT_MASK_SET,
+ .params.mask.flags = rcvd_mask
+ };
+ p_lncp->pending_rsp.rsp_code = notify_app(p_lncp, &evt);
+
+ if (p_lncp->pending_rsp.rsp_code == LNCP_RSP_SUCCESS)
+ {
+ p_lncp->mask.flags = rcvd_mask;
+ }
+}
+
+
+/**@brief Event handler for control point write.
+ *
+ * @param[in] p_lncp Location and Navigation Service structure.
+ * @param[in] p_ble_evt Event received from the BLE stack.
+ */
+static void on_nav_control(ble_lncp_t * p_lncp, ble_gatts_evt_write_t const * p_evt_write)
+{
+ if ( !(p_lncp->is_navigation_present) )
+ {
+ p_lncp->pending_rsp.rsp_code = LNCP_RSP_OP_CODE_NOT_SUPPORTED;
+ return;
+ }
+
+ if (p_evt_write->len != LNCP_NAV_CMD_LEN)
+ {
+ p_lncp->pending_rsp.rsp_code = LNCP_RSP_INVALID_PARAMETER;
+ return;
+ }
+
+ /*lint --e{415} --e{416} -save suppress Warning 415: possible access out of bond */
+ const uint8_t data_buf = p_evt_write->data[1];
+ /*lint -restore*/
+
+ if (data_buf > LNCP_NAV_CMD_MAX)
+ {
+ p_lncp->pending_rsp.rsp_code = LNCP_RSP_INVALID_PARAMETER;
+ return;
+ }
+
+ const ble_lncp_nav_cmd_t cmd = (ble_lncp_nav_cmd_t) data_buf;
+
+ if (cmd == LNCP_CMD_NAV_START || cmd == LNCP_CMD_NAV_CONTINUE || cmd == LNCP_CMD_NAV_NEAREST)
+ {
+ p_lncp->is_navigation_running = true;
+ }
+ else if (cmd == LNCP_CMD_NAV_STOP || cmd == LNCP_CMD_NAV_PAUSE)
+ {
+ p_lncp->is_navigation_running = false;
+ }
+
+ const ble_lncp_evt_t evt = {
+ .evt_type = LNCP_EVT_NAV_COMMAND,
+ .params.nav_cmd = cmd
+ };
+ p_lncp->pending_rsp.rsp_code = notify_app(p_lncp, &evt);
+}
+
+
+/**@brief Event handler for control point write.
+ *
+ * @param[in] p_lncp Location and Navigation Service structure.
+ * @param[in] p_ble_evt Event received from the BLE stack.
+ */
+static void on_req_num_routes(ble_lncp_t * p_lncp, ble_gatts_evt_write_t const * p_evt_write)
+{
+ p_lncp->pending_rsp.rsp_code = LNCP_RSP_SUCCESS;
+
+ if ( !(p_lncp->is_navigation_present) )
+ {
+ p_lncp->pending_rsp.rsp_code = LNCP_RSP_OP_CODE_NOT_SUPPORTED;
+ return;
+ }
+
+ if (p_evt_write->len != OPCODE_LENGTH)
+ {
+ p_lncp->pending_rsp.rsp_code = LNCP_RSP_INVALID_PARAMETER;
+ return;
+ }
+
+ const uint8_t num_records = ble_ln_db_num_records_get();
+ p_lncp->pending_rsp.rsp_param_len = uint16_encode(num_records, &p_lncp->pending_rsp.rsp_param[0]);
+}
+
+
+/**@brief Event handler for control point write.
+ *
+ * @param[in] p_lncp Location and Navigation Service structure.
+ * @param[in] p_ble_evt Event received from the BLE stack.
+ */
+static void on_req_name_of_route(ble_lncp_t * p_lncp, ble_gatts_evt_write_t const * p_evt_write)
+{
+ uint8_t * p_name;
+ uint32_t err_code;
+
+ p_lncp->pending_rsp.rsp_code = LNCP_RSP_SUCCESS;
+
+ if ( !(p_lncp->is_navigation_present) )
+ {
+ p_lncp->pending_rsp.rsp_code = LNCP_RSP_OP_CODE_NOT_SUPPORTED;
+ return;
+ }
+
+ if (p_evt_write->len != OPCODE_LENGTH + INT16_LEN)
+ {
+ p_lncp->pending_rsp.rsp_code = LNCP_RSP_INVALID_PARAMETER;
+ return;
+ }
+
+ /*lint --e{415} --e{416} -save suppress Warning 415: possible access out of bond */
+ const uint16_t route_num = uint16_decode(&p_evt_write->data[1]);
+ /*lint -restore*/
+
+ err_code = ble_ln_db_record_name_get(route_num, &p_name);
+ if (err_code != NRF_SUCCESS)
+ {
+ p_lncp->pending_rsp.rsp_code = LNCP_RSP_OPERATION_FAILED;
+ return;
+ }
+ memcpy(&p_lncp->pending_rsp.rsp_param[0], p_name, BLE_LNS_MAX_ROUTE_NAME_LEN);
+
+ p_lncp->pending_rsp.rsp_param_len = BLE_LNS_MAX_ROUTE_NAME_LEN;
+}
+
+
+/**@brief Event handler for control point write.
+ *
+ * @param[in] p_lncp Location and Navigation Service structure.
+ * @param[in] p_ble_evt Event received from the BLE stack.
+ */
+static void on_select_route(ble_lncp_t * p_lncp, ble_gatts_evt_write_t const * p_evt_write)
+{
+ if ( !(p_lncp->is_navigation_present))
+ {
+ p_lncp->pending_rsp.rsp_code = LNCP_RSP_OP_CODE_NOT_SUPPORTED;
+ return;
+ }
+
+ if (p_evt_write->len != OPCODE_LENGTH + INT16_LEN)
+ {
+ p_lncp->pending_rsp.rsp_code = LNCP_RSP_INVALID_PARAMETER;
+ return;
+ }
+
+ const uint16_t route_num = uint16_decode(&p_evt_write->data[1]);
+ const uint16_t stored_num = ble_ln_db_num_records_get();
+
+ if (route_num >= stored_num)
+ {
+ p_lncp->pending_rsp.rsp_code = LNCP_RSP_INVALID_PARAMETER;
+ return;
+ }
+
+ const ble_lncp_evt_t evt = {
+ .evt_type = LNCP_EVT_ROUTE_SELECTED,
+ .params.selected_route = route_num
+ };
+ p_lncp->pending_rsp.rsp_code = notify_app(p_lncp, &evt);
+
+ if (p_lncp->pending_rsp.rsp_code == LNCP_RSP_SUCCESS)
+ {
+ p_lncp->selected_route = route_num;
+ }
+}
+
+
+/**@brief Event handler for control point write.
+ *
+ * @param[in] p_lncp Location and Navigation Service structure.
+ * @param[in] p_ble_evt Event received from the BLE stack.
+ */
+static void on_set_fix_rate(ble_lncp_t * p_lncp, ble_gatts_evt_write_t const * p_evt_write)
+{
+ p_lncp->pending_rsp.rsp_code = LNCP_RSP_SUCCESS;
+
+ if ( !(p_lncp->available_features & BLE_LNS_FEATURE_FIX_RATE_SETTING_SUPPORTED) )
+ {
+ p_lncp->pending_rsp.rsp_code = LNCP_RSP_OP_CODE_NOT_SUPPORTED;
+ return;
+ }
+
+ if (p_evt_write->len != OPCODE_LENGTH + INT8_LEN)
+ {
+ p_lncp->pending_rsp.rsp_code = LNCP_RSP_INVALID_PARAMETER;
+ return;
+ }
+
+ /*lint --e{415} --e{416} -save suppress Warning 415: possible access out of bond */
+ const uint8_t fix_rate = p_evt_write->data[1];
+ /*lint -restore*/
+
+ const ble_lncp_evt_t evt = {
+ .evt_type = LNCP_EVT_FIX_RATE_SET,
+ .params.fix_rate = fix_rate
+ };
+ p_lncp->pending_rsp.rsp_code = notify_app(p_lncp, &evt);
+
+ if (p_lncp->pending_rsp.rsp_code == LNCP_RSP_SUCCESS)
+ {
+ p_lncp->fix_rate = fix_rate;
+ }
+}
+
+
+/**@brief Event handler for control point write.
+ *
+ * @param[in] p_lncp Location and Navigation Service structure.
+ * @param[in] p_ble_evt Event received from the BLE stack.
+ */
+static void on_set_elevation(ble_lncp_t * p_lncp, ble_gatts_evt_write_t const * p_evt_write)
+{
+ p_lncp->pending_rsp.rsp_code = LNCP_RSP_SUCCESS;
+
+ if ( !(p_lncp->available_features & BLE_LNS_FEATURE_ELEVATION_SETTING_SUPPORTED) )
+ {
+ p_lncp->pending_rsp.rsp_code = LNCP_RSP_OP_CODE_NOT_SUPPORTED;
+ return;
+ }
+
+ if (p_evt_write->len != OPCODE_LENGTH + INT24_LEN)
+ {
+ p_lncp->pending_rsp.rsp_code = LNCP_RSP_INVALID_PARAMETER;
+ return;
+ }
+
+ const uint32_t elevation = uint24_decode(&p_evt_write->data[1]);
+ ble_lncp_evt_t evt = {
+ .evt_type = LNCP_EVT_ELEVATION_SET,
+ .params.elevation = elevation
+ };
+ p_lncp->pending_rsp.rsp_code = notify_app(p_lncp, &evt);
+
+ if (p_lncp->pending_rsp.rsp_code == LNCP_RSP_SUCCESS)
+ {
+ p_lncp->elevation = elevation;
+ }
+}
+
+
+/**@brief Handle write events to the Location and Navigation Service Control Point characteristic.
+ *
+ * @param[in] p_lncp Location and Navigation Service structure.
+ * @param[in] p_evt_write Write event received from the BLE stack.
+ */
+static void on_ctrlpt_write(ble_lncp_t * p_lncp, ble_gatts_evt_write_t const * p_evt_write)
+{
+ uint32_t err_code;
+
+ p_lncp->pending_rsp.rsp_param_len = 0;
+
+ ble_gatts_rw_authorize_reply_params_t write_authorize_reply;
+ memset(&write_authorize_reply, 0, sizeof(write_authorize_reply));
+
+ write_authorize_reply.type = BLE_GATTS_AUTHORIZE_TYPE_WRITE;
+
+ if (p_lncp->is_ctrlpt_indication_enabled)
+ {
+ if (p_lncp->procedure_status == LNCP_STATE_NO_PROC_IN_PROGRESS)
+ {
+ write_authorize_reply.params.write.update = 1;
+ write_authorize_reply.params.write.gatt_status = BLE_GATT_STATUS_SUCCESS;
+
+ // if the op code is navigation control, its cccd must be checked
+ if (p_evt_write->len > 0 && p_lncp->is_navigation_present)
+ {
+ if ( p_evt_write->data[0] == LNCP_OP_NAV_CONTROL
+ || p_evt_write->data[0] == LNCP_OP_REQ_NAME_OF_ROUTE
+ || p_evt_write->data[0] == LNCP_OP_REQ_NUM_ROUTES)
+ {
+ if (!p_lncp->is_nav_notification_enabled)
+ {
+ write_authorize_reply.params.write.gatt_status = LNCP_RSP_CCCD_CONFIG_IMPROPER;
+ }
+ }
+ }
+ }
+ else
+ {
+ write_authorize_reply.params.write.gatt_status = LNCP_RSP_PROC_ALR_IN_PROG;
+ }
+ }
+ else
+ {
+ write_authorize_reply.params.write.gatt_status = LNCP_RSP_CCCD_CONFIG_IMPROPER;
+ }
+
+ // reply to the write authorization
+ do {
+ err_code = sd_ble_gatts_rw_authorize_reply(p_lncp->conn_handle, &write_authorize_reply);
+ if (err_code != NRF_SUCCESS && err_code != NRF_ERROR_BUSY)
+ {
+ if (p_lncp->error_handler != NULL)
+ {
+ p_lncp->error_handler(err_code);
+ }
+ }
+ } while (err_code == NRF_ERROR_BUSY);
+
+
+ if (write_authorize_reply.params.write.gatt_status != BLE_GATT_STATUS_SUCCESS)
+ {
+ return;
+ }
+
+ // Start executing the control point write action
+ p_lncp->procedure_status = LNCP_STATE_INDICATION_PENDING;
+ if (p_evt_write->len > 0)
+ {
+ p_lncp->pending_rsp.op_code = (ble_lncp_op_code_t) p_evt_write->data[0];
+ switch (p_lncp->pending_rsp.op_code)
+ {
+ case LNCP_OP_SET_CUMULATIVE_VALUE:
+ on_set_cumulative_value(p_lncp, p_evt_write);
+ break;
+
+ case LNCP_OP_MASK_LOC_SPEED_CONTENT:
+ on_mask_loc_speed_content(p_lncp, p_evt_write);
+ break;
+
+ case LNCP_OP_NAV_CONTROL:
+ on_nav_control(p_lncp, p_evt_write);
+ break;
+
+ case LNCP_OP_REQ_NUM_ROUTES:
+ on_req_num_routes(p_lncp, p_evt_write);
+ break;
+
+ case LNCP_OP_REQ_NAME_OF_ROUTE:
+ on_req_name_of_route(p_lncp, p_evt_write);
+ break;
+
+ case LNCP_OP_SELECT_ROUTE:
+ on_select_route(p_lncp, p_evt_write);
+ break;
+
+ case LNCP_OP_SET_FIX_RATE:
+ on_set_fix_rate(p_lncp, p_evt_write);
+ break;
+
+ case LNCP_OP_SET_ELEVATION:
+ on_set_elevation(p_lncp, p_evt_write);
+ break;
+
+ // Unrecognized Op Code
+ default:
+ p_lncp->pending_rsp.rsp_code = LNCP_RSP_OP_CODE_NOT_SUPPORTED;
+ break;
+ }
+
+ resp_send(p_lncp);
+ }
+ else
+ {
+ p_lncp->procedure_status = LNCP_STATE_NO_PROC_IN_PROGRESS;
+ }
+}
+
+
+/**@brief Write authorization request event handler.
+ *
+ * @details The write authorization request event handler is only called when writing to the control point.
+ *
+ * @param[in] p_lncp Location and Navigation Service structure.
+ * @param[in] p_ble_evt Event received from the BLE stack.
+ */
+static void on_rw_authorize_req(ble_lncp_t * p_lncp, ble_evt_t const * p_ble_evt)
+{
+ const ble_gatts_evt_rw_authorize_request_t * p_auth_req =
+ &p_ble_evt->evt.gatts_evt.params.authorize_request;
+
+ if (
+ (p_auth_req->type == BLE_GATTS_AUTHORIZE_TYPE_WRITE)
+ &&
+ (p_auth_req->request.write.handle == p_lncp->ctrlpt_handles.value_handle)
+ &&
+ (p_auth_req->request.write.op != BLE_GATTS_OP_PREP_WRITE_REQ)
+ &&
+ (p_auth_req->request.write.op != BLE_GATTS_OP_EXEC_WRITE_REQ_NOW)
+ &&
+ (p_auth_req->request.write.op != BLE_GATTS_OP_EXEC_WRITE_REQ_CANCEL)
+ )
+ {
+ on_ctrlpt_write(p_lncp, &p_auth_req->request.write);
+ }
+
+}
+
+
+/**@brief Write event handler.
+ *
+ * @param[in] p_lncp Location and Navigation Service structure.
+ * @param[in] p_ble_evt Event received from the BLE stack.
+ */
+static void on_write(ble_lncp_t * p_lncp, ble_evt_t const * p_ble_evt)
+{
+ const ble_gatts_evt_write_t * p_evt_write = &p_ble_evt->evt.gatts_evt.params.write;
+
+ if (p_evt_write->handle == p_lncp->ctrlpt_handles.cccd_handle)
+ {
+ on_lncp_cccd_write(p_lncp, p_evt_write);
+ }
+ else if (p_evt_write->handle == p_lncp->navigation_handles.cccd_handle)
+ {
+ on_nav_cccd_write(p_lncp, p_evt_write);
+ }
+}
+
+
+void ble_lncp_on_ble_evt(ble_lncp_t * p_lncp, ble_evt_t const * p_ble_evt)
+{
+ VERIFY_PARAM_NOT_NULL_VOID(p_lncp);
+ VERIFY_PARAM_NOT_NULL_VOID(p_ble_evt);
+
+ switch (p_ble_evt->header.evt_id)
+ {
+ case BLE_GAP_EVT_CONNECTED:
+ on_connect(p_lncp, p_ble_evt);
+ break;
+
+ case BLE_GAP_EVT_DISCONNECTED:
+ if (p_ble_evt->evt.gap_evt.conn_handle == p_lncp->conn_handle)
+ {
+ on_disconnect(p_lncp, p_ble_evt);
+ }
+ break;
+
+ case BLE_GATTS_EVT_WRITE:
+ if (p_ble_evt->evt.gatts_evt.conn_handle == p_lncp->conn_handle)
+ {
+ on_write(p_lncp, p_ble_evt);
+ }
+ break;
+
+ case BLE_GATTS_EVT_RW_AUTHORIZE_REQUEST:
+ if (p_ble_evt->evt.gatts_evt.conn_handle == p_lncp->conn_handle)
+ {
+ on_rw_authorize_req(p_lncp, p_ble_evt);
+ }
+ break;
+
+ case BLE_GATTS_EVT_HVC:
+ if (p_ble_evt->evt.gatts_evt.conn_handle == p_lncp->conn_handle)
+ {
+ on_hvc_confirm(p_lncp, p_ble_evt);
+ }
+ break;
+
+ case BLE_GATTS_EVT_HVN_TX_COMPLETE:
+ on_tx_complete(p_lncp);
+ break;
+
+ default:
+ // no implementation
+ break;
+ }
+}
+
+
+uint32_t ble_lncp_total_distance_get(ble_lncp_t const * p_lncp)
+{
+ if (p_lncp == NULL)
+ {
+ return 0;
+ }
+
+ return p_lncp->total_distance;
+}
+
+
+uint32_t ble_lncp_elevation_get(ble_lncp_t const * p_lncp)
+{
+ if (p_lncp == NULL)
+ {
+ return 0;
+ }
+
+ return p_lncp->elevation;
+}
+
+
+ble_lncp_mask_t ble_lncp_mask_get(ble_lncp_t const * p_lncp)
+{
+ if (p_lncp == NULL)
+ {
+ const ble_lncp_mask_t empty_mask = {0};
+ return empty_mask;
+ }
+
+ return p_lncp->mask;
+}
+
+
+bool ble_lncp_is_navigation_running(ble_lncp_t const * p_lncp)
+{
+ if (p_lncp == NULL)
+ {
+ return false;
+ }
+
+ return p_lncp->is_navigation_running;
+}
+
+
+ret_code_t ble_lncp_init(ble_lncp_t * p_lncp, ble_lncp_init_t const * p_lncp_init)
+{
+ VERIFY_PARAM_NOT_NULL(p_lncp);
+ VERIFY_PARAM_NOT_NULL(p_lncp_init);
+
+ ble_add_char_params_t add_char_params;
+
+ memset(&add_char_params, 0, sizeof(add_char_params));
+
+ p_lncp->service_handle = p_lncp_init->service_handle;
+ p_lncp->evt_handler = p_lncp_init->evt_handler;
+ p_lncp->error_handler = p_lncp_init->error_handler;
+ p_lncp->available_features = p_lncp_init->available_features;
+ p_lncp->is_position_quality_present = p_lncp_init->is_position_quality_present;
+ p_lncp->is_navigation_present = p_lncp_init->is_navigation_present;
+ p_lncp->total_distance = p_lncp_init->total_distance;
+ p_lncp->elevation = p_lncp_init->elevation;
+ p_lncp->navigation_handles = p_lncp_init->navigation_handles;
+
+ p_lncp->fix_rate = BLE_LNS_NO_FIX;
+ p_lncp->selected_route = BLE_LNS_INVALID_ROUTE;
+
+ p_lncp->procedure_status = LNCP_STATE_NO_PROC_IN_PROGRESS;
+ p_lncp->conn_handle = BLE_CONN_HANDLE_INVALID;
+ p_lncp->is_navigation_running = false;
+ p_lncp->is_nav_notification_enabled = false;
+ p_lncp->is_ctrlpt_indication_enabled = false;
+
+ memset(&p_lncp->mask, 0, sizeof(ble_lncp_mask_t));
+
+ add_char_params.uuid = BLE_UUID_LN_CONTROL_POINT_CHAR;
+ add_char_params.max_len = 0;
+ add_char_params.char_props.indicate = true;
+ add_char_params.char_props.write = true;
+ add_char_params.is_defered_write = true;
+ add_char_params.is_var_len = true;
+ add_char_params.max_len = BLE_GATT_ATT_MTU_DEFAULT;
+ add_char_params.write_access = p_lncp_init->write_perm;
+ add_char_params.cccd_write_access = p_lncp_init->cccd_write_perm;
+
+ NRF_LOG_DEBUG("Initialized");
+
+ return characteristic_add(p_lncp->service_handle,
+ &add_char_params,
+ &p_lncp->ctrlpt_handles);
+}
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/experimental_ble_lns/ble_ln_cp.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/experimental_ble_lns/ble_ln_cp.h
new file mode 100644
index 0000000..768ba23
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/experimental_ble_lns/ble_ln_cp.h
@@ -0,0 +1,255 @@
+/**
+ * Copyright (c) 2015 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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
+ *
+ * @defgroup ble_sdk_srv_lncp Location and Navigation Service Control Point
+ * @{
+ * @ingroup ble_sdk_srv
+ * @brief Location and Navigation Service Control Point module
+ *
+ * @details This module implements the Location and Navigation Service Control Point behavior.
+ */
+
+#ifndef BLE_LN_CTRLPT_H__
+#define BLE_LN_CTRLPT_H__
+
+#include "ble_srv_common.h"
+#include "sdk_common.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define BLE_LNS_MAX_ROUTE_NAME_LEN BLE_GATT_ATT_MTU_DEFAULT - 5 /**< The maximum length of length of a route name. */
+#define MAX_CTRL_POINT_RESP_PARAM_LEN BLE_LNS_MAX_ROUTE_NAME_LEN + 3 /**< Maximum length of a control point response. */
+
+typedef struct ble_lncp_s ble_lncp_t;
+
+/** @brief Location and Navigation event type. This list defines the possible events types from the Location and Navigation Service. */
+typedef enum
+{
+ LNCP_EVT_ELEVATION_SET, /**< Location and Navigation elevation was set. */
+ LNCP_EVT_FIX_RATE_SET, /**< Fix rate was set. */
+ LNCP_EVT_ROUTE_SELECTED, /**< A route was selected. */
+ LNCP_EVT_NAV_COMMAND, /**< A navigation command was issued. */
+ LNCP_EVT_MASK_SET, /**< Location and Speed feature mask was set. */
+ LNCP_EVT_TOTAL_DISTANCE_SET /**< Location and Navigation total distance was set. */
+} ble_lncp_evt_type_t;
+
+
+/** @brief Navigation commands. These commands can be sent to the control point and returned by an event callback. */
+typedef enum
+{
+ LNCP_CMD_NAV_STOP = 0x00, /**< When received, is_navigation_running in @ref ble_lns_s will be set to false. */
+ LNCP_CMD_NAV_START = 0x01, /**< When received, is_navigation_running in @ref ble_lns_s will be set to true. */
+ LNCP_CMD_NAV_PAUSE = 0x02, /**< When received, is_navigation_running in @ref ble_lns_s will be set to false. */
+ LNCP_CMD_NAV_CONTINUE = 0x03, /**< When received, is_navigation_running in @ref ble_lns_s will be set to true. */
+ LNCP_CMD_NAV_SKIP_WAYPOINT = 0x04, /**< When received, is_navigation_running in @ref ble_lns_s will not be affected. */
+ LNCP_CMD_NAV_NEAREST = 0x05, /**< When received, is_navigation_running in @ref ble_lns_s will be set to true. */
+} ble_lncp_nav_cmd_t;
+#define LNCP_NAV_CMD_MAX 0x05
+#define LNCP_NAV_CMD_LEN (OPCODE_LENGTH + 1)
+
+
+#if defined(__CC_ARM)
+ #pragma push
+ #pragma anon_unions
+#elif defined(__ICCARM__)
+ #pragma language=extended
+#elif defined(__GNUC__)
+ /* anonymous unions are enabled by default */
+#endif
+
+/** @brief A mask can be used to temporarily enable and disable features of the Location and Speed characteristic.*/
+typedef union
+{
+ uint8_t flags;
+ struct
+ {
+ uint8_t instantaneous_speed :1;
+ uint8_t total_distance :1;
+ uint8_t location :1;
+ uint8_t elevation :1;
+ uint8_t heading :1;
+ uint8_t rolling_time :1;
+ uint8_t utc_time :1;
+ };
+} ble_lncp_mask_t;
+
+#if defined(__CC_ARM)
+ #pragma pop
+#elif defined(__ICCARM__)
+ /* leave anonymous unions enabled */
+#elif defined(__GNUC__)
+ /* anonymous unions are enabled by default */
+#endif
+
+typedef struct
+{
+ ble_lncp_evt_type_t evt_type;
+ union
+ {
+ ble_lncp_mask_t mask;
+ ble_lncp_nav_cmd_t nav_cmd;
+ uint32_t total_distance;
+ uint8_t fix_rate;
+ uint16_t selected_route;
+ uint32_t elevation;
+ } params;
+} ble_lncp_evt_t;
+
+
+// Location and Navigation Control Point response values
+typedef enum
+{
+ LNCP_RSP_RESERVED = 0x00, /**< Reserved for future use. */
+ LNCP_RSP_SUCCESS = 0x01, /**< Success. */
+ LNCP_RSP_OP_CODE_NOT_SUPPORTED = 0x02, /**< Op Code not supported. */
+ LNCP_RSP_INVALID_PARAMETER = 0x03, /**< Invalid Parameter. */
+ LNCP_RSP_OPERATION_FAILED = 0x04, /**< Operation Failed. */
+ LNCP_RSP_PROC_ALR_IN_PROG = BLE_GATT_STATUS_ATTERR_CPS_PROC_ALR_IN_PROG, /**< Control point procedure is already in progress. */
+ LNCP_RSP_CCCD_CONFIG_IMPROPER = BLE_GATT_STATUS_ATTERR_CPS_CCCD_CONFIG_ERROR /**< CCCD is improperly configured. */
+} ble_lncp_rsp_code_t;
+
+
+typedef ble_lncp_rsp_code_t (*ble_lncp_evt_handler_t) (ble_lncp_t const * p_lncp, ble_lncp_evt_t const * p_evt);
+
+// Location and Navigation Control Point Op Code values
+typedef enum
+{
+ LNCP_OP_RESERVED = 0x00, /**< Reserved for future use. */
+ LNCP_OP_SET_CUMULATIVE_VALUE = 0x01, /**< Set Cumulative Value. */
+ LNCP_OP_MASK_LOC_SPEED_CONTENT = 0x02, /**< Mask Location and Speed Characteristic Content. */
+ LNCP_OP_NAV_CONTROL = 0x03, /**< Navigation Control. */
+ LNCP_OP_REQ_NUM_ROUTES = 0x04, /**< Request Number of Routes. */
+ LNCP_OP_REQ_NAME_OF_ROUTE = 0x05, /**< Request Name of Route. */
+ LNCP_OP_SELECT_ROUTE = 0x06, /**< Select Route. */
+ LNCP_OP_SET_FIX_RATE = 0x07, /**< Set Fix Rate. */
+ LNCP_OP_SET_ELEVATION = 0x08, /**< Set Elevation. */
+ LNCP_OP_RESPONSE_CODE = 0x20 /**< Response code. */
+} ble_lncp_op_code_t;
+
+
+/** @brief Location and Navigation Control Point procedure status */
+typedef enum
+{
+ LNCP_STATE_NO_PROC_IN_PROGRESS, /**< No procedure in progress. */
+ LNCP_STATE_INDICATION_PENDING, /**< Control Point indication is pending. */
+ LNCP_STATE_CONFIRMATION_PENDING, /**< Waiting for the indication confirmation. */
+} ble_lncp_procedure_status_t;
+
+
+/** @brief Information included in a control point write response indication. */
+typedef struct
+{
+ ble_lncp_op_code_t op_code; /**< Opcode of the control point write action. */
+ ble_lncp_rsp_code_t rsp_code; /**< Response code of the control point write action. */
+ uint8_t rsp_param_len;
+ uint8_t rsp_param[MAX_CTRL_POINT_RESP_PARAM_LEN];
+} ble_lncp_rsp_t;
+
+
+typedef struct
+{
+ uint16_t service_handle;
+ ble_lncp_evt_handler_t evt_handler;
+ ble_srv_error_handler_t error_handler;
+
+ uint32_t available_features; /**< Value of the LN feature. */
+ bool is_position_quality_present; /**< If set to true, the position quality characteristic will be added. Else not. */
+ bool is_control_point_present; /**< If set to true, the control point characteristic will be added. Else not. */
+ bool is_navigation_present; /**< If set to true, the navigation characteristic will be added. Else not. */
+ ble_gatts_char_handles_t navigation_handles;
+
+ uint32_t total_distance;
+ uint32_t elevation;
+
+ security_req_t write_perm;
+ security_req_t cccd_write_perm;
+} ble_lncp_init_t;
+
+
+struct ble_lncp_s
+{
+ uint16_t conn_handle;
+ uint16_t service_handle;
+ ble_gatts_char_handles_t ctrlpt_handles;
+ ble_gatts_char_handles_t navigation_handles;
+ ble_lncp_evt_handler_t evt_handler;
+ ble_srv_error_handler_t error_handler;
+ ble_lncp_procedure_status_t procedure_status;
+ ble_lncp_rsp_t pending_rsp;
+
+ ble_lncp_mask_t mask;
+ uint32_t total_distance;
+ uint32_t elevation;
+ uint8_t fix_rate;
+ uint16_t selected_route;
+ uint32_t available_features; /**< Value of the LN feature. */
+ bool is_position_quality_present; /**< If set to true, the position quality characteristic will be added. Else not. */
+ bool is_control_point_present; /**< If set to true, the control point characteristic will be added. Else not. */
+ bool is_navigation_present; /**< If set to true, the navigation characteristic will be added. Else not. */
+ bool is_navigation_running; /**< This variable can be set using the control point. Must be true to be able to send navigation updates. */
+
+ bool is_ctrlpt_indication_enabled; /**< True if indication is enabled on the Control Point characteristic. */
+ bool is_nav_notification_enabled; /**< True if notification is enabled on the Navigation characteristic. */
+};
+
+
+void ble_lncp_on_ble_evt(ble_lncp_t * p_lncp, ble_evt_t const * p_ble_evt);
+
+uint32_t ble_lncp_total_distance_get(ble_lncp_t const * p_lncp);
+
+uint32_t ble_lncp_elevation_get(ble_lncp_t const * p_lncp);
+
+ble_lncp_mask_t ble_lncp_mask_get(ble_lncp_t const * p_lncp);
+
+bool ble_lncp_is_navigation_running(ble_lncp_t const * p_lncp);
+
+ret_code_t ble_lncp_init(ble_lncp_t * p_lncp, ble_lncp_init_t const * p_lncp_init);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif //BLE_LN_CTRLPT_H__
+
+/** @} */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/experimental_ble_lns/ble_ln_db.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/experimental_ble_lns/ble_ln_db.c
new file mode 100644
index 0000000..d1ef5f6
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/experimental_ble_lns/ble_ln_db.c
@@ -0,0 +1,151 @@
+/**
+ * Copyright (c) 2015 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#include "ble_ln_db.h"
+#include "ble_ln_common.h"
+
+typedef struct
+{
+ bool in_use_flag;
+ ble_lns_route_t record;
+} database_entry_t;
+
+static database_entry_t m_database[BLE_LNS_MAX_NUM_ROUTES];
+static uint8_t m_database_crossref[BLE_LNS_MAX_NUM_ROUTES];
+static uint16_t m_num_records;
+
+void ble_ln_db_init(void)
+{
+ int i;
+
+ for (i = 0; i < BLE_LNS_MAX_NUM_ROUTES; i++)
+ {
+ m_database[i].in_use_flag = false;
+ m_database_crossref[i] = 0xFF;
+ }
+
+ m_num_records = 0;
+}
+
+
+uint16_t ble_ln_db_num_records_get(void)
+{
+ return m_num_records;
+}
+
+
+ret_code_t ble_ln_db_record_get(uint8_t rec_ndx, ble_lns_route_t * p_rec)
+{
+ if (rec_ndx >= m_num_records)
+ {
+ return NRF_ERROR_INVALID_PARAM;
+ }
+
+ // copy record to the specified memory
+ *p_rec = m_database[m_database_crossref[rec_ndx]].record;
+
+ return NRF_SUCCESS;
+}
+
+
+ret_code_t ble_ln_db_record_name_get(uint8_t rec_ndx, uint8_t ** p_buf)
+{
+ if (rec_ndx >= m_num_records)
+ {
+ return NRF_ERROR_INVALID_PARAM;
+ }
+
+ // copy record to the specified memory
+ *p_buf = m_database[m_database_crossref[rec_ndx]].record.route_name;
+
+ return NRF_SUCCESS;
+}
+
+
+ret_code_t ble_ln_db_record_add(ble_lns_route_t * p_rec)
+{
+ int i;
+
+ if (m_num_records == BLE_LNS_MAX_NUM_ROUTES)
+ {
+ return NRF_ERROR_NO_MEM;
+ }
+
+ // find next available database entry
+ for (i = 0; i < BLE_LNS_MAX_NUM_ROUTES; i++)
+ {
+ if (!m_database[i].in_use_flag)
+ {
+ m_database[i].in_use_flag = true;
+ m_database[i].record = *p_rec;
+ m_database[i].record.route_id = i;
+ m_database_crossref[m_num_records] = i;
+ p_rec->route_id = i;
+ m_num_records++;
+ return NRF_SUCCESS;
+ }
+ }
+
+ return NRF_ERROR_NO_MEM;
+}
+
+
+ret_code_t ble_ln_db_record_delete(uint8_t rec_ndx)
+{
+ int i;
+
+ if (rec_ndx >= m_num_records)
+ {
+ return NRF_ERROR_NOT_FOUND;
+ }
+
+ // free entry
+ m_database[m_database_crossref[rec_ndx]].in_use_flag = false;
+
+ // decrease number of records
+ m_num_records--;
+
+ // remove cross reference index
+ for (i = rec_ndx; i < m_num_records; i++)
+ {
+ m_database_crossref[i] = m_database_crossref[i + 1];
+ }
+
+ return NRF_SUCCESS;
+}
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/experimental_ble_lns/ble_ln_db.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/experimental_ble_lns/ble_ln_db.h
new file mode 100644
index 0000000..649c19f
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/experimental_ble_lns/ble_ln_db.h
@@ -0,0 +1,122 @@
+/**
+ * Copyright (c) 2015 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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
+ *
+ * @defgroup ble_sdk_srv_ln_db Location and Navigation database
+ * @{
+ * @ingroup ble_sdk_srv
+ * @brief Location and Navigation route database
+ */
+
+#ifndef BLE_LN_DB__
+#define BLE_LN_DB__
+
+#include "ble_lns.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**@brief Function for initializing the route database.
+ *
+ * @details This call initializes the database holding route records.
+ *
+ * @return NRF_SUCCESS on success.
+ */
+void ble_ln_db_init(void);
+
+/**@brief Function for getting the number of records in the database.
+ *
+ * @details This call returns the number of records in the database.
+ *
+ * @return Number of records in the database.
+ */
+uint16_t ble_ln_db_num_records_get(void);
+
+/**@brief Function for getting a record from the database.
+ *
+ * @details This call returns a specified record from the database.
+ *
+ * @param[in] record_num Index of the record to retrieve.
+ * @param[out] p_rec Pointer to record structure where retrieved record is copied to.
+ *
+ * @return NRF_SUCCESS on success.
+ */
+ret_code_t ble_ln_db_record_get(uint8_t record_num, ble_lns_route_t * p_rec);
+
+/**@brief Function for getting a record name from the database.
+ *
+ * @details This call returns a specified record name from the database.
+ *
+ * @param[in] rec_ndx Index of the record to retrieve.
+ * @param[out] p_buf Pointer to array where retrieved record name is copied to.
+ *
+ * @return NRF_SUCCESS on success.
+ */
+ret_code_t ble_ln_db_record_name_get(uint8_t rec_ndx, uint8_t ** p_buf);
+
+/**@brief Function for adding a record at the end of the database.
+ *
+ * @details This call adds a record as the last record in the database.
+ *
+ * @param[in] p_rec Pointer to record to add to database.
+ *
+ * @return NRF_SUCCESS on success.
+ */
+ret_code_t ble_ln_db_record_add(ble_lns_route_t * p_rec);
+
+/**@brief Function for deleting a database entry.
+ *
+ * @details This call deletes an record from the database.
+ *
+ * @param[in] record_num Index of record to delete.
+ *
+ * @return NRF_SUCCESS on success.
+ */
+ret_code_t ble_ln_db_record_delete(uint8_t record_num);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // BLE_LN_DB_H__
+
+/** @} */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/experimental_ble_lns/ble_lns.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/experimental_ble_lns/ble_lns.c
new file mode 100644
index 0000000..4129d1d
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/experimental_ble_lns/ble_lns.c
@@ -0,0 +1,1014 @@
+/**
+ * Copyright (c) 2015 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#include "ble_lns.h"
+#include "ble_ln_db.h"
+#include "ble_ln_common.h"
+#include "sdk_common.h"
+
+#define NRF_LOG_MODULE_NAME ble_lns
+#include "nrf_log.h"
+NRF_LOG_MODULE_REGISTER();
+
+// Location and Speed flag bits
+#define LOC_SPEED_FLAG_INSTANT_SPEED_PRESENT (0x01 << 0) /**< Instantaneous Speed Present bit. */
+#define LOC_SPEED_FLAG_TOTAL_DISTANCE_PRESENT (0x01 << 1) /**< Total Distance Present bit. */
+#define LOC_SPEED_FLAG_LOCATION_PRESENT (0x01 << 2) /**< Location Present bit. */
+#define LOC_SPEED_FLAG_ELEVATION_PRESENT (0x01 << 3) /**< Elevation Present bit. */
+#define LOC_SPEED_FLAG_HEADING_PRESENT (0x01 << 4) /**< Heading Present bit. */
+#define LOC_SPEED_FLAG_ROLLING_TIME_PRESENT (0x01 << 5) /**< Rolling Time Present bit. */
+#define LOC_SPEED_FLAG_UTC_TIME_PRESENT (0x01 << 6) /**< UTC Time Present bit. */
+#define LOC_SPEED_FLAG_POSITION_STATUS (0x03 << 7) /**< Position Status bits(2). */
+#define LOC_SPEED_FLAG_SPEED_AND_DIST_FORMAT (0x01 << 9) /**< Speed and Distance Format. */
+#define LOC_SPEED_FLAG_ELEVATION_SOURCE (0x03 << 10) /**< Elevation Source bits(2). */
+#define LOC_SPEED_FLAG_HEADING_SOURCE (0x01 << 12) /**< Heading Source. */
+
+// Position Quality flag bits
+#define POS_QUAL_FLAG_NUM_SATS_IN_SOLUTION_PRESENT (0x01 << 0) /**< Number of Satellites in Solution Present bit. */
+#define POS_QUAL_FLAG_NUM_SATS_IN_VIEW_PRESENT (0x01 << 1) /**< Number of Satellites in View Present bit. */
+#define POS_QUAL_FLAG_TIME_TO_FIRST_FIX_PRESESNT (0x01 << 2) /**< Time to First Fix Present bit. */
+#define POS_QUAL_FLAG_EHPE_PRESENT (0x01 << 3) /**< EHPE Present bit. */
+#define POS_QUAL_FLAG_EVPE_PRESENT (0x01 << 4) /**< EVPE Present bit. */
+#define POS_QUAL_FLAG_HDOP_PRESENT (0x01 << 5) /**< HDOP Present bit. */
+#define POS_QUAL_FLAG_VDOP_PRESENT (0x01 << 6) /**< VDOP Present bit. */
+#define POS_QUAL_FLAG_POSITION_STATUS (0x03 << 7) /**< Position Status bits(2). */
+
+// Navigation flag bits
+#define NAV_FLAG_REMAINING_DIST_PRESENT (0x01 << 0) /**< Remaining Distance Present bit. */
+#define NAV_FLAG_REAMINGING_VERT_DIST_PRESESNT (0x01 << 1) /**< Remaining Vertical Distance Present bit . */
+#define NAV_FLAG_ETA_PRESENT (0x01 << 2) /**< Estimated Time of Arrival Present bit. */
+#define NAV_FLAG_POSITION_STATUS (0x03 << 3) /**< Position Status bits(2). */
+#define NAV_FLAG_HEADING_SOURCE (0x01 << 5) /**< Heading Source bit. */
+#define NAV_FLAG_NAVIGATION_INDICATOR_TYPE (0x01 << 6) /**< Navigation Indicator Type bit. */
+#define NAV_FLAG_WAYPOINT_REACHED (0x01 << 7) /**< Waypoint Reached bit. */
+#define NAV_FLAG_DESTINATION_REACHED (0x01 << 8) /**< Destination Reached bit. */
+
+#define BLE_LNS_NAV_MAX_LEN 19 /**< The length of a navigation notification when all features are enabled. See @ref ble_lns_navigation_t to see what this represents, or check https://developer.bluetooth.org/gatt/characteristics/Pages/CharacteristicViewer.aspx?u=org.bluetooth.characteristic.navigation.xml. */
+
+
+static void notification_buffer_process(ble_lns_t * p_lns)
+{
+ notification_t * p_notification;
+
+ // See if a notification is pending
+ if (p_lns->pending_loc_speed_notifications[0].is_pending == true)
+ {
+ p_notification = &p_lns->pending_loc_speed_notifications[0];
+ }
+ else if (p_lns->pending_loc_speed_notifications[1].is_pending == true)
+ {
+ p_notification = &p_lns->pending_loc_speed_notifications[1];
+ }
+ else if (p_lns->pending_navigation_notification.is_pending == true)
+ {
+ p_notification = &p_lns->pending_navigation_notification;
+ }
+ else
+ {
+ p_notification = NULL;
+ }
+
+ // send the notification if necessary
+ if (p_notification != NULL)
+ {
+ uint32_t err_code;
+ ble_gatts_hvx_params_t hvx_params;
+
+ memset(&hvx_params, 0, sizeof(hvx_params));
+
+ uint16_t hvx_len = p_notification->len;
+
+ hvx_params.handle = p_notification->handle;
+ hvx_params.type = BLE_GATT_HVX_NOTIFICATION;
+ hvx_params.offset = 0;
+ hvx_params.p_len = &hvx_len;
+ hvx_params.p_data = &p_notification->data[0];
+
+ err_code = sd_ble_gatts_hvx(p_lns->conn_handle, &hvx_params);
+
+ if ((err_code == NRF_SUCCESS) && (hvx_len == p_notification->len))
+ {
+ p_notification->is_pending = false;
+ }
+ }
+}
+
+
+/**@brief Connect event handler.
+ *
+ * @param[in] p_lns Location and Navigation Service structure.
+ * @param[in] p_ble_evt Event received from the BLE stack.
+ */
+static void on_connect(ble_lns_t * p_lns, ble_evt_t const * p_ble_evt)
+{
+ p_lns->conn_handle = p_ble_evt->evt.gap_evt.conn_handle;
+
+ // clear pending notifications
+ p_lns->pending_loc_speed_notifications[0].is_pending = false;
+ p_lns->pending_loc_speed_notifications[1].is_pending = false;
+ p_lns->pending_navigation_notification.is_pending = false;
+}
+
+
+/**@brief Disconnect event handler.
+ *
+ * @param[in] p_lns Location and Navigation Service structure.
+ * @param[in] p_ble_evt Event received from the BLE stack.
+ */
+static void on_disconnect(ble_lns_t * p_lns, ble_evt_t const * p_ble_evt)
+{
+ if (p_lns->conn_handle != p_ble_evt->evt.gatts_evt.conn_handle)
+ {
+ return;
+ }
+
+ p_lns->conn_handle = BLE_CONN_HANDLE_INVALID;
+}
+
+
+/**@brief Handle write events to the control point cccd.
+ *
+ * @param[in] p_lncp Location and Navigation Service structure.
+ * @param[in] p_evt_write Write event received from the BLE stack.
+ */
+static void on_ctrl_pt_cccd_write(ble_lns_t * p_lns, ble_gatts_evt_write_t const * p_evt_write)
+{
+ if (p_evt_write->len == BLE_CCCD_VALUE_LEN)
+ {
+ if (p_lns->evt_handler != NULL)
+ {
+ ble_lns_evt_t evt;
+
+ if (ble_srv_is_indication_enabled(p_evt_write->data))
+ {
+ evt.evt_type = BLE_LNS_CTRLPT_EVT_INDICATION_ENABLED;
+ }
+ else
+ {
+ evt.evt_type = BLE_LNS_CTRLPT_EVT_INDICATION_DISABLED;
+ }
+
+ p_lns->evt_handler(p_lns, &evt);
+ }
+ }
+}
+
+
+/**@brief Handle write events to the Location and Speed cccd.
+ *
+ * @param[in] p_lns Location and Navigation Service structure.
+ * @param[in] p_evt_write Write event received from the BLE stack.
+ */
+static void on_loc_speed_cccd_write(ble_lns_t * p_lns,
+ ble_gatts_evt_write_t const * p_evt_write)
+{
+ if (p_evt_write->len == BLE_CCCD_VALUE_LEN)
+ {
+ // CCCD written, update notification state
+ p_lns->is_loc_speed_notification_enabled = ble_srv_is_notification_enabled(p_evt_write->data);
+ if (p_lns->evt_handler != NULL)
+ {
+ ble_lns_evt_t evt;
+
+ if (p_lns->is_loc_speed_notification_enabled)
+ {
+ evt.evt_type = BLE_LNS_LOC_SPEED_EVT_NOTIFICATION_ENABLED;
+ }
+ else
+ {
+ evt.evt_type = BLE_LNS_LOC_SPEED_EVT_NOTIFICATION_DISABLED;
+ }
+
+ p_lns->evt_handler(p_lns, &evt);
+ }
+ }
+}
+
+
+/**@brief Handle write events to the navigation cccd.
+ *
+ * @param[in] p_lns Location and Navigation Service structure.
+ * @param[in] p_evt_write Write event received from the BLE stack.
+ */
+static void on_nav_cccd_write(ble_lns_t * p_lns,
+ ble_gatts_evt_write_t const * p_evt_write)
+{
+ if (p_evt_write->len == BLE_CCCD_VALUE_LEN)
+ {
+ p_lns->is_nav_notification_enabled = ble_srv_is_notification_enabled(p_evt_write->data);
+ if (p_lns->evt_handler != NULL)
+ {
+ ble_lns_evt_t evt;
+
+ if (p_lns->is_nav_notification_enabled)
+ {
+ evt.evt_type = BLE_LNS_NAVIGATION_EVT_NOTIFICATION_ENABLED;
+ }
+ else
+ {
+ evt.evt_type = BLE_LNS_NAVIGATION_EVT_NOTIFICATION_DISABLED;
+ }
+
+ p_lns->evt_handler(p_lns, &evt);
+ }
+ }
+}
+
+
+/**@brief Write event handler.
+ *
+ * @param[in] p_lns Location and Navigation Service structure.
+ * @param[in] p_ble_evt Event received from the BLE stack.
+ */
+static void on_write(ble_lns_t * p_lns, ble_evt_t const * p_ble_evt)
+{
+ if (p_lns->conn_handle != p_ble_evt->evt.gatts_evt.conn_handle)
+ {
+ return;
+ }
+
+ ble_gatts_evt_write_t const * p_evt_write = &p_ble_evt->evt.gatts_evt.params.write;
+
+ if (p_evt_write->handle == p_lns->ctrlpt_handles.cccd_handle)
+ {
+ on_ctrl_pt_cccd_write(p_lns, p_evt_write);
+ }
+ else if (p_evt_write->handle == p_lns->loc_speed_handles.cccd_handle)
+ {
+ on_loc_speed_cccd_write(p_lns, p_evt_write);
+ }
+ else if (p_evt_write->handle == p_lns->navigation_handles.cccd_handle)
+ {
+ on_nav_cccd_write(p_lns, p_evt_write);
+ }
+}
+
+
+/**@brief Tx Complete event handler. This is used to retry sending a packet.
+ *
+ * @details Tx Complete event handler.
+ * Handles WRITE events from the BLE stack and if an indication was pending try sending it
+ * again.
+ *
+ * @param[in] p_lns Location navigation structure.
+ */
+static void on_tx_complete(ble_lns_t * p_lns)
+{
+ notification_buffer_process(p_lns);
+}
+
+
+/**@brief Encode position quality.
+ *
+ * @param[in] p_lns Location and Navigation Service structure.
+ * @param[in] p_pos_qual Position quality data to be encoded.
+ * @param[out] p_encoded_buffer Buffer where the encoded data will be written.
+ *
+ * @return Size of encoded data.
+ */
+static uint8_t pos_qual_encode(ble_lns_t const * p_lns,
+ ble_lns_pos_quality_t const * p_pos_qual,
+ uint8_t * p_encoded_buffer)
+{
+ uint16_t flags = 0;
+ uint8_t len = 2; // flags are added at last
+
+ flags |= ((uint16_t)p_pos_qual->position_status << 7) & POS_QUAL_FLAG_POSITION_STATUS;
+
+ if (p_pos_qual->number_of_satellites_in_solution_present)
+ {
+ flags |= POS_QUAL_FLAG_NUM_SATS_IN_SOLUTION_PRESENT;
+ p_encoded_buffer[len++] = p_pos_qual->number_of_satellites_in_solution;
+ }
+
+ if (p_pos_qual->number_of_satellites_in_view_present)
+ {
+ flags |= POS_QUAL_FLAG_NUM_SATS_IN_VIEW_PRESENT;
+ p_encoded_buffer[len++] = p_pos_qual->number_of_satellites_in_view;
+ }
+
+ if (p_pos_qual->time_to_first_fix_present)
+ {
+ flags |= POS_QUAL_FLAG_TIME_TO_FIRST_FIX_PRESESNT;
+ len += uint16_encode(p_pos_qual->time_to_first_fix, &p_encoded_buffer[len]);
+ }
+
+ if (p_pos_qual->ehpe_present)
+ {
+ flags |= POS_QUAL_FLAG_EHPE_PRESENT;
+ len += uint32_encode(p_pos_qual->ehpe, &p_encoded_buffer[len]);
+ }
+
+ if (p_pos_qual->evpe_present)
+ {
+ flags |= POS_QUAL_FLAG_EVPE_PRESENT;
+ len += uint32_encode(p_pos_qual->evpe, &p_encoded_buffer[len]);
+ }
+
+ if (p_pos_qual->hdop_present)
+ {
+ flags |= POS_QUAL_FLAG_HDOP_PRESENT;
+ p_encoded_buffer[len++] = p_pos_qual->hdop;
+ }
+
+ if (p_pos_qual->vdop_present)
+ {
+ flags |= POS_QUAL_FLAG_VDOP_PRESENT;
+ p_encoded_buffer[len++] = p_pos_qual->vdop;
+ }
+
+ // Flags field
+ uint16_encode(flags, &p_encoded_buffer[0]); //lint !e534 "Ignoring return value of function"
+
+ return len;
+}
+
+
+/**@brief Encode Location and Speed data packet 1
+ *
+ * @param[in] p_lns Location and Navigation Service structure.
+ * @param[in] p_loc_speed Location and Speed data to be encoded.
+ * @param[out] p_encoded_buffer Pointer to buffer buffer where encoded data will be written.
+ *
+ * @return Size of encoded data.
+ *
+ */
+static uint8_t loc_speed_encode_packet1(ble_lns_t const * p_lns,
+ ble_lns_loc_speed_t const * p_loc_speed,
+ uint8_t * p_encoded_buffer)
+{
+ uint16_t flags = 0;
+ uint8_t len = 2;
+
+ ble_lncp_mask_t const mask = ble_lncp_mask_get(&p_lns->ctrl_pt);
+
+ // Instantaneous Speed
+ if (p_lns->available_features & BLE_LNS_FEATURE_INSTANT_SPEED_SUPPORTED)
+ {
+ if (p_loc_speed->instant_speed_present && !mask.instantaneous_speed)
+ {
+ flags |= LOC_SPEED_FLAG_INSTANT_SPEED_PRESENT;
+ flags |= ((uint16_t)p_loc_speed->data_format<<9) & LOC_SPEED_FLAG_SPEED_AND_DIST_FORMAT;
+ len += uint16_encode(p_loc_speed->instant_speed, &p_encoded_buffer[len]);
+ }
+ }
+
+ // Total Distance
+ if (p_lns->available_features & BLE_LNS_FEATURE_TOTAL_DISTANCE_SUPPORTED)
+ {
+ if (p_loc_speed->total_distance_present && !mask.total_distance)
+ {
+ uint32_t const total_distance = ble_lncp_total_distance_get(&p_lns->ctrl_pt);
+ flags |= LOC_SPEED_FLAG_TOTAL_DISTANCE_PRESENT;
+ len += uint24_encode(total_distance, &p_encoded_buffer[len]);
+ }
+ }
+
+ // Location
+ if (p_lns->available_features & BLE_LNS_FEATURE_LOCATION_SUPPORTED)
+ {
+ if (p_loc_speed->location_present && !mask.location)
+ {
+ flags |= LOC_SPEED_FLAG_LOCATION_PRESENT;
+ flags |= ((uint16_t)p_loc_speed->position_status <<7) & LOC_SPEED_FLAG_POSITION_STATUS;
+ len += uint32_encode(p_loc_speed->latitude, &p_encoded_buffer[len]);
+ len += uint32_encode(p_loc_speed->longitude, &p_encoded_buffer[len]);
+ }
+ }
+
+ // Flags field
+ uint16_encode(flags, &p_encoded_buffer[0]); //lint !e534 "Ignoring return value of function"
+
+ return len;
+}
+
+
+/**@brief Encode Location and Speed data packet 2
+ *
+ * @param[in] p_lns Location and Navigation Service structure.
+ * @param[in] p_loc_speed Location and Speed data to be encoded.
+ * @param[out] p_encoded_buffer Pointer to buffer buffer where encoded data will be written.
+ *
+ * @return Size of encoded data.
+ *
+ */
+static uint8_t loc_speed_encode_packet2(ble_lns_t const * p_lns,
+ ble_lns_loc_speed_t const * p_loc_speed,
+ uint8_t * p_encoded_buffer)
+{
+ uint16_t flags = 0;
+ uint8_t len = 2;
+
+ ble_lncp_mask_t const mask = ble_lncp_mask_get(&p_lns->ctrl_pt);
+
+ // Elevation
+ if (p_lns->available_features & BLE_LNS_FEATURE_ELEVATION_SUPPORTED)
+ {
+ if (p_loc_speed->elevation_present && !mask.elevation)
+ {
+ uint32_t const elevation = ble_lncp_elevation_get(&p_lns->ctrl_pt);
+
+ flags |= LOC_SPEED_FLAG_ELEVATION_PRESENT;
+ flags |= ((uint16_t) p_loc_speed->elevation_source << 10) & LOC_SPEED_FLAG_ELEVATION_SOURCE;
+ len += uint24_encode(elevation, &p_encoded_buffer[len]);
+ }
+ }
+
+ // Heading
+ if (p_lns->available_features & BLE_LNS_FEATURE_HEADING_SUPPORTED)
+ {
+ if (p_loc_speed->heading_present && !mask.heading)
+ {
+ flags |= LOC_SPEED_FLAG_HEADING_PRESENT;
+ flags |= ((uint16_t) p_loc_speed->heading_source << 12) & LOC_SPEED_FLAG_HEADING_SOURCE;
+ len += uint16_encode(p_loc_speed->heading, &p_encoded_buffer[len]);
+ }
+ }
+
+ // Rolling Time
+ if (p_lns->available_features & BLE_LNS_FEATURE_ROLLING_TIME_SUPPORTED)
+ {
+ if ((p_loc_speed->rolling_time_present && !mask.rolling_time))
+ {
+ flags |= LOC_SPEED_FLAG_ROLLING_TIME_PRESENT;
+ p_encoded_buffer[len++] = p_loc_speed->rolling_time;
+ }
+ }
+
+ // UTC Time
+ if (p_lns->available_features & BLE_LNS_FEATURE_UTC_TIME_SUPPORTED)
+ {
+ if ((p_loc_speed->utc_time_time_present && !mask.utc_time))
+ {
+ flags |= LOC_SPEED_FLAG_UTC_TIME_PRESENT;
+ len += ble_date_time_encode(&p_loc_speed->utc_time, &p_encoded_buffer[len]);
+ }
+ }
+ // Flags field
+ uint16_encode(flags, &p_encoded_buffer[0]); //lint !e534 "Ignoring return value of function"
+
+ return len;
+}
+
+
+/**@brief Encode Navigation data.
+ *
+ * @param[in] p_lns Location and Navigation Service structure.
+ * @param[in] p_navigation Navigation data to be encoded.
+ * @param[out] p_encoded_buffer Buffer where the encoded data will be written.
+ *
+ * @return Size of encoded data.
+ */
+static uint8_t navigation_encode(ble_lns_t const * p_lns,
+ ble_lns_navigation_t const * p_navigation,
+ uint8_t * p_encoded_buffer)
+{
+ uint16_t flags = 0;
+ uint8_t len = 2;
+
+ // Bearing
+ len += uint16_encode(p_navigation->bearing, &p_encoded_buffer[len]);
+
+ // Heading
+ len += uint16_encode(p_navigation->heading, &p_encoded_buffer[len]);
+
+ // Remaining Distance
+ if (p_lns->available_features & BLE_LNS_FEATURE_REMAINING_DISTANCE_SUPPORTED)
+ {
+ if (p_navigation->remaining_dist_present)
+ {
+ flags |= NAV_FLAG_REMAINING_DIST_PRESENT;
+ p_encoded_buffer[len++] = ((p_navigation->remaining_distance >> 0) & 0xFF);
+ p_encoded_buffer[len++] = ((p_navigation->remaining_distance >> 8) & 0xFF);
+ p_encoded_buffer[len++] = ((p_navigation->remaining_distance >> 16) & 0xFF);
+ }
+ }
+
+ // Remaining Vertical Distance
+ if (p_lns->available_features & BLE_LNS_FEATURE_REMAINING_VERT_DISTANCE_SUPPORTED)
+ {
+ if (p_navigation->remaining_vert_dist_present)
+ {
+ flags |= NAV_FLAG_REAMINGING_VERT_DIST_PRESESNT;
+ p_encoded_buffer[len++] = ((p_navigation->remaining_vert_distance >> 0) & 0xFF);
+ p_encoded_buffer[len++] = ((p_navigation->remaining_vert_distance >> 8) & 0xFF);
+ p_encoded_buffer[len++] = ((p_navigation->remaining_vert_distance >> 16) & 0xFF);
+ }
+ }
+
+ // Estimated Time of Arrival
+ if (p_lns->available_features & BLE_LNS_FEATURE_EST_TIME_OF_ARRIVAL_SUPPORTED)
+ {
+ if (p_navigation->eta_present)
+ {
+ flags |= NAV_FLAG_ETA_PRESENT;
+ len += ble_date_time_encode(&p_navigation->eta, &p_encoded_buffer[len]);
+ }
+ }
+
+ flags |= ((uint16_t)p_navigation->position_status <<3) & NAV_FLAG_POSITION_STATUS;
+ flags |= ((uint16_t)p_navigation->heading_source <<5) & NAV_FLAG_HEADING_SOURCE;
+ flags |= ((uint16_t)p_navigation->navigation_indicator_type<<6)& NAV_FLAG_NAVIGATION_INDICATOR_TYPE;
+ flags |= ((uint16_t)p_navigation->waypoint_reached <<7)& NAV_FLAG_WAYPOINT_REACHED;
+ flags |= ((uint16_t)p_navigation->destination_reached <<8)& NAV_FLAG_DESTINATION_REACHED;
+
+ // Flags field
+ uint16_encode(flags, &p_encoded_buffer[0]); //lint !e534 "Ignoring return value of function"
+
+ return len;
+}
+
+
+/**@brief Add Location and Navigation Feature characteristic.
+ *
+ * @param[in] p_lns Location and Navigation Service structure.
+ * @param[in] p_lns_init Information needed to initialize the service.
+ *
+ * @return NRF_SUCCESS on success, otherwise an error code.
+ */
+static ret_code_t loc_and_nav_feature_char_add(ble_lns_t * p_lns, ble_lns_init_t const * p_lns_init)
+{
+ uint8_t init_value_encoded[sizeof(uint32_t)];
+ uint8_t len;
+ ble_add_char_params_t add_char_params;
+
+ len = uint32_encode(p_lns_init->available_features, init_value_encoded);
+
+ memset(&add_char_params, 0, sizeof(add_char_params));
+
+ add_char_params.uuid = BLE_UUID_LN_FEATURE_CHAR;
+ add_char_params.max_len = len;
+ add_char_params.init_len = len;
+ add_char_params.p_init_value = &init_value_encoded[0];
+ add_char_params.char_props.read = true;
+ add_char_params.read_access = p_lns_init->loc_nav_feature_security_req_read_perm;
+
+ return characteristic_add(p_lns->service_handle,
+ &add_char_params,
+ &p_lns->feature_handles);
+}
+
+
+/**@brief Add Location and Speed characteristic.
+ *
+ * @param[in] p_lns Location and Navigation Service structure.
+ * @param[in] p_lns_init Information needed to initialize the service.
+ *
+ * @return NRF_SUCCESS on success, otherwise an error code.
+ */
+static ret_code_t loc_speed_char_add(ble_lns_t * p_lns, ble_lns_init_t const * p_lns_init)
+{
+ uint8_t encoded_initial_loc_speed1[BLE_GATT_ATT_MTU_DEFAULT];
+ uint8_t len;
+ ble_add_char_params_t add_char_params;
+
+ len = loc_speed_encode_packet1(p_lns, p_lns_init->p_location_speed, &encoded_initial_loc_speed1[0]);
+
+ memset(&add_char_params, 0, sizeof(add_char_params));
+
+ add_char_params.uuid = BLE_UUID_LN_LOCATION_AND_SPEED_CHAR;
+ add_char_params.max_len = BLE_GATT_ATT_MTU_DEFAULT ;
+ add_char_params.init_len = len;
+ add_char_params.p_init_value = &encoded_initial_loc_speed1[0];
+ add_char_params.is_var_len = true;
+ add_char_params.char_props.notify = true;
+ add_char_params.cccd_write_access = p_lns_init->loc_speed_security_req_cccd_write_perm;
+
+ return characteristic_add(p_lns->service_handle,
+ &add_char_params,
+ &p_lns->loc_speed_handles);
+}
+
+
+/**@brief Add Location and Navigation position quality characteristic.
+ *
+ * @param[in] p_lns Location and Navigation Service structure.
+ * @param[in] p_lns_init Information needed to initialize the service.
+ *
+ * @return NRF_SUCCESS on success, otherwise an error code.
+ */
+static ret_code_t pos_quality_char_add(ble_lns_t * p_lns, ble_lns_init_t const * p_lns_init)
+{
+ uint8_t len;
+ uint8_t init_value_encoded[BLE_GATT_ATT_MTU_DEFAULT];
+ ble_add_char_params_t add_char_params;
+
+ len = pos_qual_encode(p_lns, p_lns_init->p_position_quality, init_value_encoded);
+
+ memset(&add_char_params, 0, sizeof(add_char_params));
+
+ add_char_params.uuid = BLE_UUID_LN_POSITION_QUALITY_CHAR;
+ add_char_params.max_len = BLE_GATT_ATT_MTU_DEFAULT ;
+ add_char_params.init_len = len;
+ add_char_params.p_init_value = init_value_encoded;
+ add_char_params.char_props.read = true;
+ add_char_params.read_access = p_lns_init->position_quality_security_req_read_perm;
+
+ return characteristic_add(p_lns->service_handle,
+ &add_char_params,
+ &p_lns->pos_qual_handles);
+}
+
+
+/**@brief Add Navigation characteristic.
+ *
+ * @param[in] p_lns Location and Navigation Service structure.
+ * @param[in] p_lns_init Information needed to initialize the service.
+ *
+ * @return NRF_SUCCESS on success, otherwise an error code.
+ */
+static ret_code_t navigation_char_add(ble_lns_t * p_lns, ble_lns_init_t const * p_lns_init)
+{
+ ble_add_char_params_t add_char_params;
+
+ memset(&add_char_params, 0, sizeof(add_char_params));
+
+ add_char_params.uuid = BLE_UUID_LN_NAVIGATION_CHAR;
+ add_char_params.max_len = BLE_LNS_NAV_MAX_LEN;
+ add_char_params.init_len = 0;
+ add_char_params.p_init_value = NULL;
+ add_char_params.char_props.notify = true;
+ add_char_params.cccd_write_access = p_lns_init->navigation_security_req_cccd_write_perm;
+
+ return characteristic_add(p_lns->service_handle,
+ &add_char_params,
+ &p_lns->navigation_handles);
+}
+
+
+/** @brief Check if there is a mismatch in initialization parameters.
+ *
+ * @details It is possible to give an input which has an internal mismatch. Such a mismatch can arise in two different ways.
+ * One possibility is a mismatch between the characteristic present indicators and the available features specified.
+ * The other mismatch arises when no pointer to the characteristic data structure is specified.
+ *
+ * @param[in] p_lns_init The init structure which will be checked
+ *
+ * @return false if there is no mismatch. true if there is a mismatch
+ */
+static bool init_param_mismatch_present(ble_lns_init_t const * p_lns_init)
+{
+ if (p_lns_init->is_position_quality_present == false)
+ {
+ if (p_lns_init->available_features &
+ (BLE_LNS_FEATURE_NUM_SATS_IN_SOLUTION_SUPPORTED |
+ BLE_LNS_FEATURE_NUM_SATS_IN_VIEW_SUPPORTED |
+ BLE_LNS_FEATURE_TIME_TO_FIRST_FIX_SUPPORTED |
+ BLE_LNS_FEATURE_EST_HORZ_POS_ERROR_SUPPORTED |
+ BLE_LNS_FEATURE_EST_VERT_POS_ERROR_SUPPORTED |
+ BLE_LNS_FEATURE_HORZ_DILUTION_OF_PRECISION_SUPPORTED |
+ BLE_LNS_FEATURE_VERT_DILUTION_OF_PRECISION_SUPPORTED)
+ )
+ {
+ return true;
+ }
+ if (p_lns_init->p_position_quality != NULL)
+ {
+ return true;
+ }
+ }
+ else if (p_lns_init->is_position_quality_present == true)
+ {
+ if (p_lns_init->p_position_quality == NULL)
+ {
+ return true;
+ }
+ }
+
+ if (p_lns_init->is_control_point_present == false)
+ {
+ if (p_lns_init->available_features &
+ (BLE_LNS_FEATURE_LOC_AND_SPEED_CONTENT_MASKING_SUPPORTED |
+ BLE_LNS_FEATURE_FIX_RATE_SETTING_SUPPORTED |
+ BLE_LNS_FEATURE_ELEVATION_SETTING_SUPPORTED)
+ )
+ {
+ return true;
+ }
+ }
+
+ if (p_lns_init->is_navigation_present == false)
+ {
+ if (p_lns_init->available_features &
+ (BLE_LNS_FEATURE_REMAINING_DISTANCE_SUPPORTED |
+ BLE_LNS_FEATURE_REMAINING_VERT_DISTANCE_SUPPORTED |
+ BLE_LNS_FEATURE_EST_TIME_OF_ARRIVAL_SUPPORTED)
+ )
+ {
+ return true;
+ }
+ if (p_lns_init->p_navigation != NULL)
+ {
+ return true;
+ }
+ }
+ else if (p_lns_init->is_navigation_present == true)
+ {
+ if (p_lns_init->p_navigation == NULL)
+ {
+ return true;
+ }
+ }
+
+ // location and speed must always be specified
+ if (p_lns_init->p_location_speed == NULL)
+ {
+ return true;
+ }
+
+ return false;
+}
+
+
+void ble_lns_on_ble_evt(ble_evt_t const * p_ble_evt, void * p_context)
+{
+ VERIFY_PARAM_NOT_NULL_VOID(p_context);
+ VERIFY_PARAM_NOT_NULL_VOID(p_ble_evt);
+
+ ble_lns_t * p_lns = (ble_lns_t *)p_context;
+ ble_lncp_on_ble_evt(&p_lns->ctrl_pt, p_ble_evt);
+
+ switch (p_ble_evt->header.evt_id)
+ {
+ case BLE_GAP_EVT_CONNECTED:
+ on_connect(p_lns, p_ble_evt);
+ break;
+
+ case BLE_GAP_EVT_DISCONNECTED:
+ on_disconnect(p_lns, p_ble_evt);
+ break;
+
+ case BLE_GATTS_EVT_WRITE:
+ on_write(p_lns, p_ble_evt);
+ break;
+
+ case BLE_GATTS_EVT_HVN_TX_COMPLETE:
+ on_tx_complete(p_lns);
+ break;
+
+ default:
+ // no implementation
+ break;
+ }
+}
+
+
+ret_code_t ble_lns_init(ble_lns_t * p_lns, ble_lns_init_t const * p_lns_init)
+{
+ VERIFY_PARAM_NOT_NULL(p_lns);
+ VERIFY_PARAM_NOT_NULL(p_lns_init);
+
+ if (init_param_mismatch_present(p_lns_init) == true)
+ {
+ return NRF_ERROR_INVALID_PARAM;
+ }
+
+ uint32_t err_code;
+ ble_uuid_t service_uuid;
+ ble_lncp_init_t lncp_init;
+
+ // Initialize service structure
+ p_lns->evt_handler = p_lns_init->evt_handler;
+ p_lns->error_handler = p_lns_init->error_handler;
+ p_lns->conn_handle = BLE_CONN_HANDLE_INVALID;
+ p_lns->available_features = p_lns_init->available_features;
+ p_lns->is_navigation_present = p_lns_init->is_navigation_present;
+
+ // clear pending notifications
+ p_lns->pending_loc_speed_notifications[0].is_pending = false;
+ p_lns->pending_loc_speed_notifications[1].is_pending = false;
+ p_lns->pending_navigation_notification.is_pending = false;
+
+ p_lns->p_location_speed = p_lns_init->p_location_speed;
+ p_lns->p_position_quality = p_lns_init->p_position_quality;
+ p_lns->p_navigation = p_lns_init->p_navigation;
+
+ p_lns->is_loc_speed_notification_enabled = false;
+ p_lns->is_nav_notification_enabled = false;
+
+ ble_ln_db_init();
+
+ // Add service
+ BLE_UUID_BLE_ASSIGN(service_uuid, BLE_UUID_LOCATION_AND_NAVIGATION_SERVICE);
+
+ err_code = sd_ble_gatts_service_add(BLE_GATTS_SRVC_TYPE_PRIMARY, &service_uuid, &p_lns->service_handle);
+ VERIFY_SUCCESS(err_code);
+
+ // Add location and navigation feature characteristic
+ err_code = loc_and_nav_feature_char_add(p_lns, p_lns_init);
+ VERIFY_SUCCESS(err_code);
+
+ // Add location and speed characteristic
+ err_code = loc_speed_char_add(p_lns, p_lns_init);
+ VERIFY_SUCCESS(err_code);
+
+ if (p_lns_init->is_position_quality_present)
+ {
+ // Add Position quality characteristic
+ err_code = pos_quality_char_add(p_lns, p_lns_init);
+ VERIFY_SUCCESS(err_code);
+ }
+ else
+ {
+ p_lns->pos_qual_handles.cccd_handle = BLE_GATT_HANDLE_INVALID;
+ p_lns->pos_qual_handles.sccd_handle = BLE_GATT_HANDLE_INVALID;
+ p_lns->pos_qual_handles.user_desc_handle = BLE_GATT_HANDLE_INVALID;
+ p_lns->pos_qual_handles.value_handle = BLE_GATT_HANDLE_INVALID;
+ }
+
+ if (p_lns_init->is_navigation_present)
+ {
+ // Add navigation characteristic
+ err_code = navigation_char_add(p_lns, p_lns_init);
+ VERIFY_SUCCESS(err_code);
+ }
+ else
+ {
+ p_lns->navigation_handles.cccd_handle = BLE_GATT_HANDLE_INVALID;
+ p_lns->navigation_handles.sccd_handle = BLE_GATT_HANDLE_INVALID;
+ p_lns->navigation_handles.user_desc_handle = BLE_GATT_HANDLE_INVALID;
+ p_lns->navigation_handles.value_handle = BLE_GATT_HANDLE_INVALID;
+ }
+
+ if (p_lns_init->is_control_point_present)
+ {
+ lncp_init.error_handler = p_lns_init->error_handler;
+ lncp_init.evt_handler = p_lns_init->lncp_evt_handler;
+ lncp_init.write_perm = p_lns_init->ctrl_point_security_req_write_perm;
+ lncp_init.cccd_write_perm = p_lns_init->ctrl_point_security_req_cccd_write_perm;
+ lncp_init.available_features = p_lns_init->available_features;
+ lncp_init.is_position_quality_present = p_lns_init->is_position_quality_present;
+ lncp_init.is_navigation_present = p_lns_init->is_navigation_present;
+
+ lncp_init.total_distance = p_lns_init->p_location_speed->total_distance;
+ lncp_init.elevation = p_lns_init->p_location_speed->elevation;
+
+ lncp_init.service_handle = p_lns->service_handle;
+ lncp_init.navigation_handles = p_lns->navigation_handles;
+
+ // Add control pointer characteristic
+ err_code = ble_lncp_init(&p_lns->ctrl_pt, &lncp_init);
+ VERIFY_SUCCESS(err_code);
+
+ memcpy(&p_lns->ctrlpt_handles, &p_lns->ctrl_pt.ctrlpt_handles, sizeof(ble_gatts_char_handles_t));
+ }
+
+ NRF_LOG_DEBUG("Initialized");
+
+ return NRF_SUCCESS;
+}
+
+
+ret_code_t ble_lns_loc_speed_send(ble_lns_t * p_lns)
+{
+ VERIFY_PARAM_NOT_NULL(p_lns);
+
+ if (p_lns->conn_handle == BLE_CONN_HANDLE_INVALID)
+ {
+ return NRF_ERROR_INVALID_STATE;
+ }
+
+ if (!p_lns->is_loc_speed_notification_enabled)
+ {
+ return NRF_ERROR_INVALID_STATE;
+ }
+
+ notification_t * notif1 = &p_lns->pending_loc_speed_notifications[0];
+ notification_t * notif2 = &p_lns->pending_loc_speed_notifications[1];
+
+ // clear previous unsent data. Previous data is invalid.
+ notif1->is_pending = false;
+ notif2->is_pending = false;
+
+ // check if it is necessary to send packet 1
+ if (p_lns->available_features & (BLE_LNS_FEATURE_INSTANT_SPEED_SUPPORTED
+ | BLE_LNS_FEATURE_TOTAL_DISTANCE_SUPPORTED
+ | BLE_LNS_FEATURE_LOCATION_SUPPORTED))
+ {
+ // encode
+ notif1->len = loc_speed_encode_packet1(p_lns, p_lns->p_location_speed, &notif1->data[0]);
+ notif1->handle = p_lns->loc_speed_handles.value_handle;
+ notif1->is_pending = true;
+
+ // send
+ notification_buffer_process(p_lns);
+ }
+
+ // check if it is necessary to send packet 2
+ if (p_lns->available_features & (BLE_LNS_FEATURE_ELEVATION_SUPPORTED
+ | BLE_LNS_FEATURE_HEADING_SUPPORTED
+ | BLE_LNS_FEATURE_ROLLING_TIME_SUPPORTED
+ | BLE_LNS_FEATURE_UTC_TIME_SUPPORTED))
+ {
+ notif2->len = loc_speed_encode_packet2(p_lns, p_lns->p_location_speed, &notif2->data[0]);
+ notif2->handle = p_lns->loc_speed_handles.value_handle;
+ notif2->is_pending = true;
+
+ // send
+ notification_buffer_process(p_lns);
+ }
+
+ return NRF_SUCCESS;
+}
+
+
+ret_code_t ble_lns_navigation_send(ble_lns_t * p_lns)
+{
+ VERIFY_PARAM_NOT_NULL(p_lns);
+
+ if (p_lns->conn_handle == BLE_CONN_HANDLE_INVALID)
+ {
+ return NRF_ERROR_INVALID_STATE;
+ }
+
+ notification_t * notif = &p_lns->pending_navigation_notification;
+
+ // clear previous unsent data. Previous data is invalid.
+ notif->is_pending = false;
+
+ if (!p_lns->is_navigation_present)
+ {
+ return NRF_ERROR_NOT_SUPPORTED;
+ }
+
+ if (!p_lns->is_nav_notification_enabled)
+ {
+ return NRF_ERROR_INVALID_STATE;
+ }
+
+ if (!ble_lncp_is_navigation_running(&p_lns->ctrl_pt))
+ {
+ return NRF_ERROR_INVALID_STATE;
+ }
+
+ notif->len = navigation_encode(p_lns, p_lns->p_navigation, &notif->data[0]);
+ notif->handle = p_lns->navigation_handles.value_handle;
+ notif->is_pending = true;
+
+ notification_buffer_process(p_lns);
+
+ return NRF_SUCCESS;
+}
+
+
+ret_code_t ble_lns_add_route(ble_lns_t * p_lns, ble_lns_route_t * p_route)
+{
+ VERIFY_PARAM_NOT_NULL(p_lns);
+ VERIFY_PARAM_NOT_NULL(p_route);
+
+ if (p_lns->is_navigation_present == false)
+ {
+ return NRF_ERROR_NOT_SUPPORTED;
+ }
+
+ return ble_ln_db_record_add(p_route);
+}
+
+
+ret_code_t ble_lns_remove_route(ble_lns_t * p_lns, uint16_t route_id)
+{
+ VERIFY_PARAM_NOT_NULL(p_lns);
+
+ if (p_lns->is_navigation_present == false)
+ {
+ return NRF_ERROR_NOT_SUPPORTED;
+ }
+
+ return ble_ln_db_record_delete(route_id);
+}
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/experimental_ble_lns/ble_lns.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/experimental_ble_lns/ble_lns.h
new file mode 100644
index 0000000..28a9223
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/experimental_ble_lns/ble_lns.h
@@ -0,0 +1,381 @@
+/**
+ * Copyright (c) 2015 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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
+ *
+ * @defgroup ble_lns Location and Navigation Service
+ * @{
+ * @ingroup ble_sdk_srv
+ * @brief Location and Navigation Service module.
+ *
+ * @details This module implements the Location and Navigation Service with the Location and Speed, Position
+ * Quality, Feature, Control Point, and Navigation characteristics.
+ *
+ * If an event handler is supplied by the application, the Location and Navigation Service will
+ * generate Location and Navigation Service events to the application.
+ *
+ * @note The application must register this module as BLE event observer using the
+ * NRF_SDH_BLE_OBSERVER macro. Example:
+ * @code
+ * ble_lns_t instance;
+ * NRF_SDH_BLE_OBSERVER(anything, BLE_LNS_BLE_OBSERVER_PRIO,
+ * ble_lns_on_ble_evt, &instance);
+ * @endcode
+ */
+
+#ifndef BLE_LNS_H__
+#define BLE_LNS_H__
+
+#include "ble_srv_common.h"
+#include "ble_date_time.h"
+#include "ble_ln_common.h"
+#include "ble_ln_cp.h"
+#include "sdk_common.h"
+#include "nrf_sdh_ble.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**@ Macro for defining a ble_lns instance.
+ *
+ * @param _name Name of the instance.
+ * @hideinitializer
+ */
+#define BLE_LNS_DEF(_name) \
+static ble_lns_t _name; \
+NRF_SDH_BLE_OBSERVER(_name ## _obs, \
+ BLE_LNS_BLE_OBSERVER_PRIO, \
+ ble_lns_on_ble_evt, &_name)
+
+
+/**@brief Location and Navigation event type. This list defines the possible events types from the Location and Navigation Service. */
+typedef enum
+{
+ BLE_LNS_CTRLPT_EVT_INDICATION_ENABLED, /**< Control Point value indication was enabled. */
+ BLE_LNS_CTRLPT_EVT_INDICATION_DISABLED, /**< Control Point value indication was disabled. */
+ BLE_LNS_LOC_SPEED_EVT_NOTIFICATION_ENABLED, /**< Location and Speed value notification was enabled. */
+ BLE_LNS_LOC_SPEED_EVT_NOTIFICATION_DISABLED, /**< Location and Speed value notification was disabled. */
+ BLE_LNS_NAVIGATION_EVT_NOTIFICATION_ENABLED, /**< Navigation value notification was enabled. */
+ BLE_LNS_NAVIGATION_EVT_NOTIFICATION_DISABLED, /**< Navigation value notification was disabled. */
+} ble_lns_evt_type_t;
+
+/**@brief Location and Navigation event structure. When an event occurs, the data structures of the module are automatically updated. */
+typedef struct
+{
+ ble_lns_evt_type_t evt_type;
+} ble_lns_evt_t;
+
+// Forward declarations of the ble_lns types.
+typedef struct ble_lns_init_s ble_lns_init_t;
+typedef struct ble_lns_s ble_lns_t;
+typedef struct ble_lns_loc_speed_s ble_lns_loc_speed_t;
+typedef struct ble_lns_pos_quality_s ble_lns_pos_quality_t;
+typedef struct ble_lns_navigation_s ble_lns_navigation_t;
+
+
+typedef struct
+{
+ bool is_pending;
+ uint16_t handle;
+ uint16_t len;
+ uint8_t data[BLE_GATT_ATT_MTU_DEFAULT];
+} notification_t;
+
+
+/**@brief Location and Navigation Service event handler type. */
+typedef void (*ble_lns_evt_handler_t) (ble_lns_t const * p_lns, ble_lns_evt_t const * p_evt);
+
+
+/**@brief Location and Navigation Service init structure. This structure contains all options
+ * and data needed to initialize the service.
+ */
+struct ble_lns_init_s
+{
+ ble_lns_evt_handler_t evt_handler; /**< Event handler to be called for handling events in the Location and Navigation Service. */
+ ble_lncp_evt_handler_t lncp_evt_handler;
+ ble_srv_error_handler_t error_handler; /**< Errors will be sent back to this function. */
+
+ bool is_position_quality_present; /**< If set to true, the position quality characteristic will be added. Else not. */
+ bool is_control_point_present; /**< If set to true, the control point characteristic will be added. Else not. */
+ bool is_navigation_present; /**< If set to true, the navigation characteristic will be added. Else not. */
+
+ security_req_t loc_nav_feature_security_req_read_perm; /**< Read security level of the LN Feature characteristic. */
+ security_req_t loc_speed_security_req_cccd_write_perm; /**< CCCD write security level of the Write Location and Speed characteristic. */
+ security_req_t position_quality_security_req_read_perm; /**< Read security level of the Position Quality characteristic. */
+ security_req_t navigation_security_req_cccd_write_perm; /**< CCCD write security level of the Navigation characteristic. */
+ security_req_t ctrl_point_security_req_write_perm; /**< Read security level of the LN Control Point characteristic. */
+ security_req_t ctrl_point_security_req_cccd_write_perm; /**< CCCD write security level of the LN Control Point characteristic. */
+
+ uint32_t available_features; /**< Value of the LN feature. */
+ ble_lns_loc_speed_t * p_location_speed; /**< Initial Location and Speed. */
+ ble_lns_pos_quality_t * p_position_quality; /**< Initial Position Quality. */
+ ble_lns_navigation_t * p_navigation; /**< Initial Navigation data structure. */
+};
+
+/**@brief Definition of a navigation route.*/
+typedef struct
+{
+ uint16_t route_id;
+ uint8_t route_name[BLE_LNS_MAX_ROUTE_NAME_LEN];
+} ble_lns_route_t;
+
+/**@brief Location and Navigation Service structure. This structure contains various status information for the service. */
+struct ble_lns_s
+{
+ ble_lns_evt_handler_t evt_handler; /**< Event handler to be called for handling events in the Location and Navigation Service. */
+ ble_srv_error_handler_t error_handler; /**< Error handler. */
+
+ bool is_navigation_present; /**< If set to true, the navigation characteristic is present. Else not. */
+
+ uint16_t conn_handle; /**< Handle of the current connection (as provided by the BLE stack; BLE_CONN_HANDLE_INVALID if not in a connection). */
+ uint16_t service_handle; /**< Handle of Location and Navigation Service (as provided by the BLE stack). */
+ ble_gatts_char_handles_t loc_speed_handles; /**< Handles related to the Location and Speed characteristic. */
+ ble_gatts_char_handles_t feature_handles; /**< Handles related to the Location and Navigation Feature characteristic. */
+ ble_gatts_char_handles_t navigation_handles; /**< Handles related to the Navigation characteristic. */
+ ble_gatts_char_handles_t pos_qual_handles; /**< Handles related to the Position Quality characteristic. */
+ ble_gatts_char_handles_t ctrlpt_handles;
+ uint32_t available_features; /**< Value of Location and Navigation feature. */
+
+ bool is_loc_speed_notification_enabled; /**< True if notification is enabled on the Location and Speed characteristic. */
+ bool is_nav_notification_enabled; /**< True if notification is enabled on the Navigation characteristic. */
+
+ notification_t pending_loc_speed_notifications[2]; /**< This buffer holds location and speed notifications. */
+ notification_t pending_navigation_notification; /**< This buffer holds navigation notifications. */
+ ble_lns_loc_speed_t * p_location_speed; /**< Location and Speed. */
+ ble_lns_pos_quality_t * p_position_quality; /**< Position measurement quality. */
+ ble_lns_navigation_t * p_navigation; /**< Navigation data structure. */
+ ble_lncp_t ctrl_pt;
+};
+
+/**@brief Position status. This enumeration defines how to interpret the position data. */
+typedef enum
+{
+ BLE_LNS_NO_POSITION = 0,
+ BLE_LNS_POSITION_OK = 1,
+ BLE_LNS_ESTIMATED = 2,
+ BLE_LNS_LAST_KNOWN_POSITION = 3
+} ble_lns_pos_status_type_t;
+
+/**@brief The format of the position and speed measurements. */
+typedef enum
+{
+ BLE_LNS_SPEED_DISTANCE_FORMAT_2D = 0,
+ BLE_LNS_SPEED_DISTANCE_FORMAT_3D = 1
+} ble_lns_speed_distance_format_t;
+
+/**@brief Elevation source. */
+typedef enum
+{
+ BLE_LNS_ELEV_SOURCE_POSITIONING_SYSTEM = 0,
+ BLE_LNS_ELEV_SOURCE_BAROMETRIC = 1,
+ BLE_LNS_ELEV_SOURCE_DATABASE_SERVICE = 2,
+ BLE_LNS_ELEV_SOURCE_OTHER = 3
+} ble_lns_elevation_source_t;
+
+/**@brief Heading source. */
+typedef enum
+{
+ BLE_LNS_HEADING_SOURCE_MOVEMENT = 0,
+ BLE_LNS_HEADING_SOURCE_COMPASS = 1
+} ble_lns_heading_source_t;
+
+/**@brief Location and Speed data structure. */
+struct ble_lns_loc_speed_s
+{
+ bool instant_speed_present; /**< Instantaneous Speed present (0=not present, 1=present). */
+ bool total_distance_present; /**< Total Distance present (0=not present, 1=present). */
+ bool location_present; /**< Location present (0=not present, 1=present). */
+ bool elevation_present; /**< Elevation present (0=not present, 1=present). */
+ bool heading_present; /**< Heading present (0=not present, 1=present). */
+ bool rolling_time_present; /**< Rolling Time present (0=not present, 1=present). */
+ bool utc_time_time_present; /**< UTC Time present (0=not present, 1=present). */
+ ble_lns_pos_status_type_t position_status; /**< Status of current position */
+ ble_lns_speed_distance_format_t data_format; /**< Format of data (either 2D or 3D). */
+ ble_lns_elevation_source_t elevation_source; /**< Source of the elevation measurement. */
+ ble_lns_heading_source_t heading_source; /**< Source of the heading measurement. */
+ uint16_t instant_speed; /**< Instantaneous Speed (1/10 meter per sec). */
+ uint32_t total_distance; /**< Total Distance (meters), size=24 bits. */
+ int32_t latitude; /**< Latitude (10e-7 degrees). */
+ int32_t longitude; /**< Longitude (10e-7 degrees). */
+ int32_t elevation; /**< Elevation (1/100 meters), size=24 bits. */
+ uint16_t heading; /**< Heading (1/100 degrees). */
+ uint8_t rolling_time; /**< Rolling Time (seconds). */
+ ble_date_time_t utc_time; /**< UTC Time. */
+};
+
+/**@brief Position quality structure. */
+struct ble_lns_pos_quality_s
+{
+ bool number_of_satellites_in_solution_present; /**< The number of satellites present in solution (0=not present, 1=present). */
+ bool number_of_satellites_in_view_present; /**< The number of satellites present in solution (0=not present, 1=present). */
+ bool time_to_first_fix_present; /**< Time to the first position fix present (0=not present, 1=present). */
+ bool ehpe_present; /**< Error in horizontal position estimate present (0=not present, 1=present). */
+ bool evpe_present; /**< Error in vertical position estimate present (0=not present, 1=present). */
+ bool hdop_present; /**< Horizontal dilution of precision present (0=not present, 1=present). */
+ bool vdop_present; /**< Vertical dilution of precision present (0=not present, 1=present). */
+ ble_lns_pos_status_type_t position_status; /**< Status of last measured position. */
+ uint8_t number_of_satellites_in_solution; /**< The number of satellites in solution (unitless, with a resolution of 1). */
+ uint8_t number_of_satellites_in_view; /**< The number of satellites in view (unitless, with a resolution of 1). */
+ uint16_t time_to_first_fix; /**< Time to the first position fix (seconds, with a resolution of 1/10). */
+ uint32_t ehpe; /**< Error in horizontal position estimate (meters, with a resolution of 1/100). */
+ uint32_t evpe; /**< Error in vertical position estimate (meters, with a resolution of 1/100). */
+ uint8_t hdop; /**< Horizontal dilution of precision (unitless, with a resolution of 2/10). */
+ uint8_t vdop; /**< Vertical dilution of precision (unitless, with a resolution of 2/10). */
+};
+
+/**@brief Navigation indicator type. */
+typedef enum
+{
+ BLE_LNS_NAV_TO_WAYPOINT = 0,
+ BLE_LNS_NAV_TO_DESTINATION = 1
+} ble_lns_nav_indicator_type_t;
+
+/**@brief Navigation data structure. */
+struct ble_lns_navigation_s
+{
+ bool remaining_dist_present; /**< Remaining Distance present (0=not present, 1=present). */
+ bool remaining_vert_dist_present; /**< Remaining Vertical Distance present (0=not present, 1=present). */
+ bool eta_present; /**< Estimated Time of Arrival present (0=not present, 1=present). */
+ ble_lns_pos_status_type_t position_status; /**< Status of last measured position. */
+ ble_lns_heading_source_t heading_source; /**< Source of the heading measurement. */
+ ble_lns_nav_indicator_type_t navigation_indicator_type; /**< Navigation indicator type. */
+ bool waypoint_reached; /**< Waypoint Reached (0=not reached, 1=reached). */
+ bool destination_reached; /**< Destination Reached (0=not reached, 1=reached). */
+ uint16_t bearing; /**< Bearing (1/100 degrees).*/
+ uint16_t heading; /**< Heading (1/100 degrees), size=24 bit. */
+ uint32_t remaining_distance; /**< Remaining Distance (1/10 meters), size=24 bit. */
+ int32_t remaining_vert_distance; /**< Remaining Vertical Distance (1/100 meters), size=24 bit. */
+ ble_date_time_t eta; /**< Estimated Time of Arrival. */
+};
+
+
+/**@brief Function for initializing the Location and Navigation Service.
+ *
+ * @param[out] p_lns Location and Navigation Service structure. This structure must be supplied by
+ * the application. It is initialized by this function, and will later
+ * be used to identify this particular service instance.
+ * @param[in] p_lns_init Information needed to initialize the service.
+ *
+ * @retval NRF_SUCCESS If the service was initialized successfully.
+ * @retval NRF_ERROR_NULL If a NULL parameter was provided.
+ * @retval NRF_INVALID_PARAMS If there is an inconsistency in the initialization structure.
+ * @return Otherwise, an error code from either sd_ble_gatts_service_add() or sd_ble_gatts_characteristic_add() is returned.
+ */
+ret_code_t ble_lns_init(ble_lns_t * p_lns, ble_lns_init_t const * p_lns_init);
+
+
+/**@brief Function for handling Location and Navigation Service BLE stack events.
+ *
+ * @details This function handles all events from the BLE stack that are of interest to the
+ * Location and Navigation Service.
+ *
+ * @note The function returns when a NULL parameter is provided.
+ *
+ * @param[in] p_ble_evt Event received from the BLE stack.
+ * @param[in] p_context Location and Navigation Service structure.
+ */
+void ble_lns_on_ble_evt(ble_evt_t const * p_ble_evt, void * p_context);
+
+
+/**@brief Function for sending location and speed data if notification has been enabled.
+ *
+ * @details The application calls this function after having performed a location and speed determination.
+ * If notification has been enabled, the location and speed data is encoded and sent to
+ * the client.
+ *
+ * @param[in] p_lns Location and Navigation Service structure holding the location and speed data.
+ *
+ * @retval NRF_SUCCESS If the data was sent successfully.
+ * @retval NRF_ERROR_NULL If a NULL parameter was provided.
+ * @retval NRF_ERROR_INVALID_STATE If notification is disabled.
+ */
+ret_code_t ble_lns_loc_speed_send(ble_lns_t * p_lns);
+
+
+/**@brief Function for sending navigation data if notification has been enabled.
+ *
+ * @details The application calls this function after having performed a navigation determination.
+ * If notification has been enabled, the navigation data is encoded and sent to
+ * the client.
+ *
+ * @param[in] p_lns Location and Navigation Service structure holding the navigation data.
+ *
+ * @retval NRF_SUCCESS If the data was sent successfully.
+ * @retval NRF_ERROR_NULL If a NULL parameter was provided.
+ * @retval NRF_ERROR_NOT_SUPPORTED If the navigation characteristic is absent.
+ * @retval NRF_ERROR_INVALID_STATE If navigation is not running or notification is disabled.
+ */
+ret_code_t ble_lns_navigation_send(ble_lns_t * p_lns);
+
+
+/**@brief Function for adding a route to the Location and Navigation Service.
+ *
+ * @param[in] p_lns Location and Navigation Service structure.
+ * @param[in,out] p_route The new route to be added. The route ID is updated.
+ *
+ * @retval NRF_SUCCESS If the route was added successfully.
+ * @retval NRF_ERROR_NULL If a NULL parameter was provided.
+ * @retval NRF_ERROR_NOT_SUPPORTED If the navigation characteristic is absent.
+ * @retval NRF_ERROR_NO_MEM If there is no memory left.
+ * @retval NRF_ERROR_INTERNAL If there is an inconsistency in the routes table.
+ */
+ret_code_t ble_lns_add_route(ble_lns_t * p_lns, ble_lns_route_t * p_route);
+
+
+/**@brief Function for removing a route from the Location and Navigation Service.
+ *
+ * @param[in] p_lns Location and Navigation Service structure.
+ * @param[in] route_id The ID of the route to be removed.
+ *
+ * @retval NRF_SUCCESS If the route was removed successfully.
+ * @retval NRF_ERROR_NULL If a NULL parameter was provided.
+ * @retval NRF_ERROR_NOT_SUPPORTED If the navigation characteristic is absent.
+ * @retval NRF_INVALID_PARAM If the route ID does not exist.
+ */
+ret_code_t ble_lns_remove_route(ble_lns_t * p_lns, uint16_t route_id);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // BLE_LNS_H__
+
+/** @} */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/experimental_ble_ots/ble_hvx_buffering.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/experimental_ble_ots/ble_hvx_buffering.c
new file mode 100644
index 0000000..80b3afc
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/experimental_ble_ots/ble_hvx_buffering.c
@@ -0,0 +1,102 @@
+/**
+ * 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+
+#include "ble_hvx_buffering.h"
+#include <string.h>
+
+uint32_t ble_hvx_init(ble_hvx_buf_t * p_ble_hvx_buf)
+{
+ if (p_ble_hvx_buf == NULL)
+ {
+ return NRF_ERROR_NULL;
+ }
+
+ p_ble_hvx_buf->insert_index = 0;
+ p_ble_hvx_buf->read_index = 0;
+
+ return NRF_SUCCESS;
+}
+
+ble_hvx_t * ble_hvx_get_p_to_next_hvx(ble_hvx_buf_t * p_ble_hvx_buf)
+{
+ ble_hvx_t * p_hvx;
+ p_hvx = &p_ble_hvx_buf->buf[p_ble_hvx_buf->insert_index++];
+
+ p_hvx->params.p_data = p_hvx->data;
+ p_hvx->params.p_len = &p_hvx->data_len;
+
+ p_ble_hvx_buf->insert_index &= BLE_HVX_BUF_MASK;
+ return p_hvx;
+}
+
+
+uint32_t ble_hvx_buffer_process(ble_hvx_buf_t * p_ble_hvx_buf)
+{
+ uint32_t err_code;
+ while (p_ble_hvx_buf->read_index != p_ble_hvx_buf->insert_index)
+ {
+
+ ble_gatts_hvx_params_t * p_hvx_params;
+
+ p_hvx_params = &p_ble_hvx_buf->buf[p_ble_hvx_buf->read_index].params;
+ err_code = sd_ble_gatts_hvx(p_ble_hvx_buf->buf[p_ble_hvx_buf->read_index].conn_handle, p_hvx_params);
+
+ if (err_code == NRF_SUCCESS)
+ {
+ p_ble_hvx_buf->read_index++;
+ p_ble_hvx_buf->read_index &= BLE_HVX_BUF_MASK;
+ }
+ else
+ {
+ if (err_code == NRF_ERROR_BUSY || err_code == NRF_ERROR_RESOURCES)
+ {
+ return NRF_SUCCESS; // not a critical error.
+ }
+ else
+ {
+ // remove element from buffer
+ p_ble_hvx_buf->insert_index--;
+ p_ble_hvx_buf->insert_index &= BLE_HVX_BUF_MASK;
+ return err_code;
+ }
+ }
+ }
+ return NRF_SUCCESS;
+}
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/experimental_ble_ots/ble_hvx_buffering.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/experimental_ble_ots/ble_hvx_buffering.h
new file mode 100644
index 0000000..005e123
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/experimental_ble_ots/ble_hvx_buffering.h
@@ -0,0 +1,104 @@
+/**
+ * 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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
+ *
+ * @defgroup ble_sdk_srv_ots_buf Object Transfer Service, HVX buffering
+ * @{
+ * @ingroup ble_ots
+ * @brief Object Transfer Service module
+ *
+ * @details This module is responsible for buffering indications and notifications.
+ */
+
+#ifndef BLE_HVX_BUFFERING_H__
+#define BLE_HVX_BUFFERING_H__
+
+
+#include <stdint.h>
+#include "ble_types.h"
+#include "ble_gatts.h"
+
+#define BLE_HVX_BUF_LEN (1 << 3) // 8
+#define BLE_HVX_BUF_MASK (BLE_HVX_BUF_LEN-1)
+
+/**@brief ble_hvx_t represents one notification/indication. */
+typedef struct {
+ uint16_t conn_handle; /**< The associated connection handle. */
+ uint8_t data[BLE_GATT_ATT_MTU_DEFAULT]; /**< The hvx data. */
+ uint16_t data_len;
+ ble_gatts_hvx_params_t params; /**< Parameters of the hvx. */
+} ble_hvx_t;
+
+/**@brief ble_hvx_buf_t is the structure holding the state of the hvx buffering module. */
+typedef struct {
+ ble_hvx_t buf[BLE_HVX_BUF_LEN]; /**< A buffer of nofications/indications. */
+
+ uint8_t insert_index;
+ uint8_t read_index;
+} ble_hvx_buf_t;
+
+/**@brief Function for initializing the HVX buffer module.
+ *
+ * @param[out] p_ble_hvx_buf HVX buffering structure.
+ * @return NRF_SUCCESS If the given paramer is valid.
+ */
+uint32_t ble_hvx_init(ble_hvx_buf_t * p_ble_hvx_buf);
+
+/**@brief Function for obtaining the pointer to the next hvx. The user can then fill out the hvx structure.
+ *
+ * @param[in] p_ble_hvx_buf HVX buffering structure.
+ * @return ble_hvx_t * If there is a free ble_hvx_t.
+ * @return NULL If there is no free ble_hvx_t, or an invalid parameter is supplied.
+ */
+ble_hvx_t * ble_hvx_get_p_to_next_hvx(ble_hvx_buf_t * p_ble_hvx_buf);
+
+/**@brief Function for sending something from the HVX buffer.
+ *
+ * @param[in] p_ble_hvx_buf HVX buffering structure.
+ * @return NRF_SUCCESS If a indication/notification was successfully sent.
+ */
+uint32_t ble_hvx_buffer_process(ble_hvx_buf_t * p_ble_hvx_buf);
+
+
+#endif // BLE_HVX_BUFFERING_H__
+
+/** @} */
+
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/experimental_ble_ots/ble_ots.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/experimental_ble_ots/ble_ots.c
new file mode 100644
index 0000000..b4076c4
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/experimental_ble_ots/ble_ots.c
@@ -0,0 +1,249 @@
+/**
+ * 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+
+#include <stdint.h>
+#include <string.h>
+#include "ble_ots.h"
+#include "ble_ots_object.h"
+#include "ble_ots_oacp.h"
+#include "fds.h"
+
+#define BLE_OTS_MAX_OBJ_TYPE_SIZE 16
+#define BLE_OTS_OBJ_CHANGED_SIZE 7
+#define OTS_INVALID_ID 0xFF
+
+#define SIZE_DATE_TIME 7
+
+#define BLE_OTS_INVALID_OCTET_OFFSET BLE_GATT_STATUS_ATTERR_APP_BEGIN + 1
+#define BLE_OTS_INVALID_METADATA BLE_GATT_STATUS_ATTERR_APP_BEGIN + 2
+#define BLE_OTS_CONCURRENCY_LIMIT_EXCEEDED BLE_GATT_STATUS_ATTERR_APP_BEGIN + 3
+
+
+#define BLE_OTS_OACP_SUPPORT_FEATURE_CREATE_bp 0
+#define BLE_OTS_OACP_SUPPORT_FEATURE_DELETE_bp 1
+#define BLE_OTS_OACP_SUPPORT_FEATURE_CALC_CHECKSUM_bp 2
+#define BLE_OTS_OACP_SUPPORT_FEATURE_EXECUTE_bp 3
+#define BLE_OTS_OACP_SUPPORT_FEATURE_READ_bp 4
+#define BLE_OTS_OACP_SUPPORT_FEATURE_WRITE_bp 5
+#define BLE_OTS_OACP_SUPPORT_FEATURE_APPEND_bp 6
+#define BLE_OTS_OACP_SUPPORT_FEATURE_TRUNCATE_bp 7
+#define BLE_OTS_OACP_SUPPORT_FEATURE_PATCH_bp 8
+#define BLE_OTS_OACP_SUPPORT_FEATURE_ABORT_bp 9
+
+#define BLE_OTS_OLCP_SUPPORT_FEATURE_GOTO_bp 0
+#define BLE_OTS_OLCP_SUPPORT_FEATURE_ORDER_bp 1
+#define BLE_OTS_OLCP_SUPPORT_FEATURE_REQ_NUM_OBJECTS_bp 2
+#define BLE_OTS_OLCP_SUPPORT_FEATURE_CLEAR_MARKING_bp 3
+
+/**@brief Function for adding the features characteristic.
+ *
+ * @param[in] p_ots Object Transfer Service structure.
+ * @param[in] read_access Read security level for the feature characteristic.
+ * @param[in] p_feature_char_handles Pointer to the handles for the feature characteristic.
+ */
+static uint32_t feature_char_add(ble_ots_t * const p_ots,
+ security_req_t read_access,
+ ble_gatts_char_handles_t * p_feature_char_handles)
+{
+ ble_add_char_params_t add_char_params;
+
+ uint8_t feature[BLE_OTS_FEATURE_LEN];
+
+ uint32_t oacp_features;
+ uint32_t olcp_features;
+
+ oacp_features = 0;
+ oacp_features |= (1 << BLE_OTS_OACP_SUPPORT_FEATURE_READ_bp);
+ oacp_features |= (1 << BLE_OTS_OACP_SUPPORT_FEATURE_APPEND_bp);
+ oacp_features |= (1 << BLE_OTS_OACP_SUPPORT_FEATURE_TRUNCATE_bp);
+ oacp_features |= (1 << BLE_OTS_OACP_SUPPORT_FEATURE_PATCH_bp);
+ oacp_features |= (1 << BLE_OTS_OACP_SUPPORT_FEATURE_ABORT_bp);
+
+ olcp_features = 0;
+
+ uint32_t i = 0;
+ i += uint32_encode(oacp_features, &feature[i]);
+ i += uint32_encode(olcp_features, &feature[i]);
+
+ memset(&add_char_params, 0, sizeof(add_char_params));
+
+ add_char_params.uuid = BLE_UUID_OTS_FEATURES;
+ add_char_params.uuid_type = BLE_UUID_TYPE_BLE;
+ add_char_params.max_len = BLE_OTS_FEATURE_LEN;
+ add_char_params.init_len = BLE_OTS_FEATURE_LEN;
+ add_char_params.p_init_value = &feature[0];
+ add_char_params.char_props.read = 1;
+ add_char_params.read_access = read_access;
+
+ return characteristic_add(p_ots->service_handle,
+ &add_char_params,
+ p_feature_char_handles);
+}
+
+/**@brief Function for handling the Connect event.
+ *
+ * @param[in] p_ots Object Transfer Service structure.
+ * @param[in] p_ble_evt Event received from the BLE stack.
+ */
+static void on_connect(ble_ots_t * p_ots, ble_evt_t const * p_ble_evt)
+{
+ p_ots->conn_handle = p_ble_evt->evt.gap_evt.conn_handle;
+}
+
+/**@brief Function for handling the BLE_GAP_EVT_DISCONNECTED event.
+ *
+ * @param[in] p_ots OTS Service Structure.
+ * @param[in] p_ble_evt Pointer to the event received from BLE stack.
+ */
+static void on_disconnect(ble_ots_t * p_ots, ble_evt_t const * p_ble_evt)
+{
+ p_ots->conn_handle = BLE_CONN_HANDLE_INVALID;
+}
+
+uint32_t ble_ots_init(ble_ots_t * p_ots, ble_ots_init_t * p_ots_init)
+{
+ if ((p_ots == NULL) || (p_ots_init == NULL))
+ {
+ return NRF_ERROR_NULL;
+ }
+
+ if (p_ots_init->p_object == NULL)
+ {
+ return NRF_ERROR_NULL;
+ }
+
+ p_ots->conn_handle = BLE_CONN_HANDLE_INVALID;
+ p_ots->error_handler = p_ots_init->error_handler;
+ p_ots->evt_handler = p_ots_init->evt_handler;
+ p_ots->p_current_object = p_ots_init->p_object;
+ p_ots->error_handler = p_ots_init->error_handler;
+ p_ots->evt_handler = p_ots_init->evt_handler;
+ p_ots->p_current_object = p_ots_init->p_object;
+
+
+ ble_uuid_t service_uuid =
+ {
+ .uuid = BLE_UUID_OTS_SERVICE,
+ .type = BLE_UUID_TYPE_BLE
+ };
+ uint32_t err_code;
+
+ err_code = fds_init();
+ if (err_code != NRF_SUCCESS)
+ {
+ return err_code;
+ }
+
+ err_code = sd_ble_gatts_service_add(BLE_GATTS_SRVC_TYPE_PRIMARY,
+ &service_uuid,
+ &(p_ots->service_handle));
+ if (err_code != NRF_SUCCESS)
+ {
+ return err_code;
+ }
+
+ err_code = feature_char_add(p_ots, p_ots_init->feature_char_read_access, &p_ots->feature_handles);
+ if (err_code != NRF_SUCCESS)
+ {
+ return err_code;
+ }
+
+ err_code = ble_ots_object_representation_init(&p_ots->object_chars, &p_ots_init->object_chars_init);
+ if (err_code != NRF_SUCCESS)
+ {
+ return err_code;
+ }
+
+ err_code = ble_ots_oacp_init(&p_ots->oacp_chars, &p_ots_init->oacp_init);
+ if (err_code != NRF_SUCCESS)
+ {
+ return err_code;
+ }
+ p_ots->oacp_chars.ots_l2cap.conn_mps = p_ots_init->rx_mps;
+ p_ots->oacp_chars.ots_l2cap.conn_mtu = p_ots_init->rx_mtu;
+
+ return NRF_SUCCESS;
+}
+
+/**@brief Function for handling the BLE_EVT_TX_COMPLETE event. Calls the hvx buffering module.
+ * @param[in] p_ots Object Transfer Service structure. */
+static inline void on_tx_complete(ble_ots_t * p_ots)
+{
+ uint32_t err_code;
+ err_code = ble_hvx_buffer_process(&p_ots->hvx_buf);
+ if (err_code != NRF_SUCCESS)
+ {
+ p_ots->error_handler(err_code);
+ }
+
+}
+
+void ble_ots_on_ble_evt(ble_evt_t const * p_ble_evt, void * p_context)
+{
+ ble_ots_t * p_ots;
+ p_ots = (ble_ots_t*) p_context;
+
+ if ((p_ots == NULL) || (p_ble_evt == NULL))
+ {
+ return;
+ }
+ ble_ots_oacp_on_ble_evt(&p_ots->oacp_chars, p_ble_evt);
+ ble_ots_object_on_ble_evt(&p_ots->object_chars, p_ble_evt);
+
+ switch (p_ble_evt->header.evt_id)
+ {
+ case BLE_GAP_EVT_CONNECTED:
+ on_connect(p_ots, p_ble_evt);
+ break;
+
+ case BLE_GAP_EVT_DISCONNECTED:
+ on_disconnect(p_ots, p_ble_evt);
+ break;
+
+ case BLE_GATTS_EVT_HVN_TX_COMPLETE:
+ on_tx_complete(p_ots);
+ break;
+
+ default:
+ // No implementation needed.
+ break;
+ }
+}
+
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/experimental_ble_ots/ble_ots.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/experimental_ble_ots/ble_ots.h
new file mode 100644
index 0000000..634bfd4
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/experimental_ble_ots/ble_ots.h
@@ -0,0 +1,472 @@
+/**
+ * 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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
+ *
+ * @defgroup ble_ots Object Transfer Service
+ * @{
+ * @ingroup ble_sdk_srv
+ * @brief Object Transfer Service module
+ *
+ * @details This is the main module of the OTS service.
+ */
+
+#ifndef BLE_OTS_H__
+#define BLE_OTS_H__
+
+#include <stdint.h>
+#include "ble_srv_common.h"
+#include "ble_date_time.h"
+#include "ble_hvx_buffering.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**@brief Macro for defining a ble_ots instance.
+ *
+ * @param _name Name of the instance.
+ * @hideinitializer
+ */
+#define BLE_OTS_DEF(_name) \
+static ble_ots_t _name; \
+NRF_SDH_BLE_OBSERVER(_name ## _ble_obs, \
+ BLE_OTS_BLE_OBSERVER_PRIO, \
+ ble_ots_on_ble_evt, &_name) \
+
+
+#define NRF_BLE_OTS_SIZE_CHAR_LEN (2*sizeof(uint32_t))
+#define BLE_OTS_FEATURE_LEN (2*sizeof(uint32_t))
+#define BLE_OTS_NAME_MAX_SIZE 128
+#define BLE_OTS_MAX_OBJ_SIZE 1028
+#define BLE_OTS_INVALID_CID 0x0000 /**< Invalid connection ID. */
+#define BLE_OTS_PSM 0x0025
+#define BLE_OTS_MAX_OACP_SIZE 21
+#define BLE_OTS_WRITE_MODE_TRUNCATE (1 << 1)
+#define BLE_OTS_WRITE_MODE_NO_TRUNCATE 0
+
+// Forward declarations.
+typedef struct ble_ots_s ble_ots_t;
+typedef struct ble_ots_oacp_s ble_ots_oacp_t;
+typedef struct ble_ots_l2cap_s ble_ots_l2cap_t;
+
+
+/*------------------------------------------ BLE OTS OBJECT --------------------------------------*/
+
+/**@brief Properties of an Object Transfer Service object. */
+typedef union
+{
+ struct
+ {
+ bool is_delete_permitted :1;
+ bool is_execute_permitted :1;
+ bool is_read_permitted :1;
+ bool is_write_permitted :1;
+ bool is_append_permitted :1;
+ bool is_truncate_permitted:1; /**< When writing using truncate mode, and the written length is shorter than the object, the object size is decreased. */
+ bool is_patch_permitted :1; /**< When patching, a part of the object is replaced. */
+ bool is_marked :1;
+ } decoded;
+ uint32_t raw;
+} ble_ots_obj_properties_t;
+
+/**@brief A structure representing the object type. */
+typedef struct
+{
+ uint8_t len; /**< The length of the object type in bytes. 2 and 16 are the only valid type lengths. */
+ union
+ {
+ uint16_t type16;
+ uint8_t type128[16];
+ } param;
+} ble_ots_obj_type_t;
+
+/**@brief The structure representing one Object Transfer Service object. */
+typedef struct
+{
+ uint8_t name[BLE_OTS_NAME_MAX_SIZE]; /**< The name of the object. If the name is "", the object will be invalidated on disconnect. */
+ uint8_t data[BLE_OTS_MAX_OBJ_SIZE];
+ ble_ots_obj_type_t type;
+ ble_ots_obj_properties_t properties;
+ uint32_t current_size;
+ uint32_t alloc_len;
+ bool is_valid; /**< States if the object will be shown in a list. */
+ bool is_locked; /**< When an object is written or read, the object will be locked. */
+} ble_ots_object_t;
+
+/**@brief The definition of an event from the object characteristics. */
+typedef struct
+{
+ enum
+ {
+ BLE_OTS_OBJECT_EVT_NAME_CHANGED,
+ BLE_OTS_OBJECT_EVT_PROPERTIES_CHANGED,
+ } type;
+ union
+ {
+ ble_ots_object_t * p_object;
+ } evt;
+} ble_ots_object_evt_t;
+
+/**@brief Initialization properties of the Object Transfer Service Object characteristics. */
+typedef struct
+{
+ ble_ots_t * p_ots;
+ security_req_t name_read_access;
+ security_req_t name_write_access;
+ security_req_t type_read_access;
+ security_req_t size_read_access;
+ security_req_t properties_read_access;
+ security_req_t properties_write_access;
+} ble_ots_object_chars_init_t;
+
+/**@brief The structure holding the state of the OTS object characteristics. */
+typedef struct
+{
+ ble_ots_t * p_ots;
+ ble_gatts_char_handles_t obj_name_handles;
+ ble_gatts_char_handles_t obj_type_handles;
+ ble_gatts_char_handles_t obj_size_handles;
+ ble_gatts_char_handles_t obj_properties_handles;
+} ble_ots_object_chars_t;
+
+
+/*------------------------------------------ BLE OTS L2CAP ---------------------------------------*/
+
+/**@brief L2cap event types. */
+typedef enum
+{
+ BLE_OTS_L2CAP_EVT_CH_CONNECTED,
+ BLE_OTS_L2CAP_EVT_CH_DISCONNECTED,
+ BLE_OTS_L2CAP_EVT_SEND_COMPLETE,
+ BLE_OTS_L2CAP_EVT_RECV_COMPLETE,
+} ble_ots_l2cap_evt_type_t;
+
+/**@brief l2cap event. */
+typedef struct
+{
+ ble_ots_l2cap_evt_type_t type;
+ struct
+ {
+ uint8_t * p_data;
+ uint16_t len;
+ } param;
+} ble_ots_l2cap_evt_t;
+
+/**@brief L2CAP event handler. */
+typedef void (*ble_ots_l2cap_evt_handler_t)(ble_ots_l2cap_t * p_ots_l2cap,
+ ble_ots_l2cap_evt_t * p_evt);
+
+/**@brief The structure holding the l2cap connection oriented channels state. */
+struct ble_ots_l2cap_s
+{
+ ble_ots_l2cap_evt_handler_t evt_handler;
+ ble_ots_oacp_t * p_ots_oacp;
+ enum
+ {
+ NOT_CONNECTED,
+ CONNECTED,
+ SENDING,
+ RECEIVING
+ } state;
+ ble_data_t tx_transfer_buffer;
+ ble_l2cap_ch_rx_params_t rx_params;
+ ble_l2cap_ch_tx_params_t tx_params;
+ uint16_t remaining_bytes; /**< The number of remaining bytes in the current transfer. */
+ uint16_t transfered_bytes;
+ uint16_t transfer_len; /**< The total number of bytes in the current transfer. */
+ uint16_t local_cid; /**< Connection id of the current connection. */
+ uint16_t conn_mtu; /**< The maximum transmission unit, that is the number of packets that can be sent or received. */
+ uint16_t conn_mps; /**< MPS defines the maximum payload size in bytes. */
+};
+
+/**@brief The initialization structure of the l2cap module. */
+typedef struct
+{
+ ble_ots_oacp_t * p_ots_oacp;
+ ble_ots_l2cap_evt_handler_t evt_handler;
+ uint8_t * p_transfer_buffer; /**< The user must provide buffer for transfers. */
+ uint16_t buffer_len; /**< Length of the transfer buffer. */
+} ble_ots_l2cap_init_t;
+
+
+/*------------------------------------------ BLE OTS OCAP ----------------------------------------*/
+
+/**< Types of Object Action Control Point Procedures. */
+typedef enum
+{
+ BLE_OTS_OACP_PROC_CREATE = 0x01, //!< Create object.
+ BLE_OTS_OACP_PROC_DELETE = 0x02, //!< Delete object.
+ BLE_OTS_OACP_PROC_CALC_CHKSUM = 0x03, //!< Calculate Checksum.
+ BLE_OTS_OACP_PROC_EXECUTE = 0x04, //!< Execute Object.
+ BLE_OTS_OACP_PROC_READ = 0x05, //!< Read object.
+ BLE_OTS_OACP_PROC_WRITE = 0x06, //!< Write object.
+ BLE_OTS_OACP_PROC_ABORT = 0x07, //!< Abort object.
+ BLE_OTS_OACP_PROC_RESP = 0x60 //!< Procedure response.
+} ble_ots_oacp_proc_type_t;
+
+/**< Object Action Control Point return codes. */
+typedef enum
+{
+ BLE_OTS_OACP_RES_SUCCESS = 0x01, //!< Success.
+ BLE_OTS_OACP_RES_OPCODE_NOT_SUP = 0x02, //!< Not supported
+ BLE_OTS_OACP_RES_INV_PARAM = 0x03, //!< Invalid parameter
+ BLE_OTS_OACP_RES_INSUFF_RES = 0x04, //!< Insufficient resources.
+ BLE_OTS_OACP_RES_INV_OBJ = 0x05, //!< Invalid object.
+ BLE_OTS_OACP_RES_CHAN_UNAVAIL = 0x06, //!< Channel unavailable.
+ BLE_OTS_OACP_RES_UNSUP_TYPE = 0x07, //!< Unsupported procedure.
+ BLE_OTS_OACP_RES_NOT_PERMITTED = 0x08, //!< Procedure not permitted.
+ BLE_OTS_OACP_RES_OBJ_LOCKED = 0x09, //!< Object locked.
+ BLE_OTS_OACP_RES_OPER_FAILED = 0x0A //!< Operation Failed.
+} ble_ots_oacp_res_code_t;
+
+/**< Object Action Control Point procedure definition. */
+typedef struct
+{
+ ble_ots_oacp_proc_type_t type;
+ union
+ {
+ struct
+ {
+ uint32_t size;
+ ble_ots_obj_type_t * p_obj_type;
+ } create_params;
+ struct
+ {
+ uint32_t offset;
+ uint32_t length;
+ } checksum_params;
+ struct
+ {
+ uint8_t cmd_data_len;
+ uint8_t * p_cmd_data;
+ } execute_params;
+ struct
+ {
+ uint32_t offset;
+ uint32_t length;
+ } read_params;
+ struct
+ {
+ uint32_t offset;
+ uint32_t length;
+ uint8_t write_mode;
+ } write_params;
+ } params;
+} ble_ots_oacp_proc_t;
+
+/**@brief Definition of an OACP event. */
+typedef struct
+{
+ enum
+ {
+ BLE_OTS_OACP_EVT_EXECUTE,
+ BLE_OTS_OACP_EVT_REQ_READ,
+ BLE_OTS_OACP_EVT_INCREASE_ALLOC_LEN,
+ BLE_OTS_OACP_EVT_REQ_WRITE,
+ BLE_OTS_OACP_EVT_ABORT,
+ } type;
+ union
+ {
+ ble_ots_object_t * p_object;
+ struct
+ {
+ uint8_t cmd_data_len;
+ uint8_t * p_cmd_data;
+ } execute_params;
+ } evt;
+} ble_ots_oacp_evt_t;
+
+/**@brief OACP initialization properties. */
+typedef struct
+{
+ ble_ots_t * p_ots;
+ uint32_t on_create_obj_properties_raw; /**< The encoded properties of a newly created object.*/
+ security_req_t write_access; /**< The write security level for the OACP. */
+ security_req_t cccd_write_access; /**< The write security level for the OACP CCCD. */
+ uint8_t * p_l2cap_buffer;
+ uint16_t l2cap_buffer_len;
+} ble_ots_oacp_init_t;
+
+struct ble_ots_oacp_s
+{
+ ble_ots_t * p_ots;
+ uint32_t on_create_obj_properties_raw; /**< The encoded properties of a newly created object.*/
+ ble_ots_l2cap_t ots_l2cap; /**< L2CAP connection oriented channel module. */
+ ble_gatts_char_handles_t oacp_handles; /**< The characteristic handles of the OACP. */
+};
+
+
+/*------------------------------------------ BLE OTS ---------------------------------------------*/
+
+/**@brief The event type indicates which module the event is connected to.*/
+typedef enum
+{
+ BLE_OTS_EVT_OACP,
+ BLE_OTS_EVT_OBJECT,
+ BLE_OTS_EVT_INDICATION_ENABLED,
+ BLE_OTS_EVT_INDICATION_DISABLED,
+ BLE_OTS_EVT_OBJECT_RECEIVED /**< If this event is received, data is now available in the current object.*/
+} ble_ots_evt_type_t;
+
+/**@brief This structure represents the state of the Object Transfer Service. */
+typedef struct
+{
+ ble_ots_evt_type_t type;
+ union
+ {
+ ble_ots_oacp_evt_t oacp_evt;
+ ble_ots_object_evt_t object_evt;
+
+ } evt; /**< Event data. */
+} ble_ots_evt_t;
+
+/**@brief OTS event handler. */
+typedef void (*ble_ots_evt_handler_t) (ble_ots_t * p_ots, ble_ots_evt_t * p_evt);
+
+/**@brief Structure for initializing the OTS. */
+typedef struct
+{
+ ble_ots_evt_handler_t evt_handler;
+ ble_srv_error_handler_t error_handler;
+ ble_ots_object_t * p_object; /**< Pointer to the object. */
+ security_req_t feature_char_read_access; /**< Read security level for the feature characteristic value. */
+ ble_ots_object_chars_init_t object_chars_init; /**< The initialization structure of the object characteristics. */
+ ble_ots_oacp_init_t oacp_init; /**< The initialization structure of the object action control point. */
+ uint16_t rx_mps; /**< Size of L2CAP Rx MPS (must be at least BLE_L2CAP_MPS_MIN).*/
+ uint16_t rx_mtu; /**< Size of L2CAP Rx MTU (must be at least BLE_L2CAP_MTU_MIN).*/
+} ble_ots_init_t;
+
+struct ble_ots_s
+{
+ uint16_t conn_handle; /**< Connection handle of service. */
+ uint16_t service_handle; /**< THe service handle of OTS. */
+ ble_ots_evt_handler_t evt_handler;
+ ble_srv_error_handler_t error_handler;
+ ble_gatts_char_handles_t feature_handles;
+ ble_ots_object_chars_t object_chars; /**< The structure holding the object characteristics representation. */
+ ble_ots_oacp_t oacp_chars; /**< The structure holding the object action control point characteristics representation. */
+ ble_ots_object_t * p_current_object; /**< Pointer to the currently selected object. */
+ ble_hvx_buf_t hvx_buf; /**< A buffer holding unsent handle value indications/notifications. */
+};
+
+
+/**@brief Function for initializing the Object Transfer Service.
+ *
+ * @param[out] p_ots Object Transfer Service structure. This structure will have to be supplied by
+ * the application. It will be initialized by this function, and will later
+ * be used to identify this particular service instance.
+ * @param[in] p_ots_init Information needed to initialize the service.
+ *
+ * @return NRF_SUCCESS on successful initialization of service, otherwise an error code.
+ */
+uint32_t ble_ots_init(ble_ots_t * p_ots, ble_ots_init_t * p_ots_init);
+
+/**@brief Function for handling the Application's BLE Stack events.
+ *
+ * @details Handles all events from the BLE stack of interest to the Object Transfer Service.
+ *
+ * @param[in] p_ble_evt Event received from the BLE stack.
+ * @param[in] p_context Object Transfer Service structure.
+ */
+void ble_ots_on_ble_evt(ble_evt_t const * p_ble_evt, void * p_context);
+
+/**@brief Function for setting the name of an object.
+ *
+ * @details If p_object is the current selected object, and the notifications is enabled, the client will be notified that the object has changed.
+ * @note If the name of the object is "" on disconnection, the object will be invalidated.
+ *
+ * @param[in] p_ots_object_chars Object Transfer Service Object Characteristics structure.
+ * @param[in] p_object Pointer to the object where the name will be changed.
+ * @param[in] new_name The new name of the object.
+ *
+ * @return NRF_SUCCESS On success, otherwise an error code.
+ */
+uint32_t ble_ots_object_set_name(ble_ots_object_chars_t * p_ots_object_chars,
+ ble_ots_object_t * p_object,
+ char const * new_name);
+
+/**@brief Function for setting the type of an object.
+ *
+ * @details If p_object is the current selected object, and the notifications is enabled, the client will be notified that the object has changed.
+ * @param[in] p_ots_object_chars Object Transfer Service Object Characteristics structure.
+ * @param[in] p_object Pointer to the object where the type will be changed.
+ * @param[in] p_new_type Pointer to the new type of the object.
+ *
+ * @return NRF_SUCCESS On success, otherwise an error code.
+ */
+uint32_t ble_ots_object_set_type(ble_ots_object_chars_t * p_ots_object_chars,
+ ble_ots_object_t * p_object,
+ ble_ots_obj_type_t * p_new_type);
+
+/**@brief Function for setting the current size of an object.
+ *
+ * @details If p_object is the current selected object, and the notifications is enabled, the client will be notified that the object has changed.
+ * @note If the new current size is smaller than the current size, the object will be truncated.
+ *
+ * @param[in] p_ots_object_chars Object Transfer Service Object Characteristics structure.
+ * @param[in] p_object Pointer to the object where the current size will be changed.
+ * @param[in] new_current_size The new current size of the object.
+ *
+ * @return NRF_SUCCESS On success, otherwise an error code.
+ */
+uint32_t ble_ots_object_set_current_size(ble_ots_object_chars_t * p_ots_object_chars,
+ ble_ots_object_t * p_object,
+ uint32_t new_current_size);
+
+/**@brief Function for setting the properties of an object.
+ *
+ * @details If p_object is the current selected object, and the notifications is enabled, the client will be notified that the object has changed.
+ *
+ * @param[in] p_ots_object_chars Object Transfer Service Object Characteristics structure.
+ * @param[in] p_object Pointer to the object where the properties will be changed.
+ * @param[in] p_new_properties The properties of the object.
+ *
+ * @return NRF_SUCCESS On success, otherwise an error code.
+ */
+uint32_t ble_ots_object_set_properties(ble_ots_object_chars_t * p_ots_object_chars,
+ ble_ots_object_t * p_object,
+ ble_ots_obj_properties_t * p_new_properties);
+
+
+
+#endif // BLE_OTS_H__
+
+/** @} */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/experimental_ble_ots/ble_ots_l2cap.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/experimental_ble_ots/ble_ots_l2cap.c
new file mode 100644
index 0000000..b51e086
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/experimental_ble_ots/ble_ots_l2cap.c
@@ -0,0 +1,437 @@
+/**
+ * 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#include "ble_ots_l2cap.h"
+
+#include <string.h>
+#include "ble_l2cap.h"
+
+#include "ble_ots.h"
+#include "ble_ots_oacp.h"
+
+#define NRF_LOG_MODULE_NAME ble_ots_l2cap
+#include "nrf_log.h"
+NRF_LOG_MODULE_REGISTER();
+
+#define SDU_SIZE 256
+
+
+static uint8_t data[SDU_SIZE];
+static ble_data_t m_sdu_buf =
+{
+ .p_data = data,
+ .len = SDU_SIZE
+};
+
+bool ble_ots_l2cap_is_channel_available(ble_ots_l2cap_t * p_ots_l2cap)
+{
+ return p_ots_l2cap->state == CONNECTED;
+}
+
+uint32_t ble_ots_l2cap_abort_transmission(ble_ots_l2cap_t * p_ots_l2cap)
+{
+ if (p_ots_l2cap == NULL)
+ {
+ return NRF_ERROR_NULL;
+ }
+ return NRF_ERROR_INVALID_PARAM;
+}
+
+uint32_t ble_ots_l2cap_init(ble_ots_l2cap_t * p_ots_l2cap, ble_ots_l2cap_init_t * p_ots_l2cap_init)
+{
+ if (p_ots_l2cap == NULL || p_ots_l2cap_init == NULL)
+ {
+ return NRF_ERROR_NULL;
+ }
+ if (p_ots_l2cap_init->p_transfer_buffer == NULL || p_ots_l2cap_init->buffer_len == 0)
+ {
+ return NRF_ERROR_INVALID_PARAM;
+ }
+ if (p_ots_l2cap_init->p_ots_oacp == NULL)
+ {
+ return NRF_ERROR_INVALID_PARAM;
+ }
+ if (p_ots_l2cap_init->evt_handler == NULL)
+ {
+ return NRF_ERROR_INVALID_PARAM;
+ }
+
+ memset(p_ots_l2cap, 0, sizeof(ble_ots_l2cap_t));
+
+ p_ots_l2cap->local_cid = BLE_OTS_INVALID_CID;
+
+ p_ots_l2cap->p_ots_oacp = p_ots_l2cap_init->p_ots_oacp;
+ p_ots_l2cap->evt_handler = p_ots_l2cap_init->evt_handler;
+ p_ots_l2cap->rx_params.sdu_buf.len = m_sdu_buf.len;
+ p_ots_l2cap->rx_params.sdu_buf.p_data = m_sdu_buf.p_data;
+
+ p_ots_l2cap->state = NOT_CONNECTED;
+
+ return NRF_SUCCESS;
+}
+
+
+
+/**@brief This function resumes sending data after an interrupt in the transfer.
+ *
+ * @param[in] p_ots_l2cap Object Transfer Service structure.
+ */
+static void ble_ots_l2cap_resume_send(ble_ots_l2cap_t * p_ots_l2cap)
+{
+ uint16_t transmit_size;
+ ble_data_t data_buf;
+
+ transmit_size = MIN(p_ots_l2cap->tx_params.tx_mtu, p_ots_l2cap->remaining_bytes);
+
+ data_buf.p_data = &p_ots_l2cap->tx_transfer_buffer.p_data[p_ots_l2cap->transfer_len - p_ots_l2cap->remaining_bytes];
+ data_buf.len = transmit_size;
+
+
+ uint32_t err_code = sd_ble_l2cap_ch_tx(p_ots_l2cap->p_ots_oacp->p_ots->conn_handle,
+ p_ots_l2cap->local_cid,
+ &data_buf);
+
+ if (err_code != NRF_SUCCESS && err_code != NRF_ERROR_BUSY)
+ {
+ if (p_ots_l2cap->p_ots_oacp->p_ots->error_handler != NULL)
+ {
+ p_ots_l2cap->p_ots_oacp->p_ots->error_handler(err_code);
+ return;
+ }
+ }
+}
+
+
+uint32_t ble_ots_l2cap_start_send(ble_ots_l2cap_t * p_ots_l2cap, uint8_t * p_data, uint16_t data_len)
+{
+ if (p_ots_l2cap == NULL)
+ {
+ return NRF_ERROR_NULL;
+ }
+ if (p_data == NULL)
+ {
+ return NRF_ERROR_NULL;
+ }
+ if (data_len == 0)
+ {
+ return NRF_ERROR_INVALID_LENGTH;
+ }
+ if (p_ots_l2cap->local_cid == BLE_L2CAP_CID_INVALID)
+ {
+ return NRF_ERROR_INVALID_STATE;
+ }
+ if (p_ots_l2cap->state != CONNECTED)
+ {
+ return NRF_ERROR_INVALID_STATE;
+ }
+
+ p_ots_l2cap->tx_transfer_buffer.p_data = p_data;
+ p_ots_l2cap->tx_transfer_buffer.len = data_len;
+
+ p_ots_l2cap->remaining_bytes = data_len;
+ p_ots_l2cap->transfer_len = data_len;
+
+ p_ots_l2cap->state = SENDING;
+
+ ble_ots_l2cap_resume_send(p_ots_l2cap);
+
+ return NRF_SUCCESS;
+}
+
+uint32_t ble_ots_l2cap_start_recv(ble_ots_l2cap_t * p_ots_l2cap, uint16_t len)
+{
+ uint32_t err_code;
+
+ if (p_ots_l2cap == NULL)
+ {
+ return NRF_ERROR_NULL;
+ }
+ if (p_ots_l2cap->state != CONNECTED)
+ {
+ return NRF_ERROR_INVALID_STATE;
+ }
+ if (p_ots_l2cap->local_cid == BLE_L2CAP_CID_INVALID)
+ {
+ return NRF_ERROR_INVALID_STATE;
+ }
+ p_ots_l2cap->transfered_bytes = 0;
+ p_ots_l2cap->remaining_bytes = len;
+ p_ots_l2cap->transfer_len = len;
+
+ err_code = sd_ble_l2cap_ch_rx(p_ots_l2cap->p_ots_oacp->p_ots->conn_handle,
+ p_ots_l2cap->local_cid,
+ &p_ots_l2cap->rx_params.sdu_buf);
+ if (err_code == NRF_SUCCESS)
+ {
+ p_ots_l2cap->state = RECEIVING;
+ }
+
+ return err_code;
+}
+
+/**@brief This function is called on a channel setup request. It responds with the connection parameters.
+ * @param[in] p_ots_l2cap Object transfer service l2cap module structure.
+ * @param[in] p_ble_evt Event received from the BLE stack.
+ */
+static inline void on_l2cap_ch_setup_request(ble_ots_l2cap_t * p_ots_l2cap, ble_evt_t const * p_ble_evt)
+{
+ uint32_t err_code;
+ ble_l2cap_ch_setup_params_t ch_setup_params = {{0}};
+
+ if (p_ble_evt->evt.l2cap_evt.params.ch_setup_request.le_psm != BLE_OTS_PSM)
+ {
+ ch_setup_params.status = BLE_L2CAP_CH_STATUS_CODE_LE_PSM_NOT_SUPPORTED;
+ NRF_LOG_WARNING("l2cap setup request for PSM 0x%x, rejecting since OTS PSM is 0x%x",
+ p_ble_evt->evt.l2cap_evt.params.ch_setup_request.le_psm,
+ BLE_L2CAP_CH_STATUS_CODE_LE_PSM_NOT_SUPPORTED);
+ }
+
+ else
+ {
+ ch_setup_params.status = BLE_L2CAP_CH_STATUS_CODE_SUCCESS;
+
+ ch_setup_params.rx_params.rx_mps = p_ots_l2cap->conn_mps;
+ if (ch_setup_params.rx_params.rx_mps < BLE_L2CAP_MPS_MIN)
+ {
+ ch_setup_params.rx_params.rx_mps = BLE_L2CAP_MPS_MIN;
+ }
+ ch_setup_params.rx_params.rx_mtu = p_ots_l2cap->conn_mtu;
+ if (ch_setup_params.rx_params.rx_mtu < BLE_L2CAP_MTU_MIN)
+ {
+ ch_setup_params.rx_params.rx_mtu = BLE_L2CAP_MTU_MIN;
+ }
+ ch_setup_params.rx_params.sdu_buf.p_data = NULL;
+ }
+
+ p_ots_l2cap->local_cid = p_ble_evt->evt.l2cap_evt.local_cid;
+
+ err_code = sd_ble_l2cap_ch_setup(p_ots_l2cap->p_ots_oacp->p_ots->conn_handle,
+ &p_ots_l2cap->local_cid,
+ &ch_setup_params);
+ if (err_code != NRF_SUCCESS)
+ {
+ if (p_ots_l2cap->p_ots_oacp->p_ots->error_handler != NULL)
+ {
+ p_ots_l2cap->p_ots_oacp->p_ots->error_handler(err_code);
+ }
+
+ }
+ NRF_LOG_INFO("Accepted L2CAP Channel");
+}
+
+
+/**@brief This function is called on a channel setup request. The parameters are stored. Events are forwarded.
+ *
+ * @param[in] p_ots_l2cap Object transfer service l2cap module structure.
+ * @param[in] p_ble_evt Event received from the BLE stack.
+ */
+static inline void on_l2cap_ch_setup(ble_ots_l2cap_t * p_ots_l2cap, ble_evt_t const * p_ble_evt)
+{
+ p_ots_l2cap->local_cid = p_ble_evt->evt.l2cap_evt.local_cid;
+ p_ots_l2cap->tx_params.credits = p_ble_evt->evt.l2cap_evt.params.ch_setup.tx_params.credits;
+ p_ots_l2cap->tx_params.tx_mps = p_ble_evt->evt.l2cap_evt.params.ch_setup.tx_params.tx_mps;
+ p_ots_l2cap->tx_params.tx_mtu = p_ble_evt->evt.l2cap_evt.params.ch_setup.tx_params.tx_mtu;
+ ble_ots_l2cap_evt_t evt;
+
+ evt.type = BLE_OTS_L2CAP_EVT_CH_CONNECTED;
+
+ p_ots_l2cap->state = CONNECTED;
+ p_ots_l2cap->evt_handler(p_ots_l2cap, &evt);
+}
+
+
+/**@brief Function for handling the BLE_L2CAP_EVT_CH_RELEASED event.
+ *
+ * @param[in] p_ots_l2cap Object transfer service l2cap module structure.
+ * @param[in] p_ble_evt Pointer to the event received from BLE stack.
+ */
+static inline void on_l2cap_ch_released(ble_ots_l2cap_t * p_ots_l2cap, ble_evt_t const * p_ble_evt)
+{
+ if(p_ots_l2cap->local_cid != p_ble_evt->evt.l2cap_evt.local_cid)
+ {
+ return;
+ }
+ ble_ots_l2cap_evt_t evt;
+
+ evt.type = BLE_OTS_L2CAP_EVT_CH_DISCONNECTED;
+
+ p_ots_l2cap->evt_handler(p_ots_l2cap, &evt);
+
+ p_ots_l2cap->state = NOT_CONNECTED;
+
+ p_ots_l2cap->local_cid = BLE_OTS_INVALID_CID;
+
+}
+
+
+/**@brief This function ois called tx is completet. It continues to send if necessary.
+ *
+ * @param[in] p_ots_l2cap Object transfer service l2cap module structure.
+ * @param[in] p_ble_evt Pointer to the event received from BLE stack.
+ */
+static void on_tx_complete(ble_ots_l2cap_t * p_ots_l2cap, ble_evt_t const * p_ble_evt)
+{
+ if(p_ots_l2cap->local_cid != p_ble_evt->evt.l2cap_evt.local_cid)
+ {
+ return;
+ }
+
+ p_ots_l2cap->remaining_bytes -= p_ble_evt->evt.l2cap_evt.params.tx.sdu_buf.len;
+
+ if (p_ots_l2cap->remaining_bytes == 0)
+ {
+ ble_ots_l2cap_evt_t evt;
+
+ evt.type = BLE_OTS_L2CAP_EVT_SEND_COMPLETE;
+ evt.param.len = p_ots_l2cap->transfer_len;
+ evt.param.p_data = p_ots_l2cap->tx_transfer_buffer.p_data;
+ evt.param.len = p_ots_l2cap->tx_transfer_buffer.len;
+
+ p_ots_l2cap->evt_handler(p_ots_l2cap, &evt);
+
+ p_ots_l2cap->state = CONNECTED;
+
+ p_ots_l2cap->transfer_len = 0;
+ }
+ else
+ {
+ ble_ots_l2cap_resume_send(p_ots_l2cap);
+ }
+}
+
+
+static void on_l2cap_ch_rx(ble_ots_l2cap_t * p_ots_l2cap, ble_evt_t const * p_ble_evt)
+{
+ if(p_ots_l2cap->local_cid != p_ble_evt->evt.l2cap_evt.local_cid)
+ {
+ return;
+ }
+
+ ble_ots_l2cap_evt_t evt;
+
+ memcpy(&p_ots_l2cap->p_ots_oacp->p_ots->p_current_object->data[p_ots_l2cap->transfered_bytes],
+ p_ble_evt->evt.l2cap_evt.params.rx.sdu_buf.p_data,
+ p_ble_evt->evt.l2cap_evt.params.rx.sdu_len);
+ NRF_LOG_DEBUG("Object buffer dump");
+ NRF_LOG_HEXDUMP_DEBUG(p_ots_l2cap->rx_params.sdu_buf.p_data , p_ots_l2cap->rx_params.sdu_buf.len);
+ p_ots_l2cap->transfered_bytes += p_ble_evt->evt.l2cap_evt.params.rx.sdu_len;
+ p_ots_l2cap->remaining_bytes -= p_ble_evt->evt.l2cap_evt.params.rx.sdu_len;
+ NRF_LOG_INFO("Bytes remaining to receive: %i", p_ots_l2cap->remaining_bytes);
+ p_ots_l2cap->state = CONNECTED;
+
+ p_ots_l2cap->transfer_len = 0;
+
+ if(p_ots_l2cap->remaining_bytes <= 0)
+ {
+ evt.type = BLE_OTS_L2CAP_EVT_RECV_COMPLETE;
+ evt.param.len = p_ots_l2cap->rx_params.sdu_buf.len;
+ evt.param.p_data = p_ots_l2cap->rx_params.sdu_buf.p_data;
+ p_ots_l2cap->evt_handler(p_ots_l2cap, &evt);
+ }
+ else
+ {
+ ret_code_t err_code;
+
+ ble_data_t sdu_buf;
+ sdu_buf.p_data = &p_ots_l2cap->rx_params.sdu_buf.p_data[p_ots_l2cap->transfered_bytes];
+ sdu_buf.len = p_ots_l2cap->rx_params.sdu_buf.len;
+
+ err_code = sd_ble_l2cap_ch_rx(p_ots_l2cap->p_ots_oacp->p_ots->conn_handle,
+ p_ots_l2cap->local_cid,
+ &sdu_buf);
+ if (err_code == NRF_SUCCESS)
+ {
+ p_ots_l2cap->state = RECEIVING;
+ }
+ else
+ {
+ p_ots_l2cap->state = CONNECTED;
+ }
+ }
+}
+
+
+
+void ble_ots_l2cap_on_ble_evt(ble_ots_l2cap_t * p_ots_l2cap, ble_evt_t const * p_ble_evt)
+{
+ if ((p_ots_l2cap == NULL) || (p_ble_evt == NULL))
+ {
+ return;
+ }
+
+ switch (p_ble_evt->header.evt_id)
+ {
+ case BLE_L2CAP_EVT_CH_SETUP_REQUEST:
+ on_l2cap_ch_setup_request(p_ots_l2cap, p_ble_evt);
+ break;
+
+ case BLE_L2CAP_EVT_CH_SETUP_REFUSED:
+ // This should not happen because the client should be the initiator.
+ if (p_ots_l2cap->p_ots_oacp->p_ots->error_handler != NULL)
+ {
+ p_ots_l2cap->p_ots_oacp->p_ots->error_handler(NRF_ERROR_INVALID_STATE);
+ }
+ break;
+
+ case BLE_L2CAP_EVT_CH_SETUP:
+ on_l2cap_ch_setup(p_ots_l2cap, p_ble_evt);
+ break;
+
+ case BLE_L2CAP_EVT_CH_RELEASED:
+ on_l2cap_ch_released(p_ots_l2cap, p_ble_evt);
+ break;
+ case BLE_L2CAP_EVT_CH_SDU_BUF_RELEASED:
+ break;
+ case BLE_L2CAP_EVT_CH_CREDIT:
+ break;
+ case BLE_L2CAP_EVT_CH_RX:
+ on_l2cap_ch_rx(p_ots_l2cap, p_ble_evt);
+ break;
+
+ case BLE_L2CAP_EVT_CH_TX:
+ on_tx_complete(p_ots_l2cap, p_ble_evt);
+ break;
+ default:
+ // No implementation needed.
+ break;
+ }
+}
+
+
+
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/experimental_ble_ots/ble_ots_l2cap.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/experimental_ble_ots/ble_ots_l2cap.h
new file mode 100644
index 0000000..be0312a
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/experimental_ble_ots/ble_ots_l2cap.h
@@ -0,0 +1,117 @@
+/**
+ * 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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
+ *
+ * @defgroup ble_sdk_srv_ots_l2cap Object Transfer Service, l2cap channel handling
+ * @{
+ * @ingroup ble_ots
+ * @brief Object Transfer Service module
+ *
+ * @details This module is responsible for handling the l2cap connection oriented channels.
+ */
+
+#ifndef BLE_OTS_L2CAP_H__
+#define BLE_OTS_L2CAP_H__
+
+#include <stdint.h>
+#include "ble_ots.h"
+
+/**@brief Function for initializing the Object Transfer Service l2cap module.
+ *
+ * @param[out] p_ots_l2cap Object Transfer Service l2cap structure. This structure will have to be
+ * supplied by the application. It will be initialized by this function, * and will later be used to identify this particular instance.
+ * @param[in] p_ots_l2cap_init Information needed to initialize the service.
+ *
+ * @return NRF_SUCCESS on successful initialization, otherwise an error code.
+ */
+uint32_t ble_ots_l2cap_init(ble_ots_l2cap_t * p_ots_l2cap, ble_ots_l2cap_init_t * p_ots_l2cap_init);
+
+/**@brief Function for handling the Application's BLE Stack events.
+ *
+ * @details Handles all events from the BLE stack of interest to the l2cap module.
+ *
+ * @param[in] p_ots_l2cap Object transfer service l2cap module structure.
+ * @param[in] p_ble_evt Event received from the BLE stack.
+ */
+void ble_ots_l2cap_on_ble_evt(ble_ots_l2cap_t * p_ots_l2cap, ble_evt_t const * p_ble_evt);
+
+/**@brief Function starting to send the data in the transfer buffer.
+ *
+ * @param[in] p_ots_l2cap Object transfer service l2cap module structure.
+ * @param[in] p_data Pointer to the data to be sent.
+ * @param[in] data_len The length of the data to be sent.
+ *
+ * @return NRF_SUCCESS If the transmission was started.
+ * @return NRF_ERROR_INVALID_STATE When in an invalid state. Otherwise an other error code.
+ */
+uint32_t ble_ots_l2cap_start_send(ble_ots_l2cap_t * p_ots_l2cap, uint8_t * p_data, uint16_t data_len);
+
+/**@brief Function starting to receive data to the transfer buffer.
+ *
+ * @param[in] p_ots_l2cap Object transfer service l2cap module structure.
+ * @param[in] len The length of the data to be received.
+ *
+ * @return NRF_SUCCESS If the transmission was started.
+ * @return NRF_ERROR_INVALID_STATE When in an invalid state. Otherwise an other error code.
+ */
+uint32_t ble_ots_l2cap_start_recv(ble_ots_l2cap_t * p_ots_l2cap, uint16_t len);
+
+/**@brief Function that checks if the channel is available for transmission.
+ *
+ * @param[in] p_ots_l2cap Object transfer service l2cap module structure.
+ *
+ * @return true if the channel is available.
+ */
+bool ble_ots_l2cap_is_channel_available(ble_ots_l2cap_t * p_ots_l2cap);
+
+/**@brief Function starting to abort the current transmission.
+ *
+ * @param[in] p_ots_l2cap Object transfer service l2cap module structure.
+ *
+ * @return NRF_SUCCESS If the transmission was aborted.
+ * @return NRF_ERROR_INVALID_STATE When in an invalid state. Otherwise an other error code.
+ */
+uint32_t ble_ots_l2cap_abort_transmission(ble_ots_l2cap_t * p_ots_l2cap);
+
+#endif // BLE_OTS_L2CAP_H__
+
+/** @} */ // End tag for the file.
+
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/experimental_ble_ots/ble_ots_oacp.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/experimental_ble_ots/ble_ots_oacp.c
new file mode 100644
index 0000000..1357b29
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/experimental_ble_ots/ble_ots_oacp.c
@@ -0,0 +1,606 @@
+/**
+ * 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#include "ble_ots_oacp.h"
+
+#include <string.h>
+#include "fds.h"
+#include "crc32.h"
+
+#include "ble_ots.h"
+#include "ble_ots_l2cap.h"
+#include "ble_ots_object.h"
+
+#define NRF_LOG_MODULE_NAME ble_ots_oacp
+#include "nrf_log.h"
+NRF_LOG_MODULE_REGISTER();
+
+#define OTS_FILE_ID 1234
+#define OTS_FDS_KEY 4321
+
+
+/**@brief Checks if the cccd handle is configured for indication
+ *
+ * @param[in] cccd_handle The CCCD handle.
+ */
+bool is_cccd_configured(ble_ots_oacp_t * const p_ots_oacp)
+{
+ uint32_t err_code;
+ uint8_t cccd_value_buf[BLE_CCCD_VALUE_LEN];
+ bool is_oacp_indic_enabled = false;
+ ble_gatts_value_t gatts_value;
+
+ uint16_t cccd_handle = p_ots_oacp->oacp_handles.cccd_handle;
+ uint16_t conn_handle = p_ots_oacp->p_ots->conn_handle;
+ // Initialize value struct.
+ memset(&gatts_value, 0, sizeof(gatts_value));
+
+ gatts_value.len = BLE_CCCD_VALUE_LEN;
+ gatts_value.offset = 0;
+ gatts_value.p_value = cccd_value_buf;
+
+ err_code = sd_ble_gatts_value_get(conn_handle,
+ cccd_handle,
+ &gatts_value);
+ if (err_code != NRF_SUCCESS)
+ {
+ // Report error to application
+ if (p_ots_oacp->p_ots->error_handler != NULL)
+ {
+ p_ots_oacp->p_ots->error_handler(err_code);
+ }
+ }
+
+ is_oacp_indic_enabled = ble_srv_is_indication_enabled(cccd_value_buf);
+
+ return is_oacp_indic_enabled;
+}
+
+
+
+/** @brief This is the l2cap connection oriented channel event handler.
+ *
+ * @param[in] p_ots_l2cap Pointer to the l2cap module
+ * @param[in] p_evt The pointer to the event.
+ */
+static void ots_l2cap_evt_handler(ble_ots_l2cap_t * p_ots_l2cap, ble_ots_l2cap_evt_t * p_evt)
+{
+ uint32_t err_code;
+
+ switch (p_evt->type)
+ {
+ case BLE_OTS_L2CAP_EVT_CH_CONNECTED:
+ NRF_LOG_INFO("BLE_OTS_L2CAP_EVT_CH_CONNECTED.");
+ break;
+ case BLE_OTS_L2CAP_EVT_CH_DISCONNECTED:
+ NRF_LOG_INFO("BLE_OTS_L2CAP_EVT_CH_DISCONNECTED.");
+ break;
+ case BLE_OTS_L2CAP_EVT_SEND_COMPLETE:
+ p_ots_l2cap->p_ots_oacp->p_ots->p_current_object->is_locked = false;
+ break;
+ case BLE_OTS_L2CAP_EVT_RECV_COMPLETE:
+ NRF_LOG_INFO("BLE_OTS_L2CAP_EVT_RECV_COMPLETE.");
+ memcpy(p_ots_l2cap->p_ots_oacp->p_ots->p_current_object->data,
+ p_ots_l2cap->rx_params.sdu_buf.p_data,
+ p_ots_l2cap->rx_params.sdu_buf.len);
+ err_code = ble_ots_object_set_current_size(&p_ots_l2cap->p_ots_oacp->p_ots->object_chars,
+ p_ots_l2cap->p_ots_oacp->p_ots->p_current_object,
+ p_ots_l2cap->p_ots_oacp->p_ots->p_current_object->current_size);
+ if (err_code != NRF_SUCCESS)
+ {
+ NRF_LOG_ERROR("ble_ots_object_set_current_size returned error 0x%x", err_code);
+ }
+ ble_ots_evt_t evt;
+ evt.type = BLE_OTS_EVT_OBJECT_RECEIVED;
+ p_ots_l2cap->p_ots_oacp->p_ots->evt_handler(p_ots_l2cap->p_ots_oacp->p_ots, &evt);
+ break;
+ }
+}
+
+
+/**@brief Adds the OACP characteristic
+ *
+ * @param[in] p_ots_oacp Pointer to the OACP structure.
+ * @param[in] service_handle The service handle to attach the characteristic to.
+ * @param[in] write_access The write security level for the OACP value handle.
+ * @param[in] cccd_write_access The write security level for the OACP cccd handle.
+ *
+ * @return NRF_SUCCESS When added successfully, else an error code from characteristic_add().
+ */
+static uint32_t oacp_char_add(ble_ots_oacp_t * const p_ots_oacp,
+ uint16_t service_handle,
+ security_req_t write_access,
+ security_req_t cccd_write_access)
+{
+ ble_add_char_params_t add_char_params;
+ memset(&add_char_params, 0, sizeof(add_char_params));
+
+ add_char_params.uuid = BLE_UUID_OTS_OACP;
+ add_char_params.uuid_type = BLE_UUID_TYPE_BLE;
+ add_char_params.max_len = BLE_OTS_MAX_OACP_SIZE;
+ add_char_params.init_len = 0;
+ add_char_params.is_var_len = 1;
+ add_char_params.char_props.indicate = true;
+ add_char_params.char_props.write = true;
+ add_char_params.cccd_write_access = cccd_write_access;
+ //add_char_params.is_defered_write = true;
+ add_char_params.write_access = write_access;
+
+ return characteristic_add(service_handle,
+ &add_char_params,
+ &p_ots_oacp->oacp_handles);
+}
+
+
+/**@brief Handling the OACP write procedure.
+ *
+ * @details The object is opened, and a l2cap transfer is started.
+ *
+ * @param[in] p_ots_oacp Pointer to the OACP structure.
+ * @param[in] offset The offset for where the read should start.
+ * @param[in] length The length of the read.
+ */
+static inline ble_ots_oacp_res_code_t oacp_write_proc(ble_ots_oacp_t * p_ots_oacp,
+ uint32_t offset,
+ uint32_t length,
+ uint8_t mode)
+{
+ uint32_t err_code;
+
+ if (p_ots_oacp->p_ots->p_current_object == NULL)
+ {
+ return BLE_OTS_OACP_RES_INV_OBJ;
+ }
+ if (p_ots_oacp->p_ots->p_current_object->is_valid == false)
+ {
+ return BLE_OTS_OACP_RES_INV_OBJ;
+ }
+
+
+ if (p_ots_oacp->p_ots->p_current_object->properties.decoded.is_write_permitted == false)
+ {
+ return BLE_OTS_OACP_RES_NOT_PERMITTED;
+ }
+
+ if (ble_ots_l2cap_is_channel_available(&p_ots_oacp->ots_l2cap) == false)
+ {
+ return BLE_OTS_OACP_RES_CHAN_UNAVAIL;
+ }
+
+ if (length + offset > p_ots_oacp->p_ots->p_current_object->alloc_len)
+ {
+ return BLE_OTS_OACP_RES_INV_PARAM;
+ }
+
+ if (p_ots_oacp->p_ots->p_current_object->is_locked)
+ {
+ return BLE_OTS_OACP_RES_OBJ_LOCKED;
+ }
+
+ err_code = ble_ots_l2cap_start_recv(&p_ots_oacp->ots_l2cap, length);
+ if (err_code != NRF_SUCCESS)
+ {
+ return BLE_OTS_OACP_RES_OPER_FAILED;
+ }
+
+ ble_ots_evt_t ble_ots_evt;
+
+ ble_ots_evt.type = BLE_OTS_EVT_OACP;
+
+ ble_ots_evt.evt.oacp_evt.type = BLE_OTS_OACP_EVT_REQ_WRITE;
+ ble_ots_evt.evt.oacp_evt.evt.p_object = p_ots_oacp->p_ots->p_current_object;
+
+ p_ots_oacp->p_ots->p_current_object->current_size = length;
+
+ p_ots_oacp->p_ots->evt_handler(p_ots_oacp->p_ots, &ble_ots_evt);
+
+ return BLE_OTS_OACP_RES_SUCCESS;
+}
+
+
+
+/**@brief Handling the OACP read procedure.
+ *
+ * @details The object is opened, and a l2cap transfer is started.
+ *
+ * @param[in] p_ots_oacp Pointer to the OACP structure.
+ * @param[in] offset The offset for where the read should start.
+ * @param[in] length The length of the read.
+ */
+static inline ble_ots_oacp_res_code_t oacp_read_proc(ble_ots_oacp_t * p_ots_oacp,
+ uint32_t offset,
+ uint32_t length)
+{
+
+ if (p_ots_oacp->p_ots->p_current_object == NULL)
+ {
+ return BLE_OTS_OACP_RES_INV_OBJ;
+ }
+ if (p_ots_oacp->p_ots->p_current_object->is_valid == false)
+ {
+ return BLE_OTS_OACP_RES_INV_OBJ;
+ }
+
+
+ if (p_ots_oacp->p_ots->p_current_object->properties.decoded.is_read_permitted == false)
+ {
+ return BLE_OTS_OACP_RES_NOT_PERMITTED;
+ }
+
+ if (ble_ots_l2cap_is_channel_available(&p_ots_oacp->ots_l2cap) == false)
+ {
+ return BLE_OTS_OACP_RES_CHAN_UNAVAIL;
+ }
+
+ if (length + offset > p_ots_oacp->p_ots->p_current_object->current_size)
+ {
+ return BLE_OTS_OACP_RES_INV_PARAM;
+ }
+
+ if (p_ots_oacp->p_ots->p_current_object->is_locked)
+ {
+ return BLE_OTS_OACP_RES_OBJ_LOCKED;
+ }
+
+ ble_ots_evt_t ble_ots_evt;
+
+ ble_ots_evt.type = BLE_OTS_EVT_OACP;
+
+ ble_ots_evt.evt.oacp_evt.type = BLE_OTS_OACP_EVT_REQ_READ;
+ ble_ots_evt.evt.oacp_evt.evt.p_object = p_ots_oacp->p_ots->p_current_object;
+
+ p_ots_oacp->p_ots->evt_handler(p_ots_oacp->p_ots, &ble_ots_evt);
+
+ ret_code_t err_code = ble_ots_l2cap_start_send(&p_ots_oacp->ots_l2cap,
+ p_ots_oacp->p_ots->p_current_object->data,
+ p_ots_oacp->p_ots->p_current_object->current_size);
+ if (err_code != NRF_SUCCESS)
+ {
+ NRF_LOG_ERROR("ble_ots_l2cap_start_send returned error 0x%x", err_code);
+ }
+ return BLE_OTS_OACP_RES_SUCCESS;
+}
+
+
+/**@brief Handling the OACP abort procedure.
+ *
+ * @details The transmission is aborted.
+ *
+ * @param[in] p_ots_oacp Pointer to the OACP structure.
+ */
+static inline ble_ots_oacp_res_code_t oacp_abort_proc(ble_ots_oacp_t * p_ots_oacp)
+{
+ uint32_t err_code;
+
+ err_code = ble_ots_l2cap_abort_transmission(&p_ots_oacp->ots_l2cap);
+ if (err_code != NRF_SUCCESS)
+ {
+ return BLE_OTS_OACP_RES_OPER_FAILED;
+ }
+
+ p_ots_oacp->p_ots->p_current_object->is_locked = false;
+
+ ble_ots_evt_t ble_ots_evt;
+
+ ble_ots_evt.type = BLE_OTS_EVT_OACP;
+
+ ble_ots_evt.evt.oacp_evt.type = BLE_OTS_OACP_EVT_ABORT;
+ ble_ots_evt.evt.oacp_evt.evt.p_object = p_ots_oacp->p_ots->p_current_object;
+ p_ots_oacp->p_ots->evt_handler(p_ots_oacp->p_ots, &ble_ots_evt);
+
+ return BLE_OTS_OACP_RES_SUCCESS;
+}
+
+/**@brief Sending the oacp procedure response back to the client.
+ *
+ * @details Encodes and sends the response.
+ *
+ * @param[in] p_ots_oacp Pointer to the OACP structure.
+ * @param[in] req_op_code The operation code of the procedure.
+ * @param[in] result_code The result of the procedure.
+ * @param[in] conn_handle The connection handle to send the result to.
+ */
+static uint32_t ble_ots_oacp_response_send(ble_ots_oacp_t * p_ots_oacp,
+ ble_ots_oacp_proc_type_t req_op_code,
+ ble_ots_oacp_res_code_t result_code,
+ uint16_t conn_handle)
+{
+ uint16_t index = 0;
+ uint8_t * p_data;
+ ble_gatts_hvx_params_t *p_hvx_params;
+
+ ble_hvx_t * p_hvx = ble_hvx_get_p_to_next_hvx(&p_ots_oacp->p_ots->hvx_buf);
+ p_data = p_hvx->data;
+ p_hvx_params = &p_hvx->params;
+
+ p_data[index++] = BLE_OTS_OACP_PROC_RESP;
+
+ // Encode the Request Op code
+ p_data[index++] = (uint8_t)req_op_code;
+
+ // Encode the Result code.
+ p_data[index++] = (uint8_t)result_code;
+
+
+ memset(p_hvx_params, 0, sizeof(ble_gatts_hvx_params_t));
+
+ p_hvx_params->handle = p_ots_oacp->oacp_handles.value_handle;
+ p_hvx_params->type = BLE_GATT_HVX_INDICATION;
+ p_hvx_params->offset = 0;
+ p_hvx_params->p_len = &index;
+ p_hvx_params->p_data = p_data;
+
+ return ble_hvx_buffer_process(&p_ots_oacp->p_ots->hvx_buf);
+}
+
+/**@brief Decode an OACP command, and extract its data.
+ *
+ * @param[in] p_ble_write_evt The write event from BLE stack.
+ * @param[out] p_proc The decoded OACP procedure is sent out.
+ *
+ * @return BLE_OTS_WRITE_SUCCESS If the filter was decoded correctly, else an error code.
+ */
+static inline ble_ots_oacp_res_code_t decode_oacp_command(ble_gatts_evt_write_t const * p_ble_write_evt,
+ ble_ots_oacp_proc_t * p_proc)
+{
+ uint32_t index = 0;
+
+ p_proc->type = (ble_ots_oacp_proc_type_t)p_ble_write_evt->data[index++];
+
+ switch (p_proc->type)
+ {
+ case BLE_OTS_OACP_PROC_READ:
+ if (p_ble_write_evt->len !=
+ sizeof(p_proc->params.read_params.offset)
+ + sizeof(p_proc->params.read_params.length)
+ + index)
+ {
+ return BLE_OTS_OACP_RES_INV_PARAM;
+ }
+/*lint --e{415} --e{416} -save suppress Warning 415: Likely access of out-of-bounds pointer */
+ p_proc->params.read_params.offset = uint32_decode(&(p_ble_write_evt->data[index]));
+ index += 4;
+ p_proc->params.read_params.length = uint32_decode(&(p_ble_write_evt->data[index]));
+/*lint -restore*/
+ break;
+ //return BLE_OTS_OACP_RES_SUCCESS;
+ case BLE_OTS_OACP_PROC_WRITE:
+ p_proc->params.write_params.offset = uint32_decode(&(p_ble_write_evt->data[index]));
+ index += sizeof(uint32_t);
+ p_proc->params.write_params.length = uint32_decode(&(p_ble_write_evt->data[index]));
+ index += sizeof(uint32_t);
+ p_proc->params.write_params.write_mode = p_ble_write_evt->data[index];
+ break;
+ default:
+ // No implementation needed
+ break;
+ }
+ return BLE_OTS_OACP_RES_SUCCESS;
+}
+
+
+/**@brief Function for handling the BLE_GAP_EVT_DISCONNECTED event.
+ *
+ * @param[in] p_ots_oacp OTS OACP Structure.
+ * @param[in] p_ble_evt Pointer to the event received from BLE stack.
+ */
+static inline void on_disconnect(ble_ots_oacp_t * p_ots_oacp, ble_evt_t const * p_ble_evt)
+{
+ uint32_t err_code;
+ err_code = fds_gc();
+ if (err_code != NRF_SUCCESS)
+ {
+ p_ots_oacp->p_ots->error_handler(err_code);
+ }
+
+}
+
+
+/**@brief Function for handling the write events to the Blood Pressure Measurement characteristic.
+ *
+ * @param[in] p_bps Blood Pressure Service structure.
+ * @param[in] p_evt_write Write event received from the BLE stack.
+ */
+static void on_cccd_write(ble_ots_oacp_t * p_ots_oacp, ble_gatts_evt_write_t const * p_evt_write)
+{
+ if (p_evt_write->len == 2)
+ {
+ // CCCD written, update indication state
+ if (p_ots_oacp->p_ots->evt_handler != NULL)
+ {
+ ble_ots_evt_t evt;
+
+ if (ble_srv_is_indication_enabled(p_evt_write->data))
+ {
+ evt.type = BLE_OTS_EVT_INDICATION_ENABLED;
+ }
+ else
+ {
+ evt.type = BLE_OTS_EVT_INDICATION_DISABLED;
+ }
+
+ p_ots_oacp->p_ots->evt_handler(p_ots_oacp->p_ots, &evt);
+ }
+ }
+}
+
+
+static void on_oacp_write(ble_ots_oacp_t * p_ots_oacp, ble_gatts_evt_write_t const * p_ble_evt_write)
+{
+ ret_code_t err_code;
+ ble_ots_oacp_res_code_t oacp_status;
+ ble_ots_oacp_proc_t oacp_proc;
+
+ memset(&oacp_proc, 0, sizeof(oacp_proc));
+
+ oacp_status = decode_oacp_command(p_ble_evt_write, &oacp_proc);
+
+ if (oacp_status == BLE_OTS_OACP_RES_SUCCESS)
+ {
+ oacp_status = ble_ots_oacp_do_proc(p_ots_oacp, &oacp_proc);
+ }
+
+ err_code = ble_ots_oacp_response_send(p_ots_oacp,
+ oacp_proc.type,
+ oacp_status,
+ p_ots_oacp->p_ots->conn_handle);
+
+ if (err_code != NRF_SUCCESS)
+ {
+ p_ots_oacp->p_ots->error_handler(err_code);
+ }
+}
+
+
+
+/**@brief Function for handling the Write event.
+ *
+ * @param[in] p_bps Blood Pressure Service structure.
+ * @param[in] p_ble_evt Event received from the BLE stack.
+ */
+static void on_write(ble_ots_oacp_t * p_ots_oacp, ble_evt_t const * p_ble_evt)
+{
+ ble_gatts_evt_write_t const * p_evt_write = &p_ble_evt->evt.gatts_evt.params.write;
+
+ if (p_evt_write->handle == p_ots_oacp->p_ots->oacp_chars.oacp_handles.cccd_handle)
+ {
+ on_cccd_write(p_ots_oacp, p_evt_write);
+ }
+ if (p_evt_write->handle == p_ots_oacp->p_ots->oacp_chars.oacp_handles.value_handle)
+ {
+ on_oacp_write(p_ots_oacp, p_evt_write);
+ }
+}
+
+
+void ble_ots_oacp_on_ble_evt(ble_ots_oacp_t * p_ots_oacp, ble_evt_t const * p_ble_evt)
+{
+ if ((p_ots_oacp == NULL) || (p_ble_evt == NULL))
+ {
+ return;
+ }
+
+ ble_ots_l2cap_on_ble_evt(&p_ots_oacp->ots_l2cap, p_ble_evt);
+
+ switch (p_ble_evt->header.evt_id)
+ {
+
+ case BLE_GAP_EVT_DISCONNECTED:
+ on_disconnect(p_ots_oacp, p_ble_evt);
+ break;
+
+ case BLE_GATTS_EVT_WRITE:
+ on_write(p_ots_oacp, p_ble_evt);
+ break;
+ default:
+ // No implementation needed.
+ break;
+ }
+}
+
+uint32_t ble_ots_oacp_init(ble_ots_oacp_t * p_ots_oacp, ble_ots_oacp_init_t * p_ots_oacp_init)
+{
+ uint32_t err_code;
+
+ if (p_ots_oacp == NULL || p_ots_oacp_init == NULL)
+ {
+ return NRF_ERROR_NULL;
+ }
+ p_ots_oacp->p_ots = p_ots_oacp_init->p_ots;
+ p_ots_oacp->on_create_obj_properties_raw = p_ots_oacp_init->on_create_obj_properties_raw;
+
+ ble_ots_l2cap_init_t l2cap_init;
+
+ l2cap_init.p_ots_oacp = p_ots_oacp;
+ l2cap_init.evt_handler = ots_l2cap_evt_handler;
+ l2cap_init.p_transfer_buffer = p_ots_oacp_init->p_l2cap_buffer;
+ l2cap_init.buffer_len = p_ots_oacp_init->l2cap_buffer_len;
+
+ err_code = ble_ots_l2cap_init(&p_ots_oacp->ots_l2cap, &l2cap_init);
+ if (err_code != NRF_SUCCESS)
+ {
+ return err_code;
+ }
+
+
+ return oacp_char_add(p_ots_oacp,
+ p_ots_oacp->p_ots->service_handle,
+ p_ots_oacp_init->write_access,
+ p_ots_oacp_init->cccd_write_access);
+}
+
+
+ble_ots_oacp_res_code_t ble_ots_oacp_do_proc(ble_ots_oacp_t * p_ots_oacp,
+ ble_ots_oacp_proc_t * p_oacp_proc)
+{
+ if (p_ots_oacp == NULL || p_oacp_proc == NULL)
+ {
+ return BLE_OTS_OACP_RES_INV_PARAM;
+ }
+
+ ble_ots_oacp_res_code_t oacp_status;
+
+ switch (p_oacp_proc->type)
+ {
+ case BLE_OTS_OACP_PROC_WRITE:
+ oacp_status = oacp_write_proc(p_ots_oacp,
+ p_oacp_proc->params.write_params.offset,
+ p_oacp_proc->params.write_params.length,
+ p_oacp_proc->params.write_params.write_mode);
+ break;
+ case BLE_OTS_OACP_PROC_READ:
+ oacp_status = oacp_read_proc(p_ots_oacp,
+ p_oacp_proc->params.read_params.offset,
+ p_oacp_proc->params.read_params.length);
+ break;
+
+ case BLE_OTS_OACP_PROC_ABORT:
+ oacp_status = oacp_abort_proc(p_ots_oacp);
+ break;
+
+ default:
+ // Unsupported op code.
+ oacp_status = BLE_OTS_OACP_RES_OPCODE_NOT_SUP;
+
+ }
+ return oacp_status;
+}
+
+
+
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/experimental_ble_ots/ble_ots_oacp.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/experimental_ble_ots/ble_ots_oacp.h
new file mode 100644
index 0000000..9f41204
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/experimental_ble_ots/ble_ots_oacp.h
@@ -0,0 +1,90 @@
+/**
+ * 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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
+ *
+ * @defgroup ble_sdk_srv_ots_oacp Object Transfer Service, OACP handling
+ * @{
+ * @ingroup ble_ots
+ * @brief Object Transfer Service module
+ *
+ * @details This module is responsible for handling the Object Transfer Service
+ * Object Action Control Point.
+ */
+#ifndef BLE_OTS_OACP_H__
+#define BLE_OTS_OACP_H__
+
+#include <stdint.h>
+#include "ble_ots.h"
+
+/**@brief Function for initializing the Object Transfer OACP characteristic.
+ *
+ * @param[out] p_ots_oacp Object Transfer Service OACP structure. This structure will have
+ * to be supplied by the application. It will be initialized by this function,
+ * and will later be used to identify this particular instance.
+ * @param[in] p_ots_oacp_init Information needed to initialize the module.
+ *
+ * @return NRF_SUCCESS on successful initialization, otherwise an error code.
+ */
+uint32_t ble_ots_oacp_init(ble_ots_oacp_t * p_ots_oacp, ble_ots_oacp_init_t * p_ots_oacp_init);
+
+/**@brief Function for handling the Application's BLE Stack events.
+ *
+ * @details Handles all events from the BLE stack of interest to the OACP module.
+ *
+ * @param[in] p_ots_oacp Object Transfer Service OACP structure
+ * @param[in] p_ble_evt Event received from the BLE stack.
+ */
+void ble_ots_oacp_on_ble_evt(ble_ots_oacp_t * p_ots_oacp, ble_evt_t const * p_ble_evt);
+
+/**@brief Execute an Object Action Control Point procedure
+ *
+ * @param[in] p_ots_oacp Object Transfer Service OACP structure.
+ * @param[in] p_oacp_proc Pointer to the procedure to be applied.
+ *
+ * @return BLE_OTS_WRITE_SUCCESS on success, otherwise an error.
+ */
+ble_ots_oacp_res_code_t ble_ots_oacp_do_proc(ble_ots_oacp_t * p_ots_oacp,
+ ble_ots_oacp_proc_t * p_oacp_proc);
+
+
+#endif // BLE_OTS_OACP_H__
+
+/** @} */ // End tag for the file.
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/experimental_ble_ots/ble_ots_object.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/experimental_ble_ots/ble_ots_object.c
new file mode 100644
index 0000000..0abc39d
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/experimental_ble_ots/ble_ots_object.c
@@ -0,0 +1,577 @@
+/**
+ * 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#include "ble_ots_object.h"
+
+#include <string.h>
+#include "ble_srv_common.h"
+
+#include "ble_ots.h"
+
+#define BLE_OTS_WRITE_REQUEST_REJECTED 0x80
+
+#define BLE_OTS_OBJECT_NOT_SELECTED 0x81
+#define BLE_OTS_CONCURRENCY_LIMIT_EXCEEDED 0x82
+#define BLE_OTS_OBJ_NAME_ALREADY_EXISTS 0x83
+#define BLE_SIZE_DATE_TIME 7
+
+
+uint32_t ble_ots_object_refresh_current(ble_ots_object_chars_t * p_ots_object_chars)
+{
+ uint32_t err_code;
+ ble_ots_object_t * p_obj;
+
+ p_obj = p_ots_object_chars->p_ots->p_current_object;
+
+ if (p_obj == NULL)
+ {
+ // Clear all characteristics
+ return NRF_SUCCESS;
+ }
+
+
+ // obtain the largest necessary buffer
+ typedef union {
+ uint8_t type_buf[sizeof(ble_ots_obj_type_t)+sizeof(uint8_t)];
+ uint8_t size_buf[2*sizeof(uint32_t)];
+ uint8_t prop_buf[sizeof(uint32_t)];
+ } buffer_t;
+
+ buffer_t buffer;
+
+ ble_gatts_value_t gatts_value;
+
+ memset(&gatts_value, 0, sizeof(gatts_value));
+
+ // name
+ gatts_value.len = strlen((const char *)p_obj->name) + 1;
+ gatts_value.p_value = p_obj->name;
+ err_code = sd_ble_gatts_value_set(p_ots_object_chars->p_ots->conn_handle,
+ p_ots_object_chars->obj_name_handles.value_handle,
+ &gatts_value);
+ if (err_code != NRF_SUCCESS)
+ {
+ return err_code;
+ }
+
+ // type
+ if (p_obj->type.len == sizeof(uint16_t))
+ {
+ gatts_value.len = uint16_encode(p_obj->type.param.type16, buffer.type_buf);
+ gatts_value.p_value = buffer.type_buf;
+ err_code = sd_ble_gatts_value_set(p_ots_object_chars->p_ots->conn_handle,
+ p_ots_object_chars->obj_type_handles.value_handle,
+ &gatts_value);
+ }
+ else
+ {
+ gatts_value.len = uint16_encode(p_obj->type.param.type16, buffer.type_buf);
+ gatts_value.p_value = p_obj->type.param.type128;
+ err_code = sd_ble_gatts_value_set(p_ots_object_chars->p_ots->conn_handle,
+ p_ots_object_chars->obj_type_handles.value_handle,
+ &gatts_value);
+ }
+ if (err_code != NRF_SUCCESS)
+ {
+ return err_code;
+ }
+
+ gatts_value.len = uint32_encode(p_obj->current_size, &buffer.size_buf[0]);
+ gatts_value.len += uint32_encode(p_obj->alloc_len, &buffer.size_buf[gatts_value.len]);
+ gatts_value.p_value = &buffer.size_buf[0];
+ err_code = sd_ble_gatts_value_set(p_ots_object_chars->p_ots->conn_handle,
+ p_ots_object_chars->obj_size_handles.value_handle,
+ &gatts_value);
+ if (err_code != NRF_SUCCESS)
+ {
+ return err_code;
+ }
+
+ gatts_value.len = uint32_encode(p_obj->properties.raw, buffer.prop_buf);
+ gatts_value.p_value = buffer.prop_buf;
+ err_code = sd_ble_gatts_value_set(p_ots_object_chars->p_ots->conn_handle,
+ p_ots_object_chars->obj_properties_handles.value_handle,
+ &gatts_value);
+ if (err_code != NRF_SUCCESS)
+ {
+ return err_code;
+ }
+
+ return NRF_SUCCESS;
+}
+
+/**@brief Function for adding the object name characteristic.
+ *
+ * @param[in] p_ots_object_chars Pointer the the object characteristics.
+ * @param[in] service_handle The service handle where the characteristic should be added.
+ * @param[in] read_access The read security level for the characteristic.
+ * @param[in] write_access The write security level for the characteristic.
+ *
+ * @return NRF_SUCCESS if the characteristic was successfully added, else a return code from
+ * characteristic_add().
+ */
+static uint32_t obj_name_char_add(ble_ots_object_chars_t * const p_ots_object_chars,
+ uint16_t service_handle,
+ security_req_t read_access,
+ security_req_t write_access)
+{
+ ble_add_char_params_t add_char_params;
+
+ memset(&add_char_params, 0, sizeof(add_char_params));
+
+ add_char_params.uuid = BLE_UUID_OTS_OBJECT_NAME;
+ add_char_params.uuid_type = BLE_UUID_TYPE_BLE;
+ add_char_params.max_len = BLE_OTS_NAME_MAX_SIZE;
+ add_char_params.is_var_len = 1;
+ add_char_params.char_props.read = 1;
+ add_char_params.read_access = read_access;
+ add_char_params.char_props.write = 0;
+
+ return characteristic_add(service_handle,
+ &add_char_params,
+ &p_ots_object_chars->obj_name_handles);
+}
+
+/**@brief Function for adding the object type characteristic.
+ *
+ * @param[in] p_ots_object_chars Pointer the the object characteristics.
+ * @param[in] service_handle The service handle where the characteristic should be added.
+ * @param[in] read_access The read security level for the characteristic.
+ *
+ * @return NRF_SUCCESS if the characteristic was successfully added, else a return code from
+ * characteristic_add().
+ */
+static uint32_t obj_type_char_add(ble_ots_object_chars_t * const p_ots_object_chars,
+ uint16_t service_handle,
+ security_req_t read_access)
+{
+ ble_add_char_params_t add_char_params;
+
+ memset(&add_char_params, 0, sizeof(add_char_params));
+
+ add_char_params.uuid = BLE_UUID_OTS_OBJECT_TYPE;
+ add_char_params.uuid_type = BLE_UUID_TYPE_BLE;
+ add_char_params.max_len = sizeof(ble_ots_obj_type_t);
+ add_char_params.is_var_len = 1;
+ add_char_params.char_props.read = 1;
+ add_char_params.read_access = read_access;
+
+ return characteristic_add(service_handle,
+ &add_char_params,
+ &p_ots_object_chars->obj_type_handles);
+}
+
+/**@brief Function for adding the object size characteristic.
+ *
+ * @param[in] p_ots_object_chars Pointer the the object characteristics.
+ * @param[in] service_handle The service handle where the characteristic should be added.
+ * @param[in] read_access The read security level for the characteristic.
+ *
+ * @return NRF_SUCCESS if the characteristic was successfully added, else a return code from
+ * characteristic_add().
+ */
+static uint32_t obj_size_char_add(ble_ots_object_chars_t * const p_ots_object_chars,
+ uint16_t service_handle,
+ security_req_t read_access)
+{
+ ble_add_char_params_t add_char_params;
+
+ memset(&add_char_params, 0, sizeof(add_char_params));
+
+ add_char_params.uuid = BLE_UUID_OTS_OBJECT_SIZE;
+ add_char_params.uuid_type = BLE_UUID_TYPE_BLE;
+ add_char_params.max_len = NRF_BLE_OTS_SIZE_CHAR_LEN;
+ add_char_params.is_var_len = 0;
+ add_char_params.char_props.read = 1;
+ add_char_params.read_access = read_access;
+
+ return characteristic_add(service_handle,
+ &add_char_params,
+ &p_ots_object_chars->obj_size_handles);
+}
+
+/**@brief Function for adding the object properties characteristic.
+ *
+ * @param[in] p_ots_object_chars Pointer the the object characteristics.
+ * @param[in] service_handle The service handle where the characteristic should be added.
+ * @param[in] read_access The read security level for the characteristic.
+ * @param[in] write_access The write security level for the characteristic.
+ *
+ * @return NRF_SUCCESS if the characteristic was successfully added, else a return code from
+ * characteristic_add().
+ */
+static uint32_t obj_prop_char_add(ble_ots_object_chars_t * const p_ots_object_chars,
+ uint16_t service_handle,
+ security_req_t read_access,
+ security_req_t write_access)
+{
+ ble_add_char_params_t add_char_params;
+
+ memset(&add_char_params, 0, sizeof(add_char_params));
+
+ add_char_params.uuid = BLE_UUID_OTS_OBJECT_PROPERTIES;
+ add_char_params.uuid_type = BLE_UUID_TYPE_BLE;
+ add_char_params.max_len = sizeof(uint32_t);
+ add_char_params.is_var_len = 0;
+ add_char_params.char_props.read = 1;
+ add_char_params.read_access = read_access;
+
+ add_char_params.is_defered_write = 1;
+ add_char_params.write_access = write_access;
+
+ return characteristic_add(service_handle,
+ &add_char_params,
+ &p_ots_object_chars->obj_properties_handles);
+}
+
+
+
+
+
+uint32_t ble_ots_object_representation_init(ble_ots_object_chars_t * p_ots_object_chars,
+ ble_ots_object_chars_init_t * p_ots_object_chars_init)
+{
+ if (p_ots_object_chars == NULL || p_ots_object_chars_init == NULL)
+ {
+ return NRF_ERROR_NULL;
+ }
+
+ uint32_t err_code;
+
+ p_ots_object_chars->p_ots = p_ots_object_chars_init->p_ots;
+
+ err_code = obj_name_char_add(p_ots_object_chars,
+ p_ots_object_chars_init->p_ots->service_handle,
+ p_ots_object_chars_init->name_read_access,
+ p_ots_object_chars_init->name_write_access);
+ if (err_code != NRF_SUCCESS)
+ {
+ return err_code;
+ }
+
+ err_code = obj_type_char_add(p_ots_object_chars,
+ p_ots_object_chars_init->p_ots->service_handle,
+ p_ots_object_chars_init->type_read_access);
+ if (err_code != NRF_SUCCESS)
+ {
+ return err_code;
+ }
+ err_code = obj_size_char_add(p_ots_object_chars,
+ p_ots_object_chars_init->p_ots->service_handle,
+ p_ots_object_chars_init->size_read_access);
+ if (err_code != NRF_SUCCESS)
+ {
+ return err_code;
+ }
+ err_code = obj_prop_char_add(p_ots_object_chars,
+ p_ots_object_chars_init->p_ots->service_handle,
+ p_ots_object_chars_init->properties_read_access,
+ p_ots_object_chars_init->properties_write_access);
+ if (err_code != NRF_SUCCESS)
+ {
+ return err_code;
+ }
+ return ble_ots_object_refresh_current(p_ots_object_chars);
+}
+
+
+uint32_t ble_ots_object_set_name(ble_ots_object_chars_t * p_ots_object_chars,
+ ble_ots_object_t * p_object,
+ const char * new_name)
+{
+ if (p_ots_object_chars == NULL || p_object == NULL || new_name == NULL)
+ {
+ return NRF_ERROR_NULL;
+ }
+
+
+
+ strncpy((char *)p_object->name, new_name, BLE_OTS_NAME_MAX_SIZE);
+
+ if (p_object == p_ots_object_chars->p_ots->p_current_object)
+ {
+ // update characteristic
+ uint32_t err_code;
+ ble_gatts_value_t gatts_value;
+
+ memset(&gatts_value, 0, sizeof(gatts_value));
+
+ gatts_value.len = strlen((const char *)p_object->name) + 1;
+ gatts_value.p_value = p_object->name;
+ err_code = sd_ble_gatts_value_set(p_ots_object_chars->p_ots->conn_handle,
+ p_ots_object_chars->obj_name_handles.value_handle,
+ &gatts_value);
+ if (err_code != NRF_SUCCESS)
+ {
+ return err_code;
+ }
+ }
+
+
+ return NRF_SUCCESS;
+}
+
+uint32_t ble_ots_object_set_type(ble_ots_object_chars_t * p_ots_object_chars,
+ ble_ots_object_t * p_object,
+ ble_ots_obj_type_t * p_new_type)
+{
+ if (p_ots_object_chars == NULL || p_object == NULL || p_new_type == NULL)
+ {
+ return NRF_ERROR_NULL;
+ }
+
+ if (p_new_type->len != sizeof(p_new_type->param.type16) && p_new_type->len != sizeof(p_new_type->param.type128))
+ {
+ return NRF_ERROR_INVALID_PARAM;
+ }
+
+ memcpy(&p_object->type, p_new_type, sizeof(ble_ots_obj_type_t));
+
+ if (p_object == p_ots_object_chars->p_ots->p_current_object)
+ {
+ // update characteristic
+ uint32_t err_code;
+ uint8_t buffer[sizeof(p_new_type->param.type16)];
+ ble_gatts_value_t gatts_value;
+
+ memset(&gatts_value, 0, sizeof(gatts_value));
+
+ if (p_object->type.len == sizeof(uint16_t))
+ {
+ gatts_value.len = uint16_encode(p_object->type.param.type16, buffer);
+ gatts_value.p_value = buffer;
+ err_code = sd_ble_gatts_value_set(p_ots_object_chars->p_ots->conn_handle,
+ p_ots_object_chars->obj_type_handles.value_handle,
+ &gatts_value);
+ }
+ else
+ {
+ gatts_value.len = uint16_encode(p_object->type.param.type16, buffer);
+ gatts_value.p_value = p_object->type.param.type128;
+ err_code = sd_ble_gatts_value_set(p_ots_object_chars->p_ots->conn_handle,
+ p_ots_object_chars->obj_type_handles.value_handle,
+ &gatts_value);
+ }
+ if (err_code != NRF_SUCCESS)
+ {
+ return err_code;
+ }
+ }
+
+
+ return NRF_SUCCESS;
+
+}
+
+uint32_t ble_ots_object_set_current_size(ble_ots_object_chars_t * p_ots_object_chars,
+ ble_ots_object_t * p_object,
+ uint32_t new_current_size)
+{
+ if (p_ots_object_chars == NULL || p_object == NULL)
+ {
+ return NRF_ERROR_NULL;
+ }
+
+ p_object->current_size = new_current_size;
+
+ if (p_object == p_ots_object_chars->p_ots->p_current_object)
+ {
+ // update characteristic
+ uint32_t err_code;
+ uint8_t buffer[NRF_BLE_OTS_SIZE_CHAR_LEN];
+ ble_gatts_value_t gatts_value;
+
+ memset(&gatts_value, 0, sizeof(gatts_value));
+
+ gatts_value.len = 0;
+ gatts_value.len += uint32_encode(p_object->current_size, &buffer[gatts_value.len]);
+ gatts_value.len += uint32_encode(p_object->alloc_len, &buffer[gatts_value.len]);
+ gatts_value.p_value = &buffer[0];
+ err_code = sd_ble_gatts_value_set(p_ots_object_chars->p_ots->conn_handle,
+ p_ots_object_chars->obj_size_handles.value_handle,
+ &gatts_value);
+ if (err_code != NRF_SUCCESS)
+ {
+ return err_code;
+ }
+ }
+
+
+ return NRF_SUCCESS;
+
+}
+
+
+/**@brief Function for handling write on object properties meta data.
+ *
+ * @param[in] p_ots_object_chars Pointer the the object characteristics.
+ * @param[in] p_ble_evt Pointer to the event received from BLE stack.
+ */
+static uint32_t on_obj_properties_write(ble_ots_object_chars_t * p_ots_object_chars,
+ ble_evt_t const * p_ble_evt)
+{
+// uint32_t err_code;
+ ble_gatts_rw_authorize_reply_params_t write_authorize_reply;
+ ble_gatts_evt_write_t const * p_write_evt;
+
+ p_write_evt = &p_ble_evt->evt.gatts_evt.params.authorize_request.request.write;
+
+ write_authorize_reply.type = BLE_GATTS_AUTHORIZE_TYPE_WRITE;
+
+ uint32_t raw_prop = uint32_decode(p_write_evt->data);
+ if ((raw_prop & 0xFFFFFF80) != 0)
+ {
+ write_authorize_reply.params.write.gatt_status = BLE_OTS_WRITE_REQUEST_REJECTED;
+ }
+ else
+ {
+ p_ots_object_chars->p_ots->p_current_object->properties.raw = raw_prop;
+ write_authorize_reply.params.write.gatt_status = BLE_GATT_STATUS_SUCCESS;
+
+ ble_ots_evt_t ble_ots_evt;
+
+ ble_ots_evt.type = BLE_OTS_EVT_OBJECT;
+
+ ble_ots_evt.evt.object_evt.type = BLE_OTS_OBJECT_EVT_PROPERTIES_CHANGED;
+ ble_ots_evt.evt.object_evt.evt.p_object = p_ots_object_chars->p_ots->p_current_object;
+ p_ots_object_chars->p_ots->evt_handler(p_ots_object_chars->p_ots, &ble_ots_evt);
+
+ }
+ return sd_ble_gatts_rw_authorize_reply(p_ble_evt->evt.gatts_evt.conn_handle, &write_authorize_reply);
+}
+
+uint32_t ble_ots_object_set_properties(ble_ots_object_chars_t * p_ots_object_chars,
+ ble_ots_object_t * p_object,
+ ble_ots_obj_properties_t * p_new_properties)
+{
+ if (p_ots_object_chars == NULL || p_object == NULL)
+ {
+ return NRF_ERROR_NULL;
+ }
+
+ memcpy(&p_object->properties, p_new_properties, sizeof(ble_ots_obj_properties_t));
+
+
+ if (p_object == p_ots_object_chars->p_ots->p_current_object)
+ {
+ // update characteristic
+ uint32_t err_code;
+ uint8_t buffer[sizeof(ble_ots_obj_properties_t)];
+ ble_gatts_value_t gatts_value;
+
+ memset(&gatts_value, 0, sizeof(gatts_value));
+
+ gatts_value.len = uint32_encode(p_object->properties.raw, buffer);
+ gatts_value.p_value = buffer;
+ err_code = sd_ble_gatts_value_set(p_ots_object_chars->p_ots->conn_handle,
+ p_ots_object_chars->obj_properties_handles.value_handle,
+ &gatts_value);
+
+ if (err_code != NRF_SUCCESS)
+ {
+ return err_code;
+ }
+ }
+
+ return NRF_SUCCESS;
+}
+
+
+/**@brief Function for handling the @ref BLE_GATTS_EVT_RW_AUTHORIZE_REQUEST event.
+ *
+ * @param[in] p_ots_object_chars Pointer the the object characteristics.
+ * @param[in] p_ble_evt Pointer to the event received from BLE stack.
+ */
+static void on_rw_auth_req(ble_ots_object_chars_t * p_ots_object_chars, ble_evt_t const * p_ble_evt)
+{
+ uint32_t err_code;
+ ble_gatts_evt_rw_authorize_request_t const * p_authorize_request;
+
+ p_authorize_request = &(p_ble_evt->evt.gatts_evt.params.authorize_request);
+
+ if (p_authorize_request->type == BLE_GATTS_AUTHORIZE_TYPE_WRITE)
+ {
+ if (p_authorize_request->request.write.handle == p_ots_object_chars->obj_name_handles.value_handle)
+ {
+ //err_code = on_name_prepare_write(p_ots_object_chars, p_ble_evt);
+
+ // if (err_code != NRF_SUCCESS)
+ // {
+ // p_ots_object_chars->p_ots->error_handler(err_code);
+ // }
+ }
+ else
+ if (p_authorize_request->request.write.handle == p_ots_object_chars->obj_properties_handles.value_handle)
+ {
+ err_code = on_obj_properties_write(p_ots_object_chars, p_ble_evt);
+ if (err_code != NRF_SUCCESS)
+ {
+ p_ots_object_chars->p_ots->error_handler(err_code);
+ }
+ }
+ }
+}
+
+
+void ble_ots_object_on_ble_evt(ble_ots_object_chars_t * p_ots_chars, ble_evt_t const * p_ble_evt)
+{
+ if ((p_ots_chars == NULL) || (p_ble_evt == NULL))
+ {
+ return;
+ }
+// uint32_t err_code;
+ switch (p_ble_evt->header.evt_id)
+ {
+ case BLE_GAP_EVT_CONNECTED:
+// err_code = ble_ots_object_refresh_current(p_ots_chars);
+// if (err_code != NRF_SUCCESS)
+// {
+// p_ots_chars->p_ots->error_handler(err_code);
+// }
+ break;
+
+ case BLE_GATTS_EVT_RW_AUTHORIZE_REQUEST:
+ on_rw_auth_req(p_ots_chars, p_ble_evt);
+ break;
+
+ default:
+ // No implementation needed.
+ break;
+ }
+}
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/experimental_ble_ots/ble_ots_object.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/experimental_ble_ots/ble_ots_object.h
new file mode 100644
index 0000000..b42a24d
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/experimental_ble_ots/ble_ots_object.h
@@ -0,0 +1,86 @@
+/**
+ * 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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
+ *
+ * @defgroup ble_sdk_srv_ots_obj Object Transfer Service, Object characteristics
+ * @{
+ * @ingroup ble_ots
+ * @brief Object Transfer Service module
+ *
+ * @details This module is responsible for the object properties characteristics.
+ */
+
+#ifndef BLE_OTS_OBJECT_H__
+#define BLE_OTS_OBJECT_H__
+
+#include <stdint.h>
+#include "ble_ots.h"
+
+/**@brief Function for initializing the Object Transfer Object representation characteristics.
+ *
+ * @param[out] p_ots_object_chars Object Transfer Service object characteristics representation structure. * This structure will have to be supplied by the application. It * will be initialized by this function, and will later be used to * identify this particular instance.
+ * @param[in] p_ots_object_chars_init Information needed to initialize the module.
+ *
+ * @return NRF_SUCCESS on successful initialization, otherwise an error code.
+ */
+uint32_t ble_ots_object_representation_init(ble_ots_object_chars_t * p_ots_object_chars,
+ ble_ots_object_chars_init_t * p_ots_object_chars_init);
+
+/**@brief Refresh the characteristics of the current object.
+ * @param[in] p_ots_object_chars Pointer the the object characteristics.
+ * @return NRF_SUCCESS if everything was refreshed.
+ */
+uint32_t ble_ots_object_refresh_current(ble_ots_object_chars_t * p_ots_object_chars);
+
+
+/**@brief Function for handling the Application's BLE Stack events.
+ *
+ * @details Handles all events from the BLE stack of interest to the list filter module.
+ *
+ * @param[in] p_ots_object_chars Pointer the the object characteristics.
+ * @param[in] p_ble_evt Event received from the BLE stack.
+ */
+void ble_ots_object_on_ble_evt(ble_ots_object_chars_t * p_ots_object_chars,
+ ble_evt_t const * p_ble_evt);
+
+#endif // BLE_OTS_OBJECT_H__
+
+/** @} */ // End tag for the file.
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/experimental_gatts_c/nrf_ble_gatts_c.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/experimental_gatts_c/nrf_ble_gatts_c.c
new file mode 100644
index 0000000..8450ad6
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/experimental_gatts_c/nrf_ble_gatts_c.c
@@ -0,0 +1,276 @@
+/**
+ * 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+
+#include "sdk_common.h"
+#if NRF_MODULE_ENABLED(NRF_BLE_GATTS_C)
+
+#include "nrf_ble_gatts_c.h"
+#include <string.h>
+#include "ble.h"
+
+#define NRF_LOG_MODULE_NAME nrf_ble_gatts_c
+#include "nrf_log.h"
+NRF_LOG_MODULE_REGISTER();
+
+
+#define GATTS_LOG NRF_LOG_DEBUG /**< A debug logger macro that can be used in this file to perform logging over UART. */
+#define MODULE_INITIALIZED (p_gatts_c->initialized) /**< Macro indicating whether the module has been initialized properly. */
+
+static const ble_uuid_t m_gatts_uuid = {BLE_UUID_GATT, BLE_UUID_TYPE_BLE}; /**< Service Changed indication UUID. */
+
+
+/**@brief Function for handling the indication and notifications from the GATT Service Server.
+
+ @param[in] p_gatts_c Pointer to Service Changed client structure.
+ @param[in] p_ble_gattc_evt Pointer to a gattc event.
+*/
+static void on_hvx(nrf_ble_gatts_c_t const * const p_gatts_c,
+ ble_gattc_evt_t const * const p_ble_gattc_evt)
+{
+ uint16_t srv_changed_handle = p_gatts_c->srv_changed_char.characteristic.handle_value;
+
+ if ((p_ble_gattc_evt->params.hvx.handle == srv_changed_handle)
+ && (p_gatts_c->evt_handler != NULL))
+ {
+ ret_code_t err_code = sd_ble_gattc_hv_confirm(p_ble_gattc_evt->conn_handle,
+ srv_changed_handle);
+
+ if ((err_code != NRF_SUCCESS) && (p_gatts_c->err_handler != NULL))
+ {
+ p_gatts_c->err_handler(err_code);
+ }
+
+ nrf_ble_gatts_c_evt_t evt;
+ nrf_ble_gatts_c_evt_handler_t evt_handler = p_gatts_c->evt_handler;
+
+ /*lint --e{415} --e{416} -save suppress Warning 415: Likely access of out-of-bounds pointer */
+ evt.params.handle_range.start_handle = uint16_decode(p_ble_gattc_evt->params.hvx.data);
+ evt.params.handle_range.end_handle = uint16_decode(p_ble_gattc_evt->params.hvx.data + sizeof(uint16_t));
+ /*lint -restore*/
+
+ evt.evt_type = NRF_BLE_GATTS_C_EVT_SRV_CHANGED;
+ evt.conn_handle = p_ble_gattc_evt->conn_handle;
+
+ GATTS_LOG ("Service Changed Indication.\n\r");
+ evt_handler(&evt);
+
+ }
+}
+
+
+ret_code_t nrf_ble_gatts_c_init(nrf_ble_gatts_c_t * p_gatts_c,
+ nrf_ble_gatts_c_init_t * p_gatts_c_init)
+{
+ ret_code_t err_code = NRF_SUCCESS;
+ VERIFY_PARAM_NOT_NULL(p_gatts_c);
+ VERIFY_PARAM_NOT_NULL(p_gatts_c_init);
+ VERIFY_PARAM_NOT_NULL(p_gatts_c_init->evt_handler);
+ memset (p_gatts_c, 0, sizeof(nrf_ble_gatts_c_t));
+
+ p_gatts_c->conn_handle = BLE_CONN_HANDLE_INVALID;
+ p_gatts_c->evt_handler = p_gatts_c_init->evt_handler;
+
+ err_code = ble_db_discovery_evt_register(&m_gatts_uuid);
+ VERIFY_SUCCESS(err_code);
+
+ p_gatts_c->initialized = true;
+ return err_code;
+}
+
+
+/**@brief Function for checking whether the peer's GATT Service instance and the Service Changed
+ Characteristic have been discovered.
+
+ @param[in] p_gatts_c Pointer to the GATT Service client structure instance.
+
+ @return True if the Service Changed Characteristic handle is valid.
+ @return False if the Service Changed Characteristic handle is invalid.
+ */
+static bool gatts_gatt_handles_are_valid(nrf_ble_gatts_c_t const * const p_gatts_c)
+{
+ return (p_gatts_c->srv_changed_char.characteristic.handle_value != BLE_GATT_HANDLE_INVALID);
+}
+
+
+ret_code_t nrf_ble_gatts_c_enable_indication(nrf_ble_gatts_c_t * const p_gatts_c,
+ bool const enable)
+{
+ VERIFY_MODULE_INITIALIZED();
+
+ if ( (p_gatts_c->conn_handle == BLE_CONN_HANDLE_INVALID)
+ || !(gatts_gatt_handles_are_valid(p_gatts_c)))
+ {
+ return NRF_ERROR_INVALID_STATE;
+ }
+
+ ret_code_t err_code = NRF_SUCCESS;
+ uint16_t cccd_val = (enable) ? BLE_GATT_HVX_INDICATION : 0;
+
+ ble_gattc_write_params_t gattc_params =
+ {
+ .handle = p_gatts_c->srv_changed_char.cccd_handle,
+ .len = BLE_CCCD_VALUE_LEN,
+ .p_value = (uint8_t *)&cccd_val,
+ .offset = 0,
+ .write_op = BLE_GATT_OP_WRITE_REQ,
+ };
+
+ err_code = sd_ble_gattc_write(p_gatts_c->conn_handle, &gattc_params);
+ return err_code;
+}
+
+
+void nrf_ble_gatts_c_on_db_disc_evt(nrf_ble_gatts_c_t const * const p_gatts_c,
+ ble_db_discovery_evt_t * const p_evt)
+{
+ VERIFY_MODULE_INITIALIZED_VOID();
+
+ nrf_ble_gatts_c_evt_t evt;
+ ble_gatt_db_char_t * p_chars;
+
+ p_chars = p_evt->params.discovered_db.charateristics;
+ evt.evt_type = NRF_BLE_GATTS_C_EVT_DISCOVERY_FAILED;
+
+ if ( (p_evt->evt_type == BLE_DB_DISCOVERY_COMPLETE)
+ && (p_evt->params.discovered_db.srv_uuid.uuid == BLE_UUID_GATT)
+ && (p_evt->params.discovered_db.srv_uuid.type == BLE_UUID_TYPE_BLE))
+ {
+ // Find the handles of the Service Changed Characteristics.
+ for (uint32_t i = 0; i < p_evt->params.discovered_db.char_count; i++)
+ {
+ if ( (p_chars[i].characteristic.uuid.uuid == BLE_UUID_GATT_CHARACTERISTIC_SERVICE_CHANGED)
+ && (p_chars[i].characteristic.char_props.indicate != 0))
+ {
+ memcpy(&evt.params.srv_changed_char,
+ &p_chars[i],
+ sizeof(ble_gatt_db_char_t));
+
+ evt.evt_type = NRF_BLE_GATTS_C_EVT_DISCOVERY_COMPLETE;
+ GATTS_LOG("Service Changed Characteristic found.\n\r");
+ break;
+ }
+ }
+ }
+
+ if (p_gatts_c->evt_handler != NULL)
+ {
+ nrf_ble_gatts_c_evt_handler_t evt_handler = p_gatts_c->evt_handler;
+ evt.conn_handle = p_evt->conn_handle;
+ evt_handler(&evt);
+ }
+}
+
+
+/**@brief Function for handling the Disconnect event.
+
+ @param[in] p_cts Pointer to the GATT Service client structure instance.
+ @param[in] p_ble_evt Event received from the BLE stack.
+ */
+static void on_disconnect(nrf_ble_gatts_c_t * p_gatts_c, ble_evt_t const * p_ble_evt)
+{
+ if (p_gatts_c->conn_handle == p_ble_evt->evt.gap_evt.conn_handle)
+ {
+ p_gatts_c->conn_handle = BLE_CONN_HANDLE_INVALID;
+
+ if (gatts_gatt_handles_are_valid(p_gatts_c))
+ {
+ // There was a valid instance of GATTS on the peer. Send an event to the
+ // application, so that it can do any clean up related to this module.
+ nrf_ble_gatts_c_evt_t evt;
+
+ evt.evt_type = NRF_BLE_GATTS_C_EVT_DISCONN_COMPLETE;
+
+ p_gatts_c->evt_handler(&evt);
+ p_gatts_c->srv_changed_char.characteristic.handle_value = BLE_GATT_HANDLE_INVALID;
+ p_gatts_c->srv_changed_char.cccd_handle = BLE_GATT_HANDLE_INVALID;
+ p_gatts_c->srv_changed_char.ext_prop_handle = BLE_GATT_HANDLE_INVALID;
+ p_gatts_c->srv_changed_char.report_ref_handle = BLE_GATT_HANDLE_INVALID;
+ p_gatts_c->srv_changed_char.user_desc_handle = BLE_GATT_HANDLE_INVALID;
+ }
+ }
+}
+
+
+void nrf_ble_gatts_c_on_ble_evt(ble_evt_t const * p_ble_evt,
+ void * p_context)
+{
+ nrf_ble_gatts_c_t * p_gatts_c;
+ p_gatts_c = p_context;
+
+ VERIFY_MODULE_INITIALIZED_VOID();
+ VERIFY_PARAM_NOT_NULL_VOID(p_gatts_c);
+ VERIFY_PARAM_NOT_NULL_VOID(p_ble_evt);
+
+ switch (p_ble_evt->header.evt_id)
+ {
+ case BLE_GAP_EVT_DISCONNECTED:
+ on_disconnect(p_gatts_c, p_ble_evt);
+ break;
+
+ case BLE_GATTC_EVT_HVX:
+ on_hvx(p_gatts_c, &(p_ble_evt->evt.gattc_evt));
+ break;
+
+ default:
+ break;
+ }
+}
+
+
+ret_code_t nrf_ble_gatts_c_handles_assign(nrf_ble_gatts_c_t * const p_gatts_c,
+ uint16_t const conn_handle,
+ ble_gatt_db_char_t const * const p_peer_handles)
+{
+ VERIFY_PARAM_NOT_NULL(p_gatts_c);
+ VERIFY_MODULE_INITIALIZED();
+
+ p_gatts_c->conn_handle = conn_handle;
+ if (p_peer_handles != NULL)
+ {
+ p_gatts_c->srv_changed_char.cccd_handle = p_peer_handles->cccd_handle;
+ p_gatts_c->srv_changed_char.ext_prop_handle = p_peer_handles->ext_prop_handle;
+ p_gatts_c->srv_changed_char.report_ref_handle = p_peer_handles->report_ref_handle;
+ p_gatts_c->srv_changed_char.user_desc_handle = p_peer_handles->user_desc_handle;
+ p_gatts_c->srv_changed_char.characteristic.handle_value = p_peer_handles->characteristic.handle_value;
+
+ }
+ return NRF_SUCCESS;
+}
+#endif // NRF_MODULE_ENABLED(BLE_GATTS_C)
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/experimental_gatts_c/nrf_ble_gatts_c.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/experimental_gatts_c/nrf_ble_gatts_c.h
new file mode 100644
index 0000000..fb488f0
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/experimental_gatts_c/nrf_ble_gatts_c.h
@@ -0,0 +1,229 @@
+/**
+ * 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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
+ *
+ * @defgroup nrf_ble_gatts_c GATT Service Client
+ * @{
+ * @ingroup ble_sdk_srv
+ * @brief GATT Service Client module.
+ *
+ * @details This module implements a client for the Generic Attribute Profile (GATT) Service.
+ * It subscribes to indications from the Service Changed Characteristic (0x2A05).
+ *
+ * @note The application must register this module as a BLE event observer using the
+ * NRF_SDH_BLE_OBSERVER macro. Example:
+ * @code
+ * ble_gatts_t instance;
+ * NRF_SDH_BLE_OBSERVER(anything, BLE_GATTS_BLE_OBSERVER_PRIO,
+ * nrf_ble_gatts_c_on_ble_evt, &instance);
+ * @endcode
+*/
+
+
+#ifndef NRF_BLE_GATTS_C_H__
+#define NRF_BLE_GATTS_C_H__
+
+#include <stdint.h>
+#include "ble_gattc.h"
+#include "ble.h"
+#include "nrf_error.h"
+#include "ble_srv_common.h"
+#include "ble_db_discovery.h"
+#include "sdk_errors.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**@brief Macro for defining a nrf_ble_gatts_c instance.
+ *
+ * @param _name Name of the instance.
+ * @hideinitializer
+ */
+#define NRF_BLE_GATTS_C_DEF(_name) \
+static nrf_ble_gatts_c_t _name; \
+NRF_SDH_BLE_OBSERVER(_name ## _obs, \
+ NRF_BLE_GATTS_C_BLE_OBSERVER_PRIO, \
+ nrf_ble_gatts_c_on_ble_evt, &_name)
+
+/** @brief Macro for defining multiple nrf_ble_gatts_c instances.
+ *
+ * @param _name Name of the array of instances.
+ * @param _cnt Number of instances to define.
+ * @hideinitializer
+ */
+#define NRF_BLE_GATTS_C_ARRAY_DEF(_name, _cnt) \
+static nrf_ble_gatts_c_t _name[_cnt]; \
+NRF_SDH_BLE_OBSERVERS(_name ## _obs, \
+ NRF_BLE_GATTS_C_BLE_OBSERVER_PRIO, \
+ nrf_ble_gatts_c_on_ble_evt, &_name, _cnt)
+
+/**@brief Type of the GATT Service client event. */
+typedef enum
+{
+ NRF_BLE_GATTS_C_EVT_DISCOVERY_COMPLETE, /**< Event indicating that the GATT Service and Service Changed Characteristic have been found on the peer. */
+ NRF_BLE_GATTS_C_EVT_DISCOVERY_FAILED, /**< Event indicating that the Service Changed characteristic has not been found on the peer. */
+ NRF_BLE_GATTS_C_EVT_DISCONN_COMPLETE, /**< Event indicating that the GATT Service client module has finished processing the BLE_GAP_EVT_DISCONNECTED event. The event can be used by the application to do cleanup related to the GATT Service client.*/
+ NRF_BLE_GATTS_C_EVT_SRV_CHANGED, /**< Event indicating that a Service Changed indication has been received. */
+} nrf_ble_gatts_c_evt_type_t;
+
+/**@brief Structure containing the event from the Service Changed client module to the application.
+ */
+typedef struct
+{
+ nrf_ble_gatts_c_evt_type_t evt_type; /**< Type of event. See @ref nrf_ble_gatts_c_evt_type_t. */
+ uint16_t conn_handle; /**< Handle of the connection for which this event has occurred. */
+ union
+ {
+ ble_gatt_db_char_t srv_changed_char; /**< Handles for the Service Changed characteristic. Will be filled if the event type is @ref NRF_BLE_GATTS_C_EVT_DISCOVERY_COMPLETE. */
+ ble_gattc_handle_range_t handle_range; /**< The affected attribute handle range where the service has changed. Will be provided if the event type is @ref NRF_BLE_GATTS_C_EVT_SRV_CHANGED.*/
+ } params;
+} nrf_ble_gatts_c_evt_t;
+
+/**@brief Service Changed handler type. */
+typedef void (* nrf_ble_gatts_c_evt_handler_t)(nrf_ble_gatts_c_evt_t * p_evt);
+
+/**@brief Structure for holding the information related to the Service Changed indication at the server.
+ *
+ * @details A GATT Server will never have more than one instance of the Service Changed Characteristic.
+ * Therefore, you never need more than one instance of the GATT Service client structure.
+ *
+ * @warning This structure must be zero-initialized.
+ */
+typedef struct
+{
+ bool initialized; /**< Boolean indicating whether the context has been initialized or not. */
+ bool char_found; /**< Boolean indicating whether the Service Changed indication has been found.*/
+ ble_gatt_db_char_t srv_changed_char; /**< Information of the Service Changed characteristics. */
+ uint16_t conn_handle; /**< Active connection handle. */
+ nrf_ble_gatts_c_evt_handler_t evt_handler; /**< Pointer to event handler function. */
+ ble_srv_error_handler_t err_handler; /**< Pointer to error handler function. */
+} nrf_ble_gatts_c_t;
+
+/**@brief Initialization parameters. These must be supplied when calling @ref nrf_ble_gatts_c_init. */
+typedef struct
+{
+ nrf_ble_gatts_c_evt_handler_t evt_handler; /**< Event handler that is called by the Service Changed client module when any related event occurs. */
+ ble_srv_error_handler_t err_handler; /**< Error handler that is called by the Service Changed client module if any error occurs. */
+} nrf_ble_gatts_c_init_t;
+
+
+/**@brief Function for initializing the Service Changed client module.
+ *
+ * @param[in,out] p_gatts_c Pointer to the GATT Service client structure instance.
+ * @param[in] p_gatts_c_init Init parameters containing the event handler that is called by
+ * the Service Changed client module when any related event occurs.
+ *
+ * @retval NRF_SUCCESS If the service was initialized successfully.
+ * @retval NRF_ERROR_NULL If any of the input parameters are NULL.
+ * @return If functions from other modules return errors to this function,
+ * the @ref nrf_error are propagated.
+ */
+ret_code_t nrf_ble_gatts_c_init(nrf_ble_gatts_c_t * p_gatts_c,
+ nrf_ble_gatts_c_init_t * p_gatts_c_init);
+
+
+/**@brief Function for enabling remote indication.
+ *
+ * @param[in,out] p_gatts_c Pointer to the Service Changed client structure.
+ * @param[in] enable True to enable Service Changed remote indication, false to disable.
+ *
+ * @retval NRF_SUCCESS Operation success.
+ * @return If functions from other modules return errors to this function,
+ * the @ref nrf_error are propagated.
+ */
+ret_code_t nrf_ble_gatts_c_enable_indication(nrf_ble_gatts_c_t * p_gatts_c,
+ bool enable);
+
+
+/**@brief Function for handling events from the database discovery module.
+ *
+ * @details This function handles an event from the database discovery module, and determine
+ * if it relates to the discovery of Service Changed characteristics at the peer. If so,
+ * it will call the application's event handler indicating that Service Changed
+ * characteristic has been discovered at the peer.
+ *
+ * @param[in,out] p_gatts_c Pointer to the GATT Service client structure instance.
+ * @param[in] p_evt Pointer to the event received from the database discovery module.
+ */
+void nrf_ble_gatts_c_on_db_disc_evt(nrf_ble_gatts_c_t const * p_gatts_c,
+ ble_db_discovery_evt_t * p_evt);
+
+
+/**@brief Function for handling BLE events.
+ *
+ * @param[in] p_ble_evt Event received from the BLE stack.
+ * @param[in] p_context Context.
+ */
+void nrf_ble_gatts_c_on_ble_evt(ble_evt_t const * p_ble_evt,
+ void * p_context);
+
+
+/**@brief Function for assigning handles to a GATT Service client instance.
+ *
+ * @details Call this function when a link has been established with a peer to
+ * associate this link to an instance of the module. This makes it
+ * possible to handle several links and associate each link with a particular
+ * instance of the GATT Service client module. The connection handle and attribute
+ * handles will be provided from the discovery event
+ * @ref NRF_BLE_GATTS_C_EVT_DISCOVERY_COMPLETE.
+ *
+ * @param[in,out] p_gatts_c Pointer to the GATT Service client structure instance to
+ * associate with the handles.
+ * @param[in] conn_handle Connection handle to be associated with the given
+ * GATT Service client Instance.
+ * @param[in] p_peer_handles Attribute handles on the GATT Service server that you want this
+ * GATT Service client to interact with.
+ *
+ * @retval NRF_SUCCESS If the connection handle was successfully stored in the GATT Service instance.
+ * @retval NRF_ERROR_NULL If any of the input parameters are NULL.
+ */
+ret_code_t nrf_ble_gatts_c_handles_assign(nrf_ble_gatts_c_t * p_gatts_c,
+ uint16_t conn_handle,
+ ble_gatt_db_char_t const * p_peer_handles);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // NRF_BLE_GATTS_C_H__
+
+/** @} */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/experimental_nrf_ble_cgms/cgms_db.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/experimental_nrf_ble_cgms/cgms_db.c
new file mode 100644
index 0000000..e5f6240
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/experimental_nrf_ble_cgms/cgms_db.c
@@ -0,0 +1,143 @@
+/**
+ * Copyright (c) 2016 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#include <stdbool.h>
+#include <stdint.h>
+#include "cgms_db.h"
+
+typedef struct
+{
+ bool in_use_flag;
+ ble_cgms_rec_t record;
+} database_entry_t;
+
+static database_entry_t m_database[CGMS_DB_MAX_RECORDS];
+static uint8_t m_database_crossref[CGMS_DB_MAX_RECORDS];
+static uint16_t m_num_records;
+
+
+ret_code_t cgms_db_init(void)
+{
+ int i;
+
+ for (i = 0; i < CGMS_DB_MAX_RECORDS; i++)
+ {
+ m_database[i].in_use_flag = false;
+ m_database_crossref[i] = 0xFF;
+ }
+
+ m_num_records = 0;
+
+ return NRF_SUCCESS;
+}
+
+
+uint16_t cgms_db_num_records_get(void)
+{
+ return m_num_records;
+}
+
+
+ret_code_t cgms_db_record_get(uint8_t record_num, ble_cgms_rec_t * p_rec)
+{
+ if ((record_num >= m_num_records) || (m_num_records == 0))
+ {
+ return NRF_ERROR_NOT_FOUND;
+ }
+ // copy record to the specified memory
+ *p_rec = m_database[m_database_crossref[record_num]].record;
+
+ return NRF_SUCCESS;
+}
+
+
+ret_code_t cgms_db_record_add(ble_cgms_rec_t * p_rec)
+{
+ int i;
+
+ if (m_num_records == CGMS_DB_MAX_RECORDS)
+ {
+ return NRF_ERROR_NO_MEM;
+ }
+
+ // find next available database entry
+ for (i = 0; i < CGMS_DB_MAX_RECORDS; i++)
+ {
+ if (!m_database[i].in_use_flag)
+ {
+ m_database[i].in_use_flag = true;
+ m_database[i].record = *p_rec;
+
+ m_database_crossref[m_num_records] = i;
+ m_num_records++;
+
+ return NRF_SUCCESS;
+ }
+ }
+
+ return NRF_ERROR_NO_MEM;
+}
+
+
+ret_code_t cgms_db_record_delete(uint8_t record_num)
+{
+ int i;
+
+ if (record_num >= m_num_records)
+ {
+ // Deleting a non-existent record is not an error
+ return NRF_SUCCESS;
+ }
+
+ // free entry
+ m_database[m_database_crossref[record_num]].in_use_flag = false;
+
+ // decrease number of records
+ m_num_records--;
+
+ // remove cross reference index
+ for (i = record_num; i < m_num_records; i++)
+ {
+ m_database_crossref[i] = m_database_crossref[i + 1];
+ }
+
+ return NRF_SUCCESS;
+}
+
+
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/experimental_nrf_ble_cgms/cgms_db.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/experimental_nrf_ble_cgms/cgms_db.h
new file mode 100644
index 0000000..6928057
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/experimental_nrf_ble_cgms/cgms_db.h
@@ -0,0 +1,118 @@
+/**
+ * Copyright (c) 2012 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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
+ *
+ * @defgroup ble_sdk_srv_cgms_db Continuous Glucose Monitoring Service database
+ * @{
+ * @ingroup ble_cgms
+ *
+ * @brief Continuous Glucose Monitoring Service database module.
+ *
+ * @details This module implements a database of stored glucose measurement values.
+ * This database is meant as an example of a database that the @ref ble_cgms can use.
+ * Replace this module if this implementation does not suit
+ * your application. Any replacement implementation should follow the API below to ensure
+ * that the qualification of the @ref ble_cgms is not compromised.
+ */
+
+#ifndef BLE_CGMS_DB_H__
+#define BLE_CGMS_DB_H__
+
+#include "sdk_errors.h"
+#include "nrf_ble_cgms.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define CGMS_DB_MAX_RECORDS 100 // !< Number of records that can be stored in the database.
+
+
+/**@brief Function for initializing the glucose record database.
+ *
+ * @retval NRF_SUCCESS If the database was successfully initialized.
+ */
+ret_code_t cgms_db_init(void);
+
+
+/**@brief Function for getting the number of records in the database.
+ *
+ * @return The number of records in the database.
+ */
+uint16_t cgms_db_num_records_get(void);
+
+
+/**@brief Function for getting a specific record from the database.
+ *
+ * @param[in] record_num Index of the record to retrieve.
+ * @param[out] p_rec Pointer to the record structure to which the retrieved record is copied.
+ *
+ * @retval NRF_SUCCESS If the record was successfully retrieved.
+ */
+ret_code_t cgms_db_record_get(uint8_t record_num, ble_cgms_rec_t * p_rec);
+
+
+/**@brief Function for adding a record at the end of the database.
+ *
+ * @param[in] p_rec Pointer to the record to add to the database.
+ *
+ * @retval NRF_SUCCESS If the record was successfully added to the database.
+ */
+ret_code_t cgms_db_record_add(ble_cgms_rec_t * p_rec);
+
+
+/**@brief Function for deleting a database entry.
+ *
+ * @details This call deletes an record from the database.
+ *
+ * @param[in] record_num Index of the record to delete.
+ *
+ * @retval NRF_SUCCESS If the record was successfully deleted from the database.
+ */
+ret_code_t cgms_db_record_delete(uint8_t record_num);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // BLE_CGMS_DB_H__
+
+/** @} */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/experimental_nrf_ble_cgms/cgms_meas.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/experimental_nrf_ble_cgms/cgms_meas.c
new file mode 100644
index 0000000..50d6416
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/experimental_nrf_ble_cgms/cgms_meas.c
@@ -0,0 +1,248 @@
+/**
+ * Copyright (c) 2016 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#include <stdint.h>
+#include <string.h>
+#include "ble.h"
+#include "sdk_macros.h"
+#include "ble_srv_common.h"
+#include "nrf_ble_cgms.h"
+#include "cgms_meas.h"
+#include "cgms_db.h"
+
+/**@brief Function for encoding a Glucose measurement.
+ *
+ * @param[in] p_meas Measurement to be encoded.
+ * @param[out] p_encoded_buffer Pointer to buffer where the encoded measurement is to be stored.
+ *
+ * @return Size of encoded measurement.
+ */
+static uint8_t cgms_meas_encode(nrf_ble_cgms_t * p_cgms,
+ const nrf_ble_cgms_meas_t * p_meas,
+ uint8_t * p_encoded_buffer)
+{
+ uint8_t len = 2;
+
+ uint8_t flags = p_meas->flags;
+
+ len += uint16_encode(p_meas->glucose_concentration,
+ &p_encoded_buffer[len]);
+ len += uint16_encode(p_meas->time_offset,
+ &p_encoded_buffer[len]);
+
+ if (p_meas->sensor_status_annunciation.warning != 0)
+ {
+ p_encoded_buffer[len++] = p_meas->sensor_status_annunciation.warning;
+ flags |= NRF_BLE_CGMS_STATUS_FLAGS_WARNING_OCT_PRESENT;
+ }
+
+ if (p_meas->sensor_status_annunciation.calib_temp != 0)
+ {
+ p_encoded_buffer[len++] = p_meas->sensor_status_annunciation.calib_temp;
+ flags |= NRF_BLE_CGMS_STATUS_FLAGS_CALTEMP_OCT_PRESENT;
+ }
+
+ if (p_meas->sensor_status_annunciation.status != 0)
+ {
+ p_encoded_buffer[len++] = p_meas->sensor_status_annunciation.status;
+ flags |= NRF_BLE_CGMS_STATUS_FLAGS_STATUS_OCT_PRESENT;
+ }
+
+ // Trend field
+ if (p_cgms->feature.feature & NRF_BLE_CGMS_FEAT_CGM_TREND_INFORMATION_SUPPORTED)
+ {
+ if (flags & NRF_BLE_CGMS_FLAG_TREND_INFO_PRESENT)
+ {
+ len += uint16_encode(p_meas->trend, &p_encoded_buffer[len]);
+ }
+ }
+
+ // Quality field
+ if (p_cgms->feature.feature & NRF_BLE_CGMS_FEAT_CGM_QUALITY_SUPPORTED)
+ {
+ if (flags & NRF_BLE_CGMS_FLAGS_QUALITY_PRESENT)
+ {
+ len += uint16_encode(p_meas->quality, &p_encoded_buffer[len]);
+ }
+ }
+
+ p_encoded_buffer[1] = flags;
+ p_encoded_buffer[0] = len;
+ return len;
+}
+
+
+/**@brief Function for adding a characteristic for the Continuous Glucose Meter Measurement.
+ *
+ * @param[in] p_cgms Service instance.
+ *
+ * @return NRF_SUCCESS if characteristic was successfully added, otherwise an error code.
+ */
+ret_code_t cgms_meas_char_add(nrf_ble_cgms_t * p_cgms)
+{
+ uint8_t num_recs;
+ uint8_t encoded_cgms_meas[NRF_BLE_CGMS_MEAS_LEN_MAX];
+ ble_add_char_params_t add_char_params;
+ ble_cgms_rec_t initial_cgms_rec_value;
+
+ memset(&add_char_params, 0, sizeof(add_char_params));
+ memset(&initial_cgms_rec_value, 0, sizeof(ble_cgms_rec_t));
+
+ num_recs = cgms_db_num_records_get();
+ if (num_recs > 0)
+ {
+ uint32_t err_code = cgms_db_record_get(num_recs - 1, &initial_cgms_rec_value);
+ if (err_code != NRF_SUCCESS)
+ {
+ return err_code;
+ }
+ }
+
+ add_char_params.uuid = BLE_UUID_CGM_MEASUREMENT;
+ add_char_params.max_len = NRF_BLE_CGMS_MEAS_LEN_MAX;
+ add_char_params.init_len = cgms_meas_encode(p_cgms,
+ &initial_cgms_rec_value.meas,
+ encoded_cgms_meas);
+ add_char_params.p_init_value = encoded_cgms_meas;
+ add_char_params.is_var_len = true;
+ add_char_params.char_props.notify = true;
+ add_char_params.cccd_write_access = SEC_JUST_WORKS;
+
+
+ return characteristic_add(p_cgms->service_handle,
+ &add_char_params,
+ &p_cgms->char_handles.measurment);
+}
+
+
+ret_code_t cgms_meas_send(nrf_ble_cgms_t * p_cgms, ble_cgms_rec_t * p_rec, uint8_t * p_count)
+{
+
+ uint32_t err_code;
+ uint8_t encoded_meas[NRF_BLE_CGMS_MEAS_LEN_MAX + NRF_BLE_CGMS_MEAS_REC_LEN_MAX];
+ uint16_t len = 0;
+ uint16_t hvx_len = NRF_BLE_CGMS_MEAS_LEN_MAX;
+ int i;
+ ble_gatts_hvx_params_t hvx_params;
+
+ for (i = 0; i < *p_count; i++)
+ {
+ uint8_t meas_len = cgms_meas_encode(p_cgms, &(p_rec[i].meas), (encoded_meas + len));
+ if (len + meas_len >= NRF_BLE_CGMS_MEAS_LEN_MAX)
+ {
+ break;
+ }
+ len += meas_len;
+ }
+ *p_count = i;
+ hvx_len = len;
+
+ memset(&hvx_params, 0, sizeof(hvx_params));
+
+ hvx_params.handle = p_cgms->char_handles.measurment.value_handle;
+ hvx_params.type = BLE_GATT_HVX_NOTIFICATION;
+ hvx_params.offset = 0;
+ hvx_params.p_len = &hvx_len;
+ hvx_params.p_data = encoded_meas;
+
+ err_code = sd_ble_gatts_hvx(p_cgms->conn_handle, &hvx_params);
+ if (err_code == NRF_SUCCESS)
+ {
+ if (hvx_len != len)
+ {
+ err_code = NRF_ERROR_DATA_SIZE;
+ }
+ else
+ {
+ // Measurement successfully sent
+ p_cgms->racp_data.racp_proc_records_reported += *p_count;
+ p_cgms->racp_data.racp_proc_records_reported_since_txcomplete++;
+ }
+ }
+
+ return err_code;
+}
+
+
+/**@brief Function for handling the Glucose measurement CCCD write event.
+ *
+ * @param[in] p_cgms Service instance.
+ * @param[in] p_evt_write WRITE event to be handled.
+ */
+static void on_meas_cccd_write(nrf_ble_cgms_t * p_cgms, ble_gatts_evt_write_t const * p_evt_write)
+{
+ if (p_evt_write->len == 2)
+ {
+ // CCCD written, update notification state
+ if (p_cgms->evt_handler != NULL)
+ {
+ nrf_ble_cgms_evt_t evt;
+
+ if (ble_srv_is_notification_enabled(p_evt_write->data))
+ {
+ evt.evt_type = NRF_BLE_CGMS_EVT_NOTIFICATION_ENABLED;
+ }
+ else
+ {
+ evt.evt_type = NRF_BLE_CGMS_EVT_NOTIFICATION_DISABLED;
+ }
+
+ p_cgms->evt_handler(p_cgms, &evt);
+ }
+ }
+}
+
+
+/**@brief Function for handling the WRITE event.
+ *
+ * @details Handles WRITE events from the BLE stack.
+ *
+ * @param[in] p_cgms Glucose Service structure.
+ * @param[in] p_ble_evt Event received from the BLE stack.
+ */
+void cgms_meas_on_write(nrf_ble_cgms_t * p_cgms, ble_gatts_evt_write_t const * p_evt_write)
+{
+
+ if (p_evt_write->handle == p_cgms->char_handles.measurment.cccd_handle)
+ {
+ on_meas_cccd_write(p_cgms, p_evt_write);
+ }
+}
+
+
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/experimental_nrf_ble_cgms/cgms_meas.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/experimental_nrf_ble_cgms/cgms_meas.h
new file mode 100644
index 0000000..d56c704
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/experimental_nrf_ble_cgms/cgms_meas.h
@@ -0,0 +1,103 @@
+/**
+ * Copyright (c) 2016 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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
+ *
+ * @defgroup ble_sdk_srv_cgms_meas Continuous Glucose Monitoring Service Measurement
+ * @{
+ * @ingroup ble_cgms
+ * @brief Continuous Glucose Monitoring Service Measurement module.
+ *
+ * @details This module implements parts of the Continuous Glucose Monitoring that relate to the
+ * Measurement characteristic. Events are propagated to this module from @ref ble_cgms
+ * using @ref cgms_meas_on_write.
+ *
+ */
+
+
+#ifndef NRF_BLE_CGMS_MEAS_H__
+#define NRF_BLE_CGMS_MEAS_H__
+
+#include "ble.h"
+#include "ble_srv_common.h"
+#include "sdk_errors.h"
+#include "nrf_ble_cgms.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+/**@brief Function for adding a characteristic for the Continuous Glucose Monitoring Measurement.
+ *
+ * @param[in] p_cgms Instance of the CGM Service.
+ *
+ * @retval NRF_SUCCESS If the characteristic was successfully added.
+ * @return If functions from other modules return errors to this function,
+ * the @ref nrf_error are propagated.
+ */
+ret_code_t cgms_meas_char_add(nrf_ble_cgms_t * p_cgms);
+
+/**@brief Function for sending a CGM Measurement.
+ *
+ * @param[in] p_cgms Instance of the CGM Service.
+ * @param[in] p_rec Measurement to be sent.
+ * @param[in] count Number of measurements to encode.
+ *
+ * @retval NRF_SUCCESS If the measurement was successfully sent.
+ * @return If functions from other modules return errors to this function,
+ * the @ref nrf_error are propagated.
+ */
+ret_code_t cgms_meas_send(nrf_ble_cgms_t * p_cgms, ble_cgms_rec_t * p_rec, uint8_t * count);
+
+
+/**@brief Function for handling the @ref BLE_GATTS_EVT_WRITE event from the BLE stack.
+ *
+ * @param[in] p_cgms Instance of the CGM Service.
+ * @param[in] p_evt_write Event received from the BLE stack.
+ */
+void cgms_meas_on_write(nrf_ble_cgms_t * p_cgms, ble_gatts_evt_write_t const * p_evt_write);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // NRF_BLE_CGMS_MEAS_H__
+
+/** @} */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/experimental_nrf_ble_cgms/cgms_racp.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/experimental_nrf_ble_cgms/cgms_racp.c
new file mode 100644
index 0000000..0327383
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/experimental_nrf_ble_cgms/cgms_racp.c
@@ -0,0 +1,866 @@
+/**
+ * Copyright (c) 2016 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#include <stdint.h>
+#include <string.h>
+#include "ble.h"
+#include "ble_srv_common.h"
+#include "cgms_racp.h"
+#include "cgms_db.h"
+#include "cgms_meas.h"
+
+#define OPERAND_LESS_GREATER_FILTER_TYPE_SIZE 1 // !< 1 byte.
+#define OPERAND_LESS_GREATER_FILTER_PARAM_SIZE 2 // !< 2 bytes.
+#define OPERAND_LESS_GREATER_SIZE OPERAND_LESS_GREATER_FILTER_TYPE_SIZE \
+ + OPERAND_LESS_GREATER_FILTER_PARAM_SIZE // !< Total size of the operand.
+
+/**@brief Function for adding a characteristic for the Record Access Control Point.
+ *
+ * @param[in] p_cgms Service instance.
+ *
+ * @return NRF_SUCCESS if characteristic was successfully added, otherwise an error code.
+ */
+ret_code_t cgms_racp_char_add(nrf_ble_cgms_t * p_cgms)
+{
+ ble_add_char_params_t add_char_params;
+
+ memset(&add_char_params, 0, sizeof(add_char_params));
+
+ add_char_params.uuid = BLE_UUID_RECORD_ACCESS_CONTROL_POINT_CHAR;
+ add_char_params.max_len = BLE_GATT_ATT_MTU_DEFAULT;
+ add_char_params.init_len = 0;
+ add_char_params.p_init_value = 0;
+ add_char_params.is_var_len = true;
+ add_char_params.write_access = SEC_JUST_WORKS;
+ add_char_params.char_props.write = true;
+ add_char_params.char_props.indicate = true;
+ add_char_params.cccd_write_access = SEC_JUST_WORKS;
+ add_char_params.is_defered_write = 1;
+
+ return characteristic_add(p_cgms->service_handle,
+ &add_char_params,
+ &p_cgms->char_handles.racp);
+}
+
+
+/**@brief Function for sending response from Specific Operation Control Point.
+ *
+ * @param[in] p_cgms Service instance.
+ * @param[in] p_racp_val RACP value to be sent.
+ */
+static void racp_send(nrf_ble_cgms_t * p_cgms, ble_racp_value_t * p_racp_val)
+{
+ uint32_t err_code;
+ uint8_t encoded_resp[25];
+ uint8_t len;
+ uint16_t hvx_len;
+ ble_gatts_hvx_params_t hvx_params;
+
+ if (
+ (p_cgms->cgms_com_state != STATE_RACP_RESPONSE_PENDING)
+ &&
+ (p_cgms->racp_data.racp_proc_records_reported_since_txcomplete > 0)
+ )
+ {
+ p_cgms->cgms_com_state = STATE_RACP_RESPONSE_PENDING;
+ return;
+ }
+
+ // Send indication
+ len = ble_racp_encode(p_racp_val, encoded_resp);
+ hvx_len = len;
+
+ memset(&hvx_params, 0, sizeof(hvx_params));
+
+ hvx_params.handle = p_cgms->char_handles.racp.value_handle;
+ hvx_params.type = BLE_GATT_HVX_INDICATION;
+ hvx_params.offset = 0;
+ hvx_params.p_len = &hvx_len;
+ hvx_params.p_data = encoded_resp;
+
+ err_code = sd_ble_gatts_hvx(p_cgms->conn_handle, &hvx_params);
+
+ // Error handling
+ if ((err_code == NRF_SUCCESS) && (hvx_len != len))
+ {
+ err_code = NRF_ERROR_DATA_SIZE;
+ }
+
+ switch (err_code)
+ {
+ case NRF_SUCCESS:
+ // Wait for HVC event.
+ p_cgms->cgms_com_state = STATE_RACP_RESPONSE_IND_VERIF;
+ break;
+
+ case NRF_ERROR_RESOURCES:
+ // Wait for TX_COMPLETE event to retry transmission.
+ p_cgms->cgms_com_state = STATE_RACP_RESPONSE_PENDING;
+ break;
+
+ case NRF_ERROR_INVALID_STATE:
+ // Make sure state machine returns to the default state.
+ p_cgms->cgms_com_state = STATE_NO_COMM;
+ break;
+
+ default:
+ // Report error to application.
+ if (p_cgms->error_handler != NULL)
+ {
+ p_cgms->error_handler(err_code);
+ }
+
+ // Make sure state machine returns to the default state.
+ p_cgms->cgms_com_state = STATE_NO_COMM;
+ break;
+ }
+}
+
+
+/**@brief Function for sending a RACP response containing a Response Code Op Code and Response Code Value.
+ *
+ * @param[in] p_cgms Service instance.
+ * @param[in] opcode RACP Op Code.
+ * @param[in] value RACP Response Code Value.
+ */
+static void racp_response_code_send(nrf_ble_cgms_t * p_cgms, uint8_t opcode, uint8_t value)
+{
+ p_cgms->racp_data.pending_racp_response.opcode = RACP_OPCODE_RESPONSE_CODE;
+ p_cgms->racp_data.pending_racp_response.operator = RACP_OPERATOR_NULL;
+ p_cgms->racp_data.pending_racp_response.operand_len = 2;
+ p_cgms->racp_data.pending_racp_response.p_operand =
+ p_cgms->racp_data.pending_racp_response_operand;
+
+ p_cgms->racp_data.pending_racp_response_operand[0] = opcode;
+ p_cgms->racp_data.pending_racp_response_operand[1] = value;
+
+ racp_send(p_cgms, &p_cgms->racp_data.pending_racp_response);
+}
+
+
+/**@brief Function for responding to the ALL operation.
+ *
+ * @param[in] p_cgms Service instance.
+ *
+ * @return NRF_SUCCESS on success, otherwise an error code.
+ */
+static uint32_t racp_report_records_all(nrf_ble_cgms_t * p_cgms)
+{
+ uint16_t total_records = cgms_db_num_records_get();
+ uint16_t cur_nb_rec;
+ uint8_t i;
+ uint8_t nb_rec_to_send;
+
+ if (p_cgms->racp_data.racp_proc_record_ndx >= total_records)
+ {
+ p_cgms->cgms_com_state = STATE_NO_COMM;
+ }
+ else
+ {
+ uint32_t err_code;
+ ble_cgms_rec_t rec[NRF_BLE_CGMS_MEAS_REC_PER_NOTIF_MAX];
+
+ cur_nb_rec = total_records - p_cgms->racp_data.racp_proc_record_ndx;
+ if (cur_nb_rec > NRF_BLE_CGMS_MEAS_REC_PER_NOTIF_MAX)
+ {
+ cur_nb_rec = NRF_BLE_CGMS_MEAS_REC_PER_NOTIF_MAX;
+ }
+ nb_rec_to_send = (uint8_t)cur_nb_rec;
+
+ for (i = 0; i < cur_nb_rec; i++)
+ {
+ err_code = cgms_db_record_get(p_cgms->racp_data.racp_proc_record_ndx + i, &(rec[i]));
+ if (err_code != NRF_SUCCESS)
+ {
+ return err_code;
+ }
+ }
+ err_code = cgms_meas_send(p_cgms, rec, &nb_rec_to_send);
+ if (err_code != NRF_SUCCESS)
+ {
+ return err_code;
+ }
+ p_cgms->racp_data.racp_proc_record_ndx += nb_rec_to_send;
+ }
+
+ return NRF_SUCCESS;
+}
+
+
+/**@brief Function for responding to the FIRST or the LAST operation.
+ *
+ * @param[in] p_cgms Service instance.
+ *
+ * @return NRF_SUCCESS on success, otherwise an error code.
+ */
+static uint32_t racp_report_records_first_last(nrf_ble_cgms_t * p_cgms)
+{
+ uint32_t err_code;
+ ble_cgms_rec_t rec;
+ uint16_t total_records;
+ uint8_t nb_rec_to_send = 1;
+
+ total_records = cgms_db_num_records_get();
+
+ if ((p_cgms->racp_data.racp_proc_records_reported != 0) || (total_records == 0))
+ {
+ p_cgms->cgms_com_state = STATE_NO_COMM;
+ }
+ else
+ {
+ if (p_cgms->racp_data.racp_proc_operator == RACP_OPERATOR_FIRST)
+ {
+ err_code = cgms_db_record_get(0, &rec);
+ if (err_code != NRF_SUCCESS)
+ {
+ return err_code;
+ }
+ }
+ else if (p_cgms->racp_data.racp_proc_operator == RACP_OPERATOR_LAST)
+ {
+ err_code = cgms_db_record_get(total_records - 1, &rec);
+ if (err_code != NRF_SUCCESS)
+ {
+ return err_code;
+ }
+ }
+
+ err_code = cgms_meas_send(p_cgms, &rec, &nb_rec_to_send);
+ if (err_code != NRF_SUCCESS)
+ {
+ return err_code;
+ }
+ p_cgms->racp_data.racp_proc_record_ndx++;
+ }
+
+ return NRF_SUCCESS;
+}
+
+
+/**@brief Function for responding to the LESS OR EQUAL operation.
+ *
+ * @param[in] p_cgms Service instance.
+ *
+ * @return NRF_SUCCESS on success, otherwise an error code.
+ */
+static ret_code_t racp_report_records_less_equal(nrf_ble_cgms_t * p_cgms)
+{
+ uint16_t total_rec_nb_to_send;
+ uint16_t rec_nb_left_to_send;
+ uint8_t nb_rec_to_send;
+ uint16_t i;
+
+ total_rec_nb_to_send = p_cgms->racp_data.racp_proc_records_ndx_last_to_send +1;
+
+ if (p_cgms->racp_data.racp_proc_record_ndx >= total_rec_nb_to_send)
+ {
+ p_cgms->cgms_com_state = STATE_NO_COMM;
+ }
+ else
+ {
+ ret_code_t err_code;
+ ble_cgms_rec_t rec[NRF_BLE_CGMS_MEAS_REC_PER_NOTIF_MAX];
+
+ rec_nb_left_to_send = total_rec_nb_to_send - p_cgms->racp_data.racp_proc_records_reported;
+
+ if (rec_nb_left_to_send > NRF_BLE_CGMS_MEAS_REC_PER_NOTIF_MAX)
+ {
+ nb_rec_to_send = NRF_BLE_CGMS_MEAS_REC_PER_NOTIF_MAX;
+ }
+ else
+ {
+ nb_rec_to_send = (uint8_t)rec_nb_left_to_send;
+ }
+
+ for (i = 0; i < nb_rec_to_send; i++)
+ {
+ err_code = cgms_db_record_get(p_cgms->racp_data.racp_proc_record_ndx + i, &(rec[i]));
+ if (err_code != NRF_SUCCESS)
+ {
+ return err_code;
+ }
+ }
+ err_code = cgms_meas_send(p_cgms, rec, &nb_rec_to_send);
+ if (err_code != NRF_SUCCESS)
+ {
+ return err_code;
+ }
+ p_cgms->racp_data.racp_proc_record_ndx += nb_rec_to_send;
+ }
+
+ return NRF_SUCCESS;
+}
+
+
+/**@brief Function for responding to the GREATER OR EQUAL operation.
+ *
+ * @param[in] p_cgms Service instance.
+ *
+ * @return NRF_SUCCESS on success, otherwise an error code.
+ */
+static ret_code_t racp_report_records_greater_equal(nrf_ble_cgms_t * p_cgms)
+{
+ ret_code_t err_code;
+ uint16_t total_rec_nb = cgms_db_num_records_get();
+ uint16_t rec_nb_left_to_send;
+ uint8_t nb_rec_to_send;
+ uint16_t i;
+
+
+ total_rec_nb = cgms_db_num_records_get();
+ if (p_cgms->racp_data.racp_proc_record_ndx >= total_rec_nb)
+ {
+ p_cgms->cgms_com_state = STATE_NO_COMM;
+ return NRF_SUCCESS;
+ }
+
+ ble_cgms_rec_t rec[NRF_BLE_CGMS_MEAS_REC_PER_NOTIF_MAX];
+
+ rec_nb_left_to_send = total_rec_nb - p_cgms->racp_data.racp_proc_record_ndx;
+ if (rec_nb_left_to_send > NRF_BLE_CGMS_MEAS_REC_PER_NOTIF_MAX)
+ {
+ nb_rec_to_send = NRF_BLE_CGMS_MEAS_REC_PER_NOTIF_MAX;
+ }
+ else
+ {
+ nb_rec_to_send = (uint8_t)rec_nb_left_to_send;
+ }
+
+ for (i = 0; i < nb_rec_to_send; i++)
+ {
+ err_code = cgms_db_record_get(p_cgms->racp_data.racp_proc_record_ndx + i, &(rec[i]));
+ if (err_code != NRF_SUCCESS)
+ {
+ return err_code;
+ }
+ }
+ err_code = cgms_meas_send(p_cgms, rec, &nb_rec_to_send);
+ if (err_code != NRF_SUCCESS)
+ {
+ return err_code;
+ }
+ p_cgms->racp_data.racp_proc_record_ndx += nb_rec_to_send;
+
+ return NRF_SUCCESS;
+}
+
+
+/**@brief Function for informing that the REPORT RECORDS procedure is completed.
+ *
+ * @param[in] p_cgms Service instance.
+ */
+static void racp_report_records_completed(nrf_ble_cgms_t * p_cgms)
+{
+ uint8_t resp_code_value;
+
+ if (p_cgms->racp_data.racp_proc_records_reported > 0)
+ {
+ resp_code_value = RACP_RESPONSE_SUCCESS;
+ }
+ else
+ {
+ resp_code_value = RACP_RESPONSE_NO_RECORDS_FOUND;
+ }
+
+ racp_response_code_send(p_cgms, RACP_OPCODE_REPORT_RECS, resp_code_value);
+}
+
+
+/**@brief Function for the RACP report records procedure.
+ *
+ * @param[in] p_cgms Service instance.
+ */
+static void racp_report_records_procedure(nrf_ble_cgms_t * p_cgms)
+{
+ ret_code_t err_code = NRF_SUCCESS;
+
+ while (p_cgms->cgms_com_state == STATE_RACP_PROC_ACTIVE)
+ {
+ // Execute requested procedure
+ switch (p_cgms->racp_data.racp_proc_operator)
+ {
+ case RACP_OPERATOR_ALL:
+ err_code = racp_report_records_all(p_cgms);
+ break;
+
+ case RACP_OPERATOR_FIRST:
+ // Fall through.
+ case RACP_OPERATOR_LAST:
+ err_code = racp_report_records_first_last(p_cgms);
+ break;
+ case RACP_OPERATOR_GREATER_OR_EQUAL:
+ err_code = racp_report_records_greater_equal(p_cgms);
+ break;
+ case RACP_OPERATOR_LESS_OR_EQUAL:
+ err_code = racp_report_records_less_equal(p_cgms);
+ break;
+ default:
+ // Report error to application
+ if (p_cgms->error_handler != NULL)
+ {
+ p_cgms->error_handler(NRF_ERROR_INTERNAL);
+ }
+
+ // Make sure state machine returns to the default state
+ // state_set(STATE_NO_COMM);
+ p_cgms->cgms_com_state = STATE_NO_COMM;
+ return;
+ }
+
+ // Error handling
+ switch (err_code)
+ {
+ case NRF_SUCCESS:
+ if (p_cgms->cgms_com_state != STATE_RACP_PROC_ACTIVE)
+ {
+ racp_report_records_completed(p_cgms);
+ }
+ break;
+
+ case NRF_ERROR_RESOURCES:
+ // Wait for TX_COMPLETE event to resume transmission.
+ return;
+
+ case NRF_ERROR_INVALID_STATE:
+ // Notification is probably not enabled. Ignore request.
+ p_cgms->cgms_com_state = STATE_NO_COMM;
+ return;
+
+ default:
+ // Report error to application.
+ if (p_cgms->error_handler != NULL)
+ {
+ p_cgms->error_handler(err_code);
+ }
+
+ // Make sure state machine returns to the default state.
+ p_cgms->cgms_com_state = STATE_NO_COMM;
+ return;
+ }
+ }
+}
+
+
+/**@brief Function for testing if the received request is to be executed.
+ *
+ * @param[in] p_racp_request Request to be checked.
+ * @param[out] p_response_code Response code to be sent in case the request is rejected.
+ * RACP_RESPONSE_RESERVED is returned if the received message is
+ * to be rejected without sending a respone.
+ *
+ * @return TRUE if the request is to be executed, FALSE if it is to be rejected.
+ * If it is to be rejected, p_response_code will contain the response code to be
+ * returned to the central.
+ */
+static bool is_request_to_be_executed(nrf_ble_cgms_t * p_cgms,
+ const ble_racp_value_t * p_racp_request,
+ uint8_t * p_response_code)
+{
+ *p_response_code = RACP_RESPONSE_RESERVED;
+
+ if (p_racp_request->opcode == RACP_OPCODE_ABORT_OPERATION)
+ {
+ if (p_cgms->cgms_com_state == STATE_RACP_PROC_ACTIVE)
+ {
+ if (p_racp_request->operator != RACP_OPERATOR_NULL)
+ {
+ *p_response_code = RACP_RESPONSE_INVALID_OPERATOR;
+ }
+ else if (p_racp_request->operand_len != 0)
+ {
+ *p_response_code = RACP_RESPONSE_INVALID_OPERAND;
+ }
+ else
+ {
+ *p_response_code = RACP_RESPONSE_SUCCESS;
+ }
+ }
+ else
+ {
+ *p_response_code = RACP_RESPONSE_ABORT_FAILED;
+ }
+ }
+ else if (p_cgms->cgms_com_state != STATE_NO_COMM)
+ {
+ return false;
+ }
+ // Supported opcodes
+ else if ((p_racp_request->opcode == RACP_OPCODE_REPORT_RECS) ||
+ (p_racp_request->opcode == RACP_OPCODE_REPORT_NUM_RECS))
+ {
+ switch (p_racp_request->operator)
+ {
+ // Operators without a filter.
+ case RACP_OPERATOR_ALL:
+ // Fall through.
+ case RACP_OPERATOR_FIRST:
+ // Fall through.
+ case RACP_OPERATOR_LAST:
+ if (p_racp_request->operand_len != 0)
+ {
+ *p_response_code = RACP_RESPONSE_INVALID_OPERAND;
+ }
+ break;
+
+ // Operators with a filter as part of the operand.
+ case RACP_OPERATOR_LESS_OR_EQUAL:
+ // Fall Through.
+ case RACP_OPERATOR_GREATER_OR_EQUAL:
+ if (*(p_racp_request->p_operand) == RACP_OPERAND_FILTER_TYPE_FACING_TIME)
+ {
+ *p_response_code = RACP_RESPONSE_PROCEDURE_NOT_DONE;
+ }
+ if (p_racp_request->operand_len != OPERAND_LESS_GREATER_SIZE)
+ {
+ *p_response_code = RACP_RESPONSE_INVALID_OPERAND;
+ }
+ break;
+
+ case RACP_OPERATOR_RANGE:
+ *p_response_code = RACP_RESPONSE_OPERATOR_UNSUPPORTED;
+ break;
+
+ // Invalid operators.
+ case RACP_OPERATOR_NULL:
+ // Fall through.
+ default:
+ *p_response_code = RACP_RESPONSE_INVALID_OPERATOR;
+ break;
+ }
+ }
+ // Unsupported opcodes.
+ else if (p_racp_request->opcode == RACP_OPCODE_DELETE_RECS)
+ {
+ *p_response_code = RACP_RESPONSE_OPCODE_UNSUPPORTED;
+ }
+ // Unknown opcodes.
+ else
+ {
+ *p_response_code = RACP_RESPONSE_OPCODE_UNSUPPORTED;
+ }
+
+ return (*p_response_code == RACP_RESPONSE_RESERVED);
+}
+
+
+
+
+/**@brief Function for getting a record with time offset less or equal to the input param.
+ *
+ * @param[in] offset The record that this function returns must have an time offset less or greater to this.
+ * @param[out] record_num Pointer to the record index of the record that has the desired time offset.
+ *
+ * @retval NRF_SUCCESS If the record was successfully retrieved.
+ * @retval NRF_ERROR_NOT_FOUND A record with the desired offset does not exist in the database.
+ * @return If functions from other modules return errors to this function,
+ * the @ref nrf_error are propagated.
+ */
+static ret_code_t record_index_offset_less_or_equal_get(uint16_t offset, uint16_t * record_num)
+{
+ ret_code_t err_code;
+ ble_cgms_rec_t rec;
+ uint16_t upper_bound = cgms_db_num_records_get();
+
+ for((*record_num) = upper_bound; (*record_num)-- >0;)
+ {
+ err_code = cgms_db_record_get(*record_num, &rec);
+ if (err_code != NRF_SUCCESS)
+ {
+ return err_code;
+ }
+ if (rec.meas.time_offset <= offset)
+ {
+ return NRF_SUCCESS;
+ }
+ }
+ return NRF_ERROR_NOT_FOUND;
+}
+
+
+
+/**@brief Function for getting a record with time offset greater or equal to the input param.
+ *
+ * @param[in] offset The record that this function returns must have an time offset equal or
+ * greater to this.
+ * @param[out] record_num Pointer to the record index of the record that has the desired time offset.
+ *
+ * @retval NRF_SUCCESS If the record was successfully retrieved.
+ * @retval NRF_ERROR_NOT_FOUND A record with the desired offset does not exist in the database.
+ * @return If functions from other modules return errors to this function,
+ * the @ref nrf_error are propagated.
+ */
+static ret_code_t record_index_offset_greater_or_equal_get(uint16_t offset, uint16_t * record_num)
+{
+ ret_code_t err_code;
+ ble_cgms_rec_t rec;
+ uint16_t upper_bound = cgms_db_num_records_get();
+
+ for(*record_num = 0; *record_num < upper_bound; (*record_num)++)
+ {
+ err_code = cgms_db_record_get(*record_num, &rec);
+ if (err_code != NRF_SUCCESS)
+ {
+ return err_code;
+ }
+ if (rec.meas.time_offset >= offset)
+ {
+ return NRF_SUCCESS;
+ }
+ }
+ return NRF_ERROR_NOT_FOUND;
+}
+
+
+/**@brief Function for processing a REPORT RECORDS request.
+ *
+ * @details Set initial values before entering the state machine of racp_report_records_procedure().
+ *
+ * @param[in] p_cgms Service instance.
+ * @param[in] p_racp_request Request to be executed.
+ */
+static void report_records_request_execute(nrf_ble_cgms_t * p_cgms,
+ ble_racp_value_t * p_racp_request)
+{
+ p_cgms->cgms_com_state = STATE_RACP_PROC_ACTIVE;
+
+ p_cgms->racp_data.racp_proc_record_ndx = 0;
+ p_cgms->racp_data.racp_proc_operator = p_racp_request->operator;
+ p_cgms->racp_data.racp_proc_records_reported = 0;
+ p_cgms->racp_data.racp_proc_records_ndx_last_to_send = 0;
+
+ if (p_cgms->racp_data.racp_proc_operator == RACP_OPERATOR_GREATER_OR_EQUAL)
+ {
+ uint16_t offset_requested = uint16_decode(&p_cgms->racp_data.racp_request.p_operand[OPERAND_LESS_GREATER_FILTER_TYPE_SIZE]);
+ ret_code_t err_code = record_index_offset_greater_or_equal_get(offset_requested, &p_cgms->racp_data.racp_proc_record_ndx);
+ if (err_code != NRF_SUCCESS)
+ {
+ racp_report_records_completed(p_cgms);
+ }
+
+ }
+ if (p_cgms->racp_data.racp_proc_operator == RACP_OPERATOR_LESS_OR_EQUAL)
+ {
+ uint16_t offset_requested = uint16_decode(&p_cgms->racp_data.racp_request.p_operand[OPERAND_LESS_GREATER_FILTER_TYPE_SIZE]);
+ ret_code_t err_code = record_index_offset_less_or_equal_get(offset_requested,
+ &p_cgms->racp_data.racp_proc_records_ndx_last_to_send);
+ if (err_code != NRF_SUCCESS)
+ {
+ racp_report_records_completed(p_cgms);
+ }
+ }
+ racp_report_records_procedure(p_cgms);
+}
+
+
+/**@brief Function for processing a REPORT NUM RECORDS request.
+ *
+ * @param[in] p_cgms Service instance.
+ * @param[in] p_racp_request Request to be executed.
+ */
+static void report_num_records_request_execute(nrf_ble_cgms_t * p_cgms,
+ ble_racp_value_t * p_racp_request)
+{
+ uint16_t total_records;
+ uint16_t num_records;
+
+ total_records = cgms_db_num_records_get();
+ num_records = 0;
+
+ if (p_racp_request->operator == RACP_OPERATOR_ALL)
+ {
+ num_records = total_records;
+ }
+ else if ((p_racp_request->operator == RACP_OPERATOR_FIRST) ||
+ (p_racp_request->operator == RACP_OPERATOR_LAST))
+ {
+ if (total_records > 0)
+ {
+ num_records = 1;
+ }
+ }
+ else if (p_racp_request->operator == RACP_OPERATOR_GREATER_OR_EQUAL)
+ {
+ uint16_t index_of_offset;
+ uint16_t offset_requested = uint16_decode(&p_cgms->racp_data.racp_request.p_operand[OPERAND_LESS_GREATER_FILTER_TYPE_SIZE]);
+ ret_code_t err_code = record_index_offset_greater_or_equal_get(offset_requested, &index_of_offset);
+
+ if (err_code != NRF_SUCCESS)
+ {
+ num_records = 0;
+ }
+ else
+ {
+ num_records = total_records - index_of_offset;
+ }
+ }
+
+ p_cgms->racp_data.pending_racp_response.opcode = RACP_OPCODE_NUM_RECS_RESPONSE;
+ p_cgms->racp_data.pending_racp_response.operator = RACP_OPERATOR_NULL;
+ p_cgms->racp_data.pending_racp_response.operand_len = sizeof(uint16_t);
+ p_cgms->racp_data.pending_racp_response.p_operand =
+ p_cgms->racp_data.pending_racp_response_operand;
+
+ p_cgms->racp_data.pending_racp_response_operand[0] = num_records & 0xFF;
+ p_cgms->racp_data.pending_racp_response_operand[1] = num_records >> 8;
+
+ racp_send(p_cgms, &p_cgms->racp_data.pending_racp_response);
+}
+
+
+/**@brief Function for handling a write event to the Record Access Control Point.
+ *
+ * @param[in] p_cgms Service instance.
+ * @param[in] p_evt_write WRITE event to be handled.
+ */
+static void on_racp_value_write(nrf_ble_cgms_t * p_cgms, ble_gatts_evt_write_t const * p_evt_write)
+{
+ uint8_t response_code;
+
+ // set up reply to authorized write.
+ ble_gatts_rw_authorize_reply_params_t auth_reply;
+ uint32_t err_code;
+
+ auth_reply.type = BLE_GATTS_AUTHORIZE_TYPE_WRITE;
+ auth_reply.params.write.offset = 0;
+ auth_reply.params.write.len = 0;
+ auth_reply.params.write.p_data = NULL;
+
+ // Decode request.
+ ble_racp_decode(p_evt_write->len, p_evt_write->data, &p_cgms->racp_data.racp_request);
+
+ // Check if request is to be executed
+ if (is_request_to_be_executed(p_cgms, &p_cgms->racp_data.racp_request, &response_code))
+ {
+ auth_reply.params.write.gatt_status = BLE_GATT_STATUS_SUCCESS;
+ auth_reply.params.write.update = 1;
+
+ err_code = sd_ble_gatts_rw_authorize_reply(p_cgms->conn_handle,
+ &auth_reply);
+ if (err_code != NRF_SUCCESS)
+ {
+ if (p_cgms->error_handler != NULL)
+ {
+ p_cgms->error_handler(err_code);
+ }
+ return;
+ }
+
+ // Execute request
+ if (p_cgms->racp_data.racp_request.opcode == RACP_OPCODE_REPORT_RECS)
+ {
+ report_records_request_execute(p_cgms, &p_cgms->racp_data.racp_request);
+ }
+ else if (p_cgms->racp_data.racp_request.opcode == RACP_OPCODE_REPORT_NUM_RECS)
+ {
+ report_num_records_request_execute(p_cgms, &p_cgms->racp_data.racp_request);
+ }
+ }
+ else if (response_code != RACP_RESPONSE_RESERVED)
+ {
+ auth_reply.params.write.gatt_status = BLE_GATT_STATUS_SUCCESS;
+ auth_reply.params.write.update = 1;
+ err_code = sd_ble_gatts_rw_authorize_reply(p_cgms->conn_handle,
+ &auth_reply);
+
+ if (err_code != NRF_SUCCESS)
+ {
+ if (p_cgms->error_handler != NULL)
+ {
+ p_cgms->error_handler(err_code);
+ }
+ return;
+ }
+ // Abort any running procedure
+ p_cgms->cgms_com_state = STATE_NO_COMM;
+
+ // Respond with error code
+ racp_response_code_send(p_cgms, p_cgms->racp_data.racp_request.opcode, response_code);
+ }
+ else
+ {
+ // ignore request
+ auth_reply.params.write.gatt_status = BLE_GATT_STATUS_SUCCESS;
+ auth_reply.params.write.update = 1;
+ err_code = sd_ble_gatts_rw_authorize_reply(p_cgms->conn_handle,
+ &auth_reply);
+
+ if (err_code != NRF_SUCCESS)
+ {
+ if (p_cgms->error_handler != NULL)
+ {
+ p_cgms->error_handler(err_code);
+ }
+ return;
+ }
+ }
+}
+
+
+void cgms_racp_on_rw_auth_req(nrf_ble_cgms_t * p_cgms,
+ ble_gatts_evt_rw_authorize_request_t const * p_auth_req)
+{
+ if (p_auth_req->type == BLE_GATTS_AUTHORIZE_TYPE_WRITE)
+ {
+ if (p_auth_req->request.write.handle == p_cgms->char_handles.racp.value_handle)
+ {
+ on_racp_value_write(p_cgms, &p_auth_req->request.write);
+ }
+ }
+}
+
+
+/**@brief Function for handling BLE_GATTS_EVT_HVN_TX_COMPLETE events.
+ *
+ * @param[in] p_cgms Glucose Service structure.
+ */
+void cgms_racp_on_tx_complete(nrf_ble_cgms_t * p_cgms)
+{
+ p_cgms->racp_data.racp_proc_records_reported_since_txcomplete = 0;
+
+ if (p_cgms->cgms_com_state == STATE_RACP_RESPONSE_PENDING)
+ {
+ racp_send(p_cgms, &p_cgms->racp_data.pending_racp_response);
+ }
+ else if (p_cgms->cgms_com_state == STATE_RACP_PROC_ACTIVE)
+ {
+ racp_report_records_procedure(p_cgms);
+ }
+}
+
+
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/experimental_nrf_ble_cgms/cgms_racp.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/experimental_nrf_ble_cgms/cgms_racp.h
new file mode 100644
index 0000000..e1d92af
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/experimental_nrf_ble_cgms/cgms_racp.h
@@ -0,0 +1,99 @@
+/**
+ * Copyright (c) 2016 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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
+ *
+ * @defgroup ble_sdk_srv_cgms_racp Record Access Control Point
+ * @{
+ * @ingroup ble_cgms
+ * @brief Continuous Glucose Monitoring Service RACP module.
+ *
+ * @details This module implements parts of the Continuous Glucose Monitoring that relate to the
+ * Record Access Control Point. Events are propagated to this module from @ref ble_cgms
+ * using @ref cgms_racp_on_rw_auth_req and @ref cgms_racp_on_tx_complete.
+ *
+ */
+
+#ifndef NRF_BLE_CGMS_RACP_H__
+#define NRF_BLE_CGMS_RACP_H__
+
+#include "ble.h"
+#include "ble_srv_common.h"
+#include "sdk_errors.h"
+#include "nrf_ble_cgms.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+/**@brief Function for adding a characteristic for the Record Access Control Point.
+ *
+ * @param[in] p_cgms Instance of the CGM Service.
+ *
+ * @retval NRF_SUCCESS If the characteristic was successfully added.
+ * @retval NRF_ERROR_NULL If any of the input parameters are NULL.
+ * @return If functions from other modules return errors to this function,
+ * the @ref nrf_error are propagated.
+ */
+ret_code_t cgms_racp_char_add(nrf_ble_cgms_t * p_cgms);
+
+
+/**@brief Function for handling @ref BLE_GATTS_EVT_RW_AUTHORIZE_REQUEST events.
+ *
+ * @param[in] p_cgms Instance of the CGM Service.
+ * @param[in] p_auth_req Authorize request event to be handled.
+ */
+void cgms_racp_on_rw_auth_req(nrf_ble_cgms_t * p_cgms,
+ ble_gatts_evt_rw_authorize_request_t const * p_auth_req);
+
+
+/**@brief Function for handling @ref BLE_GATTS_EVT_HVN_TX_COMPLETE events.
+ *
+ * @param[in] p_cgms Instance of the CGM Service.
+ */
+void cgms_racp_on_tx_complete(nrf_ble_cgms_t * p_cgms);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // NRF_BLE_CGMS_RACP_H__
+
+/** @} */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/experimental_nrf_ble_cgms/cgms_socp.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/experimental_nrf_ble_cgms/cgms_socp.c
new file mode 100644
index 0000000..2ade378
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/experimental_nrf_ble_cgms/cgms_socp.c
@@ -0,0 +1,431 @@
+/**
+ * Copyright (c) 2016 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#include <stdint.h>
+#include <string.h>
+#include "ble.h"
+#include "ble_srv_common.h"
+#include "cgms_sst.h"
+#include "cgms_socp.h"
+
+
+#define NRF_BLE_CGMS_PLUS_INFINTE 0x07FE
+#define NRF_BLE_CGMS_MINUS_INFINTE 0x0802
+
+/**@brief Specific Operation Control Point opcodes. */
+#define SOCP_OPCODE_RESERVED 0x00 /**< Specific Operation Control Point opcode - Reserved for future use. */
+#define SOCP_WRITE_CGM_COMMUNICATION_INTERVAL 0x01
+#define SOCP_READ_CGM_COMMUNICATION_INTERVAL 0x02
+#define SOCP_READ_CGM_COMMUNICATION_INTERVAL_RESPONSE 0x03
+#define SOCP_WRITE_GLUCOSE_CALIBRATION_VALUE 0x04
+#define SOCP_READ_GLUCOSE_CALIBRATION_VALUE 0x05
+#define SOCP_READ_GLUCOSE_CALIBRATION_VALUE_RESPONSE 0x06
+#define SOCP_WRITE_PATIENT_HIGH_ALERT_LEVEL 0x07
+#define SOCP_READ_PATIENT_HIGH_ALERT_LEVEL 0x08
+#define SOCP_READ_PATIENT_HIGH_ALERT_LEVEL_RESPONSE 0x09
+#define SOCP_WRITE_PATIENT_LOW_ALERT_LEVEL 0x0A
+#define SOCP_READ_PATIENT_LOW_ALERT_LEVEL 0x0B
+#define SOCP_READ_PATIENT_LOW_ALERT_LEVEL_RESPONSE 0x0C
+#define SOCP_SET_HYPO_ALERT_LEVEL 0x0D /**Set Hypo Alert Level Hypo Alert Level value in mg/dL The response to this control point is Response Code. */
+#define SOCP_GET_HYPO_ALERT_LEVEL 0x0E /**Get Hypo Alert Level N/A The normal response to this control point is Op Code 0x0F. For error conditions, the response is Response Code */
+#define SOCP_HYPO_ALERT_LEVEL_RESPONSE 0x0F /**Hypo Alert Level Response Hypo Alert Level value in mg/dL This is the normal response to Op Code 0x0E */
+#define SOCP_SET_HYPER_ALERT_LEVEL 0x10 /**Set Hyper Alert Level Hyper Alert Level value in mg/dL The response to this control point is Response Code. */
+#define SOCP_GET_HYPER_ALERT_LEVEL 0x11 /**Get Hyper Alert Level N/A The normal response to this control point is Op Code 0x12. For error conditions, the response is Response Code */
+#define SOCP_HYPER_ALERT_LEVEL_RESPONSE 0x12 /**Hyper Alert Level Response Hyper Alert Level value in mg/dL This is the normal response to Op Code 0x11 */
+#define SOCP_SET_RATE_OF_DECREASE_ALERT_LEVEL 0x13 /**Set Rate of Decrease Alert Level Rate of Decrease Alert Level value in mg/dL/min The response to this control point is Response Code. */
+#define SOCP_GET_RATE_OF_DECREASE_ALERT_LEVEL 0x14 /**Get Rate of Decrease Alert Level N/A The normal response to this control point is Op Code 0x15. For error conditions, the response is Response Code */
+#define SOCP_RATE_OF_DECREASE_ALERT_LEVEL_RESPONSE 0x15 /**Rate of Decrease Alert Level Response Rate of Decrease Alert Level value in mg/dL/min This is the normal response to Op Code 0x14 */
+#define SOCP_SET_RATE_OF_INCREASE_ALERT_LEVEL 0x16 /**Set Rate of Increase Alert Level Rate of Increase Alert Level value in mg/dL/min The response to this control point is Response Code. */
+#define SOCP_GET_RATE_OF_INCREASE_ALERT_LEVEL 0x17 /**Get Rate of Increase Alert Level N/A The normal response to this control point is Op Code 0x18. For error conditions, the response is Response Code */
+#define SOCP_RATE_OF_INCREASE_ALERT_LEVEL_RESPONSE 0x18 /**Rate of Increase Alert Level Response Rate of Increase Alert Level value in mg/dL/min This is the normal response to Op Code 0x17 */
+#define SOCP_RESET_DEVICE_SPECIFIC_ALERT 0x19 /**Reset Device Specific Alert N/A The response to this control point is Response Code. */
+
+#define SOCP_START_THE_SESSION 0x1A
+#define SOCP_STOP_THE_SESSION 0x1B
+#define SOCP_RESPONSE_CODE 0x1C
+
+#define SOCP_RSP_RESERVED_FOR_FUTURE_USE 0x00
+#define SOCP_RSP_SUCCESS 0x01
+#define SOCP_RSP_OP_CODE_NOT_SUPPORTED 0x02
+#define SOCP_RSP_INVALID_OPERAND 0x03
+#define SOCP_RSP_PROCEDURE_NOT_COMPLETED 0x04
+#define SOCP_RSP_OUT_OF_RANGE 0x05
+
+static void ble_socp_decode(uint8_t data_len, uint8_t const * p_data, ble_cgms_socp_value_t * p_socp_val)
+{
+ p_socp_val->opcode = 0xFF;
+ p_socp_val->operand_len = 0;
+ p_socp_val->p_operand = NULL;
+
+ if (data_len > 0)
+ {
+ p_socp_val->opcode = p_data[0];
+ }
+ if (data_len > 1)
+ {
+ p_socp_val->operand_len = data_len - 1;
+ p_socp_val->p_operand = (uint8_t*)&p_data[1]; // lint !e416
+ }
+}
+
+
+uint8_t ble_socp_encode(const ble_socp_rsp_t * p_socp_rsp, uint8_t * p_data)
+{
+ uint8_t len = 0;
+ int i;
+
+
+ if (p_data != NULL)
+ {
+ p_data[len++] = p_socp_rsp->opcode;
+
+ if (
+ (p_socp_rsp->opcode != SOCP_READ_CGM_COMMUNICATION_INTERVAL_RESPONSE)
+ && (p_socp_rsp->opcode != SOCP_READ_PATIENT_HIGH_ALERT_LEVEL_RESPONSE)
+ && (p_socp_rsp->opcode != SOCP_READ_PATIENT_LOW_ALERT_LEVEL_RESPONSE)
+ && (p_socp_rsp->opcode != SOCP_HYPO_ALERT_LEVEL_RESPONSE)
+ && (p_socp_rsp->opcode != SOCP_HYPER_ALERT_LEVEL_RESPONSE)
+ && (p_socp_rsp->opcode != SOCP_RATE_OF_DECREASE_ALERT_LEVEL_RESPONSE)
+ && (p_socp_rsp->opcode != SOCP_RATE_OF_INCREASE_ALERT_LEVEL_RESPONSE)
+ && (p_socp_rsp->opcode != SOCP_READ_GLUCOSE_CALIBRATION_VALUE_RESPONSE)
+ )
+ {
+ p_data[len++] = p_socp_rsp->req_opcode;
+ p_data[len++] = p_socp_rsp->rsp_code;
+ }
+
+ for (i = 0; i < p_socp_rsp->size_val; i++)
+ {
+ p_data[len++] = p_socp_rsp->resp_val[i];
+ }
+ }
+
+ return len;
+}
+
+
+/**@brief Function for adding a characteristic for the Specific Operations Control Point.
+ *
+ * @param[in] p_cgms Service instance.
+ *
+ * @return NRF_SUCCESS if characteristic was successfully added, otherwise an error code.
+ */
+ret_code_t cgms_socp_char_add(nrf_ble_cgms_t * p_cgms)
+{
+ ble_add_char_params_t add_char_params;
+
+ memset(&add_char_params, 0, sizeof(add_char_params));
+
+ add_char_params.uuid = BLE_UUID_CGM_SPECIFIC_OPS_CTRLPT;
+ add_char_params.max_len = BLE_GATT_ATT_MTU_DEFAULT;
+ add_char_params.init_len = 0;
+ add_char_params.p_init_value = 0;
+ add_char_params.is_var_len = true;
+ add_char_params.char_props.indicate = true;
+ add_char_params.char_props.write = true;
+ add_char_params.write_access = SEC_JUST_WORKS;
+ add_char_params.cccd_write_access = SEC_JUST_WORKS;
+ add_char_params.is_defered_write = 1;
+
+ return characteristic_add(p_cgms->service_handle,
+ &add_char_params,
+ &p_cgms->char_handles.socp);
+}
+
+
+/**@brief Function for sending a response from the Specific Operation Control Point.
+ *
+ * @param[in] p_cgms Service instance.
+ */
+static void socp_send(nrf_ble_cgms_t * p_cgms)
+{
+ uint32_t err_code;
+ uint8_t encoded_resp[25];
+ uint8_t len;
+ uint16_t hvx_len;
+ ble_gatts_hvx_params_t hvx_params;
+
+ // Send indication
+ len = ble_socp_encode(&(p_cgms->socp_response), encoded_resp);
+ hvx_len = len;
+
+ memset(&hvx_params, 0, sizeof(hvx_params));
+
+ hvx_params.handle = p_cgms->char_handles.socp.value_handle;
+ hvx_params.type = BLE_GATT_HVX_INDICATION;
+ hvx_params.offset = 0;
+ hvx_params.p_len = &hvx_len;
+ hvx_params.p_data = encoded_resp;
+
+ err_code = sd_ble_gatts_hvx(p_cgms->conn_handle, &hvx_params);
+
+ // Error handling
+ if ((err_code == NRF_SUCCESS) && (hvx_len != len))
+ {
+ err_code = NRF_ERROR_DATA_SIZE;
+ }
+
+ switch (err_code)
+ {
+ case NRF_SUCCESS:
+ // Wait for HVC event.
+ p_cgms->cgms_com_state = STATE_SOCP_RESPONSE_IND_VERIF;
+ break;
+
+ case NRF_ERROR_RESOURCES:
+ // Wait for TX_COMPLETE event to retry transmission.
+ p_cgms->cgms_com_state = STATE_SOCP_RESPONSE_PENDING;
+ break;
+
+ case NRF_ERROR_INVALID_STATE:
+ // Make sure state machine returns to the default state.
+ p_cgms->cgms_com_state = STATE_NO_COMM;
+ break;
+
+ default:
+ // Report error to application.
+ if (p_cgms->error_handler != NULL)
+ {
+ p_cgms->error_handler(err_code);
+ }
+
+ // Make sure state machine returns to the default state.
+ p_cgms->cgms_com_state = STATE_NO_COMM;
+ break;
+ }
+}
+
+
+void encode_get_response(uint8_t rsp_code, ble_socp_rsp_t * p_rsp, uint16_t in_val)
+{
+ p_rsp->opcode = rsp_code;
+ p_rsp->rsp_code = SOCP_RSP_SUCCESS;
+ p_rsp->size_val += uint16_encode(in_val, &(p_rsp->resp_val[p_rsp->size_val]));
+}
+
+
+void decode_set_opcode(nrf_ble_cgms_t * p_cgms,
+ ble_cgms_socp_value_t * rcv_val,
+ uint16_t min,
+ uint16_t max,
+ uint16_t * p_val)
+{
+ uint16_t rcvd_val = uint16_decode(rcv_val->p_operand);
+
+ if ((rcvd_val == NRF_BLE_CGMS_PLUS_INFINTE)
+ || (rcvd_val == NRF_BLE_CGMS_MINUS_INFINTE)
+ || (rcvd_val > max)
+ || (rcvd_val < min))
+ {
+ p_cgms->socp_response.rsp_code = SOCP_RSP_OUT_OF_RANGE;
+ }
+ else
+ {
+ p_cgms->socp_response.rsp_code = SOCP_RSP_SUCCESS;
+ *p_val = rcvd_val;
+ }
+}
+
+
+static bool is_feature_present(nrf_ble_cgms_t * p_cgms, uint32_t feature)
+{
+ return (p_cgms->feature.feature & feature);
+}
+
+
+/**@brief Function for handling a write event to the Specific Operation Control Point.
+ *
+ * @param[in] p_cgms Service instance.
+ * @param[in] p_evt_write WRITE event to be handled.
+ */
+static void on_socp_value_write(nrf_ble_cgms_t * p_cgms, ble_gatts_evt_write_t const * p_evt_write)
+{
+ ble_cgms_socp_value_t socp_request;
+ nrf_ble_cgms_evt_t evt;
+ ble_gatts_rw_authorize_reply_params_t auth_reply;
+ uint32_t err_code;
+
+ memset(&auth_reply, 0, sizeof(auth_reply));
+
+ auth_reply.type = BLE_GATTS_AUTHORIZE_TYPE_WRITE;
+
+ auth_reply.params.write.gatt_status = BLE_GATT_STATUS_SUCCESS;
+ auth_reply.params.write.update = 1;
+
+ err_code = sd_ble_gatts_rw_authorize_reply(p_cgms->conn_handle, &auth_reply);
+ if (err_code != NRF_SUCCESS)
+ {
+ if (p_cgms->error_handler != NULL)
+ {
+ p_cgms->error_handler(err_code);
+ }
+ return;
+ }
+
+ // Decode request
+ ble_socp_decode(p_evt_write->len, p_evt_write->data, &socp_request);
+
+ p_cgms->socp_response.opcode = SOCP_RESPONSE_CODE;
+ p_cgms->socp_response.req_opcode = socp_request.opcode;
+ p_cgms->socp_response.rsp_code = SOCP_RSP_OP_CODE_NOT_SUPPORTED;
+ p_cgms->socp_response.size_val = 0;
+
+
+ switch (socp_request.opcode)
+ {
+ case SOCP_WRITE_CGM_COMMUNICATION_INTERVAL:
+ p_cgms->socp_response.rsp_code = SOCP_RSP_SUCCESS;
+ p_cgms->comm_interval = socp_request.p_operand[0];
+ evt.evt_type = NRF_BLE_CGMS_EVT_WRITE_COMM_INTERVAL;
+ p_cgms->evt_handler(p_cgms, &evt);
+ break;
+
+ case SOCP_READ_CGM_COMMUNICATION_INTERVAL:
+ p_cgms->socp_response.opcode = SOCP_READ_CGM_COMMUNICATION_INTERVAL_RESPONSE;
+ p_cgms->socp_response.resp_val[0] = p_cgms->comm_interval;
+ p_cgms->socp_response.size_val++;
+ break;
+
+ case SOCP_START_THE_SESSION:
+ if (p_cgms->is_session_started)
+ {
+ p_cgms->socp_response.rsp_code = SOCP_RSP_PROCEDURE_NOT_COMPLETED;
+ }
+ else if ((p_cgms->nb_run_session != 0) &&
+ !(is_feature_present(p_cgms, NRF_BLE_CGMS_FEAT_MULTIPLE_SESSIONS_SUPPORTED)))
+ {
+ p_cgms->socp_response.rsp_code = SOCP_RSP_PROCEDURE_NOT_COMPLETED;
+ }
+ else
+ {
+ p_cgms->socp_response.rsp_code = SOCP_RSP_SUCCESS;
+ p_cgms->is_session_started = true;
+ p_cgms->nb_run_session++;
+
+ if (p_cgms->evt_handler != NULL)
+ {
+ evt.evt_type = NRF_BLE_CGMS_EVT_START_SESSION;
+ p_cgms->evt_handler(p_cgms, &evt);
+ }
+
+ ble_cgms_sst_t sst;
+ memset(&sst, 0, sizeof(ble_cgms_sst_t));
+
+ err_code = cgms_sst_set(p_cgms, &sst);
+ if (err_code != NRF_SUCCESS)
+ {
+ if (p_cgms->error_handler != NULL)
+ {
+ p_cgms->error_handler(err_code);
+ }
+ }
+ p_cgms->sensor_status.time_offset = 0;
+ p_cgms->sensor_status.status.status &= (~NRF_BLE_CGMS_STATUS_SESSION_STOPPED);
+
+ err_code = nrf_ble_cgms_update_status(p_cgms, &p_cgms->sensor_status);
+ if (err_code != NRF_SUCCESS)
+ {
+ if (p_cgms->error_handler != NULL)
+ {
+ p_cgms->error_handler(err_code);
+ }
+ }
+ }
+ break;
+
+ case SOCP_STOP_THE_SESSION:
+ {
+ nrf_ble_cgm_status_t status;
+ memset(&status, 0, sizeof(nrf_ble_cgm_status_t));
+
+ p_cgms->evt_handler(p_cgms, &evt);
+ p_cgms->socp_response.rsp_code = SOCP_RSP_SUCCESS;
+ p_cgms->is_session_started = false;
+
+ status.time_offset = p_cgms->sensor_status.time_offset;
+ status.status.status = p_cgms->sensor_status.status.status |
+ NRF_BLE_CGMS_STATUS_SESSION_STOPPED;
+
+ if (p_cgms->evt_handler != NULL)
+ {
+ evt.evt_type = NRF_BLE_CGMS_EVT_STOP_SESSION;
+ p_cgms->evt_handler(p_cgms, &evt);
+ }
+ err_code = nrf_ble_cgms_update_status(p_cgms, &status);
+ if (err_code != NRF_SUCCESS)
+ {
+ if (p_cgms->error_handler != NULL)
+ {
+ p_cgms->error_handler(err_code);
+ }
+ }
+ break;
+ }
+
+ default:
+ p_cgms->socp_response.rsp_code = SOCP_RSP_OP_CODE_NOT_SUPPORTED;
+ break;
+ }
+
+ socp_send(p_cgms);
+}
+
+
+void cgms_socp_on_rw_auth_req(nrf_ble_cgms_t * p_cgms,
+ ble_gatts_evt_rw_authorize_request_t const * p_auth_req)
+{
+ if (p_auth_req->type == BLE_GATTS_AUTHORIZE_TYPE_WRITE)
+ {
+ if (p_auth_req->request.write.handle == p_cgms->char_handles.socp.value_handle)
+ {
+ on_socp_value_write(p_cgms, &p_auth_req->request.write);
+ }
+ }
+}
+
+
+void cgms_socp_on_tx_complete(nrf_ble_cgms_t * p_cgms)
+{
+ if (p_cgms->cgms_com_state == STATE_SOCP_RESPONSE_PENDING)
+ {
+ socp_send(p_cgms);
+ }
+}
+
+
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/experimental_nrf_ble_cgms/cgms_socp.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/experimental_nrf_ble_cgms/cgms_socp.h
new file mode 100644
index 0000000..80cb35b
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/experimental_nrf_ble_cgms/cgms_socp.h
@@ -0,0 +1,107 @@
+/**
+ * Copyright (c) 2016 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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
+ *
+ * @defgroup ble_sdk_srv_cgms_socp Specific Operations Control Point
+ * @{
+ * @ingroup ble_cgms
+ * @brief Continuous Glucose Monitoring Service SOCP module.
+ *
+ * @details This module implements parts of the Continuous Glucose Monitoring that relate to the
+ * Specific Operations Control Point. Events are propagated to this module from @ref ble_cgms
+ * using @ref cgms_socp_on_rw_auth_req and @ref cgms_socp_on_tx_complete.
+ *
+ */
+
+#ifndef NRF_BLE_CGMS_SOCP_H__
+#define NRF_BLE_CGMS_SOCP_H__
+
+#include "ble.h"
+#include "ble_srv_common.h"
+#include "sdk_errors.h"
+#include "nrf_ble_cgms.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+/**@brief Specific Operation Control Point value. */
+typedef struct
+{
+ uint8_t opcode; /**< Opcode. */
+ uint8_t operand_len; /**< Length of the operand. */
+ uint8_t * p_operand; /**< Pointer to the operand. */
+} ble_cgms_socp_value_t;
+
+
+/**@brief Function for adding a characteristic for the Specific Operations Control Point.
+ *
+ * @param[in] p_cgms Instance of the CGM Service.
+ *
+ * @retval NRF_SUCCESS If the characteristic was successfully added.
+ * @return If functions from other modules return errors to this function,
+ * the @ref nrf_error are propagated.
+ */
+ret_code_t cgms_socp_char_add(nrf_ble_cgms_t * p_cgms);
+
+
+/**@brief Function for handling @ref BLE_GATTS_EVT_RW_AUTHORIZE_REQUEST events.
+ *
+ * @param[in] p_cgms Instance of the CGM Service.
+ * @param[in] p_auth_req Authorize request event to be handled.
+ */
+void cgms_socp_on_rw_auth_req(nrf_ble_cgms_t * p_cgms,
+ ble_gatts_evt_rw_authorize_request_t const * p_auth_req);
+
+
+/**@brief Function for handling @ref BLE_GATTS_EVT_HVN_TX_COMPLETE events.
+ *
+ * @param[in] p_cgms Instance of the CGM Service.
+ */
+void cgms_socp_on_tx_complete(nrf_ble_cgms_t * p_cgms);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // NRF_BLE_CGMS_SOCP_H__
+
+/** @} */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/experimental_nrf_ble_cgms/cgms_sst.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/experimental_nrf_ble_cgms/cgms_sst.c
new file mode 100644
index 0000000..b6b2fcd
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/experimental_nrf_ble_cgms/cgms_sst.c
@@ -0,0 +1,235 @@
+/**
+ * Copyright (c) 2016 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#include <stdint.h>
+#include <string.h>
+#include <time.h>
+#include "ble.h"
+#include "ble_srv_common.h"
+#include "nrf_ble_cgms.h"
+#include "cgms_sst.h"
+
+
+void sst_decode(ble_cgms_sst_t * p_sst, const uint8_t * p_data, const uint16_t len)
+{
+ uint32_t index;
+
+ if (len != NRF_BLE_CGMS_SST_LEN)
+ {
+ return;
+ }
+
+ index = ble_date_time_decode(&p_sst->date_time, p_data);
+
+ p_sst->time_zone = p_data[index++];
+ p_sst->dst = p_data[index++];
+}
+
+
+void convert_ble_time_c_time(ble_cgms_sst_t * p_sst, struct tm * p_c_time_date)
+{
+ p_c_time_date->tm_sec = p_sst->date_time.seconds;
+ p_c_time_date->tm_min = p_sst->date_time.minutes;
+ p_c_time_date->tm_hour = p_sst->date_time.hours;
+ p_c_time_date->tm_mday = p_sst->date_time.day;
+ p_c_time_date->tm_mon = p_sst->date_time.month;
+ p_c_time_date->tm_year = p_sst->date_time.year - 1900;
+
+ // Ignore daylight saving for this conversion.
+ p_c_time_date->tm_isdst = 0;
+}
+
+
+void calc_sst(uint16_t offset, struct tm * p_c_time_date)
+{
+ time_t c_time_in_sec;
+
+ c_time_in_sec = mktime(p_c_time_date);
+ c_time_in_sec = c_time_in_sec - (offset * 60);
+ *p_c_time_date = *(localtime(&c_time_in_sec));
+
+ if (p_c_time_date->tm_isdst == 1)
+ {
+ // Daylight saving time is not used and must be removed.
+ p_c_time_date->tm_hour = p_c_time_date->tm_hour - 1;
+ p_c_time_date->tm_isdst = 0;
+ }
+}
+
+
+static void convert_c_time_ble_time(ble_cgms_sst_t * p_sst, struct tm * p_c_time_date)
+{
+ p_sst->date_time.seconds = p_c_time_date->tm_sec;
+ p_sst->date_time.minutes = p_c_time_date->tm_min;
+ p_sst->date_time.hours = p_c_time_date->tm_hour;
+ p_sst->date_time.day = p_c_time_date->tm_mday;
+ p_sst->date_time.month = p_c_time_date->tm_mon;
+ p_sst->date_time.year = p_c_time_date->tm_year + 1900;
+}
+
+
+static uint8_t sst_encode(ble_cgms_sst_t * p_sst, uint8_t * p_encoded_sst)
+{
+ uint8_t len;
+
+ len = ble_date_time_encode(&p_sst->date_time, p_encoded_sst);
+
+ p_encoded_sst[len++] = p_sst->time_zone;
+ p_encoded_sst[len++] = p_sst->dst;
+
+ return len;
+}
+
+
+static ret_code_t cgm_update_sst(nrf_ble_cgms_t * p_cgms, ble_gatts_evt_write_t const * p_evt_write)
+{
+ ble_cgms_sst_t sst;
+ struct tm c_time_and_date;
+
+ memset(&sst, 0, sizeof(ble_cgms_sst_t));
+
+ sst_decode(&sst, p_evt_write->data, p_evt_write->len);
+ convert_ble_time_c_time(&sst, &c_time_and_date);
+ calc_sst(p_cgms->sensor_status.time_offset, &c_time_and_date);
+ convert_c_time_ble_time(&sst, &c_time_and_date);
+
+ return cgms_sst_set(p_cgms, &sst);
+}
+
+
+/**@brief Function for handling the Glucose session start time write event.
+ *
+ * @param[in] p_cgms Service instance.
+ * @param[in] p_evt_write WRITE event to be handled.
+ */
+static void on_sst_value_write(nrf_ble_cgms_t * p_cgms, ble_gatts_evt_write_t const * p_evt_write)
+{
+ ble_gatts_rw_authorize_reply_params_t auth_reply;
+ uint32_t err_code;
+
+ memset(&auth_reply, 0, sizeof(auth_reply));
+
+ auth_reply.type = BLE_GATTS_AUTHORIZE_TYPE_WRITE;
+ auth_reply.params.write.update = 1;
+ auth_reply.params.write.gatt_status = BLE_GATT_STATUS_SUCCESS;
+
+ err_code = sd_ble_gatts_rw_authorize_reply(p_cgms->conn_handle, &auth_reply);
+ if (err_code != NRF_SUCCESS)
+ {
+ if (p_cgms->error_handler != NULL)
+ {
+ p_cgms->error_handler(err_code);
+ }
+ }
+
+ err_code = cgm_update_sst(p_cgms, p_evt_write);
+ if (err_code != NRF_SUCCESS)
+ {
+ if (p_cgms->error_handler != NULL)
+ {
+ p_cgms->error_handler(err_code);
+ }
+ }
+}
+
+
+/**@brief Function for adding a characteristic for the Session Start Time.
+ *
+ * @param[in] p_cgms Service instance.
+ *
+ * @return NRF_SUCCESS if characteristic was successfully added, otherwise an error code.
+ */
+ret_code_t cgms_sst_char_add(nrf_ble_cgms_t * p_cgms)
+{
+ ble_add_char_params_t add_char_params;
+ uint8_t init_value[NRF_BLE_CGMS_SST_LEN] = {0};
+
+ memset(&add_char_params, 0, sizeof(add_char_params));
+
+ add_char_params.uuid = BLE_UUID_CGM_SESSION_START_TIME;
+ add_char_params.max_len = NRF_BLE_CGMS_SST_LEN;
+
+ add_char_params.init_len = NRF_BLE_CGMS_SST_LEN;
+ add_char_params.p_init_value = init_value;
+
+ add_char_params.read_access = SEC_JUST_WORKS;
+ add_char_params.write_access = SEC_JUST_WORKS;
+ add_char_params.is_defered_write = 1;
+ add_char_params.char_props.write = true;
+ add_char_params.char_props.read = true;
+
+ return characteristic_add(p_cgms->service_handle,
+ &add_char_params,
+ &p_cgms->char_handles.sst);
+}
+
+
+ret_code_t cgms_sst_set(nrf_ble_cgms_t * p_cgms, ble_cgms_sst_t * p_sst)
+{
+ uint16_t conn_handle;
+ uint16_t value_handle;
+ ble_gatts_value_t sst_val;
+ uint8_t encoded_start_session_time[NRF_BLE_CGMS_SST_LEN];
+ uint8_t gatts_value_set_len = 0;
+
+ gatts_value_set_len = sst_encode(p_sst, encoded_start_session_time);
+ conn_handle = p_cgms->conn_handle;
+ value_handle = p_cgms->char_handles.sst.value_handle;
+ memset(&sst_val, 0, sizeof(ble_gatts_value_t));
+ sst_val.len = gatts_value_set_len;
+ sst_val.p_value = encoded_start_session_time;
+ sst_val.offset = 0;
+
+ return (sd_ble_gatts_value_set(conn_handle, value_handle, &sst_val));
+}
+
+
+void cgms_sst_on_rw_auth_req(nrf_ble_cgms_t * p_cgms,
+ ble_gatts_evt_rw_authorize_request_t const * p_auth_req)
+{
+ if (p_auth_req->type == BLE_GATTS_AUTHORIZE_TYPE_WRITE)
+ {
+ if (p_auth_req->request.write.handle == p_cgms->char_handles.sst.value_handle)
+ {
+ on_sst_value_write(p_cgms, &p_auth_req->request.write);
+ }
+ }
+}
+
+
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/experimental_nrf_ble_cgms/cgms_sst.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/experimental_nrf_ble_cgms/cgms_sst.h
new file mode 100644
index 0000000..800c81c
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/experimental_nrf_ble_cgms/cgms_sst.h
@@ -0,0 +1,115 @@
+/**
+ * Copyright (c) 2016 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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
+ *
+ * @defgroup ble_sdk_srv_cgms_sst Session Start Time
+ * @{
+ * @ingroup ble_cgms
+ *
+ * @brief Continuous Glucose Monitoring Service SST module.
+ *
+ * @details This module implements parts of the Continuous Glucose Monitoring that relate to the
+ * Session Start Time characteristic. Events are propagated to this module from @ref ble_cgms
+ * using @ref cgms_sst_on_rw_auth_req.
+ *
+ */
+
+#ifndef NRF_BLE_CGMS_SST_H__
+#define NRF_BLE_CGMS_SST_H__
+
+
+#include "ble.h"
+#include "ble_srv_common.h"
+#include "ble_date_time.h"
+#include "sdk_errors.h"
+#include "nrf_ble_cgms.h"
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+/**@brief Required data for setting the SST characteristic value. */
+typedef struct
+{
+ ble_date_time_t date_time; /**< Date and time. */
+ uint8_t time_zone; /**< Time zone. */
+ uint8_t dst; /**< Daylight saving time. */
+}ble_cgms_sst_t;
+
+/**@brief Function for adding a characteristic for the Session Start Time.
+ *
+ * @param[in] p_cgms Instance of the CGM Service.
+ *
+ * @retval NRF_SUCCESS If the characteristic was successfully added.
+ * @return If functions from other modules return errors to this function,
+ * the @ref nrf_error are propagated.
+ */
+ret_code_t cgms_sst_char_add(nrf_ble_cgms_t * p_cgms);
+
+
+/**@brief Function for setting the Session Run Time attribute.
+ *
+ * @param[in] p_cgms Instance of the CGM Service.
+ * @param[in] p_sst Time and date that will be displayed in the session start time attribute.
+ *
+ * @retval NRF_SUCCESS If the Session Run Time Attribute was successfully set.
+ * @return If functions from other modules return errors to this function,
+ * the @ref nrf_error are propagated.
+ */
+ret_code_t cgms_sst_set(nrf_ble_cgms_t * p_cgms, ble_cgms_sst_t * p_sst);
+
+
+/**@brief Function for handling @ref BLE_GATTS_EVT_RW_AUTHORIZE_REQUEST events.
+ *
+ * @param[in] p_cgms Instance of the CGM Service.
+ * @param[in] p_auth_req Authorize request event to be handled.
+ */
+void cgms_sst_on_rw_auth_req(nrf_ble_cgms_t * p_cgms,
+ ble_gatts_evt_rw_authorize_request_t const * p_auth_req);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // NRF_BLE_CGMS_SST_H__
+
+/** @} */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/experimental_nrf_ble_cgms/nrf_ble_cgms.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/experimental_nrf_ble_cgms/nrf_ble_cgms.c
new file mode 100644
index 0000000..f895edb
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/experimental_nrf_ble_cgms/nrf_ble_cgms.c
@@ -0,0 +1,504 @@
+/**
+ * Copyright (c) 2016 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#include "ble_racp.h"
+#include "ble_srv_common.h"
+
+#include "ble_date_time.h"
+#include "sdk_common.h"
+
+#include "nrf_ble_cgms.h"
+#include "cgms_db.h"
+#include "cgms_meas.h"
+#include "cgms_racp.h"
+#include "cgms_socp.h"
+#include "cgms_sst.h"
+
+#define OPERAND_FILTER_TYPE_RESV 0x00 /**< Filter type value reserved for future use. */
+#define OPERAND_FILTER_TYPE_SEQ_NUM 0x01 /**< Filter data using Sequence Number criteria. */
+#define OPERAND_FILTER_TYPE_FACING_TIME 0x02 /**< Filter data using User Facing Time criteria. */
+
+
+/**@brief Function for setting next sequence number by reading the last record in the data base.
+ *
+ * @return NRF_SUCCESS on successful initialization of service, otherwise an error code.
+ */
+static uint32_t next_sequence_number_set(void)
+{
+ uint16_t num_records;
+ ble_cgms_rec_t rec;
+
+ num_records = cgms_db_num_records_get();
+ if (num_records > 0)
+ {
+ // Get last record
+ uint32_t err_code = cgms_db_record_get(num_records - 1, &rec);
+ if (err_code != NRF_SUCCESS)
+ {
+ return err_code;
+ }
+ }
+
+ return NRF_SUCCESS;
+}
+
+
+uint8_t encode_feature_location_type(uint8_t * p_out_buffer, nrf_ble_cgms_feature_t * p_in_feature)
+{
+ uint8_t len = 0;
+
+ len += uint24_encode(p_in_feature->feature, &p_out_buffer[len]);
+ p_out_buffer[len++] = (p_in_feature->sample_location << 4) | (p_in_feature->type & 0x0F);
+ len += uint16_encode(0xFFFF, &p_out_buffer[len]);
+
+ return len;
+}
+
+
+/**@brief Function for adding a characteristic for the glucose feature.
+ *
+ * @param[in] p_cgms Service instance.
+ *
+ * @return NRF_SUCCESS if characteristic was successfully added, otherwise an error code.
+ */
+static uint32_t glucose_feature_char_add(nrf_ble_cgms_t * p_cgms)
+{
+ uint8_t init_value_len;
+ uint8_t encoded_initial_feature[NRF_BLE_CGMS_FEATURE_LEN];
+ ble_add_char_params_t add_char_params;
+
+ memset(&add_char_params, 0, sizeof(add_char_params));
+
+ init_value_len = encode_feature_location_type(encoded_initial_feature, &(p_cgms->feature));
+
+ add_char_params.uuid = BLE_UUID_CGM_FEATURE;
+ add_char_params.max_len = init_value_len;
+ add_char_params.init_len = init_value_len;
+ add_char_params.p_init_value = encoded_initial_feature;
+ add_char_params.read_access = SEC_JUST_WORKS;
+ add_char_params.write_access = SEC_NO_ACCESS;
+
+
+ return characteristic_add(p_cgms->service_handle,
+ &add_char_params,
+ &p_cgms->char_handles.feature);
+}
+
+
+uint8_t encode_status(uint8_t * p_out_buffer, nrf_ble_cgms_t * p_cgms)
+{
+ uint8_t len = 0;
+
+ len += uint16_encode(p_cgms->sensor_status.time_offset, &p_out_buffer[len]);
+
+ p_out_buffer[len++] = p_cgms->sensor_status.status.status;
+ p_out_buffer[len++] = p_cgms->sensor_status.status.calib_temp;
+ p_out_buffer[len++] = p_cgms->sensor_status.status.warning;
+
+ return len;
+}
+
+
+/**@brief Function for adding a status characteristic for the CGMS.
+ *
+ * @param[in] p_cgms Service instance.
+ *
+ * @return NRF_SUCCESS if characteristic was successfully added, otherwise an error code.
+ */
+static uint32_t status_char_add(nrf_ble_cgms_t * p_cgms)
+{
+ uint8_t init_value_len;
+ uint8_t encoded_initial_status[NRF_BLE_CGMS_STATUS_LEN];
+ ble_add_char_params_t add_char_params;
+
+ memset(&add_char_params, 0, sizeof(add_char_params));
+
+ init_value_len = encode_status(encoded_initial_status, p_cgms);
+
+ add_char_params.uuid = BLE_UUID_CGM_STATUS;
+ add_char_params.max_len = init_value_len;
+ add_char_params.init_len = init_value_len;
+ add_char_params.p_init_value = encoded_initial_status;
+ add_char_params.read_access = SEC_JUST_WORKS;
+ add_char_params.write_access = SEC_NO_ACCESS;
+
+ return characteristic_add(p_cgms->service_handle,
+ &add_char_params,
+ &p_cgms->char_handles.status);
+}
+
+
+/**@brief Function for adding a characteristic for the Session Run Time.
+ *
+ * @param[in] p_cgms Service instance.
+ *
+ * @return NRF_SUCCESS if characteristic was successfully added, otherwise an error code.
+ */
+static uint32_t srt_char_add(nrf_ble_cgms_t * p_cgms)
+{
+ uint8_t len = 0;
+ uint8_t encoded_initial_srt[NRF_BLE_CGMS_SRT_LEN];
+ ble_add_char_params_t add_char_params;
+
+ memset(&add_char_params, 0, sizeof(add_char_params));
+
+
+ len += uint16_encode(p_cgms->session_run_time, &(encoded_initial_srt[len]));
+
+ add_char_params.uuid = BLE_UUID_CGM_SESSION_RUN_TIME;
+ add_char_params.max_len = NRF_BLE_CGMS_SRT_LEN;
+ add_char_params.init_len = len;
+ add_char_params.p_init_value = encoded_initial_srt;
+ add_char_params.read_access = SEC_JUST_WORKS;
+ add_char_params.write_access = SEC_NO_ACCESS;
+ add_char_params.char_props.read = true;
+
+ return characteristic_add(p_cgms->service_handle,
+ &add_char_params,
+ &p_cgms->char_handles.srt);
+}
+
+
+uint8_t init_calib_val[] = {
+ 0x3E,
+ 0x00,
+ 0x07,
+ 0x00,
+ 0x06,
+ 0x07,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x00,
+};
+ret_code_t nrf_ble_cgms_init(nrf_ble_cgms_t * p_cgms, const nrf_ble_cgms_init_t * p_cgms_init)
+{
+ VERIFY_PARAM_NOT_NULL(p_cgms);
+ VERIFY_PARAM_NOT_NULL(p_cgms_init);
+ VERIFY_PARAM_NOT_NULL(p_cgms_init->evt_handler);
+
+ uint32_t err_code;
+ ble_uuid_t ble_uuid;
+
+ // Initialize data base
+ err_code = cgms_db_init();
+ if (err_code != NRF_SUCCESS)
+ {
+ return err_code;
+ }
+
+ err_code = next_sequence_number_set();
+ if (err_code != NRF_SUCCESS)
+ {
+ return err_code;
+ }
+
+ // Initialize service structure
+ p_cgms->evt_handler = p_cgms_init->evt_handler;
+ p_cgms->error_handler = p_cgms_init->error_handler;
+ p_cgms->feature = p_cgms_init->feature;
+ p_cgms->sensor_status = p_cgms_init->initial_sensor_status;
+ p_cgms->session_run_time = p_cgms_init->initial_run_time;
+ p_cgms->is_session_started = false;
+ p_cgms->nb_run_session = 0;
+ p_cgms->conn_handle = BLE_CONN_HANDLE_INVALID;
+
+ p_cgms->feature.feature = 0;
+ p_cgms->feature.feature |= NRF_BLE_CGMS_FEAT_MULTIPLE_BOND_SUPPORTED;
+ p_cgms->feature.feature |= NRF_BLE_CGMS_FEAT_MULTIPLE_SESSIONS_SUPPORTED;
+ p_cgms->feature.type = NRF_BLE_CGMS_MEAS_TYPE_VEN_BLOOD;
+ p_cgms->feature.sample_location = NRF_BLE_CGMS_MEAS_LOC_AST;
+ p_cgms->feature.feature |= NRF_BLE_CGMS_FEAT_MULTIPLE_BOND_SUPPORTED;
+
+ memcpy(p_cgms->calibration_val[0].value, init_calib_val, NRF_BLE_CGMS_MAX_CALIB_LEN);
+
+ // Initialize global variables
+ p_cgms->cgms_com_state = STATE_NO_COMM;
+ p_cgms->racp_data.racp_proc_records_reported_since_txcomplete = 0;
+
+ // Add service
+ BLE_UUID_BLE_ASSIGN(ble_uuid, BLE_UUID_CGM_SERVICE);
+
+ err_code = sd_ble_gatts_service_add(BLE_GATTS_SRVC_TYPE_PRIMARY,
+ &ble_uuid,
+ &p_cgms->service_handle);
+ if (err_code != NRF_SUCCESS)
+ {
+ return err_code;
+ }
+
+ // Add glucose measurement characteristic
+ err_code = cgms_meas_char_add(p_cgms);
+ if (err_code != NRF_SUCCESS)
+ {
+ return err_code;
+ }
+
+ // Add glucose measurement feature characteristic
+ err_code = glucose_feature_char_add(p_cgms);
+ if (err_code != NRF_SUCCESS)
+ {
+ return err_code;
+ }
+
+ // Add glucose measurement status characteristic
+ err_code = status_char_add(p_cgms);
+ if (err_code != NRF_SUCCESS)
+ {
+ return err_code;
+ }
+
+ // Add record control access point characteristic
+ err_code = cgms_racp_char_add(p_cgms);
+ if (err_code != NRF_SUCCESS)
+ {
+ return err_code;
+ }
+
+ // Add Start Session Time characteristic
+ err_code = cgms_sst_char_add(p_cgms);
+ if (err_code != NRF_SUCCESS)
+ {
+ return err_code;
+ }
+
+ // Add Session Run Time characteristic
+ err_code = srt_char_add(p_cgms);
+ if (err_code != NRF_SUCCESS)
+ {
+ return err_code;
+ }
+
+ // Add Specific Operations Control Point characteristic
+ err_code = cgms_socp_char_add(p_cgms);
+ if (err_code != NRF_SUCCESS)
+ {
+ return err_code;
+ }
+
+ return NRF_SUCCESS;
+}
+
+
+/**@brief Function for handling the WRITE event.
+ *
+ * @details Handles WRITE events from the BLE stack.
+ *
+ * @param[in] p_cgms Glucose Service structure.
+ * @param[in] p_ble_evt Event received from the BLE stack.
+ */
+static void on_write(nrf_ble_cgms_t * p_cgms, ble_evt_t const * p_ble_evt)
+{
+ ble_gatts_evt_write_t const * p_evt_write = &p_ble_evt->evt.gatts_evt.params.write;
+
+ cgms_meas_on_write(p_cgms, p_evt_write);
+}
+
+
+/**@brief Function for handling the TX_COMPLETE event.
+ *
+ * @details Handles TX_COMPLETE events from the BLE stack.
+ *
+ * @param[in] p_cgms Glucose Service structure.
+ * @param[in] p_ble_evt Event received from the BLE stack.
+ */
+static void on_tx_complete(nrf_ble_cgms_t * p_cgms, ble_evt_t const * p_ble_evt)
+{
+ p_cgms->racp_data.racp_proc_records_reported_since_txcomplete = 0;
+
+ cgms_racp_on_tx_complete(p_cgms);
+ cgms_socp_on_tx_complete(p_cgms);
+}
+
+
+/**@brief Function for handling the HVC event.
+ *
+ * @details Handles HVC events from the BLE stack.
+ *
+ * @param[in] p_cgms Glucose Service structure.
+ * @param[in] p_ble_evt Event received from the BLE stack.
+ */
+static void on_hvc(nrf_ble_cgms_t * p_cgms, ble_evt_t const * p_ble_evt)
+{
+ ble_gatts_evt_hvc_t const * p_hvc = &p_ble_evt->evt.gatts_evt.params.hvc;
+
+ if (p_hvc->handle == p_cgms->char_handles.racp.value_handle)
+ {
+ if (p_cgms->cgms_com_state == STATE_RACP_RESPONSE_IND_VERIF)
+ {
+ // Indication has been acknowledged. Return to default state.
+ p_cgms->cgms_com_state = STATE_NO_COMM;
+ }
+ else
+ {
+ // We did not expect this event in this state. Report error to application.
+ if (p_cgms->error_handler != NULL)
+ {
+ p_cgms->error_handler(NRF_ERROR_INVALID_STATE);
+ }
+ }
+ }
+ if (p_hvc->handle == p_cgms->char_handles.socp.value_handle)
+ {
+ if (p_cgms->cgms_com_state == STATE_SOCP_RESPONSE_IND_VERIF)
+ {
+ // Indication has been acknowledged. Return to default state.
+ p_cgms->cgms_com_state = STATE_NO_COMM;
+ }
+ else
+ {
+ // We did not expect this event in this state. Report error to application.
+ if (p_cgms->error_handler != NULL)
+ {
+ p_cgms->error_handler(NRF_ERROR_INVALID_STATE);
+ }
+ }
+ }
+}
+
+
+static void on_rw_authorize_request(nrf_ble_cgms_t * p_cgms, ble_gatts_evt_t const * p_gatts_evt)
+{
+ ble_gatts_evt_rw_authorize_request_t const * p_auth_req =
+ &p_gatts_evt->params.authorize_request;
+
+ cgms_racp_on_rw_auth_req(p_cgms, p_auth_req);
+ cgms_socp_on_rw_auth_req(p_cgms, p_auth_req);
+ cgms_sst_on_rw_auth_req(p_cgms, p_auth_req);
+}
+
+
+void nrf_ble_cgms_on_ble_evt(ble_evt_t const * p_ble_evt, void * p_context)
+{
+ nrf_ble_cgms_t * p_cgms = (nrf_ble_cgms_t *)p_context;
+
+ switch (p_ble_evt->header.evt_id)
+ {
+ case BLE_GAP_EVT_CONNECTED:
+ p_cgms->conn_handle = p_ble_evt->evt.gap_evt.conn_handle;
+ p_cgms->cgms_com_state = STATE_NO_COMM;
+ break;
+
+ case BLE_GAP_EVT_DISCONNECTED:
+ p_cgms->conn_handle = BLE_CONN_HANDLE_INVALID;
+ break;
+
+ case BLE_GATTS_EVT_WRITE:
+ on_write(p_cgms, p_ble_evt);
+ break;
+
+ case BLE_GATTS_EVT_HVN_TX_COMPLETE:
+ on_tx_complete(p_cgms, p_ble_evt);
+ break;
+
+ case BLE_GATTS_EVT_RW_AUTHORIZE_REQUEST:
+ on_rw_authorize_request(p_cgms, &p_ble_evt->evt.gatts_evt);
+ break;
+
+ case BLE_GATTS_EVT_HVC:
+ on_hvc(p_cgms, p_ble_evt);
+ break;
+
+ default:
+ // No implementation needed.
+ break;
+ }
+}
+
+
+ret_code_t nrf_ble_cgms_meas_create(nrf_ble_cgms_t * p_cgms, ble_cgms_rec_t * p_rec)
+{
+ uint32_t err_code = NRF_SUCCESS;
+ uint8_t nb_rec_to_send = 1;
+
+ err_code = cgms_db_record_add(p_rec);
+ if (err_code != NRF_SUCCESS)
+ {
+ return err_code;
+ }
+ if ((p_cgms->conn_handle != BLE_CONN_HANDLE_INVALID) && (p_cgms->comm_interval != 0))
+ {
+ err_code = cgms_meas_send(p_cgms, p_rec, &nb_rec_to_send);
+ }
+ return err_code;
+}
+
+
+ret_code_t nrf_ble_cgms_update_status(nrf_ble_cgms_t * p_cgms, nrf_ble_cgm_status_t * p_status)
+{
+ uint8_t encoded_status[NRF_BLE_CGMS_STATUS_LEN];
+ ble_gatts_value_t status_val;
+
+ memset(&status_val, 0, sizeof(status_val));
+ p_cgms->sensor_status = *p_status;
+ status_val.len = encode_status(encoded_status, p_cgms);
+ status_val.p_value = encoded_status;
+ status_val.offset = 0;
+
+ return (sd_ble_gatts_value_set(p_cgms->conn_handle, p_cgms->char_handles.status.value_handle,
+ &status_val));
+}
+
+
+ret_code_t nrf_ble_cgms_conn_handle_assign(nrf_ble_cgms_t * p_cgms, uint16_t conn_handle)
+{
+ VERIFY_PARAM_NOT_NULL(p_cgms);
+ p_cgms->conn_handle = conn_handle;
+ return NRF_SUCCESS;
+}
+
+
+ret_code_t nrf_ble_cgms_srt_set(nrf_ble_cgms_t * p_cgms, uint16_t run_time)
+{
+ ble_gatts_value_t srt_val;
+ uint8_t encoded_session_run_time[NRF_BLE_CGMS_SRT_LEN];
+ uint8_t gatts_value_set_len = 0;
+
+ gatts_value_set_len = uint16_encode(run_time, encoded_session_run_time); // (p_sst, encoded_start_session_time);
+
+ memset(&srt_val, 0, sizeof(ble_gatts_value_t));
+ srt_val.len = gatts_value_set_len;
+ srt_val.p_value = encoded_session_run_time;
+ srt_val.offset = 0;
+
+ return (sd_ble_gatts_value_set(p_cgms->conn_handle, p_cgms->char_handles.srt.value_handle,
+ &srt_val));
+}
+
+
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/experimental_nrf_ble_cgms/nrf_ble_cgms.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/experimental_nrf_ble_cgms/nrf_ble_cgms.h
new file mode 100644
index 0000000..dbac766
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/experimental_nrf_ble_cgms/nrf_ble_cgms.h
@@ -0,0 +1,453 @@
+/**
+ * Copyright (c) 2016 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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
+ *
+ * @defgroup ble_cgms Continuous Glucose Monitoring Service
+ * @{
+ * @ingroup ble_sdk_srv
+ * @brief Continuous Glucose Monitoring Service (CGMS) module.
+ *
+ * @details This module implements a sensor for the Continuous Glucose Monitoring Service.
+ * The sensor is a GATT Server that sends CGM measurements to a connected CGMS
+ * Collector. The CGMS Sensor stores records that can be accessed with the
+ * Record Access Control Point (RACP). The collector can access the features and status
+ * of the sensor. Session Run Time and Session Start Time can be used to convey timing
+ * information between the sensor and the collector. The Specific Operations Control Point
+ * is used to stop and start monitoring sessions, among other things.
+ *
+ * @note The application must register this module as BLE event observer using the
+ * NRF_SDH_BLE_OBSERVER macro. Example:
+ * @code
+ * nrf_ble_cgms_t instance;
+ * NRF_SDH_BLE_OBSERVER(anything, NRF_BLE_CGMS_BLE_OBSERVER_PRIO,
+ * nrf_ble_cgms_on_ble_evt, &instance);
+ * @endcode
+ */
+
+#ifndef NRF_BLE_CGMS_H__
+#define NRF_BLE_CGMS_H__
+
+#include "ble_srv_common.h"
+#include "sdk_errors.h"
+#include "ble_racp.h"
+#include "nrf_sdh_ble.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**@brief Macro for defining a nrf_ble_cgms instance.
+ *
+ * @param _name Name of the instance.
+ * @hideinitializer
+ */
+#define NRF_BLE_CGMS_DEF(_name) \
+static nrf_ble_cgms_t _name; \
+NRF_SDH_BLE_OBSERVER(_name ## _obs, \
+ NRF_BLE_CGMS_BLE_OBSERVER_PRIO, \
+ nrf_ble_cgms_on_ble_evt, &_name)
+
+/**@name CGM Feature characteristic defines
+ * @{ */
+#define NRF_BLE_CGMS_FEAT_CALIBRATION_SUPPORTED (0x01 << 0) //!< Calibration supported.
+#define NRF_BLE_CGMS_FEAT_PATIENT_HIGH_LOW_ALERTS_SUPPORTED (0x01 << 1) //!< Patient High/Low Alerts supported.
+#define NRF_BLE_CGMS_FEAT_HYPO_ALERTS_SUPPORTED (0x01 << 2) //!< Hypo Alerts supported.
+#define NRF_BLE_CGMS_FEAT_HYPER_ALERTS_SUPPORTED (0x01 << 3) //!< Hyper Alerts supported.
+#define NRF_BLE_CGMS_FEAT_RATE_OF_INCREASE_DECREASE_ALERTS_SUPPORTED (0x01 << 4) //!< Rate of Increase/Decrease Alerts supported.
+#define NRF_BLE_CGMS_FEAT_DEVICE_SPECIFIC_ALERT_SUPPORTED (0x01 << 5) //!< Device Specific Alert supported.
+#define NRF_BLE_CGMS_FEAT_SENSOR_MALFUNCTION_DETECTION_SUPPORTED (0x01 << 6) //!< Sensor Malfunction Detection supported.
+#define NRF_BLE_CGMS_FEAT_SENSOR_TEMPERATURE_HIGH_LOW_DETECTION_SUPPORTED (0x01 << 7) //!< Sensor Temperature High-Low Detection supported.
+#define NRF_BLE_CGMS_FEAT_SENSOR_RESULT_HIGH_LOW_DETECTION_SUPPORTED (0x01 << 8) //!< Sensor Result High-Low Detection supported.
+#define NRF_BLE_CGMS_FEAT_LOW_BATTERY_DETECTION_SUPPORTED (0x01 << 9) //!< Low Battery Detection supported.
+#define NRF_BLE_CGMS_FEAT_SENSOR_TYPE_ERROR_DETECTION_SUPPORTED (0x01 << 10) //!< Sensor Type Error Detection supported.
+#define NRF_BLE_CGMS_FEAT_GENERAL_DEVICE_FAULT_SUPPORTED (0x01 << 11) //!< General Device Fault supported.
+#define NRF_BLE_CGMS_FEAT_E2E_CRC_SUPPORTED (0x01 << 12) //!< E2E-CRC supported.
+#define NRF_BLE_CGMS_FEAT_MULTIPLE_BOND_SUPPORTED (0x01 << 13) //!< Multiple Bond supported.
+#define NRF_BLE_CGMS_FEAT_MULTIPLE_SESSIONS_SUPPORTED (0x01 << 14) //!< Multiple Sessions supported.
+#define NRF_BLE_CGMS_FEAT_CGM_TREND_INFORMATION_SUPPORTED (0x01 << 15) //!< CGM Trend Information supported.
+#define NRF_BLE_CGMS_FEAT_CGM_QUALITY_SUPPORTED (0x01 << 16) //!< CGM Quality supported.
+/** @} */
+
+/**@name Continuous Glucose Monitoring type
+ * @{ */
+#define NRF_BLE_CGMS_MEAS_TYPE_CAP_BLOOD 0x01 //!< Capillary Whole blood.
+#define NRF_BLE_CGMS_MEAS_TYPE_CAP_PLASMA 0x02 //!< Capillary Plasma.
+#define NRF_BLE_CGMS_MEAS_TYPE_VEN_BLOOD 0x03 //!< Venous Whole blood.
+#define NRF_BLE_CGMS_MEAS_TYPE_VEN_PLASMA 0x04 //!< Venous Plasma.
+#define NRF_BLE_CGMS_MEAS_TYPE_ART_BLOOD 0x05 //!< Arterial Whole blood.
+#define NRF_BLE_CGMS_MEAS_TYPE_ART_PLASMA 0x06 //!< Arterial Plasma.
+#define NRF_BLE_CGMS_MEAS_TYPE_UNDET_BLOOD 0x07 //!< Undetermined Whole blood.
+#define NRF_BLE_CGMS_MEAS_TYPE_UNDET_PLASMA 0x08 //!< Undetermined Plasma.
+#define NRF_BLE_CGMS_MEAS_TYPE_FLUID 0x09 //!< Interstitial Fluid (ISF).
+#define NRF_BLE_CGMS_MEAS_TYPE_CONTROL 0x0A //!< Control Solution.
+/** @} */
+
+/**@name CGM sample location
+ * @{ */
+#define NRF_BLE_CGMS_MEAS_LOC_FINGER 0x01 //!< Finger.
+#define NRF_BLE_CGMS_MEAS_LOC_AST 0x02 //!< Alternate Site Test (AST).
+#define NRF_BLE_CGMS_MEAS_LOC_EAR 0x03 //!< Earlobe.
+#define NRF_BLE_CGMS_MEAS_LOC_CONTROL 0x04 //!< Control solution.
+#define NRF_BLE_CGMS_MEAS_LOC_SUB_TISSUE 0x05 //!< Subcutaneous tissue.
+#define NRF_BLE_CGMS_MEAS_LOC_NOT_AVAIL 0x0F //!< Sample Location value not available.
+/** @} */
+
+/**@name CGM Measurement Sensor Status Annunciation
+ * @{ */
+#define NRF_BLE_CGMS_STATUS_SESSION_STOPPED (0x01 << 0) //!< Status: Session Stopped.
+#define NRF_BLE_CGMS_STATUS_DEVICE_BATTERY_LOW (0x01 << 1) //!< Status: Device Battery Low.
+#define NRF_BLE_CGMS_STATUS_SENSOR_TYPE_INCORRECT_FOR_DEVICE (0x01 << 2) //!< Status: Sensor type incorrect for device.
+#define NRF_BLE_CGMS_STATUS_SENSOR_MALFUNCTION (0x01 << 3) //!< Status: Sensor malfunction.
+#define NRF_BLE_CGMS_STATUS_DEVICE_SPECIFIC_ALERT (0x01 << 4) //!< Status: Device Specific Alert.
+#define NRF_BLE_CGMS_STATUS_GENERAL_DEVICE_FAULT (0x01 << 5) //!< Status: General device fault has occurred in the sensor.
+/** @} */
+
+/**@name CGM Measurement flags
+ * @{ */
+#define NRF_BLE_CGMS_FLAG_TREND_INFO_PRESENT 0x01 //!< CGM Trend Information Present.
+#define NRF_BLE_CGMS_FLAGS_QUALITY_PRESENT 0x02 //!< CGM Quality Present.
+#define NRF_BLE_CGMS_STATUS_FLAGS_WARNING_OCT_PRESENT 0x20 //!< Sensor Status Annunciation Field, Warning-Octet present.
+#define NRF_BLE_CGMS_STATUS_FLAGS_CALTEMP_OCT_PRESENT 0x40 //!< Sensor Status Annunciation Field, Cal/Temp-Octet present.
+#define NRF_BLE_CGMS_STATUS_FLAGS_STATUS_OCT_PRESENT 0x80 //!< Sensor Status Annunciation Field, Status-Octet present.
+/** @} */
+
+/**@name Byte length of various commands (used for validating, encoding, and decoding data).
+ * @{ */
+#define NRF_BLE_CGMS_MEAS_OP_LEN 1 //!< Length of the opcode inside the Glucose Measurement packet.
+#define NRF_BLE_CGMS_MEAS_HANDLE_LEN 2 //!< Length of the handle inside the Glucose Measurement packet.
+#define NRF_BLE_CGMS_MEAS_LEN_MAX (BLE_GATT_ATT_MTU_DEFAULT - \
+ NRF_BLE_CGMS_MEAS_OP_LEN - \
+ NRF_BLE_CGMS_MEAS_HANDLE_LEN) //!< Maximum size of a transmitted Glucose Measurement.
+
+#define NRF_BLE_CGMS_MEAS_REC_LEN_MAX 15 //!< Maximum length of one measurement record. Size 1 byte, flags 1 byte, glucose concentration 2 bytes, offset 2 bytes, status 3 bytes, trend 2 bytes, quality 2 bytes, CRC 2 bytes.
+#define NRF_BLE_CGMS_MEAS_REC_LEN_MIN 6 //!< Minimum length of one measurement record. Size 1 byte, flags 1 byte, glucose concentration 2 bytes, offset 2 bytes.
+#define NRF_BLE_CGMS_MEAS_REC_PER_NOTIF_MAX (NRF_BLE_CGMS_MEAS_LEN_MAX / \
+ NRF_BLE_CGMS_MEAS_REC_LEN_MIN) //!< Maximum number of records per notification. We can send more than one measurement record per notification, but we do not want a a single record split over two notifications.
+
+#define NRF_BLE_CGMS_SOCP_RESP_CODE_LEN 2 //!< Length of a response. Response code 1 byte, response value 1 byte.
+#define NRF_BLE_CGMS_FEATURE_LEN 6 //!< Length of a feature. Feature 3 bytes, type 4 bits, sample location 4 bits, CRC 2 bytes.
+#define NRF_BLE_CGMS_STATUS_LEN 7 //!< Length of a status. Offset 2 bytes, status 3 bytes, CRC 2 bytes.
+#define NRF_BLE_CGMS_MAX_CALIB_LEN 10 //!< Length of a calibration record. Concentration 2 bytes, time 2 bytes, calibration 4 bits, calibration sample location 4 bits, next calibration time 2 bytes, record number 2 bytes, calibration status 1 byte.
+#define NRF_BLE_CGMS_CALIBS_NB_MAX 5 //!< Maximum number of calibration values that can be stored.
+#define NRF_BLE_CGMS_SST_LEN 9 //!< Length of the start time. Date time 7 bytes, time zone 1 byte, DST 1 byte.
+#define NRF_BLE_CGMS_CRC_LEN 2 //!< Length of the CRC bytes (if used).
+#define NRF_BLE_CGMS_SRT_LEN 2 //!< Length of the Session Run Time attribute.
+
+#define NRF_BLE_CGMS_SOCP_RESP_LEN (NRF_BLE_CGMS_MEAS_LEN_MAX - \
+ NRF_BLE_CGMS_SOCP_RESP_CODE_LEN) //!< Max lenth of a SOCP response.
+
+#define NRF_BLE_CGMS_RACP_PENDING_OPERANDS_MAX 2 // !< Maximum number of pending Record Access Control Point operations.
+/** @} */
+
+/**
+ * @defgroup nrf_ble_cgms_enums Enumerations
+ * @{
+ */
+
+/**@brief CGM Service events. */
+typedef enum
+{
+ NRF_BLE_CGMS_EVT_NOTIFICATION_ENABLED, /**< Glucose value notification enabled. */
+ NRF_BLE_CGMS_EVT_NOTIFICATION_DISABLED, /**< Glucose value notification disabled. */
+ NRF_BLE_CGMS_EVT_START_SESSION, /**< Glucose value notification start session. */
+ NRF_BLE_CGMS_EVT_STOP_SESSION, /**< Glucose value notification stop session. */
+ NRF_BLE_CGMS_EVT_WRITE_COMM_INTERVAL, /**< Glucose value write communication interval. */
+} nrf_ble_cgms_evt_type_t;
+
+
+/**@brief CGM Service communication states. */
+typedef enum
+{
+ STATE_NO_COMM, /**< The service is not in a communicating state. */
+ STATE_RACP_PROC_ACTIVE, /**< Processing requested data. */
+ STATE_RACP_RESPONSE_PENDING, /**< There is an RACP indication waiting to be sent. */
+ STATE_RACP_RESPONSE_IND_VERIF, /**< Waiting for a verification of an RACP indication. */
+ STATE_SOCP_RESPONSE_PENDING, /**< There is an SOCP indication waiting to be sent. */
+ STATE_SOCP_RESPONSE_IND_VERIF /**< Waiting for a verification of an SOCP indication. */
+} nrf_ble_cgms_com_state_t;
+
+/** @} */ // End tag for Enumeration group.
+
+/**
+ * @defgroup nrf_ble_cgms_structs Structures
+ * @{
+ */
+
+/**@brief CGM Service event. */
+typedef struct
+{
+ nrf_ble_cgms_evt_type_t evt_type; /**< Type of event. */
+} nrf_ble_cgms_evt_t;
+
+/** @} */ // End tag for Structure group.
+
+/**
+ * @defgroup nrf_ble_cgms_types Types
+ * @{
+ */
+
+/**@brief Forward declaration of the nrf_ble_cgms_t type. */
+typedef struct ble_cgms_s nrf_ble_cgms_t;
+
+
+/**@brief CGM Service event handler type. */
+typedef void (* ble_cgms_evt_handler_t) (nrf_ble_cgms_t * p_cgms, nrf_ble_cgms_evt_t * p_evt);
+
+/** @} */ // End tag for Types group.
+
+/**
+ * @addtogroup nrf_ble_cgms_structs
+ * @{
+ */
+
+/**@brief CGM Measurement Sensor Status Annunciation. */
+typedef struct
+{
+ uint8_t warning; /**< Warning annunciation. */
+ uint8_t calib_temp; /**< Calibration and Temperature annunciation. */
+ uint8_t status; /**< Status annunciation. */
+} nrf_ble_cgms_sensor_annunc_t;
+
+
+/**@brief CGM measurement. */
+typedef struct
+{
+ uint8_t flags; /**< Indicates the presence of optional fields and the Sensor Status Annunciation field. */
+ uint16_t glucose_concentration; /**< Glucose concentration. 16-bit word comprising 4-bit exponent and signed 12-bit mantissa. */
+ uint16_t time_offset; /**< Time offset. Represents the time difference between measurements. */
+ nrf_ble_cgms_sensor_annunc_t sensor_status_annunciation; /**< Sensor Status Annunciation. Variable length, can include Status, Cal/Temp, and Warning. */
+ uint16_t trend; /**< Optional field that can include Trend Information. */
+ uint16_t quality; /**< Optional field that includes the Quality of the measurement. */
+} nrf_ble_cgms_meas_t;
+
+
+/**@brief CGM Measurement record. */
+typedef struct
+{
+ nrf_ble_cgms_meas_t meas; /**< CGM measurement. */
+} ble_cgms_rec_t;
+
+
+/**@brief Features supported by the CGM Service. */
+typedef struct
+{
+ uint32_t feature; /**< Information on supported features in the CGM Service. */
+ uint8_t type; /**< Type. */
+ uint8_t sample_location; /**< Sample location. */
+}nrf_ble_cgms_feature_t;
+
+
+/**@brief Status of the CGM measurement. */
+typedef struct
+{
+ uint16_t time_offset; /**< Time offset. */
+ nrf_ble_cgms_sensor_annunc_t status; /**< Status. */
+} nrf_ble_cgm_status_t;
+
+
+/**@brief CGM Service initialization structure that contains all options and data needed for
+ * initializing the service. */
+typedef struct
+{
+ ble_cgms_evt_handler_t evt_handler; /**< Event handler to be called for handling events in the CGM Service. */
+ ble_srv_error_handler_t error_handler; /**< Function to be called when an error occurs. */
+ nrf_ble_cgms_feature_t feature; /**< Features supported by the service. */
+ nrf_ble_cgm_status_t initial_sensor_status; /**< Sensor status. */
+ uint16_t initial_run_time; /**< Run time. */
+} nrf_ble_cgms_init_t;
+
+
+/**@brief Specific Operation Control Point response structure. */
+typedef struct
+{
+ uint8_t opcode; /**< Opcode describing the response. */
+ uint8_t req_opcode; /**< The original opcode for the request to which this response belongs. */
+ uint8_t rsp_code; /**< Response code. */
+ uint8_t resp_val[NRF_BLE_CGMS_SOCP_RESP_LEN]; /**< Array containing the response value. */
+ uint8_t size_val; /**< Length of the response value. */
+} ble_socp_rsp_t;
+
+
+/**@brief Calibration value. */
+typedef struct
+{
+ uint8_t value[NRF_BLE_CGMS_MAX_CALIB_LEN]; /**< Array containing the calibration value. */
+} nrf_ble_cgms_calib_t;
+
+
+/**@brief Record Access Control Point transaction data. */
+typedef struct
+{
+ uint8_t racp_proc_operator; /**< Operator of the current request. */
+ uint16_t racp_proc_record_ndx; /**< Current record index. */
+ uint16_t racp_proc_records_ndx_last_to_send; /**< The last record to send, can be used together with racp_proc_record_ndx to determine a range of records to send. (used by greater/less filters). */
+ uint16_t racp_proc_records_reported; /**< Number of reported records. */
+ uint16_t racp_proc_records_reported_since_txcomplete; /**< Number of reported records since the last TX_COMPLETE event. */
+ ble_racp_value_t racp_request; /**< RACP procedure that has been requested from the peer. */
+ ble_racp_value_t pending_racp_response; /**< RACP response to be sent. */
+ uint8_t pending_racp_response_operand[NRF_BLE_CGMS_RACP_PENDING_OPERANDS_MAX]; /**< Operand of the RACP response to be sent. */
+} nrf_ble_cgms_racp_t;
+
+
+/** @brief Handles related to CGM characteristics. */
+typedef struct
+{
+ ble_gatts_char_handles_t measurment; /**< Handles related to the CGM Measurement characteristic. */
+ ble_gatts_char_handles_t feature; /**< Handles related to the CGM Feature characteristic. */
+ ble_gatts_char_handles_t sst; /**< Handles related to the CGM Session Start Time characteristic. */
+ ble_gatts_char_handles_t racp; /**< Handles related to the CGM Record Access Control Point characteristic. */
+ ble_gatts_char_handles_t srt; /**< Handles related to the CGM Session Run Time characteristic. */
+ ble_gatts_char_handles_t socp; /**< Handles related to the CGM Specific Operations Control Point characteristic. */
+ ble_gatts_char_handles_t status; /**< Handles related to the CGM Status characteristic. */
+} nrf_ble_cgms_char_handler_t;
+
+
+/**@brief Status information for the CGM Service. */
+struct ble_cgms_s
+{
+ ble_cgms_evt_handler_t evt_handler; /**< Event handler to be called for handling events in the CGM Service. */
+ ble_srv_error_handler_t error_handler; /**< Function to be called if an error occurs. */
+ uint16_t service_handle; /**< Handle of the CGM Service (as provided by the BLE stack). */
+ nrf_ble_cgms_char_handler_t char_handles; /**< GATTS characteristic handles for the different characteristics in the service. */
+ uint16_t conn_handle; /**< Handle of the current connection (as provided by the BLE stack; @ref BLE_CONN_HANDLE_INVALID if not in a connection). */
+ nrf_ble_cgms_feature_t feature; /**< Structure to store the value of the feature characteristic. */
+ uint8_t comm_interval; /**< Variable to keep track of the communication interval. */
+ ble_socp_rsp_t socp_response; /**< Structure containing reponse data to be indicated to the peer device. */
+ nrf_ble_cgms_calib_t calibration_val[NRF_BLE_CGMS_CALIBS_NB_MAX]; /**< Calibration value. Can be read from and written to SOCP. */
+ bool is_session_started; /**< Indicator if we are currently in a session. */
+ uint8_t nb_run_session; /**< Variable to keep track of the number of sessions that were run. */
+ uint16_t session_run_time; /**< Variable to store the expected run time of a session. */
+ nrf_ble_cgm_status_t sensor_status; /**< Structure to keep track of the sensor status. */
+ nrf_ble_cgms_com_state_t cgms_com_state; /**< Current communication state. */
+ nrf_ble_cgms_racp_t racp_data; /**< Structure to manage Record Access requests. */
+};
+
+/** @} */
+
+
+/**
+ * @defgroup nrf_ble_cgms_functions Functions
+ * @{
+ */
+
+/**@brief Function for updating the status.
+ *
+ * @param[in] p_cgms Instance of the CGM Service.
+ * @param[in] p_status New status.
+ *
+ * @retval NRF_SUCCESS If the status was updated successfully.
+ * @return If functions from other modules return errors to this function,
+ * the @ref nrf_error are propagated.
+ */
+ret_code_t nrf_ble_cgms_update_status(nrf_ble_cgms_t * p_cgms, nrf_ble_cgm_status_t * p_status);
+
+
+/**@brief Function for initializing the CGM Service.
+ *
+ * @param[out] p_cgms CGM Service structure. This structure must be supplied by
+ * the application. It is initialized by this function and will later
+ * be used to identify this particular service instance.
+ * @param[in] p_cgms_init Information needed to initialize the service.
+ *
+ * @retval NRF_SUCCESS If the service was initialized successfully.
+ * @retval NRF_ERROR_NULL If any of the input parameters are NULL.
+ * @return If functions from other modules return errors to this function,
+ * the @ref nrf_error are propagated.
+ */
+ret_code_t nrf_ble_cgms_init(nrf_ble_cgms_t * p_cgms, const nrf_ble_cgms_init_t * p_cgms_init);
+
+
+/**@brief Function for handling the application's BLE stack events.
+ *
+ * @details Handles all events from the BLE stack that are of interest to the CGM Service.
+ *
+ * @param[in] p_ble_evt Event received from the BLE stack.
+ * @param[in] p_context Instance of the CGM Service.
+ */
+void nrf_ble_cgms_on_ble_evt(ble_evt_t const * p_ble_evt, void * p_context);
+
+
+/**@brief Function for reporting a new glucose measurement to the CGM Service module.
+ *
+ * @details The application calls this function after having performed a new glucose measurement.
+ * The new measurement is recorded in the RACP database.
+ *
+ * @param[in] p_cgms Instance of the CGM Service.
+ * @param[in] p_rec Pointer to the glucose record (measurement plus context).
+ *
+ * @retval NRF_SUCCESS If a measurement was successfully created.
+ * @return If functions from other modules return errors to this function,
+ * the @ref nrf_error are propagated.
+ */
+ret_code_t nrf_ble_cgms_meas_create(nrf_ble_cgms_t * p_cgms, ble_cgms_rec_t * p_rec);
+
+
+/**@brief Function for assigning a connection handle to a CGM Service instance.
+ *
+ * @param[in] p_cgms Instance of the CGM Service.
+ * @param[in] conn_handle Connection Handle to use for this instance of the CGM Service.
+ *
+ * @retval NRF_SUCCESS If the connection handle was successfully stored in the CGM Service instance.
+ * @retval NRF_ERROR_NULL If any of the input parameters are NULL.
+ */
+ret_code_t nrf_ble_cgms_conn_handle_assign(nrf_ble_cgms_t * p_cgms, uint16_t conn_handle);
+
+
+/**@brief Function for setting the Session Run Time attribute value.
+ *
+ * @param[in] p_cgms Instance of the CGM Service.
+ * @param[in] run_time Run Time that will be displayed in the Session Run Time
+ * attribute value.
+ *
+ * @retval NRF_SUCCESS If the Session Run Time attribute value was set successfully.
+ * @return If functions from other modules return errors to this function,
+ * the @ref nrf_error are propagated.
+ */
+ret_code_t nrf_ble_cgms_srt_set(nrf_ble_cgms_t * p_cgms, uint16_t run_time);
+
+/** @} */ // End tag for Function group.
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // NRF_BLE_CGMS_H__
+
+/** @} */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/experimental_nrf_ble_ots_c/nrf_ble_ots_c.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/experimental_nrf_ble_ots_c/nrf_ble_ots_c.c
new file mode 100644
index 0000000..aa5c6ee
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/experimental_nrf_ble_ots_c/nrf_ble_ots_c.c
@@ -0,0 +1,374 @@
+/**
+ * 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+
+#include "sdk_common.h"
+#if NRF_MODULE_ENABLED(BLE_OTS_C)
+#include <stdlib.h>
+#include "nrf_ble_ots_c.h"
+#include "nrf_ble_ots_c_oacp.h"
+#include "nrf_ble_ots_c_l2cap.h"
+#include "ble.h"
+
+#define NRF_LOG_MODULE_NAME ble_ots_c
+#include "nrf_log.h"
+NRF_LOG_MODULE_REGISTER();
+
+#include "sdk_common.h"
+
+
+#define BLE_OTS_OACP_SUPPORT_FEATURE_CREATE_bp 0
+#define BLE_OTS_OACP_SUPPORT_FEATURE_DELETE_bp 1
+#define BLE_OTS_OACP_SUPPORT_FEATURE_CALC_CHECKSUM_bp 2
+#define BLE_OTS_OACP_SUPPORT_FEATURE_EXECUTE_bp 3
+#define BLE_OTS_OACP_SUPPORT_FEATURE_READ_bp 4
+#define BLE_OTS_OACP_SUPPORT_FEATURE_WRITE_bp 5
+#define BLE_OTS_OACP_SUPPORT_FEATURE_APPEND_bp 6
+#define BLE_OTS_OACP_SUPPORT_FEATURE_TRUNCATE_bp 7
+#define BLE_OTS_OACP_SUPPORT_FEATURE_PATCH_bp 8
+#define BLE_OTS_OACP_SUPPORT_FEATURE_ABORT_bp 9
+
+#define BLE_OTS_OLCP_SUPPORT_FEATURE_GOTO_bp 0
+#define BLE_OTS_OLCP_SUPPORT_FEATURE_ORDER_bp 1
+#define BLE_OTS_OLCP_SUPPORT_FEATURE_REQ_NUM_OBJECTS_bp 2
+#define BLE_OTS_OLCP_SUPPORT_FEATURE_CLEAR_MARKING_bp 3
+
+#define MODULE_INITIALIZED (p_ots_c->initialized) /**< Macro designating whether the module has been initialized properly. */
+
+static const ble_uuid_t m_ots_uuid = {BLE_UUID_OTS_SERVICE, BLE_UUID_TYPE_BLE}; /**< Object Transfer Service UUID. */
+
+
+ret_code_t nrf_ble_ots_c_init(nrf_ble_ots_c_t * p_ots_c,
+ nrf_ble_ots_c_init_t * p_ots_c_init)
+{
+ ret_code_t err_code = NRF_SUCCESS;
+ VERIFY_PARAM_NOT_NULL(p_ots_c);
+ VERIFY_PARAM_NOT_NULL(p_ots_c_init);
+ VERIFY_PARAM_NOT_NULL(p_ots_c_init->evt_handler);
+ memset (p_ots_c, 0, sizeof(nrf_ble_ots_c_t));
+
+ p_ots_c->conn_handle = BLE_CONN_HANDLE_INVALID;
+ p_ots_c->evt_handler = p_ots_c_init->evt_handler;
+
+ err_code = ble_db_discovery_evt_register(&m_ots_uuid);
+ VERIFY_SUCCESS(err_code);
+
+ p_ots_c->initialized = true;
+ return err_code;
+}
+
+
+/**@brief Function for checking whether the peer's Object Transfer Service instance has been discovered.
+
+ @param[in] p_ots_c Pointer to the GATT Service client structure instance.
+
+ @return True if the Object Transfer service handles are valid.
+ @return False if the Object Transfer service handles are invalid
+ */
+static bool ots_gatt_handles_are_valid(const nrf_ble_ots_c_t * const p_ots_c)
+{
+ return (p_ots_c->service.object_prop_char.handle_value != BLE_GATT_HANDLE_INVALID
+ && p_ots_c->service.object_size_char.handle_value != BLE_GATT_HANDLE_INVALID
+ && p_ots_c->service.object_type_char.handle_value != BLE_GATT_HANDLE_INVALID
+ && p_ots_c->service.ots_feature_char.handle_value != BLE_GATT_HANDLE_INVALID);
+}
+
+
+ret_code_t nrf_ble_ots_c_feature_read(nrf_ble_ots_c_t * const p_ots_c)
+{
+ VERIFY_MODULE_INITIALIZED();
+
+ ret_code_t err_code;
+ err_code = sd_ble_gattc_read(p_ots_c->conn_handle,
+ p_ots_c->service.ots_feature_char.handle_value,
+ 0);
+ return err_code;
+}
+
+
+ret_code_t nrf_ble_ots_c_obj_size_read(nrf_ble_ots_c_t * const p_ots_c)
+{
+ VERIFY_MODULE_INITIALIZED();
+
+ if( p_ots_c->service.object_size_char.handle_value == BLE_GATT_HANDLE_INVALID)
+ {
+ return NRF_ERROR_INVALID_STATE;
+ }
+ ret_code_t err_code;
+ err_code = sd_ble_gattc_read(p_ots_c->conn_handle,
+ p_ots_c->service.object_size_char.handle_value,
+ 0);
+ return err_code;
+}
+
+/**@brief Function for handling read response events.
+ *
+ * @details This function will validate the read response and raise the appropriate
+ * event to the application.
+ *
+ * @param[in] p_bas_c Pointer to the Battery Service Client Structure.
+ * @param[in] p_ble_evt Pointer to the SoftDevice event.
+ */
+static void on_read_rsp(nrf_ble_ots_c_t * p_ots_c, const ble_evt_t * p_ble_evt)
+{
+ const ble_gattc_evt_read_rsp_t * p_response;
+
+ // Check if the event is on the link for this instance
+ if (p_ots_c->conn_handle != p_ble_evt->evt.gattc_evt.conn_handle)
+ {
+ return;
+ }
+
+ p_response = &p_ble_evt->evt.gattc_evt.params.read_rsp;
+
+ if (p_response->handle == p_ots_c->service.ots_feature_char.handle_value)
+ {
+ nrf_ble_ots_c_evt_t evt;
+
+ evt.conn_handle = p_ble_evt->evt.gattc_evt.conn_handle;
+ evt.evt_type = NRF_BLE_OTS_C_EVT_FEATURE_READ_RESP;
+
+ uint32_t oacp_features;
+ oacp_features = uint32_decode(&p_response->data[0]);
+ evt.params.feature.oacp_create = oacp_features >> BLE_OTS_OACP_SUPPORT_FEATURE_CREATE_bp;
+ evt.params.feature.oacp_delete = oacp_features >> BLE_OTS_OACP_SUPPORT_FEATURE_DELETE_bp;
+ evt.params.feature.oacp_crc = oacp_features >> BLE_OTS_OACP_SUPPORT_FEATURE_CALC_CHECKSUM_bp;
+ evt.params.feature.oacp_execute = oacp_features >> BLE_OTS_OACP_SUPPORT_FEATURE_EXECUTE_bp;
+ evt.params.feature.oacp_read = oacp_features >> BLE_OTS_OACP_SUPPORT_FEATURE_READ_bp;
+ evt.params.feature.oacp_write = oacp_features >> BLE_OTS_OACP_SUPPORT_FEATURE_WRITE_bp;
+ evt.params.feature.oacp_append = oacp_features >> BLE_OTS_OACP_SUPPORT_FEATURE_APPEND_bp;
+ evt.params.feature.oacp_truncate = oacp_features >> BLE_OTS_OACP_SUPPORT_FEATURE_TRUNCATE_bp;
+ evt.params.feature.oacp_patch = oacp_features >> BLE_OTS_OACP_SUPPORT_FEATURE_PATCH_bp;
+ evt.params.feature.oacp_abort = oacp_features >> BLE_OTS_OACP_SUPPORT_FEATURE_ABORT_bp;
+
+ uint32_t olcp_features;
+/*lint --e{415} --e{416} -save suppress Warning 415: Likely access of out-of-bounds pointer */
+ olcp_features = uint32_decode(&p_response->data[sizeof(uint32_t)]);
+/*lint -restore*/
+ evt.params.feature.olcp_goto = olcp_features >> BLE_OTS_OLCP_SUPPORT_FEATURE_GOTO_bp;
+ evt.params.feature.olcp_order = olcp_features >> BLE_OTS_OLCP_SUPPORT_FEATURE_ORDER_bp;
+ evt.params.feature.olcp_req_num = olcp_features >> BLE_OTS_OLCP_SUPPORT_FEATURE_REQ_NUM_OBJECTS_bp;
+ evt.params.feature.olcp_clear = olcp_features >> BLE_OTS_OLCP_SUPPORT_FEATURE_CLEAR_MARKING_bp;
+
+ p_ots_c->evt_handler(&evt);
+ }
+ if (p_response->handle == p_ots_c->service.object_size_char.handle_value)
+ {
+ nrf_ble_ots_c_evt_t evt;
+
+ evt.conn_handle = p_ble_evt->evt.gattc_evt.conn_handle;
+ evt.evt_type = NRF_BLE_OTS_C_EVT_SIZE_READ_RESP;
+
+ uint8_t len = 0;
+ evt.params.size.current_size = uint32_decode(&p_response->data[len]);
+ len += sizeof(uint32_t);
+/*lint --e{415} --e{416} -save suppress Warning 415: Likely access of out-of-bounds pointer */
+ evt.params.size.allocated_size = uint32_decode(&p_response->data[len]);
+/*lint -restore*/
+
+/*lint --e{438} -save */
+ len += sizeof(uint32_t);
+/*lint -restore*/
+
+ p_ots_c->evt_handler(&evt);
+ }
+}
+
+
+void nrf_ble_ots_c_on_db_disc_evt(nrf_ble_ots_c_t const * const p_ots_c,
+ ble_db_discovery_evt_t * const p_evt)
+{
+ VERIFY_MODULE_INITIALIZED_VOID();
+
+ nrf_ble_ots_c_evt_t evt;
+ ble_gatt_db_char_t* p_chars;
+
+ p_chars = p_evt->params.discovered_db.charateristics;
+ evt.evt_type = NRF_BLE_OTS_C_EVT_DISCOVERY_FAILED;
+
+ if ((p_evt->evt_type == BLE_DB_DISCOVERY_COMPLETE) &&
+ (p_evt->params.discovered_db.srv_uuid.uuid == BLE_UUID_OTS_SERVICE) &&
+ (p_evt->params.discovered_db.srv_uuid.type == BLE_UUID_TYPE_BLE))
+ {
+ // Find the handles of the ANCS characteristic.
+ for (uint32_t i = 0; i < p_evt->params.discovered_db.char_count; i++)
+ {
+ switch (p_chars[i].characteristic.uuid.uuid)
+ {
+ case BLE_UUID_OTS_FEATURES:
+ NRF_LOG_DEBUG("OTS Feature Characteristic found.\r\n");
+ memcpy(&evt.params.handles.ots_feature_char,
+ &p_chars[i].characteristic,
+ sizeof(ble_gattc_char_t));
+ break;
+
+ case BLE_UUID_OTS_OBJECT_NAME:
+ NRF_LOG_DEBUG("Object Name Characteristic found.\r\n");
+ memcpy(&evt.params.handles.object_name_char,
+ &p_chars[i].characteristic,
+ sizeof(ble_gattc_char_t));
+ break;
+
+ case BLE_UUID_OTS_OBJECT_TYPE:
+ NRF_LOG_DEBUG("Object Type Characteristic found.\r\n");
+ memcpy(&evt.params.handles.object_type_char,
+ &p_chars[i].characteristic,
+ sizeof(ble_gattc_char_t));
+ break;
+
+ case BLE_UUID_OTS_OBJECT_SIZE:
+ NRF_LOG_DEBUG("Object Size Characteristic found.\r\n");
+ memcpy(&evt.params.handles.object_size_char,
+ &p_chars[i].characteristic,
+ sizeof(ble_gattc_char_t));
+ break;
+
+ case BLE_UUID_OTS_OBJECT_PROPERTIES:
+ NRF_LOG_DEBUG("Object Properties Characteristic found.\r\n");
+ memcpy(&evt.params.handles.object_prop_char,
+ &p_chars[i].characteristic,
+ sizeof(ble_gattc_char_t));
+ break;
+
+ case BLE_UUID_OTS_OACP:
+ NRF_LOG_DEBUG("Object Action Control Point found. CCCD Handle %x\r\n", p_chars[i].cccd_handle);
+ memcpy(&evt.params.handles.object_action_cp_char,
+ &p_chars[i].characteristic,
+ sizeof(ble_gattc_char_t));
+ evt.params.handles.object_action_cp_cccd.handle = p_chars[i].cccd_handle;
+ break;
+
+ default:
+ break;
+ }
+ }
+ evt.evt_type = NRF_BLE_OTS_C_EVT_DISCOVERY_COMPLETE;
+ evt.conn_handle = p_evt->conn_handle;
+ p_ots_c->evt_handler(&evt);
+ }
+ else
+ {
+ evt.evt_type = NRF_BLE_OTS_C_EVT_DISCOVERY_FAILED;
+ p_ots_c->evt_handler(&evt);
+ }
+}
+
+
+/**@brief Function for handling the Disconnect event.
+
+ @param[in] p_cts Pointer to the GATT Service client structure instance.
+ @param[in] p_ble_evt Event received from the BLE stack.
+ */
+static void on_disconnect(nrf_ble_ots_c_t * const p_ots_c, ble_evt_t const * const p_ble_evt)
+{
+ if (p_ots_c->conn_handle == p_ble_evt->evt.gap_evt.conn_handle)
+ {
+ p_ots_c->conn_handle = BLE_CONN_HANDLE_INVALID;
+
+ if (ots_gatt_handles_are_valid(p_ots_c))
+ {
+ // There was a valid instance of ots on the peer. Send an event to the
+ // application, so that it can do any clean up related to this module.
+ nrf_ble_ots_c_evt_t evt;
+
+ evt.evt_type = NRF_BLE_OTS_C_EVT_DISCONN_COMPLETE;
+
+ p_ots_c->evt_handler(&evt);
+ memset(&p_ots_c->service, 0, sizeof(nrf_ble_ots_c_service_t));
+ }
+ }
+}
+
+
+void nrf_ble_ots_c_on_ble_evt(ble_evt_t const * const p_ble_evt,
+ void * p_context)
+{
+ nrf_ble_ots_c_t * p_ots_c;
+ p_ots_c = (nrf_ble_ots_c_t*) p_context;
+
+ VERIFY_MODULE_INITIALIZED_VOID();
+ VERIFY_PARAM_NOT_NULL_VOID(p_ots_c);
+ VERIFY_PARAM_NOT_NULL_VOID(p_ble_evt);
+
+ switch (p_ble_evt->header.evt_id)
+ {
+ case BLE_GAP_EVT_DISCONNECTED:
+ on_disconnect(p_ots_c, p_ble_evt);
+ break;
+
+ case BLE_GATTC_EVT_READ_RSP:
+ on_read_rsp(p_ots_c, p_ble_evt);
+ break;
+
+ case BLE_GATTC_EVT_WRITE_RSP:
+ //on_write_rsp()
+ NRF_LOG_DEBUG("error handle write response: %x\r\n", p_ble_evt->evt.gattc_evt.error_handle);
+ break;
+
+ default:
+ break;
+ }
+ ots_c_l2cap_on_ble_evt(p_ots_c, p_ble_evt);
+ ots_c_oacp_on_ble_evt(p_ots_c, p_ble_evt);
+}
+
+
+ret_code_t nrf_ble_ots_c_handles_assign(nrf_ble_ots_c_t * const p_ots_c,
+ uint16_t const conn_handle,
+ nrf_ble_ots_c_service_t const * const p_peer_handles)
+{
+ VERIFY_MODULE_INITIALIZED();
+ VERIFY_PARAM_NOT_NULL(p_ots_c);
+
+ p_ots_c->conn_handle = conn_handle;
+ if (p_peer_handles != NULL)
+ {
+ p_ots_c->service.ots_feature_char.handle_value = p_peer_handles->ots_feature_char.handle_value;
+ p_ots_c->service.object_type_char.handle_value = p_peer_handles->object_type_char.handle_value;
+ p_ots_c->service.object_size_char.handle_value = p_peer_handles->object_size_char.handle_value;
+ p_ots_c->service.object_prop_char.handle_value = p_peer_handles->object_prop_char.handle_value;
+ p_ots_c->service.object_action_cp_char.handle_value = p_peer_handles->object_action_cp_char.handle_value;
+ p_ots_c->service.object_action_cp_cccd.handle = p_peer_handles->object_action_cp_cccd.handle;
+
+ }
+ return NRF_SUCCESS;
+}
+
+
+#endif // NRF_MODULE_ENABLED(BLE_OTS_C)
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/experimental_nrf_ble_ots_c/nrf_ble_ots_c.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/experimental_nrf_ble_ots_c/nrf_ble_ots_c.h
new file mode 100644
index 0000000..01e13ba
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/experimental_nrf_ble_ots_c/nrf_ble_ots_c.h
@@ -0,0 +1,320 @@
+/**
+ * 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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
+ *
+ * @defgroup nrf_ble_ots_c Object Transfer Service Client
+ * @{
+ * @ingroup ble_sdk_srv
+ * @brief Object Transfer Service client module
+ *
+ * @details This is the main module of the Object Transfer Service (OTS) client.
+ */
+
+#ifndef NRF_BLE_OTS_C_H__
+#define NRF_BLE_OTS_C_H__
+
+#include <stdint.h>
+#include "ble_gattc.h"
+#include "ble.h"
+#include "nrf_error.h"
+#include "ble_srv_common.h"
+#include "ble_db_discovery.h"
+#include "sdk_errors.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**@brief Macro for defining a ble_ots instance.
+ *
+ * @param _name Name of the instance.
+ * @hideinitializer
+ */
+#define NRF_BLE_OTS_C_DEF(_name) \
+static nrf_ble_ots_c_t _name; \
+NRF_SDH_BLE_OBSERVER(_name ## _ble_obs, \
+ BLE_OTS_C_BLE_OBSERVER_PRIO, \
+ nrf_ble_ots_c_on_ble_evt, &_name) \
+
+/** @brief Macro for defining multiple ble_ots instances.
+ *
+ * @param _name Name of the array of instances.
+ * @param _cnt Number of instances to define.
+ * @hideinitializer
+ */
+#define NRF_BLE_OTS_C_ARRAY_DEF(_name, _cnt) \
+static nrf_ble_ots_c_t _name[_cnt]; \
+NRF_SDH_BLE_OBSERVERS(_name ## _ble_obs, \
+ BLE_OTS_C_BLE_OBSERVER_PRIO, \
+ nrf_ble_ots_c_on_ble_evt, &_name, _cnt)
+
+
+/** @brief Types of Object Action Control Point Procedures. */
+typedef enum
+{
+ NRF_BLE_OTS_C_OACP_PROC_CREATE = 0x01, //!< Create object.
+ NRF_BLE_OTS_C_OACP_PROC_DELETE = 0x02, //!< Delete object.
+ NRF_BLE_OTS_C_OACP_PROC_CALC_CHKSUM = 0x03, //!< Calculate Checksum.
+ NRF_BLE_OTS_C_OACP_PROC_EXECUTE = 0x04, //!< Execute Object.
+ NRF_BLE_OTS_C_OACP_PROC_READ = 0x05, //!< Read object.
+ NRF_BLE_OTS_C_OACP_PROC_WRITE = 0x06, //!< Write object.
+ NRF_BLE_OTS_C_OACP_PROC_ABORT = 0x07, //!< Abort object.
+ NRF_BLE_OTS_C_OACP_PROC_RESP = 0x60 //!< Procedure response.
+} ble_ots_c_oacp_proc_type_t;
+
+/** @brief Object Action Control Point return codes. */
+typedef enum
+{
+ NRF_BLE_OTS_C_OACP_RES_SUCCESS = 0x01, //!< Success.
+ NRF_BLE_OTS_C_OACP_RES_OPCODE_NOT_SUP = 0x02, //!< Not supported
+ NRF_BLE_OTS_C_OACP_RES_INV_PARAM = 0x03, //!< Invalid parameter
+ NRF_BLE_OTS_C_OACP_RES_INSUFF_RES = 0x04, //!< Insufficient resources.
+ NRF_BLE_OTS_C_OACP_RES_INV_OBJ = 0x05, //!< Invalid object.
+ NRF_BLE_OTS_C_OACP_RES_CHAN_UNAVAIL = 0x06, //!< Channel unavailable.
+ NRF_BLE_OTS_C_OACP_RES_UNSUP_TYPE = 0x07, //!< Unsupported procedure.
+ NRF_BLE_OTS_C_OACP_RES_NOT_PERMITTED = 0x08, //!< Procedure not permitted.
+ NRF_BLE_OTS_C_OACP_RES_OBJ_LOCKED = 0x09, //!< Object locked.
+ NRF_BLE_OTS_C_OACP_RES_OPER_FAILED = 0x0A //!< Operation Failed.
+} ble_ots_c_oacp_res_code_t;
+
+/**@brief Type of the Object Transfer Service client event.
+ */
+typedef enum
+{
+ NRF_BLE_OTS_C_EVT_DISCOVERY_FAILED, //!< Event indicating that the Object Transfer Service has not been found on the peer.
+ NRF_BLE_OTS_C_EVT_DISCOVERY_COMPLETE, //!< Event indicating that the Object Transfer Service is present on the peer device.
+ NRF_BLE_OTS_C_EVT_DISCONN_COMPLETE, //!< Event indicating that the Object Transfer Service client module has finished processing the BLE_GAP_EVT_DISCONNECTED event. The event can be used by the application to do clean up related to the Object Transfer Service client.
+ NRF_BLE_OTS_C_EVT_FEATURE_READ_RESP, //!< Event indicating that the feature characteristic was read, The available features of the peer will be provided in the event.
+ NRF_BLE_OTS_C_EVT_OACP_RESP, //!< Event indicating that a response was received (result of a write to the OACP).
+ NRF_BLE_OTS_C_EVT_OBJ_READ, //!< Event indicating that the Object Transfer Service client finished reading object from the peer
+ NRF_BLE_OTS_C_EVT_CHANNEL_RELEASED, //!< Event indicating that the L2CAP Connection Oriented Channel has been disconnected
+ NRF_BLE_OTS_C_EVT_SIZE_READ_RESP //!< Event indicating that the object size characteristic was read.
+} nrf_ble_ots_c_evt_type_t;
+
+/** @brief Structure to hold the features of a server */
+typedef struct
+{
+ uint8_t oacp_create : 1;
+ uint8_t oacp_delete : 1;
+ uint8_t oacp_crc : 1;
+ uint8_t oacp_execute : 1;
+ uint8_t oacp_read : 1;
+ uint8_t oacp_write : 1;
+ uint8_t oacp_append : 1;
+ uint8_t oacp_truncate : 1;
+ uint8_t oacp_patch : 1;
+ uint8_t oacp_abort : 1;
+ uint8_t olcp_goto : 1;
+ uint8_t olcp_order : 1;
+ uint8_t olcp_req_num : 1;
+ uint8_t olcp_clear : 1;
+} nrf_ble_ots_c_feature_t;
+
+/**@brief Structure used for holding the Apple Notification Center Service found during the
+ discovery process.
+ */
+typedef struct
+{
+ ble_gattc_service_t service; //!< The Object Transfer Service holding the discovered Object Transfer Service. (0x1825).
+ ble_gattc_char_t ots_feature_char; //!< OTS Feature (0x2ABD)
+ ble_gattc_char_t object_name_char; //!< Object Name (0x2ABE)
+ ble_gattc_char_t object_type_char; //!< Object Type (0x2ABF)
+ ble_gattc_char_t object_size_char; //!< Object Size (0x2AC0)
+ ble_gattc_char_t object_prop_char; //!< Object Properties (0x2AC4)
+ ble_gattc_char_t object_action_cp_char; //!< Object Action Control Point (0x2AC5)
+ ble_gattc_desc_t object_action_cp_cccd; //!< Object Action Control Point Descriptor. Enables or disables Object Transfer notifications.
+} nrf_ble_ots_c_service_t;
+
+
+typedef struct
+{
+ ble_ots_c_oacp_proc_type_t request_op_code;
+ ble_ots_c_oacp_res_code_t result_code;
+} nrf_ble_ots_c_oacp_response_t;
+
+typedef struct
+{
+ uint32_t current_size;
+ uint32_t allocated_size;
+} nrf_ble_ots_c_obj_size;
+
+/**@brief Structure containing the event from the Object Transfer client module to the application.
+ */
+typedef struct
+{
+ nrf_ble_ots_c_evt_type_t evt_type; /**< Type of event. See @ref nrf_ble_ots_c_evt_type_t. */
+ uint16_t conn_handle; /**< Handle of the connection for which this event has occurred. */
+ union
+ {
+ nrf_ble_ots_c_feature_t feature; /**< Will be provided if the event type is @ref NRF_BLE_OTS_C_EVT_FEATURE_READ_RESP.*/
+ nrf_ble_ots_c_service_t handles; /**< Handles that the Object Transfer service occupies in the peer device. Will be filled if the event type is @ref NRF_BLE_OTS_C_EVT_DISCOVERY_COMPLETE.*/
+ nrf_ble_ots_c_oacp_response_t response; /**< Will be provided if the event type is @ref NRF_BLE_OTS_C_EVT_OACP_RESP. */
+ ble_data_t object; /**< Will be provided if the event type is @ref NRF_BLE_OTS_C_EVT_OBJ_READ. */
+ nrf_ble_ots_c_obj_size size; /**< Will be provided if the event type is @ref NRF_BLE_OTS_C_EVT_SIZE_READ_RESP. */
+ } params;
+} nrf_ble_ots_c_evt_t;
+
+
+/**@brief Object Transfer handler type. */
+typedef void (* nrf_ble_ots_c_evt_handler_t)(nrf_ble_ots_c_evt_t * p_evt);
+
+
+/**@brief Structure for holding the information related to the Object Transfer Service.
+
+ @warning This structure must be zero-initialized.
+*/
+typedef struct
+{
+ bool initialized; /**< Boolean telling whether the context has been initialized or not. */
+ uint16_t conn_handle; /**< Active connection handle */
+ nrf_ble_ots_c_service_t service; /**< Structure to store the different handles and UUIDs related to the service. */
+ nrf_ble_ots_c_evt_handler_t evt_handler; /**< Pointer to event handler function. */
+ ble_srv_error_handler_t err_handler; /**< Pointer to error handler function. */
+ uint16_t local_cid;
+ ble_l2cap_evt_ch_setup_t ch_setup; /**< L2CAP Channel Setup Completed Event Parameters. */
+ uint32_t current_credits;
+ uint32_t remaining_bytes;
+ uint32_t transmitted_bytes;
+ uint32_t received_bytes;
+ ble_data_t * current_obj;
+} nrf_ble_ots_c_t;
+
+
+/**@brief Initialization parameters, these must be supplied when calling @ref nrf_ble_ots_c_init. */
+typedef struct
+{
+ nrf_ble_ots_c_evt_handler_t evt_handler; /**< The event handler that is called by the Object Transfer client module when any related event occurs. */
+ ble_srv_error_handler_t err_handler; /**< the error handler that is called by the Object Transfer client module if any error occurs. */
+} nrf_ble_ots_c_init_t;
+
+/**@brief Function for initializing the Object Transfer client module.
+
+ @param[in,out] p_ots_c Pointer to the Object Transfer Service client structure instance.
+ @param[in] p_ots_c_init Init parameters contraining the event handler that is called by
+ the Object Transfer client module when any related event occurs.
+
+ @retval NRF_SUCCESS If the service was initialized successfully.
+ @retval NRF_ERROR_NULL If any of the input parameters are NULL.
+ @return If functions from other modules return errors to this function,
+ the @ref nrf_error are propagated.
+*/
+ret_code_t nrf_ble_ots_c_init(nrf_ble_ots_c_t * p_ots_c,
+ nrf_ble_ots_c_init_t * p_ots_c_init);
+
+
+/**@brief Function for handling events from the database discovery module.
+
+ @details This function will handle an event from the database discovery module, and determine
+ if it relates to the discovery of Object Transfer Service at the peer. If so,
+ it will call the application's event handler indicating that Object Transfer Service
+ has been discovered at the peer.
+
+ @param[in,out] p_ots_c Pointer to the Object Transfer Service client structure instance.
+ @param[in] p_evt Pointer to the event received from the database discovery module.
+*/
+void nrf_ble_ots_c_on_db_disc_evt(nrf_ble_ots_c_t const * const p_ots_c,
+ ble_db_discovery_evt_t * const p_evt);
+
+
+/**@brief Function for reading the features characteristic (@ref BLE_UUID_OTS_FEATURES) on the server.
+
+ @param[in,out] p_ots_c Pointer to Object Transfer client structure.
+
+ @retval NRF_SUCCESS Operation success.
+ @return If functions from other modules return errors to this function,
+ the @ref nrf_error are propagated.
+*/
+ret_code_t nrf_ble_ots_c_feature_read(nrf_ble_ots_c_t * const p_ots_c);
+
+
+/**@brief Function for reading the Object Size characteristic (@ref BLE_UUID_OTS_FEATURES) on the server.
+
+ @param[in,out] p_ots_c Pointer to Object Transfer client structure.
+
+ @retval NRF_SUCCESS Operation success.
+ @return NRF_ERROR_INVALID_STATE if the Object Size characteristic has not been discovered. If functions from other modules return errors to this function,
+ the @ref nrf_error are propagated.
+*/
+ret_code_t nrf_ble_ots_c_obj_size_read(nrf_ble_ots_c_t * const p_ots_c);
+
+
+/**@brief Function for handling the Application's BLE Stack events.
+
+ @param[in] p_ble_evt Pointer to the BLE event received.
+ @param[in,out] p_context Pointer to the Object Transfer Service client structure instance.
+*/
+void nrf_ble_ots_c_on_ble_evt(const ble_evt_t * const p_ble_evt,
+ void * p_context);
+
+
+ret_code_t nrf_ble_ots_c_obj_name_read(nrf_ble_ots_c_t * const p_ots_c, ble_data_t * p_obj);
+ret_code_t nrf_ble_ots_c_obj_name_write(nrf_ble_ots_c_t * const p_ots_c, ble_data_t * p_obj);
+ret_code_t nrf_ble_ots_c_obj_type_read(nrf_ble_ots_c_t * const p_ots_c);
+ret_code_t nrf_ble_ots_c_obj_size_read(nrf_ble_ots_c_t * const p_ots_c);
+ret_code_t nrf_ble_ots_c_obj_properties_read(nrf_ble_ots_c_t * const p_ots_c);
+
+
+/**@brief Function for assigning handles to a Object Transfer Service client instance.
+
+ @details Call this function when a link has been established with a peer to
+ associate this link to an instance of the module. This makes it
+ possible to handle several link and associate each link to a particular
+ instance of the Object Transfer Service client module. The connection handle and
+ attribute handles will be provided from the discovery event
+ @ref NRF_BLE_OTS_C_EVT_DISCOVERY_COMPLETE.
+
+ @param[in,out] p_ots_c Pointer to the Object Transfer Service client structure instance to associate
+ with the handles.
+ @param[in] conn_handle Connection handle to be associated with the given Object Transfer Service client
+ Instance.
+ @param[in] p_peer_handles Attribute handles on the Object Transfer Service server that you want this
+ Object Transfer Service client to interact with.
+
+ @retval NRF_SUCCESS If the connection handle was successfully stored in the Object Transfer Service instance.
+ @retval NRF_ERROR_NULL If any of the input parameters are NULL.
+*/
+ret_code_t nrf_ble_ots_c_handles_assign(nrf_ble_ots_c_t * const p_ots_c,
+ uint16_t const conn_handle,
+ nrf_ble_ots_c_service_t const * const p_peer_handles);
+
+#endif // NRF_BLE_OTS_C_H__
+
+/** @} */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/experimental_nrf_ble_ots_c/nrf_ble_ots_c_l2cap.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/experimental_nrf_ble_ots_c/nrf_ble_ots_c_l2cap.c
new file mode 100644
index 0000000..8509329
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/experimental_nrf_ble_ots_c/nrf_ble_ots_c_l2cap.c
@@ -0,0 +1,244 @@
+/**
+ * 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+
+#include "sdk_common.h"
+#if NRF_MODULE_ENABLED(BLE_OTS_C_L2CAP)
+#include <stdlib.h>
+#include "nrf_ble_ots_c.h"
+#include "nrf_ble_ots_c_oacp.h"
+#include "nrf_ble_ots_c_l2cap.h"
+#include "ble.h"
+
+#define NRF_LOG_MODULE_NAME ble_ots_c_l2cap
+#include "nrf_log.h"
+NRF_LOG_MODULE_REGISTER();
+
+#include "sdk_common.h"
+
+#define MODULE_INITIALIZED (p_ots_c->initialized) /**< Macro designating whether the module has been initialized properly. */
+
+
+static void on_l2cap_setup_complete(nrf_ble_ots_c_t * const p_ots_c,
+ ble_evt_t const * const p_ble_evt)
+{
+ p_ots_c->local_cid = p_ble_evt->evt.l2cap_evt.local_cid;
+ p_ots_c->ch_setup.tx_params.peer_mps = p_ble_evt->evt.l2cap_evt.params.ch_setup.tx_params.peer_mps;
+ p_ots_c->ch_setup.tx_params.tx_mps = p_ble_evt->evt.l2cap_evt.params.ch_setup.tx_params.tx_mps;
+ p_ots_c->ch_setup.tx_params.tx_mtu = p_ble_evt->evt.l2cap_evt.params.ch_setup.tx_params.tx_mtu;
+ p_ots_c->ch_setup.tx_params.credits = p_ble_evt->evt.l2cap_evt.params.ch_setup.tx_params.credits;
+ p_ots_c->current_credits = p_ots_c->ch_setup.tx_params.credits;
+}
+
+
+static void send_next_mtu(nrf_ble_ots_c_t * const p_ots_c)
+{
+ // Remaining bytes to transmit.
+ if(p_ots_c->transmitted_bytes < p_ots_c->current_obj->len)
+ {
+ ret_code_t err_code;
+ uint16_t tx_size;
+
+ tx_size = MIN((p_ots_c->current_obj->len - p_ots_c->transmitted_bytes),
+ p_ots_c->ch_setup.tx_params.tx_mtu);
+ ble_data_t obj;
+ obj.len = tx_size;
+ obj.p_data = &p_ots_c->current_obj->p_data[p_ots_c->transmitted_bytes];
+ err_code = sd_ble_l2cap_ch_tx(p_ots_c->conn_handle, p_ots_c->local_cid, &obj);
+ if (err_code == NRF_ERROR_RESOURCES)
+ {
+ return; // Too many SDUs queued for transmission, the transmission will be tried again on the next BLE_L2CAP_EVT_CH_TX event.
+ }
+ if(err_code != NRF_SUCCESS && p_ots_c->err_handler != NULL)
+ {
+ p_ots_c->err_handler(err_code);
+ }
+ }
+}
+
+
+static void on_l2cap_ch_tx(nrf_ble_ots_c_t * const p_ots_c,
+ ble_evt_t const * const p_ble_evt)
+{
+ NRF_LOG_INFO("Bytes sent: %i", p_ble_evt->evt.l2cap_evt.params.tx.sdu_buf.len);
+ NRF_LOG_HEXDUMP_INFO(p_ble_evt->evt.l2cap_evt.params.tx.sdu_buf.p_data,
+ p_ble_evt->evt.l2cap_evt.params.tx.sdu_buf.len);
+
+ p_ots_c->transmitted_bytes += p_ble_evt->evt.l2cap_evt.params.tx.sdu_buf.len;
+
+ NRF_LOG_INFO("\r\n Remaining bytes to send: %i",
+ (p_ots_c->current_obj->len - p_ots_c->transmitted_bytes));
+ p_ots_c->current_credits --;
+ NRF_LOG_INFO("\r\n Remaining Credits: %i",
+ (p_ots_c->current_credits));
+ if (p_ots_c->current_credits > 0)
+ {
+ send_next_mtu(p_ots_c);
+ }
+}
+
+
+static void on_l2cap_ch_rx(nrf_ble_ots_c_t * const p_ots_c,
+ ble_evt_t const * const p_ble_evt)
+{
+ NRF_LOG_INFO("Bytes received: %i", p_ble_evt->evt.l2cap_evt.params.rx.sdu_len);
+ NRF_LOG_HEXDUMP_INFO(p_ble_evt->evt.l2cap_evt.params.rx.sdu_buf.p_data,
+ p_ble_evt->evt.l2cap_evt.params.rx.sdu_len);
+
+ memcpy(&p_ots_c->current_obj->p_data[p_ots_c->received_bytes],
+ p_ble_evt->evt.l2cap_evt.params.rx.sdu_buf.p_data,
+ p_ble_evt->evt.l2cap_evt.params.rx.sdu_len);
+ p_ots_c->received_bytes += p_ble_evt->evt.l2cap_evt.params.rx.sdu_len;
+ NRF_LOG_INFO("Remaining bytes to received: %i", (p_ots_c->current_obj->len - p_ots_c->received_bytes));
+
+ if(p_ots_c->received_bytes >= p_ots_c->current_obj->len)
+ {
+ nrf_ble_ots_c_evt_t evt;
+
+ evt.evt_type = NRF_BLE_OTS_C_EVT_OBJ_READ;
+ evt.params.object.len = p_ots_c->current_obj->len;
+ evt.params.object.p_data = p_ots_c->current_obj->p_data;
+ p_ots_c->evt_handler(&evt);
+ }
+ else
+ {
+ ret_code_t err_code;
+
+ ble_data_t sdu_buf;
+ sdu_buf.p_data = &p_ots_c->current_obj->p_data[p_ots_c->received_bytes];
+ sdu_buf.len = p_ots_c->current_obj->len;
+
+ err_code = sd_ble_l2cap_ch_rx(p_ots_c->conn_handle,
+ p_ots_c->local_cid,
+ &sdu_buf);
+ UNUSED_PARAMETER(err_code);
+ }
+
+}
+
+
+static void on_l2cap_credit(nrf_ble_ots_c_t * const p_ots_c,
+ ble_evt_t const * const p_ble_evt)
+{
+ p_ots_c->current_credits = p_ble_evt->evt.l2cap_evt.params.credit.credits;
+ send_next_mtu(p_ots_c);
+}
+
+
+static void on_l2cap_released(nrf_ble_ots_c_t * const p_ots_c,
+ ble_evt_t const * const p_ble_evt)
+{
+ nrf_ble_ots_c_evt_t evt;
+
+ evt.evt_type = NRF_BLE_OTS_C_EVT_CHANNEL_RELEASED;
+ p_ots_c->evt_handler(&evt);
+}
+
+
+void ots_c_l2cap_on_ble_evt(nrf_ble_ots_c_t * const p_ots_c,
+ ble_evt_t const * const p_ble_evt)
+{
+
+ VERIFY_MODULE_INITIALIZED_VOID();
+ VERIFY_PARAM_NOT_NULL_VOID(p_ots_c);
+ VERIFY_PARAM_NOT_NULL_VOID(p_ble_evt);
+
+ if (p_ble_evt->evt.l2cap_evt.local_cid != p_ots_c->local_cid)
+ {
+ return;
+ }
+ switch (p_ble_evt->header.evt_id)
+ {
+ case BLE_L2CAP_EVT_CH_SETUP:
+ NRF_LOG_DEBUG("BLE_L2CAP_EVT_CH_SETUP");
+ on_l2cap_setup_complete(p_ots_c, p_ble_evt);
+ break;
+
+ case BLE_L2CAP_EVT_CH_TX:
+ NRF_LOG_DEBUG("BLE_L2CAP_EVT_CH_TX");
+ on_l2cap_ch_tx(p_ots_c, p_ble_evt);
+ break;
+
+ case BLE_L2CAP_EVT_CH_RX:
+ NRF_LOG_DEBUG("BLE_L2CAP_EVT_CH_RX");
+ on_l2cap_ch_rx(p_ots_c, p_ble_evt);
+ break;
+
+ case BLE_L2CAP_EVT_CH_CREDIT:
+ NRF_LOG_DEBUG("BLE_L2CAP_EVT_CH_CREDIT");
+ on_l2cap_credit(p_ots_c, p_ble_evt);
+ break;
+ case BLE_L2CAP_EVT_CH_RELEASED:
+ NRF_LOG_DEBUG("BLE_L2CAP_EVT_CH_RELEASED");
+ on_l2cap_released(p_ots_c, p_ble_evt);
+ break;
+ default:
+ break;
+ }
+}
+
+
+ret_code_t nrf_ble_ots_c_l2cap_obj_send(nrf_ble_ots_c_t * const p_ots_c, ble_data_t * p_obj)
+{
+ ret_code_t err_code;
+ uint16_t tx_size;
+ p_ots_c->transmitted_bytes = 0;
+ tx_size = MIN(p_obj->len, p_ots_c->ch_setup.tx_params.tx_mtu);
+ p_ots_c->current_obj = p_obj;
+
+ ble_data_t obj;
+ obj.len = tx_size;
+ obj.p_data = p_obj->p_data;
+ err_code = sd_ble_l2cap_ch_tx(p_ots_c->conn_handle, p_ots_c->local_cid, &obj);
+ return err_code;
+}
+
+
+ret_code_t nrf_ble_ots_c_l2cap_obj_receive(nrf_ble_ots_c_t * const p_ots_c, ble_data_t * p_obj)
+{
+ uint32_t err_code;
+ p_ots_c->received_bytes = 0;
+ p_ots_c->current_obj = p_obj;
+ err_code = sd_ble_l2cap_ch_rx(p_ots_c->conn_handle,
+ p_ots_c->local_cid,
+ p_ots_c->current_obj);
+ return err_code;
+}
+
+#endif // NRF_MODULE_ENABLED(BLE_OTS_C_L2CAP)
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/experimental_nrf_ble_ots_c/nrf_ble_ots_c_l2cap.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/experimental_nrf_ble_ots_c/nrf_ble_ots_c_l2cap.h
new file mode 100644
index 0000000..3d76920
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/experimental_nrf_ble_ots_c/nrf_ble_ots_c_l2cap.h
@@ -0,0 +1,101 @@
+/**
+ * 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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
+ *
+ * @defgroup nrf_ble_ots_c_l2cap Object Transfer Service Client
+ * @{
+ * @ingroup nrf_ble_ots_c
+ * @brief Object Transfer Service client module
+ *
+ * @details This is the main module of the Object Transfer Service (OTS) client.
+ */
+
+#ifndef NRF_BLE_OTS_C_L2CAP_H__
+#define NRF_BLE_OTS_C_L2CAP_H__
+
+#include <stdint.h>
+#include "ble_gattc.h"
+#include "ble.h"
+#include "nrf_error.h"
+#include "ble_srv_common.h"
+#include "ble_db_discovery.h"
+#include "sdk_errors.h"
+#include "nrf_ble_ots_c.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+/**@brief Function for handling the Application's BLE Stack events.
+
+ @param[in,out] p_ots_c Pointer to Object Transfer client structure.
+ @param[in] p_ble_evt Pointer to the BLE event received.
+*/
+void ots_c_l2cap_on_ble_evt(nrf_ble_ots_c_t * const p_ots_c,
+ ble_evt_t const * const p_ble_evt);
+
+
+/**@brief Function sending an object.
+
+ @details This Function will only succeed in sending an object if the peer is in a state to
+ receive it. call @ref nrf_ble_ots_c_oacp_write_object before this function.
+
+ @param[in,out] p_ots_c Pointer to Object Transfer client structure.
+ @param[in,out] p_obj Pointer to object that will be sent to the peer.
+*/
+ret_code_t nrf_ble_ots_c_l2cap_obj_send(nrf_ble_ots_c_t * const p_ots_c, ble_data_t * p_obj);
+
+
+/**@brief Function for receiving an object.
+
+ @details This Function will only succeed in receiving an object if the peer is in a state to
+ send it. call @ref nrf_ble_ots_c_oacp_read_object before this function.
+
+ @param[in,out] p_ots_c Pointer to Object Transfer client structure.
+ @param[in,out] p_obj Pointer to buffer where the received data will be stored.
+*/
+ret_code_t nrf_ble_ots_c_l2cap_obj_receive(nrf_ble_ots_c_t * const p_ots_c, ble_data_t * p_obj);
+
+
+#endif // NRF_BLE_OTS_C_L2CAP_H__
+
+/** @} */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/experimental_nrf_ble_ots_c/nrf_ble_ots_c_oacp.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/experimental_nrf_ble_ots_c/nrf_ble_ots_c_oacp.c
new file mode 100644
index 0000000..dd6547f
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/experimental_nrf_ble_ots_c/nrf_ble_ots_c_oacp.c
@@ -0,0 +1,253 @@
+/**
+ * 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+
+#include "sdk_common.h"
+#if NRF_MODULE_ENABLED(BLE_OTS_C_OACP)
+#include <stdlib.h>
+#include "nrf_ble_ots_c_oacp.h"
+#include "ble.h"
+
+#define NRF_LOG_MODULE_NAME ble_ots_c_oacp
+#include "nrf_log.h"
+NRF_LOG_MODULE_REGISTER();
+
+#include "sdk_common.h"
+
+#define BLE_OTS_OACP_WRITE_OP_SIZE 10
+#define BLE_OTS_OACP_READ_OP_SIZE 9
+
+#define MODULE_INITIALIZED (p_ots_c->initialized)
+
+static void oacp_response(nrf_ble_ots_c_t const * const p_ots_c,
+ ble_gattc_evt_t const * const p_ble_gattc_evt)
+{
+ nrf_ble_ots_c_evt_t evt;
+ nrf_ble_ots_c_evt_handler_t evt_handler = p_ots_c->evt_handler;
+
+/*lint --e{415} --e{416} -save suppress Warning 415: Likely access of out-of-bounds pointer */
+ evt.params.response.request_op_code = (ble_ots_c_oacp_proc_type_t) p_ble_gattc_evt->params.hvx.data[sizeof(uint8_t)];
+ evt.params.response.result_code = (ble_ots_c_oacp_res_code_t) p_ble_gattc_evt->params.hvx.data[2*sizeof(uint8_t)];
+/*lint -restore*/
+ evt.evt_type = NRF_BLE_OTS_C_EVT_OACP_RESP;
+ evt.conn_handle = p_ble_gattc_evt->conn_handle;
+ evt_handler(&evt);
+}
+
+/**@brief Function for handling the indication and notifications from the GATT Service Server.
+
+ @param[in] p_ots_c Pointer to Object Transfer client structure.
+ @param[in] p_ble_gattc_evt Pointer to a gattc event.
+*/
+static void on_hvx(nrf_ble_ots_c_t const * const p_ots_c,
+ ble_gattc_evt_t const * const p_ble_gattc_evt)
+{
+
+
+ uint16_t oacp_handle = p_ots_c->service.object_action_cp_char.handle_value;
+
+ if ((p_ble_gattc_evt->params.hvx.handle == oacp_handle)
+ && (p_ots_c->evt_handler != NULL))
+ {
+ ret_code_t err_code = sd_ble_gattc_hv_confirm(p_ble_gattc_evt->conn_handle,
+ oacp_handle);
+
+ if ((err_code != NRF_SUCCESS) && (p_ots_c->err_handler != NULL))
+ {
+ p_ots_c->err_handler(err_code);
+ }
+ uint8_t op_code = p_ble_gattc_evt->params.hvx.data[0];
+
+ if(op_code == NRF_BLE_OTS_C_OACP_PROC_RESP)
+ {
+ oacp_response(p_ots_c, p_ble_gattc_evt);
+ }
+ }
+}
+
+/**@brief Function for checking whether the peer's Object Transfer Service instance has been discovered.
+
+ @param[in] p_ots_c Pointer to the GATT Service client structure instance.
+
+ @return True if the Object Transfer service handles are valid.
+ @return False if the Object Transfer service handles are invalid
+ */
+static bool ots_gatt_handles_are_valid(const nrf_ble_ots_c_t * const p_ots_c)
+{
+ return (p_ots_c->service.object_prop_char.handle_value != BLE_GATT_HANDLE_INVALID
+ && p_ots_c->service.object_size_char.handle_value != BLE_GATT_HANDLE_INVALID
+ && p_ots_c->service.object_type_char.handle_value != BLE_GATT_HANDLE_INVALID
+ && p_ots_c->service.ots_feature_char.handle_value != BLE_GATT_HANDLE_INVALID);
+}
+
+
+ret_code_t nrf_ble_ots_c_indication_enable(nrf_ble_ots_c_t * const p_ots_c,
+ bool const enable)
+{
+ VERIFY_MODULE_INITIALIZED();
+ VERIFY_TRUE(ots_gatt_handles_are_valid(p_ots_c), NRF_ERROR_INVALID_STATE);
+
+ if (p_ots_c->conn_handle == BLE_CONN_HANDLE_INVALID)
+ {
+ return NRF_ERROR_INVALID_STATE;
+ }
+
+ ret_code_t err_code = NRF_SUCCESS;
+
+ ble_gattc_write_params_t gattc_params;
+
+ memset(&gattc_params, 0x00, sizeof(gattc_params));
+ uint16_t cccd_val = (enable) ? BLE_GATT_HVX_INDICATION : 0;
+
+ gattc_params.handle = p_ots_c->service.object_action_cp_cccd.handle;
+ gattc_params.len = BLE_CCCD_VALUE_LEN;
+ gattc_params.p_value = (uint8_t *)&cccd_val;
+ gattc_params.offset = 0;
+ gattc_params.write_op = BLE_GATT_OP_WRITE_REQ;
+
+ err_code = sd_ble_gattc_write(p_ots_c->conn_handle, &gattc_params);
+ return err_code;
+}
+
+
+ret_code_t nrf_ble_ots_c_oacp_write_object(nrf_ble_ots_c_t * const p_ots_c, uint32_t offset, uint32_t len, bool truncate)
+{
+ VERIFY_MODULE_INITIALIZED();
+ VERIFY_TRUE(ots_gatt_handles_are_valid(p_ots_c), NRF_ERROR_INVALID_STATE);
+
+ if (p_ots_c->conn_handle == BLE_CONN_HANDLE_INVALID)
+ {
+ return NRF_ERROR_INVALID_STATE;
+ }
+
+ ret_code_t err_code = NRF_SUCCESS;
+
+ uint8_t val[BLE_OTS_OACP_WRITE_OP_SIZE];
+ memset(val, 0, sizeof(val));
+
+ uint32_t i = 0;
+
+ // OP Code
+ val[i++] = NRF_BLE_OTS_C_OACP_PROC_WRITE;
+
+ //Offset
+ i += uint32_encode(offset, &val[i]);
+
+ //Len
+ i += uint32_encode(len, &val[i]);
+
+ val[i] |= (truncate << 0);
+ ble_gattc_write_params_t gattc_params;
+ memset(&gattc_params, 0, sizeof(ble_gattc_write_params_t));
+
+ gattc_params.handle = p_ots_c->service.object_action_cp_char.handle_value;
+ gattc_params.len = i;
+ gattc_params.p_value = (uint8_t *)val;
+ gattc_params.offset = 0;
+ gattc_params.write_op = BLE_GATT_OP_WRITE_REQ;
+
+ err_code = sd_ble_gattc_write(p_ots_c->conn_handle, &gattc_params);
+ if(err_code != NRF_SUCCESS)
+ {
+ p_ots_c->err_handler(err_code);
+ }
+ return err_code;
+}
+
+ret_code_t nrf_ble_ots_c_oacp_read_object(nrf_ble_ots_c_t * const p_ots_c, uint32_t offset, uint32_t len)
+{
+ VERIFY_MODULE_INITIALIZED();
+ VERIFY_TRUE(ots_gatt_handles_are_valid(p_ots_c), NRF_ERROR_INVALID_STATE);
+
+ if (p_ots_c->conn_handle == BLE_CONN_HANDLE_INVALID)
+ {
+ return NRF_ERROR_INVALID_STATE;
+ }
+
+ ret_code_t err_code = NRF_SUCCESS;
+
+ uint8_t val[BLE_OTS_OACP_READ_OP_SIZE];
+ memset(val, 0, sizeof(val));
+
+ uint32_t i = 0;
+
+ // OP Code
+ val[i++] = NRF_BLE_OTS_C_OACP_PROC_READ;
+
+ //Offset
+ i += uint32_encode(offset, &val[i]);
+
+ //Len
+ i += uint32_encode(len, &val[i]);
+
+ ble_gattc_write_params_t gattc_params;
+ memset(&gattc_params, 0, sizeof(ble_gattc_write_params_t));
+
+ gattc_params.handle = p_ots_c->service.object_action_cp_char.handle_value;
+ gattc_params.len = sizeof(val);
+ gattc_params.p_value = (uint8_t *)val;
+ gattc_params.offset = 0;
+ gattc_params.write_op = BLE_GATT_OP_WRITE_REQ;
+
+ err_code = sd_ble_gattc_write(p_ots_c->conn_handle, &gattc_params);
+ return err_code;
+}
+
+
+
+void ots_c_oacp_on_ble_evt(nrf_ble_ots_c_t * const p_ots_c,
+ ble_evt_t const * const p_ble_evt)
+{
+ VERIFY_MODULE_INITIALIZED_VOID();
+ VERIFY_PARAM_NOT_NULL_VOID(p_ots_c);
+ VERIFY_PARAM_NOT_NULL_VOID(p_ble_evt);
+
+ switch (p_ble_evt->header.evt_id)
+ {
+
+ case BLE_GATTC_EVT_HVX:
+ on_hvx(p_ots_c, &(p_ble_evt->evt.gattc_evt));
+ break;
+
+ default:
+ break;
+ }
+}
+
+#endif // NRF_MODULE_ENABLED(BLE_OTS_C)
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/experimental_nrf_ble_ots_c/nrf_ble_ots_c_oacp.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/experimental_nrf_ble_ots_c/nrf_ble_ots_c_oacp.h
new file mode 100644
index 0000000..a2eb31e
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/experimental_nrf_ble_ots_c/nrf_ble_ots_c_oacp.h
@@ -0,0 +1,126 @@
+/**
+ * Copyright (c) 2016 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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
+ *
+ * @defgroup nrf_ble_ots_c_oacp Object Transfer Service Client Object Action Control Point
+ * @{
+ * @ingroup nrf_ble_ots_c
+ * @brief Object Action Control Point module
+ *
+ * @details This is the Object Action Control Point module of the Object Transfer Service (OTS) client.
+ */
+
+#ifndef NRF_BLE_OTS_C_OACP_H__
+#define NRF_BLE_OTS_C_OACP_H__
+
+#include <stdint.h>
+#include "ble_gattc.h"
+#include "ble.h"
+#include "nrf_error.h"
+#include "ble_srv_common.h"
+#include "ble_db_discovery.h"
+#include "sdk_errors.h"
+#include "nrf_ble_ots_c.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+/**@brief Function for enabling remote indication.
+
+ @param[in,out] p_ots_c Pointer to Object Transfer client structure.
+ @param[in] enable True to enable Object Action Control Point (OACP) indication, false to disable.
+
+ @retval NRF_SUCCESS Operation success.
+ @return If functions from other modules return errors to this function,
+ the @ref nrf_error are propagated.
+*/
+ret_code_t nrf_ble_ots_c_indication_enable(nrf_ble_ots_c_t * const p_ots_c,
+ bool const enable);
+
+
+/**@brief Function for requesting a write of an object.
+
+ @details With this function we let the peer know the length of the object we want to write.
+ (The object itself is not written by this function.)
+ The peer will indicate a response on the Object Action Control Point.
+ If the write is accepted (the event NRF_BLE_OTS_C_OACP_RES_SUCCESS ), an object can be
+ transfered with @ref nrf_ble_ots_c_l2cap_obj_send.
+
+ @param[in,out] p_ots_c Pointer to Object Transfer client structure.
+ @param[in] offset Offset of the write.
+ @param[in] len length of the object to write.
+ @param[in] truncate True to let the write truncate on the object.
+
+ @retval NRF_SUCCESS Operation success.
+ @retval NRF_ERROR_INVALID_STATE Module is not initialized, or the handles of the peer OACP
+ are invalid.
+ @return If functions from other modules return errors to this function,
+ the @ref nrf_error are propagated.
+*/
+ret_code_t nrf_ble_ots_c_oacp_write_object(nrf_ble_ots_c_t * const p_ots_c, uint32_t offset, uint32_t len, bool truncate);
+
+/**@brief Function for requesting a read of an object.
+
+ @param[in,out] p_ots_c Pointer to Object Transfer client structure.
+ @param[in] offset Offset of the read.
+ @param[in] len length of the read.
+
+ @retval NRF_SUCCESS Operation success.
+ @return If functions from other modules return errors to this function,
+ the @ref nrf_error are propagated.
+*/
+ret_code_t nrf_ble_ots_c_oacp_read_object(nrf_ble_ots_c_t * const p_ots_c, uint32_t offset, uint32_t len);
+
+
+/**@brief Function for handling the Application's BLE Stack events.
+
+ @param[in,out] p_ots_c Pointer to Object Transfer client structure.
+ @param[in] p_ble_evt Pointer to the BLE event received.
+*/
+void ots_c_oacp_on_ble_evt(nrf_ble_ots_c_t * const p_ots_c,
+ ble_evt_t const * const p_ble_evt);
+
+
+#endif // NRF_BLE_OTS_C_OACP_H__
+
+/** @} */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/experimental_nrf_ble_ots_c/ots_tx_buffer.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/experimental_nrf_ble_ots_c/ots_tx_buffer.c
new file mode 100644
index 0000000..0ce1816
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/experimental_nrf_ble_ots_c/ots_tx_buffer.c
@@ -0,0 +1,113 @@
+/**
+ * Copyright (c) 2016 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+/* Disclaimer: This client implementation of the Apple Notification Center Service can and will be changed at any time by Nordic Semiconductor ASA.
+ * Server implementations such as the ones found in iOS can be changed at any time by Apple and may cause this client implementation to stop working.
+ */
+
+ #include "nrf_ble_ots_c.h"
+ #include "ancs_tx_buffer.h"
+ #include "sdk_macros.h"
+ #include "nrf_log.h"
+ #include "string.h"
+
+
+static tx_message_t m_tx_buffer[TX_BUFFER_SIZE]; /**< Transmit buffer for messages to be transmitted to the Notification Provider. */
+static uint32_t m_tx_insert_index = 0; /**< Current index in the transmit buffer where the next message should be inserted. */
+static uint32_t m_tx_index = 0; /**< Current index in the transmit buffer from where the next message to be transmitted resides. */
+
+
+void tx_buffer_init(void)
+{
+ memset(m_tx_buffer, 0, sizeof(m_tx_buffer));
+}
+
+
+void tx_buffer_insert(tx_message_t * p_msg)
+{
+
+ memset(&(m_tx_buffer[m_tx_insert_index]), 0, sizeof(m_tx_buffer)/sizeof(tx_message_t));
+
+ m_tx_buffer[m_tx_insert_index].conn_handle = p_msg->conn_handle;
+ m_tx_buffer[m_tx_insert_index].type = p_msg->type;
+
+ m_tx_buffer[m_tx_insert_index].req.write_req.gattc_params.handle = p_msg->req.write_req.gattc_params.handle;
+ m_tx_buffer[m_tx_insert_index].req.write_req.gattc_params.len = p_msg->req.write_req.gattc_params.len;
+ m_tx_buffer[m_tx_insert_index].req.write_req.gattc_params.write_op = p_msg->req.write_req.gattc_params.write_op;
+ m_tx_buffer[m_tx_insert_index].req.write_req.gattc_params.flags = p_msg->req.write_req.gattc_params.flags;
+ m_tx_buffer[m_tx_insert_index].req.write_req.gattc_params.p_value = m_tx_buffer[m_tx_insert_index].req.write_req.gattc_value;
+ m_tx_buffer[m_tx_insert_index].req.write_req.gattc_params.offset = p_msg->req.write_req.gattc_params.offset;
+
+ if(p_msg->type == WRITE_REQ)
+ {
+ memcpy(m_tx_buffer[m_tx_insert_index].req.write_req.gattc_value,
+ p_msg->req.write_req.gattc_value,
+ WRITE_MESSAGE_LENGTH);
+ }
+
+ m_tx_insert_index++;
+ m_tx_insert_index &= TX_BUFFER_MASK;
+}
+
+
+
+void tx_buffer_process(void)
+{
+ if (m_tx_index != m_tx_insert_index)
+ {
+ uint32_t err_code;
+
+ if (m_tx_buffer[m_tx_index].type == READ_REQ)
+ {
+ err_code = sd_ble_gattc_read(m_tx_buffer[m_tx_index].conn_handle,
+ m_tx_buffer[m_tx_index].req.read_handle,
+ 0);
+ }
+ else
+ {
+ err_code = sd_ble_gattc_write(m_tx_buffer[m_tx_index].conn_handle,
+ &m_tx_buffer[m_tx_index].req.write_req.gattc_params);
+ }
+ if (err_code == NRF_SUCCESS)
+ {
+ ++m_tx_index;
+ m_tx_index &= TX_BUFFER_MASK;
+ }
+ }
+}
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/experimental_nrf_ble_ots_c/ots_tx_buffer.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/experimental_nrf_ble_ots_c/ots_tx_buffer.h
new file mode 100644
index 0000000..6953438
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/experimental_nrf_ble_ots_c/ots_tx_buffer.h
@@ -0,0 +1,103 @@
+/**
+ * Copyright (c) 2012 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#ifndef ANCS_TX_BUFFER_H__
+#define ANCS_TX_BUFFER_H__
+
+#include "nrf_ble_ancs_c.h"
+
+/** @file
+ *
+ * @addtogroup ble_ancs_c
+ * @{
+ */
+
+#define TX_BUFFER_MASK 0x07 //!< TX buffer mask. Must be a mask of contiguous zeroes followed by a contiguous sequence of ones: 000...111.
+#define TX_BUFFER_SIZE (TX_BUFFER_MASK + 1) //!< Size of the send buffer, which is 1 bigger than the mask.
+#define WRITE_MESSAGE_LENGTH 20 //!< Length of the write message for the CCCD/control point.
+
+/**@brief ANCS request types.
+ */
+typedef enum
+{
+ READ_REQ = 1, /**< Type identifying that this TX message is a read request. */
+ WRITE_REQ /**< Type identifying that this TX message is a write request. */
+} tx_request_t;
+
+
+/**@brief Structure for writing a message to the central, thus the Control Point or CCCD.
+ */
+typedef struct
+{
+ uint8_t gattc_value[WRITE_MESSAGE_LENGTH]; //!< The message to write.
+ ble_gattc_write_params_t gattc_params; //!< GATTC parameters for this message.
+} write_params_t;
+
+
+/**@brief Data to be transmitted to the connected master.
+ */
+typedef struct
+{
+ uint16_t conn_handle; //!< Connection handle to be used when transmitting this message.
+ tx_request_t type; //!< Type of this message (read or write message).
+ union
+ {
+ uint16_t read_handle; //!< Read request message.
+ write_params_t write_req; //!< Write request message.
+ } req;
+} tx_message_t;
+
+/**@brief Function for clearing the TX buffer.
+ *
+ * @details Always call this function before using the TX buffer.
+*/
+void tx_buffer_init(void);
+
+/**@brief Function for moving the pointer of the ring buffer to the next element.
+*/
+void tx_buffer_insert(tx_message_t * p_msg);
+
+/**@brief Function for passing any pending request from the buffer to the stack.
+*/
+void tx_buffer_process(void);
+
+/** @} */
+
+#endif // ANCS_TX_BUFFER_H__
+
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/nrf_ble_bms/nrf_ble_bms.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/nrf_ble_bms/nrf_ble_bms.c
new file mode 100644
index 0000000..5757750
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/nrf_ble_bms/nrf_ble_bms.c
@@ -0,0 +1,622 @@
+/**
+ * Copyright (c) 2016 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#include <string.h>
+
+#include "nrf_ble_bms.h"
+#include "ble_srv_common.h"
+
+#define NRF_LOG_MODULE_NAME ble_bms
+#include "nrf_log.h"
+NRF_LOG_MODULE_REGISTER();
+
+/*@brief Check if a returned error code is NRF_SUCCESS, and call the error handler if not.
+ *
+ * @param[in] err_code Error code that should be checked.
+ * @param[in] err_handler Error handler that should be called.
+ */
+static void error_check(ret_code_t err_code, ble_srv_error_handler_t err_handler)
+{
+ if (err_code != NRF_SUCCESS)
+ {
+ err_handler(err_code);
+ }
+}
+
+
+/**@brief Function for adding the Bond Management Control Point characteristic.
+ *
+ * @param[in] p_bms Bond Management Service structure.
+ * @param[in] p_bms_init Information needed to initialize the service.
+ *
+ * @return NRF_SUCCESS on success, otherwise an error code returned by @ref characteristic_add.
+ */
+static ret_code_t ctrlpt_char_add(nrf_ble_bms_t * p_bms, nrf_ble_bms_init_t const * p_bms_init)
+{
+ ble_add_char_params_t add_char_params;
+
+ memset(&add_char_params, 0, sizeof(add_char_params));
+ add_char_params.uuid = BLE_UUID_BMS_CTRLPT;
+ add_char_params.char_props.write = 1;
+ add_char_params.is_defered_write = true;
+ add_char_params.is_var_len = true;
+ add_char_params.max_len = NRF_BLE_BMS_CTRLPT_MAX_LEN;
+ add_char_params.read_access = SEC_NO_ACCESS;
+ add_char_params.write_access = p_bms_init->bms_ctrlpt_sec_req;
+
+ if (p_bms_init->p_qwr != NULL)
+ {
+ add_char_params.char_ext_props.reliable_wr = 1;
+ }
+
+ return characteristic_add(p_bms->service_handle, &add_char_params, &p_bms->ctrlpt_handles);
+}
+
+
+/**@brief Forward an authorization request to the application, if necessary.
+ *
+ * @param[in] p_bms Bond Management Service structure.
+ * @param[in] p_ctrlpt Pointer to the received Control Point value.
+ */
+static void ctrlpt_auth(nrf_ble_bms_t * p_bms, nrf_ble_bms_ctrlpt_t * p_ctrlpt)
+{
+ nrf_ble_bms_features_t * p_feature = &p_bms->feature;
+
+ p_bms->auth_status = NRF_BLE_BMS_AUTH_STATUS_ALLOWED;
+
+ /* Check if the authorization feature is enabled for this op code. */
+ if ((
+ (p_ctrlpt->op_code == NRF_BLE_BMS_OP_DEL_BOND_REQ_DEVICE_LE_ONLY) &&
+ (p_feature->delete_requesting_auth)
+ ) ||
+ (
+ (p_ctrlpt->op_code == NRF_BLE_BMS_OP_DEL_ALL_BONDS_ON_SERVER_LE_ONLY) &&
+ (p_feature->delete_all_auth)
+ ) ||
+ (
+ (p_ctrlpt->op_code == NRF_BLE_BMS_OP_DEL_ALL_BUT_ACTIVE_BOND_LE_ONLY) &&
+ (p_feature->delete_all_but_requesting_auth)
+ )
+ )
+ {
+ if (p_bms->evt_handler != NULL)
+ {
+ nrf_ble_bms_evt_t bms_evt;
+
+ memset(&bms_evt, 0, sizeof(bms_evt));
+ bms_evt.evt_type = NRF_BLE_BMS_EVT_AUTH;
+ bms_evt.auth_code.len = p_ctrlpt->auth_code.len;
+ memcpy(bms_evt.auth_code.code, p_ctrlpt->auth_code.code, p_ctrlpt->auth_code.len);
+
+ p_bms->auth_status = NRF_BLE_BMS_AUTH_STATUS_PENDING;
+
+ p_bms->evt_handler(p_bms, &bms_evt);
+ }
+ else
+ {
+ p_bms->auth_status = NRF_BLE_BMS_AUTH_STATUS_DENIED;
+ }
+ }
+}
+
+
+/**@brief Decode an incoming Control Point write.
+ *
+ * @param[in] p_rcvd_val Received write value.
+ * @param[in] len Value length.
+ * @param[out] p_ctrlpt Decoded control point structure.
+ *
+ * @retval NRF_ERROR_INVALID_LENGTH The supplied value length is invalid.
+ * @retval NRF_ERROR_NOT_SUPPORTED The supplied op code is not supported.
+ * @retval NRF_SUCCESS Operation successful.
+ */
+static ret_code_t ctrlpt_decode(uint8_t const * p_rcvd_val,
+ uint16_t len,
+ nrf_ble_bms_ctrlpt_t * p_ctrlpt)
+{
+ uint16_t pos = 0;
+
+ VERIFY_TRUE(len >= NRF_BLE_BMS_CTRLPT_MIN_LEN, NRF_ERROR_INVALID_LENGTH);
+ VERIFY_TRUE(len <= NRF_BLE_BMS_CTRLPT_MAX_LEN, NRF_ERROR_INVALID_LENGTH);
+
+ p_ctrlpt->op_code = (nrf_ble_bms_op_t) p_rcvd_val[pos++];
+ p_ctrlpt->auth_code.len = (len - pos);
+ memcpy(p_ctrlpt->auth_code.code, &(p_rcvd_val[pos]), p_ctrlpt->auth_code.len);
+
+ return NRF_SUCCESS;
+}
+
+
+/**@brief Function for performing an operation requested through the Control Point.
+ *
+ * @param[in] p_bms Bond Management Service structure.
+ * @param[in] op_code Op code to execute.
+ */
+static void ctrlpt_execute(nrf_ble_bms_t * p_bms, nrf_ble_bms_op_t op_code)
+{
+ switch (op_code)
+ {
+ case NRF_BLE_BMS_OP_DEL_BOND_REQ_DEVICE_LE_ONLY:
+ /* Delete single bond */
+ p_bms->bond_callbacks.delete_requesting(p_bms);
+ break; // NRF_BLE_BMS_OP_DEL_BOND_REQ_DEVICE_LE_ONLY
+
+ case NRF_BLE_BMS_OP_DEL_ALL_BONDS_ON_SERVER_LE_ONLY:
+ /* Delete all bonds */
+ p_bms->bond_callbacks.delete_all(p_bms);
+ break; // NRF_BLE_BMS_OP_DEL_ALL_BONDS_ON_SERVER_LE_ONLY
+
+ case NRF_BLE_BMS_OP_DEL_ALL_BUT_ACTIVE_BOND_LE_ONLY:
+ /* Delete all but current bond */
+ p_bms->bond_callbacks.delete_all_except_requesting(p_bms);
+ break; // NRF_BLE_BMS_OP_DEL_ALL_BUT_ACTIVE_BOND_LE_ONLY
+
+ default:
+ /* No implemementation needed. */
+ break;
+ }
+}
+
+
+/*@brief Validate an incoming Control Point write.
+ *
+ * @param[in] op_code Received op code.
+ * @param[in] p_feature Supported features.
+ *
+ * @returns True if the op code is supported, or false.
+ */
+static bool ctrlpt_validate(nrf_ble_bms_ctrlpt_t * p_ctrlpt, nrf_ble_bms_features_t * p_feature)
+{
+ switch (p_ctrlpt->op_code)
+ {
+ case NRF_BLE_BMS_OP_DEL_BOND_REQ_DEVICE_LE_ONLY:
+ if (p_feature->delete_requesting || p_feature->delete_requesting_auth)
+ {
+ return true;
+ }
+ break;
+
+ case NRF_BLE_BMS_OP_DEL_ALL_BONDS_ON_SERVER_LE_ONLY:
+ if (p_feature->delete_all || p_feature->delete_all_auth)
+ {
+ return true;
+ }
+ break;
+
+ case NRF_BLE_BMS_OP_DEL_ALL_BUT_ACTIVE_BOND_LE_ONLY:
+ if (p_feature->delete_all_but_requesting || p_feature->delete_all_but_requesting_auth)
+ {
+ return true;
+ }
+ break;
+
+ default:
+ /* No implementation needed. */
+ break;
+ }
+
+ return false;
+}
+
+
+/**@brief Function for processing a write to the Control Point.
+ *
+ * @param[in] p_bms Bond Management Service structure.
+ * @param[in] p_rcvd_val Received write value.
+ * @param[in] len Value length.
+ * @param[out] p_ctrlpt Decoded control point structure.
+ */
+static uint16_t ctrlpt_process(nrf_ble_bms_t * p_bms,
+ uint8_t const * p_rcvd_val,
+ uint16_t len,
+ nrf_ble_bms_ctrlpt_t * p_ctrlpt)
+{
+ ret_code_t err_code;
+
+ /* Decode operation */
+ err_code = ctrlpt_decode(p_rcvd_val, len, p_ctrlpt);
+ if (err_code != NRF_SUCCESS)
+ {
+ NRF_LOG_ERROR("Control point write: Operation failed.");
+ return NRF_BLE_BMS_OPERATION_FAILED;
+ }
+
+ /* Verify that the operation is allowed. */
+ if (!ctrlpt_validate(p_ctrlpt, &p_bms->feature))
+ {
+ NRF_LOG_ERROR("Control point write: Invalid op code.");
+ return NRF_BLE_BMS_OPCODE_NOT_SUPPORTED;
+ }
+
+ /* Request authorization */
+ ctrlpt_auth(p_bms, p_ctrlpt);
+ if (p_bms->auth_status != NRF_BLE_BMS_AUTH_STATUS_ALLOWED)
+ {
+ NRF_LOG_ERROR("Control point long write: Invalid auth.");
+ return BLE_GATT_STATUS_ATTERR_INSUF_AUTHORIZATION;
+ }
+
+ return BLE_GATT_STATUS_SUCCESS;
+}
+
+
+/**@brief Function for encoding the Bond Management Feature characteristic.
+ *
+ * @param[in] p_bms Bond Management Service structure.
+ * @param[out] p_encoded_feature Encoded features.
+ *
+ * @return Size of the encoded feature.
+ */
+static uint8_t feature_encode(nrf_ble_bms_features_t const * p_feature, uint8_t * p_encoded_feature)
+{
+ uint32_t data = 0;
+
+ if (p_feature->delete_all_auth)
+ {
+ data |= NRF_BLE_BMS_ALL_BONDS_LE_AUTH_CODE;
+ }
+ if (p_feature->delete_all_but_requesting_auth)
+ {
+ data |= NRF_BLE_BMS_ALL_EXCEPT_REQUESTING_DEVICE_LE_AUTH_CODE;
+ }
+ if (p_feature->delete_all_but_requesting)
+ {
+ data |= NRF_BLE_BMS_ALL_EXCEPT_REQUESTING_DEVICE_LE;
+ }
+ if (p_feature->delete_all)
+ {
+ data |= NRF_BLE_BMS_ALL_BONDS_LE;
+ }
+ if (p_feature->delete_requesting_auth)
+ {
+ data |= NRF_BLE_BMS_REQUESTING_DEVICE_LE_AUTH_CODE;
+ }
+ if (p_feature->delete_requesting)
+ {
+ data |= NRF_BLE_BMS_REQUESTING_DEVICE_LE;
+ }
+
+ return (uint24_encode(data, p_encoded_feature));
+}
+
+
+/**@brief Function for adding the Bond Management Feature characteristic.
+ *
+ * @param[in] p_bms Bond Management Service structure.
+ * @param[in] p_bms_init Information needed to initialize the service.
+ *
+ * @return NRF_SUCCESS on success, otherwise an error code returned by @ref characteristic_add.
+ */
+static ret_code_t feature_char_add(nrf_ble_bms_t * p_bms, nrf_ble_bms_init_t const * p_bms_init)
+{
+ uint8_t encoded_feature[NRF_BLE_BMS_FEATURE_LEN];
+ uint8_t init_value_len;
+ ble_add_char_params_t add_char_params;
+ nrf_ble_bms_features_t * p_feature = &p_bms->feature;
+
+ if ((p_feature->delete_all_auth) ||
+ (p_feature->delete_all_but_requesting_auth) ||
+ (p_feature->delete_requesting_auth))
+ {
+ VERIFY_PARAM_NOT_NULL(p_bms_init->evt_handler);
+ }
+
+ if ((p_feature->delete_requesting_auth) ||
+ (p_feature->delete_requesting))
+ {
+ VERIFY_PARAM_NOT_NULL(p_bms_init->bond_callbacks.delete_requesting);
+ }
+
+ if ((p_feature->delete_all) ||
+ (p_feature->delete_all_auth))
+ {
+ VERIFY_PARAM_NOT_NULL(p_bms_init->bond_callbacks.delete_all);
+ }
+
+ if ((p_feature->delete_all_but_requesting) ||
+ (p_feature->delete_all_but_requesting_auth))
+ {
+ VERIFY_PARAM_NOT_NULL(p_bms_init->bond_callbacks.delete_all_except_requesting);
+ }
+
+ init_value_len = feature_encode(&p_bms->feature, encoded_feature);
+
+ memset(&add_char_params, 0, sizeof(add_char_params));
+ add_char_params.uuid = BLE_UUID_BMS_FEATURE;
+ add_char_params.char_props.read = true;
+ add_char_params.max_len = init_value_len;
+ add_char_params.p_init_value = encoded_feature;
+ add_char_params.init_len = init_value_len;
+ add_char_params.read_access = p_bms_init->bms_feature_sec_req;
+ add_char_params.write_access = SEC_NO_ACCESS;
+
+ return characteristic_add(p_bms->service_handle, &add_char_params, &p_bms->feature_handles);
+}
+
+
+/**@brief Handle a write event to the Bond Management Service Control Point.
+ *
+ * @param[in] p_bms Bond Management Service structure.
+ * @param[in] p_evt_write WRITE event to be handled.
+ */
+static void on_ctrlpt_write(nrf_ble_bms_t * p_bms,
+ ble_gatts_evt_write_t const * p_evt_write,
+ ble_gatts_authorize_params_t * p_auth_params)
+{
+ ret_code_t err_code;
+ nrf_ble_bms_ctrlpt_t ctrlpt;
+
+ err_code = ctrlpt_process(p_bms, p_evt_write->data, p_evt_write->len, &ctrlpt);
+ if (err_code != NRF_SUCCESS)
+ {
+ p_auth_params->gatt_status = err_code;
+ p_auth_params->update = 0;
+
+ return;
+ }
+
+ p_auth_params->gatt_status = BLE_GATT_STATUS_SUCCESS;
+ p_auth_params->update = 1;
+
+ NRF_LOG_INFO("Control point write: Success");
+
+ /* Execute the requested operation. */
+ ctrlpt_execute(p_bms, ctrlpt.op_code);
+}
+
+
+/**@brief Authorize WRITE request event handler.
+ *
+ * @details Handles WRITE events from the BLE stack.
+ *
+ * @param[in] p_bms Bond Management Service structure.
+ * @param[in] p_gatts_evt GATTS Event received from the BLE stack.
+ *
+ */
+static void on_rw_auth_req(nrf_ble_bms_t * p_bms, ble_gatts_evt_t const * p_gatts_evt)
+{
+ ret_code_t err_code;
+ ble_gatts_rw_authorize_reply_params_t auth_reply;
+
+ ble_gatts_evt_rw_authorize_request_t const * p_auth_req =
+ &p_gatts_evt->params.authorize_request;
+
+ memset(&auth_reply, 0, sizeof(auth_reply));
+
+ if ((p_auth_req->type == BLE_GATTS_AUTHORIZE_TYPE_WRITE) &&
+ (p_auth_req->request.write.op == BLE_GATTS_OP_WRITE_REQ) &&
+ (p_auth_req->request.write.handle == p_bms->ctrlpt_handles.value_handle))
+ {
+ auth_reply.type = BLE_GATTS_AUTHORIZE_TYPE_WRITE;
+ on_ctrlpt_write(p_bms, &p_auth_req->request.write, &auth_reply.params.write);
+
+ /* Send authorization reply */
+ err_code = sd_ble_gatts_rw_authorize_reply(p_bms->conn_handle, &auth_reply);
+ error_check(err_code, p_bms->error_handler);
+ }
+
+}
+
+
+/**@brief Handle authorization request events from the Queued Write module.
+ *
+ * @param[in] p_bms Bond Management Service structure.
+ * @param[in] p_qwr Queued Write Structure.
+ * @param[in] p_evt Event received from the Queued Writes module.
+ *
+ * @retval BLE_GATT_STATUS_SUCCESS If the received event is accepted.
+ * @retval BLE_BMS_OPCODE_OPERATION_FAILED If the received event is not relevant for any of this module's attributes.
+ * @retval BLE_BMS_OPCODE_NOT_SUPPORTED If the received opcode is not supported.
+ * @retval BLE_GATT_STATUS_ATTERR_INSUF_AUTHORIZATION If the application handler returns that the authorization code is not valid.
+ */
+uint16_t on_qwr_auth_req(nrf_ble_bms_t * p_bms, nrf_ble_qwr_t * p_qwr, nrf_ble_qwr_evt_t * p_evt)
+{
+ ret_code_t err_code;
+ uint16_t len = NRF_BLE_BMS_CTRLPT_MAX_LEN;
+ uint8_t mem_buffer[NRF_BLE_BMS_CTRLPT_MAX_LEN];
+ nrf_ble_bms_ctrlpt_t ctrlpt;
+
+ err_code = nrf_ble_qwr_value_get(p_qwr, p_evt->attr_handle, mem_buffer, &len);
+ if (err_code != NRF_SUCCESS)
+ {
+ NRF_LOG_ERROR("Control point write: Operation failed.");
+ return NRF_BLE_BMS_OPERATION_FAILED;
+ }
+
+ return ctrlpt_process(p_bms, mem_buffer, len, &ctrlpt);
+}
+
+
+/**@brief Handle execute write events to from the Queued Write module.
+ *
+ * @param[in] p_bms Bond Management Service structure.
+ * @param[in] p_qwr Queued Write Structure.
+ * @param[in] p_evt Event received from the Queued Writes module.
+ *
+ * @retval BLE_GATT_STATUS_SUCCESS If the received event is accepted.
+ * @retval BLE_BMS_OPCODE_OPERATION_FAILED If the received event is not relevant for any of this module's attributes.
+ * @retval BLE_BMS_OPCODE_NOT_SUPPORTED If the received opcode is not supported.
+ */
+uint16_t on_qwr_exec_write(nrf_ble_bms_t * p_bms, nrf_ble_qwr_t * p_qwr, nrf_ble_qwr_evt_t * p_evt)
+{
+ ret_code_t err_code;
+ uint16_t len = NRF_BLE_BMS_CTRLPT_MAX_LEN;
+ uint8_t mem_buffer[NRF_BLE_BMS_CTRLPT_MAX_LEN];
+ nrf_ble_bms_ctrlpt_t ctrlpt;
+ ble_gatts_value_t ctrlpt_value;
+
+ ctrlpt_value.len = NRF_BLE_BMS_CTRLPT_MAX_LEN;
+ ctrlpt_value.offset = 0;
+ ctrlpt_value.p_value = mem_buffer;
+
+ const uint16_t ctrlpt_handle = p_bms->ctrlpt_handles.value_handle;
+ err_code = sd_ble_gatts_value_get(p_bms->conn_handle, ctrlpt_handle, &ctrlpt_value);
+ if (err_code != NRF_SUCCESS)
+ {
+ NRF_LOG_ERROR("Control point write: Operation failed.");
+ return NRF_BLE_BMS_OPERATION_FAILED;
+ }
+
+ /* Decode operation */
+ err_code = ctrlpt_decode(ctrlpt_value.p_value, len, &ctrlpt);
+ if (err_code != NRF_SUCCESS)
+ {
+ NRF_LOG_ERROR("Control point write: Operation failed.");
+ return NRF_BLE_BMS_OPERATION_FAILED;
+ }
+
+ /* Execute the requested operation. */
+ ctrlpt_execute(p_bms, ctrlpt.op_code);
+
+ /* Reset authorization status */
+ p_bms->auth_status = NRF_BLE_BMS_AUTH_STATUS_DENIED;
+
+ return BLE_GATT_STATUS_SUCCESS;
+}
+
+
+uint16_t nrf_ble_bms_on_qwr_evt(nrf_ble_bms_t * p_bms,
+ nrf_ble_qwr_t * p_qwr,
+ nrf_ble_qwr_evt_t * p_evt)
+{
+ VERIFY_TRUE(p_bms != NULL, (NRF_BLE_QWR_REJ_REQUEST_ERR_CODE));
+ VERIFY_TRUE(p_qwr != NULL, (NRF_BLE_QWR_REJ_REQUEST_ERR_CODE));
+ VERIFY_TRUE(p_evt != NULL, (NRF_BLE_QWR_REJ_REQUEST_ERR_CODE));
+ VERIFY_TRUE(p_evt->attr_handle == p_bms->ctrlpt_handles.value_handle,
+ (NRF_BLE_QWR_REJ_REQUEST_ERR_CODE));
+
+ if (p_evt->evt_type == NRF_BLE_QWR_EVT_AUTH_REQUEST)
+ {
+ return on_qwr_auth_req(p_bms, p_qwr, p_evt);
+ }
+ else if ((p_evt->evt_type == NRF_BLE_QWR_EVT_EXECUTE_WRITE) &&
+ (p_bms->auth_status == NRF_BLE_BMS_AUTH_STATUS_ALLOWED))
+ {
+ return on_qwr_exec_write(p_bms, p_qwr, p_evt);
+ }
+
+ return BLE_GATT_STATUS_SUCCESS;
+}
+
+
+void nrf_ble_bms_on_ble_evt(ble_evt_t const * p_ble_evt, void * p_context)
+{
+ VERIFY_PARAM_NOT_NULL_VOID(p_context);
+ VERIFY_PARAM_NOT_NULL_VOID(p_ble_evt);
+
+ nrf_ble_bms_t * p_bms = (nrf_ble_bms_t *)p_context;
+
+ switch (p_ble_evt->header.evt_id)
+ {
+ case BLE_GATTS_EVT_RW_AUTHORIZE_REQUEST:
+ on_rw_auth_req(p_bms, &p_ble_evt->evt.gatts_evt);
+ break;
+
+ default:
+ break;
+ }
+}
+
+
+ret_code_t nrf_ble_bms_set_conn_handle(nrf_ble_bms_t * p_bms, uint16_t conn_handle)
+{
+ VERIFY_PARAM_NOT_NULL(p_bms);
+
+ p_bms->conn_handle = conn_handle;
+ return NRF_SUCCESS;
+}
+
+
+ret_code_t nrf_ble_bms_init(nrf_ble_bms_t * p_bms, nrf_ble_bms_init_t * p_bms_init)
+{
+ ret_code_t err_code;
+ ble_uuid_t ble_uuid;
+
+ VERIFY_PARAM_NOT_NULL(p_bms_init);
+ VERIFY_PARAM_NOT_NULL(p_bms);
+
+ // Add service
+ BLE_UUID_BLE_ASSIGN(ble_uuid, BLE_UUID_BMS_SERVICE);
+
+ p_bms->evt_handler = p_bms_init->evt_handler;
+ p_bms->error_handler = p_bms_init->error_handler;
+ p_bms->feature = p_bms_init->feature;
+ p_bms->bond_callbacks = p_bms_init->bond_callbacks;
+ p_bms->conn_handle = BLE_CONN_HANDLE_INVALID;
+
+ err_code = sd_ble_gatts_service_add(BLE_GATTS_SRVC_TYPE_PRIMARY,
+ &ble_uuid,
+ &p_bms->service_handle);
+ VERIFY_SUCCESS(err_code);
+
+ err_code = feature_char_add(p_bms, p_bms_init);
+ VERIFY_SUCCESS(err_code);
+
+ err_code = ctrlpt_char_add(p_bms, p_bms_init);
+ VERIFY_SUCCESS(err_code);
+
+ if (p_bms_init->p_qwr != NULL)
+ {
+ return nrf_ble_qwr_attr_register(p_bms_init->p_qwr, p_bms->ctrlpt_handles.value_handle);
+ }
+
+ NRF_LOG_INFO("Init complete.");
+
+ return NRF_SUCCESS;
+}
+
+
+ret_code_t nrf_ble_bms_auth_response(nrf_ble_bms_t * p_bms, bool authorize)
+{
+ VERIFY_PARAM_NOT_NULL(p_bms);
+ VERIFY_TRUE(p_bms->auth_status == NRF_BLE_BMS_AUTH_STATUS_PENDING, NRF_ERROR_INVALID_STATE);
+
+ if (authorize)
+ {
+ p_bms->auth_status = NRF_BLE_BMS_AUTH_STATUS_ALLOWED;
+ }
+ else
+ {
+ p_bms->auth_status = NRF_BLE_BMS_AUTH_STATUS_DENIED;
+ }
+
+ return NRF_SUCCESS;
+}
+
+
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/nrf_ble_bms/nrf_ble_bms.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/nrf_ble_bms/nrf_ble_bms.h
new file mode 100644
index 0000000..1aa6abb
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/ble_services/nrf_ble_bms/nrf_ble_bms.h
@@ -0,0 +1,316 @@
+/**
+ * Copyright (c) 2016 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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
+ *
+ * @defgroup ble_bms Bond Management Service
+ * @{
+ * @ingroup ble_sdk_srv
+ * @brief Bond Management Service (BMS) module.
+ *
+ * @details This module implements the Bond Management Service (BMS).
+ * By writing to the Bond Management Control Point, the connected peer can request the deletion of
+ * bond information from the device.
+ * If authorization is configured, the application must supply an event handler for receiving Bond
+ * Management Service events. Using this handler, the service requests authorization when
+ * a procedure is requested by writing to the Bond Management Control Point.
+ *
+ * @msc
+ * hscale = "1.3";
+ * APP,BMS,PEER;
+ * |||;
+ * APP rbox PEER [label="Connection established"];
+ * |||;
+ * BMS<=PEER [label="BMCP write request {procedure}"];
+ * APP<-BMS [label="NRF_BLE_BMS_EVT_AUTH {auth_code}"];
+ * --- [label="Variant #1: app grants authorization"];
+ * APP->BMS [label="nrf_ble_bms_auth_reponse (true)"];
+ * BMS>>APP [label="NRF_SUCCESS"];
+ * BMS=>PEER [label="BMCP write response"];
+ * BMS rbox BMS [label="Procedure initiated"];
+ * --- [label="Variant #2: app denies authorization"];
+ * APP->BMS [label="nrf_ble_bms_auth_reponse (false)"];
+ * BMS>>APP [label="NRF_SUCCESS"];
+ * BMS=>PEER [label="BMCP error response"];
+ * @endmsc
+ *
+ * @note The application must register this module as BLE event observer using the
+ * NRF_SDH_BLE_OBSERVER macro. Example:
+ * @code
+ * nrf_ble_bms_t instance;
+ * NRF_SDH_BLE_OBSERVER(anything, NRF_BLE_BMS_BLE_OBSERVER_PRIO,
+ * nrf_ble_bms_on_ble_evt, &instance);
+ * @endcode
+ */
+
+#ifndef NRF_BLE_BMS_H__
+#define NRF_BLE_BMS_H__
+
+#include <stdint.h>
+#include <stdbool.h>
+#include "ble.h"
+#include "ble_srv_common.h"
+#include "nrf_ble_qwr.h"
+#include "nrf_sdh_ble.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**@brief Macro for defining a nrf_ble_bms instance.
+ *
+ * @param _name Name of the instance.
+ * @hideinitializer
+ */
+#define NRF_BLE_BMS_DEF(_name) \
+static nrf_ble_bms_t _name; \
+NRF_SDH_BLE_OBSERVER(_name ## _obs, \
+ NRF_BLE_BMS_BLE_OBSERVER_PRIO, \
+ nrf_ble_bms_on_ble_evt, &_name)
+
+#define NRF_BLE_BMS_FEATURE_LEN 3 //!< Length of the Feature Characteristic (in bytes).
+#define NRF_BLE_BMS_CTRLPT_MAX_LEN 128 //!< Maximum length of the Bond Management Control Point Characteristic (in bytes).
+#define NRF_BLE_BMS_CTRLPT_MIN_LEN 1 //!< Minimum length of the Bond Management Control Point Characteristic (in bytes).
+#define NRF_BLE_BMS_AUTH_CODE_MAX_LEN NRF_BLE_BMS_CTRLPT_MAX_LEN - 1 //!< Maximum length of the Bond Management Control Point Authorization Code (in bytes).
+
+/** @defgroup NRF_BLE_BMS_FEATURES BMS feature bits
+ * @{ */
+#define NRF_BLE_BMS_REQUESTING_DEVICE_BR_LE (0x01 << 0) //!< Delete bond of the requesting device (BR/EDR and LE).
+#define NRF_BLE_BMS_REQUESTING_DEVICE_BR_LE_AUTH_CODE (0x01 << 1) //!< Delete bond of the requesting device (BR/EDR and LE) with an authorization code.
+#define NRF_BLE_BMS_REQUESTING_DEVICE_BR (0x01 << 2) //!< Delete bond of the requesting device (BR/EDR transport only).
+#define NRF_BLE_BMS_REQUESTING_DEVICE_BR_AUTH_CODE (0x01 << 3) //!< Delete bond of the requesting device (BR/EDR transport only) with an authorization code.
+#define NRF_BLE_BMS_REQUESTING_DEVICE_LE (0x01 << 4) //!< Delete bond of the requesting device (LE transport only).
+#define NRF_BLE_BMS_REQUESTING_DEVICE_LE_AUTH_CODE (0x01 << 5) //!< Delete bond of the requesting device (LE transport only) with an authorization code.
+#define NRF_BLE_BMS_ALL_BONDS_BR_LE (0x01 << 6) //!< Delete all bonds on the device (BR/EDR and LE).
+#define NRF_BLE_BMS_ALL_BONDS_BR_LE_AUTH_CODE (0x01 << 7) //!< Delete all bonds on the device (BR/EDR and LE) with an authorization code.
+#define NRF_BLE_BMS_ALL_BONDS_BR (0x01 << 8) //!< Delete all bonds on the device (BR/EDR transport only).
+#define NRF_BLE_BMS_ALL_BONDS_BR_AUTH_CODE (0x01 << 9) //!< Delete all bonds on the device (BR/EDR transport only) with an authorization code.
+#define NRF_BLE_BMS_ALL_BONDS_LE (0x01 << 10) //!< Delete all bonds on the device (LE transport only).
+#define NRF_BLE_BMS_ALL_BONDS_LE_AUTH_CODE (0x01 << 11) //!< Delete all bonds on the device (LE transport only) with an authorization code.
+#define NRF_BLE_BMS_ALL_EXCEPT_REQUESTING_DEVICE_BR_LE (0x01 << 12) //!< Delete all bonds on the device except for the bond of the requesting device (BR/EDR and LE).
+#define NRF_BLE_BMS_ALL_EXCEPT_REQUESTING_DEVICE_BR_LE_AUTH_CODE (0x01 << 13) //!< Delete all bonds on the device except for the bond of the requesting device (BR/EDR and LE) with an authorization code.
+#define NRF_BLE_BMS_ALL_EXCEPT_REQUESTING_DEVICE_BR (0x01 << 14) //!< Delete all bonds on the device except for the bond of the requesting device (BR/EDR transport only).
+#define NRF_BLE_BMS_ALL_EXCEPT_REQUESTING_DEVICE_BR_AUTH_CODE (0x01 << 15) //!< Delete all bonds on the device except for the bond of the requesting device (BR/EDR transport only) with an authorization code.
+#define NRF_BLE_BMS_ALL_EXCEPT_REQUESTING_DEVICE_LE (0x01 << 16) //!< Delete all bonds on the device except for the bond of the requesting device (LE transport only).
+#define NRF_BLE_BMS_ALL_EXCEPT_REQUESTING_DEVICE_LE_AUTH_CODE (0x01 << 17) //!< Delete all bonds on the device except for the bond of the requesting device (LE transport only) with an authorization code.
+/** @} */
+
+#define NRF_BLE_BMS_OPCODE_NOT_SUPPORTED (BLE_GATT_STATUS_ATTERR_APP_BEGIN + 0) //!< Error sent back when receiving a control point write with an unsupported opcode.
+#define NRF_BLE_BMS_OPERATION_FAILED (BLE_GATT_STATUS_ATTERR_APP_BEGIN + 1) //!< Error sent back when a control point operation fails.
+
+
+/**@brief Supported features. */
+typedef struct
+{
+ bool delete_all : 1; //!< Indicates whether the application wants to support the operation to delete all bonds.
+ bool delete_all_auth : 1; //!< Indicates whether the application wants to support the operation to delete all bonds with authorization code.
+ bool delete_requesting : 1; //!< Indicates whether the application wants to support the operation to delete the bonds of the requesting device.
+ bool delete_requesting_auth : 1; //!< Indicates whether the application wants to support the operation to delete the bonds of the requesting device with authorization code.
+ bool delete_all_but_requesting : 1; //!< Indicates whether the application wants to support the operation to delete all bonds except for the bond of the requesting device.
+ bool delete_all_but_requesting_auth : 1; //!< Indicates whether the application wants to support the operation to delete all bonds except for the bond of the requesting device with authorization code.
+} nrf_ble_bms_features_t;
+
+/**@brief BMS Control Point opcodes. */
+typedef enum
+{
+ NRF_BLE_BMS_OP_DEL_BOND_REQ_DEVICE_BR_LE = 0x01, //!< Initiates the procedure to delete the bond of the requesting device on BR/EDR and LE transports.
+ NRF_BLE_BMS_OP_DEL_BOND_REQ_DEVICE_BR_ONLY = 0x02, //!< Initiates the procedure to delete the bond of the requesting device on BR/EDR transport.
+ NRF_BLE_BMS_OP_DEL_BOND_REQ_DEVICE_LE_ONLY = 0x03, //!< Initiates the procedure to delete the bond of the requesting device on LE transport.
+ NRF_BLE_BMS_OP_DEL_ALL_BONDS_ON_SERVER_BR_LE = 0x04, //!< Initiates the procedure to delete all bonds on the device on BR/EDR and LE transports.
+ NRF_BLE_BMS_OP_DEL_ALL_BONDS_ON_SERVER_BR_ONLY = 0x05, //!< Initiates the procedure to delete all bonds on the device on BR/EDR transport.
+ NRF_BLE_BMS_OP_DEL_ALL_BONDS_ON_SERVER_LE_ONLY = 0x06, //!< Initiates the procedure to delete all bonds on the device on LE transport.
+ NRF_BLE_BMS_OP_DEL_ALL_BUT_ACTIVE_BOND_BR_LE = 0x07, //!< Initiates the procedure to delete all bonds except for the one of the requesting device on BR/EDR and LE transports.
+ NRF_BLE_BMS_OP_DEL_ALL_BUT_ACTIVE_BOND_BR_ONLY = 0x08, //!< Initiates the procedure to delete all bonds except for the one of the requesting device on BR/EDR transport.
+ NRF_BLE_BMS_OP_DEL_ALL_BUT_ACTIVE_BOND_LE_ONLY = 0x09, //!< Initiates the procedure to delete all bonds except for the one of the requesting device on LE transport.
+ NRF_BLE_BMS_OP_NONE = 0xFF //!< Indicates an invalid opcode or no pending opcode.
+} nrf_ble_bms_op_t;
+
+/**@brief Authorization status values. */
+typedef enum
+{
+ NRF_BLE_BMS_AUTH_STATUS_ALLOWED, //!< Authorization is granted.
+ NRF_BLE_BMS_AUTH_STATUS_DENIED, //!< Authorization is denied.
+ NRF_BLE_BMS_AUTH_STATUS_PENDING //!< Authorization is pending.
+} nrf_ble_bms_auth_status_t;
+
+/**@brief Received authorization codes. */
+typedef struct
+{
+ uint8_t code[NRF_BLE_BMS_AUTH_CODE_MAX_LEN]; //!< Authorization code.
+ uint16_t len; //!< Length of the authorization code.
+} nrf_ble_bms_auth_code_t;
+
+/**@brief BMS event types. */
+typedef enum
+{
+ NRF_BLE_BMS_EVT_AUTH, //!< Event that indicates that the application shall verify the supplied authentication code.
+} nrf_ble_bms_evt_type_t;
+
+/**@brief BMS events. */
+typedef struct
+{
+ nrf_ble_bms_evt_type_t evt_type; //!< Type of event.
+ nrf_ble_bms_auth_code_t auth_code; //!< Received authorization code.
+} nrf_ble_bms_evt_t;
+
+/**@brief BMS control points. */
+typedef struct
+{
+ nrf_ble_bms_op_t op_code; //!< Control Point Op Code.
+ nrf_ble_bms_auth_code_t auth_code; //!< Control Point Authorization Code.
+} nrf_ble_bms_ctrlpt_t;
+
+// Forward declaration of the nrf_ble_bms_t type.
+typedef struct nrf_ble_bms_s nrf_ble_bms_t;
+
+/**@brief BMS event handler type. */
+typedef void (* nrf_ble_bms_bond_handler_t) (nrf_ble_bms_t const * p_bms);
+
+/**@brief BMS bond management callbacks. */
+typedef struct
+{
+ nrf_ble_bms_bond_handler_t delete_requesting; //!< Function to be called to delete the bonding information of the requesting device.
+ nrf_ble_bms_bond_handler_t delete_all; //!< Function to be called to delete the bonding information of all bonded devices.
+ nrf_ble_bms_bond_handler_t delete_all_except_requesting; //!< Function to be called to delete the bonding information of all bonded devices except for the requesting device.
+} nrf_ble_bms_bond_cbs_t;
+
+/**@brief BMS event handler type. The event handler returns a @ref BLE_GATT_STATUS_CODES "BLE GATT status code". */
+typedef void (* ble_bms_evt_handler_t) (nrf_ble_bms_t * p_bms, nrf_ble_bms_evt_t * p_evt);
+
+/**@brief BMS initialization structure that contains all information needed to initialize the service. */
+typedef struct
+{
+ ble_bms_evt_handler_t evt_handler; //!< Event handler to be called for handling events in the Bond Management Service.
+ ble_srv_error_handler_t error_handler; //!< Function to be called if an error occurs.
+ nrf_ble_bms_features_t feature; //!< Initial value for features of the service.
+ security_req_t bms_feature_sec_req; //!< Initial security level for the Feature characteristic.
+ security_req_t bms_ctrlpt_sec_req; //!< Initial security level for the Control Point characteristic.
+ nrf_ble_qwr_t * p_qwr; //!< Pointer to the initialized Queued Write context.
+ nrf_ble_bms_bond_cbs_t bond_callbacks; //!< Callback functions for deleting bonds.
+} nrf_ble_bms_init_t;
+
+/**@brief Status information for the service. */
+struct nrf_ble_bms_s
+{
+ uint16_t service_handle; //!< Handle of the Bond Management Service (as provided by the BLE stack).
+ uint16_t conn_handle; //!< Handle of the current connection (as provided by the BLE stack). @ref BLE_CONN_HANDLE_INVALID if not in a connection.
+ ble_bms_evt_handler_t evt_handler; //!< Event handler to be called for handling events in the Bond Management Service.
+ ble_srv_error_handler_t error_handler; //!< Function to be called if an error occurs.
+ nrf_ble_bms_features_t feature; //!< Value for features of the service (see @ref NRF_BLE_BMS_FEATURES).
+ ble_gatts_char_handles_t feature_handles; //!< Handles related to the Bond Management Feature characteristic.
+ ble_gatts_char_handles_t ctrlpt_handles; //!< Handles related to the Bond Management Control Point characteristic.
+ nrf_ble_bms_bond_cbs_t bond_callbacks; //!< Callback functions for deleting bonds.
+ nrf_ble_bms_auth_status_t auth_status; //!< Authorization status.
+};
+
+
+/**@brief Function for responding to an authorization request.
+ *
+ * @details This function should be called when receiving the @ref NRF_BLE_BMS_EVT_AUTH event to
+ * respond to the service with an authorization result.
+ *
+ * @param[in] p_bms BMS structure.
+ * @param[in] authorize Authorization response. True if the authorization is considered successful.
+ *
+ * @retval NRF_ERROR_NULL If @p p_bms was NULL.
+ * @retval NRF_ERROR_INVALID_STATE If no authorization request was pending.
+ * @retval NRF_SUCCESS If the response was received successfully.
+ */
+ret_code_t nrf_ble_bms_auth_response(nrf_ble_bms_t * p_bms, bool authorize);
+
+
+/**@brief Function for initializing the Bond Management Service.
+ *
+ * @param[out] p_bms BMS structure.
+ * @param[in] p_bms_init Information needed to initialize the service.
+ *
+ * @retval NRF_ERROR_NULL If @p p_bms or @p p_bms_init was NULL.
+ * @retval NRF_SUCCESS If the service was initialized successfully.
+ * Otherwise, an error code is returned.
+ */
+ret_code_t nrf_ble_bms_init(nrf_ble_bms_t * p_bms, nrf_ble_bms_init_t * p_bms_init);
+
+
+/**@brief Function for assigning handles to the Bond Management Service instance.
+ *
+ * @details Call this function when a link with a peer has been established to
+ * associate the link to this instance of the module.
+ *
+ * @param[in] p_bms Pointer to the BMS structure instance to associate.
+ * @param[in] conn_handle Connection handle to be associated with the given BMS instance.
+ *
+ * @retval NRF_ERROR_NULL If @p p_bms was NULL.
+ * @retval NRF_SUCCESS If the operation was successful.
+ */
+ret_code_t nrf_ble_bms_set_conn_handle(nrf_ble_bms_t * p_bms, uint16_t conn_handle);
+
+
+/**@brief Function for handling Bond Management BLE stack events.
+ *
+ * @details This function handles all events from the BLE stack that are of interest to the Bond Management Service.
+ *
+ * @param[in] p_ble_evt Event received from the BLE stack.
+ * @param[in] p_context BMS structure.
+ */
+void nrf_ble_bms_on_ble_evt(ble_evt_t const * p_ble_evt, void * p_context);
+
+
+/**@brief Function for handling events from the @ref nrf_ble_qwr.
+ *
+ * @param[in] p_bms BMS structure.
+ * @param[in] p_qwr Queued Write structure.
+ * @param[in] p_evt Event received from the Queued Writes module.
+ *
+ * @retval BLE_GATT_STATUS_SUCCESS If the received event is accepted.
+ * @retval NRF_BLE_QWR_REJ_REQUEST_ERR_CODE If the received event is not relevant for any of this module's attributes.
+ * @retval BLE_BMS_OPCODE_NOT_SUPPORTED If the received opcode is not supported.
+ * @retval BLE_GATT_STATUS_ATTERR_INSUF_AUTHORIZATION If the application handler returns that the authorization code is not valid.
+ */
+uint16_t nrf_ble_bms_on_qwr_evt(nrf_ble_bms_t * p_bms,
+ nrf_ble_qwr_t * p_qwr,
+ nrf_ble_qwr_evt_t * p_evt);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // NRF_BLE_BMS_H__
+
+/** @} */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/common/ble_advdata.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/common/ble_advdata.c
new file mode 100644
index 0000000..894a5e9
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/common/ble_advdata.c
@@ -0,0 +1,827 @@
+/**
+ * Copyright (c) 2012 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#include "ble_advdata.h"
+#include "ble_gap.h"
+#include "ble_srv_common.h"
+#include "sdk_common.h"
+
+// NOTE: For now, Security Manager Out of Band Flags (OOB) are omitted from the advertising data.
+
+
+// Types of LE Bluetooth Device Address AD type
+#define AD_TYPE_BLE_DEVICE_ADDR_TYPE_PUBLIC 0UL
+#define AD_TYPE_BLE_DEVICE_ADDR_TYPE_RANDOM 1UL
+
+#define UUID16_SIZE 2 /**< Size of 16 bit UUID. */
+#define UUID32_SIZE 4 /**< Size of 32 bit UUID. */
+#define UUID128_SIZE 16 /**< Size of 128 bit UUID. */
+
+#define N_AD_TYPES 2 /**< The number of Advertising data types to search for at a time. */
+
+
+static ret_code_t ble_device_addr_encode(uint8_t * p_encoded_data,
+ uint16_t * p_offset,
+ uint16_t max_size)
+{
+ ret_code_t err_code;
+ ble_gap_addr_t device_addr;
+
+ // Check for buffer overflow.
+ if (((*p_offset) + AD_TYPE_BLE_DEVICE_ADDR_SIZE) > max_size)
+ {
+ return NRF_ERROR_DATA_SIZE;
+ }
+
+ // Get BLE address.
+ err_code = sd_ble_gap_addr_get(&device_addr);
+ VERIFY_SUCCESS(err_code);
+
+ // Encode LE Bluetooth Device Address.
+ p_encoded_data[*p_offset] = (uint8_t)(AD_TYPE_FIELD_SIZE +
+ AD_TYPE_BLE_DEVICE_ADDR_DATA_SIZE);
+ *p_offset += AD_LENGTH_FIELD_SIZE;
+ p_encoded_data[*p_offset] = BLE_GAP_AD_TYPE_LE_BLUETOOTH_DEVICE_ADDRESS;
+ *p_offset += AD_TYPE_FIELD_SIZE;
+ memcpy(&p_encoded_data[*p_offset], &device_addr.addr[0], BLE_GAP_ADDR_LEN);
+ *p_offset += BLE_GAP_ADDR_LEN;
+ if (BLE_GAP_ADDR_TYPE_PUBLIC == device_addr.addr_type)
+ {
+ p_encoded_data[*p_offset] = AD_TYPE_BLE_DEVICE_ADDR_TYPE_PUBLIC;
+ }
+ else
+ {
+ p_encoded_data[*p_offset] = AD_TYPE_BLE_DEVICE_ADDR_TYPE_RANDOM;
+ }
+ *p_offset += AD_TYPE_BLE_DEVICE_ADDR_TYPE_SIZE;
+
+ return NRF_SUCCESS;
+}
+
+static ret_code_t name_encode(const ble_advdata_t * p_advdata,
+ uint8_t * p_encoded_data,
+ uint16_t * p_offset,
+ uint16_t max_size)
+{
+ ret_code_t err_code;
+ uint16_t rem_adv_data_len;
+ uint16_t actual_length;
+ uint8_t adv_data_format;
+
+
+ // Validate parameters
+ if ((BLE_ADVDATA_SHORT_NAME == p_advdata->name_type) && (0 == p_advdata->short_name_len))
+ {
+ return NRF_ERROR_INVALID_PARAM;
+ }
+
+ // Check for buffer overflow.
+ if ( (((*p_offset) + AD_DATA_OFFSET) > max_size) ||
+ ( (BLE_ADVDATA_SHORT_NAME == p_advdata->name_type) &&
+ (((*p_offset) + AD_DATA_OFFSET + p_advdata->short_name_len) > max_size)))
+ {
+ return NRF_ERROR_DATA_SIZE;
+ }
+
+ rem_adv_data_len = max_size - (*p_offset) - AD_DATA_OFFSET;
+ actual_length = rem_adv_data_len;
+
+ // Get GAP device name and length
+ err_code = sd_ble_gap_device_name_get(&p_encoded_data[(*p_offset) + AD_DATA_OFFSET],
+ &actual_length);
+ VERIFY_SUCCESS(err_code);
+
+ // Check if device intend to use short name and it can fit available data size.
+ if ((p_advdata->name_type == BLE_ADVDATA_FULL_NAME) && (actual_length <= rem_adv_data_len))
+ {
+ // Complete device name can fit, setting Complete Name in Adv Data.
+ adv_data_format = BLE_GAP_AD_TYPE_COMPLETE_LOCAL_NAME;
+ }
+ else
+ {
+ // Else short name needs to be used. Or application has requested use of short name.
+ adv_data_format = BLE_GAP_AD_TYPE_SHORT_LOCAL_NAME;
+
+ // If application has set a preference on the short name size, it needs to be considered,
+ // else fit what can be fit.
+ if ((BLE_ADVDATA_SHORT_NAME == p_advdata->name_type) &&
+ (p_advdata->short_name_len <= rem_adv_data_len))
+ {
+ // Short name fits available size.
+ actual_length = p_advdata->short_name_len;
+ }
+ // Else whatever can fit the data buffer will be packed.
+ else
+ {
+ actual_length = rem_adv_data_len;
+ }
+ }
+
+ // There is only 1 byte intended to encode length which is (actual_length + AD_TYPE_FIELD_SIZE)
+ if (actual_length > (0x00FF - AD_TYPE_FIELD_SIZE))
+ {
+ return NRF_ERROR_DATA_SIZE;
+ }
+
+ // Complete name field in encoded data.
+ p_encoded_data[*p_offset] = (uint8_t)(AD_TYPE_FIELD_SIZE + actual_length);
+ *p_offset += AD_LENGTH_FIELD_SIZE;
+ p_encoded_data[*p_offset] = adv_data_format;
+ *p_offset += AD_TYPE_FIELD_SIZE;
+ *p_offset += actual_length;
+
+ return NRF_SUCCESS;
+}
+
+
+static ret_code_t appearance_encode(uint8_t * p_encoded_data,
+ uint16_t * p_offset,
+ uint16_t max_size)
+{
+ ret_code_t err_code;
+ uint16_t appearance;
+
+ // Check for buffer overflow.
+ if (((*p_offset) + AD_TYPE_APPEARANCE_SIZE) > max_size)
+ {
+ return NRF_ERROR_DATA_SIZE;
+ }
+
+ // Get GAP appearance field.
+ err_code = sd_ble_gap_appearance_get(&appearance);
+ VERIFY_SUCCESS(err_code);
+
+ // Encode Length, AD Type and Appearance.
+ p_encoded_data[*p_offset] = (uint8_t)(AD_TYPE_FIELD_SIZE + AD_TYPE_APPEARANCE_DATA_SIZE);
+ *p_offset += AD_LENGTH_FIELD_SIZE;
+ p_encoded_data[*p_offset] = BLE_GAP_AD_TYPE_APPEARANCE;
+ *p_offset += AD_TYPE_FIELD_SIZE;
+ *p_offset += uint16_encode(appearance, &p_encoded_data[*p_offset]);
+
+ return NRF_SUCCESS;
+}
+
+static ret_code_t flags_encode(int8_t flags,
+ uint8_t * p_encoded_data,
+ uint16_t * p_offset,
+ uint16_t max_size)
+{
+ // Check for buffer overflow.
+ if (((*p_offset) + AD_TYPE_FLAGS_SIZE) > max_size)
+ {
+ return NRF_ERROR_DATA_SIZE;
+ }
+
+ // Encode flags.
+ p_encoded_data[*p_offset] = (uint8_t)(AD_TYPE_FIELD_SIZE + AD_TYPE_FLAGS_DATA_SIZE);
+ *p_offset += AD_LENGTH_FIELD_SIZE;
+ p_encoded_data[*p_offset] = BLE_GAP_AD_TYPE_FLAGS;
+ *p_offset += AD_TYPE_FIELD_SIZE;
+ p_encoded_data[*p_offset] = flags;
+ *p_offset += AD_TYPE_FLAGS_DATA_SIZE;
+
+ return NRF_SUCCESS;
+}
+
+static ret_code_t tx_power_level_encode(int8_t tx_power_level,
+ uint8_t * p_encoded_data,
+ uint16_t * p_offset,
+ uint16_t max_size)
+{
+ // Check for buffer overflow.
+ if (((*p_offset) + AD_TYPE_TX_POWER_LEVEL_SIZE) > max_size)
+ {
+ return NRF_ERROR_DATA_SIZE;
+ }
+
+ // Encode TX Power Level.
+ p_encoded_data[*p_offset] = (uint8_t)(AD_TYPE_FIELD_SIZE +
+ AD_TYPE_TX_POWER_LEVEL_DATA_SIZE);
+ *p_offset += AD_LENGTH_FIELD_SIZE;
+ p_encoded_data[*p_offset] = BLE_GAP_AD_TYPE_TX_POWER_LEVEL;
+ *p_offset += AD_TYPE_FIELD_SIZE;
+ p_encoded_data[*p_offset] = tx_power_level;
+ *p_offset += AD_TYPE_TX_POWER_LEVEL_DATA_SIZE;
+
+ return NRF_SUCCESS;
+}
+
+
+static ret_code_t uuid_list_sized_encode(const ble_advdata_uuid_list_t * p_uuid_list,
+ uint8_t adv_type,
+ uint8_t uuid_size,
+ uint8_t * p_encoded_data,
+ uint16_t * p_offset,
+ uint16_t max_size)
+{
+ int i;
+ bool is_heading_written = false;
+ uint16_t start_pos = *p_offset;
+ uint16_t length;
+
+ for (i = 0; i < p_uuid_list->uuid_cnt; i++)
+ {
+ ret_code_t err_code;
+ uint8_t encoded_size;
+ ble_uuid_t uuid = p_uuid_list->p_uuids[i];
+
+ // Find encoded uuid size.
+ err_code = sd_ble_uuid_encode(&uuid, &encoded_size, NULL);
+ VERIFY_SUCCESS(err_code);
+
+ // Check size.
+ if (encoded_size == uuid_size)
+ {
+ uint8_t heading_bytes = (is_heading_written) ? 0 : AD_DATA_OFFSET;
+
+ // Check for buffer overflow
+ if (((*p_offset) + encoded_size + heading_bytes) > max_size)
+ {
+ return NRF_ERROR_DATA_SIZE;
+ }
+
+ if (!is_heading_written)
+ {
+ // Write AD structure heading.
+ *p_offset += AD_LENGTH_FIELD_SIZE;
+ p_encoded_data[*p_offset] = adv_type;
+ *p_offset += AD_TYPE_FIELD_SIZE;
+ is_heading_written = true;
+ }
+
+ // Write UUID.
+ err_code = sd_ble_uuid_encode(&uuid, &encoded_size, &p_encoded_data[*p_offset]);
+ VERIFY_SUCCESS(err_code);
+ *p_offset += encoded_size;
+ }
+ }
+
+ if (is_heading_written)
+ {
+ // Write length.
+ length = (*p_offset) - (start_pos + AD_LENGTH_FIELD_SIZE);
+ // There is only 1 byte intended to encode length
+ if (length > 0x00FF)
+ {
+ return NRF_ERROR_DATA_SIZE;
+ }
+ p_encoded_data[start_pos] = (uint8_t)length;
+ }
+
+ return NRF_SUCCESS;
+}
+
+
+static ret_code_t uuid_list_encode(const ble_advdata_uuid_list_t * p_uuid_list,
+ uint8_t adv_type_16,
+ uint8_t adv_type_128,
+ uint8_t * p_encoded_data,
+ uint16_t * p_offset,
+ uint16_t max_size)
+{
+ ret_code_t err_code;
+
+ // Encode 16 bit UUIDs.
+ err_code = uuid_list_sized_encode(p_uuid_list,
+ adv_type_16,
+ sizeof(uint16_le_t),
+ p_encoded_data,
+ p_offset,
+ max_size);
+ VERIFY_SUCCESS(err_code);
+
+ // Encode 128 bit UUIDs.
+ err_code = uuid_list_sized_encode(p_uuid_list,
+ adv_type_128,
+ sizeof(ble_uuid128_t),
+ p_encoded_data,
+ p_offset,
+ max_size);
+ VERIFY_SUCCESS(err_code);
+
+ return NRF_SUCCESS;
+}
+
+
+static ret_code_t conn_int_check(const ble_advdata_conn_int_t *p_conn_int)
+{
+ // Check Minimum Connection Interval.
+ if ((p_conn_int->min_conn_interval < 0x0006) ||
+ (
+ (p_conn_int->min_conn_interval > 0x0c80) &&
+ (p_conn_int->min_conn_interval != 0xffff)
+ )
+ )
+ {
+ return NRF_ERROR_INVALID_PARAM;
+ }
+
+ // Check Maximum Connection Interval.
+ if ((p_conn_int->max_conn_interval < 0x0006) ||
+ (
+ (p_conn_int->max_conn_interval > 0x0c80) &&
+ (p_conn_int->max_conn_interval != 0xffff)
+ )
+ )
+ {
+ return NRF_ERROR_INVALID_PARAM;
+ }
+
+ // Make sure Minimum Connection Interval is not bigger than Maximum Connection Interval.
+ if ((p_conn_int->min_conn_interval != 0xffff) &&
+ (p_conn_int->max_conn_interval != 0xffff) &&
+ (p_conn_int->min_conn_interval > p_conn_int->max_conn_interval)
+ )
+ {
+ return NRF_ERROR_INVALID_PARAM;
+ }
+
+ return NRF_SUCCESS;
+}
+
+
+static ret_code_t conn_int_encode(const ble_advdata_conn_int_t * p_conn_int,
+ uint8_t * p_encoded_data,
+ uint16_t * p_offset,
+ uint16_t max_size)
+{
+ ret_code_t err_code;
+
+ // Check for buffer overflow.
+ if (((*p_offset) + AD_TYPE_CONN_INT_SIZE) > max_size)
+ {
+ return NRF_ERROR_DATA_SIZE;
+ }
+
+ // Check parameters.
+ err_code = conn_int_check(p_conn_int);
+ VERIFY_SUCCESS(err_code);
+
+ // Encode Length and AD Type.
+ p_encoded_data[*p_offset] = (uint8_t)(AD_TYPE_FIELD_SIZE + AD_TYPE_CONN_INT_DATA_SIZE);
+ *p_offset += AD_LENGTH_FIELD_SIZE;
+ p_encoded_data[*p_offset] = BLE_GAP_AD_TYPE_SLAVE_CONNECTION_INTERVAL_RANGE;
+ *p_offset += AD_TYPE_FIELD_SIZE;
+
+ // Encode Minimum and Maximum Connection Intervals.
+ *p_offset += uint16_encode(p_conn_int->min_conn_interval, &p_encoded_data[*p_offset]);
+ *p_offset += uint16_encode(p_conn_int->max_conn_interval, &p_encoded_data[*p_offset]);
+
+ return NRF_SUCCESS;
+}
+
+
+static ret_code_t manuf_specific_data_encode(const ble_advdata_manuf_data_t * p_manuf_sp_data,
+ uint8_t * p_encoded_data,
+ uint16_t * p_offset,
+ uint16_t max_size)
+{
+ uint32_t data_size = AD_TYPE_MANUF_SPEC_DATA_ID_SIZE + p_manuf_sp_data->data.size;
+
+ // Check for buffer overflow.
+ if (((*p_offset) + AD_DATA_OFFSET + data_size) > max_size)
+ {
+ return NRF_ERROR_DATA_SIZE;
+ }
+
+ // There is only 1 byte intended to encode length which is (data_size + AD_TYPE_FIELD_SIZE)
+ if (data_size > (0x00FF - AD_TYPE_FIELD_SIZE))
+ {
+ return NRF_ERROR_DATA_SIZE;
+ }
+
+ // Encode Length and AD Type.
+ p_encoded_data[*p_offset] = (uint8_t)(AD_TYPE_FIELD_SIZE + data_size);
+ *p_offset += AD_LENGTH_FIELD_SIZE;
+ p_encoded_data[*p_offset] = BLE_GAP_AD_TYPE_MANUFACTURER_SPECIFIC_DATA;
+ *p_offset += AD_TYPE_FIELD_SIZE;
+
+ // Encode Company Identifier.
+ *p_offset += uint16_encode(p_manuf_sp_data->company_identifier, &p_encoded_data[*p_offset]);
+
+ // Encode additional manufacturer specific data.
+ if (p_manuf_sp_data->data.size > 0)
+ {
+ if (p_manuf_sp_data->data.p_data == NULL)
+ {
+ return NRF_ERROR_INVALID_PARAM;
+ }
+ memcpy(&p_encoded_data[*p_offset], p_manuf_sp_data->data.p_data, p_manuf_sp_data->data.size);
+ *p_offset += p_manuf_sp_data->data.size;
+ }
+
+ return NRF_SUCCESS;
+}
+
+// Implemented only for 16-bit UUIDs
+static ret_code_t service_data_encode(const ble_advdata_t * p_advdata,
+ uint8_t * p_encoded_data,
+ uint16_t * p_offset,
+ uint16_t max_size)
+{
+ uint8_t i;
+
+ // Check parameter consistency.
+ if (p_advdata->p_service_data_array == NULL)
+ {
+ return NRF_ERROR_INVALID_PARAM;
+ }
+
+ for (i = 0; i < p_advdata->service_data_count; i++)
+ {
+ ble_advdata_service_data_t * p_service_data;
+ uint32_t data_size;
+
+ p_service_data = &p_advdata->p_service_data_array[i];
+ // For now implemented only for 16-bit UUIDs
+ data_size = AD_TYPE_SERV_DATA_16BIT_UUID_SIZE + p_service_data->data.size;
+
+ // There is only 1 byte intended to encode length which is (data_size + AD_TYPE_FIELD_SIZE)
+ if (data_size > (0x00FF - AD_TYPE_FIELD_SIZE))
+ {
+ return NRF_ERROR_DATA_SIZE;
+ }
+
+ // Encode Length and AD Type.
+ p_encoded_data[*p_offset] = (uint8_t)(AD_TYPE_FIELD_SIZE + data_size);
+ *p_offset += AD_LENGTH_FIELD_SIZE;
+ p_encoded_data[*p_offset] = BLE_GAP_AD_TYPE_SERVICE_DATA;
+ *p_offset += AD_TYPE_FIELD_SIZE;
+
+ // Encode service 16-bit UUID.
+ *p_offset += uint16_encode(p_service_data->service_uuid, &p_encoded_data[*p_offset]);
+
+ // Encode additional service data.
+ if (p_service_data->data.size > 0)
+ {
+ if (p_service_data->data.p_data == NULL)
+ {
+ return NRF_ERROR_INVALID_PARAM;
+ }
+ memcpy(&p_encoded_data[*p_offset], p_service_data->data.p_data, p_service_data->data.size);
+ *p_offset += p_service_data->data.size;
+ }
+ }
+
+ return NRF_SUCCESS;
+}
+
+ret_code_t ble_advdata_encode(ble_advdata_t const * const p_advdata,
+ uint8_t * const p_encoded_data,
+ uint16_t * const p_len)
+{
+ ret_code_t err_code = NRF_SUCCESS;
+ uint16_t max_size = *p_len;
+ *p_len = 0;
+
+ // Encode LE Bluetooth Device Address
+ if (p_advdata->include_ble_device_addr)
+ {
+ err_code = ble_device_addr_encode(p_encoded_data, p_len, max_size);
+ VERIFY_SUCCESS(err_code);
+ }
+
+ // Encode appearance.
+ if (p_advdata->include_appearance)
+ {
+ err_code = appearance_encode(p_encoded_data, p_len, max_size);
+ VERIFY_SUCCESS(err_code);
+ }
+
+ //Encode Flags
+ if (p_advdata->flags != 0 )
+ {
+ err_code = flags_encode(p_advdata->flags, p_encoded_data, p_len, max_size);
+ VERIFY_SUCCESS(err_code);
+ }
+
+ // Encode TX power level.
+ if (p_advdata->p_tx_power_level != NULL)
+ {
+ err_code = tx_power_level_encode(*p_advdata->p_tx_power_level,
+ p_encoded_data,
+ p_len,
+ max_size);
+ VERIFY_SUCCESS(err_code);
+ }
+
+ // Encode 'more available' uuid list.
+ if (p_advdata->uuids_more_available.uuid_cnt > 0)
+ {
+ err_code = uuid_list_encode(&p_advdata->uuids_more_available,
+ BLE_GAP_AD_TYPE_16BIT_SERVICE_UUID_MORE_AVAILABLE,
+ BLE_GAP_AD_TYPE_128BIT_SERVICE_UUID_MORE_AVAILABLE,
+ p_encoded_data,
+ p_len,
+ max_size);
+ VERIFY_SUCCESS(err_code);
+ }
+
+ // Encode 'complete' uuid list.
+ if (p_advdata->uuids_complete.uuid_cnt > 0)
+ {
+ err_code = uuid_list_encode(&p_advdata->uuids_complete,
+ BLE_GAP_AD_TYPE_16BIT_SERVICE_UUID_COMPLETE,
+ BLE_GAP_AD_TYPE_128BIT_SERVICE_UUID_COMPLETE,
+ p_encoded_data,
+ p_len,
+ max_size);
+ VERIFY_SUCCESS(err_code);
+ }
+
+ // Encode 'solicited service' uuid list.
+ if (p_advdata->uuids_solicited.uuid_cnt > 0)
+ {
+ err_code = uuid_list_encode(&p_advdata->uuids_solicited,
+ BLE_GAP_AD_TYPE_SOLICITED_SERVICE_UUIDS_16BIT,
+ BLE_GAP_AD_TYPE_SOLICITED_SERVICE_UUIDS_128BIT,
+ p_encoded_data,
+ p_len,
+ max_size);
+ VERIFY_SUCCESS(err_code);
+ }
+
+ // Encode Slave Connection Interval Range.
+ if (p_advdata->p_slave_conn_int != NULL)
+ {
+ err_code = conn_int_encode(p_advdata->p_slave_conn_int, p_encoded_data, p_len, max_size);
+ VERIFY_SUCCESS(err_code);
+ }
+
+ // Encode Manufacturer Specific Data.
+ if (p_advdata->p_manuf_specific_data != NULL)
+ {
+ err_code = manuf_specific_data_encode(p_advdata->p_manuf_specific_data,
+ p_encoded_data,
+ p_len,
+ max_size);
+ VERIFY_SUCCESS(err_code);
+ }
+
+ // Encode Service Data.
+ if (p_advdata->service_data_count > 0)
+ {
+ err_code = service_data_encode(p_advdata, p_encoded_data, p_len, max_size);
+ VERIFY_SUCCESS(err_code);
+ }
+
+ // Encode name. WARNING: it is encoded last on purpose since too long device name is truncated.
+ if (p_advdata->name_type != BLE_ADVDATA_NO_NAME)
+ {
+ err_code = name_encode(p_advdata, p_encoded_data, p_len, max_size);
+ VERIFY_SUCCESS(err_code);
+ }
+
+ return err_code;
+}
+
+
+uint16_t ble_advdata_search(uint8_t const * p_encoded_data,
+ uint16_t data_len,
+ uint16_t * p_offset,
+ uint8_t ad_type)
+{
+ if ((p_encoded_data == NULL) || (p_offset == NULL))
+ {
+ return 0;
+ }
+
+ uint16_t i = 0;
+
+ while (((i < *p_offset) || (p_encoded_data[i + 1] != ad_type)) && (i < data_len))
+ {
+ // Jump to next data.
+ i += (p_encoded_data[i] + 1);
+ }
+
+ if (i >= data_len)
+ {
+ return 0;
+ }
+ else
+ {
+ *p_offset = i + 2;
+ return (p_encoded_data[i] - 1);
+ }
+}
+
+
+uint8_t * ble_advdata_parse(uint8_t * p_encoded_data,
+ uint16_t data_len,
+ uint8_t ad_type)
+{
+ uint16_t offset = 0;
+ uint16_t len = ble_advdata_search(p_encoded_data, data_len, &offset, ad_type);
+
+ if (len == 0)
+ {
+ return NULL;
+ }
+ else
+ {
+ return &p_encoded_data[offset];
+ }
+}
+
+
+bool ble_advdata_name_find(uint8_t const * p_encoded_data,
+ uint16_t data_len,
+ char const * p_target_name)
+{
+ uint16_t parsed_name_len;
+ uint8_t const * p_parsed_name;
+ uint16_t data_offset = 0;
+
+ if (p_target_name == NULL)
+ {
+ return false;
+ }
+
+
+ parsed_name_len = ble_advdata_search(p_encoded_data,
+ data_len,
+ &data_offset,
+ BLE_GAP_AD_TYPE_COMPLETE_LOCAL_NAME);
+
+ p_parsed_name = &p_encoded_data[data_offset];
+
+ if ( (data_offset != 0)
+ && (parsed_name_len != 0)
+ && (strlen(p_target_name) == parsed_name_len)
+ && (memcmp(p_target_name, p_parsed_name, parsed_name_len) == 0))
+ {
+ return true;
+ }
+
+ return false;
+}
+
+
+bool ble_advdata_short_name_find(uint8_t const * p_encoded_data,
+ uint16_t data_len,
+ char const * p_target_name,
+ uint8_t const short_name_min_len)
+{
+ uint16_t parsed_name_len;
+ uint8_t const * p_parsed_name;
+ uint16_t data_offset = 0;
+
+ if (p_target_name == NULL)
+ {
+ return false;
+ }
+
+ parsed_name_len = ble_advdata_search(p_encoded_data,
+ data_len,
+ &data_offset,
+ BLE_GAP_AD_TYPE_SHORT_LOCAL_NAME);
+
+ p_parsed_name = &p_encoded_data[data_offset];
+
+ if ( (data_offset != 0)
+ && (parsed_name_len != 0)
+ && (parsed_name_len >= short_name_min_len)
+ && (parsed_name_len < strlen(p_target_name))
+ && (memcmp(p_target_name, p_parsed_name, parsed_name_len) == 0))
+ {
+ return true;
+ }
+
+ return false;
+}
+
+
+bool ble_advdata_uuid_find(uint8_t const * p_encoded_data,
+ uint16_t data_len,
+ ble_uuid_t const * p_target_uuid)
+{
+
+ ret_code_t err_code;
+ uint16_t data_offset = 0;
+ uint8_t raw_uuid_len = UUID128_SIZE;
+ uint8_t const * p_parsed_uuid;
+ uint16_t parsed_uuid_len = data_len;
+ uint8_t raw_uuid[UUID128_SIZE];
+ uint8_t ad_types[N_AD_TYPES];
+
+ err_code = sd_ble_uuid_encode(p_target_uuid, &raw_uuid_len, raw_uuid);
+
+ if ((p_encoded_data == NULL) || (err_code != NRF_SUCCESS))
+ {
+ // Invalid p_encoded_data or p_target_uuid.
+ return false;
+ }
+
+ switch (raw_uuid_len)
+ {
+ case UUID16_SIZE:
+ ad_types[0] = BLE_GAP_AD_TYPE_16BIT_SERVICE_UUID_COMPLETE;
+ ad_types[1] = BLE_GAP_AD_TYPE_16BIT_SERVICE_UUID_MORE_AVAILABLE;
+ break;
+
+ case UUID32_SIZE:
+ // Not currently supported by sd_ble_uuid_encode().
+ ad_types[0] = BLE_GAP_AD_TYPE_32BIT_SERVICE_UUID_COMPLETE;
+ ad_types[1] = BLE_GAP_AD_TYPE_32BIT_SERVICE_UUID_MORE_AVAILABLE;
+ break;
+
+ case UUID128_SIZE:
+ ad_types[0] = BLE_GAP_AD_TYPE_128BIT_SERVICE_UUID_COMPLETE;
+ ad_types[1] = BLE_GAP_AD_TYPE_128BIT_SERVICE_UUID_MORE_AVAILABLE;
+ break;
+
+ default:
+ return false;
+ }
+
+ for (uint8_t i = 0; (i < N_AD_TYPES) && (data_offset == 0); i++)
+ {
+ parsed_uuid_len = ble_advdata_search(p_encoded_data, data_len, &data_offset, ad_types[i]);
+ }
+
+ if (data_offset == 0)
+ {
+ // Could not find any relevant UUIDs in the encoded data.
+ return false;
+ }
+
+ p_parsed_uuid = &p_encoded_data[data_offset];
+
+ // Verify if any UUID matches the given UUID.
+ for (uint16_t list_offset = 0; list_offset < parsed_uuid_len; list_offset += raw_uuid_len)
+ {
+ if (memcmp(&p_parsed_uuid[list_offset], raw_uuid, raw_uuid_len) == 0)
+ {
+ return true;
+ }
+ }
+
+ // Could not find the UUID among the encoded data.
+ return false;
+}
+
+
+bool ble_advdata_appearance_find(uint8_t const * p_encoded_data,
+ uint16_t data_len,
+ uint16_t const * p_target_appearance)
+{
+ uint16_t data_offset = 0;
+ uint8_t appearance_len;
+ uint16_t decoded_appearance;
+
+ appearance_len = ble_advdata_search(p_encoded_data, data_len, &data_offset, BLE_GAP_AD_TYPE_APPEARANCE);
+
+ if ( (data_offset == 0)
+ || (p_target_appearance == NULL)
+ || (appearance_len == 0))
+ {
+ // Could not find any Appearance in the encoded data, or invalid p_target_appearance.
+ return false;
+ }
+
+ decoded_appearance = uint16_decode(&p_encoded_data[data_offset]);
+
+ if (decoded_appearance == *p_target_appearance)
+ {
+ return true;
+ }
+
+ // Could not find the appearance among the encoded data.
+ return false;
+}
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/common/ble_advdata.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/common/ble_advdata.h
new file mode 100644
index 0000000..ad15efc
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/common/ble_advdata.h
@@ -0,0 +1,326 @@
+/**
+ * Copyright (c) 2012 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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
+ *
+ * @defgroup ble_sdk_lib_advdata Advertising and Scan Response Data Encoder
+ * @{
+ * @ingroup ble_sdk_lib
+ * @brief Functions for encoding data in the Advertising and Scan Response Data format,
+ * and for passing the data to the stack.
+ */
+
+#ifndef BLE_ADVDATA_H__
+#define BLE_ADVDATA_H__
+
+#include <stdint.h>
+#include <stdbool.h>
+#include <string.h>
+#include "ble.h"
+#include "sdk_common.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+#define AD_LENGTH_FIELD_SIZE 1UL /**< Advertising Data and Scan Response format contains 1 octet for the length. */
+#define AD_TYPE_FIELD_SIZE 1UL /**< Advertising Data and Scan Response format contains 1 octet for the AD type. */
+#define AD_DATA_OFFSET (AD_LENGTH_FIELD_SIZE + AD_TYPE_FIELD_SIZE) /**< Offset for the AD data field of the Advertising Data and Scan Response format. */
+
+#define AD_TYPE_BLE_DEVICE_ADDR_TYPE_SIZE 1UL /**< Data size (in octets) of the Address type of the LE Bluetooth Device Address AD type. */
+#define AD_TYPE_BLE_DEVICE_ADDR_DATA_SIZE (BLE_GAP_ADDR_LEN + \
+ AD_TYPE_BLE_DEVICE_ADDR_TYPE_SIZE) /**< Data size (in octets) of the LE Bluetooth Device Address AD type. */
+#define AD_TYPE_BLE_DEVICE_ADDR_SIZE (AD_DATA_OFFSET + \
+ AD_TYPE_BLE_DEVICE_ADDR_DATA_SIZE) /**< Size (in octets) of the LE Bluetooth Device Address AD type. */
+#define AD_TYPE_APPEARANCE_DATA_SIZE 2UL /**< Data size (in octets) of the Appearance AD type. */
+#define AD_TYPE_APPEARANCE_SIZE (AD_DATA_OFFSET + \
+ AD_TYPE_APPEARANCE_DATA_SIZE) /**< Size (in octets) of the Appearance AD type. */
+#define AD_TYPE_FLAGS_DATA_SIZE 1UL /**< Data size (in octets) of the Flags AD type. */
+#define AD_TYPE_FLAGS_SIZE (AD_DATA_OFFSET + \
+ AD_TYPE_FLAGS_DATA_SIZE) /**< Size (in octets) of the Flags AD type. */
+#define AD_TYPE_TX_POWER_LEVEL_DATA_SIZE 1UL /**< Data size (in octets) of the TX Power Level AD type. */
+#define AD_TYPE_TX_POWER_LEVEL_SIZE (AD_DATA_OFFSET + \
+ AD_TYPE_TX_POWER_LEVEL_DATA_SIZE) /**< Size (in octets) of the TX Power Level AD type. */
+#define AD_TYPE_CONN_INT_DATA_SIZE 4UL /**< Data size (in octets) of the Slave Connection Interval Range AD type. */
+#define AD_TYPE_CONN_INT_SIZE (AD_DATA_OFFSET + \
+ AD_TYPE_CONN_INT_DATA_SIZE) /**< Data size (in octets) of the Slave Connection Interval Range AD type. */
+#define AD_TYPE_MANUF_SPEC_DATA_ID_SIZE 2UL /**< Size (in octets) of the Company Identifier Code, which is a part of the Manufacturer Specific Data AD type. */
+#define AD_TYPE_SERV_DATA_16BIT_UUID_SIZE 2UL /**< Size (in octets) of the 16-bit UUID, which is a part of the Service Data AD type. */
+
+#define BLE_ADV_DATA_MATCH_FULL_NAME 0xff
+
+
+/**@brief Security Manager TK value. */
+typedef struct
+{
+ uint8_t tk[BLE_GAP_SEC_KEY_LEN]; /**< Array containing TK value in little-endian format. */
+} ble_advdata_tk_value_t;
+
+/**@brief Advertising data LE Role types. This enumeration contains the options available for the LE role inside
+ * the advertising data. */
+typedef enum
+{
+ BLE_ADVDATA_ROLE_NOT_PRESENT = 0, /**< LE Role AD structure not present. */
+ BLE_ADVDATA_ROLE_ONLY_PERIPH, /**< Only Peripheral Role supported. */
+ BLE_ADVDATA_ROLE_ONLY_CENTRAL, /**< Only Central Role supported. */
+ BLE_ADVDATA_ROLE_BOTH_PERIPH_PREFERRED, /**< Peripheral and Central Role supported. Peripheral Role preferred for connection establishment. */
+ BLE_ADVDATA_ROLE_BOTH_CENTRAL_PREFERRED /**< Peripheral and Central Role supported. Central Role preferred for connection establishment */
+} ble_advdata_le_role_t;
+
+/**@brief Advertising data name type. This enumeration contains the options available for the device name inside
+ * the advertising data. */
+typedef enum
+{
+ BLE_ADVDATA_NO_NAME, /**< Include no device name in advertising data. */
+ BLE_ADVDATA_SHORT_NAME, /**< Include short device name in advertising data. */
+ BLE_ADVDATA_FULL_NAME /**< Include full device name in advertising data. */
+} ble_advdata_name_type_t;
+
+/**@brief UUID list type. */
+typedef struct
+{
+ uint16_t uuid_cnt; /**< Number of UUID entries. */
+ ble_uuid_t * p_uuids; /**< Pointer to UUID array entries. */
+} ble_advdata_uuid_list_t;
+
+/**@brief Connection interval range structure. */
+typedef struct
+{
+ uint16_t min_conn_interval; /**< Minimum connection interval, in units of 1.25 ms, range 6 to 3200 (7.5 ms to 4 s). */
+ uint16_t max_conn_interval; /**< Maximum connection interval, in units of 1.25 ms, range 6 to 3200 (7.5 ms to 4 s). The value 0xFFFF indicates no specific maximum. */
+} ble_advdata_conn_int_t;
+
+/**@brief Manufacturer specific data structure. */
+typedef struct
+{
+ uint16_t company_identifier; /**< Company identifier code. */
+ uint8_array_t data; /**< Additional manufacturer specific data. */
+} ble_advdata_manuf_data_t;
+
+/**@brief Service data structure. */
+typedef struct
+{
+ uint16_t service_uuid; /**< Service UUID. */
+ uint8_array_t data; /**< Additional service data. */
+} ble_advdata_service_data_t;
+
+/**@brief Advertising data structure. This structure contains all options and data needed for encoding and
+ * setting the advertising data. */
+typedef struct
+{
+ ble_advdata_name_type_t name_type; /**< Type of device name. */
+ uint8_t short_name_len; /**< Length of short device name (if short type is specified). */
+ bool include_appearance; /**< Determines if Appearance shall be included. */
+ uint8_t flags; /**< Advertising data Flags field. */
+ int8_t * p_tx_power_level; /**< TX Power Level field. */
+ ble_advdata_uuid_list_t uuids_more_available; /**< List of UUIDs in the 'More Available' list. */
+ ble_advdata_uuid_list_t uuids_complete; /**< List of UUIDs in the 'Complete' list. */
+ ble_advdata_uuid_list_t uuids_solicited; /**< List of solicited UUIDs. */
+ ble_advdata_conn_int_t * p_slave_conn_int; /**< Slave Connection Interval Range. */
+ ble_advdata_manuf_data_t * p_manuf_specific_data; /**< Manufacturer specific data. */
+ ble_advdata_service_data_t * p_service_data_array; /**< Array of Service data structures. */
+ uint8_t service_data_count; /**< Number of Service data structures. */
+ bool include_ble_device_addr; /**< Determines if LE Bluetooth Device Address shall be included. */
+ ble_advdata_le_role_t le_role; /**< LE Role field. Included when different from @ref BLE_ADVDATA_ROLE_NOT_PRESENT. @warning This field can be used only for NFC. For BLE advertising, set it to NULL. */
+ ble_advdata_tk_value_t * p_tk_value; /**< Security Manager TK value field. Included when different from NULL. @warning This field can be used only for NFC. For BLE advertising, set it to NULL.*/
+ uint8_t * p_sec_mgr_oob_flags; /**< Security Manager Out Of Band Flags field. Included when different from NULL. @warning This field can be used only for NFC. For BLE advertising, set it to NULL.*/
+ ble_gap_lesc_oob_data_t * p_lesc_data; /**< LE Secure Connections OOB data. Included when different from NULL. @warning This field can be used only for NFC. For BLE advertising, set it to NULL.*/
+} ble_advdata_t;
+
+/**@brief Function for encoding data in the Advertising and Scan Response data format (AD structures).
+ *
+ * @details This function encodes data into the Advertising and Scan Response data format
+ * (AD structures) based on the fields in the supplied structures. This function can be
+ * used to create a payload of Advertising packet or Scan Response packet, or a payload of
+ * NFC message intended for initiating the Out-of-Band pairing.
+ *
+ * @param[in] p_advdata Pointer to the structure for specifying the content of encoded data.
+ * @param[out] p_encoded_data Pointer to the buffer where encoded data will be returned.
+ * @param[in,out] p_len \c in: Size of \p p_encoded_data buffer.
+ * \c out: Length of encoded data.
+ *
+ * @retval NRF_SUCCESS If the operation was successful.
+ * @retval NRF_ERROR_INVALID_PARAM If the operation failed because a wrong parameter was provided in
+ * \p p_advdata.
+ * @retval NRF_ERROR_DATA_SIZE If the operation failed because not all the requested data could
+ * fit into the provided buffer or some encoded AD structure is too
+ * long and its length cannot be encoded with one octet.
+ *
+ * @warning This API may override the application's request to use the long name and use a short name
+ * instead. This truncation will occur in case the long name does not fit the provided buffer size.
+ * The application can specify a preferred short name length if truncation is required.
+ * For example, if the complete device name is ABCD_HRMonitor, the application can specify the short name
+ * length to be 8, so that the short device name appears as ABCD_HRM instead of ABCD_HRMo or ABCD_HRMoni
+ * if the available size for the short name is 9 or 12 respectively, to have a more appropriate short name.
+ * However, it should be noted that this is just a preference that the application can specify, and
+ * if the preference is too large to fit in the provided buffer, the name can be truncated further.
+ */
+ret_code_t ble_advdata_encode(ble_advdata_t const * const p_advdata,
+ uint8_t * const p_encoded_data,
+ uint16_t * const p_len);
+
+
+/**@brief Function for searching encoded Advertising or Scan Response data for specific data types.
+ *
+ * @details This function searches through encoded data e.g. the data produced by
+ * @ref ble_advdata_encode, or the data found in Advertising reports
+ * (@ref BLE_GAP_EVT_ADV_REPORT), and gives the offset of the data within the data buffer.
+ * The data with type \p ad_type can be found at p_encoded_data[*p_offset] after calling
+ * the function. This function can iterate through multiple instances of data of one
+ * type by calling it again with the offset provided by the previous call.
+ *
+ * Example code for finding multiple instances of one type of data:
+ * offset = 0;
+ * ble_advdata_search(&data, len, &offset, AD_TYPE);
+ * first_instance_of_data = data[offset];
+ * ble_advdata_search(&data, len, &offset, AD_TYPE);
+ * second_instance_of_data = data[offset];
+ *
+ * @param[in] p_encoded_data The data buffer containing the encoded Advertising data.
+ * @param[in] data_len The length of the data buffer \p p_encoded_data.
+ * @param[inout] p_offset \c in: The offset to start searching from.
+ * \c out: The offset the data type can be found at.
+ * This value is not changed if the call returns 0.
+ * @param[in] ad_type The type of data to search for.
+ *
+ * @return The length of the found data, or 0 if no data was found with the the type \p ad_type,
+ * or if \p p_encoded_data or \p p_offset were NULL.
+ */
+uint16_t ble_advdata_search(uint8_t const * p_encoded_data,
+ uint16_t data_len,
+ uint16_t * p_offset,
+ uint8_t ad_type);
+
+/**@brief Function for getting specific data from encoded Advertising or Scan Response data.
+ *
+ * @details This function searches through encoded data e.g. the data produced by
+ * @ref ble_advdata_encode, or the data found in Advertising reports
+ * (@ref BLE_GAP_EVT_ADV_REPORT), and returns a pointer directly to the data within the
+ * data buffer.
+ *
+ * Example code:
+ * ad_type_data = ble_advdata_parse(&data, len, AD_TYPE);
+ *
+ * @param[in] p_encoded_data Data buffer containing the encoded Advertising data.
+ * @param[in] data_len Length of the data buffer \p p_encoded_data.
+ * @param[in] ad_type Type of data to search for.
+ *
+ * @return Pointer to the found data, or NULL if no data was found with the type \p ad_type,
+ * or if \p p_encoded_data or \p p_data_len were NULL.
+ */
+uint8_t * ble_advdata_parse(uint8_t * p_encoded_data,
+ uint16_t data_len,
+ uint8_t ad_type);
+
+
+/**@brief Function for searching through encoded Advertising data for a complete local name.
+ *
+ * @param[in] p_encoded_data Data buffer containing the encoded Advertising data.
+ * @param[in] data_len Length of the data buffer \p p_encoded_data.
+ * @param[in] p_target_name Name to search for.
+ *
+ * @retval true If \p p_target_name was found among \p p_encoded_data, as a complete local name.
+ * @retval false If \p p_target_name was not found among \p p_encoded_data, or if \p p_encoded_data
+ * or \p p_target_name was NULL.
+ */
+bool ble_advdata_name_find(uint8_t const * p_encoded_data,
+ uint16_t data_len,
+ char const * p_target_name);
+
+
+/**@brief Function for searching through encoded Advertising data for a device shortened name.
+ *
+ * @param[in] p_encoded_data Data buffer containing the encoded Advertising data.
+ * @param[in] data_len Length of the data buffer \p p_encoded_data.
+ * @param[in] p_target_name Name to search for.
+ * @param[in] short_name_min_len Minimum length of the shortened name.
+ * For example, if the advertising data has a shortened name 'No' and this parameter is
+ * set to 4 with a target_name set to Nordic_XXX it will return false, but if
+ * the shortened name in the advertising data is 'Nord', it will return true.
+ * @note: If the shortened name in the Advertising data has the same length as the target name,
+ * this function will return false, since this means that the complete name is actually
+ * longer, thus different than the target name.
+ *
+ * @retval true If \p p_target_name was found among \p p_encoded_data, as short local name.
+ * @retval false If \p p_target_name was not found among \p p_encoded_data, or if \p p_encoded_data
+ * or \p p_target_name was NULL.
+ */
+bool ble_advdata_short_name_find(uint8_t const * p_encoded_data,
+ uint16_t data_len,
+ char const * p_target_name,
+ uint8_t const short_name_min_len);
+
+/**@brief Function for searching through encoded Advertising data for a UUID (16-bit or 128-bit).
+ *
+ * @param[in] p_encoded_data Data buffer containing the encoded Advertising data.
+ * @param[in] data_len Length of the data buffer \p p_encoded_data.
+ * @param[in] p_target_uuid UUID to search for.
+ *
+ * @retval true If \p p_target_uuid was found among \p p_encoded_data.
+ * @retval false If \p p_target_uuid was not found among \p p_encoded_data, or if \p p_encoded_data
+ * or \p p_target_uuid was NULL.
+ */
+bool ble_advdata_uuid_find(uint8_t const * p_encoded_data,
+ uint16_t data_len,
+ ble_uuid_t const * p_target_uuid);
+
+
+/**@brief Function for searching through encoded Advertising data for an appearance.
+ *
+ * @param[in] p_encoded_data Data buffer containing the encoded Advertising data.
+ * @param[in] data_len Length of the data buffer \p p_encoded_data.
+ * @param[in] p_target_appearance Appearance to search for.
+ *
+ * @retval true If \p p_target_appearance was found among \p p_encoded_data.
+ * @retval false If \p p_target_appearance was not found among \p p_encoded_data, or if \p p_encoded_data
+ * or \p p_target_appearance was NULL.
+ */
+bool ble_advdata_appearance_find(uint8_t const * p_encoded_data,
+ uint16_t data_len,
+ uint16_t const * p_target_appearance);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // BLE_ADVDATA_H__
+
+/** @} */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/common/ble_conn_params.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/common/ble_conn_params.c
new file mode 100644
index 0000000..4cb78f4
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/common/ble_conn_params.c
@@ -0,0 +1,572 @@
+/**
+ * Copyright (c) 2012 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#include "sdk_common.h"
+#if NRF_MODULE_ENABLED(NRF_BLE_CONN_PARAMS)
+#include <stdlib.h>
+#include "nrf.h"
+#include "sdk_errors.h"
+#include "ble_hci.h"
+#include "ble_err.h"
+#include "ble_conn_params.h"
+#include "ble_srv_common.h"
+#include "ble_conn_state.h"
+#include "nrf_sdh_ble.h"
+#include "app_timer.h"
+#include "app_util.h"
+
+
+#define NRF_BLE_CONN_PARAMS_INSTANCE_COUNT NRF_SDH_BLE_PERIPHERAL_LINK_COUNT //!< The number of @ref ble_conn_params_instance_t instances kept by the conn_params module.
+
+#if (NRF_BLE_CONN_PARAMS_INSTANCE_COUNT < 1)
+#error Invalid NRF_SDH_BLE_PERIPHERAL_LINK_COUNT value. Set it in SDK config (nrf_sdh_ble).
+#endif
+
+/** @brief Each peripheral link has such an instance associated with it.
+ */
+typedef struct
+{
+ uint16_t conn_handle; //!< The connection handle of this link. If this is @ref BLE_CONN_HANDLE_INVALID, the instance is free.
+ app_timer_id_t timer_id; //!< The ID of the timer associated with this link.
+ uint8_t update_count; //!< The number of times the connection parameters have been attempted negotiated on this link.
+ uint8_t params_ok; //!< Whether the current connection parameters on this link are acceptable according to the @p preferred_conn_params, and configured maximum deviations.
+ ble_gap_conn_params_t preferred_conn_params; //!< The desired connection parameters for this link.
+} ble_conn_params_instance_t;
+
+static app_timer_t m_timer_data[NRF_BLE_CONN_PARAMS_INSTANCE_COUNT] = {{{0}}}; //!< Data needed for timers.
+static ble_conn_params_instance_t m_conn_params_instances[NRF_BLE_CONN_PARAMS_INSTANCE_COUNT] = {{0}}; //!< Configuration data for each connection.
+static ble_conn_params_init_t m_conn_params_config; //!< Configuration as provided by the application during intialization.
+static ble_gap_conn_params_t m_preferred_conn_params; //!< The preferred connection parameters as specified during initialization.
+//lint -esym(551, m_preferred_conn_params) "Not accessed"
+
+
+/**@brief Function for retrieving the conn_params instance belonging to a conn_handle
+ *
+ * @params[in] conn_handle The connection handle to retrieve the instance of.
+ *
+ * @return A pointer to the instance, or NULL if no instance was found with that conn_handle.
+ */
+static ble_conn_params_instance_t * instance_get(uint16_t conn_handle)
+{
+ //lint -save -e681 "Loop not entered" when NRF_BLE_CONN_PARAMS_INSTANCE_COUNT is 0
+ for (uint32_t i = 0; i < NRF_BLE_CONN_PARAMS_INSTANCE_COUNT; i++)
+ {
+ if (m_conn_params_instances[i].conn_handle == conn_handle)
+ {
+ return &m_conn_params_instances[i];
+ }
+ }
+ //lint -restore
+ return NULL;
+}
+
+
+/**@brief Function for initializing an instance, and associating it with a conn_handle.
+ *
+ * @params[in] p_instance The instance to initialize and associate.
+ * @params[in] conn_handle The connection handle to associate with.
+ */
+static __INLINE void instance_claim(ble_conn_params_instance_t * p_instance, uint16_t conn_handle)
+{
+ p_instance->conn_handle = conn_handle;
+ p_instance->update_count = 0;
+ p_instance->preferred_conn_params = m_preferred_conn_params;
+}
+
+
+/**@brief Function for freeing an instance.
+ *
+ * @params[in] p_instance The instance to free.
+ */
+static __INLINE void instance_free(ble_conn_params_instance_t * p_instance)
+{
+ p_instance->conn_handle = BLE_CONN_HANDLE_INVALID;
+}
+
+
+/**@brief Function for validating a set of connection parameters against the preferred parameters.
+ *
+ * @param[in] p_preferred_conn_params The desired parameters.
+ * @param[in] p_actual_conn_params The parameters to validate.
+ * @param[in] max_slave_latency_err The amount of discrepancy in slave latency, in number of
+ * connection intervals, that will be accepted.
+ * @param[in] max_sup_timeout_err The amount of discrepancy in supervision timeout, in tens of
+ * milliseconds, that will be accepted.
+ *
+ * @return Whether the params in @p p_actual_conn_params are acceptable given the other parameters.
+ */
+static bool is_conn_params_ok(ble_gap_conn_params_t const * p_preferred_conn_params,
+ ble_gap_conn_params_t const * p_actual_conn_params,
+ uint16_t max_slave_latency_err,
+ uint16_t max_sup_timeout_err)
+{
+ uint32_t max_allowed_sl = p_preferred_conn_params->slave_latency + max_slave_latency_err;
+ uint32_t min_allowed_sl = p_preferred_conn_params->slave_latency
+ - MIN(max_slave_latency_err, p_preferred_conn_params->slave_latency);
+ uint32_t max_allowed_to = p_preferred_conn_params->conn_sup_timeout + max_sup_timeout_err;
+ uint32_t min_allowed_to = p_preferred_conn_params->conn_sup_timeout
+ - MIN(max_sup_timeout_err, p_preferred_conn_params->conn_sup_timeout);
+
+ // Check if interval is within the acceptable range.
+ // NOTE: Using max_conn_interval in the received event data because this contains
+ // the client's connection interval.
+ if ((p_actual_conn_params->max_conn_interval < p_preferred_conn_params->min_conn_interval)
+ || (p_actual_conn_params->max_conn_interval > p_preferred_conn_params->max_conn_interval))
+ {
+ return false;
+ }
+
+ // Check if slave latency is within the acceptable deviation.
+ if ((p_actual_conn_params->slave_latency < min_allowed_sl)
+ || (p_actual_conn_params->slave_latency > max_allowed_sl))
+ {
+ return false;
+ }
+
+ // Check if supervision timeout is within the acceptable deviation.
+ if ((p_actual_conn_params->conn_sup_timeout < min_allowed_to)
+ || (p_actual_conn_params->conn_sup_timeout > max_allowed_to))
+ {
+ return false;
+ }
+
+ return true;
+}
+
+
+static void send_error_evt(ret_code_t err_code)
+{
+ if (m_conn_params_config.error_handler != NULL)
+ {
+ m_conn_params_config.error_handler(err_code);
+ }
+}
+
+
+/**@brief Function for sending a conn_param_update request on-air, and handling errors.
+ *
+ * @param[in] conn_handle Connection to send request on.
+ * @param[in] p_new_conn_params Connection parameters to request.
+ *
+ * @return Whether the request was successfully sent.
+ */
+static bool send_update_request(uint16_t conn_handle, ble_gap_conn_params_t * p_new_conn_params)
+{
+ ret_code_t err_code;
+
+ err_code = sd_ble_gap_conn_param_update(conn_handle, p_new_conn_params);
+ if ((err_code != NRF_SUCCESS) && (err_code != NRF_ERROR_BUSY)) // NRF_ERROR_BUSY means another conn_param_update request is pending.
+ {
+ send_error_evt(err_code);
+ }
+
+ return (err_code == NRF_SUCCESS);
+}
+
+
+/**@brief Function called after conn_params_update_delay has happened. This is triggered by app_timer.
+ *
+ * @param[in] p_context Context identifying which connection this is for.
+ */
+static void update_timeout_handler(void * p_context)
+{
+ uint32_t conn_handle = (uint32_t)p_context;
+ ble_conn_params_instance_t * p_instance = instance_get(conn_handle);
+
+ if (p_instance != NULL)
+ {
+ // Check if we have reached the maximum number of attempts
+ if (p_instance->update_count < m_conn_params_config.max_conn_params_update_count)
+ {
+ bool update_sent = send_update_request(conn_handle, &p_instance->preferred_conn_params);
+ if (update_sent)
+ {
+ p_instance->update_count++;
+ }
+ }
+ else
+ {
+ p_instance->update_count = 0;
+
+ // Negotiation failed, disconnect automatically if this has been configured
+ if (m_conn_params_config.disconnect_on_fail)
+ {
+ ret_code_t err_code;
+
+ err_code = sd_ble_gap_disconnect(conn_handle, BLE_HCI_CONN_INTERVAL_UNACCEPTABLE);
+ if ((err_code != NRF_SUCCESS) && (err_code != NRF_ERROR_INVALID_STATE)) // NRF_ERROR_INVALID_STATE means disconnect is already in progress.
+ {
+ send_error_evt(err_code);
+ }
+ }
+
+ // Notify the application that the procedure has failed
+ if (m_conn_params_config.evt_handler != NULL)
+ {
+ ble_conn_params_evt_t evt;
+
+ evt.evt_type = BLE_CONN_PARAMS_EVT_FAILED;
+ evt.conn_handle = conn_handle;
+ m_conn_params_config.evt_handler(&evt);
+ }
+ }
+ }
+}
+
+
+ret_code_t ble_conn_params_init(const ble_conn_params_init_t * p_init)
+{
+ ret_code_t err_code;
+
+ VERIFY_PARAM_NOT_NULL(p_init);
+
+ m_conn_params_config = *p_init;
+ m_conn_params_config.p_conn_params = &m_preferred_conn_params;
+
+ if (p_init->p_conn_params != NULL)
+ {
+ // Set the connection params in stack.
+ err_code = sd_ble_gap_ppcp_set(p_init->p_conn_params);
+ if (err_code != NRF_SUCCESS)
+ {
+ return err_code;
+ }
+ m_preferred_conn_params = *p_init->p_conn_params;
+ }
+ else
+ {
+ // Get the (default) connection params from stack.
+ err_code = sd_ble_gap_ppcp_get(&m_preferred_conn_params);
+ if (err_code != NRF_SUCCESS)
+ {
+ return err_code;
+ }
+ }
+
+ //lint -save -e681 "Loop not entered" when NRF_BLE_CONN_PARAMS_INSTANCE_COUNT is 0
+ for (uint32_t i = 0; i < NRF_BLE_CONN_PARAMS_INSTANCE_COUNT; i++)
+ {
+ ble_conn_params_instance_t * p_instance = &m_conn_params_instances[i];
+
+ instance_free(p_instance);
+ p_instance->timer_id = &m_timer_data[i];
+
+ err_code = app_timer_create(&p_instance->timer_id,
+ APP_TIMER_MODE_SINGLE_SHOT,
+ update_timeout_handler);
+ if (err_code != NRF_SUCCESS)
+ {
+ return NRF_ERROR_INTERNAL;
+ }
+ }
+ //lint -restore
+
+ return NRF_SUCCESS;
+}
+
+
+ret_code_t ble_conn_params_stop(void)
+{
+ ret_code_t err_code;
+
+ //lint -save -e681 "Loop not entered" when NRF_BLE_CONN_PARAMS_INSTANCE_COUNT is 0
+ for (uint32_t i = 0; i < NRF_BLE_CONN_PARAMS_INSTANCE_COUNT; i++)
+ {
+ err_code = app_timer_stop(m_conn_params_instances[i].timer_id);
+ switch (err_code)
+ {
+ case NRF_SUCCESS:
+ /* do nothing */
+ break;
+
+ case NRF_ERROR_INVALID_STATE:
+ /* do nothing */
+ break;
+
+ case NRF_ERROR_NO_MEM:
+ return NRF_ERROR_BUSY;
+
+ case NRF_ERROR_INVALID_PARAM:
+ /* fallthrough */
+ default:
+ return NRF_ERROR_INTERNAL;
+ }
+ }
+ //lint -restore
+ return NRF_SUCCESS;
+}
+
+
+/**@brief Function for taking appropriate action based on the current state of connection parameters.
+ *
+ * @param[in] conn_handle Connection to handle.
+ * @param[in] p_instance Configuration for the connection.
+ */
+static void conn_params_negotiation(uint16_t conn_handle, ble_conn_params_instance_t * p_instance)
+ {
+ // Start negotiation if the received connection parameters are not acceptable
+ if (!p_instance->params_ok)
+ {
+ ret_code_t err_code;
+ uint32_t timeout_ticks;
+
+ if (p_instance->update_count == 0)
+ {
+ // First connection parameter update
+ timeout_ticks = m_conn_params_config.first_conn_params_update_delay;
+ }
+ else
+ {
+ timeout_ticks = m_conn_params_config.next_conn_params_update_delay;
+ }
+
+ err_code = app_timer_start(p_instance->timer_id, timeout_ticks, (void *)(uint32_t)conn_handle);
+ if (err_code != NRF_SUCCESS)
+ {
+ send_error_evt(err_code);
+ }
+ }
+ else
+ {
+ p_instance->update_count = 0;
+
+ // Notify the application that the procedure has succeeded
+ if (m_conn_params_config.evt_handler != NULL)
+ {
+ ble_conn_params_evt_t evt;
+
+ evt.evt_type = BLE_CONN_PARAMS_EVT_SUCCEEDED;
+ evt.conn_handle = conn_handle;
+ m_conn_params_config.evt_handler(&evt);
+ }
+ }
+}
+
+
+/**@brief Function for handling a connection event from the SoftDevice.
+ *
+ * @param[in] p_ble_evt Event from the SoftDevice.
+ */
+static void on_connect(ble_evt_t const * p_ble_evt)
+{
+ uint8_t role = p_ble_evt->evt.gap_evt.params.connected.role;
+ uint16_t conn_handle = p_ble_evt->evt.gap_evt.conn_handle;
+
+ if (role != BLE_GAP_ROLE_PERIPH)
+ {
+ return;
+ }
+
+ ble_conn_params_instance_t * p_instance = instance_get(BLE_CONN_HANDLE_INVALID);
+
+ if (p_instance == NULL)
+ {
+ send_error_evt(NRF_ERROR_NO_MEM);
+ return;
+ }
+
+ instance_claim(p_instance, conn_handle);
+ p_instance->params_ok = is_conn_params_ok(&p_instance->preferred_conn_params,
+ &p_ble_evt->evt.gap_evt.params.connected.conn_params,
+ NRF_BLE_CONN_PARAMS_MAX_SLAVE_LATENCY_DEVIATION,
+ NRF_BLE_CONN_PARAMS_MAX_SUPERVISION_TIMEOUT_DEVIATION);
+
+ // Check if we shall handle negotiation on connect
+ if (m_conn_params_config.start_on_notify_cccd_handle == BLE_GATT_HANDLE_INVALID)
+ {
+ conn_params_negotiation(conn_handle, p_instance);
+ }
+}
+
+
+/**@brief Function for handling a disconnection event from the SoftDevice.
+ *
+ * @param[in] p_ble_evt Event from the SoftDevice.
+ */
+static void on_disconnect(ble_evt_t const * p_ble_evt)
+{
+ ret_code_t err_code;
+ uint16_t conn_handle = p_ble_evt->evt.gap_evt.conn_handle;
+ ble_conn_params_instance_t * p_instance = instance_get(conn_handle);
+
+ if (p_instance != NULL)
+ {
+ // Stop timer if running
+ err_code = app_timer_stop(p_instance->timer_id);
+ if (err_code != NRF_SUCCESS)
+ {
+ send_error_evt(err_code);
+ }
+
+ instance_free(p_instance);
+ }
+}
+
+
+/**@brief Function for handling a GATT write event from the SoftDevice.
+ *
+ * @details To provide the start_on_notify_cccd_handle functionality.
+ *
+ * @param[in] p_ble_evt Event from the SoftDevice.
+ */
+static void on_write(ble_evt_t const * p_ble_evt)
+{
+ ble_gatts_evt_write_t const * p_evt_write = &p_ble_evt->evt.gatts_evt.params.write;
+
+ // Check if this is the correct CCCD
+ if (
+ (p_evt_write->handle == m_conn_params_config.start_on_notify_cccd_handle)
+ &&
+ (p_evt_write->len == 2)
+ )
+ {
+ uint16_t conn_handle = p_ble_evt->evt.gap_evt.conn_handle;
+ ble_conn_params_instance_t * p_instance = instance_get(conn_handle);
+
+ if (p_instance != NULL)
+ {
+ // Check if this is a 'start notification'
+ if (ble_srv_is_notification_enabled(p_evt_write->data))
+ {
+ // Do connection parameter negotiation if necessary
+ conn_params_negotiation(conn_handle, p_instance);
+ }
+ else
+ {
+ ret_code_t err_code;
+
+ // Stop timer if running
+ err_code = app_timer_stop(p_instance->timer_id);
+ if (err_code != NRF_SUCCESS)
+ {
+ send_error_evt(err_code);
+ }
+ }
+ }
+ }
+}
+
+
+/**@brief Function for handling a connection parameter update event from the SoftDevice.
+ *
+ * @details This event means the peer central has changed the connection parameters or declined our
+ * request.
+ *
+ * @param[in] p_ble_evt Event from the SoftDevice.
+ */
+static void on_conn_params_update(ble_evt_t const * p_ble_evt)
+{
+ uint16_t conn_handle = p_ble_evt->evt.gap_evt.conn_handle;
+ ble_conn_params_instance_t * p_instance = instance_get(conn_handle);
+
+ if (p_instance != NULL)
+ {
+ p_instance->params_ok = is_conn_params_ok(
+ &p_instance->preferred_conn_params,
+ &p_ble_evt->evt.gap_evt.params.conn_param_update.conn_params,
+ NRF_BLE_CONN_PARAMS_MAX_SLAVE_LATENCY_DEVIATION,
+ NRF_BLE_CONN_PARAMS_MAX_SUPERVISION_TIMEOUT_DEVIATION);
+
+ conn_params_negotiation(conn_handle, p_instance);
+ }
+}
+
+
+/**
+ * @brief Function for handling BLE events.
+ *
+ * @param[in] p_ble_evt Event received from the BLE stack.
+ * @param[in] p_context Context.
+ */
+static void ble_evt_handler(ble_evt_t const * p_ble_evt, void * p_context)
+{
+ switch (p_ble_evt->header.evt_id)
+ {
+ case BLE_GAP_EVT_CONNECTED:
+ on_connect(p_ble_evt);
+ break;
+
+ case BLE_GAP_EVT_DISCONNECTED:
+ on_disconnect(p_ble_evt);
+ break;
+
+ case BLE_GATTS_EVT_WRITE:
+ on_write(p_ble_evt);
+ break;
+
+ case BLE_GAP_EVT_CONN_PARAM_UPDATE:
+ on_conn_params_update(p_ble_evt);
+ break;
+
+ default:
+ // No implementation needed.
+ break;
+ }
+}
+
+
+ret_code_t ble_conn_params_change_conn_params(uint16_t conn_handle,
+ ble_gap_conn_params_t * p_new_params)
+{
+ ret_code_t err_code = BLE_ERROR_INVALID_CONN_HANDLE;
+ ble_conn_params_instance_t * p_instance = instance_get(conn_handle);
+
+ if (p_new_params == NULL)
+ {
+ p_new_params = &m_preferred_conn_params;
+ }
+
+ if (p_instance != NULL)
+ {
+ // Send request to central.
+ err_code = sd_ble_gap_conn_param_update(conn_handle, p_new_params);
+ if (err_code == NRF_SUCCESS)
+ {
+ p_instance->params_ok = false;
+ p_instance->update_count = 1;
+ p_instance->preferred_conn_params = *p_new_params;
+ }
+ }
+
+ return err_code;
+}
+
+NRF_SDH_BLE_OBSERVER(m_ble_observer, BLE_CONN_PARAMS_BLE_OBSERVER_PRIO, ble_evt_handler, NULL);
+
+#endif //ENABLED
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/common/ble_conn_params.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/common/ble_conn_params.h
new file mode 100644
index 0000000..d76db72
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/common/ble_conn_params.h
@@ -0,0 +1,156 @@
+/**
+ * Copyright (c) 2012 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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
+ *
+ * @defgroup ble_conn_params Connection Parameters Negotiation
+ * @{
+ * @ingroup ble_sdk_lib
+ * @brief Module for initiating and executing a connection parameters negotiation procedure.
+ */
+
+#ifndef BLE_CONN_PARAMS_H__
+#define BLE_CONN_PARAMS_H__
+
+#include <stdint.h>
+#include "ble.h"
+#include "ble_srv_common.h"
+#include "sdk_errors.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**@brief Connection Parameters Module event type. */
+typedef enum
+{
+ BLE_CONN_PARAMS_EVT_FAILED, //!< Negotiation procedure failed.
+ BLE_CONN_PARAMS_EVT_SUCCEEDED //!< Negotiation procedure succeeded.
+} ble_conn_params_evt_type_t;
+
+/**@brief Connection Parameters Module event. */
+typedef struct
+{
+ ble_conn_params_evt_type_t evt_type; //!< Type of event.
+ uint16_t conn_handle; //!< Connection the event refers to.
+} ble_conn_params_evt_t;
+
+/**@brief Connection Parameters Module event handler type. */
+typedef void (*ble_conn_params_evt_handler_t) (ble_conn_params_evt_t * p_evt);
+
+/**@brief Connection Parameters Module init structure. This contains all options and data needed for
+ * initialization of the connection parameters negotiation module. */
+typedef struct
+{
+ ble_gap_conn_params_t * p_conn_params; //!< Pointer to the connection parameters desired by the application. When calling ble_conn_params_init, if this parameter is set to NULL, the connection parameters will be fetched from host.
+ uint32_t first_conn_params_update_delay; //!< Time from initiating event (connect or start of notification) to first time sd_ble_gap_conn_param_update is called (in number of timer ticks).
+ uint32_t next_conn_params_update_delay; //!< Time between each call to sd_ble_gap_conn_param_update after the first (in number of timer ticks). Recommended value 30 seconds as per BLUETOOTH SPECIFICATION Version 4.0.
+ uint8_t max_conn_params_update_count; //!< Number of attempts before giving up the negotiation.
+ uint16_t start_on_notify_cccd_handle; //!< If procedure is to be started when notification is started, set this to the handle of the corresponding CCCD. Set to BLE_GATT_HANDLE_INVALID if procedure is to be started on connect event.
+ bool disconnect_on_fail; //!< Set to TRUE if a failed connection parameters update shall cause an automatic disconnection, set to FALSE otherwise.
+ ble_conn_params_evt_handler_t evt_handler; //!< Event handler to be called for handling events in the Connection Parameters.
+ ble_srv_error_handler_t error_handler; //!< Function to be called in case of an error.
+} ble_conn_params_init_t;
+
+
+/**@brief Function for initializing the Connection Parameters module.
+ *
+ * @note If the negotiation procedure should be triggered when notification/indication of
+ * any characteristic is enabled by the peer, then this function must be called after
+ * having initialized the services.
+ *
+ * @param[in] p_init This contains information needed to initialize this module.
+ *
+ * @retval NRF_SUCCESS Successful initialization.
+ * @retval NRF_ERROR_INVALID_ADDR The provided Connection Parameters pointer is invalid.
+ * @retval NRF_ERROR_INVALID_PARAM The provided Connection Parameters are not valid.
+ * @retval NRF_ERROR_NULL @p p_init was NULL.
+ * @retval NRF_ERROR_INTERNAL An unexpected error occurred.
+ */
+ret_code_t ble_conn_params_init(const ble_conn_params_init_t * p_init);
+
+/**@brief Function for stopping the Connection Parameters module.
+ *
+ * @details This function is intended to be used by the application to clean up the connection
+ * parameters update module. This will stop the connection parameters update timer if
+ * running, thereby preventing any impending connection parameters update procedure. This
+ * function must be called by the application when it needs to clean itself up (for
+ * example, before disabling the bluetooth SoftDevice) so that an unwanted timer expiry
+ * event can be avoided.
+ *
+ * @retval NRF_SUCCESS Successfully stopped module.
+ * @retval NRF_ERROR_BUSY Could not complete operation at this time. Try again later.
+ Note that some timers may have been disabled.
+ * @retval NRF_ERROR_INTERNAL An unexpected error occurred.
+ */
+ret_code_t ble_conn_params_stop(void);
+
+/**@brief Function for changing the current connection parameters to a new set.
+ *
+ * @details Use this function to change the connection parameters to a new set of parameter
+ * (ie different from the ones given at init of the module).
+ * This function is useful for scenario where most of the time the application
+ * needs a relatively big connection interval, and just sometimes, for a temporary
+ * period requires shorter connection interval, for example to transfer a higher
+ * amount of data.
+ * If the given parameters does not match the current connection's parameters
+ * this function initiates a new negotiation.
+ *
+ * @param[in] conn_handle The connection to change connection parameters on.
+ * @param[in] p_new_params This contains the new connections parameters to setup.
+ *
+ * @retval NRF_SUCCESS Successfully started Connection Parameter update procedure.
+ * @retval NRF_ERROR_INVALID_ADDR The provided Connection Parameters pointer is invalid.
+ * @retval NRF_ERROR_INVALID_PARAM The provided Connection Parameters are not valid.
+ * @retval BLE_ERROR_INVALID_CONN_HANDLE The provided connection handle is invalid.
+ * @retval NRF_ERROR_INVALID_STATE The connection is not in a state where this operation can
+ * performed.
+ * @retval NRF_ERROR_BUSY Could not start operation at this time. Try again later.
+ * @retval NRF_ERROR_NO_MEM The SoftDevice lacks the memory to perform the action.
+ */
+ret_code_t ble_conn_params_change_conn_params(uint16_t conn_handle,
+ ble_gap_conn_params_t * p_new_params);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // BLE_CONN_PARAMS_H__
+
+/** @} */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/common/ble_conn_state.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/common/ble_conn_state.c
new file mode 100644
index 0000000..32c6b96
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/common/ble_conn_state.c
@@ -0,0 +1,481 @@
+/**
+ * Copyright (c) 2015 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#include "ble_conn_state.h"
+#include <stdbool.h>
+#include <stdint.h>
+#include <string.h>
+#include "ble.h"
+#include "nrf_atflags.h"
+#include "app_error.h"
+#include "nrf_sdh_ble.h"
+#include "app_util_platform.h"
+
+
+
+#define DEFAULT_FLAG_COLLECTION_COUNT 5 /**< The number of flags kept for each connection, excluding user flags. */
+#define TOTAL_FLAG_COLLECTION_COUNT (DEFAULT_FLAG_COLLECTION_COUNT \
+ + BLE_CONN_STATE_USER_FLAG_COUNT) /**< The number of flags kept for each connection, including user flags. */
+
+/**@brief Structure containing all the flag collections maintained by the Connection State module.
+ */
+typedef struct
+{
+ nrf_atflags_t valid_flags; /**< Flags indicating which connection handles are valid. */
+ nrf_atflags_t connected_flags; /**< Flags indicating which connections are connected, since disconnected connection handles will not immediately be invalidated. */
+ nrf_atflags_t central_flags; /**< Flags indicating in which connections the local device is the central. */
+ nrf_atflags_t encrypted_flags; /**< Flags indicating which connections are encrypted. */
+ nrf_atflags_t mitm_protected_flags; /**< Flags indicating which connections have encryption with protection from man-in-the-middle attacks. */
+ nrf_atflags_t user_flags[BLE_CONN_STATE_USER_FLAG_COUNT]; /**< Flags that can be reserved by the user. The flags will be cleared when a connection is invalidated, otherwise, the user is wholly responsible for the flag states. */
+} ble_conn_state_flag_collections_t;
+
+
+ANON_UNIONS_ENABLE;
+
+/**@brief Structure containing the internal state of the Connection State module.
+ */
+typedef struct
+{
+ nrf_atflags_t acquired_flags; /**< Bitmap for keeping track of which user flags have been acquired. */
+ union
+ {
+ ble_conn_state_flag_collections_t flags; /**< Flag collections kept by the Connection State module. */
+ nrf_atflags_t flag_array[TOTAL_FLAG_COLLECTION_COUNT]; /**< Flag collections as array to allow iterating over all flag collections. */
+ };
+} ble_conn_state_t;
+
+ANON_UNIONS_DISABLE;
+
+
+static ble_conn_state_t m_bcs = {0}; /**< Instantiation of the internal state. */
+
+
+/**@brief Function for resetting all internal memory to the values it had at initialization.
+ */
+void bcs_internal_state_reset(void)
+{
+ memset( &m_bcs, 0, sizeof(ble_conn_state_t) );
+}
+
+
+ble_conn_state_conn_handle_list_t conn_handle_list_get(nrf_atflags_t flags)
+{
+ ble_conn_state_conn_handle_list_t conn_handle_list;
+ conn_handle_list.len = 0;
+
+ if (flags != 0)
+ {
+ for (uint32_t i = 0; i < BLE_CONN_STATE_MAX_CONNECTIONS; i++)
+ {
+ if (nrf_atflags_get(&flags, i))
+ {
+ conn_handle_list.conn_handles[conn_handle_list.len++] = i;
+ }
+ }
+ }
+
+ return conn_handle_list;
+}
+
+
+uint32_t active_flag_count(nrf_atflags_t flags)
+{
+ uint32_t set_flag_count = 0;
+
+ for (uint32_t i = 0; i < BLE_CONN_STATE_MAX_CONNECTIONS; i++)
+ {
+ if (nrf_atflags_get(&flags, i))
+ {
+ set_flag_count += 1;
+ }
+ }
+ return set_flag_count;
+}
+
+
+/**@brief Function for activating a connection record.
+ *
+ * @param p_record The record to activate.
+ * @param conn_handle The connection handle to copy into the record.
+ * @param role The role of the connection.
+ *
+ * @return whether the record was activated successfully.
+ */
+static bool record_activate(uint16_t conn_handle)
+{
+ if (conn_handle >= BLE_CONN_STATE_MAX_CONNECTIONS)
+ {
+ return false;
+ }
+ nrf_atflags_set(&m_bcs.flags.connected_flags, conn_handle);
+ nrf_atflags_set(&m_bcs.flags.valid_flags, conn_handle);
+ return true;
+}
+
+
+/**@brief Function for marking a connection record as invalid and resetting the values.
+ *
+ * @param p_record The record to invalidate.
+ */
+static void record_invalidate(uint16_t conn_handle)
+{
+ for (uint32_t i = 0; i < TOTAL_FLAG_COLLECTION_COUNT; i++)
+ {
+ nrf_atflags_clear(&m_bcs.flag_array[i], conn_handle);
+ }
+}
+
+
+/**@brief Function for marking a connection as disconnected. See @ref BLE_CONN_STATUS_DISCONNECTED.
+ *
+ * @param p_record The record of the connection to set as disconnected.
+ */
+static void record_set_disconnected(uint16_t conn_handle)
+{
+ nrf_atflags_clear(&m_bcs.flags.connected_flags, conn_handle);
+}
+
+
+/**@brief Function for invalidating records with a @ref BLE_CONN_STATUS_DISCONNECTED
+ * connection status
+ */
+static void record_purge_disconnected()
+{
+ nrf_atflags_t disconnected_flags = ~m_bcs.flags.connected_flags;
+ ble_conn_state_conn_handle_list_t disconnected_list;
+
+ UNUSED_RETURN_VALUE(nrf_atomic_u32_and(&disconnected_flags, m_bcs.flags.valid_flags));
+ disconnected_list = conn_handle_list_get(disconnected_flags);
+
+ for (uint32_t i = 0; i < disconnected_list.len; i++)
+ {
+ record_invalidate(disconnected_list.conn_handles[i]);
+ }
+}
+
+
+/**@brief Function for checking if a user flag has been acquired.
+ *
+ * @param[in] flag_id Which flag to check.
+ *
+ * @return Whether the flag has been acquired.
+ */
+static bool user_flag_is_acquired(ble_conn_state_user_flag_id_t flag_id)
+{
+ return nrf_atflags_get(&m_bcs.acquired_flags, flag_id);
+}
+
+
+void ble_conn_state_init(void)
+{
+ bcs_internal_state_reset();
+}
+
+/**
+ * @brief Function for handling BLE events.
+ *
+ * @param[in] p_ble_evt Event received from the BLE stack.
+ * @param[in] p_context Context.
+ */
+static void ble_evt_handler(ble_evt_t const * p_ble_evt, void * p_context)
+{
+ uint16_t conn_handle = p_ble_evt->evt.gap_evt.conn_handle;
+ switch (p_ble_evt->header.evt_id)
+ {
+ case BLE_GAP_EVT_CONNECTED:
+ record_purge_disconnected();
+
+ if ( !record_activate(conn_handle) )
+ {
+ // No more records available. Should not happen.
+ APP_ERROR_HANDLER(NRF_ERROR_NO_MEM);
+ }
+ else if ((p_ble_evt->evt.gap_evt.params.connected.role != BLE_GAP_ROLE_PERIPH))
+ {
+ // Central
+ nrf_atflags_set(&m_bcs.flags.central_flags, conn_handle);
+ }
+
+ break;
+
+ case BLE_GAP_EVT_DISCONNECTED:
+ record_set_disconnected(conn_handle);
+ break;
+
+ case BLE_GAP_EVT_CONN_SEC_UPDATE:
+ {
+ bool encrypted = (p_ble_evt->evt.gap_evt.params.conn_sec_update.conn_sec.sec_mode.lv > 1);
+ bool mitm = (p_ble_evt->evt.gap_evt.params.conn_sec_update.conn_sec.sec_mode.lv > 2);
+
+ if (encrypted)
+ {
+ nrf_atflags_set(&m_bcs.flags.encrypted_flags, conn_handle);
+ if (mitm)
+ {
+ nrf_atflags_set(&m_bcs.flags.mitm_protected_flags, conn_handle);
+ }
+ else
+ {
+ nrf_atflags_clear(&m_bcs.flags.mitm_protected_flags, conn_handle);
+ }
+ }
+ else
+ {
+ nrf_atflags_clear(&m_bcs.flags.encrypted_flags, conn_handle);
+ nrf_atflags_clear(&m_bcs.flags.mitm_protected_flags, conn_handle);
+ }
+ break;
+ }
+ }
+}
+
+NRF_SDH_BLE_OBSERVER(m_ble_evt_observer, BLE_CONN_STATE_BLE_OBSERVER_PRIO, ble_evt_handler, NULL);
+
+
+bool ble_conn_state_valid(uint16_t conn_handle)
+{
+ if (conn_handle >= BLE_CONN_STATE_MAX_CONNECTIONS)
+ {
+ return false;
+ }
+ return nrf_atflags_get(&m_bcs.flags.valid_flags, conn_handle);
+}
+
+
+uint8_t ble_conn_state_role(uint16_t conn_handle)
+{
+ uint8_t role = BLE_GAP_ROLE_INVALID;
+
+ if (ble_conn_state_valid(conn_handle))
+ {
+#if !defined (S112)
+ bool central = nrf_atflags_get(&m_bcs.flags.central_flags, conn_handle);
+ role = central ? BLE_GAP_ROLE_CENTRAL : BLE_GAP_ROLE_PERIPH;
+#else
+ role = BLE_GAP_ROLE_PERIPH;
+#endif // !defined (S112)
+ }
+
+ return role;
+}
+
+
+ble_conn_state_status_t ble_conn_state_status(uint16_t conn_handle)
+{
+ ble_conn_state_status_t conn_status = BLE_CONN_STATUS_INVALID;
+
+ if (ble_conn_state_valid(conn_handle))
+ {
+ bool connected = nrf_atflags_get(&m_bcs.flags.connected_flags, conn_handle);
+ conn_status = connected ? BLE_CONN_STATUS_CONNECTED : BLE_CONN_STATUS_DISCONNECTED;
+ }
+
+ return conn_status;
+}
+
+
+bool ble_conn_state_encrypted(uint16_t conn_handle)
+{
+ if (ble_conn_state_valid(conn_handle))
+ {
+ return nrf_atflags_get(&m_bcs.flags.encrypted_flags, conn_handle);
+ }
+ return false;
+}
+
+
+bool ble_conn_state_mitm_protected(uint16_t conn_handle)
+{
+ if (ble_conn_state_valid(conn_handle))
+ {
+ return nrf_atflags_get(&m_bcs.flags.mitm_protected_flags, conn_handle);
+ }
+ return false;
+}
+
+
+uint32_t ble_conn_state_conn_count(void)
+{
+ return active_flag_count(m_bcs.flags.connected_flags);
+}
+
+
+uint32_t ble_conn_state_central_conn_count(void)
+{
+ nrf_atflags_t central_conn_flags = m_bcs.flags.central_flags;
+ UNUSED_RETURN_VALUE(nrf_atomic_u32_and(&central_conn_flags, m_bcs.flags.connected_flags));
+
+ return active_flag_count(central_conn_flags);
+}
+
+
+uint32_t ble_conn_state_peripheral_conn_count(void)
+{
+ nrf_atflags_t peripheral_conn_flags = ~m_bcs.flags.central_flags;
+ UNUSED_RETURN_VALUE(nrf_atomic_u32_and(&peripheral_conn_flags, m_bcs.flags.connected_flags));
+
+ return active_flag_count(peripheral_conn_flags);
+}
+
+
+ble_conn_state_conn_handle_list_t ble_conn_state_conn_handles(void)
+{
+ return conn_handle_list_get(m_bcs.flags.valid_flags);
+}
+
+
+ble_conn_state_conn_handle_list_t ble_conn_state_central_handles(void)
+{
+ nrf_atflags_t central_conn_flags = m_bcs.flags.central_flags;
+ UNUSED_RETURN_VALUE(nrf_atomic_u32_and(&central_conn_flags, m_bcs.flags.connected_flags));
+
+ return conn_handle_list_get(central_conn_flags);
+}
+
+
+ble_conn_state_conn_handle_list_t ble_conn_state_periph_handles(void)
+{
+ nrf_atflags_t peripheral_conn_flags = ~m_bcs.flags.central_flags;
+ UNUSED_RETURN_VALUE(nrf_atomic_u32_and(&peripheral_conn_flags, m_bcs.flags.connected_flags));
+
+ return conn_handle_list_get(peripheral_conn_flags);
+}
+
+
+uint16_t ble_conn_state_conn_idx(uint16_t conn_handle)
+{
+ if (ble_conn_state_valid(conn_handle))
+ {
+ return conn_handle;
+ }
+ else
+ {
+ return BLE_CONN_STATE_MAX_CONNECTIONS;
+ }
+}
+
+
+ble_conn_state_user_flag_id_t ble_conn_state_user_flag_acquire(void)
+{
+ uint32_t acquired_flag = nrf_atflags_find_and_set_flag(&m_bcs.acquired_flags,
+ BLE_CONN_STATE_USER_FLAG_COUNT);
+
+ if (acquired_flag == BLE_CONN_STATE_USER_FLAG_COUNT)
+ {
+ return BLE_CONN_STATE_USER_FLAG_INVALID;
+ }
+ return (ble_conn_state_user_flag_id_t)acquired_flag;
+}
+
+
+bool ble_conn_state_user_flag_get(uint16_t conn_handle, ble_conn_state_user_flag_id_t flag_id)
+{
+ if (user_flag_is_acquired(flag_id) && ble_conn_state_valid(conn_handle))
+ {
+ return nrf_atflags_get(&m_bcs.flags.user_flags[flag_id], conn_handle);
+ }
+ else
+ {
+ return false;
+ }
+}
+
+
+void ble_conn_state_user_flag_set(uint16_t conn_handle,
+ ble_conn_state_user_flag_id_t flag_id,
+ bool value)
+{
+ if (user_flag_is_acquired(flag_id) && ble_conn_state_valid(conn_handle))
+ {
+ if (value)
+ {
+ nrf_atflags_set(&m_bcs.flags.user_flags[flag_id], conn_handle);
+ }
+ else
+ {
+ nrf_atflags_clear(&m_bcs.flags.user_flags[flag_id], conn_handle);
+ }
+ }
+}
+
+
+static uint32_t for_each_set_flag(nrf_atflags_t flags,
+ ble_conn_state_user_function_t user_function,
+ void * p_context)
+{
+ if (user_function == NULL)
+ {
+ return 0;
+ }
+
+ uint32_t call_count = 0;
+
+ if (flags != 0)
+ {
+ for (uint32_t i = 0; i < BLE_CONN_STATE_MAX_CONNECTIONS; i++)
+ {
+ if (nrf_atflags_get(&flags, i))
+ {
+ user_function(i, p_context);
+ call_count += 1;
+ }
+ }
+ }
+ return call_count;
+}
+
+
+uint32_t ble_conn_state_for_each_connected(ble_conn_state_user_function_t user_function,
+ void * p_context)
+{
+ return for_each_set_flag(m_bcs.flags.connected_flags, user_function, p_context);
+}
+
+
+uint32_t ble_conn_state_for_each_set_user_flag(ble_conn_state_user_flag_id_t flag_id,
+ ble_conn_state_user_function_t user_function,
+ void * p_context)
+{
+ if (!user_flag_is_acquired(flag_id))
+ {
+ return 0;
+ }
+
+ return for_each_set_flag(m_bcs.flags.user_flags[flag_id], user_function, p_context);
+}
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/common/ble_conn_state.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/common/ble_conn_state.h
new file mode 100644
index 0000000..8d1efc4
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/common/ble_conn_state.h
@@ -0,0 +1,345 @@
+/**
+ * Copyright (c) 2015 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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
+ *
+ * @defgroup ble_conn_state Connection state
+ * @ingroup ble_sdk_lib
+ * @{
+ * @brief Module for storing data on BLE connections.
+ *
+ * @details This module stores certain states for each connection, which can be queried by
+ * connection handle. The module uses BLE events to keep the states updated.
+ *
+ * In addition to the preprogrammed states, this module can also keep track of a number of
+ * binary user states, or <i>user flags</i>. These are reset to 0 for new connections, but
+ * otherwise not touched by this module.
+ *
+ * This module uses the @ref nrf_atomic module to make the flag operations thread-safe.
+ *
+ * @note A connection handle is not immediately invalidated when it is disconnected. Certain states,
+ * such as the role, can still be queried until the next time a new connection is established
+ * to any device.
+ *
+ */
+
+#ifndef BLE_CONN_STATE_H__
+#define BLE_CONN_STATE_H__
+
+#include <stdbool.h>
+#include <stdint.h>
+#include "ble.h"
+#include "ble_gap.h"
+#include "nrf_atomic.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**@brief Connection handle statuses.
+ */
+typedef enum
+{
+ BLE_CONN_STATUS_INVALID, /**< The connection handle is invalid. */
+ BLE_CONN_STATUS_DISCONNECTED, /**< The connection handle refers to a connection that has been disconnected, but not yet invalidated. */
+ BLE_CONN_STATUS_CONNECTED, /**< The connection handle refers to an active connection. */
+} ble_conn_state_status_t;
+
+#define BLE_CONN_STATE_MAX_CONNECTIONS BLE_GAP_ROLE_COUNT_COMBINED_MAX /**< The maximum number of connections supported. */
+#define BLE_CONN_STATE_USER_FLAG_COUNT 24 /**< The number of available user flags. */
+
+
+/**@brief Type used to present a list of conn_handles.
+ */
+typedef struct
+{
+ uint32_t len; /**< The length of the list. */
+ uint16_t conn_handles[BLE_CONN_STATE_MAX_CONNECTIONS]; /**< The list of handles. */
+} ble_conn_state_conn_handle_list_t;
+
+/**@brief One ID for each user flag collection.
+ *
+ * @details These IDs are used to identify user flag collections in the API calls.
+ */
+typedef enum
+{
+ BLE_CONN_STATE_USER_FLAG0 = 0,
+ BLE_CONN_STATE_USER_FLAG1,
+ BLE_CONN_STATE_USER_FLAG2,
+ BLE_CONN_STATE_USER_FLAG3,
+ BLE_CONN_STATE_USER_FLAG4,
+ BLE_CONN_STATE_USER_FLAG5,
+ BLE_CONN_STATE_USER_FLAG6,
+ BLE_CONN_STATE_USER_FLAG7,
+ BLE_CONN_STATE_USER_FLAG8,
+ BLE_CONN_STATE_USER_FLAG9,
+ BLE_CONN_STATE_USER_FLAG10,
+ BLE_CONN_STATE_USER_FLAG11,
+ BLE_CONN_STATE_USER_FLAG12,
+ BLE_CONN_STATE_USER_FLAG13,
+ BLE_CONN_STATE_USER_FLAG14,
+ BLE_CONN_STATE_USER_FLAG15,
+ BLE_CONN_STATE_USER_FLAG16,
+ BLE_CONN_STATE_USER_FLAG17,
+ BLE_CONN_STATE_USER_FLAG18,
+ BLE_CONN_STATE_USER_FLAG19,
+ BLE_CONN_STATE_USER_FLAG20,
+ BLE_CONN_STATE_USER_FLAG21,
+ BLE_CONN_STATE_USER_FLAG22,
+ BLE_CONN_STATE_USER_FLAG23,
+ BLE_CONN_STATE_USER_FLAG_INVALID,
+} ble_conn_state_user_flag_id_t;
+
+
+/**@brief Function to be called when a flag ID is set. See @ref ble_conn_state_for_each_set_user_flag.
+ *
+ * @param[in] conn_handle The connection the flag is set for.
+ * @param[in] p_context Arbitrary pointer provided by the caller of
+ * @ref ble_conn_state_for_each_set_user_flag.
+ */
+typedef void (*ble_conn_state_user_function_t)(uint16_t conn_handle, void * p_context);
+
+
+/**
+ * @defgroup ble_conn_state_functions BLE connection state functions
+ * @{
+ */
+
+
+/**@brief Function for initializing or resetting the module.
+ *
+ * @details This function sets all states to their default, removing all records of connection handles.
+ */
+void ble_conn_state_init(void);
+
+
+/**@brief Function for querying whether a connection handle represents a valid connection.
+ *
+ * @details A connection might be valid and have a BLE_CONN_STATUS_DISCONNECTED status.
+ * Those connections are invalidated after a new connection occurs.
+ *
+ * @param[in] conn_handle Handle of the connection.
+ *
+ * @retval true If conn_handle represents a valid connection, thus a connection for which
+ we have a record.
+ * @retval false If conn_handle is @ref BLE_GAP_ROLE_INVALID, or if it has never been recorded.
+ */
+bool ble_conn_state_valid(uint16_t conn_handle);
+
+
+/**@brief Function for querying the role of the local device in a connection.
+ *
+ * @param[in] conn_handle Handle of the connection to get the role for.
+ *
+ * @return The role of the local device in the connection (see @ref BLE_GAP_ROLES).
+ * If conn_handle is not valid, the function returns BLE_GAP_ROLE_INVALID.
+ */
+uint8_t ble_conn_state_role(uint16_t conn_handle);
+
+
+/**@brief Function for querying the status of a connection.
+ *
+ * @param[in] conn_handle Handle of the connection.
+ *
+ * @return The status of the connection.
+ * If conn_handle is not valid, the function returns BLE_CONN_STATE_INVALID.
+ */
+ble_conn_state_status_t ble_conn_state_status(uint16_t conn_handle);
+
+
+/**@brief Function for querying whether a connection is encrypted.
+ *
+ * @param[in] conn_handle Handle of connection to get the encryption state for.
+ *
+ * @retval true If the connection is encrypted.
+ * @retval false If the connection is not encrypted or conn_handle is invalid.
+ */
+bool ble_conn_state_encrypted(uint16_t conn_handle);
+
+
+/**@brief Function for querying whether a connection encryption is protected from Man in the Middle
+ * attacks.
+ *
+ * @param[in] conn_handle Handle of connection to get the MITM state for.
+ *
+ * @retval true If the connection is encrypted with MITM protection.
+ * @retval false If the connection is not encrypted, or encryption is not MITM protected, or
+ * conn_handle is invalid.
+ */
+bool ble_conn_state_mitm_protected(uint16_t conn_handle);
+
+
+/**@brief Function for querying the total number of connections.
+ *
+ * @return The total number of valid connections for which the module has a record.
+ */
+uint32_t ble_conn_state_conn_count(void);
+
+
+/**@brief Function for querying the total number of connections in which the role of the local
+ * device is @ref BLE_GAP_ROLE_CENTRAL.
+ *
+ * @return The number of connections in which the role of the local device is
+ * @ref BLE_GAP_ROLE_CENTRAL.
+ */
+uint32_t ble_conn_state_central_conn_count(void);
+
+
+/**@brief Function for querying the total number of connections in which the role of the local
+ * device is @ref BLE_GAP_ROLE_PERIPH.
+ *
+ * @return The number of connections in which the role of the local device is
+ * @ref BLE_GAP_ROLE_PERIPH.
+ */
+uint32_t ble_conn_state_peripheral_conn_count(void);
+
+
+/**@brief Function for obtaining a list of all connection handles for which the module has a record.
+ *
+ * @details This function takes into account connections whose state is BLE_CONN_STATUS_DISCONNECTED.
+ *
+ * @return A list of all valid connection handles for which the module has a record.
+ */
+ble_conn_state_conn_handle_list_t ble_conn_state_conn_handles(void);
+
+
+/**@brief Function for obtaining a list of connection handles in which the role of the local
+ * device is @ref BLE_GAP_ROLE_CENTRAL.
+ *
+ * @details This function takes into account connections whose state is BLE_CONN_STATUS_DISCONNECTED.
+ *
+ * @return A list of all valid connection handles for which the module has a record and in which
+ * the role of local device is @ref BLE_GAP_ROLE_CENTRAL.
+ */
+ble_conn_state_conn_handle_list_t ble_conn_state_central_handles(void);
+
+
+/**@brief Function for obtaining the handle for the connection in which the role of the local device
+ * is @ref BLE_GAP_ROLE_PERIPH.
+ *
+ * @details This function takes into account connections whose state is BLE_CONN_STATUS_DISCONNECTED.
+ *
+ * @return A list of all valid connection handles for which the module has a record and in which
+ * the role of local device is @ref BLE_GAP_ROLE_PERIPH.
+ */
+ble_conn_state_conn_handle_list_t ble_conn_state_periph_handles(void);
+
+
+/**@brief Function for translating a connection handle to a value that can be used as an array index.
+ *
+ * @details Function for mapping connection handles onto the range <0 - MAX_CONNECTIONS>.
+ *
+ * @note The index will be the same as long as a connection is invalid. A subsequent connection with
+ * the same connection handle might have a different index.
+ *
+ * @param[in] conn_handle The connection for which to retrieve an index.
+ *
+ * @return An index unique to this connection. Or @ref BLE_CONN_STATE_MAX_CONNECTIONS if
+ * @p conn_handle refers to an invalid connection.
+ */
+uint16_t ble_conn_state_conn_idx(uint16_t conn_handle);
+
+
+/**@brief Function for obtaining exclusive access to one of the user flag collections.
+ *
+ * @details The acquired collection contains one flag for each connection. These flags can be set
+ * and read individually for each connection.
+ *
+ * The state of user flags will not be modified by the connection state module, except to
+ * set it to 0 for a connection when that connection is invalidated.
+ *
+ * @return The ID of the acquired flag, or BLE_CONN_STATE_USER_FLAG_INVALID if none are available.
+ */
+ble_conn_state_user_flag_id_t ble_conn_state_user_flag_acquire(void);
+
+
+/**@brief Function for reading the value of a user flag.
+ *
+ * @param[in] conn_handle Handle of connection to get the flag state for.
+ * @param[in] flag_id Which flag to get the state for.
+ *
+ * @return The state of the flag. If conn_handle is invalid, the function returns false.
+ */
+bool ble_conn_state_user_flag_get(uint16_t conn_handle, ble_conn_state_user_flag_id_t flag_id);
+
+
+/**@brief Function for setting the value of a user flag.
+ *
+ * @param[in] conn_handle Handle of connection to set the flag state for.
+ * @param[in] flag_id Which flag to set the state for.
+ * @param[in] value Value to set the flag state to.
+ */
+void ble_conn_state_user_flag_set(uint16_t conn_handle,
+ ble_conn_state_user_flag_id_t flag_id,
+ bool value);
+
+
+/**@brief Function for running a function for each active connection.
+ *
+ * @param[in] user_function The function to run for each connection.
+ * @param[in] p_context Arbitrary context to be passed to \p user_function.
+ *
+ * @return The number of times \p user_function was run.
+ */
+uint32_t ble_conn_state_for_each_connected(ble_conn_state_user_function_t user_function,
+ void * p_context);
+
+
+/**@brief Function for running a function for each flag that is set in a user flag collection.
+ *
+ * @param[in] flag_id Which flags to check.
+ * @param[in] user_function The function to run when a flag is set.
+ * @param[in] p_context Arbitrary context to be passed to \p user_function.
+ *
+ * @return The number of times \p user_function was run.
+ */
+uint32_t ble_conn_state_for_each_set_user_flag(ble_conn_state_user_flag_id_t flag_id,
+ ble_conn_state_user_function_t user_function,
+ void * p_context);
+
+/** @} */
+/** @} */
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* BLE_CONN_STATE_H__ */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/common/ble_date_time.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/common/ble_date_time.h
new file mode 100644
index 0000000..72dd8b8
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/common/ble_date_time.h
@@ -0,0 +1,113 @@
+/**
+ * Copyright (c) 2011 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+/* Attention!
+* To maintain compliance with Nordic Semiconductor ASA’s Bluetooth profile
+* qualification listings, this section of source code must not be modified.
+*/
+
+/** @file
+ * @brief Contains definition of ble_date_time structure.
+ */
+
+/** @file
+ *
+ * @defgroup ble_sdk_srv_date_time BLE Date Time characteristic type
+ * @{
+ * @ingroup ble_sdk_lib
+ * @brief Definition of ble_date_time_t type.
+ */
+
+#ifndef BLE_DATE_TIME_H__
+#define BLE_DATE_TIME_H__
+
+#include <stdint.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**@brief Date and Time structure. */
+typedef struct
+{
+ uint16_t year;
+ uint8_t month;
+ uint8_t day;
+ uint8_t hours;
+ uint8_t minutes;
+ uint8_t seconds;
+} ble_date_time_t;
+
+static __INLINE uint8_t ble_date_time_encode(const ble_date_time_t * p_date_time,
+ uint8_t * p_encoded_data)
+{
+ uint8_t len = uint16_encode(p_date_time->year, p_encoded_data);
+
+ p_encoded_data[len++] = p_date_time->month;
+ p_encoded_data[len++] = p_date_time->day;
+ p_encoded_data[len++] = p_date_time->hours;
+ p_encoded_data[len++] = p_date_time->minutes;
+ p_encoded_data[len++] = p_date_time->seconds;
+
+ return len;
+}
+
+static __INLINE uint8_t ble_date_time_decode(ble_date_time_t * p_date_time,
+ const uint8_t * p_encoded_data)
+{
+ uint8_t len = sizeof(uint16_t);
+
+ p_date_time->year = uint16_decode(p_encoded_data);
+ p_date_time->month = p_encoded_data[len++];
+ p_date_time->day = p_encoded_data[len++];
+ p_date_time->hours = p_encoded_data[len++];
+ p_date_time->minutes = p_encoded_data[len++];
+ p_date_time->seconds = p_encoded_data[len++];
+
+ return len;
+}
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // BLE_DATE_TIME_H__
+
+/** @} */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/common/ble_gatt_db.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/common/ble_gatt_db.h
new file mode 100644
index 0000000..314c2b8
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/common/ble_gatt_db.h
@@ -0,0 +1,92 @@
+/**
+ * Copyright (c) 2016 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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
+ *
+ * @defgroup ble_sdk_lib_gatt_db GATT Database Service Structure
+ * @{
+ * @ingroup ble_sdk_lib
+ */
+
+#ifndef BLE_GATT_DB_H__
+#define BLE_GATT_DB_H__
+
+#include <stdint.h>
+#include "ble.h"
+#include "ble_gattc.h"
+#include "sdk_config.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifndef BLE_GATT_DB_MAX_CHARS
+#define BLE_GATT_DB_MAX_CHARS 6 /**< The maximum number of characteristics present in a service record. */
+#endif // BLE_GATT_DB_MAX_CHARS
+
+/**@brief Structure for holding the characteristic and the handle of its CCCD present on a server.
+ */
+typedef struct
+{
+ ble_gattc_char_t characteristic; /**< Structure containing information about the characteristic. */
+ uint16_t cccd_handle; /**< CCCD Handle value for this characteristic. This will be set to BLE_GATT_HANDLE_INVALID if a CCCD is not present at the server. */
+ uint16_t ext_prop_handle; /**< Extended Properties Handle value for this characteristic. This will be set to BLE_GATT_HANDLE_INVALID if an Extended Properties descriptor is not present at the server. */
+ uint16_t user_desc_handle; /**< User Description Handle value for this characteristic. This will be set to BLE_GATT_HANDLE_INVALID if a User Description descriptor is not present at the server. */
+ uint16_t report_ref_handle; /**< Report Reference Handle value for this characteristic. This will be set to BLE_GATT_HANDLE_INVALID if a Report Reference descriptor is not present at the server. */
+} ble_gatt_db_char_t;
+
+/**@brief Structure for holding information about the service and the characteristics present on a
+ * server.
+ */
+typedef struct
+{
+ ble_uuid_t srv_uuid; /**< UUID of the service. */
+ uint8_t char_count; /**< Number of characteristics present in the service. */
+ ble_gattc_handle_range_t handle_range; /**< Service Handle Range. */
+ ble_gatt_db_char_t charateristics[BLE_GATT_DB_MAX_CHARS]; /**< Array of information related to the characteristics present in the service. This list can extend further than one. */
+} ble_gatt_db_srv_t;
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* BLE_GATT_DB_H__ */
+
+/** @} */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/common/ble_sensor_location.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/common/ble_sensor_location.h
new file mode 100644
index 0000000..b54bdac
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/common/ble_sensor_location.h
@@ -0,0 +1,76 @@
+/**
+ * Copyright (c) 2012 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+/* Attention!
+* To maintain compliance with Nordic Semiconductor ASA’s Bluetooth profile
+* qualification listings, this section of source code must not be modified.
+*/
+
+#ifndef BLE_SENSOR_LOCATION_H__
+#define BLE_SENSOR_LOCATION_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef enum {
+ BLE_SENSOR_LOCATION_OTHER = 0 , /**<-- Other */
+ BLE_SENSOR_LOCATION_TOP_OF_SHOE = 1 , /**<-- Top of shoe */
+ BLE_SENSOR_LOCATION_IN_SHOE = 2 , /**<-- In shoe */
+ BLE_SENSOR_LOCATION_HIP = 3 , /**<-- Hip */
+ BLE_SENSOR_LOCATION_FRONT_WHEEL = 4 , /**<-- Front Wheel */
+ BLE_SENSOR_LOCATION_LEFT_CRANK = 5 , /**<-- Left Crank */
+ BLE_SENSOR_LOCATION_RIGHT_CRANK = 6 , /**<-- Right Crank */
+ BLE_SENSOR_LOCATION_LEFT_PEDAL = 7 , /**<-- Left Pedal */
+ BLE_SENSOR_LOCATION_RIGHT_PEDAL = 8 , /**<-- Right Pedal */
+ BLE_SENSOR_LOCATION_FRONT_HUB = 9 , /**<-- Front Hub */
+ BLE_SENSOR_LOCATION_REAR_DROPOUT = 10, /**<-- Rear Dropout */
+ BLE_SENSOR_LOCATION_CHAINSTAY = 11, /**<-- Chainstay */
+ BLE_SENSOR_LOCATION_REAR_WHEEL = 12, /**<-- Rear Wheel */
+ BLE_SENSOR_LOCATION_REAR_HUB = 13, /**<-- Rear Hub */
+}ble_sensor_location_t;
+
+#define BLE_NB_MAX_SENSOR_LOCATIONS 14
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // BLE_SENSOR_LOCATION_H__
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/common/ble_srv_common.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/common/ble_srv_common.c
new file mode 100644
index 0000000..473d2b9
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/common/ble_srv_common.c
@@ -0,0 +1,237 @@
+/**
+ * Copyright (c) 2012 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+/* Attention!
+ * To maintain compliance with Nordic Semiconductor ASA's Bluetooth profile
+ * qualification listings, this section of source code must not be modified.
+ */
+
+#include "ble_srv_common.h"
+#include <string.h>
+#include "nordic_common.h"
+#include "app_error.h"
+#include "ble.h"
+
+bool ble_srv_is_notification_enabled(uint8_t const * p_encoded_data)
+{
+ uint16_t cccd_value = uint16_decode(p_encoded_data);
+ return ((cccd_value & BLE_GATT_HVX_NOTIFICATION) != 0);
+}
+
+bool ble_srv_is_indication_enabled(uint8_t const * p_encoded_data)
+{
+ uint16_t cccd_value = uint16_decode(p_encoded_data);
+ return ((cccd_value & BLE_GATT_HVX_INDICATION) != 0);
+}
+
+uint8_t ble_srv_report_ref_encode(uint8_t * p_encoded_buffer,
+ const ble_srv_report_ref_t * p_report_ref)
+{
+ uint8_t len = 0;
+
+ p_encoded_buffer[len++] = p_report_ref->report_id;
+ p_encoded_buffer[len++] = p_report_ref->report_type;
+
+ APP_ERROR_CHECK_BOOL(len == BLE_SRV_ENCODED_REPORT_REF_LEN);
+ return len;
+}
+
+
+void ble_srv_ascii_to_utf8(ble_srv_utf8_str_t * p_utf8, char * p_ascii)
+{
+ p_utf8->length = (uint16_t)strlen(p_ascii);
+ p_utf8->p_str = (uint8_t *)p_ascii;
+}
+
+
+/**@brief Function for setting security requirements of a characteristic.
+ *
+ * @param[in] level required security level.
+ * @param[out] p_perm Characteristic security requirements.
+ *
+ * @return encoded security level and security mode.
+ */
+static inline void set_security_req(security_req_t level, ble_gap_conn_sec_mode_t * p_perm)
+{
+
+
+ BLE_GAP_CONN_SEC_MODE_SET_NO_ACCESS(p_perm);
+ switch (level)
+ {
+ case SEC_NO_ACCESS:
+ BLE_GAP_CONN_SEC_MODE_SET_NO_ACCESS(p_perm);
+ break;
+ case SEC_OPEN:
+ BLE_GAP_CONN_SEC_MODE_SET_OPEN(p_perm);
+ break;
+ case SEC_JUST_WORKS:
+ BLE_GAP_CONN_SEC_MODE_SET_ENC_NO_MITM(p_perm);
+ break;
+ case SEC_MITM:
+ BLE_GAP_CONN_SEC_MODE_SET_ENC_WITH_MITM(p_perm);
+ break;
+ case SEC_SIGNED:
+ BLE_GAP_CONN_SEC_MODE_SET_SIGNED_NO_MITM(p_perm);
+ break;
+ case SEC_SIGNED_MITM:
+ BLE_GAP_CONN_SEC_MODE_SET_SIGNED_WITH_MITM(p_perm);
+ break;
+ }
+ return;
+}
+
+
+uint32_t characteristic_add(uint16_t service_handle,
+ ble_add_char_params_t * p_char_props,
+ ble_gatts_char_handles_t * p_char_handle)
+{
+ ble_gatts_char_md_t char_md;
+ ble_gatts_attr_t attr_char_value;
+ ble_uuid_t char_uuid;
+ ble_gatts_attr_md_t attr_md;
+ ble_gatts_attr_md_t user_descr_attr_md;
+ ble_gatts_attr_md_t cccd_md;
+
+ if (p_char_props->uuid_type == 0)
+ {
+ char_uuid.type = BLE_UUID_TYPE_BLE;
+ }
+ else
+ {
+ char_uuid.type = p_char_props->uuid_type;
+ }
+ char_uuid.uuid = p_char_props->uuid;
+
+ memset(&attr_md, 0, sizeof(ble_gatts_attr_md_t));
+ set_security_req(p_char_props->read_access, &attr_md.read_perm);
+ set_security_req(p_char_props->write_access, & attr_md.write_perm);
+ attr_md.rd_auth = (p_char_props->is_defered_read ? 1 : 0);
+ attr_md.wr_auth = (p_char_props->is_defered_write ? 1 : 0);
+ attr_md.vlen = (p_char_props->is_var_len ? 1 : 0);
+ attr_md.vloc = (p_char_props->is_value_user ? BLE_GATTS_VLOC_USER : BLE_GATTS_VLOC_STACK);
+
+
+ memset(&char_md, 0, sizeof(ble_gatts_char_md_t));
+ if ((p_char_props->char_props.notify == 1)||(p_char_props->char_props.indicate == 1))
+ {
+
+ memset(&cccd_md, 0, sizeof(cccd_md));
+ set_security_req(p_char_props->cccd_write_access, &cccd_md.write_perm);
+ BLE_GAP_CONN_SEC_MODE_SET_OPEN(&cccd_md.read_perm);
+
+ cccd_md.vloc = BLE_GATTS_VLOC_STACK;
+
+ char_md.p_cccd_md = &cccd_md;
+ }
+ char_md.char_props = p_char_props->char_props;
+ char_md.char_ext_props = p_char_props->char_ext_props;
+
+ memset(&attr_char_value, 0, sizeof(ble_gatts_attr_t));
+ attr_char_value.p_uuid = &char_uuid;
+ attr_char_value.p_attr_md = &attr_md;
+ attr_char_value.max_len = p_char_props->max_len;
+ if (p_char_props->p_init_value != NULL)
+ {
+ attr_char_value.init_len = p_char_props->init_len;
+ attr_char_value.p_value = p_char_props->p_init_value;
+ }
+ if (p_char_props->p_user_descr != NULL)
+ {
+ memset(&user_descr_attr_md, 0, sizeof(ble_gatts_attr_md_t));
+ char_md.char_user_desc_max_size = p_char_props->p_user_descr->max_size;
+ char_md.char_user_desc_size = p_char_props->p_user_descr->size;
+ char_md.p_char_user_desc = p_char_props->p_user_descr->p_char_user_desc;
+
+ char_md.p_user_desc_md = &user_descr_attr_md;
+
+ set_security_req(p_char_props->p_user_descr->read_access, &user_descr_attr_md.read_perm);
+ set_security_req(p_char_props->p_user_descr->write_access, &user_descr_attr_md.write_perm);
+
+ user_descr_attr_md.rd_auth = (p_char_props->p_user_descr->is_defered_read ? 1 : 0);
+ user_descr_attr_md.wr_auth = (p_char_props->p_user_descr->is_defered_write ? 1 : 0);
+ user_descr_attr_md.vlen = (p_char_props->p_user_descr->is_var_len ? 1 : 0);
+ user_descr_attr_md.vloc = (p_char_props->p_user_descr->is_value_user ? BLE_GATTS_VLOC_USER : BLE_GATTS_VLOC_STACK);
+ }
+ if (p_char_props->p_presentation_format != NULL)
+ {
+ char_md.p_char_pf = p_char_props->p_presentation_format;
+ }
+ return sd_ble_gatts_characteristic_add(service_handle,
+ &char_md,
+ &attr_char_value,
+ p_char_handle);
+}
+
+
+uint32_t descriptor_add(uint16_t char_handle,
+ ble_add_descr_params_t * p_descr_props,
+ uint16_t * p_descr_handle)
+{
+ ble_gatts_attr_t descr_params;
+ ble_uuid_t desc_uuid;
+ ble_gatts_attr_md_t attr_md;
+
+ memset(&descr_params, 0, sizeof(descr_params));
+ if (p_descr_props->uuid_type == 0)
+ {
+ desc_uuid.type = BLE_UUID_TYPE_BLE;
+ }
+ else
+ {
+ desc_uuid.type = p_descr_props->uuid_type;
+ }
+ desc_uuid.uuid = p_descr_props->uuid;
+ descr_params.p_uuid = &desc_uuid;
+
+ set_security_req(p_descr_props->read_access, &attr_md.read_perm);
+ set_security_req(p_descr_props->write_access,&attr_md.write_perm);
+
+ attr_md.rd_auth = (p_descr_props->is_defered_read ? 1 : 0);
+ attr_md.wr_auth = (p_descr_props->is_defered_write ? 1 : 0);
+ attr_md.vlen = (p_descr_props->is_var_len ? 1 : 0);
+ attr_md.vloc = (p_descr_props->is_value_user ? BLE_GATTS_VLOC_USER : BLE_GATTS_VLOC_STACK);
+ descr_params.p_attr_md = &attr_md;
+
+ descr_params.init_len = p_descr_props->init_len;
+ descr_params.init_offs = p_descr_props->init_offs;
+ descr_params.max_len = p_descr_props->max_len;
+ descr_params.p_value = p_descr_props->p_value;
+
+ return sd_ble_gatts_descriptor_add(char_handle, &descr_params, p_descr_handle);
+}
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/common/ble_srv_common.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/common/ble_srv_common.h
new file mode 100644
index 0000000..285cbed
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/common/ble_srv_common.h
@@ -0,0 +1,409 @@
+/**
+ * Copyright (c) 2012 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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
+ *
+ * @defgroup ble_sdk_srv_common Common service definitions
+ * @{
+ * @ingroup ble_sdk_srv
+ * @brief Constants, type definitions, and functions that are common to all services.
+ */
+
+#ifndef BLE_SRV_COMMON_H__
+#define BLE_SRV_COMMON_H__
+
+#include <stdint.h>
+#include <stdbool.h>
+#include "ble_types.h"
+#include "app_util.h"
+#include "ble.h"
+#include "ble_gap.h"
+#include "ble_gatt.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** @defgroup UUID_SERVICES Service UUID definitions
+ * @{ */
+#define BLE_UUID_ALERT_NOTIFICATION_SERVICE 0x1811 /**< Alert Notification service UUID. */
+#define BLE_UUID_BATTERY_SERVICE 0x180F /**< Battery service UUID. */
+#define BLE_UUID_BLOOD_PRESSURE_SERVICE 0x1810 /**< Blood Pressure service UUID. */
+#define BLE_UUID_CURRENT_TIME_SERVICE 0x1805 /**< Current Time service UUID. */
+#define BLE_UUID_CYCLING_SPEED_AND_CADENCE 0x1816 /**< Cycling Speed and Cadence service UUID. */
+#define BLE_UUID_LOCATION_AND_NAVIGATION_SERVICE 0x1819 /**< Location and Navigation service UUID. */
+#define BLE_UUID_DEVICE_INFORMATION_SERVICE 0x180A /**< Device Information service UUID. */
+#define BLE_UUID_GLUCOSE_SERVICE 0x1808 /**< Glucose service UUID. */
+#define BLE_UUID_HEALTH_THERMOMETER_SERVICE 0x1809 /**< Health Thermometer service UUID. */
+#define BLE_UUID_HEART_RATE_SERVICE 0x180D /**< Heart Rate service UUID. */
+#define BLE_UUID_HUMAN_INTERFACE_DEVICE_SERVICE 0x1812 /**< Human Interface Device service UUID. */
+#define BLE_UUID_IMMEDIATE_ALERT_SERVICE 0x1802 /**< Immediate Alert service UUID. */
+#define BLE_UUID_LINK_LOSS_SERVICE 0x1803 /**< Link Loss service UUID. */
+#define BLE_UUID_NEXT_DST_CHANGE_SERVICE 0x1807 /**< Next Dst Change service UUID. */
+#define BLE_UUID_PHONE_ALERT_STATUS_SERVICE 0x180E /**< Phone Alert Status service UUID. */
+#define BLE_UUID_REFERENCE_TIME_UPDATE_SERVICE 0x1806 /**< Reference Time Update service UUID. */
+#define BLE_UUID_RUNNING_SPEED_AND_CADENCE 0x1814 /**< Running Speed and Cadence service UUID. */
+#define BLE_UUID_SCAN_PARAMETERS_SERVICE 0x1813 /**< Scan Parameters service UUID. */
+#define BLE_UUID_TX_POWER_SERVICE 0x1804 /**< TX Power service UUID. */
+#define BLE_UUID_IPSP_SERVICE 0x1820 /**< Internet Protocol Support service UUID. */
+#define BLE_UUID_BMS_SERVICE 0x181E /**< BOND MANAGEMENT service UUID*/
+#define BLE_UUID_CGM_SERVICE 0x181F /**< Continuous Glucose Monitoring service UUID*/
+#define BLE_UUID_PLX_SERVICE 0x1822 /**< Pulse Oximeter Service UUID*/
+#define BLE_UUID_OTS_SERVICE 0x1825 /**< Object Transfer Service UUID*/
+
+/** @} */
+
+/** @defgroup UUID_CHARACTERISTICS Characteristic UUID definitions
+ * @{ */
+#define BLE_UUID_REMOVABLE_CHAR 0x2A3A /**< Removable characteristic UUID. */
+#define BLE_UUID_SERVICE_REQUIRED_CHAR 0x2A3B /**< Service Required characteristic UUID. */
+#define BLE_UUID_ALERT_CATEGORY_ID_CHAR 0x2A43 /**< Alert Category Id characteristic UUID. */
+#define BLE_UUID_ALERT_CATEGORY_ID_BIT_MASK_CHAR 0x2A42 /**< Alert Category Id Bit Mask characteristic UUID. */
+#define BLE_UUID_ALERT_LEVEL_CHAR 0x2A06 /**< Alert Level characteristic UUID. */
+#define BLE_UUID_ALERT_NOTIFICATION_CONTROL_POINT_CHAR 0x2A44 /**< Alert Notification Control Point characteristic UUID. */
+#define BLE_UUID_ALERT_STATUS_CHAR 0x2A3F /**< Alert Status characteristic UUID. */
+#define BLE_UUID_BATTERY_LEVEL_CHAR 0x2A19 /**< Battery Level characteristic UUID. */
+#define BLE_UUID_BLOOD_PRESSURE_FEATURE_CHAR 0x2A49 /**< Blood Pressure Feature characteristic UUID. */
+#define BLE_UUID_BLOOD_PRESSURE_MEASUREMENT_CHAR 0x2A35 /**< Blood Pressure Measurement characteristic UUID. */
+#define BLE_UUID_BODY_SENSOR_LOCATION_CHAR 0x2A38 /**< Body Sensor Location characteristic UUID. */
+#define BLE_UUID_BOOT_KEYBOARD_INPUT_REPORT_CHAR 0x2A22 /**< Boot Keyboard Input Report characteristic UUID. */
+#define BLE_UUID_BOOT_KEYBOARD_OUTPUT_REPORT_CHAR 0x2A32 /**< Boot Keyboard Output Report characteristic UUID. */
+#define BLE_UUID_BOOT_MOUSE_INPUT_REPORT_CHAR 0x2A33 /**< Boot Mouse Input Report characteristic UUID. */
+#define BLE_UUID_CURRENT_TIME_CHAR 0x2A2B /**< Current Time characteristic UUID. */
+#define BLE_UUID_DATE_TIME_CHAR 0x2A08 /**< Date Time characteristic UUID. */
+#define BLE_UUID_DAY_DATE_TIME_CHAR 0x2A0A /**< Day Date Time characteristic UUID. */
+#define BLE_UUID_DAY_OF_WEEK_CHAR 0x2A09 /**< Day Of Week characteristic UUID. */
+#define BLE_UUID_DST_OFFSET_CHAR 0x2A0D /**< Dst Offset characteristic UUID. */
+#define BLE_UUID_EXACT_TIME_256_CHAR 0x2A0C /**< Exact Time 256 characteristic UUID. */
+#define BLE_UUID_FIRMWARE_REVISION_STRING_CHAR 0x2A26 /**< Firmware Revision String characteristic UUID. */
+#define BLE_UUID_GLUCOSE_FEATURE_CHAR 0x2A51 /**< Glucose Feature characteristic UUID. */
+#define BLE_UUID_GLUCOSE_MEASUREMENT_CHAR 0x2A18 /**< Glucose Measurement characteristic UUID. */
+#define BLE_UUID_GLUCOSE_MEASUREMENT_CONTEXT_CHAR 0x2A34 /**< Glucose Measurement Context characteristic UUID. */
+#define BLE_UUID_HARDWARE_REVISION_STRING_CHAR 0x2A27 /**< Hardware Revision String characteristic UUID. */
+#define BLE_UUID_HEART_RATE_CONTROL_POINT_CHAR 0x2A39 /**< Heart Rate Control Point characteristic UUID. */
+#define BLE_UUID_HEART_RATE_MEASUREMENT_CHAR 0x2A37 /**< Heart Rate Measurement characteristic UUID. */
+#define BLE_UUID_HID_CONTROL_POINT_CHAR 0x2A4C /**< Hid Control Point characteristic UUID. */
+#define BLE_UUID_HID_INFORMATION_CHAR 0x2A4A /**< Hid Information characteristic UUID. */
+#define BLE_UUID_IEEE_REGULATORY_CERTIFICATION_DATA_LIST_CHAR 0x2A2A /**< IEEE Regulatory Certification Data List characteristic UUID. */
+#define BLE_UUID_INTERMEDIATE_CUFF_PRESSURE_CHAR 0x2A36 /**< Intermediate Cuff Pressure characteristic UUID. */
+#define BLE_UUID_INTERMEDIATE_TEMPERATURE_CHAR 0x2A1E /**< Intermediate Temperature characteristic UUID. */
+#define BLE_UUID_LOCAL_TIME_INFORMATION_CHAR 0x2A0F /**< Local Time Information characteristic UUID. */
+#define BLE_UUID_MANUFACTURER_NAME_STRING_CHAR 0x2A29 /**< Manufacturer Name String characteristic UUID. */
+#define BLE_UUID_MEASUREMENT_INTERVAL_CHAR 0x2A21 /**< Measurement Interval characteristic UUID. */
+#define BLE_UUID_MODEL_NUMBER_STRING_CHAR 0x2A24 /**< Model Number String characteristic UUID. */
+#define BLE_UUID_UNREAD_ALERT_CHAR 0x2A45 /**< Unread Alert characteristic UUID. */
+#define BLE_UUID_NEW_ALERT_CHAR 0x2A46 /**< New Alert characteristic UUID. */
+#define BLE_UUID_PNP_ID_CHAR 0x2A50 /**< PNP Id characteristic UUID. */
+#define BLE_UUID_PROTOCOL_MODE_CHAR 0x2A4E /**< Protocol Mode characteristic UUID. */
+#define BLE_UUID_RECORD_ACCESS_CONTROL_POINT_CHAR 0x2A52 /**< Record Access Control Point characteristic UUID. */
+#define BLE_UUID_REFERENCE_TIME_INFORMATION_CHAR 0x2A14 /**< Reference Time Information characteristic UUID. */
+#define BLE_UUID_REPORT_CHAR 0x2A4D /**< Report characteristic UUID. */
+#define BLE_UUID_REPORT_MAP_CHAR 0x2A4B /**< Report Map characteristic UUID. */
+#define BLE_UUID_RINGER_CONTROL_POINT_CHAR 0x2A40 /**< Ringer Control Point characteristic UUID. */
+#define BLE_UUID_RINGER_SETTING_CHAR 0x2A41 /**< Ringer Setting characteristic UUID. */
+#define BLE_UUID_SCAN_INTERVAL_WINDOW_CHAR 0x2A4F /**< Scan Interval Window characteristic UUID. */
+#define BLE_UUID_SCAN_REFRESH_CHAR 0x2A31 /**< Scan Refresh characteristic UUID. */
+#define BLE_UUID_SERIAL_NUMBER_STRING_CHAR 0x2A25 /**< Serial Number String characteristic UUID. */
+#define BLE_UUID_SOFTWARE_REVISION_STRING_CHAR 0x2A28 /**< Software Revision String characteristic UUID. */
+#define BLE_UUID_SUPPORTED_NEW_ALERT_CATEGORY_CHAR 0x2A47 /**< Supported New Alert Category characteristic UUID. */
+#define BLE_UUID_SUPPORTED_UNREAD_ALERT_CATEGORY_CHAR 0x2A48 /**< Supported Unread Alert Category characteristic UUID. */
+#define BLE_UUID_SYSTEM_ID_CHAR 0x2A23 /**< System Id characteristic UUID. */
+#define BLE_UUID_TEMPERATURE_MEASUREMENT_CHAR 0x2A1C /**< Temperature Measurement characteristic UUID. */
+#define BLE_UUID_TEMPERATURE_TYPE_CHAR 0x2A1D /**< Temperature Type characteristic UUID. */
+#define BLE_UUID_TIME_ACCURACY_CHAR 0x2A12 /**< Time Accuracy characteristic UUID. */
+#define BLE_UUID_TIME_SOURCE_CHAR 0x2A13 /**< Time Source characteristic UUID. */
+#define BLE_UUID_TIME_UPDATE_CONTROL_POINT_CHAR 0x2A16 /**< Time Update Control Point characteristic UUID. */
+#define BLE_UUID_TIME_UPDATE_STATE_CHAR 0x2A17 /**< Time Update State characteristic UUID. */
+#define BLE_UUID_TIME_WITH_DST_CHAR 0x2A11 /**< Time With Dst characteristic UUID. */
+#define BLE_UUID_TIME_ZONE_CHAR 0x2A0E /**< Time Zone characteristic UUID. */
+#define BLE_UUID_TX_POWER_LEVEL_CHAR 0x2A07 /**< TX Power Level characteristic UUID. */
+#define BLE_UUID_CSC_FEATURE_CHAR 0x2A5C /**< Cycling Speed and Cadence Feature characteristic UUID. */
+#define BLE_UUID_CSC_MEASUREMENT_CHAR 0x2A5B /**< Cycling Speed and Cadence Measurement characteristic UUID. */
+#define BLE_UUID_RSC_FEATURE_CHAR 0x2A54 /**< Running Speed and Cadence Feature characteristic UUID. */
+#define BLE_UUID_SC_CTRLPT_CHAR 0x2A55 /**< Speed and Cadence Control Point UUID. */
+#define BLE_UUID_RSC_MEASUREMENT_CHAR 0x2A53 /**< Running Speed and Cadence Measurement characteristic UUID. */
+#define BLE_UUID_SENSOR_LOCATION_CHAR 0x2A5D /**< Sensor Location characteristic UUID. */
+#define BLE_UUID_EXTERNAL_REPORT_REF_DESCR 0x2907 /**< External Report Reference descriptor UUID. */
+#define BLE_UUID_REPORT_REF_DESCR 0x2908 /**< Report Reference descriptor UUID. */
+#define BLE_UUID_LN_FEATURE_CHAR 0x2A6A /**< Location Navigation Service, Feature characteristic UUID. */
+#define BLE_UUID_LN_POSITION_QUALITY_CHAR 0x2A69 /**< Location Navigation Service, Position quality UUID. */
+#define BLE_UUID_LN_LOCATION_AND_SPEED_CHAR 0x2A67 /**< Location Navigation Service, Location and Speed characteristic UUID. */
+#define BLE_UUID_LN_NAVIGATION_CHAR 0x2A68 /**< Location Navigation Service, Navigation characteristic UUID. */
+#define BLE_UUID_LN_CONTROL_POINT_CHAR 0x2A6B /**< Location Navigation Service, Control point characteristic UUID. */
+#define BLE_UUID_BMS_CTRLPT 0x2AA4 /**< BMS Control Point characteristic UUID. */
+#define BLE_UUID_BMS_FEATURE 0x2AA5 /**< BMS Feature characteristic UUID. */
+#define BLE_UUID_CGM_MEASUREMENT 0x2AA7 /**< CGM Service, Measurement characteristic UUID*/
+#define BLE_UUID_CGM_FEATURE 0x2AA8 /**< CGM Service, Feature characteristic UUID*/
+#define BLE_UUID_CGM_STATUS 0x2AA9 /**< CGM Service, Status characteristic UUID*/
+#define BLE_UUID_CGM_SESSION_START_TIME 0x2AAA /**< CGM Service, session start time characteristic UUID*/
+#define BLE_UUID_CGM_SESSION_RUN_TIME 0x2AAB /**< CGM Service, session run time characteristic UUID*/
+#define BLE_UUID_CGM_SPECIFIC_OPS_CTRLPT 0x2AAC /**< CGM Service, specific ops ctrlpt characteristic UUID*/
+#define BLE_UUID_PLX_SPOT_CHECK_MEAS 0x2A5E /**< PLX Service, spot check measurement characteristic UUID*/
+#define BLE_UUID_PLX_CONTINUOUS_MEAS 0x2A5F /**< PLX Service, continuous measurement characteristic UUID*/
+#define BLE_UUID_PLX_FEATURES 0x2A60 /**< PLX Service, feature characteristic UUID*/
+#define BLE_UUID_OTS_FEATURES 0x2ABD /**< OTS Service, feature characteristic UUID*/
+#define BLE_UUID_OTS_OBJECT_NAME 0x2ABE /**< OTS Service, Object Name characteristic UUID*/
+#define BLE_UUID_OTS_OBJECT_TYPE 0x2ABF /**< OTS Service, Object Type characteristic UUID*/
+#define BLE_UUID_OTS_OBJECT_SIZE 0x2AC0 /**< OTS Service, Object Size characteristic UUID*/
+#define BLE_UUID_OTS_OBJECT_FIRST_CREATED 0x2AC1 /**< OTS Service, Object First Created characteristic UUID*/
+#define BLE_UUID_OTS_OBJECT_LAST_MODIFIED 0x2AC2 /**< OTS Service, Object Last Modified characteristic UUID*/
+#define BLE_UUID_OTS_OBJECT_ID 0x2AC3 /**< OTS Service, Object ID characteristic UUID*/
+#define BLE_UUID_OTS_OBJECT_PROPERTIES 0x2AC4 /**< OTS Service, Object Properties characteristic UUID*/
+#define BLE_UUID_OTS_OACP 0x2AC5 /**< OTS Service, Object Action Control Point characteristic UUID*/
+#define BLE_UUID_OTS_OLCP 0x2AC6 /**< OTS Service, Object List Control Point characteristic UUID*/
+#define BLE_UUID_OTS_LF 0x2AC7 /**< OTS Service, Object List Filter characteristic UUID*/
+#define BLE_UUID_OTS_OBJECT_CHANGED 0x2AC8 /**< OTS Service, Object Changed characteristic UUID*/
+
+
+
+
+/** @} */
+
+/** @defgroup ALERT_LEVEL_VALUES Definitions for the Alert Level characteristic values
+ * @{ */
+#define BLE_CHAR_ALERT_LEVEL_NO_ALERT 0x00 /**< No Alert. */
+#define BLE_CHAR_ALERT_LEVEL_MILD_ALERT 0x01 /**< Mild Alert. */
+#define BLE_CHAR_ALERT_LEVEL_HIGH_ALERT 0x02 /**< High Alert. */
+/** @} */
+
+#define BLE_SRV_ENCODED_REPORT_REF_LEN 2 /**< The length of an encoded Report Reference Descriptor. */
+#define BLE_CCCD_VALUE_LEN 2 /**< The length of a CCCD value. */
+
+/**@brief Type definition for error handler function that will be called in case of an error in
+ * a service or a service library module. */
+typedef void (*ble_srv_error_handler_t) (uint32_t nrf_error);
+
+
+
+/**@brief Value of a Report Reference descriptor.
+ *
+ * @details This is mapping information that maps the parent characteristic to the Report ID(s) and
+ * Report Type(s) defined within a Report Map characteristic.
+ */
+typedef struct
+{
+ uint8_t report_id; /**< Non-zero value if there is more than one instance of the same Report Type */
+ uint8_t report_type; /**< Type of Report characteristic (see @ref BLE_HIDS_REPORT_TYPE) */
+} ble_srv_report_ref_t;
+
+/**@brief UTF-8 string data type.
+ *
+ * @note The type can only hold a pointer to the string data (i.e. not the actual data).
+ */
+typedef struct
+{
+ uint16_t length; /**< String length. */
+ uint8_t * p_str; /**< String data. */
+} ble_srv_utf8_str_t;
+
+
+/**@brief Security settings structure.
+ * @details This structure contains the security options needed during initialization of the
+ * service.
+ */
+typedef struct
+{
+ ble_gap_conn_sec_mode_t read_perm; /**< Read permissions. */
+ ble_gap_conn_sec_mode_t write_perm; /**< Write permissions. */
+} ble_srv_security_mode_t;
+
+/**@brief Security settings structure.
+ * @details This structure contains the security options needed during initialization of the
+ * service. It can be used when the characteristics contains a CCCD.
+ */
+typedef struct
+{
+ ble_gap_conn_sec_mode_t cccd_write_perm; /**< Write permissions for Client Characteristic Configuration Descriptor. */
+ ble_gap_conn_sec_mode_t read_perm; /**< Read permissions. */
+ ble_gap_conn_sec_mode_t write_perm; /**< Write permissions. */
+} ble_srv_cccd_security_mode_t;
+
+/**@brief Function for decoding a CCCD value, and then testing if notification is
+ * enabled.
+ *
+ * @param[in] p_encoded_data Buffer where the encoded CCCD is stored.
+ *
+ * @retval TRUE If notification is enabled.
+ * @retval FALSE Otherwise.
+ */
+bool ble_srv_is_notification_enabled(uint8_t const * p_encoded_data);
+
+
+/**@brief Function for decoding a CCCD value, and then testing if indication is
+ * enabled.
+ *
+ * @param[in] p_encoded_data Buffer where the encoded CCCD is stored.
+ *
+ * @retval TRUE If indication is enabled.
+ * @retval FALSE Otherwise.
+ */
+bool ble_srv_is_indication_enabled(uint8_t const * p_encoded_data);
+
+
+/**@brief Function for encoding a Report Reference Descriptor.
+ *
+ * @param[in] p_encoded_buffer The buffer of the encoded data.
+ * @param[in] p_report_ref Report Reference value to be encoded.
+ *
+ * @return Length of the encoded data.
+ */
+uint8_t ble_srv_report_ref_encode(uint8_t * p_encoded_buffer,
+ const ble_srv_report_ref_t * p_report_ref);
+
+/**@brief Function for making a UTF-8 structure refer to an ASCII string.
+ *
+ * @param[out] p_utf8 UTF-8 structure to be set.
+ * @param[in] p_ascii ASCII string to be referred to.
+ */
+void ble_srv_ascii_to_utf8(ble_srv_utf8_str_t * p_utf8, char * p_ascii);
+
+
+/**@brief Security Access enumeration.
+ * @details This enumeration gives the possible requirements for accessing a characteristic value.
+ */
+typedef enum
+{
+ SEC_NO_ACCESS = 0, /**< Not possible to access. */
+ SEC_OPEN = 1, /**< Access open. */
+ SEC_JUST_WORKS = 2, /**< Access possible with 'Just Works' security at least. */
+ SEC_MITM = 3, /**< Access possible with 'MITM' security at least. */
+ SEC_SIGNED = 4, /**< Access possible with 'signed' security at least. */
+ SEC_SIGNED_MITM = 5 /**< Access possible with 'signed and MITM' security at least. */
+}security_req_t;
+
+
+/**@brief Characteristic User Descriptor parameters.
+ * @details This structure contains the parameters for User Descriptor.
+ */
+typedef struct
+{
+ uint16_t max_size; /**< Maximum size of the user descriptor*/
+ uint16_t size; /**< Size of the user descriptor*/
+ uint8_t *p_char_user_desc; /**< User descriptor content, pointer to a UTF-8 encoded string (non-NULL terminated)*/
+ bool is_var_len; /**< Indicates if the user descriptor has variable length.*/
+ ble_gatt_char_props_t char_props; /**< user descriptor properties.*/
+ bool is_defered_read; /**< Indicate if deferred read operations are supported.*/
+ bool is_defered_write; /**< Indicate if deferred write operations are supported.*/
+ security_req_t read_access; /**< Security requirement for reading the user descriptor.*/
+ security_req_t write_access; /**< Security requirement for writing the user descriptor.*/
+ bool is_value_user; /**< Indicate if the content of the characteristic is to be stored in the application (user) or in the stack.*/
+}ble_add_char_user_desc_t;
+
+
+/**@brief Add characteristic parameters structure.
+ * @details This structure contains the parameters needed to use the @ref characteristic_add function.
+ */
+typedef struct
+{
+ uint16_t uuid; /**< Characteristic UUID (16 bits UUIDs).*/
+ uint8_t uuid_type; /**< Base UUID. If 0, the Bluetooth SIG UUID will be used. Otherwise, this should be a value returned by @ref sd_ble_uuid_vs_add when adding the base UUID.*/
+ uint16_t max_len; /**< Maximum length of the characteristic value.*/
+ uint16_t init_len; /**< Initial length of the characteristic value.*/
+ uint8_t * p_init_value; /**< Initial encoded value of the characteristic.*/
+ bool is_var_len; /**< Indicates if the characteristic value has variable length.*/
+ ble_gatt_char_props_t char_props; /**< Characteristic properties.*/
+ ble_gatt_char_ext_props_t char_ext_props; /**< Characteristic extended properties.*/
+ bool is_defered_read; /**< Indicate if deferred read operations are supported.*/
+ bool is_defered_write; /**< Indicate if deferred write operations are supported.*/
+ security_req_t read_access; /**< Security requirement for reading the characteristic value.*/
+ security_req_t write_access; /**< Security requirement for writing the characteristic value.*/
+ security_req_t cccd_write_access; /**< Security requirement for writing the characteristic's CCCD.*/
+ bool is_value_user; /**< Indicate if the content of the characteristic is to be stored in the application (user) or in the stack.*/
+ ble_add_char_user_desc_t *p_user_descr; /**< Pointer to user descriptor if needed*/
+ ble_gatts_char_pf_t *p_presentation_format; /**< Pointer to characteristic format if needed*/
+} ble_add_char_params_t;
+
+
+/**@brief Add descriptor parameters structure.
+ * @details This structure contains the parameters needed to use the @ref descriptor_add function.
+ */
+typedef struct
+{
+ uint16_t uuid; /**< descriptor UUID (16 bits UUIDs).*/
+ uint8_t uuid_type; /**< Base UUID. If 0, the Bluetooth SIG UUID will be used. Otherwise, this should be a value returned by @ref sd_ble_uuid_vs_add when adding the base UUID.*/
+ bool is_defered_read; /**< Indicate if deferred read operations are supported.*/
+ bool is_defered_write; /**< Indicate if deferred write operations are supported.*/
+ bool is_var_len; /**< Indicates if the descriptor value has variable length.*/
+ security_req_t read_access; /**< Security requirement for reading the descriptor value.*/
+ security_req_t write_access; /**< Security requirement for writing the descriptor value.*/
+ bool is_value_user; /**< Indicate if the content of the characteristic is to be stored in the application (user) or in the stack.*/
+ uint16_t init_len; /**< Initial descriptor value length in bytes. */
+ uint16_t init_offs; /**< Initial descriptor value offset in bytes. If different from zero, the first init_offs bytes of the attribute value will be left uninitialized. */
+ uint16_t max_len; /**< Maximum descriptor value length in bytes, see @ref BLE_GATTS_ATTR_LENS_MAX for maximum values. */
+ uint8_t* p_value; /**< Pointer to the value of the descriptor*/
+} ble_add_descr_params_t;
+
+
+/**@brief Function for adding a characteristic to a given service.
+ *
+ * If no pointer is given for the initial value,
+ * the initial length parameter will be ignored and the initial length will be 0.
+ *
+ * @param[in] service_handle Handle of the service to which the characteristic is to be added.
+ * @param[in] p_char_props Information needed to add the characteristic.
+ * @param[out] p_char_handle Handle of the added characteristic.
+ *
+ * @retval NRF_SUCCESS If the characteristic was added successfully. Otherwise, an error code is returned.
+ */
+uint32_t characteristic_add(uint16_t service_handle,
+ ble_add_char_params_t * p_char_props,
+ ble_gatts_char_handles_t * p_char_handle);
+
+
+/**@brief Function for adding a characteristic's descriptor to a given characteristic.
+ *
+ * @param[in] char_handle Handle of the characteristic to which the descriptor is to be added, if @ref BLE_GATT_HANDLE_INVALID is used, it will be placed sequentially.
+ * @param[in] p_descr_props Information needed to add the descriptor.
+ * @param[out] p_descr_handle Handle of the added descriptor.
+ *
+ * @retval NRF_SUCCESS If the characteristic was added successfully. Otherwise, an error code is returned.
+ */
+uint32_t descriptor_add(uint16_t char_handle,
+ ble_add_descr_params_t * p_descr_props,
+ uint16_t * p_descr_handle);
+
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // BLE_SRV_COMMON_H__
+
+/** @} */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/nrf_ble_gatt/nrf_ble_gatt.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/nrf_ble_gatt/nrf_ble_gatt.c
new file mode 100644
index 0000000..51a5250
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/nrf_ble_gatt/nrf_ble_gatt.c
@@ -0,0 +1,550 @@
+/**
+ * Copyright (c) 2016 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+
+#include "sdk_common.h"
+#if NRF_MODULE_ENABLED(NRF_BLE_GATT)
+
+#include "nrf_ble_gatt.h"
+
+#define NRF_LOG_MODULE_NAME nrf_ble_gatt
+#include "nrf_log.h"
+NRF_LOG_MODULE_REGISTER();
+
+#include "nrf_strerror.h"
+
+#define BLE_GAP_DATA_LENGTH_DEFAULT 27 //!< The stack's default data length.
+#define BLE_GAP_DATA_LENGTH_MAX 251 //!< Maximum data length.
+
+
+STATIC_ASSERT(NRF_SDH_BLE_GAP_DATA_LENGTH < 252);
+
+
+/**@brief Initialize a link's parameters to defaults. */
+static void link_init(nrf_ble_gatt_link_t * p_link)
+{
+ p_link->att_mtu_desired = NRF_SDH_BLE_GATT_MAX_MTU_SIZE;
+ p_link->att_mtu_effective = BLE_GATT_ATT_MTU_DEFAULT;
+ p_link->att_mtu_exchange_pending = false;
+ p_link->att_mtu_exchange_requested = false;
+#if !defined (S112)
+ p_link->data_length_desired = NRF_SDH_BLE_GAP_DATA_LENGTH;
+ p_link->data_length_effective = BLE_GAP_DATA_LENGTH_DEFAULT;
+#endif // !defined (S112)
+}
+
+/**@brief Start a data length update request procedure on a given connection. */
+#if !defined (S112)
+static ret_code_t data_length_update(uint16_t conn_handle, uint16_t data_length)
+{
+ NRF_LOG_DEBUG("Updating data length to %u on connection 0x%x.",
+ data_length, conn_handle);
+
+ ble_gap_data_length_params_t const dlp =
+ {
+ .max_rx_octets = data_length,
+ .max_tx_octets = data_length,
+ .max_rx_time_us = BLE_GAP_DATA_LENGTH_AUTO,
+ .max_tx_time_us = BLE_GAP_DATA_LENGTH_AUTO,
+ };
+
+ ble_gap_data_length_limitation_t dll = {0};
+
+ ret_code_t err_code = sd_ble_gap_data_length_update(conn_handle, &dlp, &dll);
+ if (err_code != NRF_SUCCESS)
+ {
+ NRF_LOG_ERROR("sd_ble_gap_data_length_update() (request) on connection 0x%x returned %s.",
+ conn_handle, nrf_strerror_get(err_code));
+
+ if ( (dll.tx_payload_limited_octets != 0)
+ || (dll.rx_payload_limited_octets != 0))
+ {
+ NRF_LOG_ERROR("The requested TX/RX packet length is too long by %u/%u octets.",
+ dll.tx_payload_limited_octets, dll.rx_payload_limited_octets);
+ }
+
+ if (dll.tx_rx_time_limited_us != 0)
+ {
+ NRF_LOG_ERROR("The requested combination of TX and RX packet lengths "
+ "is too long by %u microseconds.",
+ dll.tx_rx_time_limited_us);
+ }
+ }
+
+ return err_code;
+}
+#endif // !defined (S112)
+
+
+/**@brief Handle a connected event.
+ *
+ * Begins an ATT MTU exchange procedure, followed by a data length update request as necessary.
+ *
+ * @param[in] p_gatt GATT structure.
+ * @param[in] p_ble_evt Event received from the BLE stack.
+ */
+static void on_connected_evt(nrf_ble_gatt_t * p_gatt, ble_evt_t const * p_ble_evt)
+{
+ ret_code_t err_code;
+ uint16_t conn_handle = p_ble_evt->evt.common_evt.conn_handle;
+ nrf_ble_gatt_link_t * p_link = &p_gatt->links[conn_handle];
+
+ // Update the link desired settings to reflect the current global settings.
+#if !defined (S112)
+ p_link->data_length_desired = p_gatt->data_length;
+#endif // !defined (S112)
+
+ switch (p_ble_evt->evt.gap_evt.params.connected.role)
+ {
+ case BLE_GAP_ROLE_PERIPH:
+ p_link->att_mtu_desired = p_gatt->att_mtu_desired_periph;
+ break;
+
+#if !defined (S112)
+ case BLE_GAP_ROLE_CENTRAL:
+ p_link->att_mtu_desired = p_gatt->att_mtu_desired_central;
+ break;
+#endif // !defined (S112)
+
+ default:
+ // Ignore.
+ break;
+ }
+
+ // Begin an ATT MTU exchange if necessary.
+ if (p_link->att_mtu_desired > p_link->att_mtu_effective)
+ {
+ NRF_LOG_DEBUG("Requesting to update ATT MTU to %u bytes on connection 0x%x.",
+ p_link->att_mtu_desired, conn_handle);
+
+ err_code = sd_ble_gattc_exchange_mtu_request(conn_handle, p_link->att_mtu_desired);
+
+ if (err_code == NRF_SUCCESS)
+ {
+ p_link->att_mtu_exchange_requested = true;
+ }
+ else if (err_code == NRF_ERROR_BUSY)
+ {
+ p_link->att_mtu_exchange_pending = true;
+ NRF_LOG_DEBUG("sd_ble_gattc_exchange_mtu_request()"
+ " on connection 0x%x returned busy, will retry.", conn_handle);
+ }
+ else
+ {
+ NRF_LOG_ERROR("sd_ble_gattc_exchange_mtu_request() returned %s.",
+ nrf_strerror_get(err_code));
+ }
+ }
+
+#if !defined (S112)
+ // Send a data length update request if necessary.
+ if (p_link->data_length_desired > p_link->data_length_effective)
+ {
+ (void) data_length_update(conn_handle, p_link->data_length_desired);
+ }
+#endif // !defined (S112)
+}
+
+
+static void on_disconnected_evt(nrf_ble_gatt_t * p_gatt, ble_evt_t const * p_ble_evt)
+{
+ // Reset connection parameters.
+ link_init(&p_gatt->links[p_ble_evt->evt.gap_evt.conn_handle]);
+}
+
+
+/**@brief Handle a BLE_GATTC_EVT_EXCHANGE_MTU_RSP event.
+ *
+ * @details The effective ATT MTU is set to the lowest between what we requested and the peer's
+ * response. This events concludes the ATT MTU exchange. An event is sent to the user
+ * and a data length update procedure is started if necessary.
+ *
+ * @param[in] p_gatt GATT structure.
+ * @param[in] p_ble_evt Event received from the BLE stack.
+ */
+static void on_exchange_mtu_rsp_evt(nrf_ble_gatt_t * p_gatt, ble_evt_t const * p_ble_evt)
+{
+ uint16_t conn_handle = p_ble_evt->evt.gattc_evt.conn_handle;
+ uint16_t server_rx_mtu = p_ble_evt->evt.gattc_evt.params.exchange_mtu_rsp.server_rx_mtu;
+
+ nrf_ble_gatt_link_t * p_link = &p_gatt->links[conn_handle];
+
+ // Determine the lowest MTU between our own desired MTU and the peer's.
+ // The MTU may not be less than BLE_GATT_ATT_MTU_DEFAULT.
+ p_link->att_mtu_effective = MIN(server_rx_mtu, p_link->att_mtu_desired);
+ p_link->att_mtu_effective = MAX(p_link->att_mtu_effective, BLE_GATT_ATT_MTU_DEFAULT);
+
+ NRF_LOG_DEBUG("ATT MTU updated to %u bytes on connection 0x%x (response).",
+ p_link->att_mtu_effective, conn_handle);
+
+ // Trigger an event indicating that the ATT MTU size has changed.
+ // Send an event to the application only if an ATT MTU exchange was requested.
+ if ((p_gatt->evt_handler != NULL) && (p_link->att_mtu_exchange_requested))
+ {
+ nrf_ble_gatt_evt_t const evt =
+ {
+ .evt_id = NRF_BLE_GATT_EVT_ATT_MTU_UPDATED,
+ .conn_handle = conn_handle,
+ .params.att_mtu_effective = p_link->att_mtu_effective,
+ };
+
+ p_gatt->evt_handler(p_gatt, &evt);
+ }
+
+ p_link->att_mtu_exchange_requested = false;
+ p_link->att_mtu_exchange_pending = false;
+}
+
+
+/**@brief Handle a BLE_GATTS_EVT_EXCHANGE_MTU_REQUEST event.
+ *
+ * @param[in] p_gatt GATT structure.
+ * @param[in] p_ble_evt Event received from the BLE stack.
+ */
+static void on_exchange_mtu_request_evt(nrf_ble_gatt_t * p_gatt, ble_evt_t const * p_ble_evt)
+{
+ ret_code_t err_code;
+ uint16_t conn_handle = p_ble_evt->evt.gatts_evt.conn_handle;
+ uint16_t client_mtu = p_ble_evt->evt.gatts_evt.params.exchange_mtu_request.client_rx_mtu;
+
+ nrf_ble_gatt_link_t * p_link = &p_gatt->links[conn_handle];
+
+ NRF_LOG_DEBUG("Peer on connection 0x%x requested an ATT MTU of %u bytes.",
+ conn_handle, client_mtu);
+
+ client_mtu = MAX(client_mtu, BLE_GATT_ATT_MTU_DEFAULT);
+ p_link->att_mtu_effective = MIN(client_mtu, p_link->att_mtu_desired);
+ p_link->att_mtu_exchange_pending = false;
+
+ NRF_LOG_DEBUG("Updating ATT MTU to %u bytes (desired: %u) on connection 0x%x.",
+ p_link->att_mtu_effective, p_link->att_mtu_desired, conn_handle);
+
+ err_code = sd_ble_gatts_exchange_mtu_reply(conn_handle, p_link->att_mtu_desired);
+
+ if (err_code != NRF_SUCCESS)
+ {
+ NRF_LOG_ERROR("sd_ble_gatts_exchange_mtu_reply() returned %s.", nrf_strerror_get(err_code));
+ }
+
+ // If an ATT_MTU exchange was requested to the peer, defer sending
+ // the data length update request and the event to the application until
+ // the response for that request is received.
+ if (p_link->att_mtu_exchange_requested)
+ {
+ return;
+ }
+
+ // The ATT MTU exchange has finished. Send an event to the application.
+ if (p_gatt->evt_handler != NULL)
+ {
+ nrf_ble_gatt_evt_t const evt =
+ {
+ .evt_id = NRF_BLE_GATT_EVT_ATT_MTU_UPDATED,
+ .conn_handle = conn_handle,
+ .params.att_mtu_effective = p_link->att_mtu_effective,
+ };
+
+ p_gatt->evt_handler(p_gatt, &evt);
+ }
+}
+
+
+/**@brief Handle a BLE_GAP_EVT_DATA_LENGTH_UPDATE event.
+ *
+ * @details Update the connection data length and send an event to the user.
+ *
+ * @param[in] p_gatt GATT structure.
+ * @param[in] p_ble_evt Event received from the BLE stack.
+ */
+#if !defined (S112)
+static void on_data_length_update_evt(nrf_ble_gatt_t * p_gatt, ble_evt_t const * p_ble_evt)
+{
+ ble_gap_evt_t const gap_evt = p_ble_evt->evt.gap_evt;
+ uint16_t const conn_handle = gap_evt.conn_handle;
+
+ // Update the connection data length.
+ // The SoftDevice only supports symmetric RX/TX data length settings.
+ p_gatt->links[conn_handle].data_length_effective =
+ gap_evt.params.data_length_update.effective_params.max_tx_octets;
+
+ NRF_LOG_DEBUG("Data length updated to %u on connection 0x%0x.",
+ p_gatt->links[conn_handle].data_length_effective,
+ conn_handle);
+
+ NRF_LOG_DEBUG("max_rx_octets: %u",
+ gap_evt.params.data_length_update.effective_params.max_rx_octets);
+ NRF_LOG_DEBUG("max_tx_octets: %u",
+ gap_evt.params.data_length_update.effective_params.max_tx_octets);
+ NRF_LOG_DEBUG("max_rx_time: %u",
+ gap_evt.params.data_length_update.effective_params.max_rx_time_us);
+ NRF_LOG_DEBUG("max_tx_time: %u",
+ gap_evt.params.data_length_update.effective_params.max_tx_time_us);
+
+ if (p_gatt->evt_handler != NULL)
+ {
+ nrf_ble_gatt_evt_t const evt =
+ {
+ .evt_id = NRF_BLE_GATT_EVT_DATA_LENGTH_UPDATED,
+ .conn_handle = conn_handle,
+ .params.data_length = p_gatt->links[conn_handle].data_length_effective,
+ };
+
+ p_gatt->evt_handler(p_gatt, &evt);
+ }
+}
+
+
+/**@brief Handle a BLE_GAP_EVT_DATA_LENGTH_UPDATE_REQUEST event.
+ *
+ *@details Reply with a sd_ble_gap_data_length_update() call, using the minimum between the
+ * link's preferred data length, and what requested by the peer.
+ * The link preferred data length is set to the global preferred data length
+ * upon connection and can be overridden by calling nrf_ble_gatt_data_length_set().
+ * The default is NRF_SDH_BLE_GAP_DATA_LENGTH.
+ *
+ *@note The SoftDevice will not send any BLE_GAP_EVT_DATA_LENGTH_UPDATE events on this side.
+ * Therefore, the connection data length is updated immediately and an event is sent
+ * to the user.
+ *
+ * @param[in] p_gatt GATT structure.
+ * @param[in] p_ble_evt Event received from the BLE stack.
+ */
+static void on_data_length_update_request_evt(nrf_ble_gatt_t * p_gatt, ble_evt_t const * p_ble_evt)
+{
+ ble_gap_evt_t const * p_gap_evt = &p_ble_evt->evt.gap_evt;
+ nrf_ble_gatt_link_t * p_link = &p_gatt->links[p_gap_evt->conn_handle];
+
+ // The SoftDevice only supports symmetric RX/TX data length settings.
+ uint8_t const data_length_requested =
+ p_gap_evt->params.data_length_update_request.peer_params.max_tx_octets;
+
+ NRF_LOG_DEBUG("Peer on connection 0x%x requested a data length of %u bytes.",
+ p_gap_evt->conn_handle, data_length_requested);
+
+ uint8_t const data_length_effective = MIN(p_link->data_length_desired, data_length_requested);
+
+ (void) data_length_update(p_gap_evt->conn_handle, data_length_effective);
+}
+#endif // !defined (S112)
+
+
+ret_code_t nrf_ble_gatt_init(nrf_ble_gatt_t * p_gatt, nrf_ble_gatt_evt_handler_t evt_handler)
+{
+ VERIFY_PARAM_NOT_NULL(p_gatt);
+
+ p_gatt->evt_handler = evt_handler;
+ p_gatt->att_mtu_desired_periph = NRF_SDH_BLE_GATT_MAX_MTU_SIZE;
+ p_gatt->att_mtu_desired_central = NRF_SDH_BLE_GATT_MAX_MTU_SIZE;
+ p_gatt->data_length = NRF_SDH_BLE_GAP_DATA_LENGTH;
+
+ for (uint32_t i = 0; i < NRF_BLE_GATT_LINK_COUNT; i++)
+ {
+ link_init(&p_gatt->links[i]);
+ }
+
+ return NRF_SUCCESS;
+}
+
+
+ret_code_t nrf_ble_gatt_att_mtu_periph_set(nrf_ble_gatt_t * p_gatt, uint16_t desired_mtu)
+{
+ VERIFY_PARAM_NOT_NULL(p_gatt);
+
+ if ((desired_mtu < BLE_GATT_ATT_MTU_DEFAULT) || (desired_mtu > NRF_SDH_BLE_GATT_MAX_MTU_SIZE))
+ {
+ return NRF_ERROR_INVALID_PARAM;
+ }
+
+ p_gatt->att_mtu_desired_periph = desired_mtu;
+ return NRF_SUCCESS;
+}
+
+
+ret_code_t nrf_ble_gatt_att_mtu_central_set(nrf_ble_gatt_t * p_gatt, uint16_t desired_mtu)
+{
+ VERIFY_PARAM_NOT_NULL(p_gatt);
+
+ if ((desired_mtu < BLE_GATT_ATT_MTU_DEFAULT) || (desired_mtu > NRF_SDH_BLE_GATT_MAX_MTU_SIZE))
+ {
+ return NRF_ERROR_INVALID_PARAM;
+ }
+
+ p_gatt->att_mtu_desired_central = desired_mtu;
+ return NRF_SUCCESS;
+}
+
+
+uint16_t nrf_ble_gatt_eff_mtu_get(nrf_ble_gatt_t const * p_gatt, uint16_t conn_handle)
+{
+ if ((p_gatt == NULL) || (conn_handle >= NRF_BLE_GATT_LINK_COUNT))
+ {
+ return 0;
+ }
+
+ return p_gatt->links[conn_handle].att_mtu_effective;
+}
+
+#if !defined (S112)
+ret_code_t nrf_ble_gatt_data_length_set(nrf_ble_gatt_t * p_gatt,
+ uint16_t conn_handle,
+ uint8_t data_length)
+{
+ if (p_gatt == NULL)
+ {
+ return NRF_ERROR_NULL;
+ }
+
+ // Check early to avoid requesting an invalid data length for upcoming connections.
+ if ( (data_length > BLE_GAP_DATA_LENGTH_MAX)
+ || (data_length < BLE_GAP_DATA_LENGTH_DEFAULT))
+ {
+ return NRF_ERROR_INVALID_PARAM;
+ }
+
+ if (conn_handle == BLE_CONN_HANDLE_INVALID)
+ {
+ // Save value and request upon connection.
+ p_gatt->data_length = data_length;
+ return NRF_SUCCESS;
+ }
+
+ if (conn_handle >= NRF_BLE_GATT_LINK_COUNT)
+ {
+ return NRF_ERROR_INVALID_PARAM;
+ }
+
+ // Request data length on existing link.
+ p_gatt->links[conn_handle].data_length_desired = data_length;
+
+ return data_length_update(conn_handle, data_length);
+}
+
+
+ret_code_t nrf_ble_gatt_data_length_get(nrf_ble_gatt_t const * p_gatt,
+ uint16_t conn_handle,
+ uint8_t * p_data_length)
+{
+ if ((p_gatt == NULL) || (p_data_length == NULL))
+ {
+ return NRF_ERROR_NULL;
+ }
+
+ if (conn_handle == BLE_CONN_HANDLE_INVALID)
+ {
+ *p_data_length = p_gatt->data_length;
+ return NRF_SUCCESS;
+ }
+
+ if (conn_handle >= NRF_BLE_GATT_LINK_COUNT)
+ {
+ return NRF_ERROR_INVALID_PARAM;
+ }
+
+ *p_data_length = p_gatt->links[conn_handle].data_length_effective;
+ return NRF_SUCCESS;
+}
+#endif // !defined (S112)
+
+
+void nrf_ble_gatt_on_ble_evt(ble_evt_t const * p_ble_evt, void * p_context)
+{
+ nrf_ble_gatt_t * p_gatt = (nrf_ble_gatt_t *)p_context;
+ uint16_t conn_handle = p_ble_evt->evt.common_evt.conn_handle;
+
+ if (conn_handle >= NRF_BLE_GATT_LINK_COUNT)
+ {
+ return;
+ }
+
+ switch (p_ble_evt->header.evt_id)
+ {
+ case BLE_GAP_EVT_CONNECTED:
+ on_connected_evt(p_gatt, p_ble_evt);
+ break;
+
+ case BLE_GAP_EVT_DISCONNECTED:
+ on_disconnected_evt(p_gatt, p_ble_evt);
+ break;
+
+ case BLE_GATTC_EVT_EXCHANGE_MTU_RSP:
+ on_exchange_mtu_rsp_evt(p_gatt, p_ble_evt);
+ break;
+
+ case BLE_GATTS_EVT_EXCHANGE_MTU_REQUEST:
+ on_exchange_mtu_request_evt(p_gatt, p_ble_evt);
+ break;
+
+#if !defined (S112)
+ case BLE_GAP_EVT_DATA_LENGTH_UPDATE:
+ on_data_length_update_evt(p_gatt, p_ble_evt);
+ break;
+
+ case BLE_GAP_EVT_DATA_LENGTH_UPDATE_REQUEST:
+ on_data_length_update_request_evt(p_gatt, p_ble_evt);
+ break;
+#endif // !defined (S112)
+
+ default:
+ break;
+ }
+
+ if (p_gatt->links[conn_handle].att_mtu_exchange_pending)
+ {
+ ret_code_t err_code;
+
+ err_code = sd_ble_gattc_exchange_mtu_request(conn_handle,
+ p_gatt->links[conn_handle].att_mtu_desired);
+
+ if (err_code == NRF_SUCCESS)
+ {
+ p_gatt->links[conn_handle].att_mtu_exchange_pending = false;
+ p_gatt->links[conn_handle].att_mtu_exchange_requested = true;
+
+ NRF_LOG_DEBUG("Requesting to update ATT MTU to %u bytes on connection 0x%x (retry).",
+ p_gatt->links[conn_handle].att_mtu_desired, conn_handle);
+ }
+ else if (err_code != NRF_ERROR_BUSY)
+ {
+ NRF_LOG_ERROR("sd_ble_gattc_exchange_mtu_request() returned %s.",
+ nrf_strerror_get(err_code));
+ }
+ }
+}
+
+#endif //NRF_BLE_GATT_ENABLED
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/nrf_ble_gatt/nrf_ble_gatt.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/nrf_ble_gatt/nrf_ble_gatt.h
new file mode 100644
index 0000000..2970671
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/nrf_ble_gatt/nrf_ble_gatt.h
@@ -0,0 +1,242 @@
+/**
+ * Copyright (c) 2016 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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
+ *
+ * @defgroup nrf_ble_gatt GATT module
+ * @{
+ * @ingroup ble_sdk_lib
+ * @brief Module for negotiating and keeping track of GATT connection parameters and updating the data length.
+ */
+
+#ifndef NRF_BLE_GATT_H__
+#define NRF_BLE_GATT_H__
+
+#include <stdint.h>
+#include <stdbool.h>
+#include <string.h>
+#include "ble.h"
+#include "ble_gatt.h"
+#include "sdk_config.h"
+#include "sdk_errors.h"
+#include "app_util.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**@brief Macro for defining a nrf_ble_gatt instance.
+ *
+ * @param _name Name of the instance.
+ * @hideinitializer
+ */
+#define NRF_BLE_GATT_DEF(_name) \
+static nrf_ble_gatt_t _name; \
+NRF_SDH_BLE_OBSERVER(_name ## _obs, \
+ NRF_BLE_GATT_BLE_OBSERVER_PRIO, \
+ nrf_ble_gatt_on_ble_evt, &_name)
+
+/**@brief The maximum number of peripheral and central connections combined.
+ * This value is based on what is configured in the SoftDevice handler sdk_config.
+ */
+#define NRF_BLE_GATT_LINK_COUNT (NRF_SDH_BLE_PERIPHERAL_LINK_COUNT + NRF_SDH_BLE_CENTRAL_LINK_COUNT)
+
+
+/**@brief GATT module event types. */
+typedef enum
+{
+ NRF_BLE_GATT_EVT_ATT_MTU_UPDATED = 0xA77, //!< The ATT_MTU size was updated.
+ NRF_BLE_GATT_EVT_DATA_LENGTH_UPDATED = 0xDA7A, //!< The data length was updated.
+} nrf_ble_gatt_evt_id_t;
+
+/**@brief GATT module event. */
+typedef struct
+{
+ nrf_ble_gatt_evt_id_t evt_id; //!< Event ID.
+ uint16_t conn_handle; //!< Connection handle on which the event happened.
+ union
+ {
+ uint16_t att_mtu_effective; //!< Effective ATT_MTU.
+#if !defined (S112)
+ uint8_t data_length; //!< Data length value.
+#endif // !defined (S112)
+ } params;
+} nrf_ble_gatt_evt_t;
+
+// Forward declaration of the nrf_ble_gatt_t type.
+typedef struct nrf_ble_gatt_s nrf_ble_gatt_t;
+
+/**@brief GATT module event handler type.
+ *
+ * The GATT module calls a function of this type when a parameter value is changed.
+ */
+typedef void (*nrf_ble_gatt_evt_handler_t) (nrf_ble_gatt_t * p_gatt, nrf_ble_gatt_evt_t const * p_evt);
+
+/**@brief GATT information for each connection. */
+typedef struct
+{
+ uint16_t att_mtu_desired; //!< Requested ATT_MTU size (in bytes).
+ uint16_t att_mtu_effective; //!< Effective ATT_MTU size (in bytes).
+ bool att_mtu_exchange_pending; //!< Indicates that an ATT_MTU exchange request is pending (the call to @ref sd_ble_gattc_exchange_mtu_request returned @ref NRF_ERROR_BUSY).
+ bool att_mtu_exchange_requested; //!< Indicates that an ATT_MTU exchange request was made.
+#if !defined (S112)
+ uint8_t data_length_desired; //!< Desired data length (in bytes).
+ uint8_t data_length_effective; //!< Requested data length (in bytes).
+#endif // !defined (S112)
+} nrf_ble_gatt_link_t;
+
+
+/**@brief GATT structure that contains status information for the GATT module. */
+struct nrf_ble_gatt_s
+{
+ uint16_t att_mtu_desired_periph; //!< Requested ATT_MTU size for the next peripheral connection that is established.
+ uint16_t att_mtu_desired_central; //!< Requested ATT_MTU size for the next central connection that is established.
+ uint8_t data_length; //!< Data length to use for the next connection that is established.
+ nrf_ble_gatt_link_t links[NRF_BLE_GATT_LINK_COUNT]; //!< GATT related information for all active connections.
+ nrf_ble_gatt_evt_handler_t evt_handler; //!< GATT event handler.
+};
+
+
+/**@brief Function for initializing the GATT module.
+ *
+ * @param[in] evt_handler Event handler.
+ * @param[out] p_gatt Pointer to the GATT structure.
+ *
+ * @retval NRF_SUCCESS If the operation was successful.
+ * @retval NRF_ERROR_NULL If @p p_gatt is NULL.
+ */
+ret_code_t nrf_ble_gatt_init(nrf_ble_gatt_t * p_gatt, nrf_ble_gatt_evt_handler_t evt_handler);
+
+
+/**@brief Function for setting the ATT_MTU size for the next connection that is established as peripheral.
+ *
+ * @param[in] p_gatt Pointer to the GATT structure.
+ * @param[in] desired_mtu Requested ATT_MTU size.
+ *
+ * @retval NRF_SUCCESS If the operation was successful.
+ * @retval NRF_ERROR_NULL If @p p_gatt is NULL.
+ * @retval NRF_ERROR_INVALID_PARAM If the size of @p desired_mtu is bigger than
+ * @ref NRF_SDH_BLE_GATT_MAX_MTU_SIZE or smaller than
+ * @ref BLE_GATT_ATT_MTU_DEFAULT.
+ */
+ret_code_t nrf_ble_gatt_att_mtu_periph_set(nrf_ble_gatt_t * p_gatt, uint16_t desired_mtu);
+
+
+/**@brief Function for setting the ATT_MTU size for the next connection that is established as central.
+ *
+ * @param[in,out] p_gatt Pointer to the GATT structure.
+ * @param[in] desired_mtu Requested ATT_MTU size.
+ *
+ * @retval NRF_SUCCESS If the operation was successful.
+ * @retval NRF_ERROR_NULL If @p p_gatt is NULL.
+ * @retval NRF_ERROR_INVALID_PARAM If the size of @p desired_mtu is bigger than
+ * @ref NRF_SDH_BLE_GATT_MAX_MTU_SIZE or smaller
+ * than @ref BLE_GATT_ATT_MTU_DEFAULT.
+ */
+ret_code_t nrf_ble_gatt_att_mtu_central_set(nrf_ble_gatt_t * p_gatt, uint16_t desired_mtu);
+
+
+/**@brief Function for setting the data length for a connection.
+ *
+ * @details If @p conn_handle is a handle to an existing connection, a data length update
+ * request is sent on that connection.
+ * If @p conn_handle is @ref BLE_CONN_HANDLE_INVALID, a data length update request
+ * is sent on the next connection that is established after the ATT_MTU
+ * exchange has completed. If no ATT_MTU exchange procedure is carried
+ * out (for example, if a default ATT_MTU size is used), the data length
+ * is not changed.
+ */
+#if !defined (S112)
+ret_code_t nrf_ble_gatt_data_length_set(nrf_ble_gatt_t * p_gatt,
+ uint16_t conn_handle,
+ uint8_t data_length);
+#endif // !defined (S112)
+
+/**@brief Function for retrieving the data length of a connection.
+ *
+ * @details If @p conn_handle is @ref BLE_CONN_HANDLE_INVALID, the function retrieves the data
+ * length that will be requested for the next connection.
+ * If @p conn_handle is a handle to an existing connection, the function retrieves
+ * the effective data length that was negotiated for that connection.
+ *
+ * @param[in,out] p_gatt Pointer to the GATT structure.
+ * @param[in] conn_handle The connection for which to retrieve the data length, or
+ * @ref BLE_CONN_HANDLE_INVALID to retrieve the requested data length
+ * for the next connection.
+ * @param[out] p_data_length The connection data length.
+ *
+ * @retval NRF_SUCCESS If the operation was successful.
+ * @retval NRF_ERROR_NULL If @p p_gatt or @p p_data_length is NULL.
+ * @retval NRF_ERROR_INVALID_PARAM If @p conn_handle is larger than @ref NRF_BLE_GATT_LINK_COUNT.
+ */
+#if !defined (S112)
+ret_code_t nrf_ble_gatt_data_length_get(nrf_ble_gatt_t const * p_gatt,
+ uint16_t conn_handle,
+ uint8_t * p_data_length);
+#endif // !defined (S112)
+
+/**@brief Function for handling BLE stack events.
+ *
+ * @details This function handles events from the BLE stack that are of interest to the module.
+ *
+ * @param[in] p_ble_evt Event received from the BLE stack.
+ * @param[in] p_context Pointer to the GATT structure.
+ */
+void nrf_ble_gatt_on_ble_evt(ble_evt_t const * p_ble_evt, void * p_context);
+
+
+/**@brief Function for getting the current ATT_MTU size for a given connection.
+ *
+ * @param[in] p_gatt Pointer to the GATT structure.
+ * @param[in] conn_handle Connection handle of the connection.
+ *
+ * @return ATT_MTU size for the given connection.
+ * @retval 0 If @p p_gatt is NULL or if @p conn_handle is larger than
+ * the supported maximum number of connections.
+ */
+uint16_t nrf_ble_gatt_eff_mtu_get(nrf_ble_gatt_t const * p_gatt, uint16_t conn_handle);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // NRF_BLE_GATT_H__
+
+/** @} */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/nrf_ble_qwr/nrf_ble_qwr.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/nrf_ble_qwr/nrf_ble_qwr.c
new file mode 100644
index 0000000..0f06372
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/nrf_ble_qwr/nrf_ble_qwr.c
@@ -0,0 +1,488 @@
+/**
+ * Copyright (c) 2016 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#include "sdk_common.h"
+#if NRF_MODULE_ENABLED(NRF_BLE_QWR)
+#include <stdlib.h>
+#include "nrf_ble_qwr.h"
+#include "ble.h"
+#include "ble_srv_common.h"
+
+
+#define NRF_BLE_QWR_INITIALIZED 0xDE // Non-zero value used to make sure the given structure has been initialized by the module.
+#define MODULE_INITIALIZED (p_qwr->initialized == NRF_BLE_QWR_INITIALIZED)
+#include "sdk_macros.h"
+
+ret_code_t nrf_ble_qwr_init(nrf_ble_qwr_t * p_qwr,
+ nrf_ble_qwr_init_t const * p_qwr_init)
+{
+ VERIFY_PARAM_NOT_NULL(p_qwr);
+ VERIFY_PARAM_NOT_NULL(p_qwr_init);
+ if (MODULE_INITIALIZED)
+ {
+ return NRF_ERROR_INVALID_STATE;
+ }
+
+ p_qwr->error_handler = p_qwr_init->error_handler;
+ p_qwr->initialized = NRF_BLE_QWR_INITIALIZED;
+ p_qwr->conn_handle = BLE_CONN_HANDLE_INVALID;
+#if (NRF_BLE_QWR_MAX_ATTR > 0)
+ memset(p_qwr->attr_handles, 0, sizeof(p_qwr->attr_handles));
+ p_qwr->nb_registered_attr = 0;
+ p_qwr->is_user_mem_reply_pending = false;
+ p_qwr->mem_buffer = p_qwr_init->mem_buffer;
+ p_qwr->callback = p_qwr_init->callback;
+ p_qwr->nb_written_handles = 0;
+#endif
+ return NRF_SUCCESS;
+}
+
+
+#if (NRF_BLE_QWR_MAX_ATTR > 0)
+ret_code_t nrf_ble_qwr_attr_register(nrf_ble_qwr_t * p_qwr, uint16_t attr_handle)
+{
+ VERIFY_PARAM_NOT_NULL(p_qwr);
+ VERIFY_MODULE_INITIALIZED();
+
+ if ((p_qwr->nb_registered_attr == NRF_BLE_QWR_MAX_ATTR)
+ || (p_qwr->mem_buffer.p_mem == NULL)
+ || (p_qwr->mem_buffer.len == 0))
+ {
+ return (NRF_ERROR_NO_MEM);
+ }
+
+ if (attr_handle == BLE_GATT_HANDLE_INVALID)
+ {
+ return NRF_ERROR_INVALID_PARAM;
+ }
+
+ p_qwr->attr_handles[p_qwr->nb_registered_attr] = attr_handle;
+ p_qwr->nb_registered_attr++;
+
+ return NRF_SUCCESS;
+}
+
+
+ret_code_t nrf_ble_qwr_value_get(nrf_ble_qwr_t * p_qwr,
+ uint16_t attr_handle,
+ uint8_t * p_mem,
+ uint16_t * p_len)
+{
+ VERIFY_PARAM_NOT_NULL(p_qwr);
+ VERIFY_PARAM_NOT_NULL(p_mem);
+ VERIFY_PARAM_NOT_NULL(p_len);
+ VERIFY_MODULE_INITIALIZED();
+
+ uint16_t i = 0;
+ uint16_t handle = BLE_GATT_HANDLE_INVALID;
+ uint16_t val_len = 0;
+ uint16_t val_offset = 0;
+ uint16_t cur_len = 0;
+
+ do
+ {
+ handle = uint16_decode(&(p_qwr->mem_buffer.p_mem[i]));
+
+ if (handle == BLE_GATT_HANDLE_INVALID)
+ {
+ break;
+ }
+
+ i += sizeof(uint16_t);
+ val_offset = uint16_decode(&(p_qwr->mem_buffer.p_mem[i]));
+ i += sizeof(uint16_t);
+ val_len = uint16_decode(&(p_qwr->mem_buffer.p_mem[i]));
+ i += sizeof(uint16_t);
+
+ if (handle == attr_handle)
+ {
+ cur_len = val_offset + val_len;
+ if (cur_len <= *p_len)
+ {
+ memcpy((p_mem + val_offset), &(p_qwr->mem_buffer.p_mem[i]), val_len);
+ }
+ else
+ {
+ return NRF_ERROR_NO_MEM;
+ }
+ }
+
+ i += val_len;
+ }
+ while (i < p_qwr->mem_buffer.len);
+
+ *p_len = cur_len;
+ return NRF_SUCCESS;
+}
+#endif
+
+
+ret_code_t nrf_ble_qwr_conn_handle_assign(nrf_ble_qwr_t * p_qwr,
+ uint16_t conn_handle)
+{
+ VERIFY_PARAM_NOT_NULL(p_qwr);
+ VERIFY_MODULE_INITIALIZED();
+ p_qwr->conn_handle = conn_handle;
+ return NRF_SUCCESS;
+}
+
+
+/**@brief checks if a user_mem_reply is pending, if so attempts to send it.
+ *
+ * @param[in] p_qwr QWR structure.
+ */
+static void user_mem_reply(nrf_ble_qwr_t * p_qwr)
+{
+ if (p_qwr->is_user_mem_reply_pending)
+ {
+ ret_code_t err_code;
+#if (NRF_BLE_QWR_MAX_ATTR == 0)
+ err_code = sd_ble_user_mem_reply(p_qwr->conn_handle, NULL);
+#else
+ err_code = sd_ble_user_mem_reply(p_qwr->conn_handle, &p_qwr->mem_buffer);
+#endif
+ if (err_code == NRF_SUCCESS)
+ {
+ p_qwr->is_user_mem_reply_pending = false;
+ }
+ else if (err_code == NRF_ERROR_BUSY)
+ {
+ p_qwr->is_user_mem_reply_pending = true;
+ }
+ else
+ {
+ p_qwr->error_handler(err_code);
+ }
+ }
+}
+
+
+/**@brief Handle a user memory request event.
+ *
+ * @param[in] p_qwr QWR structure.
+ * @param[in] p_common_evt User_mem_request event to be handled.
+ */
+static void on_user_mem_request(nrf_ble_qwr_t * p_qwr,
+ ble_common_evt_t const * p_common_evt)
+{
+ if ((p_common_evt->params.user_mem_request.type == BLE_USER_MEM_TYPE_GATTS_QUEUED_WRITES) &&
+ (p_common_evt->conn_handle == p_qwr->conn_handle))
+ {
+ p_qwr->is_user_mem_reply_pending = true;
+ user_mem_reply(p_qwr);
+ }
+}
+
+
+/**@brief Handle a user memory release event.
+ *
+ * @param[in] p_qwr QWR structure.
+ * @param[in] p_common_evt User_mem_release event to be handled.
+ */
+static void on_user_mem_release(nrf_ble_qwr_t * p_qwr,
+ ble_common_evt_t const * p_common_evt)
+{
+#if (NRF_BLE_QWR_MAX_ATTR > 0)
+ if ((p_common_evt->params.user_mem_release.type == BLE_USER_MEM_TYPE_GATTS_QUEUED_WRITES) &&
+ (p_common_evt->conn_handle == p_qwr->conn_handle))
+ {
+ // Cancel the current operation.
+ p_qwr->nb_written_handles = 0;
+ }
+#endif
+}
+
+
+#if (NRF_BLE_QWR_MAX_ATTR > 0)
+/**@brief Handle a prepare write event.
+ *
+ * @param[in] p_qwr QWR structure.
+ * @param[in] p_evt_write WRITE event to be handled.
+ */
+static void on_prepare_write(nrf_ble_qwr_t * p_qwr,
+ ble_gatts_evt_write_t const * p_evt_write)
+{
+ uint32_t err_code;
+ ble_gatts_rw_authorize_reply_params_t auth_reply;
+ memset(&auth_reply, 0, sizeof(auth_reply));
+
+ auth_reply.params.write.gatt_status = NRF_BLE_QWR_REJ_REQUEST_ERR_CODE;
+ auth_reply.type = BLE_GATTS_AUTHORIZE_TYPE_WRITE;
+
+ uint32_t i;
+
+ for (i = 0; i < p_qwr->nb_written_handles; i++)
+ {
+ if (p_qwr->written_attr_handles[i] == p_evt_write->handle)
+ {
+ auth_reply.params.write.gatt_status = BLE_GATT_STATUS_SUCCESS;
+ break;
+ }
+ }
+
+ if (auth_reply.params.write.gatt_status != BLE_GATT_STATUS_SUCCESS)
+ {
+ for (i = 0; i < p_qwr->nb_registered_attr; i++)
+ {
+ if (p_qwr->attr_handles[i] == p_evt_write->handle)
+ {
+ auth_reply.params.write.gatt_status = BLE_GATT_STATUS_SUCCESS;
+ p_qwr->written_attr_handles[p_qwr->nb_written_handles++] = p_evt_write->handle;
+ break;
+ }
+ }
+ }
+
+ err_code = sd_ble_gatts_rw_authorize_reply(p_qwr->conn_handle, &auth_reply);
+ if (err_code != NRF_SUCCESS)
+ {
+ // Cancel the current operation.
+ p_qwr->nb_written_handles = 0;
+
+ // Report error to application.
+ p_qwr->error_handler(err_code);
+ }
+
+}
+
+
+/**@brief Handle an execute write event.
+ *
+ * @param[in] p_qwr QWR structure.
+ * @param[in] p_evt_write EXEC WRITE event to be handled.
+ */
+static void on_execute_write(nrf_ble_qwr_t * p_qwr,
+ ble_gatts_evt_write_t const * p_evt_write)
+{
+ uint32_t err_code;
+ ble_gatts_rw_authorize_reply_params_t auth_reply;
+ memset(&auth_reply, 0, sizeof(auth_reply));
+
+ auth_reply.params.write.gatt_status = BLE_GATT_STATUS_SUCCESS;
+ auth_reply.type = BLE_GATTS_AUTHORIZE_TYPE_WRITE;
+
+ if (p_qwr->nb_written_handles == 0)
+ {
+ auth_reply.params.write.gatt_status = NRF_BLE_QWR_REJ_REQUEST_ERR_CODE;
+ err_code = sd_ble_gatts_rw_authorize_reply(p_qwr->conn_handle, &auth_reply);
+ if (err_code != NRF_SUCCESS)
+ {
+ // Report error to application.
+ p_qwr->error_handler(err_code);
+ }
+ return;
+ }
+
+ for (uint16_t i = 0; i < p_qwr->nb_written_handles; i++)
+ {
+ nrf_ble_qwr_evt_t evt;
+ uint16_t ret_val;
+
+ evt.evt_type = NRF_BLE_QWR_EVT_AUTH_REQUEST;
+ evt.attr_handle = p_qwr->written_attr_handles[i];
+ ret_val = p_qwr->callback(p_qwr, &evt);
+ if (ret_val != BLE_GATT_STATUS_SUCCESS)
+ {
+ auth_reply.params.write.gatt_status = ret_val;
+ }
+ }
+
+ err_code = sd_ble_gatts_rw_authorize_reply(p_qwr->conn_handle, &auth_reply);
+ if (err_code != NRF_SUCCESS)
+ {
+ // Report error to application.
+ p_qwr->error_handler(err_code);
+ }
+
+ // If the execute has not been rejected by any of the registered applications, propagate execute write event to all written handles. */
+ if (auth_reply.params.write.gatt_status == BLE_GATT_STATUS_SUCCESS)
+ {
+ for (uint16_t i = 0; i < p_qwr->nb_written_handles; i++)
+ {
+ nrf_ble_qwr_evt_t evt;
+ evt.evt_type = NRF_BLE_QWR_EVT_EXECUTE_WRITE;
+ evt.attr_handle = p_qwr->written_attr_handles[i];
+ /*lint -e534 -save "Ignoring return value of function" */
+ p_qwr->callback(p_qwr, &evt);
+ /*lint -restore*/
+
+ auth_reply.params.write.gatt_status = BLE_GATT_STATUS_SUCCESS;
+ }
+ }
+ p_qwr->nb_written_handles = 0;
+}
+
+
+/**@brief Handle a cancel write event.
+ *
+ * @param[in] p_qwr QWR structure.
+ * @param[in] p_evt_write EXEC WRITE event to be handled.
+ */
+static void on_cancel_write(nrf_ble_qwr_t * p_qwr,
+ ble_gatts_evt_write_t const * p_evt_write)
+{
+ uint32_t err_code;
+ ble_gatts_rw_authorize_reply_params_t auth_reply;
+ memset(&auth_reply, 0, sizeof(auth_reply));
+
+ auth_reply.type = BLE_GATTS_AUTHORIZE_TYPE_WRITE;
+ auth_reply.params.write.gatt_status = BLE_GATT_STATUS_SUCCESS;
+
+ err_code = sd_ble_gatts_rw_authorize_reply(p_qwr->conn_handle, &auth_reply);
+ if (err_code != NRF_SUCCESS)
+ {
+ // Report error to application.
+ p_qwr->error_handler(err_code);
+ }
+ p_qwr->nb_written_handles = 0;
+}
+#endif
+
+/**@brief Handle a rw_authorize_request event.
+ *
+ * @param[in] p_qwr QWR structure.
+ * @param[in] p_gatts_evt RW_authorize_request event to be handled.
+ */
+static void on_rw_authorize_request(nrf_ble_qwr_t * p_qwr,
+ ble_gatts_evt_t const * p_gatts_evt)
+{
+ if (p_gatts_evt->conn_handle != p_qwr->conn_handle)
+ {
+ return;
+ }
+
+ ble_gatts_evt_rw_authorize_request_t const * p_auth_req = &p_gatts_evt->params.authorize_request;
+
+ if (p_auth_req->type != BLE_GATTS_AUTHORIZE_TYPE_WRITE)
+ {
+ return;
+ }
+
+#if (NRF_BLE_QWR_MAX_ATTR == 0)
+ // Handle only queued write related operations.
+ if ((p_auth_req->request.write.op != BLE_GATTS_OP_PREP_WRITE_REQ) &&
+ (p_auth_req->request.write.op != BLE_GATTS_OP_EXEC_WRITE_REQ_NOW) &&
+ (p_auth_req->request.write.op != BLE_GATTS_OP_EXEC_WRITE_REQ_CANCEL))
+ {
+ return;
+ }
+
+ // Prepare the response.
+ ble_gatts_rw_authorize_reply_params_t auth_reply = {0};
+
+ auth_reply.type = BLE_GATTS_AUTHORIZE_TYPE_WRITE;
+ auth_reply.params.write.gatt_status = NRF_BLE_QWR_REJ_REQUEST_ERR_CODE;
+ if (p_auth_req->request.write.op == BLE_GATTS_OP_EXEC_WRITE_REQ_CANCEL)
+ {
+ auth_reply.params.write.gatt_status = BLE_GATT_STATUS_SUCCESS;
+ }
+
+ ret_code_t err_code = sd_ble_gatts_rw_authorize_reply(p_gatts_evt->conn_handle, &auth_reply);
+ if (err_code != NRF_SUCCESS)
+ {
+ // Report error to application.
+ p_qwr->error_handler(err_code);
+ }
+#else
+ switch (p_auth_req->request.write.op)
+ {
+ case BLE_GATTS_OP_PREP_WRITE_REQ:
+ on_prepare_write(p_qwr, &p_auth_req->request.write);
+ break; // BLE_GATTS_OP_PREP_WRITE_REQ
+
+ case BLE_GATTS_OP_EXEC_WRITE_REQ_NOW:
+ on_execute_write(p_qwr, &p_auth_req->request.write);
+ break; // BLE_GATTS_OP_EXEC_WRITE_REQ_NOW
+
+ case BLE_GATTS_OP_EXEC_WRITE_REQ_CANCEL:
+ on_cancel_write(p_qwr, &p_auth_req->request.write);
+ break; // BLE_GATTS_OP_EXEC_WRITE_REQ_CANCEL
+
+ default:
+ // No implementation needed.
+ break;
+ }
+#endif
+}
+
+
+void nrf_ble_qwr_on_ble_evt(ble_evt_t const * p_ble_evt, void * p_context)
+{
+ VERIFY_PARAM_NOT_NULL_VOID(p_context);
+ VERIFY_PARAM_NOT_NULL_VOID(p_ble_evt);
+
+ nrf_ble_qwr_t * p_qwr = (nrf_ble_qwr_t *)p_context;
+
+ VERIFY_MODULE_INITIALIZED_VOID();
+
+ if (p_ble_evt->evt.common_evt.conn_handle == p_qwr->conn_handle)
+ {
+ user_mem_reply(p_qwr);
+ }
+
+ switch (p_ble_evt->header.evt_id)
+ {
+ case BLE_EVT_USER_MEM_REQUEST:
+ on_user_mem_request(p_qwr, &p_ble_evt->evt.common_evt);
+ break; // BLE_EVT_USER_MEM_REQUEST
+
+ case BLE_EVT_USER_MEM_RELEASE:
+ on_user_mem_release(p_qwr, &p_ble_evt->evt.common_evt);
+ break; // BLE_EVT_USER_MEM_REQUEST
+
+ case BLE_GATTS_EVT_RW_AUTHORIZE_REQUEST:
+ on_rw_authorize_request(p_qwr, &p_ble_evt->evt.gatts_evt);
+ break; // BLE_GATTS_EVT_RW_AUTHORIZE_REQUEST
+
+ case BLE_GAP_EVT_DISCONNECTED:
+ if (p_ble_evt->evt.gap_evt.conn_handle == p_qwr->conn_handle)
+ {
+ p_qwr->conn_handle = BLE_CONN_HANDLE_INVALID;
+#if (NRF_BLE_QWR_MAX_ATTR > 0)
+ p_qwr->nb_written_handles = 0;
+#endif
+ }
+ break; // BLE_GAP_EVT_DISCONNECTED
+
+ default:
+ break;
+ }
+
+}
+#endif // NRF_MODULE_ENABLED(NRF_BLE_QWR)
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/nrf_ble_qwr/nrf_ble_qwr.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/nrf_ble_qwr/nrf_ble_qwr.h
new file mode 100644
index 0000000..6ec27cb
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/nrf_ble_qwr/nrf_ble_qwr.h
@@ -0,0 +1,246 @@
+/**
+ * Copyright (c) 2016 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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
+ *
+ * @defgroup nrf_ble_qwr Queued Writes module
+ * @{
+ * @ingroup ble_sdk_lib
+ * @brief Module for handling Queued Write operations.
+ *
+ * @details This module handles prepare write, execute write, and cancel write
+ * commands. It also manages memory requests related to these operations.
+ *
+ * @note The application must propagate BLE stack events to this module by calling
+ * @ref nrf_ble_qwr_on_ble_evt().
+ */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifndef NRF_BLE_QUEUED_WRITES_H__
+#define NRF_BLE_QUEUED_WRITES_H__
+
+#include <stdint.h>
+#include "nordic_common.h"
+#include "sdk_common.h"
+#include "ble.h"
+#include "ble_srv_common.h"
+
+/**@brief Macro for defining a nrf_ble_qwr instance.
+ *
+ * @param _name Name of the instance.
+ * @hideinitializer
+ */
+#define NRF_BLE_QWR_DEF(_name) \
+ static nrf_ble_qwr_t _name; \
+ NRF_SDH_BLE_OBSERVER(_name ## _obs, \
+ NRF_BLE_QWR_BLE_OBSERVER_PRIO, \
+ nrf_ble_qwr_on_ble_evt, \
+ &_name)
+
+/**@brief Macro for defining an array of nrf_ble_qwr instance.
+ *
+ * @param _name Name of the array.
+ * @param _cnt Size of the array.
+ * @hideinitializer
+ */
+#define NRF_BLE_QWRS_DEF(_name, _cnt) \
+ static nrf_ble_qwr_t _name[_cnt]; \
+ NRF_SDH_BLE_OBSERVERS(_name ## _obs, \
+ NRF_BLE_QWR_BLE_OBSERVER_PRIO, \
+ nrf_ble_qwr_on_ble_evt, \
+ &_name, \
+ _cnt)
+
+
+#define NRF_BLE_QWR_REJ_REQUEST_ERR_CODE BLE_GATT_STATUS_ATTERR_APP_BEGIN + 0 //!< Error code used by the module to reject prepare write requests on non-registered attributes.
+
+
+/**@brief Queued Writes module event types. */
+typedef enum
+{
+ NRF_BLE_QWR_EVT_EXECUTE_WRITE, //!< Event that indicates that an execute write command was received for a registered handle and that the received data was actually written and is now ready.
+ NRF_BLE_QWR_EVT_AUTH_REQUEST, //!< Event that indicates that an execute write command was received for a registered handle and that the write request must now be accepted or rejected.
+} nrf_ble_qwr_evt_type_t;
+
+/**@brief Queued Writes module events. */
+typedef struct
+{
+ nrf_ble_qwr_evt_type_t evt_type; //!< Type of the event.
+ uint16_t attr_handle; //!< Handle of the attribute to which the event relates.
+} nrf_ble_qwr_evt_t;
+
+// Forward declaration of the nrf_ble_qwr_t type.
+struct nrf_ble_qwr_t;
+
+/**@brief Queued Writes module event handler type.
+ *
+ * If the provided event is of type @ref NRF_BLE_QWR_EVT_AUTH_REQUEST,
+ * this function must accept or reject the execute write request by returning
+ * one of the @ref BLE_GATT_STATUS_CODES.*/
+typedef uint16_t (* nrf_ble_qwr_evt_handler_t) (struct nrf_ble_qwr_t * p_qwr,
+ nrf_ble_qwr_evt_t * p_evt);
+
+/**@brief Queued Writes structure.
+ * @details This structure contains status information for the Queued Writes module. */
+typedef struct nrf_ble_qwr_t
+{
+ uint8_t initialized; //!< Flag that indicates whether the module has been initialized.
+ uint16_t conn_handle; //!< Connection handle.
+ ble_srv_error_handler_t error_handler; //!< Error handler.
+ bool is_user_mem_reply_pending; //!< Flag that indicates whether a mem_reply is pending (because a previous attempt returned busy).
+#if (NRF_BLE_QWR_MAX_ATTR > 0)
+ uint16_t attr_handles[NRF_BLE_QWR_MAX_ATTR]; //!< List of handles for registered attributes, for which the module accepts and handles prepare write operations.
+ uint8_t nb_registered_attr; //!< Number of registered attributes.
+ uint16_t written_attr_handles[NRF_BLE_QWR_MAX_ATTR]; //!< List of attribute handles that have been written to during the current prepare write or execute write operation.
+ uint8_t nb_written_handles; //!< Number of attributes that have been written to during the current prepare write or execute write operation.
+ ble_user_mem_block_t mem_buffer; //!< Memory buffer that is provided to the SoftDevice on an ON_USER_MEM_REQUEST event.
+ nrf_ble_qwr_evt_handler_t callback; //!< Event handler function that is called for events concerning the handles of all registered attributes.
+#endif
+} nrf_ble_qwr_t;
+
+/**@brief Queued Writes init structure.
+ * @details This structure contains all information
+ * that is needed to initialize the Queued Writes module. */
+typedef struct
+{
+ ble_srv_error_handler_t error_handler; //!< Error handler.
+#if (NRF_BLE_QWR_MAX_ATTR > 0)
+ ble_user_mem_block_t mem_buffer; //!< Memory buffer that is provided to the SoftDevice on an ON_USER_MEM_REQUEST event.
+ nrf_ble_qwr_evt_handler_t callback; //!< Event handler function that is called for events concerning the handles of all registered attributes.
+#endif
+} nrf_ble_qwr_init_t;
+
+
+/**@brief Function for initializing the Queued Writes module.
+ *
+ * @details Call this function in the main entry of your application to
+ * initialize the Queued Writes module. It must be called only once with a
+ * given Queued Writes structure.
+ *
+ * @param[out] p_qwr Queued Writes structure. This structure must be
+ * supplied by the application. It is initialized by this function
+ * and is later used to identify the particular Queued Writes instance.
+ * @param[in] p_qwr_init Initialization structure.
+ *
+ * @retval NRF_SUCCESS If the Queued Writes module was initialized successfully.
+ * @retval NRF_ERROR_NULL If any of the given pointers is NULL.
+ * @retval NRF_ERROR_INVALID_STATE If the given context has already been initialized.
+ */
+ret_code_t nrf_ble_qwr_init(nrf_ble_qwr_t * p_qwr,
+ nrf_ble_qwr_init_t const * p_qwr_init);
+
+
+/**@brief Function for assigning a connection handle to a given instance of the Queued Writes module.
+ *
+ * @details Call this function when a link with a peer has been established to
+ * associate this link to the instance of the module. This makes it
+ * possible to handle several links and associate each link to a particular
+ * instance of this module.
+ *
+ * @param[in] p_qwr Queued Writes structure.
+ * @param[in] conn_handle Connection handle to be associated with the given Queued Writes instance.
+ *
+ * @retval NRF_SUCCESS If the assignment was successful.
+ * @retval NRF_ERROR_NULL If any of the given pointers is NULL.
+ * @retval NRF_ERROR_INVALID_STATE If the given context has not been initialized.
+ */
+ret_code_t nrf_ble_qwr_conn_handle_assign(nrf_ble_qwr_t * p_qwr,
+ uint16_t conn_handle);
+
+
+/**@brief Function for handling BLE stack events.
+ *
+ * @details Handles all events from the BLE stack that are of interest to the Queued Writes module.
+ *
+ * @param[in] p_ble_evt Event received from the BLE stack.
+ * @param[in] p_context Queued Writes structure.
+ */
+void nrf_ble_qwr_on_ble_evt(ble_evt_t const * p_ble_evt, void * p_context);
+
+
+#if (NRF_BLE_QWR_MAX_ATTR > 0)
+/**@brief Function for registering an attribute with the Queued Writes module.
+ *
+ * @details Call this function for each attribute that you want to enable for
+ * Queued Writes (thus a series of prepare write and execute write operations).
+ *
+ * @param[in] p_qwr Queued Writes structure.
+ * @param[in] attr_handle Handle of the attribute to register.
+ *
+ * @retval NRF_SUCCESS If the registration was successful.
+ * @retval NRF_ERROR_NO_MEM If no more memory is available to add this registration.
+ * @retval NRF_ERROR_NULL If any of the given pointers is NULL.
+ * @retval NRF_ERROR_INVALID_STATE If the given context has not been initialized.
+ */
+ret_code_t nrf_ble_qwr_attr_register(nrf_ble_qwr_t * p_qwr, uint16_t attr_handle);
+
+
+/**@brief Function for retrieving the received data for a given attribute.
+ *
+ * @details Call this function after receiving an @ref NRF_BLE_QWR_EVT_AUTH_REQUEST
+ * event to retrieve a linear copy of the data that was received for the given attribute.
+ *
+ * @param[in] p_qwr Queued Writes structure.
+ * @param[in] attr_handle Handle of the attribute.
+ * @param[out] p_mem Pointer to the application buffer where the received data will be copied.
+ * @param[in,out] p_len Input: length of the input buffer. Output: length of the received data.
+ *
+ *
+ * @retval NRF_SUCCESS If the data was retrieved and stored successfully.
+ * @retval NRF_ERROR_NO_MEM If the provided buffer was smaller than the received data.
+ * @retval NRF_ERROR_NULL If any of the given pointers is NULL.
+ * @retval NRF_ERROR_INVALID_STATE If the given context has not been initialized.
+ */
+ret_code_t nrf_ble_qwr_value_get(nrf_ble_qwr_t * p_qwr,
+ uint16_t attr_handle,
+ uint8_t * p_mem,
+ uint16_t * p_len);
+#endif // (NRF_BLE_QWR_MAX_ATTR > 0)
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // NRF_BLE_QUEUED_WRITES_H__
+
+/** @} */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/peer_manager/gatt_cache_manager.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/peer_manager/gatt_cache_manager.c
new file mode 100644
index 0000000..053a389
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/peer_manager/gatt_cache_manager.c
@@ -0,0 +1,578 @@
+/**
+ * Copyright (c) 2015 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#include "sdk_common.h"
+#if NRF_MODULE_ENABLED(PEER_MANAGER)
+#include "gatt_cache_manager.h"
+
+#include "ble_gap.h"
+#include "ble_err.h"
+#include "ble_conn_state.h"
+#include "peer_manager_types.h"
+#include "peer_manager_internal.h"
+#include "id_manager.h"
+#include "gatts_cache_manager.h"
+#include "peer_database.h"
+#include "pm_mutex.h"
+
+
+// The number of registered event handlers.
+#define GCM_EVENT_HANDLERS_CNT (sizeof(m_evt_handlers) / sizeof(m_evt_handlers[0]))
+
+// GATT Cache Manager event handler in Peer Manager.
+extern void pm_gcm_evt_handler(pm_evt_t * p_gcm_evt);
+
+// GATT Cache Manager events' handlers.
+// The number of elements in this array is GCM_EVENT_HANDLERS_CNT.
+static pm_evt_handler_internal_t m_evt_handlers[] =
+{
+ pm_gcm_evt_handler
+};
+
+static bool m_module_initialized;
+static uint8_t m_db_update_in_progress_mutex; /**< Mutex indicating whether a local DB write operation is ongoing. */
+static ble_conn_state_user_flag_id_t m_flag_local_db_update_pending; /**< Flag ID for flag collection to keep track of which connections need a local DB update procedure. */
+static ble_conn_state_user_flag_id_t m_flag_local_db_apply_pending; /**< Flag ID for flag collection to keep track of which connections need a local DB apply procedure. */
+static ble_conn_state_user_flag_id_t m_flag_service_changed_pending; /**< Flag ID for flag collection to keep track of which connections need to be sent a service changed indication. */
+static ble_conn_state_user_flag_id_t m_flag_service_changed_sent; /**< Flag ID for flag collection to keep track of which connections have been sent a service changed indication and are waiting for a handle value confirmation. */
+
+#ifdef PM_SERVICE_CHANGED_ENABLED
+ STATIC_ASSERT(PM_SERVICE_CHANGED_ENABLED || !NRF_SDH_BLE_SERVICE_CHANGED,
+ "PM_SERVICE_CHANGED_ENABLED should be enabled if NRF_SDH_BLE_SERVICE_CHANGED is enabled.");
+#else
+ #define PM_SERVICE_CHANGED_ENABLED 1
+#endif
+
+/**@brief Function for resetting the module variable(s) of the GSCM module.
+ *
+ * @param[out] The instance to reset.
+ */
+static void internal_state_reset()
+{
+ m_module_initialized = false;
+}
+
+
+static void evt_send(pm_evt_t * p_gcm_evt)
+{
+ p_gcm_evt->peer_id = im_peer_id_get_by_conn_handle(p_gcm_evt->conn_handle);
+
+ for (uint32_t i = 0; i < GCM_EVENT_HANDLERS_CNT; i++)
+ {
+ m_evt_handlers[i](p_gcm_evt);
+ }
+}
+
+
+/**@brief Function for checking a write event for whether a CCCD was written during the write
+ * operation.
+ *
+ * @param[in] p_write_evt The parameters of the write event.
+ *
+ * @return Whether the write was on a CCCD.
+ */
+static bool cccd_written(ble_gatts_evt_write_t const * p_write_evt)
+{
+ return ( (p_write_evt->op == BLE_GATTS_OP_WRITE_REQ)
+ && (p_write_evt->uuid.type == BLE_UUID_TYPE_BLE)
+ && (p_write_evt->uuid.uuid == BLE_UUID_DESCRIPTOR_CLIENT_CHAR_CONFIG)
+ );
+}
+
+
+/**@brief Function for sending an PM_EVT_ERROR_UNEXPECTED event.
+ *
+ * @param[in] conn_handle The connection handle the event pertains to.
+ * @param[in] err_code The unexpected error that occurred.
+ */
+static void send_unexpected_error(uint16_t conn_handle, ret_code_t err_code)
+{
+ pm_evt_t error_evt =
+ {
+ .evt_id = PM_EVT_ERROR_UNEXPECTED,
+ .conn_handle = conn_handle,
+ .params =
+ {
+ .error_unexpected =
+ {
+ .error = err_code,
+ }
+ }
+ };
+ evt_send(&error_evt);
+}
+
+
+/**@brief Function for performing the local DB update procedure in an event context, where no return
+ * code can be given.
+ *
+ * @details This function will do the procedure, and check the result, set a flag if needed, and
+ * send an event if needed.
+ *
+ * @param[in] conn_handle The connection to perform the procedure on.
+ */
+static void local_db_apply_in_evt(uint16_t conn_handle)
+{
+ bool set_procedure_as_pending = false;
+ ret_code_t err_code;
+ pm_evt_t event =
+ {
+ .conn_handle = conn_handle,
+ };
+
+ if (conn_handle == BLE_CONN_HANDLE_INVALID)
+ {
+ return;
+ }
+
+ err_code = gscm_local_db_cache_apply(conn_handle);
+
+ switch (err_code)
+ {
+ case NRF_SUCCESS:
+ event.evt_id = PM_EVT_LOCAL_DB_CACHE_APPLIED;
+
+ evt_send(&event);
+ break;
+
+ case NRF_ERROR_BUSY:
+ set_procedure_as_pending = true;
+ break;
+
+ case NRF_ERROR_INVALID_DATA:
+ event.evt_id = PM_EVT_LOCAL_DB_CACHE_APPLY_FAILED;
+
+ evt_send(&event);
+ break;
+
+ case BLE_ERROR_INVALID_CONN_HANDLE:
+ /* Do nothing */
+ break;
+
+ default:
+ send_unexpected_error(conn_handle, err_code);
+ break;
+ }
+
+ ble_conn_state_user_flag_set(conn_handle, m_flag_local_db_apply_pending, set_procedure_as_pending);
+}
+
+
+/**@brief Function for asynchronously starting a DB update procedure.
+ *
+ * @note This procedure can only be started asynchronously.
+ *
+ * @param[in] conn_handle The connection to perform the procedure on.
+ * @param[in] update Whether to perform the procedure.
+ */
+static __INLINE void local_db_update(uint16_t conn_handle, bool update)
+{
+ ble_conn_state_user_flag_set(conn_handle, m_flag_local_db_update_pending, update);
+}
+
+
+/**@brief Function for performing the local DB update procedure in an event context, where no return
+ * code can be given.
+ *
+ * @details This function will do the procedure, and check the result, set a flag if needed, and
+ * send an event if needed.
+ *
+ * @param[in] conn_handle The connection to perform the procedure on.
+ */
+static bool local_db_update_in_evt(uint16_t conn_handle)
+{
+ bool set_procedure_as_pending = false;
+ bool success = false;
+ ret_code_t err_code = gscm_local_db_cache_update(conn_handle);
+
+ switch (err_code)
+ {
+ case NRF_SUCCESS:
+ success = true;
+ break;
+
+ case BLE_ERROR_INVALID_CONN_HANDLE:
+ /* Do nothing */
+ break;
+
+ case NRF_ERROR_BUSY:
+ set_procedure_as_pending = true;
+ break;
+
+ case NRF_ERROR_STORAGE_FULL:
+ {
+ pm_evt_t event =
+ {
+ .evt_id = PM_EVT_STORAGE_FULL,
+ .conn_handle = conn_handle,
+ };
+
+ evt_send(&event);
+ break;
+ }
+
+ default:
+ send_unexpected_error(conn_handle, err_code);
+ break;
+ }
+
+ local_db_update(conn_handle, set_procedure_as_pending);
+
+ return success;
+}
+
+#if PM_SERVICE_CHANGED_ENABLED
+/**@brief Function for sending a service changed indication in an event context, where no return
+ * code can be given.
+ *
+ * @details This function will do the procedure, and check the result, set a flag if needed, and
+ * send an event if needed.
+ *
+ * @param[in] conn_handle The connection to perform the procedure on.
+ */
+static void service_changed_send_in_evt(uint16_t conn_handle)
+{
+ bool sc_pending_state = true;
+ bool sc_sent_state = false;
+ ret_code_t err_code = gscm_service_changed_ind_send(conn_handle);
+
+ switch (err_code)
+ {
+ case NRF_SUCCESS:
+ {
+ pm_evt_t event =
+ {
+ .evt_id = PM_EVT_SERVICE_CHANGED_IND_SENT,
+ .conn_handle = conn_handle,
+ };
+
+ sc_sent_state = true;
+
+ evt_send(&event);
+ break;
+ }
+
+ case NRF_ERROR_BUSY:
+ // Do nothing.
+ break;
+
+ case NRF_ERROR_INVALID_STATE:
+ // CCCDs not enabled. Drop indication.
+ // Fallthrough.
+
+ case NRF_ERROR_NOT_SUPPORTED:
+ // Service changed not supported. Drop indication.
+ sc_pending_state = false;
+ gscm_db_change_notification_done(im_peer_id_get_by_conn_handle(conn_handle));
+ break;
+
+ case BLE_ERROR_GATTS_SYS_ATTR_MISSING:
+ local_db_apply_in_evt(conn_handle);
+ break;
+
+ case BLE_ERROR_INVALID_CONN_HANDLE:
+ // Do nothing.
+ break;
+
+ default:
+ send_unexpected_error(conn_handle, err_code);
+ break;
+ }
+
+ ble_conn_state_user_flag_set(conn_handle, m_flag_service_changed_pending, sc_pending_state);
+ ble_conn_state_user_flag_set(conn_handle, m_flag_service_changed_sent, sc_sent_state);
+}
+#endif
+
+static void apply_pending_handle(uint16_t conn_handle, void * p_context)
+{
+ UNUSED_PARAMETER(p_context);
+ local_db_apply_in_evt(conn_handle);
+}
+
+
+static __INLINE void apply_pending_flags_check(void)
+{
+ UNUSED_RETURN_VALUE(ble_conn_state_for_each_set_user_flag(m_flag_local_db_apply_pending,
+ apply_pending_handle,
+ NULL));
+}
+
+
+static void db_update_pending_handle(uint16_t conn_handle, void * p_context)
+{
+ UNUSED_PARAMETER(p_context);
+ if (pm_mutex_lock(&m_db_update_in_progress_mutex, 0))
+ {
+ if (local_db_update_in_evt(conn_handle))
+ {
+ // Successfully started writing to flash.
+ return;
+ }
+ else
+ {
+ pm_mutex_unlock(&m_db_update_in_progress_mutex, 0);
+ }
+ }
+}
+
+
+static __INLINE void update_pending_flags_check(void)
+{
+ UNUSED_RETURN_VALUE(ble_conn_state_for_each_set_user_flag(m_flag_local_db_update_pending,
+ db_update_pending_handle,
+ NULL));
+}
+
+
+#if PM_SERVICE_CHANGED_ENABLED
+static void sc_send_pending_handle(uint16_t conn_handle, void * p_context)
+{
+ UNUSED_PARAMETER(p_context);
+ if (!ble_conn_state_user_flag_get(conn_handle, m_flag_service_changed_sent))
+ {
+ service_changed_send_in_evt(conn_handle);
+ }
+}
+
+
+static __INLINE void service_changed_pending_flags_check(void)
+{
+ UNUSED_RETURN_VALUE(ble_conn_state_for_each_set_user_flag(m_flag_service_changed_pending,
+ sc_send_pending_handle,
+ NULL));
+}
+#endif
+
+
+/**@brief Callback function for events from the ID Manager module.
+ * This function is registered in the ID Manager module.
+ *
+ * @param[in] p_event The event from the ID Manager module.
+ */
+void gcm_im_evt_handler(pm_evt_t * p_event)
+{
+ switch (p_event->evt_id)
+ {
+ case PM_EVT_BONDED_PEER_CONNECTED:
+ local_db_apply_in_evt(p_event->conn_handle);
+#if (PM_SERVICE_CHANGED_ENABLED == 1)
+ if (gscm_service_changed_ind_needed(p_event->conn_handle))
+ {
+ ble_conn_state_user_flag_set(p_event->conn_handle, m_flag_service_changed_pending, true);
+ }
+#endif
+ break;
+ default:
+ break;
+ }
+}
+
+
+/**@brief Callback function for events from the Peer Database module.
+ * This handler is extern in Peer Database.
+ *
+ * @param[in] p_event The event from the Security Dispatcher module.
+ */
+void gcm_pdb_evt_handler(pm_evt_t * p_event)
+{
+ if ( p_event->evt_id == PM_EVT_PEER_DATA_UPDATE_SUCCEEDED
+ && p_event->params.peer_data_update_succeeded.action == PM_PEER_DATA_OP_UPDATE)
+ {
+ switch (p_event->params.peer_data_update_succeeded.data_id)
+ {
+ case PM_PEER_DATA_ID_BONDING:
+ {
+ uint16_t conn_handle = im_conn_handle_get(p_event->peer_id);
+
+ if (conn_handle != BLE_CONN_HANDLE_INVALID)
+ {
+ local_db_update(conn_handle, true);
+ }
+ break;
+ }
+
+#if PM_SERVICE_CHANGED_ENABLED
+ case PM_PEER_DATA_ID_SERVICE_CHANGED_PENDING:
+ {
+ ret_code_t err_code;
+ pm_peer_data_flash_t peer_data;
+
+ err_code = pdb_peer_data_ptr_get(p_event->peer_id,
+ PM_PEER_DATA_ID_SERVICE_CHANGED_PENDING,
+ &peer_data);
+
+ if (err_code == NRF_SUCCESS)
+ {
+ if (*peer_data.p_service_changed_pending)
+ {
+ uint16_t conn_handle = im_conn_handle_get(p_event->peer_id);
+ if (conn_handle != BLE_CONN_HANDLE_INVALID)
+ {
+ ble_conn_state_user_flag_set(conn_handle, m_flag_service_changed_pending, true);
+ service_changed_pending_flags_check();
+ }
+ }
+ }
+ break;
+ }
+#endif
+
+ case PM_PEER_DATA_ID_GATT_LOCAL:
+ pm_mutex_unlock(&m_db_update_in_progress_mutex, 0);
+ // Expecting a call to update_pending_flags_check() immediately.
+ break;
+
+ default:
+ /* No action */
+ break;
+ }
+ }
+
+ update_pending_flags_check();
+}
+
+
+ret_code_t gcm_init()
+{
+ NRF_PM_DEBUG_CHECK(!m_module_initialized);
+
+ internal_state_reset();
+
+ m_flag_local_db_update_pending = ble_conn_state_user_flag_acquire();
+ m_flag_local_db_apply_pending = ble_conn_state_user_flag_acquire();
+ m_flag_service_changed_pending = ble_conn_state_user_flag_acquire();
+ m_flag_service_changed_sent = ble_conn_state_user_flag_acquire();
+
+ if ((m_flag_local_db_update_pending == BLE_CONN_STATE_USER_FLAG_INVALID)
+ || (m_flag_local_db_apply_pending == BLE_CONN_STATE_USER_FLAG_INVALID)
+ || (m_flag_service_changed_pending == BLE_CONN_STATE_USER_FLAG_INVALID)
+ || (m_flag_service_changed_sent == BLE_CONN_STATE_USER_FLAG_INVALID)
+ )
+ {
+ return NRF_ERROR_INTERNAL;
+ }
+
+ pm_mutex_init(&m_db_update_in_progress_mutex, 1);
+
+ m_module_initialized = true;
+
+ return NRF_SUCCESS;
+}
+
+
+/**@brief Callback function for BLE events from the SoftDevice.
+ *
+ * @param[in] p_ble_evt The BLE event from the SoftDevice.
+ */
+void gcm_ble_evt_handler(ble_evt_t const * p_ble_evt)
+{
+ uint16_t conn_handle = p_ble_evt->evt.gatts_evt.conn_handle;
+
+ switch (p_ble_evt->header.evt_id)
+ {
+ case BLE_GATTS_EVT_SYS_ATTR_MISSING:
+ local_db_apply_in_evt(conn_handle);
+ break;
+
+#if PM_SERVICE_CHANGED_ENABLED
+ case BLE_GATTS_EVT_SC_CONFIRM:
+ {
+ pm_evt_t event =
+ {
+ .evt_id = PM_EVT_SERVICE_CHANGED_IND_CONFIRMED,
+ .peer_id = im_peer_id_get_by_conn_handle(conn_handle),
+ .conn_handle = conn_handle,
+ };
+
+ gscm_db_change_notification_done(event.peer_id);
+
+ ble_conn_state_user_flag_set(conn_handle, m_flag_service_changed_sent, false);
+ ble_conn_state_user_flag_set(conn_handle, m_flag_service_changed_pending, false);
+ evt_send(&event);
+ break;
+ }
+#endif
+
+ case BLE_GATTS_EVT_WRITE:
+ if (cccd_written(&p_ble_evt->evt.gatts_evt.params.write))
+ {
+ local_db_update(conn_handle, true);
+ update_pending_flags_check();
+ }
+ break;
+ }
+
+ apply_pending_flags_check();
+#if PM_SERVICE_CHANGED_ENABLED
+ service_changed_pending_flags_check();
+#endif
+}
+
+
+ret_code_t gcm_local_db_cache_update(uint16_t conn_handle)
+{
+ NRF_PM_DEBUG_CHECK(m_module_initialized);
+
+ local_db_update(conn_handle, true);
+ update_pending_flags_check();
+
+ return NRF_SUCCESS;
+}
+
+
+#if PM_SERVICE_CHANGED_ENABLED
+void gcm_local_database_has_changed(void)
+{
+ gscm_local_database_has_changed();
+
+ ble_conn_state_conn_handle_list_t conn_handles = ble_conn_state_conn_handles();
+
+ for (uint16_t i = 0; i < conn_handles.len; i++)
+ {
+ if (im_peer_id_get_by_conn_handle(conn_handles.conn_handles[i]) == PM_PEER_ID_INVALID)
+ {
+ ble_conn_state_user_flag_set(conn_handles.conn_handles[i], m_flag_service_changed_pending, true);
+ }
+ }
+
+ service_changed_pending_flags_check();
+}
+#endif
+#endif // NRF_MODULE_ENABLED(PEER_MANAGER)
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/peer_manager/gatt_cache_manager.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/peer_manager/gatt_cache_manager.h
new file mode 100644
index 0000000..0cb508a
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/peer_manager/gatt_cache_manager.h
@@ -0,0 +1,113 @@
+/**
+ * Copyright (c) 2015 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#ifndef GATT_CACHE_MANAGER_H__
+#define GATT_CACHE_MANAGER_H__
+
+#include <stdint.h>
+#include "sdk_errors.h"
+#include "ble.h"
+#include "ble_gap.h"
+#include "peer_manager_types.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+
+/**
+ * @cond NO_DOXYGEN
+ * @defgroup gatt_cache_manager GATT Cache Manager
+ * @ingroup peer_manager
+ * @{
+ * @brief An internal module of @ref peer_manager. A module for managing persistent storing of GATT
+ * attributes.
+ */
+
+
+/**@brief Function for initializing the GATT Cache Manager module.
+ *
+ * @retval NRF_SUCCESS Initialization was successful.
+ * @retval NRF_ERROR_INTERNAL If an internal error occurred.
+ */
+ret_code_t gcm_init(void);
+
+
+/**@brief Function for dispatching SoftDevice events to the GATT Cache Manager module.
+ *
+ * @param[in] p_ble_evt The SoftDevice event.
+ */
+void gcm_ble_evt_handler(ble_evt_t const * p_ble_evt);
+
+
+/**@brief Function for triggering local GATT database data to be stored persistently.
+ *
+ * @details Values are retrieved from SoftDevice and written to persistent storage.
+ *
+ * @note This operation happens asynchronously, so any errors are reported as events.
+ *
+ * @note This function is only needed when you want to override the regular functionality of the
+ * module, e.g. to immediately store to flash instead of waiting for the native logic to
+ * perform the update.
+ *
+ * @param[in] conn_handle Connection handle to perform update on.
+ *
+ * @retval NRF_SUCCESS Store operation started.
+ */
+ret_code_t gcm_local_db_cache_update(uint16_t conn_handle);
+
+
+/**@brief Function for manually informing that the local database has changed.
+ *
+ * @details This causes a service changed notification to be sent to all bonded peers that
+ * subscribe to it.
+ */
+void gcm_local_database_has_changed(void);
+
+/** @}
+ * @endcond
+ */
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* GATT_CACHE_MANAGER_H__ */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/peer_manager/gatts_cache_manager.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/peer_manager/gatts_cache_manager.c
new file mode 100644
index 0000000..3b70837
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/peer_manager/gatts_cache_manager.c
@@ -0,0 +1,347 @@
+/**
+ * Copyright (c) 2015 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#include "sdk_common.h"
+#if NRF_MODULE_ENABLED(PEER_MANAGER)
+#include "gatts_cache_manager.h"
+
+#include <string.h>
+#include "ble_gap.h"
+#include "ble_err.h"
+#include "peer_manager_types.h"
+#include "peer_manager_internal.h"
+#include "peer_database.h"
+#include "id_manager.h"
+
+
+// Syntactic sugar, two spoons.
+#define SYS_ATTR_SYS (BLE_GATTS_SYS_ATTR_FLAG_SYS_SRVCS)
+#define SYS_ATTR_USR (BLE_GATTS_SYS_ATTR_FLAG_USR_SRVCS)
+#define SYS_ATTR_BOTH (SYS_ATTR_SYS | SYS_ATTR_USR)
+
+static bool m_module_initialized;
+static pm_peer_id_t m_current_sc_store_peer_id;
+
+
+/**@brief Function for resetting the module variable(s) of the GSCM module.
+ */
+static void internal_state_reset()
+{
+ m_module_initialized = false;
+ m_current_sc_store_peer_id = PM_PEER_ID_INVALID;
+
+ // If PM_SERVICE_CHANGED_ENABLED is 0, this variable is unused.
+ UNUSED_VARIABLE(m_current_sc_store_peer_id);
+}
+
+
+#if !defined(PM_SERVICE_CHANGED_ENABLED) || (PM_SERVICE_CHANGED_ENABLED == 1)
+//lint -save -e550
+/**@brief Function for storing service_changed_pending = true to flash for all peers, in sequence.
+ *
+ * This function aborts if it gets @ref NRF_ERROR_BUSY when trying to store. A subsequent call will
+ * continue where the last call was aborted.
+ */
+static void service_changed_pending_set(void)
+{
+ NRF_PM_DEBUG_CHECK(m_module_initialized);
+
+ ret_code_t err_code;
+ // Use a uint32_t to enforce 4-byte alignment.
+ static const uint32_t service_changed_pending = true;
+
+ //lint -save -e65 -e64
+ pm_peer_data_const_t peer_data =
+ {
+ .data_id = PM_PEER_DATA_ID_SERVICE_CHANGED_PENDING,
+ .length_words = PM_SC_STATE_N_WORDS(),
+ .p_service_changed_pending = (bool*)&service_changed_pending,
+ };
+ //lint -restore
+
+ err_code = pdb_raw_store(m_current_sc_store_peer_id, &peer_data, NULL);
+ while ((m_current_sc_store_peer_id != PM_PEER_ID_INVALID) && (err_code != NRF_ERROR_BUSY))
+ {
+ m_current_sc_store_peer_id = pdb_next_peer_id_get(m_current_sc_store_peer_id);
+ err_code = pdb_raw_store(m_current_sc_store_peer_id, &peer_data, NULL);
+ }
+}
+//lint -restore
+
+
+
+/**@brief Event handler for events from the Peer Database module.
+ * This function is extern in Peer Database.
+ *
+ * @param[in] p_event The event that has happend with peer id and flags.
+ */
+void gscm_pdb_evt_handler(pm_evt_t * p_event)
+{
+ if (m_current_sc_store_peer_id != PM_PEER_ID_INVALID)
+ {
+ service_changed_pending_set();
+ }
+}
+#endif
+
+
+ret_code_t gscm_init()
+{
+ NRF_PM_DEBUG_CHECK(!m_module_initialized);
+
+ internal_state_reset();
+ m_module_initialized = true;
+
+ return NRF_SUCCESS;
+}
+
+
+ret_code_t gscm_local_db_cache_update(uint16_t conn_handle)
+{
+ NRF_PM_DEBUG_CHECK(m_module_initialized);
+
+ pm_peer_id_t peer_id = im_peer_id_get_by_conn_handle(conn_handle);
+ ret_code_t err_code;
+
+ if (peer_id == PM_PEER_ID_INVALID)
+ {
+ return BLE_ERROR_INVALID_CONN_HANDLE;
+ }
+ else
+ {
+ pm_peer_data_t peer_data;
+ uint16_t n_bufs = 1;
+ bool retry_with_bigger_buffer = false;
+
+ do
+ {
+ retry_with_bigger_buffer = false;
+
+ err_code = pdb_write_buf_get(peer_id, PM_PEER_DATA_ID_GATT_LOCAL, n_bufs++, &peer_data);
+ if (err_code == NRF_SUCCESS)
+ {
+ pm_peer_data_local_gatt_db_t * p_local_gatt_db = peer_data.p_local_gatt_db;
+
+ p_local_gatt_db->flags = SYS_ATTR_BOTH;
+
+ err_code = sd_ble_gatts_sys_attr_get(conn_handle, &p_local_gatt_db->data[0], &p_local_gatt_db->len, p_local_gatt_db->flags);
+
+ if (err_code == NRF_SUCCESS)
+ {
+ err_code = pdb_write_buf_store(peer_id, PM_PEER_DATA_ID_GATT_LOCAL, peer_id);
+ }
+ else
+ {
+ if (err_code == NRF_ERROR_DATA_SIZE)
+ {
+ // The sys attributes are bigger than the requested write buffer.
+ retry_with_bigger_buffer = true;
+ }
+ else if (err_code == NRF_ERROR_NOT_FOUND)
+ {
+ // There are no sys attributes in the GATT db, so nothing needs to be stored.
+ err_code = NRF_SUCCESS;
+ }
+
+ ret_code_t err_code_release = pdb_write_buf_release(peer_id, PM_PEER_DATA_ID_GATT_LOCAL);
+ if (err_code_release != NRF_SUCCESS)
+ {
+ err_code = NRF_ERROR_INTERNAL;
+ }
+ }
+ }
+ else if (err_code == NRF_ERROR_INVALID_PARAM)
+ {
+ // The sys attributes are bigger than the entire write buffer.
+ err_code = NRF_ERROR_DATA_SIZE;
+ }
+ } while (retry_with_bigger_buffer);
+ }
+
+ return err_code;
+}
+
+
+ret_code_t gscm_local_db_cache_apply(uint16_t conn_handle)
+{
+ NRF_PM_DEBUG_CHECK(m_module_initialized);
+
+ pm_peer_id_t peer_id = im_peer_id_get_by_conn_handle(conn_handle);
+ ret_code_t err_code;
+ pm_peer_data_flash_t peer_data;
+ uint8_t const * p_sys_attr_data = NULL;
+ uint16_t sys_attr_len = 0;
+ uint32_t sys_attr_flags = (SYS_ATTR_BOTH);
+ bool all_attributes_applied = true;
+
+ if (peer_id != PM_PEER_ID_INVALID)
+ {
+ err_code = pdb_peer_data_ptr_get(peer_id, PM_PEER_DATA_ID_GATT_LOCAL, &peer_data);
+ if (err_code == NRF_SUCCESS)
+ {
+ pm_peer_data_local_gatt_db_t const * p_local_gatt_db;
+
+ p_local_gatt_db = peer_data.p_local_gatt_db;
+ p_sys_attr_data = p_local_gatt_db->data;
+ sys_attr_len = p_local_gatt_db->len;
+ sys_attr_flags = p_local_gatt_db->flags;
+ }
+ }
+
+ do
+ {
+ err_code = sd_ble_gatts_sys_attr_set(conn_handle, p_sys_attr_data, sys_attr_len, sys_attr_flags);
+
+ if (err_code == NRF_ERROR_NO_MEM)
+ {
+ err_code = NRF_ERROR_BUSY;
+ }
+ else if (err_code == NRF_ERROR_INVALID_STATE)
+ {
+ err_code = NRF_SUCCESS;
+ }
+ else if (err_code == NRF_ERROR_INVALID_DATA)
+ {
+ all_attributes_applied = false;
+
+ if (sys_attr_flags & SYS_ATTR_USR)
+ {
+ // Try setting only system attributes.
+ sys_attr_flags = SYS_ATTR_SYS;
+ }
+ else if (p_sys_attr_data || sys_attr_len)
+ {
+ // Try reporting that none exist.
+ p_sys_attr_data = NULL;
+ sys_attr_len = 0;
+ sys_attr_flags = SYS_ATTR_BOTH;
+ }
+ else
+ {
+ err_code = NRF_ERROR_INTERNAL;
+ }
+ }
+ } while (err_code == NRF_ERROR_INVALID_DATA);
+
+ if (!all_attributes_applied)
+ {
+ err_code = NRF_ERROR_INVALID_DATA;
+ }
+
+ return err_code;
+}
+
+#if !defined(PM_SERVICE_CHANGED_ENABLED) || (PM_SERVICE_CHANGED_ENABLED == 1)
+void gscm_local_database_has_changed(void)
+{
+ NRF_PM_DEBUG_CHECK(m_module_initialized);
+ m_current_sc_store_peer_id = pdb_next_peer_id_get(PM_PEER_ID_INVALID);
+ service_changed_pending_set();
+}
+
+
+bool gscm_service_changed_ind_needed(uint16_t conn_handle)
+{
+ ret_code_t err_code;
+ bool service_changed_state;
+ pm_peer_data_flash_t peer_data;
+
+ peer_data.p_service_changed_pending = &service_changed_state;
+ pm_peer_id_t peer_id = im_peer_id_get_by_conn_handle(conn_handle);
+
+ err_code = pdb_peer_data_ptr_get(peer_id, PM_PEER_DATA_ID_SERVICE_CHANGED_PENDING, &peer_data);
+
+ if (err_code != NRF_SUCCESS)
+ {
+ return false;
+ }
+
+ return *peer_data.p_service_changed_pending;
+}
+
+
+ret_code_t gscm_service_changed_ind_send(uint16_t conn_handle)
+{
+ static uint16_t start_handle;
+ const uint16_t end_handle = 0xFFFF;
+ ret_code_t err_code;
+
+ err_code = sd_ble_gatts_initial_user_handle_get(&start_handle);
+
+ if (err_code != NRF_SUCCESS)
+ {
+ return NRF_ERROR_INTERNAL;
+ }
+
+ do
+ {
+ err_code = sd_ble_gatts_service_changed(conn_handle, start_handle, end_handle);
+ if (err_code == BLE_ERROR_INVALID_ATTR_HANDLE)
+ {
+ start_handle += 1;
+ }
+ } while (err_code == BLE_ERROR_INVALID_ATTR_HANDLE);
+
+ return err_code;
+}
+
+
+void gscm_db_change_notification_done(pm_peer_id_t peer_id)
+{
+ NRF_PM_DEBUG_CHECK(m_module_initialized);
+
+ // Use a uint32_t to enforce 4-byte alignment.
+ static const uint32_t service_changed_pending = false;
+
+ //lint -save -e65 -e64
+ pm_peer_data_const_t peer_data =
+ {
+ .data_id = PM_PEER_DATA_ID_SERVICE_CHANGED_PENDING,
+ .length_words = PM_SC_STATE_N_WORDS(),
+ .p_service_changed_pending = (bool*)&service_changed_pending,
+ };
+ //lint -restore
+
+ // Don't need to check return code, because all error conditions can be ignored.
+ //lint -save -e550
+ (void) pdb_raw_store(peer_id, &peer_data, NULL);
+ //lint -restore
+}
+#endif
+#endif // NRF_MODULE_ENABLED(PEER_MANAGER)
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/peer_manager/gatts_cache_manager.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/peer_manager/gatts_cache_manager.h
new file mode 100644
index 0000000..b1303df
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/peer_manager/gatts_cache_manager.h
@@ -0,0 +1,163 @@
+/**
+ * Copyright (c) 2015 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#ifndef GATTS_CACHE_MANAGER_H__
+#define GATTS_CACHE_MANAGER_H__
+
+#include <stdint.h>
+#include "sdk_errors.h"
+#include "ble.h"
+#include "ble_gap.h"
+#include "peer_manager_types.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+
+/**
+ * @cond NO_DOXYGEN
+ * @defgroup gatts_cache_manager GATT Server Cache Manager
+ * @ingroup peer_manager
+ * @{
+ * @brief An internal module of @ref peer_manager. A module for managing persistent storing of GATT
+ * attributes pertaining to the GATT server role of the local device.
+ */
+
+
+/**@brief Function for initializing the GATT Server Cache Manager module.
+ *
+ * @retval NRF_SUCCESS Initialization was successful.
+ * @retval NRF_ERROR_INTERNAL If an internal error occurred.
+ */
+ret_code_t gscm_init(void);
+
+
+/**@brief Function for triggering local GATT database data to be stored persistently. Values are
+ * retrieved from the SoftDevice and written to persistent storage.
+ *
+ * @param[in] conn_handle Connection handle to perform update on.
+ *
+ * @retval NRF_SUCCESS Store operation started.
+ * @retval BLE_ERROR_INVALID_CONN_HANDLE conn_handle does not refer to an active connection with a
+ * bonded peer.
+ * @retval NRF_ERROR_BUSY Unable to perform operation at this time. Reattempt later.
+ * @retval NRF_ERROR_DATA_SIZE Write buffer not large enough. Call will never work with
+ * this GATT database.
+ * @retval NRF_ERROR_STORAGE_FULL No room in persistent_storage. Free up space; the
+ * operation will be automatically reattempted after the
+ * next FDS garbage collection procedure.
+ */
+ret_code_t gscm_local_db_cache_update(uint16_t conn_handle);
+
+
+/**@brief Function for applying stored local GATT database data to the SoftDevice. Values are
+ * retrieved from persistent storage and given to the SoftDevice.
+ *
+ * @param[in] conn_handle Connection handle to apply values to.
+ *
+ * @retval NRF_SUCCESS Store operation started.
+ * @retval BLE_ERROR_INVALID_CONN_HANDLE conn_handle does not refer to an active connection with a
+ * bonded peer.
+ * @retval NRF_ERROR_INVALID_DATA The stored data was rejected by the SoftDevice, which
+ * probably means that the local database has changed. The
+ * system part of the sys_attributes was attempted applied,
+ * so service changed indications can be sent to subscribers.
+ * @retval NRF_ERROR_BUSY Unable to perform operation at this time. Reattempt later.
+ * @return An unexpected return value from an internal function call.
+ */
+ret_code_t gscm_local_db_cache_apply(uint16_t conn_handle);
+
+
+/**@brief Function for storing the fact that the local database has changed, for all currently
+ * bonded peers.
+ *
+ * @note This will cause a later call to @ref gscm_service_changed_ind_needed to return true for
+ * a connection with a currently bonded peer.
+ */
+void gscm_local_database_has_changed(void);
+
+
+/**@brief Function for checking if a service changed indication should be sent.
+ *
+ * @param[in] conn_handle The connection to check.
+ *
+ * @return true if a service changed indication should be sent, false if not.
+ */
+bool gscm_service_changed_ind_needed(uint16_t conn_handle);
+
+
+/**@brief Function for sending a service changed indication to a connected peer.
+ *
+ * @param[in] conn_handle The connection to send the indication on.
+ *
+ * @retval NRF_SUCCESS Indication sent or not needed.
+ * @retval BLE_ERROR_INVALID_CONN_HANDLE conn_handle does not refer to an active connection.
+ * @retval NRF_ERROR_BUSY Unable to send indication at this time. Reattempt later.
+ * @retval BLE_ERROR_GATTS_SYS_ATTR_MISSING Information missing. Apply local cache, then reattempt.
+ * @retval NRF_ERROR_INVALID_PARAM From @ref sd_ble_gatts_service_changed. Unexpected.
+ * @retval NRF_ERROR_NOT_SUPPORTED Service changed characteristic is not present.
+ * @retval NRF_ERROR_INVALID_STATE Service changed cannot be indicated to this peer
+ * because the peer has not subscribed to it.
+ * @retval NRF_ERROR_INTERNAL An unexpected error happened.
+ */
+ret_code_t gscm_service_changed_ind_send(uint16_t conn_handle);
+
+
+/**@brief Function for specifying that a peer has been made aware of the latest local database
+ * change.
+ *
+ * @note After calling this, a later call to @ref gscm_service_changed_ind_needed will to return
+ * false for this peer unless @ref gscm_local_database_has_changed is called again.
+ *
+ * @param[in] peer_id The connection to send the indication on.
+ */
+void gscm_db_change_notification_done(pm_peer_id_t peer_id);
+
+/** @}
+ * @endcond
+*/
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* GATTS_CACHE_MANAGER_H__ */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/peer_manager/id_manager.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/peer_manager/id_manager.c
new file mode 100644
index 0000000..bbe7702
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/peer_manager/id_manager.c
@@ -0,0 +1,890 @@
+/**
+ * Copyright (c) 2015 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#include "sdk_common.h"
+#if NRF_MODULE_ENABLED(PEER_MANAGER)
+#include "id_manager.h"
+
+#include <string.h>
+#include "ble.h"
+#include "ble_gap.h"
+#include "ble_err.h"
+#include "ble_conn_state.h"
+#include "peer_manager_types.h"
+#include "peer_database.h"
+#include "peer_data_storage.h"
+#include "nrf_soc.h"
+
+
+#define IM_MAX_CONN_HANDLES (20)
+#define IM_NO_INVALID_CONN_HANDLES (0xFF)
+#define IM_ADDR_CLEARTEXT_LENGTH (3)
+#define IM_ADDR_CIPHERTEXT_LENGTH (3)
+
+// The number of registered event handlers.
+#define IM_EVENT_HANDLERS_CNT (sizeof(m_evt_handlers) / sizeof(m_evt_handlers[0]))
+
+
+// Identity Manager event handlers in Peer Manager and GATT Cache Manager.
+extern void pm_im_evt_handler(pm_evt_t * p_event);
+extern void gcm_im_evt_handler(pm_evt_t * p_event);
+
+// Identity Manager events' handlers.
+// The number of elements in this array is IM_EVENT_HANDLERS_CNT.
+static pm_evt_handler_internal_t const m_evt_handlers[] =
+{
+ pm_im_evt_handler,
+ gcm_im_evt_handler
+};
+
+
+typedef struct
+{
+ pm_peer_id_t peer_id;
+ uint16_t conn_handle;
+ ble_gap_addr_t peer_address;
+} im_connection_t;
+
+static bool m_module_initialized;
+static im_connection_t m_connections[IM_MAX_CONN_HANDLES];
+static ble_conn_state_user_flag_id_t m_conn_state_user_flag_id;
+
+static uint8_t m_wlisted_peer_cnt;
+static pm_peer_id_t m_wlisted_peers[BLE_GAP_WHITELIST_ADDR_MAX_COUNT];
+
+
+static void internal_state_reset()
+{
+ m_conn_state_user_flag_id = BLE_CONN_STATE_USER_FLAG_INVALID;
+
+ for (uint32_t i = 0; i < IM_MAX_CONN_HANDLES; i++)
+ {
+ m_connections[i].conn_handle = BLE_CONN_HANDLE_INVALID;
+ }
+}
+
+
+/**@brief Function for sending an event to all registered event handlers.
+ *
+ * @param[in] p_event The event to distribute.
+ */
+static void evt_send(pm_evt_t * p_event)
+{
+ for (uint32_t i = 0; i < IM_EVENT_HANDLERS_CNT; i++)
+ {
+ m_evt_handlers[i](p_event);
+ }
+}
+
+/**@brief Function finding a free position in m_connections.
+ *
+ * @detail All connection handles in the m_connections array are checked against the connection
+ * state module. The index of the first one that is not a connection handle for a current
+ * connection is returned. This position in the array can safely be used for a new connection.
+ *
+ * @return Either the index of a free position in the array or IM_NO_INVALID_CONN_HANDLES if no free
+ position exists.
+ */
+uint8_t get_free_connection()
+{
+ for (uint32_t i = 0; i < IM_MAX_CONN_HANDLES; i++)
+ {
+ // Query the connection state module to check if the
+ // connection handle does not belong to a valid connection.
+ if (!ble_conn_state_user_flag_get(m_connections[i].conn_handle, m_conn_state_user_flag_id))
+ {
+ return i;
+ }
+ }
+ // If all connection handles belong to a valid connection, return IM_NO_INVALID_CONN_HANDLES.
+ return IM_NO_INVALID_CONN_HANDLES;
+}
+
+
+/**@brief Function finding a particular connection handle m_connections.
+ *
+ * @param[in] conn_handle The handle to find.
+ *
+ * @return Either the index of the conn_handle in the array or IM_NO_INVALID_CONN_HANDLES if the
+ * handle was not found.
+ */
+uint8_t get_connection_by_conn_handle(uint16_t conn_handle)
+{
+ if (ble_conn_state_user_flag_get(conn_handle, m_conn_state_user_flag_id))
+ {
+ for (uint32_t i = 0; i < IM_MAX_CONN_HANDLES; i++)
+ {
+ if (m_connections[i].conn_handle == conn_handle)
+ {
+ return i;
+ }
+ }
+ }
+ // If all connection handles belong to a valid connection, return IM_NO_INVALID_CONN_HANDLES.
+ return IM_NO_INVALID_CONN_HANDLES;
+}
+
+
+/**@brief Function for registering a new connection instance.
+ *
+ * @param[in] conn_handle The handle of the new connection.
+ * @param[in] p_ble_addr The address used to connect.
+ *
+ * @return Either the index of the new connection in the array or IM_NO_INVALID_CONN_HANDLES if no
+ * free position exists.
+ */
+uint8_t new_connection(uint16_t conn_handle, ble_gap_addr_t * p_ble_addr)
+{
+ uint8_t conn_index = IM_NO_INVALID_CONN_HANDLES;
+
+ if ((p_ble_addr != NULL) && (conn_handle != BLE_CONN_HANDLE_INVALID))
+ {
+ ble_conn_state_user_flag_set(conn_handle, m_conn_state_user_flag_id, true);
+
+ conn_index = get_connection_by_conn_handle(conn_handle);
+ if (conn_index == IM_NO_INVALID_CONN_HANDLES)
+ {
+ conn_index = get_free_connection();
+ }
+
+ if (conn_index != IM_NO_INVALID_CONN_HANDLES)
+ {
+ m_connections[conn_index].conn_handle = conn_handle;
+ m_connections[conn_index].peer_id = PM_PEER_ID_INVALID;
+ m_connections[conn_index].peer_address = *p_ble_addr;
+ }
+ }
+ return conn_index;
+}
+
+
+/**@brief Function checking the validity of an IRK
+ *
+ * @detail An all-zero IRK is not valid. This function will check if a given IRK is valid.
+ *
+ * @param[in] p_irk The IRK for which the validity is going to be checked.
+ *
+ * @retval true The IRK is valid.
+ * @retval false The IRK is invalid.
+ */
+bool is_valid_irk(ble_gap_irk_t const * p_irk)
+{
+ NRF_PM_DEBUG_CHECK(p_irk != NULL);
+
+ for (uint32_t i = 0; i < BLE_GAP_SEC_KEY_LEN; i++)
+ {
+ if (p_irk->irk[i] != 0)
+ {
+ return true;
+ }
+ }
+ return false;
+}
+
+
+/**@brief Function for comparing two addresses to determine if they are identical
+ *
+ * @note The address type need to be identical, as well as every bit in the address itself.
+ *
+ * @param[in] p_addr1 The first address to be compared.
+ * @param[in] p_addr2 The second address to be compared.
+ *
+ * @retval true The addresses are identical.
+ * @retval false The addresses are not identical.
+ */
+bool addr_compare(ble_gap_addr_t const * p_addr1, ble_gap_addr_t const * p_addr2)
+{
+ // @note emdi: use NRF_PM_DEBUG_CHECK ?
+ if ((p_addr1 == NULL) || (p_addr2 == NULL))
+ {
+ return false;
+ }
+
+ // Check that the addr type is identical, return false if it is not
+ if (p_addr1->addr_type != p_addr2->addr_type)
+ {
+ return false;
+ }
+
+ // Check if the addr bytes are is identical
+ return (memcmp(p_addr1->addr, p_addr2->addr, BLE_GAP_ADDR_LEN) == 0);
+}
+
+
+void im_ble_evt_handler(ble_evt_t const * ble_evt)
+{
+ ble_gap_evt_t gap_evt;
+ pm_peer_id_t bonded_matching_peer_id;
+
+ NRF_PM_DEBUG_CHECK(m_module_initialized);
+
+ if (ble_evt->header.evt_id != BLE_GAP_EVT_CONNECTED)
+ {
+ // Nothing to do.
+ return;
+ }
+
+ gap_evt = ble_evt->evt.gap_evt;
+ bonded_matching_peer_id = PM_PEER_ID_INVALID;
+
+ if ( gap_evt.params.connected.peer_addr.addr_type
+ != BLE_GAP_ADDR_TYPE_RANDOM_PRIVATE_NON_RESOLVABLE)
+ {
+ /* Search the database for bonding data matching the one that triggered the event.
+ * Public and static addresses can be matched on address alone, while resolvable
+ * random addresses can be resolved agains known IRKs. Non-resolvable random addresses
+ * are never matching because they are not longterm form of identification.
+ */
+
+ pm_peer_id_t peer_id;
+ pm_peer_data_flash_t peer_data;
+
+ pds_peer_data_iterate_prepare();
+
+ switch (gap_evt.params.connected.peer_addr.addr_type)
+ {
+ case BLE_GAP_ADDR_TYPE_PUBLIC:
+ case BLE_GAP_ADDR_TYPE_RANDOM_STATIC:
+ {
+ while (pds_peer_data_iterate(PM_PEER_DATA_ID_BONDING, &peer_id, &peer_data))
+ {
+ if (addr_compare(&gap_evt.params.connected.peer_addr,
+ &peer_data.p_bonding_data->peer_ble_id.id_addr_info))
+ {
+ bonded_matching_peer_id = peer_id;
+ break;
+ }
+ }
+ }
+ break;
+
+ case BLE_GAP_ADDR_TYPE_RANDOM_PRIVATE_RESOLVABLE:
+ {
+ while (pds_peer_data_iterate(PM_PEER_DATA_ID_BONDING, &peer_id, &peer_data))
+ {
+ if (im_address_resolve(&gap_evt.params.connected.peer_addr,
+ &peer_data.p_bonding_data->peer_ble_id.id_info))
+ {
+ bonded_matching_peer_id = peer_id;
+ break;
+ }
+ }
+ }
+ break;
+
+ default:
+ NRF_PM_DEBUG_CHECK(false);
+ break;
+ }
+ }
+
+ uint8_t new_index = new_connection(gap_evt.conn_handle,
+ &gap_evt.params.connected.peer_addr);
+ UNUSED_VARIABLE(new_index);
+
+ if (bonded_matching_peer_id != PM_PEER_ID_INVALID)
+ {
+ im_new_peer_id(gap_evt.conn_handle, bonded_matching_peer_id);
+
+ // Send a bonded peer event
+ pm_evt_t im_evt;
+ im_evt.conn_handle = gap_evt.conn_handle;
+ im_evt.peer_id = bonded_matching_peer_id;
+ im_evt.evt_id = PM_EVT_BONDED_PEER_CONNECTED;
+ evt_send(&im_evt);
+ }
+}
+
+
+/**@brief Function to compare two sets of bonding data to check if they belong to the same device.
+ * @note Invalid irks will never match even though they are identical.
+ *
+ * @param[in] p_bonding_data1 First bonding data for comparison
+ * @param[in] p_bonding_data2 Second bonding data for comparison
+ *
+ * @return True if the input matches, false if it does not.
+ */
+bool im_is_duplicate_bonding_data(pm_peer_data_bonding_t const * p_bonding_data1,
+ pm_peer_data_bonding_t const * p_bonding_data2)
+{
+ NRF_PM_DEBUG_CHECK(p_bonding_data1 != NULL);
+ NRF_PM_DEBUG_CHECK(p_bonding_data2 != NULL);
+
+ ble_gap_addr_t const * p_addr1 = &p_bonding_data1->peer_ble_id.id_addr_info;
+ ble_gap_addr_t const * p_addr2 = &p_bonding_data2->peer_ble_id.id_addr_info;
+
+ bool duplicate_irk = ((memcmp(p_bonding_data1->peer_ble_id.id_info.irk,
+ p_bonding_data2->peer_ble_id.id_info.irk,
+ BLE_GAP_SEC_KEY_LEN) == 0)
+ && is_valid_irk(&p_bonding_data1->peer_ble_id.id_info)
+ && is_valid_irk(&p_bonding_data2->peer_ble_id.id_info));
+
+ bool duplicate_addr = addr_compare(p_addr1, p_addr2);
+
+ bool id_addrs = ((p_addr1->addr_type != BLE_GAP_ADDR_TYPE_RANDOM_PRIVATE_RESOLVABLE)
+ && (p_addr1->addr_type != BLE_GAP_ADDR_TYPE_RANDOM_PRIVATE_NON_RESOLVABLE)
+ && (p_addr2->addr_type != BLE_GAP_ADDR_TYPE_RANDOM_PRIVATE_RESOLVABLE)
+ && (p_addr2->addr_type != BLE_GAP_ADDR_TYPE_RANDOM_PRIVATE_NON_RESOLVABLE));
+
+ return (duplicate_addr && id_addrs) || (duplicate_irk && !id_addrs);
+}
+
+
+pm_peer_id_t im_find_duplicate_bonding_data(pm_peer_data_bonding_t const * p_bonding_data,
+ pm_peer_id_t peer_id_skip)
+{
+ pm_peer_id_t peer_id;
+ pm_peer_data_flash_t peer_data_duplicate;
+
+ NRF_PM_DEBUG_CHECK(p_bonding_data != NULL);
+
+ pds_peer_data_iterate_prepare();
+
+ while (pds_peer_data_iterate(PM_PEER_DATA_ID_BONDING, &peer_id, &peer_data_duplicate))
+ {
+ if ( (peer_id != peer_id_skip)
+ && im_is_duplicate_bonding_data(p_bonding_data,
+ peer_data_duplicate.p_bonding_data))
+ {
+ return peer_id;
+ }
+ }
+ return PM_PEER_ID_INVALID;
+}
+
+
+ret_code_t im_init(void)
+{
+ NRF_PM_DEBUG_CHECK(!m_module_initialized);
+
+ internal_state_reset();
+
+ m_conn_state_user_flag_id = ble_conn_state_user_flag_acquire();
+ if (m_conn_state_user_flag_id == BLE_CONN_STATE_USER_FLAG_INVALID)
+ {
+ return NRF_ERROR_INTERNAL;
+ }
+
+ m_module_initialized = true;
+
+ return NRF_SUCCESS;
+}
+
+
+pm_peer_id_t im_peer_id_get_by_conn_handle(uint16_t conn_handle)
+{
+ uint8_t conn_index;
+
+ NRF_PM_DEBUG_CHECK(m_module_initialized);
+
+ conn_index = get_connection_by_conn_handle(conn_handle);
+
+ if (conn_index != IM_NO_INVALID_CONN_HANDLES)
+ {
+ return m_connections[conn_index].peer_id;
+ }
+
+ return PM_PEER_ID_INVALID;
+}
+
+
+ret_code_t im_ble_addr_get(uint16_t conn_handle, ble_gap_addr_t * p_ble_addr)
+{
+ uint8_t conn_index;
+
+ NRF_PM_DEBUG_CHECK(m_module_initialized);
+ NRF_PM_DEBUG_CHECK(p_ble_addr != NULL);
+
+ conn_index = get_connection_by_conn_handle(conn_handle);
+
+ if (conn_index != IM_NO_INVALID_CONN_HANDLES)
+ {
+ *p_ble_addr = m_connections[conn_index].peer_address;
+ return NRF_SUCCESS;
+ }
+
+ return NRF_ERROR_NOT_FOUND;
+}
+
+
+bool im_master_ids_compare(ble_gap_master_id_t const * p_master_id1,
+ ble_gap_master_id_t const * p_master_id2)
+{
+ NRF_PM_DEBUG_CHECK(m_module_initialized);
+ NRF_PM_DEBUG_CHECK(p_master_id1 != NULL);
+ NRF_PM_DEBUG_CHECK(p_master_id2 != NULL);
+
+ if (!im_master_id_is_valid(p_master_id1))
+ {
+ return false;
+ }
+
+ if (p_master_id1->ediv != p_master_id2->ediv)
+ {
+ return false;
+ }
+
+ return (memcmp(p_master_id1->rand, p_master_id2->rand, BLE_GAP_SEC_RAND_LEN) == 0);
+}
+
+
+pm_peer_id_t im_peer_id_get_by_master_id(ble_gap_master_id_t const * p_master_id)
+{
+ pm_peer_id_t peer_id;
+ pm_peer_data_flash_t peer_data;
+
+ NRF_PM_DEBUG_CHECK(m_module_initialized);
+ NRF_PM_DEBUG_CHECK(p_master_id != NULL);
+
+ pds_peer_data_iterate_prepare();
+
+ // For each stored peer, check if the master_id matches p_master_id
+ while (pds_peer_data_iterate(PM_PEER_DATA_ID_BONDING, &peer_id, &peer_data))
+ {
+ if (im_master_ids_compare(p_master_id, &peer_data.p_bonding_data->own_ltk.master_id) ||
+ im_master_ids_compare(p_master_id, &peer_data.p_bonding_data->peer_ltk.master_id))
+ {
+ // If a matching master ID is found then return the peer ID.
+ return peer_id;
+ }
+ }
+
+ // If no matching master ID is found return PM_PEER_ID_INVALID.
+ return PM_PEER_ID_INVALID;
+}
+
+
+uint16_t im_conn_handle_get(pm_peer_id_t peer_id)
+{
+ NRF_PM_DEBUG_CHECK(m_module_initialized);
+
+ for (uint32_t i = 0; i < IM_MAX_CONN_HANDLES; i++)
+ {
+ if (peer_id == m_connections[i].peer_id)
+ {
+ return m_connections[i].conn_handle;
+ }
+ }
+ return BLE_CONN_HANDLE_INVALID;
+}
+
+
+bool im_master_id_is_valid(ble_gap_master_id_t const * p_master_id)
+{
+ NRF_PM_DEBUG_CHECK(m_module_initialized);
+
+ if (p_master_id->ediv != 0)
+ {
+ return true;
+ }
+
+ for (uint32_t i = 0; i < BLE_GAP_SEC_RAND_LEN; i++)
+ {
+ if (p_master_id->rand[i] != 0)
+ {
+ return true;
+ }
+ }
+ return false;
+}
+
+
+/**@brief Function to set the peer ID associated with a connection handle.
+ *
+ * @param[in] conn_handle The connection handle.
+ * @param[in] peer_id The peer ID to associate with @c conn_handle.
+ */
+static void peer_id_set(uint16_t conn_handle, pm_peer_id_t peer_id)
+{
+ uint8_t conn_index = get_connection_by_conn_handle(conn_handle);
+ if (conn_index != IM_NO_INVALID_CONN_HANDLES)
+ {
+ m_connections[conn_index].peer_id = peer_id;
+ }
+}
+
+
+void im_new_peer_id(uint16_t conn_handle, pm_peer_id_t peer_id)
+{
+ NRF_PM_DEBUG_CHECK(m_module_initialized);
+
+ peer_id_set(conn_handle, peer_id);
+}
+
+
+ret_code_t im_peer_free(pm_peer_id_t peer_id)
+{
+ uint16_t conn_handle;
+ ret_code_t ret;
+
+ NRF_PM_DEBUG_CHECK(m_module_initialized);
+
+ conn_handle = im_conn_handle_get(peer_id);
+ ret = pdb_peer_free(peer_id);
+
+ if ((conn_handle != BLE_CONN_HANDLE_INVALID) && (ret == NRF_SUCCESS))
+ {
+ peer_id_set(conn_handle, PM_PEER_ID_INVALID);
+ }
+ return ret;
+}
+
+
+/**@brief Given a list of peers, loads their GAP address and IRK into the provided buffers.
+ */
+static ret_code_t peers_id_keys_get(pm_peer_id_t const * p_peers,
+ uint32_t peer_cnt,
+ ble_gap_addr_t * p_gap_addrs,
+ uint32_t * p_addr_cnt,
+ ble_gap_irk_t * p_gap_irks,
+ uint32_t * p_irk_cnt)
+{
+ ret_code_t ret;
+
+ pm_peer_data_bonding_t bond_data;
+ pm_peer_data_t peer_data;
+
+ uint32_t const buf_size = sizeof(bond_data);
+
+ bool copy_addrs = false;
+ bool copy_irks = false;
+
+ NRF_PM_DEBUG_CHECK(p_peers != NULL);
+
+ // One of these two has to be provided.
+ NRF_PM_DEBUG_CHECK((p_gap_addrs != NULL) || (p_gap_irks != NULL));
+
+ if ((p_gap_addrs != NULL) && (p_addr_cnt != NULL))
+ {
+ NRF_PM_DEBUG_CHECK((*p_addr_cnt) >= peer_cnt);
+
+ copy_addrs = true;
+ *p_addr_cnt = 0;
+ }
+
+ if ((p_gap_irks != NULL) && (p_irk_cnt != NULL))
+ {
+ NRF_PM_DEBUG_CHECK((*p_irk_cnt) >= peer_cnt);
+
+ copy_irks = true;
+ *p_irk_cnt = 0;
+ }
+
+ memset(&peer_data, 0x00, sizeof(peer_data));
+ peer_data.p_bonding_data = &bond_data;
+
+ // Read through flash memory and look for peers ID keys.
+
+ for (uint32_t i = 0; i < peer_cnt; i++)
+ {
+ memset(&bond_data, 0x00, sizeof(bond_data));
+
+ // Read peer data from flash.
+ ret = pds_peer_data_read(p_peers[i], PM_PEER_DATA_ID_BONDING,
+ &peer_data, &buf_size);
+
+ if ((ret == NRF_ERROR_NOT_FOUND) || (ret == NRF_ERROR_INVALID_PARAM))
+ {
+ // Peer data coulnd't be found in flash or peer ID is not valid.
+ return NRF_ERROR_NOT_FOUND;
+ }
+
+ uint8_t const addr_type = bond_data.peer_ble_id.id_addr_info.addr_type;
+
+ if ((addr_type != BLE_GAP_ADDR_TYPE_PUBLIC) &&
+ (addr_type != BLE_GAP_ADDR_TYPE_RANDOM_STATIC))
+ {
+ // The address shared by the peer during bonding can't be used for whitelisting.
+ return BLE_ERROR_GAP_INVALID_BLE_ADDR;
+ }
+
+ // Copy the GAP address.
+ if (copy_addrs)
+ {
+ memcpy(&p_gap_addrs[i], &bond_data.peer_ble_id.id_addr_info, sizeof(ble_gap_addr_t));
+ (*p_addr_cnt)++;
+ }
+
+ // Copy the IRK.
+ if (copy_irks)
+ {
+ memcpy(&p_gap_irks[i], bond_data.peer_ble_id.id_info.irk, BLE_GAP_SEC_KEY_LEN);
+ (*p_irk_cnt)++;
+ }
+ }
+
+ return NRF_SUCCESS;
+}
+
+
+ret_code_t im_device_identities_list_set(pm_peer_id_t const * p_peers,
+ uint32_t peer_cnt)
+{
+ ret_code_t ret;
+ pm_peer_data_t peer_data;
+ pm_peer_data_bonding_t bond_data;
+
+ ble_gap_id_key_t keys[BLE_GAP_DEVICE_IDENTITIES_MAX_COUNT];
+ ble_gap_id_key_t const * key_ptrs[BLE_GAP_DEVICE_IDENTITIES_MAX_COUNT];
+
+ if ((p_peers == NULL) || (peer_cnt == 0))
+ {
+ // Clear the device identities list.
+ return sd_ble_gap_device_identities_set(NULL, NULL, 0);
+ }
+
+ peer_data.p_bonding_data = &bond_data;
+ uint32_t const buf_size = sizeof(bond_data);
+
+ memset(keys, 0x00, sizeof(keys));
+ for (uint32_t i = 0; i < BLE_GAP_DEVICE_IDENTITIES_MAX_COUNT; i++)
+ {
+ key_ptrs[i] = &keys[i];
+ }
+
+ for (uint32_t i = 0; i < peer_cnt; i++)
+ {
+ memset(&bond_data, 0x00, sizeof(bond_data));
+
+ // Read peer data from flash.
+ ret = pds_peer_data_read(p_peers[i], PM_PEER_DATA_ID_BONDING,
+ &peer_data, &buf_size);
+
+ if ((ret == NRF_ERROR_NOT_FOUND) || (ret == NRF_ERROR_INVALID_PARAM))
+ {
+ // Peer data coulnd't be found in flash or peer ID is not valid.
+ return NRF_ERROR_NOT_FOUND;
+ }
+
+ uint8_t const addr_type = bond_data.peer_ble_id.id_addr_info.addr_type;
+
+ if ((addr_type != BLE_GAP_ADDR_TYPE_PUBLIC) &&
+ (addr_type != BLE_GAP_ADDR_TYPE_RANDOM_STATIC))
+ {
+ // The address shared by the peer during bonding can't be whitelisted.
+ return BLE_ERROR_GAP_INVALID_BLE_ADDR;
+ }
+
+ // Copy data to the buffer.
+ memcpy(&keys[i], &bond_data.peer_ble_id, sizeof(ble_gap_id_key_t));
+ }
+
+ return sd_ble_gap_device_identities_set(key_ptrs, NULL, peer_cnt);
+}
+
+
+ret_code_t im_id_addr_set(ble_gap_addr_t const * p_addr)
+{
+ return sd_ble_gap_addr_set(p_addr);
+}
+
+
+ret_code_t im_id_addr_get(ble_gap_addr_t * p_addr)
+{
+ NRF_PM_DEBUG_CHECK(p_addr != NULL);
+
+ return sd_ble_gap_addr_get(p_addr);
+}
+
+
+ret_code_t im_privacy_set(pm_privacy_params_t const * p_privacy_params)
+{
+ return sd_ble_gap_privacy_set(p_privacy_params);
+}
+
+
+ret_code_t im_privacy_get(pm_privacy_params_t * p_privacy_params)
+{
+ return sd_ble_gap_privacy_get(p_privacy_params);
+}
+
+
+/* Create a whitelist for the user using the cached list of peers.
+ * This whitelist is meant to be provided by the application to the Advertising module.
+ */
+ret_code_t im_whitelist_get(ble_gap_addr_t * p_addrs,
+ uint32_t * p_addr_cnt,
+ ble_gap_irk_t * p_irks,
+ uint32_t * p_irk_cnt)
+{
+ // One of the two buffers has to be provided.
+ NRF_PM_DEBUG_CHECK((p_addrs != NULL) || (p_irks != NULL));
+ NRF_PM_DEBUG_CHECK((p_addr_cnt != NULL) || (p_irk_cnt != NULL));
+
+ if (((p_addr_cnt != NULL) && (m_wlisted_peer_cnt > *p_addr_cnt)) ||
+ ((p_irk_cnt != NULL) && (m_wlisted_peer_cnt > *p_irk_cnt)))
+ {
+ // The size of the cached list of peers is larger than the provided buffers.
+ return NRF_ERROR_NO_MEM;
+ }
+
+ // NRF_SUCCESS or
+ // NRF_ERROR_NOT_FOUND, if a peer or its data were not found.
+ // BLE_ERROR_GAP_INVALID_BLE_ADDR, if a peer address can not be used for whitelisting.
+ return peers_id_keys_get(m_wlisted_peers, m_wlisted_peer_cnt,
+ p_addrs, p_addr_cnt,
+ p_irks, p_irk_cnt);
+}
+
+
+/* Copies the peers to whitelist into a local cache.
+ * The cached list will be used by im_whitelist_get() to retrieve the active whitelist.
+ * For SoftDevices 3x, also loads the peers' GAP addresses and whitelists them using
+ * sd_ble_gap_whitelist_set().
+ */
+ret_code_t im_whitelist_set(pm_peer_id_t const * p_peers,
+ uint32_t peer_cnt)
+{
+ // Clear the cache of whitelisted peers.
+ memset(m_wlisted_peers, 0x00, sizeof(m_wlisted_peers));
+
+ if ((p_peers == NULL) || (peer_cnt == 0))
+ {
+ // Clear the current whitelist.
+ m_wlisted_peer_cnt = 0;
+
+ // NRF_SUCCESS, or
+ // BLE_GAP_ERROR_WHITELIST_IN_USE
+ return sd_ble_gap_whitelist_set(NULL, 0);
+ }
+
+ // @todo emdi: should not ever cache more than BLE_GAP_WHITELIST_ADDR_MAX_COUNT...
+
+ // Copy the new whitelisted peers.
+ m_wlisted_peer_cnt = peer_cnt;
+ memcpy(m_wlisted_peers, p_peers, sizeof(pm_peer_id_t) * peer_cnt);
+
+ ret_code_t ret;
+ uint32_t wlist_addr_cnt = 0;
+
+ ble_gap_addr_t const * addr_ptrs[BLE_GAP_WHITELIST_ADDR_MAX_COUNT];
+ ble_gap_addr_t addrs[BLE_GAP_WHITELIST_ADDR_MAX_COUNT];
+
+ memset(addrs, 0x00, sizeof(addrs));
+
+ // Fetch GAP addresses for these peers, but don't fetch IRKs.
+ ret = peers_id_keys_get(p_peers, peer_cnt, addrs, &wlist_addr_cnt, NULL, NULL);
+
+ if (ret != NRF_SUCCESS)
+ {
+ // NRF_ERROR_NOT_FOUND, if a peer or its data were not found.
+ // BLE_ERROR_GAP_INVALID_BLE_ADDR, if a peer address can not be used for whitelisting.
+ return ret;
+ }
+
+ for (uint32_t i = 0; i < BLE_GAP_WHITELIST_ADDR_MAX_COUNT; i++)
+ {
+ addr_ptrs[i] = &addrs[i];
+ }
+
+ // NRF_ERROR_DATA_SIZE, if peer_cnt > BLE_GAP_WHITELIST_ADDR_MAX_COUNT.
+ // BLE_ERROR_GAP_WHITELIST_IN_USE, if a whitelist is in use.
+ return sd_ble_gap_whitelist_set(addr_ptrs, peer_cnt);
+}
+
+
+/**@brief Function for calculating the ah() hash function described in Bluetooth core specification
+ * 4.2 section 3.H.2.2.2.
+ *
+ * @detail BLE uses a hash function to calculate the first half of a resolvable address
+ * from the second half of the address and an irk. This function will use the ECB
+ * periferal to hash these data acording to the Bluetooth core specification.
+ *
+ * @note The ECB expect little endian input and output.
+ * This function expect big endian and will reverse the data as necessary.
+ *
+ * @param[in] p_k The key used in the hash function.
+ * For address resolution this is should be the irk.
+ * The array must have a length of 16.
+ * @param[in] p_r The rand used in the hash function. For generating a new address
+ * this would be a random number. For resolving a resolvable address
+ * this would be the last half of the address being resolved.
+ * The array must have a length of 3.
+ * @param[out] p_local_hash The result of the hash operation. For address resolution this
+ * will match the first half of the address being resolved if and only
+ * if the irk used in the hash function is the same one used to generate
+ * the address.
+ * The array must have a length of 16.
+ */
+void ah(uint8_t const * p_k, uint8_t const * p_r, uint8_t * p_local_hash)
+{
+ nrf_ecb_hal_data_t ecb_hal_data;
+
+ for (uint32_t i = 0; i < SOC_ECB_KEY_LENGTH; i++)
+ {
+ ecb_hal_data.key[i] = p_k[SOC_ECB_KEY_LENGTH - 1 - i];
+ }
+
+ memset(ecb_hal_data.cleartext, 0, SOC_ECB_KEY_LENGTH - IM_ADDR_CLEARTEXT_LENGTH);
+
+ for (uint32_t i = 0; i < IM_ADDR_CLEARTEXT_LENGTH; i++)
+ {
+ ecb_hal_data.cleartext[SOC_ECB_KEY_LENGTH - 1 - i] = p_r[i];
+ }
+
+ // Can only return NRF_SUCCESS.
+ (void) sd_ecb_block_encrypt(&ecb_hal_data);
+
+ for (uint32_t i = 0; i < IM_ADDR_CIPHERTEXT_LENGTH; i++)
+ {
+ p_local_hash[i] = ecb_hal_data.ciphertext[SOC_ECB_KEY_LENGTH - 1 - i];
+ }
+}
+
+
+bool im_address_resolve(ble_gap_addr_t const * p_addr, ble_gap_irk_t const * p_irk)
+{
+ NRF_PM_DEBUG_CHECK(m_module_initialized);
+
+ uint8_t hash[IM_ADDR_CIPHERTEXT_LENGTH];
+ uint8_t local_hash[IM_ADDR_CIPHERTEXT_LENGTH];
+ uint8_t prand[IM_ADDR_CLEARTEXT_LENGTH];
+
+ if (p_addr->addr_type != BLE_GAP_ADDR_TYPE_RANDOM_PRIVATE_RESOLVABLE)
+ {
+ return false;
+ }
+
+ memcpy(hash, p_addr->addr, IM_ADDR_CIPHERTEXT_LENGTH);
+ memcpy(prand, &p_addr->addr[IM_ADDR_CIPHERTEXT_LENGTH], IM_ADDR_CLEARTEXT_LENGTH);
+ ah(p_irk->irk, prand, local_hash);
+
+ return (memcmp(hash, local_hash, IM_ADDR_CIPHERTEXT_LENGTH) == 0);
+}
+#endif // NRF_MODULE_ENABLED(PEER_MANAGER)
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/peer_manager/id_manager.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/peer_manager/id_manager.h
new file mode 100644
index 0000000..fc73958
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/peer_manager/id_manager.h
@@ -0,0 +1,327 @@
+/**
+ * Copyright (c) 2015 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#ifndef PEER_ID_MANAGER_H__
+#define PEER_ID_MANAGER_H__
+
+#include <stdint.h>
+#include "sdk_errors.h"
+#include "ble.h"
+#include "ble_gap.h"
+#include "peer_manager_types.h"
+#include "peer_manager_internal.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+/**
+ * @cond NO_DOXYGEN
+ * @defgroup id_manager ID Manager
+ * @ingroup peer_manager
+ * @{
+ * @brief An internal module of @ref peer_manager. A module for keeping track of peer identities
+ * (IRK and peer address).
+ */
+
+
+/**@brief Function for initializing the Identity manager.
+ *
+ * @retval NRF_SUCCESS If initialization was successful.
+ * @retval NRF_ERROR_INTERNAL If an error occurred.
+ */
+ret_code_t im_init(void);
+
+
+/**@brief Function for dispatching SoftDevice events to the ID Manager module.
+ *
+ * @param[in] p_ble_evt The SoftDevice event.
+ */
+void im_ble_evt_handler(ble_evt_t const * p_ble_evt);
+
+
+/**@brief Function for getting the corresponding peer ID from a connection handle.
+ *
+ * @param[in] conn_handle The connection handle.
+ *
+ * @return The corresponding peer ID, or @ref PM_PEER_ID_INVALID if none could be resolved.
+ */
+pm_peer_id_t im_peer_id_get_by_conn_handle(uint16_t conn_handle);
+
+
+/**@brief Function for getting the corresponding peer ID from a master ID (EDIV and rand).
+ *
+ * @param[in] p_master_id The master ID.
+ *
+ * @return The corresponding peer ID, or @ref PM_PEER_ID_INVALID if none could be resolved.
+ */
+pm_peer_id_t im_peer_id_get_by_master_id(ble_gap_master_id_t const * p_master_id);
+
+
+/**@brief Function for getting the corresponding connection handle from a peer ID.
+ *
+ * @param[in] peer_id The peer ID.
+ *
+ * @return The corresponding connection handle, or @ref BLE_CONN_HANDLE_INVALID if none could be
+ * resolved.
+ */
+uint16_t im_conn_handle_get(pm_peer_id_t peer_id);
+
+
+/**@brief Function for comparing two master ids
+ * @note Two invalid master IDs will not match.
+ *
+ * @param[in] p_master_id1 First master id for comparison
+ * @param[in] p_master_id2 Second master id for comparison
+ *
+ * @return True if the input matches, false if it does not.
+ */
+bool im_master_ids_compare(ble_gap_master_id_t const * p_master_id1,
+ ble_gap_master_id_t const * p_master_id2);
+
+
+/**@brief Function for getting the BLE address used by the peer when connecting.
+ *
+ * @param[in] conn_handle The connection handle.
+ * @param[out] p_ble_addr The BLE address used by the peer when the connection specified by
+ * conn_handle was established.
+ *
+ * @retval NRF_SUCCESS The address was found and copied.
+ * @retval BLE_ERROR_CONN_HANDLE_INVALID conn_handle does not refer to an active connection.
+ * @retval NRF_ERROR_NULL p_ble_addr was NULL.
+ */
+ret_code_t im_ble_addr_get(uint16_t conn_handle, ble_gap_addr_t * p_ble_addr);
+
+
+/**@brief Function for checking if a master ID is valid or invalid
+ *
+ * @param[in] p_master_id The master ID.
+ *
+ * @retval true The master id is valid.
+ * @retval false The master id is invalid (i.e. all zeros).
+ */
+bool im_master_id_is_valid(ble_gap_master_id_t const * p_master_id);
+
+
+/**@brief Function for checking if two pieces of bonding data correspond to the same peer.
+ *
+ * @param[in] p_bonding_data1 The first piece of bonding data to check.
+ * @param[in] p_bonding_data2 The second piece of bonding data to check.
+ *
+ * @retval true The bonding data correspond to the same peer.
+ * @retval false The bonding data do not correspond to the same peer.
+ */
+bool im_is_duplicate_bonding_data(pm_peer_data_bonding_t const * p_bonding_data1,
+ pm_peer_data_bonding_t const * p_bonding_data2);
+
+
+/**@brief Function for finding if we are already bonded to a peer.
+ *
+ * @param[in] p_bonding_data The bonding data to check.
+ * @param[in] peer_id_skip Optional peer to ignore when searching for duplicates.
+ *
+ * @return An existing peer ID for the peer, or PM_PEER_ID_INVALID if none was found.
+ */
+pm_peer_id_t im_find_duplicate_bonding_data(pm_peer_data_bonding_t const * p_bonding_data,
+ pm_peer_id_t peer_id_skip);
+
+
+/**@brief Function for reporting that a new peer ID has been allocated for a specified connection.
+ *
+ * @param[in] conn_handle The connection.
+ * @param[in] peer_id The new peer ID.
+ */
+void im_new_peer_id(uint16_t conn_handle, pm_peer_id_t peer_id);
+
+
+/**@brief Function for deleting all of a peer's data from flash and disassociating it from any
+ * connection handles it is associated with.
+ *
+ * @param[in] peer_id The peer to free.
+ *
+ * @return Any error code returned by @ref pdb_peer_free.
+ */
+ret_code_t im_peer_free(pm_peer_id_t peer_id);
+
+
+/**@brief Function to set the local Bluetooth identity address.
+ *
+ * @details The local Bluetooth identity address is the address that identifies this device to other
+ * peers. The address type must be either @ref BLE_GAP_ADDR_TYPE_PUBLIC or @ref
+ * BLE_GAP_ADDR_TYPE_RANDOM_STATIC. The identity address cannot be changed while roles are
+ * running.
+ *
+ * @note This address will be distributed to the peer during bonding.
+ * If the address changes, the address stored in the peer device will not be valid and the
+ * ability to reconnect using the old address will be lost.
+ *
+ * @note By default the SoftDevice will set an address of type @ref BLE_GAP_ADDR_TYPE_RANDOM_STATIC
+ * upon being enabled. The address is a random number populated during the IC manufacturing
+ * process and remains unchanged for the lifetime of each IC.
+ *
+ * @param[in] p_addr Pointer to address structure.
+ *
+ * @retval NRF_SUCCESS Address successfully set.
+ * @retval BLE_ERROR_GAP_INVALID_BLE_ADDR If the GAP address is invalid.
+ * @retval NRF_ERROR_BUSY Could not process at this time. Process SoftDevice events
+ * and retry.
+ * @retval NRF_ERROR_INVALID_STATE The identity address cannot be changed while advertising,
+ * scanning, or while in a connection.
+ * @retval NRF_ERROR_INTERNAL If an internal error occurred.
+ */
+ret_code_t im_id_addr_set(ble_gap_addr_t const * p_addr);
+
+
+/**@brief Function to get the local Bluetooth identity address.
+ *
+ * @note This will always return the identity address irrespective of the privacy settings,
+ * i.e. the address type will always be either @ref BLE_GAP_ADDR_TYPE_PUBLIC or @ref
+ * BLE_GAP_ADDR_TYPE_RANDOM_STATIC.
+ *
+ * @param[out] p_addr Pointer to address structure to be filled in.
+ *
+ * @retval NRF_SUCCESS If the address was successfully retrieved.
+ */
+ret_code_t im_id_addr_get(ble_gap_addr_t * p_addr);
+
+
+/**@brief Function to set privacy settings.
+ *
+ * @details Privacy settings cannot be set while advertising, scanning, or while in a connection.
+ *
+ * @param[in] p_privacy_params Privacy settings.
+ *
+ * @retval NRF_SUCCESS If privacy options were set successfully.
+ * @retval NRF_ERROR_NULL If @p p_privacy_params is NULL.
+ * @retval NRF_ERROR_INVALID_PARAM If the address type is not valid.
+ * @retval NRF_ERROR_BUSY If the request could not be processed at this time.
+ * Process SoftDevice events and retry.
+ * @retval NRF_ERROR_INVALID_STATE Privacy settings cannot be changed while BLE roles using
+ * privacy are enabled.
+ */
+ret_code_t im_privacy_set(pm_privacy_params_t const * p_privacy_params);
+
+
+/**@brief Function to retrieve the current privacy settings.
+ *
+ * @details The privacy settings returned include the current device irk as well.
+ *
+ * @param[in] p_privacy_params Privacy settings.
+ *
+ * @retval NRF_SUCCESS Successfully retrieved privacy settings.
+ * @retval NRF_ERROR_NULL @c p_privacy_params is NULL.
+ * @retval NRF_ERROR_INTERNAL If an internal error occurred.
+ */
+ret_code_t im_privacy_get(pm_privacy_params_t * p_privacy_params);
+
+
+/**@brief Function for resolving a resolvable address with an identity resolution key (IRK).
+ *
+ * @details This function will use the ECB peripheral to resolve a resolvable address.
+ * This can be used to resolve the identity of a device distributing a random
+ * resolvable address based on any IRKs you have received earlier. If an address is
+ * resolved by an IRK, the device distributing the address must also know the IRK.
+ *
+ * @param[in] p_addr A random resolvable address.
+ * @param[in] p_irk An identity resolution key (IRK).
+ *
+ * @retval true The irk used matched the one used to create the address.
+ * @retval false The irk used did not match the one used to create the address, or an argument was
+ * NULL.
+ */
+bool im_address_resolve(ble_gap_addr_t const * p_addr, ble_gap_irk_t const * p_irk);
+
+
+/**@brief Function for setting / clearing the whitelist.
+ *
+ * @param p_peers The peers to whitelist. Pass NULL to clear the whitelist.
+ * @param peer_cnt The number of peers to whitelist. Pass zero to clear the whitelist.
+ *
+ * @retval NRF_SUCCESS If the whitelist was successfully set or cleared.
+ * @retval BLE_GAP_ERROR_WHITELIST_IN_USE If a whitelist is in use.
+ * @retval BLE_ERROR_GAP_INVALID_BLE_ADDR If any peer has an address which can not be used
+ * for whitelisting.
+ * @retval NRF_ERROR_NOT_FOUND If any peer or its data could not be found.
+ * @retval NRF_ERROR_DATA_SIZE If @p peer_cnt is greater than
+ * @ref BLE_GAP_WHITELIST_ADDR_MAX_COUNT.
+ */
+ret_code_t im_whitelist_set(pm_peer_id_t const * p_peers,
+ uint32_t const peer_cnt);
+
+
+/**@brief Retrieves the current whitelist, set by a previous call to @ref im_whitelist_set.
+ *
+ * @param[out] A buffer where to copy the GAP addresses.
+ * @param[inout] In: the size of the @p p_addrs buffer.
+ * Out: the number of address copied into the buffer.
+ * @param[out] A buffer where to copy the IRKs.
+ * @param[inout] In: the size of the @p p_irks buffer.
+ * Out: the number of IRKs copied into the buffer.
+ *
+ * @retval NRF_SUCCESS If the whitelist was successfully retreived.
+ * @retval BLE_ERROR_GAP_INVALID_BLE_ADDR If any peer has an address which can not be used for
+ * whitelisting.
+ * @retval NRF_ERROR_NOT_FOUND If the data for any of the cached whitelisted peers
+ * can not be found anymore. It might have been deleted in
+ * the meanwhile.
+ * @retval NRF_ERROR_NO_MEM If the provided buffers are too small.
+ */
+ret_code_t im_whitelist_get(ble_gap_addr_t * p_addrs,
+ uint32_t * p_addr_cnt,
+ ble_gap_irk_t * p_irks,
+ uint32_t * p_irk_cnt);
+
+
+/**@brief Set the device identities list.
+ */
+ret_code_t im_device_identities_list_set(pm_peer_id_t const * p_peers,
+ uint32_t peer_cnt);
+
+
+/** @}
+ * @endcond
+ */
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* PEER_ID_MANAGER_H__ */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/peer_manager/peer_data_storage.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/peer_manager/peer_data_storage.c
new file mode 100644
index 0000000..12058d7
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/peer_manager/peer_data_storage.c
@@ -0,0 +1,678 @@
+/**
+ * Copyright (c) 2015 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#include "sdk_common.h"
+#if NRF_MODULE_ENABLED(PEER_MANAGER)
+#include "peer_data_storage.h"
+
+#include <stdint.h>
+#include <string.h>
+#include "sdk_errors.h"
+#include "peer_manager_types.h"
+#include "peer_manager_internal.h"
+#include "peer_id.h"
+#include "fds.h"
+
+
+// Macro for verifying that the peer id is within a valid range.
+#define VERIFY_PEER_ID_IN_RANGE(id) VERIFY_FALSE((id >= PM_PEER_ID_N_AVAILABLE_IDS), \
+ NRF_ERROR_INVALID_PARAM)
+
+// Macro for verifying that the peer data id is withing a valid range.
+#define VERIFY_PEER_DATA_ID_IN_RANGE(id) VERIFY_TRUE(peer_data_id_is_valid(id), \
+ NRF_ERROR_INVALID_PARAM)
+
+// The number of registered event handlers.
+#define PDS_EVENT_HANDLERS_CNT (sizeof(m_evt_handlers) / sizeof(m_evt_handlers[0]))
+
+
+// Peer Data Storage event handler in Peer Database.
+extern void pdb_pds_evt_handler(pm_evt_t *);
+
+// Peer Data Storage events' handlers.
+// The number of elements in this array is PDS_EVENT_HANDLERS_CNT.
+static pm_evt_handler_internal_t const m_evt_handlers[] =
+{
+ pdb_pds_evt_handler,
+};
+
+static bool m_module_initialized = false;
+static volatile bool m_peer_delete_deferred = false;
+
+// A token used for Flash Data Storage searches.
+static fds_find_token_t m_fds_ftok;
+
+
+// Function for dispatching events to all registered event handlers.
+static void pds_evt_send(pm_evt_t * p_event)
+{
+ p_event->conn_handle = BLE_CONN_HANDLE_INVALID;
+
+ for (uint32_t i = 0; i < PDS_EVENT_HANDLERS_CNT; i++)
+ {
+ m_evt_handlers[i](p_event);
+ }
+}
+
+
+// Function to convert peer IDs to file IDs.
+static uint16_t peer_id_to_file_id(pm_peer_id_t peer_id)
+{
+ return (uint16_t)(peer_id + PEER_ID_TO_FILE_ID);
+}
+
+
+// Function to convert peer data id to type id.
+static pm_peer_id_t file_id_to_peer_id(uint16_t file_id)
+{
+ return (pm_peer_id_t)(file_id + FILE_ID_TO_PEER_ID);
+}
+
+
+// Function to convert peer data IDs to record keys.
+static uint16_t peer_data_id_to_record_key(pm_peer_data_id_t peer_data_id)
+{
+ return (uint16_t)(peer_data_id + DATA_ID_TO_RECORD_KEY);
+}
+
+
+// Function to convert record keys to peer data IDs.
+static pm_peer_data_id_t record_key_to_peer_data_id(uint16_t record_key)
+{
+ return (pm_peer_data_id_t)(record_key + RECORD_KEY_TO_DATA_ID);
+}
+
+
+// Function for checking whether a file ID is relevant for the Peer Manager.
+static bool file_id_within_pm_range(uint16_t file_id)
+{
+ return ((PDS_FIRST_RESERVED_FILE_ID <= file_id)
+ && (file_id <= PDS_LAST_RESERVED_FILE_ID));
+}
+
+
+// Function for checking whether a record key is relevant for the Peer Manager.
+static bool record_key_within_pm_range(uint16_t record_key)
+{
+ return ((PDS_FIRST_RESERVED_RECORD_KEY <= record_key)
+ && (record_key <= PDS_LAST_RESERVED_RECORD_KEY));
+}
+
+
+static bool peer_data_id_is_valid(pm_peer_data_id_t data_id)
+{
+ return ((data_id == PM_PEER_DATA_ID_BONDING) ||
+ (data_id == PM_PEER_DATA_ID_SERVICE_CHANGED_PENDING) ||
+ (data_id == PM_PEER_DATA_ID_GATT_LOCAL) ||
+ (data_id == PM_PEER_DATA_ID_GATT_REMOTE) ||
+ (data_id == PM_PEER_DATA_ID_PEER_RANK) ||
+ (data_id == PM_PEER_DATA_ID_APPLICATION));
+}
+
+
+/**@brief Function for sending a PM_EVT_ERROR_UNEXPECTED event.
+ *
+ * @param[in] peer_id The peer the event pertains to.
+ * @param[in] err_code The unexpected error that occurred.
+ */
+static void send_unexpected_error(pm_peer_id_t peer_id, ret_code_t err_code)
+{
+ pm_evt_t error_evt =
+ {
+ .evt_id = PM_EVT_ERROR_UNEXPECTED,
+ .peer_id = peer_id,
+ .params =
+ {
+ .error_unexpected =
+ {
+ .error = err_code,
+ }
+ }
+ };
+ pds_evt_send(&error_evt);
+}
+
+
+// Function for deleting all data beloning to a peer.
+// These operations will be sent to FDS one at a time.
+static void peer_data_delete_process()
+{
+ ret_code_t ret;
+ pm_peer_id_t peer_id;
+ uint16_t file_id;
+ fds_record_desc_t desc;
+ fds_find_token_t ftok;
+
+ m_peer_delete_deferred = false;
+
+ memset(&ftok, 0x00, sizeof(fds_find_token_t));
+ peer_id = peer_id_get_next_deleted(PM_PEER_ID_INVALID);
+
+ while ( (peer_id != PM_PEER_ID_INVALID)
+ && (fds_record_find_in_file(peer_id_to_file_id(peer_id), &desc, &ftok)
+ == FDS_ERR_NOT_FOUND))
+ {
+ peer_id_free(peer_id);
+ peer_id = peer_id_get_next_deleted(peer_id);
+ }
+
+ if (peer_id != PM_PEER_ID_INVALID)
+ {
+ file_id = peer_id_to_file_id(peer_id);
+ ret = fds_file_delete(file_id);
+
+ if (ret == FDS_ERR_NO_SPACE_IN_QUEUES)
+ {
+ m_peer_delete_deferred = true;
+ }
+ else if (ret != FDS_SUCCESS)
+ {
+ send_unexpected_error(peer_id, ret);
+ }
+ }
+}
+
+
+static ret_code_t peer_data_find(pm_peer_id_t peer_id,
+ pm_peer_data_id_t data_id,
+ fds_record_desc_t * const p_desc)
+{
+ ret_code_t ret;
+ fds_find_token_t ftok;
+
+ NRF_PM_DEBUG_CHECK(peer_id < PM_PEER_ID_N_AVAILABLE_IDS);
+ NRF_PM_DEBUG_CHECK(peer_data_id_is_valid(data_id));
+ NRF_PM_DEBUG_CHECK(p_desc != NULL);
+
+ memset(&ftok, 0x00, sizeof(fds_find_token_t));
+
+ uint16_t file_id = peer_id_to_file_id(peer_id);
+ uint16_t record_key = peer_data_id_to_record_key(data_id);
+
+ ret = fds_record_find(file_id, record_key, p_desc, &ftok);
+
+ if (ret != FDS_SUCCESS)
+ {
+ return NRF_ERROR_NOT_FOUND;
+ }
+
+ return NRF_SUCCESS;
+}
+
+
+static void peer_ids_load()
+{
+ fds_record_desc_t record_desc;
+ fds_flash_record_t record;
+ fds_find_token_t ftok;
+
+ memset(&ftok, 0x00, sizeof(fds_find_token_t));
+
+ uint16_t const record_key = peer_data_id_to_record_key(PM_PEER_DATA_ID_BONDING);
+
+ while (fds_record_find_by_key(record_key, &record_desc, &ftok) == FDS_SUCCESS)
+ {
+ pm_peer_id_t peer_id;
+
+ // It is safe to ignore the return value since the descriptor was
+ // just obtained and also 'record' is different from NULL.
+ (void)fds_record_open(&record_desc, &record);
+ peer_id = file_id_to_peer_id(record.p_header->file_id);
+ (void)fds_record_close(&record_desc);
+
+ (void)peer_id_allocate(peer_id);
+ }
+}
+
+
+static void fds_evt_handler(fds_evt_t const * const p_fds_evt)
+{
+ pm_evt_t pds_evt =
+ {
+ .peer_id = file_id_to_peer_id(p_fds_evt->write.file_id)
+ };
+
+ switch (p_fds_evt->id)
+ {
+ case FDS_EVT_WRITE:
+ case FDS_EVT_UPDATE:
+ case FDS_EVT_DEL_RECORD:
+ if ( file_id_within_pm_range(p_fds_evt->write.file_id)
+ || record_key_within_pm_range(p_fds_evt->write.record_key))
+ {
+ pds_evt.params.peer_data_update_succeeded.data_id
+ = record_key_to_peer_data_id(p_fds_evt->write.record_key);
+ pds_evt.params.peer_data_update_succeeded.action
+ = (p_fds_evt->id == FDS_EVT_DEL_RECORD) ? PM_PEER_DATA_OP_DELETE
+ : PM_PEER_DATA_OP_UPDATE;
+ pds_evt.params.peer_data_update_succeeded.token = p_fds_evt->write.record_id;
+
+ if (p_fds_evt->result == FDS_SUCCESS)
+ {
+ pds_evt.evt_id = PM_EVT_PEER_DATA_UPDATE_SUCCEEDED;
+ pds_evt.params.peer_data_update_succeeded.flash_changed = true;
+ }
+ else
+ {
+ pds_evt.evt_id = PM_EVT_PEER_DATA_UPDATE_FAILED;
+ pds_evt.params.peer_data_update_failed.error = p_fds_evt->result;
+ }
+
+ pds_evt_send(&pds_evt);
+ }
+ break;
+
+ case FDS_EVT_DEL_FILE:
+ if ( file_id_within_pm_range(p_fds_evt->del.file_id)
+ && (p_fds_evt->del.record_key == FDS_RECORD_KEY_DIRTY))
+ {
+ if (p_fds_evt->result == FDS_SUCCESS)
+ {
+ pds_evt.evt_id = PM_EVT_PEER_DELETE_SUCCEEDED;
+ peer_id_free(pds_evt.peer_id);
+ }
+ else
+ {
+ pds_evt.evt_id = PM_EVT_PEER_DELETE_FAILED;
+ }
+
+ m_peer_delete_deferred = true; // Trigger remaining deletes.
+
+ pds_evt_send(&pds_evt);
+ }
+ break;
+
+ case FDS_EVT_GC:
+ pds_evt.evt_id = PM_EVT_FLASH_GARBAGE_COLLECTED;
+ pds_evt.peer_id = PM_PEER_ID_INVALID;
+
+ pds_evt_send(&pds_evt);
+ break;
+
+ default:
+ // No action.
+ break;
+ }
+
+ if (m_peer_delete_deferred)
+ {
+ peer_data_delete_process();
+ }
+}
+
+
+ret_code_t pds_init()
+{
+ ret_code_t ret;
+
+ // Check for re-initialization if debugging.
+ NRF_PM_DEBUG_CHECK(!m_module_initialized);
+
+ ret = fds_register(fds_evt_handler);
+ if (ret != NRF_SUCCESS)
+ {
+ return NRF_ERROR_INTERNAL;
+ }
+
+ ret = fds_init();
+ if (ret != NRF_SUCCESS)
+ {
+ return NRF_ERROR_STORAGE_FULL;
+ }
+
+ peer_id_init();
+ peer_ids_load();
+
+ m_module_initialized = true;
+
+ return NRF_SUCCESS;
+}
+
+
+ret_code_t pds_peer_data_read(pm_peer_id_t peer_id,
+ pm_peer_data_id_t data_id,
+ pm_peer_data_t * const p_data,
+ uint32_t const * const p_buf_len)
+{
+ ret_code_t ret;
+ fds_record_desc_t rec_desc;
+ fds_flash_record_t rec_flash;
+
+ NRF_PM_DEBUG_CHECK(m_module_initialized);
+ NRF_PM_DEBUG_CHECK(p_data != NULL);
+
+ VERIFY_PEER_ID_IN_RANGE(peer_id);
+ VERIFY_PEER_DATA_ID_IN_RANGE(data_id);
+
+ ret = peer_data_find(peer_id, data_id, &rec_desc);
+
+ if (ret != NRF_SUCCESS)
+ {
+ return NRF_ERROR_NOT_FOUND;
+ }
+
+ // Shouldn't fail, unless the record was deleted in the meanwhile or the CRC check has failed.
+ ret = fds_record_open(&rec_desc, &rec_flash);
+
+ if (ret != NRF_SUCCESS)
+ {
+ return NRF_ERROR_NOT_FOUND;
+ }
+
+ p_data->data_id = data_id;
+ p_data->length_words = rec_flash.p_header->length_words;
+
+ // If p_buf_len is NULL, provide a pointer to data in flash, otherwise,
+ // check that the buffer is large enough and copy the data in flash into the buffer.
+ if (p_buf_len == NULL)
+ {
+ // The cast is necessary because if no buffer is provided, we just copy the pointer,
+ // but in that case it should be considered a pointer to const data by the caller,
+ // since it is a pointer to data in flash.
+ p_data->p_all_data = (void*)rec_flash.p_data;
+ }
+ else
+ {
+ uint32_t const data_len_bytes = (p_data->length_words * sizeof(uint32_t));
+
+ if ((*p_buf_len) >= data_len_bytes)
+ {
+ memcpy(p_data->p_all_data, rec_flash.p_data, data_len_bytes);
+ }
+ else
+ {
+ return NRF_ERROR_NO_MEM;
+ }
+ }
+
+ // Shouldn't fail unless the record was already closed, in which case it can be ignored.
+ (void)fds_record_close(&rec_desc);
+
+ return NRF_SUCCESS;
+}
+
+
+void pds_peer_data_iterate_prepare(void)
+{
+ memset(&m_fds_ftok, 0x00, sizeof(fds_find_token_t));
+}
+
+
+bool pds_peer_data_iterate(pm_peer_data_id_t data_id,
+ pm_peer_id_t * const p_peer_id,
+ pm_peer_data_flash_t * const p_data)
+{
+ ret_code_t ret;
+ uint16_t rec_key;
+ fds_record_desc_t rec_desc;
+ fds_flash_record_t rec_flash;
+
+ NRF_PM_DEBUG_CHECK(m_module_initialized);
+ NRF_PM_DEBUG_CHECK(p_peer_id != NULL);
+ NRF_PM_DEBUG_CHECK(p_data != NULL);
+
+ VERIFY_PEER_DATA_ID_IN_RANGE(data_id);
+
+ rec_key = peer_data_id_to_record_key(data_id);
+
+ if (fds_record_find_by_key(rec_key, &rec_desc, &m_fds_ftok) != NRF_SUCCESS)
+ {
+ return false;
+ }
+
+ ret = fds_record_open(&rec_desc, &rec_flash);
+
+ if (ret != NRF_SUCCESS)
+ {
+ // It can only happen if the record was deleted after the call to fds_record_find_by_key(),
+ // before we could open it, or if CRC support was enabled in Flash Data Storage at compile
+ // time and the CRC check failed.
+ return false;
+ }
+
+ p_data->data_id = data_id;
+ p_data->length_words = rec_flash.p_header->length_words;
+ p_data->p_all_data = rec_flash.p_data;
+
+ *p_peer_id = file_id_to_peer_id(rec_flash.p_header->file_id);
+
+ (void)fds_record_close(&rec_desc);
+
+ return true;
+}
+
+
+ret_code_t pds_space_reserve(pm_peer_data_const_t const * p_peer_data,
+ pm_prepare_token_t * p_prepare_token)
+{
+ ret_code_t ret;
+
+ NRF_PM_DEBUG_CHECK(m_module_initialized);
+ NRF_PM_DEBUG_CHECK(p_peer_data != NULL);
+ NRF_PM_DEBUG_CHECK(p_prepare_token != NULL);
+
+ VERIFY_PEER_DATA_ID_IN_RANGE(p_peer_data->data_id);
+
+ ret = fds_reserve((fds_reserve_token_t*)p_prepare_token, p_peer_data->length_words);
+
+ switch (ret)
+ {
+ case FDS_SUCCESS:
+ return NRF_SUCCESS;
+
+ case FDS_ERR_RECORD_TOO_LARGE:
+ return NRF_ERROR_INVALID_LENGTH;
+
+ case FDS_ERR_NO_SPACE_IN_FLASH:
+ return NRF_ERROR_STORAGE_FULL;
+
+ default:
+ return NRF_ERROR_INTERNAL;
+ }
+}
+
+
+ret_code_t pds_space_reserve_cancel(pm_prepare_token_t prepare_token)
+{
+ ret_code_t ret;
+
+ NRF_PM_DEBUG_CHECK(m_module_initialized);
+ NRF_PM_DEBUG_CHECK(prepare_token != PDS_PREPARE_TOKEN_INVALID);
+
+ ret = fds_reserve_cancel((fds_reserve_token_t*)&prepare_token);
+
+ if (ret != FDS_SUCCESS)
+ {
+ return NRF_ERROR_INTERNAL;
+ }
+
+ return NRF_SUCCESS;
+}
+
+
+ret_code_t pds_peer_data_store(pm_peer_id_t peer_id,
+ pm_peer_data_const_t const * p_peer_data,
+ pm_prepare_token_t prepare_token,
+ pm_store_token_t * p_store_token)
+{
+ ret_code_t ret;
+ fds_record_t rec;
+ fds_record_desc_t rec_desc;
+
+ NRF_PM_DEBUG_CHECK(m_module_initialized);
+ NRF_PM_DEBUG_CHECK(p_peer_data != NULL);
+
+ VERIFY_PEER_ID_IN_RANGE(peer_id);
+ VERIFY_PEER_DATA_ID_IN_RANGE(p_peer_data->data_id);
+
+ // Prepare the record to be stored in flash.
+ rec.file_id = peer_id_to_file_id(peer_id);
+ rec.key = peer_data_id_to_record_key(p_peer_data->data_id);
+ rec.data.p_data = (void*)p_peer_data->p_all_data;
+ rec.data.length_words = p_peer_data->length_words;
+
+ ret = peer_data_find(peer_id, p_peer_data->data_id, &rec_desc);
+
+ if (ret == NRF_ERROR_NOT_FOUND)
+ {
+ // No previous data exists in flash.
+ if (prepare_token == PDS_PREPARE_TOKEN_INVALID)
+ {
+ // No space was previously reserved.
+ ret = fds_record_write(&rec_desc, &rec);
+ }
+ else
+ {
+ // Space for this record was previously reserved.
+ ret = fds_record_write_reserved(&rec_desc, &rec, (fds_reserve_token_t*)&prepare_token);
+ }
+ }
+ else // NRF_SUCCESS
+ {
+ if (prepare_token != PDS_PREPARE_TOKEN_INVALID)
+ {
+ (void)fds_reserve_cancel((fds_reserve_token_t*)&prepare_token);
+ }
+
+ // Update existing record.
+ ret = fds_record_update(&rec_desc, &rec);
+ }
+
+ switch (ret)
+ {
+ case FDS_SUCCESS:
+ if (p_store_token != NULL)
+ {
+ // Update the store token.
+ (void)fds_record_id_from_desc(&rec_desc, (uint32_t*)p_store_token);
+ }
+ return NRF_SUCCESS;
+
+ case FDS_ERR_BUSY:
+ case FDS_ERR_NO_SPACE_IN_QUEUES:
+ return NRF_ERROR_BUSY;
+
+ case FDS_ERR_NO_SPACE_IN_FLASH:
+ return NRF_ERROR_STORAGE_FULL;
+
+ default:
+ return NRF_ERROR_INTERNAL;
+ }
+}
+
+
+ret_code_t pds_peer_data_delete(pm_peer_id_t peer_id, pm_peer_data_id_t data_id)
+{
+ ret_code_t ret;
+ fds_record_desc_t record_desc;
+
+ NRF_PM_DEBUG_CHECK(m_module_initialized);
+
+ VERIFY_PEER_ID_IN_RANGE(peer_id);
+ VERIFY_PEER_DATA_ID_IN_RANGE(data_id);
+
+ ret = peer_data_find(peer_id, data_id, &record_desc);
+
+ if (ret != NRF_SUCCESS)
+ {
+ return NRF_ERROR_NOT_FOUND;
+ }
+
+ ret = fds_record_delete(&record_desc);
+
+ switch (ret)
+ {
+ case FDS_SUCCESS:
+ return NRF_SUCCESS;
+
+ case FDS_ERR_NO_SPACE_IN_QUEUES:
+ return NRF_ERROR_BUSY;
+
+ default:
+ return NRF_ERROR_INTERNAL;
+ }
+}
+
+
+pm_peer_id_t pds_peer_id_allocate(void)
+{
+ NRF_PM_DEBUG_CHECK(m_module_initialized);
+ return peer_id_allocate(PM_PEER_ID_INVALID);
+}
+
+
+ret_code_t pds_peer_id_free(pm_peer_id_t peer_id)
+{
+ NRF_PM_DEBUG_CHECK(m_module_initialized);
+ VERIFY_PEER_ID_IN_RANGE(peer_id);
+
+ (void)peer_id_delete(peer_id);
+ peer_data_delete_process();
+
+ return NRF_SUCCESS;
+}
+
+
+bool pds_peer_id_is_allocated(pm_peer_id_t peer_id)
+{
+ NRF_PM_DEBUG_CHECK(m_module_initialized);
+ return peer_id_is_allocated(peer_id);
+}
+
+
+pm_peer_id_t pds_next_peer_id_get(pm_peer_id_t prev_peer_id)
+{
+ NRF_PM_DEBUG_CHECK(m_module_initialized);
+ return peer_id_get_next_used(prev_peer_id);
+}
+
+
+pm_peer_id_t pds_next_deleted_peer_id_get(pm_peer_id_t prev_peer_id)
+{
+ NRF_PM_DEBUG_CHECK(m_module_initialized);
+ return peer_id_get_next_deleted(prev_peer_id);
+}
+
+
+uint32_t pds_peer_count_get(void)
+{
+ NRF_PM_DEBUG_CHECK(m_module_initialized);
+ return peer_id_n_ids();
+}
+#endif // NRF_MODULE_ENABLED(PEER_MANAGER)
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/peer_manager/peer_data_storage.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/peer_manager/peer_data_storage.h
new file mode 100644
index 0000000..fccfabc
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/peer_manager/peer_data_storage.h
@@ -0,0 +1,270 @@
+/**
+ * Copyright (c) 2015 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#ifndef PEER_DATA_STORAGE_H__
+#define PEER_DATA_STORAGE_H__
+
+
+#include <stdint.h>
+#include "sdk_errors.h"
+#include "ble_gap.h"
+#include "peer_manager_types.h"
+#include "peer_manager_internal.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+/**
+ * @cond NO_DOXYGEN
+ * @defgroup peer_data_storage Peer Data Storage
+ * @ingroup peer_manager
+ * @{
+ * @brief An internal module of @ref peer_manager. This module provides a Peer Manager-specific API
+ * to the persistent storage.
+ *
+ * @details This module uses Flash Data Storage (FDS) to interface with persistent storage.
+ */
+
+#define PDS_PREPARE_TOKEN_INVALID (0) /**< Invalid value for prepare token. */
+#define PDS_FIRST_RESERVED_FILE_ID (0xC000) /**< The beginning of the range of file IDs reserved for Peer Manager. */
+#define PDS_LAST_RESERVED_FILE_ID (0xFFFE) /**< The end of the range of file IDs reserved for Peer Manager. */
+#define PDS_FIRST_RESERVED_RECORD_KEY (0xC000) /**< The beginning of the range of record keys reserved for Peer Manager. */
+#define PDS_LAST_RESERVED_RECORD_KEY (0xFFFE) /**< The end of the range of record keys reserved for Peer Manager. */
+
+#define PEER_ID_TO_FILE_ID ( PDS_FIRST_RESERVED_FILE_ID) //!< Macro for converting a @ref pm_peer_id_t to an FDS file ID.
+#define FILE_ID_TO_PEER_ID (-PDS_FIRST_RESERVED_FILE_ID) //!< Macro for converting an FDS file ID to a @ref pm_peer_id_t.
+#define DATA_ID_TO_RECORD_KEY ( PDS_FIRST_RESERVED_RECORD_KEY) //!< Macro for converting a @ref pm_peer_data_id_t to an FDS record ID.
+#define RECORD_KEY_TO_DATA_ID (-PDS_FIRST_RESERVED_RECORD_KEY) //!< Macro for converting an FDS record ID to a @ref pm_peer_data_id_t.
+
+
+/**@brief Function for initializing the module.
+ *
+ * @retval NRF_SUCCESS If initialization was successful.
+ * @retval NRF_ERROR_STORAGE_FULL If no flash pages were available for use.
+ * @retval NRF_ERROR_INTERNAL If the module couldn't register with the flash filesystem.
+ */
+ret_code_t pds_init(void);
+
+
+/**@brief Function for reading peer data in flash.
+ *
+ * @param[in] peer_id The peer the data belongs to.
+ * @param[in] data_id The data to retrieve.
+ * @param[out] p_data The peer data. May not be @c NULL.
+ * @param[in] p_buf_len Length of the provided buffer, in bytes. Pass @c NULL to only copy
+ * a pointer to the data in flash.
+ *
+ * @retval NRF_SUCCESS If the operation was successful.
+ * @retval NRF_ERROR_INVALID_PARAM If @p peer_id or @p data_id are invalid.
+ * @retval NRF_ERROR_NOT_FOUND If the data was not found in flash.
+ * @retval NRF_ERROR_NO_MEM If the provided buffer is too small.
+ */
+ret_code_t pds_peer_data_read(pm_peer_id_t peer_id,
+ pm_peer_data_id_t data_id,
+ pm_peer_data_t * const p_data,
+ uint32_t const * const p_buf_len);
+
+
+/**@brief Function to prepare iterating over peer data in flash using @ref pds_peer_data_iterate.
+ * Call this function once each time before iterating using @ref pds_peer_data_iterate.
+ */
+void pds_peer_data_iterate_prepare(void);
+
+
+/**@brief Function for iterating peers' data in flash.
+ * Always call @ref pds_peer_data_iterate_prepare before starting iterating.
+ *
+ * @param[in] data_id The peer data to iterate over.
+ * @param[out] p_peer_id The peer the data belongs to.
+ * @param[out] p_data The peer data in flash.
+ *
+ * @retval true If the operation was successful.
+ * @retval false If the data was not found in flash, or another error occurred.
+ */
+bool pds_peer_data_iterate(pm_peer_data_id_t data_id,
+ pm_peer_id_t * const p_peer_id,
+ pm_peer_data_flash_t * const p_data);
+
+
+/**@brief Function for reserving space in flash to store data.
+ *
+ * @param[in] p_peer_data The data to be stored in flash. Only data length and type (ID) are
+ * relevant for this operation. May not be @c NULL.
+ * @param[out] p_prepare_token A token identifying the reserved space. May not be @c NULL.
+ *
+ * @retval NRF_SUCCESS If the operation was successful.
+ * @retval NRF_ERROR_INVALID_PARAM If the data ID in @p p_peer_data is invalid.
+ * @retval NRF_ERROR_INVALID_LENGTH If data length exceeds the maximum allowed length.
+ * @retval NRF_ERROR_STORAGE_FULL If no space is available in flash.
+ * @retval NRF_ERROR_INTERNAL If an unexpected error occurred.
+ */
+ret_code_t pds_space_reserve(pm_peer_data_const_t const * p_peer_data,
+ pm_prepare_token_t * p_prepare_token);
+
+
+/**@brief Function for undoing a previous call to @ref pds_space_reserve.
+ *
+ * @param[in] prepare_token A token identifying the reservation to cancel.
+ *
+ * @retval NRF_SUCCESS If the operation was successful.
+ * @retval NRF_ERROR_INTERNAL If an unexpected error occurred.
+ */
+ret_code_t pds_space_reserve_cancel(pm_prepare_token_t prepare_token);
+
+
+/**@brief Function for storing peer data in flash. If the same piece of data already exists for the
+ * given peer, it will be updated. This operation is asynchronous.
+ * Expect a @ref PM_EVT_PEER_DATA_UPDATE_SUCCEEDED or @ref PM_EVT_PEER_DATA_UPDATE_FAILED
+ * event.
+ *
+ * @param[in] peer_id The peer the data belongs to.
+ * @param[in] p_peer_data The peer data. May not be @c NULL.
+ * @param[in] prepare_token A token identifying the reservation made in flash to store the data.
+ * Pass @ref PDS_PREPARE_TOKEN_INVALID if no space was reserved.
+ * @param[out] p_store_token A token identifying this particular store operation. The token can be
+ * used to identify events pertaining to this operation. Pass @p NULL
+ * if not used.
+ *
+ * @retval NRF_SUCCESS If the operation was initiated successfully.
+ * @retval NRF_ERROR_INVALID_PARAM If @p peer_id or the data ID in @p_peer_data are invalid.
+ * @retval NRF_ERROR_STORAGE_FULL If no space is available in flash. This can only happen if
+ * @p p_prepare_token is @ref PDS_PREPARE_TOKEN_INVALID.
+ * @retval NRF_ERROR_BUSY If the flash filesystem was busy.
+ * @retval NRF_ERROR_INTERNAL If an unexpected error occurred.
+ */
+ret_code_t pds_peer_data_store(pm_peer_id_t peer_id,
+ pm_peer_data_const_t const * p_peer_data,
+ pm_prepare_token_t prepare_token,
+ pm_store_token_t * p_store_token);
+
+
+/**@brief Function for deleting peer data in flash. This operation is asynchronous.
+ * Expect a @ref PM_EVT_PEER_DATA_UPDATE_SUCCEEDED or @ref PM_EVT_PEER_DATA_UPDATE_FAILED
+ * event.
+ *
+ * @param[in] peer_id The peer the data belongs to
+ * @param[in] data_id The data to delete.
+ *
+ * @retval NRF_SUCCESS If the operation was initiated successfully.
+ * @retval NRF_ERROR_INVALID_PARAM If @p peer_id or @p data_id are invalid.
+ * @retval NRF_ERROR_NOT_FOUND If data was not found in flash.
+ * @retval NRF_ERROR_BUSY If the flash filesystem was busy.
+ * @retval NRF_ERROR_INTERNAL If an unexpected error occurred.
+ */
+ret_code_t pds_peer_data_delete(pm_peer_id_t peer_id, pm_peer_data_id_t data_id);
+
+
+/**@brief Function for claiming an unused peer ID.
+ *
+ * @retval PM_PEER_ID_INVALID If no peer ID was available.
+ */
+pm_peer_id_t pds_peer_id_allocate(void);
+
+
+/**@brief Function for freeing a peer ID and deleting all data associated with it in flash.
+ *
+ * @param[in] peer_id The ID of the peer to free.
+ *
+ * @retval NRF_SUCCESS The operation was initiated successfully.
+ * @retval NRF_ERROR_INVALID_PARAM If @p peer_id is invalid.
+ */
+ret_code_t pds_peer_id_free(pm_peer_id_t peer_id);
+
+
+/**@brief Function for finding out whether a peer ID is in use.
+ *
+ * @param[in] peer_id The peer ID to inquire about.
+ *
+ * @retval true @p peer_id is in use.
+ * @retval false @p peer_id is free.
+ */
+bool pds_peer_id_is_allocated(pm_peer_id_t peer_id);
+
+
+/**@brief Function for getting the next peer ID in the sequence of all used peer IDs. Can be
+ * used to loop through all used peer IDs.
+ *
+ * @note @ref PM_PEER_ID_INVALID is considered to be before the first and after the last ordinary
+ * peer ID.
+ *
+ * @param[in] prev_peer_id The previous peer ID.
+ *
+ * @return The first ordinary peer ID If @p prev_peer_id is @ref PM_PEER_ID_INVALID.
+ * @retval PM_PEER_ID_INVALID If @p prev_peer_id is the last ordinary peer ID or the module
+ * is not initialized.
+ */
+pm_peer_id_t pds_next_peer_id_get(pm_peer_id_t prev_peer_id);
+
+
+/**@brief Function for getting the next peer ID in the sequence of all peer IDs pending deletion.
+ * Can be used to loop through all used peer IDs.
+ *
+ * @note @ref PM_PEER_ID_INVALID is considered to be before the first and after the last ordinary
+ * peer ID.
+ *
+ * @param[in] prev_peer_id The previous peer ID.
+ *
+ * @return The next peer ID pending deletion.
+ * @return The first ordinary peer ID if prev_peer_id was @ref PM_PEER_ID_INVALID.
+ * @retval PM_PEER_ID_INVALID if prev_peer_id was the last ordinary peer ID or the module
+ * is not initialized.
+ */
+pm_peer_id_t pds_next_deleted_peer_id_get(pm_peer_id_t prev_peer_id);
+
+
+/**@brief Function for querying the number of valid peer IDs available. I.E the number of peers
+ * in persistent storage.
+ *
+ * @return The number of valid peer IDs.
+ */
+uint32_t pds_peer_count_get(void);
+
+
+/** @}
+ * @endcond
+ */
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* PEER_DATA_STORAGE_H__ */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/peer_manager/peer_database.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/peer_manager/peer_database.c
new file mode 100644
index 0000000..53b6680
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/peer_manager/peer_database.c
@@ -0,0 +1,814 @@
+/**
+ * Copyright (c) 2015 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#include "sdk_common.h"
+#if NRF_MODULE_ENABLED(PEER_MANAGER)
+#include "peer_database.h"
+
+#include <string.h>
+#include "peer_manager_types.h"
+#include "peer_manager_internal.h"
+#include "peer_data_storage.h"
+#include "pm_buffer.h"
+
+
+/**@brief Macro for verifying that the data ID is among the values eligible for using the write buffer.
+ *
+ * @param[in] data_id The data ID to verify.
+ */
+// @note emdi: could this maybe be a function?
+#define VERIFY_DATA_ID_WRITE_BUF(data_id) \
+do \
+{ \
+ if (((data_id) != PM_PEER_DATA_ID_BONDING) && ((data_id) != PM_PEER_DATA_ID_GATT_LOCAL)) \
+ { \
+ return NRF_ERROR_INVALID_PARAM; \
+ } \
+} while (0)
+
+
+// The number of registered event handlers.
+#define PDB_EVENT_HANDLERS_CNT (sizeof(m_evt_handlers) / sizeof(m_evt_handlers[0]))
+
+
+// Peer Database event handlers in other Peer Manager submodules.
+extern void pm_pdb_evt_handler(pm_evt_t * p_event);
+extern void sm_pdb_evt_handler(pm_evt_t * p_event);
+#if !defined(PM_SERVICE_CHANGED_ENABLED) || (PM_SERVICE_CHANGED_ENABLED == 1)
+extern void gscm_pdb_evt_handler(pm_evt_t * p_event);
+#endif
+extern void gcm_pdb_evt_handler(pm_evt_t * p_event);
+
+// Peer Database events' handlers.
+// The number of elements in this array is PDB_EVENT_HANDLERS_CNT.
+static pm_evt_handler_internal_t const m_evt_handlers[] =
+{
+ pm_pdb_evt_handler,
+ sm_pdb_evt_handler,
+#if !defined(PM_SERVICE_CHANGED_ENABLED) || (PM_SERVICE_CHANGED_ENABLED == 1)
+ gscm_pdb_evt_handler,
+#endif
+ gcm_pdb_evt_handler,
+};
+
+
+/**@brief Struct for keeping track of one write buffer, from allocation, until it is fully written
+ * or cancelled.
+ */
+typedef struct
+{
+ pm_peer_id_t peer_id; /**< The peer ID this buffer belongs to. */
+ pm_peer_data_id_t data_id; /**< The data ID this buffer belongs to. */
+ pm_prepare_token_t prepare_token; /**< Token given by Peer Data Storage if room in flash has been reserved. */
+ pm_store_token_t store_token; /**< Token given by Peer Data Storage when a flash write has been successfully requested. This is used as the check for whether such an operation has been successfully requested. */
+ uint8_t n_bufs; /**< The number of buffer blocks containing peer data. */
+ uint8_t buffer_block_id; /**< The index of the first (or only) buffer block containing peer data. */
+ uint8_t store_flash_full : 1; /**< Flag indicating that the buffer was attempted written to flash, but a flash full error was returned and the operation should be retried after room has been made. */
+ uint8_t store_busy : 1; /**< Flag indicating that the buffer was attempted written to flash, but a busy error was returned and the operation should be retried. */
+} pdb_buffer_record_t;
+
+
+static bool m_module_initialized;
+static pm_buffer_t m_write_buffer; /**< The internal states of the write buffer. */
+static pdb_buffer_record_t m_write_buffer_records[PM_FLASH_BUFFERS]; /**< The available write buffer records. */
+static bool m_pending_store = false; /**< Whether there are any pending (Not yet successfully requested in Peer Data Storage) store operations. This flag is for convenience only. The real bookkeeping is in the records (@ref m_write_buffer_records). */
+
+
+
+/**@brief Function for invalidating a record of a write buffer allocation.
+ *
+ * @param[in] p_record The record to invalidate.
+ */
+static void write_buffer_record_invalidate(pdb_buffer_record_t * p_record)
+{
+ p_record->peer_id = PM_PEER_ID_INVALID;
+ p_record->data_id = PM_PEER_DATA_ID_INVALID;
+ p_record->buffer_block_id = PM_BUFFER_INVALID_ID;
+ p_record->store_busy = false;
+ p_record->store_flash_full = false;
+ p_record->n_bufs = 0;
+ p_record->prepare_token = PDS_PREPARE_TOKEN_INVALID;
+ p_record->store_token = PM_STORE_TOKEN_INVALID;
+}
+
+
+/**@brief Function for finding a record of a write buffer allocation.
+ *
+ * @param[in] peer_id The peer ID in the record.
+ * @param[inout] p_index In: The starting index, out: The index of the record
+ *
+ * @return A pointer to the matching record, or NULL if none was found.
+ */
+static pdb_buffer_record_t * write_buffer_record_find_next(pm_peer_id_t peer_id, uint32_t * p_index)
+{
+ for (uint32_t i = *p_index; i < PM_FLASH_BUFFERS; i++)
+ {
+ if ((m_write_buffer_records[i].peer_id == peer_id))
+ {
+ *p_index = i;
+ return &m_write_buffer_records[i];
+ }
+ }
+ return NULL;
+}
+
+
+/**@brief Function for finding a record of a write buffer allocation.
+ *
+ * @param[in] peer_id The peer ID in the record.
+ * @param[in] data_id The data ID in the record.
+ *
+ * @return A pointer to the matching record, or NULL if none was found.
+ */
+static pdb_buffer_record_t * write_buffer_record_find(pm_peer_id_t peer_id,
+ pm_peer_data_id_t data_id)
+{
+ uint32_t index = 0;
+ pdb_buffer_record_t * p_record = write_buffer_record_find_next(peer_id, &index);
+
+ while ((p_record != NULL) && ( (p_record->data_id != data_id)
+ || (p_record->store_busy)
+ || (p_record->store_flash_full)
+ || (p_record->store_token != PM_STORE_TOKEN_INVALID)))
+ {
+ index++;
+ p_record = write_buffer_record_find_next(peer_id, &index);
+ }
+
+ return p_record;
+}
+
+
+/**@brief Function for finding a record of a write buffer allocation that has been sent to be stored.
+ *
+ * @param[in] store_token The store token received when store was called for the record.
+ *
+ * @return A pointer to the matching record, or NULL if none was found.
+ */
+static pdb_buffer_record_t * write_buffer_record_find_stored(pm_store_token_t store_token)
+{
+ for (int i = 0; i < PM_FLASH_BUFFERS; i++)
+ {
+ if (m_write_buffer_records[i].store_token == store_token)
+ {
+ return &m_write_buffer_records[i];
+ }
+ }
+ return NULL;
+}
+
+
+/**@brief Function for finding an available record for write buffer allocation.
+ *
+ * @return A pointer to the available record, or NULL if none was found.
+ */
+static pdb_buffer_record_t * write_buffer_record_find_unused(void)
+{
+ return write_buffer_record_find(PM_PEER_ID_INVALID, PM_PEER_DATA_ID_INVALID);
+}
+
+
+/**@brief Function for gracefully deactivating a write buffer record.
+ *
+ * @details This function will first release any buffers, then invalidate the record.
+ *
+ * @param[inout] p_write_buffer_record The record to release.
+ *
+ * @return A pointer to the matching record, or NULL if none was found.
+ */
+static void write_buffer_record_release(pdb_buffer_record_t * p_write_buffer_record)
+{
+ for (uint32_t i = 0; i < p_write_buffer_record->n_bufs; i++)
+ {
+ pm_buffer_release(&m_write_buffer, p_write_buffer_record->buffer_block_id + i);
+ }
+
+ write_buffer_record_invalidate(p_write_buffer_record);
+}
+
+
+/**@brief Function for claiming and activating a write buffer record.
+ *
+ * @param[out] pp_write_buffer_record The claimed record.
+ * @param[in] peer_id The peer ID this record should have.
+ * @param[in] data_id The data ID this record should have.
+ */
+static void write_buffer_record_acquire(pdb_buffer_record_t ** pp_write_buffer_record,
+ pm_peer_id_t peer_id,
+ pm_peer_data_id_t data_id)
+{
+ if (pp_write_buffer_record == NULL)
+ {
+ return;
+ }
+ *pp_write_buffer_record = write_buffer_record_find_unused();
+ if (*pp_write_buffer_record == NULL)
+ {
+ // This also means the buffer is full.
+ return;
+ }
+ (*pp_write_buffer_record)->peer_id = peer_id;
+ (*pp_write_buffer_record)->data_id = data_id;
+}
+
+
+/**@brief Function for dispatching outbound events to all registered event handlers.
+ *
+ * @param[in] p_event The event to dispatch.
+ */
+static void pdb_evt_send(pm_evt_t * p_event)
+{
+ for (uint32_t i = 0; i < PDB_EVENT_HANDLERS_CNT; i++)
+ {
+ m_evt_handlers[i](p_event);
+ }
+}
+
+
+/**@brief Function for resetting the internal state of the Peer Database module.
+ *
+ * @param[out] p_event The event to dispatch.
+ */
+static void internal_state_reset()
+{
+ for (uint32_t i = 0; i < PM_FLASH_BUFFERS; i++)
+ {
+ write_buffer_record_invalidate(&m_write_buffer_records[i]);
+ }
+}
+
+
+static void peer_data_point_to_buffer(pm_peer_data_t * p_peer_data, pm_peer_data_id_t data_id, uint8_t * p_buffer_memory, uint16_t n_bufs)
+{
+ uint16_t n_bytes = n_bufs * PDB_WRITE_BUF_SIZE;
+ p_peer_data->data_id = data_id;
+
+ p_peer_data->p_all_data = (pm_peer_data_bonding_t *)p_buffer_memory;
+ p_peer_data->length_words = BYTES_TO_WORDS(n_bytes);
+}
+
+
+static void peer_data_const_point_to_buffer(pm_peer_data_const_t * p_peer_data, pm_peer_data_id_t data_id, uint8_t * p_buffer_memory, uint32_t n_bufs)
+{
+ peer_data_point_to_buffer((pm_peer_data_t*)p_peer_data, data_id, p_buffer_memory, n_bufs);
+}
+
+
+static void write_buf_length_words_set(pm_peer_data_const_t * p_peer_data)
+{
+ switch (p_peer_data->data_id)
+ {
+ case PM_PEER_DATA_ID_BONDING:
+ p_peer_data->length_words = PM_BONDING_DATA_N_WORDS();
+ break;
+ case PM_PEER_DATA_ID_SERVICE_CHANGED_PENDING:
+ p_peer_data->length_words = PM_SC_STATE_N_WORDS();
+ break;
+ case PM_PEER_DATA_ID_PEER_RANK:
+ p_peer_data->length_words = PM_USAGE_INDEX_N_WORDS();
+ break;
+ case PM_PEER_DATA_ID_GATT_LOCAL:
+ p_peer_data->length_words = PM_LOCAL_DB_N_WORDS(p_peer_data->p_local_gatt_db->len);
+ break;
+ default:
+ // No action needed.
+ break;
+ }
+}
+
+
+/**@brief Function for writing data into persistent storage. Writing happens asynchronously.
+ *
+ * @note This will unlock the data after it has been written.
+ *
+ * @param[in] p_write_buffer_record The write buffer record to write into persistent storage.
+ *
+ * @retval NRF_SUCCESS Data storing was successfully started.
+ * @retval NRF_ERROR_STORAGE_FULL No space available in persistent storage. Please clear some
+ * space, the operation will be reattempted after the next compress
+ * procedure. This error will not happen if
+ * @ref pdb_write_buf_store_prepare is called beforehand.
+ * @retval NRF_ERROR_INVALID_PARAM Data ID was invalid.
+ * @retval NRF_ERROR_INVALID_STATE Module is not initialized.
+ * @retval NRF_ERROR_INTERNAL Unexpected internal error.
+ */
+ret_code_t write_buf_store(pdb_buffer_record_t * p_write_buffer_record)
+{
+ ret_code_t err_code = NRF_SUCCESS;
+ pm_peer_data_const_t peer_data = {.data_id = p_write_buffer_record->data_id};
+ uint8_t * p_buffer_memory;
+
+ p_buffer_memory = pm_buffer_ptr_get(&m_write_buffer, p_write_buffer_record->buffer_block_id);
+ if (p_buffer_memory == NULL)
+ {
+ return NRF_ERROR_INTERNAL;
+ }
+
+ peer_data_const_point_to_buffer(&peer_data,
+ p_write_buffer_record->data_id,
+ p_buffer_memory,
+ p_write_buffer_record->n_bufs);
+ write_buf_length_words_set(&peer_data);
+
+ err_code = pds_peer_data_store(p_write_buffer_record->peer_id,
+ &peer_data,
+ p_write_buffer_record->prepare_token,
+ &p_write_buffer_record->store_token);
+
+
+ switch (err_code)
+ {
+ case NRF_SUCCESS:
+ p_write_buffer_record->store_busy = false;
+ p_write_buffer_record->store_flash_full = false;
+ break;
+
+ case NRF_ERROR_BUSY:
+ p_write_buffer_record->store_busy = true;
+ p_write_buffer_record->store_flash_full = false;
+ m_pending_store = true;
+
+ err_code = NRF_SUCCESS;
+ break;
+
+ case NRF_ERROR_STORAGE_FULL:
+ p_write_buffer_record->store_busy = false;
+ p_write_buffer_record->store_flash_full = true;
+ m_pending_store = true;
+ break;
+
+ case NRF_ERROR_INVALID_PARAM:
+ // No action.
+ break;
+
+ default:
+ err_code = NRF_ERROR_INTERNAL;
+ break;
+ }
+
+ return err_code;
+}
+
+
+/**@brief This calls @ref write_buf_store and sends events based on the return value.
+ *
+ * See @ref write_buf_store for more info.
+ *
+ * @return Whether or not the store operation succeeded.
+ */
+static bool write_buf_store_in_event(pdb_buffer_record_t * p_write_buffer_record)
+{
+ ret_code_t err_code;
+ pm_evt_t event;
+
+ err_code = write_buf_store(p_write_buffer_record);
+ if (err_code != NRF_SUCCESS)
+ {
+ event.conn_handle = BLE_CONN_HANDLE_INVALID;
+ event.peer_id = p_write_buffer_record->peer_id;
+
+ if (err_code == NRF_ERROR_STORAGE_FULL)
+ {
+ event.evt_id = PM_EVT_STORAGE_FULL;
+ }
+ else
+ {
+ event.evt_id = PM_EVT_ERROR_UNEXPECTED;
+ event.params.error_unexpected.error = err_code;
+ }
+
+ pdb_evt_send(&event);
+
+ return false;
+ }
+
+ return true;
+}
+
+
+/**@brief This reattempts store operations on write buffers, that previously failed because of @ref
+ * NRF_ERROR_BUSY or @ref NRF_ERROR_STORAGE_FULL errors.
+ *
+ * param[in] retry_flash_full Whether to retry operations that failed because of an
+ * @ref NRF_ERROR_STORAGE_FULL error.
+ */
+static void reattempt_previous_operations(bool retry_flash_full)
+{
+ bool found_pending_operation = false;
+
+ if (!m_pending_store)
+ {
+ return;
+ }
+
+ for (uint32_t i = 0; i < PM_FLASH_BUFFERS; i++)
+ {
+ if ((m_write_buffer_records[i].store_busy)
+ || (m_write_buffer_records[i].store_flash_full && retry_flash_full))
+ {
+ found_pending_operation = true;
+
+ bool success = write_buf_store_in_event(&m_write_buffer_records[i]);
+
+ if (!success)
+ {
+ return;
+ }
+ }
+ }
+
+ if (!found_pending_operation)
+ {
+ // All records have been searched and none were pending.
+ // Clear flag so records aren't searched.
+ m_pending_store = false;
+ }
+}
+
+
+/**@brief Function for handling events from the Peer Data Storage module.
+ * This function is extern in Peer Data Storage.
+ *
+ * @param[in] p_event The event to handle.
+ */
+void pdb_pds_evt_handler(pm_evt_t * p_event)
+{
+ pdb_buffer_record_t * p_write_buffer_record;
+ bool evt_send = true;
+ bool retry_flash_full = false;
+
+ p_write_buffer_record = write_buffer_record_find_stored(p_event->params.peer_data_update_succeeded.token);
+
+ switch (p_event->evt_id)
+ {
+ case PM_EVT_PEER_DATA_UPDATE_SUCCEEDED:
+ if ( (p_event->params.peer_data_update_succeeded.action == PM_PEER_DATA_OP_UPDATE)
+ && (p_write_buffer_record != NULL))
+ {
+ // The write came from PDB.
+ write_buffer_record_release(p_write_buffer_record);
+ }
+ break;
+
+ case PM_EVT_PEER_DATA_UPDATE_FAILED:
+ if ( (p_event->params.peer_data_update_succeeded.action == PM_PEER_DATA_OP_UPDATE)
+ && (p_write_buffer_record != NULL))
+ {
+ // The write came from PDB, retry.
+ p_write_buffer_record->store_token = PM_STORE_TOKEN_INVALID;
+ p_write_buffer_record->store_busy = true;
+ m_pending_store = true;
+ evt_send = false;
+ }
+ break;
+
+ case PM_EVT_FLASH_GARBAGE_COLLECTED:
+ retry_flash_full = true;
+ break;
+
+ default:
+ break;
+ }
+
+ if (evt_send)
+ {
+ // Forward the event to all registered Peer Database event handlers.
+ pdb_evt_send(p_event);
+ }
+
+ reattempt_previous_operations(retry_flash_full);
+}
+
+
+ret_code_t pdb_init()
+{
+ ret_code_t ret;
+
+ NRF_PM_DEBUG_CHECK(!m_module_initialized);
+
+ internal_state_reset();
+
+ PM_BUFFER_INIT(&m_write_buffer, PM_FLASH_BUFFERS, PDB_WRITE_BUF_SIZE, ret);
+
+ if (ret != NRF_SUCCESS)
+ {
+ return NRF_ERROR_INTERNAL;
+ }
+
+ m_module_initialized = true;
+
+ return NRF_SUCCESS;
+}
+
+
+pm_peer_id_t pdb_peer_allocate(void)
+{
+ NRF_PM_DEBUG_CHECK(m_module_initialized);
+ return pds_peer_id_allocate();
+}
+
+
+ret_code_t pdb_peer_free(pm_peer_id_t peer_id)
+{
+ ret_code_t err_code_in = NRF_SUCCESS;
+ ret_code_t err_code_out = NRF_SUCCESS;
+
+ NRF_PM_DEBUG_CHECK(m_module_initialized);
+
+ uint32_t index = 0;
+ pdb_buffer_record_t * p_record = write_buffer_record_find_next(peer_id, &index);
+
+ while (p_record != NULL)
+ {
+ err_code_in = pdb_write_buf_release(peer_id, p_record->data_id);
+
+ if ( (err_code_in != NRF_SUCCESS)
+ && (err_code_in != NRF_ERROR_NOT_FOUND))
+ {
+ err_code_out = NRF_ERROR_INTERNAL;
+ }
+
+ index++;
+ p_record = write_buffer_record_find_next(peer_id, &index);
+ }
+
+ if (err_code_out == NRF_SUCCESS)
+ {
+ err_code_in = pds_peer_id_free(peer_id);
+
+ if (err_code_in == NRF_SUCCESS)
+ {
+ // No action needed.
+ }
+ else if (err_code_in == NRF_ERROR_INVALID_PARAM)
+ {
+ err_code_out = NRF_ERROR_INVALID_PARAM;
+ }
+ else
+ {
+ err_code_out = NRF_ERROR_INTERNAL;
+ }
+ }
+
+ return err_code_out;
+}
+
+
+ret_code_t pdb_peer_data_ptr_get(pm_peer_id_t peer_id,
+ pm_peer_data_id_t data_id,
+ pm_peer_data_flash_t * const p_peer_data)
+{
+ NRF_PM_DEBUG_CHECK(m_module_initialized);
+ NRF_PM_DEBUG_CHECK(p_peer_data != NULL);
+
+ // Pass NULL to only retrieve a pointer.
+ return pds_peer_data_read(peer_id, data_id, (pm_peer_data_t*)p_peer_data, NULL);
+}
+
+
+
+ret_code_t pdb_write_buf_get(pm_peer_id_t peer_id,
+ pm_peer_data_id_t data_id,
+ uint32_t n_bufs,
+ pm_peer_data_t * p_peer_data)
+{
+ NRF_PM_DEBUG_CHECK(m_module_initialized);
+
+ VERIFY_PARAM_NOT_NULL(p_peer_data);
+ VERIFY_DATA_ID_WRITE_BUF(data_id);
+
+ if ( (n_bufs == 0)
+ || (n_bufs > PM_FLASH_BUFFERS)
+ || !pds_peer_id_is_allocated(peer_id))
+ {
+ return NRF_ERROR_INVALID_PARAM;
+ }
+
+ pdb_buffer_record_t * p_write_buffer_record;
+ uint8_t * p_buffer_memory;
+ bool new_record = false;
+
+ p_write_buffer_record = write_buffer_record_find(peer_id, data_id);
+
+ if (p_write_buffer_record == NULL)
+ {
+ // No buffer exists.
+ write_buffer_record_acquire(&p_write_buffer_record, peer_id, data_id);
+ if (p_write_buffer_record == NULL)
+ {
+ return NRF_ERROR_BUSY;
+ }
+ }
+ else if (p_write_buffer_record->n_bufs != n_bufs)
+ {
+ // Buffer exists with a different n_bufs from what was requested.
+ return NRF_ERROR_FORBIDDEN;
+ }
+
+ if (p_write_buffer_record->buffer_block_id == PM_BUFFER_INVALID_ID)
+ {
+ p_write_buffer_record->buffer_block_id = pm_buffer_block_acquire(&m_write_buffer, n_bufs);
+
+ if (p_write_buffer_record->buffer_block_id == PM_BUFFER_INVALID_ID)
+ {
+ write_buffer_record_invalidate(p_write_buffer_record);
+ return NRF_ERROR_BUSY;
+ }
+
+ new_record = true;
+ }
+
+ p_write_buffer_record->n_bufs = n_bufs;
+
+ p_buffer_memory = pm_buffer_ptr_get(&m_write_buffer, p_write_buffer_record->buffer_block_id);
+
+ if (p_buffer_memory == NULL)
+ {
+ return NRF_ERROR_INTERNAL;
+ }
+
+ peer_data_point_to_buffer(p_peer_data, data_id, p_buffer_memory, n_bufs);
+ if (new_record && (data_id == PM_PEER_DATA_ID_GATT_LOCAL))
+ {
+ p_peer_data->p_local_gatt_db->len = PM_LOCAL_DB_LEN(p_peer_data->length_words);
+ }
+
+ return NRF_SUCCESS;
+}
+
+
+ret_code_t pdb_write_buf_release(pm_peer_id_t peer_id, pm_peer_data_id_t data_id)
+{
+ NRF_PM_DEBUG_CHECK(m_module_initialized);
+
+ ret_code_t err_code = NRF_SUCCESS;
+ pdb_buffer_record_t * p_write_buffer_record;
+ p_write_buffer_record = write_buffer_record_find(peer_id, data_id);
+
+ if (p_write_buffer_record == NULL)
+ {
+ return NRF_ERROR_NOT_FOUND;
+ }
+
+ if (p_write_buffer_record->prepare_token != PDS_PREPARE_TOKEN_INVALID)
+ {
+ err_code = pds_space_reserve_cancel(p_write_buffer_record->prepare_token);
+ if (err_code != NRF_SUCCESS)
+ {
+ err_code = NRF_ERROR_INTERNAL;
+ }
+ }
+
+ write_buffer_record_release(p_write_buffer_record);
+
+ return err_code;
+}
+
+
+ret_code_t pdb_write_buf_store_prepare(pm_peer_id_t peer_id, pm_peer_data_id_t data_id)
+{
+ NRF_PM_DEBUG_CHECK(m_module_initialized);
+
+ VERIFY_DATA_ID_WRITE_BUF(data_id);
+
+ ret_code_t err_code = NRF_SUCCESS;
+ pdb_buffer_record_t * p_write_buffer_record;
+ p_write_buffer_record = write_buffer_record_find(peer_id, data_id);
+
+ if (p_write_buffer_record == NULL)
+ {
+ return NRF_ERROR_NOT_FOUND;
+ }
+
+ if (p_write_buffer_record->prepare_token == PDS_PREPARE_TOKEN_INVALID)
+ {
+ uint8_t * p_buffer_memory = pm_buffer_ptr_get(&m_write_buffer,
+ p_write_buffer_record->buffer_block_id);
+ pm_peer_data_const_t peer_data = {.data_id = data_id};
+
+ if (p_buffer_memory == NULL)
+ {
+ return NRF_ERROR_INTERNAL;
+ }
+
+ peer_data_const_point_to_buffer(&peer_data, data_id, p_buffer_memory, p_write_buffer_record->n_bufs);
+
+ write_buf_length_words_set(&peer_data);
+
+ err_code = pds_space_reserve(&peer_data, &p_write_buffer_record->prepare_token);
+ if (err_code == NRF_ERROR_INVALID_LENGTH)
+ {
+ return NRF_ERROR_INTERNAL;
+ }
+ }
+
+ return err_code;
+}
+
+
+ret_code_t pdb_write_buf_store(pm_peer_id_t peer_id,
+ pm_peer_data_id_t data_id,
+ pm_peer_id_t new_peer_id)
+{
+ NRF_PM_DEBUG_CHECK(m_module_initialized);
+
+ VERIFY_DATA_ID_WRITE_BUF(data_id);
+
+ pdb_buffer_record_t * p_write_buffer_record = write_buffer_record_find(peer_id, data_id);
+
+ if (p_write_buffer_record == NULL)
+ {
+ return NRF_ERROR_NOT_FOUND;
+ }
+
+ p_write_buffer_record->peer_id = new_peer_id;
+ p_write_buffer_record->data_id = data_id;
+ return write_buf_store(p_write_buffer_record);
+}
+
+
+ret_code_t pdb_clear(pm_peer_id_t peer_id, pm_peer_data_id_t data_id)
+{
+ NRF_PM_DEBUG_CHECK(m_module_initialized);
+ return pds_peer_data_delete(peer_id, data_id);
+}
+
+
+uint32_t pdb_n_peers(void)
+{
+ NRF_PM_DEBUG_CHECK(m_module_initialized);
+ return pds_peer_count_get();
+}
+
+
+pm_peer_id_t pdb_next_peer_id_get(pm_peer_id_t prev_peer_id)
+{
+ NRF_PM_DEBUG_CHECK(m_module_initialized);
+ return pds_next_peer_id_get(prev_peer_id);
+}
+
+
+pm_peer_id_t pdb_next_deleted_peer_id_get(pm_peer_id_t prev_peer_id)
+{
+ NRF_PM_DEBUG_CHECK(m_module_initialized);
+ return pds_next_deleted_peer_id_get(prev_peer_id);
+}
+
+
+ret_code_t pdb_peer_data_load(pm_peer_id_t peer_id,
+ pm_peer_data_id_t data_id,
+ pm_peer_data_t * const p_peer_data)
+{
+ NRF_PM_DEBUG_CHECK(m_module_initialized);
+ NRF_PM_DEBUG_CHECK(p_peer_data != NULL);
+
+ // Provide the buffer length in bytes.
+ uint32_t const data_len_bytes = (p_peer_data->length_words * sizeof(uint32_t));
+ return pds_peer_data_read(peer_id, data_id, p_peer_data, &data_len_bytes);
+}
+
+
+ret_code_t pdb_raw_store(pm_peer_id_t peer_id,
+ pm_peer_data_const_t * p_peer_data,
+ pm_store_token_t * p_store_token)
+{
+ NRF_PM_DEBUG_CHECK(m_module_initialized);
+ return pds_peer_data_store(peer_id, p_peer_data, PDS_PREPARE_TOKEN_INVALID, p_store_token);
+}
+#endif // NRF_MODULE_ENABLED(PEER_MANAGER)
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/peer_manager/peer_database.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/peer_manager/peer_database.h
new file mode 100644
index 0000000..819a9eb
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/peer_manager/peer_database.h
@@ -0,0 +1,309 @@
+/**
+ * Copyright (c) 2015 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#ifndef PEER_DATABASE_H__
+#define PEER_DATABASE_H__
+
+#include <stdint.h>
+#include "peer_manager_types.h"
+#include "peer_manager_internal.h"
+#include "sdk_errors.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @cond NO_DOXYGEN
+ * @defgroup peer_database Peer Database
+ * @ingroup peer_manager
+ * @{
+ * @brief An internal module of @ref peer_manager. A module for simple management of reading and
+ * writing of peer data into persistent storage.
+ *
+ */
+
+#define PDB_WRITE_BUF_SIZE (sizeof(pm_peer_data_bonding_t)) //!< The size (in bytes) of each block in the internal buffer accessible via @ref pdb_write_buf_get.
+
+
+/**@brief Function for initializing the module.
+ *
+ * @retval NRF_SUCCESS If initialization was successful.
+ * @retval NRF_ERROR_INTERNAL An unexpected error happened.
+ */
+ret_code_t pdb_init(void);
+
+
+/**@brief Function for allocating persistent bond storage for a peer.
+ *
+ * @return The ID of the newly allocated storage.
+ * @retval PM_PEER_ID_INVALID If no peer ID is available.
+ */
+pm_peer_id_t pdb_peer_allocate(void);
+
+
+/**@brief Function for freeing a peer's persistent bond storage.
+ *
+ * @note This function will call @ref pdb_write_buf_release on the data for this peer.
+ *
+ * @param[in] peer_id ID to be freed.
+ *
+ * @retval NRF_SUCCESS Peer ID was released and clear operation was initiated successfully.
+ * @retval NRF_ERROR_INVALID_PARAM Peer ID was invalid.
+ */
+ret_code_t pdb_peer_free(pm_peer_id_t peer_id);
+
+
+/**@brief Function for retrieving a pointer to peer data in flash (read-only).
+ *
+ * @note Dereferencing this pointer is not the safest thing to do if interrupts are enabled,
+ * because Flash Data Storage garbage collection might move the data around. Either disable
+ * interrupts while using the data, or use @ref pdb_peer_data_load.
+ *
+ * @param[in] peer_id The peer the data belongs to.
+ * @param[in] data_id The data to read.
+ * @param[out] p_peer_data The peer data, read-only.
+ *
+ * @retval NRF_SUCCESS If the pointer to the data was retrieved successfully.
+ * @retval NRF_ERROR_INVALID_PARAM If either @p peer_id or @p data_id are invalid.
+ * @retval NRF_ERROR_NOT_FOUND If data was not found in flash.
+ */
+ret_code_t pdb_peer_data_ptr_get(pm_peer_id_t peer_id,
+ pm_peer_data_id_t data_id,
+ pm_peer_data_flash_t * const p_peer_data);
+
+
+/**@brief Function for retrieving pointers to a write buffer for peer data.
+ *
+ * @details This function will provide pointers to a buffer of the data. The data buffer will not be
+ * written to persistent storage until @ref pdb_write_buf_store is called. The buffer is
+ * released by calling either @ref pdb_write_buf_release, @ref pdb_write_buf_store, or
+ * @ref pdb_peer_free.
+ *
+ * When the data_id refers to a variable length data type, the available size is written
+ * to the data, both the top-level, and any internal length fields.
+ *
+ * @note Calling this function on a peer_id/data_id pair that already has a buffer created will
+ * give the same buffer, not create a new one. If n_bufs was increased since last time, the
+ * buffer might be relocated to be able to provide additional room. In this case, the data
+ * will be copied. If n_bufs was increased since last time, this function might return @ref
+ * NRF_ERROR_BUSY. In that case, the buffer is automatically released.
+ *
+ * @param[in] peer_id ID of peer to get a write buffer for.
+ * @param[in] data_id Which piece of data to get.
+ * @param[in] n_bufs The number of contiguous buffers needed.
+ * @param[out] p_peer_data Pointers to mutable peer data.
+ *
+ * @retval NRF_SUCCESS Data retrieved successfully.
+ * @retval NRF_ERROR_INVALID_PARAM Data ID or Peer ID was invalid or unallocated, or n_bufs was 0
+ * or more than the total available buffers.
+ * @retval NRF_ERROR_FORBIDDEN n_bufs was higher or lower than the existing buffer. If needed,
+ * release the existing buffer with @ref pdb_write_buf_release, and
+ * call this function again.
+ * @retval NRF_ERROR_NULL p_peer_data was NULL.
+ * @retval NRF_ERROR_BUSY Not enough buffer(s) available.
+ * @retval NRF_ERROR_INTERNAL Unexpected internal error.
+ */
+ret_code_t pdb_write_buf_get(pm_peer_id_t peer_id,
+ pm_peer_data_id_t data_id,
+ uint32_t n_bufs,
+ pm_peer_data_t * p_peer_data);
+
+
+/**@brief Function for freeing a write buffer allocated with @ref pdb_write_buf_get.
+ *
+ * @note This function will not write peer data to persistent memory. Data in released buffer will
+ * be lost.
+ *
+ * @note This function will undo any previous call to @ref pdb_write_buf_store_prepare for this
+ * piece of data.
+ *
+ * @param[in] peer_id ID of peer to release buffer for.
+ * @param[in] data_id Which piece of data to release buffer for.
+ *
+ * @retval NRF_SUCCESS Successfully released buffer.
+ * @retval NRF_ERROR_NOT_FOUND No buffer was allocated for this peer ID/data ID pair.
+ * @retval NRF_ERROR_INTERNAL Unexpected internal error.
+ */
+ret_code_t pdb_write_buf_release(pm_peer_id_t peer_id, pm_peer_data_id_t data_id);
+
+
+/**@brief Function for reserving space in persistent storage for data in a buffer.
+ *
+ * @note This function only works for data which has a write buffer allocated. If the write buffer
+ * is released, this prepare is undone.
+ *
+ * @note If space has already been reserved for this data, nothing is done.
+ *
+ * @param[in] peer_id The peer whose data to reserve space for.
+ * @param[in] data_id The type of data to reserve space for.
+ *
+ * @retval NRF_SUCCESS Successfully reserved space in persistent storage.
+ * @retval NRF_ERROR_STORAGE_FULL Not enough room in persistent storage.
+ * @retval NRF_ERROR_NOT_FOUND No buffer has been allocated for this peer ID/data ID pair.
+ * @retval NRF_ERROR_INVALID_PARAM Data ID or Peer ID was invalid or unallocated.
+ */
+ret_code_t pdb_write_buf_store_prepare(pm_peer_id_t peer_id, pm_peer_data_id_t data_id);
+
+
+/**@brief Function for writing data into persistent storage. Writing happens asynchronously.
+ *
+ * @note This will unlock the data after it has been written.
+ *
+ * @param[in] peer_id The ID used to address the write buffer.
+ * @param[in] data_id Which piece of data to store.
+ * @param[in] new_peer_id The ID to put in flash. This will usually be the same as peer_id.
+ *
+ * @retval NRF_SUCCESS Data storing was successfully started.
+ * @retval NRF_ERROR_STORAGE_FULL No space available in persistent storage. Please clear some
+ * space, the operation will be reattempted after the next compress
+ * procedure. This error will not happen if
+ * @ref pdb_write_buf_store_prepare is called beforehand.
+ * @retval NRF_ERROR_INVALID_PARAM Data ID was invalid.
+ * @retval NRF_ERROR_NOT_FOUND No buffer has been allocated for this peer ID/data ID pair.
+ * @retval NRF_ERROR_INTERNAL Unexpected internal error.
+ */
+ret_code_t pdb_write_buf_store(pm_peer_id_t peer_id,
+ pm_peer_data_id_t data_id,
+ pm_peer_id_t new_peer_id);
+
+
+/**@brief Function for clearing data from persistent storage.
+ *
+ * @param[in] peer_id ID of peer to clear data for.
+ * @param[in] data_id Which piece of data to clear.
+ *
+ * @retval NRF_SUCCESS The clear was initiated successfully.
+ * @retval NRF_ERROR_INVALID_PARAM Data ID or peer ID was invalid.
+ * @retval NRF_ERROR_NOT_FOUND Nothing to clear for this peer ID/data ID combination.
+ * @retval NRF_ERROR_BUSY Underlying modules are busy and can't take any more requests at
+ * this moment.
+ * @retval NRF_ERROR_INTERNAL Internal error.
+ */
+ret_code_t pdb_clear(pm_peer_id_t peer_id, pm_peer_data_id_t data_id);
+
+
+/**@brief Function for querying the number of valid peer IDs available. I.E the number of peers
+ * in persistent storage.
+ *
+ * @return The number of valid peer IDs.
+ */
+uint32_t pdb_n_peers(void);
+
+
+/**@brief Function for getting the next peer ID in the sequence of all used peer IDs. Can be
+ * used to loop through all used peer IDs.
+ *
+ * @note @ref PM_PEER_ID_INVALID is considered to be before the first and after the last ordinary
+ * peer ID.
+ *
+ * @param[in] prev_peer_id The previous peer ID.
+ *
+ * @return The next peer ID.
+ * @return The first ordinary peer ID if prev_peer_id was @ref PM_PEER_ID_INVALID.
+ * @retval PM_PEER_ID_INVALID if prev_peer_id was the last ordinary peer ID.
+ */
+pm_peer_id_t pdb_next_peer_id_get(pm_peer_id_t prev_peer_id);
+
+
+/**@brief Function for getting the next peer ID in the sequence of all peer IDs pending deletion.
+ * Can be used to loop through all used peer IDs.
+ *
+ * @note @ref PM_PEER_ID_INVALID is considered to be before the first and after the last ordinary
+ * peer ID.
+ *
+ * @param[in] prev_peer_id The previous peer ID.
+ *
+ * @return The next peer ID pending deletion.
+ * @return The first ordinary peer ID if prev_peer_id was @ref PM_PEER_ID_INVALID.
+ * @retval PM_PEER_ID_INVALID if prev_peer_id was the last ordinary peer ID.
+ */
+pm_peer_id_t pdb_next_deleted_peer_id_get(pm_peer_id_t prev_peer_id);
+
+
+/**@brief Function for copy peer data from flash into a provided buffer.
+ *
+ * @param[in] peer_id The peer the data belongs to.
+ * @param[in] data_id The data to read.
+ * @param[inout] p_peer_data The buffer where to copy data into. The field @c length_words in this
+ * parameter must represent the buffer length in words.
+ *
+ * @note Actually, it represents the buffer length in bytes upon entering the function,
+ * and upon exit it represents the length of the data in words.. not good. Fix this.
+ *
+ * @retval NRF_SUCCESS If the operation was successful.
+ * @retval NRF_ERROR_INVALID_PARAM If @p peer_id or @p data_id are invalid.
+ * @retval NRF_ERROR_NOT_FOUND If the data was not found in flash.
+ * @retval NRF_ERROR_NO_MEM If the provided buffer is too small.
+ */
+ret_code_t pdb_peer_data_load(pm_peer_id_t peer_id,
+ pm_peer_data_id_t data_id,
+ pm_peer_data_t * const p_peer_data);
+
+
+/**@brief Function for writing data directly to persistent storage from external memory.
+ *
+ * @param[in] peer_id ID of peer to write data for.
+ * @param[in] p_peer_data Data to store.
+ * @param[out] p_store_token A token identifying this particular store operation. The token can be
+ * used to identify events pertaining to this operation.
+ *
+ * @retval NRF_SUCCESS Data successfully written.
+ * @retval NRF_ERROR_INVALID_PARAM Data ID or Peer ID was invalid or unallocated.
+ * @retval NRF_ERROR_NULL p_peer_data contained a NULL pointer.
+ * @retval NRF_ERROR_STORAGE_FULL No space available in persistent storage.
+ * @retval NRF_ERROR_INVALID_LENGTH Data length above the maximum allowed.
+ * @retval NRF_ERROR_BUSY Unable to perform operation at this time.
+ */
+ret_code_t pdb_raw_store(pm_peer_id_t peer_id,
+ pm_peer_data_const_t * p_peer_data,
+ pm_store_token_t * p_store_token);
+
+/** @}
+ * @endcond
+ */
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* PEER_DATABASE_H__ */
+
+
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/peer_manager/peer_id.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/peer_manager/peer_id.c
new file mode 100644
index 0000000..a5f5475
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/peer_manager/peer_id.c
@@ -0,0 +1,202 @@
+/**
+ * Copyright (c) 2015 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#include "sdk_common.h"
+#if NRF_MODULE_ENABLED(PEER_MANAGER)
+#include "peer_id.h"
+
+#include <stdint.h>
+#include <string.h>
+#include "sdk_errors.h"
+#include "peer_manager_types.h"
+#include "pm_mutex.h"
+
+
+typedef struct
+{
+ uint8_t used_peer_ids[MUTEX_STORAGE_SIZE(PM_PEER_ID_N_AVAILABLE_IDS)]; /**< Bitmap designating which peer IDs are in use. */
+ uint8_t deleted_peer_ids[MUTEX_STORAGE_SIZE(PM_PEER_ID_N_AVAILABLE_IDS)]; /**< Bitmap designating which peer IDs are marked for deletion. */
+} pi_t;
+
+
+static pi_t m_pi = {{0}, {0}};
+
+
+static void internal_state_reset(pi_t * p_pi)
+{
+ memset(p_pi, 0, sizeof(pi_t));
+}
+
+
+void peer_id_init(void)
+{
+ internal_state_reset(&m_pi);
+ pm_mutex_init(m_pi.used_peer_ids, PM_PEER_ID_N_AVAILABLE_IDS);
+ pm_mutex_init(m_pi.deleted_peer_ids, PM_PEER_ID_N_AVAILABLE_IDS);
+}
+
+
+static pm_peer_id_t claim(pm_peer_id_t peer_id, uint8_t * mutex_group)
+{
+ pm_peer_id_t allocated_peer_id = PM_PEER_ID_INVALID;
+ if (peer_id == PM_PEER_ID_INVALID)
+ {
+ allocated_peer_id = pm_mutex_lock_first_available(mutex_group, PM_PEER_ID_N_AVAILABLE_IDS);
+ if (allocated_peer_id == PM_PEER_ID_N_AVAILABLE_IDS)
+ {
+ allocated_peer_id = PM_PEER_ID_INVALID;
+ }
+ }
+ else if (peer_id < PM_PEER_ID_N_AVAILABLE_IDS)
+ {
+ bool lock_success = pm_mutex_lock(mutex_group, peer_id);
+ allocated_peer_id = lock_success ? peer_id : PM_PEER_ID_INVALID;
+ }
+ return allocated_peer_id;
+}
+
+
+static void release(pm_peer_id_t peer_id, uint8_t * mutex_group)
+{
+ if (peer_id < PM_PEER_ID_N_AVAILABLE_IDS)
+ {
+ pm_mutex_unlock(mutex_group, peer_id);
+ }
+}
+
+
+pm_peer_id_t peer_id_allocate(pm_peer_id_t peer_id)
+{
+ return claim(peer_id, m_pi.used_peer_ids);
+}
+
+
+bool peer_id_delete(pm_peer_id_t peer_id)
+{
+ pm_peer_id_t deleted_peer_id;
+
+ if (peer_id == PM_PEER_ID_INVALID)
+ {
+ return false;
+ }
+
+ deleted_peer_id = claim(peer_id, m_pi.deleted_peer_ids);
+
+ return (deleted_peer_id == peer_id);
+}
+
+
+void peer_id_free(pm_peer_id_t peer_id)
+{
+ release(peer_id, m_pi.used_peer_ids);
+ release(peer_id, m_pi.deleted_peer_ids);
+}
+
+
+bool peer_id_is_allocated(pm_peer_id_t peer_id)
+{
+ if (peer_id < PM_PEER_ID_N_AVAILABLE_IDS)
+ {
+ return pm_mutex_lock_status_get(m_pi.used_peer_ids, peer_id);
+ }
+ return false;
+}
+
+
+bool peer_id_is_deleted(pm_peer_id_t peer_id)
+{
+ if (peer_id < PM_PEER_ID_N_AVAILABLE_IDS)
+ {
+ return pm_mutex_lock_status_get(m_pi.deleted_peer_ids, peer_id);
+ }
+ return false;
+}
+
+
+pm_peer_id_t next_id_get(pm_peer_id_t prev_peer_id, uint8_t * mutex_group)
+{
+ pm_peer_id_t i = (prev_peer_id == PM_PEER_ID_INVALID) ? 0 : (prev_peer_id + 1);
+ for (; i < PM_PEER_ID_N_AVAILABLE_IDS; i++)
+ {
+ if (pm_mutex_lock_status_get(mutex_group, i))
+ {
+ return i;
+ }
+ }
+
+ return PM_PEER_ID_INVALID;
+}
+
+
+pm_peer_id_t peer_id_get_next_used(pm_peer_id_t peer_id)
+{
+ peer_id = next_id_get(peer_id, m_pi.used_peer_ids);
+
+ while (peer_id != PM_PEER_ID_INVALID)
+ {
+ if (!peer_id_is_deleted(peer_id))
+ {
+ return peer_id;
+ }
+
+ peer_id = next_id_get(peer_id, m_pi.used_peer_ids);
+ }
+
+ return peer_id;
+}
+
+
+pm_peer_id_t peer_id_get_next_deleted(pm_peer_id_t prev_peer_id)
+{
+ return next_id_get(prev_peer_id, m_pi.deleted_peer_ids);
+}
+
+
+uint32_t peer_id_n_ids(void)
+{
+ uint32_t n_ids = 0;
+
+ for (pm_peer_id_t i = 0; i < PM_PEER_ID_N_AVAILABLE_IDS; i++)
+ {
+ n_ids += pm_mutex_lock_status_get(m_pi.used_peer_ids, i);
+ }
+
+ return n_ids;
+}
+#endif // NRF_MODULE_ENABLED(PEER_MANAGER)
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/peer_manager/peer_id.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/peer_manager/peer_id.h
new file mode 100644
index 0000000..04c99ff
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/peer_manager/peer_id.h
@@ -0,0 +1,167 @@
+/**
+ * Copyright (c) 2015 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#ifndef PEER_ID_H__
+#define PEER_ID_H__
+
+
+#include <stdint.h>
+#include "sdk_errors.h"
+#include "ble_gap.h"
+#include "peer_manager_types.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+/**
+ * @cond NO_DOXYGEN
+ * @defgroup peer_id Peer IDs
+ * @ingroup peer_manager
+ * @{
+ * @brief An internal module of @ref peer_manager. This module keeps track of which peer IDs are in
+ * use and which are free.
+ */
+
+
+/**@brief Function for initializing the module.
+ */
+void peer_id_init(void);
+
+
+/**@brief Function for claiming an unused peer ID.
+ *
+ * @param peer_id The peer ID to allocate. If this is @ref PM_PEER_ID_INVALID, the first available
+ * will be allocated.
+ *
+ * @return The allocated peer ID.
+ * @retval PM_PEER_ID_INVALID If no peer ID could be allocated or module is not initialized.
+ */
+pm_peer_id_t peer_id_allocate(pm_peer_id_t peer_id);
+
+
+/**@brief Function for marking a peer ID for deletion.
+ *
+ * @param peer_id The peer ID to delete.
+ *
+ * @retval true Deletion was successful.
+ * @retval false Peer ID already marked for deletion, peer_id was PM_PEER_ID_INVALID, or module is
+ * not initialized.
+ */
+bool peer_id_delete(pm_peer_id_t peer_id);
+
+
+/**@brief Function for freeing a peer ID and clearing all data associated with it in persistent
+ * storage.
+ *
+ * @param[in] peer_id Peer ID to free.
+ */
+void peer_id_free(pm_peer_id_t peer_id);
+
+
+/**@brief Function for finding out whether a peer ID is marked for deletion.
+ *
+ * @param[in] peer_id The peer ID to inquire about.
+ *
+ * @retval true peer_id is in marked for deletion.
+ * @retval false peer_id is not marked for deletion, or the module is not initialized.
+ */
+bool peer_id_is_deleted(pm_peer_id_t peer_id);
+
+
+/**@brief Function for finding out whether a peer ID is in use.
+ *
+ * @param[in] peer_id The peer ID to inquire about.
+ *
+ * @retval true peer_id is in use.
+ * @retval false peer_id is free, or the module is not initialized.
+ */
+bool peer_id_is_allocated(pm_peer_id_t peer_id);
+
+
+/**@brief Function for getting the next peer ID in the sequence of all used peer IDs. Can be
+ * used to loop through all used peer IDs.
+ *
+ * @note @ref PM_PEER_ID_INVALID is considered to be before the first and after the last ordinary
+ * peer ID.
+ *
+ * @param[in] prev_peer_id The previous peer ID.
+ *
+ * @return The next peer ID.
+ * @return The first used peer ID if prev_peer_id was @ref PM_PEER_ID_INVALID.
+ * @retval PM_PEER_ID_INVALID if prev_peer_id was the last ordinary peer ID or the module is
+ * not initialized.
+ */
+pm_peer_id_t peer_id_get_next_used(pm_peer_id_t prev_peer_id);
+
+
+/**@brief Function for getting the next peer ID in the sequence of all peer IDs marked for deletion.
+ * Can be used to loop through all peer IDs marked for deletion.
+ *
+ * @note @ref PM_PEER_ID_INVALID is considered to be before the first and after the last ordinary
+ * peer ID.
+ *
+ * @param[in] prev_peer_id The previous peer ID.
+ *
+ * @return The next peer ID.
+ * @return The first used peer ID if prev_peer_id was @ref PM_PEER_ID_INVALID.
+ * @retval PM_PEER_ID_INVALID if prev_peer_id was the last ordinary peer ID or the module is
+ * not initialized.
+ */
+pm_peer_id_t peer_id_get_next_deleted(pm_peer_id_t prev_peer_id);
+
+
+/**@brief Function for querying the number of valid peer IDs available. I.E the number of peers
+ * in persistent storage.
+ *
+ * @return The number of valid peer IDs, or 0 if module is not initialized.
+ */
+uint32_t peer_id_n_ids(void);
+
+/** @}
+ * @endcond
+ */
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* PEER_ID_H__ */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/peer_manager/peer_manager.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/peer_manager/peer_manager.c
new file mode 100644
index 0000000..7de5793
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/peer_manager/peer_manager.c
@@ -0,0 +1,983 @@
+/**
+ * Copyright (c) 2015 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#include "sdk_common.h"
+#if NRF_MODULE_ENABLED(PEER_MANAGER)
+#include "ble_err.h"
+#include "peer_manager.h"
+#include <string.h>
+#include "security_manager.h"
+#include "security_dispatcher.h"
+#include "gatt_cache_manager.h"
+#include "gatts_cache_manager.h"
+#include "peer_database.h"
+#include "peer_data_storage.h"
+#include "id_manager.h"
+#include "ble_conn_state.h"
+#include "peer_manager_internal.h"
+#include "nrf_sdh_ble.h"
+
+#ifndef PM_PEER_RANKS_ENABLED
+ #define PM_PEER_RANKS_ENABLED 1
+#endif
+
+#define MODULE_INITIALIZED (m_module_initialized) /**< Macro indicating whether the module has been initialized properly. */
+
+
+static bool m_module_initialized; /**< Whether or not @ref pm_init has been called successfully. */
+static bool m_peer_rank_initialized; /**< Whether or not @ref rank_init has been called successfully. */
+static bool m_deleting_all; /**< True from when @ref pm_peers_delete is called until all peers have been deleted. */
+static pm_store_token_t m_peer_rank_token; /**< The store token of an ongoing peer rank update via a call to @ref pm_peer_rank_highest. If @ref PM_STORE_TOKEN_INVALID, there is no ongoing update. */
+static uint32_t m_current_highest_peer_rank; /**< The current highest peer rank. Used by @ref pm_peer_rank_highest. */
+static pm_peer_id_t m_highest_ranked_peer; /**< The peer with the highest peer rank. Used by @ref pm_peer_rank_highest. */
+static pm_evt_handler_t m_evt_handlers[PM_MAX_REGISTRANTS];/**< The subscribers to Peer Manager events, as registered through @ref pm_register. */
+static uint8_t m_n_registrants; /**< The number of event handlers registered through @ref pm_register. */
+
+
+/**@brief Function for sending a Peer Manager event to all subscribers.
+ *
+ * @param[in] p_pm_evt The event to send.
+ */
+static void evt_send(pm_evt_t const * p_pm_evt)
+{
+ for (int i = 0; i < m_n_registrants; i++)
+ {
+ m_evt_handlers[i](p_pm_evt);
+ }
+}
+
+
+#if PM_PEER_RANKS_ENABLED == 1
+/**@brief Function for initializing peer rank static variables.
+ */
+static void rank_vars_update(void)
+{
+ ret_code_t err_code = pm_peer_ranks_get(&m_highest_ranked_peer,
+ &m_current_highest_peer_rank,
+ NULL,
+ NULL);
+
+ m_peer_rank_initialized = ((err_code == NRF_SUCCESS) || (err_code == NRF_ERROR_NOT_FOUND));
+}
+#endif
+
+
+/**@brief Event handler for events from the Peer Database module.
+ * This handler is extern in the Peer Database module.
+ *
+ * @param[in] p_pdb_evt The incoming Peer Database event.
+ */
+void pm_pdb_evt_handler(pm_evt_t * p_pdb_evt)
+{
+ bool send_evt = true;
+
+ p_pdb_evt->conn_handle = im_conn_handle_get(p_pdb_evt->peer_id);
+
+ switch (p_pdb_evt->evt_id)
+ {
+#if PM_PEER_RANKS_ENABLED == 1
+ case PM_EVT_PEER_DATA_UPDATE_SUCCEEDED:
+ if (p_pdb_evt->params.peer_data_update_succeeded.action == PM_PEER_DATA_OP_UPDATE)
+ {
+ if ( (m_peer_rank_token != PM_STORE_TOKEN_INVALID)
+ && (m_peer_rank_token == p_pdb_evt->params.peer_data_update_succeeded.token))
+ {
+ m_peer_rank_token = PM_STORE_TOKEN_INVALID;
+ m_highest_ranked_peer = p_pdb_evt->peer_id;
+
+ p_pdb_evt->params.peer_data_update_succeeded.token = PM_STORE_TOKEN_INVALID;
+ }
+ else if ( m_peer_rank_initialized
+ && (p_pdb_evt->peer_id == m_highest_ranked_peer)
+ && (p_pdb_evt->params.peer_data_update_succeeded.data_id
+ == PM_PEER_DATA_ID_PEER_RANK))
+ {
+ // Update peer rank variable if highest ranked peer has changed its rank.
+ rank_vars_update();
+ }
+ }
+ else if (p_pdb_evt->params.peer_data_update_succeeded.action == PM_PEER_DATA_OP_DELETE)
+ {
+ if ( m_peer_rank_initialized
+ && (p_pdb_evt->peer_id == m_highest_ranked_peer)
+ && (p_pdb_evt->params.peer_data_update_succeeded.data_id == PM_PEER_DATA_ID_PEER_RANK))
+ {
+ // Update peer rank variable if highest ranked peer has deleted its rank.
+ rank_vars_update();
+ }
+ }
+ break;
+
+ case PM_EVT_PEER_DATA_UPDATE_FAILED:
+ if (p_pdb_evt->params.peer_data_update_succeeded.action == PM_PEER_DATA_OP_UPDATE)
+ {
+ if ( (m_peer_rank_token != PM_STORE_TOKEN_INVALID)
+ && (m_peer_rank_token == p_pdb_evt->params.peer_data_update_failed.token))
+ {
+ m_peer_rank_token = PM_STORE_TOKEN_INVALID;
+ m_current_highest_peer_rank -= 1;
+
+ p_pdb_evt->params.peer_data_update_succeeded.token = PM_STORE_TOKEN_INVALID;
+ }
+ }
+ break;
+#endif
+
+ case PM_EVT_PEER_DELETE_SUCCEEDED:
+ // Check that no peers marked for deletion are left.
+ if (m_deleting_all
+ && (pdb_next_peer_id_get(PM_PEER_ID_INVALID) == PM_PEER_ID_INVALID)
+ && (pdb_next_deleted_peer_id_get(PM_PEER_ID_INVALID) == PM_PEER_ID_INVALID))
+ {
+ // pm_peers_delete() has been called and this is the last peer to be deleted.
+ m_deleting_all = false;
+
+ pm_evt_t pm_delete_all_evt;
+ memset(&pm_delete_all_evt, 0, sizeof(pm_evt_t));
+ pm_delete_all_evt.evt_id = PM_EVT_PEERS_DELETE_SUCCEEDED;
+ pm_delete_all_evt.peer_id = PM_PEER_ID_INVALID;
+ pm_delete_all_evt.conn_handle = BLE_CONN_HANDLE_INVALID;
+
+ send_evt = false;
+
+ // Forward the event to all registered Peer Manager event handlers.
+ evt_send(p_pdb_evt); // Ensure that PEER_DELETE_SUCCEEDED arrives before PEERS_DELETE_SUCCEEDED.
+ evt_send(&pm_delete_all_evt);
+ }
+
+#if PM_PEER_RANKS_ENABLED == 1
+ if (m_peer_rank_initialized && (p_pdb_evt->peer_id == m_highest_ranked_peer))
+ {
+ // Update peer rank variable if highest ranked peer has been deleted.
+ rank_vars_update();
+ }
+#endif
+ break;
+
+ case PM_EVT_PEER_DELETE_FAILED:
+ if (m_deleting_all)
+ {
+ // pm_peers_delete() was called and has thus failed.
+
+ m_deleting_all = false;
+
+ pm_evt_t pm_delete_all_evt;
+ memset(&pm_delete_all_evt, 0, sizeof(pm_evt_t));
+ pm_delete_all_evt.evt_id = PM_EVT_PEERS_DELETE_FAILED;
+ pm_delete_all_evt.peer_id = PM_PEER_ID_INVALID;
+ pm_delete_all_evt.conn_handle = BLE_CONN_HANDLE_INVALID;
+ pm_delete_all_evt.params.peers_delete_failed_evt.error
+ = p_pdb_evt->params.peer_delete_failed.error;
+
+ send_evt = false;
+
+ // Forward the event to all registered Peer Manager event handlers.
+ evt_send(p_pdb_evt); // Ensure that PEER_DELETE_FAILED arrives before PEERS_DELETE_FAILED.
+ evt_send(&pm_delete_all_evt);
+ }
+ break;
+
+ default:
+ // Do nothing.
+ break;
+ }
+
+ if (send_evt)
+ {
+ // Forward the event to all registered Peer Manager event handlers.
+ evt_send(p_pdb_evt);
+ }
+}
+
+
+/**@brief Event handler for events from the Security Manager module.
+ * This handler is extern in the Security Manager module.
+ *
+ * @param[in] p_sm_evt The incoming Security Manager event.
+ */
+void pm_sm_evt_handler(pm_evt_t * p_sm_evt)
+{
+ VERIFY_PARAM_NOT_NULL_VOID(p_sm_evt);
+
+ // Forward the event to all registered Peer Manager event handlers.
+ evt_send(p_sm_evt);
+}
+
+
+/**@brief Event handler for events from the GATT Cache Manager module.
+ * This handler is extern in GATT Cache Manager.
+ *
+ * @param[in] p_gcm_evt The incoming GATT Cache Manager event.
+ */
+void pm_gcm_evt_handler(pm_evt_t * p_gcm_evt)
+{
+ // Forward the event to all registered Peer Manager event handlers.
+ evt_send(p_gcm_evt);
+}
+
+
+/**@brief Event handler for events from the ID Manager module.
+ * This function is registered in the ID Manager.
+ *
+ * @param[in] p_im_evt The incoming ID Manager event.
+ */
+void pm_im_evt_handler(pm_evt_t * p_im_evt)
+{
+ // Forward the event to all registered Peer Manager event handlers.
+ evt_send(p_im_evt);
+}
+
+/**
+ * @brief Function for handling BLE events.
+ *
+ * @param[in] p_ble_evt Event received from the BLE stack.
+ * @param[in] p_context Context.
+ */
+static void ble_evt_handler(ble_evt_t const * p_ble_evt, void * p_context)
+{
+ VERIFY_MODULE_INITIALIZED_VOID();
+
+ im_ble_evt_handler(p_ble_evt);
+ sm_ble_evt_handler(p_ble_evt);
+ gcm_ble_evt_handler(p_ble_evt);
+}
+
+NRF_SDH_BLE_OBSERVER(m_ble_evt_observer, PM_BLE_OBSERVER_PRIO, ble_evt_handler, NULL);
+
+
+/**@brief Function for resetting the internal state of this module.
+ */
+static void internal_state_reset()
+{
+ m_highest_ranked_peer = PM_PEER_ID_INVALID;
+ m_peer_rank_token = PM_STORE_TOKEN_INVALID;
+}
+
+
+ret_code_t pm_init(void)
+{
+ ret_code_t err_code;
+
+ err_code = pds_init();
+ if (err_code != NRF_SUCCESS)
+ {
+ return NRF_ERROR_INTERNAL;
+ }
+
+ err_code = pdb_init();
+ if (err_code != NRF_SUCCESS)
+ {
+ return NRF_ERROR_INTERNAL;
+ }
+
+ err_code = sm_init();
+ if (err_code != NRF_SUCCESS)
+ {
+ return NRF_ERROR_INTERNAL;
+ }
+
+ err_code = smd_init();
+ if (err_code != NRF_SUCCESS)
+ {
+ return NRF_ERROR_INTERNAL;
+ }
+
+ err_code = gcm_init();
+ if (err_code != NRF_SUCCESS)
+ {
+ return NRF_ERROR_INTERNAL;
+ }
+
+ err_code = gscm_init();
+ if (err_code != NRF_SUCCESS)
+ {
+ return NRF_ERROR_INTERNAL;
+ }
+
+ err_code = im_init();
+ if (err_code != NRF_SUCCESS)
+ {
+ return NRF_ERROR_INTERNAL;
+ }
+
+ internal_state_reset();
+
+ m_peer_rank_initialized = false;
+ m_module_initialized = true;
+
+ // If PM_PEER_RANKS_ENABLED is 0, these variables are unused.
+ UNUSED_VARIABLE(m_peer_rank_initialized);
+ UNUSED_VARIABLE(m_peer_rank_token);
+ UNUSED_VARIABLE(m_current_highest_peer_rank);
+ UNUSED_VARIABLE(m_highest_ranked_peer);
+
+ return NRF_SUCCESS;
+}
+
+
+ret_code_t pm_register(pm_evt_handler_t event_handler)
+{
+ VERIFY_MODULE_INITIALIZED();
+
+ if (m_n_registrants >= PM_MAX_REGISTRANTS)
+ {
+ return NRF_ERROR_NO_MEM;
+ }
+
+ m_evt_handlers[m_n_registrants] = event_handler;
+ m_n_registrants += 1;
+
+ return NRF_SUCCESS;
+}
+
+
+ret_code_t pm_sec_params_set(ble_gap_sec_params_t * p_sec_params)
+{
+ VERIFY_MODULE_INITIALIZED();
+
+ ret_code_t err_code;
+
+ err_code = sm_sec_params_set(p_sec_params);
+
+ // NRF_ERROR_INVALID_PARAM if parameters are invalid,
+ // NRF_SUCCESS otherwise.
+ return err_code;
+}
+
+
+ret_code_t pm_conn_secure(uint16_t conn_handle, bool force_repairing)
+{
+ VERIFY_MODULE_INITIALIZED();
+
+ ret_code_t err_code;
+
+ err_code = sm_link_secure(conn_handle, force_repairing);
+
+ if (err_code == NRF_ERROR_INVALID_STATE)
+ {
+ err_code = NRF_ERROR_BUSY;
+ }
+
+ return err_code;
+}
+
+
+void pm_conn_sec_config_reply(uint16_t conn_handle, pm_conn_sec_config_t * p_conn_sec_config)
+{
+ if (p_conn_sec_config != NULL)
+ {
+ sm_conn_sec_config_reply(conn_handle, p_conn_sec_config);
+ }
+}
+
+
+ret_code_t pm_conn_sec_params_reply(uint16_t conn_handle,
+ ble_gap_sec_params_t * p_sec_params,
+ void const * p_context)
+{
+ VERIFY_MODULE_INITIALIZED();
+
+ return sm_sec_params_reply(conn_handle, p_sec_params, p_context);
+}
+
+
+void pm_local_database_has_changed(void)
+{
+#if !defined(PM_SERVICE_CHANGED_ENABLED) || (PM_SERVICE_CHANGED_ENABLED == 1)
+ VERIFY_MODULE_INITIALIZED_VOID();
+
+ gcm_local_database_has_changed();
+#endif
+}
+
+
+ret_code_t pm_id_addr_set(ble_gap_addr_t const * p_addr)
+{
+ VERIFY_MODULE_INITIALIZED();
+ return im_id_addr_set(p_addr);
+}
+
+
+ret_code_t pm_id_addr_get(ble_gap_addr_t * p_addr)
+{
+ VERIFY_MODULE_INITIALIZED();
+ VERIFY_PARAM_NOT_NULL(p_addr);
+ return im_id_addr_get(p_addr);
+}
+
+
+ret_code_t pm_privacy_set(pm_privacy_params_t const * p_privacy_params)
+{
+ VERIFY_MODULE_INITIALIZED();
+ VERIFY_PARAM_NOT_NULL(p_privacy_params);
+ return im_privacy_set(p_privacy_params);
+}
+
+
+ret_code_t pm_privacy_get(pm_privacy_params_t * p_privacy_params)
+{
+ VERIFY_MODULE_INITIALIZED();
+ VERIFY_PARAM_NOT_NULL(p_privacy_params);
+ VERIFY_PARAM_NOT_NULL(p_privacy_params->p_device_irk);
+ return im_privacy_get(p_privacy_params);
+}
+
+
+bool pm_address_resolve(ble_gap_addr_t const * p_addr, ble_gap_irk_t const * p_irk)
+{
+ VERIFY_MODULE_INITIALIZED();
+
+ if ((p_addr == NULL) || (p_irk == NULL))
+ {
+ return false;
+ }
+ else
+ {
+ return im_address_resolve(p_addr, p_irk);
+ }
+}
+
+
+ret_code_t pm_whitelist_set(pm_peer_id_t const * p_peers,
+ uint32_t peer_cnt)
+{
+ VERIFY_MODULE_INITIALIZED();
+ return im_whitelist_set(p_peers, peer_cnt);
+}
+
+
+ret_code_t pm_whitelist_get(ble_gap_addr_t * p_addrs,
+ uint32_t * p_addr_cnt,
+ ble_gap_irk_t * p_irks,
+ uint32_t * p_irk_cnt)
+{
+ VERIFY_MODULE_INITIALIZED();
+
+ if (((p_addrs == NULL) && (p_irks == NULL)) ||
+ ((p_addrs != NULL) && (p_addr_cnt == NULL)) ||
+ ((p_irks != NULL) && (p_irk_cnt == NULL)))
+ {
+ // The buffers can't be both NULL, and if a buffer is provided its size must be specified.
+ return NRF_ERROR_NULL;
+ }
+
+ return im_whitelist_get(p_addrs, p_addr_cnt, p_irks, p_irk_cnt);
+}
+
+
+ret_code_t pm_device_identities_list_set(pm_peer_id_t const * p_peers,
+ uint32_t peer_cnt)
+{
+ VERIFY_MODULE_INITIALIZED();
+ return im_device_identities_list_set(p_peers, peer_cnt);
+}
+
+
+ret_code_t pm_conn_sec_status_get(uint16_t conn_handle, pm_conn_sec_status_t * p_conn_sec_status)
+{
+ VERIFY_MODULE_INITIALIZED();
+ VERIFY_PARAM_NOT_NULL(p_conn_sec_status);
+
+ ble_conn_state_status_t status = ble_conn_state_status(conn_handle);
+
+ if (status == BLE_CONN_STATUS_INVALID)
+ {
+ return BLE_ERROR_INVALID_CONN_HANDLE;
+ }
+
+ p_conn_sec_status->connected = (status == BLE_CONN_STATUS_CONNECTED);
+ p_conn_sec_status->bonded = (im_peer_id_get_by_conn_handle(conn_handle) != PM_PEER_ID_INVALID);
+ p_conn_sec_status->encrypted = ble_conn_state_encrypted(conn_handle);
+ p_conn_sec_status->mitm_protected = ble_conn_state_mitm_protected(conn_handle);
+ return NRF_SUCCESS;
+}
+
+
+ret_code_t pm_lesc_public_key_set(ble_gap_lesc_p256_pk_t * p_public_key)
+{
+ VERIFY_MODULE_INITIALIZED();
+ return sm_lesc_public_key_set(p_public_key);
+}
+
+
+ret_code_t pm_conn_handle_get(pm_peer_id_t peer_id, uint16_t * p_conn_handle)
+{
+ VERIFY_MODULE_INITIALIZED();
+ VERIFY_PARAM_NOT_NULL(p_conn_handle);
+ *p_conn_handle = im_conn_handle_get(peer_id);
+ return NRF_SUCCESS;
+}
+
+
+ret_code_t pm_peer_id_get(uint16_t conn_handle, pm_peer_id_t * p_peer_id)
+{
+ VERIFY_MODULE_INITIALIZED();
+ VERIFY_PARAM_NOT_NULL(p_peer_id);
+ *p_peer_id = im_peer_id_get_by_conn_handle(conn_handle);
+ return NRF_SUCCESS;
+}
+
+
+uint32_t pm_peer_count(void)
+{
+ if (!MODULE_INITIALIZED)
+ {
+ return 0;
+ }
+ return pdb_n_peers();
+}
+
+
+pm_peer_id_t pm_next_peer_id_get(pm_peer_id_t prev_peer_id)
+{
+ if (!MODULE_INITIALIZED)
+ {
+ return PM_PEER_ID_INVALID;
+ }
+ return pdb_next_peer_id_get(prev_peer_id);
+}
+
+
+ret_code_t pm_peer_data_load(pm_peer_id_t peer_id,
+ pm_peer_data_id_t data_id,
+ void * p_data,
+ uint16_t * p_length)
+{
+ VERIFY_MODULE_INITIALIZED();
+ VERIFY_PARAM_NOT_NULL(p_data);
+ VERIFY_PARAM_NOT_NULL(p_length);
+ if (ALIGN_NUM(4, *p_length) != *p_length)
+ {
+ return NRF_ERROR_INVALID_PARAM;
+ }
+
+ pm_peer_data_t peer_data;
+ memset(&peer_data, 0, sizeof(peer_data));
+ peer_data.length_words = BYTES_TO_WORDS(*p_length);
+ peer_data.data_id = data_id;
+ peer_data.p_all_data = p_data;
+
+ ret_code_t err_code = pdb_peer_data_load(peer_id, data_id, &peer_data);
+
+ *p_length = peer_data.length_words * BYTES_PER_WORD;
+
+ return err_code;
+}
+
+
+ret_code_t pm_peer_data_bonding_load(pm_peer_id_t peer_id,
+ pm_peer_data_bonding_t * p_data)
+{
+ uint16_t length = sizeof(pm_peer_data_bonding_t);
+ return pm_peer_data_load(peer_id,
+ PM_PEER_DATA_ID_BONDING,
+ p_data,
+ &length);
+}
+
+
+ret_code_t pm_peer_data_remote_db_load(pm_peer_id_t peer_id,
+ ble_gatt_db_srv_t * p_data,
+ uint16_t * p_length)
+{
+ return pm_peer_data_load(peer_id,
+ PM_PEER_DATA_ID_GATT_REMOTE,
+ p_data,
+ p_length);
+}
+
+
+ret_code_t pm_peer_data_app_data_load(pm_peer_id_t peer_id,
+ void * p_data,
+ uint16_t * p_length)
+{
+ return pm_peer_data_load(peer_id,
+ PM_PEER_DATA_ID_APPLICATION,
+ p_data,
+ p_length);
+}
+
+
+ret_code_t pm_peer_data_store(pm_peer_id_t peer_id,
+ pm_peer_data_id_t data_id,
+ void const * p_data,
+ uint16_t length,
+ pm_store_token_t * p_token)
+{
+ VERIFY_MODULE_INITIALIZED();
+ VERIFY_PARAM_NOT_NULL(p_data);
+ if (ALIGN_NUM(4, length) != length)
+ {
+ return NRF_ERROR_INVALID_PARAM;
+ }
+
+ if (data_id == PM_PEER_DATA_ID_BONDING)
+ {
+ pm_peer_id_t dupl_peer_id;
+ dupl_peer_id = im_find_duplicate_bonding_data((pm_peer_data_bonding_t *) p_data, peer_id);
+
+ if (dupl_peer_id != PM_PEER_ID_INVALID)
+ {
+ return NRF_ERROR_FORBIDDEN;
+ }
+ }
+
+ pm_peer_data_flash_t peer_data;
+ memset(&peer_data, 0, sizeof(peer_data));
+ peer_data.length_words = BYTES_TO_WORDS(length);
+ peer_data.data_id = data_id;
+ peer_data.p_all_data = p_data;
+
+ return pdb_raw_store(peer_id, &peer_data, p_token);
+}
+
+
+ret_code_t pm_peer_data_bonding_store(pm_peer_id_t peer_id,
+ pm_peer_data_bonding_t const * p_data,
+ pm_store_token_t * p_token)
+{
+ return pm_peer_data_store(peer_id,
+ PM_PEER_DATA_ID_BONDING,
+ p_data,
+ ALIGN_NUM(4, sizeof(pm_peer_data_bonding_t)),
+ p_token);
+}
+
+
+ret_code_t pm_peer_data_remote_db_store(pm_peer_id_t peer_id,
+ ble_gatt_db_srv_t const * p_data,
+ uint16_t length,
+ pm_store_token_t * p_token)
+{
+ return pm_peer_data_store(peer_id,
+ PM_PEER_DATA_ID_GATT_REMOTE,
+ p_data,
+ length,
+ p_token);
+}
+
+
+ret_code_t pm_peer_data_app_data_store(pm_peer_id_t peer_id,
+ void const * p_data,
+ uint16_t length,
+ pm_store_token_t * p_token)
+{
+ return pm_peer_data_store(peer_id,
+ PM_PEER_DATA_ID_APPLICATION,
+ p_data,
+ length,
+ p_token);
+}
+
+
+ret_code_t pm_peer_data_delete(pm_peer_id_t peer_id, pm_peer_data_id_t data_id)
+{
+ VERIFY_MODULE_INITIALIZED();
+
+ if (data_id == PM_PEER_DATA_ID_BONDING)
+ {
+ return NRF_ERROR_INVALID_PARAM;
+ }
+
+ return pdb_clear(peer_id, data_id);
+}
+
+
+ret_code_t pm_peer_new(pm_peer_id_t * p_new_peer_id,
+ pm_peer_data_bonding_t * p_bonding_data,
+ pm_store_token_t * p_token)
+{
+ ret_code_t err_code;
+ pm_peer_id_t peer_id;
+ pm_peer_data_flash_t peer_data;
+
+ VERIFY_MODULE_INITIALIZED();
+ VERIFY_PARAM_NOT_NULL(p_bonding_data);
+ VERIFY_PARAM_NOT_NULL(p_new_peer_id);
+
+ memset(&peer_data, 0, sizeof(pm_peer_data_flash_t));
+
+ // Search through existing bonds to look for a duplicate.
+ pds_peer_data_iterate_prepare();
+
+ // @note emdi: should maybe use a critical section, since data is not copied while iterating.
+ while (pds_peer_data_iterate(PM_PEER_DATA_ID_BONDING, &peer_id, &peer_data))
+ {
+ if (im_is_duplicate_bonding_data(p_bonding_data, peer_data.p_bonding_data))
+ {
+ *p_new_peer_id = peer_id;
+ return NRF_SUCCESS;
+ }
+ }
+
+ // If no duplicate data is found, prepare to write a new bond to flash.
+
+ *p_new_peer_id = pdb_peer_allocate();
+
+ if (*p_new_peer_id == PM_PEER_ID_INVALID)
+ {
+ return NRF_ERROR_NO_MEM;
+ }
+
+ memset(&peer_data, 0, sizeof(pm_peer_data_flash_t));
+
+ peer_data.data_id = PM_PEER_DATA_ID_BONDING;
+ peer_data.p_bonding_data = p_bonding_data;
+ peer_data.length_words = BYTES_TO_WORDS(sizeof(pm_peer_data_bonding_t));
+
+ err_code = pdb_raw_store(*p_new_peer_id, &peer_data, p_token);
+
+ if (err_code != NRF_SUCCESS)
+ {
+ if (im_peer_free(*p_new_peer_id) != NRF_SUCCESS)
+ {
+ return NRF_ERROR_INTERNAL;
+ }
+
+ // NRF_ERROR_STORAGE_FULL, if no space in flash.
+ // NRF_ERROR_BUSY, if flash filesystem was busy.
+ // NRF_ERROR_INTENRAL, on internal error.
+ return err_code;
+ }
+
+ return NRF_SUCCESS;
+}
+
+
+ret_code_t pm_peer_delete(pm_peer_id_t peer_id)
+{
+ VERIFY_MODULE_INITIALIZED();
+
+ return im_peer_free(peer_id);
+}
+
+
+ret_code_t pm_peers_delete(void)
+{
+ VERIFY_MODULE_INITIALIZED();
+
+ m_deleting_all = true;
+
+ pm_peer_id_t current_peer_id = pdb_next_peer_id_get(PM_PEER_ID_INVALID);
+
+ if (current_peer_id == PM_PEER_ID_INVALID)
+ {
+ // No peers bonded.
+ m_deleting_all = false;
+
+ pm_evt_t pm_delete_all_evt;
+ memset(&pm_delete_all_evt, 0, sizeof(pm_evt_t));
+ pm_delete_all_evt.evt_id = PM_EVT_PEERS_DELETE_SUCCEEDED;
+ pm_delete_all_evt.peer_id = PM_PEER_ID_INVALID;
+ pm_delete_all_evt.conn_handle = BLE_CONN_HANDLE_INVALID;
+
+ evt_send(&pm_delete_all_evt);
+ }
+
+ while (current_peer_id != PM_PEER_ID_INVALID)
+ {
+ ret_code_t err_code = pm_peer_delete(current_peer_id);
+ if (err_code != NRF_SUCCESS)
+ {
+ return NRF_ERROR_INTERNAL;
+ }
+
+ current_peer_id = pdb_next_peer_id_get(current_peer_id);
+ }
+
+ return NRF_SUCCESS;
+}
+
+
+ret_code_t pm_peer_ranks_get(pm_peer_id_t * p_highest_ranked_peer,
+ uint32_t * p_highest_rank,
+ pm_peer_id_t * p_lowest_ranked_peer,
+ uint32_t * p_lowest_rank)
+{
+#if PM_PEER_RANKS_ENABLED == 0
+ return NRF_ERROR_NOT_SUPPORTED;
+#else
+ VERIFY_MODULE_INITIALIZED();
+
+ pm_peer_id_t peer_id = pdb_next_peer_id_get(PM_PEER_ID_INVALID);
+ uint32_t peer_rank = 0;
+ //lint -save -e65 -e64
+ pm_peer_data_t peer_data = {.length_words = BYTES_TO_WORDS(sizeof(peer_rank)),
+ .p_peer_rank = &peer_rank};
+ //lint -restore
+ ret_code_t err_code = pdb_peer_data_load(peer_id, PM_PEER_DATA_ID_PEER_RANK, &peer_data);
+ uint32_t highest_rank = 0;
+ uint32_t lowest_rank = 0xFFFFFFFF;
+ pm_peer_id_t highest_ranked_peer = PM_PEER_ID_INVALID;
+ pm_peer_id_t lowest_ranked_peer = PM_PEER_ID_INVALID;
+
+ if (err_code == NRF_ERROR_INVALID_PARAM)
+ {
+ // No peer IDs exist.
+ return NRF_ERROR_NOT_FOUND;
+ }
+
+ while ((err_code == NRF_SUCCESS) || (err_code == NRF_ERROR_NOT_FOUND))
+ {
+ if (err_code == NRF_ERROR_NOT_FOUND)
+ {
+ peer_rank = 0;
+ }
+ if (peer_rank >= highest_rank)
+ {
+ highest_rank = peer_rank;
+ highest_ranked_peer = peer_id;
+ }
+ if (peer_rank < lowest_rank)
+ {
+ lowest_rank = peer_rank;
+ lowest_ranked_peer = peer_id;
+ }
+ peer_id = pdb_next_peer_id_get(peer_id);
+ err_code = pdb_peer_data_load(peer_id, PM_PEER_DATA_ID_PEER_RANK, &peer_data);
+ }
+ if (peer_id == PM_PEER_ID_INVALID)
+ {
+ err_code = NRF_SUCCESS;
+ if (p_highest_ranked_peer != NULL)
+ {
+ *p_highest_ranked_peer = highest_ranked_peer;
+ }
+ if (p_highest_rank != NULL)
+ {
+ *p_highest_rank = highest_rank;
+ }
+ if (p_lowest_ranked_peer != NULL)
+ {
+ *p_lowest_ranked_peer = lowest_ranked_peer;
+ }
+ if (p_lowest_rank != NULL)
+ {
+ *p_lowest_rank = lowest_rank;
+ }
+ }
+ else
+ {
+ err_code = NRF_ERROR_INTERNAL;
+ }
+ return err_code;
+#endif
+}
+
+
+#if PM_PEER_RANKS_ENABLED == 1
+/**@brief Function for initializing peer rank functionality.
+ */
+static void rank_init(void)
+{
+ rank_vars_update();
+}
+#endif
+
+
+ret_code_t pm_peer_rank_highest(pm_peer_id_t peer_id)
+{
+#if PM_PEER_RANKS_ENABLED == 0
+ return NRF_ERROR_NOT_SUPPORTED;
+#else
+ VERIFY_MODULE_INITIALIZED();
+
+ ret_code_t err_code;
+ //lint -save -e65 -e64
+ pm_peer_data_flash_t peer_data = {.length_words = BYTES_TO_WORDS(sizeof(m_current_highest_peer_rank)),
+ .data_id = PM_PEER_DATA_ID_PEER_RANK,
+ .p_peer_rank = &m_current_highest_peer_rank};
+ //lint -restore
+
+
+ if (!m_peer_rank_initialized)
+ {
+ rank_init();
+ }
+
+ if (!m_peer_rank_initialized || (m_peer_rank_token != PM_STORE_TOKEN_INVALID))
+ {
+ err_code = NRF_ERROR_BUSY;
+ }
+ else
+ {
+ if ((peer_id == m_highest_ranked_peer) && (m_current_highest_peer_rank > 0))
+ {
+ pm_evt_t pm_evt;
+
+ // The reported peer is already regarded as highest (provided it has an index at all)
+ err_code = NRF_SUCCESS;
+
+ memset(&pm_evt, 0, sizeof(pm_evt));
+ pm_evt.evt_id = PM_EVT_PEER_DATA_UPDATE_SUCCEEDED;
+ pm_evt.conn_handle = im_conn_handle_get(peer_id);
+ pm_evt.peer_id = peer_id;
+ pm_evt.params.peer_data_update_succeeded.data_id = PM_PEER_DATA_ID_PEER_RANK;
+ pm_evt.params.peer_data_update_succeeded.action = PM_PEER_DATA_OP_UPDATE;
+ pm_evt.params.peer_data_update_succeeded.token = PM_STORE_TOKEN_INVALID;
+ pm_evt.params.peer_data_update_succeeded.flash_changed = false;
+
+ evt_send(&pm_evt);
+ }
+ else
+ {
+ if (m_current_highest_peer_rank == UINT32_MAX)
+ {
+ err_code = NRF_ERROR_RESOURCES;
+ }
+ else
+ {
+ m_current_highest_peer_rank += 1;
+ err_code = pdb_raw_store(peer_id, &peer_data, &m_peer_rank_token);
+ if (err_code != NRF_SUCCESS)
+ {
+ m_peer_rank_token = PM_STORE_TOKEN_INVALID;
+ m_current_highest_peer_rank -= 1;
+ {
+ if ((err_code != NRF_ERROR_BUSY) && (err_code != NRF_ERROR_STORAGE_FULL))
+ err_code = NRF_ERROR_INTERNAL;
+ }
+ }
+ }
+ }
+ }
+ return err_code;
+#endif
+}
+#endif // NRF_MODULE_ENABLED(PEER_MANAGER)
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/peer_manager/peer_manager.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/peer_manager/peer_manager.h
new file mode 100644
index 0000000..c320101
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/peer_manager/peer_manager.h
@@ -0,0 +1,781 @@
+/**
+ * Copyright (c) 2015 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 peer_manager.h
+ *
+ * @defgroup peer_manager Peer Manager
+ * @ingroup ble_sdk_lib
+ * @{
+ * @brief Module for managing BLE bonding, which includes controlling encryption and pairing
+ * procedures as well as persistently storing different pieces of data that must be stored
+ * when bonded.
+ *
+ * @details The API consists of functions for configuring the pairing and encryption behavior of the
+ * device and functions for manipulating the stored data.
+ *
+ * This module uses Flash Data Storage (FDS) to interface with persistent storage. The
+ * Peer Manager needs exclusive use of certain FDS file IDs and record keys. See
+ * @ref lib_fds_functionality_keys for more information.
+ */
+
+
+#ifndef PEER_MANAGER_H__
+#define PEER_MANAGER_H__
+
+#include <stdint.h>
+#include <stdbool.h>
+#include "sdk_common.h"
+#include "ble.h"
+#include "ble_gap.h"
+#include "peer_manager_types.h"
+#include "peer_database.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+
+/**@brief Security status of a connection.
+ */
+typedef struct
+{
+ uint8_t connected : 1; /**< @brief The connection is active (not disconnected). */
+ uint8_t encrypted : 1; /**< @brief Communication on this link is encrypted. */
+ uint8_t mitm_protected : 1; /**< @brief The encrypted communication is also protected against man-in-the-middle attacks. */
+ uint8_t bonded : 1; /**< @brief The peer is bonded with us. */
+} pm_conn_sec_status_t;
+
+
+/**@brief Function for initializing the Peer Manager.
+ *
+ * @details You must initialize the Peer Manager before you can call any other Peer Manager
+ * functions.
+ *
+ * @retval NRF_SUCCESS If initialization was successful.
+ * @retval NRF_ERROR_INTERNAL If an internal error occurred.
+ */
+ret_code_t pm_init(void);
+
+
+/**@brief Function for registering an event handler with the Peer Manager.
+ *
+ * @param[in] event_handler Callback for events from the @ref peer_manager module. @p event_handler
+ * is called for every event that the Peer Manager sends after this
+ * function is called.
+ *
+ * @retval NRF_SUCCESS If initialization was successful.
+ * @retval NRF_ERROR_NULL If @p event_handler was NULL.
+ * @retval NRF_ERROR_NO_MEM If no more registrations can happen.
+ * @retval NRF_ERROR_INVALID_STATE If the Peer Manager is not initialized.
+ */
+ret_code_t pm_register(pm_evt_handler_t event_handler);
+
+
+/**@brief Function for providing pairing and bonding parameters to use for pairing procedures.
+ *
+ * @details Until this function is called, all bonding procedures that are initiated by the
+ * peer are rejected.
+ *
+ * This function can be called multiple times with different parameters, even with NULL as
+ * @p p_sec_params, in which case the Peer Manager starts rejecting all procedures again.
+ *
+ * @param[in] p_sec_params Security parameters to be used for subsequent security procedures.
+ *
+ * @retval NRF_SUCCESS If the parameters were set successfully.
+ * @retval NRF_ERROR_INVALID_PARAM If the combination of parameters is invalid.
+ * @retval NRF_ERROR_INVALID_STATE If the Peer Manager is not initialized.
+ * @retval NRF_ERROR_INTERNAL If an internal error occurred.
+ */
+ret_code_t pm_sec_params_set(ble_gap_sec_params_t * p_sec_params);
+
+
+/**@brief Function for establishing encryption on a connection, and optionally establishing a bond.
+ *
+ * @details This function attempts to secure the link that is specified by @p conn_handle. It uses
+ * the parameters that were previously provided in a call to @ref pm_sec_params_set.
+ *
+ * If the connection is a master connection, calling this function starts a security
+ * procedure on the link. If we have keys from a previous bonding procedure with this peer
+ * and the keys meet the security requirements in the currently active security parameters,
+ * the function attempts to establish encryption with the existing keys. If no key exists,
+ * the function attempts to perform pairing and bonding according to the currently active
+ * security parameters.
+ *
+ * If the function completes successfully, a @ref PM_EVT_CONN_SEC_START event is sent.
+ * The procedure might be queued, in which case the @ref PM_EVT_CONN_SEC_START event is
+ * delayed until the procedure is initiated in the SoftDevice.
+ *
+ * If the connection is a slave connection, the function sends a security request to
+ * the peer (master). It is up to the peer then to initiate pairing or encryption.
+ * If the peer ignores the request, a @ref BLE_GAP_EVT_AUTH_STATUS event occurs
+ * with the status @ref BLE_GAP_SEC_STATUS_TIMEOUT. Otherwise, the peer initiates
+ * security, in which case things happen as if the peer had initiated security itself.
+ * See @ref PM_EVT_CONN_SEC_START for information about peer-initiated security.
+ *
+ * @param[in] conn_handle Connection handle of the link as provided by the SoftDevice.
+ * @param[in] force_repairing Whether to force a pairing procedure even if there is an existing
+ * encryption key. This argument is relevant only for
+ * the central role. Recommended value: false.
+ *
+ * @retval NRF_SUCCESS If the operation completed successfully.
+ * @retval NRF_ERROR_BUSY If a security procedure is already in progress on the link,
+ * or if the link is disconnecting or disconnected.
+ * @retval NRF_ERROR_TIMEOUT If there was an SMP time-out, so that no more security
+ * operations can be performed on this link.
+ * @retval BLE_ERROR_INVALID_CONN_HANDLE If the connection handle is invalid.
+ * @retval NRF_ERROR_NOT_FOUND If the security parameters have not been set, either by
+ * @ref pm_sec_params_set or by @ref pm_conn_sec_params_reply.
+ * @retval NRF_ERROR_INVALID_DATA If the peer is bonded, but no LTK was found in the stored
+ * bonding data. Repairing was not requested.
+ * @retval NRF_ERROR_STORAGE_FULL If there is no more space in persistent storage.
+ * @retval NRF_ERROR_NO_MEM If no more authentication procedures can run in parallel
+ * for the given role. See @ref sd_ble_gap_authenticate.
+ * @retval NRF_ERROR_INVALID_STATE If the Peer Manager is not initialized.
+ * @retval NRF_ERROR_INTERNAL If an internal error occurred.
+ */
+ret_code_t pm_conn_secure(uint16_t conn_handle, bool force_repairing);
+
+
+/**@brief Function for providing security configuration for a link.
+ *
+ * @details This function is optional, and must be called in reply to a @ref
+ * PM_EVT_CONN_SEC_CONFIG_REQ event, before the Peer Manager event handler returns. If it
+ * is not called in time, a default configuration is used. See @ref pm_conn_sec_config_t
+ * for the value of the default.
+ *
+ * @param[in] conn_handle The connection to set the configuration for.
+ * @param[in] p_conn_sec_config The configuration.
+ */
+void pm_conn_sec_config_reply(uint16_t conn_handle, pm_conn_sec_config_t * p_conn_sec_config);
+
+
+/**@brief Function for providing security parameters for a link.
+ *
+ * @details This function is optional, and must be called in reply to a @ref
+ * PM_EVT_CONN_SEC_PARAMS_REQ event, before the Peer Manager event handler returns. If it
+ * is not called in time, the parameters given in @ref pm_sec_params_set are used. See @ref
+ * pm_conn_sec_config_t for the value of the default.
+ *
+ * @param[in] conn_handle The connection to set the parameters for.
+ * @param[in] p_sec_params The parameters. If NULL, the security procedure is rejected.
+ * @param[in] p_context The context found in the request event that this function replies to.
+ *
+ * @retval NRF_SUCCESS Successful reply.
+ * @retval NRF_ERROR_NULL p_sec_params or p_context was null.
+ * @retval NRF_ERROR_INVALID_PARAM Value of p_sec_params was invalid.
+ * @retval NRF_ERROR_INVALID_STATE This module is not initialized.
+ */
+ret_code_t pm_conn_sec_params_reply(uint16_t conn_handle,
+ ble_gap_sec_params_t * p_sec_params,
+ void const * p_context);
+
+
+/**@brief Function for manually informing that the local database has changed.
+ *
+ * @details This function sends a service changed indication to all bonded and/or connected peers
+ * that subscribe to this indication. If a bonded peer is not connected, the indication is
+ * sent when it reconnects. Every time an indication is sent, a @ref
+ * PM_EVT_SERVICE_CHANGED_IND_SENT event occurs, followed by a @ref
+ * PM_EVT_SERVICE_CHANGED_IND_CONFIRMED when the peer sends its confirmation. Peers that
+ * are not subscribed to the service changed indication when this function is called do not
+ * receive an indication, and no events are sent to the user. Likewise, if the service
+ * changed characteristic is not present in the local database, or if the @ref
+ * PM_SERVICE_CHANGED_ENABLED is set to 0, no indications are sent peers, and no events are
+ * sent to the user.
+ */
+void pm_local_database_has_changed(void);
+
+
+/**@brief Function for getting the security status of a connection.
+ *
+ * @param[in] conn_handle Connection handle of the link as provided by the SoftDevice.
+ * @param[out] p_conn_sec_status Security status of the link.
+ *
+ * @retval NRF_SUCCESS If pairing was initiated successfully.
+ * @retval BLE_ERROR_INVALID_CONN_HANDLE If the connection handle is invalid.
+ * @retval NRF_ERROR_NULL If @p p_conn_sec_status was NULL.
+ * @retval NRF_ERROR_INVALID_STATE If the Peer Manager is not initialized.
+ */
+ret_code_t pm_conn_sec_status_get(uint16_t conn_handle, pm_conn_sec_status_t * p_conn_sec_status);
+
+
+/**@brief Experimental function for specifying the public key to use for LESC operations.
+ *
+ * @details This function can be called multiple times. The specified public key will be used for
+ * all subsequent LESC (LE Secure Connections) operations until the next time this function
+ * is called.
+ *
+ * @note The key must continue to reside in application memory as it is not copied by Peer Manager.
+ *
+ * @param[in] p_public_key The public key to use for all subsequent LESC operations.
+ *
+ * @retval NRF_SUCCESS If pairing was initiated successfully.
+ * @retval NRF_ERROR_INVALID_STATE If the Peer Manager is not initialized.
+ */
+ret_code_t pm_lesc_public_key_set(ble_gap_lesc_p256_pk_t * p_public_key);
+
+
+/**@brief Function for setting or clearing the whitelist.
+ *
+ * When using the S13x SoftDevice v3.x, this function sets or clears the whitelist.
+ * When using the S13x SoftDevice v2.x, this function caches a list of
+ * peers that can be retrieved later by @ref pm_whitelist_get to pass to the @ref lib_ble_advertising.
+ *
+ * To clear the current whitelist, pass either NULL as @p p_peers or zero as @p peer_cnt.
+ *
+ * @param[in] p_peers The peers to add to the whitelist. Pass NULL to clear the current whitelist.
+ * @param[in] peer_cnt The number of peers to add to the whitelist. The number must not be greater than
+ * @ref BLE_GAP_WHITELIST_ADDR_MAX_COUNT. Pass zero to clear the current
+ * whitelist.
+ *
+ * @retval NRF_SUCCESS If the whitelist was successfully set or cleared.
+ * @retval BLE_GAP_ERROR_WHITELIST_IN_USE If a whitelist is already in use and cannot be set.
+ * @retval BLE_ERROR_GAP_INVALID_BLE_ADDR If a peer in @p p_peers has an address that cannot
+ * be used for whitelisting.
+ * @retval NRF_ERROR_NOT_FOUND If any of the peers in @p p_peers cannot be found.
+ * @retval NRF_ERROR_DATA_SIZE If @p peer_cnt is greater than
+ * @ref BLE_GAP_WHITELIST_ADDR_MAX_COUNT.
+ * @retval NRF_ERROR_INVALID_STATE If the Peer Manager is not initialized.
+ */
+ret_code_t pm_whitelist_set(pm_peer_id_t const * p_peers,
+ uint32_t peer_cnt);
+
+
+/**@brief Function for retrieving the previously set whitelist.
+ *
+ * The function retrieves the whitelist of GAP addresses and IRKs that was
+ * previously set by @ref pm_whitelist_set.
+ *
+ * To retrieve only GAP addresses or only IRKs, provide only one of the
+ * buffers. If a buffer is provided, its size must be specified.
+ *
+ * @param[out] p_addrs The buffer where to store GAP addresses. Pass NULL to retrieve
+ * only IRKs (in that case, @p p_irks must not be NULL).
+ * @param[in,out] p_addr_cnt In: The size of the @p p_addrs buffer.
+ * May be NULL if and only if @p p_addrs is NULL.
+ * Out: The number of GAP addresses copied into the buffer.
+ * If @p p_addrs is NULL, this parameter remains unchanged.
+ * @param[out] p_irks The buffer where to store IRKs. Pass NULL to retrieve
+ * only GAP addresses (in that case, @p p_addrs must not NULL).
+ * @param[in,out] p_irk_cnt In: The size of the @p p_irks buffer.
+ * May be NULL if and only if @p p_irks is NULL.
+ * Out: The number of IRKs copied into the buffer.
+ * If @p p_irks is NULL, this paramater remains unchanged.
+ *
+ * @retval NRF_SUCCESS If the whitelist was successfully retrieved.
+ * @retval BLE_ERROR_GAP_INVALID_BLE_ADDR If a peer has an address that cannot be used for
+ * whitelisting (this error can occur only
+ * when using the S13x SoftDevice v2.x).
+ * @retval NRF_ERROR_NULL If a required parameter is NULL.
+ * @retval NRF_ERROR_NO_MEM If the provided buffers are too small.
+ * @retval NRF_ERROR_NOT_FOUND If the data for any of the cached whitelisted peers
+ * cannot be found. It might have been deleted.
+ * @retval NRF_ERROR_INVALID_STATE If the Peer Manager is not initialized.
+ */
+ret_code_t pm_whitelist_get(ble_gap_addr_t * p_addrs,
+ uint32_t * p_addr_cnt,
+ ble_gap_irk_t * p_irks,
+ uint32_t * p_irk_cnt);
+
+
+/**@brief Function for setting and clearing the device identities list.
+ *
+ * @param[in] p_peers The peers to add to the device identities list. Pass NULL to clear
+ * the device identities list.
+ * @param[in] peer_cnt The number of peers. Pass zero to clear the device identities list.
+ *
+ * @retval NRF_SUCCESS If the device identities list was successfully
+ * set or cleared.
+ * @retval NRF_ERROR_NOT_FOUND If a peer is invalid or its data could not
+ * be found in flash.
+ * @retval BLE_ERROR_GAP_INVALID_BLE_ADDR If a peer has an address that cannot be
+ * used for whitelisting.
+ * @retval BLE_ERROR_GAP_DEVICE_IDENTITIES_IN_USE If the device identities list is in use and
+ * cannot be set.
+ * @retval NRF_ERROR_INVALID_STATE If the Peer Manager is not initialized.
+ * @retval NRF_ERROR_NOT_SUPPORTED If using a SoftDevice that does not support
+ * device identities, e.g. S130 v2.0.
+ */
+ret_code_t pm_device_identities_list_set(pm_peer_id_t const * p_peers,
+ uint32_t peer_cnt);
+
+
+/**@brief Function for setting the local <em>Bluetooth</em> identity address.
+ *
+ * @details The local <em>Bluetooth</em> identity address is the address that identifies the device
+ * to other peers. The address type must be either @ref BLE_GAP_ADDR_TYPE_PUBLIC or @ref
+ * BLE_GAP_ADDR_TYPE_RANDOM_STATIC. The identity address cannot be changed while roles are running.
+ *
+ * The SoftDevice sets a default address of type @ref BLE_GAP_ADDR_TYPE_RANDOM_STATIC when it is
+ * enabled. This default address is a random number that is populated during the IC manufacturing
+ * process. It remains unchanged for the lifetime of each IC, but the application can use this
+ * function to assign a different identity address.
+ *
+ * The identity address is distributed to the peer during bonding. Changing the identity address
+ * means bonded devices might not recognize us.
+ *
+ * @note The SoftDevice functions @ref sd_ble_gap_addr_set and @ref sd_ble_gap_privacy_set must not
+ * be called when using the Peer Manager. Use the Peer Manager equivalents instead.
+ *
+ * @param[in] p_addr The GAP address to be set.
+ *
+ * @retval NRF_SUCCESS If the identity address was set successfully.
+ * @retval NRF_ERROR_NULL If @p p_addr is NULL.
+ * @retval NRF_ERROR_INVALID_ADDR If the @p p_addr pointer is invalid.
+ * @retval BLE_ERROR_GAP_INVALID_BLE_ADDR If the BLE address is invalid.
+ * @retval NRF_ERROR_BUSY If the SoftDevice was busy. Process SoftDevice events
+ * and retry.
+ * @retval NRF_ERROR_INVALID_STATE If the Peer Manager is not initialized or if this function
+ * was called while advertising, scanning, or while connected.
+ * @retval NRF_ERROR_INTERNAL If an internal error occurred.
+ */
+ret_code_t pm_id_addr_set(ble_gap_addr_t const * p_addr);
+
+
+/**@brief Function for retrieving the local <em>Bluetooth</em> identity address.
+ *
+ * This function always returns the identity address, irrespective of the privacy settings.
+ * This means that the address type will always be either @ref BLE_GAP_ADDR_TYPE_PUBLIC or @ref
+ * BLE_GAP_ADDR_TYPE_RANDOM_STATIC.
+ *
+ * @param[out] p_addr Pointer to the address structure to be filled in.
+ *
+ * @retval NRF_SUCCESS If the address was retrieved successfully.
+ * @retval NRF_ERROR_NULL If @p p_addr is NULL.
+ * @retval NRF_ERROR_INVALID_STATE If the Peer Manager is not initialized.
+ */
+ret_code_t pm_id_addr_get(ble_gap_addr_t * p_addr);
+
+
+/**@brief Function for configuring privacy settings.
+ *
+ * The privacy settings cannot be configured while advertising, scanning, or while in a connection.
+ *
+ * @note The SoftDevice functions @ref sd_ble_gap_addr_set
+ * and @ref sd_ble_gap_privacy_set must not be called when using the Peer Manager.
+ * Use this function instead.
+ *
+ * @param[in] p_privacy_params Privacy settings.
+ *
+ * @retval NRF_SUCCESS If the privacy settings were configured successfully.
+ * @retval NRF_ERROR_NULL If @p p_privacy_params is NULL.
+ * @retval NRF_ERROR_BUSY If the operation could not be performed at this time.
+ * Process SoftDevice events and retry.
+ * @retval NRF_ERROR_INVALID_PARAM If the address type is invalid.
+ * @retval NRF_ERROR_INVALID_STATE If this function is called while BLE roles using
+ * privacy are enabled.
+ * @retval NRF_ERROR_INVALID_STATE If the Peer Manager is not initialized.
+ */
+ret_code_t pm_privacy_set(pm_privacy_params_t const * p_privacy_params);
+
+
+/**@brief Function for retrieving privacy settings.
+ *
+ * The privacy settings that are returned include the current IRK as well.
+ *
+ * @param[out] p_privacy_params Privacy settings.
+ *
+ * @retval NRF_SUCCESS If the privacy settings were retrieved successfully.
+ * @retval NRF_ERROR_NULL If @p p_privacy_params or @p p_privacy_params->p_device_irk is
+ * NULL.
+ * @retval NRF_ERROR_INVALID_STATE If the Peer Manager is not initialized.
+ */
+ret_code_t pm_privacy_get(pm_privacy_params_t * p_privacy_params);
+
+
+/**@brief Function for resolving a resolvable address with an identity resolution key (IRK).
+ *
+ * @param[in] p_addr A private random resolvable address.
+ * @param[in] p_irk An identity resolution key (IRK).
+ *
+ * @retval true The IRK used matched the one used to create the address.
+ * @retval false The IRK used did not match the one used to create the address, or an argument was
+ * NULL or invalid.
+ */
+bool pm_address_resolve(ble_gap_addr_t const * p_addr, ble_gap_irk_t const * p_irk);
+
+
+/**@brief Function for getting the connection handle of the connection with a bonded peer.
+ *
+ * @param[in] peer_id The peer ID of the bonded peer.
+ * @param[out] p_conn_handle Connection handle, or @ref BLE_ERROR_INVALID_CONN_HANDLE if the peer
+ * is not connected.
+ *
+ * @retval NRF_SUCCESS If the connection handle was retrieved successfully.
+ * @retval NRF_ERROR_NULL If @p p_conn_handle was NULL.
+ * @retval NRF_ERROR_INVALID_STATE If the Peer Manager is not initialized.
+ */
+ret_code_t pm_conn_handle_get(pm_peer_id_t peer_id, uint16_t * p_conn_handle);
+
+
+/**@brief Function for retrieving the ID of a peer, given its connection handle.
+ *
+ * @param[in] conn_handle The connection handle of the peer.
+ * @param[out] p_peer_id The peer ID, or @ref PM_PEER_ID_INVALID if the peer is not bonded or
+ * @p conn_handle does not refer to a valid connection.
+ *
+ * @retval NRF_SUCCESS If the peer ID was retrieved successfully.
+ * @retval NRF_ERROR_NULL If @p p_peer_id was NULL.
+ * @retval NRF_ERROR_INVALID_STATE If the Peer Manager is not initialized.
+ */
+ret_code_t pm_peer_id_get(uint16_t conn_handle, pm_peer_id_t * p_peer_id);
+
+
+/**@brief Function for getting the next peer ID in the sequence of all used peer IDs.
+ *
+ * @details This function can be used to loop through all used peer IDs. The order in which
+ * peer IDs are returned should be considered unpredictable. @ref PM_PEER_ID_INVALID
+ * is considered to be before the first and after the last used peer ID.
+ *
+ * @details To loop through all peer IDs exactly once, use the following constuct:
+ * @code{c}
+ * pm_peer_id_t current_peer_id = pm_next_peer_id_get(PM_PEER_ID_INVALID);
+ * while (current_peer_id != PM_PEER_ID_INVALID)
+ * {
+ * // Do something with current_peer_id.
+ * current_peer_id = pm_next_peer_id_get(current_peer_id)
+ * }
+ * @endcode
+ *
+ * @param[in] prev_peer_id The previous peer ID.
+ *
+ * @return The next peer ID. If @p prev_peer_id was @ref PM_PEER_ID_INVALID, the
+ * next peer ID is the first used peer ID. If @p prev_peer_id was the last
+ * used peer ID, the function returns @ref PM_PEER_ID_INVALID.
+ */
+pm_peer_id_t pm_next_peer_id_get(pm_peer_id_t prev_peer_id);
+
+
+/**@brief Function for querying the number of valid peer IDs that are available.
+ *
+ * @details This function returns the number of peers for which there is data in persistent storage.
+ *
+ * @return The number of valid peer IDs.
+ */
+uint32_t pm_peer_count(void);
+
+
+
+
+/**@anchor PM_PEER_DATA_FUNCTIONS
+ * @name Functions (Peer Data)
+ * Functions for manipulating peer data.
+ * @{
+ */
+
+/**
+ * @{
+ */
+
+/**@brief Function for retrieving stored data of a peer.
+ *
+ * @note The length of the provided buffer must be a multiple of 4.
+ *
+ * @param[in] peer_id Peer ID to get data for.
+ * @param[in] data_id Which type of data to read.
+ * @param[out] p_data Where to put the retrieved data. The documentation for
+ * @ref pm_peer_data_id_t specifies what data type each data ID is stored as.
+ * @param[inout] p_len In: The length in bytes of @p p_data.
+ * Out: The length in bytes of the read data, if the read was successful.
+ *
+ * @retval NRF_SUCCESS If the data was read successfully.
+ * @retval NRF_ERROR_INVALID_PARAM If the the data type or the peer ID was invalid or unallocated,
+ * or if the length in @p p_length was not a multiple of 4.
+ * @retval NRF_ERROR_NULL If a pointer parameter was NULL.
+ * @retval NRF_ERROR_NOT_FOUND If no stored data was found for this peer ID/data ID combination.
+ * @retval NRF_ERROR_DATA_SIZE If the provided buffer was not large enough.
+ * @retval NRF_ERROR_INVALID_STATE If the Peer Manager is not initialized.
+ */
+ret_code_t pm_peer_data_load(pm_peer_id_t peer_id,
+ pm_peer_data_id_t data_id,
+ void * p_data,
+ uint16_t * p_len);
+
+/**@brief Function for reading a peer's bonding data (@ref PM_PEER_DATA_ID_BONDING).
+ * @details See @ref pm_peer_data_load for parameters and return values. */
+ret_code_t pm_peer_data_bonding_load(pm_peer_id_t peer_id,
+ pm_peer_data_bonding_t * p_data);
+
+/**@brief Function for reading a peer's remote DB values. (@ref PM_PEER_DATA_ID_GATT_REMOTE).
+ * @details See @ref pm_peer_data_load for parameters and return values. */
+ret_code_t pm_peer_data_remote_db_load(pm_peer_id_t peer_id,
+ ble_gatt_db_srv_t * p_data,
+ uint16_t * p_len);
+
+/**@brief Function for reading a peer's application data. (@ref PM_PEER_DATA_ID_APPLICATION).
+ * @details See @ref pm_peer_data_load for parameters and return values. */
+ret_code_t pm_peer_data_app_data_load(pm_peer_id_t peer_id,
+ void * p_data,
+ uint16_t * p_len);
+/** @}*/
+
+
+/**
+ * @{
+ */
+
+/**@brief Function for setting or updating stored data of a peer.
+ *
+ * @note Writing the data to persistent storage happens asynchronously. Therefore, the buffer
+ * that contains the data must be kept alive until the operation has completed.
+ *
+ * @note The data written using this function might later be overwritten as a result of internal
+ * operations in the Peer Manager. A Peer Manager event is sent each time data is updated,
+ * regardless of whether the operation originated internally or from action by the user.
+ *
+ * @param[in] peer_id Peer ID to set data for.
+ * @param[in] data_id Which type of data to set.
+ * @param[in] p_data New value to set. The documentation for @ref pm_peer_data_id_t specifies
+ * what data type each data ID should be stored as.
+ * @param[in] len The length in bytes of @p p_data.
+ * @param[out] p_token A token that identifies this particular store operation. The token can be
+ * used to identify events that pertain to this operation. This parameter can
+ * be NULL.
+ *
+ * @retval NRF_SUCCESS If the data is scheduled to be written to persistent storage.
+ * @retval NRF_ERROR_NULL If @p p_data is NULL.
+ * @retval NRF_ERROR_NOT_FOUND If no peer was found for the peer ID.
+ * @retval NRF_ERROR_BUSY If the underlying flash handler is busy with other flash
+ * operations. Try again after receiving a Peer Manager event.
+ * @retval NRF_ERROR_FORBIDDEN If data ID is @ref PM_PEER_DATA_ID_BONDING and the new bonding
+ * data also corresponds to another bonded peer. No data is written
+ * so duplicate entries are avoided.
+ * @retval NRF_ERROR_INVALID_STATE If the Peer Manager is not initialized.
+ */
+ret_code_t pm_peer_data_store(pm_peer_id_t peer_id,
+ pm_peer_data_id_t data_id,
+ void const * p_data,
+ uint16_t len,
+ pm_store_token_t * p_token);
+
+/**@brief Function for setting or updating a peer's bonding data (@ref PM_PEER_DATA_ID_BONDING).
+ * @details See @ref pm_peer_data_store for parameters and return values. */
+ret_code_t pm_peer_data_bonding_store(pm_peer_id_t peer_id,
+ pm_peer_data_bonding_t const * p_data,
+ pm_store_token_t * p_token);
+
+/**@brief Function for setting or updating a peer's remote DB values. (@ref PM_PEER_DATA_ID_GATT_REMOTE).
+ * @details See @ref pm_peer_data_store for parameters and return values. */
+ret_code_t pm_peer_data_remote_db_store(pm_peer_id_t peer_id,
+ ble_gatt_db_srv_t const * p_data,
+ uint16_t len,
+ pm_store_token_t * p_token);
+
+/**@brief Function for setting or updating a peer's application data. (@ref PM_PEER_DATA_ID_APPLICATION).
+ * @details See @ref pm_peer_data_store for parameters and return values. */
+ret_code_t pm_peer_data_app_data_store(pm_peer_id_t peer_id,
+ void const * p_data,
+ uint16_t len,
+ pm_store_token_t * p_token);
+/** @}*/
+
+
+/**
+ * @{
+ */
+
+/**@brief Function for deleting a peer's stored pieces of data.
+ *
+ * @details This function deletes specific data that is stored for a peer. Note that bonding data
+ * cannot be cleared separately.
+ *
+ * To delete all data for a peer (including bonding data), use @ref pm_peer_delete.
+ *
+ * @note Clearing data in persistent storage happens asynchronously.
+ *
+ * @param[in] peer_id Peer ID to clear data for.
+ * @param[in] data_id Which data to clear.
+ *
+ * @retval NRF_SUCCESS If the clear procedure was initiated successfully.
+ * @retval NRF_ERROR_INVALID_PARAM If @p data_id was PM_PEER_DATA_ID_BONDING or invalid, or
+ * @p peer_id was invalid.
+ * @retval NRF_ERROR_NOT_FOUND If there was no data to clear for this peer ID/data ID combination.
+ * @retval NRF_ERROR_BUSY If the underlying flash handler is busy with other flash
+ * operations. Try again after receiving a Peer Manager event.
+ * @retval NRF_ERROR_INVALID_STATE If the Peer Manager is not initialized.
+ * @retval NRF_ERROR_INTERNAL If an internal error occurred.
+ */
+ret_code_t pm_peer_data_delete(pm_peer_id_t peer_id, pm_peer_data_id_t data_id);
+
+
+/**@brief Function for manually adding a peer to the persistent storage.
+ *
+ * @details This function allocates a new peer ID and stores bonding data for the new peer. The
+ * bonding data is necessary to prevent ambiguity/inconsistency in peer data.
+ *
+ * @param[in] p_bonding_data The bonding data of the new peer (must contain a public/static
+ * address or a non-zero IRK).
+ * @param[out] p_new_peer_id Peer ID for the new peer, or an existing peer if a match was found.
+ * @param[out] p_token A token that identifies this particular store operation (storing the
+ * bonding data). The token can be used to identify events that pertain
+ * to this operation. This parameter can be NULL.
+ *
+ * @retval NRF_SUCCESS If the store operation for bonding data was initiated successfully.
+ * @retval NRF_ERROR_NULL If @p p_bonding_data or @p p_new_peer_id is NULL.
+ * @retval NRF_ERROR_STORAGE_FULL If there is no more space in persistent storage.
+ * @retval NRF_ERROR_NO_MEM If there are no more available peer IDs.
+ * @retval NRF_ERROR_BUSY If the underlying flash filesystem is busy with other flash
+ * operations. Try again after receiving a Peer Manager event.
+ * @retval NRF_ERROR_INVALID_STATE If the Peer Manager is not initialized.
+ * @retval NRF_ERROR_INTERNAL If an internal error occurred.
+ */
+ret_code_t pm_peer_new(pm_peer_id_t * p_new_peer_id,
+ pm_peer_data_bonding_t * p_bonding_data,
+ pm_store_token_t * p_token);
+
+
+/**@brief Function for freeing persistent storage for a peer.
+ *
+ * @details This function deletes every piece of data that is associated with the specified peer and
+ * frees the peer ID to be used for another peer. The deletion happens asynchronously, and
+ * the peer ID is not freed until the data is deleted. When the operation finishes, a @ref
+ * PM_EVT_PEER_DELETE_SUCCEEDED or @ref PM_EVT_PEER_DELETE_FAILED event is sent.
+ *
+ * @warning Use this function only when not connected to or connectable for the peer that is being
+ * deleted. If the peer is or becomes connected or data is manually written in flash during
+ * this procedure (until the success or failure event happens), the behavior is undefined.
+ *
+ * @param[in] peer_id Peer ID to be freed and have all associated data deleted.
+ *
+ * @retval NRF_SUCCESS If the operation was initiated successfully.
+ * @retval NRF_ERROR_INVALID_PARAM If the peer ID was not valid.
+ * @retval NRF_ERROR_INVALID_STATE If the Peer Manager is not initialized.
+ */
+ret_code_t pm_peer_delete(pm_peer_id_t peer_id);
+
+
+/**@brief Function for deleting all data stored for all peers.
+ *
+ * @details This function sends either a @ref PM_EVT_PEERS_DELETE_SUCCEEDED or a @ref
+ * PM_EVT_PEERS_DELETE_FAILED event. In addition, a @ref PM_EVT_PEER_DELETE_SUCCEEDED or
+ * @ref PM_EVT_PEER_DELETE_FAILED event is sent for each deleted peer.
+ *
+ * @note When there is no peer data in flash the @ref PM_EVT_PEER_DELETE_SUCCEEDED event is sent synchronously.
+ *
+ * @warning Use this function only when not connected or connectable. If a peer is or becomes
+ * connected or a @ref PM_PEER_DATA_FUNCTIONS function is used during this procedure (until
+ * the success or failure event happens), the behavior is undefined.
+ *
+ * @retval NRF_SUCCESS If the deletion process was initiated successfully.
+ * @retval NRF_ERROR_INVALID_STATE If the Peer Manager is not initialized.
+ * @retval NRF_ERROR_INTERNAL If an internal error occurred.
+ */
+ret_code_t pm_peers_delete(void);
+/** @}*/
+
+
+/**
+ * @{
+ */
+
+
+/**@brief Function for finding the highest and lowest ranked peers.
+ *
+ * @details The rank is saved in persistent storage under the data ID @ref PM_PEER_DATA_ID_PEER_RANK.
+ *
+ * @details The interpretation of rank is up to the user, because the rank is only updated by
+ * calling @ref pm_peer_rank_highest or by manipulating the value using a @ref
+ * PM_PEER_DATA_FUNCTIONS function.
+ *
+ * @note Any argument that is NULL is ignored.
+ *
+ * @param[out] p_highest_ranked_peer The peer ID with the highest rank of all peers, for example,
+ * the most recently used peer.
+ * @param[out] p_highest_rank The highest rank.
+ * @param[out] p_lowest_ranked_peer The peer ID with the lowest rank of all peers, for example,
+ * the least recently used peer.
+ * @param[out] p_lowest_rank The lowest rank.
+ *
+ * @retval NRF_SUCCESS If the operation completed successfully.
+ * @retval NRF_ERROR_NOT_FOUND If no peers were found.
+ * @retval NRF_ERROR_INVALID_STATE If the Peer Manager is not initialized.
+ * @retval NRF_ERROR_INTERNAL If an internal error occurred.
+ * @retval NRF_ERROR_NOT_SUPPORTED If peer rank functionality has been disabled via the @ref
+ * PM_PEER_RANKS_ENABLED configuration option.
+ */
+ret_code_t pm_peer_ranks_get(pm_peer_id_t * p_highest_ranked_peer,
+ uint32_t * p_highest_rank,
+ pm_peer_id_t * p_lowest_ranked_peer,
+ uint32_t * p_lowest_rank);
+
+
+/**@brief Function for updating the rank of a peer to be highest among all stored peers.
+ *
+ * @details If this function returns @ref NRF_SUCCESS, either a @ref PM_EVT_PEER_DATA_UPDATE_SUCCEEDED or a
+ * @ref PM_EVT_PEER_DATA_UPDATE_FAILED event is sent with a @ref
+ * PM_STORE_TOKEN_INVALID store token when the operation is complete. Until the operation
+ * is complete, this function returns @ref NRF_ERROR_BUSY.
+ *
+ * When the operation is complete, the peer is the highest ranked peer as reported by
+ * @ref pm_peer_ranks_get.
+ *
+ * @note The @ref PM_EVT_PEER_DATA_UPDATE_SUCCEEDED event can arrive before the function returns if the peer
+ * is already ranked highest. In this case, the @ref pm_peer_data_update_succeeded_evt_t::flash_changed flag
+ * in the event will be false.
+ *
+ * @param[in] peer_id The peer to rank highest.
+ *
+ * @retval NRF_SUCCESS If the peer's rank is, or will be updated to be highest.
+ * @retval NRF_ERROR_BUSY If the underlying flash handler is busy with other flash
+ * operations, or if a previous call to this function has not
+ * completed. Try again after receiving a Peer Manager event.
+ * @retval NRF_ERROR_INVALID_STATE If the Peer Manager is not initialized.
+ * @retval NRF_ERROR_RESOURCES If the highest rank is UINT32_MAX, so the new rank would wrap
+ * around to 0. To fix this, manually update all ranks to smaller
+ * values, while still keeping their order.
+ * @retval NRF_ERROR_INTERNAL If an internal error occurred.
+ * @retval NRF_ERROR_NOT_SUPPORTED If peer rank functionality has been disabled via the @ref
+ * PM_PEER_RANKS_ENABLED configuration option.
+ */
+ret_code_t pm_peer_rank_highest(pm_peer_id_t peer_id);
+
+/** @}*/
+
+/** @} */
+
+/** @} */
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // PEER_MANAGER_H__
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/peer_manager/peer_manager_internal.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/peer_manager/peer_manager_internal.h
new file mode 100644
index 0000000..59bb811
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/peer_manager/peer_manager_internal.h
@@ -0,0 +1,207 @@
+/**
+ * Copyright (c) 2015 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#ifndef PEER_MANAGER_INTERNAL_H__
+#define PEER_MANAGER_INTERNAL_H__
+
+#include <stdint.h>
+#include "sdk_errors.h"
+#include "ble.h"
+#include "ble_gap.h"
+#include "peer_manager_types.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+/**
+ * @cond NO_DOXYGEN
+ * @file peer_manager_types.h
+ *
+ * @addtogroup peer_manager
+ * @brief File containing definitions used solely inside the Peer Manager's modules.
+ * @{
+ */
+
+ANON_UNIONS_ENABLE;
+
+/**@brief One piece of data associated with a peer, together with its type.
+ *
+ * @note This type is deprecated.
+ */
+typedef struct
+{
+ uint16_t length_words; /**< @brief The length of the data in words. */
+ pm_peer_data_id_t data_id; /**< @brief ID that specifies the type of data (defines which member of the union is used). */
+ union
+ {
+ pm_peer_data_bonding_t * p_bonding_data; /**< @brief The exchanged bond information in addition to metadata of the bonding. */
+ uint32_t * p_peer_rank; /**< @brief A value locally assigned to this peer. Its interpretation is up to the user. The rank is not set automatically by the Peer Manager, but it is assigned by the user using either @ref pm_peer_rank_highest or a @ref PM_PEER_DATA_FUNCTIONS function. */
+ bool * p_service_changed_pending; /**< @brief Whether a service changed indication should be sent to the peer. */
+ pm_peer_data_local_gatt_db_t * p_local_gatt_db; /**< @brief Persistent information pertaining to a peer GATT client. */
+ ble_gatt_db_srv_t * p_remote_gatt_db; /**< @brief Persistent information pertaining to a peer GATT server. */
+ uint8_t * p_application_data; /**< @brief Arbitrary data to associate with the peer. This data can be freely used by the application. */
+ void * p_all_data; /**< @brief Generic access pointer to the data. It is used only to handle the data without regard to type. */
+ }; /**< @brief The data. */
+} pm_peer_data_t;
+
+
+/**@brief Immutable version of @ref pm_peer_data_t.
+ *
+ * @note This type is deprecated.
+ */
+typedef struct
+{
+ uint16_t length_words; /**< @brief The length of the data in words. */
+ pm_peer_data_id_t data_id; /**< @brief ID that specifies the type of data (defines which member of the union is used). */
+ union
+ {
+ pm_peer_data_bonding_t const * p_bonding_data; /**< @brief Immutable @ref pm_peer_data_t::p_bonding_data. */
+ uint32_t const * p_peer_rank; /**< @brief Immutable @ref pm_peer_data_t::p_peer_rank. */
+ bool const * p_service_changed_pending; /**< @brief Immutable @ref pm_peer_data_t::p_service_changed_pending. */
+ pm_peer_data_local_gatt_db_t const * p_local_gatt_db; /**< @brief Immutable @ref pm_peer_data_t::p_local_gatt_db. */
+ ble_gatt_db_srv_t const * p_remote_gatt_db; /**< @brief Immutable @ref pm_peer_data_t::p_remote_gatt_db. */
+ uint8_t const * p_application_data; /**< @brief Immutable @ref pm_peer_data_t::p_application_data. */
+ void const * p_all_data; /**< @brief Immutable @ref pm_peer_data_t::p_all_data. */
+ }; /**< @brief The data. */
+} pm_peer_data_const_t;
+
+ANON_UNIONS_DISABLE;
+
+
+/**@brief Version of @ref pm_peer_data_t that reflects the structure of peer data in flash.
+ *
+ * @note This type is deprecated.
+ */
+typedef pm_peer_data_const_t pm_peer_data_flash_t;
+
+
+/**@brief Event handler for events from the @ref peer_manager module.
+ *
+ * @sa pm_register
+ *
+ * @param[in] p_event The event that has occurred.
+ */
+typedef void (*pm_evt_handler_internal_t)(pm_evt_t * p_event);
+
+
+/**@brief Macro for calculating the flash size of bonding data.
+ *
+ * @return The number of words that the data takes in flash.
+ */
+#define PM_BONDING_DATA_N_WORDS() BYTES_TO_WORDS(sizeof(pm_peer_data_bonding_t))
+
+
+/**@brief Macro for calculating the flash size of service changed pending state.
+ *
+ * @return The number of words that the data takes in flash.
+ */
+#define PM_SC_STATE_N_WORDS() BYTES_TO_WORDS(sizeof(bool))
+
+
+/**@brief Macro for calculating the flash size of local GATT database data.
+ *
+ * @param[in] local_db_len The length, in bytes, of the database as reported by the SoftDevice.
+ *
+ * @return The number of words that the data takes in flash.
+ */
+#define PM_LOCAL_DB_N_WORDS(local_db_len) \
+ BYTES_TO_WORDS((local_db_len) + PM_LOCAL_DB_LEN_OVERHEAD_BYTES)
+
+
+/**@brief Macro for calculating the length of a local GATT database attribute array.
+ *
+ * @param[in] n_words The number of words that the data takes in flash.
+ *
+ * @return The length of the database attribute array.
+ */
+#define PM_LOCAL_DB_LEN(n_words) (((n_words) * BYTES_PER_WORD) - PM_LOCAL_DB_LEN_OVERHEAD_BYTES)
+
+
+/**@brief Macro for calculating the flash size of remote GATT database data.
+ *
+ * @param[in] service_count The number of services in the service array.
+ *
+ * @return The number of words that the data takes in flash.
+ */
+#define PM_REMOTE_DB_N_WORDS(service_count) BYTES_TO_WORDS(sizeof(ble_gatt_db_srv_t) * (service_count))
+
+
+/**@brief Macro for calculating the flash size of remote GATT database data.
+ *
+ * @param[in] n_words The length in number of words.
+ *
+ * @return The number of words that the data takes in flash.
+ */
+#define PM_REMOTE_DB_N_SERVICES(n_words) (((n_words) * BYTES_PER_WORD) / sizeof(ble_gatt_db_srv_t))
+
+
+/**@brief Function for calculating the flash size of the usage index.
+ *
+ * @return The number of words that the data takes in flash.
+ */
+#define PM_USAGE_INDEX_N_WORDS() BYTES_TO_WORDS(sizeof(uint32_t))
+
+/** @}
+ * @endcond
+ */
+
+
+#ifdef NRF_PM_DEBUG
+
+ #define NRF_PM_DEBUG_CHECK(condition) \
+ if (!(condition)) \
+ { \
+ __asm("bkpt #0"); \
+ }
+
+#else
+
+ // Prevent "variable set but never used" compiler warnings.
+ #define NRF_PM_DEBUG_CHECK(condition) (void)(condition)
+
+#endif
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* PEER_MANAGER_INTERNAL_H__ */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/peer_manager/peer_manager_types.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/peer_manager/peer_manager_types.h
new file mode 100644
index 0000000..34fd328
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/peer_manager/peer_manager_types.h
@@ -0,0 +1,354 @@
+/**
+ * Copyright (c) 2015 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 peer_manager_types.h
+ *
+ * @addtogroup peer_manager
+ * @{
+ */
+
+#ifndef PEER_MANAGER_TYPES_H__
+#define PEER_MANAGER_TYPES_H__
+
+#include <stdint.h>
+#include <stdbool.h>
+#include <stddef.h>
+#include "nrf.h"
+#include "ble_gap.h"
+#include "ble_hci.h"
+#include "ble_gatt_db.h"
+#include "app_util.h"
+#include "app_util_platform.h"
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+/**@brief Handle to uniquely identify a peer for which we have persistently stored data.
+ */
+typedef uint16_t pm_peer_id_t;
+
+/**@brief Type that is used for write prepares (used to reserve space in flash).
+ */
+typedef uint32_t pm_prepare_token_t;
+
+/**@brief Type that is used to hold a reference to a stored item in flash.
+ */
+typedef uint32_t pm_store_token_t;
+
+/**@brief Errors from security procedures in Peer Manager.
+ *
+ * @details Possible values are defined in @ref PM_SEC_ERRORS and @ref BLE_GAP_SEC_STATUS.
+ */
+typedef uint16_t pm_sec_error_code_t;
+
+
+//lint -emacro(516,PM_LOCAL_DB_LEN_OVERHEAD_BYTES)
+
+#define PM_PEER_ID_INVALID 0xFFFF /**< @brief Invalid value for @ref pm_peer_id_t. */
+#define PM_STORE_TOKEN_INVALID 0 /**< @brief Invalid value for store token. */
+#define PM_PEER_ID_N_AVAILABLE_IDS 256 /**< @brief The number of available peer IDs. */
+#define PM_LOCAL_DB_LEN_OVERHEAD_BYTES offsetof(pm_peer_data_local_gatt_db_t, data) /**< @brief The static-length part of the local GATT data struct. */
+
+
+#define PM_CONN_SEC_ERROR_BASE 0x1000 /**< @brief The base for Peer Manager defined errors. See @ref PM_SEC_ERRORS and @ref pm_sec_error_code_t. */
+
+
+/**@defgroup PM_SEC_ERRORS Peer Manager defined security errors
+ *
+ * @details The first 256 numbers in this range correspond to the status codes in
+ * @ref BLE_HCI_STATUS_CODES.
+ * @{ */
+#define PM_CONN_SEC_ERROR_PIN_OR_KEY_MISSING (PM_CONN_SEC_ERROR_BASE + 0x06) /**< @brief Encryption failed because the peripheral has lost the LTK for this bond. See also @ref BLE_HCI_STATUS_CODE_PIN_OR_KEY_MISSING and Table 3.7 ("Pairing Failed Reason Codes") in the Bluetooth Core Specification 4.2, section 3.H.3.5.5 (@linkBLEcore). */
+#define PM_CONN_SEC_ERROR_MIC_FAILURE (PM_CONN_SEC_ERROR_BASE + 0x3D) /**< @brief Encryption ended with disconnection because of mismatching keys or a stray packet during a procedure. See the SoftDevice GAP Message Sequence Charts on encryption (@linkBLEMSCgap), the Bluetooth Core Specification 4.2, sections 6.B.5.1.3.1 and 3.H.3.5.5 (@linkBLEcore), and @ref BLE_HCI_CONN_TERMINATED_DUE_TO_MIC_FAILURE. */
+#define PM_CONN_SEC_ERROR_DISCONNECT (PM_CONN_SEC_ERROR_BASE + 0x100) /**< @brief Pairing or encryption did not finish before the link disconnected for an unrelated reason. */
+#define PM_CONN_SEC_ERROR_SMP_TIMEOUT (PM_CONN_SEC_ERROR_BASE + 0x101) /**< @brief Pairing/bonding could not start because an SMP time-out has already happened on this link. This means that no more pairing or bonding can happen on this link. To be able to pair or bond, the link must be disconnected and then reconnected. See Bluetooth Core Specification 4.2 section 3.H.3.4 (@linkBLEcore). */
+ /** @} */
+
+
+
+/**@defgroup PM_PEER_ID_VERSIONS All versions of Peer IDs.
+ * @brief The data ID for each iteration of the data formats in flash.
+ * @details Each time the format (in flash) of a piece of peer data changes, the data ID will also
+ * be updated. This list of defines is a record of each data ID that has ever existed, and
+ * code that caters to legacy formats can find the relevant IDs here.
+ * @{ */
+#define PM_PEER_DATA_ID_FIRST_VX 0 /**< @brief The smallest data ID. */
+#define PM_PEER_DATA_ID_BONDING_V1 0 /**< @brief The data ID of the first version of bonding data. */
+#define PM_PEER_DATA_ID_BONDING_V2 7 /**< @brief The data ID of the second version of bonding data. */
+#define PM_PEER_DATA_ID_SERVICE_CHANGED_PENDING_V1 1 /**< @brief The data ID of the first version of the service changed pending flag. */
+#define PM_PEER_DATA_ID_GATT_LOCAL_V1 2 /**< @brief The data ID of the first version of local GATT data. */
+#define PM_PEER_DATA_ID_GATT_LOCAL_V2 8 /**< @brief The data ID of the second version of local GATT data. */
+#define PM_PEER_DATA_ID_GATT_REMOTE_V1 3 /**< @brief The data ID of the first version of remote GATT data. */
+#define PM_PEER_DATA_ID_APPLICATION_V1 4 /**< @brief The data ID of the first version of application data. */
+#define PM_PEER_DATA_ID_GATT_REMOTE_V2 5 /**< @brief The data ID of the second version of remote GATT data. */
+#define PM_PEER_DATA_ID_PEER_RANK_V1 6 /**< @brief The data ID of the first version of the rank. */
+#define PM_PEER_DATA_ID_LAST_VX 9 /**< @brief The data ID after the last valid one. */
+#define PM_PEER_DATA_ID_INVALID_VX 0xFF /**< @brief A data ID guaranteed to be invalid. */
+/**@}*/
+
+
+/**@brief The different types of data associated with a peer.
+ */
+typedef enum
+{
+ PM_PEER_DATA_ID_FIRST = PM_PEER_DATA_ID_FIRST_VX, /**< @brief The smallest data ID. */
+ PM_PEER_DATA_ID_BONDING = PM_PEER_DATA_ID_BONDING_V2, /**< @brief The data ID for bonding data. Type: @ref pm_peer_data_bonding_t. */
+ PM_PEER_DATA_ID_SERVICE_CHANGED_PENDING = PM_PEER_DATA_ID_SERVICE_CHANGED_PENDING_V1, /**< @brief The data ID for service changed state. Type: bool. */
+ PM_PEER_DATA_ID_GATT_LOCAL = PM_PEER_DATA_ID_GATT_LOCAL_V2, /**< @brief The data ID for local GATT data (sys attributes). Type: @ref pm_peer_data_local_gatt_db_t. */
+ PM_PEER_DATA_ID_GATT_REMOTE = PM_PEER_DATA_ID_GATT_REMOTE_V2, /**< @brief The data ID for remote GATT data. Type: uint8_t array. */
+ PM_PEER_DATA_ID_PEER_RANK = PM_PEER_DATA_ID_PEER_RANK_V1, /**< @brief The data ID for peer rank. See @ref pm_peer_rank_highest. Type: uint32_t. */
+ PM_PEER_DATA_ID_APPLICATION = PM_PEER_DATA_ID_APPLICATION_V1, /**< @brief The data ID for application data. Type: uint8_t array. */
+ PM_PEER_DATA_ID_LAST = PM_PEER_DATA_ID_LAST_VX, /**< @brief One more than the highest data ID. */
+ PM_PEER_DATA_ID_INVALID = PM_PEER_DATA_ID_INVALID_VX, /**< @brief A data ID guaranteed to be invalid. */
+} pm_peer_data_id_t;
+
+
+/**@brief Different procedures that can lead to an encrypted link.
+ */
+typedef enum
+{
+ PM_CONN_SEC_PROCEDURE_ENCRYPTION, /**< @brief Using an LTK that was shared during a previous bonding procedure to encrypt the link. */
+ PM_CONN_SEC_PROCEDURE_BONDING, /**< @brief A pairing procedure, followed by a bonding procedure. */
+ PM_CONN_SEC_PROCEDURE_PAIRING, /**< @brief A pairing procedure with no bonding. */
+} pm_conn_sec_procedure_t;
+
+
+/**@brief Configuration of a security procedure.
+ */
+typedef struct
+{
+ bool allow_repairing; /** @brief Whether to allow the peer to pair if it wants to, but is already bonded. If this is false, the procedure is rejected, and no more events are sent. Default: false. */
+} pm_conn_sec_config_t;
+
+
+/**@brief Data associated with a bond to a peer.
+ */
+typedef struct
+{
+ uint8_t own_role; /**< @brief The BLE role of the local device during bonding. See @ref BLE_GAP_ROLES. */
+ ble_gap_id_key_t peer_ble_id; /**< @brief The peer's Bluetooth address and identity resolution key (IRK). */
+ ble_gap_enc_key_t peer_ltk; /**< @brief The peer's long-term encryption key (LTK) and master ID. */
+ ble_gap_enc_key_t own_ltk; /**< @brief Locally generated long-term encryption key (LTK) and master ID, distributed to the peer. */
+} pm_peer_data_bonding_t;
+
+
+/**@brief Data on a local GATT database.
+ */
+typedef struct
+{
+ uint32_t flags; /**< @brief Flags that describe the database attributes. */
+ uint16_t len; /**< @brief Size of the attribute array. */
+ uint8_t data[1]; /**< @brief Array to hold the database attributes. */
+} pm_peer_data_local_gatt_db_t;
+
+
+/**@brief Device Privacy.
+ *
+ * The privacy feature provides a way for the device to avoid being tracked over a period of
+ * time. The privacy feature, when enabled, hides the local device identity and replaces it
+ * with a private address that is automatically refreshed at a specified interval.
+ *
+ * If a device still wants to be recognized by other peers, it needs to share it's Identity
+ * Resolving Key (IRK). With this key, a device can generate a random private address that
+ * can only be recognized by peers in possession of that key, and devices can establish
+ * connections without revealing their real identities.
+ *
+ * @note If the device IRK is updated, the new IRK becomes the one to be distributed in all
+ * bonding procedures performed after @ref sd_ble_gap_privacy_set returns.
+ * The IRK distributed during bonding procedure is the device IRK that is active when @ref
+ * sd_ble_gap_sec_params_reply is called.
+ */
+typedef ble_gap_privacy_params_t pm_privacy_params_t;
+
+
+/**@brief Types of events that can come from the @ref peer_manager module.
+ */
+typedef enum
+{
+ PM_EVT_BONDED_PEER_CONNECTED, /**< @brief A connected peer has been identified as one with which we have a bond. When performing bonding with a peer for the first time, this event will not be sent until a new connection is established with the peer. When we are central, this event is always sent when the Peer Manager receives the @ref BLE_GAP_EVT_CONNECTED event. When we are peripheral, this event might in rare cases arrive later. */
+ PM_EVT_CONN_SEC_START, /**< @brief A security procedure has started on a link, initiated either locally or remotely. The security procedure is using the last parameters provided via @ref pm_sec_params_set. This event is always followed by either a @ref PM_EVT_CONN_SEC_SUCCEEDED or a @ref PM_EVT_CONN_SEC_FAILED event. This is an informational event; no action is needed for the procedure to proceed. */
+ PM_EVT_CONN_SEC_SUCCEEDED, /**< @brief A link has been encrypted, either as a result of a call to @ref pm_conn_secure or a result of an action by the peer. The event structure contains more information about the circumstances. This event might contain a peer ID with the value @ref PM_PEER_ID_INVALID, which means that the peer (central) used an address that could not be identified, but it used an encryption key (LTK) that is present in the database. */
+ PM_EVT_CONN_SEC_FAILED, /**< @brief A pairing or encryption procedure has failed. In some cases, this means that security is not possible on this link (temporarily or permanently). How to handle this error depends on the application. */
+ PM_EVT_CONN_SEC_CONFIG_REQ, /**< @brief The peer (central) has requested pairing, but a bond already exists with that peer. Reply by calling @ref pm_conn_sec_config_reply before the event handler returns. If no reply is sent, a default is used. */
+ PM_EVT_CONN_SEC_PARAMS_REQ, /**< @brief Security parameters (@ref ble_gap_sec_params_t) are needed for an ongoing security procedure. Reply with @ref pm_conn_sec_params_reply before the event handler returns. If no reply is sent, the parameters given in @ref pm_sec_params_set are used. If a peripheral connection, the central's sec_params will be available in the event. */
+ PM_EVT_STORAGE_FULL, /**< @brief There is no more room for peer data in flash storage. To solve this problem, delete data that is not needed anymore and run a garbage collection procedure in FDS. */
+ PM_EVT_ERROR_UNEXPECTED, /**< @brief An unrecoverable error happened inside Peer Manager. An operation failed with the provided error. */
+ PM_EVT_PEER_DATA_UPDATE_SUCCEEDED, /**< @brief A piece of peer data was stored, updated, or cleared in flash storage. This event is sent for all successful changes to peer data, also those initiated internally in Peer Manager. To identify an operation, compare the store token in the event with the store token received during the initiating function call. Events from internally initiated changes might have invalid store tokens. */
+ PM_EVT_PEER_DATA_UPDATE_FAILED, /**< @brief A piece of peer data could not be stored, updated, or cleared in flash storage. This event is sent instead of @ref PM_EVT_PEER_DATA_UPDATE_SUCCEEDED for the failed operation. */
+ PM_EVT_PEER_DELETE_SUCCEEDED, /**< @brief A peer was cleared from flash storage, for example because a call to @ref pm_peer_delete succeeded. This event can also be sent as part of a call to @ref pm_peers_delete or internal cleanup. */
+ PM_EVT_PEER_DELETE_FAILED, /**< @brief A peer could not be cleared from flash storage. This event is sent instead of @ref PM_EVT_PEER_DELETE_SUCCEEDED for the failed operation. */
+ PM_EVT_PEERS_DELETE_SUCCEEDED, /**< @brief A call to @ref pm_peers_delete has completed successfully. Flash storage now contains no peer data. */
+ PM_EVT_PEERS_DELETE_FAILED, /**< @brief A call to @ref pm_peers_delete has failed, which means that at least one of the peers could not be deleted. Other peers might have been deleted, or might still be queued to be deleted. No more @ref PM_EVT_PEERS_DELETE_SUCCEEDED or @ref PM_EVT_PEERS_DELETE_FAILED events are sent until the next time @ref pm_peers_delete is called. */
+ PM_EVT_LOCAL_DB_CACHE_APPLIED, /**< @brief Local database values for a peer (taken from flash storage) have been provided to the SoftDevice. */
+ PM_EVT_LOCAL_DB_CACHE_APPLY_FAILED, /**< @brief Local database values for a peer (taken from flash storage) were rejected by the SoftDevice, which means that either the database has changed or the user has manually set the local database to an invalid value (using @ref pm_peer_data_store). */
+ PM_EVT_SERVICE_CHANGED_IND_SENT, /**< @brief A service changed indication has been sent to a peer, as a result of a call to @ref pm_local_database_has_changed. This event will be followed by a @ref PM_EVT_SERVICE_CHANGED_IND_CONFIRMED event if the peer acknowledges the indication. */
+ PM_EVT_SERVICE_CHANGED_IND_CONFIRMED, /**< @brief A service changed indication that was sent has been confirmed by a peer. The peer can now be considered aware that the local database has changed. */
+ PM_EVT_SLAVE_SECURITY_REQ, /**< @brief The peer (peripheral) has requested link encryption, which has been enabled. */
+ PM_EVT_FLASH_GARBAGE_COLLECTED, /**< @brief The flash has been garbage collected (By FDS), possibly freeing up space. */
+} pm_evt_id_t;
+
+
+/**@brief Events parameters specific to the @ref PM_EVT_CONN_SEC_START event.
+ */
+typedef struct
+{
+ pm_conn_sec_procedure_t procedure; /**< @brief The procedure that has started. */
+} pm_conn_sec_start_evt_t;
+
+
+/**@brief Parameters specific to the @ref PM_EVT_CONN_SEC_SUCCEEDED event.
+ */
+typedef struct
+{
+ pm_conn_sec_procedure_t procedure; /**< @brief The procedure that led to securing the link. */
+ bool data_stored; /**< @brief Whether bonding data was successfully requested to be stored. This is false if: No bonding happened, or an internal error occurred when trying to store the data, or if the data was rejected via @ref pm_conn_sec_config_reply. */
+} pm_conn_secured_evt_t;
+
+
+/**@brief Parameters specific to the @ref PM_EVT_CONN_SEC_FAILED event.
+ */
+typedef struct
+{
+ pm_conn_sec_procedure_t procedure; /**< @brief The procedure that failed. */
+ pm_sec_error_code_t error; /**< @brief An error code that describes the failure. */
+ uint8_t error_src; /**< @brief The party that raised the error, see @ref BLE_GAP_SEC_STATUS_SOURCES. */
+} pm_conn_secure_failed_evt_t;
+
+
+/**@brief Parameters specific to the @ref PM_EVT_CONN_SEC_PARAMS_REQ event.
+ */
+typedef struct
+{
+ ble_gap_sec_params_t const * p_peer_params; /**< @brief Peer security parameters, if role is peripheral. Otherwise, this is NULL. */
+ void const * p_context; /**< @brief This pointer must be provided in the reply if the reply function takes a p_context argument. */
+} pm_conn_sec_params_req_evt_t;
+
+
+/**@brief Actions that can be performed to peer data in persistent storage.
+ */
+typedef enum
+{
+ PM_PEER_DATA_OP_UPDATE, /**< @brief Writing or overwriting the data. */
+ PM_PEER_DATA_OP_DELETE, /**< @brief Removing the data. */
+} pm_peer_data_op_t;
+
+
+/**@brief Parameters specific to the @ref PM_EVT_PEER_DATA_UPDATE_SUCCEEDED event.
+ */
+typedef struct
+{
+ pm_peer_data_id_t data_id; /**< @brief The type of the data that was changed. */
+ pm_peer_data_op_t action; /**< @brief What happened to the data. */
+ pm_store_token_t token; /**< @brief Token that identifies the operation. For @ref PM_PEER_DATA_OP_DELETE actions, this token can be disregarded. For @ref PM_PEER_DATA_OP_UPDATE actions, compare this token with the token that is received from a call to a @ref PM_PEER_DATA_FUNCTIONS function. */
+ uint8_t flash_changed : 1; /**< @brief If this is false, no operation was done in flash, because the value was already what it should be. Please note that in certain scenarios, this flag will be true even if the new value is the same as the old. */
+} pm_peer_data_update_succeeded_evt_t;
+
+
+/**@brief Parameters specific to the @ref PM_EVT_PEER_DATA_UPDATE_FAILED event.
+ */
+typedef struct
+{
+ pm_peer_data_id_t data_id; /**< @brief The type of the data that was supposed to be changed. */
+ pm_peer_data_op_t action; /**< @brief The action that failed. */
+ pm_store_token_t token; /**< @brief Token that identifies the operation. For @ref PM_PEER_DATA_OP_DELETE actions, this token can be disregarded. For @ref PM_PEER_DATA_OP_UPDATE actions, compare this token with the token that is received from a call to a @ref PM_PEER_DATA_FUNCTIONS function. */
+ ret_code_t error; /**< @brief An error code that describes the failure. */
+} pm_peer_data_update_failed_t;
+
+
+/**@brief Standard parameters for failure events.
+ */
+typedef struct
+{
+ ret_code_t error; /**< @brief The error that occurred. */
+} pm_failure_evt_t;
+
+
+/**@brief Events parameters specific to the @ref PM_EVT_SLAVE_SECURITY_REQ event.
+ */
+typedef struct
+{
+ bool bond; /**< @brief Whether the peripheral requested bonding. */
+ bool mitm; /**< @brief Whether the peripheral requested man-in-the-middle protection. */
+} pm_evt_slave_security_req_t;
+
+
+/**@brief An event from the @ref peer_manager module.
+ *
+ * @details The structure contains both standard parameters and parameters that are specific to some events.
+ */
+typedef struct
+{
+ pm_evt_id_t evt_id; /**< @brief The type of the event. */
+ uint16_t conn_handle; /**< @brief The connection that this event pertains to, or @ref BLE_CONN_HANDLE_INVALID. */
+ pm_peer_id_t peer_id; /**< @brief The bonded peer that this event pertains to, or @ref PM_PEER_ID_INVALID. */
+ union
+ {
+ pm_conn_sec_start_evt_t conn_sec_start; /**< @brief Parameters specific to the @ref PM_EVT_CONN_SEC_START event. */
+ pm_conn_secured_evt_t conn_sec_succeeded; /**< @brief Parameters specific to the @ref PM_EVT_CONN_SEC_SUCCEEDED event. */
+ pm_conn_secure_failed_evt_t conn_sec_failed; /**< @brief Parameters specific to the @ref PM_EVT_CONN_SEC_FAILED event. */
+ pm_conn_sec_params_req_evt_t conn_sec_params_req; /**< @brief Parameters specific to the @ref PM_EVT_CONN_SEC_PARAMS_REQ event. */
+ pm_peer_data_update_succeeded_evt_t peer_data_update_succeeded; /**< @brief Parameters specific to the @ref PM_EVT_PEER_DATA_UPDATE_SUCCEEDED event. */
+ pm_peer_data_update_failed_t peer_data_update_failed; /**< @brief Parameters specific to the @ref PM_EVT_PEER_DATA_UPDATE_FAILED event. */
+ pm_failure_evt_t peer_delete_failed; /**< @brief Parameters specific to the @ref PM_EVT_PEER_DELETE_FAILED event. */
+ pm_failure_evt_t peers_delete_failed_evt; /**< @brief Parameters specific to the @ref PM_EVT_PEERS_DELETE_FAILED event. */
+ pm_failure_evt_t error_unexpected; /**< @brief Parameters specific to the @ref PM_EVT_ERROR_UNEXPECTED event. */
+ pm_evt_slave_security_req_t slave_security_req; /**< @brief Parameters specific to the @ref PM_EVT_SLAVE_SECURITY_REQ event. */
+ } params;
+} pm_evt_t;
+
+
+/**@brief Event handler for events from the @ref peer_manager module.
+ *
+ * @sa pm_register
+ *
+ * @param[in] p_event The event that has occurred.
+ */
+typedef void (*pm_evt_handler_t)(pm_evt_t const * p_event);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* PEER_MANAGER_TYPES_H__ */
+
+/** @} */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/peer_manager/pm_buffer.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/peer_manager/pm_buffer.c
new file mode 100644
index 0000000..4fdbb34
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/peer_manager/pm_buffer.c
@@ -0,0 +1,151 @@
+/**
+ * Copyright (c) 2015 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#include "sdk_common.h"
+#if NRF_MODULE_ENABLED(PEER_MANAGER)
+#include "pm_buffer.h"
+
+#include <stdbool.h>
+#include <string.h>
+#include "nrf_error.h"
+#include "pm_mutex.h"
+
+
+#define BUFFER_IS_VALID(p_buffer) ((p_buffer != NULL) \
+ && (p_buffer->p_memory != NULL) \
+ && (p_buffer->p_mutex != NULL))
+
+
+
+ret_code_t pm_buffer_init(pm_buffer_t * p_buffer,
+ uint8_t * p_buffer_memory,
+ uint32_t buffer_memory_size,
+ uint8_t * p_mutex_memory,
+ uint32_t mutex_memory_size,
+ uint32_t n_blocks,
+ uint32_t block_size)
+{
+ if ( (p_buffer != NULL)
+ && (p_buffer_memory != NULL)
+ && (p_mutex_memory != NULL)
+ && (buffer_memory_size >= (n_blocks * block_size))
+ && (mutex_memory_size >= MUTEX_STORAGE_SIZE(n_blocks))
+ && (n_blocks != 0)
+ && (block_size != 0))
+ {
+ p_buffer->p_memory = p_buffer_memory;
+ p_buffer->p_mutex = p_mutex_memory;
+ p_buffer->n_blocks = n_blocks;
+ p_buffer->block_size = block_size;
+ pm_mutex_init(p_buffer->p_mutex, n_blocks);
+
+ return NRF_SUCCESS;
+ }
+ else
+ {
+ return NRF_ERROR_INVALID_PARAM;
+ }
+}
+
+
+uint8_t pm_buffer_block_acquire(pm_buffer_t * p_buffer, uint32_t n_blocks)
+{
+ if (!BUFFER_IS_VALID(p_buffer))
+ {
+ return ( PM_BUFFER_INVALID_ID );
+ }
+
+ uint8_t first_locked_mutex = PM_BUFFER_INVALID_ID;
+
+ for (uint8_t i = 0; i < p_buffer->n_blocks; i++)
+ {
+ if (pm_mutex_lock(p_buffer->p_mutex, i))
+ {
+ if (first_locked_mutex == PM_BUFFER_INVALID_ID)
+ {
+ first_locked_mutex = i;
+ }
+ if ((i - first_locked_mutex + 1) == n_blocks)
+ {
+ return first_locked_mutex;
+ }
+ }
+ else if (first_locked_mutex != PM_BUFFER_INVALID_ID)
+ {
+ for (uint8_t j = first_locked_mutex; j < i; j++)
+ {
+ pm_buffer_release(p_buffer, j);
+ }
+ first_locked_mutex = PM_BUFFER_INVALID_ID;
+ }
+ }
+
+ return ( PM_BUFFER_INVALID_ID );
+}
+
+
+uint8_t * pm_buffer_ptr_get(pm_buffer_t * p_buffer, uint8_t id)
+{
+ if (!BUFFER_IS_VALID(p_buffer))
+ {
+ return ( NULL );
+ }
+
+ if ( (id != PM_BUFFER_INVALID_ID)
+ && pm_mutex_lock_status_get(p_buffer->p_mutex, id) )
+ {
+ return ( &p_buffer->p_memory[id * p_buffer->block_size] );
+ }
+ else
+ {
+ return ( NULL );
+ }
+}
+
+
+void pm_buffer_release(pm_buffer_t * p_buffer, uint8_t id)
+{
+ if ( BUFFER_IS_VALID(p_buffer)
+ && (id != PM_BUFFER_INVALID_ID)
+ && pm_mutex_lock_status_get(p_buffer->p_mutex, id))
+ {
+ pm_mutex_unlock(p_buffer->p_mutex, id);
+ }
+}
+#endif // NRF_MODULE_ENABLED(PEER_MANAGER)
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/peer_manager/pm_buffer.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/peer_manager/pm_buffer.h
new file mode 100644
index 0000000..619af1d
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/peer_manager/pm_buffer.h
@@ -0,0 +1,159 @@
+/**
+ * Copyright (c) 2015 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#ifndef BUFFER_H__
+#define BUFFER_H__
+
+#include <stdint.h>
+#include "compiler_abstraction.h"
+#include "sdk_errors.h"
+#include "pm_mutex.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+/**
+ * @cond NO_DOXYGEN
+ * @defgroup pm_buffer Buffer
+ * @ingroup peer_manager
+ * @{
+ * @brief An internal module of @ref peer_manager. This module provides a simple buffer.
+ */
+
+
+#define PM_BUFFER_INVALID_ID 0xFF //!< Invalid buffer block ID.
+
+
+/**@brief Convenience macro for declaring memory and initializing a buffer instance.
+ *
+ * @param[out] p_buffer The buffer instance to initialize.
+ * @param[in] n_blocks The desired number of blocks in the buffer.
+ * @param[in] block_size The desired block size of the buffer.
+ * @param[out] err_code The return code from @ref pm_buffer_init.
+ */
+#define PM_BUFFER_INIT(p_buffer, n_blocks, block_size, err_code) \
+do \
+{ \
+ __ALIGN(4) static uint8_t buffer_memory[(n_blocks) * (block_size)]; \
+ static uint8_t mutex_memory[MUTEX_STORAGE_SIZE(n_blocks)]; \
+ err_code = pm_buffer_init((p_buffer), \
+ buffer_memory, \
+ (n_blocks) * (block_size), \
+ mutex_memory, \
+ MUTEX_STORAGE_SIZE(n_blocks), \
+ (n_blocks), \
+ (block_size)); \
+} while (0)
+
+
+typedef struct
+{
+ uint8_t * p_memory; /**< The storage for all buffer entries. The size of the buffer must be n_blocks*block_size. */
+ uint8_t * p_mutex; /**< A mutex group with one mutex for each buffer entry. */
+ uint32_t n_blocks; /**< The number of allocatable blocks in the buffer. */
+ uint32_t block_size; /**< The size of each block in the buffer. */
+} pm_buffer_t;
+
+/**@brief Function for initializing a buffer instance.
+ *
+ * @param[out] p_buffer The buffer instance to initialize.
+ * @param[in] p_buffer_memory The memory this buffer will use.
+ * @param[in] buffer_memory_size The size of p_buffer_memory. This must be at least
+ * n_blocks*block_size.
+ * @param[in] p_mutex_memory The memory for the mutexes. This must be at least
+ * @ref MUTEX_STORAGE_SIZE(n_blocks).
+ * @param[in] mutex_memory_size The size of p_mutex_memory.
+ * @param[in] n_blocks The number of blocks in the buffer.
+ * @param[in] block_size The size of each block.
+ *
+ * @retval NRF_SUCCESS Successfully initialized buffer instance.
+ * @retval NRF_ERROR_INVALID_PARAM A parameter was 0 or NULL or a size was too small.
+ */
+ret_code_t pm_buffer_init(pm_buffer_t * p_buffer,
+ uint8_t * p_buffer_memory,
+ uint32_t buffer_memory_size,
+ uint8_t * p_mutex_memory,
+ uint32_t mutex_memory_size,
+ uint32_t n_blocks,
+ uint32_t block_size);
+
+
+/**@brief Function for acquiring a buffer block in a buffer.
+ *
+ * @param[in] p_buffer The buffer instance acquire from.
+ * @param[in] n_blocks The number of contiguous blocks to acquire.
+ *
+ * @return The id of the acquired block, if successful.
+ * @retval PM_BUFFER_INVALID_ID If unsuccessful.
+ */
+uint8_t pm_buffer_block_acquire(pm_buffer_t * p_buffer, uint32_t n_blocks);
+
+
+/**@brief Function for getting a pointer to a specific buffer block.
+ *
+ * @param[in] p_buffer The buffer instance get from.
+ * @param[in] id The id of the buffer to get the pointer for.
+ *
+ * @return A pointer to the buffer for the specified id, if the id is valid.
+ * @retval NULL If the id is invalid.
+ */
+uint8_t * pm_buffer_ptr_get(pm_buffer_t * p_buffer, uint8_t id);
+
+
+/**@brief Function for releasing a buffer block.
+ *
+ * @param[in] p_buffer The buffer instance containing the block to release.
+ * @param[in] id The id of the block to release.
+ */
+void pm_buffer_release(pm_buffer_t * p_buffer, uint8_t id);
+
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // BUFFER_H__
+
+/**
+ * @}
+ * @endcond
+ */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/peer_manager/pm_mutex.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/peer_manager/pm_mutex.c
new file mode 100644
index 0000000..543a99b
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/peer_manager/pm_mutex.c
@@ -0,0 +1,144 @@
+/**
+ * Copyright (c) 2015 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#include "sdk_common.h"
+#if NRF_MODULE_ENABLED(PEER_MANAGER)
+#include "pm_mutex.h"
+
+#include <stdbool.h>
+#include <string.h>
+#include "nrf_error.h"
+#include "app_util_platform.h"
+
+
+
+/**@brief Locks the mutex defined by the mask.
+ *
+ * @param p_mutex pointer to the mutex storage.
+ * @param mutex_mask the mask identifying the mutex position.
+ *
+ * @retval true if the mutex could be locked.
+ * @retval false if the mutex was already locked.
+ */
+static bool lock_by_mask(uint8_t * p_mutex, uint8_t mutex_mask)
+{
+ bool success = false;
+
+ if ( (*p_mutex & mutex_mask) == 0 )
+ {
+ CRITICAL_REGION_ENTER();
+ if ( (*p_mutex & mutex_mask) == 0 )
+ {
+ *p_mutex |= mutex_mask;
+
+ success = true;
+ }
+ CRITICAL_REGION_EXIT();
+ }
+
+ return ( success );
+}
+
+
+void pm_mutex_init(uint8_t * p_mutex, uint16_t mutex_size)
+{
+ if (p_mutex != NULL)
+ {
+ memset(&p_mutex[0], 0, MUTEX_STORAGE_SIZE(mutex_size));
+ }
+}
+
+
+bool pm_mutex_lock(uint8_t * p_mutex, uint16_t mutex_id)
+{
+ if (p_mutex != NULL)
+ {
+ return ( lock_by_mask(&(p_mutex[mutex_id >> 3]), (1 << (mutex_id & 0x07))) );
+ }
+ else
+ {
+ return false;
+ }
+}
+
+
+void pm_mutex_unlock(uint8_t * p_mutex, uint16_t mutex_id)
+{
+ uint8_t mutex_base = mutex_id >> 3;
+ uint8_t mutex_mask = (1 << (mutex_id & 0x07));
+
+ if ((p_mutex != NULL)
+ && (p_mutex[mutex_base] & mutex_mask))
+ {
+ CRITICAL_REGION_ENTER();
+ p_mutex[mutex_base] &= ~mutex_mask;
+ CRITICAL_REGION_EXIT();
+ }
+}
+
+
+uint16_t pm_mutex_lock_first_available(uint8_t * p_mutex, uint16_t mutex_size)
+{
+ if (p_mutex != NULL)
+ {
+ for ( uint16_t i = 0; i < mutex_size; i++ )
+ {
+ if ( lock_by_mask(&(p_mutex[i >> 3]), 1 << (i & 0x07)) )
+ {
+ return ( i );
+ }
+ }
+ }
+
+ return ( mutex_size );
+}
+
+
+bool pm_mutex_lock_status_get(uint8_t * p_mutex, uint16_t mutex_id)
+{
+ if (p_mutex != NULL)
+ {
+ return ( (p_mutex[mutex_id >> 3] & (1 << (mutex_id & 0x07))) );
+ }
+ else
+ {
+ return true;
+ }
+}
+#endif // NRF_MODULE_ENABLED(PEER_MANAGER)
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/peer_manager/pm_mutex.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/peer_manager/pm_mutex.h
new file mode 100644
index 0000000..c598d3d
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/peer_manager/pm_mutex.h
@@ -0,0 +1,125 @@
+/**
+ * Copyright (c) 2015 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#ifndef MUTEX_H__
+#define MUTEX_H__
+
+
+#include <stdint.h>
+#include <stdbool.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @cond NO_DOXYGEN
+ * @defgroup pm_mutex Mutex
+ * @ingroup peer_manager
+ * @{
+ * @brief An internal module of @ref peer_manager. This module provides thread-safe mutexes.
+ */
+
+
+/**@brief Defines the storage size of a specified mutex group.
+ *
+ * @param number_of_mutexes the number of mutexes in the group.
+ */
+#define MUTEX_STORAGE_SIZE(number_of_mutexes) ((7 + (number_of_mutexes)) >> 3)
+
+
+/**@brief Initializes a mutex group.
+ *
+ * @param[in] p_mutex Pointer to the mutex group. See @ref MUTEX_STORAGE_SIZE().
+ * @param[in] mutex_size The size of the mutex group in number of mutexes.
+ */
+void pm_mutex_init(uint8_t * p_mutex, uint16_t mutex_size);
+
+
+/**@brief Locks the mutex specified by the bit id.
+ *
+ * @param[inout] p_mutex Pointer to the mutex group.
+ * @param[in] mutex_bit_id The bit id of the mutex.
+ *
+ * @retval true if it was possible to lock the mutex.
+ * @retval false otherwise.
+ */
+bool pm_mutex_lock(uint8_t * p_mutex, uint16_t mutex_bit_id);
+
+
+/**@brief Locks the first unlocked mutex within the mutex group.
+ *
+ * @param[in, out] p_mutex Pointer to the mutex group.
+ * @param[in] mutex_size The size of the mutex group.
+ *
+ * @return The first unlocked mutex id in the group.
+ * @retval group-size if there was no unlocked mutex available.
+ */
+uint16_t pm_mutex_lock_first_available(uint8_t * p_mutex, uint16_t mutex_size);
+
+
+/**@brief Unlocks the mutex specified by the bit id.
+ *
+ * @param[in, out] p_mutex Pointer to the mutex group.
+ * @param[in] mutex_bit_id The bit id of the mutex.
+ */
+void pm_mutex_unlock(uint8_t * p_mutex, uint16_t mutex_bit_id);
+
+
+/**@brief Gets the locking status of the specified mutex.
+ *
+ * @param[in, out] p_mutex Pointer to the mutex group.
+ * @param[in] mutex_bit_id The bit id of the mutex.
+ *
+ * @retval true if the mutex was locked.
+ * @retval false otherwise.
+ */
+bool pm_mutex_lock_status_get(uint8_t * p_mutex, uint16_t mutex_bit_id);
+
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // MUTEX_H__
+
+/** @}
+ * @endcond
+ */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/peer_manager/security_dispatcher.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/peer_manager/security_dispatcher.c
new file mode 100644
index 0000000..462bd62
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/peer_manager/security_dispatcher.c
@@ -0,0 +1,1110 @@
+/**
+ * Copyright (c) 2015 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#include "sdk_common.h"
+#if NRF_MODULE_ENABLED(PEER_MANAGER)
+#include "security_dispatcher.h"
+
+#include <string.h>
+#include "ble.h"
+#include "ble_gap.h"
+#include "ble_err.h"
+#include "ble_conn_state.h"
+#include "peer_manager_types.h"
+#include "peer_database.h"
+#include "id_manager.h"
+
+#ifndef PM_CENTRAL_ENABLED
+ #define PM_CENTRAL_ENABLED 1
+#endif
+
+// The number of registered event handlers.
+#define SMD_EVENT_HANDLERS_CNT (sizeof(m_evt_handlers) / sizeof(m_evt_handlers[0]))
+
+STATIC_ASSERT((NRF_SDH_BLE_CENTRAL_LINK_COUNT == 0) || PM_CENTRAL_ENABLED,
+ "Peer Manager Central operation must be enabled when using central links.");
+
+// Security Dispacher event handlers in Security Manager and GATT Cache Manager.
+extern void sm_smd_evt_handler(pm_evt_t * p_event);
+
+// Security Dispatcher events' handlers.
+// The number of elements in this array is SMD_EVENT_HANDLERS_CNT.
+static pm_evt_handler_internal_t const m_evt_handlers[] =
+{
+ sm_smd_evt_handler
+};
+
+static bool m_module_initialized;
+
+static ble_conn_state_user_flag_id_t m_flag_sec_proc = BLE_CONN_STATE_USER_FLAG_INVALID;
+static ble_conn_state_user_flag_id_t m_flag_sec_proc_pairing = BLE_CONN_STATE_USER_FLAG_INVALID;
+static ble_conn_state_user_flag_id_t m_flag_sec_proc_bonding = BLE_CONN_STATE_USER_FLAG_INVALID;
+static ble_conn_state_user_flag_id_t m_flag_sec_proc_new_peer = BLE_CONN_STATE_USER_FLAG_INVALID;
+static ble_conn_state_user_flag_id_t m_flag_allow_repairing = BLE_CONN_STATE_USER_FLAG_INVALID;
+
+static ble_gap_lesc_p256_pk_t m_peer_pk;
+
+
+static __INLINE bool sec_procedure(uint16_t conn_handle)
+{
+ return ble_conn_state_user_flag_get(conn_handle, m_flag_sec_proc);
+}
+
+static __INLINE bool pairing(uint16_t conn_handle)
+{
+ return ble_conn_state_user_flag_get(conn_handle, m_flag_sec_proc_pairing);
+}
+
+static __INLINE bool bonding(uint16_t conn_handle)
+{
+ return ble_conn_state_user_flag_get(conn_handle, m_flag_sec_proc_bonding);
+}
+
+static __INLINE bool peer_created(uint16_t conn_handle)
+{
+ return ble_conn_state_user_flag_get(conn_handle, m_flag_sec_proc_new_peer);
+}
+
+static __INLINE bool allow_repairing(uint16_t conn_handle)
+{
+ return ble_conn_state_user_flag_get(conn_handle, m_flag_allow_repairing);
+}
+
+
+/**@brief Function for sending an SMD event to all event handlers.
+ *
+ * @param[in] p_event The event to pass to all event handlers.
+ */
+static void evt_send(pm_evt_t * p_event)
+{
+ p_event->peer_id = im_peer_id_get_by_conn_handle(p_event->conn_handle);
+
+ for (uint32_t i = 0; i < SMD_EVENT_HANDLERS_CNT; i++)
+ {
+ m_evt_handlers[i](p_event);
+ }
+}
+
+
+/**@brief Function for sending a PM_EVT_CONN_SEC_START event.
+ *
+ * @param[in] conn_handle The connection handle the event pertains to.
+ * @param[in] procedure The procedure that has started on the connection.
+ */
+static void sec_start_send(uint16_t conn_handle,
+ pm_conn_sec_procedure_t procedure)
+{
+ pm_evt_t evt =
+ {
+ .evt_id = PM_EVT_CONN_SEC_START,
+ .conn_handle = conn_handle,
+ .params = {.conn_sec_start = {.procedure = procedure}}
+ };
+ evt_send(&evt);
+}
+
+
+/**@brief Function for sending a PM_EVT_ERROR_UNEXPECTED event.
+ *
+ * @param[in] conn_handle The connection handle the event pertains to.
+ * @param[in] err_code The unexpected error that occurred.
+ */
+static void send_unexpected_error(uint16_t conn_handle, ret_code_t err_code)
+{
+ pm_evt_t error_evt =
+ {
+ .evt_id = PM_EVT_ERROR_UNEXPECTED,
+ .conn_handle = conn_handle,
+ .params =
+ {
+ .error_unexpected =
+ {
+ .error = err_code,
+ }
+ }
+ };
+ evt_send(&error_evt);
+}
+
+
+/**@brief Function for cleaning up after a failed security procedure.
+ *
+ * @param[in] conn_handle The handle of the connection the security procedure happens on.
+ * @param[in] procedure The procedure that failed.
+ * @param[in] error The error the procedure failed with.
+ * @param[in] error_src The party that raised the error. See @ref BLE_GAP_SEC_STATUS_SOURCES.
+ */
+static void conn_sec_failure(uint16_t conn_handle,
+ pm_conn_sec_procedure_t procedure,
+ pm_sec_error_code_t error,
+ uint8_t error_src)
+{
+ pm_evt_t evt =
+ {
+ .evt_id = PM_EVT_CONN_SEC_FAILED,
+ .conn_handle = conn_handle,
+ .params =
+ {
+ .conn_sec_failed =
+ {
+ .procedure = procedure,
+ .error = error,
+ .error_src = error_src,
+ }
+ }
+ };
+
+ ble_conn_state_user_flag_set(conn_handle, m_flag_sec_proc, false);
+
+ evt_send(&evt);
+ return;
+}
+
+
+/**@brief Function for cleaning up after a failed pairing procedure.
+ *
+ * @param[in] conn_handle The handle of the connection the pairing procedure happens on.
+ * @param[in] error The error the procedure failed with.
+ * @param[in] error_src The source of the error (local or remote). See @ref
+ * BLE_GAP_SEC_STATUS_SOURCES.
+ */
+static void pairing_failure(uint16_t conn_handle,
+ pm_sec_error_code_t error,
+ uint8_t error_src)
+{
+ ret_code_t err_code = NRF_SUCCESS;
+ pm_peer_id_t peer_id = im_peer_id_get_by_conn_handle(conn_handle);
+ pm_conn_sec_procedure_t procedure = bonding(conn_handle) ? PM_CONN_SEC_PROCEDURE_BONDING
+ : PM_CONN_SEC_PROCEDURE_PAIRING;
+
+ if (peer_created(conn_handle))
+ {
+ // The peer_id was created during the procedure, and should be freed, because no data is
+ // stored under it.
+ err_code = im_peer_free(peer_id); // Attempt to free allocated peer.
+ UNUSED_VARIABLE(err_code);
+ }
+ else if(peer_id != PM_PEER_ID_INVALID)
+ {
+ err_code = pdb_write_buf_release(peer_id, PM_PEER_DATA_ID_BONDING);
+ if ((err_code != NRF_SUCCESS) && (err_code != NRF_ERROR_NOT_FOUND /* No buffer was allocated */))
+ {
+ send_unexpected_error(conn_handle, err_code);
+ }
+ }
+
+ conn_sec_failure(conn_handle, procedure, error, error_src);
+
+ return;
+}
+
+
+/**@brief Function for cleaning up after a failed encryption procedure.
+ *
+ * @param[in] conn_handle The handle of the connection the encryption procedure happens on.
+ * @param[in] error The error the procedure failed with.
+ * @param[in] error_src The party that raised the error. See @ref BLE_GAP_SEC_STATUS_SOURCES.
+ */
+static __INLINE void encryption_failure(uint16_t conn_handle,
+ pm_sec_error_code_t error,
+ uint8_t error_src)
+{
+ conn_sec_failure(conn_handle, PM_CONN_SEC_PROCEDURE_ENCRYPTION, error, error_src);
+
+ return;
+}
+
+
+/**@brief Function for possibly cleaning up after a failed pairing or encryption procedure.
+ *
+ * @param[in] conn_handle The handle of the connection the pairing procedure happens on.
+ * @param[in] error The error the procedure failed with.
+ * @param[in] error_src The party that raised the error. See @ref BLE_GAP_SEC_STATUS_SOURCES.
+ */
+static void link_secure_failure(uint16_t conn_handle,
+ pm_sec_error_code_t error,
+ uint8_t error_src)
+{
+ if (sec_procedure(conn_handle))
+ {
+ if (pairing(conn_handle))
+ {
+ pairing_failure(conn_handle, error, error_src);
+ }
+ else
+ {
+ encryption_failure(conn_handle, error, error_src);
+ }
+ }
+}
+
+
+/**@brief Function for administrative actions to be taken when a security process has started.
+ *
+ * @param[in] conn_handle The connection the security process was attempted on.
+ * @param[in] success Whether the procedure was started successfully.
+ * @param[in] procedure The procedure that was started.
+ */
+static void sec_proc_start(uint16_t conn_handle,
+ bool success,
+ pm_conn_sec_procedure_t procedure)
+{
+ ble_conn_state_user_flag_set(conn_handle, m_flag_sec_proc, success);
+ if (success)
+ {
+ ble_conn_state_user_flag_set(conn_handle,
+ m_flag_sec_proc_pairing,
+ (procedure != PM_CONN_SEC_PROCEDURE_ENCRYPTION));
+ ble_conn_state_user_flag_set(conn_handle,
+ m_flag_sec_proc_bonding,
+ (procedure == PM_CONN_SEC_PROCEDURE_BONDING));
+ ble_conn_state_user_flag_set(conn_handle, m_flag_sec_proc_new_peer, false);
+ sec_start_send(conn_handle, procedure);
+ }
+}
+
+
+
+/**@brief Function for administrative actions to be taken during the course of a security process.
+ *
+ * @param[in] conn_handle The connection the security process was attempted on.
+ * @param[in] peer_id The peer ID given to the connected peer.
+ * @param[in] success Whether the process was started successfully.
+ * @param[in] new_peer_created Whether a new peer was created during the process attempt.
+ */
+static void sec_proc_housekeeping(uint16_t conn_handle,
+ pm_peer_id_t peer_id,
+ bool success,
+ bool new_peer_created)
+{
+ if (success)
+ {
+ if (new_peer_created)
+ {
+ ble_conn_state_user_flag_set(conn_handle, m_flag_sec_proc_new_peer, true);
+ im_new_peer_id(conn_handle, peer_id);
+ }
+ }
+ else
+ {
+ if (new_peer_created)
+ {
+ ret_code_t err_code = im_peer_free(peer_id); // Attempt to free allocated peer.
+ UNUSED_VARIABLE(err_code);
+ }
+ }
+}
+
+
+
+/**@brief Function for processing the @ref BLE_GAP_EVT_SEC_INFO_REQUEST event from the SoftDevice.
+ *
+ * @param[in] p_gap_evt The event from the SoftDevice.
+ */
+static void sec_info_request_process(ble_gap_evt_t const * p_gap_evt)
+{
+ ret_code_t err_code;
+ ble_gap_enc_info_t const * p_enc_info = NULL;
+ pm_peer_data_flash_t peer_data;
+ pm_peer_id_t peer_id = im_peer_id_get_by_master_id(
+ &p_gap_evt->params.sec_info_request.master_id);
+
+ if (peer_id == PM_PEER_ID_INVALID)
+ {
+ peer_id = im_peer_id_get_by_conn_handle(p_gap_evt->conn_handle);
+ }
+ else
+ {
+ // The peer might have been unrecognized until now (since connecting). E.g. if using a
+ // random non-resolvable advertising address. Report the discovered peer ID just in case.
+ im_new_peer_id(p_gap_evt->conn_handle, peer_id);
+ }
+
+ sec_proc_start(p_gap_evt->conn_handle, true, PM_CONN_SEC_PROCEDURE_ENCRYPTION);
+
+ if (peer_id != PM_PEER_ID_INVALID)
+ {
+ err_code = pdb_peer_data_ptr_get(peer_id, PM_PEER_DATA_ID_BONDING, &peer_data);
+
+ if (err_code == NRF_SUCCESS)
+ {
+ // There is stored bonding data for this peer.
+ ble_gap_enc_key_t const * p_existing_key = &peer_data.p_bonding_data->own_ltk;
+
+ if ( p_existing_key->enc_info.lesc
+ || (im_master_ids_compare(&p_existing_key->master_id,
+ &p_gap_evt->params.sec_info_request.master_id)))
+ {
+ p_enc_info = &p_existing_key->enc_info;
+ }
+ }
+ }
+
+ err_code = sd_ble_gap_sec_info_reply(p_gap_evt->conn_handle, p_enc_info, NULL, NULL);
+
+ if (err_code != NRF_SUCCESS)
+ {
+ sec_proc_housekeeping(p_gap_evt->conn_handle, peer_id, false, false);
+ send_unexpected_error(p_gap_evt->conn_handle, err_code);
+ }
+ else if (p_enc_info == NULL)
+ {
+ sec_proc_housekeeping(p_gap_evt->conn_handle, peer_id, false, false);
+ encryption_failure(p_gap_evt->conn_handle,
+ PM_CONN_SEC_ERROR_PIN_OR_KEY_MISSING,
+ BLE_GAP_SEC_STATUS_SOURCE_LOCAL);
+ }
+
+ return;
+}
+
+
+/**@brief Function for sending a CONFIG_REQ event.
+ *
+ * @param[in] conn_handle The connection the sec parameters are needed for.
+ */
+static void send_config_req(uint16_t conn_handle)
+{
+ pm_evt_t evt;
+ memset(&evt, 0, sizeof(evt));
+
+ evt.evt_id = PM_EVT_CONN_SEC_CONFIG_REQ;
+ evt.conn_handle = conn_handle;
+
+ evt_send(&evt);
+}
+
+
+void smd_conn_sec_config_reply(uint16_t conn_handle, pm_conn_sec_config_t * p_conn_sec_config)
+{
+ NRF_PM_DEBUG_CHECK(m_module_initialized);
+ NRF_PM_DEBUG_CHECK(p_conn_sec_config != NULL);
+
+ ble_conn_state_user_flag_set(conn_handle,
+ m_flag_allow_repairing,
+ p_conn_sec_config->allow_repairing);
+}
+
+
+/**@brief Function for processing the @ref BLE_GAP_EVT_DISCONNECT event from the SoftDevice.
+ *
+ * @param[in] p_gap_evt The event from the SoftDevice.
+ */
+static void disconnect_process(ble_gap_evt_t const * p_gap_evt)
+{
+ pm_sec_error_code_t error = (p_gap_evt->params.disconnected.reason
+ == BLE_HCI_CONN_TERMINATED_DUE_TO_MIC_FAILURE)
+ ? PM_CONN_SEC_ERROR_MIC_FAILURE : PM_CONN_SEC_ERROR_DISCONNECT;
+
+ link_secure_failure(p_gap_evt->conn_handle, error, BLE_GAP_SEC_STATUS_SOURCE_LOCAL);
+}
+
+
+/**@brief Function for sending a PARAMS_REQ event.
+ *
+ * @param[in] conn_handle The connection the security parameters are needed for.
+ * @param[in] p_peer_params The security parameters from the peer. Can be NULL if the peer's parameters
+ * are not yet available.
+ */
+static void send_params_req(uint16_t conn_handle, ble_gap_sec_params_t const * p_peer_params)
+{
+ pm_evt_t evt =
+ {
+ .evt_id = PM_EVT_CONN_SEC_PARAMS_REQ,
+ .conn_handle = conn_handle,
+ .params =
+ {
+ .conn_sec_params_req =
+ {
+ .p_peer_params = p_peer_params
+ },
+ },
+ };
+
+ evt_send(&evt);
+}
+
+
+/**@brief Function for processing the @ref BLE_GAP_EVT_SEC_PARAMS_REQUEST event from the SoftDevice.
+ *
+ * @param[in] p_gap_evt The event from the SoftDevice.
+ */
+static void sec_params_request_process(ble_gap_evt_t const * p_gap_evt)
+{
+ if (ble_conn_state_role(p_gap_evt->conn_handle) == BLE_GAP_ROLE_PERIPH)
+ {
+ sec_proc_start(p_gap_evt->conn_handle,
+ true,
+ p_gap_evt->params.sec_params_request.peer_params.bond
+ ? PM_CONN_SEC_PROCEDURE_BONDING
+ : PM_CONN_SEC_PROCEDURE_PAIRING);
+ }
+
+ send_params_req(p_gap_evt->conn_handle, &p_gap_evt->params.sec_params_request.peer_params);
+ return;
+}
+
+
+/**@brief Function for processing the @ref BLE_GAP_EVT_AUTH_STATUS event from the SoftDevice, when
+ * the auth_status is success.
+ *
+ * @param[in] p_gap_evt The event from the SoftDevice.
+ */
+static void auth_status_success_process(ble_gap_evt_t const * p_gap_evt)
+{
+ ret_code_t err_code = NRF_SUCCESS;
+ uint16_t conn_handle = p_gap_evt->conn_handle;
+ pm_peer_id_t peer_id = im_peer_id_get_by_conn_handle(conn_handle);
+ pm_peer_id_t new_peer_id = peer_id;
+ pm_peer_data_t peer_data;
+ bool data_stored = false;
+
+ ble_conn_state_user_flag_set(conn_handle, m_flag_sec_proc, false);
+
+ if (p_gap_evt->params.auth_status.bonded)
+ {
+ pm_peer_id_t duplicate_peer_id = PM_PEER_ID_INVALID;
+ data_stored = true;
+
+ err_code = pdb_write_buf_get(peer_id, PM_PEER_DATA_ID_BONDING, 1, &peer_data);
+ if (err_code != NRF_SUCCESS)
+ {
+ send_unexpected_error(conn_handle, err_code);
+ data_stored = false;
+ }
+ else
+ {
+ duplicate_peer_id = im_find_duplicate_bonding_data(peer_data.p_bonding_data,
+ PM_PEER_ID_INVALID);
+ }
+
+ if (duplicate_peer_id != PM_PEER_ID_INVALID)
+ {
+ // The peer has been identified as someone we have already bonded with.
+ new_peer_id = duplicate_peer_id;
+ im_new_peer_id(conn_handle, new_peer_id);
+
+ // If the flag is true, the configuration has been requested before.
+ if (!allow_repairing(conn_handle))
+ {
+ send_config_req(conn_handle);
+ if (!allow_repairing(conn_handle))
+ {
+ data_stored = false;
+ }
+ }
+ }
+
+ if (data_stored)
+ {
+ err_code = pdb_write_buf_store(peer_id, PM_PEER_DATA_ID_BONDING, new_peer_id);
+ if (err_code != NRF_SUCCESS)
+ {
+ /* Unexpected */
+ send_unexpected_error(conn_handle, err_code);
+ data_stored = false;
+ }
+ }
+
+ if ((duplicate_peer_id != PM_PEER_ID_INVALID) && peer_created(conn_handle))
+ {
+ // We already have a bond with the peer. Now that the data has been stored for the
+ // existing peer, the peer created for this bonding procedure can be freed.
+ ret_code_t err_code_free = im_peer_free(peer_id);
+ UNUSED_VARIABLE(err_code_free); // Errors can be safely ignored.
+ }
+ }
+ else if (peer_created(conn_handle))
+ {
+ ret_code_t err_code_free = im_peer_free(peer_id);
+ UNUSED_VARIABLE(err_code_free); // Errors can be safely ignored.
+ }
+ else
+ {
+ // No action.
+ }
+
+ pm_evt_t pairing_success_evt;
+
+ pairing_success_evt.evt_id = PM_EVT_CONN_SEC_SUCCEEDED;
+ pairing_success_evt.conn_handle = conn_handle;
+ pairing_success_evt.params.conn_sec_succeeded.procedure = p_gap_evt->params.auth_status.bonded
+ ? PM_CONN_SEC_PROCEDURE_BONDING
+ : PM_CONN_SEC_PROCEDURE_PAIRING;
+ pairing_success_evt.params.conn_sec_succeeded.data_stored = data_stored;
+
+ evt_send(&pairing_success_evt);
+
+ return;
+}
+
+
+/**@brief Function for processing the @ref BLE_GAP_EVT_AUTH_STATUS event from the SoftDevice, when
+ * the auth_status is failure.
+ *
+ * @param[in] p_gap_evt The event from the SoftDevice.
+ */
+static void auth_status_failure_process(ble_gap_evt_t const * p_gap_evt)
+{
+ link_secure_failure(p_gap_evt->conn_handle,
+ p_gap_evt->params.auth_status.auth_status,
+ p_gap_evt->params.auth_status.error_src);
+}
+
+
+/**@brief Function for processing the @ref BLE_GAP_EVT_AUTH_STATUS event from the SoftDevice.
+ *
+ * @param[in] p_gap_evt The event from the SoftDevice.
+ */
+static void auth_status_process(ble_gap_evt_t const * p_gap_evt)
+{
+ switch (p_gap_evt->params.auth_status.auth_status)
+ {
+ case BLE_GAP_SEC_STATUS_SUCCESS:
+ auth_status_success_process(p_gap_evt);
+ break;
+
+ default:
+ auth_status_failure_process(p_gap_evt);
+ break;
+ }
+}
+
+
+/**@brief Function for processing the @ref BLE_GAP_EVT_CONN_SEC_UPDATE event from the SoftDevice.
+ *
+ * @param[in] p_gap_evt The event from the SoftDevice.
+ */
+static void conn_sec_update_process(ble_gap_evt_t const * p_gap_evt)
+{
+ if (!pairing(p_gap_evt->conn_handle))
+ {
+ // This is an encryption procedure (not pairing), so this event marks the end of the procedure.
+
+ if (!ble_conn_state_encrypted(p_gap_evt->conn_handle))
+ {
+ encryption_failure(p_gap_evt->conn_handle,
+ PM_CONN_SEC_ERROR_PIN_OR_KEY_MISSING,
+ BLE_GAP_SEC_STATUS_SOURCE_REMOTE);
+ }
+ else
+ {
+ ble_conn_state_user_flag_set(p_gap_evt->conn_handle, m_flag_sec_proc, false);
+
+ pm_evt_t evt;
+
+ evt.evt_id = PM_EVT_CONN_SEC_SUCCEEDED;
+ evt.conn_handle = p_gap_evt->conn_handle;
+ evt.params.conn_sec_succeeded.procedure = PM_CONN_SEC_PROCEDURE_ENCRYPTION;
+ evt.params.conn_sec_succeeded.data_stored = false;
+
+ evt_send(&evt);
+ }
+ }
+}
+
+
+/**@brief Funtion for initializing a BLE Connection State user flag.
+ *
+ * @param[out] flag_id The flag to initialize.
+ */
+static void flag_id_init(ble_conn_state_user_flag_id_t * p_flag_id)
+{
+ if (*p_flag_id == BLE_CONN_STATE_USER_FLAG_INVALID)
+ {
+ *p_flag_id = ble_conn_state_user_flag_acquire();
+ }
+}
+
+
+ret_code_t smd_init(void)
+{
+ NRF_PM_DEBUG_CHECK(!m_module_initialized);
+
+ flag_id_init(&m_flag_sec_proc);
+ flag_id_init(&m_flag_sec_proc_pairing);
+ flag_id_init(&m_flag_sec_proc_bonding);
+ flag_id_init(&m_flag_sec_proc_new_peer);
+ flag_id_init(&m_flag_allow_repairing);
+
+ if ((m_flag_sec_proc == BLE_CONN_STATE_USER_FLAG_INVALID) ||
+ (m_flag_sec_proc_pairing == BLE_CONN_STATE_USER_FLAG_INVALID) ||
+ (m_flag_sec_proc_bonding == BLE_CONN_STATE_USER_FLAG_INVALID) ||
+ (m_flag_sec_proc_new_peer == BLE_CONN_STATE_USER_FLAG_INVALID) ||
+ (m_flag_allow_repairing == BLE_CONN_STATE_USER_FLAG_INVALID))
+ {
+ return NRF_ERROR_INTERNAL;
+ }
+
+ m_module_initialized = true;
+
+ return NRF_SUCCESS;
+}
+
+
+/**@brief Function for putting retrieving a buffer and putting pointers into a @ref ble_gap_sec_keyset_t.
+ *
+ * @param[in] conn_handle The connection the security procedure is happening on.
+ * @param[in] peer_id The peer the security procedure is happening with.
+ * @param[in] role Our role in the connection.
+ * @param[in] p_public_key Pointer to a buffer holding the public key, or NULL.
+ * @param[out] p_sec_keyset Pointer to the keyset to be filled.
+ *
+ * @retval NRF_SUCCESS Success.
+ * @retval NRF_ERROR_STORAGE_FULL Not enough room in persistent storage.
+ * @retval NRF_ERROR_BUSY Could not process request at this time. Reattempt later.
+ * @retval NRF_ERROR_INVALID_PARAM Data ID or Peer ID was invalid or unallocated.
+ * @retval NRF_ERROR_INTERNAL Fatal error.
+ */
+static ret_code_t sec_keyset_fill(uint16_t conn_handle,
+ pm_peer_id_t peer_id,
+ uint8_t role,
+ ble_gap_lesc_p256_pk_t * p_public_key,
+ ble_gap_sec_keyset_t * p_sec_keyset)
+{
+ ret_code_t err_code;
+ pm_peer_data_t peer_data;
+
+ if (p_sec_keyset == NULL)
+ {
+ return NRF_ERROR_INTERNAL;
+ }
+
+ // Acquire a memory buffer to receive bonding data into.
+ err_code = pdb_write_buf_get(peer_id, PM_PEER_DATA_ID_BONDING, 1, &peer_data);
+
+ if (err_code == NRF_ERROR_BUSY)
+ {
+ // No action.
+ }
+ else if (err_code != NRF_SUCCESS)
+ {
+ err_code = NRF_ERROR_INTERNAL;
+ }
+ else /* if (err_code == NRF_SUCCESS) */
+ {
+ memset(peer_data.p_bonding_data, 0, sizeof(pm_peer_data_bonding_t));
+
+ peer_data.p_bonding_data->own_role = role;
+
+ p_sec_keyset->keys_own.p_enc_key = &peer_data.p_bonding_data->own_ltk;
+ p_sec_keyset->keys_own.p_pk = p_public_key;
+ p_sec_keyset->keys_peer.p_enc_key = &peer_data.p_bonding_data->peer_ltk;
+ p_sec_keyset->keys_peer.p_id_key = &peer_data.p_bonding_data->peer_ble_id;
+ p_sec_keyset->keys_peer.p_pk = &m_peer_pk;
+
+ // Retrieve the address the peer used during connection establishment.
+ // This address will be overwritten if ID is shared. Should not fail.
+ err_code = im_ble_addr_get(conn_handle, &peer_data.p_bonding_data->peer_ble_id.id_addr_info);
+ if (err_code != NRF_SUCCESS)
+ {
+ return NRF_ERROR_INTERNAL;
+ }
+
+ // Buffer is OK, reserve room in flash for the data.
+ err_code = pdb_write_buf_store_prepare(peer_id, PM_PEER_DATA_ID_BONDING);
+ if (err_code == NRF_ERROR_NOT_FOUND)
+ {
+ return NRF_ERROR_INTERNAL;
+ }
+ }
+
+ return err_code;
+}
+
+
+ret_code_t smd_params_reply(uint16_t conn_handle,
+ ble_gap_sec_params_t * p_sec_params,
+ ble_gap_lesc_p256_pk_t * p_public_key)
+{
+ NRF_PM_DEBUG_CHECK(m_module_initialized);
+
+ uint8_t role = ble_conn_state_role(conn_handle);
+ pm_peer_id_t peer_id = PM_PEER_ID_INVALID;
+ ret_code_t err_code = NRF_SUCCESS;
+ uint8_t sec_status = BLE_GAP_SEC_STATUS_SUCCESS;
+ bool new_peer_created = peer_created(conn_handle);
+ ble_gap_sec_keyset_t sec_keyset;
+
+ memset(&sec_keyset, 0, sizeof(ble_gap_sec_keyset_t));
+ if (role == BLE_GAP_ROLE_PERIPH)
+ {
+ // Set the default value for allowing repairing at the start of the sec proc. (for peripheral)
+ ble_conn_state_user_flag_set(conn_handle, m_flag_allow_repairing, false);
+ }
+
+ if (role == BLE_GAP_ROLE_INVALID)
+ {
+ return BLE_ERROR_INVALID_CONN_HANDLE;
+ }
+
+ if (p_sec_params == NULL)
+ {
+ // NULL params means reject pairing.
+ sec_status = BLE_GAP_SEC_STATUS_PAIRING_NOT_SUPP;
+ }
+ else if (!p_sec_params->bond)
+ {
+ // Pairing, no bonding.
+
+ sec_keyset.keys_own.p_pk = p_public_key;
+ sec_keyset.keys_peer.p_pk = &m_peer_pk;
+ }
+ else
+ {
+ // Bonding is to be performed, prepare to receive bonding data.
+
+ peer_id = im_peer_id_get_by_conn_handle(conn_handle);
+
+ if (peer_id == PM_PEER_ID_INVALID)
+ {
+ // Peer is unknown to us, allocate a new peer ID for it.
+ peer_id = pdb_peer_allocate();
+ if (peer_id != PM_PEER_ID_INVALID)
+ {
+ new_peer_created = true;
+ }
+ else
+ {
+ err_code = NRF_ERROR_INTERNAL;
+ }
+ }
+ else if (role == BLE_GAP_ROLE_PERIPH && !allow_repairing(conn_handle))
+ {
+ // Bond already exists. Reject the pairing request if the user doesn't intervene.
+ // send_config_req(conn_handle, peer_id);
+ send_config_req(conn_handle);
+ if (!allow_repairing(conn_handle))
+ {
+ // Reject pairing.
+ sec_status = BLE_GAP_SEC_STATUS_PAIRING_NOT_SUPP;
+ }
+ }
+
+ if ((sec_status != BLE_GAP_SEC_STATUS_PAIRING_NOT_SUPP) && (err_code == NRF_SUCCESS))
+ {
+ err_code = sec_keyset_fill(conn_handle, peer_id, role, p_public_key, &sec_keyset);
+ }
+ }
+
+ if (err_code == NRF_SUCCESS)
+ {
+ // Everything OK, reply to SoftDevice. If an error happened, the user is given an
+ // opportunity to change the parameters and retry the call.
+ if (role == BLE_GAP_ROLE_PERIPH)
+ {
+ err_code = sd_ble_gap_sec_params_reply(conn_handle, sec_status, p_sec_params, &sec_keyset);
+ }
+ else
+ {
+ err_code = sd_ble_gap_sec_params_reply(conn_handle, sec_status, NULL, &sec_keyset);
+ }
+ }
+
+ sec_proc_housekeeping(conn_handle,
+ peer_id,
+ (err_code == NRF_SUCCESS) && (sec_status == BLE_GAP_SEC_STATUS_SUCCESS),
+ new_peer_created);
+
+ return err_code;
+}
+
+
+#if PM_CENTRAL_ENABLED
+/**@brief Function for initiating encryption as a central. See @ref smd_link_secure for more info.
+ */
+static ret_code_t link_secure_central_encryption(uint16_t conn_handle,
+ pm_peer_id_t peer_id)
+{
+ pm_peer_data_flash_t peer_data;
+ ret_code_t err_code;
+ ble_gap_enc_key_t const * p_existing_key = NULL;
+ bool lesc = false;
+
+ err_code = pdb_peer_data_ptr_get(peer_id, PM_PEER_DATA_ID_BONDING, &peer_data);
+
+ if (err_code == NRF_SUCCESS)
+ {
+ // Use peer's key since they are peripheral.
+ p_existing_key = &(peer_data.p_bonding_data->peer_ltk);
+
+ lesc = peer_data.p_bonding_data->own_ltk.enc_info.lesc;
+ if (lesc) // LESC was used during bonding.
+ {
+ // For LESC, always use own key.
+ p_existing_key = &(peer_data.p_bonding_data->own_ltk);
+ }
+ }
+
+ if ((err_code != NRF_SUCCESS) && (err_code != NRF_ERROR_NOT_FOUND))
+ {
+ if (err_code != NRF_ERROR_BUSY)
+ {
+ // Unexpected error code.
+ err_code = NRF_ERROR_INTERNAL;
+ }
+ }
+ else if (p_existing_key == NULL) /* There is no bonding data stored. This means that a bonding
+ procedure is in ongoing, or that the records in flash are
+ in a bad state. */
+ {
+ err_code = NRF_ERROR_BUSY;
+ }
+ else if (!lesc && !im_master_id_is_valid(&(p_existing_key->master_id))) /* There is no valid LTK stored. */
+ {
+ // No LTK to encrypt with.
+ err_code = NRF_ERROR_INVALID_DATA;
+ }
+ else
+ {
+ // Encrypt with existing LTK.
+ err_code = sd_ble_gap_encrypt(conn_handle,
+ &(p_existing_key->master_id),
+ &(p_existing_key->enc_info));
+ }
+
+ sec_proc_start(conn_handle, err_code == NRF_SUCCESS, PM_CONN_SEC_PROCEDURE_ENCRYPTION);
+ sec_proc_housekeeping(conn_handle, peer_id, (err_code == NRF_SUCCESS), false);
+
+ return err_code;
+}
+
+
+/**@brief Function for intiating pairing as a central. See @ref smd_link_secure for more info.
+ */
+static ret_code_t link_secure_central_pairing(uint16_t conn_handle,
+ pm_peer_id_t peer_id,
+ ble_gap_sec_params_t * p_sec_params)
+{
+ pm_conn_sec_procedure_t procedure = PM_CONN_SEC_PROCEDURE_PAIRING;
+ bool new_peer_created = false;
+ ret_code_t err_code = NRF_SUCCESS;
+ pm_peer_data_t dummy_peer_data;
+
+ if (p_sec_params == NULL)
+ {
+ err_code = sd_ble_gap_authenticate(conn_handle, NULL);
+ }
+ else
+ {
+ if (p_sec_params->bond)
+ {
+ procedure = PM_CONN_SEC_PROCEDURE_BONDING;
+
+ if (peer_id == PM_PEER_ID_INVALID)
+ {
+ // New peer is required.
+ peer_id = pdb_peer_allocate();
+ new_peer_created = true;
+ }
+
+ if (peer_id == PM_PEER_ID_INVALID)
+ {
+ err_code = NRF_ERROR_INTERNAL;
+ }
+ else
+ {
+ err_code = pdb_write_buf_get(peer_id, PM_PEER_DATA_ID_BONDING, 1, &dummy_peer_data);
+ if (err_code == NRF_SUCCESS)
+ {
+ err_code = pdb_write_buf_store_prepare(peer_id, PM_PEER_DATA_ID_BONDING);
+ }
+ }
+ }
+
+ if (err_code == NRF_SUCCESS)
+ {
+ err_code = sd_ble_gap_authenticate(conn_handle, p_sec_params);
+ }
+
+ if (err_code != NRF_SUCCESS)
+ {
+ ret_code_t err_code_free = pdb_write_buf_release(peer_id, PM_PEER_DATA_ID_BONDING);
+ if ((err_code_free != NRF_SUCCESS) && (err_code_free != NRF_ERROR_NOT_FOUND))
+ {
+ err_code = NRF_ERROR_INTERNAL;
+ }
+ }
+ }
+
+ if (err_code == NRF_ERROR_NO_MEM)
+ {
+ // sd_ble_gap_authenticate() returned NRF_ERROR_NO_MEM. Too many other sec procedures running.
+ err_code = NRF_ERROR_BUSY;
+ }
+
+ sec_proc_start(conn_handle, err_code == NRF_SUCCESS, procedure);
+ sec_proc_housekeeping(conn_handle, peer_id, (err_code == NRF_SUCCESS), new_peer_created);
+
+ return err_code;
+}
+
+
+
+/**@brief Function for intiating security as a central. See @ref smd_link_secure for more info.
+ */
+static ret_code_t link_secure_central(uint16_t conn_handle,
+ ble_gap_sec_params_t * p_sec_params,
+ bool force_repairing)
+{
+ ret_code_t err_code;
+ pm_peer_id_t peer_id;
+
+ if (p_sec_params == NULL)
+ {
+ return sd_ble_gap_authenticate(conn_handle, NULL);
+ }
+
+ // Set the default value for allowing repairing at the start of the sec proc. (for central)
+ ble_conn_state_user_flag_set(conn_handle, m_flag_allow_repairing, force_repairing);
+
+ peer_id = im_peer_id_get_by_conn_handle(conn_handle);
+
+ if ((peer_id != PM_PEER_ID_INVALID) && !force_repairing)
+ {
+ // There is already data in flash for this peer, and repairing has not been requested, so
+ // link will be encrypted with the existing keys.
+ err_code = link_secure_central_encryption(conn_handle, peer_id);
+ }
+ else
+ {
+ // There are no existing keys, or repairing has been explicitly requested, so pairing
+ // (possibly including bonding) will be performed to encrypt the link.
+ err_code = link_secure_central_pairing(conn_handle, peer_id, p_sec_params);
+ }
+
+ return err_code;
+}
+
+/**@brief Function for processing the @ref BLE_GAP_EVT_SEC_REQUEST event from the SoftDevice.
+ *
+ * @param[in] p_gap_evt The event from the SoftDevice.
+ */
+static void sec_request_process(ble_gap_evt_t const * p_gap_evt)
+{
+ pm_evt_t evt =
+ {
+ .evt_id = PM_EVT_SLAVE_SECURITY_REQ,
+ .conn_handle = p_gap_evt->conn_handle,
+ .params =
+ {
+ .slave_security_req =
+ {
+ .bond = p_gap_evt->params.sec_request.bond,
+ .mitm = p_gap_evt->params.sec_request.mitm,
+ }
+ }
+ };
+ evt_send(&evt);
+ return;
+}
+#endif // PM_CENTRAL_ENABLED
+
+
+/**@brief Function for asking the central to secure the link. See @ref smd_link_secure for more info.
+ */
+static ret_code_t link_secure_peripheral(uint16_t conn_handle, ble_gap_sec_params_t * p_sec_params)
+{
+ ret_code_t err_code = NRF_SUCCESS;
+
+ if (p_sec_params != NULL)
+ {
+ err_code = sd_ble_gap_authenticate(conn_handle, p_sec_params);
+ }
+
+ return err_code;
+}
+
+
+ret_code_t smd_link_secure(uint16_t conn_handle,
+ ble_gap_sec_params_t * p_sec_params,
+ bool force_repairing)
+{
+ NRF_PM_DEBUG_CHECK(m_module_initialized);
+
+ uint8_t role = ble_conn_state_role(conn_handle);
+
+ switch (role)
+ {
+#if PM_CENTRAL_ENABLED
+ case BLE_GAP_ROLE_CENTRAL:
+ return link_secure_central(conn_handle, p_sec_params, force_repairing);
+#endif
+
+ case BLE_GAP_ROLE_PERIPH:
+ return link_secure_peripheral(conn_handle, p_sec_params);
+
+ default:
+ return BLE_ERROR_INVALID_CONN_HANDLE;
+ }
+}
+
+
+void smd_ble_evt_handler(ble_evt_t const * p_ble_evt)
+{
+ switch (p_ble_evt->header.evt_id)
+ {
+ case BLE_GAP_EVT_DISCONNECTED:
+ disconnect_process(&(p_ble_evt->evt.gap_evt));
+ break;
+
+ case BLE_GAP_EVT_SEC_PARAMS_REQUEST:
+ sec_params_request_process(&(p_ble_evt->evt.gap_evt));
+ break;
+
+ case BLE_GAP_EVT_SEC_INFO_REQUEST:
+ sec_info_request_process(&(p_ble_evt->evt.gap_evt));
+ break;
+
+#if PM_CENTRAL_ENABLED
+ case BLE_GAP_EVT_SEC_REQUEST:
+ sec_request_process(&(p_ble_evt->evt.gap_evt));
+ break;
+#endif
+
+ case BLE_GAP_EVT_AUTH_STATUS:
+ auth_status_process(&(p_ble_evt->evt.gap_evt));
+ break;
+
+ case BLE_GAP_EVT_CONN_SEC_UPDATE:
+ conn_sec_update_process(&(p_ble_evt->evt.gap_evt));
+ break;
+ };
+}
+#endif //NRF_MODULE_ENABLED(PEER_MANAGER)
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/peer_manager/security_dispatcher.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/peer_manager/security_dispatcher.h
new file mode 100644
index 0000000..0699276
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/peer_manager/security_dispatcher.h
@@ -0,0 +1,166 @@
+/**
+ * Copyright (c) 2015 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#ifndef SECURITY_DISPATCHER_H__
+#define SECURITY_DISPATCHER_H__
+
+#include <stdint.h>
+#include "sdk_errors.h"
+#include "ble.h"
+#include "ble_gap.h"
+#include "peer_manager_types.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+/**
+ * @cond NO_DOXYGEN
+ * @defgroup security_dispatcher Security Dispatcher
+ * @ingroup peer_manager
+ * @{
+ * @brief An internal module of @ref peer_manager. A module for streamlining pairing, bonding, and
+ * encryption, including flash storage of shared data.
+ *
+ */
+
+
+/**@brief Function for initializing the Security Dispatcher module.
+ *
+ * @retval NRF_SUCCESS Initialization was successful.
+ * @retval NRF_ERROR_INTERNAL An unexpected fatal error occurred.
+ */
+ret_code_t smd_init(void);
+
+
+/**@brief Function for dispatching SoftDevice events to the Security Dispatcher module.
+ *
+ * @param[in] ble_evt The SoftDevice event.
+ */
+void smd_ble_evt_handler(ble_evt_t const * ble_evt);
+
+
+/**@brief Function for providing security configuration for a link.
+ *
+ * @details This function is optional, and must be called in reply to a @ref
+ * PM_EVT_CONN_SEC_CONFIG_REQ event, before the Peer Manager event handler returns. If it
+ * is not called in time, a default configuration is used. See @ref pm_conn_sec_config_t
+ * for the value of the default.
+ *
+ * @param[in] conn_handle The connection to set the configuration for.
+ * @param[in] p_conn_sec_config The configuration.
+ */
+void smd_conn_sec_config_reply(uint16_t conn_handle, pm_conn_sec_config_t * p_conn_sec_config);
+
+
+/**@brief Function for providing pairing and bonding parameters to use for the current pairing
+ * procedure on a connection.
+ *
+ * @note If this function returns an @ref NRF_ERROR_NULL, @ref NRF_ERROR_INVALID_PARAM, @ref
+ * BLE_ERROR_INVALID_CONN_HANDLE, or @ref NRF_ERROR_STORAGE_FULL, this function can be called
+ * again after corrective action.
+ *
+ * @note To reject a request, call this function with NULL p_sec_params.
+ *
+ * @param[in] conn_handle The connection handle of the connection the pairing is happening on.
+ * @param[in] p_sec_params The security parameters to use for this link.
+ * @param[in] p_public_key A pointer to the public key to use if using LESC, or NULL.
+ *
+ * @retval NRF_SUCCESS Success.
+ * @retval NRF_ERROR_INVALID_STATE No parameters have been requested on that conn_handle, or
+ * the link is disconnecting.
+ * @retval NRF_ERROR_INVALID_PARAM Invalid combination of parameters (not including conn_handle).
+ * @retval NRF_ERROR_TIMEOUT There has been an SMP timeout, so no more SMP operations
+ * can be performed on this link.
+ * @retval BLE_ERROR_INVALID_CONN_HANDLE Invalid connection handle.
+ * @retval NRF_ERROR_STORAGE_FULL No more room in flash. Fix and reattempt after the next
+ * FDS garbage collection procedure.
+ * @retval NRF_ERROR_BUSY No write buffer. Reattempt later.
+ * @retval NRF_ERROR_INTERNAL A fatal error occurred.
+ */
+ret_code_t smd_params_reply(uint16_t conn_handle,
+ ble_gap_sec_params_t * p_sec_params,
+ ble_gap_lesc_p256_pk_t * p_public_key);
+
+
+/**@brief Function for initiating security on the link, with the specified parameters.
+ *
+ * @note If the connection is a peripheral connection, this will send a security request to the
+ * master, but the master is not obligated to initiate pairing or encryption in response.
+ * @note If the connection is a central connection and a key is available, the parameters will be
+ * used to determine whether to re-pair or to encrypt using the existing key. If no key is
+ * available, pairing will be started.
+ *
+ * @param[in] conn_handle Handle of the connection to initiate pairing on.
+ * @param[in] p_sec_params The security parameters to use for this link. As a central, this can
+ * be NULL to reject a slave security request.
+ * @param[in] force_repairing Whether to force a pairing procedure to happen regardless of whether
+ * an encryption key already exists. This argument is only relevant for
+ * the central role. Recommended value: false
+ *
+ * @retval NRF_SUCCESS Success.
+ * @retval NRF_ERROR_NULL p_sec_params was NULL (peripheral only).
+ * @retval NRF_ERROR_INVALID_STATE A security procedure is already in progress on the link,
+ * or the link is disconnecting.
+ * @retval NRF_ERROR_INVALID_PARAM Invalid combination of parameters (not including conn_handle).
+ * @retval NRF_ERROR_INVALID_DATA Peer is bonded, but no LTK was found, and repairing was
+ * not requested.
+ * @retval NRF_ERROR_BUSY Unable to initiate procedure at this time.
+ * @retval NRF_ERROR_TIMEOUT There has been an SMP timeout, so no more SMP operations
+ * can be performed on this link.
+ * @retval BLE_ERROR_INVALID_CONN_HANDLE Invalid connection handle.
+ * @retval NRF_ERROR_STORAGE_FULL No more room in flash. Fix and reattempt after the next
+ * FDS garbage collection procedure.
+ * @retval NRF_ERROR_INTERNAL No more available peer IDs.
+ */
+ret_code_t smd_link_secure(uint16_t conn_handle,
+ ble_gap_sec_params_t * p_sec_params,
+ bool force_repairing);
+
+/** @}
+ * @endcond
+ */
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* SECURITY_DISPATCHER_H__ */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/peer_manager/security_manager.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/peer_manager/security_manager.c
new file mode 100644
index 0000000..86da8a0
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/peer_manager/security_manager.c
@@ -0,0 +1,675 @@
+/**
+ * Copyright (c) 2015 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#include "sdk_common.h"
+#if NRF_MODULE_ENABLED(PEER_MANAGER)
+#include "security_manager.h"
+
+#include <string.h>
+#include "ble_err.h"
+#include "security_dispatcher.h"
+#include "peer_database.h"
+#include "ble_conn_state.h"
+#include "id_manager.h"
+#include "sdk_common.h"
+
+
+// The number of registered event handlers.
+#define SM_EVENT_HANDLERS_CNT (sizeof(m_evt_handlers) / sizeof(m_evt_handlers[0]))
+
+
+// Security Manager event handler in Peer Manager.
+extern void pm_sm_evt_handler(pm_evt_t * p_sm_evt);
+
+// Security Manager events' handlers.
+// The number of elements in this array is SM_EVENT_HANDLERS_CNT.
+static pm_evt_handler_internal_t const m_evt_handlers[] =
+{
+ pm_sm_evt_handler
+};
+
+
+// The context type that is used in PM_EVT_CONN_SEC_PARAMS_REQ events and in calls to sm_sec_params_reply().
+typedef struct
+{
+ ble_gap_sec_params_t * p_sec_params; //!< The security parameters to use in the call to the security_dispatcher
+ ble_gap_sec_params_t sec_params_mem; //!< The buffer for holding the security parameters.
+ bool params_reply_called; //!< Whether @ref sm_sec_params_reply has been called for this context instance.
+} sec_params_reply_context_t;
+
+static bool m_module_initialized; //!< Whether the Security Manager module has been initialized.
+
+static ble_gap_sec_params_t m_sec_params; //!< The buffer for the default security parameters set by @ref sm_sec_params_set.
+static ble_gap_sec_params_t * mp_sec_params = NULL; //!< The default security parameters set by @ref sm_sec_params_set.
+static bool m_sec_params_set = false; //!< Whether @ref sm_sec_params_set has been called.
+
+static ble_gap_lesc_p256_pk_t * m_p_public_key; //!< Pointer, provided by the user, to the public key to use for LESC procedures.
+
+static ble_conn_state_user_flag_id_t m_flag_link_secure_pending_busy = BLE_CONN_STATE_USER_FLAG_INVALID; //!< User flag indicating whether a connection has a pending call to @ref sm_link_secure because it returned @ref NRF_ERROR_BUSY.
+static ble_conn_state_user_flag_id_t m_flag_link_secure_pending_flash_full = BLE_CONN_STATE_USER_FLAG_INVALID; //!< User flag indicating whether a connection has a pending call to @ref sm_link_secure because it returned @ref NRF_ERROR_STORAGE_FULL.
+static ble_conn_state_user_flag_id_t m_flag_link_secure_force_repairing = BLE_CONN_STATE_USER_FLAG_INVALID; //!< User flag indicating whether a pending call to @ref sm_link_secure should be called with true for the force_repairing parameter.
+static ble_conn_state_user_flag_id_t m_flag_link_secure_null_params = BLE_CONN_STATE_USER_FLAG_INVALID; //!< User flag indicating whether a pending call to @ref sm_link_secure should be called with NULL security parameters.
+static ble_conn_state_user_flag_id_t m_flag_params_reply_pending_busy = BLE_CONN_STATE_USER_FLAG_INVALID; //!< User flag indicating whether a connection has a pending call to @ref sm_sec_params_reply because it returned @ref NRF_ERROR_BUSY.
+static ble_conn_state_user_flag_id_t m_flag_params_reply_pending_flash_full = BLE_CONN_STATE_USER_FLAG_INVALID; //!< User flag indicating whether a connection has a pending call to @ref sm_sec_params_reply because it returned @ref NRF_ERROR_STORAGE_FULL.
+
+
+/**@brief Function for sending an SM event to all registered event handlers.
+ *
+ * @param[in] p_event The event to send.
+ */
+static void evt_send(pm_evt_t * p_event)
+{
+ for (uint32_t i = 0; i < SM_EVENT_HANDLERS_CNT; i++)
+ {
+ m_evt_handlers[i](p_event);
+ }
+}
+
+
+/**@brief Function for setting or clearing user flags based on error codes returned from @ref
+ * smd_link_secure or @ref smd_params_reply.
+ *
+ * @param[in] conn_handle The connection the call pertained to.
+ * @param[in] err_code The error code returned from @ref smd_link_secure or
+ * @ref smd_params_reply.
+ * @param[in] params_reply Whether the call was to @ref smd_params_reply.
+ */
+static void flags_set_from_err_code(uint16_t conn_handle, ret_code_t err_code, bool params_reply)
+{
+ bool flag_value_flash_full = false;
+ bool flag_value_busy = false;
+
+ if ((err_code == NRF_ERROR_STORAGE_FULL))
+ {
+ flag_value_busy = false;
+ flag_value_flash_full = true;
+ }
+ else if (err_code == NRF_ERROR_BUSY)
+ {
+ flag_value_busy = true;
+ flag_value_flash_full = false;
+ }
+ else
+ {
+ flag_value_busy = false;
+ flag_value_flash_full = false;
+ }
+
+ if (params_reply)
+ {
+ ble_conn_state_user_flag_set(conn_handle,
+ m_flag_params_reply_pending_flash_full,
+ flag_value_flash_full);
+ ble_conn_state_user_flag_set(conn_handle,
+ m_flag_params_reply_pending_busy,
+ flag_value_busy);
+ ble_conn_state_user_flag_set(conn_handle,
+ m_flag_link_secure_pending_flash_full,
+ false);
+ ble_conn_state_user_flag_set(conn_handle,
+ m_flag_link_secure_pending_busy,
+ false);
+ }
+ else
+ {
+ ble_conn_state_user_flag_set(conn_handle,
+ m_flag_link_secure_pending_flash_full,
+ flag_value_flash_full);
+ ble_conn_state_user_flag_set(conn_handle,
+ m_flag_link_secure_pending_busy,
+ flag_value_busy);
+ }
+}
+
+
+/**@brief Function for sending an event based on error codes returned from @ref smd_link_secure or
+ * @ref smd_params_reply.
+ *
+ * @param[in] conn_handle The connection the event pertains to.
+ * @param[in] err_code The error code returned from @ref smd_link_secure or
+ * @ref smd_params_reply.
+ * @param[in] p_sec_params The security parameters attempted to pass in the call to
+ * @ref smd_link_secure or @ref smd_params_reply.
+ */
+static void events_send_from_err_code(uint16_t conn_handle,
+ ret_code_t err_code,
+ ble_gap_sec_params_t * p_sec_params)
+{
+ if ((err_code != NRF_SUCCESS) && (err_code != NRF_ERROR_BUSY) && (err_code != NRF_ERROR_INVALID_STATE))
+ {
+ pm_evt_t evt =
+ {
+ .conn_handle = conn_handle,
+ .peer_id = im_peer_id_get_by_conn_handle(conn_handle),
+ };
+ if (err_code == NRF_ERROR_TIMEOUT)
+ {
+ evt.evt_id = PM_EVT_CONN_SEC_FAILED;
+ evt.params.conn_sec_failed.procedure = ((p_sec_params != NULL) && p_sec_params->bond)
+ ? PM_CONN_SEC_PROCEDURE_BONDING
+ : PM_CONN_SEC_PROCEDURE_PAIRING;
+ evt.params.conn_sec_failed.error_src = BLE_GAP_SEC_STATUS_SOURCE_LOCAL;
+ evt.params.conn_sec_failed.error = PM_CONN_SEC_ERROR_SMP_TIMEOUT;
+ }
+ else if (err_code == NRF_ERROR_STORAGE_FULL)
+ {
+ evt.evt_id = PM_EVT_STORAGE_FULL;
+ }
+ else
+ {
+ evt.evt_id = PM_EVT_ERROR_UNEXPECTED;
+ evt.params.error_unexpected.error = err_code;
+ }
+ evt_send(&evt);
+ }
+}
+
+
+/**@brief Function for sending an PM_EVT_CONN_SEC_PARAMS_REQ event.
+ *
+ * @param[in] conn_handle The connection the event pertains to.
+ * @param[in] p_peer_params The peer's security parameters to include in the event. Can be NULL.
+ * @param[in] p_context Pointer to a context that the user must include in the call to @ref
+ * sm_sec_params_reply().
+ */
+static void params_req_send(uint16_t conn_handle,
+ ble_gap_sec_params_t const * p_peer_params,
+ sec_params_reply_context_t * p_context)
+{
+ pm_evt_t evt;
+ evt.evt_id = PM_EVT_CONN_SEC_PARAMS_REQ;
+ evt.conn_handle = conn_handle;
+ evt.peer_id = im_peer_id_get_by_conn_handle(conn_handle);
+ evt.params.conn_sec_params_req.p_peer_params = p_peer_params;
+ evt.params.conn_sec_params_req.p_context = p_context;
+
+ evt_send(&evt);
+}
+
+
+/**@brief Function for creating a new @ref sec_params_reply_context_t with the correct initial values.
+ *
+ * @return The new context.
+ */
+static sec_params_reply_context_t new_context_get(void)
+{
+ sec_params_reply_context_t new_context =
+ {
+ .p_sec_params = mp_sec_params,
+ .params_reply_called = false
+ };
+ return new_context;
+}
+
+
+/**@brief Internal function corresponding to @ref sm_link_secure.
+ *
+ * @param[in] conn_handle The connection to secure.
+ * @param[in] null_params Whether to pass NULL security parameters to the security_dispatcher.
+ * @param[in] force_repairing Whether to force rebonding if peer exists.
+ * @param[in] send_events Whether to send events based on the result of @ref smd_link_secure.
+ *
+ * @return Same return codes as @ref sm_link_secure.
+ */
+static ret_code_t link_secure(uint16_t conn_handle,
+ bool null_params,
+ bool force_repairing,
+ bool send_events)
+{
+ ret_code_t err_code;
+ ret_code_t return_err_code;
+ ble_gap_sec_params_t * p_sec_params;
+
+ if (null_params)
+ {
+ p_sec_params = NULL;
+ }
+ else
+ {
+ sec_params_reply_context_t context = new_context_get();
+ params_req_send(conn_handle, NULL, &context);
+ p_sec_params = context.p_sec_params;
+
+ if (!m_sec_params_set && !context.params_reply_called)
+ {
+ // Security parameters have not been set.
+ return NRF_ERROR_NOT_FOUND;
+ }
+ }
+
+
+ err_code = smd_link_secure(conn_handle, p_sec_params, force_repairing);
+
+ flags_set_from_err_code(conn_handle, err_code, false);
+
+ switch (err_code)
+ {
+ case NRF_ERROR_BUSY:
+ ble_conn_state_user_flag_set(conn_handle, m_flag_link_secure_null_params, null_params);
+ ble_conn_state_user_flag_set(conn_handle, m_flag_link_secure_force_repairing, force_repairing);
+ return_err_code = NRF_SUCCESS;
+ break;
+ case NRF_ERROR_STORAGE_FULL:
+ ble_conn_state_user_flag_set(conn_handle, m_flag_link_secure_null_params, null_params);
+ ble_conn_state_user_flag_set(conn_handle, m_flag_link_secure_force_repairing, force_repairing);
+ /* fallthrough */
+ case NRF_SUCCESS:
+ case NRF_ERROR_TIMEOUT:
+ case BLE_ERROR_INVALID_CONN_HANDLE:
+ case NRF_ERROR_INVALID_STATE:
+ case NRF_ERROR_INVALID_DATA:
+ return_err_code = err_code;
+ break;
+ default:
+ return_err_code = NRF_ERROR_INTERNAL;
+ break;
+ }
+
+ if (send_events)
+ {
+ events_send_from_err_code(conn_handle, err_code, p_sec_params);
+ }
+
+ return return_err_code;
+}
+
+
+/**@brief Function for requesting security parameters from the user and passing them to the security_dispatcher.
+ *
+ * @param[in] conn_handle The connection that needs security parameters.
+ * @param[in] p_peer_params The peer's security parameters if present. Otherwise NULL.
+ */
+static void smd_params_reply_perform(uint16_t conn_handle, ble_gap_sec_params_t const * p_peer_params)
+{
+ ret_code_t err_code;
+ sec_params_reply_context_t context = new_context_get();
+
+ params_req_send(conn_handle, p_peer_params, &context);
+
+ err_code = smd_params_reply(conn_handle, context.p_sec_params, m_p_public_key);
+
+ flags_set_from_err_code(conn_handle, err_code, true);
+ events_send_from_err_code(conn_handle, err_code, context.p_sec_params);
+}
+
+
+/**@brief Function for handling @ref PM_EVT_CONN_SEC_PARAMS_REQ events.
+ *
+ * @param[in] p_event The @ref PM_EVT_CONN_SEC_PARAMS_REQ event.
+ */
+static __INLINE void params_req_process(pm_evt_t const * p_event)
+{
+ smd_params_reply_perform(p_event->conn_handle, p_event->params.conn_sec_params_req.p_peer_params);
+}
+
+
+/**@brief Function for handling @ref PM_EVT_SLAVE_SECURITY_REQ events.
+ *
+ * @param[in] p_event The @ref PM_EVT_SLAVE_SECURITY_REQ event.
+ */
+static void sec_req_process(pm_evt_t const * p_event)
+{
+ bool null_params = false;
+ if (mp_sec_params == NULL)
+ {
+ null_params = true;
+ }
+ else if ((bool)m_sec_params.bond < (bool)p_event->params.slave_security_req.bond)
+ {
+ null_params = true;
+ }
+ else if ((bool)m_sec_params.mitm < (bool)p_event->params.slave_security_req.mitm)
+ {
+ null_params = true;
+ }
+ else
+ {
+ // No action.
+ }
+ ret_code_t err_code = link_secure(p_event->conn_handle, null_params, false, true);
+ UNUSED_VARIABLE(err_code); // It is acceptable to ignore the return code because it is
+ // acceptable to ignore a security request.
+}
+
+
+/**@brief Function for translating an SMD event to an SM event and passing it on to SM event handlers.
+ *
+ * @param[in] p_event The event to forward.
+ */
+static void evt_forward(pm_evt_t * p_event)
+{
+ evt_send(p_event);
+}
+
+
+/**@brief Event handler for events from the Security Dispatcher module.
+ * This handler is extern in Security Dispatcher.
+ *
+ * @param[in] p_event The event that has happened.
+ */
+void sm_smd_evt_handler(pm_evt_t * p_event)
+{
+ switch (p_event->evt_id)
+ {
+ case PM_EVT_CONN_SEC_PARAMS_REQ:
+ params_req_process(p_event);
+ break;
+ case PM_EVT_SLAVE_SECURITY_REQ:
+ sec_req_process(p_event);
+ /* fallthrough */
+ default:
+ // Forward the event to all registered Security Manager event handlers.
+ evt_forward(p_event);
+ break;
+ }
+}
+
+
+/**@brief Function handling a pending params_reply. See @ref ble_conn_state_user_function_t.
+ */
+static void params_reply_pending_handle(uint16_t conn_handle, void * p_context)
+{
+ UNUSED_PARAMETER(p_context);
+ smd_params_reply_perform(conn_handle, NULL);
+}
+
+
+/**@brief Function handling a pending link_secure. See @ref ble_conn_state_user_function_t.
+ */
+static void link_secure_pending_handle(uint16_t conn_handle, void * p_context)
+{
+ UNUSED_PARAMETER(p_context);
+
+ bool force_repairing = ble_conn_state_user_flag_get(conn_handle, m_flag_link_secure_force_repairing);
+ bool null_params = ble_conn_state_user_flag_get(conn_handle, m_flag_link_secure_null_params);
+
+ // If this fails, it will be automatically retried.
+ ret_code_t err_code = link_secure(conn_handle, null_params, force_repairing, true);
+ UNUSED_VARIABLE(err_code);
+}
+
+
+/**@brief Event handler for events from the Peer Database module.
+ * This handler is extern in Peer Database.
+ *
+ * @param[in] p_event The event that has happened.
+ */
+void sm_pdb_evt_handler(pm_evt_t * p_event)
+{
+ switch (p_event->evt_id)
+ {
+ case PM_EVT_FLASH_GARBAGE_COLLECTED:
+ (void) ble_conn_state_for_each_set_user_flag(m_flag_params_reply_pending_flash_full,
+ params_reply_pending_handle,
+ NULL);
+ (void) ble_conn_state_for_each_set_user_flag(m_flag_link_secure_pending_flash_full,
+ link_secure_pending_handle,
+ NULL);
+ /* fallthrough */
+ case PM_EVT_PEER_DATA_UPDATE_SUCCEEDED:
+ case PM_EVT_PEER_DATA_UPDATE_FAILED:
+ case PM_EVT_PEER_DELETE_SUCCEEDED:
+ case PM_EVT_PEER_DELETE_FAILED:
+ (void) ble_conn_state_for_each_set_user_flag(m_flag_params_reply_pending_busy,
+ params_reply_pending_handle,
+ NULL);
+ (void) ble_conn_state_for_each_set_user_flag(m_flag_link_secure_pending_busy,
+ link_secure_pending_handle,
+ NULL);
+ break;
+ default:
+ // Do nothing.
+ break;
+ }
+}
+
+
+/**@brief Funtion for initializing a BLE Connection State user flag.
+ *
+ * @param[out] flag_id The flag to initialize.
+ */
+static void flag_id_init(ble_conn_state_user_flag_id_t * p_flag_id)
+{
+ if (*p_flag_id == BLE_CONN_STATE_USER_FLAG_INVALID)
+ {
+ *p_flag_id = ble_conn_state_user_flag_acquire();
+ }
+}
+
+
+ret_code_t sm_init(void)
+{
+ NRF_PM_DEBUG_CHECK(!m_module_initialized);
+
+ flag_id_init(&m_flag_link_secure_pending_busy);
+ flag_id_init(&m_flag_link_secure_pending_flash_full);
+ flag_id_init(&m_flag_link_secure_force_repairing);
+ flag_id_init(&m_flag_link_secure_null_params);
+ flag_id_init(&m_flag_params_reply_pending_busy);
+ flag_id_init(&m_flag_params_reply_pending_flash_full);
+
+ if (m_flag_params_reply_pending_flash_full == BLE_CONN_STATE_USER_FLAG_INVALID)
+ {
+ return NRF_ERROR_INTERNAL;
+ }
+
+ m_module_initialized = true;
+
+ return NRF_SUCCESS;
+}
+
+
+void sm_ble_evt_handler(ble_evt_t const * p_ble_evt)
+{
+ NRF_PM_DEBUG_CHECK(p_ble_evt != NULL);
+
+ smd_ble_evt_handler(p_ble_evt);
+ (void) ble_conn_state_for_each_set_user_flag(m_flag_link_secure_pending_busy,
+ link_secure_pending_handle,
+ NULL);
+}
+
+
+/**@brief Funtion for checking whether security parameters are valid.
+ *
+ * @param[out] p_sec_params The security parameters to verify.
+ *
+ * @return Whether the security parameters are valid.
+ */
+static bool sec_params_verify(ble_gap_sec_params_t * p_sec_params)
+{
+ // NULL check.
+ if (p_sec_params == NULL)
+ {
+ return false;
+ }
+
+ // OOB not allowed unless MITM.
+ if (!p_sec_params->mitm && p_sec_params->oob)
+ {
+ return false;
+ }
+
+ // IO Capabilities must be one of the valid values from @ref BLE_GAP_IO_CAPS.
+ if (p_sec_params->io_caps > BLE_GAP_IO_CAPS_KEYBOARD_DISPLAY)
+ {
+ return false;
+ }
+
+ // Must have either IO capabilities or OOB if MITM.
+ if (p_sec_params->mitm && (p_sec_params->io_caps == BLE_GAP_IO_CAPS_NONE) && !p_sec_params->oob)
+ {
+ return false;
+ }
+
+ // Minimum key size cannot be larger than maximum key size.
+ if (p_sec_params->min_key_size > p_sec_params->max_key_size)
+ {
+ return false;
+ }
+
+ // Key size cannot be below 7 bytes.
+ if (p_sec_params->min_key_size < 7)
+ {
+ return false;
+ }
+
+ // Key size cannot be above 16 bytes.
+ if (p_sec_params->max_key_size > 16)
+ {
+ return false;
+ }
+
+ // Signing is not supported.
+ if (p_sec_params->kdist_own.sign || p_sec_params->kdist_peer.sign)
+ {
+ return false;
+ }
+
+ // link bit must be 0.
+ if (p_sec_params->kdist_own.link || p_sec_params->kdist_peer.link)
+ {
+ return false;
+ }
+
+ // If bonding is not enabled, no keys can be distributed.
+ if (!p_sec_params->bond && ( p_sec_params->kdist_own.enc
+ || p_sec_params->kdist_own.id
+ || p_sec_params->kdist_peer.enc
+ || p_sec_params->kdist_peer.id))
+ {
+ return false;
+ }
+
+ // If bonding is enabled, one or more keys must be distributed.
+ if ( p_sec_params->bond
+ && !p_sec_params->kdist_own.enc
+ && !p_sec_params->kdist_own.id
+ && !p_sec_params->kdist_peer.enc
+ && !p_sec_params->kdist_peer.id)
+ {
+ return false;
+ }
+
+ return true;
+}
+
+
+ret_code_t sm_sec_params_set(ble_gap_sec_params_t * p_sec_params)
+{
+ NRF_PM_DEBUG_CHECK(m_module_initialized);
+
+ if (p_sec_params == NULL)
+ {
+ mp_sec_params = NULL;
+ m_sec_params_set = true;
+ return NRF_SUCCESS;
+ }
+ else if (sec_params_verify(p_sec_params))
+ {
+ m_sec_params = *p_sec_params;
+ mp_sec_params = &m_sec_params;
+ m_sec_params_set = true;
+ return NRF_SUCCESS;
+ }
+ else
+ {
+ return NRF_ERROR_INVALID_PARAM;
+ }
+}
+
+
+void sm_conn_sec_config_reply(uint16_t conn_handle, pm_conn_sec_config_t * p_conn_sec_config)
+{
+ NRF_PM_DEBUG_CHECK(m_module_initialized);
+ NRF_PM_DEBUG_CHECK(p_conn_sec_config != NULL);
+
+ smd_conn_sec_config_reply(conn_handle, p_conn_sec_config);
+}
+
+
+ret_code_t sm_sec_params_reply(uint16_t conn_handle,
+ ble_gap_sec_params_t * p_sec_params,
+ void const * p_context)
+{
+ NRF_PM_DEBUG_CHECK(m_module_initialized);
+ VERIFY_PARAM_NOT_NULL(p_context);
+
+ sec_params_reply_context_t * p_sec_params_reply_context = (sec_params_reply_context_t *)p_context;
+ if (p_sec_params == NULL)
+ {
+ // Set the store pointer to NULL, so that NULL is passed to the SoftDevice.
+ p_sec_params_reply_context->p_sec_params = NULL;
+ }
+ else if (sec_params_verify(p_sec_params))
+ {
+ // Copy the provided sec_params into the store.
+ p_sec_params_reply_context->sec_params_mem = *p_sec_params;
+ p_sec_params_reply_context->p_sec_params = &p_sec_params_reply_context->sec_params_mem;
+ }
+ else
+ {
+ return NRF_ERROR_INVALID_PARAM;
+ }
+ p_sec_params_reply_context->params_reply_called = true;
+
+ return NRF_SUCCESS;
+}
+
+
+ret_code_t sm_lesc_public_key_set(ble_gap_lesc_p256_pk_t * p_public_key)
+{
+ NRF_PM_DEBUG_CHECK(m_module_initialized);
+
+ m_p_public_key = p_public_key;
+
+ return NRF_SUCCESS;
+}
+
+
+ret_code_t sm_link_secure(uint16_t conn_handle, bool force_repairing)
+{
+ ret_code_t ret;
+
+ NRF_PM_DEBUG_CHECK(m_module_initialized);
+
+ ret = link_secure(conn_handle, false, force_repairing, false);
+ return ret;
+}
+#endif // NRF_MODULE_ENABLED(PEER_MANAGER)
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/peer_manager/security_manager.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/peer_manager/security_manager.h
new file mode 100644
index 0000000..a91c15d
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/ble/peer_manager/security_manager.h
@@ -0,0 +1,181 @@
+/**
+ * Copyright (c) 2015 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#ifndef SECURITY_MANAGER_H__
+#define SECURITY_MANAGER_H__
+
+#include <stdint.h>
+#include "sdk_errors.h"
+#include "ble.h"
+#include "ble_gap.h"
+#include "peer_manager_types.h"
+#include "security_dispatcher.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+/**
+ * @cond NO_DOXYGEN
+ * @defgroup security_manager Security Manager
+ * @ingroup peer_manager
+ * @{
+ * @brief An internal module of @ref peer_manager. A module for streamlining pairing, bonding, and
+ * encryption, including flash storage of shared data.
+ */
+
+
+/**@brief Function for initializing the Security Manager module.
+ *
+ * @retval NRF_SUCCESS If initialization was successful.
+ * @retval NRF_ERROR_INTERNAL If an unexpected error occurred.
+ */
+ret_code_t sm_init(void);
+
+
+/**@brief Function for dispatching SoftDevice events to the Security Manager module.
+ *
+ * @param[in] ble_evt The SoftDevice event.
+ */
+void sm_ble_evt_handler(ble_evt_t const * ble_evt);
+
+
+/**@brief Function for providing pairing and bonding parameters to use for pairing procedures.
+ *
+ * @details Until this is called, all bonding procedures initiated by the peer will be rejected.
+ * This function can be called multiple times, even with NULL p_sec_params, in which case
+ * it will go back to rejecting all procedures.
+ *
+ * @param[in] p_sec_params The security parameters to use for this link. Can be NULL to reject
+ * all pairing procedures.
+ *
+ * @retval NRF_SUCCESS Success.
+ * @retval NRF_ERROR_INVALID_PARAM Invalid combination of parameters.
+ */
+ret_code_t sm_sec_params_set(ble_gap_sec_params_t * p_sec_params);
+
+
+/**@brief Function for providing security configuration for a link.
+ *
+ * @details This function is optional, and must be called in reply to a @ref
+ * PM_EVT_CONN_SEC_CONFIG_REQ event, before the Peer Manager event handler returns. If it
+ * is not called in time, a default configuration is used. See @ref pm_conn_sec_config_t
+ * for the value of the default.
+ *
+ * @param[in] conn_handle The connection to set the configuration for.
+ * @param[in] p_conn_sec_config The configuration.
+ */
+void sm_conn_sec_config_reply(uint16_t conn_handle, pm_conn_sec_config_t * p_conn_sec_config);
+
+
+/**@brief Function for providing security parameters for a link.
+ *
+ * @details This function is optional, and must be called in reply to a @ref
+ * PM_EVT_CONN_SEC_PARAMS_REQ event, before the Security Manager event handler returns. If
+ * it is not called in time, the parameters given in @ref sm_sec_params_set are used. See
+ * @ref pm_conn_sec_config_t for the value of the default.
+ *
+ * @param[in] conn_handle The connection to set the parameters for.
+ * @param[in] p_sec_params The parameters. If NULL, the security procedure is rejected.
+ * @param[in] p_context The context found in the request event that this function replies to.
+ *
+ * @retval NRF_SUCCESS Successful reply.
+ * @retval NRF_ERROR_NULL p_context was null.
+ * @retval NRF_ERROR_INVALID_PARAM Value of p_sec_params was invalid.
+ * @retval NRF_ERROR_INVALID_STATE This module is not initialized.
+ */
+ret_code_t sm_sec_params_reply(uint16_t conn_handle,
+ ble_gap_sec_params_t * p_sec_params,
+ void const * p_context);
+
+
+/**@brief Experimental function for specifying the public key to use for LESC operations.
+ *
+ * @details This function can be called multiple times. The specified public key will be used for
+ * all subsequent LESC (LE Secure Connections) operations until the next time this function
+ * is called.
+ *
+ * @note The key must continue to reside in application memory as it is not copied by Peer Manager.
+ *
+ * @param[in] p_public_key The public key to use for all subsequent LESC operations.
+ *
+ * @retval NRF_SUCCESS Pairing initiated successfully.
+ * @retval NRF_ERROR_INVALID_STATE This module is not initialized.
+ */
+ret_code_t sm_lesc_public_key_set(ble_gap_lesc_p256_pk_t * p_public_key);
+
+
+
+/**@brief Function for initiating security on the link, with the specified parameters.
+ *
+ * @note If the connection is a peripheral connection, this will send a security request to the
+ * master, but the master is not obligated to initiate pairing or encryption in response.
+ * @note If the connection is a central connection and a key is available, the parameters will be
+ * used to determine whether to re-pair or to encrypt using the existing key. If no key is
+ * available, pairing will be started.
+ *
+ * @param[in] conn_handle Handle of the connection to initiate pairing on.
+ * @param[in] force_repairing Whether to force a pairing procedure to happen regardless of whether
+ * an encryption key already exists. This argument is only relevant for
+ * the central role. Recommended value: false
+ *
+ * @retval NRF_SUCCESS Success.
+ * @retval NRF_ERROR_TIMEOUT There has been an SMP timeout, so no more SMP operations
+ * can be performed on this link.
+ * @retval BLE_ERROR_INVALID_CONN_HANDLE Invalid connection handle.
+ * @retval NRF_ERROR_INVALID_DATA Peer is bonded, but no LTK was found, and repairing was
+ * not requested.
+ * @retval NRF_ERROR_NOT_FOUND Security parameters have not been set.
+ * @retval NRF_ERROR_INVALID_STATE A security procedure is already in progress on the link,
+ * or the link is disconnecting.
+ * @retval NRF_ERROR_INTERNAL An unexpected error occurred.
+ */
+ret_code_t sm_link_secure(uint16_t conn_handle, bool force_repairing);
+
+/** @}
+ * @endcond
+ */
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* SECURITY_MANAGER_H__ */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/boards/arduino_primo.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/boards/arduino_primo.h
new file mode 100644
index 0000000..0d56b7d
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/boards/arduino_primo.h
@@ -0,0 +1,113 @@
+/**
+ * Copyright (c) 2016 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#ifndef ARDUINO_PRIMO_H
+#define ARDUINO_PRIMO_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+// LEDs definitions
+#define LEDS_NUMBER 1
+
+#define LED_1 20
+
+#define LEDS_ACTIVE_STATE 0
+
+#define LEDS_LIST { LED_1}
+
+#define BSP_LED_0 LED_1
+
+#define LEDS_INV_MASK 0
+
+#define BUTTONS_NUMBER 1
+
+#define BUTTON_START 7
+#define BUTTON_1 7
+#define BUTTON_STOP 7
+#define BUTTON_PULL NRF_GPIO_PIN_PULLUP
+
+#define BUTTONS_ACTIVE_STATE 0
+
+#define BUTTONS_LIST { BUTTON_1 }
+
+#define BSP_BUTTON_0 BUTTON_1
+
+#define RX_PIN_NUMBER 11
+#define TX_PIN_NUMBER 12
+#define CTS_PIN_NUMBER UART_PIN_DISCONNECTED
+#define RTS_PIN_NUMBER UART_PIN_DISCONNECTED
+#define HWFC false
+
+#define BUZZER_PIN_NUMBER 8
+
+// Arduino board mappings
+#define ARDUINO_SCL_PIN 27 // SCL signal pin
+#define ARDUINO_SDA_PIN 26 // SDA signal pin
+#define ARDUINO_AREF_PIN 2 // Aref pin
+#define ARDUINO_13_PIN 25 // Digital pin 13
+#define ARDUINO_12_PIN 24 // Digital pin 12
+#define ARDUINO_11_PIN 23 // Digital pin 11
+#define ARDUINO_10_PIN 22 // Digital pin 10
+#define ARDUINO_9_PIN 20 // Digital pin 9
+#define ARDUINO_8_PIN 19 // Digital pin 8
+
+#define ARDUINO_7_PIN 18 // Digital pin 7
+#define ARDUINO_6_PIN 17 // Digital pin 6
+#define ARDUINO_5_PIN 16 // Digital pin 5
+#define ARDUINO_4_PIN 15 // Digital pin 4
+#define ARDUINO_3_PIN 14 // Digital pin 3
+#define ARDUINO_2_PIN 13 // Digital pin 2
+#define ARDUINO_1_PIN 12 // Digital pin 1
+#define ARDUINO_0_PIN 11 // Digital pin 0
+
+#define ARDUINO_A0_PIN 3 // Analog channel 0
+#define ARDUINO_A1_PIN 4 // Analog channel 1
+#define ARDUINO_A2_PIN 28 // Analog channel 2
+#define ARDUINO_A3_PIN 29 // Analog channel 3
+#define ARDUINO_A4_PIN 30 // Analog channel 4
+#define ARDUINO_A5_PIN 31 // Analog channel 5
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // ARDUINO_PRIMO_H
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/boards/boards.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/boards/boards.c
new file mode 100644
index 0000000..3551fc9
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/boards/boards.c
@@ -0,0 +1,228 @@
+/**
+ * Copyright (c) 2016 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#include "boards.h"
+#if defined(BOARDS_WITH_USB_DFU_TRIGGER) && defined(BOARD_PCA10059)
+#include "nrf_dfu_trigger_usb.h"
+#endif
+#include <stdint.h>
+#include <stdbool.h>
+
+#if LEDS_NUMBER > 0
+static const uint8_t m_board_led_list[LEDS_NUMBER] = LEDS_LIST;
+#endif
+
+#if BUTTONS_NUMBER > 0
+static const uint8_t m_board_btn_list[BUTTONS_NUMBER] = BUTTONS_LIST;
+#endif
+
+#if LEDS_NUMBER > 0
+bool bsp_board_led_state_get(uint32_t led_idx)
+{
+ ASSERT(led_idx < LEDS_NUMBER);
+ bool pin_set = nrf_gpio_pin_out_read(m_board_led_list[led_idx]) ? true : false;
+ return (pin_set == (LEDS_ACTIVE_STATE ? true : false));
+}
+
+void bsp_board_led_on(uint32_t led_idx)
+{
+ ASSERT(led_idx < LEDS_NUMBER);
+ nrf_gpio_pin_write(m_board_led_list[led_idx], LEDS_ACTIVE_STATE ? 1 : 0);
+}
+
+void bsp_board_led_off(uint32_t led_idx)
+{
+ ASSERT(led_idx < LEDS_NUMBER);
+ nrf_gpio_pin_write(m_board_led_list[led_idx], LEDS_ACTIVE_STATE ? 0 : 1);
+}
+
+void bsp_board_leds_off(void)
+{
+ uint32_t i;
+ for (i = 0; i < LEDS_NUMBER; ++i)
+ {
+ bsp_board_led_off(i);
+ }
+}
+
+void bsp_board_leds_on(void)
+{
+ uint32_t i;
+ for (i = 0; i < LEDS_NUMBER; ++i)
+ {
+ bsp_board_led_on(i);
+ }
+}
+
+void bsp_board_led_invert(uint32_t led_idx)
+{
+ ASSERT(led_idx < LEDS_NUMBER);
+ nrf_gpio_pin_toggle(m_board_led_list[led_idx]);
+}
+
+#if defined(BOARD_PCA10059)
+/**
+ * Function for configuring UICR_REGOUT0 register
+ * to set GPIO output voltage to 3.0V.
+ */
+static void gpio_output_voltage_setup(void)
+{
+ // Configure UICR_REGOUT0 register only if it is set to default value.
+ if ((NRF_UICR->REGOUT0 & UICR_REGOUT0_VOUT_Msk) ==
+ (UICR_REGOUT0_VOUT_DEFAULT << UICR_REGOUT0_VOUT_Pos))
+ {
+ NRF_NVMC->CONFIG = NVMC_CONFIG_WEN_Wen;
+ while (NRF_NVMC->READY == NVMC_READY_READY_Busy){}
+
+ NRF_UICR->REGOUT0 = (NRF_UICR->REGOUT0 & ~((uint32_t)UICR_REGOUT0_VOUT_Msk)) |
+ (UICR_REGOUT0_VOUT_3V0 << UICR_REGOUT0_VOUT_Pos);
+
+ NRF_NVMC->CONFIG = NVMC_CONFIG_WEN_Ren;
+ while (NRF_NVMC->READY == NVMC_READY_READY_Busy){}
+
+ // System reset is needed to update UICR registers.
+ NVIC_SystemReset();
+ }
+}
+#endif
+
+static void bsp_board_leds_init(void)
+{
+ #if defined(BOARD_PCA10059)
+ // If nRF52 USB Dongle is powered from USB (high voltage mode),
+ // GPIO output voltage is set to 1.8 V by default, which is not
+ // enough to turn on green and blue LEDs. Therefore, GPIO voltage
+ // needs to be increased to 3.0 V by configuring the UICR register.
+ if (NRF_POWER->MAINREGSTATUS &
+ (POWER_MAINREGSTATUS_MAINREGSTATUS_High << POWER_MAINREGSTATUS_MAINREGSTATUS_Pos))
+ {
+ gpio_output_voltage_setup();
+ }
+ #endif
+
+ uint32_t i;
+ for (i = 0; i < LEDS_NUMBER; ++i)
+ {
+ nrf_gpio_cfg_output(m_board_led_list[i]);
+ }
+ bsp_board_leds_off();
+}
+
+uint32_t bsp_board_led_idx_to_pin(uint32_t led_idx)
+{
+ ASSERT(led_idx < LEDS_NUMBER);
+ return m_board_led_list[led_idx];
+}
+
+uint32_t bsp_board_pin_to_led_idx(uint32_t pin_number)
+{
+ uint32_t ret = 0xFFFFFFFF;
+ uint32_t i;
+ for (i = 0; i < LEDS_NUMBER; ++i)
+ {
+ if (m_board_led_list[i] == pin_number)
+ {
+ ret = i;
+ break;
+ }
+ }
+ return ret;
+}
+#endif //LEDS_NUMBER > 0
+
+#if BUTTONS_NUMBER > 0
+bool bsp_board_button_state_get(uint32_t button_idx)
+{
+ ASSERT(button_idx < BUTTONS_NUMBER);
+ bool pin_set = nrf_gpio_pin_read(m_board_btn_list[button_idx]) ? true : false;
+ return (pin_set == (BUTTONS_ACTIVE_STATE ? true : false));
+}
+
+static void bsp_board_buttons_init(void)
+{
+ uint32_t i;
+ for (i = 0; i < BUTTONS_NUMBER; ++i)
+ {
+ nrf_gpio_cfg_input(m_board_btn_list[i], BUTTON_PULL);
+ }
+}
+
+uint32_t bsp_board_pin_to_button_idx(uint32_t pin_number)
+{
+ uint32_t i;
+ uint32_t ret = 0xFFFFFFFF;
+ for (i = 0; i < BUTTONS_NUMBER; ++i)
+ {
+ if (m_board_btn_list[i] == pin_number)
+ {
+ ret = i;
+ break;
+ }
+ }
+ return ret;
+}
+
+uint32_t bsp_board_button_idx_to_pin(uint32_t button_idx)
+{
+ ASSERT(button_idx < BUTTONS_NUMBER);
+ return m_board_btn_list[button_idx];
+}
+#endif //BUTTONS_NUMBER > 0
+
+
+void bsp_board_init(uint32_t init_flags)
+{
+ #if defined(BOARDS_WITH_USB_DFU_TRIGGER) && defined(BOARD_PCA10059)
+ (void) nrf_dfu_trigger_usb_init();
+ #endif
+
+ #if LEDS_NUMBER > 0
+ if (init_flags & BSP_INIT_LEDS)
+ {
+ bsp_board_leds_init();
+ }
+ #endif //LEDS_NUMBER > 0
+
+ #if BUTTONS_NUMBER > 0
+ if (init_flags & BSP_INIT_BUTTONS)
+ {
+ bsp_board_buttons_init();
+ }
+ #endif //BUTTONS_NUMBER > 0
+}
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/boards/boards.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/boards/boards.h
new file mode 100644
index 0000000..4b56d56
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/boards/boards.h
@@ -0,0 +1,355 @@
+/**
+ * Copyright (c) 2014 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#ifndef BOARDS_H
+#define BOARDS_H
+
+#include "nrf_gpio.h"
+#include "nordic_common.h"
+
+#if defined(BOARD_NRF6310)
+ #include "nrf6310.h"
+#elif defined(BOARD_PCA10000)
+ #include "pca10000.h"
+#elif defined(BOARD_PCA10001)
+ #include "pca10001.h"
+#elif defined(BOARD_PCA10002)
+ #include "pca10000.h"
+#elif defined(BOARD_PCA10003)
+ #include "pca10003.h"
+#elif defined(BOARD_PCA20006)
+ #include "pca20006.h"
+#elif defined(BOARD_PCA10028)
+ #include "pca10028.h"
+#elif defined(BOARD_PCA10031)
+ #include "pca10031.h"
+#elif defined(BOARD_PCA10036)
+ #include "pca10036.h"
+#elif defined(BOARD_PCA10040)
+ #include "pca10040.h"
+#elif defined(BOARD_PCA10056)
+ #include "pca10056.h"
+#elif defined(BOARD_PCA20020)
+ #include "pca20020.h"
+#elif defined(BOARD_PCA10059)
+ #include "pca10059.h"
+#elif defined(BOARD_WT51822)
+ #include "wt51822.h"
+#elif defined(BOARD_N5DK1)
+ #include "n5_starterkit.h"
+#elif defined (BOARD_D52DK1)
+ #include "d52_starterkit.h"
+#elif defined (BOARD_ARDUINO_PRIMO)
+ #include "arduino_primo.h"
+#elif defined (CUSTOM_BOARD_INC)
+ #include STRINGIFY(CUSTOM_BOARD_INC.h)
+#elif defined(BOARD_CUSTOM)
+ #include "custom_board.h"
+#else
+#error "Board is not defined"
+
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**@defgroup BSP_BOARD_INIT_FLAGS Board initialization flags.
+ * @{ */
+#define BSP_INIT_NONE 0 /**< No initialization of LEDs or buttons (@ref bsp_board_init).*/
+#define BSP_INIT_LEDS (1 << 0) /**< Enable LEDs during initialization (@ref bsp_board_init).*/
+#define BSP_INIT_BUTTONS (1 << 1) /**< Enable buttons during initialization (@ref bsp_board_init).*/
+/**@} */
+
+/**
+ * Function for returning the state of an LED.
+ *
+ * @param led_idx LED index (starting from 0), as defined in the board-specific header.
+ *
+ * @return True if the LED is turned on.
+ */
+bool bsp_board_led_state_get(uint32_t led_idx);
+
+/**
+ * Function for turning on an LED.
+ *
+ * @param led_idx LED index (starting from 0), as defined in the board-specific header.
+ */
+void bsp_board_led_on(uint32_t led_idx);
+
+/**
+ * Function for turning off an LED.
+ *
+ * @param led_idx LED index (starting from 0), as defined in the board-specific header.
+ */
+void bsp_board_led_off(uint32_t led_idx);
+
+/**
+ * Function for inverting the state of an LED.
+ *
+ * @param led_idx LED index (starting from 0), as defined in the board-specific header.
+ */
+void bsp_board_led_invert(uint32_t led_idx);
+/**
+ * Function for turning off all LEDs.
+ */
+void bsp_board_leds_off(void);
+
+/**
+ * Function for turning on all LEDs.
+ */
+void bsp_board_leds_on(void);
+
+/**
+ * Function for initializing the BSP handling for the board.
+ *
+ * @note This also initializes the USB DFU trigger library if @ref BOARDS_WITH_USB_DFU_TRIGGER is 1.
+ *
+ * @param[in] init_flags Flags specifying what to initialize (LEDs/buttons).
+ * See @ref BSP_BOARD_INIT_FLAGS.
+ */
+void bsp_board_init(uint32_t init_flags);
+
+/**
+ * Function for converting pin number to LED index.
+ *
+ * @param pin_number Pin number.
+ *
+ * @return LED index of the given pin or 0xFFFFFFFF if invalid pin provided.
+ */
+uint32_t bsp_board_pin_to_led_idx(uint32_t pin_number);
+
+/**
+ * Function for converting LED index to pin number.
+ *
+ * @param led_idx LED index.
+ *
+ * @return Pin number.
+ */
+uint32_t bsp_board_led_idx_to_pin(uint32_t led_idx);
+
+/**
+ * Function for returning the state of a button.
+ *
+ * @param button_idx Button index (starting from 0), as defined in the board-specific header.
+ *
+ * @return True if the button is pressed.
+ */
+bool bsp_board_button_state_get(uint32_t button_idx);
+
+/**
+ * Function for converting pin number to button index.
+ *
+ * @param pin_number Pin number.
+ *
+ * @return Button index of the given pin or 0xFFFFFFFF if invalid pin provided.
+ */
+uint32_t bsp_board_pin_to_button_idx(uint32_t pin_number);
+
+
+/**
+ * Function for converting button index to pin number.
+ *
+ * @param button_idx Button index.
+ *
+ * @return Pin number.
+ */
+uint32_t bsp_board_button_idx_to_pin(uint32_t button_idx);
+
+#define BSP_BOARD_LED_0 0
+#define BSP_BOARD_LED_1 1
+#define BSP_BOARD_LED_2 2
+#define BSP_BOARD_LED_3 3
+#define BSP_BOARD_LED_4 4
+#define BSP_BOARD_LED_5 5
+#define BSP_BOARD_LED_6 6
+#define BSP_BOARD_LED_7 7
+
+#define PIN_MASK(_pin) /*lint -save -e504 */ \
+ (1u << (uint32_t)((_pin) & (~P0_PIN_NUM))) \
+ /*lint -restore */
+
+#define PIN_PORT(_pin) (((_pin) >= P0_PIN_NUM) ? NRF_P1 : NRF_GPIO)
+
+#ifdef BSP_LED_0
+#define BSP_LED_0_MASK PIN_MASK(BSP_LED_0)
+#define BSP_LED_0_PORT PIN_PORT(BSP_LED_0)
+#else
+#define BSP_LED_0_MASK 0
+#define BSP_LED_0_PORT 0
+#endif
+#ifdef BSP_LED_1
+#define BSP_LED_1_MASK PIN_MASK(BSP_LED_1)
+#define BSP_LED_1_PORT PIN_PORT(BSP_LED_1)
+#else
+#define BSP_LED_1_MASK 0
+#define BSP_LED_1_PORT 0
+#endif
+#ifdef BSP_LED_2
+#define BSP_LED_2_MASK PIN_MASK(BSP_LED_2)
+#define BSP_LED_2_PORT PIN_PORT(BSP_LED_2)
+#else
+#define BSP_LED_2_MASK 0
+#define BSP_LED_2_PORT 0
+#endif
+#ifdef BSP_LED_3
+#define BSP_LED_3_MASK PIN_MASK(BSP_LED_3)
+#define BSP_LED_3_PORT PIN_PORT(BSP_LED_3)
+#else
+#define BSP_LED_3_MASK 0
+#define BSP_LED_3_PORT 0
+#endif
+#ifdef BSP_LED_4
+#define BSP_LED_4_MASK PIN_MASK(BSP_LED_4)
+#define BSP_LED_4_PORT PIN_PORT(BSP_LED_4)
+#else
+#define BSP_LED_4_MASK 0
+#define BSP_LED_4_PORT 0
+#endif
+#ifdef BSP_LED_5
+#define BSP_LED_5_MASK PIN_MASK(BSP_LED_5)
+#define BSP_LED_5_PORT PIN_PORT(BSP_LED_5)
+#else
+#define BSP_LED_5_MASK 0
+#define BSP_LED_5_PORT 0
+#endif
+#ifdef BSP_LED_6
+#define BSP_LED_6_MASK PIN_MASK(BSP_LED_6)
+#define BSP_LED_6_PORT PIN_PORT(BSP_LED_6)
+#else
+#define BSP_LED_6_MASK 0
+#define BSP_LED_6_PORT 0
+#endif
+#ifdef BSP_LED_7
+#define BSP_LED_7_MASK PIN_MASK(BSP_LED_7)
+#define BSP_LED_7_PORT PIN_PORT(BSP_LED_7)
+#else
+#define BSP_LED_7_MASK 0
+#define BSP_LED_7_PORT 0
+#endif
+
+
+#define LEDS_MASK (BSP_LED_0_MASK | BSP_LED_1_MASK | \
+ BSP_LED_2_MASK | BSP_LED_3_MASK | \
+ BSP_LED_4_MASK | BSP_LED_5_MASK | \
+ BSP_LED_6_MASK | BSP_LED_7_MASK)
+
+#define BSP_BOARD_BUTTON_0 0
+#define BSP_BOARD_BUTTON_1 1
+#define BSP_BOARD_BUTTON_2 2
+#define BSP_BOARD_BUTTON_3 3
+#define BSP_BOARD_BUTTON_4 4
+#define BSP_BOARD_BUTTON_5 5
+#define BSP_BOARD_BUTTON_6 6
+#define BSP_BOARD_BUTTON_7 7
+
+
+#ifdef BSP_BUTTON_0
+#define BSP_BUTTON_0_MASK (1<<BSP_BUTTON_0)
+#else
+#define BSP_BUTTON_0_MASK 0
+#endif
+#ifdef BSP_BUTTON_1
+#define BSP_BUTTON_1_MASK (1<<BSP_BUTTON_1)
+#else
+#define BSP_BUTTON_1_MASK 0
+#endif
+#ifdef BSP_BUTTON_2
+#define BSP_BUTTON_2_MASK (1<<BSP_BUTTON_2)
+#else
+#define BSP_BUTTON_2_MASK 0
+#endif
+#ifdef BSP_BUTTON_3
+#define BSP_BUTTON_3_MASK (1<<BSP_BUTTON_3)
+#else
+#define BSP_BUTTON_3_MASK 0
+#endif
+#ifdef BSP_BUTTON_4
+#define BSP_BUTTON_4_MASK (1<<BSP_BUTTON_4)
+#else
+#define BSP_BUTTON_4_MASK 0
+#endif
+#ifdef BSP_BUTTON_5
+#define BSP_BUTTON_5_MASK (1<<BSP_BUTTON_5)
+#else
+#define BSP_BUTTON_5_MASK 0
+#endif
+#ifdef BSP_BUTTON_6
+#define BSP_BUTTON_6_MASK (1<<BSP_BUTTON_6)
+#else
+#define BSP_BUTTON_6_MASK 0
+#endif
+#ifdef BSP_BUTTON_7
+#define BSP_BUTTON_7_MASK (1<<BSP_BUTTON_7)
+#else
+#define BSP_BUTTON_7_MASK 0
+#endif
+
+#define BUTTONS_MASK (BSP_BUTTON_0_MASK | BSP_BUTTON_1_MASK | \
+ BSP_BUTTON_2_MASK | BSP_BUTTON_3_MASK | \
+ BSP_BUTTON_4_MASK | BSP_BUTTON_5_MASK | \
+ BSP_BUTTON_6_MASK | BSP_BUTTON_7_MASK)
+
+
+#define LEDS_OFF(leds_mask) do { ASSERT(sizeof(leds_mask) == 4); \
+ NRF_GPIO->OUTSET = (leds_mask) & (LEDS_MASK & LEDS_INV_MASK); \
+ NRF_GPIO->OUTCLR = (leds_mask) & (LEDS_MASK & ~LEDS_INV_MASK); } while (0)
+
+#define LEDS_ON(leds_mask) do { ASSERT(sizeof(leds_mask) == 4); \
+ NRF_GPIO->OUTCLR = (leds_mask) & (LEDS_MASK & LEDS_INV_MASK); \
+ NRF_GPIO->OUTSET = (leds_mask) & (LEDS_MASK & ~LEDS_INV_MASK); } while (0)
+
+#define LED_IS_ON(leds_mask) ((leds_mask) & (NRF_GPIO->OUT ^ LEDS_INV_MASK) )
+
+#define LEDS_INVERT(leds_mask) do { uint32_t gpio_state = NRF_GPIO->OUT; \
+ ASSERT(sizeof(leds_mask) == 4); \
+ NRF_GPIO->OUTSET = ((leds_mask) & ~gpio_state); \
+ NRF_GPIO->OUTCLR = ((leds_mask) & gpio_state); } while (0)
+
+#define LEDS_CONFIGURE(leds_mask) do { uint32_t pin; \
+ ASSERT(sizeof(leds_mask) == 4); \
+ for (pin = 0; pin < 32; pin++) \
+ if ( (leds_mask) & (1 << pin) ) \
+ nrf_gpio_cfg_output(pin); } while (0)
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/boards/d52_starterkit.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/boards/d52_starterkit.h
new file mode 100644
index 0000000..9c9d3cd
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/boards/d52_starterkit.h
@@ -0,0 +1,148 @@
+/**
+ * This software is subject to the ANT+ Shared Source License
+ * www.thisisant.com/swlicenses
+ * Copyright (c) Dynastream Innovations, Inc. 2016
+ * 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 Dynastream nor the names of its
+ * contributors may be used to endorse or promote products
+ * derived from this software without specific prior
+ * written permission.
+ *
+ * The following actions are prohibited:
+ * 1) Redistribution of source code containing the ANT+ Network
+ * Key. The ANT+ Network Key is available to ANT+ Adopters.
+ * Please refer to http://thisisant.com to become an ANT+
+ * Adopter and access the key.
+ *
+ * 2) Reverse engineering, decompilation, and/or disassembly of
+ * software provided in binary form under this license.
+ *
+ * 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 HEREBY
+ * 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; DAMAGE TO ANY DEVICE, 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. SOME STATES DO NOT ALLOW
+ * THE EXCLUSION OF INCIDENTAL OR CONSEQUENTIAL DAMAGES, SO THE
+ * ABOVE LIMITATIONS MAY NOT APPLY TO YOU.
+ *
+ */
+#ifndef D52STARTERKIT_H
+#define D52STARTERKIT_H
+
+#include "nrf_gpio.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+// LEDs definitions for D52DK1
+#define LEDS_NUMBER 4
+
+// IO board active low leds
+// D52DK1 does not define LED_START or LED_STOP since the LEDS are not on sequential pins
+#define LED_A 24 //LED A on D52 Starter Kit IO Board
+#define LED_B 31 //LED B on D52 Starter Kit IO Board
+#define LED_C 17 //LED C on D52 Starter Kit IO Board
+#define LED_D 20 //LED D on D52 Starter Kit IO Board
+
+#define LEDS_ACTIVE_STATE 0
+
+#define LEDS_LIST { LED_A, LED_B, LED_C, LED_D }
+
+#define BSP_LED_0 LED_A
+#define BSP_LED_1 LED_B
+#define BSP_LED_2 LED_C
+#define BSP_LED_3 LED_D
+
+#define LEDS_INV_MASK LEDS_MASK
+
+#define BUTTONS_NUMBER 4
+
+// IO board pull-up buttons
+#define BUTTON_A 6 //BUTTON A on D52 Starter Kit IO Board
+#define BUTTON_B 7 //BUTTON B on D52 Starter Kit IO Board
+#define BUTTON_C 16 //BUTTON C on D52 Starter Kit IO Board
+#define BUTTON_D 19 //BUTTON D on D52 Starter Kit IO Board
+#define BUTTON_PULL NRF_GPIO_PIN_PULLUP
+
+#define BUTTONS_ACTIVE_STATE 0
+
+#define BSP_BUTTON_0 BUTTON_A
+#define BSP_BUTTON_1 BUTTON_B
+#define BSP_BUTTON_2 BUTTON_C
+#define BSP_BUTTON_3 BUTTON_D
+
+#define BUTTONS_LIST { BUTTON_A, BUTTON_B, BUTTON_C, BUTTON_D }
+
+// Battery board pull-up switches
+#define SWITCH_1 12 // Switch 1 on D52 Starter Kit Battery Board
+#define SWITCH_2 8 // Switch 2 on D52 Starter Kit Battery Board
+#define SWITCH_3 15 // Switch 3 on D52 Starter Kit Battery Board
+#define SWITCH_4 11 // Switch 4 on D52 Starter Kit Battery Board
+#define SWITCH_5 14 // Switch 5 on D52 Starter Kit Battery Board
+#define SWITCH_PULL NRF_GPIO_PIN_PULLUP
+
+#define SWITCHES_NUMBER 5
+
+#define BSP_SWITCH_0 SWITCH_1
+#define BSP_SWITCH_1 SWITCH_2
+#define BSP_SWITCH_2 SWITCH_3
+#define BSP_SWITCH_3 SWITCH_4
+#define BSP_SWITCH_4 SWITCH_5
+
+#define BSP_SWITCH_0_MASK (1<<BSP_SWITCH_0)
+#define BSP_SWITCH_1_MASK (1<<BSP_SWITCH_1)
+#define BSP_SWITCH_2_MASK (1<<BSP_SWITCH_2)
+#define BSP_SWITCH_3_MASK (1<<BSP_SWITCH_3)
+#define BSP_SWITCH_4_MASK (1<<BSP_SWITCH_4)
+
+#define SWITCHES_MASK (BSP_SWITCH_0_MASK | BSP_SWITCH_1_MASK | BSP_SWITCH_2_MASK | BSP_SWITCH_3_MASK | BSP_SWITCH_4_MASK)
+
+// D52DK1 does not have UART peripheral. Dummy defines for compilation.
+#define RX_PIN_NUMBER UART_PIN_DISCONNECTED
+#define TX_PIN_NUMBER UART_PIN_DISCONNECTED
+#define CTS_PIN_NUMBER UART_PIN_DISCONNECTED
+#define RTS_PIN_NUMBER UART_PIN_DISCONNECTED
+
+// serialization CONNECTIVITY board
+#define SER_CON_RX_PIN 22 // UART RX pin number.
+#define SER_CON_TX_PIN 23 // UART TX pin number.
+#define SER_CON_CTS_PIN 25 // UART Clear To Send pin number. Not used if HWFC is set to false.
+#define SER_CON_RTS_PIN 2 // UART Request To Send pin number. Not used if HWFC is set to false.
+
+// serialization APPLICATION board - temp. setup for running serialized MEMU tests
+#define SER_APP_RX_PIN 23 // UART RX pin number.
+#define SER_APP_TX_PIN 22 // UART TX pin number.
+#define SER_APP_CTS_PIN 2 // UART Clear To Send pin number.
+#define SER_APP_RTS_PIN 25 // UART Request To Send pin number.
+
+
+#define SER_CONN_CHIP_RESET_PIN 11 // Pin used to reset connectivity chip
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/boards/n5_starterkit.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/boards/n5_starterkit.h
new file mode 100644
index 0000000..57d88f7
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/boards/n5_starterkit.h
@@ -0,0 +1,128 @@
+/**
+ * This software is subject to the ANT+ Shared Source License
+ * www.thisisant.com/swlicenses
+ * Copyright (c) Dynastream Innovations, Inc. 2015
+ * 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 Dynastream nor the names of its
+ * contributors may be used to endorse or promote products
+ * derived from this software without specific prior
+ * written permission.
+ *
+ * The following actions are prohibited:
+ * 1) Redistribution of source code containing the ANT+ Network
+ * Key. The ANT+ Network Key is available to ANT+ Adopters.
+ * Please refer to http://thisisant.com to become an ANT+
+ * Adopter and access the key.
+ *
+ * 2) Reverse engineering, decompilation, and/or disassembly of
+ * software provided in binary form under this license.
+ *
+ * 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 HEREBY
+ * 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; DAMAGE TO ANY DEVICE, 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. SOME STATES DO NOT ALLOW
+ * THE EXCLUSION OF INCIDENTAL OR CONSEQUENTIAL DAMAGES, SO THE
+ * ABOVE LIMITATIONS MAY NOT APPLY TO YOU.
+ *
+ */
+#ifndef N5STARTERKIT_H
+#define N5STARTERKIT_H
+
+#include "nrf_gpio.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+// LEDs definitions for N5DK1
+#define LEDS_NUMBER 4
+
+// IO board active low leds
+// N5DK1 does not define LED_START or LED_STOP since the LEDS are not on sequential pins
+#define LED_A 8 //LED A on N5 Starter Kit IO Board
+#define LED_B 3 //LED B on N5 Starter Kit IO Board
+#define LED_C 15 //LED C on N5 Starter Kit IO Board
+#define LED_D 30 //LED D on N5 Starter Kit IO Board
+
+#define LEDS_ACTIVE_STATE 0
+
+#define LEDS_LIST { LED_A, LED_B, LED_C, LED_D }
+
+#define LEDS_INV_MASK LEDS_MASK
+
+#define BSP_LED_0 LED_A
+#define BSP_LED_1 LED_B
+#define BSP_LED_2 LED_C
+#define BSP_LED_3 LED_D
+
+#define BUTTONS_NUMBER 4
+
+// IO board pull-up buttons
+#define BUTTON_A 23 //BUTTON A on N5 Starter Kit IO Board
+#define BUTTON_B 2 //BUTTON B on N5 Starter Kit IO Board
+#define BUTTON_C 12 //BUTTON C on N5 Starter Kit IO Board
+#define BUTTON_D 11 //BUTTON D on N5 Starter Kit IO Board
+#define BUTTON_PULL NRF_GPIO_PIN_PULLUP
+
+#define BUTTONS_ACTIVE_STATE 0
+
+#define BSP_BUTTON_0 BUTTON_A
+#define BSP_BUTTON_1 BUTTON_B
+#define BSP_BUTTON_2 BUTTON_C
+#define BSP_BUTTON_3 BUTTON_D
+
+#define BUTTONS_LIST { BUTTON_A, BUTTON_B, BUTTON_C, BUTTON_D }
+
+// Battery board pull-up switches
+#define SWITCH_1 5 // Switch 1 on N5 Starter Kit Battery Board
+#define SWITCH_2 0 // Switch 2 on N5 Starter Kit Battery Board
+#define SWITCH_3 6 // Switch 3 on N5 Starter Kit Battery Board
+#define SWITCH_4 24 // Switch 4 on N5 Starter Kit Battery Board
+#define SWITCH_5 9 // Switch 5 on N5 Starter Kit Battery Board
+#define SWITCH_PULL NRF_GPIO_PIN_PULLUP
+
+#define SWITCHES_NUMBER 5
+
+#define BSP_SWITCH_0 SWITCH_1
+#define BSP_SWITCH_1 SWITCH_2
+#define BSP_SWITCH_2 SWITCH_3
+#define BSP_SWITCH_3 SWITCH_4
+#define BSP_SWITCH_4 SWITCH_5
+
+#define SWITCHES_MASK 0x01000261
+
+// N5DK1 does not have UART peripheral. Dummy defines for compilation.
+#define RX_PIN_NUMBER UART_PIN_DISCONNECTED
+#define TX_PIN_NUMBER UART_PIN_DISCONNECTED
+#define CTS_PIN_NUMBER UART_PIN_DISCONNECTED
+#define RTS_PIN_NUMBER UART_PIN_DISCONNECTED
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/boards/nrf6310.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/boards/nrf6310.h
new file mode 100644
index 0000000..b42e77e
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/boards/nrf6310.h
@@ -0,0 +1,180 @@
+/**
+ * Copyright (c) 2012 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#ifndef NRF6310_H__
+#define NRF6310_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define LED_START 8
+#define LED_0 8
+#define LED_1 9
+#define LED_2 10
+#define LED_3 11
+#define LED_4 12
+#define LED_5 13
+#define LED_6 14
+#define LED_7 15
+#define LED_STOP 15
+
+#define BSP_LED_0 LED_0
+#define BSP_LED_1 LED_1
+#define BSP_LED_2 LED_2
+#define BSP_LED_3 LED_3
+#define BSP_LED_4 LED_4
+#define BSP_LED_5 LED_5
+#define BSP_LED_6 LED_6
+#define BSP_LED_7 LED_7
+
+#define LEDS_ACTIVE_STATE 1
+
+#define BUTTON_START 0
+#define BUTTON_0 0
+#define BUTTON_1 1
+#define BUTTON_2 2
+#define BUTTON_3 3
+#define BUTTON_4 4
+#define BUTTON_5 5
+#define BUTTON_6 6
+#define BUTTON_7 7
+#define BUTTON_STOP 7
+#define BUTTON_PULL NRF_GPIO_PIN_NOPULL
+
+#define BSP_BUTTON_0 BUTTON_0
+#define BSP_BUTTON_1 BUTTON_1
+#define BSP_BUTTON_2 BUTTON_2
+#define BSP_BUTTON_3 BUTTON_3
+#define BSP_BUTTON_4 BUTTON_4
+#define BSP_BUTTON_5 BUTTON_5
+#define BSP_BUTTON_6 BUTTON_6
+#define BSP_BUTTON_7 BUTTON_7
+
+#define BUTTONS_ACTIVE_STATE 1
+
+#define BUTTONS_LIST {BUTTON_0, BUTTON_1, BUTTON_2, BUTTON_3, BUTTON_4, BUTTON_5, BUTTON_6, BUTTON_7}
+#define LEDS_LIST {LED_0, LED_1, LED_2, LED_3, LED_4, LED_5, LED_6, LED_7}
+
+#define LEDS_INV_MASK 0x00000000
+
+#define BUTTONS_NUMBER 8
+#define LEDS_NUMBER 8
+
+#define RX_PIN_NUMBER 16 // UART RX pin number.
+#define TX_PIN_NUMBER 17 // UART TX pin number.
+#define CTS_PIN_NUMBER 18 // UART Clear To Send pin number. Not used if HWFC is set to false.
+#define RTS_PIN_NUMBER 19 // UART Request To Send pin number. Not used if HWFC is set to false.
+#define HWFC false // UART hardware flow control.
+
+#define SPIS_MISO_PIN 20 // SPI MISO signal.
+#define SPIS_CSN_PIN 21 // SPI CSN signal.
+#define SPIS_MOSI_PIN 22 // SPI MOSI signal.
+#define SPIS_SCK_PIN 23 // SPI SCK signal.
+
+#define SPIM0_SCK_PIN 23u /**< SPI clock GPIO pin number. */
+#define SPIM0_MOSI_PIN 20u /**< SPI Master Out Slave In GPIO pin number. */
+#define SPIM0_MISO_PIN 22u /**< SPI Master In Slave Out GPIO pin number. */
+#define SPIM0_SS_PIN 21u /**< SPI Slave Select GPIO pin number. */
+
+#define SPIM1_SCK_PIN 16u /**< SPI clock GPIO pin number. */
+#define SPIM1_MOSI_PIN 18u /**< SPI Master Out Slave In GPIO pin number. */
+#define SPIM1_MISO_PIN 17u /**< SPI Master In Slave Out GPIO pin number. */
+#define SPIM1_SS_PIN 19u /**< SPI Slave Select GPIO pin number. */
+
+// serialization APPLICATION board
+#define SER_APP_RX_PIN 16 // UART RX pin number.
+#define SER_APP_TX_PIN 17 // UART TX pin number.
+#define SER_APP_CTS_PIN 18 // UART Clear To Send pin number.
+#define SER_APP_RTS_PIN 19 // UART Request To Send pin number.
+
+#if 0
+#define SER_APP_SPIM0_SCK_PIN 20 // SPI clock GPIO pin number.
+#define SER_APP_SPIM0_MOSI_PIN 17 // SPI Master Out Slave In GPIO pin number
+#define SER_APP_SPIM0_MISO_PIN 16 // SPI Master In Slave Out GPIO pin number
+#define SER_APP_SPIM0_SS_PIN 21 // SPI Slave Select GPIO pin number
+#define SER_APP_SPIM0_RDY_PIN 19 // SPI READY GPIO pin number
+#define SER_APP_SPIM0_REQ_PIN 18 // SPI REQUEST GPIO pin number
+#else
+#define SER_APP_SPIM0_SCK_PIN 23 // SPI clock GPIO pin number.
+#define SER_APP_SPIM0_MOSI_PIN 20 // SPI Master Out Slave In GPIO pin number
+#define SER_APP_SPIM0_MISO_PIN 22 // SPI Master In Slave Out GPIO pin number
+#define SER_APP_SPIM0_SS_PIN 21 // SPI Slave Select GPIO pin number
+#define SER_APP_SPIM0_RDY_PIN 29 // SPI READY GPIO pin number
+#define SER_APP_SPIM0_REQ_PIN 28 // SPI REQUEST GPIO pin number
+
+#endif
+
+// serialization CONNECTIVITY board
+#if 0
+#define SER_CON_RX_PIN 17 // UART RX pin number.
+#define SER_CON_TX_PIN 16 // UART TX pin number.
+#define SER_CON_CTS_PIN 19 // UART Clear To Send pin number. Not used if HWFC is set to false.
+#define SER_CON_RTS_PIN 18 // UART Request To Send pin number. Not used if HWFC is set to false.
+#else
+#define SER_CON_RX_PIN 16 // UART RX pin number.
+#define SER_CON_TX_PIN 17 // UART TX pin number.
+#define SER_CON_CTS_PIN 18 // UART Clear To Send pin number. Not used if HWFC is set to false.
+#define SER_CON_RTS_PIN 19 // UART Request To Send pin number. Not used if HWFC is set to false.
+#endif
+
+#if 0
+#define SER_CON_SPIS_SCK_PIN 20 // SPI SCK signal.
+#define SER_CON_SPIS_MISO_PIN 16 // SPI MISO signal.
+#define SER_CON_SPIS_MOSI_PIN 17 // SPI MOSI signal.
+#define SER_CON_SPIS_CSN_PIN 21 // SPI CSN signal.
+#define SER_CON_SPIS_RDY_PIN 19 // SPI READY GPIO pin number.
+#define SER_CON_SPIS_REQ_PIN 18 // SPI REQUEST GPIO pin number.
+#else
+#define SER_CON_SPIS_SCK_PIN 23 // SPI SCK signal.
+#define SER_CON_SPIS_MOSI_PIN 22 // SPI MOSI signal.
+#define SER_CON_SPIS_MISO_PIN 20 // SPI MISO signal.
+#define SER_CON_SPIS_CSN_PIN 21 // SPI CSN signal.
+#define SER_CON_SPIS_RDY_PIN 29 // SPI READY GPIO pin number.
+#define SER_CON_SPIS_REQ_PIN 28 // SPI REQUEST GPIO pin number.
+#endif
+
+#define SER_CONN_ASSERT_LED_PIN LED_2
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // NRF6310_H__
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/boards/pca10000.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/boards/pca10000.h
new file mode 100644
index 0000000..8423fbe
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/boards/pca10000.h
@@ -0,0 +1,98 @@
+/**
+ * Copyright (c) 2012 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#ifndef PCA10000_H
+#define PCA10000_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "nrf_gpio.h"
+
+// Definitions for PCA10000 v2.0.0 or higher
+#if 1
+
+#define LEDS_NUMBER 3
+
+// there is RGB LED on this board
+#define LED_RGB_RED 21
+#define LED_RGB_GREEN 22
+#define LED_RGB_BLUE 23
+
+#define LED_START LED_RGB_RED
+#define BSP_LED_0 LED_RGB_RED
+#define BSP_LED_1 LED_RGB_GREEN
+#define BSP_LED_2 LED_RGB_BLUE
+#define LED_STOP LED_RGB_BLUE
+
+#define LEDS_ACTIVE_STATE 0
+
+#define BUTTONS_LIST {}
+#define LEDS_LIST { LED_RGB_RED, LED_RGB_GREEN, LED_RGB_BLUE }
+
+#define LEDS_INV_MASK LEDS_MASK
+
+// there are no buttons on this board
+#define BUTTONS_NUMBER 0
+
+// UART pins connected to J-Link
+#define RX_PIN_NUMBER 11
+#define TX_PIN_NUMBER 9
+#define CTS_PIN_NUMBER 10
+#define RTS_PIN_NUMBER 8
+#define HWFC true
+
+// Definitions for PCA10000 v1.0
+#else
+
+#define RX_PIN_NUMBER 3
+#define TX_PIN_NUMBER 1
+#define CTS_PIN_NUMBER 2
+#define RTS_PIN_NUMBER 0
+#define HWFC true
+
+#endif
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/boards/pca10001.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/boards/pca10001.h
new file mode 100644
index 0000000..5e492d9
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/boards/pca10001.h
@@ -0,0 +1,165 @@
+/**
+ * Copyright (c) 2012 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#ifndef PCA10001_H
+#define PCA10001_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "nrf_gpio.h"
+
+#define LED_START 18
+#define LED_0 18
+#define LED_1 19
+#define LED_STOP 19
+
+#define LEDS_ACTIVE_STATE 1
+
+#define BSP_LED_0 LED_0
+#define BSP_LED_1 LED_1
+
+#define LEDS_INV_MASK 0x00000000
+
+#define BUTTON_START 16
+#define BUTTON_0 16
+#define BUTTON_1 17
+#define BUTTON_STOP 17
+#define BUTTON_PULL NRF_GPIO_PIN_PULLUP
+
+#define BUTTONS_ACTIVE_STATE 0
+
+#define BSP_BUTTON_0 BUTTON_0
+#define BSP_BUTTON_1 BUTTON_1
+
+#define BUTTONS_NUMBER 2
+#define LEDS_NUMBER 2
+
+#define BUTTONS_LIST { BUTTON_0, BUTTON_1 }
+#define LEDS_LIST { LED_0, LED_1 }
+
+#define RX_PIN_NUMBER 11
+#define TX_PIN_NUMBER 9
+#define CTS_PIN_NUMBER 10
+#define RTS_PIN_NUMBER 8
+#define HWFC true
+
+#define SPIS_MISO_PIN 20 // SPI MISO signal.
+#define SPIS_CSN_PIN 21 // SPI CSN signal.
+#define SPIS_MOSI_PIN 22 // SPI MOSI signal.
+#define SPIS_SCK_PIN 23 // SPI SCK signal.
+
+#define SPIM0_SCK_PIN 23u /**< SPI clock GPIO pin number. */
+#define SPIM0_MOSI_PIN 20u /**< SPI Master Out Slave In GPIO pin number. */
+#define SPIM0_MISO_PIN 22u /**< SPI Master In Slave Out GPIO pin number. */
+#define SPIM0_SS_PIN 21u /**< SPI Slave Select GPIO pin number. */
+
+#define SPIM1_SCK_PIN 29u /**< SPI clock GPIO pin number. */
+#define SPIM1_MOSI_PIN 24u /**< SPI Master Out Slave In GPIO pin number. */
+#define SPIM1_MISO_PIN 28u /**< SPI Master In Slave Out GPIO pin number. */
+#define SPIM1_SS_PIN 25u /**< SPI Slave Select GPIO pin number. */
+
+// serialization APPLICATION board
+
+// UART
+// this configuration works with the SPI wires setup
+#define SER_APP_RX_PIN 20 // UART RX pin number.
+#define SER_APP_TX_PIN 22 // UART TX pin number.
+#define SER_APP_CTS_PIN 23 // UART Clear To Send pin number.
+#define SER_APP_RTS_PIN 21 // UART Request To Send pin number.
+
+// SPI
+#if 0
+#define SER_APP_SPIM0_SCK_PIN 20 // SPI clock GPIO pin number.
+#define SER_APP_SPIM0_MOSI_PIN 17 // SPI Master Out Slave In GPIO pin number
+#define SER_APP_SPIM0_MISO_PIN 16 // SPI Master In Slave Out GPIO pin number
+#define SER_APP_SPIM0_SS_PIN 21 // SPI Slave Select GPIO pin number
+#define SER_APP_SPIM0_RDY_PIN 19 // SPI READY GPIO pin number
+#define SER_APP_SPIM0_REQ_PIN 18 // SPI REQUEST GPIO pin number
+#else
+#define SER_APP_SPIM0_SCK_PIN 23 // SPI clock GPIO pin number.
+#define SER_APP_SPIM0_MOSI_PIN 20 // SPI Master Out Slave In GPIO pin number
+#define SER_APP_SPIM0_MISO_PIN 22 // SPI Master In Slave Out GPIO pin number
+#define SER_APP_SPIM0_SS_PIN 21 // SPI Slave Select GPIO pin number
+#define SER_APP_SPIM0_RDY_PIN 25 // SPI READY GPIO pin number
+#define SER_APP_SPIM0_REQ_PIN 24 // SPI REQUEST GPIO pin number
+#endif
+
+// serialization CONNECTIVITY board
+
+// UART
+#if 0
+#define SER_CON_RX_PIN 22 // UART RX pin number.
+#define SER_CON_TX_PIN 20 // UART TX pin number.
+#define SER_CON_CTS_PIN 21 // UART Clear To Send pin number. Not used if HWFC is set to false.
+#define SER_CON_RTS_PIN 23 // UART Request To Send pin number. Not used if HWFC is set to false.
+#else
+// this configuration works with the SPI wires setup
+#define SER_CON_RX_PIN 20 // UART RX pin number.
+#define SER_CON_TX_PIN 22 // UART TX pin number.
+#define SER_CON_CTS_PIN 21 // UART Clear To Send pin number. Not used if HWFC is set to false.
+#define SER_CON_RTS_PIN 23 // UART Request To Send pin number. Not used if HWFC is set to false.
+#endif
+
+//SPI
+#if 0
+#define SER_CON_SPIS_SCK_PIN 20 // SPI SCK signal.
+#define SER_CON_SPIS_MISO_PIN 16 // SPI MISO signal.
+#define SER_CON_SPIS_MOSI_PIN 17 // SPI MOSI signal.
+#define SER_CON_SPIS_CSN_PIN 21 // SPI CSN signal.
+#define SER_CON_SPIS_RDY_PIN 19 // SPI READY GPIO pin number.
+#define SER_CON_SPIS_REQ_PIN 18 // SPI REQUEST GPIO pin number.
+#else
+#define SER_CON_SPIS_SCK_PIN 23 // SPI SCK signal.
+#define SER_CON_SPIS_MOSI_PIN 22 // SPI MOSI signal.
+#define SER_CON_SPIS_MISO_PIN 20 // SPI MISO signal.
+#define SER_CON_SPIS_CSN_PIN 21 // SPI CSN signal.
+#define SER_CON_SPIS_RDY_PIN 25 // SPI READY GPIO pin number.
+#define SER_CON_SPIS_REQ_PIN 24 // SPI REQUEST GPIO pin number.
+#endif
+
+#define SER_CONN_ASSERT_LED_PIN LED_0
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/boards/pca10003.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/boards/pca10003.h
new file mode 100644
index 0000000..834d1ed
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/boards/pca10003.h
@@ -0,0 +1,89 @@
+/**
+ * Copyright (c) 2014 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#ifndef PCA10003_H
+#define PCA10003_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "nrf_gpio.h"
+
+#define LED_START 18
+#define LED_0 18
+#define LED_1 19
+#define LED_STOP 19
+
+#define LEDS_ACTIVE_STATE 1
+
+#define LEDS_INV_MASK 0x00000000
+
+#define BSP_LED_0 LED_0
+#define BSP_LED_1 LED_1
+
+#define BUTTON_START 16
+#define BUTTON_0 16
+#define BUTTON_1 17
+#define BUTTON_STOP 17
+#define BUTTON_PULL NRF_GPIO_PIN_PULLUP
+
+#define BUTTONS_ACTIVE_STATE 0
+
+#define BSP_BUTTON_0 BUTTON_0
+#define BSP_BUTTON_1 BUTTON_1
+
+#define BUTTONS_NUMBER 2
+#define LEDS_NUMBER 2
+#define LEDS_LIST { LED_0, LED_1 }
+
+#define BUTTONS_LIST { BUTTON_0, BUTTON_1 }
+
+#define RX_PIN_NUMBER 11
+#define TX_PIN_NUMBER 9
+#define CTS_PIN_NUMBER 10
+#define RTS_PIN_NUMBER 8
+#define HWFC true
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/boards/pca10028.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/boards/pca10028.h
new file mode 100644
index 0000000..a20fd49
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/boards/pca10028.h
@@ -0,0 +1,171 @@
+/**
+ * Copyright (c) 2014 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#ifndef PCA10028_H
+#define PCA10028_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "nrf_gpio.h"
+
+// LEDs definitions for PCA10028
+#define LEDS_NUMBER 4
+
+#define LED_START 21
+#define LED_1 21
+#define LED_2 22
+#define LED_3 23
+#define LED_4 24
+#define LED_STOP 24
+
+#define LEDS_ACTIVE_STATE 0
+
+#define LEDS_LIST { LED_1, LED_2, LED_3, LED_4 }
+
+#define LEDS_INV_MASK LEDS_MASK
+
+#define BSP_LED_0 LED_1
+#define BSP_LED_1 LED_2
+#define BSP_LED_2 LED_3
+#define BSP_LED_3 LED_4
+
+#define BUTTONS_NUMBER 4
+
+#define BUTTON_START 17
+#define BUTTON_1 17
+#define BUTTON_2 18
+#define BUTTON_3 19
+#define BUTTON_4 20
+#define BUTTON_STOP 20
+#define BUTTON_PULL NRF_GPIO_PIN_PULLUP
+
+#define BUTTONS_ACTIVE_STATE 0
+
+#define BUTTONS_LIST { BUTTON_1, BUTTON_2, BUTTON_3, BUTTON_4 }
+
+#define BSP_BUTTON_0 BUTTON_1
+#define BSP_BUTTON_1 BUTTON_2
+#define BSP_BUTTON_2 BUTTON_3
+#define BSP_BUTTON_3 BUTTON_4
+
+#define RX_PIN_NUMBER 11
+#define TX_PIN_NUMBER 9
+#define CTS_PIN_NUMBER 10
+#define RTS_PIN_NUMBER 8
+#define HWFC true
+
+#define SPIS_MISO_PIN 28 // SPI MISO signal.
+#define SPIS_CSN_PIN 12 // SPI CSN signal.
+#define SPIS_MOSI_PIN 25 // SPI MOSI signal.
+#define SPIS_SCK_PIN 29 // SPI SCK signal.
+
+#define SPIM0_SCK_PIN 4 /**< SPI clock GPIO pin number. */
+#define SPIM0_MOSI_PIN 1 /**< SPI Master Out Slave In GPIO pin number. */
+#define SPIM0_MISO_PIN 3 /**< SPI Master In Slave Out GPIO pin number. */
+#define SPIM0_SS_PIN 2 /**< SPI Slave Select GPIO pin number. */
+
+#define SPIM1_SCK_PIN 15 /**< SPI clock GPIO pin number. */
+#define SPIM1_MOSI_PIN 12 /**< SPI Master Out Slave In GPIO pin number. */
+#define SPIM1_MISO_PIN 14 /**< SPI Master In Slave Out GPIO pin number. */
+#define SPIM1_SS_PIN 13 /**< SPI Slave Select GPIO pin number. */
+
+// serialization APPLICATION board
+#define SER_CONN_CHIP_RESET_PIN 12 // Pin used to reset connectivity chip
+
+#define SER_APP_RX_PIN 25 // UART RX pin number.
+#define SER_APP_TX_PIN 28 // UART TX pin number.
+#define SER_APP_CTS_PIN 0 // UART Clear To Send pin number.
+#define SER_APP_RTS_PIN 29 // UART Request To Send pin number.
+
+#define SER_APP_SPIM0_SCK_PIN 7 // SPI clock GPIO pin number.
+#define SER_APP_SPIM0_MOSI_PIN 0 // SPI Master Out Slave In GPIO pin number
+#define SER_APP_SPIM0_MISO_PIN 30 // SPI Master In Slave Out GPIO pin number
+#define SER_APP_SPIM0_SS_PIN 25 // SPI Slave Select GPIO pin number
+#define SER_APP_SPIM0_RDY_PIN 29 // SPI READY GPIO pin number
+#define SER_APP_SPIM0_REQ_PIN 28 // SPI REQUEST GPIO pin number
+
+// serialization CONNECTIVITY board
+#define SER_CON_RX_PIN 28 // UART RX pin number.
+#define SER_CON_TX_PIN 25 // UART TX pin number.
+#define SER_CON_CTS_PIN 29 // UART Clear To Send pin number. Not used if HWFC is set to false.
+#define SER_CON_RTS_PIN 0 // UART Request To Send pin number. Not used if HWFC is set to false.
+
+
+#define SER_CON_SPIS_SCK_PIN 7 // SPI SCK signal.
+#define SER_CON_SPIS_MOSI_PIN 0 // SPI MOSI signal.
+#define SER_CON_SPIS_MISO_PIN 30 // SPI MISO signal.
+#define SER_CON_SPIS_CSN_PIN 25 // SPI CSN signal.
+#define SER_CON_SPIS_RDY_PIN 29 // SPI READY GPIO pin number.
+#define SER_CON_SPIS_REQ_PIN 28 // SPI REQUEST GPIO pin number.
+
+// Arduino board mappings
+#define ARDUINO_SCL_PIN 7 // SCL signal pin
+#define ARDUINO_SDA_PIN 30 // SDA signal pin
+#define ARDUINO_AREF_PIN 0 // Aref pin
+#define ARDUINO_13_PIN 29 // Digital pin 13
+#define ARDUINO_12_PIN 28 // Digital pin 12
+#define ARDUINO_11_PIN 25 // Digital pin 11
+#define ARDUINO_10_PIN 24 // Digital pin 10
+#define ARDUINO_9_PIN 23 // Digital pin 9
+#define ARDUINO_8_PIN 20 // Digital pin 8
+
+#define ARDUINO_7_PIN 19 // Digital pin 7
+#define ARDUINO_6_PIN 18 // Digital pin 6
+#define ARDUINO_5_PIN 17 // Digital pin 5
+#define ARDUINO_4_PIN 16 // Digital pin 4
+#define ARDUINO_3_PIN 15 // Digital pin 3
+#define ARDUINO_2_PIN 14 // Digital pin 2
+#define ARDUINO_1_PIN 13 // Digital pin 1
+#define ARDUINO_0_PIN 12 // Digital pin 0
+
+#define ARDUINO_A0_PIN 1 // Analog channel 0
+#define ARDUINO_A1_PIN 2 // Analog channel 1
+#define ARDUINO_A2_PIN 3 // Analog channel 2
+#define ARDUINO_A3_PIN 4 // Analog channel 3
+#define ARDUINO_A4_PIN 5 // Analog channel 4
+#define ARDUINO_A5_PIN 6 // Analog channel 5
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // PCA10028_H
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/boards/pca10031.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/boards/pca10031.h
new file mode 100644
index 0000000..d335941
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/boards/pca10031.h
@@ -0,0 +1,88 @@
+/**
+ * Copyright (c) 2014 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#ifndef PCA10031_H
+#define PCA10031_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "nrf_gpio.h"
+
+// LEDs definitions for PCA10031
+#define LEDS_NUMBER 3
+
+#define LED_START 21
+#define LED_RGB_RED 21
+#define LED_RGB_GREEN 22
+#define LED_RGB_BLUE 23
+#define LED_STOP 23
+
+#define LEDS_ACTIVE_STATE 1
+
+#define LEDS_INV_MASK LEDS_MASK
+
+#define LED_RGB_RED_MASK (1<<LED_RGB_RED)
+#define LED_RGB_GREEN_MASK (1<<LED_RGB_GREEN)
+#define LED_RGB_BLUE_MASK (1<<LED_RGB_BLUE)
+
+#define LEDS_LIST { LED_RGB_RED, LED_RGB_GREEN, LED_RGB_BLUE}
+// defining RGB led as 3 single LEDs
+#define BSP_LED_0 LED_RGB_RED
+#define BSP_LED_1 LED_RGB_GREEN
+#define BSP_LED_2 LED_RGB_BLUE
+
+// there are no user buttons
+#define BUTTONS_NUMBER 0
+#define BUTTONS_LIST {}
+
+// UART connection with J-Link
+#define RX_PIN_NUMBER 11
+#define TX_PIN_NUMBER 9
+#define CTS_PIN_NUMBER 10
+#define RTS_PIN_NUMBER 8
+#define HWFC true
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/boards/pca10036.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/boards/pca10036.h
new file mode 100644
index 0000000..cbb12f2
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/boards/pca10036.h
@@ -0,0 +1,176 @@
+/**
+ * Copyright (c) 2014 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#ifndef PCA10036_H
+#define PCA10036_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "nrf_gpio.h"
+
+// LEDs definitions for PCA10036
+#define LEDS_NUMBER 4
+
+#define LED_START 17
+#define LED_1 17
+#define LED_2 18
+#define LED_3 19
+#define LED_4 20
+#define LED_STOP 20
+
+#define LEDS_ACTIVE_STATE 0
+
+#define LEDS_INV_MASK LEDS_MASK
+
+#define LEDS_LIST { LED_1, LED_2, LED_3, LED_4 }
+
+#define BSP_LED_0 LED_1
+#define BSP_LED_1 LED_2
+#define BSP_LED_2 LED_3
+#define BSP_LED_3 LED_4
+
+#define BUTTONS_NUMBER 4
+
+#define BUTTON_START 13
+#define BUTTON_1 13
+#define BUTTON_2 14
+#define BUTTON_3 15
+#define BUTTON_4 16
+#define BUTTON_STOP 16
+#define BUTTON_PULL NRF_GPIO_PIN_PULLUP
+
+#define BUTTONS_ACTIVE_STATE 0
+
+#define BUTTONS_LIST { BUTTON_1, BUTTON_2, BUTTON_3, BUTTON_4 }
+
+#define BSP_BUTTON_0 BUTTON_1
+#define BSP_BUTTON_1 BUTTON_2
+#define BSP_BUTTON_2 BUTTON_3
+#define BSP_BUTTON_3 BUTTON_4
+
+#define RX_PIN_NUMBER 8
+#define TX_PIN_NUMBER 6
+#define CTS_PIN_NUMBER 7
+#define RTS_PIN_NUMBER 5
+#define HWFC true
+
+#define SPIS_MISO_PIN 28 // SPI MISO signal.
+#define SPIS_CSN_PIN 12 // SPI CSN signal.
+#define SPIS_MOSI_PIN 25 // SPI MOSI signal.
+#define SPIS_SCK_PIN 29 // SPI SCK signal.
+
+#define SPIM0_SCK_PIN 29 // SPI clock GPIO pin number.
+#define SPIM0_MOSI_PIN 25 // SPI Master Out Slave In GPIO pin number.
+#define SPIM0_MISO_PIN 28 // SPI Master In Slave Out GPIO pin number.
+#define SPIM0_SS_PIN 12 // SPI Slave Select GPIO pin number.
+
+#define SPIM1_SCK_PIN 2 // SPI clock GPIO pin number.
+#define SPIM1_MOSI_PIN 3 // SPI Master Out Slave In GPIO pin number.
+#define SPIM1_MISO_PIN 4 // SPI Master In Slave Out GPIO pin number.
+#define SPIM1_SS_PIN 5 // SPI Slave Select GPIO pin number.
+
+#define SPIM2_SCK_PIN 12 // SPI clock GPIO pin number.
+#define SPIM2_MOSI_PIN 13 // SPI Master Out Slave In GPIO pin number.
+#define SPIM2_MISO_PIN 14 // SPI Master In Slave Out GPIO pin number.
+#define SPIM2_SS_PIN 15 // SPI Slave Select GPIO pin number.
+
+// serialization APPLICATION board - temp. setup for running serialized MEMU tests
+#define SER_APP_RX_PIN 23 // UART RX pin number.
+#define SER_APP_TX_PIN 24 // UART TX pin number.
+#define SER_APP_CTS_PIN 2 // UART Clear To Send pin number.
+#define SER_APP_RTS_PIN 25 // UART Request To Send pin number.
+
+#define SER_APP_SPIM0_SCK_PIN 27 // SPI clock GPIO pin number.
+#define SER_APP_SPIM0_MOSI_PIN 2 // SPI Master Out Slave In GPIO pin number
+#define SER_APP_SPIM0_MISO_PIN 26 // SPI Master In Slave Out GPIO pin number
+#define SER_APP_SPIM0_SS_PIN 23 // SPI Slave Select GPIO pin number
+#define SER_APP_SPIM0_RDY_PIN 25 // SPI READY GPIO pin number
+#define SER_APP_SPIM0_REQ_PIN 24 // SPI REQUEST GPIO pin number
+
+// serialization CONNECTIVITY board
+#define SER_CON_RX_PIN 24 // UART RX pin number.
+#define SER_CON_TX_PIN 23 // UART TX pin number.
+#define SER_CON_CTS_PIN 25 // UART Clear To Send pin number. Not used if HWFC is set to false.
+#define SER_CON_RTS_PIN 2 // UART Request To Send pin number. Not used if HWFC is set to false.
+
+
+#define SER_CON_SPIS_SCK_PIN 27 // SPI SCK signal.
+#define SER_CON_SPIS_MOSI_PIN 2 // SPI MOSI signal.
+#define SER_CON_SPIS_MISO_PIN 26 // SPI MISO signal.
+#define SER_CON_SPIS_CSN_PIN 23 // SPI CSN signal.
+#define SER_CON_SPIS_RDY_PIN 25 // SPI READY GPIO pin number.
+#define SER_CON_SPIS_REQ_PIN 24 // SPI REQUEST GPIO pin number.
+
+#define SER_CONN_CHIP_RESET_PIN 11 // Pin used to reset connectivity chip
+
+// Arduino board mappings
+#define ARDUINO_SCL_PIN 27 // SCL signal pin
+#define ARDUINO_SDA_PIN 26 // SDA signal pin
+#define ARDUINO_AREF_PIN 2 // Aref pin
+#define ARDUINO_13_PIN 25 // Digital pin 13
+#define ARDUINO_12_PIN 24 // Digital pin 12
+#define ARDUINO_11_PIN 23 // Digital pin 11
+#define ARDUINO_10_PIN 22 // Digital pin 10
+#define ARDUINO_9_PIN 20 // Digital pin 9
+#define ARDUINO_8_PIN 19 // Digital pin 8
+
+#define ARDUINO_7_PIN 18 // Digital pin 7
+#define ARDUINO_6_PIN 17 // Digital pin 6
+#define ARDUINO_5_PIN 16 // Digital pin 5
+#define ARDUINO_4_PIN 15 // Digital pin 4
+#define ARDUINO_3_PIN 14 // Digital pin 3
+#define ARDUINO_2_PIN 13 // Digital pin 2
+#define ARDUINO_1_PIN 12 // Digital pin 1
+#define ARDUINO_0_PIN 11 // Digital pin 0
+
+#define ARDUINO_A0_PIN 3 // Analog channel 0
+#define ARDUINO_A1_PIN 4 // Analog channel 1
+#define ARDUINO_A2_PIN 28 // Analog channel 2
+#define ARDUINO_A3_PIN 29 // Analog channel 3
+#define ARDUINO_A4_PIN 30 // Analog channel 4
+#define ARDUINO_A5_PIN 31 // Analog channel 5
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // PCA10036_H
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/boards/pca10040.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/boards/pca10040.h
new file mode 100644
index 0000000..9d390a3
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/boards/pca10040.h
@@ -0,0 +1,177 @@
+/**
+ * Copyright (c) 2014 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#ifndef PCA10040_H
+#define PCA10040_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "nrf_gpio.h"
+
+// LEDs definitions for PCA10040
+#define LEDS_NUMBER 4
+
+#define LED_START 17
+#define LED_1 17
+#define LED_2 18
+#define LED_3 19
+#define LED_4 20
+#define LED_STOP 20
+
+#define LEDS_ACTIVE_STATE 0
+
+#define LEDS_INV_MASK LEDS_MASK
+
+#define LEDS_LIST { LED_1, LED_2, LED_3, LED_4 }
+
+#define BSP_LED_0 LED_1
+#define BSP_LED_1 LED_2
+#define BSP_LED_2 LED_3
+#define BSP_LED_3 LED_4
+
+#define BUTTONS_NUMBER 4
+
+#define BUTTON_START 13
+#define BUTTON_1 13
+#define BUTTON_2 14
+#define BUTTON_3 15
+#define BUTTON_4 16
+#define BUTTON_STOP 16
+#define BUTTON_PULL NRF_GPIO_PIN_PULLUP
+
+#define BUTTONS_ACTIVE_STATE 0
+
+#define BUTTONS_LIST { BUTTON_1, BUTTON_2, BUTTON_3, BUTTON_4 }
+
+#define BSP_BUTTON_0 BUTTON_1
+#define BSP_BUTTON_1 BUTTON_2
+#define BSP_BUTTON_2 BUTTON_3
+#define BSP_BUTTON_3 BUTTON_4
+
+#define RX_PIN_NUMBER 8
+#define TX_PIN_NUMBER 6
+#define CTS_PIN_NUMBER 7
+#define RTS_PIN_NUMBER 5
+#define HWFC true
+
+#define SPIS_MISO_PIN 28 // SPI MISO signal.
+#define SPIS_CSN_PIN 12 // SPI CSN signal.
+#define SPIS_MOSI_PIN 25 // SPI MOSI signal.
+#define SPIS_SCK_PIN 29 // SPI SCK signal.
+
+#define SPIM0_SCK_PIN 29 // SPI clock GPIO pin number.
+#define SPIM0_MOSI_PIN 25 // SPI Master Out Slave In GPIO pin number.
+#define SPIM0_MISO_PIN 28 // SPI Master In Slave Out GPIO pin number.
+#define SPIM0_SS_PIN 12 // SPI Slave Select GPIO pin number.
+
+#define SPIM1_SCK_PIN 2 // SPI clock GPIO pin number.
+#define SPIM1_MOSI_PIN 3 // SPI Master Out Slave In GPIO pin number.
+#define SPIM1_MISO_PIN 4 // SPI Master In Slave Out GPIO pin number.
+#define SPIM1_SS_PIN 5 // SPI Slave Select GPIO pin number.
+
+#define SPIM2_SCK_PIN 12 // SPI clock GPIO pin number.
+#define SPIM2_MOSI_PIN 13 // SPI Master Out Slave In GPIO pin number.
+#define SPIM2_MISO_PIN 14 // SPI Master In Slave Out GPIO pin number.
+#define SPIM2_SS_PIN 15 // SPI Slave Select GPIO pin number.
+
+// serialization APPLICATION board - temp. setup for running serialized MEMU tests
+#define SER_APP_RX_PIN 23 // UART RX pin number.
+#define SER_APP_TX_PIN 24 // UART TX pin number.
+#define SER_APP_CTS_PIN 2 // UART Clear To Send pin number.
+#define SER_APP_RTS_PIN 25 // UART Request To Send pin number.
+
+#define SER_APP_SPIM0_SCK_PIN 27 // SPI clock GPIO pin number.
+#define SER_APP_SPIM0_MOSI_PIN 2 // SPI Master Out Slave In GPIO pin number
+#define SER_APP_SPIM0_MISO_PIN 26 // SPI Master In Slave Out GPIO pin number
+#define SER_APP_SPIM0_SS_PIN 23 // SPI Slave Select GPIO pin number
+#define SER_APP_SPIM0_RDY_PIN 25 // SPI READY GPIO pin number
+#define SER_APP_SPIM0_REQ_PIN 24 // SPI REQUEST GPIO pin number
+
+// serialization CONNECTIVITY board
+#define SER_CON_RX_PIN 24 // UART RX pin number.
+#define SER_CON_TX_PIN 23 // UART TX pin number.
+#define SER_CON_CTS_PIN 25 // UART Clear To Send pin number. Not used if HWFC is set to false.
+#define SER_CON_RTS_PIN 2 // UART Request To Send pin number. Not used if HWFC is set to false.
+
+
+#define SER_CON_SPIS_SCK_PIN 27 // SPI SCK signal.
+#define SER_CON_SPIS_MOSI_PIN 2 // SPI MOSI signal.
+#define SER_CON_SPIS_MISO_PIN 26 // SPI MISO signal.
+#define SER_CON_SPIS_CSN_PIN 23 // SPI CSN signal.
+#define SER_CON_SPIS_RDY_PIN 25 // SPI READY GPIO pin number.
+#define SER_CON_SPIS_REQ_PIN 24 // SPI REQUEST GPIO pin number.
+
+#define SER_CONN_CHIP_RESET_PIN 11 // Pin used to reset connectivity chip
+
+
+// Arduino board mappings
+#define ARDUINO_SCL_PIN 27 // SCL signal pin
+#define ARDUINO_SDA_PIN 26 // SDA signal pin
+#define ARDUINO_AREF_PIN 2 // Aref pin
+#define ARDUINO_13_PIN 25 // Digital pin 13
+#define ARDUINO_12_PIN 24 // Digital pin 12
+#define ARDUINO_11_PIN 23 // Digital pin 11
+#define ARDUINO_10_PIN 22 // Digital pin 10
+#define ARDUINO_9_PIN 20 // Digital pin 9
+#define ARDUINO_8_PIN 19 // Digital pin 8
+
+#define ARDUINO_7_PIN 18 // Digital pin 7
+#define ARDUINO_6_PIN 17 // Digital pin 6
+#define ARDUINO_5_PIN 16 // Digital pin 5
+#define ARDUINO_4_PIN 15 // Digital pin 4
+#define ARDUINO_3_PIN 14 // Digital pin 3
+#define ARDUINO_2_PIN 13 // Digital pin 2
+#define ARDUINO_1_PIN 12 // Digital pin 1
+#define ARDUINO_0_PIN 11 // Digital pin 0
+
+#define ARDUINO_A0_PIN 3 // Analog channel 0
+#define ARDUINO_A1_PIN 4 // Analog channel 1
+#define ARDUINO_A2_PIN 28 // Analog channel 2
+#define ARDUINO_A3_PIN 29 // Analog channel 3
+#define ARDUINO_A4_PIN 30 // Analog channel 4
+#define ARDUINO_A5_PIN 31 // Analog channel 5
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // PCA10040_H
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/boards/pca10056.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/boards/pca10056.h
new file mode 100644
index 0000000..de0a265
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/boards/pca10056.h
@@ -0,0 +1,163 @@
+/**
+ * Copyright (c) 2016 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#ifndef PCA10056_H
+#define PCA10056_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "nrf_gpio.h"
+
+// LEDs definitions for PCA10056
+#define LEDS_NUMBER 4
+
+#define LED_1 NRF_GPIO_PIN_MAP(0,13)
+#define LED_2 NRF_GPIO_PIN_MAP(0,14)
+#define LED_3 NRF_GPIO_PIN_MAP(0,15)
+#define LED_4 NRF_GPIO_PIN_MAP(0,16)
+#define LED_START LED_1
+#define LED_STOP LED_4
+
+#define LEDS_ACTIVE_STATE 0
+
+#define LEDS_LIST { LED_1, LED_2, LED_3, LED_4 }
+
+#define LEDS_INV_MASK LEDS_MASK
+
+#define BSP_LED_0 13
+#define BSP_LED_1 14
+#define BSP_LED_2 15
+#define BSP_LED_3 16
+
+#define BUTTONS_NUMBER 4
+
+#define BUTTON_1 11
+#define BUTTON_2 12
+#define BUTTON_3 24
+#define BUTTON_4 25
+#define BUTTON_PULL NRF_GPIO_PIN_PULLUP
+
+#define BUTTONS_ACTIVE_STATE 0
+
+#define BUTTONS_LIST { BUTTON_1, BUTTON_2, BUTTON_3, BUTTON_4 }
+
+#define BSP_BUTTON_0 BUTTON_1
+#define BSP_BUTTON_1 BUTTON_2
+#define BSP_BUTTON_2 BUTTON_3
+#define BSP_BUTTON_3 BUTTON_4
+
+#define RX_PIN_NUMBER 8
+#define TX_PIN_NUMBER 6
+#define CTS_PIN_NUMBER 7
+#define RTS_PIN_NUMBER 5
+#define HWFC true
+
+#define BSP_QSPI_SCK_PIN 19
+#define BSP_QSPI_CSN_PIN 17
+#define BSP_QSPI_IO0_PIN 20
+#define BSP_QSPI_IO1_PIN 21
+#define BSP_QSPI_IO2_PIN 22
+#define BSP_QSPI_IO3_PIN 23
+
+
+// serialization APPLICATION board - temp. setup for running serialized MEMU tests
+#define SER_APP_RX_PIN NRF_GPIO_PIN_MAP(1,13) // UART RX pin number.
+#define SER_APP_TX_PIN NRF_GPIO_PIN_MAP(1,14) // UART TX pin number.
+#define SER_APP_CTS_PIN NRF_GPIO_PIN_MAP(0,2) // UART Clear To Send pin number.
+#define SER_APP_RTS_PIN NRF_GPIO_PIN_MAP(1,15) // UART Request To Send pin number.
+
+#define SER_APP_SPIM0_SCK_PIN NRF_GPIO_PIN_MAP(0,27) // SPI clock GPIO pin number.
+#define SER_APP_SPIM0_MOSI_PIN NRF_GPIO_PIN_MAP(0,2) // SPI Master Out Slave In GPIO pin number
+#define SER_APP_SPIM0_MISO_PIN NRF_GPIO_PIN_MAP(0,26) // SPI Master In Slave Out GPIO pin number
+#define SER_APP_SPIM0_SS_PIN NRF_GPIO_PIN_MAP(1,13) // SPI Slave Select GPIO pin number
+#define SER_APP_SPIM0_RDY_PIN NRF_GPIO_PIN_MAP(1,15) // SPI READY GPIO pin number
+#define SER_APP_SPIM0_REQ_PIN NRF_GPIO_PIN_MAP(1,14) // SPI REQUEST GPIO pin number
+
+// serialization CONNECTIVITY board
+#define SER_CON_RX_PIN NRF_GPIO_PIN_MAP(1,14) // UART RX pin number.
+#define SER_CON_TX_PIN NRF_GPIO_PIN_MAP(1,13) // UART TX pin number.
+#define SER_CON_CTS_PIN NRF_GPIO_PIN_MAP(1,15) // UART Clear To Send pin number. Not used if HWFC is set to false.
+#define SER_CON_RTS_PIN NRF_GPIO_PIN_MAP(0,2) // UART Request To Send pin number. Not used if HWFC is set to false.
+
+
+#define SER_CON_SPIS_SCK_PIN NRF_GPIO_PIN_MAP(0,27) // SPI SCK signal.
+#define SER_CON_SPIS_MOSI_PIN NRF_GPIO_PIN_MAP(0,2) // SPI MOSI signal.
+#define SER_CON_SPIS_MISO_PIN NRF_GPIO_PIN_MAP(0,26) // SPI MISO signal.
+#define SER_CON_SPIS_CSN_PIN NRF_GPIO_PIN_MAP(1,13) // SPI CSN signal.
+#define SER_CON_SPIS_RDY_PIN NRF_GPIO_PIN_MAP(1,15) // SPI READY GPIO pin number.
+#define SER_CON_SPIS_REQ_PIN NRF_GPIO_PIN_MAP(1,14) // SPI REQUEST GPIO pin number.
+
+#define SER_CONN_CHIP_RESET_PIN NRF_GPIO_PIN_MAP(1,1) // Pin used to reset connectivity chip
+
+// Arduino board mappings
+#define ARDUINO_SCL_PIN 27 // SCL signal pin
+#define ARDUINO_SDA_PIN 26 // SDA signal pin
+#define ARDUINO_AREF_PIN 2 // Aref pin
+
+#define ARDUINO_13_PIN NRF_GPIO_PIN_MAP(1, 15) // Digital pin 13
+#define ARDUINO_12_PIN NRF_GPIO_PIN_MAP(1, 14) // Digital pin 12
+#define ARDUINO_11_PIN NRF_GPIO_PIN_MAP(1, 13) // Digital pin 11
+#define ARDUINO_10_PIN NRF_GPIO_PIN_MAP(1, 12) // Digital pin 10
+#define ARDUINO_9_PIN NRF_GPIO_PIN_MAP(1, 11) // Digital pin 9
+#define ARDUINO_8_PIN NRF_GPIO_PIN_MAP(1, 10) // Digital pin 8
+
+#define ARDUINO_7_PIN NRF_GPIO_PIN_MAP(1, 8) // Digital pin 7
+#define ARDUINO_6_PIN NRF_GPIO_PIN_MAP(1, 7) // Digital pin 6
+#define ARDUINO_5_PIN NRF_GPIO_PIN_MAP(1, 6) // Digital pin 5
+#define ARDUINO_4_PIN NRF_GPIO_PIN_MAP(1, 5) // Digital pin 4
+#define ARDUINO_3_PIN NRF_GPIO_PIN_MAP(1, 4) // Digital pin 3
+#define ARDUINO_2_PIN NRF_GPIO_PIN_MAP(1, 3) // Digital pin 2
+#define ARDUINO_1_PIN NRF_GPIO_PIN_MAP(1, 2) // Digital pin 1
+#define ARDUINO_0_PIN NRF_GPIO_PIN_MAP(1, 1) // Digital pin 0
+
+#define ARDUINO_A0_PIN 3 // Analog channel 0
+#define ARDUINO_A1_PIN 4 // Analog channel 1
+#define ARDUINO_A2_PIN 28 // Analog channel 2
+#define ARDUINO_A3_PIN 29 // Analog channel 3
+#define ARDUINO_A4_PIN 30 // Analog channel 4
+#define ARDUINO_A5_PIN 31 // Analog channel 5
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // PCA10056_H
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/boards/pca10059.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/boards/pca10059.h
new file mode 100644
index 0000000..bb987c1
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/boards/pca10059.h
@@ -0,0 +1,95 @@
+/**
+ * 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#ifndef PCA10059_H
+#define PCA10059_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "nrf_gpio.h"
+
+// LED definitions for PCA10059
+// Each LED color is considered a separate LED
+#define LEDS_NUMBER 4
+
+#define LED1_G NRF_GPIO_PIN_MAP(0,6)
+#define LED2_R NRF_GPIO_PIN_MAP(0,8)
+#define LED2_G NRF_GPIO_PIN_MAP(1,9)
+#define LED2_B NRF_GPIO_PIN_MAP(0,12)
+
+#define LED_1 LED1_G
+#define LED_2 LED2_R
+#define LED_3 LED2_G
+#define LED_4 LED2_B
+
+#define LEDS_ACTIVE_STATE 0
+
+#define LEDS_LIST { LED_1, LED_2, LED_3, LED_4 }
+
+#define LEDS_INV_MASK LEDS_MASK
+
+#define BSP_LED_0 LED_1
+#define BSP_LED_1 LED_2
+#define BSP_LED_2 LED_3
+#define BSP_LED_3 LED_4
+
+// There is only one button for the application
+// as the second button is used for a RESET.
+#define BUTTONS_NUMBER 1
+
+#define BUTTON_1 NRF_GPIO_PIN_MAP(1,6)
+#define BUTTON_PULL NRF_GPIO_PIN_PULLUP
+
+#define BUTTONS_ACTIVE_STATE 0
+
+#define BUTTONS_LIST { BUTTON_1 }
+
+#define BSP_BUTTON_0 BUTTON_1
+
+#define BSP_SELF_PINRESET_PIN NRF_GPIO_PIN_MAP(0,19)
+
+#define HWFC true
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // PCA10059_H
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/boards/pca20006.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/boards/pca20006.h
new file mode 100644
index 0000000..1ad1fa4
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/boards/pca20006.h
@@ -0,0 +1,90 @@
+/**
+ * Copyright (c) 2014 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#ifndef PCA20006_H
+#define PCA20006_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "nrf_gpio.h"
+
+// LEDs and buttons definition for PCA20006 board (beacon)
+#define LEDS_NUMBER 3
+
+#define LED_RGB_RED 16
+#define LED_RGB_GREEN 12
+#define LED_RGB_BLUE 15
+
+#define LEDS_ACTIVE_STATE 0
+
+#define BSP_LED_0 LED_RGB_RED
+#define BSP_LED_1 LED_RGB_GREEN
+#define BSP_LED_2 LED_RGB_BLUE
+
+#define LEDS_LIST { LED_RGB_RED, LED_RGB_GREEN, LED_RGB_BLUE}
+
+#define LEDS_INV_MASK LEDS_MASK
+
+#define BUTTON_0 8
+#define BUTTON_1 18
+#define BUTTON_PULL NRF_GPIO_PIN_PULLUP
+
+#define BUTTONS_ACTIVE_STATE 0
+
+#define BSP_BUTTON_0 BUTTON_0
+#define BSP_BUTTON_1 BUTTON_1
+
+#define BUTTONS_NUMBER 2
+
+#define BUTTONS_LIST { BUTTON_0, BUTTON_1 }
+
+#define RX_PIN_NUMBER 24
+#define TX_PIN_NUMBER 9
+#define CTS_PIN_NUMBER 21
+#define RTS_PIN_NUMBER 11
+#define HWFC true
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/boards/pca20020.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/boards/pca20020.h
new file mode 100644
index 0000000..2c86b3f
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/boards/pca20020.h
@@ -0,0 +1,126 @@
+/**
+ * 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#ifndef PCA20020_H
+#define PCA20020_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "nrf_gpio.h"
+
+#define NRF_NUM_GPIO_PINS 32
+
+#define OSC_XL1 0
+#define OSC_XL2 1
+#define ANA_DIG0 2
+#define ANA_DIG1 3
+#define ANA_DIG2 4
+#define IOEXT_OSCIO 5
+#define MPU_INT 6
+#define TWI_SDA 7
+#define TWI_SCL 8
+#define NFC1 9
+#define NFC2 10
+#define BUTTON 11
+#define LIS_INT1 12
+#define USB_DETECT 13
+#define TWI_SDA_EXT 14
+#define TWI_SCL_EXT 15
+#define SX_RESET 16
+#define BAT_CHG_STAT 17
+#define MOS_1 18
+#define MOS_2 19
+#define MOS_3 20
+#define MOS_4 21
+#define CCS_INT 22
+#define LPS_INT 23
+#define HTS_INT 24
+#define MIC_DOUT 25
+#define MIC_CLK 26
+#define SPEAKER 27
+#define BATTERY 28
+#define SPK_PWR_CTRL 29
+#define VDD_PWR_CTRL 30
+#define BH_INT 31
+
+// Button config
+#define BUTTONS_NUMBER 1
+#define BUTTON_START BUTTON
+#define BUTTON_STOP BUTTON
+#define BUTTON_PULL NRF_GPIO_PIN_PULLUP
+#define BUTTONS_ACTIVE_STATE 0
+#define BUTTONS_LIST { BUTTON }
+
+#define LEDS_NUMBER 0
+
+// IO expander pins
+#define SX_IOEXT_NUM_PINS 16
+
+#define SX_IOEXT_0 0
+#define SX_IOEXT_1 1
+#define SX_IOEXT_2 2
+#define SX_IOEXT_3 3
+#define SX_BAT_MON_EN 4
+#define SX_LIGHTWELL_G 5
+#define SX_LIGHTWELL_B 6
+#define SX_LIGHTWELL_R 7
+#define SX_MPU_PWR_CTRL 8
+#define SX_MIC_PWR_CTRL 9
+#define SX_CCS_PWR_CTRL 10
+#define SX_CCS_RESET 11
+#define SX_CCS_WAKE 12
+#define SX_SENSE_LED_R 13
+#define SX_SENSE_LED_G 14
+#define SX_SENSE_LED_B 15
+
+// Uart configuration for testing
+#define RX_PIN_NUMBER ANA_DIG1
+#define TX_PIN_NUMBER ANA_DIG0
+#define CTS_PIN_NUMBER 0
+#define RTS_PIN_NUMBER 0
+#define HWFC false
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // PCA20020_H
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/boards/wt51822.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/boards/wt51822.h
new file mode 100644
index 0000000..f5c602f
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/boards/wt51822.h
@@ -0,0 +1,94 @@
+/**
+ * Copyright (c) 2014 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#ifndef WT51822_H
+#define WT51822_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define LEDS_NUMBER 3
+
+#define LED_1 3
+#define LED_2 4
+#define LED_3 5
+
+#define LEDS_LIST { LED_1, LED_2, LED_3 }
+
+#define LEDS_ACTIVE_STATE 0
+
+#define BSP_LED_0 LED_1
+#define BSP_LED_1 LED_2
+#define BSP_LED_2 LED_3
+
+#define LEDS_INV_MASK LEDS_MASK
+
+#define BUTTONS_NUMBER 3
+
+#define SW_1 0
+#define SW_2 1
+#define SW_3 2
+#define BUTTON_PULL NRF_GPIO_PIN_PULLUP
+
+#define BUTTONS_LIST { SW_1, SW_2, SW_3 }
+
+#define BUTTONS_ACTIVE_STATE 0
+
+#define BSP_BUTTON_0 SW_1
+#define BSP_BUTTON_1 SW_2
+#define BSP_BUTTON_2 SW_3
+
+#define RX_PIN_NUMBER 13
+#define TX_PIN_NUMBER 12
+#define CTS_PIN_NUMBER 14
+#define RTS_PIN_NUMBER 15
+#define HWFC true
+
+#define SER_CON_RX_PIN 13
+#define SER_CON_TX_PIN 12
+#define SER_CON_CTS_PIN 14
+#define SER_CON_RTS_PIN 15
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/drivers_ext/adns2080/adns2080.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/drivers_ext/adns2080/adns2080.c
new file mode 100644
index 0000000..6b30f11
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/drivers_ext/adns2080/adns2080.c
@@ -0,0 +1,358 @@
+/**
+ * Copyright (c) 2009 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#include <stdbool.h>
+#include <stdint.h>
+
+#include "adns2080.h"
+#include "sdio.h"
+
+/*lint ++flb "Enter library region" */
+
+#define ADNS2080_PRODUCT_ID (0x2AU) /*!< ADNS2080 product id */
+#define ADNS2080_RESET_NUMBER (0x5AU) /*!< ADNS2080 reset code */
+
+/* ADNS2080 register addresses */
+#define REG_PROD_ID (0x00U) /*!< Product ID. Default value : 0x2A */
+#define REG_REV_ID (0x01U) /*!< Revision ID. Default value : 0x00 */
+#define REG_MOTION_ST (0x02U) /*!< Motion Status. Default value : 0x00 */
+#define REG_DELTA_X (0x03U) /*!< Lower byte of Delta_X. Default value : 0x00 */
+#define REG_DELTA_Y (0x04U) /*!< Lower byte of Delta_Y. Default value : 0x00 */
+#define REG_SQUAL (0x05U) /*!< Squal Quality. Default value : 0x00 */
+#define REG_SHUT_HI (0x06U) /*!< Shutter Open Time (Upper 8-bit). Default value : 0x00 */
+#define REG_SHUT_LO (0x07U) /*!< Shutter Open Time (Lower 8-bit). Default value : 0x64 */
+#define REG_PIX_MAX (0x08U) /*!< Maximum Pixel Value. Default value : 0xD0 */
+#define REG_PIX_ACCUM (0x09U) /*!< Average Pixel Value. Default value : 0x80 */
+#define REG_PIX_MIN (0x0AU) /*!< Minimum Pixel Value. Default value : 0x00 */
+#define REG_PIX_GRAB (0x0BU) /*!< Pixel Grabber. Default value : 0x00 */
+#define REG_DELTA_XY_HIGH (0x0CU) /*!< Upper 4 bits of Delta X and Y displacement. Default value : 0x00 */
+#define REG_MOUSE_CTRL (0x0DU) /*!< Mouse Control. Default value : 0x01 */
+#define REG_RUN_DOWNSHIFT (0x0EU) /*!< Run to Rest1 Time. Default value : 0x08 */
+#define REG_REST1_PERIOD (0x0FU) /*!< Rest1 Period. Default value : 0x01 */
+#define REG_REST1_DOWNSHIFT (0x10U) /*!< Rest1 to Rest2 Time. Default value : 0x1f */
+#define REG_REST2_PERIOD (0x11U) /*!< Rest2 Period. Default value : 0x09 */
+#define REG_REST2_DOWNSHIFT (0x12U) /*!< Rest2 to Rest3 Time. Default value : 0x2f */
+#define REG_REST3_PERIOD (0x13U) /*!< Rest3 Period. Default value : 0x31 */
+#define REG_PERFORMANCE (0x22U) /*!< Performance. Default value : 0x00 */
+#define REG_RESET (0x3aU) /*!< Reset. Default value : 0x00 */
+#define REG_NOT_REV_ID (0x3fU) /*!< Inverted Revision ID. Default value : 0xff */
+#define REG_LED_CTRL (0x40U) /*!< LED Control. Default value : 0x00 */
+#define REG_MOTION_CTRL (0x41U) /*!< Motion Control. Default value : 0x40 */
+#define REG_BURST_READ_FIRST (0x42U) /*!< Burst Read Starting Register. Default value : 0x03 */
+#define REG_BURST_READ_LAST (0x44U) /*!< Burst Read Ending Register. Default value : 0x09 */
+#define REG_REST_MODE_CONFIG (0x45U) /*!< Rest Mode Confi guration. Default value : 0x00 */
+#define REG_MOTION_BURST (0x63U) /*!< Burst Read. Default value : 0x00 */
+
+/* ADNS2080 register bits */
+#define REG_MOUSE_CTRL_POWERDOWN (0x02U) /*!< Mouse control register powerdown bit */
+#define REG_MOTION_CTRL_MOT_A (0x80U) /*!< Motion control register polarity bit */
+#define REG_MOTION_CTRL_MOT_S (0x40U) /*!< Motion control register edge sensitivity bit */
+#define REG_MOUSE_CTRL_RES_EN (0x40U) /*!< Mouse control register resolution enable bit */
+#define REG_MOUSE_CTRL_BIT_REPORTING (0x80U) /*!< Mouse control register "number of motion bits" bit*/
+
+void adns2080_movement_read(int16_t * deltaX, int16_t * deltaY)
+{
+ uint8_t delta_x; /*!< Stores REG_DELTA_X contents */
+ uint8_t delta_y; /*!< Stores REG_DELTA_Y contents */
+ uint8_t delta_xy_high; /*!< Stores REG_DELTA_XY contents which contains upper 4 bits for both delta_x and delta_y when 12 bit mode is used */
+ uint8_t delta_x_high; /*!< Stores delta_x 4 MSB bits */
+ uint8_t delta_y_high; /*!< Stores delta_y 4 MSB bits */
+
+ uint16_t u16_deltaX; /*!< This is used to buffer the result and will be cast later to int16_t */
+ uint16_t u16_deltaY; /*!< This is used to buffer the result and will be cast later to int16_t */
+
+ delta_x = sdio_read_byte(REG_DELTA_X);
+ delta_y = sdio_read_byte(REG_DELTA_Y);
+
+ if (adns2080_motion_bits_read() == ADNS2080_MOTION_BITS_12)
+ {
+ // In 12 bit mode the upper 4 bits are stored in a separate register
+ // where first 4 upper bits are for delta_x and lower 4 bits for delta_y.
+ delta_xy_high = sdio_read_byte(REG_DELTA_XY_HIGH);
+
+ delta_x_high = ((delta_xy_high & 0xF0) >> 4);
+ delta_y_high = (delta_xy_high & 0x0F);
+
+ // Check if MSB is 1. If it is, this is a negative number and we have
+ // to fill the upper unused bits with 1s.
+ if (delta_x_high & 0x08)
+ {
+ u16_deltaX = 0xF000;
+ }
+ else
+ {
+ u16_deltaX = 0x0000;
+ }
+
+ // Check if MSB is 1. If it is, this is a negative number and we have
+ // to fill the upper unused bits with 1s.
+ if (delta_y_high & 0x08)
+ {
+ u16_deltaY = 0xF000;
+ }
+ else
+ {
+ u16_deltaY = 0x0000;
+ }
+
+ u16_deltaX |= (delta_x_high << 4) | delta_x;
+ u16_deltaY |= (delta_y_high << 4) | delta_y;
+ }
+ else // Only 8 bits is used for motion data
+ {
+ // Check if MSB is 1. If it is, this is a negative number and we have
+ // to fill the upper unused bits with 1s.
+ if (delta_x & 0x80)
+ {
+ u16_deltaX = 0xFF00;
+ }
+ else
+ {
+ u16_deltaX = 0x0000;
+ }
+
+ // Check if MSB is 1. If it is, this is a negative number and we have
+ // to fill the upper unused bits with 1s.
+ if (delta_y & 0x80)
+ {
+ u16_deltaY = 0xFF00;
+ }
+ else
+ {
+ u16_deltaY = 0x0000;
+ }
+
+ u16_deltaX |= delta_x;
+ u16_deltaY |= delta_y;
+ }
+
+ *deltaX = (int16_t)u16_deltaX;
+ *deltaY = (int16_t)u16_deltaY;
+}
+
+adns2080_motion_bits_t adns2080_motion_bits_read(void)
+{
+ /* Read the most significant bit */
+ return (adns2080_motion_bits_t)((sdio_read_byte(REG_MOUSE_CTRL) >> 7) & 0x01);
+}
+
+bool adns2080_is_motion_detected(void)
+{
+ return ((sdio_read_byte(REG_MOTION_ST) & 0x80) != 0);
+}
+
+uint8_t adns2080_product_id_read(void)
+{
+ return sdio_read_byte(REG_PROD_ID);
+}
+
+uint8_t adns2080_revision_id_read(void)
+{
+ return sdio_read_byte(REG_REV_ID);
+}
+
+adns2080_status_t adns2080_init(void)
+{
+ sdio_init();
+ adns2080_reset();
+
+ if (adns2080_product_id_read() != ADNS2080_PRODUCT_ID)
+ {
+ return ADNS2080_CHIP_NOT_DETECTED;
+ }
+
+ sdio_write_byte(REG_BURST_READ_FIRST, REG_DELTA_X);
+ sdio_write_byte(REG_BURST_READ_LAST, REG_DELTA_Y);
+
+ return ADNS2080_OK;
+}
+
+void adns2080_reset(void)
+{
+ sdio_write_byte(REG_RESET, ADNS2080_RESET_NUMBER);
+}
+
+void adns2080_powerdown(void)
+{
+ sdio_write_byte(REG_MOUSE_CTRL, REG_MOUSE_CTRL_POWERDOWN);
+}
+
+void adns2080_wakeup(void)
+{
+ adns2080_reset();
+}
+
+adns2080_status_t adns2080_motion_interrupt_set(motion_output_polarity_t polarity, motion_output_sensitivity_t sensitivity)
+{
+ uint8_t databyte = 0;
+ adns2080_status_t status = ADNS2080_OK;
+
+ switch (polarity)
+ {
+ case ADNS2080_MOTION_OUTPUT_POLARITY_LOW:
+ databyte = 0; // Clear REG_MOTION_CTRL_MOT_A bit
+ break;
+
+ case ADNS2080_MOTION_OUTPUT_POLARITY_HIGH:
+ databyte = REG_MOTION_CTRL_MOT_A;
+ break;
+
+ default:
+ status = ADNS2080_INVALID_PARAMETER;
+ break;
+ }
+
+ switch (sensitivity)
+ {
+ case ADNS2080_MOTION_OUTPUT_SENSITIVITY_LEVEL:
+ databyte &= ~(REG_MOTION_CTRL_MOT_S);
+ break;
+
+ case ADNS2080_MOTION_OUTPUT_SENSITIVITY_EDGE:
+ databyte |= (REG_MOTION_CTRL_MOT_S);
+ break;
+
+ default:
+ status = ADNS2080_INVALID_PARAMETER;
+ break;
+ }
+
+ if (status == ADNS2080_OK)
+ {
+ sdio_write_byte(REG_MOTION_CTRL, databyte);
+ }
+
+ return status;
+}
+
+adns2080_status_t adns2080_resolution_set(adns2080_resolution_t resolution)
+{
+ uint8_t databyte = sdio_read_byte(REG_MOUSE_CTRL);
+ adns2080_status_t status = ADNS2080_OK;
+
+ // Enable resolution settings on REG_MOUSE_CTRL [4:2]
+ databyte |= (REG_MOUSE_CTRL_RES_EN);
+
+ switch (resolution)
+ {
+ case ADNS2080_RESOLUTION_250DPI:
+ case ADNS2080_RESOLUTION_500DPI:
+ case ADNS2080_RESOLUTION_1000DPI:
+ case ADNS2080_RESOLUTION_1250DPI:
+ case ADNS2080_RESOLUTION_1500DPI:
+ case ADNS2080_RESOLUTION_1750DPI:
+ case ADNS2080_RESOLUTION_2000DPI:
+ // Clear resolution bits [4:2]
+ databyte &= ~(0x1C); // 0b00011100;
+ // Set resolution bits
+ databyte |= (uint8_t)((uint8_t)resolution << 2);
+ break;
+
+ default:
+ status = ADNS2080_INVALID_PARAMETER;
+ break;
+ }
+
+ if (status == ADNS2080_OK)
+ {
+ sdio_write_byte(REG_MOUSE_CTRL, databyte);
+ }
+
+ return status;
+}
+
+adns2080_status_t adns2080_motion_bits_set(adns2080_motion_bits_t motion_bits)
+{
+ uint8_t databyte = sdio_read_byte(REG_MOUSE_CTRL);
+ adns2080_status_t status = ADNS2080_OK;
+
+ switch (motion_bits)
+ {
+ case ADNS2080_MOTION_BITS_8:
+ databyte &= ~(REG_MOUSE_CTRL_BIT_REPORTING);
+ break;
+
+ case ADNS2080_MOTION_BITS_12:
+ databyte |= (REG_MOUSE_CTRL_BIT_REPORTING);
+ break;
+
+ default:
+ status = ADNS2080_INVALID_PARAMETER;
+ break;
+ }
+
+ if (status == ADNS2080_OK)
+ {
+ sdio_write_byte(REG_MOUSE_CTRL, databyte);
+ }
+
+ return status;
+}
+
+void adns2080_rest_periods_set(uint8_t rest1_period, uint8_t rest2_period, uint8_t rest3_period)
+{
+ adns2080_mode_t current_mode = adns2080_force_mode_read();
+ adns2080_force_mode_set(ADNS2080_MODE_RUN1);
+ sdio_write_byte(REG_REST1_PERIOD, rest1_period);
+ sdio_write_byte(REG_REST2_PERIOD, rest2_period);
+ sdio_write_byte(REG_REST3_PERIOD, rest3_period);
+ adns2080_force_mode_set(current_mode);
+}
+
+void adns2080_downshift_times_set(uint8_t run_to_rest1_mode_time, uint8_t rest1_to_rest2_mode_time, uint8_t rest2_to_rest3_mode_time)
+{
+ adns2080_mode_t current_mode = adns2080_force_mode_read();
+ adns2080_force_mode_set(ADNS2080_MODE_RUN1);
+ sdio_write_byte(REG_RUN_DOWNSHIFT, run_to_rest1_mode_time);
+ sdio_write_byte(REG_REST1_DOWNSHIFT, rest1_to_rest2_mode_time);
+ sdio_write_byte(REG_REST2_DOWNSHIFT, rest2_to_rest3_mode_time);
+ adns2080_force_mode_set(current_mode);
+}
+
+adns2080_mode_t adns2080_force_mode_read(void)
+{
+ return (adns2080_mode_t)((sdio_read_byte(REG_PERFORMANCE) >> 4) & 0x07);
+}
+
+void adns2080_force_mode_set(adns2080_mode_t mode)
+{
+ sdio_write_byte(REG_PERFORMANCE, (uint8_t)((uint8_t)mode << 4));
+}
+
+/*lint --flb "Leave library region" */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/drivers_ext/adns2080/adns2080.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/drivers_ext/adns2080/adns2080.h
new file mode 100644
index 0000000..1ea60b6
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/drivers_ext/adns2080/adns2080.h
@@ -0,0 +1,317 @@
+/**
+ * Copyright (c) 2009 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#ifndef ADNS2080_H
+#define ADNS2080_H
+
+/*lint ++flb "Enter library region" */
+
+#include <stdbool.h>
+#include <stdint.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** @file
+* @brief ADNS2080 mouse sensor driver
+*
+* @defgroup nrf_drivers_adns2080 ADNS2080 driver
+* @{
+* @ingroup ext_drivers
+* @brief ADNS2080 mouse sensor driver.
+*/
+
+/**
+ * Describes return values for @ref adns2080_init.
+ */
+typedef enum
+{
+ ADNS2080_OK, /*!< Operation was succesful */
+ ADNS2080_SERIAL_COMM_FAILURE, /*!< Serial communication failed */
+ ADNS2080_CHIP_NOT_DETECTED, /*!< Product/Revision ID was not what was expected */
+ ADNS2080_INVALID_PARAMETER /*!< Given parameters were not valid */
+} adns2080_status_t;
+
+/**
+ * ADNS2080 motion output pin polarity values.
+ */
+typedef enum
+{
+ ADNS2080_MOTION_OUTPUT_POLARITY_LOW = 0, /*!< Motion output polarity active low */
+ ADNS2080_MOTION_OUTPUT_POLARITY_HIGH = 1 /*!< Motion output polarity active high */
+} motion_output_polarity_t;
+
+/**
+ * Motion output pin configuration.
+ */
+typedef enum
+{
+ ADNS2080_MOTION_OUTPUT_SENSITIVITY_LEVEL = 0, /*!< Motion output pin will be driven low/high (depending on the polarity setting) as long as there is motion data in DELTA registers */
+ ADNS2080_MOTION_OUTPUT_SENSITIVITY_EDGE = 1 /*!< Motion output pin will be driven low/high (depending on the polarity setting) for 380 ns when motion is detected during rest modes */
+} motion_output_sensitivity_t;
+
+/**
+ * Mouse sensor resolution values.
+ */
+typedef enum
+{
+ ADNS2080_RESOLUTION_250DPI = 1, /*!< 250 dpi resolution */
+ ADNS2080_RESOLUTION_500DPI = 2, /*!< 500 dpi resolution */
+ ADNS2080_RESOLUTION_1000DPI = 0, /*!< 1000 dpi resolution */
+ ADNS2080_RESOLUTION_1250DPI = 3, /*!< 1250 dpi resolution */
+ ADNS2080_RESOLUTION_1500DPI = 4, /*!< 1500 dpi resolution */
+ ADNS2080_RESOLUTION_1750DPI = 5, /*!< 1750 dpi resolution */
+ ADNS2080_RESOLUTION_2000DPI = 6 /*!< 2000 dpi resolution */
+} adns2080_resolution_t;
+
+/**
+ * Mouse sensor forced mode options.
+ */
+typedef enum
+{
+ ADNS2080_MODE_NORMAL = 0, /*!< Normal operation mode */
+ ADNS2080_MODE_REST1 = 1, /*!< Rest1 operation mode */
+ ADNS2080_MODE_REST2 = 2, /*!< Rest2 operation mode */
+ ADNS2080_MODE_REST3 = 3, /*!< Rest3 operation mode */
+ ADNS2080_MODE_RUN1 = 4, /*!< Run1 operation mode */
+ ADNS2080_MODE_RUN2 = 5, /*!< Run2 operation mode */
+ ADNS2080_MODE_IDLE = 6 /*!< Idle operation mode */
+} adns2080_mode_t;
+
+/**
+ * Mouse sensor motion reporting bits.
+ */
+typedef enum
+{
+ ADNS2080_MOTION_BITS_8 = 0, /*!< Motion reporting uses 8 bits */
+ ADNS2080_MOTION_BITS_12 = 1 /*!< Motion reporting uses 12 bits */
+} adns2080_motion_bits_t;
+
+/**
+ * @brief Function for initializing the mouse sensor chip.
+ *
+ * Valid mouse sensor information will be available 50 milliseconds after this
+ * function finishes.
+ *
+ * @return
+ * @retval ADNS2080_OK Mouse sensor was initialized succesfully.
+ * @retval ADNS2080_SERIAL_COMM_FAILURE Serial communications failure.
+ * @retval ADNS2080_CHIP_NOT_DETECTED Could not find revision 0 ADNS2080 chip.
+ */
+adns2080_status_t adns2080_init(void);
+
+/**
+ * @brief Function for resetting the mouse sensor chip.
+ *
+ * Valid mouse sensor information will be available 50 milliseconds after this
+ * function finishes.
+ * All register settings will be lost and need to be reloaded.
+ *
+ */
+void adns2080_reset(void);
+
+/**
+ * @brief Function for reading mouse sensor product ID.
+ *
+ * Chip is expected to be initialized before calling this function.
+ * Returned product ID should always be 0x2A.
+ *
+ * @return Product ID.
+ */
+uint8_t adns2080_product_id_read(void);
+
+/**
+ * @brief Function for reading mouse sensor revision ID.
+ *
+ * Chip is expected to be initialized before calling this function.
+ *
+ * @return Product ID.
+ */
+uint8_t adns2080_revision_id_read(void); // also note there is "not rev id" register
+
+/**
+ * @brief Function for powering down the mouse sensor.
+ *
+ * Chip is expected to be initialized before calling this function.
+ * Serial port should not be accessed during the power down. To exit the power
+ * down mode, @ref adns2080_wakeup must be called.
+ *
+ */
+void adns2080_powerdown(void);
+
+/**
+ * @brief Function for waking up the mouse sensor.
+ *
+ * After wakeup, all mouse sensor settings must be reloaded. Valid mouse sensor
+ * information will be available 55 milliseconds after this function finishes.
+ */
+void adns2080_wakeup(void);
+
+/**
+ * @brief Function for configuring the MOTION interrupt output pin.
+ *
+ * When motion is detected by the mouse sensor, the chip has a MOTION pin
+ * indicating there is motion data in DELTA_X and DELTA_Y registers. This
+ * function configures the polarity and sensitivity of that pin.
+ *
+ * Chip is expected to be initialized before calling this function.
+ *
+ * @param polarity MOTION output pin is either active LOW (default) or active HIGH
+ * @param sensitivity Level or Edge (default) sensitive
+ * @return
+ * @retval ADNS2080_OK Operation succeeded.
+ * @retval ADNS2080_INVALID_PARAMETER One of the parameters was not within valid range.
+ */
+adns2080_status_t adns2080_motion_interrupt_set(motion_output_polarity_t polarity, motion_output_sensitivity_t sensitivity);
+
+/**
+ * @brief Function for setting mouse sensor resolution.
+ *
+ * Chip is expected to be initialized before calling this function.
+ *
+ * @param resolution Desired resolution.
+ * @return
+ * @retval ADNS2080_OK Operation succeeded.
+ * @retval ADNS2080_INVALID_PARAMETER One of the parameters was not within valid range.
+ */
+adns2080_status_t adns2080_resolution_set(adns2080_resolution_t resolution);
+
+/**
+ * @brief Function for setting number of bits used for mouse sensor motion reporting.
+ *
+ * Chip is expected to be initialized before calling this function.
+ *
+ * @param motion_bits Desired number of bits.
+ * @return
+ * @retval ADNS2080_OK Operation succeeded.
+ * @retval ADNS2080_INVALID_PARAMETER One of the parameters was not within valid range.
+ */
+adns2080_status_t adns2080_motion_bits_set(adns2080_motion_bits_t motion_bits);
+
+/**
+ * @brief Function for reading number of bits used for mouse sensor motion reporting.
+ *
+ * Chip is expected to be initialized before calling this function.
+ *
+ * @return motion_bits Number of bits.
+ */
+adns2080_motion_bits_t adns2080_motion_bits_read(void);
+
+/**
+ * @brief Function for reading X- and Y-axis movement (in counts) since last report.
+ *
+ * Absolute value is determined by resolution.
+ * Chip is expected to be initialized before calling this function.
+ *
+ * @param p_delta_x Location to store X-axis movement
+ * @param p_delta_y Location to store Y-axis movement
+ */
+void adns2080_movement_read(int16_t *p_delta_x, int16_t *p_delta_y);
+
+/**
+ * @brief Function for checking if motion has been detected since last call.
+ *
+ * Chip is expected to be initialized before calling this function.
+ *
+ * @return
+ * @retval true, if movement has been detected
+ * @retval false, if no movement has been detected
+ */
+bool adns2080_is_motion_detected(void);
+
+/**
+ * @brief Function for setting mouse sensor Rest1, Rest2 and Rest3 mode motion detection time period.
+ *
+ * Allowed range for the periods is 0x01 to 0xFD.
+ * Resulting period is derived from the following equation :
+ * Period = (Rest period + 1) * 10 milliseconds
+ * Chip is expected to be initialized before calling this function.
+ *
+ * @param rest1_period Rest1 period
+ * @param rest2_period Rest2 period
+ * @param rest3_period Rest3 period
+ */
+void adns2080_rest_periods_set(uint8_t rest1_period, uint8_t rest2_period, uint8_t rest3_period);
+
+/**
+ * @brief Function for setting mouse sensor mode downshift time periods.
+ *
+ * Allowed range for run_to_rest1_mode_time period is 0x00 to 0xFF.
+ * Allowed range for rest1_to_rest2_mode_time period is 0x01 to 0xFF.
+ * Allowed range for rest2_to_rest3_mode_time period is 0x01 to 0xFF.
+ *
+ * Chip is expected to be initialized before calling this function.
+ *
+ * @param run_to_rest1_mode_time Run mode to Rest1 mode downshift time period (Time = run_to_rest1_mode_time * 8 * 4)
+ * @param rest1_to_rest2_mode_time Rest1 mode to Rest2 mode downshift time period (Time = rest1_to_rest2_mode_time * rest1_period * 16)
+ * @param rest2_to_rest3_mode_time Rest2 mode to Rest3 mode downshift time period (Time = rest2_to_rest3_mode_time * rest2_period * 128)
+ */
+void adns2080_downshift_times_set(uint8_t run_to_rest1_mode_time, uint8_t rest1_to_rest2_mode_time, uint8_t rest2_to_rest3_mode_time);
+
+/**
+ * @brief Function for forcing mouse sensor to a certain operating mode.
+ *
+ * Chip is expected to be initialized before calling this function.
+ * Normal operation will not continue until this function is called with ADNS2080_MODE_NORMAL parameter.
+ *
+ * @param mode Mode to force the sensor to.
+ */
+void adns2080_force_mode_set(adns2080_mode_t mode);
+
+/**
+ * @brief Function for reading the current forced operating mode.
+ *
+ * Chip is expected to be initialized before calling this function.
+ *
+ * @return Mode the sensor is forced to.
+ */
+adns2080_mode_t adns2080_force_mode_read(void);
+
+/**
+ *@}
+ **/
+
+/*lint --flb "Leave library region" */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/drivers_ext/bh1745/bh1745.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/drivers_ext/bh1745/bh1745.c
new file mode 100644
index 0000000..a69bb24
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/drivers_ext/bh1745/bh1745.c
@@ -0,0 +1,203 @@
+/**
+ * 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#include "bh1745.h"
+
+#define BH1745_SENSOR_WRITE(p_instance, msg) \
+ nrf_twi_sensor_write(p_instance->p_sensor_data, \
+ p_instance->sensor_addr, \
+ msg, \
+ ARRAY_SIZE(msg), \
+ true)
+
+ret_code_t bh1745_init(bh1745_instance_t * p_instance)
+{
+ ASSERT(p_instance != NULL);
+ if (p_instance->p_sensor_data->p_twi_mngr->p_queue->size < BH1745_MIN_QUEUE_SIZE)
+ {
+ return NRF_ERROR_INVALID_LENGTH;
+ }
+
+ static const uint8_t msg1[] = {
+ BH1745_REG_MODE_CONTROL1,
+ 0x00,
+ 0x00,
+ 0x00
+ };
+ ret_code_t err = BH1745_SENSOR_WRITE(p_instance, msg1);
+ if (err != NRF_SUCCESS)
+ {
+ return err;
+ }
+
+ static const uint8_t msg2[] = {
+ BH1745_REG_INTERRUPT,
+ 0x00,
+ 0x01,
+ 0xFF,
+ 0xFF,
+ 0x00,
+ 0x00
+ };
+ return BH1745_SENSOR_WRITE(p_instance, msg2);
+}
+
+ret_code_t bh1745_sw_reset(bh1745_instance_t * p_instance)
+{
+ ASSERT(p_instance != NULL);
+
+ static const uint8_t send_msg[] = {
+ BH1745_REG_SYSTEM_CONTROL,
+ BH1745_SW_RESET_MASK
+ };
+ return BH1745_SENSOR_WRITE(p_instance, send_msg);
+}
+
+ret_code_t bh1745_int_reset(bh1745_instance_t * p_instance)
+{
+ ASSERT(p_instance != NULL);
+
+ static const uint8_t send_msg[] = {
+ BH1745_REG_SYSTEM_CONTROL,
+ BH1745_INT_RESET_MASK
+ };
+ return BH1745_SENSOR_WRITE(p_instance, send_msg);
+}
+
+ret_code_t bh1745_meas_cfg(bh1745_instance_t * p_instance,
+ bh1745_meas_time_t meas_time,
+ bool enable,
+ bh1745_gain_t gain)
+{
+ ASSERT(p_instance != NULL);
+ if (meas_time > BH1745_MEAS_TIME_5120MS)
+ {
+ meas_time = BH1745_MEAS_TIME_5120MS;
+ }
+ if (gain > BH1745_GAIN_16X)
+ {
+ gain = BH1745_GAIN_16X;
+ }
+
+ uint8_t send_msg[] = {
+ BH1745_REG_MODE_CONTROL1,
+ 0,
+ 0,
+ 0x02
+ };
+ NRF_TWI_SENSOR_REG_SET(send_msg[1], BH1745_MEAS_TIME_MASK, BH1745_MEAS_TIME_POS, meas_time);
+ NRF_TWI_SENSOR_REG_SET(send_msg[2], BH1745_RGBC_EN_MASK, BH1745_RGBC_EN_POS, enable);
+ NRF_TWI_SENSOR_REG_SET(send_msg[2], BH1745_ADC_GAIN_MASK, BH1745_ADC_GAIN_POS, gain);
+
+ return BH1745_SENSOR_WRITE(p_instance, send_msg);
+}
+
+ret_code_t bh1745_data_read(bh1745_instance_t * p_instance,
+ bh1745_data_callback_t user_callback,
+ bh1745_data_t * p_data)
+{
+ ASSERT(p_instance != NULL);
+ ASSERT(p_data != NULL);
+ ret_code_t err_code;
+ err_code = nrf_twi_sensor_reg_read(p_instance->p_sensor_data,
+ p_instance->sensor_addr,
+ BH1745_REG_MODE_CONTROL2,
+ NULL,
+ &p_data->valid,
+ 1);
+ if (err_code != NRF_SUCCESS)
+ {
+ return err_code;
+ }
+ err_code = nrf_twi_sensor_reg_read(p_instance->p_sensor_data,
+ p_instance->sensor_addr,
+ BH1745_REG_RED_DATA_LSB,
+ (nrf_twi_sensor_reg_cb_t) user_callback,
+ (uint8_t *) &p_data->red,
+ BH1745_DATA_REG_NUM);
+ return err_code;
+}
+
+ret_code_t bh1745_int_cfg(bh1745_instance_t * p_instance,
+ bool latch,
+ bh1745_int_source_t source,
+ bool enable,
+ bh1745_persistence_t persistance)
+{
+ ASSERT(p_instance != NULL);
+
+ uint8_t int_reg = 0;
+ NRF_TWI_SENSOR_REG_SET(int_reg, BH1745_INT_ENABLE_MASK, BH1745_INT_ENABLE_POS, enable);
+ NRF_TWI_SENSOR_REG_SET(int_reg, BH1745_INT_SOURCE_MASK, BH1745_INT_SOURCE_POS, source);
+ NRF_TWI_SENSOR_REG_SET(int_reg, BH1745_INT_LATCH_MASK, BH1745_INT_LATCH_POS, latch);
+
+ uint8_t send_msg[] = {
+ BH1745_REG_INTERRUPT,
+ int_reg,
+ persistance
+ };
+
+ return BH1745_SENSOR_WRITE(p_instance, send_msg);
+}
+
+ret_code_t bh1745_high_thr_set(bh1745_instance_t * p_instance,
+ uint16_t threshold)
+{
+ ASSERT(p_instance != NULL);
+ uint8_t send_msg[] = {
+ BH1745_REG_TH_LSB,
+ LSB_16(threshold),
+ MSB_16(threshold)
+ };
+
+ return BH1745_SENSOR_WRITE(p_instance, send_msg);
+}
+
+ret_code_t bh1745_low_thr_set(bh1745_instance_t * p_instance,
+ uint16_t threshold)
+{
+ ASSERT(p_instance != NULL);
+ uint8_t send_msg[] = {
+ BH1745_REG_TL_LSB,
+ LSB_16(threshold),
+ MSB_16(threshold)
+ };
+
+ return BH1745_SENSOR_WRITE(p_instance, send_msg);
+}
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/drivers_ext/bh1745/bh1745.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/drivers_ext/bh1745/bh1745.h
new file mode 100644
index 0000000..2cc31b9
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/drivers_ext/bh1745/bh1745.h
@@ -0,0 +1,359 @@
+/**
+ * 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#ifndef BH1745_H
+#define BH1745_H
+
+#include "nrf_twi_sensor.h"
+#include "bh1745_internal.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @brief Possible sensor addresses.
+ */
+#define BH1745_BASE_ADDRESS_LOW 0x38U
+#define BH1745_BASE_ADDRESS_HIGH 0x39U
+
+// Minimum nrf_twi_sensor message buffer size and nrf_twi_mngr queue length.
+#define BH1745_MIN_QUEUE_SIZE 5
+
+/**
+ * @brief Sensor driver usage.
+ *
+ * Sensor instance has to be defined first in global context using @ref BH1745_INSTANCE DEF.
+ * After that it has to be initialized using @ref bh1745_init.
+ * At this point sensor instance is ready and all other functions can be used.
+ *
+ * Configuration functions schedule TWI operation using @ref nrf_twi_sensor module.
+ * After calling function, setting will be automatically send to sensor when TWI bus is free.
+ *
+ * There are designated functions to read status sensor registers e.g. @ref bh1745_sys_ctrl_read
+ * As parameters they receive function to be called after register is read, and pointer where
+ * register value should be stored. From that value specific parameters can be extracted
+ * using @ref NRF_TWI_SENSOR_REG_VAL_GET macro.
+ * Example:
+ * uint8_t part_id = NRF_TWI_SENSOR_REG_VAL_GET(sys_ctrl_reg,
+ * BH1745_PART_ID_MASK,
+ * BH1745_PART_ID_POS);
+ *
+ * Other functions are self-explanatory or have description on their usage.
+ */
+
+
+/**
+ * @brief Measurement time.
+ */
+typedef enum
+{
+ BH1745_MEAS_TIME_160MS,
+ BH1745_MEAS_TIME_320MS,
+ BH1745_MEAS_TIME_640MS,
+ BH1745_MEAS_TIME_1280MS,
+ BH1745_MEAS_TIME_2560MS,
+ BH1745_MEAS_TIME_5120MS
+} bh1745_meas_time_t;
+
+/**
+ * @brief RGBC (red, green, blue, clear) gain setting.
+ */
+typedef enum
+{
+ BH1745_GAIN_1X,
+ BH1745_GAIN_2X,
+ BH1745_GAIN_16X
+} bh1745_gain_t;
+
+/**
+ * @brief Persistence settings.
+ */
+typedef enum
+{
+ BH1745_TOGGLE_EACH_MEASURE,
+ BH1745_UPDATE_EACH_MEASURE,
+ BH1745_UPDATE_EVERY_FOURTH,
+ BH1745_UPDATE_EVERY_EIGHTH
+} bh1745_persistence_t;
+
+/**
+ * @brief Interrupt source settings.
+ */
+typedef enum
+{
+ BH1745_RED_CHANNEL,
+ BH1745_GREEN_CHANNEL,
+ BH1745_BLUE_CHANNEL,
+ BH1745_CLEAR_CHANNEL
+} bh1745_int_source_t;
+
+/**
+ * @brief Measurement result.
+ */
+typedef struct
+{
+ uint16_t red; //!< Raw red color value.
+ uint16_t green; //!< Raw green color value.
+ uint16_t blue; //!< Raw blue color value.
+ uint16_t clear; //!< Raw clear color pass value.
+ uint8_t valid; //!< Mode control 2 register value, used for checking data validity.
+} bh1745_data_t;
+
+/**
+ * @brief RGBC data callback prototype.
+ *
+ * @param result Result of operation (NRF_SUCCESS on success,
+ * otherwise a relevant error code).
+ * @param[in] p_user_data Pointer to color data structure.
+ */
+typedef void (* bh1745_data_callback_t)(ret_code_t result, bh1745_data_t * p_user_data);
+
+/**
+ * @brief Macro that creates sensor instance.
+ *
+ * @param[in] _bh1745_inst_name Sensor instance name.
+ * @param[in] _p_twi_sensor Pointer to common TWI sensor instance. @ref NRF_TWI_SENSOR_DEF
+ * @param[in] _sensor_address Sensor base address.
+ */
+#define BH1745_INSTANCE_DEF(_bh1745_inst_name, _p_twi_sensor, _sensor_address) \
+ BH1745_INTERNAL_INSTANCE_DEF(_bh1745_inst_name, _p_twi_sensor, _sensor_address)
+
+/**
+ * @brief Function for initializing the BH1745 sensor instance.
+ *
+ * TWI manager queue length has to be at least BH1745_MIN_QUEUE_SIZE.
+ *
+ * @param[in] p_instance Pointer to the sensor instance.
+ *
+ * @return Return error code from nrf_twi_sensor @ref nrf_twi_sensor_write
+ */
+ret_code_t bh1745_init(bh1745_instance_t * p_instance);
+
+/**
+ * @brief Function for resetting the BH1745 registers.
+ *
+ * @param[in] p_instance Pointer to the sensor instance.
+ *
+ * @return Return error code from nrf_twi_sensor @ref nrf_twi_sensor_write
+ */
+ret_code_t bh1745_sw_reset(bh1745_instance_t * p_instance);
+
+/**
+ * @brief Function for resetting the interrupt.
+ *
+ * @param[in] p_instance Pointer to the sensor instance.
+ *
+ * @return Return error code from nrf_twi_sensor @ref nrf_twi_sensor_write
+ */
+ret_code_t bh1745_int_reset(bh1745_instance_t * p_instance);
+
+/**
+ * @brief Function for setting measurement configuration.
+ *
+ * @param[in] p_instance Pointer to the sensor instance.
+ * @param[in] meas_time Measurement time.
+ * @param[in] enable Enable RGBC measurements.
+ * @param[in] gain Measurement gain.
+ *
+ * @return Return error code from nrf_twi_sensor @ref nrf_twi_sensor_write
+ */
+ret_code_t bh1745_meas_cfg(bh1745_instance_t * p_instance,
+ bh1745_meas_time_t meas_time,
+ bool enable,
+ bh1745_gain_t gain);
+
+/**
+ * @brief Function for setting interrupt configuration.
+ *
+ * @param p_instance Pointer to sensor instance.
+ * @param latch INT pin latch.
+ * @arg false INT pin is latched until INTERRUPT register is read or initialized.
+ * @arg true INT pin is updated after each measurement.
+ * @param source Interrupt source.
+ * @param enable Enable INT pin.
+ * @param persistence Set persistence.
+ *
+ * @return Return error code from nrf_twi_sensor @ref nrf_twi_sensor_write
+ */
+ret_code_t bh1745_int_cfg(bh1745_instance_t * p_instance,
+ bool latch,
+ bh1745_int_source_t source,
+ bool enable,
+ bh1745_persistence_t persistance);
+
+/**
+ * @brief Function for setting high interrupt threshold.
+ *
+ * @param[in] p_instance Pointer to sensor instance.
+ * @param[in] threshold Threshold value.
+ *
+ * @return Return error code from nrf_twi_sensor @ref nrf_twi_sensor_write
+ */
+ret_code_t bh1745_high_thr_set(bh1745_instance_t * p_instance,
+ uint16_t threshold);
+
+/**
+ * @brief Function for setting low interrupt threshold.
+ *
+ * @param[in] p_instance Pointer to sensor instance.
+ * @param[in] threshold Threshold value.
+ *
+ * @return Return error code from nrf_twi_sensor @ref nrf_twi_sensor_write
+ */
+ret_code_t bh1745_low_thr_set(bh1745_instance_t * p_instance,
+ uint16_t threshold);
+
+/**
+ * @brief Function for getting the BH1745 data.
+ *
+ * @param[in] p_instance Pointer to the sensor instance.
+ * @param[in] user_callback Callback function created by user.
+ * @param[out] p_data The measurement results.
+ *
+ * @return Return error code from nrf_twi_sensor @ref nrf_twi_sensor_reg_read
+ */
+ret_code_t bh1745_data_read(bh1745_instance_t * p_instance,
+ bh1745_data_callback_t user_callback,
+ bh1745_data_t * p_data);
+
+/**
+ * @brief Function for reading system control register.
+ *
+ * @param[in] p_instance Pointer to sensor instance.
+ * @param[in] user_cb Function to be called after register is read.
+ * @param[out] reg_val Register value, single uint8_t.
+ *
+ * @return Return error code from nrf_twi_sensor @ref nrf_twi_sensor_reg_read
+ */
+__STATIC_INLINE ret_code_t bh1745_sys_ctrl_read(bh1745_instance_t * p_instance,
+ nrf_twi_sensor_reg_cb_t user_cb,
+ uint8_t * reg_val);
+
+/**
+ * @brief Function for reading interrupt register.
+ *
+ * @param[in] p_instance Pointer to sensor instance.
+ * @param[in] user_cb Function to be called after register is read.
+ * @param[out] reg_val Register value, single uint8_t.
+ *
+ * @return Return error code from nrf_twi_sensor @ref nrf_twi_sensor_reg_read
+ */
+__STATIC_INLINE ret_code_t bh1745_interrupt_read(bh1745_instance_t * p_instance,
+ nrf_twi_sensor_reg_cb_t user_cb,
+ uint8_t * reg_val);
+
+/**
+ * @brief Function for reading manufacturer id register.
+ *
+ * @param[in] p_instance Pointer to sensor instance.
+ * @param[in] user_cb Function to be called after register is read.
+ * @param[out] reg_val Register value, single uint8_t.
+ *
+ * @return Return error code from nrf_twi_sensor @ref nrf_twi_sensor_reg_read
+ */
+__STATIC_INLINE ret_code_t bh1745_manu_id_read(bh1745_instance_t * p_instance,
+ nrf_twi_sensor_reg_cb_t user_cb,
+ uint8_t * reg_val);
+
+/**
+ * @brief Function for checking if RGBC data has been updated after last configuration change.
+ *
+ * This function should be used in data callback.
+ *
+ * @param[in] p_instance Pointer to the sensor instance.
+ *
+ * @return True if data is valid.
+ */
+__STATIC_INLINE bool bh1745_is_data_valid(bh1745_data_t * p_data);
+
+#ifndef SUPPRESS_INLINE_IMPLEMENTATION
+
+__STATIC_INLINE ret_code_t bh1745_sys_ctrl_read(bh1745_instance_t * p_instance,
+ nrf_twi_sensor_reg_cb_t user_cb,
+ uint8_t * reg_val)
+{
+ ASSERT(p_instance != NULL);
+ return nrf_twi_sensor_reg_read(p_instance->p_sensor_data,
+ p_instance->sensor_addr,
+ BH1745_REG_SYSTEM_CONTROL,
+ user_cb,
+ reg_val,
+ 1);
+}
+
+__STATIC_INLINE ret_code_t bh1745_interrupt_read(bh1745_instance_t * p_instance,
+ nrf_twi_sensor_reg_cb_t user_cb,
+ uint8_t * reg_val)
+{
+ ASSERT(p_instance != NULL);
+ return nrf_twi_sensor_reg_read(p_instance->p_sensor_data,
+ p_instance->sensor_addr,
+ BH1745_REG_INTERRUPT,
+ user_cb,
+ reg_val,
+ 1);
+}
+
+__STATIC_INLINE ret_code_t bh1745_manu_id_read(bh1745_instance_t * p_instance,
+ nrf_twi_sensor_reg_cb_t user_cb,
+ uint8_t * reg_val)
+{
+ ASSERT(p_instance != NULL);
+ return nrf_twi_sensor_reg_read(p_instance->p_sensor_data,
+ p_instance->sensor_addr,
+ BH1745_REG_MANUFACTURER_ID,
+ user_cb,
+ reg_val,
+ 1);
+}
+
+__STATIC_INLINE bool bh1745_is_data_valid(bh1745_data_t * p_data)
+{
+ return NRF_TWI_SENSOR_REG_VAL_GET(p_data->valid,
+ BH1745_VALID_MASK,
+ BH1745_VALID_POS);
+}
+
+#endif //SUPPRESS_INLINE_IMPLEMENTATION
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // BH1745_H
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/drivers_ext/bh1745/bh1745_internal.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/drivers_ext/bh1745/bh1745_internal.h
new file mode 100644
index 0000000..76b38da
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/drivers_ext/bh1745/bh1745_internal.h
@@ -0,0 +1,180 @@
+/**
+ * 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#ifndef BH1745_INTERNAL_H
+#define BH1745_INTERNAL_H
+
+#include "nrf_twi_sensor.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @brief Possible sensor addresses.
+ */
+#define BH1745_BASE_ADDRESS_LOW 0x38U
+#define BH1745_BASE_ADDRESS_HIGH 0x39U
+
+#define BH1745_MIN_QUEUE_SIZE 5
+
+/**
+ * @brief Sensor registers.
+ */
+#define BH1745_REG_SYSTEM_CONTROL 0x40
+#define BH1745_REG_MODE_CONTROL1 0x41
+#define BH1745_REG_MODE_CONTROL2 0x42
+#define BH1745_REG_RED_DATA_LSB 0x50
+#define BH1745_REG_DINT_DATA_LSB 0x58
+#define BH1745_REG_INTERRUPT 0x60
+#define BH1745_REG_PERSISTENCE 0x61
+#define BH1745_REG_TH_LSB 0x62
+#define BH1745_REG_TL_LSB 0x64
+#define BH1745_REG_MANUFACTURER_ID 0x92
+
+#define BH1745_DATA_REG_NUM 8
+
+#define BH1745_MANU_ID 0xE0
+#define BH1745_PART_ID 0x0B
+
+
+/**
+ * @brief System Control register bitmasks.
+ */
+
+// Default value for system control register.
+#define BH1745_DEF_SYSTEM_CONTROL 0x0B
+
+// Bitmasks for sw reset.
+#define BH1745_SW_RESET_POS 7
+#define BH1745_SW_RESET_MASK (1 << BH1745_SW_RESET_POS)
+
+// Bitmasks for int reset.
+#define BH1745_INT_RESET_POS 6
+#define BH1745_INT_RESET_MASK (1 << BH1745_INT_RESET_POS)
+
+// Bitmasks for part id.
+#define BH1745_PART_ID_POS 0
+#define BH1745_PART_ID_MASK (0x3F << BH1745_PART_ID_POS)
+
+
+/**
+ * @brief Mode Control 1 register bitmasks.
+ */
+
+// Bitmasks for meas time.
+#define BH1745_MEAS_TIME_POS 0
+#define BH1745_MEAS_TIME_MASK (0x07 << BH1745_MEAS_TIME_POS)
+
+
+/**
+ * @brief Mode Control 2 register bitmasks.
+ */
+
+// Bitmasks for valid.
+#define BH1745_VALID_POS 7
+#define BH1745_VALID_MASK (1 << BH1745_VALID_POS)
+
+// Bitmasks for rgbc en.
+#define BH1745_RGBC_EN_POS 4
+#define BH1745_RGBC_EN_MASK (1 << BH1745_RGBC_EN_POS)
+
+// Bitmasks for adc gain.
+#define BH1745_ADC_GAIN_POS 0
+#define BH1745_ADC_GAIN_MASK (3 << BH1745_ADC_GAIN_POS)
+
+
+/**
+ * @brief Interrupt register bitmasks.
+ */
+
+// Bitmasks for int status.
+#define BH1745_INT_STATUS_POS 7
+#define BH1745_INT_STATUS_MASK (1 << BH1745_INT_STATUS_POS)
+
+// Bitmasks for int latch.
+#define BH1745_INT_LATCH_POS 4
+#define BH1745_INT_LATCH_MASK (1 << BH1745_INT_LATCH_POS)
+
+// Bitmasks for int source.
+#define BH1745_INT_SOURCE_POS 2
+#define BH1745_INT_SOURCE_MASK (3 << BH1745_INT_SOURCE_POS)
+
+// Bitmasks for int enable.
+#define BH1745_INT_ENABLE_POS 0
+#define BH1745_INT_ENABLE_MASK (1 << BH1745_INT_ENABLE_POS)
+
+
+/**
+ * @brief Persistence register bitmasks.
+ */
+
+// Default value for persistence register.
+#define BH1745_DEF_PERSISTENCE 0x01
+
+// Bitmasks for persistence.
+#define BH1745_PERSISTENCE_POS 0
+#define BH1745_PERSISTENCE_MASK (3 << BH1745_PERSISTENCE_POS)
+
+// Default value for high threshold registers.
+#define BH1745_DEF_TH 0xFFFF
+
+
+/**
+ * @brief Sensor instance information.
+ */
+typedef struct
+{
+ nrf_twi_sensor_t * const p_sensor_data;
+ uint8_t const sensor_addr;
+} bh1745_instance_t;
+
+
+#define BH1745_INTERNAL_INSTANCE_DEF(_bh1745_inst_name, _p_twi_sensor, _sensor_address) \
+ static bh1745_instance_t _bh1745_inst_name = \
+ { \
+ .p_sensor_data = _p_twi_sensor, \
+ .sensor_addr = _sensor_address \
+ }
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // BH1745_INTERNAL_H
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/drivers_ext/ccs811/ccs811.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/drivers_ext/ccs811/ccs811.c
new file mode 100644
index 0000000..0c31977
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/drivers_ext/ccs811/ccs811.c
@@ -0,0 +1,225 @@
+/**
+ * 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#include "ccs811.h"
+
+#define SWAP_16(arg) ((arg) = (MSB_16(arg) | (LSB_16(arg) << 8)))
+
+ret_code_t ccs811_init(ccs811_instance_t const * p_instance)
+{
+ ASSERT(p_instance != NULL);
+ if (p_instance->p_sensor_data->p_twi_mngr->p_queue->size < CCS811_MIN_QUEUE_SIZE)
+ {
+ return NRF_ERROR_INVALID_LENGTH;
+ }
+ static uint8_t const send_msg[] = {
+ CCS811_REG_APP_START
+ };
+ ret_code_t err = nrf_twi_sensor_write(p_instance->p_sensor_data,
+ p_instance->sensor_addr,
+ send_msg,
+ ARRAY_SIZE(send_msg),
+ true);
+ err = ccs811_drive_mode_set(p_instance, CCS811_MODE_0, false, false);
+ if (err != NRF_SUCCESS)
+ {
+ return err;
+ }
+ err = ccs811_env_set(p_instance, CCS811_DEFAULT_TEMPERATURE, 0, CCS811_DEFAULT_HUMIDITY, 0);
+ if (err != NRF_SUCCESS)
+ {
+ return err;
+ }
+ return ccs811_thr_cfg(p_instance,
+ CCS811_DEFAULT_LOW_THR,
+ CCS811_DEFAULT_HIGH_THR,
+ CCS811_DEFAULT_HYSTERESIS);
+}
+
+ret_code_t ccs811_drive_mode_set(ccs811_instance_t const * p_instance,
+ ccs811_drive_mode_t mode,
+ bool drdy_en,
+ bool thr_en)
+{
+ ASSERT(p_instance != NULL);
+ uint8_t reg = 0;
+ NRF_TWI_SENSOR_REG_SET(reg, CCS811_DRIVE_MODE_MASK, CCS811_DRIVE_MODE_POS, mode);
+ NRF_TWI_SENSOR_REG_SET(reg, CCS811_DATA_READY_MASK, CCS811_DATA_READY_POS, drdy_en);
+ NRF_TWI_SENSOR_REG_SET(reg, CCS811_THRESH_MASK, CCS811_THRESH_POS, thr_en);
+
+ uint8_t send_msg[] = {
+ CCS811_REG_MEAS_MODE,
+ reg
+ };
+
+ return nrf_twi_sensor_write(p_instance->p_sensor_data,
+ p_instance->sensor_addr,
+ send_msg,
+ ARRAY_SIZE(send_msg),
+ true);
+}
+
+ret_code_t ccs811_alg_data_read(ccs811_instance_t const * p_instance,
+ ccs811_data_callback_t user_cb,
+ ccs811_alg_data_t * p_alg_data,
+ ccs811_last_data_byte_t last)
+{
+ ASSERT(p_instance != NULL);
+ ASSERT(p_alg_data != NULL);
+
+ return nrf_twi_sensor_reg_read(p_instance->p_sensor_data,
+ p_instance->sensor_addr,
+ CCS811_REG_ALG_RESULT_DATA,
+ (nrf_twi_sensor_reg_cb_t) user_cb,
+ (uint8_t *) p_alg_data,
+ last);
+}
+
+void ccs811_alg_data_process(ccs811_alg_data_t * p_alg_data)
+{
+ ASSERT(p_alg_data != NULL);
+
+ SWAP_16(p_alg_data->eco2);
+ SWAP_16(p_alg_data->tvoc);
+ SWAP_16(p_alg_data->raw);
+}
+
+ret_code_t ccs811_env_set(ccs811_instance_t const * p_instance,
+ int8_t temp_value,
+ uint16_t temp_fraction,
+ uint8_t hum_percent,
+ uint16_t hum_fraction)
+{
+ ASSERT(p_instance != NULL);
+ temp_value += CCS811_TEMPERATURE_OFFSET;
+ if(temp_value < 0)
+ {
+ temp_value = 0;
+ }
+ uint16_t env_temp = ( *((uint16_t *) &temp_value) << CCS811_ENV_TEMP_VALUE_POS)
+ | (temp_fraction & CCS811_ENV_TEMP_FRACTION_MASK);
+ uint16_t env_hum = ( *((uint16_t *) &hum_percent) << CCS811_ENV_HUM_PERCENT_POS)
+ | (hum_fraction & CCS811_ENV_HUM_FRACTION_MASK);
+
+ uint8_t send_msg[] = {
+ CCS811_REG_ENV_DATA,
+ MSB_16(env_temp),
+ LSB_16(env_temp),
+ MSB_16(env_hum),
+ LSB_16(env_hum)
+ };
+
+ return nrf_twi_sensor_write(p_instance->p_sensor_data,
+ p_instance->sensor_addr,
+ send_msg,
+ ARRAY_SIZE(send_msg),
+ true);
+}
+
+ret_code_t ccs811_thr_cfg(ccs811_instance_t const * p_instance,
+ uint16_t l_to_m,
+ uint16_t m_to_h,
+ uint8_t hysteresis)
+{
+ ASSERT(p_instance != NULL);
+ uint8_t send_msg[] = {
+ CCS811_REG_THRESHOLDS,
+ MSB_16(l_to_m),
+ LSB_16(l_to_m),
+ MSB_16(m_to_h),
+ LSB_16(m_to_h),
+ hysteresis
+ };
+
+ return nrf_twi_sensor_write(p_instance->p_sensor_data,
+ p_instance->sensor_addr,
+ send_msg,
+ ARRAY_SIZE(send_msg),
+ true);
+}
+
+ret_code_t ccs811_baseline_read(ccs811_instance_t const * p_instance,
+ nrf_twi_sensor_reg_cb_t user_cb,
+ uint16_t * p_baseline)
+{
+ ASSERT(p_instance != NULL);
+ ASSERT(p_baseline != NULL);
+ return nrf_twi_sensor_reg_read(p_instance->p_sensor_data,
+ p_instance->sensor_addr,
+ CCS811_REG_BASELINE,
+ user_cb,
+ (uint8_t *) p_baseline,
+ 2);
+}
+
+ret_code_t ccs811_baseline_set(ccs811_instance_t const * p_instance, uint16_t baseline)
+{
+ ASSERT(p_instance != NULL);
+ uint8_t * p_base = (uint8_t *) &baseline;
+ uint8_t send_msg[] = {
+ CCS811_REG_BASELINE,
+ p_base[0],
+ p_base[1]
+ };
+
+ return nrf_twi_sensor_write(p_instance->p_sensor_data,
+ p_instance->sensor_addr,
+ send_msg,
+ ARRAY_SIZE(send_msg),
+ true);
+}
+
+ret_code_t ccs811_sw_reset(ccs811_instance_t const * p_instance)
+{
+ ASSERT(p_instance != NULL);
+ static uint8_t const send_msg[] = {
+ CCS811_REG_SW_RESET,
+ CCS811_SW_RESET_BYTE0,
+ CCS811_SW_RESET_BYTE1,
+ CCS811_SW_RESET_BYTE2,
+ CCS811_SW_RESET_BYTE3
+ };
+
+ return nrf_twi_sensor_write(p_instance->p_sensor_data,
+ p_instance->sensor_addr,
+ send_msg,
+ ARRAY_SIZE(send_msg),
+ true);
+}
+
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/drivers_ext/ccs811/ccs811.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/drivers_ext/ccs811/ccs811.h
new file mode 100644
index 0000000..6b7b336
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/drivers_ext/ccs811/ccs811.h
@@ -0,0 +1,297 @@
+/**
+ * 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#ifndef CCS811_H
+#define CCS811_H
+
+#include "nrf_twi_sensor.h"
+#include "ccs811_internal.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @brief Possible sensor addresses.
+ */
+#define CCS811_BASE_ADDRESS_LOW 0x5AU
+#define CCS811_BASE_ADDRESS_HIGH 0x5BU
+
+// Minimum nrf_twi_sensor message buffer size and nrf_twi_mngr queue length.
+#define CCS811_MIN_QUEUE_SIZE 6
+
+// Hardware ID register value
+#define CCS811_HARDWARE_ID 0x81
+
+/**
+ * @brief Sensor driver usage.
+ *
+ * Sensor instance has to be defined first in global context using @ref CCS811_INSTANCE_DEF.
+ * After that it has to be initialized using @ref ccs811_init.
+ * At this point sensor instance is ready and all other functions can be used.
+ *
+ * Configuration functions schedule TWI operation using @ref nrf_twi_sensor module.
+ * After calling function, setting will be automatically send to sensor when TWI bus is free.
+ *
+ * There are designated functions to read status sensor registers e.g. @ref ccs811_status_read
+ * As parameters they receive function to be called after register is read, and pointer where
+ * register value should be stored. From that value specific parameters can be extracted
+ * using @ref NRF_TWI_SENSOR_REG_VAL_GET macro.
+ * Example:
+ * bool drdy = NRF_TWI_SENSOR_REG_VAL_GET(status, CCS811_DATA_READY_MASK, CCS811_DATA_READY_POS);
+ *
+ * Other functions are self-explanatory or have description on their usage.
+ */
+
+/**
+ * @brief Drive mode setting.
+ */
+typedef enum
+{
+ CCS811_MODE_0,//!< CCS811_MODE_0 - Idle
+ CCS811_MODE_1,//!< CCS811_MODE_1 - Constant power, measure every second.
+ CCS811_MODE_2,//!< CCS811_MODE_2 - Pulse heating mode, measure every 10 seconds.
+ CCS811_MODE_3,//!< CCS811_MODE_3 - Low power pulse heating mode, measure every 60 seconds.
+ CCS811_MODE_4 //!< CCS811_MODE_4 - Constant power, measure every 250ms, only raw data.
+} ccs811_drive_mode_t;
+
+/**
+ * @brief Last byte read from algorithm data.
+ *
+ * Used with @ref ccs811_alg_data_read function, defines to which byte data should be read.
+ */
+typedef enum
+{
+ CCS811_LAST_ECO2 = 2,
+ CCS811_LAST_TVOC = 4,
+ CCS811_LAST_STATUS,
+ CCS811_LAST_ERROR_ID,
+ CCS811_LAST_RAW = 8
+} ccs811_last_data_byte_t;
+
+/**
+ * @brief Structure for holding algorithm data.
+ */
+typedef struct
+{
+ uint16_t eco2; //!< eC02 value in ppm.
+ uint16_t tvoc; //!< TVOC value in ppb.
+ uint8_t status; //!< Status register data.
+ uint8_t error_id; //!< Error register data.
+ uint16_t raw; //!< Raw data.
+} ccs811_alg_data_t;
+
+/**
+ * @brief Data callback prototype.
+ *
+ * @param[in] result Return code from TWI manager and underlying drivers.
+ * @param[in] p_data Pointer to sensor data.
+ */
+typedef void (* ccs811_data_callback_t)(ret_code_t result, ccs811_alg_data_t * p_data);
+
+/**
+ * @brief Macro that creates sensor instance.
+ *
+ * @param[in] _ccs811_inst_name Sensor instance name.
+ * @param[in] _p_twi_sensor Pointer to common TWI sensor instance.
+ * @param[in] _sensor_address Sensor base address.
+ */
+#define CCS811_INSTANCE_DEF(_ccs811_inst_name, _p_twi_sensor, _sensor_address) \
+ CCS811_INTERNAL_INSTANCE_DEF(_ccs811_inst_name, _p_twi_sensor, _sensor_address)
+
+/**
+ * @brief Function initializing ccs811 sensor
+ *
+ * TWI manager queue length has to be at least CCS811_MIN_QUEUE_SIZE
+ *
+ * @param[in] p_instance Pointer to sensor instance created by macro
+ *
+ * @return Return error code from nrf_twi_sensor @ref nrf_twi_sensor_write
+ */
+ret_code_t ccs811_init(ccs811_instance_t const * p_instance);
+
+/**
+ * @brief Function for setting drive mode.
+ *
+ * @param[in] p_instance Pointer to sensor instance.
+ * @param[in] mode Drive mode.
+ * @param[in] drdy_en Enable data ready pin.
+ * @param[in] thr_en Enable threshold.
+ *
+ * @return Return error code from nrf_twi_sensor @ref nrf_twi_sensor_write
+ */
+ret_code_t ccs811_drive_mode_set(ccs811_instance_t const * p_instance,
+ ccs811_drive_mode_t mode,
+ bool drdy_en,
+ bool thr_en);
+
+/**
+ * @brief Function for reading sensor data.
+ *
+ * @param[in] p_instance Pointer to sensor instance.
+ * @param[in] user_cb Function to be called after data read.
+ * @param[out] p_alg_data Pointer to structure holding sensor algorithm data.
+ * @param[in] last Last byte to read.
+ *
+ * @return Return error code from nrf_twi_sensor @ref nrf_twi_sensor_reg_read
+ */
+ret_code_t ccs811_alg_data_read(ccs811_instance_t const * p_instance,
+ ccs811_data_callback_t user_cb,
+ ccs811_alg_data_t * p_alg_data,
+ ccs811_last_data_byte_t last);
+
+/**
+ * @brief Function for processing algorithm data
+ *
+ * @param[in/out] p_alg_data Pointer to read data to be processed.
+ */
+void ccs811_alg_data_process(ccs811_alg_data_t * p_alg_data);
+
+/**
+ * @brief Function for setting environment temperature.
+ *
+ * @param[in] p_instance Pointer to sensor instance.
+ * @param[in] temp_value Temperature value (-25 to 100 degree celsius).
+ * @param[in] temp_fraction Temperature fraction.
+ * @param[in] hum_percent Humidity percent.
+ * @param[in] hum_fraction Humidity fraction.
+ *
+ * @return Return error code from nrf_twi_sensor @ref nrf_twi_sensor_write
+ */
+ret_code_t ccs811_env_set(ccs811_instance_t const * p_instance,
+ int8_t temp_value,
+ uint16_t temp_fraction,
+ uint8_t hum_percent,
+ uint16_t hum_fraction);
+
+/**
+ * @brief Function for threshold configuration
+ *
+ * @param[in] p_instance Pointer to sensor instance.
+ * @param[in] l_to_m Low to medium threshold.
+ * @param[in] m_to_h Medium to high threshold.
+ * @param[in] hysteresis Hysteresis.
+ *
+ * @return Return error code from nrf_twi_sensor @ref nrf_twi_sensor_write
+ */
+ret_code_t ccs811_thr_cfg(ccs811_instance_t const * p_instance,
+ uint16_t l_to_m,
+ uint16_t m_to_h,
+ uint8_t hysteresis);
+
+/**
+ * @brief Function for reading baseline.
+ *
+ * @param[in] p_instance Pointer to sensor instance.
+ * @param[in] user_cb Function to be called after baseline read.
+ * @param[out] baseline Baseline value, single uint16_t.
+ *
+ * @return Return error code from nrf_twi_sensor @ref nrf_twi_sensor_reg_read
+ */
+ret_code_t ccs811_baseline_read(ccs811_instance_t const * p_instance,
+ nrf_twi_sensor_reg_cb_t user_cb,
+ uint16_t * p_baseline);
+
+/**
+ * @brief Function for setting baseline.
+ *
+ * @param[in] p_instance Pointer to sensor instance.
+ * @param[in] baseline Baseline value.
+ *
+ * @return Return error code from nrf_twi_sensor @ref nrf_twi_sensor_write
+ */
+ret_code_t ccs811_baseline_set(ccs811_instance_t const * p_instance,
+ uint16_t baseline);
+
+/**
+ * @brief Function commencing software reset.
+ *
+ * @param[in] p_instance Pointer to sensor instance.
+ *
+ * @note To use sensor after reset, it has to be initialized again using @ref ccs811_init function.
+ *
+ * @return Return error code from nrf_twi_sensor @ref nrf_twi_sensor_write
+ */
+ret_code_t ccs811_sw_reset(ccs811_instance_t const * p_instance);
+
+
+/**
+ * @brief Function for reading status register.
+ *
+ * @param[in] p_instance Pointer to sensor instance.
+ * @param[in] user_cb Function to be called after register is read.
+ * @param[out] p_reg_val Pointer to register value, single uint8_t.
+ *
+ * @return Return error code from nrf_twi_sensor @ref nrf_twi_sensor_reg_read
+ */
+__STATIC_INLINE ret_code_t ccs811_status_read(ccs811_instance_t const * p_instance,
+ nrf_twi_sensor_reg_cb_t user_cb,
+ uint8_t * p_reg_val);
+
+/**
+ * @brief Function for reading hardware id register.
+ *
+ * @param[in] p_instance Pointer to sensor instance.
+ * @param[in] user_cb Function to be called after register is read.
+ * @param[out] p_reg_val Pointer to register value, single uint8_t.
+ *
+ * @return Return error code from nrf_twi_sensor @ref nrf_twi_sensor_reg_read
+ */
+__STATIC_INLINE ret_code_t ccs811_hw_id_read(ccs811_instance_t const * p_instance,
+ nrf_twi_sensor_reg_cb_t user_cb,
+ uint8_t * p_reg_val);
+
+/**
+ * @brief Function for reading error id register.
+ *
+ * @param[in] p_instance Pointer to sensor instance.
+ * @param[in] user_cb Function to be called after register is read.
+ * @param[out] p_reg_val Pointer to register value, single uint8_t.
+ *
+ * @return Return error code from nrf_twi_sensor @ref nrf_twi_sensor_reg_read
+ */
+__STATIC_INLINE ret_code_t ccs811_error_read(ccs811_instance_t const * p_instance,
+ nrf_twi_sensor_reg_cb_t user_cb,
+ uint8_t * p_reg_val);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // CCS811_H
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/drivers_ext/ccs811/ccs811_internal.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/drivers_ext/ccs811/ccs811_internal.h
new file mode 100644
index 0000000..423e61d
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/drivers_ext/ccs811/ccs811_internal.h
@@ -0,0 +1,259 @@
+/**
+ * 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#ifndef CCS811_INTERNAL_H
+#define CCS811_INTERNAL_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @brief CCS811 sensor registers.
+ */
+#define CCS811_REG_STATUS 0x00
+#define CCS811_REG_MEAS_MODE 0x01
+#define CCS811_REG_ALG_RESULT_DATA 0x02
+#define CCS811_REG_RAW_DATA 0x03
+#define CCS811_REG_ENV_DATA 0x05
+#define CCS811_REG_NTC 0x06
+#define CCS811_REG_THRESHOLDS 0x10
+#define CCS811_REG_BASELINE 0x11
+#define CCS811_REG_HW_ID 0x20
+#define CCS811_REG_HW_VER 0x21
+#define CCS811_REG_FW_BOOT_VER 0x23
+#define CCS811_REG_FW_APP_VER 0x24
+#define CCS811_REG_ERROR_ID 0xE0
+#define CCS811_REG_SW_RESET 0xFF
+#define CCS811_REG_APP_START 0xF4
+
+/**
+ * @brief CCS811 Default configuration values.
+ */
+#define CCS811_DEFAULT_HUMIDITY 50
+#define CCS811_DEFAULT_TEMPERATURE 25
+#define CCS811_DEFAULT_LOW_THR 1500
+#define CCS811_DEFAULT_HIGH_THR 2500
+#define CCS811_DEFAULT_HYSTERESIS 50
+
+/**
+ * @brief CCS811 Environment temperature offset.
+ */
+#define CCS811_TEMPERATURE_OFFSET 25
+
+/**
+ * @brief Status register bitmasks.
+ */
+
+// Bitmasks for FW_MODE.
+#define CCS811_FW_MODE_POS 7
+#define CCS811_FW_MODE_MASK (1 << CCS811_FW_MODE_POS)
+
+// Bitmasks for APP_VALID.
+#define CCS811_APP_VALID_POS 4
+#define CCS811_APP_VALID_MASK (1 << CCS811_APP_VALID_POS)
+
+// Bitmasks for DATA_READY.
+#define CCS811_DATA_READY_POS 3
+#define CCS811_DATA_READY_MASK (1 << CCS811_DATA_READY_POS)
+
+// Bitmasks for ERROR.
+#define CCS811_ERROR_POS 0
+#define CCS811_ERROR_MASK (1 << CCS811_ERROR_POS)
+
+
+/**
+ * @brief Meas mode register bitmasks.
+ */
+
+// Register validity mask.
+#define CCS811_MEAS_MODE_VALID_MASK 0x83U
+
+// Bitmasks for DRIVE_MODE.
+#define CCS811_DRIVE_MODE_POS 4
+#define CCS811_DRIVE_MODE_MASK (7 << CCS811_DRIVE_MODE_POS)
+
+// Bitmasks for INTERRUPT.
+#define CCS811_INTERRUPT_POS 3
+#define CCS811_INTERRUPT_MASK (1 << CCS811_INTERRUPT_MASK)
+
+// Bitmasks for THRESH.
+#define CCS811_THRESH_POS 2
+#define CCS811_THRESH_MASK (1 << CCS811_THRESH_POS)
+
+/**
+ * @brief Algorithm results data bytes.
+ */
+
+#define CCS811_ALG_RESULT_BYTE_NUM 8
+#define CCS811_ALG_ECO2_H_BYTE 0
+#define CCS811_ALG_ECO2_L_BYTE 1
+#define CCS811_ALG_TVOC_H_BYTE 2
+#define CCS811_ALG_TVOC_L_BYTE 3
+#define CCS811_ALG_STATUS_BYTE 4
+#define CCS811_ALG_ERROR_BYTE 5
+#define CCS811_ALG_RAW_DATA1_BYTE 6
+#define CCS811_ALG_RAW_DATA2_BYTE 7
+
+/**
+ * @brief Environment data register.
+ */
+
+#define CCS811_ENV_HUMIDITY_H_BYTE 0
+
+// Humidity percent position.
+#define CCS811_ENV_HUM_PERCENT_POS 9
+
+// Bitmasks for humidity fraction.
+#define CCS811_ENV_HUM_FRACTION_MASK (0x01FF)
+
+
+// Temperature value position.
+#define CCS811_ENV_TEMP_VALUE_POS 9
+
+// Bitmasks for temperature fraction.
+#define CCS811_ENV_TEMP_FRACTION_MASK (0x01FF)
+
+
+/**
+ * @brief Error register.
+ */
+
+// Bitmasks for HEATER_SUPPLY
+#define CCS811_ERROR_HEATER_SUPPLY_POS 5
+#define CCS811_ERROR_HEATER_SUPPLY_MASK (1 << CCS811_ERROR_HEATER_SUPPLY_POS)
+
+// Bitmasks for HEATER_FAULT
+#define CCS811_ERROR_HEATER_FAULT_POS 4
+#define CCS811_ERROR_HEATER_FAULT_MASK (1 << CCS811_ERROR_HEATER_FAULT_POS)
+
+// Bitmasks for MAX_RESISTANCE
+#define CCS811_ERROR_MAX_RESISTANCE_POS 3
+#define CCS811_ERROR_MAX_RESISTANCE_MASK (1 << CCS811_ERROR_MAX_RESISTANCE_POS)
+
+// Bitmasks for MEASMODE_INVALID
+#define CCS811_ERROR_MEAS_MODE_POS 2
+#define CCS811_ERROR_MEAS_MODE_MASK (1 CCS811_ERROR_MEAS_MODE_POS)
+
+// Bitmasks for READ_REG
+#define CCS811_ERROR_READ_REG_POS 1
+#define CCS811_ERROR_READ_REG_MASK (1 << CCS811_ERROR_READ_REG_POS)
+
+// Bitmasks for WRITE_REG
+#define CCS811_ERROR_WRITE_REG_POS 0
+#define CCS811_ERROR_WRITE_REG_MASK (1 << CCS811_ERROR_WRITE_REG_POS)
+
+/**
+ * @brief Software reset register.
+ */
+#define CCS811_SW_RESET_BYTE0 0x11
+#define CCS811_SW_RESET_BYTE1 0xE5
+#define CCS811_SW_RESET_BYTE2 0x72
+#define CCS811_SW_RESET_BYTE3 0x8A
+
+/**
+ * @brief Structure holding sensor instance
+ */
+typedef struct
+{
+ nrf_twi_sensor_t * const p_sensor_data;
+ uint8_t const sensor_addr;
+} ccs811_instance_t;
+
+/**
+ * @brief Macro that creates sensor instance.
+ */
+#define CCS811_INTERNAL_INSTANCE_DEF(_ccs811_inst_name, _p_twi_sensor, _sensor_address) \
+ static ccs811_instance_t _ccs811_inst_name = \
+ { \
+ .p_sensor_data = _p_twi_sensor, \
+ .sensor_addr = _sensor_address, \
+ }
+
+#ifndef SUPPRESS_INLINE_IMPLEMENTATION
+
+__STATIC_INLINE ret_code_t ccs811_status_read(ccs811_instance_t const * p_instance,
+ nrf_twi_sensor_reg_cb_t user_cb,
+ uint8_t * p_reg_val)
+{
+ ASSERT(p_instance != NULL);
+ ASSERT(p_reg_val != NULL);
+ return nrf_twi_sensor_reg_read(p_instance->p_sensor_data,
+ p_instance->sensor_addr,
+ CCS811_REG_STATUS,
+ user_cb,
+ p_reg_val,
+ 1);
+}
+
+__STATIC_INLINE ret_code_t ccs811_hw_id_read(ccs811_instance_t const * p_instance,
+ nrf_twi_sensor_reg_cb_t user_cb,
+ uint8_t * p_reg_val)
+{
+ ASSERT(p_instance != NULL);
+ ASSERT(p_reg_val != NULL);
+ return nrf_twi_sensor_reg_read(p_instance->p_sensor_data,
+ p_instance->sensor_addr,
+ CCS811_REG_HW_ID,
+ user_cb,
+ p_reg_val,
+ 1);
+}
+
+__STATIC_INLINE ret_code_t ccs811_error_read(ccs811_instance_t const * p_instance,
+ nrf_twi_sensor_reg_cb_t user_cb,
+ uint8_t * p_reg_val)
+{
+ ASSERT(p_instance != NULL);
+ ASSERT(p_reg_val != NULL);
+ return nrf_twi_sensor_reg_read(p_instance->p_sensor_data,
+ p_instance->sensor_addr,
+ CCS811_REG_ERROR_ID,
+ user_cb,
+ p_reg_val,
+ 1);
+}
+
+#endif //SUPPRESS_INLINE_IMPLEMENTATION
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // CCS811_INTERNAL_H
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/drivers_ext/cherry8x16/cherry8x16.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/drivers_ext/cherry8x16/cherry8x16.c
new file mode 100644
index 0000000..ce087db
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/drivers_ext/cherry8x16/cherry8x16.c
@@ -0,0 +1,474 @@
+/**
+ * Copyright (c) 2009 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#include <stdint.h>
+#include <stdbool.h>
+
+#include "cherry8x16.h"
+#include "nrf.h"
+
+#define CHERRY8x16_NUM_OF_COLUMNS 16 // !< Number of columns in the keyboard matrix
+#define CHERRY8x16_NUM_OF_ROWS 8 // !< Number of rows in the keyboard matrix
+
+#define MODIFIER_HID_START 0xE0
+#define MODIFIER_HID_END 0xE7
+static uint8_t m_currently_pressed_keys[CHERRY8x16_MAX_NUM_OF_PRESSED_KEYS]; //!< Array holding currently pressed keys. Filled up from index 0. Values are
+static uint8_t m_transmitted_keys[CHERRY8x16_MAX_NUM_OF_PRESSED_KEYS]; //!< Array holding the keys that have already been transmitted.
+static uint8_t m_num_of_currently_pressed_keys; //!< Number of keys in m_currently_pressed_keys
+static uint8_t m_number_of_transmitted_keys; //!< Number of keys in m_transmitted_keys
+
+static uint8_t m_key_packet[KEY_PACKET_SIZE]; //!< Stores last created key packet. One byte is used for modifier keys, one for OEMs. Key values are USB HID keycodes.
+
+static const uint8_t volatile * m_row_port; //!< Pointer to location where row IO can be read
+static uint16_t volatile * m_column_port; //!< Pointer to location where column IO can be written
+static const uint8_t * matrix_lookup; //!< Pointer to the key lookup matrix in use
+
+/** Table containing the mapping between the key matrix and the HID Usage codes for each key. */
+static const uint8_t default_matrix_lookup[CHERRY8x16_NUM_OF_COLUMNS * CHERRY8x16_NUM_OF_ROWS] =
+{
+ 0xE7, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0xE3, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0xE0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0xE1, 0xE6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0xE2, 0xE5, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x29, 0x3E, 0x3D, 0x3C, 0x3B, 0x3A, 0x3F, 0x40,
+ 0x1E, 0x23, 0x22, 0x21, 0x20, 0x1F, 0x24, 0x25,
+ 0x4F, 0x43, 0x47, 0x53, 0x46, 0x48, 0x42, 0x41,
+ 0x51, 0x2D, 0x2E, 0x2A, 0x00, 0x4A, 0x27, 0x26,
+ 0x52, 0x13, 0x2F, 0x30, 0x00, 0x4B, 0x12, 0x0C,
+ 0x50, 0x33, 0x34, 0x32, 0x28, 0x4E, 0x0F, 0x0E,
+ 0x2C, 0x38, 0x4C, 0x49, 0x65, 0x4D, 0x37, 0x36,
+ 0x35, 0x05, 0x19, 0x06, 0x1B, 0x1D, 0x11, 0x10,
+ 0x39, 0x0A, 0x09, 0x07, 0x16, 0x04, 0x0B, 0x0D,
+ 0x2B, 0x17, 0x15, 0x08, 0x1A, 0x14, 0x1C, 0x18
+};
+
+static bool cherry8x16_have_keys_changed(const uint8_t * state_now,
+ uint8_t number_of_now_pressed_keys,
+ const uint8_t * state_before,
+ uint8_t number_of_before_pressed_keys);
+static bool cherry8x16_keymatrix_read(uint8_t * pressed_keys, uint8_t * number_of_pressed_keys);
+static void cherry8x16_keypacket_addkey(uint8_t key);
+static void cherry8x16_keypacket_create(uint8_t * key_packet, uint8_t key_packet_size);
+static void cherry8x16_remap_fn_keys(uint8_t * keys, uint8_t number_of_keys);
+static uint8_t cherry8x16_row_read(void);
+
+cherry8x16_status_t cherry8x16_init(const uint8_t volatile * row_port,
+ uint16_t * column_port,
+ const uint8_t * key_lookup_matrix)
+{
+ cherry8x16_status_t status = CHERRY8x16_OK;
+
+ if (row_port == 0 || column_port == 0)
+ {
+ status = CHERRY8x16_INVALID_PARAMETER;
+ }
+ else
+ {
+ m_row_port = row_port;
+ m_column_port = column_port;
+
+ *m_column_port = 0x0000;
+ if (*m_row_port != 0x00)
+ {
+ status = CHERRY8x16_NOT_DETECTED;
+ }
+ else
+ {
+ m_num_of_currently_pressed_keys = 0;
+ m_number_of_transmitted_keys = 0;
+
+ for (uint_fast8_t i = CHERRY8x16_MAX_NUM_OF_PRESSED_KEYS; i--;)
+ {
+ m_currently_pressed_keys[i] = 0;
+ m_transmitted_keys[i] = 0;
+ }
+ }
+
+ if (key_lookup_matrix == CHERRY8x16_DEFAULT_KEY_LOOKUP_MATRIX)
+ {
+ matrix_lookup = default_matrix_lookup;
+ }
+ else
+ {
+ matrix_lookup = key_lookup_matrix;
+ }
+ }
+
+ return status;
+}
+
+bool cherry8x16_new_packet(const uint8_t ** p_key_packet, uint8_t * p_key_packet_size)
+{
+ bool new_packet_prepared;
+
+ // Save currently pressed keys
+ for (uint_fast8_t i = CHERRY8x16_MAX_NUM_OF_PRESSED_KEYS; i--; )
+ {
+ m_transmitted_keys[i] = m_currently_pressed_keys[i];
+ }
+ m_number_of_transmitted_keys = m_num_of_currently_pressed_keys;
+
+ // Create a new packet if key states have changed and there are no keys blocking each other (ghosting/phantom keys)
+ if (cherry8x16_keymatrix_read(m_currently_pressed_keys, &m_num_of_currently_pressed_keys))
+ {
+ if (cherry8x16_have_keys_changed(m_currently_pressed_keys, m_num_of_currently_pressed_keys,
+ m_transmitted_keys, m_number_of_transmitted_keys))
+ {
+ cherry8x16_keypacket_create(&m_key_packet[0], KEY_PACKET_SIZE);
+ *p_key_packet = &m_key_packet[0];
+ *p_key_packet_size = KEY_PACKET_SIZE;
+ new_packet_prepared = true;
+ }
+ else
+ {
+ // The same keys are still pressed, no need to create a new packet
+ new_packet_prepared = false;
+ }
+ }
+ else
+ {
+ // Ghosting detected. Don't create a packet.
+ new_packet_prepared = false;
+ }
+
+ return new_packet_prepared;
+}
+
+
+/**
+ * @brief Function for reading and returning keyboard matrix row state.
+ *
+ * @return uint8_t Row state
+ */
+static uint8_t cherry8x16_row_read(void)
+{
+ return *m_row_port;
+}
+
+
+/**
+ * @brief Function for reading the keyboard matrix state and stores the pressed keys to an array.
+ *
+ * This function resolves keys from the matrix and finds their corresponding HID usage codes
+ * If there are any ghost key conditions the packet will be discarded
+ * @param pressed_keys Array holding pressed keys. Must be at least CHERRY8x16_MAX_NUM_OF_PRESSED_KEYS in size.
+ * @param number_of_pressed_keys Pointer to variable where number of pressed keys will be stored.
+ * @return
+ * @retval true If no keys were blocking each other.
+ * @retval false If some keys were blocking each other o rno key is pressed.
+ */
+static bool cherry8x16_keymatrix_read(uint8_t * pressed_keys, uint8_t * number_of_pressed_keys)
+{
+ uint_fast8_t row_state[CHERRY8x16_NUM_OF_COLUMNS];
+ uint_fast8_t blocking_mask = 0;
+
+ *number_of_pressed_keys = 0;
+
+ for (uint_fast8_t column = CHERRY8x16_NUM_OF_COLUMNS; column--;)
+ {
+ // drive column under test
+ *m_column_port = (uint16_t)(1UL << column);
+ row_state[column] = cherry8x16_row_read();
+
+ // Check if any keys are pressed
+ if (row_state[column] != 0)
+ {
+ uint_fast8_t detected_keypresses_on_column = 0;
+
+ // Loop through rows, check for active rows and add pressed keys to the array
+ for (uint_fast8_t row = CHERRY8x16_NUM_OF_ROWS; row--;)
+ {
+ if (row_state[column] & (1U << row))
+ {
+ if (*number_of_pressed_keys < CHERRY8x16_MAX_NUM_OF_PRESSED_KEYS)
+ {
+ *pressed_keys = matrix_lookup[column * CHERRY8x16_NUM_OF_ROWS + row];
+ pressed_keys++;
+ (*number_of_pressed_keys)++;
+ }
+ detected_keypresses_on_column++;
+ }
+ }
+
+ if (detected_keypresses_on_column > 1)
+ {
+ if (blocking_mask & row_state[column])
+ {
+ // Cannot determine reliably all pressed keys, two or more keys are blocking each other.
+ return false;
+ }
+ }
+ blocking_mask |= row_state[column];
+ }
+ }
+
+ return true;
+}
+
+
+/**
+ * @brief Function for remapping the keypad, F11 and F12 keys in case when Fn key is pressed.
+ *
+ * @param keys Array holding pressed keys.
+ * @param number_of_keys Number of elements if 'keys' array.
+ */
+static void cherry8x16_remap_fn_keys(uint8_t * keys, uint8_t number_of_keys)
+{
+
+ /*lint -e845 -save // A zero has been given as right argument to operator '<<'" */
+ /*lint -e778 -save // Constant expression evaluates to zero */
+
+#define MODIFIER_LEFT_CONTROL_HID 0xE0
+#define MODIFER_RIGHT_CONTROL_HID 0xE4
+ // Check if Fn key is pressed along with any other modifier key (only usage now is Fn + Left_Ctrl = Right Ctrl)
+ // So we modify the modifier byte if Fn + Left_Ctrl is pressed, HID for left_Ctrl = 0xE0
+ if ( keys[0] & (1UL << (MODIFIER_LEFT_CONTROL_HID - MODIFIER_HID_START)) )
+ {
+ keys[0] &= ~(1UL << (MODIFIER_LEFT_CONTROL_HID - MODIFIER_HID_START));
+ keys[0] |= (1UL << (MODIFER_RIGHT_CONTROL_HID - MODIFIER_HID_START));
+ }
+
+ /*lint -restore */
+ /*lint -restore */
+
+ for (uint_fast8_t i = 2; i < number_of_keys; i++)
+ {
+ switch (keys[i])
+ {
+ case 0x10: // 'M'
+ keys[i] = 0x62; // Keypad 0
+ break;
+
+ case 0x37: // '>'
+ keys[i] = 0x63; // Keypad .
+ break;
+
+ case 0x38: // '/'
+ keys[i] = 0x54; // Keypad /
+ break;
+
+ case 0x0D: // 'J'
+ keys[i] = 0x59; // Keypad 1
+ break;
+
+ case 0x0E: // 'K'
+ keys[i] = 0x5A; // Keypad 2
+ break;
+
+ case 0x0F: // 'L'
+ keys[i] = 0x5B; // Keypad 3
+ break;
+
+ case 0x33: // ''
+ keys[i] = 0x57; // Keypad +
+ break;
+
+ case 0x28: // 'Enter'
+ keys[i] = 0x58; // Keypad enter
+ break;
+
+ case 0x18: // 'U'
+ keys[i] = 0x5C; // Keypad 4
+ break;
+
+ case 0x0C: // 'I'
+ keys[i] = 0x5D; // Keypad 5
+ break;
+
+ case 0x12: // 'O'
+ keys[i] = 0x5E; // Keypad 6
+ break;
+
+ case 0x13: // 'P'
+ keys[i] = 0x56; // Keypad -
+ break;
+
+ case 0x24: // '7'
+ keys[i] = 0x5F; // Keypad 7
+ break;
+
+ case 0x25: // '8'
+ keys[i] = 0x60; // Keypad 8
+ break;
+
+ case 0x26: // '9'
+ keys[i] = 0x61; // Keypad 9
+ break;
+
+ case 0x27: // '0'
+ keys[i] = 0x55; // Keypad *
+ break;
+
+ case 0x3A: // 'F1'
+ keys[i] = 0x44; // 'F11'
+ break;
+
+ case 0x3B: // 'F2'
+ keys[i] = 0x45; // 'F12'
+ break;
+
+ default:
+ break;
+ }
+ }
+}
+
+
+/**
+ * @brief Function for determining whether the keyboard matrix state has changed compared to the state before.
+ *
+ * @param state_now List of pressed keys in current state
+ * @param number_of_now_pressed_keys Number of pressed keys in current state
+ * @param state_before List of pressed keys in previous state
+ * @param number_of_before_pressed_keys Number of pressed keys in previous state
+ * @return
+ * @retval true If keyboard matrix is different compared to state before.
+ * @retval false If keyboard matrix is the same compared to state before.
+ */
+static bool cherry8x16_have_keys_changed(const uint8_t * state_now,
+ uint8_t number_of_now_pressed_keys,
+ const uint8_t * state_before,
+ uint8_t number_of_before_pressed_keys)
+{
+ if (number_of_now_pressed_keys != number_of_before_pressed_keys)
+ {
+ return true;
+ }
+ else
+ {
+ for (uint_fast8_t i = number_of_now_pressed_keys; i--;)
+ {
+ if (state_now[i] != state_before[i])
+ {
+ return true;
+ }
+ }
+ }
+ return false;
+}
+
+/**
+ * @brief Function for adding a key to the key packet.
+ *
+ * If key is found to be in the packet, it will not be added twice.
+ * Attempts to add more keys than the buffer capacity allows will be silently ignored.
+ *
+ * @param key Key to add
+ */
+static void cherry8x16_keypacket_addkey(uint8_t key)
+{
+ for (uint_fast8_t i = KEY_PACKET_KEY_INDEX; i < KEY_PACKET_SIZE; i++)
+ {
+ if (m_key_packet[i] == key)
+ {
+ return;
+ }
+ }
+
+ for (uint_fast8_t i = KEY_PACKET_KEY_INDEX; i < KEY_PACKET_SIZE; i++)
+ {
+ if (m_key_packet[i] == KEY_PACKET_NO_KEY)
+ {
+ m_key_packet[i] = key;
+ return;
+ }
+ }
+}
+
+/**
+ * @brief Function for creating a new key packet.
+ *
+ * This function uses @ref m_currently_pressed_keys to determine pressed keys.
+ * Priority is given to those keys that were found in the previous packet.
+ * All modifier keys can be found in all packets.
+ * If Fn key is detected to be pressed, some keys are remapped to different functions.
+ *
+ * @param key_packet Pointer to location where packet contents will be put
+ * @param key_packet_size Key packet size in bytes
+ */
+static void cherry8x16_keypacket_create(uint8_t * key_packet, uint8_t key_packet_size)
+{
+ // Clear key_packet contents
+ for (uint_fast8_t i = KEY_PACKET_KEY_INDEX; i < key_packet_size; i++)
+ {
+ key_packet[i] = KEY_PACKET_NO_KEY;
+ }
+ key_packet[KEY_PACKET_MODIFIER_KEY_INDEX] = 0;
+ key_packet[KEY_PACKET_RESERVED_INDEX] = 0;
+
+ // Give priority to keys that were already pressed when we transmitted them the last time.
+ for (uint_fast8_t i = 0; i < m_number_of_transmitted_keys; i++)
+ {
+ for (uint_fast8_t j = 0; j < m_num_of_currently_pressed_keys; j++)
+ {
+ if (m_transmitted_keys[i] == m_currently_pressed_keys[j])
+ {
+ cherry8x16_keypacket_addkey(m_currently_pressed_keys[j]);
+ break;
+ }
+ }
+ }
+
+ bool fn_key_is_set = false;
+
+ // Detect if Fn is pressed, detect modifier keys, and add rest of the keys to the packet
+ for (uint_fast8_t i = 0; i < m_num_of_currently_pressed_keys; i++)
+ {
+ if (m_currently_pressed_keys[i] == 0xFF) // Pressing Fn key changes function of certain keys and it must handled by the firmware
+ {
+ fn_key_is_set = true;
+ }
+ // Modifier HID usage codes are from 0xE0 to 0xE7
+ else if (m_currently_pressed_keys[i] >= MODIFIER_HID_START && m_currently_pressed_keys[i] <= MODIFIER_HID_END) // Detect and set modifier keys
+ {
+ key_packet[KEY_PACKET_MODIFIER_KEY_INDEX] |= (uint8_t)(1U << (m_currently_pressed_keys[i] - MODIFIER_HID_START));
+ }
+ else if (m_currently_pressed_keys[i] != 0)
+ {
+ cherry8x16_keypacket_addkey(m_currently_pressed_keys[i]);
+ }
+ }
+
+ if (fn_key_is_set)
+ {
+ cherry8x16_remap_fn_keys(&key_packet[0], KEY_PACKET_MAX_KEYS);
+ }
+}
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/drivers_ext/cherry8x16/cherry8x16.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/drivers_ext/cherry8x16/cherry8x16.h
new file mode 100644
index 0000000..b4e099d
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/drivers_ext/cherry8x16/cherry8x16.h
@@ -0,0 +1,119 @@
+/**
+ * Copyright (c) 2009 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#ifndef CHERRY8x16_H
+#define CHERRY8x16_H
+
+/*lint ++flb "Enter library region" */
+
+#include <stdbool.h>
+#include <stdint.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** @file
+* @brief Cherry 8x16 keyboard matrix driver
+*
+*
+* @defgroup nrf_drivers_cherry8x16 Cherry 8x16 keyboard matrix driver
+* @{
+* @ingroup ext_drivers
+* @brief Cherry 8x16 keyboard matrix driver.
+*/
+
+#define CHERRY8x16_MAX_NUM_OF_PRESSED_KEYS 6 //!< Maximum number of pressed keys kept in buffers
+#define CHERRY8x16_DEFAULT_KEY_LOOKUP_MATRIX (const uint8_t*)0 //!< If passed to @ref cherry8x16_init, default lookup matrix will be used
+
+#define KEY_PACKET_MODIFIER_KEY_INDEX (0) //!< Index in the key packet where modifier keys such as ALT and Control are stored
+#define KEY_PACKET_RESERVED_INDEX (1) //!< Index in the key packet where OEMs can store information
+#define KEY_PACKET_KEY_INDEX (2) //!< Start index in the key packet where pressed keys are stored
+#define KEY_PACKET_MAX_KEYS (6) //!< Maximum number of keys that can be stored into the key packet
+#define KEY_PACKET_SIZE (KEY_PACKET_KEY_INDEX + KEY_PACKET_MAX_KEYS) //!< Total size of the key packet in bytes
+#define KEY_PACKET_NO_KEY (0) //!< Value to be stored to key index to indicate no key is pressed
+
+
+/**
+ * Describes return values for:
+ * @ref cherry8x16_init
+ */
+typedef enum
+{
+ CHERRY8x16_OK, /*!< Operation was succesful. */
+ CHERRY8x16_NOT_DETECTED, /*!< Product/Revision ID was not what was expected */
+ CHERRY8x16_INVALID_PARAMETER /*!< Given parameters were not valid */
+} cherry8x16_status_t;
+
+/**
+ * @brief Function for initializing the driver.
+ *
+ * @note Before calling this function, setup row_port as IO inputs with pulldowns enabled and column_port as IO outputs.
+ *
+ * @param row_port Pointer to GPIO port address that is used as key matrix row input.
+ * @param column_port Pointer to GPIO port address that is used as key matrix column output.
+ * @param key_lookup_matrix If NULL, use a default key lookup matrix. Otherwise pointer to a 128 (8x16) element array containing HID keycodes.
+ * @return
+ * @retval CHERRY8X16_OK Peripheral was initialized succesfully.
+ * @retval CHERRY8X16_NOT_DETECTED Could not detect the peripheral.
+ */
+cherry8x16_status_t cherry8x16_init(const uint8_t volatile * row_port, uint16_t * column_port, const uint8_t * key_lookup_matrix);
+
+/**
+ * @brief Function for creating a new key packet if new data is available and key ghosting is not detected.
+ *
+ * @param p_key_packet Array that will hold the created key packet. Previously created packet will be discarded.
+ * @param p_key_packet_size Key packet size in bytes.
+ * @return
+ * @retval true If new packet was created.
+ * @retval false If packet was not created.
+ */
+bool cherry8x16_new_packet(const uint8_t ** p_key_packet, uint8_t *p_key_packet_size);
+
+/**
+ *@}
+ **/
+
+/*lint --flb "Leave library region" */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/drivers_ext/ds1624/ds1624.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/drivers_ext/ds1624/ds1624.c
new file mode 100644
index 0000000..ac4da3b
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/drivers_ext/ds1624/ds1624.c
@@ -0,0 +1,154 @@
+/**
+ * Copyright (c) 2012 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#include "ds1624.h"
+#include "twi_master.h"
+#include "nrf_delay.h"
+
+/*lint ++flb "Enter library region" */
+
+#define DS1634_BASE_ADDRESS 0x90 //!< 4 MSBs of the DS1624 TWI address
+
+#define DS1624_ONESHOT_MODE 0x01 //!< Bit in configuration register for 1-shot mode
+#define DS1624_CONVERSION_DONE 0x80 //!< Bit in configuration register to indicate completed temperature conversion
+
+static uint8_t m_device_address; //!< Device address in bits [7:1]
+
+const uint8_t command_access_memory = 0x17; //!< Reads or writes to 256-byte EEPROM memory
+const uint8_t command_access_config = 0xAC; //!< Reads or writes configuration data to configuration register
+const uint8_t command_read_temp = 0xAA; //!< Reads last converted temperature value from temperature register
+const uint8_t command_start_convert_temp = 0xEE; //!< Initiates temperature conversion.
+const uint8_t command_stop_convert_temp = 0x22; //!< Halts temperature conversion.
+
+/**
+ * @brief Function for reading the current configuration of the sensor.
+ *
+ * @return uint8_t Zero if communication with the sensor failed. Contents (always non-zero) of configuration register (@ref DS1624_ONESHOT_MODE and @ref DS1624_CONVERSION_DONE) if communication succeeded.
+ */
+static uint8_t ds1624_config_read(void)
+{
+ uint8_t config = 0;
+
+ // Write: command protocol
+ if (twi_master_transfer(m_device_address, (uint8_t*)&command_access_config, 1, TWI_DONT_ISSUE_STOP))
+ {
+ if (twi_master_transfer(m_device_address | TWI_READ_BIT, &config, 1, TWI_ISSUE_STOP)) // Read: current configuration
+ {
+ // Read succeeded, configuration stored to variable "config"
+ }
+ else
+ {
+ // Read failed
+ config = 0;
+ }
+ }
+
+ return config;
+}
+
+bool ds1624_init(uint8_t device_address)
+{
+ bool transfer_succeeded = true;
+ m_device_address = DS1634_BASE_ADDRESS + (uint8_t)(device_address << 1);
+
+ uint8_t config = ds1624_config_read();
+
+ if (config != 0)
+ {
+ // Configure DS1624 for 1SHOT mode if not done so already.
+ if (!(config & DS1624_ONESHOT_MODE))
+ {
+ uint8_t data_buffer[2];
+
+ data_buffer[0] = command_access_config;
+ data_buffer[1] = DS1624_ONESHOT_MODE;
+
+ transfer_succeeded &= twi_master_transfer(m_device_address, data_buffer, 2, TWI_ISSUE_STOP);
+ }
+ }
+ else
+ {
+ transfer_succeeded = false;
+ }
+
+ return transfer_succeeded;
+}
+
+bool ds1624_start_temp_conversion(void)
+{
+ return twi_master_transfer(m_device_address, (uint8_t*)&command_start_convert_temp, 1, TWI_ISSUE_STOP);
+}
+
+bool ds1624_is_temp_conversion_done(void)
+{
+ uint8_t config = ds1624_config_read();
+
+ if (config & DS1624_CONVERSION_DONE)
+ {
+ return true;
+ }
+ else
+ {
+ return false;
+ }
+}
+
+bool ds1624_temp_read(int8_t * temperature_in_celcius, int8_t * temperature_fraction)
+{
+ bool transfer_succeeded = false;
+
+ // Write: Begin read temperature command
+ if (twi_master_transfer(m_device_address, (uint8_t*)&command_read_temp, 1, TWI_DONT_ISSUE_STOP))
+ {
+ uint8_t data_buffer[2];
+
+ // Read: 2 temperature bytes to data_buffer
+ if (twi_master_transfer(m_device_address | TWI_READ_BIT, data_buffer, 2, TWI_ISSUE_STOP))
+ {
+ *temperature_in_celcius = (int8_t)data_buffer[0];
+ *temperature_fraction = (int8_t)data_buffer[1];
+
+ transfer_succeeded = true;
+ }
+ }
+
+ return transfer_succeeded;
+}
+
+/*lint --flb "Leave library region" */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/drivers_ext/ds1624/ds1624.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/drivers_ext/ds1624/ds1624.h
new file mode 100644
index 0000000..e331119
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/drivers_ext/ds1624/ds1624.h
@@ -0,0 +1,113 @@
+/**
+ * Copyright (c) 2009 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#ifndef DS1624_H
+#define DS1624_H
+
+/*lint ++flb "Enter library region" */
+
+#include <stdbool.h>
+#include <stdint.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** @file
+* @brief DS1624 digital temperature sensor driver.
+*
+*
+* @defgroup nrf_drivers_ds1624 DS1624 digital temperature sensor driver
+* @{
+* @ingroup ext_drivers
+* @brief DS1624 digital temperature sensor driver.
+*/
+
+/**
+ * @brief Function for initializing DS1624 temperature sensor to 1-shot mode.
+ *
+ * @note Before calling this function, you must initialize twi_master first.
+ *
+ * @param device_address Bits [2:0] for the device address. All other bits must be zero.
+ * @return
+ * @retval true If communication succeeded with the device.
+ * @retval false If communication failed with the device.
+ */
+bool ds1624_init(uint8_t device_address);
+
+/**
+ * @brief Function for reading temperature from the sensor.
+ *
+ * @param temperature_in_celcius Memory location to store temperature in full celcius degrees.
+ * @param temperature_fraction Memory location to store temperature's fraction part in 0.03125 celcius degree increments.
+ * @return
+ * @retval true Temperature was successfully read
+ * @retval false Temperature reading failed or conversion was not yet complete
+ */
+bool ds1624_temp_read(int8_t *temperature_in_celcius, int8_t *temperature_fraction);
+
+/**
+ * @brief Function for starting temperature conversion. Valid data will be available 400 - 1000 milliseconds after exiting this function.
+ *
+ * @return
+ * @retval true Temperature conversion started.
+ * @retval false Temperature converion failed to start.
+*/
+bool ds1624_start_temp_conversion(void);
+
+/**
+ * @brief Function for checking if temperature conversion is done.
+ *
+ * @return
+ * @retval true Temperature conversion done.
+ * @retval false Temperature converion still in progress.
+*/
+bool ds1624_is_temp_conversion_done(void);
+
+/**
+ *@}
+ **/
+
+/*lint --flb "Leave library region" */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/drivers_ext/hts221/hts221.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/drivers_ext/hts221/hts221.c
new file mode 100644
index 0000000..ce77d60
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/drivers_ext/hts221/hts221.c
@@ -0,0 +1,255 @@
+/**
+ * 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#include "hts221.h"
+#include <string.h>
+
+#define HTS221_WRITE(p_instance, msg) \
+ nrf_twi_sensor_write(p_instance->p_sensor_data, \
+ p_instance->sensor_addr, \
+ msg, \
+ ARRAY_SIZE(msg), \
+ true)
+
+static void hts221_init_cb(ret_code_t result, void * p_register_data)
+{
+ hts221_calib_t * calib_info = (hts221_calib_t *) p_register_data;
+ uint8_t calib_raw[HTS221_REG_CALIBRATION_NUM];
+ memcpy(calib_raw, calib_info, HTS221_REG_CALIBRATION_NUM);
+
+ calib_info->H0_rH_x2 = calib_raw[0];
+ calib_info->H1_rH_x2 = calib_raw[1];
+ calib_info->T0_degC_x8 = (uint16_t)calib_raw[2]
+ + ((uint16_t)(calib_raw[5] & 0x03) << 8);
+ calib_info->T1_degC_x8 = (uint16_t)calib_raw[3]
+ + ((uint16_t)((calib_raw[5] >> 2) & 0x03) << 8);
+ calib_info->H0_T0_OUT = (int16_t)calib_raw[6] + ((int16_t)calib_raw[7] << 8);
+ calib_info->H1_T0_OUT = (int16_t)calib_raw[10] + ((int16_t)calib_raw[11] << 8);
+ calib_info->T0_OUT = (int16_t)calib_raw[12] + ((int16_t)calib_raw[13] << 8);
+ calib_info->T1_OUT = (int16_t)calib_raw[14] + ((int16_t)calib_raw[15] << 8);
+
+}
+
+ret_code_t hts221_init(hts221_instance_t * p_instance)
+{
+ ASSERT(p_instance != NULL);
+ if (p_instance->p_sensor_data->p_twi_mngr->p_queue->size < HTS221_MIN_QUEUE_SIZE)
+ {
+ return NRF_ERROR_INVALID_LENGTH;
+ }
+ p_instance->ctrl_reg1 = 0;
+ uint8_t send_msg[] = {
+ HTS221_REG_AV_CONF,
+ HTS221_DEF_AV_CONF,
+ 0,
+ 0,
+ 0
+ };
+
+ ret_code_t err = HTS221_WRITE(p_instance, send_msg);
+ if (err != NRF_SUCCESS)
+ {
+ return err;
+ }
+
+ return nrf_twi_sensor_reg_read(p_instance->p_sensor_data,
+ p_instance->sensor_addr,
+ HTS221_REG_CALIBRATION | HTS221_INCR_REG_MASK,
+ hts221_init_cb,
+ (uint8_t *) &p_instance->calib_info,
+ HTS221_REG_CALIBRATION_NUM);
+}
+
+ret_code_t hts221_avg_cfg(hts221_instance_t * p_instance,
+ hts221_temp_avg_samples_t temp_avg,
+ hts221_hum_avg_samples_t hum_avg)
+{
+ ASSERT(p_instance != NULL);
+ uint8_t reg_val = 0;
+ NRF_TWI_SENSOR_REG_SET(reg_val, HTS221_AVGT_MASK, HTS221_AVGT_POS, temp_avg);
+ NRF_TWI_SENSOR_REG_SET(reg_val, HTS221_AVGH_MASK, HTS221_AVGH_POS, hum_avg);
+
+ uint8_t send_msg[] = {
+ HTS221_REG_AV_CONF,
+ reg_val
+ };
+
+ return HTS221_WRITE(p_instance, send_msg);
+}
+
+ret_code_t hts221_data_rate_cfg(hts221_instance_t * p_instance, hts221_odr_t odr)
+{
+ ASSERT(p_instance != NULL);
+ NRF_TWI_SENSOR_REG_SET(p_instance->ctrl_reg1, HTS221_ODR_MASK, HTS221_ODR_POS, odr);
+
+ uint8_t send_msg[] = {
+ HTS221_REG_CTRL_REG1,
+ p_instance->ctrl_reg1
+ };
+
+ return HTS221_WRITE(p_instance, send_msg);
+}
+
+ret_code_t hts221_pd_enable(hts221_instance_t * p_instance, bool enable)
+{
+ ASSERT(p_instance != NULL);
+ NRF_TWI_SENSOR_REG_SET(p_instance->ctrl_reg1, HTS221_PD_MASK, HTS221_PD_POS, enable);
+ uint8_t send_msg[] = {
+ HTS221_REG_CTRL_REG1,
+ p_instance->ctrl_reg1
+ };
+
+ return HTS221_WRITE(p_instance, send_msg);
+}
+
+
+
+ret_code_t hts221_boot(hts221_instance_t * p_instance)
+{
+ ASSERT(p_instance != NULL);
+ uint8_t reg_val = p_instance->ctrl_reg2;
+ NRF_TWI_SENSOR_REG_SET(reg_val, HTS221_BOOT_MASK, HTS221_BOOT_POS, 1);
+ uint8_t send_msg[] = {
+ HTS221_REG_CTRL_REG2,
+ reg_val
+ };
+
+ return HTS221_WRITE(p_instance, send_msg);
+}
+
+ret_code_t hts221_heater_enable(hts221_instance_t * p_instance, bool enable)
+{
+ ASSERT(p_instance != NULL);
+ NRF_TWI_SENSOR_REG_SET(p_instance->ctrl_reg2, HTS221_HEATER_MASK, HTS221_HEATER_POS, enable);
+
+ uint8_t send_msg[] = {
+ HTS221_REG_CTRL_REG2,
+ p_instance->ctrl_reg2
+ };
+
+ return HTS221_WRITE(p_instance, send_msg);
+}
+
+ret_code_t hts221_oneshot(hts221_instance_t * p_instance)
+{
+ ASSERT(p_instance != NULL);
+ uint8_t reg_val = p_instance->ctrl_reg2;
+ NRF_TWI_SENSOR_REG_SET(reg_val, HTS221_ONE_SHOT_MASK, HTS221_ONE_SHOT_POS, true);
+ uint8_t send_msg[] = {
+ HTS221_REG_CTRL_REG2,
+ reg_val
+ };
+
+ return HTS221_WRITE(p_instance, send_msg);
+}
+
+ret_code_t hts221_drdy_pin_cfg(hts221_instance_t * p_instance,
+ bool active_low,
+ bool operation,
+ bool drdy_enable)
+{
+ ASSERT(p_instance != NULL);
+ uint8_t reg_val = 0;
+ NRF_TWI_SENSOR_REG_SET(reg_val, HTS221_DRDY_H_L_MASK, HTS221_DRDY_H_L_POS, active_low);
+ NRF_TWI_SENSOR_REG_SET(reg_val, HTS221_PP_OD_MASK, HTS221_PP_OD_POS, operation);
+ NRF_TWI_SENSOR_REG_SET(reg_val, HTS221_DRDY_EN_MASK, HTS221_DRDY_EN_POS, drdy_enable);
+
+ uint8_t send_msg[] = {
+ HTS221_REG_CTRL_REG3,
+ reg_val
+ };
+
+ return HTS221_WRITE(p_instance, send_msg);
+}
+
+ret_code_t hts221_temp_read(hts221_instance_t * p_instance,
+ hts221_data_callback_t user_callback,
+ int16_t * p_temp)
+{
+ ASSERT(p_instance != NULL);
+ return nrf_twi_sensor_reg_read(p_instance->p_sensor_data,
+ p_instance->sensor_addr,
+ HTS221_REG_TEMP_OUT_L | HTS221_INCR_REG_MASK,
+ (nrf_twi_sensor_reg_cb_t) user_callback,
+ (uint8_t *) p_temp,
+ 2);
+}
+
+int16_t hts221_temp_process(hts221_instance_t * p_instance, int16_t raw_temp)
+{
+ ASSERT(p_instance != NULL);
+ int32_t y;
+ int32_t x0 = p_instance->calib_info.T0_OUT;
+ int32_t x1 = p_instance->calib_info.T1_OUT;
+ int32_t y0 = p_instance->calib_info.T0_degC_x8;
+ int32_t y1 = p_instance->calib_info.T1_degC_x8;
+
+ y = ((y0 * (x1 - raw_temp)) + (y1 * (raw_temp - x0))) / (x1 - x0);
+
+ return y;
+}
+
+ret_code_t hts221_hum_read(hts221_instance_t * p_instance,
+ hts221_data_callback_t user_callback,
+ int16_t * p_hum)
+{
+ ASSERT(p_instance != NULL);
+ return nrf_twi_sensor_reg_read(p_instance->p_sensor_data,
+ p_instance->sensor_addr,
+ HTS221_REG_HUM_OUT_L | HTS221_INCR_REG_MASK,
+ (nrf_twi_sensor_reg_cb_t) user_callback,
+ (uint8_t *) p_hum,
+ 2);
+}
+
+int16_t hts221_hum_process(hts221_instance_t * p_instance, int16_t raw_hum)
+{
+ ASSERT(p_instance != NULL);
+ int32_t y;
+ int32_t x0 = p_instance->calib_info.H0_T0_OUT;
+ int32_t x1 = p_instance->calib_info.H1_T0_OUT;
+ int32_t y0 = p_instance->calib_info.H0_rH_x2;
+ int32_t y1 = p_instance->calib_info.H1_rH_x2;
+
+ y = ((y0 * (x1 - raw_hum)) + (y1 * (raw_hum - x0))) / (x1 - x0);
+
+ return y;
+}
+
+
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/drivers_ext/hts221/hts221.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/drivers_ext/hts221/hts221.h
new file mode 100644
index 0000000..c44d86f
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/drivers_ext/hts221/hts221.h
@@ -0,0 +1,309 @@
+/**
+ * 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#ifndef HTS221_H
+#define HTS221_H
+
+#include "nrf_twi_sensor.h"
+#include "hts221_internal.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @brief Possible sensor addresses.
+ */
+#define HTS221_BASE_ADDRESS 0x5FU
+
+// Who am I default value.
+#define HTS221_WHO_AM_I 0xBC
+
+// Minimal TWI Manager queue size needed for sensor.
+#define HTS221_MIN_QUEUE_SIZE 4
+
+/**
+ * @brief Sensor driver usage.
+ *
+ * Sensor instance has to be defined first in global context using @ref HTS221_INSTANCE_DEF.
+ * After that it has to be initialized using @ref hts221_init.
+ * At this point sensor instance is ready and all other functions can be used.
+ *
+ * Configuration functions schedule TWI operation using @ref nrf_twi_sensor module.
+ * After calling function, setting will be automatically send to sensor when TWI bus is free.
+ *
+ * There are designated functions to read status sensor registers e.g. @ref hts221_status_read
+ * As parameters they receive function to be called after register is read, and pointer where
+ * register value should be stored. From that value specific parameters can be extracted
+ * using @ref NRF_TWI_SENSOR_REG_VAL_GET macro.
+ * Example:
+ * uint8_t h_da = NRF_TWI_SENSOR_REG_VAL_GET(status, HTS221_H_DA_MASK, HTS221_H_DA_POS);
+ *
+ * Other functions are self-explanatory or have description on their usage.
+ */
+
+/**
+ * @brief Temperature average setting.
+ */
+
+typedef enum
+{
+ HTS221_TEMP_SAMPLES_2,
+ HTS221_TEMP_SAMPLES_4,
+ HTS221_TEMP_SAMPLES_8,
+ HTS221_TEMP_SAMPLES_16,
+ HTS221_TEMP_SAMPLES_32,
+ HTS221_TEMP_SAMPLES_64,
+ HTS221_TEMP_SAMPLES_128,
+ HTS221_TEMP_SAMPLES_256
+} hts221_temp_avg_samples_t;
+
+/**
+ * @brief Humidity average setting.
+ */
+typedef enum
+{
+ HTS221_HUMIDITY_SAMPLES_4,
+ HTS221_HUMIDITY_SAMPLES_8,
+ HTS221_HUMIDITY_SAMPLES_16,
+ HTS221_HUMIDITY_SAMPLES_32,
+ HTS221_HUMIDITY_SAMPLES_64,
+ HTS221_HUMIDITY_SAMPLES_128,
+ HTS221_HUMIDITY_SAMPLES_256,
+ HTS221_HUMIDITY_SAMPLES_512
+} hts221_hum_avg_samples_t;
+
+/**
+ * @brief Output data rate settings.
+ */
+typedef enum
+{
+ HTS221_ODR_ONESHOT,
+ HTS221_ODR_1HZ,
+ HTS221_ODR_7HZ,
+ HTS221_ODR_12_5HZ,
+} hts221_odr_t;
+
+/**
+ * @brief Data callback prototype.
+ *
+ * @param[in] result Return error code from TWI manager and underlying drivers.
+ * @param[in] p_data Pointer to sensor data.
+ */
+typedef void (* hts221_data_callback_t)(ret_code_t result, int16_t * p_data);
+
+/**
+ * @brief Macro creating hts221 sensor instance.
+ *
+ * @param[in] _hts221_inst_name Sensor instance name.
+ * @param[in] _p_twi_sensor Pointer to common TWI sensor instance. @ref NRF_TWI_SENSOR_DEF
+ * @param[in] _sensor_address Sensor base address.
+ */
+#define HTS221_INSTANCE_DEF(_hts221_inst_name, _p_twi_sensor, _sensor_address) \
+ HTS221_INTERNAL_INSTANCE_DEF(_hts221_inst_name, _p_twi_sensor, _sensor_address)
+
+/**
+ * @brief Function initializing hts221 sensor
+ *
+ * Writes configuration from sensor instance into sensor.
+ *
+ * @param[in] p_instance Pointer to sensor instance created by macro
+ *
+ * @note TWI manager queue size has to be at least
+ * HTS221_MIN_QUEUE_SIZE element long.
+ *
+ * @return Return error code from nrf_twi_sensor @ref nrf_twi_sensor_write
+ */
+ret_code_t hts221_init(hts221_instance_t * p_instance);
+
+/**
+ * @brief Function for setting average configuration.
+ *
+ * @param[in] p_instance Pointer to sensor instance.
+ * @param[in] temp_avg Number of temperature average samples.
+ * @param[in] hum_avg Number of humidity average samples.
+ *
+ * @return Return error code from nrf_twi_sensor @ref nrf_twi_sensor_write
+ */
+ret_code_t hts221_avg_cfg(hts221_instance_t * p_instance,
+ hts221_temp_avg_samples_t temp_avg,
+ hts221_hum_avg_samples_t hum_avg);
+
+/**
+ * @brief Function for setting power down mode
+ *
+ * @param[in] p_instance Pointer to sensor instance.
+ * @param[in] enable True if device is powered, false if power down.
+ *
+ * @note Changes made by this function don't take effect before @ref hts221_cfg_commit
+ */
+ret_code_t hts221_pd_enable(hts221_instance_t * p_instance, bool enable);
+
+/**
+ * @brief Function for rebooting sensor.
+ *
+ * @param[in] p_instance Pointer to sensor instance.
+ *
+ * @return Return error code from nrf_twi_sensor @ref nrf_twi_sensor_write
+ */
+ret_code_t hts221_boot(hts221_instance_t * p_instance);
+
+/**
+ * @brief Function for setting heater.
+ *
+ * @param[in] p_instance Pointer to sensor instance.
+ * @param[in] enable True if heater is on.
+ *
+ * @note Changes made by this function don't take effect before @ref hts221_cfg_commit
+ */
+ret_code_t hts221_heater_enable(hts221_instance_t * p_instance, bool enable);
+
+/**
+ * @brief Function for setting one shot mode
+ *
+ * @param[in] p_instance Pointer to sensor instance.
+ * @param[in] enable True if one shot mode is on.
+ *
+ * @return Return error code from nrf_twi_sensor @ref nrf_twi_sensor_write
+ */
+ret_code_t hts221_oneshot(hts221_instance_t * p_instance);
+
+/**
+ * @brief Function for setting sensor_data ready output signal.
+ *
+ * @param[in] p_instance Pointer to sensor instance.
+ * @param[in] active_low True if active low, false if active high.
+ * @param[in] open_drain True if open drain, false if push-pull.
+ * @param[in] drdy_enable True if pin is enabled.
+ *
+ * @note Changes made by this function don't take effect before @ref hts221_cfg_commit
+ */
+ret_code_t hts221_drdy_pin_cfg(hts221_instance_t * p_instance,
+ bool active_low,
+ bool operation,
+ bool drdy_enable);
+
+/**
+ * @brief Function for setting output data rate.
+ *
+ * @param[in] p_instance Pointer to sensor instance.
+ * @param[in] odr Desired output data rate.
+ *
+ * @note Changes made by this function don't take effect before @ref hts221_cfg_commit
+ */
+ret_code_t hts221_data_rate_cfg(hts221_instance_t * p_instance, hts221_odr_t odr);
+
+/**
+ * @brief Function for reading sensors temperature.
+ *
+ * @param[in] p_instance Pointer to sensor instance.
+ * @param[in] user_callback Function to be called when sensor data is gathered.
+ * @param[out] p_temp Pointer for raw temperature value, single int16_t.
+ *
+ * @return Return error code from nrf_twi_sensor @ref nrf_twi_sensor_reg_read
+ */
+ret_code_t hts221_temp_read(hts221_instance_t * p_instance,
+ hts221_data_callback_t user_callback,
+ int16_t * p_temp);
+
+/**
+ * @brief Function for calculating temperature based on sensors calibration data.
+ *
+ * @param[in] p_instance Pointer to sensor instance.
+ * @param[in] raw_temp Raw temperature in.
+ *
+ * @return Temperature * 8
+ */
+int16_t hts221_temp_process(hts221_instance_t * p_instance, int16_t raw_temp);
+
+/**
+ * @brief Function for reading sensors humidity.
+ *
+ * @param[in] p_instance Pointer to sensor instance.
+ * @param[in] user_callback Function to be called when data is gathered.
+ * @param[out] p_hum Pointer for raw humidity value, single int16_t.
+ *
+ * @return Return error code from nrf_twi_sensor @ref nrf_twi_sensor_reg_read
+ */
+ret_code_t hts221_hum_read(hts221_instance_t * p_instance,
+ hts221_data_callback_t user_callback,
+ int16_t * p_hum);
+
+/**
+ * @brief Function for calculating humidity based on sensors calibration data.
+ *
+ * @param[in] p_instance Pointer to sensor instance.
+ * @param[in] raw_hum Raw humidity in.
+ *
+ * @return Humidity * 2
+ */
+int16_t hts221_hum_process(hts221_instance_t * p_instance, int16_t raw_hum);
+
+/**
+ * @brief Function for reading WHO_AM_I register.
+ *
+ * @param[in] p_instance Pointer to sensor instance.
+ * @param[in] user_cb Function to be called after register is read.
+ * @param[out] reg_val Register value, single uint8_t.
+ *
+ * @return Return error code from nrf_twi_sensor @ref nrf_twi_sensor_reg_read
+ */
+__STATIC_INLINE ret_code_t hts221_who_am_i_read(hts221_instance_t * p_instance,
+ nrf_twi_sensor_reg_cb_t user_cb,
+ uint8_t * reg_val);
+
+/**
+ * @brief Function for reading status register.
+ *
+ * @param[in] p_instance Pointer to sensor instance.
+ * @param[in] user_cb Function to be called after register is read.
+ * @param[out] reg_val Register value, single uint8_t.
+ *
+ * @return Return error code from nrf_twi_sensor @ref nrf_twi_sensor_reg_read
+ */
+__STATIC_INLINE ret_code_t hts221_status_read(hts221_instance_t * p_instance,
+ nrf_twi_sensor_reg_cb_t user_cb,
+ uint8_t * reg_val);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // HTS221_H
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/drivers_ext/hts221/hts221_internal.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/drivers_ext/hts221/hts221_internal.h
new file mode 100644
index 0000000..c4e538f
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/drivers_ext/hts221/hts221_internal.h
@@ -0,0 +1,235 @@
+/**
+ * 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#ifndef HTS221_INTERNAL_H
+#define HTS221_INTERNAL_H
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @brief HTS221 sensor registers.
+ */
+#define HTS221_REG_WHO_AM_I 0x0F
+#define HTS221_REG_AV_CONF 0x10
+#define HTS221_REG_CTRL_REG1 0x20
+#define HTS221_REG_CTRL_REG2 0x21
+#define HTS221_REG_CTRL_REG3 0x22
+#define HTS221_REG_STATUS_REG 0x27
+#define HTS221_REG_HUM_OUT_L 0x28
+#define HTS221_REG_HUM_OUT_H 0x29
+#define HTS221_REG_TEMP_OUT_L 0x2A
+#define HTS221_REG_TEMP_OUT_H 0x2B
+
+// Calibration registers
+#define HTS221_REG_CALIBRATION 0x30
+
+#define HTS221_REG_CALIBRATION_NUM 16
+#define HTS221_REG_CTRL_NUM 3
+
+// For auto incrementing address, msb in register address must be set to 1.
+#define HTS221_INCR_REG_MASK 0x80
+
+/**
+ * @brief AV_CONF register bitmasks.
+ */
+#define HTS221_DEF_AV_CONF 0x1B
+
+// Register validity bitmask.
+#define HTS221_AV_CONF_VALID_MASK 0xC0
+
+// Bitmasks for AVGT.
+#define HTS221_AVGT_POS 3
+#define HTS221_AVGT_MASK (7 << HTS221_AVGT_POS)
+
+// Bitmasks for AVGH.
+#define HTS221_AVGH_POS 0
+#define HTS221_AVGH_MASK (7 << HTS221_AVGH_POS)
+
+
+/**
+ * @brief Control register 1 bitmasks.
+ */
+
+// Register validity bitmask.
+#define HTS221_CTRL1_VALID_MASK 0x78
+
+// Bitmasks for PD.
+#define HTS221_PD_POS 7
+#define HTS221_PD_MASK (1 << HTS221_PD_POS)
+
+// Bitmasks for BDU.
+#define HTS221_BDU_POS 2
+#define HTS221_BDU_MASK (1 << HTS221_BDU_POS)
+
+// Bitmasks for ODR.
+#define HTS221_ODR_POS 0
+#define HTS221_ODR_MASK (3 << HTS221_ODR_POS)
+
+
+/**
+ * @brief Control register 2 bitmasks.
+ */
+
+// Register validity bitmask.
+#define HTS221_CTRL2_VALID_MASK 0x7C
+
+// Bitmasks for BOOT.
+#define HTS221_BOOT_POS 7
+#define HTS221_BOOT_MASK (1 << HTS221_BOOT_POS)
+
+// Bitmasks for Heater.
+#define HTS221_HEATER_POS 1
+#define HTS221_HEATER_MASK (1 << HTS221_HEATER_POS)
+
+// Bitmasks for ONE_SHOT.
+#define HTS221_ONE_SHOT_POS 0
+#define HTS221_ONE_SHOT_MASK (1 << HTS221_ONE_SHOT_POS)
+
+
+/**
+ * @brief Control register 3 bitmasks.
+ */
+
+// Register validity bitmask.
+#define HTS221_CTRL3_VALID_MASK 0x3B
+
+// Bitmasks for DRDY_H_L.
+#define HTS221_DRDY_H_L_POS 7
+#define HTS221_DRDY_H_L_MASK (1 << HTS221_DRDY_H_L_POS)
+
+// Bitmasks for PP_OD
+#define HTS221_PP_OD_POS 6
+#define HTS221_PP_OD_MASK (1 << HTS221_PP_OD_POS)
+
+// Bitmasks for DRDY_EN.
+#define HTS221_DRDY_EN_POS 2
+#define HTS221_DRDY_EN_MASK (1 << HTS221_DRDY_EN_POS)
+
+
+/**
+ * @brief Status register bitmasks.
+ */
+
+// Bitmasks for H_DA.
+#define HTS221_H_DA_POS 1
+#define HTS221_H_DA_MASK (1 << HTS221_H_DA_POS)
+
+// Bitmasks for T_DA
+#define HTS221_T_DA_POS 0
+#define HTS221_T_DA_MASK (1 << HTS221_T_DA_POS)
+
+
+/**
+ * @brief Structure holding calibration information.
+ */
+typedef struct
+{
+ uint8_t H0_rH_x2;
+ uint8_t H1_rH_x2;
+ uint16_t T0_degC_x8;
+ uint16_t T1_degC_x8;
+ int16_t H0_T0_OUT;
+ int16_t H1_T0_OUT;
+ int16_t T0_OUT;
+ int16_t T1_OUT;
+ uint16_t padding; //<- Additional memory needed to store all calibration registers.
+} hts221_calib_t;
+
+/**
+ * @brief Structure holding sensor instance
+ */
+typedef struct
+{
+ nrf_twi_sensor_t * const p_sensor_data;
+ uint8_t const sensor_addr;
+
+ hts221_calib_t calib_info;
+ uint8_t ctrl_reg1;
+ uint8_t ctrl_reg2;
+
+} hts221_instance_t;
+
+/**
+ * @brief Macro creating hts221 sensor instance.
+ */
+#define HTS221_INTERNAL_INSTANCE_DEF(_hts221_inst_name, _p_twi_sensor, _sensor_address) \
+ static hts221_instance_t _hts221_inst_name = \
+ { \
+ .p_sensor_data = _p_twi_sensor, \
+ .sensor_addr = _sensor_address, \
+ }
+
+#ifndef SUPPRESS_INLINE_IMPLEMENTATION
+
+__STATIC_INLINE ret_code_t hts221_who_am_i_read(hts221_instance_t * p_instance,
+ nrf_twi_sensor_reg_cb_t user_cb,
+ uint8_t * reg_val)
+{
+ ASSERT(p_instance != NULL);
+ return nrf_twi_sensor_reg_read(p_instance->p_sensor_data,
+ p_instance->sensor_addr,
+ HTS221_REG_WHO_AM_I,
+ user_cb,
+ reg_val,
+ 1);
+}
+
+__STATIC_INLINE ret_code_t hts221_status_read(hts221_instance_t * p_instance,
+ nrf_twi_sensor_reg_cb_t user_cb,
+ uint8_t * reg_val)
+{
+ ASSERT(p_instance != NULL);
+ return nrf_twi_sensor_reg_read(p_instance->p_sensor_data,
+ p_instance->sensor_addr,
+ HTS221_REG_STATUS_REG,
+ user_cb,
+ reg_val,
+ 1);
+}
+
+#endif //SUPPRESS_INLINE_IMPLEMENTATION
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // HTS221_INTERNAL_H
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/drivers_ext/ili9341/ili9341.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/drivers_ext/ili9341/ili9341.c
new file mode 100644
index 0000000..f61a87d
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/drivers_ext/ili9341/ili9341.c
@@ -0,0 +1,401 @@
+/**
+ * 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+
+#include "sdk_common.h"
+
+#if NRF_MODULE_ENABLED(ILI9341)
+
+#include "nrf_lcd.h"
+#include "nrf_drv_spi.h"
+#include "nrf_delay.h"
+#include "nrf_gpio.h"
+#include "boards.h"
+
+// Set of commands described in ILI9341 datasheet.
+#define ILI9341_NOP 0x00
+#define ILI9341_SWRESET 0x01
+#define ILI9341_RDDID 0x04
+#define ILI9341_RDDST 0x09
+
+#define ILI9341_SLPIN 0x10
+#define ILI9341_SLPOUT 0x11
+#define ILI9341_PTLON 0x12
+#define ILI9341_NORON 0x13
+
+#define ILI9341_RDMODE 0x0A
+#define ILI9341_RDMADCTL 0x0B
+#define ILI9341_RDPIXFMT 0x0C
+#define ILI9341_RDIMGFMT 0x0D
+#define ILI9341_RDSELFDIAG 0x0F
+
+#define ILI9341_INVOFF 0x20
+#define ILI9341_INVON 0x21
+#define ILI9341_GAMMASET 0x26
+#define ILI9341_DISPOFF 0x28
+#define ILI9341_DISPON 0x29
+
+#define ILI9341_CASET 0x2A
+#define ILI9341_PASET 0x2B
+#define ILI9341_RAMWR 0x2C
+#define ILI9341_RAMRD 0x2E
+
+#define ILI9341_PTLAR 0x30
+#define ILI9341_MADCTL 0x36
+#define ILI9341_PIXFMT 0x3A
+
+#define ILI9341_FRMCTR1 0xB1
+#define ILI9341_FRMCTR2 0xB2
+#define ILI9341_FRMCTR3 0xB3
+#define ILI9341_INVCTR 0xB4
+#define ILI9341_DFUNCTR 0xB6
+
+#define ILI9341_PWCTR1 0xC0
+#define ILI9341_PWCTR2 0xC1
+#define ILI9341_PWCTR3 0xC2
+#define ILI9341_PWCTR4 0xC3
+#define ILI9341_PWCTR5 0xC4
+#define ILI9341_VMCTR1 0xC5
+#define ILI9341_VMCTR2 0xC7
+#define ILI9341_PWCTRSEQ 0xCB
+#define ILI9341_PWCTRA 0xCD
+#define ILI9341_PWCTRB 0xCF
+
+#define ILI9341_RDID1 0xDA
+#define ILI9341_RDID2 0xDB
+#define ILI9341_RDID3 0xDC
+#define ILI9341_RDID4 0xDD
+
+#define ILI9341_GMCTRP1 0xE0
+#define ILI9341_GMCTRN1 0xE1
+#define ILI9341_DGMCTR1 0xE2
+#define ILI9341_DGMCTR2 0xE3
+#define ILI9341_TIMCTRA 0xE8
+#define ILI9341_TIMCTRB 0xEA
+
+#define ILI9341_ENGMCTR 0xF2
+#define ILI9341_INCTR 0xF6
+#define ILI9341_PUMP 0xF7
+
+#define ILI9341_MADCTL_MY 0x80
+#define ILI9341_MADCTL_MX 0x40
+#define ILI9341_MADCTL_MV 0x20
+#define ILI9341_MADCTL_ML 0x10
+#define ILI9341_MADCTL_RGB 0x00
+#define ILI9341_MADCTL_BGR 0x08
+#define ILI9341_MADCTL_MH 0x04
+
+static const nrf_drv_spi_t spi = NRF_DRV_SPI_INSTANCE(ILI9341_SPI_INSTANCE);
+
+static inline void spi_write(const void * data, size_t size)
+{
+ APP_ERROR_CHECK(nrf_drv_spi_transfer(&spi, data, size, NULL, 0));
+}
+
+static inline void write_command(uint8_t c)
+{
+ nrf_gpio_pin_clear(ILI9341_DC_PIN);
+ spi_write(&c, sizeof(c));
+}
+
+static inline void write_data(uint8_t c)
+{
+ nrf_gpio_pin_set(ILI9341_DC_PIN);
+ spi_write(&c, sizeof(c));
+}
+
+static void set_addr_window(uint16_t x_0, uint16_t y_0, uint16_t x_1, uint16_t y_1)
+{
+ ASSERT(x_0 <= x_1);
+ ASSERT(y_0 <= y_1);
+
+ write_command(ILI9341_CASET);
+ write_data(x_0 >> 8);
+ write_data(x_0);
+ write_data(x_1 >> 8);
+ write_data(x_1);
+ write_command(ILI9341_PASET);
+ write_data(y_0 >> 8);
+ write_data(y_0);
+ write_data(y_1 >> 8);
+ write_data(y_1);
+ write_command(ILI9341_RAMWR);
+}
+
+static void command_list(void)
+{
+ write_command(ILI9341_SWRESET);
+ nrf_delay_ms(120);
+ write_command(ILI9341_DISPOFF);
+ nrf_delay_ms(120);
+ write_command(ILI9341_PWCTRB);
+ write_data(0x00);
+ write_data(0XC1);
+ write_data(0X30);
+
+ write_command(ILI9341_TIMCTRA);
+ write_data(0x85);
+ write_data(0x00);
+ write_data(0x78);
+
+ write_command(ILI9341_PWCTRSEQ);
+ write_data(0x39);
+ write_data(0x2C);
+ write_data(0x00);
+ write_data(0x34);
+ write_data(0x02);
+
+ write_command(ILI9341_PUMP);
+ write_data(0x20);
+
+ write_command(ILI9341_TIMCTRB);
+ write_data(0x00);
+ write_data(0x00);
+
+ write_command(ILI9341_PWCTR1);
+ write_data(0x23);
+
+ write_command(ILI9341_PWCTR2);
+ write_data(0x10);
+
+ write_command(ILI9341_VMCTR1);
+ write_data(0x3e);
+ write_data(0x28);
+
+ write_command(ILI9341_VMCTR2);
+ write_data(0x86);
+
+ write_command(ILI9341_MADCTL);
+ write_data(0x48);
+
+ write_command(ILI9341_PIXFMT);
+ write_data(0x55);
+
+ write_command(ILI9341_FRMCTR1);
+ write_data(0x00);
+ write_data(0x18);
+
+ write_command(ILI9341_DFUNCTR);
+ write_data(0x08);
+ write_data(0x82);
+ write_data(0x27);
+
+ write_command(ILI9341_ENGMCTR);
+ write_data(0x00);
+
+ write_command(ILI9341_GAMMASET);
+ write_data(0x01);
+
+ write_command(ILI9341_GMCTRP1);
+ write_data(0x0F);
+ write_data(0x31);
+ write_data(0x2B);
+ write_data(0x0C);
+ write_data(0x0E);
+ write_data(0x08);
+ write_data(0x4E);
+ write_data(0xF1);
+ write_data(0x37);
+ write_data(0x07);
+ write_data(0x10);
+ write_data(0x03);
+ write_data(0x0E);
+ write_data(0x09);
+ write_data(0x00);
+
+ write_command(ILI9341_GMCTRN1);
+ write_data(0x00);
+ write_data(0x0E);
+ write_data(0x14);
+ write_data(0x03);
+ write_data(0x11);
+ write_data(0x07);
+ write_data(0x31);
+ write_data(0xC1);
+ write_data(0x48);
+ write_data(0x08);
+ write_data(0x0F);
+ write_data(0x0C);
+ write_data(0x31);
+ write_data(0x36);
+ write_data(0x0F);
+
+ write_command(ILI9341_SLPOUT);
+ nrf_delay_ms(120);
+ write_command(ILI9341_DISPON);
+}
+
+static ret_code_t hardware_init(void)
+{
+ ret_code_t err_code;
+
+ nrf_gpio_cfg_output(ILI9341_DC_PIN);
+
+ nrf_drv_spi_config_t spi_config = NRF_DRV_SPI_DEFAULT_CONFIG;
+
+ spi_config.sck_pin = ILI9341_SCK_PIN;
+ spi_config.miso_pin = ILI9341_MISO_PIN;
+ spi_config.mosi_pin = ILI9341_MOSI_PIN;
+ spi_config.ss_pin = ILI9341_SS_PIN;
+
+ err_code = nrf_drv_spi_init(&spi, &spi_config, NULL, NULL);
+ return err_code;
+}
+
+static ret_code_t ili9341_init(void)
+{
+ ret_code_t err_code;
+
+ err_code = hardware_init();
+ if (err_code != NRF_SUCCESS)
+ {
+ return err_code;
+ }
+
+ command_list();
+
+ return err_code;
+}
+
+static void ili9341_uninit(void)
+{
+ nrf_drv_spi_uninit(&spi);
+}
+
+static void ili9341_pixel_draw(uint16_t x, uint16_t y, uint32_t color)
+{
+ set_addr_window(x, y, x, y);
+
+ const uint8_t data[2] = {color >> 8, color};
+
+ nrf_gpio_pin_set(ILI9341_DC_PIN);
+
+ spi_write(data, sizeof(data));
+
+ nrf_gpio_pin_clear(ILI9341_DC_PIN);
+}
+
+static void ili9341_rect_draw(uint16_t x, uint16_t y, uint16_t width, uint16_t height, uint32_t color)
+{
+ set_addr_window(x, y, x + width - 1, y + height - 1);
+
+ const uint8_t data[2] = {color >> 8, color};
+
+ nrf_gpio_pin_set(ILI9341_DC_PIN);
+
+ // Duff's device algorithm for optimizing loop.
+ uint32_t i = (height * width + 7) / 8;
+
+/*lint -save -e525 -e616 -e646 */
+ switch ((height * width) % 8) {
+ case 0:
+ do {
+ spi_write(data, sizeof(data));
+ case 7:
+ spi_write(data, sizeof(data));
+ case 6:
+ spi_write(data, sizeof(data));
+ case 5:
+ spi_write(data, sizeof(data));
+ case 4:
+ spi_write(data, sizeof(data));
+ case 3:
+ spi_write(data, sizeof(data));
+ case 2:
+ spi_write(data, sizeof(data));
+ case 1:
+ spi_write(data, sizeof(data));
+ } while (--i > 0);
+ default:
+ break;
+ }
+/*lint -restore */
+
+ nrf_gpio_pin_clear(ILI9341_DC_PIN);
+}
+
+static void ili9341_dummy_display(void)
+{
+ /* No implementation needed. */
+}
+
+static void ili9341_rotation_set(nrf_lcd_rotation_t rotation)
+{
+ write_command(ILI9341_MADCTL);
+ switch (rotation) {
+ case NRF_LCD_ROTATE_0:
+ write_data(ILI9341_MADCTL_MX | ILI9341_MADCTL_BGR);
+ break;
+ case NRF_LCD_ROTATE_90:
+ write_data(ILI9341_MADCTL_MV | ILI9341_MADCTL_BGR);
+ break;
+ case NRF_LCD_ROTATE_180:
+ write_data(ILI9341_MADCTL_MY | ILI9341_MADCTL_BGR);
+ break;
+ case NRF_LCD_ROTATE_270:
+ write_data(ILI9341_MADCTL_MX | ILI9341_MADCTL_MY | ILI9341_MADCTL_MV | ILI9341_MADCTL_BGR);
+ break;
+ default:
+ break;
+ }
+}
+
+static void ili9341_display_invert(bool invert)
+{
+ write_command(invert ? ILI9341_INVON : ILI9341_INVOFF);
+}
+
+static lcd_cb_t ili9341_cb = {
+ .height = ILI9341_HEIGHT,
+ .width = ILI9341_WIDTH
+};
+
+
+const nrf_lcd_t nrf_lcd_ili9341 = {
+ .lcd_init = ili9341_init,
+ .lcd_uninit = ili9341_uninit,
+ .lcd_pixel_draw = ili9341_pixel_draw,
+ .lcd_rect_draw = ili9341_rect_draw,
+ .lcd_display = ili9341_dummy_display,
+ .lcd_rotation_set = ili9341_rotation_set,
+ .lcd_display_invert = ili9341_display_invert,
+ .p_lcd_cb = &ili9341_cb
+};
+
+#endif // NRF_MODULE_ENABLED(ILI9341)
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/drivers_ext/lis2dh12/lis2dh12.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/drivers_ext/lis2dh12/lis2dh12.c
new file mode 100644
index 0000000..77b43b0
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/drivers_ext/lis2dh12/lis2dh12.c
@@ -0,0 +1,173 @@
+/**
+ * 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+
+#include "lis2dh12.h"
+
+#define RETURN_IF_ERR(err) \
+ if (err != NRF_SUCCESS) \
+ { \
+ return err; \
+ }
+
+ret_code_t lis2dh12_init(lis2dh12_instance_t * p_inst)
+{
+ ASSERT(p_inst != NULL);
+ memset(&p_inst->temp_cfg, 0, &p_inst->act_dur - &p_inst->temp_cfg);
+ p_inst->ctrl0 = LIS2DH12_CTRL_REG0_VALID_SET;
+ p_inst->ctrl1 = 0x07;
+ p_inst->ctrl4 = 0x80;
+
+ return lis2dh12_cfg_commit(p_inst);
+}
+
+ret_code_t lis2dh12_cfg_commit(lis2dh12_instance_t * p_inst)
+{
+ ASSERT(p_inst != NULL);
+ ret_code_t err;
+ p_inst->ctrl0 &= ~LIS2DH12_CTRL_REG0_VALID_MASK;
+ p_inst->ctrl0 |= LIS2DH12_CTRL_REG0_VALID_SET;
+
+ uint8_t ctrl_msg[] = {
+ LIS2DH12_REG_CTRL_REG0 | LIS2DH12_AUTO_INCR_MASK,
+ p_inst->ctrl0,
+ p_inst->temp_cfg,
+ p_inst->ctrl1,
+ p_inst->ctrl2,
+ p_inst->ctrl3,
+ p_inst->ctrl4,
+ p_inst->ctrl5,
+ p_inst->ctrl6,
+ p_inst->reference
+ };
+ err = nrf_twi_sensor_write(p_inst->p_sensor_data,
+ p_inst->sensor_addr,
+ ctrl_msg,
+ ARRAY_SIZE(ctrl_msg),
+ true);
+ RETURN_IF_ERR(err);
+ uint8_t fifo_msg[] = {
+ LIS2DH12_REG_FIFO_CTRL | LIS2DH12_AUTO_INCR_MASK,
+ p_inst->fifo_ctrl,
+ 0,
+ p_inst->int1_cfg,
+ 0,
+ p_inst->int1_ths,
+ p_inst->int1_dur,
+ p_inst->int2_cfg,
+ 0,
+ p_inst->int2_ths,
+ p_inst->int2_dur,
+ p_inst->click_cfg
+ };
+ err = nrf_twi_sensor_write(p_inst->p_sensor_data,
+ p_inst->sensor_addr,
+ fifo_msg,
+ ARRAY_SIZE(fifo_msg),
+ true);
+ RETURN_IF_ERR(err);
+
+ uint8_t time_msg[] = {
+ LIS2DH12_REG_CLICK_THS | LIS2DH12_AUTO_INCR_MASK,
+ p_inst->click_ths,
+ p_inst->time_lim,
+ p_inst->latency,
+ p_inst->time_win,
+ p_inst->act_ths,
+ p_inst->act_dur
+ };
+ err = nrf_twi_sensor_write(p_inst->p_sensor_data,
+ p_inst->sensor_addr,
+ time_msg,
+ ARRAY_SIZE(time_msg),
+ true);
+ return err;
+}
+
+ret_code_t lis2dh12_data_read(lis2dh12_instance_t * p_inst,
+ lis2dh12_data_cb_t user_cb,
+ lis2dh12_data_t * p_data,
+ uint8_t samples)
+{
+ ASSERT(p_inst != NULL);
+ return nrf_twi_sensor_reg_read(p_inst->p_sensor_data,
+ p_inst->sensor_addr,
+ LIS2DH12_REG_OUT_X_L | LIS2DH12_AUTO_INCR_MASK,
+ (nrf_twi_sensor_reg_cb_t) user_cb,
+ (uint8_t *) p_data,
+ samples * LIS2DH12_BYTES_PER_SAMPLE);
+}
+
+ret_code_t lis2dh12_temp_enable(lis2dh12_instance_t * p_inst, bool temp_en)
+{
+ ASSERT(p_inst != NULL);
+ if (temp_en == true)
+ {
+ NRF_TWI_SENSOR_REG_SET(p_inst->temp_cfg, LIS2DH12_TEMP_EN_MASK, LIS2DH12_TEMP_EN_POS, 3);
+ }
+ else
+ {
+ NRF_TWI_SENSOR_REG_SET(p_inst->temp_cfg, LIS2DH12_TEMP_EN_MASK, LIS2DH12_TEMP_EN_POS, 0);
+ }
+
+ uint8_t send_msg[] = {
+ LIS2DH12_REG_TEMP_CFG_REG,
+ p_inst->temp_cfg
+ };
+
+ return nrf_twi_sensor_write(p_inst->p_sensor_data,
+ p_inst->sensor_addr,
+ send_msg,
+ ARRAY_SIZE(send_msg),
+ true);
+
+}
+
+ret_code_t lis2dh12_temp_read(lis2dh12_instance_t * p_inst,
+ lis2dh12_temp_cb_t user_cb,
+ int16_t * p_temp)
+{
+ ASSERT(p_inst != NULL);
+ return nrf_twi_sensor_reg_read(p_inst->p_sensor_data,
+ p_inst->sensor_addr,
+ LIS2DH12_REG_OUT_TEMP_L | LIS2DH12_AUTO_INCR_MASK,
+ (nrf_twi_sensor_reg_cb_t) user_cb,
+ (uint8_t *) p_temp,
+ LIS2DH12_BYTES_PER_TEMP);
+}
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/drivers_ext/lis2dh12/lis2dh12.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/drivers_ext/lis2dh12/lis2dh12.h
new file mode 100644
index 0000000..13dd0ed
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/drivers_ext/lis2dh12/lis2dh12.h
@@ -0,0 +1,491 @@
+/**
+ * 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#ifndef LIS2DH12_H
+#define LIS2DH12_H
+
+#include "nrf_twi_sensor.h"
+#include "lis2dh12_internal.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @brief Possible sensor addresses.
+ */
+#define LIS2DH12_BASE_ADDRESS_LOW 0x18U
+#define LIS2DH12_BASE_ADDRESS_HIGH 0x19U
+
+// WHO_AM_I register value.
+#define LIS2DH12_WHO_AM_I 0x33
+
+/**
+ * @brief Sensor driver usage.
+ *
+ * Sensor instance has to be defined first in global context using @ref LIS2DH12_INSTANCE DEF.
+ * After that it has to be initialized using @ref lis2dh12_init.
+ * At this point sensor instance is ready and all other functions can be used.
+ *
+ * Sensor settings are modified using asynchronous macros, using them does not change
+ * real sensor settings until @ref lis2dh12_cfg_commit is called.
+ * Example:
+ * LIS2DH12_DATA_CFG(m_sensor, LIS2DH12_ODR_200HZ, false, true, true, true, LIS2DH12_SCALE_2G, 1);
+ * lis2dh12_cfg_commit(&m_sensor);
+ *
+ * There are designated functions to read status sensor registers e.g. @ref lis2dh12_status_read
+ * As parameters they receive function to be called after register is read, and pointer where
+ * register value should be stored. From that value specific parameters can be extracted
+ * using @ref NRF_TWI_SENSOR_REG_VAL_GET macro. For specific bitmasks, check lis2dh12_internal.h
+ * Example:
+ * bool zyxor = NRF_TWI_SENSOR_REG_VAL_GET(status_reg, LIS2DH12_ZYXOR_MASK, LIS2DH12_ZYXOR_POS);
+ *
+ * Other functions are self-explanatory or have description on their usage.
+ */
+
+/**
+ * @brief Output data rate settings.
+ */
+typedef enum
+{
+ LIS2DH12_ODR_POWERDOWN,
+ LIS2DH12_ODR_1HZ,
+ LIS2DH12_ODR_10HZ,
+ LIS2DH12_ODR_25HZ,
+ LIS2DH12_ODR_50HZ,
+ LIS2DH12_ODR_100HZ,
+ LIS2DH12_ODR_200HZ,
+ LIS2DH12_ODR_400HZ,
+ LIS2DH12_ODR_1620HZ,
+ LIS2DH12_ODR_1344_5376HZ
+} lis2dh12_odr_t;
+
+/**
+ * @brief Fifo mode settings.
+ */
+typedef enum
+{
+ LIS2DH12_BYPASS,
+ LIS2DH12_FIFO,
+ LIS2DH12_STREAM,
+ LIS2DH12_STREAM_TO_FIFO
+} lis2dh12_fifo_mode_t;
+
+/**
+ * @brief Filter mode setting.
+ */
+typedef enum
+{
+ LIS2DH12_FILTER_MODE_NORMAL_W_RESET,
+ LIS2DH12_FILTER_MODE_REFERENCE,
+ LIS2DH12_FILTER_MODE_NORMAL,
+ LIS2DH12_FILTER_MODE_AUTO_RESET
+} lis2dh12_filter_mode_t;
+
+/**
+ * @brief Filter frequency setting.
+ */
+typedef enum
+{
+ LIS2DH12_FILTER_FREQ_1,
+ LIS2DH12_FILTER_FREQ_2,
+ LIS2DH12_FILTER_FREQ_3,
+ LIS2DH12_FILTER_FREQ_4
+} lis2dh12_filter_freq_t;
+
+/**
+ * @brief Accelerometer scale setting.
+ */
+typedef enum
+{
+ LIS2DH12_SCALE_2G,
+ LIS2DH12_SCALE_4G,
+ LIS2DH12_SCALE_8G,
+ LIS2DH12_SCALE_16G
+} lis2dh12_scale_t;
+
+/**
+ * @brief Structure containing accelerometer data.
+ */
+typedef struct
+{
+ int16_t x;
+ int16_t y;
+ int16_t z;
+} lis2dh12_data_t;
+
+/**
+ * @brief Data callback prototype.
+ *
+ * @param[in] result Result of operation (NRF_SUCCESS on success,
+ * otherwise a relevant error code).
+ * @param[in] p_data Pointer to raw sensor data structure.
+ */
+typedef void (* lis2dh12_data_cb_t)(ret_code_t result, lis2dh12_data_t * p_data);
+
+/**
+ * @brief Temperature callback prototype.
+ *
+ * @param[in] result Result of operation (NRF_SUCCESS on success,
+ * otherwise a relevant error code).
+ * @param[in] p_temp Temperature value.
+ */
+typedef void (* lis2dh12_temp_cb_t)(ret_code_t result, int16_t * p_temp);
+
+/**
+ * @brief Macro for defining sensor instance.
+ *
+ * @param[in] _lis2dh12_inst_name Sensor instance name.
+ * @param[in] _p_twi_sensor Pointer to common TWI sensor instance.
+ * @param[in] _sensor_address Sensor base address.
+ */
+#define LIS2DH12_INSTANCE_DEF(_lis2dh12_inst_name, _p_twi_sensor, _sensor_address) \
+ LIS2DH12_INTERNAL_INSTANCE_DEF(_lis2dh12_inst_name, _p_twi_sensor, _sensor_address)
+
+/**
+ * @brief Macro for setting data acquisition configuration.
+ *
+ * @param[in] _s Sensor instance.
+ * @param[in] _odr Data rate. @ref lis2dh12_odr_t
+ * @param[in] _lp Power mode. True if low power mode is enabled.
+ * @param[in] _z_en Enable measure in z-axis. True if enabled.
+ * @param[in] _y_en Enable measure in y-axis. True if enabled.
+ * @param[in] _x_en Enable measure in x-axis. True if enabled.
+ * @param[in] _scale Measurement scale. @ref lis2dh12_scale_t
+ * @param[in] _high_res High resolution mode. True if enabled.
+ * Low power can't be enabled when in high resolution mode.
+ */
+#define LIS2DH12_DATA_CFG(_s, _odr, _lp, _z_en, _y_en, _x_en, _scale, _high_res) \
+ LIS2DH12_INTERNAL_DATA_CFG(_s, _odr, _lp, _z_en, _y_en, _x_en, _scale, _high_res)
+
+/**
+ * @brief Function for setting filter configuration.
+ *
+ * @param[in] _s Sensor instance.
+ * @param[in] _mode Filter mode. @ref lis2dh12_filter_mode_t
+ * @param[in] _freq Filter frequency. @ref lis2dh12_filter_freq_t
+ * @param[in] _d_en Enable filter for data acquisition.
+ * @param[in] _c_en Enable filter for click interrupt.
+ * @param[in] _i1_en Enable filter for interrupt 1 aoi.
+ * @param[in] _i2_en Enable filter for interrupt 2 aoi.
+ */
+#define LIS2DH12_FILTER_CFG(_s, _mode, _freq, _d_en, _c_en, _i1_en, _i2_en) \
+ LIS2DH12_INTERNAL_FILTER_CFG(_s, _mode, _freq, _d_en, _c_en, _i1_en, _i2_en)
+
+/**
+ * @brief Macro for configuring INT1 pin.
+ *
+ * @param[in] _s Sensor instance.
+ * @param[in] _cl Enable CLICK interrupt on pin.
+ * @param[in] _ia1 Enable IA1 interrupt on pin.
+ * @param[in] _ia2 Enable IA2 interrupt on pin.
+ * @param[in] _zyxda Enable ZYXDA interrupt on pin.
+ * @param[in] _wtm Enable FIFO watermark interrupt on pin.
+ * @param[in] _ovr Enable FIFO overrun interrupt on pin.
+ * @param[in] _pol Pin active state. Affects also int2 pin.
+ * @arg true Pin is active low.
+ * @arg false Pin is active high
+ * @param[in] _d4d Enable 4D detection on INT1 pin when 6D is enabled on interrupt 1.
+ */
+#define LIS2DH12_INT1_PIN_CFG(_s, _cl, _ia1, _ia2, _zyxda, _wtm, _ovr, _pol, _d4d) \
+ LIS2DH12_INTERNAL_INT1_PIN_CFG(_s, _cl, _ia1, _ia2, _zyxda, _wtm, _ovr, _pol, _d4d)
+
+/**
+ * @brief Macro for configuring INT2 pin.
+ *
+ * @param[in] _s Sensor instance.
+ * @param[in] _cl Enable CLICK interrupt on pin.
+ * @param[in] _ia1 Enable IA1 interrupt on pin.
+ * @param[in] _ia2 Enable IA2 interrupt on pin.
+ * @param[in] _boot Enable boot on pin.
+ * @param[in] _avt Enable activity interrupt on pin.
+ * @param[in] _pol Pin active state. Affects also int1 pin.
+ * @arg true Pin is active low.
+ * @arg false Pin is active high
+ * @param[in] _d4d Enable 4D detection on INT2 pin when 6D is enabled on interrupt 2.
+ */
+#define LIS2DH12_INT2_PIN_CFG(_s, _cl, _ia1, _ia2, _boot, _act, _pol, _d4d) \
+ LIS2DH12_INTERNAL_INT2_PIN_CFG(_s, _cl, _ia1, _ia2, _boot, _act, _pol, _d4d)
+
+ /**
+ * @brief Macro for configuring interrupt 1.
+ *
+ * @param[in] _s Sensor instance.
+ * @param[in] _thr Interrupt threshold.
+ * @param[in] _dur Interrupt duration.
+ * @param[in] _aoi And/Or combination of interrupt events. True if and.
+ * @param[in] _6d 6-direction detection enable. True if enabled.
+ * @param[in] _zh Enable interrupt on Z high event or direction recognition.
+ * @param[in] _zl Enable interrupt on Z low event or direction recognition.
+ * @param[in] _yh Enable interrupt on Y high event or direction recognition.
+ * @param[in] _yl Enable interrupt on Y low event or direction recognition.
+ * @param[in] _xh Enable interrupt on X high event or direction recognition.
+ * @param[in] _xl Enable interrupt on X low event or direction recognition.
+ * @param[in] _lir Latch interrupt 1 request. True if enabled.
+ */
+#define LIS2DH12_INT1_CFG(_s, _thr, _dur, _aoi, _6d, _zh, _zl, _yh, yl, _xh, _xl, _lir) \
+ LIS2DH12_INTERNAL_INT1_CFG(_s, _thr, _dur, _aoi, _6d, _zh, _zl, _yh, yl, _xh, _xl, _lir)
+
+/**
+ * @brief Macro for configuring interrupt 2.
+ *
+ * @param[in] _s Sensor instance.
+ * @param[in] _thr Interrupt threshold.
+ * @param[in] _dur Interrupt duration.
+ * @param[in] _aoi And/Or combination of interrupt events. True if and.
+ * @param[in] _6d 6-direction detection enable. True if enabled.
+ * @param[in] _zh Enable interrupt on Z high event or direction recognition.
+ * @param[in] _zl Enable interrupt on Z low event or direction recognition.
+ * @param[in] _yh Enable interrupt on Y high event or direction recognition.
+ * @param[in] _yl Enable interrupt on Y low event or direction recognition.
+ * @param[in] _xh Enable interrupt on X high event or direction recognition.
+ * @param[in] _xl Enable interrupt on X low event or direction recognition.
+ * @param[in] _lir Latch interrupt 1 request. True if enabled.
+ */
+#define LIS2DH12_INT2_CFG(_s, _thr, _dur, _aoi, _6d, _zh, _zl, _yh, yl, _xh, _xl, _lir) \
+ LIS2DH12_INTERNAL_INT2_CFG(_s, _thr, _dur, _aoi, _6d, _zh, _zl, _yh, yl, _xh, _xl, _lir)
+
+/**
+ * @brief Function for setting click configuration.
+ *
+ * @param[in] _s Sensor instance.
+ * @param[in] _zd Enable interrupt double-click on Z-axis.
+ * @param[in] _zs Enable interrupt single-click on Z-axis.
+ * @param[in] _yd Enable interrupt double-click on Y-axis.
+ * @param[in] _ys Enable interrupt single-click on Y-axis.
+ * @param[in] _xd Enable interrupt double-click on X-axis.
+ * @param[in] _xs Enable interrupt single-click on X-axis.
+ * @param[in] _lir Keep high until CLICK_SRC is read.
+ * @arg true Interrupt is kept high until CLICK_SRC is read.
+ * @arg false Interrupt is kept high for the duration of latency window.
+ * @param[in] _ths Click threshold.
+ * @param[in] _lim Click time limit.
+ * @param[in] _ltc Click time latency.
+ * @param[in] _win Click time window.
+ */
+#define LIS2DH12_CLICK_CFG(_s, _zd, _zs, _yd, _ys, _xd, _xs, _lir, _ths, _lim, _ltc, _win) \
+ LIS2DH12_INTERNAL_CLICK_CFG(_s, _zd, _zs, _yd, _ys, _xd, _xs, _lir, _ths, _lim, _ltc, _win)
+
+ /**
+ * @brief Macro for setting sleep configuration.
+ *
+ * @param[in] _s Sensor instance.
+ * @param[in] _ths Sleep-to-wake, return-to-sleep activation threshold in low-power mode.
+ * @param[in] _dur Sleep-to-wake, return-to-sleep duration.
+ */
+#define LIS2DH12_SLEEP_CFG(_s, _ths, _dur) \
+ LIS2DH12_INTERNAL_SLEEP_CFG(_s, _ths, _dur)
+
+/**
+ * @brief Macro for setting reference value for interrupt generation.
+ *
+ * @param[in] _s Sensor instance.
+ * @param[in] _ref Reference value.
+ */
+#define LIS2DH_REF_SET(_s, _ref) \
+ LIS2DH_INTERNAL_REF_SET(_s, _ref)
+
+/**
+ * @brief Macro for setting FIFO configuration.
+ *
+ * @param[in] _s Sensor instance.
+ * @param[in] _en Enables FIFO. True if enabled. False clears FIFO setting.
+ * @param[in] _mode FIFO mode. @ref lis2dh12_fifo_mode_t
+ * @param[in] _t_sel Trigger event pin selection. True if int2 pin, false if int1 pin.
+ * @param[in] _t_thr Trigger threshold.
+ */
+#define LIS2DH12_FIFO_CFG(_s, _en, _mode, _t_sel, _t_thr) \
+ LIS2DH12_INTERNAL_FIFO_CFG(_s, _en, _mode, _t_sel, _t_thr)
+
+/**
+ * @brief Function for initializing LIS2DH12 instance.
+ *
+ * @param[in] p_inst Pointer to sensor instance defined by macro. @ref LIS2DH12_INSTANCE_DEF
+ *
+ * @return Return error code from nrf_twi_sensor @ref nrf_twi_sensor_write
+ */
+ret_code_t lis2dh12_init(lis2dh12_instance_t * p_inst);
+
+/**
+ * @brief Function for writing configuration to sensor.
+ *
+ * @param[in] p_inst Pointer to sensor instance.
+ *
+ * @return Return error code from nrf_twi_sensor @ref nrf_twi_sensor_write
+ */
+ret_code_t lis2dh12_cfg_commit(lis2dh12_instance_t * p_inst);
+
+/**
+ * @brief Function for reading accelerometer data.
+ *
+ * @param[in] p_inst Pointer to sensor instance.
+ * @param[in] user_cb Function to be called after data read is complete.
+ * @param[in] p_data Pointer to data structure.
+ * @param[in] samples Number of samples to read.
+ *
+ * @note When trying to read more than one sample and FIFO is disabled,
+ * current output value will be copied to all read samples.
+ * When trying to read more samples than there is currently in FIFO,
+ * excess samples will be equal to 0.
+ *
+ * @return Return error code from nrf_twi_sensor @ref nrf_twi_sensor_reg_read
+ */
+ret_code_t lis2dh12_data_read(lis2dh12_instance_t * p_inst,
+ lis2dh12_data_cb_t user_cb,
+ lis2dh12_data_t * p_data,
+ uint8_t samples);
+
+/**
+ * @brief Function for enabling temperature measurement.
+ *
+ * @param[in] p_inst Pointer to sensor instance.
+ * @param[in] temp_en Temperature measure enable. True if enabled.
+ *
+ * @return Return error code from nrf_twi_sensor @ref nrf_twi_sensor_write
+ */
+ret_code_t lis2dh12_temp_enable(lis2dh12_instance_t * p_inst, bool temp_en);
+
+/**
+ * @brief Function for reading temperature data.
+ *
+ * @param[in] p_inst Pointer to sensor instance.
+ * @param[in] user_cb Function to be called after temperature read is complete.
+ * @param[in] p_temp Temperature value. Pointer to single int16_t.
+ *
+ * @return Return error code from nrf_twi_sensor @ref nrf_twi_sensor_reg_read
+ */
+ret_code_t lis2dh12_temp_read(lis2dh12_instance_t * p_inst,
+ lis2dh12_temp_cb_t user_cb,
+ int16_t * p_temp);
+
+/**
+ * @brief Function for reading temperature status register.
+ *
+ * @param[in] p_inst Pointer to sensor instance.
+ * @param[in] user_cb Function to be called after register read.
+ * @param[in] p_data Pointer to register data. Single uint8_t.
+ *
+ * @return Return error code from nrf_twi_sensor @ref nrf_twi_sensor_reg_read
+ */
+__STATIC_INLINE ret_code_t lis2dh12_temp_status_read(lis2dh12_instance_t * p_inst,
+ nrf_twi_sensor_reg_cb_t user_cb,
+ uint8_t * p_data);
+
+/**
+ * @brief Function for reading WHO_AM_I register.
+ *
+ * @param[in] p_inst Pointer to sensor instance.
+ * @param[in] user_cb Function to be called after register read.
+ * @param[in] p_data Pointer to register data. Single uint8_t.
+ *
+ * @return Return error code from nrf_twi_sensor @ref nrf_twi_sensor_reg_read
+ */
+__STATIC_INLINE ret_code_t lis2dh12_who_am_i_read(lis2dh12_instance_t * p_inst,
+ nrf_twi_sensor_reg_cb_t user_cb,
+ uint8_t * p_data);
+
+/**
+ * @brief Function for reading status register.
+ *
+ * @param[in] p_inst Pointer to sensor instance.
+ * @param[in] user_cb Function to be called after register read.
+ * @param[in] p_data Pointer to register data. Single uint8_t.
+ *
+ * @return Return error code from nrf_twi_sensor @ref nrf_twi_sensor_reg_read
+ */
+__STATIC_INLINE ret_code_t lis2dh12_status_read(lis2dh12_instance_t * p_inst,
+ nrf_twi_sensor_reg_cb_t user_cb,
+ uint8_t * p_data);
+
+/**
+ * @brief Function for reading FIFO source register.
+ *
+ * @param[in] p_inst Pointer to sensor instance.
+ * @param[in] user_cb Function to be called after register read.
+ * @param[in] p_data Pointer to register data. Single uint8_t.
+ *
+ * @return Return error code from nrf_twi_sensor @ref nrf_twi_sensor_reg_read
+ */
+__STATIC_INLINE ret_code_t lis2dh12_fifo_src_read(lis2dh12_instance_t * p_inst,
+ nrf_twi_sensor_reg_cb_t user_cb,
+ uint8_t * p_data);
+
+/**
+ * @brief Function for reading interrupt 1 source register.
+ *
+ * @param[in] p_inst Pointer to sensor instance.
+ * @param[in] user_cb Function to be called after register read.
+ * @param[in] p_data Pointer to register data. Single uint8_t.
+ *
+ * @return Return error code from nrf_twi_sensor @ref nrf_twi_sensor_reg_read
+ */
+__STATIC_INLINE ret_code_t lis2dh12_int1_src_read(lis2dh12_instance_t * p_inst,
+ nrf_twi_sensor_reg_cb_t user_cb,
+ uint8_t * p_data);
+
+/**
+ * @brief Function for reading interrupt 2 source register.
+ *
+ * @param[in] p_inst Pointer to sensor instance.
+ * @param[in] user_cb Function to be called after register read.
+ * @param[in] p_data Pointer to register data. Single uint8_t.
+ *
+ * @return Return error code from nrf_twi_sensor @ref nrf_twi_sensor_reg_read
+ */
+__STATIC_INLINE ret_code_t lis2dh12_int2_src_read(lis2dh12_instance_t * p_inst,
+ nrf_twi_sensor_reg_cb_t user_cb,
+ uint8_t * p_data);
+
+/**
+ * @brief Function for reading click source register.
+ *
+ * @param[in] p_inst Pointer to sensor instance.
+ * @param[in] user_cb Function to be called after register read.
+ * @param[in] p_data Pointer to register data. Single uint8_t.
+ *
+ * @return Return error code from nrf_twi_sensor @ref nrf_twi_sensor_reg_read
+ */
+__STATIC_INLINE ret_code_t lis2dh12_click_src_read(lis2dh12_instance_t * p_inst,
+ nrf_twi_sensor_reg_cb_t user_cb,
+ uint8_t * p_data);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // LIS2DH12_H
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/drivers_ext/lis2dh12/lis2dh12_internal.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/drivers_ext/lis2dh12/lis2dh12_internal.h
new file mode 100644
index 0000000..f7b30cf
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/drivers_ext/lis2dh12/lis2dh12_internal.h
@@ -0,0 +1,823 @@
+/**
+ * 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#ifndef LIS2DH12_INTERNAL_H
+#define LIS2DH12_INTERNAL_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+#define LIS2DH12_AUTO_INCR_MASK 0x80
+/**
+ * @brief LIS2DH12 sensor registers.
+ */
+#define LIS2DH12_REG_STATUS_AUX 0x07
+#define LIS2DH12_REG_OUT_TEMP_L 0x0C
+#define LIS2DH12_REG_OUT_TEMP_H 0x0D
+#define LIS2DH12_REG_WHO_AM_I 0x0F
+#define LIS2DH12_REG_CTRL_REG0 0x1E
+#define LIS2DH12_REG_TEMP_CFG_REG 0x1F
+#define LIS2DH12_REG_CTRL_REG1 0x20
+#define LIS2DH12_REG_CTRL_REG2 0x21
+#define LIS2DH12_REG_CTRL_REG3 0x22
+#define LIS2DH12_REG_CTRL_REG4 0x23
+#define LIS2DH12_REG_CTRL_REG5 0x24
+#define LIS2DH12_REG_CTRL_REG6 0x25
+#define LIS2DH12_REG_REFERENCE 0x26
+#define LIS2DH12_REG_STATUS 0x27
+#define LIS2DH12_REG_OUT_X_L 0x28
+#define LIS2DH12_REG_OUT_X_H 0x29
+#define LIS2DH12_REG_OUT_Y_L 0x2A
+#define LIS2DH12_REG_OUT_Y_H 0x2B
+#define LIS2DH12_REG_OUT_Z_L 0x2C
+#define LIS2DH12_REG_OUT_Z_H 0x2D
+#define LIS2DH12_REG_FIFO_CTRL 0x2E
+#define LIS2DH12_REG_FIFO_SRC 0x2F
+#define LIS2DH12_REG_INT1_CFG 0x30
+#define LIS2DH12_REG_INT1_SRC 0x31
+#define LIS2DH12_REG_INT1_THS 0x32
+#define LIS2DH12_REG_INT1_DURATION 0x33
+#define LIS2DH12_REG_INT2_CFG 0x34
+#define LIS2DH12_REG_INT2_SRC 0x35
+#define LIS2DH12_REG_INT2_THS 0x36
+#define LIS2DH12_REG_INT2_DURATION 0x37
+#define LIS2DH12_REG_CLICK_CFG 0x38
+#define LIS2DH12_REG_CLICK_SRC 0x39
+#define LIS2DH12_REG_CLICK_THS 0x3A
+#define LIS2DH12_REG_TIME_LIMIT 0x3B
+#define LIS2DH12_REG_TIME_LATENCY 0x3C
+#define LIS2DH12_REG_TIME_WINDOW 0x3D
+#define LIS2DH12_REG_ACT_THS 0x3E
+#define LIS2DH12_REG_ACT_DUR 0x3F
+
+
+/**
+ * @brief Config register defaults.
+ */
+#define LIS2DH12_DEF_CTRL_REG0 0x10
+#define LIS2DH12_DEF_CTRL_REG1 0x07
+
+#define LIS2DH12_BYTES_PER_SAMPLE 6
+#define LIS2DH12_BYTES_PER_TEMP 2
+
+/**
+ * @brief Status reg aux bitmasks.
+ */
+
+// Bitmasks for TOR.
+#define LIS2DH12_TOR_POS 6
+#define LIS2DH12_TOR_MASK (1 << LIS2DH12_TOR_POS)
+
+// Bitmasks for TDA.
+#define LIS2DH12_TDA_POS 2
+#define LIS2DH12_TDA_MASK (1 << LIS2DH12_TDA_POS)
+
+
+/**
+ * @brief Control register 0 bitmasks
+ */
+#define LIS2DH12_CTRL_REG0_VALID_MASK 0x7F
+#define LIS2DH12_CTRL_REG0_VALID_SET 0x10
+
+// Bitmasks for SDO_PU_DISC.
+#define LIS2DH12_SDO_PU_DISC_POS 7
+#define LIS2DH12_SDO_PU_DISC_MASK (1 << LIS2DH12_SDO_PU_DISC_POS)
+
+
+/**
+ * @brief Temp config register bitmasks
+ */
+#define LIS2DH12_TEMP_CONF_VALID_MASK 0x3F
+
+// Bitmasks for TEMP_EN
+#define LIS2DH12_TEMP_EN_POS 6
+#define LIS2DH12_TEMP_EN_MASK (3 << LIS2DH12_TEMP_EN_POS)
+
+
+/**
+ * @brief Control register 1 bitmasks
+ */
+
+// Bitmasks for ODR.
+#define LIS2DH12_ODR_POS 4
+#define LIS2DH12_ODR_MASK (0x0F << LIS2DH12_ODR_POS)
+
+// Bitmasks for LP_EN
+#define LIS2DH12_LP_EN_POS 3
+#define LIS2DH12_LP_EN_MASK (1 << LIS2DH12_LP_EN_POS)
+
+// Bitmasks for Z_EN
+#define LIS2DH12_Z_EN_POS 2
+#define LIS2DH12_Z_EN_MASK (1 << LIS2DH12_Z_EN_POS)
+
+// Bitmasks for Y_EN
+#define LIS2DH12_Y_EN_POS 1
+#define LIS2DH12_Y_EN_MASK (1 << LIS2DH12_Y_EN_POS)
+
+// Bitmasks for X_EN
+#define LIS2DH12_X_EN_POS 0
+#define LIS2DH12_X_EN_MASK (1 << LIS2DH12_X_EN_POS)
+
+
+/**
+ * @brief Control register 2 bitmasks.
+ */
+
+// Bitmasks for HPM.
+#define LIS2DH12_HPM_POS 6
+#define LIS2DH12_HPM_MASK (3 << LIS2DH12_HPM_POS)
+
+// Bitmasks for HPCF.
+#define LIS2DH12_HPCF_POS 4
+#define LIS2DH12_HPCF_MASK (3 << LIS2DH12_HPCF_POS)
+
+// Bitmasks for FDS.
+#define LIS2DH12_FDS_POS 3
+#define LIS2DH12_FDS_MASK (1 << LIS2DH12_FDS_POS)
+
+// Bitmasks for HPCLICK.
+#define LIS2DH12_HP_C_POS 2
+#define LIS2DH12_HP_C_MASK (1 << LIS2DH12_HP_C_POS)
+
+// Bitmasks for HP_IA2.
+#define LIS2DH12_HP_I2_POS 1
+#define LIS2DH12_HP_I2_MASK (1 << LIS2DH12_HP_I2_POS)
+
+// Bitmasks for HP_IA1.
+#define LIS2DH12_HP_I1_POS 0
+#define LIS2DH12_HP_I1_MASK (1 << LIS2DH12_HP_I1_POS)
+
+
+/**
+ * @brief Control register 3 bitmasks.
+ */
+
+// Bitmasks for I1_CLICK.
+#define LIS2DH12_I1_CLICK_POS 7
+#define LIS2DH12_I1_CLICK_MASK (1 << LIS2DH12_I1_CLICK_POS)
+
+// Bitmasks for I1_IA1.
+#define LIS2DH12_I1_IA1_POS 6
+#define LIS2DH12_I1_IA1_MASK (1 << LIS2DH12_I1_IA1_POS)
+
+// Bitmasks for I1_IA2.
+#define LIS2DH12_I1_IA2_POS 5
+#define LIS2DH12_I1_IA2_MASK (1 << LIS2DH12_I1_IA2_POS)
+
+// Bitmasks for I1_ZYXDA.
+#define LIS2DH12_I1_ZYXDA_POS 4
+#define LIS2DH12_I1_ZYXDA_MASK (1 << LIS2DH12_I1_ZYXDA_POS)
+
+// Bitmasks for I1_WTM.
+#define LIS2DH12_I1_WTM_POS 2
+#define LIS2DH12_I1_WTM_MASK (1 << LIS2DH12_I1_WTM_POS)
+
+// Bitmasks for I1_OVERRUN.
+#define LIS2DH12_I1_OVERRUN_POS 1
+#define LIS2DH12_I1_OVERRUN_MASK (1 << LIS2DH12_I1_OVERRUN_POS)
+
+
+/**
+ * @brief Control register 4 bitmasks.
+ */
+
+// Bitmasks for BDU.
+#define LIS2DH12_BDU_POS 7
+#define LIS2DH12_BDU_MASK (1 << LIS2DH12_BDU_POS)
+
+// Bitmasks for BLE.
+#define LIS2DH12_BLE_POS 6
+#define LIS2DH12_BLE_MASK (1 << LIS2DH12_BLE_POS)
+
+// Bitmasks for FS.
+#define LIS2DH12_FS_POS 4
+#define LIS2DH12_FS_MASK (3 << LIS2DH12_FS_POS)
+
+// Bitmasks for HR.
+#define LIS2DH12_HR_POS 3
+#define LIS2DH12_HR_MASK (1 << LIS2DH12_HR_POS)
+
+// Bitmasks for ST.
+#define LIS2DH12_ST_POS 1
+#define LIS2DH12_ST_MASK (3 << LIS2DH12_ST_POS)
+
+// Bitmasks for SIM.
+#define LIS2DH12_SIM_POS 0
+#define LIS2DH12_SIM_MASK (1 << LIS2DH12_SIM_POS)
+
+
+/**
+ * @brief Control register 5 bitmasks.
+ */
+
+// Bitmasks for BOOT.
+#define LIS2DH12_BOOT_POS 7
+#define LIS2DH12_BOOT_MASK (1 << LIS2DH12_BOOT_POS)
+
+// Bitmasks for FIFO_EN.
+#define LIS2DH12_FIFO_EN_POS 6
+#define LIS2DH12_FIFO_EN_MASK (1 << LIS2DH12_FIFO_EN_POS)
+
+// Bitmasks for LIR_INT1.
+#define LIS2DH12_LIR_INT1_POS 3
+#define LIS2DH12_LIR_INT1_MASK (1 << LIS2DH12_LIR_INT1_POS)
+
+// Bitmasks for D4D_INT1.
+#define LIS2DH12_D4D_INT1_POS 2
+#define LIS2DH12_D4D_INT1_MASK (1 << LIS2DH12_D4D_INT1_POS)
+
+// Bitmasks for LIR_INT2.
+#define LIS2DH12_LIR_INT2_POS 1
+#define LIS2DH12_LIR_INT2_MASK (1 << LIS2DH12_LIR_INT2_POS)
+
+// Bitmasks for D4D_INT2.
+#define LIS2DH12_D4D_INT2_POS 0
+#define LIS2DH12_D4D_INT2_MASK (1 << LIS2DH12_D4D_INT2_POS)
+
+
+/**
+ * @brief Control register 6 bitmasks.
+ */
+
+// Bitmasks for I2_CLICK.
+#define LIS2DH12_I2_CLICK_POS 7
+#define LIS2DH12_I2_CLICK_MASK (1 << LIS2DH12_I2_CLICK_POS)
+
+// Bitmasks for I2_IA1.
+#define LIS2DH12_I2_IA1_POS 6
+#define LIS2DH12_I2_IA1_MASK (1 << LIS2DH12_I2_IA1_POS)
+
+// Bitmasks for I2_IA2.
+#define LIS2DH12_I2_IA2_POS 5
+#define LIS2DH12_I2_IA2_MASK (1 << LIS2DH12_I2_IA2_POS)
+
+// Bitmasks for I2_BOOT.
+#define LIS2DH12_I2_BOOT_POS 4
+#define LIS2DH12_I2_BOOT_MASK (1 << LIS2DH12_I2_BOOT_POS)
+
+// Bitmasks for I2_ACT.
+#define LIS2DH12_I2_ACT_POS 3
+#define LIS2DH12_I2_ACT_MASK (1 << LIS2DH12_I2_ACT_POS)
+
+// Bitmasks for INT_POLARITY.
+#define LIS2DH12_INT_POLARITY_POS 1
+#define LIS2DH12_INT_POLARITY_MASK (1 << LIS2DH12_INT_POLARITY_POS)
+
+
+/**
+ * @brief Status register bitmasks.
+ */
+
+// Bitmasks for ZYXOR.
+#define LIS2DH12_ZYXOR_POS 7
+#define LIS2DH12_ZYXOR_MASK (1 << LIS2DH12_ZYXOR_POS)
+
+// Bitmasks for ZOR.
+#define LIS2DH12_ZOR_POS 6
+#define LIS2DH12_ZOR_MASK (1 << LIS2DH12_ZOR_POS)
+
+// Bitmasks for YOR.
+#define LIS2DH12_YOR_POS 5
+#define LIS2DH12_YOR_MASK (1 << LIS2DH12_YOR_POS)
+
+// Bitmasks for XOR.
+#define LIS2DH12_XOR_POS 4
+#define LIS2DH12_XOR_MASK (1 << LIS2DH12_XOR_POS)
+
+// Bitmasks for ZYXDA.
+#define LIS2DH12_ZYXDA_POS 3
+#define LIS2DH12_ZYXDA_MASK (1 << LIS2DH12_ZYXDA_POS)
+
+// Bitmasks for ZDA.
+#define LIS2DH12_ZDA_POS 2
+#define LIS2DH12_ZDA_MASK (1 << LIS2DH12_ZDA_POS)
+
+// Bitmasks for YDA.
+#define LIS2DH12_YDA_POS 1
+#define LIS2DH12_YDA_MASK (1 << LIS2DH12_YDA_POS)
+
+// Bitmasks for XDA.
+#define LIS2DH12_XDA_POS 0
+#define LIS2DH12_XDA_MASK (1 << LIS2DH12_XDA_POS)
+/**
+ * @brief FIFO control register bitmasks.
+ */
+
+// Bitmasks for FM.
+#define LIS2DH12_FM_POS 6
+#define LIS2DH12_FM_MASK (3 << LIS2DH12_FM_POS)
+
+// Bitmasks for TR.
+#define LIS2DH12_TR_POS 5
+#define LIS2DH12_TR_MASK (1 << LIS2DH12_TR_POS)
+
+// Bitmasks for FTH.
+#define LIS2DH12_FTH_POS 0
+#define LIS2DH12_FTH_MASK (0x1F << LIS2DH12_FTH_POS)
+
+
+/**
+ * @brief FIFO source register bitmasks.
+ */
+
+// Bitmasks for WTM.
+#define LIS2DH12_WTM_POS 7
+#define LIS2DH12_WTM_MASK (1 << LIS2DH12_WTM_POS)
+
+// Bitmasks for OVRN_FIFO.
+#define LIS2DH12_OVRN_FIFO_POS 6
+#define LIS2DH12_OVRN_FIFO_MASK (1 << LIS2DH12_OVRN_FIFO_POS)
+
+// Bitmasks for EMPTY.
+#define LIS2DH12_EMPTY_POS 5
+#define LIS2DH12_EMPTY_MASK (1 << LIS2DH12_EMPTY_POS)
+
+// Bitmasks for FSS.
+#define LIS2DH12_FSS_POS 0
+#define LIS2DH12_FSS_MASK (0x1F << LIS2DH12_FSS_POS)
+
+
+/**
+ * @brief Interrupt config register bitmasks.
+ */
+
+// Bitmasks for INT_AOI.
+#define LIS2DH12_INT_AOI_POS 7
+#define LIS2DH12_INT_AOI_MASK (1 << LIS2DH12_INT_AOI_POS)
+
+// Bitmasks for INT_6D.
+#define LIS2DH12_INT_6D_POS 6
+#define LIS2DH12_INT_6D_MASK (1 << LIS2DH12_INT_6D_POS)
+
+// Bitmasks for INT_ZHIE.
+#define LIS2DH12_INT_ZHIE_POS 5
+#define LIS2DH12_INT_ZHIE_MASK (1 << LIS2DH12_INT_ZHIE_POS)
+
+// Bitmasks for INT_ZLIE.
+#define LIS2DH12_INT_ZLIE_POS 4
+#define LIS2DH12_INT_ZLIE_MASK (1 << LIS2DH12_INT_ZLIE_POS)
+
+// Bitmasks for INT_YHIE.
+#define LIS2DH12_INT_YHIE_POS 3
+#define LIS2DH12_INT_YHIE_MASK (1 << LIS2DH12_INT_YHIE_POS)
+
+// Bitmasks for INT_YLIE.
+#define LIS2DH12_INT_YLIE_POS 2
+#define LIS2DH12_INT_YLIE_MASK (1 << LIS2DH12_INT_YLIE_POS)
+
+// Bitmasks for INT_XHIE.
+#define LIS2DH12_INT_XHIE_POS 1
+#define LIS2DH12_INT_XHIE_MASK (1 << LIS2DH12_INT_XHIE_POS)
+
+// Bitmasks for INT_XLIE.
+#define LIS2DH12_INT_XLIE_POS 0
+#define LIS2DH12_INT_XLIE_MASK (1 << LIS2DH12_INT_XLIE_POS)
+
+
+/**
+ * @brief Interrupt source register bitmasks.
+ */
+
+// Bitmasks for IA.
+#define LIS2DH12_INT_IA_POS 6
+#define LIS2DH12_INT_IA_MASK (1 << LIS2DH12_INT_IA_POS)
+
+// Bitmasks for ZH.
+#define LIS2DH12_INT_ZH_POS 5
+#define LIS2DH12_INT_ZH_MASK (1 << LIS2DH12_INT_ZH_POS)
+
+// Bitmasks for ZL.
+#define LIS2DH12_INT_ZL_POS 4
+#define LIS2DH12_INT_ZL_MASK (1 << LIS2DH12_INT_ZL_POS)
+
+// Bitmasks for YH.
+#define LIS2DH12_INT_YH_POS 3
+#define LIS2DH12_INT_YH_MASK (1 << LIS2DH12_INT_YH_POS)
+
+// Bitmasks for YL.
+#define LIS2DH12_INT_YL_POS 2
+#define LIS2DH12_INT_YL_MASK (1 << LIS2DH12_INT_YL_POS)
+
+// Bitmasks for XH.
+#define LIS2DH12_INT_XH_POS 1
+#define LIS2DH12_INT_XH_MASK (1 << LIS2DH12_INT_XH_POS)
+
+// Bitmasks for XL.
+#define LIS2DH12_INT_XL_POS 0
+#define LIS2DH12_INT_XL_MASK (1 << LIS2DH12_INT_XL_POS)
+
+
+/**
+ * @brief Interrupt threshold register bitmasks.
+ */
+
+// Bitmasks for THS.
+#define LIS2DH12_INT_THS_POS 0
+#define LIS2DH12_INT_THS_MASK (0x7F << LIS2DH12_INT_THS_POS)
+
+
+/**
+ * @brief Interrupt duration register bitmasks.
+ */
+
+// Bitmasks for DUR.
+#define LIS2DH12_INT_DUR_POS 0
+#define LIS2DH12_INT_DUR_MASK (0x7F << LIS2DH12_INT_DUR_POS)
+
+
+/**
+ * @brief Click config register bitmasks.
+ */
+
+// Bitmasks for ZD.
+#define LIS2DH12_CLICK_ZD_POS 5
+#define LIS2DH12_CLICK_ZD_MASK (1 << LIS2DH12_CLICK_ZD_POS)
+
+// Bitmasks for ZS.
+#define LIS2DH12_CLICK_ZS_POS 4
+#define LIS2DH12_CLICK_ZS_MASK (1 << LIS2DH12_CLICK_ZS_POS)
+
+// Bitmasks for YD.
+#define LIS2DH12_CLICK_YD_POS 3
+#define LIS2DH12_CLICK_YD_MASK (1 << LIS2DH12_CLICK_YD_POS)
+
+// Bitmasks for YS.
+#define LIS2DH12_CLICK_YS_POS 2
+#define LIS2DH12_CLICK_YS_MASK (1 << LIS2DH12_CLICK_YS_POS)
+
+// Bitmasks for XD.
+#define LIS2DH12_CLICK_XD_POS 1
+#define LIS2DH12_CLICK_XD_MASK (1 << LIS2DH12_CLICK_XD_POS)
+
+// Bitmasks for XS.
+#define LIS2DH12_CLICK_XS_POS 0
+#define LIS2DH12_CLICK_XS_MASK (1 << LIS2DH12_CLICK_XS_POS)
+
+
+/**
+ * @brief Click source register bitmasks.
+ */
+
+// Bitmasks for IA.
+#define LIS2DH12_CLICK_IA_POS 6
+#define LIS2DH12_CLICK_IA_MASK (1 << LIS2DH12_CLICK_IA_POS)
+
+// Bitmasks for DCLICK.
+#define LIS2DH12_CLICK_DCLICK_POS 5
+#define LIS2DH12_CLICK_DCLICK_MASK (1 << LIS2DH12_CLICK_DCLICK_POS)
+
+// Bitmasks for SCLICK.
+#define LIS2DH12_CLICK_SCLICK_POS 4
+#define LIS2DH12_CLICK_SCLICK_MASK (1 << LIS2DH12_CLICK_SCLICK_POS)
+
+// Bitmasks for SIGN.
+#define LIS2DH12_CLICK_SIGN_POS 3
+#define LIS2DH12_CLICK_SIGN_MASK (1 << LIS2DH12_CLICK_SIGN_POS)
+
+// Bitmasks for Z.
+#define LIS2DH12_CLICK_Z_POS 2
+#define LIS2DH12_CLICK_Z_MASK (1 << LIS2DH12_CLICK_Z_POS)
+
+// Bitmasks for Y.
+#define LIS2DH12_CLICK_Y_POS 1
+#define LIS2DH12_CLICK_Y_MASK (1 << LIS2DH12_CLICK_Y_POS)
+
+// Bitmasks for X.
+#define LIS2DH12_CLICK_X_POS 0
+#define LIS2DH12_CLICK_X_MASK (1 << LIS2DH12_CLICK_X_POS)
+
+
+/**
+ * @brief Click threshold register bitmasks.
+ */
+
+// Bitmasks for LIR.
+#define LIS2DH12_CLICK_LIR_POS 7
+#define LIS2DH12_CLICK_LIR_MASK (1 << LIS2DH12_CLICK_LIR_POS)
+
+// Bitmasks for THS.
+#define LIS2DH12_CLICK_THS_POS 0
+#define LIS2DH12_CLICK_THS_MASK (0x7F << LIS2DH12_CLICK_THS_POS)
+
+
+/**
+ * @brief Click time limit register bitmasks.
+ */
+
+// Bitmasks for TLI.
+#define LIS2DH12_CLICK_TLI_POS 0
+#define LIS2DH12_CLICK_TLI_MASK (0x7F << LIS2DH12_CLICK_TLI_POS)
+
+
+/**
+ * @brief Activation threshold register bitmasks.
+ */
+
+// Bitmasks for THS.
+#define LIS2DH12_ACT_THS_POS 0
+#define LIS2DH12_ACT_THS_MASK (0x7F << LIS2DH12_ACT_THS_POS)
+
+/**
+ * @brief Structure holding sensor instance
+ */
+typedef struct
+{
+ nrf_twi_sensor_t * const p_sensor_data;
+ uint8_t const sensor_addr;
+
+ uint8_t ctrl0;
+ uint8_t temp_cfg;
+ uint8_t ctrl1;
+ uint8_t ctrl2;
+ uint8_t ctrl3;
+ uint8_t ctrl4;
+ uint8_t ctrl5;
+ uint8_t ctrl6;
+ uint8_t reference;
+ uint8_t fifo_ctrl;
+ uint8_t int1_cfg;
+ uint8_t int1_ths;
+ uint8_t int1_dur;
+ uint8_t int2_cfg;
+ uint8_t int2_ths;
+ uint8_t int2_dur;
+ uint8_t click_cfg;
+ uint8_t click_ths;
+ uint8_t time_lim;
+ uint8_t latency;
+ uint8_t time_win;
+ uint8_t act_ths;
+ uint8_t act_dur;
+
+} lis2dh12_instance_t;
+
+/**
+ * @brief Macro for defining sensor instance.
+ */
+#define LIS2DH12_INTERNAL_INSTANCE_DEF(_lis2dh12_inst_name, _p_twi_sensor, _sensor_address) \
+ static lis2dh12_instance_t _lis2dh12_inst_name = \
+ { \
+ .p_sensor_data = _p_twi_sensor, \
+ .sensor_addr = _sensor_address \
+ }
+
+
+/**
+ * @brief Macro for setting data acquisition configuration.
+ */
+#define LIS2DH12_INTERNAL_DATA_CFG(_s, _odr, _lp, _z_en, _y_en, _x_en, _scale, _high_res) \
+ NRF_TWI_SENSOR_REG_SET(_s.ctrl1, LIS2DH12_ODR_MASK, LIS2DH12_ODR_POS, _odr); \
+ NRF_TWI_SENSOR_REG_SET(_s.ctrl1, LIS2DH12_LP_EN_MASK, LIS2DH12_LP_EN_POS, _lp); \
+ NRF_TWI_SENSOR_REG_SET(_s.ctrl1, LIS2DH12_Z_EN_MASK, LIS2DH12_Z_EN_POS, _z_en); \
+ NRF_TWI_SENSOR_REG_SET(_s.ctrl1, LIS2DH12_Y_EN_MASK, LIS2DH12_Y_EN_POS, _y_en); \
+ NRF_TWI_SENSOR_REG_SET(_s.ctrl1, LIS2DH12_X_EN_MASK, LIS2DH12_X_EN_POS, _x_en); \
+ NRF_TWI_SENSOR_REG_SET(_s.ctrl4, LIS2DH12_FS_MASK, LIS2DH12_FS_POS, _scale); \
+ NRF_TWI_SENSOR_REG_SET(_s.ctrl4, LIS2DH12_HR_MASK, LIS2DH12_HR_POS, _high_res)
+
+/**
+ * @brief Function for setting filter configuration.
+ */
+#define LIS2DH12_INTERNAL_FILTER_CFG(_s, _mode, _freq, _d_en, _c_en, _i1_en, _i2_en) \
+ NRF_TWI_SENSOR_REG_SET(_s.ctrl2, LIS2DH12_HPM_MASK, LIS2DH12_HPM_POS, _mode); \
+ NRF_TWI_SENSOR_REG_SET(_s.ctrl2, LIS2DH12_HPCF_MASK, LIS2DH12_HPCF_POS, _freq); \
+ NRF_TWI_SENSOR_REG_SET(_s.ctrl2, LIS2DH12_FDS_MASK, LIS2DH12_FDS_POS, _d_en); \
+ NRF_TWI_SENSOR_REG_SET(_s.ctrl2, LIS2DH12_HP_C_MASK, LIS2DH12_HP_C_POS, _c_en); \
+ NRF_TWI_SENSOR_REG_SET(_s.ctrl2, LIS2DH12_HP_I1_MASK, LIS2DH12_HP_I1_POS, _i1_en); \
+ NRF_TWI_SENSOR_REG_SET(_s.ctrl2, LIS2DH12_HP_I2_MASK, LIS2DH12_HP_I2_POS, _i2_en)
+
+/**
+ * @brief Macro for configuring INT1 pin.
+ */
+#define LIS2DH12_INTERNAL_INT1_PIN_CFG(_s, _cl, _ia1, _ia2, _zyxda, _wtm, _ovr, _pol, _d4d) \
+ NRF_TWI_SENSOR_REG_SET(_s.ctrl3, LIS2DH12_I1_CLICK_MASK, LIS2DH12_I1_CLICK_POS, _cl); \
+ NRF_TWI_SENSOR_REG_SET(_s.ctrl3, LIS2DH12_I1_IA1_MASK, LIS2DH12_I1_IA1_POS, _ia1); \
+ NRF_TWI_SENSOR_REG_SET(_s.ctrl3, LIS2DH12_I1_IA2_MASK, LIS2DH12_I1_IA2_POS, _ia2); \
+ NRF_TWI_SENSOR_REG_SET(_s.ctrl3, LIS2DH12_I1_ZYXDA_MASK, LIS2DH12_I1_ZYXDA_POS, _zyxda); \
+ NRF_TWI_SENSOR_REG_SET(_s.ctrl3, LIS2DH12_I1_WTM_MASK, LIS2DH12_I1_WTM_POS, _wtm); \
+ NRF_TWI_SENSOR_REG_SET(_s.ctrl3, LIS2DH12_I1_OVERRUN_MASK, LIS2DH12_I1_OVERRUN_POS, _ovr); \
+ NRF_TWI_SENSOR_REG_SET(_s.ctrl6, LIS2DH12_INT_POLARITY_MASK, LIS2DH12_INT_POLARITY_POS, _pol); \
+ NRF_TWI_SENSOR_REG_SET(_s.ctrl5, LIS2DH12_D4D_INT1_MASK, LIS2DH12_D4D_INT1_POS, _d4d)
+
+/**
+ * @brief Macro for configuring INT2 pin.
+ */
+#define LIS2DH12_INTERNAL_INT2_PIN_CFG(_s, _cl, _ia1, _ia2, _boot, _act, _pol, _d4d) \
+ NRF_TWI_SENSOR_REG_SET(_s.ctrl6, LIS2DH12_I2_CLICK_MASK, LIS2DH12_I2_CLICK_POS, _cl); \
+ NRF_TWI_SENSOR_REG_SET(_s.ctrl6, LIS2DH12_I2_IA1_MASK, LIS2DH12_I2_IA1_POS, _ia1); \
+ NRF_TWI_SENSOR_REG_SET(_s.ctrl6, LIS2DH12_I2_IA2_MASK, LIS2DH12_I2_IA2_POS, _ia2); \
+ NRF_TWI_SENSOR_REG_SET(_s.ctrl6, LIS2DH12_I2_BOOT_MASK, LIS2DH12_I2_BOOT_POS, _boot);\
+ NRF_TWI_SENSOR_REG_SET(_s.ctrl6, LIS2DH12_I2_ACT_MASK, LIS2DH12_I2_ACT_POS, _act); \
+ NRF_TWI_SENSOR_REG_SET(_s.ctrl6, LIS2DH12_INT_POLARITY_MASK, LIS2DH12_INT_POLARITY_POS, _pol); \
+ NRF_TWI_SENSOR_REG_SET(_s.ctrl5, LIS2DH12_D4D_INT2_MASK, LIS2DH12_D4D_INT2_POS, _d4d)
+
+ /**
+ * @brief Macro for configuring interrupt 1.
+ */
+#define LIS2DH12_INTERNAL_INT1_CFG(_s, _thr, _dur, _aoi, _6d, _zh, _zl, _yh, yl, _xh, _xl, _lir) \
+ NRF_TWI_SENSOR_REG_SET(_s.int1_ths, LIS2DH12_INT_THS_MASK, LIS2DH12_INT_THS_POS, _thr); \
+ NRF_TWI_SENSOR_REG_SET(_s.int1_dur, LIS2DH12_INT_DUR_MASK, LIS2DH12_INT_DUR_POS, _dur); \
+ NRF_TWI_SENSOR_REG_SET(_s.int1_cfg, LIS2DH12_INT_AOI_MASK, LIS2DH12_INT_AOI_POS, _aoi); \
+ NRF_TWI_SENSOR_REG_SET(_s.int1_cfg, LIS2DH12_INT_6D_MASK, LIS2DH12_INT_6D_POS, _6d); \
+ NRF_TWI_SENSOR_REG_SET(_s.int1_cfg, LIS2DH12_INT_ZHIE_MASK, LIS2DH12_INT_ZHIE_POS, _zh); \
+ NRF_TWI_SENSOR_REG_SET(_s.int1_cfg, LIS2DH12_INT_ZLIE_MASK, LIS2DH12_INT_ZLIE_POS, _zl); \
+ NRF_TWI_SENSOR_REG_SET(_s.int1_cfg, LIS2DH12_INT_YHIE_MASK, LIS2DH12_INT_YHIE_POS, _yh); \
+ NRF_TWI_SENSOR_REG_SET(_s.int1_cfg, LIS2DH12_INT_YLIE_MASK, LIS2DH12_INT_YLIE_POS, _yl); \
+ NRF_TWI_SENSOR_REG_SET(_s.int1_cfg, LIS2DH12_INT_XHIE_MASK, LIS2DH12_INT_XHIE_POS, _xh); \
+ NRF_TWI_SENSOR_REG_SET(_s.int1_cfg, LIS2DH12_INT_XLIE_MASK, LIS2DH12_INT_XLIE_POS, _xl); \
+ NRF_TWI_SENSOR_REG_SET(_s.ctrl5, LIS2DH12_LIR_INT1_MASK, LIS2DH12_LIR_INT1_POS, _lir)
+
+
+/**
+ * @brief Macro for configuring interrupt 2.
+ */
+#define LIS2DH12_INTERNAL_INT2_CFG(_s, _thr, _dur, _aoi, _6d, _zh, _zl, _yh, yl, _xh, _xl, _lir) \
+ NRF_TWI_SENSOR_REG_SET(_s.int2_ths, LIS2DH12_INT_THS_MASK, LIS2DH12_INT_THS_POS, _thr); \
+ NRF_TWI_SENSOR_REG_SET(_s.int2_dur, LIS2DH12_INT_DUR_MASK, LIS2DH12_INT_DUR_POS, _dur); \
+ NRF_TWI_SENSOR_REG_SET(_s.int2_cfg, LIS2DH12_INT_AOI_MASK, LIS2DH12_INT_AOI_POS, _aoi); \
+ NRF_TWI_SENSOR_REG_SET(_s.int2_cfg, LIS2DH12_INT_6D_MASK, LIS2DH12_INT_6D_POS, _6d); \
+ NRF_TWI_SENSOR_REG_SET(_s.int2_cfg, LIS2DH12_INT_ZHIE_MASK, LIS2DH12_INT_ZHIE_POS, _zh); \
+ NRF_TWI_SENSOR_REG_SET(_s.int2_cfg, LIS2DH12_INT_ZLIE_MASK, LIS2DH12_INT_ZLIE_POS, _zl); \
+ NRF_TWI_SENSOR_REG_SET(_s.int2_cfg, LIS2DH12_INT_YHIE_MASK, LIS2DH12_INT_YHIE_POS, _yh); \
+ NRF_TWI_SENSOR_REG_SET(_s.int2_cfg, LIS2DH12_INT_YLIE_MASK, LIS2DH12_INT_YLIE_POS, _yl); \
+ NRF_TWI_SENSOR_REG_SET(_s.int2_cfg, LIS2DH12_INT_XHIE_MASK, LIS2DH12_INT_XHIE_POS, _xh); \
+ NRF_TWI_SENSOR_REG_SET(_s.int2_cfg, LIS2DH12_INT_XLIE_MASK, LIS2DH12_INT_XLIE_POS, _xl); \
+ NRF_TWI_SENSOR_REG_SET(_s.ctrl5, LIS2DH12_LIR_INT2_MASK, LIS2DH12_LIR_INT2_POS, _lir)
+
+/**
+ * @brief Function for setting click configuration.
+ */
+#define LIS2DH12_INTERNAL_CLICK_CFG(_s, _zd, _zs, _yd, _ys, _xd, _xs, _lir, _ths, _lim, _ltc, _win) \
+ NRF_TWI_SENSOR_REG_SET(_s.click_cfg, LIS2DH12_CLICK_ZD_MASK, LIS2DH12_CLICK_ZD_POS, _zd); \
+ NRF_TWI_SENSOR_REG_SET(_s.click_cfg, LIS2DH12_CLICK_ZS_MASK, LIS2DH12_CLICK_ZD_POS, _zd); \
+ NRF_TWI_SENSOR_REG_SET(_s.click_cfg, LIS2DH12_CLICK_YD_MASK, LIS2DH12_CLICK_YD_POS, _yd); \
+ NRF_TWI_SENSOR_REG_SET(_s.click_cfg, LIS2DH12_CLICK_YS_MASK, LIS2DH12_CLICK_YS_POS, _ys); \
+ NRF_TWI_SENSOR_REG_SET(_s.click_cfg, LIS2DH12_CLICK_XD_MASK, LIS2DH12_CLICK_XD_POS, _xd); \
+ NRF_TWI_SENSOR_REG_SET(_s.click_cfg, LIS2DH12_CLICK_XS_MASK, LIS2DH12_CLICK_XS_POS, _xs); \
+ NRF_TWI_SENSOR_REG_SET(_s.click_ths, LIS2DH12_CLICK_LIR_MASK, LIS2DH12_CLICK_LIR_POS, _lir); \
+ NRF_TWI_SENSOR_REG_SET(_s.click_ths, LIS2DH12_CLICK_THS_MASK, LIS2DH12_CLICK_THS_POS, _ths); \
+ NRF_TWI_SENSOR_REG_SET(_s.time_lim, LIS2DH12_CLICK_TLI_MASK, LIS2DH12_CLICK_TLI_POS, _lim); \
+ _s.latency = _ltc; \
+ _s.time_win = _win
+
+ /**
+ * @brief Macro for setting sleep configuration.
+ */
+#define LIS2DH12_INTERNAL_SLEEP_CFG(_s, _ths, _dur) \
+ NRF_TWI_SENSOR_REG_SET(_s.act_ths, LIS2DH12_ACT_THS_MASK, LIS2DH12_ACT_THS_POS, _ths); \
+ _s.act_dur = _dur
+
+/**
+ * @brief Macro for setting reference value for interrupt generation.
+ */
+#define LIS2DH12_INTERNAL_REF_SET(_s, _ref) \
+ _s.reference = _ref
+
+
+/**
+ * @brief Macro for setting FIFO configuration.
+ */
+#define LIS2DH12_INTERNAL_FIFO_CFG(_s, _en, _mode, _t_sel, _t_thr) \
+ NRF_TWI_SENSOR_REG_SET(_s.fifo_ctrl, LIS2DH12_FM_MASK, LIS2DH12_FM_POS, _mode); \
+ NRF_TWI_SENSOR_REG_SET(_s.fifo_ctrl, LIS2DH12_TR_MASK, LIS2DH12_TR_POS, _t_sel); \
+ NRF_TWI_SENSOR_REG_SET(_s.fifo_ctrl, LIS2DH12_FTH_MASK, LIS2DH12_FTH_POS, _t_thr); \
+ NRF_TWI_SENSOR_REG_SET(_s.ctrl5, LIS2DH12_FIFO_EN_MASK, LIS2DH12_FIFO_EN_POS, _en)
+
+
+#ifndef SUPPRESS_INLINE_IMPLEMENTATION
+
+__STATIC_INLINE ret_code_t lis2dh12_temp_status_read(lis2dh12_instance_t * p_inst,
+ nrf_twi_sensor_reg_cb_t user_cb,
+ uint8_t * p_data)
+{
+ ASSERT(p_inst != NULL);
+ return nrf_twi_sensor_reg_read(p_inst->p_sensor_data,
+ p_inst->sensor_addr,
+ LIS2DH12_REG_STATUS_AUX,
+ user_cb,
+ p_data,
+ 1);
+}
+
+__STATIC_INLINE ret_code_t lis2dh12_who_am_i_read(lis2dh12_instance_t * p_inst,
+ nrf_twi_sensor_reg_cb_t user_cb,
+ uint8_t * p_data)
+{
+ ASSERT(p_inst != NULL);
+ return nrf_twi_sensor_reg_read(p_inst->p_sensor_data,
+ p_inst->sensor_addr,
+ LIS2DH12_REG_WHO_AM_I,
+ user_cb,
+ p_data,
+ 1);
+}
+
+__STATIC_INLINE ret_code_t lis2dh12_status_read(lis2dh12_instance_t * p_inst,
+ nrf_twi_sensor_reg_cb_t user_cb,
+ uint8_t * p_data)
+{
+ ASSERT(p_inst != NULL);
+ return nrf_twi_sensor_reg_read(p_inst->p_sensor_data,
+ p_inst->sensor_addr,
+ LIS2DH12_REG_STATUS,
+ user_cb,
+ p_data,
+ 1);
+}
+
+__STATIC_INLINE ret_code_t lis2dh12_fifo_src_read(lis2dh12_instance_t * p_inst,
+ nrf_twi_sensor_reg_cb_t user_cb,
+ uint8_t * p_data)
+{
+ ASSERT(p_inst != NULL);
+ return nrf_twi_sensor_reg_read(p_inst->p_sensor_data,
+ p_inst->sensor_addr,
+ LIS2DH12_REG_FIFO_SRC,
+ user_cb,
+ p_data,
+ 1);
+}
+
+__STATIC_INLINE ret_code_t lis2dh12_int1_src_read(lis2dh12_instance_t * p_inst,
+ nrf_twi_sensor_reg_cb_t user_cb,
+ uint8_t * p_data)
+{
+ ASSERT(p_inst != NULL);
+ return nrf_twi_sensor_reg_read(p_inst->p_sensor_data,
+ p_inst->sensor_addr,
+ LIS2DH12_REG_INT1_SRC,
+ user_cb,
+ p_data,
+ 1);
+}
+
+__STATIC_INLINE ret_code_t lis2dh12_int2_src_read(lis2dh12_instance_t * p_inst,
+ nrf_twi_sensor_reg_cb_t user_cb,
+ uint8_t * p_data)
+{
+ ASSERT(p_inst != NULL);
+ return nrf_twi_sensor_reg_read(p_inst->p_sensor_data,
+ p_inst->sensor_addr,
+ LIS2DH12_REG_INT2_SRC,
+ user_cb,
+ p_data,
+ 1);
+}
+
+__STATIC_INLINE ret_code_t lis2dh12_click_src_read(lis2dh12_instance_t * p_inst,
+ nrf_twi_sensor_reg_cb_t user_cb,
+ uint8_t * p_data)
+{
+ ASSERT(p_inst != NULL);
+ return nrf_twi_sensor_reg_read(p_inst->p_sensor_data,
+ p_inst->sensor_addr,
+ LIS2DH12_REG_CLICK_SRC,
+ user_cb,
+ p_data,
+ 1);
+}
+
+#endif //SUPPRESS_INLINE_IMPLEMENTATION
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // LIS2DH12_INTERNAL_H
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/drivers_ext/lps22hb/lps22hb.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/drivers_ext/lps22hb/lps22hb.c
new file mode 100644
index 0000000..8dee20a
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/drivers_ext/lps22hb/lps22hb.c
@@ -0,0 +1,320 @@
+/**
+ * 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+
+#include "lps22hb.h"
+
+ret_code_t lps22hb_init(lps22hb_instance_t * p_instance)
+{
+ ASSERT(p_instance != NULL);
+ p_instance->interrupt_cfg = 0;
+ p_instance->ctrl_reg[0] = 0;
+ p_instance->ctrl_reg[1] = LPS22HB_CTRL_REG2_DEFAULT;
+ p_instance->ctrl_reg[2] = 0;
+ p_instance->fifo_ctrl = 0;
+ ret_code_t err_code;
+ if (p_instance->p_sensor_data->p_twi_mngr->p_queue->size < LPS22HB_MIN_QUEUE_SIZE)
+ {
+ return NRF_ERROR_INVALID_LENGTH;
+ }
+
+ err_code = lps22hb_cfg_commit(p_instance);
+ return err_code;
+}
+
+ret_code_t lps22hb_autorifp_enable(lps22hb_instance_t * p_instance, bool enable)
+{
+ ASSERT(p_instance != NULL);
+ uint8_t reg = p_instance->interrupt_cfg;
+ if (enable == true)
+ {
+ NRF_TWI_SENSOR_REG_SET(reg, LPS22HB_AUTORIFP_MASK, LPS22HB_AUTORIFP_POS, 1);
+ }
+ else
+ {
+ NRF_TWI_SENSOR_REG_SET(reg, LPS22HB_RESET_ARP_MASK, LPS22HB_RESET_ARP_POS, 1);
+ }
+ uint8_t send_msg[] = {
+ LPS22HB_REG_INTERRUPT_CONFIG,
+ reg
+ };
+ return nrf_twi_sensor_write(p_instance->p_sensor_data,
+ p_instance->sensor_addr,
+ send_msg,
+ ARRAY_SIZE(send_msg),
+ true);
+}
+
+ret_code_t lps22hb_autozero_enable(lps22hb_instance_t * p_instance, bool enable)
+{
+ ASSERT(p_instance != NULL);
+ uint8_t reg = p_instance->interrupt_cfg;
+ if (enable == true)
+ {
+ NRF_TWI_SENSOR_REG_SET(reg, LPS22HB_AUTOZERO_MASK, LPS22HB_AUTOZERO_POS, 1);
+ }
+ else
+ {
+ NRF_TWI_SENSOR_REG_SET(reg, LPS22HB_RESET_AZ_MASK, LPS22HB_RESET_AZ_POS, 1);
+ }
+ uint8_t send_msg[] = {
+ LPS22HB_REG_INTERRUPT_CONFIG,
+ reg
+ };
+ return nrf_twi_sensor_write(p_instance->p_sensor_data,
+ p_instance->sensor_addr,
+ send_msg,
+ ARRAY_SIZE(send_msg),
+ true);
+}
+
+
+void lps22hb_data_rate_set(lps22hb_instance_t * p_instance, lps22hb_odr_t odr)
+{
+ ASSERT(p_instance != NULL);
+ NRF_TWI_SENSOR_REG_SET(p_instance->ctrl_reg[0], LPS22HB_ODR_MASK, LPS22HB_ODR_POS, odr);
+}
+
+ret_code_t lps22hb_data_read(lps22hb_instance_t * p_instance,
+ lps22hb_data_callback_t user_callback,
+ lps22hb_data_t * p_out_data,
+ uint8_t samples)
+{
+ ASSERT(p_instance != NULL);
+ ret_code_t err_code;
+ err_code = nrf_twi_sensor_reg_read(p_instance->p_sensor_data,
+ p_instance->sensor_addr,
+ LPS22HB_REG_PRESS_OUT_XL,
+ (nrf_twi_sensor_reg_cb_t) user_callback,
+ (uint8_t *) p_out_data,
+ samples * LPS22HB_BYTES_PER_SAMPLE);
+ return err_code;
+}
+
+void lps22hb_data_decode(lps22hb_data_t * p_data, uint8_t samples)
+{
+ ASSERT(p_data != NULL);
+ lps22hb_raw_data_t * p_in_data = (lps22hb_raw_data_t *) p_data;
+ uint32_t pres;
+ uint16_t temp;
+ for (int i = samples-1; i >= 0; i--)
+ {
+ pres = ((uint32_t) p_in_data[i].press_out_xl) |
+ (((uint32_t) p_in_data[i].press_out_l) << 8) |
+ (((uint32_t) p_in_data[i].press_out_h) << 16);
+ pres <<= 8;
+ temp = ((uint16_t) p_in_data[i].temp_out_l) |
+ (((uint16_t) p_in_data[i].temp_out_h) << 8);
+ // Dividing by 256 because signed integer can't be shifted by 8
+ p_data[i].pressure = *((int32_t *) &pres) / 256;
+ p_data[i].temperature = *((int16_t *) &temp);
+ }
+}
+
+ret_code_t lps22hb_threshold_set(lps22hb_instance_t * p_instance, uint16_t thr)
+{
+ ASSERT(p_instance != NULL);
+ thr *= 16;
+ uint8_t send_msg[] = {
+ LPS22HB_REG_THS_P_L,
+ thr & 0x00FFU,
+ thr >> 8
+ };
+ ret_code_t err_code;
+ err_code = nrf_twi_sensor_write(p_instance->p_sensor_data,
+ p_instance->sensor_addr,
+ send_msg,
+ ARRAY_SIZE(send_msg),
+ true);
+ return err_code;
+}
+
+ret_code_t lps22hb_ref_pressure_set(lps22hb_instance_t * p_instance, int32_t pressure)
+{
+ ASSERT(p_instance != NULL);
+ // Multiplying by 256 because signed integer can't be shifted by 8
+ pressure *= 256;
+ uint32_t pres = *((uint32_t *) &pressure);
+ pres >>= 8;
+ uint8_t send_msg[] = {
+ LPS22HB_REG_REF_P_XL,
+ pres & 0x00FFU,
+ (pres >> 8) & 0x00FFU,
+ (pres >> 16) & 0x00FFU
+ };
+ ret_code_t err_code;
+ err_code = nrf_twi_sensor_write(p_instance->p_sensor_data,
+ p_instance->sensor_addr,
+ send_msg,
+ ARRAY_SIZE(send_msg),
+ true);
+ return err_code;
+}
+
+ret_code_t lps22hb_offset_set(lps22hb_instance_t * p_instance, int16_t offset)
+{
+ ASSERT(p_instance != NULL);
+ offset *= 16;
+ uint16_t off = *((uint16_t *) &offset);
+ uint8_t send_msg[] = {
+ LPS22HB_REG_RPDS_L,
+ off & 0x00FFU,
+ off >> 8
+ };
+ ret_code_t err_code;
+ err_code = nrf_twi_sensor_write(p_instance->p_sensor_data,
+ p_instance->sensor_addr,
+ send_msg,
+ ARRAY_SIZE(send_msg),
+ true);
+ return err_code;
+}
+
+
+
+ret_code_t lps22hb_cfg_commit(lps22hb_instance_t * p_instance)
+{
+ ASSERT(p_instance != NULL);
+ p_instance->ctrl_reg[1] |= LPS22HB_CTRL_REG2_DEFAULT;
+ p_instance->ctrl_reg[0] &= ~LPS22HB_CTRL1_VALID_MASK;
+ p_instance->ctrl_reg[1] &= ~LPS22HB_CTRL2_VALID_MASK;
+
+ ret_code_t err_code;
+
+ err_code = nrf_twi_sensor_reg_write(p_instance->p_sensor_data,
+ p_instance->sensor_addr,
+ LPS22HB_REG_INTERRUPT_CONFIG,
+ &p_instance->interrupt_cfg,
+ 1);
+ if (err_code != NRF_SUCCESS)
+ {
+ return err_code;
+ }
+ err_code = nrf_twi_sensor_reg_write(p_instance->p_sensor_data,
+ p_instance->sensor_addr,
+ LPS22HB_REG_CTRL1,
+ p_instance->ctrl_reg,
+ 3);
+ if (err_code != NRF_SUCCESS)
+ {
+ return err_code;
+ }
+ err_code = nrf_twi_sensor_reg_write(p_instance->p_sensor_data,
+ p_instance->sensor_addr,
+ LPS22HB_REG_FIFO_CTRL,
+ &p_instance->fifo_ctrl,
+ 1);
+ return err_code;
+}
+
+ret_code_t lps22hb_sw_reset(lps22hb_instance_t * p_instance)
+{
+ ASSERT(p_instance != NULL);
+ uint8_t reg_val = p_instance->ctrl_reg[1];
+ NRF_TWI_SENSOR_REG_SET(reg_val, LPS22HB_SWRESET_MASK, LPS22HB_SWRESET_POS, 1);
+
+ uint8_t send_msg[] = {
+ LPS22HB_REG_CTRL2,
+ reg_val
+ };
+ ret_code_t err_code;
+ err_code = nrf_twi_sensor_write(p_instance->p_sensor_data,
+ p_instance->sensor_addr,
+ send_msg,
+ ARRAY_SIZE(send_msg),
+ true);
+
+ return err_code;
+}
+
+ret_code_t lps22hb_boot(lps22hb_instance_t * p_instance)
+{
+ ASSERT(p_instance != NULL);
+ uint8_t reg_val = p_instance->ctrl_reg[1];
+ NRF_TWI_SENSOR_REG_SET(reg_val, LPS22HB_BOOT_MASK, LPS22HB_BOOT_POS, 1);
+
+ uint8_t send_msg[] = {
+ LPS22HB_REG_CTRL2,
+ reg_val
+ };
+ ret_code_t err_code;
+ err_code = nrf_twi_sensor_write(p_instance->p_sensor_data,
+ p_instance->sensor_addr,
+ send_msg,
+ ARRAY_SIZE(send_msg),
+ true);
+
+ return err_code;
+}
+
+ret_code_t lps22hb_oneshot(lps22hb_instance_t * p_instance)
+{
+ ASSERT(p_instance != NULL);
+ uint8_t reg_val = p_instance->ctrl_reg[1];
+ NRF_TWI_SENSOR_REG_SET(reg_val, LPS22HB_ONE_SHOT_MASK, LPS22HB_ONE_SHOT_POS, 1);
+
+ uint8_t send_msg[] = {
+ LPS22HB_REG_CTRL2,
+ reg_val
+ };
+ ret_code_t err_code;
+ err_code = nrf_twi_sensor_write(p_instance->p_sensor_data,
+ p_instance->sensor_addr,
+ send_msg,
+ ARRAY_SIZE(send_msg),
+ true);
+
+ return err_code;
+}
+
+ret_code_t lps22hb_low_power_enable(lps22hb_instance_t * p_instance, bool enable)
+{
+ ASSERT(p_instance != NULL);
+ uint8_t send_msg[] = {
+ LPS22HB_REG_RES_CONF,
+ enable
+ };
+ ret_code_t err_code;
+ err_code = nrf_twi_sensor_write(p_instance->p_sensor_data,
+ p_instance->sensor_addr,
+ send_msg,
+ ARRAY_SIZE(send_msg),
+ true);
+ return err_code;
+}
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/drivers_ext/lps22hb/lps22hb.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/drivers_ext/lps22hb/lps22hb.h
new file mode 100644
index 0000000..c61ee6a
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/drivers_ext/lps22hb/lps22hb.h
@@ -0,0 +1,512 @@
+/**
+ * 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+
+#ifndef LPS22HB_H
+#define LPS22HB_H
+
+#include "nrf_twi_sensor.h"
+#include "lps22hb_internal.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @brief Possible sensor addresses.
+ */
+#define LPS22HB_BASE_ADDRESS_LOW 0x5CU
+#define LPS22HB_BASE_ADDRESS_HIGH 0x5DU
+
+// WHO_AM_I register value
+#define LPS22HB_WHO_AM_I 0xB1
+
+// Minimum nrf_twi_sensor message buffer size and nrf_twi_mngr queue length.
+#define LPS22HB_MIN_QUEUE_SIZE 4
+
+/**
+ * @brief Sensor driver usage.
+ *
+ * Sensor instance has to be defined first in global context using @ref LPS22HB_INSTANCE DEF.
+ * After that it has to be initialized using @ref lps22hb_init.
+ * At this point sensor instance is ready and all other functions can be used.
+ *
+ * There are two ways in which sensor settings are set:
+ *
+ * First one are asynchronous macros, using them does not change real sensor settings
+ * until @ref lps22hb_cfg_commit is called.
+ * Example:
+ * LPS22HB_DATA_CFG(m_sensor1, LPS22HB_ODR_POWERDOWN, false, false);
+ * LPS22HB_FIFO_CFG(m_sensor1, LPS22HB_STREAM, true, false, 15);
+ * lps22hb_cfg_commit(&m_sensor1);
+ *
+ * Second way are functions, functions schedule TWI operation using @ref nrf_twi_sensor module.
+ * After calling function, setting will be automatically send to sensor when TWI bus is free.
+ * Example:
+ * lps22hb_low_power_enable(&m_sensor1, true);
+ * lps22hb_offset_set(&m_sensor1, -27);
+ *
+ * There are designated functions to read status sensor registers e.g. @ref lps22hb_int_source_read
+ * As parameters they receive function to be called after register is read, and pointer where
+ * register value should be stored. From that value specific parameters can be extracted
+ * using @ref NRF_TWI_SENSOR_REG_VAL_GET macro.
+ * Example:
+ * uint8_t ia = NRF_TWI_SENSOR_REG_VAL_GET(int_source_reg, LPS22HB_IA_MASK, LPS22HB_IA_POS);
+ *
+ * Other functions are self-explanatory or have description on their usage.
+ */
+
+
+/**
+ * @brief Output data rate settings.
+ */
+typedef enum
+{
+ LPS22HB_ODR_POWERDOWN,
+ LPS22HB_ODR_1HZ,
+ LPS22HB_ODR_10HZ,
+ LPS22HB_ODR_25HZ,
+ LPS22HB_ODR_50HZ,
+ LPS22HB_ODR_75HZ
+} lps22hb_odr_t;
+
+/**
+ * @brief Fifo mode settings.
+ */
+typedef enum
+{
+ LPS22HB_BYPASS,
+ LPS22HB_FIFO,
+ LPS22HB_STREAM,
+ LPS22HB_STREAM_TO_FIFO,
+ LPS22HB_BYPASS_TO_STREAM,
+ LPS22HB_RESERVED_FIFO,
+ LPS22HB_DYNAMIC_STREAM,
+ LPS22HB_BYPASS_TO_FIFO
+} lps22hb_fifo_mode_t;
+
+/**
+ * @brief Low pass filter configuration.
+ */
+typedef enum
+{
+ LPS22HB_LPFP_DISABLE = 1,
+ LPS22HB_LPFP_ODR_DIV_9,
+ LPS22HB_LPFP_ODR_DIV_20
+} lps22hb_lpfp_t;
+
+/**
+ * @brief Pressure and temperature output data.
+ *
+ * @note To get pressure in hPa it has to be divided by 4096.
+ * To get temperature in degrees it has to be divided by 100.
+ */
+typedef struct
+{
+ int32_t pressure;
+ int16_t temperature;
+} lps22hb_data_t;
+
+/**
+ * @brief Data callback prototype.
+ *
+ * @param[in] result Result of operation (NRF_SUCCESS on success,
+ * otherwise a relevant error code).
+ * @param[in] p_raw_data Pointer to raw sensor data structure.
+ */
+
+typedef void (* lps22hb_data_callback_t)(ret_code_t result, lps22hb_data_t * p_raw_data);
+
+
+/**
+ * @brief Macro creating lps22hb sensor instance.
+ *
+ * @param[in] _lps22hb_inst_name Sensor instance name.
+ * @param[in] _p_twi_sensor Pointer to common TWI sensor instance.
+ * @param[in] _sensor_address Sensor base address.
+ */
+#define LPS22HB_INSTANCE_DEF(_lps22hb_inst_name, _p_twi_sensor, _sensor_address) \
+ LPS22HB_INTERNAL_INSTANCE_DEF(_lps22hb_inst_name, _p_twi_sensor, _sensor_address)
+
+/**
+ * ===============================================================================================
+ * @brief Sensor configuration macros.
+ *
+ * @note After setting configuration using these macros, it has to be committed to sensor
+ * using @ref lps22hb_cfg_commit
+ */
+
+/**
+ * @brief Macro for interrupt configuration.
+ *
+ * @param[in] _s Sensor instance.
+ * @param[in] _diff_en Enable interrupt generation. True if enabled.
+ * @param[in] _lir Latch interrupt request to INT_SOURCE register. True if enabled.
+ * @param[in] _ple Enable interrupt generation on pressure low event. True if enabled.
+ * @param[in] _phe Enable interrupt generation on pressure high event. True if enabled.
+ */
+#define LPS22HB_INT_CFG(_s, _diff_en, _lir, _ple, _phe)\
+ LPS22HB_INTERNAL_INT_CFG(_s, _diff_en, _lir, _ple, _phe)
+/**
+ * @brief Macro for data acquisition configuration.
+ *
+ * @param[in] _s Sensor instance.
+ * @param[in] _odr Desired output data rate. @ref lps22hb_odr_t
+ * @param[in] _f_en Enables filter. True if enabled.
+ * @param[in] _f_cfg Filter configuration.
+ * @arg true Filter bandwidth is ODR/20
+ * @arg false Filter bandwidth is ODR/9
+ */
+#define LPS22HB_DATA_CFG(_s, _odr, _f_en, _f_cfg)\
+ LPS22HB_INTERNAL_DATA_CFG(_s, _odr, _f_en, _f_cfg)
+
+/**
+ * @brief Macro for FIFO configuration.
+ *
+ * @param[in] _s Sensor instance.
+ * @param[in] _f_mode FIFO mode. @ref lps22hb_fifo_mode_t
+ * @param[in] _f_en Enable FIFO. True if enabled.
+ * @param[in] _f_stop Stop on FIFO watermark. True if enabled.
+ * @param[in] _f_wtm FIFO watermark value. Between 0 and 31.
+ *
+ * @return Return error code from nrf_twi_sensor @ref nrf_twi_sensor_write
+ */
+#define LPS22HB_FIFO_CFG(_s, _f_mode, _f_en, _f_stop, _f_wtm)\
+ LPS22HB_INTERNAL_FIFO_CFG(_s, _f_mode, _f_en, _f_stop, _f_wtm)
+
+/**
+ * @brief Macro for INT_DRDY pin configuration.
+ * @param[in] _s Sensor instance.
+ * @param[in] _activ Active state.
+ * @arg true Active low.
+ * @arg false Active high.
+ * @param[in] _pp_od Pin operation.
+ * @arg true Open drain.
+ * @arg false Push-pull.
+ * @param[in] _fss FIFO full flag. True if enabled.
+ * @param[in] _fth FIFO watermark status. True if enabled.
+ * @param[in] _ovr FIFO overrun interrupt. True if enabled.
+ * @param[in] _drdy Data Ready signal. True if enabled.
+ * @param[in] _high Pressure higher than interrupt threshold. True if enabled.
+ * @param[in] _low Pressure lower than interrupt threshold. True if enabled.
+ */
+#define LPS22HB_DRDY_CFG(_s, _activ, _pp_od, _fss, _fth, _ovr, _drdy, _high, _low)\
+ LPS22HB_INTERNAL_DRDY_CFG(_s, _activ, _pp_od, _fss, _fth, _ovr, _drdy, _high, _low)
+/**
+ * ===============================================================================================
+ */
+
+
+/**
+ * @brief Function for initializing lps22hb sensor.
+ *
+ * Writes configuration data in sensor instance to sensor.
+ *
+ * @param[in] p_instance Pointer to sensor instance created by macro
+ *
+ * @return Return error code from nrf_twi_sensor @ref nrf_twi_sensor_write
+ */
+ret_code_t lps22hb_init(lps22hb_instance_t * p_instance);
+
+/**
+ * @brief Function for enabling autorifp.
+ *
+ * @param[in] p_instance Pointer to sensor instance
+ * @param[in] enable Autorifp setting.
+ * @arg true Autorifp is enabled.
+ * @arg false Autorifp is disabled and reset.
+ *
+ * @return Return error code from nrf_twi_sensor @ref nrf_twi_sensor_write
+ */
+ret_code_t lps22hb_autorifp_enable(lps22hb_instance_t * p_instance, bool enable);
+
+/**
+ * @brief Function for enabling autozero.
+ *
+ * @param[in] p_instance Pointer to sensor instance
+ * @param[in] enable Autozero setting.
+ * @arg true Autozero is enabled.
+ * @arg false Autozero is disabled and reset.
+ *
+ * @return Return error code from nrf_twi_sensor @ref nrf_twi_sensor_write
+ */
+ret_code_t lps22hb_autozero_enable(lps22hb_instance_t * p_instance, bool enable);
+
+/**
+ * @brief Function performing software reset.
+ *
+ * @param[in] p_instance Pointer to sensor instance.
+ *
+ * @return Return error code from nrf_twi_sensor @ref nrf_twi_sensor_write
+ */
+ret_code_t lps22hb_sw_reset(lps22hb_instance_t * p_instance);
+
+/**
+ * @brief Function performing boot.
+ *
+ * @param[in] p_instance Pointer to sensor instance.
+ *
+ * @return Return error code from nrf_twi_sensor @ref nrf_twi_sensor_write
+ */
+ret_code_t lps22hb_boot(lps22hb_instance_t * p_instance);
+
+/**
+ * @brief Function setting oneshot.
+ *
+ * @param[in] p_instance Pointer to sensor instance.
+ *
+ * @return Return error code from nrf_twi_sensor @ref nrf_twi_sensor_write
+ */
+ret_code_t lps22hb_oneshot(lps22hb_instance_t * p_instance);
+
+/**
+ * @brief Function for reading pressure and temperature data.
+ *
+ * @param[in] p_instance Pointer to sensor instance.
+ * @param[in] user_callback Function to be called when data is gathered.
+ * @param[out] p_out_data Pointer to raw data buffer.
+ * @param[in] samples Number of data samples to read.
+ *
+ * @note Data can be read in two ways. With or without sensors FIFO.
+ * FIFO mode depends on FIFO mode set using lps22hb_fifo_mode_set function.
+ * FIFO is enabled using lps22hb_fifo_enable function.
+ * Without FIFO only one sample can be acquired, p_out_data can be pointer to single variable.
+ * With FIFO enabled, data can be read in burst mode, p_out_data table has to be same
+ * or bigger than number of samples to read.
+ *
+ * @return Return error code from nrf_twi_sensor @ref nrf_twi_sensor_reg_read
+ */
+ret_code_t lps22hb_data_read(lps22hb_instance_t * p_instance,
+ lps22hb_data_callback_t user_callback,
+ lps22hb_data_t * p_out_data,
+ uint8_t samples);
+
+/**
+ * @brief Function for converting raw sensor data to real.
+ *
+ * @param[in/out] p_data Pointer to data to be processed.
+ * @param[in] samples Number of samples to be processed.
+ *
+ * @note After data is processed, structure contains pressure in hPa*4096
+ * and temperature in Celsius degrees*100
+ */
+void lps22hb_data_decode(lps22hb_data_t * p_data, uint8_t samples);
+
+/**
+ * @brief Function for setting reference pressure.
+ *
+ * @param[in] p_instance Pointer to sensor instance.
+ * @param[in] pressure Reference pressure in hPa*4096
+ *
+ * @return Return error code from nrf_twi_sensor @ref nrf_twi_sensor_write
+ */
+ret_code_t lps22hb_ref_pressure_set(lps22hb_instance_t * p_instance, int32_t pressure);
+
+/**
+ * @brief Function for setting pressure offset.
+ *
+ * @param[in] p_instance Pointer to sensor instance.
+ * @param[in] offset Pressure offset in hPa.
+ *
+ * @return Return error code from nrf_twi_sensor @ref nrf_twi_sensor_write
+ */
+ret_code_t lps22hb_offset_set(lps22hb_instance_t * p_instance, int16_t offset);
+
+/**
+ * @brief Function for setting interrupt threshold.
+ *
+ * @param[in] p_instance Pointer to sensor instance.
+ * @param[in] threshold Interrupt threshold in hPa.
+ *
+ * @return Return error code from nrf_twi_sensor @ref nrf_twi_sensor_write
+ */
+ret_code_t lps22hb_threshold_set(lps22hb_instance_t * p_instance, uint16_t threshold);
+
+/**
+ * @brief Function for enabling low power mode.
+ *
+ * @param[in] p_instance Pointer to sensor instance.
+ * @param[in] enable Enable low power mode. True if enabled.
+ *
+ * @return Return error code from nrf_twi_sensor @ref nrf_twi_sensor_write
+ */
+ret_code_t lps22hb_low_power_enable(lps22hb_instance_t * p_instance, bool enable);
+
+/**
+ * @brief Function for setting sensor configuration.
+ *
+ * @param[in] p_instance Pointer to sensor instance.
+ *
+ * @return Return error code from nrf_twi_sensor @ref nrf_twi_sensor_write
+ */
+ret_code_t lps22hb_cfg_commit(lps22hb_instance_t * p_instance);
+
+/**
+ * @brief Function for resetting filter.
+ *
+ * @param[in] p_instance Pointer to sensor instance.
+ *
+ * @return Return error code from nrf_twi_sensor @ref nrf_twi_sensor_write
+ */
+__STATIC_INLINE ret_code_t lps22hb_reset_filter(lps22hb_instance_t * p_instance);
+
+/**
+ * @brief Function for reading who am i register.
+ *
+ * @param[in] p_instance Pointer to sensor instance.
+ * @param[in] user_cb Function to be called after register is read.
+ * @param[out] reg_val Register value, single uint8_t.
+ *
+ * @return Return error code from nrf_twi_sensor @ref nrf_twi_sensor_reg_read
+ */
+__STATIC_INLINE ret_code_t lps22hb_who_am_i_read(lps22hb_instance_t * p_instance,
+ nrf_twi_sensor_reg_cb_t user_cb,
+ uint8_t * reg_val);
+
+/**
+ * @brief Function for reading interrupt source register.
+ *
+ * @param[in] p_instance Pointer to sensor instance.
+ * @param[in] user_cb Function to be called after register is read.
+ * @param[out] reg_val Register value, single uint8_t.
+ *
+ * @return Return error code from nrf_twi_sensor @ref nrf_twi_sensor_reg_read
+ */
+__STATIC_INLINE ret_code_t lps22hb_int_source_read(lps22hb_instance_t * p_instance,
+ nrf_twi_sensor_reg_cb_t user_cb,
+ uint8_t * reg_val);
+
+/**
+ * @brief Function for reading fifo status register.
+ *
+ * @param[in] p_instance Pointer to sensor instance.
+ * @param[in] user_cb Function to be called after register is read.
+ * @param[out] reg_val Register value, single uint8_t.
+ *
+ * @return Return error code from nrf_twi_sensor @ref nrf_twi_sensor_reg_read
+ */
+__STATIC_INLINE ret_code_t lps22hb_fifo_status_read(lps22hb_instance_t * p_instance,
+ nrf_twi_sensor_reg_cb_t user_cb,
+ uint8_t * reg_val);
+
+/**
+ * @brief Function for reading status register.
+ *
+ * @param[in] p_instance Pointer to sensor instance.
+ * @param[in] user_cb Function to be called after register is read.
+ * @param[out] reg_val Register value, single uint8_t.
+ *
+ * @return Return error code from nrf_twi_sensor @ref nrf_twi_sensor_reg_read
+ */
+__STATIC_INLINE ret_code_t lps22hb_status_read(lps22hb_instance_t * p_instance,
+ nrf_twi_sensor_reg_cb_t user_cb,
+ uint8_t * reg_val);
+
+#ifndef SUPPRESS_INLINE_IMPLEMENTATION
+
+__STATIC_INLINE ret_code_t lps22hb_reset_filter(lps22hb_instance_t * p_instance)
+{
+ ASSERT(p_instance != NULL);
+ static uint8_t temp;
+ return nrf_twi_sensor_reg_read(p_instance->p_sensor_data,
+ p_instance->sensor_addr,
+ LPS22HB_REG_LPFP_RES,
+ NULL,
+ &temp,
+ 1);
+}
+
+__STATIC_INLINE ret_code_t lps22hb_who_am_i_read(lps22hb_instance_t * p_instance,
+ nrf_twi_sensor_reg_cb_t user_cb,
+ uint8_t * reg_val)
+{
+ ASSERT(p_instance != NULL);
+ return nrf_twi_sensor_reg_read(p_instance->p_sensor_data,
+ p_instance->sensor_addr,
+ LPS22HB_REG_WHO_AM_I,
+ user_cb,
+ reg_val,
+ 1);
+}
+
+__STATIC_INLINE ret_code_t lps22hb_int_source_read(lps22hb_instance_t * p_instance,
+ nrf_twi_sensor_reg_cb_t user_cb,
+ uint8_t * reg_val)
+{
+ ASSERT(p_instance != NULL);
+ return nrf_twi_sensor_reg_read(p_instance->p_sensor_data,
+ p_instance->sensor_addr,
+ LPS22HB_REG_INT_SOURCE,
+ user_cb,
+ reg_val,
+ 1);
+}
+
+__STATIC_INLINE ret_code_t lps22hb_fifo_status_read(lps22hb_instance_t * p_instance,
+ nrf_twi_sensor_reg_cb_t user_cb,
+ uint8_t * reg_val)
+{
+ ASSERT(p_instance != NULL);
+ return nrf_twi_sensor_reg_read(p_instance->p_sensor_data,
+ p_instance->sensor_addr,
+ LPS22HB_REG_FIFO_STATUS,
+ user_cb,
+ reg_val,
+ 1);
+}
+
+__STATIC_INLINE ret_code_t lps22hb_status_read(lps22hb_instance_t * p_instance,
+ nrf_twi_sensor_reg_cb_t user_cb,
+ uint8_t * reg_val)
+{
+ ASSERT(p_instance != NULL);
+ return nrf_twi_sensor_reg_read(p_instance->p_sensor_data,
+ p_instance->sensor_addr,
+ LPS22HB_REG_STATUS,
+ user_cb,
+ reg_val,
+ 1);
+}
+
+#endif //SUPPRESS_INLINE_IMPLEMENTATION
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // LPS22HB_H
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/drivers_ext/lps22hb/lps22hb_internal.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/drivers_ext/lps22hb/lps22hb_internal.h
new file mode 100644
index 0000000..68d636a
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/drivers_ext/lps22hb/lps22hb_internal.h
@@ -0,0 +1,365 @@
+/**
+ * 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+
+#ifndef LPS22HB_INTERNAL_H
+#define LPS22HB_INTERNAL_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define LPS22HB_BYTES_PER_SAMPLE 5
+
+/**
+ * @brief LPS22HB sensor registers.
+ */
+#define LPS22HB_REG_INTERRUPT_CONFIG 0x0B
+#define LPS22HB_REG_THS_P_L 0x0C
+#define LPS22HB_REG_THS_P_H 0x0D
+#define LPS22HB_REG_WHO_AM_I 0x0F
+#define LPS22HB_REG_CTRL1 0x10
+#define LPS22HB_REG_CTRL2 0x11
+#define LPS22HB_REG_CTRL3 0x12
+#define LPS22HB_REG_FIFO_CTRL 0x14
+#define LPS22HB_REG_REF_P_XL 0x15
+#define LPS22HB_REG_REF_P_L 0x16
+#define LPS22HB_REG_REF_P_H 0x17
+#define LPS22HB_REG_RPDS_L 0x18
+#define LPS22HB_REG_RPDS_H 0x19
+#define LPS22HB_REG_RES_CONF 0x1A
+#define LPS22HB_REG_INT_SOURCE 0x25
+#define LPS22HB_REG_FIFO_STATUS 0x26
+#define LPS22HB_REG_STATUS 0x27
+#define LPS22HB_REG_PRESS_OUT_XL 0x28
+#define LPS22HB_REG_PRESS_OUT_L 0x29
+#define LPS22HB_REG_PRESS_OUT_H 0x2A
+#define LPS22HB_REG_TEMP_OUT_L 0x2B
+#define LPS22HB_REG_TEMP_OUT_H 0x2C
+#define LPS22HB_REG_LPFP_RES 0x33
+/**
+ * @brief Interrupt config register bitmasks.
+ */
+
+// Bitmasks for AUTORIFP.
+#define LPS22HB_AUTORIFP_POS 7
+#define LPS22HB_AUTORIFP_MASK (1 << LPS22HB_AUTORIFP_POS)
+
+// Bitmasks for RESET_ARP.
+#define LPS22HB_RESET_ARP_POS 6
+#define LPS22HB_RESET_ARP_MASK (1 << LPS22HB_RESET_ARP_POS)
+
+// Bitmasks for AUTOZERO.
+#define LPS22HB_AUTOZERO_POS 5
+#define LPS22HB_AUTOZERO_MASK (1 << LPS22HB_AUTOZERO_POS)
+
+// Bitmasks for RESET_AZ.
+#define LPS22HB_RESET_AZ_POS 4
+#define LPS22HB_RESET_AZ_MASK (1 << LPS22HB_RESET_AZ_POS)
+
+// Bitmasks for DIFF_EN.
+#define LPS22HB_DIFF_EN_POS 3
+#define LPS22HB_DIFF_EN_MASK (1 << LPS22HB_DIFF_EN_POS)
+
+// Bitmasks for LIR.
+#define LPS22HB_LIR_POS 2
+#define LPS22HB_LIR_MASK (1 << LPS22HB_LIR_POS)
+
+// Bitmasks for PLE.
+#define LPS22HB_PLE_POS 1
+#define LPS22HB_PLE_MASK (1 << LPS22HB_PLE_POS)
+
+// Bitmasks for PHE.
+#define LPS22HB_PHE_POS 0
+#define LPS22HB_PHE_MASK (1 << LPS22HB_PHE_POS)
+
+
+/**
+ * @brief Control register 1 bitmasks.
+ */
+
+// Register validity bitmask.
+#define LPS22HB_CTRL1_VALID_MASK 0x80
+
+// Bitmasks for ODR.
+#define LPS22HB_ODR_POS 4
+#define LPS22HB_ODR_MASK (7 << LPS22HB_ODR_POS)
+
+// Bitmasks for EN_LPFP.
+#define LPS22HB_EN_LPFP_POS 3
+#define LPS22HB_EN_LPFP_MASK (1 << LPS22HB_EN_LPFP_POS)
+
+// Bitmasks for LPFP_CFG.
+#define LPS22HB_LPFP_CFG_POS 2
+#define LPS22HB_LPFP_CFG_MASK (1 << LPS22HB_LPFP_CFG_POS)
+
+// Bitmasks for BDU.
+#define LPS22HB_BDU_POS 1
+#define LPS22HB_BDU_MASK (1 << LPS22HB_BDU_POS)
+
+// Bitmasks for SIM.
+#define LPS22HB_SIM_POS 0
+#define LPS22HB_SIM_MASK (1 << LPS22HB_SIM_POS)
+
+
+/**
+ * @brief Control register 2 bitmasks.
+ */
+
+// Register validity bitmask.
+#define LPS22HB_CTRL2_VALID_MASK 0x02
+
+// Bitmasks for BOOT.
+#define LPS22HB_BOOT_POS 7
+#define LPS22HB_BOOT_MASK (1 << LPS22HB_BOOT_POS)
+
+// Bitmasks for FIFO_EN.
+#define LPS22HB_FIFO_EN_POS 6
+#define LPS22HB_FIFO_EN_MASK (1 << LPS22HB_FIFO_EN_POS)
+
+// Bitmasks for STOP_ON_FTH.
+#define LPS22HB_STOP_ON_FTH_POS 5
+#define LPS22HB_STOP_ON_FTH_MASK (1 << LPS22HB_STOP_ON_FTH_POS)
+
+// Bitmasks for IF_ADD_INC.
+#define LPS22HB_IF_ADD_INC_POS 4
+#define LPS22HB_IF_ADD_INC_MASK (1 << LPS22HB_IF_ADD_INC_POS)
+
+// Bitmasks for I2C_DIS.
+#define LPS22HB_I2C_DIS_POS 3
+#define LPS22HB_I2C_DIS_MASK (1 << LPS22HB_I2C_DIS_POS)
+
+// Bitmasks for SWRESET.
+#define LPS22HB_SWRESET_POS 2
+#define LPS22HB_SWRESET_MASK (1 << LPS22HB_SWRESET_POS)
+
+// Bitmasks for ONE_SHOT.
+#define LPS22HB_ONE_SHOT_POS 0
+#define LPS22HB_ONE_SHOT_MASK (1 << LPS22HB_ONE_SHOT_POS)
+
+
+/**
+ * @brief Control register 3 bitmasks.
+ */
+
+// Bitmasks for INT_H_L.
+#define LPS22HB_INT_H_L_POS 7
+#define LPS22HB_INT_H_L_MASK (1 << LPS22HB_INT_H_L_POS)
+
+// Bitmasks for PP_OD.
+#define LPS22HB_PP_OD_POS 6
+#define LPS22HB_PP_OD_MASK (1 << LPS22HB_PP_OD_POS)
+
+// Bitmasks for F_FSS5.
+#define LPS22HB_F_FSS5_POS 5
+#define LPS22HB_F_FSS5_MASK (1 << LPS22HB_F_FSS5_POS)
+
+// Bitmasks for F_FTH.
+#define LPS22HB_F_FTH_POS 4
+#define LPS22HB_F_FTH_MASK (1 << LPS22HB_F_FTH_POS)
+
+// Bitmasks for F_OVR.
+#define LPS22HB_F_OVR_POS 3
+#define LPS22HB_F_OVR_MASK (1 << LPS22HB_F_OVR_POS)
+
+// Bitmasks for DRDY.
+#define LPS22HB_DRDY_POS 2
+#define LPS22HB_DRDY_MASK (1 << LPS22HB_DRDY_POS)
+
+// Bitmasks for INT_S.
+#define LPS22HB_INT_S_POS 0
+#define LPS22HB_INT_S_MASK (3 << LPS22HB_INT_S_POS)
+
+
+/**
+ * @brief Fifo control register bitmasks.
+ */
+
+// Bitmasks for F_MODE.
+#define LPS22HB_F_MODE_POS 5
+#define LPS22HB_F_MODE_MASK (7 << LPS22HB_F_MODE_POS)
+
+// Bitmasks for WTM
+#define LPS22HB_WTM_POS 0
+#define LPS22HB_WTM_MASK (0x1F << LPS22HB_WTM_POS)
+
+
+/**
+ * @brief Low power mode register bitmasks.
+ */
+
+// Register validity bitmask.
+#define LPS22HB_RES_CONF_VALID_MASK 0xFE
+
+// Bitmasks for LC_EN
+#define LPS22HB_LC_EN_POS 0
+#define LPS22HB_LC_EN_MASK (1 << LPS22HB_LC_EN_POS)
+
+
+/**
+ * @brief INT source register bitmasks.
+ */
+
+// Bitmasks for IA
+#define LPS22HB_IA_POS 2
+#define LPS22HB_IA_MASK (1 << LPS22HB_IA_POS)
+
+// Bitmasks for PL
+#define LPS22HB_PL_POS 1
+#define LPS22HB_PL_MASK (1 << LPS22HB_PL_POS)
+
+// Bitmasks for PH
+#define LPS22HB_PH_POS 0
+#define LPS22HB_PH_MASK (1 << LPS22HB_PH_POS)
+
+
+/**
+ * @brief FIFO status register bitmasks.
+ */
+
+// Bitmasks for FTH_FIFO
+#define LPS22HB_FTH_FIFO_POS 7
+#define LPS22HB_FTH_FIFO_MASK (1 << LPS22HB_FTH_FIFO_POS)
+
+// Bitmasks for OVR
+#define LPS22HB_OVR_POS 6
+#define LPS22HB_OVR_MASK (1 << LPS22HB_OVR_POS)
+
+// Bitmasks for stored data level
+#define LPS22HB_FSS_POS 0
+#define LPS22HB_FSS_MASK (0x3F << LPS22HB_FSS_POS)
+
+
+/**
+ * @brief Status register bitmasks.
+ */
+
+// Bitmasks for T_OR.
+#define LPS22HB_T_OR_POS 5
+#define LPS22HB_T_OR_MASK (1 << LPS22HB_T_OR_POS)
+
+// Bitmasks for P_OR.
+#define LPS22HB_P_OR_POS 4
+#define LPS22HB_P_OR_MASK (1 << LPS22HB_P_OR_POS)
+
+// Bitmasks for T_DA.
+#define LPS22HB_T_DA_POS 1
+#define LPS22HB_T_DA_MASK (1 << LPS22HB_T_DA_POS)
+
+// Bitmasks for P_DA.
+#define LPS22HB_P_DA_POS 0
+#define LPS22HB_P_DA_MASK (1 << LPS22HB_P_DA_POS)
+
+/**
+ * @brief Config registers defaults.
+ */
+#define LPS22HB_CTRL_REG2_DEFAULT 0x10
+
+/**
+ * @brief Raw pressure and temperature data.
+ *
+ * @note For internal use only.
+ */
+typedef struct
+{
+ uint8_t press_out_xl;
+ uint8_t press_out_l;
+ uint8_t press_out_h;
+ uint8_t temp_out_l;
+ uint8_t temp_out_h;
+} lps22hb_raw_data_t;
+
+/**
+ * @brief Structure holding sensor instance
+ *
+ * @note For internal use only.
+ */
+typedef struct
+{
+ nrf_twi_sensor_t * const p_sensor_data;
+ uint8_t const sensor_addr;
+
+ uint8_t interrupt_cfg;
+ uint8_t ctrl_reg[3];
+ uint8_t fifo_ctrl;
+} lps22hb_instance_t;
+
+#define LPS22HB_INTERNAL_INSTANCE_DEF(_lps22hb_inst_name, _p_twi_sensor, _sensor_address) \
+ static lps22hb_instance_t _lps22hb_inst_name = \
+ { \
+ .p_sensor_data = _p_twi_sensor, \
+ .sensor_addr = _sensor_address, \
+ }
+
+#define LPS22HB_INTERNAL_INT_CFG(_s, _diff_en, _lir, _ple, _phe) \
+ NRF_TWI_SENSOR_REG_SET(_s.interrupt_cfg, LPS22HB_DIFF_EN_MASK, LPS22HB_DIFF_EN_POS, _diff_en); \
+ NRF_TWI_SENSOR_REG_SET(_s.interrupt_cfg, LPS22HB_LIR_MASK, LPS22HB_LIR_POS, _lir); \
+ NRF_TWI_SENSOR_REG_SET(_s.interrupt_cfg, LPS22HB_PLE_MASK, LPS22HB_PLE_POS, _ple); \
+ NRF_TWI_SENSOR_REG_SET(_s.interrupt_cfg, LPS22HB_PHE_MASK, LPS22HB_PHE_POS, _phe);
+
+#define LPS22HB_INTERNAL_DATA_CFG(_s, _odr, _f_en, _f_cfg) \
+ NRF_TWI_SENSOR_REG_SET(_s.ctrl_reg[0], LPS22HB_ODR_MASK, LPS22HB_ODR_POS, _odr); \
+ NRF_TWI_SENSOR_REG_SET(_s.ctrl_reg[0], LPS22HB_EN_LPFP_MASK, LPS22HB_EN_LPFP_POS, _f_en); \
+ NRF_TWI_SENSOR_REG_SET(_s.ctrl_reg[0], LPS22HB_LPFP_CFG_MASK, LPS22HB_LPFP_CFG_POS, _f_cfg);
+
+
+#define LPS22HB_INTERNAL_FIFO_CFG(_s, _f_mode, _f_en, _f_stop, _f_wtm) \
+ NRF_TWI_SENSOR_REG_SET(_s.fifo_ctrl, LPS22HB_F_MODE_MASK, LPS22HB_F_MODE_POS, _f_mode); \
+ NRF_TWI_SENSOR_REG_SET(_s.fifo_ctrl, LPS22HB_WTM_MASK, LPS22HB_WTM_POS, _f_wtm); \
+ NRF_TWI_SENSOR_REG_SET(_s.ctrl_reg[1], LPS22HB_FIFO_EN_MASK, LPS22HB_FIFO_EN_POS, _f_en); \
+ NRF_TWI_SENSOR_REG_SET(_s.ctrl_reg[1], \
+ LPS22HB_STOP_ON_FTH_MASK, \
+ LPS22HB_STOP_ON_FTH_POS, \
+ _f_stop)
+
+#define LPS22HB_INTERNAL_DRDY_CFG(_s, _activ, _pp_od, _fss, _fth, _ovr, _drdy, _high, _low) \
+ NRF_TWI_SENSOR_REG_SET(_s.ctrl_reg[2], LPS22HB_INT_H_L_MASK, LPS22HB_INT_H_L_POS, _activ); \
+ NRF_TWI_SENSOR_REG_SET(_s.ctrl_reg[2], LPS22HB_PP_OD_MASK, LPS22HB_PP_OD_POS, _pp_od); \
+ NRF_TWI_SENSOR_REG_SET(_s.ctrl_reg[2], LPS22HB_F_FSS5_MASK, LPS22HB_F_FSS5_POS, _fss); \
+ NRF_TWI_SENSOR_REG_SET(_s.ctrl_reg[2], LPS22HB_F_FTH_MASK, LPS22HB_F_FTH_POS, _fth); \
+ NRF_TWI_SENSOR_REG_SET(_s.ctrl_reg[2], LPS22HB_F_OVR_MASK, LPS22HB_F_OVR_POS, _ovr); \
+ NRF_TWI_SENSOR_REG_SET(_s.ctrl_reg[2], \
+ LPS22HB_INT_S_MASK, \
+ LPS22HB_INT_S_MASK, \
+ (_low << 1) + _high);
+#ifdef __cplusplus
+}
+#endif
+
+#endif // LPS22HB_INTERNAL_H
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/drivers_ext/max9850/max9850.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/drivers_ext/max9850/max9850.c
new file mode 100644
index 0000000..bd765a1
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/drivers_ext/max9850/max9850.c
@@ -0,0 +1,71 @@
+/**
+ * Copyright (c) 2016 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#include "max9850.h"
+
+#include <string.h>
+
+ret_code_t max9850_init(max9850_config_t const * p_max9850)
+{
+ ret_code_t ret = NRF_SUCCESS;
+
+ ret = nrf_drv_twi_init(&p_max9850->twi, &p_max9850->twi_cfg, NULL, NULL);
+ if (ret != NRF_SUCCESS)
+ {
+ return ret;
+ }
+
+ nrf_drv_twi_enable(&p_max9850->twi);
+
+ /*Probe device*/
+ uint8_t rx[] = {0};
+ ret = nrf_drv_twi_rx(&p_max9850->twi, p_max9850->twi_addr, rx, sizeof(rx));
+ if (ret != NRF_SUCCESS)
+ {
+ return ret;
+ }
+
+ uint8_t regs[sizeof(max9850_regmap_t) + 1];
+
+ regs[0] = 0x00;
+ memcpy(regs + 1, &p_max9850->regmap, sizeof(max9850_regmap_t));
+
+ /*Write configuration*/
+ return nrf_drv_twi_tx(&p_max9850->twi, p_max9850->twi_addr, regs, sizeof(regs), false);
+}
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/drivers_ext/max9850/max9850.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/drivers_ext/max9850/max9850.h
new file mode 100644
index 0000000..043f6c3
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/drivers_ext/max9850/max9850.h
@@ -0,0 +1,130 @@
+/**
+ * Copyright (c) 2016 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#ifndef MAX9850_H__
+#define MAX9850_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <stdint.h>
+
+#include "nrf_drv_twi.h"
+
+/**
+ * @brief Default MAX9850 TWI configuration
+ *
+ * @param scl_pin SCL pin number
+ * @param sda_pin SDA pin number
+ */
+#define MAX9850_DEFAULT_TWI_CONFIG(scl_pin, sda_pin) { \
+ .scl = scl_pin, \
+ .sda = sda_pin, \
+ .frequency = NRF_DRV_TWI_FREQ_100K, \
+ .interrupt_priority = APP_IRQ_PRIORITY_HIGH, \
+ .clear_bus_init = false, \
+ .hold_bus_uninit = false \
+}
+
+/**
+ * @brief Internal MAX9850 register map
+ * */
+typedef struct {
+ uint8_t status_a; //!< Status register A (R)
+ uint8_t status_b; //!< Status register B (R)
+ uint8_t volume; //!< Volume control (RW)
+ uint8_t general_purpose; //!< General purpose register (RW)
+ uint8_t interrupt_enable; //!< Interrupt enable (RW)
+ uint8_t enable; //!< Enable register (RW)
+ uint8_t clock; //!< Clock control (RW)
+ uint8_t charge_pump; //!< Charge pump (RW)
+ uint8_t lrclk_msb; //!< LRCLK MSB register (RW)
+ uint8_t lrclk_lsb; //!< LRCLK LSB register (RW)
+ uint8_t digital_audio; //!< Digital audio (RW)
+} max9850_regmap_t;
+
+/**
+ * @brief MAX9850 register map after reset
+ * */
+#define MAX9850_DEFAULT_REGMAP() { \
+ .status_a = 0, \
+ .status_b = 0, \
+ .volume = 0x0C, \
+ .general_purpose = 0, \
+ .interrupt_enable = 0, \
+ .enable = 0, \
+ .clock = 0, \
+ .charge_pump = 0, \
+ .lrclk_msb = 0, \
+ .lrclk_lsb = 0, \
+ .digital_audio = 0, \
+}
+
+/**
+ * @brief Helper macro for creating MAX9850 TWI address
+ * */
+#define MAX9850_TWI_ADDR(v) (0x10 + (v))
+
+
+/**
+ * @brief MAX9850 configuration
+ * */
+typedef struct {
+ nrf_drv_twi_t twi; //!< TWI instance
+ nrf_drv_twi_config_t twi_cfg; //!< TWI configuration
+ max9850_regmap_t regmap; //!< MAX9850 register map
+ uint8_t twi_addr; //!< MAX9850 TWI address
+} max9850_config_t;
+
+/**
+ * @brief Initializes MAX9850 IC
+ *
+ * @param p_max9850 MAX9850 configuration
+ *
+ * @return Standard error code
+ * */
+ret_code_t max9850_init(max9850_config_t const * p_max9850);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* MAX9850_H__ */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/drivers_ext/mcp4725/mcp4725.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/drivers_ext/mcp4725/mcp4725.c
new file mode 100644
index 0000000..de720e7
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/drivers_ext/mcp4725/mcp4725.c
@@ -0,0 +1,156 @@
+/**
+ * Copyright (c) 2016 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#include "mcp4725.h"
+#include "nrf_drv_twi.h"
+#include "nrf_delay.h"
+#include "boards.h"
+#include "app_util_platform.h"
+
+/*lint ++flb "Enter library region" */
+#define MCP4725_BASE_ADDRESS 0x60 //!< MCP4725 base address
+
+#define MCP4725_DAC_ADDRESS 0x40 //!< MCP4725 write-to-dac register
+#define MCP4725_EEPROM_ADDRESS 0x60 //!< MCP4725 write-to-eeprom register
+
+#define RDY_BIT_POS 0x07 //!< Position of RDY bit
+
+/* TWI instance. */
+static const nrf_drv_twi_t m_twi = NRF_DRV_TWI_INSTANCE(TWI_INSTANCE_ID_USED);
+
+/* Twi transfer indicators. */
+volatile bool m_xfer_done = false;
+volatile bool m_read_done = false;
+
+/**
+ * @brief TWI events handler.
+ */
+static void twi_handler(nrf_drv_twi_evt_t const * p_event, void * p_context)
+{
+ switch (p_event->type)
+ {
+ case NRF_DRV_TWI_EVT_DONE:
+ if (p_event->xfer_desc.type == NRF_DRV_TWI_XFER_TX)
+ {
+ m_xfer_done = true;
+ }
+ if (p_event->xfer_desc.type == NRF_DRV_TWI_XFER_RX)
+ {
+ m_read_done = true;
+ }
+ break;
+ default:
+ break;
+ }
+}
+
+/**
+ * @brief TWI initialization.
+ *
+ * @param[in] p_pins_config Pointer to structere holding pins numbers to be used by TWI.
+ */
+static ret_code_t twi_init(mcp4725_pins_config_t const * p_pins_config)
+{
+ ret_code_t err_code;
+
+ const nrf_drv_twi_config_t twi_mcp4725_config = {
+ .scl = p_pins_config->scl_pin,
+ .sda = p_pins_config->sda_pin,
+ .frequency = NRF_DRV_TWI_FREQ_100K,
+ .interrupt_priority = APP_IRQ_PRIORITY_HIGH,
+ .clear_bus_init = false
+ };
+
+ err_code = nrf_drv_twi_init(&m_twi, &twi_mcp4725_config, twi_handler, NULL);
+ if (err_code != NRF_SUCCESS)
+ {
+ return err_code;
+ }
+
+ nrf_drv_twi_enable(&m_twi);
+ return NRF_SUCCESS;
+}
+
+ret_code_t mcp4725_setup(mcp4725_pins_config_t const * p_pins_config)
+{
+ ret_code_t err_code = twi_init(p_pins_config);
+ if (err_code != NRF_SUCCESS)
+ {
+ return err_code;
+ }
+
+ return NRF_SUCCESS;
+}
+
+ret_code_t mcp4725_set_voltage(uint16_t val, bool write_eeprom)
+{
+ /* Shift parameter val to get 2 8-bits values. */
+ uint8_t reg[3] = {write_eeprom ? MCP4725_EEPROM_ADDRESS : MCP4725_DAC_ADDRESS,
+ (val>>4), (val<<4)};
+
+ m_xfer_done = false;
+
+ ret_code_t err_code = nrf_drv_twi_tx(&m_twi, MCP4725_BASE_ADDRESS, reg, sizeof(reg), false);
+ if (err_code != NRF_SUCCESS)
+ {
+ return err_code;
+ }
+
+ while (m_xfer_done == false);
+
+ return NRF_SUCCESS;
+}
+
+bool mcp4725_is_busy(void)
+{
+ uint8_t busy;
+ m_read_done = false;
+
+ ret_code_t err_code = nrf_drv_twi_rx(&m_twi, MCP4725_BASE_ADDRESS, &busy, sizeof(busy));
+ if (err_code != NRF_SUCCESS)
+ {
+ return err_code;
+ }
+
+ while (m_read_done == false);
+
+ return (bool)(!(busy >> RDY_BIT_POS));
+}
+
+/*lint --flb "Leave library region" */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/drivers_ext/mcp4725/mcp4725.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/drivers_ext/mcp4725/mcp4725.h
new file mode 100644
index 0000000..0a71e21
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/drivers_ext/mcp4725/mcp4725.h
@@ -0,0 +1,107 @@
+/**
+ * Copyright (c) 2016 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#ifndef MCP4725_H
+#define MCP4725_H
+
+/*lint ++flb "Enter library region" */
+
+#include <stdbool.h>
+#include <stdint.h>
+#include "app_util_platform.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** @file
+* @brief MCP4725 digital DAC driver.
+*
+*
+* @defgroup mcp4725 MCP4725 digital DAC driver
+* @{
+* @ingroup ext_drivers
+* @brief MCP4725 digital DAC driver.
+*/
+
+typedef struct
+{
+ uint8_t scl_pin;
+ uint8_t sda_pin;
+}mcp4725_pins_config_t;
+
+/**
+ * @brief Function for setting up the driver.
+ *
+ * @param[in] p_pins_config Pointer to structere holding pins numbers to be used by TWI.
+ *
+ * @return Values returned by @ref nrfx_twi_init.
+ */
+ret_code_t mcp4725_setup(mcp4725_pins_config_t const * p_pins_config);
+
+
+/**
+ * @brief Function for setting new value to DAC.
+ *
+ * @param[in] val 12-bit value. Base on it voltage is set (Vout = (val/4095) * Vcc).
+ * @param[in] write_eeprom Defines if value will be written to DAC only or to EEPROM memmory also.
+ *
+ * @return Values returned by @ref nrfx_twi_tx.
+ */
+ret_code_t mcp4725_set_voltage(uint16_t val, bool write_eeprom);
+
+/**
+ * @brief Function for checking if DAC is busy saving data in EEPROM.
+ *
+ * @retval true If DAC is busy.
+ * @retval false If Dac is not busy.
+ */
+bool mcp4725_is_busy(void);
+
+/**
+ *@}
+ **/
+
+/*lint --flb "Leave library region" */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif //MCP4725_H
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/drivers_ext/mpu6050/mpu6050.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/drivers_ext/mpu6050/mpu6050.c
new file mode 100644
index 0000000..17ff011
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/drivers_ext/mpu6050/mpu6050.c
@@ -0,0 +1,108 @@
+/**
+ * Copyright (c) 2009 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#include <stdbool.h>
+#include <stdint.h>
+
+#include "twi_master.h"
+#include "mpu6050.h"
+
+/*lint ++flb "Enter library region" */
+
+#define ADDRESS_WHO_AM_I (0x75U) // !< WHO_AM_I register identifies the device. Expected value is 0x68.
+#define ADDRESS_SIGNAL_PATH_RESET (0x68U) // !<
+
+static const uint8_t expected_who_am_i = 0x68U; // !< Expected value to get from WHO_AM_I register.
+static uint8_t m_device_address; // !< Device address in bits [7:1]
+
+bool mpu6050_init(uint8_t device_address)
+{
+ bool transfer_succeeded = true;
+
+ m_device_address = (uint8_t)(device_address << 1);
+
+ // Do a reset on signal paths
+ uint8_t reset_value = 0x04U | 0x02U | 0x01U; // Resets gyro, accelerometer and temperature sensor signal paths.
+ transfer_succeeded &= mpu6050_register_write(ADDRESS_SIGNAL_PATH_RESET, reset_value);
+
+ // Read and verify product ID
+ transfer_succeeded &= mpu6050_verify_product_id();
+
+ return transfer_succeeded;
+}
+
+bool mpu6050_verify_product_id(void)
+{
+ uint8_t who_am_i;
+
+ if (mpu6050_register_read(ADDRESS_WHO_AM_I, &who_am_i, 1))
+ {
+ if (who_am_i != expected_who_am_i)
+ {
+ return false;
+ }
+ else
+ {
+ return true;
+ }
+ }
+ else
+ {
+ return false;
+ }
+}
+
+bool mpu6050_register_write(uint8_t register_address, uint8_t value)
+{
+ uint8_t w2_data[2];
+
+ w2_data[0] = register_address;
+ w2_data[1] = value;
+ return twi_master_transfer(m_device_address, w2_data, 2, TWI_ISSUE_STOP);
+}
+
+bool mpu6050_register_read(uint8_t register_address, uint8_t * destination, uint8_t number_of_bytes)
+{
+ bool transfer_succeeded;
+ transfer_succeeded = twi_master_transfer(m_device_address, &register_address, 1, TWI_DONT_ISSUE_STOP);
+ transfer_succeeded &= twi_master_transfer(m_device_address|TWI_READ_BIT, destination, number_of_bytes, TWI_ISSUE_STOP);
+ return transfer_succeeded;
+}
+
+/*lint --flb "Leave library region" */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/drivers_ext/mpu6050/mpu6050.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/drivers_ext/mpu6050/mpu6050.h
new file mode 100644
index 0000000..f5d8d0c
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/drivers_ext/mpu6050/mpu6050.h
@@ -0,0 +1,110 @@
+/**
+ * Copyright (c) 2009 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#ifndef MPU6050_H
+#define MPU6050_H
+
+/*lint ++flb "Enter library region" */
+
+#include <stdbool.h>
+#include <stdint.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** @file
+* @brief MPU6050 gyro/accelerometer driver.
+*
+*
+* @defgroup nrf_drivers_mpu6050 MPU6050 gyro/accelerometer driver
+* @{
+* @ingroup ext_drivers
+* @brief MPU6050 gyro/accelerometer driver.
+*/
+
+/**
+ * @brief Function for initializing MPU6050 and verifies it's on the bus.
+ *
+ * @param device_address Device TWI address in bits [6:0].
+ * @return
+ * @retval true MPU6050 found on the bus and ready for operation.
+ * @retval false MPU6050 not found on the bus or communication failure.
+ */
+bool mpu6050_init(uint8_t device_address);
+
+/**
+ @brief Function for writing a MPU6050 register contents over TWI.
+ @param[in] register_address Register address to start writing to
+ @param[in] value Value to write to register
+ @retval true Register write succeeded
+ @retval false Register write failed
+*/
+bool mpu6050_register_write(uint8_t register_address, const uint8_t value);
+
+/**
+ @brief Function for reading MPU6050 register contents over TWI.
+ Reads one or more consecutive registers.
+ @param[in] register_address Register address to start reading from
+ @param[in] number_of_bytes Number of bytes to read
+ @param[out] destination Pointer to a data buffer where read data will be stored
+ @retval true Register read succeeded
+ @retval false Register read failed
+*/
+bool mpu6050_register_read(uint8_t register_address, uint8_t *destination, uint8_t number_of_bytes);
+
+/**
+ @brief Function for reading and verifying MPU6050 product ID.
+ @retval true Product ID is what was expected
+ @retval false Product ID was not what was expected
+*/
+bool mpu6050_verify_product_id(void);
+
+/**
+ *@}
+ **/
+
+/*lint --flb "Leave library region" */
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* MPU6050_H */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/drivers_ext/nrf6350/nrf6350.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/drivers_ext/nrf6350/nrf6350.c
new file mode 100644
index 0000000..af73cd1
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/drivers_ext/nrf6350/nrf6350.c
@@ -0,0 +1,305 @@
+/**
+ * Copyright (c) 2008 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#include "nrf6350.h"
+#include "nrf_delay.h"
+#include "twi_master.h"
+
+/*lint ++flb "Enter library region" */
+
+#define DDRAM_ADR 0x80 //!< Write to DDRAM AC
+#define DDRAM_WR 0x40 //!< Write to DDRAM
+#define FUNC_SET 0x00 //!< Enter LCD Function settings
+#define LCD_ADDR 0x3E //!< LCD display adr
+#define JS_ADDR 0x3F //!< Joystick adr
+
+#define X 0 //!< X direction in pos 0 of joystick array
+#define Y 1 //!< Y direction in pos 1 of joystick array
+
+
+//static void nrf6350_nrf6350_lcd_set_instruction(uint8_t instr);
+
+#define BUF_LEN 32 //!< LCD data buffer length
+static uint8_t data_buffer[BUF_LEN]; //!< LCD data buffer
+static uint8_t empty_str[18] = {DDRAM_WR, ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' '}; //!< Blank line
+
+
+static bool nrf6350_lcd_set_instruction(uint8_t instr)
+{
+ nrf_delay_us(10000);
+ data_buffer[0] = FUNC_SET;
+ data_buffer[1] = instr;
+ return twi_master_transfer(LCD_ADDR << 1, data_buffer, 2, TWI_ISSUE_STOP);
+}
+
+bool nrf6350_lcd_clear(void)
+{
+ nrf_delay_us(10000);
+ data_buffer[0] = FUNC_SET;
+ data_buffer[1] = (uint8_t)(DDRAM_ADR + LCD_UPPER_LINE);
+ if (!twi_master_transfer(LCD_ADDR << 1, data_buffer, 2, TWI_ISSUE_STOP))
+ return false;
+ if (!twi_master_transfer(LCD_ADDR << 1, empty_str, 18, TWI_ISSUE_STOP))
+ {
+ return false;
+ }
+ data_buffer[1] = DDRAM_ADR + LCD_LOWER_LINE;
+ if (!twi_master_transfer(LCD_ADDR << 1, data_buffer, 2, TWI_ISSUE_STOP))
+ return false;
+ if (!twi_master_transfer(LCD_ADDR << 1, empty_str, 18, TWI_ISSUE_STOP))
+ return false;
+ return true;
+}
+
+bool nrf6350_lcd_set_contrast(uint8_t contrast)
+{
+ nrf_delay_us(10000);
+ data_buffer[0] = FUNC_SET;
+ data_buffer[1] = 0x70 | contrast;
+ return twi_master_transfer(LCD_ADDR << 1, data_buffer, 2, TWI_ISSUE_STOP);
+}
+
+bool nrf6350_lcd_on(void)
+{
+ nrf_delay_us(10000);
+ data_buffer[0] = FUNC_SET;
+ data_buffer[1] = 0x0C;
+ return twi_master_transfer(LCD_ADDR << 1, data_buffer, 2, TWI_ISSUE_STOP);
+}
+
+bool nrf6350_lcd_off(void)
+{
+ nrf_delay_us(10000);
+ data_buffer[0] = FUNC_SET;
+ data_buffer[1] = 0x08;
+ return twi_master_transfer(LCD_ADDR << 1, data_buffer, 2, TWI_ISSUE_STOP);
+}
+
+bool nrf6350_lcd_init(void)
+{
+ if (!twi_master_init())
+ {
+ return false;
+ }
+
+ // Sometimes the first command doesn't get through, so we'll try
+ // sending non-important "wake up" command first and don't care if it fails.
+ (void)nrf6350_lcd_wake_up();
+
+ if (!nrf6350_lcd_set_instruction(0x38)) // Function set.
+ return false;
+ if (!nrf6350_lcd_set_instruction(0x39)) // Choose two-line mode.
+ return false;
+ if (!nrf6350_lcd_set_instruction(0x14)) // Internal OSC frequency.
+ return false;
+ if (!nrf6350_lcd_set_contrast(LCD_CONTRAST_HIGH)) // Contrast set (low byte).
+ return false;
+ if (!nrf6350_lcd_set_instruction(0x5F)) // Power/ICON control/.
+ return false;
+ if (!nrf6350_lcd_set_instruction(0x6A)) // Follower control.
+ return false;
+ nrf_delay_us(200000); // Need to wait 200ms here according to datasheet.
+ if (!nrf6350_lcd_on()) // Display ON.
+ return false;
+ if (!nrf6350_lcd_clear()) // Clear display.
+ return false;
+ return nrf6350_lcd_set_instruction(0x06); // Entry mode set.
+}
+
+bool nrf6350_lcd_write_string(const char *p_text, uint8_t size, uint8_t line, uint8_t pos)
+{
+ uint8_t i;
+
+ data_buffer[0] = FUNC_SET;
+ data_buffer[1] = DDRAM_ADR + (pos + line);
+ if (!twi_master_transfer(LCD_ADDR << 1, data_buffer, 2, TWI_ISSUE_STOP))
+ return false;
+ if (!twi_master_transfer(LCD_ADDR << 1, empty_str, 18 - pos, TWI_ISSUE_STOP))
+ return false;
+ data_buffer[0] = FUNC_SET;
+ data_buffer[1] = DDRAM_ADR + (pos + line);
+ if (!twi_master_transfer(LCD_ADDR << 1, data_buffer, 2, TWI_ISSUE_STOP))
+ return false;
+ data_buffer[0] = DDRAM_WR;
+ for (i=0;i<size;i++)
+ {
+ if (i == LCD_LLEN)
+ break;
+ data_buffer[i + 1] = (uint8_t) * p_text++;
+ }
+ return twi_master_transfer(LCD_ADDR << 1, data_buffer, i + 1, TWI_ISSUE_STOP);
+}
+
+bool nrf6350_js_get_value(int8_t * val)
+{
+ uint8_t js_data;
+
+ if (!twi_master_transfer(JS_ADDR << 1 | TWI_READ_BIT, data_buffer, 1, TWI_ISSUE_STOP))
+ return false;
+ js_data = (~data_buffer[0] & 0x1D); // Select the useful bits.
+
+ if ((js_data & 0x01) != 0) // Check joystick position.
+ {
+ val[X] = -1;
+ }
+ else if ((js_data & 0x10) != 0)
+ {
+ val[X] = 1;
+ }
+ else
+ {
+ val[X] = 0;
+ }
+
+ if ((js_data & 0x04) != 0)
+ {
+ val[Y] = 1;
+ }
+ else if ((js_data & 0x08) != 0)
+ {
+ val[Y] = -1;
+ }
+ else
+ {
+ val[Y] = 0;
+ }
+ return true;
+}
+
+
+bool nrf6350_js_get_status(uint8_t * js_state)
+{
+ uint8_t js_data;
+
+ if (!twi_master_transfer(JS_ADDR << 1 | TWI_READ_BIT, &js_data, 1, TWI_ISSUE_STOP))
+ {
+ return false;
+ }
+ js_data = ~js_data;
+ *js_state = js_data & 0x1F;
+ return true;
+}
+
+/** @brief First time communication with the development kit nRF6350 display will fail, this
+ * returns false on timeout instead of attempting to recover.
+ */
+static bool nrf6350_lcd_write_without_recovery(uint8_t * data,
+ uint8_t data_length,
+ bool issue_stop_condition)
+{
+ uint32_t timeout = 20000; /* max loops to wait for EVENTS_TXDSENT event*/
+
+ if (data_length == 0)
+ {
+ /* Return false for requesting data of size 0 */
+ return false;
+ }
+
+ NRF_TWI1->TXD = *data++;
+ NRF_TWI1->TASKS_STARTTX = 1;
+
+ /** @snippet [TWI HW master write] */
+ while (true)
+ {
+ while (NRF_TWI1->EVENTS_TXDSENT == 0 && (--timeout))
+ {
+ // Do nothing.
+ }
+
+ if (timeout == 0)
+ {
+ NRF_TWI1->EVENTS_STOPPED = 0;
+ NRF_TWI1->TASKS_STOP = 1;
+
+ /* Wait until stop sequence is sent */
+ while (NRF_TWI1->EVENTS_STOPPED == 0)
+ {
+ // Do nothing.
+ }
+
+ /* Timeout before receiving event*/
+ return false;
+ }
+
+ NRF_TWI1->EVENTS_TXDSENT = 0;
+ if (--data_length == 0)
+ {
+ break;
+ }
+
+ NRF_TWI1->TXD = *data++;
+ }
+ /** @snippet [TWI HW master write] */
+
+ if (issue_stop_condition)
+ {
+ NRF_TWI1->EVENTS_STOPPED = 0;
+ NRF_TWI1->TASKS_STOP = 1;
+
+ /* Wait until stop sequence is sent */
+ while (NRF_TWI1->EVENTS_STOPPED == 0)
+ {
+ // Do nothing.
+ }
+ }
+ return true;
+}
+
+/** @brief Function for transfer by twi_master.
+ */
+bool nrf6350_lcd_wake_up(void)
+{
+ uint8_t address = (LCD_ADDR << 1);
+ uint8_t dummy_data[] = {0, 0, 0, 0};
+ uint8_t dummy_data_length = 4;
+ bool issue_stop_condition = 0;
+ bool transfer_succeeded = false;
+
+ NRF_TWI1->ADDRESS = (address >> 1);
+
+ transfer_succeeded = nrf6350_lcd_write_without_recovery(dummy_data,
+ dummy_data_length,
+ issue_stop_condition);
+
+ NRF_TWI1->EVENTS_ERROR = 0;
+
+ return transfer_succeeded;
+}
+
+/*lint --flb "Leave library region" */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/drivers_ext/nrf6350/nrf6350.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/drivers_ext/nrf6350/nrf6350.h
new file mode 100644
index 0000000..09af87e
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/drivers_ext/nrf6350/nrf6350.h
@@ -0,0 +1,154 @@
+/**
+ * Copyright (c) 2012 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#ifndef NRF6350_H_
+#define NRF6350_H_
+
+#include <stdbool.h>
+#include <stdint.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define LCD_LLEN 16 //!< LCD Line length
+
+#define JS_BUTTON_NONE 0x00 //!< Joystick not touched
+#define JS_BUTTON_LEFT 0x01 //!< joystick pulled left
+#define JS_BUTTON_PUSH 0x02 //!< joystick pushed
+#define JS_BUTTON_DOWN 0x04 //!< joystick pulled down
+#define JS_BUTTON_UP 0x08 //!< joystick pulled up
+#define JS_BUTTON_RIGHT 0x10 //!< joystick pulled right
+#define LCD_UPPER_LINE 0x00 //!< LCD upper line
+#define LCD_LOWER_LINE 0x40 //!< LCD lower line
+#define LCD_CONTRAST_LOW 0x00 //!< LCD Low contrast
+#define LCD_CONTRAST_MEDIUM 0x02 //!< LCD Medium contrast
+#define LCD_CONTRAST_HIGH 0x08 //!< LCD High contrast
+
+
+/**
+ * @brief Function for initializing the LCD display prior to writing.
+ * @return
+ * @retval true Operation succeeded
+ * @retval false Operation failed
+ */
+bool nrf6350_lcd_init(void);
+
+/**
+ * @brief Function for writing a text string on the LCD-display.
+ *
+ * @param p_text A pointer to the text string to be written
+ * @param size Size of the text string to be written
+ * @param line The line the text should be written to
+ * @param pos The start position of the text on the line
+ * @return
+ * @retval true Write succeeded
+ * @retval false Write failed
+ */
+bool nrf6350_lcd_write_string(const char *p_text, uint8_t size, uint8_t line, uint8_t pos);
+
+/**
+ * @brief Function for clearing the contents of the LCD-display.
+ *
+ * @return
+ * @retval true Operation succeeded
+ * @retval false Operation failed
+ */
+bool nrf6350_lcd_clear(void);
+
+/**
+ * @brief Function for adjusting the contrast of the LCD-display, select between
+ * LCD_CONTRAST_LOW, LCD_CONTRAST_MEDIUM and LCD_CONTRAST_HIGH.
+ *
+ * @param contrast The desired contrast of the lcd display
+ * @return
+ * @retval true Operation succeeded
+ * @retval false Operation failed
+ */
+bool nrf6350_lcd_set_contrast(uint8_t contrast);
+
+/**
+ * @brief Function for turning ON the LCD-display.
+ *
+ * @return
+ * @retval true Operation succeeded
+ * @retval false Operation failed
+ */
+bool nrf6350_lcd_on(void);
+
+/**
+ * @brief Function for turning OFF the LCD-display.
+ *
+ * @return
+ * @retval true Operation succeeded
+ * @retval false Operation failed
+ */
+bool nrf6350_lcd_off(void);
+
+/**
+ * @brief Function for getting the position of the joystick.
+ *
+ * @param val pointer to a 2 byte array where the X,Y position is stored
+ * @return
+ * @retval true Operation succeeded
+ * @retval false Operation failed
+ */
+bool nrf6350_js_get_value(int8_t *val);
+
+/**
+ * @brief Function for getting the status of the joystick.
+ *
+ * @param js_state pointer to a uint8_t that receives the status of the joystick
+ * @return
+ * @retval true Operation succeeded
+ * @retval false Operation failed
+ */
+bool nrf6350_js_get_status(uint8_t *js_state);
+
+/** @brief Function for transferring data over TWI bus. Used the first time you want to communicate nRF6350 to bypass a fail.
+ */
+bool nrf6350_lcd_wake_up(void);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // NRF6350_H_
+/** @} */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/drivers_ext/st7735/st7735.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/drivers_ext/st7735/st7735.c
new file mode 100644
index 0000000..8821525
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/drivers_ext/st7735/st7735.c
@@ -0,0 +1,474 @@
+/**
+ * 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+
+#include "sdk_common.h"
+
+#if NRF_MODULE_ENABLED(ST7735)
+
+#include "nrf_lcd.h"
+#include "nrf_drv_spi.h"
+#include "nrf_delay.h"
+#include "nrf_gpio.h"
+#include "boards.h"
+
+// Set of commands described in ST7735 data sheet.
+#define ST7735_NOP 0x00
+#define ST7735_SWRESET 0x01
+#define ST7735_RDDID 0x04
+#define ST7735_RDDST 0x09
+
+#define ST7735_SLPIN 0x10
+#define ST7735_SLPOUT 0x11
+#define ST7735_PTLON 0x12
+#define ST7735_NORON 0x13
+
+#define ST7735_INVOFF 0x20
+#define ST7735_INVON 0x21
+#define ST7735_DISPOFF 0x28
+#define ST7735_DISPON 0x29
+#define ST7735_CASET 0x2A
+#define ST7735_RASET 0x2B
+#define ST7735_RAMWR 0x2C
+#define ST7735_RAMRD 0x2E
+
+#define ST7735_PTLAR 0x30
+#define ST7735_COLMOD 0x3A
+#define ST7735_MADCTL 0x36
+
+#define ST7735_FRMCTR1 0xB1
+#define ST7735_FRMCTR2 0xB2
+#define ST7735_FRMCTR3 0xB3
+#define ST7735_INVCTR 0xB4
+#define ST7735_DISSET5 0xB6
+
+#define ST7735_PWCTR1 0xC0
+#define ST7735_PWCTR2 0xC1
+#define ST7735_PWCTR3 0xC2
+#define ST7735_PWCTR4 0xC3
+#define ST7735_PWCTR5 0xC4
+#define ST7735_VMCTR1 0xC5
+
+#define ST7735_RDID1 0xDA
+#define ST7735_RDID2 0xDB
+#define ST7735_RDID3 0xDC
+#define ST7735_RDID4 0xDD
+
+#define ST7735_PWCTR6 0xFC
+
+#define ST7735_GMCTRP1 0xE0
+#define ST7735_GMCTRN1 0xE1
+
+#define ST7735_MADCTL_MY 0x80
+#define ST7735_MADCTL_MX 0x40
+#define ST7735_MADCTL_MV 0x20
+#define ST7735_MADCTL_ML 0x10
+#define ST7735_MADCTL_RGB 0x00
+#define ST7735_MADCTL_BGR 0x08
+#define ST7735_MADCTL_MH 0x04
+/* @} */
+
+#define RGB2BGR(x) (x << 11) | (x & 0x07E0) | (x >> 11)
+
+static const nrf_drv_spi_t spi = NRF_DRV_SPI_INSTANCE(ST7735_SPI_INSTANCE); /**< SPI instance. */
+
+/**
+ * @brief Structure holding ST7735 controller basic parameters.
+ */
+typedef struct
+{
+ uint8_t tab_color; /**< Color of tab attached to the used screen. */
+}st7735_t;
+
+/**
+ * @brief Enumerator with TFT tab colors.
+ */
+typedef enum{
+ INITR_GREENTAB = 0, /**< Green tab. */
+ INITR_REDTAB, /**< Red tab. */
+ INITR_BLACKTAB, /**< Black tab. */
+ INITR_144GREENTAB /**< Green tab, 1.44" display. */
+}st7735_tab_t;
+
+static st7735_t m_st7735;
+
+static inline void spi_write(const void * data, size_t size)
+{
+ APP_ERROR_CHECK(nrf_drv_spi_transfer(&spi, data, size, NULL, 0));
+}
+
+static inline void write_command(uint8_t c)
+{
+ nrf_gpio_pin_clear(ST7735_DC_PIN);
+ spi_write(&c, sizeof(c));
+}
+
+static inline void write_data(uint8_t c)
+{
+ nrf_gpio_pin_set(ST7735_DC_PIN);
+ spi_write(&c, sizeof(c));
+}
+
+static void set_addr_window(uint8_t x0, uint8_t y0, uint8_t x1, uint8_t y1)
+{
+ ASSERT(x0 <= x1);
+ ASSERT(y0 <= y1);
+
+ write_command(ST7735_CASET);
+ write_data(0x00); // For a 128x160 display, it is always 0.
+ write_data(x0);
+ write_data(0x00); // For a 128x160 display, it is always 0.
+ write_data(x1);
+ write_command(ST7735_RASET);
+ write_data(0x00); // For a 128x160 display, it is always 0.
+ write_data(y0);
+ write_data(0x00); // For a 128x160 display, it is always 0.
+ write_data(y1);
+ write_command(ST7735_RAMWR);
+}
+
+static void command_list(void)
+{
+ write_command(ST7735_SWRESET);
+ nrf_delay_ms(150);
+ write_command(ST7735_SLPOUT);
+ nrf_delay_ms(500);
+
+ write_command(ST7735_FRMCTR1);
+ write_data(0x01);
+ write_data(0x2C);
+ write_data(0x2D);
+ write_command(ST7735_FRMCTR2);
+ write_data(0x01);
+ write_data(0x2C);
+ write_data(0x2D);
+ write_command(ST7735_FRMCTR3);
+ write_data(0x01);
+ write_data(0x2C);
+ write_data(0x2D);
+ write_data(0x01);
+ write_data(0x2C);
+ write_data(0x2D);
+
+ write_command(ST7735_INVCTR);
+ write_data(0x07);
+
+ write_command(ST7735_PWCTR1);
+ write_data(0xA2);
+ write_data(0x02);
+ write_data(0x84);
+ write_command(ST7735_PWCTR2);
+ write_data(0xC5);
+ write_command(ST7735_PWCTR3);
+ write_data(0x0A);
+ write_data(0x00);
+ write_command(ST7735_PWCTR3);
+ write_data(0x8A);
+ write_data(0x2A);
+ write_command(ST7735_PWCTR5);
+ write_data(0x8A);
+ write_data(0xEE);
+ write_data(0x0E);
+
+ write_command(ST7735_INVOFF);
+ write_command(ST7735_MADCTL);
+ write_data(0xC8);
+
+ write_command(ST7735_COLMOD);
+ write_data(0x05);
+
+ if (m_st7735.tab_color == INITR_GREENTAB)
+ {
+ write_command(ST7735_CASET);
+ write_data(0x00);
+ write_data(0x02);
+ write_data(0x00);
+ write_data(0x81);
+ write_command(ST7735_RASET);
+ write_data(0x00);
+ write_data(0x01);
+ write_data(0x00);
+ write_data(0xA0);
+ }
+ else if (m_st7735.tab_color == INITR_144GREENTAB)
+ {
+ write_command(ST7735_CASET);
+ write_data(0x00);
+ write_data(0x00);
+ write_data(0x00);
+ write_data(0x7F);
+ write_command(ST7735_RASET);
+ write_data(0x00);
+ write_data(0x00);
+ write_data(0x00);
+ write_data(0x7F);
+ }
+ else if (m_st7735.tab_color == INITR_REDTAB)
+ {
+ write_command(ST7735_CASET);
+ write_data(0x00);
+ write_data(0x00);
+ write_data(0x00);
+ write_data(0x7F);
+ write_command(ST7735_RASET);
+ write_data(0x00);
+ write_data(0x00);
+ write_data(0x00);
+ write_data(0x9F);
+ }
+
+ write_command(ST7735_GMCTRP1);
+ write_data(0x02);
+ write_data(0x1c);
+ write_data(0x07);
+ write_data(0x12);
+ write_data(0x37);
+ write_data(0x32);
+ write_data(0x29);
+ write_data(0x2d);
+ write_data(0x29);
+ write_data(0x25);
+ write_data(0x2b);
+ write_data(0x39);
+ write_data(0x00);
+ write_data(0x01);
+ write_data(0x03);
+ write_data(0x10);
+ write_command(ST7735_GMCTRN1);
+ write_data(0x03);
+ write_data(0x1d);
+ write_data(0x07);
+ write_data(0x06);
+ write_data(0x2e);
+ write_data(0x2c);
+ write_data(0x29);
+ write_data(0x2d);
+ write_data(0x2e);
+ write_data(0x2e);
+ write_data(0x37);
+ write_data(0x3f);
+ write_data(0x00);
+ write_data(0x00);
+ write_data(0x02);
+ write_data(0x10);
+
+ write_command(ST7735_NORON);
+ nrf_delay_ms(10);
+ write_command(ST7735_DISPON);
+ nrf_delay_ms(100);
+
+ if (m_st7735.tab_color == INITR_BLACKTAB)
+ {
+ write_command(ST7735_MADCTL);
+ write_data(0xC0);
+ }
+}
+
+
+static ret_code_t hardware_init(void)
+{
+ ret_code_t err_code;
+
+ nrf_gpio_cfg_output(ST7735_DC_PIN);
+
+ nrf_drv_spi_config_t spi_config = NRF_DRV_SPI_DEFAULT_CONFIG;
+
+ spi_config.sck_pin = ST7735_SCK_PIN;
+ spi_config.miso_pin = ST7735_MISO_PIN;
+ spi_config.mosi_pin = ST7735_MOSI_PIN;
+ spi_config.ss_pin = ST7735_SS_PIN;
+
+ err_code = nrf_drv_spi_init(&spi, &spi_config, NULL, NULL);
+ return err_code;
+}
+
+static ret_code_t st7735_init(void)
+{
+ ret_code_t err_code;
+
+ m_st7735.tab_color = ST7735_TAB_COLOR;
+
+ err_code = hardware_init();
+ if (err_code != NRF_SUCCESS)
+ {
+ return err_code;
+ }
+
+ command_list();
+
+ return err_code;
+}
+
+static void st7735_uninit(void)
+{
+ nrf_drv_spi_uninit(&spi);
+}
+
+static void st7735_pixel_draw(uint16_t x, uint16_t y, uint32_t color)
+{
+ set_addr_window(x, y, x, y);
+
+ color = RGB2BGR(color);
+
+ const uint8_t data[2] = {color >> 8, color};
+
+ nrf_gpio_pin_set(ST7735_DC_PIN);
+
+ spi_write(data, sizeof(data));
+
+ nrf_gpio_pin_clear(ST7735_DC_PIN);
+}
+
+static void st7735_rect_draw(uint16_t x, uint16_t y, uint16_t width, uint16_t height, uint32_t color)
+{
+ set_addr_window(x, y, x + width - 1, y + height - 1);
+
+ color = RGB2BGR(color);
+
+ const uint8_t data[2] = {color >> 8, color};
+
+ nrf_gpio_pin_set(ST7735_DC_PIN);
+
+ // Duff's device algorithm for optimizing loop.
+ uint32_t i = (height * width + 7) / 8;
+
+/*lint -save -e525 -e616 -e646 */
+ switch ((height * width) % 8) {
+ case 0:
+ do {
+ spi_write(data, sizeof(data));
+ case 7:
+ spi_write(data, sizeof(data));
+ case 6:
+ spi_write(data, sizeof(data));
+ case 5:
+ spi_write(data, sizeof(data));
+ case 4:
+ spi_write(data, sizeof(data));
+ case 3:
+ spi_write(data, sizeof(data));
+ case 2:
+ spi_write(data, sizeof(data));
+ case 1:
+ spi_write(data, sizeof(data));
+ } while (--i > 0);
+ default:
+ break;
+ }
+/*lint -restore */
+ nrf_gpio_pin_clear(ST7735_DC_PIN);
+}
+
+static void st7735_dummy_display(void)
+{
+ /* No implementation needed. */
+}
+
+static void st7735_rotation_set(nrf_lcd_rotation_t rotation)
+{
+ write_command(ST7735_MADCTL);
+ switch (rotation) {
+ case NRF_LCD_ROTATE_0:
+ if (m_st7735.tab_color == INITR_BLACKTAB)
+ {
+ write_data(ST7735_MADCTL_MX | ST7735_MADCTL_MY | ST7735_MADCTL_RGB);
+ }
+ else
+ {
+ write_data(ST7735_MADCTL_MX | ST7735_MADCTL_MY | ST7735_MADCTL_BGR);
+ }
+ break;
+ case NRF_LCD_ROTATE_90:
+ if (m_st7735.tab_color == INITR_BLACKTAB)
+ {
+ write_data(ST7735_MADCTL_MY | ST7735_MADCTL_MV | ST7735_MADCTL_RGB);
+ }
+ else
+ {
+ write_data(ST7735_MADCTL_MY | ST7735_MADCTL_MV | ST7735_MADCTL_BGR);
+ }
+ break;
+ case NRF_LCD_ROTATE_180:
+ if (m_st7735.tab_color == INITR_BLACKTAB)
+ {
+ write_data(ST7735_MADCTL_RGB);
+ }
+ else
+ {
+ write_data(ST7735_MADCTL_BGR);
+ }
+ break;
+ case NRF_LCD_ROTATE_270:
+ if (m_st7735.tab_color == INITR_BLACKTAB)
+ {
+ write_data(ST7735_MADCTL_MX | ST7735_MADCTL_MV | ST7735_MADCTL_RGB);
+ }
+ else
+ {
+ write_data(ST7735_MADCTL_MX | ST7735_MADCTL_MV | ST7735_MADCTL_BGR);
+ }
+ break;
+ default:
+ break;
+ }
+}
+
+
+static void st7735_display_invert(bool invert)
+{
+ write_command(invert ? ST7735_INVON : ST7735_INVOFF);
+}
+
+static lcd_cb_t st7735_cb = {
+ .height = ST7735_HEIGHT,
+ .width = ST7735_WIDTH
+};
+
+const nrf_lcd_t nrf_lcd_st7735 = {
+ .lcd_init = st7735_init,
+ .lcd_uninit = st7735_uninit,
+ .lcd_pixel_draw = st7735_pixel_draw,
+ .lcd_rect_draw = st7735_rect_draw,
+ .lcd_display = st7735_dummy_display,
+ .lcd_rotation_set = st7735_rotation_set,
+ .lcd_display_invert = st7735_display_invert,
+ .p_lcd_cb = &st7735_cb
+};
+
+#endif // NRF_MODULE_ENABLED(ST7735)
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/drivers_ext/sx1509b/sx1509b.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/drivers_ext/sx1509b/sx1509b.c
new file mode 100644
index 0000000..03ac91a
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/drivers_ext/sx1509b/sx1509b.c
@@ -0,0 +1,1002 @@
+/**
+ * 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#include "sx1509b.h"
+
+static sx1509b_instance_t * m_p_instances;
+static uint8_t m_max_instance_count;
+static uint8_t m_inst_count;
+
+#define RETURN_IF_ERR(_err) \
+ if (_err != NRF_SUCCESS)\
+ { \
+ return _err; \
+ }
+
+/**
+ * ===============================================================================================
+ * @brief General expander utility functions.
+ */
+
+void sx1509b_init(sx1509b_instance_t * p_instances, uint8_t count)
+{
+ ASSERT(p_instances != NULL);
+ m_p_instances = p_instances;
+ m_max_instance_count = count;
+ m_inst_count = 0;
+}
+
+static void sx1509b_default_cfg_set(uint8_t instance_num)
+{
+ m_p_instances[instance_num].start_addr = 0x00;
+ for (uint8_t i = SX1509B_REG_INPUT_DISABLE_B; i < SX1509B_REG_DIR_B; i++)
+ {
+ m_p_instances[instance_num].registers[i] = 0;
+ }
+ for (uint8_t i = SX1509B_REG_DIR_B; i < SX1509B_REG_SENSE_H_B; i++)
+ {
+ m_p_instances[instance_num].registers[i] = 0xFF;
+ }
+ for (uint8_t i = SX1509B_REG_SENSE_H_B; i < SX1509B_REG_KEY_DATA_1; i++)
+ {
+ m_p_instances[instance_num].registers[i] = 0;
+ }
+ m_p_instances[instance_num].registers[SX1509B_REG_KEY_DATA_1] = 0xFF;
+ m_p_instances[instance_num].registers[SX1509B_REG_KEY_DATA_2] = 0xFF;
+ m_p_instances[instance_num].registers[SX1509B_REG_MISC] = 0x01;
+ m_p_instances[instance_num].high_input[0] = 0;
+ m_p_instances[instance_num].high_input[1] = 0;
+
+}
+ret_code_t sx1509b_add_instance(nrf_twi_sensor_t * p_twi_sensor,
+ uint8_t sensor_address)
+{
+ ASSERT(p_twi_sensor != NULL);
+ if (m_p_instances == NULL)
+ {
+ return NRF_ERROR_MODULE_NOT_INITIALIZED;
+ }
+ if (m_inst_count >= m_max_instance_count)
+ {
+ return NRF_ERROR_STORAGE_FULL;
+ }
+ m_p_instances[m_inst_count].p_sensor_data = p_twi_sensor;
+ m_p_instances[m_inst_count].sensor_addr = sensor_address;
+ sx1509b_default_cfg_set(m_inst_count);
+ m_inst_count++;
+ ret_code_t err_code = sx1509b_cfg_write(m_inst_count - 1);
+
+ return err_code;
+}
+
+ret_code_t sx1509b_cfg_write(uint8_t instance_num)
+{
+ if (instance_num >= m_inst_count)
+ {
+ return NRF_ERROR_INVALID_PARAM;
+ }
+ ret_code_t err = nrf_twi_sensor_reg_write(m_p_instances[instance_num].p_sensor_data,
+ m_p_instances[instance_num].sensor_addr,
+ SX1509B_REG_HIGH_INPUT_B,
+ m_p_instances[instance_num].high_input,
+ 2);
+ RETURN_IF_ERR(err);
+ return nrf_twi_sensor_write(m_p_instances[instance_num].p_sensor_data,
+ m_p_instances[instance_num].sensor_addr,
+ &m_p_instances[instance_num].start_addr,
+ SX1509B_REG_COUNT + 1,
+ false);
+}
+
+ret_code_t sx1509b_cfg_read(uint8_t instance_num)
+{
+ if (instance_num >= m_inst_count)
+ {
+ return NRF_ERROR_INVALID_PARAM;
+ }
+ ret_code_t err = nrf_twi_sensor_reg_read(m_p_instances[instance_num].p_sensor_data,
+ m_p_instances[instance_num].sensor_addr,
+ SX1509B_REG_HIGH_INPUT_B,
+ NULL,
+ m_p_instances[instance_num].high_input,
+ 2);
+ RETURN_IF_ERR(err);
+ return nrf_twi_sensor_reg_read(m_p_instances[instance_num].p_sensor_data,
+ m_p_instances[instance_num].sensor_addr,
+ m_p_instances[instance_num].start_addr,
+ NULL,
+ m_p_instances[instance_num].registers,
+ SX1509B_REG_COUNT);
+}
+
+ret_code_t sx1509b_clock_set(uint8_t instance_num, sx1509b_clock_t source, bool oscio_set, uint8_t oscio_freq)
+{
+ if (instance_num >= m_inst_count)
+ {
+ return NRF_ERROR_INVALID_PARAM;
+ }
+ uint8_t * p_reg_val = &m_p_instances[instance_num].registers[SX1509B_REG_CLOCK];
+
+ NRF_TWI_SENSOR_REG_SET(*p_reg_val, SX1509B_OSC_SRC_MASK, SX1509B_OSC_SRC_POS, source);
+ NRF_TWI_SENSOR_REG_SET(*p_reg_val, SX1509B_OSCIO_PIN_MASK, SX1509B_OSCIO_PIN_POS, oscio_set);
+ NRF_TWI_SENSOR_REG_SET(*p_reg_val,
+ SX1509B_OSCOUT_FREQ_MASK,
+ SX1509B_OSCOUT_FREQ_POS,
+ oscio_freq);
+
+ uint8_t send_msg[] = {
+ SX1509B_REG_CLOCK,
+ *p_reg_val
+ };
+ return nrf_twi_sensor_write(m_p_instances[instance_num].p_sensor_data,
+ m_p_instances[instance_num].sensor_addr,
+ send_msg,
+ ARRAY_SIZE(send_msg),
+ true);
+}
+
+ret_code_t sx1509b_misc_set(uint8_t instance_num,
+ bool nreset_func,
+ sx1509b_debounce_t debounce_time,
+ bool autoclear_nint)
+{
+ if (instance_num >= m_inst_count)
+ {
+ return NRF_ERROR_INVALID_PARAM;
+ }
+ uint8_t * p_reg_val = &m_p_instances[instance_num].registers[SX1509B_REG_MISC];
+
+ NRF_TWI_SENSOR_REG_SET(*p_reg_val, SX1509B_NRESET_PIN_MASK, SX1509B_NRESET_PIN_POS, nreset_func);
+ NRF_TWI_SENSOR_REG_SET(*p_reg_val,
+ SX1509B_AUTO_CLEAR_NINT_MASK,
+ SX1509B_AUTO_CLEAR_NINT_POS,
+ autoclear_nint);
+ uint8_t send_msg[] = {
+ SX1509B_REG_MISC,
+ *p_reg_val
+ };
+ ret_code_t err = nrf_twi_sensor_write(m_p_instances[instance_num].p_sensor_data,
+ m_p_instances[instance_num].sensor_addr,
+ send_msg,
+ ARRAY_SIZE(send_msg),
+ true);
+ RETURN_IF_ERR(err);
+ m_p_instances[instance_num].registers[SX1509B_REG_DEBOUNCE_CONFIG] = debounce_time;
+ send_msg[0] = SX1509B_REG_DEBOUNCE_CONFIG;
+ send_msg[1] = debounce_time;
+
+ return nrf_twi_sensor_write(m_p_instances[instance_num].p_sensor_data,
+ m_p_instances[instance_num].sensor_addr,
+ send_msg,
+ ARRAY_SIZE(send_msg),
+ true);
+
+}
+
+ret_code_t sx1509b_sw_reset(uint8_t instance_num)
+{
+ if (instance_num >= m_inst_count)
+ {
+ return NRF_ERROR_INVALID_PARAM;
+ }
+ uint8_t send_msg[] = {
+ SX1509B_REG_SW_RESET,
+ SX1509B_INNER_RESET_BYTE1
+ };
+ ret_code_t err = nrf_twi_sensor_write(m_p_instances[instance_num].p_sensor_data,
+ m_p_instances[instance_num].sensor_addr,
+ send_msg,
+ ARRAY_SIZE(send_msg),
+ true);
+ RETURN_IF_ERR(err);
+ send_msg[1] = SX1509B_INNER_RESET_BYTE2;
+ err = nrf_twi_sensor_write(m_p_instances[instance_num].p_sensor_data,
+ m_p_instances[instance_num].sensor_addr,
+ send_msg,
+ ARRAY_SIZE(send_msg),
+ true);
+ RETURN_IF_ERR(err);
+ sx1509b_default_cfg_set(instance_num);
+ return err;
+}
+
+ret_code_t sx1509b_pin_cfg_reg_set(sx1509b_registers_t reg, uint32_t pin, uint8_t set)
+{
+ if (pin >= SX1509B_INNER_PIN_COUNT * m_inst_count)
+ {
+ return NRF_ERROR_INVALID_PARAM;
+ }
+
+ uint8_t inst_num = pin / SX1509B_INNER_PIN_COUNT;
+ pin %= SX1509B_INNER_PIN_COUNT;
+ uint8_t * p_reg_val;
+
+ uint8_t reg_addr = reg;
+ uint32_t mask = 1;
+ if (reg_addr == SX1509B_REG_LEVEL_SHIFTER_1)
+ {
+ mask = 3; // Level shifter register parameter is 2 bits long.
+ pin %= SX1509B_INNER_NEXT_BANK;
+ pin *= 2;
+ }
+ if (reg_addr == SX1509B_REG_SENSE_H_B)
+ {
+ reg_addr += 3 - (pin / SX1509B_INNER_SENSE_REG_NUM); // Setting correct sense register
+ pin %= SX1509B_INNER_SENSE_REG_NUM;
+ pin *= 2; // Multiplying by 2 to make space for 2 bits.
+ mask = 3; // Sense register parameter is 2 bits long.
+ }
+ else
+ {
+ if (pin >= SX1509B_INNER_NEXT_BANK)
+ {
+ reg_addr = reg;
+ pin -= SX1509B_INNER_NEXT_BANK;
+ }
+ else
+ {
+ reg_addr = reg + 1; // Moving to bank A registers
+
+ }
+ }
+
+ p_reg_val = &m_p_instances[inst_num].registers[reg_addr];
+
+ NRF_TWI_SENSOR_REG_SET(*p_reg_val, (mask<<pin), pin, set);
+ uint8_t send_msg[] = {
+ reg_addr,
+ *p_reg_val
+ };
+ return nrf_twi_sensor_write(m_p_instances[inst_num].p_sensor_data,
+ m_p_instances[inst_num].sensor_addr,
+ send_msg,
+ ARRAY_SIZE(send_msg),
+ true);
+}
+
+uint8_t sx1509b_pin_cfg_reg_get(sx1509b_registers_t reg, uint32_t pin)
+{
+ if (pin >= SX1509B_INNER_PIN_COUNT * m_inst_count)
+ {
+ return 0xFF;
+ }
+
+ uint8_t inst_num = pin / SX1509B_INNER_PIN_COUNT;
+ pin %= SX1509B_INNER_PIN_COUNT;
+ uint8_t * p_reg_val;
+ uint8_t reg_addr = reg;
+ uint8_t mask = 1;
+ if (reg_addr == SX1509B_REG_LEVEL_SHIFTER_1)
+ {
+ mask = 3; // Level shifter register parameter is 2 bits long.
+ pin %= SX1509B_INNER_NEXT_BANK;
+ pin *= 2;
+ }
+ if (reg_addr >= SX1509B_REG_SENSE_H_B && reg_addr <= SX1509B_REG_SENSE_L_A)
+ {
+ reg_addr += 3 - (pin / SX1509B_INNER_SENSE_REG_NUM); // Setting correct sense register
+ pin %= SX1509B_INNER_SENSE_REG_NUM;
+ pin *= 2; // Multiplying by 2 to make space for 2 bits.
+ mask = 3; // Sense register parameter is 2 bits long.
+ }
+ else
+ {
+ reg_addr += (pin >= SX1509B_INNER_NEXT_BANK) ? 0 : 1;
+ pin %= SX1509B_INNER_NEXT_BANK;
+ }
+ p_reg_val = &m_p_instances[inst_num].registers[reg_addr];
+
+ return NRF_TWI_SENSOR_REG_VAL_GET(*p_reg_val,(mask<<pin),pin);
+}
+
+ret_code_t sx1509b_port_cfg_reg_set(sx1509b_registers_t reg,
+ uint32_t port,
+ uint8_t mask,
+ sx1509b_port_op_t flag)
+{
+ if (port >= SX1509B_INNER_PORT_COUNT * m_inst_count)
+ {
+ return NRF_ERROR_INVALID_PARAM;
+ }
+
+ uint8_t inst_num = port / SX1509B_INNER_PORT_COUNT;
+ port %= SX1509B_INNER_PORT_COUNT;
+ uint8_t reg_addr = reg + !port;
+
+ uint8_t * reg_val = &m_p_instances[inst_num].registers[reg_addr];
+
+ switch (flag)
+ {
+ case SX1509B_PORT_WRITE:
+ *reg_val = mask;
+ break;
+ case SX1509B_PORT_CLEAR:
+ *reg_val &= ~mask;
+ break;
+ case SX1509B_PORT_SET:
+ *reg_val |= mask;
+ break;
+ default:
+ return NRF_ERROR_INVALID_PARAM;
+ }
+ uint8_t send_msg[] = {
+ reg_addr,
+ *reg_val
+ };
+ return nrf_twi_sensor_write(m_p_instances[inst_num].p_sensor_data, m_p_instances[inst_num].sensor_addr, send_msg, ARRAY_SIZE(send_msg), true);
+}
+
+uint8_t sx1509b_port_cfg_reg_get(sx1509b_registers_t reg, uint32_t port)
+{
+ if (port >= SX1509B_INNER_PORT_COUNT * m_inst_count)
+ {
+ return 0;
+ }
+
+ uint8_t inst_num = port / SX1509B_INNER_PORT_COUNT;
+ port %= SX1509B_INNER_PORT_COUNT;
+ uint8_t reg_addr = reg + !port;
+ return m_p_instances[inst_num].registers[reg_addr];
+}
+
+ret_code_t sx1509b_pin_data_update(nrf_twi_sensor_reg_cb_t user_cb)
+{
+ ret_code_t err_code;
+ for (uint8_t i = 0; i < m_inst_count - 1; i++)
+ {
+ err_code = nrf_twi_sensor_reg_read(m_p_instances[i].p_sensor_data,
+ m_p_instances[i].sensor_addr,
+ SX1509B_REG_DATA_B,
+ NULL,
+ &m_p_instances[i].registers[SX1509B_REG_DATA_B],
+ 2);
+ RETURN_IF_ERR(err_code);
+ }
+ return nrf_twi_sensor_reg_read(m_p_instances[m_inst_count - 1].p_sensor_data,
+ m_p_instances[m_inst_count - 1].sensor_addr,
+ SX1509B_REG_DATA_B,
+ user_cb,
+ &m_p_instances[m_inst_count - 1].registers[SX1509B_REG_DATA_B],
+ 2);
+}
+
+ret_code_t sx1509b_pin_latch_update(nrf_twi_sensor_reg_cb_t user_cb)
+{
+ ret_code_t err_code;
+ for (uint8_t i = 0; i < m_inst_count - 1; i++) // -1 so last read triggers callback
+ {
+ err_code = nrf_twi_sensor_reg_read(m_p_instances[i].p_sensor_data,
+ m_p_instances[i].sensor_addr,
+ SX1509B_REG_INT_SRC_B,
+ NULL,
+ &m_p_instances[i].registers[SX1509B_REG_INT_SRC_B],
+ 2);
+ RETURN_IF_ERR(err_code);
+ }
+ return nrf_twi_sensor_reg_read(m_p_instances[m_inst_count - 1].p_sensor_data,
+ m_p_instances[m_inst_count - 1].sensor_addr,
+ SX1509B_REG_INT_SRC_B,
+ user_cb,
+ &m_p_instances[m_inst_count - 1].registers[SX1509B_REG_INT_SRC_B],
+ 2);
+}
+
+
+
+
+ret_code_t sx1509b_pin_high_input(uint32_t pin_number, bool set)
+{
+ if (pin_number >= SX1509B_INNER_PIN_COUNT * m_inst_count)
+ {
+ return NRF_ERROR_INVALID_PARAM;
+ }
+
+ uint8_t inst_num = pin_number / SX1509B_INNER_PIN_COUNT;
+ pin_number %= SX1509B_INNER_PIN_COUNT;
+ uint8_t reg_addr;
+ uint8_t * p_reg_val;
+ if (pin_number < SX1509B_INNER_NEXT_BANK)
+ {
+ reg_addr = SX1509B_REG_HIGH_INPUT_A;
+ p_reg_val = &m_p_instances[inst_num].high_input[1];
+ }
+ else
+ {
+ reg_addr = SX1509B_REG_HIGH_INPUT_B;
+ p_reg_val = &m_p_instances[inst_num].high_input[0];
+ pin_number -= SX1509B_INNER_NEXT_BANK;
+ }
+ NRF_TWI_SENSOR_REG_SET(*p_reg_val, (1U << pin_number), pin_number, set);
+ uint8_t send_msg[] = {
+ reg_addr,
+ *p_reg_val
+ };
+ return nrf_twi_sensor_write(m_p_instances[inst_num].p_sensor_data,
+ m_p_instances[inst_num].sensor_addr,
+ send_msg,
+ ARRAY_SIZE(send_msg),
+ true);
+}
+
+
+ret_code_t sx1509b_port_high_input(uint8_t port_num, uint8_t out_mask, sx1509b_port_op_t flag)
+{
+ if (port_num >= SX1509B_INNER_PORT_COUNT * m_inst_count)
+ {
+ return NRF_ERROR_INVALID_PARAM;
+ }
+
+ uint8_t inst_num = port_num / SX1509B_INNER_PORT_COUNT;
+ port_num %= SX1509B_INNER_PORT_COUNT;
+ uint8_t reg_addr = SX1509B_REG_HIGH_INPUT_B + !port_num;
+
+ uint8_t * reg_val = &m_p_instances[inst_num].high_input[!port_num];
+
+ switch (flag)
+ {
+ case SX1509B_PORT_WRITE:
+ *reg_val = out_mask;
+ break;
+ case SX1509B_PORT_CLEAR:
+ *reg_val &= ~out_mask;
+ break;
+ case SX1509B_PORT_SET:
+ *reg_val |= out_mask;
+ break;
+ default:
+ return NRF_ERROR_INVALID_PARAM;
+ }
+ uint8_t send_msg[] = {
+ reg_addr,
+ *reg_val
+ };
+ return nrf_twi_sensor_write(m_p_instances[inst_num].p_sensor_data,
+ m_p_instances[inst_num].sensor_addr,
+ send_msg,
+ ARRAY_SIZE(send_msg),
+ true);
+
+}
+
+/**
+ * ===============================================================================================
+ * @brief Functions compatible with nrf_gpio
+ */
+
+
+
+ret_code_t sx1509b_pin_cfg_input(uint32_t pin_number, sx1509b_pin_pull_t pull_config)
+{
+ ret_code_t err_code = sx1509b_pin_cfg_reg_set(SX1509B_REG_DIR_B, pin_number, SX1509B_PIN_DIR_INPUT);
+ RETURN_IF_ERR(err_code);
+ err_code = sx1509b_pin_cfg_reg_set(SX1509B_REG_INPUT_DISABLE_B, pin_number, 0);
+ RETURN_IF_ERR(err_code);
+ switch (pull_config)
+ {
+ case SX1509B_PIN_NOPULL:
+ err_code = sx1509b_pin_cfg_reg_set(SX1509B_REG_PULL_DOWN_B, pin_number, 0);
+ RETURN_IF_ERR(err_code);
+ err_code = sx1509b_pin_cfg_reg_set(SX1509B_REG_PULL_UP_B, pin_number, 0);
+ break;
+ case SX1509B_PIN_PULLDOWN:
+ err_code = sx1509b_pin_cfg_reg_set(SX1509B_REG_PULL_DOWN_B, pin_number, 1);
+ RETURN_IF_ERR(err_code);
+ err_code = sx1509b_pin_cfg_reg_set(SX1509B_REG_PULL_UP_B, pin_number, 0);
+ break;
+ case SX1509B_PIN_PULLUP:
+ err_code = sx1509b_pin_cfg_reg_set(SX1509B_REG_PULL_DOWN_B, pin_number, 0);
+ RETURN_IF_ERR(err_code);
+ err_code = sx1509b_pin_cfg_reg_set(SX1509B_REG_PULL_UP_B, pin_number, 1);
+ break;
+ };
+ return err_code;
+}
+
+ret_code_t sx1509b_pin_cfg_default(uint32_t pin_number)
+{
+ if (pin_number >= SX1509B_INNER_PIN_COUNT * m_inst_count)
+ {
+ return NRF_ERROR_INVALID_PARAM;
+ }
+ uint8_t inst_num = pin_number / SX1509B_INNER_PIN_COUNT;
+ pin_number %= SX1509B_INNER_PIN_COUNT;
+ uint8_t reg = (pin_number >= SX1509B_INNER_NEXT_BANK) ? 0 : 1;
+ pin_number %= SX1509B_INNER_NEXT_BANK;
+
+ ret_code_t err_code = NRF_SUCCESS;
+ for (uint8_t i = SX1509B_REG_INPUT_DISABLE_B + reg; i < SX1509B_REG_DIR_B; i += 2)
+ {
+ if (IS_SET(m_p_instances[inst_num].registers[i], pin_number) == 1)
+ {
+ CLR_BIT(m_p_instances[inst_num].registers[i], pin_number);
+ err_code = nrf_twi_sensor_reg_write(m_p_instances[inst_num].p_sensor_data,
+ m_p_instances[inst_num].sensor_addr,
+ i,
+ &m_p_instances[inst_num].registers[i],
+ 1);
+ }
+ }
+ for (uint8_t i = SX1509B_REG_DIR_B + reg; i < SX1509B_REG_SENSE_H_B; i += 2)
+ {
+ if (IS_SET(m_p_instances[inst_num].registers[i], pin_number) == 0)
+ {
+ SET_BIT(m_p_instances[inst_num].registers[i], pin_number);
+ err_code = nrf_twi_sensor_reg_write(m_p_instances[inst_num].p_sensor_data,
+ m_p_instances[inst_num].sensor_addr,
+ i,
+ &m_p_instances[inst_num].registers[i],
+ 1);
+ }
+ }
+ for (uint8_t i = SX1509B_REG_SENSE_H_B + reg; i < SX1509B_REG_KEY_DATA_1; i += 2)
+ {
+ if (IS_SET(m_p_instances[inst_num].registers[i], pin_number) == 1)
+ {
+ CLR_BIT(m_p_instances[inst_num].registers[i], pin_number);
+ err_code = nrf_twi_sensor_reg_write(m_p_instances[inst_num].p_sensor_data,
+ m_p_instances[inst_num].sensor_addr,
+ i,
+ &m_p_instances[inst_num].registers[i],
+ 1);
+ }
+ }
+ return err_code;
+}
+
+ret_code_t sx1509b_pin_cfg_sense_input(uint32_t pin_number,
+ sx1509b_pin_pull_t pull_config,
+ sx1509b_pin_sense_t sense_config)
+{
+ ret_code_t err_code = sx1509b_pin_cfg_input(pin_number, pull_config);
+ RETURN_IF_ERR(err_code);
+ return sx1509b_pin_cfg_sense_set(pin_number, sense_config);
+}
+
+
+ret_code_t sx1509b_pin_cfg_sense_set(uint32_t pin_number, sx1509b_pin_sense_t sense_config)
+{
+ ret_code_t err;
+ if (sense_config == SX1509B_PIN_NOSENSE)
+ {
+ err = sx1509b_pin_cfg_reg_set(SX1509B_REG_INT_MASK_B, pin_number, 1);
+ RETURN_IF_ERR(err);
+ }
+ else
+ {
+ err = sx1509b_pin_cfg_reg_set(SX1509B_REG_INT_MASK_B, pin_number, 0);
+ RETURN_IF_ERR(err);
+ }
+ return sx1509b_pin_cfg_reg_set(SX1509B_REG_SENSE_H_B, pin_number, sense_config);
+}
+
+ret_code_t sx1509b_pin_dir_set(uint32_t pin_number, sx1509b_pin_dir_t direction)
+{
+ if (direction == SX1509B_PIN_DIR_INPUT)
+ {
+ return sx1509b_pin_cfg_input(pin_number, SX1509B_PIN_NOPULL);
+ }
+ else
+ {
+ return sx1509b_pin_cfg_output(pin_number);
+ }
+}
+
+ret_code_t sx1509b_ports_read(uint8_t start_port, uint32_t length, uint8_t * p_masks)
+{
+ if (start_port + length > SX1509B_INNER_PORT_COUNT * m_inst_count)
+ {
+ return NRF_ERROR_INVALID_LENGTH;
+ }
+
+ for (uint8_t i = 0; i < length; i++)
+ {
+ p_masks[i] = sx1509b_port_in_read(start_port + i);
+ }
+ return NRF_SUCCESS;
+}
+
+ret_code_t sx1509b_latches_read(uint8_t start_port, uint32_t length, uint8_t * p_masks)
+{
+ if (start_port + length > SX1509B_INNER_PORT_COUNT * m_inst_count)
+ {
+ return NRF_ERROR_INVALID_LENGTH;
+ }
+
+ for (uint8_t i = 0; i < length; i++)
+ {
+ p_masks[i] = sx1509b_port_cfg_reg_get(SX1509B_REG_INT_SRC_B, start_port + i);
+ }
+ return NRF_SUCCESS;
+}
+
+ret_code_t sx1509b_pin_latch_clear(uint32_t pin_number)
+{
+ ret_code_t err_code = sx1509b_pin_cfg_reg_set(SX1509B_REG_INT_SRC_B, pin_number, 1);
+ RETURN_IF_ERR(err_code);
+ uint8_t inst_num = pin_number / SX1509B_INNER_PIN_COUNT;
+ pin_number %= SX1509B_INNER_PIN_COUNT;
+ uint8_t reg = SX1509B_REG_INT_SRC_B;
+ reg += (pin_number >= SX1509B_INNER_NEXT_BANK) ? 0 : 1;
+ pin_number %= SX1509B_INNER_NEXT_BANK;
+ CLR_BIT(m_p_instances[inst_num].registers[reg], pin_number);
+ return err_code;
+}
+
+/**
+ * ===============================================================================================
+ * @brief Led driver functions.
+ */
+
+ret_code_t sx1509b_led_driver_enable(uint8_t instance_num, bool clock_internal, uint8_t frequency)
+{
+ if (instance_num >= m_inst_count)
+ {
+ return NRF_ERROR_INVALID_PARAM;
+ }
+
+ NRF_TWI_SENSOR_REG_SET(m_p_instances[instance_num].registers[SX1509B_REG_CLOCK],
+ SX1509B_OSC_SRC_MASK,
+ SX1509B_OSC_SRC_POS,
+ (clock_internal == 1) ? 2 : 1);
+ NRF_TWI_SENSOR_REG_SET(m_p_instances[instance_num].registers[SX1509B_REG_MISC],
+ SX1509B_LED_FREQ_MASK,
+ SX1509B_LED_FREQ_POS,
+ frequency);
+ uint8_t send_msg[] = {
+ SX1509B_REG_CLOCK,
+ m_p_instances[instance_num].registers[SX1509B_REG_CLOCK],
+ m_p_instances[instance_num].registers[SX1509B_REG_MISC]
+ };
+ return nrf_twi_sensor_write(m_p_instances[instance_num].p_sensor_data,
+ m_p_instances[instance_num].sensor_addr,
+ send_msg,
+ ARRAY_SIZE(send_msg),
+ true);
+}
+
+ret_code_t sx1509b_led_mode(uint8_t port_num, bool mode)
+{
+ if (port_num >= SX1509B_INNER_PORT_COUNT * m_inst_count)
+ {
+ return NRF_ERROR_INVALID_PARAM;
+ }
+
+ uint8_t inst_num = port_num / SX1509B_INNER_PORT_COUNT;
+ port_num %= SX1509B_INNER_PORT_COUNT;
+ uint8_t *p_reg_val = &m_p_instances[inst_num].registers[SX1509B_REG_MISC];
+
+ if (port_num == 1)
+ {
+ NRF_TWI_SENSOR_REG_SET(*p_reg_val, SX1509B_LED_MODE_B_MASK, SX1509B_LED_MODE_B_POS, mode);
+ }
+ else
+ {
+ NRF_TWI_SENSOR_REG_SET(*p_reg_val, SX1509B_LED_MODE_A_MASK, SX1509B_LED_MODE_A_POS, mode);
+ }
+ uint8_t send_msg[] = {
+ SX1509B_REG_MISC,
+ *p_reg_val
+ };
+ return nrf_twi_sensor_write(m_p_instances[inst_num].p_sensor_data,
+ m_p_instances[inst_num].sensor_addr,
+ send_msg,
+ ARRAY_SIZE(send_msg),
+ true);
+}
+
+uint8_t sx1509b_led_driver_get_reg(uint32_t pin_number)
+{
+ uint8_t reg;
+ bool fade_reg = false;
+ if (pin_number >= SX1509B_INNER_NEXT_BANK)
+ {
+ pin_number %= SX1509B_INNER_NEXT_BANK;
+ if (pin_number >= SX1509B_LED_DRIVER_TIME_REG_NUM)
+ {
+ reg = SX1509B_REG_LED_FADE_B_START;
+ fade_reg = true;
+ }
+ else
+ {
+ reg = SX1509B_REG_LED_BANK_B_START;
+ }
+ }
+ else
+ {
+ if (pin_number >= SX1509B_LED_DRIVER_TIME_REG_NUM)
+ {
+ reg = SX1509B_REG_LED_FADE_A_START;
+ fade_reg = true;
+ }
+ else
+ {
+ reg = SX1509B_REG_LED_BANK_A_START;
+ }
+ }
+
+ if (fade_reg == true)
+ {
+ pin_number %= SX1509B_LED_DRIVER_FADE_REG_NUM;
+ reg += SX1509B_LED_DRIVER_FADE_REG_LEN * pin_number;
+ }
+ else
+ {
+ pin_number %= SX1509B_LED_DRIVER_TIME_REG_NUM;
+ reg += SX1509B_LED_DRIVER_TIME_REG_LEN * pin_number;
+ }
+
+ return reg;
+}
+
+ret_code_t sx1509b_led_pin_time(uint32_t pin_number,
+ uint8_t on_time,
+ uint8_t on_intensity,
+ uint8_t off_time,
+ uint8_t off_intensity)
+{
+ uint8_t inst_num = pin_number / SX1509B_INNER_PIN_COUNT;
+ if (inst_num >= m_inst_count)
+ {
+ return NRF_ERROR_INVALID_PARAM;
+ }
+ pin_number %= SX1509B_INNER_PIN_COUNT;
+ uint8_t reg = sx1509b_led_driver_get_reg(pin_number);
+ uint8_t send_msg[] = {
+ reg,
+ on_time & 0x1F,
+ on_intensity,
+ (off_time << SX1509B_OFF_TIME_POS) | (off_intensity & SX1509B_OFF_INTENSITY_MASK)
+ };
+ return nrf_twi_sensor_write(m_p_instances[inst_num].p_sensor_data,
+ m_p_instances[inst_num].sensor_addr,
+ send_msg,
+ ARRAY_SIZE(send_msg),
+ true);
+}
+
+ret_code_t sx1509b_led_pin_fade(uint32_t pin_number, uint8_t fade_in, uint8_t fade_out)
+{
+ if ((pin_number % SX1509B_INNER_NEXT_BANK) <= SX1509B_LED_DRIVER_TIME_REG_LEN)
+ {
+ return NRF_ERROR_INVALID_PARAM;
+ }
+ uint8_t inst_num = pin_number / SX1509B_INNER_PIN_COUNT;
+ if (inst_num >= m_inst_count)
+ {
+ return NRF_ERROR_INVALID_PARAM;
+ }
+ pin_number %= SX1509B_INNER_PIN_COUNT;
+ uint8_t reg = sx1509b_led_driver_get_reg(pin_number) + SX1509B_LED_DRIVER_T_RISE;
+ uint8_t send_msg[] = {
+ reg,
+ fade_in & 0x1F,
+ fade_out & 0x1F
+ };
+ return nrf_twi_sensor_write(m_p_instances[inst_num].p_sensor_data,
+ m_p_instances[inst_num].sensor_addr,
+ send_msg,
+ ARRAY_SIZE(send_msg),
+ true);
+}
+
+ret_code_t sx1509b_led_pin_enable(uint32_t pin_number)
+{
+ uint8_t inst_num = pin_number / SX1509B_INNER_PIN_COUNT;
+ if (inst_num >= m_inst_count)
+ {
+ return NRF_ERROR_INVALID_PARAM;
+ }
+ pin_number %= SX1509B_INNER_PIN_COUNT;
+ uint8_t reg_add = (pin_number > SX1509B_INNER_NEXT_BANK) ? 0 : 1;
+ pin_number %= SX1509B_INNER_NEXT_BANK;
+ SET_BIT(m_p_instances[inst_num].registers[SX1509B_REG_INPUT_DISABLE_B + reg_add], pin_number);
+ CLR_BIT(m_p_instances[inst_num].registers[SX1509B_REG_PULL_UP_B + reg_add], pin_number);
+ SET_BIT(m_p_instances[inst_num].registers[SX1509B_REG_OPEN_DRAIN_B + reg_add], pin_number);
+ CLR_BIT(m_p_instances[inst_num].registers[SX1509B_REG_DIR_B + reg_add], pin_number);
+ CLR_BIT(m_p_instances[inst_num].registers[SX1509B_REG_DATA_B + reg_add], pin_number);
+ SET_BIT(m_p_instances[inst_num].registers[SX1509B_REG_LED_DRV_ENABLE_B + reg_add], pin_number);
+ return nrf_twi_sensor_write(m_p_instances[inst_num].p_sensor_data,
+ m_p_instances[inst_num].sensor_addr,
+ &m_p_instances[inst_num].start_addr,
+ SX1509B_REG_DEBOUNCE_CONFIG + 1, // + 1 byte for address
+ false);
+}
+
+ret_code_t sx1509b_led_pin_disable(uint32_t pin_number)
+{
+ uint8_t inst_num = pin_number / SX1509B_INNER_PIN_COUNT;
+ if (inst_num >= m_inst_count)
+ {
+ return NRF_ERROR_INVALID_PARAM;
+ }
+ pin_number %= SX1509B_INNER_PIN_COUNT;
+ uint8_t reg_add = (pin_number > SX1509B_INNER_NEXT_BANK) ? 0 : 1;
+ pin_number %= SX1509B_INNER_NEXT_BANK;
+ CLR_BIT(m_p_instances[inst_num].registers[SX1509B_REG_INPUT_DISABLE_B + reg_add], pin_number);
+ CLR_BIT(m_p_instances[inst_num].registers[SX1509B_REG_OPEN_DRAIN_B + reg_add], pin_number);
+ SET_BIT(m_p_instances[inst_num].registers[SX1509B_REG_DIR_B + reg_add], pin_number);
+ SET_BIT(m_p_instances[inst_num].registers[SX1509B_REG_DATA_B + reg_add], pin_number);
+ CLR_BIT(m_p_instances[inst_num].registers[SX1509B_REG_LED_DRV_ENABLE_B + reg_add], pin_number);
+ return nrf_twi_sensor_write(m_p_instances[inst_num].p_sensor_data,
+ m_p_instances[inst_num].sensor_addr,
+ &m_p_instances[inst_num].start_addr,
+ SX1509B_REG_DEBOUNCE_CONFIG + 1, // + 1 byte for address
+ false);
+}
+
+/**
+ * ===============================================================================================
+ * @brief Key Engine functions.
+ */
+ret_code_t sx1509b_key_engine_enable(uint8_t instance_num,
+ uint8_t rows,
+ uint8_t columns,
+ sx1509b_key_sleep_t sleep_time,
+ sx1509b_key_scan_t scan_time,
+ sx1509b_debounce_t debounce_time)
+{
+ if (instance_num >= m_inst_count)
+ {
+ return NRF_ERROR_INVALID_PARAM;
+ }
+ if (rows < 2)
+ {
+ NRF_TWI_SENSOR_REG_SET(m_p_instances[instance_num].registers[SX1509B_REG_KEY_CONFIG_2],
+ SX1509B_ROW_NUM_MASK,
+ SX1509B_ROW_NUM_POS,
+ 0);
+ uint8_t send_msg[] = {
+ SX1509B_REG_KEY_CONFIG_2,
+ m_p_instances[instance_num].registers[SX1509B_REG_KEY_CONFIG_2]
+ };
+ return nrf_twi_sensor_write(m_p_instances[instance_num].p_sensor_data,
+ m_p_instances[instance_num].sensor_addr,
+ send_msg,
+ ARRAY_SIZE(send_msg),
+ true);
+ }
+
+ uint8_t in_mask = 0, out_mask = 0;
+ uint8_t in_port = 0 + instance_num * SX1509B_INNER_PORT_COUNT;
+ uint8_t out_port = 1 + instance_num * SX1509B_INNER_PORT_COUNT;
+ for (uint8_t i = 0; i < rows; i++)
+ {
+ in_mask <<= 1;
+ in_mask |= 1;
+ }
+
+ for (uint8_t i = 0; i < columns; i++)
+ {
+ out_mask <<= 1;
+ out_mask |= 1;
+ }
+
+ ret_code_t err = sx1509b_port_dir_output_set(in_port, in_mask);
+ RETURN_IF_ERR(err);
+ err = sx1509b_port_dir_input_set(out_port, out_mask);
+ RETURN_IF_ERR(err);
+ err = sx1509b_port_open_drain(out_port, out_mask, SX1509B_PORT_SET);
+ RETURN_IF_ERR(err);
+ err = sx1509b_port_pull_up(in_port, in_mask, SX1509B_PORT_SET);
+ RETURN_IF_ERR(err);
+
+ m_p_instances[instance_num].registers[SX1509B_REG_DEBOUNCE_CONFIG] = debounce_time;
+ m_p_instances[instance_num].registers[SX1509B_REG_DEBOUNCE_EN_B] |= in_mask;
+ NRF_TWI_SENSOR_REG_SET(m_p_instances[instance_num].registers[SX1509B_REG_KEY_CONFIG_1],
+ SX1509B_SLEEP_TIME_MASK,
+ SX1509B_SLEEP_TIME_POS,
+ sleep_time);
+ NRF_TWI_SENSOR_REG_SET(m_p_instances[instance_num].registers[SX1509B_REG_KEY_CONFIG_1],
+ SX1509B_SCAN_TIME_MASK,
+ SX1509B_SCAN_TIME_POS,
+ scan_time);
+ NRF_TWI_SENSOR_REG_SET(m_p_instances[instance_num].registers[SX1509B_REG_KEY_CONFIG_2],
+ SX1509B_ROW_NUM_MASK,
+ SX1509B_ROW_NUM_POS,
+ rows - 1);
+ NRF_TWI_SENSOR_REG_SET(m_p_instances[instance_num].registers[SX1509B_REG_KEY_CONFIG_2],
+ SX1509B_COL_NUM_MASK,
+ SX1509B_COL_NUM_POS,
+ columns - 1);
+ uint8_t send_msg[] = {
+ SX1509B_REG_DEBOUNCE_CONFIG,
+ m_p_instances[instance_num].registers[SX1509B_REG_DEBOUNCE_CONFIG],
+ m_p_instances[instance_num].registers[SX1509B_REG_DEBOUNCE_EN_B],
+ m_p_instances[instance_num].registers[SX1509B_REG_DEBOUNCE_EN_A],
+ m_p_instances[instance_num].registers[SX1509B_REG_KEY_CONFIG_1],
+ m_p_instances[instance_num].registers[SX1509B_REG_KEY_CONFIG_2]
+ };
+ return nrf_twi_sensor_write(m_p_instances[instance_num].p_sensor_data,
+ m_p_instances[instance_num].sensor_addr,
+ send_msg,
+ ARRAY_SIZE(send_msg),
+ true);
+}
+
+ret_code_t sx1509b_key_data_update(uint8_t instance_num, nrf_twi_sensor_reg_cb_t user_cb)
+{
+ if (instance_num >= m_inst_count)
+ {
+ return NRF_ERROR_INVALID_PARAM;
+ }
+ return nrf_twi_sensor_reg_read(m_p_instances[instance_num].p_sensor_data,
+ m_p_instances[instance_num].sensor_addr,
+ SX1509B_REG_KEY_DATA_1,
+ user_cb,
+ &m_p_instances[instance_num].registers[SX1509B_REG_KEY_DATA_1],
+ 2);
+}
+
+static uint8_t sx1509b_key_get_bit_pos(uint8_t reg)
+{
+ uint8_t ret_val = 0xFF;
+ for(uint8_t i = 0; i < 8; i++)
+ {
+ if (IS_SET(reg, 0) == 1)
+ {
+ ret_val = i;
+ break;
+ }
+ reg >>= 1;
+ }
+ return ret_val;
+}
+
+uint8_t sx1509b_key_column_get(uint8_t instance_num)
+{
+ if (instance_num >= m_inst_count)
+ {
+ return NRF_ERROR_INVALID_PARAM;
+ }
+ uint8_t reg_val = ~m_p_instances[instance_num].registers[SX1509B_REG_KEY_DATA_1];
+
+ return sx1509b_key_get_bit_pos(reg_val);
+
+}
+
+uint8_t sx1509b_key_row_get(uint8_t instance_num)
+{
+ if (instance_num >= m_inst_count)
+ {
+ return NRF_ERROR_INVALID_PARAM;
+ }
+ uint8_t reg_val = ~m_p_instances[instance_num].registers[SX1509B_REG_KEY_DATA_2];
+
+ return sx1509b_key_get_bit_pos(reg_val);
+}
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/drivers_ext/sx1509b/sx1509b.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/drivers_ext/sx1509b/sx1509b.h
new file mode 100644
index 0000000..2c6e828
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/drivers_ext/sx1509b/sx1509b.h
@@ -0,0 +1,1238 @@
+/**
+ * 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#ifndef SX1509B_H
+#define SX1509B_H
+
+#include "nrf_twi_sensor.h"
+#include "sx1509b_internal.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @brief Possible sensor addresses.
+ */
+#define SX1509B_BASE_ADDRESS_FIRST 0x3Eu
+#define SX1509B_BASE_ADDRESS_SECOND 0x3Fu
+#define SX1509B_BASE_ADDRESS_THIRD 0x70u
+#define SX1509B_BASE_ADDRESS_FOURTH 0x71u
+
+/**
+ * @brief Led driver registers.
+ */
+typedef enum
+{
+ SX1509B_LED_DRIVER_T_ON,
+ SX1509B_LED_DRIVER_I_ON,
+ SX1509B_LED_DRIVER_OFF,
+ SX1509B_LED_DRIVER_T_RISE,
+ SX1509B_LED_DRIVER_T_FALL
+} sx1509b_led_driver_set_t;
+
+
+/**
+ * @brief Pin direction setting.
+ */
+typedef enum
+{
+ SX1509B_PIN_DIR_OUTPUT,
+ SX1509B_PIN_DIR_INPUT
+} sx1509b_pin_dir_t;
+
+/**
+ * @brief Pin output setting.
+ */
+typedef enum
+{
+ SX1509B_PIN_CLR,
+ SX1509B_PIN_SET
+} sx1509b_pin_set_t;
+
+/**
+ * @brief Pin pull setting.
+ */
+typedef enum
+{
+ SX1509B_PIN_NOPULL,
+ SX1509B_PIN_PULLDOWN,
+ SX1509B_PIN_PULLUP
+} sx1509b_pin_pull_t;
+
+/**
+ * @brief Pin sense setting.
+ */
+typedef enum
+{
+ SX1509B_PIN_NOSENSE,
+ SX1509B_PIN_SENSE_RISING,
+ SX1509B_PIN_SENSE_FALLING,
+ SX1509B_PIN_SENSE_BOTH
+} sx1509b_pin_sense_t;
+
+/**
+ * @brief Port operation setting.
+ *
+ * SX1509B_PORT_WRITE - mask is written to the port.
+ * SX1509B_PORT_CLEAR - positive bits in mask are cleared in port.
+ * SX1509B_PORT_SET - positive bits in mask are set in port.
+ */
+typedef enum
+{
+ SX1509B_PORT_WRITE,
+ SX1509B_PORT_CLEAR,
+ SX1509B_PORT_SET
+} sx1509b_port_op_t;
+
+/**
+ * @brief Level shifter setting.
+ */
+typedef enum
+{
+ SX1509B_LEVEL_OFF,
+ SX1509B_LEVEL_A_TO_B,
+ SX1509B_LEVEL_B_TO_A
+} sx1509b_level_shift_t;
+
+
+/**
+ * @brief Debounce settings.
+ */
+typedef enum
+{
+ SX1509B_DEBOUNCE_0_5MS,
+ SX1509B_DEBOUNCE_1MS,
+ SX1509B_DEBOUNCE_2MS,
+ SX1509B_DEBOUNCE_4MS,
+ SX1509B_DEBOUNCE_8MS,
+ SX1509B_DEBOUNCE_16MS,
+ SX1509B_DEBOUNCE_32MS,
+ SX1509B_DEBOUNCE_64MS
+} sx1509b_debounce_t;
+
+
+/**
+ * @brief Clock setting.
+ */
+typedef enum
+{
+ SX1509B_CLOCK_DISABLED,
+ SX1509B_CLOCK_EXTERNAL,
+ SX1509B_CLOCK_INTERNAL
+} sx1509b_clock_t;
+
+
+/**
+ * @brief Key engine sleep time setting.
+ */
+typedef enum
+{
+ SX1509B_KEY_TIME_SLEEP_OFF,
+ SX1509B_KEY_TIME_SLEEP_128MS,
+ SX1509B_KEY_TIME_SLEEP_256MS,
+ SX1509B_KEY_TIME_SLEEP_512MS,
+ SX1509B_KEY_TIME_SLEEP_1S,
+ SX1509B_KEY_TIME_SLEEP_2S,
+ SX1509B_KEY_TIME_SLEEP_4S,
+ SX1509B_KEY_TIME_SLEEP_8S
+} sx1509b_key_sleep_t;
+
+
+/**
+ * @brief Key engine scan time setting.
+ */
+typedef enum
+{
+ SX1509B_KEY_TIME_SCAN_1MS,
+ SX1509B_KEY_TIME_SCAN_2MS,
+ SX1509B_KEY_TIME_SCAN_4MS,
+ SX1509B_KEY_TIME_SCAN_8MS,
+ SX1509B_KEY_TIME_SCAN_16MS,
+ SX1509B_KEY_TIME_SCAN_32MS,
+ SX1509B_KEY_TIME_SCAN_64MS,
+ SX1509B_KEY_TIME_SCAN_128MS
+} sx1509b_key_scan_t;
+
+/**
+ * @brief Macro that defines expander module.
+ *
+ * @param[in] sx1509b_inst_name Name of the instance to be created.
+ * @param[in] instance_count Number of connected expanders.
+ */
+#define SX1509B_INSTANCES_DEF_START(sx1509b_inst_name, instance_count)\
+ static sx1509b_instance_t sx1509b_inst_name[instance_count]
+
+
+/**
+ * ===============================================================================================
+ * @brief General expander utility functions.
+ */
+
+/**
+ * @brief Function initialising expander module.
+ *
+ * @param[in] p_instances Pointer to expander module.
+ * @param[in] Number of connected expanders.
+ */
+void sx1509b_init(sx1509b_instance_t * p_instances, uint8_t count);
+
+/**
+ * @brief Function adding expander instance.
+ *
+ * @note Should be called for every connected expander.
+ * Order of calls define order of pins and ports.
+ *
+ * @param[in] p_twi_sensor Pointer to common sensor instance. @ref NRF_TWI_SENSOR_DEF
+ * @param[in] sensor_address Address of expander on I2C bus.
+ *
+ * @retval NRF_ERROR_MODULE_NOT_INITIALIZED Returned if expander module wasn't initialised
+ * @retval NRF_ERROR_STORAGE_FULL Returned if trying to add more instances than defined.
+ * @retval other Return error code from nrf_twi_sensor
+ * @ref nrf_twi_sensor_write
+ */
+ret_code_t sx1509b_add_instance(nrf_twi_sensor_t * p_twi_sensor, uint8_t sensor_address);
+
+/**
+ * @brief Function for writing current configuration to expander.
+ *
+ * @param[in] instance_num Number of expander, order is the same as sx1509b_add_instance calls.
+ *
+ * @retval NRF_ERROR_INVALID_PARAM Returned if there is no expander with given number.
+ * @retval other Return error code from nrf_twi_sensor @ref nrf_twi_sensor_write
+ */
+ret_code_t sx1509b_cfg_write(uint8_t instance_num);
+
+/**
+ * @brief Function for reading current configuration of expander.
+ *
+ * @param[in] instance_num Number of expander, order is the same as sx1509b_add_instance calls.
+ *
+ * @retval NRF_ERROR_INVALID_PARAM Returned if there is no expander with given number.
+ * @retval other Return error code from nrf_twi_sensor @ref nrf_twi_sensor_write
+ */
+ret_code_t sx1509b_cfg_read(uint8_t instance_num);
+
+/**
+ * @brief Function for setting clock configuration.
+ *
+ * @param instance_num Number of expander.
+ * @param source Clock source.
+ * @param oscio_set Oscio pin setting. True if pin is enabled.
+ * @param oscio_freq Oscio frequency divider. Refer to expander documentation.
+ *
+ * @retval NRF_ERROR_INVALID_PARAM Returned if there is no expander with given number.
+ * @retval other Return error code from nrf_twi_sensor @ref nrf_twi_sensor_write
+ */
+ret_code_t sx1509b_clock_set(uint8_t instance_num,
+ sx1509b_clock_t source,
+ bool oscio_set,
+ uint8_t oscio_freq);
+
+/*
+ * @brief Function for setting nreset and debounce time.
+ *
+ * @param instance_num Number of expander.
+ * @param nreset_func Purpose of nreset pin.
+ * @arg true Pin resets PWM/Blink/Fade counters.
+ * @arg false Pin is equivalent to POR.
+ * @param debounce_time Debounce time setting.
+ * @param autoclear_nint Autoclear nint and interrupt source registers when pin data is read.
+ * True if disabled.
+ *
+ * @retval NRF_ERROR_INVALID_PARAM Returned if there is no expander with such number.
+ * @retval other Return error code from nrf_twi_sensor @ref nrf_twi_sensor_write
+ */
+ret_code_t sx1509b_misc_set(uint8_t instance_num,
+ bool nreset_func,
+ sx1509b_debounce_t debounce_time,
+ bool autoclear_nint);
+
+/**
+ * @brief Function sending software reset command to expander.
+ *
+ * @param instance_num Number of expander.
+ *
+ * @retval NRF_ERROR_INVALID_PARAM Returned if there is no expander with such number.
+ * @retval other Return error code from nrf_twi_sensor @ref nrf_twi_sensor_write
+ */
+ret_code_t sx1509b_sw_reset(uint8_t instance_num);
+
+/**
+ * @brief Function for setting register configuration of a single pin.
+ *
+ * @param[in] reg Register address, if register has two banks, address of bank B has to be used.
+ * @param[in] pin Pin number.
+ * @param[in] set Value to set.
+ *
+ * @retval NRF_ERROR_INVALID_PARAM Returned if there is no pin with such number.
+ * @retval other Return error code from nrf_twi_sensor @ref nrf_twi_sensor_write
+ */
+ret_code_t sx1509b_pin_cfg_reg_set(sx1509b_registers_t reg, uint32_t pin, uint8_t set);
+
+/**
+ * @brief Function for getting register configuration of a single pin.
+ *
+ * @param[in] reg Register address, if register has two banks, address of bank B has to be used.
+ * @param[in] pin Pin number.
+ *
+ * @retval 0xFF Returned if there is no pin with given number.
+ * @return other Pin setting value at given register.
+ */
+uint8_t sx1509b_pin_cfg_reg_get(sx1509b_registers_t reg, uint32_t pin);
+
+/**
+ * @brief Function for setting register configuration of a port.
+ *
+ * @param reg Register address, if register has two banks, address of bank B has to be used.
+ * @param port Port number.
+ * @param mask Mask for the operating.
+ * @param flag Operation, should the mask be written into register, clear values or set them.
+ *
+ * @retval NRF_ERROR_INVALID_PARAM Returned if there is no port with such number.
+ * @retval other Return error code from nrf_twi_sensor @ref nrf_twi_sensor_write
+ */
+ret_code_t sx1509b_port_cfg_reg_set(sx1509b_registers_t reg,
+ uint32_t port,
+ uint8_t mask,
+ sx1509b_port_op_t flag);
+
+/**
+ * @brief Function for getting register configuration of a port.
+ *
+ * @param reg Register address, if register has two banks, address of bank B has to be used.
+ * @param port Port number.
+ *
+ * @retval Register value.
+ */
+uint8_t sx1509b_port_cfg_reg_get(sx1509b_registers_t reg, uint32_t port);
+
+/**
+ * @brief Function for updating pin data.
+ *
+ * @param user_cb Function to be called after pin data update is done.
+ *
+ * @return Return error code from nrf_twi_sensor @ref nrf_twi_sensor_reg_read
+ */
+ret_code_t sx1509b_pin_data_update(nrf_twi_sensor_reg_cb_t user_cb);
+
+/**
+ * @brief Function for updating latch data.
+ *
+ * @param user_cb Function to be called after latch update is done.
+ *
+ * @return Return error code from nrf_twi_sensor @ref nrf_twi_sensor_reg_read
+ */
+ret_code_t sx1509b_pin_latch_update(nrf_twi_sensor_reg_cb_t user_cb);
+
+/**
+ * @brief Function for setting long slew for given pin.
+ *
+ * @param pin_number Pin number.
+ * @param set Long slew setting.
+ * @arg true Long slew is enabled.
+ * @arg false Long slew is disabled.
+ *
+ * @return Return error code from pin config set @ref sx1509b_pin_cfg_reg_set
+ */
+__STATIC_INLINE ret_code_t sx1509b_pin_long_slew(uint32_t pin_number, bool set);
+
+/**
+ * @brief Function for setting low drive for given pin.
+ *
+ * @param pin_number Pin number.
+ * @param set Low drive setting.
+ * @arg true Low drive is enabled.
+ * @arg false Low drive is disabled.
+ *
+ * @return Return error code from pin config set @ref sx1509b_pin_cfg_reg_set
+ */
+__STATIC_INLINE ret_code_t sx1509b_pin_low_drive(uint32_t pin_number, bool set);
+
+/**
+ * @brief Function for setting open drain for given pin.
+ *
+ * @param pin_number Pin number.
+ * @param set Open drain setting.
+ * @arg true Open drain is enabled.
+ * @arg false Open drain is disabled.
+ *
+ * @return Return error code from pin config set @ref sx1509b_pin_cfg_reg_set
+ */
+__STATIC_INLINE ret_code_t sx1509b_pin_open_drain(uint32_t pin_number, bool set);
+
+/**
+ * @brief Function for setting polarity for given pin.
+ *
+ * @param pin_number Pin number.
+ * @param set Polarity setting.
+ * @arg true Inverted polarity.
+ * @arg false Normal polarity.
+ *
+ * @return Return error code from pin config set @ref sx1509b_pin_cfg_reg_set
+ */
+__STATIC_INLINE ret_code_t sx1509b_pin_polarity(uint32_t pin_number, bool set);
+
+/**
+ * @brief Function for setting debounce for given pin.
+ *
+ * @param pin_number Pin number.
+ * @param set Debounce setting.
+ * @arg true Debouncing is enabled.
+ * @arg false Debouncing is disabled.
+ *
+ * @return Return error code from pin config set @ref sx1509b_pin_cfg_reg_set
+ */
+__STATIC_INLINE ret_code_t sx1509b_pin_debounce(uint32_t pin_number, bool set);
+
+/**
+ * @brief Function for setting high input for given pin.
+ *
+ * @param pin_number Pin number.
+ * @param set High input setting.
+ * @arg true High input is enabled.
+ * @arg false High input is disabled.
+ *
+ * @retval NRF_ERROR_INVALID_PARAM Returned if there is no pin with such number.
+ * @retval other Return error code from nrf_twi_sensor @ref nrf_twi_sensor_write
+ */
+ret_code_t sx1509b_pin_high_input(uint32_t pin_number, bool set);
+/**
+ * @brief Function for setting level shift for given pin.
+ *
+ * @param pin_number Pin number.
+ * @param set Level shift setting.
+ *
+ * @return Return error code from pin config set @ref sx1509b_pin_cfg_reg_set
+ */
+__STATIC_INLINE ret_code_t sx1509b_pin_level_shifter(uint32_t pin_number,
+ sx1509b_level_shift_t set);
+
+/**
+ * @brief Function for setting longslew for given port.
+ *
+ * @param port_num Port number.
+ * @param out_mask Long slew mask.
+ * @param flag Port operation flag. @ref sx1509b_port_op_t
+ *
+ * @return Return error code from port config set @ref sx1509b_port_cfg_reg_set
+ */
+__STATIC_INLINE ret_code_t sx1509b_port_long_slew(uint8_t port_num,
+ uint8_t out_mask,
+ sx1509b_port_op_t flag);
+
+/**
+ * @brief Function for setting low drive for given port.
+ *
+ * @param port_num Port number.
+ * @param out_mask Low drive mask.
+ * @param flag Port operation flag. @ref sx1509b_port_op_t
+ *
+ * @return Return error code from port config set @ref sx1509b_port_cfg_reg_set
+ */
+__STATIC_INLINE ret_code_t sx1509b_port_low_drive(uint8_t port_num,
+ uint8_t out_mask,
+ sx1509b_port_op_t flag);
+
+/**
+ * @brief Function for setting open drain for given port.
+ *
+ * @param port_num Port number.
+ * @param out_mask Open drain mask.
+ * @param flag Port operation flag. @ref sx1509b_port_op_t
+ *
+ * @return Return error code from port config set @ref sx1509b_port_cfg_reg_set
+ */
+__STATIC_INLINE ret_code_t sx1509b_port_open_drain(uint8_t port_num,
+ uint8_t out_mask,
+ sx1509b_port_op_t flag);
+
+/**
+ * @brief Function for setting polarity for given port.
+ *
+ * @param port_num Port number.
+ * @param out_mask Polarity mask.
+ * @param flag Port operation flag. @ref sx1509b_port_op_t
+ *
+ * @return Return error code from port config set @ref sx1509b_port_cfg_reg_set
+ */
+__STATIC_INLINE ret_code_t sx1509b_port_polarity(uint8_t port_num,
+ uint8_t out_mask,
+ sx1509b_port_op_t flag);
+
+/**
+ * @brief Function for setting debounce for given port.
+ *
+ * @param port_num Port number.
+ * @param out_mask Debounce mask.
+ * @param flag Port operation flag. @ref sx1509b_port_op_t
+ *
+ * @return Return error code from port config set @ref sx1509b_port_cfg_reg_set
+ */
+__STATIC_INLINE ret_code_t sx1509b_port_debounce(uint8_t port_num,
+ uint8_t out_mask,
+ sx1509b_port_op_t flag);
+
+/**
+ * @brief Function for setting high input for given port.
+ *
+ * @param port_num Port number.
+ * @param out_mask High input mask.
+ * @param flag Port operation flag. @ref sx1509b_port_op_t
+ *
+ * @retval NRF_ERROR_INVALID_PARAM Returned if there is no pin with such number.
+ * @retval other Return error code from nrf_twi_sensor @ref nrf_twi_sensor_write
+ */
+ret_code_t sx1509b_port_high_input(uint8_t port_num, uint8_t out_mask, sx1509b_port_op_t flag);
+
+/**
+ * @brief Function for setting pull up for given port.
+ *
+ * @param port_num Port number.
+ * @param out_mask Pull up mask.
+ * @param flag Port operation flag. @ref sx1509b_port_op_t
+ *
+ * @return Return error code from port config set @ref sx1509b_port_cfg_reg_set
+ */
+__STATIC_INLINE ret_code_t sx1509b_port_pull_up(uint8_t port_num,
+ uint8_t out_mask,
+ sx1509b_port_op_t flag);
+
+/**
+ * @brief Function for setting pull down for given port.
+ *
+ * @param port_num Port number.
+ * @param out_mask Pull down mask.
+ * @param flag Port operation flag. @ref sx1509b_port_op_t
+ *
+ * @return Return error code from port config set @ref sx1509b_port_cfg_reg_set
+ */
+__STATIC_INLINE ret_code_t sx1509b_port_pull_down(uint8_t port_num,
+ uint8_t out_mask,
+ sx1509b_port_op_t flag);
+
+/**
+ * ===============================================================================================
+ * @brief Functions compatible with nrf_gpio
+ */
+
+/**
+ * @brief Function for configuring the given GPIO pin number as output, hiding inner details.
+ * This function can be used to configure a pin as simple output with gate driving.
+ *
+ * @param pin_number Specifies the pin number.
+ *
+ * @note Sense capability on the pin is disabled as the pins are configured as output.
+ *
+ * @return Return error code from pin config set @ref sx1509b_pin_cfg_reg_set
+ */
+__STATIC_INLINE ret_code_t sx1509b_pin_cfg_output(uint32_t pin_number);
+
+/**
+ * @brief Function for configuring the given GPIO pin number as input, hiding inner details.
+ * This function can be used to configure a pin as simple input.
+ *
+ * @param pin_number Specifies the pin number.
+ * @param pull_config State of the pin range pull resistor (no pull, pulled down, or pulled high).
+ *
+ * @note Sense capability on the pin is disabled and input is connected to buffer.
+ *
+ * @return Return error code from pin config set @ref sx1509b_pin_cfg_reg_set
+ */
+ret_code_t sx1509b_pin_cfg_input(uint32_t pin_number, sx1509b_pin_pull_t pull_config);
+
+/**
+ * @brief Function for resetting pin configuration to its default state.
+ *
+ * @param pin_number Specifies the pin number.
+ *
+ * @return Return error code from pin config set @ref sx1509b_pin_cfg_reg_set
+ */
+ret_code_t sx1509b_pin_cfg_default(uint32_t pin_number);
+
+/**
+ * @brief Function for configuring the given GPIO pin number as a watcher. Only input is connected.
+ *
+ * @param pin_number Specifies the pin number.
+ *
+ * @return Return error code from pin config set @ref sx1509b_pin_cfg_reg_set
+ */
+__STATIC_INLINE ret_code_t sx1509b_pin_cfg_watcher(uint32_t pin_number); // non
+
+/**
+ * @brief Function for disconnecting input for the given GPIO.
+ *
+ * @param pin_number Specifies the pin number.
+ *
+ * @return Return error code from pin config set @ref sx1509b_pin_cfg_reg_set
+ */
+__STATIC_INLINE ret_code_t sx1509b_pin_cfg_input_disconnect(uint32_t pin_number);
+
+/**
+ * @brief Function for configuring the given GPIO pin number as input, hiding inner details.
+ * Sense capability on the pin is configurable and input is connected to buffer.
+ *
+ * @param pin_number Specifies the pin number.
+ * @param pull_config State of the pin pull resistor (no pull, pulled down, or pulled high).
+ * @param sense_config Sense level of the pin (no sense, sense low, sense high or sense both).
+ *
+ * @return Return error code from pin config set @ref sx1509b_pin_cfg_reg_set
+ */
+ret_code_t sx1509b_pin_cfg_sense_input(uint32_t pin_number,
+ sx1509b_pin_pull_t pull_config,
+ sx1509b_pin_sense_t sense_config);
+
+/**
+ * @brief Function for configuring sense level for the given GPIO.
+ *
+ * @param pin_number Specifies the pin number.
+ * @param sense_config Sense configuration.
+ *
+ * @return Return error code from pin config set @ref sx1509b_pin_cfg_reg_set
+ */
+ret_code_t sx1509b_pin_cfg_sense_set(uint32_t pin_number, sx1509b_pin_sense_t sense_config);
+
+/**
+ * @brief Function for setting the direction for a GPIO pin.
+ *
+ * @param pin_number Specifies the pin number for which to set the direction.
+ * @param direction Specifies the direction.
+ *
+ * @return Return error code from pin config set @ref sx1509b_pin_cfg_reg_set
+ */
+ret_code_t sx1509b_pin_dir_set(uint32_t pin_number, sx1509b_pin_dir_t direction);
+
+/**
+ * @brief Function for setting a GPIO pin.
+ *
+ * Note that the pin must be configured as an output for this function to have any effect.
+ *
+ * @param pin_number Specifies the pin number to set.
+ *
+ * @return Return error code from pin config set @ref sx1509b_pin_cfg_reg_set
+ */
+__STATIC_INLINE ret_code_t sx1509b_pin_set(uint32_t pin_number);
+
+/**
+ * @brief Function for clearing a GPIO pin.
+ *
+ * Note that the pin must be configured as an output for this
+ * function to have any effect.
+ *
+ * @param pin_number Specifies the pin number to clear.
+ *
+ * @return Return error code from pin config set @ref sx1509b_pin_cfg_reg_set
+ */
+__STATIC_INLINE ret_code_t sx1509b_pin_clear(uint32_t pin_number);
+
+/**
+ * @brief Function for toggling a GPIO pin.
+ *
+ * Note that the pin must be configured as an output for this
+ * function to have any effect.
+ *
+ * @param pin_number Specifies the pin number to toggle.
+ *
+ * @return Return error code from pin config set @ref sx1509b_pin_cfg_reg_set
+ */
+__STATIC_INLINE ret_code_t sx1509b_pin_toggle(uint32_t pin_number);
+
+/**
+ * @brief Function for writing a value to a GPIO pin.
+ *
+ * Note that the pin must be configured as an output for this
+ * function to have any effect.
+ *
+ * @param pin_number Specifies the pin number to write.
+ *
+ * @param value Specifies the value to be written to the pin.
+ * @arg 0 Clears the pin.
+ * @arg >=1 Sets the pin.
+ *
+ * @return Return error code from pin config set @ref sx1509b_pin_cfg_reg_set
+ */
+__STATIC_INLINE ret_code_t sx1509b_pin_write(uint32_t pin_number, sx1509b_pin_set_t value);
+
+/**
+ * @brief Function for reading the input level of a GPIO pin.
+ *
+ * @note The pin must have input connected for the value
+ * returned from this function to be valid.
+ * Due to specifics of TWI expander, pin data must be updated first
+ * to get current value @ref sx1509b_pin_data_update
+ *
+ * @param pin_number Specifies the pin number to read.
+ *
+ * @return 0 if the pin input level is low. Positive value if the pin is high.
+ */
+__STATIC_INLINE uint32_t sx1509b_pin_read(uint32_t pin_number);
+
+
+
+/**
+ * @brief Function for reading the output level of a GPIO pin.
+ *
+ * @param pin_number Specifies the pin number to read.
+ *
+ * @return 0 if the pin output level is low. Positive value if pin output is high.
+ */
+__STATIC_INLINE uint32_t sx1509b_pin_out_read(uint32_t pin_number);
+
+/**
+ * @brief Function for reading the sense configuration of a GPIO pin.
+ *
+ * @param pin_number Specifies the pin number to read.
+ *
+ * @retval Sense configuration.
+ */
+__STATIC_INLINE sx1509b_pin_sense_t sx1509b_pin_sense_get(uint32_t pin_number);
+
+/**
+ * @brief Function for getting expander port number based on pin number.
+ *
+ * @retval Port number.
+ */
+__STATIC_INLINE uint8_t sx1509b_pin_port_decode(uint32_t pin_number);
+
+/**
+ * @brief Function for setting output direction on selected pins on a given port.
+ *
+ * @param port_num Port number.
+ * @param out_mask Mask specifying the pins to set as output.
+ *
+ * @return Return error code from port config set @ref sx1509b_port_cfg_reg_set
+ */
+__STATIC_INLINE ret_code_t sx1509b_port_dir_output_set(uint8_t port_num, uint8_t out_mask);
+
+/**
+ * @brief Function for setting input direction on selected pins on a given port.
+ *
+ * @param port_num Port number.
+ * @param in_mask Mask specifying the pins to set as input.
+ *
+ * @return Return error code from port config set @ref sx1509b_port_cfg_reg_set
+ */
+__STATIC_INLINE ret_code_t sx1509b_port_dir_input_set(uint8_t port_num, uint8_t in_mask);
+
+/**
+ * @brief Function for writing the direction configuration of GPIO pins in a given port.
+ *
+ * @param port_num Port number.
+ * @param dir_mask Mask specifying the direction of pins.
+ * Bit set means that the given pin is configured as output.
+ *
+ * @return Return error code from port config set @ref sx1509b_port_cfg_reg_set
+ */
+__STATIC_INLINE ret_code_t sx1509b_port_dir_write(uint8_t port_num, uint8_t dir_mask);
+
+/**
+ * @brief Function for reading the direction configuration of a GPIO port.
+ *
+ * @param port_num Port number.
+ *
+ * @note Returns 0 if port doesn't exist.
+ *
+ * @retval Pin configuration of the current direction settings.
+ * Bit set means that the given pin is configured as output.
+ */
+__STATIC_INLINE uint8_t sx1509b_port_dir_read(uint8_t port_num);
+
+/**
+ * @brief Function for reading the input signals of GPIO pins on a given port.
+ *
+ * @param port_num Port number.
+ *
+ * @note Returns 0 if port doesn't exist.
+ *
+ * @retval Port input values.
+ */
+__STATIC_INLINE uint8_t sx1509b_port_in_read(uint8_t port_num);
+
+/**
+ * @brief Function for reading the output signals of GPIO pins of a given port.
+ *
+ * @param port_num Port number.
+ *
+ * @note Returns 0 if port doesn't exist.
+ *
+ * @retval Port output values.
+ */
+__STATIC_INLINE uint8_t sx1509b_port_out_read(uint8_t port_num);
+
+/**
+ * @brief Function for writing the GPIO pins output on a given port.
+ *
+ * @param port_num Port number.
+ * @param value Output port mask.
+ *
+ * @return Return error code from port config set @ref sx1509b_port_cfg_reg_set
+ */
+__STATIC_INLINE ret_code_t sx1509b_port_out_write(uint8_t port_num, uint8_t value);
+
+/**
+ * @brief Function for setting high level on selected GPIO pins of a given port.
+ *
+ * @param port_num Port number.
+ * @param set_mask Mask with pins to set as logical high level.
+ *
+ * @return Return error code from port config set @ref sx1509b_port_cfg_reg_set
+ */
+__STATIC_INLINE ret_code_t sx1509b_port_out_set(uint8_t port_num, uint8_t set_mask);
+
+/**
+ * @brief Function for setting low level on selected GPIO pins of a given port.
+ *
+ * @param port_num Port number.
+ * @param clr_mask Mask with pins to set as logical low level.
+ *
+ * @return Return error code from port config set @ref sx1509b_port_cfg_reg_set
+ */
+__STATIC_INLINE ret_code_t sx1509b_port_out_clear(uint8_t port_num, uint8_t clr_mask);
+
+/**
+ * @brief Function for reading pins state of multiple consecutive ports.
+ *
+ * @note Due to specifics of TWI expander, pin data must be updated first
+ * to get current value @ref sx1509b_pin_data_update
+ *
+ * @param start_port Index of the first port to read.
+ * @param length Number of ports to read.
+ * @param p_masks Pointer to output array where port states will be stored.
+ *
+ * @retval NRF_ERROR_INVALID_LENGTH If trying to read more ports than available.
+ * @retval NRF_SUCCESS If operation was successful.
+ */
+ret_code_t sx1509b_ports_read(uint8_t start_port, uint32_t length, uint8_t * p_masks);
+
+/**
+ * @brief Function for reading latch state of multiple consecutive ports.
+ *
+ * @note Due to specifics of TWI expander, latch data must be updated first
+ * to get current value @ref sx1509b_pin_latch_update
+ *
+ * @param start_port Index of the first port to read.
+ * @param length Number of ports to read.
+ * @param p_masks Pointer to output array where latch states will be stored.
+ *
+ * @retval NRF_ERROR_INVALID_LENGTH If trying to read more ports than available.
+ * @retval NRF_SUCCESS If operation was successful.
+ */
+ret_code_t sx1509b_latches_read(uint8_t start_port, uint32_t length, uint8_t * p_masks);
+
+/**
+ * @brief Function for reading latch state of single pin.
+ *
+ * @note Due to specifics of TWI expander, latch data must be updated first
+ * to get current value @ref sx1509b_pin_latch_update
+ *
+ * @param pin_number Pin number.
+ *
+ * @retval 0 Returned if latch is not set
+ * @retval 1 Returned if latch is set.
+ * @retval other Return from @ref sx1509b_pin_cfg_reg_get
+ */
+__STATIC_INLINE uint32_t sx1509b_pin_latch_get(uint32_t pin_number);
+
+/**
+ * @brief Function for clearing latch state of a single pin.
+ *
+ * @param pin_number Pin number.
+ *
+ * @return Return error code from pin config set @ref sx1509b_pin_cfg_reg_set
+ */
+ret_code_t sx1509b_pin_latch_clear(uint32_t pin_number);
+
+/**
+ * ===============================================================================================
+ * @brief Led driver functions.
+ */
+
+/**
+ * @brief Function enabling led driver.
+ *
+ * @param instance_num Number of expander instance.
+ * @param clock_internal Sets clock source.
+ * @arg true External clock source
+ * @arg false Internal 2Mhz clock
+ * @param frequency Frequency divider.
+ * @arg 0 Led driver functionality is disabled for all IOs.
+ * @arg Else Divider value, refer to expander documentation.
+ *
+ * @retval NRF_ERROR_INVALID_PARAM Returned if given instance isn't present.
+ * @retval other Return error code from nrf_twi_sensor @ref nrf_twi_sensor_write
+ */
+ret_code_t sx1509b_led_driver_enable(uint8_t instance_num, bool clock_internal, uint8_t frequency);
+
+/**
+ * @brief Function for setting led driver mode.
+ *
+ * @param port_num Port for which mode will be set.
+ * @param mode Led driver mode.
+ * @arg true Logarithmic mode
+ * @arg false Linear mode
+ *
+ * @retval NRF_ERROR_INVALID_PARAM Returned if given port isn't present.
+ * @retval other Return error code from nrf_twi_sensor @ref nrf_twi_sensor_write
+ */
+ret_code_t sx1509b_led_mode(uint8_t port_num, bool mode);
+
+/**
+ * @brief Function for setting led driver pin times.
+ *
+ * @param pin_number Pin which settings will be changed.
+ * @param on_time On time of pin. Refer to expander documentation.
+ * @param on_intensity Intensity during on time. Between 0 and 255.
+ * @param off_time Off time of pin. Refer to expander documentation.
+ * @param off_intensity Intensity during off time. Between 0 and 7.
+ *
+ * @retval NRF_ERROR_INVALID_PARAM Returned if there is no pin with given number.
+ * @retval other Return error code from nrf_twi_sensor @ref nrf_twi_sensor_write
+ */
+ret_code_t sx1509b_led_pin_time(uint32_t pin_number,
+ uint8_t on_time,
+ uint8_t on_intensity,
+ uint8_t off_time,
+ uint8_t off_intensity);
+
+/**
+ * @brief Function for setting led driver pin fade characteristics.
+ *
+ * @param pin_number Pin which settings will be changed.
+ * @param fade_in Fade in time of pin. Refer to expander documentation.
+ * @param fade_out Fade out time of pin. Refer to expander documentation.
+ *
+ * @retval NRF_ERROR_INVALID_PARAM Returned if given pin has no fade capability,
+ * or there is no pin with given number.
+ * @retval other Return error code from nrf_twi_sensor @ref nrf_twi_sensor_write
+ */
+ret_code_t sx1509b_led_pin_fade(uint32_t pin_number, uint8_t fade_in, uint8_t fade_out);
+
+/**
+ * @brief Function for enabling led driver on selected pin.
+ *
+ * @param pin_number Pin number.
+ *
+ * @retval NRF_ERROR_INVALID_PARAM Returned if there is no pin with given number.
+ * @retval other Return error code from nrf_twi_sensor @ref nrf_twi_sensor_write
+ */
+ret_code_t sx1509b_led_pin_enable(uint32_t pin_number);
+
+/**
+ * @brief Function for disabling led driver on selected pin.
+ *
+ * @param pin_number Pin number.
+ *
+ * @retval NRF_ERROR_INVALID_PARAM Returned if there is no pin with given number.
+ * @retval other Return error code from nrf_twi_sensor @ref nrf_twi_sensor_write
+ */
+ret_code_t sx1509b_led_pin_disable(uint32_t pin_number);
+
+/**
+ * @brief Function for getting led driver time on register of selected pin.
+ *
+ * @param pin_number Pin number.
+ *
+ * @retval Time on led driver register of selected pin
+ */
+uint8_t sx1509b_led_driver_get_reg(uint32_t pin_number);
+
+/**
+ * ===============================================================================================
+ * @brief Key Engine functions.
+ */
+
+/**
+ * @brief Function enabling key engine.
+ *
+ * @param instance_num Number of expander.
+ * @param rows Number of keyboard rows.
+ * @arg < 2 Disable key engine.
+ * @arg >= 2 Number of rows (max 8).
+ * @param columns Number of columns (max 8).
+ * @param sleep_time Time of inactivity before key engine enters sleep mode.
+ * @param scan_time Scan time per column. Must be bigger than debounce time.
+ * @param debounce_time Input debounce time.
+ *
+ * @retval NRF_ERROR_INVALID_PARAM Returned if there is no expander with given number.
+ * @retval other Return error code from nrf_twi_sensor @ref nrf_twi_sensor_write
+ */
+ret_code_t sx1509b_key_engine_enable(uint8_t instance_num,
+ uint8_t rows,
+ uint8_t columns,
+ sx1509b_key_sleep_t sleep_time,
+ sx1509b_key_scan_t scan_time,
+ sx1509b_debounce_t debounce_time);
+
+/**
+ * @brief Function scheduling key data update.
+ *
+ * @param instance_num Number of expander to update.
+ * @param user_cb Function called after key data update.
+ *
+ * @retval NRF_ERROR_INVALID_PARAM Returned if there is no expander with given number.
+ * @retval other Return error code from nrf_twi_sensor @ref nrf_twi_sensor_write
+ */
+ret_code_t sx1509b_key_data_update(uint8_t instance_num, nrf_twi_sensor_reg_cb_t user_cb);
+
+/**
+ * @brief Function returning pressed key column.
+ *
+ * @param instance_num Number of expander.
+ *
+ * @retval NRF_ERROR_INVALID_PARAM Returned if there is no expander with given number.
+ * @retval 0xFF If no key was pressed.
+ * @retval 0 - 7 Column number.
+ */
+uint8_t sx1509b_key_column_get(uint8_t instance_num);
+
+/**
+ * @brief Function returning pressed key row.
+ *
+ * @param instance_num Number of expander.
+ *
+ * @retval NRF_ERROR_INVALID_PARAM Returned if there is no expander with given number.
+ * @retval 0xFF If no key was pressed.
+ * @retval 0 - 7 Row number.
+ */
+uint8_t sx1509b_key_row_get(uint8_t instance_num);
+
+#ifndef SUPPRESS_INLINE_IMPLEMENTATION
+
+/**
+ * ===============================================================================================
+ * @brief General expander inline utility functions.
+ */
+
+__STATIC_INLINE ret_code_t sx1509b_pin_long_slew(uint32_t pin_number, bool set)
+{
+ return sx1509b_pin_cfg_reg_set(SX1509B_REG_LONG_SLEW_B, pin_number, set);
+}
+
+__STATIC_INLINE ret_code_t sx1509b_pin_low_drive(uint32_t pin_number, bool set)
+{
+ return sx1509b_pin_cfg_reg_set(SX1509B_REG_LOW_DRIVE_B, pin_number, set);
+}
+
+__STATIC_INLINE ret_code_t sx1509b_pin_open_drain(uint32_t pin_number, bool set)
+{
+ return sx1509b_pin_cfg_reg_set(SX1509B_REG_OPEN_DRAIN_B, pin_number, set);
+}
+
+__STATIC_INLINE ret_code_t sx1509b_pin_polarity(uint32_t pin_number, bool set)
+{
+ return sx1509b_pin_cfg_reg_set(SX1509B_REG_POLARITY_B, pin_number, set);
+}
+
+__STATIC_INLINE ret_code_t sx1509b_pin_debounce(uint32_t pin_number, bool set)
+{
+ return sx1509b_pin_cfg_reg_set(SX1509B_REG_DEBOUNCE_EN_B, pin_number, set);
+}
+
+__STATIC_INLINE ret_code_t sx1509b_pin_level_shifter(uint32_t pin_number, sx1509b_level_shift_t set)
+{
+ return sx1509b_pin_cfg_reg_set(SX1509B_REG_LEVEL_SHIFTER_1, pin_number, set);
+}
+
+__STATIC_INLINE ret_code_t sx1509b_port_long_slew(uint8_t port_num,
+ uint8_t out_mask,
+ sx1509b_port_op_t flag)
+{
+ return sx1509b_port_cfg_reg_set(SX1509B_REG_LONG_SLEW_B, port_num, out_mask, flag);
+}
+
+__STATIC_INLINE ret_code_t sx1509b_port_low_drive(uint8_t port_num,
+ uint8_t out_mask,
+ sx1509b_port_op_t flag)
+{
+ return sx1509b_port_cfg_reg_set(SX1509B_REG_LOW_DRIVE_B, port_num, out_mask, flag);
+}
+
+__STATIC_INLINE ret_code_t sx1509b_port_open_drain(uint8_t port_num,
+ uint8_t out_mask,
+ sx1509b_port_op_t flag)
+{
+ return sx1509b_port_cfg_reg_set(SX1509B_REG_OPEN_DRAIN_B, port_num, out_mask, flag);
+}
+
+__STATIC_INLINE ret_code_t sx1509b_port_polarity(uint8_t port_num,
+ uint8_t out_mask,
+ sx1509b_port_op_t flag)
+{
+ return sx1509b_port_cfg_reg_set(SX1509B_REG_POLARITY_B, port_num, out_mask, flag);
+}
+
+__STATIC_INLINE ret_code_t sx1509b_port_debounce(uint8_t port_num,
+ uint8_t out_mask,
+ sx1509b_port_op_t flag)
+{
+ return sx1509b_port_cfg_reg_set(SX1509B_REG_DEBOUNCE_EN_B, port_num, out_mask, flag);
+}
+
+__STATIC_INLINE ret_code_t sx1509b_port_pull_up(uint8_t port_num,
+ uint8_t out_mask,
+ sx1509b_port_op_t flag)
+{
+ return sx1509b_port_cfg_reg_set(SX1509B_REG_PULL_UP_B, port_num, out_mask, flag);
+}
+
+__STATIC_INLINE ret_code_t sx1509b_port_pull_down(uint8_t port_num,
+ uint8_t out_mask,
+ sx1509b_port_op_t flag)
+{
+ return sx1509b_port_cfg_reg_set(SX1509B_REG_PULL_DOWN_B, port_num, out_mask, flag);
+}
+
+/**
+ * ===============================================================================================
+ * @brief Inline functions compatible with nrf_gpio
+ */
+__STATIC_INLINE ret_code_t sx1509b_pin_cfg_output(uint32_t pin_number)
+{
+ return sx1509b_pin_cfg_reg_set(SX1509B_REG_DIR_B, pin_number, SX1509B_PIN_DIR_OUTPUT);
+}
+
+__STATIC_INLINE ret_code_t sx1509b_pin_cfg_watcher(uint32_t pin_number)
+{
+ return sx1509b_pin_cfg_input(pin_number, SX1509B_PIN_NOPULL);
+}
+
+__STATIC_INLINE ret_code_t sx1509b_pin_cfg_input_disconnect(uint32_t pin_number)
+{
+ return sx1509b_pin_cfg_reg_set(SX1509B_REG_INPUT_DISABLE_B, pin_number, 1);
+}
+
+__STATIC_INLINE ret_code_t sx1509b_pin_set(uint32_t pin_number)
+{
+ return sx1509b_pin_cfg_reg_set(SX1509B_REG_DATA_B, pin_number, SX1509B_PIN_SET);
+}
+
+__STATIC_INLINE ret_code_t sx1509b_pin_clear(uint32_t pin_number)
+{
+ return sx1509b_pin_cfg_reg_set(SX1509B_REG_DATA_B, pin_number, SX1509B_PIN_CLR);
+}
+
+__STATIC_INLINE ret_code_t sx1509b_pin_toggle(uint32_t pin_number)
+{
+ uint8_t val = sx1509b_pin_cfg_reg_get(SX1509B_REG_DATA_B, pin_number);
+ val = !val;
+ return sx1509b_pin_cfg_reg_set(SX1509B_REG_DATA_B, pin_number, val);
+}
+
+__STATIC_INLINE ret_code_t sx1509b_pin_write(uint32_t pin_number, sx1509b_pin_set_t value)
+{
+ value = (value >= 1) ? 1 : 0;
+ return sx1509b_pin_cfg_reg_set(SX1509B_REG_DATA_B, pin_number, value);
+}
+
+__STATIC_INLINE uint32_t sx1509b_pin_read(uint32_t pin_number)
+{
+ return sx1509b_pin_cfg_reg_get(SX1509B_REG_DATA_B, pin_number);
+}
+
+__STATIC_INLINE uint32_t sx1509b_pin_out_read(uint32_t pin_number)
+{
+ return sx1509b_pin_cfg_reg_get(SX1509B_REG_DATA_B, pin_number);
+}
+
+__STATIC_INLINE sx1509b_pin_sense_t sx1509b_pin_sense_get(uint32_t pin_number)
+{
+ return sx1509b_pin_cfg_reg_get(SX1509B_REG_SENSE_H_B, pin_number);
+}
+
+__STATIC_INLINE uint8_t sx1509b_pin_port_decode(uint32_t pin_number)
+{
+ return pin_number / SX1509B_INNER_NEXT_BANK;
+}
+
+__STATIC_INLINE ret_code_t sx1509b_port_dir_output_set(uint8_t port_num, uint8_t out_mask)
+{
+ return sx1509b_port_cfg_reg_set(SX1509B_REG_DIR_B, port_num, out_mask, SX1509B_PORT_CLEAR);
+}
+
+__STATIC_INLINE ret_code_t sx1509b_port_dir_input_set(uint8_t port_num, uint8_t in_mask)
+{
+ return sx1509b_port_cfg_reg_set(SX1509B_REG_DIR_B, port_num, in_mask, SX1509B_PORT_SET);
+}
+
+__STATIC_INLINE ret_code_t sx1509b_port_dir_write(uint8_t port_num, uint8_t dir_mask)
+{
+ return sx1509b_port_cfg_reg_set(SX1509B_REG_DIR_B, port_num, ~dir_mask, SX1509B_PORT_WRITE);
+}
+
+__STATIC_INLINE uint8_t sx1509b_port_dir_read(uint8_t port_num)
+{
+ return ~sx1509b_port_cfg_reg_get(SX1509B_REG_DIR_B, port_num);
+}
+
+__STATIC_INLINE uint8_t sx1509b_port_in_read(uint8_t port_num)
+{
+ return sx1509b_port_cfg_reg_get(SX1509B_REG_DATA_B, port_num);
+}
+
+__STATIC_INLINE uint8_t sx1509b_port_out_read(uint8_t port_num)
+{
+ return sx1509b_port_cfg_reg_get(SX1509B_REG_DATA_B, port_num);
+}
+
+__STATIC_INLINE ret_code_t sx1509b_port_out_write(uint8_t port_num, uint8_t value)
+{
+ return sx1509b_port_cfg_reg_set(SX1509B_REG_DATA_B, port_num, value, SX1509B_PORT_WRITE);
+}
+
+__STATIC_INLINE ret_code_t sx1509b_port_out_set(uint8_t port_num, uint8_t set_mask)
+{
+ return sx1509b_port_cfg_reg_set(SX1509B_REG_DATA_B, port_num, set_mask, SX1509B_PORT_SET);
+}
+
+__STATIC_INLINE ret_code_t sx1509b_port_out_clear(uint8_t port_num, uint8_t clr_mask)
+{
+ return sx1509b_port_cfg_reg_set(SX1509B_REG_DATA_B, port_num, clr_mask, SX1509B_PORT_CLEAR);
+}
+
+__STATIC_INLINE uint32_t sx1509b_pin_latch_get(uint32_t pin_number)
+{
+ return sx1509b_pin_cfg_reg_get(SX1509B_REG_INT_SRC_B, pin_number);
+}
+#endif //SUPPRESS_INLINE_IMPLEMENTATION
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // SX1509B_H
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/drivers_ext/sx1509b/sx1509b_internal.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/drivers_ext/sx1509b/sx1509b_internal.h
new file mode 100644
index 0000000..a5f2051
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/drivers_ext/sx1509b/sx1509b_internal.h
@@ -0,0 +1,232 @@
+/**
+ * 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#ifndef SX1509B_INTERNAL_H
+#define SX1509B_INTERNAL_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @brief Device and IO banks registers.
+ */
+typedef enum
+{
+ SX1509B_REG_INPUT_DISABLE_B,
+ SX1509B_REG_INPUT_DISABLE_A,
+ SX1509B_REG_LONG_SLEW_B,
+ SX1509B_REG_LONG_SLEW_A,
+ SX1509B_REG_LOW_DRIVE_B,
+ SX1509B_REG_LOW_DRIVE_A,
+ SX1509B_REG_PULL_UP_B,
+ SX1509B_REG_PULL_UP_A,
+ SX1509B_REG_PULL_DOWN_B,
+ SX1509B_REG_PULL_DOWN_A,
+ SX1509B_REG_OPEN_DRAIN_B,
+ SX1509B_REG_OPEN_DRAIN_A,
+ SX1509B_REG_POLARITY_B,
+ SX1509B_REG_POLARITY_A,
+ SX1509B_REG_DIR_B,
+ SX1509B_REG_DIR_A,
+ SX1509B_REG_DATA_B,
+ SX1509B_REG_DATA_A,
+ SX1509B_REG_INT_MASK_B,
+ SX1509B_REG_INT_MASK_A,
+ SX1509B_REG_SENSE_H_B,
+ SX1509B_REG_SENSE_L_B,
+ SX1509B_REG_SENSE_H_A,
+ SX1509B_REG_SENSE_L_A,
+ SX1509B_REG_INT_SRC_B,
+ SX1509B_REG_INT_SRC_A,
+ SX1509B_REG_EVENT_STATUS_B,
+ SX1509B_REG_EVENT_STATUS_A,
+ SX1509B_REG_LEVEL_SHIFTER_1,
+ SX1509B_REG_LEVEL_SHIFTER_2,
+ SX1509B_REG_CLOCK,
+ SX1509B_REG_MISC,
+ SX1509B_REG_LED_DRV_ENABLE_B,
+ SX1509B_REG_LED_DRV_ENABLE_A,
+ SX1509B_REG_DEBOUNCE_CONFIG,
+ SX1509B_REG_DEBOUNCE_EN_B,
+ SX1509B_REG_DEBOUNCE_EN_A,
+ SX1509B_REG_KEY_CONFIG_1,
+ SX1509B_REG_KEY_CONFIG_2,
+ SX1509B_REG_KEY_DATA_1,
+ SX1509B_REG_KEY_DATA_2,
+ SX1509B_REG_COUNT
+} sx1509b_registers_t;
+
+#define SX1509B_INNER_PIN_COUNT 16
+#define SX1509B_INNER_NEXT_BANK 8
+
+#define SX1509B_INNER_PORT_COUNT 2
+#define SX1509B_INNER_SENSE_REG_NUM 4
+#define SX1509B_INNER_RESET_BYTE1 0x12
+#define SX1509B_INNER_RESET_BYTE2 0x34
+/**
+ * @brief LED Driver registers.
+ */
+#define SX1509B_REG_LED_BANK_A_START 0x29
+#define SX1509B_REG_LED_FADE_A_START 0x35
+#define SX1509B_REG_LED_BANK_B_START 0x49
+#define SX1509B_REG_LED_FADE_B_START 0x55
+
+#define SX1509B_LED_DRIVER_TIME_REG_LEN 3
+#define SX1509B_LED_DRIVER_FADE_REG_LEN 5
+#define SX1509B_LED_DRIVER_TIME_REG_NUM ((SX1509B_REG_LED_FADE_A_START \
+ - SX1509B_REG_LED_BANK_A_START) \
+ / SX1509B_LED_DRIVER_TIME_REG_LEN)
+
+#define SX1509B_LED_DRIVER_FADE_REG_NUM ((SX1509B_REG_LED_BANK_B_START \
+ - SX1509B_REG_LED_FADE_A_START) \
+ / SX1509B_LED_DRIVER_FADE_REG_LEN)
+
+/**
+ * @brief Clock register bitmasks.
+ */
+
+// Bitmasks for osc src.
+#define SX1509B_OSC_SRC_POS 5
+#define SX1509B_OSC_SRC_MASK (3 << SX1509B_OSC_SRC_POS)
+
+// Bitmasks for oscio pin.
+#define SX1509B_OSCIO_PIN_POS 4
+#define SX1509B_OSCIO_PIN_MASK (1 << SX1509B_OSCIO_PIN_POS)
+
+// Bitmasks for oscout freq.
+#define SX1509B_OSCOUT_FREQ_POS 0
+#define SX1509B_OSCOUT_FREQ_MASK (0x0F << SX1509B_OSCOUT_FREQ_POS)
+
+
+/**
+ * @brief Miscellaneous register bitmasks.
+ */
+
+// Bitmasks for led mode b.
+#define SX1509B_LED_MODE_B_POS 7
+#define SX1509B_LED_MODE_B_MASK (1 << SX1509B_LED_MODE_B_POS)
+
+// Bitmasks for led freq.
+#define SX1509B_LED_FREQ_POS 4
+#define SX1509B_LED_FREQ_MASK (7 << SX1509B_LED_FREQ_POS)
+
+// Bitmasks for led mode a.
+#define SX1509B_LED_MODE_A_POS 3
+#define SX1509B_LED_MODE_A_MASK (1 << SX1509B_LED_MODE_A_POS)
+
+// Bitmasks for nreset pin.
+#define SX1509B_NRESET_PIN_POS 2
+#define SX1509B_NRESET_PIN_MASK (1 << SX1509B_NRESET_PIN_POS)
+
+// Bitmasks for auto incr.
+#define SX1509B_AUTO_INCR_POS 1
+#define SX1509B_AUTO_INCR_MASK (1 << SX1509B_AUTO_INCR_POS)
+
+// Bitmasks for auto clear nint.
+#define SX1509B_AUTO_CLEAR_NINT_POS 0
+#define SX1509B_AUTO_CLEAR_NINT_MASK (1 << SX1509B_AUTO_CLEAR_NINT_POS)
+
+
+/**
+ * @brief Key config 1 register bitmasks.
+ */
+
+// Bitmasks for sleep time.
+#define SX1509B_SLEEP_TIME_POS 4
+#define SX1509B_SLEEP_TIME_MASK (7 << SX1509B_SLEEP_TIME_POS)
+
+// Bitmasks for scan time.
+#define SX1509B_SCAN_TIME_POS 0
+#define SX1509B_SCAN_TIME_MASK (7 << SX1509B_SCAN_TIME_POS)
+
+
+/**
+ * @brief Key config 2 register bitmasks.
+ */
+
+// Bitmasks for row num.
+#define SX1509B_ROW_NUM_POS 3
+#define SX1509B_ROW_NUM_MASK (7 << SX1509B_ROW_NUM_POS)
+
+// Bitmasks for col num.
+#define SX1509B_COL_NUM_POS 0
+#define SX1509B_COL_NUM_MASK (7 << SX1509B_COL_NUM_POS)
+
+
+/**
+ * @brief Led driver off register bitmasks.
+ */
+
+// Bitmasks for OFF_TIME.
+#define SX1509B_OFF_TIME_POS 3
+#define SX1509B_OFF_TIME_MASK (0x1F << SX1509B_OFF_TIME_POS)
+
+// Bitmasks for off intensity.
+#define SX1509B_OFF_INTENSITY_POS 0
+#define SX1509B_OFF_INTENSITY_MASK (7 << SX1509B_OFF_INTENSITY_POS)
+
+
+/**
+ * @brief Miscellaneous registers.
+ */
+#define SX1509B_REG_HIGH_INPUT_B 0x69
+#define SX1509B_REG_HIGH_INPUT_A 0x6A
+#define SX1509B_REG_SW_RESET 0x7D
+#define SX1509B_REG_TEST_1 0x7E
+#define SX1509B_REG_TEST_2 0x7F
+
+/**
+ * @brief Structure containing expander instance.
+ */
+typedef struct
+{
+ nrf_twi_sensor_t * p_sensor_data;
+ uint8_t sensor_addr;
+ uint8_t start_addr;
+ uint8_t registers[SX1509B_REG_COUNT];
+ uint8_t high_input[2];
+} sx1509b_instance_t;
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // SX1509B_INTERNAL_H
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/drivers_ext/synaptics_touchpad/synaptics_touchpad.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/drivers_ext/synaptics_touchpad/synaptics_touchpad.c
new file mode 100644
index 0000000..53294ad
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/drivers_ext/synaptics_touchpad/synaptics_touchpad.c
@@ -0,0 +1,142 @@
+/**
+ * Copyright (c) 2009 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#include <stdbool.h>
+#include <stdint.h>
+
+#include "twi_master.h"
+#include "synaptics_touchpad.h"
+
+/*lint ++flb "Enter library region" */
+
+#define PRODUCT_ID_BYTES 10U //!< Number of bytes to expect to be in product ID
+
+static uint8_t m_device_address; // !< Device address in bits [7:1]
+static const uint8_t expected_product_id[PRODUCT_ID_BYTES] = {'T', 'M', '1', '9', '4', '4', '-', '0', '0', '2'}; //!< Product ID expected to get from product ID query
+
+bool touchpad_init(uint8_t device_address)
+{
+ bool transfer_succeeded = true;
+
+ m_device_address = (uint8_t)(device_address << 1);
+
+ // Do a soft reset
+ uint8_t reset_command = 0x01;
+ transfer_succeeded &= touchpad_write_register(TOUCHPAD_RESET, reset_command);
+
+ // Page select 0
+ uint8_t page_to_select = 0x00;
+ transfer_succeeded &= touchpad_write_register(TOUCHPAD_PAGESELECT, page_to_select);
+
+ // Read and verify product ID
+ transfer_succeeded &= touchpad_product_id_verify();
+
+ return transfer_succeeded;
+}
+
+
+bool touchpad_product_id_verify(void)
+{
+ bool transfer_succeeded = true;
+ uint8_t product_id[PRODUCT_ID_BYTES];
+ transfer_succeeded &= touchpad_product_id_read(product_id, PRODUCT_ID_BYTES);
+
+ for (uint8_t i = 0; i < 10; i++)
+ {
+ if (product_id[i] != expected_product_id[i])
+ {
+ transfer_succeeded = false;
+ }
+ }
+
+ return transfer_succeeded;
+}
+
+bool touchpad_reset(void)
+{
+ uint8_t w2_data[2] = {TOUCHPAD_COMMAND, 0x01};
+
+ return twi_master_transfer(m_device_address, w2_data, 2, TWI_ISSUE_STOP);
+}
+
+bool touchpad_interrupt_status_read(uint8_t *interrupt_status)
+{
+ return touchpad_read_register(TOUCHPAD_INT_STATUS, interrupt_status);
+}
+
+bool touchpad_set_sleep_mode(TouchpadSleepMode_t mode)
+{
+ return touchpad_write_register(TOUCHPAD_CONTROL, (uint8_t)mode);
+}
+
+bool touchpad_read_register(uint8_t register_address, uint8_t *value)
+{
+ bool transfer_succeeded = true;
+ transfer_succeeded &= twi_master_transfer(m_device_address, &register_address, 1, TWI_DONT_ISSUE_STOP);
+ if (transfer_succeeded)
+ {
+ transfer_succeeded &= twi_master_transfer(m_device_address | TWI_READ_BIT, value, 1, TWI_ISSUE_STOP);
+ }
+ return transfer_succeeded;
+}
+
+bool touchpad_write_register(uint8_t register_address, const uint8_t value)
+{
+ uint8_t w2_data[2];
+
+ w2_data[0] = register_address;
+ w2_data[1] = value;
+ return twi_master_transfer(m_device_address, w2_data, 2, TWI_ISSUE_STOP);
+}
+
+bool touchpad_product_id_read(uint8_t * product_id, uint8_t product_id_bytes)
+{
+ uint8_t w2_data[1];
+ bool transfer_succeeded = true;
+
+ w2_data[0] = TOUCHPAD_PRODUCT_ID;
+ transfer_succeeded &= twi_master_transfer(m_device_address, w2_data, 1, TWI_DONT_ISSUE_STOP);
+ if (transfer_succeeded)
+ {
+ transfer_succeeded &= twi_master_transfer(m_device_address | TWI_READ_BIT, product_id, product_id_bytes, TWI_ISSUE_STOP);
+ }
+ return transfer_succeeded;
+}
+
+/*lint --flb "Leave library region" */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/drivers_ext/synaptics_touchpad/synaptics_touchpad.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/drivers_ext/synaptics_touchpad/synaptics_touchpad.h
new file mode 100644
index 0000000..1996396
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/drivers_ext/synaptics_touchpad/synaptics_touchpad.h
@@ -0,0 +1,164 @@
+/**
+ * Copyright (c) 2009 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#ifndef SYNAPTICS_TOUCHPAD_H
+#define SYNAPTICS_TOUCHPAD_H
+
+/*lint ++flb "Enter library region" */
+
+#include <stdbool.h>
+#include <stdint.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** @file
+* @brief Synaptics Touchpad driver
+*
+*
+* @defgroup nrf_drivers_synaptics_touchpad Synaptics Touchpad driver
+* @{
+* @ingroup ext_drivers
+* @brief Synaptics Touchpad driver.
+*/
+
+/**
+ Touchpad register addresses.
+*/
+#define TOUCHPAD_INT_STATUS 0x14 //!< Interrupt status register
+#define TOUCHPAD_BUTTON_STATUS 0x41 //!< Button status register
+#define TOUCHPAD_FINGER0_REL 0x30 //!< First register in finger delta block
+#define TOUCHPAD_GESTURE_FLAGS 0x3A //!< Gesture flags 0
+#define TOUCHPAD_SCROLL 0x3F //!< Scroll zone X / horizontal multifinger scroll
+#define TOUCHPAD_CONTROL 0x42 //!< Device control register
+#define TOUCHPAD_COMMAND 0x8F //!< Device command register
+
+#define TOUCHPAD_RESET 0x54 //!< Address of reset
+#define TOUCHPAD_PAGESELECT 0xFF //!< Address of page select (can be found in every page at the same address)
+#define TOUCHPAD_PRODUCT_ID 0xA2 //!< Address of product ID string
+
+/**
+ Operational states
+*/
+typedef enum
+{
+ SleepmodeNormal = 0x00, //!< Normal operation
+ SleepmodeSensorSleep = 0x01 //!< Low power operation
+} TouchpadSleepMode_t;
+
+/**
+ @brief Function for Touchpad initialization.
+ @param device_address TWI address of the device in bits [6:0]
+ @retval true Touchpad was successfully identified and initialized
+ @retval false Unexpected product ID or communication failure
+*/
+bool touchpad_init(uint8_t device_address);
+
+/**
+ @brief Function for attempting to soft-reset the device.
+ @retval true Reset succeeded
+ @retval false Reset failed
+*/
+bool touchpad_reset(void);
+
+/**
+ @brief Function for reading the interrupt status register of the device. This clears all interrupts.
+ @param interrupt_status Address to store interrupt status to.
+ @retval true Register contents read successfully to interrupt_status
+ @retval false Reading failed
+*/
+bool touchpad_interrupt_status_read(uint8_t *interrupt_status);
+
+/**
+ @brief Function for sleep mode configuration.
+ @note In low power mode the touchpad do not generate interrupts from touch sensing.
+ @param[in] mode Operational mode
+ @retval true Sleep mode set successfully
+ @retval false Sleep mode setting failed
+*/
+bool touchpad_set_sleep_mode(TouchpadSleepMode_t mode);
+
+/**
+ @brief Function for reading a touchpad register contents over TWI.
+ @param[in] register_address Register address
+ @param[out] value Pointer to a data buffer where read data will be stored
+ @retval true Register read succeeded
+ @retval false Register read failed
+*/
+bool touchpad_read_register(uint8_t register_address, uint8_t *value);
+
+/**
+ @brief Function for writing a touchpad register contents over TWI.
+ @param[in] register_address Register address
+ @param[in] value Value to write to register
+ @retval true Register write succeeded
+ @retval false Register write failed
+*/
+bool touchpad_write_register(uint8_t register_address, uint8_t value);
+
+/**
+ @brief Function for writing touchpad register contents over TWI.
+ Writes one or more consecutive registers.
+ @param[out] product_id Pointer to a address to store product ID. Memory must be allocated for product_id_bytes number of bytes.
+ @param[in] product_id_bytes Number of bytes to read
+ @retval true Product ID read succeeded
+ @retval false Product ID read failed
+*/
+bool touchpad_product_id_read(uint8_t *product_id, uint8_t product_id_bytes);
+
+/**
+ @brief Function for reading and verifying touchpad's product ID.
+ @retval true Product ID is what was expected
+ @retval false Product ID was not what was expected
+*/
+bool touchpad_product_id_verify(void);
+
+/**
+ *@}
+ **/
+
+/*lint --flb "Leave library region" */
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __TOUCHPAD_H__ */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/drivers_ext/uda1380/uda1380.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/drivers_ext/uda1380/uda1380.c
new file mode 100644
index 0000000..05095d7
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/drivers_ext/uda1380/uda1380.c
@@ -0,0 +1,124 @@
+/**
+ * Copyright (c) 2016 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#include "uda1380.h"
+#include <string.h>
+
+ret_code_t uda1380_init(uda1380_iface_t const * p_iface,
+ uda1380_reg_t const * p_reg_config,
+ size_t reg_size)
+{
+ ret_code_t ret = NRF_SUCCESS;
+
+ ret = nrf_drv_twi_init(&p_iface->twi, &p_iface->twi_cfg, NULL, NULL);
+ if (ret != NRF_SUCCESS)
+ {
+ return ret;
+ }
+
+ nrf_drv_twi_enable(&p_iface->twi);
+
+ /*Probe device*/
+ uint8_t rx[] = {0};
+ ret = nrf_drv_twi_rx(&p_iface->twi, p_iface->twi_addr, rx, sizeof(rx));
+ if (ret != NRF_SUCCESS)
+ {
+ return ret;
+ }
+
+ for (size_t i = 0; i < reg_size; ++i)
+ {
+ uint8_t p_dat[sizeof(uda1380_reg_t)];
+ memcpy(p_dat, &p_reg_config[i], sizeof(uda1380_reg_t));
+ ret = nrf_drv_twi_tx(&p_iface->twi, p_iface->twi_addr, p_dat, sizeof(uda1380_reg_t), false);
+ if (ret != NRF_SUCCESS)
+ {
+ break;
+ }
+ }
+
+ return ret;
+}
+
+
+ret_code_t uda1380_enable(uda1380_iface_t const * p_iface)
+{
+ ret_code_t ret = NRF_SUCCESS;
+
+ static const uda1380_reg_t enable[] = {
+ UDA1380_REG_INIT(UDA1380_REG_PWR, 0xA500),
+ UDA1380_REG_INIT(UDA1380_REG_CLK, 0x0332),
+ };
+
+ for (size_t i = 0; i < ARRAY_SIZE(enable); ++i)
+ {
+ uint8_t p_dat[sizeof(uda1380_reg_t)];
+ memcpy(p_dat, &enable[i], sizeof(uda1380_reg_t));
+ ret = nrf_drv_twi_tx(&p_iface->twi, p_iface->twi_addr, p_dat, sizeof(uda1380_reg_t), false);
+ if (ret != NRF_SUCCESS)
+ {
+ break;
+ }
+ }
+
+ return ret;
+}
+
+
+ret_code_t uda1380_disable(uda1380_iface_t const * p_iface)
+{
+ ret_code_t ret = NRF_SUCCESS;
+
+ static const uda1380_reg_t disable[] = {
+ UDA1380_REG_INIT(UDA1380_REG_PWR, 0x0000),
+ UDA1380_REG_INIT(UDA1380_REG_CLK, 0x0000),
+ };
+
+ for (size_t i = 0; i < ARRAY_SIZE(disable); ++i)
+ {
+ const uint8_t * p_dat = (const uint8_t *)&disable[i];
+ ret = nrf_drv_twi_tx(&p_iface->twi, p_iface->twi_addr, p_dat, sizeof(uda1380_reg_t), false);
+ if (ret != NRF_SUCCESS)
+ {
+ break;
+ }
+ }
+
+ return ret;
+}
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/drivers_ext/uda1380/uda1380.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/drivers_ext/uda1380/uda1380.h
new file mode 100644
index 0000000..321ff31
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/drivers_ext/uda1380/uda1380.h
@@ -0,0 +1,140 @@
+/**
+ * Copyright (c) 2016 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#ifndef UDA1380_H__
+#define UDA1380_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <stdint.h>
+#include "nrf_drv_twi.h"
+
+
+#define UDA1380_REG_CLK 0x00
+#define UDA1380_REG_I2S 0x01
+#define UDA1380_REG_PWR 0x02
+#define UDA1380_REG_AMIX 0x03
+#define UDA1380_REG_HPA 0x04
+
+#define UDA1380_REG_VOL 0x10
+#define UDA1380_REG_MIX_VOL 0x11
+#define UDA1380_REG_PPROC 0x12
+#define UDA1380_REG_DEEMP 0x13
+#define UDA1380_REG_MIXER 0x14
+
+#define UDA1380_REG_RESET 0x7F
+
+
+/**
+ * @brief Default UDA1380 TWI configuration
+ *
+ * @param scl_pin SCL pin number
+ * @param sda_pin SDA pin number
+ */
+#define UDA1380_DEFAULT_TWI_CONFIG(scl_pin, sda_pin) { \
+ .scl = scl_pin, \
+ .sda = sda_pin, \
+ .frequency = NRF_DRV_TWI_FREQ_100K, \
+ .interrupt_priority = APP_IRQ_PRIORITY_HIGH, \
+ .clear_bus_init = false, \
+ .hold_bus_uninit = false \
+}
+
+/**
+ * @brief UDA1380 register descriptor
+ * */
+typedef struct {
+ uint8_t addr; //!< Internal register address
+ uint8_t val[2]; //!< Internal register value
+} uda1380_reg_t;
+
+#define UDA1380_REG_INIT(address, value) { \
+ .addr = address, \
+ .val = {(value) / 256, (value) & 0xFF}, \
+}
+
+/**
+ * @brief UDA1380 TWI bus address*/
+#define UDA1380_TWI_ADDRESS (0x18)
+
+/**
+ * @brief UDA1380 interface
+ * */
+typedef struct {
+ nrf_drv_twi_t twi; //!< TWI instance
+ nrf_drv_twi_config_t twi_cfg; //!< TWI configuration
+ uint8_t twi_addr; //!< UDA1380 TWI address
+} uda1380_iface_t;
+
+
+/**
+ * @brief Initializes UDA1380 codec IC
+ *
+ * @param p_iface Communication interface
+ * @param p_reg_config Configuration registers
+ * @param reg_size Number of configuration registers
+ *
+ * @return Standard error code
+ * */
+ret_code_t uda1380_init(uda1380_iface_t const * p_iface,
+ uda1380_reg_t const * p_reg_config,
+ size_t reg_size);
+
+/**
+ * @brief Enable UDA1380 codec
+ *
+ * @return Standard error code
+ * */
+ret_code_t uda1380_enable(uda1380_iface_t const * p_iface);
+
+
+/**
+ * @brief Disable UDA1380 codec
+ *
+ * @return Standard error code
+ * */
+ret_code_t uda1380_disable(uda1380_iface_t const * p_iface);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* UDA1380_H__ */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/drivers_nrf/nrf_soc_nosd/nrf_error.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/drivers_nrf/nrf_soc_nosd/nrf_error.h
new file mode 100644
index 0000000..c673beb
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/drivers_nrf/nrf_soc_nosd/nrf_error.h
@@ -0,0 +1,95 @@
+/**
+ * Copyright (c) 2012 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+/* Header guard */
+
+#ifndef SOFTDEVICE_PRESENT
+
+/**
+ @defgroup nrf_error Global Error Codes
+ @{
+
+ @brief Global Error definitions
+*/
+
+#ifndef NRF_ERROR_H__
+#define NRF_ERROR_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** @defgroup NRF_ERRORS_BASE Error Codes Base number definitions
+ * @{ */
+#define NRF_ERROR_BASE_NUM (0x0) ///< Global error base
+#define NRF_ERROR_SDM_BASE_NUM (0x1000) ///< SDM error base
+#define NRF_ERROR_SOC_BASE_NUM (0x2000) ///< SoC error base
+#define NRF_ERROR_STK_BASE_NUM (0x3000) ///< STK error base
+/** @} */
+
+#define NRF_SUCCESS (NRF_ERROR_BASE_NUM + 0) ///< Successful command
+#define NRF_ERROR_SVC_HANDLER_MISSING (NRF_ERROR_BASE_NUM + 1) ///< SVC handler is missing
+#define NRF_ERROR_SOFTDEVICE_NOT_ENABLED (NRF_ERROR_BASE_NUM + 2) ///< SoftDevice has not been enabled
+#define NRF_ERROR_INTERNAL (NRF_ERROR_BASE_NUM + 3) ///< Internal Error
+#define NRF_ERROR_NO_MEM (NRF_ERROR_BASE_NUM + 4) ///< No Memory for operation
+#define NRF_ERROR_NOT_FOUND (NRF_ERROR_BASE_NUM + 5) ///< Not found
+#define NRF_ERROR_NOT_SUPPORTED (NRF_ERROR_BASE_NUM + 6) ///< Not supported
+#define NRF_ERROR_INVALID_PARAM (NRF_ERROR_BASE_NUM + 7) ///< Invalid Parameter
+#define NRF_ERROR_INVALID_STATE (NRF_ERROR_BASE_NUM + 8) ///< Invalid state, operation disallowed in this state
+#define NRF_ERROR_INVALID_LENGTH (NRF_ERROR_BASE_NUM + 9) ///< Invalid Length
+#define NRF_ERROR_INVALID_FLAGS (NRF_ERROR_BASE_NUM + 10) ///< Invalid Flags
+#define NRF_ERROR_INVALID_DATA (NRF_ERROR_BASE_NUM + 11) ///< Invalid Data
+#define NRF_ERROR_DATA_SIZE (NRF_ERROR_BASE_NUM + 12) ///< Data size exceeds limit
+#define NRF_ERROR_TIMEOUT (NRF_ERROR_BASE_NUM + 13) ///< Operation timed out
+#define NRF_ERROR_NULL (NRF_ERROR_BASE_NUM + 14) ///< Null Pointer
+#define NRF_ERROR_FORBIDDEN (NRF_ERROR_BASE_NUM + 15) ///< Forbidden Operation
+#define NRF_ERROR_INVALID_ADDR (NRF_ERROR_BASE_NUM + 16) ///< Bad Memory Address
+#define NRF_ERROR_BUSY (NRF_ERROR_BASE_NUM + 17) ///< Busy
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // NRF_ERROR_H__
+
+/**
+ @}
+*/
+
+#endif // SOFTDEVICE_PRESENT
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/drivers_nrf/nrf_soc_nosd/nrf_nvic.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/drivers_nrf/nrf_soc_nosd/nrf_nvic.c
new file mode 100644
index 0000000..8fa8b2b
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/drivers_nrf/nrf_soc_nosd/nrf_nvic.c
@@ -0,0 +1,123 @@
+/**
+ * Copyright (c) 2016 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#include <stdlib.h>
+#include "nrf_soc.h"
+#include "nrf_error.h"
+
+static uint8_t m_in_critical_region = 0;
+
+uint32_t sd_nvic_EnableIRQ(IRQn_Type IRQn)
+{
+ NVIC_EnableIRQ(IRQn);
+ return NRF_SUCCESS;
+}
+
+uint32_t sd_nvic_DisableIRQ(IRQn_Type IRQn)
+{
+ NVIC_DisableIRQ(IRQn);
+ return NRF_SUCCESS;
+}
+
+uint32_t sd_nvic_GetPendingIRQ(IRQn_Type IRQn, uint32_t * p_pending_irq)
+{
+ if (p_pending_irq != NULL)
+ {
+ *p_pending_irq = NVIC_GetPendingIRQ(IRQn);
+ return NRF_SUCCESS;
+ }
+ return NRF_ERROR_NULL;
+}
+
+uint32_t sd_nvic_SetPendingIRQ(IRQn_Type IRQn)
+{
+ NVIC_SetPendingIRQ(IRQn);
+ return NRF_SUCCESS;
+}
+
+uint32_t sd_nvic_ClearPendingIRQ(IRQn_Type IRQn)
+{
+ NVIC_ClearPendingIRQ(IRQn);
+ return NRF_SUCCESS;
+}
+
+uint32_t sd_nvic_SetPriority(IRQn_Type IRQn, uint32_t priority)
+{
+ NVIC_SetPriority(IRQn, priority);
+ return NRF_SUCCESS;
+}
+
+uint32_t sd_nvic_GetPriority(IRQn_Type IRQn, uint32_t * p_priority)
+{
+ if (p_priority != NULL)
+ {
+ *p_priority = NVIC_GetPriority(IRQn);
+ return NRF_SUCCESS;
+ }
+
+ return NRF_ERROR_NULL;
+}
+
+uint32_t sd_nvic_SystemReset(void)
+{
+ NVIC_SystemReset();
+ return NRF_SUCCESS;
+}
+
+uint32_t sd_nvic_critical_region_enter(uint8_t * p_is_nested_critical_region)
+{
+ __disable_irq();
+
+ *p_is_nested_critical_region = (m_in_critical_region != 0);
+ m_in_critical_region++;
+
+ return NRF_SUCCESS;
+}
+
+uint32_t sd_nvic_critical_region_exit(uint8_t is_nested_critical_region)
+{
+ m_in_critical_region--;
+
+ if (is_nested_critical_region == 0)
+ {
+ m_in_critical_region = 0;
+ __enable_irq();
+ }
+ return NRF_SUCCESS;
+}
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/drivers_nrf/nrf_soc_nosd/nrf_nvic.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/drivers_nrf/nrf_soc_nosd/nrf_nvic.h
new file mode 100644
index 0000000..58dd027
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/drivers_nrf/nrf_soc_nosd/nrf_nvic.h
@@ -0,0 +1,166 @@
+/**
+ * Copyright (c) 2014 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#ifndef NRF_NVIC_H__
+#define NRF_NVIC_H__
+
+#include <stdint.h>
+#include "nrf.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**@brief Enable External Interrupt.
+ * @note Corresponds to NVIC_EnableIRQ in CMSIS.
+ *
+ * @pre{IRQn is valid and not reserved by the stack}
+ *
+ * @param[in] IRQn See the NVIC_EnableIRQ documentation in CMSIS.
+ *
+ * @retval ::NRF_SUCCESS The interrupt was enabled.
+ */
+uint32_t sd_nvic_EnableIRQ(IRQn_Type IRQn);
+
+/**@brief Disable External Interrupt.
+ * @note Corresponds to NVIC_DisableIRQ in CMSIS.
+ *
+ * @pre{IRQn is valid and not reserved by the stack}
+ *
+ * @param[in] IRQn See the NVIC_DisableIRQ documentation in CMSIS
+ *
+ * @retval ::NRF_SUCCESS The interrupt was disabled.
+ */
+uint32_t sd_nvic_DisableIRQ(IRQn_Type IRQn);
+
+/**@brief Get Pending Interrupt.
+ * @note Corresponds to NVIC_GetPendingIRQ in CMSIS.
+ *
+ * @pre{IRQn is valid and not reserved by the stack}
+ *
+ * @param[in] IRQn See the NVIC_GetPendingIRQ documentation in CMSIS.
+ * @param[out] p_pending_irq Return value from NVIC_GetPendingIRQ.
+ *
+ * @retval ::NRF_SUCCESS The interrupt is available for the application.
+ */
+uint32_t sd_nvic_GetPendingIRQ(IRQn_Type IRQn, uint32_t * p_pending_irq);
+
+/**@brief Set Pending Interrupt.
+ * @note Corresponds to NVIC_SetPendingIRQ in CMSIS.
+ *
+ * @pre{IRQn is valid and not reserved by the stack}
+ *
+ * @param[in] IRQn See the NVIC_SetPendingIRQ documentation in CMSIS.
+ *
+ * @retval ::NRF_SUCCESS The interrupt is set pending.
+ */
+uint32_t sd_nvic_SetPendingIRQ(IRQn_Type IRQn);
+
+/**@brief Clear Pending Interrupt.
+ * @note Corresponds to NVIC_ClearPendingIRQ in CMSIS.
+ *
+ * @pre{IRQn is valid and not reserved by the stack}
+ *
+ * @param[in] IRQn See the NVIC_ClearPendingIRQ documentation in CMSIS.
+ *
+ * @retval ::NRF_SUCCESS The interrupt pending flag is cleared.
+ */
+uint32_t sd_nvic_ClearPendingIRQ(IRQn_Type IRQn);
+
+/**@brief Set Interrupt Priority.
+ * @note Corresponds to NVIC_SetPriority in CMSIS.
+ *
+ * @pre{IRQn is valid and not reserved by the stack}
+ * @pre{priority is valid and not reserved by the stack}
+ *
+ * @param[in] IRQn See the NVIC_SetPriority documentation in CMSIS.
+ * @param[in] priority A valid IRQ priority for use by the application.
+ *
+ * @retval ::NRF_SUCCESS The interrupt and priority level is available for the application.
+ */
+uint32_t sd_nvic_SetPriority(IRQn_Type IRQn, uint32_t priority);
+
+/**@brief Get Interrupt Priority.
+ * @note Corresponds to NVIC_GetPriority in CMSIS.
+ *
+ * @pre{IRQn is valid and not reserved by the stack}
+ *
+ * @param[in] IRQn See the NVIC_GetPriority documentation in CMSIS.
+ * @param[out] p_priority Return value from NVIC_GetPriority.
+ *
+ * @retval ::NRF_SUCCESS The interrupt priority is returned in p_priority.
+ */
+uint32_t sd_nvic_GetPriority(IRQn_Type IRQn, uint32_t * p_priority);
+
+/**@brief System Reset.
+ * @note Corresponds to NVIC_SystemReset in CMSIS.
+ *
+ * @retval ::NRF_ERROR_SOC_NVIC_SHOULD_NOT_RETURN
+ */
+uint32_t sd_nvic_SystemReset(void);
+
+/**@brief Enters critical region.
+ *
+ * @post Application interrupts will be disabled.
+ * @sa sd_nvic_critical_region_exit
+ *
+ * @param[out] p_is_nested_critical_region 1: If in a nested critical region.
+ * 0: Otherwise.
+ *
+ * @retval ::NRF_SUCCESS
+ */
+uint32_t sd_nvic_critical_region_enter(uint8_t * p_is_nested_critical_region);
+
+/**@brief Exit critical region.
+ *
+ * @pre Application has entered a critical region using ::sd_nvic_critical_region_enter.
+ * @post If not in a nested critical region, the application interrupts will restored to the state before ::sd_nvic_critical_region_enter was called.
+ *
+ * @param[in] is_nested_critical_region If this is set to 1, the critical region won't be exited. @sa sd_nvic_critical_region_enter.
+ *
+ * @retval ::NRF_SUCCESS
+ */
+uint32_t sd_nvic_critical_region_exit(uint8_t is_nested_critical_region);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* NRF_NVIC_H__ */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/drivers_nrf/nrf_soc_nosd/nrf_sdm.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/drivers_nrf/nrf_soc_nosd/nrf_sdm.h
new file mode 100644
index 0000000..ec3f150
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/drivers_nrf/nrf_soc_nosd/nrf_sdm.h
@@ -0,0 +1,56 @@
+/**
+ * Copyright (c) 2015 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#ifndef NRF_SDM_H__
+#define NRF_SDM_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+#define NRF_FAULT_ID_SD_RANGE_START 0x00000000 /**< SoftDevice ID range start. */
+#define NRF_FAULT_ID_APP_RANGE_START 0x00001000 /**< Application ID range start. */
+
+#ifdef __cplusplus
+}
+#endif
+#endif // NRF_SDM_H__
+
+
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/drivers_nrf/nrf_soc_nosd/nrf_soc.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/drivers_nrf/nrf_soc_nosd/nrf_soc.c
new file mode 100644
index 0000000..da25fbb
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/drivers_nrf/nrf_soc_nosd/nrf_soc.c
@@ -0,0 +1,48 @@
+/**
+ * Copyright (c) 2014 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#include <stdlib.h>
+#include "nrf_soc.h"
+#include "nrf_error.h"
+
+uint32_t sd_app_evt_wait(void)
+{
+ __WFE();
+ return NRF_SUCCESS;
+}
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/drivers_nrf/nrf_soc_nosd/nrf_soc.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/drivers_nrf/nrf_soc_nosd/nrf_soc.h
new file mode 100644
index 0000000..c1c9d04
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/drivers_nrf/nrf_soc_nosd/nrf_soc.h
@@ -0,0 +1,80 @@
+/**
+ * Copyright (c) 2014 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#ifndef NRF_SOC_H__
+#define NRF_SOC_H__
+
+#include <stdint.h>
+#include "nrf.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**@brief Waits for an application event.
+ *
+ * An application event is either an application interrupt or a pended interrupt when the
+ * interrupt is disabled. When the interrupt is enabled it will be taken immediately since
+ * this function will wait in thread mode, then the execution will return in the application's
+ * main thread. When an interrupt is disabled and gets pended it will return to the application's
+ * thread main. The application must ensure that the pended flag is cleared using
+ * ::sd_nvic_ClearPendingIRQ in order to sleep using this function. This is only necessary for
+ * disabled interrupts, as the interrupt handler will clear the pending flag automatically for
+ * enabled interrupts.
+ *
+ * In order to wake up from disabled interrupts, the SEVONPEND flag has to be set in the Cortex-M0
+ * System Control Register (SCR). @sa CMSIS_SCB
+ *
+ * @note If an application interrupt has happened since the last time sd_app_evt_wait was
+ * called this function will return immediately and not go to sleep. This is to avoid race
+ * conditions that can occur when a flag is updated in the interrupt handler and processed
+ * in the main loop.
+ *
+ * @post An application interrupt has happened or a interrupt pending flag is set.
+ *
+ * @retval ::NRF_SUCCESS
+ */
+uint32_t sd_app_evt_wait(void);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* NRF_SOC_H__ */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/drivers_nrf/radio_config/radio_config.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/drivers_nrf/radio_config/radio_config.c
new file mode 100644
index 0000000..e3849df
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/drivers_nrf/radio_config/radio_config.c
@@ -0,0 +1,188 @@
+/**
+ * Copyright (c) 2009 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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
+* @addtogroup nrf_dev_radio_rx_example_main nrf_dev_radio_tx_example_main
+* @{
+*/
+
+#include "radio_config.h"
+#include "nrf_delay.h"
+
+/* These are set to zero as ShockBurst packets don't have corresponding fields. */
+#define PACKET_S1_FIELD_SIZE (0UL) /**< Packet S1 field size in bits. */
+#define PACKET_S0_FIELD_SIZE (0UL) /**< Packet S0 field size in bits. */
+#define PACKET_LENGTH_FIELD_SIZE (0UL) /**< Packet length field size in bits. */
+
+/**
+ * @brief Function for swapping/mirroring bits in a byte.
+ *
+ *@verbatim
+ * output_bit_7 = input_bit_0
+ * output_bit_6 = input_bit_1
+ * :
+ * output_bit_0 = input_bit_7
+ *@endverbatim
+ *
+ * @param[in] inp is the input byte to be swapped.
+ *
+ * @return
+ * Returns the swapped/mirrored input byte.
+ */
+static uint32_t swap_bits(uint32_t inp);
+
+/**
+ * @brief Function for swapping bits in a 32 bit word for each byte individually.
+ *
+ * The bits are swapped as follows:
+ * @verbatim
+ * output[31:24] = input[24:31]
+ * output[23:16] = input[16:23]
+ * output[15:8] = input[8:15]
+ * output[7:0] = input[0:7]
+ * @endverbatim
+ * @param[in] input is the input word to be swapped.
+ *
+ * @return
+ * Returns the swapped input byte.
+ */
+static uint32_t bytewise_bitswap(uint32_t inp);
+
+static uint32_t swap_bits(uint32_t inp)
+{
+ uint32_t i;
+ uint32_t retval = 0;
+
+ inp = (inp & 0x000000FFUL);
+
+ for (i = 0; i < 8; i++)
+ {
+ retval |= ((inp >> i) & 0x01) << (7 - i);
+ }
+
+ return retval;
+}
+
+
+static uint32_t bytewise_bitswap(uint32_t inp)
+{
+ return (swap_bits(inp >> 24) << 24)
+ | (swap_bits(inp >> 16) << 16)
+ | (swap_bits(inp >> 8) << 8)
+ | (swap_bits(inp));
+}
+
+
+/**
+ * @brief Function for configuring the radio to operate in ShockBurst compatible mode.
+ *
+ * To configure the application running on nRF24L series devices:
+ *
+ * @verbatim
+ * uint8_t tx_address[5] = { 0xC0, 0x01, 0x23, 0x45, 0x67 };
+ * hal_nrf_set_rf_channel(7);
+ * hal_nrf_set_address_width(HAL_NRF_AW_5BYTES);
+ * hal_nrf_set_address(HAL_NRF_TX, tx_address);
+ * hal_nrf_set_address(HAL_NRF_PIPE0, tx_address);
+ * hal_nrf_open_pipe(0, false);
+ * hal_nrf_set_datarate(HAL_NRF_1MBPS);
+ * hal_nrf_set_crc_mode(HAL_NRF_CRC_16BIT);
+ * hal_nrf_setup_dynamic_payload(0xFF);
+ * hal_nrf_enable_dynamic_payload(false);
+ * @endverbatim
+ *
+ * When transmitting packets with hal_nrf_write_tx_payload(const uint8_t *tx_pload, uint8_t length),
+ * match the length with PACKET_STATIC_LENGTH.
+ * hal_nrf_write_tx_payload(payload, PACKET_STATIC_LENGTH);
+ *
+*/
+void radio_configure()
+{
+ // Radio config
+ NRF_RADIO->TXPOWER = (RADIO_TXPOWER_TXPOWER_0dBm << RADIO_TXPOWER_TXPOWER_Pos);
+ NRF_RADIO->FREQUENCY = 7UL; // Frequency bin 7, 2407MHz
+ NRF_RADIO->MODE = (RADIO_MODE_MODE_Nrf_1Mbit << RADIO_MODE_MODE_Pos);
+
+ // Radio address config
+ NRF_RADIO->PREFIX0 =
+ ((uint32_t)swap_bits(0xC3) << 24) // Prefix byte of address 3 converted to nRF24L series format
+ | ((uint32_t)swap_bits(0xC2) << 16) // Prefix byte of address 2 converted to nRF24L series format
+ | ((uint32_t)swap_bits(0xC1) << 8) // Prefix byte of address 1 converted to nRF24L series format
+ | ((uint32_t)swap_bits(0xC0) << 0); // Prefix byte of address 0 converted to nRF24L series format
+
+ NRF_RADIO->PREFIX1 =
+ ((uint32_t)swap_bits(0xC7) << 24) // Prefix byte of address 7 converted to nRF24L series format
+ | ((uint32_t)swap_bits(0xC6) << 16) // Prefix byte of address 6 converted to nRF24L series format
+ | ((uint32_t)swap_bits(0xC4) << 0); // Prefix byte of address 4 converted to nRF24L series format
+
+ NRF_RADIO->BASE0 = bytewise_bitswap(0x01234567UL); // Base address for prefix 0 converted to nRF24L series format
+ NRF_RADIO->BASE1 = bytewise_bitswap(0x89ABCDEFUL); // Base address for prefix 1-7 converted to nRF24L series format
+
+ NRF_RADIO->TXADDRESS = 0x00UL; // Set device address 0 to use when transmitting
+ NRF_RADIO->RXADDRESSES = 0x01UL; // Enable device address 0 to use to select which addresses to receive
+
+ // Packet configuration
+ NRF_RADIO->PCNF0 = (PACKET_S1_FIELD_SIZE << RADIO_PCNF0_S1LEN_Pos) |
+ (PACKET_S0_FIELD_SIZE << RADIO_PCNF0_S0LEN_Pos) |
+ (PACKET_LENGTH_FIELD_SIZE << RADIO_PCNF0_LFLEN_Pos); //lint !e845 "The right argument to operator '|' is certain to be 0"
+
+ // Packet configuration
+ NRF_RADIO->PCNF1 = (RADIO_PCNF1_WHITEEN_Disabled << RADIO_PCNF1_WHITEEN_Pos) |
+ (RADIO_PCNF1_ENDIAN_Big << RADIO_PCNF1_ENDIAN_Pos) |
+ (PACKET_BASE_ADDRESS_LENGTH << RADIO_PCNF1_BALEN_Pos) |
+ (PACKET_STATIC_LENGTH << RADIO_PCNF1_STATLEN_Pos) |
+ (PACKET_PAYLOAD_MAXSIZE << RADIO_PCNF1_MAXLEN_Pos); //lint !e845 "The right argument to operator '|' is certain to be 0"
+
+ // CRC Config
+ NRF_RADIO->CRCCNF = (RADIO_CRCCNF_LEN_Two << RADIO_CRCCNF_LEN_Pos); // Number of checksum bits
+ if ((NRF_RADIO->CRCCNF & RADIO_CRCCNF_LEN_Msk) == (RADIO_CRCCNF_LEN_Two << RADIO_CRCCNF_LEN_Pos))
+ {
+ NRF_RADIO->CRCINIT = 0xFFFFUL; // Initial value
+ NRF_RADIO->CRCPOLY = 0x11021UL; // CRC poly: x^16 + x^12^x^5 + 1
+ }
+ else if ((NRF_RADIO->CRCCNF & RADIO_CRCCNF_LEN_Msk) == (RADIO_CRCCNF_LEN_One << RADIO_CRCCNF_LEN_Pos))
+ {
+ NRF_RADIO->CRCINIT = 0xFFUL; // Initial value
+ NRF_RADIO->CRCPOLY = 0x107UL; // CRC poly: x^8 + x^2^x^1 + 1
+ }
+}
+
+/**
+ * @}
+ */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/drivers_nrf/radio_config/radio_config.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/drivers_nrf/radio_config/radio_config.h
new file mode 100644
index 0000000..f8e8be5
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/drivers_nrf/radio_config/radio_config.h
@@ -0,0 +1,58 @@
+/**
+ * Copyright (c) 2009 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#ifndef RADIO_CONFIG_H
+#define RADIO_CONFIG_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define PACKET_BASE_ADDRESS_LENGTH (4UL) //!< Packet base address length field size in bytes
+#define PACKET_STATIC_LENGTH (1UL) //!< Packet static length in bytes
+#define PACKET_PAYLOAD_MAXSIZE (PACKET_STATIC_LENGTH) //!< Packet payload maximum size in bytes
+
+void radio_configure(void);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/drivers_nrf/sdio/config/sdio_config.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/drivers_nrf/sdio/config/sdio_config.h
new file mode 100644
index 0000000..6551ec0
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/drivers_nrf/sdio/config/sdio_config.h
@@ -0,0 +1,55 @@
+/**
+ * Copyright (c) 2012 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#ifndef SDIO_CONFIG_H
+#define SDIO_CONFIG_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define SDIO_CONFIG_CLOCK_PIN_NUMBER 24
+#define SDIO_CONFIG_DATA_PIN_NUMBER 25
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/drivers_nrf/sdio/sdio.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/drivers_nrf/sdio/sdio.c
new file mode 100644
index 0000000..68763b0
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/drivers_nrf/sdio/sdio.c
@@ -0,0 +1,244 @@
+/**
+ * Copyright (c) 2009 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#include <stdint.h>
+
+#include "nrf.h"
+#include "nrf_delay.h"
+#include "sdio.h"
+#include "nrf_gpio.h"
+
+#include "sdio_config.h"
+
+/*lint ++flb "Enter library region" */
+
+/*lint -e717 -save "Suppress do {} while (0) for these macros" */
+#define SDIO_CLOCK_HIGH() do { NRF_GPIO->OUTSET = (1UL << SDIO_CONFIG_CLOCK_PIN_NUMBER); } while (0) /*!< Pulls SCL line high */
+#define SDIO_CLOCK_LOW() do { NRF_GPIO->OUTCLR = (1UL << SDIO_CONFIG_CLOCK_PIN_NUMBER); } while (0) /*!< Pulls SCL line low */
+#define SDIO_DATA_HIGH() do { NRF_GPIO->OUTSET = (1UL << SDIO_CONFIG_DATA_PIN_NUMBER); } while (0) /*!< Pulls SDA line high */
+#define SDIO_DATA_LOW() do { NRF_GPIO->OUTCLR = (1UL << SDIO_CONFIG_DATA_PIN_NUMBER); } while (0) /*!< Pulls SDA line low */
+#define SDIO_DATA_OUTPUT() do { NRF_GPIO->DIRSET = (1UL << SDIO_CONFIG_DATA_PIN_NUMBER); } while (0) /*!< Configures SDA pin as output */
+#define SDIO_CLOCK_OUTPUT() do { NRF_GPIO->DIRSET = (1UL << SDIO_CONFIG_CLOCK_PIN_NUMBER); } while (0) /*!< Configures SCL pin as output */
+/*lint -restore */
+
+/*lint -emacro(845,SDIO_DATA_INPUT) // A zero has been given as right argument to operator '|'" */
+
+#define SDIO_DATA_INPUT() do { \
+ nrf_gpio_cfg_input(25, NRF_GPIO_PIN_NOPULL); \
+} while (0)
+
+#define SDIO_DATA_READ() ((NRF_GPIO->IN >> SDIO_CONFIG_DATA_PIN_NUMBER) & 0x1UL) /*!< Reads current state of SDA */
+#define SDIO_CLOCK_READ() ((NRF_GPIO->IN >> SDIO_CONFIG_CLOCK_PIN_NUMBER) & 0x1UL) /*!< Reads current state of SCL */
+#define SDIO_DELAY() nrf_delay_us(10) /*!< Time to wait when pin states are changed. For fast-mode the delay can be zero and for standard-mode 4 us delay is sufficient. */
+
+void sdio_init(void)
+{
+ SDIO_CLOCK_HIGH();
+ SDIO_DATA_HIGH();
+ SDIO_CLOCK_OUTPUT();
+ SDIO_DATA_INPUT();
+
+ // If slave is stuck in the middle of transfer, clock out bits until the slave ACKs the transfer
+ for (uint_fast8_t i = 16; i--;)
+ {
+ SDIO_DELAY();
+ SDIO_CLOCK_LOW();
+ SDIO_DELAY();
+ SDIO_CLOCK_HIGH();
+ SDIO_DELAY();
+
+ if (SDIO_DATA_READ())
+ {
+ break;
+ }
+ }
+
+ for (uint_fast8_t i = 5; i--;)
+ {
+ SDIO_DELAY();
+ SDIO_CLOCK_LOW();
+ SDIO_DELAY();
+ SDIO_CLOCK_HIGH();
+ }
+
+ SDIO_DATA_OUTPUT();
+ SDIO_DATA_HIGH();
+
+ SDIO_DELAY();
+}
+
+uint8_t sdio_read_byte(uint8_t address)
+{
+ uint8_t data_byte = 0;
+
+ SDIO_DATA_OUTPUT();
+
+ for (uint_fast8_t i = 8; i--;)
+ {
+ SDIO_DELAY();
+
+ SDIO_CLOCK_LOW();
+
+ if (address & (1U << i))
+ {
+ SDIO_DATA_HIGH();
+ }
+ else
+ {
+ SDIO_DATA_LOW();
+ }
+
+ SDIO_DELAY();
+
+ SDIO_CLOCK_HIGH();
+ }
+
+ nrf_delay_us(20);
+
+ SDIO_DATA_INPUT();
+
+ for (uint_fast8_t i = 8; i--;)
+ {
+ SDIO_CLOCK_LOW();
+ SDIO_DELAY();
+ SDIO_CLOCK_HIGH();
+ SDIO_DELAY();
+ data_byte |= (uint8_t)(SDIO_DATA_READ() << i);
+ }
+
+ SDIO_DATA_HIGH();
+ SDIO_DATA_OUTPUT();
+
+ SDIO_DELAY();
+
+ return data_byte;
+}
+
+void sdio_read_burst(uint8_t * target_buffer, uint8_t target_buffer_size)
+{
+ uint_fast8_t address = 0x63;
+
+ SDIO_DATA_OUTPUT();
+
+ for (uint_fast8_t bit_index=8; bit_index--;)
+ {
+ SDIO_CLOCK_LOW();
+
+ if (address & (1U << bit_index))
+ {
+ SDIO_DATA_HIGH();
+ }
+ else
+ {
+ SDIO_DATA_LOW();
+ }
+
+ SDIO_CLOCK_HIGH();
+ }
+
+ SDIO_DATA_INPUT();
+
+ for (uint_fast8_t target_buffer_index = 0; target_buffer_index < target_buffer_size; target_buffer_index++)
+ {
+ target_buffer[target_buffer_index] = 0;
+
+ for (uint_fast8_t bit_index = 8; bit_index--;)
+ {
+ SDIO_CLOCK_LOW();
+ SDIO_CLOCK_HIGH();
+ target_buffer[target_buffer_index] |= (uint8_t)(SDIO_DATA_READ() << bit_index);
+ }
+ }
+}
+
+void sdio_write_byte(uint8_t address, uint8_t data_byte)
+{
+ // Add write indication bit
+ address |= 0x80;
+
+ SDIO_DATA_OUTPUT();
+
+ for (uint_fast8_t i = 8; i--;)
+ {
+ SDIO_DELAY();
+
+ SDIO_CLOCK_LOW();
+
+ if (address & (1U << i))
+ {
+ SDIO_DATA_HIGH();
+ }
+ else
+ {
+ SDIO_DATA_LOW();
+ }
+
+ SDIO_DELAY();
+
+ SDIO_CLOCK_HIGH();
+ }
+
+ SDIO_DELAY();
+
+ for (uint_fast8_t i = 8; i--;)
+ {
+ SDIO_CLOCK_LOW();
+
+ if (data_byte & (1U << i))
+ {
+ SDIO_DATA_HIGH();
+ }
+ else
+ {
+ SDIO_DATA_LOW();
+ }
+
+ SDIO_DELAY();
+
+ SDIO_CLOCK_HIGH();
+
+ SDIO_DELAY();
+ }
+
+ SDIO_DATA_HIGH();
+
+ SDIO_DELAY();
+}
+
+/*lint --flb "Leave library region" */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/drivers_nrf/sdio/sdio.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/drivers_nrf/sdio/sdio.h
new file mode 100644
index 0000000..bea2062
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/drivers_nrf/sdio/sdio.h
@@ -0,0 +1,105 @@
+/**
+ * Copyright (c) 2009 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#ifndef SDIO_H
+#define SDIO_H
+
+/*lint ++flb "Enter library region" */
+
+#include <stdbool.h>
+#include <stdint.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** @file
+* @brief 2-wire serial interface driver (compatible with ADNS2080 mouse sensor driver)
+*
+*
+* @defgroup nrf_drivers_sdio SDIO driver
+* @{
+* @ingroup nrf_drivers
+* @brief 2-wire serial interface driver.
+*/
+
+/**
+ * @brief Function for initializing 2-wire serial interface and trying to handle stuck slaves.
+ *
+ */
+void sdio_init(void);
+
+/**
+ * @brief Function for reading a byte over 2-wire serial interface.
+ *
+ * Developer needs to implement this function in a way that suits the hardware.
+ * @param address Register address to read from
+ * @return Byte read
+ */
+uint8_t sdio_read_byte(uint8_t address);
+
+/**
+ * @brief Function for reading several bytes over 2-wire serial interface using burst mode.
+ *
+ * Developer needs to implement this function in a way that suits the hardware.
+ * @param target_buffer Buffer location to store read bytes to
+ * @param target_buffer_size Bytes allocated for target_buffer
+ */
+void sdio_read_burst(uint8_t *target_buffer, uint8_t target_buffer_size);
+
+/**
+ * @brief Function for writing a byte over 2-wire serial interface.
+ *
+ * Developer needs to implement this function in a way that suits the hardware.
+ * @param address Register address to write to
+ * @param data_byte Data byte to write
+ */
+void sdio_write_byte(uint8_t address, uint8_t data_byte);
+
+/**
+ *@}
+ **/
+
+/*lint --flb "Leave library region" */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/drivers_nrf/spi_master/spi_5W_master.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/drivers_nrf/spi_master/spi_5W_master.c
new file mode 100644
index 0000000..031863d
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/drivers_nrf/spi_master/spi_5W_master.c
@@ -0,0 +1,629 @@
+/**
+ * Copyright (c) 2014 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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
+ *
+ * @defgroup ser_phy_spi_5W_hw_driver_master spi_5W_master.c
+ * @{
+ * @ingroup ser_phy_spi_5W_hw_driver_master
+ *
+ * @brief SPI_5W_RAW hardware driver.
+ */
+
+#include "app_error.h"
+#include "app_util_platform.h"
+#include "nrf_gpio.h"
+#include "nrf.h"
+#include "spi_5W_master.h"
+#include "ser_config_5W_app.h"
+#include "ser_phy_debug_app.h"
+#include "sdk_common.h"
+
+
+#define _static
+
+#define DOUBLE_BUFFERED /**< A flag for enabling double buffering. */
+
+#define SPI_PIN_DISCONNECTED 0xFFFFFFFF /**< A value used to the PIN deinitialization. */
+#define SPI_DEFAULT_TX_BYTE 0x00 /**< Default byte (used to clock transmission
+ from slave to the master) */
+
+typedef struct
+{
+ NRF_SPI_Type * p_nrf_spi; /**< A pointer to the NRF SPI master */
+ IRQn_Type irq_type; /**< A type of NVIC IRQn */
+
+ uint8_t * p_tx_buffer; /**< A pointer to TX buffer. */
+ uint16_t tx_length; /**< A length of TX buffer. */
+ uint16_t tx_index; /**< A index of the current element in the TX buffer. */
+
+ uint8_t * p_rx_buffer; /**< A pointer to RX buffer. */
+ uint16_t rx_length; /**< A length RX buffer. */
+ uint16_t rx_index; /**< A index of the current element in the RX buffer. */
+
+ uint16_t max_length; /**< Max length (Max of the TX and RX length). */
+ uint16_t bytes_count;
+ uint8_t pin_slave_select; /**< A pin for Slave Select. */
+
+ spi_master_event_handler_t callback_event_handler; /**< A handler for event callback function. */
+ spi_master_state_t state; /**< A state of an instance of SPI master. */
+ bool start_flag;
+ bool abort_flag;
+
+} spi_master_instance_t;
+
+#ifdef _SPI_5W_
+typedef enum
+{
+ HOOK_STATE_DISABLED,
+ HOOK_STATE_IDLE,
+ HOOK_STATE_GUARDED,
+ HOOK_STATE_ABORTED,
+ HOOK_STATE_RESTARTED,
+ HOOK_STATE_PASSING
+} spi_hook_state_t;
+
+
+_static spi_master_event_handler_t m_ser_phy_event_handler;
+_static spi_master_hw_instance_t m_spi_master_hw_instance;
+_static spi_hook_state_t m_hook_state = HOOK_STATE_DISABLED;
+#endif
+
+#ifdef SER_PHY_DEBUG_APP_ENABLE
+_static spi_master_raw_callback_t m_debug_callback;
+#endif
+
+_static spi_master_instance_t m_spi_master_instances[SPI_MASTER_HW_ENABLED_COUNT];
+
+static __INLINE spi_master_instance_t * spi_master_get_instance(
+ const spi_master_hw_instance_t spi_master_hw_instance);
+static __INLINE void spi_master_send_recv_irq(spi_master_instance_t * const p_spi_instance);
+static __INLINE void spi_master_signal_evt(spi_master_instance_t * const p_spi_instance,
+ spi_master_evt_type_t event_type,
+ const uint16_t data);
+
+#ifdef SPI_MASTER_0_ENABLE
+/**
+ * @brief SPI0 interrupt handler.
+ */
+void SPI0_TWI0_IRQHandler(void)
+{
+ if (NRF_SPI0->EVENTS_READY != 0)
+ {
+ NRF_SPI0->EVENTS_READY = 0;
+
+ spi_master_instance_t * p_spi_instance = spi_master_get_instance(SPI_MASTER_0);
+
+ spi_master_send_recv_irq(p_spi_instance);
+ }
+}
+#endif //SPI_MASTER_0_ENABLE
+
+#ifdef SPI_MASTER_1_ENABLE
+/**
+ * @brief SPI0 interrupt handler.
+ */
+void SPI1_TWI1_IRQHandler(void)
+{
+ if (NRF_SPI1->EVENTS_READY != 0)
+ {
+ NRF_SPI1->EVENTS_READY = 0;
+
+ spi_master_instance_t * p_spi_instance = spi_master_get_instance(SPI_MASTER_1);
+
+ spi_master_send_recv_irq(p_spi_instance);
+ }
+}
+#endif //SPI_MASTER_1_ENABLE
+
+#if defined(SPI_MASTER_0_ENABLE) || defined(SPI_MASTER_1_ENABLE)
+
+/**@brief Function for getting an instance of SPI master. */
+static __INLINE spi_master_instance_t * spi_master_get_instance(
+ const spi_master_hw_instance_t spi_master_hw_instance)
+{
+ return &(m_spi_master_instances[(uint8_t)spi_master_hw_instance]);
+}
+
+/** @brief Function for initializing instance of SPI master by default values. */
+static __INLINE void spi_master_init_hw_instance(NRF_SPI_Type * p_nrf_spi,
+ IRQn_Type irq_type,
+ spi_master_instance_t * p_spi_instance)
+{
+ APP_ERROR_CHECK_BOOL(p_spi_instance != NULL);
+
+ p_spi_instance->p_nrf_spi = p_nrf_spi;
+ p_spi_instance->irq_type = irq_type;
+
+ p_spi_instance->p_tx_buffer = NULL;
+ p_spi_instance->tx_length = 0;
+ p_spi_instance->tx_index = 0;
+
+ p_spi_instance->p_rx_buffer = NULL;
+ p_spi_instance->rx_length = 0;
+ p_spi_instance->rx_index = 0;
+
+ p_spi_instance->bytes_count = 0;
+ p_spi_instance->max_length = 0;
+ p_spi_instance->pin_slave_select = 0;
+
+ p_spi_instance->callback_event_handler = NULL;
+
+ p_spi_instance->state = SPI_MASTER_STATE_DISABLED;
+ p_spi_instance->abort_flag = false;
+ p_spi_instance->start_flag = false;
+}
+
+/**@brief Function for initializing TX or RX buffer. */
+static __INLINE void spi_master_buffer_init(uint8_t * const p_buf,
+ const uint16_t buf_len,
+ uint8_t * * pp_buf,
+ uint16_t * const p_buf_len,
+ uint16_t * const p_index)
+{
+ APP_ERROR_CHECK_BOOL(pp_buf != NULL);
+ APP_ERROR_CHECK_BOOL(p_buf_len != NULL);
+ APP_ERROR_CHECK_BOOL(p_index != NULL);
+
+ *pp_buf = p_buf;
+ *p_buf_len = (p_buf != NULL) ? buf_len : 0;
+ *p_index = 0;
+}
+
+/**@brief Function for releasing TX or RX buffer. */
+static __INLINE void spi_master_buffer_release(uint8_t * * const pp_buf, uint16_t * const p_buf_len)
+{
+ APP_ERROR_CHECK_BOOL(pp_buf != NULL);
+ APP_ERROR_CHECK_BOOL(p_buf_len != NULL);
+
+ *pp_buf = NULL;
+ *p_buf_len = 0;
+}
+
+/**@brief Function for sending events by callback. */
+static __INLINE void spi_master_signal_evt(spi_master_instance_t * const p_spi_instance,
+ spi_master_evt_type_t event_type,
+ const uint16_t data)
+{
+ APP_ERROR_CHECK_BOOL(p_spi_instance != NULL);
+
+ if (p_spi_instance->callback_event_handler != NULL)
+ {
+ spi_master_evt_t event = {SPI_MASTER_EVT_TYPE_MAX, 0};
+ event.type = event_type;
+ event.data = data;
+ p_spi_instance->callback_event_handler(event);
+ }
+}
+
+/**@brief Function insert to a TX buffer another byte or two bytes (depends on flag @ref DOUBLE_BUFFERED). */
+static __INLINE void spi_master_send_initial_bytes(spi_master_instance_t * const p_spi_instance)
+{
+ APP_ERROR_CHECK_BOOL(p_spi_instance != NULL);
+
+ p_spi_instance->p_nrf_spi->TXD = ((p_spi_instance->p_tx_buffer != NULL) &&
+ (p_spi_instance->tx_index < p_spi_instance->tx_length)) ?
+ p_spi_instance->p_tx_buffer[p_spi_instance->tx_index] :
+ SPI_DEFAULT_TX_BYTE;
+ (p_spi_instance->tx_index)++;
+
+ #ifdef DOUBLE_BUFFERED
+
+ if (p_spi_instance->tx_index < p_spi_instance->max_length)
+ {
+ p_spi_instance->p_nrf_spi->TXD = ((p_spi_instance->p_tx_buffer != NULL) &&
+ (p_spi_instance->tx_index < p_spi_instance->tx_length)) ?
+ p_spi_instance->p_tx_buffer[p_spi_instance->tx_index] :
+ SPI_DEFAULT_TX_BYTE;
+ (p_spi_instance->tx_index)++;
+ }
+ #endif
+}
+
+/**@brief Function for receiving and sending data from IRQ. (The same for both IRQs). */
+static __INLINE void spi_master_send_recv_irq(spi_master_instance_t * const p_spi_instance)
+{
+
+ uint8_t rx_byte;
+
+ APP_ERROR_CHECK_BOOL(p_spi_instance != NULL);
+ APP_ERROR_CHECK_BOOL(p_spi_instance->state == SPI_MASTER_STATE_BUSY);
+
+ p_spi_instance->bytes_count++;
+ rx_byte = p_spi_instance->p_nrf_spi->RXD;
+
+ if (p_spi_instance->start_flag)
+ {
+ p_spi_instance->start_flag = false;
+ spi_master_signal_evt(p_spi_instance, SPI_MASTER_EVT_FIRST_BYTE_RECEIVED, (uint16_t)rx_byte);
+ }
+ else if (p_spi_instance->abort_flag ) //this is tricky, but callback for SPI_MASTER_EVT_FIRST_BYTE_RECEIVED will set this flag for a first byte, which is bad because there is still byte in a buffer
+ { //and for a single byte transaction you will get XFERDONE event to restart
+ p_spi_instance->abort_flag = false;
+ p_spi_instance->state = SPI_MASTER_STATE_ABORTED;
+ nrf_gpio_pin_set(p_spi_instance->pin_slave_select);
+ spi_master_signal_evt(p_spi_instance, SPI_MASTER_EVT_TRANSFER_ABORTED, 0);
+ return;
+ }
+
+ if ((p_spi_instance->p_rx_buffer != NULL) &&
+ (p_spi_instance->rx_index < p_spi_instance->rx_length))
+ {
+ p_spi_instance->p_rx_buffer[p_spi_instance->rx_index++] = rx_byte;
+ }
+
+ if ((p_spi_instance->tx_index < p_spi_instance->max_length) && (!(p_spi_instance->abort_flag))) //do not TX if you know that there is an abort to be done - this should work for a DOUBLE BUFFERING ???
+ {
+ p_spi_instance->p_nrf_spi->TXD = ((p_spi_instance->p_tx_buffer != NULL) &&
+ (p_spi_instance->tx_index < p_spi_instance->tx_length)) ?
+ p_spi_instance->p_tx_buffer[p_spi_instance->tx_index] :
+ SPI_DEFAULT_TX_BYTE;
+ (p_spi_instance->tx_index)++;
+ }
+
+ if (p_spi_instance->bytes_count >= p_spi_instance->max_length)
+ {
+ APP_ERROR_CHECK_BOOL(p_spi_instance->bytes_count == p_spi_instance->max_length);
+ nrf_gpio_pin_set(p_spi_instance->pin_slave_select);
+ p_spi_instance->state = SPI_MASTER_STATE_IDLE;
+ spi_master_signal_evt(p_spi_instance,
+ SPI_MASTER_EVT_TRANSFER_COMPLETED,
+ p_spi_instance->tx_index);
+ }
+ return;
+}
+#endif //defined(SPI_MASTER_0_ENABLE) || defined(SPI_MASTER_1_ENABLE)
+
+
+/**
+ * @brief Function for opening and initializing a SPI master driver. */
+uint32_t spi_master_open(const spi_master_hw_instance_t spi_master_hw_instance,
+ spi_master_config_t const * const p_spi_master_config)
+{
+ #if defined(SPI_MASTER_0_ENABLE) || defined(SPI_MASTER_1_ENABLE)
+
+
+ VERIFY_PARAM_NOT_NULL(p_spi_master_config);
+
+ spi_master_instance_t * p_spi_instance = spi_master_get_instance(spi_master_hw_instance);
+
+ switch (spi_master_hw_instance)
+ {
+ #ifdef SPI_MASTER_0_ENABLE
+ case SPI_MASTER_0:
+ spi_master_init_hw_instance(NRF_SPI0, SPI0_TWI0_IRQn, p_spi_instance);
+ break;
+ #endif //SPI_MASTER_0_ENABLE
+
+ #ifdef SPI_MASTER_1_ENABLE
+ case SPI_MASTER_1:
+ spi_master_init_hw_instance(NRF_SPI1, SPI1_TWI1_IRQn, p_spi_instance);
+ break;
+ #endif //SPI_MASTER_1_ENABLE
+
+ default:
+ break;
+ }
+
+ //A Slave select must be set as high before setting it as output,
+ //because during connect it to the pin it causes glitches.
+ nrf_gpio_pin_set(p_spi_master_config->SPI_Pin_SS);
+ nrf_gpio_cfg_output(p_spi_master_config->SPI_Pin_SS);
+ nrf_gpio_pin_set(p_spi_master_config->SPI_Pin_SS);
+
+ //Configure GPIO
+ nrf_gpio_cfg_output(p_spi_master_config->SPI_Pin_SCK);
+ nrf_gpio_cfg_output(p_spi_master_config->SPI_Pin_MOSI);
+ nrf_gpio_cfg_input(p_spi_master_config->SPI_Pin_MISO, NRF_GPIO_PIN_NOPULL);
+ p_spi_instance->pin_slave_select = p_spi_master_config->SPI_Pin_SS;
+
+ /* Configure SPI hardware */
+ p_spi_instance->p_nrf_spi->PSELSCK = p_spi_master_config->SPI_Pin_SCK;
+ p_spi_instance->p_nrf_spi->PSELMOSI = p_spi_master_config->SPI_Pin_MOSI;
+ p_spi_instance->p_nrf_spi->PSELMISO = p_spi_master_config->SPI_Pin_MISO;
+
+ p_spi_instance->p_nrf_spi->FREQUENCY = p_spi_master_config->SPI_Freq;
+
+ p_spi_instance->p_nrf_spi->CONFIG =
+ (uint32_t)(p_spi_master_config->SPI_CPHA << SPI_CONFIG_CPHA_Pos) |
+ (p_spi_master_config->SPI_CPOL << SPI_CONFIG_CPOL_Pos) |
+ (p_spi_master_config->SPI_ORDER << SPI_CONFIG_ORDER_Pos);
+
+
+ /* Clear waiting interrupts and events */
+ p_spi_instance->p_nrf_spi->EVENTS_READY = 0;
+
+ NVIC_ClearPendingIRQ(p_spi_instance->irq_type);
+ NVIC_SetPriority(p_spi_instance->irq_type, APP_IRQ_PRIORITY_MID);
+
+ /* Clear event handler */
+ p_spi_instance->callback_event_handler = NULL;
+
+ /* Enable interrupt */
+ p_spi_instance->p_nrf_spi->INTENSET = (SPI_INTENSET_READY_Set << SPI_INTENCLR_READY_Pos);
+ NVIC_EnableIRQ(p_spi_instance->irq_type);
+
+ /* Enable SPI hardware */
+ p_spi_instance->p_nrf_spi->ENABLE = (SPI_ENABLE_ENABLE_Enabled << SPI_ENABLE_ENABLE_Pos);
+
+ /* Change state to IDLE */
+ p_spi_instance->state = SPI_MASTER_STATE_IDLE;
+
+ return NRF_SUCCESS;
+ #else
+ return NRF_ERROR_NOT_SUPPORTED;
+ #endif
+}
+
+/**
+ * @brief Function for closing a SPI master driver.
+ */
+void spi_master_close(const spi_master_hw_instance_t spi_master_hw_instance)
+{
+ #if defined(SPI_MASTER_0_ENABLE) || defined(SPI_MASTER_1_ENABLE)
+ spi_master_instance_t * p_spi_instance = spi_master_get_instance(spi_master_hw_instance);
+
+ /* Disable interrupt */
+ NVIC_ClearPendingIRQ(p_spi_instance->irq_type);
+ NVIC_DisableIRQ(p_spi_instance->irq_type);
+
+ p_spi_instance->p_nrf_spi->ENABLE = (SPI_ENABLE_ENABLE_Disabled << SPI_ENABLE_ENABLE_Pos);
+
+ /* Set Slave Select pin as input with pull-up. */
+ nrf_gpio_pin_set(p_spi_instance->pin_slave_select);
+ nrf_gpio_cfg_input(p_spi_instance->pin_slave_select, NRF_GPIO_PIN_PULLUP);
+ p_spi_instance->pin_slave_select = (uint8_t)0xFF;
+
+ /* Disconnect pins from SPI hardware */
+ p_spi_instance->p_nrf_spi->PSELSCK = (uint32_t)SPI_PIN_DISCONNECTED;
+ p_spi_instance->p_nrf_spi->PSELMOSI = (uint32_t)SPI_PIN_DISCONNECTED;
+ p_spi_instance->p_nrf_spi->PSELMISO = (uint32_t)SPI_PIN_DISCONNECTED;
+
+ /* Reset to default values */
+ spi_master_init_hw_instance(NULL, (IRQn_Type)0, p_spi_instance);
+ #else
+ return;
+ #endif
+}
+
+/**
+ * @brief Function for getting current state of the SPI master driver.
+ */
+__INLINE spi_master_state_t spi_master_get_state(
+ const spi_master_hw_instance_t spi_master_hw_instance)
+{
+ #if defined(SPI_MASTER_0_ENABLE) || defined(SPI_MASTER_1_ENABLE)
+ spi_master_instance_t * spi_instance = spi_master_get_instance(spi_master_hw_instance);
+ return spi_instance->state;
+ #else
+ return SPI_MASTER_STATE_DISABLED;
+ #endif
+}
+
+/**
+ * @brief Function for event handler registration.
+ */
+__INLINE void spi_master_evt_handler_reg(const spi_master_hw_instance_t spi_master_hw_instance,
+ spi_master_event_handler_t event_handler)
+{
+ #if defined(SPI_MASTER_0_ENABLE) || defined(SPI_MASTER_1_ENABLE)
+ spi_master_instance_t * spi_instance = spi_master_get_instance(spi_master_hw_instance);
+ spi_instance->callback_event_handler = event_handler;
+ #else
+ return;
+ #endif
+}
+
+/**
+ * @brief Function for transmitting data between SPI master and SPI slave.
+ */
+uint32_t spi_master_send_recv(const spi_master_hw_instance_t spi_master_hw_instance,
+ uint8_t * const p_tx_buf, const uint16_t tx_buf_len,
+ uint8_t * const p_rx_buf, const uint16_t rx_buf_len)
+{
+ #if defined(SPI_MASTER_0_ENABLE) || defined(SPI_MASTER_1_ENABLE)
+ spi_master_instance_t * p_spi_instance = spi_master_get_instance(spi_master_hw_instance);
+
+ uint32_t err_code = NRF_SUCCESS;
+ uint16_t max_length = 0;
+
+ if (p_spi_instance->state == SPI_MASTER_STATE_IDLE)
+ {
+ NVIC_DisableIRQ(p_spi_instance->irq_type);
+
+ max_length = (rx_buf_len > tx_buf_len) ? rx_buf_len : tx_buf_len;
+
+ if (max_length > 0)
+ {
+ p_spi_instance->state = SPI_MASTER_STATE_BUSY;
+ p_spi_instance->start_flag = true; //abort_flag should set by abort and cleared only by restart
+ p_spi_instance->bytes_count = 0;
+ p_spi_instance->max_length = max_length;
+ spi_master_buffer_release(&(p_spi_instance->p_tx_buffer), &(p_spi_instance->tx_length));
+ spi_master_buffer_release(&(p_spi_instance->p_rx_buffer), &(p_spi_instance->rx_length));
+ /* Initialize buffers */
+ spi_master_buffer_init(p_tx_buf, tx_buf_len, &(p_spi_instance->p_tx_buffer),
+ &(p_spi_instance->tx_length), &(p_spi_instance->tx_index));
+ spi_master_buffer_init(p_rx_buf, rx_buf_len, &(p_spi_instance->p_rx_buffer),
+ &(p_spi_instance->rx_length), &(p_spi_instance->rx_index));
+ nrf_gpio_pin_clear(p_spi_instance->pin_slave_select);
+ spi_master_send_initial_bytes(p_spi_instance);
+ spi_master_signal_evt(p_spi_instance, SPI_MASTER_EVT_TRANSFER_STARTED, max_length);
+ }
+ else
+ {
+ err_code = NRF_ERROR_INVALID_PARAM;
+ }
+
+ NVIC_EnableIRQ(p_spi_instance->irq_type);
+ }
+ else
+ {
+ err_code = NRF_ERROR_BUSY;
+ }
+
+ return err_code;
+ #else
+ return NRF_ERROR_NOT_SUPPORTED;
+ #endif
+}
+
+#ifdef _SPI_5W_
+
+/**
+ * @brief Function for aborting transfer
+ */
+uint32_t spi_master_abort(const spi_master_hw_instance_t spi_master_hw_instance)
+{
+ spi_master_instance_t * p_spi_instance = spi_master_get_instance(spi_master_hw_instance);
+
+ NVIC_DisableIRQ(p_spi_instance->irq_type);
+
+ if (p_spi_instance->state == SPI_MASTER_STATE_BUSY)
+ {
+ //set_flag - but only when there are events pending
+ //ignore when in IDLE - must be able to restart a completed transfer
+ p_spi_instance->abort_flag = true;
+ }
+ NVIC_EnableIRQ(p_spi_instance->irq_type);
+ return NRF_SUCCESS;
+}
+
+/**
+ * @brief Function for restarting transfer
+ */
+uint32_t spi_master_restart(const spi_master_hw_instance_t spi_master_hw_instance)
+{
+ spi_master_instance_t * p_spi_instance = spi_master_get_instance(spi_master_hw_instance);
+
+ NVIC_DisableIRQ(p_spi_instance->irq_type);
+ spi_master_signal_evt(p_spi_instance, SPI_MASTER_EVT_TRANSFER_RESTARTED, 0);
+ p_spi_instance->state = SPI_MASTER_STATE_BUSY;
+ p_spi_instance->bytes_count = 0;
+ p_spi_instance->tx_index = 0;
+ p_spi_instance->rx_index = 0;
+ p_spi_instance->start_flag = true;
+ p_spi_instance->abort_flag = false; //you should force clearing abort flag - no other way for 1 byte transfer
+ nrf_gpio_pin_clear(p_spi_instance->pin_slave_select);
+ spi_master_send_initial_bytes(p_spi_instance);
+ NVIC_EnableIRQ(p_spi_instance->irq_type);
+
+ return NRF_SUCCESS;
+}
+
+static void spi_5W_master_event_handler(spi_master_evt_t evt)
+{
+
+ switch (m_hook_state)
+ {
+ case HOOK_STATE_IDLE:
+
+ if (evt.type == SPI_MASTER_EVT_TRANSFER_STARTED)
+ {
+ DEBUG_EVT_SPI_MASTER_RAW_XFER_GUARDED(0);
+ m_hook_state = HOOK_STATE_GUARDED;
+ m_ser_phy_event_handler(evt);
+ }
+ break;
+
+ case HOOK_STATE_GUARDED:
+
+ if (evt.type == SPI_MASTER_EVT_FIRST_BYTE_RECEIVED)
+ {
+ if (evt.data == 0)
+ {
+ DEBUG_EVT_SPI_MASTER_RAW_XFER_PASSED(0);
+ m_hook_state = HOOK_STATE_PASSING;
+ }
+ else
+ {
+ DEBUG_EVT_SPI_MASTER_RAW_XFER_ABORTED(0);
+ m_hook_state = HOOK_STATE_ABORTED;
+ (void)spi_master_abort(m_spi_master_hw_instance);
+ }
+ }
+ break;
+
+ case HOOK_STATE_ABORTED:
+
+ if ((evt.type == SPI_MASTER_EVT_TRANSFER_ABORTED) ||
+ (evt.type == SPI_MASTER_EVT_TRANSFER_COMPLETED))
+ {
+ DEBUG_EVT_SPI_MASTER_RAW_XFER_RESTARTED(0);
+ m_hook_state = HOOK_STATE_RESTARTED;
+ (void)spi_master_restart(m_spi_master_hw_instance);
+ }
+ break;
+
+ case HOOK_STATE_RESTARTED:
+
+ if (evt.type == SPI_MASTER_EVT_TRANSFER_RESTARTED)
+ {
+ DEBUG_EVT_SPI_MASTER_RAW_XFER_GUARDED(0);
+ m_hook_state = HOOK_STATE_GUARDED;
+ }
+ break;
+
+ case HOOK_STATE_PASSING:
+
+ if (evt.type == SPI_MASTER_EVT_TRANSFER_COMPLETED)
+ {
+ m_hook_state = HOOK_STATE_IDLE;
+ m_ser_phy_event_handler(evt); //this is the only way to get a signal from complete transaction
+ }
+ break;
+
+ default:
+ break;
+ }
+}
+
+void spi_5W_master_evt_handler_reg(const spi_master_hw_instance_t spi_master_hw_instance,
+ spi_master_event_handler_t event_handler)
+{
+ m_ser_phy_event_handler = event_handler;
+ m_spi_master_hw_instance = spi_master_hw_instance;
+ m_hook_state = HOOK_STATE_IDLE;
+ spi_master_evt_handler_reg(spi_master_hw_instance, spi_5W_master_event_handler);
+ return;
+}
+
+#endif
+
+/** @} */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/drivers_nrf/spi_master/spi_5W_master.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/drivers_nrf/spi_master/spi_5W_master.h
new file mode 100644
index 0000000..a0017c5
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/drivers_nrf/spi_master/spi_5W_master.h
@@ -0,0 +1,206 @@
+/**
+ * Copyright (c) 2014 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#ifndef APP_SPI_MASTER_H
+#define APP_SPI_MASTER_H
+
+#include <stdint.h>
+#include <stdlib.h>
+#include "boards.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define _SPI_5W_
+
+/**@brief Struct containing configuration parameters of the SPI master. */
+typedef struct
+{
+ uint32_t SPI_Freq; /**< SPI frequency. */
+ uint32_t SPI_Pin_SCK; /**< SCK pin number. */
+ uint32_t SPI_Pin_MISO; /**< MISO pin number. */
+ uint32_t SPI_Pin_MOSI; /**< MOSI pin number .*/
+ uint32_t SPI_Pin_SS; /**< Slave select pin number. */
+ uint8_t SPI_ORDER; /**< Bytes order MSBFIRST or LSBFIRST. */
+ uint8_t SPI_CPOL; /**< Serial clock polarity ACTIVEHIGH or ACTIVELOW. */
+ uint8_t SPI_CPHA; /**< Serial clock phase LEADING or TRAILING. */
+ } spi_master_config_t;
+
+/**@brief SPI master driver events types. */
+typedef enum
+{
+ SPI_MASTER_EVT_TRANSFER_STARTED = 0, /**< An event indicating that transfer has been started */
+ SPI_MASTER_EVT_TRANSFER_COMPLETED, /**< An event indicating that transfer has been completed */
+ SPI_MASTER_EVT_TRANSFER_ABORTED, /**< An event indicating that transfer has been aborted */
+ SPI_MASTER_EVT_TRANSFER_RESTARTED, /**< An event indicating that transfer has been resumed */
+ SPI_MASTER_EVT_FIRST_BYTE_RECEIVED, /**< An event indicating end of one byte transfer */
+ SPI_MASTER_EVT_TYPE_MAX /**< Enumeration upper bound. */
+} spi_master_evt_type_t;
+
+/**@brief Struct containing parameters of the SPI MASTER event */
+ typedef struct
+ {
+ spi_master_evt_type_t type; /**< Type of an event */
+ uint16_t data; /**< event data - context dependent */
+ } spi_master_evt_t;
+
+ /**@brief SPI MASTER internal states types. */
+ typedef enum
+ {
+ SPI_MASTER_STATE_DISABLED, /**< A state indicating that SPI master is disabled. */
+ SPI_MASTER_STATE_BUSY, /**< A state indicating that SPI master is sending now. */
+ SPI_MASTER_STATE_ABORTED,
+ SPI_MASTER_STATE_IDLE /**< A state indicating that SPI master is idle now. */
+ } spi_master_state_t;
+
+ /**@brief Instances of SPI master module. */
+ typedef enum
+ {
+ #ifdef SPI_MASTER_0_ENABLE
+ SPI_MASTER_0, /**< A instance of SPI master 0. */
+ #endif
+
+ #ifdef SPI_MASTER_1_ENABLE
+ SPI_MASTER_1, /**< A instance of SPI master 1. */
+ #endif
+
+ SPI_MASTER_HW_ENABLED_COUNT /**< A number of enabled instances of SPI master. */
+ } spi_master_hw_instance_t;
+
+/**@brief Type of generic callback function handler to be used by all SPI MASTER driver events.
+ *
+ * @param[in] spi_master_evt SPI MASTER driver event.
+ */
+typedef void (*spi_master_event_handler_t) (spi_master_evt_t spi_master_evt);
+
+
+/**@brief Function for opening and initializing a SPI master driver.
+ *
+ * @note Function initializes SPI master hardware and internal module states, unregister events callback.
+ *
+ * @warning If the function has been already called, the function @ref spi_master_close has to be
+ * called before spi_master_open can be called again.
+ *
+ * @param[in] spi_master_hw_instance Instance of SPI master module.
+ * @param[in] p_spi_master_config Pointer to configuration structure which will be used
+ * to initialize SPI MASTER hardware.
+ *
+ * @retval NRF_SUCCESS Operation success.
+ * @retval NRF_ERROR_INVALID_STATE Operation failure. The function has been already called.
+ * To call it again the function @ref spi_master_close
+ * has to be called previously.
+ * @retval NRF_ERROR_NULL Operation failure. NULL pointer supplied.
+ */
+uint32_t spi_master_open(const spi_master_hw_instance_t spi_master_hw_instance,
+ spi_master_config_t const * const p_spi_master_config);
+
+
+/**@brief Function for closing a SPI MASTER driver.
+ *
+ * @note Function disable hardware, reset internal module states and unregister events callback
+ * function.
+ *
+ * @param[in] spi_master_hw_instance A instance of SPI master.
+ */
+void spi_master_close(const spi_master_hw_instance_t spi_master_hw_instance);
+
+
+/**@brief Function for transferring data between SPI master and SPI slave
+ *
+ * @note Function registers buffers pointed by p_tx_buf and p_rx_buf parameters, after that starts transmission.
+ * Function generates an event of type @ref SPI_MASTER_EVT_TRANSFER_STARTED when transfer has been started
+ * and @ref SPI_MASTER_EVT_TRANSFER_COMPLETED when transfer has been completed.
+ *
+ * @param[in] spi_master_hw_instance Instance of SPI master module.
+ * @param[in] p_tx_buf Pointer to a transmit buffer.
+ * @param[in] tx_buf_len Number of octets to the transfer.
+ * @param[out] p_rx_buf Pointer to a receive buffer.
+ * @param[in] rx_buf_len Number of octets to be received.
+ *
+ * @retval NRF_SUCCESS Operation success. Packet was registered to the transmission
+ * and event will be send upon transmission completion.
+ * @retval NRF_ERROR_BUSY Operation failure. Transmitting of a data is in progress.
+ */
+ uint32_t spi_master_send_recv(const spi_master_hw_instance_t spi_master_hw_instance,
+ uint8_t * const p_tx_buf, const uint16_t tx_buf_len,
+ uint8_t * const p_rx_buf, const uint16_t rx_buf_len);
+
+
+/**@brief Function for registration event handler.
+*
+* @note Function registers a event handler to be used by SPI MASTER driver for sending events.
+* @ref SPI_MASTER_EVT_TRANSFER_STARTED and @ref SPI_MASTER_EVT_TRANSFER_COMPLETED.
+*
+* @param[in] spi_master_hw_instance Instance of SPI master module.
+* @param[in] event_handler Generic callback function handler to be used
+* by all SPI master driver events.
+*/
+void spi_master_evt_handler_reg(const spi_master_hw_instance_t spi_master_hw_instance,
+ spi_master_event_handler_t event_handler);
+
+
+/**@brief Function for getting current state of the SPI master driver.
+ *
+ * @note Function gets current state of the SPI master driver.
+ *
+ * @param[in] spi_master_hw_instance Instance of SPI master module.
+ *
+ * @retval SPI_MASTER_STATE_DISABLED SPI MASTER is disabled.
+ * @retval SPI_MASTER_STATE_BUSY SPI_MASTER is sending now.
+ * @retval SPI_MASTER_STATE_IDLE SPI_MASTER is idle now.
+ */
+spi_master_state_t spi_master_get_state(const spi_master_hw_instance_t spi_master_hw_instance);
+
+#ifdef _SPI_5W_
+
+uint32_t spi_master_abort(const spi_master_hw_instance_t spi_master_hw_instance);
+
+uint32_t spi_master_restart(const spi_master_hw_instance_t spi_master_hw_instance);
+
+void spi_5W_master_evt_handler_reg(const spi_master_hw_instance_t spi_master_hw_instance,
+ spi_master_event_handler_t event_handler);
+#endif
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/drivers_nrf/twi_master/deprecated/config/twi_master_config.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/drivers_nrf/twi_master/deprecated/config/twi_master_config.h
new file mode 100644
index 0000000..9c182e6
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/drivers_nrf/twi_master/deprecated/config/twi_master_config.h
@@ -0,0 +1,55 @@
+/**
+ * Copyright (c) 2012 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#ifndef TWI_MASTER_CONFIG
+#define TWI_MASTER_CONFIG
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define TWI_MASTER_CONFIG_CLOCK_PIN_NUMBER (24U)
+#define TWI_MASTER_CONFIG_DATA_PIN_NUMBER (25U)
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/drivers_nrf/twi_master/deprecated/twi_hw_master.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/drivers_nrf/twi_master/deprecated/twi_hw_master.c
new file mode 100644
index 0000000..e3692a3
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/drivers_nrf/twi_master/deprecated/twi_hw_master.c
@@ -0,0 +1,331 @@
+/**
+ * Copyright (c) 2009 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#include "twi_master.h"
+#include "twi_master_config.h"
+#include <stdbool.h>
+#include <stdint.h>
+#include "nrf.h"
+#include "nrf_delay.h"
+#include "nrf_gpio.h"
+
+/* Max cycles approximately to wait on RXDREADY and TXDREADY event,
+ * This is optimized way instead of using timers, this is not power aware. */
+#define MAX_TIMEOUT_LOOPS (20000UL) /**< MAX while loops to wait for RXD/TXD event */
+
+static bool twi_master_write(uint8_t * data, uint8_t data_length, bool issue_stop_condition)
+{
+ uint32_t timeout = MAX_TIMEOUT_LOOPS; /* max loops to wait for EVENTS_TXDSENT event*/
+
+ if (data_length == 0)
+ {
+ /* Return false for requesting data of size 0 */
+ return false;
+ }
+
+ NRF_TWI1->TXD = *data++;
+ NRF_TWI1->TASKS_STARTTX = 1;
+
+ /** @snippet [TWI HW master write] */
+ while (true)
+ {
+ while (NRF_TWI1->EVENTS_TXDSENT == 0 && NRF_TWI1->EVENTS_ERROR == 0 && (--timeout))
+ {
+ // Do nothing.
+ }
+
+ if (timeout == 0 || NRF_TWI1->EVENTS_ERROR != 0)
+ {
+ // Recover the peripheral as indicated by PAN 56: "TWI: TWI module lock-up." found at
+ // Product Anomaly Notification document found at
+ // https://www.nordicsemi.com/eng/Products/Bluetooth-R-low-energy/nRF51822/#Downloads
+ NRF_TWI1->EVENTS_ERROR = 0;
+ NRF_TWI1->ENABLE = TWI_ENABLE_ENABLE_Disabled << TWI_ENABLE_ENABLE_Pos;
+ NRF_TWI1->POWER = 0;
+ nrf_delay_us(5);
+ NRF_TWI1->POWER = 1;
+ NRF_TWI1->ENABLE = TWI_ENABLE_ENABLE_Enabled << TWI_ENABLE_ENABLE_Pos;
+
+ (void)twi_master_init();
+
+ return false;
+ }
+ NRF_TWI1->EVENTS_TXDSENT = 0;
+ if (--data_length == 0)
+ {
+ break;
+ }
+
+ NRF_TWI1->TXD = *data++;
+ }
+ /** @snippet [TWI HW master write] */
+
+ if (issue_stop_condition)
+ {
+ NRF_TWI1->EVENTS_STOPPED = 0;
+ NRF_TWI1->TASKS_STOP = 1;
+ /* Wait until stop sequence is sent */
+ while (NRF_TWI1->EVENTS_STOPPED == 0)
+ {
+ // Do nothing.
+ }
+ }
+ return true;
+}
+
+
+/** @brief Function for read by twi_master.
+ */
+static bool twi_master_read(uint8_t * data, uint8_t data_length, bool issue_stop_condition)
+{
+ uint32_t timeout = MAX_TIMEOUT_LOOPS; /* max loops to wait for RXDREADY event*/
+
+ if (data_length == 0)
+ {
+ /* Return false for requesting data of size 0 */
+ return false;
+ }
+ else if (data_length == 1)
+ {
+ NRF_PPI->CH[0].TEP = (uint32_t)&NRF_TWI1->TASKS_STOP;
+ }
+ else
+ {
+ NRF_PPI->CH[0].TEP = (uint32_t)&NRF_TWI1->TASKS_SUSPEND;
+ }
+
+ NRF_PPI->CHENSET = PPI_CHENSET_CH0_Msk;
+ NRF_TWI1->EVENTS_RXDREADY = 0;
+ NRF_TWI1->TASKS_STARTRX = 1;
+
+ /** @snippet [TWI HW master read] */
+ while (true)
+ {
+ while (NRF_TWI1->EVENTS_RXDREADY == 0 && NRF_TWI1->EVENTS_ERROR == 0 && (--timeout))
+ {
+ // Do nothing.
+ }
+ NRF_TWI1->EVENTS_RXDREADY = 0;
+
+ if (timeout == 0 || NRF_TWI1->EVENTS_ERROR != 0)
+ {
+ // Recover the peripheral as indicated by PAN 56: "TWI: TWI module lock-up." found at
+ // Product Anomaly Notification document found at
+ // https://www.nordicsemi.com/eng/Products/Bluetooth-R-low-energy/nRF51822/#Downloads
+ NRF_TWI1->EVENTS_ERROR = 0;
+ NRF_TWI1->ENABLE = TWI_ENABLE_ENABLE_Disabled << TWI_ENABLE_ENABLE_Pos;
+ NRF_TWI1->POWER = 0;
+ nrf_delay_us(5);
+ NRF_TWI1->POWER = 1;
+ NRF_TWI1->ENABLE = TWI_ENABLE_ENABLE_Enabled << TWI_ENABLE_ENABLE_Pos;
+
+ (void)twi_master_init();
+
+ return false;
+ }
+
+ *data++ = NRF_TWI1->RXD;
+
+ /* Configure PPI to stop TWI master before we get last BB event */
+ if (--data_length == 1)
+ {
+ NRF_PPI->CH[0].TEP = (uint32_t)&NRF_TWI1->TASKS_STOP;
+ }
+
+ if (data_length == 0)
+ {
+ break;
+ }
+
+ // Recover the peripheral as indicated by PAN 56: "TWI: TWI module lock-up." found at
+ // Product Anomaly Notification document found at
+ // https://www.nordicsemi.com/eng/Products/Bluetooth-R-low-energy/nRF51822/#Downloads
+ nrf_delay_us(20);
+ NRF_TWI1->TASKS_RESUME = 1;
+ }
+ /** @snippet [TWI HW master read] */
+
+ /* Wait until stop sequence is sent */
+ while (NRF_TWI1->EVENTS_STOPPED == 0)
+ {
+ // Do nothing.
+ }
+ NRF_TWI1->EVENTS_STOPPED = 0;
+
+ NRF_PPI->CHENCLR = PPI_CHENCLR_CH0_Msk;
+ return true;
+}
+
+
+/**
+ * @brief Function for detecting stuck slaves (SDA = 0 and SCL = 1) and tries to clear the bus.
+ *
+ * @return
+ * @retval false Bus is stuck.
+ * @retval true Bus is clear.
+ */
+static bool twi_master_clear_bus(void)
+{
+ uint32_t twi_state;
+ bool bus_clear;
+ uint32_t clk_pin_config;
+ uint32_t data_pin_config;
+
+ // Save and disable TWI hardware so software can take control over the pins.
+ twi_state = NRF_TWI1->ENABLE;
+ NRF_TWI1->ENABLE = TWI_ENABLE_ENABLE_Disabled << TWI_ENABLE_ENABLE_Pos;
+
+ clk_pin_config = \
+ NRF_GPIO->PIN_CNF[TWI_MASTER_CONFIG_CLOCK_PIN_NUMBER];
+ NRF_GPIO->PIN_CNF[TWI_MASTER_CONFIG_CLOCK_PIN_NUMBER] = \
+ (GPIO_PIN_CNF_SENSE_Disabled << GPIO_PIN_CNF_SENSE_Pos) \
+ | (GPIO_PIN_CNF_DRIVE_S0D1 << GPIO_PIN_CNF_DRIVE_Pos) \
+ | (GPIO_PIN_CNF_PULL_Pullup << GPIO_PIN_CNF_PULL_Pos) \
+ | (GPIO_PIN_CNF_INPUT_Connect << GPIO_PIN_CNF_INPUT_Pos) \
+ | (GPIO_PIN_CNF_DIR_Output << GPIO_PIN_CNF_DIR_Pos);
+
+ data_pin_config = \
+ NRF_GPIO->PIN_CNF[TWI_MASTER_CONFIG_DATA_PIN_NUMBER];
+ NRF_GPIO->PIN_CNF[TWI_MASTER_CONFIG_DATA_PIN_NUMBER] = \
+ (GPIO_PIN_CNF_SENSE_Disabled << GPIO_PIN_CNF_SENSE_Pos) \
+ | (GPIO_PIN_CNF_DRIVE_S0D1 << GPIO_PIN_CNF_DRIVE_Pos) \
+ | (GPIO_PIN_CNF_PULL_Pullup << GPIO_PIN_CNF_PULL_Pos) \
+ | (GPIO_PIN_CNF_INPUT_Connect << GPIO_PIN_CNF_INPUT_Pos) \
+ | (GPIO_PIN_CNF_DIR_Output << GPIO_PIN_CNF_DIR_Pos);
+
+ TWI_SDA_HIGH();
+ TWI_SCL_HIGH();
+ TWI_DELAY();
+
+ if ((TWI_SDA_READ() == 1) && (TWI_SCL_READ() == 1))
+ {
+ bus_clear = true;
+ }
+ else
+ {
+ uint_fast8_t i;
+ bus_clear = false;
+
+ // Clock max 18 pulses worst case scenario(9 for master to send the rest of command and 9
+ // for slave to respond) to SCL line and wait for SDA come high.
+ for (i=18; i--;)
+ {
+ TWI_SCL_LOW();
+ TWI_DELAY();
+ TWI_SCL_HIGH();
+ TWI_DELAY();
+
+ if (TWI_SDA_READ() == 1)
+ {
+ bus_clear = true;
+ break;
+ }
+ }
+ }
+
+ NRF_GPIO->PIN_CNF[TWI_MASTER_CONFIG_CLOCK_PIN_NUMBER] = clk_pin_config;
+ NRF_GPIO->PIN_CNF[TWI_MASTER_CONFIG_DATA_PIN_NUMBER] = data_pin_config;
+
+ NRF_TWI1->ENABLE = twi_state;
+
+ return bus_clear;
+}
+
+
+/** @brief Function for initializing the twi_master.
+ */
+bool twi_master_init(void)
+{
+ /* To secure correct signal levels on the pins used by the TWI
+ master when the system is in OFF mode, and when the TWI master is
+ disabled, these pins must be configured in the GPIO peripheral.
+ */
+ NRF_GPIO->PIN_CNF[TWI_MASTER_CONFIG_CLOCK_PIN_NUMBER] = \
+ (GPIO_PIN_CNF_SENSE_Disabled << GPIO_PIN_CNF_SENSE_Pos) \
+ | (GPIO_PIN_CNF_DRIVE_S0D1 << GPIO_PIN_CNF_DRIVE_Pos) \
+ | (GPIO_PIN_CNF_PULL_Pullup << GPIO_PIN_CNF_PULL_Pos) \
+ | (GPIO_PIN_CNF_INPUT_Connect << GPIO_PIN_CNF_INPUT_Pos) \
+ | (GPIO_PIN_CNF_DIR_Input << GPIO_PIN_CNF_DIR_Pos);
+
+ NRF_GPIO->PIN_CNF[TWI_MASTER_CONFIG_DATA_PIN_NUMBER] = \
+ (GPIO_PIN_CNF_SENSE_Disabled << GPIO_PIN_CNF_SENSE_Pos) \
+ | (GPIO_PIN_CNF_DRIVE_S0D1 << GPIO_PIN_CNF_DRIVE_Pos) \
+ | (GPIO_PIN_CNF_PULL_Pullup << GPIO_PIN_CNF_PULL_Pos) \
+ | (GPIO_PIN_CNF_INPUT_Connect << GPIO_PIN_CNF_INPUT_Pos) \
+ | (GPIO_PIN_CNF_DIR_Input << GPIO_PIN_CNF_DIR_Pos);
+
+ NRF_TWI1->EVENTS_RXDREADY = 0;
+ NRF_TWI1->EVENTS_TXDSENT = 0;
+ NRF_TWI1->PSELSCL = TWI_MASTER_CONFIG_CLOCK_PIN_NUMBER;
+ NRF_TWI1->PSELSDA = TWI_MASTER_CONFIG_DATA_PIN_NUMBER;
+ NRF_TWI1->FREQUENCY = TWI_FREQUENCY_FREQUENCY_K100 << TWI_FREQUENCY_FREQUENCY_Pos;
+ NRF_PPI->CH[0].EEP = (uint32_t)&NRF_TWI1->EVENTS_BB;
+ NRF_PPI->CH[0].TEP = (uint32_t)&NRF_TWI1->TASKS_SUSPEND;
+ NRF_PPI->CHENCLR = PPI_CHENCLR_CH0_Msk;
+ NRF_TWI1->ENABLE = TWI_ENABLE_ENABLE_Enabled << TWI_ENABLE_ENABLE_Pos;
+
+ return twi_master_clear_bus();
+}
+
+
+/** @brief Function for transfer by twi_master.
+ */
+bool twi_master_transfer(uint8_t address,
+ uint8_t * data,
+ uint8_t data_length,
+ bool issue_stop_condition)
+{
+ bool transfer_succeeded = false;
+ if (data_length > 0 && twi_master_clear_bus())
+ {
+ NRF_TWI1->ADDRESS = (address >> 1);
+
+ if ((address & TWI_READ_BIT))
+ {
+ transfer_succeeded = twi_master_read(data, data_length, issue_stop_condition);
+ }
+ else
+ {
+ transfer_succeeded = twi_master_write(data, data_length, issue_stop_condition);
+ }
+ }
+ return transfer_succeeded;
+}
+
+/*lint --flb "Leave library region" */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/drivers_nrf/twi_master/deprecated/twi_master.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/drivers_nrf/twi_master/deprecated/twi_master.h
new file mode 100644
index 0000000..3cd975e
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/drivers_nrf/twi_master/deprecated/twi_master.h
@@ -0,0 +1,137 @@
+/**
+ * Copyright (c) 2009 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#ifndef TWI_MASTER_H
+#define TWI_MASTER_H
+
+/*lint ++flb "Enter library region" */
+
+#include <stdbool.h>
+#include <stdint.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** @file
+* @brief Software controlled TWI Master driver.
+*
+*
+* @defgroup lib_driver_twi_master Software controlled TWI Master driver
+* @{
+* @ingroup nrf_twi
+* @brief Software controlled TWI Master driver (deprecated).
+*
+* @warning This module is deprecated.
+*
+* Supported features:
+* - Repeated start
+* - No multi-master
+* - Only 7-bit addressing
+* - Supports clock stretching (with optional SMBus style slave timeout)
+* - Tries to handle slaves stuck in the middle of transfer
+*/
+
+#define TWI_READ_BIT (0x01) //!< If this bit is set in the address field, transfer direction is from slave to master.
+
+#define TWI_ISSUE_STOP ((bool)true) //!< Parameter for @ref twi_master_transfer
+#define TWI_DONT_ISSUE_STOP ((bool)false) //!< Parameter for @ref twi_master_transfer
+
+/* These macros are needed to see if the slave is stuck and we as master send dummy clock cycles to end its wait */
+/*lint -e717 -save "Suppress do {} while (0) for these macros" */
+/*lint ++flb "Enter library region" */
+#define TWI_SCL_HIGH() do { NRF_GPIO->OUTSET = (1UL << TWI_MASTER_CONFIG_CLOCK_PIN_NUMBER); } while (0) /*!< Pulls SCL line high */
+#define TWI_SCL_LOW() do { NRF_GPIO->OUTCLR = (1UL << TWI_MASTER_CONFIG_CLOCK_PIN_NUMBER); } while (0) /*!< Pulls SCL line low */
+#define TWI_SDA_HIGH() do { NRF_GPIO->OUTSET = (1UL << TWI_MASTER_CONFIG_DATA_PIN_NUMBER); } while (0) /*!< Pulls SDA line high */
+#define TWI_SDA_LOW() do { NRF_GPIO->OUTCLR = (1UL << TWI_MASTER_CONFIG_DATA_PIN_NUMBER); } while (0) /*!< Pulls SDA line low */
+#define TWI_SDA_INPUT() do { NRF_GPIO->DIRCLR = (1UL << TWI_MASTER_CONFIG_DATA_PIN_NUMBER); } while (0) /*!< Configures SDA pin as input */
+#define TWI_SDA_OUTPUT() do { NRF_GPIO->DIRSET = (1UL << TWI_MASTER_CONFIG_DATA_PIN_NUMBER); } while (0) /*!< Configures SDA pin as output */
+#define TWI_SCL_OUTPUT() do { NRF_GPIO->DIRSET = (1UL << TWI_MASTER_CONFIG_CLOCK_PIN_NUMBER); } while (0) /*!< Configures SCL pin as output */
+/*lint -restore */
+
+#define TWI_SDA_READ() ((NRF_GPIO->IN >> TWI_MASTER_CONFIG_DATA_PIN_NUMBER) & 0x1UL) /*!< Reads current state of SDA */
+#define TWI_SCL_READ() ((NRF_GPIO->IN >> TWI_MASTER_CONFIG_CLOCK_PIN_NUMBER) & 0x1UL) /*!< Reads current state of SCL */
+
+#define TWI_DELAY() nrf_delay_us(4) /*!< Time to wait when pin states are changed. For fast-mode the delay can be zero and for standard-mode 4 us delay is sufficient. */
+
+
+/**
+ * @brief Function for initializing TWI bus IO pins and checks if the bus is operational.
+ *
+ * Both pins are configured as Standard-0, No-drive-1 (open drain).
+ *
+ * @return
+ * @retval true TWI bus is clear for transfers.
+ * @retval false TWI bus is stuck.
+ */
+bool twi_master_init(void);
+
+/**
+ * @brief Function for transferring data over TWI bus.
+ *
+ * If TWI master detects even one NACK from the slave or timeout occurs, STOP condition is issued
+ * and the function returns false.
+ * Bit 0 (@ref TWI_READ_BIT) in the address parameter controls transfer direction;
+ * - If 1, master reads data_length number of bytes from the slave
+ * - If 0, master writes data_length number of bytes to the slave.
+ *
+ * @note Make sure at least data_length number of bytes is allocated in data if TWI_READ_BIT is set.
+ * @note @ref TWI_ISSUE_STOP
+ *
+ * @param address Data transfer direction (LSB) / Slave address (7 MSBs).
+ * @param data Pointer to data.
+ * @param data_length Number of bytes to transfer.
+ * @param issue_stop_condition If @ref TWI_ISSUE_STOP, STOP condition is issued before exiting function. If @ref TWI_DONT_ISSUE_STOP, STOP condition is not issued before exiting function. If transfer failed for any reason, STOP condition will be issued in any case.
+ * @return
+ * @retval true Data transfer succeeded without errors.
+ * @retval false Data transfer failed.
+ */
+bool twi_master_transfer(uint8_t address, uint8_t *data, uint8_t data_length, bool issue_stop_condition);
+
+/**
+ *@}
+ **/
+
+/*lint --flb "Leave library region" */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif //TWI_MASTER_H
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/drivers_nrf/twi_master/deprecated/twi_sw_master.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/drivers_nrf/twi_master/deprecated/twi_sw_master.c
new file mode 100644
index 0000000..115e997
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/drivers_nrf/twi_master/deprecated/twi_sw_master.c
@@ -0,0 +1,519 @@
+/**
+ * Copyright (c) 2009 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#include <stdbool.h>
+#include <stdint.h>
+#include "twi_master.h"
+#include "nrf_delay.h"
+
+#include "twi_master_config.h"
+
+/*lint -e415 -e845 -save "Out of bounds access" */
+#define TWI_SDA_STANDARD0_NODRIVE1() do { \
+ NRF_GPIO->PIN_CNF[TWI_MASTER_CONFIG_DATA_PIN_NUMBER] = (GPIO_PIN_CNF_SENSE_Disabled << GPIO_PIN_CNF_SENSE_Pos) \
+ |(GPIO_PIN_CNF_DRIVE_S0D1 << GPIO_PIN_CNF_DRIVE_Pos) \
+ |(GPIO_PIN_CNF_PULL_Pullup << GPIO_PIN_CNF_PULL_Pos) \
+ |(GPIO_PIN_CNF_INPUT_Connect << GPIO_PIN_CNF_INPUT_Pos) \
+ |(GPIO_PIN_CNF_DIR_Input << GPIO_PIN_CNF_DIR_Pos); \
+} while (0) /*!< Configures SDA pin to Standard-0, No-drive 1 */
+
+
+#define TWI_SCL_STANDARD0_NODRIVE1() do { \
+ NRF_GPIO->PIN_CNF[TWI_MASTER_CONFIG_CLOCK_PIN_NUMBER] = (GPIO_PIN_CNF_SENSE_Disabled << GPIO_PIN_CNF_SENSE_Pos) \
+ |(GPIO_PIN_CNF_DRIVE_S0D1 << GPIO_PIN_CNF_DRIVE_Pos) \
+ |(GPIO_PIN_CNF_PULL_Pullup << GPIO_PIN_CNF_PULL_Pos) \
+ |(GPIO_PIN_CNF_INPUT_Connect << GPIO_PIN_CNF_INPUT_Pos) \
+ |(GPIO_PIN_CNF_DIR_Input << GPIO_PIN_CNF_DIR_Pos); \
+} while (0) /*!< Configures SCL pin to Standard-0, No-drive 1 */
+
+
+/*lint -restore */
+
+#ifndef TWI_MASTER_TIMEOUT_COUNTER_LOAD_VALUE
+#define TWI_MASTER_TIMEOUT_COUNTER_LOAD_VALUE (0UL) //!< Unit is number of empty loops. Timeout for SMBus devices is 35 ms. Set to zero to disable slave timeout altogether.
+#endif
+
+static bool twi_master_clear_bus(void);
+static bool twi_master_issue_startcondition(void);
+static bool twi_master_issue_stopcondition(void);
+static bool twi_master_clock_byte(uint_fast8_t databyte);
+static bool twi_master_clock_byte_in(uint8_t * databyte, bool ack);
+static bool twi_master_wait_while_scl_low(void);
+
+bool twi_master_init(void)
+{
+ // Configure both pins to output Standard 0, No-drive (open-drain) 1
+ TWI_SDA_STANDARD0_NODRIVE1(); /*lint !e416 "Creation of out of bounds pointer" */
+ TWI_SCL_STANDARD0_NODRIVE1(); /*lint !e416 "Creation of out of bounds pointer" */
+
+ // Configure SCL as output
+ TWI_SCL_HIGH();
+ TWI_SCL_OUTPUT();
+
+ // Configure SDA as output
+ TWI_SDA_HIGH();
+ TWI_SDA_OUTPUT();
+
+ return twi_master_clear_bus();
+}
+
+bool twi_master_transfer(uint8_t address, uint8_t * data, uint8_t data_length, bool issue_stop_condition)
+{
+ bool transfer_succeeded = true;
+
+ transfer_succeeded &= twi_master_issue_startcondition();
+ transfer_succeeded &= twi_master_clock_byte(address);
+
+ if (address & TWI_READ_BIT)
+ {
+ /* Transfer direction is from Slave to Master */
+ while (data_length-- && transfer_succeeded)
+ {
+ // To indicate to slave that we've finished transferring last data byte
+ // we need to NACK the last transfer.
+ if (data_length == 0)
+ {
+ transfer_succeeded &= twi_master_clock_byte_in(data, (bool)false);
+ }
+ else
+ {
+ transfer_succeeded &= twi_master_clock_byte_in(data, (bool)true);
+ }
+ data++;
+ }
+ }
+ else
+ {
+ /* Transfer direction is from Master to Slave */
+ while (data_length-- && transfer_succeeded)
+ {
+ transfer_succeeded &= twi_master_clock_byte(*data);
+ data++;
+ }
+ }
+
+ if (issue_stop_condition || !transfer_succeeded)
+ {
+ transfer_succeeded &= twi_master_issue_stopcondition();
+ }
+
+ return transfer_succeeded;
+}
+
+/**
+ * @brief Function for detecting stuck slaves and tries to clear the bus.
+ *
+ * @return
+ * @retval false Bus is stuck.
+ * @retval true Bus is clear.
+ */
+static bool twi_master_clear_bus(void)
+{
+ bool bus_clear;
+
+ TWI_SDA_HIGH();
+ TWI_SCL_HIGH();
+ TWI_DELAY();
+
+
+ if (TWI_SDA_READ() == 1 && TWI_SCL_READ() == 1)
+ {
+ bus_clear = true;
+ }
+ else if (TWI_SCL_READ() == 1)
+ {
+ bus_clear = false;
+ // Clock max 18 pulses worst case scenario(9 for master to send the rest of command and 9 for slave to respond) to SCL line and wait for SDA come high
+ for (uint_fast8_t i = 18; i--;)
+ {
+ TWI_SCL_LOW();
+ TWI_DELAY();
+ TWI_SCL_HIGH();
+ TWI_DELAY();
+
+ if (TWI_SDA_READ() == 1)
+ {
+ bus_clear = true;
+ break;
+ }
+ }
+ }
+ else
+ {
+ bus_clear = false;
+ }
+
+ return bus_clear;
+}
+
+/**
+ * @brief Function for issuing TWI START condition to the bus.
+ *
+ * START condition is signaled by pulling SDA low while SCL is high. After this function SCL and SDA will be low.
+ *
+ * @return
+ * @retval false Timeout detected
+ * @retval true Clocking succeeded
+ */
+static bool twi_master_issue_startcondition(void)
+{
+#if 0
+ if (TWI_SCL_READ() == 1 && TWI_SDA_READ() == 1)
+ {
+ // Pull SDA low
+ TWI_SDA_LOW();
+ }
+ else if (TWI_SCL_READ() == 1 && TWI_SDA_READ() == 0)
+ {
+ // Issue Stop by pulling SDA high
+ TWI_SDA_HIGH();
+ TWI_DELAY();
+
+ // Then Start by pulling SDA low
+ TWI_SDA_LOW();
+ }
+ else if (TWI_SCL_READ() == 0 && TWI_SDA_READ() == 0)
+ {
+ // First pull SDA high
+ TWI_SDA_HIGH();
+
+ // Then SCL high
+ if (!twi_master_wait_while_scl_low())
+ {
+ return false;
+ }
+
+ // Then SDA low
+ TWI_SDA_LOW();
+ }
+ else if (TWI_SCL_READ() == 0 && TWI_SDA_READ() == 1)
+ {
+ // SCL high
+ if (!twi_master_wait_while_scl_low())
+ {
+ return false;
+ }
+
+ // Then SDA low
+ TWI_SDA_LOW();
+ }
+
+ TWI_DELAY();
+ TWI_SCL_LOW();
+#endif
+
+ // Make sure both SDA and SCL are high before pulling SDA low.
+ TWI_SDA_HIGH();
+ TWI_DELAY();
+ if (!twi_master_wait_while_scl_low())
+ {
+ return false;
+ }
+
+ TWI_SDA_LOW();
+ TWI_DELAY();
+
+ // Other module function expect SCL to be low
+ TWI_SCL_LOW();
+ TWI_DELAY();
+
+ return true;
+}
+
+/**
+ * @brief Function for issuing TWI STOP condition to the bus.
+ *
+ * STOP condition is signaled by pulling SDA high while SCL is high. After this function SDA and SCL will be high.
+ *
+ * @return
+ * @retval false Timeout detected
+ * @retval true Clocking succeeded
+ */
+static bool twi_master_issue_stopcondition(void)
+{
+#if 0
+ if (TWI_SCL_READ() == 1 && TWI_SDA_READ() == 1)
+ {
+ // Issue start, then issue stop
+
+ // Pull SDA low to issue START
+ TWI_SDA_LOW();
+ TWI_DELAY();
+
+ // Pull SDA high while SCL is high to issue STOP
+ TWI_SDA_HIGH();
+ }
+ else if (TWI_SCL_READ() == 1 && TWI_SDA_READ() == 0)
+ {
+ // Pull SDA high while SCL is high to issue STOP
+ TWI_SDA_HIGH();
+ }
+ else if (TWI_SCL_READ() == 0 && TWI_SDA_READ() == 0)
+ {
+ if (!twi_master_wait_while_scl_low())
+ {
+ return false;
+ }
+
+ // Pull SDA high while SCL is high to issue STOP
+ TWI_SDA_HIGH();
+ }
+ else if (TWI_SCL_READ() == 0 && TWI_SDA_READ() == 1)
+ {
+ TWI_SDA_LOW();
+ TWI_DELAY();
+
+ // SCL high
+ if (!twi_master_wait_while_scl_low())
+ {
+ return false;
+ }
+
+ // Pull SDA high while SCL is high to issue STOP
+ TWI_SDA_HIGH();
+ }
+
+ TWI_DELAY();
+#endif
+
+ TWI_SDA_LOW();
+ TWI_DELAY();
+ if (!twi_master_wait_while_scl_low())
+ {
+ return false;
+ }
+
+ TWI_SDA_HIGH();
+ TWI_DELAY();
+
+ return true;
+}
+
+/**
+ * @brief Function for clocking one data byte out and reads slave acknowledgment.
+ *
+ * Can handle clock stretching.
+ * After calling this function SCL is low and SDA low/high depending on the
+ * value of LSB of the data byte.
+ * SCL is expected to be output and low when entering this function.
+ *
+ * @param databyte Data byte to clock out.
+ * @return
+ * @retval true Slave acknowledged byte.
+ * @retval false Timeout or slave didn't acknowledge byte.
+ */
+static bool twi_master_clock_byte(uint_fast8_t databyte)
+{
+ bool transfer_succeeded = true;
+
+ /** @snippet [TWI SW master write] */
+ // Make sure SDA is an output
+ TWI_SDA_OUTPUT();
+
+ // MSB first
+ for (uint_fast8_t i = 0x80; i != 0; i >>= 1)
+ {
+ TWI_SCL_LOW();
+ TWI_DELAY();
+
+ if (databyte & i)
+ {
+ TWI_SDA_HIGH();
+ }
+ else
+ {
+ TWI_SDA_LOW();
+ }
+
+ if (!twi_master_wait_while_scl_low())
+ {
+ transfer_succeeded = false; // Timeout
+ break;
+ }
+ }
+
+ // Finish last data bit by pulling SCL low
+ TWI_SCL_LOW();
+ TWI_DELAY();
+
+ /** @snippet [TWI SW master write] */
+
+ // Configure TWI_SDA pin as input for receiving the ACK bit
+ TWI_SDA_INPUT();
+
+ // Give some time for the slave to load the ACK bit on the line
+ TWI_DELAY();
+
+ // Pull SCL high and wait a moment for SDA line to settle
+ // Make sure slave is not stretching the clock
+ transfer_succeeded &= twi_master_wait_while_scl_low();
+
+ // Read ACK/NACK. NACK == 1, ACK == 0
+ transfer_succeeded &= !(TWI_SDA_READ());
+
+ // Finish ACK/NACK bit clock cycle and give slave a moment to release control
+ // of the SDA line
+ TWI_SCL_LOW();
+ TWI_DELAY();
+
+ // Configure TWI_SDA pin as output as other module functions expect that
+ TWI_SDA_OUTPUT();
+
+ return transfer_succeeded;
+}
+
+
+/**
+ * @brief Function for clocking one data byte in and sends ACK/NACK bit.
+ *
+ * Can handle clock stretching.
+ * SCL is expected to be output and low when entering this function.
+ * After calling this function, SCL is high and SDA low/high depending if ACK/NACK was sent.
+ *
+ * @param databyte Data byte to clock out.
+ * @param ack If true, send ACK. Otherwise send NACK.
+ * @return
+ * @retval true Byte read succesfully
+ * @retval false Timeout detected
+ */
+static bool twi_master_clock_byte_in(uint8_t *databyte, bool ack)
+{
+ uint_fast8_t byte_read = 0;
+ bool transfer_succeeded = true;
+
+ /** @snippet [TWI SW master read] */
+ // Make sure SDA is an input
+ TWI_SDA_INPUT();
+
+ // SCL state is guaranteed to be high here
+
+ // MSB first
+ for (uint_fast8_t i = 0x80; i != 0; i >>= 1)
+ {
+ if (!twi_master_wait_while_scl_low())
+ {
+ transfer_succeeded = false;
+ break;
+ }
+
+ if (TWI_SDA_READ())
+ {
+ byte_read |= i;
+ }
+ else
+ {
+ // No need to do anything
+ }
+
+ TWI_SCL_LOW();
+ TWI_DELAY();
+ }
+
+ // Make sure SDA is an output before we exit the function
+ TWI_SDA_OUTPUT();
+ /** @snippet [TWI SW master read] */
+
+ *databyte = (uint8_t)byte_read;
+
+ // Send ACK bit
+
+ // SDA high == NACK, SDA low == ACK
+ if (ack)
+ {
+ TWI_SDA_LOW();
+ }
+ else
+ {
+ TWI_SDA_HIGH();
+ }
+
+ // Let SDA line settle for a moment
+ TWI_DELAY();
+
+ // Drive SCL high to start ACK/NACK bit transfer
+ // Wait until SCL is high, or timeout occurs
+ if (!twi_master_wait_while_scl_low())
+ {
+ transfer_succeeded = false; // Timeout
+ }
+
+ // Finish ACK/NACK bit clock cycle and give slave a moment to react
+ TWI_SCL_LOW();
+ TWI_DELAY();
+
+ return transfer_succeeded;
+}
+
+
+/**
+ * @brief Function for pulling SCL high and waits until it is high or timeout occurs.
+ *
+ * SCL is expected to be output before entering this function.
+ * @note If TWI_MASTER_TIMEOUT_COUNTER_LOAD_VALUE is set to zero, timeout functionality is not compiled in.
+ * @return
+ * @retval true SCL is now high.
+ * @retval false Timeout occurred and SCL is still low.
+ */
+static bool twi_master_wait_while_scl_low(void)
+{
+#if TWI_MASTER_TIMEOUT_COUNTER_LOAD_VALUE != 0
+ uint32_t volatile timeout_counter = TWI_MASTER_TIMEOUT_COUNTER_LOAD_VALUE;
+#endif
+
+ // Pull SCL high just in case if something left it low
+ TWI_SCL_HIGH();
+ TWI_DELAY();
+
+ while (TWI_SCL_READ() == 0)
+ {
+ // If SCL is low, one of the slaves is busy and we must wait
+
+#if TWI_MASTER_TIMEOUT_COUNTER_LOAD_VALUE != 0
+ if (timeout_counter-- == 0)
+ {
+ // If timeout_detected, return false
+ return false;
+ }
+#endif
+ }
+
+ return true;
+}
+
+/*lint --flb "Leave library region" */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/drivers_nrf/usbd/nrf_drv_usbd.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/drivers_nrf/usbd/nrf_drv_usbd.c
new file mode 100644
index 0000000..1432d9f
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/drivers_nrf/usbd/nrf_drv_usbd.c
@@ -0,0 +1,2333 @@
+/**
+ * Copyright (c) 2016 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#include "sdk_common.h"
+#if NRF_MODULE_ENABLED(USBD)
+
+#include "nrf_drv_usbd.h"
+#include "nrf.h"
+#include "nrf_atomic.h"
+#include "app_util_platform.h"
+#include "nrf_delay.h"
+
+#include <stdbool.h>
+#include <string.h>
+#include <inttypes.h>
+
+#define NRF_LOG_MODULE_NAME USBD
+
+#if USBD_CONFIG_LOG_ENABLED
+#define NRF_LOG_LEVEL USBD_CONFIG_LOG_LEVEL
+#define NRF_LOG_INFO_COLOR USBD_CONFIG_INFO_COLOR
+#define NRF_LOG_DEBUG_COLOR USBD_CONFIG_DEBUG_COLOR
+#else //USBD_CONFIG_LOG_ENABLED
+#define NRF_LOG_LEVEL 0
+#endif //USBD_CONFIG_LOG_ENABLED
+#include "nrf_log.h"
+NRF_LOG_MODULE_REGISTER();
+
+#ifndef NRF_DRV_USBD_EARLY_DMA_PROCESS
+/* Try to process DMA request when endpoint transmission has been detected
+ * and just after last EasyDMA has been processed.
+ * It speeds up the transmission a little (about 10% measured)
+ * with a cost of more CPU power used.
+ */
+#define NRF_DRV_USBD_EARLY_DMA_PROCESS 1
+#endif
+
+#ifndef NRF_DRV_USBD_PROTO1_FIX_DEBUG
+/* Debug information when events are fixed*/
+#define NRF_DRV_USBD_PROTO1_FIX_DEBUG 1
+#endif
+
+#define NRF_DRV_USBD_LOG_PROTO1_FIX_PRINTF(...) \
+ do{ \
+ if (NRF_DRV_USBD_PROTO1_FIX_DEBUG){ NRF_LOG_DEBUG(__VA_ARGS__); }\
+ } while (0)
+
+#ifndef NRF_DRV_USBD_STARTED_EV_ENABLE
+#define NRF_DRV_USBD_STARTED_EV_ENABLE 0
+#endif
+
+#ifndef NRF_USBD_ISO_DEBUG
+/* Also generate information about ISOCHRONOUS events and transfers.
+ * Turn this off if no ISOCHRONOUS transfers are going to be debugged and this
+ * option generates a lot of useless messages. */
+#define NRF_USBD_ISO_DEBUG 1
+#endif
+
+#ifndef NRF_USBD_FAILED_TRANSFERS_DEBUG
+/* Also generate debug information for failed transfers.
+ * It might be useful but may generate a lot of useless debug messages
+ * in some library usages (for example when transfer is generated and the
+ * result is used to check whatever endpoint was busy. */
+#define NRF_USBD_FAILED_TRANSFERS_DEBUG 1
+#endif
+
+#ifndef NRF_USBD_DMAREQ_PROCESS_DEBUG
+/* Generate additional messages that mark the status inside
+ * @ref usbd_dmareq_process.
+ * It is useful to debug library internals but may generate a lot of
+ * useless debug messages. */
+#define NRF_USBD_DMAREQ_PROCESS_DEBUG 1
+#endif
+
+
+/**
+ * @defgroup nrf_drv_usbd_int USB Device driver internal part
+ * @internal
+ * @ingroup nrf_drv_usbd
+ *
+ * This part contains auxiliary internal macros, variables and functions.
+ * @{
+ */
+
+/**
+ * @brief Assert endpoint number validity
+ *
+ * Internal macro to be used during program creation in debug mode.
+ * Generates assertion if endpoint number is not valid.
+ *
+ * @param ep Endpoint number to validity check
+ */
+#define USBD_ASSERT_EP_VALID(ep) ASSERT( \
+ ((NRF_USBD_EPIN_CHECK(ep) && (NRF_USBD_EP_NR_GET(ep) < NRF_USBD_EPIN_CNT )) \
+ || \
+ (NRF_USBD_EPOUT_CHECK(ep) && (NRF_USBD_EP_NR_GET(ep) < NRF_USBD_EPOUT_CNT))) \
+);
+
+/**
+ * @brief Lowest position of bit for IN endpoint
+ *
+ * The first bit position corresponding to IN endpoint.
+ * @sa ep2bit bit2ep
+ */
+#define USBD_EPIN_BITPOS_0 0
+
+/**
+ * @brief Lowest position of bit for OUT endpoint
+ *
+ * The first bit position corresponding to OUT endpoint
+ * @sa ep2bit bit2ep
+ */
+#define USBD_EPOUT_BITPOS_0 16
+
+/**
+ * @brief Input endpoint bits mask
+ */
+#define USBD_EPIN_BIT_MASK (0xFFFFU << USBD_EPIN_BITPOS_0)
+
+/**
+ * @brief Output endpoint bits mask
+ */
+#define USBD_EPOUT_BIT_MASK (0xFFFFU << USBD_EPOUT_BITPOS_0)
+
+/**
+ * @brief Auxiliary macro to change EP number into bit position
+ *
+ * This macro is used by @ref ep2bit function but also for statically check
+ * the bitpos values integrity during compilation.
+ *
+ * @param[in] ep Endpoint number.
+ * @return Endpoint bit position.
+ */
+#define USBD_EP_BITPOS(ep) \
+ ((NRF_USBD_EPIN_CHECK(ep) ? USBD_EPIN_BITPOS_0 : USBD_EPOUT_BITPOS_0) + NRF_USBD_EP_NR_GET(ep))
+
+/**
+ * @brief Helper macro for creating an endpoint transfer event.
+ *
+ * @param[in] name Name of the created transfer event variable.
+ * @param[in] endpoint Endpoint number.
+ * @param[in] ep_stat Endpoint state to report.
+ *
+ * @return Initialized event constant variable.
+ */
+#define NRF_DRV_USBD_EP_TRANSFER_EVENT(name, endpont, ep_stat) \
+ const nrf_drv_usbd_evt_t name = { \
+ NRF_DRV_USBD_EVT_EPTRANSFER, \
+ .data = { \
+ .eptransfer = { \
+ .ep = endpont, \
+ .status = ep_stat \
+ } \
+ } \
+ }
+
+/* Check it the bit positions values match defined DATAEPSTATUS bit positions */
+STATIC_ASSERT(USBD_EP_BITPOS(NRF_DRV_USBD_EPIN1) == USBD_EPDATASTATUS_EPIN1_Pos );
+STATIC_ASSERT(USBD_EP_BITPOS(NRF_DRV_USBD_EPIN2) == USBD_EPDATASTATUS_EPIN2_Pos );
+STATIC_ASSERT(USBD_EP_BITPOS(NRF_DRV_USBD_EPIN3) == USBD_EPDATASTATUS_EPIN3_Pos );
+STATIC_ASSERT(USBD_EP_BITPOS(NRF_DRV_USBD_EPIN4) == USBD_EPDATASTATUS_EPIN4_Pos );
+STATIC_ASSERT(USBD_EP_BITPOS(NRF_DRV_USBD_EPIN5) == USBD_EPDATASTATUS_EPIN5_Pos );
+STATIC_ASSERT(USBD_EP_BITPOS(NRF_DRV_USBD_EPIN6) == USBD_EPDATASTATUS_EPIN6_Pos );
+STATIC_ASSERT(USBD_EP_BITPOS(NRF_DRV_USBD_EPIN7) == USBD_EPDATASTATUS_EPIN7_Pos );
+STATIC_ASSERT(USBD_EP_BITPOS(NRF_DRV_USBD_EPOUT1) == USBD_EPDATASTATUS_EPOUT1_Pos);
+STATIC_ASSERT(USBD_EP_BITPOS(NRF_DRV_USBD_EPOUT2) == USBD_EPDATASTATUS_EPOUT2_Pos);
+STATIC_ASSERT(USBD_EP_BITPOS(NRF_DRV_USBD_EPOUT3) == USBD_EPDATASTATUS_EPOUT3_Pos);
+STATIC_ASSERT(USBD_EP_BITPOS(NRF_DRV_USBD_EPOUT4) == USBD_EPDATASTATUS_EPOUT4_Pos);
+STATIC_ASSERT(USBD_EP_BITPOS(NRF_DRV_USBD_EPOUT5) == USBD_EPDATASTATUS_EPOUT5_Pos);
+STATIC_ASSERT(USBD_EP_BITPOS(NRF_DRV_USBD_EPOUT6) == USBD_EPDATASTATUS_EPOUT6_Pos);
+STATIC_ASSERT(USBD_EP_BITPOS(NRF_DRV_USBD_EPOUT7) == USBD_EPDATASTATUS_EPOUT7_Pos);
+
+
+/**
+ * @name Internal auxiliary definitions for SETUP packet
+ *
+ * Definitions used to take out the information about last SETUP packet direction
+ * from @c bmRequestType.
+ * @{
+ */
+/** The position of DIR bit in bmRequestType inside SETUP packet */
+#define USBD_DRV_REQUESTTYPE_DIR_BITPOS 7
+/** The mask of DIR bit in bmRequestType inside SETUP packet */
+#define USBD_DRV_REQUESTTYPE_DIR_MASK (1U << USBD_DRV_REQUESTTYPE_DIR_BITPOS)
+/** The value of DIR bit for OUT direction (Host -> Device) */
+#define USBD_DRV_REQUESTTYPE_DIR_OUT (0U << USBD_DRV_REQUESTTYPE_DIR_BITPOS)
+/** The value of DIR bit for IN direction (Device -> Host) */
+#define USBD_DRV_REQUESTTYPE_DIR_IN (1U << USBD_DRV_REQUESTTYPE_DIR_BITPOS)
+/** @} */
+
+/**
+ * @brief Current driver state
+ */
+static nrfx_drv_state_t m_drv_state = NRFX_DRV_STATE_UNINITIALIZED;
+
+/**
+ * @brief Event handler for the library
+ *
+ * Event handler that would be called on events.
+ *
+ * @note Currently it cannot be null if any interrupt is activated.
+ */
+static nrf_drv_usbd_event_handler_t m_event_handler;
+
+/**
+ * @brief Detected state of the bus
+ *
+ * Internal state changed in interrupts handling when
+ * RESUME or SUSPEND event is processed.
+ *
+ * Values:
+ * - true - bus suspended
+ * - false - ongoing normal communication on the bus
+ *
+ * @note This is only the bus state and does not mean that the peripheral is in suspend state.
+ */
+static volatile bool m_bus_suspend;
+
+/**
+ * @brief Internal constant that contains interrupts disabled in suspend state
+ *
+ * Internal constant used in @ref nrf_drv_usbd_suspend_irq_config and @ref nrf_drv_usbd_active_irq_config
+ * functions.
+ */
+static const uint32_t m_irq_disabled_in_suspend =
+ NRF_USBD_INT_ENDEPIN0_MASK |
+ NRF_USBD_INT_EP0DATADONE_MASK |
+ NRF_USBD_INT_ENDEPOUT0_MASK |
+ NRF_USBD_INT_EP0SETUP_MASK |
+ NRF_USBD_INT_DATAEP_MASK;
+
+/**
+ * @brief Direction of last received Setup transfer
+ *
+ * This variable is used to redirect internal setup data event
+ * into selected endpoint (IN or OUT).
+ */
+static nrf_drv_usbd_ep_t m_last_setup_dir;
+
+/**
+ * @brief Mark endpoint readiness for DMA transfer
+ *
+ * Bits in this variable are cleared and set in interrupts.
+ * 1 means that endpoint is ready for DMA transfer.
+ * 0 means that DMA transfer cannot be performed on selected endpoint.
+ */
+static uint32_t m_ep_ready;
+
+/**
+ * @brief Mark endpoint with prepared data to transfer by DMA
+ *
+ * This variable can be from any place in the code (interrupt or main thread).
+ * It would be cleared only from USBD interrupt.
+ *
+ * Mask prepared USBD data for transmission.
+ * It is cleared when no more data to transmit left.
+ */
+static uint32_t m_ep_dma_waiting;
+
+/**
+ * @brief Current EasyDMA state
+ *
+ * Single flag, updated only inside interrupts, that marks current EasyDMA state.
+ * In USBD there is only one DMA channel working in background, and new transfer
+ * cannot be started when there is ongoing transfer on any other channel.
+ */
+static bool m_dma_pending;
+
+/**
+ * @brief Simulated data EP status bits required for errata 104
+ *
+ * Marker to delete when not required anymore: >> NRF_DRV_USBD_ERRATA_ENABLE <<
+ */
+static uint32_t m_simulated_dataepstatus;
+
+/**
+ * @brief The structure that would hold transfer configuration to every endpoint
+ *
+ * The structure that holds all the data required by the endpoint to proceed
+ * with LIST functionality and generate quick callback directly when data
+ * buffer is ready.
+ */
+typedef struct
+{
+ nrf_drv_usbd_handler_t handler; //!< Handler for current transfer, function pointer
+ void * p_context; //!< Context for transfer handler
+ size_t transfer_cnt; //!< Number of transferred bytes in the current transfer
+ uint16_t max_packet_size; //!< Configured endpoint size
+ nrf_drv_usbd_ep_status_t status; //!< NRF_SUCCESS or error code, never NRF_ERROR_BUSY - this one is calculated
+}usbd_drv_ep_state_t;
+
+/**
+ * @brief The array of transfer configurations for the endpoints.
+ *
+ * The status of the transfer on each endpoint.
+ */
+static struct
+{
+ usbd_drv_ep_state_t ep_out[NRF_USBD_EPOUT_CNT]; //!< Status for OUT endpoints.
+ usbd_drv_ep_state_t ep_in [NRF_USBD_EPIN_CNT ]; //!< Status for IN endpoints.
+}m_ep_state;
+
+/**
+ * @brief Status variables for integrated feeders.
+ *
+ * Current status for integrated feeders (IN transfers).
+ * Integrated feeders are used for default transfers:
+ * 1. Simple RAM transfer
+ * 2. Simple flash transfer
+ * 3. RAM transfer with automatic ZLP
+ * 4. Flash transfer with automatic ZLP
+ */
+nrf_drv_usbd_transfer_t m_ep_feeder_state[NRF_USBD_EPIN_CNT];
+
+/**
+ * @brief Status variables for integrated consumers
+ *
+ * Current status for integrated consumers
+ * Currently one type of transfer is supported:
+ * 1. Transfer to RAM
+ *
+ * Transfer is finished automatically when received data block is smaller
+ * than the endpoint buffer or all the required data is received.
+ */
+nrf_drv_usbd_transfer_t m_ep_consumer_state[NRF_USBD_EPOUT_CNT];
+
+
+/**
+ * @brief Buffer used to send data directly from FLASH
+ *
+ * This is internal buffer that would be used to emulate the possibility
+ * to transfer data directly from FLASH.
+ * We do not have to care about the source of data when calling transfer functions.
+ *
+ * We do not need more buffers that one, because only one transfer can be pending
+ * at once.
+ */
+static uint32_t m_tx_buffer[CEIL_DIV(
+ NRF_DRV_USBD_FEEDER_BUFFER_SIZE, sizeof(uint32_t))];
+
+
+/* Early declaration. Documentation above definition. */
+static void usbd_dmareq_process(void);
+
+
+/**
+ * @brief Change endpoint number to endpoint event code
+ *
+ * @param ep Endpoint number
+ *
+ * @return Connected endpoint event code.
+ *
+ * Marker to delete when not required anymore: >> NRF_DRV_USBD_ERRATA_ENABLE <<
+ */
+static inline nrf_usbd_event_t nrf_drv_usbd_ep_to_endevent(nrf_drv_usbd_ep_t ep)
+{
+ USBD_ASSERT_EP_VALID(ep);
+
+ static const nrf_usbd_event_t epin_endev[] =
+ {
+ NRF_USBD_EVENT_ENDEPIN0,
+ NRF_USBD_EVENT_ENDEPIN1,
+ NRF_USBD_EVENT_ENDEPIN2,
+ NRF_USBD_EVENT_ENDEPIN3,
+ NRF_USBD_EVENT_ENDEPIN4,
+ NRF_USBD_EVENT_ENDEPIN5,
+ NRF_USBD_EVENT_ENDEPIN6,
+ NRF_USBD_EVENT_ENDEPIN7,
+ NRF_USBD_EVENT_ENDISOIN0
+ };
+ static const nrf_usbd_event_t epout_endev[] =
+ {
+ NRF_USBD_EVENT_ENDEPOUT0,
+ NRF_USBD_EVENT_ENDEPOUT1,
+ NRF_USBD_EVENT_ENDEPOUT2,
+ NRF_USBD_EVENT_ENDEPOUT3,
+ NRF_USBD_EVENT_ENDEPOUT4,
+ NRF_USBD_EVENT_ENDEPOUT5,
+ NRF_USBD_EVENT_ENDEPOUT6,
+ NRF_USBD_EVENT_ENDEPOUT7,
+ NRF_USBD_EVENT_ENDISOOUT0
+ };
+
+ return (NRF_USBD_EPIN_CHECK(ep) ? epin_endev : epout_endev)[NRF_USBD_EP_NR_GET(ep)];
+}
+
+
+/**
+ * @brief Get interrupt mask for selected endpoint
+ *
+ * @param[in] ep Endpoint number
+ *
+ * @return Interrupt mask related to the EasyDMA transfer end for the
+ * chosen endpoint.
+ */
+static inline uint32_t nrf_drv_usbd_ep_to_int(nrf_drv_usbd_ep_t ep)
+{
+ USBD_ASSERT_EP_VALID(ep);
+
+ static const uint8_t epin_bitpos[] =
+ {
+ USBD_INTEN_ENDEPIN0_Pos,
+ USBD_INTEN_ENDEPIN1_Pos,
+ USBD_INTEN_ENDEPIN2_Pos,
+ USBD_INTEN_ENDEPIN3_Pos,
+ USBD_INTEN_ENDEPIN4_Pos,
+ USBD_INTEN_ENDEPIN5_Pos,
+ USBD_INTEN_ENDEPIN6_Pos,
+ USBD_INTEN_ENDEPIN7_Pos,
+ USBD_INTEN_ENDISOIN_Pos
+ };
+ static const uint8_t epout_bitpos[] =
+ {
+ USBD_INTEN_ENDEPOUT0_Pos,
+ USBD_INTEN_ENDEPOUT1_Pos,
+ USBD_INTEN_ENDEPOUT2_Pos,
+ USBD_INTEN_ENDEPOUT3_Pos,
+ USBD_INTEN_ENDEPOUT4_Pos,
+ USBD_INTEN_ENDEPOUT5_Pos,
+ USBD_INTEN_ENDEPOUT6_Pos,
+ USBD_INTEN_ENDEPOUT7_Pos,
+ USBD_INTEN_ENDISOOUT_Pos
+ };
+
+ return 1UL << (NRF_USBD_EPIN_CHECK(ep) ? epin_bitpos : epout_bitpos)[NRF_USBD_EP_NR_GET(ep)];
+}
+
+/**
+ * @name Integrated feeders and consumers
+ *
+ * Internal, default functions for transfer processing.
+ * @{
+ */
+
+/**
+ * @brief Integrated consumer to RAM buffer.
+ *
+ * @param p_next See @ref nrf_drv_usbd_consumer_t documentation.
+ * @param p_context See @ref nrf_drv_usbd_consumer_t documentation.
+ * @param ep_size See @ref nrf_drv_usbd_consumer_t documentation.
+ * @param data_size See @ref nrf_drv_usbd_consumer_t documentation.
+ *
+ * @retval true Continue transfer.
+ * @retval false This was the last transfer.
+ */
+bool nrf_drv_usbd_consumer(
+ nrf_drv_usbd_ep_transfer_t * p_next,
+ void * p_context,
+ size_t ep_size,
+ size_t data_size)
+{
+ nrf_drv_usbd_transfer_t * p_transfer = p_context;
+ ASSERT(ep_size >= data_size);
+ ASSERT((p_transfer->p_data.rx == NULL) ||
+ nrfx_is_in_ram((const void*)(p_transfer->p_data.ptr)));
+
+ size_t size = p_transfer->size;
+ if (size < data_size)
+ {
+ NRF_LOG_DEBUG("consumer: buffer too small: r: %u, l: %u", data_size, size);
+ /* Buffer size to small */
+ p_next->size = 0;
+ p_next->p_data = p_transfer->p_data;
+ }
+ else
+ {
+ p_next->size = data_size;
+ p_next->p_data = p_transfer->p_data;
+ size -= data_size;
+ p_transfer->size = size;
+ p_transfer->p_data.ptr += data_size;
+ }
+ return (ep_size == data_size) && (size != 0);
+}
+
+/**
+ * @brief Integrated feeder from RAM source.
+ *
+ * @param[out] p_next See @ref nrf_drv_usbd_feeder_t documentation.
+ * @param[in,out] p_context See @ref nrf_drv_usbd_feeder_t documentation.
+ * @param[in] ep_size See @ref nrf_drv_usbd_feeder_t documentation.
+ *
+ * @retval true Continue transfer.
+ * @retval false This was the last transfer.
+ */
+bool nrf_drv_usbd_feeder_ram(
+ nrf_drv_usbd_ep_transfer_t * p_next,
+ void * p_context,
+ size_t ep_size)
+{
+ nrf_drv_usbd_transfer_t * p_transfer = p_context;
+ ASSERT(nrfx_is_in_ram((const void*)(p_transfer->p_data.ptr)));
+
+ size_t tx_size = p_transfer->size;
+ if (tx_size > ep_size)
+ {
+ tx_size = ep_size;
+ }
+
+ p_next->p_data = p_transfer->p_data;
+ p_next->size = tx_size;
+
+ p_transfer->size -= tx_size;
+ p_transfer->p_data.ptr += tx_size;
+
+ return (p_transfer->size != 0);
+}
+
+/**
+ * @brief Integrated feeder from RAM source with ZLP.
+ *
+ * @param[out] p_next See @ref nrf_drv_usbd_feeder_t documentation.
+ * @param[in,out] p_context See @ref nrf_drv_usbd_feeder_t documentation.
+ * @param[in] ep_size See @ref nrf_drv_usbd_feeder_t documentation.
+ *
+ * @retval true Continue transfer.
+ * @retval false This was the last transfer.
+ */
+bool nrf_drv_usbd_feeder_ram_zlp(
+ nrf_drv_usbd_ep_transfer_t * p_next,
+ void * p_context,
+ size_t ep_size)
+{
+ nrf_drv_usbd_transfer_t * p_transfer = p_context;
+ ASSERT(nrfx_is_in_ram((const void*)(p_transfer->p_data.ptr)));
+
+ size_t tx_size = p_transfer->size;
+ if (tx_size > ep_size)
+ {
+ tx_size = ep_size;
+ }
+
+ p_next->p_data.tx = (tx_size == 0) ? NULL : p_transfer->p_data.tx;
+ p_next->size = tx_size;
+
+ p_transfer->size -= tx_size;
+ p_transfer->p_data.ptr += tx_size;
+
+ return (tx_size != 0);
+}
+
+/**
+ * @brief Integrated feeder from a flash source.
+ *
+ * @param[out] p_next See @ref nrf_drv_usbd_feeder_t documentation.
+ * @param[in,out] p_context See @ref nrf_drv_usbd_feeder_t documentation.
+ * @param[in] ep_size See @ref nrf_drv_usbd_feeder_t documentation.
+ *
+ * @retval true Continue transfer.
+ * @retval false This was the last transfer.
+ */
+bool nrf_drv_usbd_feeder_flash(
+ nrf_drv_usbd_ep_transfer_t * p_next,
+ void * p_context,
+ size_t ep_size)
+{
+ nrf_drv_usbd_transfer_t * p_transfer = p_context;
+ ASSERT(!nrfx_is_in_ram((const void*)(p_transfer->p_data.ptr)));
+
+ size_t tx_size = p_transfer->size;
+ void * p_buffer = nrf_drv_usbd_feeder_buffer_get();
+
+ if (tx_size > ep_size)
+ {
+ tx_size = ep_size;
+ }
+
+ ASSERT(tx_size <= NRF_DRV_USBD_FEEDER_BUFFER_SIZE);
+ memcpy(p_buffer, (p_transfer->p_data.tx), tx_size);
+
+ p_next->p_data.tx = p_buffer;
+ p_next->size = tx_size;
+
+ p_transfer->size -= tx_size;
+ p_transfer->p_data.ptr += tx_size;
+
+ return (p_transfer->size != 0);
+}
+
+/**
+ * @brief Integrated feeder from a flash source with ZLP.
+ *
+ * @param[out] p_next See @ref nrf_drv_usbd_feeder_t documentation.
+ * @param[in,out] p_context See @ref nrf_drv_usbd_feeder_t documentation.
+ * @param[in] ep_size See @ref nrf_drv_usbd_feeder_t documentation.
+ *
+ * @retval true Continue transfer.
+ * @retval false This was the last transfer.
+ */
+bool nrf_drv_usbd_feeder_flash_zlp(
+ nrf_drv_usbd_ep_transfer_t * p_next,
+ void * p_context,
+ size_t ep_size)
+{
+ nrf_drv_usbd_transfer_t * p_transfer = p_context;
+ ASSERT(!nrfx_is_in_ram((const void*)(p_transfer->p_data.ptr)));
+
+ size_t tx_size = p_transfer->size;
+ void * p_buffer = nrf_drv_usbd_feeder_buffer_get();
+
+ if (tx_size > ep_size)
+ {
+ tx_size = ep_size;
+ }
+
+ ASSERT(tx_size <= NRF_DRV_USBD_FEEDER_BUFFER_SIZE);
+
+ if (tx_size != 0)
+ {
+ memcpy(p_buffer, (p_transfer->p_data.tx), tx_size);
+ p_next->p_data.tx = p_buffer;
+ }
+ else
+ {
+ p_next->p_data.tx = NULL;
+ }
+ p_next->size = tx_size;
+
+ p_transfer->size -= tx_size;
+ p_transfer->p_data.ptr += tx_size;
+
+ return (tx_size != 0);
+}
+
+/** @} */
+
+/**
+ * @brief Change Driver endpoint number to HAL endpoint number
+ *
+ * @param ep Driver endpoint identifier
+ *
+ * @return Endpoint identifier in HAL
+ *
+ * @sa nrf_drv_usbd_ep_from_hal
+ */
+static inline uint8_t ep_to_hal(nrf_drv_usbd_ep_t ep)
+{
+ USBD_ASSERT_EP_VALID(ep);
+ return (uint8_t)ep;
+}
+
+/**
+ * @brief Generate start task number for selected endpoint index
+ *
+ * @param ep Endpoint number
+ *
+ * @return Task for starting EasyDMA transfer on selected endpoint.
+ */
+static inline nrf_usbd_task_t task_start_ep(nrf_drv_usbd_ep_t ep)
+{
+ USBD_ASSERT_EP_VALID(ep);
+ return (nrf_usbd_task_t)(
+ (NRF_USBD_EPIN_CHECK(ep) ? NRF_USBD_TASK_STARTEPIN0 : NRF_USBD_TASK_STARTEPOUT0) +
+ (NRF_USBD_EP_NR_GET(ep) * sizeof(uint32_t)));
+}
+
+/**
+ * @brief Access selected endpoint state structure
+ *
+ * Function used to change or just read the state of selected endpoint.
+ * It is used for internal transmission state.
+ *
+ * @param ep Endpoint number
+ */
+static inline usbd_drv_ep_state_t* ep_state_access(nrf_drv_usbd_ep_t ep)
+{
+ USBD_ASSERT_EP_VALID(ep);
+ return ((NRF_USBD_EPIN_CHECK(ep) ? m_ep_state.ep_in : m_ep_state.ep_out) +
+ NRF_USBD_EP_NR_GET(ep));
+}
+
+/**
+ * @brief Change endpoint number to bit position
+ *
+ * Bit positions are defined the same way as they are placed in DATAEPSTATUS register,
+ * but bits for endpoint 0 are included.
+ *
+ * @param ep Endpoint number
+ *
+ * @return Bit position related to the given endpoint number
+ *
+ * @sa bit2ep
+ */
+static inline uint8_t ep2bit(nrf_drv_usbd_ep_t ep)
+{
+ USBD_ASSERT_EP_VALID(ep);
+ return USBD_EP_BITPOS(ep);
+}
+
+/**
+ * @brief Change bit position to endpoint number
+ *
+ * @param bitpos Bit position
+ *
+ * @return Endpoint number corresponding to given bit position.
+ *
+ * @sa ep2bit
+ */
+static inline nrf_drv_usbd_ep_t bit2ep(uint8_t bitpos)
+{
+ STATIC_ASSERT(USBD_EPOUT_BITPOS_0 > USBD_EPIN_BITPOS_0);
+ return (nrf_drv_usbd_ep_t)((bitpos >= USBD_EPOUT_BITPOS_0) ?
+ NRF_USBD_EPOUT(bitpos - USBD_EPOUT_BITPOS_0) : NRF_USBD_EPIN(bitpos));
+}
+
+/**
+ * @brief Mark that EasyDMA is working
+ *
+ * Internal function to set the flag informing about EasyDMA transfer pending.
+ * This function is called always just after the EasyDMA transfer is started.
+ */
+static inline void usbd_dma_pending_set(void)
+{
+ if (nrf_drv_usb_errata_199())
+ {
+ *((volatile uint32_t *)0x40027C1C) = 0x00000082;
+ }
+ m_dma_pending = true;
+}
+
+/**
+ * @brief Mark that EasyDMA is free
+ *
+ * Internal function to clear the flag informing about EasyDMA transfer pending.
+ * This function is called always just after the finished EasyDMA transfer is detected.
+ */
+static inline void usbd_dma_pending_clear(void)
+{
+ if (nrf_drv_usb_errata_199())
+ {
+ *((volatile uint32_t *)0x40027C1C) = 0x00000000;
+ }
+ m_dma_pending = false;
+}
+
+/**
+ * @brief Start selected EasyDMA transmission
+ *
+ * This is internal auxiliary function.
+ * No checking is made if EasyDMA is ready for new transmission.
+ *
+ * @param[in] ep Number of endpoint for transmission.
+ * If it is OUT endpoint transmission would be directed from endpoint to RAM.
+ * If it is in endpoint transmission would be directed from RAM to endpoint.
+ */
+static inline void usbd_dma_start(nrf_drv_usbd_ep_t ep)
+{
+ nrf_usbd_task_trigger(task_start_ep(ep));
+}
+
+/**
+ * @brief Abort pending transfer on selected endpoint
+ *
+ * @param ep Endpoint number.
+ *
+ * @note
+ * This function locks interrupts that may be costly.
+ * It is good idea to test if the endpoint is still busy before calling this function:
+ * @code
+ (m_ep_dma_waiting & (1U << ep2bit(ep)))
+ * @endcode
+ * This function would check it again, but it makes it inside critical section.
+ */
+static inline void usbd_ep_abort(nrf_drv_usbd_ep_t ep)
+{
+ CRITICAL_REGION_ENTER();
+
+ usbd_drv_ep_state_t * p_state = ep_state_access(ep);
+
+ if (NRF_USBD_EPOUT_CHECK(ep))
+ {
+ /* Host -> Device */
+ if ((~m_ep_dma_waiting) & (1U << ep2bit(ep)))
+ {
+ /* If the bit in m_ep_dma_waiting in cleared - nothing would be
+ * processed inside transfer processing */
+ nrf_drv_usbd_transfer_out_drop(ep);
+ }
+ else
+ {
+ p_state->handler.consumer = NULL;
+ m_ep_dma_waiting &= ~(1U << ep2bit(ep));
+ m_ep_ready &= ~(1U << ep2bit(ep));
+ }
+ /* Aborted */
+ p_state->status = NRF_USBD_EP_ABORTED;
+ }
+ else
+ {
+ if ((m_ep_dma_waiting | (~m_ep_ready)) & (1U << ep2bit(ep)))
+ {
+ /* Device -> Host */
+ m_ep_dma_waiting &= ~(1U << ep2bit(ep));
+ m_ep_ready |= 1U << ep2bit(ep) ;
+
+ p_state->handler.feeder = NULL;
+ p_state->status = NRF_USBD_EP_ABORTED;
+ NRF_DRV_USBD_EP_TRANSFER_EVENT(evt, ep, NRF_USBD_EP_ABORTED);
+ m_event_handler(&evt);
+ }
+ }
+ CRITICAL_REGION_EXIT();
+}
+
+void nrf_drv_usbd_ep_abort(nrf_drv_usbd_ep_t ep)
+{
+ usbd_ep_abort(ep);
+}
+
+
+/**
+ * @brief Abort all pending endpoints
+ *
+ * Function aborts all pending endpoint transfers.
+ */
+static void usbd_ep_abort_all(void)
+{
+ uint32_t ep_waiting = m_ep_dma_waiting | (m_ep_ready & USBD_EPOUT_BIT_MASK);
+ while (0 != ep_waiting)
+ {
+ uint8_t bitpos = __CLZ(__RBIT(ep_waiting));
+ if(!NRF_USBD_EPISO_CHECK(bit2ep(bitpos)))
+ {
+ usbd_ep_abort(bit2ep(bitpos));
+ }
+ ep_waiting &= ~(1U << bitpos);
+ }
+
+ m_ep_ready = (((1U << NRF_USBD_EPIN_CNT) - 1U) << USBD_EPIN_BITPOS_0);
+}
+
+/**
+ * @brief Force the USBD interrupt into pending state
+ *
+ * This function is used to force USBD interrupt to be processed right now.
+ * It makes it possible to process all EasyDMA access on one thread priority level.
+ */
+static inline void usbd_int_rise(void)
+{
+ NVIC_SetPendingIRQ(USBD_IRQn);
+}
+
+/**
+ * @name USBD interrupt runtimes
+ *
+ * Interrupt runtimes that would be vectorized using @ref m_ivec_isr
+ * @{
+ */
+
+static void ev_usbreset_handler(void)
+{
+ m_bus_suspend = false;
+ m_last_setup_dir = NRF_DRV_USBD_EPOUT0;
+
+ const nrf_drv_usbd_evt_t evt = {
+ .type = NRF_DRV_USBD_EVT_RESET
+ };
+
+ m_event_handler(&evt);
+}
+
+static void ev_started_handler(void)
+{
+#if NRF_DRV_USBD_STARTED_EV_ENABLE
+ uint32_t epstatus = nrf_usbd_epstatus_get_and_clear();
+
+ /* All finished endpoint have to be marked as busy */
+ // #warning Check this one
+ // ASSERT(epstatus == ((~m_ep_ready) & epstatus));
+ while (epstatus)
+ {
+ uint8_t bitpos = __CLZ(__RBIT(epstatus));
+ nrf_drv_usbd_ep_t ep = bit2ep(bitpos);
+ epstatus &= ~(1UL << bitpos);
+
+ UNUSED_VARIABLE(ep);
+ }
+#endif
+}
+
+/**
+ * @brief Handler for EasyDMA event without endpoint clearing.
+ *
+ * This handler would be called when EasyDMA transfer for endpoints that does not require clearing.
+ * All in endpoints are cleared automatically when new EasyDMA transfer is initialized.
+ * For endpoint 0 see @ref nrf_usbd_ep0out_dma_handler
+ *
+ * @param[in] ep Endpoint number
+ */
+static inline void nrf_usbd_ep0in_dma_handler(void)
+{
+ const nrf_drv_usbd_ep_t ep = NRF_DRV_USBD_EPIN0;
+ NRF_LOG_DEBUG("USB event: DMA ready IN0");
+ usbd_dma_pending_clear();
+
+ usbd_drv_ep_state_t * p_state = ep_state_access(ep);
+ if (NRF_USBD_EP_ABORTED == p_state->status)
+ {
+ /* Clear transfer information just in case */
+ UNUSED_RETURN_VALUE(nrf_atomic_u32_and(&m_ep_dma_waiting, ~(1U << ep2bit(ep))));
+ }
+ else if (p_state->handler.feeder == NULL)
+ {
+ UNUSED_RETURN_VALUE(nrf_atomic_u32_and(&m_ep_dma_waiting, ~(1U << ep2bit(ep))));
+ }
+ else
+ {
+ /* Nothing to do */
+ }
+}
+
+/**
+ * @brief Handler for EasyDMA event without endpoint clearing.
+ *
+ * This handler would be called when EasyDMA transfer for endpoints that does not require clearing.
+ * All in endpoints are cleared automatically when new EasyDMA transfer is initialized.
+ * For endpoint 0 see @ref nrf_usbd_ep0out_dma_handler
+ *
+ * @param[in] ep Endpoint number
+ */
+static inline void nrf_usbd_epin_dma_handler(nrf_drv_usbd_ep_t ep)
+{
+
+ NRF_LOG_DEBUG("USB event: DMA ready IN: %x", ep);
+ ASSERT(NRF_USBD_EPIN_CHECK(ep));
+ ASSERT(!NRF_USBD_EPISO_CHECK(ep));
+ ASSERT(NRF_USBD_EP_NR_GET(ep) > 0);
+ usbd_dma_pending_clear();
+
+ usbd_drv_ep_state_t * p_state = ep_state_access(ep);
+ if (NRF_USBD_EP_ABORTED == p_state->status)
+ {
+ /* Clear transfer information just in case */
+ UNUSED_RETURN_VALUE(nrf_atomic_u32_and(&m_ep_dma_waiting, ~(1U << ep2bit(ep))));
+ }
+ else if (p_state->handler.feeder == NULL)
+ {
+ UNUSED_RETURN_VALUE(nrf_atomic_u32_and(&m_ep_dma_waiting, ~(1U << ep2bit(ep))));
+ }
+ else
+ {
+ /* Nothing to do */
+ }
+}
+
+/**
+ * @brief Handler for EasyDMA event from in isochronous endpoint
+ *
+ * @todo RK documentation
+ */
+static inline void nrf_usbd_epiniso_dma_handler(nrf_drv_usbd_ep_t ep)
+{
+ if (NRF_USBD_ISO_DEBUG)
+ {
+ NRF_LOG_DEBUG("USB event: DMA ready ISOIN: %x", ep);
+ }
+ ASSERT(NRF_USBD_EPIN_CHECK(ep));
+ ASSERT(NRF_USBD_EPISO_CHECK(ep));
+ usbd_dma_pending_clear();
+
+ usbd_drv_ep_state_t * p_state = ep_state_access(ep);
+ if (NRF_USBD_EP_ABORTED == p_state->status)
+ {
+ /* Clear transfer information just in case */
+ UNUSED_RETURN_VALUE(nrf_atomic_u32_and(&m_ep_dma_waiting, ~(1U << ep2bit(ep))));
+ }
+ else if (p_state->handler.feeder == NULL)
+ {
+ UNUSED_RETURN_VALUE(nrf_atomic_u32_and(&m_ep_dma_waiting, ~(1U << ep2bit(ep))));
+ /* Send event to the user - for an ISO IN endpoint, the whole transfer is finished in this moment */
+ NRF_DRV_USBD_EP_TRANSFER_EVENT(evt, ep, NRF_USBD_EP_OK);
+ m_event_handler(&evt);
+ }
+ else
+ {
+ /* Nothing to do */
+ }
+}
+
+/**
+ * @brief Handler for EasyDMA event for OUT endpoint 0.
+ *
+ * EP0 OUT have to be cleared automatically in special way - only in the middle of the transfer.
+ * It cannot be cleared when required transfer is finished because it means the same that accepting the comment.
+ */
+static inline void nrf_usbd_ep0out_dma_handler(void)
+{
+ const nrf_drv_usbd_ep_t ep = NRF_DRV_USBD_EPOUT0;
+ NRF_LOG_DEBUG("USB event: DMA ready OUT0");
+ usbd_dma_pending_clear();
+
+ usbd_drv_ep_state_t * p_state = ep_state_access(ep);
+ if (NRF_USBD_EP_ABORTED == p_state->status)
+ {
+ /* Clear transfer information just in case */
+ UNUSED_RETURN_VALUE(nrf_atomic_u32_and(&m_ep_dma_waiting, ~(1U << ep2bit(ep))));
+ }
+ else if (p_state->handler.consumer == NULL)
+ {
+ UNUSED_RETURN_VALUE(nrf_atomic_u32_and(&m_ep_dma_waiting, ~(1U << ep2bit(ep))));
+ /* Send event to the user - for an OUT endpoint, the whole transfer is finished in this moment */
+ NRF_DRV_USBD_EP_TRANSFER_EVENT(evt, ep, NRF_USBD_EP_OK);
+ m_event_handler(&evt);
+ }
+ else
+ {
+ nrf_drv_usbd_setup_data_clear();
+ }
+}
+
+/**
+ * @brief Handler for EasyDMA event from endpoinpoint that requires clearing.
+ *
+ * This handler would be called when EasyDMA transfer for OUT endpoint has been finished.
+ *
+ * @param[in] ep Endpoint number
+ *
+ */
+static inline void nrf_usbd_epout_dma_handler(nrf_drv_usbd_ep_t ep)
+{
+ NRF_LOG_DEBUG("USB drv: DMA ready OUT: %x", ep);
+ ASSERT(NRF_USBD_EPOUT_CHECK(ep));
+ ASSERT(!NRF_USBD_EPISO_CHECK(ep));
+ ASSERT(NRF_USBD_EP_NR_GET(ep) > 0);
+ usbd_dma_pending_clear();
+
+ usbd_drv_ep_state_t * p_state = ep_state_access(ep);
+ if (NRF_USBD_EP_ABORTED == p_state->status)
+ {
+ /* Clear transfer information just in case */
+ UNUSED_RETURN_VALUE(nrf_atomic_u32_and(&m_ep_dma_waiting, ~(1U << ep2bit(ep))));
+ }
+ else if (p_state->handler.consumer == NULL)
+ {
+ UNUSED_RETURN_VALUE(nrf_atomic_u32_and(&m_ep_dma_waiting, ~(1U << ep2bit(ep))));
+ /* Send event to the user - for an OUT endpoint, the whole transfer is finished in this moment */
+ NRF_DRV_USBD_EP_TRANSFER_EVENT(evt, ep, NRF_USBD_EP_OK);
+ m_event_handler(&evt);
+ }
+ else
+ {
+ /* Nothing to do */
+ }
+
+#if NRF_DRV_USBD_EARLY_DMA_PROCESS
+ /* Speed up */
+ usbd_dmareq_process();
+#endif
+}
+
+/**
+ * @brief Handler for EasyDMA event from out isochronous endpoint
+ *
+ * @todo RK documentation
+ */
+
+static inline void nrf_usbd_epoutiso_dma_handler(nrf_drv_usbd_ep_t ep)
+{
+ if (NRF_USBD_ISO_DEBUG)
+ {
+ NRF_LOG_DEBUG("USB drv: DMA ready ISOOUT: %x", ep);
+ }
+ ASSERT(NRF_USBD_EPISO_CHECK(ep));
+ usbd_dma_pending_clear();
+
+ usbd_drv_ep_state_t * p_state = ep_state_access(ep);
+ if (NRF_USBD_EP_ABORTED == p_state->status)
+ {
+ /* Nothing to do - just ignore */
+ }
+ else if (p_state->handler.consumer == NULL)
+ {
+ UNUSED_RETURN_VALUE(nrf_atomic_u32_and(&m_ep_dma_waiting, ~(1U << ep2bit(ep))));
+ /* Send event to the user - for an OUT endpoint, the whole transfer is finished in this moment */
+ NRF_DRV_USBD_EP_TRANSFER_EVENT(evt, ep, NRF_USBD_EP_OK);
+ m_event_handler(&evt);
+ }
+ else
+ {
+ /* Nothing to do */
+ }
+}
+
+
+static void ev_dma_epin0_handler(void) { nrf_usbd_ep0in_dma_handler(); }
+static void ev_dma_epin1_handler(void) { nrf_usbd_epin_dma_handler(NRF_DRV_USBD_EPIN1 ); }
+static void ev_dma_epin2_handler(void) { nrf_usbd_epin_dma_handler(NRF_DRV_USBD_EPIN2 ); }
+static void ev_dma_epin3_handler(void) { nrf_usbd_epin_dma_handler(NRF_DRV_USBD_EPIN3 ); }
+static void ev_dma_epin4_handler(void) { nrf_usbd_epin_dma_handler(NRF_DRV_USBD_EPIN4 ); }
+static void ev_dma_epin5_handler(void) { nrf_usbd_epin_dma_handler(NRF_DRV_USBD_EPIN5 ); }
+static void ev_dma_epin6_handler(void) { nrf_usbd_epin_dma_handler(NRF_DRV_USBD_EPIN6 ); }
+static void ev_dma_epin7_handler(void) { nrf_usbd_epin_dma_handler(NRF_DRV_USBD_EPIN7 ); }
+static void ev_dma_epin8_handler(void) { nrf_usbd_epiniso_dma_handler(NRF_DRV_USBD_EPIN8 ); }
+
+static void ev_dma_epout0_handler(void) { nrf_usbd_ep0out_dma_handler(); }
+static void ev_dma_epout1_handler(void) { nrf_usbd_epout_dma_handler(NRF_DRV_USBD_EPOUT1); }
+static void ev_dma_epout2_handler(void) { nrf_usbd_epout_dma_handler(NRF_DRV_USBD_EPOUT2); }
+static void ev_dma_epout3_handler(void) { nrf_usbd_epout_dma_handler(NRF_DRV_USBD_EPOUT3); }
+static void ev_dma_epout4_handler(void) { nrf_usbd_epout_dma_handler(NRF_DRV_USBD_EPOUT4); }
+static void ev_dma_epout5_handler(void) { nrf_usbd_epout_dma_handler(NRF_DRV_USBD_EPOUT5); }
+static void ev_dma_epout6_handler(void) { nrf_usbd_epout_dma_handler(NRF_DRV_USBD_EPOUT6); }
+static void ev_dma_epout7_handler(void) { nrf_usbd_epout_dma_handler(NRF_DRV_USBD_EPOUT7); }
+static void ev_dma_epout8_handler(void) { nrf_usbd_epoutiso_dma_handler(NRF_DRV_USBD_EPOUT8); }
+
+static void ev_sof_handler(void)
+{
+ nrf_drv_usbd_evt_t evt = {
+ NRF_DRV_USBD_EVT_SOF,
+ .data = { .sof = { .framecnt = nrf_usbd_framecntr_get() }}
+ };
+
+ /* Process isochronous endpoints */
+ m_ep_ready |=
+ (1U << ep2bit(NRF_DRV_USBD_EPIN8 )) |
+ (1U << ep2bit(NRF_DRV_USBD_EPOUT8));
+
+ m_event_handler(&evt);
+}
+
+/**
+ * @brief React on data transfer finished
+ *
+ * Auxiliary internal function.
+ * @param ep Endpoint number
+ * @param bitpos Bit position for selected endpoint number
+ */
+static void usbd_ep_data_handler(nrf_drv_usbd_ep_t ep, uint8_t bitpos)
+{
+ NRF_LOG_DEBUG("USBD event: EndpointData: %x", ep);
+ /* Mark endpoint ready for next DMA access */
+ m_ep_ready |= (1U << bitpos);
+
+ if (NRF_USBD_EPIN_CHECK(ep))
+ {
+ /* IN endpoint (Device -> Host) */
+ if (0 == (m_ep_dma_waiting & (1U << bitpos)))
+ {
+ NRF_LOG_DEBUG("USBD event: EndpointData: In finished");
+ /* No more data to be send - transmission finished */
+ NRF_DRV_USBD_EP_TRANSFER_EVENT(evt, ep, NRF_USBD_EP_OK);
+ m_event_handler(&evt);
+ }
+ }
+ else
+ {
+ /* OUT endpoint (Host -> Device) */
+ if (0 == (m_ep_dma_waiting & (1U << bitpos)))
+ {
+ NRF_LOG_DEBUG("USBD event: EndpointData: Out waiting");
+ /* No buffer prepared - send event to the application */
+ NRF_DRV_USBD_EP_TRANSFER_EVENT(evt, ep, NRF_USBD_EP_WAITING);
+ m_event_handler(&evt);
+ }
+ }
+}
+
+static void ev_setup_data_handler(void)
+{
+ usbd_ep_data_handler(m_last_setup_dir, ep2bit(m_last_setup_dir));
+}
+
+static void ev_setup_handler(void)
+{
+ NRF_LOG_DEBUG("USBD event: Setup (rt:%.2x r:%.2x v:%.4x i:%.4x l:%u )",
+ nrf_usbd_setup_bmrequesttype_get(),
+ nrf_usbd_setup_brequest_get(),
+ nrf_usbd_setup_wvalue_get(),
+ nrf_usbd_setup_windex_get(),
+ nrf_usbd_setup_wlength_get());
+ uint8_t bmRequestType = nrf_usbd_setup_bmrequesttype_get();
+
+
+ if ((m_ep_dma_waiting | ((~m_ep_ready) & USBD_EPIN_BIT_MASK)) & (1U <<ep2bit(m_last_setup_dir)))
+ {
+ NRF_LOG_DEBUG("USBD drv: Trying to abort last transfer on EP0");
+ usbd_ep_abort(m_last_setup_dir);
+ }
+
+ m_last_setup_dir =
+ ((bmRequestType & USBD_DRV_REQUESTTYPE_DIR_MASK) == USBD_DRV_REQUESTTYPE_DIR_OUT) ?
+ NRF_DRV_USBD_EPOUT0 : NRF_DRV_USBD_EPIN0;
+
+ UNUSED_RETURN_VALUE(nrf_atomic_u32_and(
+ &m_ep_dma_waiting,
+ ~((1U << ep2bit(NRF_DRV_USBD_EPOUT0)) | (1U << ep2bit(NRF_DRV_USBD_EPIN0)))));
+ m_ep_ready |= 1U << ep2bit(NRF_DRV_USBD_EPIN0);
+
+
+ const nrf_drv_usbd_evt_t evt = {
+ .type = NRF_DRV_USBD_EVT_SETUP
+ };
+ m_event_handler(&evt);
+}
+
+static void ev_usbevent_handler(void)
+{
+ uint32_t event = nrf_usbd_eventcause_get_and_clear();
+
+ if (event & NRF_USBD_EVENTCAUSE_ISOOUTCRC_MASK)
+ {
+ /* Currently no support */
+ }
+ if (event & NRF_USBD_EVENTCAUSE_SUSPEND_MASK)
+ {
+ m_bus_suspend = true;
+ const nrf_drv_usbd_evt_t evt = {
+ .type = NRF_DRV_USBD_EVT_SUSPEND
+ };
+ m_event_handler(&evt);
+ }
+ if (event & NRF_USBD_EVENTCAUSE_RESUME_MASK)
+ {
+ m_bus_suspend = false;
+ const nrf_drv_usbd_evt_t evt = {
+ .type = NRF_DRV_USBD_EVT_RESUME
+ };
+ m_event_handler(&evt);
+ }
+ if (event & NRF_USBD_EVENTCAUSE_WUREQ_MASK)
+ {
+ if (m_bus_suspend)
+ {
+ ASSERT(!nrf_usbd_lowpower_check());
+ m_bus_suspend = false;
+
+ nrf_usbd_dpdmvalue_set(NRF_USBD_DPDMVALUE_RESUME);
+ nrf_usbd_task_trigger(NRF_USBD_TASK_DRIVEDPDM);
+
+ const nrf_drv_usbd_evt_t evt = {
+ .type = NRF_DRV_USBD_EVT_WUREQ
+ };
+ m_event_handler(&evt);
+ }
+ }
+}
+
+static void ev_epdata_handler(void)
+{
+ /* Get all endpoints that have acknowledged transfer */
+ uint32_t dataepstatus = nrf_usbd_epdatastatus_get_and_clear();
+ if (nrf_drv_usbd_errata_104())
+ {
+ dataepstatus |= (m_simulated_dataepstatus &
+ ~((1U << USBD_EPOUT_BITPOS_0) | (1U << USBD_EPIN_BITPOS_0)));
+ m_simulated_dataepstatus &=
+ ((1U << USBD_EPOUT_BITPOS_0) | (1U << USBD_EPIN_BITPOS_0));
+ }
+ NRF_LOG_DEBUG("USBD event: EndpointEPStatus: %x", dataepstatus);
+
+ /* All finished endpoint have to be marked as busy */
+ while (dataepstatus)
+ {
+ uint8_t bitpos = __CLZ(__RBIT(dataepstatus));
+ nrf_drv_usbd_ep_t ep = bit2ep(bitpos);
+ dataepstatus &= ~(1UL << bitpos);
+
+ UNUSED_RETURN_VALUE(usbd_ep_data_handler(ep, bitpos));
+ }
+ if (NRF_DRV_USBD_EARLY_DMA_PROCESS)
+ {
+ /* Speed up */
+ usbd_dmareq_process();
+ }
+}
+
+/**
+ * @brief Function to select the endpoint to start
+ *
+ * Function that realizes algorithm to schedule right channel for EasyDMA transfer.
+ * It gets a variable with flags for the endpoints currently requiring transfer.
+ *
+ * @param[in] req Bit flags for channels currently requiring transfer.
+ * Bits 0...8 used for IN endpoints.
+ * Bits 16...24 used for OUT endpoints.
+ * @note
+ * This function would be never called with 0 as a @c req argument.
+ * @return The bit number of the endpoint that should be processed now.
+ */
+static uint8_t usbd_dma_scheduler_algorithm(uint32_t req)
+{
+ /* Only prioritized scheduling mode is supported */
+ STATIC_ASSERT(USBD_CONFIG_DMASCHEDULER_MODE == NRF_DRV_USBD_DMASCHEDULER_PRIORITIZED);
+ return __CLZ(__RBIT(req));
+}
+
+/**
+ * @brief Get the size of isochronous endpoint
+ *
+ * The size of isochronous endpoint is configurable.
+ * This function returns the size of isochronous buffer taking into account
+ * current configuration.
+ *
+ * @param[in] ep Endpoint number.
+ *
+ * @return The size of endpoint buffer.
+ */
+static inline size_t usbd_ep_iso_capacity(nrf_drv_usbd_ep_t ep)
+{
+ UNUSED_PARAMETER(ep);
+ nrf_usbd_isosplit_t split = nrf_usbd_isosplit_get();
+ if (NRF_USBD_ISOSPLIT_Half == split)
+ {
+ return NRF_DRV_USBD_ISOSIZE / 2;
+ }
+ return NRF_DRV_USBD_ISOSIZE;
+}
+
+/**
+ * @brief Process all DMA requests
+ *
+ * Function that have to be called from USBD interrupt handler.
+ * It have to be called when all the interrupts connected with endpoints transfer
+ * and DMA transfer are already handled.
+ */
+static void usbd_dmareq_process(void)
+{
+ if (!m_dma_pending)
+ {
+ uint32_t req;
+ while (0 != (req = m_ep_dma_waiting & m_ep_ready))
+ {
+ uint8_t pos = usbd_dma_scheduler_algorithm(req);
+ nrf_drv_usbd_ep_t ep = bit2ep(pos);
+ usbd_drv_ep_state_t * p_state = ep_state_access(ep);
+
+ nrf_drv_usbd_ep_transfer_t transfer;
+ bool continue_transfer;
+
+ STATIC_ASSERT(offsetof(usbd_drv_ep_state_t, handler.feeder) ==
+ offsetof(usbd_drv_ep_state_t, handler.consumer));
+ ASSERT((p_state->handler.feeder) != NULL);
+
+ if (NRF_USBD_EPIN_CHECK(ep))
+ {
+ /* Device -> Host */
+ continue_transfer = p_state->handler.feeder(
+ &transfer,
+ p_state->p_context,
+ p_state->max_packet_size);
+
+ if (!continue_transfer)
+ {
+ p_state->handler.feeder = NULL;
+ }
+ }
+ else
+ {
+ /* Host -> Device */
+ const size_t rx_size = nrf_drv_usbd_epout_size_get(ep);
+ continue_transfer = p_state->handler.consumer(
+ &transfer,
+ p_state->p_context,
+ p_state->max_packet_size,
+ rx_size);
+
+ if (transfer.p_data.rx == NULL)
+ {
+ /* Dropping transfer - allow processing */
+ ASSERT(transfer.size == 0);
+ }
+ else if (transfer.size < rx_size)
+ {
+ NRF_LOG_DEBUG("Endpoint %x overload (r: %u, e: %u)", ep, rx_size, transfer.size);
+ p_state->status = NRF_USBD_EP_OVERLOAD;
+ UNUSED_RETURN_VALUE(nrf_atomic_u32_and(&m_ep_dma_waiting, ~(1U << pos)));
+ NRF_DRV_USBD_EP_TRANSFER_EVENT(evt, ep, NRF_USBD_EP_OVERLOAD);
+ m_event_handler(&evt);
+ /* This endpoint will not be transmitted now, repeat the loop */
+ continue;
+ }
+ else
+ {
+ /* Nothing to do - only check integrity if assertions are enabled */
+ ASSERT(transfer.size == rx_size);
+ }
+
+ if (!continue_transfer)
+ {
+ p_state->handler.consumer = NULL;
+ }
+ }
+
+ usbd_dma_pending_set();
+ m_ep_ready &= ~(1U << pos);
+ if (NRF_USBD_ISO_DEBUG || (!NRF_USBD_EPISO_CHECK(ep)))
+ {
+ NRF_LOG_DEBUG(
+ "USB DMA process: Starting transfer on EP: %x, size: %u",
+ ep,
+ transfer.size);
+ }
+ /* Update number of currently transferred bytes */
+ p_state->transfer_cnt += transfer.size;
+ /* Start transfer to the endpoint buffer */
+ nrf_usbd_ep_easydma_set(ep, transfer.p_data.ptr, (uint32_t)transfer.size);
+
+ if (nrf_drv_usbd_errata_104())
+ {
+ uint32_t cnt_end = (uint32_t)(-1);
+ do
+ {
+ uint32_t cnt = (uint32_t)(-1);
+ do
+ {
+ nrf_usbd_event_clear(NRF_USBD_EVENT_STARTED);
+ usbd_dma_start(ep);
+ nrf_delay_us(2);
+ ++cnt;
+ }while (!nrf_usbd_event_check(NRF_USBD_EVENT_STARTED));
+ if (cnt)
+ {
+ NRF_DRV_USBD_LOG_PROTO1_FIX_PRINTF(" DMA restarted: %u times", cnt);
+ }
+
+ nrf_delay_us(30);
+ while (0 == (0x20 & *((volatile uint32_t *)(NRF_USBD_BASE + 0x474))))
+ {
+ nrf_delay_us(2);
+ }
+ nrf_delay_us(1);
+
+ ++cnt_end;
+ } while (!nrf_usbd_event_check(nrf_drv_usbd_ep_to_endevent(ep)));
+ if (cnt_end)
+ {
+ NRF_DRV_USBD_LOG_PROTO1_FIX_PRINTF(" DMA fully restarted: %u times", cnt_end);
+ }
+ }
+ else
+ {
+ usbd_dma_start(ep);
+ /* There is a lot of USBD registers that cannot be accessed during EasyDMA transfer.
+ * This is quick fix to maintain stability of the stack.
+ * It cost some performance but makes stack stable. */
+ while (!nrf_usbd_event_check(nrf_drv_usbd_ep_to_endevent(ep)))
+ {
+ /* Empty */
+ }
+ }
+
+ if (NRF_USBD_DMAREQ_PROCESS_DEBUG)
+ {
+ NRF_LOG_DEBUG("USB DMA process - finishing");
+ }
+ /* Transfer started - exit the loop */
+ break;
+ }
+ }
+ else
+ {
+ if (NRF_USBD_DMAREQ_PROCESS_DEBUG)
+ {
+ NRF_LOG_DEBUG("USB DMA process - EasyDMA busy");
+ }
+ }
+}
+/** @} */
+
+typedef void (*nrf_drv_usbd_isr_t)(void);
+
+/**
+ * @brief USBD interrupt service runtimes
+ *
+ */
+static const nrf_drv_usbd_isr_t m_isr[] =
+{
+ [USBD_INTEN_USBRESET_Pos ] = ev_usbreset_handler,
+ [USBD_INTEN_STARTED_Pos ] = ev_started_handler,
+ [USBD_INTEN_ENDEPIN0_Pos ] = ev_dma_epin0_handler,
+ [USBD_INTEN_ENDEPIN1_Pos ] = ev_dma_epin1_handler,
+ [USBD_INTEN_ENDEPIN2_Pos ] = ev_dma_epin2_handler,
+ [USBD_INTEN_ENDEPIN3_Pos ] = ev_dma_epin3_handler,
+ [USBD_INTEN_ENDEPIN4_Pos ] = ev_dma_epin4_handler,
+ [USBD_INTEN_ENDEPIN5_Pos ] = ev_dma_epin5_handler,
+ [USBD_INTEN_ENDEPIN6_Pos ] = ev_dma_epin6_handler,
+ [USBD_INTEN_ENDEPIN7_Pos ] = ev_dma_epin7_handler,
+ [USBD_INTEN_EP0DATADONE_Pos] = ev_setup_data_handler,
+ [USBD_INTEN_ENDISOIN_Pos ] = ev_dma_epin8_handler,
+ [USBD_INTEN_ENDEPOUT0_Pos ] = ev_dma_epout0_handler,
+ [USBD_INTEN_ENDEPOUT1_Pos ] = ev_dma_epout1_handler,
+ [USBD_INTEN_ENDEPOUT2_Pos ] = ev_dma_epout2_handler,
+ [USBD_INTEN_ENDEPOUT3_Pos ] = ev_dma_epout3_handler,
+ [USBD_INTEN_ENDEPOUT4_Pos ] = ev_dma_epout4_handler,
+ [USBD_INTEN_ENDEPOUT5_Pos ] = ev_dma_epout5_handler,
+ [USBD_INTEN_ENDEPOUT6_Pos ] = ev_dma_epout6_handler,
+ [USBD_INTEN_ENDEPOUT7_Pos ] = ev_dma_epout7_handler,
+ [USBD_INTEN_ENDISOOUT_Pos ] = ev_dma_epout8_handler,
+ [USBD_INTEN_SOF_Pos ] = ev_sof_handler,
+ [USBD_INTEN_USBEVENT_Pos ] = ev_usbevent_handler,
+ [USBD_INTEN_EP0SETUP_Pos ] = ev_setup_handler,
+ [USBD_INTEN_EPDATA_Pos ] = ev_epdata_handler
+};
+
+/**
+ * @name Interrupt handlers
+ *
+ * @{
+ */
+void USBD_IRQHandler(void)
+{
+ const uint32_t enabled = nrf_usbd_int_enable_get();
+ uint32_t to_process = enabled;
+ uint32_t active = 0;
+
+ /* Check all enabled interrupts */
+ while (to_process)
+ {
+ uint8_t event_nr = __CLZ(__RBIT(to_process));
+ if (nrf_usbd_event_get_and_clear((nrf_usbd_event_t)nrfx_bitpos_to_event(event_nr)))
+ {
+ active |= 1UL << event_nr;
+ }
+ to_process &= ~(1UL << event_nr);
+ }
+
+ if (nrf_drv_usbd_errata_104())
+ {
+ /* Event correcting */
+ if ((!m_dma_pending) && (0 != (active & (USBD_INTEN_SOF_Msk))))
+ {
+ uint8_t usbi, uoi, uii;
+ /* Testing */
+ *((volatile uint32_t *)(NRF_USBD_BASE + 0x800)) = 0x7A9;
+ uii = (uint8_t)(*((volatile uint32_t *)(NRF_USBD_BASE + 0x804)));
+ if (0 != uii)
+ {
+ uii &= (uint8_t)(*((volatile uint32_t *)(NRF_USBD_BASE + 0x804)));
+ }
+
+ *((volatile uint32_t *)(NRF_USBD_BASE + 0x800)) = 0x7AA;
+ uoi = (uint8_t)(*((volatile uint32_t *)(NRF_USBD_BASE + 0x804)));
+ if (0 != uoi)
+ {
+ uoi &= (uint8_t)(*((volatile uint32_t *)(NRF_USBD_BASE + 0x804)));
+ }
+ *((volatile uint32_t *)(NRF_USBD_BASE + 0x800)) = 0x7AB;
+ usbi = (uint8_t)(*((volatile uint32_t *)(NRF_USBD_BASE + 0x804)));
+ if (0 != usbi)
+ {
+ usbi &= (uint8_t)(*((volatile uint32_t *)(NRF_USBD_BASE + 0x804)));
+ }
+ /* Processing */
+ *((volatile uint32_t *)(NRF_USBD_BASE + 0x800)) = 0x7AC;
+ uii &= (uint8_t)*((volatile uint32_t *)(NRF_USBD_BASE + 0x804));
+ if (0 != uii)
+ {
+ uint8_t rb;
+ m_simulated_dataepstatus |= ((uint32_t)uii) << USBD_EPIN_BITPOS_0;
+ *((volatile uint32_t *)(NRF_USBD_BASE + 0x800)) = 0x7A9;
+ *((volatile uint32_t *)(NRF_USBD_BASE + 0x804)) = uii;
+ rb = (uint8_t)*((volatile uint32_t *)(NRF_USBD_BASE + 0x804));
+ NRF_DRV_USBD_LOG_PROTO1_FIX_PRINTF(" uii: 0x%.2x (0x%.2x)", uii, rb);
+ }
+
+ *((volatile uint32_t *)(NRF_USBD_BASE + 0x800)) = 0x7AD;
+ uoi &= (uint8_t)*((volatile uint32_t *)(NRF_USBD_BASE + 0x804));
+ if (0 != uoi)
+ {
+ uint8_t rb;
+ m_simulated_dataepstatus |= ((uint32_t)uoi) << USBD_EPOUT_BITPOS_0;
+ *((volatile uint32_t *)(NRF_USBD_BASE + 0x800)) = 0x7AA;
+ *((volatile uint32_t *)(NRF_USBD_BASE + 0x804)) = uoi;
+ rb = (uint8_t)*((volatile uint32_t *)(NRF_USBD_BASE + 0x804));
+ NRF_DRV_USBD_LOG_PROTO1_FIX_PRINTF(" uoi: 0x%.2u (0x%.2x)", uoi, rb);
+ }
+
+ *((volatile uint32_t *)(NRF_USBD_BASE + 0x800)) = 0x7AE;
+ usbi &= (uint8_t)*((volatile uint32_t *)(NRF_USBD_BASE + 0x804));
+ if (0 != usbi)
+ {
+ uint8_t rb;
+ if (usbi & 0x01)
+ {
+ active |= USBD_INTEN_EP0SETUP_Msk;
+ }
+ if (usbi & 0x10)
+ {
+ active |= USBD_INTEN_USBRESET_Msk;
+ }
+ *((volatile uint32_t *)(NRF_USBD_BASE + 0x800)) = 0x7AB;
+ *((volatile uint32_t *)(NRF_USBD_BASE + 0x804)) = usbi;
+ rb = (uint8_t)*((volatile uint32_t *)(NRF_USBD_BASE + 0x804));
+ NRF_DRV_USBD_LOG_PROTO1_FIX_PRINTF(" usbi: 0x%.2u (0x%.2x)", usbi, rb);
+ }
+
+ if (0 != (m_simulated_dataepstatus &
+ ~((1U << USBD_EPOUT_BITPOS_0) | (1U << USBD_EPIN_BITPOS_0))))
+ {
+ active |= enabled & NRF_USBD_INT_DATAEP_MASK;
+ }
+ if (0 != (m_simulated_dataepstatus &
+ ((1U << USBD_EPOUT_BITPOS_0) | (1U << USBD_EPIN_BITPOS_0))))
+ {
+ if (0 != (enabled & NRF_USBD_INT_EP0DATADONE_MASK))
+ {
+ m_simulated_dataepstatus &=
+ ~((1U << USBD_EPOUT_BITPOS_0) | (1U << USBD_EPIN_BITPOS_0));
+ active |= NRF_USBD_INT_EP0DATADONE_MASK;
+ }
+ }
+ }
+ }
+
+ /* Process the active interrupts */
+ bool setup_active = 0 != (active & NRF_USBD_INT_EP0SETUP_MASK);
+ active &= ~NRF_USBD_INT_EP0SETUP_MASK;
+
+ while (active)
+ {
+ uint8_t event_nr = __CLZ(__RBIT(active));
+ m_isr[event_nr]();
+ active &= ~(1UL << event_nr);
+ }
+ usbd_dmareq_process();
+
+ if (setup_active)
+ {
+ m_isr[USBD_INTEN_EP0SETUP_Pos]();
+ }
+}
+
+/** @} */
+/** @} */
+
+ret_code_t nrf_drv_usbd_init(nrf_drv_usbd_event_handler_t const event_handler)
+{
+ if (NULL == event_handler)
+ {
+ return NRF_ERROR_INVALID_PARAM;
+ }
+ if ( m_drv_state != NRFX_DRV_STATE_UNINITIALIZED)
+ {
+ return NRF_ERROR_INVALID_STATE;
+ }
+
+ m_event_handler = event_handler;
+ m_drv_state = NRFX_DRV_STATE_INITIALIZED;
+
+ uint8_t n;
+ for (n=0; n<NRF_USBD_EPIN_CNT; ++n)
+ {
+ nrf_drv_usbd_ep_t ep = NRF_DRV_USBD_EPIN(n);
+ nrf_drv_usbd_ep_max_packet_size_set(ep, NRF_USBD_EPISO_CHECK(ep) ?
+ (NRF_DRV_USBD_ISOSIZE / 2) : NRF_DRV_USBD_EPSIZE);
+ usbd_drv_ep_state_t * p_state = ep_state_access(ep);
+ p_state->status = NRF_USBD_EP_OK;
+ p_state->handler.feeder = NULL;
+ p_state->transfer_cnt = 0;
+ }
+ for (n=0; n<NRF_USBD_EPOUT_CNT; ++n)
+ {
+ nrf_drv_usbd_ep_t ep = NRF_DRV_USBD_EPOUT(n);
+ nrf_drv_usbd_ep_max_packet_size_set(ep, NRF_USBD_EPISO_CHECK(ep) ?
+ (NRF_DRV_USBD_ISOSIZE / 2) : NRF_DRV_USBD_EPSIZE);
+ usbd_drv_ep_state_t * p_state = ep_state_access(ep);
+ p_state->status = NRF_USBD_EP_OK;
+ p_state->handler.consumer = NULL;
+ p_state->transfer_cnt = 0;
+ }
+
+ return NRF_SUCCESS;
+}
+
+ret_code_t nrf_drv_usbd_uninit(void)
+{
+ if (m_drv_state != NRFX_DRV_STATE_INITIALIZED)
+ {
+ return NRF_ERROR_INVALID_STATE;
+ }
+
+ m_event_handler = NULL;
+ m_drv_state = NRFX_DRV_STATE_UNINITIALIZED;
+ return NRF_SUCCESS;
+}
+
+void nrf_drv_usbd_enable(void)
+{
+ ASSERT(m_drv_state == NRFX_DRV_STATE_INITIALIZED);
+
+ /* Prepare for READY event receiving */
+ nrf_usbd_eventcause_clear(NRF_USBD_EVENTCAUSE_READY_MASK);
+
+ if (nrf_drv_usbd_errata_187())
+ {
+ CRITICAL_REGION_ENTER();
+ if (*((volatile uint32_t *)(0x4006EC00)) == 0x00000000)
+ {
+ *((volatile uint32_t *)(0x4006EC00)) = 0x00009375;
+ *((volatile uint32_t *)(0x4006ED14)) = 0x00000003;
+ *((volatile uint32_t *)(0x4006EC00)) = 0x00009375;
+ }
+ else
+ {
+ *((volatile uint32_t *)(0x4006ED14)) = 0x00000003;
+ }
+ CRITICAL_REGION_EXIT();
+ }
+
+ if (nrf_drv_usbd_errata_171())
+ {
+ CRITICAL_REGION_ENTER();
+ if (*((volatile uint32_t *)(0x4006EC00)) == 0x00000000)
+ {
+ *((volatile uint32_t *)(0x4006EC00)) = 0x00009375;
+ *((volatile uint32_t *)(0x4006EC14)) = 0x000000C0;
+ *((volatile uint32_t *)(0x4006EC00)) = 0x00009375;
+ }
+ else
+ {
+ *((volatile uint32_t *)(0x4006EC14)) = 0x000000C0;
+ }
+ CRITICAL_REGION_EXIT();
+ }
+
+ /* Enable the peripheral */
+ nrf_usbd_enable();
+ /* Waiting for peripheral to enable, this should take a few us */
+ while (0 == (NRF_USBD_EVENTCAUSE_READY_MASK & nrf_usbd_eventcause_get()))
+ {
+ /* Empty loop */
+ }
+ nrf_usbd_eventcause_clear(NRF_USBD_EVENTCAUSE_READY_MASK);
+
+ if (nrf_drv_usbd_errata_171())
+ {
+ CRITICAL_REGION_ENTER();
+ if (*((volatile uint32_t *)(0x4006EC00)) == 0x00000000)
+ {
+ *((volatile uint32_t *)(0x4006EC00)) = 0x00009375;
+ *((volatile uint32_t *)(0x4006EC14)) = 0x00000000;
+ *((volatile uint32_t *)(0x4006EC00)) = 0x00009375;
+ }
+ else
+ {
+ *((volatile uint32_t *)(0x4006EC14)) = 0x00000000;
+ }
+
+ CRITICAL_REGION_EXIT();
+ }
+
+ if (nrf_drv_usbd_errata_187())
+ {
+ CRITICAL_REGION_ENTER();
+ if (*((volatile uint32_t *)(0x4006EC00)) == 0x00000000)
+ {
+ *((volatile uint32_t *)(0x4006EC00)) = 0x00009375;
+ *((volatile uint32_t *)(0x4006ED14)) = 0x00000000;
+ *((volatile uint32_t *)(0x4006EC00)) = 0x00009375;
+ }
+ else
+ {
+ *((volatile uint32_t *)(0x4006ED14)) = 0x00000000;
+ }
+ CRITICAL_REGION_EXIT();
+ }
+
+ if (nrf_drv_usbd_errata_166())
+ {
+ *((volatile uint32_t *)(NRF_USBD_BASE + 0x800)) = 0x7E3;
+ *((volatile uint32_t *)(NRF_USBD_BASE + 0x804)) = 0x40;
+ __ISB();
+ __DSB();
+ }
+
+ nrf_usbd_isosplit_set(NRF_USBD_ISOSPLIT_Half);
+
+ m_ep_ready = (((1U << NRF_USBD_EPIN_CNT) - 1U) << USBD_EPIN_BITPOS_0);
+ m_ep_dma_waiting = 0;
+ usbd_dma_pending_clear();
+ m_last_setup_dir = NRF_DRV_USBD_EPOUT0;
+
+ m_drv_state = NRFX_DRV_STATE_POWERED_ON;
+}
+
+void nrf_drv_usbd_disable(void)
+{
+ ASSERT(m_drv_state != NRFX_DRV_STATE_UNINITIALIZED);
+
+ /* Stop just in case */
+ nrf_drv_usbd_stop();
+
+ /* Disable all parts */
+ nrf_usbd_int_disable(nrf_usbd_int_enable_get());
+ nrf_usbd_disable();
+ usbd_dma_pending_clear();
+ m_drv_state = NRFX_DRV_STATE_INITIALIZED;
+}
+
+void nrf_drv_usbd_start(bool enable_sof)
+{
+ ASSERT(m_drv_state == NRFX_DRV_STATE_POWERED_ON);
+ m_bus_suspend = false;
+
+ uint32_t ints_to_enable =
+ NRF_USBD_INT_USBRESET_MASK |
+ NRF_USBD_INT_STARTED_MASK |
+ NRF_USBD_INT_ENDEPIN0_MASK |
+ NRF_USBD_INT_EP0DATADONE_MASK |
+ NRF_USBD_INT_ENDEPOUT0_MASK |
+ NRF_USBD_INT_USBEVENT_MASK |
+ NRF_USBD_INT_EP0SETUP_MASK |
+ NRF_USBD_INT_DATAEP_MASK;
+
+ if (enable_sof || nrf_drv_usbd_errata_104())
+ {
+ ints_to_enable |= NRF_USBD_INT_SOF_MASK;
+ }
+
+ /* Enable all required interrupts */
+ nrf_usbd_int_enable(ints_to_enable);
+
+ /* Enable interrupt globally */
+ NRFX_IRQ_PRIORITY_SET(USBD_IRQn, USBD_CONFIG_IRQ_PRIORITY);
+ NRFX_IRQ_ENABLE(USBD_IRQn);
+
+ /* Enable pullups */
+ nrf_usbd_pullup_enable();
+}
+
+void nrf_drv_usbd_stop(void)
+{
+ ASSERT(m_drv_state == NRFX_DRV_STATE_POWERED_ON);
+
+ if(NRFX_IRQ_IS_ENABLED(USBD_IRQn))
+ {
+ /* Abort transfers */
+ usbd_ep_abort_all();
+
+ /* Disable pullups */
+ nrf_usbd_pullup_disable();
+
+ /* Disable interrupt globally */
+ NRFX_IRQ_DISABLE(USBD_IRQn);
+
+ /* Disable all interrupts */
+ nrf_usbd_int_disable(~0U);
+ }
+}
+
+bool nrf_drv_usbd_is_initialized(void)
+{
+ return (m_drv_state >= NRFX_DRV_STATE_INITIALIZED);
+}
+
+bool nrf_drv_usbd_is_enabled(void)
+{
+ return (m_drv_state >= NRFX_DRV_STATE_POWERED_ON);
+}
+
+bool nrf_drv_usbd_is_started(void)
+{
+ return (nrf_drv_usbd_is_enabled() && NRFX_IRQ_IS_ENABLED(USBD_IRQn));
+}
+
+bool nrf_drv_usbd_suspend(void)
+{
+ bool suspended = false;
+
+ CRITICAL_REGION_ENTER();
+ if (m_bus_suspend)
+ {
+ usbd_ep_abort_all();
+
+ if (!(nrf_usbd_eventcause_get() & NRF_USBD_EVENTCAUSE_RESUME_MASK))
+ {
+ nrf_usbd_lowpower_enable();
+ if (nrf_usbd_eventcause_get() & NRF_USBD_EVENTCAUSE_RESUME_MASK)
+ {
+ nrf_usbd_lowpower_disable();
+ }
+ else
+ {
+ suspended = true;
+
+ if (nrf_drv_usbd_errata_171())
+ {
+ if (*((volatile uint32_t *)(0x4006EC00)) == 0x00000000)
+ {
+ *((volatile uint32_t *)(0x4006EC00)) = 0x00009375;
+ *((volatile uint32_t *)(0x4006EC14)) = 0x00000000;
+ *((volatile uint32_t *)(0x4006EC00)) = 0x00009375;
+ }
+ else
+ {
+ *((volatile uint32_t *)(0x4006EC14)) = 0x00000000;
+ }
+ }
+ }
+ }
+ }
+ CRITICAL_REGION_EXIT();
+
+ return suspended;
+}
+
+bool nrf_drv_usbd_wakeup_req(void)
+{
+ bool started = false;
+
+ CRITICAL_REGION_ENTER();
+ if (m_bus_suspend && nrf_usbd_lowpower_check())
+ {
+ nrf_usbd_lowpower_disable();
+ started = true;
+
+ if (nrf_drv_usbd_errata_171())
+ {
+ if (*((volatile uint32_t *)(0x4006EC00)) == 0x00000000)
+ {
+ *((volatile uint32_t *)(0x4006EC00)) = 0x00009375;
+ *((volatile uint32_t *)(0x4006EC14)) = 0x000000C0;
+ *((volatile uint32_t *)(0x4006EC00)) = 0x00009375;
+ }
+ else
+ {
+ *((volatile uint32_t *)(0x4006EC14)) = 0x000000C0;
+ }
+
+ }
+ }
+ CRITICAL_REGION_EXIT();
+
+ return started;
+}
+
+bool nrf_drv_usbd_suspend_check(void)
+{
+ return nrf_usbd_lowpower_check();
+}
+
+void nrf_drv_usbd_suspend_irq_config(void)
+{
+ nrf_usbd_int_disable(m_irq_disabled_in_suspend);
+}
+
+void nrf_drv_usbd_active_irq_config(void)
+{
+ nrf_usbd_int_enable(m_irq_disabled_in_suspend);
+}
+
+bool nrf_drv_usbd_bus_suspend_check(void)
+{
+ return m_bus_suspend;
+}
+
+void nrf_drv_usbd_ep_max_packet_size_set(nrf_drv_usbd_ep_t ep, uint16_t size)
+{
+ /* Only power of 2 size allowed */
+ ASSERT((size != 0) && (size & (size - 1)) == 0);
+ /* Packet size cannot be higher than maximum buffer size */
+ ASSERT( ( NRF_USBD_EPISO_CHECK(ep) && (size <= usbd_ep_iso_capacity(ep)))
+ ||
+ ((!NRF_USBD_EPISO_CHECK(ep)) && (size <= NRF_DRV_USBD_EPSIZE)));
+
+ usbd_drv_ep_state_t * p_state = ep_state_access(ep);
+ p_state->max_packet_size = size;
+}
+
+uint16_t nrf_drv_usbd_ep_max_packet_size_get(nrf_drv_usbd_ep_t ep)
+{
+ usbd_drv_ep_state_t const * p_state = ep_state_access(ep);
+ return p_state->max_packet_size;
+}
+
+bool nrf_drv_usbd_ep_enable_check(nrf_drv_usbd_ep_t ep)
+{
+ return nrf_usbd_ep_enable_check(ep_to_hal(ep));
+}
+
+void nrf_drv_usbd_ep_enable(nrf_drv_usbd_ep_t ep)
+{
+ nrf_usbd_int_enable(nrf_drv_usbd_ep_to_int(ep));
+
+ if(nrf_usbd_ep_enable_check(ep))
+ {
+ return;
+ }
+ nrf_usbd_ep_enable(ep_to_hal(ep));
+ if ((NRF_USBD_EP_NR_GET(ep) != 0) && NRF_USBD_EPOUT_CHECK(ep) && (!NRF_USBD_EPISO_CHECK(ep)))
+ {
+ CRITICAL_REGION_ENTER();
+ nrf_drv_usbd_transfer_out_drop(ep);
+ m_ep_dma_waiting &= ~(1U << ep2bit(ep));
+ CRITICAL_REGION_EXIT();
+ }
+}
+
+void nrf_drv_usbd_ep_disable(nrf_drv_usbd_ep_t ep)
+{
+ usbd_ep_abort(ep);
+ nrf_usbd_ep_disable(ep_to_hal(ep));
+ nrf_usbd_int_disable(nrf_drv_usbd_ep_to_int(ep));
+}
+
+void nrf_drv_usbd_ep_default_config(void)
+{
+ nrf_usbd_int_disable(
+ NRF_USBD_INT_ENDEPIN1_MASK |
+ NRF_USBD_INT_ENDEPIN2_MASK |
+ NRF_USBD_INT_ENDEPIN3_MASK |
+ NRF_USBD_INT_ENDEPIN4_MASK |
+ NRF_USBD_INT_ENDEPIN5_MASK |
+ NRF_USBD_INT_ENDEPIN6_MASK |
+ NRF_USBD_INT_ENDEPIN7_MASK |
+ NRF_USBD_INT_ENDISOIN0_MASK |
+ NRF_USBD_INT_ENDEPOUT1_MASK |
+ NRF_USBD_INT_ENDEPOUT2_MASK |
+ NRF_USBD_INT_ENDEPOUT3_MASK |
+ NRF_USBD_INT_ENDEPOUT4_MASK |
+ NRF_USBD_INT_ENDEPOUT5_MASK |
+ NRF_USBD_INT_ENDEPOUT6_MASK |
+ NRF_USBD_INT_ENDEPOUT7_MASK |
+ NRF_USBD_INT_ENDISOOUT0_MASK
+ );
+ nrf_usbd_int_enable(NRF_USBD_INT_ENDEPIN0_MASK | NRF_USBD_INT_ENDEPOUT0_MASK);
+ nrf_usbd_ep_all_disable();
+}
+
+ret_code_t nrf_drv_usbd_ep_transfer(
+ nrf_drv_usbd_ep_t ep,
+ nrf_drv_usbd_transfer_t const * const p_transfer)
+{
+ ret_code_t ret;
+ const uint8_t ep_bitpos = ep2bit(ep);
+ ASSERT(NULL != p_transfer);
+
+ CRITICAL_REGION_ENTER();
+ /* Setup data transaction can go only in one direction at a time */
+ if ((NRF_USBD_EP_NR_GET(ep) == 0) && (ep != m_last_setup_dir))
+ {
+ ret = NRF_ERROR_INVALID_ADDR;
+ if (NRF_USBD_FAILED_TRANSFERS_DEBUG && (NRF_USBD_ISO_DEBUG || (!NRF_USBD_EPISO_CHECK(ep))))
+ {
+ NRF_LOG_DEBUG("USB driver: Transfer failed: Invalid EPr\n");
+ }
+ }
+ else if ((m_ep_dma_waiting | ((~m_ep_ready) & USBD_EPIN_BIT_MASK)) & (1U << ep_bitpos))
+ {
+ /* IN (Device -> Host) transfer has to be transmitted out to allow new transmission */
+ ret = NRF_ERROR_BUSY;
+ if (NRF_USBD_FAILED_TRANSFERS_DEBUG)
+ {
+ NRF_LOG_DEBUG("USB driver: Transfer failed: EP is busy");
+ }
+ }
+ else
+ {
+ usbd_drv_ep_state_t * p_state = ep_state_access(ep);
+ /* Prepare transfer context and handler description */
+ nrf_drv_usbd_transfer_t * p_context;
+ if (NRF_USBD_EPIN_CHECK(ep))
+ {
+ p_context = m_ep_feeder_state + NRF_USBD_EP_NR_GET(ep);
+ if (nrfx_is_in_ram(p_transfer->p_data.tx))
+ {
+ /* RAM */
+ if (0 == (p_transfer->flags & NRF_DRV_USBD_TRANSFER_ZLP_FLAG))
+ {
+ p_state->handler.feeder = nrf_drv_usbd_feeder_ram;
+ if (NRF_USBD_ISO_DEBUG || (!NRF_USBD_EPISO_CHECK(ep)))
+ {
+ NRF_LOG_DEBUG(
+ "USB driver: Transfer called on endpoint %x, size: %u, mode: "
+ "RAM",
+ ep,
+ p_transfer->size);
+ }
+ }
+ else
+ {
+ p_state->handler.feeder = nrf_drv_usbd_feeder_ram_zlp;
+ if (NRF_USBD_ISO_DEBUG || (!NRF_USBD_EPISO_CHECK(ep)))
+ {
+ NRF_LOG_DEBUG(
+ "USB driver: Transfer called on endpoint %x, size: %u, mode: "
+ "RAM_ZLP",
+ ep,
+ p_transfer->size);
+ }
+ }
+ }
+ else
+ {
+ /* Flash */
+ if (0 == (p_transfer->flags & NRF_DRV_USBD_TRANSFER_ZLP_FLAG))
+ {
+ p_state->handler.feeder = nrf_drv_usbd_feeder_flash;
+ if (NRF_USBD_ISO_DEBUG || (!NRF_USBD_EPISO_CHECK(ep)))
+ {
+ NRF_LOG_DEBUG(
+ "USB driver: Transfer called on endpoint %x, size: %u, mode: "
+ "FLASH",
+ ep,
+ p_transfer->size);
+ }
+ }
+ else
+ {
+ p_state->handler.feeder = nrf_drv_usbd_feeder_flash_zlp;
+ if (NRF_USBD_ISO_DEBUG || (!NRF_USBD_EPISO_CHECK(ep)))
+ {
+ NRF_LOG_DEBUG(
+ "USB driver: Transfer called on endpoint %x, size: %u, mode: "
+ "FLASH_ZLP",
+ ep,
+ p_transfer->size);
+ }
+ }
+ }
+ }
+ else
+ {
+ p_context = m_ep_consumer_state + NRF_USBD_EP_NR_GET(ep);
+ ASSERT((p_transfer->p_data.rx == NULL) || (nrfx_is_in_ram(p_transfer->p_data.rx)));
+ p_state->handler.consumer = nrf_drv_usbd_consumer;
+ }
+ *p_context = *p_transfer;
+ p_state->p_context = p_context;
+
+ p_state->transfer_cnt = 0;
+ p_state->status = NRF_USBD_EP_OK;
+ m_ep_dma_waiting |= 1U << ep_bitpos;
+ ret = NRF_SUCCESS;
+ usbd_int_rise();
+ }
+ CRITICAL_REGION_EXIT();
+ return ret;
+}
+
+ret_code_t nrf_drv_usbd_ep_handled_transfer(
+ nrf_drv_usbd_ep_t ep,
+ nrf_drv_usbd_handler_desc_t const * const p_handler)
+{
+ ret_code_t ret;
+ const uint8_t ep_bitpos = ep2bit(ep);
+ ASSERT(NULL != p_handler);
+
+ CRITICAL_REGION_ENTER();
+ /* Setup data transaction can go only in one direction at a time */
+ if ((NRF_USBD_EP_NR_GET(ep) == 0) && (ep != m_last_setup_dir))
+ {
+ ret = NRF_ERROR_INVALID_ADDR;
+ if (NRF_USBD_FAILED_TRANSFERS_DEBUG && (NRF_USBD_ISO_DEBUG || (!NRF_USBD_EPISO_CHECK(ep))))
+ {
+ NRF_LOG_DEBUG("USB driver: Transfer failed: Invalid EP");
+ }
+ }
+ else if ((m_ep_dma_waiting | ((~m_ep_ready) & USBD_EPIN_BIT_MASK)) & (1U << ep_bitpos))
+ {
+ /* IN (Device -> Host) transfer has to be transmitted out to allow a new transmission */
+ ret = NRF_ERROR_BUSY;
+ if (NRF_USBD_FAILED_TRANSFERS_DEBUG && (NRF_USBD_ISO_DEBUG || (!NRF_USBD_EPISO_CHECK(ep))))
+ {
+ NRF_LOG_DEBUG("USB driver: Transfer failed: EP is busy");\
+ }
+ }
+ else
+ {
+ /* Transfer can be configured now */
+ usbd_drv_ep_state_t * p_state = ep_state_access(ep);
+
+ p_state->transfer_cnt = 0;
+ p_state->handler = p_handler->handler;
+ p_state->p_context = p_handler->p_context;
+ p_state->status = NRF_USBD_EP_OK;
+ m_ep_dma_waiting |= 1U << ep_bitpos;
+
+ ret = NRF_SUCCESS;
+ if (NRF_USBD_ISO_DEBUG || (!NRF_USBD_EPISO_CHECK(ep)))
+ {
+ NRF_LOG_DEBUG("USB driver: Transfer called on endpoint %x, mode: Handler", ep);
+ }
+ usbd_int_rise();
+ }
+ CRITICAL_REGION_EXIT();
+ return ret;
+}
+
+void * nrf_drv_usbd_feeder_buffer_get(void)
+{
+ return m_tx_buffer;
+}
+
+ret_code_t nrf_drv_usbd_ep_status_get(nrf_drv_usbd_ep_t ep, size_t * p_size)
+{
+ ret_code_t ret;
+
+ usbd_drv_ep_state_t const * p_state = ep_state_access(ep);
+ CRITICAL_REGION_ENTER();
+ *p_size = p_state->transfer_cnt;
+ ret = (p_state->handler.consumer == NULL) ? p_state->status : NRF_ERROR_BUSY;
+ CRITICAL_REGION_EXIT();
+ return ret;
+}
+
+size_t nrf_drv_usbd_epout_size_get(nrf_drv_usbd_ep_t ep)
+{
+ return nrf_usbd_epout_size_get(ep_to_hal(ep));
+}
+
+bool nrf_drv_usbd_ep_is_busy(nrf_drv_usbd_ep_t ep)
+{
+ return (0 != ((m_ep_dma_waiting | ((~m_ep_ready) & USBD_EPIN_BIT_MASK)) & (1U << ep2bit(ep))));
+}
+
+void nrf_drv_usbd_ep_stall(nrf_drv_usbd_ep_t ep)
+{
+ NRF_LOG_DEBUG("USB: EP %x stalled.", ep);
+ nrf_usbd_ep_stall(ep_to_hal(ep));
+}
+
+void nrf_drv_usbd_ep_stall_clear(nrf_drv_usbd_ep_t ep)
+{
+ nrf_usbd_ep_unstall(ep_to_hal(ep));
+}
+
+bool nrf_drv_usbd_ep_stall_check(nrf_drv_usbd_ep_t ep)
+{
+ return nrf_usbd_ep_is_stall(ep_to_hal(ep));
+}
+
+void nrf_drv_usbd_ep_dtoggle_clear(nrf_drv_usbd_ep_t ep)
+{
+ nrf_usbd_dtoggle_set(ep, NRF_USBD_DTOGGLE_DATA0);
+}
+
+void nrf_drv_usbd_setup_get(nrf_drv_usbd_setup_t * const p_setup)
+{
+ memset(p_setup, 0, sizeof(nrf_drv_usbd_setup_t));
+ p_setup->bmRequestType = nrf_usbd_setup_bmrequesttype_get();
+ p_setup->bmRequest = nrf_usbd_setup_brequest_get();
+ p_setup->wValue = nrf_usbd_setup_wvalue_get();
+ p_setup->wIndex = nrf_usbd_setup_windex_get();
+ p_setup->wLength = nrf_usbd_setup_wlength_get();
+}
+
+void nrf_drv_usbd_setup_data_clear(void)
+{
+ if (nrf_drv_usbd_errata_104())
+ {
+ /* For this fix to work properly, it must be ensured that the task is
+ * executed twice one after another - blocking ISR. This is however a temporary
+ * solution to be used only before production version of the chip. */
+ uint32_t primask_copy = __get_PRIMASK();
+ __disable_irq();
+ nrf_usbd_task_trigger(NRF_USBD_TASK_EP0RCVOUT);
+ nrf_usbd_task_trigger(NRF_USBD_TASK_EP0RCVOUT);
+ __set_PRIMASK(primask_copy);
+ }
+ else
+ {
+ nrf_usbd_task_trigger(NRF_USBD_TASK_EP0RCVOUT);
+ }
+}
+
+void nrf_drv_usbd_setup_clear(void)
+{
+ nrf_usbd_task_trigger(NRF_USBD_TASK_EP0STATUS);
+}
+
+void nrf_drv_usbd_setup_stall(void)
+{
+ NRF_LOG_DEBUG("Setup stalled.");
+ nrf_usbd_task_trigger(NRF_USBD_TASK_EP0STALL);
+}
+
+nrf_drv_usbd_ep_t nrf_drv_usbd_last_setup_dir_get(void)
+{
+ return m_last_setup_dir;
+}
+
+void nrf_drv_usbd_transfer_out_drop(nrf_drv_usbd_ep_t ep)
+{
+ ASSERT(NRF_USBD_EPOUT_CHECK(ep));
+
+ if (nrf_drv_usbd_errata_sizeepout_rw())
+ {
+ CRITICAL_REGION_ENTER();
+ m_ep_ready &= ~(1U << ep2bit(ep));
+ *((volatile uint32_t *)(NRF_USBD_BASE + 0x800)) = 0x7C5 + (2u * NRF_USBD_EP_NR_GET(ep));
+ *((volatile uint32_t *)(NRF_USBD_BASE + 0x804)) = 0;
+ UNUSED_VARIABLE(((volatile uint32_t *)(NRF_USBD_BASE + 0x804)));
+ CRITICAL_REGION_EXIT();
+ }
+ else
+ {
+ CRITICAL_REGION_ENTER();
+ m_ep_ready &= ~(1U << ep2bit(ep));
+ if (!NRF_USBD_EPISO_CHECK(ep))
+ {
+ nrf_usbd_epout_clear(ep);
+ }
+ CRITICAL_REGION_EXIT();
+ }
+}
+
+#endif // NRF_MODULE_ENABLED(USBD)
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/drivers_nrf/usbd/nrf_drv_usbd.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/drivers_nrf/usbd/nrf_drv_usbd.h
new file mode 100644
index 0000000..24a14f4
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/drivers_nrf/usbd/nrf_drv_usbd.h
@@ -0,0 +1,943 @@
+/**
+ * Copyright (c) 2016 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+
+#ifndef NRF_DRV_USBD_H__
+#define NRF_DRV_USBD_H__
+
+#include "sdk_errors.h"
+#include "nrf_usbd.h"
+#include <stdint.h>
+#include <stdbool.h>
+#include "app_util.h"
+#include "nrf_drv_usbd_errata.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @defgroup nrf_drv_usbd USB Device HAL and driver
+ * @ingroup nrf_drivers
+ * @brief @tagAPI52840 USB Device APIs.
+ * @details The USB Device HAL provides basic APIs for accessing
+ * the registers of the USBD.
+ * The USB Device driver provides APIs on a higher level.
+ *
+ * @{
+ */
+
+/**
+ * @name Possible schemes of DMA scheduling
+ *
+ * Definition of available configuration constants used by DMA scheduler
+ * @{
+ */
+ /**
+ * @brief Highly prioritized access
+ *
+ * Endpoint with lower number has always higher priority and its data would
+ * be transfered first.
+ * OUT endpoints ale processed before IN endpoints
+ */
+ #define NRF_DRV_USBD_DMASCHEDULER_PRIORITIZED 0
+
+ /**
+ * @brief Round robin scheme
+ *
+ * All endpoints are processed in round-robin scheme.
+ * It means that when one endpoint is processed next in order would be
+ * the nearest with lower number.
+ * When no endpoints with lower number requires processing - then
+ * all endpoints from 0 are tested.
+ */
+ #define NRF_DRV_USBD_DMASCHEDULER_ROUNDROBIN 1
+
+/** @} */
+
+/**
+ * @brief Number of bytes in the endpoint
+ *
+ * Constant that informs about endpoint size
+ */
+#define NRF_DRV_USBD_EPSIZE 64
+
+/**
+ * @brief Number of bytes for isochronous endpoints
+ *
+ * Number of bytes for isochronous endpoints in total.
+ * This number would be shared between IN and OUT endpoint.
+ * It may be also assigned totaly to one endpoint.
+ * @sa nrf_usbd_isosplit_set
+ * @sa nrf_usbd_isosplit_get
+ */
+#define NRF_DRV_USBD_ISOSIZE 1024
+
+/**
+ * @brief The size of internal feeder buffer.
+ *
+ * @sa nrf_drv_usbd_feeder_buffer_get
+ */
+#define NRF_DRV_USBD_FEEDER_BUFFER_SIZE NRF_DRV_USBD_EPSIZE
+
+/**
+ * @name Macros for creating endpoint identifiers
+ *
+ * Auxiliary macros to be used to create Endpoint identifier that is compatible
+ * with USB specification.
+ * @{
+ */
+
+ /**
+ * @brief Create identifier for IN endpoint
+ *
+ * Simple macro to create IN endpoint identifier for given endpoint number.
+ *
+ * @param[in] n Endpoint number.
+ *
+ * @return Endpoint identifier that connects endpoint number and endpoint direction.
+ */
+ #define NRF_DRV_USBD_EPIN(n) ((nrf_drv_usbd_ep_t)NRF_USBD_EPIN(n))
+ /**
+ * @brief Create identifier for OUT endpoint
+ *
+ * Simple macro to create OUT endpoint identifier for given endpoint number.
+ *
+ * @param[in] n Endpoint number.
+ *
+ * @return Endpoint identifier that connects endpoint number and endpoint direction.
+ */
+ #define NRF_DRV_USBD_EPOUT(n) ((nrf_drv_usbd_ep_t)NRF_USBD_EPOUT(n))
+
+/** @} */
+
+/**
+ * @brief Endpoint identifier
+ *
+ * Endpoint identifier used in the driver.
+ * This endpoint number is consistent with USB 2.0 specification.
+ */
+typedef enum
+{
+ NRF_DRV_USBD_EPOUT0 = NRF_USBD_EPOUT(0), /**< Endpoint OUT 0 */
+ NRF_DRV_USBD_EPOUT1 = NRF_USBD_EPOUT(1), /**< Endpoint OUT 1 */
+ NRF_DRV_USBD_EPOUT2 = NRF_USBD_EPOUT(2), /**< Endpoint OUT 2 */
+ NRF_DRV_USBD_EPOUT3 = NRF_USBD_EPOUT(3), /**< Endpoint OUT 3 */
+ NRF_DRV_USBD_EPOUT4 = NRF_USBD_EPOUT(4), /**< Endpoint OUT 4 */
+ NRF_DRV_USBD_EPOUT5 = NRF_USBD_EPOUT(5), /**< Endpoint OUT 5 */
+ NRF_DRV_USBD_EPOUT6 = NRF_USBD_EPOUT(6), /**< Endpoint OUT 6 */
+ NRF_DRV_USBD_EPOUT7 = NRF_USBD_EPOUT(7), /**< Endpoint OUT 7 */
+ NRF_DRV_USBD_EPOUT8 = NRF_USBD_EPOUT(8), /**< Endpoint OUT 8 */
+
+ NRF_DRV_USBD_EPIN0 = NRF_USBD_EPIN(0), /**< Endpoint IN 0 */
+ NRF_DRV_USBD_EPIN1 = NRF_USBD_EPIN(1), /**< Endpoint IN 1 */
+ NRF_DRV_USBD_EPIN2 = NRF_USBD_EPIN(2), /**< Endpoint IN 2 */
+ NRF_DRV_USBD_EPIN3 = NRF_USBD_EPIN(3), /**< Endpoint IN 3 */
+ NRF_DRV_USBD_EPIN4 = NRF_USBD_EPIN(4), /**< Endpoint IN 4 */
+ NRF_DRV_USBD_EPIN5 = NRF_USBD_EPIN(5), /**< Endpoint IN 5 */
+ NRF_DRV_USBD_EPIN6 = NRF_USBD_EPIN(6), /**< Endpoint IN 6 */
+ NRF_DRV_USBD_EPIN7 = NRF_USBD_EPIN(7), /**< Endpoint IN 7 */
+ NRF_DRV_USBD_EPIN8 = NRF_USBD_EPIN(8), /**< Endpoint IN 8 */
+}nrf_drv_usbd_ep_t;
+
+/**
+ * @brief Events generated by the library
+ *
+ * Enumeration of possible events that may be generated by the library.
+ */
+typedef enum
+{
+ NRF_DRV_USBD_EVT_SOF, /**< Start Of Frame event on USB bus detected */
+ NRF_DRV_USBD_EVT_RESET, /**< Reset condition on USB bus detected */
+ NRF_DRV_USBD_EVT_SUSPEND, /**< This device should go to suspend mode now */
+ NRF_DRV_USBD_EVT_RESUME, /**< This device should resume from suspend now */
+ NRF_DRV_USBD_EVT_WUREQ, /**< Wakeup request - the USBD peripheral is ready to generate WAKEUP signal after exiting low power mode. */
+ NRF_DRV_USBD_EVT_SETUP, /**< Setup frame received and decoded */
+ NRF_DRV_USBD_EVT_EPTRANSFER, /**<
+ * For Rx (OUT: Host->Device):
+ * 1. The packet has been received but there is no buffer prepared for transfer already.
+ * 2. Whole transfer has been finished
+ *
+ * For Tx (IN: Device->Host):
+ * The last packet from requested transfer has been transfered over USB bus and acknowledged
+ */
+ NRF_DRV_USBD_EVT_CNT /**< Number of defined events */
+}nrf_drv_usbd_event_type_t;
+
+/**
+ * @brief Possible endpoint error codes
+ *
+ * Error codes that may be returned with @ref NRF_DRV_USBD_EVT_EPTRANSFER
+ */
+typedef enum
+{
+ NRF_USBD_EP_OK, /**< No error */
+ NRF_USBD_EP_WAITING, /**< Data received, no buffer prepared already - waiting for configured transfer */
+ NRF_USBD_EP_OVERLOAD, /**< Received number of bytes cannot fit given buffer
+ * This error would also be returned when next_transfer function has been defined
+ * but currently received data cannot fit completely in current buffer.
+ * No data split from single endpoint transmission is supported.
+ *
+ * When this error is reported - data is left inside endpoint buffer.
+ * Clear endpoint or prepare new buffer and read it.
+ */
+ NRF_USBD_EP_ABORTED, /**< EP0 transfer can be aborted when new setup comes.
+ * Any other transfer can be aborted by USB reset or library stopping.
+ */
+}nrf_drv_usbd_ep_status_t;
+
+
+/**
+ * @brief Event structure
+ *
+ * Structure passed to event handler
+ */
+typedef struct
+{
+ nrf_drv_usbd_event_type_t type;
+ union
+ {
+ struct{
+ uint16_t framecnt; //!< Current value of frame counter
+ }sof; //!< Data aviable for @ref NRF_DRV_USBD_EVT_SOF
+ struct{
+ nrf_drv_usbd_ep_t ep; //!< Endpoint number
+ }isocrc;
+ struct{
+ nrf_drv_usbd_ep_t ep; //!< Endpoint number
+ nrf_drv_usbd_ep_status_t status; //!< Status for the endpoint
+ }eptransfer;
+ }data;
+}nrf_drv_usbd_evt_t;
+
+/**
+ * @brief USBD event callback function type.
+ *
+ * @param[in] p_event Event information structure.
+ */
+typedef void (*nrf_drv_usbd_event_handler_t)(nrf_drv_usbd_evt_t const * const p_event);
+
+/**
+ * @brief Universal data pointer.
+ *
+ * Universal data pointer that can be used for any type of transfer.
+ */
+typedef union
+{
+ void const * tx; //!< Constant TX buffer pointer.
+ void * rx; //!< Writable RX buffer pointer.
+ uint32_t ptr; //!< Numeric value used internally by the library.
+}nrf_drv_usbd_data_ptr_t;
+
+/**
+ * @brief Structure to be filled with information about the next transfer.
+ *
+ * This is used mainly for transfer feeders and consumers.
+ * It describes a single endpoint transfer and therefore the size of the buffer
+ * can never be higher than the endpoint size.
+ */
+typedef struct
+{
+ nrf_drv_usbd_data_ptr_t p_data; //!< Union with available data pointers used by the library.
+ size_t size; //!< Size of the requested transfer.
+}nrf_drv_usbd_ep_transfer_t;
+
+/**
+ * @brief Flags for the current transfer.
+ *
+ * Flags configured for the transfer that can be merged using the bitwise 'or' operator (|).
+ */
+typedef enum
+{
+ NRF_DRV_USBD_TRANSFER_ZLP_FLAG = 1U << 0, //!< Add a zero-length packet.
+}nrf_drv_usbd_transfer_flags_t;
+
+/**
+ * @brief Total transfer configuration.
+ *
+ * This structure is used to configure total transfer information.
+ * It is used by internal built-in feeders and consumers.
+ */
+typedef struct
+{
+ nrf_drv_usbd_data_ptr_t p_data; //!< Union with available data pointers used by the library.
+ size_t size; //!< Total size of the requested transfer.
+ uint32_t flags; //!< Transfer flags.
+ /**< Use the @ref nrf_drv_usbd_transfer_flags_t values. */
+}nrf_drv_usbd_transfer_t;
+
+
+/**
+ * @brief Auxiliary macro for declaring IN transfer description with flags.
+ *
+ * The base macro for creating transfers with any configuration option.
+ *
+ * @param name Instance name.
+ * @param tx_buff Buffer to transfer.
+ * @param tx_size Transfer size.
+ * @param tx_flags Flags for the transfer (see @ref nrf_drv_usbd_transfer_flags_t).
+ *
+ * @return Configured variable with total transfer description.
+ */
+#define NRF_DRV_USBD_TRANSFER_IN_FLAGS(name, tx_buff, tx_size, tx_flags) \
+ const nrf_drv_usbd_transfer_t name = { \
+ .p_data = { .tx = (tx_buff) }, \
+ .size = (tx_size), \
+ .flags = (tx_flags) \
+ }
+
+/**
+ * @brief Helper macro for declaring IN transfer description
+ *
+ * Normal transfer mode, no ZLP would be automatically generated.
+ *
+ * @sa nrf_drv_usbd_transfer_t
+ * @sa NRF_DRV_USBD_TRANSFER_IN_ZLP
+ *
+ * @param name Instance name
+ * @param tx_buff Buffer to transfer
+ * @param tx_size Transfer size
+ *
+ * @return Configured variable with total transfer description
+ *
+ */
+#define NRF_DRV_USBD_TRANSFER_IN(name, tx_buff, tx_size) \
+ NRF_DRV_USBD_TRANSFER_IN_FLAGS(name, tx_buff, tx_size, 0)
+
+/**
+ * @brief Helper macro for declaring IN transfer description
+ *
+ * ZLP mode - Zero Length Packet would be generated on the end of the transfer
+ * (always!).
+ *
+ * @sa nrf_drv_usbd_transfer_t
+ * @sa NRF_DRV_USBD_TRANSFER_IN
+ *
+ * @param name Instance name
+ * @param tx_buff Buffer to transfer
+ * @param tx_size Transfer size
+ *
+ * @return Configured variable with total transfer description
+ */
+#define NRF_DRV_USBD_TRANSFER_IN_ZLP(name, tx_buff, tx_size) \
+ NRF_DRV_USBD_TRANSFER_IN_FLAGS( \
+ name, \
+ tx_buff, \
+ tx_size, \
+ NRF_DRV_USBD_TRANSFER_ZLP_FLAG)
+
+/**
+ * @brief Helper macro for declaring OUT transfer item (@ref nrf_drv_usbd_transfer_t)
+ *
+ * @param name Instance name
+ * @param rx_buff Buffer to transfer
+ * @param rx_size Transfer size
+ * */
+#define NRF_DRV_USBD_TRANSFER_OUT(name, rx_buff, rx_size) \
+ const nrf_drv_usbd_transfer_t name = { \
+ .p_data = { .rx = (rx_buff) }, \
+ .size = (rx_size), \
+ .flags = 0 \
+ }
+
+/**
+ * @brief USBD transfer feeder.
+ *
+ * Pointer for a transfer feeder.
+ * Transfer feeder is a feedback function used to prepare a single
+ * TX (Device->Host) endpoint transfer.
+ *
+ * The transfers provided by the feeder must be simple:
+ * - The size of the transfer provided by this function is limited to a single endpoint buffer.
+ * Bigger transfers are not handled automatically in this case.
+ * - Flash transfers are not automatically supported- you must copy them to the RAM buffer before.
+ *
+ * @note
+ * This function may use @ref nrf_drv_usbd_feeder_buffer_get to gain a temporary buffer
+ * that can be used to prepare transfer.
+ *
+ * @param[out] p_next Structure with the data for the next transfer to be filled.
+ * Required only if the function returns true.
+ * @param[in,out] p_context Context variable configured with the transfer.
+ * @param[in] ep_size The endpoint size.
+ *
+ * @retval false The current transfer is the last one - you do not need to call
+ * the function again.
+ * @retval true There is more data to be prepared and when the current transfer
+ * finishes, the feeder function is expected to be called again.
+ */
+typedef bool (*nrf_drv_usbd_feeder_t)(
+ nrf_drv_usbd_ep_transfer_t * p_next,
+ void * p_context,
+ size_t ep_size);
+
+/**
+ * @brief USBD transfer consumer.
+ *
+ * Pointer for a transfer consumer.
+ * Transfer consumer is a feedback function used to prepare a single
+ * RX (Host->Device) endpoint transfer.
+ *
+ * The transfer must provide a buffer big enough to fit the whole data from the endpoint.
+ * Otherwise, the NRF_USBD_EP_OVERLOAD event is generated.
+ *
+ * @param[out] p_next Structure with the data for the next transfer to be filled.
+ * Required only if the function returns true.
+ * @param[in,out] p_context Context variable configured with the transfer.
+ * @param[in] ep_size The endpoint size.
+ * @param[in] data_size Number of received bytes in the endpoint buffer.
+ *
+ * @retval false Current transfer is the last one - you do not need to call
+ * the function again.
+ * @retval true There is more data to be prepared and when current transfer
+ * finishes, the feeder function is expected to be called again.
+ */
+typedef bool (*nrf_drv_usbd_consumer_t)(
+ nrf_drv_usbd_ep_transfer_t * p_next,
+ void * p_context,
+ size_t ep_size,
+ size_t data_size);
+
+/**
+ * @brief Universal transfer handler.
+ *
+ * Union with feeder and consumer function pointer.
+ */
+typedef union
+{
+ nrf_drv_usbd_feeder_t feeder; //!< Feeder function pointer.
+ nrf_drv_usbd_consumer_t consumer; //!< Consumer function pointer.
+}nrf_drv_usbd_handler_t;
+
+/**
+ * @brief USBD transfer descriptor.
+ *
+ * Universal structure that may hold the setup for callback configuration for
+ * IN or OUT type of the transfer.
+ */
+typedef struct
+{
+ nrf_drv_usbd_handler_t handler; //!< Handler for the current transfer, function pointer.
+ void * p_context; //!< Context for the transfer handler.
+}nrf_drv_usbd_handler_desc_t;
+
+/**
+ * @brief Setup packet structure
+ *
+ * Structure that contains interpreted SETUP packet.
+ */
+typedef struct
+{
+ uint8_t bmRequestType; //!< byte 0
+ uint8_t bmRequest; //!< byte 1
+ uint16_t wValue; //!< byte 2
+ uint16_t wIndex; //!< byte 4, 5
+ uint16_t wLength; //!< byte 6, 7
+}nrf_drv_usbd_setup_t;
+
+/**
+ * @brief Library initialization
+ *
+ * @param[in] event_handler Event handler provided by the user.
+ */
+ret_code_t nrf_drv_usbd_init(nrf_drv_usbd_event_handler_t const event_handler);
+
+/**
+ * @brief Library deinitialization
+ */
+ret_code_t nrf_drv_usbd_uninit(void);
+
+/**
+ * @brief Enable the USBD port
+ *
+ * After calling this function USBD peripheral would be enabled.
+ * The USB LDO would be enabled.
+ * Enabled USBD peripheral would request HFCLK.
+ * This function does not enable external oscillator, so if it is not enabled by other part of the
+ * program after enabling USBD driver HFINT would be used for the USBD peripheral.
+ * It is perfectly fine until USBD is started. See @ref nrf_drv_usbd_start.
+ *
+ * In normal situation this function should be called in reaction to USBDETECTED
+ * event from POWER peripheral.
+ *
+ * Interrupts and USB pins pull-up would stay disabled until @ref nrf_drv_usbd_start
+ * function is called.
+ */
+void nrf_drv_usbd_enable(void);
+
+/**
+ * @brief Disable the USBD port
+ *
+ * After calling this function USBD peripheral would be disabled.
+ * No events would be detected or processed by the library.
+ * Clock for the peripheral would be disconnected.
+ */
+void nrf_drv_usbd_disable(void);
+
+/**
+ * @brief Start USB functionality
+ *
+ * After calling this function USBD peripheral should be fully functional
+ * and all new incoming events / interrupts would be processed by the library.
+ *
+ * Also only after calling this function host sees new connected device.
+ *
+ * Call this function when USBD power LDO regulator is ready - on USBPWRRDY event
+ * from POWER peripheral.
+ *
+ * Before USBD interrupts are enabled, external HFXO is requested.
+ *
+ * @param enable_sof The flag that is used to enable SOF processing.
+ * If it is false, SOF interrupt is left disabled and will not be generated.
+ * This improves power saving if SOF is not required.
+ *
+ * @note If the isochronous endpoints are going to be used,
+ * it is required to enable the SOF.
+ * In other case any isochronous endpoint would stay busy
+ * after first transmission.
+ */
+void nrf_drv_usbd_start(bool enable_sof);
+
+/**
+ * @brief Stop USB functionality
+ *
+ * This function disables USBD pull-up and interrupts.
+ *
+ * The HFXO request is released in this function.
+ *
+ * @note
+ * This function can also be used to logically disconnect USB from the HOST that
+ * would force it to enumerate device after calling @ref nrf_drv_usbd_start.
+ */
+void nrf_drv_usbd_stop(void);
+
+/**
+ * @brief Check if driver is initialized
+ *
+ * @retval false Driver is not initialized
+ * @retval true Driver is initialized
+ */
+bool nrf_drv_usbd_is_initialized(void);
+
+/**
+ * @brief Check if driver is enabled
+ *
+ * @retval false Driver is disabled
+ * @retval true Driver is enabled
+ */
+bool nrf_drv_usbd_is_enabled(void);
+
+/**
+ * @brief Check if driver is started
+ *
+ * @retval false Driver is not started
+ * @retval true Driver is started (fully functional)
+ * @note The USBD peripheral interrupt state is checked
+ */
+bool nrf_drv_usbd_is_started(void);
+
+/**
+ * @brief Suspend USBD operation
+ *
+ * The USBD peripheral is forced to go into the low power mode.
+ * The function has to be called in the reaction to @ref NRF_DRV_USBD_EVT_SUSPEND event
+ * when the firmware is ready.
+ *
+ * After successful call of this function most of the USBD registers would be unavailable.
+ *
+ * @note Check returned value for the feedback if suspending was successful.
+ *
+ * @retval true USBD peripheral successfully suspended
+ * @retval false USBD peripheral was not suspended due to resume detection.
+ *
+ */
+bool nrf_drv_usbd_suspend(void);
+
+/**
+ * @brief Start wake up procedure
+ *
+ * The USBD peripheral is forced to quit the low power mode.
+ * After calling this function all the USBD registers would be available.
+ *
+ * The hardware starts measuring time when wake up is possible.
+ * This may take 0-5&nbsp;ms depending on how long the SUSPEND state was kept on the USB line.
+
+ * When NRF_DRV_USBD_EVT_WUREQ event is generated it means that Wake Up signaling has just been
+ * started on the USB lines.
+ *
+ * @note Do not expect only @ref NRF_DRV_USBD_EVT_WUREQ event.
+ * There always may appear @ref NRF_DRV_USBD_EVT_RESUME event.
+ * @note NRF_DRV_USBD_EVT_WUREQ event means that Remote WakeUp signal
+ * has just begun to be generated.
+ * This may take up to 20&nbsp;ms for the bus to become active.
+ *
+ * @retval true WakeUp procedure started.
+ * @retval false No WakeUp procedure started - bus is already active.
+ */
+bool nrf_drv_usbd_wakeup_req(void);
+
+/**
+ * @brief Check if USBD is in SUSPEND mode
+ *
+ * @note This is the information about peripheral itself, not about the bus state.
+ *
+ * @retval true USBD peripheral is suspended
+ * @retval false USBD peripheral is active
+ */
+bool nrf_drv_usbd_suspend_check(void);
+
+/**
+ * @brief Enable only interrupts that should be processed in SUSPEND mode
+ *
+ * Auxiliary function to help with SUSPEND mode integration.
+ * It enables only the interrupts that can be properly processed without stable HFCLK.
+ *
+ * Normally all the interrupts are enabled.
+ * Use this function to suspend interrupt processing that may require stable HFCLK until the
+ * clock is enabled.
+ *
+ * @sa nrf_drv_usbd_active_irq_config
+ */
+void nrf_drv_usbd_suspend_irq_config(void);
+
+/**
+ * @brief Default active interrupt configuration
+ *
+ * Default interrupt configuration.
+ * Use in a pair with @ref nrf_drv_usbd_active_irq_config.
+ *
+ * @sa nrf_drv_usbd_suspend_irq_config
+ */
+void nrf_drv_usbd_active_irq_config(void);
+
+/**
+ * @brief Check the bus state
+ *
+ * This function checks if the bus state is suspended
+ *
+ * @note The value returned by this function changes on SUSPEND and RESUME event processing.
+ *
+ * @retval true USBD bus is suspended
+ * @retval false USBD bus is active
+ */
+bool nrf_drv_usbd_bus_suspend_check(void);
+
+/**
+ * @brief Configure packet size that should be supported by the endpoint
+ *
+ * The real endpoint buffer size is always the same.
+ * This value sets max packet size that would be transmitted over the endpoint.
+ * This is required by the library
+ *
+ * @param[in] ep Endpoint number
+ * @param[in] size Required maximum packet size
+ *
+ * @note Endpoint size is always set to @ref NRF_DRV_USBD_EPSIZE or @ref NRF_DRV_USBD_ISOSIZE / 2
+ * when @ref nrf_drv_usbd_ep_enable function is called.
+ */
+void nrf_drv_usbd_ep_max_packet_size_set(nrf_drv_usbd_ep_t ep, uint16_t size);
+
+/**
+ * @brief Get configured endpoint packet size
+ *
+ * Function to get configured endpoint size on the buffer.
+ *
+ * @param[in] ep Endpoint number
+ *
+ * @return Maximum pocket size configured on selected endpoint
+ */
+uint16_t nrf_drv_usbd_ep_max_packet_size_get(nrf_drv_usbd_ep_t ep);
+
+/**
+ * @brief Check if the selected endpoint is enabled.
+ *
+ * @param ep Endpoint number to check.
+ *
+ * @retval true Endpoint is enabled.
+ * @retval false Endpoint is disabled.
+ */
+bool nrf_drv_usbd_ep_enable_check(nrf_drv_usbd_ep_t ep);
+
+/**
+ * @brief Enable selected endpoint
+ *
+ * This function enables endpoint itself and its interrupts.
+ * @param ep Endpoint number to enable
+ *
+ * @note
+ * Max packet size is set to endpoint default maximum value.
+ *
+ * @sa nrf_drv_usbd_ep_max_packet_size_set
+ */
+void nrf_drv_usbd_ep_enable(nrf_drv_usbd_ep_t ep);
+
+/**
+ * @brief Disable selected endpoint
+ *
+ * This function disables endpoint itself and its interrupts.
+ * @param ep Endpoint number to disable
+ */
+void nrf_drv_usbd_ep_disable(nrf_drv_usbd_ep_t ep);
+
+/**
+ * @brief Disable all endpoints except for EP0
+ *
+ * Disable all endpoints that can be disabled in USB device while it is still active.
+ */
+void nrf_drv_usbd_ep_default_config(void);
+
+/**
+ * @brief Start sending data over endpoint
+ *
+ * Function initializes endpoint transmission.
+ * This is asynchronous function - it finishes immediately after configuration
+ * for transmission is prepared.
+ *
+ * @note Data buffer pointed by p_data have to be kept active till
+ * @ref NRF_DRV_USBD_EVT_EPTRANSFER event is generated.
+ *
+ * @param[in] ep Endpoint number.
+ * For IN endpoint sending would be initiated.
+ * For OUT endpoint receiving would be initiated.
+ * @param[in] p_transfer
+ *
+ * @retval NRF_ERROR_BUSY Selected endpoint is pending.
+ * @retval NRF_ERROR_INVALID_ADDR Unexpected transfer on EPIN0 or EPOUT0.
+ * @retval NRF_ERROR_FORBIDDEN Endpoint stalled.
+ * @retval NRF_SUCCESS Transfer queued or started.
+ */
+ret_code_t nrf_drv_usbd_ep_transfer(
+ nrf_drv_usbd_ep_t ep,
+ nrf_drv_usbd_transfer_t const * const p_transfer);
+
+/**
+ * @brief Start sending data over the endpoint using the transfer handler function.
+ *
+ * This function initializes an endpoint transmission.
+ * Just before data is transmitted, the transfer handler
+ * is called and it prepares a data chunk.
+ *
+ * @param[in] ep Endpoint number.
+ * For an IN endpoint, sending is initiated.
+ * For an OUT endpoint, receiving is initiated.
+ * @param p_handler Transfer handler - feeder for IN direction and consumer for
+ * OUT direction.
+ *
+ * @retval NRF_ERROR_BUSY Selected endpoint is pending.
+ * @retval NRF_ERROR_INVALID_ADDR Unexpected transfer on EPIN0 or EPOUT0.
+ * @retval NRF_ERROR_FORBIDDEN Endpoint stalled.
+ * @retval NRF_SUCCESS Transfer queued or started.
+ */
+ret_code_t nrf_drv_usbd_ep_handled_transfer(
+ nrf_drv_usbd_ep_t ep,
+ nrf_drv_usbd_handler_desc_t const * const p_handler);
+
+/**
+ * @brief Get the temporary buffer to be used by the feeder.
+ *
+ * This buffer is used for TX transfers and it can be reused automatically
+ * when the transfer is finished.
+ * Use it for transfer preparation.
+ *
+ * May be used inside the feeder configured in @ref nrf_drv_usbd_ep_handled_transfer.
+ *
+ * @return Pointer to the buffer that can be used temporarily.
+ *
+ * @sa NRF_DRV_USBD_FEEDER_BUFFER_SIZE
+ */
+void * nrf_drv_usbd_feeder_buffer_get(void);
+
+/**
+ * @brief Get the information about last finished or current transfer
+ *
+ * Function returns the status of the last buffer set for transfer on selected endpoint.
+ * The status considers last buffer set by @ref nrf_drv_usbd_ep_transfer function or
+ * by transfer callback function.
+ *
+ * @param[in] ep Endpoint number.
+ * @param[out] p_size Information about the current/last transfer size.
+ *
+ * @retval NRF_SUCCESS Transfer already finished
+ * @retval NRF_ERROR_BUSY Ongoing transfer
+ * @retval NRF_ERROR_DATA_SIZE Too much of data received that cannot fit into buffer and cannot be splited into chunks.
+ * This may happen if buffer size is not a multiplication of endpoint buffer size.
+ */
+ret_code_t nrf_drv_usbd_ep_status_get(nrf_drv_usbd_ep_t ep, size_t * p_size);
+
+/**
+ * @brief Get number of received bytes
+ *
+ * Get the number of received bytes.
+ * The function behavior is undefined when called on IN endpoint.
+ *
+ * @param ep Endpoint number.
+ *
+ * @return Number of received bytes
+ */
+size_t nrf_drv_usbd_epout_size_get(nrf_drv_usbd_ep_t ep);
+
+/**
+ * @brief Check if endpoint buffer is ready or is under USB IP control
+ *
+ * Function to test if endpoint is busy.
+ * Endpoint that is busy cannot be accessed by MCU.
+ * It means that:
+ * - OUT (TX) endpoint: Last uploaded data is still in endpoint and is waiting
+ * to be received by the host.
+ * - IN (RX) endpoint: Endpoint is ready to receive data from the host
+ * and the endpoint does not have any data.
+ * When endpoint is not busy:
+ * - OUT (TX) endpoint: New data can be uploaded.
+ * - IN (RX) endpoint: New data can be downloaded using @ref nrf_drv_usbd_ep_transfer
+ * function.
+ */
+bool nrf_drv_usbd_ep_is_busy(nrf_drv_usbd_ep_t ep);
+
+/**
+ * @brief Stall endpoint
+ *
+ * Stall endpoit to send error information during next transfer request from
+ * the host.
+ *
+ * @note To stall endpoint it is safer to use @ref nrf_drv_usbd_setup_stall
+ * @note Stalled endpoint would not be cleared when DMA transfer finishes.
+ *
+ * @param ep Endpoint number to stall
+ *
+ */
+void nrf_drv_usbd_ep_stall(nrf_drv_usbd_ep_t ep);
+
+/**
+ * @brief Clear stall flag on endpoint
+ *
+ * This function clears endpoint that is stalled.
+ * @note
+ * If it is OUT endpoint (receiving) it would be also prepared for reception.
+ * It means that busy flag would be set.
+ * @note
+ * In endpoint (transmitting) would not be cleared - it gives possibility to
+ * write new data before transmitting.
+ */
+void nrf_drv_usbd_ep_stall_clear(nrf_drv_usbd_ep_t ep);
+
+/**
+ * @brief Check if endpoint is stalled
+ *
+ * This function gets stall state of selected endpoint
+ *
+ * @param ep Endpoint number to check
+ */
+bool nrf_drv_usbd_ep_stall_check(nrf_drv_usbd_ep_t ep);
+
+/**
+ * @brief Clear current endpoint data toggle
+ *
+ * @param ep Endpoint number to clear
+ */
+void nrf_drv_usbd_ep_dtoggle_clear(nrf_drv_usbd_ep_t ep);
+
+/**
+ * @brief Get parsed setup data
+ *
+ * Function fills the parsed setup data structure.
+ *
+ * @param[out] p_setup Pointer to data structure that would be filled by
+ * parsed data.
+ */
+void nrf_drv_usbd_setup_get(nrf_drv_usbd_setup_t * const p_setup);
+
+/**
+ * @brief Clear only for data transmission on setup endpoint
+ *
+ * This function may be called if any more data in control write transfer is expected.
+ * Clears only OUT endpoint to be able to take another OUT data token.
+ * It does not allow STATUS stage.
+ * @sa nrf_drv_usbd_setup_clear
+ */
+void nrf_drv_usbd_setup_data_clear(void);
+
+/**
+ * @brief Clear setup endpoint
+ *
+ * This function acknowledges setup when SETUP command was received and processed.
+ * It has to be called if no data respond for the SETUP command is sent.
+ */
+void nrf_drv_usbd_setup_clear(void);
+
+/**
+ * @brief Stall setup endpoint
+ *
+ * Mark and error on setup endpoint.
+ */
+void nrf_drv_usbd_setup_stall(void);
+
+/**
+* @note
+* This function locks interrupts that may be costly.
+* It is good idea to test if the endpoint is still busy before calling this function:
+* @code
+ (m_ep_dma_waiting & (1U << ep2bit(ep)))
+* @endcode
+* This function would check it again, but it makes it inside critical section.
+*/
+void nrf_drv_usbd_ep_abort(nrf_drv_usbd_ep_t ep);
+
+/**
+ * @brief Get the information about expected transfer SETUP data direction
+ *
+ * Function returns the information about last expected transfer direction.
+ *
+ * @retval NRF_DRV_USBD_EPOUT0 Expecting OUT (Host->Device) direction or no data
+ * @retval NRF_DRV_USBD_EPIN0 Expecting IN (Device->Host) direction
+ */
+nrf_drv_usbd_ep_t nrf_drv_usbd_last_setup_dir_get(void);
+
+/**
+ * @brief Drop transfer on OUT endpoint
+ *
+ * @param[in] ep OUT endpoint ID
+ */
+void nrf_drv_usbd_transfer_out_drop(nrf_drv_usbd_ep_t ep);
+
+#ifdef __cplusplus
+}
+#endif
+
+/** @} */
+#endif /* NRF_DRV_USBD_H__ */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/drivers_nrf/usbd/nrf_drv_usbd_errata.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/drivers_nrf/usbd/nrf_drv_usbd_errata.h
new file mode 100644
index 0000000..ad24f3c
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/drivers_nrf/usbd/nrf_drv_usbd_errata.h
@@ -0,0 +1,193 @@
+/**
+ * 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+
+#ifndef NRF_DRV_USBD_ERRATA_H__
+#define NRF_DRV_USBD_ERRATA_H__
+
+#include <stdbool.h>
+/**
+ * @defgroup nrf_drv_usbd_errata Functions to check if selected PAN is present in current chip
+ * @{
+ * @ingroup nrf_drv_usbd
+ *
+ * Functions here are checking the presence of an error in current chip.
+ * The checking is done at runtime based on the microcontroller version.
+ * This file is subject to removal when nRF51840 prototype support is removed.
+ */
+
+#ifndef NRF_DRV_USBD_ERRATA_ENABLE
+/**
+ * @brief The constant that informs if errata should be enabled at all
+ *
+ * If this constant is set to 0, all the Errata bug fixes will be automatically disabled.
+ */
+#define NRF_DRV_USBD_ERRATA_ENABLE 1
+#endif
+
+/**
+ * @brief Internal auxiliary function to check if the program is running on NRF52840 chip
+ * @retval true It is NRF52480 chip
+ * @retval false It is other chip
+ */
+static inline bool nrf_drv_usbd_errata_type_52840(void)
+{
+ return ((((*(uint32_t *)0xF0000FE0) & 0xFF) == 0x08) &&
+ (((*(uint32_t *)0xF0000FE4) & 0x0F) == 0x0));
+}
+
+/**
+ * @brief Internal auxiliary function to check if the program is running on first sample of
+ * NRF52840 chip
+ * @retval true It is NRF52480 chip and it is first sample version
+ * @retval false It is other chip
+ */
+static inline bool nrf_drv_usbd_errata_type_52840_proto1(void)
+{
+ return ( nrf_drv_usbd_errata_type_52840() &&
+ ( ((*(uint32_t *)0xF0000FE8) & 0xF0) == 0x00 ) &&
+ ( ((*(uint32_t *)0xF0000FEC) & 0xF0) == 0x00 ) );
+}
+
+/**
+ * @brief Internal auxiliary function to check if the program is running on first final product of
+ * NRF52840 chip
+ * @retval true It is NRF52480 chip and it is first final product
+ * @retval false It is other chip
+ */
+static inline bool nrf_drv_usbd_errata_type_52840_fp1(void)
+{
+ return ( nrf_drv_usbd_errata_type_52840() &&
+ ( ((*(uint32_t *)0xF0000FE8) & 0xF0) == 0x10 ) &&
+ ( ((*(uint32_t *)0xF0000FEC) & 0xF0) == 0x00 ) );
+}
+
+/**
+ * @brief Function to check if chip requires errata 104
+ *
+ * Errata: USBD: EPDATA event is not always generated.
+ *
+ * @retval true Errata should be implemented
+ * @retval false Errata should not be implemented
+ */
+static inline bool nrf_drv_usbd_errata_104(void)
+{
+ return NRF_DRV_USBD_ERRATA_ENABLE && nrf_drv_usbd_errata_type_52840_proto1();
+}
+
+/**
+ * @brief Function to check if chip requires errata 154
+ *
+ * Errata: During setup read/write transfer USBD acknowledges setup stage without SETUP task.
+ *
+ * @retval true Errata should be implemented
+ * @retval false Errata should not be implemented
+ */
+static inline bool nrf_drv_usbd_errata_154(void)
+{
+ return NRF_DRV_USBD_ERRATA_ENABLE && nrf_drv_usbd_errata_type_52840_proto1();
+}
+
+/**
+ * @brief Function to check if chip requires errata 166
+ *
+ * Errata: ISO double buffering not functional
+ *
+ * @retval true Errata should be implemented
+ * @retval false Errata should not be implemented
+ */
+static inline bool nrf_drv_usbd_errata_166(void)
+{
+ return NRF_DRV_USBD_ERRATA_ENABLE && true;
+}
+
+/**
+ * @brief Function to check if chip requires errata 171
+ *
+ * Errata: USBD might not reach its active state.
+ *
+ * @retval true Errata should be implemented
+ * @retval false Errata should not be implemented
+ */
+static inline bool nrf_drv_usbd_errata_171(void)
+{
+ return NRF_DRV_USBD_ERRATA_ENABLE && true;
+}
+
+/**
+ * @brief Function to check if chip requires errata 187
+ *
+ * Errata: USB cannot be enabled
+ *
+ * @retval true Errata should be implemented
+ * @retval false Errata should not be implemented
+ */
+static inline bool nrf_drv_usbd_errata_187(void)
+{
+ return NRF_DRV_USBD_ERRATA_ENABLE && nrf_drv_usbd_errata_type_52840_fp1();
+}
+
+/**
+ * @brief Function to check if chip requires errata ???
+ *
+ * Errata: SIZE.EPOUT not writable
+ *
+ * @retval true Errata should be implemented
+ * @retval false Errata should not be implemented
+ */
+static inline bool nrf_drv_usbd_errata_sizeepout_rw(void)
+{
+ return NRF_DRV_USBD_ERRATA_ENABLE && nrf_drv_usbd_errata_type_52840_proto1();
+}
+
+/**
+ * @brief Function to check if chip requires errata 199
+ *
+ * Errata: USBD cannot receive tasks during DMA
+ *
+ * @retval true Errata should be implemented
+ * @retval false Errata should not be implemented
+ */
+static inline bool nrf_drv_usb_errata_199(void)
+{
+ return NRF_DRV_USBD_ERRATA_ENABLE && true;
+}
+
+/** @} */
+#endif /* NRF_DRV_USBD_ERRATA_H__ */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/background_dfu/background_dfu_block.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/background_dfu/background_dfu_block.c
new file mode 100644
index 0000000..8b08068
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/background_dfu/background_dfu_block.c
@@ -0,0 +1,456 @@
+/**
+ * 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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
+ *
+ * @defgroup background_dfu_block background_dfu_block.c
+ * @{
+ * @ingroup background_dfu
+ * @brief Background DFU block handling implementation.
+ *
+ */
+
+#include "background_dfu_block.h"
+
+#include <assert.h>
+
+#include "sdk_config.h"
+#include "app_scheduler.h"
+#include "background_dfu_operation.h"
+#include "compiler_abstraction.h"
+#include "nrf_dfu_handling_error.h"
+
+#define NRF_LOG_MODULE_NAME background_dfu
+
+#define NRF_LOG_LEVEL BACKGROUND_DFU_CONFIG_LOG_LEVEL
+#define NRF_LOG_INFO_COLOR BACKGROUND_DFU_CONFIG_INFO_COLOR
+#define NRF_LOG_DEBUG_COLOR BACKGROUND_DFU_CONFIG_DEBUG_COLOR
+
+#include "nrf_log.h"
+
+#define BITMAP_BYTE_FROM_INDEX(index) ((index) / 8)
+#define BITMAP_BIT_FROM_INDEX(index) (7 - ((index) % 8))
+
+static void block_buffer_store(background_dfu_block_manager_t * p_bm);
+
+/**@brief Convert block number to bitmap index.
+ *
+ * @param[in] block_num Block number.
+ *
+ * @return Corresponding index.
+ */
+static __INLINE uint16_t block_num_to_index(uint32_t block_num)
+{
+ return block_num % BLOCKS_PER_BUFFER;
+}
+
+/**@brief Set a bit in a bitmap.
+ *
+ * @param[inout] p_bitmap A pointer to the bitmap.
+ * @param[in] index Bit index to set.
+ */
+static __INLINE void set_bitmap_bit(uint8_t * p_bitmap, uint16_t index)
+{
+ p_bitmap[BITMAP_BYTE_FROM_INDEX(index)] |= (0x01 << BITMAP_BIT_FROM_INDEX(index));
+}
+
+/**@brief Clear a bit in a bitmap.
+ *
+ * @param[inout] p_bitmap A pointer to the bitmap.
+ * @param[in] index Bit index to clear.
+ */
+static __INLINE void clear_bitmap_bit(uint8_t * p_bitmap, uint16_t index)
+{
+ p_bitmap[BITMAP_BYTE_FROM_INDEX(index)] &= ~((uint8_t)(0x01 << BITMAP_BIT_FROM_INDEX(index)));
+}
+
+/**@brief Check if a bit in a bitmap is set.
+ *
+ * @param[inout] p_bitmap A pointer to the bitmap.
+ * @param[in] index Bit index to check.
+ *
+ * @return True if bit is set, false otherwise.
+ */
+static __INLINE bool is_block_present(const uint8_t * p_bitmap, uint16_t index)
+{
+ return (p_bitmap[BITMAP_BYTE_FROM_INDEX(index)] >> BITMAP_BIT_FROM_INDEX(index)) & 0x01;
+}
+
+/**
+ * @brief A callback function for DFU operation.
+ */
+static void dfu_operation_callback(nrf_dfu_response_t * p_res, void * p_context)
+{
+ background_dfu_block_manager_t * p_bm = (background_dfu_block_manager_t *)p_context;
+ ret_code_t res_code;
+
+ if (p_res->result != NRF_DFU_RES_CODE_SUCCESS)
+ {
+ p_bm->result_handler(BACKGROUND_DFU_BLOCK_STORE_ERROR, p_bm->p_context);
+ }
+ else
+ {
+ switch (p_res->request)
+ {
+ case NRF_DFU_OP_OBJECT_CREATE:
+ {
+ // Object created, write respective block.
+ uint32_t current_size = p_bm->currently_stored_block * DEFAULT_BLOCK_SIZE;
+ uint16_t data_offset = block_num_to_index(p_bm->currently_stored_block) * DEFAULT_BLOCK_SIZE;
+ uint16_t store_size = MIN(DEFAULT_BLOCK_SIZE, (p_bm->image_size - current_size));
+ res_code = background_dfu_op_write(p_bm->data + data_offset,
+ store_size,
+ dfu_operation_callback,
+ p_bm);
+
+ if (res_code != NRF_SUCCESS)
+ {
+ NRF_LOG_ERROR("Failed to store block (b:%d c:%d).",
+ p_bm->currently_stored_block,
+ p_bm->current_block);
+ p_bm->result_handler(BACKGROUND_DFU_BLOCK_STORE_ERROR, p_bm->p_context);
+ }
+
+ break;
+ }
+
+ case NRF_DFU_OP_OBJECT_WRITE:
+ if (!((p_bm->currently_stored_block + 1) % BLOCKS_PER_DFU_OBJECT) ||
+ ((p_bm->currently_stored_block + 1) == BLOCKS_PER_SIZE(p_bm->image_size)))
+ {
+ res_code = background_dfu_op_crc(dfu_operation_callback, p_bm);
+
+ if (res_code != NRF_SUCCESS)
+ {
+ NRF_LOG_ERROR("Failed to store block (b:%d c:%d).",
+ p_bm->currently_stored_block,
+ p_bm->current_block);
+ p_bm->result_handler(BACKGROUND_DFU_BLOCK_STORE_ERROR, p_bm->p_context);
+ }
+ }
+ else
+ {
+ p_bm->last_block_stored = p_bm->currently_stored_block;
+ clear_bitmap_bit(p_bm->bitmap, block_num_to_index(p_bm->currently_stored_block));
+ p_bm->currently_stored_block = INVALID_BLOCK_NUMBER;
+
+ p_bm->result_handler(BACKGROUND_DFU_BLOCK_SUCCESS, p_bm->p_context);
+
+ block_buffer_store(p_bm);
+ }
+
+ break;
+
+ case NRF_DFU_OP_CRC_GET:
+ res_code = background_dfu_op_execute(dfu_operation_callback, p_bm);
+
+ if (res_code != NRF_SUCCESS)
+ {
+ NRF_LOG_ERROR("Failed to store block (b:%d c:%d).",
+ p_bm->currently_stored_block,
+ p_bm->current_block);
+ p_bm->result_handler(BACKGROUND_DFU_BLOCK_STORE_ERROR, p_bm->p_context);
+ }
+
+ break;
+
+ case NRF_DFU_OP_OBJECT_EXECUTE:
+ p_bm->last_block_stored = p_bm->currently_stored_block;
+ clear_bitmap_bit(p_bm->bitmap, block_num_to_index(p_bm->currently_stored_block));
+ p_bm->currently_stored_block = INVALID_BLOCK_NUMBER;
+
+ p_bm->result_handler(BACKGROUND_DFU_BLOCK_SUCCESS, p_bm->p_context);
+
+ block_buffer_store(p_bm);
+
+ break;
+
+ default:
+ ASSERT(false);
+ }
+ }
+}
+
+/**@brief Store a block from the buffer in a flash.
+ *
+ * @param[inout] p_bm A pointer to the block manager.
+ * @param[in] p_block A block number to store.
+ *
+ * @return NRF_SUCCESS on success, an error code is returned otherwise.
+ */
+static ret_code_t block_store(background_dfu_block_manager_t * p_bm, uint32_t block_num)
+{
+ p_bm->currently_stored_block = block_num;
+
+ ret_code_t res_code = NRF_SUCCESS;
+ uint32_t current_size = block_num * DEFAULT_BLOCK_SIZE;
+
+ do
+ {
+ // Initialize DFU object if needed.
+ if (!(block_num % BLOCKS_PER_DFU_OBJECT))
+ {
+ uint32_t object_size = MIN(DEFAULT_DFU_OBJECT_SIZE, (p_bm->image_size - current_size));
+
+ res_code = background_dfu_op_create(p_bm->image_type,
+ object_size,
+ dfu_operation_callback,
+ p_bm);
+ break;
+ }
+
+ // Store block.
+ uint16_t data_offset = block_num_to_index(block_num) * DEFAULT_BLOCK_SIZE;
+ uint16_t store_size = MIN(DEFAULT_BLOCK_SIZE, (p_bm->image_size - current_size));
+ res_code = background_dfu_op_write(p_bm->data + data_offset,
+ store_size,
+ dfu_operation_callback,
+ p_bm);
+
+ } while (0);
+ return res_code;
+}
+
+/**@brief Check if block manager is busy storing a block.
+ *
+ * @param[inout] p_bm A pointer to the block manager.
+ *
+ */
+static bool is_block_manager_busy(background_dfu_block_manager_t * p_bm)
+{
+ return p_bm->currently_stored_block >= 0;
+}
+
+/**@brief Store any valid blocks from the buffer in a flash.
+ *
+ * @param[inout] p_bm A pointer to the block manager.
+ *
+ */
+static void block_buffer_store(background_dfu_block_manager_t * p_bm)
+{
+ ret_code_t res_code = NRF_SUCCESS;
+
+ if (!is_block_manager_busy(p_bm))
+ {
+ if (p_bm->last_block_stored < p_bm->current_block)
+ {
+ int32_t block = p_bm->last_block_stored + 1;
+
+ if (is_block_present(p_bm->bitmap, block_num_to_index(block)))
+ {
+ NRF_LOG_INFO("Storing block (b:%d c:%d).", block, p_bm->current_block);
+
+ // There is a block to store.
+ res_code = block_store(p_bm, block);
+ if (res_code != NRF_SUCCESS)
+ {
+ NRF_LOG_ERROR("Failed to store block (b:%d c:%d).", block, p_bm->current_block);
+ p_bm->result_handler(BACKGROUND_DFU_BLOCK_STORE_ERROR, p_bm->p_context);
+ }
+ }
+ else
+ {
+ NRF_LOG_WARNING("Gap encountered - quit (b:%d c:%d).", block, p_bm->current_block);
+ }
+ }
+ }
+}
+
+/**
+ * @brief A callback function for scheduling DFU block operations.
+ */
+static void block_store_scheduled(void * p_evt, uint16_t event_length)
+{
+ UNUSED_PARAMETER(event_length);
+
+ background_dfu_block_manager_t * p_bm = *((background_dfu_block_manager_t **)p_evt);
+ block_buffer_store(p_bm);
+}
+
+/**@brief Copy block data to the buffer.
+ *
+ * @param[inout] p_bm A pointer to the block manager.
+ * @param[in] p_block A pointer to the block.
+ */
+static void block_buffer_add(background_dfu_block_manager_t * p_bm,
+ const background_dfu_block_t * p_block)
+{
+ uint16_t index = block_num_to_index(p_block->number);
+
+ memcpy(p_bm->data + index * DEFAULT_BLOCK_SIZE, p_block->p_payload, DEFAULT_BLOCK_SIZE);
+ set_bitmap_bit(p_bm->bitmap, index);
+
+ if (p_bm->current_block < (int32_t)p_block->number)
+ {
+ p_bm->current_block = (int32_t)p_block->number;
+ }
+
+ // Schedule block store.
+ UNUSED_RETURN_VALUE(app_sched_event_put(&p_bm, sizeof(p_bm), block_store_scheduled));
+}
+
+/***************************************************************************************************
+ * @section Public
+ **************************************************************************************************/
+
+void block_manager_init(background_dfu_block_manager_t * p_bm,
+ uint32_t object_type,
+ uint32_t object_size,
+ int32_t initial_block,
+ block_manager_result_notify_t result_handler,
+ void * p_context)
+{
+ p_bm->image_type = object_type;
+ p_bm->image_size = object_size;
+ p_bm->last_block_stored = p_bm->current_block = initial_block - 1;
+ p_bm->result_handler = result_handler;
+ p_bm->p_context = p_context;
+ p_bm->currently_stored_block = INVALID_BLOCK_NUMBER;
+
+ memset(p_bm->bitmap, 0, sizeof(p_bm->bitmap));
+}
+
+background_dfu_block_result_t block_manager_block_process(background_dfu_block_manager_t * p_bm,
+ const background_dfu_block_t * p_block)
+{
+ /*
+ * Possible scenarios:
+ * 1) We receive a block older than our last stored block - simply ignore it.
+ * 2) We receive a block that fits within current buffer range - process it.
+ * 3) We receive a block that exceeds current buffer range - abort DFU as we won't be able to catch-up.
+ */
+
+ if (p_block->size != DEFAULT_BLOCK_SIZE)
+ {
+ NRF_LOG_WARNING("Block with incorrect size received (s:%d n:%d).",
+ p_block->size, p_block->number);
+ return BACKGROUND_DFU_BLOCK_IGNORE;
+ }
+
+ if ((int32_t)p_block->number <= p_bm->last_block_stored)
+ {
+ NRF_LOG_WARNING("Ignoring block that already was stored(o:%d n:%d).",
+ p_bm->last_block_stored, p_block->number);
+ return BACKGROUND_DFU_BLOCK_IGNORE;
+ }
+
+ if ((int32_t)p_block->number > p_bm->last_block_stored + BLOCKS_PER_BUFFER)
+ {
+ NRF_LOG_WARNING("Too many blocks missed - abort DFU (o:%d n:%d).",
+ p_bm->last_block_stored, p_block->number);
+ return BACKGROUND_DFU_BLOCK_INVALID;
+ }
+
+ // Block fits within current buffer - copy it into the buffer and update the current block if most
+ // recent block was received.
+ block_buffer_add(p_bm, p_block);
+
+ return BACKGROUND_DFU_BLOCK_SUCCESS;
+}
+
+bool block_manager_is_image_complete(const background_dfu_block_manager_t * p_bm)
+{
+ uint32_t image_blocks = BLOCKS_PER_SIZE(p_bm->image_size);
+
+ NRF_LOG_DEBUG("Is image complete (o:%d n:%d).", p_bm->last_block_stored, image_blocks);
+
+ if (p_bm->last_block_stored + 1 == image_blocks)
+ {
+ return true;
+ }
+
+ return false;
+}
+
+bool block_manager_request_bitmap_get(const background_dfu_block_manager_t * p_bm,
+ background_dfu_request_bitmap_t * p_req_bmp)
+{
+ if (p_bm->current_block > p_bm->last_block_stored)
+ {
+ memset(p_req_bmp, 0, sizeof(*p_req_bmp));
+ p_req_bmp->offset = p_bm->last_block_stored + 1;
+ p_req_bmp->size = (p_bm->current_block - p_bm->last_block_stored + 7) / 8;
+
+ for (uint16_t block = p_req_bmp->offset; block <= p_bm->current_block; block++)
+ {
+ if (!is_block_present(p_bm->bitmap, block_num_to_index(block)))
+ {
+ set_bitmap_bit(p_req_bmp->bitmap, block - p_req_bmp->offset);
+ }
+ }
+
+ // Clip empty bytes at the end.
+ while ((p_req_bmp->size > 0) && (p_req_bmp->bitmap[p_req_bmp->size - 1] == 0))
+ {
+ p_req_bmp->size--;
+ }
+
+ if (p_req_bmp->size == 0)
+ {
+ return false;
+ }
+
+ return true;
+ }
+
+ return false;
+}
+
+bool block_manager_increment_current_block(background_dfu_block_manager_t * p_bm)
+{
+ uint32_t image_blocks = BLOCKS_PER_SIZE(p_bm->image_size);
+
+ if (p_bm->current_block + 1 == image_blocks)
+ {
+ // Already on last block.
+ return false;
+ }
+ else
+ {
+ p_bm->current_block++;
+ }
+
+ return true;
+}
+
+int32_t block_manager_get_current_block(const background_dfu_block_manager_t * p_bm)
+{
+ return p_bm->current_block;
+}
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/background_dfu/background_dfu_block.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/background_dfu/background_dfu_block.h
new file mode 100644
index 0000000..e1e468b
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/background_dfu/background_dfu_block.h
@@ -0,0 +1,197 @@
+/**
+ * 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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
+ *
+ * @defgroup background_dfu_block background_dfu_block.H
+ * @{
+ * @ingroup background_dfu
+ * @brief Background DFU block handling.
+ *
+ */
+
+#ifndef BACKGROUND_DFU_BLOCK_H_
+#define BACKGROUND_DFU_BLOCK_H_
+
+#include <stdint.h>
+#include <stdbool.h>
+
+#include "app_util_platform.h"
+#include "sdk_config.h"
+
+/** @brief Macro for calculating the number of blocks that fits in particular size. */
+#define BLOCKS_PER_SIZE(SIZE) ((SIZE + DEFAULT_BLOCK_SIZE - 1) / DEFAULT_BLOCK_SIZE)
+
+/** @brief Default block size for background DFU blocks. */
+#define DEFAULT_BLOCK_SIZE BACKGROUND_DFU_DEFAULT_BLOCK_SIZE
+
+/** @brief Number of blocks in superblock. */
+#define BLOCKS_PER_BUFFER BACKGROUND_DFU_BLOCKS_PER_BUFFER
+
+/** @brief Size of the block buffer. Shall be a multiply of @ref DEFAULT_BLOCK_SIZE. */
+#define BLOCK_BUFFER_SIZE (BLOCKS_PER_BUFFER * DEFAULT_BLOCK_SIZE)
+
+/** @brief Size of the bitmap reflecting the state of the blocks in a superblock. */
+#define BITMAP_SIZE ((BLOCKS_PER_BUFFER + 7) / 8)
+
+/** @brief Default size of DFU object. Shall be a multiply of @ref DEFAULT_BLOCK_SIZE. */
+#define DEFAULT_DFU_OBJECT_SIZE 4096
+
+/** @brief Number of blocks in DFU object. */
+#define BLOCKS_PER_DFU_OBJECT (BLOCKS_PER_SIZE(DEFAULT_DFU_OBJECT_SIZE))
+
+/** @brief Value of invalid block number (for example to indicate that no block is being stored). */
+#define INVALID_BLOCK_NUMBER (-1)
+
+/** @brief Result of a DFU block operation. */
+typedef enum
+{
+ BACKGROUND_DFU_BLOCK_SUCCESS, /**< Block operation completed successfully. */
+ BACKGROUND_DFU_BLOCK_IGNORE, /**< Block was ignored in current DFU context (i.e. duplicated block). */
+ BACKGROUND_DFU_BLOCK_INVALID, /**< Block is invalid in current context, indicates that DFU shall be aborted. */
+ BACKGROUND_DFU_BLOCK_STORE_ERROR /**< Block was not stored due to internal store error. */
+} background_dfu_block_result_t;
+
+/**@brief A function that module can register to receive block manager error notifications. */
+typedef void (* block_manager_result_notify_t)(background_dfu_block_result_t result,
+ void * p_context);
+
+/**@brief Block information structure. */
+typedef struct
+{
+ uint16_t size; /**< Size of the block in bytes. */
+ uint32_t number; /**< Block number. */
+ uint8_t * p_payload; /**< Block payload. */
+} background_dfu_block_t;
+
+/**@brief Block manager structure.
+ *
+ * Block manager keeps track of received blocks, ensuring that they are written into flash in
+ * a correct order, and updates the missing blocks bitmap, so that they could be requested from
+ * the server.
+ */
+typedef struct
+{
+ uint32_t image_size; /**< Size of currently stored image. */
+ uint32_t image_type; /**< Image type (init command or firmware). */
+ int32_t last_block_stored; /**< Number of the last block written in the flash. */
+ int32_t current_block; /**< Last received (or expected) block. */
+ uint8_t data[BLOCK_BUFFER_SIZE]; /**< Block buffer. */
+ uint8_t bitmap[BITMAP_SIZE]; /**< A bitmap indicating which blocks have been received. */
+ block_manager_result_notify_t result_handler; /**< A callback function for error notification. */
+ void * p_context; /**< A context for result notification.*/
+ int32_t currently_stored_block; /**< Number of block that is currently being stored. */
+} background_dfu_block_manager_t;
+
+/**@brief Bitmap structure used in bitmap requests. */
+typedef struct
+{
+ uint16_t size; /**< Size of the bitmap, in bytes.*/
+ uint16_t offset; /**< Bitmap offset, indicating which block is referenced by first bit in bitmap. */
+ uint8_t bitmap[BITMAP_SIZE]; /**< Bitmap itself. One in specific bit indicates which block is missing. */
+} background_dfu_request_bitmap_t;
+
+/**@brief Initialize block manager.
+ *
+ * @param[inout] p_bm A pointer to the block manager.
+ * @param[in] object_type Type of the image to store.
+ * @param[in] object_size Size of the image to store.
+ * @param[in] initial_block Number of the first block to receive. Typically it would be 0, but
+ * in case DFU restarted in the middle, it may differ.
+ * @param[in] error_handler A callback for error notification.
+ * @param[in] p_context A context for error notification.
+ */
+void block_manager_init(background_dfu_block_manager_t * p_bm,
+ uint32_t object_type,
+ uint32_t object_size,
+ int32_t initial_block,
+ block_manager_result_notify_t result_handler,
+ void * p_context);
+
+/**@brief Process a single block.
+ *
+ * @param[inout] p_bm A pointer to the block manager.
+ * @param[in] p_block A pointer to the block structure containing information about the block.
+ *
+ * @retval BACKGROUND_DFU_BLOCK_SUCCESS Block stored successfully.
+ * @retval BACKGROUND_DFU_BLOCK_IGNORE Invalid block size or block already stored in flash.
+ * @retval BACKGROUND_DFU_BLOCK_INVALID Block number indicates that too many blocks were missed.
+ * @retval BACKGROUND_DFU_BLOCK_STORE_ERROR Block store in flash failed.
+ */
+background_dfu_block_result_t block_manager_block_process(background_dfu_block_manager_t * p_bm,
+ const background_dfu_block_t * p_block);
+
+/**@brief Check if an image managed by a block manager is complete.
+ *
+ * @param[in] p_bm A pointer to the block manager.
+ *
+ * @return True if image is complete, false otherwise.
+ */
+bool block_manager_is_image_complete(const background_dfu_block_manager_t * p_bm);
+
+/**@brief Get current block bitmap.
+ *
+ * @param[in] p_bm A pointer to the block manager.
+ * @param[out] p_req_bmp A pointer to the block bitmap structure.
+ *
+ * @return True if non-empty bitmap was generated, false otherwise.
+ */
+bool block_manager_request_bitmap_get(const background_dfu_block_manager_t * p_bm,
+ background_dfu_request_bitmap_t * p_req_bmp);
+
+/**@brief Increment current block, in case no blocks were received and block timeout shot.
+ *
+ * @param[in] p_bm A pointer to the block manager.
+ *
+ * @return True if block was incremented, false if block manager is already on a last block of the image.
+ */
+bool block_manager_increment_current_block(background_dfu_block_manager_t * p_bm);
+
+/**@brief Get current block number that block manager received/expects.
+ *
+ * @param[in] p_bm A pointer to the block manager.
+ *
+ * @return Current block number.
+ */
+int32_t block_manager_get_current_block(const background_dfu_block_manager_t * p_bm);
+
+#endif /* BACKGROUND_DFU_BLOCK_H_ */
+
+/** @} */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/background_dfu/background_dfu_operation.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/background_dfu/background_dfu_operation.c
new file mode 100644
index 0000000..7aa6679
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/background_dfu/background_dfu_operation.c
@@ -0,0 +1,141 @@
+/**
+ * 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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
+ *
+ * @defgroup background_dfu_operation background_dfu_operation.c
+ * @{
+ * @ingroup background_dfu
+ * @brief Background DFU operations implementation.
+ *
+ */
+
+#include "background_dfu_operation.h"
+
+#include "sdk_config.h"
+#include "nrf_dfu_req_handler.h"
+
+#define NRF_LOG_MODULE_NAME background_dfu
+
+#define NRF_LOG_LEVEL BACKGROUND_DFU_CONFIG_LOG_LEVEL
+#define NRF_LOG_INFO_COLOR BACKGROUND_DFU_CONFIG_INFO_COLOR
+#define NRF_LOG_DEBUG_COLOR BACKGROUND_DFU_CONFIG_DEBUG_COLOR
+
+#include "nrf_log.h"
+
+ret_code_t background_dfu_op_select(uint32_t object_type,
+ nrf_dfu_response_callback_t callback,
+ void * p_context)
+{
+ nrf_dfu_request_t dfu_req;
+
+ memset(&dfu_req, 0, sizeof(dfu_req));
+
+ dfu_req.request = NRF_DFU_OP_OBJECT_SELECT;
+ dfu_req.select.object_type = object_type;
+ dfu_req.p_context = p_context;
+ dfu_req.callback.response = callback;
+
+ return nrf_dfu_req_handler_on_req(&dfu_req);
+}
+
+ret_code_t background_dfu_op_create(uint32_t object_type,
+ uint32_t object_size,
+ nrf_dfu_response_callback_t callback,
+ void * p_context)
+{
+ nrf_dfu_request_t dfu_req;
+
+ memset(&dfu_req, 0, sizeof(dfu_req));
+
+ dfu_req.request = NRF_DFU_OP_OBJECT_CREATE;
+ dfu_req.create.object_size = object_size;
+ dfu_req.create.object_type = object_type;
+ dfu_req.p_context = p_context;
+ dfu_req.callback.response = callback;
+
+ return nrf_dfu_req_handler_on_req(&dfu_req);
+}
+
+ret_code_t background_dfu_op_write(const uint8_t * p_payload,
+ uint16_t payload_length,
+ nrf_dfu_response_callback_t callback,
+ void * p_context)
+{
+ nrf_dfu_request_t dfu_req;
+
+ memset(&dfu_req, 0, sizeof(dfu_req));
+
+ dfu_req.request = NRF_DFU_OP_OBJECT_WRITE;
+ dfu_req.write.p_data = (uint8_t *)p_payload;
+ dfu_req.write.len = payload_length;
+ dfu_req.p_context = p_context;
+ dfu_req.callback.response = callback;
+
+ return nrf_dfu_req_handler_on_req(&dfu_req);
+}
+
+ret_code_t background_dfu_op_crc(nrf_dfu_response_callback_t callback,
+ void * p_context)
+{
+ nrf_dfu_request_t dfu_req;
+
+ memset(&dfu_req, 0, sizeof(dfu_req));
+
+ dfu_req.request = NRF_DFU_OP_CRC_GET;
+ dfu_req.p_context = p_context;
+ dfu_req.callback.response = callback;
+
+ return nrf_dfu_req_handler_on_req(&dfu_req);
+}
+
+ret_code_t background_dfu_op_execute(nrf_dfu_response_callback_t callback,
+ void * p_context)
+{
+ nrf_dfu_request_t dfu_req;
+
+ memset(&dfu_req, 0, sizeof(dfu_req));
+
+ dfu_req.request = NRF_DFU_OP_OBJECT_EXECUTE;
+ dfu_req.p_context = p_context;
+ dfu_req.callback.response = callback;
+
+ return nrf_dfu_req_handler_on_req(&dfu_req);
+}
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/background_dfu/background_dfu_operation.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/background_dfu/background_dfu_operation.h
new file mode 100644
index 0000000..b01d9b2
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/background_dfu/background_dfu_operation.h
@@ -0,0 +1,117 @@
+/**
+ * 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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
+ *
+ * @defgroup background_dfu_operation background_dfu_operation.h
+ * @{
+ * @ingroup background_dfu
+ * @brief Background DFU operations.
+ *
+ */
+
+#ifndef BACKGROUND_DFU_OPERATION_H_
+#define BACKGROUND_DFU_OPERATION_H_
+
+#include <stdint.h>
+
+#include "nrf_dfu_handling_error.h"
+
+/** @brief Select DFU object.
+ *
+ * @param[in] object_type Object type which should be selected.
+ * @param[in] callback A callback function to be executed after operation is completed.
+ * @param[in] p_context A pointer to the operation context.
+ *
+ * @return Operation result code.
+ */
+ret_code_t background_dfu_op_select(uint32_t object_type,
+ nrf_dfu_response_callback_t callback,
+ void * p_context);
+
+/** @brief Create DFU object.
+ *
+ * @param[in] object_type Object type which should be selected.
+ * @param[in] object_size Size of an object to create.
+ * @param[in] callback A callback function to be executed after operation is completed.
+ * @param[in] p_context A pointer to the operation context.
+ *
+ * @return Operation result code.
+ */
+ret_code_t background_dfu_op_create(uint32_t object_type,
+ uint32_t object_size,
+ nrf_dfu_response_callback_t callback,
+ void * p_context);
+
+/** @brief Write DFU object.
+ *
+ * @param[in] p_payload A pointer to data which should be written to the object.
+ * @param[in] payload_length Length, in bytes, of data which should be written to the object.
+ * @param[in] callback A callback function to be executed after operation is completed.
+ * @param[in] p_context A pointer to the operation context.
+ *
+ * @return Operation result code.
+ */
+ret_code_t background_dfu_op_write(const uint8_t * p_payload,
+ uint16_t payload_length,
+ nrf_dfu_response_callback_t callback,
+ void * p_context);
+
+/** @brief Calculate DFU object CRC.
+ *
+ * @param[in] callback A callback function to be executed after operation is completed.
+ * @param[in] p_context A pointer to the operation context.
+ *
+ * @return Operation result code.
+ */
+ret_code_t background_dfu_op_crc(nrf_dfu_response_callback_t callback,
+ void * p_context);
+
+/** @brief Execute selected DFU.
+ *
+ * @param[in] callback A callback function to be executed after operation is completed.
+ * @param[in] p_context A pointer to the operation context.
+ *
+ * @return Operation result code.
+ */
+ret_code_t background_dfu_op_execute(nrf_dfu_response_callback_t callback,
+ void * p_context);
+
+#endif /* BACKGROUND_DFU_OPERATION_H_ */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/background_dfu/background_dfu_state.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/background_dfu/background_dfu_state.c
new file mode 100644
index 0000000..5004558
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/background_dfu/background_dfu_state.c
@@ -0,0 +1,835 @@
+/**
+ * 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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
+ *
+ * @defgroup background_dfu_state background_dfu_state.c
+ * @{
+ * @ingroup background_dfu
+ * @brief Background DFU state management.
+ *
+ */
+
+#include "background_dfu_state.h"
+
+#include <string.h>
+
+#include "sdk_config.h"
+#include "app_timer.h"
+#include "compiler_abstraction.h"
+#include "nrf_dfu_types.h"
+#include "nrf_dfu_settings.h"
+#include "sha256.h"
+#include "background_dfu_transport.h"
+#include "background_dfu_operation.h"
+
+#define NRF_LOG_MODULE_NAME background_dfu
+
+#define NRF_LOG_LEVEL BACKGROUND_DFU_CONFIG_LOG_LEVEL
+#define NRF_LOG_INFO_COLOR BACKGROUND_DFU_CONFIG_INFO_COLOR
+#define NRF_LOG_DEBUG_COLOR BACKGROUND_DFU_CONFIG_DEBUG_COLOR
+
+#include "nrf_log.h"
+NRF_LOG_MODULE_REGISTER();
+
+#define BLOCK_REQUEST_JITTER_MIN 200 /**< Minimum jitter value when sending bitmap with requested blocks in multicast DFU. */
+#define BLOCK_REQUEST_JITTER_MAX 2000 /**< Maximum jitter value when sending bitmap with requested blocks in multicast DFU. */
+#define BLOCK_RECEIVE_TIMEOUT 2000 /**< Timeout value after which block is considered missing in multicast DFU. */
+
+#define DFU_DATE_TIME (__DATE__ " " __TIME__)
+
+/**@brief DFU trigger packet version. */
+#define TRIGGER_VERSION 1
+
+/**
+ * @defgroup background_dfu_trigger_flags Trigger flags and offsets.
+ * @{
+ */
+#define TRIGGER_FLAGS_VERSION_OFFSET 4
+#define TRIGGER_FLAGS_VERSION_MASK 0xF0
+#define TRIGGER_FLAGS_MODE_OFFSET 3
+#define TRIGGER_FLAGS_MODE_MASK 0x08
+#define TRIGGER_FLAGS_RESET_OFFSET 2
+#define TRIGGER_FLAGS_RESET_MASK 0x04
+/** @} */
+
+APP_TIMER_DEF(m_missing_block_timer);
+APP_TIMER_DEF(m_block_timeout_timer);
+
+/**@brief Defines how many retries are performed in case no response is received. */
+#define DEFAULT_RETRIES 3
+
+/**@brief DFU error handler.
+ *
+ * @param[inout] p_dfu_ctx DFU context.
+ */
+static __INLINE void dfu_handle_error(background_dfu_context_t * p_dfu_ctx)
+{
+ p_dfu_ctx->dfu_state = BACKGROUND_DFU_ERROR;
+
+ background_dfu_handle_error();
+}
+
+/**@brief Get randomized jitter value.
+ *
+ * @return Randomized jitter value between BLOCK_REQUEST_JITTER_MIN and BLOCK_REQUEST_JITTER_MAX.
+ */
+static __INLINE uint32_t block_request_jitter_get(void)
+{
+ return BLOCK_REQUEST_JITTER_MIN + (background_dfu_random() %
+ (BLOCK_REQUEST_JITTER_MAX - BLOCK_REQUEST_JITTER_MIN));
+}
+
+/**@brief Starts block timeout timer.
+ *
+ * @param[inout] p_dfu_ctx DFU context.
+ */
+static __INLINE void start_block_timeout_timer(background_dfu_context_t * p_dfu_ctx)
+{
+ uint32_t err_code = app_timer_start(m_block_timeout_timer,
+ APP_TIMER_TICKS(BLOCK_RECEIVE_TIMEOUT),
+ p_dfu_ctx);
+ if (err_code != NRF_SUCCESS)
+ {
+ NRF_LOG_ERROR("Error in app_timer_start (%d)", err_code);
+ }
+}
+
+/**@brief Stops block timeout timer.
+ *
+ * @param[inout] p_dfu_ctx DFU context.
+ */
+static __INLINE void stop_block_timeout_timer(background_dfu_context_t * p_dfu_ctx)
+{
+ UNUSED_PARAMETER(p_dfu_ctx);
+ uint32_t err_code = app_timer_stop(m_block_timeout_timer);
+ if (err_code != NRF_SUCCESS)
+ {
+ NRF_LOG_ERROR("Error in app_timer_stop (%d)", err_code);
+ }
+}
+
+/**@brief Restarts block timeout timer.
+ *
+ * @param[inout] p_dfu_ctx DFU context.
+ */
+static __INLINE void restart_block_timeout_timer(background_dfu_context_t * p_dfu_ctx)
+{
+ stop_block_timeout_timer(p_dfu_ctx);
+ start_block_timeout_timer(p_dfu_ctx);
+}
+
+/***************************************************************************************************
+ * @section Handle DFU Trigger
+ **************************************************************************************************/
+
+/**@brief Parses trigger data and updates DFU client context accordingly.
+ *
+ * @param[inout] p_dfu_ctx A pointer to DFU Client context.
+ * @param[in] p_trigger A pointer to trigger data.
+ *
+ * @return True if parsing was successful, false otherwise.
+ */
+static bool parse_trigger(background_dfu_context_t * p_dfu_ctx,
+ const background_dfu_trigger_t * p_trigger)
+{
+ uint8_t trigger_version = (p_trigger->flags & TRIGGER_FLAGS_VERSION_MASK)
+ >> TRIGGER_FLAGS_VERSION_OFFSET;
+
+ if (trigger_version <= TRIGGER_VERSION)
+ {
+ // Base fields available from version 0.
+ p_dfu_ctx->init_cmd_size = uint32_big_decode((const uint8_t *)&p_trigger->init_length);
+ p_dfu_ctx->init_cmd_crc = uint32_big_decode((const uint8_t *)&p_trigger->init_crc);
+ p_dfu_ctx->firmware_size = uint32_big_decode((const uint8_t *)&p_trigger->image_length);
+ p_dfu_ctx->firmware_crc = uint32_big_decode((const uint8_t *)&p_trigger->image_crc);
+
+ // Mode flag was added in DFU Trigger version 1.
+ if (trigger_version >= 1)
+ {
+ p_dfu_ctx->dfu_mode = (background_dfu_mode_t)((p_trigger->flags
+ & TRIGGER_FLAGS_MODE_MASK) >> TRIGGER_FLAGS_MODE_OFFSET);
+ p_dfu_ctx->reset_suppress = (p_trigger->flags & TRIGGER_FLAGS_RESET_MASK) >>
+ TRIGGER_FLAGS_RESET_OFFSET;
+
+ }
+ else
+ {
+ p_dfu_ctx->dfu_mode = BACKGROUND_DFU_MODE_UNICAST;
+ }
+
+ NRF_LOG_INFO("DFU trigger: init (sz=%d, crc=%0X) image (sz=%d, crc=%0X)",
+ p_dfu_ctx->init_cmd_size,
+ p_dfu_ctx->init_cmd_crc,
+ p_dfu_ctx->firmware_size,
+ p_dfu_ctx->firmware_crc);
+
+ return true;
+ }
+
+ return false;
+}
+
+bool background_dfu_validate_trigger(background_dfu_context_t * p_dfu_ctx,
+ const uint8_t * p_payload,
+ uint32_t payload_len)
+{
+ if (payload_len != sizeof(background_dfu_trigger_t))
+ {
+ NRF_LOG_ERROR("Validate trigger: size mismatch");
+ return false;
+ }
+
+ if ((p_dfu_ctx->dfu_state != BACKGROUND_DFU_IDLE) &&
+ (p_dfu_ctx->dfu_state != BACKGROUND_DFU_DOWNLOAD_TRIG))
+ {
+ NRF_LOG_ERROR("Validate trigger: DFU already in progress (s:%s).",
+ (uint32_t)background_dfu_state_to_string(p_dfu_ctx->dfu_state));
+ return false;
+ }
+
+ uint8_t trigger_version = (((background_dfu_trigger_t *)p_payload)->flags
+ & TRIGGER_FLAGS_VERSION_MASK) >> TRIGGER_FLAGS_VERSION_OFFSET;
+ if (trigger_version > TRIGGER_VERSION)
+ {
+ NRF_LOG_ERROR("Validate trigger: invalid trigger version.");
+ return false;
+ }
+
+ return true;
+}
+
+bool background_dfu_process_trigger(background_dfu_context_t * p_dfu_ctx,
+ const uint8_t * p_payload,
+ uint32_t payload_len)
+{
+ bool result = false;
+
+ do
+ {
+ if (!parse_trigger(p_dfu_ctx, (background_dfu_trigger_t *)p_payload))
+ {
+ NRF_LOG_ERROR("Process trigger: failed to parse payload");
+ break;
+ }
+
+ p_dfu_ctx->dfu_state = BACKGROUND_DFU_DOWNLOAD_TRIG;
+
+ uint32_t err_code = background_dfu_handle_event(p_dfu_ctx,
+ BACKGROUND_DFU_EVENT_TRANSFER_COMPLETE);
+ if (err_code != NRF_SUCCESS)
+ {
+ NRF_LOG_ERROR("Error in background_dfu_handle_event (%d)", err_code);
+ }
+
+ result = true;
+ } while(0);
+
+ return result;
+}
+
+/***************************************************************************************************
+ * @section DFU checks
+ **************************************************************************************************/
+
+background_dfu_block_result_t background_dfu_process_block(background_dfu_context_t * p_dfu_ctx,
+ const background_dfu_block_t * p_block)
+{
+ background_dfu_block_result_t result = block_manager_block_process(&p_dfu_ctx->block_manager,
+ p_block);
+ uint32_t err_code = NRF_SUCCESS;
+
+ switch (result)
+ {
+ case BACKGROUND_DFU_BLOCK_IGNORE:
+ // Ignore.
+ if (p_dfu_ctx->dfu_mode == BACKGROUND_DFU_MODE_MULTICAST)
+ {
+ restart_block_timeout_timer(p_dfu_ctx);
+ }
+
+ break;
+
+ case BACKGROUND_DFU_BLOCK_SUCCESS:
+ // Intentionally empty.
+ break;
+
+ default:
+ err_code = background_dfu_handle_event(p_dfu_ctx, BACKGROUND_DFU_EVENT_PROCESSING_ERROR);
+ if (err_code != NRF_SUCCESS)
+ {
+ NRF_LOG_ERROR("Error in background_dfu_handle_event (%d)", err_code);
+ }
+
+ break;
+ }
+
+ return result;
+}
+
+/**@brief Check if installed image is different from the incoming one.
+ *
+ * @param[in] p_dfu_ctx A pointer to DFU client context.
+ *
+ * @return True if image different, false otherwise.
+ *
+ */
+static bool is_image_different(const background_dfu_context_t * p_dfu_ctx)
+{
+ if (s_dfu_settings.bank_0.bank_code == NRF_DFU_BANK_INVALID)
+ {
+ NRF_LOG_WARNING("No image in bank 0");
+ return true;
+ }
+
+ if (s_dfu_settings.bank_0.image_crc != p_dfu_ctx->firmware_crc)
+ {
+ NRF_LOG_WARNING("Installed image CRC is different");
+ return true;
+ }
+
+ return false;
+}
+
+/**
+ * @brief A callback function for block manager.
+ */
+static void dfu_block_manager_result_handler(background_dfu_block_result_t result, void * p_context)
+{
+ background_dfu_context_t * p_dfu_ctx = p_context;
+ uint32_t err_code;
+
+ if (result == BACKGROUND_DFU_BLOCK_SUCCESS)
+ {
+ if (p_dfu_ctx->dfu_mode == BACKGROUND_DFU_MODE_MULTICAST)
+ {
+ restart_block_timeout_timer(p_dfu_ctx);
+ }
+
+ if (block_manager_is_image_complete(&p_dfu_ctx->block_manager))
+ {
+ err_code = background_dfu_handle_event(p_dfu_ctx,
+ BACKGROUND_DFU_EVENT_TRANSFER_COMPLETE);
+ if (err_code != NRF_SUCCESS)
+ {
+ NRF_LOG_ERROR("Error in background_dfu_handle_event (%d)", err_code);
+ }
+ }
+ else
+ {
+ // FIXME I don't like it here.
+ p_dfu_ctx->block_num++;
+
+ err_code = background_dfu_handle_event(p_dfu_ctx,
+ BACKGROUND_DFU_EVENT_TRANSFER_CONTINUE);
+ if (err_code != NRF_SUCCESS)
+ {
+ NRF_LOG_ERROR("Error in background_dfu_handle_event (%d)", err_code);
+ }
+ }
+ }
+ else
+ {
+ err_code = background_dfu_handle_event(p_dfu_ctx, BACKGROUND_DFU_EVENT_PROCESSING_ERROR);
+ if (err_code != NRF_SUCCESS)
+ {
+ NRF_LOG_ERROR("Error in background_dfu_handle_event (%d)", err_code);
+ }
+ }
+}
+
+/**
+ * @brief Prepare state machine to download init command.
+ */
+static void setup_download_init_command(background_dfu_context_t * p_dfu_ctx)
+{
+ p_dfu_ctx->p_resource_size = &p_dfu_ctx->init_cmd_size;
+ p_dfu_ctx->retry_count = DEFAULT_RETRIES;
+ p_dfu_ctx->block_num = 0;
+
+ background_dfu_transport_state_update(p_dfu_ctx);
+
+ block_manager_init(&p_dfu_ctx->block_manager,
+ p_dfu_ctx->dfu_state,
+ *p_dfu_ctx->p_resource_size,
+ p_dfu_ctx->block_num,
+ dfu_block_manager_result_handler,
+ p_dfu_ctx);
+
+ if (p_dfu_ctx->dfu_mode == BACKGROUND_DFU_MODE_MULTICAST)
+ {
+ NRF_LOG_INFO("Init complete. Multicast Mode.");
+ uint32_t jitter = block_request_jitter_get();
+ uint32_t err_code = app_timer_start(m_missing_block_timer,
+ APP_TIMER_TICKS(jitter),
+ p_dfu_ctx);
+ if (err_code != NRF_SUCCESS)
+ {
+ NRF_LOG_ERROR("Error in app_timer_start (%d)", err_code);
+ }
+ }
+ else
+ {
+ NRF_LOG_INFO("Init complete. Unicast Mode.");
+ }
+}
+
+/**
+ * @brief A callback function for DFU command operations.
+ */
+static void dfu_init_check_callback(nrf_dfu_response_t * p_res, void * p_context)
+{
+ background_dfu_context_t * p_dfu_ctx = (background_dfu_context_t *)p_context;
+
+ switch (p_res->request)
+ {
+ case NRF_DFU_OP_OBJECT_SELECT:
+ if (p_res->result != NRF_DFU_RES_CODE_SUCCESS)
+ {
+ NRF_LOG_ERROR("No valid init command - select failed");
+ setup_download_init_command((background_dfu_context_t *)p_context);
+
+ UNUSED_RETURN_VALUE(background_dfu_handle_event(p_dfu_ctx, BACKGROUND_DFU_EVENT_TRANSFER_CONTINUE));
+ }
+
+ p_dfu_ctx->max_obj_size = p_res->select.max_size;
+ p_dfu_ctx->block_num = p_res->select.offset / DEFAULT_BLOCK_SIZE;
+
+ if (background_dfu_op_execute(dfu_init_check_callback, p_context) != NRF_SUCCESS)
+ {
+ NRF_LOG_ERROR("No valid init command - execute error");
+ setup_download_init_command((background_dfu_context_t *)p_context);
+
+ UNUSED_RETURN_VALUE(background_dfu_handle_event(p_dfu_ctx, BACKGROUND_DFU_EVENT_TRANSFER_CONTINUE));
+ }
+
+ break;
+
+ case NRF_DFU_OP_OBJECT_EXECUTE:
+ if ((p_res->result != NRF_DFU_RES_CODE_SUCCESS) ||
+ (s_dfu_settings.progress.command_crc != p_dfu_ctx->init_cmd_crc))
+ {
+ NRF_LOG_ERROR("Init commad has changed");
+ p_dfu_ctx->remaining_size = 0;
+ setup_download_init_command((background_dfu_context_t *)p_context);
+
+ UNUSED_RETURN_VALUE(background_dfu_handle_event(p_dfu_ctx, BACKGROUND_DFU_EVENT_TRANSFER_CONTINUE));
+ }
+ else
+ {
+ // Valid init command stored, download firmware.
+ p_dfu_ctx->dfu_diag.state = BACKGROUND_DFU_DOWNLOAD_INIT_CMD;
+
+ UNUSED_RETURN_VALUE(background_dfu_handle_event(p_dfu_ctx, BACKGROUND_DFU_EVENT_TRANSFER_COMPLETE));
+ }
+
+ break;
+
+ default:
+ ASSERT(false);
+ }
+}
+
+/**
+ * @brief A callback function for DFU data operation.
+ */
+static void dfu_data_select_callback(nrf_dfu_response_t * p_res, void * p_context)
+{
+ ASSERT(p_res->request == NRF_DFU_OP_OBJECT_SELECT);
+
+ background_dfu_context_t * p_dfu_ctx = (background_dfu_context_t *)p_context;
+ if (p_res->result != NRF_DFU_RES_CODE_SUCCESS)
+ {
+ NRF_LOG_ERROR("Select failed");
+ dfu_handle_error(p_dfu_ctx);
+ return;
+ }
+
+ p_dfu_ctx->dfu_state = BACKGROUND_DFU_DOWNLOAD_FIRMWARE;
+ p_dfu_ctx->p_resource_size = &p_dfu_ctx->firmware_size;
+ p_dfu_ctx->retry_count = DEFAULT_RETRIES;
+ p_dfu_ctx->block_num = (p_res->select.offset / DEFAULT_BLOCK_SIZE);
+ p_dfu_ctx->max_obj_size = p_res->select.max_size;
+
+ background_dfu_transport_state_update(p_dfu_ctx);
+
+ block_manager_init(&p_dfu_ctx->block_manager,
+ p_dfu_ctx->dfu_state,
+ *p_dfu_ctx->p_resource_size,
+ p_dfu_ctx->block_num,
+ dfu_block_manager_result_handler,
+ p_dfu_ctx);
+
+ UNUSED_RETURN_VALUE(background_dfu_handle_event(p_dfu_ctx, BACKGROUND_DFU_EVENT_TRANSFER_CONTINUE));
+}
+
+/***************************************************************************************************
+ * @section Timer handlers
+ **************************************************************************************************/
+
+/**@brief Handler function for block request timer.
+ *
+ * @param[inout] p_context DFU context.
+ */
+static void block_request_handler(void * p_context)
+{
+ background_dfu_context_t * p_dfu_ctx = (background_dfu_context_t *)p_context;
+
+ if ((p_dfu_ctx->dfu_state != BACKGROUND_DFU_DOWNLOAD_FIRMWARE) &&
+ (p_dfu_ctx->dfu_state != BACKGROUND_DFU_DOWNLOAD_INIT_CMD))
+ {
+ return;
+ }
+
+ background_dfu_request_bitmap_t req_bmp;
+ if (block_manager_request_bitmap_get(&p_dfu_ctx->block_manager, &req_bmp) &&
+ (req_bmp.size > 0))
+ {
+ background_dfu_transport_block_request_send(p_dfu_ctx, &req_bmp);
+ }
+
+ // Reschedule the timer.
+ uint32_t jitter = block_request_jitter_get();
+ uint32_t err_code = app_timer_start(m_missing_block_timer, APP_TIMER_TICKS(jitter), p_dfu_ctx);
+ if (err_code != NRF_SUCCESS)
+ {
+ NRF_LOG_ERROR("Error in app_timer_start (%d)", err_code);
+ }
+}
+
+/**@brief Handler function for block timeout timer.
+ *
+ * @param[inout] p_context DFU context.
+ */
+static void block_timeout_handler(void * p_context)
+{
+ background_dfu_context_t * p_dfu_ctx = (background_dfu_context_t *)p_context;
+
+ NRF_LOG_INFO("Block timeout! (b: %d)",
+ block_manager_get_current_block(&p_dfu_ctx->block_manager));
+
+ if ((p_dfu_ctx->dfu_state != BACKGROUND_DFU_DOWNLOAD_FIRMWARE) &&
+ (p_dfu_ctx->dfu_state != BACKGROUND_DFU_DOWNLOAD_INIT_CMD))
+ {
+ return;
+ }
+
+ if (block_manager_increment_current_block(&p_dfu_ctx->block_manager))
+ {
+ start_block_timeout_timer(p_dfu_ctx);
+ }
+}
+
+/***************************************************************************************************
+ * @section API functions
+ **************************************************************************************************/
+
+/** @brief Helper function converting DFU state to string.
+ *
+ * @param[in] state DFU client state.
+ *
+ * @return A pointer to null terminated string with state name.
+ */
+const char * background_dfu_state_to_string(const background_dfu_state_t state)
+{
+ static const char * const names[] =
+ {
+ "DFU_DOWNLOAD_INIT_CMD",
+ "DFU_DOWNLOAD_FIRMWARE",
+ "DFU_DOWNLOAD_TRIG",
+ "DFU_WAIT_FOR_RESET",
+ "DFU_IDLE",
+ "DFU_ERROR",
+ };
+
+ return names[(uint32_t)state - BACKGROUND_DFU_DOWNLOAD_INIT_CMD];
+}
+
+/** @brief Helper function convering DFU event name to string.
+ *
+ * @param[in] state DFU client event.
+ *
+ * @return A pointer to null terminated string with event name.
+ */
+const char * background_dfu_event_to_string(const background_dfu_event_t event)
+{
+ static const char * const names[] = {
+ "DFU_EVENT_TRANSFER_COMPLETE",
+ "DFU_EVENT_TRANSFER_CONTINUE",
+ "DFU_EVENT_TRANSFER_ERROR",
+ "DFU_EVENT_PROCESSING_ERROR",
+ };
+
+ return names[event];
+}
+
+uint32_t background_dfu_handle_event(background_dfu_context_t * p_dfu_ctx,
+ background_dfu_event_t event)
+{
+ uint32_t err_code = NRF_SUCCESS;
+
+ NRF_LOG_INFO("state=%s event=%s",
+ (uint32_t)background_dfu_state_to_string(p_dfu_ctx->dfu_state),
+ (uint32_t)background_dfu_event_to_string(event));
+
+ switch (p_dfu_ctx->dfu_state)
+ {
+ case BACKGROUND_DFU_IDLE:
+ {
+ if (event == BACKGROUND_DFU_EVENT_TRANSFER_COMPLETE)
+ {
+ p_dfu_ctx->dfu_diag.prev_state = BACKGROUND_DFU_IDLE;
+
+ p_dfu_ctx->dfu_state = BACKGROUND_DFU_DOWNLOAD_TRIG;
+ p_dfu_ctx->block_num = 0;
+ p_dfu_ctx->retry_count = DEFAULT_RETRIES;
+
+ background_dfu_transport_state_update(p_dfu_ctx);
+ }
+
+ break;
+ }
+
+ case BACKGROUND_DFU_DOWNLOAD_TRIG:
+ {
+ if (event == BACKGROUND_DFU_EVENT_TRANSFER_COMPLETE)
+ {
+ if (!is_image_different(p_dfu_ctx))
+ {
+ NRF_LOG_INFO("Image is already installed");
+ background_dfu_reset_state(p_dfu_ctx);
+ break;
+ }
+
+ p_dfu_ctx->dfu_diag.prev_state = BACKGROUND_DFU_DOWNLOAD_TRIG;
+
+ p_dfu_ctx->dfu_state = BACKGROUND_DFU_DOWNLOAD_INIT_CMD;
+
+ // Initiate init command check procedure.
+ if (background_dfu_op_select(NRF_DFU_OBJ_TYPE_COMMAND,
+ dfu_init_check_callback,
+ p_dfu_ctx) != NRF_SUCCESS)
+ {
+ NRF_LOG_ERROR("No valid init command - select error");
+ setup_download_init_command(p_dfu_ctx);
+ }
+ else
+ {
+ // We wait for dfu request to finish - do not send anything.
+ return NRF_SUCCESS;
+ }
+ }
+
+ break;
+ }
+
+ case BACKGROUND_DFU_DOWNLOAD_INIT_CMD:
+ {
+ if (event == BACKGROUND_DFU_EVENT_TRANSFER_COMPLETE)
+ {
+ p_dfu_ctx->dfu_diag.prev_state = BACKGROUND_DFU_DOWNLOAD_INIT_CMD;
+
+ if (p_dfu_ctx->dfu_mode == BACKGROUND_DFU_MODE_MULTICAST)
+ {
+ stop_block_timeout_timer(p_dfu_ctx);
+ }
+
+ if (background_dfu_op_select(NRF_DFU_OBJ_TYPE_DATA,
+ dfu_data_select_callback,
+ p_dfu_ctx) != NRF_SUCCESS)
+ {
+ NRF_LOG_ERROR("Select failed");
+ dfu_handle_error(p_dfu_ctx);
+ err_code = NRF_ERROR_INTERNAL;
+ }
+ else
+ {
+ return NRF_SUCCESS;
+ }
+ }
+ else if (event == BACKGROUND_DFU_EVENT_PROCESSING_ERROR)
+ {
+ p_dfu_ctx->dfu_diag.prev_state = BACKGROUND_DFU_DOWNLOAD_INIT_CMD;
+
+ if (p_dfu_ctx->dfu_mode == BACKGROUND_DFU_MODE_MULTICAST)
+ {
+ stop_block_timeout_timer(p_dfu_ctx);
+ }
+
+ NRF_LOG_ERROR("Processing error while downloading init command.");
+ dfu_handle_error(p_dfu_ctx);
+ }
+ break;
+ }
+
+ case BACKGROUND_DFU_DOWNLOAD_FIRMWARE:
+ {
+ if (event == BACKGROUND_DFU_EVENT_TRANSFER_COMPLETE)
+ {
+ p_dfu_ctx->dfu_diag.prev_state = BACKGROUND_DFU_DOWNLOAD_FIRMWARE;
+
+ p_dfu_ctx->dfu_state = BACKGROUND_DFU_WAIT_FOR_RESET;
+
+ if (p_dfu_ctx->dfu_mode == BACKGROUND_DFU_MODE_MULTICAST)
+ {
+ stop_block_timeout_timer(p_dfu_ctx);
+ }
+
+ background_dfu_transport_state_update(p_dfu_ctx);
+ }
+ else if (event == BACKGROUND_DFU_EVENT_PROCESSING_ERROR)
+ {
+ p_dfu_ctx->dfu_diag.prev_state = BACKGROUND_DFU_DOWNLOAD_FIRMWARE;
+
+ if (p_dfu_ctx->dfu_mode == BACKGROUND_DFU_MODE_MULTICAST)
+ {
+ stop_block_timeout_timer(p_dfu_ctx);
+ }
+
+ NRF_LOG_ERROR("Processing error while downloading firmware.");
+ dfu_handle_error(p_dfu_ctx);
+ }
+ break;
+ }
+
+ case BACKGROUND_DFU_WAIT_FOR_RESET:
+ NRF_LOG_WARNING("An event received in wait for reset state. This should not happen.");
+ break;
+
+ default:
+ NRF_LOG_ERROR("Unhandled state");
+ break;
+ }
+
+ if ((p_dfu_ctx->dfu_state != BACKGROUND_DFU_IDLE) &&
+ (p_dfu_ctx->dfu_state != BACKGROUND_DFU_ERROR) &&
+ (p_dfu_ctx->dfu_state != BACKGROUND_DFU_WAIT_FOR_RESET))
+ {
+ if (((p_dfu_ctx->dfu_state == BACKGROUND_DFU_DOWNLOAD_FIRMWARE) ||
+ (p_dfu_ctx->dfu_state == BACKGROUND_DFU_DOWNLOAD_INIT_CMD)) &&
+ (p_dfu_ctx->dfu_mode == BACKGROUND_DFU_MODE_MULTICAST))
+ {
+ // In multicast DFU firmware download, client doesn't initiate block requests.
+ }
+ else
+ {
+ if ((event == BACKGROUND_DFU_EVENT_TRANSFER_ERROR) && (p_dfu_ctx->retry_count > 0))
+ {
+ p_dfu_ctx->retry_count -= 1;
+ }
+
+ if (p_dfu_ctx->retry_count > 0)
+ {
+ background_dfu_transport_send_request(p_dfu_ctx);
+ }
+ else
+ {
+ NRF_LOG_ERROR("No more retries");
+ dfu_handle_error(p_dfu_ctx);
+ }
+ }
+ }
+
+ return err_code;
+}
+
+void background_dfu_reset_state(background_dfu_context_t * p_dfu_ctx)
+{
+ sha256_context_t sha256_ctx;
+
+ uint8_t hash[32];
+ uint32_t err_code = NRF_SUCCESS;
+
+ p_dfu_ctx->dfu_state = BACKGROUND_DFU_IDLE;
+ p_dfu_ctx->dfu_mode = BACKGROUND_DFU_MODE_UNICAST;
+ p_dfu_ctx->init_cmd_size = 0;
+ p_dfu_ctx->firmware_size = 0;
+ p_dfu_ctx->remaining_size = 0;
+
+ memset(&p_dfu_ctx->dfu_diag, 0, sizeof(p_dfu_ctx->dfu_diag));
+
+ err_code = sha256_init(&sha256_ctx);
+ if (err_code != NRF_SUCCESS)
+ {
+ NRF_LOG_ERROR("Error in sha256_init (%d)", err_code);
+ }
+
+ err_code = sha256_update(&sha256_ctx, (const uint8_t *)DFU_DATE_TIME, strlen(DFU_DATE_TIME));
+ if (err_code != NRF_SUCCESS)
+ {
+ NRF_LOG_ERROR("Error in sha256_update (%d)", err_code);
+ }
+
+ err_code = sha256_final(&sha256_ctx, (uint8_t *)hash, false);
+ if (err_code != NRF_SUCCESS)
+ {
+ NRF_LOG_ERROR("Error in sha256_final (%d)", err_code);
+ }
+
+ p_dfu_ctx->dfu_diag.build_id = uint32_big_decode(hash);
+ p_dfu_ctx->dfu_diag.state = BACKGROUND_DFU_IDLE;
+ p_dfu_ctx->dfu_diag.prev_state = BACKGROUND_DFU_IDLE;
+
+ NRF_LOG_INFO("Current DFU Diag version: %s, 0x%08x",
+ (uint32_t)DFU_DATE_TIME, p_dfu_ctx->dfu_diag.build_id);
+}
+
+void background_dfu_state_init(background_dfu_context_t * p_dfu_ctx)
+{
+ uint32_t err_code;
+
+ err_code = app_timer_create(&m_missing_block_timer,
+ APP_TIMER_MODE_SINGLE_SHOT,
+ block_request_handler);
+ if (err_code != NRF_SUCCESS)
+ {
+ NRF_LOG_ERROR("Error in app_timer_create (%d)", err_code);
+ }
+
+ err_code = app_timer_create(&m_block_timeout_timer,
+ APP_TIMER_MODE_SINGLE_SHOT,
+ block_timeout_handler);
+ if (err_code != NRF_SUCCESS)
+ {
+ NRF_LOG_ERROR("Error in app_timer_create (%d)", err_code);
+ }
+
+ background_dfu_reset_state(p_dfu_ctx);
+}
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/background_dfu/background_dfu_state.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/background_dfu/background_dfu_state.h
new file mode 100644
index 0000000..8dd4395
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/background_dfu/background_dfu_state.h
@@ -0,0 +1,216 @@
+/**
+ * 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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
+ *
+ * @defgroup background_dfu_state background_dfu_state.h
+ * @{
+ * @ingroup background_dfu
+ * @brief Background DFU state management.
+ *
+ */
+
+#ifndef BACKGROUND_DFU_STATE_H_
+#define BACKGROUND_DFU_STATE_H_
+
+#include <stdint.h>
+#include <stdbool.h>
+
+#include "background_dfu_block.h"
+#include "nrf_dfu_req_handler.h"
+
+/** @brief DFU client state ID.
+ *
+ * We reuse DFU object type IDs as DFU process states IDs,
+ * so that current state can be used as the object type in
+ * function which expect one.
+ */
+typedef enum
+{
+ BACKGROUND_DFU_DOWNLOAD_INIT_CMD = NRF_DFU_OBJ_TYPE_COMMAND,
+ BACKGROUND_DFU_DOWNLOAD_FIRMWARE = NRF_DFU_OBJ_TYPE_DATA,
+ BACKGROUND_DFU_DOWNLOAD_TRIG,
+ BACKGROUND_DFU_WAIT_FOR_RESET,
+ BACKGROUND_DFU_IDLE,
+ BACKGROUND_DFU_ERROR,
+} background_dfu_state_t;
+
+/** @brief DFU event definitions. */
+typedef enum
+{
+ BACKGROUND_DFU_EVENT_TRANSFER_COMPLETE,
+ BACKGROUND_DFU_EVENT_TRANSFER_CONTINUE,
+ BACKGROUND_DFU_EVENT_TRANSFER_ERROR,
+ BACKGROUND_DFU_EVENT_PROCESSING_ERROR,
+} background_dfu_event_t;
+
+/** @brief DFU mode definitions. */
+typedef enum
+{
+ BACKGROUND_DFU_MODE_UNICAST,
+ BACKGROUND_DFU_MODE_MULTICAST
+} background_dfu_mode_t;
+
+/** @brief Trigger packet structure. */
+typedef PACKED_STRUCT
+{
+ uint8_t flags; /**< Trigger message flags. Bits 7:4 (oldest) - trigger version, bit 3 - DFU mode, bits 2:0 - reserved. */
+ uint32_t init_length;
+ uint32_t init_crc;
+ uint32_t image_length;
+ uint32_t image_crc;
+} background_dfu_trigger_t;
+
+/**@brief Structure with DFU diagnostic information. */
+typedef PACKED_STRUCT background_dfu_diagnostic
+{
+ uint32_t build_id; /**< Build identifier, based on compilation time. */
+ uint8_t state; /**< Current DFU state. */
+ uint8_t prev_state; /**< Previous DFU state. */
+ uint16_t init_blocks_requested; /**< Number of requested missing init blocks. */
+ uint16_t image_blocks_requested; /**< Number of requested missing image blocks. */
+ uint16_t triggers_received; /**< Number of triggers received. */
+ uint16_t total_init_blocks_received; /**< Total number of init blocks received, including retransmitted ones. */
+ uint16_t total_image_blocks_received; /**< Total number of image blocks received, including retransmitted ones. */
+} background_dfu_diagnostic_t;
+
+/** @brief DFU client state. */
+typedef struct dfu_context
+{
+ background_dfu_state_t dfu_state; /**< Current DFU client state. */
+ background_dfu_mode_t dfu_mode; /**< Current DFU mode. */
+ bool reset_suppress; /**< If set then device won't automatically reset after
+ downloading firmware. */
+ background_dfu_diagnostic_t dfu_diag; /**< DFU diagnostic information. */
+
+ uint32_t init_cmd_size; /**< Current init command size. */
+ uint32_t init_cmd_crc; /**< Current init command checksum. */
+ uint32_t firmware_size; /**< Current firmware command size. */
+ uint32_t firmware_crc; /**< Current firmware command checksum. */
+ uint32_t max_obj_size; /**< Maximum size of the DFU object. */
+ uint32_t remaining_size; /**< Remaining size, in bytes, of the resource which
+ is being downloaded. */
+ /* TODO Move the block num to the block manager. */
+ uint32_t block_num; /**< Currently requested block number. */
+ uint32_t * p_resource_size; /**< Downloaded resource size. */
+ background_dfu_block_manager_t block_manager; /**< An entity managing block reception and storage. */
+ uint8_t retry_count; /**< Number of remaining retires. */
+} background_dfu_context_t;
+
+/**@brief Check if payload contains valid trigger.
+ *
+ * @param[inout] p_dfu_ctx DFU context.
+ * @param[in] p_payload A pointer to the message payload.
+ * @param[in[ payload_len Payload length.
+ *
+ * @return True if trigger was valid, false otherwise.
+ */
+bool background_dfu_validate_trigger(background_dfu_context_t * p_dfu_ctx,
+ const uint8_t * p_payload,
+ uint32_t payload_len);
+
+/**@brief Process a payload with a DFU trigger.
+ *
+ * @param[inout] p_dfu_ctx DFU context.
+ * @param[in] p_payload A pointer to the message payload.
+ * @param[in[ payload_len Payload length.
+ *
+ * @return True if trigger was successfully processed, false otherwise.
+ */
+bool background_dfu_process_trigger(background_dfu_context_t * p_dfu_ctx,
+ const uint8_t * p_payload,
+ uint32_t payload_len);
+
+/**@brief Process the block and return CoAP result code corresponding to the result of operation.
+ *
+ * @param[inout] p_dfu_ctx DFU context.
+ * @param[in] p_block A pointer to the block structure.
+ *
+ * @return True if init command is valid, false otherwise.
+ *
+ * @retval BACKGROUND_DFU_BLOCK_SUCCESS The block was processed correctly.
+ * @retval BACKGROUND_DFU_BLOCK_IGNORE The block was incorrect for this node, but did not
+ * indicate that the DFU shall be stopped.
+ * @retval BACKGROUND_DFU_BLOCK_INVALID The block indicated that the node would not catch-up with the DFU
+ * transfer or other error occured. Node aborted DFU.
+ * @retval BACKGROUND_DFU_BLOCK_STORE_ERROR DFU store error.
+ */
+background_dfu_block_result_t background_dfu_process_block(background_dfu_context_t * p_dfu_ctx,
+ const background_dfu_block_t * p_block);
+
+/**@brief DFU state machine handler.
+ *
+ * @param[in] p_dfu_ctx DFU context.
+ * @param[in] event DFU event.
+ *
+ * @return NRF_SUCCESS or error code
+ */
+uint32_t background_dfu_handle_event(background_dfu_context_t * p_dfu_ctx,
+ background_dfu_event_t event);
+
+/**@brief Reset state machine state.
+ *
+ * @param[in] p_dfu_ctx A pointer to DFU client context.
+ */
+void background_dfu_reset_state(background_dfu_context_t * p_dfu_ctx);
+
+/**@brief Initialize state machine state.
+ *
+ * @param[in] p_dfu_ctx A pointer to DFU client context.
+ */
+void background_dfu_state_init(background_dfu_context_t * p_dfu_ctx);
+
+/**@brief Convert a DFU event enum value to a string description.
+ *
+ * @param[in] event A DFU event.
+ *
+ * @return String representing the event.
+ */
+const char * background_dfu_event_to_string(const background_dfu_event_t event);
+
+/**@brief Convert a DFU state enum value to a string description.
+ *
+ * @param[in] event A DFU state.
+ *
+ * @return String representing the state.
+ */
+const char * background_dfu_state_to_string(const background_dfu_state_t state);
+
+#endif /* BACKGROUND_DFU_STATE_H_ */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/background_dfu/transport/background_dfu_transport.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/background_dfu/transport/background_dfu_transport.h
new file mode 100644
index 0000000..061a921
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/background_dfu/transport/background_dfu_transport.h
@@ -0,0 +1,91 @@
+/**
+ * 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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
+ *
+ * @defgroup background_dfu_transport background_dfu_state.h
+ * @{
+ * @ingroup background_dfu
+ * @brief Background DFU transport API.
+ *
+ */
+
+#ifndef BACKGROUND_DFU_TRANSPORT_H_
+#define BACKGROUND_DFU_TRANSPORT_H_
+
+#include "background_dfu_state.h"
+
+/**@brief Create and send DFU block request with missing blocks.
+ *
+ * This function is used in multicast DFU.
+ *
+ * @param[in] p_dfu_ctx A pointer to the background DFU context.
+ * @param[in] p_req_bmp A pointer to the bitmap structure that shall be sent.
+ */
+void background_dfu_transport_block_request_send(background_dfu_context_t * p_dfu_ctx,
+ background_dfu_request_bitmap_t * p_req_bmp);
+
+/**@brief Send background DFU request, based on DFU state.
+ *
+ * @param[in] p_dfu_ctx A pointer to the background DFU context.
+ */
+void background_dfu_transport_send_request(background_dfu_context_t * p_dfu_ctx);
+
+/**@brief Update background DFU transport state.
+ *
+ * @param[in] p_dfu_ctx A pointer to the background DFU context.
+ */
+void background_dfu_transport_state_update(background_dfu_context_t * p_dfu_ctx);
+
+/**@brief Get random value.
+ *
+ * @returns A random value of uint32_t type.
+ */
+uint32_t background_dfu_random(void);
+
+/** @brief Handle DFU error.
+ *
+ * Notify transport about DFU error.
+ */
+void background_dfu_handle_error(void);
+
+#endif /* BACKGROUND_DFU_COAP_H_ */
+
+/** @} */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/background_dfu/transport/tftp/tftp_dfu.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/background_dfu/transport/tftp/tftp_dfu.c
new file mode 100644
index 0000000..923d220
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/background_dfu/transport/tftp/tftp_dfu.c
@@ -0,0 +1,928 @@
+/**
+ * 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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
+ *
+ * @brief TFTP DFU Example - Background DFU transport implementation.
+ *
+ */
+#include "tftp_dfu.h"
+
+#include "background_dfu_transport.h"
+
+#include <stdbool.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <string.h>
+#include "app_timer.h"
+#include "background_dfu_block.h"
+#include "background_dfu_transport.h"
+#include "cJSON.h"
+#include "cJSON_iot_hooks.h"
+#include "crc16.h"
+#include "iot_file_static.h"
+#include "iot_tftp.h"
+#include "nrf.h"
+#include "nrf_assert.h"
+#include "nrf_delay.h"
+#include "nrf_dfu_req_handler.h"
+#include "nrf_dfu_settings.h"
+#include "nrf_dfu_utils.h"
+#include "nrf_log_ctrl.h"
+
+#define NRF_LOG_LEVEL 4
+#define NRF_LOG_MODULE_NAME TFTP_DFU
+#include "nrf_log.h"
+NRF_LOG_MODULE_REGISTER();
+
+#define MAX_LENGTH_FILENAME 32 /**< Maximum length of the filename. */
+#define MAX_CONFIG_SIZE 1024 /**< Maximum DFU of the config size. */
+
+#define CONFIG_APP_KEY "app"
+#define CONFIG_SD_KEY "sd"
+#define CONFIG_APPSD_KEY "appsd"
+#define CONFIG_BL_KEY "bl"
+#define CONFIG_PATH_KEY "p"
+#define CONFIG_INIT_PATH_KEY "i"
+#define CONFIG_SIZE_KEY "s"
+#define CONFIG_ID_KEY "id"
+#define CONFIG_INIT_SIZE_KEY "is"
+#define CONFIG_INIT_ID_KEY "iid"
+
+#define APP_TFTP_BLOCK_SIZE 512 /**< Maximum or negotiated size of data block. */
+#define APP_TFTP_RETRANSMISSION_TIME 3 /**< Number of milliseconds between retransmissions. */
+
+#define BOOTLOADER_REGION_START 0x0007D000 /**< This field should correspond to start address of the bootloader, found in UICR.RESERVED, 0x10001014, register.
+ This value is used for sanity check, so the bootloader will fail immediately if this value differs from runtime value.
+ The value is used to determine max application size for updating. */
+
+#define TFTP_SOFTDEVICE_UPGRADE_SUPPORT false /**< Upgrade of softdevice or bootloader is not supported with current version of Background DFU module. */
+
+/** The device info offset can be modified to place the device info settings at a different location.
+ * If the customer reserved UICR location is used for other application specific data, the offset
+ * must be updated to avoid collision with that data.:
+ */
+/** [DFU UICR DEV offset] */
+#define UICR_CUSTOMER_DEVICE_INFO_OFFSET 0x0 /**< Device info offset inside the customer UICR reserved area. Customers may change this value to place the device information in a user-preferred location. */
+/** [DFU UICR DEV offset] */
+#define UICR_CUSTOMER_RESERVED_OFFSET 0x80 /**< Customer reserved area in the UICR. The area from UICR + 0x80 is reserved for customer usage. */
+#define DFU_DEVICE_INFO_BASE (NRF_UICR_BASE + \
+ UICR_CUSTOMER_RESERVED_OFFSET + \
+ UICR_CUSTOMER_DEVICE_INFO_OFFSET) /**< The device information base address inside of UICR. */
+#define DFU_DEVICE_INFO ((dfu_device_info_t *)DFU_DEVICE_INFO_BASE) /**< The memory mapped structure for device information data. */
+
+
+/**@brief Structure holding basic device information settings.
+ */
+typedef struct
+{
+ uint16_t device_type; /**< Device type (2 bytes), for example Heart Rate. This number must be defined by the customer before production. It can be located in UICR or FICR. */
+ uint16_t device_rev; /**< Device revision (2 bytes), for example major revision 1, minor revision 0. This number must be defined by the customer before production. It can be located in UICR or FICR. */
+} dfu_device_info_t;
+
+/**@brief Description of single block of firmware. */
+typedef struct
+{
+ uint32_t size; /**< Size of firmware block. */
+ uint32_t crc; /**< CRC of firmware block. Set to 0 if no checksum checking is needed. */
+ uint32_t init_size; /**< Size of init file. */
+ uint32_t init_crc; /**< CRC of init file. */
+} iot_dfu_firmware_block_t;
+
+
+/**@brief Description of the new firmware that has been written into flash memory. */
+typedef struct
+{
+ iot_dfu_firmware_block_t application; /**< Description of Application block in firmware image. */
+ iot_dfu_firmware_block_t softdevice; /**< Description of SoftDevice block in firmware image. */
+ iot_dfu_firmware_block_t bootloader; /**< Description of Bootloader block in firmware image. */
+} iot_dfu_firmware_desc_t;
+
+/**@brief Type of image being updated by the DFU module. */
+typedef enum
+{
+ TFTP_DFU_IMAGE_TYPE_APPLICATION, /**< DFU updates application. */
+ TFTP_DFU_IMAGE_TYPE_SOFTDEVICE, /**< DFU updates softdevice and application. */
+ TFTP_DFU_IMAGE_TYPE_BOOTLOADER, /**< DFU updates bootloader. */
+} tftp_dfu_image_type_t;
+
+/**@brief Static data used by TFTP DFU module. */
+typedef struct
+{
+ iot_tftp_t tftp; /**< TFTP instance. */
+ char resource_path[MAX_LENGTH_FILENAME]; /**< Path of remote resource to get. */
+ uint32_t block_number; /**< Number of block that will be passed to background DFU module. */
+ uint8_t block[DEFAULT_BLOCK_SIZE]; /**< Buffer for parts of blocks to pass to background DFU module. */
+ uint16_t block_size; /**< Size of data in block buffer. */
+ tftp_dfu_image_type_t image_type; /**< Type of image that is currently updated. */
+ iot_file_t config_file; /**< Pointer to the file used for config of DFU. */
+ uint8_t config_mem[MAX_CONFIG_SIZE]; /**< Static memory for configuration file. */
+ cJSON * p_config_json; /**< Pointer of cJSON instance. */
+ iot_dfu_firmware_desc_t firmware_desc; /**< Details from configuration file. */
+} tftp_dfu_context_t;
+
+static background_dfu_context_t m_dfu_ctx; /**< Background DFU context. */
+static tftp_dfu_context_t m_tftp_dfu_ctx; /**< TFTP DFU context. */
+
+/***************************************************************************************************
+ * @section Common operations
+ **************************************************************************************************/
+
+/**@brief Set resource path to trigger (config) file. */
+static void trigger_path_set(void)
+{
+ int retval = snprintf(m_tftp_dfu_ctx.resource_path,
+ sizeof(m_tftp_dfu_ctx.resource_path),
+ "/dfu/c/%d/%d",
+ DFU_DEVICE_INFO->device_type,
+ DFU_DEVICE_INFO->device_rev);
+ if (retval < 0) {
+ NRF_LOG_ERROR("Failed to set path using snprintf, retval: %d", retval);
+ }
+}
+
+/**@brief Function for reading binary path from JSON configuration.
+ *
+ * @param[out] p_dst_str Pointer to memory, where path should be stored.
+ * @param[in] p_key Key inside JSON configuration file, describing firmware.
+ *
+ * @return NRF_SUCCESS if path found and stored in p_dst_str, otherwise error code.
+ */
+static uint32_t get_path(char * p_dst_str, const char * p_key)
+{
+ cJSON * p_cursor;
+
+ if ((m_tftp_dfu_ctx.p_config_json == NULL) || (p_dst_str == NULL))
+ {
+ NRF_LOG_ERROR("Invalid parameters");
+ return NRF_ERROR_INVALID_PARAM;
+ }
+
+ p_cursor = cJSON_GetObjectItem(m_tftp_dfu_ctx.p_config_json, CONFIG_PATH_KEY);
+ if (p_cursor != NULL)
+ {
+ p_cursor = cJSON_GetObjectItem(p_cursor, (const char *)p_key);
+ if ((p_cursor != NULL) && (p_cursor->type == cJSON_String))
+ {
+ memcpy(p_dst_str, p_cursor->valuestring, strlen(p_cursor->valuestring));
+ }
+ else
+ {
+ return NRF_ERROR_INVALID_PARAM;
+ }
+ }
+ else
+ {
+ return NRF_ERROR_INVALID_PARAM;
+ }
+
+ return NRF_SUCCESS;
+}
+
+/**@brief Function for reading init binary path from JSON configuration.
+ *
+ * @param[out] p_dst_str Pointer to memory, where path should be stored.
+ * @param[in] p_key Key inside JSON configuration file, describing firmware.
+ *
+ * @return NRF_SUCCESS if path found and stored in p_dst_str, otherwise error code.
+ */
+static uint32_t get_init_path(char * p_dst_str, const char * p_key)
+{
+ cJSON * p_cursor;
+
+ if ((m_tftp_dfu_ctx.p_config_json == NULL) || (p_dst_str == NULL))
+ {
+ NRF_LOG_ERROR("Invalid parameters");
+ return NRF_ERROR_INVALID_PARAM;
+ }
+
+ p_cursor = cJSON_GetObjectItem(m_tftp_dfu_ctx.p_config_json, CONFIG_INIT_PATH_KEY);
+ if (p_cursor != NULL)
+ {
+ p_cursor = cJSON_GetObjectItem(p_cursor, (const char *)p_key);
+ if ((p_cursor != NULL) && (p_cursor->type == cJSON_String))
+ {
+ memcpy(p_dst_str, p_cursor->valuestring, strlen(p_cursor->valuestring));
+ }
+ else
+ {
+ return NRF_ERROR_INVALID_PARAM;
+ }
+ }
+ else
+ {
+ return NRF_ERROR_INVALID_PARAM;
+ }
+
+ return NRF_SUCCESS;
+}
+
+/**@brief Function for parsing JSON file to get details of an application.
+ *
+ * @param[in] p_key Key inside JSON configuration file, describing firmware.
+ * @param[out] p_block Pointer to structure containing description of single block of firmware.
+ *
+ * @returns NRF_SUCCESS if correctly parsed data. Otherwise an error code indicating failure reason.
+ */
+static uint32_t details_parse(const char * p_key, iot_dfu_firmware_block_t * p_block)
+{
+ cJSON * p_cursor;
+ cJSON * p_cursor_back;
+
+ // Clear output parameters.
+ memset(p_block, 0, sizeof(*p_block));
+
+ if (m_tftp_dfu_ctx.p_config_json == NULL)
+ {
+ NRF_LOG_ERROR("Invalid JSON file");
+ return NRF_ERROR_INVALID_DATA;
+ }
+
+ p_cursor = cJSON_GetObjectItem(m_tftp_dfu_ctx.p_config_json, (const char *)p_key);
+ if (p_cursor != NULL)
+ {
+ p_cursor_back = p_cursor;
+ p_cursor = cJSON_GetObjectItem(p_cursor, CONFIG_ID_KEY);
+ if (p_cursor != NULL)
+ {
+ if (p_cursor->type != cJSON_Number)
+ {
+ return NRF_ERROR_INVALID_DATA;
+ }
+
+ p_block->crc = p_cursor->valueint;
+ }
+ else
+ {
+ NRF_LOG_ERROR("No binary ID inside JSON.");
+ return NRF_ERROR_INVALID_DATA;
+ }
+
+ p_cursor = p_cursor_back;
+ p_cursor = cJSON_GetObjectItem(p_cursor, CONFIG_INIT_SIZE_KEY);
+ if (p_cursor != NULL)
+ {
+ if (p_cursor->type != cJSON_Number)
+ {
+ return NRF_ERROR_INVALID_DATA;
+ }
+
+ p_block->init_size = p_cursor->valueint;
+ }
+ else
+ {
+ NRF_LOG_ERROR("No init SIZE inside JSON.");
+ return NRF_ERROR_INVALID_DATA;
+ }
+
+ p_cursor = p_cursor_back;
+ p_cursor = cJSON_GetObjectItem(p_cursor, CONFIG_INIT_ID_KEY);
+ if (p_cursor != NULL)
+ {
+ if (p_cursor->type != cJSON_Number)
+ {
+ return NRF_ERROR_INVALID_DATA;
+ }
+
+ p_block->init_crc = p_cursor->valueint;
+ }
+ else
+ {
+ NRF_LOG_ERROR("No init ID inside JSON.");
+ return NRF_ERROR_INVALID_DATA;
+ }
+
+ p_cursor = p_cursor_back;
+ p_cursor = cJSON_GetObjectItem(p_cursor, CONFIG_SIZE_KEY);
+ if (p_cursor != NULL)
+ {
+ if ((p_cursor->type != cJSON_Number) || (p_cursor->valueint == 0))
+ {
+ return NRF_ERROR_INVALID_DATA;
+ }
+
+ p_block->size = p_cursor->valueint;
+ }
+ else
+ {
+ NRF_LOG_ERROR("No binary SIZE inside JSON.");
+ return NRF_ERROR_INVALID_DATA;
+ }
+ }
+ else
+ {
+ NRF_LOG_ERROR("No binary KEY inside JSON.");
+ return NRF_ERROR_INVALID_DATA;
+ }
+
+ return NRF_SUCCESS;
+}
+
+
+/**@brief Function for parsing and processing config file.
+ *
+ * @param[out] p_dfu_firmware_desc Details of available firmware images (size and CRC)
+ * @param[out] p_filename Remote path to init file that should be downloaded in DFU process
+ *
+ * @return NRF_SUCCESS If config file is valid. Otherwise an error code indicating failure reason.
+ */
+static uint32_t app_dfu_config_process(iot_dfu_firmware_desc_t * p_dfu_firmware_desc,
+ char * p_filename)
+{
+ uint32_t err_code = NRF_SUCCESS;
+ iot_dfu_firmware_block_t app;
+#if TFTP_SOFTDEVICE_UPGRADE_SUPPORT
+ iot_dfu_firmware_block_t sd;
+ iot_dfu_firmware_block_t bl;
+#endif // TFTP_SOFTDEVICE_UPGRADE_SUPPORT
+ bool app_present = false;
+#if TFTP_SOFTDEVICE_UPGRADE_SUPPORT
+ bool sd_present = false;
+ bool bl_present = false;
+#endif // TFTP_SOFTDEVICE_UPGRADE_SUPPORT
+
+ // Clear global parameters before parsing a new one.
+ memset(p_filename, 0, MAX_LENGTH_FILENAME);
+
+ m_tftp_dfu_ctx.p_config_json = cJSON_Parse((const char *)m_tftp_dfu_ctx.config_mem);
+ if (m_tftp_dfu_ctx.p_config_json == NULL)
+ {
+ NRF_LOG_ERROR("JSON parse failed.");
+ return NRF_ERROR_INVALID_DATA;
+ }
+
+#if TFTP_SOFTDEVICE_UPGRADE_SUPPORT
+ if (details_parse(CONFIG_SD_KEY, &sd) == NRF_SUCCESS)
+ {
+ sd_present = true;
+ }
+
+ if (details_parse(CONFIG_BL_KEY, &bl) == NRF_SUCCESS)
+ {
+ bl_present = true;
+ }
+#endif // TFTP_SOFTDEVICE_UPGRADE_SUPPORT
+
+ if (details_parse(CONFIG_APP_KEY, &app) == NRF_SUCCESS)
+ {
+ app_present = true;
+ }
+
+#if TFTP_SOFTDEVICE_UPGRADE_SUPPORT
+ // Background DFU does not support SoftDevice or bootloader update yet.
+ if ((sd_present) && (app_present))
+ {
+ NRF_LOG_INFO("Update Softdevice with Application.");
+ m_tftp_dfu_ctx.image_type = TFTP_DFU_IMAGE_TYPE_SOFTDEVICE;
+ }
+ else if (bl_present)
+ {
+ NRF_LOG_INFO("Update Bootloader.");
+ m_tftp_dfu_ctx.image_type = TFTP_DFU_IMAGE_TYPE_BOOTLOADER;
+ }
+ else
+#endif // TFTP_SOFTDEVICE_UPGRADE_SUPPORT
+ {
+ if (app_present)
+ {
+ NRF_LOG_INFO("Update Application only.");
+ m_tftp_dfu_ctx.image_type = TFTP_DFU_IMAGE_TYPE_APPLICATION;
+ }
+ else
+ {
+ // This example application does not implement SoftDevice with Bootloader update
+ NRF_LOG_INFO("Device firmware up to date.");
+ err_code = NRF_ERROR_NOT_FOUND;
+ }
+ }
+
+ if (err_code == NRF_SUCCESS)
+ {
+ switch (m_tftp_dfu_ctx.image_type)
+ {
+ case TFTP_DFU_IMAGE_TYPE_APPLICATION:
+ err_code = get_init_path(p_filename, CONFIG_APP_KEY);
+ if (err_code == NRF_SUCCESS)
+ {
+ p_dfu_firmware_desc->application = app;
+ }
+
+ break;
+
+#if TFTP_SOFTDEVICE_UPGRADE_SUPPORT
+ case TFTP_DFU_IMAGE_TYPE_BOOTLOADER:
+ err_code = get_init_path(p_filename, CONFIG_BL_KEY);
+ if (err_code == NRF_SUCCESS)
+ {
+ p_dfu_firmware_desc->bootloader = bl;
+ }
+
+ break;
+
+ case TFTP_DFU_IMAGE_TYPE_SOFTDEVICE:
+ err_code = get_init_path(p_filename, CONFIG_APPSD_KEY);
+ if (err_code == NRF_SUCCESS)
+ {
+ p_dfu_firmware_desc->softdevice = sd;
+ p_dfu_firmware_desc->application = app;
+ }
+
+ break;
+#endif // TFTP_SOFTDEVICE_UPGRADE_SUPPORT
+
+ default:
+ ASSERT(false);
+ }
+ }
+
+ if (p_filename[0] == '\0')
+ {
+ NRF_LOG_ERROR("File name has not be found.");
+ err_code = NRF_ERROR_INVALID_PARAM;
+ }
+
+ cJSON_Delete(m_tftp_dfu_ctx.p_config_json);
+
+ return err_code;
+}
+
+/** @brief Set resource path to point to firmware binary file.
+ *
+ * @param [out] p_filename Pointer to resource path.
+ *
+ * @return NRF_SUCCESS if setting firmware path succeeded or error code indicating failure reason.
+ */
+static uint32_t set_firmware_path(char * p_filename)
+{
+ uint32_t err_code = NRF_SUCCESS;
+
+ m_tftp_dfu_ctx.p_config_json = cJSON_Parse((const char *)m_tftp_dfu_ctx.config_mem);
+ if (m_tftp_dfu_ctx.p_config_json == NULL)
+ {
+ NRF_LOG_ERROR("JSON parse failed.");
+ return NRF_ERROR_INVALID_DATA;
+ }
+
+ switch (m_tftp_dfu_ctx.image_type)
+ {
+ case TFTP_DFU_IMAGE_TYPE_APPLICATION:
+ err_code = get_path(p_filename, CONFIG_APP_KEY);
+ break;
+
+ case TFTP_DFU_IMAGE_TYPE_BOOTLOADER:
+ err_code = get_path(p_filename, CONFIG_BL_KEY);
+ break;
+
+ case TFTP_DFU_IMAGE_TYPE_SOFTDEVICE:
+ err_code = get_path(p_filename, CONFIG_APPSD_KEY);
+ break;
+
+ default:
+ ASSERT(false);
+ }
+
+ if (p_filename[0] == '\0')
+ {
+ NRF_LOG_ERROR("File name has not be found.");
+ err_code = NRF_ERROR_INVALID_PARAM;
+ }
+
+ cJSON_Delete(m_tftp_dfu_ctx.p_config_json);
+
+ return err_code;
+}
+
+/** @brief Send download request to the TFTP server.
+ *
+ * @param[in] p_file Pointer to file instance used to store file. May be NULL if file is not
+ * stored by TFTP module.
+ */
+static void send_request(iot_file_t * p_file)
+{
+ uint32_t err_code;
+ iot_tftp_trans_params_t trans_params;
+
+ trans_params.block_size = APP_TFTP_BLOCK_SIZE;
+ trans_params.next_retr = APP_TFTP_RETRANSMISSION_TIME;
+
+ err_code = iot_tftp_set_params(&m_tftp_dfu_ctx.tftp, &trans_params);
+ ASSERT(err_code == NRF_SUCCESS);
+
+ err_code = iot_tftp_get(&m_tftp_dfu_ctx.tftp, p_file, m_tftp_dfu_ctx.resource_path);
+ ASSERT(err_code == NRF_SUCCESS);
+
+ UNUSED_VARIABLE(err_code);
+}
+
+/***************************************************************************************************
+ * @section TFTP handler
+ **************************************************************************************************/
+
+/**
+ * @brief Process retrieved config file
+ *
+ * @param[in] p_file Pointer to retrieved config file.
+ */
+static void config_file_retrieved(iot_file_t * p_file)
+{
+ uint32_t err_code;
+ background_dfu_trigger_t trigger;
+ iot_dfu_firmware_block_t * p_firmware_block = NULL;
+
+ NRF_LOG_INFO("Config file successfully downloaded.");
+
+ m_tftp_dfu_ctx.config_mem[p_file->file_size] = 0;
+ memset(&m_tftp_dfu_ctx.firmware_desc, 0, sizeof(m_tftp_dfu_ctx.firmware_desc));
+
+ err_code = app_dfu_config_process(&m_tftp_dfu_ctx.firmware_desc, m_tftp_dfu_ctx.resource_path);
+
+ if (err_code == NRF_SUCCESS)
+ {
+ NRF_LOG_INFO("New sofware available. Starting downloading procedure.");
+
+ switch(m_tftp_dfu_ctx.image_type)
+ {
+ case TFTP_DFU_IMAGE_TYPE_APPLICATION:
+ p_firmware_block = &m_tftp_dfu_ctx.firmware_desc.application;
+ break;
+
+ case TFTP_DFU_IMAGE_TYPE_BOOTLOADER:
+ p_firmware_block = &m_tftp_dfu_ctx.firmware_desc.bootloader;
+ break;
+
+ case TFTP_DFU_IMAGE_TYPE_SOFTDEVICE:
+ p_firmware_block = &m_tftp_dfu_ctx.firmware_desc.softdevice;
+ break;
+ }
+
+ memset(&trigger, 0, sizeof(trigger));
+ trigger.init_length = uint32_big_decode((const uint8_t *)&p_firmware_block->init_size);
+ trigger.init_crc = uint32_big_decode((const uint8_t *)&p_firmware_block->init_crc);
+ trigger.image_length = uint32_big_decode((const uint8_t *)&p_firmware_block->size);
+ trigger.image_crc = uint32_big_decode((const uint8_t *)&p_firmware_block->crc);
+
+ if (background_dfu_validate_trigger(&m_dfu_ctx, (uint8_t *)&trigger, sizeof(trigger)))
+ {
+ if (!background_dfu_process_trigger(&m_dfu_ctx, (uint8_t *)&trigger, sizeof(trigger)))
+ {
+ NRF_LOG_ERROR("Error in TFTP background_dfu_process_trigger");
+ }
+
+ if (m_dfu_ctx.dfu_state == BACKGROUND_DFU_IDLE)
+ {
+ // State in DFU_IDLE, nothing to download.
+ err_code = iot_tftp_uninit(&m_tftp_dfu_ctx.tftp);
+ if (err_code != NRF_SUCCESS)
+ {
+ NRF_LOG_ERROR("Error in TFTP uninit (%d)", err_code);
+ }
+ }
+ }
+ }
+ else
+ {
+ NRF_LOG_INFO("No new sofware available or incorrect JSON file.");
+ }
+}
+
+/**
+ * @brief Pass block of retrieved data to background DFU module.
+ *
+ * @param[in] p_block Pointer to block of retrieved data.
+ */
+static void process_block(uint8_t * p_block)
+{
+ background_dfu_block_t block;
+ background_dfu_block_result_t result;
+
+ block.number = m_tftp_dfu_ctx.block_number;
+ block.size = DEFAULT_BLOCK_SIZE;
+ block.p_payload = p_block;
+
+ m_tftp_dfu_ctx.block_number++;
+
+ result = background_dfu_process_block(&m_dfu_ctx, &block);
+ if (result != BACKGROUND_DFU_BLOCK_SUCCESS)
+ {
+ NRF_LOG_ERROR("Error in TFTP background_dfu_process_block (%d)", result);
+ }
+}
+
+/**
+ * @brief Process retrieved data chunk.
+ *
+ * Split retrieved data to blocks of DEFAULT_BLOCK_SIZE bytes and pass to DFU module.
+ *
+ * @param[in] p_data_received Pointer to structure describing received data chunk.
+ */
+static void data_chunk_retrieved(iot_tftp_evt_data_received_t * p_data_received)
+{
+ uint16_t processed_bytes = 0;
+
+ // Process part of block from previous chunk
+ if (m_tftp_dfu_ctx.block_size)
+ {
+ uint16_t first_block_missing_size = DEFAULT_BLOCK_SIZE - m_tftp_dfu_ctx.block_size;
+
+ if (p_data_received->size < first_block_missing_size)
+ {
+ first_block_missing_size = p_data_received->size;
+ }
+
+ memcpy(&m_tftp_dfu_ctx.block[m_tftp_dfu_ctx.block_size],
+ p_data_received->p_data,
+ first_block_missing_size);
+
+ process_block(m_tftp_dfu_ctx.block);
+
+ processed_bytes = first_block_missing_size;
+ }
+
+ // Process received chunks
+ while (p_data_received->size - processed_bytes >= DEFAULT_BLOCK_SIZE)
+ {
+ process_block(&p_data_received->p_data[processed_bytes]);
+ processed_bytes += DEFAULT_BLOCK_SIZE;
+ }
+
+ m_tftp_dfu_ctx.block_size = p_data_received->size - processed_bytes;
+
+ // Leave not processed data
+ if (p_data_received->size > processed_bytes)
+ {
+ memcpy(m_tftp_dfu_ctx.block,
+ &p_data_received->p_data[processed_bytes],
+ m_tftp_dfu_ctx.block_size);
+ }
+}
+
+/**
+ * @brief Process data left from previous chunk.
+ */
+static void preserved_block_process(void)
+{
+ process_block(m_tftp_dfu_ctx.block);
+ m_tftp_dfu_ctx.block_size = 0;
+}
+
+/**
+ * @brief Handler of TFTP events.
+ */
+static void tftp_dfu_tftp_handler(iot_tftp_t * p_tftp, iot_tftp_evt_t * p_evt)
+{
+ switch (p_evt->id)
+ {
+ case IOT_TFTP_EVT_TRANSFER_DATA_RECEIVED:
+ switch (m_dfu_ctx.dfu_state)
+ {
+ case BACKGROUND_DFU_DOWNLOAD_TRIG:
+ break;
+
+ case BACKGROUND_DFU_DOWNLOAD_INIT_CMD:
+ case BACKGROUND_DFU_DOWNLOAD_FIRMWARE:
+ data_chunk_retrieved(&p_evt->param.data_received);
+ break;
+
+ default:
+ ASSERT(false);
+ break;
+ }
+ break;
+
+ case IOT_TFTP_EVT_TRANSFER_GET_COMPLETE:
+ switch (m_dfu_ctx.dfu_state)
+ {
+ case BACKGROUND_DFU_DOWNLOAD_TRIG:
+ config_file_retrieved(p_evt->p_file);
+ break;
+
+ case BACKGROUND_DFU_DOWNLOAD_INIT_CMD:
+ case BACKGROUND_DFU_DOWNLOAD_FIRMWARE:
+ preserved_block_process();
+ break;
+
+ default:
+ ASSERT(false);
+ break;
+ }
+ break;
+
+ case IOT_TFTP_EVT_ERROR:
+ background_dfu_handle_error();
+ break;
+
+ default:
+ ASSERT(false);
+ break;
+ }
+}
+
+static void dfu_observer(nrf_dfu_evt_type_t evt_type)
+{
+ switch (evt_type)
+ {
+ case NRF_DFU_EVT_DFU_COMPLETED:
+ NRF_LOG_FINAL_FLUSH();
+
+#if NRF_MODULE_ENABLED(NRF_LOG_BACKEND_RTT)
+ // To allow the buffer to be flushed by the host.
+ nrf_delay_ms(100);
+#endif
+
+ NVIC_SystemReset();
+ break;
+
+ default:
+ break;
+ }
+}
+
+
+/***************************************************************************************************
+ * @section Private API
+ **************************************************************************************************/
+
+void background_dfu_transport_block_request_send(background_dfu_context_t * p_dfu_ctx,
+ background_dfu_request_bitmap_t * p_req_bmp)
+{
+ // Intentionally empty: multicast DFU not implemented.
+}
+
+void background_dfu_transport_send_request(background_dfu_context_t * p_dfu_ctx)
+{
+ switch (m_dfu_ctx.dfu_state)
+ {
+ case BACKGROUND_DFU_DOWNLOAD_TRIG:
+ send_request(&m_tftp_dfu_ctx.config_file);
+ break;
+
+ default:
+ // In other states download operation is triggered by state_update() notification.
+ break;
+ }
+}
+
+void background_dfu_transport_state_update(background_dfu_context_t * p_dfu_ctx)
+{
+ switch (p_dfu_ctx->dfu_state)
+ {
+ case BACKGROUND_DFU_DOWNLOAD_TRIG:
+ trigger_path_set();
+ break;
+
+ case BACKGROUND_DFU_DOWNLOAD_INIT_CMD:
+ m_tftp_dfu_ctx.block_number = 0;
+ m_tftp_dfu_ctx.block_size = 0;
+ send_request(NULL);
+ break;
+
+ case BACKGROUND_DFU_DOWNLOAD_FIRMWARE:
+ m_tftp_dfu_ctx.block_number = 0;
+ m_tftp_dfu_ctx.block_size = 0;
+ UNUSED_RETURN_VALUE(set_firmware_path(m_tftp_dfu_ctx.resource_path));
+ send_request(NULL);
+ break;
+
+ case BACKGROUND_DFU_WAIT_FOR_RESET:
+ // Do nothing.
+ break;
+
+ default:
+ NRF_LOG_WARNING("Unhandled state in background_dfu_transport_state_update (s: %s).",
+ (uint32_t)background_dfu_state_to_string(p_dfu_ctx->dfu_state));
+ }
+}
+
+uint32_t background_dfu_random(void)
+{
+ // Intentionally empty: multicast DFU not implemented.
+ return 0;
+}
+
+/***************************************************************************************************
+ * @section Public API
+ **************************************************************************************************/
+
+uint32_t tftp_dfu_init(void)
+{
+ uint32_t err_code = NRF_SUCCESS;
+
+ memset(&m_tftp_dfu_ctx, 0, sizeof(m_tftp_dfu_ctx));
+
+ err_code = nrf_dfu_settings_init(true);
+ if (err_code != NRF_SUCCESS)
+ {
+ return err_code;
+ }
+ err_code = nrf_dfu_req_handler_init(dfu_observer);
+ if (err_code != NRF_SUCCESS)
+ {
+ return err_code;
+ }
+
+ background_dfu_state_init(&m_dfu_ctx);
+
+ cJSON_Init();
+
+ // Initialize file static instance.
+ IOT_FILE_STATIC_INIT(&m_tftp_dfu_ctx.config_file,
+ m_tftp_dfu_ctx.resource_path,
+ m_tftp_dfu_ctx.config_mem,
+ MAX_CONFIG_SIZE);
+
+ return err_code;
+}
+
+uint32_t tftp_dfu_trigger(const ipv6_addr_t * p_host_ipv6, uint16_t src_port, uint16_t dst_port)
+{
+ uint32_t err_code;
+ iot_tftp_init_t tftp_init_params;
+
+ NRF_LOG_INFO("Triggering DFU");
+
+ if (p_host_ipv6 == NULL)
+ {
+ NRF_LOG_WARNING("NULL IPv6 address");
+ return NRF_ERROR_NULL;
+ }
+
+ if (m_dfu_ctx.dfu_state != BACKGROUND_DFU_IDLE)
+ {
+ NRF_LOG_WARNING("Invalid state");
+ return NRF_ERROR_INVALID_STATE;
+ }
+
+ // Set TFTP configuration
+ memset(&tftp_init_params, 0, sizeof(iot_tftp_init_t));
+ tftp_init_params.p_ipv6_addr = (ipv6_addr_t *)p_host_ipv6;
+ tftp_init_params.src_port = src_port;
+ tftp_init_params.dst_port = dst_port;
+ tftp_init_params.callback = tftp_dfu_tftp_handler;
+
+ // Initialize instance, bind socket, check parameters.
+ err_code = iot_tftp_init(&m_tftp_dfu_ctx.tftp, &tftp_init_params);
+ if (err_code != NRF_SUCCESS)
+ {
+ NRF_LOG_ERROR("Error in TFTP init (%d)", err_code);
+ return err_code;
+ }
+
+ trigger_path_set();
+
+ // Transition from DFU_IDLE to DFU_DOWNLOAD_TRIG.
+ return background_dfu_handle_event(&m_dfu_ctx, BACKGROUND_DFU_EVENT_TRANSFER_COMPLETE);
+}
+
+void background_dfu_handle_error(void)
+{
+ UNUSED_RETURN_VALUE(iot_tftp_uninit(&m_tftp_dfu_ctx.tftp));
+ tftp_dfu_handle_error();
+}
+
+__WEAK void tftp_dfu_handle_error(void)
+{
+
+}
+
+bool nrf_dfu_button_enter_check(void)
+{
+ // Dummy function for Keil compilation. This should not be called.
+ return false;
+}
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/background_dfu/transport/tftp/tftp_dfu.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/background_dfu/transport/tftp/tftp_dfu.h
new file mode 100644
index 0000000..6c8370b
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/background_dfu/transport/tftp/tftp_dfu.h
@@ -0,0 +1,80 @@
+/**
+ * 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 tftp_dfu.h
+ *
+ * @defgroup tftp_dfu TFTP transport for Background DFU
+ * @ingroup iot_tftp_dfu
+ * @{
+ * @brief TFTP transport for Background DFU.
+ *
+ */
+
+#ifndef TFTP_DFU_H_
+#define TFTP_DFU_H_
+
+#include <stdint.h>
+#include "iot_defines.h"
+
+/** @brief Initialize DFU client.
+ *
+ * @returns NRF_SUCCESS if DFU procedure started. Otherwise an error code indicating problem.
+ */
+uint32_t tftp_dfu_init(void);
+
+/** @brief Trigger DFU.
+ *
+ * @param[in] p_host_ipv6 IPv6 address of TFTP host.
+ * @param[in] src_port Source UDP port used by TFTP service.
+ * @param[in] dst_port Destination UDP port used by TFTP service.
+ *
+ * @returns NRF_SUCCESS if DFU procedure started. Otherwise an error code indicating problem.
+ */
+uint32_t tftp_dfu_trigger(const ipv6_addr_t * p_host_ipv6, uint16_t src_port, uint16_t dst_port);
+
+/** @brief Handle DFU error.
+ *
+ * This function can be implemented in the application to undertake application-specific action on DFU error.
+ */
+extern void tftp_dfu_handle_error(void);
+
+#endif /* TFTP_DFU_H_ */
+
+/** @} */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/ble_6lowpan/ble_6lowpan.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/ble_6lowpan/ble_6lowpan.c
new file mode 100644
index 0000000..b7bf6fa
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/ble_6lowpan/ble_6lowpan.c
@@ -0,0 +1,1978 @@
+/**
+ * Copyright (c) 2013 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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
+ *
+ * @defgroup ble_sdk_6lowpan 6LoWPAN Adaptation Layer
+ * @{
+ * @ingroup ble_sdk_iot
+ * @brief 6LoWPAN Adaptation Layer
+ *
+ * @details This module enables 6LoWPAN over Bluetooth Low Energy.
+ *
+ */
+
+#include <stdbool.h>
+#include <stdint.h>
+#include <string.h>
+#include "nrf_soc.h"
+#include "nordic_common.h"
+#include "ble_ipsp.h"
+#include "ble_6lowpan.h"
+#include "iot_common.h"
+#include "iot_context_manager.h"
+#include "app_util_platform.h"
+#include "mem_manager.h"
+
+/**
+ * @defgroup ble_sdk_6lowpan Module's Log Macros
+ * @details Macros used for creating module logs which can be useful in understanding handling
+ * of events or actions on API requests. These are intended for debugging purposes and
+ * can be enabled by defining the IOT_BLE_6LOWPAN_CONFIG_LOG_ENABLED.
+ * @note If NRF_LOG_ENABLED is disabled, having IOT_BLE_6LOWPAN_CONFIG_LOG_ENABLED
+ * has no effect.
+ * @{
+ */
+
+#if IOT_BLE_6LOWPAN_CONFIG_LOG_ENABLED
+
+#define NRF_LOG_MODULE_NAME 6lowpan
+
+#define NRF_LOG_LEVEL IOT_BLE_6LOWPAN_CONFIG_LOG_LEVEL
+#define NRF_LOG_INFO_COLOR IOT_BLE_6LOWPAN_CONFIG_INFO_COLOR
+#define NRF_LOG_DEBUG_COLOR IOT_BLE_6LOWPAN_CONFIG_DEBUG_COLOR
+
+#include "nrf_log.h"
+NRF_LOG_MODULE_REGISTER();
+
+#define BLE_6LOWPAN_TRC NRF_LOG_DEBUG /**< Used for getting trace of execution in the module. */
+#define BLE_6LOWPAN_ERR NRF_LOG_ERROR /**< Used for logging errors in the module. */
+#define BLE_6LOWPAN_DUMP NRF_LOG_HEXDUMP_DEBUG /**< Used for dumping octet information to get details of bond information etc. */
+
+#define BLE_6LOWPAN_ENTRY() BLE_6LOWPAN_TRC(">> %s", __func__)
+#define BLE_6LOWPAN_EXIT() BLE_6LOWPAN_TRC("<< %s", __func__)
+
+#else // IOT_BLE_6LOWPAN_CONFIG_LOG_ENABLED
+
+#define BLE_6LOWPAN_TRC(...) /**< Disables traces. */
+#define BLE_6LOWPAN_DUMP(...) /**< Disables dumping of octet streams. */
+#define BLE_6LOWPAN_ERR(...) /**< Disables error logs. */
+
+#define BLE_6LOWPAN_ENTRY(...)
+#define BLE_6LOWPAN_EXIT(...)
+
+#endif // IOT_BLE_6LOWPAN_CONFIG_LOG_ENABLED
+
+
+
+/** @} */
+
+/**
+ * @defgroup ble_6lowpan_mutex_lock_unlock Module's Mutex Lock/Unlock Macros.
+ *
+ * @details Macros used to lock and unlock modules. Currently, SDK does not use mutexes but
+ * framework is provided in case need arises to use an alternative architecture.
+ * @{
+ */
+#define BLE_6LOWPAN_MUTEX_LOCK() SDK_MUTEX_LOCK(m_6lowpan_mutex) /**< Lock module using mutex */
+#define BLE_6LOWPAN_MUTEX_UNLOCK() SDK_MUTEX_UNLOCK(m_6lowpan_mutex) /**< Unlock module using mutex */
+/** @} */
+
+/**
+ * @defgroup api_param_check API Parameters check macros.
+ *
+ * @details Macros that verify parameters passed to the module in the APIs. These macros
+ * could be mapped to nothing in final versions of code to save execution and size.
+ * BLE_6LOWPAN_DISABLE_API_PARAM_CHECK should be set to 0 to enable these checks.
+ *
+ * @{
+ */
+
+#if (BLE_6LOWPAN_DISABLE_API_PARAM_CHECK == 0)
+
+/**@brief Macro to check is module is initialized before requesting one of the module procedures. */
+#define VERIFY_MODULE_IS_INITIALIZED() \
+ if (m_event_handler == NULL) \
+ { \
+ return (SDK_ERR_MODULE_NOT_INITIALIZED | BLE_6LOWPAN_ERR_BASE); \
+ }
+
+/**@brief Verify NULL parameters are not passed to API by application. */
+#define NULL_PARAM_CHECK(PARAM) \
+ if ((PARAM) == NULL) \
+ { \
+ return (NRF_ERROR_NULL | BLE_6LOWPAN_ERR_BASE); \
+ }
+
+/**@brief Check if packet has at least IP Header in it (40 bytes). */
+#define PACKET_LENGTH_CHECK(PARAM) \
+ if ((PARAM) < IPV6_IP_HEADER_SIZE) \
+ { \
+ return (NRF_ERROR_INVALID_PARAM | BLE_6LOWPAN_ERR_BASE); \
+ }
+
+#else // BLE_6LOWPAN_DISABLE_API_PARAM_CHECK
+
+#define VERIFY_MODULE_IS_INITIALIZED()
+#define NULL_PARAM_CHECK(PARAM)
+#define PACKET_LENGTH_CHECK(PARAM)
+
+#endif // BLE_6LOWPAN_DISABLE_API_PARAM_CHECK
+
+/** @} */
+
+/**@brief Maximum different between compressed and uncompressed packet. */
+#define IPHC_MAX_COMPRESSED_DIFF (IPV6_IP_HEADER_SIZE + UDP_HEADER_SIZE - 7)
+
+/**@brief Transmit FIFO mask. */
+#define TX_FIFO_MASK (BLE_6LOWPAN_TX_FIFO_SIZE - 1)
+
+/**@brief Value and position of IPHC dispatch. */
+#define IPHC_START_DISPATCH 0x03
+#define IPHC_START_DISPATCH_POS 5
+
+/**@brief Values and positions of IPHC fields. */
+#define IPHC_TF_MASK 0x18
+#define IPHC_TF_POS 3
+#define IPHC_NH_MASK 0x04
+#define IPHC_NH_POS 2
+#define IPHC_HLIM_MASK 0x03
+#define IPHC_HLIM_POS 0
+#define IPHC_CID_MASK 0x80
+#define IPHC_CID_POS 7
+#define IPHC_SAC_MASK 0x40
+#define IPHC_SAC_POS 6
+#define IPHC_SAM_MASK 0x30
+#define IPHC_SAM_POS 4
+#define IPHC_M_MASK 0x08
+#define IPHC_M_POS 3
+#define IPHC_DAC_MASK 0x04
+#define IPHC_DAC_POS 2
+#define IPHC_DAM_MASK 0x03
+#define IPHC_DAM_POS 0
+
+/**@brief IPHC Traffic Flow compression. */
+#define IPHC_TF_DSCP_MASK 0x3F
+#define IPHC_TF_ECN_MASK 0xC0
+#define IPHC_TF_ECN_POS 6
+
+/**@brief IPHC values of fields. */
+#define IPHC_TF_00 0x00
+#define IPHC_TF_01 0x01
+#define IPHC_TF_10 0x02
+#define IPHC_TF_11 0x03
+#define IPHC_NH_0 0x00
+#define IPHC_NH_1 0x01
+#define IPHC_HLIM_00 0x00
+#define IPHC_HLIM_01 0x01
+#define IPHC_HLIM_10 0x02
+#define IPHC_HLIM_11 0x03
+#define IPHC_CID_0 0x00
+#define IPHC_CID_1 0x01
+#define IPHC_SAC_0 0x00
+#define IPHC_SAC_1 0x01
+#define IPHC_SAM_00 0x00
+#define IPHC_SAM_01 0x01
+#define IPHC_SAM_10 0x02
+#define IPHC_SAM_11 0x03
+#define IPHC_M_0 0x00
+#define IPHC_M_1 0x01
+#define IPHC_DAC_0 0x00
+#define IPHC_DAC_1 0x01
+#define IPHC_DAM_00 0x00
+#define IPHC_DAM_01 0x01
+#define IPHC_DAM_10 0x02
+#define IPHC_DAM_11 0x03
+
+/**@brief IPHC Context Identifier compression. */
+#define IPHC_CID_SOURCE_MASK 0xF0
+#define IPHC_CID_SOURCE_POS 4
+#define IPHC_CID_DESTINATION_MASK 0x0F
+#define IPHC_CID_DESTINATION_POS 0
+
+/**@brief IPHC Next Header Compression dispatches. */
+#define IPHC_NHC_UDP_DISPATCH 0xF0
+#define IPHC_NHC_UDP_MASK 0xF8
+#define IPHC_NHC_EXT_DISPATCH 0xE0
+#define IPHC_NHC_EXT_MASK 0xF0
+
+/**@brief IPHC Next Header Compression UDP fields. */
+#define IPHC_NHC_UDP_CSUM_MASK 0x04
+#define IPHC_NHC_UDP_CSUM_POS 0x02
+#define IPHC_NHC_UDP_PORTS_MASK 0x03
+#define IPHC_NHC_UDP_PORTS_POS 0x00
+#define IPHC_NHC_UDP_PORTS_00 0x00
+#define IPHC_NHC_UDP_PORTS_01 0x01
+#define IPHC_NHC_UDP_PORTS_10 0x02
+#define IPHC_NHC_UDP_PORTS_11 0x03
+
+#define IPHC_NHC_UDP_COMPRESSION_MAX_MASK 0xFFF0
+#define IPHC_NHC_UDP_COMPRESSION_MAX 0xF0B0
+#define IPHC_NHC_UDP_COMPRESSION_MIN_MASK 0xFF00
+#define IPHC_NHC_UDP_COMPRESSION_MIN 0xF000
+
+/**@brief IPHC Next Header Compression Extended Header fields. */
+#define IPHC_NHC_EXT_EID_MASK 0x0E
+#define IPHC_NHC_EXT_EID_POS 0x01
+#define IPHC_NHC_EXT_EID_HOP_BY_HOP 0x00
+#define IPHC_NHC_EXT_EID_ROUTING 0x01
+#define IPHC_NHC_EXT_EID_FRAGMENT 0x02
+#define IPHC_NHC_EXT_EID_DESTINATION 0x03
+#define IPHC_NHC_EXT_EID_MOBILITY 0x04
+#define IPHC_NHC_EXT_EID_IPV6 0x07
+
+/**@brief IPHC default value of IPv6 Header fields. */
+#define IPHC_IPHEADER_VER_TC 0x60
+#define IPHC_IPHEADER_TC_FL 0x00
+#define IPHC_IPHEADER_FL 0x00
+
+/**@brief Check if address can be fully elidable. */
+#define IPV6_ADDRESS_IS_FULLY_ELIDABLE(ll_addr, addr) \
+ (((addr)->u8[8] == (((ll_addr[0]) ^ IPV6_IID_FLIP_VALUE))) && \
+ ((addr)->u8[9] == ll_addr[1]) && \
+ ((addr)->u8[10] == ll_addr[2]) && \
+ ((addr)->u8[11] == ll_addr[3]) && \
+ ((addr)->u8[12] == ll_addr[4]) && \
+ ((addr)->u8[11] == 0xff) && \
+ ((addr)->u8[12] == 0xfe) && \
+ ((addr)->u8[13] == ll_addr[5]) && \
+ ((addr)->u8[14] == ll_addr[6]) && \
+ ((addr)->u8[15] == ll_addr[7]) \
+ )
+
+/**@brief Check if address is 16-bit and can be compressed.
+ * 16-bit COMPRESSABLE format: ::0000:00ff:fe00:XXXX.
+ */
+#define IPV6_ADDRESS_IS_16_BIT_COMPRESSABLE(addr) \
+ (((addr)->u8[8] == 0) && \
+ ((addr)->u8[9] == 0) && \
+ ((addr)->u8[10] == 0) && \
+ ((addr)->u8[11] == 0xff) && \
+ ((addr)->u8[12] == 0xfe) && \
+ ((addr)->u8[13] == 0) \
+ )
+
+/**@brief Check if address is 48-bit multi-cast and can be compressed.
+ * 48-bit COMPRESSABLE format: FFXX::00XX:XXXX:XXXX.
+ */
+#define IPV6_ADDRESS_IS_48_BIT_MCAST_COMPRESSABLE(addr) \
+ (((addr)->u16[1] == 0) && \
+ ((addr)->u16[2] == 0) && \
+ ((addr)->u16[3] == 0) && \
+ ((addr)->u16[4] == 0) && \
+ ((addr)->u8[10] == 0) \
+ )
+
+/**@brief Check if address is 32-bit multi-cast and can be compressed.
+ * 32-bit COMPRESSABLE format: FFXX::00XX:XXXX.
+ */
+#define IPV6_ADDRESS_IS_32_BIT_MCAST_COMPRESSABLE(addr) \
+ (((addr)->u16[1] == 0) && \
+ ((addr)->u32[1] == 0) && \
+ ((addr)->u32[2] == 0) && \
+ ((addr)->u8[12] == 0) \
+ )
+
+/**@brief Check if address is 8-bit multi-cast and can be compressed.
+ * 8-bit COMPRESSABLE format: FF02::XX.
+ */
+#define IPV6_ADDRESS_IS_8_BIT_MCAST_COMPRESSABLE(addr) \
+ (((addr)->u8[1] == 2) && \
+ ((addr)->u16[1] == 0) && \
+ ((addr)->u32[1] == 0) && \
+ ((addr)->u32[2] == 0) && \
+ ((addr)->u16[6] == 0) && \
+ ((addr)->u8[14] == 0) \
+ )
+
+/******************************************************************************
+ * 6LoWPAN Core and Transport structures.
+ ******************************************************************************/
+
+/**@brief Element of TX Queue. */
+typedef struct
+{
+ uint8_t * p_mem_block; /**< Base address of memory block, using for release the buffer. */
+ uint8_t * p_data; /**< Pointer to TX Data. */
+ uint16_t data_len; /**< Size of TX data. */
+} tx_packet_t;
+
+/**@brief A TX Queue (FIFO) structure. */
+typedef struct
+{
+ tx_packet_t packets[BLE_6LOWPAN_TX_FIFO_SIZE]; /**< Array of TX packet in FIFO. */
+ volatile uint32_t read_pos; /**< Next read position in the FIFO buffer. */
+ volatile uint32_t write_pos; /**< Next write position in the FIFO buffer. */
+} tx_fifo_t;
+
+/**@brief Transport instance structure. */
+typedef struct
+{
+ iot_interface_t interface;
+ ble_ipsp_handle_t handle;
+ tx_fifo_t tx_fifo;
+ tx_packet_t * p_tx_cur_packet;
+} transport_instance_t;
+
+/******************************************************************************
+ * @name Global variables
+ *****************************************************************************/
+
+/**@brief Application Event Handler. */
+static ble_6lowpan_evt_handler_t m_event_handler = NULL;
+
+/**@brief Hop Limit options. */
+static const uint8_t m_hop_limit[] = {0, 1, 64, 255};
+
+/**@brief Link-local prefix. */
+static const uint8_t m_link_local_prefix[] = {0xFE, 0x80};
+
+/**@brief Additional extenders for EUI-48. */
+static const uint8_t m_link_local_16_middle[] = {0xFF, 0xFE};
+
+/**@brief nRF EUI-64 link-layer address */
+static eui64_t m_ll_addr = {{0, 0, 0, 0, 0, 0, 0, 0}};
+
+/**@brief Transport interfaces table. */
+static transport_instance_t m_instances[BLE_6LOWPAN_MAX_INTERFACE];
+
+/**@brief Mutex variable. Currently unused, this declaration does not occupy any space in RAM. */
+SDK_MUTEX_DEFINE(m_6lowpan_mutex)
+
+/******************************************************************************
+ * @name 6LoWPAN core functions
+ *****************************************************************************/
+
+/**@brief Function for checking if IID can be completely elided. This situation
+ * may happen when receiver can still reconstruct IPv6 address by using context
+ * prefix and Link Layer address.
+ *
+ * @param[in] p_addr Pointer to IPv6 address.
+ * @param[in] p_context Pointer to context entry that is compressed with.
+ * @param[in] p_ll_addr Pointer to link layer address of BT-LE device.
+ *
+ * @return True if IID can be elided, False otherwise.
+ */
+static bool is_context_cover_iid(const ipv6_addr_t * p_addr,
+ const iot_context_t * p_context,
+ const eui64_t * p_ll_addr)
+{
+ uint32_t start_byte, offset;
+
+ // Context covers IPv6 address by its size.
+ if (p_context->prefix_len == 128)
+ {
+ return true;
+ }
+
+ // Check if IID can be retrieved in case of longer prefix than 64 bits.
+ if (p_context->prefix_len > 64)
+ {
+ // Check only IID fields that are not covered by context prefix.
+ start_byte = p_context->prefix_len >> 3;
+ offset = p_context->prefix_len % 8;
+
+ // Check all bytes from the second one.
+ if (start_byte == 15 ||
+ 0 == memcmp(&p_addr->u8[start_byte+1], &p_ll_addr->identifier[start_byte-7], 15-start_byte))
+ {
+ // Then check first byte.
+ return (p_addr->u8[start_byte] << offset) == (p_ll_addr->identifier[start_byte-8] << offset);
+ }
+ }
+
+ return false;
+}
+
+/**@brief Function for decoding Next Header Compression.
+ * It supports UDP header decompression.
+ *
+ * @param[in] p_iphc Pointer to currently process IPHC field.
+ * @param[in] p_data Pointer to constructing uncompressed IP packet.
+ * @param[in] p_length Place of UDP header in case of Extension Header.
+ * @param[out] p_length Length of the constructed uncompressed header.
+ *
+ * @return Number of processed IPHC field.
+ */
+static uint32_t iphc_nhc_decode(uint8_t * p_iphc, uint8_t * p_data, uint16_t * p_length)
+{
+ uint8_t nhc_dispatch = *p_iphc;
+ uint8_t * p_nhc = p_iphc;
+
+ ipv6_header_t * iphdr = (ipv6_header_t *)&p_data[0];
+
+ // UDP Next Header Compression.
+ if ((nhc_dispatch & IPHC_NHC_UDP_MASK) == IPHC_NHC_UDP_DISPATCH)
+ {
+ udp6_header_t * udphdr = (udp6_header_t * )&p_data[IPV6_IP_HEADER_SIZE + *p_length];
+
+ iphdr->next_header = IPV6_NEXT_HEADER_UDP;
+
+ // Start length from UDP Header Size.
+ *p_length += UDP_HEADER_SIZE;
+ p_nhc += 1;
+
+ switch ((nhc_dispatch & IPHC_NHC_UDP_PORTS_MASK) >> IPHC_NHC_UDP_PORTS_POS)
+ {
+ case IPHC_NHC_UDP_PORTS_00:
+ memcpy(&udphdr->srcport, p_nhc, 2);
+ memcpy(&udphdr->destport, p_nhc + 2, 2);
+ p_nhc += 4;
+ break;
+
+ case IPHC_NHC_UDP_PORTS_01:
+ memcpy(&udphdr->srcport, p_nhc, 2);
+ udphdr->destport = HTONS(IPHC_NHC_UDP_COMPRESSION_MIN | *(p_nhc + 2));
+ p_nhc += 3;
+ break;
+
+ case IPHC_NHC_UDP_PORTS_10:
+ udphdr->srcport = HTONS(IPHC_NHC_UDP_COMPRESSION_MIN | *p_nhc);
+ memcpy(&udphdr->destport, p_nhc + 1, 2);
+ p_nhc += 3;
+ break;
+
+ case IPHC_NHC_UDP_PORTS_11:
+ udphdr->srcport = HTONS((IPHC_NHC_UDP_COMPRESSION_MAX | ((*p_nhc & 0xf0) >> 4)));
+ udphdr->destport = HTONS((IPHC_NHC_UDP_COMPRESSION_MAX | ((*p_nhc & 0x0f))));
+ p_nhc += 1;
+ break;
+ }
+
+ if ((nhc_dispatch & IPHC_NHC_UDP_CSUM_MASK) >> IPHC_NHC_UDP_CSUM_POS)
+ {
+ udphdr->checksum = 0;
+ }
+ else
+ {
+ memcpy(&udphdr->checksum, p_nhc, 2);
+ p_nhc += 2;
+ }
+ }
+
+ return (p_nhc - p_iphc);
+}
+
+/**@brief Function for encoding Next Header Compression.
+ * It supports UDP header compression.
+ *
+ * @param[in] p_iphc Pointer to currently process IPHC field.
+ * @param[in] p_data Pointer to constructing uncompressed IP packet.
+ * @param[in] p_length Place of UDP header in case of Extension Header.
+ * @param[out] p_length Length of the constructed uncompressed header.
+ *
+ * @return Number of processed IPHC field.
+ */
+static uint32_t iphc_nhc_encode(uint8_t * p_iphc, const uint8_t * p_data, uint16_t * p_length)
+{
+ uint8_t * p_nhc = p_iphc;
+ ipv6_header_t * iphdr = (ipv6_header_t *)p_data;
+
+ switch (iphdr->next_header)
+ {
+ case IPV6_NEXT_HEADER_UDP:
+ {
+ udp6_header_t * udphdr = (udp6_header_t * )&p_data[IPV6_IP_HEADER_SIZE + *p_length];
+ *p_iphc = IPHC_NHC_UDP_DISPATCH;
+ p_nhc += 1;
+
+ // Full 4-bit compression for source and destination ports.
+ if ( ((HTONS(udphdr->srcport) & IPHC_NHC_UDP_COMPRESSION_MAX_MASK) ==
+ IPHC_NHC_UDP_COMPRESSION_MAX) &&
+ ((HTONS(udphdr->destport) & IPHC_NHC_UDP_COMPRESSION_MAX_MASK) ==
+ IPHC_NHC_UDP_COMPRESSION_MAX))
+ {
+ *p_iphc |= (IPHC_NHC_UDP_PORTS_11 >> IPHC_NHC_UDP_PORTS_POS);
+
+ *p_nhc =
+ (((HTONS(udphdr->srcport) & 0x0f) << 4) | (HTONS(udphdr->destport) & 0x0f));
+ p_nhc += 1;
+ }
+ // Source port compressed, destination in-line.
+ else if ((HTONS(udphdr->srcport) & IPHC_NHC_UDP_COMPRESSION_MIN_MASK) ==
+ IPHC_NHC_UDP_COMPRESSION_MIN)
+ {
+ *p_iphc |= (IPHC_NHC_UDP_PORTS_10 >> IPHC_NHC_UDP_PORTS_POS);
+
+ *p_nhc = (HTONS(udphdr->srcport) & 0xff);
+ p_nhc += 1;
+
+ memcpy(p_nhc, &udphdr->destport, 2);
+ p_nhc += 2;
+ }
+ // Source port in-line, destination compressed.
+ else if ((HTONS(udphdr->destport) & IPHC_NHC_UDP_COMPRESSION_MIN_MASK) ==
+ IPHC_NHC_UDP_COMPRESSION_MIN)
+ {
+ *p_iphc |= (IPHC_NHC_UDP_PORTS_01 >> IPHC_NHC_UDP_PORTS_POS);
+
+ memcpy(p_nhc, &udphdr->srcport, 2);
+ p_nhc += 2;
+
+ *p_nhc = (HTONS(udphdr->destport) & 0xff);
+ p_nhc += 1;
+ }
+ // Source and destination port in-line.
+ else
+ {
+ *p_iphc |= (IPHC_NHC_UDP_PORTS_00 >> IPHC_NHC_UDP_PORTS_POS);
+
+ memcpy(p_nhc, &udphdr->srcport, 2);
+ memcpy(p_nhc + 2, &udphdr->destport, 2);
+ p_nhc += 4;
+ }
+
+ // Checksum always in-line, [RFC4944] disallows the compression of the
+ // UDP checksum. The compressor MUST NOT set the C bit unless it has received
+ // authorization.
+ memcpy(p_nhc, &udphdr->checksum, 2);
+ p_nhc += 2;
+
+ // Set UDP ext header size.
+ *p_length = UDP_HEADER_SIZE;
+
+ break;
+ }
+ }
+
+ return (p_nhc - p_iphc);
+}
+
+
+ /**@brief Function for checking if it's possible to use NHC.
+ *
+ * @param[in] next_header Value of Next Header field in IPv6 packet.
+ *
+ * @return Returns 1 if header can be compressed, otherwise 0.
+ */
+static uint32_t iphc_nhc_compressable(uint8_t next_header)
+{
+ switch (next_header)
+ {
+ case IPV6_NEXT_HEADER_UDP:
+ return 1;
+ }
+
+ return 0;
+}
+
+
+/**@brief Function for decoding IPHC (IP Header Compression) defined in
+ * IETF RFC 6282.
+ *
+ * @param[in] p_instance Transport instance from where packet came.
+ * @param[in] p_input Pointer to received packet from IPSP module.
+ * @param[in] input_len Length of received packet.
+ * @param[in] p_output Pointer to allocated buffer for decompressed packet.
+ * @param[out] p_output Pointer to decompressed IPv6 packet.
+ * @param[out] p_output_len Length of decompressed IPv6 packet.
+ *
+ * @return NRF_SUCCESS on success, otherwise an error code.
+ */
+static uint32_t iphc_decode(iot_interface_t * p_interface,
+ uint8_t * p_output,
+ uint16_t * p_output_len,
+ uint8_t * p_input,
+ uint16_t input_len,
+ iot_context_id_t * p_rx_contexts)
+{
+ uint32_t retval = NRF_SUCCESS;
+ uint32_t err_code = NRF_SUCCESS;
+ uint8_t * p_iphc = p_input;
+ uint8_t sci = IPV6_CONTEXT_IDENTIFIER_NONE;
+ uint8_t dci = IPV6_CONTEXT_IDENTIFIER_NONE;
+ uint16_t nhc_length = 0;
+ iot_context_t * p_ctx = NULL;
+
+ // IPv6 headers used in decompression.
+ ipv6_header_t * p_iphdr = (ipv6_header_t *)p_output;
+ udp6_header_t * p_udphdr = (udp6_header_t *)&p_output[IPV6_IP_HEADER_SIZE];
+
+ // Check if format of packet is correct.
+ if ((p_input[0] >> IPHC_START_DISPATCH_POS) != IPHC_START_DISPATCH)
+ {
+ BLE_6LOWPAN_ERR("[6LoWPAN] Packet has incorrect IPHC structure!");
+
+ return NRF_ERROR_INVALID_DATA;
+ }
+
+ // IPHC basic form has 2 bytes.
+ p_iphc += 2;
+
+ // RFC6282: An additional 8-bit Context Identifier Extension field
+ // immediately follows the Destination Address Mode (DAM) field.
+ if ((p_input[1] & IPHC_CID_MASK))
+ {
+ sci = ((*p_iphc & IPHC_CID_SOURCE_MASK) >> IPHC_CID_SOURCE_POS);
+ dci = ((*p_iphc & IPHC_CID_DESTINATION_MASK) >> IPHC_CID_DESTINATION_POS);
+ p_iphc += 1;
+ }
+
+ // Set proper context identifiers.
+ p_rx_contexts->src_cntxt_id = sci;
+ p_rx_contexts->dest_cntxt_id = dci;
+
+ switch ((p_input[0] & IPHC_TF_MASK) >> IPHC_TF_POS)
+ {
+ case IPHC_TF_11:
+ // Elide Traffic Class and Flow Label.
+ p_iphdr->version_traffic_class = IPHC_IPHEADER_VER_TC;
+ p_iphdr->traffic_class_flowlabel = IPHC_IPHEADER_TC_FL;
+ p_iphdr->flowlabel = IPHC_IPHEADER_FL;
+ break;
+
+ case IPHC_TF_10:
+ // Elide Flow Label.
+ p_iphdr->version_traffic_class = IPHC_IPHEADER_VER_TC | ((*p_iphc & IPHC_TF_DSCP_MASK) >> 2);
+ p_iphdr->traffic_class_flowlabel = ((*p_iphc & 0x03) << 6) |
+ ((*p_iphc & IPHC_TF_ECN_MASK) >> 2);
+ p_iphdr->flowlabel = IPHC_IPHEADER_FL;
+ p_iphc += 1;
+ break;
+
+ case IPHC_TF_01:
+ // Elide DSCP, carry ECN and Flow Label.
+ p_iphdr->version_traffic_class = IPHC_IPHEADER_VER_TC;
+ p_iphdr->traffic_class_flowlabel = ((*p_iphc & IPHC_TF_ECN_MASK) >> 2) |
+ ((*p_iphc & 0x0f));
+ memcpy(&p_iphdr->flowlabel, p_iphc + 1, 2);
+ p_iphc += 3;
+ break;
+
+ case IPHC_TF_00:
+ // Flow Label and Traffic Class in-line.
+ p_iphdr->version_traffic_class = IPHC_IPHEADER_VER_TC | ((*p_iphc & IPHC_TF_DSCP_MASK) >> 2);
+ p_iphdr->traffic_class_flowlabel = ((*p_iphc & 0x03) << 6) |
+ ((*p_iphc & IPHC_TF_ECN_MASK) >> 2) |
+ ((*(p_iphc + 1) & 0x0f));
+ memcpy(&p_iphdr->flowlabel, p_iphc + 2, 2);
+ p_iphc += 4;
+ break;
+ }
+
+ if (!((p_input[0] & IPHC_NH_MASK)))
+ {
+ // Set next header.
+ p_iphdr->next_header = *p_iphc++;
+ }
+
+ if ((p_input[0] & IPHC_HLIM_MASK))
+ {
+ p_iphdr->hoplimit = m_hop_limit[((p_input[0] & IPHC_HLIM_MASK) >> IPHC_HLIM_POS)];
+ }
+ else
+ {
+ p_iphdr->hoplimit = *p_iphc++;
+ }
+
+ // Clear IPv6 addresses.
+ memset(p_iphdr->srcaddr.u8, 0, IPV6_ADDR_SIZE);
+ memset(p_iphdr->destaddr.u8, 0, IPV6_ADDR_SIZE);
+
+ // Source address decompression.
+ if ((p_input[1] & IPHC_SAC_MASK) >> IPHC_SAC_POS)
+ {
+ if ( ((p_input[1] & IPHC_SAM_MASK) >> IPHC_SAM_POS) == IPHC_SAM_00 )
+ {
+ // Unspecified address.
+ memset(p_iphdr->srcaddr.u8, 0, IPV6_ADDR_SIZE);
+ }
+ else
+ {
+ switch ((p_input[1] & IPHC_SAM_MASK) >> IPHC_SAM_POS)
+ {
+ case IPHC_SAM_01:
+ // 64 bits in-line, first IID then prefix in case prefix > 64.
+ memcpy(p_iphdr->srcaddr.u8 + 8, p_iphc, 8);
+ p_iphc += 8;
+ break;
+
+ case IPHC_SAM_10:
+ // 16 bits in-line.
+ memcpy(p_iphdr->srcaddr.u8 + 14, p_iphc, 2);
+ memcpy(p_iphdr->srcaddr.u8 + 11, m_link_local_16_middle, 2);
+ p_iphc += 2;
+ break;
+
+ case IPHC_SAM_11:
+ // Take the address from lower layer.
+ memcpy(p_iphdr->srcaddr.u8 + 8, p_interface->peer_addr.identifier, 8);
+ p_iphdr->srcaddr.u8[8] ^= IPV6_IID_FLIP_VALUE;
+ break;
+ }
+
+ /* Look up for context */
+ BLE_6LOWPAN_MUTEX_UNLOCK();
+ err_code = iot_context_manager_get_by_cid(p_interface, sci, &p_ctx);
+ BLE_6LOWPAN_MUTEX_LOCK();
+
+ if (err_code == NRF_SUCCESS)
+ {
+ /* Add prefix */
+ IPV6_ADDRESS_PREFIX_SET(p_iphdr->srcaddr.u8, p_ctx->prefix.u8, p_ctx->prefix_len);
+ }
+ else
+ {
+ /* Set error and continue decompression. */
+ retval = BLE_6LOWPAN_CID_NOT_FOUND;
+
+ BLE_6LOWPAN_ERR("Cannot find context identifier in the context table.");
+ }
+ }
+ }
+ else
+ {
+ switch ((p_input[1] & IPHC_SAM_MASK) >> IPHC_SAM_POS)
+ {
+ case IPHC_SAM_00:
+ // Full 128-bits in-line.
+ memcpy(p_iphdr->srcaddr.u8, p_iphc, IPV6_ADDR_SIZE);
+ p_iphc += IPV6_ADDR_SIZE;
+ break;
+
+ case IPHC_SAM_01:
+ // 64 bits in-line, first IID then prefix in case prefix > 64.
+ memcpy(p_iphdr->srcaddr.u8, m_link_local_prefix, 2);
+ memcpy(p_iphdr->srcaddr.u8 + 8, p_iphc, 8);
+ p_iphc += 8;
+ break;
+
+ case IPHC_SAM_10:
+ // 16 bits in-line.
+ memcpy(p_iphdr->srcaddr.u8, m_link_local_prefix, 2);
+ memcpy(p_iphdr->srcaddr.u8 + 11, m_link_local_16_middle, 2);
+ memcpy(p_iphdr->srcaddr.u8 + 14, p_iphc, 2);
+ p_iphc += 2;
+ break;
+
+ case IPHC_SAM_11:
+ memcpy(p_iphdr->srcaddr.u8, m_link_local_prefix, 2);
+ memcpy(p_iphdr->srcaddr.u8 + 8, p_interface->peer_addr.identifier, 8);
+ p_iphdr->srcaddr.u8[8] ^= IPV6_IID_FLIP_VALUE;
+ break;
+ }
+ }
+
+ // Destination address decompression.
+ if ((p_input[1] & IPHC_DAC_MASK) >> IPHC_DAC_POS)
+ {
+ if ((p_input[1] & IPHC_M_MASK) >> IPHC_M_POS)
+ {
+ switch ((p_input[1] & IPHC_DAM_MASK) >> IPHC_DAM_POS)
+ {
+ case IPHC_DAM_00:
+ // 48-bits in-line.
+ p_iphdr->destaddr.u8[0] = 0xff;
+ memcpy(p_iphdr->destaddr.u8 + 1, p_iphc, 2);
+ memcpy(p_iphdr->destaddr.u8 + 12, p_iphc + 2, 4);
+ p_iphc += 6;
+ break;
+
+ default:
+ BLE_6LOWPAN_ERR("Reserved value in IPHC header!");
+ return NRF_ERROR_INVALID_DATA;
+ }
+ }
+ else
+ {
+ switch ((p_input[1] & IPHC_DAM_MASK) >> IPHC_DAM_POS)
+ {
+ case IPHC_DAM_01:
+ // 64 bits in-line.
+ memcpy(p_iphdr->destaddr.u8 + 8, p_iphc, 8);
+ p_iphc += 8;
+ break;
+
+ case IPHC_DAM_10:
+ // 16 bits in-line.
+ memcpy(p_iphdr->destaddr.u8 + 11, m_link_local_16_middle, 2);
+ memcpy(p_iphdr->destaddr.u8 + 14, p_iphc, 2);
+ p_iphc += 2;
+ break;
+
+ case IPHC_DAM_11:
+ // Take the address from lower layer.
+ memcpy(p_iphdr->destaddr.u8 + 8, p_interface->local_addr.identifier, 8);
+ p_iphdr->destaddr.u8[8] ^= IPV6_IID_FLIP_VALUE;
+ break;
+
+ default:
+ BLE_6LOWPAN_ERR("Reserved value in IPHC header!");
+ return NRF_ERROR_INVALID_DATA;
+ }
+
+ /* Look up for context */
+ BLE_6LOWPAN_MUTEX_UNLOCK();
+ err_code = iot_context_manager_get_by_cid(p_interface, dci, &p_ctx);
+ BLE_6LOWPAN_MUTEX_LOCK();
+
+ if (err_code == NRF_SUCCESS)
+ {
+ /* Add prefix */
+ IPV6_ADDRESS_PREFIX_SET(p_iphdr->destaddr.u8, p_ctx->prefix.u8, p_ctx->prefix_len);
+ }
+ else
+ {
+ /* Set error and continue decompression. */
+ retval = BLE_6LOWPAN_CID_NOT_FOUND;
+
+ BLE_6LOWPAN_ERR("Cannot find context identifier in the context table.");
+ }
+ }
+ }
+ else
+ {
+ if ((p_input[1] & IPHC_M_MASK) >> IPHC_M_POS)
+ {
+ switch ((p_input[1] & IPHC_DAM_MASK) >> IPHC_DAM_POS)
+ {
+ case IPHC_DAM_00:
+ // 128 bits in-line.
+ memcpy(p_iphdr->destaddr.u8, p_iphc, IPV6_ADDR_SIZE);
+ p_iphc += IPV6_ADDR_SIZE;
+ break;
+
+ case IPHC_DAM_01:
+ // 48 bits in-line.
+ p_iphdr->destaddr.u8[0] = 0xFF;
+ p_iphdr->destaddr.u8[1] = *p_iphc;
+ memcpy(p_iphdr->destaddr.u8 + 11, p_iphc + 1, 5);
+ p_iphc += 6;
+ break;
+
+ case IPHC_DAM_10:
+ // 32 bits in-line.
+ p_iphdr->destaddr.u8[0] = 0xFF;
+ p_iphdr->destaddr.u8[1] = *p_iphc;
+ memcpy(p_iphdr->destaddr.u8 + 13, p_iphc + 1, 3);
+ p_iphc += 4;
+ break;
+
+ case IPHC_DAM_11:
+ // 8 bits in-line.
+ p_iphdr->destaddr.u8[0] = 0xFF;
+ p_iphdr->destaddr.u8[1] = 0x02;
+ p_iphdr->destaddr.u8[15] = *p_iphc;
+ p_iphc += 1;
+ break;
+ }
+ }
+ else
+ {
+ switch ((p_input[1] & IPHC_DAM_MASK) >> IPHC_DAM_POS)
+ {
+ case IPHC_DAM_00:
+ // 128 bits in-line.
+ memcpy(p_iphdr->destaddr.u8, p_iphc, IPV6_ADDR_SIZE);
+ p_iphc += IPV6_ADDR_SIZE;
+ break;
+
+ case IPHC_DAM_01:
+ // 64 bits in-line, first IID then prefix in case prefix > 64.
+ memcpy(p_iphdr->destaddr.u8, m_link_local_prefix, 2);
+ memcpy(p_iphdr->destaddr.u8 + 8, p_iphc, 8);
+ p_iphc += 8;
+ break;
+
+ case IPHC_DAM_10:
+ // 16 bits in-line.
+ memcpy(p_iphdr->destaddr.u8, m_link_local_prefix, 2);
+ memcpy(p_iphdr->destaddr.u8 + 11, m_link_local_16_middle, 2);
+ memcpy(p_iphdr->destaddr.u8 + 14, p_iphc, 2);
+ p_iphc += 2;
+ break;
+
+ case IPHC_DAM_11:
+ // Take the address from lower layer.
+ memcpy(p_iphdr->destaddr.u8, m_link_local_prefix, 2);
+ memcpy(p_iphdr->destaddr.u8 + 8, p_interface->local_addr.identifier, 8);
+ p_iphdr->destaddr.u8[8] ^= IPV6_IID_FLIP_VALUE;
+ break;
+ }
+ }
+ }
+
+ // Perform next header compression.
+ if (((p_input[0] & IPHC_NH_MASK) >> IPHC_NH_POS))
+ {
+ p_iphc += iphc_nhc_decode(p_iphc, p_output, &nhc_length);
+
+ if (nhc_length == 0)
+ {
+ // Unknown NHC field.
+ BLE_6LOWPAN_ERR("IPHC contains unsupported NHC header!");
+
+ return NRF_ERROR_INVALID_DATA;
+ }
+ }
+
+ // Calculate IPv6 Header Length.
+ p_iphdr->length = input_len - (p_iphc - p_input);
+
+ // Check if IPHC contains more bytes than whole packet.
+ if (p_iphdr->length > input_len)
+ {
+ // We cannot decompress it.
+ BLE_6LOWPAN_ERR("IPHC contains more bytes than expected!");
+
+ return NRF_ERROR_INVALID_DATA;
+ }
+
+ // Copy the data.
+ memcpy(p_output + IPV6_IP_HEADER_SIZE + nhc_length, p_iphc, p_iphdr->length);
+
+ // Add uncompressed headers length if any.
+ p_iphdr->length += nhc_length;
+
+ // Return length of whole IPv6 packet.
+ *p_output_len = p_iphdr->length + IPV6_IP_HEADER_SIZE;
+
+ // Keep proper endianness.
+ p_iphdr->length = HTONS(p_iphdr->length);
+
+ // Restore UDP length if compression was used.
+ if ( p_iphdr->next_header == IPV6_NEXT_HEADER_UDP )
+ {
+ memcpy(&p_udphdr->length, &p_iphdr->length, 2);
+ }
+
+ return retval;
+}
+
+
+/**@brief Function for encoding IPHC (IP Header Compression) defined in
+ * IETF RFC 6282. Instead of having separate buffer for compression,
+ * needed compression is performed on the IPv6 packet and buffer holding
+ * the packet is reused to overwrite the headers compressed.
+ *
+ * @param[in] p_interface IoT interface where packet must be sent.
+ * @param[in] p_input Pointer to full IPv6 packet.
+ * @param[in] input_len Length of IPv6 packet.
+ * @param[out] p_output Pointer to place of start IPHC packet.
+ * @param[out] p_output_len Length of compressed packet.
+ *
+ * @return NRF_SUCCESS on success, otherwise an error code.
+ */
+static uint32_t iphc_encode(const iot_interface_t * p_interface,
+ uint8_t ** p_output,
+ uint16_t * p_output_len,
+ const uint8_t * p_input,
+ uint16_t input_len)
+{
+ // Create a buffer with maximum of IPHC value.
+ uint32_t err_code;
+ uint8_t iphc_buff[IPV6_IP_HEADER_SIZE + UDP_HEADER_SIZE];
+ uint8_t traffic_class;
+ uint8_t * p_iphc = &iphc_buff[2];
+ uint16_t iphc_len = 0;
+ uint16_t nhc_length = 0;
+ iot_context_t * p_ctx = NULL;
+ uint8_t sci = p_interface->tx_contexts.src_cntxt_id;
+ uint8_t dci = p_interface->tx_contexts.dest_cntxt_id;
+ bool sci_cover = false;
+ bool dci_cover = false;
+
+ // IPv6 header.
+ ipv6_header_t * p_iphdr = (ipv6_header_t *)p_input;
+
+ *p_iphc = 0;
+
+ // Set IPHC dispatch.
+ iphc_buff[0] = IPHC_START_DISPATCH << IPHC_START_DISPATCH_POS;
+
+ // Check if address can be compressed using context identifier.
+ if (sci == IPV6_CONTEXT_IDENTIFIER_NONE)
+ {
+ BLE_6LOWPAN_MUTEX_UNLOCK();
+ err_code = iot_context_manager_get_by_addr(p_interface, &p_iphdr->srcaddr, &p_ctx);
+ BLE_6LOWPAN_MUTEX_LOCK();
+
+ if (err_code == NRF_SUCCESS)
+ {
+ sci_cover = is_context_cover_iid(&p_iphdr->srcaddr, p_ctx, &p_interface->local_addr);
+ sci = p_ctx->context_id;
+ }
+ }
+
+ if (dci == IPV6_CONTEXT_IDENTIFIER_NONE)
+ {
+ BLE_6LOWPAN_MUTEX_UNLOCK();
+ err_code = iot_context_manager_get_by_addr(p_interface, &p_iphdr->destaddr, &p_ctx);
+ BLE_6LOWPAN_MUTEX_LOCK();
+
+ if (err_code == NRF_SUCCESS)
+ {
+ dci_cover = is_context_cover_iid(&p_iphdr->destaddr, p_ctx, &p_interface->peer_addr);
+ dci = p_ctx->context_id;
+ }
+ }
+
+ if (((sci != IPV6_CONTEXT_IDENTIFIER_NONE) || dci != IPV6_CONTEXT_IDENTIFIER_NONE))
+ {
+ iphc_buff[1] = (IPHC_CID_1 << IPHC_CID_POS);
+
+ // Add Source Context if exists.
+ if (sci != IPV6_CONTEXT_IDENTIFIER_NONE)
+ {
+ *p_iphc |= (sci << 4);
+ }
+
+ // Add Destination Context if exists.
+ if (dci != IPV6_CONTEXT_IDENTIFIER_NONE)
+ {
+ *p_iphc |= dci;
+ }
+
+ p_iphc += 1;
+ }
+ else
+ {
+ // Unset Context Identifier bit.
+ iphc_buff[1] = (IPHC_CID_0 << IPHC_CID_POS);
+ }
+
+ // Change ECN with DSCP in Traffic Class.
+ traffic_class = (p_iphdr->version_traffic_class & 0x0f) << 4;
+ traffic_class |= ((p_iphdr->traffic_class_flowlabel & 0xf0) >> 4);
+ traffic_class = (((traffic_class & 0x03) << 6) | (traffic_class >> 2));
+
+ if ((p_iphdr->flowlabel == 0) && ((p_iphdr->traffic_class_flowlabel & 0x0f) == 0))
+ {
+ if (traffic_class == 0)
+ {
+ // Elide Flow Label and Traffic Class.
+ iphc_buff[0] |= (IPHC_TF_11 << IPHC_TF_POS);
+ }
+ else
+ {
+ // Elide Flow Label and carry Traffic Class in-line.
+ iphc_buff[0] |= (IPHC_TF_10 << IPHC_TF_POS);
+
+ *p_iphc++ = traffic_class;
+ }
+ }
+ else
+ {
+ if (traffic_class & IPHC_TF_DSCP_MASK)
+ {
+ // Carry Flow Label and Traffic Class in-line.
+ iphc_buff[0] |= (IPHC_TF_00 << IPHC_TF_POS);
+
+ *p_iphc++ = traffic_class;
+ *p_iphc++ = (p_iphdr->traffic_class_flowlabel & 0x0f);
+ memcpy(p_iphc, &p_iphdr->flowlabel, 2);
+ p_iphc += 2;
+ }
+ else
+ {
+ // Carry Flow Label and ECN only with 2-bit padding.
+ iphc_buff[0] |= (IPHC_TF_01 << IPHC_TF_POS);
+
+ *p_iphc++ =
+ ((traffic_class & IPHC_TF_ECN_MASK) | (p_iphdr->traffic_class_flowlabel & 0x0f));
+ memcpy(p_iphc, &p_iphdr->flowlabel, 2);
+ p_iphc += 2;
+ }
+ }
+
+ // Checks if next header is compressed.
+ if (iphc_nhc_compressable(p_iphdr->next_header))
+ {
+ iphc_buff[0] |= (IPHC_NH_1 << IPHC_NH_POS);
+ }
+ else
+ {
+ iphc_buff[0] |= (IPHC_NH_0 << IPHC_NH_POS);
+ *p_iphc++ = p_iphdr->next_header;
+ }
+
+ // Hop limit compression.
+ switch (p_iphdr->hoplimit)
+ {
+ case 1:
+ iphc_buff[0] |= (IPHC_HLIM_01 << IPHC_HLIM_POS);
+ break;
+
+ case 64:
+ iphc_buff[0] |= (IPHC_HLIM_10 << IPHC_HLIM_POS);
+ break;
+
+ case 255:
+ iphc_buff[0] |= (IPHC_HLIM_11 << IPHC_HLIM_POS);
+ break;
+
+ default:
+ // Carry Hop Limit in-line.
+ iphc_buff[0] |= (IPHC_HLIM_00 << IPHC_HLIM_POS);
+ *p_iphc++ = p_iphdr->hoplimit;
+ break;
+ }
+
+ // Source address compression.
+ if (IPV6_ADDRESS_IS_UNSPECIFIED(&p_iphdr->srcaddr))
+ {
+ iphc_buff[1] |= (IPHC_SAC_1 << IPHC_SAC_POS);
+ iphc_buff[1] |= (IPHC_SAM_00 << IPHC_SAM_POS);
+ }
+ else if (sci != IPV6_CONTEXT_IDENTIFIER_NONE || IPV6_ADDRESS_IS_LINK_LOCAL(&p_iphdr->srcaddr))
+ {
+ if (sci != IPV6_CONTEXT_IDENTIFIER_NONE)
+ {
+ // Set stateful source address compression.
+ iphc_buff[1] |= (IPHC_SAC_1 << IPHC_SAC_POS);
+ }
+
+ if (IPV6_ADDRESS_IS_FULLY_ELIDABLE(p_interface->local_addr.identifier,
+ &p_iphdr->srcaddr)
+ ||
+ sci_cover == true)
+ {
+ iphc_buff[1] |= (IPHC_SAM_11 << IPHC_SAM_POS);
+ }
+ else if (IPV6_ADDRESS_IS_16_BIT_COMPRESSABLE(&p_iphdr->srcaddr))
+ {
+ iphc_buff[1] |= (IPHC_SAM_10 << IPHC_SAM_POS);
+ memcpy(p_iphc, &p_iphdr->srcaddr.u8[14], 2);
+ p_iphc += 2;
+ }
+ else
+ {
+ iphc_buff[1] |= (IPHC_SAM_01 << IPHC_SAM_POS);
+ memcpy(p_iphc, &p_iphdr->srcaddr.u8[8], 8);
+ p_iphc += 8;
+ }
+ }
+ else
+ {
+ // Carry full source address in-line.
+ iphc_buff[1] |= (IPHC_SAC_0 << IPHC_SAC_POS);
+ iphc_buff[1] |= (IPHC_SAM_00 << IPHC_SAM_POS);
+ memcpy(p_iphc, p_iphdr->srcaddr.u8, IPV6_ADDR_SIZE);
+ p_iphc += IPV6_ADDR_SIZE;
+ }
+
+ // Destination compression.
+ if (IPV6_ADDRESS_IS_MULTICAST(&p_iphdr->destaddr))
+ {
+ iphc_buff[1] |= (IPHC_M_1 << IPHC_M_POS);
+
+ if (dci != IPV6_CONTEXT_IDENTIFIER_NONE)
+ {
+ iphc_buff[1] |= (IPHC_DAC_1 << IPHC_DAC_POS);
+ iphc_buff[1] |= (IPHC_DAM_00 << IPHC_DAM_POS);
+
+ p_iphdr->destaddr.u8[0] = 0xff;
+ memcpy(p_iphc, &p_iphdr->destaddr.u8[1], 2);
+ memcpy(p_iphc + 2, &p_iphdr->destaddr.u8[12], 4);
+ p_iphc += 6;
+ }
+ else if (IPV6_ADDRESS_IS_8_BIT_MCAST_COMPRESSABLE(&p_iphdr->destaddr))
+ {
+ iphc_buff[1] |= (IPHC_DAC_0 << IPHC_DAC_POS);
+ iphc_buff[1] |= (IPHC_DAM_11 << IPHC_DAM_POS);
+ *p_iphc++ = p_iphdr->destaddr.u8[15];
+
+ }
+ else if (IPV6_ADDRESS_IS_32_BIT_MCAST_COMPRESSABLE(&p_iphdr->destaddr))
+ {
+ iphc_buff[1] |= (IPHC_DAC_0 << IPHC_DAC_POS);
+ iphc_buff[1] |= (IPHC_DAM_10 << IPHC_DAM_POS);
+
+ *p_iphc = p_iphdr->destaddr.u8[1];
+ memcpy(p_iphc + 1, &p_iphdr->destaddr.u8[13], 3);
+ p_iphc += 4;
+ }
+ else if (IPV6_ADDRESS_IS_48_BIT_MCAST_COMPRESSABLE(&p_iphdr->destaddr))
+ {
+ iphc_buff[1] |= (IPHC_DAC_0 << IPHC_DAC_POS);
+ iphc_buff[1] |= (IPHC_DAM_01 << IPHC_DAM_POS);
+
+ *p_iphc = p_iphdr->destaddr.u8[1];
+ memcpy(p_iphc + 1, &p_iphdr->destaddr.u8[11], 5);
+ p_iphc += 6;
+ }
+ else
+ {
+ // Carry full destination multi-cast address in-line.
+ iphc_buff[1] |= (IPHC_DAC_0 << IPHC_DAC_POS);
+ iphc_buff[1] |= (IPHC_DAM_00 << IPHC_DAM_POS);
+ memcpy(p_iphc, p_iphdr->destaddr.u8, IPV6_ADDR_SIZE);
+ p_iphc += IPV6_ADDR_SIZE;
+ }
+ }
+ else
+ {
+ iphc_buff[1] |= (IPHC_M_0 << IPHC_M_POS);
+
+ if (dci != IPV6_CONTEXT_IDENTIFIER_NONE || IPV6_ADDRESS_IS_LINK_LOCAL(&p_iphdr->destaddr))
+ {
+ if (dci != IPV6_CONTEXT_IDENTIFIER_NONE)
+ {
+ iphc_buff[1] |= (IPHC_DAC_1 << IPHC_DAC_POS);
+ }
+
+ if (IPV6_ADDRESS_IS_FULLY_ELIDABLE(p_interface->peer_addr.identifier,
+ &p_iphdr->destaddr)
+ ||
+ dci_cover == true)
+ {
+ iphc_buff[1] |= (IPHC_DAM_11 << IPHC_DAM_POS);
+ }
+ else if (IPV6_ADDRESS_IS_16_BIT_COMPRESSABLE(&p_iphdr->destaddr))
+ {
+ iphc_buff[1] |= (IPHC_DAM_10 << IPHC_DAM_POS);
+ memcpy(p_iphc, &p_iphdr->destaddr.u8[14], 2);
+ p_iphc += 2;
+ }
+ else
+ {
+ iphc_buff[1] |= (IPHC_DAM_01 << IPHC_DAM_POS);
+ memcpy(p_iphc, &p_iphdr->destaddr.u8[8], 8);
+ p_iphc += 8;
+ }
+ }
+ else
+ {
+ // Carry full destination address in-line.
+ iphc_buff[1] |= (IPHC_DAC_0 << IPHC_DAC_POS);
+ iphc_buff[1] |= (IPHC_DAM_00 << IPHC_DAM_POS);
+ memcpy(p_iphc, p_iphdr->destaddr.u8, IPV6_ADDR_SIZE);
+ p_iphc += IPV6_ADDR_SIZE;
+ }
+ }
+
+ if ( iphc_buff[0] & IPHC_NH_MASK)
+ {
+ p_iphc += iphc_nhc_encode(p_iphc, p_input, &nhc_length);
+ }
+
+ // Calculate IPHC size.
+ iphc_len = (p_iphc - iphc_buff);
+
+ // Calculate IPv6 packet size.
+ *p_output_len = input_len - (IPV6_IP_HEADER_SIZE - iphc_len + nhc_length);
+
+ // Use p_data as final buffer (since IPHC+NHC <= IPv6 Header + NHC (UDP)).
+ memcpy((uint8_t *)&p_input[IPV6_IP_HEADER_SIZE + nhc_length - iphc_len], iphc_buff, iphc_len);
+
+ // Set correct address of output data.
+ *p_output = (uint8_t *) &p_input[IPV6_IP_HEADER_SIZE + nhc_length - iphc_len];
+
+ return NRF_SUCCESS;
+}
+
+
+/******************************************************************************
+ * @name 6LoWPAN transport functions
+ *****************************************************************************/
+
+/**@brief Function for notifying application of an error in an ongoing procedure.
+ *
+ * @param[in] p_interface Pointer to 6LoWPAN interface.
+ * @param[in] err_code Internally error code.
+ *
+ * @return None.
+ */
+static void app_notify_error(iot_interface_t * p_interface,
+ uint32_t err_code)
+{
+ ble_6lowpan_event_t event;
+
+ event.event_id = BLE_6LO_EVT_ERROR;
+ event.event_result = err_code;
+
+ BLE_6LOWPAN_MUTEX_UNLOCK();
+
+ m_event_handler(p_interface, &event);
+
+ BLE_6LOWPAN_MUTEX_LOCK();
+}
+
+
+/**@brief Function for notifying application of the new packet received.
+ *
+ * @param[in] p_interface Pointer to iot interface.
+ * @param[in] p_packet Pointer to decompressed IPv6 packet.
+ * @param[in] packet_len Length of IPv6 packet.
+ * @param[in] result Processing result of packet. Could be NRF_SUCCESS, or
+ * NRF_ERROR_NOT_FOUND if context identifier is unknown.
+ * @param[in] p_rx_contexts Received contexts if any.
+ *
+ * @return None.
+ */
+static void app_notify_rx_data(iot_interface_t * p_interface,
+ uint8_t * p_packet,
+ uint16_t packet_len,
+ uint32_t result,
+ iot_context_id_t * p_rx_contexts)
+{
+ ble_6lowpan_event_t event;
+
+ event.event_id = BLE_6LO_EVT_INTERFACE_DATA_RX;
+ event.event_result = result;
+ event.event_param.rx_event_param.p_packet = p_packet;
+ event.event_param.rx_event_param.packet_len = packet_len;
+ event.event_param.rx_event_param.rx_contexts = *(p_rx_contexts);
+
+ BLE_6LOWPAN_MUTEX_UNLOCK();
+
+ m_event_handler(p_interface, &event);
+
+ BLE_6LOWPAN_MUTEX_LOCK();
+}
+
+
+/**@brief Function for notifying application of the new interface established.
+ *
+ * @param[in] p_interface Pointer to new iot interface.
+ *
+ * @return None.
+ */
+static void app_notify_interface_add(iot_interface_t * p_interface)
+{
+ ble_6lowpan_event_t event;
+
+ event.event_id = BLE_6LO_EVT_INTERFACE_ADD;
+ event.event_result = NRF_SUCCESS;
+
+ BLE_6LOWPAN_MUTEX_UNLOCK();
+
+ m_event_handler(p_interface, &event);
+
+ BLE_6LOWPAN_MUTEX_LOCK();
+}
+
+
+/**@brief Function for notifying application of the interface disconnection.
+ *
+ * @param[in] p_interface Pointer to removed iot interface.
+ *
+ * @return None.
+ */
+static void app_notify_interface_delete(iot_interface_t * p_interface)
+{
+ ble_6lowpan_event_t event;
+
+ event.event_id = BLE_6LO_EVT_INTERFACE_DELETE;
+ event.event_result = NRF_SUCCESS;
+
+ BLE_6LOWPAN_MUTEX_UNLOCK();
+
+ m_event_handler(p_interface, &event);
+
+ BLE_6LOWPAN_MUTEX_LOCK();
+}
+
+
+/**@brief Function for initialize transmit FIFO.
+ *
+ * @param[in] p_fifo Pointer to transmit FIFO instance.
+ *
+ * @return None.
+ */
+static void tx_fifo_init(tx_fifo_t * p_fifo)
+{
+ memset(p_fifo->packets, 0, BLE_6LOWPAN_TX_FIFO_SIZE * sizeof (tx_packet_t));
+ p_fifo->read_pos = 0;
+ p_fifo->write_pos = 0;
+}
+
+
+/**@brief Function for putting new packet to transmit FIFO.
+ *
+ * @param[in] p_fifo Pointer to transmit FIFO instance.
+ * @param[in] p_packet Pointer to new packet.
+ *
+ * @return NRF_SUCCESS on success, otherwise NRF_ERROR_NO_MEM error.
+ */
+static uint32_t tx_fifo_put(tx_fifo_t * p_fifo, tx_packet_t * p_packet)
+{
+ uint32_t err_code = BLE_6LOWPAN_TX_FIFO_FULL;
+
+ // To prevent "The order of volatile accesses is undefined in this statement"
+ // in subsequent conditional statement.
+ uint32_t write_pos = p_fifo->write_pos;
+ uint32_t read_pos = p_fifo->read_pos;
+
+ if ((write_pos - read_pos) <= TX_FIFO_MASK)
+ {
+ p_fifo->packets[p_fifo->write_pos & TX_FIFO_MASK].p_data = p_packet->p_data;
+ p_fifo->packets[p_fifo->write_pos & TX_FIFO_MASK].data_len = p_packet->data_len;
+ p_fifo->packets[p_fifo->write_pos & TX_FIFO_MASK].p_mem_block = p_packet->p_mem_block;
+
+ p_fifo->write_pos++;
+
+ err_code = NRF_SUCCESS;
+ }
+
+ return err_code;
+}
+
+
+/**@brief Function for popping currently processed packet in transmit FIFO.
+ * It releases element on FIFO only when processing of the element is done.
+ *
+ * @param[in] p_fifo Pointer to transmit FIFO instance.
+ *
+ * @return None.
+ */
+static void tx_fifo_release(tx_fifo_t * p_fifo)
+{
+ p_fifo->read_pos++;
+}
+
+
+/**@brief Function for reading front element of transmit FIFO.
+ * After finish processing element in queue, it must be
+ * released using tx_fifo_release function.
+ *
+ * @param[in] p_fifo Pointer to transmit FIFO instance.
+ * @param[in] pp_packet Pointer to front packet.
+ *
+ * @return NRF_SUCCESS on success, otherwise NRF_ERROR_NO_MEM error.
+ */
+static uint32_t tx_fifo_get(tx_fifo_t * p_fifo, tx_packet_t * * pp_packet)
+{
+ uint32_t err_code = NRF_ERROR_NOT_FOUND;
+
+ // To prevent "The order of volatile accesses is undefined in this statement"
+ // in subsequent conditional statement.
+ uint32_t write_pos = p_fifo->write_pos;
+ uint32_t read_pos = p_fifo->read_pos;
+
+ if ((write_pos - read_pos) != 0)
+ {
+ *pp_packet = &p_fifo->packets[p_fifo->read_pos & TX_FIFO_MASK];
+ err_code = NRF_SUCCESS;
+ }
+
+ return err_code;
+}
+
+
+/**@brief Function for searching transport interface by given IPSP handle.
+ *
+ * @param[in] p_ipsp_handle Pointer to IPSP handle.
+ *
+ * @return Transport interface related with IPSP handle, or NULL if not found.
+ */
+static transport_instance_t * interface_get_by_handle(const ble_ipsp_handle_t * p_ipsp_handle)
+{
+ uint32_t index;
+
+ for (index = 0; index < BLE_6LOWPAN_MAX_INTERFACE; index++)
+ {
+ if (m_instances[index].handle.cid == p_ipsp_handle->cid &&
+ m_instances[index].handle.conn_handle == p_ipsp_handle->conn_handle)
+ {
+ return &m_instances[index];
+ }
+ }
+
+ return NULL;
+}
+
+
+/**@brief Function for initializing transport instance.
+ *
+ * @param[in] index Index of instance.
+ *
+ * @return None.
+ */
+static void instance_init(uint32_t index)
+{
+ memset(&m_instances[index], 0, sizeof (transport_instance_t));
+ m_instances[index].handle.cid = BLE_L2CAP_CID_INVALID;
+ m_instances[index].p_tx_cur_packet = NULL;
+ m_instances[index].interface.p_transport = (void *) index;
+}
+
+
+/**@brief Function for resetting specific 6lowpan interface.
+ *
+ * @param[in] p_interface Pointer to transport interface.
+ *
+ * @return None.
+ */
+static void interface_reset(transport_instance_t * p_instance)
+{
+ uint32_t index;
+ uint32_t instance_id = (uint32_t) p_instance->interface.p_transport;
+
+ // Free all queued packets.
+ for (index = 0; index < BLE_6LOWPAN_TX_FIFO_SIZE; index++)
+ {
+ if (m_instances[instance_id].tx_fifo.packets[index].p_mem_block != NULL)
+ {
+ nrf_free(m_instances[instance_id].tx_fifo.packets[index].p_mem_block);
+ }
+ }
+
+ instance_init (instance_id);
+}
+
+
+/**@brief Function for adding new transport instance.
+ *
+ * @param[in] p_peer_addr Pointer EUI-64 of peer address.
+ * @param[in] p_ipsp_handle Pointer IPSP handle, related with L2CAP CoC channel.
+ * @param[out] pp_instance Pointer to added transport instances, if operation succeeded.
+ *
+ * @return NRF_SUCCESS on success, otherwise NRF_ERROR_NO_MEM error.
+ */
+static uint32_t interface_add(const eui64_t * p_peer_addr,
+ const ble_ipsp_handle_t * p_ipsp_handle,
+ transport_instance_t ** pp_instance)
+{
+ uint32_t index;
+
+ for (index = 0; index < BLE_6LOWPAN_MAX_INTERFACE; index++)
+ {
+ if (m_instances[index].handle.cid == BLE_L2CAP_CID_INVALID)
+ {
+ m_instances[index].handle.cid = p_ipsp_handle->cid;
+ m_instances[index].handle.conn_handle = p_ipsp_handle->conn_handle;
+ m_instances[index].interface.tx_contexts.src_cntxt_id = IPV6_CONTEXT_IDENTIFIER_NONE;
+ m_instances[index].interface.tx_contexts.dest_cntxt_id = IPV6_CONTEXT_IDENTIFIER_NONE;
+
+ memcpy(&m_instances[index].interface.peer_addr, p_peer_addr, sizeof (eui64_t));
+ memcpy(&m_instances[index].interface.local_addr, &m_ll_addr, sizeof (eui64_t));
+
+ // Initialize TX FIFO.
+ tx_fifo_init(&m_instances[index].tx_fifo);
+
+ *pp_instance = &m_instances[index];
+
+ return NRF_SUCCESS;
+ }
+ }
+
+ return NRF_ERROR_NO_MEM;
+}
+
+
+/**@brief Function for checking if any transmission is currently processing on specific interface.
+ * Current version of L2CAP CoC in SoftDevice has limitation to send one packet at same
+ * time.
+ *
+ * @param[in] p_instance Pointer to transport instance.
+ *
+ * @return TRUE if interface not sending any packets, FALSE if busy.
+ */
+static bool tx_is_free(transport_instance_t * p_instance)
+{
+ return (NULL == p_instance->p_tx_cur_packet);
+}
+
+
+/**@brief Function uses for indicating transmission complete on specific interface.
+ *
+ * @param[in] p_instance Pointer to transport instance.
+ *
+ * @return None.
+ */
+static void tx_complete(transport_instance_t * p_instance)
+{
+ BLE_6LOWPAN_TRC("[CID 0x%04X]: Transmission complete.",
+ p_instance->handle.cid);
+
+ // Free the transmit buffer.
+ nrf_free(p_instance->p_tx_cur_packet->p_mem_block);
+ p_instance->p_tx_cur_packet = NULL;
+
+ // Release last processed packet.
+ tx_fifo_release(&p_instance->tx_fifo);
+}
+
+
+/**@brief Function for sending front packet from transmit FIFO on specific interface.
+ *
+ * @param[in] p_instance Pointer to transport instance.
+ *
+ * @return None.
+ */
+static void tx_send(transport_instance_t * p_instance)
+{
+ uint32_t err_code = NRF_SUCCESS;
+
+ if (NRF_SUCCESS == tx_fifo_get(&p_instance->tx_fifo,
+ &p_instance->p_tx_cur_packet))
+ {
+ err_code = ble_ipsp_send(&p_instance->handle,
+ p_instance->p_tx_cur_packet->p_data,
+ p_instance->p_tx_cur_packet->data_len);
+
+ if (NRF_SUCCESS != err_code)
+ {
+ BLE_6LOWPAN_TRC("Cannot send the packet, error = 0x%08lX", err_code);
+
+ app_notify_error(&p_instance->interface, err_code);
+
+ tx_complete(p_instance);
+
+ // Try to send another packet.
+ tx_send(p_instance);
+ }
+ }
+}
+
+/**@brief Callback registered with IPSP to receive asynchronous events from the module.
+ *
+ * @param[in] p_handle Pointer to IPSP handle.
+ * @param[in] p_evt Pointer to specific event, generated by IPSP module.
+ *
+ * @return NRF_SUCCESS on success, otherwise NRF_ERROR_NO_MEM error.
+ */
+static uint32_t ipsp_evt_handler(ble_ipsp_handle_t const * p_handle, ble_ipsp_evt_t const * p_evt)
+{
+ BLE_6LOWPAN_ENTRY();
+
+ VERIFY_MODULE_IS_INITIALIZED();
+
+ uint32_t mem_size;
+ uint16_t buff_len;
+ eui64_t peer_addr;
+ iot_context_id_t rx_contexts;
+ uint32_t retval = NRF_SUCCESS;
+ transport_instance_t * p_instance = NULL;
+ uint8_t * p_buff = NULL;
+
+ BLE_6LOWPAN_MUTEX_LOCK();
+
+ p_instance = interface_get_by_handle(p_handle);
+
+ switch (p_evt->evt_id)
+ {
+ case BLE_IPSP_EVT_CHANNEL_CONNECTED:
+ {
+ BLE_6LOWPAN_TRC("[CID 0x%04X]: >> BLE_IPSP_EVT_CHANNEL_CONNECTED",
+ p_handle->cid);
+ BLE_6LOWPAN_TRC("New channel established.");
+
+ if (p_instance == NULL)
+ {
+ IPV6_EUI64_CREATE_FROM_EUI48(peer_addr.identifier,
+ p_evt->p_evt_param->p_peer->addr,
+ p_evt->p_evt_param->p_peer->addr_type);
+
+ // Add interface to internal table.
+ retval = interface_add(&peer_addr, p_handle, &p_instance);
+
+ if (NRF_SUCCESS == retval)
+ {
+ BLE_6LOWPAN_TRC("Added new IPSP interface.");
+
+ // Notify application.
+ app_notify_interface_add(&p_instance->interface);
+ }
+ else
+ {
+ BLE_6LOWPAN_ERR("Cannot add new interface. Table is full.");
+ UNUSED_VARIABLE(ble_ipsp_disconnect(p_handle));
+ }
+ }
+ else
+ {
+ // Got a connection event, when already connected.
+ UNUSED_VARIABLE(ble_ipsp_disconnect(p_handle));
+ }
+
+ break;
+ }
+
+ case BLE_IPSP_EVT_CHANNEL_DISCONNECTED:
+ {
+ BLE_6LOWPAN_TRC("[CID 0x%04X]: >> BLE_IPSP_EVT_CHANNEL_DISCONNECTED",
+ p_handle->cid);
+ BLE_6LOWPAN_TRC("Channel disconnection.");
+
+ if (NULL != p_instance)
+ {
+ BLE_6LOWPAN_TRC("Removed IPSP interface.");
+
+ // Notify application.
+ app_notify_interface_delete(&p_instance->interface);
+
+ // Remove interface from internal table.
+ interface_reset(p_instance);
+ }
+
+ break;
+ }
+
+ case BLE_IPSP_EVT_CHANNEL_DATA_RX:
+ {
+
+ if (NULL != p_instance)
+ {
+ const uint16_t packet_len = MIN(p_evt->p_evt_param->p_l2cap_evt->params.rx.sdu_buf.len,
+ p_evt->p_evt_param->p_l2cap_evt->params.rx.sdu_len);
+
+ BLE_6LOWPAN_TRC("[CID 0x%04X]: >> BLE_IPSP_EVT_CHANNEL_DATA_RX",
+ p_handle->cid);
+
+ BLE_6LOWPAN_DUMP(p_evt->p_evt_param->p_l2cap_evt->params.rx.sdu_buf.p_data,
+ packet_len);
+
+ BLE_6LOWPAN_TRC("Processing received data.");
+
+ mem_size = packet_len + IPHC_MAX_COMPRESSED_DIFF;
+
+ // Try to allocate memory for incoming data.
+ retval = nrf_mem_reserve(&p_buff, &mem_size);
+
+ if (retval == NRF_SUCCESS)
+ {
+ // Decompress IPHC data into IPv6 packet.
+ retval = iphc_decode(&p_instance->interface,
+ p_buff,
+ &buff_len,
+ p_evt->p_evt_param->p_l2cap_evt->params.rx.sdu_buf.p_data,
+ packet_len,
+ &rx_contexts);
+
+ // Do not discard if packet decompressed successfully,
+ // otherwise error in Context based decompression.
+ if (retval == NRF_SUCCESS || retval == BLE_6LOWPAN_CID_NOT_FOUND)
+ {
+ if ((p_evt->evt_result == NRF_ERROR_BLE_IPSP_RX_PKT_TRUNCATED) &&
+ (retval == NRF_SUCCESS))
+ {
+ // Inform the application that the packet is truncated.
+ retval = NRF_ERROR_BLE_IPSP_RX_PKT_TRUNCATED;
+ }
+
+ BLE_6LOWPAN_TRC("Decompressed packet:");
+ BLE_6LOWPAN_DUMP(p_buff, buff_len);
+
+ // Notify application.
+ app_notify_rx_data(&p_instance->interface,
+ p_buff,
+ buff_len,
+ retval,
+ &rx_contexts);
+ }
+ else
+ {
+ BLE_6LOWPAN_ERR("Decompression failed!");
+
+ nrf_free(p_buff);
+ }
+ }
+ else
+ {
+ BLE_6LOWPAN_ERR(
+ "No buffer in memory pool available, packet dropped!");
+ }
+ }
+ else
+ {
+ BLE_6LOWPAN_ERR("Got data to unknown interface!");
+ }
+
+ break;
+ }
+
+ case BLE_IPSP_EVT_CHANNEL_DATA_TX_COMPLETE:
+ {
+ BLE_6LOWPAN_TRC("[CID 0x%04X]: >> BLE_IPSP_EVT_CHANNEL_DATA_TX_COMPLETE",
+ p_handle->cid);
+
+ // Free TX buffer.
+ tx_complete(p_instance);
+
+ // Try to send another packet.
+ tx_send(p_instance);
+
+ break;
+ }
+
+ default:
+ break;
+ }
+
+ BLE_6LOWPAN_MUTEX_UNLOCK();
+
+ BLE_6LOWPAN_EXIT();
+
+ return retval;
+}
+
+/******************************************************************************
+ * @name 6LoWPAN API functions
+ *****************************************************************************/
+
+uint32_t ble_6lowpan_init(const ble_6lowpan_init_t * p_init)
+{
+ BLE_6LOWPAN_ENTRY();
+
+ uint32_t index;
+ uint32_t retval = NRF_SUCCESS;
+ ble_ipsp_init_t ipsp_init_params;
+
+ NULL_PARAM_CHECK(p_init);
+ NULL_PARAM_CHECK(p_init->p_eui64);
+ NULL_PARAM_CHECK(p_init->event_handler);
+
+ // Check if the transmit FIFO size is a power of two.
+ if (!IS_POWER_OF_TWO(BLE_6LOWPAN_TX_FIFO_SIZE))
+ {
+ return NRF_ERROR_INVALID_LENGTH | BLE_6LOWPAN_ERR_BASE;
+ }
+
+ SDK_MUTEX_INIT(m_6lowpan_mutex);
+
+ BLE_6LOWPAN_MUTEX_LOCK();
+
+ // Store EUI64 in internal variable.
+ memcpy(m_ll_addr.identifier, p_init->p_eui64->identifier, EUI_64_ADDR_SIZE);
+
+ // Set application event handler.
+ m_event_handler = p_init->event_handler;
+
+ // Clear transport interfaces table.
+ for (index = 0; index < BLE_6LOWPAN_MAX_INTERFACE; index++)
+ {
+ instance_init(index);
+ }
+
+ // IPSP module initialization.
+ ipsp_init_params.evt_handler = ipsp_evt_handler;
+
+ // Initialize the IPSP module.
+ retval = ble_ipsp_init(&ipsp_init_params);
+
+ BLE_6LOWPAN_MUTEX_UNLOCK();
+
+ BLE_6LOWPAN_EXIT();
+
+ return retval;
+}
+
+
+uint32_t ble_6lowpan_interface_disconnect(const iot_interface_t * p_interface)
+{
+ BLE_6LOWPAN_ENTRY();
+
+ VERIFY_MODULE_IS_INITIALIZED();
+
+ NULL_PARAM_CHECK(p_interface);
+
+ uint32_t retval;
+ transport_instance_t * p_instance = &m_instances[(uint32_t)p_interface->p_transport];
+
+ BLE_6LOWPAN_MUTEX_LOCK();
+
+ retval = ble_ipsp_disconnect(&p_instance->handle);
+
+ BLE_6LOWPAN_MUTEX_UNLOCK();
+
+ BLE_6LOWPAN_EXIT();
+
+ return retval;
+}
+
+
+uint32_t ble_6lowpan_interface_send(const iot_interface_t * p_interface,
+ const uint8_t * p_packet,
+ uint16_t packet_len)
+{
+ BLE_6LOWPAN_ENTRY();
+
+ VERIFY_MODULE_IS_INITIALIZED();
+
+ NULL_PARAM_CHECK(p_packet);
+ NULL_PARAM_CHECK(p_interface);
+ PACKET_LENGTH_CHECK(packet_len);
+
+ uint32_t retval = NRF_SUCCESS;
+ uint8_t * p_output_buff = NULL;
+ uint16_t output_len;
+ tx_packet_t tx_packet;
+ transport_instance_t * p_instance = &m_instances[(uint32_t)p_interface->p_transport];
+
+ BLE_6LOWPAN_MUTEX_LOCK();
+
+ BLE_6LOWPAN_TRC("Uncompressed packet:");
+ BLE_6LOWPAN_DUMP((uint8_t *)p_packet, packet_len);
+
+ // Encode IP packet into IPHC.
+ retval = iphc_encode(p_interface,
+ &p_output_buff,
+ &output_len,
+ p_packet,
+ packet_len);
+
+ if (NRF_SUCCESS == retval)
+ {
+ BLE_6LOWPAN_TRC("Successfully compressed packet.");
+
+ tx_packet.p_data = p_output_buff;
+ tx_packet.data_len = output_len;
+ tx_packet.p_mem_block = (uint8_t *)p_packet;
+
+ retval = tx_fifo_put(&p_instance->tx_fifo, &tx_packet);
+
+ if (NRF_SUCCESS == retval)
+ {
+ BLE_6LOWPAN_TRC("Compressed packet:");
+ BLE_6LOWPAN_DUMP(p_output_buff, output_len);
+
+ // Send packet immediately if transport interface is not busy.
+ if (tx_is_free(p_instance))
+ {
+ tx_send(p_instance);
+ }
+ }
+ else
+ {
+ BLE_6LOWPAN_ERR("No place in TX queue!");
+ }
+ }
+ else
+ {
+ BLE_6LOWPAN_ERR("Error while compression!");
+ }
+
+ BLE_6LOWPAN_MUTEX_UNLOCK();
+
+ BLE_6LOWPAN_EXIT();
+
+ return retval;
+}
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/ble_6lowpan/ble_6lowpan.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/ble_6lowpan/ble_6lowpan.h
new file mode 100644
index 0000000..267ff30
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/ble_6lowpan/ble_6lowpan.h
@@ -0,0 +1,168 @@
+/**
+ * Copyright (c) 2014 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 ble_6lowpan.h
+ *
+ * @defgroup ble_6lowpan BLE 6LoWPAN library
+ * @ingroup iot_sdk_6lowpan
+ * @{
+ * @brief 6LoWPAN techniques defined for BLE.
+ *
+ * @details This module implements 6LoWPAN techniques defined for BLE, including
+ * IP and UDP header compression and decompression and conversion of EUI-48 BLE
+ * addresses to EUI-64 and on to IPv6 addresses. This layer does not implement IP level
+ * functionality of neighbor discovery etc.
+ * @note Currently, only the 6LoWPAN node (host) role is supported.
+ */
+
+#ifndef BLE_6LOWPAN_H__
+#define BLE_6LOWPAN_H__
+
+#include <stdint.h>
+#include "iot_defines.h"
+#include "iot_common.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**@brief Maximum 6LoWPAN interface supported by module. */
+#define BLE_6LOWPAN_MAX_INTERFACE 1
+
+/**@brief Maximum transmit packets that are buffered per interface.
+ *
+ * @details FIFO size must be a power of 2.
+ */
+#define BLE_6LOWPAN_TX_FIFO_SIZE 16
+
+/**@brief Asynchronous event identifiers type. */
+typedef enum
+{
+ BLE_6LO_EVT_ERROR, /**< Notification of an error in the module. */
+ BLE_6LO_EVT_INTERFACE_ADD, /**< Notification of a new 6LoWPAN interface added. */
+ BLE_6LO_EVT_INTERFACE_DELETE, /**< Notification of a 6LoWPAN interface deleted. */
+ BLE_6LO_EVT_INTERFACE_DATA_RX, /**< Notification of an IP packet received on the interface. */
+} ble_6lowpan_event_id_t;
+
+/**@brief Event parameters associated with the BLE_6LO_EVT_INTERFACE_DATA_RX event. */
+typedef struct
+{
+ uint8_t * p_packet; /**< Uncompressed IPv6 packet received. This memory is available to the application until it is freed by the application using mem_free. */
+ uint16_t packet_len; /**< Length of IPv6 packet. */
+ iot_context_id_t rx_contexts; /**< RX contexts used in stateful decompression. IPV6_CONTEXT_IDENTIFIER_NONE if not used. */
+} ble_6lowpan_data_rx_t;
+
+/**@brief Asynchronous event parameter type. */
+typedef union
+{
+ ble_6lowpan_data_rx_t rx_event_param; /**< Parameters notified with the received packet. */
+} ble_6lowpan_event_param_t;
+
+/**@brief Asynchronous event type. */
+typedef struct
+{
+ ble_6lowpan_event_id_t event_id; /**< Event identifier. */
+ ble_6lowpan_event_param_t event_param; /**< Event parameters. */
+ uint32_t event_result; /**< Result of event being notified. */
+} ble_6lowpan_event_t;
+
+/**@brief Asynchronous event notification callback type. */
+typedef void (*ble_6lowpan_evt_handler_t)(iot_interface_t * p_interface,
+ ble_6lowpan_event_t * p_event);
+
+
+/**@brief Initialization parameters type. */
+typedef struct
+{
+ eui64_t * p_eui64; /**< EUI-64 address. */
+ ble_6lowpan_evt_handler_t event_handler; /**< Asynchronous event notification callback registered to receive 6LoWPAN events. */
+} ble_6lowpan_init_t;
+
+
+/**@brief Initializes the module.
+ *
+ * @param[in] p_init Initialization parameters.
+ *
+ * @retval NRF_SUCCESS If initialization was successful. Otherwise, an error code is returned.
+ */
+uint32_t ble_6lowpan_init(const ble_6lowpan_init_t * p_init);
+
+
+/**@brief Disconnects 6LoWPAN interface.
+ *
+ * @details This function is used to terminate connection on the L2CAP CoC layer. It calls
+ * \ref ble_ipsp_disconnect to perform disconnection procedure. The registered callback
+ * from 6LoWPAN module propagates \ref BLE_6LO_EVT_INTERFACE_DELETE event after
+ * operation is finished.
+ *
+ * @param[in] p_interface Identifies the interface on which the disconnection has to be performed.
+ *
+ * @retval NRF_SUCCESS If disconnection was successful. Otherwise, an error code is returned.
+ */
+uint32_t ble_6lowpan_interface_disconnect(const iot_interface_t * p_interface);
+
+
+/**@brief Sends IPv6 packet on the 6LoWPAN interface.
+ *
+ * @details This function is used to send an IPv6 packet on the interface. 6LoWPAN compression
+ * techniques are applied on the packet before the packet is transmitted. The packet might
+ * not be transferred to the peer immediately based on the flow control on the BLE Link.
+ * In this case, the packet is queued to be transferred later.
+ *
+ * @param[in] p_interface Identifies the interface on which the packet is to be sent.
+ * @param[in] p_packet IPv6 packet to be sent. Memory for the packet should be allocated
+ * using mem_alloc and should not be freed. The module is responsible for
+ * freeing the memory using mem_free. The module will free the packet once
+ * the transmission is complete or the packet can no longer be transmitted
+ * (in case of link disconnection.)
+ * @param[in] packet_len Length of the IPv6 packet.
+ *
+ * @retval NRF_SUCCESS If the send request was successful.
+ */
+uint32_t ble_6lowpan_interface_send(const iot_interface_t * p_interface,
+ const uint8_t * p_packet,
+ uint16_t packet_len);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif //BLE_6LOWPAN_H__
+
+/** @} */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/coap/coap.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/coap/coap.c
new file mode 100644
index 0000000..4d58384
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/coap/coap.c
@@ -0,0 +1,854 @@
+/**
+ * Copyright (c) 2014 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#include <stdbool.h>
+#include <string.h>
+#include "nordic_common.h"
+#include "nrf.h"
+#include "coap_api.h"
+#include "coap.h"
+#include "coap_queue.h"
+#include "coap_transport.h"
+#include "sdk_common.h"
+#include "iot_common.h"
+#include "mem_manager.h"
+#include "coap_resource.h"
+#include "coap_observe_api.h"
+#include "coap_observe.h"
+
+#if IOT_COAP_CONFIG_LOG_ENABLED
+
+#define NRF_LOG_MODULE_NAME coap
+
+#define NRF_LOG_LEVEL IOT_COAP_CONFIG_LOG_LEVEL
+#define NRF_LOG_INFO_COLOR IOT_COAP_CONFIG_INFO_COLOR
+#define NRF_LOG_DEBUG_COLOR IOT_COAP_CONFIG_DEBUG_COLOR
+
+#include "nrf_log.h"
+NRF_LOG_MODULE_REGISTER();
+
+#define COAP_TRC NRF_LOG_DEBUG /**< Used for getting trace of execution in the module. */
+#define COAP_ERR NRF_LOG_ERROR /**< Used for logging errors in the module. */
+#define COAP_DUMP NRF_LOG_HEXDUMP_DEBUG /**< Used for dumping octet information to get details of bond information etc. */
+
+#define COAP_ENTRY() COAP_TRC(">> %s", __func__)
+#define COAP_EXIT() COAP_TRC("<< %s", __func__)
+#define COAP_EXIT_WITH_RESULT(result) COAP_TRC("<< %s, result: %d", __func__, result)
+
+#else // IOT_COAP_CONFIG_LOG_ENABLED
+
+#define COAP_TRC(...) /**< Disables traces. */
+#define COAP_DUMP(...) /**< Disables dumping of octet streams. */
+#define COAP_ERR(...) /**< Disables error logs. */
+
+#define COAP_ENTRY(...)
+#define COAP_EXIT(...)
+#define COAP_EXIT_WITH_RESULT(...)
+
+#endif // IOT_COAP_CONFIG_LOG_ENABLED
+
+#define COAP_REQUEST_ENTITY_MAX_SIZE (BLE_IPSP_RX_BUFFER_SIZE - (IPV6_IP_HEADER_SIZE + \
+ UDP_HEADER_SIZE)) /** Maximum request entity size. */
+
+SDK_MUTEX_DEFINE(m_coap_mutex) /**< Mutex variable. Currently unused, this declaration does not occupy any space in RAM. */
+
+static uint32_t m_token_seed; /**< Token seed provided by application to be used for generating token numbers. */
+static uint32_t m_message_id_counter; /**< Message ID counter, used to generate unique message IDs. */
+static coap_error_callback_t m_error_callback; /**< Function pointer to an application CoAP error handler. */
+
+static coap_request_handler_t m_request_handler = NULL; /**< Request handler where to forward all incoming requests. */
+
+#define COAP_MESSAGE_ACK_SET(REMOTE, LOCAL_PORT, MID) { \
+ memcpy(&m_coap_empty_message.remote, (REMOTE), sizeof(coap_remote_t)); \
+ m_coap_empty_message.port.port_number = (LOCAL_PORT); \
+ m_coap_empty_message.header.id = (MID); \
+ m_coap_empty_message.header.type = COAP_TYPE_ACK; \
+}
+
+#define COAP_MESSAGE_RST_SET(REMOTE, LOCAL_PORT, MID) { \
+ memcpy(&m_coap_empty_message.remote, (REMOTE), sizeof(coap_remote_t)); \
+ m_coap_empty_message.port.port_number = (LOCAL_PORT); \
+ m_coap_empty_message.header.id = (MID); \
+ m_coap_empty_message.header.type = COAP_TYPE_RST; \
+}
+
+static coap_message_t m_coap_empty_message = {
+ .header = {
+ .version = 1,
+ .type = COAP_TYPE_ACK,
+ .token_len = 0,
+ .code = COAP_CODE_EMPTY_MESSAGE,
+ .id = 0,
+ },
+ .p_payload = NULL,
+ .payload_len = 0,
+ .options_count = 0,
+ .p_arg = NULL,
+ .response_callback = NULL,
+ .port = {
+ .port_number = 0
+ },
+ .options_len = 0,
+ .options_offset = 0,
+ .p_data = NULL,
+ .data_len = 0
+};
+
+static inline bool is_ping(coap_message_t * p_message)
+{
+ return (p_message->header.code == COAP_CODE_EMPTY_MESSAGE) &&
+ (p_message->header.type == COAP_TYPE_CON);
+}
+
+static inline bool is_ack(coap_message_t * p_message)
+{
+ return (p_message->header.code == COAP_CODE_EMPTY_MESSAGE) &&
+ (p_message->header.type == COAP_TYPE_ACK);
+}
+
+static inline bool is_reset(coap_message_t * p_message)
+{
+ return (p_message->header.type == COAP_TYPE_RST);
+}
+
+static inline bool is_con(coap_message_t * p_message)
+{
+ return (p_message->header.type == COAP_TYPE_CON);
+}
+
+static inline bool is_non(coap_message_t * p_message)
+{
+ return (p_message->header.type == COAP_TYPE_NON);
+}
+
+static inline bool is_request(uint8_t message_code)
+{
+ return (message_code >= 1) && (message_code < 32);
+}
+
+static inline bool is_response(uint8_t message_code)
+{
+ return (message_code >= 64) && (message_code < 192);
+}
+
+static inline void app_error_notify(uint32_t err_code, coap_message_t * p_message)
+{
+ if (m_error_callback != NULL)
+ {
+ COAP_MUTEX_UNLOCK();
+
+ m_error_callback(err_code, p_message);
+
+ COAP_MUTEX_LOCK();
+ }
+}
+
+uint32_t coap_init(uint32_t token_rand_seed, coap_transport_init_t * p_transport_param)
+{
+ COAP_ENTRY();
+
+ uint32_t err_code;
+
+ SDK_MUTEX_INIT(m_coap_mutex);
+
+ COAP_MUTEX_LOCK();
+
+ internal_coap_observe_init();
+
+ m_error_callback = NULL;
+
+ m_token_seed = token_rand_seed;
+ (void)m_token_seed;
+
+ m_message_id_counter = 1;
+
+ err_code = coap_transport_init(p_transport_param);
+ if (err_code != NRF_SUCCESS)
+ {
+ COAP_MUTEX_UNLOCK();
+ return err_code;
+ }
+
+ err_code = coap_queue_init();
+ if (err_code != NRF_SUCCESS)
+ {
+ COAP_MUTEX_UNLOCK();
+ return err_code;
+ }
+
+ err_code = coap_resource_init();
+
+ COAP_MUTEX_UNLOCK();
+
+ COAP_EXIT();
+
+ return err_code;
+
+}
+
+uint32_t coap_error_handler_register(coap_error_callback_t error_callback)
+{
+ // TODO: error handling, null pointer, module initilized etc.
+ COAP_MUTEX_LOCK();
+
+ m_error_callback = error_callback;
+
+ COAP_MUTEX_UNLOCK();
+
+ return NRF_SUCCESS;
+}
+
+uint32_t internal_coap_message_send(uint32_t * p_handle, coap_message_t * p_message)
+{
+ if (p_message == NULL)
+ {
+ return (NRF_ERROR_NULL | IOT_COAP_ERR_BASE);
+ }
+
+ // Compiled away if COAP_ENABLE_OBSERVE_CLIENT is not set to 1.
+ coap_observe_client_send_handle(p_message);
+
+ COAP_ENTRY();
+
+ // Fetch the expected length of the packet serialized by passing length of 0.
+ uint16_t expected_length = 0;
+ uint32_t err_code = coap_message_encode(p_message, NULL, &expected_length);
+ if (err_code != NRF_SUCCESS)
+ {
+ return err_code;
+ }
+
+ // Allocate a buffer to serialize the message into.
+ uint8_t * p_buffer;
+ uint32_t request_length = expected_length;
+ err_code = nrf_mem_reserve(&p_buffer, &request_length);
+ if (err_code != NRF_SUCCESS)
+ {
+ COAP_TRC("p_buffer alloc error = 0x%08lX!", err_code);
+ return err_code;
+ }
+ memset(p_buffer, 0, request_length);
+ COAP_TRC("Alloc mem, p_buffer = %p", (uint8_t *)p_buffer);
+
+ // Serialize the message.
+ uint16_t buffer_length = (uint16_t)request_length;
+ err_code = coap_message_encode(p_message, p_buffer, &buffer_length);
+ if (err_code != NRF_SUCCESS)
+ {
+ COAP_TRC("Encode error!");
+ COAP_TRC("Free mem, p_buffer = %p", p_buffer);
+ UNUSED_VARIABLE(nrf_free(p_buffer));
+
+ return err_code;
+ }
+
+ err_code = coap_transport_write(&p_message->port, &p_message->remote, p_buffer, buffer_length);
+
+ if (err_code == NRF_SUCCESS)
+ {
+ if (is_con(p_message) || (is_non(p_message) &&
+ is_request(p_message->header.code) &&
+ (p_message->response_callback != NULL)))
+ {
+ coap_queue_item_t item;
+ item.p_arg = p_message->p_arg;
+ item.mid = p_message->header.id;
+ item.callback = p_message->response_callback;
+ item.p_buffer = p_buffer;
+ item.buffer_len = buffer_length;
+ item.timeout_val = COAP_ACK_TIMEOUT * COAP_ACK_RANDOM_FACTOR;
+
+ if (p_message->header.type == COAP_TYPE_CON)
+ {
+ item.timeout = item.timeout_val;
+ item.retrans_count = 0;
+ }
+ else
+ {
+ item.timeout = COAP_MAX_TRANSMISSION_SPAN;
+ item.retrans_count = COAP_MAX_RETRANSMIT_COUNT;
+ }
+
+ item.port = p_message->port;
+ item.token_len = p_message->header.token_len;
+
+ memcpy(&item.remote, &p_message->remote, sizeof(coap_remote_t));
+ memcpy(item.token, p_message->token, p_message->header.token_len);
+
+ err_code = coap_queue_add(&item);
+ if (err_code != NRF_SUCCESS)
+ {
+ COAP_TRC("Message queue error = 0x%08lX!", err_code);
+
+ COAP_TRC("Free mem, p_buffer = %p", p_buffer);
+ UNUSED_VARIABLE(nrf_free(p_buffer));
+
+ return err_code;
+ }
+
+ *p_handle = item.handle;
+ }
+ else
+ {
+ *p_handle = COAP_MESSAGE_QUEUE_SIZE;
+
+ COAP_TRC("Free mem, p_buffer = %p", p_buffer);
+ UNUSED_VARIABLE(nrf_free(p_buffer));
+ }
+ }
+ else
+ {
+ COAP_TRC("Free mem, p_buffer = %p", p_buffer);
+ UNUSED_VARIABLE(nrf_free(p_buffer));
+ }
+
+ COAP_EXIT();
+
+ return err_code;
+}
+
+
+static uint32_t create_response(coap_message_t ** pp_response, coap_message_t * p_request, uint16_t data_size)
+{
+ uint32_t err_code;
+
+ // Allocate space for a new message.
+ uint32_t size = sizeof(coap_message_t);
+ err_code = nrf_mem_reserve((uint8_t **)pp_response, &size);
+ if (err_code != NRF_SUCCESS)
+ {
+ return err_code;
+ }
+
+ coap_message_t * p_response = (*pp_response);
+
+ memset(p_response, 0, sizeof(coap_message_t));
+ COAP_TRC("Alloc mem, p_response = %p", (uint8_t *)p_response);
+
+ if (data_size > 0)
+ {
+ // Allocate a scratch buffer for payload and options.
+ size = data_size;
+ err_code = nrf_mem_reserve(&(p_response->p_data), &size);
+ if (err_code != NRF_SUCCESS)
+ {
+ return err_code;
+ }
+ memset(p_response->p_data, 0, size);
+ p_response->data_len = size;
+ COAP_TRC("Alloc mem, p_response->p_data = %p", p_response->p_data);
+ }
+
+ coap_message_conf_t config;
+ memset (&config, 0, sizeof(coap_message_conf_t));
+
+ config.token_len = p_request->header.token_len;
+ config.id = p_request->header.id;
+ config.code = COAP_CODE_404_NOT_FOUND;
+ config.port.port_number = p_request->port.port_number;
+
+ memcpy(config.token, p_request->token, p_request->header.token_len);
+
+ if ((coap_msg_type_t)p_request->header.type == COAP_TYPE_CON)
+ {
+ config.type = COAP_TYPE_ACK;
+ }
+ else
+ {
+ config.type = (coap_msg_type_t)p_request->header.type;
+ }
+
+ err_code = coap_message_create(p_response, &config);
+ if (err_code != NRF_SUCCESS)
+ {
+ return err_code;
+ }
+
+ (void)coap_message_remote_addr_set(p_response, &p_request->remote);
+
+ return NRF_SUCCESS;
+}
+
+
+/**@brief Common function for sending response error message
+ *
+ * @param[in] p_message Pointer to the original request message.
+ * @param[in] code CoAP message code to send in the reponse.
+ *
+ * @retval NRF_SUCCESS If the response was sent out successfully.
+ */
+static uint32_t send_error_response(coap_message_t * p_message, uint8_t code)
+{
+ coap_message_t * p_error_response = NULL;
+
+ uint32_t err_code = create_response(&p_error_response, p_message, COAP_MESSAGE_DATA_MAX_SIZE);
+ if (err_code != NRF_SUCCESS)
+ {
+ // If message could not be created, notify the application.
+ app_error_notify(err_code, p_message);
+ return err_code;
+ }
+
+ // Set the response code.
+ p_error_response->header.code = code;
+
+ if (p_error_response != NULL)
+ {
+ uint32_t handle;
+ err_code = internal_coap_message_send(&handle, p_error_response);
+
+ COAP_TRC("Free mem, p_response->p_data = %p", p_error_response->p_data);
+ UNUSED_VARIABLE(nrf_free(p_error_response->p_data));
+
+ COAP_TRC("Free mem, p_response = %p", (uint8_t *)p_error_response);
+ UNUSED_VARIABLE(nrf_free((uint8_t *)p_error_response));
+ }
+
+ return err_code;
+}
+
+uint32_t coap_transport_read(const coap_port_t * p_port,
+ const coap_remote_t * p_remote,
+ const coap_remote_t * p_local,
+ uint32_t result,
+ const uint8_t * p_data,
+ uint16_t datalen)
+{
+ COAP_ENTRY();
+
+ // Discard all packets if not success or truncated.
+ if (!(result == NRF_SUCCESS || result == UDP_TRUNCATED_PACKET))
+ {
+ return NRF_SUCCESS;
+ }
+
+ uint32_t err_code;
+ coap_message_t * p_message;
+
+ // Allocate space for a new message.
+ uint32_t size = sizeof(coap_message_t);
+ err_code = nrf_mem_reserve((uint8_t **)&p_message, &size);
+ if (err_code != NRF_SUCCESS)
+ {
+ return err_code;
+ }
+
+ memset(p_message, 0, sizeof(coap_message_t));
+ COAP_TRC("Alloc mem, p_message = %p", (uint8_t *)p_message);
+
+ err_code = coap_message_decode(p_message, p_data, datalen);
+ if (err_code != NRF_SUCCESS)
+ {
+ app_error_notify(err_code, p_message);
+
+ UNUSED_VARIABLE(nrf_free((uint8_t *)p_message));
+ return err_code;
+ }
+
+ // Copy the remote address information.
+ memcpy(&p_message->remote, p_remote, sizeof(coap_remote_t));
+
+ // Copy the destination address information.
+ if (p_local)
+ {
+ memcpy(&p_message->local, p_local, sizeof(coap_remote_t));
+ }
+
+ // Copy the local port information.
+ memcpy(&p_message->port, p_port, sizeof(coap_port_t));
+
+ if (result == UDP_TRUNCATED_PACKET)
+ {
+ app_error_notify(result, p_message);
+ }
+ else if (is_ping(p_message))
+ {
+ COAP_MESSAGE_RST_SET(&p_message->remote, p_message->port.port_number, p_message->header.id);
+
+ uint32_t handle;
+ err_code = internal_coap_message_send(&handle, &m_coap_empty_message);
+ }
+ else if (is_ack(p_message) ||
+ is_reset(p_message))
+ {
+ // Populate the token with the one used sending, before passing it to the application.
+ coap_queue_item_t * p_item = NULL;
+ err_code = coap_queue_item_by_mid_get(&p_item, p_message->header.id);
+
+ if (err_code == NRF_SUCCESS)
+ {
+ if (p_item->callback != NULL)
+ {
+ // As the token is missing from peer, it will be added before giving it to the application.
+ memcpy(p_message->token, p_item->token, p_item->token_len);
+ p_message->header.token_len = p_item->token_len;
+
+ // Compiled away if COAP_ENABLE_OBSERVE_CLIENT is not set to 1.
+ coap_observe_client_response_handle(p_message, p_item);
+
+ COAP_TRC(">> application callback");
+
+ COAP_MUTEX_UNLOCK();
+
+ if (is_ack(p_message))
+ {
+ p_item->callback(NRF_SUCCESS, p_item->p_arg, p_message);
+ }
+ else
+ {
+ p_item->callback(COAP_TRANSMISSION_RESET_BY_PEER, p_item->p_arg, p_message);
+ }
+
+ COAP_MUTEX_LOCK();
+
+ COAP_TRC("<< application callback");
+ }
+
+ COAP_TRC("Free mem, p_item->p_buffer = %p", p_item->p_buffer);
+ UNUSED_VARIABLE(nrf_free(p_item->p_buffer));
+
+ // Remove the queue element, as a match occured.
+ err_code = coap_queue_remove(p_item);
+ }
+ }
+ else if (is_response(p_message->header.code))
+ {
+ COAP_TRC("CoAP message type: RESPONSE");
+
+ coap_queue_item_t * p_item;
+ err_code = coap_queue_item_by_token_get(&p_item, p_message->token, p_message->header.token_len);
+ if (err_code != NRF_SUCCESS)
+ {
+ // Compiled away if COAP_ENABLE_OBSERVE_CLIENT is not set to 1.
+ coap_observe_client_response_handle(p_message, NULL);
+
+ UNUSED_VARIABLE(nrf_free((uint8_t *)p_message));
+
+ COAP_MUTEX_UNLOCK();
+
+ return err_code;
+ }
+
+ if (p_item->callback != NULL)
+ {
+ // Compiled away if COAP_ENABLE_OBSERVE_CLIENT is not set to 1.
+ coap_observe_client_response_handle(p_message, p_item);
+
+ COAP_TRC(">> application callback");
+
+ COAP_MUTEX_UNLOCK();
+
+ p_item->callback(NRF_SUCCESS, p_item->p_arg, p_message);
+
+ COAP_MUTEX_LOCK();
+
+ COAP_TRC("<< application callback");
+ }
+
+ COAP_TRC("Free mem, p_item->p_buffer = %p", p_item->p_buffer);
+ UNUSED_VARIABLE(nrf_free(p_item->p_buffer));
+
+ err_code = coap_queue_remove(p_item);
+
+ }
+ else if (is_request(p_message->header.code))
+ {
+ COAP_TRC("CoAP message type: REQUEST");
+
+ if (m_request_handler != NULL)
+ {
+ uint32_t return_code = m_request_handler(p_message);
+
+ // If success, then all processing and any responses has been sent
+ // by the application callback.
+
+ // If not success, then send an appropriate error message back to the
+ // origin with the return_code from the callback.
+ if (return_code != NRF_SUCCESS)
+ {
+ if (return_code == NRF_ERROR_NOT_FOUND)
+ {
+ // Send response with provided CoAP code.
+ (void)send_error_response(p_message, COAP_CODE_404_NOT_FOUND);
+ }
+ else if (return_code == NRF_ERROR_NULL)
+ {
+ (void)send_error_response(p_message, COAP_CODE_405_METHOD_NOT_ALLOWED);
+ }
+ else
+ {
+ (void)send_error_response(p_message, COAP_CODE_400_BAD_REQUEST);
+ }
+ }
+ }
+ else
+ {
+ uint8_t * uri_pointers[COAP_RESOURCE_MAX_DEPTH] = {0, };
+
+ uint8_t uri_path_count = 0;
+ uint16_t index;
+
+ for (index = 0; index < p_message->options_count; index++)
+ {
+ if (p_message->options[index].number == COAP_OPT_URI_PATH)
+ {
+ uri_pointers[uri_path_count++] = p_message->options[index].p_data;
+ }
+ }
+
+ coap_resource_t * found_resource;
+ err_code = coap_resource_get(&found_resource, uri_pointers, uri_path_count);
+
+ if (found_resource != NULL)
+ {
+ if (found_resource->callback != NULL)
+ {
+ if (((found_resource->permission) & (1 << ((p_message->header.code) - 1))) > 0) // Has permission for the requested CoAP method.
+ {
+ COAP_MUTEX_UNLOCK();
+
+ found_resource->callback(found_resource, p_message);
+
+ COAP_MUTEX_LOCK();
+ }
+ else
+ {
+ // Reply with Method Not Allowed.
+ err_code = send_error_response(p_message, COAP_CODE_405_METHOD_NOT_ALLOWED);
+ }
+ }
+ else
+ {
+ // Reply with Method Not Allowed.
+ err_code = send_error_response(p_message, COAP_CODE_405_METHOD_NOT_ALLOWED);
+ }
+ }
+ else
+ {
+ // Reply with NOT FOUND.
+ err_code = send_error_response(p_message, COAP_CODE_404_NOT_FOUND);
+ }
+ }
+ }
+
+ COAP_TRC("Free mem, p_message = %p", (uint8_t *)p_message);
+ UNUSED_VARIABLE(nrf_free((uint8_t *)p_message));
+
+ COAP_EXIT();
+ return err_code;
+}
+
+uint32_t coap_message_send(uint32_t * p_handle, coap_message_t * p_message)
+{
+ COAP_MUTEX_LOCK();
+
+ uint32_t err_code = internal_coap_message_send(p_handle, p_message);
+
+ COAP_MUTEX_UNLOCK();
+
+ return err_code;
+}
+
+uint32_t coap_message_abort(uint32_t handle)
+{
+
+ return NRF_ERROR_NOT_SUPPORTED;
+}
+
+uint32_t coap_message_new(coap_message_t ** p_request, coap_message_conf_t * p_config)
+{
+ COAP_ENTRY();
+
+ uint32_t err_code;
+
+ // If port is not configured, return error and skip initialization of the message.
+ if (p_config->port.port_number == 0)
+ {
+ return (NRF_ERROR_INVALID_PARAM | IOT_COAP_ERR_BASE);
+ }
+
+ COAP_MUTEX_LOCK();
+
+ // Allocate space for a new message.
+ uint32_t size = sizeof(coap_message_t);
+ err_code = nrf_mem_reserve((uint8_t **)p_request, &size);
+ if (err_code != NRF_SUCCESS)
+ {
+ COAP_MUTEX_UNLOCK();
+ return err_code;
+ }
+
+ memset(*p_request, 0, sizeof(coap_message_t));
+ COAP_TRC("Alloc mem, *p_request = %p", (uint8_t *)(*p_request));
+
+ // Allocate a scratch buffer for payload and options.
+ size = COAP_MESSAGE_DATA_MAX_SIZE;
+ err_code = nrf_mem_reserve(&((*p_request)->p_data), &size);
+ if (err_code != NRF_SUCCESS)
+ {
+ COAP_TRC("Allocation of message data buffer failed!");
+
+ COAP_TRC("Free mem, *p_request = %p", (uint8_t *)(*p_request));
+ UNUSED_VARIABLE(nrf_free((uint8_t *)(*p_request)));
+
+ COAP_MUTEX_UNLOCK();
+ return err_code;
+ }
+
+ memset((*p_request)->p_data, 0, size);
+ (*p_request)->data_len = size;
+
+ COAP_TRC("Alloc mem, (*p_request)->p_data = %p", (uint8_t *)((*p_request)->p_data));
+
+ if (p_config->id == 0) // Message id is not set, generate one.
+ {
+ p_config->id = m_message_id_counter++;
+ }
+
+ err_code = coap_message_create(*p_request, p_config);
+
+ COAP_MUTEX_UNLOCK();
+
+ COAP_EXIT_WITH_RESULT(err_code);
+
+ return err_code;
+}
+
+uint32_t coap_message_delete(coap_message_t * p_message)
+{
+ COAP_ENTRY();
+
+ COAP_MUTEX_LOCK();
+
+ //If this is a request free the coap_message_t and the data buffer.
+
+ COAP_TRC("Free mem, p_message->p_data = %p", p_message->p_data);
+ UNUSED_VARIABLE(nrf_free(p_message->p_data));
+
+ COAP_TRC("Free mem, p_message = %p", (uint8_t *)p_message);
+ UNUSED_VARIABLE(nrf_free((uint8_t *)p_message));
+
+
+ COAP_MUTEX_UNLOCK();
+
+ COAP_EXIT();
+
+ return NRF_SUCCESS;
+}
+
+
+uint32_t coap_time_tick(void)
+{
+ COAP_MUTEX_LOCK();
+
+ coap_transport_process();
+
+ // Loop through the message queue to see if any packets needs retransmission, or has timed out.
+ coap_queue_item_t * p_item = NULL;
+ while (coap_queue_item_next_get(&p_item, p_item) == NRF_SUCCESS)
+ {
+ if (p_item->timeout == 0)
+ {
+ // If there is still retransmission attempts left.
+ if (p_item->retrans_count < COAP_MAX_RETRANSMIT_COUNT)
+ {
+ p_item->timeout = p_item->timeout_val * 2;
+ p_item->timeout_val = p_item->timeout;
+ p_item->retrans_count++;
+
+ // Retransmit the message.
+ uint32_t err_code = coap_transport_write(&p_item->port, &p_item->remote, p_item->p_buffer, p_item->buffer_len);
+ if (err_code != NRF_SUCCESS)
+ {
+ app_error_notify(err_code, NULL);
+ }
+ }
+
+ // No more retransmission attempts left, or max transmit span reached.
+ if ((p_item->timeout > COAP_MAX_TRANSMISSION_SPAN) ||
+ (p_item->retrans_count >= COAP_MAX_RETRANSMIT_COUNT))
+ {
+
+ COAP_MUTEX_UNLOCK();
+
+ p_item->callback(COAP_TRANSMISSION_TIMEOUT, p_item->p_arg, NULL);
+
+ COAP_MUTEX_LOCK();
+
+ COAP_TRC("Free mem, p_item->p_buffer = %p", p_item->p_buffer);
+ UNUSED_VARIABLE(nrf_free(p_item->p_buffer));
+
+ (void)coap_queue_remove(p_item);
+ }
+ }
+ else
+ {
+ p_item->timeout--;
+ }
+ }
+
+ COAP_MUTEX_UNLOCK();
+
+ return NRF_SUCCESS;
+}
+
+uint32_t coap_request_handler_register(coap_request_handler_t p_request_handler)
+{
+ COAP_MUTEX_LOCK();
+
+ m_request_handler = p_request_handler;
+
+ COAP_MUTEX_UNLOCK();
+
+ return NRF_SUCCESS;
+}
+
+__WEAK void coap_transport_input(void)
+{
+ // By default not implemented. Transport specific.
+}
+
+void coap_input(void)
+{
+ COAP_MUTEX_LOCK();
+
+ coap_transport_input();
+
+ COAP_MUTEX_UNLOCK();
+}
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/coap/coap.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/coap/coap.h
new file mode 100644
index 0000000..09d9ecb
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/coap/coap.h
@@ -0,0 +1,125 @@
+/**
+ * Copyright (c) 2014 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 coap.h
+ *
+ * @defgroup iot_sdk_coap_api CoAP interface
+ * @ingroup iot_sdk_coap
+ * @{
+ * @brief Interface for the CoAP protocol.
+ */
+
+#ifndef COAP_H__
+#define COAP_H__
+
+#include "iot_errors.h"
+#include "coap_api.h"
+#include "sdk_os.h"
+
+/**
+ * @defgroup iot_coap_log Module's Log Macros
+ * @details Macros used for creating module logs which can be useful in understanding handling
+ * of events or actions on API requests. These are intended for debugging purposes and
+ * can be enabled by defining the COAP_ENABLE_LOGS to 1.
+ * @note If NRF_LOG_ENABLED is disabled, having COAP_ENABLE_LOGS has no effect.
+ * @{
+ */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#if (COAP_DISABLE_API_PARAM_CHECK == 0)
+
+/**@brief Verify NULL parameters are not passed to API by application. */
+#define NULL_PARAM_CHECK(PARAM) \
+ if ((PARAM) == NULL) \
+ { \
+ return (NRF_ERROR_NULL | IOT_COAP_ERR_BASE); \
+ }
+
+/**@brief Verify that parameter members has been set by the application. */
+#define NULL_PARAM_MEMBER_CHECK(PARAM) \
+ if ((PARAM) == NULL) \
+ { \
+ return (NRF_ERROR_INVALID_PARAM | IOT_COAP_ERR_BASE); \
+ }
+#else
+
+#define NULL_PARAM_CHECK(PARAM)
+#define NULL_PARAM_MEMBER_CHECK(PARAM)
+
+#endif // COAP_DISABLE_API_PARAM_CHECK
+
+/**
+ * @defgroup iot_coap_mutex_lock_unlock Module's Mutex Lock/Unlock Macros.
+ *
+ * @details Macros used to lock and unlock modules. Currently, SDK does not use mutexes but
+ * framework is provided in case the need to use an alternative architecture arises.
+ * @{
+ */
+#define COAP_MUTEX_LOCK() SDK_MUTEX_LOCK(m_coap_mutex) /**< Lock module using mutex */
+#define COAP_MUTEX_UNLOCK() SDK_MUTEX_UNLOCK(m_coap_mutex) /**< Unlock module using mutex */
+
+SDK_MUTEX_DEFINE(m_coap_mutex)
+
+/** @} */
+
+/**@brief Sends a CoAP message.
+ *
+ * @details Sends out a request using the underlying transport layer. Before sending, the
+ * \ref coap_message_t structure is serialized and added to an internal message queue
+ * in the library. The handle returned can be used to abort the message from being
+ * retransmitted at any time.
+ *
+ * @param[out] p_handle Handle to the message if CoAP CON/ACK messages has been used. Returned
+ * by reference.
+ * @param[in] p_message Message to be sent.
+ *
+ * @retval NRF_SUCCESS If the message was successfully encoded and scheduled for transmission.
+ */
+uint32_t internal_coap_message_send(uint32_t * p_handle, coap_message_t * p_message);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // COAP_H__
+
+/** @} */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/coap/coap_api.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/coap/coap_api.h
new file mode 100644
index 0000000..9bc0222
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/coap/coap_api.h
@@ -0,0 +1,663 @@
+/**
+ * Copyright (c) 2014 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 coap_api.h
+ *
+ * @defgroup iot_sdk_coap_api CoAP Application Programming Interface
+ * @ingroup iot_sdk_coap
+ * @{
+ * @brief Public API of Nordic's CoAP implementation.
+ *
+ */
+
+#ifndef COAP_API_H__
+#define COAP_API_H__
+
+#include <stdint.h>
+#include "coap_transport.h"
+#include "coap_codes.h"
+#include "sdk_config.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**@defgroup COAP_CONTENT_TYPE_MASK Resource content type bitmask values
+ * @{ */
+#define COAP_CT_MASK_PLAIN_TEXT 0x01 /**< Content type Plain text supported in the endpoint resource. */
+#define COAP_CT_MASK_CHARSET_UTF8 0x02 /**< Content type Charset-UTF8 supported in the endpoint resource. */
+#define COAP_CT_MASK_APP_LINK_FORMAT 0x04 /**< Content type Application/link-format supported in the endpoint resource. */
+#define COAP_CT_MASK_APP_XML 0x08 /**< Content type Application/xml supported in the endpoint resource. */
+#define COAP_CT_MASK_APP_OCTET_STREAM 0x10 /**< Content type Application/octet-stream supported in the endpoint resource. */
+#define COAP_CT_MASK_APP_EXI 0x20 /**< Content type Application/exi supported in the endpoint resource. */
+#define COAP_CT_MASK_APP_JSON 0x40 /**< Content type Application/json supported in the endpoint resource. */
+/**@} */
+
+/**@defgroup COAP_METHOD_PERMISSION Resource method permission bitmask values
+ * @{ */
+#define COAP_PERM_NONE 0x0000 /**< Permission by default. Do not allow any method in the COAP/COAPS endpoint resource. */
+#define COAP_PERM_GET 0x0001 /**< Permission to allow GET method in the COAP endpoint resource. */
+#define COAP_PERM_POST 0x0002 /**< Permission to allow POST method in the COAP endpoint resource. */
+#define COAP_PERM_PUT 0x0004 /**< Permission to allow PUT method in the COAP endpoint resource. */
+#define COAP_PERM_DELETE 0x0008 /**< Permission to allow DELETE method in the COAP endpoint resource. */
+#define COAPS_PERM_GET 0x0010 /**< Permission to allow GET method in the COAPS endpoint resource. */
+#define COAPS_PERM_POST 0x0020 /**< Permission to allow POST method in the COAPS endpoint resource. */
+#define COAPS_PERM_PUT 0x0040 /**< Permission to allow PUT method in the COAPS endpoint resource. */
+#define COAPS_PERM_DELETE 0x0080 /**< Permission to allow DELETE method in the COAPS endpoint resource. */
+#define COAP_PERM_OBSERVE 0x0100 /**< Permission to allow OBSERVE of the endpoint resource. */
+/**@} */
+
+/**@cond */
+// Forward declare structs.
+typedef struct coap_message_t coap_message_t;
+typedef struct coap_resource_t coap_resource_t;
+/**@endcond */
+
+/**@brief Callback function to call upon undefined behaviour.
+ *
+ * @param[in] error_code Error code from CoAP module.
+ * @param[in] p_message CoAP message processed when error ocoured. Could be NULL.
+ */
+typedef void (*coap_error_callback_t)(uint32_t error_code, coap_message_t * p_message);
+
+/**@brief Callback function to be registered with CoAP messages.
+ *
+ * @param[in] status Response status. Possible status codes:
+ * NRF_SUCCESS If response was successfully received,
+ * COAP_TRANSMISSION_RESET_BY_PEER if a reset response was recieved or,
+ * COAP_TRANSMISSION_TIMEOUT if transmission
+ * @param[in] p_arg Miscellaneous pointer to application provided data that is associated with
+ * the message.
+ * @param[in] p_message Pointer to a CoAP Response message.
+ */
+typedef void (*coap_response_callback_t)(uint32_t status, void * p_arg, coap_message_t * p_message);
+
+/**@brief Handler function for manually handling all incoming requests.
+ *
+ * @details If the function is set, the error code given back will trigger error messages
+ * to be sent back by CoAP to indicate failure. Default error message will be 4.00
+ * BAD REQUEST. On success, it is expected that the callback has already sent a
+ * response message.
+ *
+ * @param[in] p_request Pointer to a CoAP Request message.
+ *
+ * @retval NRF_SUCCESS If the message was successfully has been handled.
+ * @retval NRF_ERROR_NOT_FOUND If the message did not match any recognized resources, and a
+ * 4.04 NOT FOUND error message should be sent back to the requester.
+ * @retval NRF_ERROR_NULL If the message resolved the resource and operation not permitted,
+ * and a 4.05 METHOD NOT ALLOWED error message should be sent back to
+ * the reqester.
+ *
+ */
+typedef uint32_t (*coap_request_handler_t)(coap_message_t * p_request);
+
+#ifdef COAP_AUTOMODE
+
+/**@brief Callback function to be registered with CoAP endpoint resources. in auto-mode.
+ *
+ * @details The callback needs to implement any action based on the request. The p_response message
+ * will automatically be sent as response when the callback function returns. The memory
+ * is allocated by the caller, so the application does not have to free up the memory used
+ * for the response.
+ *
+ * @param[in] p_resource Pointer to the request message's target resource.
+ * @param[in] p_request Pointer to the request message.
+ * @param[out] p_response Pointer to the prepared response message. The Application can override
+ * its values.
+ */
+typedef void (*coap_method_callback_t) (coap_resource_t * p_resource, coap_message_t * p_request, coap_message_t * p_response);
+
+#else // COAP_AUTOMODE
+
+/**@brief Callback function to be registered with CoAP endpoint resources. in auto-mode.
+ *
+ * @details The callback needs to implement any action based on the request. The callback is
+ * responsible of handling the sending of any response back to the requester. The memory
+ * for p_request will be freed up by the coap module after the callback has been
+ * completed.
+ *
+ * @param[in] p_resource Pointer to the request message's target resource.
+ * @param[in] p_request Pointer to the request message.
+ */
+typedef void (*coap_method_callback_t) (coap_resource_t * p_resource, coap_message_t * p_request);
+
+#endif // COAP_AUTOMODE
+
+/**@brief Enumeration of CoAP content types. */
+typedef enum
+{
+ COAP_CT_PLAIN_TEXT = 0, /**< Plain text content format number. Default. */
+ COAP_CT_APP_LINK_FORMAT = 40, /**< Application/link-format content format number. */
+ COAP_CT_APP_XML = 41, /**< Application/xml content format number. */
+ COAP_CT_APP_OCTET_STREAM = 42, /**< Application/octet-stream content format number. */
+ COAP_CT_APP_EXI = 47, /**< Application/exi content format number. */
+ COAP_CT_APP_JSON = 50 /**< Application/json content format number. */
+} coap_content_type_t;
+
+/**@brief Enumeration of CoAP options numbers. */
+
+#define COAP_OPT_RESERVED0 0 /**< Reserved option number. */
+#define COAP_OPT_IF_MATCH 1 /**< If-Match option number. */
+#define COAP_OPT_URI_HOST 3 /**< URI-Host option number. */
+#define COAP_OPT_ETAG 4 /**< ETag option number. */
+#define COAP_OPT_IF_NONE_MATCH 5 /**< If-None-Match option number. */
+#define COAP_OPT_URI_PORT 7 /**< URI-Port option number. */
+#define COAP_OPT_LOCATION_PATH 8 /**< Location-Path option number. */
+#define COAP_OPT_URI_PATH 11 /**< URI-Path option number. */
+#define COAP_OPT_CONTENT_FORMAT 12 /**< Content-Format option number. */
+#define COAP_OPT_MAX_AGE 14 /**< Max-Age option number. */
+#define COAP_OPT_URI_QUERY 15 /**< URI-Query option number. */
+#define COAP_OPT_ACCEPT 17 /**< Accept option number. */
+#define COAP_OPT_LOCATION_QUERY 20 /**< Location-Query option number. */
+#define COAP_OPT_BLOCK2 23 /**< Block2 option number. */
+#define COAP_OPT_BLOCK1 27 /**< Block1 option number. */
+#define COAP_OPT_SIZE2 28 /**< Size2 option number. */
+#define COAP_OPT_PROXY_URI 35 /**< Proxy-URI option number. */
+#define COAP_OPT_PROXY_SCHEME 39 /**< Proxy-Scheme option number. */
+#define COAP_OPT_SIZE1 60 /**< Size1 option number. */
+#define COAP_OPT_RESERVED1 128 /**< Reserved option number. */
+#define COAP_OPT_RESERVED2 132 /**< Reserved option number. */
+#define COAP_OPT_RESERVED3 136 /**< Reserved option number. */
+#define COAP_OPT_RESERVED4 140 /**< Reserved option number. */
+
+
+/**@brief Enumeration of CoAP message types. */
+typedef enum
+{
+ COAP_TYPE_CON = 0, /**< Confirmable Message type. */
+ COAP_TYPE_NON, /**< Non-Confirmable Message type. */
+ COAP_TYPE_ACK, /**< Acknowledge Message type. */
+ COAP_TYPE_RST /**< Reset Message type. */
+} coap_msg_type_t;
+
+/**@brief Structure to hold a CoAP option.
+ */
+typedef struct
+{
+ uint16_t number; /**< Option number (including the extended delta value if any). */
+ uint16_t length; /**< Option length (including the extended length value in any). */
+ uint8_t * p_data; /**< Pointer to the memory where the data of the option is located. */
+} coap_option_t;
+
+
+
+/**@brief Structure to hold a CoAP message configuration.
+ *
+ * @details The structure is used when calling the \ref coap_message_new API function.
+ * All data supplied will be copied to the created message.
+ */
+typedef struct
+{
+ coap_response_callback_t response_callback; /**< Callback function to be called when a response matching the token is identified. */
+ uint8_t token[8]; /**< Message token. token_len must be set to indicate how many of the bytes should be used in the token. */
+ uint8_t token_len; /**< Token size in bytes. */
+ uint16_t id; /**< Message ID. If 0 is given, the library will replace this number with an autogenerated value. */
+ coap_msg_type_t type; /**< Message type: COAP_TYPE_CON, COAP_TYPE_NON, COAP_TYPE_ACK, or COAP_TYPE_RST. */
+ coap_msg_code_t code; /**< Message code (definitions found in coap_msg_code_t). */
+ coap_port_t port; /**< Transport layer variable to associate the message with an underlying Transport Layer socket descriptor. */
+} coap_message_conf_t;
+
+/**@brief Structure to hold a CoAP message header.
+ *
+ * @details This structure holds the 4-byte mandatory CoAP header. The structure uses bitfields
+ * to save memory footprint.
+ */
+typedef struct
+{
+ uint8_t version :2; /**< CoAP version number. The current specification RFC7252 mandates this to be version 1. The version number can be modified in sdk_config.h. */
+ uint8_t type :2; /**< Message type: COAP_TYPE_CON, COAP_TYPE_NON, COAP_TYPE_ACK, or COAP_TYPE_RST. */
+ uint8_t token_len :4; /**< Length of the message token. */
+ uint8_t code; /**< Message code (definitions found in @ref coap_msg_code_t). */
+ uint16_t id; /**< Message ID in little-endian format. Convertion to Network Byte Order will be handled by the library. */
+} coap_message_header_t;
+
+/**@brief Structure to hold a CoAP message.
+ *
+ * @details The CoAP message structure contains both internal and public members to
+ * serialize and deserialize data supplied from the application to a byte buffer sent
+ * over UDP. The message structure is used both in transmission and reception, which
+ * makes it easy to handle in an application. Updating the message should be done
+ * using the provided APIs, not by manually assigning new values to the members directly.
+ * Reading the members, on the other hand, is fine.
+ */
+struct coap_message_t
+{
+ coap_remote_t remote; /**< Public. Structure containing address information and port number to the remote. */
+ coap_remote_t local; /**< Public. Structure containing local destination address information and port number. */
+ coap_message_header_t header; /**< Public. Header structure containing the mandatory CoAP 4-byte header fields. */
+ uint8_t * p_payload; /**< Public. Pointer to the payload buffer in the message. */
+ uint16_t payload_len; /**< Public. Size of the payload in the message. */
+ uint8_t options_count; /**< Public. The number of options in the message. */
+ coap_option_t options[COAP_MAX_NUMBER_OF_OPTIONS]; /**< Public. Array options in the message. */
+ void * p_arg; /**< Public. Miscellaneous pointer to application provided data that is associated with the message. */
+
+ coap_response_callback_t response_callback; /**< Internal. Function callback set by the application to be called when a response to this message is received. Should be set by the application through a configuration parameter. */
+ uint8_t token[8]; /**< Internal. Array holding the variable-sized message token. Should be set by the application through a configuration parameter. */
+ coap_port_t port; /**< Internal. Transport layer variable to associate the message with an underlying Transport Layer socket descriptor. */
+ uint16_t options_len; /**< Internal. Length of the options including the mandatory header with extension bytes and option data. Accumulated every time a new options is added. */
+ uint16_t options_offset; /**< Internal. Index to where the next option or payload can be added in the message's data buffer */
+ uint16_t options_delta; /**< Internal. Current option number. Used to calculate the next option delta when adding new options to the message. */
+ uint8_t * p_data; /**< Internal. Data buffer for adding dynamically sized options and payload. */
+ uint16_t data_len; /**< Internal. Length of the provided data buffer for options and payload. */
+};
+
+
+/**@brief Structure to hold a CoAP endpoint resource.
+*/
+struct coap_resource_t
+{
+ uint8_t child_count; /**< Number of children in the linked list. */
+ uint16_t permission; /**< Bitmask to tell which methods are permitted on the resource. Bit values available can be seen in \ref COAP_METHOD_PERMISSION. */
+ coap_resource_t * p_sibling; /**< Sibling pointer to the next element in the list. */
+ coap_resource_t * p_front; /**< Pointer to the beginning of the linked list. */
+ coap_resource_t * p_tail; /**< Pointer to the last added child in the list. */
+ coap_method_callback_t callback; /**< Callback to the resource handler. */
+ uint32_t ct_support_mask; /**< Bitmask to tell which content types are supported by the resource. Bit values available can be seen in \ref COAP_CONTENT_TYPE_MASK. */
+ uint32_t max_age; /**< Max age of resource endpoint value. */
+ uint32_t expire_time; /**< Number of seconds until expire. */
+ char name[COAP_RESOURCE_MAX_NAME_LEN+1]; /**< Name of the resource. Must be zero terminated. */
+};
+
+/**@brief Initializes the CoAP module.
+ *
+ * @details Initializes the library module and resets internal queues and resource registrations.
+ *
+ * @param[in] token_rand_seed Random number seed to be used to generate the token numbers.
+ * @param[in] p_transport_params Pointer to transport parameters. Providing the list of ports
+ * to be used by CoAP.
+ *
+ * @retval NRF_SUCCESS If initialization succeeded.
+ */
+uint32_t coap_init(uint32_t token_rand_seed, coap_transport_init_t * p_transport_params);
+
+/**@brief Register error handler callback to the CoAP module.
+ *
+ * @param[in] error_callback Function to be called upon unknown messages and failure.
+ *
+ * @retval NRF_SUCCESS If registration was successful.
+ */
+uint32_t coap_error_handler_register(coap_error_callback_t error_callback);
+
+/**@brief Register request handler which should handle all incoming requests.
+ *
+ * @details Setting this request handler redirects all requests to the application provided
+ * callback routine. The callback handler might be cleared by NULL, making coap
+ * module handle the requests and do resource lookup in order to process the
+ * requests.
+ *
+ * @param[in] p_request_handler Function pointer to the provided request handler.
+ *
+ * @retval NRF_SUCCESS If registration was successful.
+ */
+uint32_t coap_request_handler_register(coap_request_handler_t p_request_handler);
+
+/**@brief Sends a CoAP message.
+ *
+ * @details Sends out a request using the underlying transport layer. Before sending, the
+ * \ref coap_message_t structure is serialized and added to an internal message queue
+ * in the library. The handle returned can be used to abort the message from being
+ * retransmitted at any time.
+ *
+ * @param[out] p_handle Handle to the message if CoAP CON/ACK messages has been used. Returned
+ * by reference.
+ * @param[in] p_message Message to be sent.
+ *
+ * @retval NRF_SUCCESS If the message was successfully encoded and scheduled for transmission.
+ */
+uint32_t coap_message_send(uint32_t * p_handle, coap_message_t * p_message);
+
+/**@brief Abort a CoAP message.
+ *
+ * @details Aborts an ongoing transmission. If the message has not yet been sent, it will be
+ * deleted from the message queue as well as stop any ongoing re-transmission of the
+ * message.
+ *
+ * @param[in] handle Handle of the message to abort.
+ *
+ * @retval NRF_SUCCESS If the message was successfully aborted and removed from the
+ * message queue.
+ * @retval NRF_ERROR_NOT_FOUND If the message with the given handle was not located in the
+ * message queue.
+ */
+uint32_t coap_message_abort(uint32_t handle);
+
+/**@brief Creates CoAP message, initializes, and allocates the needed memory.
+ *
+ * @details Creates a CoAP message. This is an intermediate representation of the message,
+ * because the message will be serialized by the library before it is transmitted. The structure
+ * is verbose to facilitate configuring the message. Options, payload, and
+ * remote address information can be added using API function calls.
+ *
+ * @param[inout] p_request Pointer to be filled by the allocated CoAP message structures.
+ * @param[in] p_config Configuration for the message to be created. Manual configuration
+ * can be performed after the message creation, except for the CLIENT port
+ * association.
+ *
+ * @retval NRF_SUCCESS If the request was successfully allocated and initialized.
+ * @retval NRF_ERROR_INVALID_PARAM If local port number was not configured.
+ */
+uint32_t coap_message_new(coap_message_t ** p_request, coap_message_conf_t * p_config);
+
+/**@brief Deletes the CoAP request message.
+ *
+ * @details Frees up memory associated with the request message.
+ *
+ * @param[in] p_message Pointer to the request message to delete.
+ */
+uint32_t coap_message_delete(coap_message_t * p_message);
+
+/**@brief Adds a payload to a CoAP message.
+ *
+ * @details Sets a data payload to a request or response message.
+ *
+ * This function must be called after all CoAP options have been added.
+ * Due to internal buffers in the library, the payload will be added after any options
+ * in the buffer. If an option is added after the payload, this option will over-write
+ * the payload in the internal buffer.
+ *
+ * @param[inout] p_message Pointer to the message to add the payload to.
+ * @param[in] p_payload Pointer to the payload to be added.
+ * @param[in] payload_len Size of the payload to be added.
+ *
+ * @retval NRF_SUCCESS If the payload was successfully added to the message.
+ * @retval NRF_ERROR_NO_MEM If the payload could not fit within the allocated payload memory
+ * defined by sdk_config.h COAP_MESSAGE_DATA_MAX_SIZE.
+ */
+uint32_t coap_message_payload_set(coap_message_t * p_message,
+ void * p_payload,
+ uint16_t payload_len);
+
+/**@brief Adds an empty CoAP option to the message.
+ *
+ * Option numbers must be in ascending order, adding the one with the smallest number
+ * first and greatest last. If the order is incorrect, the delta number calculation will
+ * result in an invalid or wrong delta number for the option.
+ *
+ * @param[inout] p_message Pointer to the message to add the option to. Should not be NULL.
+ * @param[in] option_num The option number to add to the message.
+ *
+ * @retval NRF_SUCCESS If the empty option was successfully added to the message.
+ * @retval NRF_ERROR_DATA_SIZE If the data exceeds the available message buffer data size.
+ * @retval NRF_ERROR_NO_MEM If the maximum number of options that can be added to a message has been reached.
+ */
+uint32_t coap_message_opt_empty_add(coap_message_t * p_message, uint16_t option_num);
+
+/**@brief Adds a uint CoAP option to the message.
+ *
+ * Option numbers must be in ascending order, adding the one with the smallest number
+ * first and greatest last. If the order is incorrect, the delta number calculation will
+ * result in an invalid or wrong delta number for the option.
+ *
+ * @param[inout] p_message Pointer to the message to add the option to. Should not be NULL.
+ * @param[in] option_num The option number to add to the message.
+ * @param[in] data An unsigned value (8-bit, 16-bit, or 32-bit) casted to uint32_t.
+ * The value of the data is used to determine how many bytes
+ * CoAP must use to represent this option value.
+ *
+ * @retval NRF_SUCCESS If the unsigned integer option was successfully added to the message.
+ * @retval NRF_ERROR_DATA_SIZE If the data exceeds the available message buffer data size.
+ * @retval NRF_ERROR_NO_MEM If the maximum number of options that can be added to a message has been reached.
+ */
+uint32_t coap_message_opt_uint_add(coap_message_t * p_message, uint16_t option_num, uint32_t data);
+
+/**@brief Adds a string CoAP option to the message.
+ *
+ * Option numbers must be in ascending order, adding the one with the smallest number
+ * first and greatest last. If the order is incorrect, the delta number calculation will
+ * result in an invalid or wrong delta number for the option.
+ *
+ * @param[inout] p_message Pointer to the message to add the option to. Should not be NULL.
+ * @param[in] option_num The option number to add to the message.
+ * @param[in] p_data Pointer to a string buffer to be used as value for the option.
+ * Should not be NULL.
+ * @param[in] length Length of the string buffer provided.
+ *
+ * @retval NRF_SUCCESS If the string option was successfully added to the message.
+ * @retval NRF_ERROR_DATA_SIZE If the data exceeds the available message buffer data size.
+ * @retval NRF_ERROR_NO_MEM If the maximum number of options that can be added to a message has been reached.
+ */
+uint32_t coap_message_opt_str_add(coap_message_t * p_message, uint16_t option_num, uint8_t * p_data, uint16_t length);
+
+/**@brief Adds an opaque CoAP option to the message.
+ *
+ * Option numbers must be in ascending order, adding the one with the smallest number
+ * first and greatest last. If the order is incorrect, the delta number calculation will
+ * result in an invalid or wrong delta number for the option.
+ *
+ * @param[inout] p_message Pointer to the message to add the option to. Should not be NULL.
+ * @param[in] option_num The option number to add to the message.
+ * @param[in] p_data Pointer to an opaque buffer to be used as value for the option.
+ * Should not be NULL.
+ * @param[in] length Length of the opaque buffer provided.
+ *
+ * @retval NRF_SUCCESS If the opaque option was successfully added to the message.
+ * @retval NRF_ERROR_DATA_SIZE If the data exceeds the available message buffer data size.
+ * @retval NRF_ERROR_NO_MEM If the maximum number of options that can be added to a message has been reached.
+ */
+uint32_t coap_message_opt_opaque_add(coap_message_t * p_message, uint16_t option_num, uint8_t * p_data, uint16_t length);
+
+/**@brief Sets a remote address and port number to a CoAP message.
+ *
+ * @details Copies the content of the provided pointer into the CoAP message.
+ *
+ * @param[inout] p_message Pointer to the message to add the address information to.
+ * Should not be NULL.
+ * @param[in] p_address Pointer to a structure holding the address information for the remote server or client.
+ * Should not be NULL.
+ *
+ * @retval NRF_SUCCESS When copying the content has finished.
+ */
+uint32_t coap_message_remote_addr_set(coap_message_t * p_message, coap_remote_t * p_address);
+
+/**@brief Creates a CoAP endpoint resource.
+ *
+ * @details Initializes the \ref coap_resource_t members.
+ *
+ * The first resource that is created will be set as the root of the resource
+ * hierarchy.
+ *
+ * @param[in] p_resource Pointer to coap_resource_t passed in by reference.
+ * This variable must be stored in non-volatile memory.
+ * Should not be NULL.
+ * @param[in] name Verbose name of the service (zero-terminated
+ * string). The maximum length of a name is defined
+ * by COAP_RESOURCE_MAX_NAME_LEN in @c sdk_config.h
+ * and can be adjusted if needed. Should not be NULL.
+ * @retval NRF_ERROR_DATA_SIZE If the provided name is larger than the available name buffer.
+ * @retval NRF_ERROR_NULL If the pointer to the resource or the provided
+ * name buffer is NULL.
+ */
+uint32_t coap_resource_create(coap_resource_t * p_resource, const char * name);
+
+/**@brief Adds a child resource.
+ *
+ * @details The hierarchy is constructed as a linked list with a maximum number of children.
+ * COAP_RESOURCE_MAX_DEPTH in @c sdk_config.h sets the maximum depth. The maximum
+ * number of children can be adjusted if more levels are needed.
+ *
+ * @param[in] p_parent Resource to attach the child to. Should not be NULL.
+ * @param[in] p_child Child resource to attach. Should not be NULL.
+ *
+ * @retval NRF_SUCCESS If the child was successfully added.
+ * @retval COAP_ERROR_MAX_DEPTH_REACHED If the child is exceeding the maximum depth defined.
+ */
+uint32_t coap_resource_child_add(coap_resource_t * p_parent, coap_resource_t * p_child);
+
+/**@brief Generates .well-known/core string.
+ *
+ * @details This is a helper function for generating a CoRE link-format encoded string used for
+ * CoAP discovery. The function traverse the resource hierarchy recursively.
+ * The result will be resources listed in link-format. This function can be called when
+ * all resources have been added by the application.
+ *
+ * @param[inout] string Buffer to use for the .well-known/core string. Should not be NULL.
+ * @param[inout] length Length of the string buffer. Returns the used number of bytes from
+ * the provided buffer.
+ *
+ * @retval NRF_SUCCESS If string generation was successful.
+ * @retval NRF_ERROR_NULL If the string buffer was a NULL pointer.
+ * @retval NRF_ERROR_DATA_SIZE If the size of the generated string exceeds the given buffer size.
+ * @retval NRF_ERROR_INVALID_STATE If no resource has been registered.
+ */
+uint32_t coap_resource_well_known_generate(uint8_t * string, uint16_t * length);
+
+/**@brief Get the root resource pointer.
+ *
+ * @param[out] pp_resource Pointer to be filled with pointer to the root resource.
+ *
+ * @retval NRF_SUCCESS If root resource was located.
+ * @retval NRF_ERROR_NOT_FOUND If root resource was not located.
+ * @retval NRF_ERROR_NULL If output pointer was NULL.
+ */
+uint32_t coap_resource_root_get(coap_resource_t ** pp_resource);
+
+/**@brief Check whether a message contains a given CoAP Option.
+ *
+ * @param[in] p_message Pointer to the to check for the CoAP Option.
+ * Should not be NULL.
+ * @param[in] option CoAP Option to check for in the CoAP message.
+ *
+ * @retval NRF_SUCCESS If the CoAP Option is present in the message.
+ * @retval NRF_ERROR_NULL If the pointer to the message is NULL.
+ * @retval NRF_ERROR_NOT_FOUND If the CoAP Option is not present in the message.
+ */
+uint32_t coap_message_opt_present(coap_message_t * p_message, uint16_t option);
+
+/**@brief Check whether a message contains a given CoAP Option and return the index of the entry
+ * in the message option list.
+ *
+ * @param[in] p_index Value by reference to fill the resolved index into. Should not be NULL.
+ * @param[in] p_message Pointer to the to check for the CoAP Option.
+ * Should not be NULL.
+ * @param[in] option CoAP Option to check for in the CoAP message.
+ *
+ * @retval NRF_SUCCESS If the CoAP Option is present in the message.
+ * @retval NRF_ERROR_NULL If the pointer to the message or the p_index is NULL.
+ * @retval NRF_ERROR_NOT_FOUND If the CoAP Option is not present in the message.
+ */
+uint32_t coap_message_opt_index_get(uint8_t * p_index, coap_message_t * p_message, uint16_t option);
+
+/**@brief Find common content type between the CoAP message and the resource.
+ *
+ * @details The return value will be the first match between the ACCEPT options and the supported
+ * content types in the resource. The priority is by content-format ID starting going
+ * from the lowest value to the highest.
+ *
+ * @param[out] p_ct Resolved content type given by reference. Should not be NULL.
+ * @param[in] p_message Pointer to the message. Should not be NULL.
+ * @param[in] p_resource Pointer to the resource. Should not be NULL.
+ *
+ * @retval NRF_SUCCESS If match was found.
+ * @retval NRF_ERROR_NOT_FOUND If no match was found.
+ */
+uint32_t coap_message_ct_match_select(coap_content_type_t * p_ct, coap_message_t * p_message, coap_resource_t * p_resource);
+
+/**@brief CoAP time tick used for retransmitting any message in the queue if needed.
+ *
+ * @retval NRF_SUCCESS If time tick update was successfully handled.
+ */
+uint32_t coap_time_tick(void);
+
+#if (COAP_DISABLE_DTLS_API == 0)
+/**@brief Setup secure DTLS session.
+ *
+ * @details For the client role, this API triggers a DTLS handshake. Until the handshake is complete
+ * with the remote, \ref coap_message_send will fail.
+ * For the server role, this API does not create any DTLS session. A DTLS session is
+ * created each time a new client remote endpoint sends a request on the local port of the
+ * server.
+ *
+ * @note The success of this function does not imply that the DTLS handshake is successfull.
+ *
+ * @note Only one DTLS session is permitted between a local and remote endpoint. Therefore, in case
+ * a DTLS session was established between the local and remote endpoint, the existing DTLS
+ * session will be reused irrespective of the role and number of times this API was called.
+ * In case the application desires a fresh security setup, it must first call the
+ * \ref coap_security_destroy to tear down the existing setup.
+ *
+ * @param[in] local_port Local port to bind the session to.
+ * @param[in] role Role of the session. DTLS server or client defined in the enumeration
+ * \ref nrf_tls_role_t.
+ * @param[in] p_remote Pointer to a structure holding the address information for the remote
+ * endpoint. If a the device is acting as a server, a NULL pointer shall be
+ * given as a parameter. Rationale: The server is not envisioned to be
+ * bound a pre-known client endpoint. Therefore, security server settings
+ * shall be setup irrespective of the remote client.
+ * @param[in] p_settings Pointer to a structure holding the DTLS credentials.
+ *
+ * @retval NRF_SUCCESS If setup of the secure DTLS session was successfull.
+ */
+uint32_t coap_security_setup(uint16_t local_port,
+ nrf_tls_role_t role,
+ coap_remote_t * const p_remote,
+ nrf_tls_key_settings_t * const p_settings);
+
+
+/**@brief Destroy a secure DTLS session.
+ *
+ * @details Terminate and clean up any session associated with the local port and the remote.
+ *
+ * @param[in] local_port Local port to unbind the session from.
+ * @param[in] p_remote Pointer to a structure holding the address information for the remote
+ * endpoint. Providing a NULL as p_remote will clean up all DTLS sessions
+ * associated with the local port.
+ *
+ * @retval NRF_SUCCESS If the destruction of the secure DTLS session was successfull.
+ */
+uint32_t coap_security_destroy(uint16_t local_port,
+ coap_remote_t * const p_remote);
+
+#endif // COAP_DISABLE_DTLS_API
+
+/**@brief Process loop when using coap BSD socket transport implementation.
+ *
+ * @details This is blocking call. The function unblock is only
+ * triggered upon an socket event registered to select() by coap transport.
+ * This function must be called as often as possible in order to dispatch incoming
+ * socket events. Preferred to be put in the application's main loop or similar.
+ **/
+void coap_input(void);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // COAP_API_H__
+
+/** @} */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/coap/coap_block.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/coap/coap_block.c
new file mode 100644
index 0000000..f915f54
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/coap/coap_block.c
@@ -0,0 +1,203 @@
+/**
+ * Copyright (c) 2015 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#include <stdbool.h>
+#include <stddef.h>
+
+#include "coap_block.h"
+#include "nrf_error.h"
+#include "iot_errors.h"
+#include "sdk_config.h"
+
+
+/**
+ * @defgroup api_param_check API Parameters check macros.
+ *
+ * @details Macros that verify parameters passed to the module in the APIs. These macros
+ * could be mapped to nothing in final versions of code to save execution and size.
+ * COAP_DISABLE_API_PARAM_CHECK should be defined to disable these checks.
+ *
+ * @{
+ */
+#if (COAP_DISABLE_API_PARAM_CHECK == 0)
+
+/**@brief Verify NULL parameters are not passed to API by application. */
+#define NULL_PARAM_CHECK(PARAM) \
+ if ((PARAM) == NULL) \
+ { \
+ return (NRF_ERROR_NULL | IOT_COAP_ERR_BASE); \
+ }
+#else // COAP_DISABLE_API_PARAM_CHECK
+
+#define NULL_PARAM_CHECK(PARAM)
+
+#endif // COAP_DISABLE_API_PARAM_CHECK
+/** @} */
+
+
+#define BLOCK_SIZE_BASE_CONSTANT 4 /**< Block size base exponent. 4 means a base block size of 2^4 = 16 bytes. */
+
+#define BLOCK_SIZE_16 0 /**< Block size of 2^(4+0) = 16 bytes. */
+#define BLOCK_SIZE_32 1 /**< Block size of 2^(4+1) = 32 bytes. */
+#define BLOCK_SIZE_64 2 /**< Block size of 2^(4+2) = 64 bytes. */
+#define BLOCK_SIZE_128 3 /**< Block size of 2^(4+3) = 128 bytes. */
+#define BLOCK_SIZE_256 4 /**< Block size of 2^(4+4) = 256 bytes. */
+#define BLOCK_SIZE_512 5 /**< Block size of 2^(4+5) = 512 bytes. */
+#define BLOCK_SIZE_1024 6 /**< Block size of 2^(4+6) = 1024 bytes. */
+#define BLOCK_SIZE_2048_RESERVED 7 /**< Reserved. */
+
+#define BLOCK_MORE_BIT_UNSET 0 /**< Value when more flag is set. */
+#define BLOCK_MORE_BIT_SET 1 /**< Value when more flag is not set. */
+
+#define BLOCK_SIZE_POS 0 /**< Bit offset to the size. */
+#define BLOCK_MORE_BIT_POS 3 /**< Bit offset to the more bit. */
+#define BLOCK_NUMBER_POS 4 /**< Bit offset to the block number. */
+
+#define BLOCK_SIZE_MASK 0x7 /**< Block size mask. */
+#define BLOCK_MORE_BIT_MASK (1 << BLOCK_MORE_BIT_POS) /**< More bit mask. */
+#define BLOCK_NUMBER_MASK (0xFFFFF << 4) /**< Block number mask. */
+
+#define BLOCK_SIZE_MAX 0x7 /**< Maximum block size number. */
+#define BLOCK_MORE_BIT_MAX BLOCK_MORE_BIT_SET /**< Maximum more bit value. */
+#define BLOCK_NUMBER_MAX 0xFFFFF /**< Maximum block number. 20 bits max value is (1 << 20) - 1. */
+
+static uint32_t block_opt_encode(uint8_t more,
+ uint16_t size,
+ uint32_t number,
+ uint32_t * p_encoded)
+{
+ if ((number > BLOCK_NUMBER_MAX) || (more > BLOCK_MORE_BIT_MAX))
+ {
+ return (NRF_ERROR_INVALID_PARAM | IOT_COAP_ERR_BASE);
+ }
+
+ uint32_t val = 0;
+
+ switch (size)
+ {
+ case 16:
+ val = BLOCK_SIZE_16;
+ break;
+
+ case 32:
+ val = BLOCK_SIZE_32;
+ break;
+
+ case 64:
+ val = BLOCK_SIZE_64;
+ break;
+
+ case 128:
+ val = BLOCK_SIZE_128;
+ break;
+
+ case 256:
+ val = BLOCK_SIZE_256;
+ break;
+
+ case 512:
+ val = BLOCK_SIZE_512;
+ break;
+
+ case 1024:
+ val = BLOCK_SIZE_1024;
+ break;
+
+ case 2048:
+ // Falltrough.
+ default:
+ // Break omitted.
+ return (NRF_ERROR_INVALID_PARAM | IOT_COAP_ERR_BASE);
+ }
+
+ // Value has been initialized.
+ val |= (more) << BLOCK_MORE_BIT_POS;
+ val |= (number) << BLOCK_NUMBER_POS;
+
+ *p_encoded = val;
+ return NRF_SUCCESS;
+}
+
+static uint32_t block_opt_decode(uint32_t encoded,
+ uint8_t * p_more,
+ uint16_t * p_size,
+ uint32_t * p_number)
+{
+ if ((encoded & BLOCK_SIZE_MASK) == BLOCK_SIZE_2048_RESERVED)
+ {
+ return (NRF_ERROR_INVALID_DATA | IOT_COAP_ERR_BASE);
+ }
+
+ if ((encoded >> BLOCK_NUMBER_POS) > BLOCK_NUMBER_MAX)
+ {
+ return (NRF_ERROR_INVALID_PARAM | IOT_COAP_ERR_BASE);
+ }
+
+ *p_size = (1 << ((BLOCK_SIZE_BASE_CONSTANT + (encoded & BLOCK_SIZE_MASK))));
+ *p_more = (encoded & BLOCK_MORE_BIT_MASK) >> BLOCK_MORE_BIT_POS;
+ *p_number = (encoded & BLOCK_NUMBER_MASK) >> BLOCK_NUMBER_POS;
+
+ return NRF_SUCCESS;
+}
+
+uint32_t coap_block_opt_block1_encode(uint32_t * p_encoded, coap_block_opt_block1_t * p_opt)
+{
+ NULL_PARAM_CHECK(p_encoded);
+ NULL_PARAM_CHECK(p_opt);
+ return block_opt_encode(p_opt->more, p_opt->size, p_opt->number, p_encoded);
+}
+
+uint32_t coap_block_opt_block1_decode(coap_block_opt_block1_t * p_opt, uint32_t encoded)
+{
+ NULL_PARAM_CHECK(p_opt);
+ return block_opt_decode(encoded, &p_opt->more, &p_opt->size, &p_opt->number);
+}
+
+uint32_t coap_block_opt_block2_encode(uint32_t * p_encoded, coap_block_opt_block2_t * p_opt)
+{
+ NULL_PARAM_CHECK(p_encoded);
+ NULL_PARAM_CHECK(p_opt);
+ return block_opt_encode(p_opt->more, p_opt->size, p_opt->number, p_encoded);
+}
+
+uint32_t coap_block_opt_block2_decode(coap_block_opt_block2_t * p_opt, uint32_t encoded)
+{
+ NULL_PARAM_CHECK(p_opt);
+ return block_opt_decode(encoded, &p_opt->more, &p_opt->size, &p_opt->number);
+}
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/coap/coap_block.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/coap/coap_block.h
new file mode 100644
index 0000000..fa2e9ee
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/coap/coap_block.h
@@ -0,0 +1,126 @@
+/**
+ * Copyright (c) 2015 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 coap_block.h
+ *
+ * @defgroup iot_sdk_coap_block CoAP Block transfer
+ * @ingroup iot_sdk_coap
+ * @{
+ * @brief CoAP block transfer options encoding and decoding interface and definitions.
+ *
+ */
+
+#ifndef COAP_BLOCK_H__
+#define COAP_BLOCK_H__
+
+#include <stdint.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define COAP_BLOCK_OPT_BLOCK_MORE_BIT_UNSET 0 /**< Value when more flag is set. */
+#define COAP_BLOCK_OPT_BLOCK_MORE_BIT_SET 1 /**< Value when more flag is not set. */
+
+typedef struct
+{
+ uint8_t more; /**< More bit value. */
+ uint16_t size; /**< Size of the block in bytes. */
+ uint32_t number; /**< Block number. */
+} coap_block_opt_block1_t;
+
+typedef coap_block_opt_block1_t coap_block_opt_block2_t;
+
+/**@brief Encode block1 option into its uint binary counter part.
+ *
+ * @param[out] p_encoded Encoded version of the coap block1 option value. Must not be NULL.
+ * @param[in] p_opt Pointer to block1 option structure to be decoded into uint format. Must
+ * not be NULL.
+ *
+ * @retval NRF_SUCCESS If encoding of option was successful.
+ * @retval NRF_ERROR_NULL If one of the parameters supplied is a null pointer.
+ * @retval NRF_ERROR_INVALID_PARAM If one of the fields in the option structure has an illegal
+ * value.
+ */
+uint32_t coap_block_opt_block1_encode(uint32_t * p_encoded, coap_block_opt_block1_t * p_opt);
+
+/**@brief Decode block1 option from a uint to its structure counter part.
+ *
+ * @param[out] p_opt Pointer to block1 option structure to be filled by the function. Must not
+ * be NULL.
+ * @param[in] encoded Encoded version of the coap block1 option value.
+ *
+ * @retval NRF_SUCCESS If decoding of the option was successful.
+ * @retval NRF_ERROR_NULL If p_opt parameter is NULL.
+ * @retval NRF_ERROR_INVALID_PARAM If the block number is higher then allowed by spec (more than
+ 20 bits).
+ * @retval NRF_ERROR_INVALID_DATA If the size has the value of the reserved 2048 value (7).
+ */
+uint32_t coap_block_opt_block1_decode(coap_block_opt_block1_t * p_opt, uint32_t encoded);
+
+/**@brief Encode block2 option into its uint binary counter part.
+ *
+ * @param[out] p_encoded Encoded version of the coap block2 option value. Must not be NULL.
+ * @param[in] p_opt Pointer to block2 option structure to be decoded into uint format. Must
+ * not be NULL.
+ *
+ * @retval NRF_SUCCESS If encoding of option was successful.
+ * @retval NRF_ERROR_NULL If one of the parameters supplied is a null pointer.
+ * @retval NRF_ERROR_INVALID_PARAM If one of the fields in the option structure has an illegal
+ * value.
+ */
+uint32_t coap_block_opt_block2_encode(uint32_t * p_encoded, coap_block_opt_block2_t * p_opt);
+
+/**@brief Decode block2 option from a uint to its structure counter part.
+ *
+ * @param[out] p_opt Pointer to block2 option structure to be filled by the function. Must not
+ * be NULL.
+ * @param[in] encoded Encoded version of the coap block2 option value.
+ *
+ * @retval NRF_SUCCESS If decoding of the option was successful.
+ * @retval NRF_ERROR_NULL If p_opt parameter is NULL.
+ * @retval NRF_ERROR_INVALID_PARAM If the block number is higher then allowed by spec (more than
+ 20 bits).
+ * @retval NRF_ERROR_INVALID_DATA If the size has the value of the reserved 2048 value (7).
+ */
+uint32_t coap_block_opt_block2_decode(coap_block_opt_block2_t * p_opt, uint32_t encoded);
+
+#endif // COAP_BLOCK_H__
+
+/** @} */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/coap/coap_codes.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/coap/coap_codes.h
new file mode 100644
index 0000000..88b1d48
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/coap/coap_codes.h
@@ -0,0 +1,115 @@
+/**
+ * Copyright (c) 2014 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 coap_codes.h
+ *
+ * @defgroup iot_sdk_coap_codes CoAP Codes
+ * @ingroup iot_sdk_coap
+ * @{
+ * @brief CoAP message and response codes.
+ */
+
+#ifndef COAP_CODES_H__
+#define COAP_CODES_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define COAP_CODE(c, dd) \
+ ((((c) & 0x7) << 5) | (((1 ## dd) - 100) & 0x1F))
+/**
+ @note macro adds 1xx to the number in order to prevent dd from being
+ interpreted as octal.
+*/
+
+/*lint -save -e122 */ /* Suppress "Digit (8) too large for radix" */
+
+/** @brief CoAP Message codes
+*/
+typedef enum
+{
+ // CoAP Empty Message
+ COAP_CODE_EMPTY_MESSAGE = COAP_CODE(0,00), /**< CoAP code 0.00, Decimal: 0, Hex: 0x00. */
+
+ // CoAP Method Codes
+ COAP_CODE_GET = COAP_CODE(0,01), /**< CoAP code 0.01, Decimal: 1, Hex: 0x01. */
+ COAP_CODE_POST = COAP_CODE(0,02), /**< CoAP code 0.02, Decimal: 2, Hex: 0x02. */
+ COAP_CODE_PUT = COAP_CODE(0,03), /**< CoAP code 0.03, Decimal: 3, Hex: 0x03. */
+ COAP_CODE_DELETE = COAP_CODE(0,04), /**< CoAP code 0.04, Decimal: 4, Hex: 0x04. */
+
+ // CoAP Success Response Codes
+ COAP_CODE_201_CREATED = COAP_CODE(2,01), /**< CoAP code 2.01, Decimal: 65, Hex: 0x41. */
+ COAP_CODE_202_DELETED = COAP_CODE(2,02), /**< CoAP code 2.02, Decimal: 66, Hex: 0x42. */
+ COAP_CODE_203_VALID = COAP_CODE(2,03), /**< CoAP code 2.03, Decimal: 67, Hex: 0x43. */
+ COAP_CODE_204_CHANGED = COAP_CODE(2,04), /**< CoAP code 2.04, Decimal: 68, Hex: 0x44. */
+ COAP_CODE_205_CONTENT = COAP_CODE(2,05), /**< CoAP code 2.05, Decimal: 69, Hex: 0x45. */
+ COAP_CODE_231_CONTINUE = COAP_CODE(2,31), /**< CoAP code 2.31, Decimal: 95, Hex: 0x5F. */
+
+ // CoAP Client Error Response Codes
+ COAP_CODE_400_BAD_REQUEST = COAP_CODE(4,00), /**< CoAP code 4.00, Decimal: 128, Hex: 0x80. */
+ COAP_CODE_401_UNAUTHORIZED = COAP_CODE(4,01), /**< CoAP code 4.01, Decimal: 129, Hex: 0x81. */
+ COAP_CODE_402_BAD_OPTION = COAP_CODE(4,02), /**< CoAP code 4.02, Decimal: 130, Hex: 0x82. */
+ COAP_CODE_403_FORBIDDEN = COAP_CODE(4,03), /**< CoAP code 4.03, Decimal: 131, Hex: 0x83. */
+ COAP_CODE_404_NOT_FOUND = COAP_CODE(4,04), /**< CoAP code 4.04, Decimal: 132, Hex: 0x84. */
+ COAP_CODE_405_METHOD_NOT_ALLOWED = COAP_CODE(4,05), /**< CoAP code 4.05, Decimal: 133, Hex: 0x85. */
+ COAP_CODE_406_NOT_ACCEPTABLE = COAP_CODE(4,06), /**< CoAP code 4.06, Decimal: 134, Hex: 0x86. */
+ COAP_CODE_408_REQUEST_ENTITY_INCOMPLETE = COAP_CODE(4,08), /**< CoAP code 4.08, Decimal: 136, Hex: 0x88. */
+ COAP_CODE_412_PRECONDITION_FAILED = COAP_CODE(4,12), /**< CoAP code 4.12, Decimal: 140, Hex: 0x8C. */
+ COAP_CODE_413_REQUEST_ENTITY_TOO_LARGE = COAP_CODE(4,13), /**< CoAP code 4.13, Decimal: 141, Hex: 0x8D. */
+ COAP_CODE_415_UNSUPPORTED_CONTENT_FORMAT = COAP_CODE(4,15), /**< CoAP code 4.15, Decimal: 143, Hex: 0x8F. */
+
+ // CoAP Server Error Response Codes
+ COAP_CODE_500_INTERNAL_SERVER_ERROR = COAP_CODE(5,00), /**< CoAP code 5.00, Decimal: 160, Hex: 0xA0. */
+ COAP_CODE_501_NOT_IMPLEMENTED = COAP_CODE(5,01), /**< CoAP code 5.01, Decimal: 161, Hex: 0xA1. */
+ COAP_CODE_502_BAD_GATEWAY = COAP_CODE(5,02), /**< CoAP code 5.02, Decimal: 162, Hex: 0xA2. */
+ COAP_CODE_503_SERVICE_UNAVAILABLE = COAP_CODE(5,03), /**< CoAP code 5.03, Decimal: 163, Hex: 0xA3. */
+ COAP_CODE_504_GATEWAY_TIMEOUT = COAP_CODE(5,04), /**< CoAP code 5.04, Decimal: 164, Hex: 0xA4. */
+ COAP_CODE_505_PROXYING_NOT_SUPPORTED = COAP_CODE(5,05) /**< CoAP code 5.05, Decimal: 165, Hex: 0xA5. */
+} coap_msg_code_t;
+
+/*lint -restore */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // COAP_CODES_H__
+
+/** @} */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/coap/coap_message.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/coap/coap_message.c
new file mode 100644
index 0000000..db0f7bf
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/coap/coap_message.c
@@ -0,0 +1,804 @@
+/**
+ * Copyright (c) 2014 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#include <stdlib.h>
+#include <string.h>
+
+#include "nordic_common.h"
+#include "coap_message.h"
+#include "coap_api.h"
+#include "iot_common.h"
+#include "sdk_config.h"
+#include "app_util.h"
+
+#define COAP_PAYLOAD_MARKER_SIZE 1
+
+/**@brief Verify that there is a index available for a new option. */
+#define OPTION_INDEX_AVAIL_CHECK(COUNT) \
+ if ((COUNT) >= COAP_MAX_NUMBER_OF_OPTIONS) \
+ { \
+ return (NRF_ERROR_NO_MEM | IOT_COAP_ERR_BASE); \
+ }
+
+#if (COAP_DISABLE_API_PARAM_CHECK == 0)
+
+/**@brief Verify NULL parameters are not passed to API by application. */
+#define NULL_PARAM_CHECK(PARAM) \
+ if ((PARAM) == NULL) \
+ { \
+ return (NRF_ERROR_NULL | IOT_COAP_ERR_BASE); \
+ }
+#else
+
+#define NULL_PARAM_CHECK(PARAM)
+#define OPTION_INDEX_AVAIL_CHECK(COUNT)
+
+#endif // COAP_DISABLE_API_PARAM_CHECK
+
+uint32_t coap_message_create(coap_message_t * p_message, coap_message_conf_t * p_init_config)
+{
+ NULL_PARAM_CHECK(p_message);
+ NULL_PARAM_CHECK(p_init_config);
+
+ // Setting default value for version.
+ p_message->header.version = COAP_VERSION;
+
+ // Copy values from the init config.
+ p_message->header.type = p_init_config->type;
+ p_message->header.token_len = p_init_config->token_len;
+ p_message->header.code = p_init_config->code;
+ p_message->header.id = p_init_config->id;
+ p_message->response_callback = p_init_config->response_callback;
+ p_message->p_arg = NULL;
+
+ if (p_init_config->port.port_number == 0)
+ {
+ return (NRF_ERROR_INVALID_PARAM | IOT_COAP_ERR_BASE);
+ }
+ memcpy(&p_message->port, &p_init_config->port, sizeof(coap_port_t));
+
+ memcpy(p_message->token, p_init_config->token, sizeof(p_init_config->token));
+ return NRF_SUCCESS;
+}
+
+/**@brief Decode CoAP option
+ *
+ * @param[in] p_raw_option Pointer to the memory buffer where the raw option is located.
+ * @param[inout] p_message Pointer to the current message. Used to retrieve information about
+ * where current option delta and the size of free memory to add the
+ * values of the option. Used as a container where to put
+ * the parsed option.
+ * @param[out] byte_count Number of bytes parsed. Used to indicate where the next option
+ * might be located (if any left) in the raw message buffer.
+ *
+ * @retval NRF_SUCCESS If the option parsing went successful.
+ * @retval NRF_ERROR_DATA_SIZE If there is no more space left in the free memory to add the
+ * option value to the p_message.
+ */
+static uint32_t decode_option(const uint8_t * p_raw_option, coap_message_t * p_message, uint16_t * byte_count)
+{
+ uint16_t byte_index = 0;
+ uint8_t option_num = p_message->options_count;
+
+ // Calculate the option number.
+ uint16_t option_delta = (p_raw_option[byte_index] & 0xF0) >> 4;
+ // Calculate the option length.
+ uint16_t option_length = (p_raw_option[byte_index] & 0x0F);
+ byte_index++;
+
+ uint16_t acc_option_delta = p_message->options_delta;
+
+ if (option_delta == 13)
+ {
+ // read one additional byte to get the extended delta.
+ acc_option_delta += 13 + p_raw_option[byte_index++];
+
+ }
+ else if (option_delta == 14)
+ {
+ // read one additional byte to get the extended delta.
+ acc_option_delta += 269;
+ acc_option_delta += (p_raw_option[byte_index++] << 8);
+ acc_option_delta += (p_raw_option[byte_index++]);
+ }
+ else
+ {
+ acc_option_delta += option_delta;
+ }
+
+ // Set the accumlated delta as the option number.
+ p_message->options[option_num].number = acc_option_delta;
+
+ if (option_length == 13)
+ {
+ option_length = 13 + p_raw_option[byte_index++];
+ }
+ else if (option_length == 14)
+ {
+ option_length = 269;
+ option_length += (p_raw_option[byte_index++] << 8);
+ option_length += p_raw_option[byte_index++];
+ }
+
+ // Set the option length including extended bytes.
+ p_message->options[option_num].length = option_length;
+
+ // Point p_data to the memory where to find the option value.
+ p_message->options[option_num].p_data = (uint8_t *)&p_raw_option[byte_index];
+
+ // Update the delta counter with latest option number.
+ p_message->options_delta = p_message->options[option_num].number;
+
+ byte_index += p_message->options[option_num].length;
+ *byte_count = byte_index;
+
+ return NRF_SUCCESS;
+}
+
+
+/**@brief Encode CoAP option delta and length bytes.
+ *
+ * @param[inout] encoded_value Value to encode. In return the value after encoding.
+ * @param[out] encoded_value_ext The value of the encoded extended bytes.
+ *
+ * @return The size of the extended byte field.
+ */
+static inline uint8_t encode_extended_bytes(uint16_t * value,
+ uint16_t * value_ext)
+{
+ uint16_t raw_value = *value;
+
+ uint8_t ext_size = 0;
+
+ if (raw_value >= 269)
+ {
+ *value = 14;
+ *value_ext = raw_value - 269;
+ ext_size = 2;
+ }
+ else if (raw_value >= 13)
+ {
+ *value = 13;
+ *value_ext = raw_value - 13;
+ ext_size = 1;
+ }
+ else
+ {
+ *value = raw_value;
+ *value_ext = 0;
+ }
+
+ return ext_size;
+}
+
+
+static uint32_t encode_option(uint8_t * p_buffer, coap_option_t * p_option, uint16_t * byte_count)
+{
+ uint16_t delta_ext = 0;
+ uint16_t delta = p_option->number;
+
+ uint8_t delta_ext_size = encode_extended_bytes(&delta,
+ &delta_ext);
+
+ uint16_t length = p_option->length;
+ uint16_t length_ext = 0;
+
+ uint8_t length_ext_size = encode_extended_bytes(&length,
+ &length_ext);
+
+ if (p_buffer == NULL)
+ {
+ uint16_t header_size = 1;
+ *byte_count = header_size + delta_ext_size + length_ext_size + p_option->length;
+ return NRF_SUCCESS;
+ }
+
+ uint16_t byte_index = 0;
+
+ // Add the option header.
+ p_buffer[byte_index++] = ((delta & 0x0F) << 4) | (length & 0x0F);
+
+ // Add option delta extended bytes to the buffer.
+ if (delta_ext_size == 1)
+ {
+ // Add first byte of delta_ext to the option header.
+ p_buffer[byte_index++] = (uint8_t)delta_ext;
+ }
+ else if (delta_ext_size == 2)
+ {
+ // uint16 in Network Byte Order.
+ p_buffer[byte_index++] = (uint8_t)((delta_ext & 0xFF00) >> 8);
+ p_buffer[byte_index++] = (uint8_t)((delta_ext & 0x00FF));
+ }
+
+ if (length_ext_size == 1)
+ {
+ // Add first byte of length_ext to the option header.
+ p_buffer[byte_index++] = (uint8_t)length_ext;
+ }
+ else if (length_ext_size == 2)
+ {
+ // uint16 in Network Byte Order.
+ p_buffer[byte_index++] = (uint8_t)((length_ext & 0xFF00) >> 8);
+ p_buffer[byte_index++] = (uint8_t)((length_ext & 0x00FF));
+ }
+
+ memcpy(&p_buffer[byte_index], p_option->p_data, p_option->length);
+ *byte_count = byte_index + p_option->length;
+
+ return NRF_SUCCESS;
+}
+
+uint32_t coap_message_decode(coap_message_t * p_message,
+ const uint8_t * p_raw_message,
+ uint16_t message_len)
+{
+ NULL_PARAM_CHECK(p_message);
+ NULL_PARAM_CHECK(p_raw_message);
+
+ // Check that the raw message contains the mandatory header.
+ if (message_len < 4)
+ {
+ return (NRF_ERROR_INVALID_LENGTH | IOT_COAP_ERR_BASE);
+ }
+
+ // Parse the content of the raw message buffer.
+ uint16_t byte_index = 0;
+
+ // Parse the 4 byte CoAP header.
+ p_message->header.version = (p_raw_message[byte_index] >> 6);
+ p_message->header.type = (coap_msg_type_t)((p_raw_message[byte_index] >> 4) & 0x03);
+ p_message->header.token_len = (p_raw_message[byte_index] & 0x0F);
+ byte_index++;
+
+ p_message->header.code = (coap_msg_code_t)p_raw_message[byte_index];
+ byte_index++;
+
+ p_message->header.id = p_raw_message[byte_index++] << 8;
+ p_message->header.id += p_raw_message[byte_index++];
+
+ // Parse the token, if any.
+ for (uint8_t index = 0; (byte_index < message_len) && (index < p_message->header.token_len); index++)
+ {
+ p_message->token[index] = p_raw_message[byte_index++];
+ }
+
+ p_message->options_count = 0;
+ p_message->options_delta = 0;
+
+ // Parse the options if any.
+ while ((byte_index < message_len) && (p_raw_message[byte_index] != COAP_PAYLOAD_MARKER))
+ {
+
+ uint32_t err_code;
+ uint16_t byte_count = 0;
+
+ err_code = decode_option(&p_raw_message[byte_index], p_message, &byte_count);
+ if (err_code != NRF_SUCCESS)
+ {
+ return err_code;
+ }
+
+ p_message->options_count += 1;
+
+ byte_index += byte_count;
+ }
+
+ // If there any more bytes to parse this would be the payload.
+ if (byte_index < message_len)
+ {
+ // Verify that we have a payload marker.
+ if (p_raw_message[byte_index] == COAP_PAYLOAD_MARKER)
+ {
+ byte_index++;
+ }
+ else
+ {
+ return COAP_MESSAGE_INVALID_CONTENT;
+ }
+
+ p_message->payload_len = message_len - byte_index;
+ p_message->p_payload = (uint8_t *)&p_raw_message[byte_index];
+ }
+
+ return NRF_SUCCESS;
+}
+
+
+uint32_t coap_message_encode(coap_message_t * p_message,
+ uint8_t * p_buffer,
+ uint16_t * p_length)
+{
+ NULL_PARAM_CHECK(p_length);
+ NULL_PARAM_CHECK(p_message);
+
+ // calculated size
+ uint16_t total_packet_size = 4;
+
+ if (p_message->payload_len > 0)
+ {
+ total_packet_size += p_message->payload_len;
+ total_packet_size += COAP_PAYLOAD_MARKER_SIZE;
+ }
+
+ if (p_message->header.token_len > 8)
+ {
+ return (NRF_ERROR_INVALID_DATA | IOT_COAP_ERR_BASE);
+ }
+ total_packet_size += p_message->header.token_len;
+ total_packet_size += p_message->options_len;
+
+ // If this was a length check, return after setting the length in the output parameter.
+ if (*p_length == 0)
+ {
+ *p_length = total_packet_size;
+ return NRF_SUCCESS;
+ }
+
+ // Check that the buffer provided is sufficient.
+ if (*p_length < total_packet_size)
+ {
+ return (NRF_ERROR_DATA_SIZE | IOT_COAP_ERR_BASE);
+ }
+
+ if (((p_message->payload_len > 0 && p_message->p_payload == NULL)) ||
+ (p_buffer == NULL))
+ {
+ return COAP_MESSAGE_ERROR_NULL;
+ }
+
+ // Start filling the bytes.
+ uint16_t byte_index = 0;
+
+ // TODO: Verify the values of the header fields.
+ // if (version > 1)
+ // if (p_message->type > COAP_TYPE_RST)
+ // if (p_message->token_len > 8)
+
+
+ p_buffer[byte_index] = (((p_message->header.version & 0x3) << 6) | ((p_message->header.type & 0x3) << 4)) | (p_message->header.token_len & 0x0F);
+ byte_index++;
+
+ p_buffer[byte_index] = p_message->header.code;
+ byte_index++;
+
+ p_buffer[byte_index++] = (p_message->header.id & 0xFF00) >> 8;
+ p_buffer[byte_index++] = (p_message->header.id & 0x00FF);
+
+ memcpy(&p_buffer[byte_index], p_message->token, p_message->header.token_len);
+ byte_index += p_message->header.token_len;
+
+ //memcpy(&p_buffer[byte_index], &p_message->p_data[0], p_message->options_len);
+ for (uint8_t i = 0; i < p_message->options_count; i++)
+ {
+ uint32_t err_code;
+
+ uint16_t byte_count = 0;
+ err_code = encode_option(&p_buffer[byte_index], &p_message->options[i], &byte_count);
+ if (err_code == NRF_SUCCESS)
+ {
+ byte_index += byte_count;
+ }
+ else
+ {
+ // Throw an error.
+ }
+ }
+
+ if (p_message->payload_len > 0 && p_message->p_payload != NULL)
+ {
+ p_buffer[byte_index++] = 0xFF;
+ memcpy(&p_buffer[byte_index], p_message->p_payload, p_message->payload_len);
+ }
+
+ *p_length = total_packet_size;
+
+ return NRF_SUCCESS;
+}
+
+uint32_t coap_message_opt_empty_add(coap_message_t * p_message, uint16_t option_num)
+{
+ OPTION_INDEX_AVAIL_CHECK(p_message->options_count);
+
+ uint32_t err_code;
+ uint16_t encoded_len = 0;
+ uint8_t current_option_index = p_message->options_count;
+
+ p_message->options[current_option_index].number = option_num - p_message->options_delta;
+ p_message->options[current_option_index].length = encoded_len;
+
+ // Set accumulated option delta for next option.
+ p_message->options_delta = option_num;
+
+ // Calculate option size
+ uint16_t option_byte_count = 0;
+
+ // do a length check to encode_option to get the header length.
+ err_code = encode_option(NULL, &p_message->options[current_option_index], &option_byte_count);
+
+ // Accumulate expected size of all options with headers.
+ p_message->options_len += option_byte_count;
+
+ p_message->options_count += 1;
+
+ return err_code;
+}
+
+uint32_t coap_message_opt_uint_add(coap_message_t * p_message,
+ uint16_t option_num,
+ uint32_t data)
+{
+ OPTION_INDEX_AVAIL_CHECK(p_message->options_count);
+
+ uint32_t err_code;
+ uint16_t encoded_len = p_message->data_len - p_message->options_offset;
+ uint8_t current_option_index = p_message->options_count;
+ uint8_t * p_next_option_data = &p_message->p_data[p_message->options_offset];
+
+ // If the value of the option is 0, do not encode the 0, as this can be omitted. (RFC7252 3.2)
+ if (data == 0)
+ {
+ encoded_len = 0;
+ }
+ else
+ {
+ err_code = coap_opt_uint_encode(p_next_option_data, &encoded_len, data);
+ if (err_code != NRF_SUCCESS)
+ {
+ return err_code;
+ }
+ }
+
+ p_message->options[current_option_index].p_data = p_next_option_data;
+ p_message->options[current_option_index].number = option_num - p_message->options_delta;
+ p_message->options[current_option_index].length = encoded_len;
+
+ // Set accumulated option delta for next option.
+ p_message->options_delta = option_num;
+
+ // Calculate option size.
+ uint16_t option_byte_count = 0;
+
+ // Do a length check to encode_option to get the header length.
+ err_code = encode_option(NULL, &p_message->options[current_option_index], &option_byte_count);
+
+ // Accumulate expected size of all options with headers.
+ p_message->options_len += option_byte_count;
+
+ p_message->options_count += 1;
+
+ // Increase the pointer offset for the next option data in the scratch buffer.
+ p_message->options_offset += encoded_len;
+
+ return err_code;
+}
+
+uint32_t coap_message_opt_str_add(coap_message_t * p_message, uint16_t option_num, uint8_t * p_data, uint16_t length)
+{
+ OPTION_INDEX_AVAIL_CHECK(p_message->options_count);
+
+ uint32_t err_code;
+
+ uint16_t encoded_len = length;
+ uint8_t current_option_index = p_message->options_count;
+ uint8_t * p_next_option_data = &p_message->p_data[p_message->options_offset];
+
+
+ err_code = coap_opt_string_encode(p_next_option_data, &encoded_len, p_data, length);
+ if (err_code != NRF_SUCCESS)
+ {
+ return err_code;
+ }
+
+ p_message->options[current_option_index].p_data = p_next_option_data;
+ p_message->options[current_option_index].number = option_num - p_message->options_delta;
+ p_message->options[current_option_index].length = encoded_len;
+
+ // Set accumulated option delta for next option.
+ p_message->options_delta = option_num;
+
+ // Calculate option size
+ uint16_t option_byte_count = 0;
+
+ // do a length check to encode_option to get the header length.
+ err_code = encode_option(NULL, &p_message->options[current_option_index], &option_byte_count);
+
+ // Accumulate expected size of all options with headers.
+ p_message->options_len += option_byte_count;
+
+ p_message->options_count += 1;
+ p_message->options_offset += encoded_len;
+
+ return err_code;
+
+}
+
+uint32_t coap_message_opt_opaque_add(coap_message_t * p_message, uint16_t option_num, uint8_t * p_data, uint16_t length)
+{
+ OPTION_INDEX_AVAIL_CHECK(p_message->options_count);
+
+ // Check if it is possible to add a new option of this length.
+ if ((p_message->data_len - p_message->options_offset) < length)
+ {
+ return (NRF_ERROR_DATA_SIZE | IOT_COAP_ERR_BASE);
+ }
+
+ uint32_t err_code = NRF_SUCCESS;
+
+ uint16_t encoded_len = length;
+ uint8_t current_option_index = p_message->options_count;
+ uint8_t * p_next_option_data = &p_message->p_data[p_message->options_offset];
+
+
+ memcpy(p_next_option_data, p_data, encoded_len);
+
+ p_message->options[current_option_index].p_data = p_next_option_data;
+ p_message->options[current_option_index].number = option_num - p_message->options_delta;
+ p_message->options[current_option_index].length = encoded_len;
+
+ // Set accumulated option delta for next option.
+ p_message->options_delta = option_num;
+
+ // Calculate option size
+ uint16_t option_byte_count = 0;
+
+ // do a length check to encode_option to get the header length.
+ err_code = encode_option(NULL, &p_message->options[current_option_index], &option_byte_count);
+
+ // Accumulate expected size of all options with headers.
+ p_message->options_len += option_byte_count;
+
+ p_message->options_count += 1;
+ p_message->options_offset += encoded_len;
+
+ return err_code;
+}
+
+uint32_t coap_message_payload_set(coap_message_t * p_message,
+ void * p_payload,
+ uint16_t payload_len)
+{
+ // Check that there is available memory in the p_message->p_data scratch buffer.
+ if (payload_len > (COAP_MESSAGE_DATA_MAX_SIZE - p_message->options_offset))
+ {
+ return (NRF_ERROR_NO_MEM | IOT_COAP_ERR_BASE);
+ }
+
+ p_message->p_payload = &p_message->p_data[p_message->options_offset];
+ p_message->payload_len = payload_len;
+ memcpy(p_message->p_payload, p_payload, payload_len);
+
+ return NRF_SUCCESS;
+}
+
+
+uint32_t coap_message_remote_addr_set(coap_message_t * p_message, coap_remote_t * p_address)
+{
+ memcpy(&p_message->remote, p_address, sizeof(coap_remote_t));
+ return NRF_SUCCESS;
+}
+
+uint32_t coap_message_opt_index_get(uint8_t * p_index, coap_message_t * p_message, uint16_t option)
+{
+ NULL_PARAM_CHECK(p_index);
+ NULL_PARAM_CHECK(p_message);
+
+ uint8_t index;
+ for (index = 0; index < p_message->options_count; index++)
+ {
+ if (p_message->options[index].number == option)
+ {
+ *p_index = index;
+ return NRF_SUCCESS;
+ }
+ }
+ return (NRF_ERROR_NOT_FOUND | IOT_COAP_ERR_BASE);
+}
+
+uint32_t coap_message_opt_present(coap_message_t * p_message, uint16_t option)
+{
+ NULL_PARAM_CHECK(p_message);
+
+ uint8_t index;
+ for (index = 0; index < p_message->options_count; index++)
+ {
+ if (p_message->options[index].number == option)
+ {
+ return NRF_SUCCESS;
+ }
+ }
+ return (NRF_ERROR_NOT_FOUND | IOT_COAP_ERR_BASE);
+}
+
+static uint32_t bit_to_content_format(coap_content_type_t * p_ct, uint32_t bit)
+{
+ switch (bit)
+ {
+ case COAP_CT_MASK_PLAIN_TEXT:
+ *p_ct = COAP_CT_PLAIN_TEXT;
+ break;
+
+ case COAP_CT_MASK_APP_LINK_FORMAT:
+ *p_ct = COAP_CT_APP_LINK_FORMAT;
+ break;
+
+ case COAP_CT_MASK_APP_XML:
+ *p_ct = COAP_CT_APP_XML;
+ break;
+
+ case COAP_CT_MASK_APP_OCTET_STREAM:
+ *p_ct = COAP_CT_APP_OCTET_STREAM;
+ break;
+
+ case COAP_CT_MASK_APP_EXI:
+ *p_ct = COAP_CT_APP_EXI;
+ break;
+
+ case COAP_CT_MASK_APP_JSON:
+ *p_ct = COAP_CT_APP_JSON;
+ break;
+
+ default:
+ return (NRF_ERROR_NOT_FOUND | IOT_COAP_ERR_BASE);
+ }
+ return NRF_SUCCESS;
+}
+
+static uint32_t content_format_to_bit(coap_content_type_t ct)
+{
+ uint32_t mask = 0;
+ switch (ct)
+ {
+ case COAP_CT_PLAIN_TEXT:
+ mask = COAP_CT_MASK_PLAIN_TEXT;
+ break;
+
+ case COAP_CT_APP_LINK_FORMAT:
+ mask = COAP_CT_MASK_APP_LINK_FORMAT;
+ break;
+
+ case COAP_CT_APP_XML:
+ mask = COAP_CT_MASK_APP_XML;
+ break;
+
+ case COAP_CT_APP_OCTET_STREAM:
+ mask = COAP_CT_MASK_APP_OCTET_STREAM;
+ break;
+
+ case COAP_CT_APP_EXI:
+ mask = COAP_CT_MASK_APP_EXI;
+ break;
+
+ case COAP_CT_APP_JSON:
+ mask = COAP_CT_MASK_APP_JSON;
+ break;
+
+ default:
+ break;
+ }
+
+ return mask;
+}
+
+uint32_t coap_message_ct_mask_get(coap_message_t * p_message, uint32_t * p_mask)
+{
+ NULL_PARAM_CHECK(p_message);
+ NULL_PARAM_CHECK(p_mask);
+
+ (*p_mask) = 0;
+
+ for (uint8_t index = 0; index < p_message->options_count; index++)
+ {
+ if (p_message->options[index].number == COAP_OPT_CONTENT_FORMAT)
+ {
+ uint32_t value;
+ uint32_t err_code = coap_opt_uint_decode(&value,
+ p_message->options[index].length,
+ p_message->options[index].p_data);
+ if (err_code == NRF_SUCCESS)
+ {
+ coap_content_type_t ct = (coap_content_type_t)value;
+ *p_mask |= content_format_to_bit(ct);
+ }
+ else
+ {
+ return err_code;
+ }
+ }
+ }
+ return NRF_SUCCESS;
+}
+
+uint32_t coap_message_accept_mask_get(coap_message_t * p_message, uint32_t * p_mask)
+{
+ NULL_PARAM_CHECK(p_message);
+ NULL_PARAM_CHECK(p_mask);
+
+ (*p_mask) = 0;
+
+ for (uint8_t index = 0; index < p_message->options_count; index++)
+ {
+ if (p_message->options[index].number == COAP_OPT_ACCEPT)
+ {
+ uint32_t value;
+ uint32_t err_code = coap_opt_uint_decode(&value,
+ p_message->options[index].length,
+ p_message->options[index].p_data);
+ if (err_code == NRF_SUCCESS)
+ {
+ coap_content_type_t ct = (coap_content_type_t)value;
+ (*p_mask) |= content_format_to_bit(ct);
+ }
+ else
+ {
+ return err_code;
+ }
+ }
+ }
+
+ return NRF_SUCCESS;
+}
+
+uint32_t coap_message_ct_match_select(coap_content_type_t * p_ct, coap_message_t * p_message, coap_resource_t * p_resource)
+{
+ // Check ACCEPT options
+ uint32_t accept_mask = 0;
+ (void)coap_message_accept_mask_get(p_message, &accept_mask);
+
+ if (accept_mask == 0)
+ {
+ // Default to plain text if option not set.
+ accept_mask = COAP_CT_MASK_PLAIN_TEXT;
+ }
+
+ // Select the first common content-type between the resource and the CoAP client.
+ uint32_t common_ct = p_resource->ct_support_mask & accept_mask;
+ uint32_t bit_index;
+ for (bit_index = 0; bit_index < 32; bit_index++)
+ {
+ if (((common_ct >> bit_index) & 0x1 ) == 1)
+ {
+ break;
+ }
+ }
+
+ uint32_t err_code = bit_to_content_format(p_ct, 1 << bit_index);
+
+ return err_code;
+}
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/coap/coap_message.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/coap/coap_message.h
new file mode 100644
index 0000000..efd226b
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/coap/coap_message.h
@@ -0,0 +1,158 @@
+/**
+ * Copyright (c) 2014 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 coap_message.h
+ *
+ * @defgroup iot_sdk_coap_msg CoAP Message
+ * @ingroup iot_sdk_coap
+ * @{
+ * @brief TODO.
+ */
+
+#ifndef COAP_MESSAGE_H__
+#define COAP_MESSAGE_H__
+
+#include <stdint.h>
+#include "coap_api.h"
+#include "coap_codes.h"
+#include "coap_transport.h"
+#include "coap_option.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define COAP_PAYLOAD_MARKER 0xFF
+
+/**@brief Create a new CoAP message.
+ *
+ * @details The function will allocate memory for the message internally and return
+ * a CoAP message structure. The callback provided will be called if a matching
+ * message ID/Token occurs in a response message.
+ * @param[out] p_message Pointer to set the generated coap_message_t structure to.
+ * @param[in] p_init_config Initial configuration parameters of the message to generate.
+ *
+ * @retval NRF_SUCCESS If memory for the new message was allocated and the
+ * initialization of the message went successfully.
+ * @retval NRF_ERROR_NULL Either the message or init_config parameter was NULL.
+ * @retval NRF_ERROR_INVALID_PARAM If port number in the port field is set to 0.
+ */
+uint32_t coap_message_create(coap_message_t * p_message, coap_message_conf_t * p_init_config);
+
+/**@brief Decode a message from a raw buffer.
+ *
+ * @details When the underlying transport layer receives a message, it has to
+ * be decoded into a CoAP message type structure. This functions returns
+ * a decoded message if decoding was successfully, or NULL otherwise.
+ *
+ * @param[out] p_message The generated coap_message_t after decoding the raw message.
+ * @param[in] p_raw_message Pointer to the encoded message memory buffer.
+ * @param[in] message_len Length of the p_raw_message.
+ *
+ * @retval NRF_SUCCESS If the decoding of the message succeeds.
+ * @retval NRF_ERROR_NULL If pointer to the p_message or p_raw_message were NULL.
+ * @retval NRF_ERROR_INVALID_LENGTH If the message is less than 4 bytes, not containing a
+ * full header.
+ * @retval COAP_MESSAGE_INVALID_CONTENT If the message could not be decoded successfully. This
+ * could happen if message length provided is larger than
+ * what is possible to decode (ex. missing payload marker).
+ *
+ */
+uint32_t coap_message_decode(coap_message_t * p_message,
+ const uint8_t * p_raw_message,
+ uint16_t message_len);
+
+/**@brief Encode a CoAP message into a byte buffer.
+ *
+ * @details This functions has two operations. One is the actual encoding into a
+ * byte buffer. The other is to query the size of a potential encoding.
+ * If p_buffer variable is omitted, the return value will be the size of a
+ * potential serialized message. This can be used to get some persistent memory from
+ * transport layer. The message have to be kept until all potential
+ * retransmissions has been attempted.
+ *
+ * The p_message can be deleted after this point if the function succeeds.
+ *
+ * @param[in] p_message Message to encode.
+ * @param[in] p_buffer Pointer to the byte buffer where to put the encoded message.
+ * @param[inout] p_length Length of the provided byte buffer passed in by reference.
+ * If the value 0 is supplied, the encoding will not take place,
+ * but only the dry run calculating the expected length of the
+ * encoded message.
+ *
+ * @retval NRF_SUCCESS If the encoding of the message succeeds.
+ * @retval NRF_ERROR_NULL If message or length parameter is NULL pointer.
+ * @retval NRF_ERROR_NO_MEM If the provided buffer is not sufficient for
+ * the encoded message.
+ * @retval COAP_MESSAGE_ERROR_NULL If the message has indicated the length of data,
+ * but memory pointer is NULL.
+ */
+uint32_t coap_message_encode(coap_message_t * p_message,
+ uint8_t * p_buffer,
+ uint16_t * p_length);
+
+/**@brief Get the content format mask of the message.
+ *
+ * @param[in] p_message Pointer to the message which to generate the content format mask from.
+ * Should not be NULL.
+ * @param[out] p_mask Value by reference to the variable to fill the result mask into.
+ *
+ * @retval NRF_SUCCESS If the mask could be generated.
+ * @retval NRF_ERROR_NULL If the message pointer or the mask pointer given was NULL.
+ */
+uint32_t coap_message_ct_mask_get(coap_message_t * p_message, uint32_t * p_mask);
+
+/**@brief Get the accept mask of the message.
+ *
+ * @param[in] p_message Pointer to the message which to generate the accept mask from.
+ * Should not be NULL.
+ * @param[out] p_mask Value by reference to the variable to fill the result mask into.
+ *
+ * @retval NRF_SUCCESS If the mask could be generated.
+ * @retval NRF_ERROR_NULL If the message pointer or the mask pointer given was NULL.
+ */
+uint32_t coap_message_accept_mask_get(coap_message_t * p_message, uint32_t * p_mask);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // COAP_MESSAGE_H__
+
+/** @} */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/coap/coap_observe.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/coap/coap_observe.c
new file mode 100644
index 0000000..b4c60aa
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/coap/coap_observe.c
@@ -0,0 +1,688 @@
+/**
+ * Copyright (c) 2014 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#include <string.h>
+
+#include "coap_observe_api.h"
+#include "coap_observe.h"
+#include "nrf_error.h"
+#include "iot_common.h"
+#include "sdk_common.h"
+#include "sdk_config.h"
+#include "coap.h"
+
+#if IOT_COAP_CONFIG_LOG_ENABLED
+
+#define NRF_LOG_MODULE_NAME coapobs
+
+#define NRF_LOG_LEVEL IOT_COAP_CONFIG_LOG_LEVEL
+#define NRF_LOG_INFO_COLOR IOT_COAP_CONFIG_INFO_COLOR
+#define NRF_LOG_DEBUG_COLOR IOT_COAP_CONFIG_DEBUG_COLOR
+
+#include "nrf_log.h"
+NRF_LOG_MODULE_REGISTER();
+
+#define COAP_TRC NRF_LOG_DEBUG /**< Used for getting trace of execution in the module. */
+#define COAP_ERR NRF_LOG_ERROR /**< Used for logging errors in the module. */
+#define COAP_DUMP NRF_LOG_HEXDUMP_DEBUG /**< Used for dumping octet information to get details of bond information etc. */
+
+#define COAP_ENTRY() COAP_TRC(">> %s", __func__)
+#define COAP_EXIT() COAP_TRC("<< %s", __func__)
+
+#else // IOT_COAP_CONFIG_LOG_ENABLED
+
+#define COAP_TRC(...) /**< Disables traces. */
+#define COAP_DUMP(...) /**< Disables dumping of octet streams. */
+#define COAP_ERR(...) /**< Disables error logs. */
+
+#define COAP_ENTRY(...)
+#define COAP_EXIT(...)
+
+#endif // IOT_COAP_CONFIG_LOG_ENABLED
+
+#if (COAP_ENABLE_OBSERVE_SERVER == 1)
+static coap_observer_t m_observers[COAP_OBSERVE_MAX_NUM_OBSERVERS];
+
+static void observe_server_init(void)
+{
+ COAP_ENTRY();
+
+ // Loop through the observer array and clear the memory.
+ for (uint32_t i = 0; i < COAP_OBSERVE_MAX_NUM_OBSERVERS; i++)
+ {
+ memset(&m_observers[i], 0, sizeof(coap_observer_t));
+ }
+
+ COAP_EXIT();
+}
+
+uint32_t internal_coap_observe_server_register(uint32_t * p_handle, coap_observer_t * p_observer)
+{
+ COAP_ENTRY();
+
+ NULL_PARAM_CHECK(p_handle);
+ NULL_PARAM_CHECK(p_observer);
+
+ NULL_PARAM_MEMBER_CHECK(p_observer->p_resource_of_interest);
+
+ // Check if there is already a registered observer in the list to be reused.
+ uint32_t handle;
+ uint32_t err_code = coap_observe_server_search(&handle,
+ &p_observer->remote,
+ p_observer->p_resource_of_interest);
+ if (err_code == NRF_SUCCESS)
+ {
+ memcpy(&m_observers[handle], p_observer, sizeof(coap_observer_t));
+ *p_handle = handle;
+ return NRF_SUCCESS;
+ }
+
+ // Check if there is an available spot in the observer list.
+ for (uint32_t i = 0; i < COAP_OBSERVE_MAX_NUM_OBSERVERS; i++)
+ {
+ if (m_observers[i].p_resource_of_interest == NULL)
+ {
+ memcpy(&m_observers[i], p_observer, sizeof(coap_observer_t));
+
+ *p_handle = i;
+ return NRF_SUCCESS;
+ }
+ }
+
+
+ COAP_EXIT();
+
+ return (NRF_ERROR_NO_MEM | IOT_COAP_ERR_BASE);
+}
+
+
+uint32_t internal_coap_observe_server_unregister(uint32_t handle)
+{
+ COAP_ENTRY();
+
+ if (handle >= COAP_OBSERVE_MAX_NUM_OBSERVERS)
+ {
+ return (NRF_ERROR_NOT_FOUND | IOT_COAP_ERR_BASE);
+ }
+
+ if (m_observers[handle].p_resource_of_interest == NULL)
+ {
+ return (NRF_ERROR_NOT_FOUND | IOT_COAP_ERR_BASE);
+ }
+
+ m_observers[handle].p_resource_of_interest = NULL;
+
+ COAP_EXIT();
+
+ return NRF_SUCCESS;
+}
+
+
+uint32_t internal_coap_observe_server_search(uint32_t * p_handle,
+ coap_remote_t * p_observer_addr,
+ coap_resource_t * p_resource)
+{
+ NULL_PARAM_CHECK(p_handle);
+ NULL_PARAM_CHECK(p_observer_addr);
+ NULL_PARAM_CHECK(p_resource);
+
+ for (uint32_t i = 0; i < COAP_OBSERVE_MAX_NUM_OBSERVERS; i++)
+ {
+ if (m_observers[i].p_resource_of_interest == p_resource)
+ {
+ if (m_observers[i].remote.port_number == p_observer_addr->port_number)
+ {
+ if (memcmp(p_observer_addr->addr, m_observers[i].remote.addr, sizeof(p_observer_addr->addr)) == 0)
+ {
+ *p_handle = i;
+ return NRF_SUCCESS;
+ }
+ }
+ }
+ }
+
+ return (NRF_ERROR_NOT_FOUND | IOT_COAP_ERR_BASE);
+}
+
+
+uint32_t internal_coap_observe_server_next_get(coap_observer_t ** pp_observer,
+ coap_observer_t * p_observer,
+ coap_resource_t * p_resource)
+{
+ NULL_PARAM_CHECK(p_resource);
+ NULL_PARAM_CHECK(pp_observer);
+
+ if (p_observer == NULL)
+ {
+ for (uint32_t i = 0; i < COAP_OBSERVE_MAX_NUM_OBSERVERS; i++)
+ {
+ if (m_observers[i].p_resource_of_interest == p_resource)
+ {
+ (*pp_observer) = &m_observers[i];
+ return NRF_SUCCESS;
+ }
+ }
+ }
+ else
+ {
+ uint32_t index_to_previous = (uint8_t)(((uint32_t)p_observer - (uint32_t)m_observers) / (uint32_t)sizeof(coap_observer_t));
+
+ for (uint32_t i = index_to_previous + 1; i < COAP_OBSERVE_MAX_NUM_OBSERVERS; i++)
+ {
+ if (m_observers[i].p_resource_of_interest == p_resource)
+ {
+ (*pp_observer) = &m_observers[i];
+ return NRF_SUCCESS;
+ }
+ }
+ }
+ (*pp_observer) = NULL;
+
+ return (NRF_ERROR_NOT_FOUND | IOT_COAP_ERR_BASE);
+}
+
+uint32_t internal_coap_observe_server_get(uint32_t handle, coap_observer_t ** pp_observer)
+{
+ NULL_PARAM_CHECK(pp_observer);
+
+ if (handle >= COAP_OBSERVE_MAX_NUM_OBSERVERS)
+ {
+ return (NRF_ERROR_NOT_FOUND | IOT_COAP_ERR_BASE);
+ }
+
+ if (m_observers[handle].p_resource_of_interest == NULL)
+ {
+ return (NRF_ERROR_NOT_FOUND | IOT_COAP_ERR_BASE);
+ }
+
+ *pp_observer = &m_observers[handle];
+ return NRF_SUCCESS;
+}
+#else
+#define observe_server_init(...)
+#endif
+
+#if (COAP_ENABLE_OBSERVE_CLIENT == 1)
+static coap_observable_t m_observables[COAP_OBSERVE_MAX_NUM_OBSERVABLES];
+
+static void observe_client_init(void)
+{
+ // Loop through the observable array and clear the memory.
+ for (uint32_t i = 0; i < COAP_OBSERVE_MAX_NUM_OBSERVABLES; i++)
+ {
+ memset(&m_observables[i], 0, sizeof(coap_observable_t));
+ }
+}
+
+
+uint32_t internal_coap_observe_client_register(uint32_t * p_handle,
+ coap_observable_t * p_observable)
+{
+ COAP_ENTRY();
+
+ NULL_PARAM_CHECK(p_handle);
+ NULL_PARAM_CHECK(p_observable);
+
+ NULL_PARAM_MEMBER_CHECK(p_observable->response_callback);
+
+ // Check if there is an available spot in the observer list.
+ for (uint32_t i = 0; i < COAP_OBSERVE_MAX_NUM_OBSERVABLES; i++)
+ {
+ if (m_observables[i].response_callback == NULL)
+ {
+ memcpy(&m_observables[i], p_observable, sizeof(coap_observable_t));
+ *p_handle = i;
+ return NRF_SUCCESS;
+ }
+ }
+
+ COAP_EXIT();
+
+ return (NRF_ERROR_NO_MEM | IOT_COAP_ERR_BASE);
+}
+
+
+uint32_t internal_coap_observe_client_unregister(uint32_t handle)
+{
+ COAP_ENTRY();
+
+ if (handle >= COAP_OBSERVE_MAX_NUM_OBSERVABLES)
+ {
+ return (NRF_ERROR_NOT_FOUND | IOT_COAP_ERR_BASE);
+ }
+
+ if (m_observables[handle].response_callback == NULL)
+ {
+ return (NRF_ERROR_NOT_FOUND | IOT_COAP_ERR_BASE);
+ }
+
+ m_observables[handle].response_callback = NULL;
+
+ COAP_EXIT();
+
+ return NRF_SUCCESS;
+}
+
+
+uint32_t internal_coap_observe_client_search(uint32_t * p_handle, uint8_t * p_token, uint16_t token_len)
+{
+ NULL_PARAM_CHECK(p_handle);
+ NULL_PARAM_CHECK(p_token);
+
+ for (uint32_t i = 0; i < COAP_OBSERVE_MAX_NUM_OBSERVABLES; i++)
+ {
+ if ((m_observables[i].response_callback != NULL) &&
+ (0 != m_observables[i].token_len) &&
+ (memcmp(m_observables[i].token, p_token, m_observables[i].token_len) == 0))
+ {
+ *p_handle = i;
+ return NRF_SUCCESS;
+ }
+ }
+
+ return (NRF_ERROR_NOT_FOUND | IOT_COAP_ERR_BASE);
+}
+
+
+uint32_t internal_coap_observe_client_get(uint32_t handle, coap_observable_t ** pp_observable)
+{
+ NULL_PARAM_CHECK(pp_observable);
+
+ if (handle >= COAP_OBSERVE_MAX_NUM_OBSERVABLES)
+ {
+ return (NRF_ERROR_NOT_FOUND | IOT_COAP_ERR_BASE);
+ }
+
+ if (m_observables[handle].response_callback == NULL)
+ {
+ return (NRF_ERROR_NOT_FOUND | IOT_COAP_ERR_BASE);
+ }
+
+ *pp_observable = &m_observables[handle];
+
+ return NRF_SUCCESS;
+}
+
+uint32_t internal_coap_observe_client_next_get(coap_observable_t ** pp_observable,
+ uint32_t * p_handle,
+ coap_observable_t * p_observable)
+{
+ NULL_PARAM_CHECK(pp_observable);
+
+ if (p_observable == NULL)
+ {
+ for (uint32_t i = 0; i < COAP_OBSERVE_MAX_NUM_OBSERVABLES; i++)
+ {
+ if (m_observables[i].response_callback != NULL)
+ {
+ (*pp_observable) = &m_observables[i];
+ (*p_handle) = i;
+ return NRF_SUCCESS;
+ }
+ }
+ }
+ else
+ {
+ uint32_t index_to_previous = (uint8_t)(((uint32_t)p_observable - (uint32_t)m_observables) / (uint32_t)sizeof(coap_observable_t));
+
+ for (uint32_t i = index_to_previous + 1; i < COAP_OBSERVE_MAX_NUM_OBSERVABLES; i++)
+ {
+ if (m_observables[i].response_callback != NULL)
+ {
+ (*pp_observable) = &m_observables[i];
+ (*p_handle) = i;
+ return NRF_SUCCESS;
+ }
+ }
+ }
+ (*pp_observable) = NULL;
+
+ COAP_MUTEX_UNLOCK();
+
+ return (NRF_ERROR_NOT_FOUND | IOT_COAP_ERR_BASE);
+}
+
+static uint32_t observe_opt_present(coap_message_t * p_message)
+{
+ uint8_t index;
+ for (index = 0; index < p_message->options_count; index++)
+ {
+ if (p_message->options[index].number == COAP_OPT_OBSERVE)
+ {
+ return NRF_SUCCESS;
+ }
+ }
+ return NRF_ERROR_NOT_FOUND;
+}
+
+static void set_max_age(coap_observable_t * observable, coap_message_t * p_response)
+{
+ uint8_t index;
+ for (index = 0; index < p_response->options_count; index++)
+ {
+ if (p_response->options[index].number == COAP_OPT_MAX_AGE)
+ {
+ uint32_t max_age;
+ observable->max_age = coap_opt_uint_decode(&max_age,
+ p_response->options[index].length,
+ p_response->options[index].p_data);
+ observable->max_age = max_age;
+ return;
+ }
+ }
+
+ // Max-Age option is not present, set default value to 60.
+ observable->max_age = 60;
+}
+
+void coap_observe_client_send_handle(coap_message_t * p_request)
+{
+ COAP_ENTRY();
+
+ if (p_request->header.code == COAP_CODE_GET)
+ {
+ uint32_t observe_option = 0;
+ if (observe_opt_present(p_request) == NRF_SUCCESS)
+ {
+ // Locate option and check value.
+ uint8_t index;
+ for (index = 0; index < p_request->options_count; index++)
+ {
+ if (p_request->options[index].number == COAP_OPT_OBSERVE)
+ {
+ uint32_t err_code = coap_opt_uint_decode(&observe_option,
+ p_request->options[index].length,
+ p_request->options[index].p_data);
+ if (err_code != NRF_SUCCESS)
+ {
+ return;
+ }
+ break;
+ }
+ }
+ }
+
+ if (observe_option == 1)
+ {
+ // Un-register observable instance.
+ uint32_t handle;
+ uint32_t err_code = internal_coap_observe_client_search(&handle,
+ p_request->token,
+ p_request->header.token_len);
+ if (err_code == NRF_SUCCESS)
+ {
+ (void)internal_coap_observe_client_unregister(handle);
+ COAP_TRC("OBSERVE=1 in request, client_unregister handle: %i", handle);
+
+ }
+ }
+ }
+
+ COAP_EXIT();
+}
+
+void coap_observe_client_response_handle(coap_message_t * p_response, coap_queue_item_t * p_item)
+{
+ COAP_ENTRY();
+
+ if (observe_opt_present(p_response) == NRF_SUCCESS)
+ {
+ if (p_item == NULL)
+ {
+ // Search for the token in the observable list.
+ uint32_t handle;
+ uint32_t err_code = internal_coap_observe_client_search(&handle, p_response->token, p_response->header.token_len);
+ if (err_code == NRF_SUCCESS)
+ {
+ // Fetch the observable.
+ coap_observable_t * p_observable;
+ err_code = internal_coap_observe_client_get(handle, &p_observable);
+ if (err_code == NRF_SUCCESS)
+ {
+ // Update max-age to the newly recieved message.
+ set_max_age(p_observable, p_response);
+
+ COAP_MUTEX_UNLOCK();
+
+ // Callback to the application.
+ p_observable->response_callback(NRF_SUCCESS, NULL, p_response);
+
+ COAP_MUTEX_LOCK();
+
+ COAP_TRC("Notification received on handle: %i", handle);
+
+ #ifdef COAP_AUTOMODE
+ if (p_response->header.type == COAP_TYPE_CON)
+ {
+ // Reply an ACK upon CON message.
+ }
+ else if (p_response->header.type == COAP_TYPE_RST)
+ {
+ // Remove observable from list.
+ }
+ #endif
+ }
+ else
+ {
+ #ifdef COAP_AUTOMODE
+ if (p_response->header.type == COAP_TYPE_CON)
+ {
+ // Reply reset upon CON message when observer is not located.
+ }
+ #endif
+ }
+ }
+ else
+ {
+ // Send RST message back to server to indicate there is no one listening.
+ }
+ }
+ else // p_item set.
+ {
+ // If there is no observable instance created yet for thit token, add it.
+ uint32_t handle;
+ uint32_t err_code = internal_coap_observe_client_search(&handle, p_response->token, p_response->header.token_len);
+ if (err_code == (NRF_ERROR_NOT_FOUND | IOT_COAP_ERR_BASE))
+ {
+ // If the response is a valid response, add the observable resource.
+ if (p_response->header.code == COAP_CODE_205_CONTENT)
+ {
+ coap_observable_t observable;
+ // Token Length.
+ observable.token_len = p_response->header.token_len;
+ // Remote.
+ memcpy(&observable.remote, &p_response->remote, sizeof(coap_remote_t));
+ // Token.
+ memcpy(observable.token, p_response->token, observable.token_len);
+ // Callback to be called upon notification.
+ observable.response_callback = p_item->callback;
+
+ // Update max-age to the newly recieved message.
+ set_max_age(&observable, p_response);
+
+ // Register the observable.
+ uint32_t observable_resource_handle;
+ (void)internal_coap_observe_client_register(&observable_resource_handle, &observable);
+ // TODO: error check
+
+ COAP_TRC("Subscription response received, client_register handle: %i", observable_resource_handle);
+ }
+ }
+ }
+ }
+ else // COAP_OPT_OBSERVE not present
+ {
+ uint32_t handle;
+ uint32_t err_code = internal_coap_observe_client_search(&handle, p_response->token, p_response->header.token_len);
+ if (err_code == NRF_SUCCESS)
+ {
+ (void)internal_coap_observe_client_unregister(handle);
+ COAP_TRC("OBSERVE not present in notification, client_unregister handle: %i", handle);
+ }
+ }
+
+ COAP_EXIT();
+}
+#else
+#define observe_client_init(...)
+#endif
+
+void internal_coap_observe_init(void)
+{
+ observe_server_init();
+ observe_client_init();
+}
+
+#if (COAP_ENABLE_OBSERVE_SERVER == 1)
+
+uint32_t coap_observe_server_register(uint32_t * p_handle, coap_observer_t * p_observer)
+{
+ COAP_MUTEX_UNLOCK();
+
+ uint32_t err_code = internal_coap_observe_server_register(p_handle, p_observer);
+
+ COAP_MUTEX_UNLOCK();
+
+ return err_code;
+}
+
+uint32_t coap_observe_server_unregister(uint32_t handle)
+{
+ COAP_MUTEX_UNLOCK();
+
+ uint32_t err_code = internal_coap_observe_server_unregister(handle);
+
+ COAP_MUTEX_UNLOCK();
+
+ return err_code;
+}
+
+uint32_t coap_observe_server_search(uint32_t * p_handle, coap_remote_t * p_observer_addr, coap_resource_t * p_resource)
+{
+ COAP_MUTEX_UNLOCK();
+
+ uint32_t err_code = internal_coap_observe_server_search(p_handle, p_observer_addr, p_resource);
+
+ COAP_MUTEX_UNLOCK();
+
+ return err_code;
+}
+
+uint32_t coap_observe_server_next_get(coap_observer_t ** pp_observer, coap_observer_t * p_observer, coap_resource_t * p_resource)
+{
+ COAP_MUTEX_UNLOCK();
+
+ uint32_t err_code = internal_coap_observe_server_next_get(pp_observer, p_observer, p_resource);
+
+ COAP_MUTEX_UNLOCK();
+
+ return err_code;
+}
+
+uint32_t coap_observe_server_get(uint32_t handle, coap_observer_t ** pp_observer)
+{
+ COAP_MUTEX_UNLOCK();
+
+ uint32_t err_code = internal_coap_observe_server_get(handle, pp_observer);
+
+ COAP_MUTEX_UNLOCK();
+
+ return err_code;
+}
+
+#endif // COAP_ENABLE_OBSERVE_SERVER = 1
+
+#if (COAP_ENABLE_OBSERVE_CLIENT == 1)
+
+uint32_t coap_observe_client_register(uint32_t * p_handle, coap_observable_t * p_observable)
+{
+ COAP_MUTEX_UNLOCK();
+
+ uint32_t err_code = internal_coap_observe_client_register(p_handle, p_observable);
+
+ COAP_MUTEX_UNLOCK();
+
+ return err_code;
+}
+
+uint32_t coap_observe_client_unregister(uint32_t handle)
+{
+ COAP_MUTEX_UNLOCK();
+
+ uint32_t err_code = internal_coap_observe_client_unregister(handle);
+
+ COAP_MUTEX_UNLOCK();
+
+ return err_code;
+}
+
+uint32_t coap_observe_client_search(uint32_t * p_handle, uint8_t * p_token, uint16_t token_len)
+{
+ COAP_MUTEX_UNLOCK();
+
+ uint32_t err_code = internal_coap_observe_client_search(p_handle, p_token, token_len);
+
+ COAP_MUTEX_UNLOCK();
+
+ return err_code;
+}
+
+uint32_t coap_observe_client_get(uint32_t handle, coap_observable_t ** pp_observable)
+{
+ COAP_MUTEX_UNLOCK();
+
+ uint32_t err_code = internal_coap_observe_client_get(handle, pp_observable);
+
+ COAP_MUTEX_UNLOCK();
+
+ return err_code;
+}
+
+uint32_t coap_observe_client_next_get(coap_observable_t ** pp_observable, uint32_t * p_handle, coap_observable_t * p_observable)
+{
+ COAP_MUTEX_UNLOCK();
+
+ uint32_t err_code = internal_coap_observe_client_next_get(pp_observable, p_handle, p_observable);
+
+ COAP_MUTEX_UNLOCK();
+
+ return err_code;
+}
+
+#endif // COAP_ENABLE_OBSERVE_CLIENT == 1
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/coap/coap_observe.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/coap/coap_observe.h
new file mode 100644
index 0000000..bb72b89
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/coap/coap_observe.h
@@ -0,0 +1,248 @@
+/**
+ * Copyright (c) 2015 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 coap_observe.h
+ *
+ * @defgroup iot_sdk_coap_observe CoAP Observe
+ * @ingroup iot_sdk_coap
+ * @{
+ * @brief Internal API of Nordic's CoAP Observe implementation.
+ */
+#ifndef COAP_OBSERVE_H__
+#define COAP_OBSERVE_H__
+
+#include <stdint.h>
+
+#include "coap_observe_api.h"
+#include "coap_api.h"
+#include "coap_queue.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**@cond NO_DOXYGEN */
+
+/**@brief Register a new observer.
+ *
+ * @param[out] p_handle Handle to the observer instance registered. Returned by reference.
+ * Should not be NULL.
+ * @param[in] p_observer Pointer to the observer structure to register. The data will be
+ * copied. Should not be NULL.
+ *
+ * @retval NRF_SUCCESS If the observer was registered successfully.
+ * @retval NRF_ERROR_NO_MEM If the observer could not be added to the list.
+ * @retval NRF_ERROR_NULL If one of the parameters is a NULL pointer.
+ */
+uint32_t internal_coap_observe_server_register(uint32_t * p_handle, coap_observer_t * p_observer);
+
+/**@brief Unregister an observer.
+ *
+ * @details Unregister the observer and clear the memory used by this instance.
+ *
+ * @param[in] handle Handle to the observer instance registered.
+ *
+ * @retval NRF_SUCCESS If the observer was successfully unregistered.
+ * @retval NRF_ERROR_NOT_FOUND If the given handle was not found in the observer list.
+ */
+uint32_t internal_coap_observe_server_unregister(uint32_t handle);
+
+/**@brief Search the observer list for an observer matching remote address and subject given.
+ *
+ * @param[out] p_handle Handle to the observer instance registered. Returned by reference.
+ * Should not be NULL.
+ * @param[in] p_observer_addr Pointer to an address structure giving remote address of the observer and port number.
+ * Should not be NULL.
+ * @param[in] p_resource Pointer to the resource the observer is registered to. Should not be NULL.
+ *
+ * @retval NRF_SUCCESS If observer was found in the observer list.
+ * @retval NRF_ERROR_NULL If one of the pointers are NULL.
+ * @retval NRF_ERROR_NOT_FOUND If observer was not found.
+ */
+uint32_t internal_coap_observe_server_search(uint32_t * p_handle, coap_remote_t * p_observer_addr, coap_resource_t * p_resource);
+
+/**@brief Iterate through observers subscribing to a specific resource.
+ *
+ * @param[out] pp_observer Pointer to be filled by the search function upon finding the next observer starting from
+ * from the p_observer pointer provided. Should not be NULL.
+ * @param[in] p_observer Pointer to the observer where to start the search.
+ * @param[in] p_resource Pointer to the resource of interest. Should not be NULL.
+ *
+ * @retval NRF_SUCCESS If observer was found.
+ * @retval NRF_ERROR_NULL If pp_observer or p_resource pointer is NULL.
+ * @retval NRF_ERROR_NOT_FOUND If next observer was not found.
+ */
+uint32_t internal_coap_observe_server_next_get(coap_observer_t ** pp_observer, coap_observer_t * p_observer, coap_resource_t * p_resource);
+
+/**@brief Retrieve the observer based on handle.
+ *
+ * @param[in] handle Handle to the coap_observer_t instance.
+ * @param[out] pp_observer Pointer to an observer return by reference.
+ * Should not be NULL.
+ *
+ * @retval NRF_SUCCESS If observer was found in the observer list.
+ * @retval NRF_ERROR_NULL If pp_observer pointer is NULL.
+ * @retval NRF_ERROR_NOT_FOUND If observer associated with the handle was not found.
+ */
+uint32_t internal_coap_observe_server_get(uint32_t handle, coap_observer_t ** pp_observer);
+
+/**@brief Register a new observable resource.
+ *
+ * @param[out] p_handle Handle to the observable resource instance registered. Returned by
+ * reference. Should not be NULL.
+ * @param[in] p_observable Pointer to a observable resource structure to register. The structure
+ * will be copied. Should not be NULL.
+ *
+ * @retval NRF_SUCCESS If the observable resource was registered successfully.
+ * @retval NRF_ERROR_NO_MEM If the observable resource could not be added to the list.
+ * @retval NRF_ERROR_NULL If one of the parameters is a NULL pointer.
+ */
+uint32_t internal_coap_observe_client_register(uint32_t * p_handle, coap_observable_t * p_observable);
+
+/**@brief Unregister an observable resource.
+ *
+ * @details Unregister the observable resource and clear the memory used by this instance.
+ *
+ * @param[in] handle Handle to the observable resource instance registered.
+ *
+ * @retval NRF_SUCCESS If the observable resource was successfully unregistered.
+ * @retval NRF_ERROR_NOT_FOUND If the given handle was not found in the observable
+ * resource list.
+ */
+uint32_t internal_coap_observe_client_unregister(uint32_t handle);
+
+/**@brief Search for a observable resource instance by token.
+ *
+ * @param[out] p_handle Handle to the observable resource instance registered. Returned by
+ * reference. Should not be NULL.
+ * @param[in] p_token Pointer to the byte array holding the token id. Should not be NULL.
+ * @param[in] token_len Length of the token.
+ *
+ * @retval NRF_SUCCESS If observable resource was found in the observable
+ * resource list.
+ * @retval NRF_ERROR_NULL If one of the pointers are NULL.
+ * @retval NRF_ERROR_NOT_FOUND If observable resource was not found in the observable
+ * resource list.
+ */
+uint32_t internal_coap_observe_client_search(uint32_t * p_handle, uint8_t * p_token, uint16_t token_len);
+
+/**@brief Retrieve the observable resource based on handle.
+ *
+ * @param[in] handle Handle to the coap_observable_t instance.
+ * @param[out] pp_observable Pointer to an observable resource return by reference.
+ * Should not be NULL.
+ *
+ * @retval NRF_SUCCESS If observable resource was found in the observable
+ * resource list.
+ * @retval NRF_ERROR_NULL If pp_observable pointer is NULL.
+ * @retval NRF_ERROR_NOT_FOUND If observable resource associated with the handle
+ * was not found.
+ */
+uint32_t internal_coap_observe_client_get(uint32_t handle, coap_observable_t ** pp_observable);
+
+/**@brief Iterate through observable resources.
+ *
+ * @param[out] pp_observable Pointer to be filled by the search function upon finding the next
+ * observable resource starting from from the pointer provided.
+ * Should not be NULL.
+ * @param[out] p_handle Handler to the observable resource found returned by reference. Should
+ * not be NULL.
+ * @param[in] p_observable Pointer to the observable resource where to start the search.
+ *
+ * @retval NRF_SUCCESS If observer was found.
+ * @retval NRF_ERROR_NULL If pp_observer or p_observer pointer is NULL.
+ * @retval NRF_ERROR_NOT_FOUND If next observer was not found.
+ */
+uint32_t internal_coap_observe_client_next_get(coap_observable_t ** pp_observable, uint32_t * p_handle, coap_observable_t * p_observable);
+
+
+#if (COAP_ENABLE_OBSERVE_SERVER == 1) || (COAP_ENABLE_OBSERVE_CLIENT == 1)
+
+/**@brief Internal function to initilize observer (client) and observable (server) lists.
+ *
+ * @retval NRF_SUCCESS If initialization was successful.
+ */
+void internal_coap_observe_init(void);
+
+#else // COAP_ENABLE_OBSERVE_SERVER || COAP_ENABLE_OBSERVE_CLIENT
+
+#define internal_coap_observe_init(...)
+
+#endif // COAP_ENABLE_OBSERVE_SERVER || COAP_ENABLE_OBSERVE_CLIENT
+
+#if (COAP_ENABLE_OBSERVE_CLIENT == 1)
+
+/**@brief Observe client function to be run when sending requests.
+ *
+ * @details The function will peek into the outgoing messages to see if any actions regarding
+ * subscription to observable resources has to be done.
+ *
+ * @param[in] p_request Pointer to the outgoing request.
+ */
+void coap_observe_client_send_handle(coap_message_t * p_request);
+
+/**@brief Observe client function to be run when response message has been received.
+ *
+ * @details The function will register and unregister observable resources based on the received
+ * response messages. Upon a notification max-age values will be updated, and the correct
+ * response callback will be called. If a notification is terminated by the peer, the function
+ * will automatically terminate the subscription from the client by unregistering the
+ * observable resource.
+ *
+ * @param[in] p_response Pointer to the response message received.
+ * @param[in] p_item Pointer to the queued element of the outgoing request.
+ */
+void coap_observe_client_response_handle(coap_message_t * p_response, coap_queue_item_t * p_item);
+
+#else // COAP_ENABLE_OBSERVE_CLIENT
+
+#define coap_observe_client_send_handle(...)
+#define coap_observe_client_response_handle(...)
+
+#endif // COAP_ENABLE_OBSERVE_CLIENT
+
+/**@endcond */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // COAP_OBSERVE_H__
+
+/** @} */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/coap/coap_observe_api.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/coap/coap_observe_api.h
new file mode 100644
index 0000000..3075e88
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/coap/coap_observe_api.h
@@ -0,0 +1,222 @@
+/**
+ * Copyright (c) 2015 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 coap_observe_api.h
+ *
+ * @defgroup iot_sdk_coap_observe CoAP Observe
+ * @ingroup iot_sdk_coap
+ * @{
+ * @brief Public API of Nordic's CoAP Observe implementation.
+ */
+#ifndef COAP_OBSERVE_API_H__
+#define COAP_OBSERVE_API_H__
+
+#include <stdint.h>
+#include "coap_api.h"
+#include "coap_transport.h"
+#include "coap_queue.h"
+#include "compiler_abstraction.h"
+#include "sdk_errors.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define COAP_OPT_OBSERVE 6 /**< Observe option number. */
+
+/**@brief Struct for CoAP Server for holding an instance of a remote observer. */
+typedef struct
+{
+ coap_remote_t remote; /**< Remote address and port number. */
+ uint8_t token[8]; /**< Message Token ID. */
+ uint8_t token_len; /**< Length of the token. */
+ coap_content_type_t ct; /**< Content type to use when sending notifications. */
+ coap_resource_t * p_resource_of_interest; /**< Pointer to the resource of interest. */
+} coap_observer_t;
+
+/**@brief Struct for CoAP Client for holding an instance of a remote observable resource. */
+typedef struct
+{
+ coap_remote_t remote; /**< Remote address and port number. */
+ uint8_t token[8]; /**< Message Token ID. */
+ uint8_t token_len; /**< Length of the token. */
+ coap_response_callback_t response_callback; /**< Function callback set by the application to be called when a notifications has been received. Should be set by the application. */
+ uint32_t max_age; /**< Max-Age of the observable resources value. If timed out, the value is no longer valid as a representation of the observable resource. */
+} coap_observable_t;
+
+
+/**@brief Register a new observer.
+ *
+ * @param[out] p_handle Handle to the observer instance registered. Returned by reference.
+ * Should not be NULL.
+ * @param[in] p_observer Pointer to the observer structure to register. The data will be
+ * copied. Should not be NULL.
+ *
+ * @retval NRF_SUCCESS If the observer was registered successfully.
+ * @retval NRF_ERROR_NO_MEM If the observer could not be added to the list.
+ * @retval NRF_ERROR_NULL If one of the parameters is a NULL pointer.
+ */
+uint32_t coap_observe_server_register(uint32_t * p_handle, coap_observer_t * p_observer);
+
+/**@brief Unregister an observer.
+ *
+ * @details Unregister the observer and clear the memory used by this instance.
+ *
+ * @param[in] handle Handle to the observer instance registered.
+ *
+ * @retval NRF_SUCCESS If the observer was successfully unregistered.
+ * @retval NRF_ERROR_NOT_FOUND If the given handle was not found in the observer list.
+ */
+uint32_t coap_observe_server_unregister(uint32_t handle);
+
+/**@brief Search the observer list for an observer matching remote address and subject given.
+ *
+ * @param[out] p_handle Handle to the observer instance registered. Returned by reference.
+ * Should not be NULL.
+ * @param[in] p_observer_addr Pointer to an address structure giving remote address of the observer and port number.
+ * Should not be NULL.
+ * @param[in] p_resource Pointer to the resource the observer is registered to. Should not be NULL.
+ *
+ * @retval NRF_SUCCESS If observer was found in the observer list.
+ * @retval NRF_ERROR_NULL If one of the pointers are NULL.
+ * @retval NRF_ERROR_NOT_FOUND If observer was not found.
+ */
+uint32_t coap_observe_server_search(uint32_t * p_handle, coap_remote_t * p_observer_addr, coap_resource_t * p_resource);
+
+/**@brief Iterate through observers subscribing to a specific resource.
+ *
+ * @param[out] pp_observer Pointer to be filled by the search function upon finding the next observer starting from
+ * from the p_observer pointer provided. Should not be NULL.
+ * @param[in] p_observer Pointer to the observer where to start the search.
+ * @param[in] p_resource Pointer to the resource of interest. Should not be NULL.
+ *
+ * @retval NRF_SUCCESS If observer was found.
+ * @retval NRF_ERROR_NULL If pp_observer or p_resource pointer is NULL.
+ * @retval NRF_ERROR_NOT_FOUND If next observer was not found.
+ */
+uint32_t coap_observe_server_next_get(coap_observer_t ** pp_observer, coap_observer_t * p_observer, coap_resource_t * p_resource);
+
+/**@brief Retrieve the observer based on handle.
+ *
+ * @param[in] handle Handle to the coap_observer_t instance.
+ * @param[out] pp_observer Pointer to an observer return by reference.
+ * Should not be NULL.
+ *
+ * @retval NRF_SUCCESS If observer was found in the observer list.
+ * @retval NRF_ERROR_NULL If pp_observer pointer is NULL.
+ * @retval NRF_ERROR_NOT_FOUND If observer associated with the handle was not found.
+ */
+uint32_t coap_observe_server_get(uint32_t handle, coap_observer_t ** pp_observer);
+
+/**@brief Register a new observable resource.
+ *
+ * @param[out] p_handle Handle to the observable resource instance registered. Returned by
+ * reference. Should not be NULL.
+ * @param[in] p_observable Pointer to a observable resource structure to register. The structure
+ * will be copied. Should not be NULL.
+ *
+ * @retval NRF_SUCCESS If the observable resource was registered successfully.
+ * @retval NRF_ERROR_NO_MEM If the observable resource could not be added to the list.
+ * @retval NRF_ERROR_NULL If one of the parameters is a NULL pointer.
+ */
+uint32_t coap_observe_client_register(uint32_t * p_handle, coap_observable_t * p_observable);
+
+/**@brief Unregister an observable resource.
+ *
+ * @details Unregister the observable resource and clear the memory used by this instance.
+ *
+ * @param[in] handle Handle to the observable resource instance registered.
+ *
+ * @retval NRF_SUCCESS If the observable resource was successfully unregistered.
+ * @retval NRF_ERROR_NOT_FOUND If the given handle was not found in the observable
+ * resource list.
+ */
+uint32_t coap_observe_client_unregister(uint32_t handle);
+
+/**@brief Search for a observable resource instance by token.
+ *
+ * @param[out] p_handle Handle to the observable resource instance registered. Returned by
+ * reference. Should not be NULL.
+ * @param[in] p_token Pointer to the byte array holding the token id. Should not be NULL.
+ * @param[in] token_len Length of the token.
+ *
+ * @retval NRF_SUCCESS If observable resource was found in the observable
+ * resource list.
+ * @retval NRF_ERROR_NULL If one of the pointers are NULL.
+ * @retval NRF_ERROR_NOT_FOUND If observable resource was not found in the observable
+ * resource list.
+ */
+uint32_t coap_observe_client_search(uint32_t * p_handle, uint8_t * p_token, uint16_t token_len);
+
+/**@brief Retrieve the observable resource based on handle.
+ *
+ * @param[in] handle Handle to the coap_observable_t instance.
+ * @param[out] pp_observable Pointer to an observable resource return by reference.
+ * Should not be NULL.
+ *
+ * @retval NRF_SUCCESS If observable resource was found in the observable
+ * resource list.
+ * @retval NRF_ERROR_NULL If pp_observable pointer is NULL.
+ * @retval NRF_ERROR_NOT_FOUND If observable resource associated with the handle
+ * was not found.
+ */
+uint32_t coap_observe_client_get(uint32_t handle, coap_observable_t ** pp_observable);
+
+/**@brief Iterate through observable resources.
+ *
+ * @param[out] pp_observable Pointer to be filled by the search function upon finding the next
+ * observable resource starting from from the pointer provided.
+ * Should not be NULL.
+ * @param[out] p_handle Handler to the observable resource found returned by reference. Should
+ * not be NULL.
+ * @param[in] p_observable Pointer to the observable resource where to start the search.
+ *
+ * @retval NRF_SUCCESS If observer was found.
+ * @retval NRF_ERROR_NULL If pp_observer or p_observer pointer is NULL.
+ * @retval NRF_ERROR_NOT_FOUND If next observer was not found.
+ */
+uint32_t coap_observe_client_next_get(coap_observable_t ** pp_observable, uint32_t * p_handle, coap_observable_t * p_observable);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // COAP_OBSERVE_API_H__
+
+/** @} */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/coap/coap_option.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/coap/coap_option.c
new file mode 100644
index 0000000..0ae74be
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/coap/coap_option.c
@@ -0,0 +1,182 @@
+/**
+ * Copyright (c) 2014 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#include <stdlib.h>
+#include <string.h>
+
+#include "coap_option.h"
+#include "iot_common.h"
+
+#if (COAP_DISABLE_API_PARAM_CHECK == 0)
+
+#define NULL_PARAM_CHECK(PARAM) \
+ if ((PARAM) == NULL) \
+ { \
+ return (NRF_ERROR_NULL | IOT_COAP_ERR_BASE); \
+ }
+
+#else
+
+#define NULL_PARAM_CHECK(PARAM)
+
+#endif // COAP_DISABLE_API_PARAM_CHECK
+
+uint32_t coap_opt_string_encode(uint8_t * p_encoded, uint16_t * p_length, uint8_t * p_string, uint16_t str_len)
+{
+ NULL_PARAM_CHECK(p_encoded);
+ NULL_PARAM_CHECK(p_length);
+ NULL_PARAM_CHECK(p_string);
+
+ if (str_len > *p_length)
+ {
+ return (NRF_ERROR_DATA_SIZE | IOT_COAP_ERR_BASE);
+ }
+
+ memcpy(p_encoded, p_string, str_len);
+
+ *p_length = str_len;
+
+ return NRF_SUCCESS;
+}
+
+uint32_t coap_opt_string_decode(uint8_t * p_string, uint16_t * p_length, uint8_t * p_encoded)
+{
+ return NRF_SUCCESS;
+}
+
+uint32_t coap_opt_uint_encode(uint8_t * p_encoded, uint16_t * p_length, uint32_t data)
+{
+ NULL_PARAM_CHECK(p_encoded);
+ NULL_PARAM_CHECK(p_length);
+
+ uint16_t byte_index = 0;
+
+ if (data <= UINT8_MAX)
+ {
+ if (*p_length < sizeof(uint8_t))
+ {
+ return (NRF_ERROR_DATA_SIZE | IOT_COAP_ERR_BASE);
+ }
+
+ p_encoded[byte_index++] = (uint8_t)data;
+ }
+ else if (data <= UINT16_MAX)
+ {
+ if (*p_length < sizeof(uint16_t))
+ {
+ return (NRF_ERROR_DATA_SIZE | IOT_COAP_ERR_BASE);
+ }
+
+ p_encoded[byte_index++] = (uint8_t)((data & 0xFF00) >> 8);
+ p_encoded[byte_index++] = (uint8_t)(data & 0x00FF);
+ }
+ else
+ {
+ if (*p_length < sizeof(uint32_t))
+ {
+ return (NRF_ERROR_DATA_SIZE | IOT_COAP_ERR_BASE);
+ }
+
+ p_encoded[byte_index++] = (uint8_t)((data & 0xFF000000) >> 24);
+ p_encoded[byte_index++] = (uint8_t)((data & 0x00FF0000) >> 16);
+ p_encoded[byte_index++] = (uint8_t)((data & 0x0000FF00) >> 8);
+ p_encoded[byte_index++] = (uint8_t)(data & 0x000000FF);
+ }
+
+
+
+ *p_length = byte_index;
+
+ return NRF_SUCCESS;
+}
+
+uint32_t coap_opt_uint_decode(uint32_t * p_data, uint16_t length, uint8_t * p_encoded)
+{
+ NULL_PARAM_CHECK(p_data);
+ NULL_PARAM_CHECK(p_encoded);
+
+ uint8_t byte_index = 0;
+ switch (length)
+ {
+ case 0:
+ {
+ *p_data = 0;
+ }
+ break;
+
+ case 1:
+ {
+ *p_data = 0;
+ *p_data |= p_encoded[byte_index++];
+ }
+ break;
+
+ case 2:
+ {
+ *p_data = 0;
+ *p_data |= (p_encoded[byte_index++] << 8);
+ *p_data |= (p_encoded[byte_index++]);
+ }
+ break;
+
+ case 3:
+ {
+ *p_data = 0;
+ *p_data |= (p_encoded[byte_index++] << 16);
+ *p_data |= (p_encoded[byte_index++] << 8);
+ *p_data |= (p_encoded[byte_index++]);
+ }
+ break;
+
+ case 4:
+ {
+ *p_data = 0;
+ *p_data |= (p_encoded[byte_index++] << 24);
+ *p_data |= (p_encoded[byte_index++] << 16);
+ *p_data |= (p_encoded[byte_index++] << 8);
+ *p_data |= (p_encoded[byte_index++]);
+ }
+ break;
+
+ default:
+ return (NRF_ERROR_INVALID_LENGTH | IOT_COAP_ERR_BASE);
+ }
+
+ return NRF_SUCCESS;
+}
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/coap/coap_option.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/coap/coap_option.h
new file mode 100644
index 0000000..3d5c5d9
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/coap/coap_option.h
@@ -0,0 +1,161 @@
+/**
+ * Copyright (c) 2014 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 coap_option.h
+ *
+ * @defgroup iot_sdk_coap_option CoAP Option
+ * @ingroup iot_sdk_coap
+ * @{
+ * @brief Nordic's CoAP Option APIs.
+ */
+
+#ifndef COAP_OPTION_H__
+#define COAP_OPTION_H__
+
+/*
+ +-----+---+---+---+---+----------------+--------+--------+----------+
+ | No. | C | U | N | R | Name | Format | Length | Default |
+ +-----+---+---+---+---+----------------+--------+--------+----------+
+ | 1 | x | | | x | If-Match | opaque | 0-8 | (none) |
+ | 3 | x | x | - | | Uri-Host | string | 1-255 | (see |
+ | | | | | | | | | below) |
+ | 4 | | | | x | ETag | opaque | 1-8 | (none) |
+ | 5 | x | | | | If-None-Match | empty | 0 | (none) |
+ | 7 | x | x | - | | Uri-Port | uint | 0-2 | (see |
+ | | | | | | | | | below) |
+ | 8 | | | | x | Location-Path | string | 0-255 | (none) |
+ | 11 | x | x | - | x | Uri-Path | string | 0-255 | (none) |
+ | 12 | | | | | Content-Format | uint | 0-2 | (none) |
+ | 14 | | x | - | | Max-Age | uint | 0-4 | 60 |
+ | 15 | x | x | - | x | Uri-Query | string | 0-255 | (none) |
+ | 17 | x | | | | Accept | uint | 0-2 | (none) |
+ | 20 | | | | x | Location-Query | string | 0-255 | (none) |
+ | 23 | x | x | - | - | Block2 | uint | 0-3 | (none) |
+ | 27 | x | x | - | - | Block1 | uint | 0-3 | (none) |
+ | 28 | | | x | | Size2 | uint | 0-4 | (none) |
+ | 35 | x | x | - | | Proxy-Uri | string | 1-1034 | (none) |
+ | 39 | x | x | - | | Proxy-Scheme | string | 1-255 | (none) |
+ | 60 | | | x | | Size1 | uint | 0-4 | (none) |
+ +-----+---+---+---+---+----------------+--------+--------+----------+
+*/
+
+#include <stdint.h>
+#include "coap_api.h"
+#include "nrf_error.h"
+#include "sdk_errors.h"
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+typedef enum
+{
+ COAP_OPT_FORMAT_EMPTY = 0,
+ COAP_OPT_FORMAT_STRING = 1,
+ COAP_OPT_FORMAT_OPAQUE = 2,
+ COAP_OPT_FORMAT_UINT = 3
+
+} coap_opt_format_t;
+
+
+/**@brief Encode zero-terminated string into utf-8 encoded string.
+ *
+ * @param[out] p_encoded Pointer to buffer that will be used to fill the
+ * encoded string into.
+ * @param[inout] p_length Length of the buffer provided. Will also be used to
+ * return the size of the used buffer.
+ * @param[in] p_string String to encode.
+ * @param[in] str_len Length of the string to encode.
+ *
+ * @retval NRF_SUCCESS Indicates that encoding was successful.
+ * @retval NRF_ERROR_DATA_SIZE Indicates that the buffer provided was not sufficient to
+ * successfully encode the data.
+ */
+uint32_t coap_opt_string_encode(uint8_t * p_encoded, uint16_t * p_length, uint8_t * p_string, uint16_t str_len);
+
+/**@brief Decode a utf-8 string into a zero-terminated string.
+ *
+ * @param[out] p_string Pointer to the string buffer where the decoded
+ * string will be placed.
+ * @param[inout] p_length p_length of the encoded string. Returns the size of the buffer
+ * used in bytes.
+ * @param[in] p_encoded Buffer to decode.
+ *
+ * @retval NRF_SUCCESS Indicates that decoding was successful.
+ * @retval NRF_ERROR_DATA_SIZE Indicates that the buffer provided was not sufficient to
+ * successfully dencode the data.
+ */
+uint32_t coap_opt_string_decode(uint8_t * p_string, uint16_t * p_length, uint8_t * p_encoded);
+
+/**@brief Encode a uint value into a uint8_t buffer in network byte order.
+ *
+ * @param[out] p_encoded Pointer to buffer that will be used to fill the
+ * encoded uint into.
+ * @param[inout] p_length Length of the buffer provided. Will also be used to
+ * return the size of the used buffer.
+ * @param[in] data uint value which could be anything from 1 to 4 bytes.
+ *
+ * @retval NRF_SUCCESS Indicates that encoding was successful.
+ * @retval NRF_ERROR_DATA_SIZE Indicates that the buffer provided was not sufficient to
+ * successfully encode the data.
+ */
+uint32_t coap_opt_uint_encode(uint8_t * p_encoded, uint16_t * p_length, uint32_t data);
+
+/**@brief Decode a uint encoded value in network byte order to a uint32_t value.
+ *
+ * @param[out] p_data Pointer to the uint32_t value where the decoded uint will
+ * be placed.
+ * @param[inout] length Size of the encoded value.
+ * @param[in] p_encoded uint value to be decoded into a uint32_t value.
+ *
+ * @retval NRF_SUCCESS Indicates that decoding was successful.
+ * @retval NRF_ERROR_NULL If p_data or p_encoded pointer is NULL.
+ * @retval NRF_ERROR_INVALID_LENGTH If buffer was greater than uint32_t.
+ */
+uint32_t coap_opt_uint_decode(uint32_t * p_data, uint16_t length, uint8_t * p_encoded);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // COAP_OPTION_H__
+
+/** @} */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/coap/coap_queue.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/coap/coap_queue.c
new file mode 100644
index 0000000..4e12bb6
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/coap/coap_queue.c
@@ -0,0 +1,182 @@
+/**
+ * Copyright (c) 2014 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#include <string.h>
+
+#include "coap_queue.h"
+#include "iot_common.h"
+#include "sdk_config.h"
+
+#if (COAP_DISABLE_API_PARAM_CHECK == 0)
+
+/**@brief Verify NULL parameters are not passed to API by application. */
+#define NULL_PARAM_CHECK(PARAM) \
+ if ((PARAM) == NULL) \
+ { \
+ return (NRF_ERROR_NULL | IOT_COAP_ERR_BASE); \
+ }
+#else
+
+#define NULL_PARAM_CHECK(PARAM)
+
+#endif // COAP_DISABLE_API_PARAM_CHECK
+
+static coap_queue_item_t m_queue[COAP_MESSAGE_QUEUE_SIZE];
+static uint8_t m_message_queue_count = 0;
+
+uint32_t coap_queue_init(void)
+{
+ for (uint8_t i = 0; i < COAP_MESSAGE_QUEUE_SIZE; i++)
+ {
+ memset(&m_queue[i], 0, sizeof(coap_queue_item_t));
+ m_queue[i].handle = i;
+ }
+ m_message_queue_count = 0;
+
+ return NRF_SUCCESS;
+}
+
+uint32_t coap_queue_add(coap_queue_item_t * item)
+{
+ NULL_PARAM_CHECK(item);
+
+ if (m_message_queue_count >= COAP_MESSAGE_QUEUE_SIZE)
+ {
+ return (NRF_ERROR_NO_MEM | IOT_COAP_ERR_BASE);
+ }
+ else
+ {
+ for (uint8_t i = 0; i < COAP_MESSAGE_QUEUE_SIZE; i++)
+ {
+ if (m_queue[i].p_buffer == NULL)
+ {
+ // Free spot in message queue. Add message here...
+ memcpy(&m_queue[i], item, sizeof(coap_queue_item_t));
+
+ m_message_queue_count++;
+
+ return NRF_SUCCESS;
+ }
+ }
+
+ }
+ return (NRF_ERROR_DATA_SIZE | IOT_COAP_ERR_BASE);
+}
+
+uint32_t coap_queue_remove(coap_queue_item_t * p_item)
+{
+ for (uint8_t i = 0; i < COAP_MESSAGE_QUEUE_SIZE; i++)
+ {
+ if (p_item == (coap_queue_item_t *)&m_queue[i])
+ {
+ memset(&m_queue[i], 0, sizeof(coap_queue_item_t));
+ m_message_queue_count--;
+ return NRF_SUCCESS;
+ }
+ }
+
+ return (NRF_ERROR_NOT_FOUND | IOT_COAP_ERR_BASE);
+}
+
+uint32_t coap_queue_item_by_token_get(coap_queue_item_t ** pp_item, uint8_t * p_token, uint8_t token_len)
+{
+ for (uint8_t i = 0; i < COAP_MESSAGE_QUEUE_SIZE; i++)
+ {
+ if (m_queue[i].token_len == token_len)
+ {
+ if ((0 != m_queue[i].token_len) &&
+ (memcmp(m_queue[i].token, p_token, m_queue[i].token_len) == 0))
+ {
+ *pp_item = &m_queue[i];
+ return NRF_SUCCESS;
+ }
+ }
+ }
+
+ return (NRF_ERROR_NOT_FOUND | IOT_COAP_ERR_BASE);
+}
+
+
+uint32_t coap_queue_item_by_mid_get(coap_queue_item_t ** pp_item, uint16_t message_id)
+{
+
+
+ for (uint8_t i = 0; i < COAP_MESSAGE_QUEUE_SIZE; i++)
+ {
+ if (m_queue[i].mid == message_id)
+ {
+ *pp_item = &m_queue[i];
+ return NRF_SUCCESS;
+ }
+ }
+
+ return (NRF_ERROR_NOT_FOUND | IOT_COAP_ERR_BASE);
+}
+
+
+uint32_t coap_queue_item_next_get(coap_queue_item_t ** pp_item, coap_queue_item_t * p_item)
+{
+ if (p_item == NULL)
+ {
+ for (uint8_t i = 0; i < COAP_MESSAGE_QUEUE_SIZE; i++)
+ {
+ if (m_queue[i].p_buffer != NULL)
+ {
+ (*pp_item) = &m_queue[i];
+ return NRF_SUCCESS;
+ }
+ }
+ }
+ else
+ {
+ uint8_t index_to_previous = (uint8_t)(((uint32_t)p_item - (uint32_t)m_queue) / (uint32_t)sizeof(coap_queue_item_t));
+
+ for (uint8_t i = index_to_previous + 1; i < COAP_MESSAGE_QUEUE_SIZE; i++)
+ {
+ if (m_queue[i].p_buffer != NULL)
+ {
+ (*pp_item) = &m_queue[i];
+ return NRF_SUCCESS;
+ }
+ }
+ }
+ (*pp_item) = NULL;
+
+ return (NRF_ERROR_NOT_FOUND | IOT_COAP_ERR_BASE);
+}
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/coap/coap_queue.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/coap/coap_queue.h
new file mode 100644
index 0000000..24c5db6
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/coap/coap_queue.h
@@ -0,0 +1,153 @@
+/**
+ * Copyright (c) 2014 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 coap_queue.h
+ *
+ * @defgroup iot_sdk_coap_queue CoAP Message Queue
+ * @ingroup iot_sdk_coap
+ * @{
+ * @brief TODO.
+ */
+
+#ifndef COAP_QUEUE_H__
+#define COAP_QUEUE_H__
+
+#include <stdint.h>
+
+#include "coap_transport.h"
+#include "coap_message.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef struct
+{
+ void * p_arg; /**< Miscellaneous pointer to application provided data that is associated with the message. Copied from the coap_message_t when creating the item. */
+ uint32_t handle; /**< Quick reference to the handle value of the current item. */
+ uint16_t mid; /**< Message ID. */
+ uint8_t token_len; /**< Message Token length. */
+ uint8_t token[8]; /**< Message Token value up to 8 bytes. */
+ uint8_t retrans_count; /**< Re-transmission attempt count. */
+ uint16_t timeout; /**< Time until new re-transmission attempt. */
+ uint16_t timeout_val; /**< Last timeout value used. */
+ coap_port_t port; /**< Source port to use when re-transmitting. */
+ uint8_t * p_buffer; /**< Pointer to the data buffer containing the encoded CoAP message. */
+ uint32_t buffer_len; /**< Size of the data buffer containing the encoded CoAP message. */
+ coap_remote_t remote; /**< Destination address and port number to the remote. */
+ coap_response_callback_t callback; /**< Callback function to be called upon response or transmission timeout. */
+} coap_queue_item_t;
+
+/**@brief Initilize the CoAP message queue.
+ *
+ * @retval NRF_SUCCESS If initialization completed successfully.
+ */
+uint32_t coap_queue_init(void);
+
+/**@brief Add item to the queue.
+ *
+ * @param[in] p_item Pointer to an item which to add to the queue. The function will copy all
+ * data provided.
+ *
+ * @retval NRF_SUCCESS If adding the item was successful.
+ * @retval NRF_ERROR_NO_MEM If max number of queued elements has been reached. This is
+ * configured by COAP_MESSAGE_QUEUE_SIZE in sdk_config.h.
+ * @retval NRF_ERROR_DATA_SIZE If the element could not be added.
+ */
+uint32_t coap_queue_add(coap_queue_item_t * p_item);
+
+/**@brief Remove item from the queue.
+ *
+ * @param[in] p_item Pointer to an item which to remove from the queue. Should not be NULL.
+ *
+ * @retval NRF_SUCCESS If the item was successfully removed from the queue.
+ * @retval NRF_ERROR_NULL If p_item pointer is NULL.
+ * @retval NRF_ERROR_NOT_FOUND If the item was not located in the queue.
+ */
+uint32_t coap_queue_remove(coap_queue_item_t * p_item);
+
+/**@brief Search for item by token.
+ *
+ * @details Search the items for any item matching the token.
+ *
+ * @param[out] pp_item Pointer to be filled by the function if item matching the token
+ * has been found. Should not be NULL.
+ * @param[in] p_token Pointer to token array to be matched.
+ * @param[in] token_len Length of the token to be matched.
+ *
+ * @retval NRF_SUCCESS If an item was successfully located.
+ * @retval NRF_ERROR_NULL If pp_item pointer is NULL.
+ * @retval NRF_ERROR_NOT_FOUND If no item was found.
+ */
+uint32_t coap_queue_item_by_token_get(coap_queue_item_t ** pp_item, uint8_t * p_token, uint8_t token_len);
+
+/**@brief Search for item by message id.
+ *
+ * @details Search the items for any item matching the message id.
+ *
+ * @param[out] pp_item Pointer to be filled by the funciton if item matching the message id
+ * has been found. Should not be NULL.
+ * @param[in] message_id Message id to be matched.
+ *
+ * @retval NRF_SUCCESS If an item was successfully located.
+ * @retval NRF_ERROR_NULL If pp_item pointer is NULL.
+ * @retval NRF_ERROR_NOT_FOUND If no item was found.
+ */
+uint32_t coap_queue_item_by_mid_get(coap_queue_item_t ** pp_item, uint16_t message_id);
+
+/**@brief Iterate through items.
+ *
+ * @param[out] pp_item Pointer to be filled by the search function upon finding the next
+ * queued item starting from the p_item pointer provided. Should
+ * not be NULL.
+ * @param[in] p_item Pointer to the item where to start the search.
+ *
+ * @retval NRF_SUCCESS If item was found.
+ * @retval NRF_ERROR_NULL If pp_item pointer is NULL.
+ * @retval NRF_ERROR_NOT_FOUND If next item was not found.
+ */
+uint32_t coap_queue_item_next_get(coap_queue_item_t ** pp_item, coap_queue_item_t * p_item);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // COAP_QUEUE_H__
+
+/** @} */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/coap/coap_resource.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/coap/coap_resource.c
new file mode 100644
index 0000000..b928e0c
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/coap/coap_resource.c
@@ -0,0 +1,274 @@
+/**
+ * Copyright (c) 2014 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#include <string.h>
+
+#include "coap_resource.h"
+#include "coap_api.h"
+#include "iot_common.h"
+#include "sdk_config.h"
+
+#define COAP_RESOURCE_MAX_AGE_INIFINITE 0xFFFFFFFF
+
+static coap_resource_t * mp_root_resource = NULL;
+static char m_scratch_buffer[(COAP_RESOURCE_MAX_NAME_LEN + 1) * COAP_RESOURCE_MAX_DEPTH + 6];
+
+#if (COAP_DISABLE_API_PARAM_CHECK == 0)
+
+/**@brief Verify NULL parameters are not passed to API by application. */
+#define NULL_PARAM_CHECK(PARAM) \
+ if ((PARAM) == NULL) \
+ { \
+ return (NRF_ERROR_NULL | IOT_COAP_ERR_BASE); \
+ }
+#else
+
+#define NULL_PARAM_CHECK(PARAM)
+
+#endif // COAP_DISABLE_API_PARAM_CHECK
+
+uint32_t coap_resource_init(void)
+{
+ mp_root_resource = NULL;
+ return NRF_SUCCESS;
+}
+
+uint32_t coap_resource_create(coap_resource_t * p_resource, const char * name)
+{
+ NULL_PARAM_CHECK(p_resource);
+ NULL_PARAM_CHECK(name);
+
+ if (strlen(name) > COAP_RESOURCE_MAX_NAME_LEN)
+ {
+ return (NRF_ERROR_DATA_SIZE | IOT_COAP_ERR_BASE);
+ }
+
+ memcpy(p_resource->name, name, strlen(name));
+
+ if (mp_root_resource == NULL)
+ {
+ mp_root_resource = p_resource;
+ }
+
+ p_resource->max_age = COAP_RESOURCE_MAX_AGE_INIFINITE;
+
+ return NRF_SUCCESS;
+}
+
+uint32_t coap_resource_child_add(coap_resource_t * p_parent, coap_resource_t * p_child)
+{
+ NULL_PARAM_CHECK(p_parent);
+ NULL_PARAM_CHECK(p_child);
+
+ if (p_parent->child_count == 0)
+ {
+ p_parent->p_front = p_child;
+ p_parent->p_tail = p_child;
+ }
+ else
+ {
+ coap_resource_t * p_last_sibling = p_parent->p_tail;
+ p_last_sibling->p_sibling = p_child;
+ p_parent->p_tail = p_child;
+ }
+
+ p_parent->child_count++;
+
+ return NRF_SUCCESS;
+}
+
+static uint32_t generate_path(uint16_t buffer_pos, coap_resource_t * p_current_resource, char * parent_path, uint8_t * string, uint16_t * length)
+{
+ uint32_t err_code = NRF_SUCCESS;
+
+ if (parent_path == NULL)
+ {
+ m_scratch_buffer[buffer_pos++] = '<';
+
+ if (p_current_resource->p_front != NULL)
+ {
+ coap_resource_t * next_child = p_current_resource->p_front;
+ do
+ {
+ err_code = generate_path(buffer_pos, next_child, m_scratch_buffer, string, length);
+ if (err_code != NRF_SUCCESS)
+ {
+ return err_code;
+ }
+ next_child = next_child->p_sibling;
+ } while (next_child != NULL);
+ }
+ }
+ else
+ {
+ uint16_t size = strlen(p_current_resource->name);
+ m_scratch_buffer[buffer_pos++] = '/';
+
+ memcpy(&m_scratch_buffer[buffer_pos], p_current_resource->name, size);
+ buffer_pos += size;
+
+ if (p_current_resource->p_front != NULL)
+ {
+ coap_resource_t * next_child = p_current_resource->p_front;
+ do
+ {
+ err_code = generate_path(buffer_pos, next_child, m_scratch_buffer, string, length);
+ if (err_code != NRF_SUCCESS)
+ {
+ return err_code;
+ }
+ next_child = next_child->p_sibling;
+ } while (next_child != NULL);
+ }
+
+ m_scratch_buffer[buffer_pos++] = '>';
+
+ // If the resource is observable, append 'obs;' token.
+ if ((p_current_resource->permission & COAP_PERM_OBSERVE) > 0)
+ {
+ memcpy(&m_scratch_buffer[buffer_pos], ";obs", 4);
+ buffer_pos += 4;
+ }
+
+ m_scratch_buffer[buffer_pos++] = ',';
+
+ if (buffer_pos <= (*length))
+ {
+ *length -= buffer_pos;
+ memcpy(&string[strlen((char *)string)], m_scratch_buffer, buffer_pos);
+ }
+ else
+ {
+ return (NRF_ERROR_DATA_SIZE | IOT_COAP_ERR_BASE);
+ }
+ }
+
+ return err_code;
+}
+
+uint32_t coap_resource_well_known_generate(uint8_t * string, uint16_t * length)
+{
+ NULL_PARAM_CHECK(string);
+ NULL_PARAM_CHECK(length);
+
+ if (mp_root_resource == NULL)
+ {
+ return (NRF_ERROR_INVALID_STATE | IOT_COAP_ERR_BASE);
+ }
+
+ memset(string, 0, *length);
+
+ uint32_t err_code = generate_path(0, mp_root_resource, NULL, string, length);
+
+ string[strlen((char *)string) - 1] = '\0'; // remove the last comma
+
+ return err_code;
+}
+
+static coap_resource_t * coap_resource_child_resolve(coap_resource_t * p_parent,
+ char * p_path)
+{
+ coap_resource_t * result = NULL;
+ if (p_parent->p_front != NULL)
+ {
+ coap_resource_t * sibling_in_question = p_parent->p_front;
+
+ do {
+ // Check if the sibling name match.
+ size_t size = strlen(sibling_in_question->name);
+ if (strncmp(sibling_in_question->name, p_path, size) == 0)
+ {
+ return sibling_in_question;
+ }
+ else
+ {
+ sibling_in_question = sibling_in_question->p_sibling;
+ }
+ } while (sibling_in_question != NULL);
+ }
+ return result;
+}
+
+uint32_t coap_resource_get(coap_resource_t ** p_resource, uint8_t ** pp_uri_pointers, uint8_t num_of_uris)
+{
+ if (mp_root_resource == NULL)
+ {
+ // Make sure pointer is set to NULL before returning.
+ *p_resource = NULL;
+ return (NRF_ERROR_INVALID_STATE | IOT_COAP_ERR_BASE);
+ }
+
+ coap_resource_t * p_current_resource = mp_root_resource;
+
+ // Every node should start at root.
+ for (uint8_t i = 0; i < num_of_uris; i++)
+ {
+ p_current_resource = coap_resource_child_resolve(p_current_resource, (char *)pp_uri_pointers[i]);
+
+ if (p_current_resource == NULL)
+ {
+ // Stop looping as this direction will not give anything more.
+ break;
+ }
+ }
+
+ if (p_current_resource != NULL)
+ {
+ *p_resource = p_current_resource;
+ return NRF_SUCCESS;
+ }
+
+ // If nothing has been found.
+ *p_resource = NULL;
+ return (NRF_ERROR_NOT_FOUND | IOT_COAP_ERR_BASE);
+}
+
+uint32_t coap_resource_root_get(coap_resource_t ** pp_resource)
+{
+ NULL_PARAM_CHECK(pp_resource);
+
+ if (mp_root_resource == NULL)
+ {
+ return (NRF_ERROR_NOT_FOUND | IOT_COAP_ERR_BASE);
+ }
+
+ *pp_resource = mp_root_resource;
+
+ return NRF_SUCCESS;
+}
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/coap/coap_resource.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/coap/coap_resource.h
new file mode 100644
index 0000000..d73ef1f
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/coap/coap_resource.h
@@ -0,0 +1,110 @@
+/**
+ * Copyright (c) 2014 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 coap_resource.h
+ *
+ * @defgroup iot_sdk_coap_resource CoAP Resource
+ * @ingroup iot_sdk_coap
+ * @{
+ * @brief Private API of Nordic's CoAP Resource implementation.
+ */
+
+#ifndef COAP_RESOURCE_H__
+#define COAP_RESOURCE_H__
+
+#include <stdint.h>
+#include "coap_api.h"
+#include "sdk_config.h"
+#include "coap_message.h"
+#include "nrf_error.h"
+#include "sdk_errors.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**@brief Initialize the CoAP resource module.
+ *
+ * @details This function will initialize the root element pointer to NULL.
+ * This way, a new root can be assigned registered. The first
+ * resource added will be set as the new root.
+ *
+ * @retval NRF_SUCCESS This function will always return success.
+ */
+uint32_t coap_resource_init(void);
+
+/**@brief Find a resource by traversing the resource names.
+ *
+ * @param[out] p_resource Located resource.
+ * @param[in] pp_uri_pointers Array of strings which forms the hierarchical path to the resource.
+ * @param[in] num_of_uris Number of URIs supplied through the path pointer list.
+ *
+ * @retval NRF_SUCCESS The resource was instance located.
+ * @retval NRF_ERROR_NOT_FOUND The resource was not located.
+ * @retval NRF_ERROR_INVALID_STATE If no resource has been registered.
+ */
+uint32_t coap_resource_get(coap_resource_t ** p_resource,
+ uint8_t ** pp_uri_pointers,
+ uint8_t num_of_uris);
+
+
+/**@brief Process the request related to the resource.
+ *
+ * @details When a request is received and the resource has successfully been located it
+ * will pass on to this function. The method in the request will be matched against
+ * what the service provides of method handling callbacks. If the request expects a
+ * response this will be provided as output from this function. The memory provided
+ * for the response must be provided from outside.
+ *
+ * @param[in] p_resource Resource that will handle the request.
+ * @param[in] p_request The request to be handled.
+ * @param[inout] p_response Response message which can be used by the resource populate
+ * the response message.
+ */
+uint32_t coap_resource_process_request(coap_resource_t * p_resource,
+ coap_message_t * p_request,
+ coap_message_t * p_response);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // COAP_MESSAGE_H__
+
+/** @} */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/coap/coap_transport.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/coap/coap_transport.h
new file mode 100644
index 0000000..b9fd597
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/coap/coap_transport.h
@@ -0,0 +1,165 @@
+/**
+ * Copyright (c) 2014 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 coap_transport.h
+ *
+ * @defgroup iot_sdk_coap_transport CoAP transport abstraction
+ * @ingroup iot_sdk_coap
+ * @{
+ * @brief The transport interface that the CoAP depends on for sending and receiving CoAP messages.
+ *
+ * @details While the interface is well defined and should not be altered, the implementation of the
+ * interface depends on the choice of IP stack. The only exception to this is the
+ * \ref coap_transport_read API. This API is implemented in the CoAP, and the transport layer is
+ * expected to call this function when data is received on one of the CoAP ports.
+ */
+
+#ifndef COAP_TRANSPORT_H__
+#define COAP_TRANSPORT_H__
+
+#include <stdint.h>
+#include <nrf_tls.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**@brief Port identification information. */
+typedef struct
+{
+ uint16_t port_number; /**< Port number. */
+} coap_port_t;
+
+
+/**@brief Remote endpoint. */
+typedef struct
+{
+ uint8_t addr[16]; /**< Address of the remote device. */
+ uint16_t port_number; /**< Remote port number. */
+} coap_remote_t;
+
+
+/**@brief Transport initialization information. */
+typedef struct
+{
+ coap_port_t * p_port_table; /**< Information about the ports being registered. Count is assumed to be COAP_PORT_COUNT. */
+ void * p_arg; /**< Public. Miscellaneous pointer to application provided data that should be passed to the transport. */
+} coap_transport_init_t;
+
+
+
+/**@brief Initializes the transport layer to have the data ports set up for CoAP.
+ *
+ * @param[in] p_param Port count and port numbers.
+ *
+ * @retval NRF_SUCCESS If initialization was successful. Otherwise, an error code that indicates the reason for the failure is returned.
+ */
+uint32_t coap_transport_init (const coap_transport_init_t * p_param);
+
+
+/**@brief Sends data on a CoAP endpoint or port.
+ *
+ * @param[in] p_port Port on which the data is to be sent.
+ * @param[in] p_remote Remote endpoint to which the data is targeted.
+ * @param[in] p_data Pointer to the data to be sent.
+ * @param[in] datalen Length of the data to be sent.
+ *
+ * @retval NRF_SUCCESS If the data was sent successfully. Otherwise, an error code that indicates the reason for the failure is returned.
+ */
+uint32_t coap_transport_write(const coap_port_t * p_port,
+ const coap_remote_t * p_remote,
+ const uint8_t * p_data,
+ uint16_t datalen);
+
+
+
+/**@brief Handles data received on a CoAP endpoint or port.
+ *
+ * This API is not implemented by the transport layer, but assumed to exist. This approach
+ * avoids unnecessary registering of callback and remembering it in the transport layer.
+ *
+ * @param[in] p_port Port on which the data is received.
+ * @param[in] p_remote Remote endpoint from which the data is received.
+ * @param[in] p_local Local endpoint on which the data is received.
+ * @param[in] result Indicates if the data was processed successfully by lower layers.
+ * Possible failures could be NRF_SUCCESS,
+ * UDP_BAD_CHECKSUM,
+ * UDP_TRUNCATED_PACKET, or
+ * UDP_MALFORMED_PACKET.
+ * @param[in] p_data Pointer to the data received.
+ * @param[in] datalen Length of the data received.
+ *
+ * @retval NRF_SUCCESS If the data was handled successfully. Otherwise, an error code that indicates the reason for the failure is returned.
+ *
+ */
+uint32_t coap_transport_read(const coap_port_t * p_port,
+ const coap_remote_t * p_remote,
+ const coap_remote_t * p_local,
+ uint32_t result,
+ const uint8_t * p_data,
+ uint16_t datalen);
+
+
+/**@brief Process loop to handle DTLS processing.
+ *
+ * @details The function handles any processing of encrypted packets.
+ * Some encryption libraries requires to be run in a processing
+ * loop. This function is called by the CoAP library everytime
+ * \ref coap_time_tick is issued from the library user. Any other process
+ * specific routines that should be done regularly could be added in
+ * this function.
+ */
+void coap_transport_process(void);
+
+/**@brief Process loop when using coap BSD socket transport implementation.
+ *
+ * @details This is blocking call. The function unblock is only
+ * triggered upon an socket event registered to select() by coap transport.
+ * This function must be called as often as possible in order to dispatch incomming
+ * socket events. Preferred to be put in the application's main loop or similar.
+ */
+void coap_transport_input(void);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif //COAP_TRANSPORT_H__
+
+/** @} */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/coap/coap_transport_dtls.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/coap/coap_transport_dtls.c
new file mode 100644
index 0000000..b1fe138
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/coap/coap_transport_dtls.c
@@ -0,0 +1,996 @@
+/**
+ * Copyright (c) 2014 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#include "nrf_error.h"
+#include "nrf_drv_rng.h"
+#include "sdk_config.h"
+#include "iot_common.h"
+#include "iot_pbuffer.h"
+#include "coap_transport.h"
+#include "coap.h"
+#include "udp_api.h"
+#include "nrf_tls.h"
+#include "mem_manager.h"
+#include "iot_errors.h"
+
+
+#if IOT_COAP_CONFIG_LOG_ENABLED
+
+#define NRF_LOG_MODULE_NAME coap_dtls
+
+#define NRF_LOG_LEVEL IOT_COAP_CONFIG_LOG_LEVEL
+#define NRF_LOG_INFO_COLOR IOT_COAP_CONFIG_INFO_COLOR
+#define NRF_LOG_DEBUG_COLOR IOT_COAP_CONFIG_DEBUG_COLOR
+
+#include "nrf_log.h"
+NRF_LOG_MODULE_REGISTER();
+
+#define COAPT_TRC NRF_LOG_DEBUG /**< Used for getting trace of execution in the module. */
+#define COAPT_ERR NRF_LOG_ERROR /**< Used for logging errors in the module. */
+#define COAPT_DUMP NRF_LOG_HEXDUMP_DEBUG /**< Used for dumping octet information to get details of bond information etc. */
+
+#define COAPT_ENTRY() COAPT_TRC(">> %s", __func__)
+#define COAPT_EXIT() COAPT_TRC("<< %s", __func__)
+#define COAPT_ENTRY_WITH_READLEN(read_len) COAPT_TRC(">> %s, readlen %d", __func__, read_len)
+#define COAPT_EXIT_WITH_RESULT(result) COAPT_TRC("<< %s, result 0x%08lX", __func__, result)
+
+#else // IOT_COAP_CONFIG_LOG_ENABLED
+
+#define COAPT_TRC(...) /**< Disables traces. */
+#define COAPT_DUMP(...) /**< Disables dumping of octet streams. */
+#define COAPT_ERR(...) /**< Disables error logs. */
+
+#define COAPT_ENTRY(...)
+#define COAPT_EXIT(...)
+#define COAPT_ENTRY_WITH_READLEN(...)
+#define COAPT_EXIT_WITH_RESULT(...)
+
+#endif // IOT_COAP_CONFIG_LOG_ENABLED
+
+/**@brief Max size to be requested from the DTLS library when polling for decoded CoAP data. */
+#define MAX_BUFFER_SIZE 1024
+
+
+/**@brief UDP port information. */
+typedef struct
+{
+ uint32_t socket_id; /**< Socket information provided by UDP. */
+ uint16_t port_number; /**< Associated port number. */
+ nrf_tls_key_settings_t * p_settings; /**< Key preferences. */
+} udp_port_t;
+
+/**@brief CoAP remote session. Encapsulates information needed for DTLS. */
+typedef struct
+{
+ nrf_tls_instance_t dtls_instance; /**< DTLS instance identifier. */
+ coap_remote_t remote_endpoint; /**< Remote endoint indentification. */
+ uint16_t local_port_index; /**< Identifies local endpoint assoicated with the session. */
+} coap_remote_session_t;
+
+/**@brief Possible CoAP transport types. Needed for internal handling of events and data. */
+typedef enum
+{
+ COAP_TRANSPORT_NON_SECURE_DATAGRAM = 0, /**< Non-secure transport, no DTLS procedures apply. */
+ COAP_TRANSPORT_SECURE_DATAGRAM = 1, /**< Secure transport, DTLS procedures apply. */
+ COAP_TRANSPORT_MAX_TYPES = 2 /**< Maximum transport types. Not a valid transport identifer used as max count. */
+} coap_transport_type_t;
+
+/**
+ * @brief Transport write handler signature.
+ *
+ * @param[in] p_remote Remote endpoint on which data is to be written.
+ * @param[in] local_port_index Local endpoint identifier writing the data.
+ * @param[in] p_data Data to be written.
+ * @param[in] datalen Length of data to be written.
+ *
+ * @retval NRF_SUCCESS if the procedure was successful, else an error code indicating reason for
+ * failure.
+ */
+typedef uint32_t (* port_write_t) (const coap_remote_t * const p_remote,
+ uint32_t local_port_index,
+ const uint8_t * p_data,
+ uint16_t datalen);
+
+/**
+ * @brief Transport read handler signature.
+ *
+ * @param[in] p_remote Remote endpoint which sent data.
+ * @param[in] local_port_index Local endpoint identifier to which the data was sent.
+ * @param[in] p_data Data read on the transport.
+ * @param[in] datalen Length of data read on the transport.
+ *
+ * @retval NRF_SUCCESS if the procedure was successful, else an error code indicating reason for
+ * failure.
+ */
+typedef uint32_t (* port_read_t) (const coap_remote_t * const p_remote,
+ uint32_t local_port_index,
+ uint32_t read_result,
+ const uint8_t * p_data,
+ uint16_t datalen);
+
+/** Forward declaration. */
+uint32_t non_secure_datagram_write (const coap_remote_t * const p_remote,
+ uint32_t local_port_index,
+ const uint8_t * p_data,
+ uint16_t datalen);
+
+/** Forward declaration. */
+uint32_t secure_datagram_write (const coap_remote_t * const p_remote,
+ uint32_t local_port_index,
+ const uint8_t * p_data,
+ uint16_t datalen);
+
+/** Forward declaration. */
+uint32_t non_secure_datagram_read (const coap_remote_t * const p_remote,
+ uint32_t local_port_index,
+ uint32_t read_result,
+ const uint8_t * p_data,
+ uint16_t datalen);
+
+/** Forward declaration. */
+uint32_t secure_datagram_read(const coap_remote_t * const p_remote,
+ uint32_t local_port_index,
+ uint32_t read_result,
+ const uint8_t * p_data,
+ uint16_t datalen);
+
+/** Forward declaration. */
+uint32_t dtls_output_handler(nrf_tls_instance_t const * p_instance,
+ uint8_t const * p_data,
+ uint32_t datalen);
+
+static udp_port_t m_port_table[COAP_PORT_COUNT]; /**< Table maintaining association between CoAP ports and corresponding UDP socket identifiers. */
+static coap_remote_session_t m_remote_session[COAP_DTLS_MAX_REMOTE_SESSION]; /**< Table for managing security sessions with remote endpoints. */
+
+/**@brief Table of transport write handlers. */
+const port_write_t port_write_fn[COAP_TRANSPORT_MAX_TYPES] =
+{
+ non_secure_datagram_write,
+ secure_datagram_write
+};
+
+/**@brief Table of transport read handlers. */
+const port_read_t port_read_fn[COAP_TRANSPORT_MAX_TYPES] =
+{
+ non_secure_datagram_read,
+ secure_datagram_read
+};
+
+
+/**
+ * @brief Searches the local port reference based on the port number.
+ *
+ * @param[out] p_index Pointer where local port refernce should be provided (if found).
+ * @param[in] port_query Port number for which local port reference is requested.
+ *
+ * @retval NRF_SUCCESS if procedure succeeded else NRF_ERROR_NOT_FOUND.
+ */
+static uint32_t local_port_index_get(uint32_t * p_index, uint16_t port_query)
+{
+ uint32_t local_port_index;
+
+ // Find local port index.
+ for (local_port_index = 0; local_port_index < COAP_PORT_COUNT; local_port_index++)
+ {
+ if (m_port_table[local_port_index].port_number == port_query)
+ {
+ break;
+ }
+ }
+
+ // If we could not find the local port requested in the port table.
+ if (local_port_index >= COAP_PORT_COUNT)
+ {
+ return NRF_ERROR_NOT_FOUND;
+ }
+
+ *p_index = local_port_index;
+
+ return NRF_SUCCESS;
+}
+
+
+/**
+ * @brief Session to be initialized/freed.
+ *
+ * @param[in] p_session Session
+ */
+static void remote_session_init(coap_remote_session_t * p_session)
+{
+ memset(p_session, 0, sizeof(coap_remote_session_t));
+ NRF_TLS_INTSANCE_INIT(&p_session->dtls_instance);
+}
+
+
+/**
+ * @brief Creates DTLS session between remote and local endpoint.
+ *
+ * @param[in] local_port_index Identifies local endpoint.
+ * @param[in] role Identifies DTLS role to be played (server or client).
+ * @param[in] p_remote Identifies remote endpoint.
+ * @param[in] p_settings Security settings to be used for the session.
+ * @param[out] pp_session Pointer to the session created (if any).
+ *
+ * @retval NRF_SUCCESS is procedure succeeded else an error code indicating reason for failure.
+ */
+static uint32_t session_create(uint32_t local_port_index,
+ nrf_tls_role_t role,
+ const coap_remote_t * const p_remote,
+ nrf_tls_key_settings_t * const p_settings,
+ coap_remote_session_t ** pp_session)
+{
+ uint32_t err_code = NRF_ERROR_NO_MEM;
+
+ for (uint32_t index = 0; index < COAP_DTLS_MAX_REMOTE_SESSION; index++)
+ {
+ if (m_remote_session[index].remote_endpoint.port_number == 0)
+ {
+ // Found free session.
+ m_remote_session[index].remote_endpoint.port_number = p_remote->port_number;
+ memcpy(m_remote_session[index].remote_endpoint.addr, p_remote->addr, IPV6_ADDR_SIZE);
+ m_remote_session[index].local_port_index = local_port_index;
+
+ // Attempt Allocate TLS session.
+ const nrf_tls_options_t dtls_options =
+ {
+ .output_fn = dtls_output_handler,
+ .transport_type = NRF_TLS_TYPE_DATAGRAM,
+ .role = role,
+ .p_key_settings = p_settings
+ };
+
+ m_remote_session[index].dtls_instance.transport_id = index;
+
+ COAP_MUTEX_UNLOCK();
+
+ err_code = nrf_tls_alloc(&m_remote_session[index].dtls_instance, &dtls_options);
+
+ COAP_MUTEX_LOCK();
+
+ COAPT_TRC("[%p]: nrf_tls_alloc result %08x",
+ &m_remote_session[index],
+ err_code);
+
+ // TLS allocation succeeded, book keep information for endpoint.
+ if (err_code == NRF_SUCCESS)
+ {
+ (*pp_session) = &m_remote_session[index];
+ break;
+ }
+ else
+ {
+ // If free the session and notify failure.
+ remote_session_init(&m_remote_session[index]);
+ }
+ }
+ }
+
+ return err_code;
+}
+
+
+/**
+ * @brief API to free TLS session.
+ *
+ * @param[in] p_session Identifies the session to be freed.
+ */
+static __INLINE void session_free (coap_remote_session_t * p_session)
+{
+ // Free TLS session.
+ UNUSED_VARIABLE(nrf_tls_free(&p_session->dtls_instance));
+
+ // Free the session.
+ remote_session_init(p_session);
+}
+
+
+/**
+ * @brief Searches for DTLS session between remote and local endpoint.
+ *
+ * @param[in] local_port_index Identifies local endpoint.
+ * @param[in] p_remote Identifies remote endpoint.
+ * @param[out] pp_session Pointer to the session found (if any).
+ *
+ * @retval NRF_SUCCESS is procedure succeeded else NRF_ERROR_NOT_FOUND.
+ */
+uint32_t remote_session_search(uint32_t local_port_index,
+ const coap_remote_t * p_remote,
+ coap_remote_session_t ** pp_session)
+{
+ uint32_t err_code = NRF_ERROR_NOT_FOUND;
+ uint32_t index = 0;
+
+
+ for (index = 0; index < COAP_DTLS_MAX_REMOTE_SESSION; index++)
+ {
+ const coap_remote_session_t * session = &m_remote_session[index];
+ if ((session->local_port_index == local_port_index) &&
+ (session->remote_endpoint.port_number == p_remote->port_number) &&
+ ((memcmp(session->remote_endpoint.addr, p_remote->addr, IPV6_ADDR_SIZE) == 0)))
+ {
+ // Entry exists.
+ (*pp_session) = (coap_remote_session_t *)session;
+ err_code = NRF_SUCCESS;
+ break;
+ }
+ }
+
+ return err_code;
+}
+
+
+/**
+ * @brief Provides transport type to be used between remote and local endpoint.
+ *
+ * @param[in] local_port_index Identifies local endpoint.
+ * @param[in] p_remote Identifies remote endpoint.
+ *
+ * @retval COAP_TRANSPORT_SECURE_DATAGRAM if transport type to be used is secure.
+ * @retval COAP_TRANSPORT_NON_SECURE_DATAGRAM if transport type to be used is non-secure.
+ */
+uint8_t get_transport_type(uint32_t local_port_index, const coap_remote_t * p_remote)
+{
+ coap_remote_session_t * p_session;
+ uint8_t transport_type = COAP_TRANSPORT_NON_SECURE_DATAGRAM;
+
+ uint32_t err_code = remote_session_search(local_port_index, p_remote, &p_session);
+ if (err_code == NRF_SUCCESS)
+ {
+ COAPT_TRC("Transport type = SECURE");
+ transport_type = COAP_TRANSPORT_SECURE_DATAGRAM;
+ }
+ else if (m_port_table[local_port_index].p_settings != NULL)
+ {
+ COAPT_TRC("Transport type = SECURE");
+ transport_type = COAP_TRANSPORT_SECURE_DATAGRAM;
+ }
+ else
+ {
+ COAPT_TRC("Transport type = NON-SECURE");
+ }
+
+ return transport_type;
+}
+
+
+/**@brief Callback handler to receive data on the UDP port.
+ *
+ * @details Callback handler to receive data on the UDP port.
+ *
+ * @param[in] p_socket Socket identifier.
+ * @param[in] p_ip_header IPv6 header containing source and destination addresses.
+ * @param[in] p_udp_header UDP header identifying local and remote endpoints.
+ * @param[in] process_result Result of data reception, there could be possible errors like
+ * invalid checksum etc.
+ * @param[in] iot_pbuffer_t Packet buffer containing the received data packet.
+ *
+ * @retval NRF_SUCCESS Indicates received data was handled successfully, else an an
+ * error code indicating reason for failure..
+ */
+static uint32_t port_data_callback(const udp6_socket_t * p_socket,
+ const ipv6_header_t * p_ip_header,
+ const udp6_header_t * p_udp_header,
+ uint32_t process_result,
+ iot_pbuffer_t * p_rx_packet)
+{
+ uint32_t index;
+ uint32_t retval = NRF_ERROR_NOT_FOUND;
+
+ COAPT_TRC("port_data_callback: Src Port %d Dest Port %d. Len %08lx",
+ p_udp_header->srcport, p_udp_header->destport, p_rx_packet->length);
+
+ COAP_MUTEX_LOCK();
+
+ //Search for the port.
+ for (index = 0; index < COAP_PORT_COUNT; index++)
+ {
+ if (m_port_table[index].socket_id == p_socket->socket_id)
+ {
+ COAPT_TRC("port_data_callback->coap_transport_read");
+
+ //Matching port found.
+ coap_remote_t remote_endpoint;
+
+ memcpy(remote_endpoint.addr, p_ip_header->srcaddr.u8, IPV6_ADDR_SIZE);
+ remote_endpoint.port_number = p_udp_header->srcport;
+
+ uint8_t transport_type = get_transport_type(index, &remote_endpoint);
+
+ // Handle read data on scoket based on nature of transport.
+ retval = port_read_fn[transport_type](&remote_endpoint,
+ index,
+ process_result,
+ p_rx_packet->p_payload,
+ p_rx_packet->length);
+ break;
+ }
+ }
+
+ COAP_MUTEX_UNLOCK();
+
+ return retval;
+}
+
+
+/**
+ * @brief Transport read handler for non secure transport type.
+ *
+ * @param[in] p_remote Remote endpoint which sent data.
+ * @param[in] local_port_index Local endpoint identifier to which the data was sent.
+ * @param[in] read_result Indicator result of data read on the transport.
+ * Likely failures include UDP checksum failure, truncated packet etc.
+ * @param[in] p_data Data read on the transport.
+ * @param[in] datalen Length of data read on the transport.
+ *
+ * @retval NRF_SUCCESS if the procedure was successful, else an error code indicating reason for
+ * failure.
+ */
+uint32_t non_secure_datagram_read (const coap_remote_t * const p_remote,
+ uint32_t local_port_index,
+ uint32_t read_result,
+ const uint8_t * p_data,
+ uint16_t datalen)
+{
+ const coap_port_t port =
+ {
+ .port_number = m_port_table[local_port_index].port_number
+ };
+
+ return coap_transport_read(&port,
+ p_remote,
+ NULL,
+ read_result,
+ p_data,
+ datalen);
+}
+
+
+/**
+ * @brief Transport write handler for non secure transport type.
+ *
+ * @param[in] p_remote Remote endpoint on which data is to be written.
+ * @param[in] local_port_index Local endpoint identifier writing the data.
+ * @param[in] p_data Data to be written.
+ * @param[in] datalen Length of data to be written.
+ *
+ * @retval NRF_SUCCESS if the procedure was successful, else an error code indicating reason for
+ * failure.
+ */
+uint32_t non_secure_datagram_write(const coap_remote_t * p_remote,
+ uint32_t index,
+ const uint8_t * p_data,
+ uint16_t datalen)
+{
+ uint32_t err_code;
+ udp6_socket_t socket;
+ ipv6_addr_t remote_addr;
+ iot_pbuffer_t * p_buffer;
+ iot_pbuffer_alloc_param_t buffer_param;
+
+ buffer_param.type = UDP6_PACKET_TYPE;
+ buffer_param.flags = PBUFFER_FLAG_DEFAULT;
+ buffer_param.length = datalen;
+
+ COAPT_TRC("[LP %04X]:[RP %04X]: port_write, datalen %d",
+ m_port_table[index].port_number,
+ p_remote->port_number,
+ datalen);
+
+ memcpy(remote_addr.u8, p_remote->addr, IPV6_ADDR_SIZE);
+
+ // Allocate buffer to send the data on port.
+ err_code = iot_pbuffer_allocate(&buffer_param, &p_buffer);
+
+ COAPT_TRC("port_write->iot_pbuffer_allocate result 0x%08X", err_code);
+
+ if (err_code == NRF_SUCCESS)
+ {
+ socket.socket_id = m_port_table[index].socket_id;
+
+ // Make a copy of the data onto the buffer.
+ memcpy(p_buffer->p_payload, p_data, datalen);
+
+ // Send on UDP port.
+ err_code = udp6_socket_sendto(&socket,
+ &remote_addr,
+ p_remote->port_number,
+ p_buffer);
+
+ COAPT_TRC("port_write->udp6_socket_sendto result 0x%08X", err_code);
+ if (err_code != NRF_SUCCESS)
+ {
+ // Free the allocated buffer as send procedure has failed.
+ UNUSED_VARIABLE(iot_pbuffer_free(p_buffer, true));
+ }
+ }
+
+ return err_code;
+}
+
+
+/**
+ * @brief Transport read handler for secure transport type.
+ *
+ * @param[in] p_remote Remote endpoint which sent data.
+ * @param[in] local_port_index Local endpoint identifier to which the data was sent.
+ * @param[in] read_result Indicator result of data read on the transport.
+ * Likely failures include UDP checksum failure, truncated packet etc.
+ * @param[in] p_data Data read on the transport.
+ * @param[in] datalen Length of data read on the transport.
+ *
+ * @retval NRF_SUCCESS if the procedure was successful, else an error code indicating reason for
+ * failure.
+ */
+uint32_t secure_datagram_read(const coap_remote_t * const p_remote,
+ uint32_t local_port_index,
+ uint32_t read_result,
+ const uint8_t * p_data,
+ uint16_t datalen)
+{
+ const uint32_t read_len = datalen;
+ uint32_t err_code;
+ coap_remote_session_t * p_session = NULL;
+
+ COAPT_ENTRY_WITH_READLEN(read_len);
+
+ // Search is a session exists.
+ err_code = remote_session_search(local_port_index, p_remote, &p_session);
+
+ if (err_code == NRF_SUCCESS)
+ {
+ COAPT_TRC("Remote session found, processing.");
+
+ COAP_MUTEX_UNLOCK();
+
+ // Session exists, send data to DTLS for decryption.
+ err_code = nrf_tls_input(&p_session->dtls_instance, p_data, read_len);
+
+ COAP_MUTEX_LOCK();
+ }
+ else
+ {
+ COAPT_TRC("Remote session not found, look for server security settings.");
+ if (m_port_table[local_port_index].p_settings != NULL)
+ {
+ // Allocate a session for incoming client.
+ err_code = session_create(local_port_index,
+ NRF_TLS_ROLE_SERVER,
+ p_remote,
+ m_port_table[local_port_index].p_settings,
+ &p_session);
+
+ if (err_code == NRF_SUCCESS)
+ {
+ COAP_MUTEX_UNLOCK();
+
+ COAPT_TRC("[%p]: New session created as DTLS server.", p_session);
+
+ err_code = nrf_tls_input(&p_session->dtls_instance, p_data, read_len);
+
+ COAP_MUTEX_LOCK();
+ }
+ else
+ {
+ COAPT_TRC("New session creation failed, reason 0x%08x.", err_code);
+ }
+ }
+ else
+ {
+ COAPT_TRC("No remote session, no server settings, processing as raw");
+ err_code = non_secure_datagram_read(p_remote,
+ local_port_index,
+ read_result,
+ p_data,
+ datalen);
+ }
+ }
+
+ COAPT_EXIT_WITH_RESULT(err_code);
+
+ return err_code;
+}
+
+
+/**
+ * @brief Transport write handler for secure transport type.
+ *
+ * @param[in] p_remote Remote endpoint on which data is to be written.
+ * @param[in] local_port_index Local endpoint identifier writing the data.
+ * @param[in] p_data Data to be written.
+ * @param[in] datalen Length of data to be written.
+ *
+ * @retval NRF_SUCCESS if the procedure was successful, else an error code indicating reason for
+ * failure.
+ */
+uint32_t secure_datagram_write(const coap_remote_t * const p_remote,
+ uint32_t local_port_index,
+ const uint8_t * p_data,
+ uint16_t datalen)
+{
+
+ uint32_t err_code;
+ coap_remote_session_t * p_session;
+
+ // Search is a session exists.
+ err_code = remote_session_search(local_port_index, p_remote, &p_session);
+
+ if (err_code == NRF_ERROR_NOT_FOUND)
+ {
+ // No session found, return error.
+ err_code = COAP_TRANSPORT_SECURITY_MISSING;
+ }
+ else
+ {
+ // Session exists, attempt a secure write.
+ uint32_t actual_len = datalen;
+ err_code = nrf_tls_write(&p_session->dtls_instance, p_data, &actual_len);
+ }
+
+ return err_code;
+}
+
+
+/**
+ * @brief Handles DTLS output to be sent on the underlying UDP transport.
+ *
+ * @param[in] p_instance Identifies the TLS instance associated with the output.
+ * @param[in] p_data DTLS library output data to be written on the transport.
+ * @param[in] datalen Length of data.
+ *
+ * @retval NRF_SUCCESS if the procedure was successful, else an error code indicating reason for
+ * failure.
+ */
+uint32_t dtls_output_handler(nrf_tls_instance_t const * p_instance,
+ uint8_t const * p_data,
+ uint32_t datalen)
+{
+ const uint16_t transport_write_len = datalen;
+
+ if (p_instance->transport_id >= COAP_DTLS_MAX_REMOTE_SESSION)
+ {
+ return NRF_ERROR_NOT_FOUND;
+ }
+
+ COAP_MUTEX_LOCK();
+
+ coap_remote_session_t * p_session = &m_remote_session[p_instance->transport_id];
+ uint32_t err_code = NRF_ERROR_NOT_FOUND;
+
+ if (p_session->remote_endpoint.port_number != 0)
+ {
+ // Search for instance in remote sessions.
+ err_code = non_secure_datagram_write(&p_session->remote_endpoint,
+ p_session->local_port_index,
+ p_data,
+ transport_write_len);
+ }
+
+ COAP_MUTEX_UNLOCK();
+
+ return err_code;
+}
+
+
+/**@brief Creates port as requested in p_port.
+ *
+ * @details Creates port as requested in p_port.
+ *
+ * @param[in] index Index to the m_port_table where entry of the port created is to be made.
+ * @param[in] p_port Port information to be created.
+ *
+ * @retval NRF_SUCCESS Indicates if port was created successfully, else an an error code
+ * indicating reason for failure.
+ */
+static uint32_t port_create(uint32_t index, coap_port_t * p_port)
+{
+ uint32_t err_code;
+ udp6_socket_t socket;
+
+ // Request new socket creation.
+ err_code = udp6_socket_allocate(&socket);
+
+ if (err_code == NRF_SUCCESS)
+ {
+ // Bind the socket to the local port.
+ err_code = udp6_socket_bind(&socket, IPV6_ADDR_ANY, p_port->port_number);
+
+ if (err_code == NRF_SUCCESS)
+ {
+ // Register data receive callback.
+ err_code = udp6_socket_recv(&socket, port_data_callback);
+
+ if (err_code == NRF_SUCCESS)
+ {
+ // All procedure with respect to port creation succeeded, make entry in the table.
+ m_port_table[index].socket_id = socket.socket_id;
+ m_port_table[index].port_number = p_port->port_number;
+ m_port_table[index].p_settings = NULL;
+
+ socket.p_app_data = &m_port_table[index];
+ UNUSED_VARIABLE(udp6_socket_app_data_set(&socket));
+ }
+ }
+
+ if (err_code != NRF_SUCCESS)
+ {
+ // Not all procedures succeeded with allocated socket, hence free it.
+ UNUSED_VARIABLE(udp6_socket_free(&socket));
+ }
+ }
+ return err_code;
+}
+
+
+uint32_t coap_transport_init(const coap_transport_init_t * p_param)
+{
+ uint32_t err_code = NRF_ERROR_NO_MEM;
+ uint32_t index;
+
+ NULL_PARAM_CHECK(p_param);
+ NULL_PARAM_CHECK(p_param->p_port_table);
+
+ err_code = nrf_tls_init();
+
+ if (err_code == NRF_SUCCESS)
+ {
+ for (index = 0; index < COAP_PORT_COUNT; index++)
+ {
+ // Create end point for each of the CoAP ports.
+ err_code = port_create(index, &p_param->p_port_table[index]);
+ if (err_code != NRF_SUCCESS)
+ {
+ break;
+ }
+ }
+
+ for (index = 0; index < COAP_DTLS_MAX_REMOTE_SESSION; index++)
+ {
+ remote_session_init(&m_remote_session[index]);
+ }
+ }
+
+ return err_code;
+}
+
+
+uint32_t coap_transport_write(const coap_port_t * p_port,
+ const coap_remote_t * p_remote,
+ const uint8_t * p_data,
+ uint16_t datalen)
+{
+ uint32_t err_code = NRF_ERROR_NOT_FOUND;
+ uint32_t index;
+
+ NULL_PARAM_CHECK(p_port);
+ NULL_PARAM_CHECK(p_remote);
+ NULL_PARAM_CHECK(p_data);
+
+ COAP_MUTEX_LOCK();
+
+ //Search for the corresponding port.
+ for (index = 0; index < COAP_PORT_COUNT; index++)
+ {
+ if (m_port_table[index].port_number == p_port->port_number)
+ {
+ // Get transport type for remote and local.
+ uint8_t transport_type = get_transport_type(index, p_remote);
+
+ err_code = port_write_fn[transport_type](p_remote,
+ index,
+ p_data,
+ datalen);
+ break;
+ }
+ }
+
+ COAP_MUTEX_UNLOCK();
+
+ return err_code;
+}
+
+
+void coap_transport_process(void)
+{
+ nrf_tls_process();
+
+ for (uint32_t index = 0; index < COAP_DTLS_MAX_REMOTE_SESSION; index++)
+ {
+ coap_remote_session_t * p_session = &m_remote_session[index];
+
+ if (p_session->remote_endpoint.port_number != 0x0000)
+ {
+ uint32_t datalen = MAX_BUFFER_SIZE;
+
+ COAP_MUTEX_UNLOCK();
+
+ // Check if there is data to be processed/read.
+ uint32_t err_code = nrf_tls_read(&p_session->dtls_instance, NULL, &datalen);
+
+ COAP_MUTEX_LOCK();
+
+ COAPT_TRC("nrf_tls_read result %d", err_code);
+
+ if ((err_code == NRF_SUCCESS) && (datalen > 0))
+ {
+ COAPT_TRC("nrf_tls_read datalen %d", datalen);
+
+ // Allocate memory and fecth data from DTLS layer.
+ uint8_t * p_data = NULL;
+ uint32_t buffer_size = datalen;
+
+ err_code = nrf_mem_reserve(&p_data, &buffer_size);
+
+ if (p_data != NULL)
+ {
+ COAP_MUTEX_UNLOCK();
+
+ err_code = nrf_tls_read(&p_session->dtls_instance, p_data, &datalen);
+
+ COAP_MUTEX_LOCK();
+
+ if ((err_code == NRF_SUCCESS) && (datalen > 0))
+ {
+ UNUSED_VARIABLE(non_secure_datagram_read(&p_session->remote_endpoint,
+ p_session->local_port_index,
+ NRF_SUCCESS,
+ p_data,
+ datalen));
+ }
+
+ // Free the memory reserved for the incoming packet.
+ nrf_free(p_data);
+ }
+ }
+ }
+ }
+}
+
+
+uint32_t coap_security_setup(uint16_t local_port,
+ nrf_tls_role_t role,
+ coap_remote_t * const p_remote,
+ nrf_tls_key_settings_t * const p_settings)
+{
+ uint32_t err_code = NRF_ERROR_NO_MEM;
+ uint32_t local_port_index;
+ coap_remote_session_t * p_session;
+
+ COAP_MUTEX_LOCK();
+
+ // Find local port index.
+ err_code = local_port_index_get(&local_port_index, local_port);
+
+ if (err_code == NRF_SUCCESS)
+ {
+ if (role == NRF_TLS_ROLE_CLIENT)
+ {
+ if (p_remote == NULL)
+ {
+ // Clients can never register session with wildcard remote.
+ err_code = NRF_ERROR_NULL;
+ }
+ else
+ {
+ // Search is a session exists.
+ err_code = remote_session_search(local_port_index, p_remote, &p_session);
+
+ if (err_code != NRF_SUCCESS)
+ {
+ // Session does not already exist, create one.
+ err_code = session_create(local_port_index,
+ role, p_remote,
+ p_settings,
+ &p_session);
+ }
+ }
+ }
+ else
+ {
+ // For server role, disallow client specific settings.
+ // This may not always be desired. But a constraint added in current design.
+ if (p_remote != NULL)
+ {
+ err_code = NRF_ERROR_INVALID_PARAM;
+ }
+ else
+ {
+ // Cannot overwrite settings.
+ if (m_port_table[local_port_index].p_settings != NULL)
+ {
+ err_code = NRF_ERROR_FORBIDDEN;
+ }
+ else
+ {
+ COAPT_TRC("[0x%08lx]: Server security setup successful",
+ local_port_index);
+
+ m_port_table[local_port_index].p_settings = p_settings;
+ }
+ }
+
+ }
+ }
+
+ COAP_MUTEX_UNLOCK();
+
+ return err_code;
+}
+
+
+uint32_t coap_security_destroy(uint16_t local_port,
+ coap_remote_t * const p_remote)
+{
+ uint32_t err_code;
+ coap_remote_session_t * p_session;
+ uint32_t local_port_index;
+
+ COAP_MUTEX_LOCK();
+
+ // Find local port index.
+ err_code = local_port_index_get(&local_port_index, local_port);
+
+ if (err_code == NRF_SUCCESS)
+ {
+ if (p_remote != NULL)
+ {
+ // Search is a session exists.
+ err_code = remote_session_search(local_port_index, p_remote, &p_session);
+
+ if (err_code == NRF_SUCCESS)
+ {
+ session_free(p_session);
+ }
+ }
+ else
+ {
+ // Remove all session associated with the local port if p_remote is NULL.
+ for (uint32_t index = 0; index < COAP_DTLS_MAX_REMOTE_SESSION ; index++)
+ {
+ if (m_remote_session[index].local_port_index == local_port_index)
+ {
+ session_free(&m_remote_session[index]);
+ }
+ }
+ }
+ }
+
+ COAP_MUTEX_UNLOCK();
+
+ return err_code;
+}
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/coap/coap_transport_ipv6.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/coap/coap_transport_ipv6.c
new file mode 100644
index 0000000..9cf4bdb
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/coap/coap_transport_ipv6.c
@@ -0,0 +1,264 @@
+/**
+ * Copyright (c) 2014 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#include "sdk_errors.h"
+#include "sdk_config.h"
+#include "iot_common.h"
+#include "iot_pbuffer.h"
+#include "coap_transport.h"
+#include "coap.h"
+#include "udp_api.h"
+
+
+/**@brief UDP port information. */
+typedef struct
+{
+ uint32_t socket_id; /**< Socket information provided by UDP. */
+ uint16_t port_number; /**< Associated port number. */
+} udp_port_t;
+
+static udp_port_t m_port_table[COAP_PORT_COUNT]; /**< Table maintaining association between CoAP ports and corresponding UDP socket identifiers. */
+
+
+/**@brief Callback handler to receive data on the UDP port.
+ *
+ * @details Callback handler to receive data on the UDP port.
+ *
+ * @param[in] p_socket Socket identifier.
+ * @param[in] p_ip_header IPv6 header containing source and destination addresses.
+ * @param[in] p_udp_header UDP header identifying local and remote endpoints.
+ * @param[in] process_result Result of data reception, there could be possible errors like
+ * invalid checksum etc.
+ * @param[in] iot_pbuffer_t Packet buffer containing the received data packet.
+ *
+ * @retval NRF_SUCCESS Indicates received data was handled successfully, else an an
+ * error code indicating reason for failure..
+ */
+static uint32_t port_data_callback(const udp6_socket_t * p_socket,
+ const ipv6_header_t * p_ip_header,
+ const udp6_header_t * p_udp_header,
+ uint32_t process_result,
+ iot_pbuffer_t * p_rx_packet)
+{
+ uint32_t index;
+ uint32_t retval = NRF_ERROR_NOT_FOUND;
+
+ //Search for the port.
+ for (index = 0; index < COAP_PORT_COUNT; index++)
+ {
+ //Matching port found.
+ if (m_port_table[index].socket_id == p_socket->socket_id)
+ {
+ coap_remote_t remote_endpoint;
+ coap_remote_t local_endpoint;
+ const coap_port_t port = {p_udp_header->destport};
+
+ memcpy (remote_endpoint.addr, p_ip_header->srcaddr.u8, IPV6_ADDR_SIZE);
+ remote_endpoint.port_number = p_udp_header->srcport;
+
+ memcpy (local_endpoint.addr, p_ip_header->destaddr.u8, IPV6_ADDR_SIZE);
+ local_endpoint.port_number = p_udp_header->destport;
+
+ COAP_MUTEX_LOCK();
+
+ //Notify the module of received data.
+ retval = coap_transport_read(&port,
+ &remote_endpoint,
+ &local_endpoint,
+ process_result,
+ p_rx_packet->p_payload,
+ p_rx_packet->length);
+
+ COAP_MUTEX_UNLOCK();
+ }
+ }
+
+ return retval;
+}
+
+
+/**@brief Creates port as requested in p_port.
+ *
+ * @details Creates port as requested in p_port.
+ *
+ * @param[in] index Index to the m_port_table where entry of the port created is to be made.
+ * @param[in] p_port Port information to be created.
+ *
+ * @retval NRF_SUCCESS Indicates if port was created successfully, else an an error code
+ * indicating reason for failure.
+ */
+static uint32_t port_create(uint32_t index, coap_port_t * p_port)
+{
+ uint32_t err_code;
+ udp6_socket_t socket;
+
+ //Request new socket creation.
+ err_code = udp6_socket_allocate(&socket);
+
+ if (err_code == NRF_SUCCESS)
+ {
+ // Bind the socket to the local port.
+ err_code = udp6_socket_bind(&socket, IPV6_ADDR_ANY, p_port->port_number);
+ if (err_code == NRF_SUCCESS)
+ {
+ //Register data receive callback.
+ err_code = udp6_socket_recv(&socket, port_data_callback);
+ if (err_code == NRF_SUCCESS)
+ {
+ //All procedure with respect to port creation succeeded, make entry in the table.
+ m_port_table[index].socket_id = socket.socket_id;
+ m_port_table[index].port_number = p_port->port_number;
+ socket.p_app_data = &m_port_table[index];
+ UNUSED_VARIABLE(udp6_socket_app_data_set(&socket));
+ }
+ }
+
+ if (err_code != NRF_SUCCESS)
+ {
+ //Not all procedures succeeded with allocated socket, hence free it.
+ UNUSED_VARIABLE(udp6_socket_free(&socket));
+ }
+ }
+ return err_code;
+}
+
+
+uint32_t coap_transport_init(const coap_transport_init_t * p_param)
+{
+ uint32_t err_code = NRF_ERROR_NO_MEM;
+ uint32_t index;
+
+ NULL_PARAM_CHECK(p_param);
+ NULL_PARAM_CHECK(p_param->p_port_table);
+
+ for (index = 0; index < COAP_PORT_COUNT; index++)
+ {
+ // Create end point for each of the CoAP ports.
+ err_code = port_create(index, &p_param->p_port_table[index]);
+ if (err_code != NRF_SUCCESS)
+ {
+ break;
+ }
+ }
+
+ return err_code;
+}
+
+
+uint32_t coap_transport_write(const coap_port_t * p_port,
+ const coap_remote_t * p_remote,
+ const uint8_t * p_data,
+ uint16_t datalen)
+{
+ uint32_t err_code = NRF_ERROR_NOT_FOUND;
+ uint32_t index;
+ udp6_socket_t socket;
+ ipv6_addr_t remote_addr;
+ iot_pbuffer_t * p_buffer;
+ iot_pbuffer_alloc_param_t buffer_param;
+
+ NULL_PARAM_CHECK(p_port);
+ NULL_PARAM_CHECK(p_remote);
+ NULL_PARAM_CHECK(p_data);
+
+ memcpy(remote_addr.u8, p_remote->addr, 16);
+
+
+ buffer_param.type = UDP6_PACKET_TYPE;
+ buffer_param.flags = PBUFFER_FLAG_DEFAULT;
+ buffer_param.length = datalen;
+
+ //Search for the corresponding port.
+ for (index = 0; index < COAP_PORT_COUNT; index ++)
+ {
+ if (m_port_table[index].port_number == p_port->port_number)
+ {
+ //Allocate buffer to send the data on port.
+ err_code = iot_pbuffer_allocate(&buffer_param, &p_buffer);
+
+ if (err_code == NRF_SUCCESS)
+ {
+ socket.socket_id = m_port_table[index].socket_id;
+
+ //Make a copy of the data onto the buffer.
+ memcpy (p_buffer->p_payload, p_data, datalen);
+
+ COAP_MUTEX_UNLOCK();
+
+ //Send on UDP port.
+ err_code = udp6_socket_sendto(&socket,
+ &remote_addr,
+ p_remote->port_number,
+ p_buffer);
+
+ COAP_MUTEX_LOCK();
+
+ if (err_code != NRF_SUCCESS)
+ {
+ //Free the allocated buffer as send procedure has failed.
+ UNUSED_VARIABLE(iot_pbuffer_free(p_buffer, true));
+ }
+ }
+ break;
+ }
+ }
+
+ return err_code;
+}
+
+
+void coap_transport_process(void)
+{
+ return;
+}
+
+uint32_t coap_security_setup(uint16_t local_port,
+ nrf_tls_role_t role,
+ coap_remote_t * const p_remote,
+ nrf_tls_key_settings_t * const p_settings)
+{
+ return NRF_ERROR_API_NOT_IMPLEMENTED;
+}
+
+
+uint32_t coap_security_destroy(uint16_t local_port,
+ coap_remote_t * const p_remote)
+{
+ return NRF_ERROR_API_NOT_IMPLEMENTED;
+}
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/coap/coap_transport_lwip.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/coap/coap_transport_lwip.c
new file mode 100644
index 0000000..6245a97
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/coap/coap_transport_lwip.c
@@ -0,0 +1,255 @@
+/**
+ * Copyright (c) 2014 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#include <stdint.h>
+#include "sdk_errors.h"
+#include "sdk_config.h"
+#include "iot_common.h"
+#include "coap_transport.h"
+#include "coap.h"
+#include "lwip/ip6_addr.h"
+/*lint -save -e607 Suppress warning 607 "Parameter p of macro found within string" */
+#include "lwip/udp.h"
+/*lint -restore */
+
+
+/**@brief UDP port information. */
+typedef struct
+{
+ struct udp_pcb * p_socket; /**< Socket information provided by UDP. */
+ uint16_t port_number; /**< Associated port number. */
+}udp_port_t;
+
+static udp_port_t m_port_table[COAP_PORT_COUNT]; /**< Table maintaining association between CoAP ports and corresponding UDP socket identifiers. */
+
+
+/**@brief Callback handler to receive data on the UDP port.
+ *
+ * @details Callback handler to receive data on the UDP port.
+ *
+ * @param[in] p_arg Receive argument associated with the UDP socket.
+ * @param[in] p_socket Socket identifier.
+ * @param[in] p_ip_header IPv6 header containing source and destination addresses.
+ * @param[in] p_remote_addr IPv6 address of the remote device.
+ * @param[in] port Port number identifying the remote endpoint.
+ *
+ * @retval NRF_SUCCESS Indicates received data was handled successfully, else an an
+ * error code indicating reason for failure.
+ */
+static void udp_recv_data_handler(void * p_arg,
+ struct udp_pcb * p_socket,
+ struct pbuf * p_buffer,
+ const ip6_addr_t * p_remote_addr,
+ u16_t port)
+{
+ uint32_t index;
+ coap_remote_t remote_endpoint;
+ coap_port_t local_port = {p_socket->local_port};
+
+ for (index = 0; index < COAP_PORT_COUNT; index++)
+ {
+ if (m_port_table[index].p_socket == p_socket)
+ {
+ memcpy (remote_endpoint.addr, p_remote_addr, 16);
+ remote_endpoint.port_number = port;
+
+ COAP_MUTEX_LOCK();
+
+ UNUSED_VARIABLE(coap_transport_read(&local_port,
+ &remote_endpoint,
+ NULL,
+ NRF_SUCCESS,
+ (uint8_t *)p_buffer->payload,
+ (uint32_t)p_buffer->len));
+
+ COAP_MUTEX_UNLOCK();
+
+ break;
+ }
+ }
+
+ //Freeing packet (irrespective of matching p_socket is found or not
+ //to avoid memory leaks in the system.
+ UNUSED_VARIABLE(pbuf_free(p_buffer));
+}
+
+
+/**@brief Creates port as requested in p_port.
+ *
+ * @details Creates port as requested in p_port.
+ *
+ * @param[in] index Index to the m_port_table where entry of the port created is to be made.
+ * @param[in] p_port Port information to be created.
+ *
+ * @retval NRF_SUCCESS Indicates if port was created successfully, else an an error code
+ * indicating reason for failure.
+ */
+static uint32_t port_create(uint32_t index, coap_port_t * p_port)
+{
+ err_t err = NRF_ERROR_NO_MEM;
+ ip6_addr_t any_addr;
+ struct udp_pcb * p_socket = m_port_table[index].p_socket;
+
+ ip6_addr_set_any(&any_addr);
+
+ //Request new socket creation.
+ p_socket = udp_new();
+
+ if (NULL != p_socket)
+ {
+ // Bind the socket to the local port.
+ err = udp_bind(p_socket, &any_addr, p_port->port_number);
+ if (err == ERR_OK)
+ {
+ //Register data receive callback.
+ udp_recv(p_socket, udp_recv_data_handler, &m_port_table[index]);
+ //All procedure with respect to port creation succeeded, make entry in the table.
+ m_port_table[index].port_number = p_port->port_number;
+ m_port_table[index].p_socket = p_socket;
+ }
+ else
+ {
+ //Not all procedures succeeded with allocated socket, hence free it.
+ err = NRF_ERROR_INVALID_PARAM;
+ udp_remove(p_socket);
+ }
+ }
+
+ return err;
+}
+
+
+uint32_t coap_transport_init(const coap_transport_init_t * p_param)
+{
+ uint32_t err_code = NRF_SUCCESS;
+ uint32_t index;
+
+ NULL_PARAM_CHECK(p_param);
+ NULL_PARAM_CHECK(p_param->p_port_table);
+
+ for (index = 0; index < COAP_PORT_COUNT; index++)
+ {
+ // Create end point for each of the COAP ports.
+ err_code = port_create(index, &p_param->p_port_table[index]);
+ if (err_code != NRF_SUCCESS)
+ {
+ break;
+ }
+ }
+
+ return err_code;
+}
+
+
+uint32_t coap_transport_write(const coap_port_t * p_port,
+ const coap_remote_t * p_remote,
+ const uint8_t * p_data,
+ uint16_t datalen)
+{
+
+ err_t err = NRF_ERROR_NOT_FOUND;
+ uint32_t index;
+
+ NULL_PARAM_CHECK(p_port);
+ NULL_PARAM_CHECK(p_remote);
+ NULL_PARAM_CHECK(p_data);
+
+ //Search for the corresponding port.
+ for (index = 0; index < COAP_PORT_COUNT; index++)
+ {
+ if (m_port_table[index].port_number == p_port->port_number)
+ {
+ //Allocate Buffer to send the data on port.
+ struct pbuf * lwip_buffer = pbuf_alloc(PBUF_TRANSPORT, datalen, PBUF_RAM);
+
+ if (NULL != lwip_buffer)
+ {
+ //Make a copy of the data onto the buffer.
+ memcpy(lwip_buffer->payload, p_data, datalen);
+
+ COAP_MUTEX_UNLOCK();
+
+ //Send on UDP port.
+ err = udp_sendto(m_port_table[index].p_socket,
+ lwip_buffer,
+ (ip6_addr_t *)p_remote->addr,
+ p_remote->port_number);
+
+ COAP_MUTEX_LOCK();
+
+
+ if (err != ERR_OK)
+ {
+ //Free the allocated buffer as send procedure has failed.
+ err = NRF_ERROR_INTERNAL;
+ }
+ UNUSED_VARIABLE(pbuf_free(lwip_buffer));
+ }
+ else
+ {
+ //Buffer allocation failed, cannot send data.
+ err = NRF_ERROR_NO_MEM;
+ }
+ break;
+ }
+ }
+ return err;
+}
+
+
+void coap_transport_process(void)
+{
+ return;
+}
+
+
+uint32_t coap_security_setup(uint16_t local_port,
+ nrf_tls_role_t role,
+ coap_remote_t * const p_remote,
+ nrf_tls_key_settings_t * const p_settings)
+{
+ return NRF_ERROR_API_NOT_IMPLEMENTED;
+}
+
+
+uint32_t coap_security_destroy(uint16_t local_port,
+ coap_remote_t * const p_remote)
+{
+ return NRF_ERROR_API_NOT_IMPLEMENTED;
+}
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/coap/coap_transport_socket.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/coap/coap_transport_socket.c
new file mode 100644
index 0000000..d19737f
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/coap/coap_transport_socket.c
@@ -0,0 +1,292 @@
+/**
+ * Copyright (c) 2014 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#include <sys/socket.h>
+#include <sys/select.h>
+#include <netinet/in.h>
+#ifdef UNIX
+#include <fcntl.h>
+#endif
+#include <errno.h>
+#include <stdint.h>
+#include "mem_manager.h"
+#include "sdk_errors.h"
+#include "sdk_config.h"
+#include "iot_common.h"
+#include "nordic_common.h"
+#include "coap_transport.h"
+#include "coap.h"
+
+/**@brief UDP port information. */
+typedef struct
+{
+ int socket_fd; /**< Socket information provided by UDP. */
+ uint16_t port_number; /**< Associated port number. */
+} udp_port_t;
+
+static udp_port_t m_port_table[COAP_PORT_COUNT]; /**< Table maintaining association between CoAP ports and corresponding UDP socket identifiers. */
+
+static fd_set m_readfds;
+static int m_max_sd = 0;
+
+/**@brief Creates port as requested in p_port.
+ *
+ * @details Creates port as requested in p_port.
+ *
+ * @param[in] index Index to the m_port_table where entry of the port created is to be made.
+ * @param[in] p_port Port information to be created.
+ *
+ * @retval NRF_SUCCESS Indicates if port was created successfully, else an an error code
+ * indicating reason for failure.
+ */
+static uint32_t port_create(uint32_t index, coap_port_t * p_port)
+{
+ // Request new socket creation.
+ int socket_fd = socket(AF_INET6, SOCK_DGRAM, IPPROTO_UDP);
+
+ if (socket_fd != -1)
+ {
+ // Bind the socket to the local port.
+ struct sockaddr_in6 sin6;
+
+ memset(&sin6, 0, sizeof(struct sockaddr_in6));
+ sin6.sin6_family = AF_INET6;
+ sin6.sin6_port = htons(p_port->port_number);
+ sin6.sin6_addr = in6addr_any;
+
+ int retval = bind(socket_fd, (struct sockaddr *)&sin6, sizeof(sin6));
+ if (retval != -1)
+ {
+ m_port_table[index].port_number = p_port->port_number;
+ m_port_table[index].socket_fd = socket_fd;
+ }
+ else
+ {
+ // Not all procedures succeeded with allocated socket, hence free it.
+ UNUSED_VARIABLE(close(socket_fd));
+ return NRF_ERROR_INVALID_PARAM;
+ }
+ }
+
+ // Configure socket to be non-blocking.
+ int flags = fcntl(socket_fd, F_GETFL, 0);
+ flags |= O_NONBLOCK;
+ UNUSED_VARIABLE(fcntl(m_port_table[index].socket_fd, F_SETFL, flags));
+
+ // Add socket to file descriptor set.
+ FD_SET(m_port_table[index].socket_fd, &m_readfds);
+
+ // If enumeration is having a gap, increase the max fd count.
+ if (socket_fd >= m_max_sd)
+ {
+ m_max_sd = (socket_fd + 1);
+ }
+
+ return NRF_SUCCESS;
+}
+
+
+uint32_t coap_transport_init(const coap_transport_init_t * p_param)
+{
+ uint32_t err_code = NRF_SUCCESS;
+ uint32_t index;
+
+ NULL_PARAM_CHECK(p_param);
+ NULL_PARAM_CHECK(p_param->p_port_table);
+
+ FD_ZERO(&m_readfds);
+
+ err_code = nrf_mem_init();
+
+ if (err_code == NRF_SUCCESS) {
+ for (index = 0; index < COAP_PORT_COUNT; index++)
+ {
+ // Create end point for each of the COAP ports.
+ err_code = port_create(index, &p_param->p_port_table[index]);
+ if (err_code != NRF_SUCCESS)
+ {
+ break;
+ }
+ }
+ }
+
+ return err_code;
+}
+
+
+uint32_t coap_transport_write(const coap_port_t * p_port,
+ const coap_remote_t * p_remote,
+ const uint8_t * p_data,
+ uint16_t datalen)
+{
+
+ uint32_t err_code = NRF_ERROR_NOT_FOUND;
+ uint32_t index;
+
+ NULL_PARAM_CHECK(p_port);
+ NULL_PARAM_CHECK(p_remote);
+ NULL_PARAM_CHECK(p_data);
+
+ // Search for the corresponding port.
+ for (index = 0; index < COAP_PORT_COUNT; index++)
+ {
+ if (m_port_table[index].port_number == p_port->port_number)
+ {
+ COAP_MUTEX_UNLOCK();
+
+ static struct sockaddr_in6 dest_address_in6;
+
+ memset(&dest_address_in6, 0, sizeof(struct sockaddr_in6));
+ dest_address_in6.sin6_family = AF_INET6;
+ dest_address_in6.sin6_port = htons(p_remote->port_number);
+
+ memcpy(&dest_address_in6.sin6_addr, p_remote->addr, sizeof(struct in6_addr));
+
+ // Send on UDP port.
+ int retval = sendto(m_port_table[index].socket_fd,
+ p_data,
+ datalen,
+ 0,
+ (struct sockaddr *)&dest_address_in6,
+ sizeof(dest_address_in6));
+ if (retval == -1)
+ {
+ // Error in sendto.
+ err_code = NRF_ERROR_INTERNAL;
+ }
+ else
+ {
+ err_code = NRF_SUCCESS;
+ }
+
+ COAP_MUTEX_LOCK();
+ break;
+ }
+ }
+
+ return err_code;
+}
+
+
+void coap_transport_process(void)
+{
+ return;
+}
+
+
+uint32_t coap_security_setup(uint16_t local_port,
+ nrf_tls_role_t role,
+ coap_remote_t * const p_remote,
+ nrf_tls_key_settings_t * const p_settings)
+{
+ return SDK_ERR_API_NOT_IMPLEMENTED;
+}
+
+
+uint32_t coap_security_destroy(uint16_t local_port,
+ coap_remote_t * const p_remote)
+{
+ return SDK_ERR_API_NOT_IMPLEMENTED;
+}
+
+
+void coap_transport_input(void)
+{
+ int retval = select(m_max_sd, &m_readfds, NULL, NULL, NULL);
+
+ if (retval == -1)
+ {
+ // Error in select().
+ // Placeholder for debugging.
+ }
+ else if (retval >= 1) // Number of file descriptiors with activity.
+ {
+ uint32_t index = 0;
+ int socket_fd = m_port_table[index].socket_fd;
+
+ // The descriptor has data.
+ if (FD_ISSET(socket_fd, &m_readfds)) // If socket_fd is set to read.
+ {
+ static uint8_t read_mem[COAP_MESSAGE_DATA_MAX_SIZE];
+ static struct sockaddr_in6 client_address_in6;
+ socklen_t address_length = sizeof(struct sockaddr_in6);
+
+ int bytes_read = recvfrom(socket_fd,
+ read_mem,
+ sizeof(read_mem),
+ 0,
+ (struct sockaddr *)&client_address_in6,
+ (socklen_t *)&address_length); // Blocking call, waiting for incoming transaction.
+ if (bytes_read >= 0)
+ {
+ coap_port_t port;
+ port.port_number = m_port_table[index].port_number;
+
+ coap_remote_t remote_endpoint;
+ memcpy(remote_endpoint.addr, &client_address_in6.sin6_addr, sizeof(struct in6_addr));
+ remote_endpoint.port_number = ntohs(client_address_in6.sin6_port);
+
+ uint32_t result = NRF_SUCCESS;
+
+ // Notify the CoAP module of received data.
+ retval = coap_transport_read(&port,
+ &remote_endpoint,
+ NULL,
+ result,
+ read_mem,
+ (uint16_t)bytes_read);
+
+ // Nothing much to do if CoAP could not interpret the datagram.
+ UNUSED_VARIABLE(retval);
+ }
+ else
+ {
+ // Error in readfrom().
+ // Placeholder for debugging.
+ // If select() indicated this socket file descriptor to have pending
+ // data, this case should not occur.
+ }
+ }
+ }
+ else
+ {
+ // In case of socket() returning 0, timeout.
+ // Not implemented.
+ }
+}
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/common/iot_common.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/common/iot_common.h
new file mode 100644
index 0000000..58b653e
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/common/iot_common.h
@@ -0,0 +1,95 @@
+/**
+ * Copyright (c) 2014 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 iot_common.h
+ *
+ * @defgroup iot_common Common utils
+ * @ingroup iot_sdk_common
+ * @{
+ * @brief Common IoT macros that are needed by IoT modules.
+ *
+ * @details This module abstracts common macros related to IoT. These macros can be used by all IoT modules.
+ */
+
+#ifndef IOT_COMMON_H__
+#define IOT_COMMON_H__
+
+#include <stdint.h>
+#include <stdbool.h>
+#include "iot_defines.h"
+#include "iot_errors.h"
+#include "sdk_os.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**@brief Context identifiers used in stateful compression. */
+typedef struct
+{
+ uint8_t src_cntxt_id; /**< Source context identifier (if any). IPV6_CONTEXT_IDENTIFIER_NONE by default. IP Stack can set this on the interface if needed. */
+ uint8_t dest_cntxt_id; /**< Destination context identifier (if any). IPV6_CONTEXT_IDENTIFIER_NONE by default. IP Stack can set this on the interface if needed. */
+} iot_context_id_t;
+
+/**@brief Context structure used for efficient compression and decompression. */
+typedef struct
+{
+ uint8_t context_id; /**< Context identifier (CID) number. */
+ uint8_t prefix_len; /**< Length of prefix for CID. */
+ ipv6_addr_t prefix; /**< Prefix for CID. */
+ bool compression_flag; /**< Indicates if the context can be used for compression. */
+} iot_context_t;
+
+/**@brief Encapsulates all information of the 6LoWPAN interface. */
+typedef struct
+{
+ eui64_t local_addr; /**< Local EUI-64 address. */
+ eui64_t peer_addr; /**< Peer EUI-64 address. */
+ iot_context_id_t tx_contexts; /**< TX contexts can be used for effective compression. */
+ void * p_upper_stack; /**< Block to upper stack. */
+ void * p_transport; /**< Transport reference. */
+} iot_interface_t;
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif //IOT_COMMON_H__
+
+/**@} */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/common/iot_defines.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/common/iot_defines.h
new file mode 100644
index 0000000..e8c087a
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/common/iot_defines.h
@@ -0,0 +1,321 @@
+/**
+ * Copyright (c) 2014 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 iot_defines.h
+ *
+ * @defgroup iot_defines IoT Defines
+ * @ingroup iot_sdk_common
+ * @{
+ * @brief Common IoT definitions that are needed by IoT modules.
+ *
+ * @details This module abstracts common data structures and constants related to IoT.
+ * These definitions can be used by all the IoT modules.
+ */
+
+#ifndef IOT_DEFINES_H__
+#define IOT_DEFINES_H__
+
+#include <stdint.h>
+#include <sdk_config.h>
+#include <nrf.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**@brief Host to network byte-orders on half word. */
+//lint -emacro((572),HTONS) // Suppress warning 572 "Excessive shift value"
+#define HTONS(val) ((uint16_t)((((val) & 0xff00) >> 8) | ((((val) & 0x00ff) << 8))))
+
+/**@brief Host to network byte-orders on full word. */
+//lint -emacro((572),HTONL) // Suppress warning 572 "Excessive shift value"
+#define HTONL(val) ((((uint32_t) (val) & 0xff000000) >> 24) | \
+ (((uint32_t) (val) & 0x00ff0000) >> 8) | \
+ (((uint32_t) (val) & 0x0000ff00) << 8) | \
+ (((uint32_t) (val) & 0x000000ff) << 24))
+
+/**@brief Network to host byte-orders on half word. */
+#define NTOHS(val) HTONS(val)
+
+/**@brief Network to host byte-orders on full word. */
+#define NTOHL(val) HTONL(val)
+
+#if defined(NRF52) || defined(NRF52_SERIES)
+
+#define EUI_64_ADDR_SIZE 8 /**< Size of EUI-64. */
+#define IPV6_ADDR_SIZE 16 /**< Size of IPv6 128-bit address. */
+#define IPV6_CONTEXT_IDENTIFIER_NONE 0xFF /**< No context identifier in use. */
+
+#if (BLE_6LOWPAN_LEGACY_MODE == 1)
+#define IPV6_IID_FLIP_VALUE 0x02 /**< Value XORed with the first byte of EUI-64 to get IID. In some older Linux implementation, this value could be 0x03. */
+#define IPV6_LL_ADDR_SIZE 8 /**< The link-layer address size used in Neighbor Discovery messages. */
+#else
+#define IPV6_IID_FLIP_VALUE 0x00 /**< RFC 7668 specifies that no bit is flipped when IID is generated from a Bluetooth Device Address. */
+#define IPV6_LL_ADDR_SIZE 6 /**< The link-layer address size used in Neighbor Discovery messages. */
+#endif
+
+#define IPV6_IP_HEADER_SIZE 40 /**< IPv6 header size. */
+#define ICMP6_HEADER_SIZE 8 /**< ICMP header size. */
+#define UDP_HEADER_SIZE 8 /**< UDP header size. */
+#define COAP_HEADER_SIZE 4 /**< CoAP header size. */
+
+#define IPV6_DEFAULT_VER_TC 0x60 /**< Default value of version and traffic class fields in IPv6 header. */
+#define IPV6_DEFAULT_TC_FL 0x00 /**< Default value of traffic class and flow label fields in IPv6 header. */
+#define IPV6_DEFAULT_FL 0x00 /**< Default value of the flow label's two last bytes in IPv6 header. */
+
+#define IPV6_NEXT_HEADER_TCP 6 /**< TCP: protocol number. */
+#define IPV6_NEXT_HEADER_UDP 17 /**< UDP: protocol number. */
+#define IPV6_NEXT_HEADER_ICMP6 58 /**< ICMPv6: protocol number. */
+#define IPV6_NEXT_HEADER_RESERVED 255 /**< Reserved value. */
+
+/**@defgroup icmp6_type ICMPv6 message types.
+ * @ingroup iot_defines
+ * @{
+ */
+
+/**@defgroup icmp6_error_type ICMPv6 error messages.
+ * @ingroup icmp6_type
+ * @{
+ */
+#define ICMP6_TYPE_DESTINATION_UNREACHABLE 1 /**< ICMPv6: Destination unreachable error message. */
+#define ICMP6_TYPE_PACKET_TOO_LONG 2 /**< ICMPv6: Packet too long error message. */
+#define ICMP6_TYPE_TIME_EXCEED 3 /**< ICMPv6: Time-out error message. */
+#define ICMP6_TYPE_PARAMETER_PROBLEM 4 /**< ICMPv6: Parameter problem error message. */
+/** @} */
+#define ICMP6_TYPE_ECHO_REQUEST 128 /**< ICMPv6: Echo request message. */
+#define ICMP6_TYPE_ECHO_REPLY 129 /**< ICMPv6: Echo reply message. */
+#define ICMP6_TYPE_ROUTER_SOLICITATION 133 /**< ICMPv6: Neighbor discovery, router solicitation message. */
+#define ICMP6_TYPE_ROUTER_ADVERTISEMENT 134 /**< ICMPv6: Neighbor discovery, router advertisement message. */
+#define ICMP6_TYPE_NEIGHBOR_SOLICITATION 135 /**< ICMPv6: Neighbor discovery, neighbor solicitation message. */
+#define ICMP6_TYPE_NEIGHBOR_ADVERTISEMENT 136 /**< ICMPv6: Neighbor discovery, neighbor advertisement message. */
+/** @} */
+
+/**@brief Initializes IPv6 address. */
+#define IPV6_ADDRESS_INITIALIZE(ADDR) \
+ memset((ADDR)->u8, 0, IPV6_ADDR_SIZE)
+
+/**@brief Checks if prefixes match. Length in bits. */
+#define IPV6_ADDRESS_PREFIX_CMP(prefix, prefix2, length) \
+ ((0 == memcmp(prefix, prefix2, (length>>3) - ((length & 0x7) ? 1 : 0) )) && \
+ (((prefix[(length>>3)] & (((0xff00) >> (length & 0x7))))) == \
+ (prefix2[(length>>3)] & (((0xff00) >> (length & 0x7))))) \
+ )
+
+/**@brief Sets address prefix. Length in bits. */
+#define IPV6_ADDRESS_PREFIX_SET(pfx_to, pfx_from, length) \
+ do { \
+ memcpy(pfx_to, pfx_from, length>>3); \
+ if (length & 0x7) { \
+ uint8_t mask = ((0xff00) >> (length & 0x7)); \
+ uint8_t last = pfx_from[length>>3] & mask; \
+ pfx_to[length>>3] &= ~mask; \
+ pfx_to[length>>3] |= last; \
+ } \
+ } while (0)
+
+/**@brief Creates EUI-64 address from EUI-48.
+ */
+#define IPV6_EUI64_CREATE_FROM_EUI48(eui64, eui48, addr_type) \
+ eui64[0] = eui48[5]; \
+ eui64[1] = eui48[4]; \
+ eui64[2] = eui48[3]; \
+ eui64[3] = 0xFF; \
+ eui64[4] = 0xFE; \
+ eui64[5] = eui48[2]; \
+ eui64[6] = eui48[1]; \
+ eui64[7] = eui48[0]; \
+ if ((addr_type) == BLE_GAP_ADDR_TYPE_PUBLIC) \
+ { \
+ eui64[0] &= ~(IPV6_IID_FLIP_VALUE); \
+ } \
+ else \
+ { \
+ eui64[0] |= IPV6_IID_FLIP_VALUE; \
+ }
+
+/**@brief Creates link-local address from EUI-64. */
+#define IPV6_CREATE_LINK_LOCAL_FROM_EUI64(addr, eui64) \
+ (addr)->u32[0] = HTONL(0xFE800000); \
+ (addr)->u32[1] = 0; \
+ memcpy((addr)->u8 + 8, eui64, EUI_64_ADDR_SIZE); \
+ (addr)->u8[8] ^= IPV6_IID_FLIP_VALUE;
+
+/**@brief Checks if address is a link-local address. */
+#define IPV6_ADDRESS_IS_LINK_LOCAL(addr) \
+ ((addr)->u16[0] == HTONS(0xfe80))
+
+/**@brief Checks if address is a multicast address. */
+#define IPV6_ADDRESS_IS_MULTICAST(addr) \
+ ((addr)->u8[0] == 0xff)
+
+/**@brief Checks if address is a multicast all-node address. */
+#define IPV6_ADDRESS_IS_ALL_NODE(addr) \
+ (((addr)->u32[0] == HTONL(0xff020000)) && \
+ ((addr)->u32[1] == 0) && \
+ ((addr)->u32[2] == 0) && \
+ ((addr)->u32[3] == HTONL(0x01)))
+
+/**@brief Checks if address is a multicast all-router address. */
+#define IPV6_ADDRESS_IS_ALL_ROUTER(addr) \
+ (((addr)->u32[0] == HTONL(0xff020000)) && \
+ ((addr)->u32[1] == 0) && \
+ ((addr)->u32[2] == 0) && \
+ ((addr)->u32[3] == HTONL(0x02)))
+
+/**@brief Checks if address is a multicast MLDv2 address. */
+#define IPV6_ADDRESS_IS_MLDV2_MCAST(addr) \
+ (((addr)->u32[0] == HTONL(0xff020000)) && \
+ ((addr)->u32[1] == 0) && \
+ ((addr)->u32[2] == 0) && \
+ ((addr)->u32[3] == HTONL(0x16)))
+
+/**@brief Checks if address is a multicast all-node address. */
+#define IPV6_ADDRESS_IS_MULTICAST_SOLICITED_NODE(addr) \
+ (((addr)->u32[0] == HTONL(0xff020000)) && \
+ ((addr)->u32[1] == 0) && \
+ ((addr)->u32[2] == HTONL(0x00000001)) && \
+ ((addr)->u8[12] == 0xFF))
+
+/**@brief Checks if address is an unspecified address. */
+#define IPV6_ADDRESS_IS_UNSPECIFIED(addr) \
+ (((addr)->u32[0] == 0) && \
+ ((addr)->u32[1] == 0) && \
+ ((addr)->u32[2] == 0) && \
+ ((addr)->u32[3] == 0) \
+ )
+
+/**@brief Compares two IPv6 addresses. */
+#define IPV6_ADDRESS_CMP(addr1, addr2) \
+ memcmp((addr1)->u8, (addr2)->u8, IPV6_ADDR_SIZE)
+
+/**@brief Swaps two IPv6 addresses. */
+#define IPV6_ADDRESS_SWAP(addr1, addr2) \
+ do { \
+ ipv6_addr_t addr_temp; \
+ \
+ addr_temp = *addr1; \
+ *addr1 = *addr2; \
+ *addr2 = addr_temp; \
+ } while (0);
+
+/**@brief Prints an IPV6 address. */
+#define IPV6_ADDRESS_LOG(addr) \
+ NRF_LOG_RAW_INFO("%02x%02x:%02x%02x:",(addr).u8[0],(addr).u8[1],(addr).u8[2],(addr).u8[3]); \
+ NRF_LOG_RAW_INFO("%02x%02x:%02x%02x:",(addr).u8[4],(addr).u8[5],(addr).u8[6],(addr).u8[7]); \
+ NRF_LOG_RAW_INFO("%02x%02x:%02x%02x:",(addr).u8[8],(addr).u8[9],(addr).u8[10],(addr).u8[11]); \
+ NRF_LOG_RAW_INFO("%02x%02x:%02x%02x\r\n",(addr).u8[12],(addr).u8[13],(addr).u8[14],(addr).u8[15]);
+
+/**< EUI 64 data type. */
+typedef struct
+{
+ uint8_t identifier[EUI_64_ADDR_SIZE]; /**< 64-bit identifier. */
+} eui64_t;
+
+/**< IPv6 address data type. */
+typedef union
+{
+ uint8_t u8[16];
+ uint16_t u16[8];
+ uint32_t u32[4];
+} ipv6_addr_t;
+
+extern ipv6_addr_t ipv6_addr_any;
+#define IPV6_ADDR_ANY &ipv6_addr_any /**< IPV6 address represents any address. */
+
+extern eui64_t eui64_local_iid; /**< External variable assumed to be implemented in the application with desired EUI-64 to be used as the IID for SLAAC. */
+#define EUI64_LOCAL_IID &eui64_local_iid /**< EUI-64 IID of the device. */
+
+/** @brief IPv6 address states. */
+typedef enum
+{
+ IPV6_ADDR_STATE_UNUSED = 0, /**< IPv6 address is unused. */
+ IPV6_ADDR_STATE_TENTATIVE, /**< IPv6 tentative address; DUD must be performed. */
+ IPV6_ADDR_STATE_PREFERRED, /**< IPv6 preferred address; normal. state. */
+ IPV6_ADDR_STATE_DEPRECATED /**< IPv6 deprecated address. */
+} ipv6_addr_state_t;
+
+/**< IPv6 header structure. */
+typedef struct
+{
+ uint8_t version_traffic_class; /**< Version and traffic class field. */
+ uint8_t traffic_class_flowlabel; /**< Traffic class and flow label field. */
+ uint16_t flowlabel; /**< Flow label, 2nd part of field. */
+ uint16_t length; /**< Length of IPv6 payload field. */
+ uint8_t next_header; /**< Next header field. */
+ uint8_t hoplimit; /**< Hop limit field. */
+ ipv6_addr_t srcaddr; /**< IPv6 source address field. */
+ ipv6_addr_t destaddr; /**< IPv6 destination address field. */
+} ipv6_header_t;
+
+/**< IPv6 UDP header structure. */
+typedef struct
+{
+ uint16_t srcport; /**< Source port. */
+ uint16_t destport; /**< Destination port. */
+ uint16_t length; /**< Length of data with UDP header. */
+ uint16_t checksum; /**< UDP checksum field. */
+} udp6_header_t;
+
+/**< IPv6 ICMP header structure. */
+typedef struct
+{
+ uint8_t type; /**< Type of ICMP message. See @ref icmp6_type for possible values. */
+ uint8_t code; /**< Code related to the type field. */
+ uint16_t checksum; /**< ICMP6 checksum field. */
+ union /**< Message specific fields if any. */
+ {
+ uint32_t mtu; /**< MTU of next hop limit. Used only with Packet Too Big Error Message. */
+ uint32_t unused; /**< Unused fields for error messages that do not have any auxiliary information. */
+ uint32_t offset; /**< Offset field used only with Parameter Problem error message. */
+ struct { /**< Identifier and sequence number information specific associated with echo request and response. */
+ uint16_t id; /**< Identifier. */
+ uint16_t sequence; /**< Sequence number. */
+ } echo;
+ } sp;
+} icmp6_header_t;
+
+#endif // NRF52
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif //IOT_DEFINES_H__
+
+/**@} */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/common/iot_errors.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/common/iot_errors.h
new file mode 100644
index 0000000..657004a
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/common/iot_errors.h
@@ -0,0 +1,290 @@
+/**
+ * Copyright (c) 2015 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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
+ *
+ * @defgroup iot_error IoT SDK error codes
+ * @{
+ * @ingroup iot_sdk_common
+ * @{
+ * @brief Error codes for the nRF5x IoT SDK.
+ *
+ * @details
+ * Error codes are 32-bit unsigned integers. The most significant 16 bits (MSB) are reserved for
+ * identifying the module where the error occurred. The least significant 16 bits (LSB)
+ * are used to provide the cause or nature of error. Each module is assigned a 16-bit
+ * unsigned integer, which it will use to identify all errors that occurred in the module.
+ * For example, if 0x8800 identifies a certain SDK module, all error codes from
+ * 0x88000000 to 0x8800FFFF are reserved for this module.
+ *
+ * Note that common error reasons have been assigned values to make it
+ * possible to decode error reasons easily. As an example, if a module is not initialized,
+ * this error is assigned the error code 0x000A0. If an application encounters an error code
+ * 0xZZZZ00A0, the application knows that it tried to access a certain module without
+ * initializing it.
+ *
+ * Each module can define error codes that are not covered by
+ * the common codes. These values must be defined in a range that does not conflict
+ * with the common error values. Such module-specific error values might be used by
+ * different modules to indicate errors of very different nature; so the same error code LSB
+ * does not necessarily indicate the same error. If an error is already defined by the NRF
+ * common error codes, however, these codes are reused.
+ *
+ * A specific range is also reserved for the application. The application can use this range
+ * to define application-specific errors.
+ *
+ * The success code NRF_SUCCESS does not include a module identifier.
+
+ */
+
+#ifndef IOT_ERRORS_H__
+#define IOT_ERRORS_H__
+
+#include "sdk_errors.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @defgroup sdk_iot_err_base Base defined for IoT SDK Modules
+ * @{
+ */
+#define IOT_ERR_BASE NRF_ERROR_IOT_ERR_BASE_START
+/* @} */
+
+
+/**
+ * @defgroup sdk_iot_module_codes Module codes
+ * @brief Codes reserved as identification for the module where the error occurred.
+ * @{
+ */
+#define BLE_6LOWPAN_ERR_BASE (IOT_ERR_BASE+0x0200)
+
+#define IOT_PBUFFER_ERR_BASE (IOT_ERR_BASE+0x1000)
+#define IOT_CONTEXT_MANAGER_ERR_BASE (IOT_ERR_BASE+0x1100)
+#define IOT_TIMER_ERR_BASE (IOT_ERR_BASE+0x1200)
+#define IOT_FILE_ERR_BASE (IOT_ERR_BASE+0x1300)
+#define IOT_DFU_ERR_BASE (IOT_ERR_BASE+0x1400)
+#define IOT_IPV6_ERR_BASE (IOT_ERR_BASE+0x2000)
+#define IOT_ICMP6_ERR_BASE (IOT_ERR_BASE+0x2100)
+#define IOT_UDP6_ERR_BASE (IOT_ERR_BASE+0x2200)
+#define IOT_COAP_ERR_BASE (IOT_ERR_BASE+0x2300)
+#define IOT_DNS6_ERR_BASE (IOT_ERR_BASE+0x2400)
+#define IOT_NTP_ERR_BASE (IOT_ERR_BASE+0x2500)
+#define IOT_LWM2M_ERR_BASE (IOT_ERR_BASE+0x2600)
+#define IOT_SOCKET_ERR_BASE (IOT_ERR_BASE+0x2700)
+#define IOT_TFTP_ERR_BASE (IOT_ERR_BASE+0x2800)
+#define IOT_MQTT_ERR_BASE (IOT_ERR_BASE+0x2900)
+#define IOT_TLS_ERR_BASE (IOT_ERR_BASE+0x2A00)
+#define IOT_TRICKLE_ERR_BASE (IOT_ERR_BASE+0x2C00)
+/* @} */
+
+
+/**
+ * @defgroup iot_sdk_common_errors Common error codes
+ * @brief Codes reserved as identification for common errors.
+ * @{
+ */
+#define SDK_ERR_MODULE_NOT_INITIALIZED (NRF_ERROR_SDK_COMMON_ERROR_BASE+0x0000)
+#define SDK_ERR_MUTEX_INIT_FAILED (NRF_ERROR_SDK_COMMON_ERROR_BASE+0x0001)
+#define SDK_ERR_MUTEX_LOCK_FAILED (NRF_ERROR_SDK_COMMON_ERROR_BASE+0x0002)
+#define SDK_ERR_MUTEX_UNLOCK_FAILED (NRF_ERROR_SDK_COMMON_ERROR_BASE+0x0003)
+#define SDK_ERR_MUTEX_COND_INIT_FAILED (NRF_ERROR_SDK_COMMON_ERROR_BASE+0x0004)
+#define SDK_ERR_MODULE_ALREADY_INITIALZED (NRF_ERROR_SDK_COMMON_ERROR_BASE+0x0005)
+#define SDK_ERR_API_NOT_IMPLEMENTED (NRF_ERROR_SDK_COMMON_ERROR_BASE+0x0010)
+#define SDK_ERR_FEATURE_NOT_ENABLED (NRF_ERROR_SDK_COMMON_ERROR_BASE+0x0011)
+#define SDK_ERR_RX_PKT_TRUNCATED (NRF_ERROR_SDK_COMMON_ERROR_BASE+0x0012)
+/* @} */
+
+
+/**
+ * @defgroup ble_6lowpan_errors 6LoWPAN codes
+ * @brief Error and status codes specific to 6LoWPAN.
+ * @{
+ */
+#define BLE_6LOWPAN_CID_NOT_FOUND (BLE_6LOWPAN_ERR_BASE+0x0040)
+#define BLE_6LOWPAN_TX_FIFO_FULL (BLE_6LOWPAN_ERR_BASE+0x0041)
+/* @} */
+
+
+/**
+ * @defgroup iot_sdk_ipv6 IPv6 codes
+ * @brief Error and status codes specific to IPv6.
+ * @{
+ */
+#define IOT_IPV6_ERR_ADDR_IF_MISMATCH (IOT_IPV6_ERR_BASE+0x0040)
+#define IOT_IPV6_ERR_PENDING (IOT_IPV6_ERR_BASE+0x0041)
+/* @} */
+
+
+/**
+ * @defgroup iot_sdk_udp_errors UDP codes
+ * @brief Error and status codes specific to UDP.
+ * @{
+ */
+#define UDP_PORT_IN_USE (IOT_UDP6_ERR_BASE+0x0040)
+#define UDP_BAD_CHECKSUM (IOT_UDP6_ERR_BASE+0x0041)
+#define UDP_TRUNCATED_PACKET (IOT_UDP6_ERR_BASE+0x0042)
+#define UDP_MALFORMED_PACKET (IOT_UDP6_ERR_BASE+0x0043)
+#define UDP_INTERFACE_NOT_READY (IOT_UDP6_ERR_BASE+0x0044)
+/* @} */
+
+/**
+ * @defgroup iot_sdk_socket_errors socket error codes
+ * @brief Error and status codes specific to socket API.
+ * @{
+ */
+#define SOCKET_PORT_IN_USE (IOT_SOCKET_ERR_BASE + 0x0040)
+#define SOCKET_NO_AVAILABLE_PORTS (IOT_SOCKET_ERR_BASE + 0x0041)
+#define SOCKET_WOULD_BLOCK (IOT_SOCKET_ERR_BASE + 0x0042)
+#define SOCKET_NO_MEM (IOT_SOCKET_ERR_BASE + 0x0043)
+#define SOCKET_NO_ROUTE (IOT_SOCKET_ERR_BASE + 0x0044)
+#define SOCKET_TIMEOUT (IOT_SOCKET_ERR_BASE + 0x0045)
+#define SOCKET_INTERFACE_NOT_READY (IOT_SOCKET_ERR_BASE + 0x0046)
+#define SOCKET_INVALID_PARAM (IOT_SOCKET_ERR_BASE + 0x0047)
+#define SOCKET_UNSUPPORTED_PROTOCOL (IOT_SOCKET_ERR_BASE + 0x0048)
+#define SOCKET_ADDRESS_IN_USE (IOT_SOCKET_ERR_BASE + 0x0049)
+#define SOCKET_NOT_CONNECTED (IOT_SOCKET_ERR_BASE + 0x0050)
+/* @} */
+
+/**
+ * @defgroup iot_sdk_icmp6_errors ICMP codes
+ * @brief Error and status codes specific to ICMP.
+ * @{
+ */
+#define ICMP6_UNHANDLED_PACKET_TYPE (IOT_ICMP6_ERR_BASE+0x0040)
+#define ICMP6_BAD_CHECKSUM (IOT_ICMP6_ERR_BASE+0x0041)
+#define ICMP6_MALFORMED_PACKET (IOT_ICMP6_ERR_BASE+0x0042)
+#define ICMP6_INVALID_PACKET_DATA (IOT_ICMP6_ERR_BASE+0x0043)
+/* @} */
+
+
+/**
+ * @defgroup iot_sdk_coap_errros CoAP codes
+ * @brief Error and status codes specific to CoAP.
+ * @{
+ */
+#define COAP_MESSAGE_ERROR_NULL (IOT_COAP_ERR_BASE+0x0040)
+#define COAP_MESSAGE_ERROR_INVALID_CONF (IOT_COAP_ERR_BASE+0x0041)
+#define COAP_MESSAGE_INVALID_CONTENT (IOT_COAP_ERR_BASE+0x0042)
+#define COAP_TRANSMISSION_RESET_BY_PEER (IOT_COAP_ERR_BASE+0x0043)
+#define COAP_TRANSMISSION_TIMEOUT (IOT_COAP_ERR_BASE+0x0044)
+#define COAP_TRANSPORT_SECURITY_MISSING (IOT_COAP_ERR_BASE+0x0045)
+#define COAP_REQUEST_RESOURCE_NOT_FOUND (IOT_COAP_ERR_BASE+0x0046)
+#define COAP_REQUEST_HANDLER_NOT_FOUND (IOT_COAP_ERR_BASE+0x0047)
+/* @} */
+
+
+/**
+ * @defgroup iot_sdk_dns6_errors DNS codes.
+ * @brief Error and status codes specific to DNS.
+ * @{
+ */
+#define DNS6_SERVER_UNREACHABLE (IOT_DNS6_ERR_BASE+0x0040)
+#define DNS6_FORMAT_ERROR (IOT_DNS6_ERR_BASE+0x0041)
+#define DNS6_SERVER_FAILURE (IOT_DNS6_ERR_BASE+0x0042)
+#define DNS6_HOSTNAME_NOT_FOUND (IOT_DNS6_ERR_BASE+0x0043)
+#define DNS6_NOT_IMPLEMENTED (IOT_DNS6_ERR_BASE+0x0044)
+#define DNS6_REFUSED_ERROR (IOT_DNS6_ERR_BASE+0x0045)
+#define DNS6_RESPONSE_TRUNCATED (IOT_DNS6_ERR_BASE+0x0046)
+/* @} */
+
+
+/**
+ * @defgroup iot_sdk_ntp_errors NTP codes.
+ * @brief Error and status codes specific to NTP.
+ * @{
+ */
+#define NTP_SERVER_UNREACHABLE (IOT_NTP_ERR_BASE+0x0040)
+#define NTP_SERVER_BAD_RESPONSE (IOT_NTP_ERR_BASE+0x0041)
+#define NTP_SERVER_KOD_PACKET_RECEIVED (IOT_NTP_ERR_BASE+0x0042)
+/* @} */
+
+/**
+ * @defgroup iot_sdk_tftp_errors TFTP codes.
+ * @brief Error and status codes specific to TFTP.
+ * @{
+ */
+ /**@brief TFTP Error codes. */
+#define TFTP_UNDEFINED_ERROR (IOT_TFTP_ERR_BASE+0x0040)
+#define TFTP_FILE_NOT_FOUND (IOT_TFTP_ERR_BASE+0x0041)
+#define TFTP_ACCESS_DENIED (IOT_TFTP_ERR_BASE+0x0042)
+#define TFTP_FULL_STORAGE (IOT_TFTP_ERR_BASE+0x0043)
+#define TFTP_INVALID_OPCODE (IOT_TFTP_ERR_BASE+0x0044)
+#define TFTP_INVALID_TID (IOT_TFTP_ERR_BASE+0x0045)
+#define TFTP_FILE_EXSISTS (IOT_TFTP_ERR_BASE+0x0046)
+#define TFTP_WRONG_USERNAME (IOT_TFTP_ERR_BASE+0x0047)
+#define TFTP_OPTION_REJECT (IOT_TFTP_ERR_BASE+0x0048)
+#define TFTP_INVALID_PACKET (IOT_TFTP_ERR_BASE+0x0049)
+#define TFTP_REMOTE_UNREACHABLE (IOT_TFTP_ERR_BASE+0x004A)
+ /* @} */
+
+/**@defgroup iot_sdk_mqtt_err_code MQTT Error Codes
+ *@{
+ */
+#define MQTT_ERR_NOT_CONNECTED (IOT_MQTT_ERR_BASE+0x0040)
+#define MQTT_ERR_WRITE (IOT_MQTT_ERR_BASE+0x0041)
+#define MQTT_ERR_TCP_PROC_FAILED (IOT_MQTT_ERR_BASE+0x0042)
+#define MQTT_CONNECTION_FAILED (IOT_MQTT_ERR_BASE+0x0043)
+#define MQTT_ERR_TRANSPORT_CLOSED (IOT_MQTT_ERR_BASE+0x0044)
+/**@}
+ */
+
+
+/**@defgroup iot_sdk_tls_err_code NRF TLS Interface Error Codes
+ *@{
+ */
+#define NRF_TLS_CONFIGURATION_FAILED (IOT_TLS_ERR_BASE+0x0040)
+#define NRF_TLS_CONTEXT_SETUP_FAILED (IOT_TLS_ERR_BASE+0x0041)
+#define NRF_TLS_HANDSHAKE_IN_PROGRESS (IOT_TLS_ERR_BASE+0x0042)
+#define NRF_TLS_NO_FREE_INSTANCE (IOT_TLS_ERR_BASE+0x0043)
+#define NRF_TLS_INVALID_CA_CERTIFICATE (IOT_TLS_ERR_BASE+0x0044)
+#define NRF_TLS_OWN_CERT_SETUP_FAILED (IOT_TLS_ERR_BASE+0x0045)
+/**@}
+ */
+
+/** @} */
+/** @} */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // IOT_ERRORS_H__
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/context_manager/iot_context_manager.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/context_manager/iot_context_manager.c
new file mode 100644
index 0000000..a0c66ac
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/context_manager/iot_context_manager.c
@@ -0,0 +1,561 @@
+/**
+ * Copyright (c) 2014 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#include "nordic_common.h"
+#include "sdk_common.h"
+#include "sdk_config.h"
+#include "iot_common.h"
+#include "iot_context_manager.h"
+
+#if IOT_CONTEXT_MANAGER_CONFIG_LOG_ENABLED
+
+#define NRF_LOG_MODULE_NAME context_manager
+
+#define NRF_LOG_LEVEL IOT_CONTEXT_MANAGER_CONFIG_LOG_LEVEL
+#define NRF_LOG_INFO_COLOR IOT_CONTEXT_MANAGER_CONFIG_INFO_COLOR
+#define NRF_LOG_DEBUG_COLOR IOT_CONTEXT_MANAGER_CONFIG_DEBUG_COLOR
+
+#include "nrf_log.h"
+NRF_LOG_MODULE_REGISTER();
+
+#define CM_TRC NRF_LOG_DEBUG /**< Used for getting trace of execution in the module. */
+#define CM_ERR NRF_LOG_ERROR /**< Used for logging errors in the module. */
+#define CM_DUMP NRF_LOG_HEXDUMP_DEBUG /**< Used for dumping octet information to get details of bond information etc. */
+
+#define CM_ENTRY() CM_TRC(">> %s", __func__)
+#define CM_EXIT() CM_TRC("<< %s", __func__)
+
+#else // IOT_CONTEXT_MANAGER_CONFIG_LOG_ENABLED
+
+#define CM_TRC(...) /**< Disables traces. */
+#define CM_DUMP(...) /**< Disables dumping of octet streams. */
+#define CM_ERR(...) /**< Disables error logs. */
+
+#define CM_ENTRY(...)
+#define CM_EXIT(...)
+
+#endif // IOT_CONTEXT_MANAGER_CONFIG_LOG_ENABLED
+
+/**@brief Parameter maximum values. */
+#define CID_VALUE_MAX 15
+#define PREFIX_LENGTH_VALUE_MAX 128
+
+/**
+ * @defgroup api_param_check API Parameters check macros.
+ *
+ * @details Macros that verify parameters passed to the module in the APIs. These macros
+ * could be mapped to nothing in final versions of code to save execution and size.
+ * IOT_CONTEXT_MANAGER_DISABLE_API_PARAM_CHECK should be defined to disable these checks.
+ *
+ * @{
+ */
+#if (IOT_CONTEXT_MANAGER_DISABLE_API_PARAM_CHECK == 0)
+
+/**@brief Macro to check is module is initialized before requesting one of the module procedures. */
+#define VERIFY_MODULE_IS_INITIALIZED() \
+ if (m_initialization_state == false) \
+ { \
+ return (SDK_ERR_MODULE_NOT_INITIALIZED | IOT_CONTEXT_MANAGER_ERR_BASE); \
+ }
+
+/**@brief Macro to check is module is initialized before requesting one of the module procedures. */
+#define VERIFY_MODULE_IS_INITIALIZED_NULL() \
+ if (m_initialization_state == false) \
+ { \
+ return NULL; \
+ }
+
+/**
+ * @brief Verify NULL parameters are not passed to API by application.
+ */
+#define NULL_PARAM_CHECK(PARAM) \
+ if ((PARAM) == NULL) \
+ { \
+ return (NRF_ERROR_NULL | IOT_CONTEXT_MANAGER_ERR_BASE); \
+ }
+
+/**
+ * @brief Verify CID has valid value.
+ */
+#define VERIFY_CID_VALUE(CID) \
+ if (!((CID) <= CID_VALUE_MAX)) \
+ { \
+ return (NRF_ERROR_INVALID_PARAM | IOT_CONTEXT_MANAGER_ERR_BASE); \
+ }
+
+/**
+ * @brief Verify prefix length value.
+ */
+#define VERIFY_PREFIX_LEN_VALUE(PREFIX_LEN) \
+ if (!(PREFIX_LEN <= PREFIX_LENGTH_VALUE_MAX)) \
+ { \
+ return (NRF_ERROR_INVALID_PARAM | IOT_CONTEXT_MANAGER_ERR_BASE); \
+ }
+
+#else // IOT_IOT_CONTEXT_MANAGER_DISABLE_API_PARAM_CHECK
+
+#define VERIFY_MODULE_IS_INITIALIZED()
+#define VERIFY_MODULE_IS_INITIALIZED_NULL()
+#define NULL_PARAM_CHECK(PARAM)
+#define VERIFY_CID_VALUE(CID)
+#define VERIFY_PREFIX_LEN_VALUE(PREFIX_LEN)
+
+#endif //IOT_CONTEXT_MANAGER_DISABLE_API_PARAM_CHECK
+/** @} */
+
+/**
+ * @defgroup iot_context_manager_mutex_lock_unlock Module's Mutex Lock/Unlock Macros.
+ *
+ * @details Macros used to lock and unlock modules. Currently, SDK does not use mutexes but
+ * framework is provided in case need arises to use an alternative architecture.
+ * @{
+ */
+#define CM_MUTEX_LOCK() SDK_MUTEX_LOCK(m_iot_context_manager_mutex) /**< Lock module using mutex */
+#define CM_MUTEX_UNLOCK() SDK_MUTEX_UNLOCK(m_iot_context_manager_mutex) /**< Unlock module using mutex */
+/** @} */
+
+/**@brief Context table, managing by IPv6 stack. */
+typedef struct
+{
+ iot_interface_t * p_interface; /**< IoT interface pointer. */
+ uint8_t context_count; /**< Number of valid contexts in the table. */
+ iot_context_t contexts[IOT_CONTEXT_MANAGER_MAX_CONTEXTS]; /**< Array of valid contexts. */
+}iot_context_table_t;
+
+
+SDK_MUTEX_DEFINE(m_iot_context_manager_mutex) /**< Mutex variable. Currently unused, this declaration does not occupy any space in RAM. */
+static bool m_initialization_state = false; /**< Variable to maintain module initialization state. */
+static iot_context_table_t m_context_table[IOT_CONTEXT_MANAGER_MAX_TABLES]; /**< Array of contexts table managed by the module. */
+
+/**@brief Initializes context entry. */
+static void context_init(iot_context_t * p_context)
+{
+ p_context->context_id = IPV6_CONTEXT_IDENTIFIER_NONE;
+ p_context->prefix_len = 0;
+ p_context->compression_flag = false;
+
+ memset(p_context->prefix.u8, 0, IPV6_ADDR_SIZE);
+}
+
+
+/**@brief Initializes context table. */
+static void context_table_init(uint32_t table_id)
+{
+ uint32_t index;
+
+ for (index = 0; index < IOT_CONTEXT_MANAGER_MAX_CONTEXTS; index++)
+ {
+ context_init(&m_context_table[table_id].contexts[index]);
+ m_context_table[table_id].context_count = 0;
+ m_context_table[table_id].p_interface = NULL;
+ }
+}
+
+
+/**@brief Initializes context table. */
+static uint32_t context_table_find(const iot_interface_t * p_interface)
+{
+ uint32_t index;
+
+ for (index = 0; index < IOT_CONTEXT_MANAGER_MAX_TABLES; index++)
+ {
+ if (m_context_table[index].p_interface == p_interface)
+ {
+ break;
+ }
+ }
+
+ return index;
+}
+
+
+/**@brief Looks up context table for specific context identifier. */
+static uint32_t context_find_by_cid(uint32_t table_id,
+ uint8_t context_id,
+ iot_context_t ** pp_context)
+{
+ uint32_t index;
+
+ for (index = 0; index < IOT_CONTEXT_MANAGER_MAX_CONTEXTS; index++)
+ {
+ if (m_context_table[table_id].contexts[index].context_id == context_id)
+ {
+ *pp_context = &m_context_table[table_id].contexts[index];
+ return NRF_SUCCESS;
+ }
+ }
+
+ return (NRF_ERROR_NOT_FOUND | IOT_CONTEXT_MANAGER_ERR_BASE);
+}
+
+
+static uint32_t context_find_by_prefix(uint32_t table_id,
+ const ipv6_addr_t * p_prefix,
+ iot_context_t ** pp_context)
+{
+ uint32_t index;
+ uint32_t context_left;
+ uint16_t context_cmp_len;
+ iot_context_t * p_best_match = NULL;
+
+ context_left = m_context_table[table_id].context_count;
+
+ for (index = 0; index < IOT_CONTEXT_MANAGER_MAX_CONTEXTS && context_left; index++)
+ {
+ if (m_context_table[table_id].contexts[index].context_id != IPV6_CONTEXT_IDENTIFIER_NONE &&
+ m_context_table[table_id].contexts[index].compression_flag == true)
+ {
+ if ((context_cmp_len = m_context_table[table_id].contexts[index].prefix_len) < 64)
+ {
+ context_cmp_len = 64;
+ }
+
+ // Check if address have matched in CID table.
+ if (IPV6_ADDRESS_PREFIX_CMP(m_context_table[table_id].contexts[index].prefix.u8,
+ p_prefix->u8,
+ context_cmp_len))
+ {
+ if (p_best_match == NULL || p_best_match->prefix_len <
+ m_context_table[table_id].contexts[index].prefix_len)
+ {
+ p_best_match = &m_context_table[table_id].contexts[index];
+ }
+ }
+
+ // Decrease left context in table, to avoid too many checking.
+ context_left--;
+ }
+ }
+
+ if (p_best_match)
+ {
+ *pp_context = p_best_match;
+ return NRF_SUCCESS;
+ }
+
+ return (NRF_ERROR_NOT_FOUND | IOT_CONTEXT_MANAGER_ERR_BASE);
+}
+
+
+/**@brief Looks up for first empty entry in the table. */
+static uint32_t context_find_free(uint32_t table_id, iot_context_t ** pp_context)
+{
+ uint32_t index;
+
+ for (index = 0; index < IOT_CONTEXT_MANAGER_MAX_CONTEXTS; index++)
+ {
+ if (m_context_table[table_id].contexts[index].context_id == IPV6_CONTEXT_IDENTIFIER_NONE)
+ {
+ *pp_context = &m_context_table[table_id].contexts[index];
+ return NRF_SUCCESS;
+ }
+ }
+
+ return (NRF_ERROR_NO_MEM | IOT_CONTEXT_MANAGER_ERR_BASE);
+}
+
+
+uint32_t iot_context_manager_init(void)
+{
+ uint32_t index;
+
+ CM_ENTRY();
+
+ SDK_MUTEX_INIT(m_iot_context_manager_mutex);
+
+ CM_MUTEX_LOCK();
+
+ for (index = 0; index < IOT_CONTEXT_MANAGER_MAX_TABLES; index++)
+ {
+ context_table_init(index);
+ }
+
+ m_initialization_state = true;
+
+ CM_MUTEX_UNLOCK();
+
+ CM_EXIT();
+
+ return NRF_SUCCESS;
+}
+
+
+uint32_t iot_context_manager_table_alloc(const iot_interface_t * p_interface)
+{
+ VERIFY_MODULE_IS_INITIALIZED();
+ NULL_PARAM_CHECK(p_interface);
+
+ uint32_t err_code = NRF_SUCCESS;
+
+ CM_ENTRY();
+
+ CM_MUTEX_LOCK();
+
+ const uint32_t table_id = context_table_find(NULL);
+
+ if (table_id != IOT_CONTEXT_MANAGER_MAX_TABLES)
+ {
+ // Found a free context table and assign to it.
+ CM_TRC("Assigned new context table.");
+ m_context_table[table_id].p_interface = (iot_interface_t *)p_interface;
+ }
+ else
+ {
+ // No free context table found.
+ CM_ERR("No context table found.");
+ err_code = (NRF_ERROR_NO_MEM | IOT_CONTEXT_MANAGER_ERR_BASE);
+ }
+
+ CM_MUTEX_UNLOCK();
+
+ CM_EXIT();
+
+ return err_code;
+}
+
+
+uint32_t iot_context_manager_table_free(const iot_interface_t * p_interface)
+{
+ VERIFY_MODULE_IS_INITIALIZED();
+ NULL_PARAM_CHECK(p_interface);
+
+ uint32_t err_code = NRF_SUCCESS;
+
+ CM_ENTRY();
+
+ SDK_MUTEX_INIT(m_iot_context_manager_mutex);
+
+ CM_MUTEX_LOCK();
+
+ const uint32_t table_id = context_table_find(p_interface);
+
+ if (table_id != IOT_CONTEXT_MANAGER_MAX_TABLES)
+ {
+ // Clear context table.
+ CM_TRC("Found context table assigned to interface.");
+ context_table_init(table_id);
+ }
+ else
+ {
+ // No free context table found.
+ CM_ERR("No context table found.");
+ err_code = (NRF_ERROR_NOT_FOUND | IOT_CONTEXT_MANAGER_ERR_BASE);
+ }
+
+ CM_MUTEX_UNLOCK();
+
+ CM_EXIT();
+
+ return err_code;
+}
+
+
+uint32_t iot_context_manager_update(const iot_interface_t * p_interface,
+ iot_context_t * p_context)
+{
+ VERIFY_MODULE_IS_INITIALIZED();
+ NULL_PARAM_CHECK(p_context);
+ VERIFY_CID_VALUE(p_context->context_id);
+ VERIFY_PREFIX_LEN_VALUE(p_context->prefix_len);
+
+ uint32_t retval = NRF_SUCCESS;
+ uint32_t err_code = NRF_SUCCESS;
+ iot_context_t * p_internal_context;
+
+ CM_ENTRY();
+
+ CM_MUTEX_LOCK();
+
+ const uint32_t table_id = context_table_find(p_interface);
+
+ if (table_id != IOT_CONTEXT_MANAGER_MAX_TABLES)
+ {
+ // Try to find context in context table.
+ retval = context_find_by_cid(table_id, p_context->context_id, &p_internal_context);
+
+ if (retval != NRF_SUCCESS)
+ {
+ err_code = context_find_free(table_id, &p_internal_context);
+
+ // Increase context count.
+ if (err_code == NRF_SUCCESS)
+ {
+ m_context_table[table_id].context_count++;
+ }
+ }
+
+ if (err_code == NRF_SUCCESS)
+ {
+ // Update context table, with parameters from application.
+ p_internal_context->context_id = p_context->context_id;
+ p_internal_context->prefix_len = p_context->prefix_len;
+ p_internal_context->compression_flag = p_context->compression_flag;
+ memset(p_internal_context->prefix.u8, 0, IPV6_ADDR_SIZE);
+ IPV6_ADDRESS_PREFIX_SET(p_internal_context->prefix.u8, p_context->prefix.u8, p_context->prefix_len);
+ }
+ else
+ {
+ CM_ERR("No place in context table.");
+ }
+ }
+ else
+ {
+ // No free context table found.
+ CM_ERR("No context table found.");
+ err_code = (NRF_ERROR_NOT_FOUND | IOT_CONTEXT_MANAGER_ERR_BASE);
+ }
+
+ CM_MUTEX_UNLOCK();
+
+ CM_EXIT();
+
+ return err_code;
+}
+
+
+uint32_t iot_context_manager_remove(const iot_interface_t * p_interface,
+ iot_context_t * p_context)
+{
+ VERIFY_MODULE_IS_INITIALIZED();
+ NULL_PARAM_CHECK(p_interface);
+ NULL_PARAM_CHECK(p_context);
+
+ uint32_t err_code = NRF_SUCCESS;
+
+ CM_ENTRY();
+
+ CM_MUTEX_LOCK();
+
+ const uint32_t table_id = context_table_find(p_interface);
+
+ if (table_id != IOT_CONTEXT_MANAGER_MAX_TABLES)
+ {
+ if (p_context->context_id != IPV6_CONTEXT_IDENTIFIER_NONE)
+ {
+ m_context_table[table_id].context_count--;
+ }
+
+ // Reinit context entry.
+ context_init(p_context);
+ }
+ else
+ {
+ // No free context table found.
+ CM_ERR("No context table found.");
+ err_code = (NRF_ERROR_NOT_FOUND | IOT_CONTEXT_MANAGER_ERR_BASE);
+ }
+
+ CM_MUTEX_UNLOCK();
+
+ CM_EXIT();
+
+ return err_code;
+}
+
+
+uint32_t iot_context_manager_get_by_addr(const iot_interface_t * p_interface,
+ const ipv6_addr_t * p_addr,
+ iot_context_t ** pp_context)
+{
+ VERIFY_MODULE_IS_INITIALIZED();
+ NULL_PARAM_CHECK(p_interface);
+ NULL_PARAM_CHECK(p_addr);
+ NULL_PARAM_CHECK(pp_context);
+
+ uint32_t err_code;
+
+ CM_ENTRY();
+
+ CM_MUTEX_LOCK();
+
+ const uint32_t table_id = context_table_find(p_interface);
+
+ if (table_id != IOT_CONTEXT_MANAGER_MAX_TABLES)
+ {
+ err_code = context_find_by_prefix(table_id, p_addr, pp_context);
+ }
+ else
+ {
+ // No free context table found.
+ CM_ERR("No context table found.");
+ err_code = (NRF_ERROR_NOT_FOUND | IOT_CONTEXT_MANAGER_ERR_BASE);
+ }
+
+ CM_MUTEX_UNLOCK();
+
+ CM_EXIT();
+
+ return err_code;
+}
+
+
+uint32_t iot_context_manager_get_by_cid(const iot_interface_t * p_interface,
+ uint8_t context_id,
+ iot_context_t ** pp_context)
+{
+ VERIFY_MODULE_IS_INITIALIZED();
+ NULL_PARAM_CHECK(p_interface);
+ NULL_PARAM_CHECK(pp_context);
+ VERIFY_CID_VALUE(context_id);
+
+ uint32_t err_code;
+
+ CM_ENTRY();
+
+ CM_MUTEX_LOCK();
+
+ const uint32_t table_id = context_table_find(p_interface);
+
+ if (table_id != IOT_CONTEXT_MANAGER_MAX_TABLES)
+ {
+ err_code = context_find_by_cid(table_id, context_id, pp_context);
+ }
+ else
+ {
+ // No free context table found.
+ CM_TRC("No context table found.");
+ err_code = (NRF_ERROR_NOT_FOUND | IOT_CONTEXT_MANAGER_ERR_BASE);
+ }
+
+ CM_MUTEX_UNLOCK();
+
+ CM_EXIT();
+
+ return err_code;
+}
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/context_manager/iot_context_manager.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/context_manager/iot_context_manager.h
new file mode 100644
index 0000000..7fec245
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/context_manager/iot_context_manager.h
@@ -0,0 +1,155 @@
+/**
+ * Copyright (c) 2014 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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
+ *
+ * @defgroup iot_context_manager Context Manager
+ * @{
+ * @ingroup iot_sdk_common
+ * @brief Manages context identifiers and prefixes related to the identifiers.
+ *
+ * @details This module allows to handle context information throughout the IoT application.
+ * The module is used in the compression and decompression procedures of IPv6 addresses.
+ * It allows more efficient communication between two nodes using global addresses.
+ * The Context Manager contains tables of context, which can be accessed through API functions.
+ * The table is maintained by the IPv6 stack while is referenced by 6LoWPAN module to be able to
+ * compress and decompress packets.
+ *
+ * You can configure the module by changing the @c sdk_config.h configuration file.
+ */
+
+#ifndef IOT_CONTEXT_MANAGER__
+#define IOT_CONTEXT_MANAGER__
+
+#include <stdint.h>
+#include <stdbool.h>
+#include "iot_common.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**@brief Function for initializing the module.
+ *
+ * @retval NRF_SUCCESS If the module was successfully initialized. Otherwise, an error code that indicates the reason for the failure is returned.
+ */
+uint32_t iot_context_manager_init(void);
+
+
+/**@brief Function for allocating the table for the specific interface.
+ *
+ * @param[in] p_interface Pointer to the IoT interface.
+ *
+ * @retval NRF_SUCCESS If the table was successfully allocated. Otherwise, an error code that indicates the reason for the failure is returned.
+ */
+uint32_t iot_context_manager_table_alloc(const iot_interface_t * p_interface);
+
+
+/**@brief Function for freeing the table for the specific interface.
+ *
+ * @param[in] p_interface Pointer to the IoT interface.
+ *
+ * @retval NRF_SUCCESS If the table was successfully freed. Otherwise, an error code that indicates the reason for the failure is returned.
+ */
+uint32_t iot_context_manager_table_free(const iot_interface_t * p_interface);
+
+
+/**@brief Function for updating the context table.
+ *
+ * Update requests are treated as follows:
+ * - If the context identifier already exists in the context table, the context
+ * is updated.
+ * - If the context identifier does not exist yet, a new entry is generated. If
+ * no memory is available, NRF_ERROR_NO_MEMORY is returned.
+ *
+ * The compression flag indicates if a context can be used for compression.
+ * The context table can hold up to 16 context's information.
+ *
+ * @param[in] p_interface Pointer to the IoT interface.
+ * @param[in] p_context Pointer to the context entry that shall be modified or added.
+ *
+ * @retval NRF_SUCCESS If the table was successfully updated. Otherwise, an error code that indicates the reason for the failure is returned.
+ */
+uint32_t iot_context_manager_update(const iot_interface_t * p_interface, iot_context_t * p_context);
+
+
+/**@brief Function for removing context from the context table.
+ *
+ * @param[in] p_interface Pointer to the IoT interface.
+ * @param[in] p_context Pointer to the context entry, retrieved from @ref iot_context_manager_get_by_addr or
+ * @ref iot_context_manager_get_by_cid.
+ *
+ * @retval NRF_SUCCESS If the context was successfully removed. Otherwise, an error code that indicates the reason for the failure is returned.
+ */
+uint32_t iot_context_manager_remove(const iot_interface_t * p_interface, iot_context_t * p_context);
+
+
+/**@brief Function for searching the proper entry in the context table by IPv6 address.
+ * Only contexts with compression flag set to true, may be returned.
+ *
+ * @param[in] p_interface Pointer to the IoT interface.
+ * @param[in] p_addr Pointer to IPv6 address to be compared with records in the context table.
+ * @param[out] pp_context Pointer to the context in the context table.
+ *
+ * @retval NRF_SUCCESS If the procedure succeeded. Otherwise, an error code that indicates the reason for the failure is returned.
+ */
+uint32_t iot_context_manager_get_by_addr(const iot_interface_t * p_interface,
+ const ipv6_addr_t * p_addr,
+ iot_context_t ** pp_context);
+
+
+/**@brief Function for searching the proper entry in the context table by context identifier.
+ *
+ * @param[in] p_interface Pointer to the IoT interface.
+ * @param[in] context_id Context identifier to be compared with records in the context table.
+ * @param[out] pp_context Pointer to the context in the context table.
+ *
+ * @retval NRF_SUCCESS If the procedure succeeded. Otherwise, an error code that indicates the reason for the failure is returned.
+ */
+uint32_t iot_context_manager_get_by_cid(const iot_interface_t * p_interface,
+ uint8_t context_id,
+ iot_context_t ** pp_context);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // IOT_CONTEXT_MANAGER__
+
+/**@} */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/errno/errno.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/errno/errno.c
new file mode 100644
index 0000000..f1d79b5
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/errno/errno.c
@@ -0,0 +1,55 @@
+/**
+ * Copyright (c) 2015 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#include "errno.h"
+
+// TODO: Support multiple contexts
+static int m_errno_main;
+
+int *
+__error(void)
+{
+ return &m_errno_main;
+}
+
+void
+set_errno(int err_code)
+{
+ m_errno_main = err_code;
+}
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/errno/errno.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/errno/errno.h
new file mode 100644
index 0000000..f2ec459
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/errno/errno.h
@@ -0,0 +1,76 @@
+/**
+ * Copyright (c) 2015 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#ifndef ERRNO_H__
+#define ERRNO_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define EBADF 9
+#define ENOMEM 12
+#define EFAULT 14
+#define EINVAL 22
+#define EMFILE 24
+#define EAGAIN 35
+#define EPROTONOSUPPORT 43
+#define EOPNOTSUPP 45
+#define EAFNOSUPPORT 47
+#define EADDRINUSE 48
+#define ENETDOWN 50
+#define ENETUNREACH 51
+#define ECONNRESET 54
+#define EISCONN 56
+#define ENOTCONN 57
+#define ETIMEDOUT 60
+
+#define EINPROGRESS 115 /* Operation in progress. */
+#define ECANCELED 125 /* Operation canceled. */
+int * __error(void);
+void set_errno(int);
+
+#undef errno
+#define errno (* __error())
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // ERRNO_H__
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/iot_file/iot_file.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/iot_file/iot_file.c
new file mode 100644
index 0000000..285be29
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/iot_file/iot_file.c
@@ -0,0 +1,195 @@
+/**
+ * Copyright (c) 2015 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#include "sdk_config.h"
+#include "iot_file.h"
+#include "iot_common.h"
+
+/**
+ * @defgroup api_param_check API Parameters check macros.
+ *
+ * @details Macros that verify parameters passed to the module in the APIs. These macros
+ * could be mapped to nothing in final versions of code to save execution and size.
+ * IOT_FILE_DISABLE_API_PARAM_CHECK should be set to 0 to enable these checks.
+ *
+ * @{
+ */
+#if (IOT_FILE_DISABLE_API_PARAM_CHECK == 0)
+
+/**@brief Verify NULL parameters are not passed to API by application. */
+#define NULL_PARAM_CHECK(PARAM) \
+ if ((PARAM) == NULL) \
+ { \
+ return (NRF_ERROR_NULL | IOT_FILE_ERR_BASE); \
+ }
+
+#else // IOT_FILE_DISABLE_API_PARAM_CHECK
+
+#define NULL_PARAM_CHECK(PARAM)
+
+#endif // IOT_FILE_DISABLE_API_PARAM_CHECK
+/** @} */
+
+
+/**
+ * @brief Function to open IoT file. Depending on port, it should allocate required buffer.
+ */
+uint32_t iot_file_fopen(iot_file_t * p_file, uint32_t requested_size)
+{
+ NULL_PARAM_CHECK(p_file);
+
+ if (p_file->open != NULL)
+ {
+ return p_file->open(p_file, requested_size);
+ }
+ else
+ {
+ p_file->buffer_size = requested_size;
+ return NRF_ERROR_API_NOT_IMPLEMENTED;
+ }
+}
+
+
+/**
+ * @brief Function to write data buffer into a file.
+ */
+uint32_t iot_file_fwrite(iot_file_t * p_file, const void * p_data, uint32_t size)
+{
+ NULL_PARAM_CHECK(p_file);
+
+ if (p_file->write != NULL)
+ {
+ return p_file->write(p_file, p_data, size);
+ }
+ else
+ {
+ return NRF_ERROR_API_NOT_IMPLEMENTED;
+ }
+}
+
+
+/**
+ * @brief Function to read data buffer from file.
+ */
+uint32_t iot_file_fread(iot_file_t * p_file, void * p_data, uint32_t size)
+{
+ NULL_PARAM_CHECK(p_file);
+
+ if (p_file->read != NULL)
+ {
+ return p_file->read(p_file, p_data, size);
+ }
+ else
+ {
+ return NRF_ERROR_API_NOT_IMPLEMENTED;
+ }
+}
+
+
+/**
+ * @brief Function to read current cursor position.
+ */
+uint32_t iot_file_ftell(iot_file_t * p_file, uint32_t * p_cursor)
+{
+ NULL_PARAM_CHECK(p_file);
+
+ if (p_file->tell != NULL)
+ {
+ return p_file->tell(p_file, p_cursor);
+ }
+ else
+ {
+ return NRF_ERROR_API_NOT_IMPLEMENTED;
+ }
+}
+
+
+/**
+ * @brief Function to set current cursor position.
+ */
+uint32_t iot_file_fseek(iot_file_t * p_file, uint32_t cursor)
+{
+ NULL_PARAM_CHECK(p_file);
+
+ if (p_file->seek != NULL)
+ {
+ return p_file->seek(p_file, cursor);
+ }
+ else
+ {
+ return NRF_ERROR_API_NOT_IMPLEMENTED;
+ }
+}
+
+
+/**
+ * @brief Function to rewind file cursor.
+ */
+uint32_t iot_file_frewind(iot_file_t * p_file)
+{
+ NULL_PARAM_CHECK(p_file);
+
+ if (p_file->rewind != NULL)
+ {
+ return p_file->rewind(p_file);
+ }
+ else
+ {
+ return NRF_ERROR_API_NOT_IMPLEMENTED;
+ }
+}
+
+
+/**
+ * @brief Function to close IoT file. Depending on port, it should free used buffer.
+ */
+uint32_t iot_file_fclose(iot_file_t * p_file)
+{
+ NULL_PARAM_CHECK(p_file);
+
+ if (p_file->close != NULL)
+ {
+ return p_file->close(p_file);
+ }
+ else
+ {
+ return NRF_ERROR_API_NOT_IMPLEMENTED;
+ }
+}
+
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/iot_file/iot_file.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/iot_file/iot_file.h
new file mode 100644
index 0000000..c4afa7b
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/iot_file/iot_file.h
@@ -0,0 +1,175 @@
+/**
+ * Copyright (c) 2015 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 iot_file.h
+ * @brief IoT File abstraction API.
+ */
+
+#ifndef IOT_FILE_H__
+#define IOT_FILE_H__
+
+#include "iot_common.h"
+#include "iot_file_port.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @ingroup iot_sdk_common
+ * @addtogroup iot_file IoT File
+ * @brief IoT File abstraction definition.
+ * @{
+ * @defgroup iot_file_abstraction IoT file abstraction
+ * @{
+ * @brief Structures and public API definition.
+ */
+
+/**
+ * @enum iot_file_evt_t
+ * @brief List of events returned in callback for file ports with asynchronous operation
+ * like open, read, write and close.
+ */
+typedef enum {
+ IOT_FILE_OPENED, /**< Event indicates that file has been opened.*/
+ IOT_FILE_WRITE_COMPLETE, /**< Event indicates that single write operation has been completed.*/
+ IOT_FILE_READ_COMPLETE, /**< Event indicates that single read operation has been completed.*/
+ IOT_FILE_CLOSED, /**< Event indicates that file has been closed.*/
+ IOT_FILE_ERROR /**< Event indicates that file encountered a problem.*/
+} iot_file_evt_t;
+
+/**
+ * @brief IoT File user callback type definition.
+ *
+ * @param[in] p_file Reference to an IoT file instance.
+ * @param[in] event Event structure describing what has happened.
+ * @param[in] result Result code (should be NRF_SUCCESS for all events except errors).
+ * @param[in] p_data Pointer to memory buffer.
+ * @param[in] size Size of data stored in memory buffer.
+ *
+ * @retval None.
+ */
+typedef void (*iot_file_callback_t) (iot_file_t * p_file, iot_file_evt_t event, uint32_t result, void * p_data, uint32_t size);
+
+/**
+ * @brief Function to open IoT file. Depending on port, it should allocate required buffer.
+ *
+ * @param[in] p_file Pointer to an IoT file instance.
+ * @param[in] requested_size Maximum number of bytes to be read/written.
+ *
+ * @retval NRF_SUCCESS on successful execution of procedure, else an error code indicating reason
+ * for failure.
+ */
+uint32_t iot_file_fopen(iot_file_t * p_file, uint32_t requested_size);
+
+/**
+ * @brief Function to write data buffer into a file.
+ *
+ * @param[in] p_file Pointer to an IoT file instance.
+ * @param[in] p_data Pointer to data block which will be written into the file.
+ * @param[in] size Number of bytes to be written.
+ *
+ * @retval NRF_SUCCESS on successful execution of procedure, else an error code indicating reason
+ * for failure.
+ */
+uint32_t iot_file_fwrite(iot_file_t * p_file, const void * p_data, uint32_t size);
+
+/**
+ * @brief Function to read data buffer from file.
+ *
+ * @param[in] p_file Pointer to an IoT file instance.
+ * @param[in] p_data Pointer to data block to be filled with read data.
+ * @param[in] size Number of bytes to be read.
+ *
+ * @retval NRF_SUCCESS on successful execution of procedure, else an error code indicating reason
+ * for failure.
+ */
+uint32_t iot_file_fread(iot_file_t * p_file, void * p_data, uint32_t size);
+
+/**
+ * @brief Function to read current cursor position.
+ *
+ * @param[in] p_file Pointer to an IoT file instance.
+ * @param[out] p_cursor Current value of a cursor.
+ *
+ * @retval NRF_SUCCESS on successful execution of procedure, else an error code indicating reason
+ * for failure.
+ */
+uint32_t iot_file_ftell(iot_file_t * p_file, uint32_t * p_cursor);
+
+/**
+ * @brief Function to set current cursor position.
+ *
+ * @param[in] p_file Pointer to an IoT file instance.
+ * @param[in] cursor New cursor value.
+ *
+ * @retval NRF_SUCCESS on successful execution of procedure, else an error code indicating reason
+ * for failure.
+ */
+uint32_t iot_file_fseek(iot_file_t * p_file, uint32_t cursor);
+
+/**
+ * @brief Function to rewind file cursor.
+ *
+ * @param[in] p_file Pointer to an IoT file instance.
+ *
+ * @retval NRF_SUCCESS on successful execution of procedure, else an error code indicating reason
+ * for failure.
+ */
+uint32_t iot_file_frewind(iot_file_t * p_file);
+
+/**
+ * @brief Function to close IoT file. Depending on port, it should free used buffer.
+ *
+ * @param[in] p_file Pointer to an IoT file instance.
+ *
+ * @retval NRF_SUCCESS on successful execution of procedure, else an error code indicating reason
+ * for failure.
+ */
+uint32_t iot_file_fclose(iot_file_t * p_file);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // IOT_FILE_H__
+
+/** @} */
+/** @} */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/iot_file/iot_file_port.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/iot_file/iot_file_port.h
new file mode 100644
index 0000000..23e53d3
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/iot_file/iot_file_port.h
@@ -0,0 +1,147 @@
+/**
+ * Copyright (c) 2015 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 iot_file_port.h
+ * @brief Types and definitions used while writing port.
+ */
+
+#ifndef IOT_FILE_PORT_H__
+#define IOT_FILE_PORT_H__
+
+/**
+ * @defgroup iot_file_port_defs IoT file definition for port libraries.
+ * @{
+ * @ingroup iot_file
+ * @brief Type definitions for port modules.
+ */
+#include <stdint.h>
+#include <string.h>
+#include "nordic_common.h"
+#include "sdk_config.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+//NOTE: Port functions don't need to check if p_file exists, because call can be done only on a correct file instance.
+
+#define IOT_FILE_INVALID_CURSOR 0xFFFFFFFF
+
+/**
+ * @enum iot_file_type_t
+ * @brief Supported file type values.
+ */
+typedef enum
+{
+ IOT_FILE_TYPE_UNKNOWN = 0, /**< File type used for describing not initialized files. */
+ IOT_FILE_TYPE_PSTORAGE_RAW, /**< File type used for accessing flash memory. */
+ IOT_FILE_TYPE_STATIC /**< File type used for representing static buffers. */
+} iot_file_type_t;
+
+/**
+ * @brief iot_file_t structure forward definition.
+ */
+typedef struct iot_file_struct_t iot_file_t;
+
+/**
+ * @brief IoT File fopen() callback type definition.
+ */
+typedef uint32_t (*iot_fopen_t)(iot_file_t * p_file, uint32_t requested_size);
+
+/**
+ * @brief IoT File fwrite() callback type definition.
+ */
+typedef uint32_t (*iot_fwrite_t)(iot_file_t * p_file, const void * p_data, uint32_t size);
+
+/**
+ * @brief IoT File fread() callback type definition.
+ */
+typedef uint32_t (*iot_fread_t)(iot_file_t * p_file, void * p_data, uint32_t size);
+
+/**
+ * @brief IoT File ftell() callback type definition.
+ */
+typedef uint32_t (*iot_ftell_t)(iot_file_t * p_file, uint32_t * p_cursor);
+
+/**
+ * @brief IoT File fseek() callback type definition.
+ */
+typedef uint32_t (*iot_fseek_t)(iot_file_t * p_file, uint32_t cursor);
+
+/**
+ * @brief IoT File frewind() callback type definition.
+ */
+typedef uint32_t (*iot_frewind_t)(iot_file_t * p_file);
+
+/**
+ * @brief IoT File fclose() callback type definition.
+ */
+typedef uint32_t (*iot_fclose_t)(iot_file_t * p_file);
+
+/**
+ * @brief Generic IoT File instance structure.
+ */
+struct iot_file_struct_t
+{
+ const char * p_filename; /**< Public. String constant describing file name. */
+ iot_file_type_t type; /**< Public. Type of file. Each type should be added into iot_file_type_t enum. */
+ uint32_t file_size; /**< Public. Number of valid bytes inside file. */
+
+ uint32_t cursor; /**< Internal. Cursor describing which byte will be read/written. */
+ uint32_t buffer_size; /**< Internal. Size of data buffer. */
+ void * p_buffer; /**< Internal. Pointer to a data buffer set by calling fopen. */
+ void * p_callback; /**< Internal. User callback used in order to notify about finished file operations. */
+ void * p_arg; /**< Internal. User defined argument, used inside the port. */
+ iot_fopen_t open; /**< Internal. Callback for fopen operation assigned by particular port. */
+ iot_fwrite_t write; /**< Internal. Callback for fwrite operation assigned by particular port. */
+ iot_fread_t read; /**< Internal. Callback for fread operation assigned by particular port. */
+ iot_ftell_t tell; /**< Internal. Callback for ftell operation assigned by particular port. */
+ iot_fseek_t seek; /**< Internal. Callback for fseek operation assigned by particular port. */
+ iot_frewind_t rewind; /**< Internal. Callback for frewind operation assigned by particular port. */
+ iot_fclose_t close; /**< Internal. Callback for fclose operation assigned by particular port. */
+};
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // IOT_FILE_PORT_H__
+
+/** @} */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/iot_file/static/iot_file_static.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/iot_file/static/iot_file_static.c
new file mode 100644
index 0000000..4712992
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/iot_file/static/iot_file_static.c
@@ -0,0 +1,220 @@
+/**
+ * Copyright (c) 2015 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#include "sdk_config.h"
+#include "iot_file_static.h"
+#include "iot_common.h"
+#include <string.h>
+
+#if IOT_FILE_CONFIG_LOG_ENABLED
+
+#define NRF_LOG_MODULE_NAME iot_file_static
+
+#define NRF_LOG_LEVEL IOT_FILE_CONFIG_LOG_LEVEL
+#define NRF_LOG_INFO_COLOR IOT_FILE_CONFIG_INFO_COLOR
+#define NRF_LOG_DEBUG_COLOR IOT_FILE_CONFIG_DEBUG_COLOR
+
+#include "nrf_log.h"
+NRF_LOG_MODULE_REGISTER();
+
+#define FSTATIC_TRC NRF_LOG_DEBUG /**< Used for getting trace of execution in the module. */
+#define FSTATIC_ERR NRF_LOG_ERROR /**< Used for logging errors in the module. */
+#define FSTATIC_DUMP NRF_LOG_HEXDUMP_DEBUG /**< Used for dumping octet information to get details of bond information etc. */
+
+#else // IOT_FILE_CONFIG_LOG_ENABLED
+
+#define FSTATIC_TRC(...) /**< Disables traces. */
+#define FSTATIC_DUMP(...) /**< Disables dumping of octet streams. */
+#define FSTATIC_ERR(...) /**< Disables error logs. */
+
+#endif // IOT_FILE_CONFIG_LOG_ENABLED
+
+/**
+ * @defgroup api_param_check API Parameters check macros.
+ *
+ * @details Macros that verify parameters passed to the module in the APIs. These macros
+ * could be mapped to nothing in final versions of code to save execution and size.
+ * IOT_FILE_STATIC_DISABLE_API_PARAM_CHECK should be set to 0 to enable these checks.
+ *
+ * @{
+ */
+
+#if (IOT_FILE_DISABLE_API_PARAM_CHECK == 0)
+
+/**@brief Verify NULL parameters are not passed to API by application. */
+#define NULL_PARAM_CHECK(PARAM) \
+ if ((PARAM) == NULL) \
+ { \
+ return (NRF_ERROR_NULL | IOT_FILE_ERR_BASE); \
+ }
+
+#else // IOT_FILE_DISABLE_API_PARAM_CHECK
+
+#define NULL_PARAM_CHECK(PARAM)
+
+#endif // IOT_FILE_DISABLE_API_PARAM_CHECK
+/** @} */
+
+#define CHECK_CURSOR(PARAM) \
+ if ((PARAM) == IOT_FILE_INVALID_CURSOR) \
+ { \
+ return (NRF_ERROR_INVALID_STATE | IOT_FILE_ERR_BASE); \
+ }
+
+/**@brief Static buffer fwrite port function definition. */
+static uint32_t internal_fwrite(iot_file_t * p_file, const void * p_data, uint32_t size)
+{
+ NULL_PARAM_CHECK(p_data);
+ CHECK_CURSOR(p_file->cursor);
+
+ if ((size + p_file->cursor) > p_file->buffer_size)
+ {
+ return (NRF_ERROR_DATA_SIZE | IOT_FILE_ERR_BASE);
+ }
+
+ memcpy(((uint8_t *)p_file->p_buffer + p_file->cursor), p_data, size);
+ p_file->cursor += size;
+
+ if (p_file->cursor > p_file->file_size)
+ {
+ p_file->file_size = p_file->cursor;
+ }
+
+ return NRF_SUCCESS;
+}
+
+
+/**@brief Static buffer fread port function definition. */
+static uint32_t internal_fread(iot_file_t * p_file, void * p_data, uint32_t size)
+{
+ NULL_PARAM_CHECK(p_data);
+ CHECK_CURSOR(p_file->cursor);
+
+ if (size + p_file->cursor > p_file->file_size)
+ {
+ return (NRF_ERROR_DATA_SIZE | IOT_FILE_ERR_BASE);
+ }
+
+ memcpy(p_data, (uint8_t *)p_file->p_buffer + p_file->cursor, size);
+ p_file->cursor += size;
+
+ return NRF_SUCCESS;
+}
+
+
+/**@brief Static ftell port function definition. */
+static uint32_t internal_ftell(iot_file_t * p_file, uint32_t * p_cursor)
+{
+ NULL_PARAM_CHECK(p_cursor);
+ CHECK_CURSOR(p_file->cursor);
+
+ *p_cursor = p_file->cursor;
+
+ return NRF_SUCCESS;
+}
+
+
+/**@brief Static fseek port function definition. */
+static uint32_t internal_fseek(iot_file_t * p_file, uint32_t cursor)
+{
+ CHECK_CURSOR(p_file->cursor);
+
+ if (cursor > p_file->buffer_size)
+ {
+ FSTATIC_ERR("Cursor outside file!");
+ return (NRF_ERROR_INVALID_PARAM | IOT_FILE_ERR_BASE);
+ }
+
+ p_file->cursor = cursor;
+
+ return NRF_SUCCESS;
+}
+
+
+/**@brief Static frewind port function definition. */
+static uint32_t internal_frewind(iot_file_t * p_file)
+{
+ CHECK_CURSOR(p_file->cursor);
+
+ p_file->cursor = 0;
+
+ return NRF_SUCCESS;
+}
+
+
+/**@brief Static fopen port function definition. */
+static uint32_t internal_fopen(iot_file_t * p_file, uint32_t requested_size)
+{
+ p_file->cursor = 0;
+
+ if (requested_size != 0)
+ {
+ p_file->file_size = requested_size;
+ }
+
+ return NRF_SUCCESS;
+}
+
+
+/**@brief Static fclose port function definition. */
+static uint32_t internal_fclose(iot_file_t * p_file)
+{
+ p_file->cursor = IOT_FILE_INVALID_CURSOR;
+
+ return NRF_SUCCESS;
+}
+
+
+/**@brief This function is used to assign correct callbacks and file type to passed IoT File instance. */
+void iot_file_static_assign(iot_file_t * p_file)
+{
+ if (p_file == NULL)
+ {
+ return;
+ }
+
+ p_file->type = IOT_FILE_TYPE_STATIC;
+ p_file->write = internal_fwrite;
+ p_file->read = internal_fread;
+ p_file->tell = internal_ftell;
+ p_file->seek = internal_fseek;
+ p_file->rewind = internal_frewind;
+ p_file->open = internal_fopen;
+ p_file->close = internal_fclose;
+}
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/iot_file/static/iot_file_static.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/iot_file/static/iot_file_static.h
new file mode 100644
index 0000000..de3ea02
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/iot_file/static/iot_file_static.h
@@ -0,0 +1,86 @@
+/**
+ * Copyright (c) 2015 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 iot_file_static.h
+ * @brief FILE port for static buffers.
+ */
+
+#ifndef IOT_FILE_STATIC_H__
+#define IOT_FILE_STATIC_H__
+
+#include "iot_file_port.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @defgroup iot_file_static IoT file port for static buffers
+ * @ingroup iot_file
+ * @{
+ * @brief Macro function which simplifies file setup process and file type assigning function.
+ */
+
+/**
+ * @brief This macro function configures passed file as a static buffer file.
+ */
+#define IOT_FILE_STATIC_INIT(p_iot_file, p_file_name, p_mem, size) \
+ do { \
+ (p_iot_file)->p_filename = p_file_name; \
+ (p_iot_file)->cursor = IOT_FILE_INVALID_CURSOR; \
+ (p_iot_file)->p_buffer = p_mem; \
+ (p_iot_file)->buffer_size = size; \
+ (p_iot_file)->file_size = 0; \
+ (p_iot_file)->p_callback = NULL; \
+ iot_file_static_assign(p_iot_file); \
+ } while (0)
+
+/**
+ * @brief This function is used to assign correct callbacks and file type to passed IoT File instance.
+ */
+void iot_file_static_assign(iot_file_t * p_file);
+
+/** @} */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // IOT_FILE_STATIC_H__
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/iot_timer/iot_timer.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/iot_timer/iot_timer.c
new file mode 100644
index 0000000..96af2a6
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/iot_timer/iot_timer.c
@@ -0,0 +1,183 @@
+/**
+ * Copyright (c) 2015 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#include <string.h>
+#include "iot_timer.h"
+#include "sdk_common.h"
+#include "sdk_config.h"
+#include "iot_errors.h"
+
+/**
+ * @defgroup api_param_check API Parameters check macros.
+ *
+ * @details Macros that verify parameters passed to the module in the APIs. These macros
+ * could be mapped to nothing in final versions of code to save execution and size.
+ * IOT_TIMER_DISABLE_API_PARAM_CHECK should be defined to disable these checks.
+ *
+ * @{
+ */
+#if (IOT_TIMER_DISABLE_API_PARAM_CHECK == 0)
+
+/**
+ * @brief Verify NULL parameters are not passed to API by application.
+ */
+#define NULL_PARAM_CHECK(PARAM) \
+ if ((PARAM) == NULL) \
+ { \
+ return (NRF_ERROR_NULL | IOT_TIMER_ERR_BASE); \
+ }
+
+#define VERIFY_CLIENT_LIST_IS_VALID(PARAM) \
+ if ((PARAM) != NULL) \
+ { \
+ uint8_t i; \
+ for (i = 0; i < (PARAM)->client_list_length; i++) \
+ { \
+ if (((PARAM)->p_client_list[i].iot_timer_callback) == NULL) \
+ { \
+ return (NRF_ERROR_INVALID_PARAM | IOT_TIMER_ERR_BASE); \
+ } \
+ if (((PARAM)->p_client_list[i].cb_interval == 0) || \
+ ((PARAM)->p_client_list[i].cb_interval < IOT_TIMER_RESOLUTION_IN_MS) || \
+ (((PARAM)->p_client_list[i].cb_interval % IOT_TIMER_RESOLUTION_IN_MS) != 0)) \
+ { \
+ return (NRF_ERROR_INVALID_PARAM | IOT_TIMER_ERR_BASE); \
+ } \
+ } \
+ }
+
+#define VERIFY_WALL_CLOCK_VALUE_IS_VALID(PARAM) \
+ if ((PARAM) != NULL) \
+ { \
+ if ((*PARAM % IOT_TIMER_RESOLUTION_IN_MS) != 0) \
+ { \
+ return (NRF_ERROR_INVALID_PARAM | IOT_TIMER_ERR_BASE); \
+ } \
+ }
+
+/**
+ * @brief Verify NULL parameters are not passed to API by application.
+ */
+#define NULL_PARAM_CHECK(PARAM) \
+ if ((PARAM) == NULL) \
+ { \
+ return (NRF_ERROR_NULL | IOT_TIMER_ERR_BASE); \
+ }
+
+#else // IOT_TIMER_DISABLE_API_PARAM_CHECK
+
+#define NULL_PARAM_CHECK(PARAM)
+#define VERIFY_CLIENT_LIST_IS_VALID(PARAM)
+#define VERIFY_WALL_CLOCK_VALUE_IS_VALID(PARAM)
+
+#endif //IOT_TIMER_DISABLE_API_PARAM_CHECK
+/** @} */
+
+static iot_timer_time_in_ms_t m_wall_clock = 0;
+static const iot_timer_clients_list_t * m_clients = NULL;
+
+
+uint32_t iot_timer_client_list_set(const iot_timer_clients_list_t * p_list_of_clients)
+{
+ VERIFY_CLIENT_LIST_IS_VALID(p_list_of_clients);
+
+ m_clients = p_list_of_clients;
+ return NRF_SUCCESS;
+}
+
+
+uint32_t iot_timer_update(void)
+{
+ m_wall_clock += IOT_TIMER_RESOLUTION_IN_MS;
+ if ((0xFFFFFFFFUL - m_wall_clock) < IOT_TIMER_RESOLUTION_IN_MS)
+ {
+ m_wall_clock = IOT_TIMER_RESOLUTION_IN_MS;
+ }
+ if (m_clients != NULL)
+ {
+ uint8_t index;
+ for (index = 0; index < m_clients->client_list_length; index++)
+ {
+ if ((m_wall_clock % m_clients->p_client_list[index].cb_interval) == 0)
+ {
+ m_clients->p_client_list[index].iot_timer_callback(m_wall_clock);
+ }
+ }
+ }
+ return NRF_SUCCESS;
+}
+
+
+uint32_t iot_timer_wall_clock_get(iot_timer_time_in_ms_t * p_elapsed_time)
+{
+ NULL_PARAM_CHECK(p_elapsed_time);
+
+ *p_elapsed_time = m_wall_clock;
+ return NRF_SUCCESS;
+}
+
+
+uint32_t iot_timer_wall_clock_delta_get(iot_timer_time_in_ms_t * p_past_time, \
+ iot_timer_time_in_ms_t * p_delta_time)
+{
+ NULL_PARAM_CHECK(p_past_time);
+ NULL_PARAM_CHECK(p_delta_time);
+ VERIFY_WALL_CLOCK_VALUE_IS_VALID(p_past_time);
+
+ if (*p_past_time == m_wall_clock)
+ {
+ *p_delta_time = 0;
+ }
+ else if (*p_past_time < m_wall_clock)
+ {
+ *p_delta_time = m_wall_clock - *p_past_time;
+ }
+ else
+ {
+ // An integer overflow of the wall clock occured since *p_past_time.
+
+ iot_timer_time_in_ms_t max_wall_clock = (0xFFFFFFFFUL / IOT_TIMER_RESOLUTION_IN_MS) \
+ * IOT_TIMER_RESOLUTION_IN_MS;
+ *p_delta_time = max_wall_clock - *p_past_time; // Before overflow.
+ *p_delta_time += m_wall_clock; // After overflow.
+ *p_delta_time -= IOT_TIMER_RESOLUTION_IN_MS; // Because of handling of wall clock integer overflow, see above.
+ }
+
+ return NRF_SUCCESS;
+}
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/iot_timer/iot_timer.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/iot_timer/iot_timer.h
new file mode 100644
index 0000000..d7503b3
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/iot_timer/iot_timer.h
@@ -0,0 +1,175 @@
+/**
+ * Copyright (c) 2015 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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
+ *
+ * @defgroup iot_timer IoT Timer
+ * @{
+ * @ingroup iot_sdk_common
+ * @brief Timekeeping for other modules.
+ *
+ * @details The IoT Timer stores the value of the wall clock, which represents the time elapsed
+ * since startup (or an integer overflow). The unit of timekeeping is milliseconds.
+ * The IoT Timer module is conceived to be platform independent, therefore, it does not
+ * have an internal tick source. An external source has to update the wall clock of the
+ * IoT Timer at regular intervals.
+ * Other modules can query the current value of the wall clock and/or can act as clients
+ * of the IoT Timer by subscribing to callbacks that are repeated at regular intervals.
+ * You can configure the module by changing the @c sdk_config.h configuration file.
+ */
+
+#ifndef IOT_TIMER_H__
+#define IOT_TIMER_H__
+
+#include <stdint.h>
+#include "nrf_error.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define SEC_TO_MILLISEC(PARAM) (PARAM * 1000)
+
+/**@brief The type of an instant in milliseconds. */
+typedef uint32_t iot_timer_time_in_ms_t;
+
+/**@brief IoT Timer client callback type.
+ *
+ * @param[in] wall_clock_value The value of the wall clock that triggered the callback.
+ *
+ * @retval None.
+ *
+ */
+typedef void (*iot_timer_tick_cb)(iot_timer_time_in_ms_t wall_clock_value);
+
+/**@brief IoT Timer client structure.
+ *
+ * @note @ref cb_interval cannot be zero.
+ * @note @ref cb_interval must be greater or equal to @ref IOT_TIMER_RESOLUTION_IN_MS.
+ * @note If greater, @ref cb_interval must be an integral multiple of @ref IOT_TIMER_RESOLUTION_IN_MS.
+ */
+typedef struct
+{
+ iot_timer_tick_cb iot_timer_callback; /**< Callback procedure of the client. */
+ iot_timer_time_in_ms_t cb_interval; /**< Interval between repeated callbacks to the client. */
+} iot_timer_client_t;
+
+/**@brief IoT Timer client list structure. */
+typedef struct
+{
+ uint8_t client_list_length; /**< Total number of clients. */
+ const iot_timer_client_t * p_client_list; /**< Pointer to the constant array of clients or NULL. */
+} iot_timer_clients_list_t;
+
+/**@brief Function for setting the list of clients that subscribe for repeated callbacks from
+ * the module.
+ *
+ * @note To minimize drift between client callbacks, the callback function of each client
+ * should be designed in a way that the duration of execution does not vary and is as short
+ * as possible.
+ *
+ * @param[in] p_list_of_clients Address of the client list. Can be NULL to cancel all subscriptions.
+ * To see what parameters are valid, please see the description
+ * of @ref iot_timer_client_t.
+ *
+ * @retval NRF_SUCCESS Address of the list of clients successfully updated.
+ * @retval NRF_ERROR_INVALID_PARAM If any member of the client list has NULL as a callback
+ * procedure or the interval for repeated callbacks is smaller
+ * or equal to @ref IOT_TIMER_RESOLUTION_IN_MS or it is not
+ * an integral multiple of @ref IOT_TIMER_RESOLUTION_IN_MS.
+ *
+ */
+uint32_t iot_timer_client_list_set(const iot_timer_clients_list_t * p_list_of_clients);
+
+/**@brief Function for updating the wall clock.
+ *
+ * @details The application designer must ensure that this function is called at regular intervals,
+ * which is set in the @c sdk_config.h configuration file.
+ * If the updated value of the wall clock is an integral multiple of the callback interval
+ * of any clients of the module, the callback procedure of the client is executed.
+ *
+ * @note The interrupt that triggers the update of the wall clock should have a high relative
+ * priority to minimize inaccuracy.
+ *
+ * @retval NRF_SUCCESS Wall clock successfully updated.
+ *
+ */
+uint32_t iot_timer_update(void);
+
+/**@brief Function for getting the current wall clock value.
+ *
+ * @note The accuracy of timekeeping is limited by the resolution, as set in the @c sdk_config.h
+ * configuration file.
+ *
+ * @param[out] p_elapsed_time Value of the wall clock. Time in milliseconds elapsed since startup
+ * (or an integer overflow).
+ *
+ * @retval NRF_SUCCESS Query successful.
+ * @retval NRF_ERROR_NULL If @b p_elapsed_time is a NULL pointer.
+ *
+ */
+uint32_t iot_timer_wall_clock_get(iot_timer_time_in_ms_t * p_elapsed_time);
+
+/**@brief Function for getting the difference between the current and an older wall clock value.
+ *
+ * @note The accuracy of calculation is limited by the wall clock resolution, as set in
+ * the @c sdk_config.h configuration file.
+ * @note The time difference can only be calculated correctly if only at most one integer overflow
+ * of the wall clock has occured since the past wall clock value was obtained.
+ *
+ * @param[in] p_past_time Past value of the wall clock. Has to be an integral multiple of
+ * @ref IOT_TIMER_RESOLUTION_IN_MS or zero.
+ * @param[out] p_delta_time Time elapsed since @b p_past_time in milliseconds.
+ *
+ * @retval NRF_SUCCESS Query successful.
+ * @retval NRF_ERROR_NULL If @b p_past_time or @b p_delta_time is a NULL pointer.
+ * @retval NRF_ERROR_INVALID_PARAM If @b p_past_time points to a value that is not an integral
+ * multiple of @ref IOT_TIMER_RESOLUTION_IN_MS.
+ *
+ */
+uint32_t iot_timer_wall_clock_delta_get(iot_timer_time_in_ms_t * p_past_time, \
+ iot_timer_time_in_ms_t * p_delta_time);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // IOT_TIMER_H__
+
+/**@} */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/ipv6_parse/ipv6_parse.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/ipv6_parse/ipv6_parse.c
new file mode 100644
index 0000000..0581763
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/ipv6_parse/ipv6_parse.c
@@ -0,0 +1,167 @@
+/**
+ * Copyright (c) 2015 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#include <stddef.h>
+#include <stdbool.h>
+#include <string.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include "ipv6_parse.h"
+#include "nrf_error.h"
+
+static uint16_t ascii_to_hex(char * p_str)
+{
+ uint16_t res = 0;
+ sscanf(p_str, "%hx", &res);
+ return res;
+}
+
+static void reverse_string(char * p_str)
+{
+ uint32_t str_len = strlen(p_str);
+ for (uint32_t i = 0, j = str_len - 1; i < j; i++, j--)
+ {
+ char tmp = p_str[i];
+ p_str[i] = p_str[j];
+ p_str[j] = tmp;
+ }
+}
+
+uint32_t ipv6_parse_addr(uint8_t * p_addr, const char * p_uri, uint8_t uri_len)
+{
+ bool is_compressed = false;
+ uint8_t block_1_len = uri_len;
+
+ const char * compressed_position = strstr(&p_uri[0], "::");
+ if (compressed_position != NULL)
+ {
+ is_compressed = true;
+ block_1_len = compressed_position - &p_uri[0];
+ }
+ // Parse block 1.
+ uint8_t block_1_end = block_1_len;
+ char sub_addr_buf[5] = {'\0',};
+
+ uint8_t char_pos = 0;
+ uint8_t sub_addr_count_block_1 = 0;
+
+ for (uint8_t i = 0; i < block_1_end; i++)
+ {
+ if (p_uri[i] != ':')
+ {
+ sub_addr_buf[char_pos++] = p_uri[i];
+ }
+ else
+ {
+ // we have read all number bytes and hit a delimiter. Save the sub address.
+ uint16_t value = ascii_to_hex(sub_addr_buf);
+ p_addr[sub_addr_count_block_1++] = ((value & 0xFF00) >> 8);
+ p_addr[sub_addr_count_block_1++] = ((value & 0x00FF));
+
+ char_pos = 0;
+ memset(sub_addr_buf, '\0', 5);
+
+ }
+
+ // if we are at the end of block 1, save the last sub address.
+ if ((i + 1) == block_1_end)
+ {
+ uint16_t value = ascii_to_hex(sub_addr_buf);
+ p_addr[sub_addr_count_block_1++] = ((value & 0xFF00) >> 8);
+ p_addr[sub_addr_count_block_1++] = ((value & 0x00FF));
+
+
+ char_pos = 0;
+ memset(sub_addr_buf, '\0', 5);
+ }
+ }
+
+ if (is_compressed == true)
+ {
+ // NOTE: sub_addr_buf must be cleared in previous loop.
+
+ // lets parse backwards for second block.
+ uint8_t block_2_start = block_1_end + 2; // skip the '::' delimiter.
+ uint8_t block_2_len = uri_len - (block_1_len + 2);
+ uint8_t block_2_end = block_2_start + block_2_len;
+
+ uint8_t sub_addr_count_block_2 = 0;
+ uint8_t sub_addr_index = 15;
+
+ for (uint8_t i = block_2_end - 1; i > block_2_start - 1; i--)
+ {
+ if (p_uri[i] != ':')
+ {
+ sub_addr_buf[char_pos++] = p_uri[i];
+ }
+ else
+ {
+ // we have read all number bytes and hit a delimiter. Save the sub address.
+ reverse_string(sub_addr_buf);
+
+ uint16_t value = ascii_to_hex(sub_addr_buf);
+ p_addr[sub_addr_index--] = ((value & 0x00FF));
+ p_addr[sub_addr_index--] = ((value & 0xFF00) >> 8);
+ sub_addr_count_block_2 += 2;
+ char_pos = 0;
+ memset(sub_addr_buf, '\0', 5);
+
+ }
+
+ // if we are at the end of block 1, save the last sub address.
+ if (i == block_2_start)
+ {
+ reverse_string(sub_addr_buf);
+
+ uint16_t value = ascii_to_hex(sub_addr_buf);
+ p_addr[sub_addr_index--] = ((value & 0x00FF));
+ p_addr[sub_addr_index--] = ((value & 0xFF00) >> 8);
+ sub_addr_count_block_2 += 2;
+ char_pos = 0;
+ memset(sub_addr_buf, '\0', 5);
+ }
+ }
+
+ for (uint8_t i = sub_addr_count_block_1; i < (16 - sub_addr_count_block_2); i++)
+ {
+ p_addr[i] = 0x00;
+ }
+ }
+ return NRF_SUCCESS;
+}
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/ipv6_parse/ipv6_parse.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/ipv6_parse/ipv6_parse.h
new file mode 100644
index 0000000..218bfdf
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/ipv6_parse/ipv6_parse.h
@@ -0,0 +1,75 @@
+/**
+ * Copyright (c) 2015 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 ipv6_parse.h
+ *
+ * @defgroup iot_tools IoT Utility tools
+ * @ingroup iot_sdk_common
+ * @{
+ * @brief Common IoT utility tools like parsing IPv6 address from a URI.
+ *
+ * @details This module provides utility functions like parsing IPv6 address from a URI.
+ */
+#ifndef IPV6_PARSE_H__
+#define IPV6_PARSE_H__
+
+#include <stdint.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @brief IoT IPv6 address parsing.
+ *
+ * @details Supports parsing all legal IPv6 address formats as defined by the RFC.
+ *
+ * @param[out] p_addr Pointer to array large enough to hold parsed address. MUST be 16 bytes big.
+ * @param[in] p_uri String with address that should be parsed.
+ * @param[in] uri_len Length of p_uri string.
+ *
+ */
+uint32_t ipv6_parse_addr(uint8_t * p_addr, const char * p_uri, uint8_t uri_len);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // IPV6_PARSE_H__
+ /** @} */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/ipv6_stack/dns6/dns6.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/ipv6_stack/dns6/dns6.c
new file mode 100644
index 0000000..6c90ce3
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/ipv6_stack/dns6/dns6.c
@@ -0,0 +1,903 @@
+/**
+ * Copyright (c) 2015 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#include <stdint.h>
+#include <stdbool.h>
+#include <string.h>
+#include "sdk_errors.h"
+#include "sdk_os.h"
+#include "sdk_config.h"
+#include "iot_common.h"
+#include "iot_pbuffer.h"
+#include "mem_manager.h"
+#include "ipv6_api.h"
+#include "udp_api.h"
+#include "dns6_api.h"
+
+#if DNS6_CONFIG_LOG_ENABLED
+
+#define NRF_LOG_MODULE_NAME dns6
+
+#define NRF_LOG_LEVEL DNS6_CONFIG_LOG_LEVEL
+#define NRF_LOG_INFO_COLOR DNS6_CONFIG_INFO_COLOR
+#define NRF_LOG_DEBUG_COLOR DNS6_CONFIG_DEBUG_COLOR
+
+#include "nrf_log.h"
+NRF_LOG_MODULE_REGISTER();
+
+#define DNS6_TRC NRF_LOG_DEBUG /**< Used for getting trace of execution in the module. */
+#define DNS6_ERR NRF_LOG_ERROR /**< Used for logging errors in the module. */
+#define DNS6_DUMP NRF_LOG_HEXDUMP_DEBUG /**< Used for dumping octet information to get details of bond information etc. */
+
+#define DNS6_ENTRY() DNS6_TRC(">> %s", __func__)
+#define DNS6_EXIT() DNS6_TRC("<< %s", __func__)
+
+#else // DNS6_CONFIG_LOG_ENABLED
+
+#define DNS6_TRC(...) /**< Disables traces. */
+#define DNS6_DUMP(...) /**< Disables dumping of octet streams. */
+#define DNS6_ERR(...) /**< Disables error logs. */
+
+#define DNS6_ENTRY(...)
+#define DNS6_EXIT(...)
+
+#endif // DNS6_CONFIG_LOG_ENABLED
+
+/**
+ * @defgroup dns6_mutex_lock_unlock Module's Mutex Lock/Unlock Macros.
+ *
+ * @details Macros used to lock and unlock modules. Currently, SDK does not use mutexes but
+ * framework is provided in case need arises to use an alternative architecture.
+ * @{
+ */
+#define DNS6_MUTEX_LOCK() SDK_MUTEX_LOCK(m_dns6_mutex) /**< Lock module using mutex */
+#define DNS6_MUTEX_UNLOCK() SDK_MUTEX_UNLOCK(m_dns6_mutex) /**< Unlock module using mutex */
+/** @} */
+
+/**
+ * @defgroup api_param_check API Parameters check macros.
+ *
+ * @details Macros that verify parameters passed to the module in the APIs. These macros
+ * could be mapped to nothing in final versions of code to save execution and size.
+ * DNS6_DISABLE_API_PARAM_CHECK should be set to 0 to enable these checks.
+ *
+ * @{
+ */
+
+#if (DNS6_DISABLE_API_PARAM_CHECK == 0)
+
+/**@brief Macro to check is module is initialized before requesting one of the module procedures. */
+#define VERIFY_MODULE_IS_INITIALIZED() \
+ if (m_initialization_state == false) \
+ { \
+ return (SDK_ERR_MODULE_NOT_INITIALIZED | IOT_DNS6_ERR_BASE);\
+ }
+
+/**@brief Verify NULL parameters are not passed to API by application. */
+#define NULL_PARAM_CHECK(PARAM) \
+ if ((PARAM) == NULL) \
+ { \
+ return (NRF_ERROR_NULL | IOT_DNS6_ERR_BASE); \
+ }
+
+/**@brief Verify that empty parameters are not passed to API by application. */
+#define EMPTY_PARAM_CHECK(PARAM) \
+ if (*PARAM == 0) \
+ { \
+ return (NRF_ERROR_INVALID_DATA | IOT_DNS6_ERR_BASE); \
+ }
+
+#else // DNS6_DISABLE_API_PARAM_CHECK
+
+#define VERIFY_MODULE_IS_INITIALIZED()
+#define NULL_PARAM_CHECK(PARAM)
+#define EMPTY_PARAM_CHECK(PARAM)
+
+#endif // DNS6_DISABLE_API_PARAM_CHECK
+/** @} */
+
+/**@brief RFC1035 - DNS Header Fields and Values. */
+#define DNS_HEADER_FLAG1_QR_QUERY 0x00 /**< Bit specifies that message is a query. */
+#define DNS_HEADER_FLAG1_QR_RESPONSE 0x80 /**< Bit specifies that message is a response. */
+#define DNS_HEADER_FLAG1_OPCODE_STANDARD 0x00 /**< A standard type of query. */
+#define DNS_HEADER_FLAG1_OPCODE_INVERSE 0x08 /**< An inverse type of query. */
+#define DNS_HEADER_FLAG1_OPCODE_STATUS 0x10 /**< A server status request. */
+#define DNS_HEADER_FLAG1_AA 0x04 /**< Bit specifies that the responding name server is an authority for the domain name in question section. */
+#define DNS_HEADER_FLAG1_TC 0x02 /**< Bit specifies that message is truncated. */
+#define DNS_HEADER_FLAG1_RD 0x01 /**< Bit specifies that recursion is desired. */
+
+#define DNS_HEADER_FLAG2_RA 0x80 /**< Bit specifies if recursive query support is available in the name server. */
+#define DNS_HEADER_FLAG2_RCODE_NONE 0x00 /**< No error condition. */
+#define DNS_HEADER_FLAG2_RCODE_FORMAT_ERROR 0x01 /**< Error indicates that dns server is unable o interpret the query. */
+#define DNS_HEADER_FLAG2_RCODE_SERVER_FAILURE 0x02 /**< Error indicates that dns server has internal problem. */
+#define DNS_HEADER_FLAG2_RCODE_NAME_ERROR 0x03 /**< Error indicates that domain name referenced in the query does not exist. */
+#define DNS_HEADER_FLAG2_RCODE_NOT_IMPLEMENTED 0x04 /**< Error indicates that dns server does not support previously sent query. */
+#define DNS_HEADER_FLAG2_RCODE_REFUSED 0x05 /**< Error indicates that dns server refuses to perform operation. */
+#define DNS_HEADER_FLAG2_RCODE_MASK 0x0F /**< Bit mask of RCODE field. */
+
+#define DNS_QTYPE_A 0x0001 /**< QTYPE indicates IPv4 address. */
+#define DNS_QTYPE_CNAME 0x0005 /**< QTYPE indicates CNAME record. */
+#define DNS_QTYPE_AAAA 0x001C /**< QTYPE indicates IPv6 address. */
+
+#define DNS_QCLASS_IN 0x0001 /**< QCLASS indicates Internet type. */
+
+/**@brief DNS6 client module's defines. */
+#define DNS_LABEL_SEPARATOR '.' /**< Separator of hostname string. */
+#define DNS_LABEL_OFFSET 0xc0 /**< Byte indicates that offset is used to determine hostname. */
+
+#define DNS_HEADER_SIZE 12 /**< Size of DNS Header. */
+#define DNS_QUESTION_FOOTER_SIZE 4 /**< Size of DNS Question footer. */
+#define DNS_RR_BODY_SIZE 10 /**< Size of DNS Resource Record Body. */
+
+#define MESSAGE_ID_UNUSED 0 /**< Value indicates that record is unused and no request was performed yet. */
+#define MESSAGE_ID_INITIAL 0x0001 /**< Initial value of message id counter. */
+
+
+/**@brief DNS Header Format. */
+typedef struct
+{
+ uint16_t msg_id; /**< Query/Response message identifier. */
+ uint8_t flags_1; /**< Flags ( QR | Opcode | AA | TC | RD ). */
+ uint8_t flags_2; /**< Flags ( RA | Z | RCODE ). */
+ uint16_t qdcount; /**< The number of entries in the question section. */
+ uint16_t ancount; /**< The number of resource records in the answer section. */
+ uint16_t nscount; /**< The number of name server resource records in the authority records section. */
+ uint16_t arcount; /**< The number of resource records in the additional records section. */
+} dns_header_t;
+
+/**@brief DNS Question Footer Format. */
+typedef struct
+{
+ uint16_t qtype; /**< Type of the query. */
+ uint16_t qclass; /**< Class of the query. */
+} dns_question_footer_t;
+
+/**@brief DNS Resource AAAA Record Body Format. */
+typedef struct
+{
+ uint16_t rtype; /**< Type of the response. */
+ uint16_t rclass; /**< Class of the response. */
+ uint32_t rttl; /**< Time to Life field of the response. */
+ uint16_t rdlength; /**< Length of data in octets. */
+} dns_rr_body_t;
+
+/**@brief Structure holds pending query. */
+typedef struct
+{
+ uint16_t message_id; /**< Message id for DNS Query. */
+ uint8_t retries; /**< Number of already performed retries. */
+ uint8_t * p_hostname; /**< Pointer to hostname string in memory menager.*/
+ iot_timer_time_in_ms_t next_retransmission; /**< Time when next retransmission should be invoked. */
+ dns6_evt_handler_t evt_handler; /**< User registered callback. */
+} pending_query_t;
+
+SDK_MUTEX_DEFINE(m_dns6_mutex) /**< Mutex variable. Currently unused, this declaration does not occupy any space in RAM. */
+static bool m_initialization_state = false; /**< Variable to maintain module initialization state. */
+static pending_query_t m_pending_queries[DNS6_MAX_PENDING_QUERIES]; /**< Queue contains pending queries. */
+static uint16_t m_message_id_counter; /**< Message ID counter, used to generate unique message IDs. */
+static udp6_socket_t m_socket; /**< Socket information provided by UDP. */
+
+
+/**@brief Function for freeing query entry in pending queue.
+ *
+ * @param[in] index Index of query.
+ *
+ * @retval None.
+ */
+static void query_init(uint32_t index)
+{
+ if (m_pending_queries[index].p_hostname)
+ {
+ UNUSED_VARIABLE(nrf_free(m_pending_queries[index].p_hostname));
+ }
+
+ m_pending_queries[index].message_id = MESSAGE_ID_UNUSED;
+ m_pending_queries[index].retries = 0;
+ m_pending_queries[index].p_hostname = NULL;
+ m_pending_queries[index].evt_handler = NULL;
+ m_pending_queries[index].next_retransmission = 0;
+}
+
+
+/**@brief Function for adding new query to pending queue.
+ *
+ * @param[in] p_hostname Pointer to hostname string.
+ * @param[in] evt_handler User defined event to handle given query.
+ *
+ * @retval Index of element in pending queries' table or DNS6_MAX_PENDING_QUERIES if no memory.
+ */
+static uint32_t query_add(uint8_t * p_hostname, dns6_evt_handler_t evt_handler)
+{
+ uint32_t index;
+
+ for (index = 0; index < DNS6_MAX_PENDING_QUERIES; index++)
+ {
+ if (m_pending_queries[index].message_id == MESSAGE_ID_UNUSED)
+ {
+ m_pending_queries[index].message_id = m_message_id_counter++;
+ m_pending_queries[index].retries = 0;
+ m_pending_queries[index].p_hostname = p_hostname;
+ m_pending_queries[index].evt_handler = evt_handler;
+ m_pending_queries[index].next_retransmission = 0;
+
+ break;
+ }
+ }
+
+ return index;
+}
+
+
+/**@brief Function for finding element in pending queue with specific message_id.
+ *
+ * @param[in] message_id Message identifier to find.
+ *
+ * @retval Index of element in pending queue or DNS6_MAX_PENDING_QUERIES if nothing found.
+ */
+static uint32_t query_find(uint32_t message_id)
+{
+ uint32_t index;
+
+ for (index = 0; index < DNS6_MAX_PENDING_QUERIES; index++)
+ {
+ if (m_pending_queries[index].message_id == message_id)
+ {
+ break;
+ }
+ }
+
+ return index;
+}
+
+
+/**@brief Function for checking if retransmission time of DNS query has been expired.
+ *
+ * @param[in] index Index of pending query.
+ *
+ * @retval True if timer has been expired, False otherwise.
+ */
+static bool query_timer_is_expired(uint32_t index)
+{
+ uint32_t err_code;
+ iot_timer_time_in_ms_t wall_clock_value;
+
+ // Get wall clock time.
+ err_code = iot_timer_wall_clock_get(&wall_clock_value);
+
+ if (err_code == NRF_SUCCESS)
+ {
+ if (wall_clock_value >= m_pending_queries[index].next_retransmission)
+ {
+ return true;
+ }
+ }
+
+ return false;
+}
+
+
+/**@brief Function for setting retransmissions time of DNS query has been expired.
+ *
+ * @param[in] index Index of pending query.
+ *
+ * @retval None.
+ */
+static void query_timer_set(uint32_t index)
+{
+ uint32_t err_code;
+ iot_timer_time_in_ms_t wall_clock_value;
+
+ // Get wall clock time.
+ err_code = iot_timer_wall_clock_get(&wall_clock_value);
+
+ if (err_code == NRF_SUCCESS)
+ {
+ m_pending_queries[index].next_retransmission =
+ wall_clock_value + (DNS6_RETRANSMISSION_INTERVAL * 1000);
+ }
+}
+
+
+/**@brief Function for creating compressed hostname from string.
+ *
+ * @param[inout] p_dest Pointer to place where hostname will be compressed.
+ * @param[in] p_hostname Pointer to hostname string.
+ *
+ * @retval Number of used bytes to compress a hostname.
+ */
+static uint32_t compress_hostname(uint8_t * p_dest, const uint8_t * p_hostname)
+{
+ uint32_t index = 0;
+ uint32_t label_pos = 0;
+ uint8_t * p_original = p_dest;
+
+ // Elide first byte in destination buffer to put label.
+ p_dest++;
+
+ // Parse until string termination is found.
+ for (index = 0; p_hostname[index] != 0; index++)
+ {
+ // Look for string separator.
+ if (p_hostname[index] == DNS_LABEL_SEPARATOR)
+ {
+ // Put number of subsequent string to last label.
+ p_original[label_pos] = index - label_pos;
+
+ // Protection to stop compressing after getting incorrect sequence.
+ if (index == label_pos)
+ {
+ return index + 1;
+ }
+
+ label_pos = index + 1;
+ }
+ else
+ {
+ // Copy character of hostname to destination buffer.
+ *p_dest = p_hostname[index];
+ }
+
+ p_dest++;
+ }
+
+ // Set last label.
+ p_original[label_pos] = index - label_pos;
+
+ // Terminate compressed hostname with 0.
+ *p_dest = 0;
+
+ // Return length of compressed string.
+ return index + 2;
+}
+
+
+/**@brief Function for finding end of compressed hostname.
+ *
+ * @param[in] p_hostname Pointer to compressed hostname string.
+ *
+ * @retval Pointer to the end of compressed hostname.
+ */
+static uint8_t * skip_compressed_hostname(uint8_t * p_hostname)
+{
+ while (*p_hostname != 0)
+ {
+ if ((*p_hostname & DNS_LABEL_OFFSET) == DNS_LABEL_OFFSET)
+ {
+ return p_hostname + 2;
+ }
+ else
+ {
+ p_hostname += *p_hostname + 1;
+ }
+ }
+
+ return p_hostname + 1;
+}
+
+
+/**@brief Function for sending DNS query.
+ *
+ * @param[in] index Index of query.
+ *
+ * @retval NRF_SUCCESS on successful execution of procedure, else an error code indicating reason
+ * for failure.
+ */
+static uint32_t query_send(uint32_t index)
+{
+ uint32_t length;
+ uint32_t err_code;
+ iot_pbuffer_t * p_buffer;
+ iot_pbuffer_alloc_param_t buffer_param;
+
+ buffer_param.type = UDP6_PACKET_TYPE;
+ buffer_param.flags = PBUFFER_FLAG_DEFAULT;
+ buffer_param.length = DNS_HEADER_SIZE + DNS_QUESTION_FOOTER_SIZE +
+ strlen((const char *)m_pending_queries[index].p_hostname) + 2;
+
+ // Allocate packet buffer.
+ err_code = iot_pbuffer_allocate(&buffer_param, &p_buffer);
+
+ if (err_code == NRF_SUCCESS)
+ {
+ const dns_question_footer_t question_footer =
+ {
+ .qtype = HTONS(DNS_QTYPE_AAAA),
+ .qclass = HTONS(DNS_QCLASS_IN)
+ };
+
+ dns_header_t * p_dns_header = (dns_header_t *)p_buffer->p_payload;
+
+ // Fill DNS header fields.
+ p_dns_header->msg_id = HTONS(m_pending_queries[index].message_id);
+ p_dns_header->flags_1 = DNS_HEADER_FLAG1_QR_QUERY | DNS_HEADER_FLAG1_RD;
+ p_dns_header->flags_2 = DNS_HEADER_FLAG2_RCODE_NONE;
+
+ // Send only one question.
+ p_dns_header->qdcount = HTONS(1);
+ p_dns_header->ancount = HTONS(0);
+ p_dns_header->nscount = HTONS(0);
+ p_dns_header->arcount = HTONS(0);
+
+ // Start indexing from the end of the DNS header.
+ length = DNS_HEADER_SIZE;
+
+ // Compress and put hostname.
+ length += compress_hostname(&p_buffer->p_payload[length],
+ m_pending_queries[index].p_hostname);
+
+ // Add question footer.
+ memcpy(&p_buffer->p_payload[length], (uint8_t *)&question_footer, DNS_QUESTION_FOOTER_SIZE);
+
+ length += DNS_QUESTION_FOOTER_SIZE;
+
+ // Update packet buffer's data length.
+ p_buffer->length = length;
+
+ // Set retransmission timer.
+ query_timer_set(index);
+
+ // Send DNS query using UDP socket.
+ err_code = udp6_socket_send(&m_socket, p_buffer);
+
+ if (err_code != NRF_SUCCESS)
+ {
+ DNS6_ERR("Unable to send query on UDP socket. Reason %08lx.", err_code);
+
+ // Free the allocated buffer as send procedure has failed.
+ UNUSED_VARIABLE(iot_pbuffer_free(p_buffer, true));
+ }
+ }
+ else
+ {
+ DNS6_ERR("No memory to allocate packet buffer.");
+ }
+
+ return err_code;
+}
+
+
+/**@brief Function for notifying application of the DNS6 query status.
+ *
+ * @param[in] index Index of query.
+ * @param[in] process_result Variable indicates result of DNS query.
+ * @param[in] p_addr Pointer to memory that holds IPv6 addresses.
+ * @param[in] addr_count Number of found addresses.
+ *
+ * @retval None.
+ */
+static void app_notify(uint32_t index,
+ uint32_t process_result,
+ ipv6_addr_t * p_addr,
+ uint16_t addr_count)
+{
+ if (m_pending_queries[index].evt_handler)
+ {
+ DNS6_MUTEX_UNLOCK();
+
+ // Call handler of user request.
+ m_pending_queries[index].evt_handler(process_result,
+ (const char *)m_pending_queries[index].p_hostname,
+ p_addr,
+ addr_count);
+
+ DNS6_MUTEX_LOCK();
+ }
+}
+
+
+/**@brief Callback handler to receive data on the UDP port.
+ *
+ * @param[in] p_socket Socket identifier.
+ * @param[in] p_ip_header IPv6 header containing source and destination addresses.
+ * @param[in] p_udp_header UDP header identifying local and remote endpoints.
+ * @param[in] process_result Result of data reception, there could be possible errors like
+ * invalid checksum etc.
+ * @param[in] p_rx_packet Packet buffer containing the received data packet.
+ *
+ * @retval NRF_SUCCESS Indicates received data was handled successfully, else an an
+ * error code indicating reason for failure..
+ */
+static uint32_t server_response(const udp6_socket_t * p_socket,
+ const ipv6_header_t * p_ip_header,
+ const udp6_header_t * p_udp_header,
+ uint32_t process_result,
+ iot_pbuffer_t * p_rx_packet)
+{
+ uint32_t index;
+ uint32_t rr_index;
+ uint32_t err_code = NRF_SUCCESS;
+ ipv6_addr_t * p_addresses = NULL;
+ uint16_t addr_length = 0;
+
+ DNS6_MUTEX_LOCK();
+
+ DNS6_ENTRY();
+
+ // Check UDP process result and data length.
+ if ((process_result != NRF_SUCCESS) || p_rx_packet->length < DNS_HEADER_SIZE)
+ {
+ DNS6_ERR("Received erroneous response.");
+ err_code = (NRF_ERROR_INVALID_DATA | IOT_DNS6_ERR_BASE);
+ }
+ else
+ {
+ dns_header_t * p_dns_header = (dns_header_t *)p_rx_packet->p_payload;
+ uint8_t * p_data = &p_rx_packet->p_payload[DNS_HEADER_SIZE];
+ uint16_t qdcount = NTOHS(p_dns_header->qdcount);
+ uint16_t ancount = NTOHS(p_dns_header->ancount);
+
+ // Try to find a proper query for this response, else discard.
+ index = query_find(NTOHS(p_dns_header->msg_id));
+
+ if (index != DNS6_MAX_PENDING_QUERIES)
+ {
+ DNS6_TRC("Received response for hostname %s with %d answers.",
+ m_pending_queries[index].p_hostname, ancount);
+
+ // Check truncation error.
+ if (p_dns_header->flags_1 & DNS_HEADER_FLAG1_TC)
+ {
+ err_code = DNS6_RESPONSE_TRUNCATED;
+ }
+ else if (!(p_dns_header->flags_1 & DNS_HEADER_FLAG1_QR_RESPONSE))
+ {
+ err_code = (NRF_ERROR_INVALID_DATA | IOT_DNS6_ERR_BASE);
+ }
+ // Check response code.
+ else if (p_dns_header->flags_2 & DNS_HEADER_FLAG2_RCODE_MASK)
+ {
+ switch (p_dns_header->flags_2 & DNS_HEADER_FLAG2_RCODE_MASK)
+ {
+ case DNS_HEADER_FLAG2_RCODE_FORMAT_ERROR:
+ err_code = DNS6_FORMAT_ERROR;
+ break;
+
+ case DNS_HEADER_FLAG2_RCODE_SERVER_FAILURE:
+ err_code = DNS6_SERVER_FAILURE;
+ break;
+
+ case DNS_HEADER_FLAG2_RCODE_NAME_ERROR:
+ err_code = DNS6_HOSTNAME_NOT_FOUND;
+ break;
+
+ case DNS_HEADER_FLAG2_RCODE_NOT_IMPLEMENTED:
+ err_code = DNS6_NOT_IMPLEMENTED;
+ break;
+
+ case DNS_HEADER_FLAG2_RCODE_REFUSED:
+ err_code = DNS6_REFUSED_ERROR;
+ break;
+
+ default:
+ err_code = (NRF_ERROR_INVALID_DATA | IOT_DNS6_ERR_BASE);
+ break;
+ }
+ }
+ else if (ancount == 0)
+ {
+ // No answer found.
+ err_code = DNS6_HOSTNAME_NOT_FOUND;
+ }
+ else
+ {
+ dns_rr_body_t rr;
+
+ // Skip questions section.
+ for (rr_index = 0; rr_index < qdcount; rr_index++)
+ {
+ p_data = skip_compressed_hostname(p_data) + DNS_QUESTION_FOOTER_SIZE;
+ }
+
+ // Addresses are moved to beginning of the packet to ensure alignment is correct.
+ p_addresses = (ipv6_addr_t *)p_rx_packet->p_payload;
+
+ // Parse responses section.
+ for (rr_index = 0; rr_index < ancount; rr_index++)
+ {
+ p_data = skip_compressed_hostname(p_data);
+
+ // Fill resource record structure to fit alignment.
+ memcpy((uint8_t *)&rr, p_data, DNS_RR_BODY_SIZE);
+
+ if (NTOHS(rr.rtype) == DNS_QTYPE_AAAA && NTOHS(rr.rclass) == DNS_QCLASS_IN)
+ {
+ if (NTOHS(rr.rdlength) == IPV6_ADDR_SIZE)
+ {
+ DNS6_TRC("Found AAAA record with IPv6 address:");
+ DNS6_DUMP(p_data + DNS_RR_BODY_SIZE, IPV6_ADDR_SIZE);
+
+ // Move all addresses next to each other.
+ memmove(p_addresses[addr_length].u8,
+ p_data + DNS_RR_BODY_SIZE,
+ IPV6_ADDR_SIZE);
+
+ addr_length++;
+ }
+ }
+
+ p_data += DNS_RR_BODY_SIZE + NTOHS(rr.rdlength);
+ }
+
+ if (addr_length == 0)
+ {
+ DNS6_ERR("No IPv6 addresses was found.");
+
+ err_code = DNS6_HOSTNAME_NOT_FOUND;
+ }
+ }
+
+ // Notify application.
+ app_notify(index, err_code, p_addresses, addr_length);
+
+ // Initialize query entry.
+ query_init(index);
+ }
+ else
+ {
+ DNS6_ERR("Response with unknown message id.");
+ err_code = (NRF_ERROR_NOT_FOUND | IOT_DNS6_ERR_BASE);
+ }
+ }
+
+ DNS6_EXIT();
+
+ DNS6_MUTEX_UNLOCK();
+
+ return err_code;
+}
+
+
+uint32_t dns6_init(const dns6_init_t * p_dns_init)
+{
+ NULL_PARAM_CHECK(p_dns_init);
+
+ uint32_t index;
+ uint32_t err_code;
+
+ DNS6_ENTRY();
+
+ SDK_MUTEX_INIT(m_dns6_mutex);
+
+ DNS6_MUTEX_LOCK();
+
+ for (index = 0; index < DNS6_MAX_PENDING_QUERIES; index++)
+ {
+ query_init(index);
+ }
+
+ // Request new socket creation.
+ err_code = udp6_socket_allocate(&m_socket);
+
+ if (err_code == NRF_SUCCESS)
+ {
+ // Bind the socket to the local port.
+ err_code = udp6_socket_bind(&m_socket, IPV6_ADDR_ANY, p_dns_init->local_src_port);
+
+ if (err_code == NRF_SUCCESS)
+ {
+ // Connect to DNS server.
+ err_code = udp6_socket_connect(&m_socket,
+ &p_dns_init->dns_server.addr,
+ p_dns_init->dns_server.port);
+
+ if (err_code == NRF_SUCCESS)
+ {
+ // Register data receive callback.
+ err_code = udp6_socket_recv(&m_socket, server_response);
+ }
+ }
+
+ if (err_code == NRF_SUCCESS)
+ {
+ DNS6_TRC("Module initialization is complete.");
+
+ // Set initialization state flag if all procedures succeeded.
+ m_initialization_state = true;
+ m_message_id_counter = 0x0001;
+ }
+ else
+ {
+ DNS6_ERR("UDP socket initialization failed. Reason %08lx.", err_code);
+
+ // Not all procedures succeeded with allocated socket, hence free it.
+ UNUSED_VARIABLE(udp6_socket_free(&m_socket));
+ }
+ }
+
+ DNS6_EXIT();
+
+ DNS6_MUTEX_UNLOCK();
+
+ return err_code;
+}
+
+
+uint32_t dns6_uninit(void)
+{
+ VERIFY_MODULE_IS_INITIALIZED();
+
+ uint32_t index;
+
+ DNS6_ENTRY();
+
+ DNS6_MUTEX_LOCK();
+
+ for (index = 0; index < DNS6_MAX_PENDING_QUERIES; index++)
+ {
+ query_init(index);
+ }
+
+ // Free UDP socket.
+ UNUSED_VARIABLE(udp6_socket_free(&m_socket));
+
+ // Clear initialization state flag.
+ m_initialization_state = false;
+
+ DNS6_EXIT();
+
+ DNS6_MUTEX_UNLOCK();
+
+ return NRF_SUCCESS;
+}
+
+
+uint32_t dns6_query(const char * p_hostname, dns6_evt_handler_t evt_handler)
+{
+ VERIFY_MODULE_IS_INITIALIZED();
+ NULL_PARAM_CHECK(evt_handler);
+ NULL_PARAM_CHECK(p_hostname);
+ EMPTY_PARAM_CHECK(p_hostname);
+
+ uint32_t index;
+ uint32_t err_code;
+ uint32_t hostname_length;
+ uint8_t * p_hostname_buff = NULL;
+
+ DNS6_ENTRY();
+
+ DNS6_MUTEX_LOCK();
+
+ // Calculate hostname length.
+ hostname_length = strlen(p_hostname) + 1;
+
+ // Allocate memory to make copy of hostname string.
+ err_code = nrf_mem_reserve(&p_hostname_buff, &hostname_length);
+
+ if (err_code == NRF_SUCCESS)
+ {
+ // Copy hostname to cache buffer.
+ strcpy((char *)p_hostname_buff, p_hostname);
+
+ // Add query to pending queue.
+ index = query_add(p_hostname_buff, evt_handler);
+
+ if (index != DNS6_MAX_PENDING_QUERIES)
+ {
+ // Create and send DNS Query.
+ err_code = query_send(index);
+
+ if (err_code != NRF_SUCCESS)
+ {
+ // Remove query from pending queue immediately.
+ query_init(index);
+ }
+ }
+ else
+ {
+ DNS6_ERR("No place in pending queue.");
+
+ // No place in pending queue.
+ err_code = (NRF_ERROR_NO_MEM | IOT_DNS6_ERR_BASE);
+ }
+
+ // Not all procedures succeeded with sending query, hence free buffer for hostname.
+ if (err_code != NRF_SUCCESS)
+ {
+ UNUSED_VARIABLE(nrf_free(p_hostname_buff));
+ }
+ }
+ else
+ {
+ DNS6_ERR("No memory to allocate buffer for hostname.");
+ }
+
+ DNS6_EXIT();
+
+ DNS6_MUTEX_UNLOCK();
+
+ return err_code;
+}
+
+
+void dns6_timeout_process(iot_timer_time_in_ms_t wall_clock_value)
+{
+ uint32_t index;
+ uint32_t err_code;
+
+ UNUSED_PARAMETER(wall_clock_value);
+
+ DNS6_ENTRY();
+
+ DNS6_MUTEX_LOCK();
+
+ for (index = 0; index < DNS6_MAX_PENDING_QUERIES; index++)
+ {
+ if (m_pending_queries[index].message_id != MESSAGE_ID_UNUSED)
+ {
+ if (query_timer_is_expired(index))
+ {
+ err_code = NRF_SUCCESS;
+
+ if (m_pending_queries[index].retries < DNS6_MAX_RETRANSMISSION_COUNT)
+ {
+ DNS6_TRC("Query retransmission [%d] for hostname %s.",
+ m_pending_queries[index].retries, m_pending_queries[index].p_hostname);
+
+ // Increase retransmission number.
+ m_pending_queries[index].retries++;
+
+ // Send query again.
+ err_code = query_send(index);
+ }
+ else
+ {
+ DNS6_ERR("DNS server did not response on query for hostname %s.",
+ m_pending_queries[index].p_hostname);
+
+ // No response from server.
+ err_code = DNS6_SERVER_UNREACHABLE;
+ }
+
+ if (err_code != NRF_SUCCESS)
+ {
+ // Inform application that timeout occurs.
+ app_notify(index, err_code, NULL, 0);
+
+ // Remove query from pending queue.
+ query_init(index);
+ }
+ }
+ break;
+ }
+ }
+
+ DNS6_EXIT();
+
+ DNS6_MUTEX_UNLOCK();
+}
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/ipv6_stack/icmp6/icmp6.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/ipv6_stack/icmp6/icmp6.c
new file mode 100644
index 0000000..8c136b8
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/ipv6_stack/icmp6/icmp6.c
@@ -0,0 +1,1355 @@
+/**
+ * Copyright (c) 2013 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#include <stdio.h>
+#include <stdint.h>
+#include <stdbool.h>
+#include <string.h>
+
+#include "icmp6_api.h"
+#include "ipv6_api.h"
+#include "icmp6.h"
+#include "iot_context_manager.h"
+#include "ipv6_utils.h"
+#include "iot_common.h"
+
+#if ICMP6_CONFIG_LOG_ENABLED
+
+#define NRF_LOG_MODULE_NAME icmp6
+
+#define NRF_LOG_LEVEL ICMP6_CONFIG_LOG_LEVEL
+#define NRF_LOG_INFO_COLOR ICMP6_CONFIG_INFO_COLOR
+#define NRF_LOG_DEBUG_COLOR ICMP6_CONFIG_DEBUG_COLOR
+
+#include "nrf_log.h"
+NRF_LOG_MODULE_REGISTER();
+
+#define ICMP6_TRC NRF_LOG_DEBUG /**< Used for getting trace of execution in the module. */
+#define ICMP6_ERR NRF_LOG_ERROR /**< Used for logging errors in the module. */
+#define ICMP6_DUMP NRF_LOG_HEXDUMP_DEBUG /**< Used for dumping octet information to get details of bond information etc. */
+
+#define ICMP6_ENTRY() ICMP6_TRC(">> %s", __func__)
+#define ICMP6_EXIT() ICMP6_TRC("<< %s", __func__)
+
+#else // ICMP6_CONFIG_LOG_ENABLED
+
+#define ICMP6_TRC(...) /**< Disables traces. */
+#define ICMP6_DUMP(...) /**< Disables dumping of octet streams. */
+#define ICMP6_ERR(...) /**< Disables error logs. */
+
+#define ICMP6_ENTRY(...)
+#define ICMP6_EXIT(...)
+
+#endif // ICMP6_CONFIG_LOG_ENABLED
+
+/**
+ * @defgroup api_param_check API Parameters check macros.
+ *
+ * @details Macros that verify parameters passed to the module in the APIs. These macros
+ * could be mapped to nothing in final versions of code to save execution and size.
+ * ICMP6_DISABLE_API_PARAM_CHECK should be set to 1 to disable these checks.
+ *
+ * @{
+ */
+#if (ICMP6_DISABLE_API_PARAM_CHECK == 0)
+
+/**@brief Macro to check is module is initialized before requesting one of the module procedures. */
+#define VERIFY_MODULE_IS_INITIALIZED() \
+ if (m_initialization_state == false) \
+ { \
+ return (SDK_ERR_MODULE_NOT_INITIALIZED | IOT_ICMP6_ERR_BASE); \
+ }
+
+/**@brief Macro to check is module is initialized before requesting one of the module
+ procedures but does not use any return code. */
+#define VERIFY_MODULE_IS_INITIALIZED_VOID() \
+ if (m_initialization_state == false) \
+ { \
+ return; \
+ }
+
+/**
+ * @brief Verify NULL parameters are not passed to API by application.
+ */
+#define NULL_PARAM_CHECK(PARAM) \
+ if ((PARAM) == NULL) \
+ { \
+ return (NRF_ERROR_NULL | IOT_ICMP6_ERR_BASE); \
+ }
+
+/**
+ * @brief Verify packet buffer is of ICMP6 Type.
+ */
+#define PACKET_TYPE_CHECK(PACKET) \
+ if ((PACKET)->type != ICMP6_PACKET_TYPE) \
+ { \
+ return (NRF_ERROR_INVALID_PARAM | IOT_ICMP6_ERR_BASE); \
+ }
+
+
+#else // ICMP6_DISABLE_API_PARAM_CHECK
+
+#define VERIFY_MODULE_IS_INITIALIZED()
+#define VERIFY_MODULE_IS_INITIALIZED_VOID()
+#define NULL_PARAM_CHECK(PARAM)
+#define PACKET_TYPE_CHECK(PACKET)
+
+#endif // ICMP6_DISABLE_API_PARAM_CHECK
+/** @} */
+
+/**
+ * @defgroup icmp6_mutex_lock_unlock Module's Mutex Lock/Unlock Macros.
+ *
+ * @details Macros used to lock and unlock modules. Currently, SDK does not use mutexes but
+ * framework is provided in case need arises to use an alternative architecture.
+ * @{
+ */
+#define ICMP6_MUTEX_LOCK() SDK_MUTEX_LOCK(m_icmp6_mutex) /**< Lock module using mutex */
+#define ICMP6_MUTEX_UNLOCK() SDK_MUTEX_UNLOCK(m_icmp6_mutex) /**< Unlock module using mutex */
+/** @} */
+
+#define ND_NS_HEADER_SIZE 20 /**< Size of Neighbour Solicitation message. */
+#define ND_NA_HEADER_SIZE 20 /**< Size of Neighbour Advertisement message. */
+#define ND_RS_HEADER_SIZE 4 /**< Size of Router Solicitation message. */
+#define ND_RA_HEADER_SIZE 12 /**< Size of Router Advertisement message. */
+#define ND_PAYLOAD_ADJUST_OFFSET 4 /**< Adjusting ND related payload offset as the general ICMP structure is not upheld. */
+
+#define ND_NA_R_FLAG 0x80 /**< Router flag. When set, the R-bit indicates that the sender is a router. */
+#define ND_NA_S_FLAG 0x40 /**< Solicited flag. When set, the S-bit indicates that the advertisement was sent in response
+ to a Neighbor Solicitation .*/
+#define ND_NA_O_FLAG 0x20 /**< Override flag. When set, the O-bit indicates that the advertisement should override
+ an existing cache entry and update the cached link-layer address .*/
+
+#define ND_OPT_TYPE_SLLAO 1 /**< Source Link Layer Address Option. */
+#define ND_OPT_TYPE_TLLAO 2 /**< Target Link Layer Address Option. */
+#define ND_OPT_TYPE_PIO 3 /**< Prefix Information Option. */
+#define ND_OPT_TYPE_RHO 4 /**< Redirected Header Option. */
+#define ND_OPT_TYPE_MTU 5 /**< Maximum Transmit Unit Option. */
+#define ND_OPT_TYPE_ARO 33 /**< Address Registration Option. */
+#define ND_OPT_TYPE_6CO 34 /**< 6LoWPAN Context Option. */
+#define ND_OPT_TYPE_6ABRO 35 /**< Authoritative Border Router Option. */
+
+#define ND_OPT_SLLAO_SIZE (8 * (((IPV6_LL_ADDR_SIZE) / 8) + 1)) /**< Size of SLLAO option. */
+#define ND_OPT_TLLAO_SIZE (8 * (((IPV6_LL_ADDR_SIZE) / 8) + 1)) /**< Size of TLLAO option. */
+#define ND_OPT_PIO_SIZE 32 /**< Size of PIO option. */
+#define ND_OPT_MTU_SIZE 8 /**< Size of MTU option. */
+#define ND_OPT_ARO_SIZE 16 /**< Size of ARO option. */
+#define ND_OPT_6CO_SIZE 24 /**< Size of 6CO option. */
+#define ND_OPT_6ABRO_SIZE 24 /**< Size of 6ABRO option. */
+
+#define ND_OPT_SLLAO_LENGTH ((ND_OPT_SLLAO_SIZE) / 8) /**< Value of length field in SLLAO option. */
+#define ND_OPT_TLLAO_LENGTH ((ND_OPT_TLLAO_SIZE) / 8) /**< Value of length field in SLLAO option. */
+#define ND_OPT_ARO_LENGTH 2 /**< Value of length field in ARO option. */
+
+#define ND_OPT_6CO_CID_MASK 0x0F
+#define ND_OPT_6CO_CID_POS 0
+#define ND_OPT_6CO_C_MASK 0x10
+#define ND_OPT_6CO_C_POS 4
+
+#define ND_OPT_PIO_L_MASK 0x80
+#define ND_OPT_PIO_L_POS 7
+#define ND_OPT_PIO_A_MASK 0x40
+#define ND_OPT_PIO_A_POS 6
+
+#define ND_HOP_LIMIT 255 /**< Value of Hop Limit used in Neighbour Discovery procedure. */
+
+#define ICMP6_OFFSET IPV6_IP_HEADER_SIZE + ICMP6_HEADER_SIZE /**< Offset of ICMPv6 packet type. */
+
+#define ERROR_ADDITIONAL_HEADER_SIZE 4 /**< Additional 4 bytes of information every ICMP error message contains. */
+#define ERROR_MESSAGE_HEADER_SIZE (ICMP6_HEADER_SIZE + ERROR_ADDITIONAL_HEADER_SIZE) /**< Error message header size including type, code, checksum and 32-bit parameter. */
+#define ICMP6_ERROR_OFFSET IPV6_IP_HEADER_SIZE + ERROR_MESSAGE_HEADER_SIZE /**< Offset for ICMPv6 error message. */
+
+/**@brief Neighbor Solicitation header. */
+typedef struct
+{
+ uint32_t reserved; /**< Reserved field. */
+ ipv6_addr_t target_addr; /**< Target Address field. */
+} icmp6_ns_header_t;
+
+/**@brief Neighbor Advertisement header. */
+typedef struct
+{
+ uint8_t flags; /**< Flags (R,S and O). */
+ uint8_t reserved; /**< Reserved field. */
+ ipv6_addr_t target_addr; /**< Target Address field. */
+} icmp6_na_header_t;
+
+/**@brief Router Solicitation message's header. */
+typedef struct
+{
+ uint32_t reserved; /**< Reserved field. */
+} icmp6_rs_header_t;
+
+/**@brief Option header of ICMPv6 packet. */
+typedef struct
+{
+ uint8_t type; /**< Option type. */
+ uint8_t length; /**< Length, in unit of 8 octets. */
+} nd_option_t;
+
+/**@brief Source Link Layer Address Option header format. */
+typedef struct
+{
+ uint8_t type; /**< Option type. */
+ uint8_t length; /**< Length, units of 8 octets. */
+ eui64_t addr; /**< Link-layer address. */
+ uint8_t padding[6]; /**< Padding. */
+} nd_option_sllao_t;
+
+/**@brief Target Link Layer Address Option header format. */
+typedef struct
+{
+ uint8_t type; /**< Option type. */
+ uint8_t length; /**< Length, units of 8 octets. */
+ eui64_t addr; /**< Link-layer address. */
+ uint8_t padding[6]; /**< Padding. */
+} nd_option_tllao_t;
+
+/**@brief Prefix Information Option header format. */
+typedef struct
+{
+ uint8_t type; /**< Option type. */
+ uint8_t length; /**< Length, units of 8 octets. */
+ uint8_t prefix_length; /**< Prefix length. */
+ uint8_t flags; /**< Flags (L/A) and reserved. */
+ uint32_t valid_lifetime; /**< Valid Lifetime. */
+ uint32_t preferred_lifetime; /**< Preferred Lifetime. */
+ uint32_t reserved; /**< Reserved field. */
+ ipv6_addr_t prefix; /**< Prefix address. */
+} nd_option_pio_t;
+
+/**@brief Address Registration Option header format. */
+typedef struct
+{
+ uint8_t type; /**< Option type. */
+ uint8_t length; /**< Length, units of 8 octets. */
+ uint8_t status; /**< Status of ARO. */
+ uint8_t reserved; /**< Reserved1, split to avoid alignment. */
+ uint16_t reserved2; /**< Reserved2, split to avoid alignment. */
+ uint16_t registration_lifetime; /**< Registration Lifetime. */
+ eui64_t eui64; /**< EUI-64 source address. */
+} nd_option_aro_t;
+
+/**@brief 6LoWPAN Context Option header format. */
+typedef struct
+{
+ uint8_t type; /**< Option type. */
+ uint8_t length; /**< Length, units of 8 octets. */
+ uint8_t context_length; /**< Context Length. */
+ uint8_t CID_C; /**< 4-bit Context and 1-bit context compression flag. */
+ uint16_t reserved; /**< Reserved. */
+ uint16_t valid_lifetime; /**< Valid Lifetime. */
+ ipv6_addr_t context; /**< Context IPv6 Prefix. */
+} nd_option_6co_t;
+
+static bool m_initialization_state = false; /**< Variable to maintain module initialization state. */
+static uint16_t m_sequence_number = 0; /**< Sequence number from ICMPv6 packet. */
+static icmp6_receive_callback_t m_event_handler = NULL; /**< Application event handler. */
+SDK_MUTEX_DEFINE(m_icmp6_mutex) /**< Mutex variable. Currently unused, this declaration does not occupy any space in RAM. */
+
+/**@brief Function for initializing default values of IP Header for ICMP.
+ *
+ * @param[in] p_ip_header Pointer to IPv6 header.
+ * @param[in] hoplimit Hop Limit in IPv6 header.
+ *
+ * @return None.
+ */
+static __INLINE void icmp_ip_header(ipv6_header_t * p_ip_header, uint8_t hoplimit)
+{
+ ipv6_header_init(p_ip_header);
+ p_ip_header->next_header = IPV6_NEXT_HEADER_ICMP6;
+ p_ip_header->hoplimit = hoplimit;
+}
+
+/**@brief Function for adding SLLAO option to the packet.
+ *
+ * @param[in] p_interface Pointer to IoT interface.
+ * @param[in] p_data Pointer to the memory where SLLAO option should be added.
+ *
+ * @return None.
+ */
+static __INLINE void add_sllao_opt(const iot_interface_t * p_interface, nd_option_sllao_t * p_sllao)
+{
+ p_sllao->type = ND_OPT_TYPE_SLLAO;
+ p_sllao->length = ND_OPT_SLLAO_LENGTH;
+
+#if (IPV6_LL_ADDR_SIZE == 6)
+ memcpy(p_sllao->addr.identifier, p_interface->local_addr.identifier, 3);
+ memcpy(p_sllao->addr.identifier + 3, p_interface->local_addr.identifier + 5, 3);
+#else
+ // Copy EUI-64 and add padding.
+ memcpy(p_sllao->addr.identifier, p_interface->local_addr.identifier, IPV6_LL_ADDR_SIZE);
+ memset(p_sllao->padding, 0, 6);
+#endif
+}
+
+/**@brief Function for adding TLLAO option to the packet.
+ *
+ * @param[in] p_interface Pointer to IoT interface.
+ * @param[in] p_data Pointer to the memory where TLLAO option should be added.
+ *
+ * @return None.
+ */
+static __INLINE void add_tllao_opt(const iot_interface_t * p_interface, nd_option_tllao_t * p_tllao)
+{
+ p_tllao->type = ND_OPT_TYPE_TLLAO;
+ p_tllao->length = ND_OPT_TLLAO_LENGTH;
+
+#if (IPV6_LL_ADDR_SIZE == 6)
+ memcpy(p_tllao->addr.identifier, p_interface->local_addr.identifier, 3);
+ memcpy(p_tllao->addr.identifier + 3, p_interface->local_addr.identifier + 5, 3);
+#else
+ // Copy EUI-64 and add padding.
+ memcpy(p_tllao->addr.identifier, p_interface->local_addr.identifier, IPV6_LL_ADDR_SIZE);
+ memset(p_tllao->padding, 0, 6);
+#endif
+}
+
+/**@brief Function for adding ARO option to packet.
+ *
+ * @param[in] p_interface Pointer to IoT interface.
+ * @param[in] p_data Pointer to the memory where ARO option should be added.
+ * @param[in] aro_lifetime Lifetime of registration.
+ *
+ * @return None.
+ */
+static __INLINE void add_aro_opt(const iot_interface_t * p_interface,
+ nd_option_aro_t * p_aro,
+ uint16_t aro_lifetime)
+{
+ p_aro->type = ND_OPT_TYPE_ARO;
+ p_aro->length = ND_OPT_ARO_LENGTH;
+ p_aro->status = 0x00;
+ p_aro->reserved = 0x00;
+ p_aro->reserved2 = 0x00;
+ p_aro->registration_lifetime = HTONS(aro_lifetime);
+
+ // Copy EUI-64 and add padding.
+ memcpy(p_aro->eui64.identifier, p_interface->local_addr.identifier, EUI_64_ADDR_SIZE);
+}
+
+#if (ICMP6_ENABLE_ND6_MESSAGES_TO_APPLICATION == 1 || ICMP6_ENABLE_ALL_MESSAGES_TO_APPLICATION == 1)
+
+/**@brief Function for notifying application of the ICMPv6 received packet.
+ *
+ * @param[in] p_interface Pointer to external interface from which packet come.
+ * @param[in] p_pbuffer Pointer to packet buffer of ICMP6_PACKET_TYPE.
+ * @param[in] process_result Result of internal processing packet.
+ *
+ * @return NRF_SUCCESS after successful processing, error otherwise.
+ */
+static uint32_t app_notify_icmp_data(iot_interface_t * p_interface,
+ iot_pbuffer_t * p_pbuffer,
+ uint32_t process_result)
+{
+ uint32_t err_code = NRF_SUCCESS;
+
+ if (m_event_handler != NULL)
+ {
+
+ ipv6_header_t * p_ip_header = (ipv6_header_t *)
+ (p_pbuffer->p_payload - ICMP6_HEADER_SIZE - IPV6_IP_HEADER_SIZE);
+ icmp6_header_t * p_icmp_header = (icmp6_header_t *)
+ (p_pbuffer->p_payload - ICMP6_HEADER_SIZE);
+
+ ICMP6_MUTEX_UNLOCK();
+
+ // Change byte order of ICMP header given to application.
+ p_icmp_header->checksum = NTOHS(p_icmp_header->checksum);
+
+ err_code = m_event_handler(p_interface,
+ p_ip_header,
+ p_icmp_header,
+ process_result,
+ p_pbuffer);
+
+ ICMP6_MUTEX_LOCK();
+ }
+
+ return err_code;
+}
+
+#endif
+
+#if (ICMP6_ENABLE_HANDLE_ECHO_REQUEST_TO_APPLICATION == 0)
+
+/**@brief Function for responding on ECHO REQUEST message.
+ *
+ * @param[in] p_interface Pointer to external interface from which packet come.
+ * @param[in] p_ip_header Pointer to IPv6 Header.
+ * @param[in] p_icmp_header Pointer to ICMPv6 header.
+ * @param[in] p_packet Pointer to packet buffer.
+ *
+ * @return NRF_SUCCESS after successful processing, error otherwise.
+ */
+static void echo_reply_send(iot_interface_t * p_interface,
+ ipv6_header_t * p_ip_header,
+ icmp6_header_t * p_icmp_header,
+ iot_pbuffer_t * p_packet)
+{
+ uint32_t err_code;
+ uint16_t checksum;
+ iot_pbuffer_t * p_pbuffer;
+ iot_pbuffer_alloc_param_t pbuff_param;
+
+ // Headers of new packet.
+ ipv6_header_t * p_reply_ip_header;
+ icmp6_header_t * p_reply_icmp_header;
+
+ ICMP6_TRC("Sending reply on Echo Request.");
+
+ // Requesting buffer for reply
+ pbuff_param.flags = PBUFFER_FLAG_DEFAULT;
+ pbuff_param.type = ICMP6_PACKET_TYPE;
+ pbuff_param.length = p_packet->length;
+
+ err_code = iot_pbuffer_allocate(&pbuff_param, &p_pbuffer);
+ if (err_code == NRF_SUCCESS)
+ {
+ p_reply_ip_header = (ipv6_header_t *)(p_pbuffer->p_payload - ICMP6_HEADER_SIZE -
+ IPV6_IP_HEADER_SIZE);
+ p_reply_icmp_header = (icmp6_header_t *)(p_pbuffer->p_payload - ICMP6_HEADER_SIZE);
+
+ // Change ICMP header.
+ p_reply_icmp_header->type = ICMP6_TYPE_ECHO_REPLY;
+ p_reply_icmp_header->code = 0;
+ p_reply_icmp_header->checksum = 0;
+
+ // IPv6 Header initialization.
+ icmp_ip_header(p_reply_ip_header, IPV6_DEFAULT_HOP_LIMIT);
+
+ p_reply_ip_header->destaddr = p_ip_header->srcaddr;
+ p_reply_ip_header->length = HTONS(p_pbuffer->length + ICMP6_HEADER_SIZE);
+
+ if (IPV6_ADDRESS_IS_MULTICAST(&p_ip_header->destaddr))
+ {
+ IPV6_CREATE_LINK_LOCAL_FROM_EUI64(&p_reply_ip_header->srcaddr,
+ p_interface->local_addr.identifier);
+ }
+ else
+ {
+ p_reply_ip_header->srcaddr = p_ip_header->destaddr;
+ }
+
+ // Set echo reply parameters.
+ p_reply_icmp_header->sp.echo.id = p_icmp_header->sp.echo.id;
+ p_reply_icmp_header->sp.echo.sequence = p_icmp_header->sp.echo.sequence;
+
+ // Copy user data.
+ memcpy(p_pbuffer->p_payload,
+ p_packet->p_payload,
+ p_packet->length);
+
+ // Calculate checksum.
+ checksum = p_pbuffer->length + ICMP6_HEADER_SIZE + IPV6_NEXT_HEADER_ICMP6;
+
+ ipv6_checksum_calculate(p_reply_ip_header->srcaddr.u8, IPV6_ADDR_SIZE, &checksum, false);
+ ipv6_checksum_calculate(p_reply_ip_header->destaddr.u8, IPV6_ADDR_SIZE, &checksum, false);
+ ipv6_checksum_calculate(p_pbuffer->p_payload - ICMP6_HEADER_SIZE,
+ p_pbuffer->length + ICMP6_HEADER_SIZE,
+ &checksum,
+ false);
+
+ p_reply_icmp_header->checksum = HTONS((~checksum));
+
+ p_pbuffer->p_payload -= ICMP6_OFFSET;
+ p_pbuffer->length += ICMP6_OFFSET;
+
+ // Send IPv6 packet.
+ err_code = ipv6_send(p_interface, p_pbuffer);
+
+ if (err_code != NRF_SUCCESS)
+ {
+ ICMP6_ERR("Cannot send packet buffer!");
+ }
+ }
+ else
+ {
+ ICMP6_ERR("Failed to allocate packet buffer!");
+ }
+}
+#endif
+
+
+/**@brief Function for responding on Neighbor Advertisement message.
+ *
+ * @param[in] p_interface Pointer to external interface from which packet come.
+ * @param[in] p_ip_header Pointer to IPv6 Header.
+ * @param[in] p_icmp_header Pointer to ICMPv6 header.
+ * @param[in] p_target_addr Pointer to the IPv6 address.
+ *
+ * @return NRF_SUCCESS after successful processing, error otherwise.
+ */
+static uint32_t na_send(iot_interface_t * p_interface,
+ ipv6_header_t * p_ip_header,
+ icmp6_header_t * p_icmp_header,
+ ipv6_addr_t * p_target_addr)
+{
+ uint32_t err_code;
+ uint16_t checksum;
+ iot_pbuffer_t * p_pbuffer;
+ iot_pbuffer_alloc_param_t pbuff_param;
+
+ // Headers of new packet.
+ ipv6_header_t * p_reply_ip_header;
+ icmp6_header_t * p_reply_icmp_header;
+ icmp6_na_header_t * p_reply_na_header;
+ nd_option_tllao_t * p_reply_opt_tllao_header;
+
+ ICMP6_TRC("Sending reply on Neighbor Solocitation.");
+
+ // Requesting buffer for reply
+ pbuff_param.flags = PBUFFER_FLAG_DEFAULT;
+ pbuff_param.type = ICMP6_PACKET_TYPE;
+ pbuff_param.length = ND_NA_HEADER_SIZE + ND_OPT_TLLAO_SIZE - ND_PAYLOAD_ADJUST_OFFSET;
+
+ err_code = iot_pbuffer_allocate(&pbuff_param, &p_pbuffer);
+ if (err_code == NRF_SUCCESS)
+ {
+ p_reply_ip_header = (ipv6_header_t *)(p_pbuffer->p_payload - ICMP6_HEADER_SIZE -
+ IPV6_IP_HEADER_SIZE);
+ p_reply_icmp_header = (icmp6_header_t *)(p_pbuffer->p_payload - ICMP6_HEADER_SIZE);
+
+ p_pbuffer->p_payload -= ND_PAYLOAD_ADJUST_OFFSET;
+
+ p_reply_na_header = (icmp6_na_header_t *)(p_pbuffer->p_payload);
+ p_reply_opt_tllao_header = (nd_option_tllao_t *)(p_pbuffer->p_payload + ND_NA_HEADER_SIZE);
+
+ p_pbuffer->p_payload += ND_PAYLOAD_ADJUST_OFFSET;
+
+ // Change ICMP header.
+ p_reply_icmp_header->type = ICMP6_TYPE_NEIGHBOR_ADVERTISEMENT;
+ p_reply_icmp_header->code = 0;
+ p_reply_icmp_header->checksum = 0;
+
+ // IPv6 Header initialization.
+ icmp_ip_header(p_reply_ip_header, ND_HOP_LIMIT);
+
+ p_reply_ip_header->srcaddr = *p_target_addr;
+ p_reply_ip_header->destaddr = p_ip_header->srcaddr;
+ p_reply_ip_header->length = HTONS(p_pbuffer->length + ICMP6_HEADER_SIZE);
+
+ p_reply_na_header->flags = ND_NA_S_FLAG | ND_NA_O_FLAG ;
+ p_reply_na_header->reserved = 0;
+ p_reply_na_header->target_addr = *p_target_addr;
+
+ // Add TLLAO option.
+ add_tllao_opt(p_interface, p_reply_opt_tllao_header);
+
+ // Calculate checksum.
+ checksum = p_pbuffer->length + ICMP6_HEADER_SIZE + IPV6_NEXT_HEADER_ICMP6;
+
+ ipv6_checksum_calculate(p_reply_ip_header->srcaddr.u8, IPV6_ADDR_SIZE, &checksum, false);
+ ipv6_checksum_calculate(p_reply_ip_header->destaddr.u8, IPV6_ADDR_SIZE, &checksum, false);
+ ipv6_checksum_calculate(p_pbuffer->p_payload - ICMP6_HEADER_SIZE,
+ p_pbuffer->length + ICMP6_HEADER_SIZE,
+ &checksum,
+ false);
+
+ p_reply_icmp_header->checksum = HTONS((~checksum));
+
+ p_pbuffer->p_payload -= ICMP6_OFFSET;
+ p_pbuffer->length += ICMP6_OFFSET;
+
+ // Send IPv6 packet.
+ err_code = ipv6_send(p_interface, p_pbuffer);
+
+ if (err_code != NRF_SUCCESS)
+ {
+ ICMP6_ERR("Cannot send packet buffer!");
+ }
+ }
+ else
+ {
+ ICMP6_ERR("Failed to allocate packet buffer!\r\n");
+ }
+
+ return err_code;
+}
+
+
+/**@brief Function for parsing Neighbor Solicitation message.
+ *
+ * @param[in] p_interface Pointer to external interface from which packet come.
+ * @param[in] p_ip_header Pointer to IPv6 Header.
+ * @param[in] p_icmp_header Pointer to ICMPv6 header.
+ * @param[in] p_packet Pointer to packet buffer.
+ *
+ * @return NRF_SUCCESS after successful processing, error otherwise.
+ */
+static uint32_t ns_input(iot_interface_t * p_interface,
+ ipv6_header_t * p_ip_header,
+ icmp6_header_t * p_icmp_header,
+ iot_pbuffer_t * p_packet)
+{
+ uint32_t err_code = NRF_SUCCESS;
+
+ // Read target address.
+ icmp6_ns_header_t * p_ns_header = (icmp6_ns_header_t *)p_packet->p_payload;
+
+ if (ipv6_address_check(p_interface, &p_ns_header->target_addr) == NRF_SUCCESS)
+ {
+ err_code = na_send(p_interface, p_ip_header, p_icmp_header, &p_ns_header->target_addr);
+ }
+
+ return err_code;
+}
+
+
+/**@brief Function for parsing Router Advertisement message.
+ * Because stack gives all control to application, internal RA parsing take care
+ * only on Context Identifier.
+ *
+ * @param[in] p_interface Pointer to external interface from which packet come.
+ * @param[in] p_ip_header Pointer to IPv6 Header.
+ * @param[in] p_icmp_header Pointer to ICMPv6 header.
+ * @param[in] p_packet Pointer to packet buffer.
+ *
+ * @return NRF_SUCCESS after successful processing, error otherwise.
+ */
+static uint32_t ra_input(iot_interface_t * p_interface,
+ ipv6_header_t * p_ip_header,
+ icmp6_header_t * p_icmp_header,
+ iot_pbuffer_t * p_packet)
+{
+ uint32_t err_code;
+ iot_context_t context;
+ iot_context_t * p_context;
+ uint16_t curr_opt_offset = ND_RA_HEADER_SIZE;
+ nd_option_t * p_opt = NULL;
+ nd_option_6co_t * p_6co = NULL;
+ nd_option_pio_t * p_pio = NULL;
+
+ if (!IPV6_ADDRESS_IS_LINK_LOCAL(&p_ip_header->srcaddr))
+ {
+ return ICMP6_INVALID_PACKET_DATA;
+ }
+
+ // Read all option we get.
+ while (curr_opt_offset < p_packet->length)
+ {
+ p_opt = (nd_option_t *)(p_packet->p_payload + curr_opt_offset);
+
+ if (p_opt->length == 0)
+ {
+ ICMP6_ERR("Invalid zero length option!");
+ return ICMP6_INVALID_PACKET_DATA;
+ }
+
+ ICMP6_TRC("Option type = 0x%02x!", p_opt->type);
+
+ // Searching for handling options.
+ switch (p_opt->type)
+ {
+ case ND_OPT_TYPE_PIO:
+ {
+ p_pio = (nd_option_pio_t *)p_opt;
+
+ if (p_pio->prefix_length != 0 &&
+ (p_pio->flags & ND_OPT_PIO_A_MASK) &&
+ !(p_pio->flags & ND_OPT_PIO_L_MASK))
+ {
+ // Ignore Link-Local address
+ if (IPV6_ADDRESS_IS_LINK_LOCAL(&p_pio->prefix))
+ {
+ ICMP6_ERR("Ignore Link-Local prefix!");
+ break;
+ }
+
+ // For now address is automatically set as a preferred.
+ ipv6_addr_conf_t temp_address;
+
+ // Set IPv6 EUI-64
+ IPV6_CREATE_LINK_LOCAL_FROM_EUI64(&temp_address.addr,
+ p_interface->local_addr.identifier);
+
+ // Add prefix
+ IPV6_ADDRESS_PREFIX_SET(temp_address.addr.u8,
+ p_pio->prefix.u8,
+ p_pio->prefix_length);
+
+ if (p_pio->valid_lifetime != 0)
+ {
+ temp_address.state = IPV6_ADDR_STATE_PREFERRED;
+
+ err_code = ipv6_address_set(p_interface, &temp_address);
+
+ if (err_code != NRF_SUCCESS)
+ {
+ ICMP6_ERR("Cannot add new address! Address table full!");
+ }
+ }
+ else
+ {
+ err_code = ipv6_address_remove(p_interface, &temp_address.addr);
+
+ if (err_code != NRF_SUCCESS)
+ {
+ ICMP6_ERR("Cannot remove address!");
+ }
+ }
+ }
+ else
+ {
+ ICMP6_ERR("Prefix option has incorrect parameters!");
+ return ICMP6_INVALID_PACKET_DATA;
+ }
+
+ break;
+ }
+ case ND_OPT_TYPE_6CO:
+ {
+ p_6co = (nd_option_6co_t *)p_opt;
+
+ memset(context.prefix.u8, 0, IPV6_ADDR_SIZE);
+
+ context.prefix = p_6co->context;
+ context.prefix_len = p_6co->context_length;
+ context.context_id = (p_6co->CID_C & ND_OPT_6CO_CID_MASK) >>
+ ND_OPT_6CO_CID_POS;
+ context.compression_flag = (p_6co->CID_C & ND_OPT_6CO_C_MASK) >>
+ ND_OPT_6CO_C_POS;
+
+ if (p_6co->valid_lifetime == 0)
+ {
+ err_code = iot_context_manager_get_by_cid(p_interface,
+ context.context_id,
+ &p_context);
+
+ if (err_code == NRF_SUCCESS)
+ {
+ err_code = iot_context_manager_remove(p_interface, p_context);
+
+ if (err_code == NRF_SUCCESS)
+ {
+ ICMP6_TRC("Removed context! CID = 0x%02x", context.context_id);
+ }
+ }
+
+ }
+ else
+ {
+ err_code = iot_context_manager_update(p_interface, &context);
+
+ if (err_code == NRF_SUCCESS)
+ {
+ ICMP6_TRC("New context added! CID = 0x%02x", context.context_id);
+ }
+ }
+
+ break;
+ }
+ }
+
+ // Increment current offset option.
+ curr_opt_offset += 8 * p_opt->length;
+ }
+
+ return NRF_SUCCESS;
+}
+
+/**@brief Function for notifying application of the ICMPv6 received packet.
+ *
+ * @param[in] p_interface Pointer to external interface from which packet come.
+ * @param[in] p_ip_header Pointer to IPv6 Header.
+ * @param[in] p_icmp_header Pointer to ICMPv6 header.
+ * @param[in] p_packet Pointer to packet buffer.
+ *
+ * @return NRF_SUCCESS after successful processing, error otherwise.
+ */
+static uint32_t ndisc_input(iot_interface_t * p_interface,
+ ipv6_header_t * p_ip_header,
+ icmp6_header_t * p_icmp_header,
+ iot_pbuffer_t * p_packet)
+{
+ uint32_t process_result;
+
+ switch (p_icmp_header->type)
+ {
+ case ICMP6_TYPE_ROUTER_SOLICITATION:
+ ICMP6_ERR("Got unsupported Router Solicitation message.");
+ process_result = ICMP6_UNHANDLED_PACKET_TYPE;
+ break;
+
+ case ICMP6_TYPE_ROUTER_ADVERTISEMENT:
+ ICMP6_TRC("Got Router Advertisement message.");
+ process_result = ra_input(p_interface, p_ip_header, p_icmp_header, p_packet);
+ break;
+
+ case ICMP6_TYPE_NEIGHBOR_SOLICITATION:
+ ICMP6_TRC("Got Neighbour Solicitation message.");
+ process_result = ns_input(p_interface, p_ip_header, p_icmp_header, p_packet);
+ break;
+
+ case ICMP6_TYPE_NEIGHBOR_ADVERTISEMENT:
+ ICMP6_TRC("Got Neighbour Advertisement message.");
+ process_result = NRF_SUCCESS;
+ break;
+
+ default:
+ process_result = ICMP6_UNHANDLED_PACKET_TYPE;
+ break;
+ }
+
+ return process_result;
+}
+
+uint32_t icmp6_error_message(const iot_interface_t * p_interface,
+ const ipv6_addr_t * p_src_addr,
+ const ipv6_addr_t * p_dest_addr,
+ const icmp6_error_message_param_t * p_param)
+{
+ VERIFY_MODULE_IS_INITIALIZED();
+ NULL_PARAM_CHECK(p_interface);
+ NULL_PARAM_CHECK(p_src_addr);
+ NULL_PARAM_CHECK(p_dest_addr);
+ NULL_PARAM_CHECK(p_param);
+ NULL_PARAM_CHECK(p_param->p_packet);
+
+ ICMP6_MUTEX_LOCK();
+
+ ICMP6_ENTRY();
+
+ iot_pbuffer_t * p_pbuffer;
+ ipv6_header_t * p_ip_header;
+ icmp6_header_t * p_icmp_header;
+ iot_pbuffer_alloc_param_t pbuff_param;
+ uint16_t checksum;
+ uint32_t err_code = NRF_SUCCESS;
+ const uint32_t error_packet_length =
+ (MIN(p_param->packet_len,
+ ICMP6_ERROR_MESSAGE_MAX_SIZE - ICMP6_HEADER_SIZE));
+
+ // Requesting buffer for error message.
+ pbuff_param.flags = PBUFFER_FLAG_DEFAULT;
+ pbuff_param.type = ICMP6_PACKET_TYPE;
+ pbuff_param.length = error_packet_length;
+
+ err_code = iot_pbuffer_allocate(&pbuff_param, &p_pbuffer);
+ if (err_code == NRF_SUCCESS)
+ {
+ p_ip_header = (ipv6_header_t *)(p_pbuffer->p_payload - ICMP6_HEADER_SIZE -
+ IPV6_IP_HEADER_SIZE);
+ p_icmp_header = (icmp6_header_t *)(p_pbuffer->p_payload - ICMP6_HEADER_SIZE);
+
+ // Change ICMP header.
+ p_icmp_header->type = p_param->type;
+ p_icmp_header->code = p_param->code;
+ p_icmp_header->checksum = 0;
+
+ switch (p_param->type)
+ {
+ case ICMP6_TYPE_PACKET_TOO_LONG:
+ {
+ p_icmp_header->sp.mtu = HTONL(p_param->error_field.mtu);
+ break;
+ }
+ case ICMP6_TYPE_PARAMETER_PROBLEM:
+ {
+ p_icmp_header->sp.offset = HTONL(p_param->error_field.offset);
+ break;
+ }
+ default:
+ {
+ p_icmp_header->sp.unused = 0;
+ break;
+ }
+ }
+
+ // IPv6 Header initialization.
+ icmp_ip_header(p_ip_header, IPV6_DEFAULT_HOP_LIMIT);
+
+ p_ip_header->srcaddr = *p_src_addr;
+ p_ip_header->destaddr = *p_dest_addr;
+ p_ip_header->length = HTONS(p_pbuffer->length + ICMP6_HEADER_SIZE);
+
+ memcpy(p_pbuffer->p_payload, p_param->p_packet, error_packet_length);
+
+ // Calculate checksum.
+ checksum = error_packet_length + IPV6_NEXT_HEADER_ICMP6;
+
+ ipv6_checksum_calculate(p_ip_header->srcaddr.u8, IPV6_ADDR_SIZE, &checksum, false);
+ ipv6_checksum_calculate(p_ip_header->destaddr.u8, IPV6_ADDR_SIZE, &checksum, false);
+ ipv6_checksum_calculate(p_pbuffer->p_payload - ICMP6_HEADER_SIZE,
+ p_pbuffer->length + ICMP6_HEADER_SIZE,
+ &checksum,
+ false);
+
+ // Update checksum in the packet.
+ p_icmp_header->checksum = HTONS((~checksum));
+
+ p_pbuffer->p_payload -= ICMP6_OFFSET;
+ p_pbuffer->length += ICMP6_OFFSET;
+
+ // Send IPv6 packet.
+ err_code = ipv6_send(p_interface, p_pbuffer);
+ }
+
+ ICMP6_EXIT();
+
+ ICMP6_MUTEX_UNLOCK();
+
+ return err_code;
+}
+
+uint32_t icmp6_echo_request(const iot_interface_t * p_interface,
+ const ipv6_addr_t * p_src_addr,
+ const ipv6_addr_t * p_dest_addr,
+ iot_pbuffer_t * p_request)
+{
+ VERIFY_MODULE_IS_INITIALIZED();
+ NULL_PARAM_CHECK(p_interface);
+ NULL_PARAM_CHECK(p_src_addr);
+ NULL_PARAM_CHECK(p_dest_addr);
+ NULL_PARAM_CHECK(p_request);
+ PACKET_TYPE_CHECK(p_request);
+
+ uint32_t err_code = NRF_SUCCESS;
+ uint16_t checksum;
+ ipv6_header_t * p_ip_header;
+ icmp6_header_t * p_icmp_header;
+
+ ICMP6_MUTEX_LOCK();
+
+ ICMP6_ENTRY();
+
+ // Headers of IPv6 packet.
+ p_ip_header = (ipv6_header_t *)(p_request->p_payload - ICMP6_HEADER_SIZE -
+ IPV6_IP_HEADER_SIZE);
+ p_icmp_header = (icmp6_header_t *)(p_request->p_payload - ICMP6_HEADER_SIZE);
+
+ // Change ICMP header.
+ p_icmp_header->type = ICMP6_TYPE_ECHO_REQUEST;
+ p_icmp_header->code = 0;
+ p_icmp_header->checksum = 0;
+
+ // IPv6 Header initialization.
+ icmp_ip_header(p_ip_header, IPV6_DEFAULT_HOP_LIMIT);
+
+ p_ip_header->srcaddr = *p_src_addr;
+ p_ip_header->destaddr = *p_dest_addr;
+ p_ip_header->length = HTONS(p_request->length + ICMP6_HEADER_SIZE);
+
+ // Set echo reply parameters.
+ p_icmp_header->sp.echo.id = 0;
+ p_icmp_header->sp.echo.sequence = HTONS(m_sequence_number);
+
+ // Calculate checksum.
+ checksum = p_request->length + ICMP6_HEADER_SIZE + IPV6_NEXT_HEADER_ICMP6;
+
+ ipv6_checksum_calculate(p_ip_header->srcaddr.u8, IPV6_ADDR_SIZE, &checksum, false);
+ ipv6_checksum_calculate(p_ip_header->destaddr.u8, IPV6_ADDR_SIZE, &checksum, false);
+ ipv6_checksum_calculate(p_request->p_payload - ICMP6_HEADER_SIZE,
+ p_request->length + ICMP6_HEADER_SIZE,
+ &checksum,
+ false);
+
+ p_icmp_header->checksum = HTONS((~checksum));
+
+ m_sequence_number++;
+ p_request->p_payload -= ICMP6_OFFSET;
+ p_request->length += ICMP6_OFFSET;
+
+ // Send IPv6 packet.
+ err_code = ipv6_send(p_interface, p_request);
+
+ ICMP6_EXIT();
+
+ ICMP6_MUTEX_UNLOCK();
+
+ return err_code;
+}
+
+uint32_t icmp6_rs_send(const iot_interface_t * p_interface,
+ const ipv6_addr_t * p_src_addr,
+ const ipv6_addr_t * p_dest_addr)
+{
+ VERIFY_MODULE_IS_INITIALIZED();
+ NULL_PARAM_CHECK(p_interface);
+ NULL_PARAM_CHECK(p_src_addr);
+ NULL_PARAM_CHECK(p_dest_addr);
+
+ uint32_t err_code = NRF_SUCCESS;
+ uint16_t checksum;
+ iot_pbuffer_t * p_pbuffer;
+ iot_pbuffer_alloc_param_t pbuff_param;
+
+ // IPv6 Headers.
+ ipv6_header_t * p_ip_header;
+ icmp6_header_t * p_icmp_header;
+ icmp6_rs_header_t * p_rs_header;
+ nd_option_sllao_t * p_sllao_opt;
+
+ ICMP6_MUTEX_LOCK();
+
+ ICMP6_ENTRY();
+
+ // Requesting buffer for RS message
+ pbuff_param.flags = PBUFFER_FLAG_DEFAULT;
+ pbuff_param.type = ICMP6_PACKET_TYPE;
+ pbuff_param.length = ND_OPT_SLLAO_SIZE;
+
+ err_code = iot_pbuffer_allocate(&pbuff_param, &p_pbuffer);
+
+ if (err_code == NRF_SUCCESS)
+ {
+ p_ip_header = (ipv6_header_t *)(p_pbuffer->p_payload - ICMP6_HEADER_SIZE -
+ IPV6_IP_HEADER_SIZE);
+ p_icmp_header = (icmp6_header_t *)(p_pbuffer->p_payload - ICMP6_HEADER_SIZE);
+ p_rs_header = (icmp6_rs_header_t *)(&p_icmp_header->sp.unused);
+ p_sllao_opt = (nd_option_sllao_t *)(p_pbuffer->p_payload);
+
+ // Change ICMP header.
+ p_icmp_header->type = ICMP6_TYPE_ROUTER_SOLICITATION;
+ p_icmp_header->code = 0;
+ p_icmp_header->checksum = 0;
+
+ // IPv6 Header initialization.
+ icmp_ip_header(p_ip_header, ND_HOP_LIMIT);
+
+ p_ip_header->srcaddr = *p_src_addr;
+ p_ip_header->destaddr = *p_dest_addr;
+ p_ip_header->length = HTONS(p_pbuffer->length + ICMP6_HEADER_SIZE);
+
+ // Set Router Solicitation parameter.
+ p_rs_header->reserved = 0;
+
+ // Add SLLAO option.
+ add_sllao_opt(p_interface, p_sllao_opt);
+
+ // Calculate checksum.
+ checksum = p_pbuffer->length + ICMP6_HEADER_SIZE + IPV6_NEXT_HEADER_ICMP6;
+
+ ipv6_checksum_calculate(p_ip_header->srcaddr.u8, IPV6_ADDR_SIZE, &checksum, false);
+ ipv6_checksum_calculate(p_ip_header->destaddr.u8, IPV6_ADDR_SIZE, &checksum, false);
+ ipv6_checksum_calculate(p_pbuffer->p_payload - ICMP6_HEADER_SIZE,
+ p_pbuffer->length + ICMP6_HEADER_SIZE,
+ &checksum,
+ false);
+
+ p_icmp_header->checksum = HTONS((~checksum));
+
+ p_pbuffer->p_payload -= ICMP6_OFFSET;
+ p_pbuffer->length += ICMP6_OFFSET;
+
+ // Send IPv6 packet.
+ err_code = ipv6_send(p_interface, p_pbuffer);
+ }
+ else
+ {
+ ICMP6_ERR("Failed to allocate packet buffer!");
+ }
+
+ ICMP6_EXIT();
+
+ ICMP6_MUTEX_UNLOCK();
+
+ return err_code;
+}
+
+uint32_t icmp6_ns_send(const iot_interface_t * p_interface,
+ const ipv6_addr_t * p_src_addr,
+ const ipv6_addr_t * p_dest_addr,
+ const icmp6_ns_param_t * p_param)
+{
+ VERIFY_MODULE_IS_INITIALIZED();
+ NULL_PARAM_CHECK(p_interface);
+ NULL_PARAM_CHECK(p_src_addr);
+ NULL_PARAM_CHECK(p_dest_addr);
+ NULL_PARAM_CHECK(p_param);
+
+ uint32_t err_code = NRF_SUCCESS;
+ uint16_t aro_size = 0;
+ uint16_t checksum;
+ iot_pbuffer_t * p_pbuffer;
+ iot_pbuffer_alloc_param_t pbuff_param;
+
+ // IPv6 Headers.
+ ipv6_header_t * p_ip_header;
+ icmp6_header_t * p_icmp_header;
+ icmp6_ns_header_t * p_ns_header;
+ nd_option_sllao_t * p_sllao_opt;
+ nd_option_aro_t * p_aro_opt;
+
+ ICMP6_MUTEX_LOCK();
+
+ ICMP6_ENTRY();
+
+ if (p_param->add_aro)
+ {
+ aro_size = ND_OPT_ARO_SIZE;
+ }
+
+ // Requesting buffer for NS message
+ pbuff_param.flags = PBUFFER_FLAG_DEFAULT;
+ pbuff_param.type = ICMP6_PACKET_TYPE;
+ pbuff_param.length = ND_NS_HEADER_SIZE + ND_OPT_SLLAO_SIZE + \
+ aro_size - ND_PAYLOAD_ADJUST_OFFSET;
+
+ err_code = iot_pbuffer_allocate(&pbuff_param, &p_pbuffer);
+
+ if (err_code == NRF_SUCCESS)
+ {
+ p_ip_header = (ipv6_header_t *)(p_pbuffer->p_payload - ICMP6_HEADER_SIZE -
+ IPV6_IP_HEADER_SIZE);
+ p_icmp_header = (icmp6_header_t *)(p_pbuffer->p_payload - ICMP6_HEADER_SIZE);
+ p_pbuffer->p_payload -= ND_PAYLOAD_ADJUST_OFFSET;
+ p_ns_header = (icmp6_ns_header_t *)(p_pbuffer->p_payload);
+ p_sllao_opt = (nd_option_sllao_t *)(p_pbuffer->p_payload + ND_NS_HEADER_SIZE);
+ p_aro_opt = (nd_option_aro_t *)(p_pbuffer->p_payload + ND_NS_HEADER_SIZE +
+ ND_OPT_SLLAO_SIZE);
+
+ p_pbuffer->p_payload += ND_PAYLOAD_ADJUST_OFFSET;
+
+ // Change ICMP header.
+ p_icmp_header->type = ICMP6_TYPE_NEIGHBOR_SOLICITATION;
+ p_icmp_header->code = 0;
+ p_icmp_header->checksum = 0;
+
+ // IPv6 Header initialization.
+ icmp_ip_header(p_ip_header, ND_HOP_LIMIT);
+
+ p_ip_header->srcaddr = *p_src_addr;
+ p_ip_header->destaddr = *p_dest_addr;
+ p_ip_header->length = HTONS(p_pbuffer->length + ICMP6_HEADER_SIZE);
+
+ // Set Neighbour Solicitation parameter.
+ p_ns_header->reserved = 0;
+ p_ns_header->target_addr = p_param->target_addr;
+
+ // Add SLLAO option.
+ add_sllao_opt(p_interface, p_sllao_opt);
+
+ if (p_param->add_aro)
+ {
+ add_aro_opt(p_interface, p_aro_opt, p_param->aro_lifetime);
+ }
+
+ // Calculate checksum.
+ checksum = p_pbuffer->length + ICMP6_HEADER_SIZE + IPV6_NEXT_HEADER_ICMP6;
+
+ ipv6_checksum_calculate(p_ip_header->srcaddr.u8, IPV6_ADDR_SIZE, &checksum, false);
+ ipv6_checksum_calculate(p_ip_header->destaddr.u8, IPV6_ADDR_SIZE, &checksum, false);
+ ipv6_checksum_calculate(p_pbuffer->p_payload - ICMP6_HEADER_SIZE,
+ p_pbuffer->length + ICMP6_HEADER_SIZE,
+ &checksum,
+ false);
+
+ p_icmp_header->checksum = HTONS((~checksum));
+
+ p_pbuffer->p_payload -= ICMP6_OFFSET;
+ p_pbuffer->length += ICMP6_OFFSET;
+
+ // Send IPv6 packet.
+ err_code = ipv6_send(p_interface, p_pbuffer);
+ }
+ else
+ {
+ ICMP6_ERR("Failed to allocate packet buffer!");
+ }
+
+ ICMP6_EXIT();
+
+ ICMP6_MUTEX_UNLOCK();
+
+ return err_code;
+}
+
+
+uint32_t icmp6_receive_register(icmp6_receive_callback_t cb)
+{
+ VERIFY_MODULE_IS_INITIALIZED();
+ NULL_PARAM_CHECK(cb);
+ UNUSED_VARIABLE(m_event_handler);
+
+ ICMP6_MUTEX_LOCK();
+
+ ICMP6_ENTRY();
+
+ // Store application event handler.
+ m_event_handler = cb;
+
+ ICMP6_EXIT();
+
+ ICMP6_MUTEX_UNLOCK();
+
+ return NRF_SUCCESS;
+}
+
+
+uint32_t icmp6_init(void)
+{
+ SDK_MUTEX_INIT(m_icmp6_mutex);
+ ICMP6_MUTEX_LOCK();
+
+ ICMP6_ENTRY();
+
+ // Set application event handler.
+ m_event_handler = NULL;
+
+ // Indicate initialization of module.
+ m_initialization_state = true;
+
+ ICMP6_EXIT();
+
+ ICMP6_MUTEX_UNLOCK();
+
+ return NRF_SUCCESS;
+}
+
+
+uint32_t icmp6_input(iot_interface_t * p_interface,
+ ipv6_header_t * p_ip_header,
+ iot_pbuffer_t * p_packet)
+{
+ VERIFY_MODULE_IS_INITIALIZED();
+
+ NULL_PARAM_CHECK(p_interface);
+ NULL_PARAM_CHECK(p_ip_header);
+ NULL_PARAM_CHECK(p_packet);
+
+ uint16_t checksum;
+ uint32_t process_result = NRF_SUCCESS;
+ bool is_ndisc = false;
+ icmp6_header_t * p_icmp_header = (icmp6_header_t *)p_packet->p_payload;
+ uint32_t err_code = NRF_SUCCESS;
+
+ ICMP6_MUTEX_LOCK();
+
+ ICMP6_ENTRY();
+
+ if (p_packet->length < ICMP6_HEADER_SIZE || p_ip_header->length < ICMP6_HEADER_SIZE)
+ {
+ ICMP6_ERR("Received malformed packet, which has 0x%08lX bytes.", p_packet->length);
+ process_result = ICMP6_MALFORMED_PACKET;
+ }
+ else
+ {
+ // Check checksum of packet.
+ checksum = p_packet->length + IPV6_NEXT_HEADER_ICMP6;
+
+ ipv6_checksum_calculate(p_ip_header->srcaddr.u8, IPV6_ADDR_SIZE, &checksum, false);
+ ipv6_checksum_calculate(p_ip_header->destaddr.u8, IPV6_ADDR_SIZE, &checksum, false);
+ ipv6_checksum_calculate(p_packet->p_payload, p_packet->length, &checksum, false);
+ checksum = (uint16_t)~checksum;
+
+ // Change pbuffer type.
+ p_packet->type = ICMP6_PACKET_TYPE;
+ p_packet->p_payload = p_packet->p_payload + ICMP6_HEADER_SIZE;
+ p_packet->length -= ICMP6_HEADER_SIZE;
+
+ if (checksum != 0)
+ {
+ ICMP6_ERR("Bad checksum detected. Got 0x%08x but expected 0x%08x, 0x%08lX",
+ NTOHS(p_icmp_header->checksum), checksum, p_packet->length);
+ process_result = ICMP6_BAD_CHECKSUM;
+ }
+ else
+ {
+ switch (p_icmp_header->type)
+ {
+ case ICMP6_TYPE_DESTINATION_UNREACHABLE:
+ case ICMP6_TYPE_PACKET_TOO_LONG:
+ case ICMP6_TYPE_TIME_EXCEED:
+ case ICMP6_TYPE_PARAMETER_PROBLEM:
+ {
+ ICMP6_TRC("Got ICMPv6 error message with type = 0x%08x",
+ p_icmp_header->type);
+ p_icmp_header->sp.unused = NTOHL(p_icmp_header->sp.unused);
+ break;
+ }
+ case ICMP6_TYPE_ECHO_REQUEST:
+ case ICMP6_TYPE_ECHO_REPLY:
+ {
+ ICMP6_TRC("Got ICMPv6 Echo message with type = 0x%x.", p_icmp_header->type);
+ ICMP6_TRC("From IPv6 Address:");
+ ICMP6_DUMP(p_ip_header->srcaddr.u32, IPV6_ADDR_SIZE);
+ ICMP6_TRC("Identifier: 0x%04x, Sequence Number: 0x%04x",
+ NTOHS(p_icmp_header->sp.echo.id),
+ NTOHS(p_icmp_header->sp.echo.sequence));
+ break;
+ }
+ case ICMP6_TYPE_ROUTER_SOLICITATION:
+ case ICMP6_TYPE_ROUTER_ADVERTISEMENT:
+ case ICMP6_TYPE_NEIGHBOR_SOLICITATION:
+ case ICMP6_TYPE_NEIGHBOR_ADVERTISEMENT:
+ {
+ p_packet->p_payload = p_packet->p_payload - ND_PAYLOAD_ADJUST_OFFSET;
+ p_packet->length += ND_PAYLOAD_ADJUST_OFFSET;
+ process_result = ndisc_input(p_interface,
+ p_ip_header,
+ p_icmp_header,
+ p_packet);
+ p_packet->p_payload = p_packet->p_payload + ND_PAYLOAD_ADJUST_OFFSET;
+ p_packet->length -= ND_PAYLOAD_ADJUST_OFFSET;
+ is_ndisc = true;
+ break;
+ }
+ default:
+ process_result = ICMP6_UNHANDLED_PACKET_TYPE;
+ break;
+ }
+
+#if (ICMP6_ENABLE_HANDLE_ECHO_REQUEST_TO_APPLICATION == 0)
+ if (p_icmp_header->type == ICMP6_TYPE_ECHO_REQUEST)
+ {
+ echo_reply_send(p_interface, p_ip_header, p_icmp_header, p_packet);
+ }
+#endif
+ }
+ }
+
+#if (ICMP6_ENABLE_ALL_MESSAGES_TO_APPLICATION == 1)
+ err_code = app_notify_icmp_data(p_interface, p_packet, process_result);
+#elif (ICMP6_ENABLE_ND6_MESSAGES_TO_APPLICATION == 1)
+ if (is_ndisc)
+ {
+ err_code = app_notify_icmp_data(p_interface, p_packet, process_result);
+ }
+#endif
+
+ ICMP6_EXIT();
+
+ UNUSED_VARIABLE(is_ndisc);
+ UNUSED_VARIABLE(process_result);
+
+ ICMP6_MUTEX_UNLOCK();
+
+ return err_code;
+}
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/ipv6_stack/icmp6/icmp6.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/ipv6_stack/icmp6/icmp6.h
new file mode 100644
index 0000000..7ce517b
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/ipv6_stack/icmp6/icmp6.h
@@ -0,0 +1,101 @@
+/**
+ * Copyright (c) 2014 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+/** @cond */
+ /** @file icmp6.h
+ *
+ * @defgroup iot_icmp6 ICMP Module Header.
+ * @ingroup iot_sdk
+ * @{
+ * @brief Internet Control Message Protocol module header defining interface between the ICMP6
+ * module and other IP stack layers. This interface is internal to the IPv6 stack and not
+ * available to the application. The application shall not explicitly use this interface.
+ *
+ */
+
+#ifndef ICMP6_H__
+#define ICMP6_H__
+
+#include "sdk_config.h"
+#include "sdk_common.h"
+#include "ipv6_api.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @brief Module initialization function called from ipv6_init(). This shall not be called by the
+ * application explicitly.
+ *
+ * @retval NRF_SUCCESS on successful execution of procedure, else an error code indicating reason
+ * for failure.
+ */
+uint32_t icmp6_init(void);
+
+
+/**
+ * @brief Function to feed incoming ICMP packets to the module. To be called by the IPv6
+ * stack only and never by the application.
+ *
+ * @param[in] p_interface Identifies network interface on which the packet is received.
+ * @param[in] p_ip_header IP Header of the ICMP packet being fed to the module.
+ * @param[in] p_packet ICMP packet being notified to the module. p_packet->p_payload points the
+ * IPv6 payload and p_packet->length indicates total length of the payload.
+ *
+ * @note This routine is called by the stack with next header field value is set to transport
+ * protocol value of 58.
+ *
+ * @retval NRF_SUCCESS on successful handling of the packet, else an error code indicating reason
+ * for failure.
+ */
+uint32_t icmp6_input(iot_interface_t * p_interface,
+ ipv6_header_t * p_ip_header,
+ iot_pbuffer_t * p_packet);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif //ICMP6_H__
+
+/**@} */
+
+/** @endcond */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/ipv6_stack/include/dns6_api.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/ipv6_stack/include/dns6_api.h
new file mode 100644
index 0000000..0f6ecd9
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/ipv6_stack/include/dns6_api.h
@@ -0,0 +1,173 @@
+/**
+ * Copyright (c) 2015 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 dns6_api.h
+ *
+ * @defgroup iot_dns6 DNS Application Interface for Nordic's IPv6 stack
+ * @ingroup iot_sdk_stack
+ * @{
+ * @brief Domain Name System module provides implementation of DNS6 service.
+ *
+ */
+
+#ifndef DNS6_H__
+#define DNS6_H__
+
+#include "sdk_config.h"
+#include "sdk_common.h"
+#include "ipv6_api.h"
+#include "iot_timer.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** @brief DNS Server parameter. */
+typedef struct
+{
+ ipv6_addr_t addr; /**< The IPv6 address of the DNS Server. */
+ uint16_t port; /**< The default UDP port of the DNS Server. */
+} dns6_server_param_t;
+
+
+/**@brief Initialization parameters type. */
+typedef struct
+{
+ uint16_t local_src_port; /**< The local UDP port for reception the DNS responses. */
+ dns6_server_param_t dns_server; /**< Parameters of the DNS Server. */
+} dns6_init_t;
+
+
+/**
+ * @brief DNS event receive callback.
+ *
+ * @details API used to notify the application of DNS Response on specific hostname or of an error
+ * during resolving process. The process_result parameter indicates whether the DNS module
+ * was successfully processed. If the received DNS Response is malformed in a way that
+ * allow to assign response with specific callback (e.g. timeout occurs or hostname is not
+ * found), information about error is still notified to the application. The application
+ * should check process_result and number of IPv6 address before reading them.
+ *
+ * @param[in] process_result Notifies the application if the DNS module was processed successfully
+ * or if an error occurred, for example DNS server is unreachable.
+ * @param[in] p_hostname Identifies hostname (URL string) that was requested to bee resolved,
+ * e.g. "example.com".
+ * @param[in] p_addr Pointer to the IPv6 addresses being resolved for given hostname. In
+ * case addr_count variable is 0, p_addr gets NULL value and should not
+ * be used.
+ * @param[in] addr_count Number of IPv6 addresses being successfully resolved.
+ *
+ * @retval None.
+ */
+typedef void (* dns6_evt_handler_t) (uint32_t process_result,
+ const char * p_hostname,
+ ipv6_addr_t * p_addr,
+ uint16_t addr_count);
+
+/**
+ * @brief Function for initializing DNS6 module.
+ *
+ * @param[in] p_dns_init Initialization structure for DNS client. Should not be NULL.
+ *
+ * @note DNS protocol module uses UDP transport layer, therefore one UDP socket is allocated
+ * inside function and uses for further communication.
+ *
+ * @retval NRF_SUCCESS on successful execution of procedure, else an error code indicating reason
+ * for failure.
+ */
+uint32_t dns6_init(const dns6_init_t * p_dns_init);
+
+
+/**
+ * @brief Function for uninitializing DNS6 module.
+ *
+ * @note Apart of DNS specific functionality, function frees previously allocated UDP socket.
+ * Function removes any pending queries from the sending queue, so registered user
+ * callbacks will not be executed.
+ *
+ * @retval NRF_SUCCESS on successful execution of procedure, else an error code indicating reason
+ * for failure.
+ */
+uint32_t dns6_uninit(void);
+
+
+/**
+ * @brief Function for querying given URL string to DNS server, in order to get IPv6 address of
+ * given hostname.
+ *
+ * @param[in] p_hostname Identifies hostname (URL string) to be find, e.g. "example.com". Should
+ * not be NULL.
+ * @param[in] evt_handler Callback that is called once response is received, timeout occurred or
+ * internal error was detected. Should not be NULL.
+ *
+ * @note Function sends DNS Query to DNS Server to obtain all AAAA records (with IPv6 address)
+ * assigned to given hostname. In case DNS Server replies with more that one AAAA records
+ * DNS module call user defined evt_handler with addr_count indicates number of addresses.
+ *
+ * @retval NRF_SUCCESS on successful execution of procedure.
+ * @retval IOT_DNS6_ERR_BASE | NRF_ERROR_NO_MEM if there is no place in pending queries' queue.
+ * @retval IOT_PBUFFER_ERR_BASE | NRF_ERROR_NO_MEM if there is no memory for hostname allocation.
+ * @retval NRF_ERROR_MEMORY_MANAGER_ERR_BASE | NRF_ERROR_NO_MEM if there is no memory for packet allocation.
+ * @retval UDP_INTERFACE_NOT_READY if interface is not ready for sending packets e.g. interface is
+ * down.
+ * @retval Other errors indicates reason of failure.
+ */
+uint32_t dns6_query(const char * p_hostname, dns6_evt_handler_t evt_handler);
+
+
+/**@brief Function for performing retransmissions of DNS queries.
+ *
+ * @note DNS module implements the retransmission mechanism by invoking this function periodically.
+ * So that method has to be added to IoT Timer client list and has to be called with minimum of
+ * DNS6_RETRANSMISSION_INTERVAL resolution.
+ *
+ * @param[in] wall_clock_value The value of the wall clock that triggered the callback.
+ *
+ * @retval None.
+ */
+void dns6_timeout_process(iot_timer_time_in_ms_t wall_clock_value);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif //DNS6_H__
+
+/**@} */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/ipv6_stack/include/icmp6_api.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/ipv6_stack/include/icmp6_api.h
new file mode 100644
index 0000000..b13b4b6
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/ipv6_stack/include/icmp6_api.h
@@ -0,0 +1,253 @@
+/**
+ * Copyright (c) 2014 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 icmp6_api.h
+ *
+ * @defgroup iot_icmp6 ICMP6 Application Interface for Nordic's IPv6 stack
+ * @ingroup iot_sdk_stack
+ * @{
+ * @brief Nordic Internet Control Message Protocol Application Interface for Nordic's IPv6 stack.
+ *
+ * @details This module provides basic features related to ICMPv6 support.
+ */
+
+#ifndef ICMP6_API_H__
+#define ICMP6_API_H__
+
+#include "sdk_config.h"
+#include "sdk_common.h"
+#include "iot_defines.h"
+#include "ipv6_api.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define ICMP6_ECHO_REQUEST_PAYLOAD_OFFSET 8 /**< Offset of echo request payload from ICMPv6 header. */
+
+
+/**@defgroup icmp6_code ICMPv6 codes per message type as defined in RFC 4443.
+ * @ingroup iot_icmp6
+ * @{
+ */
+#define ICMP6_DU_CODE_NO_ROUTE_TO_DESTINATION 0 /**< Code for Destination Unreachable Message when there is no route to destination. */
+#define ICMP6_DU_CODE_ADMINISTRATIVELY_PROHIBITED 1 /**< Code for Destination Unreachable Message when the communication to destination administratively prohibited. */
+#define ICMP6_DU_CODE_BEYOND_SCOPE_OF_SOURCE 2 /**< Code for Destination Unreachable Message when the destination is beyond the scope of source address. */
+#define ICMP6_DU_CODE_ADDRESS_UNREACHABLE 3 /**< Code for Destination Unreachable Message when the destination address is unreachable. */
+#define ICMP6_DU_CODE_PORT_UNREACHABLE 4 /**< Code for Destination Unreachable Message when the destination port is unreachable. */
+#define ICMP6_DU_CODE_FAILED_INGRESS_EGRESS_POLICY 5 /**< Code for Destination Unreachable Message when the source address failed on ingress/egress policy. */
+#define ICMP6_DU_CODE_REJECT_ROUTE_TO_DESTINATION 6 /**< Code for Destination Unreachable Message when the route to destination is rejected. */
+
+#define ICMP6_TE_CODE_EXCEEDED_HOP_LIMIT_TRANSIT 0 /**< Code for Time Exceeded Message when the packet received had hop limit of zero. */
+#define ICMP6_TE_CODE_FAR_TIME_EXCEEDED 1 /**< Code for Time Exceeded Message to report fragmentation and reassembly timeout. */
+
+#define ICMP6_PP_CODE_INVALID_HEADER 0 /**< Code for Parameter Problem Message when the header of the incoming packet was erroneous. */
+#define ICMP6_PP_CODE_UNKNOWN_NEXT_HEADER 1 /**< Code for Parameter Problem Message when the next header of the incoming packet was unrecognized. */
+#define ICMP6_PP_CODE_UNKNOWN_IPV6_OPTION 2 /**< Code for Parameter Problem Message when the option of the incoming packet was unrecognized. */
+
+#define ICMP6_ERROR_MESSAGE_INVOKING_PKT_OFFSET 8 /**< Offset in the received ICMPv6 payload where the packet (partial or complete) that invoked the error message is found. */
+/* @} */
+
+/** Neighbor solicitation parameters. */
+typedef struct
+{
+ ipv6_addr_t target_addr; /**< The IPv6 address of the target of the solicitation. MUST NOT be a multi-cast address. */
+ bool add_aro; /**< Indicates if ARO option should be added. */
+ uint16_t aro_lifetime; /**< The amount of time in units of 60 seconds that the router should retain the NCE for the sender of the NS. */
+} icmp6_ns_param_t;
+
+/**@brief Parameters associated with error message in receive and transmit paths. */
+typedef struct
+{
+ uint8_t type; /**< Identifies error message type, valid values as described in RFC 4443. See @ref icmp6_error_type for possible values. */
+ uint8_t code; /**< Identifies code, if any associated with the error. See \ref icmp6_code and RFC 4443 for details. */
+ union /**< Additional field like MTU, pointer or unused based on message type. See RFC 4443 for more details. If unused, application may ignore this field. */
+ {
+ uint32_t mtu; /**< MTU of next hop limit, used only with ICMP6_TYPE_PACKET_TOO_LONG type. */
+ uint32_t offset; /**< Offset pointing to the parameter that resulted in the ICMP6_TYPE_PARAMETER_PROBLEM error. Used only with ICMP6_TYPE_PARAMETER_PROBLEM. */
+ uint32_t unused; /**< Any other error message. Is always zero. */
+ } error_field;
+ uint8_t * p_packet; /**< Points to the start of IPv6 packet that has resulted in the error message. */
+ uint16_t packet_len; /**< Length of the packet that resulted in error. The module may truncate the packet and pack only partially the packet based on configuration of ICMP6_ERROR_MESSAGE_MAX_SIZE. */
+} icmp6_error_message_param_t;
+
+
+/**@brief ICMPv6 data RX callback.
+ *
+ * @details Asynchronous callback used to notify the application of ICMP packets received.
+ * By default, the application is not notified through ICMP of messages related to ECHO
+ * requests or any errors. However, these notifications can easily be enabled by defining
+ * either the ICMP6_ENABLE_ND6_MESSAGES_TO_APPLICATION or the
+* ICMP6_ENABLE_ALL_MESSAGES_TO_APPLICATION if the application should handle them.
+ *
+ * @param[in] p_interface Pointer to the IPv6 interface from where the ICMP packet was received.
+ * @param[in] p_ip_header Pointer to the IP header of the ICMP packet received.
+ * @param[in] p_icmp_header Pointer to the ICMP header of the received packet.
+ * @param[in] process_result Notifies the application if the ICMP packet was processed successfully or if
+ * an error occurred, for example, if the packet was malformed.
+ * @param[in] p_rx_packet Packet buffer containing the packet received. p_rx_packet->p_payload
+ * contains the ICMP payload.
+ *
+ * @retval A provision for the application to notify the module of whether the received packet was
+ * processed successfully by application. The application may take ownership of the received
+ * packet by returning IOT_IPV6_ERR_PENDING, in which case the application must take care to
+ * free it using @ref iot_pbuffer_free.
+ */
+typedef uint32_t (*icmp6_receive_callback_t)(iot_interface_t * p_interface,
+ ipv6_header_t * p_ip_header,
+ icmp6_header_t * p_icmp_header,
+ uint32_t process_result,
+ iot_pbuffer_t * p_rx_packet);
+
+
+/**@brief Sends ICMPv6 Error Message as defined in RFC 4443.
+ *
+ * @details API to send messages categorized under error messages. See @ref icmp6_error_type and
+ * RFC 4443 for valid types.
+ *
+ * @param[in] p_interface Identifies the interface on which the procedure was requested.
+ * Shall not be NULL.
+ * @param[in] p_src_addr Source IPv6 address to be used for the request. Shall not be NULL.
+ * @param[in] p_dest_addr Destination IPv6 address to which the message send is requested.
+ * Shall not be NULL.
+ * @param[in] p_param Parameters describing Type, code, invoking packet information any
+ * additional details associated with the error message.
+ *
+ * @retval NRF_SUCCESS If the send request was successful, else, an error code indicating reason for
+ * failure.
+ */
+uint32_t icmp6_error_message(const iot_interface_t * p_interface,
+ const ipv6_addr_t * p_src_addr,
+ const ipv6_addr_t * p_dest_addr,
+ const icmp6_error_message_param_t * p_param);
+
+
+/**@brief Sends ICMPv6 echo request as defined in RFC4443.
+ *
+ * @details API used to send an ICMPv6 echo request packet to a specific destination address.
+ * The user can decide how much additional data must be sent.
+ *
+ * The application calling the function should allocate a packet before, with the type set to
+ * ICMP6_PACKET_TYPE in the allocation parameter.
+ *
+ * The application should pack the payload at ICMP6_ECHO_REQUEST_PAYLOAD_OFFSET. ID,
+ * Sequence number, ICMP Code, type checksum, etc. are filled in by the module.
+ *
+ * The application shall not free the allocated packet buffer if the procedure was successful,
+ * to ensure that no data copies are needed when transmitting a packet.
+ *
+ * @param[in] p_interface Pointer to the IPv6 interface to send the ICMP packet.
+ * @param[in] p_src_addr IPv6 source address from where the echo request is sent.
+ * @param[in] p_dest_addr IPv6 destination address to where the echo request is sent.
+ * @param[in] p_request Packet buffer containing the echo request.
+ *
+ * @retval NRF_SUCCESS If the send request was successful.
+ */
+uint32_t icmp6_echo_request(const iot_interface_t * p_interface,
+ const ipv6_addr_t * p_src_addr,
+ const ipv6_addr_t * p_dest_addr,
+ iot_pbuffer_t * p_request);
+
+
+/**@brief Sends router solicitation message defined in RFC6775.
+ *
+ * @details API used to send a neighbor discovery message of type Router Solicitation to a specific
+ * destination address. If no address is known, the user should send the message to all
+ * routers' address (FF02::1).
+ *
+ * The function internally tries to allocate a packet buffer. EUI-64 used in the SLLAO option is
+ * taken from the interface parameter defined in the @ref ipv6_init() function.
+ *
+ * @param[in] p_interface Pointer to the IPv6 interface to send the ICMP packet.
+ * @param[in] p_src_addr IPv6 source address from where the router solicitation message is
+ * sent.
+ * @param[in] p_dest_addr IPv6 destination address to where the router solicitation message is
+ * sent.
+ *
+ * @retval NRF_SUCCESS If the send request was successful.
+ */
+uint32_t icmp6_rs_send(const iot_interface_t * p_interface,
+ const ipv6_addr_t * p_src_addr,
+ const ipv6_addr_t * p_dest_addr);
+
+
+/**@brief Sends neighbour solicitation message defined in RFC6775.
+ *
+ * @details API used to send a neighbor discovery message of type Neighbor Solicitation to a
+ * specific destination address.
+ *
+ * The function internally tries to allocate a packet buffer. EUI-64 used in the SLLAO and ARO
+ * options is taken from the interface parameter defined in the @ref ipv6_init() function.
+ *
+ * @param[in] p_interface Pointer to the IPv6 interface to send the ICMP packet.
+ * @param[in] p_src_addr IPv6 source address from where the neighbor solicitation message is
+ * sent.
+ * @param[in] p_dest_addr IPv6 destination address to where the neighbor solicitation message
+ * is sent.
+ * @param[in] p_ns_param Neighbor discovery parameters.
+ *
+ * @retval NRF_SUCCESS If the send request was successful.
+ */
+uint32_t icmp6_ns_send(const iot_interface_t * p_interface,
+ const ipv6_addr_t * p_src_addr,
+ const ipv6_addr_t * p_dest_addr,
+ const icmp6_ns_param_t * p_ns_param);
+
+
+/**@brief Registers the callback function for echo reply.
+ *
+ * @details API used to register callback to indicate the ICMP echo reply packet. Could be not used.
+ *
+ * Neighbor discovery related messages are not relayed to the application by default.
+ * However, this can be enabled by using the ICMP6_ENABLE_ND6_MESSAGES_TO_APPLICATION
+ * configuration parameter.
+ *
+ * @param[in] cb Handler called when an ICMP packet is received.
+ *
+ * @retval NRF_SUCCESS If the registration was successful.
+ */
+uint32_t icmp6_receive_register(icmp6_receive_callback_t cb);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif //ICMP6_API_H__
+
+/**@} */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/ipv6_stack/include/ipv6_api.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/ipv6_stack/include/ipv6_api.h
new file mode 100644
index 0000000..33b8ec9
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/ipv6_stack/include/ipv6_api.h
@@ -0,0 +1,207 @@
+/**
+ * Copyright (c) 2014 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 ipv6_api.h
+ *
+ * @defgroup iot_ipv6 IPv6 Core Application Interface for Nordic's IPv6 stack
+ * @ingroup iot_sdk_stack
+ * @{
+ * @brief Nordic's IPv6 stack. Currently, only a Host role is supported.
+ *
+ * @details Nordic's IPv6 stack provides minimal implementations of ICMP, UDP for a Host, and
+ * IPv6 Neighbor Discovery for Host.
+ * Router, neighbor, and prefix cache are not maintained across BLE link disconnections or
+ * power cycles.
+ */
+
+#ifndef IPV6_API_H_
+#define IPV6_API_H_
+
+#include <stdint.h>
+#include "sdk_config.h"
+#include "iot_common.h"
+#include "iot_pbuffer.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**@brief Asynchronous event identifiers type. */
+typedef enum
+{
+ IPV6_EVT_INTERFACE_ADD, /**< Notification of a new IPv6 interface added. */
+ IPV6_EVT_INTERFACE_DELETE, /**< Notification of IPv6 interface deleted. */
+ IPV6_EVT_INTERFACE_RX_DATA /**< Notification of IPv6 data, depending on configuration. For example, IPV6_ENABLE_USNUPORTED_PROTOCOLS_TO_APPLICATION. */
+} ipv6_event_id_t;
+
+/**@brief IPv6 address configuration. */
+typedef struct
+{
+ ipv6_addr_t addr;
+ ipv6_addr_state_t state;
+} ipv6_addr_conf_t;
+
+/**@brief Event parameters associated with the IPV6_EVT_INTERFACE_RX_DATA event. */
+typedef struct
+{
+ ipv6_header_t * p_ip_header; /**< IPv6 header of the packet. */
+ iot_pbuffer_t * p_rx_packet; /**< Packet buffer contains received data. */
+} ipv6_data_rx_t;
+
+/**@brief Asynchronous event parameter type. */
+typedef union
+{
+ ipv6_data_rx_t rx_event_param; /**< Parameters notified with the received IPv6 packet. */
+} ipv6_event_param_t;
+
+/**@brief Asynchronous event type. */
+typedef struct
+{
+ ipv6_event_id_t event_id; /**< Event identifier. */
+ ipv6_event_param_t event_param; /**< Event parameters. */
+} ipv6_event_t;
+
+/**@brief Asynchronous event notification callback type. */
+typedef void (* ipv6_evt_handler_t)(iot_interface_t * p_interface,
+ ipv6_event_t * p_event);
+
+/**@brief Initialization parameters type. */
+typedef struct
+{
+ eui64_t * p_eui64; /**< Global identifiers EUI-64 address of device. */
+ ipv6_evt_handler_t event_handler; /**< Asynchronous event notification callback registered to receive IPv6 events. */
+} ipv6_init_t;
+
+
+/**@brief Initializes the IPv6 stack module.
+ *
+ * @param[in] p_init Initialization parameters.
+ *
+ * @retval NRF_SUCCESS If initialization was successful. Otherwise, an error code is returned.
+ */
+uint32_t ipv6_init(const ipv6_init_t * p_init);
+
+/**@brief Sets address to specific interface.
+ *
+ * @details API used to add or update an IPv6 address on an interface. The address can have three specific
+ * states that determine transmitting capabilities.
+ *
+ * @param[in] p_interface The interface on which the address must be assigned.
+ * @param[in] p_addr IPv6 address and state to be assigned/updated.
+ *
+ * @retval NRF_SUCCESS If the operation was successful.
+ * @retval NRF_ERROR_NO_MEM If no memory was available.
+ */
+uint32_t ipv6_address_set(const iot_interface_t * p_interface,
+ const ipv6_addr_conf_t * p_addr);
+
+
+/**@brief Removes address from specific interface.
+ *
+ * @details API used to remove an IPv6 address from an interface.
+ *
+ * @param[in] p_interface The interface from which the address must be removed.
+ * @param[in] p_addr IPv6 address to remove.
+ *
+ * @retval NRF_SUCCESS If the operation was successful.
+ * @retval NRF_ERROR_NOT_FOUND If no address was found.
+ */
+uint32_t ipv6_address_remove(const iot_interface_t * p_interface,
+ const ipv6_addr_t * p_addr);
+
+
+/**@brief Checks if given unicast address has been registered.
+ *
+ * @param[in] p_interface The interface on which IPv6 address wil be checked.
+ * @param[in] p_addr IPv6 address to be checked.
+ *
+ * @retval NRF_SUCCESS If the operation was successful.
+ * @retval NRF_ERROR_NOT_FOUND If no address was found.
+ */
+uint32_t ipv6_address_check(const iot_interface_t * p_interface,
+ const ipv6_addr_t * p_addr);
+
+
+/**@brief Finds the best matched address and interface.
+ *
+ * @details API used to find the most suitable interface and address to a given destination address.
+ *
+ * To look only for the interface, set p_addr_r to NULL.
+ *
+ * To find the best matched address, IPV6_ADDR_STATE_PREFERRED state of address is required.
+ *
+ * @param[out] pp_interface Interface to be found.
+ * @param[out] p_addr_r Best matching address if procedure succeeded and this value was not NULL.
+ * @param[inout] p_addr_f IPv6 address for which best matching interface and/or address are requested.
+ *
+ * @retval NRF_SUCCESS If the operation was successful.
+ * @retval NRF_ERROR_NOT_FOUND If no interface was found.
+ * @retval NRF_ERROR_NOT_SUPPORTED If the operation was not supported.
+ */
+uint32_t ipv6_address_find_best_match(iot_interface_t ** pp_interface,
+ ipv6_addr_t * p_addr_r,
+ const ipv6_addr_t * p_addr_f);
+
+
+/**@brief Sends IPv6 packet.
+ *
+ * @details API used to send an IPv6 packet. Which interface that packet must be sent to is determined
+ * by analyzing the destination address.
+ *
+ * @param[in] p_interface The interface to which the packet is to be sent.
+ * @param[in] p_packet IPv6 packet to send. The packet should be allocated using
+ * @ref iot_pbuffer_allocate, to give stack control and to release
+ * the memory buffer.
+ *
+ * @retval NRF_SUCCESS If the send request was successful.
+ * @retval NRF_ERROR_NOT_FOUND If there was a failure while looking for the interface.
+ * @retval NRF_ERROR_INVALID_PARAM If there was an error in processing the IPv6 packet.
+ * @retval NRF_ERROR_NO_MEM If no memory was available in the transport
+ * interface.
+ */
+uint32_t ipv6_send(const iot_interface_t * p_interface, iot_pbuffer_t * p_packet);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif //IPV6_API_H_
+
+/** @} */
+
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/ipv6_stack/include/udp_api.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/ipv6_stack/include/udp_api.h
new file mode 100644
index 0000000..8efa378
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/ipv6_stack/include/udp_api.h
@@ -0,0 +1,255 @@
+/**
+ * Copyright (c) 2014 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 udp_api.h
+ *
+ * @defgroup iot_udp UDP Application Interface for Nordic's IPv6 stack
+ * @ingroup iot_sdk_stack
+ * @{
+ * @brief Nordic User Datagram Protocol Application Interface for Nordic's IPv6 stack.
+ *
+ * @details This module provides basic features related to User Datagram Protocol (UDP) support.
+ */
+
+#ifndef UDP_API_H__
+#define UDP_API_H__
+
+#include "sdk_config.h"
+#include "sdk_common.h"
+#include "iot_defines.h"
+#include "ipv6_api.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @brief UDP socket reference.
+ */
+typedef struct
+{
+ uint32_t socket_id; /**< UDP socket identifier. */
+ void * p_app_data; /**< Pointer to application data mapped by the application to the socket. If no mapping is provided by the application using the @ref udp6_socket_app_data_set API, this pointer is NULL. */
+} udp6_socket_t;
+
+/**
+ * @brief UDP data receive callback.
+ *
+ * @details API used to notify the application of UDP packets received. If the received data is
+ * malformed (for example, a checksum error), the packet is still notified to the application.
+ * The process_result parameter indicates whether the packet was successfully processed by UDP.
+ * The application should check process_result before
+ * consuming the packet.
+ *
+ * @param[in] p_socket Reference to the socket on which the data is received.
+ * @param[in] p_ip6_header Pointer to the IP header of the received ICMP packet.
+ * @param[in] p_udp_header Pointer to the UDP header of the received packet.
+ * @param[in] process_result Notifies the application if the UDP packet was processed successfully success or
+ * if an error occurred, for example, the packet was malformed.
+ * @param[in] p_rx_packet Packet buffer containing the received packed. p_rx_packet->p_payload
+ * contains the UDP payload.
+ *
+ * @returns A provision for the application to notify the module of whether the received packet was
+ * processed successfully by application. The application may take ownership of the received
+ * packet by returning IOT_IPV6_ERR_PENDING, in which case the application must take care to
+ * free it using @ref iot_pbuffer_free.
+ */
+typedef uint32_t (* udp6_handler_t)(const udp6_socket_t * p_socket,
+ const ipv6_header_t * p_ip_header,
+ const udp6_header_t * p_udp_header,
+ uint32_t process_result,
+ iot_pbuffer_t * p_rx_packet);
+
+
+/**
+ * @brief Allocates a UDP socket.
+ *
+ * @details This API should be called to be assigned a UDP socket. The maximum number of sockets that can
+ * be allocated using the API is determined by the define UDP6_MAX_SOCKET_COUNT.
+ *
+ * @param[out] p_socket Reference to the allocated socket is provided in the pointer if the procedure
+ * was successful. Should not be NULL.
+ *
+ * @retval NRF_SUCCESS If the socket was allocated successfully. Otherwise, an
+ * error code that indicates the reason for the failure is returned.
+ */
+uint32_t udp6_socket_allocate(udp6_socket_t * p_socket);
+
+
+/**
+ * @brief Frees an allocated UDP socket.
+ *
+ * @details API used to free a socket allocated using @ref udp6_socket_allocate.
+ *
+ * @param[in] p_socket Handle reference to the socket. Should not be NULL.
+ *
+ * @retval NRF_SUCCESS If the socket was freed successfully. Otherwise, an
+ * error code that indicates the reason for the failure is returned.
+ *
+ */
+uint32_t udp6_socket_free(const udp6_socket_t * p_socket);
+
+
+/**
+ * @brief Registers callback to be notified of data received on a socket.
+ *
+ * @details API to register a callback to be notified of data received on a socket.
+ *
+ * @param[in] p_socket Handle reference to the socket. Should not be NULL.
+ * @param[in] callback Callback being registered to receive data. Should not be NULL.
+ *
+ * @retval NRF_SUCCESS If the procedure was executed successfully. Otherwise, an
+ * error code that indicates the reason for the failure is returned.
+ *
+ */
+uint32_t udp6_socket_recv(const udp6_socket_t * p_socket,
+ const udp6_handler_t callback);
+
+
+/**
+ * @brief Binds a UDP socket to a specific port and address.
+ *
+ * @details API used to bind a UDP socket to a local port and an address.
+ *
+ * @param[in] p_socket Handle reference to the socket. Should not be NULL.
+ * @param[in] p_src_addr Local IPv6 address to be bound on specific socket.
+ * @param[in] src_port Local UDP port to be bound on specific socket.
+ *
+ * @retval NRF_SUCCESS If the procedure was executed successfully. Otherwise, an
+ * error code that indicates the reason for the failure is returned.
+ *
+ */
+uint32_t udp6_socket_bind(const udp6_socket_t * p_socket,
+ const ipv6_addr_t * p_src_addr,
+ uint16_t src_port);
+
+
+/**
+ * @brief Connects a UDP socket to aspecific port and address.
+ *
+ * @details API used to connect a UDP socket to a remote port and remote address.
+ *
+ * @param[in] p_socket Handle reference to the socket. Should not be NULL.
+ * @param[in] p_dest_addr IPv6 address of the remote destination.
+ * @param[in] dest_port Remote USP port to connect the socket to.
+ *
+ * @retval NRF_SUCCESS If the connection was established successfully.
+ */
+uint32_t udp6_socket_connect(const udp6_socket_t * p_socket,
+ const ipv6_addr_t * p_dest_addr,
+ uint16_t dest_port);
+
+
+/**
+ * @brief Sends a UDP packet on a specific socket.
+ *
+ * @details API used to send UDP data over a UDP socket. Remote port and address must be set with
+ * \ref udp6_socket_connect() before using this API.
+ *
+ * Applications that call this function should allocate a packet with type
+ * UDP6_PACKET_TYPE (set in the allocation
+ * parameter) before calling the function.
+ *
+ * The application shall not free the allocated packet buffer if the procedure was
+ * successful, to ensure that no data copies are needed when transmitting a packet.
+ *
+ * @param[in] p_socket Handle reference to the socket. Should not be NULL.
+ * @param[in] p_packet Data to be transmitted on the socket. The application should allocate a packet
+ * buffer with type UDP6_PACKET_TYPE using \ref iot_pbuffer_allocate.
+ * p_packet->p_payload and p_packet->length should be appropriately
+ * populated by the application to contain the payload and length of the UDP
+ * packet, respectively.
+ *
+ * @retval NRF_SUCCESS If the procedure was executed successfully. Otherwise, an
+ * error code that indicates the reason for the failure is returned.
+ *
+ */
+uint32_t udp6_socket_send(const udp6_socket_t * p_socket,
+ iot_pbuffer_t * p_packet);
+
+
+/**
+ * @brief Sends a UDP packet on a specific socket to a remote address and port.
+ *
+ * @details API used to send UDP data over a UDP socket.
+ *
+ * @param[in] p_socket Handle reference to the socket. Should not be NULL.
+ * @param[in] p_dest_addr IPv6 address of the remote destination.
+ * @param[in] dest_port Remote UDP port to which data transmission is requested.
+ * @param[in] p_packet Data to be transmitted on the socket. Application should allocate a
+ * packet buffer with type UDP6_PACKET_TYPE using \ref
+ * iot_pbuffer_allocate. p_packet->p_payload and p_packet->length should
+ * be appropriately populated by the application to contain the payload and
+ * length of the UDP packet, respectively.
+ *
+ * @retval NRF_SUCCESS If the procedure was executed successfully. Otherwise, an
+ * error code that indicates the reason for the failure is returned.
+ *
+ */
+uint32_t udp6_socket_sendto(const udp6_socket_t * p_socket,
+ const ipv6_addr_t * p_dest_addr,
+ uint16_t dest_port,
+ iot_pbuffer_t * p_packet);
+
+
+/**
+ * @brief Sets application data for a socket.
+ *
+ * @details A utility API that allows the application to set any application specific mapping with the
+ * UDP Socket. The UDP module remembers the pointer provided by the application as long as the
+ * socket is not freed and if receive data callback is called each time as part of
+ * udp_socket_t.
+ *
+ * @param[in] p_socket Pointer to the socket for which the application data mapping is being set.
+ * A pointer to the application data should be provided by setting the
+ * p_socket->p_app_data field.
+ *
+ * @retval NRF_SUCCESS If the procedure was executed successfully. Otherwise, an
+ * error code that indicates the reason for the failure is returned.
+ *
+ */
+uint32_t udp6_socket_app_data_set(const udp6_socket_t * p_socket);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif //UDP_API_H__
+
+/**@} */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/ipv6_stack/ipv6/ipv6.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/ipv6_stack/ipv6/ipv6.c
new file mode 100644
index 0000000..6d7b641
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/ipv6_stack/ipv6/ipv6.c
@@ -0,0 +1,1088 @@
+/**
+ * Copyright (c) 2013 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#include <stdio.h>
+#include <stdint.h>
+#include <string.h>
+
+#include "ble_6lowpan.h"
+#include "mem_manager.h"
+#include "sdk_os.h"
+#include "sdk_config.h"
+#include "iot_common.h"
+#include "iot_context_manager.h"
+#include "ipv6_api.h"
+#include "icmp6_api.h"
+#include "udp_api.h"
+#include "icmp6.h"
+#include "udp.h"
+
+#if IPV6_CONFIG_LOG_ENABLED
+
+#define NRF_LOG_MODULE_NAME ipv6
+
+#define NRF_LOG_LEVEL IPV6_CONFIG_LOG_LEVEL
+#define NRF_LOG_INFO_COLOR IPV6_CONFIG_INFO_COLOR
+#define NRF_LOG_DEBUG_COLOR IPV6_CONFIG_DEBUG_COLOR
+
+#include "nrf_log.h"
+NRF_LOG_MODULE_REGISTER();
+
+#define IPV6_TRC NRF_LOG_DEBUG /**< Used for getting trace of execution in the module. */
+#define IPV6_ERR NRF_LOG_ERROR /**< Used for logging errors in the module. */
+#define IPV6_DUMP NRF_LOG_HEXDUMP_DEBUG /**< Used for dumping octet information to get details of bond information etc. */
+
+#define IPV6_ENTRY() IPV6_TRC(">> %s", __func__)
+#define IPV6_EXIT() IPV6_TRC("<< %s", __func__)
+
+#else // IPV6_CONFIG_LOG_ENABLED
+
+#define IPV6_TRC(...) /**< Disables traces. */
+#define IPV6_DUMP(...) /**< Disables dumping of octet streams. */
+#define IPV6_ERR(...) /**< Disables error logs. */
+
+#define IPV6_ENTRY(...)
+#define IPV6_EXIT(...)
+
+#endif // IPV6_CONFIG_LOG_ENABLED
+
+/**
+ * @defgroup ipv6_mutex_lock_unlock Module's Mutex Lock/Unlock Macros.
+ *
+ * @details Macros used to lock and unlock modules. Currently, SDK does not use mutexes but
+ * framework is provided in case need arises to use an alternative architecture.
+ * @{
+ */
+#define IPV6_MUTEX_LOCK() SDK_MUTEX_LOCK(m_ipv6_mutex) /**< Lock module using mutex */
+#define IPV6_MUTEX_UNLOCK() SDK_MUTEX_UNLOCK(m_ipv6_mutex) /**< Unlock module using mutex */
+/** @} */
+
+/**
+ * @defgroup api_param_check API Parameters check macros.
+ *
+ * @details Macros that verify parameters passed to the module in the APIs. These macros
+ * could be mapped to nothing in final versions of code to save execution and size.
+ * IPV6_DISABLE_API_PARAM_CHECK should be set to 0 to enable these checks.
+ *
+ * @{
+ */
+
+#if (IPV6_DISABLE_API_PARAM_CHECK == 0)
+
+/**@brief Macro to check is module is initialized before requesting one of the module procedures. */
+#define VERIFY_MODULE_IS_INITIALIZED() \
+ if (m_event_handler == NULL) \
+ { \
+ return (SDK_ERR_MODULE_NOT_INITIALIZED | IOT_IPV6_ERR_BASE); \
+ }
+
+/**@brief Verify NULL parameters are not passed to API by application. */
+#define NULL_PARAM_CHECK(PARAM) \
+ if ((PARAM) == NULL) \
+ { \
+ return (NRF_ERROR_NULL | IOT_IPV6_ERR_BASE); \
+ }
+
+#else // IPV6_DISABLE_API_PARAM_CHECK
+
+#define VERIFY_MODULE_IS_INITIALIZED()
+#define NULL_PARAM_CHECK(PARAM)
+
+#endif // IPV6_DISABLE_API_PARAM_CHECK
+/** @} */
+
+#define PBUFFER_ICMP_PAYLOAD_OFFSET IPV6_IP_HEADER_SIZE + ICMP6_HEADER_SIZE /**< ICMP payload offset. */
+#define PBUFFER_UDP_PAYLOAD_OFFSET IPV6_IP_HEADER_SIZE + UDP_HEADER_SIZE /**< UDP payload offset. */
+#define PBUFFER_OTHER_PAYLOAD_OFFSET IPV6_IP_HEADER_SIZE /**< Raw IPv6 payload offset. */
+
+#define IPV6_MAX_ADDRESS_COUNT (IPV6_MAX_ADDRESS_PER_INTERFACE * IPV6_MAX_INTERFACE) /**< Maximum number of addresses. */
+#define IPV6_INVALID_ADDR_INDEX 0xFF /**< Invalid address representation. */
+
+#define DEST_ADDR_OFFSET 24 /**< Offset of destination address in IPv6 packet. */
+
+/**@brief Internal interface structure. */
+typedef struct
+{
+ iot_interface_t * p_interface; /**< Pointer to driver interface */
+ uint8_t addr_range[IPV6_MAX_ADDRESS_PER_INTERFACE]; /**< Indexes to m_address_table indicating the address. If an index is IPV6_INVALID_ADDR_INDEX, it means there is no address entry. */
+} ipv6_interface_t;
+
+/**@brief Application Event Handler. */
+static ipv6_evt_handler_t m_event_handler = NULL;
+
+/**@brief Table of addresses */
+static ipv6_addr_conf_t m_address_table[IPV6_MAX_ADDRESS_COUNT];
+
+/**@brief Network interfaces table. */
+static ipv6_interface_t m_interfaces[IPV6_MAX_INTERFACE];
+
+/**@brief Number of network interfaces. */
+static uint32_t m_interfaces_count = 0;
+
+/**@brief Global address for IPv6 any. */
+ipv6_addr_t ipv6_addr_any;
+
+/**@brief Mutex variable. Currently unused, this declaration does not occupy any space in RAM. */
+SDK_MUTEX_DEFINE(m_ipv6_mutex)
+
+
+/**@brief Function for finding specific address in address table.
+ *
+ * @param[in] p_addr Checked address.
+ * @param[out] p_index Index of address.
+ *
+ * @return NRF_SUCCESS if success, NRF_ERROR_NOT_FOUND otherwise.
+ */
+static uint32_t addr_find(const ipv6_addr_t * p_addr, uint32_t * p_index)
+{
+ uint32_t index;
+ uint32_t err_code = (IOT_IPV6_ERR_BASE | NRF_ERROR_NOT_FOUND);
+
+ for (index = 0; index < IPV6_MAX_ADDRESS_COUNT; index++)
+ {
+ if ((m_address_table[index].state != IPV6_ADDR_STATE_UNUSED) &&
+ (0 == IPV6_ADDRESS_CMP(&m_address_table[index].addr, p_addr)))
+ {
+ *p_index = index;
+ err_code = NRF_SUCCESS;
+ break;
+ }
+ }
+
+ return err_code;
+}
+
+/**@brief Function for finding free place in address table.
+ *
+ * @param[out] p_index Index of address.
+ *
+ * @return NRF_SUCCESS if success, NRF_ERROR_NOT_FOUND otherwise.
+ */
+static uint32_t addr_find_free(uint32_t * p_index)
+{
+ uint32_t index;
+ uint32_t err_code = (IOT_IPV6_ERR_BASE | NRF_ERROR_NO_MEM);
+
+ for (index = 0; index < IPV6_MAX_ADDRESS_COUNT; index++)
+ {
+ if (m_address_table[index].state == IPV6_ADDR_STATE_UNUSED)
+ {
+ *p_index = index;
+ err_code = NRF_SUCCESS;
+ break;
+ }
+ }
+
+ return err_code;
+}
+
+
+/**@brief Function for freeing an address configuration entry in m_address_table.
+ *
+ * @param[in] index Index of address.
+ * @param[in] check_references Indicate that before remove references should be counted.
+ *
+ * @return None.
+ */
+static void addr_free(uint32_t addr_index, bool check_references)
+{
+ uint32_t if_index;
+ uint32_t index;
+
+ if (check_references)
+ {
+ for (if_index = 0; if_index < IPV6_MAX_INTERFACE; if_index++)
+ {
+ for (index = 0; index < IPV6_MAX_ADDRESS_PER_INTERFACE; index++)
+ {
+ if (m_interfaces[if_index].addr_range[index] == addr_index)
+ {
+ return;
+ }
+ }
+ }
+ }
+
+ m_address_table[addr_index].state = IPV6_ADDR_STATE_UNUSED;
+ IPV6_ADDRESS_INITIALIZE(&m_address_table[addr_index].addr);
+}
+
+
+/**@brief Function for checking if received packet is for us.
+ * Currently only all-node, MLDv2 and solicited-node
+* multicast addresses are accepted.
+ *
+ * @param[in] interface_id Index of the interface.
+ * @param[in] p_addr Checked address.
+ * @param[in] check_multicast Define if multicast addresses have to be checked.
+ *
+ * @return NRF_SUCCESS if packet can be processing to IPv6 multiplexer.
+ */
+static uint32_t addr_check(uint32_t interface_id, const ipv6_addr_t * p_addr, bool check_multicast)
+{
+ ipv6_addr_conf_t * p_addr_conf;
+ uint32_t index;
+ uint32_t err_code = NRF_ERROR_NOT_FOUND;
+
+ // Check basic Multicast addresses.
+ if (check_multicast && (IPV6_ADDRESS_IS_MLDV2_MCAST(p_addr) || IPV6_ADDRESS_IS_ALL_NODE(p_addr)))
+ {
+ return NRF_SUCCESS;
+ }
+
+ for (index = 0; m_interfaces[interface_id].addr_range[index] != IPV6_INVALID_ADDR_INDEX; index++)
+ {
+ p_addr_conf = &m_address_table[m_interfaces[interface_id].addr_range[index]];
+
+ if (check_multicast && IPV6_ADDRESS_IS_MULTICAST_SOLICITED_NODE(p_addr))
+ {
+ // Solicited-node multicast address is formed by taking the low-order 24 bits of an address (unicast or anycast).
+ if (0 == memcmp(&p_addr_conf->addr.u8[13], &p_addr->u8[13], 3))
+ {
+ err_code = NRF_SUCCESS;
+ break;
+ }
+ }
+ else if (0 == IPV6_ADDRESS_CMP(&p_addr_conf->addr, p_addr))
+ {
+ err_code = NRF_SUCCESS;
+ break;
+ }
+ }
+
+ return err_code;
+}
+
+
+/**@brief Function for adding/updating IPv6 address in table.
+ *
+ * @param[in] interface_id Index of interface.
+ * @param[in] p_addr Given address.
+ *
+ * @return NRF_SUCCESS if operation successful, NRF_ERROR_NO_MEM otherwise.
+ */
+static uint32_t addr_set(const iot_interface_t * p_interface,
+ const ipv6_addr_conf_t * p_addr)
+{
+ uint32_t index;
+ uint32_t addr_index;
+ uint32_t err_code;
+
+ uint32_t interface_id = (uint32_t)p_interface->p_upper_stack;
+
+ // Try to find address.
+ err_code = addr_find(&p_addr->addr, &addr_index);
+
+ if (err_code != NRF_SUCCESS)
+ {
+ // Find first empty one.
+ err_code = addr_find_free(&addr_index);
+ }
+
+ if (err_code == NRF_SUCCESS)
+ {
+ err_code = IOT_IPV6_ERR_ADDR_IF_MISMATCH;
+
+ // Check if this index entry exists in the p_interface for which API is requested.
+ for (index = 0; index < IPV6_MAX_ADDRESS_PER_INTERFACE; index++)
+ {
+ if (m_interfaces[interface_id].addr_range[index] == addr_index)
+ {
+ m_address_table[index].state = p_addr->state;
+
+ err_code = NRF_SUCCESS;
+ break;
+ }
+ }
+
+ if (err_code == IOT_IPV6_ERR_ADDR_IF_MISMATCH)
+ {
+ err_code = (IOT_IPV6_ERR_BASE | NRF_ERROR_NO_MEM);
+
+ for (index = 0; index < IPV6_MAX_ADDRESS_PER_INTERFACE; index++)
+ {
+ if (m_interfaces[interface_id].addr_range[index] == IPV6_INVALID_ADDR_INDEX)
+ {
+ m_address_table[index].state = p_addr->state;
+ memcpy(&m_address_table[index].addr, p_addr, IPV6_ADDR_SIZE);
+ m_interfaces[interface_id].addr_range[index] = addr_index;
+
+ err_code = NRF_SUCCESS;
+ break;
+ }
+ }
+ }
+ }
+
+ return err_code;
+}
+
+
+/**@brief Function for calculating how many bits of addresses are equal.
+ *
+ * @param[in] p_addr1 Base address.
+ * @param[in] p_addr2 Base address.
+ *
+ * @return Number of same bits.
+ */
+static uint32_t addr_bit_equal(const ipv6_addr_t * p_addr1,
+ const ipv6_addr_t * p_addr2)
+{
+ uint32_t index;
+ uint32_t match = 0;
+ uint8_t temp;
+ uint32_t index_tab;
+
+ for (index = 0; index < IPV6_ADDR_SIZE; index++)
+ {
+ if (p_addr1->u8[index] == p_addr2->u8[index])
+ {
+ // Add full 8bits to match
+ match += 8;
+ }
+ else
+ {
+ // Operation of XOR to detect differences
+ temp = p_addr1->u8[index] ^ p_addr2->u8[index];
+
+ // Check all single bits
+ for (index_tab = 0; index_tab < 8; index_tab++)
+ {
+ if ((temp & 0x80) == 0)
+ {
+ // If the oldest bits matched, add one more.
+ match++;
+
+ // Check next bit.
+ temp = temp << 1;
+ }
+ else
+ {
+ break;
+ }
+ }
+
+ break;
+ }
+ }
+
+ return match;
+}
+
+/**@brief Function for searching specific network interface by given address.
+ *
+ * @param[in] p_interface Pointer to IPv6 network interface.
+ * @param[in] p_dest_addr IPv6 address to be matched.
+ *
+ * @return NRF_SUCCESS if operation successful, NRF_ERROR_NOT_FOUND otherwise.
+ */
+static uint32_t interface_find(iot_interface_t ** pp_interface, const ipv6_addr_t * p_dest_addr)
+{
+ // Currently only host role is implemented, though no need to match addresses.
+ UNUSED_VARIABLE(p_dest_addr);
+
+ uint32_t index;
+ uint32_t err_code = (IOT_IPV6_ERR_BASE | NRF_ERROR_NOT_FOUND);
+
+ if (m_interfaces_count == 1)
+ {
+ for (index = 0; index < IPV6_MAX_INTERFACE; index++)
+ {
+ if (m_interfaces[index].p_interface != NULL)
+ {
+ *pp_interface = m_interfaces[index].p_interface;
+ err_code = NRF_SUCCESS;
+ break;
+ }
+ }
+ }
+ else if (m_interfaces_count == 0)
+ {
+ err_code = (IOT_IPV6_ERR_BASE | NRF_ERROR_NOT_FOUND);
+ }
+ else
+ {
+ // Not supported now.
+ err_code = (IOT_IPV6_ERR_BASE | NRF_ERROR_NOT_SUPPORTED);
+ }
+
+ return err_code;
+}
+
+
+/**@brief Function for resetting specific network interface.
+ *
+ * @param[in] p_interface Pointer to IPv6 network interface.
+ *
+ * @return None.
+ */
+static void interface_reset(ipv6_interface_t * p_interface)
+{
+ uint32_t index;
+ uint8_t addr_index;
+
+ p_interface->p_interface = NULL;
+
+ for (index = 0; index < IPV6_MAX_ADDRESS_PER_INTERFACE; index++)
+ {
+ addr_index = p_interface->addr_range[index];
+
+ if (addr_index != IPV6_INVALID_ADDR_INDEX)
+ {
+ p_interface->addr_range[index] = IPV6_INVALID_ADDR_INDEX;
+ addr_free(index, true);
+ }
+ }
+}
+
+
+/**@brief Function for getting specific network interface by 6LoWPAN interface.
+ *
+ * @param[in] p_6lo_interface Pointer to 6LoWPAN interface.
+ *
+ * @return Pointer to internal network interface on success, otherwise NULL.
+ */
+static uint32_t interface_get_by_6lo(iot_interface_t * p_6lo_interface)
+{
+ return (uint32_t)(p_6lo_interface->p_upper_stack);
+}
+
+
+/**@brief Function for adding new 6lowpan interface to interface table.
+ *
+ * @param[in] p_6lo_interface Pointer to 6LoWPAN interface.
+ * @param[out] p_index Pointer to index of internal network interface.
+ *
+ * @return NRF_SUCCESS on success, otherwise NRF_ERROR_NO_MEM error.
+ */
+static uint32_t interface_add(iot_interface_t * p_interface,
+ uint32_t * p_index )
+{
+ uint32_t index;
+ uint32_t err_code;
+ ipv6_addr_conf_t linklocal_addr;
+
+ for (index = 0; index < IPV6_MAX_INTERFACE; index++)
+ {
+ if (m_interfaces[index].p_interface == NULL)
+ {
+ m_interfaces[index].p_interface = p_interface;
+ p_interface->p_upper_stack = (void *) index;
+ (*p_index) = index;
+
+ // Add link local address.
+ IPV6_CREATE_LINK_LOCAL_FROM_EUI64(&linklocal_addr.addr, p_interface->local_addr.identifier);
+ linklocal_addr.state = IPV6_ADDR_STATE_PREFERRED;
+
+ err_code = addr_set(p_interface, &linklocal_addr);
+ if (err_code != NRF_SUCCESS)
+ {
+ IPV6_ERR("Cannot add link-local address to interface!");
+ }
+
+ return NRF_SUCCESS;
+ }
+ }
+
+ return NRF_ERROR_NO_MEM;
+}
+
+
+/**@brief Function for removing 6lowpan interface from interface table.
+ *
+ * @param[in] p_interface Pointer to internal network interface.
+ *
+ * @return None.
+ */
+static void interface_delete(uint32_t index)
+{
+ interface_reset(&m_interfaces[index]);
+}
+
+/**@brief Function for notifying application of the new interface established.
+ *
+ * @param[in] p_interface Pointer to internal network interface.
+ *
+ * @return None.
+ */
+static void app_notify_interface_add(iot_interface_t * p_interface)
+{
+ ipv6_event_t event;
+
+ event.event_id = IPV6_EVT_INTERFACE_ADD;
+
+ IPV6_MUTEX_UNLOCK();
+
+ m_event_handler(p_interface, &event);
+
+ IPV6_MUTEX_LOCK();
+}
+
+
+/**@brief Function for notifying application of the interface disconnection.
+ *
+ * @param[in] p_interface Pointer to internal network interface.
+ *
+ * @return None.
+ */
+static void app_notify_interface_delete(iot_interface_t * p_interface)
+{
+ ipv6_event_t event;
+
+ event.event_id = IPV6_EVT_INTERFACE_DELETE;
+
+ IPV6_MUTEX_UNLOCK();
+
+ m_event_handler(p_interface, &event);
+
+ IPV6_MUTEX_LOCK();
+}
+
+
+#if (IPV6_ENABLE_USNUPORTED_PROTOCOLS_TO_APPLICATION == 1)
+/**@brief Function for notifying application of the received packet (e.g. with unsupported protocol).
+ *
+ * @param[in] p_interface Pointer to external interface from which packet come.
+ * @param[in] p_pbuffer Pointer to packet buffer.
+ *
+ * @return None.
+ */
+static void app_notify_rx_data(iot_interface_t * p_interface, iot_pbuffer_t * p_pbuffer)
+{
+ ipv6_event_t event;
+
+ event.event_id = IPV6_EVT_INTERFACE_RX_DATA;
+
+ // RX Event parameter.
+ event.event_param.rx_event_param.p_rx_packet = p_pbuffer;
+ event.event_param.rx_event_param.p_ip_header = (ipv6_header_t *)p_pbuffer->p_memory;
+
+ IPV6_MUTEX_UNLOCK();
+
+ m_event_handler(p_interface, &event);
+
+ IPV6_MUTEX_LOCK();
+}
+#endif
+
+
+/**@brief Function for multiplexing transport protocol to different modules.
+ *
+ * @param[in] p_interface Pointer to external interface from which packet come.
+ * @param[in] p_pbuffer Pointer to packet buffer.
+ *
+ * @return NRF_SUCCESS if success, otherwise an error code.
+ */
+static uint32_t ipv6_input(iot_interface_t * p_interface, iot_pbuffer_t * p_pbuffer)
+{
+ uint32_t err_code = NRF_SUCCESS;
+ ipv6_header_t * p_iphdr = (ipv6_header_t *)(p_pbuffer->p_payload - IPV6_IP_HEADER_SIZE);
+
+ // Change byte order of IP header given to application.
+ p_iphdr->length = NTOHS(p_iphdr->length);
+ p_iphdr->flowlabel = NTOHS(p_iphdr->flowlabel);
+
+ switch (p_iphdr->next_header)
+ {
+ case IPV6_NEXT_HEADER_ICMP6:
+ IPV6_TRC("Got ICMPv6 packet.");
+
+ IPV6_MUTEX_UNLOCK();
+ err_code = icmp6_input(p_interface, p_iphdr, p_pbuffer);
+ IPV6_MUTEX_LOCK();
+
+ break;
+
+ case IPV6_NEXT_HEADER_UDP:
+ IPV6_TRC("Got UDP packet.");
+
+ IPV6_MUTEX_UNLOCK();
+ err_code = udp_input(p_interface, p_iphdr, p_pbuffer);
+ IPV6_MUTEX_LOCK();
+
+ break;
+
+ default:
+ IPV6_ERR("Got unsupported protocol packet. Protocol ID = 0x%x!",
+ p_iphdr->next_header);
+
+#if (IPV6_ENABLE_USNUPORTED_PROTOCOLS_TO_APPLICATION == 1)
+ app_notify_rx_data(p_interface, p_pbuffer);
+#endif
+ break;
+ }
+
+ // Free packet buffer unless marked explicitly as pending
+ if (err_code != IOT_IPV6_ERR_PENDING)
+ {
+ UNUSED_VARIABLE(iot_pbuffer_free(p_pbuffer, true));
+ }
+
+ return err_code;
+}
+
+
+/**@brief Function for receiving 6LoWPAN module events.
+ *
+ * @param[in] p_6lo_interface Pointer to 6LoWPAN interface.
+ * @param[in] p_6lo_event Pointer to 6LoWPAN related event.
+ *
+ * @return None.
+ */
+static void ble_6lowpan_evt_handler(iot_interface_t * p_interface,
+ ble_6lowpan_event_t * p_6lo_event)
+{
+ bool rx_failure = false;
+ uint32_t err_code;
+ uint32_t interface_id;
+ iot_pbuffer_t * p_pbuffer;
+ iot_pbuffer_alloc_param_t pbuff_param;
+
+ IPV6_MUTEX_LOCK();
+
+ IPV6_ENTRY();
+ IPV6_TRC("In 6LoWPAN Handler:");
+
+ interface_id = interface_get_by_6lo(p_interface);
+
+ switch (p_6lo_event->event_id)
+ {
+ case BLE_6LO_EVT_ERROR:
+ {
+ IPV6_ERR("Got error, with result %08lx", p_6lo_event->event_result);
+ break;
+ }
+ case BLE_6LO_EVT_INTERFACE_ADD:
+ {
+ IPV6_TRC("New interface established!");
+
+ // Add interface to internal table.
+ err_code = interface_add(p_interface, &interface_id);
+
+ if (NRF_SUCCESS == err_code)
+ {
+ IPV6_TRC("Added new network interface to internal table.");
+
+ err_code = iot_context_manager_table_alloc(p_interface);
+
+ if (err_code == NRF_SUCCESS)
+ {
+ IPV6_TRC("Successfully allocated context table!");
+ }
+ else
+ {
+ IPV6_ERR("Failed to allocate context table!");
+ }
+
+ // Increase number of up interfaces.
+ m_interfaces_count++;
+
+ // Notify application.
+ app_notify_interface_add(p_interface);
+ }
+ else
+ {
+ IPV6_ERR("Cannot add new interface. Table is full.");
+ }
+
+ break;
+ }
+ case BLE_6LO_EVT_INTERFACE_DELETE:
+ {
+ IPV6_TRC("Interface disconnected!");
+
+ if (interface_id < IPV6_MAX_INTERFACE)
+ {
+ IPV6_TRC("Removed network interface.");
+
+ // Notify application.
+ app_notify_interface_delete(p_interface);
+
+ err_code = iot_context_manager_table_free(p_interface);
+
+ if (err_code == NRF_SUCCESS)
+ {
+ IPV6_TRC("Successfully freed context table!");
+ }
+
+ // Decrease number of up interfaces.
+ m_interfaces_count--;
+
+ // Remove interface from internal table.
+ interface_delete(interface_id);
+ }
+ break;
+ }
+ case BLE_6LO_EVT_INTERFACE_DATA_RX:
+ {
+ IPV6_TRC("Got data with size = %d!",
+ p_6lo_event->event_param.rx_event_param.packet_len);
+ IPV6_TRC("Data: ");
+ IPV6_DUMP(p_6lo_event->event_param.rx_event_param.p_packet,
+ p_6lo_event->event_param.rx_event_param.packet_len);
+
+ if (interface_id < IPV6_MAX_INTERFACE)
+ {
+ if (p_6lo_event->event_result == NRF_ERROR_NOT_FOUND)
+ {
+ IPV6_ERR("Cannot restore IPv6 addresses!");
+ IPV6_ERR("Source CID = 0x%x, Destination CID = 0x%x",
+ p_6lo_event->event_param.rx_event_param.rx_contexts.src_cntxt_id,
+ p_6lo_event->event_param.rx_event_param.rx_contexts.dest_cntxt_id);
+
+ // Indicates failure.
+ rx_failure = true;
+ break;
+ }
+
+ // Check if packet is for us.
+ ipv6_addr_t * p_addr =
+ (ipv6_addr_t *)&p_6lo_event->event_param.rx_event_param.p_packet[DEST_ADDR_OFFSET];
+
+ err_code = addr_check(interface_id, p_addr, true);
+
+ // If no address found - drop message.
+ if (err_code != NRF_SUCCESS)
+ {
+ IPV6_ERR("Packet received on unknown address!");
+ rx_failure = true;
+ break;
+ }
+
+ // Try to allocate pbuffer, with no memory.
+ pbuff_param.flags = PBUFFER_FLAG_NO_MEM_ALLOCATION;
+ pbuff_param.type = RAW_PACKET_TYPE;
+ pbuff_param.length = p_6lo_event->event_param.rx_event_param.packet_len;
+
+ // Try to allocate pbuffer for receiving data.
+ err_code = iot_pbuffer_allocate(&pbuff_param, &p_pbuffer);
+
+ if (err_code == NRF_SUCCESS)
+ {
+ p_pbuffer->p_memory = p_6lo_event->event_param.rx_event_param.p_packet;
+ p_pbuffer->p_payload = p_pbuffer->p_memory + IPV6_IP_HEADER_SIZE;
+ p_pbuffer->length -= IPV6_IP_HEADER_SIZE;
+
+ // Execute multiplexer.
+ err_code = ipv6_input(p_interface, p_pbuffer);
+
+ if (err_code != NRF_SUCCESS)
+ {
+ IPV6_ERR("Failed while processing packet, error = 0x%08lX!", err_code);
+ }
+ }
+ else
+ {
+ IPV6_ERR("Failed to allocate packet buffer!");
+ rx_failure = true;
+ }
+ }
+ else
+ {
+ IPV6_ERR("[6LOWPAN]: Got data to unknown interface!");
+ rx_failure = true;
+ }
+
+ break;
+ }
+ default:
+ break;
+ }
+
+ if (rx_failure == true)
+ {
+ UNUSED_VARIABLE(nrf_free(p_6lo_event->event_param.rx_event_param.p_packet));
+ }
+
+ IPV6_EXIT();
+
+ IPV6_MUTEX_UNLOCK();
+}
+
+
+uint32_t ipv6_init(const ipv6_init_t * p_init)
+{
+ uint32_t index;
+ uint32_t err_code;
+ ble_6lowpan_init_t init_params;
+
+ NULL_PARAM_CHECK(p_init);
+ NULL_PARAM_CHECK(p_init->p_eui64);
+ NULL_PARAM_CHECK(p_init->event_handler);
+
+ SDK_MUTEX_INIT(m_ipv6_mutex);
+ IPV6_MUTEX_LOCK();
+
+ IPV6_ENTRY();
+
+ // Initialize related modules.
+ UNUSED_VARIABLE(nrf_mem_init());
+ UNUSED_VARIABLE(iot_pbuffer_init());
+
+ // Initialize submodules of IPv6 stack.
+ UNUSED_VARIABLE(udp_init());
+ UNUSED_VARIABLE(icmp6_init());
+
+ // Initialize context manager.
+ UNUSED_VARIABLE(iot_context_manager_init());
+
+ IPV6_ADDRESS_INITIALIZE(IPV6_ADDR_ANY);
+
+ // Set application event handler.
+ m_event_handler = p_init->event_handler;
+
+ // Clear number of interfaces.
+ m_interfaces_count = 0;
+
+ // Clear network interfaces.
+ for (index = 0; index < IPV6_MAX_INTERFACE; index++)
+ {
+ interface_reset(&m_interfaces[index]);
+ }
+
+ // Clear all addresses.
+ for (index = 0; index < IPV6_MAX_ADDRESS_COUNT; index++)
+ {
+ addr_free(index, false);
+ }
+
+ // 6LoWPAN module initialization.
+ init_params.p_eui64 = p_init->p_eui64;
+ init_params.event_handler = ble_6lowpan_evt_handler;
+
+ err_code = ble_6lowpan_init(&init_params);
+
+ IPV6_EXIT();
+
+ IPV6_MUTEX_UNLOCK();
+
+ return err_code;
+}
+
+
+uint32_t ipv6_address_set(const iot_interface_t * p_interface,
+ const ipv6_addr_conf_t * p_addr)
+{
+ VERIFY_MODULE_IS_INITIALIZED();
+
+ NULL_PARAM_CHECK(p_addr);
+ NULL_PARAM_CHECK(p_interface);
+
+ uint32_t err_code;
+
+ IPV6_MUTEX_LOCK();
+
+ IPV6_ENTRY();
+
+ err_code = addr_set(p_interface, p_addr);
+
+ IPV6_EXIT();
+
+ IPV6_MUTEX_UNLOCK();
+
+ return err_code;
+}
+
+
+uint32_t ipv6_address_check(const iot_interface_t * p_interface,
+ const ipv6_addr_t * p_addr)
+{
+ VERIFY_MODULE_IS_INITIALIZED();
+
+ NULL_PARAM_CHECK(p_addr);
+ NULL_PARAM_CHECK(p_interface);
+
+ uint32_t err_code;
+
+ IPV6_MUTEX_LOCK();
+
+ IPV6_ENTRY();
+
+ uint32_t interface_id = (uint32_t)p_interface->p_upper_stack;
+
+ err_code = addr_check(interface_id, p_addr, false);
+
+ IPV6_EXIT();
+
+ IPV6_MUTEX_UNLOCK();
+
+ return err_code;
+}
+
+
+uint32_t ipv6_address_find_best_match(iot_interface_t ** pp_interface,
+ ipv6_addr_t * p_addr_r,
+ const ipv6_addr_t * p_addr_f)
+{
+ VERIFY_MODULE_IS_INITIALIZED();
+
+ NULL_PARAM_CHECK(p_addr_f);
+ NULL_PARAM_CHECK(pp_interface);
+
+ uint32_t index;
+ uint32_t err_code;
+ uint32_t addr_index;
+ uint32_t match_temp = 0;
+ uint32_t match_best = 0;
+ ipv6_addr_t * p_best_addr = NULL;
+
+ IPV6_MUTEX_LOCK();
+
+ err_code = interface_find(pp_interface, p_addr_f);
+
+ if (err_code == NRF_SUCCESS && p_addr_r)
+ {
+ uint32_t interface_id = (uint32_t)(*pp_interface)->p_upper_stack;
+
+ for (index = 0; index < IPV6_MAX_ADDRESS_PER_INTERFACE; index++)
+ {
+ addr_index = m_interfaces[interface_id].addr_range[index];
+
+ if (addr_index != IPV6_INVALID_ADDR_INDEX)
+ {
+ if (m_address_table[addr_index].state == IPV6_ADDR_STATE_PREFERRED)
+ {
+ match_temp = addr_bit_equal(p_addr_f, &m_address_table[addr_index].addr);
+
+ if (match_temp >= match_best)
+ {
+ match_best = match_temp;
+ p_best_addr = &m_address_table[addr_index].addr;
+ }
+ }
+ }
+ }
+
+ // No address found.
+ if (p_best_addr == NULL)
+ {
+ // Set undefined :: address.
+ IPV6_ADDRESS_INITIALIZE(p_addr_r);
+ }
+ else
+ {
+ memcpy(p_addr_r->u8, p_best_addr->u8, IPV6_ADDR_SIZE);
+ }
+ }
+
+ IPV6_MUTEX_UNLOCK();
+
+ return err_code;
+}
+
+
+uint32_t ipv6_address_remove(const iot_interface_t * p_interface,
+ const ipv6_addr_t * p_addr)
+{
+ VERIFY_MODULE_IS_INITIALIZED();
+
+ NULL_PARAM_CHECK(p_addr);
+ NULL_PARAM_CHECK(p_interface);
+
+ uint32_t index;
+ uint32_t err_code;
+ uint32_t addr_index;
+
+ IPV6_MUTEX_LOCK();
+
+ IPV6_ENTRY();
+
+ uint32_t interface_id = (uint32_t)p_interface->p_upper_stack;
+
+ err_code = (IOT_IPV6_ERR_BASE | NRF_ERROR_NOT_FOUND);
+
+ for (index = 0; index < IPV6_MAX_ADDRESS_PER_INTERFACE; index++)
+ {
+ addr_index = m_interfaces[interface_id].addr_range[index];
+
+ if (addr_index != IPV6_INVALID_ADDR_INDEX)
+ {
+ if (0 == IPV6_ADDRESS_CMP(&m_address_table[addr_index].addr, p_addr))
+ {
+ m_interfaces[interface_id].addr_range[index] = IPV6_INVALID_ADDR_INDEX;
+
+ // Remove address if no reference to interface found.
+ addr_free(index, true);
+
+ err_code = NRF_SUCCESS;
+
+ break;
+ }
+ }
+ }
+
+ IPV6_EXIT();
+
+ IPV6_MUTEX_UNLOCK();
+
+ return err_code;
+}
+
+
+uint32_t ipv6_send(const iot_interface_t * p_interface, iot_pbuffer_t * p_packet)
+{
+ VERIFY_MODULE_IS_INITIALIZED();
+
+ NULL_PARAM_CHECK(p_packet);
+ NULL_PARAM_CHECK(p_interface);
+
+ uint32_t err_code;
+
+ IPV6_MUTEX_LOCK();
+
+ IPV6_ENTRY();
+
+ err_code = ble_6lowpan_interface_send(p_interface,
+ p_packet->p_payload,
+ p_packet->length);
+
+ if (err_code != NRF_SUCCESS)
+ {
+ IPV6_ERR("Cannot send packet!");
+ }
+
+ // Free pbuffer, without freeing memory.
+ UNUSED_VARIABLE(iot_pbuffer_free(p_packet, false));
+
+ IPV6_EXIT();
+
+ IPV6_MUTEX_UNLOCK();
+
+ return err_code;
+}
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/ipv6_stack/pbuffer/iot_pbuffer.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/ipv6_stack/pbuffer/iot_pbuffer.c
new file mode 100644
index 0000000..6611396
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/ipv6_stack/pbuffer/iot_pbuffer.c
@@ -0,0 +1,467 @@
+/**
+ * Copyright (c) 2014 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#include "nrf_soc.h"
+#include "nordic_common.h"
+#include "sdk_common.h"
+#include "sdk_config.h"
+#include "iot_common.h"
+#include "iot_pbuffer.h"
+#include "mem_manager.h"
+
+#if IOT_PBUFFER_CONFIG_LOG_ENABLED
+
+#define NRF_LOG_MODULE_NAME pbuffer
+
+#define NRF_LOG_LEVEL IOT_PBUFFER_CONFIG_LOG_LEVEL
+#define NRF_LOG_INFO_COLOR IOT_PBUFFER_CONFIG_INFO_COLOR
+#define NRF_LOG_DEBUG_COLOR IOT_PBUFFER_CONFIG_DEBUG_COLOR
+
+#include "nrf_log.h"
+NRF_LOG_MODULE_REGISTER();
+
+#define PBUFFER_TRC NRF_LOG_DEBUG /**< Used for getting trace of execution in the module. */
+#define PBUFFER_ERR NRF_LOG_ERROR /**< Used for logging errors in the module. */
+#define PBUFFER_DUMP NRF_LOG_HEXDUMP_DEBUG /**< Used for dumping octet information to get details of bond information etc. */
+
+#define PBUFFER_ENTRY() PBUFFER_TRC(">> %s", __func__)
+#define PBUFFER_EXIT() PBUFFER_TRC("<< %s", __func__)
+
+#else // IOT_PBUFFER_CONFIG_LOG_ENABLED
+
+#define PBUFFER_TRC(...) /**< Disables traces. */
+#define PBUFFER_DUMP(...) /**< Disables dumping of octet streams. */
+#define PBUFFER_ERR(...) /**< Disables error logs. */
+
+#define PBUFFER_ENTRY(...)
+#define PBUFFER_EXIT(...)
+
+#endif // IOT_PBUFFER_CONFIG_LOG_ENABLED
+
+/**
+ * @defgroup api_param_check API Parameters check macros.
+ *
+ * @details Macros that verify parameters passed to the module in the APIs. These macros
+ * could be mapped to nothing in final versions of code to save execution and size.
+ * BLE_HPS_DISABLE_API_PARAM_CHECK should be defined to disable these checks.
+ *
+ * @{
+ */
+#if (IOT_PBUFFER_DISABLE_API_PARAM_CHECK == 0)
+
+/**@brief Macro to check is module is initialized before requesting one of the module procedures. */
+#define VERIFY_MODULE_IS_INITIALIZED() \
+ if (m_initialization_state == false) \
+ { \
+ return (SDK_ERR_MODULE_NOT_INITIALIZED | IOT_PBUFFER_ERR_BASE); \
+ }
+
+/**@brief Macro to check is module is initialized before requesting one of the module
+ procedures but does not use any return code. */
+#define VERIFY_MODULE_IS_INITIALIZED_VOID() \
+ if (m_initialization_state == false) \
+ { \
+ return; \
+ }
+
+/**
+ * @brief Verify NULL parameters are not passed to API by application.
+ */
+#define NULL_PARAM_CHECK(PARAM) \
+ if ((PARAM) == NULL) \
+ { \
+ return (NRF_ERROR_NULL | IOT_PBUFFER_ERR_BASE); \
+ }
+
+/**
+ * @brief Verify Type field has valid value.
+ */
+#define VERIFY_PBUFFER_TYPE(TYPE) \
+ if (((TYPE) == 0) || ((TYPE) > COAP_PACKET_TYPE)) \
+ { \
+ return (NRF_ERROR_INVALID_PARAM | IOT_PBUFFER_ERR_BASE); \
+ }
+
+
+/**
+ * @brief Verify flags field has valid value.
+ */
+#define VERIFY_PBUFFER_FLAGS(FLAG) \
+ if ((uint32_t)(FLAG) > PBUFFER_FLAG_NO_MEM_ALLOCATION) \
+ { \
+ return (NRF_ERROR_INVALID_PARAM | IOT_PBUFFER_ERR_BASE); \
+ }
+
+/**
+ * @brief Verify flags field has valid value.
+ */
+#define VERIFY_NON_ZERO_LENGTH(LEN) \
+ if ((LEN) ==0) \
+ { \
+ return (NRF_ERROR_INVALID_LENGTH | IOT_PBUFFER_ERR_BASE); \
+ }
+
+#else //IOT_PBUFFER_DISABLE_API_PARAM_CHECK
+
+#define VERIFY_MODULE_IS_INITIALIZED()
+#define VERIFY_MODULE_IS_INITIALIZED_VOID()
+#define NULL_PARAM_CHECK(PARAM)
+#define VERIFY_PBUFFER_TYPE(TYPE)
+#define VERIFY_PBUFFER_FLAGS(FLAG)
+#define VERIFY_NON_ZERO_LENGTH(LEN)
+
+#endif //IOT_PBUFFER_DISABLE_API_PARAM_CHECK
+
+/**
+ * @defgroup ble_ipsp_mutex_lock_unlock Module's Mutex Lock/Unlock Macros.
+ *
+ * @details Macros used to lock and unlock modules. Currently, SDK does not use mutexes but
+ * framework is provided in case need arises to use an alternative architecture.
+ * @{
+ */
+#define PBUFFER_MUTEX_LOCK() SDK_MUTEX_LOCK(m_pbuffer_mutex) /**< Lock module using mutex */
+#define PBUFFER_MUTEX_UNLOCK() SDK_MUTEX_UNLOCK(m_pbuffer_mutex) /**< Unlock module using mutex */
+/** @} */
+
+/** @brief Packet buffer type managed by the module. */
+typedef struct
+{
+ iot_pbuffer_t buffer; /**< Packet buffer being managed. */
+ uint32_t allocated_length; /**< Length allocated for the buffer. */
+}pbuffer_t;
+
+SDK_MUTEX_DEFINE(m_pbuffer_mutex) /**< Mutex variable. Currently unused, this declaration does not occupy any space in RAM. */
+static bool m_initialization_state = false; /**< Variable to maintain module initialization state. */
+static pbuffer_t m_pbuffer[IOT_PBUFFER_MAX_COUNT]; /**< Table of packet buffers managed by the module. */
+
+
+/**@brief Initializes packet buffer. */
+static void pbuffer_init(pbuffer_t * p_buffer)
+{
+ p_buffer->buffer.p_memory = NULL;
+ p_buffer->buffer.p_payload = NULL;
+ p_buffer->buffer.length = 0;
+ p_buffer->buffer.type = UNASSIGNED_TYPE;
+ p_buffer->allocated_length = 0;
+}
+
+
+/**@brief Get size of offset to be used based on the requested type. */
+static uint32_t type_offset_get(iot_pbuffer_type_t type)
+{
+ uint32_t offset = 0;
+
+ switch (type)
+ {
+ case RAW_PACKET_TYPE:
+ {
+ offset = 0;
+ break;
+ }
+ case IPV6_PACKET_TYPE:
+ {
+ offset = IPV6_IP_HEADER_SIZE;
+ break;
+ }
+ case ICMP6_PACKET_TYPE:
+ {
+ offset = IPV6_IP_HEADER_SIZE + ICMP6_HEADER_SIZE;
+ break;
+ }
+ case UDP6_PACKET_TYPE: // Fall through.
+ {
+ offset = IPV6_IP_HEADER_SIZE + UDP_HEADER_SIZE;
+ break;
+ }
+ case COAP_PACKET_TYPE:
+ {
+ offset = IPV6_IP_HEADER_SIZE + UDP_HEADER_SIZE + COAP_HEADER_SIZE;
+ break;
+ }
+ default:
+ {
+ // Should never happen.
+ break;
+ }
+ }
+
+ return offset;
+}
+
+
+/**@brief Allocates 'length' sized packet buffer. */
+static uint32_t pbuffer_allocate(pbuffer_t ** pp_buffer, uint32_t length, iot_pbuffer_flags_t flags)
+{
+ uint32_t index;
+ uint32_t err_code = (NRF_ERROR_NO_MEM | IOT_PBUFFER_ERR_BASE);
+
+
+ for (index = 0; index < IOT_PBUFFER_MAX_COUNT; index ++)
+ {
+ if (m_pbuffer[index].allocated_length == 0)
+ {
+ // Found a free buffer, allocate.
+ PBUFFER_TRC("Found free buffer. Requesting memory allocation.");
+
+ m_pbuffer[index].allocated_length = length;
+
+ if (flags == PBUFFER_FLAG_DEFAULT)
+ {
+ err_code = nrf_mem_reserve(&m_pbuffer[index].buffer.p_memory, &m_pbuffer[index].allocated_length);
+ if (err_code == NRF_SUCCESS)
+ {
+ PBUFFER_TRC("Allocated pbuffer at index 0x%08lX", index);
+ (*pp_buffer) = &m_pbuffer[index];
+ }
+ else
+ {
+ PBUFFER_ERR("Failed to allocate memory for packet buffer of size %ld", length);
+ m_pbuffer[index].allocated_length = 0;
+ }
+ }
+ else
+ {
+ PBUFFER_TRC("Allocated pbuffer at index 0x%08lX without any memory allocation.", index);
+ (*pp_buffer) = &m_pbuffer[index];
+ err_code = NRF_SUCCESS;
+ }
+ break;
+ }
+ }
+
+ return err_code;
+}
+
+
+/**@brief Finds the internal buffer based on the external iot_pbuffer_t. */
+static uint32_t pbuffer_find(pbuffer_t ** p_internal_buffer, iot_pbuffer_t * p_buffer)
+{
+ const uint32_t size = sizeof (pbuffer_t);
+ const uint32_t diff = (((uint32_t)p_buffer) - ((uint32_t)m_pbuffer));
+
+ if ((diff > (size * IOT_PBUFFER_MAX_COUNT)) ||
+ ((diff % size) != 0))
+ {
+ return (NRF_ERROR_INVALID_ADDR | IOT_PBUFFER_ERR_BASE);
+ }
+
+ (*p_internal_buffer) = (pbuffer_t *) p_buffer;
+
+ return NRF_SUCCESS;
+}
+
+
+uint32_t iot_pbuffer_init(void)
+{
+ uint32_t index;
+
+ PBUFFER_ENTRY();
+
+ SDK_MUTEX_INIT(m_pbuffer_mutex);
+
+ PBUFFER_MUTEX_LOCK();
+
+ for (index = 0; index < IOT_PBUFFER_MAX_COUNT; index++)
+ {
+ pbuffer_init(&m_pbuffer[index]);
+ }
+
+ m_initialization_state = true;
+
+ PBUFFER_EXIT();
+
+ PBUFFER_MUTEX_UNLOCK();
+
+ return NRF_SUCCESS;
+}
+
+
+uint32_t iot_pbuffer_allocate(iot_pbuffer_alloc_param_t * p_param,
+ iot_pbuffer_t ** pp_pbuffer)
+{
+ VERIFY_MODULE_IS_INITIALIZED();
+ NULL_PARAM_CHECK(p_param);
+ NULL_PARAM_CHECK(pp_pbuffer);
+ VERIFY_PBUFFER_TYPE(p_param->type);
+ VERIFY_PBUFFER_FLAGS(p_param->flags);
+ VERIFY_NON_ZERO_LENGTH(p_param->length);
+
+ PBUFFER_ENTRY();
+
+ PBUFFER_MUTEX_LOCK();
+
+ uint32_t err_code;
+ uint32_t offset;
+ pbuffer_t * p_alloc_buffer;
+
+ // Get offset to be added to length.
+ offset = type_offset_get(p_param->type);
+
+ err_code = pbuffer_allocate(&p_alloc_buffer, ((p_param->length) + offset), p_param->flags);
+ if (err_code == NRF_SUCCESS)
+ {
+ p_alloc_buffer->buffer.length = p_param->length;
+ p_alloc_buffer->buffer.type = p_param->type;
+
+ if (p_param->flags != PBUFFER_FLAG_NO_MEM_ALLOCATION)
+ {
+ p_alloc_buffer->buffer.p_payload = ((p_alloc_buffer->buffer.p_memory) + offset);
+ }
+
+ (*pp_pbuffer) = &p_alloc_buffer->buffer;
+ }
+
+ PBUFFER_MUTEX_UNLOCK();
+
+ PBUFFER_EXIT();
+
+ return err_code;
+}
+
+
+uint32_t iot_pbuffer_reallocate(iot_pbuffer_alloc_param_t * p_param,
+ iot_pbuffer_t * p_pbuffer)
+{
+ VERIFY_MODULE_IS_INITIALIZED();
+ NULL_PARAM_CHECK(p_param);
+ NULL_PARAM_CHECK(p_pbuffer);
+ VERIFY_PBUFFER_TYPE(p_param->type);
+ VERIFY_PBUFFER_FLAGS(p_param->flags);
+ VERIFY_NON_ZERO_LENGTH(p_param->length);
+
+ PBUFFER_ENTRY();
+
+ PBUFFER_MUTEX_LOCK();
+
+ uint32_t err_code;
+ uint32_t realloc_len;
+ pbuffer_t * p_alloc_buffer;
+
+ // Ensure pointer provided is in the ranged managed by the module.
+ err_code = pbuffer_find(&p_alloc_buffer, p_pbuffer);
+
+ if (err_code == NRF_SUCCESS)
+ {
+ // Get realloc_len to be added to length.
+ const uint32_t offset = type_offset_get(p_param->type);
+ realloc_len = p_param->length + offset;
+
+ // Check if requested length cannot be accommodated in the allocated buffer.
+ if (realloc_len > p_alloc_buffer->allocated_length)
+ {
+ // No, it cannot be, request a new buffer.
+ uint8_t * p_new_mem;
+
+ if (p_param->flags != PBUFFER_FLAG_NO_MEM_ALLOCATION)
+ {
+ err_code = nrf_mem_reserve(&p_new_mem, &realloc_len);
+ if (err_code == NRF_SUCCESS)
+ {
+ // Copy data into the new buffer.
+ memcpy (p_new_mem,
+ p_pbuffer->p_memory,
+ p_alloc_buffer->allocated_length);
+
+ // Now free the old buffer. Perform the free
+ nrf_free(p_alloc_buffer->buffer.p_memory);
+
+ p_alloc_buffer->allocated_length = realloc_len;
+ p_alloc_buffer->buffer.p_memory = p_new_mem;
+ p_alloc_buffer->buffer.length = p_param->length;
+ }
+ }
+ }
+
+ if (err_code == NRF_SUCCESS)
+ {
+ p_alloc_buffer->buffer.length = p_param->length;
+ p_alloc_buffer->buffer.type = p_param->type;
+
+ if (p_param->flags == PBUFFER_FLAG_DEFAULT)
+ {
+ p_alloc_buffer->buffer.p_payload = (p_alloc_buffer->buffer.p_memory + offset);
+ }
+ }
+ }
+ else
+ {
+ PBUFFER_ERR("Cannot find buffer to be freed.");
+ }
+
+ PBUFFER_MUTEX_UNLOCK();
+
+ PBUFFER_EXIT();
+
+ return err_code;
+}
+
+
+uint32_t iot_pbuffer_free(iot_pbuffer_t * p_pbuffer, bool free_flag)
+{
+ VERIFY_MODULE_IS_INITIALIZED();
+ NULL_PARAM_CHECK(p_pbuffer);
+
+ PBUFFER_ENTRY();
+
+ PBUFFER_MUTEX_LOCK();
+
+ uint32_t err_code;
+ pbuffer_t * p_alloc_buffer;
+
+ // Ensure pointer provided is in the ranged managed by the module.
+ err_code = pbuffer_find(&p_alloc_buffer, p_pbuffer);
+ if (err_code == NRF_SUCCESS)
+ {
+ if (free_flag == true)
+ {
+ nrf_free(p_alloc_buffer->buffer.p_memory);
+ }
+ pbuffer_init(p_alloc_buffer);
+ }
+ else
+ {
+ PBUFFER_ERR("Cannot find buffer to be freed.");
+ }
+
+ PBUFFER_MUTEX_UNLOCK();
+
+ PBUFFER_EXIT();
+
+ return err_code;
+}
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/ipv6_stack/pbuffer/iot_pbuffer.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/ipv6_stack/pbuffer/iot_pbuffer.h
new file mode 100644
index 0000000..e13da3a
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/ipv6_stack/pbuffer/iot_pbuffer.h
@@ -0,0 +1,175 @@
+/**
+ * Copyright (c) 2014 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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
+ *
+ * @defgroup iot_pbuffer Packet Buffer
+ * @{
+ * @ingroup iot_sdk_stack
+ * @brief Packet buffer management for IPv6 stack layers to minimize data copy across stack layers.
+ *
+ * @details This module interfaces with the Memory Manager to allocate packet buffers
+ * for the IPv6 stack layers, without each layer having to ensure
+ * sufficient header space for layers below.
+ */
+#ifndef IOT_PBUFFER__
+#define IOT_PBUFFER__
+
+#include <stdint.h>
+#include <stdbool.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**@brief IPv6 packet type identifiers that are needed to ensure that enough
+ * space is reserved for headers from layers below during memory allocation.
+ */
+typedef enum
+{
+ UNASSIGNED_TYPE = 0, /**< Indicates that the packet buffer is unassigned and not in use. */
+ RAW_PACKET_TYPE = 1, /**< Raw packet, with no room made for headers of any lower layer. */
+ IPV6_PACKET_TYPE = 2, /**< Indicates that the packet buffer is requested for an entire IPv6 packet; pbuffer provisions 40 bytes of IPv6 header. */
+ ICMP6_PACKET_TYPE = 3, /**< Indicates that the packet buffer is requested for an ICMPv6 packet, and provision for 40 bytes of IPv6 header is made by pbuffer. */
+ UDP6_PACKET_TYPE = 4, /**< Indicates that the packet buffer is requested for a UDP packet, and provision for 40 bytes of IPv6 header and UDP header is made by pbuffer. */
+ COAP_PACKET_TYPE = 5 /**< Indicates that the packet buffer is requested for a CoAP packet, and provision for 4 bytes of CoAP header, 8 bytes of UDP header, and 40 bytes of IPv6 header is made. */
+}iot_pbuffer_type_t;
+
+/**@brief Additional information that must be provided to the module during allocation
+ * or reallocation to ensure optimal utilization of memory and avoid unnecessary data
+ * copies.
+ */
+typedef enum
+{
+ PBUFFER_FLAG_DEFAULT = 0, /**< Default behavior with respect to memory allocation when allocating packet buffer. Memory will be allocated for the length indicated by this default.*/
+ PBUFFER_FLAG_NO_MEM_ALLOCATION = 1, /**< Only allocate packet buffer, not memory. This is needed when a packet already exists and the packet buffer is needed only to feed it to the IPv6 stack.*/
+}iot_pbuffer_flags_t;
+
+/**@brief Packet buffer used for exchanging IPv6 payload across layers in both receive and transmit
+ * paths.
+ */
+typedef struct
+{
+ iot_pbuffer_type_t type; /**< Determines if any offset for lower layers must be provisioned for in the stack. */
+ uint8_t * p_memory; /**< Pointer to actual memory allocated for the buffer. */
+ uint8_t * p_payload; /**< Pointer to memory where the payload for the layer that allocates the packet buffer should be contained. */
+ uint32_t length; /**< Length of the payload of the layer processing it. This value can be modified by each layer of the IPv6 stack based on the required header information added by each.*/
+}iot_pbuffer_t;
+
+
+/**@brief Parameters required to allocate the packet buffer. */
+typedef struct
+{
+ iot_pbuffer_type_t type; /**< Payload type for which the packet buffer is requested to be allocated or reallocated. */
+ iot_pbuffer_flags_t flags; /**< Flags that indicate if memory allocation is needed or not. */
+ uint32_t length; /**< Length of payload for which the packet buffer is requested. */
+}iot_pbuffer_alloc_param_t;
+
+
+/**@brief Function for initializing the module.
+ *
+ * @retval NRF_SUCCESS If the module was successfully initialized. Otherwise, an error code that indicates the reason for the failure is returned.
+ */
+uint32_t iot_pbuffer_init(void);
+
+
+/**@brief Function for allocating a packet buffer.
+ *
+ * @param[in] p_param Pointer to allocation parameters that indicate the length of the payload requested,
+ * the type of payload, and additional information using the flags. This
+ * parameter cannot be NULL.
+ * @param[out] pp_pbuffer Pointer to allocated packet buffer. This parameter shall
+ * not be NULL.
+ *
+ * @retval NRF_SUCCESS If the packet buffer was successfully allocated. Otherwise, an error code that indicates the reason for the failure is returned.
+ */
+uint32_t iot_pbuffer_allocate(iot_pbuffer_alloc_param_t * p_param,
+ iot_pbuffer_t ** pp_pbuffer);
+
+
+/**@brief Function for reallocating a packet buffer.
+ *
+ * Reallocation requests are treated as follows:
+ * - If the requested reallocation is less than or equal to the allocated size,
+ * no data is moved, and the function returns NRF_SUCCESS.
+ * - If the requested reallocation is more than what is allocated, the function
+ * requests new memory, backs up existing data, and then frees the previously
+ * allocated memory.
+ * - If reallocation is requested with the PBUFFER_FLAG_NO_MEM_ALLOCATION flag,
+ * the function does not free previously allocated memory or copy it to the
+ * new location. In this case, the application that uses the pbuffer must
+ * decide when to move previously allocated memory and when to free it and
+ * handle this.
+ *
+ * @param[in] p_param Pointer to reallocation parameters that indicate the length of the payload requested,
+ * the type of payload, and additional information using the flags. This
+ * parameter cannot be NULL.
+ * @param[in] p_pbuffer Pointer to the packet buffer being reallocated. This parameter shall
+ * not be NULL.
+ *
+ * @retval NRF_SUCCESS If the packet buffer was successfully reallocated. Otherwise, an error code that indicates the reason for the failure is returned.
+ */
+uint32_t iot_pbuffer_reallocate(iot_pbuffer_alloc_param_t * p_param,
+ iot_pbuffer_t * p_pbuffer);
+
+
+/**@brief Function for freeing a packet buffer.
+ *
+ * This function frees the packet buffer. If the parameter free_flag is set, the
+ * function tries to free the memory allocated as well. This action is performed
+ * irrespective of whether the memory was allocated using the PBUFFER_FLAG_DEFAULT or
+ * the PBUFFER_FLAG_NO_MEM_ALLOCATION flag.
+ *
+ * @param[in] p_pbuffer Pointer to the packet buffer requested to be freed. This parameter shall
+ * not be NULL.
+ * @param[in] free_flag Indicates if the allocated memory should be freed or not when freeing the
+ * packet buffer.
+ *
+ * @retval NRF_SUCCESS If the packet buffer was successfully freed. Otherwise, an error code that indicates the reason for the failure is returned.
+ *
+ */
+uint32_t iot_pbuffer_free(iot_pbuffer_t * p_pbuffer, bool free_flag);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // IOT_PBUFFER__
+
+/**@} */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/ipv6_stack/sntp_client/sntp_client.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/ipv6_stack/sntp_client/sntp_client.c
new file mode 100644
index 0000000..2b79462
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/ipv6_stack/sntp_client/sntp_client.c
@@ -0,0 +1,607 @@
+/**
+ * Copyright (c) 2015 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#include "udp_api.h"
+#include "ipv6_api.h"
+#include "app_error.h"
+#include "sdk_common.h"
+#include "sntp_client.h"
+
+#if SNTP_CLIENT_CONFIG_LOG_ENABLED
+
+#define NRF_LOG_MODULE_NAME sntp
+
+#define NRF_LOG_LEVEL SNTP_CLIENT_CONFIG_LOG_LEVEL
+#define NRF_LOG_INFO_COLOR SNTP_CLIENT_CONFIG_INFO_COLOR
+#define NRF_LOG_DEBUG_COLOR SNTP_CLIENT_CONFIG_DEBUG_COLOR
+
+#include "nrf_log.h"
+NRF_LOG_MODULE_REGISTER();
+
+#define SNTP_TRC NRF_LOG_DEBUG /**< Used for getting trace of execution in the module. */
+#define SNTP_ERR NRF_LOG_ERROR /**< Used for logging errors in the module. */
+#define SNTP_DUMP NRF_LOG_HEXDUMP_DEBUG /**< Used for dumping octet information to get details of bond information etc. */
+
+#define SNTP_ENTRY() SNTP_TRC(">> %s", __func__)
+#define SNTP_EXIT() SNTP_TRC("<< %s", __func__)
+
+#else // SNTP_CLIENT_CONFIG_LOG_ENABLED
+
+#define SNTP_TRC(...) /**< Disables traces. */
+#define SNTP_DUMP(...) /**< Disables dumping of octet streams. */
+#define SNTP_ERR(...) /**< Disables error logs. */
+
+#define SNTP_ENTRY(...)
+#define SNTP_EXIT(...)
+
+#endif // SNTP_CLIENT_CONFIG_LOG_ENABLED
+
+/**
+ * @defgroup api_param_check API Parameters check macros.
+ *
+ * @details Macros that verify parameters passed to the module in the APIs. These macros
+ * could be mapped to nothing in final versions of code to save execution and size.
+ * SNTP_CLIENT_DISABLE_API_PARAM_CHECK should be defined to disable these checks.
+ *
+ * @{
+ */
+#if (SNTP_CLIENT_DISABLE_API_PARAM_CHECK == 0)
+
+/**
+ * @brief Verify NULL parameters are not passed to an API by application.
+ */
+#define NULL_PARAM_CHECK(PARAM) \
+ if ((PARAM) == NULL) \
+ { \
+ return (NRF_ERROR_NULL | IOT_NTP_ERR_BASE); \
+ }
+
+/**
+ * @brief Verify that not zero is passed to an API by application.
+ */
+#define ZERO_PARAM_CHECK(PARAM) \
+ if ((PARAM) == 0x00) \
+ { \
+ return (NRF_ERROR_NULL | IOT_NTP_ERR_BASE); \
+ }
+
+/**
+ * @brief Macro to check if module is initialized.
+ */
+#define VERIFY_MODULE_IS_INITIALIZED() \
+ if (m_sntp_client_state == SNTP_CLIENT_STATE_UNINITIALIZED) \
+ { \
+ return (SDK_ERR_MODULE_NOT_INITIALIZED | IOT_NTP_ERR_BASE); \
+ }
+
+#else // SNTP_CLIENT_DISABLE_API_PARAM_CHECK
+
+#define NULL_PARAM_CHECK(PARAM)
+#define ZERO_PARAM_CHECK(PARAM)
+#define VERIFY_MODULE_IS_INITIALIZED()
+
+#endif //SNTP_CLIENT_DISABLE_API_PARAM_CHECK
+/** @} */
+
+/**
+ * @defgroup ble_sntp_c_mutex_lock_unlock Module's Mutex Lock/Unlock Macros.
+ *
+ * @details Macros used to lock and unlock modules. Currently, SDK does not use mutexes but
+ * framework is provided in case need arises to use an alternative architecture.
+ * @{
+ */
+#define SNTP_C_MUTEX_LOCK() SDK_MUTEX_LOCK(m_sntp_c_mutex) /**< Lock module using mutex */
+#define SNTP_C_MUTEX_UNLOCK() SDK_MUTEX_UNLOCK(m_sntp_c_mutex) /**< Unlock module using mutex */
+/** @} */
+
+#define TIME_AT_1970 2208988800UL // Number of seconds between 1st Jan 1900 and 1st Jan 1970, for NTP<->Unix time conversion.
+#define PROTOCOL_MODE_SERVER 4
+
+/**@brief NTP Header Format. */
+typedef struct
+{
+ uint8_t flags; /**< Please see RFC 4330. */
+ uint8_t stratum; /**< Please see RFC 4330. This field is significant only in SNTP server messages. */
+ uint8_t poll_interval; /**< Please see RFC 4330. This field is significant only in SNTP server messages. */
+ uint8_t precision; /**< Please see RFC 4330. This field is significant only in SNTP server messages. */
+ uint32_t root_delay; /**< Please see RFC 4330. This field is significant only in SNTP server messages. */
+ uint32_t root_dispersion; /**< Please see RFC 4330. This field is significant only in SNTP server messages. */
+ uint32_t reference_id; /**< Please see RFC 4330. This field is significant only in SNTP server messages. */
+ uint32_t reference_timestamp[2]; /**< Please see RFC 4330. This field is significant only in SNTP server messages. */
+ uint32_t originate_timestamp[2]; /**< Please see RFC 4330. This field is significant only in SNTP server messages. */
+ uint32_t receive_timestamp[2]; /**< Please see RFC 4330. This field is significant only in SNTP server messages. */
+ uint32_t transmit_timestamp[2]; /**< Please see RFC 4330. */
+} ntp_header_t;
+
+typedef enum
+{
+ SNTP_CLIENT_STATE_UNINITIALIZED = 1,
+ SNTP_CLIENT_STATE_IDLE,
+ SNTP_CLIENT_STATE_BUSY
+} sntp_client_state_t;
+
+typedef struct
+{
+ time_t unix_time;
+ iot_timer_time_in_ms_t wall_clock_value;
+} local_timestamp_t;
+
+SDK_MUTEX_DEFINE(m_sntp_c_mutex) /**< Mutex variable. Currently unused, this declaration does not occupy any space in RAM. */
+static sntp_client_state_t m_sntp_client_state = SNTP_CLIENT_STATE_UNINITIALIZED;
+static ipv6_addr_t * m_p_ntp_server_address;
+static uint16_t m_ntp_server_port;
+static bool m_do_sync_local_time;
+static iot_timer_time_in_ms_t m_time_of_last_transmission;
+static uint8_t m_retransmission_count;
+static sntp_evt_handler_t m_app_evt_handler;
+static udp6_socket_t m_udp_socket;
+static local_timestamp_t m_local_time;
+
+/**@brief Function for checking if a received NTP packet is valid.
+ *
+ * @param[in] p_ntp_response Pointer to the NTP packet header.
+ *
+ */
+static bool is_response_valid(ntp_header_t * p_ntp_response)
+{
+ if (((p_ntp_response->transmit_timestamp[0] == 0x00) && \
+ (p_ntp_response->transmit_timestamp[1] == 0x00)) || \
+ ((p_ntp_response->flags & 0x38) == 0x00) || \
+ ((p_ntp_response->flags & 0x07) != PROTOCOL_MODE_SERVER))
+ {
+ return false;
+ }
+
+ return true;
+}
+
+
+/**@brief Callback handler to receive data on the UDP port.
+ *
+ * @param[in] p_socket Socket identifier.
+ * @param[in] p_ip_header IPv6 header containing source and destination addresses.
+ * @param[in] p_udp_header UDP header identifying local and remote endpoints.
+ * @param[in] process_result Result of data reception, there could be possible errors like
+ * invalid checksum etc.
+ * @param[in] p_rx_packet Packet buffer containing the received data packet.
+ *
+ * @retval NRF_SUCCESS Indicates received data was handled successfully, else an an
+ * error code indicating reason for failure..
+ */
+static uint32_t port_data_callback(const udp6_socket_t * p_socket,
+ const ipv6_header_t * p_ip_header,
+ const udp6_header_t * p_udp_header,
+ uint32_t process_result,
+ iot_pbuffer_t * p_rx_packet)
+{
+ SNTP_C_MUTEX_LOCK();
+
+ SNTP_ENTRY();
+
+ uint32_t err_code = NRF_SUCCESS;
+ ntp_header_t * p_ntp_header = (ntp_header_t *)p_rx_packet->p_payload;
+
+ if (m_sntp_client_state != SNTP_CLIENT_STATE_BUSY)
+ {
+ SNTP_ERR("Unexpected NTP response received.");
+
+ SNTP_C_MUTEX_UNLOCK();
+
+ SNTP_EXIT();
+ return (NRF_ERROR_INVALID_STATE | IOT_NTP_ERR_BASE);
+ }
+ else
+ {
+ // Check UDP process result and data length.
+ if ((process_result != NRF_SUCCESS) || p_rx_packet->length < sizeof(ntp_header_t))
+ {
+ SNTP_ERR("Received erroneous NTP response.");
+
+ m_sntp_client_state = SNTP_CLIENT_STATE_IDLE;
+ m_retransmission_count = 0;
+ m_do_sync_local_time = false;
+ err_code = (NRF_ERROR_INVALID_DATA | IOT_NTP_ERR_BASE);
+
+ SNTP_C_MUTEX_UNLOCK();
+
+ if (m_app_evt_handler != NULL)
+ {
+ m_app_evt_handler(&(p_ip_header->srcaddr), p_udp_header->srcport, err_code, \
+ (sntp_client_cb_param_t){ .callback_data = 0x00 });
+ }
+
+ SNTP_EXIT();
+ return err_code;
+ }
+ else
+ {
+ if (!is_response_valid(p_ntp_header))
+ {
+ SNTP_ERR("Received bad NTP response.");
+
+ m_sntp_client_state = SNTP_CLIENT_STATE_IDLE;
+ m_retransmission_count = 0;
+ m_do_sync_local_time = false;
+ err_code = NTP_SERVER_BAD_RESPONSE;
+
+ SNTP_C_MUTEX_UNLOCK();
+
+ if (m_app_evt_handler != NULL)
+ {
+ m_app_evt_handler(&(p_ip_header->srcaddr), \
+ p_udp_header->srcport, \
+ err_code, \
+ (sntp_client_cb_param_t){ .callback_data = 0x00 });
+ }
+
+ SNTP_EXIT();
+ return err_code;
+ }
+ else
+ {
+ // Check if Kiss-o'-Death packet.
+ if (p_ntp_header->stratum == 0x00)
+ {
+ SNTP_TRC("Received Kiss-o'-Death packet.");
+
+ m_sntp_client_state = SNTP_CLIENT_STATE_IDLE;
+ m_retransmission_count = 0;
+ m_do_sync_local_time = false;
+
+ SNTP_C_MUTEX_UNLOCK();
+
+ if (m_app_evt_handler != NULL)
+ {
+ m_app_evt_handler(&(p_ip_header->srcaddr), p_udp_header->srcport, \
+ NTP_SERVER_KOD_PACKET_RECEIVED, \
+ (sntp_client_cb_param_t){ .callback_data \
+ = p_ntp_header->reference_id });
+ }
+
+ SNTP_EXIT();
+ return NRF_SUCCESS;
+ }
+ else
+ {
+ // Process decent NTP response.
+ time_t time_from_response = (HTONL(p_ntp_header->transmit_timestamp[0])) - \
+ TIME_AT_1970;
+
+ if (m_do_sync_local_time)
+ {
+ iot_timer_time_in_ms_t wall_clock_value;
+ UNUSED_VARIABLE(iot_timer_wall_clock_get(&wall_clock_value));
+ m_local_time.unix_time = time_from_response;
+ m_local_time.wall_clock_value = wall_clock_value;
+ m_do_sync_local_time = false;
+ }
+
+ m_sntp_client_state = SNTP_CLIENT_STATE_IDLE;
+ m_retransmission_count = 0;
+
+ SNTP_C_MUTEX_UNLOCK();
+
+ if (m_app_evt_handler != NULL)
+ {
+ m_app_evt_handler(&(p_ip_header->srcaddr), \
+ p_udp_header->srcport, \
+ NRF_SUCCESS, \
+ (sntp_client_cb_param_t){ .time_from_server = \
+ time_from_response });
+ }
+
+ SNTP_EXIT();
+ return NRF_SUCCESS;
+ }
+ }
+ }
+ }
+}
+
+
+uint32_t sntp_client_init(const sntp_client_init_param_t * p_sntp_client_init_param)
+{
+ NULL_PARAM_CHECK(p_sntp_client_init_param);
+ ZERO_PARAM_CHECK(p_sntp_client_init_param->local_udp_port);
+
+ SNTP_ENTRY();
+
+ SDK_MUTEX_INIT(m_sntp_c_mutex);
+ SNTP_C_MUTEX_LOCK();
+
+ uint32_t err_code;
+
+ memset(&m_local_time, 0x00, sizeof(m_local_time));
+ m_app_evt_handler = p_sntp_client_init_param->app_evt_handler;
+
+ //Request new socket creation.
+ err_code = udp6_socket_allocate(&m_udp_socket);
+
+ if (err_code == NRF_SUCCESS)
+ {
+ // Bind the socket to the local port.
+ err_code = udp6_socket_bind(&m_udp_socket, \
+ IPV6_ADDR_ANY, \
+ p_sntp_client_init_param->local_udp_port);
+ if (err_code == NRF_SUCCESS)
+ {
+ //Register data receive callback.
+ err_code = udp6_socket_recv(&m_udp_socket, port_data_callback);
+ }
+ if (err_code != NRF_SUCCESS)
+ {
+ //Not all procedures succeeded with allocated socket, hence free it.
+ UNUSED_VARIABLE(udp6_socket_free(&m_udp_socket));
+ }
+ }
+
+ if (err_code == NRF_SUCCESS)
+ {
+ m_sntp_client_state = SNTP_CLIENT_STATE_IDLE;
+ }
+
+ SNTP_EXIT();
+
+ SNTP_C_MUTEX_UNLOCK();
+
+ return err_code;
+}
+
+
+static uint32_t local_time_get(time_t * p_local_time)
+{
+ uint32_t err_code = NRF_SUCCESS;
+ iot_timer_time_in_ms_t delta_ms;
+ err_code = iot_timer_wall_clock_delta_get(&m_local_time.wall_clock_value, &delta_ms);
+ if (err_code != NRF_SUCCESS)
+ {
+ return err_code;
+ }
+
+ *p_local_time = m_local_time.unix_time + (delta_ms / 1000);
+
+ return err_code;
+}
+
+
+uint32_t sntp_client_local_time_get(time_t * p_current_time)
+{
+ VERIFY_MODULE_IS_INITIALIZED();
+ NULL_PARAM_CHECK(p_current_time);
+
+ uint32_t err_code = NRF_SUCCESS;
+
+ SNTP_ENTRY();
+
+ SNTP_C_MUTEX_LOCK();
+
+ err_code = local_time_get(p_current_time);
+
+ SNTP_EXIT();
+
+ SNTP_C_MUTEX_UNLOCK();
+
+ return err_code;
+}
+
+
+/**@brief Function for sending SNTP query.
+ *
+ * @retval NRF_SUCCESS on successful execution of procedure, otherwise an error code indicating reason
+ * for failure.
+ */
+static uint32_t sntp_query_send()
+{
+ uint32_t err_code;
+ iot_pbuffer_t * p_buffer;
+ iot_pbuffer_alloc_param_t buffer_param;
+ time_t current_local_time;
+
+ err_code = local_time_get(&current_local_time);
+ if (err_code != NRF_SUCCESS)
+ {
+ SNTP_ERR("An error occurred while getting local time value!");
+ return err_code;
+ }
+
+ buffer_param.type = UDP6_PACKET_TYPE;
+ buffer_param.flags = PBUFFER_FLAG_DEFAULT;
+ buffer_param.length = sizeof(ntp_header_t);
+
+ UNUSED_VARIABLE(iot_timer_wall_clock_get(&m_time_of_last_transmission));
+
+ // Allocate packet buffer.
+ err_code = iot_pbuffer_allocate(&buffer_param, &p_buffer);
+
+ if (err_code == NRF_SUCCESS)
+ {
+ ntp_header_t * p_ntp_header = (ntp_header_t *)p_buffer->p_payload;
+ memset(p_ntp_header, 0x00, sizeof(ntp_header_t));
+
+ // Fill NTP header fields.
+ p_ntp_header->flags = 0x1B; // LI = 0; VN = 3; Mode = 3
+ p_ntp_header->transmit_timestamp[0] = HTONL((uint32_t)(current_local_time + TIME_AT_1970));
+
+ // Send NTP query using UDP socket.
+ err_code = udp6_socket_sendto(&m_udp_socket, \
+ m_p_ntp_server_address, \
+ m_ntp_server_port, \
+ p_buffer);
+ if (err_code != NRF_SUCCESS)
+ {
+ SNTP_ERR("Unable to send query on UDP socket. Reason %08lx.", err_code);
+
+ // Free the allocated buffer as send procedure has failed.
+ UNUSED_VARIABLE(iot_pbuffer_free(p_buffer, true));
+ }
+ }
+ else
+ {
+ SNTP_ERR("No memory to allocate packet buffer.");
+ }
+
+ return err_code;
+}
+
+
+uint32_t sntp_client_server_query(ipv6_addr_t * p_ntp_server_address, \
+ uint16_t ntp_server_udp_port, \
+ bool sync_local_time)
+{
+ VERIFY_MODULE_IS_INITIALIZED();
+ NULL_PARAM_CHECK(p_ntp_server_address);
+ ZERO_PARAM_CHECK(ntp_server_udp_port);
+
+ uint32_t err_code = NRF_SUCCESS;
+ SNTP_ENTRY();
+
+ SNTP_C_MUTEX_LOCK();
+
+ if (m_sntp_client_state != SNTP_CLIENT_STATE_IDLE)
+ {
+ SNTP_EXIT();
+ return (NRF_ERROR_BUSY | IOT_NTP_ERR_BASE);
+ }
+
+ m_p_ntp_server_address = p_ntp_server_address;
+ m_ntp_server_port = ntp_server_udp_port;
+ m_do_sync_local_time = sync_local_time;
+
+ err_code = sntp_query_send();
+ if (err_code == NRF_SUCCESS)
+ {
+ m_sntp_client_state = SNTP_CLIENT_STATE_BUSY;
+ }
+
+ SNTP_EXIT();
+
+ SNTP_C_MUTEX_UNLOCK();
+
+ return err_code;
+}
+
+
+/**@brief Function for determining whether it is time to retransmit a query.
+ *
+ */
+static bool is_it_time_to_retransmit()
+{
+ uint32_t err_code = NRF_SUCCESS;
+ iot_timer_time_in_ms_t delta_ms = 0;
+
+ err_code = iot_timer_wall_clock_delta_get(&m_time_of_last_transmission, &delta_ms);
+ if (err_code != NRF_SUCCESS)
+ {
+ return true;
+ }
+ if (delta_ms >= (SNTP_RETRANSMISSION_INTERVAL * 1000))
+ {
+ return true;
+ }
+ else
+ {
+ return false;
+ }
+}
+
+
+void sntp_client_timeout_process(iot_timer_time_in_ms_t wall_clock_value)
+{
+ SNTP_C_MUTEX_LOCK();
+
+ UNUSED_PARAMETER(wall_clock_value);
+
+ if (m_sntp_client_state == SNTP_CLIENT_STATE_BUSY)
+ {
+ if (is_it_time_to_retransmit())
+ {
+ m_retransmission_count++;
+ if (m_retransmission_count > SNTP_MAX_RETRANSMISSION_COUNT)
+ {
+ m_sntp_client_state = SNTP_CLIENT_STATE_IDLE;
+ m_retransmission_count = 0;
+ m_do_sync_local_time = false;
+
+ SNTP_C_MUTEX_UNLOCK();
+
+ if (m_app_evt_handler != NULL)
+ {
+ m_app_evt_handler(m_p_ntp_server_address, \
+ m_ntp_server_port, \
+ NTP_SERVER_UNREACHABLE, \
+ (sntp_client_cb_param_t){ .callback_data = 0x00 });
+ }
+
+ SNTP_TRC("NTP server did not respond to query.");
+ return;
+ }
+ else
+ {
+ SNTP_TRC("Query retransmission [%d].", m_retransmission_count);
+ UNUSED_VARIABLE(sntp_query_send());
+ }
+ }
+ }
+
+ SNTP_C_MUTEX_UNLOCK();
+ return;
+}
+
+
+uint32_t sntp_client_uninitialize()
+{
+ VERIFY_MODULE_IS_INITIALIZED();
+
+ SNTP_ENTRY();
+
+ SNTP_C_MUTEX_LOCK();
+
+ // Free UDP socket.
+ UNUSED_VARIABLE(udp6_socket_free(&m_udp_socket));
+
+ m_sntp_client_state = SNTP_CLIENT_STATE_UNINITIALIZED;
+ m_retransmission_count = 0;
+ m_do_sync_local_time = false;
+
+ SNTP_EXIT();
+
+ SNTP_C_MUTEX_UNLOCK();
+
+ return NRF_SUCCESS;
+}
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/ipv6_stack/sntp_client/sntp_client.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/ipv6_stack/sntp_client/sntp_client.h
new file mode 100644
index 0000000..d9cb7eb
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/ipv6_stack/sntp_client/sntp_client.h
@@ -0,0 +1,202 @@
+/**
+ * Copyright (c) 2015 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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
+ *
+ * @defgroup sntp_client SNTP Client
+ * @{
+ * @ingroup iot_sdk_stack
+ * @brief Simple Network Time Protocol (SNTP) client for obtaining and storing local unix time.
+ *
+ * @details Concurrent queries are not supported. Exponential-backoff algorithm for
+ * retransmissions is not implemented, retransmissions are triggered at regular intervals.
+ *
+ */
+
+#ifndef SNTP_CLIENT_H__
+#define SNTP_CLIENT_H__
+
+#include <stdint.h>
+/*lint -save -e43 -e1504 */
+#include <time.h>
+/*lint -restore */
+#include "sdk_config.h"
+#include "nrf_error.h"
+#include "ipv6_api.h"
+#include "iot_timer.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define KISS_CODE_LEN 4 /**< Kiss-o'-Death packets convey kiss codes as 4 character long @c ASCII messages. */
+
+/**@brief SNTP client callback parameter.
+ */
+typedef union
+{
+ time_t time_from_server; /**< Unix time if a proper proper response is received from an NTP server. */
+ uint32_t callback_data; /**< Data pertaining to the event triggering the callback. The kiss code from any Kiss-o'-Death packets. */
+} sntp_client_cb_param_t;
+
+/**@brief SNTP client callback type.
+ *
+ * @details Execution of the callback function marks the completion of an SNTP query.
+ * The callback will be executed if a response is received from the NTP server,
+ * or if the server remains unresponsive even after @ref SNTP_MAX_RETRANSMISSION_COUNT
+ * is reached.
+ *
+ * @param[in] p_ntp_srv_addr Pointer to the source IPv6 address of the NTP response, or to
+ * the IPv6 address of the NTP server targeted by the unsuccessful
+ * query.
+ * @param[in] ntp_srv_udp_port The source UDP port of the NTP response, or the UDP port of
+ * the NTP server targeted by the unsuccessful query.
+ * @param[in] process_result The value of this parameter reveals whether a response from the
+ * NTP server or a timeout triggered the callback.
+ * @param[in] callback_parameter This parameter holds the unix time from the server after a
+ * successful query, or the kiss code if a Kiss-o'-Death packet
+ * was received. Otherwise NULL.
+ *
+ * @retval None.
+ *
+ */
+typedef void (*sntp_evt_handler_t)(const ipv6_addr_t * p_ntp_srv_addr, \
+ uint16_t ntp_srv_udp_port, \
+ uint32_t process_result, \
+ sntp_client_cb_param_t callback_parameter);
+
+/**@brief SNTP client initialization structure.
+ *
+ * @note @ref app_evt_handler can be set to zero to disable callbacks.
+ */
+typedef struct
+{
+ sntp_evt_handler_t app_evt_handler; /**< Pointer to the event handler callback function. Triggered by a response from an NTP server to an SNTP query, or a retransmission timeout after @ref SNTP_MAX_RETRANSMISSION_COUNT is reached. */
+ uint16_t local_udp_port; /**< Local port used by the UDP socket allocated for the SNTP client module. Cannot be NULL. */
+} sntp_client_init_param_t;
+
+/**
+ * @brief Function for initializing the SNTP client module.
+ *
+ * @details The SNTP client uses UDP as transport layer, therefore, one UDP socket is allocated
+ * for the module and is used to transmit any future queries.
+ *
+ * @param[in] p_sntp_client_init_param Pointer to the initialization structure for the SNTP client.
+ * Should not be NULL.
+ *
+ * @note The event handler in the initialization structure can be set to NULL to disable callbacks
+ * from the module.
+ *
+ * @retval NRF_SUCCESS Module successfully initialized.
+ * @retval NRF_ERROR_NULL If @b p_sntp_client_init_param is NULL, or if it points to a local UDP
+ * port that is NULL.
+ *
+ */
+uint32_t sntp_client_init(const sntp_client_init_param_t * p_sntp_client_init_param);
+
+/**
+ * @brief Function for uninitializing the SNTP client module.
+ *
+ * @details This procedure frees up the UDP socket previously allocated to the module.
+ * Any pending retransmissions are cleared and no more callbacks will be executed.
+ *
+ * @retval NRF_SUCCESS Module successfully uninitialized.
+ * @retval SDK_ERR_MODULE_NOT_INITIALIZED The module was not initialized.
+ *
+ */
+uint32_t sntp_client_uninitialize(void);
+
+/**@brief Function for sending an SNTP query to the specified NTP server.
+ *
+ * @details The local unix time is set to zero (1-Jan-70) when the module is initialized. It can
+ * be updated by using the @ref sntp_client_server_query procedure. The accuracy of the
+ * output is depending on the wall clock of the IoT Timer module.
+ *
+ * @param[in] p_ntp_server_address Pointer to the IPv6 address of the NTP server. This memory must
+ * be resident until the query is completed.
+ * @param[in] ntp_server_udp_port Destination port of the NTP server. The UDP port number
+ * assigned by the IANA to NTP is 123.
+ * @param[in] sync_local_time A boolean value telling the module whether to synchronize its
+ * local clock with any response received from the NTP server.
+ *
+ * @retval NRF_SUCCESS SNTP query successfully sent.
+ * @retval SDK_ERR_MODULE_NOT_INITIALIZED The module was not initialized.
+ * @retval NRF_ERROR_NULL If @b p_ntp_server_address or @b ntp_server_udp_port
+ * is a NULL pointer.
+ *
+ */
+uint32_t sntp_client_server_query(ipv6_addr_t * p_ntp_server_address, \
+ uint16_t ntp_server_udp_port, \
+ bool sync_local_time);
+
+/**@brief Function for getting the local unix time from the module.
+ *
+ * @details The local unix time is set to zero (1-Jan-70) when the module is initialized. It can
+ * be updated by using @ref sntp_client_server_query procedure. The accuracy of the
+ * output is depending on the wall clock of the IoT Timer module.
+ *
+ * @param[out] p_current_time Local unix time.
+ *
+ * @retval NRF_SUCCESS Getting locally stored unix time successful.
+ * @retval SDK_ERR_MODULE_NOT_INITIALIZED The module was not initialized.
+ * @retval NRF_ERROR_NULL If @b p_current_time is a NULL pointer.
+ *
+ */
+uint32_t sntp_client_local_time_get(time_t * p_current_time);
+
+/**@brief Function for performing retransmissions of SNTP queries.
+ *
+ * @details The SNTP client module implements the retransmission mechanism by invoking this
+ * function periodically. This procedure is to be added to the IoT Timer client list
+ * and has to be called repeatedly with a minimum period of SNTP_RETRANSMISSION_INTERVAL.
+ *
+ * @param[in] wall_clock_value The value of the wall clock that triggered the callback.
+ *
+ * @retval None.
+ *
+ */
+void sntp_client_timeout_process(iot_timer_time_in_ms_t wall_clock_value);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // SNTP_CLIENT_H__
+
+/**@} */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/ipv6_stack/tftp/iot_tftp.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/ipv6_stack/tftp/iot_tftp.c
new file mode 100644
index 0000000..65f0ec1
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/ipv6_stack/tftp/iot_tftp.c
@@ -0,0 +1,2455 @@
+/**
+ * Copyright (c) 2015 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#include "sdk_config.h"
+#include "iot_tftp.h"
+#include "iot_common.h"
+#include "udp_api.h"
+#include "app_util.h"
+
+#if TFTP_CONFIG_LOG_ENABLED
+
+#define NRF_LOG_MODULE_NAME tftp
+
+#define NRF_LOG_LEVEL TFTP_CONFIG_LOG_LEVEL
+#define NRF_LOG_INFO_COLOR TFTP_CONFIG_INFO_COLOR
+#define NRF_LOG_DEBUG_COLOR TFTP_CONFIG_DEBUG_COLOR
+
+#include "nrf_log.h"
+NRF_LOG_MODULE_REGISTER();
+
+#define TFTP_TRC NRF_LOG_DEBUG /**< Used for getting trace of execution in the module. */
+#define TFTP_ERR NRF_LOG_ERROR /**< Used for logging errors in the module. */
+#define TFTP_DUMP NRF_LOG_HEXDUMP_DEBUG /**< Used for dumping octet information to get details of bond information etc. */
+
+#define TFTP_ENTRY() TFTP_TRC(">> %s", __func__)
+#define TFTP_EXIT() TFTP_TRC("<< %s", __func__)
+
+#else // TFTP_CONFIG_LOG_ENABLED
+
+#define TFTP_TRC(...) /**< Disables traces. */
+#define TFTP_DUMP(...) /**< Disables dumping of octet streams. */
+#define TFTP_ERR(...) /**< Disables error logs. */
+
+#define TFTP_ENTRY(...)
+#define TFTP_EXIT(...)
+
+#endif // TFTP_CONFIG_LOG_ENABLED
+/**
+ * @defgroup tftp_mutex_lock_unlock Module's Mutex Lock/Unlock Macros.
+ *
+ * @details Macros used to lock and unlock modules. Currently, SDK does not use mutexes but
+ * framework is provided in case need arises to use an alternative architecture.
+ * @{
+ */
+#define TFTP_MUTEX_LOCK() SDK_MUTEX_LOCK(m_tftp_mutex) /**< Lock module using mutex. */
+#define TFTP_MUTEX_UNLOCK() SDK_MUTEX_UNLOCK(m_tftp_mutex) /**< Unlock module using mutex. */
+/** @} */
+
+#define TFTP_HEADER_SIZE 2 /**< uint16_t opcode number. */
+#define TFTP_BLOCK_ID_SIZE 2 /**< uint16_t block id number. */
+#define TFTP_ERR_CODE_SIZE 2 /**< uint16_t error code. */
+#define TFTP_DEFAULT_BLOCK_SIZE 512 /**< uint16_t default data block size. */
+#define TFTP_DEFAULT_PORT 69 /**< uint16_t default TFTP server port number. */
+
+/**@brief Supported TFTP options. */
+#define OPTION_MODE_ASCII "netascii" /**< NETASCII mode string defined inside RFC1350. */
+#define OPTION_MODE_OCTET "octet" /**< OCTET mode string defined inside RFC1350. */
+#define OPTION_BLKSIZE "blksize" /**< Block Size option string defined inside RFC2348. */
+#define OPTION_TIMEOUT "timeout" /**< Timeout option string defined inside RFC2349. */
+#define OPTION_SIZE "tsize" /**< Transfer Size option string defined inside RFC2348. */
+
+#define NEXT_RETR_MAX_LENGTH 4 /**< Maximum length of TFTP "timeout" option value. */
+#define BLKSIZE_MAX_LENGTH 10 /**< Maximum length of TFTP "blksize" option value. */
+#define FILE_SIZE_MAX_LENGTH 10 /**< Maximum length of TFTP "tsize" option value. */
+
+#define OPTION_ERROR_MESSAGE "Unsupported option(s) requested"
+#define UDP_ERROR_MSG "UDP Error!"
+#define LENGTH_ERROR_MSG "Invalid packet length!"
+#define UNINT_ERROR_MSG "Connection reset by peer"
+#define ACCESS_ERROR_MSG "Access denied (cannot read/write from file)"
+#define OPTION_SIZE_REQUEST_VALUE "0"
+
+/**@brief TFTP Error codes. */
+#define ERR_UNDEFINED 0 /**< Not defined, see error message (if any). */
+#define ERR_FILE_NOT_FOUND 1 /**< File not found. */
+#define ERR_ACCESS_ERROR 2 /**< Access violation. */
+#define ERR_STORAGE_FULL 3 /**< Disk full or allocation exceeded. */
+#define ERR_INVALID_OP 4 /**< Illegal TFTP operation. */
+#define ERR_INVALID_TID 5 /**< Unknown transfer ID. */
+#define ERR_FILE_EXISTS 6 /**< File already exists. */
+#define ERR_BAD_USER 7 /**< No such user. */
+#define ERR_OPTION_REJECT 8 /**< Reject proposed options. */
+
+/**@brief TFTP opcode's. This field specifies type of packet. */
+#define TYPE_RRQ 1 /**< Read request (RRQ). */
+#define TYPE_WRQ 2 /**< Write request (WRQ). */
+#define TYPE_DATA 3 /**< Data (DATA). */
+#define TYPE_ACK 4 /**< Acknowledgment (ACK). */
+#define TYPE_ERR 5 /**< Error (ERROR). */
+#define TYPE_OACK 6 /**< Option Acknowledgment (RRQ/WRQ ACK). */
+
+/**
+ * @defgroup api_param_check API Parameters check macros.
+ *
+ * @details Macros that verify parameters passed to the module in the APIs. These macros
+ * could be mapped to nothing in final versions of code to save execution and size.
+ * DNS6_DISABLE_API_PARAM_CHECK should be set to 0 to enable these checks.
+ *
+ * @{
+ */
+
+#if (TFTP_DISABLE_API_PARAM_CHECK == 0)
+
+/**@brief Verify NULL parameters are not passed to API by application. */
+#define NULL_PARAM_CHECK(PARAM) \
+ if ((PARAM) == NULL) \
+ { \
+ return (NRF_ERROR_NULL | IOT_TFTP_ERR_BASE); \
+ }
+
+#else // TFTP_DISABLE_API_PARAM_CHECK
+
+#define NULL_PARAM_CHECK(PARAM)
+
+#endif // DNS6_DISABLE_API_PARAM_CHECK
+
+/**@brief Check err_code, free p_buffer and return on error. */
+#define PBUFFER_FREE_IF_ERROR(err_code) \
+ if (err_code != NRF_SUCCESS) \
+ { \
+ (void)iot_pbuffer_free(p_buffer, true); \
+ return err_code; \
+ }
+
+/**@brief Convert TFTP error code into IOT error with appropriate base. */
+#define CONVERT_TO_IOT_ERROR(error_code) \
+ ((IOT_TFTP_ERR_BASE+0x0040) + NTOHS(error_code))
+
+/**@brief Convert IOT error into TFTP error code by removing TFTP error base. */
+#define CONVERT_TO_TFTP_ERROR(error_code) \
+ (HTONS(err_code - (IOT_TFTP_ERR_BASE+0x0040)))
+
+/**@brief Iterator for string list delimited with '\0'. */
+typedef struct
+{
+ char * p_start; /**< Pointer to the beginning of a string. */
+ char * p_end; /**< Pointer to the end of a string. */
+ struct curr_struct
+ {
+ char * p_key; /**< Pointer to the last, found key string. */
+ char * p_value; /**< Pointer to the last, found value string. */
+ } curr;
+} option_iter_t;
+
+/**@brief Allowed states of a single TFTP instance. */
+typedef enum
+{
+ STATE_FREE = 0, /**< Start state, after calling UDP to allocate socket. */
+ STATE_IDLE, /**< Socket is allocated, but not used. */
+ STATE_CONNECTING_RRQ, /**< RRQ packet sent. Waiting for response. */
+ STATE_CONNECTING_WRQ, /**< WRQ packet sent. Waiting for response. */
+ STATE_SENDING, /**< Sending file and receiving ACK. */
+ STATE_SEND_HOLD, /**< Sending held. Waiting for resume call. */
+ STATE_RECEIVING, /**< Receiving file and sending ACK. */
+ STATE_RECV_HOLD, /**< Receiving held. Waiting for resume call. */
+ STATE_RECV_COMPLETE /**< State after receiving last DATA, before sending last ACK packet. There won't be another UDP event to emit IOT_TFTP_EVT_TRANSFER_GET_COMPLETE event, so next resume() should emit that event. */
+} tftp_state_t;
+
+/**@brief Internal TFTP instance structure. */
+typedef struct
+{
+ iot_tftp_trans_params_t init_params; /**< Connection parameters set during initialization. */
+ iot_tftp_trans_params_t connect_params; /**< Negotiated Connection parameters. */
+ udp6_socket_t socket; /**< UDP socket assigned to single instance. */
+ tftp_state_t state; /**< Integer representing current state of an instance. */
+ iot_tftp_callback_t callback; /**< User defined callback (passed inside initial parameters structure). */
+ iot_file_t * p_file; /**< Pointer to destination/source file assigned in get/put call. */
+ const char * p_path; /**< Path of the file on the remote node. */
+ uint16_t block_id; /**< ID of last received/sent data block. */
+ uint16_t src_tid; /**< UDP port used for sending information to the server. */
+ uint16_t dst_tid; /**< UDP port on which all packets will be sent. At first - dst_port (see below), then reassigned. */
+ uint16_t dst_port; /**< UDP port on which request packets will be sent. Usually DEFAULT_PORT. */
+ const char * p_password; /**< Pointer to a constant string containing password passed inside Read/Write Requests. */
+ ipv6_addr_t addr; /**< IPv6 server address. */
+ iot_pbuffer_t * p_packet; /**< Reference to the temporary packet buffer. */
+ uint8_t retries; /**< Number of already performed retries. */
+ volatile iot_timer_time_in_ms_t request_timeout; /**< Number of milliseconds on which last request should be retransmitted. */
+} tftp_instance_t;
+
+SDK_MUTEX_DEFINE(m_tftp_mutex) /**< Mutex variable. Currently unused, this declaration does not occupy any space in RAM. */
+static tftp_instance_t m_instances[TFTP_MAX_INSTANCES]; /**< Array of allowed TFTP instances. */
+
+/**@brief Function for finding free TFTP instance index.
+ *
+ * @param[out] p_index Index being found.
+ *
+ * @retval NRF_SUCCESS if passed instance was found, else NRF_ERROR_NO_MEM error code will
+ * be returned.
+ */
+static uint32_t find_free_instance(uint32_t * p_index)
+{
+ uint32_t index = 0;
+
+ for (index = 0; index < TFTP_MAX_INSTANCES; index++)
+ {
+ if (m_instances[index].state == STATE_FREE)
+ {
+ *p_index = index;
+
+ return NRF_SUCCESS;
+ }
+ }
+
+ return (NRF_ERROR_NO_MEM | IOT_TFTP_ERR_BASE);
+}
+
+/**@brief Function for resolving instance index by passed pointer.
+ *
+ * @param[in] p_tftp Pointer representing TFTP instance in user space.
+ * @param[out] p_index Index of passed TFTP instance.
+ *
+ * @retval NRF_SUCCESS if passed instance was found, else NRF_ERROR_INVALID_PARAM error code
+ * will be returned.
+ */
+static uint32_t find_instance(iot_tftp_t * p_tftp, uint32_t * p_index)
+{
+ if (*p_tftp > TFTP_MAX_INSTANCES)
+ {
+ return (NRF_ERROR_INVALID_PARAM | IOT_TFTP_ERR_BASE);
+ }
+
+ *p_index = *p_tftp;
+
+ return NRF_SUCCESS;
+}
+
+/**@brief Function for notifying application of the TFTP events.
+ *
+ * @param[in] p_tftp TFTP instance.
+ * @param[in] p_evt Event description.
+ *
+ * @retval None.
+ */
+static void app_notify(iot_tftp_t * p_tftp, iot_tftp_evt_t * p_evt)
+{
+ uint32_t index;
+ uint32_t err_code;
+
+ err_code = find_instance(p_tftp, &index);
+ if (err_code != NRF_SUCCESS)
+ {
+ return;
+ }
+
+ if (m_instances[index].callback)
+ {
+ TFTP_MUTEX_UNLOCK();
+
+
+ // Call handler of user request.
+ m_instances[index].callback(p_tftp, p_evt);
+
+ TFTP_MUTEX_LOCK();
+ }
+}
+
+/**@brief Increment option iterator.
+ *
+ * @details The iterator will point to the next option or to p_end if it reaches the end.
+ *
+ * @param[in] p_iter Pointer to option iterator.
+ *
+ * @retval NRF_SUCCESS if iterator successfully moved to next option, else an error code indicating reason
+ * for failure.
+ */
+static uint32_t op_get_next(option_iter_t * p_iter)
+{
+ uint32_t key_length;
+ uint32_t value_length;
+
+ NULL_PARAM_CHECK(p_iter->p_start);
+ NULL_PARAM_CHECK(p_iter->p_end);
+ NULL_PARAM_CHECK(p_iter->curr.p_key);
+ NULL_PARAM_CHECK(p_iter->curr.p_value);
+
+ // If reached end.
+ if ((p_iter->curr.p_value == p_iter->p_end) || (p_iter->curr.p_key == p_iter->p_end))
+ {
+ return (NRF_ERROR_DATA_SIZE | IOT_TFTP_ERR_BASE);
+ }
+
+ key_length = strlen(p_iter->curr.p_key);
+ value_length = strlen(p_iter->curr.p_value);
+
+ if ((p_iter->curr.p_value == p_iter->p_start) && (p_iter->curr.p_key == p_iter->p_start))
+ {
+ // First call. Check if [start] + [string] fits before [end] reached.
+ // This statement just checks if there is '\0' between start and end (passing single string as input).
+ if (p_iter->curr.p_key + key_length < p_iter->p_end)
+ {
+ p_iter->curr.p_value = p_iter->curr.p_key + key_length + 1;
+
+ return NRF_SUCCESS;
+ }
+ else
+ {
+ return (NRF_ERROR_DATA_SIZE | IOT_TFTP_ERR_BASE);
+ }
+ }
+ else if (p_iter->curr.p_value + value_length < p_iter->p_end)
+ {
+ p_iter->curr.p_key = p_iter->curr.p_value + value_length + 1;
+ p_iter->curr.p_value = p_iter->curr.p_key + strlen(p_iter->curr.p_key) + 1;
+
+ if ((*p_iter->curr.p_key == '\0') || (*p_iter->curr.p_value == '\0')) // If string list finishes before the end of the buffer.
+ {
+ p_iter->curr.p_key = p_iter->p_end;
+ p_iter->curr.p_value = p_iter->p_end;
+
+ return (NRF_ERROR_DATA_SIZE | IOT_TFTP_ERR_BASE);
+ }
+
+ return NRF_SUCCESS;
+ }
+ else
+ {
+ p_iter->curr.p_key = p_iter->p_end;
+ p_iter->curr.p_value = p_iter->p_end;
+
+ return (NRF_ERROR_DATA_SIZE | IOT_TFTP_ERR_BASE);
+ }
+}
+
+/**@brief Set new (key, value) pair at the end of a string.
+ *
+ * @param[out] p_iter Pointer to iterator, which will be used to add (key, value) pair.
+ * @param[in] p_inp_key Pointer to the new key string. If p_key is NULL, then this function will insert just value.
+ * @param[in] p_inp_value Pointer to the new value string.
+ *
+ * @retval NRF_SUCCESS on successful execution of procedure, else an error code indicating reason
+ * for failure.
+ */
+static __INLINE uint32_t op_set(option_iter_t * p_iter, const char * p_inp_key, const char * p_inp_value)
+{
+ char * p_last_key;
+ char * p_last_value;
+
+ NULL_PARAM_CHECK(p_iter->p_start);
+ NULL_PARAM_CHECK(p_iter->p_end);
+ NULL_PARAM_CHECK(p_iter->curr.p_key);
+ NULL_PARAM_CHECK(p_iter->curr.p_value);
+
+ p_last_key = p_iter->curr.p_key;
+ p_last_value = p_iter->curr.p_value;
+
+ // Print appropriate trace log.
+ if (p_inp_key != NULL)
+ {
+ TFTP_TRC("Set option: %s with value: %s.", p_inp_key, p_inp_value);
+ }
+ else
+ {
+ TFTP_TRC("Set value: %s.", p_inp_value);
+ }
+
+ // Set key & value pointers.
+ if ((p_iter->curr.p_key == p_iter->p_start) && (p_iter->curr.p_value == p_iter->p_start)) // Start condition.
+ {
+ if (p_inp_key != NULL)
+ {
+ p_iter->curr.p_value = p_iter->curr.p_key + strlen(p_inp_key) + 1;
+ }
+ else
+ {
+ p_iter->curr.p_value = p_iter->curr.p_key; // Insert only passed value.
+ p_iter->curr.p_key = p_iter->curr.p_value + strlen(p_iter->curr.p_value) + 1; // Just assign anything different that p_start and inside buffer.
+ }
+ }
+ else
+ {
+ p_iter->curr.p_key = p_iter->curr.p_value + strlen(p_iter->curr.p_value) + 1; // New key starts where last value ends.
+
+ if (p_inp_key != NULL)
+ {
+ p_iter->curr.p_value = p_iter->curr.p_key + strlen(p_inp_key) + 1; // If key not null - new value starts where new key ends.
+ }
+ else
+ {
+ p_iter->curr.p_value = p_iter->curr.p_key; // Otherwise - value is placed at the key position.
+ }
+ }
+
+ // Copy strings into set pointers.
+ if ((p_iter->curr.p_value + strlen(p_inp_value)) < p_iter->p_end)
+ {
+ if (p_inp_key != NULL)
+ {
+ memcpy(p_iter->curr.p_key, p_inp_key, strlen(p_inp_key) + 1);
+ }
+ memcpy(p_iter->curr.p_value, p_inp_value, strlen(p_inp_value) + 1);
+ }
+ else // If it is not possible to insert new key & value pair.
+ {
+ p_iter->curr.p_key = p_last_key;
+ p_iter->curr.p_value = p_last_value;
+
+ TFTP_ERR("Unable to set option (size error)!");
+
+ return (NRF_ERROR_DATA_SIZE | IOT_TFTP_ERR_BASE);
+ }
+
+ return NRF_SUCCESS;
+}
+
+/**@brief Initializes new option iterator.
+ *
+ * @param[out] p_iter Pointer to iterator, which will be configured.
+ * @param[in] p_buf Pointer to the new string buffer which iterator will be modifying.
+ * @param[in] buf_len Length of passed buffer.
+ *
+ * @retval NRF_SUCCESS on successful execution of procedure, else an error code indicating reason
+ * for failure.
+ */
+static __INLINE void op_init(option_iter_t * p_iter, char * p_buf, uint32_t buf_len)
+{
+ p_iter->p_start = p_buf;
+ p_iter->p_end = p_buf + buf_len;
+ p_iter->curr.p_key = p_buf;
+ p_iter->curr.p_value = p_buf;
+}
+
+/**@brief: Converts string containing unsigned number into uint32_t.
+ *
+ * @param[in] p_str Input string.
+ *
+ * @retval Integer number equal to read value. Reading process skips all non-digit characters.
+ */
+static uint32_t str_to_uint(char * p_str)
+{
+ uint32_t len;
+ uint32_t ret_val = 0;
+ uint32_t mul = 1;
+
+ if (p_str == NULL)
+ {
+ return 0;
+ }
+
+ len = strlen(p_str);
+
+ while (len)
+ {
+ len--;
+
+ if ((p_str[len] >= '0') && (p_str[len] <= '9')) // Skip unsupported characters.
+ {
+ ret_val += mul * (p_str[len] - '0');
+ mul *= 10;
+ }
+ }
+
+ return ret_val;
+}
+
+/**@brief: Converts unsigned number into string.
+ *
+ * @param[in] number Input number.
+ * @param[out] p_str Pointer to the output string.
+ * @param[in] len Length of the passed output string buffer.
+ *
+ * @retval NRF_SUCCESS on successful execution of procedure, else an error code indicating reason
+ * for failure.
+ */
+static uint32_t uint_to_str(uint32_t number, char * p_str, uint16_t len)
+{
+ uint32_t i = 0;
+ uint32_t temp = number;
+
+ if (len == 0)
+ {
+ return NRF_ERROR_INVALID_LENGTH;
+ }
+
+ // Check how many characters will be needed.
+ if (temp == 0)
+ {
+ i = 1;
+ }
+
+ while (temp)
+ {
+ i++;
+ temp /= 10;
+ }
+
+ // Set null character and check length.
+ if (i + 1 > len)
+ {
+ p_str[0] = '\0';
+
+ return NRF_ERROR_INVALID_LENGTH;
+ }
+
+ p_str[i] = '\0';
+
+ // Set digits.
+ while (i--)
+ {
+ p_str[i] = '0' + number % 10;
+ number /= 10;
+ }
+
+ return NRF_SUCCESS;
+}
+
+/**@brief Compare strings in a case insensitive way.
+ *
+ * @param[in] p_str1 Pointer to the first string.
+ * @param[in] p_str2 Pointer to the second String.
+ *
+ * @retval If strings are equal returns 0, otherwise number of common characters.
+ */
+static uint32_t strcmp_ci(char * p_str1, char* p_str2)
+{
+ uint32_t min_len = 0;
+ uint32_t str1_len;
+ uint32_t str2_len;
+ uint32_t i = 0;
+
+ str1_len = strlen(p_str1);
+ str2_len = strlen(p_str2);
+
+ min_len = str1_len;
+
+ if (str2_len < str1_len)
+ {
+ min_len = str2_len;
+ }
+
+ for (i = 0; i < min_len; i++)
+ {
+ char c1 = ((p_str1[i] >= 'a' && p_str1[i] <= 'z') ? p_str1[i] + 'A' - 'a' : p_str1[i]);
+ char c2 = ((p_str2[i] >= 'a' && p_str2[i] <= 'z') ? p_str2[i] + 'A' - 'a' : p_str2[i]);
+
+ if (c1 != c2)
+ {
+ return i + 1;
+ }
+ }
+
+ if (str1_len != str2_len)
+ {
+ return i + 1;
+ }
+
+ return 0;
+}
+
+/**@brief Allocates p_buffer and fills in common fields.
+ *
+ * @param[in] type First field describing packet type.
+ * @param[in] id Second field (Block ID / Error Code).
+ * @param[out] pp_buffer Sets pointer to the newly allocated buffer.
+ * @param[in] payload_len Length of payload (additional fields / data).
+ *
+ * @retval NRF_SUCCESS on successful execution of procedure, else an error code indicating reason
+ * for failure.
+ */
+static uint32_t compose_packet(uint16_t type,
+ uint16_t id,
+ iot_pbuffer_t ** pp_buffer,
+ uint32_t payload_len)
+{
+ uint32_t err_code;
+ iot_pbuffer_alloc_param_t buffer_param;
+ iot_pbuffer_t * p_buffer;
+ uint32_t byte_index;
+
+ memset(&buffer_param, 0, sizeof(iot_pbuffer_alloc_param_t));
+ buffer_param.length = TFTP_HEADER_SIZE + TFTP_BLOCK_ID_SIZE + payload_len;
+ buffer_param.type = UDP6_PACKET_TYPE;
+ buffer_param.flags = PBUFFER_FLAG_DEFAULT;
+
+ err_code = iot_pbuffer_allocate(&buffer_param, &p_buffer);
+ if (err_code != NRF_SUCCESS)
+ {
+ return err_code;
+ }
+
+ memset(p_buffer->p_payload, 0, buffer_param.length);
+ byte_index = 0;
+
+ // Insert type opcode.
+ byte_index += uint16_encode(HTONS(type), &p_buffer->p_payload[byte_index]);
+
+ if (type == TYPE_ERR)
+ {
+ // Insert err code.
+ byte_index += uint16_encode(CONVERT_TO_TFTP_ERROR(id), &p_buffer->p_payload[byte_index]);
+ }
+ else
+ {
+ // Insert block ID.
+ byte_index += uint16_encode(HTONS(id), &p_buffer->p_payload[byte_index]);
+ }
+
+ *pp_buffer = p_buffer;
+
+ return NRF_SUCCESS;
+}
+
+/**@brief Reset instance request timer.
+ *
+ * @param[in] index Index of pending instance.
+ *
+ * @retval NRF_SUCCESS on successful execution of procedure, else an error code indicating reason
+ * for failure.
+ */
+static uint32_t retr_timer_reset(uint32_t index)
+{
+ uint32_t err_code;
+ iot_timer_time_in_ms_t wall_clock_value;
+
+ // Get wall clock time.
+ err_code = iot_timer_wall_clock_get(&wall_clock_value);
+
+ if (err_code == NRF_SUCCESS)
+ {
+ m_instances[index].request_timeout = wall_clock_value + m_instances[index].connect_params.next_retr * 1000;
+ }
+
+ return err_code;
+}
+
+/**@brief Function for checking if retransmission time of TFTP instance request has been expired.
+ *
+ * @param[in] index Index of pending instance.
+ *
+ * @retval True if timer has been expired, False otherwise.
+ */
+static bool instance_timer_is_expired(uint32_t index)
+{
+ uint32_t err_code;
+ iot_timer_time_in_ms_t wall_clock_value;
+
+ // Get wall clock time.
+ err_code = iot_timer_wall_clock_get(&wall_clock_value);
+
+ if (err_code == NRF_SUCCESS)
+ {
+ if (wall_clock_value >= m_instances[index].request_timeout)
+ {
+ return true;
+ }
+ }
+
+ return false;
+}
+
+/**@brief Sets all instance values to defaults. */
+static void instance_reset(uint32_t index)
+{
+ m_instances[index].state = STATE_FREE;
+ m_instances[index].init_params.next_retr = 0;
+ m_instances[index].init_params.block_size = TFTP_DEFAULT_BLOCK_SIZE;
+ m_instances[index].connect_params.next_retr = 0;
+ m_instances[index].connect_params.block_size = TFTP_DEFAULT_BLOCK_SIZE;
+ m_instances[index].p_file = NULL;
+ m_instances[index].block_id = 0;
+ m_instances[index].p_packet = NULL;
+ m_instances[index].dst_port = TFTP_DEFAULT_PORT;
+ m_instances[index].dst_tid = TFTP_DEFAULT_PORT;
+ m_instances[index].retries = 0;
+ m_instances[index].request_timeout = 0;
+ m_instances[index].callback = NULL;
+ m_instances[index].src_tid = 0;
+ m_instances[index].p_password = NULL;
+ memset(&m_instances[index].addr, 0, sizeof(ipv6_addr_t));
+ memset(&m_instances[index].socket, 0, sizeof(udp6_socket_t));
+}
+
+/**@brief This function creates error packet for specified TFTP instance.
+ *
+ * @param[in] index Index of TFTP instance.
+ * @param[in] p_err_evt Event data structure (message and code).
+ *
+ * @retval NRF_SUCCESS on successful execution of procedure, else an error code indicating reason
+ * for failure.
+ */
+static uint32_t send_err_msg(uint32_t index, iot_tftp_evt_err_t * p_err_evt)
+{
+ iot_pbuffer_t * p_buffer;
+ uint8_t * p_resp_packet;
+ uint32_t msg_len = 0;
+ uint16_t byte_index = 0;
+ uint32_t err_code;
+
+ TFTP_TRC("Send ERROR packet.");
+
+ if (p_err_evt->p_msg != NULL)
+ {
+ msg_len = strlen(p_err_evt->p_msg) + 1;
+ }
+
+ err_code = compose_packet(TYPE_ERR, p_err_evt->code, &p_buffer, msg_len);
+ if (err_code != NRF_SUCCESS)
+ {
+ return err_code;
+ }
+
+ p_resp_packet = p_buffer->p_payload;
+ byte_index = TFTP_HEADER_SIZE + TFTP_ERR_CODE_SIZE;
+
+ if (p_err_evt->p_msg != NULL)
+ {
+ memcpy(&p_resp_packet[byte_index], p_err_evt->p_msg, msg_len);
+ byte_index += msg_len;
+ }
+
+ p_buffer->length = byte_index;
+
+ TFTP_TRC("Send packet to UDP module.");
+
+ UNUSED_VARIABLE(retr_timer_reset(index));
+
+ err_code = udp6_socket_sendto(&m_instances[index].socket,
+ &m_instances[index].addr,
+ m_instances[index].dst_tid,
+ p_buffer);
+
+ TFTP_TRC("Recv code: %08lx.", err_code);
+
+ return err_code;
+}
+
+/**@brief This function creeates error packet for TID error, not being found.
+ *
+ * @param[in] p_socket Socket from which error message is sent.
+ * @param[in] p_addr IPv6 Address to where error message is sent.
+ * @param[in] tid Erronous TID from the sender.
+ *
+ * @retval NRF_SUCCESS on successful execution of procedure, else an error code indicating reason
+ * for failure.
+ */
+static uint32_t send_err_tid(const udp6_socket_t * p_socket, const ipv6_addr_t * p_addr, uint16_t tid)
+{
+ iot_pbuffer_t * p_buffer;
+ uint32_t msg_len = 0;
+ uint16_t byte_index = 0;
+ uint32_t err_code;
+
+ TFTP_TRC("Send TID ERROR packet.");
+
+ err_code = compose_packet(TYPE_ERR, ERR_INVALID_TID, &p_buffer, msg_len);
+ if (err_code != NRF_SUCCESS)
+ {
+ return err_code;
+ }
+
+ byte_index = TFTP_HEADER_SIZE + TFTP_ERR_CODE_SIZE;
+ p_buffer->length = byte_index;
+
+ TFTP_TRC("Send packet to UDP module.");
+
+ err_code = udp6_socket_sendto(p_socket, p_addr, tid, p_buffer);
+
+ TFTP_TRC("Recv code: %08lx.", err_code);
+
+ return err_code;
+}
+
+/**@brief Sends ACK or next data chunk (block) after calling user callback or when hold timer expires.
+ *
+ * @param[in] p_tftp Pointer to the TFTP instance (from user space).
+ * @param[in] p_evt Pointer to the event structure. Used for sending error messages.
+ *
+ * @retval NRF_SUCCESS on successful execution of procedure, else an error code indicating reason
+ * for failure.
+ */
+static uint32_t send_response(iot_tftp_t * p_tftp)
+{
+ uint32_t index;
+ uint32_t err_code;
+
+ TFTP_TRC("Send packet.");
+
+ err_code = find_instance(p_tftp, &index);
+ if (err_code != NRF_SUCCESS)
+ {
+ TFTP_ERR("Cannot find instance (send)!");
+
+ return err_code;
+ }
+
+ switch (m_instances[index].state)
+ {
+ case STATE_IDLE:
+ // Server should go to the CONNECTING state (request received).
+ TFTP_TRC("Inside IDLE state (send). ");
+ return NRF_SUCCESS;
+
+ case STATE_SENDING:
+ case STATE_RECEIVING:
+ case STATE_SEND_HOLD:
+ case STATE_RECV_HOLD:
+ case STATE_RECV_COMPLETE:
+ // Send DATA/ACK packet.
+ TFTP_TRC("Send packet to UDP module.");
+
+ UNUSED_VARIABLE(retr_timer_reset(index));
+ err_code = udp6_socket_sendto(&m_instances[index].socket,
+ &m_instances[index].addr,
+ m_instances[index].dst_tid,
+ m_instances[index].p_packet);
+ TFTP_TRC("Recv code: %08lx.", err_code);
+ return err_code;
+
+ default:
+ TFTP_ERR("Invalid state (send)!");
+ return (NRF_ERROR_INVALID_STATE | IOT_TFTP_ERR_BASE);
+ }
+}
+
+
+
+/**@brief Aborts TFTP client ongoing procedure.
+ *
+ * @param[in] index Index of TFTP instance.
+ *
+ * @retval NRF_SUCCESS on successful execution of procedure, else an error code indicating reason
+ * for failure.
+ */
+void instance_abort(uint32_t index)
+{
+ uint32_t internal_err;
+
+ switch (m_instances[index].state)
+ {
+ case STATE_SEND_HOLD:
+ case STATE_RECV_HOLD:
+ // Free pbuffer.
+ internal_err = iot_pbuffer_free(m_instances[index].p_packet, true);
+ if (internal_err != NRF_SUCCESS)
+ {
+ TFTP_ERR("Cannot free pbuffer - %p", m_instances[index].p_packet);
+ }
+
+ // Close file.
+ internal_err = iot_file_fclose(m_instances[index].p_file);
+ if (internal_err != NRF_SUCCESS)
+ {
+ TFTP_ERR("Cannot close file - %p", m_instances[index].p_file);
+ }
+
+ break;
+ case STATE_SENDING:
+ case STATE_RECEIVING:
+ // Close file.
+ internal_err = iot_file_fclose(m_instances[index].p_file);
+ if (internal_err != NRF_SUCCESS)
+ {
+ TFTP_ERR("Cannot close file - %p", m_instances[index].p_file);
+ }
+ break;
+ case STATE_CONNECTING_RRQ:
+ case STATE_CONNECTING_WRQ:
+ case STATE_IDLE:
+ case STATE_FREE:
+ default:
+ break;
+ }
+
+ TFTP_TRC("Reset instance %ld.", index);
+
+ m_instances[index].state = STATE_IDLE;
+ m_instances[index].block_id = 0;
+ m_instances[index].dst_tid = m_instances[index].dst_port;
+ m_instances[index].retries = 0;
+ m_instances[index].request_timeout = 0;
+ memcpy(&m_instances[index].connect_params,
+ &m_instances[index].init_params,
+ sizeof(iot_tftp_trans_params_t));
+}
+
+
+/**@brief Generates event for application.
+ *
+ * @param[in] index Index of TFTP instance.
+ * @param[in] evt_id Id of generated event.
+ * @param[in] p_param Pointer to event parameter union.
+ */
+static void handle_evt(uint32_t index, iot_tftp_evt_id_t evt_id, iot_tftp_evt_param_t * p_param)
+{
+ uint32_t internal_err;
+ iot_tftp_evt_t evt;
+
+ memset(&evt, 0, sizeof(evt));
+ evt.id = evt_id;
+ evt.p_file = m_instances[index].p_file;
+
+ if (p_param != NULL)
+ {
+ evt.param = * p_param;
+ }
+
+ if (evt_id == IOT_TFTP_EVT_ERROR)
+ {
+ uint32_t err_code = evt.param.err.code;
+
+ TFTP_TRC("Raise an ERROR event.");
+
+ if ((err_code & IOT_TFTP_ERR_BASE) == IOT_TFTP_ERR_BASE)
+ {
+ evt.param.err.code = CONVERT_TO_TFTP_ERROR(err_code);
+
+ internal_err = send_err_msg(index, &evt.param.err);
+ if (internal_err != NRF_SUCCESS)
+ {
+ TFTP_TRC("Cannot send error message to peer %08lx.", internal_err);
+ }
+ }
+
+ // Restore error code.
+ evt.param.err.code = err_code;
+
+ // Return to IDLE and notify.
+ instance_abort(index);
+
+ app_notify(&index, &evt);
+ }
+ else if ((evt_id == IOT_TFTP_EVT_TRANSFER_GET_COMPLETE) ||
+ (evt_id == IOT_TFTP_EVT_TRANSFER_PUT_COMPLETE))
+ {
+ TFTP_TRC("Raise TRANSFER COMPLETE event.");
+
+ if (m_instances[index].state == STATE_RECV_HOLD)
+ {
+ TFTP_TRC("Holding last ACK transfer.");
+ m_instances[index].state = STATE_RECV_COMPLETE;
+ }
+ else if (m_instances[index].state != STATE_RECV_COMPLETE)
+ {
+ // Skip into IDLE state.
+ instance_abort(index);
+
+ app_notify(&index, &evt);
+ }
+ }
+ else if (evt_id == IOT_TFTP_EVT_TRANSFER_DATA_RECEIVED)
+ {
+ app_notify(&index, &evt);
+ }
+}
+
+/**@brief Generates error event for application.
+ *
+ * @param[in] index Index of TFTP instance.
+ * @param[in] err_code Code of error event.
+ * @param[in] p_msg Character string containing error message.
+ */
+static void handle_evt_err(uint32_t index, uint32_t err_code, char * p_msg)
+{
+ iot_tftp_evt_param_t evt_param;
+
+ memset(&evt_param, 0, sizeof(evt_param));
+
+ evt_param.err.code = err_code;
+ evt_param.err.p_msg = p_msg;
+ evt_param.err.size_transfered = m_instances[index].block_id * m_instances[index].connect_params.block_size;
+
+ handle_evt(index, IOT_TFTP_EVT_ERROR, &evt_param);
+}
+
+/**@brief: Find instance number by Transmission ID (UDP source port).
+ *
+ * @param[in] port UDP port number on which new message was received.
+ * @param[out] p_index Index of found TFTP instance assigned to the passed UDP port.
+ *
+ * @retval NRF_SUCCESS on successful execution of procedure, else an error code indicating reason
+ * for failure.
+ */
+static __INLINE uint32_t find_instance_by_tid(uint16_t port, uint32_t * p_index)
+{
+ uint32_t index;
+
+ for (index = 0; index < TFTP_MAX_INSTANCES; index++)
+ {
+ if (m_instances[index].src_tid == port)
+ {
+ break;
+ }
+ }
+
+ if (index == TFTP_MAX_INSTANCES)
+ {
+ return (NRF_ERROR_NOT_FOUND | IOT_TFTP_ERR_BASE);
+ }
+
+ *p_index = index;
+
+ return NRF_SUCCESS;
+}
+
+/**@brief: Negotiation procedure. This function skips through input option string and modifies instance parameters according to negotiated values.
+ *
+ * @param[in] p_iter Pointer to iterator configured to parse RQ/OACK packet.
+ * @param[out] p_instance Pointer to the instance, which parameters should be negotiated.
+ *
+ * @retval NRF_SUCCESS on successful execution of procedure, else TFTP_OPTION_REJECT error indicating
+ * that server/client requests unsupported option values.
+ */
+static uint32_t option_negotiate(option_iter_t * p_iter, tftp_instance_t * p_instance)
+{
+ uint32_t err_code;
+ bool op_size_set = false;
+ bool op_blksize_set = false;
+ bool op_time_set = false;
+
+ TFTP_TRC("Negotiate options:");
+
+ if (p_iter != NULL) // If NULL passed - reset option values to those defined by RFC.
+ {
+ UNUSED_VARIABLE(op_get_next(p_iter));
+
+ while (p_iter->curr.p_key != p_iter->p_end)
+ {
+ if (strcmp_ci(p_iter->curr.p_key, OPTION_TIMEOUT) == 0)
+ {
+ if (p_instance->init_params.next_retr != 0)
+ {
+ uint16_t server_time = str_to_uint(p_iter->curr.p_value);
+
+ if (server_time < p_instance->init_params.next_retr) // Take minimum.
+ {
+ p_instance->connect_params.next_retr = server_time;
+ }
+ else
+ {
+ p_instance->connect_params.next_retr = p_instance->init_params.next_retr;
+ }
+
+ op_time_set = true;
+
+ TFTP_TRC("TIMEOUT: %ld", p_instance->connect_params.next_retr);
+ }
+ }
+ else if (strcmp_ci(p_iter->curr.p_key, OPTION_SIZE) == 0)
+ {
+ if (p_instance->p_file != NULL)
+ {
+ uint32_t file_size = str_to_uint(p_iter->curr.p_value);
+
+ err_code = iot_file_fopen(p_instance->p_file, file_size);
+ if (err_code != NRF_SUCCESS)
+ {
+ TFTP_TRC(" TSIZE: REJECT!");
+ return TFTP_OPTION_REJECT;
+ }
+
+ op_size_set = true;
+ TFTP_TRC(" TSIZE: %ld", file_size);
+ }
+ }
+ else if (strcmp_ci(p_iter->curr.p_key, OPTION_BLKSIZE) == 0)
+ {
+ uint16_t block_size = str_to_uint(p_iter->curr.p_value);
+ op_blksize_set = true;
+
+ if (p_instance->init_params.block_size >= block_size)
+ {
+ p_instance->connect_params.block_size = block_size;
+ }
+ else
+ {
+ TFTP_TRC("BLKSIZE: REJECT!");
+ return TFTP_OPTION_REJECT;
+ }
+
+ TFTP_TRC("BLKSIZE: %d", p_instance->connect_params.block_size);
+ }
+ else if ((strlen(p_iter->curr.p_key) > 0) && (p_iter->curr.p_value == p_iter->p_end))
+ {
+ // Password option.
+ TFTP_TRC("PASSWORD FOUND: %s", p_iter->curr.p_key);
+ p_iter->curr.p_key = p_iter->p_end;
+ }
+ else
+ {
+ TFTP_TRC("UNKNOWN OPTION");
+ }
+
+ UNUSED_VARIABLE(op_get_next(p_iter));
+ }
+ }
+
+ // Set values of not negotiated options.
+ if (!op_size_set && p_instance->p_file != NULL)
+ {
+ err_code = iot_file_fopen(p_instance->p_file, 0);// Open with default file size (not known).
+
+ if (err_code != NRF_SUCCESS)
+ {
+ TFTP_TRC("TSIZE: REJECT!");
+ return TFTP_OPTION_REJECT;
+ }
+
+ TFTP_TRC("TSIZE: %ld", p_instance->p_file->file_size);
+ }
+
+ if (!op_blksize_set)
+ {
+ if ((p_instance->init_params.block_size < TFTP_DEFAULT_BLOCK_SIZE) &&
+ (p_instance->init_params.block_size != 0))
+ {
+ TFTP_TRC("BLKSIZE: REJECT!");
+ return TFTP_OPTION_REJECT;
+ }
+ else
+ {
+ p_instance->connect_params.block_size = TFTP_DEFAULT_BLOCK_SIZE;
+ }
+
+ TFTP_TRC("BLKSIZE: %d", p_instance->connect_params.block_size);
+ }
+
+ if (!op_time_set)
+ {
+ p_instance->connect_params.next_retr = p_instance->init_params.next_retr;
+
+ TFTP_TRC("TIMEOUT: %ld", p_instance->connect_params.next_retr);
+ }
+
+ return NRF_SUCCESS;
+}
+
+
+
+/**@brief This function holds ongoing transmission of TFTP.
+ *
+ * @param[in] index Index of TFTP instance.
+ *
+ * @retval NRF_SUCCESS on successful execution of procedure, else an error code indicating reason
+ * for failure.
+ */
+static uint32_t transfer_hold(uint32_t index)
+{
+ if (m_instances[index].state == STATE_SENDING)
+ {
+ m_instances[index].state = STATE_SEND_HOLD;
+ }
+ else if (m_instances[index].state == STATE_RECEIVING)
+ {
+ m_instances[index].state = STATE_RECV_HOLD;
+ }
+ else if (m_instances[index].state == STATE_RECV_COMPLETE)
+ {
+ m_instances[index].state = STATE_RECV_COMPLETE;
+ }
+ else
+ {
+ TFTP_ERR("Hold called in invalid state.");
+
+ return (NRF_ERROR_INVALID_STATE | IOT_TFTP_ERR_BASE);
+ }
+
+ return NRF_SUCCESS;
+}
+
+
+/**@brief This function resumes ongoing transmission of TFTP.
+ *
+ * @param[in] index Index of TFTP instance.
+ *
+ * @retval NRF_SUCCESS on successful execution of procedure, else an error code indicating reason
+ * for failure.
+ */
+static uint32_t transfer_resume(uint32_t index)
+{
+ uint32_t err_code = NRF_SUCCESS;
+
+ if ((m_instances[index].state != STATE_SEND_HOLD) &&
+ (m_instances[index].state != STATE_RECV_HOLD) &&
+ (m_instances[index].state != STATE_RECV_COMPLETE))
+ {
+ TFTP_ERR("Failed due to invalid state.");
+ TFTP_EXIT();
+ return (NRF_ERROR_INVALID_STATE | IOT_TFTP_ERR_BASE);
+ }
+
+ err_code = send_response(&index);
+ if (err_code != NRF_SUCCESS)
+ {
+ TFTP_ERR("Failed to send packet after resume.");
+ }
+
+ if (m_instances[index].state == STATE_SEND_HOLD)
+ {
+ m_instances[index].state = STATE_SENDING;
+ }
+ else if (m_instances[index].state == STATE_RECV_HOLD)
+ {
+ m_instances[index].state = STATE_RECEIVING;
+ }
+ else if (m_instances[index].state == STATE_RECV_COMPLETE)
+ {
+ m_instances[index].state = STATE_RECEIVING;
+ TFTP_ERR("Complete due to STATE_RECV_COMPLETE state.");
+ handle_evt(index, IOT_TFTP_EVT_TRANSFER_GET_COMPLETE, NULL);
+ }
+
+ return err_code;
+}
+
+
+/**@brief This function creates ACK packet for specified TFTP instance.
+ *
+ * @param[in] index Index of TFTP instance.
+ * @param[in] block_id Data block ID to be acknowledged.
+ *
+ * @retval NRF_SUCCESS on successful execution of procedure, else an error code indicating reason
+ * for failure.
+ */
+static uint32_t create_ack_packet(uint32_t index, uint16_t block_id)
+{
+ uint32_t err_code;
+
+ TFTP_ENTRY();
+
+ // Reuse p_packet pointer for a new (response) packet. Previous one will be automatically freed by IPv6 module.
+ err_code = compose_packet(TYPE_ACK,
+ block_id,
+ &m_instances[index].p_packet,
+ 0);
+
+ return err_code;
+}
+
+/**@brief This function creates data packet for specified TFTP instance.
+ *
+ * @param[in] index Index of TFTP instance.
+ * @param[in] block_id Data block ID to be sent.
+ *
+ * @retval NRF_SUCCESS on successful execution of procedure, else an error code indicating reason
+ * for failure.
+ */
+static uint32_t create_data_packet(uint32_t index, uint16_t block_id)
+{
+ uint32_t err_code;
+ uint32_t internal_err;
+ uint32_t cursor;
+ uint32_t byte_index;
+ iot_pbuffer_t * p_buffer = NULL;
+
+ TFTP_ENTRY();
+
+ if (m_instances[index].p_file == NULL)
+ {
+ TFTP_ERR("[TFTP]: Error while sending response. Reason: Missing file to send.\r\n");
+ return NRF_ERROR_INVALID_DATA;
+ }
+
+ // If ACK block ID doesn't match last sent packet number.
+ if (m_instances[index].block_id != block_id)
+ {
+ // fseek on file to move to the right point. If fseek returns error - whole transmission will be dropped.
+ err_code = iot_file_fseek(m_instances[index].p_file,
+ (block_id) * m_instances[index].connect_params.block_size);
+ if (err_code != NRF_SUCCESS)
+ {
+ TFTP_ERR("Unable to fseek on input data file!");
+ }
+ else
+ {
+ m_instances[index].block_id = block_id + 1;
+ }
+ }
+ else
+ {
+ m_instances[index].block_id = block_id + 1;
+ }
+
+ cursor = (m_instances[index].block_id - 1) * m_instances[index].connect_params.block_size;
+
+ // If previous DATA packet wasn't fully filled.
+ if (cursor > m_instances[index].p_file->file_size)
+ {
+ TFTP_TRC("Transfer complete. Don't send data.");
+ handle_evt(index, IOT_TFTP_EVT_TRANSFER_PUT_COMPLETE, NULL);
+ return NRF_SUCCESS;
+ }
+ else if (cursor + m_instances[index].connect_params.block_size >
+ m_instances[index].p_file->file_size) // If current sendto operation will send all remaining data.
+ {
+ TFTP_TRC("Send last data packet.");
+ err_code = compose_packet(TYPE_DATA,
+ m_instances[index].block_id,
+ &p_buffer,
+ m_instances[index].p_file->file_size - cursor);
+ }
+ else
+ {
+ TFTP_TRC("Send regular data packet.");
+ err_code = compose_packet(TYPE_DATA,
+ m_instances[index].block_id,
+ &p_buffer,
+ m_instances[index].connect_params.block_size);
+ }
+
+ if (err_code != NRF_SUCCESS)
+ {
+ return err_code;
+ }
+
+ TFTP_TRC("Created packet:");
+ TFTP_TRC("length: %ld", p_buffer->length);
+ TFTP_TRC(" type: %d", p_buffer->p_payload[0] * 256 + p_buffer->p_payload[1]);
+ TFTP_TRC(" ID: %d", p_buffer->p_payload[2] * 256 + p_buffer->p_payload[3]);
+
+ byte_index = TFTP_HEADER_SIZE + TFTP_BLOCK_ID_SIZE;
+
+ // Save reference to correctly filled packet buffer.
+ m_instances[index].p_packet = p_buffer;
+
+ if (p_buffer->length - TFTP_HEADER_SIZE - TFTP_BLOCK_ID_SIZE != 0)
+ {
+ TFTP_MUTEX_UNLOCK();
+
+ // Hold transfer.
+ internal_err = transfer_hold(index);
+ if (internal_err != NRF_SUCCESS)
+ {
+ TFTP_ERR("Error while holding the transfer. Reason: %08lx.", internal_err);
+ }
+
+ err_code = iot_file_fread(m_instances[index].p_file,
+ &(p_buffer->p_payload[byte_index]),
+ p_buffer->length - TFTP_HEADER_SIZE - TFTP_BLOCK_ID_SIZE);
+
+ // Unlock instance if file has not assigned callback (probably no needs more time to perform read/write).
+ if (m_instances[index].p_file->p_callback == NULL)
+ {
+ internal_err = transfer_resume(index);
+ if (internal_err != NRF_SUCCESS)
+ {
+ TFTP_ERR("Error while resuming the transfer. Reason: %08lx.", internal_err);
+ }
+ }
+ TFTP_MUTEX_LOCK();
+ }
+ else
+ {
+ // TFTP is going to send empty data packet, so file callback won't be called.
+ internal_err = send_response(&index);
+ if (internal_err != NRF_SUCCESS)
+ {
+ TFTP_ERR("Error while sending response. Reason: %08lx.", internal_err);
+ }
+ }
+
+ if (err_code != NRF_SUCCESS)
+ {
+ TFTP_ERR("Failed to save received data (fread)!");
+ handle_evt_err(index, TFTP_ACCESS_DENIED, ACCESS_ERROR_MSG);
+ }
+
+ return err_code;
+}
+
+
+/**@brief Callback handler to receive data on the UDP port.
+ *
+ * @param[in] p_socket Socket identifier.
+ * @param[in] p_ip_header IPv6 header containing source and destination addresses.
+ * @param[in] p_udp_header UDP header identifying local and remote endpoints.
+ * @param[in] process_result Result of data reception, there could be possible errors like
+ * invalid checksum etc.
+ * @param[in] p_rx_packet Packet buffer containing the received data packet.
+ *
+ * @retval NRF_SUCCESS Indicates received data was handled successfully, else an an
+ * error code indicating reason for failure..
+ */
+static uint32_t client_process(const udp6_socket_t * p_socket,
+ const ipv6_header_t * p_ip_header,
+ const udp6_header_t * p_udp_header,
+ uint32_t process_result,
+ iot_pbuffer_t * p_rx_packet)
+{
+ uint32_t index;
+ iot_tftp_evt_t evt;
+ uint8_t * p_new_packet;
+ uint32_t byte_index;
+ uint32_t err_code;
+ uint32_t internal_err;
+ uint16_t packet_opcode;
+ option_iter_t oack_iter;
+ uint16_t recv_block_id;
+
+ TFTP_ENTRY();
+
+ TFTP_MUTEX_LOCK();
+
+ err_code = find_instance_by_tid(p_udp_header->destport, &index);
+ if (err_code != NRF_SUCCESS)
+ {
+ TFTP_ERR("Unable to find TFTP instance associated with given UDP port.");
+
+ // Send TID error to the server.
+ err_code = send_err_tid(p_socket, &p_ip_header->srcaddr, p_udp_header->destport);
+
+ TFTP_EXIT();
+ TFTP_MUTEX_UNLOCK();
+
+ return err_code;
+ }
+
+ // Check UDP status code.
+ if (process_result != NRF_SUCCESS)
+ {
+ TFTP_ERR("UDP error!");
+
+ evt.id = IOT_TFTP_EVT_ERROR;
+ evt.param.err.code = process_result;
+ evt.param.err.p_msg = UDP_ERROR_MSG;
+
+ // Call user callback (inform about error).
+ app_notify(&index, &evt);
+
+ TFTP_EXIT();
+
+ TFTP_MUTEX_UNLOCK();
+
+ return process_result;
+ }
+
+ // Check packet length.
+ if (p_rx_packet->length < TFTP_HEADER_SIZE + TFTP_BLOCK_ID_SIZE)
+ {
+ TFTP_ERR("Invalid packet length!");
+
+ evt.id = IOT_TFTP_EVT_ERROR;
+ evt.param.err.code = TFTP_INVALID_PACKET;
+ evt.param.err.p_msg = (char *)"Invalid packet length!";
+
+ app_notify(&index, &evt);
+
+ TFTP_EXIT();
+
+ TFTP_MUTEX_UNLOCK();
+
+ return evt.param.err.code;
+ }
+
+ // Read received packet type.
+ p_new_packet = p_rx_packet->p_payload;
+ packet_opcode = uint16_decode(p_new_packet);
+ packet_opcode = NTOHS(packet_opcode);
+ byte_index = TFTP_HEADER_SIZE;
+
+ if ((m_instances[index].state == STATE_SEND_HOLD) ||
+ (m_instances[index].state == STATE_RECV_HOLD) ||
+ (m_instances[index].state == STATE_IDLE))
+ {
+ TFTP_TRC("Ignore packets in HOLD/IDLE states.");
+
+ TFTP_MUTEX_UNLOCK();
+
+ TFTP_EXIT();
+
+ return NRF_SUCCESS; // Ignore retransmission of other side.
+ }
+
+ switch (packet_opcode)
+ {
+ case TYPE_OACK:
+ if ((m_instances[index].state != STATE_CONNECTING_RRQ) &&
+ (m_instances[index].state != STATE_CONNECTING_WRQ) &&
+ (m_instances[index].state != STATE_IDLE && m_instances[index].retries > 0))
+ {
+ TFTP_ERR("Invalid TFTP instance state!");
+ break;
+ }
+
+ op_init(&oack_iter,
+ (char *)&p_new_packet[byte_index],
+ p_rx_packet->length - TFTP_HEADER_SIZE); // Options uses whole packet except opcode.
+
+ TFTP_TRC("Received OACK.");
+ err_code = option_negotiate(&oack_iter, &m_instances[index]);
+ if (err_code != NRF_SUCCESS)
+ {
+ TFTP_ERR("Failed to negotiate options!");
+ handle_evt_err(index, TFTP_OPTION_REJECT, OPTION_ERROR_MESSAGE);
+ break;
+ }
+
+ // Set server transmission id.
+ m_instances[index].dst_tid = p_udp_header->srcport;
+
+ if (m_instances[index].state == STATE_CONNECTING_RRQ)
+ {
+ m_instances[index].p_packet = p_rx_packet;
+ m_instances[index].state = STATE_RECEIVING;
+
+ err_code = create_ack_packet(index, 0);
+
+ if (err_code == NRF_SUCCESS)
+ {
+ err_code = send_response(&index);
+ }
+ }
+ else if (m_instances[index].state == STATE_CONNECTING_WRQ)
+ {
+ m_instances[index].state = STATE_SENDING;
+
+ err_code = create_data_packet(index, 0);
+ }
+ else
+ {
+ TFTP_ERR("Incorrect state to receive OACK!");
+ }
+
+ if (err_code != NRF_SUCCESS)
+ {
+ TFTP_ERR("Failed to create packet!");
+ handle_evt_err(index, err_code, NULL);
+ }
+ break;
+
+ case TYPE_ACK:
+ recv_block_id = uint16_decode(&p_new_packet[byte_index]);
+ recv_block_id = NTOHS(recv_block_id);
+
+ if (m_instances[index].state == STATE_CONNECTING_WRQ)
+ {
+ TFTP_TRC("Options not supported. Received ACK.");
+ err_code = option_negotiate(NULL, &m_instances[index]);
+ if (err_code != NRF_SUCCESS)
+ {
+ TFTP_ERR("Failed to negotiate default options!");
+ handle_evt_err(index, TFTP_OPTION_REJECT, OPTION_ERROR_MESSAGE);
+ break;
+ }
+
+ // Set server transmission id.
+ m_instances[index].dst_tid = p_udp_header->srcport;
+
+ // Set instance state.
+ m_instances[index].state = STATE_SENDING;
+ m_instances[index].block_id = 0;
+ }
+
+ if (m_instances[index].state == STATE_SENDING || m_instances[index].state == STATE_RECEIVING)
+ {
+ if (recv_block_id == m_instances[index].block_id)
+ {
+ m_instances[index].retries = 0;
+ }
+ TFTP_TRC("Received ACK. Send block %4d of %ld.", m_instances[index].block_id + 1,
+ CEIL_DIV(m_instances[index].p_file->file_size, m_instances[index].connect_params.block_size) +
+ ((m_instances[index].p_file->file_size % m_instances[index].connect_params.block_size == 0) ? 0 : 1));
+
+ err_code = create_data_packet(index, recv_block_id);
+ if ((err_code != (NRF_ERROR_DATA_SIZE | IOT_TFTP_ERR_BASE)) && (err_code != NRF_SUCCESS))
+ {
+ TFTP_ERR("Failed to create data packet.");
+ handle_evt_err(index, err_code, NULL);
+ }
+ }
+ else
+ {
+ TFTP_ERR("Invalid state to receive ACK packet.");
+
+ TFTP_MUTEX_UNLOCK();
+
+ TFTP_EXIT();
+
+ return NRF_SUCCESS;
+ }
+ break;
+
+ case TYPE_DATA:
+ recv_block_id = uint16_decode(&p_new_packet[byte_index]);
+ recv_block_id = NTOHS(recv_block_id);
+ byte_index += TFTP_BLOCK_ID_SIZE;
+
+ if (m_instances[index].state == STATE_CONNECTING_RRQ)
+ {
+ TFTP_TRC("Options not supported. Received DATA.");
+ err_code = option_negotiate(NULL, &m_instances[index]);
+ if (err_code != NRF_SUCCESS)
+ {
+ TFTP_ERR("Failed to set default options.");
+ handle_evt_err(index, TFTP_OPTION_REJECT, OPTION_ERROR_MESSAGE);
+ break;
+ }
+
+ if (recv_block_id == 1) // Received first data block.
+ {
+ m_instances[index].block_id = 0;
+ m_instances[index].state = STATE_RECEIVING;
+ }
+
+ // Set server transmission id.
+ m_instances[index].dst_tid = p_udp_header->srcport;
+ }
+
+ if (m_instances[index].state == STATE_RECEIVING)
+ {
+ TFTP_TRC("Received DATA.");
+
+ m_instances[index].p_packet = p_rx_packet;
+
+ if (recv_block_id == m_instances[index].block_id + 1)
+ {
+ TFTP_TRC("Received next DATA (n+1).");
+
+ m_instances[index].retries = 0;
+
+ err_code = create_ack_packet(index, m_instances[index].block_id + 1);
+
+ if (err_code != NRF_SUCCESS)
+ {
+ TFTP_ERR("Failed to create ACK packet!");
+ handle_evt_err(index, err_code, NULL);
+ break;
+ }
+ }
+ else
+ {
+ TFTP_TRC("Skip current DATA packet. Try to request proper block ID by sending ACK.");
+
+ err_code = create_ack_packet(index, m_instances[index].block_id);
+
+ if (err_code == NRF_SUCCESS)
+ {
+ err_code = send_response(&index);
+ }
+ else
+ {
+ TFTP_ERR("Failed to create ACK packet.");
+ handle_evt_err(index, err_code, NULL);
+ }
+ }
+
+ // Check if payload size is smaller than defined block size.
+ if ((p_rx_packet->length - TFTP_BLOCK_ID_SIZE - TFTP_HEADER_SIZE) <
+ m_instances[index].connect_params.block_size)
+ {
+ m_instances[index].state = STATE_RECV_COMPLETE;
+ }
+ else if (err_code != NRF_SUCCESS)
+ {
+ TFTP_ERR("Failed to create ACK packet.");
+ handle_evt_err(index, err_code, NULL);
+ break;
+ }
+
+ TFTP_TRC("Send block %4d of %ld ACK.", m_instances[index].block_id,
+ m_instances[index].p_file->file_size / m_instances[index].connect_params.block_size);
+
+ if (recv_block_id == m_instances[index].block_id + 1)
+ {
+ m_instances[index].block_id = recv_block_id;
+ TFTP_MUTEX_UNLOCK();
+
+ if (p_rx_packet->length - byte_index > 0)
+ {
+ iot_tftp_evt_param_t evt_param;
+ memset(&evt_param, 0, sizeof(evt_param));
+ evt_param.data_received.p_data = &p_new_packet[byte_index];
+ evt_param.data_received.size = p_rx_packet->length - byte_index;
+
+ internal_err = transfer_hold(index);
+ if (internal_err != NRF_SUCCESS)
+ {
+ TFTP_ERR("Error while holding the transfer. Reason: %08lx.", internal_err);
+ }
+
+ if (m_instances[index].p_file != NULL)
+ {
+ err_code = iot_file_fwrite(m_instances[index].p_file,
+ evt_param.data_received.p_data,
+ evt_param.data_received.size);
+ }
+
+ handle_evt(index, IOT_TFTP_EVT_TRANSFER_DATA_RECEIVED, &evt_param);
+
+ // Unlock instance if file has not assigned callback (probably not needs more time to perform read/write).
+ if (m_instances[index].p_file == NULL || m_instances[index].p_file->p_callback == NULL)
+ {
+ internal_err = transfer_resume(index);
+ if (internal_err != NRF_SUCCESS)
+ {
+ TFTP_ERR("Error while resuming the transfer. Reason: %08lx.", internal_err);
+ }
+ }
+ }
+ else
+ {
+ if (m_instances[index].p_file != NULL)
+ {
+ err_code = iot_file_fclose(m_instances[index].p_file);
+ }
+
+ internal_err = send_response(&index);
+ if (internal_err != NRF_SUCCESS)
+ {
+ TFTP_ERR("Error while sending response. Reason: %08lx.", internal_err);
+ }
+
+ TFTP_ERR("Complete due to packet length. (%ld: %ld)", p_rx_packet->length, byte_index);
+ m_instances[index].state = STATE_RECEIVING;
+ handle_evt(index, IOT_TFTP_EVT_TRANSFER_GET_COMPLETE, NULL);
+ }
+
+ TFTP_MUTEX_LOCK();
+
+ if (err_code != NRF_SUCCESS)
+ {
+ TFTP_ERR("Failed to save received data (fwrite)!");
+ handle_evt_err(index, TFTP_ACCESS_DENIED, ACCESS_ERROR_MSG);
+ break;
+ }
+ }
+ }
+ else
+ {
+ TFTP_ERR("Invalid state to receive DATA packet.");
+
+ TFTP_MUTEX_UNLOCK();
+
+ TFTP_EXIT();
+
+ return NRF_SUCCESS;
+ }
+ break;
+
+ case TYPE_ERR:
+ recv_block_id = uint16_decode(&p_new_packet[byte_index]);
+ recv_block_id = NTOHS(recv_block_id);
+ byte_index += TFTP_ERR_CODE_SIZE;
+
+ TFTP_ERR("Received error packet!");
+
+ evt.id = IOT_TFTP_EVT_ERROR;
+ evt.param.err.code = CONVERT_TO_IOT_ERROR(recv_block_id);
+
+ if (p_rx_packet->length > TFTP_HEADER_SIZE + TFTP_ERR_CODE_SIZE)
+ {
+ evt.param.err.p_msg = (char *) &p_new_packet[byte_index];
+ p_new_packet[p_rx_packet->length-1] = '\0';
+ }
+
+ app_notify(&index, &evt);
+
+ TFTP_MUTEX_UNLOCK();
+
+ TFTP_EXIT();
+
+ if (evt.param.err.code != TFTP_INVALID_TID)
+ {
+ instance_abort(index);
+ }
+
+ return evt.param.err.code;
+
+ default:
+ TFTP_ERR("Invalid TFTP packet opcode!");
+ handle_evt_err(index, TFTP_INVALID_PACKET, NULL);
+ break;
+ }
+
+ TFTP_EXIT();
+
+ return err_code;
+}
+
+/**@brief Count how many bytes are required to store options inside request packet.
+ *
+ * @param[in] index Index of TFTP instance.
+ * @param[in] type Type of TFTP request.
+ *
+ * @retval NRF_SUCCESS on successful execution of procedure, else an error code indicating reason
+ * for failure.
+ */
+static uint32_t count_options_length(uint32_t index, uint32_t type)
+{
+ uint32_t op_length = 0;
+ char next_retr_str[NEXT_RETR_MAX_LENGTH];
+ char block_size_str[BLKSIZE_MAX_LENGTH];
+ char file_size_str[FILE_SIZE_MAX_LENGTH];
+
+ if ((m_instances[index].init_params.next_retr > 0) &&
+ (m_instances[index].init_params.next_retr < 256))
+ {
+ UNUSED_VARIABLE(uint_to_str(m_instances[index].init_params.next_retr, next_retr_str, NEXT_RETR_MAX_LENGTH));
+ op_length += sizeof(OPTION_TIMEOUT); // Time out option length.
+ op_length += strlen(next_retr_str) + 1; // The '\0' character ate the end of a string.
+ }
+
+ if ((m_instances[index].init_params.block_size > 0) &&
+ (m_instances[index].init_params.block_size != TFTP_DEFAULT_BLOCK_SIZE))
+ {
+ UNUSED_VARIABLE(uint_to_str(m_instances[index].init_params.block_size, block_size_str, sizeof(block_size_str)));
+ op_length += sizeof(OPTION_BLKSIZE); // Time out option length.
+ op_length += strlen(block_size_str) + 1; // The '\0' character ate the end of a string.
+ }
+
+ op_length += sizeof(OPTION_SIZE); // TFTP tsize option length.
+
+ if (type == TYPE_RRQ)
+ {
+ op_length += sizeof(OPTION_SIZE_REQUEST_VALUE); // Just send 0 to inform other side that you support this option and would like to receive file size inside OptionACK.
+ }
+
+ if (type == TYPE_WRQ)
+ {
+ UNUSED_VARIABLE(uint_to_str(m_instances[index].p_file->file_size, file_size_str, sizeof(file_size_str)));
+ op_length += strlen(file_size_str) + 1;
+ }
+
+ if (m_instances[index].p_password != NULL)
+ {
+ if (m_instances[index].p_password[0] != '\0')
+ {
+ op_length += strlen(m_instances[index].p_password) + 1; // Password is always sent as last string without option name.
+ }
+ }
+
+ return op_length;
+}
+
+/**@brief This function inserts options into request packet payload using passed option iterator.
+ *
+ * @param[in] index Index of TFTP instance.
+ * @param[in] type Type of TFTP request.
+ * @param[in] p_iter Iterator which will be used to set options.
+ *
+ * @retval NRF_SUCCESS on successful execution of procedure, else an error code indicating reason
+ * for failure.
+ */
+static uint32_t insert_options(uint32_t index, uint32_t type, option_iter_t * p_iter)
+{
+ uint32_t err_code = NRF_SUCCESS;
+ char next_retr_str[NEXT_RETR_MAX_LENGTH];
+ char block_size_str[BLKSIZE_MAX_LENGTH];
+ char file_size_str[FILE_SIZE_MAX_LENGTH];
+
+ if (type == TYPE_RRQ)
+ {
+ err_code = op_set(p_iter, OPTION_SIZE, OPTION_SIZE_REQUEST_VALUE);
+ }
+
+ if (type == TYPE_WRQ)
+ {
+ UNUSED_VARIABLE(uint_to_str(m_instances[index].p_file->file_size, file_size_str, FILE_SIZE_MAX_LENGTH));
+ err_code = op_set(p_iter, OPTION_SIZE, file_size_str);
+ }
+
+ if (err_code == NRF_SUCCESS)
+ {
+ if ((m_instances[index].init_params.next_retr > 0) &&
+ (m_instances[index].init_params.next_retr < 256))
+ {
+ UNUSED_VARIABLE(uint_to_str(m_instances[index].init_params.next_retr, next_retr_str, NEXT_RETR_MAX_LENGTH));
+ err_code = op_set(p_iter, OPTION_TIMEOUT, next_retr_str);
+ if (err_code != NRF_SUCCESS)
+ {
+ return err_code;
+ }
+ }
+
+ if ((m_instances[index].init_params.block_size > 0) &&
+ (m_instances[index].init_params.block_size != TFTP_DEFAULT_BLOCK_SIZE))
+ {
+ UNUSED_VARIABLE(uint_to_str(m_instances[index].init_params.block_size, block_size_str, BLKSIZE_MAX_LENGTH));
+ err_code = op_set(p_iter, OPTION_BLKSIZE, block_size_str);
+ if (err_code != NRF_SUCCESS)
+ {
+ return err_code;
+ }
+ }
+
+ if (m_instances[index].p_password != NULL)
+ {
+ if (m_instances[index].p_password[0] != '\0')
+ {
+ err_code = op_set(p_iter, NULL, m_instances[index].p_password);
+ }
+ }
+ }
+
+ return err_code;
+}
+
+/**@Sends Read/Write TFTP Request.
+ *
+ * @param[in] type Type of request (allowed values: TYPE_RRQ and TYPE_WRQ).
+ * @param[in] p_tftp Pointer to the TFTP instance (from user space).
+ * @param[in] p_file Pointer to the file, which should be assigned to passed instance.
+ * @param[in] p_params Pointer to transmission parameters structure (retransmission time, block size).
+ *
+ * @retval NRF_SUCCESS on successful execution of procedure, else an error code indicating reason
+ * for failure.
+ */
+static uint32_t send_request(uint32_t type,
+ iot_tftp_t * p_tftp,
+ iot_file_t * p_file,
+ const char * p_path)
+{
+ uint32_t err_code;
+ iot_pbuffer_t * p_buffer;
+ iot_pbuffer_alloc_param_t buffer_param;
+ uint8_t * p_rrq_packet;
+ option_iter_t rrq_iter;
+ uint32_t index;
+ uint32_t byte_index;
+
+ err_code = find_instance(p_tftp, &index);
+ if (err_code != NRF_SUCCESS)
+ {
+ return err_code;
+ }
+
+ if (p_path == NULL || p_path[0] == '\0')
+ {
+ TFTP_ERR("[TFTP]: Invalid path passed.\r\n");
+ return (NRF_ERROR_INVALID_PARAM | IOT_TFTP_ERR_BASE);
+ }
+
+ if (p_file != NULL && p_file->p_filename[0] == '\0')
+ {
+ TFTP_ERR("Invalid file name passed!");
+ return (NRF_ERROR_INVALID_PARAM | IOT_TFTP_ERR_BASE);
+ }
+
+ if (m_instances[index].state != STATE_IDLE)
+ {
+ TFTP_ERR("Invalid instance state!");
+ return (NRF_ERROR_INVALID_STATE | IOT_TFTP_ERR_BASE);
+ }
+
+ // Assign file with TFTP instance.
+ m_instances[index].p_file = p_file;
+ m_instances[index].p_path = p_path;
+ m_instances[index].block_id = 0;
+ m_instances[index].dst_tid = m_instances[index].dst_port;
+
+ memset(&buffer_param, 0, sizeof(buffer_param));
+ buffer_param.type = UDP6_PACKET_TYPE;
+ buffer_param.flags = PBUFFER_FLAG_DEFAULT;
+
+ // Calculate size of required packet.
+ buffer_param.length = TFTP_HEADER_SIZE; // Bytes reserved for TFTP opcode value.
+ buffer_param.length += strlen(p_path) + 1; // File name with '\0' character.
+ buffer_param.length += sizeof(OPTION_MODE_OCTET); // Mode option value length.
+
+ TFTP_TRC("Estimated packet length without options: %ld.", buffer_param.length);
+
+ buffer_param.length += count_options_length(index, type); // TFTP options.
+
+ TFTP_TRC("Estimated packet length with options: %ld.", buffer_param.length);
+
+ // Allocate packet buffer.
+ err_code = iot_pbuffer_allocate(&buffer_param, &p_buffer);
+ if (err_code != NRF_SUCCESS)
+ {
+ return err_code;
+ }
+
+ memset(p_buffer->p_payload, 0, buffer_param.length);
+ byte_index = 0;
+
+ // Compose TFTP Read Request according to configuration.
+ p_rrq_packet = p_buffer->p_payload;
+ uint16_t size = uint16_encode(HTONS(type), &p_rrq_packet[byte_index]);
+ byte_index += size;
+
+ // Initialization of option iterator.
+ op_init(&rrq_iter, (char *)&p_rrq_packet[byte_index], buffer_param.length - TFTP_HEADER_SIZE); // Options uses whole packet except opcode.
+ rrq_iter.p_start[0] = '\0';
+
+ // Insert file path and mode strings.
+ err_code = op_set(&rrq_iter, NULL, p_path);
+ PBUFFER_FREE_IF_ERROR(err_code);
+
+ err_code = op_set(&rrq_iter, NULL, OPTION_MODE_OCTET);
+ PBUFFER_FREE_IF_ERROR(err_code);
+
+ // Insert TFTP options into packet.
+ err_code = insert_options(index, type, &rrq_iter);
+ PBUFFER_FREE_IF_ERROR(err_code);
+
+ // Change instance status to connecting.
+ if (type == TYPE_RRQ)
+ {
+ m_instances[index].state = STATE_CONNECTING_RRQ;
+ }
+ else
+ {
+ m_instances[index].state = STATE_CONNECTING_WRQ;
+ }
+
+ // Send read request.
+ UNUSED_VARIABLE(retr_timer_reset(index));
+ err_code = udp6_socket_sendto(&m_instances[index].socket,
+ &m_instances[index].addr,
+ m_instances[index].dst_tid,
+ p_buffer);
+
+ if (err_code != NRF_SUCCESS)
+ {
+ TFTP_ERR("Unable to send request!");
+ m_instances[index].state = STATE_IDLE;
+ }
+
+ PBUFFER_FREE_IF_ERROR(err_code);
+
+ return NRF_SUCCESS;
+}
+
+/**@brief Function used in order to change initial connection parameters. */
+uint32_t iot_tftp_set_params(iot_tftp_t * p_tftp, iot_tftp_trans_params_t * p_params)
+{
+ uint32_t err_code;
+ uint32_t index;
+
+ NULL_PARAM_CHECK(p_params);
+ NULL_PARAM_CHECK(p_tftp);
+
+ TFTP_ENTRY();
+
+ TFTP_MUTEX_LOCK();
+
+ err_code = find_instance(p_tftp, &index);
+ if (err_code == NRF_SUCCESS)
+ {
+ // Modifying connection parameters could be done only when TFTP instance is disconnected.
+ // NOTE: STATE_FREE is not allowed, because there have to be a moment (e.g. after calling iot_tftp_init()) when transmission parameters were set to default values.
+ if (m_instances[index].state == STATE_IDLE)
+ {
+ // Reset connection parameters to initial values. They will be set (negotiated) after get/put call.
+ memcpy(&m_instances[index].init_params, p_params, sizeof(iot_tftp_trans_params_t));
+ }
+ else
+ {
+ err_code = (NRF_ERROR_INVALID_STATE | IOT_TFTP_ERR_BASE);
+
+ TFTP_ERR("Cannot modify connection parameters inside %d state!", m_instances[index].state);
+ }
+ }
+ else
+ {
+ TFTP_ERR("Unable to find TFTP instance!");
+ }
+
+ TFTP_MUTEX_UNLOCK();
+
+ TFTP_EXIT();
+
+ return err_code;
+}
+
+/**@brief Function for performing retransmissions of TFTP acknowledgments. */
+void iot_tftp_timeout_process(iot_timer_time_in_ms_t wall_clock_value)
+{
+ uint32_t index;
+ uint32_t err_code;
+
+ UNUSED_PARAMETER(wall_clock_value);
+
+ TFTP_MUTEX_LOCK();
+
+ for (index = 0; index < TFTP_MAX_INSTANCES; index++)
+ {
+ if ((m_instances[index].state == STATE_CONNECTING_RRQ) ||
+ (m_instances[index].state == STATE_CONNECTING_WRQ) ||
+ (m_instances[index].state == STATE_SENDING) ||
+ (m_instances[index].state == STATE_RECEIVING))
+ {
+ TFTP_ENTRY();
+ TFTP_TRC("Current timer: %ld, %ld", m_instances[index].request_timeout, wall_clock_value);
+
+ if (instance_timer_is_expired(index))
+ {
+ err_code = NRF_SUCCESS;
+
+ if (m_instances[index].retries < TFTP_MAX_RETRANSMISSION_COUNT)
+ {
+ TFTP_TRC("Query retransmission [%d] for file %s.",
+ m_instances[index].retries, m_instances[index].p_file->p_filename);
+
+ // Increase retransmission number.
+ m_instances[index].retries++;
+
+ TFTP_TRC("Compose packet for retransmission.");
+ // Send packet again.
+ if (m_instances[index].state == STATE_RECEIVING)
+ {
+ TFTP_TRC("Retransmission of ACK packet.");
+ err_code = create_ack_packet(index, m_instances[index].block_id);
+
+ if (err_code == NRF_SUCCESS)
+ {
+ err_code = send_response(&index);
+ }
+ else
+ {
+ TFTP_ERR("Failed to create packet!");
+ handle_evt_err(index, err_code, NULL);
+ }
+ }
+ else if (m_instances[index].state == STATE_SENDING)
+ {
+ TFTP_TRC("Retransmission of DATA packet.");
+ err_code = create_data_packet(index, m_instances[index].block_id - 1);
+
+ if (err_code == NRF_SUCCESS)
+ {
+ if (m_instances[index].p_file->p_callback == NULL)
+ {
+ err_code = send_response(&index);
+ }
+ }
+ else
+ {
+ TFTP_ERR("Failed to create packet!");
+ handle_evt_err(index, err_code, NULL);
+ }
+ }
+ else if (m_instances[index].state == STATE_CONNECTING_RRQ)
+ {
+ TFTP_TRC("OACK time out. Retransmit RRQ.");
+ m_instances[index].state = STATE_IDLE;
+ err_code = send_request(TYPE_RRQ, &index, m_instances[index].p_file, m_instances[index].p_path);
+ }
+ else if (m_instances[index].state == STATE_CONNECTING_WRQ)
+ {
+ TFTP_TRC("OACK time out. Retransmit WRQ.");
+ m_instances[index].state = STATE_IDLE;
+ err_code = send_request(TYPE_WRQ, &index, m_instances[index].p_file, NULL);
+ }
+ else
+ {
+ TFTP_TRC("In idle state.");
+ }
+ }
+ else
+ {
+ TFTP_ERR("TFTP server did not response on query for file %s.",
+ m_instances[index].p_file->p_filename);
+
+ // No response from server.
+ err_code = TFTP_REMOTE_UNREACHABLE;
+ }
+
+ if (err_code != NRF_SUCCESS)
+ {
+ // Inform application that timeout occurs.
+ TFTP_ERR("Timeout error.");
+ handle_evt_err(index, err_code, NULL);
+ }
+ }
+ TFTP_MUTEX_UNLOCK();
+
+ TFTP_EXIT();
+
+ return;
+ }
+ }
+
+ TFTP_MUTEX_UNLOCK();
+}
+
+/**@brief Initializes TFTP client. */
+uint32_t iot_tftp_init(iot_tftp_t * p_tftp, iot_tftp_init_t * p_init_params)
+{
+ uint32_t index = 0;
+ uint32_t err_code;
+
+ NULL_PARAM_CHECK(p_tftp);
+ NULL_PARAM_CHECK(p_init_params);
+ NULL_PARAM_CHECK(p_init_params->p_ipv6_addr);
+
+ TFTP_ENTRY();
+
+ TFTP_MUTEX_LOCK();
+
+ // Find first available instance.
+ err_code = find_free_instance(&index);
+ if (err_code == NRF_SUCCESS)
+ {
+ // Reset instance values.
+ instance_reset(index);
+
+ // Assign new values.
+ *p_tftp = index;
+ m_instances[index].callback = p_init_params->callback;
+ m_instances[index].src_tid = p_init_params->src_port;
+ m_instances[index].dst_port = p_init_params->dst_port;
+ m_instances[index].p_password = p_init_params->p_password;
+ m_instances[index].dst_tid = m_instances[index].dst_port;
+ memcpy(&m_instances[index].addr, p_init_params->p_ipv6_addr, sizeof(ipv6_addr_t));
+
+ // Configure socket.
+ err_code = udp6_socket_allocate(&m_instances[index].socket);
+ if (err_code == NRF_SUCCESS)
+ {
+ err_code = udp6_socket_bind(&m_instances[index].socket,
+ IPV6_ADDR_ANY,
+ p_init_params->src_port);
+ if (err_code == NRF_SUCCESS)
+ {
+ // Attach callback.
+ err_code = udp6_socket_recv(&m_instances[index].socket, client_process);
+ if (err_code == NRF_SUCCESS)
+ {
+ m_instances[index].state = STATE_IDLE;
+ }
+ }
+
+ if (err_code != NRF_SUCCESS)
+ {
+ (void)udp6_socket_free(&m_instances[index].socket);
+
+ TFTP_ERR("UDP socket configuration failure!");
+ }
+ }
+ }
+ else
+ {
+ TFTP_ERR("No more free instances left!");
+ }
+
+ TFTP_MUTEX_UNLOCK();
+
+ TFTP_EXIT();
+
+ return err_code;
+}
+
+/**@brief Resets TFTP client instance, so it is possible to make another request after error. */
+uint32_t iot_tftp_abort(iot_tftp_t * p_tftp)
+{
+ uint32_t err_code;
+ uint32_t index;
+
+ NULL_PARAM_CHECK(p_tftp);
+
+ TFTP_ENTRY();
+
+ TFTP_MUTEX_LOCK();
+
+ err_code = find_instance(p_tftp, &index);
+ if (err_code == NRF_SUCCESS)
+ {
+ instance_abort(index);
+ }
+
+ TFTP_MUTEX_UNLOCK();
+
+ TFTP_EXIT();
+
+ return err_code;
+}
+
+/**@brief Frees assigned sockets. */
+uint32_t iot_tftp_uninit(iot_tftp_t * p_tftp)
+{
+ uint32_t err_code;
+ uint32_t index;
+
+ NULL_PARAM_CHECK(p_tftp);
+
+ TFTP_ENTRY();
+
+ TFTP_MUTEX_LOCK();
+
+ err_code = find_instance(p_tftp, &index);
+ if (err_code == NRF_SUCCESS)
+ {
+ if (m_instances[index].state == STATE_SEND_HOLD ||
+ m_instances[index].state == STATE_RECV_HOLD ||
+ m_instances[index].state == STATE_SENDING ||
+ m_instances[index].state == STATE_RECEIVING)
+ {
+ // Free pbuffer.
+ err_code = iot_pbuffer_free(m_instances[index].p_packet, true);
+ if (err_code != NRF_SUCCESS)
+ {
+ TFTP_ERR("Cannot free pbuffer - %p", m_instances[index].p_packet);
+ }
+
+ err_code = iot_file_fclose(m_instances[index].p_file);
+ if (err_code != NRF_SUCCESS)
+ {
+ TFTP_ERR("Cannot close file - %p", m_instances[index].p_file);
+ }
+ }
+
+ if (m_instances[index].state != STATE_IDLE)
+ {
+ handle_evt_err(index, TFTP_UNDEFINED_ERROR, UNINT_ERROR_MSG);
+ }
+
+ (void)udp6_socket_free(&m_instances[index].socket);
+ m_instances[index].state = STATE_FREE;
+ }
+
+ TFTP_MUTEX_UNLOCK();
+
+ TFTP_EXIT();
+
+ return err_code;
+}
+
+/**@brief Retrieves file from remote server into p_file. */
+uint32_t iot_tftp_get(iot_tftp_t * p_tftp, iot_file_t * p_file, const char * p_path)
+{
+ uint32_t err_code;
+
+ NULL_PARAM_CHECK(p_tftp);
+ NULL_PARAM_CHECK(p_path);
+ if (p_file != NULL)
+ {
+ NULL_PARAM_CHECK(p_file->p_filename);
+ }
+
+ TFTP_ENTRY();
+
+ TFTP_MUTEX_LOCK();
+
+ err_code = send_request(TYPE_RRQ, p_tftp, p_file, p_path);
+ if (err_code != NRF_SUCCESS)
+ {
+ TFTP_ERR("Error while sending read request. Reason: %08lx.", err_code);
+ }
+
+ TFTP_MUTEX_UNLOCK();
+
+ TFTP_EXIT();
+
+ return err_code;
+}
+
+/**@brief Sends local file p_file to a remote server. */
+uint32_t iot_tftp_put(iot_tftp_t * p_tftp, iot_file_t * p_file, const char * p_path)
+{
+ uint32_t err_code;
+
+ NULL_PARAM_CHECK(p_tftp);
+ NULL_PARAM_CHECK(p_file);
+ NULL_PARAM_CHECK(p_file->p_filename);
+
+ TFTP_ENTRY();
+
+ TFTP_MUTEX_LOCK();
+
+ err_code = send_request(TYPE_WRQ, p_tftp, p_file, p_path);
+ if (err_code != NRF_SUCCESS)
+ {
+ TFTP_ERR("Error while sending write request. Reason: %08lx.", err_code);
+ }
+
+ TFTP_MUTEX_UNLOCK();
+
+ TFTP_EXIT();
+
+ return err_code;
+}
+
+/**@brief Holds transmission of ACK (use in order to slow transmission). */
+uint32_t iot_tftp_hold(iot_tftp_t * p_tftp)
+{
+ uint32_t index;
+ uint32_t err_code;
+
+ NULL_PARAM_CHECK(p_tftp);
+
+ TFTP_ENTRY();
+
+ TFTP_MUTEX_LOCK();
+
+ err_code = find_instance(p_tftp, &index);
+ if (err_code == NRF_SUCCESS)
+ {
+ // Hold transfer.
+ err_code = transfer_hold(index);
+ }
+ else
+ {
+ TFTP_ERR("Hold called on unknown TFTP instance.");
+ }
+
+ TFTP_MUTEX_UNLOCK();
+
+ TFTP_EXIT();
+
+ return err_code;
+}
+
+/**@brief Resumes transmission. */
+uint32_t iot_tftp_resume(iot_tftp_t * p_tftp)
+{
+ uint32_t index;
+ uint32_t err_code;
+
+ NULL_PARAM_CHECK(p_tftp);
+
+ TFTP_ENTRY();
+
+ TFTP_MUTEX_LOCK();
+
+ err_code = find_instance(p_tftp, &index);
+ if (err_code == NRF_SUCCESS)
+ {
+ err_code = transfer_resume(index);
+ }
+ else
+ {
+ TFTP_ERR("Failed to find instance.");
+ }
+
+ TFTP_MUTEX_UNLOCK();
+
+ TFTP_EXIT();
+
+ return err_code;
+}
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/ipv6_stack/tftp/iot_tftp.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/ipv6_stack/tftp/iot_tftp.h
new file mode 100644
index 0000000..0405af2
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/ipv6_stack/tftp/iot_tftp.h
@@ -0,0 +1,245 @@
+/**
+ * Copyright (c) 2015 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 iot_tftp.h
+ *
+ * @defgroup iot_tftp TFTP Application Interface for Nordic's IPv6 stack
+ * @ingroup iot_sdk_stack
+ * @{
+ * @brief Trivial File Transfer Protocol module provides implementation of TFTP Client.
+ *
+ */
+
+#ifndef IOT_TFTP_H__
+#define IOT_TFTP_H__
+
+#include "sdk_common.h"
+#include "iot_common.h"
+#include "iot_timer.h"
+#include "iot_file.h"
+#include "iot_defines.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**@brief TFTP global instance number. */
+typedef uint32_t iot_tftp_t;
+
+/**@brief TFTP module Events. */
+typedef enum
+{
+ IOT_TFTP_EVT_ERROR, /**< Event code indicating that an error occurred. */
+ IOT_TFTP_EVT_TRANSFER_DATA_RECEIVED, /**< Event code indicating that a data packet was received during read transfer. */
+ IOT_TFTP_EVT_TRANSFER_GET_COMPLETE, /**< Event code indicating that transfer read was completed. */
+ IOT_TFTP_EVT_TRANSFER_PUT_COMPLETE, /**< Event code indicating that transfer write was completed. */
+} iot_tftp_evt_id_t;
+
+/**@brief TFTP error event structure. */
+typedef struct
+{
+ uint32_t code; /**< Error code. */
+ char * p_msg; /**< Message describing the reason or NULL if no description is available. */
+ uint32_t size_transfered; /**< In case of an error, variable indicates a number of successfully read or write bytes. */
+} iot_tftp_evt_err_t;
+
+/**@brief TFTP data received event structure. */
+typedef struct
+{
+ uint8_t * p_data; /**< Pointer to received data chunk. */
+ uint16_t size; /**< Size of received data chunk. */
+} iot_tftp_evt_data_received_t;
+
+/**@brief TFTP event structure. */
+typedef union
+{
+ iot_tftp_evt_err_t err; /**< Error event structure. Used only in case of IOT_TFTP_EVT_ERROR error. */
+ iot_tftp_evt_data_received_t data_received; /**< Data received event structure. Used only in case of IOT_TFTP_EVT_TRANSFER_DATA_RECEIVED event. */
+} iot_tftp_evt_param_t;
+
+/**@brief Asynchronous event type. */
+typedef struct
+{
+ iot_tftp_evt_id_t id; /**< Event code. */
+ iot_tftp_evt_param_t param; /**< Union to structures describing event. */
+ iot_file_t * p_file; /**< File associated with TFTP transfer. */
+} iot_tftp_evt_t;
+
+/**@brief TFTP Transmission initialization structure (both GET and PUT). */
+typedef struct
+{
+ uint32_t next_retr; /**< Number of seconds between retransmissions. */
+ uint16_t block_size; /**< Maximum or negotiated size of data block. */
+} iot_tftp_trans_params_t;
+
+/**@brief User callback from TFTP module.
+ *
+ * @note TFTP module user callback will be invoked even if user asks TFTP to abort (TFTP error event).
+ *
+ * @param[in] p_tftp Pointer to the TFTP instance.
+ * @param[in] p_evt Pointer to the TFTP event structure, describing reason.
+ *
+ * @retval None.
+ */
+typedef void (*iot_tftp_callback_t)(iot_tftp_t * p_tftp, iot_tftp_evt_t * p_evt);
+
+
+/**@brief TFTP initialization structure. */
+typedef struct
+{
+ ipv6_addr_t * p_ipv6_addr; /**< IPv6 address of the server. */
+ uint16_t src_port; /**< Source port (local UDP port) from which all request and data will be sent. Should be choosen randomly. */
+ uint16_t dst_port; /**< Destination port - UDP port on which server listens for new connections. */
+ iot_tftp_callback_t callback; /**< Reference to the user callback. */
+ const char * p_password; /**< Server password for all requests. Shall be NULL if no password is required. */
+} iot_tftp_init_t;
+
+
+/**@brief Initializes TFTP client.
+ *
+ * @param[in] p_tftp Pointer to the TFTP instance. Should not be NULL.
+ * @param[in] p_init_params Initialization structure for TFTP client. Should not be NULL.
+ *
+ * @retval NRF_SUCCESS on successful execution of procedure, else an error code indicating reason
+ * for failure.
+ */
+uint32_t iot_tftp_init(iot_tftp_t * p_tftp, iot_tftp_init_t * p_init_params);
+
+
+/**@brief Function used in order to change initial connection parameters.
+ *
+ * @param[in] p_tftp Reference to the TFTP instance.
+ * @param[in] p_params Pointer to transmission parameters structure. Should not be NULL.
+ *
+ * @retval NRF_SUCCESS if parameters successfully set, else an error code indicating reason
+ * for failure.
+ */
+uint32_t iot_tftp_set_params(iot_tftp_t * p_tftp, iot_tftp_trans_params_t * p_params);
+
+
+/**@brief Retrieves file from remote server into p_file.
+ *
+ * If @p p_file is a NULL pointer, the content of received file can be retrieved by handling
+ * @ref IOT_TFTP_EVT_TRANSFER_DATA_RECEIVED event. This event is generated each time a data
+ * packet (containing a chunk of requested file) is received.
+ * IOT_TFTP_EVT_TRANSFER_GET_COMPLETE event is generated after download is complete.
+ *
+ * @note This function should not be called until previous download operation is completed.
+ *
+ * @param[in] p_tftp Pointer to the TFTP instance.
+ * @param[in] p_file Reference to the file from which data should be read.
+ * @param[in] p_path Path of the requested file on the remote server. Shall not be NULL.
+ *
+ * @retval NRF_SUCCESS on successful execution of procedure, else an error code indicating reason
+ * for failure.
+ */
+uint32_t iot_tftp_get(iot_tftp_t * p_tftp, iot_file_t * p_file, const char * p_path);
+
+
+/**@brief Sends local file p_file to a remote server.
+ *
+ * @param[in] p_tftp Pointer to the TFTP instance.
+ * @param[in] p_file Reference to the file to which data should be stored. Should not be NULL.
+ * @param[in] p_path Path of the file on the remote server. Shall not be NULL.
+ *
+ * @retval NRF_SUCCESS on successful execution of procedure, else an error code indicating reason
+ * for failure.
+ */
+uint32_t iot_tftp_put(iot_tftp_t * p_tftp, iot_file_t * p_file, const char * p_path);
+
+
+/**@brief Holds transmission of ACK (use in order to slow transmission).
+ *
+ * @param[in] p_tftp Pointer to the TFTP instance.
+ *
+ * @retval NRF_SUCCESS on successful execution of procedure, else an error code indicating reason
+ * for failure.
+ */
+uint32_t iot_tftp_hold(iot_tftp_t * p_tftp);
+
+
+/**@brief Resumes transmission.
+ *
+ * @param[in] p_tftp Pointer to the TFTP instance.
+ *
+ * @retval NRF_SUCCESS on successful execution of procedure, else an error code indicating reason
+ * for failure.
+ */
+uint32_t iot_tftp_resume(iot_tftp_t * p_tftp);
+
+
+/**@brief Resets TFTP client instance, so it is possible to make another request after error.
+ *
+ * @param[in] p_tftp Pointer to the TFTP instance.
+ *
+ * @retval NRF_SUCCESS on successful execution of procedure, else an error code indicating reason
+ * for failure.
+ */
+uint32_t iot_tftp_abort(iot_tftp_t * p_tftp);
+
+
+/**@brief Frees assigned sockets.
+ *
+ * @param[in] p_tftp Pointer to the TFTP instance.
+ *
+ * @retval NRF_SUCCESS on successful execution of procedure, else an error code indicating reason
+ * for failure.
+ */
+uint32_t iot_tftp_uninit(iot_tftp_t * p_tftp);
+
+
+/**@brief Function for performing retransmissions of TFTP acknowledgments.
+ *
+ * @note TFTP module implements the retransmission mechanism by invoking this function periodically.
+ * So that method has to be added to IoT Timer client list and has to be called with minimum of
+ * TFTP_RETRANSMISSION_INTERVAL resolution.
+ *
+ * @param[in] wall_clock_value The value of the wall clock that triggered the callback.
+ *
+ * @retval None.
+ */
+void iot_tftp_timeout_process(iot_timer_time_in_ms_t wall_clock_value);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // IOT_TFTP_H__
+
+/** @} */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/ipv6_stack/udp/udp.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/ipv6_stack/udp/udp.h
new file mode 100644
index 0000000..ae316b0
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/ipv6_stack/udp/udp.h
@@ -0,0 +1,98 @@
+/**
+ * Copyright (c) 2014 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+/** @cond */
+ /** @file udp.h
+ *
+ * @defgroup iot_udp UDP Module Header.
+ * @ingroup iot_sdk
+ * @{
+ * @brief User Datagram Protocol module header defining interface between
+ * UDP and other IP stack layers which are not exposed to the application.
+ */
+
+#ifndef UDP_H__
+#define UDP_H__
+
+#include "sdk_config.h"
+#include "sdk_common.h"
+#include "ipv6_api.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @brief Module initialization function called from ipv6_init(). This shall not be called by the
+ * application explicitly.
+ *
+ * @retval NRF_SUCCESS on successful execution of procedure, else an error code indicating reason
+ * for failure.
+ */
+uint32_t udp_init(void);
+
+
+/**
+ * @brief Function to feed incoming UDP packets to the module. To be called by the IPv6
+ * stack only and never by the application.
+ *
+ * @param[in] p_interface Identifies network interface on which the packet is received.
+ * @param[in] p_ip_header IP Header of the UDP packet being fed to the module.
+ * @param[in] p_packet UDP packet being notified to the module. p_packet->p_payload points the
+ * IPv6 payload and p_packet->length indicates total length of the payload.
+ *
+ * @note This routine is called by the stack with next header field value is set to UDP protocol
+ * value of 17.
+ *
+ * @retval NRF_SUCCESS on successful handling of the packet, else an error code indicating reason
+ * for failure.
+ */
+uint32_t udp_input(const iot_interface_t * p_interface,
+ const ipv6_header_t * p_ip_header,
+ iot_pbuffer_t * p_packet);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif //UDP_H__
+
+/**@} */
+
+/** @endcond */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/ipv6_stack/udp/udp6.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/ipv6_stack/udp/udp6.c
new file mode 100644
index 0000000..0572c4a
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/ipv6_stack/udp/udp6.c
@@ -0,0 +1,708 @@
+/**
+ * Copyright (c) 2014 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#include "nordic_common.h"
+#include "sdk_common.h"
+#include "sdk_config.h"
+#include "iot_common.h"
+#include "iot_pbuffer.h"
+#include "udp_api.h"
+#include "udp.h"
+#include "ipv6_utils.h"
+
+#if UDP6_CONFIG_LOG_ENABLED
+
+#define NRF_LOG_MODULE_NAME udp6
+
+#define NRF_LOG_LEVEL UDP6_CONFIG_LOG_LEVEL
+#define NRF_LOG_INFO_COLOR UDP6_CONFIG_INFO_COLOR
+#define NRF_LOG_DEBUG_COLOR UDP6_CONFIG_DEBUG_COLOR
+
+#include "nrf_log.h"
+NRF_LOG_MODULE_REGISTER();
+
+#define UDP6_TRC NRF_LOG_DEBUG /**< Used for getting trace of execution in the module. */
+#define UDP6_ERR NRF_LOG_ERROR /**< Used for logging errors in the module. */
+#define UDP6_DUMP NRF_LOG_HEXDUMP_DEBUG /**< Used for dumping octet information to get details of bond information etc. */
+
+#define UDP6_ENTRY() UDP6_TRC(">> %s", __func__)
+#define UDP6_EXIT() UDP6_TRC("<< %s", __func__)
+
+#else // UDP6_CONFIG_LOG_ENABLED
+
+#define UDP6_TRC(...) /**< Disables traces. */
+#define UDP6_DUMP(...) /**< Disables dumping of octet streams. */
+#define UDP6_ERR(...) /**< Disables error logs. */
+
+#define UDP6_ENTRY(...)
+#define UDP6_EXIT(...)
+
+#endif // UDP6_CONFIG_LOG_ENABLED
+
+/**
+ * @defgroup api_param_check API Parameters check macros.
+ *
+ * @details Macros that verify parameters passed to the module in the APIs. These macros
+ * could be mapped to nothing in final versions of code to save execution and size.
+ * UDP_DISABLE_API_PARAM_CHECK should be set to 1 to disable these checks.
+ *
+ * @{
+ */
+#if (UDP6_DISABLE_API_PARAM_CHECK == 0)
+
+/**@brief Macro to check is module is initialized before requesting one of the module procedures. */
+#define VERIFY_MODULE_IS_INITIALIZED() \
+ if (m_initialization_state == false) \
+ { \
+ return (SDK_ERR_MODULE_NOT_INITIALIZED | IOT_UDP6_ERR_BASE); \
+ }
+
+/**@brief Macro to check is module is initialized before requesting one of the module
+ procedures but does not use any return code. */
+#define VERIFY_MODULE_IS_INITIALIZED_VOID() \
+ if (m_initialization_state == false) \
+ { \
+ return; \
+ }
+
+/**
+ * @brief Verify NULL parameters are not passed to API by application.
+ */
+#define NULL_PARAM_CHECK(PARAM) \
+ if ((PARAM) == NULL) \
+ { \
+ return (NRF_ERROR_NULL | IOT_UDP6_ERR_BASE); \
+ }
+
+/**
+ * @brief Verify socket id passed on the API by application is valid.
+ */
+#define VERIFY_SOCKET_ID(ID) \
+ if (((ID) >= UDP6_MAX_SOCKET_COUNT)) \
+ { \
+ return (NRF_ERROR_INVALID_ADDR | IOT_UDP6_ERR_BASE); \
+ }
+
+/**
+ * @brief Verify socket id passed on the API by application is valid.
+ */
+#define VERIFY_PORT_NUMBER(PORT) \
+ if ((PORT) == 0) \
+ { \
+ return (NRF_ERROR_INVALID_PARAM | IOT_UDP6_ERR_BASE); \
+ }
+
+/**
+ * @brief Verify socket id passed on the API by application is valid.
+ */
+#define VERIFY_NON_ZERO_LENGTH(LEN) \
+ if ((LEN) == 0) \
+ { \
+ return (NRF_ERROR_INVALID_LENGTH | IOT_UDP6_ERR_BASE); \
+ }
+
+#else // UDP6_DISABLE_API_PARAM_CHECK
+
+#define VERIFY_MODULE_IS_INITIALIZED()
+#define VERIFY_MODULE_IS_INITIALIZED_VOID()
+#define NULL_PARAM_CHECK(PARAM)
+#define VERIFY_SOCKET_ID(ID)
+#endif //UDP6_DISABLE_API_PARAM_CHECK
+
+/**
+ * @defgroup ble_ipsp_mutex_lock_unlock Module's Mutex Lock/Unlock Macros.
+ *
+ * @details Macros used to lock and unlock modules. Currently, SDK does not use mutexes but
+ * framework is provided in case need arises to use an alternative architecture.
+ * @{
+ */
+#define UDP_MUTEX_LOCK() SDK_MUTEX_LOCK(m_udp_mutex) /**< Lock module using mutex */
+#define UDP_MUTEX_UNLOCK() SDK_MUTEX_UNLOCK(m_udp_mutex) /**< Unlock module using mutex */
+/** @} */
+
+#define UDP_PORT_FREE 0 /**< Reserved port of the socket, indicates that port is free. */
+
+/**@brief UDP Socket Data needed by the module to manage it. */
+typedef struct
+{
+ uint16_t local_port; /**< Local Port of the socket. */
+ uint16_t remote_port; /**< Remote port of the socket. */
+ ipv6_addr_t local_addr; /**< Local IPv6 Address of the socket. */
+ ipv6_addr_t remote_addr; /**< Remote IPv6 Address of the socket. */
+ udp6_handler_t rx_cb; /**< Callback registered by application to receive data on the socket. */
+ void * p_app_data; /**< Application data mapped to the socket using the udp6_app_data_set. */
+} udp_socket_entry_t;
+
+
+SDK_MUTEX_DEFINE(m_udp_mutex) /**< Mutex variable. Currently unused, this declaration does not occupy any space in RAM. */
+static bool m_initialization_state = false; /**< Variable to maintain module initialization state. */
+static udp_socket_entry_t m_socket[UDP6_MAX_SOCKET_COUNT]; /**< Table of sockets managed by the module. */
+
+
+/** @brief Initializes socket managed by the module. */
+static void udp_socket_init(udp_socket_entry_t * p_socket)
+{
+ p_socket->local_port = UDP_PORT_FREE;
+ p_socket->remote_port = UDP_PORT_FREE;
+ p_socket->rx_cb = NULL;
+ p_socket->p_app_data = NULL;
+ IPV6_ADDRESS_INITIALIZE(&p_socket->local_addr);
+ IPV6_ADDRESS_INITIALIZE(&p_socket->remote_addr);
+}
+
+/**
+ * @brief Find UDP socket based on local port. If found its index to m_socket table is returned.
+ * else UDP6_MAX_SOCKET_COUNT is returned.
+ */
+static uint32_t socket_find(uint16_t port)
+{
+ uint32_t index;
+
+ for (index = 0; index < UDP6_MAX_SOCKET_COUNT; index++)
+ {
+ if (m_socket[index].local_port == port)
+ {
+ break;
+ }
+ }
+
+ return index;
+}
+
+
+uint32_t udp_init(void)
+{
+ uint32_t index;
+
+ UDP6_ENTRY();
+
+ SDK_MUTEX_INIT(m_udp_mutex);
+
+ UDP_MUTEX_LOCK();
+
+ for (index = 0; index < UDP6_MAX_SOCKET_COUNT; index++)
+ {
+ udp_socket_init(&m_socket[index]);
+ }
+
+ m_initialization_state = true;
+
+ UDP6_EXIT();
+
+ UDP_MUTEX_UNLOCK();
+
+ return NRF_SUCCESS;
+}
+
+
+uint32_t udp6_socket_allocate(udp6_socket_t * p_socket)
+{
+ VERIFY_MODULE_IS_INITIALIZED();
+ NULL_PARAM_CHECK(p_socket);
+
+ UDP6_ENTRY();
+
+ UDP_MUTEX_LOCK();
+
+ //Search for an unassigned socket.
+ const uint32_t socket_id = socket_find(UDP_PORT_FREE);
+ uint32_t err_code = NRF_SUCCESS;
+
+ if (socket_id != UDP6_MAX_SOCKET_COUNT)
+ {
+ UDP6_TRC("Assigned socket 0x%08lX", socket_id);
+
+ // Found a free socket. Assign.
+ p_socket->socket_id = socket_id;
+ }
+ else
+ {
+ // No free socket found.
+ UDP6_ERR("No room for new socket.");
+ err_code = (NRF_ERROR_NO_MEM | IOT_UDP6_ERR_BASE);
+ }
+
+ UDP_MUTEX_UNLOCK();
+
+ UDP6_EXIT();
+
+ return err_code;
+}
+
+
+uint32_t udp6_socket_free(const udp6_socket_t * p_socket)
+{
+ VERIFY_MODULE_IS_INITIALIZED();
+ NULL_PARAM_CHECK(p_socket);
+ VERIFY_SOCKET_ID(p_socket->socket_id);
+
+ UDP6_ENTRY();
+
+ UDP_MUTEX_LOCK();
+
+ udp_socket_init(&m_socket[p_socket->socket_id]);
+
+ UDP_MUTEX_UNLOCK();
+
+ UDP6_EXIT();
+
+ return NRF_SUCCESS;
+}
+
+
+uint32_t udp6_socket_recv(const udp6_socket_t * p_socket,
+ const udp6_handler_t callback)
+{
+ VERIFY_MODULE_IS_INITIALIZED();
+ NULL_PARAM_CHECK(p_socket);
+ NULL_PARAM_CHECK(callback);
+ VERIFY_SOCKET_ID(p_socket->socket_id);
+ VERIFY_PORT_NUMBER(m_socket[p_socket->socket_id].local_port);
+
+ UDP6_ENTRY();
+
+ UDP_MUTEX_LOCK();
+
+ m_socket[p_socket->socket_id].rx_cb = callback;
+
+ UDP_MUTEX_UNLOCK();
+
+ UDP6_EXIT();
+
+ return NRF_SUCCESS;
+}
+
+
+uint32_t udp6_socket_bind(const udp6_socket_t * p_socket,
+ const ipv6_addr_t * p_src_addr,
+ uint16_t src_port)
+{
+ VERIFY_MODULE_IS_INITIALIZED();
+ NULL_PARAM_CHECK(p_socket);
+ NULL_PARAM_CHECK(p_src_addr);
+ VERIFY_SOCKET_ID(p_socket->socket_id);
+ VERIFY_PORT_NUMBER(src_port);
+
+ UDP6_ENTRY();
+
+ UDP_MUTEX_LOCK();
+
+ uint32_t err_code = NRF_SUCCESS;
+
+ // Change Host Byte Order to Network Byte Order.
+ src_port = HTONS(src_port);
+
+ //Check if port is already registered.
+ for (uint32_t index = 0; index < UDP6_MAX_SOCKET_COUNT; index ++)
+ {
+ if (m_socket[index].local_port == src_port)
+ {
+ err_code = UDP_PORT_IN_USE;
+ }
+ }
+
+ if (err_code == NRF_SUCCESS)
+ {
+ m_socket[p_socket->socket_id].local_port = src_port;
+ m_socket[p_socket->socket_id].local_addr = (*p_src_addr);
+
+ }
+ UDP_MUTEX_UNLOCK();
+
+ UDP6_EXIT();
+
+ return err_code;
+}
+
+
+uint32_t udp6_socket_connect(const udp6_socket_t * p_socket,
+ const ipv6_addr_t * p_dest_addr,
+ uint16_t dest_port)
+{
+ VERIFY_MODULE_IS_INITIALIZED();
+ NULL_PARAM_CHECK(p_socket);
+ NULL_PARAM_CHECK(p_dest_addr);
+ VERIFY_SOCKET_ID(p_socket->socket_id);
+ VERIFY_PORT_NUMBER(dest_port);
+ VERIFY_PORT_NUMBER(m_socket[p_socket->socket_id].local_port);
+
+ UDP6_ENTRY();
+
+ UDP_MUTEX_LOCK();
+
+ m_socket[p_socket->socket_id].remote_port = HTONS(dest_port);
+ m_socket[p_socket->socket_id].remote_addr = (*p_dest_addr);
+
+ UDP_MUTEX_UNLOCK();
+
+ UDP6_EXIT();
+
+ return NRF_SUCCESS;
+}
+
+
+uint32_t udp6_socket_send(const udp6_socket_t * p_socket,
+ iot_pbuffer_t * p_packet)
+{
+ VERIFY_MODULE_IS_INITIALIZED();
+ NULL_PARAM_CHECK(p_socket);
+ NULL_PARAM_CHECK(p_packet);
+ NULL_PARAM_CHECK(p_packet->p_payload);
+ VERIFY_NON_ZERO_LENGTH(p_packet->length);
+ VERIFY_SOCKET_ID(p_socket->socket_id);
+ VERIFY_PORT_NUMBER(m_socket[p_socket->socket_id].local_port);
+ VERIFY_PORT_NUMBER(m_socket[p_socket->socket_id].remote_port);
+
+ UDP6_ENTRY();
+
+ UDP_MUTEX_LOCK();
+
+ uint32_t err_code;
+ const udp_socket_entry_t * p_skt = &m_socket[p_socket->socket_id];
+ const uint32_t header_size = UDP_HEADER_SIZE + IPV6_IP_HEADER_SIZE;
+ udp6_header_t * p_header = (udp6_header_t *)(p_packet->p_payload - UDP_HEADER_SIZE);
+ ipv6_header_t * p_ip_header = (ipv6_header_t *)(p_packet->p_payload - header_size);
+ iot_interface_t * p_interface = NULL;
+ uint16_t checksum;
+
+ p_header->srcport = p_skt->local_port;
+ p_header->destport = p_skt->remote_port;
+ p_header->checksum = 0;
+
+ p_header->length = HTONS(p_packet->length + UDP_HEADER_SIZE);
+
+ // Pack destination address.
+ p_ip_header->destaddr = p_skt->remote_addr;
+
+ // Pack source address.
+ if ((0 == IPV6_ADDRESS_CMP(&p_skt->local_addr, IPV6_ADDR_ANY)))
+ {
+ err_code = ipv6_address_find_best_match(&p_interface,
+ &p_ip_header->srcaddr,
+ &p_ip_header->destaddr);
+ }
+ else
+ {
+ err_code = ipv6_address_find_best_match(&p_interface,
+ NULL,
+ &p_ip_header->destaddr);
+
+ p_ip_header->srcaddr = p_skt->local_addr;
+ }
+
+ if (err_code == NRF_SUCCESS)
+ {
+ // Pack next header.
+ p_ip_header->next_header = IPV6_NEXT_HEADER_UDP;
+
+ //Pack HOP Limit.
+ p_ip_header->hoplimit = IPV6_DEFAULT_HOP_LIMIT;
+
+ //Traffic class and flow label.
+ p_ip_header->version_traffic_class = 0x60;
+ p_ip_header->traffic_class_flowlabel = 0x00;
+ p_ip_header->flowlabel = 0x0000;
+
+ // Length.
+ p_ip_header->length = HTONS(p_packet->length + UDP_HEADER_SIZE);
+
+ checksum = p_packet->length + UDP_HEADER_SIZE + IPV6_NEXT_HEADER_UDP;
+
+ ipv6_checksum_calculate(p_ip_header->srcaddr.u8, IPV6_ADDR_SIZE, &checksum, false);
+ ipv6_checksum_calculate(p_ip_header->destaddr.u8, IPV6_ADDR_SIZE, &checksum, false);
+ ipv6_checksum_calculate(p_packet->p_payload - UDP_HEADER_SIZE,
+ p_packet->length + UDP_HEADER_SIZE,
+ &checksum,
+ true);
+
+ p_header->checksum = HTONS((~checksum));
+
+ p_packet->p_payload -= header_size;
+ p_packet->length += header_size;
+
+ err_code = ipv6_send(p_interface, p_packet);
+ }
+ else
+ {
+ err_code = UDP_INTERFACE_NOT_READY;
+ }
+
+ UDP_MUTEX_UNLOCK();
+
+ UDP6_EXIT();
+
+ return err_code;
+}
+
+
+uint32_t udp6_socket_sendto(const udp6_socket_t * p_socket,
+ const ipv6_addr_t * p_dest_addr,
+ uint16_t dest_port,
+ iot_pbuffer_t * p_packet)
+{
+ VERIFY_MODULE_IS_INITIALIZED();
+ NULL_PARAM_CHECK(p_socket);
+ NULL_PARAM_CHECK(p_dest_addr);
+ NULL_PARAM_CHECK(p_packet);
+ NULL_PARAM_CHECK(p_packet->p_payload);
+ VERIFY_NON_ZERO_LENGTH(p_packet->length);
+ VERIFY_SOCKET_ID(p_socket->socket_id);
+ VERIFY_PORT_NUMBER(dest_port);
+
+ UDP6_ENTRY();
+
+ UDP_MUTEX_LOCK();
+
+ uint32_t err_code;
+ const udp_socket_entry_t * p_skt = &m_socket[p_socket->socket_id];
+ const uint32_t header_size = UDP_HEADER_SIZE + IPV6_IP_HEADER_SIZE;
+ udp6_header_t * p_header = (udp6_header_t *)(p_packet->p_payload - UDP_HEADER_SIZE);
+ ipv6_header_t * p_ip_header = (ipv6_header_t *)(p_packet->p_payload - header_size);
+ iot_interface_t * p_interface = NULL;
+ uint16_t checksum;
+
+ p_header->srcport = p_skt->local_port;
+ p_header->destport = HTONS(dest_port);
+ p_header->checksum = 0;
+
+ checksum = p_packet->length + UDP_HEADER_SIZE + IPV6_NEXT_HEADER_UDP;
+
+ p_header->length = HTONS(p_packet->length + UDP_HEADER_SIZE);
+
+ //Pack destination address.
+ p_ip_header->destaddr = *p_dest_addr;
+
+ // Pack source address.
+ if ((0 == IPV6_ADDRESS_CMP(&p_skt->local_addr, IPV6_ADDR_ANY)))
+ {
+ err_code = ipv6_address_find_best_match(&p_interface,
+ &p_ip_header->srcaddr,
+ &p_ip_header->destaddr);
+ }
+ else
+ {
+ err_code = ipv6_address_find_best_match(&p_interface,
+ NULL,
+ &p_ip_header->destaddr);
+
+ p_ip_header->srcaddr = p_skt->local_addr;
+ }
+
+ if (err_code == NRF_SUCCESS)
+ {
+ //Pack next header.
+ p_ip_header->next_header = IPV6_NEXT_HEADER_UDP;
+
+ //Pack HOP Limit.
+ p_ip_header->hoplimit = IPV6_DEFAULT_HOP_LIMIT;
+
+ //Traffic class and flow label.
+ p_ip_header->version_traffic_class = 0x60;
+ p_ip_header->traffic_class_flowlabel = 0x00;
+ p_ip_header->flowlabel = 0x0000;
+
+ // Length.
+ p_ip_header->length = HTONS(p_packet->length + UDP_HEADER_SIZE);
+
+ ipv6_checksum_calculate(p_ip_header->srcaddr.u8, IPV6_ADDR_SIZE, &checksum, false);
+ ipv6_checksum_calculate(p_ip_header->destaddr.u8, IPV6_ADDR_SIZE, &checksum, false);
+ ipv6_checksum_calculate(p_packet->p_payload - UDP_HEADER_SIZE,
+ p_packet->length + UDP_HEADER_SIZE,
+ &checksum,
+ true);
+
+ p_header->checksum = HTONS((~checksum));
+
+ p_packet->p_payload -= header_size;
+ p_packet->length += header_size;
+
+ err_code = ipv6_send(p_interface, p_packet);
+ }
+ else
+ {
+ err_code = UDP_INTERFACE_NOT_READY;
+ }
+
+ UDP_MUTEX_UNLOCK();
+
+ UDP6_EXIT();
+
+ return err_code;
+}
+
+
+uint32_t udp6_socket_app_data_set(const udp6_socket_t * p_socket)
+{
+ VERIFY_MODULE_IS_INITIALIZED();
+ NULL_PARAM_CHECK(p_socket);
+ VERIFY_SOCKET_ID(p_socket->socket_id);
+
+ //Note: no null check is performed on the p_app_data as it is permissible
+ //to pass on a NULL value if need be.
+
+ UDP6_ENTRY();
+
+ UDP_MUTEX_LOCK();
+
+ m_socket[p_socket->socket_id].p_app_data = p_socket->p_app_data;
+
+ UDP_MUTEX_UNLOCK();
+
+ UDP6_EXIT();
+
+ return NRF_SUCCESS;
+}
+
+
+uint32_t udp_input(const iot_interface_t * p_interface,
+ const ipv6_header_t * p_ip_header,
+ iot_pbuffer_t * p_packet)
+{
+ NULL_PARAM_CHECK(p_interface);
+ NULL_PARAM_CHECK(p_ip_header);
+ NULL_PARAM_CHECK(p_packet);
+
+ UNUSED_VARIABLE(p_interface);
+
+ uint32_t err_code = (NRF_ERROR_NOT_FOUND | IOT_UDP6_ERR_BASE);
+
+ if ((p_packet->length > UDP_HEADER_SIZE) && (p_ip_header->length > UDP_HEADER_SIZE))
+ {
+ UDP_MUTEX_LOCK();
+
+ UDP6_ENTRY();
+
+ uint32_t index;
+ udp6_header_t * p_udp_header = (udp6_header_t *)(p_packet->p_payload);
+
+ // Check to which UDP socket, port and address was bind.
+ for (index = 0; index < UDP6_MAX_SOCKET_COUNT; index ++)
+ {
+ if (m_socket[index].local_port == p_udp_header->destport)
+ {
+ if ((0 == IPV6_ADDRESS_CMP(&m_socket[index].local_addr, IPV6_ADDR_ANY)) ||
+ (0 == IPV6_ADDRESS_CMP(&m_socket[index].local_addr, &p_ip_header->destaddr)))
+ {
+ // Check if connection was established.
+ if (m_socket[index].remote_port == 0 || m_socket[index].remote_port == p_udp_header->srcport)
+ {
+ if ((0 == IPV6_ADDRESS_CMP(&m_socket[index].remote_addr, IPV6_ADDR_ANY)) ||
+ (0 == IPV6_ADDRESS_CMP(&m_socket[index].remote_addr, &p_ip_header->srcaddr)))
+ {
+ err_code = NRF_SUCCESS;
+ break;
+ }
+ }
+ }
+ }
+ }
+
+ if (index < UDP6_MAX_SOCKET_COUNT)
+ {
+ uint16_t checksum = p_packet->length + IPV6_NEXT_HEADER_UDP;
+ uint32_t process_result = NRF_SUCCESS;
+ uint16_t udp_hdr_length = NTOHS(p_udp_header->length);
+
+ if (udp_hdr_length > p_packet->length)
+ {
+ UDP6_ERR("Received truncated packet, "
+ "payload length 0x%08lX, length in header 0x%08X.",
+ p_packet->length, NTOHS(p_udp_header->length));
+ process_result = UDP_TRUNCATED_PACKET;
+ }
+ else if (udp_hdr_length < p_packet->length)
+ {
+ UDP6_ERR("Received malformed packet, "
+ "payload length 0x%08lX, length in header 0x%08X.",
+ p_packet->length, NTOHS(p_udp_header->length));
+
+ process_result = UDP_MALFORMED_PACKET;
+ }
+ else
+ {
+ ipv6_checksum_calculate(p_ip_header->srcaddr.u8, IPV6_ADDR_SIZE, &checksum, false);
+ ipv6_checksum_calculate(p_ip_header->destaddr.u8, IPV6_ADDR_SIZE, &checksum, false);
+ ipv6_checksum_calculate(p_packet->p_payload, p_packet->length, &checksum, false);
+
+ if (checksum != 0 && checksum != 0xFFFF)
+ {
+ UDP6_ERR("Bad checksum detected.");
+ process_result = UDP_BAD_CHECKSUM;
+ }
+ }
+
+ p_packet->p_payload = p_packet->p_payload + UDP_HEADER_SIZE;
+ p_packet->length -= UDP_HEADER_SIZE;
+
+ //Found port for which data is intended.
+ const udp6_socket_t sock = {index, m_socket[index].p_app_data};
+
+ //Give application a callback if callback is registered.
+ if (m_socket[index].rx_cb != NULL)
+ {
+ UDP_MUTEX_UNLOCK();
+
+ // Change byte ordering given to application.
+ p_udp_header->destport = NTOHS(p_udp_header->destport);
+ p_udp_header->srcport = NTOHS(p_udp_header->srcport);
+ p_udp_header->length = NTOHS(p_udp_header->length);
+ p_udp_header->checksum = NTOHS(p_udp_header->checksum);
+
+ err_code = m_socket[index].rx_cb(&sock, p_ip_header, p_udp_header, process_result, p_packet);
+
+ UDP_MUTEX_LOCK();
+ }
+ }
+ else
+ {
+ UDP6_ERR("Packet received on unknown port, dropping!");
+ }
+
+ UDP_MUTEX_UNLOCK();
+
+ UDP6_EXIT();
+ }
+ else
+ {
+ UDP6_ERR("Packet of length less than UDP header size received!");
+ err_code = (IOT_UDP6_ERR_BASE | NRF_ERROR_INVALID_LENGTH);
+ }
+
+ return err_code;
+}
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/ipv6_stack/utils/ipv6_utils.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/ipv6_stack/utils/ipv6_utils.c
new file mode 100644
index 0000000..8b70cba
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/ipv6_stack/utils/ipv6_utils.c
@@ -0,0 +1,101 @@
+/**
+ * Copyright (c) 2014 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#include <stdint.h>
+#include <stdbool.h>
+#include "nordic_common.h"
+#include "sdk_common.h"
+#include "sdk_config.h"
+#include "ipv6_utils.h"
+
+void ipv6_checksum_calculate(const uint8_t * p_data, uint16_t len, uint16_t * p_checksum, bool flip_flag)
+{
+ uint16_t checksum_even = (((*p_checksum) & 0xFF00) >> 8);
+ uint16_t checksum_odd = ((*p_checksum) & 0x00FF);
+
+ while (len)
+ {
+ if ( len == 1 )
+ {
+ checksum_even += (*p_data);
+ len -= 1;
+ }
+ else
+ {
+ checksum_even += *p_data++;
+ checksum_odd += *p_data++;
+ len -= 2;
+ }
+
+ if (checksum_odd & 0xFF00)
+ {
+ checksum_even += ((checksum_odd & 0xFF00) >> 8);
+ checksum_odd = (checksum_odd & 0x00FF);
+ }
+
+ if (checksum_even & 0xFF00)
+ {
+ checksum_odd += ((checksum_even & 0xFF00) >> 8);
+ checksum_even = (checksum_even & 0x00FF);
+ }
+ }
+
+ checksum_even = (checksum_even << 8) + (checksum_odd & 0xFFFF);
+
+ if (flip_flag)
+ {
+ // We use 0xFFFF instead of 0x0000 because of not operator.
+ if (checksum_even == 0xFFFF)
+ {
+ checksum_even = 0x0000;
+ }
+ }
+
+ (*p_checksum) = (uint16_t)(checksum_even);
+}
+
+void ipv6_header_init(ipv6_header_t * p_ip_header)
+{
+ p_ip_header->version_traffic_class = IPV6_DEFAULT_VER_TC;
+ p_ip_header->traffic_class_flowlabel = IPV6_DEFAULT_TC_FL;
+ p_ip_header->flowlabel = IPV6_DEFAULT_FL;
+ p_ip_header->next_header = IPV6_NEXT_HEADER_RESERVED;
+ p_ip_header->hoplimit = IPV6_DEFAULT_HOP_LIMIT;
+ p_ip_header->length = 0;
+}
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/ipv6_stack/utils/ipv6_utils.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/ipv6_stack/utils/ipv6_utils.h
new file mode 100644
index 0000000..5cbdf15
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/ipv6_stack/utils/ipv6_utils.h
@@ -0,0 +1,93 @@
+/**
+ * Copyright (c) 2014 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 ipv6_utils.h
+ *
+ * @defgroup iot_utils Common utils
+ * @ingroup iot_sdk_common
+ * @{
+ * @brief Abstracts common IOT macros needed by IOT modules.
+ *
+ * @details Common macros related to IOT are defined here for use by all IOT modules.
+ */
+
+#ifndef IPV6_UTILS_H__
+#define IPV6_UTILS_H__
+
+#include <stdint.h>
+#include <stdbool.h>
+#include "iot_defines.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**@brief Function for calculating checksum using IPv6 algorithm.
+ *
+ * @param[in] p_data Pointer to the data needs to be checksummed.
+ * @param[in] len Length of the data.
+ * @param[in] p_checksum Pointer to actual value of checksum.
+ * @param[out] p_checksum Value of calculated checksum.
+ *
+ * @retval None.
+ */
+void ipv6_checksum_calculate(const uint8_t * p_data,
+ uint16_t len,
+ uint16_t * p_checksum,
+ bool flip_zero);
+
+
+/**@brief Function for initializing default values of IPv6 Header.
+ *
+ * @note Function initializes Version, Traffic Class, Flow Label, Next Header, Hop Limit and
+ * Length fields.
+ *
+ * @param[in] p_ip_header Pointer to the IPv6 Header.
+ *
+ * @retval None.
+ */
+void ipv6_header_init(ipv6_header_t * p_ip_header);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif //IPV6_UTILS_H__
+
+/**@} */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/lwm2m/ipso_objects.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/lwm2m/ipso_objects.c
new file mode 100644
index 0000000..638277a
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/lwm2m/ipso_objects.c
@@ -0,0 +1,553 @@
+/**
+ * Copyright (c) 2015 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#include <string.h>
+#include <stddef.h>
+
+#include "ipso_objects.h"
+#include "lwm2m.h"
+#include "lwm2m_tlv.h"
+
+//lint -e516 -save // Symbol '__INTADDR__()' has arg. type conflict
+#define LWM2M_INSTANCE_OFFSET_SET(instance, type) \
+ instance->proto.operations_offset = offsetof(type, operations); \
+ instance->proto.resource_ids_offset = offsetof(type, resource_ids);
+//lint -restore
+
+void ipso_instance_digital_input_init(ipso_digital_input_t * p_instance)
+{
+ LWM2M_INSTANCE_OFFSET_SET(p_instance, ipso_digital_input_t);
+
+ p_instance->proto.object_id = IPSO_SO_ID_DIGITAL_INPUT;
+ p_instance->proto.instance_id = 0;
+ p_instance->proto.num_resources = sizeof(((ipso_digital_input_t *)0)->operations);
+
+ // Set access types.
+ p_instance->operations[0] = LWM2M_OPERATION_CODE_READ;
+ p_instance->operations[1] = LWM2M_OPERATION_CODE_READ;
+ p_instance->operations[2] = (LWM2M_OPERATION_CODE_READ | LWM2M_OPERATION_CODE_WRITE);
+ p_instance->operations[3] = (LWM2M_OPERATION_CODE_READ | LWM2M_OPERATION_CODE_WRITE);
+ p_instance->operations[4] = (LWM2M_OPERATION_CODE_READ | LWM2M_OPERATION_CODE_WRITE);
+ p_instance->operations[5] = LWM2M_OPERATION_CODE_EXECUTE;
+ p_instance->operations[6] = (LWM2M_OPERATION_CODE_READ | LWM2M_OPERATION_CODE_WRITE);
+ p_instance->operations[7] = LWM2M_OPERATION_CODE_READ;
+
+
+ // Set resource IDs.
+ p_instance->resource_ids[0] = IPSO_RR_ID_DIGITAL_INPUT_STATE;
+ p_instance->resource_ids[1] = IPSO_RR_ID_DIGITAL_INPUT_COUNTER;
+ p_instance->resource_ids[2] = IPSO_RR_ID_DIGITAL_INPUT_POLARITY;
+ p_instance->resource_ids[3] = IPSO_RR_ID_DIGITAL_INPUT_DEBOUNCE_PERIOD;
+ p_instance->resource_ids[4] = IPSO_RR_ID_DIGITAL_INPUT_EDGE_SELECTION;
+ p_instance->resource_ids[5] = IPSO_RR_ID_DIGITAL_INPUT_COUNTER_RESET;
+ p_instance->resource_ids[6] = IPSO_RR_ID_APPLICATION_TYPE;
+ p_instance->resource_ids[7] = IPSO_RR_ID_SENSOR_TYPE;
+
+
+}
+
+void ipso_instance_digital_output_init(ipso_digital_output_t * p_instance)
+{
+ // Set prototype variables.
+ LWM2M_INSTANCE_OFFSET_SET(p_instance, ipso_digital_output_t);
+
+ p_instance->proto.object_id = IPSO_SO_ID_DIGITAL_OUTPUT;
+ p_instance->proto.instance_id = 0;
+ p_instance->proto.num_resources = sizeof(((ipso_digital_output_t *)0)->operations);
+
+ // Set access types.
+ p_instance->operations[0] = (LWM2M_OPERATION_CODE_READ | LWM2M_OPERATION_CODE_WRITE);
+ p_instance->operations[1] = (LWM2M_OPERATION_CODE_READ | LWM2M_OPERATION_CODE_WRITE);
+ p_instance->operations[2] = (LWM2M_OPERATION_CODE_READ | LWM2M_OPERATION_CODE_WRITE);
+
+ // Set resource IDs.
+ p_instance->resource_ids[0] = IPSO_RR_ID_DIGITAL_OUTPUT_STATE;
+ p_instance->resource_ids[1] = IPSO_RR_ID_DIGITAL_OUTPUT_POLARITY;
+ p_instance->resource_ids[2] = IPSO_RR_ID_APPLICATION_TYPE;
+}
+
+
+void ipso_instance_analog_input_init(ipso_analog_input_t * p_instance)
+{
+
+ // Set prototype variables.
+ LWM2M_INSTANCE_OFFSET_SET(p_instance, ipso_analog_input_t);
+
+ p_instance->proto.object_id = IPSO_SO_ID_ANALOGUE_INPUT;
+ p_instance->proto.instance_id = 0;
+ p_instance->proto.num_resources = sizeof(((ipso_analog_input_t *)0)->operations);
+
+ // Set access types.
+ p_instance->operations[0] = LWM2M_OPERATION_CODE_READ;
+ p_instance->operations[1] = LWM2M_OPERATION_CODE_READ;
+ p_instance->operations[2] = LWM2M_OPERATION_CODE_READ;
+ p_instance->operations[3] = LWM2M_OPERATION_CODE_READ;
+ p_instance->operations[4] = LWM2M_OPERATION_CODE_READ;
+ p_instance->operations[5] = LWM2M_OPERATION_CODE_EXECUTE;
+ p_instance->operations[6] = (LWM2M_OPERATION_CODE_READ | LWM2M_OPERATION_CODE_WRITE);
+ p_instance->operations[7] = LWM2M_OPERATION_CODE_READ;
+
+ // Set resource IDs.
+ p_instance->resource_ids[0] = IPSO_RR_ID_ANALOG_INPUT_CURRENT_VALUE;
+ p_instance->resource_ids[1] = IPSO_RR_ID_MIN_MEASURED_VALUE;
+ p_instance->resource_ids[2] = IPSO_RR_ID_MAX_MEASURED_VALUE;
+ p_instance->resource_ids[3] = IPSO_RR_ID_MIN_RANGE_VALUE;
+ p_instance->resource_ids[4] = IPSO_RR_ID_MAX_RANGE_VALUE;
+ p_instance->resource_ids[5] = IPSO_RR_ID_RESET_MIN_MAX_MEASURED_VALUES;
+ p_instance->resource_ids[6] = IPSO_RR_ID_APPLICATION_TYPE;
+ p_instance->resource_ids[7] = IPSO_RR_ID_SENSOR_TYPE;
+}
+
+void ipso_instance_analog_output_init(ipso_analog_output_t * p_instance)
+{
+ // Set prototype variables.
+ LWM2M_INSTANCE_OFFSET_SET(p_instance, ipso_analog_output_t);
+
+ p_instance->proto.object_id = IPSO_SO_ID_ANALOGUE_OUTPUT;
+ p_instance->proto.instance_id = 0;
+ p_instance->proto.num_resources = sizeof(((ipso_analog_output_t *)0)->operations);
+
+ // Set access types.
+ p_instance->operations[0] = (LWM2M_OPERATION_CODE_READ | LWM2M_OPERATION_CODE_WRITE);
+ p_instance->operations[1] = LWM2M_OPERATION_CODE_READ;
+ p_instance->operations[2] = LWM2M_OPERATION_CODE_READ;
+ p_instance->operations[3] = (LWM2M_OPERATION_CODE_READ | LWM2M_OPERATION_CODE_WRITE);
+
+ // Set resource IDs.
+ p_instance->resource_ids[0] = IPSO_RR_ID_ANALOG_OUTPUT_CURRENT_VALUE;
+ p_instance->resource_ids[1] = IPSO_RR_ID_MIN_RANGE_VALUE;
+ p_instance->resource_ids[2] = IPSO_RR_ID_MAX_RANGE_VALUE;
+ p_instance->resource_ids[3] = IPSO_RR_ID_APPLICATION_TYPE;
+}
+
+void ipso_instance_generic_sensor_init(ipso_generic_sensor_t * p_instance)
+{
+ // Set prototype variables.
+ LWM2M_INSTANCE_OFFSET_SET(p_instance, ipso_generic_sensor_t);
+
+ p_instance->proto.object_id = IPSO_SO_ID_GENERIC_SENSOR;
+ p_instance->proto.instance_id = 0;
+ p_instance->proto.num_resources = sizeof(((ipso_generic_sensor_t *)0)->operations);
+
+ // Set access types.
+ p_instance->operations[0] = LWM2M_OPERATION_CODE_READ;
+ p_instance->operations[1] = LWM2M_OPERATION_CODE_READ;
+ p_instance->operations[2] = LWM2M_OPERATION_CODE_READ;
+ p_instance->operations[3] = LWM2M_OPERATION_CODE_READ;
+ p_instance->operations[4] = LWM2M_OPERATION_CODE_READ;
+ p_instance->operations[5] = LWM2M_OPERATION_CODE_READ;
+ p_instance->operations[6] = LWM2M_OPERATION_CODE_EXECUTE;
+ p_instance->operations[7] = (LWM2M_OPERATION_CODE_READ | LWM2M_OPERATION_CODE_WRITE);
+ p_instance->operations[8] = LWM2M_OPERATION_CODE_READ;
+
+ // Set resource IDs.
+ p_instance->resource_ids[0] = IPSO_RR_ID_SENSOR_VALUE;
+ p_instance->resource_ids[1] = IPSO_RR_ID_SENSOR_UNITS;
+ p_instance->resource_ids[2] = IPSO_RR_ID_MIN_MEASURED_VALUE;
+ p_instance->resource_ids[3] = IPSO_RR_ID_MAX_MEASURED_VALUE;
+ p_instance->resource_ids[4] = IPSO_RR_ID_MIN_RANGE_VALUE;
+ p_instance->resource_ids[5] = IPSO_RR_ID_MAX_RANGE_VALUE;
+ p_instance->resource_ids[6] = IPSO_RR_ID_RESET_MIN_MAX_MEASURED_VALUES;
+ p_instance->resource_ids[7] = IPSO_RR_ID_APPLICATION_TYPE;
+ p_instance->resource_ids[8] = IPSO_RR_ID_SENSOR_TYPE;
+}
+
+void ipso_instance_illuminance_init(ipso_illuminance_t * p_instance)
+{
+ // Set prototype variables.
+ LWM2M_INSTANCE_OFFSET_SET(p_instance, ipso_illuminance_t);
+
+ p_instance->proto.object_id = IPSO_SO_ID_ILLUMINANCE_SENSOR;
+ p_instance->proto.instance_id = 0;
+ p_instance->proto.num_resources = sizeof(((ipso_illuminance_t *)0)->operations);
+
+ // Set access types.
+ p_instance->operations[0] = LWM2M_OPERATION_CODE_READ;
+ p_instance->operations[1] = LWM2M_OPERATION_CODE_READ;
+ p_instance->operations[2] = LWM2M_OPERATION_CODE_READ;
+ p_instance->operations[3] = LWM2M_OPERATION_CODE_READ;
+ p_instance->operations[4] = LWM2M_OPERATION_CODE_READ;
+ p_instance->operations[5] = LWM2M_OPERATION_CODE_READ;
+ p_instance->operations[6] = LWM2M_OPERATION_CODE_EXECUTE;
+
+ // Set resource IDs.
+ p_instance->resource_ids[0] = IPSO_RR_ID_SENSOR_VALUE;
+ p_instance->resource_ids[1] = IPSO_RR_ID_SENSOR_UNITS;
+ p_instance->resource_ids[2] = IPSO_RR_ID_MIN_MEASURED_VALUE;
+ p_instance->resource_ids[3] = IPSO_RR_ID_MAX_MEASURED_VALUE;
+ p_instance->resource_ids[4] = IPSO_RR_ID_MIN_RANGE_VALUE;
+ p_instance->resource_ids[5] = IPSO_RR_ID_MAX_RANGE_VALUE;
+ p_instance->resource_ids[6] = IPSO_RR_ID_RESET_MIN_MAX_MEASURED_VALUES;
+}
+
+void ipso_instance_presence_init(ipso_presence_t * p_instance)
+{
+ // Set prototype variables.
+ LWM2M_INSTANCE_OFFSET_SET(p_instance, ipso_presence_t);
+
+ p_instance->proto.object_id = IPSO_SO_ID_PRESENCE_SENSOR;
+ p_instance->proto.instance_id = 0;
+ p_instance->proto.num_resources = sizeof(((ipso_presence_t *)0)->operations);
+
+ // Set access types.
+ p_instance->operations[0] = LWM2M_OPERATION_CODE_READ;
+ p_instance->operations[1] = LWM2M_OPERATION_CODE_READ;
+ p_instance->operations[2] = LWM2M_OPERATION_CODE_EXECUTE;
+ p_instance->operations[3] = LWM2M_OPERATION_CODE_READ;
+ p_instance->operations[4] = (LWM2M_OPERATION_CODE_READ | LWM2M_OPERATION_CODE_WRITE);
+ p_instance->operations[5] = (LWM2M_OPERATION_CODE_READ | LWM2M_OPERATION_CODE_WRITE);
+
+ // Set resource IDs.
+ p_instance->resource_ids[0] = IPSO_RR_ID_DIGITAL_INPUT_STATE;
+ p_instance->resource_ids[1] = IPSO_RR_ID_DIGITAL_INPUT_COUNTER;
+ p_instance->resource_ids[2] = IPSO_RR_ID_DIGITAL_INPUT_COUNTER_RESET;
+ p_instance->resource_ids[3] = IPSO_RR_ID_SENSOR_TYPE;
+ p_instance->resource_ids[4] = IPSO_RR_ID_BUSY_TO_CLEAR_DELAY;
+ p_instance->resource_ids[5] = IPSO_RR_ID_CLEAR_TO_BUSY_DELAY;
+}
+
+void ipso_instance_temperature_init(ipso_temperature_t * p_instance)
+{
+ // Set prototype variables.
+ LWM2M_INSTANCE_OFFSET_SET(p_instance, ipso_temperature_t);
+
+ p_instance->proto.object_id = IPSO_SO_ID_TEMPERATURE_SENSOR;
+ p_instance->proto.instance_id = 0;
+ p_instance->proto.num_resources = sizeof(((ipso_temperature_t *)0)->operations);
+
+ // Set access types.
+ p_instance->operations[0] = LWM2M_OPERATION_CODE_READ;
+ p_instance->operations[1] = LWM2M_OPERATION_CODE_READ;
+ p_instance->operations[2] = LWM2M_OPERATION_CODE_READ;
+ p_instance->operations[3] = LWM2M_OPERATION_CODE_READ;
+ p_instance->operations[4] = LWM2M_OPERATION_CODE_READ;
+ p_instance->operations[5] = LWM2M_OPERATION_CODE_READ;
+ p_instance->operations[6] = LWM2M_OPERATION_CODE_EXECUTE;
+
+ // Set resource IDs.
+ p_instance->resource_ids[0] = IPSO_RR_ID_SENSOR_VALUE;
+ p_instance->resource_ids[1] = IPSO_RR_ID_SENSOR_UNITS;
+ p_instance->resource_ids[2] = IPSO_RR_ID_MIN_MEASURED_VALUE;
+ p_instance->resource_ids[3] = IPSO_RR_ID_MAX_MEASURED_VALUE;
+ p_instance->resource_ids[4] = IPSO_RR_ID_MIN_RANGE_VALUE;
+ p_instance->resource_ids[5] = IPSO_RR_ID_MAX_RANGE_VALUE;
+ p_instance->resource_ids[6] = IPSO_RR_ID_RESET_MIN_MAX_MEASURED_VALUES;
+}
+
+void ipso_instance_humidity_init(ipso_humidity_t * p_instance)
+{
+ // Set prototype variables.
+ LWM2M_INSTANCE_OFFSET_SET(p_instance, ipso_humidity_t);
+
+ p_instance->proto.object_id = IPSO_SO_ID_HUMIDITY_SENSOR;
+ p_instance->proto.instance_id = 0;
+ p_instance->proto.num_resources = sizeof(((ipso_humidity_t *)0)->operations);
+
+ // Set access types.
+ p_instance->operations[0] = LWM2M_OPERATION_CODE_READ;
+ p_instance->operations[1] = LWM2M_OPERATION_CODE_READ;
+ p_instance->operations[2] = LWM2M_OPERATION_CODE_READ;
+ p_instance->operations[3] = LWM2M_OPERATION_CODE_READ;
+ p_instance->operations[4] = LWM2M_OPERATION_CODE_READ;
+ p_instance->operations[5] = LWM2M_OPERATION_CODE_READ;
+ p_instance->operations[6] = LWM2M_OPERATION_CODE_EXECUTE;
+
+ // Set resource IDs.
+ p_instance->resource_ids[0] = IPSO_RR_ID_SENSOR_VALUE;
+ p_instance->resource_ids[1] = IPSO_RR_ID_SENSOR_UNITS;
+ p_instance->resource_ids[2] = IPSO_RR_ID_MIN_MEASURED_VALUE;
+ p_instance->resource_ids[3] = IPSO_RR_ID_MAX_MEASURED_VALUE;
+ p_instance->resource_ids[4] = IPSO_RR_ID_MIN_RANGE_VALUE;
+ p_instance->resource_ids[5] = IPSO_RR_ID_MAX_RANGE_VALUE;
+ p_instance->resource_ids[6] = IPSO_RR_ID_RESET_MIN_MAX_MEASURED_VALUES;
+}
+
+void ipso_instance_power_measurement_init(ipso_power_measurement_t * p_instance)
+{
+ // Set prototype variables.
+ LWM2M_INSTANCE_OFFSET_SET(p_instance, ipso_power_measurement_t);
+
+ p_instance->proto.object_id = IPSO_SO_ID_POWER_MEASUREMENT;
+ p_instance->proto.instance_id = 0;
+ p_instance->proto.num_resources = sizeof(((ipso_power_measurement_t *)0)->operations);
+
+ // Set access types.
+ p_instance->operations[0] = LWM2M_OPERATION_CODE_READ;
+ p_instance->operations[1] = LWM2M_OPERATION_CODE_READ;
+ p_instance->operations[2] = LWM2M_OPERATION_CODE_READ;
+ p_instance->operations[3] = LWM2M_OPERATION_CODE_READ;
+ p_instance->operations[4] = LWM2M_OPERATION_CODE_READ;
+ p_instance->operations[5] = LWM2M_OPERATION_CODE_READ;
+ p_instance->operations[6] = LWM2M_OPERATION_CODE_WRITE;
+ p_instance->operations[7] = LWM2M_OPERATION_CODE_READ;
+ p_instance->operations[8] = LWM2M_OPERATION_CODE_READ;
+ p_instance->operations[9] = LWM2M_OPERATION_CODE_READ;
+ p_instance->operations[10] = LWM2M_OPERATION_CODE_READ;
+ p_instance->operations[11] = LWM2M_OPERATION_CODE_READ;
+ p_instance->operations[12] = LWM2M_OPERATION_CODE_EXECUTE;
+ p_instance->operations[13] = LWM2M_OPERATION_CODE_READ;
+ p_instance->operations[14] = LWM2M_OPERATION_CODE_WRITE;
+ p_instance->operations[15] = LWM2M_OPERATION_CODE_READ;
+ p_instance->operations[16] = (LWM2M_OPERATION_CODE_READ | LWM2M_OPERATION_CODE_WRITE);
+ p_instance->operations[17] = LWM2M_OPERATION_CODE_EXECUTE;
+
+ // Set resource IDs.
+ p_instance->resource_ids[0] = IPSO_RR_ID_INSTANTANEOUS_ACTIVE_POWER;
+ p_instance->resource_ids[1] = IPSO_RR_ID_MIN_MEASURED_ACTIVE_POWER;
+ p_instance->resource_ids[2] = IPSO_RR_ID_MAX_MEASURED_ACTIVE_POWER;
+ p_instance->resource_ids[3] = IPSO_RR_ID_MIN_RANGE_ACTIVE_POWER;
+ p_instance->resource_ids[4] = IPSO_RR_ID_MAX_RANGE_ACTIVE_POWER;
+ p_instance->resource_ids[5] = IPSO_RR_ID_CUMULATIVE_ACTIVE_POWER;
+ p_instance->resource_ids[6] = IPSO_RR_ID_ACTIVE_POWER_CALIBRATION;
+ p_instance->resource_ids[7] = IPSO_RR_ID_INSTANTANEOUS_REACTIVE_POWER;
+ p_instance->resource_ids[8] = IPSO_RR_ID_MIN_MEASURED_REACTIVE_POWER;
+ p_instance->resource_ids[9] = IPSO_RR_ID_MAX_MEASURED_REACTIVE_POWER;
+ p_instance->resource_ids[10] = IPSO_RR_ID_MIN_RANGE_REACTIVE_POWER;
+ p_instance->resource_ids[11] = IPSO_RR_ID_MAX_RANGE_REACTIVE_POWER;
+ p_instance->resource_ids[12] = IPSO_RR_ID_RESET_MIN_MAX_MEASURED_VALUES;
+ p_instance->resource_ids[13] = IPSO_RR_ID_CUMULATIVE_REACTIVE_POWER;
+ p_instance->resource_ids[14] = IPSO_RR_ID_REACTIVE_POWER_CALIBRATION;
+ p_instance->resource_ids[15] = IPSO_RR_ID_POWER_FACTOR;
+ p_instance->resource_ids[16] = IPSO_RR_ID_CURRENT_CALIBRATION;
+ p_instance->resource_ids[17] = IPSO_RR_ID_RESET_CUMULATIVE_ENERGY;
+}
+
+void ipso_instance_actuation_init(ipso_actuation_t * p_instance)
+{
+ // Set prototype variables.
+ LWM2M_INSTANCE_OFFSET_SET(p_instance, ipso_actuation_t);
+
+ p_instance->proto.object_id = IPSO_SO_ID_ACTUATION;
+ p_instance->proto.instance_id = 0;
+ p_instance->proto.num_resources = sizeof(((ipso_actuation_t *)0)->operations);
+
+ // Set access types.
+ p_instance->operations[0] = (LWM2M_OPERATION_CODE_READ | LWM2M_OPERATION_CODE_WRITE);
+ p_instance->operations[1] = (LWM2M_OPERATION_CODE_READ | LWM2M_OPERATION_CODE_WRITE);
+ p_instance->operations[2] = (LWM2M_OPERATION_CODE_READ | LWM2M_OPERATION_CODE_WRITE);
+ p_instance->operations[3] = (LWM2M_OPERATION_CODE_READ | LWM2M_OPERATION_CODE_WRITE);
+ p_instance->operations[4] = (LWM2M_OPERATION_CODE_READ | LWM2M_OPERATION_CODE_WRITE);
+
+ // Set resource IDs.
+ p_instance->resource_ids[0] = IPSO_RR_ID_ON_OFF;
+ p_instance->resource_ids[1] = IPSO_RR_ID_DIMMER;
+ p_instance->resource_ids[2] = IPSO_RR_ID_ON_TIME;
+ p_instance->resource_ids[3] = IPSO_RR_ID_MULTI_STATE_OUTPUT;
+ p_instance->resource_ids[4] = IPSO_RR_ID_APPLICATION_TYPE;
+}
+
+void ipso_instance_set_point_init(ipso_set_point_t * p_instance)
+{
+ // Set prototype variables.
+ LWM2M_INSTANCE_OFFSET_SET(p_instance, ipso_set_point_t);
+
+ p_instance->proto.object_id = IPSO_SO_ID_SET_POINT;
+ p_instance->proto.instance_id = 0;
+ p_instance->proto.num_resources = sizeof(((ipso_set_point_t *)0)->operations);
+
+ // Set access types.
+ p_instance->operations[0] = (LWM2M_OPERATION_CODE_READ | LWM2M_OPERATION_CODE_WRITE);
+ p_instance->operations[1] = (LWM2M_OPERATION_CODE_READ | LWM2M_OPERATION_CODE_WRITE);
+ p_instance->operations[2] = LWM2M_OPERATION_CODE_READ;
+ p_instance->operations[3] = (LWM2M_OPERATION_CODE_READ | LWM2M_OPERATION_CODE_WRITE);
+
+ // Set resource IDs.
+ p_instance->resource_ids[0] = IPSO_RR_ID_SETPOINT_VALUE;
+ p_instance->resource_ids[1] = IPSO_RR_ID_COLOUR;
+ p_instance->resource_ids[2] = IPSO_RR_ID_SENSOR_UNITS;
+ p_instance->resource_ids[3] = IPSO_RR_ID_APPLICATION_TYPE;
+}
+
+void ipso_instance_load_control_init(ipso_load_control_t * p_instance)
+{
+ // Set prototype variables.
+ LWM2M_INSTANCE_OFFSET_SET(p_instance, ipso_load_control_t);
+
+ p_instance->proto.object_id = IPSO_SO_ID_LOAD_CONTROL;
+ p_instance->proto.instance_id = 0;
+ p_instance->proto.num_resources = sizeof(((ipso_load_control_t *)0)->operations);
+
+ // Set access types.
+ p_instance->operations[0] = (LWM2M_OPERATION_CODE_READ | LWM2M_OPERATION_CODE_WRITE);
+ p_instance->operations[1] = (LWM2M_OPERATION_CODE_READ | LWM2M_OPERATION_CODE_WRITE);
+ p_instance->operations[2] = (LWM2M_OPERATION_CODE_READ | LWM2M_OPERATION_CODE_WRITE);
+ p_instance->operations[3] = (LWM2M_OPERATION_CODE_READ | LWM2M_OPERATION_CODE_WRITE);
+ p_instance->operations[4] = (LWM2M_OPERATION_CODE_READ | LWM2M_OPERATION_CODE_WRITE);
+ p_instance->operations[5] = (LWM2M_OPERATION_CODE_READ | LWM2M_OPERATION_CODE_WRITE);
+
+ // Set resource IDs.
+ p_instance->resource_ids[0] = IPSO_RR_ID_EVENT_IDENTIFIER;
+ p_instance->resource_ids[1] = IPSO_RR_ID_START_TIME;
+ p_instance->resource_ids[2] = IPSO_RR_ID_DURATION_IN_MIN;
+ p_instance->resource_ids[3] = IPSO_RR_ID_CRITICALITY_LEVEL;
+ p_instance->resource_ids[4] = IPSO_RR_ID_AVG_LOAD_ADJPCT;
+ p_instance->resource_ids[5] = IPSO_RR_ID_DUTY_CYCLE;
+}
+
+void ipso_instance_light_control_init(ipso_light_control_t * p_instance)
+{
+ // Set prototype variables.
+ LWM2M_INSTANCE_OFFSET_SET(p_instance, ipso_light_control_t);
+
+ p_instance->proto.object_id = IPSO_SO_ID_LIGHT_CONTROL;
+ p_instance->proto.instance_id = 0;
+ p_instance->proto.num_resources = sizeof(((ipso_light_control_t *)0)->operations);
+
+ // Set access types.
+ p_instance->operations[0] = (LWM2M_OPERATION_CODE_READ | LWM2M_OPERATION_CODE_WRITE);
+ p_instance->operations[1] = (LWM2M_OPERATION_CODE_READ | LWM2M_OPERATION_CODE_WRITE);
+ p_instance->operations[2] = (LWM2M_OPERATION_CODE_READ | LWM2M_OPERATION_CODE_WRITE);
+ p_instance->operations[3] = LWM2M_OPERATION_CODE_READ;
+ p_instance->operations[4] = (LWM2M_OPERATION_CODE_READ | LWM2M_OPERATION_CODE_WRITE);
+ p_instance->operations[5] = LWM2M_OPERATION_CODE_READ;
+ p_instance->operations[6] = LWM2M_OPERATION_CODE_READ;
+
+ // Set resource IDs.
+ p_instance->resource_ids[0] = IPSO_RR_ID_ON_OFF;
+ p_instance->resource_ids[1] = IPSO_RR_ID_DIMMER;
+ p_instance->resource_ids[2] = IPSO_RR_ID_COLOUR;
+ p_instance->resource_ids[3] = IPSO_RR_ID_SENSOR_UNITS;
+ p_instance->resource_ids[4] = IPSO_RR_ID_ON_TIME;
+ p_instance->resource_ids[5] = IPSO_RR_ID_CUMULATIVE_ACTIVE_POWER;
+ p_instance->resource_ids[6] = IPSO_RR_ID_POWER_FACTOR;
+}
+
+void ipso_instance_power_control_init(ipso_power_control_t * p_instance)
+{
+ // Set prototype variables.
+ LWM2M_INSTANCE_OFFSET_SET(p_instance, ipso_power_control_t);
+
+ p_instance->proto.object_id = IPSO_SO_ID_POWER_CONTROL;
+ p_instance->proto.instance_id = 0;
+ p_instance->proto.num_resources = sizeof(((ipso_power_control_t *)0)->operations);
+
+ // Set access types.
+ p_instance->operations[0] = (LWM2M_OPERATION_CODE_READ | LWM2M_OPERATION_CODE_WRITE);
+ p_instance->operations[1] = (LWM2M_OPERATION_CODE_READ | LWM2M_OPERATION_CODE_WRITE);
+ p_instance->operations[2] = (LWM2M_OPERATION_CODE_READ | LWM2M_OPERATION_CODE_WRITE);
+ p_instance->operations[3] = LWM2M_OPERATION_CODE_READ;
+ p_instance->operations[4] = LWM2M_OPERATION_CODE_READ;
+
+ // Set resource IDs.
+ p_instance->resource_ids[0] = IPSO_RR_ID_ON_OFF;
+ p_instance->resource_ids[1] = IPSO_RR_ID_DIMMER;
+ p_instance->resource_ids[2] = IPSO_RR_ID_ON_TIME;
+ p_instance->resource_ids[3] = IPSO_RR_ID_CUMULATIVE_ACTIVE_POWER;
+ p_instance->resource_ids[4] = IPSO_RR_ID_POWER_FACTOR;
+}
+
+void ipso_instance_accelerometer_init(ipso_accelerometer_t * p_instance)
+{
+ // Set prototype variables.
+ LWM2M_INSTANCE_OFFSET_SET(p_instance, ipso_accelerometer_t);
+
+ p_instance->proto.object_id = IPSO_SO_ID_ACCELEROMETER;
+ p_instance->proto.instance_id = 0;
+ p_instance->proto.num_resources = sizeof(((ipso_accelerometer_t *)0)->operations);
+
+ // Set access types.
+ p_instance->operations[0] = LWM2M_OPERATION_CODE_READ;
+ p_instance->operations[1] = LWM2M_OPERATION_CODE_READ;
+ p_instance->operations[2] = LWM2M_OPERATION_CODE_READ;
+ p_instance->operations[3] = LWM2M_OPERATION_CODE_READ;
+ p_instance->operations[4] = LWM2M_OPERATION_CODE_READ;
+ p_instance->operations[5] = LWM2M_OPERATION_CODE_READ;
+
+ // Set resource IDs.
+ p_instance->resource_ids[0] = IPSO_RR_ID_X_VALUE;
+ p_instance->resource_ids[1] = IPSO_RR_ID_Y_VALUE;
+ p_instance->resource_ids[2] = IPSO_RR_ID_Z_VALUE;
+ p_instance->resource_ids[3] = IPSO_RR_ID_SENSOR_UNITS;
+ p_instance->resource_ids[4] = IPSO_RR_ID_MIN_RANGE_VALUE;
+ p_instance->resource_ids[5] = IPSO_RR_ID_MAX_RANGE_VALUE;
+}
+
+void ipso_instance_magnetometer_init(ipso_magnetometer_t * p_instance)
+{
+ // Set prototype variables.
+ LWM2M_INSTANCE_OFFSET_SET(p_instance, ipso_magnetometer_t);
+
+ p_instance->proto.object_id = IPSO_SO_ID_MAGNETOMETER;
+ p_instance->proto.instance_id = 0;
+ p_instance->proto.num_resources = sizeof(((ipso_magnetometer_t *)0)->operations);
+
+ // Set access types.
+ p_instance->operations[0] = LWM2M_OPERATION_CODE_READ;
+ p_instance->operations[1] = LWM2M_OPERATION_CODE_READ;
+ p_instance->operations[2] = LWM2M_OPERATION_CODE_READ;
+ p_instance->operations[3] = LWM2M_OPERATION_CODE_READ;
+ p_instance->operations[4] = LWM2M_OPERATION_CODE_READ;
+
+ // Set resource IDs.
+ p_instance->resource_ids[0] = IPSO_RR_ID_X_VALUE;
+ p_instance->resource_ids[1] = IPSO_RR_ID_Y_VALUE;
+ p_instance->resource_ids[2] = IPSO_RR_ID_Z_VALUE;
+ p_instance->resource_ids[3] = IPSO_RR_ID_SENSOR_UNITS;
+ p_instance->resource_ids[4] = IPSO_RR_ID_COMPASS_DIRECTION;
+}
+
+void ipso_instance_barometer_init(ipso_barometer_t * p_instance)
+{
+ // Set prototype variables.
+ LWM2M_INSTANCE_OFFSET_SET(p_instance, ipso_barometer_t);
+
+ p_instance->proto.object_id = IPSO_SO_ID_BAROMETER;
+ p_instance->proto.instance_id = 0;
+ p_instance->proto.num_resources = sizeof(((ipso_barometer_t *)0)->operations);
+
+ // Set access types.
+ p_instance->operations[0] = LWM2M_OPERATION_CODE_READ;
+ p_instance->operations[1] = LWM2M_OPERATION_CODE_READ;
+ p_instance->operations[2] = LWM2M_OPERATION_CODE_READ;
+ p_instance->operations[3] = LWM2M_OPERATION_CODE_READ;
+ p_instance->operations[4] = LWM2M_OPERATION_CODE_READ;
+ p_instance->operations[5] = LWM2M_OPERATION_CODE_READ;
+ p_instance->operations[6] = LWM2M_OPERATION_CODE_EXECUTE;
+
+ // Set resource IDs.
+
+
+ p_instance->resource_ids[0] = IPSO_RR_ID_SENSOR_VALUE;
+ p_instance->resource_ids[1] = IPSO_RR_ID_SENSOR_UNITS;
+ p_instance->resource_ids[2] = IPSO_RR_ID_MIN_MEASURED_VALUE;
+ p_instance->resource_ids[3] = IPSO_RR_ID_MAX_MEASURED_VALUE;
+ p_instance->resource_ids[4] = IPSO_RR_ID_MIN_RANGE_VALUE;
+ p_instance->resource_ids[5] = IPSO_RR_ID_MAX_RANGE_VALUE;
+ p_instance->resource_ids[6] = IPSO_RR_ID_RESET_MIN_MAX_MEASURED_VALUES;
+}
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/lwm2m/ipso_objects.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/lwm2m/ipso_objects.h
new file mode 100644
index 0000000..7a9ca8e
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/lwm2m/ipso_objects.h
@@ -0,0 +1,628 @@
+/**
+ * Copyright (c) 2015 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 lwm2m_objects.h
+ *
+ * @defgroup iot_sdk_ipso_objects IPSO Smart Object definititions and types
+ * @ingroup iot_sdk_lwm2m
+ * @{
+ * @brief IPSO objects definitions and types.
+ *
+ * @note The definitions used in this module are from the IPSO Alliance
+ * "IPSO SmartOject Guideline - Smart Objects Starter Pack1.0".
+ * The specification could be found at http://www.ipso-alliance.org/.
+ */
+
+#ifndef IPSO_OBJECTS_H__
+#define IPSO_OBJECTS_H__
+
+#include "lwm2m_api.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define IPSO_SO_ID_DIGITAL_INPUT 3200
+#define IPSO_SO_ID_DIGITAL_OUTPUT 3201
+#define IPSO_SO_ID_ANALOGUE_INPUT 3202
+#define IPSO_SO_ID_ANALOGUE_OUTPUT 3203
+#define IPSO_SO_ID_GENERIC_SENSOR 3300
+#define IPSO_SO_ID_ILLUMINANCE_SENSOR 3301
+#define IPSO_SO_ID_PRESENCE_SENSOR 3302
+#define IPSO_SO_ID_TEMPERATURE_SENSOR 3303
+#define IPSO_SO_ID_HUMIDITY_SENSOR 3304
+#define IPSO_SO_ID_POWER_MEASUREMENT 3305
+#define IPSO_SO_ID_ACTUATION 3306
+#define IPSO_SO_ID_SET_POINT 3308
+#define IPSO_SO_ID_LOAD_CONTROL 3310
+#define IPSO_SO_ID_LIGHT_CONTROL 3311
+#define IPSO_SO_ID_POWER_CONTROL 3312
+#define IPSO_SO_ID_ACCELEROMETER 3313
+#define IPSO_SO_ID_MAGNETOMETER 3314
+#define IPSO_SO_ID_BAROMETER 3315
+
+/** @brief IPSO Reusable Resource IDs (Section 21). */
+#define IPSO_RR_ID_DIGITAL_INPUT_STATE 5500
+#define IPSO_RR_ID_DIGITAL_INPUT_COUNTER 5501
+#define IPSO_RR_ID_DIGITAL_INPUT_POLARITY 5502
+#define IPSO_RR_ID_DIGITAL_INPUT_DEBOUNCE_PERIOD 5503
+#define IPSO_RR_ID_DIGITAL_INPUT_EDGE_SELECTION 5504
+#define IPSO_RR_ID_DIGITAL_INPUT_COUNTER_RESET 5505
+
+#define IPSO_RR_ID_DIGITAL_OUTPUT_STATE 5550
+#define IPSO_RR_ID_DIGITAL_OUTPUT_POLARITY 5551
+
+
+// Digital output polarity options.
+#define IPSO_RR_ID_DIGITAL_OUTPUT_POLARITY_NORMAL 0
+#define IPSO_RR_ID_DIGITAL_OUTPUT_POLARITY_REVERSED 1
+
+#define IPSO_RR_ID_ANALOG_INPUT_CURRENT_VALUE 5600
+#define IPSO_RR_ID_MIN_MEASURED_VALUE 5601
+#define IPSO_RR_ID_MAX_MEASURED_VALUE 5602
+#define IPSO_RR_ID_MIN_RANGE_VALUE 5603
+#define IPSO_RR_ID_MAX_RANGE_VALUE 5604
+#define IPSO_RR_ID_RESET_MIN_MAX_MEASURED_VALUES 5605
+
+#define IPSO_RR_ID_ANALOG_OUTPUT_CURRENT_VALUE 5650
+
+#define IPSO_RR_ID_SENSOR_VALUE 5700
+#define IPSO_RR_ID_SENSOR_UNITS 5701
+#define IPSO_RR_ID_X_VALUE 5702
+#define IPSO_RR_ID_Y_VALUE 5703
+#define IPSO_RR_ID_Z_VALUE 5704
+#define IPSO_RR_ID_COMPASS_DIRECTION 5705
+#define IPSO_RR_ID_COLOUR 5706
+
+#define IPSO_RR_ID_APPLICATION_TYPE 5750
+#define IPSO_RR_ID_SENSOR_TYPE 5751
+
+#define IPSO_RR_ID_INSTANTANEOUS_ACTIVE_POWER 5800
+#define IPSO_RR_ID_MIN_MEASURED_ACTIVE_POWER 5801
+#define IPSO_RR_ID_MAX_MEASURED_ACTIVE_POWER 5802
+#define IPSO_RR_ID_MIN_RANGE_ACTIVE_POWER 5803
+#define IPSO_RR_ID_MAX_RANGE_ACTIVE_POWER 5804
+#define IPSO_RR_ID_CUMULATIVE_ACTIVE_POWER 5805
+#define IPSO_RR_ID_ACTIVE_POWER_CALIBRATION 5806
+
+#define IPSO_RR_ID_INSTANTANEOUS_REACTIVE_POWER 5810
+#define IPSO_RR_ID_MIN_MEASURED_REACTIVE_POWER 5811
+#define IPSO_RR_ID_MAX_MEASURED_REACTIVE_POWER 5812
+#define IPSO_RR_ID_MIN_RANGE_REACTIVE_POWER 5813
+#define IPSO_RR_ID_MAX_RANGE_REACTIVE_POWER 5814
+#define IPSO_RR_ID_CUMULATIVE_REACTIVE_POWER 5815
+#define IPSO_RR_ID_REACTIVE_POWER_CALIBRATION 5816
+
+#define IPSO_RR_ID_POWER_FACTOR 5820
+#define IPSO_RR_ID_CURRENT_CALIBRATION 5821
+#define IPSO_RR_ID_RESET_CUMULATIVE_ENERGY 5822
+#define IPSO_RR_ID_EVENT_IDENTIFIER 5823
+#define IPSO_RR_ID_START_TIME 5824
+#define IPSO_RR_ID_DURATION_IN_MIN 5825
+#define IPSO_RR_ID_CRITICALITY_LEVEL 5826
+#define IPSO_RR_ID_AVG_LOAD_ADJPCT 5827
+#define IPSO_RR_ID_DUTY_CYCLE 5828
+
+#define IPSO_RR_ID_ON_OFF 5850
+#define IPSO_RR_ID_DIMMER 5851
+#define IPSO_RR_ID_ON_TIME 5852
+#define IPSO_RR_ID_MULTI_STATE_OUTPUT 5853
+
+#define IPSO_RR_ID_SETPOINT_VALUE 5900
+
+#define IPSO_RR_ID_BUSY_TO_CLEAR_DELAY 5903
+#define IPSO_RR_ID_CLEAR_TO_BUSY_DELAY 5904
+
+
+
+/* Digital input ID: 3200 */
+typedef struct
+{
+ lwm2m_instance_prototype_t proto; /* Internal. */
+ uint8_t operations[8]; /* Internal. */
+ uint16_t resource_ids[8]; /* Internal. */
+
+ /* Public members. */
+ bool state;
+ uint32_t counter;
+ bool polarity;
+ uint32_t debounce_period; /* Unit: milliseconds */
+ uint8_t edge_selection; /* Range: 1-3 */
+ /* Counter reset is execute only */
+ lwm2m_string_t application_type;
+ lwm2m_string_t sensor_type;
+
+} ipso_digital_input_t;
+
+
+/* Digital output ID: 3201 */
+typedef struct
+{
+ lwm2m_instance_prototype_t proto; /* Internal. MUST be first. */
+ uint8_t operations[3]; /* Internal. MUST be second. */
+ uint16_t resource_ids[3]; /* Internal. MUST be third. */
+
+ /* Public members. */
+ bool digital_output_state;
+ bool digital_output_polarity;
+ lwm2m_string_t application_type;
+
+} ipso_digital_output_t;
+
+/* Analog input ID: 3202 */
+typedef struct
+{
+ lwm2m_instance_prototype_t proto; /* Internal. */
+ uint8_t operations[8]; /* Internal. */
+ uint16_t resource_ids[8]; /* Internal. */
+
+ /* Public members. */
+ float current_value;
+ float min_measured_value;
+ float max_measured_value;
+ float min_range_value;
+ float max_range_value;
+ /* Reset min and max measured values is execute only */
+ lwm2m_string_t application_type;
+ lwm2m_string_t sensor_type;
+} ipso_analog_input_t;
+
+/* Analog output ID: 3203 */
+typedef struct
+{
+ lwm2m_instance_prototype_t proto; /* Internal. */
+ uint8_t operations[4]; /* Internal. */
+ uint16_t resource_ids[4]; /* Internal. */
+
+ /* Public members. */
+ float current_value;
+ float min_range_value;
+ float max_range_value;
+ lwm2m_string_t application_type;
+
+} ipso_analog_output_t;
+
+/* Generic sensor ID: 3300 */
+typedef struct
+{
+ lwm2m_instance_prototype_t proto; /* Internal. */
+ uint8_t operations[9]; /* Internal. */
+ uint16_t resource_ids[9]; /* Internal. */
+
+ /* Public members. */
+ float sensor_value;
+ lwm2m_string_t units;
+ float min_measured_value;
+ float max_measured_value;
+ float min_range_value;
+ float max_range_value;
+ /* Reset min and max measured values is execute only */
+ lwm2m_string_t application_type;
+ lwm2m_string_t sensor_type;
+
+} ipso_generic_sensor_t;
+
+/* Illuminance ID: 3301 */
+typedef struct
+{
+ lwm2m_instance_prototype_t proto; /* Internal. */
+ uint8_t operations[7]; /* Internal. */
+ uint16_t resource_ids[7]; /* Internal. */
+
+ /* Public members. */
+ float sensor_value;
+ lwm2m_string_t units;
+ float min_measured_value;
+ float max_measured_value;
+ float min_range_value;
+ float max_range_value;
+ /* Reset min and max measured values is execute only */
+
+} ipso_illuminance_t;
+
+/* Presence ID: 3302 */
+typedef struct
+{
+ lwm2m_instance_prototype_t proto; /* Internal. */
+ uint8_t operations[8]; /* Internal. */
+ uint16_t resource_ids[8]; /* Internal. */
+
+ /* Public members. */
+ bool digital_input_state;
+ uint32_t digital_input_counter;
+ /* Digital input counter reset is execute only */
+ lwm2m_string_t sensor_type;
+ uint32_t busy_to_clear_delay; // Unit: ms
+ uint32_t clear_to_busy_delay; // Unit: ms
+
+
+} ipso_presence_t;
+
+/* Temperature ID: 3303 */
+typedef struct
+{
+ lwm2m_instance_prototype_t proto; /* Internal. */
+ uint8_t operations[7]; /* Internal. */
+ uint16_t resource_ids[7]; /* Internal. */
+
+ /* Public members. */
+ float sensor_value;
+ lwm2m_string_t units;
+ float min_measured_value;
+ float max_measured_value;
+ float min_range_value;
+ float max_range_value;
+ /* Reset min and max measured values is execute only */
+
+
+} ipso_temperature_t;
+
+/* Humidity ID: 3304 */
+typedef struct
+{
+ lwm2m_instance_prototype_t proto; /* Internal. */
+ uint8_t operations[8]; /* Internal. */
+ uint16_t resource_ids[8]; /* Internal. */
+
+ /* Public members. */
+ float sensor_value;
+ lwm2m_string_t units;
+ float min_measured_value;
+ float max_measured_value;
+ float min_range_value;
+ float max_range_value;
+ /* Reset min and max measured values is execute only */
+
+} ipso_humidity_t;
+
+/* Power measurement ID: 3305 */
+typedef struct
+{
+ lwm2m_instance_prototype_t proto; /* Internal. */
+ uint8_t operations[18]; /* Internal. */
+ uint16_t resource_ids[18]; /* Internal. */
+
+ /* Public members. */
+ float instantaneous_active_power;
+ float min_measured_active_power;
+ float max_measured_active_power;
+ float min_range_active_power;
+ float max_range_active_power;
+ float cumulative_active_power;
+ float active_power_calibration;
+ float instantaneous_reactive_power;
+ float min_measured_reactive_power;
+ float max_measured_reactive_power;
+ float min_range_reactive_power;
+ float max_range_reactive_power;
+ /* Reset min and max measured values is execute only */
+ float cumulative_reactive_power;
+ float reactive_power_calibration;
+ float power_factor;
+ float current_calibration;
+ /* Reset cumulative is execute only */
+
+} ipso_power_measurement_t;
+
+/* Actuation ID: 3306 */
+typedef struct
+{
+ lwm2m_instance_prototype_t proto; /* Internal. */
+ uint8_t operations[5]; /* Internal. */
+ uint16_t resource_ids[5]; /* Internal. */
+
+ /* Public members. */
+ bool on;
+ uint16_t dimmer; // Unit: % Range: 0 - 100
+ uint32_t on_time; // Unit: s
+ lwm2m_string_t multi_state_output;
+ lwm2m_string_t application_type;
+
+} ipso_actuation_t;
+
+/* Set point ID: 3308 */
+typedef struct
+{
+ lwm2m_instance_prototype_t proto; /* Internal. */
+ uint8_t operations[4]; /* Internal. */
+ uint16_t resource_ids[4]; /* Internal. */
+
+ /* Public members. */
+ float set_point_value;
+ lwm2m_string_t colour;
+ lwm2m_string_t units;
+ lwm2m_string_t application_type;
+
+} ipso_set_point_t;
+
+/* Load control ID: 3310 */
+typedef struct
+{
+ lwm2m_instance_prototype_t proto; /* Internal. */
+ uint8_t operations[6]; /* Internal. */
+ uint16_t resource_ids[6]; /* Internal. */
+
+ /* Public members. */
+ lwm2m_string_t event_identifier;
+ lwm2m_time_t start_time;
+ uint32_t duration_in_min;
+ uint8_t criticality_level; // Range: 0-3
+ uint16_t avg_load_adjpct; // Unit: % range: 0-100
+ uint16_t duty_cycle; // Unit: % range: 0-100
+
+
+} ipso_load_control_t;
+
+/* Light control ID: 3311 */
+typedef struct
+{
+ lwm2m_instance_prototype_t proto; /* Internal. */
+ uint8_t operations[7]; /* Internal. */
+ uint16_t resource_ids[7]; /* Internal. */
+
+ /* Public members. */
+ bool on;
+ uint16_t dimmer; // Unit: % Range: 0 - 100
+ lwm2m_string_t colour;
+ lwm2m_string_t units;
+ uint32_t on_time; // Unit: s
+ float cumulative_active_power;
+ float power_factor;
+
+} ipso_light_control_t;
+
+/* Power control ID: 3312 */
+typedef struct
+{
+ lwm2m_instance_prototype_t proto; /* Internal. */
+ uint8_t operations[5]; /* Internal. */
+ uint16_t resource_ids[5]; /* Internal. */
+
+ /* Public members. */
+ bool on;
+ uint16_t dimmer; // Unit: % Range: 0 - 100
+ uint32_t on_time; // Unit: s
+ float cumulative_active_power;
+ float power_factor;
+
+} ipso_power_control_t;
+
+/* Accelerometer ID: 3313 */
+typedef struct
+{
+ lwm2m_instance_prototype_t proto; /* Internal. */
+ uint8_t operations[6]; /* Internal. */
+ uint16_t resource_ids[6]; /* Internal. */
+
+ /* Public members. */
+ float x_value;
+ float y_value;
+ float z_value;
+ lwm2m_string_t units;
+ float min_range_value;
+ float max_range_value;
+
+} ipso_accelerometer_t;
+
+/* Magnetometer ID: 3314 */
+typedef struct
+{
+ lwm2m_instance_prototype_t proto; /* Internal. */
+ uint8_t operations[8]; /* Internal. */
+ uint16_t resource_ids[8]; /* Internal. */
+
+ /* Public members. */
+ float x_value;
+ float y_value;
+ float z_value;
+ lwm2m_string_t units;
+ float compass_direction; // Unit: deg Range: 0-360
+
+} ipso_magnetometer_t;
+
+/* Barometer ID: 3315 */
+typedef struct
+{
+ lwm2m_instance_prototype_t proto; /* Internal. */
+ uint8_t operations[7]; /* Internal. */
+ uint16_t resource_ids[7]; /* Internal. */
+
+ /* Public members. */
+ float sensor_value;
+ lwm2m_string_t units;
+ float min_measured_value;
+ float max_measured_value;
+ float min_range_value;
+ float max_range_value;
+ /* Reset min and max measured values is execute only */
+
+} ipso_barometer_t;
+
+
+/**@brief Initialize an IPSO digital input object instance.
+ *
+ * @details Must be called before any use of the instance.
+ *
+ * @param[in] p_instance Pointer to instance structure to initialize.
+ */
+void ipso_instance_digital_input_init(ipso_digital_input_t * p_instance);
+
+/**@brief Initialize an IPSO digital output object instance.
+ *
+ * @details Must be called before any use of the instance.
+ *
+ * @param[in] p_instance Pointer to instance structure to initialize.
+ */
+void ipso_instance_digital_output_init(ipso_digital_output_t * p_instance);
+
+/**@brief Initialize an IPSO analog input object instance.
+ *
+ * @details Must be called before any use of the instance.
+ *
+ * @param[in] p_instance Pointer to instance structure to initialize.
+ */
+void ipso_instance_analog_input_init(ipso_analog_input_t * p_instance);
+
+/**@brief Initialize an IPSO analog output object instance.
+ *
+ * @details Must be called before any use of the instance.
+ *
+ * @param[in] p_instance Pointer to instance structure to initialize.
+ */
+void ipso_instance_analog_output_init(ipso_analog_output_t * p_instance);
+
+/**@brief Initialize an IPSO generic sensor object instance.
+ *
+ * @details Must be called before any use of the instance.
+ *
+ * @param[in] p_instance Pointer to instance structure to initialize.
+ */
+void ipso_instance_generic_sensor_init(ipso_generic_sensor_t * p_instance);
+
+/**@brief Initialize an IPSO illuminance object instance.
+ *
+ * @details Must be called before any use of the instance.
+ *
+ * @param[in] p_instance Pointer to instance structure to initialize.
+ */
+void ipso_instance_illuminance_init(ipso_illuminance_t * p_instance);
+
+/**@brief Initialize an IPSO presence object instance.
+ *
+ * @details Must be called before any use of the instance.
+ *
+ * @param[in] p_instance Pointer to instance structure to initialize.
+ */
+void ipso_instance_presence_init(ipso_presence_t * p_instance);
+
+/**@brief Initialize an IPSO temperature object instance.
+ *
+ * @details Must be called before any use of the instance.
+ *
+ * @param[in] p_instance Pointer to instance structure to initialize.
+ */
+void ipso_instance_temperature_init(ipso_temperature_t * p_instance);
+
+/**@brief Initialize an IPSO humidity object instance.
+ *
+ * @details Must be called before any use of the instance.
+ *
+ * @param[in] p_instance Pointer to instance structure to initialize.
+ */
+void ipso_instance_humidity_init(ipso_humidity_t * p_instance);
+
+/**@brief Initialize an IPSO power measurement object instance.
+ *
+ * @details Must be called before any use of the instance.
+ *
+ * @param[in] p_instance Pointer to instance structure to initialize.
+ */
+void ipso_instance_power_measurement_init(ipso_power_measurement_t * p_instance);
+
+/**@brief Initialize an IPSO actuation object instance.
+ *
+ * @details Must be called before any use of the instance.
+ *
+ * @param[in] p_instance Pointer to instance structure to initialize.
+ */
+void ipso_instance_actuation_init(ipso_actuation_t * p_instance);
+
+/**@brief Initialize an IPSO set point object instance.
+ *
+ * @details Must be called before any use of the instance.
+ *
+ * @param[in] p_instance Pointer to instance structure to initialize.
+ */
+void ipso_instance_set_point_init(ipso_set_point_t * p_instance);
+
+/**@brief Initialize an IPSO load control object instance.
+ *
+ * @details Must be called before any use of the instance.
+ *
+ * @param[in] p_instance Pointer to instance structure to initialize.
+ */
+void ipso_instance_load_control_init(ipso_load_control_t * p_instance);
+
+/**@brief Initialize an IPSO light control object instance.
+ *
+ * @details Must be called before any use of the instance.
+ *
+ * @param[in] p_instance Pointer to instance structure to initialize.
+ */
+void ipso_instance_light_control_init(ipso_light_control_t * p_instance);
+
+/**@brief Initialize an IPSO power control object instance.
+ *
+ * @details Must be called before any use of the instance.
+ *
+ * @param[in] p_instance Pointer to instance structure to initialize.
+ */
+void ipso_instance_power_control_init(ipso_power_control_t * p_instance);
+
+/**@brief Initialize an IPSO accelerometer object instance.
+ *
+ * @details Must be called before any use of the instance.
+ *
+ * @param[in] p_instance Pointer to instance structure to initialize.
+ */
+void ipso_instance_accelerometer_init(ipso_accelerometer_t * p_instance);
+
+/**@brief Initialize an IPSO magnetometer object instance.
+ *
+ * @details Must be called before any use of the instance.
+ *
+ * @param[in] p_instance Pointer to instance structure to initialize.
+ */
+void ipso_instance_magnetometer_init(ipso_magnetometer_t * p_instance);
+
+/**@brief Initialize an IPSO barometer object instance.
+ *
+ * @details Must be called before any use of the instance.
+ *
+ * @param[in] p_instance Pointer to instance structure to initialize.
+ */
+void ipso_instance_barometer_init(ipso_barometer_t * p_instance);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // LWM2M_OBJECTS_H__
+
+/** @} */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/lwm2m/ipso_objects_tlv.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/lwm2m/ipso_objects_tlv.c
new file mode 100644
index 0000000..5cb53ec
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/lwm2m/ipso_objects_tlv.c
@@ -0,0 +1,143 @@
+/**
+ * Copyright (c) 2015 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#include "ipso_objects_tlv.h"
+#include "lwm2m_tlv.h"
+
+static void index_buffer_len_update(uint32_t * index, uint32_t * buffer_len, uint32_t max_buffer)
+{
+ *index += *buffer_len;
+ *buffer_len = max_buffer - *index;
+}
+
+uint32_t ipso_tlv_ipso_digital_output_decode(ipso_digital_output_t * p_digital_output,
+ uint8_t * p_buffer,
+ uint32_t buffer_len)
+{
+ uint32_t err_code;
+ lwm2m_tlv_t tlv;
+
+ uint32_t index = 0;
+
+ while (index < buffer_len)
+ {
+ err_code = lwm2m_tlv_decode(&tlv, &index, p_buffer, buffer_len);
+
+ if (err_code != NRF_SUCCESS)
+ {
+ return err_code;
+ }
+
+ switch (tlv.id)
+ {
+ case IPSO_RR_ID_DIGITAL_OUTPUT_STATE:
+ {
+ p_digital_output->digital_output_state = tlv.value[0];
+ break;
+ }
+
+ case IPSO_RR_ID_DIGITAL_OUTPUT_POLARITY:
+ {
+ p_digital_output->digital_output_polarity = tlv.value[0];
+ break;
+ }
+
+ case IPSO_RR_ID_APPLICATION_TYPE:
+ {
+ p_digital_output->application_type.p_val = (char *)tlv.value;
+ p_digital_output->application_type.len = tlv.length;
+ break;
+ }
+
+ default:
+ break;
+ }
+ }
+
+ return NRF_SUCCESS;
+}
+
+uint32_t ipso_tlv_ipso_digital_output_encode(uint8_t * p_buffer,
+ uint32_t * p_buffer_len,
+ ipso_digital_output_t * p_digital_output)
+{
+ uint32_t err_code;
+ uint32_t max_buffer = *p_buffer_len;
+ uint32_t index = 0;
+
+ lwm2m_tlv_t tlv;
+ tlv.id_type = TLV_TYPE_RESOURCE_VAL; // type is the same for all.
+
+ // Encode state.
+ lwm2m_tlv_bool_set(&tlv, p_digital_output->digital_output_state, IPSO_RR_ID_DIGITAL_OUTPUT_STATE);
+ err_code = lwm2m_tlv_encode(p_buffer + index, p_buffer_len, &tlv);
+
+ if (err_code != NRF_SUCCESS)
+ {
+ return err_code;
+ }
+
+ index_buffer_len_update(&index, p_buffer_len, max_buffer);
+
+ // Encode polarity.
+ lwm2m_tlv_bool_set(&tlv, p_digital_output->digital_output_polarity, IPSO_RR_ID_DIGITAL_OUTPUT_POLARITY);
+ err_code = lwm2m_tlv_encode(p_buffer + index, p_buffer_len, &tlv);
+
+ if (err_code != NRF_SUCCESS)
+ {
+ return err_code;
+ }
+
+ index_buffer_len_update(&index, p_buffer_len, max_buffer);
+
+ // Encode application type.
+ lwm2m_tlv_string_set(&tlv, p_digital_output->application_type, IPSO_RR_ID_APPLICATION_TYPE);
+ err_code = lwm2m_tlv_encode(p_buffer + index, p_buffer_len, &tlv);
+
+ if (err_code != NRF_SUCCESS)
+ {
+ return err_code;
+ }
+
+ index_buffer_len_update(&index, p_buffer_len, max_buffer);
+
+ *p_buffer_len = index;
+
+ return NRF_SUCCESS;
+}
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/lwm2m/ipso_objects_tlv.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/lwm2m/ipso_objects_tlv.h
new file mode 100644
index 0000000..e2c1228
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/lwm2m/ipso_objects_tlv.h
@@ -0,0 +1,94 @@
+/**
+ * Copyright (c) 2015 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 lwm2m_objects_tlv.h
+ *
+ * @defgroup iot_sdk_ipso_objects_tlv IPSO Smart Object TLV encoder and decoder API
+ * @ingroup iot_sdk_lwm2m
+ * @{
+ * @brief IPSO Smart Object TLV encoder and decoder API.
+ */
+
+#ifndef IPSO_OBJECTS_TLV_H__
+#define IPSO_OBJECTS_TLV_H__
+
+#include <stdint.h>
+#include "ipso_objects.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**@brief Decode an IPSO digital output object from a TLV byte buffer.
+ *
+ * @note Resource values NOT found in the tlv will not be altered.
+ *
+ * @warning lwm2m_string_t and lwm2m_opaque_t values will point to the byte buffer and needs
+ * to be copied by the application before the byte buffer is freed.
+ *
+ * @param[out] p_digital_output Pointer to a LWM2M server object to be filled by the decoded TLVs.
+ * @param[in] p_buffer Pointer to the TLV byte buffer to be decoded.
+ * @param[in] buffer_len Size of the buffer to be decoded.
+ *
+ * @retval NRF_SUCCESS If decoding was successfull.
+ */
+uint32_t ipso_tlv_ipso_digital_output_decode(ipso_digital_output_t * p_digital_output,
+ uint8_t * p_buffer,
+ uint32_t buffer_len);
+
+/**@brief Encode an IPSO digital output object to a TLV byte buffer.
+ *
+ * @param[out] p_buffer Pointer to a byte buffer to be used to fill the encoded TLVs.
+ * @param[inout] p_buffer_len Value by reference inicating the size of the buffer provided.
+ * Will return the number of used bytes on return.
+ * @param[in] p_digital_output Pointer to the IPSO digital output object to be encoded into TLVs.
+ *
+ * @retval NRF_SUCCESS If the encoded was successfull.
+ */
+uint32_t ipso_tlv_ipso_digital_output_encode(uint8_t * p_buffer,
+ uint32_t * p_buffer_len,
+ ipso_digital_output_t * p_digital_output);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // IPSO_OBJECTS_TLV_H__
+
+/** @} */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/lwm2m/lwm2m.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/lwm2m/lwm2m.c
new file mode 100644
index 0000000..bc022f1
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/lwm2m/lwm2m.c
@@ -0,0 +1,885 @@
+/**
+ * Copyright (c) 2015 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#include <string.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <ctype.h>
+
+#include "lwm2m_api.h"
+#include "lwm2m_register.h"
+#include "lwm2m_bootstrap.h"
+#include "sdk_os.h"
+#include "lwm2m.h"
+#include "sdk_config.h"
+
+#if LWM2M_CONFIG_LOG_ENABLED
+
+#define NRF_LOG_MODULE_NAME lwm2m
+
+#define NRF_LOG_LEVEL LWM2M_CONFIG_LOG_LEVEL
+#define NRF_LOG_INFO_COLOR LWM2M_CONFIG_INFO_COLOR
+#define NRF_LOG_DEBUG_COLOR LWM2M_CONFIG_DEBUG_COLOR
+
+#include "nrf_log.h"
+NRF_LOG_MODULE_REGISTER();
+
+#define LWM2M_TRC NRF_LOG_DEBUG /**< Used for getting trace of execution in the module. */
+#define LWM2M_ERR NRF_LOG_ERROR /**< Used for logging errors in the module. */
+#define LWM2M_DUMP NRF_LOG_HEXDUMP_DEBUG /**< Used for dumping octet information to get details of bond information etc. */
+
+#define LWM2M_ENTRY() LWM2M_TRC(">> %s", __func__)
+#define LWM2M_EXIT() LWM2M_TRC("<< %s", __func__)
+
+#else // LWM2M_CONFIG_LOG_ENABLED
+
+#define LWM2M_TRC(...) /**< Disables traces. */
+#define LWM2M_DUMP(...) /**< Disables dumping of octet streams. */
+#define LWM2M_ERR(...) /**< Disables error logs. */
+
+#define LWM2M_ENTRY(...)
+#define LWM2M_EXIT(...)
+
+#endif // LWM2M_CONFIG_LOG_ENABLED
+
+#if (LWM2M_CONFIG_LOG_ENABLED != 0)
+
+static uint8_t op_desc_idx_lookup(uint8_t bitmask)
+{
+ for (uint8_t i = 0; i < 8; i++)
+ {
+ if ((bitmask > i) == 0x1)
+ {
+ return i;
+ }
+ }
+
+ // If no bits where set in the bitmask.
+ return 0;
+}
+
+static const char m_operation_desc[8][9] = {
+ "NONE",
+ "READ",
+ "WRITE",
+ "EXECUTE",
+ "DELETE",
+ "CREATE",
+ "DISCOVER",
+ "OBSERVE"
+};
+
+#endif
+
+SDK_MUTEX_DEFINE(m_lwm2m_mutex) /**< Mutex variable. Currently unused, this declaration does not occupy any space in RAM. */
+
+static lwm2m_object_prototype_t * m_objects[LWM2M_COAP_HANDLER_MAX_OBJECTS];
+static lwm2m_instance_prototype_t * m_instances[LWM2M_COAP_HANDLER_MAX_INSTANCES];
+static uint16_t m_num_objects;
+static uint16_t m_num_instances;
+
+static void coap_error_handler(uint32_t error_code, coap_message_t * p_message)
+{
+ LWM2M_ERR("[CoAP]: Unhandled coap message recieved. Error code: %lu", error_code);
+}
+
+static void internal_coap_handler_init(void)
+{
+ memset(m_objects, 0, sizeof(m_objects));
+ memset(m_instances, 0, sizeof(m_instances));
+
+ m_num_objects = 0;
+ m_num_instances = 0;
+}
+
+
+static bool numbers_only(const char * p_str, uint16_t str_len)
+{
+ for (uint16_t i = 0; i < str_len; i++)
+ {
+ if (isdigit(p_str[i]) == 0)
+ {
+ return false;
+ }
+ }
+ return true;
+}
+
+
+static uint32_t instance_resolve(lwm2m_instance_prototype_t ** p_instance,
+ uint16_t object_id,
+ uint16_t instance_id)
+{
+ for (int i = 0; i < m_num_instances; ++i)
+ {
+ if (m_instances[i]->object_id == object_id &&
+ m_instances[i]->instance_id == instance_id)
+ {
+ if (m_instances[i]->callback == NULL)
+ {
+ return NRF_ERROR_NULL;
+ }
+
+ *p_instance = m_instances[i];
+
+ return NRF_SUCCESS;
+ }
+ }
+
+ return NRF_ERROR_NOT_FOUND;
+}
+
+
+static uint32_t object_resolve(lwm2m_object_prototype_t ** p_instance,
+ uint16_t object_id)
+{
+ for (int i = 0; i < m_num_objects; ++i)
+ {
+ if (m_objects[i]->object_id == object_id)
+ {
+ if (m_objects[i]->callback == NULL)
+ {
+ return NRF_ERROR_NULL;
+ }
+
+ *p_instance = m_objects[i];
+
+ return NRF_SUCCESS;
+ }
+ }
+
+ return NRF_ERROR_NOT_FOUND;
+}
+
+static uint32_t op_code_resolve(lwm2m_instance_prototype_t * p_instance,
+ uint16_t resource_id,
+ uint8_t * operation)
+{
+ uint8_t * operations = (uint8_t *) p_instance + p_instance->operations_offset;
+ uint16_t * operations_ids = (uint16_t *)((uint8_t *) p_instance +
+ p_instance->resource_ids_offset);
+
+ for (int j = 0; j < p_instance->num_resources; ++j)
+ {
+ if (operations_ids[j] == resource_id)
+ {
+ *operation = operations[j];
+ return NRF_SUCCESS;
+ }
+ }
+
+ return NRF_ERROR_NOT_FOUND;
+}
+
+static uint32_t internal_request_handle(coap_message_t * p_request,
+ uint16_t * p_path,
+ uint8_t path_len)
+{
+ uint32_t err_code;
+ uint8_t operation = LWM2M_OPERATION_CODE_NONE;
+ uint32_t content_type = 0;
+
+ err_code = coap_message_ct_mask_get(p_request, &content_type);
+ if (err_code != NRF_SUCCESS)
+ {
+ return err_code;
+ }
+
+ /**
+ * TODO: the methods should check if we have read / write / execute rights
+ * through ACL and resource operations
+ */
+
+ switch (p_request->header.code)
+ {
+ case COAP_CODE_GET:
+ {
+ LWM2M_TRC("[CoAP]: CoAP GET request");
+ if (content_type == COAP_CT_APP_LINK_FORMAT) // Discover
+ {
+ operation = LWM2M_OPERATION_CODE_DISCOVER;
+ }
+ else // Read
+ {
+ operation = LWM2M_OPERATION_CODE_READ;
+ }
+ break;
+ }
+
+ case COAP_CODE_PUT:
+ {
+ operation = LWM2M_OPERATION_CODE_WRITE;
+ break;
+ }
+
+ case COAP_CODE_POST:
+ {
+ operation = LWM2M_OPERATION_CODE_WRITE;
+ break;
+ }
+
+ case COAP_CODE_DELETE:
+ {
+ operation = LWM2M_OPERATION_CODE_DELETE;
+ break;
+ }
+
+ default:
+ break; // Maybe send response with unsupported method not allowed?
+ }
+
+ err_code = NRF_ERROR_NOT_FOUND;
+
+ switch (path_len)
+ {
+ case 0:
+ {
+ if (operation == LWM2M_OPERATION_CODE_DELETE)
+ {
+ LWM2M_TRC("[CoAP]: >> %s root /",
+ m_operation_desc[op_desc_idx_lookup(operation)]);
+
+ LWM2M_MUTEX_UNLOCK();
+
+ err_code = lwm2m_coap_handler_root(LWM2M_OPERATION_CODE_DELETE, p_request);
+
+ LWM2M_MUTEX_LOCK();
+
+ LWM2M_TRC("[CoAP]: << %s root /",
+ m_operation_desc[op_desc_idx_lookup(operation)]);
+ }
+ break;
+ }
+
+ case 1:
+ {
+ LWM2M_TRC("[CoAP]: >> %s object /%u/",
+ m_operation_desc[op_desc_idx_lookup(operation)],
+ p_path[0]);
+
+ lwm2m_object_prototype_t * p_object;
+
+ err_code = object_resolve(&p_object, p_path[0]);
+
+ if (err_code != NRF_SUCCESS)
+ {
+ break;
+ }
+
+ LWM2M_MUTEX_UNLOCK();
+
+ err_code = p_object->callback(p_object, LWM2M_INVALID_INSTANCE, operation, p_request);
+
+ LWM2M_MUTEX_LOCK();
+
+ LWM2M_TRC("[CoAP]: << %s object /%u/, result: %s",
+ m_operation_desc[op_desc_idx_lookup(operation)],
+ p_path[0],
+ (err_code == NRF_SUCCESS) ? "SUCCESS" : "NOT_FOUND");
+
+ break;
+ }
+
+ case 2:
+ {
+ LWM2M_TRC("[CoAP]: >> %s instance /%u/%u/",
+ m_operation_desc[op_desc_idx_lookup(operation)],
+ p_path[0],
+ p_path[1]);
+
+ lwm2m_instance_prototype_t * p_instance;
+
+ err_code = instance_resolve(&p_instance, p_path[0], p_path[1]);
+ if (err_code == NRF_SUCCESS)
+ {
+ LWM2M_MUTEX_UNLOCK();
+
+ err_code = p_instance->callback(p_instance, LWM2M_INVALID_RESOURCE, operation, p_request);
+
+ LWM2M_MUTEX_LOCK();
+
+ LWM2M_TRC("[CoAP]: << %s instance /%u/%u/, result: %s",
+ m_operation_desc[op_desc_idx_lookup(operation)],
+ p_path[0],
+ p_path[1],
+ (err_code == NRF_SUCCESS) ? "SUCCESS" : "NOT_FOUND");
+ break;
+ }
+
+ // Bootstrap can write to non-existing instances
+ if (err_code == NRF_ERROR_NOT_FOUND &&
+ operation == LWM2M_OPERATION_CODE_WRITE &&
+ p_request->header.code == COAP_CODE_PUT)
+ {
+ LWM2M_TRC("[CoAP]: >> %s object /%u/%u/",
+ m_operation_desc[op_desc_idx_lookup(operation)],
+ p_path[0],
+ p_path[1]);
+
+ lwm2m_object_prototype_t * p_object;
+
+ err_code = object_resolve(&p_object, p_path[0]);
+
+ if (err_code != NRF_SUCCESS)
+ {
+ break;
+ }
+
+ LWM2M_MUTEX_UNLOCK();
+
+ err_code = p_object->callback(p_object, p_path[1], operation, p_request);
+
+ LWM2M_MUTEX_LOCK();
+
+ LWM2M_TRC("[CoAP]: << %s object /%u/%u/, result: %s",
+ m_operation_desc[op_desc_idx_lookup(operation)],
+ p_path[0],
+ p_path[1],
+ (err_code == NRF_SUCCESS) ? "SUCCESS" : "NOT_FOUND");
+ }
+
+ if (err_code == NRF_ERROR_NOT_FOUND &&
+ operation == LWM2M_OPERATION_CODE_WRITE &&
+ p_request->header.code == COAP_CODE_POST)
+ {
+ LWM2M_TRC("[CoAP]: >> CREATE object /%u/%u/",
+ p_path[0],
+ p_path[1]);
+
+ lwm2m_object_prototype_t * p_object;
+
+ err_code = object_resolve(&p_object, p_path[0]);
+
+ if (err_code != NRF_SUCCESS)
+ {
+ break;
+ }
+
+ LWM2M_MUTEX_UNLOCK();
+
+ err_code = p_object->callback(p_object, p_path[1], LWM2M_OPERATION_CODE_CREATE, p_request);
+
+ LWM2M_MUTEX_LOCK();
+
+ LWM2M_TRC("[CoAP]: << CREATE object /%u/%u/, result: %s",
+ p_path[0],
+ p_path[1],
+ (err_code == NRF_SUCCESS) ? "SUCCESS" : "NOT_FOUND");
+ break;
+ }
+
+ break;
+ }
+
+ case 3:
+ {
+ if (operation == LWM2M_OPERATION_CODE_DELETE)
+ {
+ // Deleting resources within an instance not allowed.
+ break;
+ }
+
+ if (p_request->header.code == COAP_CODE_POST)
+ {
+ for (int i = 0; i < m_num_instances; ++i)
+ {
+ if ((m_instances[i]->object_id == p_path[0]) &&
+ (m_instances[i]->instance_id == p_path[1]))
+ {
+ if (m_instances[i]->callback == NULL)
+ {
+ err_code = NRF_ERROR_NULL;
+ break;
+ }
+
+ uint8_t resource_operation = 0;
+ err_code = op_code_resolve(m_instances[i], p_path[2], &resource_operation);
+
+ if (err_code != NRF_SUCCESS)
+ break;
+
+ if ((resource_operation & LWM2M_OPERATION_CODE_EXECUTE) > 0)
+ {
+ operation = LWM2M_OPERATION_CODE_EXECUTE;
+ }
+
+ if ((resource_operation & LWM2M_OPERATION_CODE_WRITE) > 0)
+ {
+ operation = LWM2M_OPERATION_CODE_WRITE;
+ }
+
+ LWM2M_TRC("[CoAP]: >> %s instance /%u/%u/%u/",
+ m_operation_desc[op_desc_idx_lookup(operation)],
+ m_instances[i]->object_id,
+ m_instances[i]->instance_id,
+ p_path[2]);
+
+ LWM2M_MUTEX_UNLOCK();
+
+ (void)m_instances[i]->callback(m_instances[i],
+ p_path[2],
+ operation,
+ p_request);
+
+ LWM2M_MUTEX_LOCK();
+
+ err_code = NRF_SUCCESS;
+
+ LWM2M_TRC("[CoAP]: << %s instance /%u/%u/%u/",
+ m_operation_desc[op_desc_idx_lookup(operation)],
+ m_instances[i]->object_id,
+ m_instances[i]->instance_id,
+ p_path[2]);
+
+ break;
+ }
+ }
+ }
+ else
+ {
+ LWM2M_TRC("[CoAP]: >> %s instance /%u/%u/%u/",
+ m_operation_desc[op_desc_idx_lookup(operation)],
+ p_path[0],
+ p_path[1],
+ p_path[2]);
+
+ lwm2m_instance_prototype_t * p_instance;
+
+ err_code = instance_resolve(&p_instance, p_path[0], p_path[1]);
+ if (err_code != NRF_SUCCESS)
+ {
+ break;
+ }
+
+ LWM2M_MUTEX_UNLOCK();
+
+ err_code = p_instance->callback(p_instance, p_path[2], operation, p_request);
+
+ LWM2M_MUTEX_LOCK();
+
+ LWM2M_TRC("[CoAP]: << %s instance /%u/%u/%u/, result: %s",
+ m_operation_desc[op_desc_idx_lookup(operation)],
+ p_path[0],
+ p_path[1],
+ p_path[2],
+ (err_code == NRF_SUCCESS) ? "SUCCESS" : "NOT_FOUND");
+ }
+ break;
+ }
+
+ default:
+ break;
+ }
+
+ return err_code;
+}
+
+
+static uint32_t lwm2m_coap_handler_handle_request(coap_message_t * p_request)
+{
+ LWM2M_ENTRY();
+
+ uint16_t index;
+ uint16_t path[3];
+ char * endptr;
+
+ bool is_numbers_only = true;
+ uint16_t path_index = 0;
+ uint32_t err_code = NRF_SUCCESS;
+
+ LWM2M_MUTEX_LOCK();
+
+ for (index = 0; index < p_request->options_count; index++)
+ {
+ if (p_request->options[index].number == COAP_OPT_URI_PATH)
+ {
+ uint16_t option_len = p_request->options[index].length;
+ bool numbers = numbers_only((char *)p_request->options[index].p_data,
+ option_len);
+
+ if (numbers)
+ {
+ // Declare a temporary array that is 1 byte longer than the
+ // option data in order to leave space for a terminating character.
+ uint8_t option_data[option_len + 1];
+ // Set the temporary array to zero.
+ memset(option_data, 0, sizeof(option_data));
+ // Copy the option data string to the temporary array.
+ memcpy(option_data, p_request->options[index].p_data, option_len);
+
+ // Convert the zero-terminated string to a long int value.
+ path[path_index] = strtol((char *)option_data, &endptr, 10);
+
+ ++path_index;
+
+ if (endptr == ((char *)option_data))
+ {
+ err_code = NRF_ERROR_NOT_FOUND;
+ break;
+ }
+
+ if (endptr != ((char *)option_data + option_len))
+ {
+ err_code = NRF_ERROR_NOT_FOUND;
+ break;
+ }
+ }
+ else
+ {
+ is_numbers_only = false;
+ break;
+ }
+ }
+ }
+
+ if (err_code == NRF_SUCCESS)
+ {
+ if (is_numbers_only == true)
+ {
+ err_code = internal_request_handle(p_request, path, path_index);
+ }
+ else
+ {
+ // If uri path did not consist of numbers only.
+ char * requested_uri = NULL;
+ for (index = 0; index < p_request->options_count; index++)
+ {
+ if (p_request->options[index].number == COAP_OPT_URI_PATH)
+ {
+ requested_uri = (char *)p_request->options[index].p_data;
+
+ // Stop on first URI hit.
+ break;
+ }
+ }
+
+ if (requested_uri == NULL)
+ {
+ err_code = NRF_ERROR_NOT_FOUND;
+ }
+ else
+ {
+ // Try to look up if there is a match with object with an alias name.
+ for (int i = 0; i < m_num_objects; ++i)
+ {
+ if (m_objects[i]->object_id == LWM2M_NAMED_OBJECT)
+ {
+ size_t size = strlen(m_objects[i]->p_alias_name);
+ if ((strncmp(m_objects[i]->p_alias_name, requested_uri, size) == 0))
+ {
+ if (m_objects[i]->callback == NULL)
+ {
+ err_code = NRF_ERROR_NULL;
+ break;
+ }
+
+ LWM2M_MUTEX_UNLOCK();
+
+ err_code = m_objects[i]->callback(m_objects[i],
+ LWM2M_INVALID_INSTANCE,
+ LWM2M_OPERATION_CODE_NONE,
+ p_request);
+
+ LWM2M_MUTEX_LOCK();
+
+ break;
+ }
+ }
+ else
+ {
+ // This is not a name object, return error code.
+ err_code = NRF_ERROR_NOT_FOUND;
+ break;
+ }
+ }
+ }
+ }
+ }
+
+ LWM2M_MUTEX_UNLOCK();
+
+ LWM2M_EXIT();
+
+ return err_code;
+}
+
+
+uint32_t lwm2m_coap_handler_instance_add(lwm2m_instance_prototype_t * p_instance)
+{
+ LWM2M_ENTRY();
+
+ NULL_PARAM_CHECK(p_instance);
+
+ LWM2M_MUTEX_LOCK();
+
+ if (m_num_instances == LWM2M_COAP_HANDLER_MAX_INSTANCES)
+ {
+ LWM2M_MUTEX_UNLOCK();
+
+ return NRF_ERROR_NO_MEM;
+ }
+
+ m_instances[m_num_instances] = p_instance;
+ ++m_num_instances;
+
+ LWM2M_MUTEX_UNLOCK();
+
+ return NRF_SUCCESS;
+}
+
+
+uint32_t lwm2m_coap_handler_instance_delete(lwm2m_instance_prototype_t * p_instance)
+{
+ LWM2M_ENTRY();
+
+ NULL_PARAM_CHECK(p_instance);
+
+ LWM2M_MUTEX_LOCK();
+
+ for (int i = 0; i < m_num_instances; ++i)
+ {
+ if ((m_instances[i]->object_id == p_instance->object_id) &&
+ (m_instances[i]->instance_id == p_instance->instance_id))
+ {
+ // Move current last entry into this index position, and trim down the length.
+ // If this is the last element, it cannot be accessed because the m_num_instances
+ // count is 0.
+ m_instances[i] = m_instances[m_num_instances - 1];
+ --m_num_instances;
+
+ LWM2M_MUTEX_UNLOCK();
+
+ return NRF_SUCCESS;
+ }
+ }
+
+ LWM2M_MUTEX_UNLOCK();
+
+ return NRF_ERROR_NOT_FOUND;
+}
+
+
+uint32_t lwm2m_coap_handler_object_add(lwm2m_object_prototype_t * p_object)
+{
+ LWM2M_ENTRY();
+
+ NULL_PARAM_CHECK(p_object);
+
+ LWM2M_MUTEX_LOCK();
+
+ if (m_num_objects == LWM2M_COAP_HANDLER_MAX_INSTANCES)
+ {
+ LWM2M_MUTEX_UNLOCK();
+
+ return NRF_ERROR_NO_MEM;
+ }
+
+ m_objects[m_num_objects] = p_object;
+ ++m_num_objects;
+
+ LWM2M_MUTEX_UNLOCK();
+
+ return NRF_SUCCESS;
+}
+
+
+uint32_t lwm2m_coap_handler_object_delete(lwm2m_object_prototype_t * p_object)
+{
+ LWM2M_ENTRY();
+
+ NULL_PARAM_CHECK(p_object);
+
+ LWM2M_MUTEX_LOCK();
+
+ for (int i = 0; i < m_num_objects; ++i)
+ {
+ if ( m_objects[i]->object_id == p_object->object_id)
+ {
+ // Move current last entry into this index position, and trim down the length.
+ // If this is the last element, it cannot be accessed because the m_num_objects
+ // count is 0.
+ m_objects[i] = m_objects[m_num_objects - 1];
+ --m_num_objects;
+
+ LWM2M_MUTEX_UNLOCK();
+
+ return NRF_SUCCESS;
+ }
+ }
+
+ LWM2M_MUTEX_UNLOCK();
+
+ return NRF_ERROR_NOT_FOUND;
+}
+
+
+uint32_t lwm2m_coap_handler_gen_link_format(uint8_t * p_buffer, uint16_t * p_buffer_len)
+{
+
+ LWM2M_ENTRY();
+
+ NULL_PARAM_CHECK(p_buffer_len);
+
+ LWM2M_MUTEX_LOCK();
+
+ uint16_t buffer_index = 0;
+ uint8_t * p_string_buffer;
+ uint16_t buffer_max_size;
+
+ uint8_t dry_run_buffer[16];
+ bool dry_run = false;
+ uint16_t dry_run_size = 0;
+
+ if (p_buffer == NULL)
+ {
+ // Dry-run only, in order to calculate the size of the needed buffer.
+ dry_run = true;
+ p_string_buffer = dry_run_buffer;
+ buffer_max_size = sizeof(dry_run_buffer);
+ }
+ else
+ {
+ p_string_buffer = p_buffer;
+ buffer_max_size = *p_buffer_len;
+ }
+
+ for (int i = 0; i < m_num_objects; ++i)
+ {
+ // We need more than 3 chars to write a new link
+ if (buffer_max_size - buffer_index <= 3)
+ {
+ LWM2M_MUTEX_UNLOCK();
+
+ return NRF_ERROR_NO_MEM;
+ }
+
+ uint16_t curr_object = m_objects[i]->object_id;
+
+ if (curr_object == LWM2M_NAMED_OBJECT)
+ {
+ // Skip this object as it is a named object.
+ continue;
+ }
+
+ bool instance_present = false;
+ for (int j = 0; j < m_num_instances; ++j)
+ {
+ if (m_instances[j]->object_id == curr_object)
+ {
+ instance_present = true;
+
+ buffer_index += snprintf((char *)&p_string_buffer[buffer_index],
+ buffer_max_size - buffer_index,
+ "</%u/%u>,",
+ m_instances[j]->object_id,
+ m_instances[j]->instance_id);
+ if (dry_run == true)
+ {
+ dry_run_size += buffer_index;
+ buffer_index = 0;
+ }
+ }
+ }
+
+ if (!instance_present)
+ {
+ buffer_index += snprintf((char *)&p_string_buffer[buffer_index],
+ buffer_max_size - buffer_index,
+ "</%u>,",
+ curr_object);
+ if (dry_run == true)
+ {
+ dry_run_size += buffer_index;
+ buffer_index = 0;
+ }
+ }
+ }
+
+ if (dry_run == true)
+ {
+ *p_buffer_len = dry_run_size - 1;
+ }
+ else
+ {
+ *p_buffer_len = buffer_index - 1; // Remove the last comma
+ }
+
+ LWM2M_MUTEX_UNLOCK();
+
+ return NRF_SUCCESS;
+}
+
+
+uint32_t lwm2m_init(void)
+{
+ SDK_MUTEX_INIT(m_lwm2m_mutex);
+
+ LWM2M_MUTEX_LOCK();
+
+ uint32_t err_code;
+
+ err_code = internal_lwm2m_register_init();
+ if (err_code != NRF_SUCCESS)
+ {
+ LWM2M_MUTEX_UNLOCK();
+ return err_code;
+ }
+
+ err_code = internal_lwm2m_bootstrap_init();
+ if (err_code != NRF_SUCCESS)
+ {
+ LWM2M_MUTEX_UNLOCK();
+ return err_code;
+ }
+
+ err_code = coap_error_handler_register(coap_error_handler);
+ if (err_code != NRF_SUCCESS)
+ {
+ LWM2M_MUTEX_UNLOCK();
+ return err_code;
+ }
+
+ internal_coap_handler_init();
+
+ err_code = coap_request_handler_register(lwm2m_coap_handler_handle_request);
+
+ LWM2M_MUTEX_UNLOCK();
+
+ return err_code;
+}
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/lwm2m/lwm2m.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/lwm2m/lwm2m.h
new file mode 100644
index 0000000..fe03b4d
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/lwm2m/lwm2m.h
@@ -0,0 +1,109 @@
+/**
+ * Copyright (c) 2015 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 lwm2m.h
+ *
+ * @defgroup iot_sdk_lwm2m_api LWM2M library private definitions.
+ * @ingroup iot_sdk_lwm2m
+ * @{
+ * @brief LWM2M library private definitions.
+ */
+
+#ifndef LWM2M_H__
+#define LWM2M_H__
+
+#include "stdint.h"
+#include "stdbool.h"
+#include "coap_message.h"
+#include "coap_codes.h"
+#include "sdk_config.h"
+#include "sdk_os.h"
+#include "iot_errors.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @defgroup iot_coap_mutex_lock_unlock Module's Mutex Lock/Unlock Macros.
+ *
+ * @details Macros used to lock and unlock modules. Currently, SDK does not use mutexes but
+ * framework is provided in case the need to use an alternative architecture arises.
+ * @{
+ */
+#define LWM2M_MUTEX_LOCK() SDK_MUTEX_LOCK(m_lwm2m_mutex) /**< Lock module using mutex */
+#define LWM2M_MUTEX_UNLOCK() SDK_MUTEX_UNLOCK(m_lwm2m_mutex) /**< Unlock module using mutex */
+
+/** @} */
+
+/**
+ * @defgroup api_param_check API Parameters check macros.
+ *
+ * @details Macros that verify parameters passed to the module in the APIs. These macros
+ * could be mapped to nothing in final versions of code to save execution and size.
+ * LWM2M_DISABLE_API_PARAM_CHECK should be set to 0 to enable these checks.
+ *
+ * @{
+ */
+#if (LWM2M_DISABLE_API_PARAM_CHECK == 0)
+
+/**@brief Verify NULL parameters are not passed to API by application. */
+#define NULL_PARAM_CHECK(PARAM) \
+ if ((PARAM) == NULL) \
+ { \
+ return (NRF_ERROR_NULL | IOT_LWM2M_ERR_BASE); \
+ }
+#else
+
+#define NULL_PARAM_CHECK(PARAM)
+
+#endif // LWM2M_DISABLE_API_PARAM_CHECK
+
+#define LWM2M_REQUEST_TYPE_BOOTSTRAP 1
+#define LWM2M_REQUEST_TYPE_REGISTER 2
+#define LWM2M_REQUEST_TYPE_UPDATE 3
+#define LWM2M_REQUEST_TYPE_DEREGISTER 4
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // LWM2M_H__
+
+/** @} */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/lwm2m/lwm2m_api.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/lwm2m/lwm2m_api.h
new file mode 100644
index 0000000..444c3e5
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/lwm2m/lwm2m_api.h
@@ -0,0 +1,426 @@
+/**
+ * Copyright (c) 2015 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 lwm2m_api.h
+*
+* @defgroup iot_sdk_lwm2m_api LWM2M Application Programming Interface
+* @ingroup iot_sdk_lwm2m
+* @{
+* @brief Public API of Nordic's LWM2M implementation.
+*/
+#ifndef LWM2M_API_H__
+#define LWM2M_API_H__
+
+#include <stdint.h>
+
+#include "lwm2m.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**@addtogroup LWM2M_opcodes Types
+ * @{
+ * @brief LWMW2M Bootstrap type definitions.
+ */
+
+/**@brief LWM2M remote structure type. */
+typedef coap_remote_t lwm2m_remote_t;
+
+/**@brief LWM2M time type. */
+typedef uint32_t lwm2m_time_t;
+
+/**@brief LWM2M string type. */
+typedef struct
+{
+ char * p_val; /**< Pointer to the value of the string data. */
+ uint32_t len; /**< Length of p_val. */
+} lwm2m_string_t;
+
+/**@brief LWM2M opaque type. */
+typedef struct
+{
+ uint8_t * p_val; /**< Pointer to the value of the opaque data. */
+ uint32_t len; /**< Length of p_val. */
+} lwm2m_opaque_t;
+
+/**@brief Application notification callback types. */
+typedef enum
+{
+ LWM2M_NOTIFCATION_TYPE_BOOTSTRAP, /**< Notification from a bootstrap request. */
+ LWM2M_NOTIFCATION_TYPE_REGISTER, /**< Notification from a register request. */
+ LWM2M_NOTIFCATION_TYPE_UPDATE, /**< Notification from a update request. */
+ LWM2M_NOTIFCATION_TYPE_DEREGISTER /**< Notification from a deregister request. */
+} lwm2m_notification_type_t;
+
+/**@brief LWM2M server configuration type. */
+typedef struct
+{
+ uint32_t lifetime; /** Lifetime parameter **/
+ uint64_t msisdn; /** SMS number MSISDN **/
+ uint8_t lwm2m_version_major; /** LWM2M major version number **/
+ uint8_t lwm2m_version_minor; /** LWM2M miner version number **/
+ lwm2m_string_t binding;
+} lwm2m_server_config_t;
+
+/**@brief LWM2M client identity types. */
+typedef enum
+{
+ LWM2M_CLIENT_ID_TYPE_UUID = 36,
+ LWM2M_CLIENT_ID_TYPE_IMEI = 15,
+ LWM2M_CLIENT_ID_TYPE_ESN = 8,
+ LWM2M_CLIENT_ID_TYPE_MEID = 14
+} lwm2m_client_identity_type_t;
+
+/**@brief LWM2M identity string.
+ *
+ * @details Using the string representation of UUID/OPS/OS/IMEI/ESN/MEID.
+ *
+ * @note: OPS- and OS URN are not currently supported.
+ */
+typedef union
+{
+ char uuid[36];
+ char imei[15];
+ char esn[8];
+ char meid[14];
+} lwm2m_identity_string_t;
+
+/**@brief LWM2M client identity structure type. */
+typedef struct
+{
+ lwm2m_identity_string_t value;
+ lwm2m_client_identity_type_t type;
+} lwm2m_client_identity_t;
+/**@} */
+
+/**@addtogroup LWM2M_defines Defines
+ * @{
+ * @brief LWMW2M operation code and invalid object/instance definitions.
+ */
+
+/**
+ * @warning The invalid resource and instance are not stated by the lwm2m spec as reserved and will
+ * cause issues if instances or resources with these IDs is added.
+ */
+#define LWM2M_NAMED_OBJECT 65535 /**< Flag to indicate that the object does not use Integer as object id. */
+#define LWM2M_INVALID_RESOURCE 65535 /**< Invalid Resource ID. */
+#define LWM2M_INVALID_INSTANCE 65535 /**< Invalid Instance ID. */
+
+#define LWM2M_OPERATION_CODE_NONE 0x00 /**< Bit mask for LWM2M no operation. */
+#define LWM2M_OPERATION_CODE_READ 0x01 /**< Bit mask for LWM2M read operation. */
+#define LWM2M_OPERATION_CODE_WRITE 0x02 /**< Bit mask for LWM2M write operation. */
+#define LWM2M_OPERATION_CODE_EXECUTE 0x04 /**< Bit mask for LWM2M execute operation. */
+#define LWM2M_OPERATION_CODE_DELETE 0x08 /**< Bit mask for LWM2M delete operation. */
+#define LWM2M_OPERATION_CODE_CREATE 0x10 /**< Bit mask for LWM2M create operation. */
+#define LWM2M_OPERATION_CODE_DISCOVER 0x20 /**< Bit mask for LWM2M discover operation. */
+#define LWM2M_OPERATION_CODE_OBSERVE 0x40 /**< Bit mask for LWM2M observe operation. */
+/**@} */
+
+/**@cond */
+// Forward declare structs.
+typedef struct lwm2m_object_prototype_t lwm2m_object_prototype_t;
+typedef struct lwm2m_instance_prototype_t lwm2m_instance_prototype_t;
+/**@endcond */
+
+/**@brief Callback function upon requests on a given LWM2M resource instance.
+ *
+ * @details Will be called when the request is for an instance Ex. /0/1.
+ *
+ * If no instance could be located the object callback will be called.
+ * The instance_id corresponds to the one in the URI-patch in the CoAP request and may be used to
+ * create a new instance. If the value of resource_id is set to LWM2M_INVALID_RESOURCE the callback
+ * should treated it as a call to the instance instead of a resource inside of the instance.
+ *
+ * If a resource has been found p_instance pointer will be set, else it will be NULL.
+ *
+ * @param[in] p_instance Pointer to the located resource if it already exists.
+ * @param[in] resource_id Id of the resource requested.
+ * @param[in] op_code Opcode of the request. Values of the opcodes are defined
+ * in \ref LWM2M_opcodes.
+ * @param[in] p_request Pointer to the CoAP request message.
+ *
+ * @retval NRF_SUCCESS Will always return success.
+ */
+typedef uint32_t (*lwm2m_instance_callback_t)(lwm2m_instance_prototype_t * p_instance,
+ uint16_t resource_id,
+ uint8_t op_code,
+ coap_message_t * p_request);
+
+/**@brief Callback function upon request on a given LWM2M object or instance create.
+ *
+ * @details Will be called when the request is for an object Ex: /0 or /0/1 an instance and the
+ * op_code is CREATE. Depending on the CoAP request code the user might create an instance
+ * or just return the tlv of current instances. If the value of instance_id is set to
+ * LWM2M_INVALID_INSTANCE the callback should treated it as a call to the instance instead
+ * of an instance of the object.
+ *
+ * @param[in] p_object Pointer to the located object.
+ * @param[in] instance_id Id of the instance requested.
+ * @param[in] op_code Opcode of the request. Values of the opcodes are defined
+ * in \ref LWM2M_opcodes.
+ * @param[in] p_request Pointer to the CoAP request message.
+ *
+ * @retval NRF_SUCCESS Will always return success.
+ */
+typedef uint32_t (*lwm2m_object_callback_t)(lwm2m_object_prototype_t * p_object,
+ uint16_t instance_id,
+ uint8_t op_code,
+ coap_message_t * p_request);
+
+/**@brief LWM2M object prototype structure.
+ *
+ * @details Each instance will have this structure in the front of its instance structure.
+ * The object is used to have a common way of looking up its object id and callback
+ * structure for each of the inherited. As there is no instance of the objects themselves,
+ * the prototype is used as a meta object in order to have a common set of functions
+ * for all instances of a object kind.
+ */
+struct lwm2m_object_prototype_t
+{
+ uint16_t object_id; /**< Identifies the object. */
+ lwm2m_object_callback_t callback; /**< Called when for request to /0 (object) and /0/1 if instance 1 is not found. */
+ char * p_alias_name; /**< Alternative name of the resource, used when LWM2M_NAMED_OBJECT is set. */
+};
+
+/**@brief LWM2M instance structure.
+ *
+ * @details Prototype for the instance object, this enables us to search through the instances
+ * without knowing the type.
+ */
+struct lwm2m_instance_prototype_t
+{
+ uint16_t object_id; /**< Identifies what object this instance belongs to. */
+ uint16_t instance_id; /**< Used to identify the instance. */
+ uint16_t num_resources; /**< Number of resources MUST equal number of members in the lwm2m instance, sizeof resource_access and sizeof resource_ids. */
+ uint8_t operations_offset; /**< Internal use. */
+ uint8_t resource_ids_offset; /**< Internal use. */
+ lwm2m_instance_callback_t callback; /**< Called when an operation is done on this instance. */
+};
+
+/**@brief Callback interface from the enabler interface (bootstrap/register) to the application.
+ *
+ * @warning This is an interface function. MUST BE IMPLEMENTED BY APPLICATION.
+ *
+ * @param[in] type Notification type. The types are defined in \ref lwm2m_notification_type_t.
+ * @param[in] p_remote remote that answered the request
+ * @param[in] coap_code coap op code from the response
+ *
+ * @retval NRF_SUCCESS If the client application handled the notification successfully.
+ */
+uint32_t lwm2m_notification(lwm2m_notification_type_t type,
+ lwm2m_remote_t * p_remote,
+ uint8_t coap_code);
+
+/**@brief CoAP Request handler for the root of the object/instance/resource hierarchy.
+ *
+ * @details The function is called when a request is for the lwm2m root (ie no object instance
+ * or resource).
+ *
+ * @warning This is an interface function. MUST BE IMPLEMENTED BY APPLICATION.
+ *
+ * @param[in] op_code LWM2M operation code.
+ * @param[in] p_request Pointer to CoAP request message.
+ *
+ * @retval NRF_SUCCESS If the handler processed the request successfully.
+ */
+uint32_t lwm2m_coap_handler_root(uint8_t op_code, coap_message_t * p_request);
+
+/**@brief Initialize LWM2M library.
+ *
+ * @retval NRF_SUCCESS If initialization was successful.
+ */
+uint32_t lwm2m_init(void);
+
+/**@brief Send bootstrap request to a remote bootstrap server.
+ *
+ * @details Sends a bootstrap request with specified ID to the specified remote, calls the
+ * lwm2m_notification with answer from the bootstrap server.
+ *
+ * @param[in] p_remote Pointer to the structure holding connection information of the remote
+ * LWM2M bootstrap server.
+ * @param[in] p_id Pointer to the structure holding the Id of the client.
+ * @param[in] local_port Port number of the local port to be used to send the bootstrap request.
+ *
+ * @retval NRF_SUCCESS If bootstrap request to the LWM2M bootstrap server was sent successfully.
+ * @retval NRF_ERROR_NULL If one of the parameters was a NULL pointer.
+ */
+uint32_t lwm2m_bootstrap(lwm2m_remote_t * p_remote,
+ lwm2m_client_identity_t * p_id,
+ uint16_t local_port);
+
+/**@brief Register with a remote LWM2M server.
+ *
+ * @param[in] p_remote Pointer to the structure holding connection information
+ * of the remote LWM2M server.
+ * @param[in] p_id Pointer to the structure holding the Id of the client.
+ * @param[in] p_config Registration parameters.
+ * @param[in] local_port Port number of the local port to be used to send the
+ * register request.
+ * @param[in] p_link_format_string Pointer to a link format encoded string to send in the
+ * register request.
+ * @param[in] link_format_len Length of the link format string provided.
+ *
+ * @retval NRF_SUCCESS If registration request to the LWM2M server was sent out successfully.
+ */
+uint32_t lwm2m_register(lwm2m_remote_t * p_remote,
+ lwm2m_client_identity_t * p_id ,
+ lwm2m_server_config_t * p_config,
+ uint16_t local_port,
+ uint8_t * p_link_format_string,
+ uint16_t link_format_len);
+
+/**@brief Update a registration with a remote server.
+ *
+ * @param[in] p_remote Pointer to the structure holding connection information of the remote
+ * LWM2M server.
+ * @param[in] p_config Registration parameters.
+ * @param[in] local_port Port number of the local port to be used to send the update request.
+ *
+ * @retval NRF_SUCCESS If update request to the LWM2M server was sent out successfully.
+ */
+uint32_t lwm2m_update(lwm2m_remote_t * p_remote,
+ lwm2m_server_config_t * p_config,
+ uint16_t local_port);
+
+/**@brief Deregister from a remote server.
+ *
+ * @param[in] p_remote Pointer to the structure holding connection information of the remote
+ * LWM2M server.
+ * @param[in] local_port Port number of the local port to be used to send the deregister request.
+ *
+ * @retval NRF_SUCCESS If deregister request to the LWM2M server was sent out successfully.
+ */
+uint32_t lwm2m_deregister(lwm2m_remote_t * p_remote, uint16_t local_port);
+
+/**@brief Add an instance to coap_handler in order to match requests to the given instance.
+ *
+ * @details Add a new LWM2M instance to the coap_handler. The application MUST initialize
+ * and allocate the additional data in the struct.
+ *
+ * @param[in] p_instance Pointer to the instance to add.
+ *
+ * @retval NRF_SUCCESS If registration was successful.
+ * @retval NRF_ERROR_NO_MEM If the module was not able to add the instance. Verify that
+ * the LWM2M_COAP_HANDLER_MAX_INSTANCES setting in sdk_config.h
+ * has a correct value.
+ */
+uint32_t lwm2m_coap_handler_instance_add(lwm2m_instance_prototype_t * p_instance);
+
+/**@brief Delete an instance from coap_handler in order to stop matching requests to the given
+ * instance.
+ *
+ * @param[in] p_instance Pointer to the instance to delete.
+ *
+ * @retval NRF_SUCCESS If unregistration was a success.
+ * @retval NRF_ERROR_NOT_FOUND If the given instance was not located.
+ */
+uint32_t lwm2m_coap_handler_instance_delete(lwm2m_instance_prototype_t * p_instance);
+
+/**@brief Add an object to coap_handler in order to match requests to the given object.
+ *
+ * @details Add a new LWM2M object to the coap_handler. The application MUST initialize
+ * and allocate the additional data in the struct.
+ *
+ * @param[in] p_object Pointer to the object to add.
+ *
+ * @retval NRF_SUCCESS If registration was successful.
+ * @retval NRF_ERROR_NO_MEM If the module was not able to add the object. Verify that
+ * the LWM2M_COAP_HANDLER_MAX_OBJECTS setting in sdk_config.h
+ * has a correct value.
+ */
+uint32_t lwm2m_coap_handler_object_add(lwm2m_object_prototype_t * p_object);
+
+/**@brief Delete an object from coap_handler in order to stop matching requests to the given
+ * object.
+ *
+ * @param[in] p_object Pointer to the object to delete.
+ *
+ * @retval NRF_SUCCESS If unregistration was a success.
+ * @retval NRF_ERROR_NOT_FOUND If the given object was not located.
+ */
+uint32_t lwm2m_coap_handler_object_delete(lwm2m_object_prototype_t * p_object);
+
+/**@brief Generate link format string based on registered objects and instances.
+ *
+ * @note For generation of links to work properly it is required that objects is added
+ * before instances.
+ *
+ * @param[inout] p_buffer Pointer to a buffer to fill with link format encoded string. If
+ * a NULL pointer is provided the function will dry-run the function
+ * in order to calculate how much memory that is needed for the link
+ * format string.
+ * @param[inout] p_buffer_len As input used to indicate the length of the buffer. It will return the
+ * used amount of buffer length by reference in response. If NULL pointer
+ * is provided for p_buffer, the value by reference output will be the number
+ * of bytes needed to generate the link format string.
+ *
+ * @retval NRF_SUCCESS If generation of link format string was successful.
+ * @retval NRF_ERROR_NO_MEM If the provided memory was not large enough.
+ */
+uint32_t lwm2m_coap_handler_gen_link_format(uint8_t * p_buffer, uint16_t * p_buffer_len);
+
+/**@brief Send CoAP 2.05 Content response with the payload provided.
+ *
+ * @param[in] p_payload Pointer to the payload to send. Must not be NULL.
+ * @param[in] payload_len Size of the payload.
+ * @param[in] p_request Original CoAP request. Must not be NULL.
+ *
+ * @retval NRF_SUCCESS If the response was sent out successfully.
+ */
+uint32_t lwm2m_respond_with_payload(uint8_t * p_payload,
+ uint16_t payload_len,
+ coap_message_t * p_request);
+
+/**@brief Send CoAP response with a given CoAP message code.
+ *
+ * @param [in] code CoAP response code to send.
+ * @param [in] p_request Original CoAP request. Must not be NULL.
+ *
+ * @retval NRF_SUCCESS If the response was sent out successfully.
+ */
+uint32_t lwm2m_respond_with_code(coap_msg_code_t code, coap_message_t * p_request);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // LWM2M_API_H__
+
+/** @} */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/lwm2m/lwm2m_bootstrap.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/lwm2m/lwm2m_bootstrap.c
new file mode 100644
index 0000000..7724e10
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/lwm2m/lwm2m_bootstrap.c
@@ -0,0 +1,203 @@
+/**
+ * Copyright (c) 2015 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#include <string.h>
+#include <stdio.h>
+#include <stdint.h>
+#include "lwm2m_api.h"
+#include "lwm2m_bootstrap.h"
+#include "lwm2m.h"
+#include "coap_api.h"
+#include "coap_message.h"
+#include "coap_codes.h"
+#include "sdk_config.h"
+#include "app_util.h"
+
+#if LWM2M_CONFIG_LOG_ENABLED
+
+#define NRF_LOG_MODULE_NAME lwm2m
+
+#define NRF_LOG_LEVEL LWM2M_CONFIG_LOG_LEVEL
+#define NRF_LOG_INFO_COLOR LWM2M_CONFIG_INFO_COLOR
+#define NRF_LOG_DEBUG_COLOR LWM2M_CONFIG_DEBUG_COLOR
+
+#include "nrf_log.h"
+
+#define LWM2M_TRC NRF_LOG_DEBUG /**< Used for getting trace of execution in the module. */
+#define LWM2M_ERR NRF_LOG_ERROR /**< Used for logging errors in the module. */
+#define LWM2M_DUMP NRF_LOG_HEXDUMP_DEBUG /**< Used for dumping octet information to get details of bond information etc. */
+
+#define LWM2M_ENTRY() LWM2M_TRC(">> %s", __func__)
+#define LWM2M_EXIT() LWM2M_TRC("<< %s", __func__)
+
+#else // LWM2M_CONFIG_LOG_ENABLED
+
+#define LWM2M_TRC(...) /**< Disables traces. */
+#define LWM2M_DUMP(...) /**< Disables dumping of octet streams. */
+#define LWM2M_ERR(...) /**< Disables error logs. */
+
+#define LWM2M_ENTRY(...)
+#define LWM2M_EXIT(...)
+
+#endif // LWM2M_CONFIG_LOG_ENABLED
+
+#define LWM2M_BOOTSTRAP_URI_PATH "bs"
+
+#define TOKEN_START 0x012A
+
+static uint16_t m_token = TOKEN_START;
+
+static uint32_t internal_message_new(coap_message_t ** pp_msg,
+ coap_msg_code_t code,
+ coap_response_callback_t callback,
+ uint16_t local_port)
+{
+ uint32_t err_code;
+ coap_message_conf_t conf;
+ memset (&conf, 0, sizeof(coap_message_conf_t));
+
+ conf.type = COAP_TYPE_CON;
+ conf.code = code;
+ conf.response_callback = callback;
+ conf.port.port_number = local_port;
+
+ conf.token_len = uint16_encode(m_token, conf.token);
+
+ m_token++;
+
+ err_code = coap_message_new(pp_msg, &conf);
+
+ return err_code;
+}
+
+
+/**@brief Function to be used as callback function upon a bootstrap request. */
+static void lwm2m_bootstrap_cb(uint32_t status, void * p_arg, coap_message_t * p_message)
+{
+ LWM2M_TRC("[Bootstrap]: lwm2m_bootstrap_cb, status: %ul, coap code: %u",
+ status,
+ p_message->header.code);
+
+ (void)lwm2m_notification(LWM2M_NOTIFCATION_TYPE_BOOTSTRAP,
+ &p_message->remote,
+ p_message->header.code);
+}
+
+
+uint32_t internal_lwm2m_bootstrap_init(void)
+{
+ m_token = TOKEN_START;
+ return NRF_SUCCESS;
+}
+
+
+uint32_t lwm2m_bootstrap(lwm2m_remote_t * p_remote, lwm2m_client_identity_t * p_id, uint16_t local_port)
+{
+ LWM2M_ENTRY();
+
+ NULL_PARAM_CHECK(p_remote);
+ NULL_PARAM_CHECK(p_id);
+
+ LWM2M_MUTEX_LOCK();
+
+ uint32_t err_code;
+ coap_message_t * p_msg;
+
+ lwm2m_string_t endpoint;
+
+ endpoint.p_val = LWM2M_BOOTSTRAP_URI_PATH;
+ endpoint.len = 2;
+
+ err_code = internal_message_new(&p_msg, COAP_CODE_POST, lwm2m_bootstrap_cb, local_port);
+ if (err_code != NRF_SUCCESS)
+ {
+ LWM2M_MUTEX_UNLOCK();
+ return err_code;
+ }
+
+ if (err_code == NRF_SUCCESS)
+ {
+ err_code = coap_message_remote_addr_set(p_msg, p_remote);
+ }
+
+ if (err_code == NRF_SUCCESS)
+ {
+ err_code = coap_message_opt_str_add(p_msg,
+ COAP_OPT_URI_PATH,
+ (uint8_t *)endpoint.p_val,
+ endpoint.len); // end_point length is always 2
+ }
+
+ if (err_code == NRF_SUCCESS)
+ {
+ char buffer[40];
+ buffer[0] = 'e';
+ buffer[1] = 'p';
+ buffer[2] = '=';
+ memcpy(buffer + 3, &p_id->value, p_id->type);
+
+ err_code = coap_message_opt_str_add(p_msg,
+ COAP_OPT_URI_QUERY,
+ (uint8_t *)buffer,
+ p_id->type + 3);
+ }
+
+ if (err_code == NRF_SUCCESS)
+ {
+ uint32_t msg_handle;
+ err_code = coap_message_send(&msg_handle, p_msg);
+ }
+
+ if (err_code == NRF_SUCCESS)
+ {
+ err_code = coap_message_delete(p_msg);
+ }
+ else
+ {
+ // If we have hit an error try to clean up.
+ // Return the original error code.
+ (void)coap_message_delete(p_msg);
+ }
+
+ LWM2M_EXIT();
+
+ LWM2M_MUTEX_UNLOCK();
+
+ return err_code;
+}
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/lwm2m/lwm2m_bootstrap.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/lwm2m/lwm2m_bootstrap.h
new file mode 100644
index 0000000..68bdf6b
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/lwm2m/lwm2m_bootstrap.h
@@ -0,0 +1,69 @@
+/**
+ * Copyright (c) 2015 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 lwm2m_bootstrap.h
+ *
+ * @defgroup iot_sdk_lwm2m_bootstrap_api LWM2M bootstrap API interface
+ * @ingroup iot_sdk_lwm2m
+ * @{
+ * @brief Bootstrap API interface for the LWM2M protocol.
+ */
+
+#ifndef LWM2M_BOOTSTRAP_H__
+#define LWM2M_BOOTSTRAP_H__
+
+#include <stdint.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**@brief Initialize the LWM2M register module.
+ *
+ * @details Calling this function will set the module in default state.
+ */
+uint32_t internal_lwm2m_bootstrap_init(void);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // LWM2M_BOOTSTRAP_H__
+
+/**@} */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/lwm2m/lwm2m_coap_util.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/lwm2m/lwm2m_coap_util.c
new file mode 100644
index 0000000..bf7bece
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/lwm2m/lwm2m_coap_util.c
@@ -0,0 +1,166 @@
+/**
+ * Copyright (c) 2015 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#include <string.h>
+#include "coap_api.h"
+#include "coap_message.h"
+#include "coap_codes.h"
+#include "lwm2m.h"
+
+
+uint32_t lwm2m_respond_with_code(coap_msg_code_t code, coap_message_t * p_request)
+{
+ NULL_PARAM_CHECK(p_request);
+
+ // Application helper function, no need for mutex.
+ coap_message_conf_t response_config;
+ memset (&response_config, 0, sizeof(coap_message_conf_t));
+
+ if (p_request->header.type == COAP_TYPE_NON)
+ {
+ response_config.type = COAP_TYPE_NON;
+ }
+ else if (p_request->header.type == COAP_TYPE_CON)
+ {
+ response_config.type = COAP_TYPE_ACK;
+ }
+
+ // PIGGY BACKED RESPONSE
+ response_config.code = code;
+ response_config.id = p_request->header.id;
+ response_config.port.port_number = p_request->port.port_number;
+
+ // Copy token.
+ memcpy(&response_config.token[0], &p_request->token[0], p_request->header.token_len);
+ // Copy token length.
+ response_config.token_len = p_request->header.token_len;
+
+ coap_message_t * p_response;
+ uint32_t err_code = coap_message_new(&p_response, &response_config);
+ if (err_code != NRF_SUCCESS)
+ {
+ return err_code;
+ }
+
+ err_code = coap_message_remote_addr_set(p_response, &p_request->remote);
+ if (err_code != NRF_SUCCESS)
+ {
+ (void)coap_message_delete(p_response);
+ return err_code;
+ }
+
+ memcpy(&p_response->remote, &p_request->remote, sizeof(coap_remote_t));
+
+ uint32_t msg_handle;
+ err_code = coap_message_send(&msg_handle, p_response);
+ if (err_code != NRF_SUCCESS)
+ {
+ (void)coap_message_delete(p_response);
+ return err_code;
+ }
+
+ err_code = coap_message_delete(p_response);
+
+ return err_code;
+}
+
+
+uint32_t lwm2m_respond_with_payload(uint8_t * p_payload, uint16_t payload_len, coap_message_t * p_request)
+{
+ NULL_PARAM_CHECK(p_request);
+ NULL_PARAM_CHECK(p_payload);
+
+ // Application helper function, no need for mutex.
+ coap_message_conf_t response_config;
+ memset (&response_config, 0, sizeof(coap_message_conf_t));
+
+ if (p_request->header.type == COAP_TYPE_NON)
+ {
+ response_config.type = COAP_TYPE_NON;
+ }
+ else if (p_request->header.type == COAP_TYPE_CON)
+ {
+ response_config.type = COAP_TYPE_ACK;
+ }
+
+ // PIGGY BACKED RESPONSE
+ response_config.code = COAP_CODE_205_CONTENT;
+ response_config.id = p_request->header.id;
+ response_config.port.port_number = p_request->port.port_number;
+
+ // Copy token.
+ memcpy(&response_config.token[0], &p_request->token[0], p_request->header.token_len);
+ // Copy token length.
+ response_config.token_len = p_request->header.token_len;
+
+ coap_message_t * p_response;
+ uint32_t err_code = coap_message_new(&p_response, &response_config);
+ if (err_code != NRF_SUCCESS)
+ {
+ return err_code;
+ }
+
+ err_code = coap_message_payload_set(p_response, p_payload, payload_len);
+ if (err_code != NRF_SUCCESS)
+ {
+ (void)coap_message_delete(p_response);
+ return err_code;
+ }
+
+ err_code = coap_message_remote_addr_set(p_response, &p_request->remote);
+ if (err_code != NRF_SUCCESS)
+ {
+ (void)coap_message_delete(p_response);
+ return err_code;
+ }
+
+ memcpy(&p_response->remote, &p_request->remote, sizeof(coap_remote_t));
+
+ uint32_t msg_handle;
+ err_code = coap_message_send(&msg_handle, p_response);
+ if (err_code != NRF_SUCCESS)
+ {
+ (void)coap_message_delete(p_response);
+ return err_code;
+ }
+
+ err_code = coap_message_delete(p_response);
+
+ return err_code;
+}
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/lwm2m/lwm2m_objects.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/lwm2m/lwm2m_objects.c
new file mode 100644
index 0000000..e61a40e
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/lwm2m/lwm2m_objects.c
@@ -0,0 +1,347 @@
+/**
+ * Copyright (c) 2015 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#include <string.h>
+#include <stddef.h>
+
+#include "lwm2m_objects.h"
+#include "lwm2m.h"
+
+//lint -e516 -save // Symbol '__INTADDR__()' has arg. type conflict
+#define LWM2M_INSTANCE_OFFSET_SET(instance, type) \
+ instance->proto.operations_offset = offsetof(type, operations); \
+ instance->proto.resource_ids_offset = offsetof(type, resource_ids);
+//lint -restore
+
+
+void lwm2m_instance_security_init(lwm2m_security_t * p_instance)
+{
+ // Set prototype variables.
+ LWM2M_INSTANCE_OFFSET_SET(p_instance, lwm2m_security_t);
+
+ p_instance->proto.object_id = LWM2M_OBJ_SECURITY;
+ p_instance->proto.instance_id = 0;
+ p_instance->proto.num_resources = sizeof(((lwm2m_security_t *)0)->operations);
+
+ // Set access types.
+ p_instance->operations[0] = LWM2M_OPERATION_CODE_NONE;
+ p_instance->operations[1] = LWM2M_OPERATION_CODE_NONE;
+ p_instance->operations[2] = LWM2M_OPERATION_CODE_NONE;
+ p_instance->operations[3] = LWM2M_OPERATION_CODE_NONE;
+ p_instance->operations[4] = LWM2M_OPERATION_CODE_NONE;
+ p_instance->operations[5] = LWM2M_OPERATION_CODE_NONE;
+ p_instance->operations[6] = LWM2M_OPERATION_CODE_NONE;
+ p_instance->operations[7] = LWM2M_OPERATION_CODE_NONE;
+ p_instance->operations[8] = LWM2M_OPERATION_CODE_NONE;
+ p_instance->operations[9] = LWM2M_OPERATION_CODE_NONE;
+ p_instance->operations[10] = LWM2M_OPERATION_CODE_NONE;
+ p_instance->operations[11] = LWM2M_OPERATION_CODE_NONE;
+
+ // Set resource IDs.
+ p_instance->resource_ids[0] = LWM2M_SECURITY_SERVER_URI;
+ p_instance->resource_ids[1] = LWM2M_SECURITY_BOOTSTRAP_SERVER;
+ p_instance->resource_ids[2] = LWM2M_SECURITY_SECURITY_MODE;
+ p_instance->resource_ids[3] = LWM2M_SECURITY_PUBLIC_KEY;
+ p_instance->resource_ids[4] = LWM2M_SECURITY_SERVER_PUBLIC_KEY;
+ p_instance->resource_ids[5] = LWM2M_SECURITY_SECRET_KEY;
+ p_instance->resource_ids[6] = LWM2M_SECURITY_SMS_SECURITY_MODE;
+ p_instance->resource_ids[7] = LWM2M_SECURITY_SMS_BINDING_KEY_PARAM;
+ p_instance->resource_ids[8] = LWM2M_SECURITY_SMS_BINDING_SECRET_KEY;
+ p_instance->resource_ids[9] = LWM2M_SECURITY_SERVER_SMS_NUMBER;
+ p_instance->resource_ids[10] = LWM2M_SECURITY_SHORT_SERVER_ID;
+ p_instance->resource_ids[11] = LWM2M_SECURITY_CLIENT_HOLD_OFF_TIME;
+}
+
+
+void lwm2m_instance_server_init(lwm2m_server_t * p_instance)
+{
+ // Set prototype variables.
+ LWM2M_INSTANCE_OFFSET_SET(p_instance, lwm2m_server_t);
+
+ p_instance->proto.object_id = LWM2M_OBJ_SERVER;
+ p_instance->proto.instance_id = 0;
+ p_instance->proto.num_resources = sizeof(((lwm2m_server_t *)0)->operations);
+
+ // Set access types.
+ p_instance->operations[0] = LWM2M_OPERATION_CODE_READ;
+ p_instance->operations[1] = (LWM2M_OPERATION_CODE_READ | LWM2M_OPERATION_CODE_WRITE);
+ p_instance->operations[2] = (LWM2M_OPERATION_CODE_READ | LWM2M_OPERATION_CODE_WRITE);
+ p_instance->operations[3] = (LWM2M_OPERATION_CODE_READ | LWM2M_OPERATION_CODE_WRITE);
+ p_instance->operations[4] = LWM2M_OPERATION_CODE_EXECUTE;
+ p_instance->operations[5] = (LWM2M_OPERATION_CODE_READ | LWM2M_OPERATION_CODE_WRITE);
+ p_instance->operations[6] = (LWM2M_OPERATION_CODE_READ | LWM2M_OPERATION_CODE_WRITE);
+ p_instance->operations[7] = (LWM2M_OPERATION_CODE_READ | LWM2M_OPERATION_CODE_WRITE);
+ p_instance->operations[8] = LWM2M_OPERATION_CODE_EXECUTE;
+
+ // Set resource IDs.
+ p_instance->resource_ids[0] = LWM2M_SERVER_SHORT_SERVER_ID;
+ p_instance->resource_ids[1] = LWM2M_SERVER_LIFETIME;
+ p_instance->resource_ids[2] = LWM2M_SERVER_DEFAULT_MIN_PERIOD;
+ p_instance->resource_ids[3] = LWM2M_SERVER_DEFAULT_MAX_PERIOD;
+ p_instance->resource_ids[4] = LWM2M_SERVER_DISABLE;
+ p_instance->resource_ids[5] = LWM2M_SERVER_DISABLE_TIMEOUT;
+ p_instance->resource_ids[6] = LWM2M_SERVER_NOTIFY_WHEN_DISABLED;
+ p_instance->resource_ids[7] = LWM2M_SERVER_BINDING;
+ p_instance->resource_ids[8] = LWM2M_SERVER_REGISTRATION_UPDATE_TRIGGER;
+}
+
+
+void lwm2m_instance_firmware_init(lwm2m_firmware_t * p_instance)
+{
+ // Set prototype variables.
+ LWM2M_INSTANCE_OFFSET_SET(p_instance, lwm2m_firmware_t);
+
+ p_instance->proto.object_id = LWM2M_OBJ_FIRMWARE;
+ p_instance->proto.instance_id = 0;
+ p_instance->proto.num_resources = sizeof(((lwm2m_firmware_t *)0)->operations);
+
+ // Set access types.
+ p_instance->operations[0] = LWM2M_OPERATION_CODE_WRITE;
+ p_instance->operations[1] = LWM2M_OPERATION_CODE_WRITE;
+ p_instance->operations[2] = LWM2M_OPERATION_CODE_EXECUTE;
+ p_instance->operations[3] = LWM2M_OPERATION_CODE_READ;
+ p_instance->operations[4] = (LWM2M_OPERATION_CODE_READ | LWM2M_OPERATION_CODE_WRITE);
+ p_instance->operations[5] = LWM2M_OPERATION_CODE_READ;
+
+ // Set resource IDs.
+ p_instance->resource_ids[0] = LWM2M_FIRMWARE_PACKAGE;
+ p_instance->resource_ids[1] = LWM2M_FIRMWARE_PACKAGE_URI;
+ p_instance->resource_ids[2] = LWM2M_FIRMWARE_UPDATE;
+ p_instance->resource_ids[3] = LWM2M_FIRMWARE_STATE;
+ p_instance->resource_ids[4] = LWM2M_FIRMWARE_UPDATE_SUPPORTED_OBJECTS;
+ p_instance->resource_ids[5] = LWM2M_FIRMWARE_UPDATE_RESULT;
+}
+
+
+void lwm2m_instance_acl_init(lwm2m_acl_t * p_instance)
+{
+ // Set prototype variables.
+ LWM2M_INSTANCE_OFFSET_SET(p_instance, lwm2m_acl_t);
+
+ p_instance->proto.object_id = LWM2M_OBJ_ACL;
+ p_instance->proto.instance_id = 0;
+ p_instance->proto.num_resources = sizeof(((lwm2m_acl_t *)0)->operations);
+
+ // Set access types.
+ p_instance->operations[0] = LWM2M_OPERATION_CODE_READ;
+ p_instance->operations[1] = LWM2M_OPERATION_CODE_READ;
+ p_instance->operations[2] = (LWM2M_OPERATION_CODE_READ | LWM2M_OPERATION_CODE_WRITE);
+ p_instance->operations[3] = (LWM2M_OPERATION_CODE_READ | LWM2M_OPERATION_CODE_WRITE);
+
+ // Set resource IDs.
+ p_instance->resource_ids[0] = LWM2M_ACL_OBJECT_ID;
+ p_instance->resource_ids[1] = LWM2M_ACL_INSTANCE_ID;
+ p_instance->resource_ids[2] = LWM2M_ACL_ACL;
+ p_instance->resource_ids[3] = LWM2M_ACL_CONTROL_OWNER;
+}
+
+
+void lwm2m_instance_connectivity_monitoring_init(lwm2m_connectivity_monitoring_t * p_instance)
+{
+ // Set prototype variables.
+ LWM2M_INSTANCE_OFFSET_SET(p_instance, lwm2m_connectivity_monitoring_t);
+
+ p_instance->proto.object_id = LWM2M_OBJ_CONN_MON;
+ p_instance->proto.instance_id = 0;
+ p_instance->proto.num_resources = sizeof(((lwm2m_connectivity_monitoring_t *)0)->operations);
+
+ // Set access types.
+ p_instance->operations[0] = LWM2M_OPERATION_CODE_READ;
+ p_instance->operations[1] = LWM2M_OPERATION_CODE_READ;
+ p_instance->operations[2] = LWM2M_OPERATION_CODE_READ;
+ p_instance->operations[3] = LWM2M_OPERATION_CODE_READ;
+ p_instance->operations[4] = LWM2M_OPERATION_CODE_READ;
+ p_instance->operations[5] = LWM2M_OPERATION_CODE_READ;
+ p_instance->operations[6] = LWM2M_OPERATION_CODE_READ;
+ p_instance->operations[7] = LWM2M_OPERATION_CODE_READ;
+ p_instance->operations[8] = LWM2M_OPERATION_CODE_READ;
+ p_instance->operations[9] = LWM2M_OPERATION_CODE_READ;
+ p_instance->operations[10] = LWM2M_OPERATION_CODE_READ;
+
+ // Set resource IDs.
+ p_instance->resource_ids[0] = LWM2M_CONN_MON_NETWORK_BEARER;
+ p_instance->resource_ids[1] = LWM2M_CONN_MON_AVAILABLE_NETWORK_BEARER;
+ p_instance->resource_ids[2] = LWM2M_CONN_MON_RADIO_SIGNAL_STRENGHT;
+ p_instance->resource_ids[3] = LWM2M_CONN_MON_LINK_QUALITY;
+ p_instance->resource_ids[4] = LWM2M_CONN_MON_IP_ADDRESSES;
+ p_instance->resource_ids[5] = LWM2M_CONN_MON_ROUTER_IP_ADRESSES;
+ p_instance->resource_ids[6] = LWM2M_CONN_MON_LINK_UTILIZATION;
+ p_instance->resource_ids[7] = LWM2M_CONN_MON_APN;
+ p_instance->resource_ids[8] = LWM2M_CONN_MON_CELL_ID;
+ p_instance->resource_ids[9] = LWM2M_CONN_MON_SMNC;
+ p_instance->resource_ids[10] = LWM2M_CONN_MON_SMCC;
+}
+
+
+void lwm2m_instance_connectivity_statistics_init(lwm2m_connectivity_statistics_t * p_instance)
+{
+ // Set prototype variables.
+ LWM2M_INSTANCE_OFFSET_SET(p_instance, lwm2m_connectivity_statistics_t);
+
+ p_instance->proto.object_id = LWM2M_OBJ_CONN_STAT;
+ p_instance->proto.instance_id = 0;
+ p_instance->proto.num_resources = sizeof(((lwm2m_connectivity_statistics_t *)0)->operations);
+
+ // Set access types.
+ p_instance->operations[0] = LWM2M_OPERATION_CODE_READ;
+ p_instance->operations[1] = LWM2M_OPERATION_CODE_READ;
+ p_instance->operations[2] = LWM2M_OPERATION_CODE_READ;
+ p_instance->operations[3] = LWM2M_OPERATION_CODE_READ;
+ p_instance->operations[4] = LWM2M_OPERATION_CODE_READ;
+ p_instance->operations[5] = LWM2M_OPERATION_CODE_READ;
+ p_instance->operations[6] = LWM2M_OPERATION_CODE_EXECUTE;
+
+ // Set resource IDs.
+ p_instance->resource_ids[0] = LWM2M_CONN_STAT_SMS_TX_COUNTER;
+ p_instance->resource_ids[1] = LWM2M_CONN_STAT_SMS_RX_COUNTER;
+ p_instance->resource_ids[2] = LWM2M_CONN_STAT_TX_DATA;
+ p_instance->resource_ids[3] = LWM2M_CONN_STAT_RX_DATA;
+ p_instance->resource_ids[4] = LWM2M_CONN_STAT_MAX_MSG_SIZE;
+ p_instance->resource_ids[5] = LWM2M_CONN_STAT_AVG_MSG_SIZE;
+ p_instance->resource_ids[6] = LWM2M_CONN_STAT_START_RESET;
+}
+
+
+void lwm2m_instance_device_init(lwm2m_device_t * p_instance)
+{
+ // Set prototype variables.
+ LWM2M_INSTANCE_OFFSET_SET(p_instance, lwm2m_device_t);
+
+ p_instance->proto.object_id = LWM2M_OBJ_DEVICE;
+ p_instance->proto.instance_id = 0;
+ p_instance->proto.num_resources = sizeof(((lwm2m_device_t *)0)->operations);
+
+ // Set access types.
+ p_instance->operations[0] = LWM2M_OPERATION_CODE_READ;
+ p_instance->operations[1] = LWM2M_OPERATION_CODE_READ;
+ p_instance->operations[2] = LWM2M_OPERATION_CODE_READ;
+ p_instance->operations[3] = LWM2M_OPERATION_CODE_READ;
+ p_instance->operations[4] = LWM2M_OPERATION_CODE_EXECUTE;
+ p_instance->operations[5] = LWM2M_OPERATION_CODE_EXECUTE;
+ p_instance->operations[6] = LWM2M_OPERATION_CODE_READ;
+ p_instance->operations[7] = LWM2M_OPERATION_CODE_READ;
+ p_instance->operations[8] = LWM2M_OPERATION_CODE_READ;
+ p_instance->operations[9] = LWM2M_OPERATION_CODE_READ;
+ p_instance->operations[10] = LWM2M_OPERATION_CODE_READ;
+ p_instance->operations[11] = LWM2M_OPERATION_CODE_READ;
+ p_instance->operations[12] = LWM2M_OPERATION_CODE_EXECUTE;
+ p_instance->operations[13] = (LWM2M_OPERATION_CODE_READ | LWM2M_OPERATION_CODE_WRITE);
+ p_instance->operations[14] = (LWM2M_OPERATION_CODE_READ | LWM2M_OPERATION_CODE_WRITE);
+ p_instance->operations[15] = (LWM2M_OPERATION_CODE_READ | LWM2M_OPERATION_CODE_WRITE);
+ p_instance->operations[16] = LWM2M_OPERATION_CODE_READ;
+
+ // Set resource IDs.
+ p_instance->resource_ids[0] = LWM2M_DEVICE_MANUFACTURER;
+ p_instance->resource_ids[1] = LWM2M_DEVICE_MODEL_NUMBER;
+ p_instance->resource_ids[2] = LWM2M_DEVICE_SERIAL_NUMBER;
+ p_instance->resource_ids[3] = LWM2M_DEVICE_FIRMWARE_VERSION;
+ p_instance->resource_ids[4] = LWM2M_DEVICE_REBOOT;
+ p_instance->resource_ids[5] = LWM2M_DEVICE_FACTORY_RESET;
+ p_instance->resource_ids[6] = LWM2M_DEVICE_AVAILABLE_POWER_SOURCES;
+ p_instance->resource_ids[7] = LWM2M_DEVICE_POWER_SOURCE_VOLTAGE;
+ p_instance->resource_ids[8] = LWM2M_DEVICE_POWER_SOURCE_CURRENT;
+ p_instance->resource_ids[9] = LWM2M_DEVICE_BATTERY_LEVEL;
+ p_instance->resource_ids[10] = LWM2M_DEVICE_MEMORY_FREE;
+ p_instance->resource_ids[11] = LWM2M_DEVICE_ERROR_CODE;
+ p_instance->resource_ids[12] = LWM2M_DEVICE_RESET_ERROR_CODE;
+ p_instance->resource_ids[13] = LWM2M_DEVICE_CURRENT_TIME;
+ p_instance->resource_ids[14] = LWM2M_DEVICE_UTC_OFFSET;
+ p_instance->resource_ids[15] = LWM2M_DEVICE_TIMEZONE;
+ p_instance->resource_ids[16] = LWM2M_DEVICE_SUPPORTED_BINDINGS;
+}
+
+
+void lwm2m_instance_location_init(lwm2m_location_t * p_instance)
+{
+ // Set prototype variables.
+ LWM2M_INSTANCE_OFFSET_SET(p_instance, lwm2m_location_t);
+
+ p_instance->proto.object_id = LWM2M_OBJ_LOCATION;
+ p_instance->proto.instance_id = 0;
+ p_instance->proto.num_resources = sizeof(((lwm2m_location_t *)0)->operations);
+
+ // Set access types.
+ p_instance->operations[0] = LWM2M_OPERATION_CODE_READ;
+ p_instance->operations[1] = LWM2M_OPERATION_CODE_READ;
+ p_instance->operations[2] = LWM2M_OPERATION_CODE_READ;
+ p_instance->operations[3] = LWM2M_OPERATION_CODE_READ;
+ p_instance->operations[4] = LWM2M_OPERATION_CODE_READ;
+ p_instance->operations[5] = LWM2M_OPERATION_CODE_READ;
+
+ // Set resource IDs.
+ p_instance->resource_ids[0] = LWM2M_LOCATION_ALTITUDE;
+ p_instance->resource_ids[1] = LWM2M_LOCATION_LONGITUDE;
+ p_instance->resource_ids[2] = LWM2M_LOCATION_ALTITUDE;
+ p_instance->resource_ids[3] = LWM2M_LOCATION_UNCERTAINTY;
+ p_instance->resource_ids[4] = LWM2M_LOCATION_VELOCITY;
+ p_instance->resource_ids[5] = LWM2M_LOCATION_TIMESTAMP;
+}
+
+
+void lwm2m_instance_software_update_init(lwm2m_software_update_t * p_instance)
+{
+ // Set prototype variables.
+ LWM2M_INSTANCE_OFFSET_SET(p_instance, lwm2m_software_update_t);
+
+ p_instance->proto.object_id = LWM2M_OBJ_SOFTWARE_UPDATE;
+ p_instance->proto.instance_id = 0;
+ p_instance->proto.num_resources = sizeof(((lwm2m_software_update_t *)0)->operations);
+
+ // Set access types.
+ p_instance->operations[0] = LWM2M_OPERATION_CODE_READ;
+ p_instance->operations[1] = LWM2M_OPERATION_CODE_READ;
+ p_instance->operations[2] = LWM2M_OPERATION_CODE_WRITE;
+ p_instance->operations[3] = LWM2M_OPERATION_CODE_WRITE;
+ p_instance->operations[4] = LWM2M_OPERATION_CODE_EXECUTE;
+ p_instance->operations[5] = LWM2M_OPERATION_CODE_READ;
+ p_instance->operations[6] = LWM2M_OPERATION_CODE_EXECUTE;
+ p_instance->operations[7] = LWM2M_OPERATION_CODE_READ;
+ p_instance->operations[8] = (LWM2M_OPERATION_CODE_READ | LWM2M_OPERATION_CODE_WRITE);
+
+ // Set resource IDs.
+ p_instance->resource_ids[0] = LWM2M_SW_UPDATE_PKG_NAME;
+ p_instance->resource_ids[1] = LWM2M_SW_UPDATE_PKG_VERSION;
+ p_instance->resource_ids[2] = LWM2M_SW_UPDATE_PACKAGE;
+ p_instance->resource_ids[3] = LWM2M_SW_UPDATE_PACKAGE_URI;
+ p_instance->resource_ids[4] = LWM2M_SW_UPDATE_INSTALL;
+ p_instance->resource_ids[5] = LWM2M_SW_UPDATE_CHECKPOINT;
+ p_instance->resource_ids[6] = LWM2M_SW_UPDATE_UNINSTALL;
+ p_instance->resource_ids[7] = LWM2M_SW_UPDATE_UPDATE_STATE;
+ p_instance->resource_ids[8] = LWM2M_SW_UPDATE_SUPPORTED_OBJECTS;
+}
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/lwm2m/lwm2m_objects.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/lwm2m/lwm2m_objects.h
new file mode 100644
index 0000000..c18917e
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/lwm2m/lwm2m_objects.h
@@ -0,0 +1,443 @@
+/**
+ * Copyright (c) 2015 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 lwm2m_objects.h
+ *
+ * @defgroup iot_sdk_lwm2m_objects OMA LWM2M objects definitions and types
+ * @ingroup iot_sdk_lwm2m
+ * @{
+ * @brief OMA LWM2M objects definitions and types.
+ *
+ * @note The definitions used in this module are from the OMA LWM2M
+ * "Lightweight Machine to Machine Technical Specification - OMA_TS-LightweightM2M-V1_0-20131210-C".
+ * The specification could be found at http://openmobilealliance.org/.
+ */
+
+#ifndef LWM2M_OBJECTS_H__
+#define LWM2M_OBJECTS_H__
+
+#include <stdint.h>
+#include <stdbool.h>
+#include "lwm2m_api.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* @brief LWM2M Enabler Object IDs Appendix E */
+#define LWM2M_OBJ_SECURITY 0
+#define LWM2M_OBJ_SERVER 1
+#define LWM2M_OBJ_ACL 2
+#define LWM2M_OBJ_DEVICE 3
+#define LWM2M_OBJ_CONN_MON 4
+#define LWM2M_OBJ_FIRMWARE 5
+#define LWM2M_OBJ_LOCATION 6
+#define LWM2M_OBJ_CONN_STAT 7
+
+/* @brief LWM2M Registry Objects */
+#define LWM2M_OBJ_SOFTWARE_UPDATE 9
+
+/* LWM2M Security Resource IDs Appendix E.1 */
+#define LWM2M_SECURITY_SERVER_URI 0
+#define LWM2M_SECURITY_BOOTSTRAP_SERVER 1
+#define LWM2M_SECURITY_SECURITY_MODE 2
+#define LWM2M_SECURITY_PUBLIC_KEY 3
+#define LWM2M_SECURITY_SERVER_PUBLIC_KEY 4
+#define LWM2M_SECURITY_SECRET_KEY 5
+#define LWM2M_SECURITY_SMS_SECURITY_MODE 6
+#define LWM2M_SECURITY_SMS_BINDING_KEY_PARAM 7
+#define LWM2M_SECURITY_SMS_BINDING_SECRET_KEY 8
+#define LWM2M_SECURITY_SERVER_SMS_NUMBER 9
+#define LWM2M_SECURITY_SHORT_SERVER_ID 10
+#define LWM2M_SECURITY_CLIENT_HOLD_OFF_TIME 11
+
+
+/* LWM2M Server Resources Appendix E.2 */
+#define LWM2M_SERVER_SHORT_SERVER_ID 0
+#define LWM2M_SERVER_LIFETIME 1
+#define LWM2M_SERVER_DEFAULT_MIN_PERIOD 2
+#define LWM2M_SERVER_DEFAULT_MAX_PERIOD 3
+#define LWM2M_SERVER_DISABLE 4
+#define LWM2M_SERVER_DISABLE_TIMEOUT 5
+#define LWM2M_SERVER_NOTIFY_WHEN_DISABLED 6
+#define LWM2M_SERVER_BINDING 7
+#define LWM2M_SERVER_REGISTRATION_UPDATE_TRIGGER 8
+
+
+/* LWM2M Firmware update Resources Appendix E.6 */
+#define LWM2M_FIRMWARE_PACKAGE 0
+#define LWM2M_FIRMWARE_PACKAGE_URI 1
+#define LWM2M_FIRMWARE_UPDATE 2
+#define LWM2M_FIRMWARE_STATE 3
+#define LWM2M_FIRMWARE_UPDATE_SUPPORTED_OBJECTS 4
+#define LWM2M_FIRMWARE_UPDATE_RESULT 5
+
+#define LWM2M_FIRMWARE_STATE_IDLE 1
+#define LWM2M_FIRMWARE_STATE_DOWNLOADING 2
+#define LWM2M_FIRMWARE_STATE_DOWNLOADED 3
+
+#define LWM2M_FIRMWARE_UPDATE_RESULT_DEFAULT 0
+#define LWM2M_FIRMWARE_UPDATE_RESULT_SUCCESS 1
+#define LWM2M_FIRMWARE_UPDATE_RESULT_ERROR_STORAGE 2
+#define LWM2M_FIRMWARE_UPDATE_RESULT_ERROR_MEMORY 3
+#define LWM2M_FIRMWARE_UPDATE_RESULT_ERROR_CONN_LOST 4
+#define LWM2M_FIRMWARE_UPDATE_RESULT_ERROR_CRC 5
+#define LWM2M_FIRMWARE_UPDATE_RESULT_ERROR_UNSUPPORTED 6
+#define LWM2M_FIRMWARE_UPDATE_RESULT_ERROR_INVALID_URI 7
+
+
+/* LWM2M ACL Resources */
+#define LWM2M_ACL_OBJECT_ID 0
+#define LWM2M_ACL_INSTANCE_ID 1
+#define LWM2M_ACL_ACL 2
+#define LWM2M_ACL_CONTROL_OWNER 3
+
+/* LWM2M Connectivity Monitoring Resources */
+#define LWM2M_CONN_MON_NETWORK_BEARER 0
+#define LWM2M_CONN_MON_AVAILABLE_NETWORK_BEARER 1
+#define LWM2M_CONN_MON_RADIO_SIGNAL_STRENGHT 2
+#define LWM2M_CONN_MON_LINK_QUALITY 3
+#define LWM2M_CONN_MON_IP_ADDRESSES 4
+#define LWM2M_CONN_MON_ROUTER_IP_ADRESSES 5
+#define LWM2M_CONN_MON_LINK_UTILIZATION 6
+#define LWM2M_CONN_MON_APN 7
+#define LWM2M_CONN_MON_CELL_ID 8
+#define LWM2M_CONN_MON_SMNC 9
+#define LWM2M_CONN_MON_SMCC 10
+
+/* LWM2M Connectivity Statistics */
+#define LWM2M_CONN_STAT_SMS_TX_COUNTER 0
+#define LWM2M_CONN_STAT_SMS_RX_COUNTER 1
+#define LWM2M_CONN_STAT_TX_DATA 2
+#define LWM2M_CONN_STAT_RX_DATA 3
+#define LWM2M_CONN_STAT_MAX_MSG_SIZE 4
+#define LWM2M_CONN_STAT_AVG_MSG_SIZE 5
+#define LWM2M_CONN_STAT_START_RESET 6
+
+/* LWM2M Device */
+#define LWM2M_DEVICE_MANUFACTURER 0
+#define LWM2M_DEVICE_MODEL_NUMBER 1
+#define LWM2M_DEVICE_SERIAL_NUMBER 2
+#define LWM2M_DEVICE_FIRMWARE_VERSION 3
+#define LWM2M_DEVICE_REBOOT 4
+#define LWM2M_DEVICE_FACTORY_RESET 5
+#define LWM2M_DEVICE_AVAILABLE_POWER_SOURCES 6
+#define LWM2M_DEVICE_POWER_SOURCE_VOLTAGE 7
+#define LWM2M_DEVICE_POWER_SOURCE_CURRENT 8
+#define LWM2M_DEVICE_BATTERY_LEVEL 9
+#define LWM2M_DEVICE_MEMORY_FREE 10
+#define LWM2M_DEVICE_ERROR_CODE 11
+#define LWM2M_DEVICE_RESET_ERROR_CODE 12
+#define LWM2M_DEVICE_CURRENT_TIME 13
+#define LWM2M_DEVICE_UTC_OFFSET 14
+#define LWM2M_DEVICE_TIMEZONE 15
+#define LWM2M_DEVICE_SUPPORTED_BINDINGS 16
+
+/* LWM2M Location */
+#define LWM2M_LOCATION_LATITUDE 0
+#define LWM2M_LOCATION_LONGITUDE 1
+#define LWM2M_LOCATION_ALTITUDE 2
+#define LWM2M_LOCATION_UNCERTAINTY 3
+#define LWM2M_LOCATION_VELOCITY 4
+#define LWM2M_LOCATION_TIMESTAMP 5
+
+/* LWM2M Software update */
+#define LWM2M_SW_UPDATE_PKG_NAME 0
+#define LWM2M_SW_UPDATE_PKG_VERSION 1
+#define LWM2M_SW_UPDATE_PACKAGE 2
+#define LWM2M_SW_UPDATE_PACKAGE_URI 3
+#define LWM2M_SW_UPDATE_INSTALL 4
+#define LWM2M_SW_UPDATE_CHECKPOINT 5
+#define LWM2M_SW_UPDATE_UNINSTALL 6
+#define LWM2M_SW_UPDATE_UPDATE_STATE 7
+#define LWM2M_SW_UPDATE_SUPPORTED_OBJECTS 8
+
+/**
+ * LWM2M Enabler
+ */
+
+typedef struct
+{
+ lwm2m_instance_prototype_t proto; /* Internal. MUST be first. */
+ uint8_t operations[12]; /* Internal. MUST be second. */
+ uint16_t resource_ids[12]; /* Internal. MUST be third. */
+
+ /* Public members. */
+ lwm2m_string_t server_uri;
+ bool bootstrap_server;
+ uint8_t security_mode;
+ lwm2m_opaque_t public_key;
+ lwm2m_opaque_t server_public_key;
+ lwm2m_opaque_t secret_key;
+ uint8_t sms_security_mode;
+ lwm2m_opaque_t sms_binding_key_param;
+ lwm2m_opaque_t sms_binding_secret_keys;
+ uint32_t sms_number;
+ uint16_t short_server_id;
+ lwm2m_time_t client_hold_off_time;
+
+} lwm2m_security_t;
+
+typedef struct
+{
+ lwm2m_instance_prototype_t proto; /* Internal. MUST be first. */
+ uint8_t operations[9]; /* Internal. MUST be second. */
+ uint16_t resource_ids[9]; /* Internal. MUST be third. */
+
+ /* Public members. */
+ uint16_t short_server_id;
+ lwm2m_time_t lifetime;
+ lwm2m_time_t default_minimum_period;
+ lwm2m_time_t default_maximum_period;
+ void * disable; // Function pointer.
+ lwm2m_time_t disable_timeout;
+ bool notification_storing_on_disabled;
+ lwm2m_string_t binding;
+ void * registration_update_trigger; // Function pointer.
+
+} lwm2m_server_t;
+
+typedef struct
+{
+ lwm2m_instance_prototype_t proto; /* Internal. MUST be first. */
+ uint8_t operations[6]; /* Internal. MUST be second. */
+ uint16_t resource_ids[6]; /* Internal. MUST be third. */
+
+ /* Public members. */
+ lwm2m_opaque_t package;
+ lwm2m_string_t package_uri;
+ uint8_t state;
+ bool update_supported_objects;
+ uint8_t update_result;
+
+} lwm2m_firmware_t;
+
+typedef struct
+{
+ lwm2m_instance_prototype_t proto;
+ uint8_t operations[4];
+ uint16_t resource_ids[4];
+
+ /* Public members. */
+ uint16_t acl_object_id;
+ uint16_t acl_instance_id;
+ uint16_t acl;
+ uint16_t control_owner;
+
+} lwm2m_acl_t;
+
+typedef struct
+{
+ lwm2m_instance_prototype_t proto;
+ uint8_t operations[11];
+ uint16_t resource_ids[11];
+
+ /* Public members. */
+ uint32_t network_bearer;
+ uint32_t available_network_bearer;// TODO this is a list!
+ uint32_t radio_signal_strength; // Unit: dBm
+ uint32_t link_quality;
+ lwm2m_string_t ip_addresses; // TODO: this is a list!
+ lwm2m_string_t router_ip_addresses; // TODO: this is a list!
+ uint8_t link_utilization; // Unit: percent
+ lwm2m_string_t apn; // TODO: this is a list!
+ uint32_t cell_id;
+ uint8_t smnc; // Unit: percent
+ uint32_t smcc;
+
+} lwm2m_connectivity_monitoring_t;
+
+typedef struct
+{
+ lwm2m_instance_prototype_t proto;
+ uint8_t operations[7];
+ uint16_t resource_ids[7];
+
+ /* Public members. */
+ uint32_t sms_tx_counter;
+ uint32_t sms_rx_counter;
+ uint32_t tx_data; // Unit: kilo-bytes
+ uint32_t rx_data; // Unit: kilo-bytes
+ uint32_t max_message_size; // Unit: byte
+ uint32_t average_message_size; // Unit: byte
+ /* StartOrReset is Execute only */
+
+} lwm2m_connectivity_statistics_t;
+
+typedef struct
+{
+ lwm2m_instance_prototype_t proto;
+ uint8_t operations[17];
+ uint16_t resource_ids[17];
+
+ /* Public members. */
+ lwm2m_string_t manufacturer;
+ lwm2m_string_t model_number;
+ lwm2m_string_t serial_number;
+ lwm2m_string_t firmware_version;
+ /* Reboot is execute only */
+ /* Factory reset is execute only */
+ uint8_t avail_power_sources; // TODO: this is a list, Range: 0-7
+ uint32_t power_source_voltage; // TODO: this is a list, Unit: mV
+ uint32_t power_source_current; // TODO: this is a list, Unit: mA
+ uint8_t battery_level; // Unit: percent
+ uint32_t memory_free; // Unit: KB
+ uint32_t error_code; // TODO: this is a list
+ /* Reset Error code is execute only */
+ lwm2m_time_t current_time;
+ lwm2m_string_t utc_offset;
+ lwm2m_string_t timezone;
+ lwm2m_string_t supported_bindings; // TODO this is a list
+
+} lwm2m_device_t;
+
+typedef struct
+{
+ lwm2m_instance_prototype_t proto;
+ uint8_t operations[6];
+ uint16_t resource_ids[6];
+
+ /* Public members. */
+ lwm2m_string_t latitude; // Unit: Deg
+ lwm2m_string_t longitude; // Unit: Deg
+ lwm2m_string_t altitude; // Unit: m
+ lwm2m_string_t uncertainty; // Unit: m
+ lwm2m_opaque_t velocity; // Unit: Refers to 3GPP GAD specs
+ lwm2m_time_t timestamp; // Range: 0-6
+
+} lwm2m_location_t;
+
+typedef struct
+{
+ lwm2m_instance_prototype_t proto;
+ uint8_t operations[9];
+ uint16_t resource_ids[9];
+
+ /* Public members. */
+ lwm2m_string_t pkg_name;
+ lwm2m_string_t pkg_version;
+ lwm2m_opaque_t package;
+ lwm2m_string_t package_uri;
+ /* Install is execute only */
+ uint16_t checkpoint; // TODO: this is of type Objlnk
+ /* Uninstall is execute only */
+ uint8_t update_state; // Range: 1-5
+ bool update_supported_objects;
+
+} lwm2m_software_update_t;
+
+/**@brief Initialize a LWM2M security object instance.
+ *
+ * @details Must be called before any use of the instance.
+ *
+ * @param[in] p_instance Pointer to instance structure to initialize.
+ */
+void lwm2m_instance_security_init(lwm2m_security_t * p_instance);
+
+/**@brief Initialize a LWM2M server object instance.
+ *
+ * @details Must be called before any use of the instance.
+
+ * @param[in] p_instance Pointer to instance structure to initialize.
+ */
+void lwm2m_instance_server_init(lwm2m_server_t * p_instance);
+
+/**@brief Initialize a LWM2M firmware object instance.
+ *
+ * @details Must be called before any use of the instance.
+ *
+ * @param[in] p_instance Pointer to instance structure to initialize.
+ */
+void lwm2m_instance_firmware_init(lwm2m_firmware_t * p_instance);
+
+/**@brief Initialize a LWM2M ACL object instance
+ *
+ * @details Must be called before any use of the instance.
+ *
+ * @param[in] p_instance Pointer to instance structure to initialize.
+ */
+void lwm2m_instance_acl_init(lwm2m_acl_t * p_instance);
+
+/**@brief Initialize a LWM2M connectivity monitoring object instance
+ *
+ * @details Must be called before any use of the instance.
+ *
+ * @param[in] p_instance Pointer to instance structure to initialize.
+ */
+void lwm2m_instance_connectivity_monitoring_init(lwm2m_connectivity_monitoring_t * p_instance);
+
+/**@brief Initialize a LWM2M connectivity statistics object instance
+ *
+ * @details Must be called before any use of the instance.
+ *
+ * @param[in] p_instance Pointer to instance structure to initialize.
+ */
+void lwm2m_instance_connectivity_statistics_init(lwm2m_connectivity_statistics_t * p_instance);
+
+/**@brief Initialize a LWM2M device object instance
+ *
+ * @details Must be called before any use of the instance.
+ *
+ * @param[in] p_instance Pointer to instance structure to initialize.
+ */
+void lwm2m_instance_device_init(lwm2m_device_t * p_instance);
+
+/**@brief Initialize a LWM2M location object instance
+ *
+ * @details Must be called before any use of the instance.
+ *
+ * @param[in] p_instance Pointer to instance structure to initialize.
+ */
+void lwm2m_instance_location_init(lwm2m_location_t * p_instance);
+
+/**@brief Initialize a LWM2M software update object instance
+ *
+ * @details Must be called before any use of the instance.
+ *
+ * @param[in] p_instance Pointer to instance structure to initialize.
+ */
+void lwm2m_instance_software_update_init(lwm2m_software_update_t * p_instance);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // LWM2M_OBJECTS_H__
+
+/** @} */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/lwm2m/lwm2m_objects_tlv.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/lwm2m/lwm2m_objects_tlv.c
new file mode 100644
index 0000000..93cb6c1
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/lwm2m/lwm2m_objects_tlv.c
@@ -0,0 +1,498 @@
+/**
+ * Copyright (c) 2015 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#include "lwm2m_objects_tlv.h"
+#include "lwm2m_tlv.h"
+
+static void index_buffer_len_update(uint32_t * index, uint32_t * buffer_len, uint32_t max_buffer)
+{
+ *index += *buffer_len;
+ *buffer_len = max_buffer - *index;
+}
+
+uint32_t lwm2m_tlv_server_decode(lwm2m_server_t * server, uint8_t * buffer, uint32_t buffer_len)
+{
+ uint32_t err_code;
+ lwm2m_tlv_t tlv;
+
+ uint32_t index = 0;
+
+ while (index < buffer_len)
+ {
+ err_code = lwm2m_tlv_decode(&tlv, &index, buffer, buffer_len);
+ if (err_code != NRF_SUCCESS)
+ {
+ return err_code;
+ }
+
+ switch (tlv.id)
+ {
+ case LWM2M_SERVER_SHORT_SERVER_ID:
+ {
+ if (lwm2m_tlv_bytebuffer_to_uint16(tlv.value, tlv.length, &server->short_server_id) != NRF_SUCCESS)
+ {
+ return NRF_ERROR_INVALID_DATA;
+ }
+
+ break;
+ }
+
+ case LWM2M_SERVER_LIFETIME:
+ {
+ if (lwm2m_tlv_bytebuffer_to_uint32(tlv.value, tlv.length, &server->lifetime))
+ {
+ return NRF_ERROR_INVALID_DATA;
+ }
+ break;
+ }
+
+ case LWM2M_SERVER_DEFAULT_MIN_PERIOD:
+ {
+ if (lwm2m_tlv_bytebuffer_to_uint32(tlv.value, tlv.length, &server->default_minimum_period))
+ {
+ return NRF_ERROR_INVALID_DATA;
+ }
+ break;
+ }
+
+ case LWM2M_SERVER_DEFAULT_MAX_PERIOD:
+ {
+ if (lwm2m_tlv_bytebuffer_to_uint32(tlv.value, tlv.length, &server->default_maximum_period))
+ {
+ return NRF_ERROR_INVALID_DATA;
+ }
+ break;
+ }
+
+ case LWM2M_SERVER_DISABLE:
+ {
+ // Execute do nothing
+ break;
+ }
+
+ case LWM2M_SERVER_DISABLE_TIMEOUT:
+ {
+ if (lwm2m_tlv_bytebuffer_to_uint32(tlv.value, tlv.length, &server->disable_timeout))
+ {
+ return NRF_ERROR_INVALID_DATA;
+ }
+ break;
+ }
+
+ case LWM2M_SERVER_NOTIFY_WHEN_DISABLED:
+ {
+ server->notification_storing_on_disabled = tlv.value[0];
+ break;
+ }
+ case LWM2M_SERVER_BINDING:
+ {
+ // If original buffer is gone this will also be gone
+ server->binding.len = tlv.length;
+ server->binding.p_val = (char *) tlv.value;
+ break;
+ }
+
+ case LWM2M_SERVER_REGISTRATION_UPDATE_TRIGGER:
+ {
+ // Execute do nothing
+ break;
+ }
+
+ default:
+ break;
+ }
+ }
+
+ return NRF_SUCCESS;
+}
+
+
+uint32_t lwm2m_tlv_security_decode(lwm2m_security_t * p_security,
+ uint8_t * p_buffer,
+ uint32_t buffer_len)
+{
+ uint32_t err_code;
+ lwm2m_tlv_t tlv;
+
+ uint32_t index = 0;
+
+ while (index < buffer_len)
+ {
+ err_code = lwm2m_tlv_decode(&tlv, &index, p_buffer, buffer_len);
+
+ if (err_code != NRF_SUCCESS)
+ {
+ return err_code;
+ }
+
+ switch (tlv.id)
+ {
+ case LWM2M_SECURITY_SERVER_URI:
+ {
+ p_security->server_uri.p_val = (char *)tlv.value;
+ p_security->server_uri.len = tlv.length;
+ break;
+ }
+
+ case LWM2M_SECURITY_BOOTSTRAP_SERVER:
+ {
+ p_security->bootstrap_server = tlv.value[0];
+ break;
+ }
+
+ case LWM2M_SECURITY_SECURITY_MODE:
+ {
+ p_security->security_mode = tlv.value[0];
+ break;
+ }
+
+ case LWM2M_SECURITY_PUBLIC_KEY:
+ {
+ p_security->public_key.p_val = tlv.value;
+ p_security->public_key.len = tlv.length;
+ break;
+ }
+
+ case LWM2M_SECURITY_SERVER_PUBLIC_KEY:
+ {
+ p_security->server_public_key.p_val = tlv.value;
+ p_security->server_public_key.len = tlv.length;
+ break;
+ }
+
+ case LWM2M_SECURITY_SECRET_KEY:
+ {
+ p_security->secret_key.p_val = tlv.value;
+ p_security->secret_key.len = tlv.length;
+ break;
+ }
+
+ case LWM2M_SECURITY_SMS_SECURITY_MODE:
+ {
+ p_security->sms_security_mode = tlv.value[0];
+ break;
+ }
+
+ case LWM2M_SECURITY_SMS_BINDING_KEY_PARAM:
+ {
+ p_security->sms_binding_key_param.p_val = tlv.value;
+ p_security->sms_binding_key_param.len = tlv.length;
+ break;
+ }
+
+ case LWM2M_SECURITY_SMS_BINDING_SECRET_KEY:
+ {
+ p_security->sms_binding_secret_keys.p_val = tlv.value;
+ p_security->sms_binding_secret_keys.len = tlv.length;
+ break;
+ }
+
+ case LWM2M_SECURITY_SERVER_SMS_NUMBER:
+ {
+ uint32_t result = lwm2m_tlv_bytebuffer_to_uint32(tlv.value,
+ tlv.length,
+ &p_security->sms_number);
+ if (result != NRF_SUCCESS)
+ {
+ return NRF_ERROR_INVALID_DATA;
+ }
+ break;
+ }
+
+ case LWM2M_SECURITY_SHORT_SERVER_ID:
+ {
+ uint32_t result = lwm2m_tlv_bytebuffer_to_uint16(tlv.value,
+ tlv.length,
+ &p_security->short_server_id);
+ if (result != NRF_SUCCESS)
+ {
+ return NRF_ERROR_INVALID_DATA;
+ }
+ break;
+ }
+
+ case LWM2M_SECURITY_CLIENT_HOLD_OFF_TIME:
+ {
+ uint32_t result = lwm2m_tlv_bytebuffer_to_uint32(tlv.value,
+ tlv.length,
+ &p_security->client_hold_off_time);
+ if (result != NRF_SUCCESS)
+ {
+ return NRF_ERROR_INVALID_DATA;
+ }
+ break;
+ }
+
+ default:
+ break;
+ }
+ }
+
+ return NRF_SUCCESS;
+}
+
+
+uint32_t lwm2m_tlv_server_encode(uint8_t * p_buffer,
+ uint32_t * p_buffer_len,
+ lwm2m_server_t * p_server)
+{
+ uint32_t err_code;
+ uint32_t max_buffer = *p_buffer_len;
+ uint32_t index = 0;
+
+ lwm2m_tlv_t tlv;
+ tlv.id_type = TLV_TYPE_RESOURCE_VAL; // Type is the same for all.
+
+ // Encode short server id.
+ lwm2m_tlv_uint16_set(&tlv, p_server->short_server_id, LWM2M_SERVER_SHORT_SERVER_ID);
+ err_code = lwm2m_tlv_encode(p_buffer + index, p_buffer_len, &tlv);
+
+ if (err_code != NRF_SUCCESS)
+ {
+ return err_code;
+ }
+
+ index_buffer_len_update(&index, p_buffer_len, max_buffer);
+
+ // Encode lifetime.
+ lwm2m_tlv_uint32_set(&tlv, p_server->lifetime, LWM2M_SERVER_LIFETIME);
+ err_code = lwm2m_tlv_encode(p_buffer + index, p_buffer_len, &tlv);
+
+ if (err_code != NRF_SUCCESS)
+ {
+ return err_code;
+ }
+
+ index_buffer_len_update(&index, p_buffer_len, max_buffer);
+
+ // Encode default minimum period.
+ lwm2m_tlv_uint32_set(&tlv, p_server->default_minimum_period, LWM2M_SERVER_DEFAULT_MIN_PERIOD);
+ err_code = lwm2m_tlv_encode(p_buffer + index, p_buffer_len, &tlv);
+
+ if (err_code != NRF_SUCCESS)
+ {
+ return err_code;
+ }
+
+ index_buffer_len_update(&index, p_buffer_len, max_buffer);
+
+ // Encode default maximum period.
+ lwm2m_tlv_uint32_set(&tlv, p_server->default_maximum_period, LWM2M_SERVER_DEFAULT_MAX_PERIOD);
+ err_code = lwm2m_tlv_encode(p_buffer + index, p_buffer_len, &tlv);
+
+ if (err_code != NRF_SUCCESS)
+ {
+ return err_code;
+ }
+
+ index_buffer_len_update(&index, p_buffer_len, max_buffer);
+
+ // Encode disable timeout.
+ lwm2m_tlv_uint32_set(&tlv, p_server->disable_timeout, LWM2M_SERVER_DISABLE_TIMEOUT);
+ err_code = lwm2m_tlv_encode(p_buffer + index, p_buffer_len, &tlv);
+
+ if (err_code != NRF_SUCCESS)
+ {
+ return err_code;
+ }
+
+ index_buffer_len_update(&index, p_buffer_len, max_buffer);
+
+ // Encode Notify when disabled.
+ lwm2m_tlv_bool_set(&tlv, p_server->notification_storing_on_disabled, LWM2M_SERVER_NOTIFY_WHEN_DISABLED);
+ err_code = lwm2m_tlv_encode(p_buffer + index, p_buffer_len, &tlv);
+
+ if (err_code != NRF_SUCCESS)
+ {
+ return err_code;
+ }
+
+ index_buffer_len_update(&index, p_buffer_len, max_buffer);
+
+ // Encode binding.
+ lwm2m_tlv_string_set(&tlv, p_server->binding, LWM2M_SERVER_BINDING);
+ err_code = lwm2m_tlv_encode(p_buffer + index, p_buffer_len, &tlv);
+
+ if (err_code != NRF_SUCCESS)
+ {
+ return err_code;
+ }
+
+ index_buffer_len_update(&index, p_buffer_len, max_buffer);
+
+ *p_buffer_len = index;
+
+ return NRF_SUCCESS;
+}
+
+
+uint32_t lwm2m_tlv_security_encode(uint8_t * p_buffer,
+ uint32_t * p_buffer_len,
+ lwm2m_security_t * p_security)
+{
+ uint32_t err_code;
+ uint32_t max_buffer = *p_buffer_len;
+ uint32_t index = 0;
+
+ lwm2m_tlv_t tlv;
+ tlv.id_type = TLV_TYPE_RESOURCE_VAL; // type is the same for all.
+
+
+ lwm2m_tlv_string_set(&tlv, p_security->server_uri, LWM2M_SECURITY_SERVER_URI);
+ err_code = lwm2m_tlv_encode(p_buffer + index, p_buffer_len, &tlv);
+
+ if (err_code != NRF_SUCCESS)
+ {
+ return err_code;
+ }
+
+ index_buffer_len_update(&index, p_buffer_len, max_buffer);
+
+ lwm2m_tlv_bool_set(&tlv, p_security->bootstrap_server, LWM2M_SECURITY_BOOTSTRAP_SERVER);
+ err_code = lwm2m_tlv_encode(p_buffer + index, p_buffer_len, &tlv);
+
+ if (err_code != NRF_SUCCESS)
+ {
+ return err_code;
+ }
+
+ index_buffer_len_update(&index, p_buffer_len, max_buffer);
+
+ lwm2m_tlv_uint16_set(&tlv, p_security->security_mode, LWM2M_SECURITY_SECURITY_MODE);
+ err_code = lwm2m_tlv_encode(p_buffer + index, p_buffer_len, &tlv);
+
+ if (err_code != NRF_SUCCESS)
+ {
+ return err_code;
+ }
+
+ index_buffer_len_update(&index, p_buffer_len, max_buffer);
+
+ lwm2m_tlv_opaque_set(&tlv, p_security->public_key, LWM2M_SECURITY_PUBLIC_KEY);
+ err_code = lwm2m_tlv_encode(p_buffer + index, p_buffer_len, &tlv);
+
+ if (err_code != NRF_SUCCESS)
+ {
+ return err_code;
+ }
+
+ index_buffer_len_update(&index, p_buffer_len, max_buffer);
+
+ lwm2m_tlv_opaque_set(&tlv, p_security->server_public_key, LWM2M_SECURITY_SERVER_PUBLIC_KEY);
+ err_code = lwm2m_tlv_encode(p_buffer + index, p_buffer_len, &tlv);
+
+ if (err_code != NRF_SUCCESS)
+ {
+ return err_code;
+ }
+
+ index_buffer_len_update(&index, p_buffer_len, max_buffer);
+
+ lwm2m_tlv_opaque_set(&tlv, p_security->secret_key, LWM2M_SECURITY_SECRET_KEY);
+ err_code = lwm2m_tlv_encode(p_buffer + index, p_buffer_len, &tlv);
+
+ if (err_code != NRF_SUCCESS)
+ {
+ return err_code;
+ }
+
+ index_buffer_len_update(&index, p_buffer_len, max_buffer);
+
+ lwm2m_tlv_uint16_set(&tlv, p_security->sms_security_mode, LWM2M_SECURITY_SMS_SECURITY_MODE);
+ err_code = lwm2m_tlv_encode(p_buffer + index, p_buffer_len, &tlv);
+
+ if (err_code != NRF_SUCCESS)
+ {
+ return err_code;
+ }
+
+ index_buffer_len_update(&index, p_buffer_len, max_buffer);
+
+ lwm2m_tlv_opaque_set(&tlv, p_security->sms_binding_key_param, LWM2M_SECURITY_SMS_BINDING_KEY_PARAM);
+ err_code = lwm2m_tlv_encode(p_buffer + index, p_buffer_len, &tlv);
+
+ if (err_code != NRF_SUCCESS)
+ {
+ return err_code;
+ }
+
+ index_buffer_len_update(&index, p_buffer_len, max_buffer);
+
+ lwm2m_tlv_opaque_set(&tlv, p_security->sms_binding_secret_keys, LWM2M_SECURITY_SMS_BINDING_SECRET_KEY);
+ err_code = lwm2m_tlv_encode(p_buffer + index, p_buffer_len, &tlv);
+
+ if (err_code != NRF_SUCCESS)
+ {
+ return err_code;
+ }
+
+ index_buffer_len_update(&index, p_buffer_len, max_buffer);
+
+ lwm2m_tlv_uint32_set(&tlv, p_security->sms_number, LWM2M_SECURITY_SERVER_SMS_NUMBER);
+ err_code = lwm2m_tlv_encode(p_buffer + index, p_buffer_len, &tlv);
+
+ if (err_code != NRF_SUCCESS)
+ {
+ return err_code;
+ }
+
+ index_buffer_len_update(&index, p_buffer_len, max_buffer);
+
+ lwm2m_tlv_uint16_set(&tlv, p_security->short_server_id, LWM2M_SECURITY_SHORT_SERVER_ID);
+ err_code = lwm2m_tlv_encode(p_buffer + index, p_buffer_len, &tlv);
+
+ if (err_code != NRF_SUCCESS)
+ {
+ return err_code;
+ }
+
+ index_buffer_len_update(&index, p_buffer_len, max_buffer);
+
+ lwm2m_tlv_uint32_set(&tlv, p_security->client_hold_off_time, LWM2M_SECURITY_CLIENT_HOLD_OFF_TIME);
+ err_code = lwm2m_tlv_encode(p_buffer + index, p_buffer_len, &tlv);
+
+ if (err_code != NRF_SUCCESS)
+ {
+ return err_code;
+ }
+
+ index_buffer_len_update(&index, p_buffer_len, max_buffer);
+
+ return NRF_SUCCESS;
+}
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/lwm2m/lwm2m_objects_tlv.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/lwm2m/lwm2m_objects_tlv.h
new file mode 100644
index 0000000..608ecef
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/lwm2m/lwm2m_objects_tlv.h
@@ -0,0 +1,124 @@
+/**
+ * Copyright (c) 2015 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 lwm2m_objects_tlv.h
+ *
+ * @defgroup iot_sdk_lwm2m_objects_tlv OMA LWM2M object TLV encoder and decoder API
+ * @ingroup iot_sdk_lwm2m
+ * @{
+ * @brief OMA LWM2M object TLV encoder and decoder API.
+ */
+
+#ifndef LWM2M_OBJECTS_TLV_H__
+#define LWM2M_OBJECTS_TLV_H__
+
+#include <stdint.h>
+#include "lwm2m_objects.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**@brief Decode a LWM2M server object from a TLV byte buffer.
+ *
+ * @note Resource values NOT found in the tlv will not be altered.
+ *
+ * @warning lwm2m_string_t and lwm2m_opaque_t values will point to the byte buffer and needs
+ * to be copied by the application before the byte buffer is freed.
+ *
+ * @param[out] p_server Pointer to a LWM2M server object to be filled by the decoded TLVs.
+ * @param[in] p_buffer Pointer to the TLV byte buffer to be decoded.
+ * @param[in] buffer_len Size of the buffer to be decoded.
+ *
+ * @retval NRF_SUCCESS If decoding was successful.
+ */
+uint32_t lwm2m_tlv_server_decode(lwm2m_server_t * p_server,
+ uint8_t * p_buffer,
+ uint32_t buffer_len);
+
+/**@brief Encode a LWM2M server object to a TLV byte buffer.
+ *
+ * @param[out] p_buffer Pointer to a byte buffer to be used to fill the encoded TLVs.
+ * @param[inout] p_buffer_len Value by reference indicating the size of the buffer provided.
+ * Will return the number of used bytes on return.
+ * @param[in] p_server Pointer to the LWM2M server object to be encoded into TLVs.
+ *
+ * @retval NRF_SUCCESS If the encoded was successful.
+ */
+uint32_t lwm2m_tlv_server_encode(uint8_t * p_buffer,
+ uint32_t * p_buffer_len,
+ lwm2m_server_t * p_server);
+
+/**@brief Decode a LWM2M security object from a TLV byte buffer.
+ *
+ * @note Resource values NOT found in the tlv will not be altered.
+ *
+ * @warning lwm2m_string_t and lwm2m_opaque_t values will point to the byte buffer and needs
+ * to be copied by the application before the byte buffer is freed.
+ *
+ * @param[out] p_security Pointer to a LWM2M server object to be filled by the decoded TLVs.
+ * @param[in] p_buffer Pointer to the TLV byte buffer to be decoded.
+ * @param[in] buffer_len Size of the buffer to be decoded.
+ *
+ * @retval NRF_SUCCESS If decoding was successful.
+ */
+uint32_t lwm2m_tlv_security_decode(lwm2m_security_t * p_security,
+ uint8_t * p_buffer,
+ uint32_t buffer_len);
+
+/**@brief Encode a LWM2M security object to a TLV byte buffer.
+ *
+ * @param[out] p_buffer Pointer to a byte buffer to be used to fill the encoded TLVs.
+ * @param[inout] p_buffer_len Value by reference indicating the size of the buffer provided.
+ * Will return the number of used bytes on return.
+ * @param[in] p_security Pointer to the LWM2M security object to be encoded into TLVs.
+ *
+ * @retval NRF_SUCCESS If the encoded was successful.
+ */
+uint32_t lwm2m_tlv_security_encode(uint8_t * p_buffer,
+ uint32_t * p_buffer_len,
+ lwm2m_security_t * p_security);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // LWM2M_OBJECTS_TLV_H__
+
+/** @} */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/lwm2m/lwm2m_register.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/lwm2m/lwm2m_register.c
new file mode 100644
index 0000000..3c273ee
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/lwm2m/lwm2m_register.c
@@ -0,0 +1,542 @@
+/**
+ * Copyright (c) 2015 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#include <string.h>
+#include <stdio.h>
+#include <stdint.h>
+#include "lwm2m_api.h"
+#include "lwm2m_register.h"
+#include "lwm2m.h"
+#include "coap_api.h"
+#include "coap_message.h"
+#include "coap_codes.h"
+#include "sdk_config.h"
+#include "app_util.h"
+
+#if LWM2M_CONFIG_LOG_ENABLED
+
+#define NRF_LOG_MODULE_NAME lwm2m
+
+#define NRF_LOG_LEVEL LWM2M_CONFIG_LOG_LEVEL
+#define NRF_LOG_INFO_COLOR LWM2M_CONFIG_INFO_COLOR
+#define NRF_LOG_DEBUG_COLOR LWM2M_CONFIG_DEBUG_COLOR
+
+#include "nrf_log.h"
+
+#define LWM2M_TRC NRF_LOG_DEBUG /**< Used for getting trace of execution in the module. */
+#define LWM2M_ERR NRF_LOG_ERROR /**< Used for logging errors in the module. */
+#define LWM2M_DUMP NRF_LOG_HEXDUMP_DEBUG /**< Used for dumping octet information to get details of bond information etc. */
+
+#define LWM2M_ENTRY() LWM2M_TRC(">> %s", __func__)
+#define LWM2M_EXIT() LWM2M_TRC("<< %s", __func__)
+
+#else // LWM2M_CONFIG_LOG_ENABLED
+
+#define LWM2M_TRC(...) /**< Disables traces. */
+#define LWM2M_DUMP(...) /**< Disables dumping of octet streams. */
+#define LWM2M_ERR(...) /**< Disables error logs. */
+
+#define LWM2M_ENTRY(...)
+#define LWM2M_EXIT(...)
+
+#endif // LWM2M_CONFIG_LOG_ENABLED
+
+#define LWM2M_REGISTER_URI_PATH "rd"
+
+#define TOKEN_START 0xAE1C
+
+typedef struct
+{
+ lwm2m_remote_t remote;
+ char location[LWM2M_REGISTER_MAX_LOCATION_LEN];
+ uint16_t location_len;
+} internal_lwm2m_remote_location_t;
+
+
+static internal_lwm2m_remote_location_t m_remote_to_location[LWM2M_MAX_SERVERS];
+
+static uint16_t num_servers = 0;
+static uint16_t m_token = TOKEN_START;
+
+static uint32_t internal_message_new(coap_message_t ** pp_msg,
+ coap_msg_code_t code,
+ coap_response_callback_t callback,
+ uint16_t local_port)
+{
+ uint32_t err_code;
+ coap_message_conf_t conf;
+ memset (&conf, 0, sizeof(coap_message_conf_t));
+
+ conf.type = COAP_TYPE_CON;
+ conf.code = code;
+ conf.response_callback = callback;
+ conf.port.port_number = local_port;
+
+ conf.token_len = uint16_encode(m_token, conf.token);
+
+ m_token++;
+
+ err_code = coap_message_new(pp_msg, &conf);
+
+ return err_code;
+}
+
+
+static uint32_t internal_location_find(lwm2m_string_t * p_location, lwm2m_remote_t * p_remote)
+{
+ for (uint16_t i = 0; i < num_servers; ++i)
+ {
+ if (memcmp(&m_remote_to_location[i].remote, p_remote, sizeof(lwm2m_remote_t)) == 0)
+ {
+ p_location->p_val = m_remote_to_location[i].location;
+ p_location->len = m_remote_to_location[i].location_len;
+ return NRF_SUCCESS;
+ }
+ }
+
+ return NRF_ERROR_NOT_FOUND;
+}
+
+
+static uint32_t internal_remote_location_save(lwm2m_string_t * location, lwm2m_remote_t * remote)
+{
+ for (uint16_t i = 0; i < num_servers; ++i)
+ {
+ if (memcmp(&m_remote_to_location[i].remote, remote, sizeof(lwm2m_remote_t)) == 0)
+ {
+ memcpy(m_remote_to_location[i].location, location->p_val, location->len);
+ m_remote_to_location[i].location_len = location->len;
+ return NRF_SUCCESS;
+ }
+ }
+
+ if (num_servers == LWM2M_MAX_SERVERS)
+ return NRF_ERROR_NO_MEM;
+
+ memcpy(&m_remote_to_location[num_servers].remote, remote, sizeof(lwm2m_remote_t));
+
+ memcpy(m_remote_to_location[num_servers].location, location->p_val, location->len);
+
+ m_remote_to_location[num_servers].location_len = location->len;
+
+ ++num_servers;
+
+ return NRF_SUCCESS;
+}
+
+
+static uint32_t internal_server_config_set(coap_message_t * msg, lwm2m_server_config_t * p_config)
+{
+ char buffer[32];
+ uint32_t err_code = NRF_SUCCESS;
+
+ if (p_config->lifetime > 0)
+ {
+ int retval = snprintf(buffer, sizeof(buffer), "lt=%lu", p_config->lifetime);
+ if (retval < 0)
+ {
+ err_code = NRF_ERROR_INVALID_PARAM;
+ }
+ else
+ {
+ err_code = coap_message_opt_str_add(msg,
+ COAP_OPT_URI_QUERY,
+ (uint8_t *)buffer,
+ strlen(buffer));
+ }
+ }
+
+ if (err_code == NRF_SUCCESS)
+ {
+ if ((p_config->lwm2m_version_major > 0) || (p_config->lwm2m_version_minor > 0))
+ {
+ int retval = snprintf(buffer,
+ sizeof(buffer),
+ "lwm2m=%d.%d",
+ p_config->lwm2m_version_major,
+ p_config->lwm2m_version_minor);
+ if (retval < 0)
+ {
+ err_code = NRF_ERROR_INVALID_PARAM;
+ }
+ else
+ {
+ err_code = coap_message_opt_str_add(msg,
+ COAP_OPT_URI_QUERY,
+ (uint8_t *)buffer,
+ strlen(buffer));
+ }
+ }
+ }
+
+ if (err_code == NRF_SUCCESS)
+ {
+ if (p_config->msisdn > 0)
+ {
+ int retval = snprintf(buffer, sizeof(buffer), "sms=%llu" , p_config->msisdn);
+ if (retval < 0)
+ {
+ err_code = NRF_ERROR_INVALID_PARAM;
+ }
+ else
+ {
+ err_code = coap_message_opt_str_add(msg,
+ COAP_OPT_URI_QUERY,
+ (uint8_t *)buffer,
+ strlen(buffer));
+ }
+ }
+ }
+
+ if (err_code == NRF_SUCCESS)
+ {
+ if (p_config->binding.len > 0)
+ {
+ if (p_config->binding.len < sizeof(buffer) - 2)
+ {
+ buffer[0] = 'b';
+ buffer[1] = '=';
+ memcpy(buffer + 2, p_config->binding.p_val, p_config->binding.len);
+
+ err_code = coap_message_opt_str_add(msg,
+ COAP_OPT_URI_QUERY,
+ (uint8_t *)buffer,
+ p_config->binding.len + 2);
+ }
+ else
+ {
+ err_code = NRF_ERROR_NO_MEM;
+ }
+ }
+ }
+
+ return err_code;
+}
+
+
+uint32_t internal_lwm2m_register_init(void)
+{
+ m_token = TOKEN_START;
+ num_servers = 0;
+ return NRF_SUCCESS;
+}
+
+
+static void lwm2m_register_cb(uint32_t status, void * p_arg, coap_message_t * p_message)
+{
+ LWM2M_TRC("[Register]: lwm2m_register_cb, status: %ul, coap code: %u",
+ status,
+ p_message->header.code);
+
+ LWM2M_MUTEX_LOCK();
+
+ for (uint16_t i = 0; i < p_message->options_count; ++i)
+ {
+ coap_option_t option = p_message->options[i];
+
+ if (option.number == COAP_OPT_LOCATION_PATH)
+ {
+ lwm2m_string_t location;
+ location.p_val = (char *) option.p_data;
+ location.len = option.length;
+ (void)internal_remote_location_save(&location, &p_message->remote);
+ }
+ }
+
+ LWM2M_MUTEX_UNLOCK();
+
+ (void)lwm2m_notification(LWM2M_NOTIFCATION_TYPE_REGISTER,
+ &p_message->remote,
+ p_message->header.code);
+}
+
+
+uint32_t lwm2m_register(lwm2m_remote_t * p_remote,
+ lwm2m_client_identity_t * p_id,
+ lwm2m_server_config_t * p_config,
+ uint16_t local_port,
+ uint8_t * p_link_format_string,
+ uint16_t link_format_len)
+{
+ LWM2M_ENTRY();
+
+ NULL_PARAM_CHECK(p_remote);
+ NULL_PARAM_CHECK(p_id);
+ NULL_PARAM_CHECK(p_config);
+ NULL_PARAM_CHECK(p_link_format_string);
+
+ LWM2M_MUTEX_LOCK();
+
+ uint32_t err_code;
+ char buffer[40];
+
+ lwm2m_string_t endpoint;
+
+ endpoint.p_val = LWM2M_REGISTER_URI_PATH;
+ endpoint.len = 2;
+
+ coap_message_t * p_msg;
+
+ err_code = internal_message_new(&p_msg, COAP_CODE_POST, lwm2m_register_cb, local_port);
+ if (err_code != NRF_SUCCESS)
+ {
+ LWM2M_MUTEX_UNLOCK();
+ return err_code;
+ }
+
+ if (err_code == NRF_SUCCESS)
+ {
+ err_code = coap_message_remote_addr_set(p_msg, p_remote);
+ }
+
+ if (err_code == NRF_SUCCESS)
+ {
+ // Set uri-path option
+ err_code = coap_message_opt_str_add(p_msg,
+ COAP_OPT_URI_PATH,
+ (uint8_t *)endpoint.p_val,
+ endpoint.len); // end_point length is always 2
+ }
+
+ if (err_code == NRF_SUCCESS)
+ {
+ // Set content format.
+ err_code = coap_message_opt_uint_add(p_msg, COAP_OPT_CONTENT_FORMAT, COAP_CT_APP_LINK_FORMAT);
+ }
+
+ if (err_code == NRF_SUCCESS)
+ {
+ // Set queries.
+ buffer[0] = 'e';
+ buffer[1] = 'p';
+ buffer[2] = '=';
+ memcpy(buffer + 3, &p_id->value, p_id->type);
+
+ err_code = coap_message_opt_str_add(p_msg,
+ COAP_OPT_URI_QUERY,
+ (uint8_t *)buffer,
+ p_id->type + 3);
+ }
+
+ if (err_code == NRF_SUCCESS)
+ {
+ err_code = internal_server_config_set(p_msg, p_config);
+ }
+
+ if (err_code == NRF_SUCCESS)
+ {
+ err_code = coap_message_payload_set(p_msg, p_link_format_string, link_format_len);
+ }
+
+ if (err_code == NRF_SUCCESS)
+ {
+ uint32_t msg_handle;
+ err_code = coap_message_send(&msg_handle, p_msg);
+ }
+
+ if (err_code == NRF_SUCCESS)
+ {
+ err_code = coap_message_delete(p_msg);
+ }
+ else
+ {
+ // If we have hit an error try to clean up.
+ // Return the original error code.
+ (void)coap_message_delete(p_msg);
+ }
+
+ LWM2M_MUTEX_UNLOCK();
+
+ LWM2M_EXIT();
+
+ return err_code;
+}
+
+void lwm2m_update_cb(uint32_t status, void * p_arg, coap_message_t * p_message)
+{
+ LWM2M_TRC("[Update]: lwm2m_update_cb, status: %ul, coap code: %u",
+ status,
+ p_message->header.code);
+
+ (void)lwm2m_notification(LWM2M_NOTIFCATION_TYPE_UPDATE,
+ &p_message->remote,
+ p_message->header.code);
+}
+
+
+uint32_t lwm2m_update(lwm2m_remote_t * p_remote, lwm2m_server_config_t * p_config, uint16_t local_port)
+{
+ LWM2M_ENTRY();
+
+ NULL_PARAM_CHECK(p_remote);
+ NULL_PARAM_CHECK(p_config);
+
+ LWM2M_MUTEX_LOCK();
+
+ uint32_t err_code;
+ coap_message_t * p_msg;
+
+ err_code = internal_message_new(&p_msg, COAP_CODE_POST, lwm2m_update_cb, local_port);
+ if (err_code != NRF_SUCCESS)
+ {
+ LWM2M_MUTEX_UNLOCK();
+ return err_code;
+ }
+
+ if (err_code == NRF_SUCCESS)
+ {
+ err_code = coap_message_remote_addr_set(p_msg, p_remote);
+ }
+
+ if (err_code == NRF_SUCCESS)
+ {
+ lwm2m_string_t location;
+ err_code = internal_location_find(&location, p_remote);
+
+ if (err_code == NRF_SUCCESS)
+ {
+ // Sets URI PATH
+ err_code = coap_message_opt_str_add(p_msg,
+ COAP_OPT_URI_PATH,
+ (uint8_t *)location.p_val,
+ location.len);
+ }
+ }
+
+ if (err_code == NRF_SUCCESS)
+ {
+ // Sets CoAP queries
+ err_code = internal_server_config_set(p_msg, p_config);
+ }
+
+ if (err_code == NRF_SUCCESS)
+ {
+ uint32_t msg_handle;
+ err_code = coap_message_send(&msg_handle, p_msg);
+ }
+
+ if (err_code == NRF_SUCCESS)
+ {
+ err_code = coap_message_delete(p_msg);
+ }
+ else
+ {
+ // If we have hit an error try to clean up.
+ // Return the original error code.
+ (void)coap_message_delete(p_msg);
+ }
+
+ LWM2M_EXIT();
+
+ LWM2M_MUTEX_UNLOCK();
+
+ return err_code;
+}
+
+void lwm2m_deregister_cb(uint32_t status, void * p_arg, coap_message_t * p_message)
+{
+ LWM2M_TRC("[DeRegister]: lwm2m_deregister_cb, status: %ul, coap code: %u",
+ status,
+ p_message->header.code);
+
+ (void)lwm2m_notification(LWM2M_NOTIFCATION_TYPE_DEREGISTER,
+ &p_message->remote,
+ p_message->header.code);
+}
+
+uint32_t lwm2m_deregister(lwm2m_remote_t * p_remote, uint16_t local_port)
+{
+ LWM2M_ENTRY();
+
+ NULL_PARAM_CHECK(p_remote);
+
+ LWM2M_MUTEX_LOCK();
+
+ uint32_t err_code;
+ coap_message_t * p_msg;
+
+ err_code = internal_message_new(&p_msg, COAP_CODE_DELETE, lwm2m_deregister_cb, local_port);
+ if (err_code != NRF_SUCCESS)
+ {
+ LWM2M_MUTEX_UNLOCK();
+ return err_code;
+ }
+
+ if (err_code == NRF_SUCCESS)
+ {
+ err_code = coap_message_remote_addr_set(p_msg, p_remote);
+ }
+
+ if (err_code == NRF_SUCCESS)
+ {
+ lwm2m_string_t location;
+ err_code = internal_location_find(&location, p_remote);
+
+ if (err_code == NRF_SUCCESS)
+ {
+ err_code = coap_message_opt_str_add(p_msg,
+ COAP_OPT_URI_PATH,
+ (uint8_t *)location.p_val,
+ location.len);
+ }
+ }
+
+ if (err_code == NRF_SUCCESS)
+ {
+ uint32_t msg_handle;
+ err_code = coap_message_send(&msg_handle, p_msg);
+ }
+
+ if (err_code == NRF_SUCCESS)
+ {
+ err_code = coap_message_delete(p_msg);
+ }
+ else
+ {
+ // If we have hit an error try to clean up.
+ // Return the original error code.
+ (void)coap_message_delete(p_msg);
+ }
+
+ LWM2M_EXIT();
+
+ LWM2M_MUTEX_UNLOCK();
+
+ return err_code;
+}
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/lwm2m/lwm2m_register.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/lwm2m/lwm2m_register.h
new file mode 100644
index 0000000..5daa950
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/lwm2m/lwm2m_register.h
@@ -0,0 +1,69 @@
+/**
+ * Copyright (c) 2015 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 lwm2m_register.h
+ *
+ * @defgroup iot_sdk_lwm2m_register_api LWM2M register API interface
+ * @ingroup iot_sdk_lwm2m
+ * @{
+ * @brief Register API interface for the LWM2M protocol.
+ */
+
+#ifndef LWM2M_REGISTER_H__
+#define LWM2M_REGISTER_H__
+
+#include <stdint.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**@brief Initialize the LWM2M register module.
+ *
+ * @details Calling this function will set the module in default state.
+ */
+uint32_t internal_lwm2m_register_init(void);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // LWM2M_REGISTER_H__
+
+/**@} */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/lwm2m/lwm2m_tlv.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/lwm2m/lwm2m_tlv.c
new file mode 100644
index 0000000..047cdb7
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/lwm2m/lwm2m_tlv.c
@@ -0,0 +1,399 @@
+/**
+ * Copyright (c) 2015 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#include <stdint.h>
+#include <string.h>
+#include "lwm2m_tlv.h"
+#include "lwm2m_objects.h"
+#include "iot_errors.h"
+#include "iot_defines.h"
+
+// Used for encoding
+// TODO: Remove this temp_buffer in order to allow to users to use the API at the same time.
+// Current implementation might fail if two different interrupt levels are executing
+// encode at the same time. The temp_buffer will be overwritten by the last user.
+static uint8_t temp_buffer[4];
+
+
+uint32_t lwm2m_tlv_bytebuffer_to_uint32(uint8_t * p_buffer, uint8_t val_len, uint32_t * p_result)
+{
+ uint32_t res;
+ switch (val_len)
+ {
+ case 0:
+ {
+ res = 0;
+ break;
+ }
+
+ case 1:
+ {
+ res = p_buffer[0];
+ break;
+ }
+
+ case 2:
+ {
+ res = ((uint32_t)p_buffer[0] << 8) |
+ p_buffer[1];
+ break;
+ }
+
+ case 3:
+ {
+ res = ((uint32_t)p_buffer[0] << 16) |
+ ((uint32_t)p_buffer[1] << 8) |
+ p_buffer[2];
+ break;
+ }
+
+ case 4:
+ {
+ res = ((uint32_t)p_buffer[0] << 24) |
+ ((uint32_t)p_buffer[1] << 16) |
+ ((uint32_t)p_buffer[2] << 8) |
+ p_buffer[3];
+ break;
+ }
+
+ default:
+ return NRF_ERROR_DATA_SIZE;
+ }
+
+ *p_result = res;
+ return NRF_SUCCESS;
+}
+
+
+uint32_t lwm2m_tlv_bytebuffer_to_uint16(uint8_t * p_buffer, uint8_t val_len, uint16_t * p_result)
+{
+ uint16_t res;
+ switch (val_len)
+ {
+ case 0:
+ {
+ res = 0;
+ break;
+ }
+
+ case 1:
+ {
+ res = p_buffer[0];
+ break;
+ }
+
+ case 2:
+ {
+ res = ((uint16_t)p_buffer[0] << 8) | p_buffer[1];
+ break;
+ }
+
+ default:
+ return NRF_ERROR_DATA_SIZE;
+ }
+
+ *p_result = res;
+ return NRF_SUCCESS;
+}
+
+
+void lwm2m_tlv_uint16_to_bytebuffer(uint8_t * p_buffer, uint8_t * p_len, uint16_t value)
+{
+ if (value == 0)
+ {
+ *p_len = 0;
+ }
+ else if (value <= UINT8_MAX)
+ {
+ p_buffer[0] = value;
+ *p_len = 1;
+ }
+ else
+ {
+
+ p_buffer[1] = value;
+ p_buffer[0] = value >> 8;
+ *p_len = 2;
+ }
+}
+
+
+void lwm2m_tlv_uint32_to_bytebuffer(uint8_t * p_buffer, uint8_t * p_len, uint32_t value)
+{
+ if (value == 0)
+ {
+ *p_len = 0;
+ }
+ else if (value <= UINT8_MAX)
+ {
+ p_buffer[0] = value;
+ *p_len = 1;
+ }
+ else if (value <= UINT16_MAX)
+ {
+
+ p_buffer[1] = value;
+ p_buffer[0] = value >> 8;
+ *p_len = 2;
+ }
+ else if (value <= 0xFFFFFF) // 24 bit
+ {
+ p_buffer[2] = value;
+ p_buffer[1] = value >> 8;
+ p_buffer[0] = value >> 16;
+ *p_len = 3;
+ }
+ else
+ {
+ p_buffer[3] = value;
+ p_buffer[2] = value >> 8;
+ p_buffer[1] = value >> 16;
+ p_buffer[0] = value >> 24;
+ *p_len = 4;
+ }
+}
+
+
+void lwm2m_tlv_uint16_set(lwm2m_tlv_t * p_tlv, uint16_t value, uint16_t id)
+{
+ uint8_t val_len;
+ lwm2m_tlv_uint16_to_bytebuffer(temp_buffer, &val_len, value);
+
+ p_tlv->length = val_len;
+ p_tlv->value = temp_buffer;
+ p_tlv->id = id;
+}
+
+
+void lwm2m_tlv_uint32_set(lwm2m_tlv_t * p_tlv, uint32_t value, uint16_t id)
+{
+ uint8_t val_len;
+ lwm2m_tlv_uint32_to_bytebuffer(temp_buffer, &val_len, value);
+
+ p_tlv->length = val_len;
+ p_tlv->value = temp_buffer;
+ p_tlv->id = id;
+}
+
+
+void lwm2m_tlv_bool_set(lwm2m_tlv_t * p_tlv, bool value, uint16_t id)
+{
+
+ if (value == true)
+ {
+ temp_buffer[0] = 1;
+ }
+ else
+ {
+ temp_buffer[0] = 0;
+ }
+
+ p_tlv->length = 1;
+ p_tlv->value = temp_buffer;
+ p_tlv->id = id;
+}
+
+
+void lwm2m_tlv_string_set(lwm2m_tlv_t * p_tlv, lwm2m_string_t string, uint16_t id)
+{
+ p_tlv->length = string.len;
+ p_tlv->value = (uint8_t *)string.p_val;
+ p_tlv->id = id;
+}
+
+
+void lwm2m_tlv_opaque_set(lwm2m_tlv_t * p_tlv, lwm2m_opaque_t opaque, uint16_t id)
+{
+ p_tlv->length = opaque.len;
+ p_tlv->value = opaque.p_val;
+ p_tlv->id = id;
+}
+
+
+uint32_t lwm2m_tlv_decode(lwm2m_tlv_t * p_tlv,
+ uint32_t * p_index,
+ uint8_t * p_buffer,
+ uint16_t buffer_len)
+{
+ uint32_t err_code;
+ uint16_t index = *p_index;
+
+ uint8_t type = (p_buffer[index] & TLV_TYPE_MASK) >> TLV_TYPE_BIT_POS;
+ uint8_t id_len = (p_buffer[index] & TLV_ID_LEN_MASK) >> TLV_ID_LEN_BIT_POS;
+ uint8_t length_len = (p_buffer[index] & TLV_LEN_TYPE_MASK) >> TLV_LEN_TYPE_BIT_POS;
+ uint32_t length = (p_buffer[index] & TLV_LEN_VAL_MASK) >> TLV_VAL_LEN_BIT_POS;
+
+ p_tlv->id_type = type;
+ p_tlv->length = 0;
+
+ // Jump to the byte following the "Type" at index 0.
+ ++index;
+
+ // Extract the Identifier based on the number of bytes indicated in id_len (bit 5).
+ // Adding one to the id_len will give the number of bytes used.
+ uint8_t id_len_size = id_len + 1;
+
+ err_code = lwm2m_tlv_bytebuffer_to_uint16(&p_buffer[index], id_len_size, &p_tlv->id);
+
+ if (err_code != NRF_SUCCESS)
+ {
+ return err_code;
+ }
+ index += id_len_size;
+
+
+ // Extract the value length.
+ // The length_len tells how many bytes are being used.
+ if (length_len == TLV_LEN_TYPE_3BIT)
+ {
+ p_tlv->length = length;
+ }
+ else
+ {
+ err_code = lwm2m_tlv_bytebuffer_to_uint32(&p_buffer[index], length_len, &length);
+ if (err_code != NRF_SUCCESS)
+ {
+ return err_code;
+ }
+
+ p_tlv->length = length;
+ index += length_len;
+ }
+
+ if (p_tlv->length > buffer_len)
+ {
+ return (IOT_LWM2M_ERR_BASE | NRF_ERROR_INVALID_DATA);
+ }
+
+ p_tlv->value = &p_buffer[index];
+
+ *p_index = index + p_tlv->length;
+
+ return NRF_SUCCESS;
+}
+
+
+uint32_t lwm2m_tlv_encode(uint8_t * p_buffer, uint32_t * buffer_len, lwm2m_tlv_t * p_tlv)
+{
+ uint8_t length_len;
+ uint8_t id_len;
+
+ uint8_t id[2] = {0,};
+ uint8_t len[3] = {0,};
+ uint16_t index = 0;
+ uint8_t type = 0;
+
+ // Set Identifier type by copying the lwm2m_tlv_t->id_type into bit 7-6.
+ type = (p_tlv->id_type << TLV_TYPE_BIT_POS);
+
+ // Set length of Identifier in bit 5 in the TLV type byte.
+ if (p_tlv->id > UINT8_MAX)
+ {
+ type |= (TLV_ID_LEN_16BIT << TLV_ID_LEN_BIT_POS);
+ id[0] = p_tlv->id >> 8;
+ id[1] = p_tlv->id;
+ id_len = 2;
+ }
+ else
+ {
+ type |= (TLV_ID_LEN_8BIT << TLV_ID_LEN_BIT_POS);
+ id[0] = p_tlv->id;
+ id_len = 1;
+ }
+
+ // Set type of Length bit 4-3 in the TLV type byte.
+
+ // If the Length can fit into 3 bits.
+ if ((p_tlv->length & TLV_LEN_VAL_MASK) == p_tlv->length)
+ {
+ type |= (TLV_LEN_TYPE_3BIT << TLV_LEN_TYPE_BIT_POS);
+ length_len = 0;
+
+ // As Length type field is set to "No Length", set bit 2-0.
+ type |= (p_tlv->length & TLV_LEN_VAL_MASK);
+ }
+ else
+ {
+ lwm2m_tlv_uint32_to_bytebuffer(&len[0], &length_len, p_tlv->length);
+
+ // Length can not be larger than 24-bit.
+ if (length_len > TLV_LEN_TYPE_24BIT)
+ {
+ return (IOT_LWM2M_ERR_BASE | NRF_ERROR_INVALID_PARAM);
+ }
+
+ type |= (length_len << TLV_LEN_TYPE_BIT_POS);
+ }
+
+ // Check if the buffer is large enough.
+ if (*buffer_len < (p_tlv->length + id_len + length_len + 1)) // + 1 for the type byte
+ {
+ return (IOT_LWM2M_ERR_BASE | NRF_ERROR_DATA_SIZE);
+ }
+
+ // Copy the type to the buffer.
+ memcpy(p_buffer + index, &type, 1);
+ ++index;
+
+ // Copy the Identifier to the buffer.
+ memcpy(p_buffer + index, id, id_len);
+ index += id_len;
+
+ // Copy length to the buffer.
+ if (length_len != 0)
+ {
+ memcpy(p_buffer + index, len, length_len);
+ index += length_len;
+ }
+
+ // Copy the value to buffer, memcpy of 0 length is undefined behavior so lets avoid it.
+ if (p_tlv->length > 0)
+ {
+ memcpy(p_buffer + index, p_tlv->value, p_tlv->length);
+ }
+
+ // Set length of the output buffer.
+ *buffer_len = p_tlv->length + index;
+
+ return NRF_SUCCESS;
+}
+
+
+
+
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/lwm2m/lwm2m_tlv.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/lwm2m/lwm2m_tlv.h
new file mode 100644
index 0000000..8ac5784
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/lwm2m/lwm2m_tlv.h
@@ -0,0 +1,207 @@
+/**
+ * Copyright (c) 2015 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 lwm2m_tlv.h
+ *
+ * @defgroup iot_sdk_lwm2m_tlv_api LWM2M TLV interface
+ * @ingroup iot_sdk_lwm2m
+ * @{
+ * @brief TLV encoding and decoding interface for the LWM2M protocol.
+ */
+
+#ifndef LWM2M_TLV_H__
+#define LWM2M_TLV_H__
+
+#include <stdint.h>
+#include "lwm2m_objects.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+* TLV type masks
+*/
+#define TLV_TYPE_BIT_POS 6
+#define TLV_ID_LEN_BIT_POS 5
+#define TLV_LEN_TYPE_BIT_POS 3
+#define TLV_VAL_LEN_BIT_POS 0
+
+#define TLV_TYPE_MASK (0x3 << TLV_TYPE_BIT_POS) /**< Type bitmask, bit 7-6 (0b11000000). */
+#define TLV_ID_LEN_MASK (0x1 << TLV_ID_LEN_BIT_POS) /**< Length bitmask, bit 5 (0b00100000). */
+#define TLV_LEN_TYPE_MASK (0x3 << TLV_LEN_TYPE_BIT_POS) /**< Length type bitmask, bit 4-3 (0b00011000). */
+#define TLV_LEN_VAL_MASK (0x7 << TLV_VAL_LEN_BIT_POS) /**< Length of the value bitmask, bit 2-0 (0b00000111). */
+
+#define TLV_TYPE_OBJECT 0x00
+#define TLV_TYPE_RESOURCE_INSTANCE 0x01
+#define TLV_TYPE_MULTI_RESOURCE 0x02
+#define TLV_TYPE_RESOURCE_VAL 0x03
+
+#define TLV_ID_LEN_8BIT 0x00
+#define TLV_ID_LEN_16BIT 0x01
+
+#define TLV_LEN_TYPE_3BIT 0x00
+#define TLV_LEN_TYPE_8BIT 0x01
+#define TLV_LEN_TYPE_16BIT 0x02
+#define TLV_LEN_TYPE_24BIT 0x03
+
+typedef struct
+{
+ uint16_t id_type; /**< Identifier type. */
+ uint16_t id; /**< Identifier ID. */
+ uint32_t length; /**< Length of the value in the TLV. */
+ uint8_t * value; /**< Value of the TLV. */
+} lwm2m_tlv_t;
+
+/**@brief Decode a LWM2M TLV byte buffer into a TLV structure.
+ *
+ * @param[out] p_tlv This struct will be filled with id, length, type and pointer to value.
+ * @param[inout] p_index Index to start decoding from.
+ * @param[in] p_buffer The buffer to decode from.
+ * @param[in] buffer_len The length of the buffer.
+ *
+ * @retval NRF_SUCCESS If decoding was successful.
+ * @retval IOT_LWM2M_ERR_BASE | NRF_INVALID_DATA
+ */
+uint32_t lwm2m_tlv_decode(lwm2m_tlv_t * p_tlv, uint32_t * p_index, uint8_t * p_buffer, uint16_t buffer_len);
+
+/**@brief Encode a TLV structure into a LWM2M TLV byte buffer.
+ *
+ * @details Encode using the provided tlv, if the buffer provided is to small an NRF_ERROR_DATA_SIZE will be returned.
+ *
+ * Maximum buffer size requirement: value_length + 6 (1 for type byte, 2 for id bytes, 3 for length bytes).
+ *
+ * @param[out] p_buffer Buffer to put the encoded tlv into.
+ * @param[inout] buffer_len Length of input buffer out: length of the encoded buffer.
+ * @param[in] p_tlv The tlv to use.
+ *
+ * @retval NRF_SUCCESS If decoding was successful.
+ * @retval IOT_LWM2M_ERR_BASE | NRF_ERROR_DATA_SIZE
+ */
+uint32_t lwm2m_tlv_encode(uint8_t * p_buffer, uint32_t * p_buffer_len, lwm2m_tlv_t * p_tlv);
+
+/**@brief Encode a byte buffer into a uint32_t.
+ *
+ * @param[in] p_buffer Buffer which holds a serialized version of the uint32_t.
+ * @param[in] val_len Length of the value in the buffer.
+ * @param[out] p_result By reference pointer to the result uint32_t.
+ *
+ * @retval NRF_SUCCESS If the conversion from byte buffer to uint32_t value was successful.
+ */
+uint32_t lwm2m_tlv_bytebuffer_to_uint32(uint8_t * p_buffer, uint8_t val_len, uint32_t * p_result);
+
+/**@brief Encode a byte buffer into a uint16_t.
+ *
+ * @param[in] p_buffer Buffer which holds a serialized version of the uint16_t.
+ * @param[in] val_len Length of the value in the buffer.
+ * @param[out] p_result By reference pointer to the result uint16_t.
+ *
+ * @retval NRF_SUCCESS If the conversion from byte buffer to uint32_t value was successful.
+ */
+uint32_t lwm2m_tlv_bytebuffer_to_uint16(uint8_t * p_buffer, uint8_t val_len, uint16_t * p_result);
+
+/**@brief Decode a uint32_t into a byte buffer.
+ *
+ * @param[out] p_buffer Buffer which holds a serialized version of the uint32_t.
+ * @param[out] p_len By reference pointer to hold the length of the serialized value in the buffer.
+ * @param[in] value Value to convert serialize into a byte buffer.
+ *
+ * @retval NRF_SUCCESS If the conversion from uint32_t value to byte buffer was successful.
+ */
+void lwm2m_tlv_uint32_to_bytebuffer(uint8_t * p_buffer, uint8_t * p_len, uint32_t value);
+
+/**@brief Decode a uint16_t into a byte buffer.
+ *
+ * @param[out] p_buffer Buffer which holds a serialized version of the uint16_t.
+ * @param[out] p_len By reference pointer to hold the length of the serialized value in the buffer.
+ * @param[in] value Value to convert serialize into a byte buffer.
+ *
+ * @retval NRF_SUCCESS If the conversion from uint16_t value to byte buffer was successful.
+ */
+void lwm2m_tlv_uint16_to_bytebuffer(uint8_t * p_buffer, uint8_t * p_len, uint16_t value);
+
+/**@brief Set a uint32_t value to a lwm2m_tlv_t structure.
+ *
+ * @param[out] p_tlv TLV containing the uint32_t tlv.
+ * @param[in] value Value to set.
+ * @param[in] id Resource Id associated with the value.
+ */
+void lwm2m_tlv_uint32_set(lwm2m_tlv_t * p_tlv, uint32_t value, uint16_t id);
+
+
+/**@brief Set a uint16_t value to a lwm2m_tlv_t structure.
+ *
+ * @param[out] p_tlv TLV containing the uint16_t tlv.
+ * @param[in] value Value to set.
+ * @param[in] id Resource Id associated with the value.
+ */
+void lwm2m_tlv_uint16_set(lwm2m_tlv_t * p_tlv, uint16_t value, uint16_t id);
+
+
+/**@brief Set a boolean value to a lwm2m_tlv_t structure.
+ *
+ * @param[out] p_tlv TLV containing the boolean tlv.
+ * @param[in] value Value to set.
+ * @param[in] id Resource Id associated with the value.
+ */
+void lwm2m_tlv_bool_set(lwm2m_tlv_t * p_tlv, bool value, uint16_t id);
+
+/**@brief Set a string value to a lwm2m_tlv_t structure.
+ *
+ * @param[out] p_tlv TLV containing the string tlv.
+ * @param[in] value Value to set.
+ * @param[in] id Resource Id associated with the value.
+ */
+void lwm2m_tlv_string_set(lwm2m_tlv_t * p_tlv, lwm2m_string_t string, uint16_t id);
+
+/**@brief Set a opaque value to a lwm2m_tlv_t structure.
+ *
+ * @param[out] p_tlv TLV containing the opaque tlv.
+ * @param[in] value Value to set.
+ * @param[in] id Resource Id associated with the value.
+ */
+void lwm2m_tlv_opaque_set(lwm2m_tlv_t * p_tlv, lwm2m_opaque_t opaque, uint16_t id);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // LWM2M_TLV_H__
+
+/** @} */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/medium/ble_ncfgs/ble_ncfgs.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/medium/ble_ncfgs/ble_ncfgs.c
new file mode 100644
index 0000000..241ec48
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/medium/ble_ncfgs/ble_ncfgs.c
@@ -0,0 +1,516 @@
+/**
+ * Copyright (c) 2015-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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#ifdef COMMISSIONING_ENABLED
+
+#include <string.h>
+#include "ble_ncfgs.h"
+#include "app_error.h"
+#include "ble.h"
+#include "nordic_common.h"
+
+/**@brief NCFGS database encapsulation. */
+typedef struct
+{
+ uint16_t service_handle;
+ ble_gatts_char_handles_t ssid_handles;
+ ble_gatts_char_handles_t keys_store_handles;
+ ble_gatts_char_handles_t ctrlp_handles;
+} ble_database_t;
+
+static ble_ncfgs_state_t m_service_state = NCFGS_STATE_IDLE; /**< Module state value. */
+static ble_ncfgs_evt_handler_t m_app_evt_handler; /**< Parent module callback function. */
+static ble_database_t m_database; /**< GATT handles database. */
+static uint8_t m_ctrlp_value_buffer[NCFGS_CTRLP_VALUE_LEN]; /**< Stores received Control Point value before parsing. */
+static ble_ncfgs_data_t m_ncfgs_data; /**< Stores all values written by the peer device. */
+
+#if NCFGS_CONFIG_LOG_ENABLED
+
+#define NRF_LOG_MODULE_NAME ble_ncfgs
+
+#define NRF_LOG_LEVEL NCFGS_CONFIG_LOG_LEVEL
+#define NRF_LOG_INFO_COLOR NCFGS_CONFIG_INFO_COLOR
+#define NRF_LOG_DEBUG_COLOR NCFGS_CONFIG_DEBUG_COLOR
+
+#include "nrf_log.h"
+NRF_LOG_MODULE_REGISTER();
+
+#define NCFGS_TRC NRF_LOG_DEBUG /**< Used for getting trace of execution in the module. */
+#define NCFGS_ERR NRF_LOG_ERROR /**< Used for logging errors in the module. */
+#define NCFGS_DUMP NRF_LOG_HEXDUMP_DEBUG /**< Used for dumping octet information to get details of bond information etc. */
+
+#define NCFGS_ENTRY() NCFGS_TRC(">> %s", __func__)
+#define NCFGS_EXIT() NCFGS_TRC("<< %s", __func__)
+
+#else // NCFGS_CONFIG_LOG_ENABLED
+
+#define NCFGS_TRC(...) /**< Disables traces. */
+#define NCFGS_DUMP(...) /**< Disables dumping of octet streams. */
+#define NCFGS_ERR(...) /**< Disables error logs. */
+
+#define NCFGS_ENTRY(...)
+#define NCFGS_EXIT(...)
+
+#endif // NCFGS_CONFIG_LOG_ENABLED
+
+/**@brief Function for adding the SSID Store characteristic.
+ *
+ * @return NRF_SUCCESS on success, otherwise an error code.
+ */
+static uint32_t add_ssid_characteristic(ble_uuid_t * p_srv_uuid)
+{
+ ble_gatts_char_md_t char_md;
+ ble_gatts_attr_t attr_char_value;
+ ble_uuid_t char_uuid;
+ ble_gatts_attr_md_t attr_md;
+
+ memset(&char_md, 0x00, sizeof(char_md));
+
+ char_md.char_props.read = 1;
+ char_md.char_props.write = 1;
+
+ memset(&attr_md, 0x00, sizeof(attr_md));
+
+ BLE_GAP_CONN_SEC_MODE_SET_OPEN(&attr_md.read_perm);
+ BLE_GAP_CONN_SEC_MODE_SET_OPEN(&attr_md.write_perm);
+ attr_md.wr_auth = 1;
+ attr_md.vloc = BLE_GATTS_VLOC_USER;
+
+ memset(&attr_char_value, 0x00, sizeof(attr_char_value));
+
+ char_uuid.type = p_srv_uuid->type;
+ char_uuid.uuid = BLE_UUID_NCFGS_SSID_CHAR;
+
+ attr_char_value.p_uuid = &char_uuid;
+ attr_char_value.p_attr_md = &attr_md;
+ attr_char_value.init_len = NCFGS_SSID_MAX_LEN;
+ attr_char_value.init_offs = 0;
+ attr_char_value.max_len = NCFGS_SSID_MAX_LEN;
+ attr_char_value.p_value = &m_ncfgs_data.ssid_from_router.ssid[0];
+
+ return sd_ble_gatts_characteristic_add(m_database.service_handle,
+ &char_md,
+ &attr_char_value,
+ &m_database.ssid_handles);
+}
+
+
+/**@brief Function for adding the Keys Store characteristic.
+ *
+ * @return NRF_SUCCESS on success, otherwise an error code.
+ */
+static uint32_t add_keys_store_characteristic(ble_uuid_t * p_srv_uuid)
+{
+ ble_gatts_char_md_t char_md;
+ ble_gatts_attr_t attr_char_value;
+ ble_uuid_t char_uuid;
+ ble_gatts_attr_md_t attr_md;
+
+ memset(&char_md, 0x00, sizeof(char_md));
+
+ char_md.char_props.read = 1;
+ char_md.char_props.write = 1;
+
+ memset(&attr_md, 0x00, sizeof(attr_md));
+
+ BLE_GAP_CONN_SEC_MODE_SET_OPEN(&attr_md.read_perm);
+ BLE_GAP_CONN_SEC_MODE_SET_OPEN(&attr_md.write_perm);
+ attr_md.wr_auth = 1;
+ attr_md.vloc = BLE_GATTS_VLOC_USER;
+
+ memset(&attr_char_value, 0x00, sizeof(attr_char_value));
+
+ char_uuid.type = p_srv_uuid->type;
+ char_uuid.uuid = BLE_UUID_NCFGS_KEYS_STORE_CHAR;
+
+ attr_char_value.p_uuid = &char_uuid;
+ attr_char_value.p_attr_md = &attr_md;
+ attr_char_value.init_len = NCFGS_KEYS_MAX_LEN;
+ attr_char_value.init_offs = 0;
+ attr_char_value.max_len = NCFGS_KEYS_MAX_LEN;
+ attr_char_value.p_value = &m_ncfgs_data.keys_from_router.keys[0];
+
+ return sd_ble_gatts_characteristic_add(m_database.service_handle,
+ &char_md,
+ &attr_char_value,
+ &m_database.keys_store_handles);
+}
+
+
+/**@brief Function for adding the Control Point characteristic.
+ *
+ * @return NRF_SUCCESS on success, otherwise an error code.
+ */
+static uint32_t add_ip_cfg_cp_characteristic(ble_uuid_t * p_srv_uuid)
+{
+ ble_gatts_char_md_t char_md;
+ ble_gatts_attr_t attr_char_value;
+ ble_uuid_t char_uuid;
+ ble_gatts_attr_md_t attr_md;
+
+ memset(&char_md, 0x00, sizeof(char_md));
+
+ char_md.char_props.read = 1;
+ char_md.char_props.write = 1;
+
+ memset(&attr_md, 0x00, sizeof(attr_md));
+
+ BLE_GAP_CONN_SEC_MODE_SET_OPEN(&attr_md.read_perm);
+ BLE_GAP_CONN_SEC_MODE_SET_OPEN(&attr_md.write_perm);
+ attr_md.wr_auth = 1;
+ attr_md.vloc = BLE_GATTS_VLOC_USER;
+
+ memset(&attr_char_value, 0x00, sizeof(attr_char_value));
+
+ char_uuid.type = p_srv_uuid->type;
+ char_uuid.uuid = BLE_UUID_NCFGS_CTRLPT_CHAR;
+
+ attr_char_value.p_uuid = &char_uuid;
+ attr_char_value.p_attr_md = &attr_md;
+ attr_char_value.init_len = NCFGS_CTRLP_VALUE_LEN;
+ attr_char_value.init_offs = 0;
+ attr_char_value.max_len = NCFGS_CTRLP_VALUE_LEN;
+ attr_char_value.p_value = &m_ctrlp_value_buffer[0];
+
+ return sd_ble_gatts_characteristic_add(m_database.service_handle,
+ &char_md,
+ &attr_char_value,
+ &m_database.ctrlp_handles);
+}
+
+
+/**@brief Function for creating the GATT database.
+ *
+ * @return NRF_SUCCESS on success, otherwise an error code.
+ */
+static uint32_t ble_ncfgs_create_database(void)
+{
+ uint32_t err_code = NRF_SUCCESS;
+
+ // Add service.
+ ble_uuid_t service_uuid;
+
+ const ble_uuid128_t base_uuid128 =
+ {
+ {
+ 0x73, 0x3E, 0x2D, 0x02, 0xB7, 0x6B, 0xBE, 0xBE, \
+ 0xE5, 0x4F, 0x40, 0x8F, 0x00, 0x00, 0x20, 0x54
+ }
+ };
+
+ service_uuid.uuid = BLE_UUID_NODE_CFG_SERVICE;
+
+ err_code = sd_ble_uuid_vs_add(&base_uuid128, &(service_uuid.type));
+ if (err_code != NRF_SUCCESS)
+ {
+ return err_code;
+ }
+
+ err_code = sd_ble_gatts_service_add(BLE_GATTS_SRVC_TYPE_PRIMARY, \
+ &service_uuid, \
+ &m_database.service_handle);
+ if (err_code != NRF_SUCCESS)
+ {
+ return err_code;
+ }
+ err_code = add_ssid_characteristic(&service_uuid);
+ if (err_code != NRF_SUCCESS)
+ {
+ return err_code;
+ }
+ err_code = add_keys_store_characteristic(&service_uuid);
+ if (err_code != NRF_SUCCESS)
+ {
+ return err_code;
+ }
+ err_code = add_ip_cfg_cp_characteristic(&service_uuid);
+ if (err_code != NRF_SUCCESS)
+ {
+ return err_code;
+ }
+ return err_code;
+}
+
+
+uint32_t ble_ncfgs_init(ble_ncfgs_evt_handler_t ble_ncfgs_cb)
+{
+ NCFGS_ENTRY();
+ uint32_t err_code;
+ memset(&m_ncfgs_data, 0x00, sizeof(m_ncfgs_data));
+
+ m_app_evt_handler = ble_ncfgs_cb;
+
+ err_code = ble_ncfgs_create_database();
+ NCFGS_EXIT();
+ return err_code;
+}
+
+
+/**@brief Function for decoding the Control Point characteristic value.
+ *
+ * @return NRF_SUCCESS on success, otherwise an error code.
+ */
+static uint32_t ctrlp_value_decode(const ble_evt_t * p_ble_evt)
+{
+ uint16_t wr_req_value_len = \
+ p_ble_evt->evt.gatts_evt.params.authorize_request.request.write.len;
+
+ memcpy(m_ctrlp_value_buffer, \
+ p_ble_evt->evt.gatts_evt.params.authorize_request.request.write.data, \
+ wr_req_value_len);
+
+ m_ncfgs_data.ctrlp_value.opcode = \
+ (ble_ncfgs_opcode_t)m_ctrlp_value_buffer[0];
+ memcpy((void *)&m_ncfgs_data.ctrlp_value.delay_sec, \
+ &m_ctrlp_value_buffer[NCFGS_CTRLP_OPCODE_LEN], \
+ sizeof(uint32_t));
+ m_ncfgs_data.ctrlp_value.delay_sec = \
+ HTONL(m_ncfgs_data.ctrlp_value.delay_sec);
+ memcpy((void *)&m_ncfgs_data.ctrlp_value.duration_sec, \
+ &m_ctrlp_value_buffer[NCFGS_CTRLP_OPCODE_LEN+NCFGS_CTRLP_DELAY_LEN], \
+ sizeof(uint32_t));
+ m_ncfgs_data.ctrlp_value.duration_sec = \
+ HTONL(m_ncfgs_data.ctrlp_value.duration_sec);
+ m_ncfgs_data.ctrlp_value.state_on_failure = \
+ (state_on_failure_t)m_ctrlp_value_buffer[NCFGS_CTRLP_OPCODE_LEN+ \
+ NCFGS_CTRLP_DELAY_LEN+ \
+ NCFGS_CTRLP_DURATION_LEN];
+
+ if ((m_ncfgs_data.ctrlp_value.state_on_failure != NCFGS_SOF_NO_CHANGE) && \
+ (m_ncfgs_data.ctrlp_value.state_on_failure != NCFGS_SOF_PWR_OFF) && \
+ (m_ncfgs_data.ctrlp_value.state_on_failure != NCFGS_SOF_CONFIG_MODE))
+ {
+ return NRF_ERROR_INVALID_DATA;
+ }
+
+ uint16_t id_data_len = wr_req_value_len - NCFGS_CTRLP_ALL_BUT_ID_DATA_LEN;
+ if (id_data_len != 0)
+ {
+ m_ncfgs_data.id_data.identity_data_len = id_data_len;
+
+ memcpy(m_ncfgs_data.id_data.identity_data, \
+ &m_ctrlp_value_buffer[NCFGS_CTRLP_ALL_BUT_ID_DATA_LEN], \
+ id_data_len);
+ }
+
+ return NRF_SUCCESS;
+}
+
+
+void ble_ncfgs_ble_evt_handler(const ble_evt_t * p_ble_evt)
+{
+ switch (p_ble_evt->header.evt_id)
+ {
+ case BLE_GATTS_EVT_RW_AUTHORIZE_REQUEST:
+ {
+ if (p_ble_evt->evt.gatts_evt.params.authorize_request.request.write.op == \
+ BLE_GATTS_OP_WRITE_REQ)
+ {
+ uint16_t wr_req_handle = \
+ p_ble_evt->evt.gatts_evt.params.authorize_request.request.write.handle;
+ uint16_t wr_req_value_len = \
+ p_ble_evt->evt.gatts_evt.params.authorize_request.request.write.len;
+
+ ble_gatts_rw_authorize_reply_params_t reply_params;
+ memset(&reply_params, 0x00, sizeof(reply_params));
+
+ reply_params.type = BLE_GATTS_AUTHORIZE_TYPE_WRITE;
+ reply_params.params.write.update = 1;
+ reply_params.params.write.offset = p_ble_evt->evt.gatts_evt.params.authorize_request.request.write.offset;
+ reply_params.params.write.len = p_ble_evt->evt.gatts_evt.params.authorize_request.request.write.len;
+ reply_params.params.write.p_data = p_ble_evt->evt.gatts_evt.params.authorize_request.request.write.data;
+
+ if (wr_req_handle == m_database.ssid_handles.value_handle)
+ {
+ NCFGS_TRC("> wr_req: ssid_handle");
+
+ if ((wr_req_value_len > NCFGS_SSID_MAX_LEN) || \
+ (wr_req_value_len < NCFGS_SSID_MIN_LEN))
+ {
+ reply_params.params.write.gatt_status = \
+ BLE_GATT_STATUS_ATTERR_INVALID_ATT_VAL_LENGTH;
+ }
+ else
+ {
+ m_ncfgs_data.ssid_from_router.ssid_len = wr_req_value_len;
+ m_service_state |= NCFGS_STATE_SSID_WRITTEN;
+
+ reply_params.params.write.gatt_status = BLE_GATT_STATUS_SUCCESS;
+ }
+
+ UNUSED_RETURN_VALUE( \
+ sd_ble_gatts_rw_authorize_reply(p_ble_evt->evt.gap_evt.conn_handle, \
+ &reply_params));
+ NCFGS_TRC("< wr_req: ssid_handle");
+ return;
+ }
+
+ else if (wr_req_handle == m_database.keys_store_handles.value_handle)
+ {
+ NCFGS_TRC("> wr_req: keys_store_handle");
+
+ if (wr_req_value_len > NCFGS_KEYS_MAX_LEN)
+ {
+ reply_params.params.write.gatt_status = \
+ BLE_GATT_STATUS_ATTERR_INVALID_ATT_VAL_LENGTH;
+ }
+ else
+ {
+ m_ncfgs_data.keys_from_router.keys_len = wr_req_value_len;
+ m_service_state |= NCFGS_STATE_KEYS_STORE_WRITTEN;
+ reply_params.params.write.gatt_status = BLE_GATT_STATUS_SUCCESS;
+ }
+
+ UNUSED_RETURN_VALUE( \
+ sd_ble_gatts_rw_authorize_reply(p_ble_evt->evt.gap_evt.conn_handle, \
+ &reply_params));
+ NCFGS_TRC("< wr_req: keys_store_handle");
+ return;
+ }
+
+ else if (wr_req_handle == m_database.ctrlp_handles.value_handle)
+ {
+ NCFGS_TRC("> wr_req: ctrlp_handle");
+
+ bool notify_app = false;
+
+ if ((wr_req_value_len > NCFGS_CTRLP_VALUE_LEN) || \
+ (wr_req_value_len < NCFGS_CTRLP_ALL_BUT_ID_DATA_LEN))
+ {
+ reply_params.params.write.gatt_status = \
+ BLE_GATT_STATUS_ATTERR_INVALID_ATT_VAL_LENGTH;
+ }
+ else
+ {
+ ble_ncfgs_opcode_t opcode_in = (ble_ncfgs_opcode_t) \
+ p_ble_evt->evt.gatts_evt.params.authorize_request.request.write.data[0];
+
+ reply_params.params.write.gatt_status = BLE_GATT_STATUS_SUCCESS;
+
+ if ((opcode_in != NCFGS_OPCODE_GOTO_JOINING_MODE) && \
+ (opcode_in != NCFGS_OPCODE_GOTO_CONFIG_MODE) && \
+ (opcode_in != NCFGS_OPCODE_GOTO_IDENTITY_MODE))
+ {
+ reply_params.params.write.gatt_status = APP_GATTERR_UNKNOWN_OPCODE;
+ }
+
+ if (opcode_in == NCFGS_OPCODE_GOTO_JOINING_MODE)
+ {
+ if (!((m_service_state & NCFGS_STATE_SSID_WRITTEN) && \
+ (m_service_state & NCFGS_STATE_KEYS_STORE_WRITTEN)))
+ {
+ reply_params.params.write.gatt_status = APP_GATTERR_NOT_CONFIGURED;
+ }
+ }
+
+ if (reply_params.params.write.gatt_status == BLE_GATT_STATUS_SUCCESS)
+ {
+ uint32_t err_code = ctrlp_value_decode(p_ble_evt);
+ if (err_code != NRF_SUCCESS)
+ {
+ reply_params.params.write.gatt_status = \
+ APP_GATTERR_INVALID_ATTR_VALUE;
+ }
+ else
+ {
+ notify_app = true;
+ }
+ }
+ }
+
+ UNUSED_RETURN_VALUE(sd_ble_gatts_rw_authorize_reply(
+ p_ble_evt->evt.gap_evt.conn_handle,
+ &reply_params));
+
+ if (notify_app == true)
+ {
+ NCFGS_TRC("> do notify parent");
+
+ m_app_evt_handler(&m_ncfgs_data);
+
+ NCFGS_TRC("< do notify parent");
+ }
+ NCFGS_TRC("< wr_req: ctrlp_handle");
+ }
+ else
+ {
+ // Invalid handle.
+ reply_params.params.write.gatt_status = BLE_GATT_STATUS_ATTERR_INVALID_HANDLE;
+ UNUSED_RETURN_VALUE(sd_ble_gatts_rw_authorize_reply(
+ p_ble_evt->evt.gap_evt.conn_handle, &reply_params));
+ }
+ }
+
+ break;
+ }
+
+ case BLE_GAP_EVT_DATA_LENGTH_UPDATE_REQUEST:
+ {
+ ble_gap_data_length_params_t dl_params;
+
+ // Clearing the struct will effectively set members to @ref BLE_GAP_DATA_LENGTH_AUTO.
+ memset(&dl_params, 0, sizeof(ble_gap_data_length_params_t));
+ UNUSED_RETURN_VALUE(sd_ble_gap_data_length_update(p_ble_evt->evt.gap_evt.conn_handle, &dl_params, NULL));
+ break;
+ }
+
+ case BLE_GAP_EVT_PHY_UPDATE_REQUEST:
+ {
+ NCFGS_TRC("> PHY update request.");
+
+ ble_gap_phys_t const phys =
+ {
+ .rx_phys = BLE_GAP_PHY_AUTO,
+ .tx_phys = BLE_GAP_PHY_AUTO,
+ };
+
+ UNUSED_RETURN_VALUE(sd_ble_gap_phy_update(p_ble_evt->evt.gap_evt.conn_handle, &phys);
+
+ NCFGS_TRC("< PHY update request.");
+ break;
+ }
+
+ default:
+ {
+ break;
+ }
+ }
+}
+
+#endif // COMMISSIONING_ENABLED
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/medium/ble_ncfgs/ble_ncfgs.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/medium/ble_ncfgs/ble_ncfgs.h
new file mode 100644
index 0000000..b59495d
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/medium/ble_ncfgs/ble_ncfgs.h
@@ -0,0 +1,194 @@
+/**
+ * Copyright (c) 2015 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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
+ *
+ * @defgroup ble_ncfgs Node Configuration Service
+ * @{
+ * @ingroup iot_sdk_common
+ * @brief Node Configuration Service module.
+ *
+ * @details The Node Configuration Service allows configuration of the node during commissioning.
+ * During initialization it adds the Node Configuration Service and the corresponding
+ * characteristics to the BLE GATT database. It decodes and checks the received values
+ * and then passes them to the parent module.
+ */
+
+#ifndef BLE_NODE_CFG_H__
+#define BLE_NODE_CFG_H__
+
+#include <stdint.h>
+#include "ble.h"
+#include "app_util.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define BLE_UUID_NODE_CFG_SERVICE 0x7799
+#define BLE_UUID_NCFGS_SSID_CHAR 0x77A9
+#define BLE_UUID_NCFGS_KEYS_STORE_CHAR 0x77B9
+#define BLE_UUID_NCFGS_CTRLPT_CHAR 0x77C9
+
+#define APP_GATTERR_NOT_CONFIGURED BLE_GATT_STATUS_ATTERR_APP_BEGIN + 1 /**< ATT Error: Node configuration incomplete. */
+#define APP_GATTERR_UNKNOWN_OPCODE BLE_GATT_STATUS_ATTERR_APP_BEGIN + 2 /**< ATT Error: Unknown opcode. */
+#define APP_GATTERR_INVALID_ATTR_VALUE BLE_GATT_STATUS_ATTERR_APP_BEGIN + 3 /**< ATT Error: Invalid attribute value. */
+
+#define NCFGS_SSID_MIN_LEN 6 /**< SSID minimum length. */
+#define NCFGS_SSID_MAX_LEN 16 /**< SSID maximum length. */
+#define NCFGS_KEYS_MAX_LEN 16 /**< Keys maximum length. */
+#define NCFGS_IDENTITY_DATA_MAX_LEN 8 /**< Identity data maximum length. */
+
+#define NCFGS_CTRLP_OPCODE_LEN 1 /**< Ctrlp: Opcode value length. */
+#define NCFGS_CTRLP_DELAY_LEN 4 /**< Ctrlp: Length of action delay value. */
+#define NCFGS_CTRLP_DURATION_LEN 4 /**< Ctrlp: Length of next mode duration value. */
+#define NCFGS_CTRLP_STATE_ON_FAILURE_LEN 1 /**< Ctrlp: Length of state-on-failure value. */
+
+#define NCFGS_CTRLP_ALL_BUT_ID_DATA_LEN (NCFGS_CTRLP_OPCODE_LEN + \
+ NCFGS_CTRLP_DELAY_LEN + \
+ NCFGS_CTRLP_DURATION_LEN + \
+ NCFGS_CTRLP_STATE_ON_FAILURE_LEN) /**< Ctrlp: Total length of all values except identity data. */
+#define NCFGS_CTRLP_VALUE_LEN (NCFGS_CTRLP_OPCODE_LEN + \
+ NCFGS_CTRLP_DELAY_LEN + \
+ NCFGS_CTRLP_DURATION_LEN + \
+ NCFGS_CTRLP_STATE_ON_FAILURE_LEN + \
+ NCFGS_IDENTITY_DATA_MAX_LEN) /**< Ctrlp: Total length of all values. */
+
+#define HTONL(val) ((((uint32_t) (val) & 0xff000000) >> 24) | \
+ (((uint32_t) (val) & 0x00ff0000) >> 8) | \
+ (((uint32_t) (val) & 0x0000ff00) << 8) | \
+ (((uint32_t) (val) & 0x000000ff) << 24))
+
+/**@brief Node Configuration Service control point opcode values. */
+typedef enum
+{
+ NCFGS_OPCODE_GOTO_JOINING_MODE = 0x01,
+ NCFGS_OPCODE_GOTO_CONFIG_MODE = 0x02,
+ NCFGS_OPCODE_GOTO_IDENTITY_MODE = 0x03
+} ble_ncfgs_opcode_t;
+
+/**@brief Node Configuration Service configuration states. */
+typedef enum
+{
+ NCFGS_STATE_IDLE = 0x00,
+ NCFGS_STATE_SSID_WRITTEN = 0x01,
+ NCFGS_STATE_KEYS_STORE_WRITTEN = 0x02
+} ble_ncfgs_state_t;
+
+/**@brief Node Configuration Service state-on-failure values. */
+typedef enum
+{
+ NCFGS_SOF_NO_CHANGE = 0x00,
+ NCFGS_SOF_PWR_OFF = 0x01,
+ NCFGS_SOF_CONFIG_MODE = 0x02
+} state_on_failure_t;
+
+/**@brief Structure for storing keys received from the peer. */
+typedef struct __attribute__ ((__packed__))
+{
+ uint8_t keys_len;
+ uint8_t keys[NCFGS_KEYS_MAX_LEN]; // Keys received from the router.
+} keys_store_t;
+
+/**@brief Structure for storing the SSID received from the peer. */
+typedef struct __attribute__ ((__packed__))
+{
+ uint8_t ssid_len;
+ uint8_t ssid[NCFGS_SSID_MAX_LEN]; // SSID received from the router.
+} ssid_store_t;
+
+/**@brief Structure for storing the identity data from the peer. */
+typedef struct __attribute__ ((__packed__))
+{
+ uint8_t identity_data_len;
+ uint8_t identity_data[NCFGS_IDENTITY_DATA_MAX_LEN]; // Custom node identifier data.
+} id_data_store_t;
+
+/**@brief Structure for control point value. */
+typedef struct __attribute__ ((__packed__))
+{
+ ble_ncfgs_opcode_t opcode; // Mode to start.
+ uint32_t delay_sec; // Delay before entering >Opcode< mode.
+ uint32_t duration_sec; // General timeout for >Opcode< mode.
+ state_on_failure_t state_on_failure; // Mode to enter if >Opcode< mode fails (times out).
+} ble_ncfgs_ctrlp_value_t;
+
+/**@brief Structure for storing Node Configuration Service characteristic values. */
+typedef struct __attribute__ ((__packed__))
+{
+ ble_ncfgs_ctrlp_value_t ctrlp_value;
+ ssid_store_t ssid_from_router; // SSID received from the peer.
+ keys_store_t keys_from_router; // Keys received from the peer.
+ id_data_store_t id_data; // Identity data received from the peer.
+} ble_ncfgs_data_t;
+
+/**@brief Function for handling BLE events.
+ *
+ * @details This function must be called from the BLE stack event dispatcher
+ * to handle BLE events that are relevant for the Node Configuration Service module.
+ * It propagates an event to the parent layer if the Control Point characteristic
+ * was successfully written.
+ *
+ * @param[in] p_ble_evt BLE stack event.
+ */
+void ble_ncfgs_ble_evt_handler(const ble_evt_t * p_ble_evt);
+
+/**@brief Node Configuration Service event handler type. */
+typedef void (*ble_ncfgs_evt_handler_t) (ble_ncfgs_data_t * ncfgs_data);
+
+/**@brief Function for initializing the Node Configuration Service module.
+ *
+ * @details Interface for the Commissioning module to create a GATT database to
+ * allow for node configuration.
+ *
+ * @param[in] ble_ncfgs_cb Function to be called in case of an error.
+ *
+ * @retval NRF_SUCCESS If initialization was successful. Otherwise, a propagated
+ * error code is returned.
+ *
+ */
+uint32_t ble_ncfgs_init(ble_ncfgs_evt_handler_t ble_ncfgs_cb);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // BLE_NODE_CFG_H__
+
+/** @} */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/medium/commissioning/commissioning.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/medium/commissioning/commissioning.c
new file mode 100644
index 0000000..4ea6884
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/medium/commissioning/commissioning.c
@@ -0,0 +1,1077 @@
+/**
+ * Copyright (c) 2015-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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#ifdef COMMISSIONING_ENABLED
+
+#include <string.h>
+#include "boards.h"
+#include "ble_hci.h"
+#include "nrf_soc.h"
+#include "app_error.h"
+#include "fds.h"
+#include "ble_advdata.h"
+#include "commissioning.h"
+#include "nordic_common.h"
+#include "ble_srv_common.h"
+#include "sdk_config.h"
+
+#define MINIMUM_ACTION_DELAY 2 /**< Delay before executing an action after the control point was written (in seconds). */
+
+#define SEC_PARAM_BOND 0 /**< Perform bonding. */
+#define SEC_PARAM_MITM 1 /**< Man In The Middle protection required (applicable when display module is detected). */
+#define SEC_PARAM_IO_CAPABILITIES BLE_GAP_IO_CAPS_KEYBOARD_ONLY /**< Display I/O capabilities. */
+#define SEC_PARAM_OOB 0 /**< Out Of Band data not available. */
+#define SEC_PARAM_MIN_KEY_SIZE 7 /**< Minimum encryption key size. */
+#define SEC_PARAM_MAX_KEY_SIZE 16 /**< Maximum encryption key size. */
+
+#define COMM_FDS_FILE_ID 0xCAFE /**< The ID of the file that the record belongs to. */
+#define COMM_FDS_RECORD_KEY 0xBEAF /**< The record key of FDS record that keeps node settings. */
+
+#define NUMBER_OF_COMMISSIONING_TIMERS 4
+#define TIMER_INDEX_DELAYED_ACTION 0
+#define TIMER_INDEX_CONFIG_MODE 1
+#define TIMER_INDEX_JOINING_MODE 2
+#define TIMER_INDEX_IDENTITY_MODE 3
+
+#define SEC_TO_MILLISEC(PARAM) (PARAM * 1000)
+
+static commissioning_settings_t m_node_settings; /**< All node settings as configured through the Node Configuration Service. */
+static commissioning_evt_handler_t m_commissioning_evt_handler; /**< Commissioning event handler of the parent layer. */
+static bool m_power_off_on_failure = false; /**< Power off on failure setting from the last NCFGS event. */
+static commissioning_timer_t m_commissioning_timers[NUMBER_OF_COMMISSIONING_TIMERS];
+
+static ipv6_medium_ble_gap_params_t m_config_mode_gap_params; /**< Advertising parameters in Config mode. */
+static ipv6_medium_ble_adv_params_t m_config_mode_adv_params; /**< GAP parameters in Config mode. */
+
+static ipv6_medium_ble_gap_params_t m_joining_mode_gap_params; /**< Advertising parameters in Joining mode. */
+static ipv6_medium_ble_adv_params_t m_joining_mode_adv_params; /**< GAP parameters in Joining mode. */
+
+static ble_uuid_t m_config_mode_adv_uuids[] = \
+ {
+ {BLE_UUID_NODE_CFG_SERVICE, \
+ BLE_UUID_TYPE_VENDOR_BEGIN}
+ }; /**< Config mode: List of available service UUIDs in advertisement data. */
+
+static ble_uuid_t m_joining_mode_adv_uuids[] = \
+ {
+ {BLE_UUID_IPSP_SERVICE, BLE_UUID_TYPE_BLE}
+ }; /**< Joining mode: List of available service UUIDs in advertisement data. */
+
+static uint16_t m_conn_handle = BLE_CONN_HANDLE_INVALID; /**< Handle of the active connection. */
+static uint8_t m_current_mode = NODE_MODE_NONE; /**< Current mode value. */
+static uint8_t m_next_mode = NODE_MODE_NONE; /**< Value of the mode the node will enter when the timeout handler of m_delayed_action_timer is triggered. */
+
+#if (FDS_ENABLED == 1)
+static fds_record_desc_t m_fds_record_desc; /**< Descriptor of FDS record. */
+#endif
+
+#define COMM_ENABLE_LOGS 1 /**< Set to 0 to disable debug trace in the module. */
+
+#if COMMISSIONING_CONFIG_LOG_ENABLED
+
+#define NRF_LOG_MODULE_NAME commissioning
+
+#define NRF_LOG_LEVEL COMMISSIONING_CONFIG_LOG_LEVEL
+#define NRF_LOG_INFO_COLOR COMMISSIONING_CONFIG_INFO_COLOR
+#define NRF_LOG_DEBUG_COLOR COMMISSIONING_CONFIG_DEBUG_COLOR
+
+#include "nrf_log.h"
+NRF_LOG_MODULE_REGISTER();
+
+#define COMM_TRC NRF_LOG_DEBUG /**< Used for getting trace of execution in the module. */
+#define COMM_ERR NRF_LOG_ERROR /**< Used for logging errors in the module. */
+#define COMM_DUMP NRF_LOG_HEXDUMP_DEBUG /**< Used for dumping octet information to get details of bond information etc. */
+
+#define COMM_ENTRY() COMM_TRC(">> %s", __func__)
+#define COMM_EXIT() COMM_TRC("<< %s", __func__)
+
+#else // COMMISSIONING_CONFIG_LOG_ENABLED
+
+#define COMM_TRC(...) /**< Disables traces. */
+#define COMM_DUMP(...) /**< Disables dumping of octet streams. */
+#define COMM_ERR(...) /**< Disables error logs. */
+
+#define COMM_ENTRY(...)
+#define COMM_EXIT(...)
+
+#endif // COMMISSIONING_CONFIG_LOG_ENABLED
+
+
+/**@brief Function for validating all node settings.
+ */
+static bool settings_are_valid()
+{
+ uint8_t tmp = m_node_settings.poweron_mode;
+ if (tmp == 0xFF)
+ {
+ return false;
+ }
+ else
+ {
+ return true;
+ }
+}
+
+#if (FDS_ENABLED == 1)
+/**@brief Function for updating the node settings in persistent memory.
+ */
+static uint32_t persistent_settings_update(void)
+{
+ uint32_t err_code;
+
+ fds_find_token_t token;
+ memset(&token, 0, sizeof(token));
+
+ fds_record_t record;
+ memset(&record, 0, sizeof(record));
+
+ record.file_id = COMM_FDS_FILE_ID;
+ record.key = COMM_FDS_RECORD_KEY;
+ record.data.p_data = &m_node_settings;
+ record.data.length_words = ALIGN_NUM(4, sizeof(commissioning_settings_t))/sizeof(uint32_t);
+
+ // Try to find FDS record with node settings.
+ err_code = fds_record_find(COMM_FDS_FILE_ID, COMM_FDS_RECORD_KEY, &m_fds_record_desc, &token);
+ if (err_code == FDS_SUCCESS)
+ {
+ err_code = fds_record_update(&m_fds_record_desc, &record);
+ }
+ else
+ {
+
+ err_code = fds_record_write(&m_fds_record_desc, &record);
+ }
+
+ if (err_code == FDS_ERR_NO_SPACE_IN_FLASH)
+ {
+ // Run garbage collector to reclaim the flash space that is occupied by records that have been deleted,
+ // or that failed to be completely written due to, for example, a power loss.
+ err_code = fds_gc();
+ }
+
+ return err_code;
+}
+
+
+/**@brief Function for loading node settings from the persistent memory.
+ */
+static void persistent_settings_load(void)
+{
+ uint32_t err_code = FDS_SUCCESS;
+ fds_flash_record_t record;
+
+ fds_find_token_t token;
+ memset(&token, 0, sizeof(token));
+
+ // Try to find FDS record with node settings.
+ err_code = fds_record_find(COMM_FDS_FILE_ID, COMM_FDS_RECORD_KEY, &m_fds_record_desc, &token);
+ if (err_code == FDS_SUCCESS)
+ {
+ err_code = fds_record_open(&m_fds_record_desc, &record);
+ if (err_code == FDS_SUCCESS)
+ {
+ if (record.p_data)
+ {
+ memcpy(&m_node_settings, record.p_data, sizeof(m_node_settings));
+ }
+ }
+ }
+}
+
+
+/**@brief Function for clearing node settings from the persistent memory.
+ */
+static void persistent_settings_clear(void)
+{
+ fds_record_delete(&m_fds_record_desc);
+}
+
+/**@brief Function for handling File Data Storage events.
+ */
+static void persistent_settings_cb(fds_evt_t const * p_evt)
+{
+ if (p_evt->id == FDS_EVT_GC)
+ {
+ if (settings_are_valid())
+ {
+ persistent_settings_update();
+ }
+ }
+}
+
+
+/**@brief Function for initializing the File Data Storage module.
+ */
+static uint32_t persistent_settings_init(void)
+{
+ uint32_t err_code;
+
+ err_code = fds_init();
+ if (err_code == FDS_SUCCESS)
+ {
+ err_code = fds_register(persistent_settings_cb);
+ }
+
+ return err_code;
+}
+#endif
+
+
+/**@brief Function for setting advertisement parameters in Config mode.
+ */
+static void config_mode_adv_params_set(void)
+{
+ COMM_ENTRY();
+ memset(&m_config_mode_adv_params, 0x00, sizeof(m_config_mode_adv_params));
+
+ m_config_mode_adv_params.advdata.name_type = BLE_ADVDATA_FULL_NAME;
+ m_config_mode_adv_params.advdata.include_appearance = false;
+ m_config_mode_adv_params.advdata.flags = \
+ BLE_GAP_ADV_FLAGS_LE_ONLY_GENERAL_DISC_MODE;
+ m_config_mode_adv_params.advdata.uuids_complete.uuid_cnt = \
+ sizeof(m_config_mode_adv_uuids) / sizeof(m_config_mode_adv_uuids[0]);
+ m_config_mode_adv_params.advdata.uuids_complete.p_uuids = m_config_mode_adv_uuids;
+ m_config_mode_adv_params.advdata.p_manuf_specific_data = NULL;
+
+ if (m_node_settings.id_data_store.identity_data_len > 0)
+ {
+ m_config_mode_adv_params.sr_man_specific_data.data.size = \
+ m_node_settings.id_data_store.identity_data_len;
+ m_config_mode_adv_params.sr_man_specific_data.data.p_data = \
+ m_node_settings.id_data_store.identity_data;
+ m_config_mode_adv_params.sr_man_specific_data.company_identifier = \
+ COMPANY_IDENTIFIER;
+ m_config_mode_adv_params.srdata.p_manuf_specific_data = \
+ &m_config_mode_adv_params.sr_man_specific_data;
+ }
+ else
+ {
+ m_config_mode_adv_params.srdata.p_manuf_specific_data = NULL;
+ }
+
+ m_config_mode_adv_params.advparams.properties.type = BLE_GAP_ADV_TYPE_CONNECTABLE_SCANNABLE_UNDIRECTED;
+ m_config_mode_adv_params.advparams.p_peer_addr = NULL; // Undirected advertisement.
+ m_config_mode_adv_params.advparams.filter_policy = BLE_GAP_ADV_FP_ANY;
+ m_config_mode_adv_params.advparams.interval = CONFIG_MODE_ADV_ADV_INTERVAL;
+ m_config_mode_adv_params.advparams.duration = CONFIG_MODE_ADV_TIMEOUT;
+
+ COMM_EXIT();
+}
+
+
+/**@brief Function for setting GAP parameters in Config mode.
+ */
+static void config_mode_gap_params_set(void)
+{
+ COMM_ENTRY();
+
+ memset(&m_config_mode_gap_params, 0x00, sizeof(m_config_mode_gap_params));
+
+ BLE_GAP_CONN_SEC_MODE_SET_OPEN(&m_config_mode_gap_params.sec_mode);
+
+ m_config_mode_gap_params.p_dev_name = (const uint8_t *)CONFIG_MODE_DEVICE_NAME;
+ m_config_mode_gap_params.dev_name_len = strlen(CONFIG_MODE_DEVICE_NAME);
+
+ m_config_mode_gap_params.gap_conn_params.min_conn_interval = \
+ (uint16_t)CONFIG_MODE_MIN_CONN_INTERVAL;
+ m_config_mode_gap_params.gap_conn_params.max_conn_interval = \
+ (uint16_t)CONFIG_MODE_MAX_CONN_INTERVAL;
+ m_config_mode_gap_params.gap_conn_params.slave_latency = CONFIG_MODE_SLAVE_LATENCY;
+ m_config_mode_gap_params.gap_conn_params.conn_sup_timeout = CONFIG_MODE_CONN_SUP_TIMEOUT;
+
+ COMM_EXIT();
+}
+
+
+/**@brief Function for setting advertisement parameters in Joining mode.
+ */
+static void joining_mode_adv_params_set(void)
+{
+ COMM_ENTRY();
+
+ memset(&m_joining_mode_adv_params, 0x00, sizeof(m_joining_mode_adv_params));
+
+ if (m_node_settings.ssid_store.ssid_len > 0)
+ {
+ m_joining_mode_adv_params.adv_man_specific_data.data.size = \
+ m_node_settings.ssid_store.ssid_len;
+ m_joining_mode_adv_params.adv_man_specific_data.data.p_data = \
+ m_node_settings.ssid_store.ssid;
+ m_joining_mode_adv_params.adv_man_specific_data.company_identifier = \
+ COMPANY_IDENTIFIER;
+ }
+
+ m_joining_mode_adv_params.advdata.name_type = BLE_ADVDATA_NO_NAME;
+ m_joining_mode_adv_params.advdata.include_appearance = false;
+ m_joining_mode_adv_params.advdata.flags = \
+ BLE_GAP_ADV_FLAG_BR_EDR_NOT_SUPPORTED;
+ m_joining_mode_adv_params.advdata.uuids_complete.uuid_cnt = \
+ sizeof(m_joining_mode_adv_uuids) / sizeof(m_joining_mode_adv_uuids[0]);
+ m_joining_mode_adv_params.advdata.uuids_complete.p_uuids = m_joining_mode_adv_uuids;
+ if (m_node_settings.ssid_store.ssid_len > 0)
+ {
+ m_joining_mode_adv_params.advdata.p_manuf_specific_data = \
+ &m_joining_mode_adv_params.adv_man_specific_data;
+ }
+ else
+ {
+ m_joining_mode_adv_params.advdata.p_manuf_specific_data = NULL;
+ }
+
+ if (m_node_settings.id_data_store.identity_data_len > 0)
+ {
+ m_joining_mode_adv_params.sr_man_specific_data.data.size = \
+ m_node_settings.id_data_store.identity_data_len;
+ m_joining_mode_adv_params.sr_man_specific_data.data.p_data = \
+ m_node_settings.id_data_store.identity_data;
+ m_joining_mode_adv_params.sr_man_specific_data.company_identifier = \
+ COMPANY_IDENTIFIER;
+ m_joining_mode_adv_params.srdata.p_manuf_specific_data = \
+ &m_joining_mode_adv_params.sr_man_specific_data;
+ }
+ else
+ {
+ m_joining_mode_adv_params.srdata.p_manuf_specific_data = NULL;
+ }
+
+ m_joining_mode_adv_params.advparams.properties.type = BLE_GAP_ADV_TYPE_CONNECTABLE_SCANNABLE_UNDIRECTED;
+ m_joining_mode_adv_params.advparams.p_peer_addr = NULL; // Undirected advertisement.
+ m_joining_mode_adv_params.advparams.filter_policy = BLE_GAP_ADV_FP_ANY;
+ m_joining_mode_adv_params.advparams.interval = APP_ADV_ADV_INTERVAL;
+ m_joining_mode_adv_params.advparams.duration = APP_ADV_DURATION;
+
+ COMM_EXIT();
+}
+
+
+/**@brief Function for setting GAP parameters in Joining mode.
+ */
+static void joining_mode_gap_params_set(void)
+{
+ COMM_ENTRY();
+
+ memset(&m_joining_mode_gap_params, 0x00, sizeof(m_joining_mode_gap_params));
+
+ BLE_GAP_CONN_SEC_MODE_SET_OPEN(&m_joining_mode_gap_params.sec_mode);
+
+ m_joining_mode_gap_params.appearance = BLE_APPEARANCE_UNKNOWN;
+
+ m_joining_mode_gap_params.p_dev_name = (const uint8_t *)DEVICE_NAME;
+ m_joining_mode_gap_params.dev_name_len = strlen(DEVICE_NAME);
+
+ m_joining_mode_gap_params.gap_conn_params.min_conn_interval = \
+ (uint16_t)JOINING_MODE_MIN_CONN_INTERVAL;
+ m_joining_mode_gap_params.gap_conn_params.max_conn_interval = \
+ (uint16_t)JOINING_MODE_MAX_CONN_INTERVAL;
+ m_joining_mode_gap_params.gap_conn_params.slave_latency = JOINING_MODE_SLAVE_LATENCY;
+ m_joining_mode_gap_params.gap_conn_params.conn_sup_timeout = JOINING_MODE_CONN_SUP_TIMEOUT;
+
+ COMM_EXIT();
+}
+
+
+/**@brief Function for starting a timer in the Commissioning module.
+ *
+ */
+static void commissioning_timer_start(uint8_t index, uint32_t timeout_sec)
+{
+ m_commissioning_timers[index].is_timer_running = true;
+ m_commissioning_timers[index].current_value_sec = timeout_sec;
+}
+
+
+/**@brief Function for stopping and re-setting a timer in the Commissioning module.
+ *
+ */
+static void commissioning_timer_stop_reset(uint8_t index)
+{
+ m_commissioning_timers[index].is_timer_running = false;
+ m_commissioning_timers[index].current_value_sec = 0x00;
+}
+
+
+void commissioning_node_mode_change(uint8_t new_mode)
+{
+ COMM_ENTRY();
+
+ commissioning_evt_t commissioning_evt;
+ memset(&commissioning_evt, 0x00, sizeof(commissioning_evt));
+ commissioning_evt.p_commissioning_settings = &m_node_settings;
+ commissioning_evt.power_off_enable_requested = m_power_off_on_failure;
+
+ commissioning_timer_stop_reset(TIMER_INDEX_DELAYED_ACTION);
+ commissioning_timer_stop_reset(TIMER_INDEX_CONFIG_MODE);
+ commissioning_timer_stop_reset(TIMER_INDEX_JOINING_MODE);
+
+ config_mode_gap_params_set();
+ config_mode_adv_params_set();
+ joining_mode_gap_params_set();
+ joining_mode_adv_params_set();
+
+ m_current_mode = new_mode;
+
+ switch (m_current_mode)
+ {
+ case NODE_MODE_CONFIG:
+ {
+ commissioning_evt.commissioning_evt_id = COMMISSIONING_EVT_CONFIG_MODE_ENTER;
+ m_commissioning_evt_handler(&commissioning_evt);
+
+ // Start Configuration mode timer.
+ COMM_TRC("Config mode timeout: %ld seconds", m_node_settings.config_mode_to);
+ commissioning_timer_start(TIMER_INDEX_CONFIG_MODE, m_node_settings.config_mode_to);
+
+ break;
+ }
+ case NODE_MODE_JOINING:
+ {
+ commissioning_evt.commissioning_evt_id = COMMISSIONING_EVT_JOINING_MODE_ENTER;
+ m_commissioning_evt_handler(&commissioning_evt);
+
+ // Start Joining mode timer.
+ COMM_TRC("Joining mode timeout: %ld seconds", m_node_settings.joining_mode_to);
+ commissioning_timer_start(TIMER_INDEX_JOINING_MODE, m_node_settings.joining_mode_to);
+
+ break;
+ }
+ case NODE_MODE_IDENTITY:
+ {
+ commissioning_evt.commissioning_evt_id = COMMISSIONING_EVT_IDENTITY_MODE_ENTER;
+ m_commissioning_evt_handler(&commissioning_evt);
+
+ // Start Identity mode timer.
+ COMM_TRC("Identity mode timeout: %ld seconds", m_node_settings.id_mode_to);
+ commissioning_timer_start(TIMER_INDEX_IDENTITY_MODE, m_node_settings.id_mode_to);
+
+ break;
+ }
+ default:
+ {
+ break;
+ }
+ }
+
+ COMM_EXIT();
+}
+
+
+/**@brief Function for handling the Delayed action timer timeout.
+ *
+ * @details This function will be called each time the delayed action timer expires.
+ *
+ */
+static void action_timeout_handler(void)
+{
+ COMM_ENTRY();
+
+ commissioning_node_mode_change(m_next_mode);
+
+ COMM_EXIT();
+}
+
+
+/**@brief Function for handling the Config mode timer timeout.
+ *
+ * @details This function will be called each time the Config mode timer expires.
+ *
+ */
+static void config_mode_timeout_handler(void)
+{
+ COMM_ENTRY();
+
+ switch (m_node_settings.config_mode_failure)
+ {
+ case NCFGS_SOF_NO_CHANGE:
+ // Fall-through.
+ case NCFGS_SOF_CONFIG_MODE:
+ {
+ commissioning_node_mode_change(NODE_MODE_CONFIG);
+
+ break;
+ }
+ case NCFGS_SOF_PWR_OFF:
+ {
+ LEDS_OFF(LEDS_MASK);
+ // The main timer in Config mode timed out, power off.
+ UNUSED_VARIABLE(sd_power_system_off());
+
+ break;
+ }
+ }
+
+ COMM_EXIT();
+}
+
+
+/**@brief Function for handling the Joining mode timer timeout.
+ *
+ * @details This function will be called each time the Joining mode timer expires.
+ *
+ */
+void joining_mode_timeout_handler(void)
+{
+ COMM_ENTRY();
+
+ switch (m_node_settings.joining_mode_failure)
+ {
+ case NCFGS_SOF_NO_CHANGE:
+ {
+ commissioning_node_mode_change(NODE_MODE_JOINING);
+ break;
+ }
+ case NCFGS_SOF_PWR_OFF:
+ {
+ LEDS_OFF(LEDS_MASK);
+
+ UNUSED_VARIABLE(sd_power_system_off());
+ break;
+ }
+ case NCFGS_SOF_CONFIG_MODE:
+ {
+ commissioning_node_mode_change(NODE_MODE_CONFIG);
+ break;
+ }
+ }
+
+ COMM_EXIT();
+}
+
+
+/**@brief Function for handling the Identity mode timer timeout.
+ *
+ * @details This function will be called each time the Identity mode timer expires.
+ *
+ */
+void identity_mode_timeout_handler(void)
+{
+ COMM_ENTRY();
+
+ commissioning_evt_t commissioning_evt;
+ memset(&commissioning_evt, 0x00, sizeof(commissioning_evt));
+ commissioning_evt.commissioning_evt_id = COMMISSIONING_EVT_IDENTITY_MODE_EXIT;
+
+ m_commissioning_evt_handler(&commissioning_evt);
+
+ COMM_EXIT();
+}
+
+
+void commissioning_joining_mode_timer_ctrl( \
+ joining_mode_timer_ctrl_cmd_t joining_mode_timer_ctrl_cmd)
+{
+ switch (joining_mode_timer_ctrl_cmd)
+ {
+ case JOINING_MODE_TIMER_STOP_RESET:
+ {
+ commissioning_timer_stop_reset(TIMER_INDEX_JOINING_MODE);
+
+ break;
+ }
+ case JOINING_MODE_TIMER_START:
+ {
+ commissioning_timer_start(TIMER_INDEX_JOINING_MODE, m_node_settings.joining_mode_to);
+
+ break;
+ }
+ }
+}
+
+
+void commissioning_gap_params_get(ipv6_medium_ble_gap_params_t ** pp_node_gap_params)
+{
+ switch (m_current_mode)
+ {
+ case NODE_MODE_JOINING:
+ {
+ *pp_node_gap_params = &m_joining_mode_gap_params;
+
+ break;
+ }
+ case NODE_MODE_IDENTITY:
+ // Fall-through.
+ case NODE_MODE_CONFIG:
+ {
+ *pp_node_gap_params = &m_config_mode_gap_params;
+
+ break;
+ }
+ }
+}
+
+
+void commissioning_adv_params_get(ipv6_medium_ble_adv_params_t ** pp_node_adv_params)
+{
+ switch (m_current_mode)
+ {
+ case NODE_MODE_JOINING:
+ {
+ *pp_node_adv_params = &m_joining_mode_adv_params;
+
+ break;
+ }
+ case NODE_MODE_IDENTITY:
+ // Fall-through.
+ case NODE_MODE_CONFIG:
+ {
+ *pp_node_adv_params = &m_config_mode_adv_params;
+
+ break;
+ }
+ }
+}
+
+
+/**@brief Function for reading all node settings from the persistent storage.
+ */
+static void read_node_settings(void)
+{
+ memset(&m_node_settings, 0x00, sizeof(m_node_settings));
+
+#if (FDS_ENABLED == 1)
+ persistent_settings_load();
+#endif // FDS_ENABLED
+
+ if (m_node_settings.ssid_store.ssid_len > NCFGS_SSID_MAX_LEN)
+ {
+ m_node_settings.ssid_store.ssid_len = 0;
+ }
+ if (m_node_settings.keys_store.keys_len > NCFGS_KEYS_MAX_LEN)
+ {
+ m_node_settings.keys_store.keys_len = 0;
+ }
+ if (m_node_settings.id_data_store.identity_data_len > NCFGS_IDENTITY_DATA_MAX_LEN)
+ {
+ m_node_settings.id_data_store.identity_data_len = 0;
+ }
+
+ // The duration of each mode needs to be at least 10 second.
+ m_node_settings.joining_mode_to = \
+ (m_node_settings.joining_mode_to < 10) ? 10 : m_node_settings.joining_mode_to;
+ m_node_settings.config_mode_to = \
+ (m_node_settings.config_mode_to < 10) ? 10 : m_node_settings.config_mode_to;
+ m_node_settings.id_mode_to = \
+ (m_node_settings.id_mode_to < 10) ? 10 : m_node_settings.id_mode_to;
+}
+
+#if (COMM_ENABLE_LOGS == 1)
+/**@brief Function for printing all node settings.
+ */
+static void print_node_settings(void)
+{
+ COMM_TRC("");
+ COMM_TRC(" Commissioning settings in memory:");
+ COMM_TRC(" Start mode: %5d", m_node_settings.poweron_mode);
+ COMM_TRC(" Mode if Joining Mode fails: %5d", m_node_settings.joining_mode_failure);
+ COMM_TRC(" General timeout in Joining Mode: %5ld", m_node_settings.joining_mode_to);
+ COMM_TRC(" Mode if Configuration Mode fails: %5d", m_node_settings.config_mode_failure);
+ COMM_TRC("General timeout in Configuration Mode: %5ld", m_node_settings.config_mode_to);
+ COMM_TRC(" Identity Mode duration: %5ld", m_node_settings.id_mode_to);
+ COMM_TRC(" Stored Keys length: %5d", m_node_settings.keys_store.keys_len);
+ COMM_TRC(" Stored Keys:");
+ uint8_t ii;
+ for (ii=0; ii<m_node_settings.keys_store.keys_len; ++ii)
+ {
+ COMM_TRC("0x%02X", m_node_settings.keys_store.keys[ii]);
+ }
+ COMM_TRC("");
+ COMM_TRC(" Stored SSID length: %5d", m_node_settings.ssid_store.ssid_len);
+ COMM_TRC(" Stored SSID:");
+ for (ii=0; ii<m_node_settings.ssid_store.ssid_len; ++ii)
+ {
+ COMM_TRC("0x%02X", m_node_settings.ssid_store.ssid[ii]);
+ }
+ COMM_TRC("");
+ COMM_TRC(" Stored Identity Data length: %5d", m_node_settings.id_data_store.identity_data_len);
+ COMM_TRC(" Stored Identity Data:");
+ for (ii=0; ii<m_node_settings.id_data_store.identity_data_len; ++ii)
+ {
+ COMM_TRC("0x%02X", m_node_settings.id_data_store.identity_data[ii]);
+ }
+ COMM_TRC("");
+}
+#endif // (COMM_ENABLE_LOGS == 1)
+
+
+void commissioning_settings_clear(void)
+{
+ COMM_ENTRY();
+ memset(&m_node_settings, 0x00, sizeof(m_node_settings));
+
+#if (FDS_ENABLED == 1)
+ persistent_settings_clear();
+#endif // FDS_ENABLED
+
+ COMM_EXIT();
+}
+
+
+void commissioning_ble_evt_handler(const ble_evt_t * p_ble_evt)
+{
+ uint32_t err_code;
+
+ switch (p_ble_evt->header.evt_id)
+ {
+ case BLE_GAP_EVT_CONNECTED:
+ {
+ m_conn_handle = p_ble_evt->evt.gap_evt.conn_handle;
+ commissioning_timer_stop_reset(TIMER_INDEX_DELAYED_ACTION);
+ commissioning_timer_stop_reset(TIMER_INDEX_CONFIG_MODE);
+
+ break;
+ }
+ case BLE_GAP_EVT_DISCONNECTED:
+ {
+ m_conn_handle = BLE_CONN_HANDLE_INVALID;
+ if (m_current_mode == NODE_MODE_CONFIG)
+ {
+ commissioning_timer_start(TIMER_INDEX_CONFIG_MODE, \
+ m_node_settings.config_mode_to);
+ }
+ if (m_current_mode == NODE_MODE_JOINING)
+ {
+ commissioning_timer_start(TIMER_INDEX_JOINING_MODE, \
+ m_node_settings.joining_mode_to);
+ }
+
+ break;
+ }
+ case BLE_GAP_EVT_AUTH_KEY_REQUEST:
+ {
+ if (m_current_mode == NODE_MODE_JOINING)
+ {
+ // If passkey is shorter than BLE_GAP_PASSKEY_LEN, add '0' character.
+ if (m_node_settings.keys_store.keys_len < BLE_GAP_PASSKEY_LEN)
+ {
+ memset(&m_node_settings.keys_store.keys[m_node_settings.keys_store.keys_len], \
+ '0', BLE_GAP_PASSKEY_LEN - m_node_settings.keys_store.keys_len);
+ }
+
+ // Short passkey to 6-length character.
+ m_node_settings.keys_store.keys[BLE_GAP_PASSKEY_LEN] = 0;
+
+ COMM_TRC("Stored passkey is: %s", m_node_settings.keys_store.keys);
+
+ err_code = sd_ble_gap_auth_key_reply(m_conn_handle, \
+ BLE_GAP_AUTH_KEY_TYPE_PASSKEY, \
+ m_node_settings.keys_store.keys);
+ APP_ERROR_CHECK(err_code);
+ }
+
+ break;
+ }
+ case BLE_GAP_EVT_AUTH_STATUS:
+ {
+ if (m_current_mode == NODE_MODE_JOINING)
+ {
+ COMM_TRC("Status of authentication: %08x", \
+ p_ble_evt->evt.gap_evt.params.auth_status.auth_status);
+ }
+
+ break;
+ }
+ case BLE_GAP_EVT_SEC_PARAMS_REQUEST:
+ {
+ if (m_current_mode == NODE_MODE_JOINING)
+ {
+ ble_gap_sec_params_t sec_param;
+ ble_gap_sec_keyset_t keys_exchanged;
+
+ memset(&sec_param, 0, sizeof(ble_gap_sec_params_t));
+ memset(&keys_exchanged, 0, sizeof(ble_gap_sec_keyset_t));
+
+ sec_param.bond = SEC_PARAM_BOND;
+ sec_param.oob = SEC_PARAM_OOB;
+ sec_param.min_key_size = SEC_PARAM_MIN_KEY_SIZE;
+ sec_param.max_key_size = SEC_PARAM_MAX_KEY_SIZE;
+ sec_param.mitm = SEC_PARAM_MITM;
+ sec_param.io_caps = SEC_PARAM_IO_CAPABILITIES;
+
+ err_code = sd_ble_gap_sec_params_reply(p_ble_evt->evt.gap_evt.conn_handle,
+ BLE_GAP_SEC_STATUS_SUCCESS,
+ &sec_param,
+ &keys_exchanged);
+ APP_ERROR_CHECK(err_code);
+ }
+
+ break;
+ }
+ default:
+ {
+ break;
+ }
+ }
+}
+
+
+void on_ble_ncfgs_evt(ble_ncfgs_data_t * ncfgs_data)
+{
+ COMM_ENTRY();
+
+ commissioning_timer_stop_reset(TIMER_INDEX_DELAYED_ACTION);
+ commissioning_timer_stop_reset(TIMER_INDEX_CONFIG_MODE);
+
+ uint32_t mode_duration_sec;
+ mode_duration_sec = ncfgs_data->ctrlp_value.duration_sec;
+ mode_duration_sec = (mode_duration_sec == 0) ? 1 : mode_duration_sec;
+
+ switch (ncfgs_data->ctrlp_value.opcode)
+ {
+ case NCFGS_OPCODE_GOTO_JOINING_MODE:
+ {
+ m_next_mode = NODE_MODE_JOINING;
+
+ m_node_settings.joining_mode_to = mode_duration_sec;
+ m_node_settings.joining_mode_failure = ncfgs_data->ctrlp_value.state_on_failure;
+
+ /* This code will get executed in two scenarios:
+ - if the previous mode was Config mode and now we are ready to connect to the router, or
+ - if the previous mode was Joining mode and the state on failure was set to No Change.
+ */
+ if (m_node_settings.joining_mode_failure == NCFGS_SOF_NO_CHANGE)
+ {
+ m_node_settings.poweron_mode = NODE_MODE_JOINING;
+ }
+ else
+ {
+ // If the state on failure is NOT No Change, start next time in Config mode.
+ m_node_settings.poweron_mode = NODE_MODE_CONFIG;
+ }
+
+ if (m_node_settings.joining_mode_failure == NCFGS_SOF_PWR_OFF)
+ {
+ COMM_TRC("Will power off on failure.");
+ m_power_off_on_failure = true; // The assert handler will power off the system.
+ }
+
+ break;
+ }
+ case NCFGS_OPCODE_GOTO_CONFIG_MODE:
+ {
+ m_next_mode = NODE_MODE_CONFIG;
+
+ m_node_settings.config_mode_to = mode_duration_sec;
+ m_node_settings.config_mode_failure = ncfgs_data->ctrlp_value.state_on_failure;
+
+ /* The node is about to enter Config mode. Regardless of what the state on failure
+ setting is (No Change or Pwr Off or Cfg Mode), the poweron_mode value should be Cfg Mode. */
+ m_node_settings.poweron_mode = NODE_MODE_CONFIG;
+
+ if (m_node_settings.config_mode_failure == NCFGS_SOF_PWR_OFF)
+ {
+ COMM_TRC("Will power off on failure.");
+ m_power_off_on_failure = true; // The assert handler will power off the system.
+ }
+
+ break;
+ }
+ case NCFGS_OPCODE_GOTO_IDENTITY_MODE:
+ {
+ m_next_mode = NODE_MODE_IDENTITY;
+
+ m_node_settings.id_mode_to = mode_duration_sec;
+
+ break;
+ }
+ default:
+ {
+ break;
+ }
+ }
+
+ memcpy(&m_node_settings.ssid_store, &ncfgs_data->ssid_from_router, sizeof(ssid_store_t));
+ memcpy(&m_node_settings.keys_store, &ncfgs_data->keys_from_router, sizeof(keys_store_t));
+ memcpy(&m_node_settings.id_data_store, &ncfgs_data->id_data, sizeof(id_data_store_t));
+
+#if (COMM_ENABLE_LOGS == 1)
+ print_node_settings();
+#endif // (COMM_ENABLE_LOGS == 1)
+
+#if (FDS_ENABLED == 1)
+ uint32_t err_code = persistent_settings_update();
+ APP_ERROR_CHECK(err_code);
+#endif // FDS_ENABLED
+
+ uint32_t action_delay_written = ncfgs_data->ctrlp_value.delay_sec;
+ // Set the timeout value to at least MINIMUM_ACTION_DELAY second(s).
+ // This is to make sure that storing settings in the persistent
+ // storage completes before activating the next mode.
+ action_delay_written = (action_delay_written < MINIMUM_ACTION_DELAY) ? \
+ MINIMUM_ACTION_DELAY : action_delay_written;
+
+ COMM_TRC("Action delay: %ld seconds.", action_delay_written);
+ commissioning_timer_start(TIMER_INDEX_DELAYED_ACTION, action_delay_written);
+
+ COMM_EXIT();
+}
+
+
+void commissioning_time_tick(iot_timer_time_in_ms_t wall_clock_value)
+{
+ UNUSED_PARAMETER(wall_clock_value);
+ uint8_t index;
+
+ for (index=0; index<NUMBER_OF_COMMISSIONING_TIMERS; ++index)
+ {
+ if (m_commissioning_timers[index].is_timer_running == true)
+ {
+ m_commissioning_timers[index].current_value_sec -= COMMISSIONING_TICK_INTERVAL_SEC;
+
+ if (m_commissioning_timers[index].current_value_sec == 0)
+ {
+ commissioning_timer_stop_reset(index);
+ m_commissioning_timers[index].timeout_handler();
+ }
+ }
+ }
+}
+
+
+static void commissioning_timers_init(void)
+{
+ memset(m_commissioning_timers, 0x00, sizeof(m_commissioning_timers));
+ m_commissioning_timers[TIMER_INDEX_DELAYED_ACTION].timeout_handler = \
+ action_timeout_handler;
+ m_commissioning_timers[TIMER_INDEX_CONFIG_MODE].timeout_handler = \
+ config_mode_timeout_handler;
+ m_commissioning_timers[TIMER_INDEX_JOINING_MODE].timeout_handler = \
+ joining_mode_timeout_handler;
+ m_commissioning_timers[TIMER_INDEX_IDENTITY_MODE].timeout_handler = \
+ identity_mode_timeout_handler;
+}
+
+uint32_t commissioning_init(commissioning_init_params_t * p_init_param, \
+ uint8_t * p_poweron_state)
+{
+ COMM_ENTRY();
+ uint32_t err_code = NRF_SUCCESS;
+
+ m_commissioning_evt_handler = p_init_param->commissioning_evt_handler;
+ m_power_off_on_failure = false;
+
+ // Initialize Commissioning timers.
+
+ commissioning_timers_init();
+
+ // Initialize GATT server.
+
+ err_code = ble_ncfgs_init(on_ble_ncfgs_evt);
+ if (err_code != NRF_SUCCESS)
+ {
+ return err_code;
+ }
+
+#if (FDS_ENABLED == 1)
+ err_code = persistent_settings_init();
+ if (err_code != NRF_SUCCESS)
+ {
+ return err_code;
+ }
+#endif
+
+ // Read application settings from persistent storage.
+ read_node_settings();
+
+#if (COMM_ENABLE_LOGS == 1)
+ print_node_settings();
+#endif // (COMM_ENABLE_LOGS == 1)
+
+ if (!settings_are_valid()) // If the settings are invalid for any reason go to Config mode.
+ {
+ COMM_ERR("Invalid settings!");
+
+ commissioning_settings_clear();
+
+ memset(&m_node_settings, 0x00, sizeof(m_node_settings));
+ m_node_settings.config_mode_to = 300;
+
+ *p_poweron_state = NODE_MODE_CONFIG;
+ }
+ else
+ {
+ if (m_node_settings.poweron_mode == NODE_MODE_JOINING)
+ {
+ /* This code will get executed in two scenarios:
+ - if the previous mode was Config mode and now we are ready to connect to the router, or
+ - if the previous mode was Joining mode and the state on failure was set to No Change.
+ */
+ if ((m_node_settings.joining_mode_failure == NCFGS_SOF_PWR_OFF) || \
+ (m_node_settings.joining_mode_failure == NCFGS_SOF_CONFIG_MODE))
+ {
+ // If the state on failure is NOT No Change, start next time in Config mode.
+ m_node_settings.poweron_mode = NODE_MODE_CONFIG;
+#if (FDS_ENABLED == 1)
+ err_code = persistent_settings_update();
+ APP_ERROR_CHECK(err_code);
+#endif // FDS_ENABLED
+ }
+
+ if (m_node_settings.joining_mode_failure == NCFGS_SOF_PWR_OFF)
+ {
+ COMM_TRC("Will power off on failure.");
+ m_power_off_on_failure = true; // The assert handler will power off the system.
+ }
+
+ *p_poweron_state = NODE_MODE_JOINING;
+ }
+ else
+ {
+ /* The app is about to enter Config mode. Regardless of what the state on failure
+ setting is (No Change or Pwr Off or Cfg Mode), the poweron_mode value should remain the same. */
+
+ if (m_node_settings.config_mode_failure == NCFGS_SOF_PWR_OFF)
+ {
+ COMM_TRC("Will power off on failure.");
+ m_power_off_on_failure = true; // The assert handler will power off the system.
+ }
+
+ *p_poweron_state = NODE_MODE_CONFIG;
+ }
+ }
+
+ // Set advertising and GAP parameters.
+ config_mode_gap_params_set();
+ config_mode_adv_params_set();
+ joining_mode_gap_params_set();
+ joining_mode_adv_params_set();
+
+ COMM_EXIT();
+ return err_code;
+}
+
+#endif // COMMISSIONING_ENABLED
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/medium/commissioning/commissioning.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/medium/commissioning/commissioning.h
new file mode 100644
index 0000000..777f60e
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/medium/commissioning/commissioning.h
@@ -0,0 +1,207 @@
+/**
+ * Copyright (c) 2015-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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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
+ *
+ * @defgroup commissioning_module Commissioning Module
+ * @{
+ * @ingroup iot_sdk_common
+ * @brief Commissioning module.
+ *
+ * @details Enables commissioning of the node by managing transitions between the Config, Joining, and
+ * Identity modes. In Config mode the node can be configured with the settings required to
+ * join the network in Joining mode. The Identity mode can be requested to make the node
+ * easily recognizable for the user.
+ * The settings managed by the module are stored in persistent storage.
+ */
+
+#ifndef COMMISSIONING_H__
+#define COMMISSIONING_H__
+
+#include <stdint.h>
+#include <stdbool.h>
+#include "ble_ncfgs.h"
+#include "iot_timer.h"
+#include "ipv6_medium_ble.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define COMMISSIONING_TICK_INTERVAL_SEC 1 /**< Interval between periodic callbacks to the Commissioning module. */
+
+#define COMMISSIONING_EVT_CONFIG_MODE_ENTER 0x01 /**< Indicates that the medium entered mode for commissioning configuration. */
+#define COMMISSIONING_EVT_JOINING_MODE_ENTER 0x02 /**< Indicates that the medium exited mode for commissioning configuration. */
+#define COMMISSIONING_EVT_IDENTITY_MODE_ENTER 0x03 /**< Indicates that identity mode was requested. */
+#define COMMISSIONING_EVT_IDENTITY_MODE_EXIT 0x04 /**< Indicates that the node should stop using any features associated with the Identity mode. */
+
+#define NODE_MODE_NONE 0x00 /**< Node mode: before initialization. */
+#define NODE_MODE_JOINING 0x01 /**< Node mode: joining the network. */
+#define NODE_MODE_CONFIG 0x02 /**< Node mode: configuration. */
+#define NODE_MODE_IDENTITY 0x03 /**< Node mode: conspicuous for the user. */
+
+/**@brief Joining mode timer control commands. */
+typedef enum
+{
+ JOINING_MODE_TIMER_START = 0x01,
+ JOINING_MODE_TIMER_STOP_RESET = 0x02
+} joining_mode_timer_ctrl_cmd_t;
+
+/**@brief Structure for storing all settings necessary for commissioning. */
+typedef struct __attribute__ ((__packed__)) __attribute__((aligned))
+{
+ uint8_t poweron_mode; // Checked at startup to enter correct mode.
+ state_on_failure_t joining_mode_failure; // Mode to enter if Joining mode fails.
+ uint32_t joining_mode_to; // General timeout in Joining mode.
+ state_on_failure_t config_mode_failure; // Mode to enter if Config mode fails.
+ uint32_t config_mode_to; // General timeout in Config mode.
+ uint32_t id_mode_to; // Duration of Identity Mode.
+ ssid_store_t ssid_store; // SSID received from the router.
+ keys_store_t keys_store; // Keys received from the router.
+ id_data_store_t id_data_store; // Custom node identifier data.
+} commissioning_settings_t;
+
+/**@brief Commissioning module event handler type. */
+typedef void (*commissioning_timeout_handler_t)(void);
+
+/**@brief Structure for creating timers in the Commissioning module. */
+typedef struct
+{
+ bool is_timer_running;
+ uint32_t current_value_sec;
+ commissioning_timeout_handler_t timeout_handler;
+} commissioning_timer_t;
+
+/**@brief Structure of events passed by the Commissioning module to the parent layer. */
+typedef struct
+{
+ uint8_t commissioning_evt_id;
+ bool power_off_enable_requested;
+ commissioning_settings_t * p_commissioning_settings;
+} commissioning_evt_t;
+
+/**@brief Function for handling BLE events.
+ *
+ * @details This function must be called from the BLE stack event dispatcher
+ * to handle BLE events that are relevant for the Commissioning module.
+ *
+ * @param[in] p_ble_evt BLE stack event.
+ */
+void commissioning_ble_evt_handler(const ble_evt_t * p_ble_evt);
+
+/**@brief Commissioning module event handler type. */
+typedef void (*commissioning_evt_handler_t)(commissioning_evt_t * p_commissioning_evt);
+
+/**@brief Structure for initialization parameters of the Commissioning module. */
+typedef struct
+{
+ commissioning_evt_handler_t commissioning_evt_handler;
+} commissioning_init_params_t;
+
+/**@brief Function for initializing the Commissioning module.
+ *
+ * @details Initializes the Node Configuration Service module to create the GATT database.
+ * Loads previously stored node settings from the persistent storage and if
+ * the settings are valid, sets up the node to start in the right mode.
+ *
+ * @param[in] p_init_param Pointer to the initialization parameters.
+ * @param[out] p_poweron_state Pointer to the value of the mode that should be started.
+ *
+ * @retval NRF_SUCCESS If initialization was successful. Otherwise, a propagated
+ * error code is returned.
+ *
+ */
+uint32_t commissioning_init(commissioning_init_params_t * p_init_param,
+ uint8_t * p_poweron_state);
+
+/**@brief Function for advancing the node to a new mode.
+ *
+ * @details Stops and starts app timers appropriate for the mode requested.
+ * Propagates the mode change event to the parent layer.
+ *
+ * @param[in] new_mode New mode to start.
+ *
+ */
+void commissioning_node_mode_change(uint8_t new_mode);
+
+/**@brief Function for getting the address of GAP parameters for the active mode.
+ *
+ * @param[out] pp_node_gap_params Address of GAP parameters for the active mode.
+ *
+ */
+void commissioning_gap_params_get(ipv6_medium_ble_gap_params_t ** pp_node_gap_params);
+
+/**@brief Function for getting the address of advertising parameters for the active mode.
+ *
+ * @param[out] pp_node_adv_params Address of advertising parameters for the active mode.
+ *
+ */
+void commissioning_adv_params_get(ipv6_medium_ble_adv_params_t ** pp_node_adv_params);
+
+/**@brief Function for clearing all node settings from the persistent storage.
+ *
+ * @details Calls the appropriate persistent storage interface function to clear
+ * all commissioning-related settings from the persistent storage.
+ *
+ */
+void commissioning_settings_clear(void);
+
+/**@brief Function for controlling the joining mode timer from the parent layer(s).
+ *
+ * @details If the Joining mode timer reaches zero, the node must enter the
+ * state-on-failure, as set by the user. This function allows the
+ * application designer to control the Joining mode timer from the
+ * application layer.
+ */
+void commissioning_joining_mode_timer_ctrl(
+ joining_mode_timer_ctrl_cmd_t joining_mode_timer_ctrl_cmd);
+
+/**@brief Commissioning time tick used for measuring delays and time between events.
+ *
+ * @param[in] wall_clock_value Wall clock value from the IoT Timer module.
+ */
+void commissioning_time_tick(iot_timer_time_in_ms_t wall_clock_value);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // COMMISSIONING_H__
+
+/** @} */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/medium/ipv6_medium.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/medium/ipv6_medium.h
new file mode 100644
index 0000000..064737d
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/medium/ipv6_medium.h
@@ -0,0 +1,238 @@
+/**
+ * Copyright (c) 2015 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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
+ *
+ * @defgroup ipv6_medium IPv6 Medium
+ * @{
+ * @ingroup iot_sdk_common
+ * @brief IPv6 Medium Interface.
+ *
+ * @details Implementation-agnostic interface of the physical transport that
+ * facilitates IPv6 traffic.
+ */
+
+#ifndef IPV6_MEDIUM_H__
+#define IPV6_MEDIUM_H__
+
+#include <stdint.h>
+#include <stdbool.h>
+#include "ipv6_medium_platform.h"
+#include "iot_defines.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define EUI_48_SIZE 6 /**< Size of a 48-bit Extended Unique Identifier in bytes. */
+
+#define IPV6_MEDIUM_ID_ANY 0x00 /**< Indicates invalid physical transport type. */
+#define IPV6_MEDIUM_ID_BLE 0x01 /**< Indicates that the physical transport is BLE. */
+#define IPV6_MEDIUM_ID_802154 0x02 /**< Indicates that the physical transport is 802.15.4. */
+
+#define IPV6_MEDIUM_EVT_CONN_DOWN 0x01 /**< Indicates that a connection is established. */
+#define IPV6_MEDIUM_EVT_CONN_UP 0x02 /**< Indicates that a connection is torn down. */
+#define IPV6_MEDIUM_EVT_CONNECTABLE_MODE_ENTER 0x01 /**< Indicates that the medium entered connectable mode. */
+#define IPV6_MEDIUM_EVT_CONNECTABLE_MODE_EXIT 0x02 /**< Indicates that the medium exited connectable mode. */
+#define IPV6_MEDIUM_EVT_MAC_ADDRESS_CHANGED 0x03 /**< Indicates that the device has a new MAC address. */
+#define IPV6_MEDIUM_EVT_PHY_SPECIFIC 0xFF /**< Indicates miscellaneous event from the physical layer. */
+
+/**@brief IPv6 medium instance identifier type. */
+typedef uint32_t ipv6_medium_instance_id_t;
+
+/**@brief Type of IPv6 medium type. */
+typedef uint8_t ipv6_medium_type_t;
+
+/**@brief IPv6 medium instance type. */
+typedef struct
+{
+ ipv6_medium_instance_id_t ipv6_medium_instance_id;
+ ipv6_medium_type_t ipv6_medium_instance_type;
+} ipv6_medium_instance_t;
+
+/**@brief EUI-48 value type. */
+typedef struct
+{
+ uint8_t identifier[EUI_48_SIZE]; /**< 48-bit identifier. */
+} eui48_t;
+
+/**@brief Type of IPv6 medium event parameters. */
+typedef struct
+{
+ ipv6_medium_instance_t ipv6_medium_instance_id;
+ uint8_t ipv6_medium_evt_id;
+ ipv6_medium_cb_params_union_t medium_specific;
+} ipv6_medium_evt_t;
+
+/**@brief Type of IPv6 medium error parameters. */
+typedef struct
+{
+ ipv6_medium_instance_t ipv6_medium_instance_id;
+ uint32_t error_label;
+ ipv6_medium_err_params_union_t medium_specific;
+} ipv6_medium_error_t;
+
+/**@brief IPv6 medium event handler type. */
+typedef void (*ipv6_medium_evt_handler_t)(ipv6_medium_evt_t * p_ipv6_medium_evt);
+
+/**@brief IPv6 medium error handler type. */
+typedef void (*ipv6_medium_error_handler_t)(ipv6_medium_error_t * p_ipv6_medium_error);
+
+#ifdef COMMISSIONING_ENABLED
+/**@brief Commissioning mode control commands. */
+typedef enum
+{
+ CMD_IDENTITY_MODE_EXIT = 0x00,
+ CMD_IDENTITY_MODE_ENTER = 0x01
+} mode_control_cmd_t;
+
+/**@brief Commissioning: Identity mode control callback function type. */
+typedef void (*commissioning_id_mode_cb_t)(mode_control_cmd_t control_command);
+
+/**@brief Commissioning: Power off on failure control callback function type. */
+typedef void (*commissioning_poweroff_cb_t)(bool do_poweroff_on_failure);
+#endif // COMMISSIONING_ENABLED
+
+/**@brief Structure for initialization parameters of the IPv6 medium. */
+typedef struct
+{
+ ipv6_medium_evt_handler_t ipv6_medium_evt_handler;
+ ipv6_medium_error_handler_t ipv6_medium_error_handler;
+#ifdef COMMISSIONING_ENABLED
+ commissioning_id_mode_cb_t commissioning_id_mode_cb;
+ commissioning_poweroff_cb_t commissioning_power_off_cb;
+#endif // COMMISSIONING_ENABLED
+} ipv6_medium_init_params_t;
+
+/**@brief Function for initializing the IPv6 medium.
+ *
+ * @details Initializes the IPv6 medium module.
+ * Performs all setup necessary that is specific to the implementation.
+ *
+ * @param[in] p_init_param Pointer to the initialization parameters.
+ * @param[in] desired_medium_type Value of the desired medium type.
+ * @param[out] p_new_medium_instance Pointer to the new medium instance initialized.
+ *
+ * @retval NRF_SUCCESS If initialization was successful. Otherwise, a propagated
+ * error code is returned.
+ *
+ */
+uint32_t ipv6_medium_init(ipv6_medium_init_params_t * p_init_param,
+ ipv6_medium_type_t desired_medium_type,
+ ipv6_medium_instance_t * p_new_medium_instance);
+
+/**@brief Function for entering connectible mode.
+ *
+ * @details Requests the IPv6 medium to enter connectible mode.
+ *
+ * @param[in] ipv6_medium_instance_id Specifies the IPv6 medium instance.
+ *
+ * @retval NRF_SUCCESS If the procedure was successful. Otherwise, a propagated
+ * error code is returned.
+ *
+ */
+uint32_t ipv6_medium_connectable_mode_enter(ipv6_medium_instance_id_t ipv6_medium_instance_id);
+
+/**@brief Function for exiting connectible mode.
+ *
+ * @details Requests the IPv6 medium to exit connectible mode.
+ *
+ * @param[in] ipv6_medium_instance_id Specifies the IPv6 medium instance.
+ *
+ * @retval NRF_SUCCESS If the procedure was successful. Otherwise, a propagated
+ * error code is returned.
+ *
+ */
+uint32_t ipv6_medium_connectable_mode_exit(ipv6_medium_instance_id_t ipv6_medium_instance_id);
+
+/**@brief Function for getting the 48-bit Extended Unique Identifier.
+ *
+ * @param[in] ipv6_medium_instance_id Specifies the IPv6 medium instance.
+ * @param[out] p_ipv6_medium_eui48 Pointer to the EUI-48 value.
+ *
+ * @retval NRF_SUCCESS If the procedure was successful. Otherwise, a propagated
+ * error code is returned.
+ *
+ */
+uint32_t ipv6_medium_eui48_get(ipv6_medium_instance_id_t ipv6_medium_instance_id,
+ eui48_t * p_ipv6_medium_eui48);
+
+/**@brief Function for setting the 48-bit Extended Unique Identifier.
+ *
+ * @param[in] ipv6_medium_instance_id Specifies the IPv6 medium instance.
+ * @param[in] p_ipv6_medium_eui48 Pointer to the EUI-48 value.
+ *
+ * @retval NRF_SUCCESS If the procedure was successful. Otherwise, a propagated
+ * error code is returned.
+ *
+ */
+uint32_t ipv6_medium_eui48_set(ipv6_medium_instance_id_t ipv6_medium_instance_id,
+ eui48_t * p_ipv6_medium_eui48);
+
+/**@brief Function for getting the 64-bit Extended Unique Identifier.
+ *
+ * @param[in] ipv6_medium_instance_id Specifies the IPv6 medium instance.
+ * @param[out] p_ipv6_medium_eui64 Pointer to the EUI-64 value.
+ *
+ * @retval NRF_SUCCESS If the procedure was successful. Otherwise, a propagated
+ * error code is returned.
+ *
+ */
+uint32_t ipv6_medium_eui64_get(ipv6_medium_instance_id_t ipv6_medium_instance_id,
+ eui64_t * p_ipv6_medium_eui64);
+
+/**@brief Function for setting the 64-bit Extended Unique Identifier.
+ *
+ * @param[in] ipv6_medium_instance_id Specifies the IPv6 medium instance.
+ * @param[in] p_ipv6_medium_eui64 Pointer to the EUI-64 value.
+ *
+ * @retval NRF_SUCCESS If the procedure was successful. Otherwise, a propagated
+ * error code is returned.
+ *
+ */
+uint32_t ipv6_medium_eui64_set(ipv6_medium_instance_id_t ipv6_medium_instance_id,
+ eui64_t * p_ipv6_medium_eui64);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // IPV6_MEDIUM_H__
+
+/** @} */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/medium/ipv6_medium_ble.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/medium/ipv6_medium_ble.c
new file mode 100644
index 0000000..0d0a415
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/medium/ipv6_medium_ble.c
@@ -0,0 +1,689 @@
+/**
+ * Copyright (c) 2015-2018 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#include <stdint.h>
+#include "boards.h"
+#include "ipv6_medium.h"
+#include "ipv6_medium_ble.h"
+#include "ble_advdata.h"
+#include "ble_hci.h"
+#include "ble_srv_common.h"
+#include "ble_ipsp.h"
+#include "sdk_config.h"
+#include "nrf_sdm.h"
+#include "nrf_sdh.h"
+#include "nrf_sdh_ble.h"
+#ifdef COMMISSIONING_ENABLED
+#include "commissioning.h"
+#endif // COMMISSIONING_ENABLED
+
+#define PUBLIC_BLE_GAP_ADDR_CREATE_FROM_EUI64(ble_gap_addr, eui64, ble_gap_addr_type) \
+ ble_gap_addr[0] = eui64[7]; \
+ ble_gap_addr[1] = eui64[6]; \
+ ble_gap_addr[2] = eui64[5]; \
+ ble_gap_addr[3] = eui64[2]; \
+ ble_gap_addr[4] = eui64[1]; \
+ ble_gap_addr[5] = 0x00; \
+ ble_gap_addr_type = BLE_GAP_ADDR_TYPE_PUBLIC;
+
+#define IOT_TIMER_DISABLE_API_PARAM_CHECK 0
+
+#if (IOT_TIMER_DISABLE_API_PARAM_CHECK == 0)
+
+#define NULL_PARAM_CHECK(PARAM) \
+ if ((PARAM) == NULL) \
+ { \
+ return (NRF_ERROR_NULL); \
+ }
+
+#else // IOT_TIMER_DISABLE_API_PARAM_CHECK
+
+#define NULL_PARAM_CHECK(PARAM)
+
+#endif //IOT_TIMER_DISABLE_API_PARAM_CHECK
+
+#define BLE_IPV6_MEDIUM_BLE_OBSERVER_PRIO 1 /**< BLE observer priority. */
+#define BLE_IPSP_TAG 35 /**< Identifies the L2CAP configuration used with SoftDevice. */
+
+
+static ipv6_medium_instance_id_t m_module_instance_id = 0x01; /**< Module instance identifier. As of today, only a single instance is supported. */
+static ipv6_medium_evt_handler_t m_ipv6_medium_evt_handler; /**< Pointer to the event handler procedure of the parent layer. */
+static ipv6_medium_error_handler_t m_ipv6_medium_error_handler; /**< Pointer to the error handler procedure of the parent layer. */
+static ble_gap_addr_t m_local_ble_addr; /**< Local BT device address. */
+static ipv6_medium_ble_gap_params_t * m_p_node_gap_params; /**< Pointer to advertising parameters to be used. */
+static ipv6_medium_ble_adv_params_t * m_p_node_adv_params; /**< Pointer to GAP parameters to be used. */
+
+#ifndef COMMISSIONING_ENABLED
+static ipv6_medium_ble_gap_params_t m_gap_params; /**< Advertising parameters w/o commissioning. */
+static ipv6_medium_ble_adv_params_t m_adv_params; /**< GAP parameters w/o commissioning. */
+static ble_uuid_t m_adv_uuids[] =
+ {
+ {BLE_UUID_IPSP_SERVICE, BLE_UUID_TYPE_BLE}
+ }; /**< List of available service UUIDs in advertisement data. */
+#else // COMMISSIONING_ENABLED
+static uint16_t m_conn_handle = BLE_CONN_HANDLE_INVALID; /**< Handle of the active connection. */
+static bool m_connectable_mode_active = false; /**< Indicates if the node is in connectable mode. */
+static commissioning_id_mode_cb_t m_commissioning_id_mode_cb;
+static commissioning_poweroff_cb_t m_commissioning_power_off_cb;
+static bool m_adv_params_applied = false; /**< Indicates if advertising (and GAP) parameters have been applied. */
+#endif // COMMISSIONING_ENABLED
+
+static uint8_t m_adv_handle = BLE_GAP_ADV_SET_HANDLE_NOT_SET; /**< Advertising handle used to identify an advertising set. */
+static uint8_t m_enc_advdata[BLE_GAP_ADV_SET_DATA_SIZE_MAX]; /**< Buffer for storing an encoded advertising set. */
+
+/**@brief Struct that contains pointers to the encoded advertising data. */
+static ble_gap_adv_data_t m_adv_data =
+{
+ .adv_data =
+ {
+ .p_data = m_enc_advdata,
+ .len = BLE_GAP_ADV_SET_DATA_SIZE_MAX
+ },
+ .scan_rsp_data =
+ {
+ .p_data = NULL,
+ .len = 0
+
+ }
+};
+
+#if IPV6_MEDIUM_CONFIG_LOG_ENABLED
+
+#define NRF_LOG_MODULE_NAME ipv6_medium
+
+#define NRF_LOG_LEVEL IPV6_MEDIUM_CONFIG_LOG_LEVEL
+#define NRF_LOG_INFO_COLOR IPV6_MEDIUM_CONFIG_INFO_COLOR
+#define NRF_LOG_DEBUG_COLOR IPV6_MEDIUM_CONFIG_DEBUG_COLOR
+
+#include "nrf_log.h"
+NRF_LOG_MODULE_REGISTER();
+
+#define IPV6M_TRC NRF_LOG_DEBUG /**< Used for getting trace of execution in the module. */
+#define IPV6M_ERR NRF_LOG_ERROR /**< Used for logging errors in the module. */
+#define IPV6M_DUMP NRF_LOG_HEXDUMP_DEBUG /**< Used for dumping octet information to get details of bond information etc. */
+
+#define IPV6M_ENTRY() IPV6M_TRC(">> %s", __func__)
+#define IPV6M_EXIT() IPV6M_TRC("<< %s", __func__)
+
+#else // IPV6_MEDIUM_CONFIG_LOG_ENABLED
+
+#define IPV6M_TRC(...) /**< Disables traces. */
+#define IPV6M_DUMP(...) /**< Disables dumping of octet streams. */
+#define IPV6M_ERR(...) /**< Disables error logs. */
+
+#define IPV6M_ENTRY(...)
+#define IPV6M_EXIT(...)
+
+#endif // IPV6_MEDIUM_CONFIG_LOG_ENABLED
+
+
+#ifndef COMMISSIONING_ENABLED
+
+/**@brief Function for setting advertisement parameters.
+ *
+ * @details These parameters are applied if the Commissioning module is
+ * not used or in Joining mode.
+ */
+static void adv_params_set(void)
+{
+ IPV6M_ENTRY();
+ memset(&m_adv_params, 0x00, sizeof(m_adv_params));
+
+ m_adv_params.advdata.name_type = BLE_ADVDATA_FULL_NAME;
+ m_adv_params.advdata.flags = BLE_GAP_ADV_FLAG_BR_EDR_NOT_SUPPORTED;
+ m_adv_params.advdata.uuids_complete.uuid_cnt = sizeof(m_adv_uuids) / sizeof(m_adv_uuids[0]);
+ m_adv_params.advdata.uuids_complete.p_uuids = m_adv_uuids;
+
+ m_adv_params.advparams.properties.type = BLE_GAP_ADV_TYPE_CONNECTABLE_SCANNABLE_UNDIRECTED;
+ m_adv_params.advparams.p_peer_addr = NULL; // Undirected advertisement.
+ m_adv_params.advparams.filter_policy = BLE_GAP_ADV_FP_ANY;
+ m_adv_params.advparams.interval = APP_ADV_ADV_INTERVAL;
+ m_adv_params.advparams.duration = APP_ADV_DURATION;
+
+ IPV6M_EXIT();
+}
+
+/**@brief Function for setting GAP parameters.
+ *
+ * @details These parameters are applied if the Commissioning module is
+ * not used or in Joining mode.
+ */
+static void gap_params_set(void)
+{
+ memset(&m_gap_params, 0x00, sizeof(m_gap_params));
+
+ BLE_GAP_CONN_SEC_MODE_SET_OPEN(&m_gap_params.sec_mode);
+
+ m_gap_params.appearance = BLE_APPEARANCE_UNKNOWN;
+
+ m_gap_params.p_dev_name = (const uint8_t *)DEVICE_NAME;
+ m_gap_params.dev_name_len = strlen(DEVICE_NAME);
+
+ m_gap_params.gap_conn_params.min_conn_interval = (uint16_t)MIN_CONN_INTERVAL;
+ m_gap_params.gap_conn_params.max_conn_interval = (uint16_t)MAX_CONN_INTERVAL;
+ m_gap_params.gap_conn_params.slave_latency = SLAVE_LATENCY;
+ m_gap_params.gap_conn_params.conn_sup_timeout = CONN_SUP_TIMEOUT;
+}
+
+#endif // COMMISSIONING_ENABLED
+
+
+/**@brief Function for applying the advertisement parameters.
+ *
+ * @details Encodes the required advertising data and passes it to the stack.
+ */
+static void adv_params_apply(void)
+{
+ uint32_t err_code;
+
+
+ err_code = ble_advdata_encode(&m_p_node_adv_params->advdata, m_adv_data.adv_data.p_data, &m_adv_data.adv_data.len);
+ APP_ERROR_CHECK(err_code);
+#ifndef COMMISSIONING_ENABLED
+ err_code = sd_ble_gap_adv_set_configure(&m_adv_handle, &m_adv_data, &m_adv_params.advparams);
+ APP_ERROR_CHECK(err_code);
+#else
+ err_code = sd_ble_gap_adv_set_configure(&m_adv_handle, &m_adv_data, &m_p_node_adv_params->advparams);
+ APP_ERROR_CHECK(err_code);
+#endif
+}
+
+
+/**@brief Function for applying the GAP configuration.
+ *
+ * @details This function sets up all the necessary GAP (Generic Access Profile) parameters of the
+ * device including the device name, appearance, and the preferred connection parameters.
+ */
+static void gap_params_apply(void)
+{
+ uint32_t err_code;
+
+ err_code = sd_ble_gap_device_name_set(&m_p_node_gap_params->sec_mode, \
+ m_p_node_gap_params->p_dev_name, \
+ m_p_node_gap_params->dev_name_len);
+ APP_ERROR_CHECK(err_code);
+
+ err_code = sd_ble_gap_appearance_set(m_p_node_gap_params->appearance);
+ APP_ERROR_CHECK(err_code);
+
+ err_code = sd_ble_gap_ppcp_set(&m_p_node_gap_params->gap_conn_params);
+ APP_ERROR_CHECK(err_code);
+}
+
+
+/**@brief Function for handling the application's BLE Stack events and
+ * passing them on to the applications as generic transport medium events.
+ *
+ * @param[in] p_ble_evt Bluetooth stack event.
+ */
+static void on_ble_evt(ble_evt_t const * p_ble_evt)
+{
+ ipv6_medium_evt_t ipv6_medium_evt;
+
+ memset(&ipv6_medium_evt, 0x00, sizeof(ipv6_medium_evt));
+ ipv6_medium_evt.ipv6_medium_instance_id.ipv6_medium_instance_id = m_module_instance_id;
+ ipv6_medium_evt.ipv6_medium_instance_id.ipv6_medium_instance_type = IPV6_MEDIUM_ID_BLE;
+ ipv6_medium_evt.medium_specific.ble.p_ble_evt = (ble_evt_t*)p_ble_evt;
+
+ ipv6_medium_error_t ipv6_medium_error;
+ memset(&ipv6_medium_error, 0x00, sizeof(ipv6_medium_error));
+ ipv6_medium_error.ipv6_medium_instance_id.ipv6_medium_instance_id = m_module_instance_id;
+ ipv6_medium_error.ipv6_medium_instance_id.ipv6_medium_instance_type = IPV6_MEDIUM_ID_BLE;
+
+ bool do_notify_event = false;
+ bool do_notify_error = false;
+
+ switch (p_ble_evt->header.evt_id)
+ {
+ case BLE_GAP_EVT_CONNECTED:
+ {
+#ifdef COMMISSIONING_ENABLED
+ m_conn_handle = p_ble_evt->evt.gap_evt.conn_handle;
+#endif // COMMISSIONING_ENABLED
+ ipv6_medium_evt.ipv6_medium_evt_id = IPV6_MEDIUM_EVT_CONN_UP;
+ do_notify_event = true;
+
+ break;
+ }
+ case BLE_GAP_EVT_DISCONNECTED:
+ {
+#ifdef COMMISSIONING_ENABLED
+ m_conn_handle = BLE_CONN_HANDLE_INVALID;
+#endif // COMMISSIONING_ENABLED
+ ipv6_medium_evt.ipv6_medium_evt_id = IPV6_MEDIUM_EVT_CONN_DOWN;
+ do_notify_event = true;
+
+ break;
+ }
+ case BLE_GAP_EVT_ADV_SET_TERMINATED:
+ {
+ if (p_ble_evt->evt.gap_evt.params.adv_set_terminated.reason == BLE_GAP_EVT_ADV_SET_TERMINATED_REASON_TIMEOUT)
+ {
+ ipv6_medium_evt.ipv6_medium_evt_id = IPV6_MEDIUM_EVT_CONNECTABLE_MODE_EXIT;
+ do_notify_event = true;
+ }
+ else
+ {
+ // This is not necessarily an error, only added here to show error handler usage.
+ ipv6_medium_error.medium_specific.ble.dummy_value = 0x13;
+ do_notify_error = true;
+ }
+ break;
+ }
+ default:
+ {
+ ipv6_medium_evt.ipv6_medium_evt_id = IPV6_MEDIUM_EVT_PHY_SPECIFIC;
+ do_notify_event = true;
+
+ break;
+ }
+ }
+
+ ble_ipsp_evt_handler(p_ble_evt);
+
+ if (do_notify_event == true)
+ {
+ m_ipv6_medium_evt_handler(&ipv6_medium_evt);
+ }
+ if (do_notify_error == true)
+ {
+ m_ipv6_medium_error_handler(&ipv6_medium_error);
+ }
+}
+
+/*
+ * @brief Function for handling BLE events.
+ *
+ * @param[in] p_ble_evt Event received from the BLE stack.
+ * @param[in] p_context Context.
+ */
+static void ble_evt_handler(const ble_evt_t * p_ble_evt, void * p_context)
+{
+ UNUSED_PARAMETER(p_context);
+#ifdef COMMISSIONING_ENABLED
+ commissioning_ble_evt_handler(p_ble_evt);
+ ble_ncfgs_ble_evt_handler(p_ble_evt);
+#endif // COMMISSIONING_ENABLED
+
+ on_ble_evt(p_ble_evt);
+}
+
+
+
+
+/**@brief Function for initializing the BLE stack.
+ *
+ * @details Initializes the SoftDevice and the BLE event interrupt.
+ */
+static uint32_t ble_stack_init(void)
+{
+ ret_code_t err_code;
+ uint32_t ram_start = 0;
+ ble_cfg_t ble_cfg;
+
+ err_code = nrf_sdh_enable_request();
+
+ if (err_code == NRF_SUCCESS)
+ {
+ // Fetch the start address of the application RAM.
+ err_code = nrf_sdh_ble_app_ram_start_get(&ram_start);
+ }
+
+ if (err_code == NRF_SUCCESS)
+ {
+ // Configure the maximum number of connections.
+ memset(&ble_cfg, 0, sizeof(ble_cfg));
+ ble_cfg.gap_cfg.role_count_cfg.periph_role_count = BLE_IPSP_MAX_CHANNELS;
+ ble_cfg.gap_cfg.role_count_cfg.central_role_count = 0;
+ ble_cfg.gap_cfg.role_count_cfg.central_sec_count = 0;
+ err_code = sd_ble_cfg_set(BLE_GAP_CFG_ROLE_COUNT, &ble_cfg, ram_start);
+ }
+
+ if (err_code == NRF_SUCCESS)
+ {
+ memset(&ble_cfg, 0, sizeof(ble_cfg));
+
+ // Configure total number of connections.
+ ble_cfg.conn_cfg.conn_cfg_tag = BLE_IPSP_TAG;
+ ble_cfg.conn_cfg.params.gap_conn_cfg.conn_count = BLE_IPSP_MAX_CHANNELS;
+ ble_cfg.conn_cfg.params.gap_conn_cfg.event_length = BLE_GAP_EVENT_LENGTH_DEFAULT;
+ err_code = sd_ble_cfg_set(BLE_CONN_CFG_GAP, &ble_cfg, ram_start);
+
+ }
+
+ if (err_code == NRF_SUCCESS)
+ {
+ memset(&ble_cfg, 0, sizeof(ble_cfg));
+
+ // Configure the number of custom UUIDS.
+#ifdef COMMISSIONING_ENABLED
+ ble_cfg.common_cfg.vs_uuid_cfg.vs_uuid_count = 1;
+#else
+ ble_cfg.common_cfg.vs_uuid_cfg.vs_uuid_count = 0;
+#endif // COMMISSIONING_ENABLED
+
+ err_code = sd_ble_cfg_set(BLE_COMMON_CFG_VS_UUID, &ble_cfg, ram_start);
+ }
+
+ if (err_code == NRF_SUCCESS)
+ {
+ memset(&ble_cfg, 0, sizeof(ble_cfg));
+
+ // Set L2CAP channel configuration
+ ble_cfg.conn_cfg.conn_cfg_tag = BLE_IPSP_TAG;
+ ble_cfg.conn_cfg.params.l2cap_conn_cfg.rx_mps = BLE_IPSP_RX_MPS;
+ ble_cfg.conn_cfg.params.l2cap_conn_cfg.rx_queue_size = BLE_IPSP_RX_BUFFER_COUNT;
+ ble_cfg.conn_cfg.params.l2cap_conn_cfg.tx_mps = BLE_IPSP_TX_MPS;
+ ble_cfg.conn_cfg.params.l2cap_conn_cfg.tx_queue_size = 1;
+ ble_cfg.conn_cfg.params.l2cap_conn_cfg.ch_count = 1; // One IPSP channel per link.
+ err_code = sd_ble_cfg_set(BLE_CONN_CFG_L2CAP, &ble_cfg, ram_start);
+ }
+
+ if (err_code == NRF_SUCCESS)
+ {
+ memset(&ble_cfg, 0, sizeof(ble_cfg));
+
+ // Set the ATT table size.
+#ifdef COMMISSIONING_ENABLED
+ ble_cfg.gatts_cfg.attr_tab_size.attr_tab_size = 1024;
+#else
+ ble_cfg.gatts_cfg.attr_tab_size.attr_tab_size = 256;
+#endif // COMMISSIONING_ENABLED
+ err_code = sd_ble_cfg_set(BLE_GATTS_CFG_ATTR_TAB_SIZE, &ble_cfg, ram_start);
+ }
+
+ if (err_code == NRF_SUCCESS)
+ {
+ err_code = nrf_sdh_ble_enable(&ram_start);
+ }
+
+ NRF_SDH_BLE_OBSERVER(m_ble_evt_observer, BLE_IPV6_MEDIUM_BLE_OBSERVER_PRIO, ble_evt_handler, NULL);
+
+ return err_code;
+}
+
+
+uint32_t ipv6_medium_connectable_mode_enter(ipv6_medium_instance_id_t ipv6_medium_instance_id)
+{
+ IPV6M_ENTRY();
+
+ if (ipv6_medium_instance_id != m_module_instance_id)
+ {
+ return NRF_ERROR_INVALID_PARAM;
+ }
+
+#ifdef COMMISSIONING_ENABLED
+ if (m_adv_params_applied == false)
+ {
+ // Apply advertising (and GAP) parameters, if not applied when node mode changed.
+ commissioning_gap_params_get(&m_p_node_gap_params);
+ commissioning_adv_params_get(&m_p_node_adv_params);
+ gap_params_apply();
+ adv_params_apply();
+ }
+ m_adv_params_applied = false;
+#endif // COMMISSIONING_ENABLED
+
+ adv_params_apply();
+
+ uint32_t err_code = sd_ble_gap_adv_start(m_adv_handle, BLE_IPSP_TAG);
+#ifdef COMMISSIONING_ENABLED
+ if (err_code == NRF_SUCCESS)
+ {
+ m_connectable_mode_active = true;
+ }
+#endif // COMMISSIONING_ENABLED
+ IPV6M_EXIT();
+ return err_code;
+}
+
+
+uint32_t ipv6_medium_connectable_mode_exit(ipv6_medium_instance_id_t ipv6_medium_instance_id)
+{
+ if (ipv6_medium_instance_id != m_module_instance_id)
+ {
+ return NRF_ERROR_INVALID_PARAM;
+ }
+
+ uint32_t err_code = sd_ble_gap_adv_stop(m_adv_handle);
+#ifdef COMMISSIONING_ENABLED
+ if (err_code == NRF_SUCCESS)
+ {
+ m_connectable_mode_active = false;
+ }
+#endif // COMMISSIONING_ENABLED
+ return err_code;
+}
+
+
+uint32_t ipv6_medium_eui48_get(ipv6_medium_instance_id_t ipv6_medium_instance_id, \
+ eui48_t * p_ipv6_medium_eui48)
+{
+ if (ipv6_medium_instance_id != m_module_instance_id)
+ {
+ return NRF_ERROR_INVALID_PARAM;
+ }
+ ble_gap_addr_t local_ble_addr;
+ uint32_t err_code = sd_ble_gap_addr_get(&local_ble_addr);
+
+ memcpy(p_ipv6_medium_eui48->identifier, local_ble_addr.addr, EUI_48_SIZE);
+
+ return err_code;
+}
+
+
+uint32_t ipv6_medium_eui48_set(ipv6_medium_instance_id_t ipv6_medium_instance_id, \
+ eui48_t * p_ipv6_medium_eui48)
+{
+ if (ipv6_medium_instance_id != m_module_instance_id)
+ {
+ return NRF_ERROR_INVALID_PARAM;
+ }
+ if (p_ipv6_medium_eui48->identifier[5] != 0x00)
+ {
+ return NRF_ERROR_INVALID_PARAM;
+ }
+
+ m_local_ble_addr.addr_type = BLE_GAP_ADDR_TYPE_PUBLIC;
+ memcpy(m_local_ble_addr.addr, p_ipv6_medium_eui48->identifier, EUI_48_SIZE);
+
+ return sd_ble_gap_addr_set(&m_local_ble_addr);
+}
+
+
+uint32_t ipv6_medium_eui64_get(ipv6_medium_instance_id_t ipv6_medium_instance_id, \
+ eui64_t * p_ipv6_medium_eui64)
+{
+ if (ipv6_medium_instance_id != m_module_instance_id)
+ {
+ return NRF_ERROR_INVALID_PARAM;
+ }
+ ble_gap_addr_t local_ble_addr;
+
+ uint32_t err_code = sd_ble_gap_addr_get(&local_ble_addr);
+ APP_ERROR_CHECK(err_code);
+
+ IPV6_EUI64_CREATE_FROM_EUI48(p_ipv6_medium_eui64->identifier,
+ local_ble_addr.addr,
+ local_ble_addr.addr_type);
+ return NRF_SUCCESS;
+}
+
+
+uint32_t ipv6_medium_eui64_set(ipv6_medium_instance_id_t ipv6_medium_instance_id, \
+ eui64_t * p_ipv6_medium_eui64)
+{
+ if (ipv6_medium_instance_id != m_module_instance_id)
+ {
+ return NRF_ERROR_INVALID_PARAM;
+ }
+ if ((p_ipv6_medium_eui64->identifier[0] != 0x02) ||
+ (p_ipv6_medium_eui64->identifier[3] != 0xFF) ||
+ (p_ipv6_medium_eui64->identifier[4] != 0xFE))
+ {
+ return NRF_ERROR_INVALID_PARAM;
+ }
+
+ ble_gap_addr_t local_ble_addr;
+
+ PUBLIC_BLE_GAP_ADDR_CREATE_FROM_EUI64(local_ble_addr.addr, \
+ p_ipv6_medium_eui64->identifier, \
+ local_ble_addr.addr_type);
+
+ return sd_ble_gap_addr_set(&local_ble_addr);
+}
+
+
+#ifdef COMMISSIONING_ENABLED
+
+void commissioning_evt_handler(commissioning_evt_t * p_commissioning_evt)
+{
+ IPV6M_ENTRY();
+
+ switch (p_commissioning_evt->commissioning_evt_id)
+ {
+ case COMMISSIONING_EVT_CONFIG_MODE_ENTER:
+ // Fall-through.
+ case COMMISSIONING_EVT_JOINING_MODE_ENTER:
+ {
+ m_commissioning_power_off_cb(p_commissioning_evt->power_off_enable_requested);
+
+ if (m_conn_handle != BLE_CONN_HANDLE_INVALID)
+ {
+ // Making sure that advertising (and GAP) parameters are
+ // applied when entering connectable mode the next time.
+ m_adv_params_applied = false;
+ UNUSED_VARIABLE(sd_ble_gap_disconnect(m_conn_handle, \
+ BLE_HCI_REMOTE_USER_TERMINATED_CONNECTION));
+ }
+ else
+ {
+ bool do_return_to_connectable_mode = m_connectable_mode_active;
+ UNUSED_VARIABLE(ipv6_medium_connectable_mode_exit(m_module_instance_id));
+
+ commissioning_gap_params_get(&m_p_node_gap_params);
+ commissioning_adv_params_get(&m_p_node_adv_params);
+ gap_params_apply();
+ adv_params_apply();
+ // Advertising and GAP parameters applied, making sure that
+ // it is not repeated when entering connectable mode the next time.
+ m_adv_params_applied = true;
+
+ if (do_return_to_connectable_mode == true)
+ {
+ // Restart connectable mode, if the node was in connectable mode applying
+ // the new parameters.
+ UNUSED_VARIABLE(ipv6_medium_connectable_mode_enter(m_module_instance_id));
+ }
+ }
+
+ break;
+ }
+ case COMMISSIONING_EVT_IDENTITY_MODE_ENTER:
+ {
+ m_commissioning_id_mode_cb(CMD_IDENTITY_MODE_ENTER);
+
+ break;
+ }
+ case COMMISSIONING_EVT_IDENTITY_MODE_EXIT:
+ {
+ m_commissioning_id_mode_cb(CMD_IDENTITY_MODE_EXIT);
+
+ break;
+ }
+ default:
+ {
+ // No implementation needed.
+ break;
+ }
+ }
+
+ IPV6M_EXIT();
+}
+
+#endif // COMMISSIONING_ENABLED
+
+
+uint32_t ipv6_medium_init(ipv6_medium_init_params_t * p_init_param, \
+ ipv6_medium_type_t desired_medium_type, \
+ ipv6_medium_instance_t * p_new_medium_instance)
+{
+ IPV6M_ENTRY();
+ uint32_t err_code = NRF_SUCCESS;
+ NULL_PARAM_CHECK(p_init_param->ipv6_medium_evt_handler);
+ if (desired_medium_type != IPV6_MEDIUM_ID_BLE)
+ {
+ return NRF_ERROR_INVALID_PARAM;
+ }
+
+ m_ipv6_medium_evt_handler = p_init_param->ipv6_medium_evt_handler;
+ m_ipv6_medium_error_handler = p_init_param->ipv6_medium_error_handler;
+
+ p_new_medium_instance->ipv6_medium_instance_type = IPV6_MEDIUM_ID_BLE;
+ p_new_medium_instance->ipv6_medium_instance_id = m_module_instance_id;
+
+ err_code = ble_stack_init();
+ if (err_code != NRF_SUCCESS)
+ {
+ return err_code;
+ }
+
+#ifndef COMMISSIONING_ENABLED
+ gap_params_set();
+ adv_params_set();
+ m_p_node_gap_params = &m_gap_params;
+ m_p_node_adv_params = &m_adv_params;
+ gap_params_apply();
+#else // COMMISSIONING_ENABLED
+ m_commissioning_id_mode_cb = p_init_param->commissioning_id_mode_cb;
+ m_commissioning_power_off_cb = p_init_param->commissioning_power_off_cb;
+
+ commissioning_init_params_t init_param;
+ memset(&init_param, 0x00, sizeof(init_param));
+ init_param.commissioning_evt_handler = commissioning_evt_handler;
+ uint8_t new_mode;
+ err_code = commissioning_init(&init_param, \
+ &new_mode);
+
+ commissioning_node_mode_change(new_mode);
+#endif // COMMISSIONING_ENABLED
+
+ IPV6M_EXIT();
+ return err_code;
+}
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/medium/ipv6_medium_ble.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/medium/ipv6_medium_ble.h
new file mode 100644
index 0000000..492afe4
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/medium/ipv6_medium_ble.h
@@ -0,0 +1,100 @@
+/**
+ * Copyright (c) 2015 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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
+ *
+ * @defgroup ipv6_medium_ble BLE IPv6 Medium Implementation
+ * @{
+ * @ingroup iot_sdk_common
+ * @brief Bluetooth Low Energy implementation of the IPv6 medium interface.
+ *
+ * @details Type definitions for the BLE implementation of the IPv6 medium interface.
+ * This header also includes the header with BLE-specific configuration.
+ */
+
+#ifndef IPV6_MEDIUM_BLE_H__
+#define IPV6_MEDIUM_BLE_H__
+
+#include <stdint.h>
+#include "ble.h"
+#include "ble_advdata.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**@brief Structure for storing all GAP parameters. */
+typedef struct
+{
+ uint16_t appearance;
+ uint8_t const * p_dev_name;
+ uint16_t dev_name_len;
+ ble_gap_conn_sec_mode_t sec_mode;
+ ble_gap_conn_params_t gap_conn_params;
+} ipv6_medium_ble_gap_params_t;
+
+/**@brief Structure for storing all advertisement parameters. */
+typedef struct
+{
+ ble_advdata_t advdata;
+ ble_advdata_manuf_data_t adv_man_specific_data;
+ ble_advdata_t srdata;
+ ble_advdata_manuf_data_t sr_man_specific_data;
+ ble_gap_adv_params_t advparams;
+} ipv6_medium_ble_adv_params_t;
+
+/**@brief Structure of BLE-specific parameters of events passed to the parent layer by the IPv6 medium. */
+typedef struct
+{
+ ble_evt_t * p_ble_evt;
+} ipv6_medium_ble_cb_params_t;
+
+/**@brief Structure of BLE-specific parameters of errors passed to the parent layer by the IPv6 medium. */
+typedef struct
+{
+ uint8_t dummy_value; // Parameters to be added.
+} ipv6_medium_ble_error_params_t;
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // IPV6_MEDIUM_BLE_H__
+
+/** @} */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/medium/ipv6_medium_platform_dummy.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/medium/ipv6_medium_platform_dummy.h
new file mode 100644
index 0000000..341d326
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/medium/ipv6_medium_platform_dummy.h
@@ -0,0 +1,54 @@
+/**
+ * Copyright (c) 2016 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#ifndef IPV6_MEDIUM_PLATFORM_DUMMY_H__
+#define IPV6_MEDIUM_PLATFORM_DUMMY_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef int ipv6_medium_cb_params_union_t;
+typedef int ipv6_medium_err_params_union_t;
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // IPV6_MEDIUM_PLATFORM_DUMMY_H__
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/mqtt/mqtt.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/mqtt/mqtt.c
new file mode 100644
index 0000000..ecb6fcd
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/mqtt/mqtt.c
@@ -0,0 +1,821 @@
+/**
+ * Copyright (c) 2015 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 mqtt.c
+ *
+ * @brief MQTT Client API Implementation.
+ */
+
+
+#include "mqtt.h"
+#include "mem_manager.h"
+#include "mqtt_transport.h"
+#include "mqtt_internal.h"
+#include "iot_timer.h"
+
+#if MQTT_CONFIG_LOG_ENABLED
+
+#define NRF_LOG_MODULE_NAME mqtt
+
+#define NRF_LOG_LEVEL MQTT_CONFIG_LOG_LEVEL
+#define NRF_LOG_INFO_COLOR MQTT_CONFIG_INFO_COLOR
+#define NRF_LOG_DEBUG_COLOR MQTT_CONFIG_DEBUG_COLOR
+
+#include "nrf_log.h"
+NRF_LOG_MODULE_REGISTER();
+
+#define MQTT_TRC NRF_LOG_DEBUG /**< Used for getting trace of execution in the module. */
+#define MQTT_ERR NRF_LOG_ERROR /**< Used for logging errors in the module. */
+#define MQTT_DUMP NRF_LOG_HEXDUMP_DEBUG /**< Used for dumping octet information to get details of bond information etc. */
+
+#define MQTT_ENTRY() MQTT_TRC(">> %s", __func__)
+#define MQTT_EXIT() MQTT_TRC("<< %s", __func__)
+
+#else // MQTT_CONFIG_LOG_ENABLED
+
+#define MQTT_TRC(...) /**< Disables traces. */
+#define MQTT_DUMP(...) /**< Disables dumping of octet streams. */
+#define MQTT_ERR(...) /**< Disables error logs. */
+
+#define MQTT_ENTRY(...)
+#define MQTT_EXIT(...)
+
+#endif // MQTT_CONFIG_LOG_ENABLED
+
+/**< Never changing ping request, needed for Keep Alive. */
+static const uint8_t m_ping_packet[MQTT_PKT_HEADER_SIZE] = \
+ {MQTT_PKT_TYPE_PINGREQ, \
+ 0x00};
+
+/**< Never changing disconnect request. */
+static const uint8_t m_disc_packet[MQTT_PKT_HEADER_SIZE] = \
+ {MQTT_PKT_TYPE_DISCONNECT, \
+ 0x00};
+
+static mqtt_client_t * m_mqtt_client[MQTT_MAX_CLIENTS]; /**< MQTT Client table. */
+SDK_MUTEX_DEFINE(m_mqtt_mutex) /**< Mutex variable for the module, currently unused. */
+
+
+static uint32_t get_client_index(mqtt_client_t * const p_client)
+{
+ for (uint32_t index = 0; index < MQTT_MAX_CLIENTS; index++)
+ {
+ if (m_mqtt_client[index] == p_client)
+ {
+ return index;
+ }
+ }
+
+ return MQTT_MAX_CLIENTS;
+}
+
+
+void client_free(mqtt_client_t * const p_client)
+{
+ MQTT_STATE_INIT(p_client);
+
+ // Free memory used for TX packets and reset the pointer.
+ nrf_free(p_client->p_packet);
+ p_client->p_packet = NULL;
+
+ // Free TLS instance and reset the instance.
+ UNUSED_VARIABLE(nrf_tls_free(&p_client->tls_instance));
+ NRF_TLS_INTSANCE_INIT(&p_client->tls_instance);
+}
+
+
+void client_init(mqtt_client_t * const p_client)
+{
+ memset(p_client, 0, sizeof(*p_client));
+
+ MQTT_STATE_INIT(p_client);
+
+ p_client->protocol_version = MQTT_VERSION_3_1_0;
+ p_client->clean_session = 1;
+
+ NRF_TLS_INTSANCE_INIT(&p_client->tls_instance);
+}
+
+
+/**@brief Notifies event to the application.
+ *
+ * @param[in] p_client Identifies the client for which the procedure is requested.
+ * @param[in] p_evt Reason for disconnection.
+ */
+void event_notify(mqtt_client_t * const p_client, const mqtt_evt_t * p_evt, uint32_t flags)
+{
+ const mqtt_evt_cb_t evt_cb = p_client->evt_cb;
+
+ if (evt_cb != NULL)
+ {
+ MQTT_MUTEX_UNLOCK();
+
+ evt_cb(p_client, p_evt);
+
+ MQTT_MUTEX_LOCK();
+
+ if (IS_SET(flags,MQTT_EVT_FLAG_INSTANCE_RESET))
+ {
+ client_init(p_client);
+ }
+ }
+}
+
+
+/**@brief Notifies disconnection event to the application.
+ *
+ * @param[in] p_client Identifies the client for which the procedure is requested.
+ * @param[in] result Reason for disconnection.
+ */
+void disconnect_event_notify(mqtt_client_t * p_client, uint32_t result)
+{
+ mqtt_evt_t evt;
+ const uint32_t client_index = get_client_index(p_client);
+
+ // Remove the client from internal table.
+ if (client_index != MQTT_MAX_CLIENTS)
+ {
+ m_mqtt_client[client_index] = NULL;
+ }
+
+ // Determine appropriate event to generate.
+ if (MQTT_VERIFY_STATE(p_client, MQTT_STATE_CONNECTED) ||
+ MQTT_VERIFY_STATE(p_client, MQTT_STATE_DISCONNECTING))
+ {
+ evt.id = MQTT_EVT_DISCONNECT;
+ evt.result = result;
+ }
+ else
+ {
+ evt.id = MQTT_EVT_CONNACK;
+ evt.result = MQTT_CONNECTION_FAILED;
+ }
+
+ // Free the instance.
+ client_free(p_client);
+
+ // Notify application.
+ event_notify(p_client, &evt, MQTT_EVT_FLAG_INSTANCE_RESET);
+}
+
+
+uint32_t mqtt_init(void)
+{
+ SDK_MUTEX_INIT(m_mqtt_mutex);
+
+ MQTT_MUTEX_LOCK();
+
+ memset(m_mqtt_client, 0, sizeof(m_mqtt_client));
+
+ MQTT_MUTEX_UNLOCK();
+
+ return nrf_tls_init();
+}
+
+
+void mqtt_client_init(mqtt_client_t * const p_client)
+{
+ NULL_PARAM_CHECK_VOID(p_client);
+
+ MQTT_MUTEX_LOCK();
+
+ client_init(p_client);
+
+ MQTT_MUTEX_UNLOCK();
+}
+
+
+uint32_t mqtt_connect(mqtt_client_t * const p_client)
+{
+ // Look for a free instance if available.
+ uint32_t err_code = NRF_SUCCESS;
+ uint32_t client_index = 0;
+
+ NULL_PARAM_CHECK(p_client);
+ NULL_PARAM_CHECK(p_client->client_id.p_utf_str);
+
+ MQTT_MUTEX_LOCK();
+
+ for (client_index = 0; client_index < MQTT_MAX_CLIENTS; client_index++)
+ {
+ if (m_mqtt_client[client_index] == NULL)
+ {
+ // Found a free instance.
+ m_mqtt_client[client_index] = p_client;
+
+ // Allocate buffer packets in TX path.
+ p_client->p_packet = nrf_malloc(MQTT_MAX_PACKET_LENGTH);
+ break;
+ }
+ }
+
+ if ((client_index == MQTT_MAX_CLIENTS) || (p_client->p_packet == NULL))
+ {
+ err_code = (NRF_ERROR_NO_MEM | IOT_MQTT_ERR_BASE);
+ }
+ else
+ {
+ err_code = tcp_request_connection(p_client);
+
+ if (err_code != NRF_SUCCESS)
+ {
+ // Free the instance.
+ m_mqtt_client[client_index] = NULL;
+ nrf_free(p_client->p_packet);
+ err_code = MQTT_ERR_TCP_PROC_FAILED;
+ }
+ }
+
+ UNUSED_VARIABLE(p_client);
+
+ MQTT_MUTEX_UNLOCK();
+
+ return err_code;
+}
+
+
+uint32_t mqtt_publish(mqtt_client_t * const p_client,
+ mqtt_publish_param_t const * const p_param)
+{
+ uint32_t err_code = MQTT_ERR_NOT_CONNECTED;
+ uint32_t offset = 0;
+ uint32_t mqtt_packetlen = 0;
+ uint8_t * p_payload;
+
+ NULL_PARAM_CHECK(p_client);
+ NULL_PARAM_CHECK(p_param);
+
+ MQTT_TRC("[CID %p]:[State 0x%02x]: >> %s Topic size 0x%08x, Data size 0x%08x",
+ p_client,
+ p_client->state,
+ __func__,
+ p_param->message.topic.topic.utf_strlen,
+ p_param->message.payload.bin_strlen);
+
+ MQTT_MUTEX_LOCK();
+
+ p_payload = &p_client->p_packet[MQTT_FIXED_HEADER_EXTENDED_SIZE];
+
+ if (MQTT_VERIFY_STATE(p_client, MQTT_STATE_PENDING_WRITE))
+ {
+ err_code = (NRF_ERROR_BUSY | IOT_MQTT_ERR_BASE);
+ }
+ else if (MQTT_VERIFY_STATE(p_client, MQTT_STATE_CONNECTED))
+ {
+ memset(p_payload, 0, MQTT_MAX_PACKET_LENGTH);
+
+ // Pack topic.
+ err_code = pack_utf8_str(&p_param->message.topic.topic,
+ MQTT_MAX_VARIABLE_HEADER_N_PAYLOAD,
+ p_payload,
+ &offset);
+
+ if (err_code == NRF_SUCCESS)
+ {
+ if (p_param->message.topic.qos)
+ {
+ err_code = pack_uint16(p_param->message_id,
+ MQTT_MAX_VARIABLE_HEADER_N_PAYLOAD,
+ p_payload,
+ &offset);
+ }
+ }
+ if (err_code == NRF_SUCCESS)
+ {
+ // Pack message on the topic.
+ err_code = pack_bin_str(&p_param->message.payload,
+ MQTT_MAX_VARIABLE_HEADER_N_PAYLOAD,
+ p_payload,
+ &offset);
+ }
+
+
+ if (err_code == NRF_SUCCESS)
+ {
+ const uint8_t message_type = MQTT_MESSAGES_OPTIONS(MQTT_PKT_TYPE_PUBLISH,
+ 0, // Duplicate flag not set.
+ p_param->message.topic.qos,
+ 0); // Retain flag not set.
+
+ mqtt_packetlen = mqtt_encode_fixed_header(message_type, // Message type
+ offset, // Payload size without the fixed header
+ &p_payload); // Address where the p_payload is contained.
+
+
+ // Publish message.
+ err_code = mqtt_transport_write(p_client, p_payload, mqtt_packetlen);
+ }
+ }
+
+ MQTT_TRC("<< %s", (uint32_t)__func__);
+
+ MQTT_MUTEX_UNLOCK();
+
+ return err_code;
+}
+
+
+/**@brief Encodes and sends messages that contain only message id in the variable header.
+ *
+ * @param[in] p_client Identifies the client for which the procedure is requested.
+ * @param[in] op_code Opcode for the message.
+ * @param[in] message_id Message id to be encoded in the variable header.
+ *
+ * @retval NRF_SUCCESS or an error code indicating a reason for failure.
+ */
+uint32_t mqtt_message_id_only_enc_n_send(mqtt_client_t * const p_client,
+ uint8_t opcode,
+ uint16_t message_id)
+{
+ uint32_t err_code = MQTT_ERR_NOT_CONNECTED;
+ uint32_t offset = 0;
+ uint32_t mqtt_packetlen = 0;
+ uint8_t * p_payload;
+
+ p_payload = &p_client->p_packet[MQTT_FIXED_HEADER_EXTENDED_SIZE];
+
+ if (MQTT_VERIFY_STATE(p_client, MQTT_STATE_PENDING_WRITE))
+ {
+ err_code = (NRF_ERROR_BUSY | IOT_MQTT_ERR_BASE);
+ }
+ else if (MQTT_VERIFY_STATE(p_client, MQTT_STATE_CONNECTED))
+ {
+ memset(p_payload, 0, MQTT_MAX_PACKET_LENGTH);
+
+ err_code = pack_uint16(message_id,
+ MQTT_MAX_VARIABLE_HEADER_N_PAYLOAD,
+ p_payload,
+ &offset);
+
+ if (err_code == NRF_SUCCESS)
+ {
+ const uint8_t message_type = MQTT_MESSAGES_OPTIONS(opcode,
+ 0, // Duplicate flag not set.
+ 0, // QoS unused.
+ 0); // Retain flag not set.
+
+ mqtt_packetlen = mqtt_encode_fixed_header(message_type, // Message type
+ offset, // Payload size without the fixed header
+ &p_payload); // Address where the p_payload is contained.
+
+ // Publish message.
+ err_code = mqtt_transport_write(p_client, p_payload, mqtt_packetlen);
+ }
+ }
+
+ return err_code;
+}
+
+
+/**@brief Sends raw message to the peer.
+ *
+ * @param[in] p_client Identifies the client for which the procedure is requested.
+ * @param[in] p_message Raw message to be sent to the peer.
+ * @param[in] message_id Message id to be encoded in the variable header.
+ *
+ * @retval NRF_SUCCESS or an error code indicating a reason for failure.
+ */
+uint32_t mqtt_raw_message_send(mqtt_client_t * const p_client,
+ const uint8_t * p_message,
+ uint16_t message_len)
+{
+ uint32_t err_code;
+
+ if (MQTT_VERIFY_STATE(p_client, MQTT_STATE_PENDING_WRITE))
+ {
+ err_code = (NRF_ERROR_BUSY | IOT_MQTT_ERR_BASE);
+ }
+ else if (MQTT_VERIFY_STATE(p_client, MQTT_STATE_CONNECTED))
+ {
+ err_code = mqtt_transport_write(p_client, p_message, message_len);
+ }
+ else
+ {
+ err_code = MQTT_ERR_NOT_CONNECTED;
+ }
+
+ return err_code;
+}
+
+
+uint32_t mqtt_publish_ack(mqtt_client_t * const p_client,
+ mqtt_puback_param_t const * p_param)
+{
+ NULL_PARAM_CHECK(p_client);
+ NULL_PARAM_CHECK(p_param);
+
+ MQTT_TRC("[CID %p]:[State 0x%02x]: >> %s Message id 0x%04x",
+ p_client,
+ p_client->state,
+ __func__,
+ p_param->message_id);
+
+ MQTT_MUTEX_LOCK();
+
+ uint32_t err_code = mqtt_message_id_only_enc_n_send(p_client,
+ MQTT_PKT_TYPE_PUBACK,
+ p_param->message_id);
+
+ MQTT_TRC("[CID %p]:[State 0x%02x]: << %s result 0x%08x",
+ p_client,
+ p_client->state,
+ __func__,
+ err_code);
+
+ MQTT_MUTEX_UNLOCK();
+
+ return err_code;
+}
+
+
+uint32_t mqtt_publish_receive(mqtt_client_t * const p_client,
+ mqtt_pubrec_param_t const * const p_param)
+{
+ NULL_PARAM_CHECK(p_client);
+ NULL_PARAM_CHECK(p_param);
+
+ MQTT_TRC("[CID %p]:[State 0x%02x]: >> %s Message id 0x%04x",
+ p_client,
+ p_client->state,
+ __func__,
+ p_param->message_id);
+
+ MQTT_MUTEX_LOCK();
+
+ uint32_t err_code = mqtt_message_id_only_enc_n_send(p_client,
+ MQTT_PKT_TYPE_PUBREC,
+ p_param->message_id);
+
+ MQTT_TRC("[CID %p]:[State 0x%02x]: << %s result 0x%08x",
+ p_client,
+ p_client->state,
+ __func__,
+ err_code);
+
+ MQTT_MUTEX_UNLOCK();
+
+ return err_code;
+}
+
+
+uint32_t mqtt_publish_release(mqtt_client_t * const p_client,
+ mqtt_pubrel_param_t const * const p_param)
+{
+ NULL_PARAM_CHECK(p_client);
+ NULL_PARAM_CHECK(p_param);
+
+ MQTT_TRC("[CID %p]:[State 0x%02x]: >> %s Message id 0x%04x",
+ p_client,
+ p_client->state,
+ __func__,
+ p_param->message_id);
+
+ MQTT_MUTEX_LOCK();
+
+ uint32_t err_code = mqtt_message_id_only_enc_n_send(p_client,
+ MQTT_PKT_TYPE_PUBREL,
+ p_param->message_id);
+
+ MQTT_TRC("[CID %p]:[State 0x%02x]: << %s result 0x%08x",
+ p_client,
+ p_client->state,
+ __func__,
+ err_code);
+
+ MQTT_MUTEX_UNLOCK();
+
+ return err_code;
+}
+
+
+uint32_t mqtt_publish_complete(mqtt_client_t * const p_client,
+ mqtt_pubcomp_param_t const * const p_param)
+{
+ NULL_PARAM_CHECK(p_client);
+ NULL_PARAM_CHECK(p_param);
+
+ MQTT_TRC("[CID %p]:[State 0x%02x]: >> %s Message id 0x%04x",
+ p_client,
+ p_client->state,
+ __func__,
+ p_param->message_id);
+
+ MQTT_MUTEX_LOCK();
+
+ uint32_t err_code = mqtt_message_id_only_enc_n_send(p_client,
+ MQTT_PKT_TYPE_PUBCOMP,
+ p_param->message_id);
+
+ MQTT_TRC("[CID %p]:[State 0x%02x]: << %s result 0x%08x",
+ p_client,
+ p_client->state,
+ __func__,
+ err_code);
+
+ MQTT_MUTEX_UNLOCK();
+
+ return err_code;
+}
+
+
+uint32_t mqtt_disconnect(mqtt_client_t * const p_client)
+{
+ uint32_t err_code = MQTT_ERR_NOT_CONNECTED;
+
+ NULL_PARAM_CHECK(p_client);
+
+ MQTT_MUTEX_LOCK();
+
+ err_code = mqtt_raw_message_send(p_client, m_disc_packet, MQTT_FIXED_HEADER_SIZE);
+
+ if (err_code == NRF_SUCCESS)
+ {
+ MQTT_SET_STATE_EXCLUSIVE(p_client, MQTT_STATE_DISCONNECTING);
+ }
+
+ MQTT_MUTEX_UNLOCK();
+
+ return err_code;
+}
+
+
+uint32_t mqtt_subscribe(mqtt_client_t * const p_client,
+ mqtt_subscription_list_t const * const p_param)
+{
+ uint32_t err_code = MQTT_ERR_NOT_CONNECTED;
+ uint32_t offset = 0;
+ uint32_t count = 0;
+ uint32_t mqtt_packetlen = 0;
+ uint8_t * p_payload;
+
+ NULL_PARAM_CHECK(p_client);
+ NULL_PARAM_CHECK(p_param);
+
+ MQTT_TRC("[CID %p]:[State 0x%02x]: >> %s message id 0x%04x topic count 0x%04x",
+ p_client,
+ p_client->state,
+ __func__,
+ p_param->message_id,
+ p_param->list_count);
+
+ MQTT_MUTEX_LOCK();
+
+ p_payload = &p_client->p_packet[MQTT_FIXED_HEADER_EXTENDED_SIZE];
+
+ if (MQTT_VERIFY_STATE(p_client, MQTT_STATE_PENDING_WRITE))
+ {
+ err_code = (NRF_ERROR_BUSY | IOT_MQTT_ERR_BASE);
+ }
+ else if (MQTT_VERIFY_STATE(p_client, MQTT_STATE_CONNECTED))
+ {
+ memset(p_payload, 0, MQTT_MAX_PACKET_LENGTH);
+
+ err_code = pack_uint16(p_param->message_id,
+ MQTT_MAX_VARIABLE_HEADER_N_PAYLOAD,
+ p_payload,
+ &offset);
+
+ if (err_code == NRF_SUCCESS)
+ {
+ do
+ {
+ err_code = pack_utf8_str(&p_param->p_list[count].topic,
+ MQTT_MAX_VARIABLE_HEADER_N_PAYLOAD,
+ p_payload,
+ &offset);
+ if (err_code == NRF_SUCCESS)
+ {
+ err_code = pack_uint8(p_param->p_list[count].qos,
+ MQTT_MAX_VARIABLE_HEADER_N_PAYLOAD,
+ p_payload,
+ &offset);
+ }
+ count++;
+ } while ((err_code != NRF_SUCCESS) || (count < p_param->list_count));
+ }
+
+ if (err_code == NRF_SUCCESS)
+ {
+ const uint8_t message_type = MQTT_MESSAGES_OPTIONS(MQTT_PKT_TYPE_SUBSCRIBE, 0, 1, 0);
+
+ // Rewind the packet to encode the packet correctly.
+ mqtt_packetlen = mqtt_encode_fixed_header(message_type, // Message type, Duplicate Flag, QoS and retain flag setting.
+ offset, // p_payload size without the fixed header
+ &p_payload); // Address where the p_payload is contained. Header will encoded by rewinding the location.
+ // Send message.
+ err_code = mqtt_transport_write(p_client, p_payload, mqtt_packetlen);
+ }
+ }
+
+ MQTT_TRC("[CID %p]:[State 0x%02x]: << %s result 0x%08x",
+ p_client,
+ p_client->state,
+ __func__,
+ err_code);
+
+ MQTT_MUTEX_UNLOCK();
+
+ return err_code;
+}
+
+
+uint32_t mqtt_unsubscribe(mqtt_client_t * const p_client,
+ mqtt_subscription_list_t const * const p_param)
+{
+ uint32_t err_code = MQTT_ERR_NOT_CONNECTED;
+ uint32_t count = 0;
+ uint32_t offset = 0;
+ uint32_t mqtt_packetlen = 0;
+ uint8_t * p_payload;
+
+ NULL_PARAM_CHECK(p_client);
+ NULL_PARAM_CHECK(p_param);
+
+ MQTT_MUTEX_LOCK();
+
+ p_payload = &p_client->p_packet[MQTT_FIXED_HEADER_EXTENDED_SIZE];
+
+ if (MQTT_VERIFY_STATE(p_client, MQTT_STATE_PENDING_WRITE))
+ {
+ err_code = (NRF_ERROR_BUSY | IOT_MQTT_ERR_BASE);
+ }
+ else if (MQTT_VERIFY_STATE(p_client, MQTT_STATE_CONNECTED))
+ {
+ memset(p_payload, 0, MQTT_MAX_PACKET_LENGTH);
+
+ err_code = pack_uint16(p_param->message_id,
+ MQTT_MAX_PACKET_LENGTH,
+ p_payload,
+ &offset);
+
+ if (err_code == NRF_SUCCESS)
+ {
+ do
+ {
+ err_code = pack_utf8_str(&p_param->p_list[count].topic,
+ MQTT_MAX_VARIABLE_HEADER_N_PAYLOAD,
+ p_payload,
+ &offset);
+ count++;
+ } while ((err_code != NRF_SUCCESS) || (count < p_param->list_count));
+ }
+
+ if (err_code == NRF_SUCCESS)
+ {
+ const uint8_t message_type = MQTT_MESSAGES_OPTIONS(MQTT_PKT_TYPE_UNSUBSCRIBE,
+ 0, // Duplicate flag.
+ MQTT_QoS_1_ATLEAST_ONCE,
+ 0); // Retain flag.
+
+ // Rewind the packet to encode the packet correctly.
+ mqtt_packetlen = mqtt_encode_fixed_header(message_type, // Message type, Duplicate Flag, QoS and retain flag setting.
+ offset, // Payload size without the fixed header
+ &p_payload); // Address where the p_payload is contained. Header will encoded by rewinding the location.
+
+ // Send message.
+ err_code = mqtt_transport_write(p_client, p_payload, mqtt_packetlen);
+ }
+ }
+
+ MQTT_MUTEX_UNLOCK();
+
+ return err_code;
+}
+
+
+uint32_t mqtt_ping(mqtt_client_t * const p_client)
+{
+ uint32_t err_code;
+
+ NULL_PARAM_CHECK(p_client);
+
+ MQTT_MUTEX_LOCK();
+
+ err_code = mqtt_raw_message_send(p_client, m_ping_packet, MQTT_PKT_HEADER_SIZE);
+
+ MQTT_MUTEX_UNLOCK();
+
+ return err_code;
+}
+
+
+uint32_t mqtt_abort(mqtt_client_t * const p_client)
+{
+ MQTT_MUTEX_LOCK();
+
+ NULL_PARAM_CHECK(p_client);
+
+ if (p_client->state != MQTT_STATE_IDLE)
+ {
+ mqtt_client_tcp_abort(p_client);
+ }
+
+ MQTT_MUTEX_UNLOCK();
+
+ return NRF_SUCCESS;
+}
+
+
+uint32_t mqtt_live(void)
+{
+ iot_timer_time_in_ms_t elapsed_time;
+ uint32_t index;
+
+ // Note: The module should not be locked when calling this TLS API.
+ nrf_tls_process();
+
+ MQTT_MUTEX_LOCK();
+
+ for (index = 0; index < MQTT_MAX_CLIENTS; index++)
+ {
+ mqtt_client_t * p_client = m_mqtt_client[index];
+ if (p_client != NULL)
+ {
+ UNUSED_VARIABLE(iot_timer_wall_clock_delta_get(&p_client->last_activity,
+ &elapsed_time));
+
+ if ((MQTT_KEEPALIVE > 0) && (elapsed_time > ((MQTT_KEEPALIVE - 2) * 1000)))
+ {
+ UNUSED_VARIABLE(mqtt_ping(p_client));
+ }
+ if (p_client->p_pending_packet != NULL)
+ {
+ uint32_t err;
+ err = mqtt_transport_write(p_client, p_client->p_pending_packet,
+ p_client->pending_packetlen);
+
+ if (err == NRF_SUCCESS)
+ {
+ p_client->p_pending_packet = NULL;
+ p_client->pending_packetlen = 0;
+ }
+ }
+ }
+ }
+
+ MQTT_MUTEX_UNLOCK();
+
+ return NRF_SUCCESS;
+}
+
+
+uint32_t mqtt_input(mqtt_client_t * p_client, uint32_t timeout)
+{
+ uint32_t err_code;
+
+ NULL_PARAM_CHECK(p_client);
+
+ MQTT_MUTEX_LOCK();
+
+ MQTT_TRC("%s: 0x%08x", __func__, p_client->state);
+
+ if (MQTT_VERIFY_STATE(p_client, MQTT_STATE_TCP_CONNECTED) ||
+ MQTT_VERIFY_STATE(p_client, MQTT_STATE_DISCONNECTING))
+ {
+ err_code = tcp_receive_packet(p_client, timeout);
+ }
+ else
+ {
+ err_code = (NRF_ERROR_INVALID_STATE | IOT_MQTT_ERR_BASE);
+ }
+
+ MQTT_MUTEX_UNLOCK();
+
+ return err_code;
+}
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/mqtt/mqtt.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/mqtt/mqtt.h
new file mode 100644
index 0000000..980426a
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/mqtt/mqtt.h
@@ -0,0 +1,506 @@
+/**
+ * Copyright (c) 2015 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 mqtt.h
+ *
+ * @defgroup iot_sdk_mqtt_api MQTT Client on nRF5x
+ * @ingroup iot_sdk_mqtt
+ * @{
+ * @brief MQTT Client Implementation on the Nordic nRF platforms.
+ *
+ * @details
+ * MQTT Client's Application interface is defined in this header.
+ *
+ * @note The implementation assumes LwIP Stack is available with TCP module enabled.
+ *
+ * @note By default the implementation uses MQTT version 3.1.0.
+ * However few cloud services like the Xively use the version 3.1.1.
+ * For this please set p_client.protocol_version = MQTT_VERSION_3_1_1.
+ */
+
+#ifndef MQTT_H_
+#define MQTT_H_
+
+#include <stdint.h>
+#include "iot_defines.h"
+#include "iot_timer.h"
+#include "nrf_tls.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**@brief MQTT Asynchronous Events notified to the application from the module
+ * through the callback registered by the application. */
+typedef enum
+{
+ MQTT_EVT_CONNACK, /**< Acknowledgment of connection request. Event result accompanying the event indicates whether the connection failed or succeeded. */
+ MQTT_EVT_DISCONNECT, /**< Disconnection Event. MQTT Client Reference is no longer valid once this event is received for the client. */
+ MQTT_EVT_PUBLISH, /**< Publish event received when message is published on a topic client is subscribed to. */
+ MQTT_EVT_PUBACK, /**< Acknowledgment for published message with QoS 1. */
+ MQTT_EVT_PUBREC, /**< Reception confirmation for published message with QoS 2. */
+ MQTT_EVT_PUBREL, /**< Release of published published messages with QoS 2. */
+ MQTT_EVT_PUBCOMP, /**< Confirmation to a publish release message. Applicable only to QoS 2 messages. */
+ MQTT_EVT_SUBACK, /**< Acknowledgment to a subscription request. */
+ MQTT_EVT_UNSUBACK /**< Acknowledgment to a unsubscription request. */
+} mqtt_evt_id_t;
+
+/**@brief MQTT version protocol level. */
+typedef enum
+{
+ MQTT_VERSION_3_1_0 = 3, /**< Protocol level for 3.1.0. */
+ MQTT_VERSION_3_1_1 = 4 /**< Protocol level for 3.1.1. */
+} mqtt_version_t;
+
+/**@brief MQTT transport type. */
+typedef enum
+{
+ MQTT_TRANSPORT_NON_SECURE = 0x00, /**< Use non secure TCP transport for MQTT connection. */
+ MQTT_TRANSPORT_SECURE = 0x01, /**< Use secure TCP transport (TLS) for MQTT connection. */
+ MQTT_TRANSPORT_MAX = 0x02 /**< Shall not be used as a transport type. Indicator of maximum transport types possible. */
+} mqtt_transport_type_t;
+
+/**@brief MQTT Quality of Service types. */
+typedef enum
+{
+ MQTT_QoS_0_AT_MOST_ONCE = 0x00, /**< Lowest Quality of Service, no acknowledgment needed for published message. */
+ MQTT_QoS_1_ATLEAST_ONCE = 0x01, /**< Medium Quality of Service, if acknowledgment expected for published message, duplicate messages permitted. */
+ MQTT_QoS_2_EACTLY_ONCE = 0x02 /**< Highest Quality of Service, acknowledgment expected and message shall be published only once. Message not published to interested parties unless client issues a PUBREL. */
+} mqtt_qos_t;
+
+/**@brief MQTT Asynchronous Events notified to the application from the module
+ * through the callback registered by the application. */
+typedef enum
+{
+ MQTT_CONNECTION_ACCEPTED = 0x00, /**< Connection accepted. */
+ MQTT_UNACCEPTABLE_PROTOCOL_VERSION = 0x01, /**< The Server does not support the level of the MQTT protocol requested by the Client. */
+ MQTT_IDENTIFIER_REJECTED = 0x02, /**< The Client identifier is correct UTF-8 but not allowed by the Server. */
+ MQTT_SERVER_UNAVAILABLE = 0x03, /**< The Network Connection has been made but the MQTT service is unavailable. */
+ MQTT_BAD_USER_NAME_OR_PASSWORD = 0x04, /**< The data in the user name or password is malformed. */
+ MQTT_NOT_AUTHORIZED = 0x05 /**< The Client is not authorized to connect. */
+} mqtt_conn_return_code_t;
+
+/**@brief MQTT client forward declaration @ref mqtt_client_t for details. */
+typedef struct mqtt_client_t mqtt_client_t;
+
+/**@brief Abstracts UTF-8 encoded strings. */
+typedef struct
+{
+ uint8_t * p_utf_str; /**< Pointer to UTF-8 string. */
+ uint32_t utf_strlen; /**< Length of UTF string. */
+} mqtt_utf8_t;
+
+/**@brief Abstracts binary strings. */
+typedef struct
+{
+ uint8_t * p_bin_str; /**< Pointer to binary stream. */
+ uint32_t bin_strlen; /**< Length of binary stream. */
+} mqtt_binstr_t;
+
+/**@brief Abstracts MQTT UTF-8 encoded topic that can be subscribed to or published. */
+typedef struct
+{
+ mqtt_utf8_t topic; /**< Topic on to be published or subscribed to. */
+ uint8_t qos; /**< Quality of service requested for the subscription. @ref mqtt_qos_t for details. */
+} mqtt_topic_t;
+
+/**@brief Abstracts MQTT UTF-8 encoded unique client identifier. */
+typedef mqtt_utf8_t mqtt_client_id_t;
+
+/**@brief Abstracts MQTT UTF-8 encoded password to be used for the client connection. */
+typedef mqtt_utf8_t mqtt_password_t;
+
+/**@brief Abstracts MQTT UTF-8 encoded user name to be used for the client connection. */
+typedef mqtt_utf8_t mqtt_username_t;
+
+/**@brief Abstracts will message used in @ref mqtt_connect request.
+ *
+ * @note utf8 is used here instead of binary string as a zero length encoding is expected in
+ * will message is empty.
+ */
+typedef mqtt_utf8_t mqtt_will_message_t;
+
+/**@brief Abstracts message in binary encoded string received or published on a topic. */
+typedef mqtt_binstr_t mqtt_message_t;
+
+/**@brief Parameters for a publish message. */
+typedef struct
+{
+ mqtt_topic_t topic; /**< Topic on which data was published. */
+ mqtt_message_t payload; /**< Payload on the topic published. */
+} mqtt_publish_message_t;
+
+/**@brief Parameters for a connection acknowledgment (connack). */
+typedef struct
+{
+ uint8_t session_present_flag; /**< The Session Present flag enables a Client to establish whether the Client and Server have a consistent view about whether there is already stored Session state. */
+ mqtt_conn_return_code_t return_code; /**< The appropriate non-zero Connect return code indicates if the Server is unable to process a connection request for some reason. */
+} mqtt_connack_param_t;
+
+/**@brief Parameters for MQTT publish acknowledgment(puback). */
+typedef struct
+{
+ uint16_t message_id;
+} mqtt_puback_param_t;
+
+/**@brief Parameters for MQTT publish receive(pubrec). */
+typedef struct
+{
+ uint16_t message_id;
+} mqtt_pubrec_param_t;
+
+/**@brief Parameters for MQTT publish release(pubrec). */
+typedef struct
+{
+ uint16_t message_id;
+} mqtt_pubrel_param_t;
+
+/**@brief Parameters for MQTT publish complete(pubcomp). */
+typedef struct
+{
+ uint16_t message_id;
+} mqtt_pubcomp_param_t;
+
+/**@brief Parameters for MQTT subscription acknowledgment (suback). */
+typedef struct
+{
+ uint16_t message_id;
+} mqtt_suback_param_t;
+
+/**@brief Parameters for MQTT unsubscription acknowledgment (unsuback). */
+typedef struct
+{
+ uint16_t message_id;
+} mqtt_unsuback_param_t;
+
+/**@brief Parameters for a publish message. */
+typedef struct
+{
+ mqtt_publish_message_t message; /**< Messages including topic, QoS and its payload (if any) to be published. */
+ uint16_t message_id; /**< Message id used for the publish message. Redundant for QoS 0. */
+ uint8_t dup_flag:1; /**< Duplicate flag. If 1, it indicates the message is being retransmitted. Has no meaning with QoS 0. */
+ uint8_t retain_flag:1; /**< retain flag. If 1, the message shall be stored persistently by the broker. */
+} mqtt_publish_param_t;
+
+/**@brief List of topics in a subscription request. */
+typedef struct
+{
+ mqtt_topic_t * p_list; /**< Array containing topics along with QoS for each. */
+ uint32_t list_count; /**< Number of topics in the subscription list */
+ uint16_t message_id; /**< Message id used to identify subscription request. */
+} mqtt_subscription_list_t;
+
+/**
+ * @brief Defines event parameters notified along with asynchronous events to the application.
+ * Currently, only MQTT_EVT_PUBLISH is accompanied with parameters.
+ */
+typedef union
+{
+ mqtt_connack_param_t connack; /**< Parameters accompanying MQTT_EVT_CONNACK event. */
+ mqtt_publish_param_t publish; /**< Parameters accompanying MQTT_EVT_PUBLISH event. */
+ mqtt_puback_param_t puback; /**< Parameters accompanying MQTT_EVT_PUBACK event. */
+ mqtt_pubrec_param_t pubrec; /**< Parameters accompanying MQTT_EVT_PUBREC event. */
+ mqtt_pubrel_param_t pubrel; /**< Parameters accompanying MQTT_EVT_PUBREL event. */
+ mqtt_pubcomp_param_t pubcomp; /**< Parameters accompanying MQTT_EVT_PUBCOMP event. */
+ mqtt_suback_param_t suback; /**< Parameters accompanying MQTT_EVT_SUBACK event. */
+ mqtt_suback_param_t unsuback; /**< Parameters accompanying MQTT_EVT_UNSUBACK event. */
+} mqtt_evt_param_t;
+
+/**@brief Defined MQTT asynchronous event notified to the application. */
+typedef struct
+{
+ mqtt_evt_id_t id; /**< Identifies the event. */
+ mqtt_evt_param_t param; /**< Contains parameters (if any) accompanying the event. */
+ uint32_t result; /**< Event result. For example, MQTT_EVT_CONNACK has a result code indicating success or failure code of connection procedure. */
+} mqtt_evt_t;
+
+/**@brief Asynchronous event notification callback registered by the application with
+ * the module to receive module events.
+ *
+ * @param[in] p_client Identifies the client for which the event is notified.
+ * @param[in] p_evet Event description along with result and associated parameters (if any).
+ */
+typedef void (*mqtt_evt_cb_t)(mqtt_client_t * const p_client, const mqtt_evt_t * p_evt);
+
+/**@brief MQTT Client definition to maintain information relevant to the client. */
+struct mqtt_client_t
+{
+ mqtt_client_id_t client_id; /**< Unique client identification to be used for the connection. Shall be zero length or NULL valued. */
+ mqtt_username_t * p_user_name; /**< User name (if any) to be used for the connection. NULL indicates no user name. */
+ mqtt_password_t * p_password; /**< Password (if any) to be used for the connection. Note that if password is provided, user name shall also be provided. NULL indicates no password. */
+ mqtt_topic_t * p_will_topic; /**< Will topic and QoS. Can be NULL. */
+ mqtt_will_message_t * p_will_message; /**< Will message. Can be NULL. Non NULL value valid only if will topic is not NULL. */
+ nrf_tls_key_settings_t * p_security_settings; /**< Provide security settings like PSK, own certificate etc here. The memory provided for the settings shall be resident. */
+ mqtt_evt_cb_t evt_cb; /**< Application callback registered with the module to get MQTT events. */
+ ipv6_addr_t broker_addr; /**< IPv6 Address of MQTT broker to which client connection is requested. */
+ uint16_t broker_port; /**< Broker's Port number. */
+ uint8_t poll_abort_counter; /**< Poll abort counter maintained for the TCP connection. */
+ uint8_t protocol_version; /**< MQTT protocol version. */
+ uint8_t transport_type; /**< Transport type selection for client instance. @ref mqtt_transport_type_t for possible values. MQTT_TRANSPORT_MAX is not a valid type.*/
+ uint8_t will_retain:1; /**< Will retain flag, 1 if will message shall be retained persistently. */
+ uint8_t clean_session:1; /**< Clean session flag indicating a fresh (1) or a retained session (0). Default is 1. */
+ iot_timer_time_in_ms_t last_activity; /**< Internal. Ticks maintaining wallcock in last activity that occurred. Needed for periodic PING. */
+ uint32_t state; /**< Internal. Shall not be touched by the application. Client's state in the connection. */
+ int socket_fd; /**< Internal. Shall not be touched by the application. TCP socket file descriptor. */
+ uint32_t tcp_id; /**< Internal. Shall not be touched by the application. TCP Connection Reference provided by the IP stack. */
+ uint8_t * p_packet; /**< Internal. Shall not be touched by the application. Used for creating MQTT packet in TX path. */
+ uint8_t * p_pending_packet; /**< Internal. Shall not be touched by the application. */
+ nrf_tls_instance_t tls_instance; /**< Internal. Shall not be touched by the application. TLS instance identifier. Valid only if transport is a secure one. */
+ uint32_t pending_packetlen; /**< Internal. Shall not be touched by the application. */
+};
+
+
+/**
+ * @brief Initializes the module.
+ *
+ * @retval NRF_SUCCESS or an error code indicating reason for failure.
+ *
+ * @note Shall be called before initiating any procedures on the module.
+ * @note If module initialization fails, no module APIs shall be called.
+ */
+uint32_t mqtt_init(void);
+
+
+/**
+ * @brief Initializes the client instance.
+ *
+ * @param[in] p_client Client instance for which the procedure is requested.
+ * Shall not be NULL.
+ *
+ * @note Shall be called before connecting the client in order to avoid unexpected behavior
+ * caused by uninitialized parameters.
+ */
+void mqtt_client_init(mqtt_client_t * const p_client);
+
+
+/**
+ * @brief API to request new MQTT client connection.
+ *
+ * @param[out] p_client Client instance for which the procedure is requested.
+ * Shall not be NULL.
+ *
+ * @note This memory is assumed to be resident until mqtt_disconnect is called.
+ * @note Any subsequent changes to parameters like broker address, user name, device id, etc. have
+ * no effect once MQTT connection is established.
+ *
+ * @retval NRF_SUCCESS or an error code indicating reason for failure.
+ *
+ * @note Default protocol revision used for connection request is 3.1.0. Please set
+ * p_client.protocol_version = MQTT_VERSION_3_1_1 to use protocol 3.1.1.
+ * @note If more than one simultaneous client connections are needed, please define
+ * MQTT_MAX_CLIENTS to override default of 1.
+ * @note Please define MQTT_KEEPALIVE time to override default of 1 minute.
+ * @note Please define MQTT_MAX_PACKET_LENGTH time to override default of 128 bytes.
+ * Ensure the system has enough memory for the new length per client.
+ */
+uint32_t mqtt_connect(mqtt_client_t * const p_client);
+
+
+/**
+ * @brief API to publish messages on topics.
+ *
+ * @param[in] p_client Client instance for which the procedure is requested.
+ * Shall not be NULL.
+ * @param[in] p_param Parameters to be used for the publish message.
+ * Shall not be NULL.
+ *
+ * @retval NRF_SUCCESS or an error code indicating reason for failure.
+ *
+ * @note Default protocol revision used for connection request is 3.1.0. Please set
+ * p_client.protocol_version = MQTT_VERSION_3_1_1 to use protocol 3.1.1.
+ */
+uint32_t mqtt_publish(mqtt_client_t * const p_client,
+ mqtt_publish_param_t const * const p_param);
+
+
+/**
+ * @brief API used by subscribing client to send acknowledgment to the broker.
+ * Applicable only to QoS 1 publish messages.
+ *
+ * @param[in] p_client Client instance for which the procedure is requested.
+ * Shall not be NULL.
+ * @param[in] p_param Identifies message being acknowledged.
+ *
+ * @retval NRF_SUCCESS or an error code indicating reason for failure.
+ *
+ * @note Default protocol revision used for connection request is 3.1.0. Please set
+ * p_client.protocol_version = MQTT_VERSION_3_1_1 to use protocol 3.1.1.
+ */
+uint32_t mqtt_publish_ack(mqtt_client_t * const p_client,
+ mqtt_puback_param_t const * const p_param);
+
+
+/**
+ * @brief API to send assured acknowledgment from a subscribing client to the broker.
+ * Should be called on reception of @ref MQTT_EVT_PUBLISH with QoS set to
+ * @ref MQTT_QoS_2_EACTLY_ONCE.
+ *
+ * @param[in] p_client Identifies client instance for which the procedure is requested.
+ * Shall not be NULL.
+ * @param[in] p_param Identifies message being acknowledged.
+ *
+ * @retval NRF_SUCCESS or an error code indicating reason for failure.
+ *
+ * @note Default protocol revision used for connection request is 3.1.0. Please set
+ * p_client.protocol_version = MQTT_VERSION_3_1_1 to use protocol 3.1.1.
+ */
+uint32_t mqtt_publish_receive(mqtt_client_t * const p_client,
+ mqtt_pubrec_param_t const * const p_param);
+
+
+/**
+ * @brief API to used by publishing client to request releasing published data.
+ * Shall be used only after @ref MQTT_EVT_PUBREC is received and is valid
+ * only for QoS level @ref MQTT_QoS_2_EACTLY_ONCE.
+ *
+ * @param[in] p_client Client instance for which the procedure is requested.
+ * Shall not be NULL.
+ * @param[in] p_param Identifies message being released.
+ *
+ * @retval NRF_SUCCESS or an error code indicating reason for failure.
+ *
+ * @note Default protocol revision used for connection request is 3.1.0. Please set
+ * p_client.protocol_version = MQTT_VERSION_3_1_1 to use protocol 3.1.1.
+ */
+uint32_t mqtt_publish_release(mqtt_client_t * const p_client,
+ mqtt_pubrel_param_t const * const p_param);
+
+
+/**
+ * @brief API used by subscribing clients to acknowledge reception of a released message.
+ * Should be used on reception @ref MQTT_EVT_PUBREL event.
+ *
+ * @param[in] p_client Identifies client instance for which the procedure is requested.
+ * Shall not be NULL.
+ * @param[in] p_param Identifies message being completed.
+ *
+ * @retval NRF_SUCCESS or an error code indicating reason for failure.
+ *
+ * @note Default protocol revision used for connection request is 3.1.0. Please set
+ * p_client.protocol_version = MQTT_VERSION_3_1_1 to use protocol 3.1.1.
+ */
+uint32_t mqtt_publish_complete(mqtt_client_t * const p_client,
+ mqtt_pubcomp_param_t const * const p_param);
+
+
+/**
+ * @brief API to request subscribing to a topic on the connection.
+ *
+ * @param[in] p_client Identifies client instance for which the procedure is requested.
+ * Shall not be NULL.
+ * @param[in] p_param Subscription parameters. Shall not be NULL.
+ *
+ * @retval NRF_SUCCESS or an error code indicating reason for failure.
+ */
+uint32_t mqtt_subscribe(mqtt_client_t * const p_client,
+ mqtt_subscription_list_t const * const p_param);
+
+
+/**
+ * @brief API to request un-subscribe from a topic on the connection.
+ *
+ * @param[in] p_client Identifies client instance for which the procedure is requested.
+ * Shall not be NULL.
+ * @param[in] p_param Parameters describing topics being unsubscribed from.
+ * Shall not be NULL.
+ *
+ * @note QoS included in topic description is unused in this API.
+ *
+ * @retval NRF_SUCCESS or an error code indicating reason for failure.
+ */
+uint32_t mqtt_unsubscribe(mqtt_client_t * const p_client,
+ mqtt_subscription_list_t const * const p_param);
+
+
+/**
+ * @brief API to abort MQTT connection.
+ *
+ * @param[in] p_client Identifies client instance for which procedure is requested.
+ *
+ * @retval NRF_SUCCESS or an error code indicating reason for failure.
+ */
+uint32_t mqtt_abort(mqtt_client_t * const p_client);
+
+
+/**
+ * @brief API to disconnect MQTT connection.
+ *
+ * @param[in] p_client Identifies client instance for which procedure is requested.
+ *
+ * @retval NRF_SUCCESS or an error code indicating reason for failure.
+ */
+uint32_t mqtt_disconnect(mqtt_client_t * const p_client);
+
+
+/**
+ * @brief This API should be called periodically for the module to be able to keep the connection
+ * alive by sending Ping Requests if need be.
+ *
+ * @note Application shall ensure that the periodicity of calling this function makes it possible to
+ * respect the Keep Alive time agreed with the broker on connection.
+ * @ref mqtt_connect for details on Keep Alive time.
+ *
+ * @retval NRF_SUCCESS or an result code indicating reason for failure.
+ */
+uint32_t mqtt_live(void);
+
+
+/**
+ * @brief Wait for an incoming MQTT packet.
+ * The registered callback will be called with the packet payload.
+ *
+ * @param[in] p_client Client instance for which the procedure is requested.
+ * Shall not be NULL.
+ * @param[in] timeout Maximum interval (in milliseconds) to wait for a packet.
+ * If timeout is 0, the interval is indefinitely.
+ *
+ * @retval NRF_SUCCESS or an error code indicating reason for failure.
+ *
+ * @note This API is only supported when using the socket transport layer.
+ */
+uint32_t mqtt_input(mqtt_client_t * const p_client, uint32_t timeout);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // MQTT_H_
+
+/**@} */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/mqtt/mqtt_decoder.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/mqtt/mqtt_decoder.c
new file mode 100644
index 0000000..4a95865
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/mqtt/mqtt_decoder.c
@@ -0,0 +1,262 @@
+/**
+ * Copyright (c) 2015 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 mqtt_decoder.c
+ *
+ * @brief Decoder functions needs for decoding packets received from the broker.
+ */
+
+#include "mqtt_internal.h"
+
+#if MQTT_CONFIG_LOG_ENABLED
+
+#define NRF_LOG_MODULE_NAME mqtt_dec
+
+#define NRF_LOG_LEVEL MQTT_CONFIG_LOG_LEVEL
+#define NRF_LOG_INFO_COLOR MQTT_CONFIG_INFO_COLOR
+#define NRF_LOG_DEBUG_COLOR MQTT_CONFIG_DEBUG_COLOR
+
+#include "nrf_log.h"
+NRF_LOG_MODULE_REGISTER();
+
+#define MQTT_TRC NRF_LOG_DEBUG /**< Used for getting trace of execution in the module. */
+#define MQTT_ERR NRF_LOG_ERROR /**< Used for logging errors in the module. */
+#define MQTT_DUMP NRF_LOG_HEXDUMP_DEBUG /**< Used for dumping octet information to get details of bond information etc. */
+
+#define MQTT_ENTRY() MQTT_TRC(">> %s", __func__)
+#define MQTT_EXIT() MQTT_TRC("<< %s", __func__)
+
+#else // MQTT_CONFIG_LOG_ENABLED
+
+#define MQTT_TRC(...) /**< Disables traces. */
+#define MQTT_DUMP(...) /**< Disables dumping of octet streams. */
+#define MQTT_ERR(...) /**< Disables error logs. */
+
+#define MQTT_ENTRY(...)
+#define MQTT_EXIT(...)
+
+#endif // MQTT_CONFIG_LOG_ENABLED
+
+#define MQTT_LENGTH_VALUE_MASK 0x7F
+#define MQTT_LENGTH_CONTINUATION_BIT 0x80
+#define MQTT_LENGTH_MULTIPLIER 0x80
+
+
+uint32_t unpack_uint8(uint8_t * p_val,
+ uint32_t buffer_len,
+ uint8_t * const buffer,
+ uint32_t * const p_offset)
+{
+ uint32_t err_code = NRF_ERROR_DATA_SIZE;
+
+ if (buffer_len > (*p_offset))
+ {
+ const uint32_t available_len = buffer_len - (*p_offset);
+
+ MQTT_TRC(">> %s BL:%08x, B:%p, O:%08x A:%08x", __func__,
+ buffer_len, buffer, (*p_offset), available_len);
+
+ if (available_len >= SIZE_OF_UINT8)
+ {
+ // Create unit8 value.
+ (*p_val) = buffer[*p_offset];
+
+ // Increment offset.
+ (*p_offset) += SIZE_OF_UINT8;
+
+ // Indicate success.
+ err_code = NRF_SUCCESS;
+ }
+ }
+
+ MQTT_TRC("<< %s result:0x%08x val:0x%02x", __func__, err_code, (*p_val));
+ return err_code;
+}
+
+
+uint32_t unpack_uint16(uint16_t * p_val,
+ uint32_t buffer_len,
+ uint8_t * const buffer,
+ uint32_t * const p_offset)
+{
+ uint32_t err_code = NRF_ERROR_DATA_SIZE;
+
+ if (buffer_len > (*p_offset))
+ {
+ const uint32_t available_len = buffer_len - (*p_offset);
+
+ MQTT_TRC(">> %s BL:%08x, B:%p, O:%08x A:%08x", __func__,
+ buffer_len, buffer, (*p_offset), available_len);
+
+ if (available_len >= SIZE_OF_UINT16)
+ {
+ // Create unit16 value.
+ (*p_val) = ((buffer[*p_offset] & 0x00FF) << 8); // MSB
+ (*p_val) |= (buffer[(*p_offset+1)] & 0x00FF); // LSB
+
+ // Increment offset.
+ (*p_offset) += SIZE_OF_UINT16;
+
+ // Indicate success.
+ err_code = NRF_SUCCESS;
+ }
+ }
+
+ MQTT_TRC("<< %s result:0x%08x val:0x%04x", __func__, err_code, (*p_val));
+
+ return err_code;
+}
+
+
+uint32_t unpack_utf8_str(mqtt_utf8_t * const p_str,
+ uint32_t buffer_len,
+ uint8_t * const buffer,
+ uint32_t * const p_offset)
+{
+ uint16_t utf8_strlen;
+ uint32_t err_code = unpack_uint16(&utf8_strlen, buffer_len, buffer, p_offset);
+
+ p_str->p_utf_str = NULL;
+ p_str->utf_strlen = 0;
+
+ if (err_code == NRF_SUCCESS)
+ {
+ const uint32_t available_len = buffer_len - (*p_offset);
+
+ MQTT_TRC(">> %s BL:%08x, B:%p, O:%08x A:%08x", __func__,
+ buffer_len, buffer, (*p_offset), available_len);
+
+ if (utf8_strlen <= available_len)
+ {
+ // Zero length UTF8 strings permitted.
+ if (utf8_strlen)
+ {
+ // Point to right location in buffer.
+ p_str->p_utf_str = &buffer[(*p_offset)];
+ }
+
+ // Populate length field.
+ p_str->utf_strlen = utf8_strlen;
+
+ // Increment offset.
+ (*p_offset) += utf8_strlen;
+
+ // Indicate success
+ err_code = NRF_SUCCESS;
+ }
+ else
+ {
+ // Reset to original value.
+ (*p_offset) -= SIZE_OF_UINT16;
+
+ err_code = NRF_ERROR_DATA_SIZE;
+ }
+ }
+
+ MQTT_TRC("<< %s result:0x%08x utf8 len:0x%08x", __func__, err_code, p_str->utf_strlen);
+
+ return err_code;
+}
+
+
+uint32_t unpack_bin_str(mqtt_binstr_t * const p_str,
+ uint32_t buffer_len,
+ uint8_t * const buffer,
+ uint32_t * const p_offset)
+{
+ uint32_t error_code = NRF_ERROR_DATA_SIZE;
+
+ MQTT_TRC(">> %s BL:%08x, B:%p, O:%08x", __func__,
+ buffer_len, buffer, (*p_offset));
+
+ if (buffer_len >= (*p_offset))
+ {
+ p_str->p_bin_str = NULL;
+ p_str->bin_strlen = 0;
+
+ // Indicate success zero length binary strings are permitted.
+ error_code = NRF_SUCCESS;
+
+ const uint32_t available_len = buffer_len - (*p_offset);
+
+ if (available_len)
+ {
+ // Point to start of binary string.
+ p_str->p_bin_str = &buffer[(*p_offset)];
+ p_str->bin_strlen = available_len;
+
+ // Increment offset.
+ (*p_offset) += available_len;
+ }
+ }
+
+ MQTT_TRC("<< %s bin len:0x%08x", __func__, p_str->bin_strlen);
+
+ return error_code;
+}
+
+
+uint32_t packet_length_decode(uint8_t * p_buffer,
+ uint32_t buffer_len,
+ uint32_t * p_remaining_length,
+ uint32_t * p_offset)
+{
+ uint32_t index = (*p_offset);
+ uint32_t remaining_length = 0;
+ uint32_t multiplier = 1;
+
+ do
+ {
+ if (index >= buffer_len)
+ {
+ return NRF_ERROR_DATA_SIZE;
+ }
+
+ remaining_length += (p_buffer[index] & MQTT_LENGTH_VALUE_MASK) * multiplier;
+ multiplier *= MQTT_LENGTH_MULTIPLIER;
+
+ } while ((p_buffer[index++] & MQTT_LENGTH_CONTINUATION_BIT) != 0);
+
+ *p_offset = index;
+ *p_remaining_length = remaining_length;
+
+ MQTT_TRC("%s: RL:0x%08x RLS:0x%08x", __func__, remaining_length, index);
+
+ return NRF_SUCCESS;
+}
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/mqtt/mqtt_encoder.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/mqtt/mqtt_encoder.c
new file mode 100644
index 0000000..74476f2
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/mqtt/mqtt_encoder.c
@@ -0,0 +1,457 @@
+/**
+ * Copyright (c) 2015 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 mqtt_encoder.c
+ *
+ * @brief Encoding functions needed to create packet to be sent to the broker.
+ */
+
+
+#include "mqtt_internal.h"
+
+#if MQTT_CONFIG_LOG_ENABLED
+
+#define NRF_LOG_MODULE_NAME mqtt_enc
+
+#define NRF_LOG_LEVEL MQTT_CONFIG_LOG_LEVEL
+#define NRF_LOG_INFO_COLOR MQTT_CONFIG_INFO_COLOR
+#define NRF_LOG_DEBUG_COLOR MQTT_CONFIG_DEBUG_COLOR
+
+#include "nrf_log.h"
+NRF_LOG_MODULE_REGISTER();
+
+#define MQTT_TRC NRF_LOG_DEBUG /**< Used for getting trace of execution in the module. */
+#define MQTT_ERR NRF_LOG_ERROR /**< Used for logging errors in the module. */
+#define MQTT_DUMP NRF_LOG_HEXDUMP_DEBUG /**< Used for dumping octet information to get details of bond information etc. */
+
+#define MQTT_ENTRY() MQTT_TRC(">> %s", __func__)
+#define MQTT_EXIT() MQTT_TRC("<< %s", __func__)
+
+#else // MQTT_CONFIG_LOG_ENABLED
+
+#define MQTT_TRC(...) /**< Disables traces. */
+#define MQTT_DUMP(...) /**< Disables dumping of octet streams. */
+#define MQTT_ERR(...) /**< Disables error logs. */
+
+#define MQTT_ENTRY(...)
+#define MQTT_EXIT(...)
+
+#endif // MQTT_CONFIG_LOG_ENABLED
+
+#define MQTT_3_1_0_PROTO_DESC_LEN 6
+#define MQTT_3_1_1_PROTO_DESC_LEN 4
+
+const uint8_t mqtt_3_1_0_proto_desc_str[MQTT_3_1_0_PROTO_DESC_LEN] = {'M', 'Q', 'I', 's', 'd', 'p'};
+const uint8_t mqtt_3_1_1_proto_desc_str[MQTT_3_1_1_PROTO_DESC_LEN] = {'M', 'Q', 'T', 'T'};
+
+const mqtt_utf8_t mqtt_3_1_0_proto_desc =
+{
+ .p_utf_str = (uint8_t *)&mqtt_3_1_0_proto_desc_str[0],
+ .utf_strlen = MQTT_3_1_0_PROTO_DESC_LEN
+};
+
+const mqtt_utf8_t mqtt_3_1_1_proto_desc =
+{
+ .p_utf_str = (uint8_t *)&mqtt_3_1_1_proto_desc_str[0],
+ .utf_strlen = MQTT_3_1_1_PROTO_DESC_LEN
+};
+
+uint32_t pack_uint8(uint8_t val,
+ uint32_t buffer_len,
+ uint8_t * const buffer,
+ uint32_t * const p_offset)
+{
+ uint32_t err_code = NRF_ERROR_DATA_SIZE;
+
+ if (buffer_len > (*p_offset))
+ {
+ MQTT_TRC(">> %s V:%02x BL:%08x, B:%p, O:%08x", __func__,
+ val, buffer_len, buffer, (*p_offset));
+
+ // Pack value.
+ buffer[(*p_offset)] = val;
+
+ // Increment offset.
+ (*p_offset) += SIZE_OF_UINT8;
+
+ // Indicate success.
+ err_code = NRF_SUCCESS;
+ }
+
+ return err_code;
+}
+
+
+uint32_t pack_uint16(uint16_t val,
+ uint32_t buffer_len,
+ uint8_t * const buffer,
+ uint32_t * const p_offset)
+{
+ uint32_t err_code = NRF_ERROR_DATA_SIZE;
+
+ if (buffer_len > (*p_offset))
+ {
+ const uint32_t available_len = buffer_len - (*p_offset);
+
+ MQTT_TRC(">> %s V:%04x BL:%08x, B:%p, O:%08x A:%08x", __func__,
+ val, buffer_len, buffer, (*p_offset), available_len);
+
+ if (available_len >= SIZE_OF_UINT16)
+ {
+ // Pack value.
+ buffer[(*p_offset)] = MSB_16(val);
+ buffer[(*p_offset)+1] = LSB_16(val);
+
+ // Increment offset.
+ (*p_offset) += SIZE_OF_UINT16;
+
+ // Indicate success.
+ err_code = NRF_SUCCESS;
+ }
+ }
+
+ return err_code;
+}
+
+
+uint32_t pack_utf8_str(mqtt_utf8_t const * const p_str,
+ uint32_t buffer_len,
+ uint8_t * const buffer,
+ uint32_t * const p_offset)
+{
+ uint32_t err_code = NRF_ERROR_DATA_SIZE;
+
+ if (buffer_len > (*p_offset))
+ {
+ const uint32_t available_len = buffer_len - (*p_offset);
+ err_code = NRF_ERROR_NO_MEM;
+
+ MQTT_TRC(">> %s USL:%08x BL:%08x, B:%p, O:%08x A:%08x", __func__,
+ GET_UT8STR_BUFFER_SIZE(p_str), buffer_len, buffer, (*p_offset), available_len);
+
+ if (available_len >= GET_UT8STR_BUFFER_SIZE(p_str))
+ {
+ // Length followed by string.
+ err_code = pack_uint16(p_str->utf_strlen, buffer_len, buffer, p_offset);
+
+ if (err_code == NRF_SUCCESS)
+ {
+ memcpy(&buffer[(*p_offset)], p_str->p_utf_str, p_str->utf_strlen);
+
+ (*p_offset) += p_str->utf_strlen;
+
+ err_code = NRF_SUCCESS;
+ }
+ }
+ }
+
+ return err_code;
+}
+
+uint32_t pack_bin_str(mqtt_binstr_t const * const p_str,
+ uint32_t buffer_len,
+ uint8_t * const buffer,
+ uint32_t * const p_offset)
+{
+ uint32_t err_code = NRF_ERROR_DATA_SIZE;
+
+ if (buffer_len > (*p_offset))
+ {
+ const uint32_t available_len = buffer_len - (*p_offset);
+ err_code = NRF_ERROR_NO_MEM;
+
+ MQTT_TRC(">> %s BSL:%08x BL:%08x, B:%p, O:%08x A:%08x", __func__,
+ GET_BINSTR_BUFFER_SIZE(p_str), buffer_len, buffer, (*p_offset), available_len);
+
+ if (available_len >= GET_BINSTR_BUFFER_SIZE(p_str))
+ {
+ memcpy(&buffer[(*p_offset)], p_str->p_bin_str, p_str->bin_strlen);
+
+ (*p_offset) += p_str->bin_strlen;
+ err_code = NRF_SUCCESS;
+ }
+ }
+
+ return err_code;
+}
+
+
+void packet_length_encode(uint32_t remaining_length, uint8_t * p_buff, uint32_t * p_size)
+{
+ uint16_t index = 0;
+ const uint32_t offset = (*p_size);
+
+ MQTT_TRC(">> RL:0x%08x O:%08x P:%p", remaining_length, offset, p_buff);
+
+ do
+ {
+ if (p_buff != NULL)
+ {
+ p_buff[offset+index] = remaining_length % 0x80;
+ }
+
+ remaining_length /= 0x80;
+
+ if (remaining_length > 0)
+ {
+ if (p_buff != NULL)
+ {
+ p_buff[offset+index] |= 0x80;
+ }
+ }
+
+ index++;
+
+ } while (remaining_length > 0);
+
+ MQTT_TRC("<< RLS:0x%08x", index);
+
+ *p_size += index;
+}
+
+
+uint32_t mqtt_encode_fixed_header(uint8_t message_type, uint32_t length, uint8_t ** pp_packet)
+{
+ uint32_t packet_length = 0xFFFFFFFF;
+
+ if (MQTT_MAX_PAYLOAD_SIZE >= length)
+ {
+ uint32_t offset = 1;
+
+ MQTT_TRC("<< %s MT:0x%02x L:0x%08x", __func__, message_type, length);
+ packet_length_encode(length, NULL, &offset);
+
+ MQTT_TRC("Remaining length size = %02x", offset);
+
+ uint8_t * p_mqtt_header = ((*pp_packet) - offset);
+
+ // Reset offset.
+ offset = 0;
+ UNUSED_VARIABLE(pack_uint8(message_type, MQTT_MAX_PACKET_LENGTH, p_mqtt_header, &offset));
+ packet_length_encode(length, p_mqtt_header, &offset);
+
+ (* pp_packet) = p_mqtt_header;
+
+ packet_length = (length + offset);
+ }
+
+ return packet_length;
+}
+
+
+uint32_t zero_len_str_encode(uint32_t buffer_len,
+ uint8_t * const buffer,
+ uint32_t * const offset)
+{
+ return pack_uint16(0x0000, buffer_len, buffer, offset);
+}
+
+
+void connect_request_encode(const mqtt_client_t * p_client,
+ uint8_t ** pp_packet,
+ uint32_t * p_packet_length)
+{
+ uint32_t err_code;
+ uint32_t offset = 0;
+ uint8_t * p_payload = &p_client->p_packet[MQTT_FIXED_HEADER_EXTENDED_SIZE];
+ uint8_t connect_flags = p_client->clean_session << 1; // Clean session always.
+
+ const mqtt_utf8_t * p_mqtt_proto_desc;
+ if (p_client->protocol_version == MQTT_VERSION_3_1_1)
+ {
+ p_mqtt_proto_desc = &mqtt_3_1_1_proto_desc;
+ }
+ else
+ {
+ p_mqtt_proto_desc = &mqtt_3_1_0_proto_desc;
+ }
+
+ memset(p_payload, 0, MQTT_MAX_PACKET_LENGTH);
+
+ // Pack protocol description.
+ MQTT_TRC("Encoding Protocol Description. Str:%s Size:%08x.",
+ p_mqtt_proto_desc->p_utf_str,
+ p_mqtt_proto_desc->utf_strlen);
+
+ err_code = pack_utf8_str(p_mqtt_proto_desc,
+ MQTT_MAX_VARIABLE_HEADER_N_PAYLOAD,
+ p_payload,
+ &offset);
+
+ if (err_code == NRF_SUCCESS)
+ {
+ MQTT_TRC("Encoding Protocol Version %02x.", p_client->protocol_version);
+ // Pack protocol version.
+ err_code = pack_uint8(p_client->protocol_version,
+ MQTT_MAX_VARIABLE_HEADER_N_PAYLOAD,
+ p_payload,
+ &offset);
+ }
+
+ // Remember position of connect flag and
+ // leave one byte for it to be packed once we determine its value.
+ const uint32_t connect_flag_offset = MQTT_FIXED_HEADER_EXTENDED_SIZE + offset;
+ offset++;
+
+ if (err_code == NRF_SUCCESS)
+ {
+ MQTT_TRC("Encoding Keep Alive Time %04x.", MQTT_KEEPALIVE);
+ // Pack keep alive time.
+ err_code = pack_uint16(MQTT_KEEPALIVE,
+ MQTT_MAX_VARIABLE_HEADER_N_PAYLOAD,
+ p_payload,
+ &offset);
+ }
+
+ if (err_code == NRF_SUCCESS)
+ {
+ MQTT_TRC("Encoding Client Id. Str:%s Size:%08x.",
+ p_client->client_id.p_utf_str,
+ p_client->client_id.utf_strlen);
+
+ // Pack client id
+ err_code = pack_utf8_str(&p_client->client_id,
+ MQTT_MAX_VARIABLE_HEADER_N_PAYLOAD,
+ p_payload,
+ &offset);
+ }
+
+ if (err_code == NRF_SUCCESS)
+ {
+ // Pack will topic and QoS
+ if (p_client->p_will_topic != NULL)
+ {
+ MQTT_TRC("Encoding Will Topic. Str:%s Size:%08x.",
+ p_client->p_will_topic->topic.p_utf_str,
+ p_client->p_will_topic->topic.utf_strlen);
+
+ // Set Will topic in connect flags.
+ connect_flags |= MQTT_CONNECT_FLAG_WILL_TOPIC;
+
+ err_code = pack_utf8_str(&p_client->p_will_topic->topic,
+ MQTT_MAX_VARIABLE_HEADER_N_PAYLOAD,
+ p_payload,
+ &offset);
+
+ if (err_code == NRF_SUCCESS)
+ {
+ // QoS is always 1 as of now.
+ connect_flags |= ((p_client->p_will_topic->qos & 0x03) << 3);
+ connect_flags |= p_client->will_retain << 5;
+
+ if (p_client->p_will_message != NULL)
+ {
+ MQTT_TRC("Encoding Will Message. Str:%s Size:%08x.",
+ p_client->p_will_message->p_utf_str,
+ p_client->p_will_message->utf_strlen);
+
+ err_code = pack_utf8_str(p_client->p_will_message,
+ MQTT_MAX_VARIABLE_HEADER_N_PAYLOAD,
+ p_payload,
+ &offset);
+ }
+ else
+ {
+ MQTT_TRC("Encoding Zero Length Will Message.");
+ err_code = zero_len_str_encode(MQTT_MAX_VARIABLE_HEADER_N_PAYLOAD,
+ p_payload,
+ &offset);
+ }
+ }
+ }
+ }
+
+ if (err_code == NRF_SUCCESS)
+ {
+ // Pack Username if any.
+ if (p_client->p_user_name != NULL)
+ {
+ connect_flags |= MQTT_CONNECT_FLAG_USERNAME;
+
+ MQTT_TRC("Encoding Username. Str:%s, Size:%08x.",
+ p_client->p_user_name->p_utf_str,
+ p_client->p_user_name->utf_strlen);
+
+ err_code = pack_utf8_str(p_client->p_user_name,
+ MQTT_MAX_VARIABLE_HEADER_N_PAYLOAD,
+ p_payload,
+ &offset);
+
+ if (err_code == NRF_SUCCESS)
+ {
+ // Pack Password if any.
+ if (p_client->p_password != NULL)
+ {
+ MQTT_TRC("Encoding Password. Str:%s Size:%08x.",
+ p_client->p_password->p_utf_str,
+ p_client->p_password->utf_strlen);
+
+ connect_flags |= MQTT_CONNECT_FLAG_PASSWORD;
+ err_code = pack_utf8_str(p_client->p_password,
+ MQTT_MAX_VARIABLE_HEADER_N_PAYLOAD,
+ p_payload,
+ &offset);
+ }
+ }
+ }
+ }
+
+ if (err_code == NRF_SUCCESS)
+ {
+ // Pack the connect flags.
+ p_client->p_packet[connect_flag_offset] = connect_flags;
+
+ const uint8_t message_type = MQTT_MESSAGES_OPTIONS(MQTT_PKT_TYPE_CONNECT,
+ 0, // Duplicate flag not set.
+ 0, // QoS not set.
+ 0); // Retain not set.
+
+ offset = mqtt_encode_fixed_header(message_type,
+ offset,
+ &p_payload);
+
+ (*p_packet_length) = offset;
+ (*pp_packet) = p_payload;
+ }
+ else
+ {
+ (*p_packet_length) = 0;
+ (*pp_packet) = NULL;
+ }
+}
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/mqtt/mqtt_internal.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/mqtt/mqtt_internal.h
new file mode 100644
index 0000000..807b2f9
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/mqtt/mqtt_internal.h
@@ -0,0 +1,446 @@
+/**
+ * Copyright (c) 2015 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 mqtt_internal.h
+ *
+ * @brief Function and data structures internal to MQTT module.
+ */
+
+#ifndef MQTT_INTERNAL_H_
+#define MQTT_INTERNAL_H_
+
+#include "nordic_common.h"
+#include "sdk_common.h"
+#include "sdk_config.h"
+#include "mqtt.h"
+#include "iot_errors.h"
+#include "nrf_tls.h"
+#include <stdint.h>
+#include <string.h>
+#include "nrf_error.h"
+#include "nrf_tls.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifndef MQTT_MAX_CLIENTS
+#define MQTT_MAX_CLIENTS 1 /**< Maximum number of clients that can be managed by the module. */
+#endif //MQTT_MAX_CLIENTS
+
+#ifndef MQTT_KEEPALIVE
+#define MQTT_KEEPALIVE 60 /**< Keep alive time for MQTT (in seconds). Sending of Ping Requests to be keep the connection alive are governed by this value. */
+#endif //MQTT_KEEPALIVE
+
+#ifndef MQTT_MAX_PACKET_LENGTH
+#define MQTT_MAX_PACKET_LENGTH 128 /**< Maximum MQTT packet size that can be sent (including the fixed and variable header). */
+#endif // MQTT_MAX_PACKET_LENGTH
+
+#define MQTT_FIXED_HEADER_SIZE 2 /**< Fixed header minimum size. Remaining length size is 1 in this case. */
+#define MQTT_FIXED_HEADER_EXTENDED_SIZE 5 /**< Maximum size of the fixed header. Remaining length size is 4 in this case. */
+
+/**@brief MQTT Control Packet Types. */
+#define MQTT_PKT_TYPE_CONNECT 0x10
+#define MQTT_PKT_TYPE_CONNACK 0x20
+#define MQTT_PKT_TYPE_PUBLISH 0x30
+#define MQTT_PKT_TYPE_PUBACK 0x40
+#define MQTT_PKT_TYPE_PUBREC 0x50
+#define MQTT_PKT_TYPE_PUBREL 0x60
+#define MQTT_PKT_TYPE_PUBCOMP 0x70
+#define MQTT_PKT_TYPE_SUBSCRIBE 0x82 // QoS 1 for subscribe
+#define MQTT_PKT_TYPE_SUBACK 0x90
+#define MQTT_PKT_TYPE_UNSUBSCRIBE 0xA2
+#define MQTT_PKT_TYPE_UNSUBACK 0xB0
+#define MQTT_PKT_TYPE_PINGREQ 0xC0
+#define MQTT_PKT_TYPE_PINGRSP 0xD0
+#define MQTT_PKT_TYPE_DISCONNECT 0xE0
+
+
+/**@brief Masks for MQTT header flags. */
+#define MQTT_HEADER_DUP_MASK 0x08
+#define MQTT_HEADER_QOS_MASK 0x06
+#define MQTT_HEADER_RETAIN_MASK 0x01
+#define MQTT_HEADER_CONNACK_MASK 0x0F
+
+/**@brief Masks for MQTT header flags. */
+#define MQTT_CONNECT_FLAG_CLEAN_SESSION 0x02
+#define MQTT_CONNECT_FLAG_WILL_TOPIC 0x04
+#define MQTT_CONNECT_FLAG_WILL_RETAIN 0x20
+#define MQTT_CONNECT_FLAG_PASSWORD 0x40
+#define MQTT_CONNECT_FLAG_USERNAME 0x80
+
+/**@brief Size of mandatory header of MQTT Packet. */
+#define MQTT_PKT_HEADER_SIZE 2
+
+/**@brief */
+#define MQTT_MAX_PAYLOAD_SIZE 0x0FFFFFFF
+
+/**@brief Maximum size of variable and payload in the packet. */
+#define MQTT_MAX_VARIABLE_HEADER_N_PAYLOAD (MQTT_MAX_PACKET_LENGTH - MQTT_FIXED_HEADER_EXTENDED_SIZE)
+
+/**@brief Defines size of uint8 in bytes. */
+#define SIZE_OF_UINT8 1
+
+/**@brief Defines size of uint8 in bytes. */
+#define SIZE_OF_UINT16 2
+
+/**@brief Computes total size needed to pack a UTF8 string. */
+#define GET_UT8STR_BUFFER_SIZE(STR) (SIZE_OF_UINT16 + (STR)->utf_strlen)
+
+/**@brief Computes total size needed to pack a binary stream. */
+#define GET_BINSTR_BUFFER_SIZE(STR) ((STR)->bin_strlen)
+
+/**@brief Unsubscribe packet size. */
+#define MQTT_UNSUBSCRIBE_PKT_SIZE 4
+
+/**@brief Sets MQTT Client's state with one indicated in 'STATE'. */
+#define MQTT_SET_STATE(CLIENT, STATE) ((CLIENT)->state |= (STATE))
+
+/**@brief Sets MQTT Client's state exclusive to 'STATE'. */
+#define MQTT_SET_STATE_EXCLUSIVE(CLIENT, STATE) ((CLIENT)->state = (STATE))
+
+/**@brief Verifies if MQTT Client's state is set with one indicated in 'STATE'. */
+#define MQTT_VERIFY_STATE(CLIENT, STATE) ((CLIENT)->state & (STATE))
+
+/**@brief Reset 'STATE' in MQTT Client's state. */
+#define MQTT_RESET_STATE(CLIENT, STATE) ((CLIENT)->state &= ~(STATE))
+
+/**@brief Initialize MQTT Client's state. */
+#define MQTT_STATE_INIT(CLIENT) (CLIENT)->state = MQTT_STATE_IDLE
+
+/**@brief Computes the first byte of MQTT message header based on message type, duplication flag,
+ * QoS and the retain flag.
+ */
+#define MQTT_MESSAGES_OPTIONS(TYPE, DUP, QOS, RETAIN) \
+ (((TYPE) & 0xF0) | \
+ (((DUP) << 3) & 0x08) | \
+ (((QOS) << 1) & 0x06) | \
+ ((RETAIN) & 0x01))
+
+
+#define MQTT_EVT_FLAG_NONE 0x00000000
+#define MQTT_EVT_FLAG_INSTANCE_RESET 0x00000001
+
+
+/**
+ * @defgroup iot_mqtt_mutex_lock_unlock Module's Mutex Lock/Unlock Macros.
+ *
+ * @details Macros used to lock and unlock modules. Currently, SDK does not use mutexes but
+ * framework is provided in case the need to use an alternative architecture arises.
+ * @{
+ */
+#define MQTT_MUTEX_LOCK() SDK_MUTEX_LOCK(m_mqtt_mutex) /**< Lock module using mutex */
+#define MQTT_MUTEX_UNLOCK() SDK_MUTEX_UNLOCK(m_mqtt_mutex) /**< Unlock module using mutex */
+
+/** @} */
+
+/**@brief Check if the input pointer is NULL, if so it returns NRF_ERROR_NULL.
+ */
+#define NULL_PARAM_CHECK(PARAM) \
+ if ((PARAM) == NULL) \
+ { \
+ return (NRF_ERROR_NULL | IOT_MQTT_ERR_BASE); \
+ }
+
+#define NULL_PARAM_CHECK_VOID(PARAM) \
+ if ((PARAM) == NULL) \
+ { \
+ return; \
+ }
+
+/**@brief MQTT States. */
+typedef enum
+{
+ MQTT_STATE_IDLE = 0x00000000, /**< Idle state, implying the client entry in the table is unused/free. */
+ MQTT_STATE_TCP_CONNECTING = 0x00000001, /**< TCP Connection has been requested, awaiting result of the request. */
+ MQTT_STATE_TCP_CONNECTED = 0x00000002, /**< TCP Connection successfully established. */
+ MQTT_STATE_CONNECTED = 0x00000004, /**< MQTT Connection successful. */
+ MQTT_STATE_PENDING_WRITE = 0x00000008, /**< State that indicates write callback is awaited for an issued request. */
+ MQTT_STATE_DISCONNECTING = 0x00000010 /**< TCP Disconnect has been requested, awaiting result of the request. */
+} mqtt_state_t;
+
+
+/**@brief Packs unsigned 8 bit value to the buffer at the offset requested.
+ *
+ * @param[in] val Value to be packed.
+ * @param[in] buffer_len Total size of the buffer on which value is to be packed.
+ * This shall not be zero.
+ * @param[out] p_buffer Buffer where the value is to be packed.
+ * @param[inout] p_offset Offset on the buffer where the value is to be packed. If the procedure
+ * is successful, the offset is incremented to point to the next write/pack
+ * location on the buffer.
+ *
+ * @retval NRF_SUCCESS if procedure is successful.
+ * @retval NRF_ERROR_DATA_SIZE if the offset is greater than or equal to the buffer length.
+ */
+uint32_t pack_uint8(uint8_t val,
+ uint32_t buffer_len,
+ uint8_t * const p_buffer,
+ uint32_t * const p_offset);
+
+
+/**@brief Packs unsigned 16 bit value to the buffer at the offset requested.
+ *
+ * @param[in] val Value to be packed.
+ * @param[in] buffer_len Total size of the buffer on which value is to be packed.
+ * This shall not be zero.
+ * @param[out] p_buffer Buffer where the value is to be packed.
+ * @param[inout] p_offset Offset on the buffer where the value is to be packed. If the procedure
+ * is successful, the offset is incremented to point to the next write/pack
+ * location on the buffer.
+ *
+ * @retval NRF_SUCCESS if the procedure is successful.
+ * @retval NRF_ERROR_DATA_SIZE if the offset is greater than or equal to the buffer length minus
+ * the size of unsigned 16 bit integer.
+ */
+uint32_t pack_uint16(uint16_t val,
+ uint32_t buffer_len,
+ uint8_t * const p_buffer,
+ uint32_t * const p_offset);
+
+
+/**@brief Packs utf8 string to the buffer at the offset requested.
+ *
+ * @param[in] p_str UTF-8 string and its length to be packed.
+ * @param[in] buffer_len Total size of the buffer on which string is to be packed.
+ * This shall not be zero.
+ * @param[out] p_buffer Buffer where the string is to be packed.
+ * @param[inout] p_offset Offset on the buffer where the string is to be packed. If the procedure
+ * is successful, the offset is incremented to point to the next write/pack
+ * location on the buffer.
+ *
+ * @retval NRF_SUCCESS if the procedure is successful.
+ * @retval NRF_ERROR_DATA_SIZE if the offset is greater than or equal to the buffer length minus
+ * the size of unsigned 16 bit integer.
+ * @retval NRF_ERROR_NO_MEM if there is no room on the buffer to pack the string.
+ */
+uint32_t pack_utf8_str(mqtt_utf8_t const * const p_str,
+ uint32_t buffer_len,
+ uint8_t * const p_buffer,
+ uint32_t * const p_offset);
+
+
+/**@brief Packs binary string to the buffer at the offset requested.
+ *
+ * @param[in] p_str Binary string and its length to be packed.
+ * @param[in] buffer_len Total size of the buffer on which string is to be packed.
+ * @param[in] p_buffer Buffer where the string is to be packed.
+ * @param[inout] p_offset Offset on the buffer where the string is to be packed. If the procedure
+ * is successful, the offset is incremented to point to the next write/pack
+ * location on the buffer.
+ *
+ * @retval NRF_SUCCESS if the procedure is successful.
+ * @retval NRF_ERROR_DATA_SIZE if the offset is greater than or equal to the buffer length.
+ * @retval NRF_ERROR_NO_MEM if there is no room on the buffer to pack the string.
+ */
+uint32_t pack_bin_str(mqtt_binstr_t const * const p_str,
+ uint32_t buffer_len,
+ uint8_t * const p_buffer,
+ uint32_t * const p_offset);
+
+
+/**@brief Unpacks unsigned 8 bit value from the buffer from the offset requested.
+ *
+ * @param[out] p_val Memory where the value is to be unpacked.
+ * @param[in] buffer_len Total size of the buffer. This shall not be zero.
+ * @param[in] p_buffer Buffer from which the value is to be unpacked.
+ * @param[inout] p_offset Offset on the buffer from where the value is to be unpacked. If the
+ * procedure is successful, the offset is incremented to point to the next
+ * read/unpack location on the buffer.
+ *
+ * @retval NRF_SUCCESS if the procedure is successful.
+ * @retval NRF_ERROR_DATA_SIZE if the offset is greater than or equal to the buffer length.
+ */
+uint32_t unpack_uint8(uint8_t * p_val,
+ uint32_t buffer_len,
+ uint8_t * const p_buffer,
+ uint32_t * const p_offset);
+
+/**@brief Unpacks unsigned 16 bit value from the buffer from the offset requested.
+ *
+ * @param[out] p_val Memory where the value is to be unpacked.
+ * @param[in] buffer_len Total size of the buffer. This shall not be zero.
+ * @param[in] p_buffer Buffer from which the value is to be unpacked.
+ * @param[inout] p_offset Offset on the buffer from where the value is to be unpacked. If the
+ * procedure is successful, the offset is incremented to point to the next
+ * read/unpack location on the buffer.
+ *
+ * @retval NRF_SUCCESS if the procedure is successful.
+ * @retval NRF_ERROR_DATA_SIZE if the offset is greater than or equal to the buffer length.
+ */
+uint32_t unpack_uint16(uint16_t * p_val,
+ uint32_t buffer_len,
+ uint8_t * const p_buffer,
+ uint32_t * const p_offset);
+
+
+/**@brief Unpacks unsigned 16 bit value from the buffer from the offset requested.
+ *
+ * @param[out] p_str Memory where the utf8 string and its value are to be unpacked.
+ * No copy of data is performed for the string.
+ * @param[in] buffer_len Total size of the buffer. This shall not be zero.
+ * @param[in] p_buffer Buffer from which the string is to be unpacked.
+ * @param[inout] p_offset Offset on the buffer from where the value is to be unpacked. If the
+ * procedure is successful, the offset is incremented to point to the next
+ * read/unpack location on the buffer.
+ *
+ * @retval NRF_SUCCESS if the procedure is successful.
+ * @retval NRF_ERROR_DATA_SIZE if the offset is greater than or equal to the buffer length.
+ */
+uint32_t unpack_utf8_str(mqtt_utf8_t * const p_str,
+ uint32_t buffer_len,
+ uint8_t * const p_buffer,
+ uint32_t * const p_offset);
+
+
+/**@brief Unpacks binary string from the buffer from the offset requested.
+ *
+ * @param[out] p_str Memory where the binary string and its length are to be unpacked.
+ * No copy of data is performed for the string.
+ * @param[in] buffer_len Total size of the buffer. This shall not be zero.
+ * @param[in] p_buffer Buffer where the value is to be unpacked.
+ * @param[inout] p_offset Offset on the buffer from where the value is to be unpacked. If the
+ * procedure is successful, the offset is incremented to point to the next
+ * read/unpack location on the buffer.
+ *
+ * @retval NRF_SUCCESS if the procedure is successful.
+ * @retval NRF_ERROR_DATA_SIZE if the offset is greater than or equal to the buffer length.
+ */
+uint32_t unpack_bin_str(mqtt_binstr_t * const p_str,
+ uint32_t buffer_len,
+ uint8_t * const p_buffer,
+ uint32_t * const p_offset);
+
+
+/**@brief Unpacks utf8 string from the buffer from the offset requested.
+ *
+ * @param[out] p_str Memory where the utf8 string and its length are to be unpacked.
+ * @param[in] buffer_len Total size of the buffer. This shall not be zero.
+ * @param[in] p_buffer Buffer where the value is to be unpacked.
+ * @param[inout] p_offset Offset on the buffer from where the value is to be unpacked. If the
+ * procedure is successful, the offset is incremented to point to the next
+ * read/unpack location on the buffer.
+ *
+ * @retval NRF_SUCCESS if the procedure is successful.
+ * @retval NRF_ERROR_DATA_SIZE if the offset is greater than or equal to the buffer length.
+ */
+uint32_t zero_len_str_encode(uint32_t buffer_len,
+ uint8_t * const p_buffer,
+ uint32_t * const p_offset);
+
+
+/**@brief Computes and encodes length for the MQTT fixed header.
+ *
+ * @note The remaining length is not packed as a fixed unsigned 32 bit integer. Instead it is packed
+ * on algorithm below:
+ *
+ * @code
+ * do
+ * encodedByte = X MOD 128
+ * X = X DIV 128
+ * // if there are more data to encode, set the top bit of this byte
+ * if ( X > 0 )
+ * encodedByte = encodedByte OR 128
+ * endif
+ * 'output' encodedByte
+ * while ( X > 0 )
+ * @endcode
+ *
+ * @param[in] remaining_length Length of variable header and payload in the MQTT message.
+ * @param[out] p_buffer Buffer where the length is to be packed.
+ * @param[inout] p_offset Offset on the buffer where the length is to be packed.
+ */
+void packet_length_encode(uint32_t remaining_length, uint8_t * p_buffer, uint32_t * p_offset);
+
+
+/**@brief Decode MQTT Packet Length in the MQTT fixed header.
+ *
+ * @param[in] p_buffer Buffer where the length is to be decoded.
+ * @param[in] buffer_len Length of p_buffer
+ * @param[out] p_remaining_length Length of variable header and payload in the MQTT message.
+ * @param[inout] p_offset Offset on the buffer from where the length is to be unpacked.
+ *
+ * @retval NRF_SUCCESS if the procedure is successful.
+ * @retval NRF_ERROR_DATA_SIZE if the offset is greater than or equal to the buffer length.
+ */
+uint32_t packet_length_decode(uint8_t * p_buffer,
+ uint32_t buffer_len,
+ uint32_t * p_remaining_length,
+ uint32_t * p_offset);
+
+
+/**@brief Encodes fixed header for the MQTT message and provides pointer to start of the header.
+ *
+ * @param[in] message_type Message type containing packet type and the flags.
+ * Use @ref MQTT_MESSAGES_OPTIONS to construct the message_type.
+ * @param[in] length Buffer where the message payload along with variable header.
+ * @param[inout] pp_packet Pointer to the MQTT message variable header and payload.
+ * The 5 bytes before the start of the message are assumed by the
+ * routine to be available to pack the fixed header. However, since
+ * the fixed header length is variable length, the pointer to the
+ * start of the MQTT message along with encoded fixed header is
+ * supplied as output parameter if the procedure was successful.
+ *
+ * @retval 0xFFFFFFFF if the procedure failed, else length of total MQTT message along with the
+ * fixed header.
+ */
+uint32_t mqtt_encode_fixed_header(uint8_t message_type, uint32_t length, uint8_t ** pp_packet);
+
+
+/**@brief Constructs/encodes connect packet.
+ *
+ * @param[in] p_client Identifies the client for which the procedure is requested.
+ * All information required for creating the packet like client id,
+ * clean session flag, retain session flag etc are assumed to be
+ * populated for the client instance when this procedure is requested.
+ * @param[out] pp_packet Pointer to the MQTT connect message.
+ * @param[out] p_packet_length Length of the connect request.
+ *
+ * @retval 0xFFFFFFFF if the procedure failed, else length of total MQTT message along with the
+ * fixed header.
+ */
+void connect_request_encode(const mqtt_client_t * p_client,
+ uint8_t ** pp_packet,
+ uint32_t * p_packet_length);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // MQTT_INTERNAL_H_
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/mqtt/mqtt_rx.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/mqtt/mqtt_rx.c
new file mode 100644
index 0000000..10b0ae4
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/mqtt/mqtt_rx.c
@@ -0,0 +1,313 @@
+/**
+ * Copyright (c) 2015 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 mqtt_rx.c
+ *
+ * @brief Handles packet receive on transport TCP or TLS.
+ */
+#include "mqtt_internal.h"
+
+void event_notify(mqtt_client_t * const p_client, const mqtt_evt_t * p_evt, uint32_t flags);
+void disconnect_event_notify(mqtt_client_t * p_client, uint32_t result);
+
+#if MQTT_CONFIG_LOG_ENABLED
+
+#define NRF_LOG_MODULE_NAME mqtt_rx
+
+#define NRF_LOG_LEVEL MQTT_CONFIG_LOG_LEVEL
+#define NRF_LOG_INFO_COLOR MQTT_CONFIG_INFO_COLOR
+#define NRF_LOG_DEBUG_COLOR MQTT_CONFIG_DEBUG_COLOR
+
+#include "nrf_log.h"
+NRF_LOG_MODULE_REGISTER();
+
+#define MQTT_TRC NRF_LOG_DEBUG /**< Used for getting trace of execution in the module. */
+#define MQTT_ERR NRF_LOG_ERROR /**< Used for logging errors in the module. */
+#define MQTT_DUMP NRF_LOG_HEXDUMP_DEBUG /**< Used for dumping octet information to get details of bond information etc. */
+
+#define MQTT_ENTRY() MQTT_TRC(">> %s", __func__)
+#define MQTT_EXIT() MQTT_TRC("<< %s", __func__)
+
+#else // MQTT_CONFIG_LOG_ENABLED
+
+#define MQTT_TRC(...) /**< Disables traces. */
+#define MQTT_DUMP(...) /**< Disables dumping of octet streams. */
+#define MQTT_ERR(...) /**< Disables error logs. */
+
+#define MQTT_ENTRY(...)
+#define MQTT_EXIT(...)
+
+#endif // MQTT_CONFIG_LOG_ENABLED
+
+static uint32_t mqtt_handle_packet(mqtt_client_t * p_client,
+ uint8_t * p_data,
+ uint32_t datalen,
+ uint32_t offset)
+{
+ mqtt_evt_t evt;
+ uint32_t err_code = NRF_SUCCESS;
+ bool notify_event = true;
+
+ // Success by default, overwritten in special cases.
+ evt.result = NRF_SUCCESS;
+
+ switch (p_data[0] & 0xF0)
+ {
+ case MQTT_PKT_TYPE_CONNACK:
+ {
+ MQTT_TRC("[%p]: Received MQTT_PKT_TYPE_CONNACK!", p_client);
+
+ if (p_client->protocol_version == MQTT_VERSION_3_1_1)
+ {
+ evt.param.connack.session_present_flag = p_data[2] & MQTT_HEADER_CONNACK_MASK;
+
+ MQTT_TRC("[%p]: session_present_flag: %d",
+ p_client,
+ evt.param.connack.session_present_flag);
+ }
+
+ evt.param.connack.return_code =
+ (mqtt_conn_return_code_t)(p_data[3] & MQTT_HEADER_CONNACK_MASK);
+
+ MQTT_TRC("[%p]: return_code: %d",
+ p_client,
+ evt.param.connack.return_code);
+
+ if (evt.param.connack.return_code == MQTT_CONNECTION_ACCEPTED)
+ {
+ // Set state.
+ MQTT_SET_STATE(p_client, MQTT_STATE_CONNECTED);
+ }
+
+ evt.result = evt.param.connack.return_code;
+ evt.id = MQTT_EVT_CONNACK;
+
+ break;
+ }
+ case MQTT_PKT_TYPE_PUBLISH:
+ {
+ evt.param.publish.dup_flag = p_data[0] & MQTT_HEADER_DUP_MASK;
+ evt.param.publish.retain_flag = p_data[0] & MQTT_HEADER_RETAIN_MASK;
+ evt.param.publish.message.topic.qos = ((p_data[0] & MQTT_HEADER_QOS_MASK) >> 1);
+
+ MQTT_TRC("[CID %p]: Received MQTT_PKT_TYPE_PUBLISH, QoS:%02x",
+ p_client, evt.param.publish.message.topic.qos);
+
+ err_code = unpack_utf8_str(&evt.param.publish.message.topic.topic,
+ datalen,
+ p_data,
+ &offset);
+
+ if (err_code == NRF_SUCCESS)
+ {
+ if (evt.param.publish.message.topic.qos)
+ {
+ err_code = unpack_uint16(&evt.param.publish.message_id,
+ datalen,
+ p_data,
+ &offset);
+ }
+ }
+
+ if (err_code == NRF_SUCCESS)
+ {
+ err_code = unpack_bin_str(&evt.param.publish.message.payload,
+ datalen,
+ p_data,
+ &offset);
+
+ // Zero length publish messages are permitted.
+ if (err_code != NRF_SUCCESS)
+ {
+ evt.param.publish.message.payload.p_bin_str = NULL;
+ evt.param.publish.message.payload.bin_strlen = 0;
+ }
+ }
+
+ MQTT_TRC("PUB message len %08x, topic len %08x",
+ evt.param.publish.message.payload.bin_strlen,
+ evt.param.publish.message.topic.topic.utf_strlen);
+
+ evt.id = MQTT_EVT_PUBLISH;
+ evt.result = err_code;
+
+ UNUSED_VARIABLE(iot_timer_wall_clock_get(&p_client->last_activity));
+
+ break;
+ }
+
+ case MQTT_PKT_TYPE_PUBACK:
+ {
+ MQTT_TRC("Received MQTT_PKT_TYPE_PUBACK!");
+
+ evt.id = MQTT_EVT_PUBACK;
+ err_code = unpack_uint16(&evt.param.puback.message_id,
+ datalen,
+ p_data,
+ &offset);
+ evt.result = err_code;
+ break;
+ }
+
+ case MQTT_PKT_TYPE_PUBREC:
+ {
+ MQTT_TRC("Received MQTT_PKT_TYPE_PUBREC!");
+
+ evt.id = MQTT_EVT_PUBREC;
+ err_code = unpack_uint16(&evt.param.pubrec.message_id,
+ datalen,
+ p_data,
+ &offset);
+ evt.result = err_code;
+ break;
+ }
+ case MQTT_PKT_TYPE_PUBREL:
+ {
+ MQTT_TRC("Received MQTT_PKT_TYPE_PUBREL!");
+
+ evt.id = MQTT_EVT_PUBREL;
+ err_code = unpack_uint16(&evt.param.pubrel.message_id,
+ datalen,
+ p_data,
+ &offset);
+ evt.result = err_code;
+ break;
+ }
+ case MQTT_PKT_TYPE_PUBCOMP:
+ {
+ MQTT_TRC("Received MQTT_PKT_TYPE_PUBCOMP!");
+
+ evt.id = MQTT_EVT_PUBCOMP;
+ err_code = unpack_uint16(&evt.param.pubcomp.message_id,
+ datalen,
+ p_data,
+ &offset);
+ evt.result = err_code;
+ break;
+ }
+ case MQTT_PKT_TYPE_SUBACK:
+ {
+ MQTT_TRC("Received MQTT_PKT_TYPE_SUBACK!");
+
+ evt.id = MQTT_EVT_SUBACK;
+ err_code = unpack_uint16(&evt.param.pubrec.message_id,
+ datalen,
+ p_data,
+ &offset);
+ evt.result = err_code;
+ break;
+ }
+ case MQTT_PKT_TYPE_UNSUBACK:
+ {
+ MQTT_TRC("Received MQTT_PKT_TYPE_UNSUBACK!");
+
+ evt.id = MQTT_EVT_UNSUBACK;
+ err_code = unpack_uint16(&evt.param.pubrec.message_id,
+ datalen,
+ p_data,
+ &offset);
+ evt.result = err_code;
+ break;
+ }
+ case MQTT_PKT_TYPE_PINGRSP:
+ {
+ MQTT_TRC("Received MQTT_PKT_TYPE_PINGRSP!");
+
+ // No notification of Ping response to application.
+ notify_event = false;
+ break;
+ }
+ default:
+ {
+ // Nothing to notify.
+ notify_event = false;
+ break;
+ }
+ }
+
+ if (notify_event == true)
+ {
+ event_notify(p_client, &evt, MQTT_EVT_FLAG_NONE);
+ }
+
+ return err_code;
+}
+
+
+uint32_t mqtt_handle_rx_data(mqtt_client_t * p_client, uint8_t * p_data, uint32_t datalen)
+{
+ uint32_t err_code = NRF_SUCCESS;
+ uint32_t offset = 0;
+
+ while (offset < datalen)
+ {
+ uint32_t start = offset;
+ uint32_t remaining_length = 0;
+
+ offset = 1; // Skip first byte to offset MQTT packet length.
+ err_code = packet_length_decode(p_data + start,
+ datalen - start,
+ &remaining_length,
+ &offset);
+ if (err_code != NRF_SUCCESS)
+ {
+ return err_code;
+ }
+
+ uint32_t packet_length = offset + remaining_length;
+
+ if (start + packet_length > datalen)
+ {
+ return NRF_ERROR_INVALID_LENGTH;
+ }
+
+ err_code = mqtt_handle_packet(p_client,
+ p_data + start,
+ packet_length,
+ offset);
+ if (err_code != NRF_SUCCESS)
+ {
+ return err_code;
+ }
+
+ offset = start + packet_length;
+ }
+
+ return err_code;
+}
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/mqtt/mqtt_rx.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/mqtt/mqtt_rx.h
new file mode 100644
index 0000000..7372f0c
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/mqtt/mqtt_rx.h
@@ -0,0 +1,74 @@
+/**
+ * Copyright (c) 2015 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 mqtt_rx.h
+ *
+ * @brief Internal methods to submit received packet.
+ */
+
+#ifndef MQTT_RX_H_
+#define MQTT_RX_H_
+
+#include "nordic_common.h"
+#include "sdk_common.h"
+#include "mqtt.h"
+#include "iot_errors.h"
+#include "nrf_tls.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**@brief Handles MQTT messages received from the peer. For TLS, this routine is evoked to handle
+ * decrypted application data. For TCP, this routine is evoked to handle TCP data.
+ *
+ * @param[in] p_client Identifies the client for which the data was received.
+ * @param[in] p_data MQTT data received.
+ * @param[inout] datalen Length of data received.
+ *
+ * @retval NRF_SUCCESS if the procedure is successful, else an error code indicating the reason
+ * for failure.
+ */
+uint32_t mqtt_handle_rx_data(mqtt_client_t * p_client, uint8_t * p_data, uint32_t datalen);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // MQTT_RX_H_
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/mqtt/mqtt_transport.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/mqtt/mqtt_transport.c
new file mode 100644
index 0000000..5d0fbd8
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/mqtt/mqtt_transport.c
@@ -0,0 +1,88 @@
+/**
+ * Copyright (c) 2016 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 mqtt_transport.c
+ *
+ * @brief Internal functions to handle transport in MQTT module.
+ */
+
+
+#include "mqtt_transport.h"
+
+
+/**< Function pointer array for TCP/TLS transport handlers. */
+const transport_procedure_t transport_fn[MQTT_TRANSPORT_MAX] =
+{
+ {
+ mqtt_client_tcp_connect,
+ mqtt_client_tcp_write,
+ mqtt_client_tcp_read,
+ mqtt_client_tcp_disconnect
+ },
+ {
+ mqtt_client_tls_connect,
+ mqtt_client_tls_write,
+ mqtt_client_tls_read,
+ mqtt_client_tls_disconnect
+ }
+};
+
+
+uint32_t mqtt_transport_connect(mqtt_client_t * p_client)
+{
+ return transport_fn[p_client->transport_type].connect(p_client);
+}
+
+
+uint32_t mqtt_transport_write(mqtt_client_t * p_client, uint8_t const * p_data, uint32_t datalen)
+{
+ return transport_fn[p_client->transport_type].write(p_client, p_data, datalen);
+}
+
+
+uint32_t mqtt_transport_read(mqtt_client_t * p_client, uint8_t * p_data, uint32_t datalen)
+{
+ return transport_fn[p_client->transport_type].read(p_client, p_data, datalen);
+}
+
+
+uint32_t mqtt_transport_disconnect(mqtt_client_t * p_client)
+{
+ return transport_fn[p_client->transport_type].disconnect(p_client);
+}
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/mqtt/mqtt_transport.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/mqtt/mqtt_transport.h
new file mode 100644
index 0000000..da588a7
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/mqtt/mqtt_transport.h
@@ -0,0 +1,233 @@
+/**
+ * Copyright (c) 2016 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 mqtt_transport.h
+ *
+ * @brief Internal functions to handle transport in MQTT module.
+ */
+
+#ifndef MQTT_TRANSPORT_H_
+#define MQTT_TRANSPORT_H_
+
+#include "mqtt.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**@brief Transport for handling transport connect procedure. */
+typedef uint32_t (*transport_connect_handler_t)(mqtt_client_t * p_client);
+
+/**@brief Transport write handler. */
+typedef uint32_t (*transport_write_handler_t)(mqtt_client_t * p_client, uint8_t const * data, uint32_t datalen);
+
+/**@brief Transport read handler. */
+typedef uint32_t (*transport_read_handler_t)(mqtt_client_t * p_client, uint8_t * data, uint32_t datalen);
+
+/**@brief Transport disconnect handler. */
+typedef uint32_t (*transport_disconnect_handler_t)(mqtt_client_t * p_client);
+
+/**@brief Transport procedure handlers. */
+typedef struct
+{
+ transport_connect_handler_t connect; /**< Transport connect handler. Handles TCP connection callback based on type of transport.*/
+ transport_write_handler_t write; /**< Transport write handler. Handles transport write based on type of transport. */
+ transport_read_handler_t read; /**< Transport read handler. Handles transport read based on type of transport. */
+ transport_disconnect_handler_t disconnect; /**< Transport disconnect handler. Handles transport disconnection based on type of transport. */
+} transport_procedure_t;
+
+
+/**@brief Handles TCP Connection Complete for configured transport.
+ *
+ * @param[in] p_client Identifies the client on which the procedure is requested.
+ *
+ * @retval NRF_SUCCESS or an error code indicating reason for failure.
+ */
+uint32_t mqtt_transport_connect(mqtt_client_t * p_client);
+
+
+/**@brief Handles write requests on configured transport.
+ *
+ * @param[in] p_client Identifies the client on which the procedure is requested.
+ * @param[in] p_data Data to be written on the transport.
+ * @param[in] datalen Length of data to be written on the transport.
+ *
+ * @retval NRF_SUCCESS or an error code indicating reason for failure.
+ */
+uint32_t mqtt_transport_write(mqtt_client_t * p_client, uint8_t const * p_data, uint32_t datalen);
+
+
+/**@brief Handles read requests on configured transport.
+ *
+ * @param[in] p_client Identifies the client on which the procedure is requested.
+ * @param[in] p_data Pointer where read data is to be fetched.
+ * @param[in] datalen Size of memory provided for the operation.
+ *
+ * @retval NRF_SUCCESS or an error code indicating reason for failure.
+ */
+uint32_t mqtt_transport_read(mqtt_client_t * p_client, uint8_t * p_data, uint32_t datalen);
+
+
+/**@brief Handles transport disconnection requests on configured transport.
+ *
+ * @param[in] p_client Identifies the client on which the procedure is requested.
+ *
+ * @retval NRF_SUCCESS or an error code indicating reason for failure.
+ */
+uint32_t mqtt_transport_disconnect(mqtt_client_t * p_client);
+
+
+/**@brief Initiates TCP Connection.
+ *
+ * @param[in] p_client Identifies the client on which the procedure is requested.
+ *
+ * @retval NRF_SUCCESS or an error code indicating reason for failure.
+ */
+uint32_t tcp_request_connection(mqtt_client_t * p_client);
+
+
+/**
+ * @brief Wait for an incoming MQTT packet.
+ * The registered callback will be called with the packet payload.
+ *
+ * @param[in] p_client Client instance for which the procedure is requested.
+ * Shall not be NULL.
+ * @param[in] timeout Maximum interval (in milliseconds) to wait for a packet.
+ * If timeout is 0, the interval is indefinitely.
+ *
+ * @retval NRF_SUCCESS or an error code indicating reason for failure.
+ */
+uint32_t tcp_receive_packet(mqtt_client_t * p_client, uint32_t timeout);
+
+
+/**@brief Handles TCP Connection Complete for TCP(non-secure) transport.
+ *
+ * @param[in] p_client Identifies the client on which the procedure is requested.
+ *
+ * @retval NRF_SUCCESS or an error code indicating reason for failure.
+ */
+uint32_t mqtt_client_tcp_connect(mqtt_client_t * p_client);
+
+
+/**@brief Handles write requests on TCP(non-secure) transport.
+ *
+ * @param[in] p_client Identifies the client on which the procedure is requested.
+ * @param[in] p_data Data to be written on the transport.
+ * @param[in] datalen Length of data to be written on the transport.
+ *
+ * @retval NRF_SUCCESS or an error code indicating reason for failure.
+ */
+uint32_t mqtt_client_tcp_write(mqtt_client_t * p_client, uint8_t const * p_data, uint32_t datalen);
+
+
+/**@brief Handles read requests on TCP(non-secure) transport.
+ *
+ * @param[in] p_client Identifies the client on which the procedure is requested.
+ * @param[in] p_data Pointer where read data is to be fetched.
+ * @param[in] datalen Size of memory provided for the operation.
+ *
+ * @retval NRF_SUCCESS or an error code indicating reason for failure.
+ */
+uint32_t mqtt_client_tcp_read(mqtt_client_t * p_client, uint8_t * p_data, uint32_t datalen);
+
+
+/**@brief Handles transport disconnection requests on TCP(non-secure) transport.
+ *
+ * @param[in] p_client Identifies the client on which the procedure is requested.
+ *
+ * @retval NRF_SUCCESS or an error code indicating reason for failure.
+ */
+uint32_t mqtt_client_tcp_disconnect(mqtt_client_t * p_client);
+
+
+/**@brief Handles read requests on TLS(secure) transport.
+ *
+ * @param[in] p_client Identifies the client on which the procedure is requested.
+ * @param[in] p_data Pointer where read data is to be fetched.
+ * @param[in] datalen Size of memory provided for the operation.
+ *
+ * @retval NRF_SUCCESS or an error code indicating reason for failure.
+ */
+uint32_t mqtt_client_tls_connect(mqtt_client_t * p_client);
+
+
+/**@brief Handles write requests on TLS(secure) transport.
+ *
+ * @param[in] p_client Identifies the client on which the procedure is requested.
+ * @param[in] p_data Data to be written on the transport.
+ * @param[in] datalen Length of data to be written on the transport.
+ *
+ * @retval NRF_SUCCESS or an error code indicating reason for failure.
+ */
+uint32_t mqtt_client_tls_write(mqtt_client_t * p_client, uint8_t const * p_data, uint32_t datalen);
+
+
+/**@brief Handles read requests on TLS(secure) transport.
+ *
+ * @param[in] p_client Identifies the client on which the procedure is requested.
+ * @param[in] p_data Pointer where read data is to be fetched.
+ * @param[in] datalen Size of memory provided for the operation.
+ *
+ * @retval NRF_SUCCESS or an error code indicating reason for failure.
+ */
+uint32_t mqtt_client_tls_read(mqtt_client_t * p_client, uint8_t * p_data, uint32_t datalen);
+
+
+/**@brief Handles transport disconnection requests on TLS(secure) transport.
+ *
+ * @param[in] p_client Identifies the client on which the procedure is requested.
+ *
+ * @retval NRF_SUCCESS or an error code indicating reason for failure.
+ */
+uint32_t mqtt_client_tls_disconnect(mqtt_client_t * p_client);
+
+
+/**@brief Aborts TCP connection.
+ *
+ * @param[in] p_client Identifies the client on which the procedure is requested.
+ *
+ * @retval NRF_SUCCESS or an error code indicating reason for failure.
+ */
+void mqtt_client_tcp_abort(mqtt_client_t * p_client);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // MQTT_TRANSPORT_H_
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/mqtt/mqtt_transport_lwip.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/mqtt/mqtt_transport_lwip.c
new file mode 100644
index 0000000..b609cd3
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/mqtt/mqtt_transport_lwip.c
@@ -0,0 +1,349 @@
+/**
+ * Copyright (c) 2015 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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
+ *
+ * @brief MQTT Client Implementation over LwIP Stack port on nRF.
+ *
+ * This file contains the source code for MQTT Protocol over LwIP Stack for a nRF device.
+ * The implementation is limited to MQTT Client role only.
+ */
+
+
+#include "mqtt_transport.h"
+#include "mqtt_internal.h"
+#include "mqtt_rx.h"
+
+#include "lwip/opt.h"
+#include "lwip/stats.h"
+#include "lwip/sys.h"
+#include "lwip/pbuf.h"
+/*lint -save -e607 */
+#include "lwip/tcp.h"
+/*lint -restore -e607 */
+
+#if MQTT_CONFIG_LOG_ENABLED
+
+#define NRF_LOG_MODULE_NAME mqtt_lwip
+
+#define NRF_LOG_LEVEL MQTT_CONFIG_LOG_LEVEL
+#define NRF_LOG_INFO_COLOR MQTT_CONFIG_INFO_COLOR
+#define NRF_LOG_DEBUG_COLOR MQTT_CONFIG_DEBUG_COLOR
+
+#include "nrf_log.h"
+NRF_LOG_MODULE_REGISTER();
+
+#define MQTT_TRC NRF_LOG_DEBUG /**< Used for getting trace of execution in the module. */
+#define MQTT_ERR NRF_LOG_ERROR /**< Used for logging errors in the module. */
+#define MQTT_DUMP NRF_LOG_HEXDUMP_DEBUG /**< Used for dumping octet information to get details of bond information etc. */
+
+#define MQTT_ENTRY() MQTT_TRC(">> %s", __func__)
+#define MQTT_EXIT() MQTT_TRC("<< %s", __func__)
+
+#else // MQTT_CONFIG_LOG_ENABLED
+
+#define MQTT_TRC(...) /**< Disables traces. */
+#define MQTT_DUMP(...) /**< Disables dumping of octet streams. */
+#define MQTT_ERR(...) /**< Disables error logs. */
+
+#define MQTT_ENTRY(...)
+#define MQTT_EXIT(...)
+
+#endif // MQTT_CONFIG_LOG_ENABLED
+
+void disconnect_event_notify(mqtt_client_t * p_client, uint32_t result);
+
+
+/**@brief Close TCP connection and clean up client instance.
+ *
+ * @param[in] p_client Identifies the client for which the procedure is requested.
+ */
+static void tcp_close_connection(const mqtt_client_t * p_client)
+{
+ tcp_arg((struct tcp_pcb *)p_client->tcp_id, NULL);
+ UNUSED_VARIABLE(tcp_output((struct tcp_pcb *)p_client->tcp_id));
+ tcp_recv((struct tcp_pcb *)p_client->tcp_id, NULL);
+
+ UNUSED_VARIABLE(tcp_close((struct tcp_pcb *)p_client->tcp_id));
+}
+
+
+err_t tcp_write_complete_cb(void *p_arg, struct tcp_pcb *ttcp_id, u16_t len)
+{
+ MQTT_MUTEX_LOCK();
+
+ mqtt_client_t *p_client = (mqtt_client_t *)(p_arg);
+
+ if (MQTT_VERIFY_STATE(p_client, MQTT_STATE_DISCONNECTING))
+ {
+ MQTT_TRC("[%p]: Closing TCP connection.", p_client);
+ tcp_close_connection(p_client);
+ disconnect_event_notify(p_client, NRF_SUCCESS);
+ }
+ else
+ {
+ MQTT_RESET_STATE(p_client, MQTT_STATE_PENDING_WRITE);
+ MQTT_TRC("[%p]: TCP Write Complete.", p_client);
+ }
+
+ MQTT_MUTEX_UNLOCK();
+
+ return NRF_SUCCESS;
+}
+
+
+uint32_t mqtt_client_tcp_write(mqtt_client_t * p_client, uint8_t const * data, uint32_t datalen)
+{
+ uint32_t retval = (NRF_ERROR_BUSY | IOT_MQTT_ERR_BASE);
+
+ if (MQTT_VERIFY_STATE(p_client, MQTT_STATE_PENDING_WRITE))
+ {
+ retval = (NRF_ERROR_BUSY | IOT_MQTT_ERR_BASE);
+ }
+ else if (MQTT_VERIFY_STATE(p_client, MQTT_STATE_TCP_CONNECTED))
+ {
+ tcp_sent((struct tcp_pcb *)p_client->tcp_id, tcp_write_complete_cb);
+
+ MQTT_MUTEX_UNLOCK ();
+
+ uint32_t err = tcp_write((struct tcp_pcb *)p_client->tcp_id,
+ data,
+ datalen,
+ TCP_WRITE_FLAG_COPY);
+
+ MQTT_MUTEX_LOCK ();
+
+ if (err == ERR_OK)
+ {
+ MQTT_SET_STATE(p_client, MQTT_STATE_PENDING_WRITE);
+ UNUSED_VARIABLE(iot_timer_wall_clock_get(&p_client->last_activity));
+ MQTT_TRC("[%p]: TCP Write in Progress, length 0x%08x.", p_client, datalen);
+ retval = NRF_SUCCESS;
+ }
+ else
+ {
+ MQTT_TRC("[%p]: TCP write failed, err = %d", err);
+ retval = (NRF_ERROR_BUSY | IOT_MQTT_ERR_BASE);
+ }
+ }
+
+ return retval;
+}
+
+
+uint32_t mqtt_client_tcp_read(mqtt_client_t * p_id, uint8_t * p_data, uint32_t datalen)
+{
+ return mqtt_handle_rx_data( p_id, p_data, datalen);
+}
+
+
+/**@brief Callback registered with TCP to handle incoming data on the connection. */
+err_t recv_callback(void * p_arg, struct tcp_pcb * p_tcp_id, struct pbuf * p_buffer, err_t err)
+{
+ MQTT_MUTEX_LOCK();
+
+ mqtt_client_t * p_client = (mqtt_client_t *)(p_arg);
+
+ MQTT_TRC(">> %s, result 0x%08x, buffer %p", __func__, err, p_buffer);
+
+ if (err == ERR_OK && p_buffer != NULL)
+ {
+ MQTT_TRC(">> Packet buffer length 0x%08x ", p_buffer->tot_len);
+ tcp_recved(p_tcp_id, p_buffer->tot_len);
+ UNUSED_VARIABLE(mqtt_transport_read(p_client, p_buffer->payload, p_buffer->tot_len));
+ }
+ else
+ {
+ MQTT_TRC("Error receiving data, closing connection");
+ tcp_close_connection(p_client);
+ disconnect_event_notify(p_client, MQTT_ERR_TRANSPORT_CLOSED);
+ }
+
+ UNUSED_VARIABLE(pbuf_free(p_buffer));
+
+ MQTT_MUTEX_UNLOCK();
+
+ return ERR_OK;
+}
+
+
+uint32_t mqtt_client_tcp_connect(mqtt_client_t * p_client)
+{
+ connect_request_encode(p_client, &p_client->p_pending_packet, &p_client->pending_packetlen);
+
+ // Send MQTT identification message to broker.
+ uint32_t err = mqtt_client_tcp_write(p_client, p_client->p_pending_packet,
+ p_client->pending_packetlen);
+ if (err != ERR_OK)
+ {
+ mqtt_client_tcp_abort(p_client);
+ }
+ else
+ {
+ p_client->p_pending_packet = NULL;
+ p_client->pending_packetlen = 0;
+ }
+
+ return err;
+}
+
+
+/**@brief TCP Connection Callback. MQTT Connection */
+err_t tcp_connection_callback(void * p_arg, struct tcp_pcb * p_tcp_id, err_t err)
+{
+ MQTT_MUTEX_LOCK();
+
+ mqtt_client_t * p_client = (mqtt_client_t *)p_arg;
+
+ if (MQTT_VERIFY_STATE(p_client, MQTT_STATE_TCP_CONNECTING) &&
+ (err == ERR_OK))
+ {
+ MQTT_SET_STATE(p_client, MQTT_STATE_TCP_CONNECTED);
+
+ // Register callback.
+ tcp_recv(p_tcp_id, recv_callback);
+ uint32_t err_code = mqtt_transport_connect(p_client);
+
+ if (err_code != NRF_SUCCESS)
+ {
+ MQTT_TRC("Transport connect handler returned %08x", err_code);
+ disconnect_event_notify(p_client, MQTT_CONNECTION_FAILED);
+ }
+ }
+
+ MQTT_MUTEX_UNLOCK();
+
+ return err;
+}
+
+
+void mqtt_client_tcp_abort(mqtt_client_t * p_client)
+{
+ tcp_abort((struct tcp_pcb *)p_client->tcp_id);
+ disconnect_event_notify(p_client, MQTT_ERR_TCP_PROC_FAILED);
+ MQTT_STATE_INIT(p_client);
+}
+
+
+void tcp_error_handler(void * p_arg, err_t err)
+{
+ MQTT_MUTEX_LOCK();
+
+ mqtt_client_t * p_client = (mqtt_client_t *)(p_arg);
+
+ disconnect_event_notify(p_client, err);
+
+ MQTT_STATE_INIT(p_client);
+
+ MQTT_MUTEX_UNLOCK();
+}
+
+
+err_t tcp_connection_poll(void * p_arg, struct tcp_pcb * p_tcp_id)
+{
+ MQTT_MUTEX_LOCK();
+
+ mqtt_client_t * p_client = (mqtt_client_t *)(p_arg);
+
+ p_client->poll_abort_counter++;
+
+ MQTT_MUTEX_UNLOCK();
+
+ return ERR_OK;
+}
+
+
+uint32_t tcp_request_connection(mqtt_client_t * p_client)
+{
+ p_client->poll_abort_counter = 0;
+ p_client->tcp_id = (uint32_t)tcp_new_ip6();
+
+ err_t err = tcp_connect((struct tcp_pcb *)p_client->tcp_id,
+ (ip_addr_t *)&p_client->broker_addr,
+ p_client->broker_port,
+ tcp_connection_callback);
+
+ if (err != ERR_OK)
+ {
+ UNUSED_VARIABLE(mqtt_abort(p_client));
+ }
+ else
+ {
+ tcp_arg((struct tcp_pcb *)p_client->tcp_id, p_client);
+ tcp_err((struct tcp_pcb *)p_client->tcp_id, tcp_error_handler);
+ tcp_poll((struct tcp_pcb *)p_client->tcp_id, tcp_connection_poll, 10);
+ tcp_accept((struct tcp_pcb *)p_client->tcp_id, tcp_connection_callback);
+
+ MQTT_SET_STATE(p_client, MQTT_STATE_TCP_CONNECTING);
+ }
+
+ return err;
+}
+
+
+uint32_t mqtt_client_tcp_disconnect(mqtt_client_t * p_client)
+{
+ uint32_t err_code = NRF_ERROR_INVALID_STATE;
+
+ if (MQTT_VERIFY_STATE(p_client, MQTT_STATE_CONNECTED))
+ {
+ const uint8_t packet[] = {MQTT_PKT_TYPE_DISCONNECT, 0x00};
+ UNUSED_VARIABLE(tcp_write((struct tcp_pcb *)p_client->tcp_id,
+ (void *)packet,
+ sizeof(packet),
+ 1));
+
+ tcp_close_connection(p_client);
+ err_code = NRF_SUCCESS;
+ }
+ else if (MQTT_VERIFY_STATE(p_client, MQTT_STATE_TCP_CONNECTED))
+ {
+ tcp_close_connection(p_client);
+ err_code = NRF_SUCCESS;
+ }
+
+ return err_code;
+}
+
+
+uint32_t tcp_receive_packet(mqtt_client_t * p_client, uint32_t timeout)
+{
+ // This is not used in the lwip transport implementation.
+ return NRF_ERROR_NOT_SUPPORTED | IOT_MQTT_ERR_BASE;
+}
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/mqtt/mqtt_transport_socket.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/mqtt/mqtt_transport_socket.c
new file mode 100644
index 0000000..27bf6b6
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/mqtt/mqtt_transport_socket.c
@@ -0,0 +1,319 @@
+/**
+ * Copyright (c) 2016 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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
+ *
+ * @brief MQTT Client Implementation over BSD Socket API on nRF.
+ *
+ * This file contains the source code for MQTT Protocol over BSD Socket API for a nRF device.
+ * The implementation is limited to MQTT Client role only.
+ */
+
+
+#include <unistd.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+
+#include "mem_manager.h"
+#include "mqtt_transport.h"
+#include "mqtt_internal.h"
+#include "mqtt_rx.h"
+
+#if MQTT_CONFIG_LOG_ENABLED
+
+#define NRF_LOG_MODULE_NAME mqtt_soc
+
+#define NRF_LOG_LEVEL MQTT_CONFIG_LOG_LEVEL
+#define NRF_LOG_INFO_COLOR MQTT_CONFIG_INFO_COLOR
+#define NRF_LOG_DEBUG_COLOR MQTT_CONFIG_DEBUG_COLOR
+
+#include "nrf_log.h"
+NRF_LOG_MODULE_REGISTER();
+
+#define MQTT_TRC NRF_LOG_DEBUG /**< Used for getting trace of execution in the module. */
+#define MQTT_ERR NRF_LOG_ERROR /**< Used for logging errors in the module. */
+#define MQTT_DUMP NRF_LOG_HEXDUMP_DEBUG /**< Used for dumping octet information to get details of bond information etc. */
+
+#define MQTT_ENTRY() MQTT_TRC(">> %s", __func__)
+#define MQTT_EXIT() MQTT_TRC("<< %s", __func__)
+
+#else // MQTT_CONFIG_LOG_ENABLED
+
+#define MQTT_TRC(...) /**< Disables traces. */
+#define MQTT_DUMP(...) /**< Disables dumping of octet streams. */
+#define MQTT_ERR(...) /**< Disables error logs. */
+
+#define MQTT_ENTRY(...)
+#define MQTT_EXIT(...)
+
+#endif // MQTT_CONFIG_LOG_ENABLED
+
+void disconnect_event_notify(mqtt_client_t * p_client, uint32_t result);
+
+
+/**@brief Close TCP connection and clean up client instance.
+ *
+ * @param[in] p_client Identifies the client for which the procedure is requested.
+ */
+static void tcp_close_connection(const mqtt_client_t * p_client)
+{
+ MQTT_TRC("Closing socket %d", p_client->socket_fd);
+ UNUSED_VARIABLE(close(p_client->socket_fd));
+}
+
+
+uint32_t mqtt_client_tcp_write(mqtt_client_t * p_client, uint8_t const * data, uint32_t datalen)
+{
+ uint32_t err_code = (NRF_ERROR_BUSY | IOT_MQTT_ERR_BASE);
+
+ if (MQTT_VERIFY_STATE(p_client, MQTT_STATE_PENDING_WRITE))
+ {
+ err_code = (NRF_ERROR_BUSY | IOT_MQTT_ERR_BASE);
+ }
+ else if (MQTT_VERIFY_STATE(p_client, MQTT_STATE_TCP_CONNECTED))
+ {
+ MQTT_TRC("[%p]: TCP writing %d bytes.", p_client, datalen);
+ MQTT_SET_STATE(p_client, MQTT_STATE_PENDING_WRITE);
+
+ MQTT_MUTEX_UNLOCK();
+
+ ssize_t nbytes = send(p_client->socket_fd, data, datalen, 0);
+
+ MQTT_MUTEX_LOCK();
+
+ MQTT_RESET_STATE(p_client, MQTT_STATE_PENDING_WRITE);
+
+ if (nbytes == datalen)
+ {
+ MQTT_TRC("[%p]: TCP write complete.", p_client);
+ UNUSED_VARIABLE(iot_timer_wall_clock_get(&p_client->last_activity));
+ err_code = NRF_SUCCESS;
+ }
+ else
+ {
+ MQTT_TRC("TCP write failed, errno = %d, closing connection", errno);
+ tcp_close_connection(p_client);
+ disconnect_event_notify(p_client, MQTT_ERR_TRANSPORT_CLOSED);
+ err_code = (NRF_ERROR_INTERNAL | IOT_MQTT_ERR_BASE);
+ }
+ }
+ else
+ {
+ err_code = MQTT_ERR_NOT_CONNECTED;
+ }
+
+ return err_code;
+}
+
+
+uint32_t mqtt_client_tcp_read(mqtt_client_t * p_client, uint8_t * p_data, uint32_t datalen)
+{
+ return mqtt_handle_rx_data(p_client, p_data, datalen);
+}
+
+
+uint32_t mqtt_client_tcp_connect(mqtt_client_t * p_client)
+{
+ uint32_t err_code;
+
+ connect_request_encode(p_client, &p_client->p_pending_packet, &p_client->pending_packetlen);
+
+ // Send MQTT identification message to broker.
+ MQTT_SET_STATE(p_client, MQTT_STATE_PENDING_WRITE);
+
+ MQTT_MUTEX_UNLOCK();
+
+ ssize_t nbytes = send(p_client->socket_fd,
+ p_client->p_pending_packet,
+ p_client->pending_packetlen,
+ 0);
+
+ MQTT_MUTEX_LOCK();
+
+ MQTT_RESET_STATE(p_client, MQTT_STATE_PENDING_WRITE);
+
+ if (nbytes == p_client->pending_packetlen)
+ {
+ UNUSED_VARIABLE(iot_timer_wall_clock_get(&p_client->last_activity));
+ p_client->p_pending_packet = NULL;
+ p_client->pending_packetlen = 0;
+ err_code = NRF_SUCCESS;
+ }
+ else
+ {
+ mqtt_client_tcp_abort(p_client);
+ err_code = (NRF_ERROR_INTERNAL | IOT_MQTT_ERR_BASE);
+ }
+
+ return err_code;
+}
+
+
+void mqtt_client_tcp_abort(mqtt_client_t * p_client)
+{
+ tcp_close_connection(p_client);
+ disconnect_event_notify(p_client, MQTT_ERR_TCP_PROC_FAILED);
+}
+
+
+uint32_t tcp_receive_packet(mqtt_client_t * p_client, uint32_t timeout)
+{
+ if (timeout != 0)
+ {
+ // TODO: Implement support for timeout.
+ return NRF_ERROR_NOT_SUPPORTED | IOT_MQTT_ERR_BASE;
+ }
+
+ uint8_t * p_packet = nrf_malloc(MQTT_MAX_PACKET_LENGTH);
+ if (p_packet == NULL)
+ {
+ return NRF_ERROR_NO_MEM | IOT_MQTT_ERR_BASE;
+ }
+
+ MQTT_MUTEX_UNLOCK();
+
+ ssize_t p_len = recv(p_client->socket_fd, p_packet, MQTT_MAX_PACKET_LENGTH, 0);
+
+ MQTT_MUTEX_LOCK();
+
+ uint32_t err_code;
+
+ if (p_len > 0)
+ {
+ err_code = mqtt_transport_read(p_client, p_packet, p_len);
+ MQTT_TRC("Received %d bytes from %d: 0x%08x",
+ p_len, p_client->socket_fd, err_code);
+ }
+ else if (p_len == 0)
+ {
+ // Receiving 0 bytes indicates an orderly shutdown.
+ MQTT_TRC("Received end of stream, closing connection");
+ tcp_close_connection(p_client);
+ disconnect_event_notify(p_client, MQTT_ERR_TRANSPORT_CLOSED);
+ err_code = NRF_SUCCESS;
+ }
+ else
+ {
+ MQTT_TRC("Error receiving data, errno = %d, closing connection", errno);
+ mqtt_client_tcp_abort(p_client);
+ err_code = (NRF_ERROR_INVALID_DATA | IOT_MQTT_ERR_BASE);
+ }
+
+ nrf_free(p_packet);
+
+ return err_code;
+}
+
+
+uint32_t tcp_request_connection(mqtt_client_t * p_client)
+{
+ uint32_t err_code = NRF_SUCCESS;
+
+ p_client->socket_fd = socket(AF_INET6, SOCK_STREAM, 0);
+ MQTT_TRC("Created socket %d", p_client->socket_fd);
+ if (p_client->socket_fd < 0)
+ {
+ err_code = (NRF_ERROR_INTERNAL | IOT_MQTT_ERR_BASE);
+ }
+
+ if (err_code == NRF_SUCCESS)
+ {
+ struct sockaddr_in6 dest;
+ memset(&dest, 0, sizeof(dest));
+ dest.sin6_family = AF_INET6;
+ dest.sin6_port = htons(p_client->broker_port);
+ memcpy(&dest.sin6_addr, p_client->broker_addr.u8, sizeof(dest.sin6_addr));
+
+ int ret = connect(p_client->socket_fd, (struct sockaddr *)&dest, sizeof(dest));
+ if (ret == 0)
+ {
+ MQTT_SET_STATE(p_client, MQTT_STATE_TCP_CONNECTED);
+ err_code = mqtt_transport_connect(p_client);
+ MQTT_TRC("Sent connect %d: 0x%08x", p_client->socket_fd, err_code);
+ }
+ else
+ {
+ mqtt_client_tcp_abort(p_client);
+ err_code = (NRF_ERROR_INTERNAL | IOT_MQTT_ERR_BASE);
+ }
+ }
+
+ while (!MQTT_VERIFY_STATE(p_client, MQTT_STATE_CONNECTED) && err_code == NRF_SUCCESS)
+ {
+ // Receive until connected.
+ MQTT_TRC("Receive until connected");
+ err_code = tcp_receive_packet(p_client, 0);
+ }
+
+ MQTT_TRC("Connect completed");
+ return err_code;
+}
+
+
+uint32_t mqtt_client_tcp_disconnect(mqtt_client_t * p_client)
+{
+ uint32_t err_code;
+
+ if (MQTT_VERIFY_STATE(p_client, MQTT_STATE_CONNECTED))
+ {
+ const uint8_t packet[] = {MQTT_PKT_TYPE_DISCONNECT, 0x00};
+ MQTT_SET_STATE(p_client, MQTT_STATE_PENDING_WRITE);
+
+ MQTT_MUTEX_UNLOCK();
+
+ UNUSED_VARIABLE(send(p_client->socket_fd, (void *)packet, sizeof(packet), 0));
+
+ MQTT_MUTEX_LOCK();
+
+ MQTT_RESET_STATE(p_client, MQTT_STATE_PENDING_WRITE);
+ tcp_close_connection(p_client);
+ err_code = NRF_SUCCESS;
+ }
+ else if (MQTT_VERIFY_STATE(p_client, MQTT_STATE_TCP_CONNECTED))
+ {
+ tcp_close_connection(p_client);
+ err_code = NRF_SUCCESS;
+ }
+ else
+ {
+ err_code = (NRF_ERROR_INVALID_STATE | IOT_MQTT_ERR_BASE);
+ }
+
+ return err_code;
+}
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/mqtt/mqtt_transport_tls.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/mqtt/mqtt_transport_tls.c
new file mode 100644
index 0000000..8f74600
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/mqtt/mqtt_transport_tls.c
@@ -0,0 +1,185 @@
+/**
+ * Copyright (c) 2016 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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
+ *
+ * @brief MQTT Client Implementation TLS layer.
+ *
+ * This file contains the source code for MQTT Protocol TLS layer for a nRF device.
+ * The implementation is limited to MQTT Client role only.
+ */
+
+
+#include "mqtt_transport.h"
+#include "mqtt_internal.h"
+#include "mqtt_rx.h"
+#include "mem_manager.h"
+
+#if MQTT_CONFIG_LOG_ENABLED
+
+#define NRF_LOG_MODULE_NAME mqtt_tls
+
+#define NRF_LOG_LEVEL MQTT_CONFIG_LOG_LEVEL
+#define NRF_LOG_INFO_COLOR MQTT_CONFIG_INFO_COLOR
+#define NRF_LOG_DEBUG_COLOR MQTT_CONFIG_DEBUG_COLOR
+
+#include "nrf_log.h"
+NRF_LOG_MODULE_REGISTER();
+
+#define MQTT_TRC NRF_LOG_DEBUG /**< Used for getting trace of execution in the module. */
+#define MQTT_ERR NRF_LOG_ERROR /**< Used for logging errors in the module. */
+#define MQTT_DUMP NRF_LOG_HEXDUMP_DEBUG /**< Used for dumping octet information to get details of bond information etc. */
+
+#define MQTT_ENTRY() MQTT_TRC(">> %s", __func__)
+#define MQTT_EXIT() MQTT_TRC("<< %s", __func__)
+
+#else // MQTT_CONFIG_LOG_ENABLED
+
+#define MQTT_TRC(...) /**< Disables traces. */
+#define MQTT_DUMP(...) /**< Disables dumping of octet streams. */
+#define MQTT_ERR(...) /**< Disables error logs. */
+
+#define MQTT_ENTRY(...)
+#define MQTT_EXIT(...)
+
+#endif // MQTT_CONFIG_LOG_ENABLED
+
+uint32_t mqtt_client_tls_output_handler(nrf_tls_instance_t const * p_instance,
+ uint8_t const * p_data,
+ uint32_t datalen)
+{
+ NULL_PARAM_CHECK(p_instance);
+
+ uint32_t err_code = NRF_ERROR_INTERNAL;
+ mqtt_client_t * p_client = (mqtt_client_t *)p_instance->transport_id;
+
+ MQTT_MUTEX_LOCK();
+
+ MQTT_TRC(">> %s, client %p", __func__, p_client);
+
+ if (p_client != NULL)
+ {
+ err_code = mqtt_client_tcp_write(p_client, p_data, datalen);
+ }
+
+ MQTT_TRC("<< %s, client %p, result 0x%08x", __func__,
+ p_client, err_code);
+
+ MQTT_MUTEX_UNLOCK();
+
+ return err_code;
+}
+
+
+uint32_t mqtt_client_tls_connect(mqtt_client_t * p_client)
+{
+ const nrf_tls_options_t tls_option =
+ {
+ .output_fn = mqtt_client_tls_output_handler,
+ .transport_type = NRF_TLS_TYPE_STREAM,
+ .role = NRF_TLS_ROLE_CLIENT,
+ .p_key_settings = p_client->p_security_settings
+ };
+
+ connect_request_encode(p_client,
+ &p_client->p_pending_packet,
+ &p_client->pending_packetlen);
+
+ p_client->tls_instance.transport_id = (uint32_t)p_client;
+
+ MQTT_MUTEX_UNLOCK ();
+
+ uint32_t err_code = nrf_tls_alloc(&p_client->tls_instance, &tls_option);
+
+ MQTT_MUTEX_LOCK ();
+
+ return err_code;
+}
+
+
+uint32_t mqtt_client_tls_write(mqtt_client_t * p_client,
+ uint8_t const * p_data,
+ uint32_t datalen)
+{
+ MQTT_MUTEX_UNLOCK ();
+
+ uint32_t err_code = nrf_tls_write(&p_client->tls_instance, p_data, &datalen);
+
+ MQTT_MUTEX_LOCK ();
+
+ return err_code;
+}
+
+
+uint32_t mqtt_client_tls_read(mqtt_client_t * p_client, uint8_t * p_data, uint32_t datalen)
+{
+ uint32_t err = nrf_tls_input(&p_client->tls_instance, p_data, datalen);
+
+ if ((err == NRF_SUCCESS) && (p_client->p_pending_packet == NULL))
+ {
+ uint32_t rx_datalen = 1024;
+ uint8_t * p_mqtt_data = nrf_malloc(1024);
+
+ if (p_data != NULL)
+ {
+ MQTT_MUTEX_UNLOCK ();
+
+ err = nrf_tls_read(&p_client->tls_instance,
+ p_mqtt_data,
+ &rx_datalen);
+
+ MQTT_MUTEX_LOCK ();
+
+ if ((err == NRF_SUCCESS) && (rx_datalen > 0))
+ {
+ err = mqtt_handle_rx_data(p_client, p_mqtt_data, rx_datalen);
+ }
+
+ nrf_free(p_mqtt_data);
+ }
+ }
+
+ return err;
+}
+
+
+uint32_t mqtt_client_tls_disconnect(mqtt_client_t * p_client)
+{
+ return mqtt_client_tcp_disconnect(p_client);
+}
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/socket/README.md b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/socket/README.md
new file mode 100644
index 0000000..9ec0b8d
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/socket/README.md
@@ -0,0 +1,28 @@
+# Socket module
+
+The socket module contains the BSD socket implementation for the IoT SDK. The purpose of the socket
+API is to
+
+* Provide a common API for all platforms
+* Simplify porting of pc network applications
+
+The socket API hides details of the underlying transport, but supports proprietary extensions for
+controlling configuration settings and using underlying transport layers.
+
+<pre>
+socket/
+ api/ - Public socket API headers
+ common/ - Common implementation of API and implementation code shared by all platforms (main socket API implementation, with hooks for different transports)
+ libraries/ - Generic libraries that are not tied to a specific platform
+ portdb/ - Port database to track and allocate socket ports
+ addr_util/ - Common address utilities
+ mbuf/ - Memory buffer utilities
+ transport/ - Transport/network stack hooks
+ ipv6/ - Nordic IPv6 stack transport hook
+ lwip/ - LwIP transport hook
+ test/ - Integration tests shared between transport stacks
+ platform/ - Platform specific code
+ ble/ - BLE specific code (only wrappers around sd_ble_app_evt_())
+ config/ - Configuration socket implementations
+ medium/ - Medium configuration socket implementation
+</pre>
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/socket/api/arpa/inet.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/socket/api/arpa/inet.h
new file mode 100644
index 0000000..c1749d3
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/socket/api/arpa/inet.h
@@ -0,0 +1,45 @@
+/**
+ * Copyright (c) 2015 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#ifndef SOCKET_ARPA_INET_H__
+#define SOCKET_ARPA_INET_H__
+
+#include "socket_api.h"
+
+#endif
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/socket/api/netinet/in.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/socket/api/netinet/in.h
new file mode 100644
index 0000000..bfcf881
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/socket/api/netinet/in.h
@@ -0,0 +1,45 @@
+/**
+ * Copyright (c) 2015 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#ifndef SOCKET_NETINET_IN_H__
+#define SOCKET_NETINET_IN_H__
+
+#include "socket_api.h"
+
+#endif
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/socket/api/socket_api.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/socket/api/socket_api.h
new file mode 100644
index 0000000..37e50d4
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/socket/api/socket_api.h
@@ -0,0 +1,593 @@
+/**
+ * Copyright (c) 2015 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 socket_api.h
+ *
+ * @defgroup iot_socket BSD Socket interface
+ * @ingroup iot_sdk_socket
+ * @{
+ * @brief Nordic socket interface for IoT.
+ *
+ * @details This module provides the socket interface for writing IoT applications. The API is
+ * designed to be compatible with the POSIX/BSD socket interface for the purpose of
+ * making porting easy. The socket options API has been extended to support configuring
+ * Nordic BLE stack, tuning of RF parameters as well as security options.
+ */
+#ifndef SOCKET_API_H__
+#define SOCKET_API_H__
+
+#include <stdint.h>
+
+#include "sdk_common.h"
+#include "iot_defines.h"
+#include "errno.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#if !defined(__GNUC__) || (__GNUC__ == 0)
+typedef int32_t ssize_t;
+#else
+#include <sys/types.h>
+#ifdef __SES_ARM
+typedef int32_t ssize_t;
+#endif
+#endif
+
+#ifndef htons
+#define htons(x) HTONS(x) /**< Convert byte order from host to network (short). */
+#endif
+
+#ifndef htonl
+#define htonl(x) HTONL(x) /**< Convert byte order from host to network (long). */
+#endif
+
+#ifndef ntohs
+#define ntohs(x) NTOHS(x) /**< Convert byte order from network to host (short). */
+#endif
+
+#ifndef ntohl
+#define ntohl(x) NTOHL(x) /**< Convert byte order from network to host (long). */
+#endif
+
+/**@defgroup socket_families Values for socket_family_t
+ * @ingroup iot_socket
+ * @{
+ */
+#define AF_INET 2 /**< IPv4 socket family. */
+#define AF_INET6 10 /**< IPv6 socket family. */
+#if defined(NRF52) || defined(NRF52_SERIES)
+#define AF_NRF_CFG 39 /**< nRF configuration socket.*/
+#endif
+/**@} */
+
+/**@defgroup socket_types Values for socket_type_t
+ * @ingroup iot_socket
+ * @{
+ */
+#define SOCK_STREAM 1 /**< TCP socket type. */
+#define SOCK_DGRAM 2 /**< UDP socket type. */
+/**@} */
+
+/**@defgroup socket_protocols Values for socket_protocol_t
+ * @ingroup iot_socket
+ * @{
+ */
+#define IPPROTO_TCP 1 /**< Use TCP as transport protocol. */
+#define IPPROTO_UDP 2 /**< Use UDP as transport protocol. */
+/**@} */
+
+/**@defgroup socket_send_recv_flags Socket send/recv flags
+ * @ingroup iot_socket
+ * @{
+ */
+#define MSG_DONTROUTE 0x01 /**< Send only to hosts on directly connected networks. */
+#define MSG_DONTWAIT 0x02 /**< Enables non-blocking operation. */
+#define MSG_OOB 0x04 /**< Sends out-of-band data on sockets that support this. */
+#define MSG_PEEK 0x08 /**< Return data from the beginning of receive queue without removing data from the queue. */
+#define MSG_WAITALL 0x10 /**< Request a blocking operation until the request is satisfied. */
+/**@} */
+
+#if defined(NRF52) || defined(NRF52_SERIES)
+/**
+ * @defgroup socket_option_levels Values for socket_opt_lvl_t
+ * @ingroup iot_socket
+ * @{
+ */
+#define SOL_SOCKET 1 /**< Standard socket options. */
+#define SOL_NRF_MEDIUM 2 /**< Nordic medium socket options. Use this to control medium parameters. */
+/**@} */
+
+/**@defgroup socket_medium_options Medium socket option level types
+ * @ingroup iot_socket
+ * @{
+ */
+#define MEDIUM_INIT_PARAMS 1 /**< Medium initialization parameters. */
+/**@}
+ */
+#endif
+
+/**@defgroup fcnt_commands fcntl commands
+ * @ingroup iot_socket
+ * @{
+ */
+#define F_SETFL 1 /**< Set flag. */
+#define F_GETFL 2 /**< Get flag. */
+/**@} */
+
+/**@defgroup fcnt_flags fcntl flags
+ * @ingroup iot_socket
+ * @{
+ */
+#define O_NONBLOCK 0x01 /**< Use non-blocking I/O. */
+/**@} */
+
+/**
+ * @brief Socket module size type.
+ */
+typedef uint32_t socklen_t;
+
+/**
+ * @brief Socket port type.
+ */
+typedef uint16_t in_port_t;
+
+/**
+ * @brief Structure specifying time interval.
+ */
+struct timeval
+{
+ uint32_t tv_sec; /**< Time interval seconds. */
+ uint32_t tv_usec; /**< Time interval microseconds. */
+};
+
+/**
+ * @brief Socket families.
+ *
+ * @details For a list of valid values, refer to @ref socket_families.
+ */
+typedef int socket_family_t;
+typedef socket_family_t sa_family_t;
+
+/**
+ * @brief Socket types.
+ *
+ * @details For a list of valid values refer to @ref socket_types.
+ */
+typedef int socket_type_t;
+
+/**
+ * @brief Socket protocols.
+ *
+ * @details Use 0 if you do not want do specify socket protocol, which should be sufficient for most users.
+ * Other values are only provided for socket API compatibility, see @ref socket_protocols.
+ */
+typedef int socket_protocol_t;
+
+/**
+ * @if (IOT)
+ * @brief Socket option levels.
+ *
+ * @details For a list of valid values, refer to @ref socket_option_levels.
+ * @endif
+ */
+typedef int socket_opt_lvl_t;
+
+/**
+ * @brief Generic socket address.
+ *
+ * @details Only provided for API compatibility.
+ */
+struct sockaddr
+{
+ uint8_t sa_len;
+ socket_family_t sa_family;
+ char sa_data[];
+};
+
+/**
+ * @brief IPv6 address.
+ */
+struct in6_addr
+{
+ uint8_t s6_addr[16];
+};
+
+/**
+ * @brief IPv4 address.
+ */
+typedef uint32_t in_addr_t;
+
+/**
+ * @brief IPv4 address structure.
+ */
+struct in_addr
+{
+ in_addr_t s_addr;
+};
+
+/**
+ * @brief Global IPv6 any-address.
+ */
+extern const struct in6_addr in6addr_any;
+
+/**
+ * @brief Global IPv4 any-address.
+ */
+extern const struct in_addr inaddr_any;
+
+/**
+ * @brief Address record for IPv6 addresses.
+ *
+ * @details Contains the address and port of the host, as well as other socket options. All fields
+ * in this structure are compatible with the POSIX variant for API compatibility.
+ */
+struct sockaddr_in6
+{
+ uint8_t sin6_len; /**< Length of this data structure. */
+ sa_family_t sin6_family; /**< Socket family. */
+ in_port_t sin6_port; /**< Port, in network byte order. */
+
+ uint32_t sin6_flowinfo; /**< IPv6 flow info parameters. Not used. */
+ struct in6_addr sin6_addr; /**< IPv6 address. */
+ uint32_t sin6_scope_id; /**< IPv6 scope ID. Not used. */
+};
+
+/**
+ * @brief Address record for IPv4 addresses.
+ *
+ * @details Contains the address and port of the host. All fields
+ * in this structure are compatible with the POSIX variant for API compatibility.
+ */
+struct sockaddr_in
+{
+ uint8_t sin_len; /**< Length of this data structure. */
+ sa_family_t sin_family; /**< Socket family. */
+ in_port_t sin_port; /**< Port, in network byte order. */
+
+ struct in_addr sin_addr; /**< IPv4 address. */
+};
+
+typedef struct sockaddr sockaddr_t;
+typedef struct sockaddr_in6 sockaddr_in6_t;
+typedef struct in6_addr in6_addr_t;
+typedef struct sockaddr_in sockaddr_in_t;
+
+/**
+ * @brief Function for creating a socket.
+ *
+ * @details API to create a socket that can be used for network communication independently
+ * of lower protocol layers.
+ *
+ * @param[in] family The protocol family of the network protocol to use. Currently, only
+ * AF_INET6 is supported.
+ * @param[in] type The protocol type to use for this socket.
+ * @param[in] protocol The transport protocol to use for this socket.
+ *
+ * @return A non-negative socket descriptor on success, or -1 on error.
+ */
+int socket(socket_family_t family, socket_type_t type, socket_protocol_t protocol);
+
+/**
+ * @brief Function for closing a socket and freeing any resources held by it.
+ *
+ * @details If the socket is already closed, this function is a noop.
+ *
+ * @param[in] sock The socket to close.
+ *
+ * @return 0 on success, or -1 on error.
+ */
+int close(int sock);
+
+/**
+ * @brief Function for controlling file descriptor options.
+ *
+ * @details Set or get file descriptor options or flags. For a list of supported commands, refer to @ref fcnt_commands.
+ * For a list of supported flags, refer to @ref fcnt_flags.
+ *
+ * @param[in] fd The descriptor to set options on.
+ * @param[in] cmd The command class for options.
+ * @param[in] flags The flags to set.
+ */
+int fcntl(int fd, int cmd, int flags);
+
+/**
+ * @brief Function for connecting to an endpoint with a given address.
+ *
+ * @details The socket handle must be a valid handle that has not yet been connected. Running
+ * connect on a connected handle will return an error.
+ *
+ * @param[in] sock The socket to use for connection.
+ * @param[in] p_servaddr The address of the server to connect to. Currently, sockaddr_in6 is
+ * the only supported type.
+ * @param[in] addrlen The size of the p_servaddr argument.
+ *
+ * @return 0 on success, or -1 on error.
+ */
+int connect(int sock, const void * p_servaddr, socklen_t addrlen);
+
+/**
+ * @brief Function for sending data through a socket.
+ *
+ * @details By default, this function will block unless the O_NONBLOCK
+ * socket option has been set, OR MSG_DONTWAIT is passed as a flag. In that case, the
+ * method will return immediately.
+ *
+ * @param[in] sock The socket to write data to.
+ * @param[in] p_buff Buffer containing the data to send.
+ * @param[in] nbytes Size of data contained on p_buff.
+ * @param[in] flags Flags to control send behavior.
+ *
+ * @return The number of bytes that were sent on success, or -1 on error.
+ */
+ssize_t send(int sock, const void * p_buff, size_t nbytes, int flags);
+
+/**
+ * @brief Function for sending datagram through a socket.
+ *
+ * @details By default, this function will block if the lower layers are not able to process the
+ * packet, unless the O_NONBLOCK socket option has been set, OR MSG_DONTWAIT is passed as a flag.
+ * In that case, the method will return immediately.
+ *
+ * @param[in] sock The socket to write data to.
+ * @param[in] p_buff Buffer containing the data to send.
+ * @param[in] nbytes Size of data contained in p_buff.
+ * @param[in] flags Flags to control send behavior.
+ * @param[in] p_servaddr The address of the server to send to. Currently, sockaddr_in6 is
+ * the only supported type.
+ * @param[in] addrlen The size of the p_servaddr argument.
+ *
+ * @return The number of bytes that were sent on success, or -1 on error.
+ */
+ssize_t sendto(int sock,
+ const void * p_buff,
+ size_t nbytes,
+ int flags,
+ const void * p_servaddr,
+ socklen_t addrlen);
+
+/**
+ * @brief Function for writing data to a socket. See \ref send() for details.
+ *
+ * @param[in] sock The socket to write data to.
+ * @param[in] p_buff Buffer containing the data to send.
+ * @param[in] nbytes Size of data contained in p_buff.
+ *
+ * @return The number of bytes that were sent on success, or -1 on error.
+ */
+ssize_t write(int sock, const void * p_buff, size_t nbytes);
+
+/**
+ * @brief Function for receiving data on a socket.
+ *
+ * @details API for receiving data from a socket. By default, this function will block, unless the
+ * O_NONBLOCK socket option has been set, or MSG_DONTWAIT is passed as a flag.
+ *
+ * @param[in] sock The socket to receive data from.
+ * @param[out] p_buff Buffer to hold the data to be read.
+ * @param[in] nbytes Number of bytes to read. Should not be larger than the size of p_buff.
+ * @param[in] flags Flags to control receive behavior.
+ *
+ * @return The number of bytes that were read, or -1 on error.
+ */
+ssize_t recv(int sock, void * p_buff, size_t nbytes, int flags);
+
+/**
+ * @brief Function for receiving datagram on a socket.
+ *
+ * @details API for receiving data from a socket. By default, this function will block, unless the
+ * O_NONBLOCK socket option has been set, or MSG_DONTWAIT is passed as a flag.
+ *
+ * @param[in] sock The socket to receive data from.
+ * @param[out] p_buff Buffer to hold the data to be read.
+ * @param[in] nbytes Number of bytes to read. Should not be larger than the size of p_buff.
+ * @param[in] flags Flags to control receive behavior.
+ * @param[out] p_cliaddr Socket address that will be set to the client's address.
+ * @param[inout] p_addrlen The size of the p_cliaddr passed. Might be modified by the function.
+ *
+ * @return The number of bytes that were read, or -1 on error.
+ */
+ssize_t recvfrom(int sock,
+ void * p_buff,
+ size_t nbytes,
+ int flags,
+ void * p_cliaddr,
+ socklen_t * p_addrlen);
+
+/**
+ * @brief Function for reading data from a socket. See \ref recv() for details.
+ *
+ * @param[in] sock The socket to receive data from.
+ * @param[out] p_buff Buffer to hold the data to be read.
+ * @param[in] nbytes Number of bytes to read. Should not be larger than the size of p_buff.
+ *
+ * @return The number of bytes that were read, or -1 on error.
+ */
+ssize_t read(int sock, void * p_buff, size_t nbytes);
+
+/**
+ * @defgroup fd_set_api API for file descriptor set
+ * @ingroup iot_socket
+ * @details File descriptor sets are used as input to the select() function for doing I/O
+ * multiplexing. The maximum number of descriptors contained in a set is defined by
+ * FD_SETSIZE.
+ *
+ * @{
+ */
+#ifndef FD_ZERO
+
+typedef uint32_t fd_set;
+#define FD_ZERO(set) (*(set) = 0) /**< Clear the entire set. */
+#define FD_SET(fd, set) (*(set) |= (1u << (fd))) /**< Set a bit in the set. */
+#define FD_CLR(fd, set) (*(set) &= ~(1u << (fd))) /**< Clear a bit in the set. */
+#define FD_ISSET(fd, set) (*(set) & (1u << (fd))) /**< Check if a bit in the set is set. */
+#define FD_SETSIZE sizeof(fd_set) /**< The max size of a set. */
+
+#endif
+/**@} */
+
+/**
+ * @brief Function for waiting for read, write, or exception events on a socket.
+ *
+ * @details Wait for a set of socket descriptors to be ready for reading, writing, or having
+ * exceptions. The set of socket descriptors is configured before calling this function.
+ * This function will block until any of the descriptors in the set has any of the required
+ * events. This function is mostly useful when using O_NONBLOCK or MSG_DONTWAIT options
+ * to enable async operation.
+ *
+ * @param[in] nfds The highest socket descriptor value contained in the sets.
+ * @param[inout] p_readset The set of descriptors for which to wait for read events. Set to NULL
+ * if not used.
+ * @param[inout] p_writeset The set of descriptors for which to wait for write events. Set to NULL
+ * if not used.
+ * @param[inout] p_exceptset The set of descriptors for which to wait for exception events. Set to
+ * NULL if not used.
+ * @param[in] p_timeout The timeout to use for select call. Set to NULL if waiting forever.
+ *
+ * @return The number of ready descriptors contained in the descriptor sets on success, or -1 on error.
+ */
+int select(int nfds,
+ fd_set * p_readset,
+ fd_set * p_writeset,
+ fd_set * p_exceptset,
+ const struct timeval * p_timeout);
+
+/**
+ * @brief Function for setting socket options for a given socket.
+ *
+ * @details The options are grouped by level, and the option value should be the expected for the
+ * given option, and the lifetime must be longer than that of the socket.
+ *
+ * @param[in] sock The socket for which to set the option.
+ * @param[in] level The level or group to which the option belongs.
+ * @param[in] optname The name of the socket option.
+ * @param[in] p_optval The value to be stored for this option.
+ * @param[in] optlen The size of p_optval.
+ *
+ * @return 0 on success, or -1 on error.
+ */
+int setsockopt(int sock,
+ socket_opt_lvl_t level,
+ int optname,
+ const void * p_optval,
+ socklen_t optlen);
+
+/**
+ * @brief Function for getting socket options for a given socket.
+ *
+ * @details The options are grouped by level, and the option value is the value described by the
+ * option name.
+ *
+ * @param[in] sock The socket for which to set the option.
+ * @param[in] level The level or group to which the option belongs.
+ * @param[in] optname The name of the socket option.
+ * @param[out] p_optval Pointer to the storage for the option value.
+ * @param[inout] p_optlen The size of p_optval. Can be modified to the actual size of p_optval.
+ *
+ * @return 0 on success, or -1 on error.
+ */
+int getsockopt(int sock,
+ socket_opt_lvl_t level,
+ int optname,
+ void * p_optval,
+ socklen_t * p_optlen);
+
+/**
+ * @brief Function for binding a socket to an address and port.
+ *
+ * @details The provided address must be supported by the socket protocol family.
+ *
+ * @param[in] sock The socket descriptor to bind.
+ * @param[in] p_myaddr The address to bind this socket to.
+ * @param[in] addrlen The size of p_myaddr.
+ *
+ * @return 0 on success, or -1 on error.
+ */
+int bind(int sock, const void * p_myaddr, socklen_t addrlen);
+
+/**
+ * @brief Function for marking a socket as listenable.
+ *
+ * @details Once a socket is marked as listenable, it cannot be unmarked. It is important to
+ * consider the backlog parameter, as it will affect how much memory your application will
+ * use in the worst case.
+ *
+ * @param[in] sock The socket descriptor on which to set the listening options.
+ * @param[in] backlog The max length of the queue of pending connections. A value of 0 means
+ * infinite.
+ *
+ * @return 0 on success, or -1 on error.
+ */
+int listen(int sock, int backlog);
+
+/**
+ * @brief Function for waiting for the next client to connect.
+ *
+ * @details This function will block if there are no clients attempting to connect.
+ *
+ * @param[in] sock The socket descriptor to use for waiting on client connections.
+ * @param[out] p_cliaddr Socket address that will be set to the client's address.
+ * @param[out] p_addrlen The size of the p_cliaddr passed. Might be modified by the function.
+ *
+ * @return A non-negative client descriptor on success, or -1 on error.
+ */
+int accept(int sock, void * p_cliaddr, socklen_t * p_addrlen);
+
+/**
+ * @brief Function for converting a human-readable IP address to a form usable by the socket API.
+ *
+ * @details This function will convert a string form of addresses and encode it into a byte array.
+ *
+ * @param[in] af Address family. Only AF_INET6 supported.
+ * @param[in] p_src Null-terminated string containing the address to convert.
+ * @param[out] p_dst Pointer to a struct in6_addr where the address will be stored.
+ *
+ * @return 1 on success, 0 if src does not contain a valid address, -1 if af is not a valid address
+ * family.
+ */
+int inet_pton(socket_family_t af, const char * p_src, void * p_dst);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif //SOCKET_API_H__
+
+/**@} */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/socket/api/sys/select.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/socket/api/sys/select.h
new file mode 100644
index 0000000..3fb05fb
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/socket/api/sys/select.h
@@ -0,0 +1,45 @@
+/**
+ * Copyright (c) 2016 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#ifndef SOCKET_SYS_SELECT_H__
+#define SOCKET_SYS_SELECT_H__
+
+#include "socket_api.h"
+
+#endif
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/socket/api/sys/socket.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/socket/api/sys/socket.h
new file mode 100644
index 0000000..c01fc3e
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/socket/api/sys/socket.h
@@ -0,0 +1,45 @@
+/**
+ * Copyright (c) 2015 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#ifndef SOCKET_SYS_SOCKET_H__
+#define SOCKET_SYS_SOCKET_H__
+
+#include "socket_api.h"
+
+#endif
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/socket/api/unistd.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/socket/api/unistd.h
new file mode 100644
index 0000000..ac77bdf
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/socket/api/unistd.h
@@ -0,0 +1,82 @@
+/**
+ * Copyright (c) 2015 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 unistd.h
+ *
+ * @defgroup iot_posix_unistd POSIX operating system API
+ * @ingroup iot_sdk_socket
+ * @{
+ * @brief POSIX standard functions.
+ */
+#ifndef SOCKET_UNISTD_H__
+#define SOCKET_UNISTD_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @brief POSIX sleep function.
+ *
+ * @note Uses busy looping nrf_delay.
+ *
+ * @param[in] seconds The number of seconds to sleep.
+ *
+ * @return The number of seconds slept.
+ */
+unsigned int sleep(unsigned int seconds);
+
+/**
+ * @brief POSIX usleep function.
+ *
+ * @note Uses busy looping nrf_delay.
+ *
+ * @param[in] useconds The number of microseconds to sleep.
+ *
+ * @return The number of microseconds slept.
+ */
+unsigned int usleep(unsigned int useconds);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // SOCKET_UNISTD_H__
+
+/**@} */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/socket/common/sleep.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/socket/common/sleep.c
new file mode 100644
index 0000000..94dd07a
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/socket/common/sleep.c
@@ -0,0 +1,53 @@
+/**
+ * Copyright (c) 2015 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#include "unistd.h"
+#include "nrf_delay.h"
+
+unsigned int sleep(unsigned int seconds)
+{
+ nrf_delay_ms(seconds * 1000);
+ return seconds;
+}
+
+unsigned int usleep(unsigned int useconds)
+{
+ nrf_delay_ms(useconds / 1000);
+ return useconds;
+}
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/socket/common/socket.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/socket/common/socket.c
new file mode 100644
index 0000000..fe7d6ca
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/socket/common/socket.c
@@ -0,0 +1,746 @@
+/**
+ * Copyright (c) 2015 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#include "nordic_common.h"
+#include "sdk_common.h"
+#include "sdk_config.h"
+#include "nrf_sdm.h"
+#include "app_scheduler.h"
+#include "app_timer.h"
+#include "iot_common.h"
+#include "app_error.h"
+#include "socket_api.h"
+#include "socket_common.h"
+#include "socket_trace.h"
+#include "sdk_os.h"
+#include "transport_if.h"
+#include "portdb.h"
+#include "errno.h"
+#include "mem_manager.h"
+#include "ipv6_parse.h"
+#include "netinet/in.h"
+#include "unistd.h"
+#include "sdk_os.h"
+#include "nrf_log_ctrl.h"
+#include "nrf_log_default_backends.h"
+
+#ifndef SOCKET_ENABLE_API_PARAM_CHECK
+#define SOCKET_ENABLE_API_PARAM_CHECK 0
+#endif
+
+#include "socket_config.h"
+
+#if SOCKET_CONFIG_LOG_ENABLED == 1
+ NRF_LOG_MODULE_REGISTER();
+#endif
+
+/**
+ * @defgroup api_param_check API Parameters check macros.
+ *
+ * @details Macros that verify parameters passed to the module in the APIs. These macros
+ * could be mapped to nothing in final versions of code to save execution and size.
+ * SOCKET_ENABLE_API_PARAM_CHECK should be set to 0 to disable these checks.
+ *
+ * @{
+ */
+#if SOCKET_ENABLE_API_PARAM_CHECK == 1
+
+/**@brief Macro to check is module is initialized before requesting one of the module procedures. */
+#define VERIFY_MODULE_IS_INITIALIZED() \
+ do { \
+ if (m_initialization_state == false) \
+ { \
+ return (SDK_ERR_MODULE_NOT_INITIALIZED | IOT_SOCKET_ERR_BASE);\
+ } \
+ } while (0)
+
+
+/**
+ * @brief Verify NULL parameters are not passed to API by application.
+ */
+#define NULL_PARAM_CHECK(PARAM) \
+ do { \
+ if ((PARAM) == NULL) \
+ { \
+ set_errno(EFAULT); \
+ return -1; \
+ } \
+ } while (0)
+
+/**
+ * @brief Verify socket id passed on the API by application is valid.
+ */
+#define VERIFY_SOCKET_ID(ID) \
+ do { \
+ if (((ID) < 0) || ((ID) >= NUM_SOCKETS)) \
+ { \
+ set_errno(EBADF); \
+ return -1; \
+ } \
+ } while (0)
+
+
+#else
+
+#define VERIFY_MODULE_IS_INITIALIZED()
+#define NULL_PARAM_CHECK(PARAM)
+#define VERIFY_SOCKET_ID(ID)
+#endif
+
+/** @} */
+#define SOCKET_MUTEX_INIT() SDK_MUTEX_INIT(m_socket_mtx);
+#define SOCKET_MUTEX_LOCK() SDK_MUTEX_LOCK(m_socket_mtx)
+#define SOCKET_MUTEX_UNLOCK() SDK_MUTEX_UNLOCK(m_socket_mtx)
+// note: one extra for configuration socket
+#define NUM_SOCKETS SOCKET_MAX_SOCKET_COUNT + 1
+
+SDK_MUTEX_DEFINE(m_socket_mtx) /**< Mutex for protecting m_socket_table (not individual entries). */
+
+#define SCHED_QUEUE_SIZE 16 /**< Maximum number of events in the scheduler queue. */
+#define SCHED_MAX_EVENT_DATA_SIZE 192 /**< Maximum size of scheduler events. */
+
+static bool m_initialization_state = false; /**< Variable to maintain module initialization state. */
+static volatile bool m_interface_up = false; /**< Interface state. */
+static socket_t m_socket_table[NUM_SOCKETS]; /**< Socket table. */
+
+const struct in6_addr in6addr_any = { {0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u, /**< IPv6 anycast address. */
+ 0u, 0u, 0u, 0u, 0u, 0u, 0u, 0u} };
+
+#if defined (NRF_LOG_ENABLED) && (NRF_LOG_ENABLED == 1)
+
+void log_init(void)
+{
+ ret_code_t err_code = NRF_LOG_INIT(NULL);
+ APP_ERROR_CHECK(err_code);
+
+ NRF_LOG_DEFAULT_BACKENDS_INIT();
+}
+
+#else // defined (NRF_LOG_ENABLED) && (NRF_LOG_ENABLED == 1)
+
+void log_init(void)
+{
+ ;
+}
+
+#endif // defined (NRF_LOG_ENABLED) && (NRF_LOG_ENABLED == 1)
+
+uint32_t socket_init(void)
+{
+ memset(m_socket_table, 0, sizeof(m_socket_table));
+
+ SOCKET_MUTEX_INIT();
+
+ log_init();
+
+ uint32_t err_code = nrf_mem_init();
+ APP_ERROR_CHECK(err_code);
+
+ APP_SCHED_INIT(SCHED_MAX_EVENT_DATA_SIZE, SCHED_QUEUE_SIZE);
+
+ err_code = app_timer_init();
+ APP_ERROR_CHECK(err_code);
+
+ err_code = config_socket_init();
+ APP_ERROR_CHECK(err_code);
+
+#if SOCKET_TRANSPORT_ENABLE == 1
+ err_code = portdb_init(SOCKET_MAX_SOCKET_COUNT);
+ APP_ERROR_CHECK(err_code);
+
+ transport_handler_init();
+#endif
+ config_socket_start();
+ m_initialization_state = true;
+
+ SOCKET_TRACE("Socket init complete");
+
+ return NRF_SUCCESS;
+}
+
+/**
+ * Finds a free entry in the socket table, marks it as used and returns it. Returns -1 if no entry
+ * was found.
+ */
+static int socket_allocate(socket_t ** pp_socket)
+{
+ int ret_sock = -1;
+ SOCKET_MUTEX_LOCK();
+ for (int sock = 0; sock < NUM_SOCKETS; sock++)
+ {
+ SOCKET_TRACE("Looking at socket %d with state %d", (int)sock, m_socket_table[sock].so_state);
+ if (m_socket_table[sock].so_state == STATE_CLOSED)
+ {
+ m_socket_table[sock].so_state = STATE_OPEN;
+ ret_sock = sock;
+ *pp_socket = &m_socket_table[sock];
+ break;
+ }
+ }
+ if (ret_sock < 0)
+ {
+ set_errno(EMFILE);
+ }
+ SOCKET_MUTEX_UNLOCK();
+ return ret_sock;
+}
+
+static socket_t * socket_find(int sock)
+{
+ SOCKET_MUTEX_LOCK();
+ socket_t * p_socket = &m_socket_table[sock];
+ SOCKET_MUTEX_UNLOCK();
+ return p_socket;
+}
+
+static void socket_free(int sock)
+{
+ SOCKET_TRACE("Freeing socket %d", (int)sock);
+ SOCKET_MUTEX_LOCK();
+ memset(&m_socket_table[sock], 0, sizeof(m_socket_table[sock]));
+ m_socket_table[sock].so_state = STATE_CLOSED;
+ SOCKET_MUTEX_UNLOCK();
+}
+
+#if SOCKET_TRANSPORT_ENABLE == 1
+void transport_interface_up(void)
+{
+ m_interface_up = true;
+}
+
+void transport_interface_down(void)
+{
+ m_interface_up = false;
+ for (int sock = 0; sock < NUM_SOCKETS; sock++)
+ {
+ (void) close(sock);
+ }
+}
+#endif
+
+int fcntl(int fd, int cmd, int flags)
+{
+ VERIFY_MODULE_IS_INITIALIZED();
+ VERIFY_SOCKET_ID(fd);
+
+ if (!((cmd == F_SETFL) || (cmd == F_GETFL)))
+ {
+ set_errno(EINVAL);
+ return -1;
+ }
+ socket_t * p_socket = socket_find(fd);
+
+ if (cmd == F_SETFL)
+ {
+ p_socket->so_flags = flags;
+ }
+ else if (cmd == F_GETFL)
+ {
+ return p_socket->so_flags;
+ }
+
+ return 0;
+}
+
+static void socket_set_errno(uint32_t err_code)
+{
+ switch (err_code) {
+ case UDP_INTERFACE_NOT_READY: // fallthrough
+ case SOCKET_INTERFACE_NOT_READY:
+ set_errno(ENETDOWN);
+ break;
+ case SOCKET_WOULD_BLOCK:
+ set_errno(EAGAIN);
+ break;
+ case SOCKET_NO_ROUTE:
+ set_errno(ENETUNREACH);
+ break;
+ case NRF_ERROR_NO_MEM: // fallthrough
+ case SOCKET_NO_MEM:
+ set_errno(ENOMEM);
+ break;
+ case SOCKET_TIMEOUT:
+ set_errno(ETIMEDOUT);
+ break;
+ case SOCKET_NO_AVAILABLE_PORTS:
+ set_errno(EMFILE);
+ break;
+ case SOCKET_PORT_IN_USE: // fallthrough
+ case SOCKET_ADDRESS_IN_USE:
+ set_errno(EADDRINUSE);
+ break;
+ case SOCKET_INVALID_PARAM:
+ set_errno(EINVAL);
+ break;
+ case SOCKET_UNSUPPORTED_PROTOCOL:
+ set_errno(EPROTONOSUPPORT);
+ break;
+ case SOCKET_NOT_CONNECTED:
+ set_errno(ENOTCONN);
+ break;
+ }
+}
+
+
+int socket(socket_family_t family, socket_type_t type, socket_protocol_t protocol)
+{
+ if (m_initialization_state == false)
+ {
+ (void) socket_init();
+ }
+ VERIFY_MODULE_IS_INITIALIZED();
+
+ int ret_sock = -1;
+ socket_t * p_socket = NULL;
+ int sock = socket_allocate(&p_socket);
+ SOCKET_TRACE("Got value %d from allocate", (int)sock);
+ if (sock >= 0)
+ {
+ p_socket->so_params.so_family = family;
+ p_socket->so_params.so_protocol = protocol;
+ p_socket->so_params.so_type = type;
+ p_socket->so_transport = NULL;
+
+ if (family == AF_INET6)
+ {
+#if SOCKET_TRANSPORT_ENABLE == 1
+ p_socket->so_transport = &transport_impl;
+#else
+ set_errno(EAFNOSUPPORT);
+#endif
+ }
+ else if (family == AF_NRF_CFG || family == AF_NRF_CFG_INTERNAL)
+ {
+ p_socket->so_transport = &config_socket_transport;
+ }
+ else
+ {
+ set_errno(EAFNOSUPPORT);
+ }
+
+ if (p_socket->so_transport != NULL)
+ {
+ uint32_t err_code = p_socket->so_transport->open(p_socket);
+ socket_set_errno(err_code);
+ ret_sock = (err_code == NRF_SUCCESS) ? sock : ret_sock;
+ }
+
+ if (ret_sock < 0)
+ {
+ socket_free(sock);
+ }
+ }
+ SOCKET_TRACE("Returning socket value %d", (int)ret_sock);
+ return ret_sock;
+}
+
+static uint32_t wait_interface_up(void)
+{
+ SOCKET_TRACE("Waiting for interface to come up");
+ uint32_t err_code = NRF_SUCCESS;
+ while (err_code == NRF_SUCCESS && m_interface_up == false)
+ {
+ err_code = socket_wait();
+ }
+ if (m_interface_up == true)
+ {
+ SOCKET_TRACE("Interface is up!");
+ }
+ return err_code;
+}
+
+static uint32_t socket_interface_up(bool is_blocking)
+{
+ uint32_t err_code = NRF_SUCCESS;
+ if (m_interface_up == false)
+ {
+ if (is_blocking)
+ {
+ (void) wait_interface_up();
+ }
+ }
+ if (m_interface_up == false)
+ {
+ err_code = SOCKET_INTERFACE_NOT_READY;
+ }
+ return err_code;
+}
+
+int connect(int sock, const void * p_addr, socklen_t addrlen)
+{
+ VERIFY_MODULE_IS_INITIALIZED();
+ VERIFY_SOCKET_ID(sock);
+ NULL_PARAM_CHECK(p_addr);
+
+ socket_t * p_socket = socket_find(sock);
+ bool is_blocking = ((p_socket->so_flags & O_NONBLOCK) == 0);
+ int ret = -1;
+
+ uint32_t err_code = socket_interface_up(is_blocking);
+ if (err_code != NRF_SUCCESS)
+ {
+ socket_set_errno(err_code);
+ }
+ else if (p_socket->so_state == STATE_OPEN)
+ {
+ err_code = p_socket->so_transport->connect(p_socket, p_addr, addrlen);
+ if (err_code == NRF_SUCCESS)
+ {
+ p_socket->so_state = STATE_CONNECTED;
+ ret = 0;
+ }
+ socket_set_errno(err_code);
+ }
+ else if (p_socket->so_state == STATE_CONNECTED)
+ {
+ set_errno(EISCONN);
+ }
+ else if (p_socket->so_state == STATE_CLOSED)
+ {
+ set_errno(EBADF);
+ }
+ return ret;
+}
+
+
+ssize_t sendto(int sock,
+ const void * p_buf,
+ size_t buflen,
+ int flags,
+ const void * p_servaddr,
+ socklen_t addrlen)
+{
+ VERIFY_MODULE_IS_INITIALIZED();
+ VERIFY_SOCKET_ID(sock);
+ NULL_PARAM_CHECK(p_buf);
+
+ socket_t * p_socket = socket_find(sock);
+
+ if ((p_socket->so_flags & O_NONBLOCK) != 0 &&
+ (flags & MSG_WAITALL) == 0)
+ {
+ flags |= MSG_DONTWAIT;
+ }
+
+ uint32_t err_code = socket_interface_up(((p_socket->so_flags & O_NONBLOCK) == 0) || ((flags & MSG_DONTWAIT) == 0));
+
+ ssize_t ret = -1;
+ if (err_code == NRF_SUCCESS)
+ {
+ err_code = p_socket->so_transport->send(p_socket, p_buf, buflen, flags, p_servaddr, addrlen);
+ if (err_code == NRF_SUCCESS)
+ {
+ ret = (ssize_t) buflen;
+ }
+ }
+ socket_set_errno(err_code);
+ return ret;
+}
+
+ssize_t send(int sock, const void * p_buf, size_t buflen, int flags)
+{
+ return sendto(sock, p_buf, buflen, flags, NULL, 0);
+}
+
+ssize_t write(int sock, const void * p_buf, size_t buflen)
+{
+ return send(sock, p_buf, buflen, 0);
+}
+
+ssize_t recvfrom(int sock,
+ void * p_buf,
+ size_t buf_size,
+ int flags,
+ void * p_cliaddr,
+ socklen_t * p_addrlen)
+{
+ VERIFY_MODULE_IS_INITIALIZED();
+ VERIFY_SOCKET_ID(sock);
+ NULL_PARAM_CHECK(p_buf);
+
+ socket_t * p_socket = socket_find(sock);
+ ssize_t ret = -1;
+ uint32_t recv_size = buf_size;
+
+ uint32_t err_code = p_socket->so_transport->recv(p_socket,
+ p_buf,
+ &recv_size,
+ flags,
+ p_cliaddr,
+ p_addrlen);
+ if (err_code == NRF_SUCCESS)
+ {
+ ret = (ssize_t) recv_size;
+ }
+ socket_set_errno(err_code);
+ return ret;
+}
+
+ssize_t recv(int sock, void * p_buf, size_t buf_size, int flags)
+{
+ return recvfrom(sock, p_buf, buf_size, flags, NULL, NULL);
+}
+
+ssize_t read(int sock, void * p_buf, size_t buf_size)
+{
+ return recv(sock, p_buf, buf_size, 0);
+}
+
+int setsockopt(int sock,
+ socket_opt_lvl_t level,
+ int optname,
+ const void * p_optval,
+ socklen_t optlen)
+{
+ VERIFY_MODULE_IS_INITIALIZED();
+ VERIFY_SOCKET_ID(sock);
+
+ socket_t * p_socket = socket_find(sock);
+
+ uint32_t err_code = p_socket->so_transport->setsockopt(p_socket,
+ level,
+ optname,
+ p_optval,
+ optlen);
+ socket_set_errno(err_code);
+ return (err_code == NRF_SUCCESS ? 0 : -1);
+}
+
+int getsockopt(int sock, socket_opt_lvl_t level, int optname, void * p_optval, socklen_t * p_optlen)
+{
+ VERIFY_MODULE_IS_INITIALIZED();
+ VERIFY_SOCKET_ID(sock);
+
+ socket_t * p_socket = socket_find(sock);
+
+ uint32_t err_code = p_socket->so_transport->getsockopt(p_socket,
+ level,
+ optname,
+ p_optval,
+ p_optlen);
+ socket_set_errno(err_code);
+ return (err_code == NRF_SUCCESS ? 0 : -1);
+}
+
+int bind(int sock, const void * p_addr, socklen_t addrlen)
+{
+ VERIFY_MODULE_IS_INITIALIZED();
+ VERIFY_SOCKET_ID(sock);
+ NULL_PARAM_CHECK(p_addr);
+
+ socket_t * p_socket = socket_find(sock);
+ bool is_blocking = ((p_socket->so_flags & O_NONBLOCK) == 0);
+ int ret = -1;
+
+ uint32_t err_code = socket_interface_up(is_blocking);
+ if (err_code == NRF_SUCCESS)
+ {
+ err_code = p_socket->so_transport->bind(p_socket, p_addr, addrlen);
+ }
+ if (err_code == NRF_SUCCESS)
+ {
+ ret = 0;
+ }
+ socket_set_errno(err_code);
+ return ret;
+}
+
+int listen(int sock, int backlog)
+{
+ VERIFY_MODULE_IS_INITIALIZED();
+ VERIFY_SOCKET_ID(sock);
+
+ socket_t * p_socket = socket_find(sock);
+
+ uint32_t err_code = p_socket->so_transport->listen(p_socket, backlog);
+ return (err_code == NRF_SUCCESS ? 0 : -1);
+}
+
+int accept(int sock, void * p_cliaddr, socklen_t * p_addrlen)
+{
+ VERIFY_MODULE_IS_INITIALIZED();
+ VERIFY_SOCKET_ID(sock);
+ NULL_PARAM_CHECK(p_cliaddr);
+ NULL_PARAM_CHECK(p_addrlen);
+
+ socket_t * p_socket = socket_find(sock);
+ int ret = -1;
+
+ if (p_socket->so_params.so_type != SOCK_STREAM)
+ {
+ set_errno(EOPNOTSUPP);
+ }
+ else
+ {
+ uint32_t err_code = NRF_SUCCESS;
+ socket_t * p_client = NULL;
+ int sock_cli = socket_allocate(&p_client);
+ if (sock_cli >= 0)
+ {
+ p_client->so_params = p_socket->so_params;
+ p_client->so_state = STATE_CONNECTED;
+ p_client->so_transport = p_socket->so_transport;
+ err_code = p_socket->so_transport->accept(p_socket, p_client, p_cliaddr, p_addrlen);
+ }
+
+ if (err_code == NRF_SUCCESS)
+ {
+ ret = sock_cli;
+ }
+ else
+ {
+ socket_set_errno(err_code);
+ socket_free(sock_cli);
+ }
+ }
+ return ret;
+}
+
+int close(int sock)
+{
+ VERIFY_MODULE_IS_INITIALIZED();
+ VERIFY_SOCKET_ID(sock);
+
+ socket_t * p_socket = socket_find(sock);
+ int ret = 0;
+
+ if (p_socket->so_state != STATE_CLOSED)
+ {
+ uint32_t err_code = p_socket->so_transport->close(p_socket);
+ ret = (err_code == NRF_SUCCESS) ? 0 : -1;
+ SOCKET_TRACE("Close socket %d: ret: %d", (int)sock, ret);
+ socket_free(sock);
+ }
+ return ret;
+}
+
+int fd_set_cmp(fd_set * set_a, fd_set * set_b)
+{
+ int ret = 0;
+ if (set_a != NULL && set_b != NULL)
+ {
+ for (uint32_t i = 0; i < FD_SETSIZE; i++)
+ {
+ if (FD_ISSET(i, set_a) != FD_ISSET(i, set_b))
+ {
+ ret = 1;
+ break;
+ }
+ }
+ }
+ return ret;
+}
+
+int select(int nfds,
+ fd_set * p_readset,
+ fd_set * p_writeset,
+ fd_set * p_exceptset,
+ const struct timeval * p_timeout)
+{
+ VERIFY_SOCKET_ID(nfds - 1);
+
+ // Approximately 10 ms sleep between each iteration
+ uint32_t timestep = 10000;
+ uint32_t endtime = 0;
+ if (p_timeout != NULL)
+ {
+ endtime = (p_timeout->tv_sec * 1000000) + p_timeout->tv_usec;
+ }
+ fd_set readset;
+ FD_ZERO(&readset);
+ fd_set writeset;
+ FD_ZERO(&writeset);
+ fd_set exceptset;
+ FD_ZERO(&exceptset);
+
+#define SELECT_CHECK_SET(in_set, out_set, evt_var) \
+ if ((in_set) != NULL) \
+ { \
+ if (FD_ISSET(sock, (in_set)) && (evt_var) > 0) \
+ { \
+ FD_SET(sock, (out_set)); \
+ num_ready++; \
+ } \
+ else \
+ { \
+ FD_CLR(sock, (out_set)); \
+ } \
+ }
+
+ int num_ready = 0;
+ uint32_t err_code = NRF_SUCCESS;
+ while (err_code == NRF_SUCCESS)
+ {
+ for (int sock = 0; sock < nfds; sock++)
+ {
+ socket_t * p_socket = socket_find(sock);
+ SELECT_CHECK_SET(p_readset, &readset, p_socket->so_read_evt);
+ SELECT_CHECK_SET(p_writeset, &writeset, p_socket->so_write_evt);
+ SELECT_CHECK_SET(p_exceptset, &exceptset, p_socket->so_except_evt);
+ }
+ // TODO: Check out how app events queue up while we checked the socket
+ if (fd_set_cmp(p_readset, &readset) == 0 &&
+ fd_set_cmp(p_writeset, &writeset) == 0 &&
+ fd_set_cmp(p_exceptset, &exceptset) == 0)
+
+ {
+ break;
+ }
+ else
+ {
+ if (p_timeout == NULL)
+ {
+ err_code = socket_wait();
+ }
+ else if (endtime - timestep < endtime)
+ {
+ (void) usleep(timestep);
+ endtime -= timestep;
+ }
+ else
+ {
+ break;
+ }
+ }
+
+ }
+
+ return num_ready;
+}
+
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/socket/common/socket_common.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/socket/common/socket_common.h
new file mode 100644
index 0000000..d9a0f8a
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/socket/common/socket_common.h
@@ -0,0 +1,115 @@
+/**
+ * Copyright (c) 2015 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 socket_common.h
+ *
+ * @defgroup socket_common BSD Socket internal functions and structures
+ * @ingroup iot_sdk_socket
+ * @{
+ * @brief Nordic socket interface internal functions and structures.
+ */
+#ifndef SOCKET_COMMON_H__
+#define SOCKET_COMMON_H__
+
+#include <stdint.h>
+#include "socket_api.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+struct socket_transport;
+
+#define AF_NRF_CFG_INTERNAL 41 /**< Socket family type, internal NRF configuration socket. */
+
+/**
+ * @brief Function for initializing the socket API module.
+ *
+ * @return NRF_SUCCESS on success, otherwise error code is returned.
+ */
+uint32_t socket_init(void);
+
+/**
+ * @brief Waiting function for sockets.
+ *
+ * @details Must be implemented by specific modules such as BLEs.
+ *
+ * @return NRF_SUCCESS on success, otherwise error code is returned.
+ */
+uint32_t socket_wait(void);
+
+/**
+ * @brief Create parameters for a socket.
+ */
+typedef struct {
+ socket_family_t so_family; /**< Socket family. */
+ socket_protocol_t so_protocol; /**< Socket protocol. */
+ socket_type_t so_type; /**< Socket type. */
+} socket_params_t;
+
+/**
+ * @brief Different states a socket can be in.
+ */
+typedef enum {
+ STATE_CLOSED = 0, /**< Socket is closed. */
+ STATE_OPEN, /**< Socket is opened. */
+ STATE_CONNECTED, /**< Socket is connected. */
+} socket_state_t;
+
+/**
+ * @brief The state associated with a socket handle.
+ */
+typedef struct {
+ socket_params_t so_params; /**< Generic socket parameters. */
+ void * so_ctx; /**< Transport specific context. */
+ int so_flags; /**< Socket flags. */
+ uint16_t so_read_evt; /**< Notifying of read events. */
+ uint16_t so_write_evt; /**< Notifying of write events. */
+ uint16_t so_except_evt; /**< Notifying of exceptional events. */
+ struct socket_transport * so_transport; /**< Transport attached to this socket. */
+ volatile socket_state_t so_state; /**< Socket state. */
+} socket_t;
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // SOCKET_COMMON_H__
+
+/**@} */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/socket/common/socket_config.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/socket/common/socket_config.h
new file mode 100644
index 0000000..cce571e
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/socket/common/socket_config.h
@@ -0,0 +1,81 @@
+/**
+ * Copyright (c) 2015 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 socket_config.h
+ *
+ * @defgroup iot_socket_config Configuration socket API
+ * @ingroup iot_sdk_socket
+ * @{
+ * @brief Configuration socket API.
+ *
+ * This API is used internally by the socket handling to support the configuration
+ * socket type. The configuration socket is implemented using a special transport hook, which is
+ * implemented differently depending on the platform.
+ */
+#ifndef SOCKET_CONFIG_H__
+#define SOCKET_CONFIG_H__
+
+#include "socket_common.h"
+#include "transport_if.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @brief Function for setting the default configuration.
+ *
+ * @return NRF_SUCCESS on success, otherwise an error code.
+ */
+uint32_t config_socket_init(void);
+
+/**
+ * @brief Function for starting the configuration layer.
+ */
+void config_socket_start(void);
+
+extern socket_transport_t config_socket_transport;
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // SOCKET_CONFIG_H__
+
+/**@} */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/socket/common/socket_trace.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/socket/common/socket_trace.h
new file mode 100644
index 0000000..87fafdf
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/socket/common/socket_trace.h
@@ -0,0 +1,102 @@
+/**
+ * Copyright (c) 2015 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 socket_trace.h
+ *
+ * @defgroup iot_socket_debug_log Module's log macros
+ * @ingroup iot_sdk_socket
+ * @{
+ * @brief Socket trace macros.
+ *
+ * @details Macros for creating module logs which can be useful in understanding the handling
+ * of events or actions on API requests. These are intended for debugging purposes and
+ * can be disabled by defining the SOCKET_CONFIG_LOG_ENABLED.
+ * @note If NRF_LOG_ENABLED is disabled, SOCKET_CONFIG_LOG_ENABLED has no effect.
+ */
+#ifndef SOCKET_TRACE_H__
+#define SOCKET_TRACE_H__
+
+#include "sdk_config.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#if SOCKET_CONFIG_LOG_ENABLED == 1
+#if defined (NRF_LOG_ENABLED) && (NRF_LOG_ENABLED == 1)
+
+#define NRF_LOG_MODULE_NAME socket
+
+#define NRF_LOG_LEVEL SOCKET_CONFIG_LOG_LEVEL
+#define NRF_LOG_INFO_COLOR SOCKET_CONFIG_INFO_COLOR
+#define NRF_LOG_DEBUG_COLOR SOCKET_CONFIG_DEBUG_COLOR
+
+#include "nrf_log.h"
+
+#define SOCKET_TRACE NRF_LOG_DEBUG /**< Used for getting trace of execution in the module. */
+#define SOCKET_ERR NRF_LOG_ERROR /**< Used for logging errors in the module. */
+#define SOCKET_DUMP NRF_LOG_HEXDUMP_DEBUG /**< Used for dumping octet information to get details of bond information etc. */
+
+#else
+
+#define SOCKET_TRACE(...) \
+ do { \
+ (void) fprintf( stderr, "socket: " ); \
+ (void) fprintf( stderr, __VA_ARGS__ ); \
+ (void) fprintf( stderr, "\r\n" ); \
+ } while (0)
+
+#endif
+
+#else // SOCKET_CONFIG_LOG_ENABLED
+
+#define SOCKET_TRACE(...) /**< Disables traces. */
+#define SOCKET_ERR(...) /**< Disables error logs. */
+#define SOCKET_DUMP(...) /**< Disables dumping of octet streams. */
+
+#endif // SOCKET_CONFIG_LOG_ENABLED
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // SOCKET_TRACE_H__
+
+/**@} */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/socket/common/transport_if.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/socket/common/transport_if.h
new file mode 100644
index 0000000..75a86c1
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/socket/common/transport_if.h
@@ -0,0 +1,161 @@
+/**
+ * Copyright (c) 2015 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 transport_if.h
+ *
+ * @defgroup iot_socket_transport_if Transport implementation interface
+ * @ingroup iot_sdk_socket
+ * @{
+ * @brief Transport implementation interface.
+ *
+ * The transport interface defines the hook to be used for socket transport. The implementation of
+ * this interface would be different across platforms and event IP stacks (i.e. Nordic IPv6 vs LwIP).
+ */
+#ifndef TRANSPORT_IF_H__
+#define TRANSPORT_IF_H__
+
+#include "iot_defines.h"
+#include "socket_api.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @brief Function for opening a socket.
+ */
+typedef uint32_t (*tr_open_t) (socket_t * p_socket);
+
+/**
+ * @brief Function for connecting a socket to an address.
+ */
+typedef uint32_t (*tr_connect_t)(socket_t * p_socket, const void * p_addr, socklen_t addrlen);
+
+/**
+ * @brief Function for sending data on a socket.
+ */
+typedef uint32_t (*tr_send_t)(socket_t * p_socket,
+ const void * p_buf,
+ uint32_t len,
+ int flags,
+ const void * p_destaddr,
+ socklen_t destaddr_len);
+
+/**
+ * @brief Function for receiving data from a socket.
+ */
+typedef uint32_t (*tr_recv_t)(socket_t * p_socket,
+ void * p_buf,
+ uint32_t * sz,
+ int flags,
+ void * p_srcaddr,
+ socklen_t * p_srcaddr_len);
+
+/**
+ * @brief Function for binding a socket to an address and port.
+ */
+typedef uint32_t (*tr_bind_t)(socket_t * p_socket, const void * p_addr, socklen_t addrlen);
+
+/**
+ * @brief Function for listening on a socket.
+ */
+typedef uint32_t (*tr_listen_t)(socket_t * p_socket, int backlog);
+
+/**
+ * @brief Function for accepting a connection on a socket.
+ */
+typedef uint32_t (*tr_accept_t)(socket_t * p_socket,
+ socket_t * p_client,
+ void * p_client_addr,
+ socklen_t * p_client_addr_len);
+
+/**
+ * @brief Function for closing a socket.
+ */
+typedef uint32_t (*tr_close_t)(socket_t * p_socket);
+
+/**
+ * @brief Function for setting options on a socket.
+ */
+typedef uint32_t (*tr_setsockopt_t)(socket_t * p_socket,
+ int level,
+ int optname,
+ const void * p_optval,
+ socklen_t optlen);
+
+/**
+ * @brief Function for getting options from a socket.
+ */
+typedef uint32_t (*tr_getsockopt_t)(socket_t * p_socket,
+ int level,
+ int optname,
+ void * p_optval,
+ socklen_t * p_optlen);
+
+/**
+ * @brief The transport interface.
+ */
+typedef struct socket_transport
+{
+ tr_open_t open; /**< Open a socket. */
+ tr_connect_t connect; /**< Connect a socket to an address. */
+ tr_send_t send; /**< Send data on a socket. */
+ tr_recv_t recv; /**< Receive data from a socket. */
+ tr_bind_t bind; /**< Bind a socket to an address and port. */
+ tr_listen_t listen; /**< Listen on a socket. */
+ tr_accept_t accept; /**< Accept connection on a socket. */
+ tr_close_t close; /**< Close a socket. */
+ tr_setsockopt_t setsockopt; /**< Set options on a socket. */
+ tr_getsockopt_t getsockopt; /**< Get options from a socket. */
+} socket_transport_t;
+
+#if SOCKET_TRANSPORT_ENABLE == 1
+extern socket_transport_t transport_impl;
+void transport_handler_init(void);
+void transport_interface_up(void);
+void transport_interface_down(void);
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // TRANSPORT_IF_H__
+
+/**@} */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/socket/config/medium/config_medium.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/socket/config/medium/config_medium.c
new file mode 100644
index 0000000..6b883dd
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/socket/config/medium/config_medium.c
@@ -0,0 +1,227 @@
+/**
+ * Copyright (c) 2016 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#include "sdk_config.h"
+#include "socket_api.h"
+#include "config_medium.h"
+#include "ipv6_medium.h"
+#include "iot_errors.h"
+#include "app_error.h"
+#include "socket_config.h"
+
+static ipv6_medium_instance_t m_ipv6_medium; /**< IPv6 medium instance. */
+eui64_t eui64_local_iid; /**< Local EUI64 value that is used as the IID for*/
+
+eui64_t * config_medium_local_iid(void)
+{
+ return &eui64_local_iid;
+}
+
+void config_medium_start(void)
+{
+ uint32_t err_code = ipv6_medium_connectable_mode_enter(m_ipv6_medium.ipv6_medium_instance_id);
+ APP_ERROR_CHECK(err_code);
+}
+
+static void on_ipv6_medium_evt(ipv6_medium_evt_t * p_ipv6_medium_evt)
+{
+ switch (p_ipv6_medium_evt->ipv6_medium_evt_id)
+ {
+ case IPV6_MEDIUM_EVT_CONN_UP:
+ {
+ // TODO: Signal
+ break;
+ }
+ case IPV6_MEDIUM_EVT_CONN_DOWN:
+ {
+ config_medium_start();
+ break;
+ }
+ default:
+ {
+ break;
+ }
+ }
+}
+
+
+static void on_ipv6_medium_error(ipv6_medium_error_t * p_ipv6_medium_error)
+{
+ // Do something.
+}
+
+static uint32_t config_medium_init(ipv6_medium_init_params_t * p_medium_params,
+ ipv6_medium_type_t medium_type)
+{
+ uint32_t err_code = ipv6_medium_init(p_medium_params, medium_type, &m_ipv6_medium);
+ if (err_code != NRF_SUCCESS)
+ {
+ return err_code;
+ }
+
+ eui48_t ipv6_medium_eui48;
+ err_code = ipv6_medium_eui48_get(m_ipv6_medium.ipv6_medium_instance_id, &ipv6_medium_eui48);
+ if (err_code != NRF_SUCCESS)
+ {
+ return err_code;
+ }
+
+ ipv6_medium_eui48.identifier[EUI_48_SIZE - 1] = 0x00;
+
+ err_code = ipv6_medium_eui48_set(m_ipv6_medium.ipv6_medium_instance_id, &ipv6_medium_eui48);
+ if (err_code != NRF_SUCCESS)
+ {
+ return err_code;
+ }
+
+ err_code = ipv6_medium_eui64_get(m_ipv6_medium.ipv6_medium_instance_id, &eui64_local_iid);
+ return err_code;
+}
+
+uint32_t config_medium_init_default(void)
+{
+ static ipv6_medium_init_params_t ipv6_medium_init_params;
+ memset(&ipv6_medium_init_params, 0x00, sizeof(ipv6_medium_init_params));
+ ipv6_medium_init_params.ipv6_medium_evt_handler = on_ipv6_medium_evt;
+ ipv6_medium_init_params.ipv6_medium_error_handler = on_ipv6_medium_error;
+ return config_medium_init(&ipv6_medium_init_params, IPV6_MEDIUM_ID_BLE);
+}
+
+uint32_t config_medium_setopt(int optname, const void * p_optarg, socklen_t optlen)
+{
+ uint32_t err_code = SOCKET_INVALID_PARAM;
+ if (optname == MEDIUM_INIT_PARAMS)
+ {
+ if (optlen == sizeof(config_medium_params_t))
+ {
+ const config_medium_params_t * p_cfg = (const config_medium_params_t *)p_optarg;
+ ipv6_medium_init_params_t ipv6_medium_init_params;
+ memset(&ipv6_medium_init_params, 0x00, sizeof(ipv6_medium_init_params));
+ ipv6_medium_init_params.ipv6_medium_evt_handler = p_cfg->evt_handler;
+ ipv6_medium_init_params.ipv6_medium_error_handler = p_cfg->error_handler;
+ err_code = config_medium_init(&ipv6_medium_init_params, p_cfg->medium_type);
+ }
+ }
+ return err_code;
+}
+
+uint32_t config_medium_getopt(int optname, void * p_optarg, socklen_t * p_optlen)
+{
+ (void) optname;
+ (void) p_optarg;
+ (void) p_optlen;
+ return SOCKET_INVALID_PARAM;
+}
+
+uint32_t config_socket_init(void)
+{
+ uint32_t err_code = NRF_SUCCESS;
+#if SOCKET_AUTOINIT_ENABLE == 1
+ err_code = config_medium_init_default();
+#endif
+ return err_code;
+}
+
+void config_socket_start(void)
+{
+#if SOCKET_AUTOINIT_ENABLE == 1
+ config_medium_start();
+#endif
+}
+
+static uint32_t config_socket_open(socket_t * p_socket)
+{
+ (void) p_socket;
+ return NRF_ERROR_NULL;
+}
+
+static uint32_t config_socket_close(socket_t * p_socket)
+{
+ (void) p_socket;
+ return NRF_ERROR_NULL;
+}
+
+uint32_t config_socket_setopt(socket_t * p_socket,
+ int level,
+ int optname,
+ const void * p_optarg,
+ socklen_t optlen)
+{
+ uint32_t err_code = NRF_SUCCESS;
+ switch (level)
+ {
+ case SOL_NRF_MEDIUM:
+ err_code = config_medium_setopt(optname, p_optarg, optlen);
+ break;
+ default:
+ err_code = SOCKET_INVALID_PARAM;
+ break;
+ }
+ return err_code;
+}
+
+uint32_t config_socket_getopt(socket_t * p_socket,
+ int level,
+ int optname,
+ void * p_optarg,
+ socklen_t * p_optlen)
+{
+ uint32_t err_code = NRF_SUCCESS;
+ switch (level)
+ {
+ case SOL_NRF_MEDIUM:
+ err_code = config_medium_getopt(optname, p_optarg, p_optlen);
+ break;
+ default:
+ err_code = SOCKET_INVALID_PARAM;
+ break;
+ }
+ return err_code;
+}
+
+/**
+ * @brief Transport for configuration socket.
+ */
+socket_transport_t config_socket_transport =
+{
+ .open = config_socket_open,
+ .setsockopt = config_socket_setopt,
+ .getsockopt = config_socket_getopt,
+ .close = config_socket_close
+};
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/socket/config/medium/config_medium.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/socket/config/medium/config_medium.h
new file mode 100644
index 0000000..e4b7c01
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/socket/config/medium/config_medium.h
@@ -0,0 +1,120 @@
+/**
+ * Copyright (c) 2015 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 config_medium.h
+ *
+ * @defgroup iot_socket_config_medium Configuration socket based on ipv6_medium
+ * @ingroup iot_sdk_socket
+ * @{
+ * @brief Configuration socket based on the ipv6_medium module.
+ *
+ * This module wraps the medium module in a configuration socket API.
+ */
+#ifndef CONFIG_MEDIUM_H__
+#define CONFIG_MEDIUM_H__
+
+#include <stdint.h>
+#include "iot_defines.h"
+#include "ipv6_medium.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @brief Function for initializing a configuration socket with default settings.
+ *
+ * @return NRF_SUCCESS on success, otherwise an error code.
+ */
+uint32_t config_medium_init_default(void);
+
+/**
+ * @brief Function for starting the medium layer.
+ *
+ * For BLE, this means to start advertising.
+ */
+void config_medium_start(void);
+
+/**
+ * @brief Function for retrieving local interface ID assigned.
+ *
+ * @return Pointer to location of interface ID.
+ */
+eui64_t * config_medium_local_iid(void);
+
+/**
+ * @brief Function for setting configuration parameters for the medium layers using the socket option.
+ *
+ * @param optname Option name/type.
+ * @param p_optarg Pointer to option value.
+ * @param optlen Length of option value.
+ *
+ * @return NRF_SUCCESS on success, otherwise an error code.
+ */
+uint32_t config_medium_setopt(int optname, const void * p_optarg, socklen_t optlen);
+
+/**
+ * @brief Function for getting configuration parameters for the medium layers using the socket option.
+ *
+ * @param optname Option name/type.
+ * @param p_optarg Pointer to the option value structure where the value should be stored.
+ * @param p_optlen Length of option value.
+ *
+ * @return NRF_SUCCESS on success, otherwise an error code.
+ */
+uint32_t config_medium_getopt(int optname, void * p_optarg, socklen_t * p_optlen);
+
+/**
+ * @brief Parameters passed for the MEDIUM_INIT_PARAMS option.
+ *
+ * These are currently the same as for ipv6_medium initialization.
+ */
+typedef struct {
+ ipv6_medium_evt_handler_t evt_handler; /**< The medium event handler callback. */
+ ipv6_medium_error_handler_t error_handler; /**< The medium error handler callback. */
+ ipv6_medium_type_t medium_type; /**< The medium type. */
+} config_medium_params_t;
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // CONFIG_MEDIUM_H__
+
+/**@} */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/socket/libraries/addr_util/inet_pton.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/socket/libraries/addr_util/inet_pton.c
new file mode 100644
index 0000000..2fd1f4c
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/socket/libraries/addr_util/inet_pton.c
@@ -0,0 +1,60 @@
+/**
+ * Copyright (c) 2015 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#include "socket_api.h"
+#include "ipv6_parse.h"
+
+int inet_pton(socket_family_t af, const char * p_src, void * p_dst)
+{
+ int ret_val = 1;
+ if (af != AF_INET6)
+ {
+ ret_val = -1;
+ }
+ else
+ {
+ in6_addr_t * p_addr = (in6_addr_t *)p_dst;
+ uint32_t err_code = ipv6_parse_addr(p_addr->s6_addr, p_src, strlen(p_src));
+ if (err_code != NRF_SUCCESS)
+ {
+ ret_val = 0;
+ }
+ }
+ return ret_val;
+}
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/socket/libraries/fifo/nrf_fifo.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/socket/libraries/fifo/nrf_fifo.c
new file mode 100644
index 0000000..1458b01
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/socket/libraries/fifo/nrf_fifo.c
@@ -0,0 +1,176 @@
+/**
+ * Copyright (c) 2015 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#include "iot_defines.h"
+#include "iot_errors.h"
+#include "nrf_fifo.h"
+#include "mem_manager.h"
+#include "nrf.h"
+
+static __INLINE uint32_t fifo_inc(nrf_fifo_t * p_fifo, uint32_t pos)
+{
+ return (pos + 1) % p_fifo->nmemb;
+}
+
+static __INLINE bool fifo_full(nrf_fifo_t * p_fifo)
+{
+ return fifo_inc(p_fifo, p_fifo->write_pos) == p_fifo->read_pos;
+}
+
+static __INLINE bool fifo_empty(nrf_fifo_t * p_fifo)
+{
+ return p_fifo->read_pos == p_fifo->write_pos;
+}
+
+static __INLINE void fifo_enq(nrf_fifo_t * p_fifo, void * p_ctx)
+{
+ p_fifo->pp_elements[p_fifo->write_pos] = p_ctx;
+ __DSB();
+ p_fifo->write_pos = fifo_inc(p_fifo, p_fifo->write_pos);
+}
+
+
+static __INLINE void fifo_deq(nrf_fifo_t * p_fifo, void ** pp_ctx)
+{
+ *pp_ctx = p_fifo->pp_elements[p_fifo->read_pos];
+ __DSB();
+ p_fifo->read_pos = fifo_inc(p_fifo, p_fifo->read_pos);
+}
+
+uint32_t nrf_fifo_init(nrf_fifo_t * p_fifo, uint32_t nmemb, fifo_wait_fn wait_fn, fifo_flush_fn flush_fn)
+{
+ uint32_t err_code = NRF_SUCCESS;
+ uint32_t nmemb_actual = nmemb + 1; // Required to allow detection of empty and full state
+ p_fifo->pp_elements = nrf_malloc(nmemb_actual * sizeof(void *));
+
+ if (p_fifo->pp_elements == NULL)
+ {
+ err_code = NRF_ERROR_NO_MEM;
+ }
+ else
+ {
+ p_fifo->nmemb = nmemb_actual;
+ p_fifo->wait = wait_fn;
+ p_fifo->flush = flush_fn;
+ p_fifo->read_pos = 0;
+ p_fifo->write_pos = 0;
+ }
+ return err_code;
+}
+
+void nrf_fifo_deinit(nrf_fifo_t * p_fifo)
+{
+ if (p_fifo->flush != NULL)
+ {
+ void * p_data;
+ uint32_t err_code = nrf_fifo_deq(p_fifo, &p_data, false);
+ while (err_code == NRF_SUCCESS)
+ {
+ p_fifo->flush(p_data);
+ err_code = nrf_fifo_deq(p_fifo, &p_data, false);
+ }
+ }
+ nrf_free(p_fifo->pp_elements);
+ p_fifo->nmemb = 0;
+ p_fifo->read_pos = 0;
+ p_fifo->write_pos = 0;
+ p_fifo->wait = NULL;
+ p_fifo->flush = NULL;
+}
+
+uint32_t nrf_fifo_enq(nrf_fifo_t * p_fifo, void * p_ctx, bool wait)
+{
+ uint32_t err_code = NRF_SUCCESS;
+
+ if (fifo_full(p_fifo) == true)
+ {
+ if (wait == false || p_fifo->wait == NULL)
+ {
+ err_code = SOCKET_WOULD_BLOCK;
+ }
+ else
+ {
+ while (fifo_full(p_fifo) == true && err_code == NRF_SUCCESS)
+ {
+ err_code = p_fifo->wait();
+ }
+ }
+ }
+ else
+ {
+ fifo_enq(p_fifo, p_ctx);
+ }
+ return err_code;
+}
+
+uint32_t nrf_fifo_deq(nrf_fifo_t * p_fifo, void ** pp_ctx, bool wait)
+{
+ uint32_t err_code = NRF_SUCCESS;
+
+ if (fifo_empty(p_fifo) == true)
+ {
+ if (wait == false || p_fifo->wait == NULL)
+ {
+ err_code = SOCKET_WOULD_BLOCK;
+ }
+ else
+ {
+ while (fifo_empty(p_fifo) == true && err_code == NRF_SUCCESS)
+ {
+ err_code = p_fifo->wait();
+ }
+ }
+ }
+
+ if (err_code == NRF_SUCCESS)
+ {
+ fifo_deq(p_fifo, pp_ctx);
+ }
+ return err_code;
+}
+
+bool nrf_fifo_empty(nrf_fifo_t * p_fifo)
+{
+ return fifo_empty(p_fifo);
+}
+
+bool nrf_fifo_full(nrf_fifo_t * p_fifo)
+{
+ return fifo_full(p_fifo);
+}
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/socket/libraries/fifo/nrf_fifo.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/socket/libraries/fifo/nrf_fifo.h
new file mode 100644
index 0000000..c6fb378
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/socket/libraries/fifo/nrf_fifo.h
@@ -0,0 +1,170 @@
+/**
+ * Copyright (c) 2015 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#ifndef NRF_FIFO_H__
+#define NRF_FIFO_H__
+
+#include <stdint.h>
+#include <stdbool.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @file nrf_fifo.h
+ *
+ * @defgroup iot_socket_fifo FIFO
+ * @ingroup iot_sdk_socket
+ * @{
+ * @brief A wait-free bounded FIFO of pointers for single producer/single consumer use.
+ *
+ * This FIFO is safe to use in single producer/single consumer patterns. In addition, the following
+ * restrictions apply for init/deinit:
+ *
+ * a) nrf_fifo_enq() and nrf_fifo_deq() may only be called after nrf_fifo_init() is called.
+ *
+ * b) All calls to nrf_fifo_enq() and nrf_fifo_deq() must be finished and no new calls must be made before nrf_fifo_deinit() is called.
+ *
+ * These restrictions must be handled by the user of the module, for instance by using a mutex.
+ */
+
+/**
+ * @brief Wait function for blocking enqueue/dequeue.
+ *
+ * Should return NRF_SUCCESS as long as there are no errors while waiting.
+ */
+typedef uint32_t (*fifo_wait_fn)(void);
+
+/**
+ * @brief Flush function called on deinit.
+ *
+ * On deinit, this function will be called with each remaining element in the FIFO as argument. This
+ * can be used to ensure that memory is deallocated properly.
+ *
+ * @param[in] p_data Pointer to data that is flushed from FIFO.
+ */
+typedef void (*fifo_flush_fn)(void * p_data);
+
+/**
+ * @brief FIFO data structure.
+ */
+typedef struct {
+ void ** pp_elements; /**< The array of elements in the FIFO. */
+ uint32_t nmemb; /**< The number of elements in this FIFO. */
+ fifo_wait_fn wait; /**< The wait function used if blocking. */
+ fifo_flush_fn flush; /**< The flush function used on deinit. */
+ volatile uint32_t read_pos; /**< Read pointer to next element to read. */
+ volatile uint32_t write_pos; /**< Write pointer to next element to write. */
+} nrf_fifo_t;
+
+/**
+ * @brief Function for initializing the FIFO.
+ *
+ * @param[out] p_fifo The FIFO to initialize.
+ * @param[in] nmemb The maximum number of elements in the FIFO.
+ * @param[in] wait_fn The wait function to use for blocking enqueue/dequeue. If NULL, the enq/deq
+ * functions will never block.
+ * @param[in] flush_fn The flush function to call on deinit. If NULL, the flush function will not
+ * be called.
+ *
+ * @retval NRF_SUCCESS if fifo was initialized successfully.
+ */
+uint32_t nrf_fifo_init(nrf_fifo_t * p_fifo, uint32_t nmemb, fifo_wait_fn wait_fn, fifo_flush_fn flush_fn);
+
+/**
+ * @brief Function for deinitializing the FIFO.
+ *
+ * Frees all memory allocated by this FIFO. All elements are removed. If a flush function was
+ * specified in nrf_fifo_init(), the function will be called for each remaining element in the
+ * FIFO.
+ *
+ * @param[in, out] p_fifo The FIFO to deinitialize.
+ */
+void nrf_fifo_deinit(nrf_fifo_t * p_fifo);
+
+/**
+ * @brief Function for enqueuing an element on the FIFO.
+ *
+ * @param[in, out] p_fifo The FIFO to enqueue elements on.
+ * @param[in] p_ctx The pointer to enqueue.
+ * @param[in] wait If true, this function will block until the FIFO has available space. Any
+ * errors returned by this function will be propagated to the caller.
+ *
+ * @retval NRF_SUCCESS if the element was queued.
+ * @retval NRF_ERROR_NO_MEM if wait was set to false and no space was available.
+ */
+uint32_t nrf_fifo_enq(nrf_fifo_t * p_fifo, void * p_ctx, bool wait);
+
+/**
+ * @brief Function for dequeuing an element from the FIFO.
+ *
+ * @param[in, out] p_fifo The FIFO to dequeue elements from.
+ * @param[out] pp_ctx Pointer to where the dequeued element should be stored.
+ * @param[in] wait If true, this function will block until the FIFO has elements for dequeuing.
+ * Any errors returned by this function will be propagated to the caller.
+ *
+ * @retval NRF_SUCCESS if the element was queued.
+ * @retval NRF_ERROR_NO_MEM if wait was set to false and no space was available.
+ */
+uint32_t nrf_fifo_deq(nrf_fifo_t * p_fifo, void ** pp_ctx, bool wait);
+
+/**
+ * @brief Function for checking if the FIFO is empty.
+ *
+ * @param[in] p_fifo The FIFO to check.
+ * @return true if empty, false if not.
+ */
+bool nrf_fifo_empty(nrf_fifo_t * p_fifo);
+
+/**
+ * @brief Function for checking if the FIFO is full.
+ *
+ * @param[in] p_fifo The FIFO to check.
+ * @return true if full, false if not.
+ */
+bool nrf_fifo_full(nrf_fifo_t * p_fifo);
+
+/**@} */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // NRF_FIFO_H__
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/socket/libraries/mbuf/mbuf.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/socket/libraries/mbuf/mbuf.c
new file mode 100644
index 0000000..d4b0c79
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/socket/libraries/mbuf/mbuf.c
@@ -0,0 +1,122 @@
+/**
+ * Copyright (c) 2015 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#include "iot_defines.h"
+#include "iot_errors.h"
+#include "sdk_config.h"
+#include "mem_manager.h"
+#include "mbuf.h"
+#include "nrf_fifo.h"
+#include "socket_common.h"
+
+uint32_t mbuf_init(mbuf_t * p_mbuf,
+ mbuf_read_fn read_fn,
+ mbuf_buf_len_fn buf_len_fn,
+ mbuf_free_fn free_fn,
+ uint32_t nmemb)
+{
+ p_mbuf->p_current = NULL;
+ p_mbuf->read_pos = 0;
+ p_mbuf->read = read_fn;
+ p_mbuf->buf_len = buf_len_fn;
+ p_mbuf->free = free_fn;
+ return nrf_fifo_init(&p_mbuf->fifo, nmemb, socket_wait, free_fn);
+}
+
+void mbuf_deinit(mbuf_t * p_mbuf)
+{
+ if (p_mbuf->p_current != NULL)
+ {
+ p_mbuf->free(p_mbuf->p_current);
+ p_mbuf->p_current = NULL;
+ }
+
+ p_mbuf->read_pos = 0;
+ p_mbuf->read = NULL;
+ p_mbuf->buf_len = NULL;
+ p_mbuf->free = NULL;
+ nrf_fifo_deinit(&p_mbuf->fifo);
+}
+
+static bool mbuf_empty_current(mbuf_t * p_mbuf)
+{
+ return (p_mbuf->buf_len(p_mbuf->p_current) == p_mbuf->read_pos);
+}
+
+bool mbuf_empty(mbuf_t * p_mbuf)
+{
+ return ((p_mbuf->p_current == NULL || mbuf_empty_current(p_mbuf)) &&
+ nrf_fifo_empty(&p_mbuf->fifo));
+}
+
+uint32_t mbuf_write(mbuf_t * p_mbuf, void * p_ctx)
+{
+ return nrf_fifo_enq(&p_mbuf->fifo, p_ctx, false);
+}
+
+static void mbuf_load(mbuf_t * p_mbuf)
+{
+ if (p_mbuf->p_current == NULL)
+ {
+ (void)nrf_fifo_deq(&p_mbuf->fifo, &p_mbuf->p_current, false);
+ }
+}
+
+uint32_t mbuf_read(mbuf_t * p_mbuf, void * p_buf, uint32_t buf_size)
+{
+ uint32_t nbytes = 0;
+ while (nbytes < buf_size && mbuf_empty(p_mbuf) == false)
+ {
+ mbuf_load(p_mbuf);
+ void * p_current = p_mbuf->p_current;
+ const uint32_t copy_len = p_mbuf->read(p_current,
+ p_mbuf->read_pos,
+ ((uint8_t *)p_buf) + nbytes,
+ buf_size - nbytes);
+ p_mbuf->read_pos += copy_len;
+ nbytes += copy_len;
+ if (mbuf_empty_current(p_mbuf) == true)
+ {
+ p_mbuf->free(p_mbuf->p_current);
+ p_mbuf->p_current = NULL;
+ p_mbuf->read_pos = 0;
+ }
+ }
+ return nbytes;
+}
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/socket/libraries/mbuf/mbuf.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/socket/libraries/mbuf/mbuf.h
new file mode 100644
index 0000000..884c650
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/socket/libraries/mbuf/mbuf.h
@@ -0,0 +1,146 @@
+/**
+ * Copyright (c) 2015 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#ifndef MBUF_H__
+#define MBUF_H__
+
+/**
+ * @file mbuf.h
+ *
+ * @defgroup iot_socket_mbuf Memory management for socket
+ * @ingroup iot_sdk_socket
+ * @{
+ * @brief Memory management for socket.
+ */
+
+#include <stdbool.h>
+#include "nrf_fifo.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**@brief Function for reading data from a buffer. */
+typedef uint32_t (*mbuf_read_fn)(void * p_ctx,
+ uint32_t read_offset,
+ uint8_t * p_dest,
+ uint32_t dest_len);
+
+/**@brief Function for checking buffer length. */
+typedef uint32_t (*mbuf_buf_len_fn)(void * p_ctx);
+
+/**@brief Function for freeing a buffer. */
+typedef void (*mbuf_free_fn)(void * p_ctx);
+
+/**@brief Memory management structure. */
+typedef struct
+{
+ nrf_fifo_t fifo; /**< FIFO for storing data buffers. */
+ mbuf_read_fn read; /**< Function for reading data from a buffer. */
+ mbuf_buf_len_fn buf_len; /**< Function for checking buffer length. */
+ mbuf_free_fn free; /**< Function for freeing a buffer. */
+ uint32_t read_pos; /**< Read position in the currently processed buffer. */
+ void * p_current; /**< Pointer to the currently processed buffer. */
+} mbuf_t;
+
+/**
+ * @brief Function for initializing the memory buffer manager.
+ *
+ * This function allocates resources for the mbuf FIFO and initializes the mbuf.
+ *
+ * @param[in, out] p_mbuf Pointer to the mbuf structure to initialize.
+ * @param[in] read_fn Function for reading data from a buffer.
+ * @param[in] buf_len_fn Function for checking buffer length.
+ * @param[in] free_fn Function for freeing a buffer.
+ * @param[in] nmemb Maximum number of data buffers.
+ *
+ * @return NRF_SUCCESS on success, otherwise error code is returned.
+ */
+uint32_t mbuf_init(mbuf_t * p_mbuf,
+ mbuf_read_fn read_fn,
+ mbuf_buf_len_fn buf_len_fn,
+ mbuf_free_fn free_fn,
+ uint32_t nmemb);
+
+/**
+ * @brief Function for deinitializing the memory buffer manager.
+ *
+ * This function releases any resources allocated for mbuf instance pointed by p_mbuf.
+ *
+ * @param[in, out] p_mbuf Pointer to the mbuf structure to deinitialize.
+ */
+void mbuf_deinit(mbuf_t * p_mbuf);
+
+/**
+ * @brief Function for putting a data buffer in the mbuf.
+ *
+ * @param[in, out] p_mbuf Pointer to the mbuf structure that shall store the buffer.
+ * @param[in] p_ctx Pointer to the data buffer to store.
+ *
+ * @return NRF_SUCCESS on success, otherwise error code is returned.
+ */
+uint32_t mbuf_write(mbuf_t * p_mbuf, void * p_ctx);
+
+/**
+ * @brief Function for reading data from the mbuf.
+ *
+ * @param[in, out] p_mbuf Pointer to the mbuf structure to read data from.
+ * @param[in] p_buf Pointer to the buffer where data shall be read from.
+ * @param[out] buf_size Size of the buffer pointed by p_buf.
+ *
+ * @return NRF_SUCCESS on success, otherwise error code is returned.
+ */
+uint32_t mbuf_read(mbuf_t * p_mbuf, void * p_buf, uint32_t buf_size);
+
+/**
+ * @brief Function for checking if the mbuf is empty.
+ *
+ * @param[in] p_mbuf Pointer to the mbuf structure that shall be checked.
+ *
+ * @return True if mbuf is empty, false otherwise.
+ */
+bool mbuf_empty(mbuf_t * p_mbuf);
+
+#ifdef __cplusplus
+}
+#endif
+
+/**@} */
+
+#endif // MBUF_H__
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/socket/libraries/portdb/portdb.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/socket/libraries/portdb/portdb.c
new file mode 100644
index 0000000..7bfbcc4
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/socket/libraries/portdb/portdb.c
@@ -0,0 +1,185 @@
+/**
+ * Copyright (c) 2016 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#include "portdb.h"
+#include <string.h>
+#include "iot_common.h"
+#include "iot_errors.h"
+#include "mem_manager.h"
+#include "nrf_error.h"
+
+#define IANA_EPHEMRAL_BEGIN 49152u /**< Minimum port number of the ephemeral port range. */
+#define IANA_EPHEMRAL_END 65535u /**< Maximum port number of the ephemeral port range. */
+
+static uint16_t * m_portdb; /**< A pointer to the port database. */
+static uint32_t m_portdb_len; /**< Length of the port database. */
+
+
+
+static __INLINE uint32_t db_size_get(void)
+{
+ return m_portdb_len * sizeof(uint16_t);
+}
+
+
+static __INLINE void db_reset(void)
+{
+ memset(&m_portdb[0], 0, db_size_get());
+}
+
+
+uint32_t portdb_init(uint32_t max_ports)
+{
+ uint32_t err_code = NRF_SUCCESS;
+ m_portdb_len = max_ports;
+ m_portdb = nrf_malloc(db_size_get());
+ if (m_portdb == NULL)
+ {
+ err_code = NRF_ERROR_NO_MEM;
+ }
+ else
+ {
+ db_reset();
+ }
+ return err_code;
+}
+
+
+void portdb_deinit(void)
+{
+ nrf_free(m_portdb);
+ m_portdb = NULL;
+ m_portdb_len = 0;
+}
+
+
+void portdb_reset(void)
+{
+ db_reset();
+}
+
+
+static inline uint32_t check_port_in_use(uint16_t port)
+{
+ uint32_t err_code = NRF_SUCCESS;
+
+ for (uint32_t i = 0; i < m_portdb_len; i++)
+ {
+ if (m_portdb[i] == port)
+ {
+ err_code = SOCKET_PORT_IN_USE;
+ break;
+ }
+ }
+ return err_code;
+}
+
+static inline uint32_t find_free_index(uint32_t * p_idx)
+{
+ uint32_t err_code = SOCKET_NO_AVAILABLE_PORTS;
+
+ for (uint32_t i = 0; i < m_portdb_len; i++)
+ {
+ if (m_portdb[i] == 0)
+ {
+ *p_idx = i;
+ err_code = NRF_SUCCESS;
+ break;
+ }
+ }
+ return err_code;
+}
+
+static uint32_t portdb_find_available_index(uint32_t * p_idx, uint16_t port)
+{
+ uint32_t err_code = SOCKET_NO_AVAILABLE_PORTS;
+
+ err_code = check_port_in_use(port);
+
+ if (err_code == NRF_SUCCESS)
+ {
+ err_code = find_free_index(p_idx);
+ }
+ return err_code;
+}
+
+uint32_t portdb_register(uint16_t port)
+{
+ uint32_t idx = 0;
+ uint32_t err_code = portdb_find_available_index(&idx, port);
+
+ if (err_code == NRF_SUCCESS)
+ {
+ m_portdb[idx] = port;
+ }
+ return err_code;
+}
+
+uint32_t portdb_alloc(uint16_t * p_port)
+{
+ uint32_t err_code = SOCKET_NO_AVAILABLE_PORTS;
+ for (uint32_t i = IANA_EPHEMRAL_BEGIN; i <= IANA_EPHEMRAL_END; i++)
+ {
+ uint16_t port = (uint16_t)i;
+ err_code = portdb_register(port);
+
+ if (err_code == NRF_SUCCESS)
+ {
+ *p_port = port;
+ break;
+ }
+ else if (err_code == SOCKET_NO_AVAILABLE_PORTS)
+ {
+ break;
+ }
+ }
+ return err_code;
+}
+
+void portdb_free(uint16_t port)
+{
+ for (uint32_t i = 0; i < m_portdb_len; i++)
+ {
+ if (m_portdb[i] == port)
+ {
+ m_portdb[i] = 0;
+ break;
+ }
+ }
+}
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/socket/libraries/portdb/portdb.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/socket/libraries/portdb/portdb.h
new file mode 100644
index 0000000..94f0d38
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/socket/libraries/portdb/portdb.h
@@ -0,0 +1,123 @@
+/**
+ * Copyright (c) 2016 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#ifndef PORTDB_H__
+#define PORTDB_H__
+
+/**
+ * @file portdb.h
+ *
+ * @defgroup iot_socket_portdb Port Database
+ * @ingroup iot_sdk_socket
+ * @{
+ * @brief Port database for sockets.
+ *
+ * The port database provides a functionality for registering, allocating, and freeing ports.
+ */
+
+#include <stdint.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @brief Function for initializing the port database.
+ *
+ * This must be called before allocating and freeing ports.
+ *
+ * @param max_len The max length of the portdb.
+ *
+ * @retval NRF_SUCCESS If successfully initialized.
+ */
+uint32_t portdb_init(uint32_t max_len);
+
+/**
+ * @brief Function for deinitializing the portdb.
+ *
+ * This will free all memory allocated by this portdb.
+ */
+void portdb_deinit(void);
+
+/**
+ * @brief Function to reset all ports without freeing any memories.
+ */
+void portdb_reset(void);
+
+/**
+ * @brief Function for allocating a port.
+ *
+ * Looks for an available port in the database and allocates it to the caller.
+ *
+ * @param[out] p_port Pointer to a variable where the allocated port number should be stored.
+ *
+ * @retval NRF_SUCCESS If a free port was located and successfully allocated.
+ * @retval SOCKET_NO_AVAILABLE_PORTS If no available ports were found.
+ */
+uint32_t portdb_alloc(uint16_t * p_port);
+
+/**
+ * @brief Function for registering a port.
+ *
+ * Marks a given port in the database as being in use.
+ *
+ * @param[in] port The port to mark as in use.
+ *
+ * @retval NRF_SUCCESS If port was successfully marked as in use.
+ * @retval SOCKET_NO_AVAILABLE_PORTS If there was no slot in which to register the port.
+ * @retval SOCKET_PORT_IN_USE If the port has already been registered or allocated.
+ */
+uint32_t portdb_register(uint16_t port);
+
+/**
+ * @brief Function for freeing a port.
+ *
+ * Mark a given port as free and make it available for others to register or allocate.
+ *
+ * @param[in] port The port to mark as free.
+ */
+void portdb_free(uint16_t port);
+
+#ifdef __cplusplus
+}
+#endif
+
+/**@} */
+
+#endif // PORTDB_H__
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/socket/platform/ble/socket_ble.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/socket/platform/ble/socket_ble.c
new file mode 100644
index 0000000..da2cc7b
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/socket/platform/ble/socket_ble.c
@@ -0,0 +1,50 @@
+/**
+ * Copyright (c) 2016 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#include <stdint.h>
+#include "nrf_soc.h"
+#include "app_scheduler.h"
+
+uint32_t socket_wait(void)
+{
+ // Execute event schedule.
+ app_sched_execute();
+
+ return sd_app_evt_wait();
+}
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/socket/transport/ipv6/transport_handler.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/socket/transport/ipv6/transport_handler.c
new file mode 100644
index 0000000..a9d6edd
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/socket/transport/ipv6/transport_handler.c
@@ -0,0 +1,387 @@
+/**
+ * Copyright (c) 2015 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#include "iot_defines.h"
+#include "iot_errors.h"
+#include "sdk_config.h"
+#include "socket_trace.h"
+#include "socket_common.h"
+#include "socket_config.h"
+#include "config_medium.h"
+#include "transport_if.h"
+#include "udp_api.h"
+#include "portdb.h"
+#include "nrf_soc.h"
+#include "nrf_fifo.h"
+
+/**@brief Verify that IPv6 address length is correct. */
+#define VERIFY_ADDRESS_LEN(len) \
+ do { \
+ if ((len) != sizeof(sockaddr_in6_t)) { \
+ return NRF_ERROR_NULL | IOT_SOCKET_ERR_BASE; \
+ } \
+ } while (0)
+
+#define SOCKET_MAX_PENDING_PACKETS 32 /**< Maximum number of pending received packets. */
+
+/**@brief Nordic IPv6 handle structure. */
+typedef struct
+{
+ udp6_socket_t socket; /**< UDP socket. */
+ nrf_fifo_t recv_queue; /**< Received packets queue. */
+ uint16_t local_port; /**< Local port number. */
+} ipv6_handle_t;
+
+static const char * unused = "UNUSED"; /**< A pointer indicating an unused socket. */
+static ipv6_handle_t ipv6_handles[SOCKET_MAX_SOCKET_COUNT]; /**< IPv6 handle array. */
+
+void free_pbuffer(void * p_data)
+{
+ (void) iot_pbuffer_free((iot_pbuffer_t *)p_data, true);
+}
+
+static ipv6_handle_t * ipv6_handle_allocate(socket_t * p_socket)
+{
+ ipv6_handle_t * p_handle = NULL;
+ for (uint32_t i = 0; i < SOCKET_MAX_SOCKET_COUNT; i++)
+ {
+ if (ipv6_handles[i].socket.p_app_data == unused)
+ {
+ p_handle = &ipv6_handles[i];
+ p_handle->socket.p_app_data = p_socket;
+ (void) nrf_fifo_init(&p_handle->recv_queue, SOCKET_MAX_PENDING_PACKETS, socket_wait, free_pbuffer);
+ uint32_t err_code = udp6_socket_app_data_set(&p_handle->socket);
+ if (err_code != NRF_SUCCESS)
+ {
+ p_handle = NULL;
+ }
+ break;
+ }
+ }
+ return p_handle;
+}
+
+static uint32_t ipv6_handle_free(ipv6_handle_t * p_handle)
+{
+ p_handle->local_port = 0;
+ p_handle->socket.p_app_data = (void *)unused;
+ return udp6_socket_app_data_set(&p_handle->socket);
+}
+
+void transport_event_handler(iot_interface_t * p_interface, ipv6_event_t * p_event)
+{
+ (void) p_interface;
+
+ switch (p_event->event_id)
+ {
+ case IPV6_EVT_INTERFACE_ADD:
+ transport_interface_up();
+ break;
+ case IPV6_EVT_INTERFACE_DELETE:
+ transport_interface_down();
+ break;
+ case IPV6_EVT_INTERFACE_RX_DATA:
+ break;
+ default:
+ break;
+ }
+}
+
+void transport_handler_init(void)
+{
+ ipv6_init_t init_param;
+ init_param.p_eui64 = config_medium_local_iid();
+ init_param.event_handler = transport_event_handler;
+
+ uint32_t err_code = ipv6_init(&init_param);
+ (void) err_code;
+ // APP_ERROR_CHECK(err_code);
+ for (uint32_t i = 0; i< SOCKET_MAX_SOCKET_COUNT; i++)
+ {
+ ipv6_handles[i].local_port = 0;
+ ipv6_handles[i].socket.socket_id = 0;
+ ipv6_handles[i].socket.p_app_data = (void *)unused;
+ }
+}
+
+static uint32_t ipv6_transport_open(socket_t * p_socket)
+{
+ uint32_t err_code = NRF_SUCCESS;
+ if (p_socket->so_params.so_type != SOCK_DGRAM)
+ {
+ err_code = SOCKET_UNSUPPORTED_PROTOCOL;
+ }
+ if (err_code == NRF_SUCCESS)
+ {
+ ipv6_handle_t * p_ipv6_handle = ipv6_handle_allocate(p_socket);
+ if (p_ipv6_handle == NULL)
+ {
+ err_code = NRF_ERROR_NULL;
+ }
+ else
+ {
+ err_code = udp6_socket_allocate(&p_ipv6_handle->socket);
+ if (err_code == NRF_SUCCESS)
+ {
+ p_socket->so_ctx = p_ipv6_handle;
+ }
+ else
+ {
+ (void) ipv6_handle_free(p_ipv6_handle);
+ }
+ }
+ }
+ return err_code;
+}
+
+static uint32_t ipv6_transport_close(socket_t * p_socket)
+{
+ ipv6_handle_t * p_ipv6_handle = (ipv6_handle_t *) p_socket->so_ctx;
+ if (p_ipv6_handle->local_port > 0)
+ {
+ portdb_free(p_ipv6_handle->local_port);
+ }
+
+ uint32_t err_code = udp6_socket_free(&p_ipv6_handle->socket);
+ if (err_code == NRF_SUCCESS)
+ {
+ err_code = ipv6_handle_free(p_ipv6_handle);
+ }
+ return err_code;
+}
+
+static uint32_t ipv6_transport_recv_callback(const udp6_socket_t * p_udp_socket,
+ const ipv6_header_t * p_ip_header,
+ const udp6_header_t * p_udp_header,
+ uint32_t process_result,
+ iot_pbuffer_t * p_rx_packet)
+{
+ uint32_t err_code = process_result;
+ socket_t * p_socket = (socket_t *)p_udp_socket->p_app_data;
+ ipv6_handle_t * p_ipv6_handle = (ipv6_handle_t *)p_socket->so_ctx;
+ if (err_code == NRF_SUCCESS)
+ {
+ err_code = nrf_fifo_enq(&p_ipv6_handle->recv_queue, p_rx_packet, false);
+ if (err_code == NRF_SUCCESS)
+ {
+ p_socket->so_read_evt++;
+ err_code = IOT_IPV6_ERR_PENDING;
+ }
+ }
+ return err_code;
+}
+
+static uint32_t ipv6_transport_bind(socket_t * p_socket, const void * p_addr, socklen_t addr_len)
+{
+ VERIFY_ADDRESS_LEN(addr_len);
+ const sockaddr_in6_t * p_addr_in6 = (const sockaddr_in6_t *)p_addr;
+ ipv6_handle_t * p_ipv6_handle = (ipv6_handle_t *)p_socket->so_ctx;
+ udp6_socket_t * p_udp_socket = &p_ipv6_handle->socket;
+
+ p_ipv6_handle->local_port = HTONS(p_addr_in6->sin6_port);
+ uint32_t err_code = portdb_register(p_ipv6_handle->local_port);
+ if (err_code == NRF_SUCCESS)
+ {
+ ipv6_addr_t * p_ipv6_addr = (ipv6_addr_t *)&p_addr_in6->sin6_addr;
+ err_code = udp6_socket_bind(p_udp_socket, p_ipv6_addr, p_ipv6_handle->local_port);
+ }
+ if (err_code == NRF_SUCCESS)
+ {
+ err_code = udp6_socket_recv(p_udp_socket, ipv6_transport_recv_callback);
+ }
+ return err_code;
+}
+
+static uint32_t ipv6_transport_bind_any(ipv6_handle_t * p_ipv6_handle)
+{
+ udp6_socket_t * p_udp_socket = &p_ipv6_handle->socket;
+ uint32_t err_code = portdb_alloc(&p_ipv6_handle->local_port);
+ if (err_code == NRF_SUCCESS)
+ {
+ SOCKET_TRACE("Binding to port %hu\r\n", p_ipv6_handle->local_port);
+ err_code = udp6_socket_bind(p_udp_socket, IPV6_ADDR_ANY, p_ipv6_handle->local_port);
+ }
+
+ if (err_code == NRF_SUCCESS)
+ {
+ err_code = udp6_socket_recv(p_udp_socket, ipv6_transport_recv_callback);
+ }
+ return err_code;
+}
+
+static uint32_t ipv6_transport_connect(socket_t * p_socket, const void * p_addr, socklen_t addr_len)
+{
+ VERIFY_ADDRESS_LEN(addr_len);
+
+ ipv6_handle_t * p_ipv6_handle = (ipv6_handle_t *)p_socket->so_ctx;
+ udp6_socket_t * p_udp_socket = &p_ipv6_handle->socket;
+ const sockaddr_in6_t * p_addr_in6 = (const sockaddr_in6_t *)p_addr;
+ uint32_t err_code = NRF_SUCCESS;
+
+ // Port might already have been bound with an explicit call to bind()
+ if (p_ipv6_handle->local_port == 0)
+ {
+ err_code = ipv6_transport_bind_any(p_ipv6_handle);
+ }
+
+ if (err_code == NRF_SUCCESS)
+ {
+ // These data structures are compatible, and can therefore be cast
+ err_code = udp6_socket_connect(p_udp_socket,
+ (ipv6_addr_t *)&p_addr_in6->sin6_addr,
+ HTONS(p_addr_in6->sin6_port));
+ }
+
+ return err_code;
+}
+
+static uint32_t ipv6_transport_send(socket_t * p_socket,
+ const void * p_buf,
+ uint32_t len,
+ int flags,
+ const void * p_destaddr,
+ socklen_t destaddr_len)
+{
+ ipv6_handle_t * p_ipv6_handle = (ipv6_handle_t *)p_socket->so_ctx;
+ udp6_socket_t * p_udp_socket = &p_ipv6_handle->socket;
+ uint32_t err_code = NRF_SUCCESS;
+ iot_pbuffer_alloc_param_t pbuff_param;
+
+ // Ensure that port is bound before sending packet
+ if (p_ipv6_handle->local_port == 0)
+ {
+ err_code = ipv6_transport_bind_any(p_ipv6_handle);
+ }
+
+ if (err_code == NRF_SUCCESS)
+ {
+ pbuff_param.flags = PBUFFER_FLAG_DEFAULT;
+ pbuff_param.type = UDP6_PACKET_TYPE;
+ pbuff_param.length = len;
+
+ iot_pbuffer_t * p_buffer = NULL;
+ err_code = iot_pbuffer_allocate(&pbuff_param, &p_buffer);
+ if (err_code == NRF_SUCCESS)
+ {
+ memcpy(p_buffer->p_payload, p_buf, len);
+ if (p_destaddr != NULL && destaddr_len == sizeof(sockaddr_in6_t))
+ {
+ sockaddr_in6_t * p_addr_in6 = (sockaddr_in6_t *)p_destaddr;
+ err_code = udp6_socket_sendto(p_udp_socket,
+ (ipv6_addr_t *)&p_addr_in6->sin6_addr,
+ HTONS(p_addr_in6->sin6_port),
+ p_buffer);
+ }
+ else
+ {
+ err_code = udp6_socket_send(p_udp_socket, p_buffer);
+ }
+ }
+ }
+ return err_code;
+}
+
+static uint32_t ipv6_transport_recv(socket_t * p_socket,
+ void * p_buf,
+ uint32_t * p_sz,
+ int flags,
+ void * p_srcaddr,
+ socklen_t * p_srcaddr_len)
+{
+ if ((p_socket->so_flags & O_NONBLOCK) != 0 &&
+ (flags & MSG_WAITALL) == 0)
+ {
+ flags |= MSG_DONTWAIT;
+ }
+
+ ipv6_handle_t * p_ipv6_handle = (ipv6_handle_t *)p_socket->so_ctx;
+ iot_pbuffer_t * p_pbuffer = NULL;
+ uint32_t err_code = nrf_fifo_deq(&p_ipv6_handle->recv_queue,
+ (void **)&p_pbuffer,
+ (flags & MSG_DONTWAIT) == 0);
+ if (err_code == NRF_SUCCESS)
+ {
+ uint32_t copy_len = MIN(*p_sz, p_pbuffer->length);
+ memcpy(p_buf, p_pbuffer->p_payload, copy_len);
+ *p_sz = copy_len;
+
+ if (p_srcaddr != NULL && p_srcaddr_len != NULL)
+ {
+ const udp6_header_t * p_udp_header =
+ (udp6_header_t *)(p_pbuffer->p_payload - UDP_HEADER_SIZE);
+ const ipv6_header_t * p_ipv6_header =
+ (ipv6_header_t *)(p_pbuffer->p_payload - UDP_HEADER_SIZE - IPV6_IP_HEADER_SIZE);
+ sockaddr_in6_t * p_srcsockaddr = (sockaddr_in6_t *)p_srcaddr;
+
+ *p_srcaddr_len = sizeof(sockaddr_in6_t);
+ p_srcsockaddr->sin6_addr = *((in6_addr_t *)&p_ipv6_header->srcaddr);
+ p_srcsockaddr->sin6_port = HTONS(p_udp_header->srcport);
+ p_srcsockaddr->sin6_len = *p_srcaddr_len;
+ p_srcsockaddr->sin6_family = AF_INET6;
+ p_srcsockaddr->sin6_flowinfo = 0;
+ p_srcsockaddr->sin6_scope_id = 0;
+ }
+
+ (void) iot_pbuffer_free(p_pbuffer, true);
+ p_socket->so_read_evt = 0;
+ }
+ return err_code;
+}
+
+static uint32_t ipv6_transport_listen(socket_t * p_socket, int backlog)
+{
+ // Ignore as this does not make sense for UDP
+ (void) p_socket;
+ (void) backlog;
+ return NRF_SUCCESS;
+}
+
+/**
+ * @brief Transport for Nordic IPv6 socket.
+ */
+socket_transport_t transport_impl =
+{
+ .open = ipv6_transport_open,
+ .bind = ipv6_transport_bind,
+ .connect = ipv6_transport_connect,
+ .send = ipv6_transport_send,
+ .recv = ipv6_transport_recv,
+ .listen = ipv6_transport_listen,
+ .close = ipv6_transport_close
+};
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/socket/transport/lwip/transport_handler.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/socket/transport/lwip/transport_handler.c
new file mode 100644
index 0000000..4537053
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/iot/socket/transport/lwip/transport_handler.c
@@ -0,0 +1,630 @@
+/**
+ * Copyright (c) 2015 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#include "iot_defines.h"
+#include "iot_errors.h"
+#include "sdk_config.h"
+#include "socket_common.h"
+#include "socket_trace.h"
+#include "transport_if.h"
+#include "portdb.h"
+#include "app_timer.h"
+#include "mem_manager.h"
+#include "nrf_fifo.h"
+#include "mbuf.h"
+#include "app_util.h"
+#include "nrf_platform_port.h"
+#include "app_util_platform.h"
+
+#include "lwip/opt.h"
+#include "lwip/init.h"
+#include "lwip/tcp.h"
+#include "lwip/timers.h"
+
+/**@brief Verify that IPv6 address length is correct. */
+#define VERIFY_ADDRESS_LEN(len) \
+ do { \
+ if ((len) != sizeof(sockaddr_in6_t)) { \
+ return NRF_ERROR_NULL | IOT_SOCKET_ERR_BASE; \
+ } \
+ } while (0)
+
+#define LWIP_SYS_TIMER_INTERVAL APP_TIMER_TICKS(100) /**< Interval for timer used as trigger to send. */
+
+#define SOCKET_MAX_PENDING_PACKETS 32 /**< Maximum number of pending received packets. */
+#define SOCKET_MAX_PENDING_CONNECTIONS 10 /**< Maximum number of simultaneous connections. */
+
+/**@brief TCP state */
+typedef enum
+{
+ TCP_STATE_IDLE,
+ TCP_STATE_REQUEST_CONNECTION,
+ TCP_STATE_CONNECTED,
+ TCP_STATE_DATA_TX_IN_PROGRESS,
+ TCP_STATE_TCP_SEND_PENDING,
+ TCP_STATE_DISCONNECTED
+} tcp_state_t;
+
+/**@brief LwIP handle structure. */
+typedef struct {
+ struct tcp_pcb * p_pcb; /**< A pointer to LwIP TCP protocol control block. */
+ socket_t * p_socket; /**< A pointer to corresponding socket. */
+ nrf_fifo_t conn_queue; /**< Connections queue. */
+ mbuf_t mbuf; /**< Memory management queue. */
+ volatile tcp_state_t tcp_state; /**< TCP state. */
+} lwip_handle_t;
+
+static lwip_handle_t lwip_handles[SOCKET_MAX_SOCKET_COUNT]; /**< LwIP handle array. */
+
+/**@brief Timer for LwIP. */
+APP_TIMER_DEF(m_lwip_timer_id);
+
+static err_t lwip_recv_callback(void * p_arg,
+ struct tcp_pcb * p_pcb,
+ struct pbuf * p_pbuf,
+ err_t err);
+
+static uint32_t lwip_buf_read(void * p_ctx,
+ uint32_t read_offset,
+ uint8_t * p_destbuf,
+ uint32_t destbuf_len)
+{
+ struct pbuf * p_pbuf = (struct pbuf *)p_ctx;
+ uint32_t copy_len = MIN(destbuf_len, (p_pbuf->len - read_offset));
+ memcpy(p_destbuf, (void *)(((uint8_t *)p_pbuf->payload) + read_offset), copy_len);
+ return copy_len;
+}
+
+static uint32_t lwip_buf_len(void * p_ctx)
+{
+ struct pbuf * p_pbuf = (struct pbuf *)p_ctx;
+ return p_pbuf->len;
+}
+
+static void lwip_buf_free(void * p_ctx)
+{
+ nrf_free(((struct pbuf *)p_ctx)->payload);
+ (void) pbuf_free((struct pbuf *)p_ctx);
+}
+
+static void lwip_timer_callback(void * p_ctx)
+{
+ (void) p_ctx;
+ sys_check_timeouts();
+}
+
+void nrf_driver_interface_up(iot_interface_t const * p_interface)
+{
+ UNUSED_PARAMETER(p_interface);
+ transport_interface_up();
+}
+
+void nrf_driver_interface_down(iot_interface_t const * p_interface)
+{
+ UNUSED_PARAMETER(p_interface);
+ transport_interface_down();
+}
+
+void transport_handler_init(void)
+{
+ lwip_init();
+ uint32_t err_code = nrf_driver_init();
+ APP_ERROR_CHECK(err_code);
+ for (uint32_t i = 0; i < SOCKET_MAX_SOCKET_COUNT; i++)
+ {
+ lwip_handles[i].p_pcb = NULL;
+ lwip_handles[i].p_socket = NULL;
+ lwip_handles[i].tcp_state = TCP_STATE_IDLE;
+ }
+ err_code = app_timer_create(&m_lwip_timer_id,
+ APP_TIMER_MODE_REPEATED,
+ lwip_timer_callback);
+ APP_ERROR_CHECK(err_code);
+ err_code = app_timer_start(m_lwip_timer_id, LWIP_SYS_TIMER_INTERVAL, NULL);
+ APP_ERROR_CHECK(err_code);
+ SOCKET_TRACE("Initialized LWIP transport handler\r\n");
+}
+
+static void lwip_error_handler(void * p_arg, err_t err)
+{
+ (void) p_arg;
+ SOCKET_TRACE("Error occured: %d\r\n", (int)err);
+ if(err == ERR_ABRT)
+ {
+ portdb_reset();
+ }
+}
+
+static err_t lwip_poll_handler(void * p_arg, struct tcp_pcb * p_pcb)
+{
+ (void) p_arg;
+ (void) p_pcb;
+
+ return ERR_OK;
+}
+
+static void lwip_drop_connection(void * p_ctx)
+{
+ struct tcp_pcb * p_pcb = (struct tcp_pcb *)p_ctx;
+ tcp_abort(p_pcb);
+}
+
+static lwip_handle_t * lwip_handle_allocate(socket_t * p_socket, struct tcp_pcb * p_pcb)
+{
+ lwip_handle_t * p_handle = NULL;
+ for (uint32_t i = 0; i < SOCKET_MAX_SOCKET_COUNT; i++)
+ {
+ if (lwip_handles[i].p_pcb == NULL)
+ {
+ p_handle = &lwip_handles[i];
+ (void)mbuf_init(&p_handle->mbuf,
+ lwip_buf_read,
+ lwip_buf_len,
+ lwip_buf_free,
+ SOCKET_MAX_PENDING_PACKETS);
+ (void) nrf_fifo_init(&p_handle->conn_queue,
+ SOCKET_MAX_PENDING_CONNECTIONS,
+ socket_wait,
+ lwip_drop_connection);
+ p_handle->p_socket = p_socket;
+ p_handle->tcp_state = TCP_STATE_IDLE;
+ if (p_pcb == NULL)
+ {
+ p_handle->p_pcb = tcp_new();
+ }
+ else
+ {
+ p_handle->p_pcb = p_pcb;
+ }
+ tcp_arg(p_handle->p_pcb, p_handle);
+ tcp_setprio(p_handle->p_pcb, TCP_PRIO_MIN);
+ tcp_recv(p_handle->p_pcb, lwip_recv_callback);
+ tcp_err(p_handle->p_pcb, lwip_error_handler);
+ tcp_poll(p_handle->p_pcb, lwip_poll_handler, 0);
+ break;
+ }
+ }
+ SOCKET_TRACE("Allocated LWIP socket handle\r\n");
+ return p_handle;
+}
+
+static void lwip_handle_free(lwip_handle_t * p_handle)
+{
+ nrf_fifo_deinit(&p_handle->conn_queue);
+ mbuf_deinit(&p_handle->mbuf);
+ p_handle->p_pcb = NULL;
+ p_handle->p_socket = NULL;
+ p_handle->tcp_state = TCP_STATE_IDLE;
+ SOCKET_TRACE("Released LWIP socket handle\r\n");
+}
+
+static uint32_t lwip_transport_open(socket_t * p_socket)
+{
+ lwip_handle_t * p_handle = NULL;
+ uint32_t err_code = NRF_SUCCESS;
+ switch (p_socket->so_params.so_type)
+ {
+ case SOCK_STREAM:
+ p_handle = lwip_handle_allocate(p_socket, NULL);
+ if (p_handle == NULL)
+ {
+ err_code = NRF_ERROR_NULL;
+ }
+ else
+ {
+ p_socket->so_ctx = p_handle;
+ }
+ break;
+ default:
+ err_code = NRF_ERROR_NULL;
+ break;
+ }
+ return err_code;
+}
+
+uint32_t lwip_error_convert(err_t lwip_err)
+{
+ uint32_t err_code = NRF_ERROR_NULL;
+ switch (lwip_err)
+ {
+ case ERR_OK:
+ err_code = NRF_SUCCESS;
+ break;
+ case ERR_MEM:
+ err_code = SOCKET_NO_MEM;
+ break;
+ case ERR_TIMEOUT:
+ err_code = SOCKET_TIMEOUT;
+ break;
+ case ERR_RTE:
+ err_code = SOCKET_NO_ROUTE;
+ break;
+ default:
+ err_code = NRF_ERROR_NULL;
+ break;
+ }
+ return err_code;
+}
+
+static uint32_t lwip_transport_close(socket_t * p_socket)
+{
+ lwip_handle_t * p_handle = (lwip_handle_t *)p_socket->so_ctx;
+ portdb_free((uint16_t)p_handle->p_pcb->local_port);
+ err_t err_code = tcp_close(p_handle->p_pcb);
+ if (err_code == ERR_OK)
+ {
+ lwip_handle_free(p_handle);
+ }
+ return lwip_error_convert(err_code);
+}
+
+static err_t lwip_connect_callback(void * p_arg, struct tcp_pcb * p_pcb, err_t err)
+{
+ lwip_handle_t * p_handle = (lwip_handle_t *)p_arg;
+ // TODO: Error check
+ SOCKET_TRACE("New connection\r\n");
+ p_handle->tcp_state = TCP_STATE_CONNECTED;
+ return ERR_OK;
+}
+
+static err_t lwip_recv_callback(void * p_arg,
+ struct tcp_pcb * p_pcb,
+ struct pbuf * p_pbuf,
+ err_t err)
+{
+ lwip_handle_t * p_handle = (lwip_handle_t *)p_arg;
+ socket_t * p_socket = p_handle->p_socket;
+ if (err == ERR_OK)
+ {
+ uint8_t * p_payload_cp = nrf_malloc(p_pbuf->len);
+ struct pbuf * p_pbuf_cp = pbuf_alloc(PBUF_RAW, p_pbuf->len, PBUF_REF);
+
+ memcpy(p_payload_cp, p_pbuf->payload, p_pbuf->len);
+ p_pbuf_cp->payload = p_payload_cp;
+ p_pbuf_cp->len = p_pbuf->len;
+ p_pbuf_cp->tot_len = p_pbuf->tot_len;
+
+ uint32_t err_code = mbuf_write(&p_handle->mbuf, p_pbuf_cp);
+ if (err_code == NRF_SUCCESS)
+ {
+ p_socket->so_read_evt++;
+ }
+ else
+ {
+ err = ERR_MEM;
+ }
+ }
+ return err;
+}
+
+static uint32_t lwip_wait_for_state(lwip_handle_t * p_handle, tcp_state_t state)
+{
+ uint32_t err_code = NRF_SUCCESS;
+ while (err_code == NRF_SUCCESS &&
+ p_handle->tcp_state != state &&
+ p_handle->tcp_state != TCP_STATE_DISCONNECTED)
+ {
+ err_code = socket_wait();
+ }
+ if (err_code == NRF_SUCCESS && p_handle->tcp_state != state)
+ {
+ err_code = NRF_ERROR_NULL;
+ }
+ return err_code;
+}
+
+static void lwipaddr_to_sockaddr(const ip6_addr_t * p_lwip_addr, sockaddr_in6_t * p_addr_in6)
+{
+ struct in6_addr * addr = &p_addr_in6->sin6_addr;
+ addr->s6_addr[0] = p_lwip_addr->addr[0] & 0xFF;
+ addr->s6_addr[1] = (p_lwip_addr->addr[0] >> 8) & 0xFF;
+ addr->s6_addr[2] = (p_lwip_addr->addr[0] >> 16) & 0xFF;
+ addr->s6_addr[3] = (p_lwip_addr->addr[0] >> 24) & 0xFF;
+
+ addr->s6_addr[4] = p_lwip_addr->addr[1] & 0xFF;
+ addr->s6_addr[5] = (p_lwip_addr->addr[1] >> 8) & 0xFF;
+ addr->s6_addr[6] = (p_lwip_addr->addr[1] >> 16) & 0xFF;
+ addr->s6_addr[7] = (p_lwip_addr->addr[1] >> 24) & 0xFF;
+
+ addr->s6_addr[8] = p_lwip_addr->addr[2] & 0xFF;
+ addr->s6_addr[9] = (p_lwip_addr->addr[2] >> 8) & 0xFF;
+ addr->s6_addr[10] = (p_lwip_addr->addr[2] >> 16) & 0xFF;
+ addr->s6_addr[11] = (p_lwip_addr->addr[2] >> 24) & 0xFF;
+
+ addr->s6_addr[12] = p_lwip_addr->addr[3] & 0xFF;
+ addr->s6_addr[13] = (p_lwip_addr->addr[3] >> 8) & 0xFF;
+ addr->s6_addr[14] = (p_lwip_addr->addr[3] >> 16) & 0xFF;
+ addr->s6_addr[15] = (p_lwip_addr->addr[3] >> 24) & 0xFF;
+}
+
+static void sockaddr_to_lwipaddr(const sockaddr_in6_t * p_addr_in6, ip6_addr_t * p_lwip_addr)
+{
+ const struct in6_addr * addr = &p_addr_in6->sin6_addr;
+ IP6_ADDR_PART(p_lwip_addr, 0, addr->s6_addr[0], addr->s6_addr[1], addr->s6_addr[2], addr->s6_addr[3]);
+ IP6_ADDR_PART(p_lwip_addr, 1, addr->s6_addr[4], addr->s6_addr[5], addr->s6_addr[6], addr->s6_addr[7]);
+ IP6_ADDR_PART(p_lwip_addr, 2, addr->s6_addr[8], addr->s6_addr[9], addr->s6_addr[10], addr->s6_addr[11]);
+ IP6_ADDR_PART(p_lwip_addr, 3, addr->s6_addr[12], addr->s6_addr[13], addr->s6_addr[14], addr->s6_addr[15]);
+}
+
+static uint32_t lwip_transport_bind(socket_t * p_socket, const void * p_addr, socklen_t addr_len)
+{
+ VERIFY_ADDRESS_LEN(addr_len);
+ const sockaddr_in6_t * p_addr_in6 = (const sockaddr_in6_t *)p_addr;
+ lwip_handle_t * p_handle = (lwip_handle_t *)p_socket->so_ctx;
+
+ uint16_t port = HTONS(p_addr_in6->sin6_port);
+ uint32_t err_code = portdb_register(port);
+ if (err_code == NRF_SUCCESS)
+ {
+ ip6_addr_t lwip_addr;
+ sockaddr_to_lwipaddr(p_addr_in6, &lwip_addr);
+ err_t err = tcp_bind(p_handle->p_pcb, &lwip_addr, port);
+ err_code = lwip_error_convert(err);
+ }
+ return err_code;
+}
+
+static uint32_t lwip_transport_connect(socket_t * p_socket,
+ const void * p_addr,
+ socklen_t addr_len)
+{
+ VERIFY_ADDRESS_LEN(addr_len);
+
+ bool is_blocking = ((p_socket->so_flags & O_NONBLOCK) == 0);
+ lwip_handle_t * p_handle = (lwip_handle_t *)p_socket->so_ctx;
+ const sockaddr_in6_t * p_addr_in6 = (const sockaddr_in6_t *)p_addr;
+ uint16_t port = 0;
+ uint32_t err_code = portdb_alloc(&port);
+
+ SOCKET_TRACE("Binding to port %d\r\n", (int)port);
+ if (err_code == NRF_SUCCESS)
+ {
+ ip6_addr_t any_addr;
+ ip6_addr_set_any(&any_addr);
+ err_t err = tcp_bind (p_handle->p_pcb, &any_addr, port);
+ SOCKET_TRACE("Err %d from bind\r\n", (int)err);
+ err_code = lwip_error_convert(err);
+ }
+
+ if (err_code == NRF_SUCCESS)
+ {
+ ip6_addr_t remote_addr;
+ sockaddr_to_lwipaddr(p_addr_in6, &remote_addr);
+
+ p_handle->tcp_state = TCP_STATE_REQUEST_CONNECTION;
+ err_t err = tcp_connect(p_handle->p_pcb, &remote_addr, HTONS(p_addr_in6->sin6_port), lwip_connect_callback);
+ SOCKET_TRACE("Err %d from connect\r\n", (int)err);
+ err_code = lwip_error_convert(err);
+
+ if (err_code == NRF_SUCCESS && is_blocking)
+ {
+ err_code = lwip_wait_for_state(p_handle, TCP_STATE_CONNECTED);
+ }
+ }
+ if (err_code != NRF_SUCCESS)
+ {
+ SOCKET_TRACE("Error %d when connecting to socket\r\n", (int)err_code);
+ portdb_free(port);
+ }
+ else
+ {
+ SOCKET_TRACE("Successfully connected to remote host!\r\n");
+ }
+
+ return err_code;
+}
+
+static err_t lwip_send_complete(void * p_arg, struct tcp_pcb * p_pcb, u16_t len)
+{
+ lwip_handle_t * p_handle = (lwip_handle_t *)p_arg;
+ if (p_handle->tcp_state == TCP_STATE_TCP_SEND_PENDING)
+ {
+ p_handle->tcp_state = TCP_STATE_DATA_TX_IN_PROGRESS;
+ }
+ return ERR_OK;
+}
+
+static inline uint32_t lwip_check_connected(socket_t * p_socket)
+{
+ return (p_socket->so_state == STATE_CONNECTED || p_socket->so_params.so_type == SOCK_DGRAM) ?
+ NRF_SUCCESS : SOCKET_NOT_CONNECTED;
+}
+
+
+static uint32_t lwip_transport_send(socket_t * p_socket,
+ const void * p_buf,
+ uint32_t buf_len,
+ int flags,
+ const void * p_destaddr,
+ socklen_t destaddr_len)
+{
+ (void) p_destaddr;
+ (void) destaddr_len;
+
+ lwip_handle_t * p_handle = (lwip_handle_t *)p_socket->so_ctx;
+ if ((p_socket->so_flags & O_NONBLOCK) != 0 &&
+ (flags & MSG_WAITALL) == 0)
+ {
+ flags |= MSG_DONTWAIT;
+ }
+
+ uint32_t err_code = lwip_check_connected(p_socket);
+ if (err_code == NRF_SUCCESS)
+ {
+ uint32_t len = tcp_sndbuf(p_handle->p_pcb);
+ if (len >= buf_len)
+ {
+ tcp_sent(p_handle->p_pcb, lwip_send_complete);
+ p_handle->tcp_state = TCP_STATE_TCP_SEND_PENDING;
+ err_t err = tcp_write(p_handle->p_pcb, p_buf, buf_len, 1);
+ err_code = lwip_error_convert(err);
+ if (err_code == NRF_SUCCESS &&
+ (flags & MSG_DONTWAIT) == 0)
+ {
+ err_code = lwip_wait_for_state(p_handle, TCP_STATE_DATA_TX_IN_PROGRESS);
+ }
+ }
+ else
+ {
+ err_code = SOCKET_NO_MEM;
+ }
+ }
+ return err_code;
+}
+
+
+static uint32_t lwip_transport_recv(socket_t * p_socket,
+ void * p_buf,
+ uint32_t * p_buf_size,
+ int flags,
+ void * p_srcaddr,
+ socklen_t * p_srcaddr_len)
+{
+ lwip_handle_t * p_handle = (lwip_handle_t *)p_socket->so_ctx;
+ if ((p_socket->so_flags & O_NONBLOCK) != 0 &&
+ (flags & MSG_WAITALL) == 0)
+ {
+ flags |= MSG_DONTWAIT;
+ }
+ uint32_t err_code = lwip_check_connected(p_socket);
+ if (err_code == NRF_SUCCESS)
+ {
+ if (mbuf_empty(&p_handle->mbuf) == true)
+ {
+ if ((flags & MSG_DONTWAIT) != 0)
+ {
+ err_code = SOCKET_WOULD_BLOCK;
+ }
+ else
+ {
+ while ((mbuf_empty(&p_handle->mbuf) == true) && (err_code == NRF_SUCCESS))
+ {
+ err_code = socket_wait();
+ }
+ }
+ }
+ }
+
+ if (err_code == NRF_SUCCESS)
+ {
+ *p_buf_size = mbuf_read(&p_handle->mbuf, p_buf, *p_buf_size);
+ tcp_recved(p_handle->p_pcb, *p_buf_size);
+ p_socket->so_read_evt = 0;
+ }
+ return err_code;
+}
+
+static err_t lwip_accept_callback(void * p_arg, struct tcp_pcb * p_pcb, err_t err)
+{
+ lwip_handle_t * p_handle = (lwip_handle_t *)p_arg;
+ socket_t * p_socket = p_handle->p_socket;
+ if (err == ERR_OK)
+ {
+ (void) nrf_fifo_enq(&p_handle->conn_queue, p_pcb, true);
+ // TODO: Error check
+ p_socket->so_read_evt++;
+ }
+ return err;
+}
+
+static uint32_t lwip_transport_listen(socket_t * p_socket, int backlog)
+{
+ lwip_handle_t * p_handle = (lwip_handle_t *)p_socket->so_ctx;
+ uint32_t err_code = NRF_SUCCESS;
+ struct tcp_pcb * p_pcb = tcp_listen_with_backlog(p_handle->p_pcb, backlog);
+ if (p_pcb == NULL)
+ {
+ err_code = SOCKET_ADDRESS_IN_USE;
+ }
+ else
+ {
+ p_handle->p_pcb = p_pcb;
+ tcp_accept(p_handle->p_pcb, lwip_accept_callback);
+ }
+ return err_code;
+}
+
+static uint32_t lwip_transport_accept(socket_t * p_socket,
+ socket_t * p_client,
+ void * p_cliaddr,
+ socklen_t * p_cliaddr_len)
+{
+ VERIFY_ADDRESS_LEN(*p_cliaddr_len);
+ struct tcp_pcb * p_client_pcb = NULL;
+ lwip_handle_t * p_lwip_handle = (lwip_handle_t *)p_socket->so_ctx;
+ uint32_t err_code = nrf_fifo_deq(&p_lwip_handle->conn_queue,
+ (void **)&p_client_pcb,
+ (p_socket->so_flags & O_NONBLOCK) == 0);
+
+ if (err_code == NRF_SUCCESS)
+ {
+ lwip_handle_t * p_lwip_client = lwip_handle_allocate(p_client, p_client_pcb);
+ sockaddr_in6_t * p_sockaddr = (sockaddr_in6_t *)p_cliaddr;
+
+ p_client->so_ctx = p_lwip_client;
+
+ lwipaddr_to_sockaddr(&p_client_pcb->remote_ip, p_sockaddr);
+ p_sockaddr->sin6_port = p_client_pcb->remote_port;
+ p_sockaddr->sin6_len = *p_cliaddr_len;
+ p_sockaddr->sin6_family = AF_INET6;
+ p_sockaddr->sin6_flowinfo = 0;
+ p_sockaddr->sin6_scope_id = 0;
+
+ /*lint -save -e548 */
+ tcp_accepted(p_lwip_handle->p_pcb);
+ /*lint -restore */
+ }
+
+ return err_code;
+}
+
+/**
+ * @brief Transport for LwIP socket.
+ */
+socket_transport_t transport_impl =
+{
+ .open = lwip_transport_open,
+ .bind = lwip_transport_bind,
+ .connect = lwip_transport_connect,
+ .send = lwip_transport_send,
+ .recv = lwip_transport_recv,
+ .listen = lwip_transport_listen,
+ .accept = lwip_transport_accept,
+ .close = lwip_transport_close
+};
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/atomic/nrf_atomic.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/atomic/nrf_atomic.c
new file mode 100644
index 0000000..8d1609f
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/atomic/nrf_atomic.c
@@ -0,0 +1,447 @@
+/**
+ * Copyright (c) 2018 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#include "nrf_atomic.h"
+
+#ifndef NRF_ATOMIC_USE_BUILD_IN
+#if (defined(__GNUC__) && defined(WIN32))
+ #define NRF_ATOMIC_USE_BUILD_IN 1
+#else
+ #define NRF_ATOMIC_USE_BUILD_IN 0
+#endif
+#endif // NRF_ATOMIC_USE_BUILD_IN
+
+#if ((__CORTEX_M >= 0x03U) || (__CORTEX_SC >= 300U))
+#define STREX_LDREX_PRESENT
+#else
+#include "app_util_platform.h"
+#endif
+
+
+#if (NRF_ATOMIC_USE_BUILD_IN == 0) && defined(STREX_LDREX_PRESENT)
+#include "nrf_atomic_internal.h"
+#endif
+
+uint32_t nrf_atomic_u32_fetch_store(nrf_atomic_u32_t * p_data, uint32_t value)
+{
+#if NRF_ATOMIC_USE_BUILD_IN
+ return __atomic_exchange_n(p_data, value, __ATOMIC_SEQ_CST);
+
+#elif defined(STREX_LDREX_PRESENT)
+ uint32_t old_val;
+ uint32_t new_val;
+ NRF_ATOMIC_OP(mov, old_val, new_val, p_data, value);
+
+ UNUSED_PARAMETER(old_val);
+ UNUSED_PARAMETER(new_val);
+ return old_val;
+#else
+ CRITICAL_REGION_ENTER();
+ uint32_t old_val = *p_data;
+ *p_data = value;
+ CRITICAL_REGION_EXIT();
+ return old_val;
+#endif //NRF_ATOMIC_USE_BUILD_IN
+}
+
+uint32_t nrf_atomic_u32_store(nrf_atomic_u32_t * p_data, uint32_t value)
+{
+#if NRF_ATOMIC_USE_BUILD_IN
+ __atomic_store_n(p_data, value, __ATOMIC_SEQ_CST);
+ return value;
+#elif defined(STREX_LDREX_PRESENT)
+ uint32_t old_val;
+ uint32_t new_val;
+
+ NRF_ATOMIC_OP(mov, old_val, new_val, p_data, value);
+
+ UNUSED_PARAMETER(old_val);
+ UNUSED_PARAMETER(new_val);
+ return new_val;
+#else
+ CRITICAL_REGION_ENTER();
+ *p_data = value;
+ CRITICAL_REGION_EXIT();
+ return value;
+#endif //NRF_ATOMIC_USE_BUILD_IN
+}
+
+uint32_t nrf_atomic_u32_fetch_or(nrf_atomic_u32_t * p_data, uint32_t value)
+{
+#if NRF_ATOMIC_USE_BUILD_IN
+ return __atomic_fetch_or(p_data, value, __ATOMIC_SEQ_CST);
+#elif defined(STREX_LDREX_PRESENT)
+ uint32_t old_val;
+ uint32_t new_val;
+
+ NRF_ATOMIC_OP(orr, old_val, new_val, p_data, value);
+ UNUSED_PARAMETER(old_val);
+ UNUSED_PARAMETER(new_val);
+ return old_val;
+#else
+ CRITICAL_REGION_ENTER();
+ uint32_t old_val = *p_data;
+ *p_data |= value;
+ CRITICAL_REGION_EXIT();
+ return old_val;
+#endif //NRF_ATOMIC_USE_BUILD_IN
+}
+
+uint32_t nrf_atomic_u32_or(nrf_atomic_u32_t * p_data, uint32_t value)
+{
+#if NRF_ATOMIC_USE_BUILD_IN
+ return __atomic_or_fetch(p_data, value, __ATOMIC_SEQ_CST);
+#elif defined(STREX_LDREX_PRESENT)
+ uint32_t old_val;
+ uint32_t new_val;
+
+ NRF_ATOMIC_OP(orr, old_val, new_val, p_data, value);
+ UNUSED_PARAMETER(old_val);
+ UNUSED_PARAMETER(new_val);
+ return new_val;
+#else
+ CRITICAL_REGION_ENTER();
+ *p_data |= value;
+ uint32_t new_value = *p_data;
+ CRITICAL_REGION_EXIT();
+ return new_value;
+#endif //NRF_ATOMIC_USE_BUILD_IN
+}
+
+uint32_t nrf_atomic_u32_fetch_and(nrf_atomic_u32_t * p_data, uint32_t value)
+{
+#if NRF_ATOMIC_USE_BUILD_IN
+ return __atomic_fetch_and(p_data, value, __ATOMIC_SEQ_CST);
+#elif defined(STREX_LDREX_PRESENT)
+ uint32_t old_val;
+ uint32_t new_val;
+
+ NRF_ATOMIC_OP(and, old_val, new_val, p_data, value);
+ UNUSED_PARAMETER(old_val);
+ UNUSED_PARAMETER(new_val);
+ return old_val;
+#else
+ CRITICAL_REGION_ENTER();
+ uint32_t old_val = *p_data;
+ *p_data &= value;
+ CRITICAL_REGION_EXIT();
+ return old_val;
+#endif //NRF_ATOMIC_USE_BUILD_IN
+}
+
+uint32_t nrf_atomic_u32_and(nrf_atomic_u32_t * p_data, uint32_t value)
+{
+#if NRF_ATOMIC_USE_BUILD_IN
+ return __atomic_and_fetch(p_data, value, __ATOMIC_SEQ_CST);
+#elif defined(STREX_LDREX_PRESENT)
+ uint32_t old_val;
+ uint32_t new_val;
+
+ NRF_ATOMIC_OP(and, old_val, new_val, p_data, value);
+ UNUSED_PARAMETER(old_val);
+ UNUSED_PARAMETER(new_val);
+ return new_val;
+#else
+ CRITICAL_REGION_ENTER();
+ *p_data &= value;
+ uint32_t new_value = *p_data;
+ CRITICAL_REGION_EXIT();
+ return new_value;
+#endif //NRF_ATOMIC_USE_BUILD_IN
+}
+
+uint32_t nrf_atomic_u32_fetch_xor(nrf_atomic_u32_t * p_data, uint32_t value)
+{
+#if NRF_ATOMIC_USE_BUILD_IN
+ return __atomic_fetch_xor(p_data, value, __ATOMIC_SEQ_CST);
+#elif defined(STREX_LDREX_PRESENT)
+ uint32_t old_val;
+ uint32_t new_val;
+
+ NRF_ATOMIC_OP(eor, old_val, new_val, p_data, value);
+ UNUSED_PARAMETER(old_val);
+ UNUSED_PARAMETER(new_val);
+ return old_val;
+#else
+ CRITICAL_REGION_ENTER();
+ uint32_t old_val = *p_data;
+ *p_data ^= value;
+ CRITICAL_REGION_EXIT();
+ return old_val;
+#endif //NRF_ATOMIC_USE_BUILD_IN
+}
+
+uint32_t nrf_atomic_u32_xor(nrf_atomic_u32_t * p_data, uint32_t value)
+{
+#if NRF_ATOMIC_USE_BUILD_IN
+ return __atomic_xor_fetch(p_data, value, __ATOMIC_SEQ_CST);
+#elif defined(STREX_LDREX_PRESENT)
+ uint32_t old_val;
+ uint32_t new_val;
+
+ NRF_ATOMIC_OP(eor, old_val, new_val, p_data, value);
+ UNUSED_PARAMETER(old_val);
+ UNUSED_PARAMETER(new_val);
+ return new_val;
+#else
+ CRITICAL_REGION_ENTER();
+ *p_data ^= value;
+ uint32_t new_value = *p_data;
+ CRITICAL_REGION_EXIT();
+ return new_value;
+#endif //NRF_ATOMIC_USE_BUILD_IN
+}
+
+uint32_t nrf_atomic_u32_fetch_add(nrf_atomic_u32_t * p_data, uint32_t value)
+{
+#if NRF_ATOMIC_USE_BUILD_IN
+ return __atomic_fetch_add(p_data, value, __ATOMIC_SEQ_CST);
+#elif defined(STREX_LDREX_PRESENT)
+ uint32_t old_val;
+ uint32_t new_val;
+
+ NRF_ATOMIC_OP(add, old_val, new_val, p_data, value);
+ UNUSED_PARAMETER(old_val);
+ UNUSED_PARAMETER(new_val);
+ return old_val;
+#else
+ CRITICAL_REGION_ENTER();
+ uint32_t old_val = *p_data;
+ *p_data += value;
+ CRITICAL_REGION_EXIT();
+ return old_val;
+#endif //NRF_ATOMIC_USE_BUILD_IN
+}
+
+uint32_t nrf_atomic_u32_add(nrf_atomic_u32_t * p_data, uint32_t value)
+{
+#if NRF_ATOMIC_USE_BUILD_IN
+ return __atomic_add_fetch(p_data, value, __ATOMIC_SEQ_CST);
+#elif defined(STREX_LDREX_PRESENT)
+ uint32_t old_val;
+ uint32_t new_val;
+
+ NRF_ATOMIC_OP(add, old_val, new_val, p_data, value);
+ UNUSED_PARAMETER(old_val);
+ UNUSED_PARAMETER(new_val);
+ return new_val;
+#else
+ CRITICAL_REGION_ENTER();
+ *p_data += value;
+ uint32_t new_value = *p_data;
+ CRITICAL_REGION_EXIT();
+ return new_value;
+#endif //NRF_ATOMIC_USE_BUILD_IN
+}
+
+uint32_t nrf_atomic_u32_fetch_sub(nrf_atomic_u32_t * p_data, uint32_t value)
+{
+#if NRF_ATOMIC_USE_BUILD_IN
+ return __atomic_fetch_sub(p_data, value, __ATOMIC_SEQ_CST);
+#elif defined(STREX_LDREX_PRESENT)
+ uint32_t old_val;
+ uint32_t new_val;
+
+ NRF_ATOMIC_OP(sub, old_val, new_val, p_data, value);
+ UNUSED_PARAMETER(old_val);
+ UNUSED_PARAMETER(new_val);
+ return old_val;
+#else
+ CRITICAL_REGION_ENTER();
+ uint32_t old_val = *p_data;
+ *p_data -= value;
+ CRITICAL_REGION_EXIT();
+ return old_val;
+#endif //NRF_ATOMIC_USE_BUILD_IN
+}
+
+uint32_t nrf_atomic_u32_sub(nrf_atomic_u32_t * p_data, uint32_t value)
+{
+#if NRF_ATOMIC_USE_BUILD_IN
+ return __atomic_sub_fetch(p_data, value, __ATOMIC_SEQ_CST);
+#elif defined(STREX_LDREX_PRESENT)
+ uint32_t old_val;
+ uint32_t new_val;
+
+ NRF_ATOMIC_OP(sub, old_val, new_val, p_data, value);
+ UNUSED_PARAMETER(old_val);
+ UNUSED_PARAMETER(new_val);
+ return new_val;
+#else
+ CRITICAL_REGION_ENTER();
+ *p_data -= value;
+ uint32_t new_value = *p_data;
+ CRITICAL_REGION_EXIT();
+ return new_value;
+#endif //NRF_ATOMIC_USE_BUILD_IN
+}
+
+bool nrf_atomic_u32_cmp_exch(nrf_atomic_u32_t * p_data,
+ uint32_t * p_expected,
+ uint32_t desired)
+{
+#if NRF_ATOMIC_USE_BUILD_IN
+ return __atomic_compare_exchange(p_data,
+ p_expected,
+ &desired,
+ 1,
+ __ATOMIC_SEQ_CST,
+ __ATOMIC_SEQ_CST);
+#elif defined(STREX_LDREX_PRESENT)
+ return nrf_atomic_internal_cmp_exch(p_data, p_expected, desired);
+#else
+ CRITICAL_REGION_ENTER();
+ if(*p_data == *p_expected)
+ {
+ *p_data = desired;
+ return true;
+ }
+ else
+ {
+ *p_expected = *p_data;
+ return false;
+ }
+ CRITICAL_REGION_EXIT();
+#endif
+}
+
+uint32_t nrf_atomic_u32_fetch_sub_hs(nrf_atomic_u32_t * p_data, uint32_t value)
+{
+#if NRF_ATOMIC_USE_BUILD_IN
+ uint32_t expected = *p_data;
+ uint32_t new_val;
+ bool success;
+
+ do
+ {
+ if (expected >= value)
+ {
+ new_val = expected - value;
+ }
+ else
+ {
+ new_val = expected;
+ }
+ success = __atomic_compare_exchange(p_data,
+ &expected,
+ &new_val,
+ 1,
+ __ATOMIC_SEQ_CST,
+ __ATOMIC_SEQ_CST);
+ } while(!success);
+ return expected;
+#elif defined(STREX_LDREX_PRESENT)
+ uint32_t old_val;
+ uint32_t new_val;
+
+ NRF_ATOMIC_OP(sub_hs, old_val, new_val, p_data, value);
+ UNUSED_PARAMETER(old_val);
+ UNUSED_PARAMETER(new_val);
+ return old_val;
+#else
+ CRITICAL_REGION_ENTER();
+ uint32_t old_val = *p_data;
+ *p_data -= value;
+ CRITICAL_REGION_EXIT();
+ return old_val;
+#endif //NRF_ATOMIC_USE_BUILD_IN
+}
+
+uint32_t nrf_atomic_u32_sub_hs(nrf_atomic_u32_t * p_data, uint32_t value)
+{
+#if NRF_ATOMIC_USE_BUILD_IN
+ uint32_t expected = *p_data;
+ uint32_t new_val;
+ bool success;
+
+ do
+ {
+ if (expected >= value)
+ {
+ new_val = expected - value;
+ }
+ else
+ {
+ new_val = expected;
+ }
+ success = __atomic_compare_exchange(p_data,
+ &expected,
+ &new_val,
+ 1,
+ __ATOMIC_SEQ_CST,
+ __ATOMIC_SEQ_CST);
+ } while(!success);
+ return new_val;
+#elif defined(STREX_LDREX_PRESENT)
+ uint32_t old_val;
+ uint32_t new_val;
+
+ NRF_ATOMIC_OP(sub_hs, old_val, new_val, p_data, value);
+ UNUSED_PARAMETER(old_val);
+ UNUSED_PARAMETER(new_val);
+ return new_val;
+#else
+ CRITICAL_REGION_ENTER();
+ *p_data -= value;
+ uint32_t new_value = *p_data;
+ CRITICAL_REGION_EXIT();
+ return new_value;
+#endif //NRF_ATOMIC_USE_BUILD_IN
+}
+
+uint32_t nrf_atomic_flag_set_fetch(nrf_atomic_flag_t * p_data)
+{
+ return nrf_atomic_u32_fetch_or(p_data, 1);
+}
+
+uint32_t nrf_atomic_flag_set(nrf_atomic_flag_t * p_data)
+{
+ return nrf_atomic_u32_or(p_data, 1);
+}
+
+uint32_t nrf_atomic_flag_clear_fetch(nrf_atomic_flag_t * p_data)
+{
+ return nrf_atomic_u32_fetch_and(p_data, 0);
+}
+
+uint32_t nrf_atomic_flag_clear(nrf_atomic_flag_t * p_data)
+{
+ return nrf_atomic_u32_and(p_data, 0);
+}
+
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/atomic/nrf_atomic.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/atomic/nrf_atomic.h
new file mode 100644
index 0000000..6a11eee
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/atomic/nrf_atomic.h
@@ -0,0 +1,274 @@
+/**
+ * Copyright (c) 2016 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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
+ *
+ * @defgroup nrf_atomic Atomic operations API
+ * @ingroup app_common
+ * @{
+ *
+ * @brief @tagAPI52 This module implements C11 stdatomic.h simplified API.
+ At this point only Cortex-M3/M4 cores are supported (LDREX/STREX instructions).
+ * Atomic types are limited to @ref nrf_atomic_u32_t and @ref nrf_atomic_flag_t.
+ */
+
+#ifndef NRF_ATOMIC_H__
+#define NRF_ATOMIC_H__
+
+#include "sdk_common.h"
+
+/**
+ * @brief Atomic 32 bit unsigned type
+ * */
+typedef volatile uint32_t nrf_atomic_u32_t;
+
+/**
+ * @brief Atomic 1 bit flag type (technically 32 bit)
+ * */
+typedef volatile uint32_t nrf_atomic_flag_t;
+
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @brief Stores value to an atomic object
+ *
+ * @param[in] p_data Atomic memory pointer
+ * @param[in] value Value to store
+ *
+ * @return Old value stored into atomic object
+ * */
+uint32_t nrf_atomic_u32_fetch_store(nrf_atomic_u32_t * p_data, uint32_t value);
+
+/**
+ * @brief Stores value to an atomic object
+ *
+ * @param[in] p_data Atomic memory pointer
+ * @param[in] value Value to store
+ *
+ * @return New value stored into atomic object
+ * */
+uint32_t nrf_atomic_u32_store(nrf_atomic_u32_t * p_data, uint32_t value);
+
+/**
+ * @brief Logical OR operation on an atomic object
+ *
+ * @param[in] p_data Atomic memory pointer
+ * @param[in] value Value of second operand OR operation
+ *
+ * @return Old value stored into atomic object
+ * */
+uint32_t nrf_atomic_u32_fetch_or(nrf_atomic_u32_t * p_data, uint32_t value);
+
+/**
+ * @brief Logical OR operation on an atomic object
+ *
+ * @param[in] p_data Atomic memory pointer
+ * @param[in] value Value of second operand OR operation
+ *
+ * @return New value stored into atomic object
+ * */
+uint32_t nrf_atomic_u32_or(nrf_atomic_u32_t * p_data, uint32_t value);
+
+/**
+ * @brief Logical AND operation on an atomic object
+ *
+ * @param[in] p_data Atomic memory pointer
+ * @param[in] value Value of second operand AND operation
+ *
+ * @return Old value stored into atomic object
+ * */
+uint32_t nrf_atomic_u32_fetch_and(nrf_atomic_u32_t * p_data, uint32_t value);
+
+/**
+ * @brief Logical AND operation on an atomic object
+ *
+ * @param[in] p_data Atomic memory pointer
+ * @param[in] value Value of second operand AND operation
+ *
+ * @return New value stored into atomic object
+ * */
+uint32_t nrf_atomic_u32_and(nrf_atomic_u32_t * p_data, uint32_t value);
+
+/**
+ * @brief Logical XOR operation on an atomic object
+ *
+ * @param[in] p_data Atomic memory pointer
+ * @param[in] value Value of second operand XOR operation
+ *
+ * @return Old value stored into atomic object
+ * */
+uint32_t nrf_atomic_u32_fetch_xor(nrf_atomic_u32_t * p_data, uint32_t value);
+
+/**
+ * @brief Logical XOR operation on an atomic object
+ *
+ * @param[in] p_data Atomic memory pointer
+ * @param[in] value Value of second operand XOR operation
+ *
+ * @return New value stored into atomic object
+ * */
+uint32_t nrf_atomic_u32_xor(nrf_atomic_u32_t * p_data, uint32_t value);
+
+/**
+ * @brief Arithmetic ADD operation on an atomic object
+ *
+ * @param[in] p_data Atomic memory pointer
+ * @param[in] value Value of second operand ADD operation
+ *
+ * @return Old value stored into atomic object
+ * */
+uint32_t nrf_atomic_u32_fetch_add(nrf_atomic_u32_t * p_data, uint32_t value);
+
+/**
+ * @brief Arithmetic ADD operation on an atomic object
+ *
+ * @param[in] p_data Atomic memory pointer
+ * @param[in] value Value of second operand ADD operation
+ *
+ * @return New value stored into atomic object
+ * */
+uint32_t nrf_atomic_u32_add(nrf_atomic_u32_t * p_data, uint32_t value);
+
+/**
+ * @brief Arithmetic SUB operation on an atomic object
+ *
+ * @param[in] p_data Atomic memory pointer
+ * @param[in] value Value of second operand SUB operation
+ *
+ * @return Old value stored into atomic object
+ * */
+uint32_t nrf_atomic_u32_fetch_sub(nrf_atomic_u32_t * p_data, uint32_t value);
+
+/**
+ * @brief Arithmetic SUB operation on an atomic object
+ *
+ * @param[in] p_data Atomic memory pointer
+ * @param[in] value Value of second operand SUB operation
+ *
+ * @return New value stored into atomic object
+ * */
+uint32_t nrf_atomic_u32_sub(nrf_atomic_u32_t * p_data, uint32_t value);
+
+/**
+ * @brief If value at pointer is equal to expected value, changes value at pointer to desired
+ *
+ * Atomically compares the value pointed to by p_data with the value pointed to by p_expected,
+ * and if those are equal, replaces the former with desired. Otherwise, loads the actual value
+ * pointed to by p_data into *p_expected.
+ *
+ * @param p_data Atomic memory pointer to test and modify.
+ * @param p_expected Pointer to test value.
+ * @param desired Value to be stored to atomic memory.
+ *
+ * @retval true *p_data was equal to *p_expected
+ * @retval false *p_data was not equal to *p_expected
+ */
+bool nrf_atomic_u32_cmp_exch(nrf_atomic_u32_t * p_data,
+ uint32_t * p_expected,
+ uint32_t desired);
+
+/**
+ * @brief Arithmetic SUB operation on an atomic object performed if object >= value.
+ *
+ * @param[in] p_data Atomic memory pointer
+ * @param[in] value Value of second operand SUB operation
+ *
+ * @return Old value stored into atomic object
+ * */
+uint32_t nrf_atomic_u32_fetch_sub_hs(nrf_atomic_u32_t * p_data, uint32_t value);
+
+/**
+ * @brief Arithmetic SUB operation on an atomic object performed if object >= value.
+ *
+ * @param[in] p_data Atomic memory pointer
+ * @param[in] value Value of second operand SUB operation
+ *
+ * @return New value stored into atomic object
+ * */
+uint32_t nrf_atomic_u32_sub_hs(nrf_atomic_u32_t * p_data, uint32_t value);
+
+/**************************************************************************************************/
+
+/**
+ * @brief Logic one bit flag set operation on an atomic object
+ *
+ * @param[in] p_data Atomic flag memory pointer
+ *
+ * @return Old flag value
+ * */
+uint32_t nrf_atomic_flag_set_fetch(nrf_atomic_flag_t * p_data);
+
+/**
+ * @brief Logic one bit flag set operation on an atomic object
+ *
+ * @param[in] p_data Atomic flag memory pointer
+ *
+ * @return New flag value
+ * */
+uint32_t nrf_atomic_flag_set(nrf_atomic_flag_t * p_data);
+
+/**
+ * @brief Logic one bit flag clear operation on an atomic object
+ *
+ * @param[in] p_data Atomic flag memory pointer
+ *
+ * @return Old flag value
+ * */
+uint32_t nrf_atomic_flag_clear_fetch(nrf_atomic_flag_t * p_data);
+
+/**
+ * @brief Logic one bit flag clear operation on an atomic object
+ *
+ * @param[in] p_data Atomic flag memory pointer
+ *
+ * @return New flag value
+ * */
+uint32_t nrf_atomic_flag_clear(nrf_atomic_flag_t * p_data);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* NRF_ATOMIC_H__ */
+
+/** @} */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/atomic/nrf_atomic_internal.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/atomic/nrf_atomic_internal.h
new file mode 100644
index 0000000..534f1b7
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/atomic/nrf_atomic_internal.h
@@ -0,0 +1,343 @@
+/**
+ * Copyright (c) 2016 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#ifndef NRF_ATOMIC_INTERNAL_H__
+#define NRF_ATOMIC_INTERNAL_H__
+
+#include "sdk_common.h"
+#include <stdbool.h>
+#include <stdint.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ *
+ * @defgroup nrf_atomic_internal Atomic operations internals
+ * @ingroup nrf_atomic
+ * @{
+ *
+ */
+
+/* Only Cortex M cores > 3 support LDREX/STREX instructions*/
+#if ((__CORTEX_M >= 0x03U) || (__CORTEX_SC >= 300U)) == 0
+#error "Unsupported core version"
+#endif
+
+#if defined ( __CC_ARM )
+static __asm uint32_t nrf_atomic_internal_mov(nrf_atomic_u32_t * p_ptr,
+ uint32_t value,
+ uint32_t * p_new)
+{
+ /* The base standard provides for passing arguments in core registers (r0-r3) and on the stack.
+ * Registers r4 and r5 have to be saved on stack. Note that only even number of register push are
+ * allowed. This is a requirement of the Procedure Call Standard for the ARM Architecture [AAPCS].
+ * */
+ push {r4, r5}
+ mov r4, r0
+
+loop_mov
+ ldrex r0, [r4]
+ mov r5, r1
+ strex r3, r5, [r4]
+ cmp r3, #0
+ bne loop_mov
+
+ str r5, [r2]
+ pop {r4, r5}
+ bx lr
+}
+
+
+static __asm uint32_t nrf_atomic_internal_orr(nrf_atomic_u32_t * p_ptr,
+ uint32_t value,
+ uint32_t * p_new)
+{
+ push {r4, r5}
+ mov r4, r0
+
+loop_orr
+ ldrex r0, [r4]
+ orr r5, r0, r1
+ strex r3, r5, [r4]
+ cmp r3, #0
+ bne loop_orr
+
+ str r5, [r2]
+ pop {r4, r5}
+ bx lr
+}
+
+static __asm uint32_t nrf_atomic_internal_and(nrf_atomic_u32_t * p_ptr,
+ uint32_t value,
+ uint32_t * p_new)
+{
+ push {r4, r5}
+ mov r4, r0
+
+loop_and
+ ldrex r0, [r4]
+ and r5, r0, r1
+ strex r3, r5, [r4]
+ cmp r3, #0
+ bne loop_and
+
+ str r5, [r2]
+ pop {r4, r5}
+ bx lr
+}
+
+static __asm uint32_t nrf_atomic_internal_eor(nrf_atomic_u32_t * p_ptr,
+ uint32_t value,
+ uint32_t * p_new)
+{
+ push {r4, r5}
+ mov r4, r0
+
+loop_eor
+ ldrex r0, [r4]
+ eor r5, r0, r1
+ strex r3, r5, [r4]
+ cmp r3, #0
+ bne loop_eor
+
+ str r5, [r2]
+ pop {r4, r5}
+ bx lr
+}
+
+static __asm uint32_t nrf_atomic_internal_add(nrf_atomic_u32_t * p_ptr,
+ uint32_t value,
+ uint32_t * p_new)
+{
+ push {r4, r5}
+ mov r4, r0
+
+loop_add
+ ldrex r0, [r4]
+ add r5, r0, r1
+ strex r3, r5, [r4]
+ cmp r3, #0
+ bne loop_add
+
+ str r5, [r2]
+ pop {r4, r5}
+ bx lr
+}
+
+static __asm uint32_t nrf_atomic_internal_sub(nrf_atomic_u32_t * p_ptr,
+ uint32_t value,
+ uint32_t * p_new)
+{
+ push {r4, r5}
+ mov r4, r0
+
+loop_sub
+ ldrex r0, [r4]
+ sub r5, r0, r1
+ strex r3, r5, [r4]
+ cmp r3, #0
+ bne loop_sub
+
+ str r5, [r2]
+ pop {r4, r5}
+ bx lr
+}
+
+static __asm bool nrf_atomic_internal_cmp_exch(nrf_atomic_u32_t * p_data,
+ uint32_t * p_expected,
+ uint32_t value)
+{
+#define RET_REG r0
+#define P_EXPC r1
+#define VALUE r2
+#define STR_RES r3
+#define P_DATA r4
+#define EXPC_VAL r5
+#define ACT_VAL r6
+
+ push {r4-r6}
+ mov P_DATA, r0
+ mov RET_REG, #0
+
+loop_cmp_exch
+ ldrex ACT_VAL, [P_DATA]
+ ldr EXPC_VAL, [P_EXPC]
+ cmp ACT_VAL, EXPC_VAL
+ ittee eq
+ strexeq STR_RES, VALUE, [P_DATA]
+ moveq RET_REG, #1
+ strexne STR_RES, ACT_VAL, [P_DATA]
+ strne ACT_VAL, [P_EXPC]
+ cmp STR_RES, #0
+ itt ne
+ movne RET_REG, #0
+ bne loop_cmp_exch
+
+ pop {r4-r6}
+ bx lr
+
+#undef RET_REG
+#undef P_EXPC
+#undef VALUE
+#undef STR_RES
+#undef P_DATA
+#undef EXPC_VAL
+#undef ACT_VAL
+}
+
+static __asm uint32_t nrf_atomic_internal_sub_hs(nrf_atomic_u32_t * p_ptr,
+ uint32_t value,
+ uint32_t * p_new)
+{
+ push {r4, r5}
+ mov r4, r0
+
+loop_sub_ge
+ ldrex r0, [r4]
+ cmp r0, r1
+ ite hs
+ subhs r5, r0, r1
+ movlo r5, r0
+ strex r3, r5, [r4]
+ cmp r3, #0
+ bne loop_sub_ge
+
+ str r5, [r2]
+ pop {r4, r5}
+ bx lr
+}
+
+
+#define NRF_ATOMIC_OP(asm_op, old_val, new_val, ptr, value) \
+ old_val = nrf_atomic_internal_##asm_op(ptr, value, &new_val)
+
+#elif defined ( __ICCARM__ ) || defined ( __GNUC__ )
+
+/**
+ * @brief Atomic operation generic macro
+ * @param[in] asm_op operation: mov, orr, and, eor, add, sub
+ * @param[out] old_val atomic object output (uint32_t), value before operation
+ * @param[out] new_val atomic object output (uint32_t), value after operation
+ * @param[in] value atomic operation operand
+ * */
+#define NRF_ATOMIC_OP(asm_op, old_val, new_val, ptr, value) \
+{ \
+ uint32_t str_res; \
+ __ASM volatile( \
+ "1: ldrex %["#old_val"], [%["#ptr"]]\n" \
+ NRF_ATOMIC_OP_##asm_op(new_val, old_val, value) \
+ " strex %[str_res], %["#new_val"], [%["#ptr"]]\n" \
+ " teq %[str_res], #0\n" \
+ " bne.n 1b" \
+ : \
+ [old_val]"=&r" (old_val), \
+ [new_val]"=&r" (new_val), \
+ [str_res]"=&r" (str_res) \
+ : \
+ [ptr]"r" (ptr), \
+ [value]"r" (value) \
+ : "cc"); \
+ UNUSED_PARAMETER(str_res); \
+}
+
+#define NRF_ATOMIC_OP_mov(new_val, old_val, value) "mov %["#new_val"], %["#value"]\n"
+#define NRF_ATOMIC_OP_orr(new_val, old_val, value) "orr %["#new_val"], %["#old_val"], %["#value"]\n"
+#define NRF_ATOMIC_OP_and(new_val, old_val, value) "and %["#new_val"], %["#old_val"], %["#value"]\n"
+#define NRF_ATOMIC_OP_eor(new_val, old_val, value) "eor %["#new_val"], %["#old_val"], %["#value"]\n"
+#define NRF_ATOMIC_OP_add(new_val, old_val, value) "add %["#new_val"], %["#old_val"], %["#value"]\n"
+#define NRF_ATOMIC_OP_sub(new_val, old_val, value) "sub %["#new_val"], %["#old_val"], %["#value"]\n"
+#define NRF_ATOMIC_OP_sub_hs(new_val, old_val, value) \
+ "cmp %["#old_val"], %["#value"]\n " \
+ "ite hs\n" \
+ "subhs %["#new_val"], %["#old_val"], %["#value"]\n" \
+ "movlo %["#new_val"], %["#old_val"]\n"
+
+static inline bool nrf_atomic_internal_cmp_exch(nrf_atomic_u32_t * p_data,
+ uint32_t * p_expected,
+ uint32_t value)
+{
+ bool res = false;
+ uint32_t str_res = 0;
+ uint32_t act_val = 0;
+ uint32_t exp_val = 0;
+ UNUSED_VARIABLE(str_res);
+ UNUSED_VARIABLE(act_val);
+ UNUSED_VARIABLE(exp_val);
+ __ASM volatile(
+ "1: ldrex %[act_val], [%[ptr]]\n"
+ " ldr %[exp_val], [%[expc]]\n"
+ " cmp %[act_val], %[exp_val]\n"
+ " ittee eq\n"
+ " strexeq %[str_res], %[value], [%[ptr]]\n"
+ " moveq %[res], #1\n"
+ " strexne %[str_res], %[act_val], [%[ptr]]\n"
+ " strne %[act_val], [%[expc]]\n"
+ " cmp %[str_res], #0\n"
+ " itt ne\n"
+ " movne %[res], #0\n"
+ " bne.n 1b"
+ :
+ [res] "=&r" (res),
+ [exp_val] "=&r" (exp_val),
+ [act_val] "=&r" (act_val),
+ [str_res] "=&r" (str_res)
+ :
+ "0" (res),
+ "1" (exp_val),
+ "2" (act_val),
+ [expc] "r" (p_expected),
+ [ptr] "r" (p_data),
+ [value] "r" (value)
+ : "cc");
+ return res;
+}
+
+#else
+#error "Unsupported compiler"
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* NRF_ATOMIC_INTERNAL_H__ */
+
+/** @} */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/atomic/nrf_atomic_sanity_check.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/atomic/nrf_atomic_sanity_check.h
new file mode 100644
index 0000000..bbc302c
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/atomic/nrf_atomic_sanity_check.h
@@ -0,0 +1,153 @@
+/**
+ * Copyright (c) 2016 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#ifndef NRF_ATOMIC_SANITY_CHECK_H__
+#define NRF_ATOMIC_SANITY_CHECK_H__
+
+#include "nrf_atomic.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @brief Quick sanity check of nrf_atomic API
+ * */
+static inline void nrf_atomic_sanity_check(void)
+{
+#if defined(DEBUG_NRF) || defined(DEBUG_NRF_USER)
+ nrf_atomic_u32_t val;
+ nrf_atomic_u32_t flag;
+
+ /*Fetch version tests*/
+ val = 0;
+ ASSERT(nrf_atomic_u32_store_fetch(&val, 10) == 0);
+ ASSERT(nrf_atomic_u32_store_fetch(&val, 0) == 10);
+
+ val = 0;
+ ASSERT(nrf_atomic_u32_or_fetch(&val, 1 << 16) == 0);
+ ASSERT(nrf_atomic_u32_or_fetch(&val, 1 << 5) == ((1 << 16)));
+ ASSERT(nrf_atomic_u32_or_fetch(&val, 1 << 5) == ((1 << 16) | (1 << 5)));
+ ASSERT(nrf_atomic_u32_or_fetch(&val, 0) == ((1 << 16) | (1 << 5)));
+ ASSERT(nrf_atomic_u32_or_fetch(&val, 0xFFFFFFFF) == ((1 << 16) | (1 << 5)));
+ ASSERT(nrf_atomic_u32_or_fetch(&val, 0xFFFFFFFF) == (0xFFFFFFFF));
+
+ val = 0xFFFFFFFF;
+ ASSERT(nrf_atomic_u32_and_fetch(&val, ~(1 << 16)) == 0xFFFFFFFF);
+ ASSERT(nrf_atomic_u32_and_fetch(&val, ~(1 << 5)) == (0xFFFFFFFF & ~((1 << 16))));
+ ASSERT(nrf_atomic_u32_and_fetch(&val, 0) == (0xFFFFFFFF & ~(((1 << 16) | (1 << 5)))));
+ ASSERT(nrf_atomic_u32_and_fetch(&val, 0xFFFFFFFF) == (0));
+
+ val = 0;
+ ASSERT(nrf_atomic_u32_xor_fetch(&val, (1 << 16)) == 0);
+ ASSERT(nrf_atomic_u32_xor_fetch(&val, (1 << 5)) == ((1 << 16)));
+ ASSERT(nrf_atomic_u32_xor_fetch(&val, 0) == ((1 << 16) | (1 << 5)));
+ ASSERT(nrf_atomic_u32_xor_fetch(&val, (1 << 16) | (1 << 5)) == ((1 << 16) | (1 << 5)));
+ ASSERT(nrf_atomic_u32_xor_fetch(&val, 0) == (0));
+
+ val = 0;
+ ASSERT(nrf_atomic_u32_add_fetch(&val, 100) == 0);
+ ASSERT(nrf_atomic_u32_add_fetch(&val, 100) == 100);
+ ASSERT(nrf_atomic_u32_add_fetch(&val, 1 << 24) == 200);
+ ASSERT(nrf_atomic_u32_add_fetch(&val, 0) == (200 + (1 << 24)));
+ ASSERT(nrf_atomic_u32_add_fetch(&val, 0xFFFFFFFF) == (200 + (1 << 24)));
+ ASSERT(nrf_atomic_u32_add_fetch(&val, 0) == (200 - 1 + (1 << 24)));
+
+ val = 1000;
+ ASSERT(nrf_atomic_u32_sub_fetch(&val, 100) == 1000);
+ ASSERT(nrf_atomic_u32_sub_fetch(&val, 100) == 900);
+ ASSERT(nrf_atomic_u32_sub_fetch(&val, 0) == 800);
+ ASSERT(nrf_atomic_u32_sub_fetch(&val, 0xFFFFFFFF) == 800);
+ ASSERT(nrf_atomic_u32_sub_fetch(&val, 0) == 801);
+
+ flag = 0;
+ ASSERT(nrf_atomic_flag_set_fetch(&flag) == 0);
+ ASSERT(nrf_atomic_flag_set_fetch(&flag) == 1);
+ ASSERT(nrf_atomic_flag_clear_fetch(&flag) == 1);
+ ASSERT(nrf_atomic_flag_clear_fetch(&flag) == 0);
+
+ /*No fetch version tests*/
+ val = 0;
+ ASSERT(nrf_atomic_u32_store(&val, 10) == 10);
+ ASSERT(nrf_atomic_u32_store(&val, 0) == 0);
+
+ val = 0;
+ ASSERT(nrf_atomic_u32_or(&val, 1 << 16) == 1 << 16);
+ ASSERT(nrf_atomic_u32_or(&val, 1 << 5) == ((1 << 16) | (1 << 5)));
+ ASSERT(nrf_atomic_u32_or(&val, 1 << 5) == ((1 << 16) | (1 << 5)));
+ ASSERT(nrf_atomic_u32_or(&val, 0) == ((1 << 16) | (1 << 5)));
+ ASSERT(nrf_atomic_u32_or(&val, 0xFFFFFFFF) == 0xFFFFFFFF);
+
+ val = 0xFFFFFFFF;
+ ASSERT(nrf_atomic_u32_and(&val, ~(1 << 16)) == (0xFFFFFFFF & ~((1 << 16))));
+ ASSERT(nrf_atomic_u32_and(&val, ~(1 << 5)) == (0xFFFFFFFF & ~(((1 << 16) | (1 << 5)))));
+ ASSERT(nrf_atomic_u32_and(&val, 0) == 0);
+
+ val = 0;
+ ASSERT(nrf_atomic_u32_xor(&val, (1 << 16)) == ((1 << 16)));
+ ASSERT(nrf_atomic_u32_xor(&val, (1 << 5)) == ((1 << 16) | (1 << 5)));
+ ASSERT(nrf_atomic_u32_xor(&val, 0) == ((1 << 16) | (1 << 5)));
+ ASSERT(nrf_atomic_u32_xor(&val, (1 << 16) | (1 << 5)) == 0);
+
+ val = 0;
+ ASSERT(nrf_atomic_u32_add(&val, 100) == 100);
+ ASSERT(nrf_atomic_u32_add(&val, 100) == 200);
+ ASSERT(nrf_atomic_u32_add(&val, 1 << 24) == (200 + (1 << 24)));
+ ASSERT(nrf_atomic_u32_add(&val, 0) == (200 + (1 << 24)));
+ ASSERT(nrf_atomic_u32_add(&val, 0xFFFFFFFF) == (200 - 1 + (1 << 24)));
+
+ val = 1000;
+ ASSERT(nrf_atomic_u32_sub(&val, 100) == 900);
+ ASSERT(nrf_atomic_u32_sub(&val, 100) == 800);
+ ASSERT(nrf_atomic_u32_sub(&val, 0) == 800);
+ ASSERT(nrf_atomic_u32_sub(&val, 0xFFFFFFFF) == 801);
+
+ flag = 0;
+ ASSERT(nrf_atomic_flag_set(&flag) == 1);
+ ASSERT(nrf_atomic_flag_set(&flag) == 1);
+ ASSERT(nrf_atomic_flag_clear(&flag) == 0);
+ ASSERT(nrf_atomic_flag_clear(&flag) == 0);
+#endif
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* NRF_ATOMIC_SANITY_CHECK_H__ */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/atomic_fifo/nrf_atfifo.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/atomic_fifo/nrf_atfifo.c
new file mode 100644
index 0000000..5d7a8ff
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/atomic_fifo/nrf_atfifo.c
@@ -0,0 +1,189 @@
+/**
+ * Copyright (c) 2011 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+
+#include <string.h>
+#include <stdint.h>
+#include <stdbool.h>
+#include "app_util.h"
+#include "nrf_atfifo.h"
+#include "nrf_atfifo_internal.h"
+
+#if NRF_ATFIFO_CONFIG_LOG_ENABLED
+ #define NRF_LOG_LEVEL NRF_ATFIFO_CONFIG_LOG_LEVEL
+ #define NRF_LOG_INIT_FILTER_LEVEL NRF_ATFIFO_CONFIG_LOG_INIT_FILTER_LEVEL
+ #define NRF_LOG_INFO_COLOR NRF_ATFIFO_CONFIG_INFO_COLOR
+ #define NRF_LOG_DEBUG_COLOR NRF_ATFIFO_CONFIG_DEBUG_COLOR
+#else
+ #define NRF_LOG_LEVEL 0
+#endif // NRF_ATFIFO_CONFIG_LOG_ENABLED
+#include "nrf_log.h"
+
+/* Unions testing */
+STATIC_ASSERT(sizeof(nrf_atfifo_postag_t) == sizeof(uint32_t));
+
+
+ret_code_t nrf_atfifo_init(nrf_atfifo_t * const p_fifo, void * p_buf, uint16_t buf_size, uint16_t item_size)
+{
+ if (NULL == p_buf)
+ {
+ NRF_LOG_INST_ERROR(p_fifo->p_log, "Initialization failed. p_buf == NULL");
+ return NRF_ERROR_NULL;
+ }
+ if (0 != (buf_size % item_size))
+ {
+ NRF_LOG_INST_ERROR(p_fifo->p_log, "Initialization failed. Buf_size not multiple of item_size");
+ return NRF_ERROR_INVALID_LENGTH;
+ }
+
+ p_fifo->p_buf = p_buf;
+ p_fifo->tail.tag = 0;
+ p_fifo->head.tag = 0;
+ p_fifo->buf_size = buf_size;
+ p_fifo->item_size = item_size;
+
+ NRF_LOG_INST_INFO(p_fifo->p_log, "Initialized.");
+ return NRF_SUCCESS;
+}
+
+
+ret_code_t nrf_atfifo_clear(nrf_atfifo_t * const p_fifo)
+{
+ bool released = nrf_atfifo_space_clear(p_fifo);
+ NRF_LOG_INST_INFO(p_fifo->p_log, "Cleared result:%s", released ? "success" : "busy");
+ return released ? NRF_SUCCESS : NRF_ERROR_BUSY;
+}
+
+
+ret_code_t nrf_atfifo_alloc_put(nrf_atfifo_t * const p_fifo, void const * p_var, size_t size, bool * const p_visible)
+{
+ nrf_atfifo_item_put_t context;
+ bool visible;
+ void * p_data = nrf_atfifo_item_alloc(p_fifo, &context);
+ if (NULL == p_data)
+ {
+ NRF_LOG_INST_WARNING(p_fifo->p_log, "Copying in element (0x%08X) failed - no space.", p_var);
+ return NRF_ERROR_NO_MEM;
+ }
+
+ memcpy(p_data, p_var, size);
+
+ visible = nrf_atfifo_item_put(p_fifo, &context);
+ if (NULL != p_visible)
+ {
+ *p_visible = visible;
+ }
+ NRF_LOG_INST_DEBUG(p_fifo->p_log, "Element (0x%08X) copied in.", p_var);
+ return NRF_SUCCESS;
+}
+
+
+void * nrf_atfifo_item_alloc(nrf_atfifo_t * const p_fifo, nrf_atfifo_item_put_t * p_context)
+{
+ if (nrf_atfifo_wspace_req(p_fifo, &(p_context->last_tail)))
+ {
+ void * p_item = ((uint8_t*)(p_fifo->p_buf)) + p_context->last_tail.pos.wr;
+ NRF_LOG_INST_DEBUG(p_fifo->p_log, "Allocated element (0x%08X).", p_item);
+ return p_item;
+ }
+ NRF_LOG_INST_WARNING(p_fifo->p_log, "Allocation failed - no space.");
+ return NULL;
+}
+
+
+bool nrf_atfifo_item_put(nrf_atfifo_t * const p_fifo, nrf_atfifo_item_put_t * p_context)
+{
+ if ((p_context->last_tail.pos.wr) == (p_context->last_tail.pos.rd))
+ {
+ NRF_LOG_INST_DEBUG(p_fifo->p_log, "Put (uninterrupted)");
+ nrf_atfifo_wspace_close(p_fifo);
+ return true;
+ }
+ NRF_LOG_INST_DEBUG(p_fifo->p_log, "Put (interrupted!)");
+ return false;
+}
+
+
+ret_code_t nrf_atfifo_get_free(nrf_atfifo_t * const p_fifo, void * const p_var, size_t size, bool * p_released)
+{
+ nrf_atfifo_item_get_t context;
+ bool released;
+ void const * p_s = nrf_atfifo_item_get(p_fifo, &context);
+ if (NULL == p_s)
+ {
+ NRF_LOG_INST_WARNING(p_fifo->p_log, "Copying out failed - no item in the FIFO.");
+ return NRF_ERROR_NOT_FOUND;
+ }
+
+ memcpy(p_var, p_s, size);
+
+ released = nrf_atfifo_item_free(p_fifo, &context);
+ if (NULL != p_released)
+ {
+ *p_released = released;
+ }
+ NRF_LOG_INST_DEBUG(p_fifo->p_log, "Element (0x%08X) copied out.", p_var);
+ return NRF_SUCCESS;
+}
+
+
+void * nrf_atfifo_item_get(nrf_atfifo_t * const p_fifo, nrf_atfifo_item_get_t * p_context)
+{
+ if (nrf_atfifo_rspace_req(p_fifo, &(p_context->last_head)))
+ {
+ void * p_item = ((uint8_t*)(p_fifo->p_buf)) + p_context->last_head.pos.rd;
+ NRF_LOG_INST_DEBUG(p_fifo->p_log, "Get element: 0x%08X", p_item);
+ return p_item;
+ }
+ NRF_LOG_INST_WARNING(p_fifo->p_log, "Get failed - no item in the FIFO.");
+ return NULL;
+}
+
+
+bool nrf_atfifo_item_free(nrf_atfifo_t * const p_fifo, nrf_atfifo_item_get_t * p_context)
+{
+ if ((p_context->last_head.pos.wr) == (p_context->last_head.pos.rd))
+ {
+ NRF_LOG_INST_DEBUG(p_fifo->p_log, "Free (uninterrupted)");
+ nrf_atfifo_rspace_close(p_fifo);
+ return true;
+ }
+ NRF_LOG_INST_DEBUG(p_fifo->p_log, "Free (interrupted)");
+ return false;
+}
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/atomic_fifo/nrf_atfifo.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/atomic_fifo/nrf_atfifo.h
new file mode 100644
index 0000000..37cfc76
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/atomic_fifo/nrf_atfifo.h
@@ -0,0 +1,424 @@
+/**
+ * Copyright (c) 2011 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#ifndef NRF_ATFIFO_H__
+#define NRF_ATFIFO_H__
+
+#include <stdint.h>
+#include <stdbool.h>
+#include "sdk_config.h"
+#include "nordic_common.h"
+#include "nrf_assert.h"
+#include "sdk_errors.h"
+#include "nrf_log_instance.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @defgroup nrf_atfifo Atomic FIFO
+ * @ingroup app_common
+ *
+ * @brief @tagAPI52 FIFO implementation that allows for making atomic transactions without
+ * locking interrupts.
+ *
+ * @details There are two types of functions to prepare the FIFO writing:
+ * - Single function for simple access:
+ * @code
+ * if (NRF_SUCCESS != nrf_atfifo_simple_put(my_fifo, &data, NULL))
+ * {
+ * // Error handling
+ * }
+ * @endcode
+ * - Function pair to limit data copying:
+ * @code
+ * struct point3d
+ * {
+ * int x, y, z;
+ * }point3d_t;
+ * nrf_atfifo_context_t context;
+ * point3d_t * point;
+ *
+ * if (NULL != (point = nrf_atfifo_item_alloc(my_fifo, &context)))
+ * {
+ * point->x = a;
+ * point->y = b;
+ * point->z = c;
+ * if (nrf_atfifo_item_put(my_fifo, &context))
+ * {
+ * // Send information to the rest of the system
+ * // that there is new data in the FIFO available for reading.
+ * }
+ * }
+ * else
+ * {
+ * // Error handling
+ * }
+ *
+ * @endcode
+ * @note
+ * This atomic FIFO implementation requires that the operation that is
+ * opened last is finished (committed/flushed) first.
+ * This is typical for operations performed from the interrupt runtime
+ * when the other operation is performed from the main thread.
+ *
+ * This implementation does not support typical multithreading operating system
+ * access where operations can be started and finished in totally unrelated order.
+ *
+ * @{
+ */
+
+/**
+ * @brief Read and write position structure.
+ *
+ * A structure that holds the read and write position used by the FIFO head and tail.
+ */
+typedef struct nrf_atfifo_postag_pos_s
+{
+ uint16_t wr; //!< First free space to write the data
+ uint16_t rd; //!< A place after the last data to read
+}nrf_atfifo_postag_pos_t;
+
+/**
+ * @brief End data index tag.
+ *
+ * A tag used to mark the end of data.
+ * To properly realize atomic data committing, the whole variable has to be
+ * accessed atomically.
+ */
+typedef union nrf_atfifo_postag_u
+{
+ uint32_t tag; //!< Whole tag, used for atomic, 32-bit access
+ nrf_atfifo_postag_pos_t pos; //!< Structure that holds reading and writing position separately
+}nrf_atfifo_postag_t;
+
+/**
+ * @brief The FIFO instance.
+ *
+ * The instance of atomic FIFO.
+ * Used with all FIFO functions.
+ */
+typedef struct nrf_atfifo_s
+{
+ void * p_buf; //!< Pointer to the data buffer
+ nrf_atfifo_postag_t tail; //!< Read and write tail position tag
+ nrf_atfifo_postag_t head; //!< Read and write head position tag
+ uint16_t buf_size; //!< FIFO size in number of bytes (has to be divisible by @c item_size)
+ uint16_t item_size; //!< Size of a single FIFO item
+ NRF_LOG_INSTANCE_PTR_DECLARE(p_log) //!< Pointer to instance of the logger object (Conditionally compiled).
+}nrf_atfifo_t;
+
+/**
+ * @brief FIFO write operation item context.
+ *
+ * Context structure used to mark an allocated space in FIFO that is ready for put.
+ * All the data required to properly put allocated and written data.
+ */
+typedef struct nrf_atfifo_item_put_s
+{
+ nrf_atfifo_postag_t last_tail; //!< Tail tag value that was here when opening the FIFO to write
+}nrf_atfifo_item_put_t;
+
+
+/**
+ * @brief FIFO read operation item context.
+ *
+ * Context structure used to mark an opened get operation to properly free an item after reading.
+ */
+typedef struct nrf_atfifo_rcontext_s
+{
+ nrf_atfifo_postag_t last_head; //!< Head tag value that was here when opening the FIFO to read
+}nrf_atfifo_item_get_t;
+
+
+/** @brief Name of the module used for logger messaging.
+ */
+#define NRF_ATFIFO_LOG_NAME atfifo
+
+/**
+ * @defgroup nrf_atfifo_instmacros FIFO instance macros
+ *
+ * A group of macros helpful for FIFO instance creation and initialization.
+ * They may be used to create and initialize instances for most use cases.
+ *
+ * FIFO may also be created and initialized directly using
+ * @ref nrf_atfifo_init function.
+ * @{
+ */
+ /**
+ * @brief Macro for generating the name for a data buffer.
+ *
+ * The name of the data buffer that would be created by
+ * @ref NRF_ATFIFO_DEF macro.
+ *
+ * @param[in] fifo_id Identifier of the FIFO object.
+ *
+ * @return Name of the buffer variable.
+ *
+ * @note This is auxiliary internal macro and in normal usage
+ * it should not be called.
+ */
+ #define NRF_ATFIFO_BUF_NAME(fifo_id) CONCAT_2(fifo_id, _data)
+
+ /**
+ * @brief Macro for generating the name for a FIFO instance.
+ *
+ * The name of the instance variable that will be created by the
+ * @ref NRF_ATFIFO_DEF macro.
+ *
+ * @param[in] fifo_id Identifier of the FIFO object.
+ *
+ * @return Name of the instance variable.
+ *
+ * @note This is auxiliary internal macro and in normal usage
+ * it should not be called.
+ */
+ #define NRF_ATFIFO_INST_NAME(fifo_id) CONCAT_2(fifo_id, _inst)
+
+ /**
+ * @brief Macro for creating an instance.
+ *
+ * Creates the FIFO object variable itself.
+ *
+ * Usage example:
+ * @code
+ * NRF_ATFIFO_DEF(my_fifo, uint16_t, 12);
+ * NRF_ATFIFO_INIT(my_fifo);
+ *
+ * uint16_t some_val = 45;
+ * nrf_atfifo_item_put(my_fifo, &some_val, sizeof(some_val), NULL);
+ * nrf_atfifo_item_get(my_fifo, &some_val, sizeof(some_val), NULL);
+ * @endcode
+ *
+ * @param[in] fifo_id Identifier of a FIFO object.
+ * This identifier will be a pointer to the instance.
+ * It makes it possible to use this directly for the functions
+ * that operate on the FIFO.
+ * Because it is a static const object, it should be optimized by the compiler.
+ * @param[in] storage_type Type of data that will be stored in the FIFO.
+ * @param[in] item_cnt Capacity of the created FIFO in maximum number of items that may be stored.
+ * The phisical size of the buffer will be 1 element bigger.
+ */
+ #define NRF_ATFIFO_DEF(fifo_id, storage_type, item_cnt) \
+ static storage_type NRF_ATFIFO_BUF_NAME(fifo_id)[(item_cnt)+1]; \
+ NRF_LOG_INSTANCE_REGISTER(NRF_ATFIFO_LOG_NAME, fifo_id, \
+ NRF_ATFIFO_CONFIG_INFO_COLOR, \
+ NRF_ATFIFO_CONFIG_DEBUG_COLOR, \
+ NRF_ATFIFO_CONFIG_LOG_INIT_FILTER_LEVEL, \
+ NRF_ATFIFO_CONFIG_LOG_ENABLED ? \
+ NRF_ATFIFO_CONFIG_LOG_LEVEL : NRF_LOG_SEVERITY_NONE); \
+ static nrf_atfifo_t NRF_ATFIFO_INST_NAME(fifo_id) = { \
+ .p_buf = NULL, \
+ NRF_LOG_INSTANCE_PTR_INIT(p_log, NRF_ATFIFO_LOG_NAME, fifo_id) \
+ }; \
+ static nrf_atfifo_t * const fifo_id = &NRF_ATFIFO_INST_NAME(fifo_id)
+
+ /**
+ * @brief Macro for initializing the FIFO that was previously declared by the macro.
+ *
+ * Use this macro to simplify FIFO initialization.
+ *
+ * @note
+ * This macro can be only used on a FIFO object defined by @ref NRF_ATFIFO_DEF macro.
+ *
+ * @param[in] fifo_id Identifier of the FIFO object.
+ *
+ * @return Value from the @ref nrf_atfifo_init function.
+ */
+ #define NRF_ATFIFO_INIT(fifo_id) \
+ nrf_atfifo_init( \
+ fifo_id, \
+ NRF_ATFIFO_BUF_NAME(fifo_id), \
+ sizeof(NRF_ATFIFO_BUF_NAME(fifo_id)), \
+ sizeof(NRF_ATFIFO_BUF_NAME(fifo_id)[0]) \
+ )
+
+/** @} */
+
+/**
+ * @brief Function for initializing the FIFO.
+ *
+ * Preparing the FIFO instance to work.
+ *
+ * @param[out] p_fifo FIFO object to initialize.
+ * @param[in,out] p_buf FIFO buffer for storing data.
+ * @param[in] buf_size Total buffer size (has to be divisible by @c item_size).
+ * @param[in] item_size Size of a single item held inside the FIFO.
+ *
+ * @retval NRF_SUCCESS If initialization was successful.
+ * @retval NRF_ERROR_NULL If a NULL pointer is provided as the buffer.
+ * @retval NRF_ERROR_INVALID_LENGTH If size of the buffer provided is not divisible by @c item_size.
+ *
+ * @note
+ * Buffer size must be able to hold one element more than the designed FIFO capacity.
+ * This one, empty element is used for overflow checking.
+ */
+ret_code_t nrf_atfifo_init(nrf_atfifo_t * const p_fifo, void * p_buf, uint16_t buf_size, uint16_t item_size);
+
+/**
+ * @brief Function for clearing the FIFO.
+ *
+ * Function for clearing the FIFO.
+ *
+ * If this function is called during an opened and uncommitted write operation,
+ * the FIFO is cleared up to the currently ongoing commit.
+ * There is no possibility to cancel an ongoing commit.
+ *
+ * If this function is called during an opened and unflushed read operation,
+ * the read position in the head is set, but copying it into the write head position
+ * is left to read closing operation.
+ *
+ * This way, there is no more data to read, but the memory is released
+ * in the moment when it is safe.
+ *
+ * @param[in,out] p_fifo FIFO object.
+ *
+ * @retval NRF_SUCCESS FIFO totally cleared.
+ * @retval NRF_ERROR_BUSY Function called in the middle of writing or reading operation.
+ * If it is called in the middle of writing operation,
+ * FIFO was cleared up to the already started and uncommitted write.
+ * If it is called in the middle of reading operation,
+ * write head was only moved. It will be copied into read tail when the reading operation
+ * is flushed.
+ */
+ret_code_t nrf_atfifo_clear(nrf_atfifo_t * const p_fifo);
+
+/**
+ * @brief Function for atomically putting data into the FIFO.
+ *
+ * It uses memcpy function inside and in most situations, it is more suitable to
+ * use @ref nrf_atfifo_item_alloc, write the data, and @ref nrf_atfifo_item_put to store a new value
+ * in a FIFO.
+ *
+ * @param[in,out] p_fifo FIFO object.
+ * @param[in] p_var Variable to copy.
+ * @param[in] size Size of the variable to copy.
+ * Can be smaller or equal to the FIFO item size.
+ * @param[out] p_visible See value returned by @ref nrf_atfifo_item_put.
+ * It may be NULL if the caller does not require the current operation status.
+ *
+ * @retval NRF_SUCCESS If an element has been successfully added to the FIFO.
+ * @retval NRF_ERROR_NO_MEM If the FIFO is full.
+ *
+ * @note
+ * To avoid data copying, you can use the @ref nrf_atfifo_item_alloc and @ref nrf_atfifo_item_put
+ * functions pair.
+ */
+ret_code_t nrf_atfifo_alloc_put(nrf_atfifo_t * const p_fifo, void const * const p_var, size_t size, bool * const p_visible);
+
+/**
+ * @brief Function for opening the FIFO for writing.
+ *
+ * Function called to start the FIFO write operation and access the given FIFO buffer directly.
+ *
+ * @param[in,out] p_fifo FIFO object.
+ * @param[out] p_context Operation context, required by @ref nrf_atfifo_item_put.
+ *
+ * @return Pointer to the space where variable data can be stored.
+ * NULL if there is no space in the buffer.
+ */
+void * nrf_atfifo_item_alloc(nrf_atfifo_t * const p_fifo, nrf_atfifo_item_put_t * p_context);
+
+/**
+ * @brief Function for closing the writing operation.
+ *
+ * Puts a previously allocated context into FIFO.
+ * This function must be called to commit an opened write operation.
+ * It sets all the buffers and marks the data, so that it is visible to read.
+ *
+ * @param[in,out] p_fifo FIFO object.
+ * @param[in] p_context Operation context, filled by the @ref nrf_atfifo_item_alloc function.
+ *
+ * @retval true Data is currently ready and will be visible to read.
+ * @retval false The internal commit was marked, but the writing operation interrupted another writing operation.
+ * The data will be available to read when the interrupted operation is committed.
+ */
+bool nrf_atfifo_item_put(nrf_atfifo_t * const p_fifo, nrf_atfifo_item_put_t * p_context);
+
+/**
+ * @brief Function for getting a single value from the FIFO.
+ *
+ * This function gets the value from the top of the FIFO.
+ * The value is removed from the FIFO memory.
+ *
+ * @param[in,out] p_fifo FIFO object.
+ * @param[out] p_var Pointer to the variable to store the data.
+ * @param[in] size Size of the data to be loaded.
+ * @param[out] p_released See the values returned by @ref nrf_atfifo_item_free.
+ *
+ * @retval NRF_SUCCESS Element was successfully copied from the FIFO memory.
+ * @retval NRF_ERROR_NOT_FOUND No data in the FIFO.
+ */
+ret_code_t nrf_atfifo_get_free(nrf_atfifo_t * const p_fifo, void * const p_var, size_t size, bool * p_released);
+
+/**
+ * @brief Function for opening the FIFO for reading.
+ *
+ * Function called to start the FIFO read operation and access the given FIFO buffer directly.
+ *
+ * @param[in,out] p_fifo FIFO object.
+ * @param[out] p_context The operation context, required by @ref nrf_atfifo_item_free
+ *
+ * @return Pointer to data buffer or NULL if there is no data in the FIFO.
+ */
+void * nrf_atfifo_item_get(nrf_atfifo_t * const p_fifo, nrf_atfifo_item_get_t * p_context);
+
+/**
+ * @brief Function for closing the reading operation.
+ *
+ * Function used to finish the reading operation.
+ * If this reading operation does not interrupt another reading operation, the head write buffer is moved.
+ * If this reading operation is placed in the middle of another reading, only the new read pointer is written.
+ *
+ * @param[in,out] p_fifo FIFO object.
+ * @param[in] p_context Context of the reading operation to be closed.
+ *
+ * @retval true This operation is not generated in the middle of another read operation and the write head will be updated to the read head (space is released).
+ * @retval false This operation was performed in the middle of another read operation and the write buffer head was not moved (no space is released).
+ */
+bool nrf_atfifo_item_free(nrf_atfifo_t * const p_fifo, nrf_atfifo_item_get_t * p_context);
+
+
+/** @} */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* NRF_ATFIFO_H__ */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/atomic_fifo/nrf_atfifo_internal.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/atomic_fifo/nrf_atfifo_internal.h
new file mode 100644
index 0000000..e38a223
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/atomic_fifo/nrf_atfifo_internal.h
@@ -0,0 +1,577 @@
+/**
+ * Copyright (c) 2011 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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
+ * @brief Atomic FIFO internal file
+ *
+ * This file should be included only by nrf_atfifo internally.
+ * Needs nrf_atfifo.h included first.
+ */
+#ifndef NRF_ATFIFO_H__
+#error This is internal file. Do not include this file in your program.
+#endif
+
+#ifndef NRF_ATFIFO_INTERNAL_H__
+#define NRF_ATFIFO_INTERNAL_H__
+#include <stddef.h>
+#include "nrf.h"
+#include "app_util.h"
+#include "nordic_common.h"
+
+#if ((__CORTEX_M >= 0x03U) || (__CORTEX_SC >= 300U)) == 0
+#error Unsupported core version
+#endif
+
+/*
+ * Make sure that rd and wr pos in a tag are aligned like expected
+ * Changing this would require changes inside assembly code!
+ */
+STATIC_ASSERT(offsetof(nrf_atfifo_postag_pos_t, wr) == 0);
+STATIC_ASSERT(offsetof(nrf_atfifo_postag_pos_t, rd) == 2);
+
+/**
+ * @brief Atomically reserve space for a new write.
+ *
+ * @param[in,out] p_fifo FIFO object.
+ * @param[out] old_tail Tail position tag before new space is reserved.
+ *
+ * @retval true Space available.
+ * @retval false Memory full.
+ *
+ * @sa nrf_atfifo_wspace_close
+ */
+static bool nrf_atfifo_wspace_req(nrf_atfifo_t * const p_fifo, nrf_atfifo_postag_t * const p_old_tail);
+
+/**
+ * @brief Atomically mark all written data available.
+ *
+ * This function marks all data available for reading.
+ * This marking is done by copying tail.pos.wr into tail.pos.rd.
+ *
+ * It must be called only when closing the first write.
+ * It cannot be called if any write access was interrupted.
+ * See the code below:
+ * @code
+ * if (old_tail.pos.wr == old_tail.pos.rd)
+ * {
+ * nrf_atfifo_wspace_close(my_fifo);
+ * return true;
+ * }
+ * return false;
+ * @endcode
+ *
+ * @param[in,out] p_fifo FIFO object.
+ *
+ * @sa nrf_atfifo_wspace_req
+ */
+static void nrf_atfifo_wspace_close(nrf_atfifo_t * const p_fifo);
+
+/**
+ * @brief Atomically get a part of a buffer to read data.
+ *
+ * @param[in,out] p_fifo FIFO object.
+ * @param[out] old_head Head position tag before the data buffer is read.
+ *
+ * @retval true Data available for reading.
+ * @retval false No data in the buffer.
+ *
+ * @sa nrf_atfifo_rspace_close
+ */
+static bool nrf_atfifo_rspace_req(nrf_atfifo_t * const p_fifo, nrf_atfifo_postag_t * const p_old_head);
+
+/**
+ * @brief Atomically release all read data.
+ *
+ * This function marks all data that was read as free space,
+ * which is available for writing.
+ * This marking is done by copying head.pos.rd into head.pos.wr.
+ *
+ * It must be called only when closing the first read.
+ * It cannot be called when the current read access interrupted any other read access.
+ * See code below:
+ * @code
+ * if (old_head.pos.wr == old_head.pos.rd)
+ * {
+ * nrf_atfifo_rspace_close(my_fifo);
+ * return true;
+ * }
+ * return false;
+ * @endcode
+ *
+ * @param[in,out] p_fifo FIFO object.
+ *
+ * @sa nrf_atfifo_rspace_req
+ */
+static void nrf_atfifo_rspace_close(nrf_atfifo_t * const p_fifo);
+
+/**
+ * @brief Safely clear the FIFO, internal function.
+ *
+ * This function realizes the functionality required by @ref nrf_atfifo_clear.
+ *
+ * @param[in,out] p_fifo FIFO object.
+ *
+ * @retval true All the data was released.
+ * @retval false All the data available for releasing was released, but there is some pending transfer.
+ */
+static bool nrf_atfifo_space_clear(nrf_atfifo_t * const p_fifo);
+
+
+/* ---------------------------------------------------------------------------
+ * Implementation starts here
+ */
+
+#if defined ( __CC_ARM )
+
+
+__ASM bool nrf_atfifo_wspace_req(nrf_atfifo_t * const p_fifo, nrf_atfifo_postag_t * const p_old_tail)
+{
+ /* Registry usage:
+ * R0 - p_fifo
+ * R1 - p_old_tail
+ * R2 - internal variable old_tail (saved by caller)
+ * R3 - internal variable new_tail (saved by caller)
+ * R4 - internal temporary register (saved by this function)
+ * R5 - not used stored to keep the stack aligned to 8 bytes
+ * Returned value:
+ * R0 (bool - 32 bits)
+ */
+ push {r4, r5}
+nrf_atfifo_wspace_req_repeat
+ /* Load tail tag and set memory monitor !!! R2 - old tail !!! */
+ ldrex r2, [r0, #__cpp(offsetof(nrf_atfifo_t, tail))]
+ /* Extract write position !!! R3 !!! */
+ uxth r3, r2
+ /* Increment address with overload support !!! R4 used temporary !!! */
+ ldrh r4, [r0, #__cpp(offsetof(nrf_atfifo_t, item_size))]
+ add r3, r4
+ ldrh r4, [r0, #__cpp(offsetof(nrf_atfifo_t, buf_size))]
+ cmp r3, r4
+ it hs
+ subhs r3, r3, r4
+
+ /* Check if FIFO would overload after making this increment !!! R4 used temporary !!! */
+ ldrh r4, [r0, #__cpp(offsetof(nrf_atfifo_t, head) + offsetof(nrf_atfifo_postag_pos_t, wr))]
+ cmp r3, r4
+ ittt eq
+ clrexeq
+ moveq r0, #__cpp(false)
+ beq nrf_atfifo_wspace_req_exit
+
+ /* Pack everything back !!! R3 - new tail !!! */
+ /* Copy lower byte from new_tail, and higher byte is a value from the top of old_tail */
+ pkhbt r3, r3, r2
+
+ /* Store new value clearing memory monitor !!! R4 used temporary !!! */
+ strex r4, r3, [r0, #__cpp(offsetof(nrf_atfifo_t, tail))]
+ cmp r4, #0
+ bne nrf_atfifo_wspace_req_repeat
+
+ /* Return true */
+ mov r0, #__cpp(true)
+nrf_atfifo_wspace_req_exit
+ /* Save old tail */
+ str r2, [r1]
+ pop {r4, r5}
+ bx lr
+}
+
+
+__ASM void nrf_atfifo_wspace_close(nrf_atfifo_t * const p_fifo)
+{
+ /* Registry usage:
+ * R0 - p_fifo
+ * R1 - internal temporary register
+ * R2 - new_tail
+ */
+nrf_atfifo_wspace_close_repeat
+ ldrex r2, [r0, #__cpp(offsetof(nrf_atfifo_t, tail))]
+ /* Copy from lower byte to higher */
+ pkhbt r2, r2, r2, lsl #16
+
+ strex r1, r2, [r0, #__cpp(offsetof(nrf_atfifo_t, tail))]
+ cmp r1, #0
+ bne nrf_atfifo_wspace_close_repeat
+ bx lr
+}
+
+
+__ASM bool nrf_atfifo_rspace_req(nrf_atfifo_t * const p_fifo, nrf_atfifo_postag_t * const p_old_head)
+{
+ /* Registry usage:
+ * R0 - p_fifo
+ * R1 - p_old_head
+ * R2 - internal variable old_head (saved by caller)
+ * R3 - internal variable new_head (saved by caller)
+ * R4 - internal temporary register (saved by this function)
+ * R5 - not used stored to keep the stack aligned to 8 bytes
+ * Returned value:
+ * R0 (bool - 32 bits)
+ */
+ push {r4, r5}
+nrf_atfifo_rspace_req_repeat
+ /* Load tail tag and set memory monitor !!! R2 - old tail !!! */
+ ldrex r2, [r0, #__cpp(offsetof(nrf_atfifo_t, head))]
+ /* Extract read position !!! R3 !!! */
+ uxth r3, r2, ror #16
+
+ /* Check if we have any data !!! R4 used temporary !!! */
+ ldrh r4, [r0, #__cpp(offsetof(nrf_atfifo_t, tail) + offsetof(nrf_atfifo_postag_pos_t, rd))]
+ cmp r3, r4
+ ittt eq
+ clrexeq
+ moveq r0, #__cpp(false)
+ beq nrf_atfifo_rspace_req_exit
+
+ /* Increment address with overload support !!! R4 used temporary !!! */
+ ldrh r4, [r0, #__cpp(offsetof(nrf_atfifo_t, item_size))]
+ add r3, r4
+ ldrh r4, [r0, #__cpp(offsetof(nrf_atfifo_t, buf_size))]
+ cmp r3, r4
+ it hs
+ subhs r3, r3, r4
+
+ /* Pack everything back !!! R3 - new tail !!! */
+ /* Copy lower byte from old_head, and higher byte is a value from write_pos */
+ pkhbt r3, r2, r3, lsl #16
+
+ /* Store new value clearing memory monitor !!! R4 used temporary !!! */
+ strex r4, r3, [r0, #__cpp(offsetof(nrf_atfifo_t, head))]
+ cmp r4, #0
+ bne nrf_atfifo_rspace_req_repeat
+
+ /* Return true */
+ mov r0, #__cpp(true)
+nrf_atfifo_rspace_req_exit
+ /* Save old head */
+ str r2, [r1]
+ pop {r4, r5}
+ bx lr
+}
+
+
+__ASM void nrf_atfifo_rspace_close(nrf_atfifo_t * const p_fifo)
+{
+ /* Registry usage:
+ * R0 - p_fifo
+ * R1 - internal temporary register
+ * R2 - new_tail
+ */
+nrf_atfifo_rspace_close_repeat
+ ldrex r2, [r0, #__cpp(offsetof(nrf_atfifo_t, head))]
+ /* Copy from higher byte to lower */
+ pkhtb r2, r2, r2, asr #16
+
+ strex r1, r2, [r0, #__cpp(offsetof(nrf_atfifo_t, head))]
+ cmp r1, #0
+ bne nrf_atfifo_rspace_close_repeat
+ bx lr
+}
+
+
+__ASM bool nrf_atfifo_space_clear(nrf_atfifo_t * const p_fifo)
+{
+ /* Registry usage:
+ * R0 - p_fifo as input, bool output after
+ * R1 - tail, rd pointer, new_head
+ * R2 - head_old, destroyed when creating new_head
+ * R3 - p_fifo - copy
+ */
+ mov r3, r0
+nrf_atfifo_space_clear_repeat
+ /* Load old head in !!! R2 register !!! and read pointer of tail in !!! R1 register !!! */
+ ldrex r2, [r3, #__cpp(offsetof(nrf_atfifo_t, head))]
+ ldrh r1, [r3, #__cpp(offsetof(nrf_atfifo_t, tail) + offsetof(nrf_atfifo_postag_pos_t, rd))]
+ cmp r2, r2, ror #16
+ /* Return false as default */
+ mov r0, #__cpp(false)
+ /* Create new head in !!! R1 register !!! Data in !!! R2 register broken !!! */
+ itett ne
+ uxthne r2, r2
+ orreq r1, r1, r1, lsl #16
+ orrne r1, r2, r1, lsl #16
+
+ /* Skip header test */
+ bne nrf_atfifo_space_clear_head_test_skip
+
+ /* Load whole tail and test it !!! R2 used !!! */
+ ldr r2, [r3, #__cpp(offsetof(nrf_atfifo_t, tail))]
+ cmp r2, r2, ror #16
+ /* Return true if equal */
+ it eq
+ moveq r0, #__cpp(true)
+
+nrf_atfifo_space_clear_head_test_skip
+ /* Store and test if success !!! R2 used temporary !!! */
+ strex r2, r1, [r3, #__cpp(offsetof(nrf_atfifo_t, head))]
+ cmp r2, #0
+ bne nrf_atfifo_space_clear_repeat
+ bx lr
+}
+
+#elif defined ( __ICCARM__ ) || defined ( __GNUC__ )
+
+bool nrf_atfifo_wspace_req(nrf_atfifo_t * const p_fifo, nrf_atfifo_postag_t * const p_old_tail)
+{
+ volatile bool ret;
+ volatile uint32_t old_tail;
+ uint32_t new_tail;
+ uint32_t temp;
+
+ __ASM volatile(
+ /* For more comments see Keil version above */
+ "1: \n"
+ " ldrex %[old_tail], [%[p_fifo], %[offset_tail]] \n"
+ " uxth %[new_tail], %[old_tail] \n"
+ " \n"
+ " ldrh %[temp], [%[p_fifo], %[offset_item_size]] \n"
+ " add %[new_tail], %[temp] \n"
+ " ldrh %[temp], [%[p_fifo], %[offset_buf_size]] \n"
+ " cmp %[new_tail], %[temp] \n"
+ " it hs \n"
+ " subhs %[new_tail], %[new_tail], %[temp] \n"
+ " \n"
+ " ldrh %[temp], [%[p_fifo], %[offset_head_wr]] \n"
+ " cmp %[new_tail], %[temp] \n"
+ " ittt eq \n"
+ " clrexeq \n"
+ " moveq %[ret], %[false_val] \n"
+ " beq.n 2f \n"
+ " \n"
+ " pkhbt %[new_tail], %[new_tail], %[old_tail] \n"
+ " \n"
+ " strex %[temp], %[new_tail], [%[p_fifo], %[offset_tail]] \n"
+ " cmp %[temp], #0 \n"
+ " bne.n 1b \n"
+ " \n"
+ " mov %[ret], %[true_val] \n"
+ "2: \n"
+ : /* Output operands */
+ [ret] "=r"(ret),
+ [temp] "=&r"(temp),
+ [old_tail]"=&r"(old_tail),
+ [new_tail]"=&r"(new_tail)
+ : /* Input operands */
+ [p_fifo] "r"(p_fifo),
+ [offset_tail] "J"(offsetof(nrf_atfifo_t, tail)),
+ [offset_head_wr] "J"(offsetof(nrf_atfifo_t, head) + offsetof(nrf_atfifo_postag_pos_t, wr)),
+ [offset_item_size]"J"(offsetof(nrf_atfifo_t, item_size)),
+ [offset_buf_size] "J"(offsetof(nrf_atfifo_t, buf_size)),
+ [true_val] "I"(true),
+ [false_val] "I"(false)
+ : /* Clobbers */
+ "cc");
+
+ p_old_tail->tag = old_tail;
+ UNUSED_VARIABLE(new_tail);
+ UNUSED_VARIABLE(temp);
+ return ret;
+}
+
+
+void nrf_atfifo_wspace_close(nrf_atfifo_t * const p_fifo)
+{
+ uint32_t temp;
+ uint32_t new_tail;
+
+ __ASM volatile(
+ /* For more comments see Keil version above */
+ "1: \n"
+ " ldrex %[new_tail], [%[p_fifo], %[offset_tail]] \n"
+ " pkhbt %[new_tail],%[new_tail], %[new_tail], lsl #16 \n"
+ " \n"
+ " strex %[temp], %[new_tail], [%[p_fifo], %[offset_tail]] \n"
+ " cmp %[temp], #0 \n"
+ " bne.n 1b \n"
+ : /* Output operands */
+ [temp] "=&r"(temp),
+ [new_tail] "=&r"(new_tail)
+ : /* Input operands */
+ [p_fifo] "r"(p_fifo),
+ [offset_tail] "J"(offsetof(nrf_atfifo_t, tail))
+ : /* Clobbers */
+ "cc");
+
+ UNUSED_VARIABLE(temp);
+ UNUSED_VARIABLE(new_tail);
+}
+
+
+bool nrf_atfifo_rspace_req(nrf_atfifo_t * const p_fifo, nrf_atfifo_postag_t * const p_old_head)
+{
+ volatile bool ret;
+ volatile uint32_t old_head;
+ uint32_t new_head;
+ uint32_t temp;
+
+ __ASM volatile(
+ /* For more comments see Keil version above */
+ "1: \n"
+ " ldrex %[old_head], [%[p_fifo], %[offset_head]] \n"
+ " uxth %[new_head], %[old_head], ror #16 \n"
+ " \n"
+ " ldrh %[temp], [%[p_fifo], %[offset_tail_rd]] \n"
+ " cmp %[new_head], %[temp] \n"
+ " ittt eq \n"
+ " clrexeq \n"
+ " moveq %[ret], %[false_val] \n"
+ " beq.n 2f \n"
+ " \n"
+ " ldrh %[temp], [%[p_fifo], %[offset_item_size]] \n"
+ " add %[new_head], %[temp] \n"
+ " ldrh %[temp], [%[p_fifo], %[offset_buf_size]] \n"
+ " cmp %[new_head], %[temp] \n"
+ " it hs \n"
+ " subhs %[new_head], %[new_head], %[temp] \n"
+ " \n"
+ " pkhbt %[new_head], %[old_head], %[new_head], lsl #16 \n"
+ " \n"
+ " strex %[temp], %[new_head], [%[p_fifo], %[offset_head]] \n"
+ " cmp %[temp], #0 \n"
+ " bne.n 1b \n"
+ " \n"
+ " mov %[ret], %[true_val] \n"
+ "2: \n"
+ : /* Output operands */
+ [ret] "=r"(ret),
+ [temp] "=&r"(temp),
+ [old_head]"=&r"(old_head),
+ [new_head]"=&r"(new_head)
+ : /* Input operands */
+ [p_fifo] "r"(p_fifo),
+ [offset_head] "J"(offsetof(nrf_atfifo_t, head)),
+ [offset_tail_rd] "J"(offsetof(nrf_atfifo_t, tail) + offsetof(nrf_atfifo_postag_pos_t, rd)),
+ [offset_item_size]"J"(offsetof(nrf_atfifo_t, item_size)),
+ [offset_buf_size] "J"(offsetof(nrf_atfifo_t, buf_size)),
+ [true_val] "I"(true),
+ [false_val] "I"(false)
+ : /* Clobbers */
+ "cc");
+
+ p_old_head->tag = old_head;
+ UNUSED_VARIABLE(new_head);
+ UNUSED_VARIABLE(temp);
+ return ret;
+}
+
+
+void nrf_atfifo_rspace_close(nrf_atfifo_t * const p_fifo)
+{
+ uint32_t temp;
+ uint32_t new_head;
+
+ __ASM volatile(
+ /* For more comments see Keil version above */
+ "1: \n"
+ " ldrex %[new_head], [%[p_fifo], %[offset_head]] \n"
+ " pkhtb %[new_head],%[new_head], %[new_head], asr #16 \n"
+ " \n"
+ " strex %[temp], %[new_head], [%[p_fifo], %[offset_head]] \n"
+ " cmp %[temp], #0 \n"
+ " bne.n 1b \n"
+ : /* Output operands */
+ [temp] "=&r"(temp),
+ [new_head] "=&r"(new_head)
+ : /* Input operands */
+ [p_fifo] "r"(p_fifo),
+ [offset_head] "J"(offsetof(nrf_atfifo_t, head))
+ : /* Clobbers */
+ "cc");
+
+ UNUSED_VARIABLE(temp);
+ UNUSED_VARIABLE(new_head);
+}
+
+
+bool nrf_atfifo_space_clear(nrf_atfifo_t * const p_fifo)
+{
+ volatile bool ret;
+ uint32_t old_head; /* This variable is left broken after assembly code finishes */
+ uint32_t new_head;
+
+ __ASM volatile(
+ "1: \n"
+ " ldrex %[old_head], [%[p_fifo], %[offset_head]] \n"
+ " ldrh %[new_head], [%[p_fifo], %[offset_tail_rd]] \n"
+ " cmp %[old_head], %[old_head], ror #16 \n"
+ " \n"
+ " mov %[ret], %[false_val] \n"
+ " \n"
+ " itett ne \n"
+ " uxthne %[old_head], %[old_head] \n"
+ " orreq %[new_head], %[new_head], %[new_head], lsl #16 \n"
+ " orrne %[new_head], %[old_head], %[new_head], lsl #16 \n"
+ " \n"
+ " bne.n 2f \n"
+ " \n"
+ " ldr %[old_head], [%[p_fifo], %[offset_tail]] \n"
+ " cmp %[old_head], %[old_head], ror #16 \n"
+ " it eq \n"
+ " moveq %[ret], %[true_val] \n"
+ " \n"
+ "2: \n"
+ " strex %[old_head], %[new_head], [%[p_fifo], %[offset_head]] \n"
+ " cmp %[old_head], #0 \n"
+ " bne.n 1b \n"
+ : /* Output operands */
+ [ret] "=&r"(ret),
+ [old_head] "=&r"(old_head),
+ [new_head] "=&r"(new_head)
+ : /* Input operands */
+ [p_fifo] "r"(p_fifo),
+ [offset_head] "J"(offsetof(nrf_atfifo_t, head)),
+ [offset_tail] "J"(offsetof(nrf_atfifo_t, tail)),
+ [offset_tail_rd] "J"(offsetof(nrf_atfifo_t, tail) + offsetof(nrf_atfifo_postag_pos_t, rd)),
+ [true_val] "I"(true),
+ [false_val] "I"(false)
+ : /* Clobbers */
+ "cc");
+
+ UNUSED_VARIABLE(old_head);
+ UNUSED_VARIABLE(new_head);
+ return ret;
+}
+
+#else
+#error Unsupported compiler
+#endif
+
+#endif /* NRF_ATFIFO_INTERNAL_H__ */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/atomic_flags/nrf_atflags.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/atomic_flags/nrf_atflags.c
new file mode 100644
index 0000000..b1d9ce2
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/atomic_flags/nrf_atflags.c
@@ -0,0 +1,160 @@
+/**
+ * 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+
+#include "nrf.h"
+#include "nrf_atomic.h"
+#include "nrf_atflags.h"
+#include "sdk_common.h"
+
+
+
+/**@brief Macro for getting the index inside the flag array where a flag can be found.
+ *
+ * @param flag_index Index of the flag.
+ *
+ * @return Index of the @ref nrf_atflags_t the flag can be found in.
+ */
+#define FLAG_BASE(flag_index) ((flag_index) / NRF_ATFLAGS_FLAGS_PER_ELEMENT)
+
+/**@brief Macro for getting the mask representing the flag within the flag array member.
+ *
+ * @param flag_index ID of the flag.
+ *
+ * @return Mask representing the flag within a single @ref nrf_atflags_t.
+ */
+#define FLAG_MASK(flag_index) (1UL << ((flag_index) % NRF_ATFLAGS_FLAGS_PER_ELEMENT))
+
+
+void nrf_atflags_set(nrf_atflags_t * p_flags, uint32_t flag_index)
+{
+ uint32_t new_value = nrf_atomic_u32_or(&p_flags[FLAG_BASE(flag_index)], FLAG_MASK(flag_index));
+ UNUSED_RETURN_VALUE(new_value);
+}
+
+
+bool nrf_atflags_fetch_set(nrf_atflags_t * p_flags, uint32_t flag_index)
+{
+ return (nrf_atomic_u32_fetch_or(&p_flags[FLAG_BASE(flag_index)], FLAG_MASK(flag_index))
+ & FLAG_MASK(flag_index)) != 0;
+}
+
+
+void nrf_atflags_clear(nrf_atflags_t * p_flags, uint32_t flag_index)
+{
+ uint32_t new_value = nrf_atomic_u32_and(&p_flags[FLAG_BASE(flag_index)], ~FLAG_MASK(flag_index));
+ UNUSED_RETURN_VALUE(new_value);
+}
+
+
+bool nrf_atflags_fetch_clear(nrf_atflags_t * p_flags, uint32_t flag_index)
+{
+ return (nrf_atomic_u32_fetch_and(&p_flags[FLAG_BASE(flag_index)], ~FLAG_MASK(flag_index))
+ & FLAG_MASK(flag_index)) != 0;
+}
+
+
+bool nrf_atflags_get(nrf_atflags_t const * p_flags, uint32_t flag_index)
+{
+ return (p_flags[FLAG_BASE(flag_index)] & FLAG_MASK(flag_index)) != 0;
+}
+
+
+uint32_t nrf_atflags_init(nrf_atflags_t * p_flags, uint32_t flags_array_len, uint32_t flag_count)
+{
+ uint32_t required_flags_array_len = NRF_ATFLAGS_ARRAY_LEN(flag_count);
+
+ if (required_flags_array_len <= flags_array_len)
+ {
+ for (uint32_t i = 0; i < required_flags_array_len; i++)
+ {
+ p_flags[i] = 0;
+ }
+ return required_flags_array_len;
+ }
+ return 0;
+}
+
+uint32_t nrf_atflags_find_and_set_flag(nrf_atflags_t * p_flags, uint32_t flag_count)
+{
+ for (uint32_t i = 0; i < NRF_ATFLAGS_ARRAY_LEN(flag_count); i++)
+ {
+ // Using __RBIT to make the order of flags more traditional.
+ uint32_t first_zero = __CLZ(__RBIT(~p_flags[i]));
+ while (first_zero < 32)
+ {
+ uint32_t first_zero_global = first_zero + (i * 32);
+ if (first_zero_global >= flag_count)
+ {
+ break;
+ }
+ if (!nrf_atflags_fetch_set(p_flags, first_zero_global))
+ {
+ return first_zero_global;
+ }
+ first_zero = __CLZ(__RBIT(~p_flags[i]));
+ }
+ }
+
+ return flag_count;
+}
+
+uint32_t nrf_atflags_find_and_clear_flag(nrf_atflags_t * p_flags, uint32_t flag_count)
+{
+ for (uint32_t i = 0; i < NRF_ATFLAGS_ARRAY_LEN(flag_count); i++)
+ {
+ // Using __RBIT to make the order of flags more traditional.
+ uint32_t first_one = __CLZ(__RBIT(p_flags[i]));
+ while (first_one < 32)
+ {
+ uint32_t first_one_global = first_one + (i * 32);
+ if (first_one_global >= flag_count)
+ {
+ break;
+ }
+ if (nrf_atflags_fetch_clear(p_flags, first_one_global))
+ {
+ return first_one_global;
+ }
+ first_one = __CLZ(__RBIT(p_flags[i]));
+ }
+ }
+
+ return flag_count;
+}
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/atomic_flags/nrf_atflags.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/atomic_flags/nrf_atflags.h
new file mode 100644
index 0000000..79bde42
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/atomic_flags/nrf_atflags.h
@@ -0,0 +1,183 @@
+/**
+ * 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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
+ *
+ * @defgroup nrf_atflags Atomic flags (bitmaps)
+ * @ingroup app_common
+ * @{
+ *
+ * @brief @tagAPI52 This module implements atomic flags as bitmaps.
+ *
+ * Operations on the individual flags are atomic, meaning that you are always sure that the flag is
+ * set to the desired value, and you always know what value was there before. You also know that no
+ * other flags were affected by the operation.
+ *
+ * Operations on the entire flag collection are NOT atomic. This essentially means that you can't
+ * know the order in which operations on different flags happened, and you can't know the state of
+ * the entire flag collection at any instant. These limitations can be overcome by protecting
+ * operations with a mutex.
+ */
+
+#ifndef NRF_ATFLAGS_H__
+#define NRF_ATFLAGS_H__
+
+
+/**
+ * @brief Array of atomic flags.
+ * */
+typedef volatile uint32_t nrf_atflags_t;
+
+
+/**
+ * @brief Number of flags per @ref nrf_atflags_t.
+ * */
+#define NRF_ATFLAGS_FLAGS_PER_ELEMENT (sizeof(nrf_atflags_t) * 8)
+
+/**@brief Macro for the length of an array of @ref nrf_atflags_t needed to keep \p flag_count flags.
+ *
+ * @param flag_count Number of flags to keep in a flag array.
+ *
+ * @return Length of the array needed to house flag_count flags.
+ */
+#define NRF_ATFLAGS_ARRAY_LEN(flag_count) ((flag_count - 1) / NRF_ATFLAGS_FLAGS_PER_ELEMENT) + 1
+
+/**@brief Macro for declaring a flag array with the right size and initial value.
+ *
+ * @note When using this macro, no call to @ref nrf_atflags_init is necessary for this array.
+ *
+ * @param _name Name to be given to the array.
+ * @param flag_count Number of flags to be kept in the flag array.
+ *
+ * @return Flag array definition.
+ */
+#define NRF_ATFLAGS_DEF(_name, flag_count) \
+ nrf_atflags_t _name[NRF_ATFLAGS_ARRAY_LEN((flag_count))] = {0}
+
+/**@brief Macro for declaring a flag array with the right size as a member of a struct.
+ *
+ * @note When using this macro, make sure to set the array to 0 or use @ref nrf_atflags_init
+ *
+ * @param _name Name to be given to the array.
+ * @param flag_count Number of flags to be kept in the flag array.
+ *
+ * @return Flag array definition.
+ */
+#define NRF_ATFLAGS_DEF_MEMBER(_name, flag_count) \
+ nrf_atflags_t _name[NRF_ATFLAGS_ARRAY_LEN((flag_count))]
+
+
+/**@brief Function for safely initializing a flag array to 0.
+ *
+ * @param p_flags Flag array to initialize.
+ * @param flags_array_len Length of \p p_flags.
+ * @param flag_count Number of flags to be kept in the flag array.
+ *
+ * @retval 0 if the given length is not sufficient to house \p flag_count flags in the array.
+ * @return If successful: The actual length required.
+ */
+uint32_t nrf_atflags_init(nrf_atflags_t * p_flags, uint32_t flags_array_len, uint32_t flag_count);
+
+/**@brief Function for atomically setting a flag to 1.
+ *
+ * @param[in] p_flags Atomic flag array.
+ * @param[in] flag_index Index of the flag in the array.
+ */
+void nrf_atflags_set(nrf_atflags_t * p_flags, uint32_t flag_index);
+
+/**@brief Function for atomically setting a flag to 1, returning the previous value of the flag.
+ *
+ * @param[in] p_flags Atomic flag array.
+ * @param[in] flag_index Index of the flag in the array.
+ *
+ * @return Old flag value.
+ */
+bool nrf_atflags_fetch_set(nrf_atflags_t * p_flags, uint32_t flag_index);
+
+/**@brief Function for atomically setting a flag to 0.
+ *
+ * @param[in] p_flags Atomic flag array.
+ * @param[in] flag_index Index of the flag in the array.
+ */
+void nrf_atflags_clear(nrf_atflags_t * p_flags, uint32_t flag_index);
+
+/**@brief Function for atomically setting a flag to 0, returning the previous value of the flag.
+ *
+ * @param[in] p_flags Atomic flag array.
+ * @param[in] flag_index Index of the flag in the array.
+ *
+ * @return Old flag value.
+ */
+bool nrf_atflags_fetch_clear(nrf_atflags_t * p_flags, uint32_t flag_index);
+
+/**@brief Function for getting the value of a flag in a flag array.
+ *
+ * @param[in] p_flags Atomic flag array.
+ * @param[in] flag_index Index of the flag in the array.
+ *
+ * @return Flag value.
+ */
+bool nrf_atflags_get(nrf_atflags_t const * p_flags, uint32_t flag_index);
+
+/**@brief Function for finding a flag with value 0, and atomically setting it to one.
+ *
+ * @param[in] p_flags Atomic flag array.
+ * @param[in] flag_count Number of flags in the array.
+ *
+ * @return Index of the cleared flag that has been set.
+ */
+uint32_t nrf_atflags_find_and_set_flag(nrf_atflags_t * p_flags, uint32_t flag_count);
+
+/**@brief Function for finding a flag with value 1, and atomically clearing it to 0.
+ *
+ * @param[in] p_flags Atomic flag array.
+ * @param[in] flag_count The number of flags in the array.
+ *
+ * @return The index of the set flag that has been cleared.
+ */
+uint32_t nrf_atflags_find_and_clear_flag(nrf_atflags_t * p_flags, uint32_t flag_count);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* NRF_ATFLAGS_H__ */
+
+/** @} */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/balloc/nrf_balloc.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/balloc/nrf_balloc.c
new file mode 100644
index 0000000..d228f32
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/balloc/nrf_balloc.c
@@ -0,0 +1,399 @@
+/**
+ * Copyright (c) 2016 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#include "sdk_common.h"
+ #if NRF_MODULE_ENABLED(NRF_BALLOC)
+
+#include "nrf_section.h"
+#include "nrf_balloc.h"
+#include "app_util_platform.h"
+
+
+#if NRF_BALLOC_CONFIG_LOG_ENABLED
+ #define NRF_LOG_LEVEL NRF_BALLOC_CONFIG_LOG_LEVEL
+ #define NRF_LOG_INITIAL_LEVEL NRF_BALLOC_CONFIG_INITIAL_LOG_LEVEL
+ #define NRF_LOG_INFO_COLOR NRF_BALLOC_CONFIG_INFO_COLOR
+ #define NRF_LOG_DEBUG_COLOR NRF_BALLOC_CONFIG_DEBUG_COLOR
+#else
+ #define NRF_LOG_LEVEL 0
+#endif // NRF_BALLOC_CONFIG_LOG_ENABLED
+#include "nrf_log.h"
+
+#define HEAD_GUARD_FILL 0xBAADF00D /**< Magic number used to mark head guard.*/
+#define TAIL_GUARD_FILL 0xBAADCAFE /**< Magic number used to mark tail guard.*/
+#define FREE_MEM_FILL 0xBAADBAAD /**< Magic number used to mark free memory.*/
+
+#if NRF_BALLOC_CONFIG_DEBUG_ENABLED
+#define POOL_ID(_p_pool) _p_pool->p_name
+#define POOL_MARKER "%s"
+#else
+#define POOL_ID(_p_pool) _p_pool
+#define POOL_MARKER "0x%08X"
+#endif
+
+NRF_SECTION_DEF(nrf_balloc, nrf_balloc_t);
+
+#if NRF_BALLOC_CLI_CMDS
+#include "nrf_cli.h"
+
+static void nrf_balloc_status(nrf_cli_t const * p_cli, size_t argc, char **argv)
+{
+ UNUSED_PARAMETER(argv);
+
+ if (nrf_cli_help_requested(p_cli))
+ {
+ nrf_cli_help_print(p_cli, NULL, 0);
+ return;
+ }
+
+ if (argc > 1)
+ {
+ nrf_cli_fprintf(p_cli, NRF_CLI_ERROR, "Bad argument count");
+ return;
+ }
+
+ uint32_t num_of_instances = NRF_SECTION_ITEM_COUNT(nrf_balloc, nrf_balloc_t);
+ uint32_t i;
+
+ for (i = 0; i < num_of_instances; i++)
+ {
+ const nrf_balloc_t * p_instance = NRF_SECTION_ITEM_GET(nrf_balloc, nrf_balloc_t, i);
+
+ uint32_t element_size = NRF_BALLOC_ELEMENT_SIZE(p_instance);
+ uint32_t dbg_addon = p_instance->block_size - element_size;
+ uint32_t pool_size = p_instance->p_stack_limit - p_instance->p_stack_base;
+ uint32_t max_util = nrf_balloc_max_utilization_get(p_instance);
+ uint32_t util = nrf_balloc_utilization_get(p_instance);
+ const char * p_name = p_instance->p_name;
+ nrf_cli_fprintf(p_cli, NRF_CLI_NORMAL,
+ "%s\r\n\t- Element size:\t%d + %d bytes of debug information\r\n"
+ "\t- Usage:\t%u%% (%u out of %u elements)\r\n"
+ "\t- Maximum:\t%u%% (%u out of %u elements)\r\n\r\n",
+ p_name, element_size, dbg_addon,
+ 100ul * util/pool_size, util,pool_size,
+ 100ul * max_util/pool_size, max_util,pool_size);
+
+ }
+}
+// Register "balloc" command and its subcommands in CLI.
+NRF_CLI_CREATE_STATIC_SUBCMD_SET(nrf_balloc_commands)
+{
+ NRF_CLI_CMD(status, NULL, "Print status of balloc instances.", nrf_balloc_status),
+ NRF_CLI_SUBCMD_SET_END
+};
+
+NRF_CLI_CMD_REGISTER(balloc, &nrf_balloc_commands, "Commands for BALLOC management", nrf_balloc_status);
+#endif //NRF_BALLOC_CLI_CMDS
+
+#if NRF_BALLOC_CONFIG_DEBUG_ENABLED
+/**@brief Validate block memory, prepare block guards, and calculate pointer to the element.
+ *
+ * @param[in] p_pool Pointer to the memory pool.
+ * @param[in] p_head Pointer to the beginning of the block.
+ *
+ * @return Pointer to the element.
+ */
+__STATIC_INLINE void * nrf_balloc_block_unwrap(nrf_balloc_t const * p_pool, void * p_head)
+{
+ ASSERT((p_pool != NULL) && ((p_pool->block_size % sizeof(uint32_t)) == 0));
+ ASSERT((p_head != NULL) && (((uint32_t)(p_head) % sizeof(uint32_t)) == 0));
+
+ uint32_t head_words = NRF_BALLOC_DEBUG_HEAD_GUARD_WORDS_GET(p_pool->debug_flags);
+ uint32_t tail_words = NRF_BALLOC_DEBUG_TAIL_GUARD_WORDS_GET(p_pool->debug_flags);
+
+ uint32_t * p_tail = (uint32_t *)((size_t)(p_head) + p_pool->block_size);
+ uint32_t * p_element = (uint32_t *)p_head + head_words;
+
+ if (NRF_BALLOC_DEBUG_DATA_TRASHING_CHECK_GET(p_pool->debug_flags))
+ {
+ for (uint32_t * ptr = p_head; ptr < p_tail; ptr++)
+ {
+ if (*ptr != FREE_MEM_FILL)
+ {
+ NRF_LOG_INST_ERROR(p_pool->p_log,
+ "Detected free memory corruption at 0x%08X (0x%08X != 0x%08X)",
+ ptr, *ptr, FREE_MEM_FILL);
+ APP_ERROR_CHECK_BOOL(false);
+ }
+ }
+ }
+
+ for (uint32_t * ptr = p_head; ptr < p_element; ptr++)
+ {
+ *ptr = HEAD_GUARD_FILL;
+ }
+
+ for (uint32_t * ptr = ( p_tail - tail_words); ptr < p_tail; ptr++)
+ {
+ *ptr = TAIL_GUARD_FILL;
+ }
+
+ return p_element;
+}
+
+/**@brief Calculate pointer to the block, validate block guards, and mark block memory as free.
+ *
+ * @param[in] p_pool Pointer to the memory pool.
+ * @param[in] p_element Pointer to the element.
+ *
+ * @return Pointer to the beginning of the block.
+ */
+__STATIC_INLINE void * nrf_balloc_element_wrap(nrf_balloc_t const * p_pool, void * p_element)
+{
+ ASSERT((p_pool != NULL) && ((p_pool->block_size % sizeof(uint32_t)) == 0));
+ ASSERT((p_element != NULL) && (((uint32_t)(p_element) % sizeof(uint32_t)) == 0));
+
+ uint32_t head_words = NRF_BALLOC_DEBUG_HEAD_GUARD_WORDS_GET(p_pool->debug_flags);
+ uint32_t tail_words = NRF_BALLOC_DEBUG_TAIL_GUARD_WORDS_GET(p_pool->debug_flags);
+
+ uint32_t * p_head = (uint32_t *)p_element - head_words;
+ uint32_t * p_tail = (uint32_t *)((size_t)(p_head) + p_pool->block_size);
+
+ for (uint32_t * ptr = p_head; ptr < (uint32_t *)p_element; ptr++)
+ {
+ if (*ptr != HEAD_GUARD_FILL)
+ {
+ NRF_LOG_INST_ERROR(p_pool->p_log,
+ "Detected Head Guard corruption at 0x%08X (0x%08X != 0x%08X)",
+ ptr, *ptr, HEAD_GUARD_FILL);
+ APP_ERROR_CHECK_BOOL(false);
+ }
+ }
+
+ for (uint32_t * ptr = ( p_tail - tail_words); ptr < p_tail; ptr++)
+ {
+ if (*ptr != TAIL_GUARD_FILL)
+ {
+ NRF_LOG_INST_ERROR(p_pool->p_log,
+ "Detected Tail Guard corruption at 0x%08X (0x%08X != 0x%08X)",
+ ptr, *ptr, TAIL_GUARD_FILL);
+ APP_ERROR_CHECK_BOOL(false);
+ }
+ }
+
+ if (NRF_BALLOC_DEBUG_DATA_TRASHING_CHECK_GET(p_pool->debug_flags))
+ {
+ for (uint32_t * ptr = p_head; ptr < p_tail; ptr++)
+ {
+ *ptr = FREE_MEM_FILL;
+ }
+ }
+
+ return p_head;
+}
+
+#endif // NRF_BALLOC_CONFIG_DEBUG_ENABLED
+
+/**@brief Convert block index to a pointer.
+ *
+ * @param[in] p_pool Pointer to the memory pool.
+ * @param[in] idx Index of the block.
+ *
+ * @return Pointer to the beginning of the block.
+ */
+static void * nrf_balloc_idx2block(nrf_balloc_t const * p_pool, uint8_t idx)
+{
+ ASSERT(p_pool != NULL);
+ return (uint8_t *)(p_pool->p_memory_begin) + ((size_t)(idx) * p_pool->block_size);
+}
+
+/**@brief Convert block pointer to index.
+ *
+ * @param[in] p_pool Pointer to the memory pool.
+ * @param[in] p_block Pointer to the beginning of the block.
+ *
+ * @return Index of the block.
+ */
+static uint8_t nrf_balloc_block2idx(nrf_balloc_t const * p_pool, void const * p_block)
+{
+ ASSERT(p_pool != NULL);
+ return ((size_t)(p_block) - (size_t)(p_pool->p_memory_begin)) / p_pool->block_size;
+}
+
+ret_code_t nrf_balloc_init(nrf_balloc_t const * p_pool)
+{
+ uint8_t pool_size;
+
+ VERIFY_PARAM_NOT_NULL(p_pool);
+
+ ASSERT(p_pool->p_cb);
+ ASSERT(p_pool->p_stack_base);
+ ASSERT(p_pool->p_stack_limit);
+ ASSERT(p_pool->p_memory_begin);
+ ASSERT(p_pool->block_size);
+
+ pool_size = p_pool->p_stack_limit - p_pool->p_stack_base;
+
+#if NRF_BALLOC_CONFIG_DEBUG_ENABLED
+ void *p_memory_end = (uint8_t *)(p_pool->p_memory_begin) + (pool_size * p_pool->block_size);
+ if (NRF_BALLOC_DEBUG_DATA_TRASHING_CHECK_GET(p_pool->debug_flags))
+ {
+ for (uint32_t * ptr = p_pool->p_memory_begin; ptr < (uint32_t *)(p_memory_end); ptr++)
+ {
+ *ptr = FREE_MEM_FILL;
+ }
+ }
+#endif
+
+ NRF_LOG_INST_INFO(p_pool->p_log, "Initialized (size: %u x %u = %u bytes)",
+ pool_size,
+ p_pool->block_size,
+ pool_size * p_pool->block_size);
+
+ p_pool->p_cb->p_stack_pointer = p_pool->p_stack_base;
+ while (pool_size--)
+ {
+ *(p_pool->p_cb->p_stack_pointer)++ = pool_size;
+ }
+
+ p_pool->p_cb->max_utilization = 0;
+
+ return NRF_SUCCESS;
+}
+
+void * nrf_balloc_alloc(nrf_balloc_t const * p_pool)
+{
+ ASSERT(p_pool != NULL);
+
+ void * p_block = NULL;
+
+ CRITICAL_REGION_ENTER();
+
+ if (p_pool->p_cb->p_stack_pointer > p_pool->p_stack_base)
+ {
+ // Allocate block.
+ p_block = nrf_balloc_idx2block(p_pool, *--(p_pool->p_cb->p_stack_pointer));
+
+ // Update utilization statistics.
+ uint8_t utilization = p_pool->p_stack_limit - p_pool->p_cb->p_stack_pointer;
+ if (p_pool->p_cb->max_utilization < utilization)
+ {
+ p_pool->p_cb->max_utilization = utilization;
+ }
+ }
+
+ CRITICAL_REGION_EXIT();
+
+#if NRF_BALLOC_CONFIG_DEBUG_ENABLED
+ if (p_block != NULL)
+ {
+ p_block = nrf_balloc_block_unwrap(p_pool, p_block);
+ }
+#endif
+
+ NRF_LOG_INST_DEBUG(p_pool->p_log, "Allocating element: 0x%08X", p_block);
+
+ return p_block;
+}
+
+void nrf_balloc_free(nrf_balloc_t const * p_pool, void * p_element)
+{
+ ASSERT(p_pool != NULL);
+ ASSERT(p_element != NULL)
+
+ NRF_LOG_INST_DEBUG(p_pool->p_log, "Freeing element: 0x%08X", p_element);
+
+#if NRF_BALLOC_CONFIG_DEBUG_ENABLED
+ void * p_block = nrf_balloc_element_wrap(p_pool, p_element);
+
+ // These checks could be done outside critical region as they use only pool configuration data.
+ if (NRF_BALLOC_DEBUG_BASIC_CHECKS_GET(p_pool->debug_flags))
+ {
+ uint8_t pool_size = p_pool->p_stack_limit - p_pool->p_stack_base;
+ void *p_memory_end = (uint8_t *)(p_pool->p_memory_begin) + (pool_size * p_pool->block_size);
+
+ // Check if the element belongs to this pool.
+ if ((p_block < p_pool->p_memory_begin) || (p_block >= p_memory_end))
+ {
+ NRF_LOG_INST_ERROR(p_pool->p_log,
+ "Attempted to free element (0x%08X) that does not belong to the pool.",
+ p_element);
+ APP_ERROR_CHECK_BOOL(false);
+ }
+
+ // Check if the pointer is valid.
+ if ((((size_t)(p_block) - (size_t)(p_pool->p_memory_begin)) % p_pool->block_size) != 0)
+ {
+ NRF_LOG_INST_ERROR(p_pool->p_log,
+ "Attempted to free corrupted element address (0x%08X).", p_element);
+ APP_ERROR_CHECK_BOOL(false);
+ }
+ }
+#else
+ void * p_block = p_element;
+#endif // NRF_BALLOC_CONFIG_DEBUG_ENABLED
+
+ CRITICAL_REGION_ENTER();
+
+#if NRF_BALLOC_CONFIG_DEBUG_ENABLED
+ // These checks have to be done in critical region as they use p_pool->p_stack_pointer.
+ if (NRF_BALLOC_DEBUG_BASIC_CHECKS_GET(p_pool->debug_flags))
+ {
+ // Check for allocated/free ballance.
+ if (p_pool->p_cb->p_stack_pointer >= p_pool->p_stack_limit)
+ {
+ NRF_LOG_INST_ERROR(p_pool->p_log,
+ "Attempted to free an element (0x%08X) while the pool is full.",
+ p_element);
+ APP_ERROR_CHECK_BOOL(false);
+ }
+ }
+
+ if (NRF_BALLOC_DEBUG_DOUBLE_FREE_CHECK_GET(p_pool->debug_flags))
+ {
+ // Check for double free.
+ for (uint8_t * p_idx = p_pool->p_stack_base; p_idx < p_pool->p_cb->p_stack_pointer; p_idx++)
+ {
+ if (nrf_balloc_idx2block(p_pool, *p_idx) == p_block)
+ {
+ NRF_LOG_INST_ERROR(p_pool->p_log, "Attempted to double-free an element (0x%08X).",
+ p_element);
+ APP_ERROR_CHECK_BOOL(false);
+ }
+ }
+ }
+#endif // NRF_BALLOC_CONFIG_DEBUG_ENABLED
+
+ // Free the element.
+ *(p_pool->p_cb->p_stack_pointer)++ = nrf_balloc_block2idx(p_pool, p_block);
+
+ CRITICAL_REGION_EXIT();
+}
+
+#endif // NRF_MODULE_ENABLED(NRF_BALLOC)
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/balloc/nrf_balloc.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/balloc/nrf_balloc.h
new file mode 100644
index 0000000..0f781a6
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/balloc/nrf_balloc.h
@@ -0,0 +1,351 @@
+/**
+ * Copyright (c) 2016 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+/**
+ * @defgroup nrf_balloc Block memory allocator
+ * @{
+ * @ingroup app_common
+ * @brief This module handles block memory allocator features.
+ */
+
+
+#ifndef NRF_BALLOC_H__
+#define NRF_BALLOC_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "sdk_errors.h"
+#include "sdk_config.h"
+#include "app_util_platform.h"
+#include "app_util.h"
+#include "nrf_log_instance.h"
+#include "nrf_section.h"
+
+/** @brief Name of the module used for logger messaging.
+ */
+#define NRF_BALLOC_LOG_NAME balloc
+
+#if NRF_BALLOC_CONFIG_DEBUG_ENABLED || NRF_BALLOC_CLI_CMDS
+#define NRF_BALLOC_HAS_NAME 1
+#else
+#define NRF_BALLOC_HAS_NAME 0
+#endif
+
+/**@defgroup NRF_BALLOC_DEBUG Macros for preparing debug flags for block allocator module.
+ * @{ */
+#define NRF_BALLOC_DEBUG_HEAD_GUARD_WORDS_SET(words) (((words) & 0xFF) << 0)
+#define NRF_BALLOC_DEBUG_HEAD_GUARD_WORDS_GET(flags) (((flags) >> 0) & 0xFF)
+#define NRF_BALLOC_DEBUG_TAIL_GUARD_WORDS_SET(words) (((words) & 0xFF) << 8)
+#define NRF_BALLOC_DEBUG_TAIL_GUARD_WORDS_GET(flags) (((flags) >> 8) & 0xFF)
+
+#define NRF_BALLOC_DEBUG_BASIC_CHECKS_SET(enable) (!!(enable) << 16)
+#define NRF_BALLOC_DEBUG_BASIC_CHECKS_GET(flags) (flags & (1 << 16))
+#define NRF_BALLOC_DEBUG_DOUBLE_FREE_CHECK_SET(enable) (!!(enable) << 17)
+#define NRF_BALLOC_DEBUG_DOUBLE_FREE_CHECK_GET(flags) (flags & (1 << 17))
+#define NRF_BALLOC_DEBUG_DATA_TRASHING_CHECK_SET(enable) (!!(enable) << 18)
+#define NRF_BALLOC_DEBUG_DATA_TRASHING_CHECK_GET(flags) (flags & (1 << 18))
+/**@} */
+
+/**@brief Default debug flags for @ref nrf_balloc. This is used by the @ref NRF_BALLOC_DEF macro.
+ * Flags can be changed in @ref sdk_config.
+ */
+#if NRF_BALLOC_CONFIG_DEBUG_ENABLED
+ #define NRF_BALLOC_DEFAULT_DEBUG_FLAGS \
+ ( \
+ NRF_BALLOC_DEBUG_HEAD_GUARD_WORDS_SET(NRF_BALLOC_CONFIG_HEAD_GUARD_WORDS) | \
+ NRF_BALLOC_DEBUG_TAIL_GUARD_WORDS_SET(NRF_BALLOC_CONFIG_TAIL_GUARD_WORDS) | \
+ NRF_BALLOC_DEBUG_BASIC_CHECKS_SET(NRF_BALLOC_CONFIG_BASIC_CHECKS_ENABLED) | \
+ NRF_BALLOC_DEBUG_DOUBLE_FREE_CHECK_SET(NRF_BALLOC_CONFIG_DOUBLE_FREE_CHECK_ENABLED) | \
+ NRF_BALLOC_DEBUG_DATA_TRASHING_CHECK_SET(NRF_BALLOC_CONFIG_DATA_TRASHING_CHECK_ENABLED) \
+ )
+#else
+ #define NRF_BALLOC_DEFAULT_DEBUG_FLAGS 0
+#endif // NRF_BALLOC_CONFIG_DEBUG_ENABLED
+
+/**@brief Block memory allocator control block.*/
+typedef struct
+{
+ uint8_t * p_stack_pointer; //!< Current allocation stack pointer.
+ uint8_t max_utilization; //!< Maximum utilization of the memory pool.
+} nrf_balloc_cb_t;
+
+/**@brief Block memory allocator pool instance. The pool is made of elements of the same size. */
+typedef struct
+{
+ nrf_balloc_cb_t * p_cb; //!< Pointer to the instance control block.
+ uint8_t * p_stack_base; //!< Base of the allocation stack.
+ /**<
+ * Stack is used to store handlers to not allocated elements.
+ */
+ uint8_t * p_stack_limit; //!< Maximum possible value of the allocation stack pointer.
+ void * p_memory_begin; //!< Pointer to the start of the memory pool.
+ /**<
+ * Memory is used as a heap for blocks.
+ */
+ NRF_LOG_INSTANCE_PTR_DECLARE(p_log) //!< Pointer to instance of the logger object (Conditionally compiled).
+#if NRF_BALLOC_HAS_NAME
+ const char * p_name; //!< Pointer to string with pool name.
+#endif
+#if NRF_BALLOC_CONFIG_DEBUG_ENABLED
+ uint32_t debug_flags; //!< Debugging settings.
+ /**<
+ * Debug flag should be created by @ref NRF_BALLOC_DEBUG.
+ */
+#endif // NRF_BALLOC_CONFIG_DEBUG_ENABLED
+ uint16_t block_size; //!< Size of the allocated block (including debug overhead).
+ /**<
+ * Single block contains user element with header and tail
+ * words.
+ */
+} nrf_balloc_t;
+
+/**@brief Get total memory consumed by single block (element size with overhead caused by debug
+ * flags).
+ *
+ * @param[in] _element_size Size of an element.
+ * @param[in] _debug_flags Debug flags.
+ */
+#if NRF_BALLOC_CONFIG_DEBUG_ENABLED
+ #define NRF_BALLOC_BLOCK_SIZE(_element_size, _debug_flags) \
+ ( \
+ (sizeof(uint32_t) * NRF_BALLOC_DEBUG_HEAD_GUARD_WORDS_GET(_debug_flags)) + \
+ ALIGN_NUM(sizeof(uint32_t), (_element_size)) + \
+ (sizeof(uint32_t) * NRF_BALLOC_DEBUG_TAIL_GUARD_WORDS_GET(_debug_flags)) \
+ )
+#else
+ #define NRF_BALLOC_BLOCK_SIZE(_element_size, _debug_flags) \
+ ALIGN_NUM(sizeof(uint32_t), (_element_size))
+#endif // NRF_BALLOC_CONFIG_DEBUG_ENABLED
+
+
+/**@brief Get element size ( excluding debugging overhead is present)
+ * flags).
+ *
+ * @param[in] _p_balloc Pointer to balloc instance.
+ */
+#if NRF_BALLOC_CONFIG_DEBUG_ENABLED
+#define NRF_BALLOC_ELEMENT_SIZE(_p_balloc) \
+ (ALIGN_NUM(sizeof(uint32_t), (_p_balloc)->block_size) - \
+ ((sizeof(uint32_t) * NRF_BALLOC_DEBUG_HEAD_GUARD_WORDS_GET((_p_balloc)->debug_flags)) + \
+ (sizeof(uint32_t) * NRF_BALLOC_DEBUG_TAIL_GUARD_WORDS_GET((_p_balloc)->debug_flags))))
+#else
+#define NRF_BALLOC_ELEMENT_SIZE(_p_balloc) \
+ (_p_balloc)->block_size
+#endif // NRF_BALLOC_CONFIG_DEBUG_ENABLED
+
+#if NRF_BALLOC_CONFIG_DEBUG_ENABLED
+#define __NRF_BALLOC_ASSIGN_DEBUG_FLAGS(_debug_flags) .debug_flags = (_debug_flags),
+#else
+#define __NRF_BALLOC_ASSIGN_DEBUG_FLAGS(_debug_flags)
+#endif
+
+#if NRF_BALLOC_HAS_NAME
+#define __NRF_BALLOC_ASSIGN_POOL_NAME(_name) .p_name = STRINGIFY(_name),
+#else
+#define __NRF_BALLOC_ASSIGN_POOL_NAME(_name)
+#endif
+
+
+/**@brief Create a block allocator instance with custom debug flags.
+ *
+ * @note This macro reserves memory for the given block allocator instance.
+ *
+ * @param[in] _name Name of the allocator.
+ * @param[in] _element_size Size of one element.
+ * @param[in] _pool_size Size of the pool.
+ * @param[in] _debug_flags Debug flags (@ref NRF_BALLOC_DEBUG).
+ */
+#define NRF_BALLOC_DBG_DEF(_name, _element_size, _pool_size, _debug_flags) \
+ STATIC_ASSERT((_pool_size) <= UINT8_MAX); \
+ static uint8_t CONCAT_2(_name, _nrf_balloc_pool_stack)[(_pool_size)]; \
+ static uint32_t CONCAT_2(_name,_nrf_balloc_pool_mem) \
+ [NRF_BALLOC_BLOCK_SIZE(_element_size, _debug_flags) * (_pool_size) / sizeof(uint32_t)]; \
+ static nrf_balloc_cb_t CONCAT_2(_name,_nrf_balloc_cb); \
+ NRF_LOG_INSTANCE_REGISTER(NRF_BALLOC_LOG_NAME, _name, \
+ NRF_BALLOC_CONFIG_INFO_COLOR, \
+ NRF_BALLOC_CONFIG_DEBUG_COLOR, \
+ NRF_BALLOC_CONFIG_INITIAL_LOG_LEVEL, \
+ NRF_BALLOC_CONFIG_LOG_ENABLED ? \
+ NRF_BALLOC_CONFIG_LOG_LEVEL : NRF_LOG_SEVERITY_NONE); \
+ NRF_SECTION_ITEM_REGISTER(nrf_balloc, const nrf_balloc_t _name) = \
+ { \
+ .p_cb = &CONCAT_2(_name,_nrf_balloc_cb), \
+ .p_stack_base = CONCAT_2(_name,_nrf_balloc_pool_stack), \
+ .p_stack_limit = CONCAT_2(_name,_nrf_balloc_pool_stack) + (_pool_size), \
+ .p_memory_begin = CONCAT_2(_name,_nrf_balloc_pool_mem), \
+ .block_size = NRF_BALLOC_BLOCK_SIZE(_element_size, _debug_flags), \
+ \
+ NRF_LOG_INSTANCE_PTR_INIT(p_log, NRF_BALLOC_LOG_NAME, _name) \
+ __NRF_BALLOC_ASSIGN_POOL_NAME(_name) \
+ __NRF_BALLOC_ASSIGN_DEBUG_FLAGS(_debug_flags) \
+ }
+
+/**@brief Create a block allocator instance.
+ *
+ * @note This macro reserves memory for the given block allocator instance.
+ *
+ * @param[in] _name Name of the allocator.
+ * @param[in] _element_size Size of one element.
+ * @param[in] _pool_size Size of the pool.
+ */
+#define NRF_BALLOC_DEF(_name, _element_size, _pool_size) \
+ NRF_BALLOC_DBG_DEF(_name, _element_size, _pool_size, NRF_BALLOC_DEFAULT_DEBUG_FLAGS)
+
+/**@brief Create a block allocator interface.
+ *
+ * @param[in] _type Type which is allocated.
+ * @param[in] _name Name of the allocator.
+ */
+#define NRF_BALLOC_INTERFACE_DEC(_type, _name) \
+ _type * CONCAT_2(_name,_alloc)(void); \
+ void CONCAT_2(_name,_free)(_type * p_element)
+
+/**@brief Define a custom block allocator interface.
+ *
+ * @param[in] _attr Function attribute that will be added to allocator function definition.
+ * @param[in] _type Type which is allocated.
+ * @param[in] _name Name of the allocator.
+ * @param[in] _p_pool Pool from which data will be allocated.
+ */
+#define NRF_BALLOC_INTERFACE_CUSTOM_DEF(_attr, _type, _name, _p_pool) \
+ _attr _type * CONCAT_2(_name,_alloc)(void) \
+ { \
+ GCC_PRAGMA("GCC diagnostic push") \
+ GCC_PRAGMA("GCC diagnostic ignored \"-Waddress\"") \
+ ASSERT((_p_pool) != NULL); \
+ ASSERT((_p_pool)->block_size >= \
+ NRF_BALLOC_BLOCK_SIZE(sizeof(_type), (_p_pool)->debug_flags)); \
+ GCC_PRAGMA("GCC diagnostic pop") \
+ return (_type *)(nrf_balloc_alloc(_p_pool)); \
+ } \
+ \
+ _attr void CONCAT_2(_name,_free)(_type * p_element) \
+ { \
+ GCC_PRAGMA("GCC diagnostic push") \
+ GCC_PRAGMA("GCC diagnostic ignored \"-Waddress\"") \
+ ASSERT((_p_pool) != NULL); \
+ ASSERT((_p_pool)->block_size >= \
+ NRF_BALLOC_BLOCK_SIZE(sizeof(_type), (_p_pool)->debug_flags)); \
+ GCC_PRAGMA("GCC diagnostic pop") \
+ nrf_balloc_free((_p_pool), p_element); \
+ }
+
+/**@brief Define block allocator interface.
+ *
+ * @param[in] _type Type which is allocated.
+ * @param[in] _name Name of the allocator.
+ * @param[in] _p_pool Pool from which data will be allocated.
+ */
+#define NRF_BALLOC_INTERFACE_DEF(_type, _name, _p_pool) \
+ NRF_BALLOC_INTERFACE_CUSTOM_DEF(/* empty */, _type, _name, _p_pool)
+
+/**@brief Define a local block allocator interface.
+ *
+ * @param[in] _type Type which is allocated.
+ * @param[in] _name Name of the allocator.
+ * @param[in] _p_pool Pool from which data will be allocated.
+ */
+#define NRF_BALLOC_INTERFACE_LOCAL_DEF(_type, _name, _p_pool) \
+ NRF_BALLOC_INTERFACE_CUSTOM_DEF(static, _type, _name, _p_pool)
+
+/**@brief Function for initializing a block memory allocator pool.
+ *
+ * @param[out] p_pool Pointer to the pool that is to be initialized.
+ *
+ * @return NRF_SUCCESS on success, otherwise error code.
+ */
+ret_code_t nrf_balloc_init(nrf_balloc_t const * p_pool);
+
+/**@brief Function for allocating an element from the pool.
+ *
+ * @note This module guarantees that the returned memory is aligned to 4.
+ *
+ * @param[in] p_pool Pointer to the memory pool from which the element will be allocated.
+ *
+ * @return Allocated element or NULL if the specified pool is empty.
+ */
+void * nrf_balloc_alloc(nrf_balloc_t const * p_pool);
+
+/**@brief Function for freeing an element back to the pool.
+ *
+ * @param[in] p_pool Pointer to the memory pool.
+ * @param[in] p_element Element to be freed.
+ */
+void nrf_balloc_free(nrf_balloc_t const * p_pool, void * p_element);
+
+/**@brief Function for getting maximum memory pool utilization.
+ *
+ * @param[in] p_pool Pointer to the memory pool instance.
+ *
+ * @return Maximum number of elements allocated from the pool.
+ */
+__STATIC_INLINE uint8_t nrf_balloc_max_utilization_get(nrf_balloc_t const * p_pool);
+
+#ifndef SUPPRESS_INLINE_IMPLEMENTATION
+__STATIC_INLINE uint8_t nrf_balloc_max_utilization_get(nrf_balloc_t const * p_pool)
+{
+ ASSERT(p_pool != NULL);
+ return p_pool->p_cb->max_utilization;
+}
+#endif //SUPPRESS_INLINE_IMPLEMENTATION
+
+/**@brief Function for getting current memory pool utilization.
+ *
+ * @param[in] p_pool Pointer to the memory pool instance.
+ *
+ * @return Maximum number of elements allocated from the pool.
+ */
+__STATIC_INLINE uint8_t nrf_balloc_utilization_get(nrf_balloc_t const * p_pool);
+
+#ifndef SUPPRESS_INLINE_IMPLEMENTATION
+__STATIC_INLINE uint8_t nrf_balloc_utilization_get(nrf_balloc_t const * p_pool)
+{
+ ASSERT(p_pool != NULL);
+ return (p_pool->p_stack_limit - p_pool->p_cb->p_stack_pointer);
+}
+#endif //SUPPRESS_INLINE_IMPLEMENTATION
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // NRF_BALLOC_H__
+/** @} */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/block_dev/empty/nrf_block_dev_empty.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/block_dev/empty/nrf_block_dev_empty.c
new file mode 100644
index 0000000..ab9f5c7
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/block_dev/empty/nrf_block_dev_empty.c
@@ -0,0 +1,210 @@
+/**
+ * Copyright (c) 2016 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#include "nrf_block_dev_empty.h"
+
+/**@file
+ *
+ * @ingroup nrf_block_dev
+ * @{
+ *
+ * @brief This module implements block device API. It would behave like:
+ * - /dev/empty for write operations
+ * - /dev/zero for read operations
+ */
+
+static ret_code_t block_dev_empty_init(nrf_block_dev_t const * p_blk_dev,
+ nrf_block_dev_ev_handler ev_handler,
+ void const * p_context)
+{
+ ASSERT(p_blk_dev);
+ nrf_block_dev_empty_t const * p_empty_dev =
+ CONTAINER_OF(p_blk_dev, nrf_block_dev_empty_t, block_dev);
+ nrf_block_dev_empty_work_t * p_work = p_empty_dev->p_work;
+
+ /* Calculate block device geometry.... */
+ p_work->geometry.blk_size = p_empty_dev->empty_config.block_size;
+ p_work->geometry.blk_count = p_empty_dev->empty_config.block_count;
+ p_work->p_context = p_context;
+ p_work->ev_handler = ev_handler;
+
+ if (p_work->ev_handler)
+ {
+ /*Asynchronous operation (simulation)*/
+ const nrf_block_dev_event_t ev = {
+ NRF_BLOCK_DEV_EVT_INIT,
+ NRF_BLOCK_DEV_RESULT_SUCCESS,
+ NULL,
+ p_work->p_context
+ };
+
+ p_work->ev_handler(p_blk_dev, &ev);
+ }
+
+ return NRF_SUCCESS;
+}
+
+static ret_code_t block_dev_empty_uninit(nrf_block_dev_t const * p_blk_dev)
+{
+ ASSERT(p_blk_dev);
+ nrf_block_dev_empty_t const * p_empty_dev =
+ CONTAINER_OF(p_blk_dev, nrf_block_dev_empty_t, block_dev);
+ nrf_block_dev_empty_work_t * p_work = p_empty_dev->p_work;
+
+ if (p_work->ev_handler)
+ {
+ /*Asynchronous operation (simulation)*/
+ const nrf_block_dev_event_t ev = {
+ NRF_BLOCK_DEV_EVT_UNINIT,
+ NRF_BLOCK_DEV_RESULT_SUCCESS,
+ NULL,
+ p_work->p_context
+ };
+
+ p_work->ev_handler(p_blk_dev, &ev);
+ }
+
+ memset(p_work, 0, sizeof(nrf_block_dev_empty_work_t));
+ return NRF_SUCCESS;
+}
+
+static ret_code_t block_dev_empty_read_req(nrf_block_dev_t const * p_blk_dev,
+ nrf_block_req_t const * p_blk)
+{
+ ASSERT(p_blk_dev);
+ ASSERT(p_blk);
+ nrf_block_dev_empty_t const * p_empty_dev =
+ CONTAINER_OF(p_blk_dev, nrf_block_dev_empty_t, block_dev);
+ nrf_block_dev_empty_work_t * p_work = p_empty_dev->p_work;
+
+ memset(p_blk->p_buff, 0, p_empty_dev->p_work->geometry.blk_size * p_blk->blk_count);
+ if (p_work->ev_handler)
+ {
+ /*Asynchronous operation (simulation)*/
+ const nrf_block_dev_event_t ev = {
+ NRF_BLOCK_DEV_EVT_BLK_READ_DONE,
+ NRF_BLOCK_DEV_RESULT_SUCCESS,
+ p_blk,
+ p_work->p_context
+ };
+
+ p_work->ev_handler(p_blk_dev, &ev);
+ }
+
+ return NRF_SUCCESS;
+}
+
+static ret_code_t block_dev_empty_write_req(nrf_block_dev_t const * p_blk_dev,
+ nrf_block_req_t const * p_blk)
+{
+ ASSERT(p_blk_dev);
+ ASSERT(p_blk);
+ nrf_block_dev_empty_t const * p_empty_dev =
+ CONTAINER_OF(p_blk_dev, nrf_block_dev_empty_t, block_dev);
+ nrf_block_dev_empty_work_t * p_work = p_empty_dev->p_work;
+
+ if (p_work->ev_handler)
+ {
+ /*Asynchronous operation (simulation)*/
+ const nrf_block_dev_event_t ev = {
+ NRF_BLOCK_DEV_EVT_BLK_WRITE_DONE,
+ NRF_BLOCK_DEV_RESULT_SUCCESS,
+ p_blk,
+ p_work->p_context
+ };
+
+ p_work->ev_handler(p_blk_dev, &ev);
+ }
+
+ return NRF_SUCCESS;
+}
+
+static ret_code_t block_dev_empty_ioctl(nrf_block_dev_t const * p_blk_dev,
+ nrf_block_dev_ioctl_req_t req, void * p_data)
+{
+ nrf_block_dev_empty_t const * p_empty_dev =
+ CONTAINER_OF(p_blk_dev, nrf_block_dev_empty_t, block_dev);
+ switch (req)
+ {
+ case NRF_BLOCK_DEV_IOCTL_REQ_CACHE_FLUSH:
+ {
+ bool * p_flushing = p_data;
+ if (p_flushing)
+ {
+ *p_flushing = false;
+ }
+ return NRF_SUCCESS;
+ }
+ case NRF_BLOCK_DEV_IOCTL_REQ_INFO_STRINGS:
+ {
+ if (p_data == NULL)
+ {
+ return NRF_ERROR_INVALID_PARAM;
+ }
+
+ nrf_block_dev_info_strings_t const * * pp_strings = p_data;
+ *pp_strings = &p_empty_dev->info_strings;
+ return NRF_SUCCESS;
+ }
+ default:
+ break;
+ }
+
+ return NRF_ERROR_NOT_SUPPORTED;
+}
+
+static nrf_block_dev_geometry_t const * block_dev_empty_geometry(nrf_block_dev_t const * p_blk_dev)
+{
+ ASSERT(p_blk_dev);
+ nrf_block_dev_empty_t const * p_empty_dev =
+ CONTAINER_OF(p_blk_dev, nrf_block_dev_empty_t, block_dev);
+ nrf_block_dev_empty_work_t const * p_work = p_empty_dev->p_work;
+
+ return &p_work->geometry;
+}
+
+const nrf_block_dev_ops_t nrf_block_device_empty_ops = {
+ .init = block_dev_empty_init,
+ .uninit = block_dev_empty_uninit,
+ .read_req = block_dev_empty_read_req,
+ .write_req = block_dev_empty_write_req,
+ .ioctl = block_dev_empty_ioctl,
+ .geometry = block_dev_empty_geometry,
+};
+
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/block_dev/empty/nrf_block_dev_empty.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/block_dev/empty/nrf_block_dev_empty.h
new file mode 100644
index 0000000..2f2dc76
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/block_dev/empty/nrf_block_dev_empty.h
@@ -0,0 +1,140 @@
+/**
+ * Copyright (c) 2016 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#ifndef NRF_BLOCK_DEV_EMPTY_H__
+#define NRF_BLOCK_DEV_EMPTY_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "nrf_block_dev.h"
+
+
+/**@file
+ *
+ * @defgroup nrf_block_dev_empty Empty implementation
+ * @ingroup nrf_block_dev
+ *
+ * This module implements block device API. It works like:
+ * - /dev/empty for write operations
+ * - /dev/zero for read operations
+ * @{
+ *
+ */
+
+/**
+ * @brief EMPTY block device operations
+ * */
+extern const nrf_block_dev_ops_t nrf_block_device_empty_ops;
+
+/**
+ * @brief Work structure of EMPTY block device.
+ */
+typedef struct {
+ nrf_block_dev_geometry_t geometry; //!< Block device geometry
+ nrf_block_dev_ev_handler ev_handler; //!< Block device event handler
+ void const * p_context; //!< Context handle passed to event handler
+} nrf_block_dev_empty_work_t;
+
+
+/**
+ * @brief EMPTY block device config initializer (@ref nrf_block_dev_empty_config_t)
+ *
+ * @param blk_size Block size
+ * @param blk_count Block count
+ * */
+#define NRF_BLOCK_DEV_EMPTY_CONFIG(blk_size, blk_count) { \
+ .block_size = (blk_size), \
+ .block_count = (blk_count) \
+}
+
+/**
+ * @brief EMPTY block device config
+ */
+typedef struct {
+ uint32_t block_size; //!< Desired block size
+ uint32_t block_count; //!< Desired block count
+} nrf_block_dev_empty_config_t;
+
+/**
+ * @brief EMPTY block device
+ * */
+typedef struct {
+ nrf_block_dev_t block_dev; //!< Block device
+ nrf_block_dev_info_strings_t info_strings; //!< Block device information strings
+ nrf_block_dev_empty_config_t empty_config; //!< EMPTY block device config
+ nrf_block_dev_empty_work_t * p_work; //!< EMPTY block device work structure
+} nrf_block_dev_empty_t;
+
+/**
+ * @brief Defines a EMPTY block device.
+ *
+ * @param name Instance name
+ * @param config Configuration @ref nrf_block_dev_empty_config_t
+ * @param info Info strings @ref NFR_BLOCK_DEV_INFO_CONFIG
+ * */
+#define NRF_BLOCK_DEV_EMPTY_DEFINE(name, config, info) \
+ static nrf_block_dev_empty_work_t CONCAT_2(name, _work); \
+ static const nrf_block_dev_empty_t name = { \
+ .block_dev = { .p_ops = &nrf_block_device_empty_ops }, \
+ .info_strings = BRACKET_EXTRACT(info), \
+ .empty_config = config, \
+ .p_work = &CONCAT_2(name, _work), \
+ }
+
+/**
+ * @brief Returns block device API handle from EMPTY block device.
+ *
+ * @param[in] p_blk_empty EMPTY block device
+ * @return Block device handle
+ */
+static inline nrf_block_dev_t const *
+nrf_block_dev_empty_ops_get(nrf_block_dev_empty_t const * p_blk_empty)
+{
+ return &p_blk_empty->block_dev;
+}
+
+/** @} */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* NRF_BLOCK_DEV_EMPTY_H__ */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/block_dev/nrf_block_dev.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/block_dev/nrf_block_dev.h
new file mode 100644
index 0000000..5d3c5c5
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/block_dev/nrf_block_dev.h
@@ -0,0 +1,352 @@
+/**
+ * Copyright (c) 2016 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#ifndef NRF_BLOCK_DEV_H__
+#define NRF_BLOCK_DEV_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "sdk_common.h"
+#include "nrf_assert.h"
+
+#include <stddef.h>
+
+/**@file
+ *
+ * @defgroup nrf_block_dev Block device
+ * @{
+ * @ingroup app_common
+ *
+ * @brief This module implements unified block device API. It could used as a middle layer between
+ * filesystems and memories.
+ */
+
+/**
+ * @brief Block device request descriptor item.
+ */
+typedef struct {
+ uint32_t blk_id; //!< Block ID
+ uint32_t blk_count; //!< Block count
+ void * p_buff; //!< Data buffer
+} nrf_block_req_t;
+
+
+/**
+ * @brief Helper macro to create block device read/write request item
+ *
+ * @param name Instance name
+ * @param block_start Block number start
+ * @param block_count Number of blocks
+ * @param buff Buffer to read/write
+ */
+#define NRF_BLOCK_DEV_REQUEST(name, block_start, block_count, buff) \
+ nrf_block_req_t name = { \
+ .blk_id = block_start, \
+ .blk_count = block_count, \
+ .p_buff = buff, \
+ }
+/**
+ * @brief Block device events.
+ *
+ * Events are propagated when event handler is defined (@ref nrf_blk_dev_init)
+ *
+ */
+typedef enum {
+ NRF_BLOCK_DEV_EVT_INIT, /**< Passed to event handler when init is done*/
+ NRF_BLOCK_DEV_EVT_UNINIT, /**< Passed to event handler when uninit is done*/
+ NRF_BLOCK_DEV_EVT_BLK_READ_DONE, /**< Passed to event handler block read operation is done*/
+ NRF_BLOCK_DEV_EVT_BLK_WRITE_DONE, /**< Passed to event handler block write operation is done*/
+} nrf_block_dev_event_type_t;
+
+typedef enum {
+ NRF_BLOCK_DEV_RESULT_SUCCESS = 0, /**< Operation completed succsefully*/
+ NRF_BLOCK_DEV_RESULT_IO_ERROR, /**< I/O error*/
+ NRF_BLOCK_DEV_RESULT_TIMEOUT, /**< Device timeout*/
+} nrf_block_dev_result_t;
+
+/**
+ * @brief Block device event
+ * */
+typedef struct {
+ nrf_block_dev_event_type_t ev_type; //!< Event type
+ nrf_block_dev_result_t result; //!< Operation status
+ nrf_block_req_t const * p_blk_req; //!< Block request
+ void const * p_context; //!< Event context
+} nrf_block_dev_event_t;
+
+struct nrf_block_dev_s;
+
+/**
+ * @brief Block device event handler.
+ *
+ * @param[in] p_blk_dev Block device handle
+ * @param[in] p_event Block device event
+ */
+typedef void (* nrf_block_dev_ev_handler)(struct nrf_block_dev_s const * p_blk_dev,
+ nrf_block_dev_event_t const * p_event);
+
+/**
+ * @brief Block device geometry
+ */
+typedef struct {
+ uint32_t blk_count; //!< Block count
+ uint32_t blk_size; //!< Block size
+} nrf_block_dev_geometry_t;
+
+/**
+ * @brief Block device information strings
+ */
+typedef struct {
+ const char * p_vendor; //!< Vendor string
+ const char * p_product; //!< Product string
+ const char * p_revision; //!< Revision string
+} nrf_block_dev_info_strings_t;
+
+/**
+ * @brief Block device information config
+ *
+ * @param vendor Vendor string
+ * @param product Product string
+ * @param revision Revision string
+ * */
+#define NFR_BLOCK_DEV_INFO_CONFIG(vendor, product, revision) ( { \
+ .p_vendor = vendor, \
+ .p_product = product, \
+ .p_revision = revision, \
+})
+
+/**
+ * @brief Empty info string initializer
+ * */
+#define NFR_BLOCK_DEV_INFO_CONFIG_EMPTY \
+ NFR_BLOCK_DEV_INFO_CONFIG(NULL, NULL, NULL)
+
+/**
+ * @brief Block device IOCTL requests
+ */
+typedef enum {
+ NRF_BLOCK_DEV_IOCTL_REQ_CACHE_FLUSH = 0, /**< Cache flush IOCTL request*/
+ NRF_BLOCK_DEV_IOCTL_REQ_INFO_STRINGS, /**< Get info strings IOCTL request*/
+} nrf_block_dev_ioctl_req_t;
+
+
+/**
+ * @brief Helper macro to get block device address from specific instance
+ *
+ * @param instance Block device instance
+ * @param member Block device member name
+ * */
+#define NRF_BLOCKDEV_BASE_ADDR(instance, member) &(instance).member
+
+/**
+ * @brief Block device API
+ * */
+typedef struct nrf_block_dev_s {
+ struct nrf_block_dev_ops_s {
+ /**
+ * @brief @ref nrf_blk_dev_init
+ */
+ ret_code_t (*init)(struct nrf_block_dev_s const * p_blk_dev,
+ nrf_block_dev_ev_handler ev_handler,
+ void const * p_context);
+
+ /**
+ * @brief @ref nrf_blk_dev_uninit
+ */
+ ret_code_t (*uninit)(struct nrf_block_dev_s const * p_blk_dev);
+
+ /**
+ * @brief @ref nrf_blk_dev_read_req
+ */
+ ret_code_t (*read_req)(struct nrf_block_dev_s const * p_blk_dev,
+ nrf_block_req_t const * p_blk);
+
+ /**
+ * @brief @ref nrf_blk_dev_write_req
+ */
+ ret_code_t (*write_req)(struct nrf_block_dev_s const * p_blk_dev,
+ nrf_block_req_t const * p_blk);
+
+ /**
+ * @brief @ref nrf_blk_dev_ioctl
+ */
+ ret_code_t (*ioctl)(struct nrf_block_dev_s const * p_blk_dev,
+ nrf_block_dev_ioctl_req_t req,
+ void * p_data);
+
+ /**
+ * @brief @ref nrf_blk_dev_geometry
+ */
+ nrf_block_dev_geometry_t const * (*geometry)(struct nrf_block_dev_s const * p_blk_dev);
+ } const * p_ops;
+} nrf_block_dev_t;
+
+/**
+ * @brief Internals of @ref nrf_block_dev_t
+ * */
+typedef struct nrf_block_dev_ops_s nrf_block_dev_ops_t;
+
+/**
+ * @brief Initializes a block device.
+ *
+ * @param[in] p_blk_dev Block device handle
+ * @param[in] ev_handler Event handler (pass NULL to work in synchronous mode)
+ * @param[in] p_context Context passed to event handler
+ *
+ * @return Standard error code
+ */
+static inline ret_code_t nrf_blk_dev_init(nrf_block_dev_t const * p_blk_dev,
+ nrf_block_dev_ev_handler ev_handler,
+ void const * p_context)
+{
+ ASSERT(p_blk_dev->p_ops->init);
+ return p_blk_dev->p_ops->init(p_blk_dev, ev_handler, p_context);
+}
+
+/**
+ * @brief Un-initializes a block device.
+ *
+ * @param[in] p_blk_dev Block device handle
+ *
+ * @return Standard error code
+ */
+static inline ret_code_t nrf_blk_dev_uninit(nrf_block_dev_t const * p_blk_dev)
+{
+ ASSERT(p_blk_dev->p_ops->uninit);
+ return p_blk_dev->p_ops->uninit(p_blk_dev);
+}
+
+/**
+ * @brief Block read request.
+ *
+ * In synchronous mode this function will execute the read operation
+ * and wait for its completion. In asynchronous mode the function will only request
+ * the operation and return immediately. Then, the @ref NRF_BLOCK_DEV_EVT_BLK_READ_DONE
+ * event will signal that operation has been completed and the specified buffer contains
+ * valid data.
+ *
+ * @param[in] p_blk_dev Block device handle
+ * @param[in] p_blk Block device request
+ *
+ * @return Standard error code
+ */
+static inline ret_code_t nrf_blk_dev_read_req(nrf_block_dev_t const * p_blk_dev,
+ nrf_block_req_t const * p_blk)
+{
+ ASSERT(p_blk_dev->p_ops->read_req);
+ ASSERT(p_blk_dev->p_ops->geometry);
+
+ if (p_blk->blk_id >= p_blk_dev->p_ops->geometry(p_blk_dev)->blk_count)
+ {
+ return NRF_ERROR_INVALID_PARAM;
+ }
+
+ return p_blk_dev->p_ops->read_req(p_blk_dev, p_blk);
+}
+
+/**
+ * @brief Block write request.
+ *
+ * In synchronous mode this function will execute the write operation
+ * and wait for its completion. In asynchronous mode the function will only request
+ * the operation and return immediately. Then, the @ref NRF_BLOCK_DEV_EVT_BLK_WRITE_DONE
+ * event will signal that operation has been completed and the specified buffer
+ * can be freed.
+ *
+ * @param[in] p_blk_dev Block device handle
+ * @param[in] p_blk Block device request
+ *
+ * @return Standard error code
+ */
+static inline ret_code_t nrf_blk_dev_write_req(nrf_block_dev_t const * p_blk_dev,
+ nrf_block_req_t const * p_blk)
+{
+ ASSERT(p_blk_dev->p_ops->write_req);
+ ASSERT(p_blk_dev->p_ops->geometry);
+
+ if (p_blk->blk_id >= p_blk_dev->p_ops->geometry(p_blk_dev)->blk_count)
+ {
+ return NRF_ERROR_INVALID_PARAM;
+ }
+
+ return p_blk_dev->p_ops->write_req(p_blk_dev, p_blk);
+}
+
+/**
+ * @brief IO control function.
+ *
+ * @param[in] p_blk_dev Block device handle
+ * @param[in] req Block device ioctl request
+ * @param[in] p_data Block device ioctl data
+ *
+ * @return Standard error code
+ * */
+static inline ret_code_t nrf_blk_dev_ioctl(nrf_block_dev_t const * p_blk_dev,
+ nrf_block_dev_ioctl_req_t req,
+ void * p_data)
+{
+ ASSERT(p_blk_dev->p_ops->ioctl);
+ return p_blk_dev->p_ops->ioctl(p_blk_dev, req, p_data);
+}
+
+/**
+ * @brief Return a geometry of a block device.
+ *
+ * @param[in] p_blk_dev Block device handle
+ *
+ * @return Block size and count @ref nrf_block_dev_geometry_t
+ */
+static inline nrf_block_dev_geometry_t const *
+nrf_blk_dev_geometry(nrf_block_dev_t const * p_blk_dev)
+{
+ ASSERT(p_blk_dev->p_ops->geometry);
+ return p_blk_dev->p_ops->geometry(p_blk_dev);
+}
+
+/** @} */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* NRF_BLOCK_DEV_H__ */
+
+
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/block_dev/qspi/nrf_block_dev_qspi.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/block_dev/qspi/nrf_block_dev_qspi.c
new file mode 100644
index 0000000..8ccac6b
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/block_dev/qspi/nrf_block_dev_qspi.c
@@ -0,0 +1,757 @@
+/**
+ * Copyright (c) 2016 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#include "nrf_serial_flash_params.h"
+#include "nrf_block_dev_qspi.h"
+
+/**@file
+ *
+ * @ingroup nrf_block_dev_qspi
+ * @{
+ *
+ * @brief This module implements block device API. It should be used as a reference block device.
+ */
+
+#define QSPI_STD_CMD_WRSR 0x01 /**< Write status register command*/
+#define QSPI_STD_CMD_RSTEN 0x66 /**< Reset enable command*/
+#define QSPI_STD_CMD_RST 0x99 /**< Reset command*/
+#define QSPI_STD_CMD_READ_ID 0x9F /**< Read ID command*/
+
+#define BD_PAGE_PROGRAM_SIZE 256 /**< Page program size (minimum block size)*/
+
+#define BD_ERASE_UNIT_INVALID_ID 0xFFFFFFFF /**< Invalid erase unit number*/
+#define BD_ERASE_UNIT_ERASE_VAL 0xFFFFFFFF /**< Erased memory value*/
+
+/**
+ * @brief Block to erase unit translation
+ *
+ * @param blk_id Block index
+ * @param blk_size Block size
+ * */
+#define BD_BLOCK_TO_ERASEUNIT(blk_id, blk_size) \
+ ((blk_id) * (blk_size)) / (NRF_BLOCK_DEV_QSPI_ERASE_UNIT_SIZE)
+
+/**
+ * @brief Blocks per erase unit
+ *
+ * @param blk_size Block size
+ * */
+#define BD_BLOCKS_PER_ERASEUNIT(blk_size) \
+ (NRF_BLOCK_DEV_QSPI_ERASE_UNIT_SIZE / (blk_size))
+
+
+static ret_code_t block_dev_qspi_eunit_write(nrf_block_dev_qspi_t const * p_qspi_dev,
+ nrf_block_req_t * p_blk_left);
+
+
+static void block_dev_qspi_read_from_eunit(nrf_block_dev_qspi_t const * p_qspi_dev)
+{
+ nrf_block_dev_qspi_work_t const * p_work = p_qspi_dev->p_work;
+
+ /*In write-back mode data that we read might not be the same as in erase unit buffer*/
+ uint32_t eunit_start = BD_BLOCK_TO_ERASEUNIT(p_work->req.blk_id,
+ p_work->geometry.blk_size);
+
+ uint32_t eunit_end = BD_BLOCK_TO_ERASEUNIT(p_work->req.blk_id + p_work->req.blk_count,
+ p_work->geometry.blk_size);
+
+ if ((eunit_start > p_work->erase_unit_idx) || (eunit_end < p_work->erase_unit_idx))
+ {
+ /*Do nothing. Read request doesn't hit current cached erase unit*/
+ return;
+ }
+
+ /*Case 1: Copy data from start erase unit*/
+ if (eunit_start == p_work->erase_unit_idx)
+ {
+ size_t blk = p_work->req.blk_id %
+ BD_BLOCKS_PER_ERASEUNIT(p_work->geometry.blk_size);
+ size_t cnt = BD_BLOCKS_PER_ERASEUNIT(p_work->geometry.blk_size) - blk;
+ size_t off = p_work->geometry.blk_size * blk;
+
+ if (cnt > p_work->req.blk_count)
+ {
+ cnt = p_work->req.blk_count;
+ }
+
+ memcpy(p_work->req.p_buff,
+ p_work->p_erase_unit_buff + off,
+ cnt * p_work->geometry.blk_size);
+
+ return;
+ }
+
+ /*Case 2: Copy data from end erase unit*/
+ if (eunit_end == p_work->erase_unit_idx)
+ {
+ size_t cnt = (p_work->req.blk_id + p_work->req.blk_count) %
+ BD_BLOCKS_PER_ERASEUNIT(p_work->geometry.blk_size);
+ size_t off = (p_work->erase_unit_idx * BD_BLOCKS_PER_ERASEUNIT(p_work->geometry.blk_size) -
+ p_work->req.blk_id) * p_work->geometry.blk_size;
+
+ if (cnt > p_work->req.blk_count)
+ {
+ cnt = p_work->req.blk_count;
+ }
+
+ memcpy((uint8_t *)p_work->req.p_buff + off,
+ p_work->p_erase_unit_buff,
+ cnt * p_work->geometry.blk_size);
+
+ return;
+ }
+
+ /*Case 3: Copy data from eunit_start < p_work->erase_unit_idx < eunit_end*/
+ size_t off = (p_work->erase_unit_idx * BD_BLOCKS_PER_ERASEUNIT(p_work->geometry.blk_size) -
+ p_work->req.blk_id) * p_work->geometry.blk_size;
+
+ memcpy((uint8_t *)p_work->req.p_buff + off,
+ p_work->p_erase_unit_buff,
+ NRF_BLOCK_DEV_QSPI_ERASE_UNIT_SIZE);
+}
+
+/**
+ * @brief Active QSPI block device handle. Only one instance.
+ * */
+static nrf_block_dev_qspi_t const * m_active_qspi_dev;
+
+static void qspi_handler(nrf_drv_qspi_evt_t event, void * p_context)
+{
+ if (m_active_qspi_dev != p_context)
+ {
+ return;
+ }
+
+ nrf_block_dev_qspi_t const * p_qspi_dev = p_context;
+ nrf_block_dev_qspi_work_t * p_work = p_qspi_dev->p_work;
+ nrf_block_req_t * p_blk_left = &p_work->left_req;
+
+ switch (p_work->state)
+ {
+ case NRF_BLOCK_DEV_QSPI_STATE_READ_EXEC:
+ {
+ if (p_work->writeback_mode)
+ {
+ block_dev_qspi_read_from_eunit(p_qspi_dev);
+ }
+
+ p_work->state = NRF_BLOCK_DEV_QSPI_STATE_IDLE;
+ if (p_work->ev_handler)
+ {
+ const nrf_block_dev_event_t ev = {
+ NRF_BLOCK_DEV_EVT_BLK_READ_DONE,
+ NRF_BLOCK_DEV_RESULT_SUCCESS,
+ &p_work->req,
+ p_work->p_context
+ };
+
+ p_work->ev_handler(&p_qspi_dev->block_dev, &ev);
+ }
+
+ break;
+ }
+ case NRF_BLOCK_DEV_QSPI_STATE_EUNIT_LOAD:
+ {
+ ret_code_t ret;
+ uint32_t erase_unit = BD_BLOCK_TO_ERASEUNIT(p_blk_left->blk_id,
+ p_work->geometry.blk_size);
+ UNUSED_VARIABLE(erase_unit);
+ ASSERT(erase_unit == p_work->erase_unit_idx);
+
+ /* Check if block is in erase unit buffer*/
+ ret = block_dev_qspi_eunit_write(p_qspi_dev, p_blk_left);
+ ASSERT(ret == NRF_SUCCESS);
+ UNUSED_VARIABLE(ret);
+ break;
+ }
+ case NRF_BLOCK_DEV_QSPI_STATE_WRITE_ERASE:
+ case NRF_BLOCK_DEV_QSPI_STATE_WRITE_EXEC:
+ {
+ /*Clear last programmed block*/
+ uint32_t block_to_program = __CLZ(__RBIT(p_work->erase_unit_dirty_blocks));
+
+ if (p_work->state == NRF_BLOCK_DEV_QSPI_STATE_WRITE_EXEC)
+ {
+ p_work->erase_unit_dirty_blocks ^= 1u << block_to_program;
+ }
+
+ if (p_work->erase_unit_dirty_blocks == 0)
+ {
+ if (p_work->left_req.blk_count)
+ {
+ /*Load next erase unit*/
+ ret_code_t ret;
+ uint32_t eunit = BD_BLOCK_TO_ERASEUNIT(p_blk_left->blk_id,
+ p_work->geometry.blk_size);
+
+ p_work->erase_unit_idx = eunit;
+ p_work->state = NRF_BLOCK_DEV_QSPI_STATE_EUNIT_LOAD;
+
+ ret = nrf_drv_qspi_read(p_work->p_erase_unit_buff,
+ NRF_BLOCK_DEV_QSPI_ERASE_UNIT_SIZE,
+ p_work->erase_unit_idx *
+ NRF_BLOCK_DEV_QSPI_ERASE_UNIT_SIZE);
+ UNUSED_VARIABLE(ret);
+
+ break;
+ }
+
+ /*All blocks are programmed. Call event handler if required.*/
+ p_work->state = NRF_BLOCK_DEV_QSPI_STATE_IDLE;
+ if (p_work->ev_handler && !p_work->cache_flushing)
+ {
+ const nrf_block_dev_event_t ev = {
+ NRF_BLOCK_DEV_EVT_BLK_WRITE_DONE,
+ NRF_BLOCK_DEV_RESULT_SUCCESS,
+ &p_work->req,
+ p_work->p_context
+ };
+
+ p_work->ev_handler(&p_qspi_dev->block_dev, &ev);
+ }
+
+ p_work->cache_flushing = false;
+ break;
+ }
+
+ /*Get next block to program from program mask*/
+ block_to_program = __CLZ(__RBIT(p_work->erase_unit_dirty_blocks));
+ uint32_t dst_address = (p_work->erase_unit_idx * NRF_BLOCK_DEV_QSPI_ERASE_UNIT_SIZE) +
+ (block_to_program * p_work->geometry.blk_size);
+
+ const void * p_src_address = p_work->p_erase_unit_buff +
+ block_to_program * p_work->geometry.blk_size;
+
+ p_work->state = NRF_BLOCK_DEV_QSPI_STATE_WRITE_EXEC;
+ ret_code_t ret = nrf_drv_qspi_write(p_src_address,
+ p_work->geometry.blk_size,
+ dst_address);
+ UNUSED_VARIABLE(ret);
+ break;
+ }
+ default:
+ ASSERT(0);
+ break;
+ }
+}
+
+static void wait_for_idle(nrf_block_dev_qspi_t const * p_qspi_dev)
+{
+ nrf_block_dev_qspi_work_t * p_work = p_qspi_dev->p_work;
+ while (p_work->state != NRF_BLOCK_DEV_QSPI_STATE_IDLE)
+ {
+ __WFI();
+ }
+}
+
+static ret_code_t block_dev_qspi_init(nrf_block_dev_t const * p_blk_dev,
+ nrf_block_dev_ev_handler ev_handler,
+ void const * p_context)
+{
+ ASSERT(p_blk_dev);
+ nrf_block_dev_qspi_t const * p_qspi_dev =
+ CONTAINER_OF(p_blk_dev, nrf_block_dev_qspi_t, block_dev);
+ nrf_block_dev_qspi_work_t * p_work = p_qspi_dev->p_work;
+ nrf_drv_qspi_config_t const * p_qspi_cfg = &p_qspi_dev->qspi_bdev_config.qspi_config;
+
+ ret_code_t ret = NRF_SUCCESS;
+
+ if (p_qspi_dev->qspi_bdev_config.block_size % BD_PAGE_PROGRAM_SIZE)
+ {
+ /*Unsupported block size*/
+ return NRF_ERROR_NOT_SUPPORTED;
+ }
+
+ if (NRF_BLOCK_DEV_QSPI_ERASE_UNIT_SIZE % p_qspi_dev->qspi_bdev_config.block_size)
+ {
+ /*Unsupported block size*/
+ return NRF_ERROR_NOT_SUPPORTED;
+ }
+
+ if (m_active_qspi_dev)
+ {
+ /* QSPI instance is BUSY*/
+ return NRF_ERROR_BUSY;
+ }
+
+ ret = nrf_drv_qspi_init(p_qspi_cfg, qspi_handler, (void *)p_blk_dev);
+ if (ret != NRF_SUCCESS)
+ {
+ return ret;
+ }
+
+ nrf_qspi_cinstr_conf_t cinstr_cfg = {
+ .opcode = QSPI_STD_CMD_RSTEN,
+ .length = NRF_QSPI_CINSTR_LEN_1B,
+ .io2_level = true,
+ .io3_level = true,
+ .wipwait = true,
+ .wren = true
+ };
+
+ /* Send reset enable */
+ ret = nrf_drv_qspi_cinstr_xfer(&cinstr_cfg, NULL, NULL);
+ if (ret != NRF_SUCCESS)
+ {
+ return ret;
+ }
+
+ /* Send reset command */
+ cinstr_cfg.opcode = QSPI_STD_CMD_RST;
+ ret = nrf_drv_qspi_cinstr_xfer(&cinstr_cfg, NULL, NULL);
+ if (ret != NRF_SUCCESS)
+ {
+ return ret;
+ }
+
+ /* Get 3 byte identification value */
+ uint8_t rdid_buf[3] = {0, 0, 0};
+ cinstr_cfg.opcode = QSPI_STD_CMD_READ_ID;
+ cinstr_cfg.length = NRF_QSPI_CINSTR_LEN_4B;
+ ret = nrf_drv_qspi_cinstr_xfer(&cinstr_cfg, NULL, rdid_buf);
+ if (ret != NRF_SUCCESS)
+ {
+ return ret;
+ }
+
+ nrf_serial_flash_params_t const * serial_flash_id = nrf_serial_flash_params_get(rdid_buf);
+
+ if (!serial_flash_id)
+ {
+ return NRF_ERROR_NOT_SUPPORTED;
+ }
+
+ if (serial_flash_id->erase_size != NRF_BLOCK_DEV_QSPI_ERASE_UNIT_SIZE)
+ {
+ return NRF_ERROR_NOT_SUPPORTED;
+ }
+
+ /* Calculate block device geometry.... */
+ uint32_t blk_size = p_qspi_dev->qspi_bdev_config.block_size;
+ uint32_t blk_count = serial_flash_id->size / p_qspi_dev->qspi_bdev_config.block_size;
+
+ if (!blk_count || (blk_count % BD_BLOCKS_PER_ERASEUNIT(blk_size)))
+ {
+ return NRF_ERROR_NOT_SUPPORTED;
+ }
+
+ p_work->geometry.blk_size = blk_size;
+ p_work->geometry.blk_count = blk_count;
+ p_work->p_context = p_context;
+ p_work->ev_handler = ev_handler;
+
+ p_work->state = NRF_BLOCK_DEV_QSPI_STATE_IDLE;
+ p_work->erase_unit_idx = BD_ERASE_UNIT_INVALID_ID;
+ p_work->writeback_mode = (p_qspi_dev->qspi_bdev_config.flags &
+ NRF_BLOCK_DEV_QSPI_FLAG_CACHE_WRITEBACK) != 0;
+ m_active_qspi_dev = p_qspi_dev;
+
+ if (p_work->ev_handler)
+ {
+ /*Asynchronous operation (simulation)*/
+ const nrf_block_dev_event_t ev = {
+ NRF_BLOCK_DEV_EVT_INIT,
+ NRF_BLOCK_DEV_RESULT_SUCCESS,
+ NULL,
+ p_work->p_context
+ };
+
+ p_work->ev_handler(p_blk_dev, &ev);
+ }
+
+ return NRF_SUCCESS;
+}
+
+static ret_code_t block_dev_qspi_uninit(nrf_block_dev_t const * p_blk_dev)
+{
+ ASSERT(p_blk_dev);
+ nrf_block_dev_qspi_t const * p_qspi_dev =
+ CONTAINER_OF(p_blk_dev, nrf_block_dev_qspi_t, block_dev);
+ nrf_block_dev_qspi_work_t * p_work = p_qspi_dev->p_work;
+
+ if (m_active_qspi_dev != p_qspi_dev)
+ {
+ /* QSPI instance is BUSY*/
+ return NRF_ERROR_BUSY;
+ }
+
+ if (p_work->state != NRF_BLOCK_DEV_QSPI_STATE_IDLE)
+ {
+ /* Previous asynchronous operation in progress*/
+ return NRF_ERROR_BUSY;
+ }
+
+ if (p_work->ev_handler)
+ {
+ /*Asynchronous operation*/
+ const nrf_block_dev_event_t ev = {
+ NRF_BLOCK_DEV_EVT_UNINIT,
+ NRF_BLOCK_DEV_RESULT_SUCCESS,
+ NULL,
+ p_work->p_context
+ };
+
+ p_work->ev_handler(p_blk_dev, &ev);
+ }
+
+ p_work->state = NRF_BLOCK_DEV_QSPI_STATE_DISABLED;
+ nrf_drv_qspi_uninit();
+
+ memset(p_work, 0, sizeof(nrf_block_dev_qspi_work_t));
+ m_active_qspi_dev = NULL;
+ return NRF_SUCCESS;
+}
+
+static ret_code_t block_dev_qspi_read_req(nrf_block_dev_t const * p_blk_dev,
+ nrf_block_req_t const * p_blk)
+{
+ ASSERT(p_blk_dev);
+ ASSERT(p_blk);
+ nrf_block_dev_qspi_t const * p_qspi_dev =
+ CONTAINER_OF(p_blk_dev, nrf_block_dev_qspi_t, block_dev);
+ nrf_block_dev_qspi_work_t * p_work = p_qspi_dev->p_work;
+
+ ret_code_t ret = NRF_SUCCESS;
+
+ if (m_active_qspi_dev != p_qspi_dev)
+ {
+ /* QSPI instance is BUSY*/
+ return NRF_ERROR_BUSY;
+ }
+
+ if (p_work->state != NRF_BLOCK_DEV_QSPI_STATE_IDLE)
+ {
+ /* Previous asynchronous operation in progress*/
+ return NRF_ERROR_BUSY;
+ }
+
+ p_work->left_req = *p_blk;
+ p_work->req = *p_blk;
+ nrf_block_req_t * p_blk_left = &p_work->left_req;
+
+ p_work->state = NRF_BLOCK_DEV_QSPI_STATE_READ_EXEC;
+ ret = nrf_drv_qspi_read(p_blk_left->p_buff,
+ p_blk_left->blk_count * p_work->geometry.blk_size,
+ p_blk_left->blk_id * p_work->geometry.blk_size);
+
+ if (ret != NRF_SUCCESS)
+ {
+ p_work->state = NRF_BLOCK_DEV_QSPI_STATE_IDLE;
+ return ret;
+ }
+
+ p_blk_left->p_buff = NULL;
+ p_blk_left->blk_count = 0;
+
+ if (!p_work->ev_handler && (p_work->state != NRF_BLOCK_DEV_QSPI_STATE_IDLE))
+ {
+ /*Synchronous operation*/
+ wait_for_idle(p_qspi_dev);
+ }
+
+ return ret;
+}
+
+static bool block_dev_qspi_update_eunit(nrf_block_dev_qspi_t const * p_qspi_dev,
+ size_t off,
+ const void * p_src,
+ size_t len)
+{
+ ASSERT((len % sizeof(uint32_t)) == 0)
+ nrf_block_dev_qspi_work_t * p_work = p_qspi_dev->p_work;
+
+ uint32_t * p_dst32 = (uint32_t *)(p_work->p_erase_unit_buff + off);
+ const uint32_t * p_src32 = p_src;
+
+ bool erase_required = false;
+ len /= sizeof(uint32_t);
+
+ /*Do normal copying until erase unit is not required*/
+ do
+ {
+ if (*p_dst32 != *p_src32)
+ {
+ if (*p_dst32 != BD_ERASE_UNIT_ERASE_VAL)
+ {
+ erase_required = true;
+ }
+
+ /*Mark block as dirty*/
+ p_work->erase_unit_dirty_blocks |= 1u << (off / p_work->geometry.blk_size);
+ }
+
+ *p_dst32++ = *p_src32++;
+ off += sizeof(uint32_t);
+ } while (--len);
+
+ return erase_required;
+}
+
+static ret_code_t block_dev_qspi_write_start(nrf_block_dev_qspi_t const * p_qspi_dev)
+{
+ nrf_block_dev_qspi_work_t * p_work = p_qspi_dev->p_work;
+
+ if (!p_work->erase_required)
+ {
+ /*Get first block to program from program mask*/
+ uint32_t block_to_program = __CLZ(__RBIT(p_work->erase_unit_dirty_blocks));
+ uint32_t dst_address = (p_work->erase_unit_idx * NRF_BLOCK_DEV_QSPI_ERASE_UNIT_SIZE) +
+ (block_to_program * p_work->geometry.blk_size);
+
+ const void * p_src_address = p_work->p_erase_unit_buff +
+ block_to_program * p_work->geometry.blk_size;
+
+ p_work->state = NRF_BLOCK_DEV_QSPI_STATE_WRITE_EXEC;
+ return nrf_drv_qspi_write(p_src_address,
+ p_work->geometry.blk_size,
+ dst_address);
+ }
+
+ /*Erase is required*/
+ uint32_t address = (p_work->erase_unit_idx * NRF_BLOCK_DEV_QSPI_ERASE_UNIT_SIZE);
+ p_work->state = NRF_BLOCK_DEV_QSPI_STATE_WRITE_ERASE;
+ p_work->erase_required = false;
+
+ return nrf_drv_qspi_erase(NRF_QSPI_ERASE_LEN_4KB, address);
+}
+
+static ret_code_t block_dev_qspi_eunit_write(nrf_block_dev_qspi_t const * p_qspi_dev,
+ nrf_block_req_t * p_blk_left)
+{
+ nrf_block_dev_qspi_work_t * p_work = p_qspi_dev->p_work;
+
+ size_t blk = p_blk_left->blk_id %
+ BD_BLOCKS_PER_ERASEUNIT(p_work->geometry.blk_size);
+ size_t cnt = BD_BLOCKS_PER_ERASEUNIT(p_work->geometry.blk_size) - blk;
+ size_t off = p_work->geometry.blk_size * blk;
+
+ if (cnt > p_blk_left->blk_count)
+ {
+ cnt = p_blk_left->blk_count;
+ }
+
+ bool erase_required = block_dev_qspi_update_eunit(p_qspi_dev,
+ off,
+ p_blk_left->p_buff,
+ cnt * p_work->geometry.blk_size);
+ if (erase_required)
+ {
+ p_work->erase_required = true;
+ }
+
+ p_blk_left->blk_count -= cnt;
+ p_blk_left->blk_id += cnt;
+ p_blk_left->p_buff = (uint8_t *)p_blk_left->p_buff + cnt * p_work->geometry.blk_size;
+
+ if (p_work->erase_required)
+ {
+ uint32_t blk_size = p_work->geometry.blk_size;
+ p_work->erase_unit_dirty_blocks |= (1u << BD_BLOCKS_PER_ERASEUNIT(blk_size)) - 1;
+ }
+
+ if (p_work->erase_unit_dirty_blocks == 0 || p_work->writeback_mode)
+ {
+ /*No dirty blocks detected. Write end.*/
+ if (p_work->ev_handler && p_blk_left->blk_count == 0)
+ {
+ const nrf_block_dev_event_t ev = {
+ NRF_BLOCK_DEV_EVT_BLK_WRITE_DONE,
+ NRF_BLOCK_DEV_RESULT_SUCCESS,
+ &p_work->req,
+ p_work->p_context
+ };
+
+
+ p_work->state = NRF_BLOCK_DEV_QSPI_STATE_IDLE;
+ p_work->ev_handler(&p_qspi_dev->block_dev, &ev);
+ return NRF_SUCCESS;
+ }
+ }
+
+ return block_dev_qspi_write_start(p_qspi_dev);
+}
+
+static ret_code_t block_dev_qspi_write_req(nrf_block_dev_t const * p_blk_dev,
+ nrf_block_req_t const * p_blk)
+{
+ ASSERT(p_blk_dev);
+ ASSERT(p_blk);
+ nrf_block_dev_qspi_t const * p_qspi_dev =
+ CONTAINER_OF(p_blk_dev, nrf_block_dev_qspi_t, block_dev);
+ nrf_block_dev_qspi_work_t * p_work = p_qspi_dev->p_work;
+
+ ret_code_t ret = NRF_SUCCESS;
+
+ if (m_active_qspi_dev != p_qspi_dev)
+ {
+ /* QSPI instance is BUSY*/
+ return NRF_ERROR_BUSY;
+ }
+
+ if (p_work->state != NRF_BLOCK_DEV_QSPI_STATE_IDLE)
+ {
+ /* Previous asynchronous operation in progress*/
+ return NRF_ERROR_BUSY;
+ }
+
+ p_work->left_req = *p_blk;
+ p_work->req = *p_blk;
+
+ nrf_block_req_t * p_blk_left = &p_work->left_req;
+
+ uint32_t erase_unit = BD_BLOCK_TO_ERASEUNIT(p_blk_left->blk_id,
+ p_work->geometry.blk_size);
+
+ /* Check if block is in erase unit buffer*/
+ if (erase_unit == p_work->erase_unit_idx)
+ {
+ ret = block_dev_qspi_eunit_write(p_qspi_dev, p_blk_left);
+ }
+ else
+ {
+ if (p_work->writeback_mode)
+ {
+ ret = block_dev_qspi_write_start(p_qspi_dev);
+ }
+ else
+ {
+ p_work->erase_unit_idx = erase_unit;
+ p_work->state = NRF_BLOCK_DEV_QSPI_STATE_EUNIT_LOAD;
+
+ ret = nrf_drv_qspi_read(p_work->p_erase_unit_buff,
+ NRF_BLOCK_DEV_QSPI_ERASE_UNIT_SIZE,
+ erase_unit * NRF_BLOCK_DEV_QSPI_ERASE_UNIT_SIZE);
+ }
+ }
+
+ if (ret != NRF_SUCCESS)
+ {
+ p_work->state = NRF_BLOCK_DEV_QSPI_STATE_IDLE;
+ return ret;
+ }
+
+ if (!p_work->ev_handler && (p_work->state != NRF_BLOCK_DEV_QSPI_STATE_IDLE))
+ {
+ /*Synchronous operation*/
+ wait_for_idle(p_qspi_dev);
+ }
+
+ return ret;
+}
+
+static ret_code_t block_dev_qspi_ioctl(nrf_block_dev_t const * p_blk_dev,
+ nrf_block_dev_ioctl_req_t req,
+ void * p_data)
+{
+ ASSERT(p_blk_dev);
+ nrf_block_dev_qspi_t const * p_qspi_dev =
+ CONTAINER_OF(p_blk_dev, nrf_block_dev_qspi_t, block_dev);
+ nrf_block_dev_qspi_work_t * p_work = p_qspi_dev->p_work;
+
+ switch (req)
+ {
+ case NRF_BLOCK_DEV_IOCTL_REQ_CACHE_FLUSH:
+ {
+ bool * p_flushing = p_data;
+ if (p_work->state != NRF_BLOCK_DEV_QSPI_STATE_IDLE)
+ {
+ return NRF_ERROR_BUSY;
+ }
+
+ if (!p_work->writeback_mode || p_work->erase_unit_dirty_blocks == 0)
+ {
+ if (p_flushing)
+ {
+ *p_flushing = false;
+ }
+
+ return NRF_SUCCESS;
+ }
+
+ ret_code_t ret = block_dev_qspi_write_start(p_qspi_dev);
+ if (ret == NRF_SUCCESS)
+ {
+ if (p_flushing)
+ {
+ *p_flushing = true;
+ }
+ p_work->cache_flushing = true;
+ }
+
+ return ret;
+ }
+ case NRF_BLOCK_DEV_IOCTL_REQ_INFO_STRINGS:
+ {
+ if (p_data == NULL)
+ {
+ return NRF_ERROR_INVALID_PARAM;
+ }
+
+ nrf_block_dev_info_strings_t const * * pp_strings = p_data;
+ *pp_strings = &p_qspi_dev->info_strings;
+ return NRF_SUCCESS;
+ }
+ default:
+ break;
+ }
+
+ return NRF_ERROR_NOT_SUPPORTED;
+}
+
+static nrf_block_dev_geometry_t const * block_dev_qspi_geometry(nrf_block_dev_t const * p_blk_dev)
+{
+ ASSERT(p_blk_dev);
+ nrf_block_dev_qspi_t const * p_qspi_dev =
+ CONTAINER_OF(p_blk_dev, nrf_block_dev_qspi_t, block_dev);
+ nrf_block_dev_qspi_work_t const * p_work = p_qspi_dev->p_work;
+
+ return &p_work->geometry;
+}
+
+const nrf_block_dev_ops_t nrf_block_device_qspi_ops = {
+ .init = block_dev_qspi_init,
+ .uninit = block_dev_qspi_uninit,
+ .read_req = block_dev_qspi_read_req,
+ .write_req = block_dev_qspi_write_req,
+ .ioctl = block_dev_qspi_ioctl,
+ .geometry = block_dev_qspi_geometry,
+};
+
+
+/** @} */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/block_dev/qspi/nrf_block_dev_qspi.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/block_dev/qspi/nrf_block_dev_qspi.h
new file mode 100644
index 0000000..f73a729
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/block_dev/qspi/nrf_block_dev_qspi.h
@@ -0,0 +1,172 @@
+/**
+ * Copyright (c) 2016 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#ifndef NRF_BLOCK_DEV_QSPI_H__
+#define NRF_BLOCK_DEV_QSPI_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "nrf_block_dev.h"
+#include "nrf_drv_qspi.h"
+
+/**@file
+ *
+ * @defgroup nrf_block_dev_qspi QSPI implementation
+ * @ingroup nrf_block_dev
+ * @{
+ *
+ */
+
+/**
+ * @brief QSPI block device operations
+ * */
+extern const nrf_block_dev_ops_t nrf_block_device_qspi_ops;
+
+/**
+ * @brief QSPI block device internal erase unit buffer size
+ * */
+#define NRF_BLOCK_DEV_QSPI_ERASE_UNIT_SIZE (4096)
+
+/**
+ * @brief Internal Block device state
+ */
+typedef enum {
+ NRF_BLOCK_DEV_QSPI_STATE_DISABLED = 0, /**< QSPI block device state DISABLED */
+ NRF_BLOCK_DEV_QSPI_STATE_IDLE, /**< QSPI block device state IDLE */
+ NRF_BLOCK_DEV_QSPI_STATE_READ_EXEC, /**< QSPI block device state READ_EXEC */
+ NRF_BLOCK_DEV_QSPI_STATE_EUNIT_LOAD, /**< QSPI block device state EUNIT_LOAD */
+ NRF_BLOCK_DEV_QSPI_STATE_WRITE_ERASE, /**< QSPI block device state WRITE_ERASE */
+ NRF_BLOCK_DEV_QSPI_STATE_WRITE_EXEC, /**< QSPI block device state WRITE_EXEC */
+} nrf_block_dev_qspi_state_t;
+
+/**
+ * @brief Work structure of QSPI block device
+ */
+typedef struct {
+ volatile nrf_block_dev_qspi_state_t state; //!< QSPI block device state
+
+ nrf_block_dev_geometry_t geometry; //!< Block device geometry
+ nrf_block_dev_ev_handler ev_handler; //!< Block device event handler
+ void const * p_context; //!< Context handle passed to event handler
+ nrf_block_req_t req; //!< Block READ/WRITE request: original value
+ nrf_block_req_t left_req; //!< Block READ/WRITE request: left value
+
+ bool cache_flushing; //!< QSPI cache flush in progress flag
+ bool writeback_mode; //!< QSPI write-back mode flag
+ bool erase_required; //!< QSPI erase required flag
+ uint32_t erase_unit_idx; //!< QSPI erase unit index
+ uint32_t erase_unit_dirty_blocks; //!< QSPI erase unit dirty blocks mask
+ uint8_t p_erase_unit_buff[NRF_BLOCK_DEV_QSPI_ERASE_UNIT_SIZE]; //!< QSPI erase unit buffer (fixed value)
+} nrf_block_dev_qspi_work_t;
+
+/**
+ * @brief QSPI block device flags*/
+typedef enum {
+ NRF_BLOCK_DEV_QSPI_FLAG_CACHE_WRITEBACK = (1u << 0) //!< Cache write-back mode enable flag
+} nrf_block_dev_qspi_flag_t;
+
+/**
+ * @brief QSPI block device config initializer (@ref nrf_block_dev_qspi_config_t)
+ *
+ * @param blk_size Block size
+ * @param blk_flags Block device flags, @ref nrf_block_dev_qspi_flag_t
+ * @param qspi_drv_config QPSI driver config
+ * */
+#define NRF_BLOCK_DEV_QSPI_CONFIG(blk_size, blk_flags, qspi_drv_config) { \
+ .block_size = (blk_size), \
+ .flags = (blk_flags), \
+ .qspi_config = qspi_drv_config \
+}
+
+/**
+ * @brief QSPI block device config
+ */
+typedef struct {
+ uint32_t block_size; //!< Desired block size
+ uint32_t flags; //!< QSPI block device flags
+ nrf_drv_qspi_config_t qspi_config; //!< QSPI configuration
+} nrf_block_dev_qspi_config_t;
+
+/**
+ * @brief QSPI block device
+ * */
+typedef struct {
+ nrf_block_dev_t block_dev; //!< Block device
+ nrf_block_dev_info_strings_t info_strings; //!< Block device information strings
+ nrf_block_dev_qspi_config_t qspi_bdev_config; //!< QSPI block device config
+ nrf_block_dev_qspi_work_t * p_work; //!< QSPI block device work structure
+} nrf_block_dev_qspi_t;
+
+/**
+ * @brief Defines a QSPI block device.
+ *
+ * @param name Instance name
+ * @param config Configuration @ref nrf_block_dev_qspi_config_t
+ * @param info Info strings @ref NFR_BLOCK_DEV_INFO_CONFIG
+ * */
+#define NRF_BLOCK_DEV_QSPI_DEFINE(name, config, info) \
+ static nrf_block_dev_qspi_work_t CONCAT_2(name, _work); \
+ static const nrf_block_dev_qspi_t name = { \
+ .block_dev = { .p_ops = &nrf_block_device_qspi_ops }, \
+ .info_strings = BRACKET_EXTRACT(info), \
+ .qspi_bdev_config = config, \
+ .p_work = &CONCAT_2(name, _work), \
+ }
+
+/**
+ * @brief Returns block device API handle from QSPI block device.
+ *
+ * @param[in] p_blk_qspi QSPI block device
+ * @return Block device handle
+ */
+static inline nrf_block_dev_t const *
+nrf_block_dev_qspi_ops_get(nrf_block_dev_qspi_t const * p_blk_qspi)
+{
+ return &p_blk_qspi->block_dev;
+}
+
+/** @} */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* NRF_BLOCK_DEV_QSPI_H__ */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/block_dev/qspi/nrf_serial_flash_params.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/block_dev/qspi/nrf_serial_flash_params.c
new file mode 100644
index 0000000..47a8232
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/block_dev/qspi/nrf_serial_flash_params.c
@@ -0,0 +1,65 @@
+/**
+ * Copyright (c) 2016 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#include "nrf_serial_flash_params.h"
+
+static const nrf_serial_flash_params_t m_sflash_params[] = {
+ { /*MXIC MX25R6435F*/
+ .read_id = { 0xC2, 0x28, 0x17 },
+ .capabilities = 0x00,
+ .size = 8 * 1024 * 1024,
+ .erase_size = 4 * 1024,
+ .program_size = 256,
+ }
+};
+
+nrf_serial_flash_params_t const * nrf_serial_flash_params_get(const uint8_t * p_read_id)
+{
+ size_t i;
+
+ for (i = 0; i < ARRAY_SIZE(m_sflash_params); ++i)
+ {
+ if (memcmp(m_sflash_params[i].read_id, p_read_id, sizeof(m_sflash_params[i].read_id)) == 0)
+ {
+ return &m_sflash_params[i];
+ }
+ }
+
+ return NULL;
+}
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/block_dev/qspi/nrf_serial_flash_params.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/block_dev/qspi/nrf_serial_flash_params.h
new file mode 100644
index 0000000..fd02404
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/block_dev/qspi/nrf_serial_flash_params.h
@@ -0,0 +1,83 @@
+/**
+ * Copyright (c) 2016 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#ifndef NRF_SERIAL_FLASH_PARAMS_H__
+#define NRF_SERIAL_FLASH_PARAMS_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "sdk_common.h"
+
+/**@file
+ *
+ * @defgroup nrf_serial_flash_params Serial flash memory parameters
+ * @ingroup nrf_block_dev
+ * @{
+ *
+ */
+
+/**
+ * @brief Serial flash memory parameters
+ * */
+typedef struct {
+ uint8_t read_id[3]; //!< Read identification command (0x9F) result
+ uint8_t capabilities; //!< Serial flash memory capabilities
+ uint32_t size; //!< Serial flash memory size (bytes)
+ uint32_t erase_size; //!< Serial flash memory erase unit size (bytes)
+ uint32_t program_size; //!< Serial flash memory program size (bytes)
+} nrf_serial_flash_params_t;
+
+
+/**
+ * @brief Returns serial flash memory identification descriptor
+ *
+ * @param p_read_params Memory read identification command result
+ *
+ * @return Serial flash memory descriptor (NULL if not found)
+ * */
+nrf_serial_flash_params_t const * nrf_serial_flash_params_get(const uint8_t * p_read_params);
+
+/** @} */
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* NRF_SERIAL_FLASH_PARAMS_H__ */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/block_dev/ram/nrf_block_dev_ram.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/block_dev/ram/nrf_block_dev_ram.c
new file mode 100644
index 0000000..1acbab9
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/block_dev/ram/nrf_block_dev_ram.c
@@ -0,0 +1,205 @@
+/**
+ * Copyright (c) 2016 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#include "nrf_block_dev_ram.h"
+
+/**@file
+ *
+ * @ingroup nrf_block_dev
+ * @{
+ *
+ * @brief This module implements block device API. It should be used as a reference block device.
+ */
+
+static ret_code_t block_dev_ram_init(nrf_block_dev_t const * p_blk_dev,
+ nrf_block_dev_ev_handler ev_handler,
+ void const * p_context)
+{
+ ASSERT(p_blk_dev);
+ nrf_block_dev_ram_t const * p_ram_dev = CONTAINER_OF(p_blk_dev, nrf_block_dev_ram_t, block_dev);
+ nrf_block_dev_ram_work_t * p_work = p_ram_dev->p_work;
+
+ /* Calculate block device geometry.... */
+ p_work->geometry.blk_size = p_ram_dev->ram_config.block_size;
+ p_work->geometry.blk_count = p_ram_dev->ram_config.size /
+ p_ram_dev->ram_config.block_size;
+ p_work->p_context = p_context;
+ p_work->ev_handler = ev_handler;
+
+ if (p_work->ev_handler)
+ {
+ /*Asynchronous operation (simulation)*/
+ const nrf_block_dev_event_t ev = {
+ NRF_BLOCK_DEV_EVT_INIT,
+ NRF_BLOCK_DEV_RESULT_SUCCESS,
+ NULL,
+ p_work->p_context
+ };
+
+ p_work->ev_handler(p_blk_dev, &ev);
+ }
+
+ return NRF_SUCCESS;
+}
+
+static ret_code_t block_dev_ram_uninit(nrf_block_dev_t const * p_blk_dev)
+{
+ ASSERT(p_blk_dev);
+ nrf_block_dev_ram_t const * p_ram_dev = CONTAINER_OF(p_blk_dev, nrf_block_dev_ram_t, block_dev);
+ nrf_block_dev_ram_work_t * p_work = p_ram_dev->p_work;
+
+ if (p_work->ev_handler)
+ {
+ /*Asynchronous operation (simulation)*/
+ const nrf_block_dev_event_t ev = {
+ NRF_BLOCK_DEV_EVT_UNINIT,
+ NRF_BLOCK_DEV_RESULT_SUCCESS,
+ NULL,
+ p_work->p_context
+ };
+
+ p_work->ev_handler(p_blk_dev, &ev);
+ }
+
+ memset(p_work, 0, sizeof(nrf_block_dev_ram_work_t));
+ return NRF_SUCCESS;
+}
+
+static ret_code_t block_dev_ram_req(nrf_block_dev_t const * p_blk_dev,
+ nrf_block_req_t const * p_blk,
+ nrf_block_dev_event_type_t event)
+{
+ ASSERT(p_blk_dev);
+ ASSERT(p_blk);
+ nrf_block_dev_ram_t const * p_ram_dev = CONTAINER_OF(p_blk_dev, nrf_block_dev_ram_t, block_dev);
+ nrf_block_dev_ram_config_t const * p_ram_config = &p_ram_dev->ram_config;
+ nrf_block_dev_ram_work_t const * p_work = p_ram_dev->p_work;
+
+ /*Synchronous operation*/
+ uint8_t * p_buff = p_ram_config->p_work_buffer;
+ p_buff += p_blk->blk_id * p_work->geometry.blk_size;
+
+ const void * p_src = (event == NRF_BLOCK_DEV_EVT_BLK_READ_DONE) ? p_buff : p_blk->p_buff;
+ void * p_dst = (event == NRF_BLOCK_DEV_EVT_BLK_READ_DONE) ? p_blk->p_buff : p_buff;
+
+ memcpy(p_dst, p_src, p_work->geometry.blk_size * p_blk->blk_count);
+
+ if (p_work->ev_handler)
+ {
+ /*Asynchronous operation (simulation)*/
+ const nrf_block_dev_event_t ev = {
+ event,
+ NRF_BLOCK_DEV_RESULT_SUCCESS,
+ p_blk,
+ p_work->p_context
+ };
+
+ p_work->ev_handler(p_blk_dev, &ev);
+ }
+
+ return NRF_SUCCESS;
+}
+
+static ret_code_t block_dev_ram_read_req(nrf_block_dev_t const * p_blk_dev,
+ nrf_block_req_t const * p_blk)
+{
+ return block_dev_ram_req(p_blk_dev, p_blk, NRF_BLOCK_DEV_EVT_BLK_READ_DONE);
+}
+
+static ret_code_t block_dev_ram_write_req(nrf_block_dev_t const * p_blk_dev,
+ nrf_block_req_t const * p_blk)
+{
+ return block_dev_ram_req(p_blk_dev, p_blk, NRF_BLOCK_DEV_EVT_BLK_WRITE_DONE);
+}
+
+static ret_code_t block_dev_ram_ioctl(nrf_block_dev_t const * p_blk_dev,
+ nrf_block_dev_ioctl_req_t req,
+ void * p_data)
+{
+ nrf_block_dev_ram_t const * p_ram_dev = CONTAINER_OF(p_blk_dev, nrf_block_dev_ram_t, block_dev);
+ switch (req)
+ {
+ case NRF_BLOCK_DEV_IOCTL_REQ_CACHE_FLUSH:
+ {
+ bool * p_flushing = p_data;
+ if (p_flushing)
+ {
+ *p_flushing = false;
+ }
+ return NRF_SUCCESS;
+ }
+ case NRF_BLOCK_DEV_IOCTL_REQ_INFO_STRINGS:
+ {
+ if (p_data == NULL)
+ {
+ return NRF_ERROR_INVALID_PARAM;
+ }
+
+ nrf_block_dev_info_strings_t const * * pp_strings = p_data;
+ *pp_strings = &p_ram_dev->info_strings;
+ return NRF_SUCCESS;
+ }
+ default:
+ break;
+ }
+
+ return NRF_ERROR_NOT_SUPPORTED;
+}
+
+
+static nrf_block_dev_geometry_t const * block_dev_ram_geometry(nrf_block_dev_t const * p_blk_dev)
+{
+ ASSERT(p_blk_dev);
+ nrf_block_dev_ram_t const * p_ram_dev = CONTAINER_OF(p_blk_dev, nrf_block_dev_ram_t, block_dev);
+ nrf_block_dev_ram_work_t const * p_work = p_ram_dev->p_work;
+
+ return &p_work->geometry;
+}
+
+const nrf_block_dev_ops_t nrf_block_device_ram_ops = {
+ .init = block_dev_ram_init,
+ .uninit = block_dev_ram_uninit,
+ .read_req = block_dev_ram_read_req,
+ .write_req = block_dev_ram_write_req,
+ .ioctl = block_dev_ram_ioctl,
+ .geometry = block_dev_ram_geometry,
+};
+
+
+/** @} */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/block_dev/ram/nrf_block_dev_ram.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/block_dev/ram/nrf_block_dev_ram.h
new file mode 100644
index 0000000..d8046dc
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/block_dev/ram/nrf_block_dev_ram.h
@@ -0,0 +1,140 @@
+/**
+ * Copyright (c) 2016 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#ifndef NRF_BLOCK_DEV_RAM_H__
+#define NRF_BLOCK_DEV_RAM_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "nrf_block_dev.h"
+
+/**@file
+ *
+ * @defgroup nrf_block_dev_ram RAM implementation
+ * @ingroup nrf_block_dev
+ * @{
+
+ *
+ * @brief This module implements block device API. It should be used as a reference block device.
+ */
+
+/**
+ * @brief RAM block device operations
+ * */
+extern const nrf_block_dev_ops_t nrf_block_device_ram_ops;
+
+/**
+ * @brief Work structure of RAM block device
+ */
+typedef struct {
+ nrf_block_dev_geometry_t geometry; //!< Block device geometry
+ nrf_block_dev_ev_handler ev_handler; //!< Block device event handler
+ void const * p_context; //!< Context handle passed to event handler
+} nrf_block_dev_ram_work_t;
+
+
+/**
+ * @brief RAM block device config initializer (@ref nrf_block_dev_ram_config_t)
+ *
+ * @param blk_size Block size
+ * @param buffer RAM work buffer
+ * @param buffer_size RAM work buffer size
+ * */
+#define NRF_BLOCK_DEV_RAM_CONFIG(blk_size, buffer, buffer_size) { \
+ .block_size = (blk_size), \
+ .p_work_buffer = (buffer), \
+ .size = (buffer_size), \
+}
+
+/**
+ * @brief Ram block device config
+ */
+typedef struct {
+ uint32_t block_size; //!< Desired block size
+ void * p_work_buffer; //!< Ram work buffer
+ size_t size; //!< Ram work buffer size
+} nrf_block_dev_ram_config_t;
+
+/**
+ * @brief Ram block device
+ * */
+typedef struct {
+ nrf_block_dev_t block_dev; //!< Block device
+ nrf_block_dev_info_strings_t info_strings; //!< Block device information strings
+ nrf_block_dev_ram_config_t ram_config; //!< Ram block device config
+ nrf_block_dev_ram_work_t * p_work; //!< Ram block device work structure
+} nrf_block_dev_ram_t;
+
+/**
+ * @brief Defines a RAM block device.
+ *
+ * @param name Instance name
+ * @param config Configuration @ref nrf_block_dev_ram_config_t
+ * @param info Info strings @ref NFR_BLOCK_DEV_INFO_CONFIG
+ * */
+#define NRF_BLOCK_DEV_RAM_DEFINE(name, config, info) \
+ static nrf_block_dev_ram_work_t CONCAT_2(name, _work); \
+ static const nrf_block_dev_ram_t name = { \
+ .block_dev = { .p_ops = &nrf_block_device_ram_ops }, \
+ .info_strings = BRACKET_EXTRACT(info), \
+ .ram_config = config, \
+ .p_work = &CONCAT_2(name, _work), \
+ }
+
+/**
+ * @brief Returns block device API handle from RAM block device.
+ *
+ * @param[in] p_blk_ram Ram block device
+ * @return Block device handle
+ */
+static inline nrf_block_dev_t const *
+nrf_block_dev_ram_ops_get(nrf_block_dev_ram_t const * p_blk_ram)
+{
+ return &p_blk_ram->block_dev;
+}
+
+/** @} */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* NRF_BLOCK_DEV_RAM_H__ */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/block_dev/sdc/nrf_block_dev_sdc.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/block_dev/sdc/nrf_block_dev_sdc.c
new file mode 100644
index 0000000..126321f
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/block_dev/sdc/nrf_block_dev_sdc.c
@@ -0,0 +1,392 @@
+/**
+ * Copyright (c) 2016 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#include "nrf_block_dev_sdc.h"
+
+/**@file
+ *
+ * @ingroup nrf_block_dev_sdc
+ * @{
+ *
+ * @brief This module implements block device API. It should be used as a reference block device.
+ */
+
+
+static volatile sdc_result_t m_last_result;
+
+
+/**
+ * @brief Active SDC block device handle. Only one instance.
+ * */
+static nrf_block_dev_sdc_t const * m_active_sdc_dev;
+
+
+
+static void wait_func(void)
+{
+}
+
+static void sdc_wait()
+{
+ while (app_sdc_busy_check())
+ {
+ wait_func();
+ }
+}
+
+
+static void sdc_handler(sdc_evt_t const * p_event)
+{
+ m_last_result = p_event->result;
+ nrf_block_dev_sdc_t const * p_sdc_dev = m_active_sdc_dev;
+ nrf_block_dev_sdc_work_t * p_work = p_sdc_dev->p_work;
+
+ switch (p_event->type)
+ {
+ case SDC_EVT_INIT:
+ {
+ p_work->geometry.blk_count = app_sdc_info_get()->num_blocks;
+ p_work->geometry.blk_size = SDC_SECTOR_SIZE;
+ if (m_active_sdc_dev->p_work->ev_handler)
+ {
+ const nrf_block_dev_event_t ev = {
+ NRF_BLOCK_DEV_EVT_INIT,
+ ((p_event->result == SDC_SUCCESS) ? \
+ NRF_BLOCK_DEV_RESULT_SUCCESS : NRF_BLOCK_DEV_RESULT_IO_ERROR),
+ NULL,
+ p_work->p_context
+ };
+ p_work->ev_handler(&p_sdc_dev->block_dev, &ev);
+ }
+ }
+ break;
+
+ case SDC_EVT_READ:
+ if (m_active_sdc_dev->p_work->ev_handler)
+ {
+ const nrf_block_dev_event_t ev = {
+ NRF_BLOCK_DEV_EVT_BLK_READ_DONE,
+ ((p_event->result == SDC_SUCCESS) ? \
+ NRF_BLOCK_DEV_RESULT_SUCCESS : NRF_BLOCK_DEV_RESULT_IO_ERROR),
+ &p_work->req,
+ p_work->p_context
+ };
+ p_work->ev_handler(&p_sdc_dev->block_dev, &ev);
+ }
+ break;
+
+ case SDC_EVT_WRITE:
+ if (m_active_sdc_dev->p_work->ev_handler)
+ {
+ const nrf_block_dev_event_t ev = {
+ NRF_BLOCK_DEV_EVT_BLK_WRITE_DONE,
+ ((p_event->result == SDC_SUCCESS) ? \
+ NRF_BLOCK_DEV_RESULT_SUCCESS : NRF_BLOCK_DEV_RESULT_IO_ERROR),
+ &p_work->req,
+ p_work->p_context
+ };
+ p_work->ev_handler(&p_sdc_dev->block_dev, &ev);
+ }
+ break;
+
+ default:
+ APP_ERROR_CHECK(NRF_ERROR_INTERNAL);
+ return;
+ }
+}
+
+
+static ret_code_t block_dev_sdc_init(nrf_block_dev_t const * p_blk_dev,
+ nrf_block_dev_ev_handler ev_handler,
+ void const * p_context)
+{
+ ASSERT(p_blk_dev);
+ nrf_block_dev_sdc_t const * p_sdc_dev =
+ CONTAINER_OF(p_blk_dev, nrf_block_dev_sdc_t, block_dev);
+ nrf_block_dev_sdc_work_t * p_work = p_sdc_dev->p_work;
+
+ if (p_sdc_dev->sdc_bdev_config.block_size != SDC_SECTOR_SIZE)
+ {
+ /* Unsupported block size. */
+ return NRF_ERROR_NOT_SUPPORTED;
+ }
+
+ if (m_active_sdc_dev)
+ {
+ /* SDC instance is busy. */
+ return NRF_ERROR_BUSY;
+ }
+
+ p_work->p_context = p_context;
+ p_work->ev_handler = ev_handler;
+ m_active_sdc_dev = p_sdc_dev;
+
+ ret_code_t err_code = NRF_SUCCESS;
+
+ err_code = app_sdc_init(&p_sdc_dev->sdc_bdev_config.sdc_config, sdc_handler);
+ if (err_code == NRF_SUCCESS)
+ {
+ if (!ev_handler)
+ {
+ /* Synchronous mode - wait for the card. */
+ sdc_wait();
+ err_code = ((m_last_result == SDC_SUCCESS) ? NRF_SUCCESS : NRF_ERROR_TIMEOUT);
+ }
+ }
+
+ if (err_code != NRF_SUCCESS)
+ {
+ m_active_sdc_dev = NULL;
+
+ if (ev_handler)
+ {
+ /* Call the user handler with an error status. */
+ const nrf_block_dev_event_t ev = {
+ NRF_BLOCK_DEV_EVT_INIT,
+ NRF_BLOCK_DEV_RESULT_IO_ERROR,
+ NULL,
+ p_work->p_context
+ };
+ p_work->ev_handler(p_blk_dev, &ev);
+ }
+ }
+
+ return err_code;
+}
+
+static ret_code_t block_dev_sdc_uninit(nrf_block_dev_t const * p_blk_dev)
+{
+ ASSERT(p_blk_dev);
+ nrf_block_dev_sdc_t const * p_sdc_dev =
+ CONTAINER_OF(p_blk_dev, nrf_block_dev_sdc_t, block_dev);
+ nrf_block_dev_sdc_work_t * p_work = p_sdc_dev->p_work;
+
+ if (m_active_sdc_dev != p_sdc_dev)
+ {
+ /* SDC instance is busy. */
+ return NRF_ERROR_BUSY;
+ }
+
+ if (app_sdc_busy_check())
+ {
+ /* Previous asynchronous operation in progress. */
+ return NRF_ERROR_BUSY;
+ }
+
+ ret_code_t err_code = app_sdc_uninit();
+ if (err_code == NRF_SUCCESS)
+ {
+ /* Free the instance on success. */
+ m_active_sdc_dev = NULL;
+ }
+
+ if (p_work->ev_handler)
+ {
+ /* SDC uninitialization is a synchronous operation. Call event handler. */
+ const nrf_block_dev_event_t ev = {
+ NRF_BLOCK_DEV_EVT_UNINIT,
+ ((err_code == NRF_SUCCESS) ? \
+ NRF_BLOCK_DEV_RESULT_SUCCESS : NRF_BLOCK_DEV_RESULT_IO_ERROR),
+ NULL,
+ p_work->p_context
+ };
+
+ p_work->ev_handler(p_blk_dev, &ev);
+ }
+
+ return err_code;
+}
+
+static ret_code_t block_dev_sdc_read_req(nrf_block_dev_t const * p_blk_dev,
+ nrf_block_req_t const * p_blk)
+{
+ ASSERT(p_blk_dev);
+ ASSERT(p_blk);
+ nrf_block_dev_sdc_t const * p_sdc_dev =
+ CONTAINER_OF(p_blk_dev, nrf_block_dev_sdc_t, block_dev);
+ nrf_block_dev_sdc_work_t * p_work = p_sdc_dev->p_work;
+
+ ret_code_t err_code = NRF_SUCCESS;
+
+ if (m_active_sdc_dev != p_sdc_dev)
+ {
+ /* SDC instance is busy. */
+ return NRF_ERROR_BUSY;
+ }
+
+ if (app_sdc_busy_check())
+ {
+ /* Previous asynchronous operation in progress. */
+ return NRF_ERROR_BUSY;
+ }
+
+ p_work->req = *p_blk;
+ err_code = app_sdc_block_read(p_blk->p_buff, p_blk->blk_id, p_blk->blk_count);
+ if (err_code == NRF_SUCCESS)
+ {
+ if (!p_work->ev_handler)
+ {
+ /* Synchronous mode - wait for the card. */
+ sdc_wait();
+ err_code = ((m_last_result == SDC_SUCCESS) ? NRF_SUCCESS : NRF_ERROR_TIMEOUT);
+ }
+ }
+
+ if ((p_work->ev_handler) && (err_code != NRF_SUCCESS))
+ {
+ /* Call the user handler with an error status. */
+ const nrf_block_dev_event_t ev = {
+ NRF_BLOCK_DEV_EVT_BLK_READ_DONE,
+ NRF_BLOCK_DEV_RESULT_IO_ERROR,
+ &p_work->req,
+ p_work->p_context
+ };
+ p_work->ev_handler(p_blk_dev, &ev);
+ }
+
+ return err_code;
+}
+
+static ret_code_t block_dev_sdc_write_req(nrf_block_dev_t const * p_blk_dev,
+ nrf_block_req_t const * p_blk)
+{
+ ASSERT(p_blk_dev);
+ ASSERT(p_blk);
+ nrf_block_dev_sdc_t const * p_sdc_dev =
+ CONTAINER_OF(p_blk_dev, nrf_block_dev_sdc_t, block_dev);
+ nrf_block_dev_sdc_work_t * p_work = p_sdc_dev->p_work;
+
+ ret_code_t err_code = NRF_SUCCESS;
+
+ if (m_active_sdc_dev != p_sdc_dev)
+ {
+ /* SDC instance is busy. */
+ return NRF_ERROR_BUSY;
+ }
+
+ if (app_sdc_busy_check())
+ {
+ /* Previous asynchronous operation in progress. */
+ return NRF_ERROR_BUSY;
+ }
+
+ p_work->req = *p_blk;
+ err_code = app_sdc_block_write(p_blk->p_buff, p_blk->blk_id, p_blk->blk_count);
+ if (err_code == NRF_SUCCESS)
+ {
+ if (!p_work->ev_handler)
+ {
+ /* Synchronous mode - wait for the card. */
+ sdc_wait();
+ err_code = ((m_last_result == SDC_SUCCESS) ? NRF_SUCCESS : NRF_ERROR_TIMEOUT);
+ }
+ }
+
+ if ((p_work->ev_handler) && (err_code != NRF_SUCCESS))
+ {
+ /* Call the user handler with an error status. */
+ const nrf_block_dev_event_t ev = {
+ NRF_BLOCK_DEV_EVT_BLK_READ_DONE,
+ NRF_BLOCK_DEV_RESULT_IO_ERROR,
+ &p_work->req,
+ p_work->p_context
+ };
+ p_work->ev_handler(p_blk_dev, &ev);
+ }
+
+ return err_code;
+}
+
+static ret_code_t block_dev_sdc_ioctl(nrf_block_dev_t const * p_blk_dev,
+ nrf_block_dev_ioctl_req_t req,
+ void * p_data)
+{
+ nrf_block_dev_sdc_t const * p_sdc_dev =
+ CONTAINER_OF(p_blk_dev, nrf_block_dev_sdc_t, block_dev);
+ switch (req)
+ {
+ case NRF_BLOCK_DEV_IOCTL_REQ_CACHE_FLUSH:
+ {
+ bool * p_flushing = p_data;
+ if (p_flushing)
+ {
+ *p_flushing = false;
+ }
+ return NRF_SUCCESS;
+ }
+ case NRF_BLOCK_DEV_IOCTL_REQ_INFO_STRINGS:
+ {
+ if (p_data == NULL)
+ {
+ return NRF_ERROR_INVALID_PARAM;
+ }
+
+ nrf_block_dev_info_strings_t const * * pp_strings = p_data;
+ *pp_strings = &p_sdc_dev->info_strings;
+ return NRF_SUCCESS;
+ }
+ default:
+ break;
+ }
+
+
+ return NRF_ERROR_NOT_SUPPORTED;
+}
+
+static nrf_block_dev_geometry_t const * block_dev_sdc_geometry(nrf_block_dev_t const * p_blk_dev)
+{
+ ASSERT(p_blk_dev);
+ nrf_block_dev_sdc_t const * p_sdc_dev =
+ CONTAINER_OF(p_blk_dev, nrf_block_dev_sdc_t, block_dev);
+ nrf_block_dev_sdc_work_t const * p_work = p_sdc_dev->p_work;
+
+ return &p_work->geometry;
+}
+
+const nrf_block_dev_ops_t nrf_block_device_sdc_ops = {
+ .init = block_dev_sdc_init,
+ .uninit = block_dev_sdc_uninit,
+ .read_req = block_dev_sdc_read_req,
+ .write_req = block_dev_sdc_write_req,
+ .ioctl = block_dev_sdc_ioctl,
+ .geometry = block_dev_sdc_geometry,
+};
+
+
+/** @} */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/block_dev/sdc/nrf_block_dev_sdc.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/block_dev/sdc/nrf_block_dev_sdc.h
new file mode 100644
index 0000000..cab8032
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/block_dev/sdc/nrf_block_dev_sdc.h
@@ -0,0 +1,139 @@
+/**
+ * Copyright (c) 2016 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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
+ *
+ * @defgroup nrf_block_dev_sdc SDC implementation
+ * @ingroup nrf_block_dev
+ * @{
+ *
+ */
+
+
+#ifndef NRF_BLOCK_DEV_SDC_H__
+#define NRF_BLOCK_DEV_SDC_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "nrf_block_dev.h"
+#include "app_sdcard.h"
+
+/**
+ * @brief SDC block device operations
+ * */
+extern const nrf_block_dev_ops_t nrf_block_device_sdc_ops;
+
+/**
+ * @brief Work structure of SDC block device
+ */
+typedef struct {
+ nrf_block_dev_geometry_t geometry; //!< Block device geometry
+ nrf_block_dev_ev_handler ev_handler; //!< Block device event handler
+ nrf_block_req_t req; //!< Block READ/WRITE request
+ void const * p_context; //!< Context handle passed to event handler
+} nrf_block_dev_sdc_work_t;
+
+/**
+ * @brief SDC block device config initializer (@ref nrf_block_dev_sdc_config_t)
+ *
+ * @param blk_size Block size
+ * @param sdc_lib_config SDC library config (@ref app_sdc_config_t)
+ * */
+#define NRF_BLOCK_DEV_SDC_CONFIG(blk_size, sdc_lib_config) \
+{ \
+ .block_size = (blk_size), \
+ .sdc_config = sdc_lib_config \
+}
+
+
+/**
+ * @brief SDC block device config
+ */
+typedef struct {
+ uint32_t block_size; //!< Desired block size
+ app_sdc_config_t sdc_config; //!< SDC library configuration
+} nrf_block_dev_sdc_config_t;
+
+/**
+ * @brief SDC block device
+ * */
+typedef struct {
+ nrf_block_dev_t block_dev; //!< Block device
+ nrf_block_dev_info_strings_t info_strings; //!< Block device information strings
+ nrf_block_dev_sdc_config_t sdc_bdev_config; //!< SDC block device config
+ nrf_block_dev_sdc_work_t * p_work; //!< SDC block device work structure
+} nrf_block_dev_sdc_t;
+
+/**
+ * @brief Defines a SDC block device.
+ *
+ * @param name Instance name
+ * @param config Configuration @ref nrf_block_dev_sdc_config_t
+ * @param info Info strings @ref NFR_BLOCK_DEV_INFO_CONFIG
+ * */
+#define NRF_BLOCK_DEV_SDC_DEFINE(name, config, info) \
+ static nrf_block_dev_sdc_work_t CONCAT_2(name, _work); \
+ static const nrf_block_dev_sdc_t name = { \
+ .block_dev = { .p_ops = &nrf_block_device_sdc_ops }, \
+ .info_strings = BRACKET_EXTRACT(info), \
+ .sdc_bdev_config = config, \
+ .p_work = &CONCAT_2(name, _work), \
+ }
+
+/**
+ * @brief Returns block device API handle from SDC block device.
+ *
+ * @param[in] p_blk_sdc SDC block device
+ * @return Block device handle
+ */
+static inline nrf_block_dev_t const *
+nrf_block_dev_sdc_ops_get(nrf_block_dev_sdc_t const * p_blk_sdc)
+{
+ return &p_blk_sdc->block_dev;
+}
+
+/** @} */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* NRF_BLOCK_DEV_SDC_H__ */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/ble_dfu/nrf_dfu_ble.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/ble_dfu/nrf_dfu_ble.c
new file mode 100644
index 0000000..44b0072
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/ble_dfu/nrf_dfu_ble.c
@@ -0,0 +1,1238 @@
+/**
+ * Copyright (c) 2016 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#include "nrf_dfu_ble.h"
+
+#include <stddef.h>
+#include "sdk_common.h"
+#include "nrf_dfu_transport.h"
+#include "nrf_dfu_types.h"
+#include "nrf_dfu_req_handler.h"
+#include "nrf_dfu_handling_error.h"
+#include "nrf_sdm.h"
+#include "nrf_dfu_mbr.h"
+#include "nrf_bootloader_info.h"
+#include "ble.h"
+#include "ble_srv_common.h"
+#include "ble_hci.h"
+#include "nrf_sdh.h"
+#include "nrf_sdh_ble.h"
+#include "nrf_balloc.h"
+#include "nrf_delay.h"
+#include "nrf_dfu_settings.h"
+
+#define NRF_LOG_MODULE_NAME nrf_dfu_ble
+#include "nrf_log.h"
+NRF_LOG_MODULE_REGISTER();
+
+
+#define APP_BLE_CONN_CFG_TAG 1 /**< A tag identifying the SoftDevice BLE configuration. */
+
+#define APP_ADV_DATA_HEADER_SIZE 9 /**< Size of encoded advertisement data header (not including device name). */
+#define APP_ADV_DURATION BLE_GAP_ADV_TIMEOUT_GENERAL_UNLIMITED /**< The advertising duration in units of 10 milliseconds. This is set to @ref BLE_GAP_ADV_TIMEOUT_GENERAL_UNLIMITED so that the advertisement is done as long as there there is a call to @ref dfu_transport_close function.*/
+#define APP_ADV_INTERVAL MSEC_TO_UNITS(25, UNIT_0_625_MS) /**< The advertising interval (25 ms.). */
+
+#define GATT_HEADER_LEN 3 /**< GATT header length. */
+#define GATT_PAYLOAD(mtu) ((mtu) - GATT_HEADER_LEN) /**< Length of the ATT payload for a given ATT MTU. */
+#define MAX_DFU_PKT_LEN (NRF_SDH_BLE_GATT_MAX_MTU_SIZE - GATT_HEADER_LEN) /**< Maximum length (in bytes) of the DFU Packet characteristic (3 bytes are used for the GATT opcode and handle). */
+#define MAX_RESPONSE_LEN 17 /**< Maximum length (in bytes) of the response to a Control Point command. */
+#define RESPONSE_HEADER_LEN 3 /**< The length of the header of a response. I.E. the index of the opcode-specific payload. */
+
+#define DFU_BLE_FLAG_INITIALIZED (1 << 0) /**< Flag to check if the DFU service was initialized by the application.*/
+#define DFU_BLE_FLAG_USE_ADV_NAME (1 << 1) /**< Flag to indicate that advertisement name is to be used. */
+#define DFU_BLE_RESETTING_SOON (1 << 2) /**< Flag to indicate that the device will reset soon. */
+
+#define BLE_OBSERVER_PRIO 2 /**< BLE observer priority. Controls the priority for BLE event handler. */
+
+#if (NRF_DFU_BLE_BUFFERS_OVERRIDE)
+/* If selected, use the override value. */
+#define MAX_DFU_BUFFERS NRF_DFU_BLE_BUFFERS
+#else
+#define MAX_DFU_BUFFERS ((CODE_PAGE_SIZE / MAX_DFU_PKT_LEN) + 1)
+#endif
+
+#if (NRF_DFU_BLE_REQUIRES_BONDS) && (!NRF_SDH_BLE_SERVICE_CHANGED)
+#error NRF_DFU_BLE_REQUIRES_BONDS requires NRF_SDH_BLE_SERVICE_CHANGED. \
+ Please update the SoftDevice BLE stack configuration in sdk_config.h
+#endif
+
+#if (MAX_DFU_PKT_LEN % 4)
+#error Payload length should be a multiple of four. \
+ Payload length is set to NRF_SDH_BLE_GATT_MAX_MTU_SIZE - 3.
+#endif
+
+
+static uint32_t ble_dfu_transport_init(nrf_dfu_observer_t observer);
+static uint32_t ble_dfu_transport_close(nrf_dfu_transport_t const * p_exception);
+
+DFU_TRANSPORT_REGISTER(nrf_dfu_transport_t const ble_dfu_transport) =
+{
+ .init_func = ble_dfu_transport_init,
+ .close_func = ble_dfu_transport_close,
+};
+
+#if (NRF_DFU_BLE_REQUIRES_BONDS)
+static nrf_dfu_peer_data_t m_peer_data;
+#else
+static nrf_dfu_adv_name_t m_adv_name;
+#endif
+
+static uint32_t m_flags;
+static ble_dfu_t m_dfu; /**< Structure used to identify the Device Firmware Update service. */
+static uint16_t m_pkt_notif_target; /**< Number of packets of firmware data to be received before transmitting the next Packet Receipt Notification to the DFU Controller. */
+static uint16_t m_pkt_notif_target_cnt; /**< Number of packets of firmware data received after sending last Packet Receipt Notification or since the receipt of a @ref BLE_DFU_PKT_RCPT_NOTIF_ENABLED event from the DFU service, which ever occurs later.*/
+static uint16_t m_conn_handle = BLE_CONN_HANDLE_INVALID; /**< Handle of the current connection. */
+static uint8_t m_adv_handle = BLE_GAP_ADV_SET_HANDLE_NOT_SET; /**< Advertising handle used to identify an advertising set. */
+static nrf_dfu_observer_t m_observer; /**< Observer function called on certain events. */
+
+static ble_gap_conn_params_t const m_gap_conn_params =
+{
+ .min_conn_interval = NRF_DFU_BLE_MIN_CONN_INTERVAL,
+ .max_conn_interval = NRF_DFU_BLE_MAX_CONN_INTERVAL,
+ /* This value is expressed in units of 10 ms, rather than 1 ms. */
+ .conn_sup_timeout = NRF_DFU_BLE_CONN_SUP_TIMEOUT_MS / 10,
+ .slave_latency = 0,
+};
+
+NRF_BALLOC_DEF(m_buffer_pool, MAX_DFU_PKT_LEN, MAX_DFU_BUFFERS);
+
+
+/**@brief Function for the Advertising functionality initialization.
+ *
+ * @details Encodes the required advertising data and passes it to the stack.
+ * The advertising data encoded here is specific for DFU.
+ */
+static uint32_t advertising_init(uint8_t adv_flags, ble_gap_adv_params_t const * const p_adv_params)
+{
+ uint32_t err_code;
+ uint16_t actual_device_name_length = BLE_GAP_ADV_SET_DATA_SIZE_MAX - APP_ADV_DATA_HEADER_SIZE;
+
+ /* This needs to be static because of SoftDevice API requirements. */
+ static uint8_t m_enc_advdata[BLE_GAP_ADV_SET_DATA_SIZE_MAX];
+
+ ble_gap_adv_data_t m_adv_data =
+ {
+ .adv_data =
+ {
+ .p_data = m_enc_advdata,
+ .len = APP_ADV_DATA_HEADER_SIZE,
+ }
+ };
+
+ /* Encode flags. */
+ m_enc_advdata[0] = 0x2;
+ m_enc_advdata[1] = BLE_GAP_AD_TYPE_FLAGS;
+ m_enc_advdata[2] = adv_flags;
+
+ /* Encode 'more available' UUID list. */
+ m_enc_advdata[3] = 0x3;
+ m_enc_advdata[4] = BLE_GAP_AD_TYPE_16BIT_SERVICE_UUID_MORE_AVAILABLE;
+ m_enc_advdata[5] = LSB_16(BLE_DFU_SERVICE_UUID);
+ m_enc_advdata[6] = MSB_16(BLE_DFU_SERVICE_UUID);
+
+ /* Get GAP device name and length. */
+ err_code = sd_ble_gap_device_name_get(&m_enc_advdata[9], &actual_device_name_length);
+ if (err_code != NRF_SUCCESS)
+ {
+ return err_code;
+ }
+
+ // Set GAP device in advertising data.
+ m_enc_advdata[7] = actual_device_name_length + 1; // (actual_length + ADV_AD_TYPE_FIELD_SIZE(1))
+ m_enc_advdata[8] = BLE_GAP_AD_TYPE_COMPLETE_LOCAL_NAME;
+
+ m_adv_data.adv_data.len += actual_device_name_length;
+
+ return sd_ble_gap_adv_set_configure(&m_adv_handle, &m_adv_data, p_adv_params);
+}
+
+
+/**@brief Function for starting advertising.
+ */
+static uint32_t advertising_start(void)
+{
+ uint32_t err_code;
+ uint8_t adv_flag = BLE_GAP_ADV_FLAGS_LE_ONLY_GENERAL_DISC_MODE;
+
+ ble_gap_adv_params_t adv_params =
+ {
+ .properties.type = BLE_GAP_ADV_TYPE_CONNECTABLE_SCANNABLE_UNDIRECTED,
+ .p_peer_addr = NULL,
+ .filter_policy = BLE_GAP_ADV_FP_ANY,
+ .interval = APP_ADV_INTERVAL,
+ .duration = APP_ADV_DURATION,
+ .primary_phy = BLE_GAP_PHY_1MBPS,
+ };
+
+ NRF_LOG_DEBUG("Advertising...");
+
+#if (NRF_DFU_BLE_REQUIRES_BONDS)
+ ble_gap_irk_t empty_irk = {{0}};
+
+ if (memcmp(m_peer_data.ble_id.id_info.irk, empty_irk.irk, sizeof(ble_gap_irk_t)) == 0)
+ {
+ NRF_LOG_DEBUG("No IRK found, general discovery");
+ }
+ else
+ {
+ NRF_LOG_DEBUG("IRK Found, setting up whitelist");
+
+ adv_flag = BLE_GAP_ADV_FLAG_BR_EDR_NOT_SUPPORTED;
+ adv_params.filter_policy = BLE_GAP_ADV_FP_FILTER_CONNREQ;
+
+ ble_gap_addr_t const * const p_gap_addr = &m_peer_data.ble_id.id_addr_info;
+ ble_gap_id_key_t const * const p_gap_id_key = &m_peer_data.ble_id;
+
+ err_code = sd_ble_gap_whitelist_set(&p_gap_addr, 1);
+ if (err_code != NRF_SUCCESS)
+ {
+ NRF_LOG_WARNING("sd_ble_gap_whitelist_set() returned %s",
+ NRF_LOG_ERROR_STRING_GET(err_code));
+ }
+
+ err_code = sd_ble_gap_device_identities_set(&p_gap_id_key, NULL, 1);
+ if (err_code != NRF_SUCCESS)
+ {
+ NRF_LOG_WARNING("sd_ble_gap_device_identities_set() returned %s",
+ NRF_LOG_ERROR_STRING_GET(err_code));
+ }
+ }
+#endif /* NRF_DFU_BLE_REQUIRES_BONDS */
+
+ err_code = advertising_init(adv_flag, &adv_params);
+ VERIFY_SUCCESS(err_code);
+
+ err_code = sd_ble_gap_adv_stop(m_adv_handle);
+ UNUSED_RETURN_VALUE(err_code);
+
+ return sd_ble_gap_adv_start(m_adv_handle, APP_BLE_CONN_CFG_TAG);
+}
+
+
+static bool is_cccd_configured(ble_dfu_t * p_dfu)
+{
+ uint8_t cccd_val_buf[BLE_CCCD_VALUE_LEN];
+
+ ble_gatts_value_t gatts_value =
+ {
+ .len = BLE_CCCD_VALUE_LEN,
+ .p_value = cccd_val_buf
+ };
+
+ /* Check the CCCD Value of DFU Control Point. */
+ uint32_t err_code = sd_ble_gatts_value_get(m_conn_handle,
+ p_dfu->dfu_ctrl_pt_handles.cccd_handle,
+ &gatts_value);
+ VERIFY_SUCCESS(err_code);
+
+ return ble_srv_is_notification_enabled(cccd_val_buf);
+}
+
+
+static ret_code_t response_send(uint8_t * p_buf, uint16_t len)
+{
+ ble_gatts_hvx_params_t hvx_params =
+ {
+ .handle = m_dfu.dfu_ctrl_pt_handles.value_handle,
+ .type = BLE_GATT_HVX_NOTIFICATION,
+ .p_data = (uint8_t *)(p_buf),
+ .p_len = &len,
+ };
+
+ return sd_ble_gatts_hvx(m_conn_handle, &hvx_params);
+}
+
+
+#if (NRF_DFU_BLE_REQUIRES_BONDS)
+static uint32_t service_changed_send(void)
+{
+ uint32_t err_code;
+
+ NRF_LOG_DEBUG("Sending Service Changed indication");
+
+ err_code = sd_ble_gatts_sys_attr_set(m_conn_handle,
+ m_peer_data.sys_serv_attr,
+ sizeof(m_peer_data.sys_serv_attr),
+ BLE_GATTS_SYS_ATTR_FLAG_SYS_SRVCS);
+ VERIFY_SUCCESS(err_code);
+
+ err_code = sd_ble_gatts_sys_attr_set(m_conn_handle,
+ NULL,
+ 0,
+ BLE_GATTS_SYS_ATTR_FLAG_USR_SRVCS);
+ VERIFY_SUCCESS(err_code);
+
+ err_code = sd_ble_gatts_service_changed(m_conn_handle, m_dfu.service_handle, 0xFFFF);
+
+ if ( (err_code == BLE_ERROR_INVALID_CONN_HANDLE)
+ || (err_code == NRF_ERROR_INVALID_STATE)
+ || (err_code == NRF_ERROR_BUSY))
+ {
+ /* These errors can be expected when trying to send a Service Changed indication */
+ /* if the CCCD is not set to indicate. Thus, set the returning error code to success. */
+ NRF_LOG_WARNING("Client did not have the Service Changed indication set to enabled."
+ "Error: 0x%08x", err_code);
+ err_code = NRF_SUCCESS;
+ }
+
+ return err_code;
+}
+#endif
+
+
+/**@brief Function for encoding the beginning of a response.
+ *
+ * @param[inout] p_buffer The buffer to encode into.
+ * @param[in] op_code The opcode of the response.
+ * @param[in] result The result of the operation.
+ *
+ * @return The length added to the buffer.
+ */
+static uint32_t response_prepare(uint8_t * p_buffer, uint8_t op_code, uint8_t result)
+{
+ ASSERT(p_buffer);
+ p_buffer[0] = NRF_DFU_OP_RESPONSE;
+ p_buffer[1] = op_code;
+ p_buffer[2] = result;
+ return RESPONSE_HEADER_LEN;
+}
+
+
+/**@brief Function for encoding a select object response into a buffer.
+ *
+ * The select object response consists of a maximum object size, a firmware offset, and a CRC value.
+ *
+ * @param[inout] p_buffer The buffer to encode the response into.
+ * @param[in] max_size The maximum object size value to encode.
+ * @param[in] fw_offset The firmware offset value to encode.
+ * @param[in] crc The CRC value to encode.
+ *
+ * @return The length added to the buffer.
+ */
+static uint32_t response_select_obj_add(uint8_t * p_buffer,
+ uint32_t max_size,
+ uint32_t fw_offset,
+ uint32_t crc)
+{
+ uint16_t offset = uint32_encode(max_size, &p_buffer[RESPONSE_HEADER_LEN]);
+ offset += uint32_encode(fw_offset, &p_buffer[RESPONSE_HEADER_LEN + offset]);
+ offset += uint32_encode(crc, &p_buffer[RESPONSE_HEADER_LEN + offset]);
+ return offset;
+}
+
+
+/**@brief Function for encoding a CRC response into a buffer.
+ *
+ * The CRC response consists of a firmware offset and a CRC value.
+ *
+ * @param[inout] p_buffer The buffer to encode the response into.
+ * @param[in] fw_offset The firmware offset value to encode.
+ * @param[in] crc The CRC value to encode.
+ *
+ * @return The length added to the buffer.
+ */
+static uint32_t response_crc_add(uint8_t * p_buffer, uint32_t fw_offset, uint32_t crc)
+{
+ uint16_t offset = uint32_encode(fw_offset, &p_buffer[RESPONSE_HEADER_LEN]);
+ offset += uint32_encode(crc, &p_buffer[RESPONSE_HEADER_LEN + offset]);
+ return offset;
+}
+
+
+/**@brief Function for appending an extended error code to the response buffer.
+ *
+ * @param[inout] p_buffer The buffer to append the extended error code to.
+ * @param[in] result The error code to append.
+ * @param[in] buf_offset The current length of the buffer.
+ *
+ * @return The length added to the buffer.
+ */
+static uint32_t response_ext_err_payload_add(uint8_t * p_buffer, uint8_t result, uint32_t buf_offset)
+{
+ p_buffer[buf_offset] = ext_error_get();
+ (void) ext_error_set(NRF_DFU_EXT_ERROR_NO_ERROR);
+ return 1;
+}
+
+
+static void ble_dfu_req_handler_callback(nrf_dfu_response_t * p_res, void * p_context)
+{
+ ASSERT(p_res);
+ ASSERT(p_context);
+
+ uint8_t len = 0;
+ uint8_t buffer[MAX_RESPONSE_LEN] = {0};
+
+ if (p_res->request == NRF_DFU_OP_OBJECT_WRITE)
+ {
+ --m_pkt_notif_target_cnt;
+ if ((m_pkt_notif_target == 0) || (m_pkt_notif_target_cnt && m_pkt_notif_target > 0))
+ {
+ return;
+ }
+
+ /* Reply with a CRC message and reset the packet counter. */
+ m_pkt_notif_target_cnt = m_pkt_notif_target;
+
+ p_res->request = NRF_DFU_OP_CRC_GET;
+ }
+
+ len += response_prepare(buffer, p_res->request, p_res->result);
+
+ if (p_res->result != NRF_DFU_RES_CODE_SUCCESS)
+ {
+ NRF_LOG_WARNING("DFU request %d failed with error: 0x%x", p_res->request, p_res->result);
+
+ if (p_res->result == NRF_DFU_RES_CODE_EXT_ERROR)
+ {
+ len += response_ext_err_payload_add(buffer, p_res->result, len);
+ }
+
+ (void) response_send(buffer, len);
+ return;
+ }
+
+ switch (p_res->request)
+ {
+ case NRF_DFU_OP_OBJECT_CREATE:
+ case NRF_DFU_OP_OBJECT_EXECUTE:
+ break;
+
+ case NRF_DFU_OP_OBJECT_SELECT:
+ {
+ len += response_select_obj_add(buffer,
+ p_res->select.max_size,
+ p_res->select.offset,
+ p_res->select.crc);
+ } break;
+
+ case NRF_DFU_OP_OBJECT_WRITE:
+ {
+ len += response_crc_add(buffer, p_res->write.offset, p_res->write.crc);
+ } break;
+
+ case NRF_DFU_OP_CRC_GET:
+ {
+ len += response_crc_add(buffer, p_res->crc.offset, p_res->crc.crc);
+ } break;
+
+ default:
+ {
+ // No action.
+ } break;
+ }
+
+ (void) response_send(buffer, len);
+}
+
+
+/**@brief Function for handling a Write event on the Control Point characteristic.
+ *
+ * @param[in] p_dfu DFU Service Structure.
+ * @param[in] p_ble_write_evt Pointer to the write event received from BLE stack.
+ *
+ * @return NRF_SUCCESS on successful processing of control point write. Otherwise an error code.
+ */
+static uint32_t on_ctrl_pt_write(ble_dfu_t * p_dfu, ble_gatts_evt_write_t const * p_ble_write_evt)
+{
+ //lint -save -e415 -e416 : Out-of-bounds access on p_ble_write_evt->data
+ nrf_dfu_request_t request =
+ {
+ .request = (nrf_dfu_op_t)(p_ble_write_evt->data[0]),
+ .p_context = p_dfu,
+ .callback.response = ble_dfu_req_handler_callback,
+ };
+
+ switch (request.request)
+ {
+ case NRF_DFU_OP_OBJECT_SELECT:
+ {
+ /* Set object type to read info about */
+ request.select.object_type = p_ble_write_evt->data[1];
+ } break;
+
+ case NRF_DFU_OP_OBJECT_CREATE:
+ {
+ /* Activity on the current transport. Close all except the current one. */
+ (void) nrf_dfu_transports_close(&ble_dfu_transport);
+
+ /* Reset the packet receipt notification on create object */
+ m_pkt_notif_target_cnt = m_pkt_notif_target;
+
+ request.create.object_type = p_ble_write_evt->data[1];
+ request.create.object_size = uint32_decode(&(p_ble_write_evt->data[2]));
+ } break;
+
+ case NRF_DFU_OP_RECEIPT_NOTIF_SET:
+ {
+ NRF_LOG_DEBUG("Set receipt notif");
+
+ m_pkt_notif_target = uint16_decode(&(p_ble_write_evt->data[1]));
+ m_pkt_notif_target_cnt = m_pkt_notif_target;
+ } break;
+
+ default:
+ break;
+ }
+ //lint -restore : Out-of-bounds access
+
+ return nrf_dfu_req_handler_on_req(&request);
+}
+
+
+/**@brief Function for handling the @ref BLE_GATTS_EVT_RW_AUTHORIZE_REQUEST event from the
+ * SoftDevice.
+ *
+ * @param[in] p_dfu DFU Service Structure.
+ * @param[in] p_ble_evt Pointer to the event received from BLE stack.
+ */
+static bool on_rw_authorize_req(ble_dfu_t * p_dfu, ble_evt_t const * p_ble_evt)
+{
+ uint32_t err_code;
+
+ ble_gatts_evt_rw_authorize_request_t const * p_authorize_request;
+ ble_gatts_evt_write_t const * p_ble_write_evt;
+
+ p_authorize_request = &(p_ble_evt->evt.gatts_evt.params.authorize_request);
+ p_ble_write_evt = &(p_ble_evt->evt.gatts_evt.params.authorize_request.request.write);
+
+ if ( (p_authorize_request->type != BLE_GATTS_AUTHORIZE_TYPE_WRITE)
+ || (p_authorize_request->request.write.handle != p_dfu->dfu_ctrl_pt_handles.value_handle)
+ || (p_authorize_request->request.write.op != BLE_GATTS_OP_WRITE_REQ))
+ {
+ return false;
+ }
+
+ ble_gatts_rw_authorize_reply_params_t auth_reply =
+ {
+ .type = BLE_GATTS_AUTHORIZE_TYPE_WRITE,
+ .params.write.update = 1,
+ .params.write.offset = p_ble_write_evt->offset,
+ .params.write.len = p_ble_write_evt->len,
+ .params.write.p_data = p_ble_write_evt->data,
+ };
+
+ if (!is_cccd_configured(p_dfu))
+ {
+ /* Send an error response to the peer indicating that the CCCD is improperly configured. */
+ auth_reply.params.write.gatt_status = BLE_GATT_STATUS_ATTERR_CPS_CCCD_CONFIG_ERROR;
+
+ /* Ignore response of auth reply */
+ (void) sd_ble_gatts_rw_authorize_reply(m_conn_handle, &auth_reply);
+ return false;
+ }
+ else
+ {
+ auth_reply.params.write.gatt_status = BLE_GATT_STATUS_SUCCESS;
+
+ err_code = sd_ble_gatts_rw_authorize_reply(m_conn_handle, &auth_reply);
+ return err_code == NRF_SUCCESS ? true : false;
+ }
+}
+
+
+static void on_flash_write(void * p_buf)
+{
+ NRF_LOG_DEBUG("Freeing buffer %p", p_buf);
+ nrf_balloc_free(&m_buffer_pool, p_buf);
+}
+
+
+/**@brief Function for handling the @ref BLE_GATTS_EVT_WRITE event from the SoftDevice.
+ *
+ * @param[in] p_dfu DFU Service Structure.
+ * @param[in] p_ble_evt Pointer to the event received from BLE stack.
+ */
+static void on_write(ble_dfu_t * p_dfu, ble_evt_t const * p_ble_evt)
+{
+ ble_gatts_evt_write_t const * const p_write_evt = &p_ble_evt->evt.gatts_evt.params.write;
+
+ if (p_write_evt->handle != p_dfu->dfu_pkt_handles.value_handle)
+ {
+ return;
+ }
+
+ /* Allocate a buffer to receive data. */
+ uint8_t * p_balloc_buf = nrf_balloc_alloc(&m_buffer_pool);
+ if (p_balloc_buf == NULL)
+ {
+ /* Operations are retried by the host; do not give up here. */
+ NRF_LOG_WARNING("cannot allocate memory buffer!");
+ return;
+ }
+
+ NRF_LOG_DEBUG("Buffer %p acquired, len %d (%d)",
+ p_balloc_buf, p_write_evt->len, MAX_DFU_PKT_LEN);
+
+ /* Copy payload into buffer. */
+ memcpy(p_balloc_buf, p_write_evt->data, p_write_evt->len);
+
+ /* Set up the request. */
+ nrf_dfu_request_t request =
+ {
+ .request = NRF_DFU_OP_OBJECT_WRITE,
+ .p_context = p_dfu,
+ .callback =
+ {
+ .response = ble_dfu_req_handler_callback,
+ .write = on_flash_write,
+ }
+ };
+
+ /* Set up the request buffer. */
+ request.write.p_data = p_balloc_buf;
+ request.write.len = p_write_evt->len;
+
+ /* Schedule handling of the request. */
+ ret_code_t rc = nrf_dfu_req_handler_on_req(&request);
+ if (rc != NRF_SUCCESS)
+ {
+ /* The error is logged in nrf_dfu_req_handler_on_req().
+ * Free the buffer.
+ */
+ (void) nrf_balloc_free(&m_buffer_pool, p_balloc_buf);
+ }
+}
+
+
+/**@brief Function for the Application's SoftDevice event handler.
+ *
+ * @param[in] p_ble_evt SoftDevice event.
+ */
+static void ble_evt_handler(ble_evt_t const * p_ble_evt, void * p_context)
+{
+ uint32_t err_code;
+ ble_gap_evt_t const * const p_gap = &p_ble_evt->evt.gap_evt;
+
+ switch (p_ble_evt->header.evt_id)
+ {
+ case BLE_GAP_EVT_CONNECTED:
+ {
+ NRF_LOG_DEBUG("Connected");
+
+ m_conn_handle = p_gap->conn_handle;
+
+ if (m_observer)
+ {
+ m_observer(NRF_DFU_EVT_TRANSPORT_ACTIVATED);
+ }
+
+ err_code = sd_ble_gap_conn_param_update(m_conn_handle, &m_gap_conn_params);
+ if (err_code != NRF_SUCCESS)
+ {
+ NRF_LOG_ERROR("Failure to update connection parameters: 0x%x", err_code);
+ }
+ } break;
+
+ case BLE_GAP_EVT_DISCONNECTED:
+ {
+ m_conn_handle = BLE_CONN_HANDLE_INVALID;
+
+ /* Restart advertising so that the DFU Controller can reconnect if possible. */
+ if (!(m_flags & DFU_BLE_RESETTING_SOON))
+ {
+ err_code = advertising_start();
+ APP_ERROR_CHECK(err_code);
+ }
+
+ if (m_observer)
+ {
+ m_observer(NRF_DFU_EVT_TRANSPORT_DEACTIVATED);
+ }
+ } break;
+
+ case BLE_GATTS_EVT_WRITE:
+ {
+ on_write(&m_dfu, p_ble_evt);
+ } break;
+
+ case BLE_GATTS_EVT_EXCHANGE_MTU_REQUEST:
+ {
+ uint16_t const mtu_requested =
+ p_ble_evt->evt.gatts_evt.params.exchange_mtu_request.client_rx_mtu;
+
+ /* If the requested MTU is smaller than the maximum, we can accept with the given
+ * stack configuration, and the payload is not word-aligned, reply with a smaller MTU
+ * that has a word-aligned payload. This ensures that the length of data we write to
+ * flash is a multiple of the word size.
+ */
+ uint16_t mtu_reply;
+
+ if (mtu_requested < NRF_SDH_BLE_GATT_MAX_MTU_SIZE)
+ {
+ /* Round the payload size down to a multiple of 4 so it is word-aligned. */
+ if (GATT_PAYLOAD(mtu_requested) % 4)
+ {
+ mtu_reply = GATT_PAYLOAD(mtu_requested) - 4;
+ mtu_reply = ALIGN_NUM(4, mtu_reply);
+ /* Add the header len to the MTU. */
+ mtu_reply += GATT_HEADER_LEN;
+ }
+ else
+ {
+ mtu_reply = mtu_requested;
+ }
+ }
+ else
+ {
+ mtu_reply = NRF_SDH_BLE_GATT_MAX_MTU_SIZE;
+ }
+
+ NRF_LOG_DEBUG("Received BLE_GATTS_EVT_EXCHANGE_MTU_REQUEST (request: %d, reply: %d).",
+ mtu_requested, mtu_reply);
+
+ err_code = sd_ble_gatts_exchange_mtu_reply(m_conn_handle, mtu_reply);
+ APP_ERROR_CHECK(err_code);
+ } break;
+
+ case BLE_GAP_EVT_DATA_LENGTH_UPDATE_REQUEST:
+ {
+ NRF_LOG_DEBUG("Received BLE_GAP_EVT_DATA_LENGTH_UPDATE_REQUEST.");
+
+ ble_gap_data_length_params_t const dlp =
+ {
+ .max_rx_octets = BLE_GAP_DATA_LENGTH_AUTO,
+ .max_tx_octets = BLE_GAP_DATA_LENGTH_AUTO,
+ };
+
+ err_code = sd_ble_gap_data_length_update(p_ble_evt->evt.gatts_evt.conn_handle,
+ &dlp, NULL);
+ APP_ERROR_CHECK(err_code);
+ } break;
+
+
+ case BLE_GAP_EVT_DATA_LENGTH_UPDATE:
+ {
+ NRF_LOG_DEBUG("Received BLE_GAP_EVT_DATA_LENGTH_UPDATE (%u, max_rx_time %u).",
+ p_gap->params.data_length_update.effective_params.max_rx_octets,
+ p_gap->params.data_length_update.effective_params.max_rx_time_us);
+ } break;
+
+ case BLE_GAP_EVT_SEC_PARAMS_REQUEST:
+ {
+ NRF_LOG_DEBUG("Received BLE_GAP_EVT_SEC_PARAMS_REQUEST");
+
+ uint16_t cccd;
+ ble_gatts_value_t gatts_value =
+ {
+ .len = BLE_CCCD_VALUE_LEN,
+ .p_value = (uint8_t*)&cccd
+ };
+
+ err_code = sd_ble_gatts_value_get(m_conn_handle,
+ BLE_UUID_GATT_CHARACTERISTIC_SERVICE_CHANGED,
+ &gatts_value);
+ APP_ERROR_CHECK(err_code);
+
+ NRF_LOG_DEBUG("CCCD for service changed is 0x%04x", cccd);
+
+ err_code = sd_ble_gap_sec_params_reply(m_conn_handle,
+ BLE_GAP_SEC_STATUS_PAIRING_NOT_SUPP,
+ NULL,
+ NULL);
+ APP_ERROR_CHECK(err_code);
+ } break;
+
+ case BLE_GAP_EVT_CONN_PARAM_UPDATE:
+ {
+ NRF_LOG_DEBUG("Received BLE_GAP_EVT_CONN_PARAM_UPDATE");
+
+ ble_gap_conn_params_t const * p_conn =
+ &p_gap->params.conn_param_update.conn_params;
+
+ NRF_LOG_DEBUG("max_conn_interval: %d", p_conn->max_conn_interval);
+ NRF_LOG_DEBUG("min_conn_interval: %d", p_conn->min_conn_interval);
+ NRF_LOG_DEBUG("slave_latency: %d", p_conn->slave_latency);
+ NRF_LOG_DEBUG("conn_sup_timeout: %d", p_conn->conn_sup_timeout);
+ } break;
+
+ case BLE_GAP_EVT_CONN_PARAM_UPDATE_REQUEST:
+ {
+ NRF_LOG_DEBUG("Received BLE_GAP_EVT_CONN_PARAM_UPDATE_REQUEST");
+
+ err_code = sd_ble_gap_conn_param_update(m_conn_handle,
+ &p_gap->params.conn_param_update_request.conn_params);
+
+ if (err_code != NRF_SUCCESS)
+ {
+ NRF_LOG_ERROR("Failure to update connection parameter request: 0x%x", err_code);
+ }
+
+ APP_ERROR_CHECK(err_code);
+ } break;
+
+ case BLE_GAP_EVT_PHY_UPDATE:
+ {
+ NRF_LOG_DEBUG("Received BLE_GAP_EVT_PHY_UPDATE (RX:%d, TX:%d, status:%d)",
+ p_gap->params.phy_update.rx_phy,
+ p_gap->params.phy_update.tx_phy,
+ p_gap->params.phy_update.status);
+ break;
+ }
+
+ case BLE_GAP_EVT_PHY_UPDATE_REQUEST:
+ {
+ NRF_LOG_DEBUG("Received BLE_GAP_EVT_PHY_UPDATE_REQUEST.");
+
+ ble_gap_phys_t const phys =
+ {
+ .rx_phys = BLE_GAP_PHY_AUTO,
+ .tx_phys = BLE_GAP_PHY_AUTO,
+ };
+
+ err_code = sd_ble_gap_phy_update(p_gap->conn_handle, &phys);
+ APP_ERROR_CHECK(err_code);
+ } break;
+
+ case BLE_GATTS_EVT_TIMEOUT:
+ {
+ if (p_ble_evt->evt.gatts_evt.params.timeout.src == BLE_GATT_TIMEOUT_SRC_PROTOCOL)
+ {
+ err_code = sd_ble_gap_disconnect(m_conn_handle,
+ BLE_HCI_REMOTE_USER_TERMINATED_CONNECTION);
+ APP_ERROR_CHECK(err_code);
+ }
+ } break;
+
+ case BLE_EVT_USER_MEM_REQUEST:
+ {
+ err_code = sd_ble_user_mem_reply(m_conn_handle, NULL);
+ APP_ERROR_CHECK(err_code);
+ } break;
+
+ case BLE_GATTS_EVT_RW_AUTHORIZE_REQUEST:
+ {
+ if (p_ble_evt->evt.gatts_evt.params.authorize_request.type
+ != BLE_GATTS_AUTHORIZE_TYPE_INVALID)
+ {
+ if (on_rw_authorize_req(&m_dfu, p_ble_evt))
+ {
+ err_code = on_ctrl_pt_write(&m_dfu,
+ &(p_ble_evt->evt.gatts_evt.params.authorize_request.request.write));
+
+ if (err_code != NRF_SUCCESS)
+ {
+ NRF_LOG_ERROR("Could not handle on_ctrl_pt_write. err_code: 0x%04x", err_code);
+ }
+ }
+ }
+ } break;
+
+ case BLE_GAP_EVT_SEC_INFO_REQUEST:
+ {
+ NRF_LOG_DEBUG("Received BLE_GAP_EVT_SEC_INFO_REQUEST");
+
+ ble_gap_enc_info_t * p_enc_info = NULL;
+ ble_gap_irk_t * p_id_info = NULL;
+
+ #if (NRF_DFU_BLE_REQUIRES_BONDS)
+ /* If there is a match in diversifier, then set the correct keys. */
+ if (p_gap->params.sec_info_request.master_id.ediv ==
+ m_peer_data.enc_key.master_id.ediv)
+ {
+ p_enc_info = &m_peer_data.enc_key.enc_info;
+ }
+ p_id_info = &m_peer_data.ble_id.id_info;
+ #endif
+
+ err_code = sd_ble_gap_sec_info_reply(p_gap->conn_handle, p_enc_info, p_id_info, NULL);
+ APP_ERROR_CHECK(err_code);
+ } break;
+
+ case BLE_GAP_EVT_CONN_SEC_UPDATE:
+ case BLE_GATTS_EVT_SYS_ATTR_MISSING:
+ {
+ #if (NRF_DFU_BLE_REQUIRES_BONDS)
+ err_code = service_changed_send();
+ #else
+ err_code = sd_ble_gatts_sys_attr_set(p_gap->conn_handle, NULL, 0, 0);
+ #endif
+ APP_ERROR_CHECK(err_code);
+ NRF_LOG_DEBUG("Finished handling conn sec update");
+ } break;
+
+ default:
+ /* No implementation needed. */
+ break;
+ }
+}
+
+
+#if (!NRF_DFU_BLE_REQUIRES_BONDS)
+static uint32_t gap_address_change(void)
+{
+ uint32_t err_code;
+ ble_gap_addr_t addr;
+
+ err_code = sd_ble_gap_addr_get(&addr);
+ VERIFY_SUCCESS(err_code);
+
+ /* Increase the BLE address by one when advertising openly. */
+ addr.addr[0] += 1;
+
+ err_code = sd_ble_gap_addr_set(&addr);
+ VERIFY_SUCCESS(err_code);
+
+ return NRF_SUCCESS;
+}
+#endif
+
+
+/**@brief Function for initializing GAP.
+ *
+ * @details This function sets up all necessary GAP (Generic Access Profile) parameters of
+ * the device. It also sets the permissions and appearance.
+ */
+static uint32_t gap_params_init(void)
+{
+ uint32_t err_code;
+ ble_gap_conn_sec_mode_t sec_mode;
+ uint8_t const * device_name;
+ uint32_t name_len;
+
+ BLE_GAP_CONN_SEC_MODE_SET_OPEN(&sec_mode);
+
+#if (!NRF_DFU_BLE_REQUIRES_BONDS)
+
+ err_code = gap_address_change();
+ VERIFY_SUCCESS(err_code);
+
+ if ((m_flags & DFU_BLE_FLAG_USE_ADV_NAME) != 0)
+ {
+ NRF_LOG_DEBUG("Setting adv name: %s, length: %d", m_adv_name.name, m_adv_name.len);
+ device_name = m_adv_name.name;
+ name_len = m_adv_name.len;
+ }
+ else
+#endif
+ {
+ NRF_LOG_DEBUG("Using default advertising name");
+ device_name = (uint8_t const *)(NRF_DFU_BLE_ADV_NAME);
+ name_len = strlen(NRF_DFU_BLE_ADV_NAME);
+ }
+
+ err_code = sd_ble_gap_device_name_set(&sec_mode, device_name, name_len);
+ VERIFY_SUCCESS(err_code);
+
+ err_code = sd_ble_gap_ppcp_set(&m_gap_conn_params);
+ return err_code;
+}
+
+
+static uint32_t ble_stack_init()
+{
+ ret_code_t err_code;
+ uint32_t ram_start = 0;
+
+ /* Register as a BLE event observer to receive BLE events. */
+ NRF_SDH_BLE_OBSERVER(m_ble_evt_observer, BLE_OBSERVER_PRIO, ble_evt_handler, NULL);
+
+ err_code = nrf_dfu_mbr_init_sd();
+ VERIFY_SUCCESS(err_code);
+
+ NRF_LOG_DEBUG("Setting up vector table: 0x%08x", BOOTLOADER_START_ADDR);
+ err_code = sd_softdevice_vector_table_base_set(BOOTLOADER_START_ADDR);
+ VERIFY_SUCCESS(err_code);
+
+ NRF_LOG_DEBUG("Enabling SoftDevice.");
+ err_code = nrf_sdh_enable_request();
+ VERIFY_SUCCESS(err_code);
+
+ /* Fetch the start address of the application RAM. */
+ err_code = nrf_sdh_ble_app_ram_start_get(&ram_start);
+ VERIFY_SUCCESS(err_code);
+
+ NRF_LOG_DEBUG("Configuring BLE stack.");
+ err_code = nrf_sdh_ble_default_cfg_set(APP_BLE_CONN_CFG_TAG, &ram_start);
+ VERIFY_SUCCESS(err_code);
+
+ /* Enable the BLE stack. */
+ NRF_LOG_DEBUG("Enabling the BLE stack.");
+ return nrf_sdh_ble_enable(&ram_start);
+}
+
+
+/**@brief Function for adding DFU Packet characteristic to the BLE Stack.
+ *
+ * @param[in] p_dfu DFU Service structure.
+ *
+ * @return NRF_SUCCESS on success. Otherwise an error code.
+ */
+static uint32_t dfu_pkt_char_add(ble_dfu_t * const p_dfu)
+{
+ ble_gatts_char_md_t char_md =
+ {
+ .char_props.write_wo_resp = 1,
+ };
+
+ ble_uuid_t char_uuid =
+ {
+ .type = p_dfu->uuid_type,
+ .uuid = BLE_DFU_PKT_CHAR_UUID,
+ };
+
+ ble_gatts_attr_md_t attr_md =
+ {
+ .vloc = BLE_GATTS_VLOC_STACK,
+ .vlen = 1,
+ .write_perm =
+ {
+ .sm = 1,
+ #if NRF_DFU_BLE_REQUIRES_BONDS
+ .lv = 2,
+ #else
+ .lv = 1,
+ #endif
+ }
+ };
+
+ ble_gatts_attr_t attr_char_value =
+ {
+ .p_uuid = &char_uuid,
+ .p_attr_md = &attr_md,
+ .max_len = MAX_DFU_PKT_LEN,
+ };
+
+ return sd_ble_gatts_characteristic_add(p_dfu->service_handle,
+ &char_md,
+ &attr_char_value,
+ &p_dfu->dfu_pkt_handles);
+}
+
+
+/**@brief Function for adding DFU Control Point characteristic to the BLE Stack.
+ *
+ * @param[in] p_dfu DFU Service structure.
+ *
+ * @return NRF_SUCCESS on success. Otherwise an error code.
+ */
+static uint32_t dfu_ctrl_pt_add(ble_dfu_t * const p_dfu)
+{
+ ble_gatts_char_md_t char_md =
+ {
+ .char_props.write = 1,
+ .char_props.notify = 1,
+ };
+
+ ble_uuid_t char_uuid =
+ {
+ .type = p_dfu->uuid_type,
+ .uuid = BLE_DFU_CTRL_PT_UUID,
+ };
+
+ ble_gatts_attr_md_t attr_md =
+ {
+ .vloc = BLE_GATTS_VLOC_STACK,
+ .wr_auth = 1,
+ .vlen = 1,
+ .write_perm =
+ {
+ .sm = 1,
+ #if NRF_DFU_BLE_REQUIRES_BONDS
+ .lv = 2,
+ #else
+ .lv = 1,
+ #endif
+ },
+ };
+
+ ble_gatts_attr_t attr_char_value =
+ {
+ .p_uuid = &char_uuid,
+ .p_attr_md = &attr_md,
+ .max_len = BLE_GATT_ATT_MTU_DEFAULT,
+ };
+
+ return sd_ble_gatts_characteristic_add(p_dfu->service_handle,
+ &char_md,
+ &attr_char_value,
+ &p_dfu->dfu_ctrl_pt_handles);
+}
+
+
+/**@brief Function for checking if the CCCD of DFU Control point is configured for Notification.
+ *
+ * @details This function checks if the CCCD of DFU Control Point characteristic is configured
+ * for Notification by the DFU Controller.
+ *
+ * @param[in] p_dfu DFU Service structure.
+ *
+ * @return True if the CCCD of DFU Control Point characteristic is configured for Notification.
+ * False otherwise.
+ */
+uint32_t ble_dfu_init(ble_dfu_t * p_dfu)
+{
+ ASSERT(p_dfu != NULL);
+
+ ble_uuid_t service_uuid;
+ uint32_t err_code;
+
+ m_conn_handle = BLE_CONN_HANDLE_INVALID;
+
+ BLE_UUID_BLE_ASSIGN(service_uuid, BLE_DFU_SERVICE_UUID);
+
+ err_code = sd_ble_gatts_service_add(BLE_GATTS_SRVC_TYPE_PRIMARY,
+ &service_uuid,
+ &(p_dfu->service_handle));
+ VERIFY_SUCCESS(err_code);
+
+ ble_uuid128_t const base_uuid128 =
+ {
+ {
+ 0x50, 0xEA, 0xDA, 0x30, 0x88, 0x83, 0xB8, 0x9F,
+ 0x60, 0x4F, 0x15, 0xF3, 0x00, 0x00, 0xC9, 0x8E
+ }
+ };
+
+ err_code = sd_ble_uuid_vs_add(&base_uuid128, &p_dfu->uuid_type);
+ VERIFY_SUCCESS(err_code);
+
+ err_code = dfu_pkt_char_add(p_dfu);
+ VERIFY_SUCCESS(err_code);
+
+ err_code = dfu_ctrl_pt_add(p_dfu);
+ VERIFY_SUCCESS(err_code);
+
+ return NRF_SUCCESS;
+}
+
+
+static uint32_t ble_dfu_transport_init(nrf_dfu_observer_t observer)
+{
+ uint32_t err_code = NRF_SUCCESS;
+
+ if (m_flags & DFU_BLE_FLAG_INITIALIZED)
+ {
+ return err_code;
+ }
+
+ NRF_LOG_DEBUG("Initializing BLE DFU transport");
+
+ m_observer = observer;
+
+ err_code = nrf_balloc_init(&m_buffer_pool);
+ UNUSED_RETURN_VALUE(err_code);
+
+ err_code = ble_stack_init();
+ VERIFY_SUCCESS(err_code);
+
+#if (NRF_DFU_BLE_REQUIRES_BONDS)
+ /* Copy out the peer data if bonds are required */
+ if (nrf_dfu_settings_peer_data_is_valid())
+ {
+ NRF_LOG_DEBUG("Copying peer data");
+
+ err_code = nrf_dfu_settings_peer_data_copy(&m_peer_data);
+ UNUSED_RETURN_VALUE(err_code);
+ }
+ else
+ {
+ APP_ERROR_HANDLER(NRF_ERROR_INTERNAL);
+ }
+#else
+ /* Copy out the new advertisement name when bonds are not required and the name is set. */
+ if (nrf_dfu_settings_adv_name_is_valid())
+ {
+ err_code = nrf_dfu_settings_adv_name_copy(&m_adv_name);
+ UNUSED_RETURN_VALUE(err_code);
+
+ /* Set flags for advertisement name that is to be used */
+ m_flags |= DFU_BLE_FLAG_USE_ADV_NAME;
+ }
+ else
+ {
+ NRF_LOG_DEBUG("No advertising name found");
+ }
+#endif
+
+ err_code = gap_params_init();
+ VERIFY_SUCCESS(err_code);
+
+ /* Initialize the Device Firmware Update Service. */
+ err_code = ble_dfu_init(&m_dfu);
+ VERIFY_SUCCESS(err_code);
+
+ err_code = advertising_start();
+ VERIFY_SUCCESS(err_code);
+
+ m_flags |= DFU_BLE_FLAG_INITIALIZED;
+
+ NRF_LOG_DEBUG("BLE DFU transport initialized.");
+
+ return NRF_SUCCESS;
+}
+
+
+static uint32_t ble_dfu_transport_close(nrf_dfu_transport_t const * p_exception)
+{
+ uint32_t err_code = NRF_SUCCESS;
+
+ if ((m_flags & DFU_BLE_FLAG_INITIALIZED) && (p_exception != &ble_dfu_transport))
+ {
+ NRF_LOG_DEBUG("Shutting down BLE transport.");
+
+ if (m_conn_handle != BLE_CONN_HANDLE_INVALID)
+ {
+ NRF_LOG_DEBUG("Disconnecting.");
+
+ /* Set flag to prevent advertisement from starting */
+ m_flags |= DFU_BLE_RESETTING_SOON;
+
+ /* Disconnect from the peer. */
+ err_code = sd_ble_gap_disconnect(m_conn_handle, BLE_HCI_REMOTE_USER_TERMINATED_CONNECTION);
+ VERIFY_SUCCESS(err_code);
+
+ /* Wait a bit for the disconnect event to be sent on air. */
+ nrf_delay_ms(200);
+ }
+ else
+ {
+ err_code = sd_ble_gap_adv_stop(m_adv_handle);
+ UNUSED_RETURN_VALUE(err_code);
+ }
+
+ err_code = nrf_sdh_disable_request();
+ if (err_code == NRF_SUCCESS)
+ {
+ NRF_LOG_DEBUG("BLE transport shut down.");
+ }
+ }
+
+ return err_code;
+}
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/ble_dfu/nrf_dfu_ble.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/ble_dfu/nrf_dfu_ble.h
new file mode 100644
index 0000000..04d2d55
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/ble_dfu/nrf_dfu_ble.h
@@ -0,0 +1,93 @@
+/**
+ * Copyright (c) 2016 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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
+ *
+ * @defgroup nrf_dfu_ble DFU BLE Service
+ * @{
+ * @ingroup nrf_dfu
+ * @brief Device Firmware Update (DFU) transport layer for <em>Bluetooth</em> low energy.
+ *
+ * @details The Device Firmware Update (DFU) Service is a GATT-based service that can be used for
+ * performing firmware updates over BLE. Note that this implementation uses
+ * vendor-specific UUIDs for the service and characteristics, and is intended to demonstrate
+ * firmware updates over BLE. See @ref lib_dfu_transport_ble "DFU Transport: BLE" for more information on the service and the profile.
+ */
+
+#ifndef NRF_DFU_BLE_H__
+#define NRF_DFU_BLE_H__
+
+#include <stdint.h>
+#include "ble_gatts.h"
+#include "ble.h"
+#include "nrf_dfu_transport.h"
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+// This is a 16-bit UUID.
+#define BLE_DFU_SERVICE_UUID 0xFE59 //!< UUID of the DFU Service.
+
+// These UUIDs are used with the Nordic base address to create a 128-bit UUID (0x8EC9XXXXF3154F609FB8838830DAEA50).
+#define BLE_DFU_CTRL_PT_UUID 0x0001 //!< UUID of the DFU Control Point.
+#define BLE_DFU_PKT_CHAR_UUID 0x0002 //!< UUID of the DFU Packet Characteristic.
+
+
+/**@brief DFU Service.
+ *
+ * @details This structure contains status information related to the service.
+ */
+typedef struct
+{
+ uint16_t service_handle; /**< Handle of the DFU Service (as provided by the SoftDevice). */
+ uint8_t uuid_type; /**< UUID type assigned to the DFU Service by the SoftDevice. */
+ ble_gatts_char_handles_t dfu_pkt_handles; /**< Handles related to the DFU Packet Characteristic. */
+ ble_gatts_char_handles_t dfu_ctrl_pt_handles; /**< Handles related to the DFU Control Point Characteristic. */
+} ble_dfu_t;
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // NRF_DFU_BLE_H__
+
+/** @} */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/ble_dfu/nrf_dfu_ble_svci_bond_sharing.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/ble_dfu/nrf_dfu_ble_svci_bond_sharing.h
new file mode 100644
index 0000000..0377a4c
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/ble_dfu/nrf_dfu_ble_svci_bond_sharing.h
@@ -0,0 +1,95 @@
+/**
+ * Copyright (c) 2016 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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
+ *
+ * @defgroup nrf_dfu_svci_bond_sharing Supervisor call interface for bond sharing
+ * @{
+ * @ingroup nrf_dfu
+ * @brief The Supervisor call interface is a thread-safe method to call into the current application or into an external application using a Supervisor instruction.
+ *
+ */
+
+
+#ifndef NRF_DFU_BLE_SVCI_BOND_SHARING_H__
+#define NRF_DFU_BLE_SVCI_BOND_SHARING_H__
+
+#include <stdbool.h>
+#include "nrf_svci.h"
+#include "nrf_svci_async_function.h"
+#include "sdk_config.h"
+#include "nrf_dfu_types.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+#define NRF_DFU_SVCI_SET_PEER_DATA 2
+#define NRF_DFU_SVCI_SET_ADV_NAME 3
+
+#if defined(NRF_DFU_TRANSPORT_BLE) && NRF_DFU_TRANSPORT_BLE
+
+/**@brief Sets up the async SVCI interface for exchanging peer data like bonding and the system attribute table.
+ *
+ * @details The peer data will be stored in flash by the bootloader. This requires memory management and
+ * handling forwarding of system events and state from the main application to the bootloader.
+ *
+ * @note This is only available in the buttonless DFU that supports bond sharing.
+ */
+NRF_SVCI_ASYNC_FUNC_DECLARE(NRF_DFU_SVCI_SET_PEER_DATA, nrf_dfu_set_peer_data, nrf_dfu_peer_data_t, nrf_dfu_peer_data_state_t);
+
+/**@brief Sets up the async SVCI interface for exchanging advertisement name to use when entering DFU mode.
+ *
+ * @details The advertisement name will be stored in flash by the bootloader. This requires memory management
+ * and handling forwarding of system events and state from the main application to the bootloader.
+ *
+ * @note This is only available in the buttonless DFU that does not support bond sharing.
+ */
+NRF_SVCI_ASYNC_FUNC_DECLARE(NRF_DFU_SVCI_SET_ADV_NAME, nrf_dfu_set_adv_name, nrf_dfu_adv_name_t, nrf_dfu_set_adv_name_state_t);
+
+#endif // NRF_DFU_TRANSPORT_BLE
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // NRF_DFU_BLE_SVCI_BOND_SHARING_H__
+
+/** @} */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/dfu/dfu-cc.options b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/dfu/dfu-cc.options
new file mode 100644
index 0000000..a9ed61e
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/dfu/dfu-cc.options
@@ -0,0 +1,3 @@
+dfu.Hash.hash max_size:32
+dfu.SignedCommand.signature max_size:64
+dfu.InitCommand.sd_req max_count:16 \ No newline at end of file
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/dfu/dfu-cc.pb.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/dfu/dfu-cc.pb.c
new file mode 100644
index 0000000..2396dc6
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/dfu/dfu-cc.pb.c
@@ -0,0 +1,116 @@
+/**
+ * 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+/* Automatically generated nanopb constant definitions */
+/* Generated by nanopb-0.3.6-dev at Wed Dec 13 13:37:53 2017. */
+
+#include "dfu-cc.pb.h"
+
+/* @@protoc_insertion_point(includes) */
+#if PB_PROTO_HEADER_VERSION != 30
+#error Regenerate this file with the current version of nanopb generator.
+#endif
+
+const bool dfu_init_command_is_debug_default = false;
+
+
+const pb_field_t dfu_hash_fields[3] = {
+ PB_FIELD( 1, UENUM , REQUIRED, STATIC , FIRST, dfu_hash_t, hash_type, hash_type, 0),
+ PB_FIELD( 2, BYTES , REQUIRED, STATIC , OTHER, dfu_hash_t, hash, hash_type, 0),
+ PB_LAST_FIELD
+};
+
+const pb_field_t dfu_init_command_fields[10] = {
+ PB_FIELD( 1, UINT32 , OPTIONAL, STATIC , FIRST, dfu_init_command_t, fw_version, fw_version, 0),
+ PB_FIELD( 2, UINT32 , OPTIONAL, STATIC , OTHER, dfu_init_command_t, hw_version, fw_version, 0),
+ PB_FIELD( 3, UINT32 , REPEATED, STATIC , OTHER, dfu_init_command_t, sd_req, hw_version, 0),
+ PB_FIELD( 4, UENUM , OPTIONAL, STATIC , OTHER, dfu_init_command_t, type, sd_req, 0),
+ PB_FIELD( 5, UINT32 , OPTIONAL, STATIC , OTHER, dfu_init_command_t, sd_size, type, 0),
+ PB_FIELD( 6, UINT32 , OPTIONAL, STATIC , OTHER, dfu_init_command_t, bl_size, sd_size, 0),
+ PB_FIELD( 7, UINT32 , OPTIONAL, STATIC , OTHER, dfu_init_command_t, app_size, bl_size, 0),
+ PB_FIELD( 8, MESSAGE , OPTIONAL, STATIC , OTHER, dfu_init_command_t, hash, app_size, &dfu_hash_fields),
+ PB_FIELD( 9, BOOL , OPTIONAL, STATIC , OTHER, dfu_init_command_t, is_debug, hash, &dfu_init_command_is_debug_default),
+ PB_LAST_FIELD
+};
+
+const pb_field_t dfu_command_fields[3] = {
+ PB_FIELD( 1, UENUM , OPTIONAL, STATIC , FIRST, dfu_command_t, op_code, op_code, 0),
+ PB_FIELD( 2, MESSAGE , OPTIONAL, STATIC , OTHER, dfu_command_t, init, op_code, &dfu_init_command_fields),
+ PB_LAST_FIELD
+};
+
+const pb_field_t dfu_signed_command_fields[4] = {
+ PB_FIELD( 1, MESSAGE , REQUIRED, STATIC , FIRST, dfu_signed_command_t, command, command, &dfu_command_fields),
+ PB_FIELD( 2, UENUM , REQUIRED, STATIC , OTHER, dfu_signed_command_t, signature_type, command, 0),
+ PB_FIELD( 3, BYTES , REQUIRED, STATIC , OTHER, dfu_signed_command_t, signature, signature_type, 0),
+ PB_LAST_FIELD
+};
+
+const pb_field_t dfu_packet_fields[3] = {
+ PB_FIELD( 1, MESSAGE , OPTIONAL, STATIC , FIRST, dfu_packet_t, command, command, &dfu_command_fields),
+ PB_FIELD( 2, MESSAGE , OPTIONAL, STATIC , OTHER, dfu_packet_t, signed_command, command, &dfu_signed_command_fields),
+ PB_LAST_FIELD
+};
+
+
+/* Check that field information fits in pb_field_t */
+#if !defined(PB_FIELD_32BIT)
+/* If you get an error here, it means that you need to define PB_FIELD_32BIT
+ * compile-time option. You can do that in pb.h or on compiler command line.
+ *
+ * The reason you need to do this is that some of your messages contain tag
+ * numbers or field sizes that are larger than what can fit in 8 or 16 bit
+ * field descriptors.
+ */
+PB_STATIC_ASSERT((pb_membersize(dfu_init_command_t, hash) < 65536 && pb_membersize(dfu_command_t, init) < 65536 && pb_membersize(dfu_signed_command_t, command) < 65536 && pb_membersize(dfu_packet_t, command) < 65536 && pb_membersize(dfu_packet_t, signed_command) < 65536), YOU_MUST_DEFINE_PB_FIELD_32BIT_FOR_MESSAGES_dfu_hash_dfu_init_command_dfu_command_dfu_signed_command_dfu_packet)
+#endif
+
+#if !defined(PB_FIELD_16BIT) && !defined(PB_FIELD_32BIT)
+/* If you get an error here, it means that you need to define PB_FIELD_16BIT
+ * compile-time option. You can do that in pb.h or on compiler command line.
+ *
+ * The reason you need to do this is that some of your messages contain tag
+ * numbers or field sizes that are larger than what can fit in the default
+ * 8 bit descriptors.
+ */
+PB_STATIC_ASSERT((pb_membersize(dfu_init_command_t, hash) < 256 && pb_membersize(dfu_command_t, init) < 256 && pb_membersize(dfu_signed_command_t, command) < 256 && pb_membersize(dfu_packet_t, command) < 256 && pb_membersize(dfu_packet_t, signed_command) < 256), YOU_MUST_DEFINE_PB_FIELD_16BIT_FOR_MESSAGES_dfu_hash_dfu_init_command_dfu_command_dfu_signed_command_dfu_packet)
+#endif
+
+
+/* @@protoc_insertion_point(eof) */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/dfu/dfu-cc.pb.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/dfu/dfu-cc.pb.h
new file mode 100644
index 0000000..fae43c5
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/dfu/dfu-cc.pb.h
@@ -0,0 +1,213 @@
+/**
+ * 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+/* Automatically generated nanopb header */
+/* Generated by nanopb-0.3.6-dev at Wed Dec 13 13:37:53 2017. */
+
+#ifndef PB_DFU_CC_PB_H_INCLUDED
+#define PB_DFU_CC_PB_H_INCLUDED
+#include <pb.h>
+
+/* @@protoc_insertion_point(includes) */
+#if PB_PROTO_HEADER_VERSION != 30
+#error Regenerate this file with the current version of nanopb generator.
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Enum definitions */
+typedef enum
+{
+ DFU_FW_TYPE_APPLICATION = 0,
+ DFU_FW_TYPE_SOFTDEVICE = 1,
+ DFU_FW_TYPE_BOOTLOADER = 2,
+ DFU_FW_TYPE_SOFTDEVICE_BOOTLOADER = 3
+} dfu_fw_type_t;
+#define DFU_FW_TYPE_MIN DFU_FW_TYPE_APPLICATION
+#define DFU_FW_TYPE_MAX DFU_FW_TYPE_SOFTDEVICE_BOOTLOADER
+#define DFU_FW_TYPE_ARRAYSIZE ((dfu_fw_type_t)(DFU_FW_TYPE_SOFTDEVICE_BOOTLOADER+1))
+
+typedef enum
+{
+ DFU_HASH_TYPE_NO_HASH = 0,
+ DFU_HASH_TYPE_CRC = 1,
+ DFU_HASH_TYPE_SHA128 = 2,
+ DFU_HASH_TYPE_SHA256 = 3,
+ DFU_HASH_TYPE_SHA512 = 4
+} dfu_hash_type_t;
+#define DFU_HASH_TYPE_MIN DFU_HASH_TYPE_NO_HASH
+#define DFU_HASH_TYPE_MAX DFU_HASH_TYPE_SHA512
+#define DFU_HASH_TYPE_ARRAYSIZE ((dfu_hash_type_t)(DFU_HASH_TYPE_SHA512+1))
+
+typedef enum
+{
+ DFU_SIGNATURE_TYPE_ECDSA_P256_SHA256 = 0,
+ DFU_SIGNATURE_TYPE_ED25519 = 1
+} dfu_signature_type_t;
+#define DFU_SIGNATURE_TYPE_MIN DFU_SIGNATURE_TYPE_ECDSA_P256_SHA256
+#define DFU_SIGNATURE_TYPE_MAX DFU_SIGNATURE_TYPE_ED25519
+#define DFU_SIGNATURE_TYPE_ARRAYSIZE ((dfu_signature_type_t)(DFU_SIGNATURE_TYPE_ED25519+1))
+
+typedef enum
+{
+ DFU_COMMAND_OP_CODE_INIT = 1
+} dfu_command_op_code_t;
+#define DFU_COMMAND_OP_CODE_MIN DFU_COMMAND_OP_CODE_INIT
+#define DFU_COMMAND_OP_CODE_MAX DFU_COMMAND_OP_CODE_INIT
+#define DFU_COMMAND_OP_CODE_ARRAYSIZE ((dfu_command_op_code_t)(DFU_COMMAND_OP_CODE_INIT+1))
+
+/* Struct definitions */
+typedef PB_BYTES_ARRAY_T(32) dfu_hash_hash_t;
+typedef struct {
+ dfu_hash_type_t hash_type;
+ dfu_hash_hash_t hash;
+/* @@protoc_insertion_point(struct:dfu_hash_t) */
+} dfu_hash_t;
+
+typedef struct {
+ bool has_fw_version;
+ uint32_t fw_version;
+ bool has_hw_version;
+ uint32_t hw_version;
+ pb_size_t sd_req_count;
+ uint32_t sd_req[16];
+ bool has_type;
+ dfu_fw_type_t type;
+ bool has_sd_size;
+ uint32_t sd_size;
+ bool has_bl_size;
+ uint32_t bl_size;
+ bool has_app_size;
+ uint32_t app_size;
+ bool has_hash;
+ dfu_hash_t hash;
+ bool has_is_debug;
+ bool is_debug;
+/* @@protoc_insertion_point(struct:dfu_init_command_t) */
+} dfu_init_command_t;
+
+typedef struct {
+ bool has_op_code;
+ dfu_command_op_code_t op_code;
+ bool has_init;
+ dfu_init_command_t init;
+/* @@protoc_insertion_point(struct:dfu_command_t) */
+} dfu_command_t;
+
+typedef PB_BYTES_ARRAY_T(64) dfu_signed_command_signature_t;
+typedef struct {
+ dfu_command_t command;
+ dfu_signature_type_t signature_type;
+ dfu_signed_command_signature_t signature;
+/* @@protoc_insertion_point(struct:dfu_signed_command_t) */
+} dfu_signed_command_t;
+
+typedef struct {
+ bool has_command;
+ dfu_command_t command;
+ bool has_signed_command;
+ dfu_signed_command_t signed_command;
+/* @@protoc_insertion_point(struct:dfu_packet_t) */
+} dfu_packet_t;
+
+/* Default values for struct fields */
+extern const bool dfu_init_command_is_debug_default;
+
+/* Initializer values for message structs */
+#define DFU_HASH_INIT_DEFAULT {(dfu_hash_type_t)0, {0, {0}}}
+#define DFU_INIT_COMMAND_INIT_DEFAULT {false, 0, false, 0, 0, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, false, (dfu_fw_type_t)0, false, 0, false, 0, false, 0, false, DFU_HASH_INIT_DEFAULT, false, false}
+#define DFU_COMMAND_INIT_DEFAULT {false, (dfu_command_op_code_t)0, false, DFU_INIT_COMMAND_INIT_DEFAULT}
+#define DFU_SIGNED_COMMAND_INIT_DEFAULT {DFU_COMMAND_INIT_DEFAULT, (dfu_signature_type_t)0, {0, {0}}}
+#define DFU_PACKET_INIT_DEFAULT {false, DFU_COMMAND_INIT_DEFAULT, false, DFU_SIGNED_COMMAND_INIT_DEFAULT}
+#define DFU_HASH_INIT_ZERO {(dfu_hash_type_t)0, {0, {0}}}
+#define DFU_INIT_COMMAND_INIT_ZERO {false, 0, false, 0, 0, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, false, (dfu_fw_type_t)0, false, 0, false, 0, false, 0, false, DFU_HASH_INIT_ZERO, false, 0}
+#define DFU_COMMAND_INIT_ZERO {false, (dfu_command_op_code_t)0, false, DFU_INIT_COMMAND_INIT_ZERO}
+#define DFU_SIGNED_COMMAND_INIT_ZERO {DFU_COMMAND_INIT_ZERO, (dfu_signature_type_t)0, {0, {0}}}
+#define DFU_PACKET_INIT_ZERO {false, DFU_COMMAND_INIT_ZERO, false, DFU_SIGNED_COMMAND_INIT_ZERO}
+
+/* Field tags (for use in manual encoding/decoding) */
+#define DFU_HASH_HASH_TYPE_TAG 1
+#define DFU_HASH_HASH_TAG 2
+#define DFU_INIT_COMMAND_FW_VERSION_TAG 1
+#define DFU_INIT_COMMAND_HW_VERSION_TAG 2
+#define DFU_INIT_COMMAND_SD_REQ_TAG 3
+#define DFU_INIT_COMMAND_TYPE_TAG 4
+#define DFU_INIT_COMMAND_SD_SIZE_TAG 5
+#define DFU_INIT_COMMAND_BL_SIZE_TAG 6
+#define DFU_INIT_COMMAND_APP_SIZE_TAG 7
+#define DFU_INIT_COMMAND_HASH_TAG 8
+#define DFU_INIT_COMMAND_IS_DEBUG_TAG 9
+#define DFU_COMMAND_OP_CODE_TAG 1
+#define DFU_COMMAND_INIT_TAG 2
+#define DFU_SIGNED_COMMAND_COMMAND_TAG 1
+#define DFU_SIGNED_COMMAND_SIGNATURE_TYPE_TAG 2
+#define DFU_SIGNED_COMMAND_SIGNATURE_TAG 3
+#define DFU_PACKET_COMMAND_TAG 1
+#define DFU_PACKET_SIGNED_COMMAND_TAG 2
+
+/* Struct field encoding specification for nanopb */
+extern const pb_field_t dfu_hash_fields[3];
+extern const pb_field_t dfu_init_command_fields[10];
+extern const pb_field_t dfu_command_fields[3];
+extern const pb_field_t dfu_signed_command_fields[4];
+extern const pb_field_t dfu_packet_fields[3];
+
+/* Maximum encoded size of messages (where known) */
+#define DFU_HASH_SIZE 36
+#define DFU_INIT_COMMAND_SIZE 168
+#define DFU_COMMAND_SIZE 173
+#define DFU_SIGNED_COMMAND_SIZE 244
+#define DFU_PACKET_SIZE 423
+
+/* Message IDs (where set with "msgid" option) */
+#ifdef PB_MSGID
+
+#define DFU_CC_MESSAGES \
+
+
+#endif
+
+#ifdef __cplusplus
+} /* extern "C" */
+#endif
+/* @@protoc_insertion_point(eof) */
+
+#endif
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/dfu/dfu-cc.proto b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/dfu/dfu-cc.proto
new file mode 100644
index 0000000..69f9680
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/dfu/dfu-cc.proto
@@ -0,0 +1,66 @@
+package dfu;
+
+// Version 0.1
+
+enum FwType {
+ APPLICATION = 0; // default, compatible with proto3
+ SOFTDEVICE = 1;
+ BOOTLOADER = 2;
+ SOFTDEVICE_BOOTLOADER = 3;
+}
+
+enum HashType {
+ NO_HASH = 0;
+ CRC = 1;
+ SHA128 = 2;
+ SHA256 = 3;
+ SHA512 = 4;
+}
+
+message Hash {
+ required HashType hash_type = 1;
+ required bytes hash = 2;
+}
+
+// Commands data
+message InitCommand {
+ optional uint32 fw_version = 1;
+ optional uint32 hw_version = 2;
+ repeated uint32 sd_req = 3 [packed = true]; // packed option is default in proto3
+ optional FwType type = 4;
+
+ optional uint32 sd_size = 5;
+ optional uint32 bl_size = 6;
+ optional uint32 app_size = 7;
+
+ optional Hash hash = 8;
+
+ optional bool is_debug = 9 [default = false];
+}
+
+// Command type
+message Command {
+ enum OpCode {
+ INIT = 1;
+ }
+ optional OpCode op_code = 1;
+ optional InitCommand init = 2;
+}
+
+// Signed command types
+enum SignatureType {
+ ECDSA_P256_SHA256 = 0;
+ ED25519 = 1;
+}
+
+message SignedCommand {
+ required Command command = 1;
+ required SignatureType signature_type = 2;
+ required bytes signature = 3;
+}
+
+// Parent packet type
+message Packet {
+ optional Command command = 1;
+ optional SignedCommand signed_command = 2;
+}
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/dfu/nrf_dfu.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/dfu/nrf_dfu.c
new file mode 100644
index 0000000..f2c9796
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/dfu/nrf_dfu.c
@@ -0,0 +1,100 @@
+/**
+ * Copyright (c) 2016 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#include "nrf_dfu.h"
+
+#include "nrf_dfu_utils.h"
+#include "nrf_dfu_transport.h"
+#include "nrf_dfu_req_handler.h"
+#include "app_timer.h"
+#include "nrf_log.h"
+
+static nrf_dfu_observer_t m_user_observer; //<! Observer callback set by the user.
+
+
+
+/**
+ * @brief This function calls the user's observer (@ref m_observer) after it is done handling the event.
+ */
+static void dfu_observer(nrf_dfu_evt_type_t event)
+{
+ switch (event)
+ {
+ case NRF_DFU_EVT_DFU_COMPLETED:
+ {
+#ifndef NRF_DFU_NO_TRANSPORT
+ UNUSED_RETURN_VALUE(nrf_dfu_transports_close(NULL));
+#endif
+ break;
+ }
+ default:
+ break;
+ }
+
+ /* Call user's observer if present. */
+ if (m_user_observer)
+ {
+ m_user_observer(event);
+ }
+}
+
+
+
+uint32_t nrf_dfu_init(nrf_dfu_observer_t observer)
+{
+ uint32_t ret_val;
+
+ m_user_observer = observer;
+
+ NRF_LOG_INFO("Entering DFU mode.");
+
+ dfu_observer(NRF_DFU_EVT_DFU_INITIALIZED);
+
+ // Initializing transports
+ ret_val = nrf_dfu_transports_init(dfu_observer);
+ if (ret_val != NRF_SUCCESS)
+ {
+ NRF_LOG_ERROR("Could not initalize DFU transport: 0x%08x", ret_val);
+ return ret_val;
+ }
+
+ ret_val = nrf_dfu_req_handler_init(dfu_observer);
+
+ return ret_val;
+}
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/dfu/nrf_dfu.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/dfu/nrf_dfu.h
new file mode 100644
index 0000000..34d7aee
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/dfu/nrf_dfu.h
@@ -0,0 +1,85 @@
+/**
+ * Copyright (c) 2016 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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
+ *
+ * @defgroup nrf_dfu DFU modules
+ * @{
+ * @ingroup nrf_bootloader
+ * @brief Modules providing Device Firmware Update (DFU) functionality.
+ *
+ * The DFU module, in combination with the @ref nrf_bootloader module,
+ * can be used to implement a bootloader that supports Device Firmware Updates.
+ */
+
+#ifndef NRF_DFU_H__
+#define NRF_DFU_H__
+
+#include <stdint.h>
+#include <stdbool.h>
+#include "nrf_dfu_types.h"
+#include "nrf_dfu_req_handler.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+#define NRF_DFU_SCHED_EVENT_DATA_SIZE (sizeof(nrf_dfu_request_t))
+
+
+/** @brief Function for initializing a DFU operation.
+ *
+ * This function initializes a DFU operation and any transports that are registered
+ * in the system.
+ *
+ * @param[in] observer Function for receiving DFU notifications.
+ *
+ * @retval NRF_SUCCESS If the DFU operation was successfully initialized.
+ */
+uint32_t nrf_dfu_init(nrf_dfu_observer_t observer);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // NRF_DFU_H__
+
+/** @} */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/dfu/nrf_dfu_flash.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/dfu/nrf_dfu_flash.c
new file mode 100644
index 0000000..c4e047a
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/dfu/nrf_dfu_flash.c
@@ -0,0 +1,167 @@
+/**
+ * Copyright (c) 2016 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+
+#include "nrf_dfu_flash.h"
+#include "nrf_dfu_types.h"
+
+#include "nrf_fstorage.h"
+#include "nrf_fstorage_sd.h"
+#include "nrf_fstorage_nvmc.h"
+
+
+#define NRF_LOG_MODULE_NAME nrf_dfu_flash
+#include "nrf_log.h"
+NRF_LOG_MODULE_REGISTER();
+
+
+void dfu_fstorage_evt_handler(nrf_fstorage_evt_t * p_evt);
+
+
+NRF_FSTORAGE_DEF(nrf_fstorage_t m_fs) =
+{
+ .evt_handler = dfu_fstorage_evt_handler,
+ .start_addr = MBR_SIZE,
+ .end_addr = BOOTLOADER_SETTINGS_ADDRESS + BOOTLOADER_SETTINGS_PAGE_SIZE
+};
+
+static uint32_t m_flash_operations_pending;
+
+void dfu_fstorage_evt_handler(nrf_fstorage_evt_t * p_evt)
+{
+ if (NRF_LOG_ENABLED && (m_flash_operations_pending > 0))
+ {
+ m_flash_operations_pending--;
+ }
+
+ if (p_evt->result == NRF_SUCCESS)
+ {
+ NRF_LOG_DEBUG("Flash %s success: addr=%p, pending %d",
+ (p_evt->id == NRF_FSTORAGE_EVT_WRITE_RESULT) ? "write" : "erase",
+ p_evt->addr, m_flash_operations_pending);
+ }
+ else
+ {
+ NRF_LOG_DEBUG("Flash %s failed (0x%x): addr=%p, len=0x%x bytes, pending %d",
+ (p_evt->id == NRF_FSTORAGE_EVT_WRITE_RESULT) ? "write" : "erase",
+ p_evt->result, p_evt->addr, p_evt->len, m_flash_operations_pending);
+ }
+
+ if (p_evt->p_param)
+ {
+ //lint -save -e611 (Suspicious cast)
+ ((nrf_dfu_flash_callback_t)(p_evt->p_param))((void*)p_evt->p_src);
+ //lint -restore
+ }
+}
+
+
+ret_code_t nrf_dfu_flash_init(bool sd_irq_initialized)
+{
+ nrf_fstorage_api_t * p_api_impl;
+
+ /* Setup the desired API implementation. */
+#ifdef BLE_STACK_SUPPORT_REQD
+ if (sd_irq_initialized)
+ {
+ NRF_LOG_DEBUG("Initializing nrf_fstorage_sd backend.");
+ p_api_impl = &nrf_fstorage_sd;
+ }
+ else
+#endif
+ {
+ NRF_LOG_DEBUG("Initializing nrf_fstorage_nvmc backend.");
+ p_api_impl = &nrf_fstorage_nvmc;
+ }
+
+ return nrf_fstorage_init(&m_fs, p_api_impl, NULL);
+}
+
+
+ret_code_t nrf_dfu_flash_store(uint32_t dest,
+ void const * p_src,
+ uint32_t len,
+ nrf_dfu_flash_callback_t callback)
+{
+ ret_code_t rc;
+
+ NRF_LOG_DEBUG("nrf_fstorage_write(addr=%p, src=%p, len=%d bytes), queue usage: %d",
+ dest, p_src, len, m_flash_operations_pending);
+
+ //lint -save -e611 (Suspicious cast)
+ rc = nrf_fstorage_write(&m_fs, dest, p_src, len, (void *)callback);
+ //lint -restore
+
+ if ((NRF_LOG_ENABLED) && (rc == NRF_SUCCESS))
+ {
+ m_flash_operations_pending++;
+ }
+ else
+ {
+ NRF_LOG_WARNING("nrf_fstorage_write() failed with error 0x%x.", rc);
+ }
+
+ return rc;
+}
+
+
+ret_code_t nrf_dfu_flash_erase(uint32_t page_addr,
+ uint32_t num_pages,
+ nrf_dfu_flash_callback_t callback)
+{
+ ret_code_t rc;
+
+ NRF_LOG_DEBUG("nrf_fstorage_erase(addr=0x%p, len=%d pages), queue usage: %d",
+ page_addr, num_pages, m_flash_operations_pending);
+
+ //lint -save -e611 (Suspicious cast)
+ rc = nrf_fstorage_erase(&m_fs, page_addr, num_pages, (void *)callback);
+ //lint -restore
+
+ if ((NRF_LOG_ENABLED) && (rc == NRF_SUCCESS))
+ {
+ m_flash_operations_pending++;
+ }
+ else
+ {
+ NRF_LOG_WARNING("nrf_fstorage_erase() failed with error 0x%x.", rc);
+ }
+
+ return rc;
+}
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/dfu/nrf_dfu_flash.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/dfu/nrf_dfu_flash.h
new file mode 100644
index 0000000..fb14610
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/dfu/nrf_dfu_flash.h
@@ -0,0 +1,132 @@
+/**
+ * Copyright (c) 2016 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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
+ *
+ * @defgroup sdk_nrf_dfu_flash Flash operations
+ * @{
+ * @ingroup nrf_dfu
+ */
+
+#ifndef NRF_DFU_FLASH_H__
+#define NRF_DFU_FLASH_H__
+
+#include <stdint.h>
+#include <stdbool.h>
+#include "sdk_errors.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+/**@brief nrf_fstorage event handler function for DFU fstorage operations.
+ *
+ * This function will be called after a flash operation has completed.
+ */
+typedef void (*nrf_dfu_flash_callback_t)(void * p_buf);
+
+
+/**@brief Function for initializing the flash module.
+ *
+ * Depending on whether or not the SoftDevice is present and its IRQ have been initialized,
+ * this function initializes the correct @ref nrf_fstorage backend.
+ *
+ * @param[in] sd_irq_initialized Whether or not the SoftDevice IRQ have been initialized.
+ *
+ * @retval NRF_SUCCESS If the operation was successful.
+ */
+ret_code_t nrf_dfu_flash_init(bool sd_irq_initialized);
+
+
+/**@brief Function for storing data to flash.
+ *
+ * This functions is asynchronous when the SoftDevice is enabled and synchronous when
+ * the SoftDevice is not present or disabled. In both cases, if a callback function is provided,
+ * it will be called when the operation has completed.
+ *
+ * @note The content of @p p_src should be kept in memory until the operation has completed.
+ *
+ * @param[in] dest The address where the data should be stored.
+ * @param[in] p_src Pointer to the address where the data should be copied from.
+ * This address can be in flash or RAM.
+ * @param[in] len The number of bytes to be copied from @p p_src to @p dest.
+ * @param[in] callback Callback function.
+ *
+ * @retval NRF_SUCCESS If the operation was successful.
+ * @retval NRF_ERROR_INVALID_STATE If nrf_dfu_flash is not initialized.
+ * @retval NRF_ERROR_INVALID_ADDR If @p p_src or @p dest is not word-aligned.
+ * @retval NRF_ERROR_INVALID_LENGTH If @p len is zero.
+ * @retval NRF_ERROR_NULL If @p p_src is NULL.
+ * @retval NRF_ERROR_NO_MEM If nrf_fstorage is out of memory.
+ */
+ret_code_t nrf_dfu_flash_store(uint32_t dest,
+ void const * p_src,
+ uint32_t len,
+ nrf_dfu_flash_callback_t callback);
+
+
+/**@brief Function for erasing data from flash.
+ *
+ * This functions is asynchronous when the SoftDevice is enabled and synchronous when
+ * the SoftDevice is not present or disabled. In both cases, if a callback function is provided,
+ * it will be called when the operation has completed.
+ *
+ * @param[in] page_addr The address of the first flash page to be deleted.
+ * @param[in] num_pages The number of flash pages to be deleted.
+ * @param[in] callback Callback function.
+ *
+ * @retval NRF_SUCCESS If the operation was successful.
+ * @retval NRF_ERROR_INVALID_STATE If nrf_dfu_flash is not initialized.
+ * @retval NRF_ERROR_INVALID_ADDR If @p page_addr is not aligned to a page boundary or the
+ * operation would go beyond the flash memory boundaries.
+ * @retval NRF_ERROR_INVALID_LENGTH If @p num_pages is zero.
+ * @retval NRF_ERROR_NULL If @p page_addr is NULL.
+ * @retval NRF_ERROR_NO_MEM If the queue of nrf_fstorage is full.
+ */
+ret_code_t nrf_dfu_flash_erase(uint32_t page_addr, uint32_t num_pages, nrf_dfu_flash_callback_t callback);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+
+#endif // NRF_DFU_FLASH_H__
+/** @} */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/dfu/nrf_dfu_handling_error.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/dfu/nrf_dfu_handling_error.c
new file mode 100644
index 0000000..ba42123
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/dfu/nrf_dfu_handling_error.c
@@ -0,0 +1,61 @@
+/**
+ * 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+
+#include "nrf_dfu_handling_error.h"
+
+#include "nrf_log.h"
+#include "nrf_dfu_req_handler.h"
+
+static nrf_dfu_ext_error_code_t m_last_error = NRF_DFU_EXT_ERROR_NO_ERROR;
+
+nrf_dfu_result_t ext_error_set(nrf_dfu_ext_error_code_t error_code)
+{
+ m_last_error = error_code;
+
+ return NRF_DFU_RES_CODE_EXT_ERROR;
+}
+
+nrf_dfu_ext_error_code_t ext_error_get()
+{
+ nrf_dfu_ext_error_code_t last_error = m_last_error;
+ m_last_error = NRF_DFU_EXT_ERROR_NO_ERROR;
+
+ return last_error;
+}
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/dfu/nrf_dfu_handling_error.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/dfu/nrf_dfu_handling_error.h
new file mode 100644
index 0000000..5a459e9
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/dfu/nrf_dfu_handling_error.h
@@ -0,0 +1,124 @@
+/**
+ * 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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
+ *
+ * @defgroup nrf_dfu_rescodes DFU result codes
+ * @{
+ * @ingroup sdk_nrf_dfu_transport
+ * @brief When the DFU controller sends requests to the DFU bootloader on
+ * the DFU target, the DFU bootloader answers with any of these result codes.
+ */
+
+
+#ifndef DFU_HANDLING_ERROR_H__
+#define DFU_HANDLING_ERROR_H__
+
+#include "nrf_dfu_types.h"
+#include "nrf_dfu_req_handler.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+
+/**@brief DFU request extended result codes.
+ *
+ * @details When an event returns @ref NRF_DFU_RES_CODE_EXT_ERROR, it also stores an extended error code.
+ * The transport layer can then send the extended error code together with the error code to give
+ * the controller additional information about the cause of the error.
+ */
+typedef enum
+{
+ NRF_DFU_EXT_ERROR_NO_ERROR = 0x00, /**< No extended error code has been set. This error indicates an implementation problem. */
+ NRF_DFU_EXT_ERROR_INVALID_ERROR_CODE = 0x01, /**< Invalid error code. This error code should never be used outside of development. */
+ NRF_DFU_EXT_ERROR_WRONG_COMMAND_FORMAT = 0x02, /**< The format of the command was incorrect. This error code is not used in the
+ current implementation, because @ref NRF_DFU_RES_CODE_OP_CODE_NOT_SUPPORTED
+ and @ref NRF_DFU_RES_CODE_INVALID_PARAMETER cover all
+ possible format errors. */
+ NRF_DFU_EXT_ERROR_UNKNOWN_COMMAND = 0x03, /**< The command was successfully parsed, but it is not supported or unknown. */
+ NRF_DFU_EXT_ERROR_INIT_COMMAND_INVALID = 0x04, /**< The init command is invalid. The init packet either has
+ an invalid update type or it is missing required fields for the update type
+ (for example, the init packet for a SoftDevice update is missing the SoftDevice size field). */
+ NRF_DFU_EXT_ERROR_FW_VERSION_FAILURE = 0x05, /**< The firmware version is too low. For an application, the version must be greater than
+ the current application. For a bootloader, it must be greater than or equal
+ to the current version. This requirement prevents downgrade attacks.*/
+ NRF_DFU_EXT_ERROR_HW_VERSION_FAILURE = 0x06, /**< The hardware version of the device does not match the required
+ hardware version for the update. */
+ NRF_DFU_EXT_ERROR_SD_VERSION_FAILURE = 0x07, /**< The array of supported SoftDevices for the update does not contain
+ the FWID of the current SoftDevice. */
+ NRF_DFU_EXT_ERROR_SIGNATURE_MISSING = 0x08, /**< The init packet does not contain a signature. This error code is not used in the
+ current implementation, because init packets without a signature
+ are regarded as invalid. */
+ NRF_DFU_EXT_ERROR_WRONG_HASH_TYPE = 0x09, /**< The hash type that is specified by the init packet is not supported by the DFU bootloader. */
+ NRF_DFU_EXT_ERROR_HASH_FAILED = 0x0A, /**< The hash of the firmware image cannot be calculated. */
+ NRF_DFU_EXT_ERROR_WRONG_SIGNATURE_TYPE = 0x0B, /**< The type of the signature is unknown or not supported by the DFU bootloader. */
+ NRF_DFU_EXT_ERROR_VERIFICATION_FAILED = 0x0C, /**< The hash of the received firmware image does not match the hash in the init packet. */
+ NRF_DFU_EXT_ERROR_INSUFFICIENT_SPACE = 0x0D, /**< The available space on the device is insufficient to hold the firmware. */
+} nrf_dfu_ext_error_code_t;
+
+
+/**@brief Function for setting an extended error code that can be retrieved later.
+ *
+ * @details When an extended error occurs in the DFU process, this function can be used to store the error.
+ *
+ * @param error_code The error code to store.
+ *
+ * @retval NRF_DFU_RES_CODE_EXT_ERROR
+ */
+nrf_dfu_result_t ext_error_set(nrf_dfu_ext_error_code_t error_code);
+
+/**@brief Function for getting the most recent extended error code.
+ *
+ * @details This function is used by the transport layer to fetch the most recent extended error code.
+ *
+ * @return The most recent error code. If the function is called again before a new error occurs, @ref NRF_DFU_EXT_ERROR_NO_ERROR is returned.
+ */
+nrf_dfu_ext_error_code_t ext_error_get( void );
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // DFU_HANDLING_ERROR_H__
+
+/** @} */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/dfu/nrf_dfu_mbr.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/dfu/nrf_dfu_mbr.c
new file mode 100644
index 0000000..974a466
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/dfu/nrf_dfu_mbr.c
@@ -0,0 +1,109 @@
+/**
+ * Copyright (c) 2016 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#include "nrf_dfu_mbr.h"
+#include "nrf_mbr.h"
+#include "nrf_dfu_types.h"
+#include "nrf_log.h"
+#include "nrf_bootloader_info.h"
+
+#define MBR_IRQ_FORWARD_ADDRESS_ADDRESS (0x20000000) //!< The address of the variable that decides where the MBR forwards interrupts
+
+uint32_t nrf_dfu_mbr_copy_bl(uint32_t * p_src, uint32_t len)
+{
+ uint32_t ret_val;
+ uint32_t const len_words = len / sizeof(uint32_t);
+
+ sd_mbr_command_t command =
+ {
+ .command = SD_MBR_COMMAND_COPY_BL,
+ .params.copy_bl.bl_src = p_src,
+ .params.copy_bl.bl_len = len_words
+ };
+
+ ret_val = sd_mbr_command(&command);
+
+ return ret_val;
+}
+
+
+uint32_t nrf_dfu_mbr_init_sd(void)
+{
+ uint32_t ret_val;
+
+ sd_mbr_command_t command =
+ {
+ .command = SD_MBR_COMMAND_INIT_SD
+ };
+
+ ret_val = sd_mbr_command(&command);
+
+ return ret_val;
+}
+
+
+uint32_t nrf_dfu_mbr_irq_forward_address_set(void)
+{
+ uint32_t ret_val = NRF_ERROR_INVALID_PARAM;
+ uint32_t address = MBR_SIZE;
+
+ NRF_LOG_DEBUG("running irq table set");
+
+#ifndef BLE_STACK_SUPPORT_REQD
+ sd_mbr_command_t command =
+ {
+ .command = SD_MBR_COMMAND_IRQ_FORWARD_ADDRESS_SET,
+ .params.irq_forward_address_set.address = address,
+ };
+
+ ret_val = sd_mbr_command(&command);
+#endif
+
+ if (ret_val == NRF_ERROR_INVALID_PARAM)
+ {
+ // Manually set the forward address if this MBR doesn't have the command.
+ *(uint32_t *)(MBR_IRQ_FORWARD_ADDRESS_ADDRESS) = address;
+
+ ret_val = NRF_SUCCESS;
+ }
+
+ NRF_LOG_DEBUG("After running irq table set");
+
+ return ret_val;
+}
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/dfu/nrf_dfu_mbr.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/dfu/nrf_dfu_mbr.h
new file mode 100644
index 0000000..2fcd1b3
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/dfu/nrf_dfu_mbr.h
@@ -0,0 +1,90 @@
+/**
+ * Copyright (c) 2016 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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
+ *
+ * @defgroup sdk_nrf_dfu_mbr MBR functions
+ * @{
+ * @ingroup nrf_dfu
+ */
+
+#ifndef NRF_DFU_MBR_H__
+#define NRF_DFU_MBR_H__
+
+#include <stdint.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** @brief Function for copying the bootloader using an MBR command.
+ *
+ * @param[in] p_src Source address of the bootloader data to copy.
+ * @param[in] len Length of the data to copy in bytes.
+ *
+ * @return This function will return only if the command request could not be run.
+ * See @ref sd_mbr_command_copy_bl_t for possible return values.
+ */
+uint32_t nrf_dfu_mbr_copy_bl(uint32_t * p_src, uint32_t len);
+
+
+/** @brief Function for initializing the SoftDevice using an MBR command.
+ *
+ * @retval NRF_SUCCESS If the SoftDevice was initialized successfully.
+ * Any other return value indicates that the SoftDevice
+ * could not be initialized.
+ */
+uint32_t nrf_dfu_mbr_init_sd(void);
+
+
+/** @brief Function for setting the address of the IRQ table to the app's using an MBR command.
+ *
+ * @retval NRF_SUCCESS If the address of the new irq table was set. Any other
+ * return value indicates that the address could not be set.
+ */
+uint32_t nrf_dfu_mbr_irq_forward_address_set(void);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // NRF_DFU_MBR_H__
+
+/** @} */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/dfu/nrf_dfu_req_handler.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/dfu/nrf_dfu_req_handler.c
new file mode 100644
index 0000000..6dfb1cc
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/dfu/nrf_dfu_req_handler.c
@@ -0,0 +1,855 @@
+/**
+ * Copyright (c) 2016 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#include <stdint.h>
+#include <stdbool.h>
+#include "sdk_config.h"
+#include "nrf_dfu.h"
+#include "nrf_dfu_types.h"
+#include "nrf_dfu_req_handler.h"
+#include "nrf_dfu_handling_error.h"
+#include "nrf_dfu_settings.h"
+#include "nrf_dfu_utils.h"
+#include "nrf_dfu_flash.h"
+#include "nrf_fstorage.h"
+#include "nrf_bootloader_info.h"
+#include "app_util.h"
+#include "pb.h"
+#include "pb_common.h"
+#include "pb_decode.h"
+#include "dfu-cc.pb.h"
+#include "crc32.h"
+#include "app_scheduler.h"
+#include "sdk_macros.h"
+#include "nrf_crypto.h"
+#include "nrf_assert.h"
+#include "nrf_dfu_validation.h"
+
+#define NRF_LOG_MODULE_NAME nrf_dfu_req_handler
+#include "nrf_log.h"
+NRF_LOG_MODULE_REGISTER();
+
+#define NRF_DFU_PROTOCOL_VERSION (0x01)
+
+
+STATIC_ASSERT(DFU_SIGNED_COMMAND_SIZE <= INIT_COMMAND_MAX_SIZE);
+
+static uint32_t m_firmware_start_addr; /**< Start address of the current firmware image. */
+static uint32_t m_firmware_size_req; /**< The size of the entire firmware image. Defined by the init command. */
+
+static nrf_dfu_observer_t m_observer;
+
+
+static void on_dfu_complete(nrf_fstorage_evt_t * p_evt)
+{
+ UNUSED_PARAMETER(p_evt);
+
+ NRF_LOG_DEBUG("All flash operations have completed. DFU completed.");
+
+ m_observer(NRF_DFU_EVT_DFU_COMPLETED);
+}
+
+
+static nrf_dfu_result_t ext_err_code_handle(nrf_dfu_result_t ret_val)
+{
+ if (ret_val < NRF_DFU_RES_CODE_EXT_ERROR)
+ {
+ return ret_val;
+ }
+ else
+ {
+ nrf_dfu_ext_error_code_t ext_err =
+ (nrf_dfu_ext_error_code_t)((uint8_t)ret_val - (uint8_t)NRF_DFU_RES_CODE_EXT_ERROR);
+ return ext_error_set(ext_err);
+ }
+}
+
+
+static void on_protocol_version_request(nrf_dfu_request_t const * p_req, nrf_dfu_response_t * p_res)
+{
+ UNUSED_PARAMETER(p_req);
+ NRF_LOG_DEBUG("Handle NRF_DFU_OP_PROTOCOL_VERSION");
+
+ if (NRF_DFU_PROTOCOL_VERSION_MSG)
+ {
+ p_res->protocol.version = NRF_DFU_PROTOCOL_VERSION;
+ }
+ else
+ {
+ NRF_LOG_DEBUG("NRF_DFU_OP_PROTOCOL_VERSION disabled.");
+ p_res->result = NRF_DFU_RES_CODE_OP_CODE_NOT_SUPPORTED;
+ }
+}
+
+
+static void on_hw_version_request(nrf_dfu_request_t const * p_req, nrf_dfu_response_t * p_res)
+{
+ NRF_LOG_DEBUG("Handle NRF_DFU_OP_HARDWARE_VERSION");
+
+ p_res->hardware.part = NRF_FICR->INFO.PART;
+ p_res->hardware.variant = NRF_FICR->INFO.VARIANT;
+
+ /* FICR values are in Kilobytes, we report them in bytes. */
+ p_res->hardware.memory.ram_size = NRF_FICR->INFO.RAM * 1024;
+ p_res->hardware.memory.rom_size = NRF_FICR->INFO.FLASH * 1024;
+ p_res->hardware.memory.rom_page_size = NRF_FICR->CODEPAGESIZE;
+}
+
+
+static void on_fw_version_request(nrf_dfu_request_t const * p_req, nrf_dfu_response_t * p_res)
+{
+ NRF_LOG_DEBUG("Handle NRF_DFU_OP_FIRMWARE_VERSION");
+ NRF_LOG_DEBUG("Firmware image requested: %d", p_req->firmware.image_number);
+
+ if (NRF_DFU_PROTOCOL_FW_VERSION_MSG)
+ {
+ uint8_t fw_count = 1;
+
+ if (SD_PRESENT)
+ {
+ fw_count++;
+ }
+
+ if (s_dfu_settings.bank_0.bank_code == NRF_DFU_BANK_VALID_APP)
+ {
+ fw_count++;
+ }
+
+ p_res->result = NRF_DFU_RES_CODE_SUCCESS;
+
+ if (p_req->firmware.image_number == 0)
+ {
+ /* Bootloader is always present and it is always image zero. */
+ p_res->firmware.type = NRF_DFU_FIRMWARE_TYPE_BOOTLOADER;
+ p_res->firmware.version = s_dfu_settings.bootloader_version;
+ p_res->firmware.addr = BOOTLOADER_START_ADDR;
+ p_res->firmware.len = BOOTLOADER_SIZE;
+ }
+ else if ((p_req->firmware.image_number == 1) && SD_PRESENT)
+ {
+ /* If a SoftDevice is present, it will be firmware image one. */
+ p_res->firmware.type = NRF_DFU_FIRMWARE_TYPE_SOFTDEVICE;
+ p_res->firmware.version = SD_VERSION_GET(MBR_SIZE);
+ p_res->firmware.addr = MBR_SIZE;
+ p_res->firmware.len = SD_SIZE_GET(MBR_SIZE);
+ }
+ else if ((p_req->firmware.image_number < fw_count))
+ {
+ /* Either there is no SoftDevice and the firmware image requested is one,
+ * or there is a SoftDevice and the firmware image requested is two.
+ */
+ p_res->firmware.type = NRF_DFU_FIRMWARE_TYPE_APPLICATION;
+ p_res->firmware.version = s_dfu_settings.app_version;
+ p_res->firmware.addr = nrf_dfu_app_start_address();
+ p_res->firmware.len = s_dfu_settings.bank_0.image_size;
+ }
+ else
+ {
+ NRF_LOG_DEBUG("No such firmware image");
+ p_res->firmware.type = NRF_DFU_FIRMWARE_TYPE_UNKNOWN;
+ p_res->firmware.version = 0x00;
+ p_res->firmware.addr = 0x00;
+ p_res->firmware.len = 0x00;
+ }
+ }
+ else
+ {
+ NRF_LOG_DEBUG("NRF_DFU_OP_FIRMWARE_VERSION disabled.");
+ p_res->result = NRF_DFU_RES_CODE_OP_CODE_NOT_SUPPORTED;
+ p_res->firmware.type = NRF_DFU_FIRMWARE_TYPE_UNKNOWN;
+ }
+}
+
+
+static void on_ping_request(nrf_dfu_request_t * p_req, nrf_dfu_response_t * p_res)
+{
+ NRF_LOG_DEBUG("Handle NRF_DFU_OP_PING");
+ p_res->ping.id = p_req->ping.id;
+}
+
+
+static void on_mtu_get_request(nrf_dfu_request_t * p_req, nrf_dfu_response_t * p_res)
+{
+ NRF_LOG_DEBUG("Handle NRF_DFU_OP_MTU_GET");
+ p_res->mtu.size = p_req->mtu.size;
+}
+
+
+static void on_prn_set_request(nrf_dfu_request_t * p_req, nrf_dfu_response_t * p_res)
+{
+ UNUSED_PARAMETER(p_req);
+ UNUSED_PARAMETER(p_res);
+ NRF_LOG_DEBUG("Handle NRF_DFU_OP_RECEIPT_NOTIF_SET");
+}
+
+
+static void on_abort_request(nrf_dfu_request_t * p_req, nrf_dfu_response_t * p_res)
+{
+ UNUSED_PARAMETER(p_req);
+ UNUSED_PARAMETER(p_res);
+ NRF_LOG_DEBUG("Handle NRF_DFU_OP_ABORT");
+
+ m_observer(NRF_DFU_EVT_DFU_ABORTED);
+}
+
+
+/* Set offset and CRC fields in the response for a 'command' message. */
+static void cmd_response_offset_and_crc_set(nrf_dfu_response_t * const p_res)
+{
+ ASSERT(p_res);
+
+ /* Copy the CRC and offset of the init packet. */
+ p_res->crc.offset = s_dfu_settings.progress.command_offset;
+ p_res->crc.crc = s_dfu_settings.progress.command_crc;
+}
+
+
+static void on_cmd_obj_select_request(nrf_dfu_request_t const * p_req, nrf_dfu_response_t * p_res)
+{
+ UNUSED_PARAMETER(p_req);
+ NRF_LOG_DEBUG("Handle NRF_DFU_OP_OBJECT_SELECT (command)");
+
+ p_res->select.max_size = INIT_COMMAND_MAX_SIZE;
+ cmd_response_offset_and_crc_set(p_res);
+}
+
+
+static void on_cmd_obj_create_request(nrf_dfu_request_t * p_req, nrf_dfu_response_t * p_res)
+{
+ ASSERT(p_req);
+ ASSERT(p_res);
+
+ NRF_LOG_DEBUG("Handle NRF_DFU_OP_OBJECT_CREATE (command)");
+
+ m_observer(NRF_DFU_EVT_DFU_STARTED);
+
+ nrf_dfu_result_t ret_val = nrf_dfu_validation_init_cmd_create(p_req->create.object_size);
+ p_res->result = ext_err_code_handle(ret_val);
+}
+
+
+static void on_cmd_obj_write_request(nrf_dfu_request_t * p_req, nrf_dfu_response_t * p_res)
+{
+ ASSERT(p_req);
+ ASSERT(p_req->write.p_data);
+ ASSERT(p_req->write.len);
+ ASSERT(p_res);
+
+ NRF_LOG_DEBUG("Handle NRF_DFU_OP_OBJECT_WRITE (command)");
+
+ nrf_dfu_result_t ret_val;
+
+ ret_val = nrf_dfu_validation_init_cmd_append(p_req->write.p_data, p_req->write.len);
+ p_res->result = ext_err_code_handle(ret_val);
+
+ /* Update response. This is only used when the PRN is triggered and the 'write' message
+ * is answered with a CRC message and these field are copied into the response. */
+ cmd_response_offset_and_crc_set(p_res);
+
+ /* If a callback to free the request payload buffer was provided, invoke it now. */
+ if (p_req->callback.write)
+ {
+ p_req->callback.write((void*)p_req->write.p_data);
+ }
+}
+
+
+static void on_cmd_obj_execute_request(nrf_dfu_request_t const * p_req, nrf_dfu_response_t * p_res)
+{
+ ASSERT(p_req);
+ ASSERT(p_res);
+
+ NRF_LOG_DEBUG("Handle NRF_DFU_OP_OBJECT_EXECUTE (command)");
+
+ nrf_dfu_result_t ret_val;
+ ret_val = nrf_dfu_validation_init_cmd_execute(&m_firmware_start_addr, &m_firmware_size_req);
+ p_res->result = ext_err_code_handle(ret_val);
+
+ if (p_res->result == NRF_DFU_RES_CODE_SUCCESS)
+ {
+ if (nrf_dfu_settings_write(NULL) == NRF_SUCCESS)
+ {
+ /* Setting DFU to initialized */
+ NRF_LOG_DEBUG("Writing valid init command to flash.");
+ }
+ else
+ {
+ p_res->result = NRF_DFU_RES_CODE_OPERATION_FAILED;
+ }
+ }
+}
+
+
+static void on_cmd_obj_crc_request(nrf_dfu_request_t const * p_req, nrf_dfu_response_t * p_res)
+{
+ UNUSED_PARAMETER(p_req);
+ NRF_LOG_DEBUG("Handle NRF_DFU_OP_CRC_GET (command)");
+
+ cmd_response_offset_and_crc_set(p_res);
+}
+
+
+/** @brief Function handling command requests from the transport layer.
+ *
+ * @param p_req[in] Pointer to the structure holding the DFU request.
+ * @param p_res[out] Pointer to the structure holding the DFU response.
+ *
+ * @retval NRF_SUCCESS If the command request was executed successfully.
+ * Any other error code indicates that the data request
+ * could not be handled.
+ */
+static void nrf_dfu_command_req(nrf_dfu_request_t * p_req, nrf_dfu_response_t * p_res)
+{
+ ASSERT(p_req);
+ ASSERT(p_res);
+
+ switch (p_req->request)
+ {
+ case NRF_DFU_OP_OBJECT_CREATE:
+ {
+ on_cmd_obj_create_request(p_req, p_res);
+ } break;
+
+ case NRF_DFU_OP_CRC_GET:
+ {
+ on_cmd_obj_crc_request(p_req, p_res);
+ } break;
+
+ case NRF_DFU_OP_OBJECT_WRITE:
+ {
+ on_cmd_obj_write_request(p_req, p_res);
+ } break;
+
+ case NRF_DFU_OP_OBJECT_EXECUTE:
+ {
+ on_cmd_obj_execute_request(p_req, p_res);
+ } break;
+
+ case NRF_DFU_OP_OBJECT_SELECT:
+ {
+ on_cmd_obj_select_request(p_req, p_res);
+ } break;
+
+ default:
+ {
+ ASSERT(false);
+ } break;
+ }
+}
+
+
+static void on_data_obj_select_request(nrf_dfu_request_t * p_req, nrf_dfu_response_t * p_res)
+{
+ NRF_LOG_DEBUG("Handle NRF_DFU_OP_OBJECT_SELECT (data)");
+
+ p_res->select.crc = s_dfu_settings.progress.firmware_image_crc;
+ p_res->select.offset = s_dfu_settings.progress.firmware_image_offset;
+
+ p_res->select.max_size = DATA_OBJECT_MAX_SIZE;
+
+ NRF_LOG_DEBUG("crc = 0x%x, offset = 0x%x, max_size = 0x%x",
+ p_res->select.crc,
+ p_res->select.offset,
+ p_res->select.max_size);
+}
+
+
+static void on_data_obj_create_request(nrf_dfu_request_t * p_req, nrf_dfu_response_t * p_res)
+{
+ NRF_LOG_DEBUG("Handle NRF_DFU_OP_OBJECT_CREATE (data)");
+
+ if (!nrf_dfu_validation_init_cmd_present())
+ {
+ /* Can't accept data because DFU isn't initialized by init command. */
+ NRF_LOG_ERROR("Cannot create data object without valid init command");
+ p_res->result = NRF_DFU_RES_CODE_OPERATION_NOT_PERMITTED;
+ return;
+ }
+
+ if (p_req->create.object_size == 0)
+ {
+ NRF_LOG_ERROR("Object size cannot be 0.")
+ p_res->result = NRF_DFU_RES_CODE_INVALID_PARAMETER;
+ return;
+ }
+
+ if ( ((p_req->create.object_size & (CODE_PAGE_SIZE - 1)) != 0)
+ && (s_dfu_settings.progress.firmware_image_offset_last + p_req->create.object_size != m_firmware_size_req))
+ {
+ NRF_LOG_ERROR("Object size must be page aligned");
+ p_res->result = NRF_DFU_RES_CODE_INVALID_PARAMETER;
+ return;
+ }
+
+ if (p_req->create.object_size > DATA_OBJECT_MAX_SIZE)
+ {
+ /* It is impossible to handle the command because the size is too large */
+ NRF_LOG_ERROR("Invalid size for object (too large)");
+ p_res->result = NRF_DFU_RES_CODE_INSUFFICIENT_RESOURCES;
+ return;
+ }
+
+ if ((s_dfu_settings.progress.firmware_image_offset_last + p_req->create.object_size) >
+ m_firmware_size_req)
+ {
+ NRF_LOG_ERROR("Creating the object with size 0x%08x would overflow firmware size. "
+ "Offset is 0x%08x and firmware size is 0x%08x.",
+ p_req->create.object_size,
+ s_dfu_settings.progress.firmware_image_offset_last,
+ m_firmware_size_req);
+
+ p_res->result = NRF_DFU_RES_CODE_OPERATION_NOT_PERMITTED;
+ return;
+ }
+
+ s_dfu_settings.progress.data_object_size = p_req->create.object_size;
+ s_dfu_settings.progress.firmware_image_crc = s_dfu_settings.progress.firmware_image_crc_last;
+ s_dfu_settings.progress.firmware_image_offset = s_dfu_settings.progress.firmware_image_offset_last;
+ s_dfu_settings.write_offset = s_dfu_settings.progress.firmware_image_offset_last;
+
+ /* Erase the page we're at. */
+ if (nrf_dfu_flash_erase((m_firmware_start_addr + s_dfu_settings.progress.firmware_image_offset),
+ CEIL_DIV(p_req->create.object_size, CODE_PAGE_SIZE), NULL) != NRF_SUCCESS)
+ {
+ NRF_LOG_ERROR("Erase operation failed");
+ p_res->result = NRF_DFU_RES_CODE_INVALID_OBJECT;
+ return;
+ }
+
+ NRF_LOG_DEBUG("Creating object with size: %d. Offset: 0x%08x, CRC: 0x%08x",
+ s_dfu_settings.progress.data_object_size,
+ s_dfu_settings.progress.firmware_image_offset,
+ s_dfu_settings.progress.firmware_image_crc);
+}
+
+
+static void on_data_obj_write_request(nrf_dfu_request_t * p_req, nrf_dfu_response_t * p_res)
+{
+ NRF_LOG_DEBUG("Handle NRF_DFU_OP_OBJECT_WRITE (data)");
+
+ if (!nrf_dfu_validation_init_cmd_present())
+ {
+ /* Can't accept data because DFU isn't initialized by init command. */
+ p_res->result = NRF_DFU_RES_CODE_OPERATION_NOT_PERMITTED;
+ return;
+ }
+
+ uint32_t const data_object_offset = s_dfu_settings.progress.firmware_image_offset -
+ s_dfu_settings.progress.firmware_image_offset_last;
+
+ if ((p_req->write.len + data_object_offset) > s_dfu_settings.progress.data_object_size)
+ {
+ /* Can't accept data because too much data has been received. */
+ NRF_LOG_ERROR("Write request too long");
+ p_res->result = NRF_DFU_RES_CODE_INVALID_PARAMETER;
+ return;
+ }
+
+ uint32_t const write_addr = m_firmware_start_addr + s_dfu_settings.write_offset;
+
+ ASSERT(p_req->callback.write);
+
+ ret_code_t ret =
+ nrf_dfu_flash_store(write_addr, p_req->write.p_data, p_req->write.len, p_req->callback.write);
+
+ if (ret != NRF_SUCCESS)
+ {
+ /* When nrf_dfu_flash_store() fails because there is no space in the queue,
+ * stop processing the request so that the peer can detect a CRC error
+ * and retransmit this object. Remember to manually free the buffer !
+ */
+ p_req->callback.write((void*)p_req->write.p_data);
+ return;
+ }
+
+ /* Update the CRC of the firmware image. */
+ s_dfu_settings.write_offset += p_req->write.len;
+ s_dfu_settings.progress.firmware_image_offset += p_req->write.len;
+ s_dfu_settings.progress.firmware_image_crc =
+ crc32_compute(p_req->write.p_data, p_req->write.len, &s_dfu_settings.progress.firmware_image_crc);
+
+ /* This is only used when the PRN is triggered and the 'write' message
+ * is answered with a CRC message and these field are copied into the response.
+ */
+ p_res->write.crc = s_dfu_settings.progress.firmware_image_crc;
+ p_res->write.offset = s_dfu_settings.progress.firmware_image_offset;
+}
+
+
+static void on_data_obj_crc_request(nrf_dfu_request_t * p_req, nrf_dfu_response_t * p_res)
+{
+ NRF_LOG_DEBUG("Handle NRF_DFU_OP_CRC_GET (data)");
+ NRF_LOG_DEBUG("Offset:%d, CRC:0x%08x",
+ s_dfu_settings.progress.firmware_image_offset,
+ s_dfu_settings.progress.firmware_image_crc);
+
+ p_res->crc.crc = s_dfu_settings.progress.firmware_image_crc;
+ p_res->crc.offset = s_dfu_settings.progress.firmware_image_offset;
+}
+
+
+static void on_data_obj_execute_request_sched(void * p_evt, uint16_t event_length)
+{
+ UNUSED_PARAMETER(event_length);
+
+ nrf_dfu_request_t * p_req = (nrf_dfu_request_t *)(p_evt);
+
+ /* Wait for all buffers to be written in flash. */
+ if (nrf_fstorage_is_busy(NULL))
+ {
+ ret_code_t ret = app_sched_event_put(p_req,
+ sizeof(nrf_dfu_request_t),
+ on_data_obj_execute_request_sched);
+ if (ret != NRF_SUCCESS)
+ {
+ NRF_LOG_ERROR("Failed to schedule object execute: 0x%x.", ret);
+ }
+ return;
+ }
+
+ nrf_dfu_response_t res =
+ {
+ .request = NRF_DFU_OP_OBJECT_EXECUTE,
+ };
+
+ nrf_dfu_flash_callback_t dfu_settings_callback;
+
+ /* Whole firmware image was received, validate it. */
+ if (s_dfu_settings.progress.firmware_image_offset == m_firmware_size_req)
+ {
+ NRF_LOG_DEBUG("Postvalidation of firmware image.");
+
+ res.result = nrf_dfu_validation_post_data_execute(m_firmware_start_addr, m_firmware_size_req);
+ res.result = ext_err_code_handle(res.result);
+
+ /* Callback to on_dfu_complete() after updating the settings. */
+ dfu_settings_callback = (nrf_dfu_flash_callback_t)(on_dfu_complete);
+ }
+ else
+ {
+ res.result = NRF_DFU_RES_CODE_SUCCESS;
+ /* No callback required. */
+ dfu_settings_callback = NULL;
+ }
+
+ /* Provide response to transport */
+ p_req->callback.response(&res, p_req->p_context);
+
+ /* Store settings to flash if the whole image was received or if configured
+ * to save progress information in flash.
+ */
+ if ((dfu_settings_callback != NULL) || NRF_DFU_SAVE_PROGRESS_IN_FLASH)
+ {
+ ret_code_t ret = nrf_dfu_settings_write(dfu_settings_callback);
+ UNUSED_RETURN_VALUE(ret);
+ }
+
+ NRF_LOG_DEBUG("Request handling complete. Result: 0x%x", res.result);
+}
+
+
+static bool on_data_obj_execute_request(nrf_dfu_request_t * p_req, nrf_dfu_response_t * p_res)
+{
+ NRF_LOG_DEBUG("Handle NRF_DFU_OP_OBJECT_EXECUTE (data)");
+
+ uint32_t const data_object_size = s_dfu_settings.progress.firmware_image_offset -
+ s_dfu_settings.progress.firmware_image_offset_last;
+
+ if (s_dfu_settings.progress.data_object_size != data_object_size)
+ {
+ /* The size of the written object was not as expected. */
+ NRF_LOG_ERROR("Invalid data. expected: %d, got: %d",
+ s_dfu_settings.progress.data_object_size,
+ data_object_size);
+
+ p_res->result = NRF_DFU_RES_CODE_OPERATION_NOT_PERMITTED;
+ return true;
+ }
+
+ /* Update the offset and crc values for the last object written. */
+ s_dfu_settings.progress.data_object_size = 0;
+ s_dfu_settings.progress.firmware_image_crc_last = s_dfu_settings.progress.firmware_image_crc;
+ s_dfu_settings.progress.firmware_image_offset_last = s_dfu_settings.progress.firmware_image_offset;
+
+ on_data_obj_execute_request_sched(p_req, 0);
+
+ m_observer(NRF_DFU_EVT_OBJECT_RECEIVED);
+
+ return false;
+}
+
+
+static bool nrf_dfu_data_req(nrf_dfu_request_t * p_req, nrf_dfu_response_t * p_res)
+{
+ ASSERT(p_req);
+ ASSERT(p_res);
+
+ bool response_ready = true;
+
+ switch (p_req->request)
+ {
+ case NRF_DFU_OP_OBJECT_CREATE:
+ {
+ on_data_obj_create_request(p_req, p_res);
+ } break;
+
+ case NRF_DFU_OP_OBJECT_WRITE:
+ {
+ on_data_obj_write_request(p_req, p_res);
+ } break;
+
+ case NRF_DFU_OP_CRC_GET:
+ {
+ on_data_obj_crc_request(p_req, p_res);
+ } break;
+
+ case NRF_DFU_OP_OBJECT_EXECUTE:
+ {
+ response_ready = on_data_obj_execute_request(p_req, p_res);
+ } break;
+
+ case NRF_DFU_OP_OBJECT_SELECT:
+ {
+ on_data_obj_select_request(p_req, p_res);
+ } break;
+
+ default:
+ {
+ ASSERT(false);
+ } break;
+ }
+
+ return response_ready;
+}
+
+
+/**@brief Function for handling requests to manipulate data or command objects.
+ *
+ * @param[in] p_req Request.
+ * @param[out] p_res Response.
+ *
+ * @return Whether response is ready to be sent.
+ */
+static bool nrf_dfu_obj_op(nrf_dfu_request_t * p_req, nrf_dfu_response_t * p_res)
+{
+ /* Keep track of the current object type since write and execute requests don't contain it. */
+ static nrf_dfu_obj_type_t current_object = NRF_DFU_OBJ_TYPE_COMMAND;
+
+ if ( (p_req->request == NRF_DFU_OP_OBJECT_SELECT)
+ || (p_req->request == NRF_DFU_OP_OBJECT_CREATE))
+ {
+ STATIC_ASSERT(offsetof(nrf_dfu_request_select_t, object_type) ==
+ offsetof(nrf_dfu_request_create_t, object_type),
+ "Wrong object_type offset!");
+
+ current_object = (nrf_dfu_obj_type_t)(p_req->select.object_type);
+ }
+
+ bool response_ready = true;
+
+ switch (current_object)
+ {
+ case NRF_DFU_OBJ_TYPE_COMMAND:
+ nrf_dfu_command_req(p_req, p_res);
+ break;
+
+ case NRF_DFU_OBJ_TYPE_DATA:
+ response_ready = nrf_dfu_data_req(p_req, p_res);
+ break;
+
+ default:
+ /* The select request had an invalid object type. */
+ NRF_LOG_ERROR("Invalid object type in request.");
+ current_object = NRF_DFU_OBJ_TYPE_INVALID;
+ p_res->result = NRF_DFU_RES_CODE_INVALID_OBJECT;
+ break;
+ }
+
+ return response_ready;
+}
+
+
+static void nrf_dfu_req_handler_req_process(nrf_dfu_request_t * p_req)
+{
+ ASSERT(p_req->callback.response);
+
+ bool response_ready = true;
+
+ /* The request handlers assume these values to be set. */
+ nrf_dfu_response_t response =
+ {
+ .request = p_req->request,
+ .result = NRF_DFU_RES_CODE_SUCCESS,
+ };
+
+
+ switch (p_req->request)
+ {
+ case NRF_DFU_OP_PROTOCOL_VERSION:
+ {
+ on_protocol_version_request(p_req, &response);
+ } break;
+
+ case NRF_DFU_OP_HARDWARE_VERSION:
+ {
+ on_hw_version_request(p_req, &response);
+ } break;
+
+ case NRF_DFU_OP_FIRMWARE_VERSION:
+ {
+ on_fw_version_request(p_req, &response);
+ } break;
+
+ case NRF_DFU_OP_PING:
+ {
+ on_ping_request(p_req, &response);
+ } break;
+
+ case NRF_DFU_OP_RECEIPT_NOTIF_SET:
+ {
+ on_prn_set_request(p_req, &response);
+ } break;
+
+ case NRF_DFU_OP_MTU_GET:
+ {
+ on_mtu_get_request(p_req, &response);
+ } break;
+
+ case NRF_DFU_OP_ABORT:
+ {
+ on_abort_request(p_req, &response);
+ } break;
+
+ case NRF_DFU_OP_OBJECT_CREATE:
+ /* Restart the inactivity timer on CREATE messages. */
+ /* Fallthrough. */
+ case NRF_DFU_OP_OBJECT_SELECT:
+ case NRF_DFU_OP_OBJECT_WRITE:
+ case NRF_DFU_OP_OBJECT_EXECUTE:
+ case NRF_DFU_OP_CRC_GET:
+ {
+ response_ready = nrf_dfu_obj_op(p_req, &response);
+ } break;
+
+ default:
+ NRF_LOG_INFO("Invalid opcode received: 0x%x.", p_req->request);
+ response.result = NRF_DFU_RES_CODE_OP_CODE_NOT_SUPPORTED;
+ break;
+ }
+
+ if (response_ready)
+ {
+ NRF_LOG_DEBUG("Request handling complete. Result: 0x%x", response.result);
+
+ p_req->callback.response(&response, p_req->p_context);
+
+ if (response.result != NRF_DFU_RES_CODE_SUCCESS)
+ {
+ m_observer(NRF_DFU_EVT_DFU_FAILED);
+ }
+ }
+}
+
+
+static void nrf_dfu_req_handler_req(void * p_evt, uint16_t event_length)
+{
+ nrf_dfu_request_t * p_req = (nrf_dfu_request_t *)(p_evt);
+ nrf_dfu_req_handler_req_process(p_req);
+}
+
+
+ret_code_t nrf_dfu_req_handler_on_req(nrf_dfu_request_t * p_req)
+{
+ ret_code_t ret;
+
+ if (p_req->callback.response == NULL)
+ {
+ return NRF_ERROR_INVALID_PARAM;
+ }
+
+ ret = app_sched_event_put(p_req, sizeof(nrf_dfu_request_t), nrf_dfu_req_handler_req);
+ if (ret != NRF_SUCCESS)
+ {
+ NRF_LOG_WARNING("Scheduler ran out of space!");
+ }
+
+ return ret;
+}
+
+
+ret_code_t nrf_dfu_req_handler_init(nrf_dfu_observer_t observer)
+{
+ ret_code_t ret_val;
+ nrf_dfu_result_t result;
+
+ if (observer == NULL)
+ {
+ return NRF_ERROR_INVALID_PARAM;
+ }
+
+#ifdef BLE_STACK_SUPPORT_REQD
+ ret_val = nrf_dfu_flash_init(true);
+#else
+ ret_val = nrf_dfu_flash_init(false);
+#endif
+ if (ret_val != NRF_SUCCESS)
+ {
+ return ret_val;
+ }
+
+ nrf_dfu_validation_init();
+ if (nrf_dfu_validation_init_cmd_present())
+ {
+ /* Execute a previously received init packed. Subsequent executes will have no effect. */
+ result = nrf_dfu_validation_init_cmd_execute(&m_firmware_start_addr, &m_firmware_size_req);
+ if (result != NRF_DFU_RES_CODE_SUCCESS)
+ {
+ /* Init packet in flash is not valid! */
+ return NRF_ERROR_INTERNAL;
+ }
+ }
+
+ m_observer = observer;
+
+ /* Initialize extended error handling with "No error" as the most recent error. */
+ result = ext_error_set(NRF_DFU_EXT_ERROR_NO_ERROR);
+ UNUSED_RETURN_VALUE(result);
+
+ return NRF_SUCCESS;
+}
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/dfu/nrf_dfu_req_handler.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/dfu/nrf_dfu_req_handler.h
new file mode 100644
index 0000000..c9d10d2
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/dfu/nrf_dfu_req_handler.h
@@ -0,0 +1,345 @@
+/**
+ * Copyright (c) 2016 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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
+ *
+ * @defgroup sdk_nrf_dfu_req_handler Request handling
+ * @{
+ * @ingroup nrf_dfu
+ */
+
+#ifndef NRF_DFU_REQ_HANDLER_H__
+#define NRF_DFU_REQ_HANDLER_H__
+
+#include <stdint.h>
+#include <stdbool.h>
+#include "app_util_platform.h"
+#include "nrf_dfu_flash.h"
+#include "nrf_dfu_types.h"
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+ANON_UNIONS_ENABLE;
+
+/**
+ * @brief DFU object types.
+ */
+typedef enum
+{
+ NRF_DFU_OBJ_TYPE_INVALID, //!< Invalid object type.
+ NRF_DFU_OBJ_TYPE_COMMAND, //!< Command object.
+ NRF_DFU_OBJ_TYPE_DATA, //!< Data object.
+} nrf_dfu_obj_type_t;
+
+/**
+ * @brief DFU protocol operation.
+ */
+typedef enum
+{
+ NRF_DFU_OP_PROTOCOL_VERSION = 0x00, //!< Retrieve protocol version.
+ NRF_DFU_OP_OBJECT_CREATE = 0x01, //!< Create selected object.
+ NRF_DFU_OP_RECEIPT_NOTIF_SET = 0x02, //!< Set receipt notification.
+ NRF_DFU_OP_CRC_GET = 0x03, //!< Request CRC of selected object.
+ NRF_DFU_OP_OBJECT_EXECUTE = 0x04, //!< Execute selected object.
+ NRF_DFU_OP_OBJECT_SELECT = 0x06, //!< Select object.
+ NRF_DFU_OP_MTU_GET = 0x07, //!< Retrieve MTU size.
+ NRF_DFU_OP_OBJECT_WRITE = 0x08, //!< Write selected object.
+ NRF_DFU_OP_PING = 0x09, //!< Ping.
+ NRF_DFU_OP_HARDWARE_VERSION = 0x0A, //!< Retrieve hardware version.
+ NRF_DFU_OP_FIRMWARE_VERSION = 0x0B, //!< Retrieve firmware version.
+ NRF_DFU_OP_ABORT = 0x0C, //!< Abort the DFU procedure.
+ NRF_DFU_OP_RESPONSE = 0x60, //!< Response.
+ NRF_DFU_OP_INVALID = 0xFF,
+} nrf_dfu_op_t;
+
+/**
+ * @brief DFU operation result code.
+ */
+typedef enum
+{
+ NRF_DFU_RES_CODE_INVALID = 0x00, //!< Invalid opcode.
+ NRF_DFU_RES_CODE_SUCCESS = 0x01, //!< Operation successful.
+ NRF_DFU_RES_CODE_OP_CODE_NOT_SUPPORTED = 0x02, //!< Opcode not supported.
+ NRF_DFU_RES_CODE_INVALID_PARAMETER = 0x03, //!< Missing or invalid parameter value.
+ NRF_DFU_RES_CODE_INSUFFICIENT_RESOURCES = 0x04, //!< Not enough memory for the data object.
+ NRF_DFU_RES_CODE_INVALID_OBJECT = 0x05, //!< Data object does not match the firmware and hardware requirements, the signature is wrong, or parsing the command failed.
+ NRF_DFU_RES_CODE_UNSUPPORTED_TYPE = 0x07, //!< Not a valid object type for a Create request.
+ NRF_DFU_RES_CODE_OPERATION_NOT_PERMITTED = 0x08, //!< The state of the DFU process does not allow this operation.
+ NRF_DFU_RES_CODE_OPERATION_FAILED = 0x0A, //!< Operation failed.
+ NRF_DFU_RES_CODE_EXT_ERROR = 0x0B, //!< Extended error. The next byte of the response contains the error code of the extended error (see @ref nrf_dfu_ext_error_code_t.
+} nrf_dfu_result_t;
+
+typedef enum
+{
+ NRF_DFU_FIRMWARE_TYPE_SOFTDEVICE = 0x00,
+ NRF_DFU_FIRMWARE_TYPE_APPLICATION = 0x01,
+ NRF_DFU_FIRMWARE_TYPE_BOOTLOADER = 0x02,
+ NRF_DFU_FIRMWARE_TYPE_UNKNOWN = 0xFF,
+} nrf_dfu_firmware_type_t;
+
+/**
+ * @brief @ref NRF_DFU_OP_PROTOCOL_VERSION response details.
+ */
+typedef struct
+{
+ uint8_t version; //!< Protocol version.
+} nrf_dfu_response_protocol_t;
+
+/**
+ * @brief @ref NRF_DFU_OP_HARDWARE_VERSION response details.
+ */
+typedef struct
+{
+ uint32_t part; //!< Hardware part, from FICR register.
+ uint32_t variant; //!< Hardware variant, from FICR register.
+ struct
+ {
+ uint32_t rom_size; //!< ROM size, in bytes.
+ uint32_t ram_size; //!< RAM size, in bytes.
+ uint32_t rom_page_size; //!< ROM flash page size, in bytes.
+ } memory;
+} nrf_dfu_response_hardware_t;
+
+/**
+ * @brief @ref NRF_DFU_OP_FIRMWARE_VERSION response details.
+ */
+typedef struct
+{
+ nrf_dfu_firmware_type_t type; //!< Firmware type.
+ uint32_t version; //!< Firmware version.
+ uint32_t addr; //!< Firmware address in flash.
+ uint32_t len; //!< Firmware length in bytes.
+} nrf_dfu_response_firmware_t;
+
+/**
+ * @brief @ref NRF_DFU_OP_OBJECT_SELECT response details.
+ */
+typedef struct
+{
+ uint32_t offset; //!< Current offset.
+ uint32_t crc; //!< Current CRC.
+ uint32_t max_size; //!< Maximum size of selected object.
+} nrf_dfu_response_select_t;
+
+/**
+ * @brief @ref NRF_DFU_OP_OBJECT_CREATE response details.
+ */
+typedef struct
+{
+ uint32_t offset; //!< Current offset
+ uint32_t crc; //!< Current CRC.
+} nrf_dfu_response_create_t;
+
+/**
+ * @brief @ref NRF_DFU_OP_OBJECT_WRITE response details.
+ */
+typedef struct
+{
+ uint32_t offset; //!< Used only when packet receipt notification is used.
+ uint32_t crc; //!< Used only when packet receipt notification is used.
+} nrf_dfu_response_write_t;
+
+/**
+ * @brief @ref NRF_DFU_OP_CRC_GET response details.
+ */
+typedef struct
+{
+ uint32_t offset; //!< Current offset.
+ uint32_t crc; //!< Current CRC.
+} nrf_dfu_response_crc_t;
+
+/**
+ * @brief @ref NRF_DFU_OP_PING response details.
+ */
+typedef struct
+{
+ uint8_t id; //!< The received ID which is echoed back.
+} nrf_dfu_response_ping_t;
+
+/**
+ * @brief @ref NRF_DFU_OP_MTU_GET response details.
+ */
+typedef struct
+{
+ uint16_t size; //!< The MTU size as specified by the local transport.
+} nrf_dfu_response_mtu_t;
+
+/**
+ * @brief DFU response message.
+ */
+typedef struct
+{
+ nrf_dfu_op_t request; //!< Requested operation.
+ nrf_dfu_result_t result; //!< Result of the operation.
+ union
+ {
+ nrf_dfu_response_protocol_t protocol; //!< Protocol version response.
+ nrf_dfu_response_hardware_t hardware; //!< Hardware version response.
+ nrf_dfu_response_firmware_t firmware; //!< Firmware version response.
+ nrf_dfu_response_select_t select; //!< Select object response..
+ nrf_dfu_response_create_t create; //!< Create object response..
+ nrf_dfu_response_write_t write; //!< Write object response.
+ nrf_dfu_response_crc_t crc; //!< CRC response.
+ nrf_dfu_response_ping_t ping; //!< Ping response.
+ nrf_dfu_response_mtu_t mtu; //!< MTU response.
+ };
+} nrf_dfu_response_t;
+
+/**
+ * @brief @ref NRF_DFU_OP_FIRMWARE_VERSION request details.
+ */
+typedef struct
+{
+ uint8_t image_number; //!< Index of the firmware.
+} nrf_dfu_request_firmware_t;
+
+/**
+ * @brief @ref NRF_DFU_OP_OBJECT_SELECT request details.
+ */
+typedef struct
+{
+ uint32_t object_type; //!< Object type. See @ref nrf_dfu_obj_type_t.
+} nrf_dfu_request_select_t;
+
+/**
+ * @brief @ref NRF_DFU_OP_OBJECT_CREATE request details.
+ */
+typedef struct
+{
+ uint32_t object_type; //!< Object type. See @ref nrf_dfu_obj_type_t.
+ uint32_t object_size; //!< Object size in bytes.
+} nrf_dfu_request_create_t;
+
+/**
+ * @brief @ref NRF_DFU_OP_OBJECT_WRITE request details.
+ */
+typedef struct
+{
+ uint8_t const * p_data; //!< Data.
+ uint16_t len; //!< Length of data in @ref nrf_dfu_request_write_t::p_data.
+} nrf_dfu_request_write_t;
+
+/**
+ * @brief @ref NRF_DFU_OP_PING request details.
+ */
+typedef struct
+{
+ uint8_t id; //!< Ping ID that will be returned in response.
+} nrf_dfu_request_ping_t;
+
+/**
+ * @brief @ref NRF_DFU_OP_MTU_GET request details.
+ */
+typedef struct
+{
+ uint16_t size; //!< Transport MTU size in bytes.
+} nrf_dfu_request_mtu_t;
+
+/**
+ * @brief @ref NRF_DFU_OP_RECEIPT_NOTIF_SET request details.
+ */
+typedef struct
+{
+ uint32_t target; //!< Target PRN.
+} nrf_dfu_request_prn_t;
+
+
+typedef void (*nrf_dfu_response_callback_t)(nrf_dfu_response_t * p_res, void * p_context);
+
+/**
+ *@brief DFU request.
+ */
+typedef struct
+{
+ nrf_dfu_op_t request; //!< Requested operation.
+ void * p_context;
+ struct
+ {
+ nrf_dfu_response_callback_t response; //!< Callback to call to send the response.
+ nrf_dfu_flash_callback_t write;
+ } callback;
+ union
+ {
+ nrf_dfu_request_firmware_t firmware; //!< Firmware version request.
+ nrf_dfu_request_select_t select; //!< Select object request.
+ nrf_dfu_request_create_t create; //!< Create object request.
+ nrf_dfu_request_write_t write; //!< Write object request.
+ nrf_dfu_request_ping_t ping; //!< Ping.
+ nrf_dfu_request_mtu_t mtu; //!< MTU size request.
+ nrf_dfu_request_prn_t prn; //!< Set receipt notification request.
+ };
+} nrf_dfu_request_t;
+
+
+/**@brief Function for initializing the request handling module.
+ *
+ * @param observer Function for receiving notifications.
+ *
+ * @retval NRF_SUCCESS If the operation was successful.
+ * @retval NRF_ERROR_INTERNAL If the init packet in flash is not valid.
+ * @retval NRF_ERROR_INVALID_PARAM If observer is not provided.
+ */
+ret_code_t nrf_dfu_req_handler_init(nrf_dfu_observer_t observer);
+
+
+/**@brief Function for scheduling processing of a DFU request.
+ *
+ * Requests are processed asynchronously by the scheduler.
+ *
+ * @param[in] p_req Request to be handled. The response callback must be non-null.
+ *
+ * @retval NRF_SUCCESS If the command request was executed successfully.
+ * @retval NRF_ERROR_NO_MEM If the scheduler ran out of memory.
+ * @retval NRF_ERROR_INVALID_PARAM If the response callback is NULL.
+ */
+ret_code_t nrf_dfu_req_handler_on_req(nrf_dfu_request_t * p_req);
+
+
+ANON_UNIONS_DISABLE;
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // NRF_DFU_REQ_HANDLER_H__
+
+/** @} */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/dfu/nrf_dfu_settings.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/dfu/nrf_dfu_settings.c
new file mode 100644
index 0000000..13e89b4
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/dfu/nrf_dfu_settings.c
@@ -0,0 +1,241 @@
+/**
+ * Copyright (c) 2016 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+
+#include "nrf_dfu_settings.h"
+#include <stddef.h>
+#include <string.h>
+#include "app_error.h"
+#include "nrf_dfu_flash.h"
+#include "nrf_soc.h"
+#include "crc32.h"
+#include "nrf_nvmc.h"
+
+#define DFU_SETTINGS_INIT_COMMAND_OFFSET offsetof(nrf_dfu_settings_t, init_command) //<! Offset in the settings struct where the InitCommand is located.
+
+#define NRF_LOG_MODULE_NAME nrf_dfu_settings
+#include "nrf_log.h"
+NRF_LOG_MODULE_REGISTER();
+
+
+/**@brief This variable reserves a page in flash for bootloader settings
+ * to ensure the linker doesn't place any code or variables at this location.
+ */
+#if defined (__CC_ARM )
+
+ uint8_t m_dfu_settings_buffer[BOOTLOADER_SETTINGS_PAGE_SIZE]
+ __attribute__((at(BOOTLOADER_SETTINGS_ADDRESS)))
+ __attribute__((used));
+
+#elif defined ( __GNUC__ ) || defined ( __SES_ARM )
+
+ uint8_t m_dfu_settings_buffer[BOOTLOADER_SETTINGS_PAGE_SIZE]
+ __attribute__((section(".bootloader_settings_page")))
+ __attribute__((used));
+
+#elif defined ( __ICCARM__ )
+
+ __no_init __root uint8_t m_dfu_settings_buffer[BOOTLOADER_SETTINGS_PAGE_SIZE]
+ @ BOOTLOADER_SETTINGS_ADDRESS;
+
+#else
+
+ #error Not a valid compiler/linker for m_dfu_settings placement.
+
+#endif // Compiler specific
+
+#ifndef BL_SETTINGS_ACCESS_ONLY
+#if defined(NRF52_SERIES)
+
+/**@brief This variable reserves a page in flash for MBR parameters
+ * to ensure the linker doesn't place any code or variables at this location.
+ */
+#if defined ( __CC_ARM )
+
+ uint8_t m_mbr_params_page[NRF_MBR_PARAMS_PAGE_SIZE]
+ __attribute__((at(NRF_MBR_PARAMS_PAGE_ADDRESS)))
+ __attribute__((used));
+
+#elif defined ( __GNUC__ ) || defined ( __SES_ARM )
+
+ uint8_t m_mbr_params_page[NRF_MBR_PARAMS_PAGE_SIZE]
+ __attribute__ ((section(".mbr_params_page")));
+
+#elif defined ( __ICCARM__ )
+
+ __no_init uint8_t m_mbr_params_page[NRF_MBR_PARAMS_PAGE_SIZE]
+ @ NRF_MBR_PARAMS_PAGE_ADDRESS;
+
+#else
+
+ #error Not a valid compiler/linker for m_mbr_params_page placement.
+
+#endif // Compiler specific
+
+
+/**@brief This variable has the linker write the MBR parameters page address to the
+ * UICR register. This value will be written in the HEX file and thus to the
+ * UICR when the bootloader is flashed into the chip.
+ */
+#if defined ( __CC_ARM )
+
+ uint32_t const m_uicr_mbr_params_page_address
+ __attribute__((at(NRF_UICR_MBR_PARAMS_PAGE_ADDRESS))) = NRF_MBR_PARAMS_PAGE_ADDRESS;
+
+#elif defined ( __GNUC__ ) || defined ( __SES_ARM )
+
+ uint32_t const m_uicr_mbr_params_page_address
+ __attribute__ ((section(".uicr_mbr_params_page")))
+ __attribute__ ((used)) = NRF_MBR_PARAMS_PAGE_ADDRESS;
+
+#elif defined ( __ICCARM__ )
+
+ __root uint32_t const m_uicr_mbr_params_page_address
+ @ NRF_UICR_MBR_PARAMS_PAGE_ADDRESS = NRF_MBR_PARAMS_PAGE_ADDRESS;
+
+#else
+
+ #error Not a valid compiler/linker for m_mbr_params_page placement.
+
+#endif // Compiler specific
+#endif // #if defined( NRF52_SERIES )
+#endif // #ifndef BL_SETTINGS_ACCESS_ONLY
+
+
+nrf_dfu_settings_t s_dfu_settings;
+
+
+static uint32_t nrf_dfu_settings_crc_get(void)
+{
+ // The crc is calculated from the s_dfu_settings struct, except the crc itself and the init command
+ return crc32_compute((uint8_t*)&s_dfu_settings + 4, DFU_SETTINGS_INIT_COMMAND_OFFSET - 4, NULL);
+}
+
+
+ret_code_t nrf_dfu_settings_init(bool sd_irq_initialized)
+{
+ NRF_LOG_DEBUG("Calling nrf_dfu_settings_init()...");
+
+ ret_code_t rc = nrf_dfu_flash_init(sd_irq_initialized);
+ if (rc != NRF_SUCCESS)
+ {
+ NRF_LOG_ERROR("nrf_dfu_flash_init() failed with error: %x", rc);
+ return NRF_ERROR_INTERNAL;
+ }
+
+ // Copy the DFU settings out of flash and into a buffer in RAM.
+ memcpy((void*)&s_dfu_settings, m_dfu_settings_buffer, sizeof(nrf_dfu_settings_t));
+
+ if (s_dfu_settings.crc != 0xFFFFFFFF)
+ {
+ // CRC is set. Content must be valid
+ uint32_t crc = nrf_dfu_settings_crc_get();
+ if (crc == s_dfu_settings.crc)
+ {
+ return NRF_SUCCESS;
+ }
+ }
+
+ // Reached if the page is erased or CRC is wrong.
+ NRF_LOG_DEBUG("Resetting bootloader settings.");
+
+ memset(&s_dfu_settings, 0x00, sizeof(nrf_dfu_settings_t));
+ s_dfu_settings.settings_version = NRF_DFU_SETTINGS_VERSION;
+
+ rc = nrf_dfu_settings_write(NULL);
+ if (rc != NRF_SUCCESS)
+ {
+ NRF_LOG_ERROR("nrf_dfu_flash_write() failed with error: %x", rc);
+ return NRF_ERROR_INTERNAL;
+ }
+ return NRF_SUCCESS;
+}
+
+
+ret_code_t nrf_dfu_settings_write(nrf_dfu_flash_callback_t callback)
+{
+ ret_code_t err_code;
+
+ if (memcmp(&s_dfu_settings, m_dfu_settings_buffer, sizeof(nrf_dfu_settings_t)) == 0)
+ {
+ NRF_LOG_DEBUG("New settings are identical to old, write not needed. Skipping.");
+ if (callback != NULL)
+ {
+ callback(NULL);
+ }
+ return NRF_SUCCESS;
+ }
+
+ NRF_LOG_DEBUG("Writing settings...");
+ NRF_LOG_DEBUG("Erasing old settings at: 0x%08x", (uint32_t)m_dfu_settings_buffer);
+
+ // Not setting the callback function because ERASE is required before STORE
+ // Only report completion on successful STORE.
+ err_code = nrf_dfu_flash_erase((uint32_t)m_dfu_settings_buffer, 1, NULL);
+
+ if (err_code != NRF_SUCCESS)
+ {
+ NRF_LOG_ERROR("Could not erase the settings page!");
+ return NRF_ERROR_INTERNAL;
+ }
+
+ s_dfu_settings.crc = nrf_dfu_settings_crc_get();
+
+ static nrf_dfu_settings_t temp_dfu_settings;
+ memcpy(&temp_dfu_settings, &s_dfu_settings, sizeof(nrf_dfu_settings_t));
+
+ err_code = nrf_dfu_flash_store((uint32_t)m_dfu_settings_buffer,
+ &temp_dfu_settings,
+ sizeof(nrf_dfu_settings_t),
+ callback);
+
+ if (err_code != NRF_SUCCESS)
+ {
+ NRF_LOG_ERROR("Could not write the DFU settings page!");
+ return NRF_ERROR_INTERNAL;
+ }
+
+ return NRF_SUCCESS;
+}
+
+__WEAK ret_code_t nrf_dfu_settings_additional_erase(void)
+{
+ NRF_LOG_WARNING("No additional data erased");
+ return NRF_SUCCESS;
+}
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/dfu/nrf_dfu_settings.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/dfu/nrf_dfu_settings.h
new file mode 100644
index 0000000..9e9dedb
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/dfu/nrf_dfu_settings.h
@@ -0,0 +1,173 @@
+/**
+ * Copyright (c) 2016 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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
+ *
+ * @defgroup nrf_dfu_settings DFU settings
+ * @{
+ * @ingroup nrf_dfu
+ */
+
+#ifndef NRF_DFU_SETTINGS_H__
+#define NRF_DFU_SETTINGS_H__
+
+#include <stdint.h>
+#include "nrf_dfu_types.h"
+#include "nrf_dfu_flash.h"
+#include "sdk_config.h"
+#include "sdk_errors.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+/**@brief Global settings.
+ *
+ * @note Using this variable is not thread-safe.
+ *
+ */
+extern nrf_dfu_settings_t s_dfu_settings;
+
+
+/**@brief Function for writing DFU settings to flash.
+ *
+ * @param[in] callback Pointer to a function that is called after completing the write operation.
+ *
+ * @retval NRF_SUCCESS If the write process was successfully initiated.
+ * @retval NRF_ERROR_INTERNAL If a flash error occurred.
+ */
+ret_code_t nrf_dfu_settings_write(nrf_dfu_flash_callback_t callback);
+
+
+/**@brief Function for initializing the DFU settings module.
+ *
+ * @retval NRF_SUCCESS If the initialization was successful.
+ * @retval NRF_ERROR_INTERNAL If a flash error occurred.
+ */
+ret_code_t nrf_dfu_settings_init(bool sd_irq_initialized);
+
+
+#if defined(NRF_DFU_TRANSPORT_BLE) && NRF_DFU_TRANSPORT_BLE
+/** @brief Function for storing peer data received through an SVCI call in DFU settings.
+ *
+ * @note The content of the type can be verified by a CRC value stored inside the struct
+ * If the CRC value is 0xFFFFFFFF, it means that no data is set.
+ *
+ * @note The storage operation is an asynchronous progress. Success will be notified
+ * through system events raised by the SoftDevice.
+ *
+ * @param[in] p_data Peer data to be stored in flash.
+ *
+ * @retval NRF_SUCCESS Asynchronous operation was successfully started.
+ * @retval NRF_ERROR_NULL p_data was NULL.
+ * @retval Any other error code reported by SoftDevice API calls.
+ */
+ret_code_t nrf_dfu_settings_peer_data_write(nrf_dfu_peer_data_t * p_data);
+
+
+/** @brief Function for copying peer data from DFU settings to RAM.
+ *
+ * @param[in,out] p_data Structure to copy peer data to.
+ *
+ * @retval NRF_SUCCESS Peer data was successfully copied.
+ * @retval NRF_ERROR_NULL p_data was NULL.
+ */
+ret_code_t nrf_dfu_settings_peer_data_copy(nrf_dfu_peer_data_t * p_data);
+
+
+/** @brief Function for validating peer data in DFU settings.
+ *
+ * @retval True if peer data is validated by CRC, false if not.
+ */
+bool nrf_dfu_settings_peer_data_is_valid(void);
+
+
+/** @brief Function for storing an advertisement name received through an SVCI call in DFU settings.
+ *
+ * @note The content of the type is verifyable by a CRC-value stored inside the struct.
+ *
+ * @note The storage operation is an asynchronous progress. Success will be notified
+ * through system events raised by the SoftDevice.
+ *
+ * @param[in] p_adv_name Structure holding information about the new advertisement name.
+ *
+ * @retval NRF_SUCCESS Asynchronous operation was successfully started.
+ * @retval NRF_ERROR_NULL p_adv_name was NULL.
+ * @retval Any other error code reported by SoftDevice API calls.
+ */
+ret_code_t nrf_dfu_settings_adv_name_write(nrf_dfu_adv_name_t * p_adv_name);
+
+
+/** @brief Function for copying the advertisement name from DFU settings to RAM.
+ *
+ * @param[in,out] p_adv_name Structure to copy the new advertisement name to.
+ *
+ * @retval NRF_SUCCESS Advertisement name was successfully copied.
+ * @retval NRF_ERROR_NULL p_adv_name was NULL.
+ */
+ret_code_t nrf_dfu_settings_adv_name_copy(nrf_dfu_adv_name_t * p_adv_name);
+
+
+/** @brief Function for validating advertisement data in DFU settings.
+ *
+ * @retval True if advertisement name is validated by CRC, false if not.
+ */
+bool nrf_dfu_settings_adv_name_is_valid(void);
+
+#endif // NRF_DFU_TRANSPORT_BLE
+
+/** @brief Function for erasing additional data in DFU settings.
+ *
+ * @note Erasing additional data in DFU settings is only possible
+ * if nrf_dfu_flash is initialized to not use SoftDevice calls.
+ *
+ * @retval NRF_SUCCESS Additional data was successfully erased.
+ * @retval Any other error code reported by nrf_dfu_flash
+ */
+ret_code_t nrf_dfu_settings_additional_erase(void);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // NRF_DFU_SETTINGS_H__
+
+/**@} */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/dfu/nrf_dfu_settings_svci.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/dfu/nrf_dfu_settings_svci.c
new file mode 100644
index 0000000..41deb9e
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/dfu/nrf_dfu_settings_svci.c
@@ -0,0 +1,185 @@
+/**
+ * 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+
+#include <stddef.h>
+#include <string.h>
+#include "app_error.h"
+#include "sdk_macros.h"
+#include "nrf_dfu_settings.h"
+#include "nrf_nvmc.h"
+#include "crc32.h"
+
+#define NRF_LOG_MODULE_NAME nrf_dfu_settings_svci
+#include "nrf_log.h"
+NRF_LOG_MODULE_REGISTER();
+
+#define DFU_SETTINGS_PEER_DATA_OFFSET offsetof(nrf_dfu_settings_t, peer_data) //<! Offset in the settings struct where the additional peer data is located.
+#define DFU_SETTINGS_ADV_NAME_OFFSET offsetof(nrf_dfu_settings_t, adv_name) //<! Offset in the settings struct where the additional advertisement name is located.
+
+extern nrf_dfu_settings_t s_dfu_settings;
+extern uint8_t m_dfu_settings_buffer[CODE_PAGE_SIZE];
+
+#if defined(NRF_DFU_BLE_REQUIRES_BONDS) && (NRF_DFU_BLE_REQUIRES_BONDS == 1)
+
+ret_code_t nrf_dfu_settings_peer_data_write(nrf_dfu_peer_data_t * p_data)
+{
+ uint32_t ret_val;
+
+ uint32_t * p_peer_data_settings =
+ (uint32_t*) &m_dfu_settings_buffer[DFU_SETTINGS_PEER_DATA_OFFSET];
+
+ uint32_t crc = (uint32_t)*p_peer_data_settings;
+
+ VERIFY_PARAM_NOT_NULL(p_data);
+
+ if (crc != 0xFFFFFFFF)
+ {
+ // Already written to, must be cleared out
+ // Reset required.
+ return NRF_ERROR_INVALID_STATE;
+ }
+
+ // Calculate the CRC for the structure excluding the CRC value itself.
+ p_data->crc = crc32_compute((uint8_t*)p_data + 4, sizeof(nrf_dfu_peer_data_t) - 4, NULL);
+
+ // Using SoftDevice call since this function cannot use static memory.
+ ret_val = sd_flash_write(p_peer_data_settings,
+ (uint32_t*)p_data,
+ sizeof(nrf_dfu_peer_data_t)/4);
+
+ return ret_val;
+}
+
+
+ret_code_t nrf_dfu_settings_peer_data_copy(nrf_dfu_peer_data_t * p_data)
+{
+ VERIFY_PARAM_NOT_NULL(p_data);
+
+ memcpy(p_data, &m_dfu_settings_buffer[DFU_SETTINGS_PEER_DATA_OFFSET], sizeof(nrf_dfu_peer_data_t));
+
+ return NRF_SUCCESS;
+}
+
+
+bool nrf_dfu_settings_peer_data_is_valid(void)
+{
+ nrf_dfu_peer_data_t * p_peer_data =
+ (nrf_dfu_peer_data_t*) &m_dfu_settings_buffer[DFU_SETTINGS_PEER_DATA_OFFSET];
+
+ // Calculate the CRC for the structure excluding the CRC value itself.
+ uint32_t crc = crc32_compute((uint8_t*)p_peer_data + 4, sizeof(nrf_dfu_peer_data_t) - 4, NULL);
+
+ return (p_peer_data->crc == crc);
+}
+
+#else // not NRF_DFU_BLE_REQUIRES_BONDS
+
+ret_code_t nrf_dfu_settings_adv_name_write(nrf_dfu_adv_name_t * p_adv_name)
+{
+ uint32_t ret_val;
+
+ uint32_t * p_adv_name_settings =
+ (uint32_t*) &m_dfu_settings_buffer[DFU_SETTINGS_ADV_NAME_OFFSET];
+
+ uint32_t crc = (uint32_t)*p_adv_name_settings;
+
+ VERIFY_PARAM_NOT_NULL(p_adv_name);
+
+ if (crc != 0xFFFFFFFF)
+ {
+ // Already written to, must be cleared out.
+ // Reset required
+ return NRF_ERROR_INVALID_STATE;
+ }
+
+ // Calculate the CRC for the structure excluding the CRC value itself.
+ p_adv_name->crc = crc32_compute((uint8_t *)p_adv_name + 4, sizeof(nrf_dfu_adv_name_t) - 4, NULL);
+
+ // Using SoftDevice call since this function cannot use static memory.
+ ret_val = sd_flash_write(p_adv_name_settings,
+ (uint32_t*) p_adv_name,
+ sizeof(nrf_dfu_adv_name_t)/4);
+ return ret_val;
+}
+
+
+ret_code_t nrf_dfu_settings_adv_name_copy(nrf_dfu_adv_name_t * p_adv_name)
+{
+ VERIFY_PARAM_NOT_NULL(p_adv_name);
+ memcpy(p_adv_name, &m_dfu_settings_buffer[DFU_SETTINGS_ADV_NAME_OFFSET], sizeof(nrf_dfu_adv_name_t));
+
+ return NRF_SUCCESS;
+}
+
+
+bool nrf_dfu_settings_adv_name_is_valid(void)
+{
+ nrf_dfu_adv_name_t * p_adv_name =
+ (nrf_dfu_adv_name_t*)&m_dfu_settings_buffer[DFU_SETTINGS_ADV_NAME_OFFSET];
+
+ // Calculate the CRC for the structure excluding the CRC value itself.
+ uint32_t crc = crc32_compute((uint8_t*)p_adv_name + 4, sizeof(nrf_dfu_adv_name_t) - 4, NULL);
+
+ return (p_adv_name->crc == crc);
+}
+
+#endif
+
+
+//lint -save -e(14)
+ret_code_t nrf_dfu_settings_additional_erase(void)
+{
+ ret_code_t ret_code = NRF_SUCCESS;
+
+ // Check CRC for both types.
+ if ( (s_dfu_settings.peer_data.crc != 0xFFFFFFFF)
+ || (s_dfu_settings.adv_name.crc != 0xFFFFFFFF))
+ {
+ NRF_LOG_DEBUG("Erasing settings page additional data.");
+
+ // Erasing and resetting the settings page without the peer data/adv data
+ nrf_nvmc_page_erase(BOOTLOADER_SETTINGS_ADDRESS);
+ nrf_nvmc_write_words(BOOTLOADER_SETTINGS_ADDRESS, (uint32_t const *)&s_dfu_settings, DFU_SETTINGS_PEER_DATA_OFFSET / 4);
+ }
+
+ return ret_code;
+}
+//lint -restore
+
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/dfu/nrf_dfu_svci.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/dfu/nrf_dfu_svci.c
new file mode 100644
index 0000000..ceff394
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/dfu/nrf_dfu_svci.c
@@ -0,0 +1,86 @@
+/**
+ * Copyright (c) 2016 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+
+#include <stdint.h>
+#include <stdbool.h>
+#include "nrf_log.h"
+#include "nrf_sdm.h"
+#include "app_util.h"
+
+#define APP_START_ADDR CODE_START
+
+
+uint32_t nrf_dfu_svci_vector_table_set(void)
+{
+ uint32_t err_code;
+
+ if (NRF_UICR->NRFFW[0] != 0xFFFFFFFF)
+ {
+ NRF_LOG_INFO("Setting vector table to bootloader: 0x%08x", NRF_UICR->NRFFW[0]);
+ err_code = sd_softdevice_vector_table_base_set(NRF_UICR->NRFFW[0]);
+ if (err_code != NRF_SUCCESS)
+ {
+ NRF_LOG_ERROR("Failed running sd_softdevice_vector_table_base_set");
+ return err_code;
+ }
+
+ return NRF_SUCCESS;
+ }
+
+ NRF_LOG_ERROR("No bootloader was found");
+ return NRF_ERROR_NO_MEM;
+}
+
+
+uint32_t nrf_dfu_svci_vector_table_unset(void)
+{
+ uint32_t err_code;
+
+ NRF_LOG_INFO("Setting vector table to main app: 0x%08x", APP_START_ADDR);
+ err_code = sd_softdevice_vector_table_base_set(APP_START_ADDR);
+ if (err_code != NRF_SUCCESS)
+ {
+ NRF_LOG_ERROR("Failed running sd_softdevice_vector_table_base_set");
+ return err_code;
+ }
+
+ return NRF_SUCCESS;
+}
+
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/dfu/nrf_dfu_svci_handler.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/dfu/nrf_dfu_svci_handler.c
new file mode 100644
index 0000000..ce75be7
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/dfu/nrf_dfu_svci_handler.c
@@ -0,0 +1,222 @@
+/**
+ * Copyright (c) 2016 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+
+#include <string.h>
+#include "nrf_svci_async_handler.h"
+#include "app_error.h"
+#include "nrf_nvmc.h"
+#include "nrf_dfu_types.h"
+#include "nrf_dfu_ble_svci_bond_sharing.h"
+#include "nrf_log.h"
+#include "nrf_dfu_settings.h"
+#include "sdk_config.h"
+
+
+#if (NRF_DFU_TRANSPORT_BLE && NRF_DFU_BLE_REQUIRES_BONDS)
+
+
+NRF_SVCI_ASYNC_HANDLER_CREATE(NRF_DFU_SVCI_SET_PEER_DATA,
+ nrf_dfu_set_peer_data, nrf_dfu_peer_data_t, nrf_dfu_peer_data_state_t);
+
+
+static uint32_t nrf_dfu_set_peer_data_handler(nrf_dfu_set_peer_data_svci_async_t * p_async)
+{
+ VERIFY_PARAM_NOT_NULL(p_async);
+
+ p_async->async_func = nrf_dfu_set_peer_data_on_call;
+ p_async->sys_evt_handler = nrf_dfu_set_peer_data_on_sys_evt;
+ p_async->state = DFU_PEER_DATA_STATE_INITIALIZED;
+
+ return NRF_SUCCESS;
+}
+
+
+static uint32_t nrf_dfu_set_peer_data_on_call(nrf_dfu_peer_data_t * p_data,
+ nrf_dfu_peer_data_state_t * p_state)
+{
+ uint32_t ret_val = NRF_ERROR_BUSY;
+
+ VERIFY_PARAM_NOT_NULL(p_state);
+
+ if (NRF_BL_SETTINGS_PAGE_PROTECT)
+ {
+ return NRF_ERROR_FORBIDDEN;
+ }
+
+ switch (*p_state)
+ {
+ case DFU_PEER_DATA_STATE_INVALID:
+ return NRF_ERROR_INVALID_STATE;
+
+ case DFU_PEER_DATA_STATE_INITIALIZED:
+ ret_val = nrf_dfu_settings_peer_data_write(p_data);
+ if (ret_val == NRF_SUCCESS)
+ {
+ *p_state = DFU_PEER_DATA_STATE_WRITE_REQUESTED;
+ }
+ break;
+
+ case DFU_PEER_DATA_STATE_WRITE_REQUESTED:
+ return NRF_ERROR_BUSY;
+
+ case DFU_PEER_DATA_STATE_WRITE_FINISHED:
+ return NRF_ERROR_INVALID_STATE;
+
+ case DFU_PEER_DATA_STATE_WRITE_FAILED:
+ return NRF_ERROR_INVALID_STATE;
+ }
+
+ return ret_val;
+}
+
+
+static uint32_t nrf_dfu_set_peer_data_on_sys_evt(uint32_t sys_event, nrf_dfu_peer_data_state_t * p_state)
+{
+ uint32_t ret_val = NRF_ERROR_INVALID_STATE;
+
+ VERIFY_PARAM_NOT_NULL(p_state);
+
+ if (*p_state == DFU_PEER_DATA_STATE_WRITE_REQUESTED)
+ {
+ switch (sys_event)
+ {
+ case NRF_EVT_FLASH_OPERATION_ERROR:
+ return NRF_ERROR_BUSY;
+
+ case NRF_EVT_FLASH_OPERATION_SUCCESS:
+ ret_val = NRF_SUCCESS;
+ (*p_state) = DFU_PEER_DATA_STATE_WRITE_FINISHED;
+ break;
+
+ default:
+ // Event not intended for us
+ break;
+ }
+ }
+
+ return ret_val;
+}
+
+#elif (NRF_DFU_TRANSPORT_BLE && !NRF_DFU_BLE_REQUIRES_BONDS)
+
+
+NRF_SVCI_ASYNC_HANDLER_CREATE(NRF_DFU_SVCI_SET_ADV_NAME,
+ nrf_dfu_set_adv_name, nrf_dfu_adv_name_t, nrf_dfu_set_adv_name_state_t);
+
+
+static uint32_t nrf_dfu_set_adv_name_handler(nrf_dfu_set_adv_name_svci_async_t * p_async)
+{
+ VERIFY_PARAM_NOT_NULL(p_async);
+
+ p_async->async_func = nrf_dfu_set_adv_name_on_call;
+ p_async->sys_evt_handler = nrf_dfu_set_adv_name_on_sys_evt;
+ p_async->state = DFU_ADV_NAME_STATE_INITIALIZED;
+
+ return NRF_SUCCESS;
+}
+
+
+static uint32_t nrf_dfu_set_adv_name_on_call(nrf_dfu_adv_name_t * p_adv_name,
+ nrf_dfu_set_adv_name_state_t * p_state)
+{
+ uint32_t ret_val = NRF_ERROR_BUSY;
+
+ VERIFY_PARAM_NOT_NULL(p_state);
+
+ if (NRF_BL_SETTINGS_PAGE_PROTECT)
+ {
+ return NRF_ERROR_FORBIDDEN;
+ }
+
+ switch (*p_state)
+ {
+ case DFU_ADV_NAME_STATE_INVALID:
+ return NRF_ERROR_INVALID_STATE;
+
+ case DFU_ADV_NAME_STATE_INITIALIZED:
+ ret_val = nrf_dfu_settings_adv_name_write(p_adv_name);
+ if (ret_val == NRF_SUCCESS)
+ {
+ *p_state = DFU_ADV_NAME_STATE_WRITE_REQUESTED;
+ }
+ break;
+
+ case DFU_ADV_NAME_STATE_WRITE_REQUESTED:
+ return NRF_ERROR_BUSY;
+
+ case DFU_ADV_NAME_STATE_WRITE_FINISHED:
+ return NRF_ERROR_INVALID_STATE;
+
+ case DFU_ADV_NAME_STATE_WRITE_FAILED:
+ return NRF_ERROR_INVALID_STATE;
+ }
+
+ return ret_val;
+}
+
+
+static uint32_t nrf_dfu_set_adv_name_on_sys_evt(uint32_t sys_event, nrf_dfu_set_adv_name_state_t * p_state)
+{
+ uint32_t ret_val = NRF_ERROR_INVALID_STATE;
+
+ VERIFY_PARAM_NOT_NULL(p_state);
+
+ if (*p_state == DFU_ADV_NAME_STATE_WRITE_REQUESTED)
+ {
+ switch (sys_event)
+ {
+ case NRF_EVT_FLASH_OPERATION_ERROR:
+ return NRF_ERROR_BUSY;
+
+ case NRF_EVT_FLASH_OPERATION_SUCCESS:
+ ret_val = NRF_SUCCESS;
+ (*p_state) = DFU_ADV_NAME_STATE_WRITE_FINISHED;
+ break;
+
+ default:
+ // Event not intended for us
+ break;
+ }
+ }
+
+ return ret_val;
+}
+
+#endif // NRF_DFU_TRANSPORT_BLE && !NRF_DFU_BLE_REQUIRES_BONDS
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/dfu/nrf_dfu_transport.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/dfu/nrf_dfu_transport.c
new file mode 100644
index 0000000..6075538
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/dfu/nrf_dfu_transport.c
@@ -0,0 +1,91 @@
+/**
+ * Copyright (c) 2016 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#include "nrf_dfu_transport.h"
+#include "nrf_log.h"
+
+
+#define DFU_TRANS_SECTION_ITEM_GET(i) NRF_SECTION_ITEM_GET(dfu_trans, nrf_dfu_transport_t, (i))
+#define DFU_TRANS_SECTION_ITEM_COUNT NRF_SECTION_ITEM_COUNT(dfu_trans, nrf_dfu_transport_t)
+
+NRF_SECTION_DEF(dfu_trans, const nrf_dfu_transport_t);
+
+
+uint32_t nrf_dfu_transports_init(nrf_dfu_observer_t observer)
+{
+ uint32_t const num_transports = DFU_TRANS_SECTION_ITEM_COUNT;
+ uint32_t ret_val = NRF_SUCCESS;
+
+ NRF_LOG_DEBUG("Initializing transports (found: %d)", num_transports);
+
+ for (uint32_t i = 0; i < num_transports; i++)
+ {
+ nrf_dfu_transport_t * const trans = DFU_TRANS_SECTION_ITEM_GET(i);
+ ret_val = trans->init_func(observer);
+ if (ret_val != NRF_SUCCESS)
+ {
+ NRF_LOG_DEBUG("Failed to initialize transport %d, error %d", i, ret_val);
+ break;
+ }
+ }
+
+ return ret_val;
+}
+
+
+uint32_t nrf_dfu_transports_close(nrf_dfu_transport_t const * p_exception)
+{
+ uint32_t const num_transports = DFU_TRANS_SECTION_ITEM_COUNT;
+ uint32_t ret_val = NRF_SUCCESS;
+
+ NRF_LOG_DEBUG("Shutting down transports (found: %d)", num_transports);
+
+ for (uint32_t i = 0; i < num_transports; i++)
+ {
+ nrf_dfu_transport_t * const trans = DFU_TRANS_SECTION_ITEM_GET(i);
+ ret_val = trans->close_func(p_exception);
+ if (ret_val != NRF_SUCCESS)
+ {
+ NRF_LOG_DEBUG("Failed to shutdown transport %d, error %d", i, ret_val);
+ break;
+ }
+ }
+
+ return ret_val;
+}
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/dfu/nrf_dfu_transport.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/dfu/nrf_dfu_transport.h
new file mode 100644
index 0000000..b8368f0
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/dfu/nrf_dfu_transport.h
@@ -0,0 +1,134 @@
+/**
+ * Copyright (c) 2016 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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
+ *
+ * @defgroup sdk_nrf_dfu_transport DFU transport
+ * @{
+ * @ingroup nrf_dfu
+ * @brief Generic Device Firmware Update (DFU) transport interface.
+ *
+ * @details The DFU transport module defines a generic interface that must
+ * be implemented for each transport layer.
+ */
+
+#ifndef NRF_DFU_TRANSPORT_H__
+#define NRF_DFU_TRANSPORT_H__
+
+#include <stdint.h>
+#include "nrf_section.h"
+#include "nrf_dfu_types.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** @brief Forward declaration of nrf_dfu_transport_t */
+typedef struct nrf_dfu_transport_s nrf_dfu_transport_t;
+
+/** @brief Function type for initializing a DFU transport.
+ *
+ * @details This function initializes a DFU transport. The implementation
+ * of the function must initialize DFU mode and stay in service
+ * until either the device is reset or the DFU operation is finalized.
+ * When the DFU transport receives requests, it should call @ref nrf_dfu_req_handler_on_req for handling the requests.
+ *
+ * @param observer Function for receiving DFU transport notifications.
+ *
+ * @retval NRF_SUCCESS If initialization was successful for the transport. Any other return code indicates that the DFU transport could not be initialized.
+ */
+typedef uint32_t (*nrf_dfu_init_fn_t)(nrf_dfu_observer_t observer);
+
+
+/** @brief Function type for closing down a DFU transport.
+ *
+ * @details This function closes down a DFU transport in a gentle way.
+ *
+ * @param[in] p_exception If exception matches current transport closing should be omitted.
+ *
+ * @retval NRF_SUCCESS If closing was successful for the transport. Any other return code indicates that the DFU transport could not be closed closed down.
+ */
+typedef uint32_t (*nrf_dfu_close_fn_t)(nrf_dfu_transport_t const * p_exception);
+
+
+
+/** @brief DFU transport registration.
+ *
+ * @details Every DFU transport must provide a registration of the initialization function.
+ */
+struct nrf_dfu_transport_s
+{
+ nrf_dfu_init_fn_t init_func; /**< Registration of the init function to run to initialize a DFU transport. */
+ nrf_dfu_close_fn_t close_func; /**< Registration of the close function to close down a DFU transport. */
+};
+
+
+/** @brief Function for initializing all the registered DFU transports.
+ *
+ * @retval NRF_SUCCESS If all DFU transport were initialized successfully.
+ * Any other error code indicates that at least one DFU
+ * transport could not be initialized.
+ */
+uint32_t nrf_dfu_transports_init(nrf_dfu_observer_t observer);
+
+/** @brief Function for closing down all (with optional exception) the registered DFU transports.
+ *
+ * @param[in] p_exception Transport which should not be closed. NULL if all transports should be closed.
+ * @retval NRF_SUCCESS If all DFU transport were closed down successfully.
+ * Any other error code indicates that at least one DFU
+ * transport could not be closed down.
+ */
+uint32_t nrf_dfu_transports_close(nrf_dfu_transport_t const * p_exception);
+
+
+/** @brief Macro for registering a DFU transport by using section variables.
+ *
+ * @details This macro places a variable in a section named "dfu_trans", which
+ * is initialized by @ref nrf_dfu_transports_init.
+ */
+#define DFU_TRANSPORT_REGISTER(trans_var) NRF_SECTION_ITEM_REGISTER(dfu_trans, trans_var)
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // NRF_DFU_TRANSPORT_H__
+
+/** @} */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/dfu/nrf_dfu_trigger_usb.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/dfu/nrf_dfu_trigger_usb.c
new file mode 100644
index 0000000..582d60c
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/dfu/nrf_dfu_trigger_usb.c
@@ -0,0 +1,237 @@
+/**
+ * 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#include "nrf_dfu_trigger_usb.h"
+#include "app_usbd_string_config.h"
+#include "app_usbd.h"
+#include "app_usbd_nrf_dfu_trigger.h"
+#include "nrf_drv_clock.h"
+#include "nrf_log_ctrl.h"
+#include "nrf_gpio.h"
+#include "boards.h"
+#include "app_util.h"
+#include "app_usbd_serial_num.h"
+#define NRF_LOG_MODULE_NAME nrf_dfu_trigger_usb
+#include "nrf_log.h"
+NRF_LOG_MODULE_REGISTER();
+
+#ifndef BSP_SELF_PINRESET_PIN
+#error "This module is intended to be used with boards that have the GP pin shortened with the RESET pin."
+#endif
+
+/**
+ * @brief Enable power USB detection.
+ *
+ * Configure if the example supports USB port connection.
+ */
+#ifndef USBD_POWER_DETECTION
+#define USBD_POWER_DETECTION true
+#endif
+
+#define DFU_FLASH_PAGE_SIZE (NRF_FICR->CODEPAGESIZE)
+#define DFU_FLASH_PAGE_COUNT (NRF_FICR->CODESIZE)
+
+// Semantic versioning string.
+#define VERSION_STRING STRINGIFY(APP_VERSION_MAJOR) "." STRINGIFY(APP_VERSION_MINOR) "." STRINGIFY(APP_VERSION_PATCH) APP_VERSION_PRERELEASE APP_VERSION_METADATA
+
+static uint8_t m_version_string[] = APP_NAME " " VERSION_STRING; ///< Human-readable version string.
+static app_usbd_nrf_dfu_trigger_nordic_info_t m_dfu_info; ///< Struct with various information about the current firmware.
+
+static void dfu_trigger_evt_handler(app_usbd_class_inst_t const * p_inst,
+ app_usbd_nrf_dfu_trigger_user_event_t event)
+{
+ UNUSED_PARAMETER(p_inst);
+
+ switch (event)
+ {
+ case APP_USBD_NRF_DFU_TRIGGER_USER_EVT_DETACH:
+ NRF_LOG_INFO("DFU Detach request received. Triggering a pin reset.");
+ NRF_LOG_FINAL_FLUSH();
+ nrf_gpio_cfg_output(BSP_SELF_PINRESET_PIN);
+ nrf_gpio_pin_clear(BSP_SELF_PINRESET_PIN);
+ break;
+ default:
+ break;
+ }
+}
+
+
+APP_USBD_NRF_DFU_TRIGGER_GLOBAL_DEF(m_app_dfu,
+ NRF_DFU_TRIGGER_USB_INTERFACE_NUM,
+ &m_dfu_info,
+ m_version_string,
+ dfu_trigger_evt_handler);
+
+
+static void usbd_user_evt_handler(app_usbd_event_type_t event)
+{
+ switch (event)
+ {
+ case APP_USBD_EVT_DRV_SUSPEND:
+ break;
+ case APP_USBD_EVT_DRV_RESUME:
+ break;
+ case APP_USBD_EVT_STARTED:
+ break;
+ case APP_USBD_EVT_STOPPED:
+ app_usbd_disable();
+ break;
+ case APP_USBD_EVT_POWER_DETECTED:
+ NRF_LOG_INFO("USB power detected");
+
+ if (!nrf_drv_usbd_is_enabled())
+ {
+ app_usbd_enable();
+ }
+ break;
+ case APP_USBD_EVT_POWER_REMOVED:
+ NRF_LOG_INFO("USB power removed");
+ app_usbd_stop();
+ break;
+ case APP_USBD_EVT_POWER_READY:
+ NRF_LOG_INFO("USB ready");
+ app_usbd_start();
+ break;
+ default:
+ break;
+ }
+}
+
+
+static void serial_number_strings_create(void)
+{
+ // Remove characters that are not supported in semantic versioning strings.
+ for (size_t i = strlen(APP_NAME) + 1; i < strlen((char*)m_version_string); i++)
+ {
+ if (((m_version_string[i] >= 'a') && (m_version_string[i] <= 'z'))
+ || ((m_version_string[i] >= 'A') && (m_version_string[i] <= 'Z'))
+ || ((m_version_string[i] >= '0') && (m_version_string[i] <= '9'))
+ || (m_version_string[i] == '+')
+ || (m_version_string[i] == '.')
+ || (m_version_string[i] == '-'))
+ {
+ // Valid semantic versioning character.
+ }
+ else
+ {
+ m_version_string[i] = '-';
+ }
+ }
+
+#if !NRF_DFU_TRIGGER_USB_USB_SHARED
+ app_usbd_serial_num_generate();
+#endif
+}
+
+#if !(APP_USBD_CONFIG_EVENT_QUEUE_ENABLE)
+static void usbd_evt_handler(app_usbd_internal_evt_t const * const p_event)
+{
+ app_usbd_event_execute(p_event);
+}
+#endif
+
+ret_code_t nrf_dfu_trigger_usb_init(void)
+{
+ ret_code_t ret;
+ static bool initialized = false;
+
+ if (initialized)
+ {
+ return NRF_SUCCESS;
+ }
+
+ m_dfu_info.wAddress = CODE_START;
+ m_dfu_info.wFirmwareSize = CODE_SIZE;
+ m_dfu_info.wVersionMajor = APP_VERSION_MAJOR;
+ m_dfu_info.wVersionMinor = APP_VERSION_MINOR;
+ m_dfu_info.wFirmwareID = APP_ID;
+ m_dfu_info.wFlashPageSize = DFU_FLASH_PAGE_SIZE;
+ m_dfu_info.wFlashSize = m_dfu_info.wFlashPageSize * DFU_FLASH_PAGE_COUNT;
+
+ serial_number_strings_create();
+
+ if (!NRF_DFU_TRIGGER_USB_USB_SHARED)
+ {
+ static const app_usbd_config_t usbd_config = {
+
+#if !(APP_USBD_CONFIG_EVENT_QUEUE_ENABLE)
+ .ev_handler = usbd_evt_handler,
+#endif
+ .ev_state_proc = usbd_user_evt_handler
+ };
+
+ ret = nrf_drv_clock_init();
+ if ((ret != NRF_SUCCESS) && (ret != NRF_ERROR_MODULE_ALREADY_INITIALIZED))
+ {
+ return ret;
+ }
+
+ ret = app_usbd_init(&usbd_config);
+ if (ret != NRF_SUCCESS)
+ {
+ return ret;
+ }
+ }
+
+ app_usbd_class_inst_t const * class_dfu = app_usbd_nrf_dfu_trigger_class_inst_get(&m_app_dfu);
+ ret = app_usbd_class_append(class_dfu);
+
+ if (!NRF_DFU_TRIGGER_USB_USB_SHARED)
+ {
+ if (USBD_POWER_DETECTION)
+ {
+ ret = app_usbd_power_events_enable();
+ APP_ERROR_CHECK(ret);
+ }
+ else
+ {
+ NRF_LOG_INFO("No USB power detection enabled\r\nStarting USB now");
+
+ app_usbd_enable();
+ app_usbd_start();
+ }
+ }
+
+ if (ret == NRF_SUCCESS)
+ {
+ initialized = true;
+ }
+
+ return ret;
+}
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/dfu/nrf_dfu_trigger_usb.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/dfu/nrf_dfu_trigger_usb.h
new file mode 100644
index 0000000..c7ce4d3
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/dfu/nrf_dfu_trigger_usb.h
@@ -0,0 +1,74 @@
+/**
+ * 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#ifndef NRF_DFU_TRIGGER_USB_H
+#define NRF_DFU_TRIGGER_USB_H
+
+#include "sdk_errors.h"
+
+/**
+ * @defgroup nrf_dfu_trigger_usb USB DFU trigger library
+ * @ingroup app_common
+ *
+ * @brief @tagAPI52840 USB DFU trigger library is used to enter the bootloader and read the firmware version.
+ *
+ * @details See @ref lib_dfu_trigger_usb for additional documentation.
+ * @{
+ */
+
+/**
+ * @brief Function for initializing the USB DFU trigger library.
+ *
+ * @note If the USB is also used for other purposes, then this function must be called after USB is
+ * initialized but before it is enabled. In this case, the configuration flag @ref
+ * NRF_DFU_TRIGGER_USB_USB_SHARED must be set to 1.
+ *
+ * @note Calling this again after the first success has no effect and returns @ref NRF_SUCCESS.
+ *
+ * @note If @ref APP_USBD_CONFIG_EVENT_QUEUE_ENABLE is on (1), USB events must be handled manually.
+ * See @ref app_usbd_event_queue_process.
+ *
+ * @retval NRF_SUCCESS On successful initialization.
+ * @return An error code on failure, for example if called at a wrong time.
+ */
+ret_code_t nrf_dfu_trigger_usb_init(void);
+
+/** @} */
+
+#endif //NRF_DFU_TRIGGER_USB_H
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/dfu/nrf_dfu_types.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/dfu/nrf_dfu_types.h
new file mode 100644
index 0000000..5ccd290
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/dfu/nrf_dfu_types.h
@@ -0,0 +1,302 @@
+/**
+ * Copyright (c) 2016 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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
+ *
+ * @defgroup sdk_nrf_dfu_types DFU types
+ * @{
+ * @ingroup nrf_dfu
+ */
+
+#ifndef NRF_DFU_TYPES_H__
+#define NRF_DFU_TYPES_H__
+
+#include <stdint.h>
+#include <stddef.h>
+
+#include "nrf.h"
+#include "nrf_mbr.h"
+#include "app_util_platform.h"
+#include "sdk_config.h"
+
+#if defined(NRF_DFU_TRANSPORT_BLE) && NRF_DFU_TRANSPORT_BLE
+#include "ble_gap.h"
+#define SYSTEM_SERVICE_ATT_SIZE 8 /**< Size of the system service attribute length including CRC-16 at the end. */
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+#define INIT_COMMAND_MAX_SIZE 256 /**< Maximum size of the init command stored in dfu_settings. */
+
+/** @brief Size of a flash page. This value is used for calculating the size of the reserved
+ * flash space in the bootloader region.
+ */
+#if defined(NRF51)
+ #define CODE_PAGE_SIZE (PAGE_SIZE_IN_WORDS * sizeof(uint32_t))
+#elif defined(NRF52) || defined(NRF52840_XXAA)
+ #define CODE_PAGE_SIZE (MBR_PAGE_SIZE_IN_WORDS * sizeof(uint32_t))
+#else
+ #error "Architecture not set."
+#endif
+
+/** @brief Maximum size of a data object.*/
+#if defined(NRF51)
+ #define DATA_OBJECT_MAX_SIZE (CODE_PAGE_SIZE * 4)
+#elif defined(NRF52_SERIES) || defined (__SDK_DOXYGEN__)
+ #define DATA_OBJECT_MAX_SIZE (CODE_PAGE_SIZE)
+#else
+ #error "Architecture not set."
+#endif
+
+/** @brief Page location of the bootloader settings address.
+ */
+#if defined (NRF51)
+ #define BOOTLOADER_SETTINGS_ADDRESS (0x0003FC00UL)
+#elif defined( NRF52810_XXAA )
+ #define BOOTLOADER_SETTINGS_ADDRESS (0x0002F000UL)
+#elif defined( NRF52832_XXAA )
+ #define BOOTLOADER_SETTINGS_ADDRESS (0x0007F000UL)
+#elif defined(NRF52840_XXAA)
+ #define BOOTLOADER_SETTINGS_ADDRESS (0x000FF000UL)
+#else
+ #error No valid target set for BOOTLOADER_SETTINGS_ADDRESS.
+#endif
+
+#define BOOTLOADER_SETTINGS_PAGE_SIZE (CODE_PAGE_SIZE)
+
+/**
+ * @brief MBR parameters page in UICR.
+ *
+ * Register location in UICR where the page address of the MBR parameters page is stored (only used by the nRF52 MBR).
+ *
+ * @note If the value at the given location is 0xFFFFFFFF, no MBR parameters page is set.
+ */
+#define NRF_UICR_MBR_PARAMS_PAGE_ADDRESS (NRF_UICR_BASE + 0x18)
+#define NRF_MBR_PARAMS_PAGE_SIZE (CODE_PAGE_SIZE)
+
+/** @brief Page location of the MBR parameters page address.
+ */
+#if defined(NRF52840_XXAA) || defined(NRF52840_XXAA_ENGA)
+ #define NRF_MBR_PARAMS_PAGE_ADDRESS (0x000FE000UL)
+#elif defined(NRF52832_XXAA)
+ #define NRF_MBR_PARAMS_PAGE_ADDRESS (0x0007E000UL)
+#elif defined(NRF52810_XXAA)
+ #define NRF_MBR_PARAMS_PAGE_ADDRESS (0x0002E000UL)
+#endif
+
+/** @brief Size (in bytes) of the flash area reserved for application data.
+ *
+ * The area is found at the end of the application area, next to the start of
+ * the bootloader. This area will not be erased by the bootloader during a
+ * firmware upgrade. The default value is 3 pages which matches the size used
+ * in most SDK examples.
+ */
+#ifndef DFU_APP_DATA_RESERVED
+#define DFU_APP_DATA_RESERVED (CODE_PAGE_SIZE * 3)
+#endif
+
+/** @brief Total size of the region between the SoftDevice and the bootloader.
+ */
+#define DFU_REGION_END(bootloader_start_addr) ((bootloader_start_addr) - (DFU_APP_DATA_RESERVED))
+
+#ifdef BLE_STACK_SUPPORT_REQD
+#define DFU_REGION_START (nrf_dfu_bank0_start_addr())
+#else
+#define DFU_REGION_START (MBR_SIZE)
+#endif
+
+#define DFU_REGION_TOTAL_SIZE ((DFU_REGION_END) - (DFU_REGION_START))
+
+#define NRF_DFU_CURRENT_BANK_0 0x00
+#define NRF_DFU_CURRENT_BANK_1 0x01
+
+#define NRF_DFU_BANK_LAYOUT_DUAL 0x00
+#define NRF_DFU_BANK_LAYOUT_SINGLE 0x01
+
+/** @brief DFU bank state codes.
+ *
+ * @details The DFU bank state indicates the content of a bank:
+ * A valid image of a certain type or an invalid image.
+ */
+
+#define NRF_DFU_BANK_INVALID 0x00 /**< Invalid image. */
+#define NRF_DFU_BANK_VALID_APP 0x01 /**< Valid application. */
+#define NRF_DFU_BANK_VALID_SD 0xA5 /**< Valid SoftDevice. */
+#define NRF_DFU_BANK_VALID_BL 0xAA /**< Valid bootloader. */
+#define NRF_DFU_BANK_VALID_SD_BL 0xAC /**< Valid SoftDevice and bootloader. */
+
+/** @brief Description of a single bank. */
+#pragma pack(4)
+typedef struct
+{
+ uint32_t image_size; /**< Size of the image in the bank. */
+ uint32_t image_crc; /**< CRC of the image. If set to 0, the CRC is ignored. */
+ uint32_t bank_code; /**< Identifier code for the bank. */
+} nrf_dfu_bank_t;
+
+/**@brief DFU progress.
+ *
+ * Be aware of the difference between objects and firmware images. A firmware image consists of multiple objects, each of a maximum size @ref DATA_OBJECT_MAX_SIZE.
+ *
+ * @note The union inside this struct is cleared when CREATE_OBJECT of command type is executed, and when there is a valid post-validation.
+ * In DFU activation (after reset) the @ref dfu_progress_t::update_start_address will be used in case of a SD/SD+BL update.
+ */
+ANON_UNIONS_ENABLE;
+typedef struct
+{
+ uint32_t command_size; /**< The size of the current init command stored in the DFU settings. */
+ uint32_t command_offset; /**< The offset of the currently received init command data. The offset will increase as the init command is received. */
+ uint32_t command_crc; /**< The calculated CRC of the init command (calculated after the transfer is completed). */
+ uint32_t data_object_size; /**< The size of the last object created. Note that this size is not the size of the whole firmware image.*/
+ union
+ {
+ struct
+ {
+ uint32_t firmware_image_crc; /**< CRC value of the current firmware (continuously calculated as data is received). */
+ uint32_t firmware_image_crc_last; /**< The CRC of the last executed object. */
+ uint32_t firmware_image_offset; /**< The offset of the current firmware image being transferred. Note that this offset is the offset in the entire firmware image and not only the current object. */
+ uint32_t firmware_image_offset_last;/**< The offset of the last executed object from the start of the firmware image. */
+ };
+ struct
+ {
+ uint32_t update_start_address; /**< Value indicating the start address of the new firmware (before copy). It's always used, but it's most important for an SD/SD+BL update where the SD changes size or if the DFU process had a power loss when updating a SD with changed size. */
+ };
+ };
+} dfu_progress_t;
+ANON_UNIONS_DISABLE;
+
+/** @brief Event types in the bootloader and DFU process. */
+typedef enum
+{
+ NRF_DFU_EVT_DFU_INITIALIZED, /**< Starting DFU. */
+ NRF_DFU_EVT_TRANSPORT_ACTIVATED, /**< Transport activated (e.g. BLE connected, USB plugged in). */
+ NRF_DFU_EVT_TRANSPORT_DEACTIVATED, /**< Transport deactivated (e.g. BLE disconnected, USB plugged out). */
+ NRF_DFU_EVT_DFU_STARTED, /**< DFU process started. */
+ NRF_DFU_EVT_OBJECT_RECEIVED, /**< A DFU data object has been received. */
+ NRF_DFU_EVT_DFU_FAILED, /**< DFU process has failed, been interrupted, or hung. */
+ NRF_DFU_EVT_DFU_COMPLETED, /**< DFU process completed. */
+ NRF_DFU_EVT_DFU_ABORTED, /**< DFU process aborted. */
+} nrf_dfu_evt_type_t;
+
+/**
+ * @brief Function for notifying DFU state.
+ */
+typedef void (*nrf_dfu_observer_t)(nrf_dfu_evt_type_t notification);
+
+
+#if defined(NRF_DFU_TRANSPORT_BLE) && NRF_DFU_TRANSPORT_BLE
+
+typedef struct
+{
+ uint32_t crc; /**< CRC of the rest of the parameters in this struct. */
+ ble_gap_id_key_t ble_id; /**< BLE GAP identity key of the device that initiated the DFU process. */
+ ble_gap_enc_key_t enc_key; /**< Encryption key structure containing encrypted diversifier and LTK for reestablishing the bond. */
+ uint8_t sys_serv_attr[SYSTEM_SERVICE_ATT_SIZE]; /**< System service attributes for restoring of Service Changed Indication setting in DFU mode. */
+} nrf_dfu_peer_data_t;
+
+typedef enum
+{
+ DFU_PEER_DATA_STATE_INVALID = 0,
+ DFU_PEER_DATA_STATE_INITIALIZED = 1,
+ DFU_PEER_DATA_STATE_WRITE_REQUESTED = 2,
+ DFU_PEER_DATA_STATE_WRITE_FINISHED = 3,
+ DFU_PEER_DATA_STATE_WRITE_FAILED = 4,
+} nrf_dfu_peer_data_state_t;
+
+typedef struct
+{
+ uint32_t crc; /**< CRC of the rest of the parameters in this struct. Calculated by the bootloader. */
+ uint8_t name[20]; /**< New advertisement name to set. */
+ uint32_t len; /**< Length of the advertisement name. */
+} nrf_dfu_adv_name_t;
+
+typedef enum
+{
+ DFU_ADV_NAME_STATE_INVALID = 0,
+ DFU_ADV_NAME_STATE_INITIALIZED = 1,
+ DFU_ADV_NAME_STATE_WRITE_REQUESTED = 2,
+ DFU_ADV_NAME_STATE_WRITE_FINISHED = 3,
+ DFU_ADV_NAME_STATE_WRITE_FAILED = 4,
+} nrf_dfu_set_adv_name_state_t;
+
+#endif // NRF_DFU_TRANSPORT_BLE
+
+
+/**@brief DFU settings for application and bank data.
+ */
+typedef struct
+{
+ uint32_t crc; /**< CRC for the stored DFU settings, not including the CRC itself. If 0xFFFFFFF, the CRC has never been calculated. */
+ uint32_t settings_version; /**< Version of the current DFU settings struct layout. */
+ uint32_t app_version; /**< Version of the last stored application. */
+ uint32_t bootloader_version; /**< Version of the last stored bootloader. */
+
+ uint32_t bank_layout; /**< Bank layout: single bank or dual bank. This value can change. */
+ uint32_t bank_current; /**< The bank that is currently used. */
+
+ nrf_dfu_bank_t bank_0; /**< Bank 0. */
+ nrf_dfu_bank_t bank_1; /**< Bank 1. */
+
+ uint32_t write_offset; /**< Write offset for the current operation. */
+ uint32_t sd_size; /**< Size of the SoftDevice. */
+
+ dfu_progress_t progress; /**< Current DFU progress. */
+
+ uint32_t enter_buttonless_dfu;
+ uint8_t init_command[INIT_COMMAND_MAX_SIZE]; /**< Buffer for storing the init command. */
+
+#if defined(NRF_DFU_TRANSPORT_BLE) && NRF_DFU_TRANSPORT_BLE
+ nrf_dfu_peer_data_t peer_data; /**< Not included in calculated CRC. */
+ nrf_dfu_adv_name_t adv_name; /**< Not included in calculated CRC. */
+#endif // NRF_DFU_TRANSPORT_BLE
+
+} nrf_dfu_settings_t;
+
+#pragma pack() // revert pack settings
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // NRF_DFU_TYPES_H__
+
+/** @} */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/dfu/nrf_dfu_utils.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/dfu/nrf_dfu_utils.c
new file mode 100644
index 0000000..286eea6
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/dfu/nrf_dfu_utils.c
@@ -0,0 +1,259 @@
+/**
+ * Copyright (c) 2016 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#include "nrf_dfu_utils.h"
+
+#include "nrf_dfu_settings.h"
+#include "nrf_bootloader_info.h"
+#include "crc32.h"
+#include "nrf_log.h"
+
+void nrf_dfu_bank_invalidate(nrf_dfu_bank_t * const p_bank)
+{
+ // Set the bank-code to invalid, and reset size/CRC
+ memset(p_bank, 0, sizeof(nrf_dfu_bank_t));
+
+ // Reset write pointer after completed operation
+ s_dfu_settings.write_offset = 0;
+}
+
+
+#ifndef BLE_STACK_SUPPORT_REQD
+void nrf_dfu_softdevice_invalidate(void)
+{
+ static const uint32_t all_zero = 0UL;
+
+ if (SD_PRESENT)
+ {
+ ret_code_t err_code = nrf_dfu_flash_store(SD_MAGIC_NUMBER_ABS_OFFSET_GET(MBR_SIZE), &all_zero, 4, NULL);
+ if (err_code != NRF_SUCCESS)
+ {
+ NRF_LOG_ERROR("Could not invalidate SoftDevice.")
+ }
+ else
+ {
+ // If there is an app it must be invalidated since its start address can no longer be resolved.
+ if (s_dfu_settings.bank_0.bank_code == NRF_DFU_BANK_VALID_APP)
+ {
+ s_dfu_settings.bank_0.bank_code = NRF_DFU_BANK_INVALID;
+ }
+ // Since the start of bank 0 has now implicitly been moved to the start
+ // of the invalidated SoftDevice, its image size must be increased by the
+ // same amount so the start of bank 1 will be correctly calculated.
+ s_dfu_settings.bank_0.image_size += SD_SIZE_GET(MBR_SIZE) - MBR_SIZE;
+ }
+ }
+}
+#endif
+
+
+uint32_t nrf_dfu_bank0_start_addr(void)
+{
+ if (SD_PRESENT)
+ {
+ return ALIGN_TO_PAGE(SD_SIZE_GET(MBR_SIZE));
+ }
+ else
+ {
+ return MBR_SIZE;
+ }
+}
+
+
+uint32_t nrf_dfu_bank1_start_addr(void)
+{
+ uint32_t bank0_addr = nrf_dfu_bank0_start_addr();
+ return ALIGN_TO_PAGE(bank0_addr + s_dfu_settings.bank_0.image_size);
+}
+
+
+uint32_t nrf_dfu_app_start_address(void)
+{
+ return nrf_dfu_bank0_start_addr();
+}
+
+
+uint32_t nrf_dfu_softdevice_start_address(void)
+{
+ return MBR_SIZE;
+}
+
+
+bool nrf_dfu_app_is_valid(bool do_crc)
+{
+ NRF_LOG_DEBUG("Enter nrf_dfu_app_is_valid");
+ if (s_dfu_settings.bank_0.bank_code != NRF_DFU_BANK_VALID_APP)
+ {
+ // Bank 0 has no valid app. Nothing to boot
+ NRF_LOG_DEBUG("Return false in valid app check");
+ return false;
+ }
+
+ // If CRC == 0, the CRC check is skipped.
+ if (do_crc && (s_dfu_settings.bank_0.image_crc != 0))
+ {
+ uint32_t crc = crc32_compute((uint8_t*) nrf_dfu_app_start_address(),
+ s_dfu_settings.bank_0.image_size,
+ NULL);
+
+ if (crc != s_dfu_settings.bank_0.image_crc)
+ {
+ // CRC does not match with what is stored.
+ NRF_LOG_DEBUG("Return false in CRC");
+ return false;
+ }
+ }
+
+ NRF_LOG_DEBUG("Return true. App was valid");
+ return true;
+}
+
+
+
+uint32_t nrf_dfu_cache_prepare(const uint32_t required_size, bool single_bank, bool keep_app, bool keep_softdevice)
+{
+ ret_code_t err_code;
+ bool cache_too_small;
+ enum
+ {
+ INITIAL_DELETE_APP = 0,
+ APP_DELETED_DELETE_SOFTDEVICE = 1,
+ SOFTDEVICE_DELETED = 2
+ } pass;
+
+ NRF_LOG_DEBUG("Enter nrf_dfu_cache_prepare()");
+ NRF_LOG_DEBUG("required_size: 0x%x.", required_size);
+ NRF_LOG_DEBUG("single_bank: %s.", single_bank ? "true" : "false");
+ NRF_LOG_DEBUG("keep_app: %s.", keep_app ? "true" : "false");
+ NRF_LOG_DEBUG("keep_softdevice: %s.", keep_softdevice ? "true" : "false");
+ NRF_LOG_DEBUG("SD_PRESENT: %s.", SD_PRESENT ? "true" : "false");
+ NRF_LOG_DEBUG("Bank contents:");
+ NRF_LOG_DEBUG("Bank 0 code: 0x%02x: Size: 0x%x", s_dfu_settings.bank_0.bank_code, s_dfu_settings.bank_0.image_size);
+ NRF_LOG_DEBUG("Bank 1 code: 0x%02x: Size: 0x%x", s_dfu_settings.bank_1.bank_code, s_dfu_settings.bank_1.image_size);
+
+ // Pass 0 deletes the app if necessary or requested, and if so, proceeds to pass 1.
+ // Pass 1 deletes the SoftDevice if necessary or requested, and if so, proceeds to pass 2.
+ // Pass 2 does a last size check.
+ for (pass = INITIAL_DELETE_APP; pass <= SOFTDEVICE_DELETED; pass++)
+ {
+ uint32_t cache_address;
+ const uint32_t bootloader_start_addr = BOOTLOADER_START_ADDR; // Assign to a variable to prevent warning in Keil 4.
+ bool keep_firmware = true;
+ bool delete_more;
+
+ switch (pass)
+ {
+ case INITIAL_DELETE_APP:
+ cache_address = nrf_dfu_bank1_start_addr();
+
+ // If there is no app, keep_app should be assumed false, so we can free up more space.
+ keep_firmware = keep_app && (s_dfu_settings.bank_0.bank_code == NRF_DFU_BANK_VALID_APP);
+ break;
+
+ case APP_DELETED_DELETE_SOFTDEVICE:
+ cache_address = nrf_dfu_bank0_start_addr();
+
+ // If there is no SoftDevice, keep_SoftDevice should be assumed true, because there is
+ // no point to continuing since the SoftDevice is the last firmware that can be deleted.
+ keep_firmware = keep_softdevice || !SD_PRESENT;
+ break;
+
+ case SOFTDEVICE_DELETED:
+ cache_address = nrf_dfu_softdevice_start_address();
+ break;
+
+ default:
+ ASSERT(false);
+ cache_address = 0;
+ break;
+ }
+
+ ASSERT(cache_address <= DFU_REGION_END(bootloader_start_addr));
+ cache_too_small = required_size > (DFU_REGION_END(bootloader_start_addr) - cache_address);
+ delete_more = cache_too_small || single_bank; // Delete app or SoftDevice only if we need more room, or if single bank is requested.
+
+ NRF_LOG_DEBUG("pass: %d.", pass);
+ NRF_LOG_DEBUG("cache_address: 0x%x.", cache_address);
+ NRF_LOG_DEBUG("cache_too_small: %s.", cache_too_small ? "true" : "false");
+ NRF_LOG_DEBUG("keep_firmware: %s.", keep_firmware ? "true" : "false");
+ NRF_LOG_DEBUG("delete_more: %s.", delete_more ? "true" : "false");
+
+ if (!delete_more || keep_firmware || (pass >= SOFTDEVICE_DELETED))
+ {
+ // Stop, done.
+ break;
+ }
+ }
+
+ if (cache_too_small)
+ {
+ NRF_LOG_WARNING("Aborting. Cannot fit new firmware on device");
+ err_code = NRF_ERROR_NO_MEM;
+ }
+ else
+ {
+ // Room was found. Make the necessary preparations for receiving update.
+
+#ifndef BLE_STACK_SUPPORT_REQD
+ if (pass >= SOFTDEVICE_DELETED)
+ {
+ NRF_LOG_DEBUG("Invalidating SoftDevice.");
+ nrf_dfu_softdevice_invalidate();
+ }
+#endif
+ if (pass >= APP_DELETED_DELETE_SOFTDEVICE)
+ {
+ NRF_LOG_DEBUG("Invalidating app.");
+ nrf_dfu_bank_invalidate(&s_dfu_settings.bank_0);
+ }
+
+ s_dfu_settings.bank_layout = NRF_DFU_BANK_LAYOUT_DUAL;
+ s_dfu_settings.bank_current = NRF_DFU_CURRENT_BANK_1;
+
+ // Prepare bank for new image.
+ nrf_dfu_bank_invalidate(&s_dfu_settings.bank_1);
+
+ // Store the Firmware size in the bank for continuations
+ s_dfu_settings.bank_1.image_size = required_size;
+
+ err_code = NRF_SUCCESS;
+ }
+
+ return err_code;
+}
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/dfu/nrf_dfu_utils.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/dfu/nrf_dfu_utils.h
new file mode 100644
index 0000000..6369f92
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/dfu/nrf_dfu_utils.h
@@ -0,0 +1,167 @@
+/**
+ * Copyright (c) 2016 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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
+ *
+ * @defgroup sdk_nrf_dfu_utils DFU utilities
+ * @{
+ * @ingroup nrf_dfu
+ */
+
+#ifndef NRF_DFU_UTILS_H__
+#define NRF_DFU_UTILS_H__
+
+#include <stdint.h>
+#include <stdbool.h>
+#include "nrf_dfu_types.h"
+#include "app_util.h"
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+/**
+ * Round up val to the next page boundary
+ */
+#define ALIGN_TO_PAGE(val) ALIGN_NUM((CODE_PAGE_SIZE), (val))
+
+
+/** @brief Function for getting the start address of bank 0.
+ *
+ * @note Bank 0 starts after the SoftDevice if a SoftDevice is present.
+ *
+ * @return The start address of bank 0.
+ */
+uint32_t nrf_dfu_bank0_start_addr(void);
+
+
+/** @brief Function for getting the start address of bank 1.
+ *
+ * @return The start address of bank 1.
+ */
+uint32_t nrf_dfu_bank1_start_addr(void);
+
+
+/** @brief Function for getting the start address of the app.
+ *
+ * @return The start address of the bootable app.
+ */
+uint32_t nrf_dfu_app_start_address(void);
+
+
+/** @brief Function for getting the start address of the SoftDevice.
+ *
+ * @return The start address of the SoftDevivce.
+ */
+uint32_t nrf_dfu_softdevice_start_address(void);
+
+
+/** @brief Function for checking if the main application is valid.
+ *
+ * @details This function checks if there is a valid application
+ * located at Bank 0.
+ *
+ * @param[in] do_crc Perform CRC check on application.
+ *
+ * @retval true If a valid application has been detected.
+ * @retval false If there is no valid application.
+ */
+bool nrf_dfu_app_is_valid(bool do_crc);
+
+
+/** @brief Function for finding and preparing a place in flash in which to store a DFU update.
+ *
+ * @details This function checks the size requirements and selects a location for
+ * placing the cache of the DFU images.
+ * The function tries to find enough space after the existing firmwares. If there is not
+ * enough space, the present application is deleted. If there is still not enough space,
+ * the SoftDevice is deleted.
+ * If @p single_bank is true, the default behavior is to immediately delete the app and
+ * SoftDevice as necessary to place the new firmware at its intended location. If the
+ * intended location cannot be made available, or if the update is a bootloader update,
+ * the update will be a dual bank update, and nothing will be deleted by this function
+ * except when needed for size.
+ * If @p keep_app is true, the app is never deleted by this function. Likewise if @p
+ * keep_softdevice is true, the SoftDevice is never deleted by this function.
+ * If the new firmware cannot fit within the constraints, nothing is deleted and the
+ * function fails.
+ *
+ * @param[in] required_size Requirements for the size of the new image.
+ * @param[in] single_bank Whether to put the firmware directly where it's meant to go.
+ * @p keep_app and @p keep_softdevice take precedence over this.
+ * @param[in] keep_app True to ensure the app is not deleted by this function. This
+ * effectively enforces dual bank update.
+ * @param[out] keep_softdevice True to ensure the SoftDevice is not deleted by this function.
+ *
+ * @retval NRF_SUCCESS If a cache location was found for the DFU process.
+ * @retval NRF_ERROR_NO_MEM If there is not enough space available to receive the update.
+ * Nothing has been deleted.
+ */
+uint32_t nrf_dfu_cache_prepare(uint32_t required_size, bool single_bank, bool keep_app, bool keep_softdevice);
+
+
+/**@brief Function for making sure a SoftDevice is not recognized as such anymore.
+ *
+ * @details It works by overwriting the magic number of the SoftDevice with 0s. The
+ * magic number is used throughout the bootloader to detect whether a SoftDevice
+ * is present.
+ *
+ * @warning This function should only be called when both banks are already invalid.
+ * because the (implicit) position of the banks will shift when the SoftDevice
+ * is invalidated.
+ */
+void nrf_dfu_softdevice_invalidate(void);
+
+
+/**@brief Function for making sure a bank is not copied or booted.
+ *
+ * @details This also sets the size of the bank to 0.
+ *
+ * @param[in] p_bank Pointer to the bank to be invalidated.
+ */
+void nrf_dfu_bank_invalidate(nrf_dfu_bank_t * const p_bank);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // NRF_DFU_UTILS_H__
+
+/** @} */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/dfu/nrf_dfu_validation.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/dfu/nrf_dfu_validation.c
new file mode 100644
index 0000000..566702d
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/dfu/nrf_dfu_validation.c
@@ -0,0 +1,745 @@
+/**
+ * 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#include <stdbool.h>
+#include "nrf_dfu_types.h"
+#include "nrf_dfu_settings.h"
+#include "nrf_dfu_utils.h"
+#include "nrf_dfu_flash.h"
+#include "nrf_bootloader_info.h"
+#include "pb.h"
+#include "pb_common.h"
+#include "pb_decode.h"
+#include "dfu-cc.pb.h"
+#include "crc32.h"
+#include "nrf_crypto.h"
+#include "nrf_assert.h"
+#include "nrf_dfu_validation.h"
+#include "nrf_dfu_ver_validation.h"
+
+#define NRF_LOG_MODULE_NAME nrf_dfu_validation
+#include "nrf_log.h"
+#include "nrf_log_ctrl.h"
+NRF_LOG_MODULE_REGISTER();
+
+
+#ifndef NRF_DFU_DEBUG
+#ifdef NRF_DFU_DEBUG_VERSION
+#define NRF_DFU_DEBUG 1
+#else
+#define NRF_DFU_DEBUG 0
+#endif
+#endif
+
+#ifndef DFU_REQUIRES_SOFTDEVICE
+#ifndef BLE_STACK_SUPPORT_REQD
+#define DFU_REQUIRES_SOFTDEVICE 0
+#else
+#define DFU_REQUIRES_SOFTDEVICE 1
+#endif
+#endif
+
+#define EXT_ERR(err) (nrf_dfu_result_t)((uint32_t)NRF_DFU_RES_CODE_EXT_ERROR + (uint32_t)err)
+
+/* Whether a complete init command has been received and prevalidated, but the firmware
+ * is not yet fully transferred. This value will also be correct after reset.
+ */
+static bool m_valid_init_cmd_present = false;
+static dfu_packet_t m_packet = DFU_PACKET_INIT_DEFAULT;
+static uint8_t* m_init_packet_data_ptr = 0;
+static uint32_t m_init_packet_data_len = 0;
+static pb_istream_t m_pb_stream;
+
+static nrf_crypto_ecdsa_verify_context_t m_verify_context = {0};
+
+static nrf_crypto_hash_context_t m_hash_context = {0};
+
+
+__ALIGN(4) extern const uint8_t pk[64];
+
+/** @brief Value length structure holding the public key.
+ *
+ * @details The pk value pointed to is the public key present in dfu_public_key.c
+ */
+static nrf_crypto_ecc_public_key_t m_public_key;
+
+/** @brief Structure to hold a signature
+ */
+static nrf_crypto_ecdsa_secp256r1_signature_t m_signature;
+
+/** @brief Structure to hold the hash for the init packet
+ */
+static nrf_crypto_hash_sha256_digest_t m_init_packet_hash;
+
+/** @brief Structure to hold the hash for the firmware image
+ */
+static nrf_crypto_hash_sha256_digest_t m_fw_hash;
+
+
+static void pb_decoding_callback(pb_istream_t *str, uint32_t tag, pb_wire_type_t wire_type, void *iter)
+{
+ pb_field_iter_t* p_iter = (pb_field_iter_t *) iter;
+
+ // match the beginning of the init command
+ if (p_iter->pos->ptr == &dfu_init_command_fields[0])
+ {
+ uint8_t * ptr = (uint8_t *)str->state;
+ uint32_t size = str->bytes_left;
+
+ // remove tag byte
+ ptr++;
+ size--;
+
+ // store the info in init_packet_data
+ m_init_packet_data_ptr = ptr;
+ m_init_packet_data_len = size;
+
+ NRF_LOG_DEBUG("PB: Init packet data len: %d", size);
+ }
+}
+
+/** @brief Function for decoding byte stream into variable.
+ *
+ * @retval true If the stored init command was successfully decoded.
+ * @retval false If there was no stored init command, or the decoding failed.
+ */
+static bool stored_init_cmd_decode(void)
+{
+ m_pb_stream = pb_istream_from_buffer(s_dfu_settings.init_command,
+ s_dfu_settings.progress.command_size);
+
+ // Attach our callback to follow the field decoding
+ m_pb_stream.decoding_callback = pb_decoding_callback;
+
+ m_init_packet_data_ptr = NULL;
+ m_init_packet_data_len = 0;
+
+ if (!pb_decode(&m_pb_stream, dfu_packet_fields, &m_packet))
+ {
+ NRF_LOG_ERROR("Handler: Invalid protocol buffer m_pb_stream");
+ return false;
+ }
+
+ return true;
+}
+
+
+void nrf_dfu_validation_init(void)
+{
+ ret_code_t err_code;
+
+ // If the command is stored to flash, init command was valid.
+ if ( (s_dfu_settings.progress.command_size != 0)
+ && stored_init_cmd_decode()
+ && (s_dfu_settings.bank_1.image_size != 0))
+ {
+ m_valid_init_cmd_present = true;
+ }
+ else
+ {
+ m_valid_init_cmd_present = false;
+ }
+
+ err_code = nrf_crypto_init();
+ ASSERT(err_code == NRF_SUCCESS);
+ UNUSED_PARAMETER(err_code);
+
+
+ err_code = nrf_crypto_ecc_public_key_from_raw(&g_nrf_crypto_ecc_secp256r1_curve_info,
+ &m_public_key,
+ pk,
+ sizeof(pk));
+ ASSERT(err_code == NRF_SUCCESS);
+ UNUSED_PARAMETER(err_code);
+}
+
+
+nrf_dfu_result_t nrf_dfu_validation_init_cmd_create(uint32_t size)
+{
+ nrf_dfu_result_t ret_val = NRF_DFU_RES_CODE_SUCCESS;
+ if (size == 0)
+ {
+ ret_val = NRF_DFU_RES_CODE_INVALID_PARAMETER;
+ }
+ else if (size > INIT_COMMAND_MAX_SIZE)
+ {
+ ret_val = NRF_DFU_RES_CODE_INSUFFICIENT_RESOURCES;
+ }
+ else
+ {
+ // Set DFU to uninitialized.
+ m_valid_init_cmd_present = false;
+
+ // Reset all progress.
+ s_dfu_settings.write_offset = 0;
+ memset(&s_dfu_settings.progress, 0x00, sizeof(dfu_progress_t));
+
+ // Set the init command size.
+ s_dfu_settings.progress.command_size = size;
+ }
+ return ret_val;
+}
+
+
+nrf_dfu_result_t nrf_dfu_validation_init_cmd_append(uint8_t const * p_data, uint32_t length)
+{
+ nrf_dfu_result_t ret_val = NRF_DFU_RES_CODE_SUCCESS;
+ if ((length + s_dfu_settings.progress.command_offset) > s_dfu_settings.progress.command_size)
+ {
+ NRF_LOG_ERROR("Init command larger than expected.");
+ ret_val = NRF_DFU_RES_CODE_INVALID_PARAMETER;
+ }
+ else
+ {
+ // Copy the received data to RAM, update offset and calculate CRC.
+ memcpy(&s_dfu_settings.init_command[s_dfu_settings.progress.command_offset],
+ p_data,
+ length);
+
+ s_dfu_settings.progress.command_offset += length;
+ s_dfu_settings.progress.command_crc = crc32_compute(p_data,
+ length,
+ &s_dfu_settings.progress.command_crc);
+ }
+ return ret_val;
+}
+
+
+void nrf_dfu_validation_init_cmd_status_get(uint32_t * p_offset,
+ uint32_t * p_crc,
+ uint32_t * p_max_size)
+{
+ *p_offset = s_dfu_settings.progress.command_offset;
+ *p_crc = s_dfu_settings.progress.command_crc;
+ *p_max_size = INIT_COMMAND_MAX_SIZE;
+}
+
+
+bool nrf_dfu_validation_init_cmd_present(void)
+{
+ return m_valid_init_cmd_present;
+}
+
+
+// Function determines if init command signature is obligatory
+static bool signature_required(dfu_fw_type_t fw_type_to_be_updated)
+{
+ bool result = true;
+
+ if ((!DFU_REQUIRES_SOFTDEVICE && (fw_type_to_be_updated == DFU_FW_TYPE_SOFTDEVICE)) ||
+ (fw_type_to_be_updated == DFU_FW_TYPE_APPLICATION))
+ {
+ result = NRF_DFU_REQUIRE_SIGNED_APP_UPDATE;
+ }
+ return result;
+}
+
+
+// Function to perform signature check if required.
+static nrf_dfu_result_t signature_check(dfu_fw_type_t fw_type,
+ dfu_signature_type_t signature_type,
+ dfu_signed_command_signature_t const * p_signature)
+{
+ ret_code_t err_code;
+ size_t hash_len = NRF_CRYPTO_HASH_SIZE_SHA256;
+
+ if (!signature_required(fw_type))
+ {
+ return NRF_DFU_RES_CODE_SUCCESS;
+ }
+
+ NRF_LOG_INFO("Signature required. Checking signature.")
+ if (p_signature == NULL)
+ {
+ NRF_LOG_WARNING("No signature found.");
+ return EXT_ERR(NRF_DFU_EXT_ERROR_SIGNATURE_MISSING);
+ }
+
+ if (signature_type != DFU_SIGNATURE_TYPE_ECDSA_P256_SHA256)
+ {
+ NRF_LOG_INFO("Invalid signature type");
+ return EXT_ERR(NRF_DFU_EXT_ERROR_WRONG_SIGNATURE_TYPE);
+ }
+
+ NRF_LOG_INFO("Calculating init packet hash (init packet len: %d)", m_init_packet_data_len);
+ err_code = nrf_crypto_hash_calculate(&m_hash_context,
+ &g_nrf_crypto_hash_sha256_info,
+ m_init_packet_data_ptr,
+ m_init_packet_data_len,
+ m_init_packet_hash,
+ &hash_len);
+ if (err_code != NRF_SUCCESS)
+ {
+ return NRF_DFU_RES_CODE_OPERATION_FAILED;
+ }
+
+ if (sizeof(m_signature) != p_signature->size)
+ {
+ return NRF_DFU_RES_CODE_OPERATION_FAILED;
+ }
+
+ // Prepare the signature received over the air.
+ memcpy(m_signature, p_signature->bytes, p_signature->size);
+
+ // calculate the signature
+ NRF_LOG_INFO("Verify signature");
+ err_code = nrf_crypto_ecdsa_verify(&m_verify_context,
+ &m_public_key,
+ m_init_packet_hash,
+ hash_len,
+ m_signature,
+ sizeof(m_signature));
+ if (err_code != NRF_SUCCESS)
+ {
+ NRF_LOG_ERROR("Signature failed (err_code: 0x%x)", err_code);
+ NRF_LOG_DEBUG("Signature:");
+ NRF_LOG_HEXDUMP_DEBUG(m_signature, sizeof(m_signature));
+ NRF_LOG_DEBUG("Hash:");
+ NRF_LOG_HEXDUMP_DEBUG(m_init_packet_hash, hash_len);
+ NRF_LOG_DEBUG("Public Key:");
+ NRF_LOG_HEXDUMP_DEBUG(pk, sizeof(pk));
+ NRF_LOG_FLUSH();
+
+ return NRF_DFU_RES_CODE_INVALID_OBJECT;
+ }
+
+ NRF_LOG_INFO("Image verified");
+ return NRF_DFU_RES_CODE_SUCCESS;
+}
+
+
+// Function to calculate the total size of the firmware(s) in the update.
+static nrf_dfu_result_t update_data_size_get(dfu_init_command_t const * p_init, uint32_t * p_size)
+{
+ nrf_dfu_result_t ret_val = EXT_ERR(NRF_DFU_EXT_ERROR_INIT_COMMAND_INVALID);
+ uint32_t fw_sz = 0;
+
+ if ((p_init->type == DFU_FW_TYPE_APPLICATION) && (p_init->has_app_size == true))
+ {
+ fw_sz = p_init->app_size;
+ }
+ else
+ {
+ if ((p_init->type & DFU_FW_TYPE_SOFTDEVICE) && (p_init->has_sd_size == true))
+ {
+ fw_sz = p_init->sd_size;
+ }
+
+ if ((p_init->type & DFU_FW_TYPE_BOOTLOADER) && (p_init->has_bl_size == true))
+ {
+ if (p_init->bl_size <= BOOTLOADER_SIZE)
+ {
+ fw_sz += p_init->bl_size;
+ }
+ else
+ {
+ NRF_LOG_ERROR("BL size (%d) over limit (%d)", p_init->bl_size, BOOTLOADER_SIZE);
+ fw_sz = 0;
+ ret_val = NRF_DFU_RES_CODE_INSUFFICIENT_RESOURCES;
+ }
+ }
+ }
+
+ if (fw_sz)
+ {
+ *p_size = fw_sz;
+ ret_val = NRF_DFU_RES_CODE_SUCCESS;
+ }
+ else
+ {
+ NRF_LOG_ERROR("Init packet does not contain valid firmware size");
+ }
+
+ return ret_val;
+}
+
+
+/**
+ * @brief Function to check if single bank update should be used.
+ *
+ * @param new_fw_type Firmware type.
+ */
+static bool use_single_bank(dfu_fw_type_t new_fw_type)
+{
+ bool result = false;
+
+ if (((new_fw_type == DFU_FW_TYPE_APPLICATION) || (new_fw_type == DFU_FW_TYPE_SOFTDEVICE)) &&
+ NRF_DFU_SINGLE_BANK_APP_UPDATES)
+ {
+ result = true;
+ }
+
+ return result;
+}
+
+
+// Function to determine if the new firmware needs a SoftDevice to be present.
+static bool update_requires_softdevice(dfu_init_command_t const * p_init)
+{
+ return ((p_init->sd_req_count > 0) && (p_init->sd_req[0] != SD_REQ_APP_OVERWRITES_SD));
+}
+
+
+// Function to determine if the SoftDevice can be removed during the update or not.
+static bool keep_softdevice(dfu_init_command_t const * p_init)
+{
+ UNUSED_PARAMETER(p_init); // It's unused when DFU_REQUIRES_SOFTDEVICE is true.
+ return DFU_REQUIRES_SOFTDEVICE || update_requires_softdevice(p_init);
+}
+
+
+/**@brief Function to determine where to temporarily store the incoming firmware.
+ * This also checks whether the update will fit, and deletes existing
+ * firmware to make room for the new firmware.
+ *
+ * @param[in] p_init Init command.
+ * @param[in] fw_size The size of the incoming firmware.
+ * @param[out] p_addr The address at which to initially store the firmware.
+ *
+ * @retval NRF_DFU_RES_CODE_SUCCESS If the size check passed and
+ * an address was found.
+ * @retval NRF_DFU_RES_CODE_INSUFFICIENT_RESOURCES If the size check failed.
+ */
+static nrf_dfu_result_t update_data_addr_get(dfu_init_command_t const * p_init,
+ uint32_t fw_size,
+ uint32_t * p_addr)
+{
+ nrf_dfu_result_t ret_val = NRF_DFU_RES_CODE_SUCCESS;
+ ret_code_t err_code = nrf_dfu_cache_prepare(fw_size,
+ use_single_bank(p_init->type),
+ NRF_DFU_FORCE_DUAL_BANK_APP_UPDATES,
+ keep_softdevice(p_init));
+ if (err_code != NRF_SUCCESS)
+ {
+ NRF_LOG_ERROR("Can't find room for update");
+ ret_val = NRF_DFU_RES_CODE_INSUFFICIENT_RESOURCES;
+ }
+ else
+ {
+ *p_addr = nrf_dfu_bank1_start_addr();
+ NRF_LOG_DEBUG("Write address set to 0x%08x", *p_addr);
+ }
+ return ret_val;
+}
+
+
+nrf_dfu_result_t nrf_dfu_validation_init_cmd_execute(uint32_t * p_dst_data_addr,
+ uint32_t * p_data_len)
+{
+ nrf_dfu_result_t ret_val = NRF_DFU_RES_CODE_SUCCESS;
+
+ if (s_dfu_settings.progress.command_offset != s_dfu_settings.progress.command_size)
+ {
+ // The object wasn't the right (requested) size
+ NRF_LOG_ERROR("Execute with faulty offset");
+ ret_val = NRF_DFU_RES_CODE_OPERATION_NOT_PERMITTED;
+ }
+ else if (m_valid_init_cmd_present)
+ {
+ *p_dst_data_addr = nrf_dfu_bank1_start_addr();
+ *p_data_len = s_dfu_settings.bank_1.image_size;
+ ret_val = NRF_DFU_RES_CODE_SUCCESS;
+ }
+ else if (stored_init_cmd_decode() &&
+ (m_packet.has_signed_command || m_packet.has_command))
+ {
+ dfu_command_t const * p_command = &m_packet.command;
+ dfu_signature_type_t signature_type = (dfu_signature_type_t) 0; // Placeholder.
+ dfu_signed_command_signature_t * p_signature = NULL;
+
+ *p_dst_data_addr = 0;
+ *p_data_len = 0;
+
+ if (m_packet.has_signed_command)
+ {
+ p_command = &m_packet.signed_command.command;
+ signature_type = m_packet.signed_command.signature_type;
+ p_signature = &m_packet.signed_command.signature;
+ }
+
+ // Validate signature.
+ ret_val = signature_check(p_command->init.type, signature_type, p_signature);
+
+ // Validate versions
+ if (ret_val == NRF_DFU_RES_CODE_SUCCESS)
+ {
+ ret_val = nrf_dfu_ver_validation_check(&p_command->init);
+ if (ret_val == NRF_DFU_RES_CODE_SUCCESS)
+ {
+ m_valid_init_cmd_present = true;
+ }
+ }
+
+ // Get size of binary
+ if (ret_val == NRF_DFU_RES_CODE_SUCCESS)
+ {
+ ret_val = update_data_size_get(&p_command->init, p_data_len);
+ }
+
+ //Get address where to flash the binary
+ if (ret_val == NRF_DFU_RES_CODE_SUCCESS)
+ {
+ ret_val = update_data_addr_get(&p_command->init, *p_data_len, p_dst_data_addr);
+ }
+ }
+ else
+ {
+ NRF_LOG_ERROR("Failed to decode init packet");
+ ret_val = NRF_DFU_RES_CODE_INVALID_OBJECT;
+ }
+
+ return ret_val;
+}
+
+
+// Function to check the hash received in the init command against the received firmware.
+static bool fw_hash_ok(dfu_init_command_t const * p_init, uint32_t fw_start_addr, uint32_t fw_size)
+{
+ ret_code_t err_code;
+ bool result = true;
+ size_t hash_len = NRF_CRYPTO_HASH_SIZE_SHA256;
+
+ ASSERT(p_init != NULL);
+
+ NRF_LOG_DEBUG("Hash verification. Firmware start address: 0x%x, size: 0x%x", fw_start_addr, fw_size);
+ err_code = nrf_crypto_hash_calculate(&m_hash_context,
+ &g_nrf_crypto_hash_sha256_info,
+ (uint8_t*)fw_start_addr,
+ fw_size,
+ m_fw_hash,
+ &hash_len);
+
+ if (err_code != NRF_SUCCESS)
+ {
+ NRF_LOG_ERROR("Could not run hash verification (err_code 0x%x).", err_code);
+ result = false;
+ }
+ else if (memcmp(m_fw_hash, p_init->hash.hash.bytes, NRF_CRYPTO_HASH_SIZE_SHA256) != 0)
+ {
+ NRF_LOG_WARNING("Hash verification failed.");
+ NRF_LOG_DEBUG("Expected FW hash:")
+ NRF_LOG_HEXDUMP_DEBUG(p_init->hash.hash.bytes, NRF_CRYPTO_HASH_SIZE_SHA256);
+ NRF_LOG_DEBUG("Actual FW hash:")
+ NRF_LOG_HEXDUMP_DEBUG(m_fw_hash, NRF_CRYPTO_HASH_SIZE_SHA256);
+ NRF_LOG_FLUSH();
+
+ result = false;
+ }
+
+ return result;
+}
+
+
+// Function to check if the update contains a SoftDevice and, if so, if it is of a different
+// major version than the existing SoftDevice.
+static bool is_major_softdevice_update(uint32_t new_sd_addr)
+{
+ // True if there is no SD right now, but there is a new one coming. This counts as a major update.
+ bool result = !SD_PRESENT && (SD_MAGIC_NUMBER_GET(new_sd_addr) == SD_MAGIC_NUMBER);
+
+ if (SD_PRESENT && (SD_MAGIC_NUMBER_GET(new_sd_addr) == SD_MAGIC_NUMBER))
+ {
+ // Both SoftDevices are present.
+ uint32_t current_SD_major = SD_MAJOR_VERSION_EXTRACT(SD_VERSION_GET(MBR_SIZE));
+ uint32_t new_SD_major = SD_MAJOR_VERSION_EXTRACT(SD_VERSION_GET(new_sd_addr));
+
+ result = (current_SD_major != new_SD_major);
+
+ NRF_LOG_INFO("SoftDevice update is a %s version update. Current: %d. New: %d.",
+ result ? "major" : "minor",
+ current_SD_major,
+ new_SD_major);
+ }
+
+ return result;
+}
+
+
+/**@brief Validate the SoftDevice size and magic number in structure found at 0x2000 in received SoftDevice.
+ *
+ * @param[in] sd_start_addr Start address of received SoftDevice.
+ * @param[in] sd_size Size of received SoftDevice in bytes.
+ */
+static bool softdevice_info_ok(uint32_t sd_start_addr, uint32_t sd_size)
+{
+ bool result = true;
+
+ if (SD_MAGIC_NUMBER_GET(sd_start_addr) != SD_MAGIC_NUMBER)
+ {
+ NRF_LOG_ERROR("The SoftDevice does not contain the magic number identifying it as a SoftDevice.");
+ result = false;
+ }
+ else if (SD_SIZE_GET(sd_start_addr) < ALIGN_TO_PAGE(sd_size + MBR_SIZE))
+ {
+ // The size in the info struct should be rounded up to a page boundary
+ // and be larger than the actual size + the size of the MBR.
+ NRF_LOG_ERROR("The SoftDevice size in the info struct is too small compared with the size reported in the init command.");
+ result = false;
+ }
+
+ return result;
+}
+
+
+static void postvalidate_app(dfu_init_command_t * p_init)
+{
+ s_dfu_settings.bank_1.bank_code = NRF_DFU_BANK_VALID_APP;
+
+ NRF_LOG_DEBUG("Invalidating old application in bank 0.");
+ s_dfu_settings.bank_0.bank_code = NRF_DFU_BANK_INVALID;
+
+ if (!DFU_REQUIRES_SOFTDEVICE && !update_requires_softdevice(p_init))
+ {
+ // App does not need SD, so it should be placed where SD is.
+ nrf_dfu_softdevice_invalidate();
+ }
+
+ if (!NRF_DFU_DEBUG ||
+ (NRF_DFU_DEBUG && (p_init->has_is_debug == false || p_init->is_debug == false)))
+ {
+ s_dfu_settings.app_version = p_init->fw_version;
+ }
+}
+
+
+// Function to check a received SoftDevice and/or Bootloader firmware
+// before it is copied into place.
+static bool postvalidate_sd_bl(dfu_init_command_t * p_init,
+ bool with_sd,
+ bool with_bl,
+ uint32_t start_addr)
+{
+ if (with_sd)
+ {
+ if (!softdevice_info_ok(start_addr, p_init->sd_size))
+ {
+ return false;
+ }
+
+ if (is_major_softdevice_update(start_addr))
+ {
+ NRF_LOG_WARNING("Invalidating app because it is incompatible with the SoftDevice.");
+ if (DFU_REQUIRES_SOFTDEVICE && !with_bl)
+ {
+ NRF_LOG_ERROR("Major SD update but no BL. Abort to avoid incapacitating the BL.");
+ return false;
+ }
+
+ // Invalidate app since it may not be compatible with new SD.
+ nrf_dfu_bank_invalidate(&s_dfu_settings.bank_0);
+ }
+
+ // Mark the update as valid.
+ s_dfu_settings.bank_1.bank_code = with_bl ? NRF_DFU_BANK_VALID_SD_BL
+ : NRF_DFU_BANK_VALID_SD;
+
+ s_dfu_settings.sd_size = p_init->sd_size;
+ }
+ else
+ {
+ s_dfu_settings.bank_1.bank_code = NRF_DFU_BANK_VALID_BL;
+ }
+
+
+ if (with_bl &&
+ (!NRF_DFU_DEBUG ||
+ (NRF_DFU_DEBUG && (p_init->has_is_debug == false || p_init->is_debug == false))))
+ {
+ // If the update contains a bootloader, update the version.
+ // Unless the update is a debug packet.
+ s_dfu_settings.bootloader_version = p_init->fw_version;
+ }
+
+ return true;
+}
+
+
+nrf_dfu_result_t nrf_dfu_validation_post_data_execute(uint32_t src_addr, uint32_t data_len)
+{
+ nrf_dfu_result_t ret_val = NRF_DFU_RES_CODE_SUCCESS;
+ dfu_init_command_t * p_init = m_packet.has_signed_command ? &m_packet.signed_command.command.init
+ : &m_packet.command.init;
+
+ if (!fw_hash_ok(p_init, src_addr, data_len))
+ {
+ ret_val = EXT_ERR(NRF_DFU_EXT_ERROR_VERIFICATION_FAILED);
+ }
+ else
+ {
+ if (p_init->type == DFU_FW_TYPE_APPLICATION)
+ {
+ postvalidate_app(p_init);
+ }
+ else
+ {
+ bool with_sd = p_init->type & DFU_FW_TYPE_SOFTDEVICE;
+ bool with_bl = p_init->type & DFU_FW_TYPE_BOOTLOADER;
+
+ if (!postvalidate_sd_bl(p_init, with_sd, with_bl, src_addr))
+ {
+ ret_val = NRF_DFU_RES_CODE_INVALID_OBJECT;
+ if (with_sd && !DFU_REQUIRES_SOFTDEVICE &&
+ (src_addr == nrf_dfu_softdevice_start_address()))
+ {
+ nrf_dfu_softdevice_invalidate();
+ }
+ }
+ }
+ }
+
+ if (ret_val == NRF_DFU_RES_CODE_SUCCESS)
+ {
+ // Store CRC32 for image
+ s_dfu_settings.bank_1.image_crc = s_dfu_settings.progress.firmware_image_crc;
+ s_dfu_settings.bank_1.image_size = data_len;
+ }
+ else
+ {
+ nrf_dfu_bank_invalidate(&s_dfu_settings.bank_1);
+ }
+
+ // Set the progress to zero and remove the last command
+ memset(&s_dfu_settings.progress, 0, sizeof(dfu_progress_t));
+ memset(s_dfu_settings.init_command, 0xFF, DFU_SIGNED_COMMAND_SIZE);
+
+ s_dfu_settings.write_offset = 0;
+ s_dfu_settings.progress.update_start_address = src_addr;
+
+ return ret_val;
+}
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/dfu/nrf_dfu_validation.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/dfu/nrf_dfu_validation.h
new file mode 100644
index 0000000..d0de004
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/dfu/nrf_dfu_validation.h
@@ -0,0 +1,127 @@
+/**
+ * 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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
+ *
+ * @defgroup sdk_nrf_dfu_validation Validation
+ * @{
+ * @ingroup nrf_dfu
+ */
+
+#ifndef __NRF_DFU_VALIDATION_H
+#define __NRF_DFU_VALIDATION_H
+
+#include "stdint.h"
+#include "sdk_errors.h"
+#include "nrf_dfu_handling_error.h"
+
+/**
+ * @brief Function for module initialization.
+ *
+ * Function checks if there is a valid init packet in DFU settings written in flash.
+ */
+void nrf_dfu_validation_init(void);
+
+/**
+ * @brief Function called on reception of init command creation request.
+ *
+ * @param[in] size Size of incoming init packet.
+ *
+ * @return Operation result. See @ref nrf_dfu_result_t
+ */
+nrf_dfu_result_t nrf_dfu_validation_init_cmd_create(uint32_t size);
+
+/**
+ * @brief Function called on reception of fragment of init command.
+ *
+ * @param[in] p_data Init command fragment.
+ * @param[in] length Init command fragment size.
+ *
+ * @return Operation result. See @ref nrf_dfu_result_t
+ */
+nrf_dfu_result_t nrf_dfu_validation_init_cmd_append(uint8_t const * p_data, uint32_t length);
+
+/**
+ * @brief Function for getting init command status.
+ *
+ * @param[out] p_offset Current offset.
+ * @param[out] p_crc Current CRC.
+ * @param[out] p_max_size Maximum size of init command.
+ */
+void nrf_dfu_validation_init_cmd_status_get(uint32_t * p_offset,
+ uint32_t * p_crc,
+ uint32_t * p_max_size);
+
+/**
+ * @brief Function for inquiring whether a valid init command has been received.
+ *
+ * @return true if there is a valid init command. This can be true at boot time
+ * if the device was reset during a DFU operation.
+ */
+bool nrf_dfu_validation_init_cmd_present(void);
+
+/**
+ * @brief Function for validating init command.
+ *
+ * If init command is successfully validated Bank 1 details are written to out parameters.
+ *
+ * Until @ref nrf_dfu_validation_init_cmd_create is called, this function can be called
+ * again after the first time without side effects to retrieve address and length.
+ *
+ * @param[out] p_dst_data_addr Bank 1 start address if validation is successful.
+ * @param[out] p_data_len Bank 1 length if validation is successful.
+ *
+ * @return Operation result. See @ref nrf_dfu_result_t
+ */
+nrf_dfu_result_t nrf_dfu_validation_init_cmd_execute(uint32_t * p_dst_data_addr,
+ uint32_t * p_data_len);
+
+/**
+ * @brief Function for postvalidating the update. Function is called once all data is received.
+ *
+ * @param[in] dst_data_addr Bank 1 start address.
+ * @param[in] data_len Bank 1 length.
+ *
+ * @return Operation result. See @ref nrf_dfu_result_t
+ */
+nrf_dfu_result_t nrf_dfu_validation_post_data_execute(uint32_t dst_data_addr, uint32_t data_len);
+
+#endif //__NRF_DFU_VALIDATION_H
+
+/** @} */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/dfu/nrf_dfu_ver_validation.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/dfu/nrf_dfu_ver_validation.c
new file mode 100644
index 0000000..4958dd3
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/dfu/nrf_dfu_ver_validation.c
@@ -0,0 +1,241 @@
+/**
+ * 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#include <stdbool.h>
+#include "nrf_dfu_types.h"
+#include "nrf_dfu_settings.h"
+#include "nrf_dfu_utils.h"
+#include "nrf_bootloader_info.h"
+#include "nrf_crypto.h"
+#include "nrf_assert.h"
+#include "dfu-cc.pb.h"
+#include "nrf_dfu_ver_validation.h"
+
+#define NRF_LOG_MODULE_NAME nrf_dfu_ver_validation
+#include "nrf_log.h"
+NRF_LOG_MODULE_REGISTER();
+
+
+#ifndef NRF_DFU_DEBUG
+#ifdef NRF_DFU_DEBUG_VERSION
+#define NRF_DFU_DEBUG 1
+#else
+#define NRF_DFU_DEBUG 0
+#endif
+#endif
+
+/** @brief Macro for reading the Firmware ID of a SoftDevice at a given base address.
+ */
+#ifndef _SD_FWID_GET
+#define _SD_FWID_GET(baseaddr) SD_OFFSET_GET_UINT16(baseaddr, 0x0C)
+#endif
+
+#define EXT_ERR(err) (nrf_dfu_result_t)((uint32_t)NRF_DFU_RES_CODE_EXT_ERROR + (uint32_t)err)
+
+static bool sd_req_check(uint32_t const * p_sd_req, uint8_t sd_req_cnt)
+{
+ bool result = false;
+ for (uint8_t i = 0; i < sd_req_cnt; i++)
+ {
+ if (p_sd_req[i] == _SD_FWID_GET(MBR_SIZE))
+ {
+ // Found a matching sd_req field. sd_req is ok.
+ result = true;
+ break;
+ }
+ }
+ return result;
+}
+
+static bool sd_req_ok(dfu_init_command_t const * p_init)
+{
+ ASSERT(p_init != NULL);
+ bool result;
+#ifdef BLE_STACK_SUPPORT_REQD
+ // The bootloader needs the SoftDevice, so disabling NRF_DFU_APP_DOWNGRADE_PREVENTION
+ // should not be applied to SoftDevice updates.
+ const bool prevent_downgrade = NRF_DFU_APP_DOWNGRADE_PREVENTION || (p_init->type == DFU_FW_TYPE_SOFTDEVICE);
+#else
+ const bool prevent_downgrade = NRF_DFU_APP_DOWNGRADE_PREVENTION;
+#endif
+
+ if (SD_PRESENT)
+ {
+ if (p_init->sd_req_count && (p_init->sd_req[0] != SD_REQ_APP_OVERWRITES_SD))
+ {
+ result = sd_req_check(p_init->sd_req, p_init->sd_req_count);
+ }
+ else if (p_init->type == DFU_FW_TYPE_APPLICATION)
+ {
+ // The application wants to overwrite the SoftDevice.
+ if (prevent_downgrade && (p_init->sd_req_count > 1) && (p_init->sd_req[0] == SD_REQ_APP_OVERWRITES_SD))
+ {
+ // The application can overwrite the SD if sd_req[0] == 0 and table has the fwid of the current SD.
+ result = sd_req_check(p_init->sd_req, p_init->sd_req_count);
+ }
+ else
+ {
+ result = true;
+ }
+ }
+ else
+ {
+ // Don't allow SoftDevice updates which assume no SD is present already.
+ result = !prevent_downgrade || (p_init->type != DFU_FW_TYPE_SOFTDEVICE);
+ }
+ }
+ else
+ {
+ if (p_init->sd_req_count && (p_init->sd_req[0] != SD_REQ_APP_OVERWRITES_SD))
+ {
+ // Fail if there is no SD and the update requires SD.
+ result = false;
+ }
+ else
+ {
+ // If there is no SD and update has SD it is accepted only if it has a fw_version.
+ result = !prevent_downgrade || p_init->has_fw_version;
+ }
+ }
+ return result;
+}
+
+static bool fw_hash_type_ok(dfu_init_command_t const * p_init)
+{
+ ASSERT(p_init != NULL);
+
+ return (p_init->hash.hash_type == DFU_HASH_TYPE_SHA256);
+}
+
+static bool fw_version_required(dfu_fw_type_t new_fw_type)
+{
+ bool result = true;
+
+ if (new_fw_type == DFU_FW_TYPE_SOFTDEVICE)
+ {
+ result = false; // fw_version is optional in SoftDevice updates. If present, it will be checked against the app version.
+ }
+ else if (new_fw_type == DFU_FW_TYPE_APPLICATION)
+ {
+ result = NRF_DFU_APP_DOWNGRADE_PREVENTION; // fw_version is configurable in app updates.
+ }
+
+ return result;
+}
+
+
+static bool fw_type_ok(dfu_init_command_t const * p_init)
+{
+ ASSERT(p_init != NULL);
+
+ return ((p_init->has_type)
+ && ( (p_init->type == DFU_FW_TYPE_APPLICATION)
+ || (p_init->type == DFU_FW_TYPE_SOFTDEVICE)
+ || (p_init->type == DFU_FW_TYPE_BOOTLOADER)
+ || (p_init->type == DFU_FW_TYPE_SOFTDEVICE_BOOTLOADER)));
+}
+
+
+// This function assumes p_init->has_fw_version.
+static bool fw_version_ok(dfu_init_command_t const * p_init)
+{
+ ASSERT(p_init != NULL);
+ ASSERT(p_init->has_fw_version);
+
+ if ( (p_init->type == DFU_FW_TYPE_APPLICATION)
+ || (p_init->type == DFU_FW_TYPE_SOFTDEVICE))
+ {
+ return ((p_init->fw_version >= s_dfu_settings.app_version) || !NRF_DFU_APP_DOWNGRADE_PREVENTION);
+ }
+ else
+ {
+ return (p_init->fw_version > s_dfu_settings.bootloader_version);
+ }
+}
+
+nrf_dfu_result_t nrf_dfu_ver_validation_check(dfu_init_command_t const * p_init)
+{
+ nrf_dfu_result_t ret_val = NRF_DFU_RES_CODE_SUCCESS;
+ if (!fw_type_ok(p_init))
+ {
+ NRF_LOG_ERROR("Invalid firmware type.");
+ ret_val = EXT_ERR(NRF_DFU_EXT_ERROR_INIT_COMMAND_INVALID);
+ }
+ else if (!fw_hash_type_ok(p_init))
+ {
+ NRF_LOG_ERROR("Invalid hash type.");
+ ret_val = EXT_ERR(NRF_DFU_EXT_ERROR_WRONG_HASH_TYPE);
+ }
+ else if (!NRF_DFU_DEBUG ||
+ (NRF_DFU_DEBUG && ((p_init->has_is_debug == false) || (p_init->is_debug == false))))
+ {
+ if (p_init->has_hw_version == false)
+ {
+ NRF_LOG_ERROR("No HW version.");
+ ret_val = EXT_ERR(NRF_DFU_EXT_ERROR_INIT_COMMAND_INVALID);
+ }
+ else if (p_init->hw_version != NRF_DFU_HW_VERSION)
+ {
+ NRF_LOG_WARNING("Faulty HW version.");
+ ret_val = EXT_ERR( NRF_DFU_EXT_ERROR_HW_VERSION_FAILURE);
+ }
+ else if (!sd_req_ok(p_init))
+ {
+ NRF_LOG_WARNING("SD req not met.");
+ ret_val = EXT_ERR(NRF_DFU_EXT_ERROR_SD_VERSION_FAILURE);
+ }
+ else if (p_init->has_fw_version)
+ {
+ if (!fw_version_ok(p_init))
+ {
+ NRF_LOG_WARNING("FW version too low.");
+ ret_val = EXT_ERR(NRF_DFU_EXT_ERROR_FW_VERSION_FAILURE);
+ }
+ }
+ else
+ {
+ if (fw_version_required(p_init->type))
+ {
+ NRF_LOG_ERROR("FW version missing.");
+ ret_val = EXT_ERR(NRF_DFU_EXT_ERROR_INIT_COMMAND_INVALID);
+ }
+ }
+ }
+ return ret_val;
+}
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/dfu/nrf_dfu_ver_validation.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/dfu/nrf_dfu_ver_validation.h
new file mode 100644
index 0000000..5014b15
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/dfu/nrf_dfu_ver_validation.h
@@ -0,0 +1,58 @@
+/**
+ * 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#ifndef __NRF_DFU_VER_VALIDATION_H
+#define __NRF_DFU_VER_VALIDATION_H
+
+#include "stdint.h"
+#include "sdk_errors.h"
+#include "nrf_dfu_handling_error.h"
+#include "dfu-cc.pb.h"
+
+/** @brief SD_REQ field value which indicates that Softdevice can be overwritten by the application. */
+#define SD_REQ_APP_OVERWRITES_SD 0
+
+/**
+ * @brief Function for validating version of new firmware.
+ *
+ * @return NRF_DFU_RES_CODE_SUCCESS if successful or error code otherwise
+ */
+nrf_dfu_result_t nrf_dfu_ver_validation_check(dfu_init_command_t const * p_init);
+
+#endif //__NRF_DFU_VER_VALIDATION_H
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/nrf_bootloader.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/nrf_bootloader.c
new file mode 100644
index 0000000..3e62e47
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/nrf_bootloader.c
@@ -0,0 +1,394 @@
+/**
+ * Copyright (c) 2016 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#include "nrf_bootloader.h"
+
+#include "compiler_abstraction.h"
+#include "nrf.h"
+#include "boards.h"
+#include "sdk_config.h"
+#include "nrf_power.h"
+#include "nrf_delay.h"
+#include "nrf_log.h"
+#include "nrf_log_ctrl.h"
+#include "nrf_dfu.h"
+#include "nrf_error.h"
+#include "nrf_dfu_settings.h"
+#include "nrf_dfu_utils.h"
+#include "nrf_bootloader_wdt.h"
+#include "nrf_bootloader_info.h"
+#include "nrf_bootloader_app_start.h"
+#include "nrf_bootloader_fw_activation.h"
+#include "nrf_bootloader_dfu_timers.h"
+#include "app_scheduler.h"
+#include "app_timer.h"
+
+static nrf_dfu_observer_t m_user_observer; //<! Observer callback set by the user.
+
+#define SCHED_QUEUE_SIZE 32 /**< Maximum number of events in the scheduler queue. */
+#define SCHED_EVENT_DATA_SIZE MAX(NRF_DFU_SCHED_EVENT_DATA_SIZE, APP_TIMER_SCHED_EVENT_DATA_SIZE) /**< Maximum app_scheduler event size. */
+
+#if !(defined(NRF_BL_DFU_ENTER_METHOD_BUTTON) && \
+ defined(NRF_BL_DFU_ENTER_METHOD_PINRESET) && \
+ defined(NRF_BL_DFU_ENTER_METHOD_GPREGRET) && \
+ defined(NRF_BL_DFU_ENTER_METHOD_BUTTONLESS))
+ #error Configuration file is missing flags. Update sdk_config.h.
+#endif
+
+STATIC_ASSERT((NRF_BL_DFU_INACTIVITY_TIMEOUT_MS >= 100) || (NRF_BL_DFU_INACTIVITY_TIMEOUT_MS == 0),
+ "NRF_BL_DFU_INACTIVITY_TIMEOUT_MS must be 100 ms or more, or 0 to indicate that it is disabled.");
+
+#if defined(NRF_LOG_BACKEND_FLASH_START_PAGE)
+STATIC_ASSERT(NRF_LOG_BACKEND_FLASH_START_PAGE != 0,
+ "If nrf_log flash backend is used it cannot use space after code because it would collide with settings page.");
+#endif
+
+/**@brief Weak implemenation of nrf_dfu_init
+ *
+ * @note This function will be overridden if nrf_dfu.c is
+ * compiled and linked with the project
+ */
+ #if (__LINT__ != 1)
+__WEAK uint32_t nrf_dfu_init(nrf_dfu_observer_t observer)
+{
+ NRF_LOG_DEBUG("in weak nrf_dfu_init");
+ return NRF_SUCCESS;
+}
+#endif
+
+
+/**@brief Weak implementation of nrf_dfu_init
+ *
+ * @note This function must be overridden in application if
+ * user-specific initialization is needed.
+ */
+__WEAK uint32_t nrf_dfu_init_user(void)
+{
+ NRF_LOG_DEBUG("in weak nrf_dfu_init_user");
+ return NRF_SUCCESS;
+}
+
+
+static void bootloader_reset(void)
+{
+ NRF_LOG_DEBUG("Resetting bootloader.");
+
+ NRF_LOG_FINAL_FLUSH();
+
+#if NRF_MODULE_ENABLED(NRF_LOG_BACKEND_RTT)
+ // To allow the buffer to be flushed by the host.
+ nrf_delay_ms(100);
+#endif
+
+ NVIC_SystemReset();
+}
+
+
+static void inactivity_timeout(void)
+{
+ NRF_LOG_INFO("Inactivity timeout.");
+ bootloader_reset();
+}
+
+
+/**@brief Function for handling DFU events.
+ */
+static void dfu_observer(nrf_dfu_evt_type_t evt_type)
+{
+ switch (evt_type)
+ {
+ case NRF_DFU_EVT_DFU_STARTED:
+ case NRF_DFU_EVT_OBJECT_RECEIVED:
+ nrf_bootloader_dfu_inactivity_timer_restart(NRF_BL_DFU_INACTIVITY_TIMEOUT_MS, inactivity_timeout);
+ break;
+ case NRF_DFU_EVT_DFU_COMPLETED:
+ case NRF_DFU_EVT_DFU_ABORTED:
+ bootloader_reset();
+ break;
+ default:
+ break;
+ }
+
+ if (m_user_observer)
+ {
+ m_user_observer(evt_type);
+ }
+}
+
+
+/**@brief Function for initializing the event scheduler.
+ */
+static void scheduler_init(void)
+{
+ APP_SCHED_INIT(SCHED_EVENT_DATA_SIZE, SCHED_QUEUE_SIZE);
+}
+
+
+/**@brief Suspend the CPU until an interrupt occurs.
+ */
+static void wait_for_event(void)
+{
+#ifdef BLE_STACK_SUPPORT_REQD
+ (void)sd_app_evt_wait();
+#else
+ // Wait for an event.
+ __WFE();
+ // Clear the internal event register.
+ __SEV();
+ __WFE();
+#endif
+}
+
+
+/**@brief Continually sleep and process tasks whenever woken.
+ */
+static void loop_forever(void)
+{
+ while (true)
+ {
+ //feed the watchdog if enabled.
+ nrf_bootloader_wdt_feed();
+
+ app_sched_execute();
+
+ if (!NRF_LOG_PROCESS())
+ {
+ wait_for_event();
+ }
+ }
+}
+
+/**@brief Function for initializing button used to enter DFU mode.
+ */
+static void dfu_enter_button_init(void)
+{
+ nrf_gpio_cfg_sense_input(NRF_BL_DFU_ENTER_METHOD_BUTTON_PIN,
+ BUTTON_PULL,
+ NRF_GPIO_PIN_SENSE_LOW);
+}
+
+
+static bool crc_on_valid_app_required(void)
+{
+ bool ret = true;
+ if (NRF_BL_APP_CRC_CHECK_SKIPPED_ON_SYSTEMOFF_RESET &&
+ (nrf_power_resetreas_get() & NRF_POWER_RESETREAS_OFF_MASK))
+ {
+ nrf_power_resetreas_clear(NRF_POWER_RESETREAS_OFF_MASK);
+ ret = false;
+ }
+ else if (NRF_BL_APP_CRC_CHECK_SKIPPED_ON_GPREGRET2 &&
+ (nrf_power_gpregret2_get() & BOOTLOADER_DFU_SKIP_CRC))
+ {
+ nrf_power_gpregret2_set(nrf_power_gpregret2_get() & ~BOOTLOADER_DFU_SKIP_CRC);
+ ret = false;
+ }
+ else
+ {
+ }
+
+ return ret;
+}
+
+
+/**@brief Function for clearing all DFU enter flags that
+ * preserve state during reset.
+ *
+ * @details This is used to make sure that each of these flags
+ * is checked only once after reset.
+ */
+static void dfu_enter_flags_clear(void)
+{
+ if (NRF_BL_DFU_ENTER_METHOD_PINRESET &&
+ (NRF_POWER->RESETREAS & POWER_RESETREAS_RESETPIN_Msk))
+ {
+ // Clear RESETPIN flag.
+ NRF_POWER->RESETREAS |= POWER_RESETREAS_RESETPIN_Msk;
+ }
+
+ if (NRF_BL_DFU_ENTER_METHOD_GPREGRET &&
+ (nrf_power_gpregret_get() & BOOTLOADER_DFU_START))
+ {
+ // Clear DFU mark in GPREGRET register.
+ nrf_power_gpregret_set(nrf_power_gpregret_get() & ~BOOTLOADER_DFU_START);
+ }
+
+ if (NRF_BL_DFU_ENTER_METHOD_BUTTONLESS &&
+ (s_dfu_settings.enter_buttonless_dfu == 1))
+ {
+ // Clear DFU flag in flash settings.
+ s_dfu_settings.enter_buttonless_dfu = 0;
+ APP_ERROR_CHECK(nrf_dfu_settings_write(NULL));
+ }
+}
+
+
+/**@brief Function for checking whether to enter DFU mode or not.
+ */
+static bool dfu_enter_check(void)
+{
+ if (!nrf_dfu_app_is_valid(crc_on_valid_app_required()))
+ {
+ NRF_LOG_DEBUG("DFU mode because app is not valid.");
+ return true;
+ }
+
+ if (NRF_BL_DFU_ENTER_METHOD_BUTTON &&
+ (nrf_gpio_pin_read(NRF_BL_DFU_ENTER_METHOD_BUTTON_PIN) == 0))
+ {
+ NRF_LOG_DEBUG("DFU mode requested via button.");
+ return true;
+ }
+
+ if (NRF_BL_DFU_ENTER_METHOD_PINRESET &&
+ (NRF_POWER->RESETREAS & POWER_RESETREAS_RESETPIN_Msk))
+ {
+ NRF_LOG_DEBUG("DFU mode requested via pin-reset.");
+ return true;
+ }
+
+ if (NRF_BL_DFU_ENTER_METHOD_GPREGRET &&
+ (nrf_power_gpregret_get() & BOOTLOADER_DFU_START))
+ {
+ NRF_LOG_DEBUG("DFU mode requested via GPREGRET.");
+ return true;
+ }
+
+ if (NRF_BL_DFU_ENTER_METHOD_BUTTONLESS &&
+ (s_dfu_settings.enter_buttonless_dfu == 1))
+ {
+ NRF_LOG_DEBUG("DFU mode requested via bootloader settings.");
+ return true;
+ }
+
+ return false;
+}
+
+
+ret_code_t nrf_bootloader_init(nrf_dfu_observer_t observer)
+{
+ NRF_LOG_DEBUG("In nrf_bootloader_init");
+
+ uint32_t ret_val;
+ nrf_bootloader_fw_activation_result_t activation_result;
+ uint32_t initial_timeout;
+ bool dfu_enter = false;
+
+ m_user_observer = observer;
+
+ if (NRF_BL_DFU_ENTER_METHOD_BUTTON)
+ {
+ dfu_enter_button_init();
+ }
+
+ ret_val = nrf_dfu_settings_init(false);
+ if (ret_val != NRF_SUCCESS)
+ {
+ return NRF_ERROR_INTERNAL;
+ }
+
+ // Check if an update needs to be activated and activate it.
+ activation_result = nrf_bootloader_fw_activate();
+
+ switch (activation_result)
+ {
+ case ACTIVATION_NONE:
+ initial_timeout = NRF_BL_DFU_INACTIVITY_TIMEOUT_MS;
+ dfu_enter = dfu_enter_check();
+ break;
+
+ case ACTIVATION_SUCCESS_EXPECT_ADDITIONAL_UPDATE:
+ initial_timeout = NRF_BL_DFU_CONTINUATION_TIMEOUT_MS;
+ dfu_enter = true;
+ break;
+
+ case ACTIVATION_SUCCESS:
+ bootloader_reset();
+ NRF_LOG_ERROR("Should never come here: After bootloader_reset()");
+ return NRF_ERROR_INTERNAL; // Should not reach this.
+
+ case ACTIVATION_ERROR:
+ default:
+ return NRF_ERROR_INTERNAL;
+ }
+
+ if (dfu_enter)
+ {
+ nrf_bootloader_wdt_init();
+
+ scheduler_init();
+
+ // Clear all DFU stop flags.
+ dfu_enter_flags_clear();
+
+ // Call user-defined init function if implemented
+ ret_val = nrf_dfu_init_user();
+ if (ret_val != NRF_SUCCESS)
+ {
+ return NRF_ERROR_INTERNAL;
+ }
+
+ nrf_bootloader_dfu_inactivity_timer_restart(initial_timeout, inactivity_timeout);
+
+ ret_val = nrf_dfu_init(dfu_observer);
+ if (ret_val != NRF_SUCCESS)
+ {
+ return NRF_ERROR_INTERNAL;
+ }
+
+ NRF_LOG_DEBUG("Enter main loop");
+ loop_forever(); // This function will never return.
+ NRF_LOG_ERROR("Should never come here: After looping forever.");
+ }
+ else
+ {
+ // Erase additional data like peer data or advertisement name
+ ret_val = nrf_dfu_settings_additional_erase();
+ if (ret_val != NRF_SUCCESS)
+ {
+ return NRF_ERROR_INTERNAL;
+ }
+
+ nrf_bootloader_app_start();
+ NRF_LOG_ERROR("Should never come here: After nrf_bootloader_app_start()");
+ }
+
+ // Should not be reached.
+ return NRF_ERROR_INTERNAL;
+}
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/nrf_bootloader.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/nrf_bootloader.h
new file mode 100644
index 0000000..d588b02
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/nrf_bootloader.h
@@ -0,0 +1,79 @@
+/**
+ * Copyright (c) 2016 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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
+ *
+ *
+ * @defgroup nrf_bootloader Bootloader modules
+ * @{
+ * @ingroup app_common
+ * @brief Bootloader and DFU modules
+ *
+ * The bootloader module can be used to implement a basic bootloader that
+ * can be extended with, for example, Device Firmware Update (DFU) support
+ * or custom functionality.
+ */
+
+#ifndef NRF_BOOTLOADER_H__
+#define NRF_BOOTLOADER_H__
+
+#include <stdint.h>
+#include "nrf_dfu.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** @brief Function for initializing the bootloader.
+ *
+ * @details This function is the entry point of all bootloader operations.
+ * If DFU functionality is compiled in, the DFU process is initialized
+ * when running this function.
+ *
+ * @note This function does not return unless an error occurred.
+ *
+ * @retval NRF_ERROR_INTERNAL Something went wrong.
+ */
+ret_code_t nrf_bootloader_init(nrf_dfu_observer_t observer);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // NRF_BOOTLOADER_H__
+/** @} */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/nrf_bootloader_app_start.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/nrf_bootloader_app_start.c
new file mode 100644
index 0000000..b12cda0
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/nrf_bootloader_app_start.c
@@ -0,0 +1,77 @@
+/**
+ * Copyright (c) 2016 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#include <stdint.h>
+#include "nrf.h"
+#include "nrf_bootloader_app_start.h"
+#include "nrf_bootloader_info.h"
+#include "nrf_log.h"
+#include "nrf_dfu_mbr.h"
+#include "nrf_log_ctrl.h"
+#include "nrf_bootloader_info.h"
+
+// Do the final stages of app_start. Protect flash and run app. See nrf_bootloader_app_start_final.c
+void nrf_bootloader_app_start_final(uint32_t start_addr);
+
+void nrf_bootloader_app_start(void)
+{
+ uint32_t start_addr = MBR_SIZE; // Always boot from end of MBR. If a SoftDevice is present, it will boot the app.
+ NRF_LOG_DEBUG("Running nrf_bootloader_app_start with address: 0x%08x", start_addr);
+ uint32_t err_code;
+
+ // Disable and clear interrupts
+ // Notice that this disables only 'external' interrupts (positive IRQn).
+ NRF_LOG_DEBUG("Disabling interrupts. NVIC->ICER[0]: 0x%x", NVIC->ICER[0]);
+
+ NVIC->ICER[0]=0xFFFFFFFF;
+ NVIC->ICPR[0]=0xFFFFFFFF;
+#if defined(__NRF_NVIC_ISER_COUNT) && __NRF_NVIC_ISER_COUNT == 2
+ NVIC->ICER[1]=0xFFFFFFFF;
+ NVIC->ICPR[1]=0xFFFFFFFF;
+#endif
+
+ err_code = nrf_dfu_mbr_irq_forward_address_set();
+ if (err_code != NRF_SUCCESS)
+ {
+ NRF_LOG_ERROR("Failed running nrf_dfu_mbr_irq_forward_address_set()");
+ }
+
+ NRF_LOG_FLUSH();
+ nrf_bootloader_app_start_final(start_addr);
+}
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/nrf_bootloader_app_start.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/nrf_bootloader_app_start.h
new file mode 100644
index 0000000..0bce18d
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/nrf_bootloader_app_start.h
@@ -0,0 +1,92 @@
+/**
+ * Copyright (c) 2016 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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
+ *
+ * @defgroup nrf_bootloader_app Application start
+ * @{
+ * @ingroup nrf_bootloader
+ */
+
+#ifndef NRF_BOOTLOADER_APP_START_H__
+#define NRF_BOOTLOADER_APP_START_H__
+
+#include <stdint.h>
+#include <stdbool.h>
+#include "sdk_errors.h"
+
+
+/**@brief Function for using hardware to protect flash from writing and reading.
+ *
+ * @details This function will apply write/erase protection to a specific area. Read
+ * protection is optional, decided by \p read_protect. This function uses
+ * the BPROT or ACL peripheral, depending on which is available.
+ *
+ * @param[in] address The start address of the area to protect. Must be a flash page
+ * boundary.
+ * @param[in] size The size of the area to protect, in bytes. Must be a multiple
+ * of flash page size.
+ * @param[in] read_protect Whether to protect the area from reading/executing as well.
+ * This is not available on chips with the BPROT peripheral
+ * (e.g. nrf52832, nrf52810).
+ *
+ * @retval NRF_SUCCESS Flash protection applied successfully.
+ * @retval NRF_ERROR_NO_MEM No more ACL instances to use for flash protection.
+ * @retval NRF_ERROR_INVALID_PARAM Address was out of range or size was not a multiple
+ * of flash page size.
+ */
+ret_code_t nrf_bootloader_flash_protect(uint32_t address, uint32_t size, bool read_protect);
+
+/**@brief Function for starting another application (and aborting the current one).
+ *
+ * @details This function uses the provided address to swap the stack pointer and then load
+ * the address of the reset handler to be executed. It checks the current system mode
+ * (thread/handler). If in thread mode, it resets into the other application.
+ * If in handler mode, isr_abort is executed to ensure that handler mode is left correctly.
+ * It then jumps into the reset handler of the other application.
+ *
+ * @note This function assumes the SoftDevice has not previously been initialized.
+ *
+ * @note This function will never return, but issues a reset into the provided application.
+ */
+void nrf_bootloader_app_start(void);
+
+#endif // NRF_BOOTLOADER_APP_START_H__
+
+/** @} */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/nrf_bootloader_app_start_final.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/nrf_bootloader_app_start_final.c
new file mode 100644
index 0000000..a818322
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/nrf_bootloader_app_start_final.c
@@ -0,0 +1,256 @@
+/**
+ * Copyright (c) 2016 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#include "sdk_config.h"
+#include "nrf_bootloader_app_start.h"
+#include <stdint.h>
+#include "nrf.h"
+#include "nrf_peripherals.h"
+#include "nrf_bootloader_info.h"
+#include "nrf_dfu_types.h"
+#include "nrf_assert.h"
+#include "nrf_log.h"
+#include "sdk_config.h"
+
+
+// Enabling the NRF_BOOTLOADER_READ_PROTECT define is untested.
+// Read-protecting the bootloader requires certain functions to run from RAM.
+// In GCC and SES this is done automatically when the define is enabled. You will
+// get warnings which can be ignored.
+// In Keil you must change project settings to run the entire file from RAM.
+#ifndef NRF_BOOTLOADER_READ_PROTECT
+#define NRF_BOOTLOADER_READ_PROTECT 0
+#endif
+
+
+#define HANDLER_MODE_EXIT 0xFFFFFFF9 // When this is jumped to, the CPU will exit interrupt context
+ // (handler mode), and pop values from the stack into registers.
+ // See ARM's documentation for "Exception entry and return".
+#define EXCEPTION_STACK_WORD_COUNT 8 // The number of words popped from the stack when
+ // HANDLER_MODE_EXIT is branched to.
+
+
+/**@brief Function that sets the stack pointer and link register, and starts executing a particular address.
+ *
+ * @param[in] new_msp The new value to set in the main stack pointer.
+ * @param[in] new_lr The new value to set in the link register.
+ * @param[in] addr The address to execute.
+ */
+#if defined ( __CC_ARM )
+__ASM __STATIC_INLINE void jump_to_addr(uint32_t new_msp, uint32_t new_lr, uint32_t addr)
+{
+ MSR MSP, R0;
+ MOV LR, R1;
+ BX R2;
+}
+#else
+__STATIC_INLINE void jump_to_addr(uint32_t new_msp, uint32_t new_lr, uint32_t addr)
+{
+ __ASM volatile ("MSR MSP, %[arg]" : : [arg] "r" (new_msp));
+ __ASM volatile ("MOV LR, %[arg]" : : [arg] "r" (new_lr) : "lr");
+ __ASM volatile ("BX %[arg]" : : [arg] "r" (addr));
+}
+#endif
+
+
+/**@brief Function for booting an app as if the chip was reset.
+ *
+ * @param[in] vector_table_addr The address of the app's vector table.
+ */
+__STATIC_INLINE void app_start(uint32_t vector_table_addr)
+{
+ const uint32_t current_isr_num = (__get_IPSR() & IPSR_ISR_Msk);
+ const uint32_t new_msp = *((uint32_t *)(vector_table_addr)); // The app's Stack Pointer is found as the first word of the vector table.
+ const uint32_t reset_handler = *((uint32_t *)(vector_table_addr + sizeof(uint32_t))); // The app's Reset Handler is found as the second word of the vector table.
+ const uint32_t new_lr = 0xFFFFFFFF;
+
+ __set_CONTROL(0x00000000); // Set CONTROL to its reset value 0.
+ __set_PRIMASK(0x00000000); // Set PRIMASK to its reset value 0.
+ __set_BASEPRI(0x00000000); // Set BASEPRI to its reset value 0.
+ __set_FAULTMASK(0x00000000); // Set FAULTMASK to its reset value 0.
+
+ if (current_isr_num == 0)
+ {
+ // The CPU is in Thread mode (main context).
+ jump_to_addr(new_msp, new_lr, reset_handler); // Jump directly to the App's Reset Handler.
+ }
+ else
+ {
+ // The CPU is in Handler mode (interrupt context).
+
+ const uint32_t exception_stack[EXCEPTION_STACK_WORD_COUNT] = // To be copied onto the stack.
+ {
+ 0x00000000, // New value of R0. Cleared by setting to 0.
+ 0x00000000, // New value of R1. Cleared by setting to 0.
+ 0x00000000, // New value of R2. Cleared by setting to 0.
+ 0x00000000, // New value of R3. Cleared by setting to 0.
+ 0x00000000, // New value of R12. Cleared by setting to 0.
+ 0xFFFFFFFF, // New value of LR. Cleared by setting to all 1s.
+ reset_handler, // New value of PC. The CPU will continue by executing the App's Reset Handler.
+ xPSR_T_Msk, // New value of xPSR (Thumb mode set).
+ };
+ const uint32_t exception_sp = new_msp - sizeof(exception_stack);
+
+ memcpy((uint32_t *)exception_sp, exception_stack, sizeof(exception_stack)); // 'Push' exception_stack onto the App's stack.
+
+ jump_to_addr(exception_sp, new_lr, HANDLER_MODE_EXIT); // 'Jump' to the special value to exit handler mode. new_lr is superfluous here.
+ // exception_stack will be popped from the stack, so the resulting SP will be the new_msp.
+ // Execution will continue from the App's Reset Handler.
+ }
+}
+
+#if NRF_BOOTLOADER_READ_PROTECT
+#ifdef __ICCARM__
+__ramfunc
+#elif defined ( __GNUC__ ) || defined ( __SES_ARM )
+__attribute__((noinline, long_call, section(".data")))
+#elif defined ( __CC_ARM )
+#warning "Keil requires changes to project settings to run this file from RAM. Ignore this warning if configuration has been made."
+#endif
+#endif
+ret_code_t nrf_bootloader_flash_protect(uint32_t address, uint32_t size, bool read_protect)
+{
+ if ((size & (CODE_PAGE_SIZE - 1)) || (address > BOOTLOADER_SETTINGS_ADDRESS))
+ {
+ return NRF_ERROR_INVALID_PARAM;
+ }
+
+#if defined(ACL_PRESENT)
+
+ // Protect using ACL.
+ static uint32_t acl_instance = 0;
+
+ uint32_t const wmask = (ACL_ACL_PERM_WRITE_Disable << ACL_ACL_PERM_WRITE_Pos);
+ uint32_t const rwmask = wmask | (ACL_ACL_PERM_READ_Disable << ACL_ACL_PERM_READ_Pos);
+ uint32_t const mask = read_protect ? rwmask: wmask;
+
+ do
+ {
+ if (acl_instance >= ACL_REGIONS_COUNT)
+ {
+ return NRF_ERROR_NO_MEM;
+ }
+
+ NRF_ACL->ACL[acl_instance].ADDR = address;
+ NRF_ACL->ACL[acl_instance].SIZE = size;
+ NRF_ACL->ACL[acl_instance].PERM = mask;
+
+ acl_instance++;
+
+ } while (NRF_ACL->ACL[acl_instance - 1].ADDR != address
+ || NRF_ACL->ACL[acl_instance - 1].SIZE != size
+ || NRF_ACL->ACL[acl_instance - 1].PERM != mask); // Check whether the acl_instance has been used before.
+
+#elif defined (BPROT_PRESENT)
+
+ // Protect using BPROT. BPROT does not support read protection.
+ uint32_t pagenum_start = address / CODE_PAGE_SIZE;
+ uint32_t pagenum_end = pagenum_start + ((size - 1) / CODE_PAGE_SIZE);
+
+ for (uint32_t i = pagenum_start; i <= pagenum_end; i++)
+ {
+ uint32_t config_index = i / 32;
+ uint32_t mask = (1 << (i - config_index * 32));
+
+ switch (config_index)
+ {
+ case 0:
+ NRF_BPROT->CONFIG0 = mask;
+ break;
+ case 1:
+ NRF_BPROT->CONFIG1 = mask;
+ break;
+ case 2:
+ NRF_BPROT->CONFIG2 = mask;
+ break;
+ case 3:
+ NRF_BPROT->CONFIG3 = mask;
+ break;
+ }
+ }
+
+#endif
+
+ return NRF_SUCCESS;
+}
+
+
+#if NRF_BOOTLOADER_READ_PROTECT
+#ifdef __ICCARM__
+__ramfunc
+#elif defined ( __GNUC__ ) || defined ( __SES_ARM )
+__attribute__((noinline, long_call, section(".data")))
+#elif defined ( __CC_ARM )
+#warning "Keil requires changes to project settings to run this file from RAM. Ignore this warning if configuration has been made."
+#endif
+#endif
+void nrf_bootloader_app_start_final(uint32_t vector_table_addr)
+{
+ ret_code_t ret_val;
+
+ // Protect MBR & bootloader code and params pages.
+ if (NRF_BOOTLOADER_READ_PROTECT)
+ {
+ ret_val = nrf_bootloader_flash_protect(0, MBR_SIZE, NRF_BOOTLOADER_READ_PROTECT);
+ }
+
+ // Size of the flash area to protect.
+ uint32_t area_size;
+
+ if (!NRF_BL_SETTINGS_PAGE_PROTECT)
+ {
+ area_size = BOOTLOADER_SIZE + NRF_MBR_PARAMS_PAGE_SIZE;
+ }
+ else
+ {
+ area_size = BOOTLOADER_SIZE + NRF_MBR_PARAMS_PAGE_SIZE + BOOTLOADER_SETTINGS_PAGE_SIZE;
+ }
+
+ ret_val = nrf_bootloader_flash_protect(BOOTLOADER_START_ADDR,
+ area_size,
+ NRF_BOOTLOADER_READ_PROTECT);
+
+ if (!NRF_BOOTLOADER_READ_PROTECT && (ret_val != NRF_SUCCESS))
+ {
+ NRF_LOG_ERROR("Could not protect bootloader and settings pages, 0x%x.", ret_val);
+ }
+
+ // Run application
+ app_start(vector_table_addr);
+}
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/nrf_bootloader_dfu_timers.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/nrf_bootloader_dfu_timers.c
new file mode 100644
index 0000000..a6b056e
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/nrf_bootloader_dfu_timers.c
@@ -0,0 +1,126 @@
+/**
+ * Copyright (c) 2018 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#include "nrf_bootloader_dfu_timers.h"
+
+#include "app_timer.h"
+#include "nrf_clock.h"
+
+APP_TIMER_DEF(m_dfu_inactivity_timer); //!< Timer for aborting DFU if no update happens.
+APP_TIMER_DEF(m_wdt_feed_timer); //!< Timer for feeding the application's watchdog (WDT) while the bootloader is running.
+
+static bool m_app_timer_initialized;
+
+/** @brief Function for handling the timeouts by calling the callback in the context.
+ */
+static void timeout_handler(void * p_context)
+{
+ if (p_context)
+ {
+ //lint -save -e611 "Suspicious cast"
+ ((nrf_bootloader_dfu_timeout_callback_t)p_context)();
+ //lint -restore
+ }
+}
+
+
+/**@brief Initialization of app_timer. Function ensures that initialization happens only once.
+ */
+static void timer_init(void)
+{
+ if (!m_app_timer_initialized)
+ {
+ if (!nrf_clock_lf_is_running())
+ {
+ nrf_clock_task_trigger(NRF_CLOCK_TASK_LFCLKSTART);
+
+ // Wait for the clock to be ready.
+ while (!nrf_clock_lf_is_running()) {;}
+ }
+
+ uint32_t err_code = app_timer_init();
+ APP_ERROR_CHECK(err_code);
+
+ // Start a single shot timer that will reset the DFU on timeout.
+ err_code = app_timer_create(&m_dfu_inactivity_timer,
+ APP_TIMER_MODE_SINGLE_SHOT,
+ timeout_handler);
+ ASSERT(err_code == NRF_SUCCESS);
+
+ err_code = app_timer_create(&m_wdt_feed_timer,
+ APP_TIMER_MODE_REPEATED,
+ timeout_handler);
+ ASSERT(err_code == NRF_SUCCESS);
+
+ m_app_timer_initialized = true;
+ }
+}
+
+
+/**@brief Function for initializing app_timer if necessary, and (re)starting a timer.
+ */
+static void timer_start(app_timer_t * p_timer, uint32_t timeout_ms, nrf_bootloader_dfu_timeout_callback_t callback)
+{
+ ret_code_t err_code;
+
+ timer_init();
+
+ err_code = app_timer_stop(p_timer);
+ ASSERT(err_code == NRF_SUCCESS);
+
+ if (timeout_ms != 0)
+ {
+ //lint -save -e611 "Suspicious cast"
+ err_code = app_timer_start(p_timer, APP_TIMER_TICKS(timeout_ms), (void *)callback);
+ //lint -restore
+ ASSERT(err_code == NRF_SUCCESS);
+ }
+}
+
+
+void nrf_bootloader_dfu_inactivity_timer_restart(uint32_t timeout_ms, nrf_bootloader_dfu_timeout_callback_t callback)
+{
+ timer_start(m_dfu_inactivity_timer, timeout_ms, callback);
+}
+
+
+void nrf_bootloader_wdt_feed_timer_start(uint32_t timeout_ms, nrf_bootloader_dfu_timeout_callback_t callback)
+{
+ timer_start(m_wdt_feed_timer, timeout_ms, callback);
+}
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/nrf_bootloader_dfu_timers.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/nrf_bootloader_dfu_timers.h
new file mode 100644
index 0000000..5104dfd
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/nrf_bootloader_dfu_timers.h
@@ -0,0 +1,87 @@
+/**
+ * Copyright (c) 2018 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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
+ *
+ * @defgroup nrf_bootloader_dfu_timers Timers for DFU in the bootloader
+ * @{
+ * @ingroup nrf_bootloader
+ */
+
+#ifndef NRF_BOOTLOADER_DFU_TIMERS_H__
+#define NRF_BOOTLOADER_DFU_TIMERS_H__
+
+#include <stdint.h>
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+/**@brief Handler called on timeout of a timer requested by the watchdog.
+ */
+typedef void (*nrf_bootloader_dfu_timeout_callback_t)(void);
+
+
+/**@brief Function for restarting the inactivity timer.
+ *
+ * @note Calling this function cancels any previous calls to this function.
+ *
+ * @param[in] timeout_ms The number of milliseconds until reset if not restarted.
+ * If 0 is passed, the timer will be stopped and not restarted.
+ * @param[in] callback Function to be called on timeout.
+ */
+void nrf_bootloader_dfu_inactivity_timer_restart(uint32_t timeout_ms, nrf_bootloader_dfu_timeout_callback_t callback);
+
+
+/**@brief Function for initializing and starting a repeated timer for feeding the watchdog.
+ *
+ * @param[in] timeout_ms Timer period.
+ * @param[in] callback Function called on every timeout.
+ */
+void nrf_bootloader_wdt_feed_timer_start(uint32_t timeout_ms, nrf_bootloader_dfu_timeout_callback_t callback);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // NRF_BOOTLOADER_DFU_TIMERS_H__
+
+/** @} */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/nrf_bootloader_fw_activation.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/nrf_bootloader_fw_activation.c
new file mode 100644
index 0000000..40e4870
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/nrf_bootloader_fw_activation.c
@@ -0,0 +1,436 @@
+/**
+ * Copyright (c) 2016 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+
+#include "nrf_bootloader_fw_activation.h"
+#include "nrf_dfu_settings.h"
+#include "nrf_dfu_mbr.h"
+#include "nrf_bootloader_info.h"
+#include "crc32.h"
+#include "nrf_log.h"
+#include "nrf_log_ctrl.h"
+#include "nrf_dfu_utils.h"
+#include "nrf_bootloader_wdt.h"
+
+
+static volatile bool m_flash_write_done;
+
+
+/**
+ * @brief Function for copying image. Image is copied in chunks. Frequency of storing progress
+ * in flash is configured by input parameter.
+ *
+ * @param[in] dst_addr Destination address. Must be page aligned.
+ * @param[in] src_addr Source address. Must be higher value than dst_addr.
+ * @param[in] size Image size.
+ * @param[in] progress_update_step Number of copied pages that triggers saving progress to non-volatile memory.
+ * Note that step can be decreased if there is a risk of corruption caused by source
+ * and destination overlapping.
+ *
+ * @return NRF_SUCCESS or error code in case of failure.
+ */
+static uint32_t image_copy(uint32_t dst_addr,
+ uint32_t src_addr,
+ uint32_t size,
+ uint32_t progress_update_step)
+{
+ if (src_addr == dst_addr)
+ {
+ NRF_LOG_DEBUG("No copy needed src_addr: 0x%x, dst_addr: 0x%x", src_addr, dst_addr);
+ return NRF_SUCCESS;
+ }
+
+ ASSERT(src_addr >= dst_addr);
+ ASSERT(progress_update_step > 0);
+ ASSERT((dst_addr % CODE_PAGE_SIZE) == 0);
+
+ uint32_t max_safe_progress_upd_step = (src_addr - dst_addr)/CODE_PAGE_SIZE;
+ ASSERT(max_safe_progress_upd_step > 0);
+
+ uint32_t ret_val = NRF_SUCCESS;
+ uint32_t pages_left = CEIL_DIV(size, CODE_PAGE_SIZE);
+
+ //Firmware copying is time consuming operation thus watchdog handling is started
+ nrf_bootloader_wdt_init();
+
+ progress_update_step = MIN(progress_update_step, max_safe_progress_upd_step);
+
+ while (size > 0)
+ {
+ uint32_t pages;
+ uint32_t bytes;
+ if (pages_left <= progress_update_step)
+ {
+ pages = pages_left;
+ bytes = size;
+ }
+ else
+ {
+ pages = progress_update_step;
+ bytes = progress_update_step * CODE_PAGE_SIZE;
+ }
+ // Erase the target pages
+ ret_val = nrf_dfu_flash_erase(dst_addr, pages, NULL);
+ if (ret_val != NRF_SUCCESS)
+ {
+ return ret_val;
+ }
+
+ // Flash one page
+ NRF_LOG_DEBUG("Copying 0x%x to 0x%x, size: 0x%x", src_addr, dst_addr, bytes);
+ ret_val = nrf_dfu_flash_store(dst_addr,
+ (uint32_t *)src_addr,
+ ALIGN_NUM(sizeof(uint32_t), bytes),
+ NULL);
+ if (ret_val != NRF_SUCCESS)
+ {
+ return ret_val;
+ }
+
+ pages_left -= pages;
+ size -= bytes;
+ dst_addr += bytes;
+ src_addr += bytes;
+ s_dfu_settings.write_offset += bytes;
+
+ //store progress in flash on every successful chunk write
+ ret_val = nrf_dfu_settings_write(NULL);
+ if (ret_val != NRF_SUCCESS)
+ {
+ NRF_LOG_ERROR("Failed to write image copying progress to settings page.");
+ return ret_val;
+ }
+ }
+
+ return ret_val;
+}
+
+/** @brief Function to continue application update.
+ *
+ * @details This function will be called after reset if there is a valid application in Bank1
+ * required to be copied down to Bank 0.
+ *
+ * @return NRF_SUCCESS if continuation was successful, NRF_ERROR_INTERNAL if new firmware does not
+ * contain softdevice or other error coming from modules used by this function.
+ */
+static uint32_t app_activate(void)
+{
+ // This function is only in use when new app is present in Bank 1
+ uint32_t const image_size = s_dfu_settings.bank_1.image_size;
+
+ uint32_t src_addr = s_dfu_settings.progress.update_start_address;
+ uint32_t ret_val = NRF_SUCCESS;
+ uint32_t target_addr = nrf_dfu_bank0_start_addr() + s_dfu_settings.write_offset;
+ uint32_t length_left = (image_size - s_dfu_settings.write_offset);
+ uint32_t crc;
+
+ NRF_LOG_DEBUG("Enter nrf_dfu_app_continue");
+
+ src_addr += s_dfu_settings.write_offset;
+
+ if (src_addr == target_addr)
+ {
+ length_left = 0;
+ }
+
+ ret_val = image_copy(target_addr, src_addr, length_left, NRF_BL_FW_COPY_PROGRESS_STORE_STEP);
+ if (ret_val != NRF_SUCCESS)
+ {
+ NRF_LOG_ERROR("Failed to copy firmware.");
+ return ret_val;
+ }
+
+ // Check the CRC of the copied data. Enable if so.
+ crc = crc32_compute((uint8_t*)nrf_dfu_bank0_start_addr(), image_size, NULL);
+
+ if (crc == s_dfu_settings.bank_1.image_crc)
+ {
+ NRF_LOG_DEBUG("Setting app as valid");
+ s_dfu_settings.bank_0.bank_code = NRF_DFU_BANK_VALID_APP;
+ s_dfu_settings.bank_0.image_crc = crc;
+ s_dfu_settings.bank_0.image_size = image_size;
+ }
+ else
+ {
+ NRF_LOG_ERROR("CRC computation failed for copied app: "
+ "src crc: 0x%08x, res crc: 0x%08x",
+ s_dfu_settings.bank_1.image_crc,
+ crc);
+ }
+
+ return ret_val;
+}
+
+
+/** @brief Function to execute the continuation of a SoftDevice update.
+ *
+ * @return NRF_SUCCESS if continuation was successful, NRF_ERROR_INTERNAL if new firmware does not
+ * contain softdevice or other error coming from modules used by this function.
+ */
+static uint32_t sd_activate(void)
+{
+ uint32_t ret_val = NRF_SUCCESS;
+ uint32_t target_addr = nrf_dfu_softdevice_start_address() + s_dfu_settings.write_offset;
+ uint32_t src_addr = s_dfu_settings.progress.update_start_address;
+ uint32_t sd_size = s_dfu_settings.sd_size;
+ uint32_t length_left = ALIGN_TO_PAGE(sd_size - s_dfu_settings.write_offset);
+
+ NRF_LOG_DEBUG("Enter nrf_bootloader_dfu_sd_continue");
+
+ if (SD_MAGIC_NUMBER_GET(src_addr) != SD_MAGIC_NUMBER)
+ {
+ NRF_LOG_ERROR("Source address does not contain a valid SoftDevice.")
+ return NRF_ERROR_INTERNAL;
+ }
+
+ // This can be a continuation due to a power failure
+ src_addr += s_dfu_settings.write_offset;
+
+ if (s_dfu_settings.write_offset == sd_size)
+ {
+ NRF_LOG_DEBUG("SD already copied");
+ return NRF_SUCCESS;
+ }
+
+ if (s_dfu_settings.write_offset == 0)
+ {
+ NRF_LOG_DEBUG("Updating SD. Old SD ver: %d, New ver: %d",
+ SD_VERSION_GET(MBR_SIZE) / 1000000, SD_VERSION_GET(src_addr) / 1000000);
+ }
+
+ ret_val = image_copy(target_addr, src_addr, length_left, NRF_BL_FW_COPY_PROGRESS_STORE_STEP);
+ if (ret_val != NRF_SUCCESS)
+ {
+ NRF_LOG_ERROR("Failed to copy firmware.");
+ return ret_val;
+ }
+
+ ret_val = nrf_dfu_settings_write(NULL);
+
+ return ret_val;
+}
+
+
+/** @brief Function to continue bootloader update.
+ *
+ * @details This function will be called after reset if there is a valid bootloader in Bank 0 or Bank 1
+ * required to be relocated and activated through MBR commands.
+ *
+ * @return This function will not return if the bootloader is copied successfully.
+ * After the copy is verified, the device will reset and start the new bootloader.
+ *
+ * @retval NRF_SUCCESS Continuation was successful.
+ * @retval NRF_ERROR_INVALID_LENGTH Invalid length of flash operation.
+ * @retval NRF_ERROR_NO_MEM If no parameter page is provided (see sds for more info).
+ * @retval NRF_ERROR_INVALID_PARAM If an invalid command is given.
+ * @retval NRF_ERROR_INTERNAL Internal error that should not happen.
+ * @retval NRF_ERROR_FORBIDDEN If NRF_UICR->BOOTADDR is not set.
+ */
+static uint32_t bl_activate(void)
+{
+ uint32_t ret_val = NRF_ERROR_INVALID_DATA;
+ nrf_dfu_bank_t * p_bank = &s_dfu_settings.bank_1;
+ uint32_t len = p_bank->image_size;
+ uint32_t src_addr = s_dfu_settings.progress.update_start_address;
+
+ if (p_bank->bank_code == NRF_DFU_BANK_VALID_SD_BL)
+ {
+ src_addr += s_dfu_settings.sd_size;
+ len -= s_dfu_settings.sd_size;
+ }
+
+ NRF_LOG_DEBUG("Verifying BL: Addr: 0x%08x, Src: 0x%08x, Len: 0x%08x", BOOTLOADER_START_ADDR, src_addr, len);
+
+ // This code is a configurable workaround for updating SD+BL from SDK 12.x.y - 14.1.0
+ // SoftDevice size increase would lead to unaligned source address when comparing new BL in SD+BL updates.
+ // This workaround is not required once BL is successfully installed with a version that is compiled SDK 14.1.0
+#if defined(NRF52832_XXAA) && defined(BLE_STACK_SUPPORT_REQD)
+ if ((p_bank->bank_code == NRF_DFU_BANK_VALID_SD_BL) &&
+ (memcmp((void *)BOOTLOADER_START_ADDR, (void *)(src_addr - 0x4000), len) == 0))
+ {
+ ret_val = NRF_SUCCESS;
+ }
+#endif // defined(NRF52832_XXAA)
+
+ // Check if the BL has already been copied.
+ if ((ret_val != NRF_SUCCESS) &&
+ (memcmp((void *)BOOTLOADER_START_ADDR, (void *)src_addr, len) == 0))
+ {
+ ret_val = NRF_SUCCESS;
+ }
+
+ // If the bootloader is the same as the banked version, the copy is finished
+ if (ret_val == NRF_SUCCESS)
+ {
+ NRF_LOG_DEBUG("No bootloader copy needed, bootloader update complete.");
+ }
+ else
+ {
+ NRF_LOG_DEBUG("Copying bootloader: Src: 0x%08x, Len: 0x%08x", src_addr, len);
+ NRF_LOG_FLUSH();
+
+ nrf_bootloader_wdt_feed();
+
+ // Bootloader is different than the banked version. Continue copy
+ // Note that if the SD and BL was combined, then the split point between them is in s_dfu_settings.sd_size
+ // On success this function won't return.
+ ret_val = nrf_dfu_mbr_copy_bl((uint32_t*)src_addr, len);
+ if (ret_val != NRF_SUCCESS)
+ {
+ NRF_LOG_ERROR("Request to copy BL failed");
+ }
+ }
+
+ return ret_val;
+}
+
+
+/** @brief Function to continue combined bootloader and SoftDevice update.
+ *
+ * @details This function will be called after reset if there is a valid bootloader and SoftDevice in Bank 0 or Bank 1
+ * required to be relocated and activated through MBR commands.
+ *
+ * @retval NRF_SUCCESS Continuation was successful.
+ * @retval NRF_ERROR_INVALID_LENGTH Invalid length.
+ * @retval NRF_ERROR_NO_MEM If UICR.NRFFW[1] is not set (i.e. is 0xFFFFFFFF).
+ * @retval NRF_ERROR_INVALID_PARAM If an invalid command is given.
+ * @retval NRF_ERROR_INTERNAL Indicates that the contents of the memory blocks where not verified correctly after copying.
+ * @retval NRF_ERROR_NULL If the content of the memory blocks differs after copying.
+ * @retval NRF_ERROR_FORBIDDEN If NRF_UICR->BOOTADDR is not set.
+ */
+static uint32_t sd_bl_activate()
+{
+ uint32_t ret_val = NRF_SUCCESS;
+
+ NRF_LOG_DEBUG("Enter nrf_dfu_sd_bl_continue");
+
+ ret_val = sd_activate();
+ if (ret_val != NRF_SUCCESS)
+ {
+ NRF_LOG_ERROR("SD+BL: SD copy failed");
+ return ret_val;
+ }
+
+ ret_val = bl_activate();
+ if (ret_val != NRF_SUCCESS)
+ {
+ NRF_LOG_ERROR("SD+BL: BL copy failed");
+ return ret_val;
+ }
+
+ return ret_val;
+}
+
+
+static void flash_write_callback(void * p_context)
+{
+ UNUSED_PARAMETER(p_context);
+ m_flash_write_done = true;
+}
+
+
+nrf_bootloader_fw_activation_result_t nrf_bootloader_fw_activate(void)
+{
+ nrf_bootloader_fw_activation_result_t result;
+ uint32_t ret_val = NRF_SUCCESS;
+ nrf_dfu_bank_t * p_bank = &s_dfu_settings.bank_1;
+ bool sd_update = false;
+
+
+ NRF_LOG_DEBUG("Enter nrf_bootloader_fw_activate");
+
+ switch (p_bank->bank_code)
+ {
+ case NRF_DFU_BANK_VALID_APP:
+ NRF_LOG_DEBUG("Valid App");
+ ret_val = app_activate();
+ break;
+ case NRF_DFU_BANK_VALID_SD:
+ NRF_LOG_DEBUG("Valid SD");
+ ret_val = sd_activate();
+ sd_update = true;
+ break;
+ case NRF_DFU_BANK_VALID_BL:
+ NRF_LOG_DEBUG("Valid BL");
+ ret_val = bl_activate();
+ break;
+ case NRF_DFU_BANK_VALID_SD_BL:
+ NRF_LOG_DEBUG("Valid SD + BL");
+ ret_val = sd_bl_activate();
+ sd_update = true;
+ break;
+ case NRF_DFU_BANK_INVALID:
+ default:
+ NRF_LOG_INFO("No firmware to activate.");
+ return ACTIVATION_NONE;
+ }
+
+ if (ret_val != NRF_SUCCESS)
+ {
+ NRF_LOG_ERROR("Activation failed with error %d (bank code: 0x%x)", ret_val, p_bank->bank_code);
+ result = ACTIVATION_ERROR;
+ }
+
+ // Invalidate bank, marking completion.
+ nrf_dfu_bank_invalidate(p_bank);
+
+ m_flash_write_done = false;
+ ret_val = nrf_dfu_settings_write(flash_write_callback);
+ ASSERT(m_flash_write_done);
+
+ /* At this point flash module is performing blocking operation. It is expected that operation is already performed. */
+ if (ret_val == NRF_SUCCESS)
+ {
+ result = ACTIVATION_SUCCESS;
+ if (sd_update && nrf_dfu_app_is_valid(true))
+ {
+ //If SD was updated and application is valid we want to stay in DFU to receive application.
+ NRF_LOG_DEBUG("A SoftDevice has just been activated. It's likely that an application will come immediately");
+ result = ACTIVATION_SUCCESS_EXPECT_ADDITIONAL_UPDATE;
+ }
+ }
+ else
+ {
+ NRF_LOG_ERROR("Could not write settings.");
+ result = ACTIVATION_ERROR;
+ }
+
+ return result;
+}
+
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/nrf_bootloader_fw_activation.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/nrf_bootloader_fw_activation.h
new file mode 100644
index 0000000..312491d
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/nrf_bootloader_fw_activation.h
@@ -0,0 +1,96 @@
+/**
+ * Copyright (c) 2018 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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
+ *
+ * @defgroup nrf_bootloader_fw_activation Firmware activation
+ * @{
+ * @ingroup nrf_bootloader
+ */
+
+#ifndef NRF_BOOTLOADER_FW_ACTIVATION_H__
+#define NRF_BOOTLOADER_FW_ACTIVATION_H__
+
+#include <stdint.h>
+#include <stdbool.h>
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+typedef enum
+{
+ ACTIVATION_NONE, //!< No new update was found.
+ ACTIVATION_SUCCESS, //!< Update was successfully activated.
+ ACTIVATION_SUCCESS_EXPECT_ADDITIONAL_UPDATE, //!< Update was successfully activated, but there might be additional update(s) to be transferred.
+ ACTIVATION_ERROR, //!< Activation of an update failed.
+} nrf_bootloader_fw_activation_result_t;
+
+/** @brief Function for activating a firmware received during DFU.
+ *
+ * @details This function initiates or continues the DFU copy-back
+ * routines. These routines are fail-safe operations to activate
+ * either a new SoftDevice, bootloader, combination of SoftDevice and
+ * bootloader, or a new application.
+ *
+ * @details This function relies on accessing MBR commands through supervisor calls.
+ * It does not rely on the SoftDevice for flash operations.
+ *
+ * @note When updating the bootloader or both bootloader and SoftDevice in combination,
+ * this function does not return, but rather initiates a reboot to activate
+ * the new bootloader.
+ *
+ * @retval ACTIVATION_NONE If no update was found.
+ * @retval ACTIVATION_SUCCESS If the firmware update was successfully activated.
+ * @retval ACTIVATION_SUCCESS_EXPECT_ADDITIONAL_UPDATE If the firmware update was successfully activated,
+ * but there are likely more updates to be transferred.
+ * @retval ACTIVATION_ERROR If the firmware update could not be activated.
+ */
+nrf_bootloader_fw_activation_result_t nrf_bootloader_fw_activate(void);
+
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // NRF_BOOTLOADER_FW_ACTIVATION_H__
+
+/** @} */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/nrf_bootloader_info.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/nrf_bootloader_info.c
new file mode 100644
index 0000000..77a8ad1
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/nrf_bootloader_info.c
@@ -0,0 +1,59 @@
+/**
+ * Copyright (c) 2016 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#include "nrf_bootloader_info.h"
+
+
+/** @brief This variable ensures that the linker script will write the bootloader start address
+ * to the UICR register. This value will be written in the HEX file and thus written to
+ * UICR when the bootloader is flashed into the chip.
+ */
+#if defined (__CC_ARM )
+ #pragma push
+ #pragma diag_suppress 1296
+ uint32_t m_uicr_bootloader_start_address __attribute__((at(NRF_UICR_BOOTLOADER_START_ADDRESS)))
+ = BOOTLOADER_START_ADDR;
+ #pragma pop
+#elif defined ( __GNUC__ ) || defined ( __SES_ARM )
+ volatile uint32_t m_uicr_bootloader_start_address __attribute__ ((section(".uicr_bootloader_start_address")))
+ = BOOTLOADER_START_ADDR;
+#elif defined ( __ICCARM__ )
+ __root const uint32_t m_uicr_bootloader_start_address @ NRF_UICR_BOOTLOADER_START_ADDRESS
+ = BOOTLOADER_START_ADDR;
+#endif
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/nrf_bootloader_info.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/nrf_bootloader_info.h
new file mode 100644
index 0000000..812cddb
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/nrf_bootloader_info.h
@@ -0,0 +1,188 @@
+/**
+ * Copyright (c) 2016 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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
+ *
+ * @defgroup nrf_bootloader_info Bootloader Information
+ * @{
+ * @ingroup nrf_bootloader
+ */
+
+#ifndef NRF_BOOTLOADER_INFO_H__
+#define NRF_BOOTLOADER_INFO_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "app_util.h"
+#include "nrf.h"
+#include "nrf_mbr.h"
+
+/** @brief Macro for getting the start address of the bootloader image.
+ *
+ * The macro is not a compile time symbol. It cannot be used as a
+ * constant expression, for example, inside a static assert or linker script
+ * at-placement.
+ */
+#ifndef BOOTLOADER_START_ADDR
+#if (__LINT__ == 1)
+ #define BOOTLOADER_START_ADDR (0x3AC00)
+#elif defined(CODE_START)
+ #define BOOTLOADER_START_ADDR (CODE_START)
+#else
+ #error Not a valid compiler/linker for BOOTLOADER_START_ADDR.
+#endif
+#endif
+
+
+/** @brief Macro for getting the size of the bootloader image.
+ */
+#ifndef BOOTLOADER_SIZE
+#if defined ( NRF51 )
+ #define BOOTLOADER_SIZE (BOOTLOADER_SETTINGS_ADDRESS - BOOTLOADER_START_ADDR)
+#elif defined( NRF52_SERIES )
+ #define BOOTLOADER_SIZE (NRF_MBR_PARAMS_PAGE_ADDRESS - BOOTLOADER_START_ADDR)
+#elif (__LINT__ == 1)
+ #define BOOTLOADER_SIZE (0x6000)
+#endif
+#endif
+
+
+/**
+ * @brief Bootloader start address in UICR.
+ *
+ * Register location in UICR where the bootloader start address is stored.
+ *
+ * @note If the value at the given location is 0xFFFFFFFF, the bootloader address is not set.
+ */
+#define NRF_UICR_BOOTLOADER_START_ADDRESS (NRF_UICR_BASE + 0x14)
+
+
+// The following macros are for accessing the SoftDevice information structure,
+// which is found inside the SoftDevice binary.
+
+/** @brief Macro for converting an offset inside the SoftDevice information struct to an absolute address.
+ */
+#define SD_INFO_ABS_OFFSET_GET(baseaddr, offset) ((baseaddr) + (SOFTDEVICE_INFO_STRUCT_OFFSET) + (offset))
+
+/** @brief Macros for reading a byte or a word at a particular offset inside a SoftDevice information struct.
+ * Use MBR_SIZE as baseaddr when the SoftDevice is installed just above the MBR (the usual case).
+ */
+#define SD_OFFSET_GET_UINT32(baseaddr, offset) (*((uint32_t *) SD_INFO_ABS_OFFSET_GET(baseaddr, offset)))
+#define SD_OFFSET_GET_UINT16(baseaddr, offset) (*((uint16_t *) SD_INFO_ABS_OFFSET_GET(baseaddr, offset)))
+#define SD_OFFSET_GET_UINT8(baseaddr, offset) (*((uint8_t *) SD_INFO_ABS_OFFSET_GET(baseaddr, offset)))
+
+
+#ifdef BLE_STACK_SUPPORT_REQD
+#include "nrf_sdm.h"
+#else
+/** @brief The offset inside the SoftDevice at which the information struct is placed.
+ * To see the layout of the information struct, see the SoftDevice specification.
+ */
+#define SOFTDEVICE_INFO_STRUCT_OFFSET (0x2000)
+
+#define SD_INFO_STRUCT_SIZE(baseaddr) SD_OFFSET_GET_UINT8(baseaddr, 0x00)
+
+/** @brief Macro for reading the size of a SoftDevice at a given base address.
+ */
+#ifndef SD_SIZE_GET
+#define SD_SIZE_GET(baseaddr) SD_OFFSET_GET_UINT32(baseaddr, 0x08)
+#endif
+
+/** @brief Macro for reading the version of a SoftDevice at a given base address.
+ * This expression checks the length of the information struct to see if the version is present.
+ * The version number is constructed like this:
+ * major_version * 1000000 + minor_version * 1000 + bugfix_version
+ */
+#ifndef SD_VERSION_GET
+#define SD_VERSION_GET(baseaddr) ((SD_INFO_STRUCT_SIZE(baseaddr) > (0x14)) \
+ ? SD_OFFSET_GET_UINT32(baseaddr, 0x14) \
+ : 0)
+#endif
+#endif
+
+
+/** @brief Macro for reading the magic number of a SoftDevice at a given base address.
+ */
+#ifndef SD_MAGIC_NUMBER_GET
+#define SD_MAGIC_NUMBER_GET(baseaddr) SD_OFFSET_GET_UINT32(baseaddr, 0x04)
+#endif
+
+/** @brief Macro for getting the absolute address of the magic number.
+ */
+#define SD_MAGIC_NUMBER_ABS_OFFSET_GET(baseaddr) SD_INFO_ABS_OFFSET_GET(baseaddr, 0x04)
+
+/** @brief The number present at a specific location in all SoftDevices.
+ */
+#define SD_MAGIC_NUMBER ((uint32_t)0x51B1E5DB)
+
+/** @brief Whether a SoftDevice is at its regular location.
+ */
+#ifndef SD_PRESENT
+#define SD_PRESENT ((SD_MAGIC_NUMBER_GET(MBR_SIZE)) == (SD_MAGIC_NUMBER))
+#endif
+
+/** @brief The multiplier for the major version of the SoftDevice. See \ref SD_VERSION_GET
+ */
+#define SD_MAJOR_VERSION_MULTIPLIER (1000000)
+
+/** @brief Read the major version of the SoftDevice from the raw version number. See \ref SD_VERSION_GET.
+ */
+#define SD_MAJOR_VERSION_EXTRACT(raw_version) ((raw_version)/SD_MAJOR_VERSION_MULTIPLIER)
+
+
+#define BOOTLOADER_DFU_GPREGRET_MASK (0xB0) /**< Magic pattern written to GPREGRET register to signal between main app and DFU. The 3 lower bits are assumed to be used for signalling purposes.*/
+#define BOOTLOADER_DFU_START_BIT_MASK (0x01) /**< Bit mask to signal from main application to enter DFU mode using a buttonless service. */
+
+#define BOOTLOADER_DFU_GPREGRET2_MASK (0xA8) /**< Magic pattern written to GPREGRET2 register to signal between main app and DFU. The 3 lower bits are assumed to be used for signalling purposes.*/
+#define BOOTLOADER_DFU_SKIP_CRC_BIT_MASK (0x01) /**< Bit mask to signal from main application that CRC-check is not needed for image verification. */
+
+
+#define BOOTLOADER_DFU_START (BOOTLOADER_DFU_GPREGRET_MASK | BOOTLOADER_DFU_START_BIT_MASK) /**< Magic number to signal that bootloader should enter DFU mode because of signal from Buttonless DFU in main app.*/
+#define BOOTLOADER_DFU_SKIP_CRC (BOOTLOADER_DFU_GPREGRET2_MASK | BOOTLOADER_DFU_SKIP_CRC_BIT_MASK) /**< Magic number to signal that CRC can be skipped due to low power modes.*/
+
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // #ifndef NRF_BOOTLOADER_INFO_H__
+/** @} */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/nrf_bootloader_wdt.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/nrf_bootloader_wdt.c
new file mode 100644
index 0000000..b75d6ef
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/nrf_bootloader_wdt.c
@@ -0,0 +1,134 @@
+/**
+ * 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#include "nrf_bootloader_wdt.h"
+#include "nrf_wdt.h"
+#include "nrf_bootloader_dfu_timers.h"
+#include "nrf_log_ctrl.h"
+
+#define NRF_LOG_MODULE_NAME nrf_bootloader_wdt
+#include "nrf_log.h"
+NRF_LOG_MODULE_REGISTER();
+
+//Flag used to determine if internal feeding should stay active.
+static bool m_wdt_keep_internal_feed;
+
+static void wdt_feed(void)
+{
+ if (nrf_wdt_started())
+ {
+ for (nrf_wdt_rr_register_t i = NRF_WDT_RR0; i < NRF_WDT_RR7; i++)
+ {
+ if (nrf_wdt_reload_request_is_enabled(i))
+ {
+ nrf_wdt_reload_request_set(i);
+ }
+ }
+ }
+}
+
+
+static void wdt_feed_timer_handler(void)
+{
+ if (m_wdt_keep_internal_feed)
+ {
+ NRF_LOG_INFO("Internal feed");
+ wdt_feed();
+ }
+}
+
+
+void WDT_IRQHandler(void)
+{
+ nrf_wdt_event_clear(NRF_WDT_EVENT_TIMEOUT);
+ NRF_LOG_FINAL_FLUSH();
+}
+
+void nrf_bootloader_wdt_init(void)
+{
+ static bool initialized = false;
+
+ if (initialized)
+ {
+ return;
+ }
+
+ if (nrf_wdt_started())
+ {
+ uint32_t approx_wdt_ms = nrf_wdt_reload_value_get() / 32;
+
+ NRF_LOG_INFO("WDT enabled CRV:%d ms", approx_wdt_ms);
+
+ //wdt_ticks must be reduced (0.75) to feed the watchdog before the timeout.
+ uint32_t reduced_timeout_ms = (approx_wdt_ms * 3)/4;
+
+ /* Ideally, watchdog should be fed by the bootloader from the main context but if bootloader latency
+ * (mainly driven by signature check) is big enough there is a risk that watchdog will not be fed
+ * on time. In that case watchdog will be fed from timer context. */
+ m_wdt_keep_internal_feed =
+ (reduced_timeout_ms < NRF_BL_WDT_MAX_SCHEDULER_LATENCY_MS);
+
+ /* initial watchdog feed */
+ wdt_feed();
+
+ /* If internal feed is needed or WDT is active in sleep module must provide regular wakeup interrupt.*/
+ bool wdt_start_timer = m_wdt_keep_internal_feed || (NRF_WDT->CONFIG & WDT_CONFIG_SLEEP_Msk);
+ if (wdt_start_timer)
+ {
+ NRF_LOG_INFO("Starting a timer (%d ms) for feeding watchdog.", reduced_timeout_ms);
+ nrf_bootloader_wdt_feed_timer_start(reduced_timeout_ms, wdt_feed_timer_handler);
+ }
+
+ NVIC_EnableIRQ(WDT_IRQn);
+ }
+ else
+ {
+ NRF_LOG_INFO("WDT is not enabled");
+ }
+
+ initialized = true;
+}
+
+void nrf_bootloader_wdt_feed(void)
+{
+ if (nrf_wdt_started())
+ {
+ wdt_feed();
+ }
+}
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/nrf_bootloader_wdt.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/nrf_bootloader_wdt.h
new file mode 100644
index 0000000..0a6cb9b
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/nrf_bootloader_wdt.h
@@ -0,0 +1,79 @@
+/**
+ * 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#ifndef NRF_BOOTLOADER_WDT_H
+#define NRF_BOOTLOADER_WDT_H
+
+/**@file
+ *
+ * @defgroup nrf_bootloader_wdt Automated feeding of the watchdog
+ * @{
+ * @ingroup nrf_bootloader
+ * @brief Module that keeps the WDT from timing out if the WDT has been started in the application.
+ */
+
+#include "sdk_errors.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+/**
+ * @brief Function for checking whether the WDT peripheral is started and for getting its configuration.
+ *
+ * The module uses app_timer to start regular feeding of the watchdog. Timer interval
+ * is chosen based on watchdog settings. When @ref nrf_bootloader_wdt_feed is called, internal
+ * feeding is stopped assuming that the application takes responsibity of watchdog feeding.
+ * However, if @ref NRF_BL_WDT_MAX_SCHEDULER_LATENCY_MS or the watchdog is configured to
+ * run during sleep, then internal feeding (from app_timer handler context) is kept active.
+ */
+void nrf_bootloader_wdt_init(void);
+
+
+/**
+ * @brief Function for feeding the watchdog (if active).
+ */
+void nrf_bootloader_wdt_feed(void);
+
+#ifdef __cplusplus
+}
+#endif
+
+/** @} */
+
+#endif //NRF_BOOTLOADER_WDT_H
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/serial_dfu/nrf_dfu_serial.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/serial_dfu/nrf_dfu_serial.c
new file mode 100644
index 0000000..8e14b05
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/serial_dfu/nrf_dfu_serial.c
@@ -0,0 +1,265 @@
+/**
+ * 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+
+#include "nrf_dfu_serial.h"
+#include "nrf_dfu_req_handler.h"
+#include "nrf_dfu_handling_error.h"
+
+#define NRF_LOG_MODULE_NAME nrf_dfu_serial
+#include "nrf_log.h"
+NRF_LOG_MODULE_REGISTER();
+
+#define NRF_SERIAL_OPCODE_SIZE (sizeof(uint8_t))
+
+
+
+static uint32_t response_ext_err_payload_add(uint8_t * p_buffer, uint32_t buf_offset)
+{
+ p_buffer[buf_offset] = ext_error_get();
+ (void) ext_error_set(NRF_DFU_EXT_ERROR_NO_ERROR);
+
+ return 1;
+}
+
+
+static void response_send(nrf_dfu_serial_t * p_transport,
+ nrf_dfu_response_t const * p_response)
+{
+ uint8_t index = 0;
+ uint8_t * p_serialized_rsp = p_transport->p_rsp_buf;
+
+ NRF_LOG_DEBUG("Sending Response: [0x%01x, 0x%01x]", p_response->request, p_response->result);
+
+ p_serialized_rsp[index++] = NRF_DFU_OP_RESPONSE;
+ p_serialized_rsp[index++] = p_response->request;
+ p_serialized_rsp[index++] = (uint8_t)(p_response->result);
+
+ if (p_response->result == NRF_DFU_RES_CODE_SUCCESS)
+ {
+ switch (p_response->request)
+ {
+ case NRF_DFU_OP_PROTOCOL_VERSION:
+ {
+ p_serialized_rsp[index] = p_response->protocol.version;
+ index += sizeof(uint8_t);
+ } break;
+
+ case NRF_DFU_OP_HARDWARE_VERSION:
+ {
+ index += uint32_encode(p_response->hardware.part, &p_serialized_rsp[index]);
+ index += uint32_encode(p_response->hardware.variant, &p_serialized_rsp[index]);
+ index += uint32_encode(p_response->hardware.memory.rom_size, &p_serialized_rsp[index]);
+ index += uint32_encode(p_response->hardware.memory.ram_size, &p_serialized_rsp[index]);
+ index += uint32_encode(p_response->hardware.memory.rom_page_size, &p_serialized_rsp[index]);
+ } break;
+
+ case NRF_DFU_OP_FIRMWARE_VERSION:
+ {
+ p_serialized_rsp[index++] = p_response->firmware.type;
+ index += uint32_encode(p_response->firmware.version, &p_serialized_rsp[index]);
+ index += uint32_encode(p_response->firmware.addr, &p_serialized_rsp[index]);
+ index += uint32_encode(p_response->firmware.len, &p_serialized_rsp[index]);
+ } break;
+
+ case NRF_DFU_OP_CRC_GET:
+ index += uint32_encode(p_response->crc.offset, &p_serialized_rsp[index]);
+ index += uint32_encode(p_response->crc.crc, &p_serialized_rsp[index]);
+ break;
+
+ case NRF_DFU_OP_OBJECT_SELECT:
+ index += uint32_encode(p_response->select.max_size, &p_serialized_rsp[index]);
+ index += uint32_encode(p_response->select.offset, &p_serialized_rsp[index]);
+ index += uint32_encode(p_response->select.crc, &p_serialized_rsp[index]);
+ break;
+
+ case NRF_DFU_OP_MTU_GET:
+ index += uint16_encode(p_response->mtu.size, &p_serialized_rsp[index]);
+ break;
+
+ case NRF_DFU_OP_PING:
+ p_serialized_rsp[index] = p_response->ping.id;
+ index += sizeof(uint8_t);
+ break;
+
+ default:
+ // no implementation
+ break;
+ }
+ }
+ else if (p_response->result == NRF_DFU_RES_CODE_EXT_ERROR)
+ {
+ index += response_ext_err_payload_add(p_serialized_rsp, index);
+ }
+
+ if (index > NRF_SERIAL_MAX_RESPONSE_SIZE)
+ {
+ NRF_LOG_ERROR("Message is larger than expected.");
+ }
+
+ // Send response.
+ if (p_transport->rsp_func((uint8_t const *)(p_serialized_rsp), index) != NRF_SUCCESS)
+ {
+ NRF_LOG_ERROR("Failed to send data over serial interface!");
+ }
+}
+
+
+void dfu_req_handler_rsp_clbk(nrf_dfu_response_t * p_res, void * p_context)
+{
+ nrf_dfu_serial_t * p_transport = (nrf_dfu_serial_t *)(p_context);
+
+ if (p_res->result != NRF_DFU_RES_CODE_SUCCESS)
+ {
+ NRF_LOG_WARNING("DFU request completed with result: 0x%x", p_res->result);
+ }
+
+ switch (p_res->request)
+ {
+ default:
+ /* Reply normally.
+ * Make sure to reply to NRF_DFU_OP_OBJECT_CREATE when running DFU over serial,
+ * otherwise the transfer might run very slow, without an apparent reason.
+ */
+ break;
+
+ case NRF_DFU_OP_OBJECT_WRITE:
+ {
+ p_transport->pkt_notif_target_count--;
+
+ if ( (p_transport->pkt_notif_target == 0)
+ || (p_transport->pkt_notif_target_count != 0))
+ {
+ /* Do not reply to _OBJECT_WRITE messages. */
+ return;
+ }
+
+ /* Reply with a CRC message and reset the packet counter. */
+ p_transport->pkt_notif_target_count = p_transport->pkt_notif_target;
+
+ p_res->request = NRF_DFU_OP_CRC_GET;
+ p_res->crc.offset = p_res->write.offset;
+ p_res->crc.crc = p_res->write.crc;
+ } break;
+ }
+
+ response_send(p_transport, p_res);
+}
+
+
+void nrf_dfu_serial_on_packet_received(nrf_dfu_serial_t * p_transport,
+ uint8_t const * p_data,
+ uint32_t length)
+{
+ uint8_t const * p_payload = &p_data[NRF_SERIAL_OPCODE_SIZE];
+ uint16_t const payload_len = (length - NRF_SERIAL_OPCODE_SIZE);
+
+ nrf_dfu_request_t request =
+ {
+ .request = (nrf_dfu_op_t)(p_data[0]),
+ .callback.response = dfu_req_handler_rsp_clbk,
+ .p_context = p_transport
+ };
+
+ bool buf_free = true;
+
+ switch (request.request)
+ {
+ case NRF_DFU_OP_FIRMWARE_VERSION:
+ {
+ request.firmware.image_number = p_payload[0];
+ } break;
+
+ case NRF_DFU_OP_RECEIPT_NOTIF_SET:
+ {
+ NRF_LOG_DEBUG("Set receipt notif target: %d", p_transport->pkt_notif_target);
+
+ p_transport->pkt_notif_target = uint16_decode(&p_payload[0]);
+ p_transport->pkt_notif_target_count = p_transport->pkt_notif_target;
+ } break;
+
+ case NRF_DFU_OP_OBJECT_SELECT:
+ {
+ request.select.object_type = p_payload[0];
+ } break;
+
+ case NRF_DFU_OP_OBJECT_CREATE:
+ {
+ // Reset the packet receipt notification on create object
+ p_transport->pkt_notif_target_count = p_transport->pkt_notif_target;
+
+ request.create.object_type = p_payload[0];
+ request.create.object_size = uint32_decode(&p_payload[1]);
+ } break;
+
+ case NRF_DFU_OP_OBJECT_WRITE:
+ {
+ // Buffer will be freed asynchronously
+ buf_free = false;
+
+ request.write.p_data = p_payload;
+ request.write.len = payload_len;
+ request.callback.write = p_transport->payload_free_func;
+ } break;
+
+ case NRF_DFU_OP_MTU_GET:
+ {
+ NRF_LOG_DEBUG("Received serial mtu");
+ request.mtu.size = p_transport->mtu;
+ } break;
+
+ case NRF_DFU_OP_PING:
+ {
+ NRF_LOG_DEBUG("Received ping %d", p_payload[0]);
+ request.ping.id = p_payload[0];
+ } break;
+
+ default:
+ /* Do nothing. */
+ break;
+ }
+
+ if (buf_free)
+ {
+ p_transport->payload_free_func((void *)(p_payload));
+ }
+
+ ret_code_t ret_code = nrf_dfu_req_handler_on_req(&request);
+ ASSERT(ret_code == NRF_SUCCESS);
+}
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/serial_dfu/nrf_dfu_serial.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/serial_dfu/nrf_dfu_serial.h
new file mode 100644
index 0000000..c14ee40
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/serial_dfu/nrf_dfu_serial.h
@@ -0,0 +1,109 @@
+/**
+ * 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+
+#ifndef NRF_DFU_SERIAL_H__
+#define NRF_DFU_SERIAL_H__
+
+#include <stdint.h>
+#include "sdk_errors.h"
+#include "nrf_dfu_req_handler.h"
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**@file
+ *
+ * @defgroup nrf_dfu_serial DFU Serial transports shared part
+ * @{
+ * @ingroup nrf_dfu
+ * @brief Shared part of Device Firmware Update (DFU) transport layers using serial interface (UART, USB CDC ACM).
+ *
+ * @defgroup nrf_dfu_serial_uart DFU Serial UART transport
+ * @ingroup nrf_dfu_serial
+ * @brief Configuration for Device Firmware Update (DFU) transport layer using UART.
+ *
+ * @defgroup nrf_dfu_serial_usb DFU Serial USB CDC ACM transport
+ * @ingroup nrf_dfu_serial
+ * @brief Configuration for Device Firmware Update (DFU) transport layer using USB CDC ACM.
+ *
+ */
+
+#define NRF_SERIAL_MAX_RESPONSE_SIZE (sizeof(nrf_dfu_response_t))
+
+/**
+ * Prototype for function for sending response over serial DFU transport.
+ */
+typedef ret_code_t (*nrf_serial_rsp_func_t)(uint8_t const * p_data, uint32_t length);
+
+/**
+ * Prototype for function for freeing RX buffer.
+ *
+ * Function is called when input data is processed.
+ */
+typedef void (*nrf_serial_rx_buf_free_func_t)(void * p_buf);
+
+
+/**@brief DFU serial transport layer state.
+ *
+ * @details This structure contains status information related to the serial transport layer type.
+ */
+typedef struct
+{
+ uint16_t pkt_notif_target;
+ uint16_t pkt_notif_target_count;
+ nrf_serial_rsp_func_t rsp_func;
+ nrf_serial_rx_buf_free_func_t payload_free_func;
+ uint32_t mtu;
+ uint8_t * p_rsp_buf;
+} nrf_dfu_serial_t;
+
+void nrf_dfu_serial_on_packet_received(nrf_dfu_serial_t * p_transport,
+ uint8_t const * p_data,
+ uint32_t length);
+
+/** @} */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // NRF_DFU_SERIAL_H__
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/serial_dfu/nrf_dfu_serial_uart.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/serial_dfu/nrf_dfu_serial_uart.c
new file mode 100644
index 0000000..3d0b783
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/serial_dfu/nrf_dfu_serial_uart.c
@@ -0,0 +1,235 @@
+/**
+ * Copyright (c) 2016 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+
+#include "nrf_dfu_serial.h"
+
+#include <string.h>
+#include "boards.h"
+#include "app_util_platform.h"
+#include "nrf_dfu_transport.h"
+#include "nrf_dfu_req_handler.h"
+#include "slip.h"
+#include "nrf_balloc.h"
+#include "nrf_drv_uart.h"
+
+#define NRF_LOG_MODULE_NAME nrf_dfu_serial_uart
+#include "nrf_log.h"
+NRF_LOG_MODULE_REGISTER();
+
+/**@file
+ *
+ * @defgroup nrf_dfu_serial_uart DFU Serial UART transport
+ * @ingroup nrf_dfu
+ * @brief Device Firmware Update (DFU) transport layer using UART.
+ */
+
+#define NRF_SERIAL_OPCODE_SIZE (sizeof(uint8_t))
+#define NRF_UART_MAX_RESPONSE_SIZE_SLIP (2 * NRF_SERIAL_MAX_RESPONSE_SIZE + 1)
+#define RX_BUF_SIZE (64) //to get 64bytes payload
+#define OPCODE_OFFSET (sizeof(uint32_t) - NRF_SERIAL_OPCODE_SIZE)
+#define DATA_OFFSET (OPCODE_OFFSET + NRF_SERIAL_OPCODE_SIZE)
+#define UART_SLIP_MTU (2 * (RX_BUF_SIZE + 1) + 1)
+#define BALLOC_BUF_SIZE ((CEIL_DIV((RX_BUF_SIZE+OPCODE_SIZE),sizeof(uint32_t))*sizeof(uint32_t)))
+
+NRF_BALLOC_DEF(m_payload_pool, (UART_SLIP_MTU + 1), NRF_DFU_SERIAL_UART_RX_BUFFERS);
+
+static nrf_drv_uart_t m_uart = NRF_DRV_UART_INSTANCE(0);
+static uint8_t m_rx_byte;
+
+static nrf_dfu_serial_t m_serial;
+static slip_t m_slip;
+static uint8_t m_rsp_buf[NRF_UART_MAX_RESPONSE_SIZE_SLIP];
+static bool m_active;
+
+static nrf_dfu_observer_t m_observer;
+
+static uint32_t uart_dfu_transport_init(nrf_dfu_observer_t observer);
+static uint32_t uart_dfu_transport_close(nrf_dfu_transport_t const * p_exception);
+
+DFU_TRANSPORT_REGISTER(nrf_dfu_transport_t const uart_dfu_transport) =
+{
+ .init_func = uart_dfu_transport_init,
+ .close_func = uart_dfu_transport_close,
+};
+
+static void payload_free(void * p_buf)
+{
+ uint8_t * p_buf_root = (uint8_t *)p_buf - DATA_OFFSET; //pointer is shifted to point to data
+ nrf_balloc_free(&m_payload_pool, p_buf_root);
+}
+
+static ret_code_t rsp_send(uint8_t const * p_data, uint32_t length)
+{
+ uint32_t slip_len;
+ (void) slip_encode(m_rsp_buf, (uint8_t *)p_data, length, &slip_len);
+
+ return nrf_drv_uart_tx(&m_uart, m_rsp_buf, slip_len);
+}
+
+static __INLINE void on_rx_complete(nrf_dfu_serial_t * p_transport, uint8_t * p_data, uint8_t len)
+{
+ ret_code_t ret_code;
+
+ ret_code = slip_decode_add_byte(&m_slip, p_data[0]);
+ (void) nrf_drv_uart_rx(&m_uart, &m_rx_byte, 1);
+
+ if (ret_code == NRF_SUCCESS)
+ {
+ // Activity detected on current transport, close all except active one.
+ UNUSED_RETURN_VALUE(nrf_dfu_transports_close(&uart_dfu_transport));
+
+ nrf_dfu_serial_on_packet_received(p_transport,
+ (uint8_t const *)m_slip.p_buffer,
+ m_slip.current_index);
+
+ uint8_t * p_rx_buf = nrf_balloc_alloc(&m_payload_pool);
+ if (p_rx_buf == NULL)
+ {
+ NRF_LOG_ERROR("Failed to allocate buffer");
+ return;
+ }
+ NRF_LOG_INFO("Allocated buffer %x", p_rx_buf);
+ // reset the slip decoding
+ m_slip.p_buffer = &p_rx_buf[OPCODE_OFFSET];
+ m_slip.current_index = 0;
+ m_slip.state = SLIP_STATE_DECODING;
+ }
+
+}
+
+static void uart_event_handler(nrf_drv_uart_event_t * p_event, void * p_context)
+{
+ switch (p_event->type)
+ {
+ case NRF_DRV_UART_EVT_RX_DONE:
+ on_rx_complete((nrf_dfu_serial_t*)p_context,
+ p_event->data.rxtx.p_data,
+ p_event->data.rxtx.bytes);
+ break;
+
+ case NRF_DRV_UART_EVT_ERROR:
+ APP_ERROR_HANDLER(p_event->data.error.error_mask);
+ break;
+
+ default:
+ // No action.
+ break;
+ }
+}
+
+static uint32_t uart_dfu_transport_init(nrf_dfu_observer_t observer)
+{
+ uint32_t err_code = NRF_SUCCESS;
+
+ if (m_active)
+ {
+ return err_code;
+ }
+
+ NRF_LOG_DEBUG("serial_dfu_transport_init()");
+
+ m_observer = observer;
+
+ err_code = nrf_balloc_init(&m_payload_pool);
+ if (err_code != NRF_SUCCESS)
+ {
+ return err_code;
+ }
+
+ uint8_t * p_rx_buf = nrf_balloc_alloc(&m_payload_pool);
+
+ m_slip.p_buffer = &p_rx_buf[OPCODE_OFFSET];
+ m_slip.current_index = 0;
+ m_slip.buffer_len = UART_SLIP_MTU;
+ m_slip.state = SLIP_STATE_DECODING;
+
+ m_serial.rsp_func = rsp_send;
+ m_serial.payload_free_func = payload_free;
+ m_serial.mtu = UART_SLIP_MTU;
+ m_serial.p_rsp_buf = &m_rsp_buf[NRF_UART_MAX_RESPONSE_SIZE_SLIP -
+ NRF_SERIAL_MAX_RESPONSE_SIZE];
+
+ nrf_drv_uart_config_t uart_config = NRF_DRV_UART_DEFAULT_CONFIG;
+
+ uart_config.pseltxd = TX_PIN_NUMBER;
+ uart_config.pselrxd = RX_PIN_NUMBER;
+ uart_config.pselcts = CTS_PIN_NUMBER;
+ uart_config.pselrts = RTS_PIN_NUMBER;
+ uart_config.hwfc = NRF_DFU_SERIAL_UART_USES_HWFC ?
+ NRF_UART_HWFC_ENABLED : NRF_UART_HWFC_DISABLED;
+ uart_config.p_context = &m_serial;
+
+ err_code = nrf_drv_uart_init(&m_uart, &uart_config, uart_event_handler);
+ if (err_code != NRF_SUCCESS)
+ {
+ NRF_LOG_ERROR("Failed initializing uart");
+ return err_code;
+ }
+
+ err_code = nrf_drv_uart_rx(&m_uart, &m_rx_byte, 1);
+ if (err_code != NRF_SUCCESS)
+ {
+ NRF_LOG_ERROR("Failed initializing rx");
+ }
+
+ NRF_LOG_DEBUG("serial_dfu_transport_init() completed");
+
+ m_active = true;
+
+ if (m_observer)
+ {
+ m_observer(NRF_DFU_EVT_TRANSPORT_ACTIVATED);
+ }
+
+ return err_code;
+}
+
+
+static uint32_t uart_dfu_transport_close(nrf_dfu_transport_t const * p_exception)
+{
+ if ((m_active == true) && (p_exception != &uart_dfu_transport))
+ {
+ nrf_drv_uart_uninit(&m_uart);
+ m_active = false;
+ }
+
+ return NRF_SUCCESS;
+}
+
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/serial_dfu/nrf_dfu_serial_usb.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/serial_dfu/nrf_dfu_serial_usb.c
new file mode 100644
index 0000000..2b45643
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/serial_dfu/nrf_dfu_serial_usb.c
@@ -0,0 +1,370 @@
+/**
+ * Copyright (c) 2016 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+
+#include <string.h>
+#include "nrf_dfu_req_handler.h"
+#include "nrf_dfu_transport.h"
+#include "slip.h"
+#include "nrf_balloc.h"
+#include "nrf_drv_power.h"
+#include "nrf_drv_clock.h"
+#include "nrf_drv_usbd.h"
+#include "nrf_dfu_serial.h"
+#include "app_scheduler.h"
+#include "app_usbd.h"
+#include "app_usbd_cdc_acm.h"
+#include "app_usbd_core.h"
+#include "app_usbd_string_desc.h"
+#include "app_util_platform.h"
+#include "app_usbd_serial_num.h"
+
+#define NRF_LOG_MODULE_NAME nrf_dfu_serial_usb
+#include "nrf_log.h"
+NRF_LOG_MODULE_REGISTER();
+
+/**@file
+ *
+ * @defgroup nrf_dfu_serial_usb DFU Serial USB CDC ACM transport
+ * @ingroup nrf_dfu
+ * @brief Device Firmware Update (DFU) transport layer using USB CDC ACM.
+ */
+
+#define NRF_SERIAL_OPCODE_SIZE (sizeof(uint8_t))
+
+#define NRF_USB_MAX_RESPONSE_SIZE_SLIP (2 * NRF_SERIAL_MAX_RESPONSE_SIZE + 1)
+
+#define RX_BUF_SIZE (1024)
+#define SLIP_MTU (2 * (RX_BUF_SIZE + 1) + 1)
+#define OPCODE_OFFSET (sizeof(uint32_t) - NRF_SERIAL_OPCODE_SIZE)
+#define DATA_OFFSET (OPCODE_OFFSET + NRF_SERIAL_OPCODE_SIZE)
+
+#define CDC_ACM_COMM_INTERFACE 0
+#define CDC_ACM_COMM_EPIN NRF_DRV_USBD_EPIN2
+#define CDC_ACM_DATA_INTERFACE 1
+#define CDC_ACM_DATA_EPIN NRF_DRV_USBD_EPIN1
+#define CDC_ACM_DATA_EPOUT NRF_DRV_USBD_EPOUT1
+
+/**
+ * @brief Enable power USB detection
+ *
+ * Configure if example supports USB port connection
+ */
+#ifndef USBD_POWER_DETECTION
+#define USBD_POWER_DETECTION true
+#endif
+
+/**
+ * @brief Interfaces list passed to @ref APP_USBD_CDC_ACM_GLOBAL_DEF
+ * */
+#define CDC_ACM_INTERFACES_CONFIG() \
+ APP_USBD_CDC_ACM_CONFIG(CDC_ACM_COMM_INTERFACE, \
+ CDC_ACM_COMM_EPIN, \
+ CDC_ACM_DATA_INTERFACE, \
+ CDC_ACM_DATA_EPIN, \
+ CDC_ACM_DATA_EPOUT)
+
+/*lint -save -e26 -e64 -e505 -e651 */
+static void cdc_acm_user_ev_handler(app_usbd_class_inst_t const * p_inst,
+ app_usbd_cdc_acm_user_event_t event);
+
+/**@brief CDC_ACM class instance. */
+APP_USBD_CDC_ACM_GLOBAL_DEF(m_app_cdc_acm,
+ cdc_acm_user_ev_handler,
+ CDC_ACM_COMM_INTERFACE,
+ CDC_ACM_DATA_INTERFACE,
+ CDC_ACM_COMM_EPIN,
+ CDC_ACM_DATA_EPIN,
+ CDC_ACM_DATA_EPOUT,
+ APP_USBD_CDC_COMM_PROTOCOL_NONE);
+/*lint -restore */
+
+NRF_BALLOC_DEF(m_payload_pool, (SLIP_MTU+1), NRF_DFU_SERIAL_USB_RX_BUFFERS);
+
+static nrf_dfu_serial_t m_serial;
+static slip_t m_slip;
+static uint8_t m_rsp_buf[NRF_USB_MAX_RESPONSE_SIZE_SLIP];
+static uint8_t m_rx_buf[NRF_DRV_USBD_EPSIZE];
+
+static nrf_dfu_observer_t m_observer;
+
+static uint32_t usb_dfu_transport_init(nrf_dfu_observer_t observer);
+static uint32_t usb_dfu_transport_close(nrf_dfu_transport_t const * p_exception);
+
+
+DFU_TRANSPORT_REGISTER(nrf_dfu_transport_t const usb_dfu_transport) =
+{
+ .init_func = usb_dfu_transport_init,
+ .close_func = usb_dfu_transport_close,
+};
+
+
+static void payload_free(void * p_buf)
+{
+ uint8_t * p_buf_root = ((uint8_t *)(p_buf)) - DATA_OFFSET; //pointer is shifted to point to data
+ nrf_balloc_free(&m_payload_pool, p_buf_root);
+}
+
+
+static ret_code_t rsp_send(uint8_t const * p_data, uint32_t length)
+{
+ ASSERT(p_data);
+ ASSERT(length != 0);
+
+ uint32_t slip_len;
+
+ // Cannot fail if inputs are non-NULL.
+ (void) slip_encode(m_rsp_buf, (uint8_t *)(p_data), length, &slip_len);
+
+ return app_usbd_cdc_acm_write(&m_app_cdc_acm, m_rsp_buf, slip_len);
+}
+
+
+static void on_rx_complete(nrf_dfu_serial_t * p_transport, uint8_t * p_data, uint8_t len)
+{
+ ret_code_t ret_code;
+
+ for (uint32_t i = 0; i < len; i++)
+ {
+ ret_code = slip_decode_add_byte(&m_slip, p_data[i]);
+ if (ret_code != NRF_SUCCESS)
+ {
+ continue;
+ }
+
+ // Activity detected on current transport, close all except active one.
+ (void) nrf_dfu_transports_close(&usb_dfu_transport);
+
+ nrf_dfu_serial_on_packet_received(p_transport,
+ (uint8_t const *)(m_slip.p_buffer),
+ m_slip.current_index);
+
+ uint8_t * p_rx_buf = nrf_balloc_alloc(&m_payload_pool);
+ if (p_rx_buf == NULL)
+ {
+ NRF_LOG_ERROR("Failed to allocate buffer!");
+ return;
+ }
+
+ NRF_LOG_DEBUG("Allocated buffer %x", p_rx_buf);
+ // reset the slip decoding
+ m_slip.p_buffer = &p_rx_buf[OPCODE_OFFSET];
+ m_slip.current_index = 0;
+ m_slip.state = SLIP_STATE_DECODING;
+ }
+}
+
+/**
+ * @brief User event handler @ref app_usbd_cdc_acm_user_ev_handler_t (headphones)
+ * */
+static void cdc_acm_user_ev_handler(app_usbd_class_inst_t const * p_inst,
+ app_usbd_cdc_acm_user_event_t event)
+{
+ ret_code_t ret_code;
+
+ switch (event)
+ {
+ case APP_USBD_CDC_ACM_USER_EVT_PORT_OPEN:
+ {
+ ret_code = app_usbd_cdc_acm_read(&m_app_cdc_acm, m_rx_buf, 1);
+ NRF_LOG_WARNING("Could not read from CDC. Error: 0x%x.", ret_code);
+ } break;
+
+ case APP_USBD_CDC_ACM_USER_EVT_RX_DONE:
+ {
+ do
+ {
+ on_rx_complete(&m_serial, m_rx_buf, 1);
+ ret_code = app_usbd_cdc_acm_read(&m_app_cdc_acm, m_rx_buf, 1);
+ } while (ret_code == NRF_SUCCESS);
+ } break;
+
+ default:
+ break;
+ }
+}
+
+
+static void usbd_dfu_transport_ev_handler(app_usbd_event_type_t event)
+{
+ switch (event)
+ {
+ case APP_USBD_EVT_STOPPED:
+ app_usbd_disable();
+ break;
+
+ case APP_USBD_EVT_POWER_DETECTED:
+ NRF_LOG_INFO("USB power detected");
+ if (!nrf_drv_usbd_is_enabled())
+ {
+ app_usbd_enable();
+ }
+
+ if (m_observer)
+ {
+ m_observer(NRF_DFU_EVT_TRANSPORT_ACTIVATED);
+ }
+ break;
+
+ case APP_USBD_EVT_POWER_REMOVED:
+ NRF_LOG_INFO("USB power removed");
+ app_usbd_stop();
+ if (m_observer)
+ {
+ m_observer(NRF_DFU_EVT_TRANSPORT_DEACTIVATED);
+ }
+ break;
+
+ case APP_USBD_EVT_POWER_READY:
+ NRF_LOG_INFO("USB ready");
+ app_usbd_start();
+ break;
+
+ default:
+ break;
+ }
+}
+
+
+static void usbd_sched_event_handler(void * p_event_data, uint16_t event_size)
+{
+ app_usbd_event_execute(p_event_data);
+}
+
+
+static void usbd_event_handler(app_usbd_internal_evt_t const * const p_event)
+{
+ ret_code_t ret_code;
+ if (p_event->type == APP_USBD_EVT_DRV_SOF)
+ {
+ app_usbd_event_execute(p_event);
+ }
+ else
+ {
+ ret_code = app_sched_event_put(p_event,
+ sizeof(app_usbd_internal_evt_t),
+ usbd_sched_event_handler);
+
+ if (ret_code != NRF_SUCCESS)
+ {
+ NRF_LOG_ERROR("Could not schedule USB event!");
+ }
+ }
+}
+
+
+static uint32_t usb_dfu_transport_init(nrf_dfu_observer_t observer)
+{
+ uint32_t err_code;
+
+ /* Execute event directly in interrupt handler */
+ static const app_usbd_config_t usbd_config =
+ {
+ .ev_handler = usbd_event_handler,
+ .ev_state_proc = usbd_dfu_transport_ev_handler
+ };
+
+ (void) nrf_balloc_init(&m_payload_pool); //Result is checked by checking result of _alloc().
+
+ m_observer = observer;
+
+ uint8_t * p_rx_buf = nrf_balloc_alloc(&m_payload_pool);
+ if (p_rx_buf == NULL)
+ {
+ NRF_LOG_ERROR("Could not allocate payload pool.");
+ return NRF_ERROR_INTERNAL;
+ }
+
+ m_slip.p_buffer = &p_rx_buf[OPCODE_OFFSET];
+ m_slip.current_index = 0;
+ m_slip.buffer_len = SLIP_MTU;
+ m_slip.state = SLIP_STATE_DECODING;
+
+ m_serial.rsp_func = rsp_send;
+ m_serial.payload_free_func = payload_free;
+ m_serial.mtu = SLIP_MTU;
+ m_serial.p_rsp_buf = &m_rsp_buf[NRF_USB_MAX_RESPONSE_SIZE_SLIP -
+ NRF_SERIAL_MAX_RESPONSE_SIZE];
+
+
+ NRF_LOG_DEBUG("Initializing drivers.");
+
+ err_code = nrf_drv_clock_init();
+ if (err_code != NRF_ERROR_MODULE_ALREADY_INITIALIZED)
+ {
+ VERIFY_SUCCESS(err_code);
+ }
+
+ err_code = nrf_drv_power_init(NULL);
+ VERIFY_SUCCESS(err_code);
+
+ app_usbd_serial_num_generate();
+
+ err_code = app_usbd_init(&usbd_config);
+ VERIFY_SUCCESS(err_code);
+
+ app_usbd_class_inst_t const * class_cdc_acm = app_usbd_cdc_acm_class_inst_get(&m_app_cdc_acm);
+ err_code = app_usbd_class_append(class_cdc_acm);
+ VERIFY_SUCCESS(err_code);
+
+ NRF_LOG_DEBUG("Starting USB");
+
+ if (USBD_POWER_DETECTION)
+ {
+ err_code = app_usbd_power_events_enable();
+ VERIFY_SUCCESS(err_code);
+ }
+ else
+ {
+ NRF_LOG_DEBUG("No USB power detection enabled, starting USB now");
+
+ app_usbd_enable();
+ app_usbd_start();
+ }
+
+ NRF_LOG_DEBUG("USB Transport initialized");
+
+ return err_code;
+}
+
+
+static uint32_t usb_dfu_transport_close(nrf_dfu_transport_t const * p_exception)
+{
+ return NRF_SUCCESS;
+}
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bsp/bsp.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bsp/bsp.c
new file mode 100644
index 0000000..3bf4d00
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bsp/bsp.c
@@ -0,0 +1,637 @@
+/**
+ * Copyright (c) 2014 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#include "bsp.h"
+#include <stddef.h>
+#include <stdio.h>
+#include "nordic_common.h"
+#include "nrf.h"
+#include "nrf_gpio.h"
+#include "nrf_error.h"
+#include "bsp_config.h"
+#include "boards.h"
+
+#ifndef BSP_SIMPLE
+#include "app_timer.h"
+#include "app_button.h"
+#endif // BSP_SIMPLE
+
+#if LEDS_NUMBER > 0 && !(defined BSP_SIMPLE)
+static bsp_indication_t m_stable_state = BSP_INDICATE_IDLE;
+static bool m_leds_clear = false;
+static uint32_t m_indication_type = 0;
+static bool m_alert_on = false;
+APP_TIMER_DEF(m_bsp_leds_tmr);
+APP_TIMER_DEF(m_bsp_alert_tmr);
+#endif // LEDS_NUMBER > 0 && !(defined BSP_SIMPLE)
+
+#if BUTTONS_NUMBER > 0
+#ifndef BSP_SIMPLE
+static bsp_event_callback_t m_registered_callback = NULL;
+static bsp_button_event_cfg_t m_events_list[BUTTONS_NUMBER] = {{BSP_EVENT_NOTHING, BSP_EVENT_NOTHING}};
+APP_TIMER_DEF(m_bsp_button_tmr);
+static void bsp_button_event_handler(uint8_t pin_no, uint8_t button_action);
+#endif // BSP_SIMPLE
+
+#ifndef BSP_SIMPLE
+static const app_button_cfg_t app_buttons[BUTTONS_NUMBER] =
+{
+ #ifdef BSP_BUTTON_0
+ {BSP_BUTTON_0, false, BUTTON_PULL, bsp_button_event_handler},
+ #endif // BUTTON_0
+
+ #ifdef BSP_BUTTON_1
+ {BSP_BUTTON_1, false, BUTTON_PULL, bsp_button_event_handler},
+ #endif // BUTTON_1
+
+ #ifdef BSP_BUTTON_2
+ {BSP_BUTTON_2, false, BUTTON_PULL, bsp_button_event_handler},
+ #endif // BUTTON_2
+
+ #ifdef BSP_BUTTON_3
+ {BSP_BUTTON_3, false, BUTTON_PULL, bsp_button_event_handler},
+ #endif // BUTTON_3
+
+ #ifdef BSP_BUTTON_4
+ {BSP_BUTTON_4, false, BUTTON_PULL, bsp_button_event_handler},
+ #endif // BUTTON_4
+
+ #ifdef BSP_BUTTON_5
+ {BSP_BUTTON_5, false, BUTTON_PULL, bsp_button_event_handler},
+ #endif // BUTTON_5
+
+ #ifdef BSP_BUTTON_6
+ {BSP_BUTTON_6, false, BUTTON_PULL, bsp_button_event_handler},
+ #endif // BUTTON_6
+
+ #ifdef BSP_BUTTON_7
+ {BSP_BUTTON_7, false, BUTTON_PULL, bsp_button_event_handler},
+ #endif // BUTTON_7
+
+};
+#endif // BSP_SIMPLE
+#endif // BUTTONS_NUMBER > 0
+
+#if (BUTTONS_NUMBER > 0)
+bool bsp_button_is_pressed(uint32_t button)
+{
+ if (button < BUTTONS_NUMBER)
+ {
+ return bsp_board_button_state_get(button);
+ }
+ else
+ {
+ //If button is not present always return false
+ return false;
+ }
+}
+#endif
+
+#if (BUTTONS_NUMBER > 0) && !(defined BSP_SIMPLE)
+/**@brief Function for handling button events.
+ *
+ * @param[in] pin_no The pin number of the button pressed.
+ * @param[in] button_action Action button.
+ */
+static void bsp_button_event_handler(uint8_t pin_no, uint8_t button_action)
+{
+ bsp_event_t event = BSP_EVENT_NOTHING;
+ uint32_t button = 0;
+ uint32_t err_code;
+ static uint8_t current_long_push_pin_no; /**< Pin number of a currently pushed button, that could become a long push if held long enough. */
+ static bsp_event_t release_event_at_push[BUTTONS_NUMBER]; /**< Array of what the release event of each button was last time it was pushed, so that no release event is sent if the event was bound after the push of the button. */
+
+ button = bsp_board_pin_to_button_idx(pin_no);
+
+ if (button < BUTTONS_NUMBER)
+ {
+ switch (button_action)
+ {
+ case APP_BUTTON_PUSH:
+ event = m_events_list[button].push_event;
+ if (m_events_list[button].long_push_event != BSP_EVENT_NOTHING)
+ {
+ err_code = app_timer_start(m_bsp_button_tmr, APP_TIMER_TICKS(BSP_LONG_PUSH_TIMEOUT_MS), (void*)&current_long_push_pin_no);
+ if (err_code == NRF_SUCCESS)
+ {
+ current_long_push_pin_no = pin_no;
+ }
+ }
+ release_event_at_push[button] = m_events_list[button].release_event;
+ break;
+ case APP_BUTTON_RELEASE:
+ (void)app_timer_stop(m_bsp_button_tmr);
+ if (release_event_at_push[button] == m_events_list[button].release_event)
+ {
+ event = m_events_list[button].release_event;
+ }
+ break;
+ case BSP_BUTTON_ACTION_LONG_PUSH:
+ event = m_events_list[button].long_push_event;
+ }
+ }
+
+ if ((event != BSP_EVENT_NOTHING) && (m_registered_callback != NULL))
+ {
+ m_registered_callback(event);
+ }
+}
+
+/**@brief Handle events from button timer.
+ *
+ * @param[in] p_context parameter registered in timer start function.
+ */
+static void button_timer_handler(void * p_context)
+{
+ bsp_button_event_handler(*(uint8_t *)p_context, BSP_BUTTON_ACTION_LONG_PUSH);
+}
+
+
+#endif // (BUTTONS_NUMBER > 0) && !(defined BSP_SIMPLE)
+
+
+#if LEDS_NUMBER > 0 && !(defined BSP_SIMPLE)
+static void leds_off(void)
+{
+ if (m_alert_on)
+ {
+ uint32_t i;
+ for (i = 0; i < LEDS_NUMBER; i++)
+ {
+ if (i != BSP_LED_ALERT)
+ {
+ bsp_board_led_off(i);
+ }
+ }
+ }
+ else
+ {
+ bsp_board_leds_off();
+ }
+}
+
+
+/**@brief Configure leds to indicate required state.
+ * @param[in] indicate State to be indicated.
+ */
+static uint32_t bsp_led_indication(bsp_indication_t indicate)
+{
+ uint32_t err_code = NRF_SUCCESS;
+ uint32_t next_delay = 0;
+
+ if (m_leds_clear)
+ {
+ m_leds_clear = false;
+ leds_off();
+ }
+
+ switch (indicate)
+ {
+ case BSP_INDICATE_IDLE:
+ leds_off();
+ m_stable_state = indicate;
+ break;
+
+ case BSP_INDICATE_SCANNING:
+ case BSP_INDICATE_ADVERTISING:
+ // in advertising blink LED_0
+ if (bsp_board_led_state_get(BSP_LED_INDICATE_INDICATE_ADVERTISING))
+ {
+ bsp_board_led_off(BSP_LED_INDICATE_INDICATE_ADVERTISING);
+ next_delay = indicate ==
+ BSP_INDICATE_ADVERTISING ? ADVERTISING_LED_OFF_INTERVAL :
+ ADVERTISING_SLOW_LED_OFF_INTERVAL;
+ }
+ else
+ {
+ bsp_board_led_on(BSP_LED_INDICATE_INDICATE_ADVERTISING);
+ next_delay = indicate ==
+ BSP_INDICATE_ADVERTISING ? ADVERTISING_LED_ON_INTERVAL :
+ ADVERTISING_SLOW_LED_ON_INTERVAL;
+ }
+
+ m_stable_state = indicate;
+ err_code = app_timer_start(m_bsp_leds_tmr, APP_TIMER_TICKS(next_delay), NULL);
+ break;
+
+ case BSP_INDICATE_ADVERTISING_WHITELIST:
+ // in advertising quickly blink LED_0
+ if (bsp_board_led_state_get(BSP_LED_INDICATE_ADVERTISING_WHITELIST))
+ {
+ bsp_board_led_off(BSP_LED_INDICATE_ADVERTISING_WHITELIST);
+ next_delay = indicate ==
+ BSP_INDICATE_ADVERTISING_WHITELIST ?
+ ADVERTISING_WHITELIST_LED_OFF_INTERVAL :
+ ADVERTISING_SLOW_LED_OFF_INTERVAL;
+ }
+ else
+ {
+ bsp_board_led_on(BSP_LED_INDICATE_ADVERTISING_WHITELIST);
+ next_delay = indicate ==
+ BSP_INDICATE_ADVERTISING_WHITELIST ?
+ ADVERTISING_WHITELIST_LED_ON_INTERVAL :
+ ADVERTISING_SLOW_LED_ON_INTERVAL;
+ }
+ m_stable_state = indicate;
+ err_code = app_timer_start(m_bsp_leds_tmr, APP_TIMER_TICKS(next_delay), NULL);
+ break;
+
+ case BSP_INDICATE_ADVERTISING_SLOW:
+ // in advertising slowly blink LED_0
+ if (bsp_board_led_state_get(BSP_LED_INDICATE_ADVERTISING_SLOW))
+ {
+ bsp_board_led_off(BSP_LED_INDICATE_ADVERTISING_SLOW);
+ next_delay = indicate ==
+ BSP_INDICATE_ADVERTISING_SLOW ? ADVERTISING_SLOW_LED_OFF_INTERVAL :
+ ADVERTISING_SLOW_LED_OFF_INTERVAL;
+ }
+ else
+ {
+ bsp_board_led_on(BSP_LED_INDICATE_ADVERTISING_SLOW);
+ next_delay = indicate ==
+ BSP_INDICATE_ADVERTISING_SLOW ? ADVERTISING_SLOW_LED_ON_INTERVAL :
+ ADVERTISING_SLOW_LED_ON_INTERVAL;
+ }
+ m_stable_state = indicate;
+ err_code = app_timer_start(m_bsp_leds_tmr, APP_TIMER_TICKS(next_delay), NULL);
+ break;
+
+ case BSP_INDICATE_ADVERTISING_DIRECTED:
+ // in advertising very quickly blink LED_0
+ if (bsp_board_led_state_get(BSP_LED_INDICATE_ADVERTISING_DIRECTED))
+ {
+ bsp_board_led_off(BSP_LED_INDICATE_ADVERTISING_DIRECTED);
+ next_delay = indicate ==
+ BSP_INDICATE_ADVERTISING_DIRECTED ?
+ ADVERTISING_DIRECTED_LED_OFF_INTERVAL :
+ ADVERTISING_SLOW_LED_OFF_INTERVAL;
+ }
+ else
+ {
+ bsp_board_led_on(BSP_LED_INDICATE_ADVERTISING_DIRECTED);
+ next_delay = indicate ==
+ BSP_INDICATE_ADVERTISING_DIRECTED ?
+ ADVERTISING_DIRECTED_LED_ON_INTERVAL :
+ ADVERTISING_SLOW_LED_ON_INTERVAL;
+ }
+ m_stable_state = indicate;
+ err_code = app_timer_start(m_bsp_leds_tmr, APP_TIMER_TICKS(next_delay), NULL);
+ break;
+
+ case BSP_INDICATE_BONDING:
+ // in bonding fast blink LED_0
+ bsp_board_led_invert(BSP_LED_INDICATE_BONDING);
+
+ m_stable_state = indicate;
+ err_code =
+ app_timer_start(m_bsp_leds_tmr, APP_TIMER_TICKS(BONDING_INTERVAL), NULL);
+ break;
+
+ case BSP_INDICATE_CONNECTED:
+ bsp_board_led_on(BSP_LED_INDICATE_CONNECTED);
+ m_stable_state = indicate;
+ break;
+
+ case BSP_INDICATE_SENT_OK:
+ // when sending shortly invert LED_1
+ m_leds_clear = true;
+ bsp_board_led_invert(BSP_LED_INDICATE_SENT_OK);
+ err_code = app_timer_start(m_bsp_leds_tmr, APP_TIMER_TICKS(SENT_OK_INTERVAL), NULL);
+ break;
+
+ case BSP_INDICATE_SEND_ERROR:
+ // on receving error invert LED_1 for long time
+ m_leds_clear = true;
+ bsp_board_led_invert(BSP_LED_INDICATE_SEND_ERROR);
+ err_code = app_timer_start(m_bsp_leds_tmr, APP_TIMER_TICKS(SEND_ERROR_INTERVAL), NULL);
+ break;
+
+ case BSP_INDICATE_RCV_OK:
+ // when receving shortly invert LED_1
+ m_leds_clear = true;
+ bsp_board_led_invert(BSP_LED_INDICATE_RCV_OK);
+ err_code = app_timer_start(m_bsp_leds_tmr, APP_TIMER_TICKS(RCV_OK_INTERVAL), NULL);
+ break;
+
+ case BSP_INDICATE_RCV_ERROR:
+ // on receving error invert LED_1 for long time
+ m_leds_clear = true;
+ bsp_board_led_invert(BSP_LED_INDICATE_RCV_ERROR);
+ err_code = app_timer_start(m_bsp_leds_tmr, APP_TIMER_TICKS(RCV_ERROR_INTERVAL), NULL);
+ break;
+
+ case BSP_INDICATE_FATAL_ERROR:
+ // on fatal error turn on all leds
+ bsp_board_leds_on();
+ m_stable_state = indicate;
+ break;
+
+ case BSP_INDICATE_ALERT_0:
+ case BSP_INDICATE_ALERT_1:
+ case BSP_INDICATE_ALERT_2:
+ case BSP_INDICATE_ALERT_3:
+ case BSP_INDICATE_ALERT_OFF:
+ err_code = app_timer_stop(m_bsp_alert_tmr);
+ next_delay = (uint32_t)BSP_INDICATE_ALERT_OFF - (uint32_t)indicate;
+
+ // a little trick to find out that if it did not fall through ALERT_OFF
+ if (next_delay && (err_code == NRF_SUCCESS))
+ {
+ if (next_delay > 1)
+ {
+ err_code = app_timer_start(m_bsp_alert_tmr,
+ APP_TIMER_TICKS(((uint16_t)next_delay * ALERT_INTERVAL)),
+ NULL);
+ }
+ bsp_board_led_on(BSP_LED_ALERT);
+ m_alert_on = true;
+ }
+ else
+ {
+ bsp_board_led_off(BSP_LED_ALERT);
+ m_alert_on = false;
+
+ }
+ break;
+
+ case BSP_INDICATE_USER_STATE_OFF:
+ leds_off();
+ m_stable_state = indicate;
+ break;
+
+ case BSP_INDICATE_USER_STATE_0:
+ leds_off();
+ bsp_board_led_on(BSP_LED_INDICATE_USER_LED1);
+ m_stable_state = indicate;
+ break;
+
+ case BSP_INDICATE_USER_STATE_1:
+ leds_off();
+ bsp_board_led_on(BSP_LED_INDICATE_USER_LED2);
+ m_stable_state = indicate;
+ break;
+
+ case BSP_INDICATE_USER_STATE_2:
+ leds_off();
+ bsp_board_led_on(BSP_LED_INDICATE_USER_LED1);
+ bsp_board_led_on(BSP_LED_INDICATE_USER_LED2);
+ m_stable_state = indicate;
+ break;
+
+ case BSP_INDICATE_USER_STATE_3:
+
+ case BSP_INDICATE_USER_STATE_ON:
+ bsp_board_leds_on();
+ m_stable_state = indicate;
+ break;
+
+ default:
+ break;
+ }
+
+ return err_code;
+}
+
+
+/**@brief Handle events from leds timer.
+ *
+ * @note Timer handler does not support returning an error code.
+ * Errors from bsp_led_indication() are not propagated.
+ *
+ * @param[in] p_context parameter registered in timer start function.
+ */
+static void leds_timer_handler(void * p_context)
+{
+ UNUSED_PARAMETER(p_context);
+
+ if (m_indication_type & BSP_INIT_LEDS)
+ {
+ UNUSED_VARIABLE(bsp_led_indication(m_stable_state));
+ }
+}
+
+
+/**@brief Handle events from alert timer.
+ *
+ * @param[in] p_context parameter registered in timer start function.
+ */
+static void alert_timer_handler(void * p_context)
+{
+ UNUSED_PARAMETER(p_context);
+ bsp_board_led_invert(BSP_LED_ALERT);
+}
+#endif // #if LEDS_NUMBER > 0 && !(defined BSP_SIMPLE)
+
+
+/**@brief Configure indicators to required state.
+ */
+uint32_t bsp_indication_set(bsp_indication_t indicate)
+{
+ uint32_t err_code = NRF_SUCCESS;
+
+#if LEDS_NUMBER > 0 && !(defined BSP_SIMPLE)
+
+ if (m_indication_type & BSP_INIT_LEDS)
+ {
+ err_code = bsp_led_indication(indicate);
+ }
+
+#endif // LEDS_NUMBER > 0 && !(defined BSP_SIMPLE)
+ return err_code;
+}
+
+
+uint32_t bsp_init(uint32_t type, bsp_event_callback_t callback)
+{
+ uint32_t err_code = NRF_SUCCESS;
+
+#if LEDS_NUMBER > 0 && !(defined BSP_SIMPLE)
+ m_indication_type = type;
+#endif // LEDS_NUMBER > 0 && !(defined BSP_SIMPLE)
+
+#if (BUTTONS_NUMBER > 0) && !(defined BSP_SIMPLE)
+ m_registered_callback = callback;
+
+ // BSP will support buttons and generate events
+ if (type & BSP_INIT_BUTTONS)
+ {
+ uint32_t num;
+
+ for (num = 0; ((num < BUTTONS_NUMBER) && (err_code == NRF_SUCCESS)); num++)
+ {
+ err_code = bsp_event_to_button_action_assign(num, BSP_BUTTON_ACTION_PUSH, BSP_EVENT_DEFAULT);
+ }
+
+ if (err_code == NRF_SUCCESS)
+ {
+ err_code = app_button_init((app_button_cfg_t *)app_buttons,
+ BUTTONS_NUMBER,
+ APP_TIMER_TICKS(50));
+ }
+
+ if (err_code == NRF_SUCCESS)
+ {
+ err_code = app_button_enable();
+ }
+
+ if (err_code == NRF_SUCCESS)
+ {
+ err_code = app_timer_create(&m_bsp_button_tmr,
+ APP_TIMER_MODE_SINGLE_SHOT,
+ button_timer_handler);
+ }
+ }
+#elif (BUTTONS_NUMBER > 0) && (defined BSP_SIMPLE)
+ bsp_board_init(type);
+#endif // (BUTTONS_NUMBER > 0) && !(defined BSP_SIMPLE)
+
+#if LEDS_NUMBER > 0 && !(defined BSP_SIMPLE)
+ if (type & BSP_INIT_LEDS)
+ {
+ //handle LEDs only. Buttons are already handled.
+ bsp_board_init(BSP_INIT_LEDS);
+
+ // timers module must be already initialized!
+ if (err_code == NRF_SUCCESS)
+ {
+ err_code =
+ app_timer_create(&m_bsp_leds_tmr, APP_TIMER_MODE_SINGLE_SHOT, leds_timer_handler);
+ }
+
+ if (err_code == NRF_SUCCESS)
+ {
+ err_code =
+ app_timer_create(&m_bsp_alert_tmr, APP_TIMER_MODE_REPEATED, alert_timer_handler);
+ }
+ }
+#endif // LEDS_NUMBER > 0 && !(defined BSP_SIMPLE)
+
+ return err_code;
+}
+
+
+#ifndef BSP_SIMPLE
+/**@brief Assign specific event to button.
+ */
+uint32_t bsp_event_to_button_action_assign(uint32_t button, bsp_button_action_t action, bsp_event_t event)
+{
+ uint32_t err_code = NRF_SUCCESS;
+
+#if BUTTONS_NUMBER > 0
+ if (button < BUTTONS_NUMBER)
+ {
+ if (event == BSP_EVENT_DEFAULT)
+ {
+ // Setting default action: BSP_EVENT_KEY_x for PUSH actions, BSP_EVENT_NOTHING for RELEASE and LONG_PUSH actions.
+ event = (action == BSP_BUTTON_ACTION_PUSH) ? (bsp_event_t)(BSP_EVENT_KEY_0 + button) : BSP_EVENT_NOTHING;
+ }
+ switch (action)
+ {
+ case BSP_BUTTON_ACTION_PUSH:
+ m_events_list[button].push_event = event;
+ break;
+ case BSP_BUTTON_ACTION_LONG_PUSH:
+ m_events_list[button].long_push_event = event;
+ break;
+ case BSP_BUTTON_ACTION_RELEASE:
+ m_events_list[button].release_event = event;
+ break;
+ default:
+ err_code = NRF_ERROR_INVALID_PARAM;
+ break;
+ }
+ }
+ else
+ {
+ err_code = NRF_ERROR_INVALID_PARAM;
+ }
+#else
+ err_code = NRF_ERROR_INVALID_PARAM;
+#endif // BUTTONS_NUMBER > 0
+
+ return err_code;
+}
+
+#endif // BSP_SIMPLE
+
+
+uint32_t bsp_buttons_enable()
+{
+#if (BUTTONS_NUMBER > 0) && !defined(BSP_SIMPLE)
+ return app_button_enable();
+#else
+ return NRF_ERROR_NOT_SUPPORTED;
+#endif
+}
+
+uint32_t bsp_buttons_disable()
+{
+#if (BUTTONS_NUMBER > 0) && !defined(BSP_SIMPLE)
+ return app_button_disable();
+#else
+ return NRF_ERROR_NOT_SUPPORTED;
+#endif
+}
+static uint32_t wakeup_button_cfg(uint32_t button_idx, bool enable)
+{
+#if !defined(BSP_SIMPLE)
+ if (button_idx < BUTTONS_NUMBER)
+ {
+ nrf_gpio_pin_sense_t sense = enable ?
+ (BUTTONS_ACTIVE_STATE ? NRF_GPIO_PIN_SENSE_HIGH : NRF_GPIO_PIN_SENSE_LOW) :
+ NRF_GPIO_PIN_NOSENSE;
+ nrf_gpio_cfg_sense_set(bsp_board_button_idx_to_pin(button_idx), sense);
+ return NRF_SUCCESS;
+ }
+#else
+ UNUSED_PARAMETER(button_idx);
+ UNUSED_PARAMETER(enable);
+#endif
+ return NRF_ERROR_NOT_SUPPORTED;
+
+}
+uint32_t bsp_wakeup_button_enable(uint32_t button_idx)
+{
+ return wakeup_button_cfg(button_idx, true);
+}
+
+uint32_t bsp_wakeup_button_disable(uint32_t button_idx)
+{
+ return wakeup_button_cfg(button_idx, false);
+}
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bsp/bsp.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bsp/bsp.h
new file mode 100644
index 0000000..904a3d4
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bsp/bsp.h
@@ -0,0 +1,307 @@
+/**
+ * Copyright (c) 2014 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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
+ *
+ * @defgroup bsp Board Support Package
+ * @{
+ * @ingroup app_common
+ *
+ * @brief BSP module.
+ * @details This module provides a layer of abstraction from the board.
+ * It allows the user to indicate certain states on LEDs in a simple way.
+ * Module functionality can be modified by defining BSP_SIMPLE to reduce
+ * functionality of this module to enable and read state of the buttons.
+ */
+
+#ifndef BSP_H__
+#define BSP_H__
+
+#include <stdint.h>
+#include <stdbool.h>
+#include "boards.h"
+
+#if !defined(BSP_DEFINES_ONLY) && !defined(BSP_SIMPLE)
+#include "app_button.h"
+
+#define BSP_BUTTON_ACTION_PUSH (APP_BUTTON_PUSH) /**< Represents pushing a button. See @ref bsp_button_action_t. */
+#define BSP_BUTTON_ACTION_RELEASE (APP_BUTTON_RELEASE) /**< Represents releasing a button. See @ref bsp_button_action_t. */
+#define BSP_BUTTON_ACTION_LONG_PUSH (2) /**< Represents pushing and holding a button for @ref BSP_LONG_PUSH_TIMEOUT_MS milliseconds. See also @ref bsp_button_action_t. */
+
+#endif
+
+/* BSP_UART_SUPPORT
+ * This define enables UART support module.
+ */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef uint8_t bsp_button_action_t; /**< The different actions that can be performed on a button. */
+
+#define BSP_INDICATIONS_LIST { \
+ "BSP_INDICATE_IDLE", \
+ "BSP_INDICATE_SCANNING", \
+ "BSP_INDICATE_ADVERTISING", \
+ "BSP_INDICATE_ADVERTISING_WHITELIST", \
+ "BSP_INDICATE_ADVERTISING_SLOW", \
+ "BSP_INDICATE_ADVERTISING_DIRECTED", \
+ "BSP_INDICATE_BONDING", \
+ "BSP_INDICATE_CONNECTED", \
+ "BSP_INDICATE_SENT_OK", \
+ "BSP_INDICATE_SEND_ERROR", \
+ "BSP_INDICATE_RCV_OK", \
+ "BSP_INDICATE_RCV_ERROR", \
+ "BSP_INDICATE_FATAL_ERROR", \
+ "BSP_INDICATE_ALERT_0", \
+ "BSP_INDICATE_ALERT_1", \
+ "BSP_INDICATE_ALERT_2", \
+ "BSP_INDICATE_ALERT_3", \
+ "BSP_INDICATE_ALERT_OFF", \
+ "BSP_INDICATE_USER_STATE_OFF", \
+ "BSP_INDICATE_USER_STATE_0", \
+ "BSP_INDICATE_USER_STATE_1", \
+ "BSP_INDICATE_USER_STATE_2", \
+ "BSP_INDICATE_USER_STATE_3", \
+ "BSP_INDICATE_USER_STATE_ON" \
+} /**< See @ref examples_bsp_states for a list of how these states are indicated for the PCA10028/PCA10040 board and the PCA10031 dongle.*/
+
+
+/**@brief BSP indication states.
+ *
+ * @details See @ref examples_bsp_states for a list of how these states are indicated for the PCA10028/PCA10040 board and the PCA10031 dongle.
+ */
+typedef enum
+{
+ BSP_INDICATE_FIRST = 0,
+ BSP_INDICATE_IDLE = BSP_INDICATE_FIRST, /**< See \ref BSP_INDICATE_IDLE.*/
+ BSP_INDICATE_SCANNING, /**< See \ref BSP_INDICATE_SCANNING.*/
+ BSP_INDICATE_ADVERTISING, /**< See \ref BSP_INDICATE_ADVERTISING.*/
+ BSP_INDICATE_ADVERTISING_WHITELIST, /**< See \ref BSP_INDICATE_ADVERTISING_WHITELIST.*/
+ BSP_INDICATE_ADVERTISING_SLOW, /**< See \ref BSP_INDICATE_ADVERTISING_SLOW.*/
+ BSP_INDICATE_ADVERTISING_DIRECTED, /**< See \ref BSP_INDICATE_ADVERTISING_DIRECTED.*/
+ BSP_INDICATE_BONDING, /**< See \ref BSP_INDICATE_BONDING.*/
+ BSP_INDICATE_CONNECTED, /**< See \ref BSP_INDICATE_CONNECTED.*/
+ BSP_INDICATE_SENT_OK, /**< See \ref BSP_INDICATE_SENT_OK.*/
+ BSP_INDICATE_SEND_ERROR, /**< See \ref BSP_INDICATE_SEND_ERROR.*/
+ BSP_INDICATE_RCV_OK, /**< See \ref BSP_INDICATE_RCV_OK.*/
+ BSP_INDICATE_RCV_ERROR, /**< See \ref BSP_INDICATE_RCV_ERROR.*/
+ BSP_INDICATE_FATAL_ERROR, /**< See \ref BSP_INDICATE_FATAL_ERROR.*/
+ BSP_INDICATE_ALERT_0, /**< See \ref BSP_INDICATE_ALERT_0.*/
+ BSP_INDICATE_ALERT_1, /**< See \ref BSP_INDICATE_ALERT_1.*/
+ BSP_INDICATE_ALERT_2, /**< See \ref BSP_INDICATE_ALERT_2.*/
+ BSP_INDICATE_ALERT_3, /**< See \ref BSP_INDICATE_ALERT_3.*/
+ BSP_INDICATE_ALERT_OFF, /**< See \ref BSP_INDICATE_ALERT_OFF.*/
+ BSP_INDICATE_USER_STATE_OFF, /**< See \ref BSP_INDICATE_USER_STATE_OFF.*/
+ BSP_INDICATE_USER_STATE_0, /**< See \ref BSP_INDICATE_USER_STATE_0.*/
+ BSP_INDICATE_USER_STATE_1, /**< See \ref BSP_INDICATE_USER_STATE_1.*/
+ BSP_INDICATE_USER_STATE_2, /**< See \ref BSP_INDICATE_USER_STATE_2.*/
+ BSP_INDICATE_USER_STATE_3, /**< See \ref BSP_INDICATE_USER_STATE_3.*/
+ BSP_INDICATE_USER_STATE_ON, /**< See \ref BSP_INDICATE_USER_STATE_ON.*/
+ BSP_INDICATE_LAST = BSP_INDICATE_USER_STATE_ON
+} bsp_indication_t;
+
+/**@brief BSP events.
+ *
+ * @note Events from BSP_EVENT_KEY_0 to BSP_EVENT_KEY_LAST are by default assigned to buttons.
+ */
+typedef enum
+{
+ BSP_EVENT_NOTHING = 0, /**< Assign this event to an action to prevent the action from generating an event (disable the action). */
+ BSP_EVENT_DEFAULT, /**< Assign this event to an action to assign the default event to the action. */
+ BSP_EVENT_CLEAR_BONDING_DATA, /**< Persistent bonding data should be erased. */
+ BSP_EVENT_CLEAR_ALERT, /**< An alert should be cleared. */
+ BSP_EVENT_DISCONNECT, /**< A link should be disconnected. */
+ BSP_EVENT_ADVERTISING_START, /**< The device should start advertising. */
+ BSP_EVENT_ADVERTISING_STOP, /**< The device should stop advertising. */
+ BSP_EVENT_WHITELIST_OFF, /**< The device should remove its advertising whitelist. */
+ BSP_EVENT_BOND, /**< The device should bond to the currently connected peer. */
+ BSP_EVENT_RESET, /**< The device should reset. */
+ BSP_EVENT_SLEEP, /**< The device should enter sleep mode. */
+ BSP_EVENT_WAKEUP, /**< The device should wake up from sleep mode. */
+ BSP_EVENT_SYSOFF, /**< The device should enter system off mode (without wakeup). */
+ BSP_EVENT_DFU, /**< The device should enter DFU mode. */
+ BSP_EVENT_KEY_0, /**< Default event of the push action of BSP_BUTTON_0 (only if this button is present). */
+ BSP_EVENT_KEY_1, /**< Default event of the push action of BSP_BUTTON_1 (only if this button is present). */
+ BSP_EVENT_KEY_2, /**< Default event of the push action of BSP_BUTTON_2 (only if this button is present). */
+ BSP_EVENT_KEY_3, /**< Default event of the push action of BSP_BUTTON_3 (only if this button is present). */
+ BSP_EVENT_KEY_4, /**< Default event of the push action of BSP_BUTTON_4 (only if this button is present). */
+ BSP_EVENT_KEY_5, /**< Default event of the push action of BSP_BUTTON_5 (only if this button is present). */
+ BSP_EVENT_KEY_6, /**< Default event of the push action of BSP_BUTTON_6 (only if this button is present). */
+ BSP_EVENT_KEY_7, /**< Default event of the push action of BSP_BUTTON_7 (only if this button is present). */
+ BSP_EVENT_KEY_LAST = BSP_EVENT_KEY_7,
+} bsp_event_t;
+
+
+typedef struct
+{
+ bsp_event_t push_event; /**< The event to fire on regular button press. */
+ bsp_event_t long_push_event; /**< The event to fire on long button press. */
+ bsp_event_t release_event; /**< The event to fire on button release. */
+} bsp_button_event_cfg_t;
+
+/**@brief BSP module event callback function type.
+ *
+ * @details Upon an event in the BSP module, this callback function will be called to notify
+ * the application about the event.
+ *
+ * @param[in] bsp_event_t BSP event type.
+ */
+typedef void (* bsp_event_callback_t)(bsp_event_t);
+
+
+/**@brief Function for initializing BSP.
+ *
+ * @details The function initializes the board support package to allow state indication and
+ * button reaction. Default events are assigned to buttons.
+ * @note Before calling this function, you must initiate the following required modules:
+ * - @ref app_timer for LED support
+ * - @ref app_gpiote for button support
+ *
+ * @param[in] type Type of peripherals used.
+ * @param[in] callback Function to be called when button press/event is detected.
+ *
+ * @retval NRF_SUCCESS If the BSP module was successfully initialized.
+ * @retval NRF_ERROR_INVALID_STATE If the application timer module has not been initialized.
+ * @retval NRF_ERROR_NO_MEM If the maximum number of timers has already been reached.
+ * @retval NRF_ERROR_INVALID_PARAM If GPIOTE has too many users.
+ * @retval NRF_ERROR_INVALID_STATE If button or GPIOTE has not been initialized.
+ */
+uint32_t bsp_init(uint32_t type, bsp_event_callback_t callback);
+
+
+/**@brief Function for checking button states.
+ *
+ * @details This function checks if the button is pressed. If the button ID is out of range,
+ * the function returns false.
+ *
+ * @param[in] button Button ID to check.
+ *
+ * @retval true If the button is pressed.
+ * @retval false If the button is not pressed.
+ */
+bool bsp_button_is_pressed(uint32_t button);
+
+
+/**@brief Function for assigning a specific event to a button.
+ *
+ * @details This function allows redefinition of standard events assigned to buttons.
+ * To unassign events, provide the event @ref BSP_EVENT_NOTHING.
+ *
+ * @param[in] button Button ID to be redefined.
+ * @param[in] action Button action to assign event to.
+ * @param[in] event Event to be assigned to button.
+ *
+ * @retval NRF_SUCCESS If the event was successfully assigned to button.
+ * @retval NRF_ERROR_INVALID_PARAM If the button ID or button action was invalid.
+ */
+uint32_t bsp_event_to_button_action_assign(uint32_t button, bsp_button_action_t action, bsp_event_t event);
+
+
+/**@brief Function for configuring indicators to required state.
+ *
+ * @details This function indicates the required state by means of LEDs (if enabled).
+ *
+ * @note Alerts are indicated independently.
+ *
+ * @param[in] indicate State to be indicated.
+ *
+ * @retval NRF_SUCCESS If the state was successfully indicated.
+ * @retval NRF_ERROR_NO_MEM If the internal timer operations queue was full.
+ * @retval NRF_ERROR_INVALID_STATE If the application timer module has not been initialized,
+ * or internal timer has not been created.
+ */
+uint32_t bsp_indication_set(bsp_indication_t indicate);
+
+
+/**@brief Function for enabling all buttons.
+ *
+ * @details After calling this function, all buttons will generate events when pressed, and
+ * all buttons will be able to wake the system up from sleep mode.
+ *
+ * @retval NRF_SUCCESS If the buttons were successfully enabled.
+ * @retval NRF_ERROR_NOT_SUPPORTED If the board has no buttons or BSP_SIMPLE is defined.
+ * @return A propagated error.
+ */
+uint32_t bsp_buttons_enable(void);
+
+
+/**@brief Function for disabling all buttons.
+ *
+ * @details After calling this function, no buttons will generate events when pressed, and
+ * no buttons will be able to wake the system up from sleep mode.
+ *
+ * @retval NRF_SUCCESS If the buttons were successfully disabled.
+ * @retval NRF_ERROR_NOT_SUPPORTED If the board has no buttons or BSP_SIMPLE is defined.
+ * @return A propagated error.
+ */
+uint32_t bsp_buttons_disable(void);
+
+
+/**@brief Function for enabling wakeup from SYSTEM OFF for given button.
+ *
+ * @details After calling this function, button can be used to wake up the chip.
+ * This function should only be called immediately before going into sleep.
+ *
+ * @param[in] button_idx Index of the button.
+ *
+ * @retval NRF_SUCCESS If the button was successfully enabled.
+ * @retval NRF_ERROR_NOT_SUPPORTED If the board has no buttons or BSP_SIMPLE is defined.
+ */
+uint32_t bsp_wakeup_button_enable(uint32_t button_idx);
+
+
+/**@brief Function for disabling wakeup for the given button.
+ *
+ * @param[in] button_idx index of the button.
+ *
+ * @retval NRF_SUCCESS If the button was successfully disabled.
+ * @retval NRF_ERROR_NOT_SUPPORTED If the board has no buttons or BSP_SIMPLE is defined.
+ */
+uint32_t bsp_wakeup_button_disable(uint32_t button_idx);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // BSP_H__
+
+/** @} */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bsp/bsp_btn_ant.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bsp/bsp_btn_ant.c
new file mode 100644
index 0000000..6706da9
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bsp/bsp_btn_ant.c
@@ -0,0 +1,172 @@
+/**
+ * Copyright (c) 2015 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#include "sdk_common.h"
+#if NRF_MODULE_ENABLED(BSP_BTN_ANT)
+#include "bsp_btn_ant.h"
+#include "nrf_sdh_ant.h"
+#include "bsp.h"
+
+
+static bool m_connected = false; /**< Notify if channel is connected. */
+static uint8_t m_channel = UINT8_MAX; /**< ANT channel number linked to indication. */
+static uint8_t m_channel_type; /**< Type of linked ANT channel. */
+
+/**@brief Function for configuring the buttons for connection.
+ *
+ * @retval NRF_SUCCESS Configured successfully.
+ * @return A propagated error code.
+ */
+static ret_code_t connection_buttons_configure(void)
+{
+ ret_code_t err_code = bsp_event_to_button_action_assign(BSP_BTN_ANT_CONFIG_SLEEP_BTN_ID,
+ BSP_BUTTON_ACTION_RELEASE,
+ BSP_EVENT_DEFAULT);
+ if (err_code == NRF_ERROR_INVALID_PARAM)
+ {
+ return NRF_SUCCESS;
+ }
+
+ return err_code;
+}
+
+/**@brief Function for configuring the buttons for searching.
+ *
+ * @retval NRF_SUCCESS Configured successfully.
+ * @return A propagated error code.
+ */
+static ret_code_t searching_buttons_configure(void)
+{
+ ret_code_t err_code = bsp_event_to_button_action_assign(BSP_BTN_ANT_CONFIG_SLEEP_BTN_ID,
+ BSP_BUTTON_ACTION_RELEASE,
+ BSP_EVENT_SLEEP);
+ if (err_code == NRF_ERROR_INVALID_PARAM)
+ {
+ return NRF_SUCCESS;
+ }
+
+ return err_code;
+}
+
+
+ret_code_t bsp_btn_ant_sleep_mode_prepare(void)
+{
+ ret_code_t err_code = bsp_buttons_disable();
+ if (err_code != NRF_SUCCESS)
+ {
+ return err_code;
+ }
+
+ err_code = bsp_wakeup_button_enable(BSP_BTN_ANT_CONFIG_WAKEUP_BTN_ID);
+ if (err_code == NRF_ERROR_NOT_SUPPORTED)
+ {
+ return NRF_SUCCESS;
+ }
+
+ return err_code;
+}
+
+/**
+ * @brief Function for handling ANT events.
+ *
+ * @param[in] p_ant_evt Event received from the ANT stack.
+ * @param[in] p_context Context.
+ */
+static void ant_evt_handler(ant_evt_t * p_ant_evt, void * p_context)
+{
+ ret_code_t err_code = NRF_SUCCESS;
+
+ if (m_channel != p_ant_evt->channel)
+ {
+ return;
+ }
+
+ switch (m_channel_type)
+ {
+ case CHANNEL_TYPE_SLAVE:
+ /* fall through */
+ case CHANNEL_TYPE_SLAVE_RX_ONLY:
+ switch (p_ant_evt->event)
+ {
+ case EVENT_RX:
+ if (!m_connected)
+ {
+ err_code = connection_buttons_configure();
+ }
+
+ m_connected = true;
+ break;
+
+ case EVENT_RX_FAIL_GO_TO_SEARCH:
+ m_connected = false;
+
+ err_code = searching_buttons_configure();
+ break;
+
+ default:
+ break;
+ }
+ break;
+ }
+
+ APP_ERROR_CHECK(err_code);
+}
+
+NRF_SDH_ANT_OBSERVER(m_ant_observer, BSP_BTN_ANT_OBSERVER_PRIO, ant_evt_handler, NULL);
+
+ret_code_t bsp_btn_ant_init(uint8_t channel, uint8_t channel_type)
+{
+ ret_code_t err_code = NRF_SUCCESS;
+
+ m_channel = channel;
+ m_channel_type = channel_type;
+
+ if (!m_connected)
+ {
+ err_code = searching_buttons_configure();
+ }
+ else
+ {
+ err_code = connection_buttons_configure();
+ }
+
+ return err_code;
+}
+
+#endif // NRF_MODULE_ENABLED(BSP_BTN_ANT)
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bsp/bsp_btn_ant.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bsp/bsp_btn_ant.h
new file mode 100644
index 0000000..061fc72
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bsp/bsp_btn_ant.h
@@ -0,0 +1,91 @@
+/**
+ * Copyright (c) 2015 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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
+ *
+ * @defgroup bsp_btn_ant BSP: ANT Button Module
+ * @{
+ * @ingroup bsp
+ *
+ * @brief Module for controlling ANT behavior through button actions.
+ *
+ * @details The application must propagate ANT events to the ANT Button Module.
+ * Based on these events, the ANT Button Module configures the Board Support Package
+ * to generate BSP events for certain button actions. These BSP events should then be
+ * handled by the application's BSP event handler.
+ *
+ */
+
+#ifndef BSP_BTN_ANT_H__
+#define BSP_BTN_ANT_H__
+
+#include <stdint.h>
+#include "sdk_errors.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+ /**@brief Function for initializing the ANT Button Module.
+ *
+ * Before calling this function, the BSP module must be initialized with buttons.
+ *
+ * @param[in] channel ANT channel number.
+ * @param[in] channel_type ANT channel type (see Assign Channel Parameters in ant_parameters.h: @ref ant_parameters).
+ *
+ * @retval NRF_SUCCESS If initialization was successful. Otherwise, a propagated error code is
+ * returned.
+ */
+ret_code_t bsp_btn_ant_init(uint8_t channel, uint8_t channel_type);
+
+/**@brief Function for setting up wakeup buttons before going into sleep mode.
+ *
+ * @retval NRF_SUCCESS If the buttons were prepared successfully. Otherwise, a propagated error
+ * code is returned.
+ */
+ret_code_t bsp_btn_ant_sleep_mode_prepare(void);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* BSP_BTN_ANT_H__ */
+
+/** @} */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bsp/bsp_btn_ble.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bsp/bsp_btn_ble.c
new file mode 100644
index 0000000..65d7a4c
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bsp/bsp_btn_ble.c
@@ -0,0 +1,254 @@
+/**
+ * Copyright (c) 2014 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#include "bsp_btn_ble.h"
+#include "nrf_sdh_ble.h"
+#include "bsp.h"
+
+#define BTN_ID_WAKEUP 0 /**< ID of button used to wake up the application. */
+#define BTN_ID_SLEEP 0 /**< ID of button used to put the application into sleep mode. */
+#define BTN_ID_DISCONNECT 0 /**< ID of button used to gracefully terminate a connection on long press. */
+#define BTN_ID_WAKEUP_BOND_DELETE 1 /**< ID of button used to wake up the application and delete all bonding information. */
+#define BTN_ID_WHITELIST_OFF 1 /**< ID of button used to turn off usage of the whitelist. */
+
+#define BTN_ACTION_SLEEP BSP_BUTTON_ACTION_RELEASE /**< Button action used to put the application into sleep mode. */
+#define BTN_ACTION_DISCONNECT BSP_BUTTON_ACTION_LONG_PUSH /**< Button action used to gracefully terminate a connection on long press. */
+#define BTN_ACTION_WHITELIST_OFF BSP_BUTTON_ACTION_LONG_PUSH /**< Button action used to turn off usage of the whitelist. */
+
+/**@brief This macro will return from the current function if err_code
+ * is not NRF_SUCCESS or NRF_ERROR_INVALID_PARAM.
+ */
+#define RETURN_ON_ERROR_NOT_INVALID_PARAM(err_code) \
+do \
+{ \
+ if (((err_code) != NRF_SUCCESS) && ((err_code) != NRF_ERROR_INVALID_PARAM)) \
+ { \
+ return err_code; \
+ } \
+} \
+while (0)
+
+
+/**@brief This macro will return from the current function if err_code
+ * is not NRF_SUCCESS or NRF_ERROR_NOT_SUPPORTED.
+ */
+#define RETURN_ON_ERROR_NOT_NOT_SUPPORTED(err_code) \
+do \
+{ \
+ if (((err_code) != NRF_SUCCESS) && ((err_code) != NRF_ERROR_NOT_SUPPORTED)) \
+ { \
+ return err_code; \
+ } \
+} \
+while (0)
+
+
+/**@brief This macro will call the registered error handler if err_code
+ * is not NRF_SUCCESS and the error handler is not NULL.
+ */
+#define CALL_HANDLER_ON_ERROR(err_code) \
+do \
+{ \
+ if (((err_code) != NRF_SUCCESS) && (m_error_handler != NULL)) \
+ { \
+ m_error_handler(err_code); \
+ } \
+} \
+while (0)
+
+
+static bsp_btn_ble_error_handler_t m_error_handler = NULL; /**< Error handler registered by the user. */
+static uint32_t m_num_connections = 0; /**< Number of connections the device is currently in. */
+
+
+/**@brief Function for configuring the buttons for connection.
+ *
+ * @retval NRF_SUCCESS Configured successfully.
+ * @return A propagated error code.
+ */
+static uint32_t connection_buttons_configure()
+{
+ uint32_t err_code;
+
+ err_code = bsp_event_to_button_action_assign(BTN_ID_SLEEP,
+ BTN_ACTION_SLEEP,
+ BSP_EVENT_DEFAULT);
+ RETURN_ON_ERROR_NOT_INVALID_PARAM(err_code);
+
+ err_code = bsp_event_to_button_action_assign(BTN_ID_WHITELIST_OFF,
+ BTN_ACTION_WHITELIST_OFF,
+ BSP_EVENT_WHITELIST_OFF);
+ RETURN_ON_ERROR_NOT_INVALID_PARAM(err_code);
+
+
+ err_code = bsp_event_to_button_action_assign(BTN_ID_DISCONNECT,
+ BTN_ACTION_DISCONNECT,
+ BSP_EVENT_DISCONNECT);
+ RETURN_ON_ERROR_NOT_INVALID_PARAM(err_code);
+
+ return NRF_SUCCESS;
+}
+
+
+/**@brief Function for configuring the buttons for advertisement.
+ *
+ * @retval NRF_SUCCESS Configured successfully.
+ * @return A propagated error code.
+ */
+static uint32_t advertising_buttons_configure()
+{
+ uint32_t err_code;
+
+ err_code = bsp_event_to_button_action_assign(BTN_ID_DISCONNECT,
+ BTN_ACTION_DISCONNECT,
+ BSP_EVENT_DEFAULT);
+ RETURN_ON_ERROR_NOT_INVALID_PARAM(err_code);
+
+ err_code = bsp_event_to_button_action_assign(BTN_ID_WHITELIST_OFF,
+ BTN_ACTION_WHITELIST_OFF,
+ BSP_EVENT_WHITELIST_OFF);
+ RETURN_ON_ERROR_NOT_INVALID_PARAM(err_code);
+
+ err_code = bsp_event_to_button_action_assign(BTN_ID_SLEEP,
+ BTN_ACTION_SLEEP,
+ BSP_EVENT_SLEEP);
+ RETURN_ON_ERROR_NOT_INVALID_PARAM(err_code);
+
+ return NRF_SUCCESS;
+}
+
+
+/**@brief Function for extracting the BSP event valid at startup.
+ *
+ * @details When a button was used to wake up the device, the button press will not generate an
+ * interrupt. This function reads which button was pressed at startup, and returns the
+ * appropriate BSP event.
+ *
+ * @param[out] p_startup_event Where to put the extracted BSP event.
+ */
+static void startup_event_extract(bsp_event_t * p_startup_event)
+{
+ // React to button states
+ if (bsp_button_is_pressed(BTN_ID_WAKEUP_BOND_DELETE))
+ {
+ *p_startup_event = BSP_EVENT_CLEAR_BONDING_DATA;
+ }
+ else if (bsp_button_is_pressed(BTN_ID_WAKEUP))
+ {
+ *p_startup_event = BSP_EVENT_WAKEUP;
+ }
+ else
+ {
+ *p_startup_event = BSP_EVENT_NOTHING;
+ }
+}
+
+
+uint32_t bsp_btn_ble_sleep_mode_prepare(void)
+{
+ uint32_t err_code;
+
+ err_code = bsp_wakeup_button_enable(BTN_ID_WAKEUP);
+ RETURN_ON_ERROR_NOT_NOT_SUPPORTED(err_code);
+
+ err_code = bsp_wakeup_button_enable(BTN_ID_WAKEUP_BOND_DELETE);
+ RETURN_ON_ERROR_NOT_NOT_SUPPORTED(err_code);
+
+ return NRF_SUCCESS;
+}
+
+
+/**
+ * @brief Function for handling BLE events.
+ *
+ * @param[in] p_ble_evt Event received from the BLE stack.
+ * @param[in] p_context Context.
+ */
+static void ble_evt_handler(ble_evt_t const * p_ble_evt, void * p_context)
+{
+ uint32_t err_code;
+
+ switch (p_ble_evt->header.evt_id)
+ {
+ case BLE_GAP_EVT_CONNECTED:
+ if (m_num_connections == 0)
+ {
+ err_code = connection_buttons_configure();
+ CALL_HANDLER_ON_ERROR(err_code);
+ }
+
+ m_num_connections++;
+ break;
+
+ case BLE_GAP_EVT_DISCONNECTED:
+ m_num_connections--;
+
+ if (m_num_connections == 0)
+ {
+ err_code = advertising_buttons_configure();
+ CALL_HANDLER_ON_ERROR(err_code);
+ }
+ break;
+
+ default:
+ break;
+ }
+}
+
+NRF_SDH_BLE_OBSERVER(m_ble_observer, BSP_BTN_BLE_OBSERVER_PRIO, ble_evt_handler, NULL);
+
+
+uint32_t bsp_btn_ble_init(bsp_btn_ble_error_handler_t error_handler, bsp_event_t * p_startup_bsp_evt)
+{
+ uint32_t err_code = NRF_SUCCESS;
+
+ m_error_handler = error_handler;
+
+ if (p_startup_bsp_evt != NULL)
+ {
+ startup_event_extract(p_startup_bsp_evt);
+ }
+
+ if (m_num_connections == 0)
+ {
+ err_code = advertising_buttons_configure();
+ }
+
+ return err_code;
+}
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bsp/bsp_btn_ble.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bsp/bsp_btn_ble.h
new file mode 100644
index 0000000..5184b61
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bsp/bsp_btn_ble.h
@@ -0,0 +1,100 @@
+/**
+ * Copyright (c) 2014 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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
+ *
+ * @defgroup bsp_btn_ble BSP: BLE Button Module
+ * @{
+ * @ingroup bsp
+ *
+ * @brief Module for controlling BLE behavior through button actions.
+ *
+ * @details The application must propagate BLE events to the BLE Button Module.
+ * Based on these events, the BLE Button Module configures the Board Support Package
+ * to generate BSP events for certain button actions. These BSP events should then be
+ * handled by the application's BSP event handler.
+ *
+ */
+
+#ifndef BSP_BTN_BLE_H__
+#define BSP_BTN_BLE_H__
+
+#include <stdint.h>
+#include "ble.h"
+#include "bsp.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**@brief BLE Button Module error handler type. */
+typedef void (*bsp_btn_ble_error_handler_t) (uint32_t nrf_error);
+
+/**@brief Function for initializing the BLE Button Module.
+ *
+ * Before calling this function, the BSP module must be initialized with buttons.
+ *
+ * @param[out] error_handler Error handler to call in case of internal errors in BLE Button
+ * Module.
+ * @param[out] p_startup_bsp_evt If not a NULL pointer, the value is filled with an event
+ * (or BSP_EVENT_NOTHING) derived from the buttons pressed on
+ * startup. For example, if the bond delete wakeup button was pressed
+ * to wake up the device, *p_startup_bsp_evt is set to
+ * @ref BSP_EVENT_CLEAR_BONDING_DATA.
+ *
+ * @retval NRF_SUCCESS If initialization was successful. Otherwise, a propagated error code is
+ * returned.
+ */
+uint32_t bsp_btn_ble_init(bsp_btn_ble_error_handler_t error_handler, bsp_event_t * p_startup_bsp_evt);
+
+/**@brief Function for setting up wakeup buttons before going into sleep mode.
+ *
+ * @retval NRF_SUCCESS If the buttons were prepared successfully. Otherwise, a propagated error
+ * code is returned.
+ */
+uint32_t bsp_btn_ble_sleep_mode_prepare(void);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* BSP_BTN_BLE_H__ */
+
+/** @} */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bsp/bsp_cli.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bsp/bsp_cli.c
new file mode 100644
index 0000000..2389d84
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bsp/bsp_cli.c
@@ -0,0 +1,77 @@
+/**
+ * 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#include "bsp_cli.h"
+
+static bsp_event_callback_t m_bsp_cli_callback = NULL;
+
+static void cmd_btn(nrf_cli_t const * p_cli, size_t argc, char **argv)
+{
+ uint32_t id;
+ ASSERT(m_bsp_cli_callback != NULL);
+
+ sscanf(argv[1], "%"SCNu32, &id);
+ bsp_event_t ev = (bsp_event_t)(BSP_EVENT_KEY_0 + id);
+ m_bsp_cli_callback(ev);
+}
+
+static void cmd_evt(nrf_cli_t const * p_cli, size_t argc, char **argv)
+{
+ uint32_t id;
+ ASSERT(m_bsp_cli_callback != NULL);
+
+ sscanf(argv[1], "%"SCNu32, &id);
+ bsp_event_t ev = (bsp_event_t)id;
+ m_bsp_cli_callback(ev);
+}
+
+ret_code_t bsp_cli_init(bsp_event_callback_t callback)
+{
+ m_bsp_cli_callback = callback;
+
+ return NRF_SUCCESS;
+}
+
+NRF_CLI_CREATE_STATIC_SUBCMD_SET(m_sub_bsp)
+{
+ NRF_CLI_CMD(btn, NULL, "BSP button event key", cmd_btn),
+ NRF_CLI_CMD(evt, NULL, "BSP event id", cmd_evt),
+ NRF_CLI_SUBCMD_SET_END
+};
+NRF_CLI_CMD_REGISTER(bsp, &m_sub_bsp, "bsp", NULL);
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bsp/bsp_cli.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bsp/bsp_cli.h
new file mode 100644
index 0000000..8c71d6a
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bsp/bsp_cli.h
@@ -0,0 +1,83 @@
+/**
+ * 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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
+ *
+ * @defgroup bsp_cli BSP over CLI Module
+ * @{
+ * @ingroup bsp
+ *
+ * @brief Module for sending BSP events over CLI.
+ *
+ * @details The module uses Command Line Interface and enables user to send events
+ * to BSP. They are later handled by the event handler provided.
+ * Available commands:
+ * - bsp btn X (where X is button number) - sends BSP_EVENT_KEY_X
+ * - bsp evt X (where X is event number) - sends BSP event with X id
+ */
+
+#ifndef BSP_CLI_H__
+#define BSP_CLI_H__
+
+#include <stdint.h>
+#include "nrf_cli.h"
+#include "bsp.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**@brief Function for initializing the BSP over CLI Module.
+ *
+ * Before calling this function, the BSP module must be initialized.
+ *
+ * @param[in] callback Function to be called when event is recevied.
+ *
+ * @retval NRF_SUCCESS If initialization was successful.
+ */
+
+ret_code_t bsp_cli_init(bsp_event_callback_t callback);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* BSP_CLI_H__ */
+
+/** @} */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bsp/bsp_config.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bsp/bsp_config.h
new file mode 100644
index 0000000..343a0fe
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bsp/bsp_config.h
@@ -0,0 +1,135 @@
+/**
+ * Copyright (c) 2014 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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
+ *
+ * @defgroup bsp Board Support Package
+ * @{
+ * @ingroup app_common
+ *
+ * @brief BSP module.
+ * @details This module provides a layer of abstraction from the board.
+ * It allows the user to indicate certain states on LEDs in a simple way.
+ * Module functionality can be modified by additional defines:
+ * - BSP_SIMPLE - reduces functionality of this module to enable
+ * and read state of the buttons.
+ * - BSP_UART_SUPPORT - enables support for UART.
+ */
+
+#ifndef BSP_CONFIG_H__
+#define BSP_CONFIG_H__
+
+#include <stdint.h>
+#include <stdbool.h>
+#include "boards.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#if !defined(BSP_DEFINES_ONLY) && !defined(BSP_SIMPLE)
+#include "app_button.h"
+
+#define BSP_BUTTON_ACTION_PUSH (APP_BUTTON_PUSH) /**< Represents pushing a button. See @ref bsp_button_action_t. */
+#define BSP_BUTTON_ACTION_RELEASE (APP_BUTTON_RELEASE) /**< Represents releasing a button. See @ref bsp_button_action_t. */
+#define BSP_BUTTON_ACTION_LONG_PUSH (2) /**< Represents pushing and holding a button for @ref BSP_LONG_PUSH_TIMEOUT_MS milliseconds. See also @ref bsp_button_action_t. */
+#endif
+
+#define BSP_MS_TO_TICK(MS) (m_app_ticks_per_100ms * (MS / 100))
+
+
+#define BUTTON_ERASE_BONDING BSP_BUTTON_0_MASK
+#define BUTTON_ERASE_ALL BSP_BUTTON_1_MASK
+#define BUTTON_ADVERTISE BSP_BUTTON_0_MASK
+#define BUTTON_CLEAR_EVT BSP_BUTTON_1_MASK
+#define BUTTON_CAPSLOCK BSP_BUTTON_2_MASK
+#define BSP_BUTTONS_ALL 0xFFFFFFFF
+#define BSP_BUTTONS_NONE 0
+
+#define BSP_LONG_PUSH_TIMEOUT_MS (1000) /**< The time to hold for a long push (in milliseconds). */
+/**@brief Types of BSP initialization.
+ */
+
+#define ADVERTISING_LED_ON_INTERVAL 200
+#define ADVERTISING_LED_OFF_INTERVAL 1800
+
+#define ADVERTISING_DIRECTED_LED_ON_INTERVAL 200
+#define ADVERTISING_DIRECTED_LED_OFF_INTERVAL 200
+
+#define ADVERTISING_WHITELIST_LED_ON_INTERVAL 200
+#define ADVERTISING_WHITELIST_LED_OFF_INTERVAL 800
+
+#define ADVERTISING_SLOW_LED_ON_INTERVAL 400
+#define ADVERTISING_SLOW_LED_OFF_INTERVAL 4000
+
+#define BONDING_INTERVAL 100
+
+#define SENT_OK_INTERVAL 100
+#define SEND_ERROR_INTERVAL 500
+
+#define RCV_OK_INTERVAL 100
+#define RCV_ERROR_INTERVAL 500
+
+#define ALERT_INTERVAL 200
+
+#define BSP_LED_INDICATE_SENT_OK BSP_BOARD_LED_1
+#define BSP_LED_INDICATE_SEND_ERROR BSP_BOARD_LED_1
+#define BSP_LED_INDICATE_RCV_OK BSP_BOARD_LED_1
+#define BSP_LED_INDICATE_RCV_ERROR BSP_BOARD_LED_1
+#define BSP_LED_INDICATE_CONNECTED BSP_BOARD_LED_0
+#define BSP_LED_INDICATE_BONDING BSP_BOARD_LED_0
+#define BSP_LED_INDICATE_ADVERTISING_DIRECTED BSP_BOARD_LED_0
+#define BSP_LED_INDICATE_ADVERTISING_SLOW BSP_BOARD_LED_0
+#define BSP_LED_INDICATE_ADVERTISING_WHITELIST BSP_BOARD_LED_0
+#define BSP_LED_INDICATE_INDICATE_ADVERTISING BSP_BOARD_LED_0
+
+#define BSP_LED_INDICATE_USER_LED1 BSP_BOARD_LED_0
+#define BSP_LED_INDICATE_USER_LED2 BSP_BOARD_LED_1
+#define BSP_LED_INDICATE_USER_LED3 BSP_BOARD_LED_2
+#define BSP_LED_INDICATE_USER_LED4 BSP_BOARD_LED_3
+
+#define BSP_LED_ALERT BSP_BOARD_LED_2
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // BSP_CONFIG_H__
+
+/** @} */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bsp/bsp_nfc.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bsp/bsp_nfc.c
new file mode 100644
index 0000000..50cc01c
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bsp/bsp_nfc.c
@@ -0,0 +1,84 @@
+/**
+ * Copyright (c) 2015 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#include "bsp_nfc.h"
+#include "bsp.h"
+#include "nrf.h"
+#include "app_util_platform.h"
+
+#ifndef BSP_SIMPLE
+#define BTN_ACTION_SLEEP BSP_BUTTON_ACTION_RELEASE /**< Button action used to put the application into sleep mode. */
+
+ret_code_t bsp_nfc_btn_init(uint32_t sleep_button)
+{
+ uint32_t err_code = bsp_event_to_button_action_assign(sleep_button,
+ BTN_ACTION_SLEEP,
+ BSP_EVENT_SLEEP);
+ return err_code;
+}
+
+ret_code_t bsp_nfc_btn_deinit(uint32_t sleep_button)
+{
+ uint32_t err_code = bsp_event_to_button_action_assign(sleep_button,
+ BTN_ACTION_SLEEP,
+ BSP_EVENT_DEFAULT);
+ return err_code;
+}
+
+ret_code_t bsp_nfc_sleep_mode_prepare(void)
+{
+#if defined(NFCT_PRESENT)
+ // Check if peripheral is not used.
+ CRITICAL_REGION_ENTER();
+#ifdef NRF52832_XXAA
+ if ((*(uint32_t *)0x40005410 & 0x07) == 0)
+#else
+ if ((NRF_NFCT->NFCTAGSTATE & NFCT_NFCTAGSTATE_NFCTAGSTATE_Msk)
+ == NFCT_NFCTAGSTATE_NFCTAGSTATE_Disabled)
+#endif // NRF52832_XXAA
+ {
+ NRF_NFCT->TASKS_SENSE = 1;
+ }
+ CRITICAL_REGION_EXIT();
+ return NRF_SUCCESS;
+#else
+ return NRF_ERROR_NOT_SUPPORTED;
+#endif
+}
+#endif //BSP_SIMPLE
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bsp/bsp_nfc.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bsp/bsp_nfc.h
new file mode 100644
index 0000000..90a8cc9
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bsp/bsp_nfc.h
@@ -0,0 +1,107 @@
+/**
+ * Copyright (c) 2016 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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
+ *
+ * @defgroup bsp_nfc NFC BSP Module
+ * @{
+ * @ingroup bsp
+ *
+ * @brief Module for setting the NFCT peripheral as a wakeup source.
+ *
+ * @details The application must notify this module before going into System OFF mode.
+ * Based on this notification, the NFC BSP Module sets the NFCT peripheral as a wakeup source
+ * through the Board Support Package. Additionally, any BSP Button can be configured to
+ * generate BSP sleep events. This module is applicable only if NFCT is used exclusively for
+ * wakeup. If NFCT is used for a different purpose, this module cannot be used.
+ */
+
+#ifndef BSP_NFC_H__
+#define BSP_NFC_H__
+
+#include <stdint.h>
+#include "sdk_errors.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**@brief Function for initializing the NFC Button Module.
+ *
+ * Before calling this function, the BSP module must be initialized with buttons. The chosen
+ * button is used to generate @ref BSP_EVENT_SLEEP events.
+ *
+ * @param[in] sleep_button Button ID used to generate @ref BSP_EVENT_SLEEP event.
+ *
+ * @retval NRF_SUCCESS If initialization was successful. Otherwise, a propagated error
+ * code is returned.
+ */
+ret_code_t bsp_nfc_btn_init(uint32_t sleep_button);
+
+/**@brief Function for deinitializing the NFC Button Module.
+ *
+ * Before calling this function, the BSP module must be initialized with buttons. The chosen
+ * button is used to generate default @ref BSP_EVENT_DEFAULT events.
+ *
+ * @param[in] sleep_button Button ID used to restore default event generation.
+ *
+ * @retval NRF_SUCCESS If initialization was successful. Otherwise, a propagated error
+ * code is returned.
+ */
+ret_code_t bsp_nfc_btn_deinit(uint32_t sleep_button);
+
+/**@brief Function for setting up NFCT peripheral as wake-up source.
+ *
+ * This function must be called before going into System OFF mode.
+ *
+ * @note This function is only applicable if NFCT is used exclusively for wakeup.
+ * If NFCT is used for a different purpose, this function cannot be used.
+ *
+ * @retval NRF_SUCCESS If NFCT peripheral was prepared successfully. Otherwise,
+ * a propagated error code is returned.
+ */
+ret_code_t bsp_nfc_sleep_mode_prepare(void);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* BSP_NFC_H__ */
+
+/** @} */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/button/app_button.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/button/app_button.c
new file mode 100644
index 0000000..b422095
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/button/app_button.c
@@ -0,0 +1,223 @@
+/**
+ * Copyright (c) 2012 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#include "sdk_common.h"
+#if NRF_MODULE_ENABLED(BUTTON)
+#include "app_button.h"
+#include "app_timer.h"
+#include "app_error.h"
+#include "nrf_drv_gpiote.h"
+#include "nrf_assert.h"
+
+
+static app_button_cfg_t const * mp_buttons = NULL; /**< Button configuration. */
+static uint8_t m_button_count; /**< Number of configured buttons. */
+static uint32_t m_detection_delay; /**< Delay before a button is reported as pushed. */
+APP_TIMER_DEF(m_detection_delay_timer_id); /**< Polling timer id. */
+
+
+static uint64_t m_pin_state;
+static uint64_t m_pin_transition;
+
+/**@brief Function for handling the timeout that delays reporting buttons as pushed.
+ *
+ * @details The detection_delay_timeout_handler(...) is a call-back issued from the app_timer
+ * module. It is called with the p_context parameter. The p_context parameter is
+ * provided to the app_timer module when a timer is started, using the call
+ * @ref app_timer_start. On @ref app_timer_start the p_context will be holding the
+ * currently pressed buttons.
+ *
+ * @param[in] p_context Pointer used for passing information app_start_timer() was called.
+ * In the app_button module the p_context holds information on pressed
+ * buttons.
+ */
+static void detection_delay_timeout_handler(void * p_context)
+{
+ uint8_t i;
+
+ // Pushed button(s) detected, execute button handler(s).
+ for (i = 0; i < m_button_count; i++)
+ {
+ app_button_cfg_t const * p_btn = &mp_buttons[i];
+ uint64_t btn_mask = 1ULL << p_btn->pin_no;
+ if (btn_mask & m_pin_transition)
+ {
+ m_pin_transition &= ~btn_mask;
+ bool pin_is_set = nrf_drv_gpiote_in_is_set(p_btn->pin_no);
+ if ((m_pin_state & (1ULL << p_btn->pin_no)) == (((uint64_t)pin_is_set) << p_btn->pin_no))
+ {
+ uint32_t transition = !(pin_is_set ^ (p_btn->active_state == APP_BUTTON_ACTIVE_HIGH));
+
+ if (p_btn->button_handler)
+ {
+ p_btn->button_handler(p_btn->pin_no, transition);
+ }
+ }
+ }
+ }
+}
+
+static void gpiote_event_handler(nrf_drv_gpiote_pin_t pin, nrf_gpiote_polarity_t action)
+{
+ uint32_t err_code;
+ uint64_t pin_mask = 1ULL << pin;
+
+ // Start detection timer. If timer is already running, the detection period is restarted.
+ // NOTE: Using the p_context parameter of app_timer_start() to transfer the pin states to the
+ // timeout handler (by casting event_pins_mask into the equally sized void * p_context
+ // parameter).
+ err_code = app_timer_stop(m_detection_delay_timer_id);
+ if (err_code != NRF_SUCCESS)
+ {
+ // The impact in app_button of the app_timer queue running full is losing a button press.
+ // The current implementation ensures that the system will continue working as normal.
+ return;
+ }
+
+ if (!(m_pin_transition & pin_mask))
+ {
+ if (nrf_drv_gpiote_in_is_set(pin))
+ {
+ m_pin_state |= pin_mask;
+ }
+ else
+ {
+ m_pin_state &= ~(pin_mask);
+ }
+ m_pin_transition |= (pin_mask);
+
+ err_code = app_timer_start(m_detection_delay_timer_id, m_detection_delay, NULL);
+ if (err_code != NRF_SUCCESS)
+ {
+ // The impact in app_button of the app_timer queue running full is losing a button press.
+ // The current implementation ensures that the system will continue working as normal.
+ }
+ }
+ else
+ {
+ m_pin_transition &= ~pin_mask;
+ }
+}
+
+uint32_t app_button_init(app_button_cfg_t const * p_buttons,
+ uint8_t button_count,
+ uint32_t detection_delay)
+{
+ uint32_t err_code;
+
+ if (detection_delay < APP_TIMER_MIN_TIMEOUT_TICKS)
+ {
+ return NRF_ERROR_INVALID_PARAM;
+ }
+
+ if (!nrf_drv_gpiote_is_init())
+ {
+ err_code = nrf_drv_gpiote_init();
+ VERIFY_SUCCESS(err_code);
+ }
+
+ // Save configuration.
+ mp_buttons = p_buttons;
+ m_button_count = button_count;
+ m_detection_delay = detection_delay;
+
+ m_pin_state = 0;
+ m_pin_transition = 0;
+
+ while (button_count--)
+ {
+ app_button_cfg_t const * p_btn = &p_buttons[button_count];
+
+#if defined(BUTTON_HIGH_ACCURACY_ENABLED) && (BUTTON_HIGH_ACCURACY_ENABLED == 1)
+ nrf_drv_gpiote_in_config_t config = GPIOTE_CONFIG_IN_SENSE_TOGGLE(p_btn->hi_accuracy);
+#else
+ nrf_drv_gpiote_in_config_t config = GPIOTE_CONFIG_IN_SENSE_TOGGLE(false);
+#endif
+ config.pull = p_btn->pull_cfg;
+
+ err_code = nrf_drv_gpiote_in_init(p_btn->pin_no, &config, gpiote_event_handler);
+ VERIFY_SUCCESS(err_code);
+ }
+
+ // Create polling timer.
+ return app_timer_create(&m_detection_delay_timer_id,
+ APP_TIMER_MODE_SINGLE_SHOT,
+ detection_delay_timeout_handler);
+}
+
+uint32_t app_button_enable(void)
+{
+ ASSERT(mp_buttons);
+
+ uint32_t i;
+ for (i = 0; i < m_button_count; i++)
+ {
+ nrf_drv_gpiote_in_event_enable(mp_buttons[i].pin_no, true);
+ }
+
+ return NRF_SUCCESS;
+}
+
+
+uint32_t app_button_disable(void)
+{
+ ASSERT(mp_buttons);
+
+ uint32_t i;
+ for (i = 0; i < m_button_count; i++)
+ {
+ nrf_drv_gpiote_in_event_disable(mp_buttons[i].pin_no);
+ }
+
+ // Make sure polling timer is not running.
+ return app_timer_stop(m_detection_delay_timer_id);
+}
+
+
+bool app_button_is_pushed(uint8_t button_id)
+{
+ ASSERT(button_id <= m_button_count);
+ ASSERT(mp_buttons != NULL);
+
+ app_button_cfg_t const * p_btn = &mp_buttons[button_id];
+ bool is_set = nrf_drv_gpiote_in_is_set(p_btn->pin_no);
+
+ return !(is_set ^ (p_btn->active_state == APP_BUTTON_ACTIVE_HIGH));
+}
+#endif //NRF_MODULE_ENABLED(BUTTON)
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/button/app_button.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/button/app_button.h
new file mode 100644
index 0000000..3c1aa5a
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/button/app_button.h
@@ -0,0 +1,142 @@
+/**
+ * Copyright (c) 2012 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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
+ *
+ * @defgroup app_button Button Handler
+ * @{
+ * @ingroup app_common
+ *
+ * @brief Buttons handling module.
+ *
+ * @details The button handler uses the @ref app_gpiote to detect that a button has been
+ * pushed. To handle debouncing, it will start a timer in the GPIOTE event handler.
+ * The button will only be reported as pushed if the corresponding pin is still active when
+ * the timer expires. If there is a new GPIOTE event while the timer is running, the timer
+ * is restarted.
+ *
+ * @note The app_button module uses the app_timer module. The user must ensure that the queue in
+ * app_timer is large enough to hold the app_timer_stop() / app_timer_start() operations
+ * which will be executed on each event from GPIOTE module (2 operations), as well as other
+ * app_timer operations queued simultaneously in the application.
+ *
+ * @note Even if the scheduler is not used, app_button.h will include app_scheduler.h, so when
+ * compiling, app_scheduler.h must be available in one of the compiler include paths.
+ */
+
+#ifndef APP_BUTTON_H__
+#define APP_BUTTON_H__
+
+#include <stdint.h>
+#include <stdbool.h>
+#include "nrf.h"
+#include "app_error.h"
+#include "nrf_gpio.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define APP_BUTTON_PUSH 1 /**< Indicates that a button is pushed. */
+#define APP_BUTTON_RELEASE 0 /**< Indicates that a button is released. */
+#define APP_BUTTON_ACTIVE_HIGH 1 /**< Indicates that a button is active high. */
+#define APP_BUTTON_ACTIVE_LOW 0 /**< Indicates that a button is active low. */
+
+/**@brief Button event handler type. */
+typedef void (*app_button_handler_t)(uint8_t pin_no, uint8_t button_action);
+
+/**@brief Button configuration structure. */
+typedef struct
+{
+ uint8_t pin_no; /**< Pin to be used as a button. */
+ uint8_t active_state; /**< APP_BUTTON_ACTIVE_HIGH or APP_BUTTON_ACTIVE_LOW. */
+#if defined(BUTTON_HIGH_ACCURACY_ENABLED) && (BUTTON_HIGH_ACCURACY_ENABLED == 1)
+ bool hi_accuracy; /**< True if GPIOTE high accuracy (IN_EVENT) is used. */
+#endif
+ nrf_gpio_pin_pull_t pull_cfg; /**< Pull-up or -down configuration. */
+ app_button_handler_t button_handler; /**< Handler to be called when button is pushed. */
+} app_button_cfg_t;
+
+/**@brief Function for initializing the Buttons.
+ *
+ * @details This function will initialize the specified pins as buttons, and configure the Button
+ * Handler module as a GPIOTE user (but it will not enable button detection).
+ *
+ * @note Normally initialization should be done using the APP_BUTTON_INIT() macro
+ *
+ * @note app_button_enable() function must be called in order to enable the button detection.
+ *
+ * @param[in] p_buttons Array of buttons to be used (NOTE: Must be static!).
+ * @param[in] button_count Number of buttons.
+ * @param[in] detection_delay Delay from a GPIOTE event until a button is reported as pushed.
+ *
+ * @return NRF_SUCCESS on success, otherwise an error code.
+ */
+uint32_t app_button_init(app_button_cfg_t const * p_buttons,
+ uint8_t button_count,
+ uint32_t detection_delay);
+
+/**@brief Function for enabling button detection.
+ *
+ * @retval NRF_SUCCESS Module successfully enabled.
+ */
+uint32_t app_button_enable(void);
+
+/**@brief Function for disabling button detection.
+ *
+ * @retval NRF_SUCCESS Button detection successfully disabled. Error code otherwise.
+ */
+uint32_t app_button_disable(void);
+
+/**@brief Function for checking if a button is currently being pushed.
+ *
+ * @param[in] button_id Button index (in the app_button_cfg_t array given to app_button_init) to be checked.
+ *
+ * @return Button state.
+ */
+bool app_button_is_pushed(uint8_t button_id);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // APP_BUTTON_H__
+
+/** @} */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/cli/ble_uart/nrf_cli_ble_uart.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/cli/ble_uart/nrf_cli_ble_uart.c
new file mode 100644
index 0000000..e469853
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/cli/ble_uart/nrf_cli_ble_uart.c
@@ -0,0 +1,317 @@
+/**
+ * Copyright (c) 2016 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+
+#include "sdk_common.h"
+#if NRF_MODULE_ENABLED(NRF_CLI_BLE_UART)
+#include "nrf_cli_ble_uart.h"
+#include "ble_nus.h"
+#include "nrf_ringbuf.h"
+#include "app_timer.h"
+#include "nrf_assert.h"
+#include "nrf_ble_gatt.h"
+#define NRF_LOG_MODULE_NAME cli_ble
+
+#if NRF_CLI_BLE_UART_CONFIG_LOG_ENABLED
+#define NRF_LOG_LEVEL NRF_CLI_BLE_UART_CONFIG_LOG_LEVEL
+#define NRF_LOG_INFO_COLOR NRF_CLI_BLE_UART_CONFIG_INFO_COLOR
+#define NRF_LOG_DEBUG_COLOR NRF_CLI_BLE_UART_CONFIG_DEBUG_COLOR
+
+#else //NRF_CLI_BLE_UART_CONFIG_LOG_ENABLED
+#define NRF_LOG_LEVEL 0
+#endif //NRF_CLI_BLE_UART_CONFIG_LOG_ENABLED
+#include "nrf_log.h"
+NRF_LOG_MODULE_REGISTER();
+
+#if NRF_CLI_BLE_UART_MAX_CLIENTS > NRF_SDH_BLE_TOTAL_LINK_COUNT
+ #error "Too few BLE peripheral links are supported by the BLE SDH module for the maximal number \
+ of BLE transport instances"
+#endif
+
+#define NRF_CLI_BLE_UART_TIMEOUT_MS 50
+#define OVERHEAD_LENGTH (OPCODE_LENGTH + HANDLE_LENGTH)
+
+BLE_NUS_DEF(m_nus, NRF_CLI_BLE_UART_MAX_CLIENTS);
+BLE_LINK_CTX_MANAGER_DEF(m_link_ctx_storage,
+ NRF_CLI_BLE_UART_MAX_CLIENTS,
+ sizeof(nrf_cli_ble_uart_internal_t *));
+
+static void tx_try(nrf_cli_ble_uart_internal_t * p_instance, uint32_t threshold)
+{
+ uint8_t * p_out_data;
+ size_t out_data_len =
+ nrf_ble_gatt_eff_mtu_get(p_instance->p_gatt, p_instance->p_cb->conn_handle) -
+ OVERHEAD_LENGTH;
+
+ ret_code_t err_code = nrf_ringbuf_get(p_instance->p_tx_ringbuf,
+ &p_out_data,
+ &out_data_len,
+ true);
+
+ if (err_code == NRF_SUCCESS)
+ {
+ if (out_data_len >= threshold)
+ {
+ size_t req_data_len = out_data_len;
+ err_code = ble_nus_data_send(&m_nus,
+ p_out_data,
+ (uint16_t*)&out_data_len,
+ p_instance->p_cb->conn_handle);
+
+ if ((err_code == NRF_ERROR_BUSY) || (err_code == NRF_ERROR_RESOURCES))
+ {
+ out_data_len = 0;
+ }
+ NRF_LOG_INFO("Conn_handle:%d TX req_len: %d, len: %d",
+ p_instance->p_cb->conn_handle, req_data_len, out_data_len);
+ NRF_LOG_HEXDUMP_DEBUG(p_out_data, out_data_len);
+ err_code = nrf_ringbuf_free(p_instance->p_tx_ringbuf, out_data_len);
+ ASSERT(err_code == NRF_SUCCESS);
+ }
+ else
+ {
+ err_code = nrf_ringbuf_free(p_instance->p_tx_ringbuf, 0);
+ ASSERT(err_code == NRF_SUCCESS);
+ }
+ }
+}
+
+static void nus_data_handler(ble_nus_evt_t * p_nus_evt)
+{
+ ret_code_t err_code = NRF_SUCCESS;
+ nrf_cli_ble_uart_internal_t * p_instance;
+ nrf_cli_ble_uart_internal_t ** pp_instance;
+
+ err_code = blcm_link_ctx_get(&m_link_ctx_storage, p_nus_evt->conn_handle, (void *) &pp_instance);
+ ASSERT(err_code == NRF_SUCCESS);
+
+ p_instance = *pp_instance;
+
+ switch (p_nus_evt->type)
+ {
+ case BLE_NUS_EVT_RX_DATA:
+ {
+ NRF_LOG_INFO("Conn_handle:%d, Received: %d",
+ p_instance->p_cb->conn_handle, p_nus_evt->params.rx_data.length);
+ NRF_LOG_HEXDUMP_DEBUG(p_nus_evt->params.rx_data.p_data, p_nus_evt->params.rx_data.length);
+ size_t len = ((size_t) p_nus_evt->params.rx_data.length) & 0x0000FFFF;
+ err_code = nrf_ringbuf_cpy_put(p_instance->p_rx_ringbuf,
+ p_nus_evt->params.rx_data.p_data,
+ (size_t *)&len);
+ ASSERT(err_code == NRF_SUCCESS);
+
+ p_instance->p_cb->handler(NRF_CLI_TRANSPORT_EVT_RX_RDY, p_instance->p_cb->p_context);
+ break;
+ }
+ case BLE_NUS_EVT_TX_RDY:
+ {
+ //TX_Complete
+ uint32_t max_tx_len = nrf_ble_gatt_eff_mtu_get(p_instance->p_gatt,
+ p_instance->p_cb->conn_handle) -
+ OVERHEAD_LENGTH;
+ tx_try(p_instance, max_tx_len);
+ p_instance->p_cb->handler(NRF_CLI_TRANSPORT_EVT_TX_RDY, p_instance->p_cb->p_context);
+ break;
+ }
+ case BLE_NUS_EVT_COMM_STARTED:
+ p_instance->p_cb->service_started = true;
+ err_code = app_timer_start(*p_instance->p_timer,
+ APP_TIMER_TICKS(NRF_CLI_BLE_UART_TIMEOUT_MS),
+ p_instance);
+ ASSERT(err_code == NRF_SUCCESS);
+ NRF_LOG_INFO("Conn_handle:%d, communication started", p_instance->p_cb->conn_handle);
+ break;
+ case BLE_NUS_EVT_COMM_STOPPED:
+ (void)app_timer_stop(*p_instance->p_timer);
+ p_instance->p_cb->service_started = false;
+ NRF_LOG_INFO("Conn_handle:%d, communication stopped", p_instance->p_cb->conn_handle);
+ break;
+ default:
+ break;
+ }
+}
+
+static void timer_handler(void * p_context)
+{
+ nrf_cli_ble_uart_internal_t * p_instance = (nrf_cli_ble_uart_internal_t *) p_context;
+ tx_try(p_instance, 1);
+
+ ret_code_t err_code = app_timer_start(*p_instance->p_timer,
+ APP_TIMER_TICKS(NRF_CLI_BLE_UART_TIMEOUT_MS), (void *)p_instance);
+ ASSERT(err_code == NRF_SUCCESS);
+ UNUSED_VARIABLE(err_code);
+ UNUSED_PARAMETER(p_context);
+}
+
+ret_code_t nrf_cli_ble_uart_service_init(void)
+{
+ ble_nus_init_t nus_init;
+
+ memset(&nus_init, 0, sizeof(nus_init));
+ nus_init.data_handler = nus_data_handler;
+
+ return ble_nus_init(&m_nus, &nus_init);
+}
+
+static ret_code_t cli_ble_uart_init(nrf_cli_transport_t const * p_transport,
+ void const * p_config,
+ nrf_cli_transport_handler_t evt_handler,
+ void * p_context)
+{
+ ret_code_t err_code;
+ nrf_cli_ble_uart_internal_t ** pp_instance;
+ nrf_cli_ble_uart_internal_t * p_instance =
+ CONTAINER_OF(p_transport, nrf_cli_ble_uart_internal_t, transport);
+ nrf_cli_ble_uart_config_t * p_ble_uart_config = (nrf_cli_ble_uart_config_t *)p_config;
+
+ p_instance->p_cb->handler = evt_handler;
+ p_instance->p_cb->p_context = p_context;
+ p_instance->p_cb->service_started = false;
+ p_instance->p_cb->conn_handle = p_ble_uart_config->conn_handle;
+
+ NRF_LOG_INFO("Conn_handle:%d init.", p_ble_uart_config->conn_handle);
+ nrf_ringbuf_init(p_instance->p_rx_ringbuf);
+ nrf_ringbuf_init(p_instance->p_tx_ringbuf);
+
+ err_code = blcm_link_ctx_get(&m_link_ctx_storage,
+ p_ble_uart_config->conn_handle,
+ (void *) &pp_instance);
+ VERIFY_SUCCESS(err_code);
+
+ *pp_instance = p_instance;
+
+ return NRF_SUCCESS;
+}
+
+static ret_code_t cli_ble_uart_uninit(nrf_cli_transport_t const * p_transport)
+{
+ nrf_cli_ble_uart_internal_t * p_instance =
+ CONTAINER_OF(p_transport, nrf_cli_ble_uart_internal_t, transport);
+
+ NRF_LOG_INFO("Conn_handle:%d uninit.", p_instance->p_cb->conn_handle);
+ ret_code_t ret = app_timer_stop(*p_instance->p_timer);
+
+ return ret;
+}
+
+static ret_code_t cli_ble_uart_enable(nrf_cli_transport_t const * p_transport, bool blocking)
+{
+ nrf_cli_ble_uart_internal_t * p_instance =
+ CONTAINER_OF(p_transport, nrf_cli_ble_uart_internal_t, transport);
+
+
+ NRF_LOG_INFO("Conn_handle:%d, enable blocking:%d", blocking, p_instance->p_cb->conn_handle);
+ if (blocking)
+ {
+ return NRF_ERROR_NOT_SUPPORTED;
+ }
+ else
+ {
+ ret_code_t err_code = NRF_SUCCESS;
+ if (!p_instance->p_cb->timer_created)
+ {
+ err_code = app_timer_create(p_instance->p_timer,
+ APP_TIMER_MODE_SINGLE_SHOT,
+ timer_handler);
+ p_instance->p_cb->timer_created = true;
+ }
+ return err_code;
+ }
+}
+
+static ret_code_t cli_ble_uart_read(nrf_cli_transport_t const * p_transport,
+ void * p_data,
+ size_t length,
+ size_t * p_cnt)
+{
+ ASSERT(p_cnt);
+ nrf_cli_ble_uart_internal_t * p_instance =
+ CONTAINER_OF(p_transport, nrf_cli_ble_uart_internal_t, transport);
+ *p_cnt = length;
+ ret_code_t err_code = nrf_ringbuf_cpy_get(p_instance->p_rx_ringbuf, p_data, p_cnt);
+
+ if (*p_cnt)
+ {
+ NRF_LOG_INFO("Conn_handle:%d, read req_len:%d read_len: %d",
+ p_instance->p_cb->conn_handle,
+ length,
+ *p_cnt);
+ NRF_LOG_HEXDUMP_DEBUG(p_data, *p_cnt);
+ }
+
+ return err_code;
+}
+
+static ret_code_t cli_ble_uart_write(nrf_cli_transport_t const * p_transport,
+ const void * p_data,
+ size_t length,
+ size_t * p_cnt)
+{
+ ASSERT(p_cnt);
+ nrf_cli_ble_uart_internal_t * p_instance =
+ CONTAINER_OF(p_transport, nrf_cli_ble_uart_internal_t, transport);
+ ret_code_t err_code = NRF_SUCCESS;
+ if (p_instance->p_cb->service_started)
+ {
+ *p_cnt = length;
+ err_code = nrf_ringbuf_cpy_put(p_instance->p_tx_ringbuf, p_data, p_cnt);
+
+ NRF_LOG_INFO("Conn_handle:%d, write req:%d, buffered:%d",
+ p_instance->p_cb->conn_handle, length, *p_cnt);
+ NRF_LOG_HEXDUMP_DEBUG(p_data, *p_cnt);
+ }
+ else
+ {
+ NRF_LOG_INFO("Conn_handle:%d, write req:%d. Notifications not enabled",
+ p_instance->p_cb->conn_handle, length);
+ *p_cnt = length;
+ p_instance->p_cb->handler(NRF_CLI_TRANSPORT_EVT_TX_RDY, p_instance->p_cb->p_context);
+ }
+ return err_code;
+}
+
+const nrf_cli_transport_api_t nrf_cli_ble_uart_transport_api = {
+ .init = cli_ble_uart_init,
+ .uninit = cli_ble_uart_uninit,
+ .enable = cli_ble_uart_enable,
+ .read = cli_ble_uart_read,
+ .write = cli_ble_uart_write,
+};
+
+#endif //NRF_MODULE_ENABLED(NRF_CLI_BLE_UART)
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/cli/ble_uart/nrf_cli_ble_uart.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/cli/ble_uart/nrf_cli_ble_uart.h
new file mode 100644
index 0000000..6111940
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/cli/ble_uart/nrf_cli_ble_uart.h
@@ -0,0 +1,123 @@
+/**
+ * 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#ifndef NRF_CLI_BLE_UART_H__
+#define NRF_CLI_BLE_UART_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "nrf_cli.h"
+#include "ble.h"
+#include "app_timer.h"
+#include "nrf_ringbuf.h"
+#include "nordic_common.h"
+#include "nrf_ble_gatt.h"
+/**@file
+ *
+ * @defgroup nrf_cli_ble_uart BLE UART command line interface transport layer
+ * @ingroup nrf_cli
+ *
+ * @{
+ *
+ */
+
+/**
+ * @brief Command line interface transport.
+ */
+
+ret_code_t nrf_cli_ble_uart_service_init(void);
+
+extern const nrf_cli_transport_api_t nrf_cli_ble_uart_transport_api;
+
+typedef struct nrf_cli_ble_uart_internal_s nrf_cli_ble_uart_internal_t;
+
+typedef struct {
+ nrf_cli_transport_handler_t handler;
+ void * p_context;
+ uint16_t conn_handle;
+ bool timer_created;
+ bool service_started;
+} nrf_cli_ble_uart_internal_cb_t;
+
+
+struct nrf_cli_ble_uart_internal_s {
+ nrf_cli_transport_t transport;
+ nrf_cli_ble_uart_internal_cb_t * p_cb;
+ app_timer_id_t const * p_timer;
+ nrf_ringbuf_t const * p_rx_ringbuf;
+ nrf_ringbuf_t const * p_tx_ringbuf;
+ nrf_ble_gatt_t const * p_gatt;
+};
+
+typedef struct {
+ uint16_t conn_handle;
+} nrf_cli_ble_uart_config_t;
+
+/**@brief CLI Bluetooth transport definition.
+ *
+ * @param _name Name of the instance.
+ * @param _p_gatt Pointer to the nrf_ble_gatt module.
+ * @param _tx_buf_sz Size of TX ring buffer.
+ * @param _rx_buf_sz Size of RX ring buffer.
+ */
+#define NRF_CLI_BLE_UART_DEF(_name, _p_gatt, _tx_buf_sz, _rx_buf_sz) \
+ APP_TIMER_DEF(CONCAT_2(_name, _timer)); \
+ NRF_RINGBUF_DEF(CONCAT_2(_name,_tx_ringbuf), _tx_buf_sz); \
+ NRF_RINGBUF_DEF(CONCAT_2(_name,_rx_ringbuf), _rx_buf_sz); \
+ static nrf_cli_ble_uart_internal_cb_t CONCAT_2(_name, _cb); \
+ static const nrf_cli_ble_uart_internal_t _name = { \
+ .transport = {.p_api = &nrf_cli_ble_uart_transport_api}, \
+ .p_cb = &CONCAT_2(_name, _cb), \
+ .p_timer = &CONCAT_2(_name, _timer), \
+ .p_rx_ringbuf = &CONCAT_2(_name,_rx_ringbuf), \
+ .p_tx_ringbuf = &CONCAT_2(_name,_tx_ringbuf), \
+ .p_gatt = _p_gatt, \
+ }
+
+
+/** @} */
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* NRF_CLI_BLE_UART_H__ */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/cli/cdc_acm/nrf_cli_cdc_acm.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/cli/cdc_acm/nrf_cli_cdc_acm.c
new file mode 100644
index 0000000..42adb75
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/cli/cdc_acm/nrf_cli_cdc_acm.c
@@ -0,0 +1,242 @@
+/**
+ * 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#include "sdk_common.h"
+#if NRF_MODULE_ENABLED(NRF_CLI_CDC_ACM)
+#include "nrf_cli_cdc_acm.h"
+#include "nrf_queue.h"
+#include "app_error.h"
+#include "nrf_assert.h"
+
+
+#if APP_USBD_CONFIG_EVENT_QUEUE_ENABLE
+#error "Current CLI CDC implementation supports only USB with event queue disabled (see APP_USBD_CONFIG_EVENT_QUEUE_ENABLE)"
+#endif
+
+static void cdc_acm_user_ev_handler(app_usbd_class_inst_t const * p_inst,
+ app_usbd_cdc_acm_user_event_t event);
+
+/*lint -save -e26 -e40 -e64 -e123 -e505 -e651*/
+
+/**
+ * @brief CDC_ACM class instance.
+ * */
+APP_USBD_CDC_ACM_GLOBAL_DEF(nrf_cli_cdc_acm,
+ cdc_acm_user_ev_handler,
+ NRF_CLI_CDC_ACM_COMM_INTERFACE,
+ NRF_CLI_CDC_ACM_DATA_INTERFACE,
+ NRF_CLI_CDC_ACM_COMM_EPIN,
+ NRF_CLI_CDC_ACM_DATA_EPIN,
+ NRF_CLI_CDC_ACM_DATA_EPOUT,
+ APP_USBD_CDC_COMM_PROTOCOL_AT_V250
+);
+
+/*lint -restore*/
+
+NRF_QUEUE_DEF(uint8_t,
+ m_rx_queue,
+ 2*NRF_DRV_USBD_EPSIZE,
+ NRF_QUEUE_MODE_OVERFLOW);
+
+static char m_rx_buffer[NRF_DRV_USBD_EPSIZE];
+
+static nrf_cli_cdc_acm_internal_t * mp_internal;
+
+/**
+ * @brief Set new buffer and process any data if already present
+ *
+ * This is internal function.
+ * The result of its execution is the library waiting for the event of the new data.
+ * If there is already any data that was returned from the CDC internal buffer
+ * it would be processed here.
+ */
+static void cdc_acm_process_and_prepare_buffer(app_usbd_cdc_acm_t const * p_cdc_acm)
+{
+ for (;;)
+ {
+ if (!nrf_queue_is_empty(&m_rx_queue))
+ {
+ mp_internal->p_cb->handler(NRF_CLI_TRANSPORT_EVT_RX_RDY, mp_internal->p_cb->p_context);
+ }
+ ret_code_t ret = app_usbd_cdc_acm_read_any(&nrf_cli_cdc_acm,
+ m_rx_buffer,
+ sizeof(m_rx_buffer));
+ if (ret == NRF_SUCCESS)
+ {
+ size_t size = app_usbd_cdc_acm_rx_size(p_cdc_acm);
+ size_t qsize = nrf_queue_in(&m_rx_queue, m_rx_buffer, size);
+ ASSERT(size == qsize);
+ UNUSED_VARIABLE(qsize);
+ }
+ else if (ret == NRF_ERROR_IO_PENDING)
+ {
+ break;
+ }
+ else
+ {
+ APP_ERROR_CHECK(ret);
+ break;
+ }
+ }
+}
+
+/**
+ * @brief User event handler.
+ * */
+static void cdc_acm_user_ev_handler(app_usbd_class_inst_t const * p_inst,
+ app_usbd_cdc_acm_user_event_t event)
+{
+ app_usbd_cdc_acm_t const * p_cdc_acm = app_usbd_cdc_acm_class_get(p_inst);
+
+
+ switch (event)
+ {
+ case APP_USBD_CDC_ACM_USER_EVT_PORT_OPEN:
+ {
+ /*Setup first transfer*/
+ cdc_acm_process_and_prepare_buffer(p_cdc_acm);
+ break;
+ }
+ case APP_USBD_CDC_ACM_USER_EVT_PORT_CLOSE:
+ break;
+ case APP_USBD_CDC_ACM_USER_EVT_TX_DONE:
+ mp_internal->p_cb->handler(NRF_CLI_TRANSPORT_EVT_TX_RDY, mp_internal->p_cb->p_context);
+ break;
+ case APP_USBD_CDC_ACM_USER_EVT_RX_DONE:
+ {
+ /*Get amount of data transfered*/
+ size_t size = app_usbd_cdc_acm_rx_size(p_cdc_acm);
+ size_t qsize = nrf_queue_in(&m_rx_queue, m_rx_buffer, size);
+ ASSERT(size == qsize);
+ UNUSED_VARIABLE(qsize);
+
+ /*Setup next transfer*/
+ cdc_acm_process_and_prepare_buffer(p_cdc_acm);
+ break;
+ }
+ default:
+ break;
+ }
+}
+
+static ret_code_t cli_cdc_acm_init(nrf_cli_transport_t const * p_transport,
+ void const * p_config,
+ nrf_cli_transport_handler_t evt_handler,
+ void * p_context)
+{
+ UNUSED_PARAMETER(p_config);
+ nrf_cli_cdc_acm_internal_t * p_internal =
+ CONTAINER_OF(p_transport, nrf_cli_cdc_acm_internal_t, transport);
+ p_internal->p_cb->handler = evt_handler;
+ p_internal->p_cb->p_context = p_context;
+
+ mp_internal = p_internal;
+ return NRF_SUCCESS;
+}
+
+static ret_code_t cli_cdc_acm_uninit(nrf_cli_transport_t const * p_transport)
+{
+ UNUSED_PARAMETER(p_transport);
+ return NRF_SUCCESS;
+}
+
+static ret_code_t cli_cdc_acm_enable(nrf_cli_transport_t const * p_transport,
+ bool blocking)
+{
+ UNUSED_PARAMETER(p_transport);
+ if (blocking)
+ {
+ return NRF_ERROR_NOT_SUPPORTED;
+ }
+ else
+ {
+ return NRF_SUCCESS;
+ }
+}
+
+static ret_code_t cli_cdc_acm_read(nrf_cli_transport_t const * p_transport,
+ void * p_data,
+ size_t length,
+ size_t * p_cnt)
+{
+ ASSERT(p_cnt);
+ UNUSED_PARAMETER(p_transport);
+ size_t size = nrf_queue_out(&m_rx_queue, p_data, length);
+ *p_cnt = size;
+
+ return NRF_SUCCESS;
+}
+
+static ret_code_t cli_cdc_acm_write(nrf_cli_transport_t const * p_transport,
+ void const * p_data,
+ size_t length,
+ size_t * p_cnt)
+{
+ ASSERT(p_cnt);
+ UNUSED_PARAMETER(p_transport);
+ ret_code_t ret;
+
+ ret = app_usbd_cdc_acm_write(&nrf_cli_cdc_acm, p_data, length);
+ if (ret == NRF_SUCCESS || ret == NRF_ERROR_INVALID_STATE)
+ {
+ *p_cnt = length;
+ ret = NRF_SUCCESS;
+ }
+ else if (ret == NRF_ERROR_BUSY)
+ {
+ *p_cnt = 0;
+ ret = NRF_SUCCESS;
+ }
+ else
+ {
+ /* Nothing to do */
+ }
+
+ return ret;
+}
+
+const nrf_cli_transport_api_t nrf_cli_cdc_acm_transport_api = {
+ .init = cli_cdc_acm_init,
+ .uninit = cli_cdc_acm_uninit,
+ .enable = cli_cdc_acm_enable,
+ .read = cli_cdc_acm_read,
+ .write = cli_cdc_acm_write,
+};
+
+#endif // NRF_MODULE_ENABLED(NRF_CLI_CDC_ACM)
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/cli/cdc_acm/nrf_cli_cdc_acm.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/cli/cdc_acm/nrf_cli_cdc_acm.h
new file mode 100644
index 0000000..a6d8829
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/cli/cdc_acm/nrf_cli_cdc_acm.h
@@ -0,0 +1,95 @@
+/**
+ * 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#ifndef NRF_CLI_CDC_ACM_H__
+#define NRF_CLI_CDC_ACM_H__
+
+#include <stdbool.h>
+
+#include "nrf_cli.h"
+#include "app_usbd_cdc_acm.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**@file
+ *
+ * @defgroup nrf_cli_cdc_acm CDC ACM command line interface transport layer
+ * @ingroup nrf_cli
+ *
+ * @{
+ *
+ */
+
+/**
+ * @brief Command line interface transport.
+ */
+extern const nrf_cli_transport_api_t nrf_cli_cdc_acm_transport_api;
+
+/**
+ * @brief Command line interface class instance.
+ */
+extern const app_usbd_cdc_acm_t nrf_cli_cdc_acm;
+
+typedef struct {
+ nrf_cli_transport_handler_t handler;
+ void * p_context;
+} nrf_cli_cdc_acm_internal_cb_t;
+
+typedef struct {
+ nrf_cli_transport_t transport;
+ nrf_cli_cdc_acm_internal_cb_t * p_cb;
+} nrf_cli_cdc_acm_internal_t;
+
+/**@brief CLI USB transport definition */
+#define NRF_CLI_CDC_ACM_DEF(_name_) \
+ static nrf_cli_cdc_acm_internal_cb_t CONCAT_2(_name_, _cb); \
+ static const nrf_cli_cdc_acm_internal_t _name_ = { \
+ .transport = {.p_api = &nrf_cli_cdc_acm_transport_api}, \
+ .p_cb = &CONCAT_2(_name_, _cb), \
+ }
+
+/** @} */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* NRF_CLI_CDC_ACM_H__ */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/cli/cli_utils_cmds.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/cli/cli_utils_cmds.c
new file mode 100644
index 0000000..9c0805d
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/cli/cli_utils_cmds.c
@@ -0,0 +1,164 @@
+/**
+ * Copyright (c) 2018 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#include "nrf_cli.h"
+#include "nrf_log.h"
+
+static void cmd_reset(nrf_cli_t const * p_cli, size_t argc, char **argv)
+{
+ UNUSED_PARAMETER(argc);
+ UNUSED_PARAMETER(argv);
+
+ if (nrf_cli_help_requested(p_cli))
+ {
+ nrf_cli_help_print(p_cli, NULL, 0);
+ return;
+ }
+
+ NVIC_SystemReset();
+}
+
+
+static void cmd_error(nrf_cli_t const * p_cli, size_t argc, char **argv)
+{
+ UNUSED_PARAMETER(argc);
+ UNUSED_PARAMETER(argv);
+
+ if (nrf_cli_help_requested(p_cli))
+ {
+ nrf_cli_help_print(p_cli, NULL, 0);
+ return;
+ }
+
+ APP_ERROR_CHECK(NRF_ERROR_INTERNAL);
+}
+
+
+static void cmd_app_size(nrf_cli_t const * p_cli, size_t argc, char **argv)
+{
+ UNUSED_PARAMETER(argc);
+ UNUSED_PARAMETER(argv);
+
+ if (nrf_cli_help_requested(p_cli))
+ {
+ nrf_cli_help_print(p_cli, NULL, 0);
+ return;
+ }
+
+ nrf_cli_fprintf(p_cli,
+ NRF_CLI_NORMAL,
+ "Application address:%d (0x%08X), size: %d (0x%08X)\r\n",
+ CODE_START,
+ CODE_START,
+ CODE_SIZE,
+ CODE_SIZE);
+}
+
+
+static void cmd_log_msg_error(nrf_cli_t const * p_cli, size_t argc, char **argv)
+{
+ if (nrf_cli_help_requested(p_cli))
+ {
+ nrf_cli_help_print(p_cli, NULL, 0);
+ return;
+ }
+
+ switch (argc-1)
+ {
+ case 0:
+ NRF_LOG_ERROR("test error message");
+ break;
+ case 1:
+ NRF_LOG_ERROR("test error message: %d", strtol(argv[1], NULL, 10));
+ break;
+ case 2:
+ NRF_LOG_ERROR("test error message: %d %d", strtol(argv[1], NULL, 10),
+ strtol(argv[2], NULL, 10));
+ break;
+ default:
+ NRF_LOG_ERROR("test error message with more than 3 arguments");
+ break;
+ }
+}
+
+
+static void cmd_log_msg_warning(nrf_cli_t const * p_cli, size_t argc, char **argv)
+{
+ if (nrf_cli_help_requested(p_cli))
+ {
+ nrf_cli_help_print(p_cli, NULL, 0);
+ return;
+ }
+
+ switch (argc-1)
+ {
+ case 0:
+ NRF_LOG_WARNING("test warning message");
+ break;
+ case 1:
+ NRF_LOG_WARNING("test warning message: %d", strtol(argv[1], NULL, 10));
+ break;
+ case 2:
+ NRF_LOG_WARNING("test warning message: %d %d", strtol(argv[1], NULL, 10),
+ strtol(argv[2], NULL, 10));
+ break;
+ default:
+ NRF_LOG_WARNING("test warning message with more than 3 arguments");
+ break;
+ }
+}
+
+/**
+ * @brief Command set array
+ * */
+
+NRF_CLI_CMD_REGISTER(reset, NULL, "System reset.", cmd_reset);
+
+NRF_CLI_CMD_REGISTER(error, NULL, "Trigger error.", cmd_error);
+
+NRF_CLI_CMD_REGISTER(app_size, NULL, "Print application size.", cmd_app_size);
+
+NRF_CLI_CREATE_STATIC_SUBCMD_SET(m_sub_log_msg)
+{
+ NRF_CLI_CMD(error, NULL, "Error log message with parameters", cmd_log_msg_error),
+ NRF_CLI_CMD(warning, NULL, "Warning log message with parameters", cmd_log_msg_warning),
+ NRF_CLI_SUBCMD_SET_END
+};
+
+NRF_CLI_CMD_REGISTER(log_msg, &m_sub_log_msg, "Trigger log message with decimal arguments", NULL);
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/cli/libuarte/nrf_cli_libuarte.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/cli/libuarte/nrf_cli_libuarte.c
new file mode 100644
index 0000000..d64e141
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/cli/libuarte/nrf_cli_libuarte.c
@@ -0,0 +1,247 @@
+/**
+ * Copyright (c) 2018 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#include "sdk_common.h"
+#include "nrf_cli_libuarte.h"
+#include "nrf_libuarte_async.h"
+#include "nrf_assert.h"
+
+#define NRF_LOG_MODULE_NAME cli_libuarte
+#if NRF_CLI_LIBUARTE_CONFIG_LOG_ENABLED
+#define NRF_LOG_LEVEL NRF_CLI_LIBUARTE_CONFIG_LOG_LEVEL
+#define NRF_LOG_INFO_COLOR NRF_CLI_LIBUARTE_CONFIG_INFO_COLOR
+#define NRF_LOG_DEBUG_COLOR NRF_CLI_LIBUARTE_CONFIG_DEBUG_COLOR
+#else //NRF_CLI_LIBUARTE_CONFIG_LOG_ENABLED
+#define NRF_LOG_LEVEL 0
+#endif //NRF_CLI_LIBUARTE_CONFIG_LOG_ENABLED
+#include "nrf_log.h"
+NRF_LOG_MODULE_REGISTER();
+
+static cli_libuarte_internal_t * mp_internal;
+static bool m_uart_busy;
+
+static void uart_event_handler(nrf_libuarte_async_evt_t * p_event)
+{
+ cli_libuarte_internal_t * p_internal = mp_internal;
+ ret_code_t err_code = NRF_SUCCESS;
+ size_t len;
+ UNUSED_VARIABLE(err_code);
+ switch (p_event->type)
+ {
+ case NRF_LIBUARTE_ASYNC_EVT_ERROR:
+ NRF_LOG_WARNING("(evt) ERROR");
+
+ break;
+
+ case NRF_LIBUARTE_ASYNC_EVT_RX_DATA:
+ {
+ len = (size_t)((uint32_t)p_event->data.rxtx.length & 0x0000FFFF);
+ err_code = nrf_ringbuf_cpy_put(p_internal->p_rx_ringbuf,
+ p_event->data.rxtx.p_data,
+ &len);
+ ASSERT(err_code == NRF_SUCCESS);
+
+ if (len != p_event->data.rxtx.length)
+ {
+ NRF_LOG_WARNING("Data lost, no room in RX ringbuf");
+ }
+ nrf_libuarte_async_rx_free(p_event->data.rxtx.p_data, p_event->data.rxtx.length);
+
+ if (p_event->data.rxtx.length)
+ {
+ NRF_LOG_DEBUG("(evt) RXRDY length:%d", p_event->data.rxtx.length);
+ NRF_LOG_HEXDUMP_DEBUG(p_event->data.rxtx.p_data, p_event->data.rxtx.length);
+ p_internal->p_cb->handler(NRF_CLI_TRANSPORT_EVT_RX_RDY,
+ p_internal->p_cb->p_context);
+ }
+
+ break;
+ }
+
+ case NRF_LIBUARTE_ASYNC_EVT_TX_DONE:
+ err_code = nrf_ringbuf_free(p_internal->p_tx_ringbuf, p_event->data.rxtx.length);
+ ASSERT(err_code == NRF_SUCCESS);
+ uint8_t * p_data;
+ len = 255;
+ err_code = nrf_ringbuf_get(p_internal->p_tx_ringbuf, &p_data, &len, true);
+ ASSERT(err_code == NRF_SUCCESS);
+ if (len)
+ {
+ NRF_LOG_DEBUG("(evt) Started TX (%d).", len);
+ err_code = nrf_libuarte_async_tx(p_data, len);
+ ASSERT(err_code == NRF_SUCCESS);
+ }
+ else
+ {
+ m_uart_busy = false;
+ }
+ p_internal->p_cb->handler(NRF_CLI_TRANSPORT_EVT_TX_RDY, p_internal->p_cb->p_context);
+ NRF_LOG_DEBUG("(evt) TX completed (%d)", p_event->data.rxtx.length);
+ break;
+
+ default:
+ NRF_LOG_ERROR("(evt) Unknown event");
+ ASSERT(false);
+ break;
+ }
+}
+
+static ret_code_t cli_libuarte_init(nrf_cli_transport_t const * p_transport,
+ void const * p_config,
+ nrf_cli_transport_handler_t evt_handler,
+ void * p_context)
+{
+ cli_libuarte_internal_t * p_internal = CONTAINER_OF(p_transport,
+ cli_libuarte_internal_t,
+ transport);
+ mp_internal = p_internal;
+ m_uart_busy = false;
+
+ p_internal->p_cb->handler = evt_handler;
+ p_internal->p_cb->p_context = p_context;
+ p_internal->p_cb->blocking = false;
+
+ cli_libuarte_config_t const * p_cli_libuarte_config = (cli_libuarte_config_t *)p_config;
+ nrf_libuarte_async_config_t uart_async_config = {
+ .tx_pin = p_cli_libuarte_config->tx_pin,
+ .rx_pin = p_cli_libuarte_config->rx_pin,
+ .baudrate = p_cli_libuarte_config->baudrate,
+ .parity = p_cli_libuarte_config->parity,
+ .hwfc = p_cli_libuarte_config->hwfc,
+ .timeout_us = 100,
+ };
+ ret_code_t err_code = nrf_libuarte_async_init(&uart_async_config, uart_event_handler);
+ if (err_code == NRF_SUCCESS)
+ {
+ nrf_ringbuf_init(p_internal->p_rx_ringbuf);
+ nrf_ringbuf_init(p_internal->p_tx_ringbuf);
+ }
+ return err_code;
+}
+
+static ret_code_t cli_libuarte_uninit(nrf_cli_transport_t const * p_transport)
+{
+ UNUSED_PARAMETER(p_transport);
+ nrf_libuarte_async_uninit();
+ return NRF_SUCCESS;
+}
+
+static ret_code_t cli_libuarte_enable(nrf_cli_transport_t const * p_transport,
+ bool blocking)
+{
+ UNUSED_PARAMETER(p_transport);
+ if (blocking)
+ {
+ return NRF_ERROR_NOT_SUPPORTED;
+ }
+ else
+ {
+ nrf_libuarte_async_enable(255);
+ }
+ return NRF_SUCCESS;
+}
+
+static ret_code_t cli_libuarte_read(nrf_cli_transport_t const * p_transport,
+ void * p_data,
+ size_t length,
+ size_t * p_cnt)
+{
+ ASSERT(p_cnt);
+ cli_libuarte_internal_t * p_instance =
+ CONTAINER_OF(p_transport, cli_libuarte_internal_t, transport);
+
+ *p_cnt = length;
+ ret_code_t err_code = nrf_ringbuf_cpy_get(p_instance->p_rx_ringbuf, p_data, p_cnt);
+
+ if (*p_cnt)
+ {
+ NRF_LOG_DEBUG("Read %d bytes (requested %d)", *p_cnt, length);
+ }
+
+ return err_code;
+}
+
+static ret_code_t cli_libuarte_write(nrf_cli_transport_t const * p_transport,
+ void const * p_data,
+ size_t length,
+ size_t * p_cnt)
+{
+ ASSERT(p_cnt);
+ cli_libuarte_internal_t * p_instance = CONTAINER_OF(p_transport,
+ cli_libuarte_internal_t,
+ transport);
+ *p_cnt = length;
+ ret_code_t err_code = nrf_ringbuf_cpy_put(p_instance->p_tx_ringbuf, p_data, p_cnt);
+ if (err_code == NRF_SUCCESS)
+ {
+ NRF_LOG_DEBUG("Requested write: %d, copied to ringbuf: %d.", length, *p_cnt);
+
+ if (m_uart_busy)
+ {
+ return err_code;
+ }
+
+ uint8_t * p_buf;
+ size_t len = 255;
+ if (nrf_ringbuf_get(p_instance->p_tx_ringbuf, &p_buf, &len, true) == NRF_SUCCESS)
+ {
+ NRF_LOG_DEBUG("Started TX (%d).", len);
+
+ err_code = nrf_libuarte_async_tx(p_buf, len);
+ if (p_instance->p_cb->blocking && (err_code == NRF_SUCCESS))
+ {
+ (void)nrf_ringbuf_free(p_instance->p_tx_ringbuf, len);
+ }
+ else
+ {
+ m_uart_busy = true;
+ }
+ }
+ }
+ return err_code;
+}
+
+const nrf_cli_transport_api_t cli_libuarte_transport_api = {
+ .init = cli_libuarte_init,
+ .uninit = cli_libuarte_uninit,
+ .enable = cli_libuarte_enable,
+ .read = cli_libuarte_read,
+ .write = cli_libuarte_write,
+};
+
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/cli/libuarte/nrf_cli_libuarte.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/cli/libuarte/nrf_cli_libuarte.h
new file mode 100644
index 0000000..e37fe64
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/cli/libuarte/nrf_cli_libuarte.h
@@ -0,0 +1,112 @@
+/**
+ * Copyright (c) 2018 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#ifndef NRF_LOG_BACKEND_LIBUARTE_H__
+#define NRF_LOG_BACKEND_LIBUARTE_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "nrf_cli.h"
+#include "nrf_libuarte.h"
+#include "nrf_ringbuf.h"
+#include "app_timer.h"
+
+/**@file
+ *
+ * @defgroup nrf_cli_libuarte libUARTE command line interface transport layer.
+ * @ingroup nrf_cli
+ *
+ * @{
+ *
+ */
+
+/**
+ * @brief Command line interface transport.
+ * */
+extern const nrf_cli_transport_api_t cli_libuarte_transport_api;
+
+typedef struct cli_libuarte_internal_s cli_libuarte_internal_t;
+
+typedef struct {
+ nrf_cli_transport_handler_t handler;
+ void * p_context;
+ bool blocking;
+} cli_libuarte_internal_cb_t;
+
+struct cli_libuarte_internal_s {
+ nrf_cli_transport_t transport;
+ cli_libuarte_internal_cb_t * p_cb;
+ nrf_ringbuf_t const * p_rx_ringbuf;
+ nrf_ringbuf_t const * p_tx_ringbuf;
+};
+
+typedef struct
+{
+ uint32_t tx_pin;
+ uint32_t rx_pin;
+ nrf_uarte_hwfc_t hwfc; ///< Flow control configuration.
+ nrf_uarte_parity_t parity; ///< Parity configuration.
+ nrf_uarte_baudrate_t baudrate; ///< Baudrate.
+} cli_libuarte_config_t;
+
+/**@brief CLI libUARTE transport definition.
+ *
+ * @param _name Name of instance.
+ * @param _tx_buf_sz Size of TX ring buffer.
+ * @param _rx_buf_sz Size of RX ring buffer.
+ */
+#define NRF_CLI_LIBUARTE_DEF(_name, _tx_buf_sz, _rx_buf_sz) \
+ NRF_RINGBUF_DEF(CONCAT_2(_name,_tx_ringbuf), _tx_buf_sz); \
+ NRF_RINGBUF_DEF(CONCAT_2(_name,_rx_ringbuf), _rx_buf_sz); \
+ static cli_libuarte_internal_cb_t CONCAT_2(_name, _cb); \
+ static const cli_libuarte_internal_t _name = { \
+ .transport = {.p_api = &cli_libuarte_transport_api}, \
+ .p_cb = &CONCAT_2(_name, _cb), \
+ .p_rx_ringbuf = &CONCAT_2(_name,_rx_ringbuf), \
+ .p_tx_ringbuf = &CONCAT_2(_name,_tx_ringbuf), \
+ }
+/** @} */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* NRF_LOG_BACKEND_LIBUARTE_H__ */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/cli/nrf_cli.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/cli/nrf_cli.c
new file mode 100644
index 0000000..1e4eba5
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/cli/nrf_cli.c
@@ -0,0 +1,3500 @@
+/**
+ * Copyright (c) 2016 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#include "sdk_common.h"
+#if NRF_MODULE_ENABLED(NRF_CLI)
+#include <ctype.h>
+#include <stdarg.h>
+#include <stdlib.h>
+#include "nrf_cli.h"
+#include "nrf_cli_vt100.h"
+#include "app_error.h"
+#include "nrf_assert.h"
+#include "nrf_delay.h"
+#include "nrf_pwr_mgmt.h"
+#include "nrf_atomic.h"
+
+#if NRF_MODULE_ENABLED(NRF_CLI_WILDCARD)
+#include "fnmatch.h"
+#endif
+
+#if NRF_MODULE_ENABLED(NRF_CLI_HISTORY)
+ #if NRF_CLI_HISTORY_ELEMENT_SIZE * NRF_CLI_HISTORY_ELEMENT_COUNT == 0
+ #error Not proper memory size allocated for NRF_CLI_HISTORY
+ #endif
+#endif
+
+/* 2 == 1 char for cmd + 1 char for '\0' */
+#if NRF_CLI_CMD_BUFF_SIZE < 2
+ #error too small NRF_CLI_CMD_BUFF_SIZE
+#endif
+
+#if NRF_CLI_PRINTF_BUFF_SIZE < 1
+ #error too small NRF_CLI_PRINTF_BUFF_SIZE
+#endif
+
+#define NRF_CLI_HELP_CLEAR "Clear screen."
+#define NRF_CLI_HELP_COLORS "Toggle colored syntax."
+#define NRF_CLI_HELP_COLORS_OFF "Disable colored syntax."
+#define NRF_CLI_HELP_COLORS_ON "Enable colored syntax."
+#define NRF_CLI_HELP_STATISTICS "CLI statistics."
+#define NRF_CLI_HELP_STATISTICS_SHOW "Get CLI statistics for the Logger module."
+#define NRF_CLI_HELP_STATISTICS_RESET "Reset CLI statistics for the Logger module."
+#define NRF_CLI_HELP_RESIZE "Console gets terminal screen size or assumes 80 in case " \
+ "the readout fails. It must be executed after each terminal " \
+ "width change to ensure correct text display."
+#define NRF_CLI_HELP_RESIZE_DEFAULT "Assume 80 chars screen width and send this setting " \
+ "to the terminal."
+#define NRF_CLI_HELP_HISTORY "Command history."
+#define NRF_CLI_HELP_ECHO "Toggle CLI echo."
+#define NRF_CLI_HELP_ECHO_ON "Enable CLI echo."
+#define NRF_CLI_HELP_ECHO_OFF "Disable CLI echo. Arrows and buttons: Backspace, " \
+ "Delete, End, Home, Insert are not handled."
+#define NRF_CLI_HELP_CLI "Useful, not Unix-like CLI commands."
+
+#define NRF_CLI_MSG_SPECIFY_SUBCOMMAND "Please specify a subcommand.\r\n"
+#define NRF_CLI_MSG_UNKNOWN_PARAMETER " unknown parameter: "
+#define NRF_CLI_MSG_COMMAND_NOT_FOUND ": command not found"
+#define NRF_CLI_MSG_TAB_OVERFLOWED "Tab function: commands counter overflowed.\r\n"
+
+/*lint -save -esym(526,cli_command*) -esym(526,cli_sorted_cmd_ptrs*)*/
+NRF_SECTION_DEF(cli_command, nrf_cli_cmd_entry_t);
+#define CLI_DATA_SECTION_ITEM_GET(i) NRF_SECTION_ITEM_GET(cli_command, nrf_cli_cmd_entry_t, (i))
+#define CLI_DATA_SECTION_ITEM_COUNT NRF_SECTION_ITEM_COUNT(cli_command, nrf_cli_cmd_entry_t)
+
+NRF_SECTION_DEF(cli_sorted_cmd_ptrs, const char *);
+/*lint -restore*/
+#define CLI_SORTED_CMD_PTRS_ITEM_GET(i) NRF_SECTION_ITEM_GET(cli_sorted_cmd_ptrs, const char *, (i))
+#define CLI_SORTED_CMD_PTRS_START_ADDR_GET NRF_SECTION_START_ADDR(cli_sorted_cmd_ptrs)
+
+#if defined(NRF_CLI_LOG_BACKEND) && NRF_CLI_LOG_BACKEND
+#include "nrf_log_str_formatter.h"
+#include "nrf_log_internal.h"
+#endif
+
+#define NRF_CLI_INIT_OPTION_PRINTER (NULL)
+
+#define NRF_CLI_MAX_TERMINAL_SIZE (250u)
+#define NRF_CLI_CURSOR_POSITION_BUFFER (10u) /* 10 == {esc, [, 2, 5, 0, ;, 2, 5, 0, '\0'} */
+#define NRF_CLI_DEFAULT_TERMINAL_WIDTH (80u) /* Default PuTTY width. */
+#define NRF_CLI_DEFAULT_TERMINAL_HEIGHT (24u) /* Default PuTTY height. */
+#define NRF_CLI_INITIAL_CURS_POS (1u) /* Initial cursor position is: (1, 1). */
+
+#define NRF_CLI_CMD_ROOT_LVL (0u)
+
+/* Macro to send VT100 commands. */
+#define NRF_CLI_VT100_CMD(_p_cli_, _cmd_) { \
+ ASSERT(_p_cli_); \
+ ASSERT(_p_cli_->p_fprintf_ctx); \
+ static char const cmd[] = _cmd_; \
+ nrf_fprintf(_p_cli_->p_fprintf_ctx, "%s", cmd); \
+}
+
+#if NRF_MODULE_ENABLED(NRF_CLI_WILDCARD)
+typedef enum
+{
+ WILDCARD_CMD_ADDED,
+ WILDCARD_CMD_ADDED_MISSING_SPACE,
+ WILDCARD_CMD_NO_MATCH_FOUND
+} wildcard_cmd_status_t;
+#endif
+
+
+static bool cli_log_entry_process(nrf_cli_t const * p_cli, bool skip);
+static void cli_execute(nrf_cli_t const * p_cli);
+
+
+static inline void transport_buffer_flush(nrf_cli_t const * p_cli)
+{
+ nrf_fprintf_buffer_flush(p_cli->p_fprintf_ctx);
+}
+
+static inline void cli_flag_help_set(nrf_cli_t const * p_cli)
+{
+ p_cli->p_ctx->internal.flag.show_help = 1;
+}
+static inline void cli_flag_help_clear(nrf_cli_t const * p_cli)
+{
+ p_cli->p_ctx->internal.flag.show_help = 0;
+}
+
+static inline void cli_flag_echo_set(nrf_cli_t const * p_cli)
+{
+ p_cli->p_ctx->internal.flag.echo = 1;
+}
+
+static inline void cli_flag_echo_clear(nrf_cli_t const * p_cli)
+{
+ p_cli->p_ctx->internal.flag.echo = 0;
+}
+
+static inline bool cli_flag_echo_is_set(nrf_cli_t const * p_cli)
+{
+ return p_cli->p_ctx->internal.flag.echo == 1 ? true : false;
+}
+
+static inline bool cli_flag_processing_is_set(nrf_cli_t const * p_cli)
+{
+ return p_cli->p_ctx->internal.flag.processing == 1 ? true : false;
+}
+
+static inline void recieve_state_change(nrf_cli_t const * p_cli, nrf_cli_receive_t state)
+{
+ p_cli->p_ctx->receive_state = state;
+}
+
+static inline size_t cli_strlen(char const * str)
+{
+ return str == NULL ? 0 : strlen(str);
+}
+
+/* Function returns true if cursor is at beginning of an empty line. */
+static inline bool cursor_in_empty_line(nrf_cli_t const * p_cli)
+{
+ return ( (p_cli->p_ctx->cmd_buff_pos + cli_strlen(p_cli->p_name)) %
+ p_cli->p_ctx->vt100_ctx.cons.terminal_wid == 0);
+}
+
+/* Function returns true if command length is equal to multiplicity of terminal width. */
+static inline bool full_line_cmd(nrf_cli_t const * p_cli)
+{
+ return ((p_cli->p_ctx->cmd_buff_len + cli_strlen(p_cli->p_name)) %
+ p_cli->p_ctx->vt100_ctx.cons.terminal_wid == 0);
+}
+
+#if NRF_MODULE_ENABLED(NRF_CLI_WILDCARD)
+/* Function returns true if string contains wildcard character: '?' or '*'. */
+static bool wildcard_character_exist(char * p_str)
+{
+ size_t str_len = cli_strlen(p_str);
+ for (size_t i = 0; i < str_len; i++)
+ {
+ if ((p_str[i] == '?') || (p_str[i] == '*'))
+ {
+ return true;
+ }
+ }
+ return false;
+}
+#endif
+
+/* Function sends data stream to the CLI instance. Each time before the cli_write function is called,
+ * it must be ensured that IO buffer of fprintf is flushed to avoid synchronization issues.
+ * For that purpose, use function transport_buffer_flush(p_cli) */
+static void cli_write(nrf_cli_t const * p_cli,
+ void const * p_data,
+ size_t length,
+ size_t * p_cnt)
+{
+ ASSERT(p_cli && p_data);
+ ASSERT(p_cli->p_iface->p_api);
+ size_t offset = 0;
+ size_t cnt;
+ while (length)
+ {
+ ret_code_t ret = p_cli->p_iface->p_api->write(p_cli->p_iface,
+ &((uint8_t const *)p_data)[offset],
+ length,
+ &cnt);
+ UNUSED_VARIABLE(ret);
+ ASSERT(ret == NRF_SUCCESS);
+ ASSERT(length >= cnt);
+ offset += cnt;
+ length -= cnt;
+ if (cnt == 0 && (p_cli->p_ctx->state != NRF_CLI_STATE_PANIC_MODE_ACTIVE))
+ {
+#if NRF_MODULE_ENABLED(NRF_CLI_USES_TASK_MANAGER)
+ (void)task_events_wait(NRF_CLI_TRANSPORT_TX_RDY_TASK_EVT);
+#else
+ while (p_cli->p_ctx->internal.flag.tx_rdy == 0)
+ {
+ ;
+ }
+ p_cli->p_ctx->internal.flag.tx_rdy = 0;
+#endif
+ }
+ }
+
+ if (p_cnt)
+ {
+ *p_cnt = cnt;
+ }
+}
+
+/* Function sends 1 character to the CLI instance. */
+static inline void cli_putc(nrf_cli_t const * p_cli, char ch)
+{
+ nrf_fprintf(p_cli->p_fprintf_ctx, "%c", ch);
+}
+
+/* Function reads data from the CLI instance. */
+static void cli_read(nrf_cli_t const * p_cli,
+ void * p_data,
+ size_t length,
+ size_t * p_cnt)
+{
+ ASSERT(p_cli && p_data);
+ ASSERT(p_cli->p_iface);
+
+ ret_code_t ret = p_cli->p_iface->p_api->read(p_cli->p_iface, p_data, length, p_cnt);
+ UNUSED_VARIABLE(ret);
+}
+
+/* Function cmd_get shall be used to search commands. It moves the pointer pp_entry to command
+ * of static command structure. If the command cannot be found, the function will set pp_entry to NULL.
+ * p_command Pointer to command which will be processed (no matter the root command).
+ * lvl Level of the requested command.
+ * idx Index of the requested command.
+ * pp_entry Pointer which points to subcommand[idx] after function execution.
+ * p_st_entry Pointer to the structure where dynamic entry data can be stored.
+ */
+static void cmd_get(nrf_cli_cmd_entry_t const * p_command,
+ size_t lvl,
+ size_t idx,
+ nrf_cli_static_entry_t const ** pp_entry,
+ nrf_cli_static_entry_t * p_st_entry)
+{
+ ASSERT (pp_entry != NULL);
+ ASSERT (p_st_entry != NULL);
+
+ if (lvl == NRF_CLI_CMD_ROOT_LVL)
+ {
+ if (idx < CLI_DATA_SECTION_ITEM_COUNT)
+ {
+ nrf_cli_cmd_entry_t const * p_cmd = NULL;
+ char const * * pp_sorted_cmds = (char const * *)CLI_SORTED_CMD_PTRS_START_ADDR_GET;
+ for (size_t i = 0; i < CLI_DATA_SECTION_ITEM_COUNT; i++)
+ {
+ p_cmd = CLI_DATA_SECTION_ITEM_GET(i);
+ if (!strcmp(pp_sorted_cmds[idx], p_cmd->u.p_static->p_syntax))
+ {
+ *pp_entry = p_cmd->u.p_static;
+ return;
+ }
+ }
+ }
+ *pp_entry = NULL;
+ return;
+ }
+
+ if (p_command == NULL)
+ {
+ *pp_entry = NULL;
+ return;
+ }
+
+ if (p_command->is_dynamic)
+ {
+ p_command->u.p_dynamic_get(idx, p_st_entry);
+ if (p_st_entry->p_syntax == NULL)
+ {
+ *pp_entry = NULL;
+ }
+ else
+ {
+ *pp_entry = p_st_entry;
+ }
+ }
+ else
+ {
+ if (p_command->u.p_static[idx].p_syntax != NULL)
+ {
+ *pp_entry = &p_command->u.p_static[idx];
+ }
+ else
+ {
+ *pp_entry = NULL;
+ }
+ }
+}
+
+/* Function multiline_console_data_check checks the current cursor position (x, y) on terminal screen
+ * based on: command length, console name length, and terminal width.
+ * Example 1:
+ * || - cursor
+ * ----------------------------
+ * |console_name $: || |
+ * ----------------------------
+ * => coordinates are: cur_x = 17, cur_x_end = 17,
+ * cur_y = 1, cur_y_end = 1
+ * Example 2:
+ * ----------------------------
+ * |console_name $: test command|
+ * |showing |e|xample |
+ * ----------------------------
+ * => coordinates are: cur_x = 9, cur_x_end = 18 (cursor can be one column after 'e')
+ * => cur_y = 2, cur_y_end = 2
+ * Example 3:
+ * ----------------------------
+ * |console_name $: test command|
+ * |showing e|x|ample with more |
+ * |parameters |
+ * ----------------------------
+ * => coordinates are: cur_x = 10, cur_x_end = 11 (cursor can be one column after 's')
+ * => cur_y = 2, cur_y_end = 3
+ */
+static nrf_cli_multiline_cons_t const * multiline_console_data_check(nrf_cli_t const * p_cli)
+{
+ nrf_cli_ctx_t * p_ctx = p_cli->p_ctx;
+ nrf_cli_multiline_cons_t * p_cons = &p_cli->p_ctx->vt100_ctx.cons;
+
+ p_cons->name_len = cli_strlen(p_cli->p_name);
+
+ /* Current cursor position in command.
+ * +1 -> because home position is (1, 1) */
+ p_cons->cur_x = (p_ctx->cmd_buff_pos + p_cons->name_len) % p_cons->terminal_wid + 1;
+ p_cons->cur_y = (p_ctx->cmd_buff_pos + p_cons->name_len) / p_cons->terminal_wid + 1;
+
+ /* Extreme position when cursor is at the end of command. */
+ p_cons->cur_y_end = (p_ctx->cmd_buff_len + p_cons->name_len) / p_cons->terminal_wid + 1;
+ p_cons->cur_x_end = (p_ctx->cmd_buff_len + p_cons->name_len) % p_cons->terminal_wid + 1;
+
+ return p_cons;
+}
+
+/* Function sends VT100 command to clear the screen from cursor position to end of the screen. */
+static inline void cli_clear_eos(nrf_cli_t const * p_cli)
+{
+ NRF_CLI_VT100_CMD(p_cli, NRF_CLI_VT100_CLEAREOS);
+}
+
+/* Function sends VT100 command to save cursor position. */
+static inline void cli_cursor_save(nrf_cli_t const * p_cli)
+{
+ NRF_CLI_VT100_CMD(p_cli, NRF_CLI_VT100_SAVECURSOR);
+}
+
+/* Function sends VT100 command to restore saved cursor position. */
+static inline void cli_cursor_restore(nrf_cli_t const * p_cli)
+{
+ NRF_CLI_VT100_CMD(p_cli, NRF_CLI_VT100_RESTORECURSOR);
+}
+
+/* Function forcing new line - cannot be replaced with function cursor_down_move. */
+static inline void cursor_next_line_move(nrf_cli_t const * p_cli)
+{
+ NRF_CLI_VT100_CMD(p_cli, NRF_CLI_VT100_NEXTLINE);
+}
+
+/* Function moves cursor left by n positions. */
+static inline void cursor_left_move(nrf_cli_t const * p_cli, nrf_cli_cmd_len_t n)
+{
+ if (n > 0)
+ {
+ nrf_fprintf(p_cli->p_fprintf_ctx, "\033[%dD", n);
+ }
+}
+
+/* Function moves cursor right by n positions. */
+static inline void cursor_right_move(nrf_cli_t const * p_cli, nrf_cli_cmd_len_t n)
+{
+ if (n > 0)
+ {
+ nrf_fprintf(p_cli->p_fprintf_ctx, "\033[%dC", n);
+ }
+}
+
+/* Function moves cursor up by n positions. */
+static inline void cursor_up_move(nrf_cli_t const * p_cli, nrf_cli_cmd_len_t n)
+{
+ if (n > 0)
+ {
+ nrf_fprintf(p_cli->p_fprintf_ctx, "\033[%dA", n);
+ }
+}
+
+/* Function moves cursor down by n positions but it will bring no effect if cursor is in the last
+ * line of terminal screen. In such case, the cursor_next_line_move function shall be invoked. */
+static inline void cursor_down_move(nrf_cli_t const * p_cli, nrf_cli_cmd_len_t n)
+{
+ if (n > 0)
+ {
+ nrf_fprintf(p_cli->p_fprintf_ctx, "\033[%dB", n);
+ }
+}
+
+/* Function increments cursor position (if possible) and moves cursor to new line if necessary. */
+static void cursor_position_increment(nrf_cli_t const * p_cli)
+{
+ if (p_cli->p_ctx->cmd_buff_pos >= p_cli->p_ctx->cmd_buff_len)
+ {
+ return; /* incrementation not possible */
+ }
+
+ nrf_cli_multiline_cons_t const * p_cons = multiline_console_data_check(p_cli);
+ nrf_cli_cmd_len_t cur_y = p_cons->cur_y;
+ ++p_cli->p_ctx->cmd_buff_pos;
+ p_cons = multiline_console_data_check(p_cli);
+
+ if (cur_y == p_cons->cur_y)
+ {
+ cursor_right_move(p_cli, 1);
+ }
+ else
+ {
+ cursor_next_line_move(p_cli);
+ }
+}
+
+/* Function will move cursor back to position == cmd_buff_pos. Example usage is when cursor needs
+ * to be moved back after printing some text. This function cannot be used to move cursor to new
+ * location by manual change of cmd_buff_pos.*/
+static void cursor_position_synchronize(nrf_cli_t const * p_cli)
+{
+ nrf_cli_multiline_cons_t const * p_cons = multiline_console_data_check(p_cli);
+ bool last_line = p_cons->cur_y == p_cons->cur_y_end ? true : false;
+
+ /* In case cursor reaches the bottom line of a terminal, it will be moved to the next line. */
+ if (cursor_in_empty_line(p_cli) || full_line_cmd(p_cli))
+ {
+ cursor_next_line_move(p_cli);
+ }
+
+ if (last_line)
+ {
+ cursor_left_move(p_cli, p_cons->cur_x_end - p_cons->cur_x);
+ }
+ else
+ {
+ cursor_up_move(p_cli, p_cons->cur_y_end - p_cons->cur_y);
+ if (p_cons->cur_x > p_cons->cur_x_end)
+ {
+ cursor_right_move(p_cli, p_cons->cur_x - p_cons->cur_x_end);
+ }
+ else
+ {
+ cursor_left_move(p_cli, p_cons->cur_x_end - p_cons->cur_x);
+ }
+ }
+}
+
+/* Function moves cursor to begin of command position, just after console name. */
+static void cursor_home_position_move(nrf_cli_t const * p_cli)
+{
+ nrf_cli_multiline_cons_t const * p_cons = multiline_console_data_check(p_cli);
+
+ if ((p_cons->cur_x == p_cons->name_len + NRF_CLI_INITIAL_CURS_POS) &&
+ (p_cons->cur_y == NRF_CLI_INITIAL_CURS_POS))
+ {
+ return; /* nothing to handle because cursor is in start position */
+ }
+
+ if (p_cons->cur_y > NRF_CLI_INITIAL_CURS_POS)
+ {
+ cursor_up_move(p_cli, p_cons->cur_y - NRF_CLI_INITIAL_CURS_POS);
+ }
+
+ if (p_cons->cur_x > p_cons->name_len)
+ {
+ cursor_left_move(p_cli, p_cons->cur_x - NRF_CLI_INITIAL_CURS_POS - p_cons->name_len);
+ }
+ else
+ {
+ cursor_right_move(p_cli, p_cons->name_len + NRF_CLI_INITIAL_CURS_POS - p_cons->cur_x);
+ }
+ /* align data buffer pointer with cursor position */
+ p_cli->p_ctx->cmd_buff_pos = 0;
+}
+
+/* Function moves cursor to end of command. */
+static void cursor_end_position_move(nrf_cli_t const * p_cli)
+{
+ nrf_cli_multiline_cons_t const * p_cons = multiline_console_data_check(p_cli);
+
+ if ((p_cons->cur_x == p_cons->cur_x_end) && (p_cons->cur_y == p_cons->cur_y_end))
+ {
+ return; /* nothing to handle because cursor is in end position */
+ }
+
+ if (p_cons->cur_y_end > p_cons->cur_y)
+ {
+ cursor_down_move(p_cli, p_cons->cur_y_end - p_cons->cur_y);
+ }
+
+ if (p_cons->cur_x > p_cons->cur_x_end)
+ {
+ cursor_left_move(p_cli, p_cons->cur_x - p_cons->cur_x_end);
+ }
+ else
+ {
+ cursor_right_move(p_cli, p_cons->cur_x_end - p_cons->cur_x);
+ }
+ /* align data buffer pointer with cursor position */
+ p_cli->p_ctx->cmd_buff_pos = p_cli->p_ctx->cmd_buff_len;
+}
+
+#if NRF_MODULE_ENABLED(NRF_CLI_BUILD_IN_CMDS)
+/* Function reads cursor position from terminal. */
+static ret_code_t cursor_position_get(nrf_cli_t const * p_cli)
+{
+ size_t cnt;
+ uint16_t x = 0; /* horizontal position */
+ uint16_t y = 0; /* vertical position */
+ char c = 0;
+
+ nrf_cli_cmd_len_t buff_idx = 0;
+
+ /* clear temp buffer */
+ memset(p_cli->p_ctx->temp_buff, 0, sizeof(p_cli->p_ctx->temp_buff));
+
+ /* escape code asking terminal about its size */
+ static char const cmd_get_terminal_size[] = "\033[6n";
+
+ nrf_fprintf(p_cli->p_fprintf_ctx, cmd_get_terminal_size);
+ /* fprintf buffer needs to be flushed to start sending prepared escape code to the terminal */
+ transport_buffer_flush(p_cli);
+
+ /* timeout for terminal response = ~1s */
+ for (uint16_t i = 0; i < 1000; i++)
+ {
+ do
+ {
+ cli_read(p_cli, &c, sizeof(c), &cnt);
+ if (cnt == 0)
+ {
+ nrf_delay_us(999);
+ continue;
+ }
+ if ((c != NRF_CLI_VT100_ASCII_ESC) &&
+ (p_cli->p_ctx->temp_buff[0] != NRF_CLI_VT100_ASCII_ESC))
+ {
+ continue;
+ }
+
+ if (c == 'R') /* end of response from the terminal */
+ {
+ p_cli->p_ctx->temp_buff[buff_idx] = '\0';
+ if (p_cli->p_ctx->temp_buff[1] != '[')
+ {
+ p_cli->p_ctx->temp_buff[0] = 0;
+ return NRF_ERROR_INVALID_DATA;
+ }
+ buff_idx = 2; /* index start position in the buffer where 'y' is stored */
+ while (p_cli->p_ctx->temp_buff[buff_idx] != ';')
+ {
+ y = y * 10 + (p_cli->p_ctx->temp_buff[buff_idx++] - '0');
+ if (buff_idx >= NRF_CLI_CMD_BUFF_SIZE)
+ {
+ return NRF_ERROR_DATA_SIZE;
+ }
+ }
+ if (++buff_idx >= NRF_CLI_CMD_BUFF_SIZE)
+ {
+ return NRF_ERROR_DATA_SIZE;
+ }
+ while (p_cli->p_ctx->temp_buff[buff_idx] != '\0')
+ {
+ x = x * 10 + (p_cli->p_ctx->temp_buff[buff_idx++] - '0');
+ if (buff_idx >= NRF_CLI_CMD_BUFF_SIZE)
+ {
+ return NRF_ERROR_DATA_SIZE;
+ }
+ }
+ /* horizontal cursor position */
+ if (x > NRF_CLI_MAX_TERMINAL_SIZE)
+ {
+ p_cli->p_ctx->vt100_ctx.cons.cur_x = NRF_CLI_MAX_TERMINAL_SIZE;
+ }
+ else
+ {
+ p_cli->p_ctx->vt100_ctx.cons.cur_x = (nrf_cli_cmd_len_t)x;
+ }
+ /* vertical cursor position */
+ if (y > NRF_CLI_MAX_TERMINAL_SIZE)
+ {
+ p_cli->p_ctx->vt100_ctx.cons.cur_y = NRF_CLI_MAX_TERMINAL_SIZE;
+ }
+ else
+ {
+ p_cli->p_ctx->vt100_ctx.cons.cur_y = (nrf_cli_cmd_len_t)y;
+ }
+ p_cli->p_ctx->temp_buff[0] = 0;
+ return NRF_SUCCESS;
+ }
+ else
+ {
+ p_cli->p_ctx->temp_buff[buff_idx] = c;
+ }
+
+ if (++buff_idx > NRF_CLI_CURSOR_POSITION_BUFFER - 1)
+ {
+ p_cli->p_ctx->temp_buff[0] = 0;
+ /* data_buf[NRF_CLI_CURSOR_POSITION_BUFFER - 1] is reserved for '\0' */
+ return NRF_ERROR_NO_MEM;
+ }
+
+ } while (cnt > 0);
+ }
+ return NRF_ERROR_TIMEOUT;
+}
+
+/* Function gets terminal width and height. */
+static ret_code_t terminal_size_get(nrf_cli_t const * p_cli,
+ nrf_cli_cmd_len_t * p_length,
+ nrf_cli_cmd_len_t * p_height)
+{
+ ASSERT(p_length);
+ ASSERT(p_height);
+
+ uint16_t x;
+ uint16_t y;
+
+ if (cursor_position_get(p_cli) == NRF_SUCCESS)
+ {
+ x = p_cli->p_ctx->vt100_ctx.cons.cur_x;
+ y = p_cli->p_ctx->vt100_ctx.cons.cur_y;
+ /* assumption: terminal widht and height < 999 */
+ cursor_right_move(p_cli, NRF_CLI_MAX_TERMINAL_SIZE); /* move to last column */
+ cursor_down_move(p_cli, NRF_CLI_MAX_TERMINAL_SIZE); /* move to last row */
+ }
+ else
+ {
+ return NRF_ERROR_NOT_SUPPORTED;
+ }
+
+ if (cursor_position_get(p_cli) == NRF_SUCCESS)
+ {
+ *p_length = p_cli->p_ctx->vt100_ctx.cons.cur_x;
+ *p_height = p_cli->p_ctx->vt100_ctx.cons.cur_y;
+ cursor_left_move(p_cli, *p_length - x);
+ cursor_up_move(p_cli, *p_height - y);
+
+ return NRF_SUCCESS;
+ }
+ return NRF_ERROR_NOT_SUPPORTED;
+}
+#endif // NRF_MODULE_ENABLED(NRF_CLI_BUILD_IN_CMDS)
+
+#if NRF_MODULE_ENABLED(NRF_CLI_VT100_COLORS)
+static void vt100_color_set(nrf_cli_t const * p_cli, nrf_cli_vt100_color_t color)
+{
+ if (color != NRF_CLI_DEFAULT)
+ {
+ if (p_cli->p_ctx->vt100_ctx.col.col == color)
+ {
+ return;
+ }
+
+ uint8_t cmd[] = NRF_CLI_VT100_COLOR(color - 1);
+
+ p_cli->p_ctx->vt100_ctx.col.col = color;
+ nrf_fprintf(p_cli->p_fprintf_ctx, "%s", cmd);
+ }
+ else
+ {
+ static uint8_t const cmd[] = NRF_CLI_VT100_MODESOFF;
+
+ p_cli->p_ctx->vt100_ctx.col.col = color;
+ nrf_fprintf(p_cli->p_fprintf_ctx, "%s", cmd);
+ }
+}
+
+static void vt100_bgcolor_set(nrf_cli_t const * p_cli, nrf_cli_vt100_color_t bgcolor)
+{
+ if (bgcolor != NRF_CLI_DEFAULT)
+ {
+ if (p_cli->p_ctx->vt100_ctx.col.bgcol == bgcolor)
+ {
+ return;
+ }
+ /* -1 because default value is first in enum */
+ uint8_t cmd[] = NRF_CLI_VT100_BGCOLOR(bgcolor - 1);
+
+ p_cli->p_ctx->vt100_ctx.col.bgcol = bgcolor;
+ nrf_fprintf(p_cli->p_fprintf_ctx, "%s", cmd);
+ }
+}
+
+static inline void vt100_colors_store(nrf_cli_t const * p_cli,
+ nrf_cli_vt100_colors_t * p_color)
+{
+ memcpy(p_color, &p_cli->p_ctx->vt100_ctx.col, sizeof(nrf_cli_vt100_colors_t));
+}
+
+static void vt100_colors_restore(nrf_cli_t const * p_cli,
+ nrf_cli_vt100_colors_t const * p_color)
+{
+ vt100_color_set(p_cli, p_color->col);
+ vt100_bgcolor_set(p_cli, p_color->bgcol);
+}
+#endif // NRF_MODULE_ENABLED(NRF_CLI_VT100_COLORS)
+
+static void left_arrow_handle(nrf_cli_t const * p_cli)
+{
+ nrf_cli_multiline_cons_t const * p_cons = multiline_console_data_check(p_cli);
+
+ if ((p_cons->cur_x == p_cons->name_len + NRF_CLI_INITIAL_CURS_POS) &&
+ (p_cons->cur_y == NRF_CLI_INITIAL_CURS_POS))
+ {
+ return; /* nothing to handle because cursor is in start position */
+ }
+
+ if (p_cons->cur_x == NRF_CLI_INITIAL_CURS_POS)
+ { /* go to previous line */
+ cursor_up_move(p_cli, 1);
+ cursor_right_move(p_cli, p_cons->terminal_wid);
+ --p_cli->p_ctx->cmd_buff_pos;
+ }
+ else
+ {
+ cursor_left_move(p_cli, 1);
+ --p_cli->p_ctx->cmd_buff_pos;
+ }
+}
+
+static void right_arrow_handle(nrf_cli_t const * p_cli)
+{
+ nrf_cli_multiline_cons_t const * p_cons = multiline_console_data_check(p_cli);
+
+ if ((p_cons->cur_x == p_cons->cur_x_end) &&
+ (p_cons->cur_y == p_cons->cur_y_end))
+ {
+ return; /* nothing to handle because cursor is in start position */
+ }
+
+ if (p_cons->cur_x == p_cons->terminal_wid) /* go to next line */
+ {
+ cursor_down_move(p_cli, 1);
+ cursor_left_move(p_cli, p_cons->terminal_wid);
+ ++p_cli->p_ctx->cmd_buff_pos;
+ }
+ else
+ {
+ cursor_right_move(p_cli, 1);
+ ++p_cli->p_ctx->cmd_buff_pos;
+ }
+}
+
+static inline void char_insert_echo_off(nrf_cli_t const * p_cli, char data)
+{
+ if (p_cli->p_ctx->cmd_buff_len >= (NRF_CLI_CMD_BUFF_SIZE - 1))
+ {
+ return;
+ }
+
+ p_cli->p_ctx->cmd_buff[p_cli->p_ctx->cmd_buff_pos++] = data;
+ p_cli->p_ctx->cmd_buff[p_cli->p_ctx->cmd_buff_pos] = '\0';
+ ++p_cli->p_ctx->cmd_buff_len;
+}
+
+static void char_insert(nrf_cli_t const * p_cli, char data)
+{
+ nrf_cli_cmd_len_t diff;
+ bool ins_mode = (bool)p_cli->p_ctx->internal.flag.insert_mode;
+
+ diff = p_cli->p_ctx->cmd_buff_len - p_cli->p_ctx->cmd_buff_pos;
+
+ if (!ins_mode)
+ {
+ if (p_cli->p_ctx->cmd_buff_len >= (NRF_CLI_CMD_BUFF_SIZE - 1))
+ {
+ return;
+ }
+ if (diff > 0)
+ {
+ memmove(&p_cli->p_ctx->cmd_buff[p_cli->p_ctx->cmd_buff_pos + 1],
+ &p_cli->p_ctx->cmd_buff[p_cli->p_ctx->cmd_buff_pos],
+ diff);
+ }
+ }
+ else
+ {
+ if ((p_cli->p_ctx->cmd_buff_len >= (NRF_CLI_CMD_BUFF_SIZE - 1)) &&
+ (diff == 0))
+ {
+ /* If cmd buffer is full, it is possible to replace chars but adding new
+ is not allowed. */
+ return;
+ }
+ }
+
+ p_cli->p_ctx->cmd_buff[p_cli->p_ctx->cmd_buff_pos] = data;
+
+ if (!ins_mode)
+ {
+ p_cli->p_ctx->cmd_buff[++p_cli->p_ctx->cmd_buff_len] = '\0';
+ }
+
+ if (diff > 0)
+ {
+ nrf_cli_multiline_cons_t const * p_cons = multiline_console_data_check(p_cli);
+ bool last_line = p_cons->cur_y == p_cons->cur_y_end ? true : false;
+
+ /* Below if-else statement is to minimize esc codes transmission. */
+ if (last_line)
+ {
+ nrf_cli_fprintf(p_cli,
+ NRF_CLI_NORMAL,
+ "%s",
+ &p_cli->p_ctx->cmd_buff[p_cli->p_ctx->cmd_buff_pos]);
+ /* Move cursor one position left less in case of insert mode. */
+ cursor_left_move(p_cli, diff - ins_mode);
+ }
+ else
+ {
+ /* Save the current cursor position in order to get back after fprintf function. */
+ cli_cursor_save(p_cli);
+ nrf_cli_fprintf(p_cli,
+ NRF_CLI_NORMAL,
+ "%s",
+ &p_cli->p_ctx->cmd_buff[p_cli->p_ctx->cmd_buff_pos]);
+ cli_cursor_restore(p_cli);
+ /* Move cursor right by one position to edit the next character. */
+ cursor_right_move(p_cli, 1);
+ }
+ }
+ else
+ {
+ /* New char appended at the end of buffer. */
+ if (ins_mode)
+ {
+ p_cli->p_ctx->cmd_buff[++p_cli->p_ctx->cmd_buff_len] = '\0';
+ }
+ cli_putc(p_cli, data);
+ }
+
+ /* Incrementation needs to be executed before invoking function: cursor_in_empty_line. */
+ ++p_cli->p_ctx->cmd_buff_pos;
+
+ /* Forcing terminal to switch to a new line if the command is too long. */
+ if (cursor_in_empty_line(p_cli))
+ {
+ cursor_next_line_move(p_cli);
+ return;
+ }
+
+ if (full_line_cmd(p_cli))
+ {
+ nrf_cli_multiline_cons_t const * p_cons = multiline_console_data_check(p_cli);
+
+ /* The code below will force the terminal to scroll one line down when the currently entered command
+ * reaches lower right corner of the terminal screen. */
+ cursor_down_move(p_cli, p_cons->cur_y_end - p_cons->cur_y - 1);
+ cursor_next_line_move(p_cli);
+ cursor_up_move(p_cli, p_cons->cur_y_end - p_cons->cur_y);
+ cursor_right_move(p_cli, p_cons->cur_x - 1);
+ return;
+ }
+}
+
+static void char_backspace(nrf_cli_t const * p_cli)
+{
+ nrf_cli_cmd_len_t diff;
+
+ if ((p_cli->p_ctx->cmd_buff_len == 0) || (p_cli->p_ctx->cmd_buff_pos == 0))
+ {
+ return;
+ }
+
+ diff = p_cli->p_ctx->cmd_buff_len - p_cli->p_ctx->cmd_buff_pos;
+
+ memmove(&p_cli->p_ctx->cmd_buff[p_cli->p_ctx->cmd_buff_pos - 1],
+ &p_cli->p_ctx->cmd_buff[p_cli->p_ctx->cmd_buff_pos],
+ diff + 1);
+
+ --p_cli->p_ctx->cmd_buff_pos;
+ --p_cli->p_ctx->cmd_buff_len;
+
+ if (diff > 0)
+ {
+ cli_putc(p_cli, NRF_CLI_VT100_ASCII_BSPACE);
+
+ nrf_cli_multiline_cons_t const * p_cons = multiline_console_data_check(p_cli);
+ bool last_line = p_cons->cur_y == p_cons->cur_y_end ? true : false;
+
+ if (last_line)
+ {
+ nrf_cli_fprintf(p_cli,
+ NRF_CLI_NORMAL,
+ "%s",
+ &p_cli->p_ctx->cmd_buff[p_cli->p_ctx->cmd_buff_pos]);
+ cli_clear_eos(p_cli);
+ cursor_left_move(p_cli, diff);
+ }
+ else
+ {
+ /* If cursor is not in last cmd line, its position needs to be saved by
+ * VT100 command. */
+ cli_cursor_save(p_cli);
+ cli_clear_eos(p_cli);
+ nrf_cli_fprintf(p_cli,
+ NRF_CLI_NORMAL,
+ "%s",
+ &p_cli->p_ctx->cmd_buff[p_cli->p_ctx->cmd_buff_pos]);
+ cli_cursor_restore(p_cli);
+ }
+ }
+ else
+ {
+ static char const cmd_bspace[] = {
+ NRF_CLI_VT100_ASCII_BSPACE, ' ', NRF_CLI_VT100_ASCII_BSPACE, '\0'};
+ nrf_fprintf(p_cli->p_fprintf_ctx, "%s", cmd_bspace);
+ }
+}
+
+static void char_delete(nrf_cli_t const * p_cli)
+{
+ nrf_cli_cmd_len_t diff;
+
+ diff = p_cli->p_ctx->cmd_buff_len - p_cli->p_ctx->cmd_buff_pos;
+
+ if (diff == 0)
+ {
+ return;
+ }
+
+ memmove(&p_cli->p_ctx->cmd_buff[p_cli->p_ctx->cmd_buff_pos],
+ &p_cli->p_ctx->cmd_buff[p_cli->p_ctx->cmd_buff_pos + 1],
+ diff);
+
+ --p_cli->p_ctx->cmd_buff_len;
+
+ nrf_cli_multiline_cons_t const * p_cons = multiline_console_data_check(p_cli);
+ bool last_line = p_cons->cur_y == p_cons->cur_y_end ? true : false;
+
+ /* If last line of command is edited, there is no need for saving cursor position. */
+ if (last_line)
+ {
+ nrf_cli_fprintf(p_cli,
+ NRF_CLI_NORMAL,
+ "%s",
+ &p_cli->p_ctx->cmd_buff[p_cli->p_ctx->cmd_buff_pos]);
+ NRF_CLI_VT100_CMD(p_cli, NRF_CLI_VT100_CLEAREOL);
+ cursor_left_move(p_cli, --diff);
+ }
+ else
+ {
+ cli_cursor_save(p_cli);
+ cli_clear_eos(p_cli);
+ nrf_cli_fprintf(p_cli,
+ NRF_CLI_NORMAL,
+ "%s",
+ &p_cli->p_ctx->cmd_buff[p_cli->p_ctx->cmd_buff_pos]);
+ cli_cursor_restore(p_cli);
+ }
+}
+
+static char make_argv(size_t * p_argc, char ** pp_argv, char * p_cmd, uint8_t max_argc)
+{
+ char c;
+ char quote = 0;
+
+ *p_argc = 0;
+ do
+ {
+ c = *p_cmd;
+ if (c == '\0')
+ {
+ break;
+ }
+
+ if (isspace((int)c))
+ {
+ *p_cmd++ = '\0';
+ continue;
+ }
+
+ pp_argv[(*p_argc)++] = p_cmd;
+ quote = 0;
+
+ while (1)
+ {
+ c = *p_cmd;
+
+ if (c == '\0')
+ {
+ break;
+ }
+
+ if (!quote)
+ {
+ switch (c)
+ {
+ case '\\':
+ memmove(p_cmd, p_cmd + 1, cli_strlen(p_cmd));
+ p_cmd += 1;
+ continue;
+
+ case '\'':
+ case '\"':
+ memmove(p_cmd, p_cmd + 1, cli_strlen(p_cmd));
+ quote = c;
+ continue;
+ default:
+ break;
+ }
+ }
+
+ if (quote == c)
+ {
+ memmove(p_cmd, p_cmd + 1, cli_strlen(p_cmd));
+ quote = 0;
+ continue;
+ }
+
+ if (quote && c == '\\')
+ {
+ char t = *(p_cmd + 1);
+
+ if (t == quote)
+ {
+ memmove(p_cmd, p_cmd + 1, cli_strlen(p_cmd));
+ p_cmd += 1;
+ continue;
+ }
+
+ if (t == '0')
+ {
+ uint8_t i;
+ uint8_t v = 0;
+
+ for (i = 2; i < (2 + 3); i++)
+ {
+ t = *(p_cmd + i);
+
+ if (t >= '0' && t <= '7')
+ {
+ v = (v << 3) | (t - '0');
+ }
+ else
+ {
+ break;
+ }
+ }
+
+ if (i > 2)
+ {
+ memmove(p_cmd, p_cmd + (i - 1), cli_strlen(p_cmd) - (i - 2));
+ *p_cmd++ = v;
+ continue;
+ }
+ }
+
+ if (t == 'x')
+ {
+ uint8_t i;
+ uint8_t v = 0;
+
+ for (i = 2; i < (2 + 2); i++)
+ {
+ t = *(p_cmd + i);
+
+ if (t >= '0' && t <= '9')
+ {
+ v = (v << 4) | (t - '0');
+ }
+ else if (t >= 'a' && t <= 'f')
+ {
+ v = (v << 4) | (t - 'a' + 10);
+ }
+ else if (t >= 'A' && t <= 'F')
+ {
+ v = (v << 4) | (t - 'A' + 10);
+ }
+ else
+ {
+ break;
+ }
+ }
+
+ if (i > 2)
+ {
+ memmove(p_cmd, p_cmd + (i - 1), cli_strlen(p_cmd) - (i - 2));
+ *p_cmd++ = v;
+ continue;
+ }
+ }
+ }
+ if (!quote && isspace((int)c))
+ {
+ break;
+ }
+
+ p_cmd += 1;
+ }
+ } while (*p_argc < max_argc);
+
+ ASSERT(*p_argc <= NRF_CLI_ARGC_MAX);
+ pp_argv[*p_argc] = 0;
+
+ return quote;
+}
+
+static void cli_state_set(nrf_cli_t const * p_cli, nrf_cli_state_t state)
+{
+ p_cli->p_ctx->state = state;
+
+ if (state == NRF_CLI_STATE_ACTIVE)
+ {
+ p_cli->p_ctx->cmd_buff[0] = '\0'; /* clear command buffer */
+ p_cli->p_ctx->cmd_buff_pos = 0;
+ p_cli->p_ctx->cmd_buff_len = 0;
+ nrf_cli_fprintf(p_cli, NRF_CLI_INFO, "%s", p_cli->p_name);
+ }
+}
+
+#if NRF_MODULE_ENABLED(NRF_CLI_HISTORY)
+static inline void history_mode_exit(nrf_cli_t const * p_cli)
+{
+ p_cli->p_ctx->p_cmd_list_element = NULL;
+}
+
+static void history_handle(nrf_cli_t const * p_cli, bool up)
+{
+ nrf_cli_memobj_header_t header = {
+ .p_prev = NULL,
+ .p_next = NULL,
+ .cmd_len = 0
+ };
+ nrf_cli_cmd_len_t current_cmd_len;
+ bool skip = false;
+
+ if (!up) /* button down */
+ {
+ if (p_cli->p_ctx->p_cmd_list_element == NULL)
+ {
+ return;
+ }
+ cursor_home_position_move(p_cli);
+
+ nrf_memobj_read(p_cli->p_ctx->p_cmd_list_element,
+ &header,
+ NRF_CLI_HISTORY_HEADER_SIZE,
+ (uint32_t)0);
+
+ p_cli->p_ctx->p_cmd_list_element = header.p_next;
+ current_cmd_len = p_cli->p_ctx->cmd_buff_len;
+
+ if (p_cli->p_ctx->p_cmd_list_element == NULL)
+ {
+ if (cli_strlen(p_cli->p_ctx->temp_buff) > 0)
+ {
+ strcpy(p_cli->p_ctx->cmd_buff, p_cli->p_ctx->temp_buff);
+ }
+ else
+ {
+ p_cli->p_ctx->cmd_buff[0] = '\0';
+ }
+ header.cmd_len = cli_strlen(p_cli->p_ctx->cmd_buff);
+ skip = true;
+ }
+ }
+ else /* button up */
+ {
+ if ((p_cli->p_ctx->p_cmd_list_element == p_cli->p_ctx->p_cmd_list_tail) ||
+ (p_cli->p_ctx->p_cmd_list_head == NULL))
+ {
+ /* Nothing to display. */
+ return;
+ }
+ cursor_home_position_move(p_cli);
+
+ if (p_cli->p_ctx->p_cmd_list_element == NULL)
+ {
+ current_cmd_len = cli_strlen(p_cli->p_ctx->cmd_buff);
+
+ p_cli->p_ctx->p_cmd_list_element = p_cli->p_ctx->p_cmd_list_head;
+ /* Save the currently entered and not executed command. */
+ if (current_cmd_len > 0)
+ {
+ strcpy(p_cli->p_ctx->temp_buff, p_cli->p_ctx->cmd_buff);
+ }
+ else
+ {
+ p_cli->p_ctx->temp_buff[0] = '\0';
+ }
+ }
+ else
+ {
+ nrf_memobj_read(p_cli->p_ctx->p_cmd_list_element,
+ &header,
+ NRF_CLI_HISTORY_HEADER_SIZE,
+ (uint32_t)0);
+ current_cmd_len = header.cmd_len;
+ p_cli->p_ctx->p_cmd_list_element = header.p_prev;
+ }
+ }
+ if (!skip)
+ {
+ nrf_memobj_read(p_cli->p_ctx->p_cmd_list_element,
+ &header,
+ NRF_CLI_HISTORY_HEADER_SIZE,
+ (uint32_t)0);
+
+ nrf_memobj_read(p_cli->p_ctx->p_cmd_list_element,
+ p_cli->p_ctx->cmd_buff,
+ header.cmd_len + 1, /* +1 for '\0' */
+ (uint32_t)NRF_CLI_HISTORY_HEADER_SIZE);
+ }
+
+ p_cli->p_ctx->cmd_buff_pos = header.cmd_len;
+ p_cli->p_ctx->cmd_buff_len = header.cmd_len;
+
+ if (current_cmd_len > header.cmd_len)
+ {
+ cli_clear_eos(p_cli);
+ }
+
+ nrf_cli_fprintf(p_cli, NRF_CLI_NORMAL, "%s", p_cli->p_ctx->cmd_buff);
+ if (cursor_in_empty_line(p_cli) || full_line_cmd(p_cli))
+ {
+ cursor_next_line_move(p_cli);
+ }
+}
+
+static void history_list_element_add(nrf_cli_t const * p_cli, nrf_memobj_t * p_memobj)
+{
+ ASSERT(p_memobj != NULL);
+
+ nrf_cli_memobj_header_t header;
+
+ if (p_cli->p_ctx->p_cmd_list_head == NULL)
+ {
+ p_cli->p_ctx->p_cmd_list_head = p_memobj;
+ p_cli->p_ctx->p_cmd_list_tail = p_memobj;
+ header.p_prev = NULL;
+ header.p_next = NULL;
+ header.cmd_len = p_cli->p_ctx->cmd_buff_len;
+ }
+ else
+ {
+ nrf_memobj_read(p_cli->p_ctx->p_cmd_list_head,
+ &header,
+ NRF_CLI_HISTORY_HEADER_SIZE,
+ (uint32_t)0);
+
+ header.p_next = p_memobj;
+
+ nrf_memobj_write(p_cli->p_ctx->p_cmd_list_head,
+ &header,
+ NRF_CLI_HISTORY_HEADER_SIZE,
+ (uint32_t)0);
+
+ header.p_next = NULL;
+ header.p_prev = p_cli->p_ctx->p_cmd_list_head;
+ header.cmd_len = p_cli->p_ctx->cmd_buff_len;
+
+ p_cli->p_ctx->p_cmd_list_head = p_memobj;
+ }
+
+ nrf_memobj_write(p_memobj,
+ &header,
+ NRF_CLI_HISTORY_HEADER_SIZE,
+ (uint32_t)0);
+
+ nrf_memobj_write(p_memobj,
+ p_cli->p_ctx->cmd_buff,
+ p_cli->p_ctx->cmd_buff_len + 1, /* +1 for '\0' */
+ (uint32_t)NRF_CLI_HISTORY_HEADER_SIZE);
+}
+
+static void history_list_element_oldest_remove(nrf_cli_t const * p_cli)
+{
+ if (p_cli->p_ctx->p_cmd_list_tail == NULL)
+ {
+ return; // nothing to do
+ }
+
+ nrf_cli_memobj_header_t header;
+ nrf_memobj_t * p_memobj = p_cli->p_ctx->p_cmd_list_tail;
+
+ nrf_memobj_read(p_memobj,
+ &header,
+ NRF_CLI_HISTORY_HEADER_SIZE,
+ (uint32_t)0);
+
+ p_cli->p_ctx->p_cmd_list_tail = header.p_next;
+ memset(&header, 0, sizeof(nrf_cli_memobj_header_t));
+ nrf_memobj_write(p_memobj, &header, NRF_CLI_HISTORY_HEADER_SIZE, 0);
+ nrf_memobj_free(p_memobj);
+
+ /* Checking if memory objects list is empty. */
+ if (p_cli->p_ctx->p_cmd_list_tail == NULL)
+ {
+ p_cli->p_ctx->p_cmd_list_head = NULL;
+ return;
+ }
+
+ nrf_memobj_read(p_cli->p_ctx->p_cmd_list_tail,
+ &header,
+ NRF_CLI_HISTORY_HEADER_SIZE,
+ (uint32_t)0);
+
+ header.p_prev = NULL;
+ nrf_memobj_write(p_cli->p_ctx->p_cmd_list_tail, &header, NRF_CLI_HISTORY_HEADER_SIZE, 0);
+}
+
+static void history_list_free_memory(nrf_cli_t const * p_cli)
+{
+ while (p_cli->p_ctx->p_cmd_list_tail != NULL)
+ {
+ history_list_element_oldest_remove(p_cli);
+ }
+}
+
+static void history_save(nrf_cli_t const * p_cli)
+{
+ nrf_cli_cmd_len_t cmd_new_len = cli_strlen(p_cli->p_ctx->cmd_buff);
+
+ history_mode_exit(p_cli);
+
+ if (cmd_new_len == 0)
+ {
+ return;
+ }
+
+ /* Checking if newly entered command is not duplicated with previous one. */
+ if (p_cli->p_ctx->p_cmd_list_head != NULL)
+ {
+ nrf_cli_memobj_header_t header;
+
+ nrf_memobj_read(p_cli->p_ctx->p_cmd_list_head,
+ &header,
+ NRF_CLI_HISTORY_HEADER_SIZE,
+ (uint32_t)0);
+ if (cmd_new_len == header.cmd_len)
+ {
+ nrf_memobj_read(p_cli->p_ctx->p_cmd_list_head,
+ p_cli->p_ctx->temp_buff,
+ header.cmd_len + 1, /* +1 for '\0' */
+ (uint32_t)NRF_CLI_HISTORY_HEADER_SIZE);
+
+ if (strcmp(p_cli->p_ctx->cmd_buff, p_cli->p_ctx->temp_buff) == 0)
+ {
+ /* Duplicated command, nothing to save. */
+ p_cli->p_ctx->temp_buff[0] = '\0';
+ return;
+ }
+ p_cli->p_ctx->temp_buff[0] = '\0';
+ }
+ }
+
+ for (size_t idx = 0; idx < NRF_CLI_HISTORY_ELEMENT_COUNT; idx++)
+ {
+ nrf_memobj_t * p_memobj;
+
+ p_memobj = nrf_memobj_alloc(p_cli->p_cmd_hist_mempool,
+ ((size_t)NRF_CLI_HISTORY_HEADER_SIZE + cmd_new_len + 1));
+ if (p_memobj != NULL)
+ {
+ history_list_element_add(p_cli, p_memobj);
+ return;
+ }
+ else
+ {
+ history_list_element_oldest_remove(p_cli);
+ }
+ }
+ return;
+}
+#endif // NRF_MODULE_ENABLED(NRF_CLI_HISTORY)
+
+/* Function checks how many identical characters have two strings starting from the first character. */
+static nrf_cli_cmd_len_t str_similarity_check(char const * str_a, char const * str_b)
+{
+ nrf_cli_cmd_len_t cnt = 0;
+
+ while (str_a[cnt] != '\0')
+ {
+ if (str_a[cnt] != str_b[cnt])
+ {
+ return cnt;
+ }
+
+ if (++cnt == 0)
+ {
+ return --cnt; /* too long strings */
+ }
+ }
+ return cnt;
+}
+
+static void completion_insert(nrf_cli_t const * p_cli,
+ char const * p_compl,
+ nrf_cli_cmd_len_t compl_len)
+{
+ ASSERT (p_compl);
+
+ nrf_cli_cmd_len_t diff = p_cli->p_ctx->cmd_buff_len - p_cli->p_ctx->cmd_buff_pos;
+
+ if ((p_cli->p_ctx->cmd_buff_len + compl_len > NRF_CLI_CMD_BUFF_SIZE - 1) ||
+ (compl_len == 0))
+ {
+ return;
+ }
+
+ /* Make space for completion. */
+ memmove(&p_cli->p_ctx->cmd_buff[p_cli->p_ctx->cmd_buff_pos + compl_len],
+ &p_cli->p_ctx->cmd_buff[p_cli->p_ctx->cmd_buff_pos],
+ diff + 1); /* + 1 for '\0' */
+
+ /* Insert completion. */
+ memmove(&p_cli->p_ctx->cmd_buff[p_cli->p_ctx->cmd_buff_pos],
+ p_compl,
+ compl_len);
+
+ p_cli->p_ctx->cmd_buff_len = cli_strlen(p_cli->p_ctx->cmd_buff);
+ nrf_cli_fprintf(p_cli,
+ NRF_CLI_NORMAL,
+ "%s",
+ &p_cli->p_ctx->cmd_buff[p_cli->p_ctx->cmd_buff_pos]);
+ p_cli->p_ctx->cmd_buff_pos += compl_len;
+
+ if (cursor_in_empty_line(p_cli) || full_line_cmd(p_cli))
+ {
+ cursor_next_line_move(p_cli);
+ }
+
+ if (diff > 0)
+ {
+ cursor_position_synchronize(p_cli);
+ }
+}
+
+static void option_print(nrf_cli_t const * p_cli,
+ char const * p_option,
+ nrf_cli_cmd_len_t longest_option)
+{
+ static char const * tab = " ";
+
+ /* Function initialization has been requested. */
+ if (p_option == NULL)
+ {
+ p_cli->p_ctx->vt100_ctx.printed_cmd = 0;
+ return;
+ }
+ longest_option += cli_strlen(tab);
+
+ nrf_cli_cmd_len_t columns =
+ (p_cli->p_ctx->vt100_ctx.cons.terminal_wid - cli_strlen(tab)) / longest_option;
+ nrf_cli_cmd_len_t diff = longest_option - cli_strlen(p_option);
+
+ if (p_cli->p_ctx->vt100_ctx.printed_cmd++ % columns == 0)
+ {
+ nrf_cli_fprintf(p_cli, NRF_CLI_OPTION, "\r\n%s%s", tab, p_option);
+ }
+ else
+ {
+ nrf_cli_fprintf(p_cli, NRF_CLI_OPTION, "%s", p_option);
+ }
+ cursor_right_move(p_cli, diff);
+}
+
+static void cli_tab_handle(nrf_cli_t const * p_cli)
+{
+ size_t cmd_idx;
+ size_t cmd_last = 0;
+ size_t cmd_first = 0;
+
+ size_t argc;
+ char * argv[NRF_CLI_ARGC_MAX + 1]; /* +1 reserved for NULL in function make_argv */
+
+ nrf_cli_cmd_len_t cmd_lvl = NRF_CLI_CMD_ROOT_LVL;
+ nrf_cli_cmd_len_t cmd_longest = 0; /* longest matching command */
+
+ /* Calculating the longest possible completion length. -1 for '\0'. */
+ nrf_cli_cmd_len_t compl_len = (NRF_CLI_CMD_BUFF_SIZE - 1) - p_cli->p_ctx->cmd_buff_len;
+
+ if (compl_len == 0)
+ {
+ return;
+ }
+
+ /* Copy command from its beginning to cursor position. */
+ memcpy(p_cli->p_ctx->temp_buff,
+ p_cli->p_ctx->cmd_buff,
+ p_cli->p_ctx->cmd_buff_pos);
+
+ p_cli->p_ctx->temp_buff[p_cli->p_ctx->cmd_buff_pos] = '\0';
+
+ /* Check if the current cursor position points to the 'space' character. */
+ bool space = isspace((int)p_cli->p_ctx->cmd_buff[p_cli->p_ctx->cmd_buff_pos - 1]);
+
+#if NRF_MODULE_ENABLED(NRF_CLI_HISTORY)
+ /* If the Tab key is pressed, "history mode" must be terminated because tab and history handlers
+ are sharing the same array: temp_buff. */
+ history_mode_exit(p_cli);
+#endif
+
+ /* Create argument list. */
+ (void)make_argv(&argc,
+ &argv[0],
+ p_cli->p_ctx->temp_buff,
+ NRF_CLI_ARGC_MAX);
+
+ nrf_cli_cmd_len_t arg_len = cli_strlen(argv[cmd_lvl]);
+
+ /* Variable 'static_entry' is needed to handle dynamic commands. */
+ nrf_cli_static_entry_t static_entry;
+
+ nrf_cli_cmd_entry_t const * p_cmd = NULL;
+ nrf_cli_static_entry_t const * p_st_cmd = NULL;
+ nrf_cli_static_entry_t const * p_st_cmd_last = NULL;
+
+ do
+ {
+ if ((argc == 0) ||
+ (cmd_lvl >= argc - 1 + space))
+ {
+ if (space)
+ {
+ arg_len = 0;
+ }
+ else
+ {
+ arg_len = cli_strlen(argv[cmd_lvl]);
+ }
+
+ cmd_idx = 0;
+
+ while (1)
+ {
+ cmd_get(p_cmd, cmd_lvl, cmd_idx++, &p_st_cmd, &static_entry);
+
+ if (p_st_cmd == NULL)
+ {
+ /* No more commands available. */
+ break;
+ }
+
+ if (strncmp(argv[cmd_lvl], p_st_cmd->p_syntax, arg_len) != 0)
+ {
+ if (p_st_cmd_last != NULL)
+ {
+ /* No more matches will be found as commands are sorted alphabetically. */
+ break;
+ }
+ continue;
+ }
+ if (p_st_cmd_last == NULL)
+ {
+ cmd_first = cmd_idx - 1;
+ cmd_longest = cli_strlen(p_st_cmd->p_syntax);
+ if (compl_len > (cmd_longest - arg_len))
+ {
+ compl_len = cmd_longest - arg_len;
+ }
+ }
+ else
+ {
+ nrf_cli_cmd_len_t len = cli_strlen(p_st_cmd->p_syntax);
+ if (len > cmd_longest)
+ {
+ cmd_longest = len;
+ }
+
+ if (compl_len > 0) /* Checking if partial completion is possible */
+ {
+ nrf_cli_static_entry_t last_entry;
+ cmd_get(p_cmd, cmd_lvl, cmd_last, &p_st_cmd_last, &last_entry);
+
+ len = str_similarity_check(p_st_cmd->p_syntax + arg_len,
+ p_st_cmd_last->p_syntax + arg_len);
+ if (compl_len > len)
+ {
+ /* Determining the longest possible completion. */
+ compl_len = len;
+ }
+ }
+ }
+ cmd_last = cmd_idx - 1;
+ p_st_cmd_last = p_st_cmd;
+
+ if (cmd_idx == 0) /* Too many possibilities */
+ {
+ nrf_cli_fprintf(p_cli, NRF_CLI_WARNING, NRF_CLI_MSG_TAB_OVERFLOWED);
+ break;
+ }
+ }
+ }
+ else
+ {
+ cmd_idx = 0;
+
+ while (1)
+ {
+ cmd_get(p_cmd, cmd_lvl, cmd_idx++, &p_st_cmd, &static_entry);
+
+ if (cmd_idx == 0)
+ {
+ /* No match found and commands counter overflowed. */
+ nrf_cli_fprintf(p_cli, NRF_CLI_WARNING, NRF_CLI_MSG_TAB_OVERFLOWED);
+ return;
+ }
+
+ if (p_st_cmd == NULL) /* No more commands available */
+ {
+ return;
+ }
+
+#if NRF_MODULE_ENABLED(NRF_CLI_WILDCARD)
+ /* Ignore wildcard character arguments if they are "standalone". Example:
+ 1. log enable info b*<tab> -> "b*" is treated as a command so no match found
+ 2. log enable info b* <tab> -> "b* " is ignored, <tab> will prompt all available
+ commands. */
+ if (wildcard_character_exist(argv[cmd_lvl]))
+ {
+ break;
+ }
+#endif
+ /* Fuction "strcmp" is used because an exact match is required. */
+ if (strcmp(argv[cmd_lvl], p_st_cmd->p_syntax) == 0)
+ {
+ p_cmd = p_st_cmd->p_subcmd;
+ break;
+ }
+ }
+ }
+
+ if ((p_cmd == NULL) || (p_st_cmd == NULL))
+ {
+ break;
+ }
+
+ } while (++cmd_lvl < argc + space);
+
+ if (p_st_cmd_last == NULL)
+ {
+ /* No match found. */
+ return;
+ }
+
+ if (cmd_first == cmd_last) /* only one match found */
+ {
+ if (p_cmd->is_dynamic)
+ {
+ /* In case of dynamic entry, function cmd_get shall be called again for matching
+ * command index (cmd_last). It is because static_entry is most likely appended by
+ * not valid data.
+ */
+ cmd_get(p_cmd, cmd_lvl, cmd_last, &p_st_cmd_last, &static_entry);
+ }
+ if (cli_strlen(p_st_cmd_last->p_syntax) != arg_len) /* no exact match found */
+ {
+ completion_insert(p_cli, p_st_cmd_last->p_syntax + arg_len, compl_len);
+ }
+
+ /* Next character in the buffer is not 'space'. */
+ if (!isspace((int)p_cli->p_ctx->cmd_buff[p_cli->p_ctx->cmd_buff_pos]))
+ {
+ if (p_cli->p_ctx->internal.flag.insert_mode)
+ {
+ p_cli->p_ctx->internal.flag.insert_mode = 0;
+ char_insert(p_cli, ' ');
+ p_cli->p_ctx->internal.flag.insert_mode = 1;
+ }
+ else
+ {
+ char_insert(p_cli, ' ');
+ }
+ }
+ else
+ {
+ /* case:
+ | | -> cursor
+ cons_name $: valid_cmd valid_sub_cmd| |argument <tab>
+ */
+ cursor_position_increment(p_cli);
+ /* result:
+ cons_name $: valid_cmd valid_sub_cmd |a|rgument
+ */
+ }
+ return;
+ }
+
+ /* Printing all matching commands (options). */
+ option_print(p_cli, NRF_CLI_INIT_OPTION_PRINTER, cmd_longest);
+ for (cmd_idx = cmd_first; cmd_idx <= cmd_last; cmd_idx++)
+ {
+ cmd_get(p_cmd, cmd_lvl, cmd_idx, &p_st_cmd, &static_entry);
+ option_print(p_cli, p_st_cmd->p_syntax, cmd_longest);
+ }
+
+ nrf_cli_fprintf(p_cli, NRF_CLI_INFO, "\r\n%s", p_cli->p_name);
+ nrf_cli_fprintf(p_cli, NRF_CLI_NORMAL, "%s", p_cli->p_ctx->cmd_buff);
+
+ cursor_position_synchronize(p_cli);
+ completion_insert(p_cli, p_st_cmd_last->p_syntax + arg_len, compl_len);
+}
+
+#define NRF_CLI_ASCII_MAX_CHAR (127u)
+static inline ret_code_t ascii_filter(char const data)
+{
+ return (uint8_t)data > NRF_CLI_ASCII_MAX_CHAR ? NRF_ERROR_INVALID_DATA : NRF_SUCCESS;
+}
+
+static void cli_state_collect(nrf_cli_t const * p_cli)
+{
+ size_t count = 0;
+ char data;
+
+ while (1)
+ {
+ cli_read(p_cli, &data, sizeof(data), &count);
+ if (count == 0)
+ {
+ return;
+ }
+
+ if (ascii_filter(data) != NRF_SUCCESS)
+ {
+ continue;
+ }
+
+#if NRF_MODULE_ENABLED(NRF_PWR_MGMT)
+ nrf_pwr_mgmt_feed();
+#endif
+
+ switch (p_cli->p_ctx->receive_state)
+ {
+ case NRF_CLI_RECEIVE_DEFAULT:
+ if (data == p_cli->newline_char)
+ {
+ if (p_cli->p_ctx->cmd_buff_len == 0)
+ {
+ cursor_next_line_move(p_cli);
+ }
+ else
+ {
+ /* Command execution */
+ cli_execute(p_cli);
+ }
+ cli_state_set(p_cli, NRF_CLI_STATE_ACTIVE);
+ return;
+ }
+ switch (data)
+ {
+ case NRF_CLI_VT100_ASCII_ESC: /* ESCAPE */
+ recieve_state_change(p_cli, NRF_CLI_RECEIVE_ESC);
+ break;
+ case '\0':
+ break;
+ case '\t': /* TAB */
+ if (cli_flag_echo_is_set(p_cli))
+ {
+ cli_tab_handle(p_cli);
+ }
+ break;
+ case NRF_CLI_VT100_ASCII_BSPACE: /* BACKSPACE */
+ if (cli_flag_echo_is_set(p_cli))
+ {
+ char_backspace(p_cli);
+ }
+ break;
+ case NRF_CLI_VT100_ASCII_DEL: /* DELETE */
+ if (cli_flag_echo_is_set(p_cli))
+ {
+ char_delete(p_cli);
+ }
+ break;
+ default:
+ if (isprint((int)data))
+ {
+ if (cli_flag_echo_is_set(p_cli))
+ {
+ char_insert(p_cli, data);
+ }
+ else
+ {
+ char_insert_echo_off(p_cli, data);
+ }
+ }
+ break;
+ }
+ break;
+ case NRF_CLI_RECEIVE_ESC:
+ if (data == '[')
+ {
+ recieve_state_change(p_cli, NRF_CLI_RECEIVE_ESC_SEQ);
+ }
+ else
+ {
+ recieve_state_change(p_cli, NRF_CLI_RECEIVE_DEFAULT);
+ }
+ break;
+ case NRF_CLI_RECEIVE_ESC_SEQ:
+ recieve_state_change(p_cli, NRF_CLI_RECEIVE_DEFAULT);
+
+ if (!cli_flag_echo_is_set(p_cli))
+ {
+ return;
+ }
+
+ switch (data)
+ {
+#if NRF_MODULE_ENABLED(NRF_CLI_HISTORY)
+ case 'A': /* UP arrow */
+ history_handle(p_cli, true);
+ break;
+ case 'B': /* DOWN arrow */
+ history_handle(p_cli, false);
+ break;
+#endif
+ case 'C': /* RIGHT arrow */
+ right_arrow_handle(p_cli);
+ break;
+ case 'D': /* LEFT arrow */
+ left_arrow_handle(p_cli);
+ break;
+ case 'F': /* END Button */
+ cursor_end_position_move(p_cli);
+ break;
+ case 'H': /* HOME Button */
+ cursor_home_position_move(p_cli);
+ break;
+ case 'L': /* INSERT Button */
+ p_cli->p_ctx->internal.flag.insert_mode ^= 1;
+ break;
+ default:
+ break;
+ }
+ break;
+ default:
+ recieve_state_change(p_cli, NRF_CLI_RECEIVE_DEFAULT);
+ break;
+ }
+ }
+}
+
+/* Function remove white chars from beginning and end of command buffer. */
+static void cmd_trim(nrf_cli_t const * p_cli)
+{
+ nrf_cli_cmd_len_t i = 0;
+
+ if (p_cli->p_ctx->cmd_buff[0] == '\0') /* no command in the buffer */
+ {
+ return;
+ }
+
+ /* Counting white characters starting from beginning of the command. */
+ while (isspace((int)p_cli->p_ctx->cmd_buff[i++]))
+ {
+ if (i == 0)
+ {
+ p_cli->p_ctx->cmd_buff[0] = '\0';
+ return;
+ }
+ }
+
+ /* Removing counted white characters. */
+ if (--i > 0)
+ {
+ memmove(p_cli->p_ctx->cmd_buff,
+ p_cli->p_ctx->cmd_buff + i,
+ (p_cli->p_ctx->cmd_buff_len + 1) - i); /* +1 for '\0' */
+ p_cli->p_ctx->cmd_buff_len = p_cli->p_ctx->cmd_buff_len - i;
+ p_cli->p_ctx->cmd_buff_pos = p_cli->p_ctx->cmd_buff_len;
+ }
+
+ /* Counting white characters starting from end of command. */
+ char * p_end = &p_cli->p_ctx->cmd_buff[p_cli->p_ctx->cmd_buff_len - 1];
+ i = 0;
+ while (isspace((int)*p_end))
+ {
+ ++i;
+ --p_end;
+ }
+
+ /* Removing counted white characters. */
+ if (p_end != &p_cli->p_ctx->cmd_buff[p_cli->p_ctx->cmd_buff_len - 1])
+ {
+ p_cli->p_ctx->cmd_buff[p_cli->p_ctx->cmd_buff_len - i] = '\0';
+ p_cli->p_ctx->cmd_buff_len = p_cli->p_ctx->cmd_buff_len - i;
+ p_cli->p_ctx->cmd_buff_pos = p_cli->p_ctx->cmd_buff_len;
+ }
+}
+
+#if NRF_MODULE_ENABLED(NRF_CLI_WILDCARD)
+static void spaces_trim(char * p_char)
+{
+ nrf_cli_cmd_len_t shift = 0;
+ nrf_cli_cmd_len_t len = cli_strlen(p_char);
+
+ if (p_char == NULL)
+ {
+ return;
+ }
+
+ for (nrf_cli_cmd_len_t i = 0; i < len - 1; i++)
+ {
+ if (isspace((int)p_char[i]))
+ {
+ for (nrf_cli_cmd_len_t j = i + 1; j < len; j++)
+ {
+ if (isspace((int)p_char[j]))
+ {
+ shift++;
+ continue;
+ }
+ if (shift > 0)
+ {
+ memmove(&p_char[i + 1], &p_char[j], len - shift + 1); // +1 for EOS
+ len -= shift;
+ shift = 0;
+ }
+ break;
+ }
+ }
+ }
+}
+
+/* Adds new command and one space just before pattern */
+static bool command_to_tmp_buffer_add(nrf_cli_t const * p_cli,
+ char const * p_new_cmd,
+ char const * p_pattern)
+{
+ nrf_cli_cmd_len_t cmd_len = cli_strlen(p_new_cmd);
+ nrf_cli_cmd_len_t shift;
+ char * p_cmd_source_addr;
+
+ /* +1 for space */
+ if (((size_t)p_cli->p_ctx->cmd_tmp_buff_len + cmd_len + 1) > NRF_CLI_CMD_BUFF_SIZE)
+ {
+ nrf_cli_fprintf(p_cli,
+ NRF_CLI_WARNING,
+ "Command buffer is too short to expand all commands matching "
+ "wildcard pattern\r\n");
+ return false;
+ }
+
+ p_cmd_source_addr = strstr(p_cli->p_ctx->temp_buff, p_pattern);
+
+ if (p_cmd_source_addr == NULL)
+ {
+ return false;
+ }
+
+ shift = cli_strlen(p_cmd_source_addr);
+
+ /* make place for new command: + 1 for space + 1 for EOS */
+ memmove(p_cmd_source_addr + cmd_len + 1, p_cmd_source_addr, shift + 1);
+ memcpy(p_cmd_source_addr, p_new_cmd, cmd_len);
+ p_cmd_source_addr[cmd_len] = ' ';
+
+ p_cli->p_ctx->cmd_tmp_buff_len += cmd_len + 1; // + 1 for space
+
+ return true;
+}
+
+/* removes pattern and following space */
+static void pattern_from_tmp_buffer_remove(nrf_cli_t const * p_cli,
+ char const * p_pattern)
+{
+ size_t shift;
+ char * p_pattern_addr = strstr(p_cli->p_ctx->temp_buff, p_pattern);
+
+ nrf_cli_cmd_len_t pattern_len = cli_strlen(p_pattern);
+
+ if (p_pattern_addr == NULL)
+ {
+ return;
+ }
+
+ if (p_pattern_addr > p_cli->p_ctx->temp_buff)
+ {
+ if (*(p_pattern_addr - 1) == ' ')
+ {
+ pattern_len++; /* space needs to be removed as well */
+ p_pattern_addr--; /* set pointer to space */
+ }
+ }
+
+ shift = cli_strlen(p_pattern_addr) - pattern_len + 1; /* +1 for EOS */
+ p_cli->p_ctx->cmd_tmp_buff_len -= pattern_len;
+
+ memmove(p_pattern_addr, p_pattern_addr + pattern_len, shift);
+}
+
+/**
+ * @internal @brief Function for searching and adding commands matching to wildcard pattern.
+ *
+ * This function is internal to nrf_cli module and shall be not called directly.
+ *
+ * @param[in/out] p_cli Pointer to the CLI instance.
+ * @param[in] p_cmd Pointer to command which will be processed
+ * @param[in] cmd_lvl Command level in the command tree.
+ * @param[in] p_pattern Pointer to wildcard pattern.
+ * @param[out] p_counter Number of found and added commands.
+ *
+ * @retval WILDCARD_CMD_ADDED All matching commands added to the buffer.
+ * @retval WILDCARD_CMD_ADDED_MISSING_SPACE Not all matching commands added because
+ * NRF_CLI_CMD_BUFF_SIZE is too small.
+ * @retval WILDCARD_CMD_NO_MATCH_FOUND No matching command found.
+ */
+static wildcard_cmd_status_t commands_expand(nrf_cli_t const * p_cli,
+ nrf_cli_cmd_entry_t const * p_cmd,
+ size_t cmd_lvl,
+ char * p_pattern,
+ size_t * p_counter)
+{
+ size_t cmd_idx = 0;
+ size_t counter = 0;
+ bool success = false;
+
+ nrf_cli_static_entry_t static_entry;
+ nrf_cli_static_entry_t const * p_static_entry = NULL;
+ wildcard_cmd_status_t ret_val = WILDCARD_CMD_NO_MATCH_FOUND;
+
+ do
+ {
+ cmd_get(p_cmd,
+ cmd_lvl,
+ cmd_idx++,
+ &p_static_entry,
+ &static_entry);
+
+ if (p_static_entry == NULL)
+ {
+ break;
+ }
+
+ if (0 == fnmatch(p_pattern, p_static_entry->p_syntax, 0))
+ {
+ success = command_to_tmp_buffer_add(p_cli,
+ p_static_entry->p_syntax,
+ p_pattern);
+ if (!success)
+ {
+ break;
+ }
+ counter++;
+ }
+
+ } while(cmd_idx != 0);
+
+ if (counter > 0)
+ {
+ *p_counter = counter;
+ pattern_from_tmp_buffer_remove(p_cli, p_pattern);
+
+ if (success)
+ {
+ ret_val = WILDCARD_CMD_ADDED;
+ }
+ else
+ {
+ ret_val = WILDCARD_CMD_ADDED_MISSING_SPACE;
+ }
+ }
+
+ return ret_val;
+}
+#endif // NRF_MODULE_ENABLED(NRF_CLI_WILDCARD)
+
+/* Function is analyzing the command buffer to find matching commands. Next, it invokes the last recognized
+ * command which has a handler and passes the rest of command buffer as arguments. */
+static void cli_execute(nrf_cli_t const * p_cli)
+{
+ char quote;
+ size_t argc;
+ char * argv[NRF_CLI_ARGC_MAX + 1]; /* +1 reserved for NULL added by function make_argv */
+
+ size_t cmd_idx; /* currently analyzed command in cmd_level */
+ size_t cmd_lvl = NRF_CLI_CMD_ROOT_LVL; /* currently analyzed command level */
+ size_t cmd_handler_lvl = 0; /* last command level for which a handler has been found */
+ size_t cmd_handler_idx = 0; /* last command index for which a handler has been found */
+
+ nrf_cli_cmd_entry_t const * p_cmd = NULL;
+
+ cmd_trim(p_cli);
+
+#if NRF_MODULE_ENABLED(NRF_CLI_HISTORY)
+ history_save(p_cli);
+#endif
+
+#if NRF_MODULE_ENABLED(NRF_CLI_WILDCARD)
+/* Wildcard can be correctly handled under following conditions:
+ - wildcard command does not have a handler
+ - wildcard command is on the deepest commands level
+ - other commands on the same level as wildcard command shall also not have a handler
+
+ Algorithm:
+ 1. Command buffer is copied to Temp buffer.
+ 2. Algorithm goes through Command buffer to find handlers and subcommands.
+ 3. If algorithm will find a wildcard character it switches to Temp buffer.
+ 4. In the Temp buffer command with found wildcard character is changed into matching command(s).
+ 5. Algorithm switch back to Command buffer and analyzes next command.
+ 6. When all arguments are analyzed from Command buffer, Temp buffer is copied to Command buffer.
+ 7. Last found handler is executed with all arguments in the Command buffer.
+*/
+ size_t commands_expanded = 0;
+
+ memset(p_cli->p_ctx->temp_buff, 0, sizeof(p_cli->p_ctx->temp_buff));
+ memcpy(p_cli->p_ctx->temp_buff,
+ p_cli->p_ctx->cmd_buff,
+ p_cli->p_ctx->cmd_buff_len);
+
+ /* Function spaces_trim must be used instead of make_argv. At this point it is important to keep
+ temp_buff as a one string. It will allow to find wildcard commands easly with strstr
+ function. */
+ spaces_trim(p_cli->p_ctx->temp_buff);
+ p_cli->p_ctx->cmd_tmp_buff_len = cli_strlen(p_cli->p_ctx->temp_buff) + 1; // +1 for EOS
+#endif
+
+ cursor_end_position_move(p_cli);
+ if (!cursor_in_empty_line(p_cli))
+ {
+ cursor_next_line_move(p_cli);
+ }
+
+ /* create argument list */
+ quote = make_argv(&argc,
+ &argv[0],
+ p_cli->p_ctx->cmd_buff,
+ NRF_CLI_ARGC_MAX);
+
+ if (!argc)
+ {
+ cursor_next_line_move(p_cli);
+ return;
+ }
+
+ if (quote != 0)
+ {
+ nrf_cli_fprintf(p_cli, NRF_CLI_ERROR, "not terminated: %c\r\n", quote);
+ return;
+ }
+
+ /* Searching for a matching root command. */
+ for (cmd_idx = 0; cmd_idx <= CLI_DATA_SECTION_ITEM_COUNT; ++cmd_idx)
+ {
+ if (cmd_idx >= CLI_DATA_SECTION_ITEM_COUNT)
+ {
+ nrf_cli_fprintf(p_cli,
+ NRF_CLI_ERROR,
+ "%s%s\r\n",
+ argv[0],
+ NRF_CLI_MSG_COMMAND_NOT_FOUND);
+ return;
+ }
+
+ p_cmd = CLI_DATA_SECTION_ITEM_GET(cmd_idx);
+ if (strcmp(argv[cmd_lvl], p_cmd->u.p_static->p_syntax) != 0)
+ {
+ continue;
+ }
+ break;
+ }
+
+ /* Root command shall be always static. */
+ ASSERT(p_cmd->is_dynamic == false);
+
+ /* Pointer to the deepest command level with a handler. */
+ nrf_cli_cmd_entry_t const * p_cmd_low_level_entry = NULL;
+
+ /* Memory reserved for dynamic commands. */
+ nrf_cli_static_entry_t static_entry;
+ nrf_cli_static_entry_t const * p_static_entry = NULL;
+
+ nrf_cli_cmd_handler handler_cmd_lvl_0 = p_cmd->u.p_static->handler;
+ if (handler_cmd_lvl_0 != NULL)
+ {
+ p_cli->p_ctx->p_current_stcmd = p_cmd->u.p_static;
+ }
+
+ p_cmd = p_cmd->u.p_static->p_subcmd;
+ cmd_lvl++;
+ cmd_idx = 0;
+
+ while (1)
+ {
+ if (cmd_lvl >= argc)
+ {
+ break;
+ }
+
+ if (!strcmp(argv[cmd_lvl], "-h") || !strcmp(argv[cmd_lvl], "--help"))
+ {
+ /* Command called with help option so it makes no sense to search deeper commands. */
+ cli_flag_help_set(p_cli);
+ break;
+ }
+
+#if NRF_MODULE_ENABLED(NRF_CLI_WILDCARD)
+ /* Wildcard character is found */
+ if (wildcard_character_exist(argv[cmd_lvl]))
+ {
+ size_t counter = 0;
+ wildcard_cmd_status_t status;
+
+ /* Function will search commands tree for commands matching wildcard pattern stored in
+ argv[cmd_lvl]. If match is found wildcard pattern will be replaced by matching
+ commands in temp_buffer. If there is no space to add all matching commands function
+ will add as many as possible. Next it will continue to search for next wildcard
+ pattern and it will try to add matching commands. */
+ status = commands_expand(p_cli, p_cmd, cmd_lvl, argv[cmd_lvl], &counter);
+ if (WILDCARD_CMD_NO_MATCH_FOUND == status)
+ {
+ break;
+ }
+ commands_expanded += counter;
+ cmd_lvl++;
+ continue;
+ }
+#endif
+
+ cmd_get(p_cmd,
+ cmd_lvl,
+ cmd_idx++,
+ &p_static_entry,
+ &static_entry);
+
+ if ((cmd_idx == 0) || (p_static_entry == NULL))
+ {
+ break;
+ }
+
+ if (strcmp(argv[cmd_lvl], p_static_entry->p_syntax) == 0)
+ {
+ /* checking if command has a handler */
+ if (p_static_entry->handler != NULL)
+ {
+#if NRF_MODULE_ENABLED(NRF_CLI_WILDCARD)
+ if (commands_expanded > 0)
+ {
+ cursor_end_position_move(p_cli);
+ if (!cursor_in_empty_line(p_cli))
+ {
+ cursor_next_line_move(p_cli);
+ }
+ /* An error occured, fnmatch argument cannot be followed by argument
+ * with a handler to avoid multiple function calls. */
+ nrf_cli_fprintf(p_cli,
+ NRF_CLI_ERROR,
+ "Error: requested multiple function executions\r\n");
+ cli_flag_help_clear(p_cli);
+ return;
+ }
+#endif
+ /* Storing p_st_cmd->handler is not feasible for dynamic commands. Data will be
+ * invalid with the next loop iteration. */
+ cmd_handler_lvl = cmd_lvl;
+ cmd_handler_idx = cmd_idx - 1;
+ p_cmd_low_level_entry = p_cmd;
+ }
+ cmd_lvl++;
+ cmd_idx = 0;
+ p_cmd = p_static_entry->p_subcmd;
+ }
+ }
+#if NRF_MODULE_ENABLED(NRF_CLI_WILDCARD)
+ if (commands_expanded > 0)
+ {
+ /* Copy temp_buff to cmd_buff */
+ memcpy(p_cli->p_ctx->cmd_buff,
+ p_cli->p_ctx->temp_buff,
+ p_cli->p_ctx->cmd_tmp_buff_len);
+ p_cli->p_ctx->cmd_buff_len = p_cli->p_ctx->cmd_tmp_buff_len;
+
+ /* calling make_arg function again because cmd_buffer has additional commads */
+ (void)make_argv(&argc,
+ &argv[0],
+ p_cli->p_ctx->cmd_buff,
+ NRF_CLI_ARGC_MAX);
+ }
+ #endif
+
+ /* Executing the deepest found handler. */
+ if (p_cmd_low_level_entry != NULL)
+ {
+ cmd_get(p_cmd_low_level_entry,
+ cmd_handler_lvl,
+ cmd_handler_idx,
+ &p_static_entry,
+ &static_entry);
+
+ p_cli->p_ctx->p_current_stcmd = p_static_entry;
+
+ p_cli->p_ctx->p_current_stcmd->handler(p_cli,
+ argc - cmd_handler_lvl,
+ &argv[cmd_handler_lvl]);
+ }
+ else if (handler_cmd_lvl_0 != NULL)
+ {
+ handler_cmd_lvl_0(p_cli, argc, &argv[0]);
+ }
+ else
+ {
+ nrf_cli_fprintf(p_cli, NRF_CLI_ERROR, NRF_CLI_MSG_SPECIFY_SUBCOMMAND);
+ }
+ cli_flag_help_clear(p_cli);
+}
+
+/* Function required by qsort. */
+static int string_cmp(void const * pp_a, void const * pp_b)
+{
+ ASSERT(pp_a);
+ ASSERT(pp_b);
+
+ char const ** pp_str_a = (char const **)pp_a;
+ char const ** pp_str_b = (char const **)pp_b;
+
+ return strcmp(*pp_str_a, *pp_str_b);
+}
+
+static void cli_transport_evt_handler(nrf_cli_transport_evt_t evt_type, void * p_context)
+{
+ nrf_cli_t * p_cli = (nrf_cli_t *)p_context;
+ ASSERT(p_cli);
+#if NRF_MODULE_ENABLED(NRF_CLI_USES_TASK_MANAGER)
+ task_events_set(p_cli->p_ctx->task_id, evt_type == NRF_CLI_TRANSPORT_EVT_RX_RDY ?
+ NRF_CLI_TRANSPORT_RX_RDY_TASK_EVT : NRF_CLI_TRANSPORT_TX_RDY_TASK_EVT);
+#else
+
+ if (evt_type == NRF_CLI_TRANSPORT_EVT_RX_RDY)
+ {
+
+ }
+ else
+ {
+ /* wr done evt */
+ p_cli->p_ctx->internal.flag.tx_rdy = 1;
+ }
+#endif
+}
+
+static ret_code_t nrf_cli_instance_init(nrf_cli_t const * p_cli,
+ void const * p_config,
+ bool use_colors)
+{
+ ASSERT(p_cli);
+ ASSERT(p_cli->p_ctx && p_cli->p_iface && p_cli->p_name);
+ ASSERT((p_cli->newline_char == '\n') || (p_cli->newline_char == '\r'));
+
+#if defined(NRF_CLI_LOG_BACKEND) && NRF_CLI_LOG_BACKEND
+ p_cli->p_log_backend->p_cli = p_cli;
+#endif
+ ret_code_t ret = p_cli->p_iface->p_api->init(p_cli->p_iface,
+ p_config,
+ cli_transport_evt_handler,
+ (void *)p_cli);
+ if (ret != NRF_SUCCESS)
+ {
+ return ret;
+ }
+
+#if NRF_MODULE_ENABLED(NRF_CLI_HISTORY)
+ ASSERT(p_cli->p_cmd_hist_mempool);
+ ret = nrf_memobj_pool_init(p_cli->p_cmd_hist_mempool);
+ if (ret != NRF_SUCCESS)
+ {
+ return ret;
+ }
+ p_cli->p_ctx->p_cmd_list_head = NULL;
+ p_cli->p_ctx->p_cmd_list_tail = NULL;
+#endif
+
+ memset(p_cli->p_ctx, 0, sizeof(nrf_cli_ctx_t));
+ p_cli->p_ctx->internal.flag.tx_rdy = 1;
+
+#if NRF_MODULE_ENABLED(NRF_CLI_VT100_COLORS)
+ p_cli->p_ctx->internal.flag.use_colors = use_colors;
+#endif
+ p_cli->p_ctx->internal.flag.echo = NRF_CLI_ECHO_STATUS;
+ p_cli->p_ctx->state = NRF_CLI_STATE_INITIALIZED;
+ p_cli->p_ctx->vt100_ctx.cons.terminal_wid = NRF_CLI_DEFAULT_TERMINAL_WIDTH;
+ p_cli->p_ctx->vt100_ctx.cons.terminal_hei = NRF_CLI_DEFAULT_TERMINAL_HEIGHT;
+
+ const char * * pp_sorted_cmds = (const char * *)CLI_SORTED_CMD_PTRS_START_ADDR_GET;
+ for (size_t i = 0; i < CLI_DATA_SECTION_ITEM_COUNT; i++)
+ {
+ const nrf_cli_cmd_entry_t * cmd;
+ cmd = CLI_DATA_SECTION_ITEM_GET(i);
+
+ /* NULL syntax commands not allowed. */
+ ASSERT(cmd);
+ ASSERT(cmd->u.p_static->p_syntax);
+
+ pp_sorted_cmds[i] = cmd->u.p_static->p_syntax;
+ }
+
+ if (CLI_DATA_SECTION_ITEM_COUNT > 0)
+ {
+ qsort(pp_sorted_cmds,
+ CLI_DATA_SECTION_ITEM_COUNT,
+ sizeof (char *),
+ string_cmp);
+ }
+
+ return NRF_SUCCESS;
+}
+
+#if NRF_MODULE_ENABLED(NRF_CLI_USES_TASK_MANAGER)
+static ret_code_t nrf_cli_instance_uninit(nrf_cli_t const * p_cli);
+void console_task(void * p_context)
+{
+ nrf_cli_t * p_cli = (nrf_cli_t *)p_context;
+
+ ret_code_t ret = nrf_cli_start(p_cli);
+ APP_ERROR_CHECK(ret);
+
+ while (1)
+ {
+ uint32_t evts = task_events_wait(NRF_CLI_TASK_EVTS);
+
+ if (evts & NRF_CLI_KILL_TASK_EVT)
+ {
+ (void)nrf_cli_instance_uninit(p_cli);
+ task_exit();
+ }
+ else
+ {
+ nrf_cli_process(p_cli);
+ }
+ }
+}
+#endif
+
+ret_code_t nrf_cli_init(nrf_cli_t const * p_cli,
+ void const * p_config,
+ bool use_colors,
+ bool log_backend,
+ nrf_log_severity_t init_lvl)
+{
+ ASSERT(p_cli);
+
+ ret_code_t err_code = nrf_cli_instance_init(p_cli, p_config, use_colors);
+
+#if NRF_CLI_LOG_BACKEND && NRF_MODULE_ENABLED(NRF_LOG)
+ if ((err_code == NRF_SUCCESS) && log_backend && NRF_CLI_LOG_BACKEND)
+ {
+ int32_t id = nrf_log_backend_add(&p_cli->p_log_backend->backend, init_lvl);
+ if (id < 0)
+ {
+ return NRF_ERROR_NO_MEM;
+ }
+
+ nrf_log_backend_enable(&p_cli->p_log_backend->backend);
+ }
+#endif
+ return err_code;
+}
+
+ret_code_t nrf_cli_task_create(nrf_cli_t const * p_cli)
+{
+#if NRF_MODULE_ENABLED(NRF_CLI_USES_TASK_MANAGER)
+ p_cli->p_ctx->task_id = task_create(console_task, p_cli->p_name,(void *)p_cli);
+ if (p_cli->p_ctx->task_id == TASK_ID_INVALID)
+ {
+ return NRF_ERROR_NO_MEM;
+ }
+ else
+ {
+ return NRF_SUCCESS;
+ }
+#else
+ return NRF_ERROR_NOT_SUPPORTED;
+#endif
+}
+
+static ret_code_t nrf_cli_instance_uninit(nrf_cli_t const * p_cli)
+{
+ ASSERT(p_cli);
+ ASSERT(p_cli->p_ctx && p_cli->p_iface && p_cli->p_name);
+
+ if (cli_flag_processing_is_set(p_cli))
+ {
+ return NRF_ERROR_BUSY;
+ }
+
+#if NRF_CLI_LOG_BACKEND && NRF_MODULE_ENABLED(NRF_LOG)
+ if (p_cli->p_log_backend != NULL)
+ {
+ nrf_log_backend_disable(&p_cli->p_log_backend->backend);
+ nrf_log_backend_remove(&p_cli->p_log_backend->backend);
+ }
+#endif
+
+ ret_code_t ret = p_cli->p_iface->p_api->uninit(p_cli->p_iface);
+ if (ret != NRF_SUCCESS)
+ {
+ return ret;
+ }
+
+#if NRF_MODULE_ENABLED(NRF_CLI_HISTORY)
+ history_list_free_memory(p_cli);
+#endif
+
+ memset(p_cli->p_ctx, 0, sizeof(nrf_cli_ctx_t));
+ p_cli->p_ctx->state = NRF_CLI_STATE_UNINITIALIZED;
+
+ return NRF_SUCCESS;
+}
+
+ret_code_t nrf_cli_uninit(nrf_cli_t const * p_cli)
+{
+#if NRF_MODULE_ENABLED(NRF_CLI_USES_TASK_MANAGER)
+ if (cli_flag_processing_is_set(p_cli))
+ {
+ return NRF_ERROR_BUSY;
+ }
+ task_events_set(p_cli->p_ctx->task_id, NRF_CLI_KILL_TASK_EVT);
+ return NRF_SUCCESS;
+#else
+ return nrf_cli_instance_uninit(p_cli);
+#endif
+}
+
+ret_code_t nrf_cli_start(nrf_cli_t const * p_cli)
+{
+ ASSERT(p_cli);
+ ASSERT(p_cli->p_ctx && p_cli->p_iface && p_cli->p_name);
+
+ if (p_cli->p_ctx->state != NRF_CLI_STATE_INITIALIZED)
+ {
+ return NRF_ERROR_INVALID_STATE;
+ }
+
+#if NRF_MODULE_ENABLED(NRF_CLI_USES_TASK_MANAGER)
+ void * p_context = (void *)((uint32_t)task_id_get());
+ p_cli->p_log_backend->p_context = p_context;
+#endif
+
+ ret_code_t err_code = p_cli->p_iface->p_api->enable(p_cli->p_iface, false);
+
+#if NRF_MODULE_ENABLED(NRF_CLI_USES_TASK_MANAGER)
+ task_events_set(task_id_get(), NRF_CLI_TRANSPORT_RX_RDY_TASK_EVT);
+#endif
+
+ if (err_code == NRF_SUCCESS)
+ {
+#if NRF_CLI_VT100_COLORS_ENABLED
+ vt100_color_set(p_cli, NRF_CLI_NORMAL);
+ vt100_bgcolor_set(p_cli, NRF_CLI_VT100_COLOR_BLACK);
+#endif
+ nrf_fprintf(p_cli->p_fprintf_ctx, "\r\n\n");
+ cli_state_set(p_cli, NRF_CLI_STATE_ACTIVE);
+ }
+
+ return err_code;
+}
+
+ret_code_t nrf_cli_stop(nrf_cli_t const * p_cli)
+{
+ ASSERT(p_cli);
+ ASSERT(p_cli->p_ctx && p_cli->p_iface && p_cli->p_name);
+
+ if (p_cli->p_ctx->state == NRF_CLI_STATE_INITIALIZED ||
+ p_cli->p_ctx->state == NRF_CLI_STATE_UNINITIALIZED)
+ {
+ return NRF_ERROR_INVALID_STATE;
+ }
+
+ cli_state_set(p_cli, NRF_CLI_STATE_INITIALIZED);
+ return NRF_SUCCESS;
+}
+
+void nrf_cli_process(nrf_cli_t const * p_cli)
+{
+ ASSERT(p_cli);
+ ASSERT(p_cli->p_ctx && p_cli->p_iface && p_cli->p_name);
+
+ nrf_cli_internal_t internal;
+ internal.value = 0;
+ internal.flag.processing = 1;
+ (void)nrf_atomic_u32_or((nrf_atomic_u32_t *)&p_cli->p_ctx->internal.value,
+ internal.value);
+
+ switch (p_cli->p_ctx->state)
+ {
+ case NRF_CLI_STATE_UNINITIALIZED:
+ case NRF_CLI_STATE_INITIALIZED:
+ /* Console initialized but not started. */
+ break;
+ case NRF_CLI_STATE_ACTIVE:
+ {
+ cli_state_collect(p_cli);
+ bool log_processed = cli_log_entry_process(p_cli, false);
+ if (log_processed)
+ {
+ nrf_cli_fprintf(p_cli, NRF_CLI_INFO, "%s", p_cli->p_name);
+ if (cli_flag_echo_is_set(p_cli))
+ {
+ nrf_cli_fprintf(p_cli, NRF_CLI_NORMAL, "%s", p_cli->p_ctx->cmd_buff);
+ cursor_position_synchronize(p_cli);
+ }
+ }
+ break;
+ }
+ default:
+ break;
+ }
+ transport_buffer_flush(p_cli);
+ internal.value = (uint32_t)0xFFFFFFFF;
+ internal.flag.processing = 0;
+ (void)nrf_atomic_u32_and((nrf_atomic_u32_t *)&p_cli->p_ctx->internal.value,
+ internal.value);
+}
+
+/* Function shall be only used by the nrf_fprintf module. */
+void nrf_cli_print_stream(void const * p_user_ctx, char const * p_data, size_t data_len)
+{
+ cli_write((nrf_cli_t const *)p_user_ctx,
+ p_data,
+ data_len,
+ NULL);
+}
+
+void nrf_cli_fprintf(nrf_cli_t const * p_cli,
+ nrf_cli_vt100_color_t color,
+ char const * p_fmt,
+ ...)
+{
+ ASSERT(p_fmt);
+ ASSERT(p_cli);
+ ASSERT(p_cli->p_ctx && p_cli->p_iface && p_cli->p_name);
+
+ va_list args = {0};
+ va_start(args, p_fmt);
+
+#if NRF_MODULE_ENABLED(NRF_CLI_VT100_COLORS)
+ if ((p_cli->p_ctx->internal.flag.use_colors) &&
+ (color != p_cli->p_ctx->vt100_ctx.col.col))
+ {
+ nrf_cli_vt100_colors_t col;
+
+ vt100_colors_store(p_cli, &col);
+ vt100_color_set(p_cli, color);
+
+ nrf_fprintf_fmt(p_cli->p_fprintf_ctx, p_fmt, &args);
+
+ vt100_colors_restore(p_cli, &col);
+ }
+ else
+#endif // NRF_MODULE_ENABLED(NRF_CLI_VT100_COLORS)
+ {
+ nrf_fprintf_fmt(p_cli->p_fprintf_ctx, p_fmt, &args);
+ }
+
+ va_end(args);
+}
+
+/* Function prints a string on terminal screen with requested margin.
+ * It takes care to not divide words.
+ * p_cli Pointer to CLI instance.
+ * p_str Pointer to string to be printed.
+ * terminal_offset Requested left margin.
+ * offset_first_line Add margin to the first printed line.
+ */
+static void format_offset_string_print(nrf_cli_t const * p_cli,
+ char const * p_str,
+ size_t terminal_offset,
+ bool offset_first_line)
+{
+ if (p_str == NULL)
+ {
+ return;
+ }
+
+ if (offset_first_line)
+ {
+ cursor_right_move(p_cli, terminal_offset);
+ }
+
+ size_t length;
+ size_t offset = 0;
+
+ /* Skipping whitespace. */
+ while (isspace((int)*(p_str + offset)))
+ {
+ ++offset;
+ }
+
+ while (1)
+ {
+ size_t idx = 0;
+ length = cli_strlen(p_str) - offset;
+
+ if (length <= p_cli->p_ctx->vt100_ctx.cons.terminal_wid - terminal_offset)
+ {
+ for (idx = 0; idx < length; idx++)
+ {
+ if (*(p_str + offset + idx) == '\n')
+ {
+ transport_buffer_flush(p_cli);
+ cli_write(p_cli, p_str + offset, idx, NULL);
+ offset += idx + 1;
+ cursor_next_line_move(p_cli);
+ cursor_right_move(p_cli, terminal_offset);
+ break;
+ }
+ }
+ /* String will fit in one line. */
+ nrf_fprintf(p_cli->p_fprintf_ctx, p_str + offset);
+ break;
+ }
+ else
+ {
+ /* String is longer than terminal line so text needs to divide in the way
+ to not divide words. */
+ length = p_cli->p_ctx->vt100_ctx.cons.terminal_wid - terminal_offset;
+
+ while (1)
+ {
+ /* Determining line break. */
+ if (isspace((int)(*(p_str + offset + idx))))
+ {
+ length = idx;
+ if (*(p_str + offset + idx) == '\n')
+ {
+ break;
+ }
+ }
+ if ((idx + terminal_offset) >= p_cli->p_ctx->vt100_ctx.cons.terminal_wid)
+ {
+ /* End of line reached. */
+ break;
+ }
+ ++idx;
+ }
+
+ /* Writing one line, fprintf IO buffer must be flushed before calling cli_write. */
+ transport_buffer_flush(p_cli);
+ cli_write(p_cli, p_str + offset, length, NULL);
+ offset += length;
+
+ /* Calculating text offset to ensure that next line will not begin with a space. */
+ while (isspace((int)(*(p_str + offset))))
+ {
+ ++offset;
+ }
+ cursor_next_line_move(p_cli);
+ cursor_right_move(p_cli, terminal_offset);
+ }
+ }
+ cursor_next_line_move(p_cli);
+}
+
+void nrf_cli_help_print(nrf_cli_t const * p_cli,
+ nrf_cli_getopt_option_t const * p_opt,
+ size_t opt_len)
+{
+ ASSERT(p_cli);
+ ASSERT(p_cli->p_ctx && p_cli->p_iface && p_cli->p_name);
+
+ static uint8_t const tab_len = 2;
+ static char const opt_sep[] =", "; /* options separator */
+ static char const help[] = "-h, --help";
+ static char const cmd_sep[] = " - "; /* command separator */
+ uint16_t field_width = 0;
+ uint16_t longest_string = cli_strlen(help) - cli_strlen(opt_sep);
+
+ /* Printing help string for command. */
+ nrf_cli_fprintf(p_cli,
+ NRF_CLI_NORMAL,
+ "%s%s",
+ p_cli->p_ctx->p_current_stcmd->p_syntax,
+ cmd_sep);
+
+ field_width = cli_strlen(p_cli->p_ctx->p_current_stcmd->p_syntax) + cli_strlen(cmd_sep);
+ format_offset_string_print(p_cli, p_cli->p_ctx->p_current_stcmd->p_help, field_width, false);
+
+ nrf_cli_fprintf(p_cli, NRF_CLI_NORMAL, "Options:\r\n");
+
+ /* Looking for the longest option string. */
+ if ((opt_len > 0) && (p_opt != NULL))
+ {
+ for (size_t i = 0; i < opt_len; ++i)
+ {
+ if (cli_strlen(p_opt[i].p_optname_short) + cli_strlen(p_opt[i].p_optname)
+ > longest_string)
+ {
+ longest_string = cli_strlen(p_opt[i].p_optname_short)
+ + cli_strlen(p_opt[i].p_optname);
+ }
+ }
+ }
+ longest_string += cli_strlen(opt_sep) + tab_len;
+
+ nrf_cli_fprintf(p_cli,
+ NRF_CLI_NORMAL,
+ " %-*s:",
+ longest_string,
+ help);
+
+ /* Print help string for options (only -h and --help). */
+ field_width = longest_string + tab_len + 1; /* tab_len + 1 == " " and ':' from: " %-*s:" */
+ format_offset_string_print(p_cli, "Show command help.", field_width, false);
+
+ /* Formating and printing all available options (except -h, --help). */
+ if (p_opt != NULL)
+ {
+ for (size_t i = 0; i < opt_len; ++i)
+ {
+ if ((p_opt[i].p_optname_short != NULL) && (p_opt[i].p_optname != NULL))
+ {
+ nrf_cli_fprintf(p_cli,
+ NRF_CLI_NORMAL,
+ " %s%s%s",
+ p_opt[i].p_optname_short,
+ opt_sep,
+ p_opt[i].p_optname);
+ field_width = longest_string + tab_len;
+ cursor_right_move(p_cli,
+ field_width - ( cli_strlen(p_opt[i].p_optname_short)
+ + cli_strlen(p_opt[i].p_optname)
+ + tab_len
+ + cli_strlen(opt_sep)));
+ cli_putc(p_cli, ':');
+ ++field_width; /* incrementing because char ':' was already printed above */
+ }
+ else if (p_opt[i].p_optname_short != NULL)
+ {
+ nrf_cli_fprintf(p_cli,
+ NRF_CLI_NORMAL,
+ " %-*s:",
+ longest_string,
+ p_opt[i].p_optname_short);
+ /* tab_len + 1 == " " and ':' from: " %-*s:" */
+ field_width = longest_string + tab_len + 1;
+ }
+ else if (p_opt[i].p_optname != NULL)
+ {
+ nrf_cli_fprintf(p_cli,
+ NRF_CLI_NORMAL,
+ " %-*s:",
+ longest_string,
+ p_opt[i].p_optname);
+ /* tab_len + 1 == " " and ':' from: " %-*s:" */
+ field_width = longest_string + tab_len + 1;
+ }
+ else
+ {
+ /* Do nothing. */
+ }
+
+ if (p_opt[i].p_optname_help != NULL)
+ {
+ format_offset_string_print(p_cli, p_opt[i].p_optname_help, field_width, false);
+ }
+ else
+ {
+ cursor_next_line_move(p_cli);
+ }
+ }
+ }
+
+ /* Checking if there are any subcommands avilable. */
+ if (p_cli->p_ctx->p_current_stcmd->p_subcmd == NULL)
+ {
+ return;
+ }
+
+ /* Printing formatted help of one level deeper subcommands. */
+ nrf_cli_static_entry_t static_entry;
+ nrf_cli_cmd_entry_t const * p_cmd = p_cli->p_ctx->p_current_stcmd->p_subcmd;
+ nrf_cli_static_entry_t const * p_st_cmd = NULL;
+
+ field_width = 0;
+ longest_string = 0;
+
+ size_t cmd_idx = 0;
+
+ /* Searching for the longest subcommand to print. */
+ while (1)
+ {
+ cmd_get(p_cmd, !NRF_CLI_CMD_ROOT_LVL, cmd_idx++, &p_st_cmd, &static_entry);
+
+ if (p_st_cmd == NULL)
+ {
+ break;
+ }
+ if (cli_strlen(p_st_cmd->p_syntax) > longest_string)
+ {
+ longest_string = cli_strlen(p_st_cmd->p_syntax);
+ }
+ }
+
+ /* Checking if there are dynamic subcommands. */
+ if (cmd_idx == 1)
+ {
+ /* No dynamic subcommands available. */
+ return;
+ }
+
+ nrf_cli_fprintf(p_cli, NRF_CLI_NORMAL, "Subcommands:\r\n");
+
+ /* Printing subcommands and help string (if exists). */
+ cmd_idx = 0;
+ while (1)
+ {
+ cmd_get(p_cmd, !NRF_CLI_CMD_ROOT_LVL, cmd_idx++, &p_st_cmd, &static_entry);
+
+ if (p_st_cmd == NULL)
+ {
+ break;
+ }
+
+ field_width = longest_string + tab_len;
+ nrf_cli_fprintf(p_cli, NRF_CLI_NORMAL," %-*s:", field_width, p_st_cmd->p_syntax);
+ field_width += tab_len + 1; /* tab_len + 1 == " " and ':' from: " %-*s:" */
+
+ if (p_st_cmd->p_help != NULL)
+ {
+ format_offset_string_print(p_cli, p_st_cmd->p_help, field_width, false);
+ }
+ else
+ {
+ cursor_next_line_move(p_cli);
+ }
+ }
+}
+
+#if NRF_CLI_LOG_BACKEND && NRF_MODULE_ENABLED(NRF_LOG)
+
+#define NRF_CLI_LOG_MSG_OVERFLOW_MSK ((uint32_t)7)
+static bool cli_log_entry_process(nrf_cli_t const * p_cli, bool skip)
+{
+ nrf_log_entry_t entry;
+
+#if NRF_MODULE_ENABLED(NRF_CLI_STATISTICS)
+ bool print_msg = false;
+#endif
+
+ if (nrf_queue_pop(p_cli->p_log_backend->p_queue, &entry) != NRF_SUCCESS)
+ {
+ return false;
+ }
+
+ if (skip)
+ {
+ nrf_memobj_put(entry);
+#if NRF_MODULE_ENABLED(NRF_CLI_STATISTICS)
+ ++p_cli->p_ctx->statistics.log_lost_cnt;
+ if ((p_cli->p_ctx->statistics.log_lost_cnt & NRF_CLI_LOG_MSG_OVERFLOW_MSK) == 1)
+ {
+ /* Set flag to print a message after clearing the currently entered command. */
+ print_msg = true;
+ }
+ else
+#endif
+ {
+ return true;
+ }
+ }
+ {
+ /* Erasing the currently displayed command and console name. */
+ nrf_cli_multiline_cons_t const * p_cons = multiline_console_data_check(p_cli);
+
+ if (p_cons->cur_y > NRF_CLI_INITIAL_CURS_POS)
+ {
+ cursor_up_move(p_cli, p_cons->cur_y - NRF_CLI_INITIAL_CURS_POS);
+ }
+
+ if (p_cons->cur_x > NRF_CLI_INITIAL_CURS_POS)
+ {
+ cursor_left_move(p_cli, p_cons->cur_x - NRF_CLI_INITIAL_CURS_POS);
+ }
+ cli_clear_eos(p_cli);
+ }
+
+#if NRF_MODULE_ENABLED(NRF_CLI_STATISTICS)
+ if (print_msg)
+ {
+ /* Print the requested string and exit function. */
+ nrf_cli_fprintf(p_cli, NRF_CLI_ERROR, "Lost logs - increase log backend queue size.\r\n");
+
+ return true;
+ }
+#endif
+
+ /* Printing logs from the queue. */
+ do
+ {
+ nrf_log_header_t header;
+ uint32_t memobj_offset = 0;
+ nrf_log_str_formatter_entry_params_t params;
+
+ nrf_memobj_read(entry, &header, HEADER_SIZE*sizeof(uint32_t), memobj_offset);
+ memobj_offset = HEADER_SIZE * sizeof(uint32_t);
+
+ params.timestamp = header.timestamp;
+ params.module_id = header.module_id;
+ params.dropped = header.dropped;
+ params.use_colors = NRF_LOG_USES_COLORS; /* Color will be provided by the console application. */
+
+ if (header.base.generic.type == HEADER_TYPE_STD)
+ {
+ char const * p_log_str = (char const *)((uint32_t)header.base.std.addr);
+ params.severity = (nrf_log_severity_t)header.base.std.severity;
+ uint32_t nargs = header.base.std.nargs;
+ uint32_t args[6];
+
+ nrf_memobj_read(entry, args, nargs*sizeof(uint32_t), memobj_offset);
+ nrf_log_std_entry_process(p_log_str,
+ args,
+ nargs,
+ &params,
+ p_cli->p_fprintf_ctx);
+ }
+ else if (header.base.generic.type == HEADER_TYPE_HEXDUMP)
+ {
+ uint32_t data_len;
+ uint8_t data_buf[8];
+ uint32_t chunk_len;
+
+ data_len = header.base.hexdump.len;
+ params.severity = (nrf_log_severity_t)header.base.hexdump.severity;
+
+ do
+ {
+ chunk_len = sizeof(data_buf) > data_len ? data_len : sizeof(data_buf);
+ nrf_memobj_read(entry, data_buf, chunk_len, memobj_offset);
+ memobj_offset += chunk_len;
+ data_len -= chunk_len;
+ nrf_log_hexdump_entry_process(data_buf, chunk_len, &params, p_cli->p_fprintf_ctx);
+ } while (data_len > 0);
+ }
+
+ nrf_memobj_put(entry);
+ } while (nrf_queue_pop(p_cli->p_log_backend->p_queue, &entry) == NRF_SUCCESS);
+ return true;
+}
+
+static void nrf_log_backend_cli_put(nrf_log_backend_t const * p_backend, nrf_log_entry_t * p_msg)
+{
+ nrf_cli_log_backend_t * p_backend_cli = CONTAINER_OF(p_backend, nrf_cli_log_backend_t, backend);
+ nrf_cli_t const * p_cli = p_backend_cli->p_cli;
+
+ //If panic mode cannot be handled, stop handling new requests.
+ if (p_cli->p_ctx->state != NRF_CLI_STATE_PANIC_MODE_INACTIVE)
+ {
+ bool panic_mode = (p_cli->p_ctx->state == NRF_CLI_STATE_PANIC_MODE_ACTIVE);
+ //If there is no place for a new log entry, remove the oldest one.
+ ret_code_t err_code = nrf_queue_push(p_backend_cli->p_queue, &p_msg);
+ while (err_code != NRF_SUCCESS)
+ {
+ (void)cli_log_entry_process(p_cli, panic_mode ? false : true);
+
+ err_code = nrf_queue_push(p_backend_cli->p_queue, &p_msg);
+ }
+ nrf_memobj_get(p_msg);
+
+ if (panic_mode)
+ {
+ (void)cli_log_entry_process(p_cli, false);
+ }
+#if NRF_MODULE_ENABLED(NRF_CLI_USES_TASK_MANAGER)
+ else
+ {
+ task_events_set((task_id_t)((uint32_t)p_backend_cli->p_context & 0x000000FF),
+ NRF_CLI_LOG_PENDING_TASK_EVT);
+ }
+#endif
+ }
+}
+
+static void nrf_log_backend_cli_flush(nrf_log_backend_t const * p_backend)
+{
+ nrf_cli_log_backend_t * p_backend_cli;
+ nrf_cli_t const * p_cli;
+ nrf_log_entry_t * p_msg;
+
+ p_backend_cli = CONTAINER_OF(p_backend, nrf_cli_log_backend_t, backend);
+ p_cli = p_backend_cli->p_cli;
+
+ if (nrf_queue_pop(p_backend_cli->p_queue, &p_msg) == NRF_SUCCESS)
+ {
+ (void)cli_log_entry_process(p_cli, false);
+ }
+ UNUSED_PARAMETER(p_backend);
+}
+
+static void nrf_log_backend_cli_panic_set(nrf_log_backend_t const * p_backend)
+{
+ nrf_cli_log_backend_t * p_backend_cli = CONTAINER_OF(p_backend, nrf_cli_log_backend_t, backend);
+ nrf_cli_t const * p_cli = p_backend_cli->p_cli;
+
+ if (p_cli->p_iface->p_api->enable(p_cli->p_iface, true) == NRF_SUCCESS)
+ {
+ p_cli->p_ctx->state = NRF_CLI_STATE_PANIC_MODE_ACTIVE;
+ }
+ else
+ {
+ p_cli->p_ctx->state = NRF_CLI_STATE_PANIC_MODE_INACTIVE;
+ }
+}
+
+const nrf_log_backend_api_t nrf_log_backend_cli_api = {
+ .put = nrf_log_backend_cli_put,
+ .flush = nrf_log_backend_cli_flush,
+ .panic_set = nrf_log_backend_cli_panic_set,
+};
+#else
+static bool cli_log_entry_process(nrf_cli_t const * p_cli, bool skip)
+{
+ UNUSED_PARAMETER(p_cli);
+ UNUSED_PARAMETER(skip);
+ return false;
+}
+#endif // NRF_CLI_LOG_BACKEND
+
+/* ============ built-in commands ============ */
+#if NRF_MODULE_ENABLED(NRF_CLI_BUILD_IN_CMDS)
+
+static bool nrf_cli_build_in_cmd_common_executed(nrf_cli_t const * p_cli,
+ bool arg_cnt_nok,
+ nrf_cli_getopt_option_t const * p_opt,
+ size_t opt_len)
+{
+ if (nrf_cli_help_requested(p_cli))
+ {
+ nrf_cli_help_print(p_cli, p_opt, opt_len);
+ return true;
+ }
+
+ if (arg_cnt_nok)
+ {
+ nrf_cli_fprintf(p_cli,
+ NRF_CLI_ERROR,
+ "%s: wrong parameter count\r\n",
+ p_cli->p_ctx->p_current_stcmd->p_syntax);
+ return true;
+ }
+
+ return false;
+}
+
+static void nrf_cli_cmd_clear(nrf_cli_t const * p_cli, size_t argc, char **argv)
+{
+ ASSERT(p_cli);
+ ASSERT(p_cli->p_ctx && p_cli->p_iface && p_cli->p_name);
+ UNUSED_PARAMETER(argv);
+
+ if ((argc == 2) && (nrf_cli_help_requested(p_cli)))
+ {
+ nrf_cli_help_print(p_cli, NULL, 0);
+ return;
+ }
+ NRF_CLI_VT100_CMD(p_cli, NRF_CLI_VT100_CURSORHOME);
+ NRF_CLI_VT100_CMD(p_cli, NRF_CLI_VT100_CLEARSCREEN);
+}
+
+static void nrf_cli_cmd_cli(nrf_cli_t const * p_cli, size_t argc, char **argv)
+{
+ ASSERT(p_cli);
+ ASSERT(p_cli->p_ctx && p_cli->p_iface && p_cli->p_name);
+ UNUSED_PARAMETER(argv);
+
+ if ((argc == 1) || ((argc == 2) && nrf_cli_help_requested(p_cli)) )
+ {
+ nrf_cli_help_print(p_cli, NULL, 0);
+ return;
+ }
+ nrf_cli_fprintf(p_cli, NRF_CLI_ERROR, NRF_CLI_MSG_SPECIFY_SUBCOMMAND);
+}
+
+#if NRF_MODULE_ENABLED(NRF_CLI_VT100_COLORS)
+static void nrf_cli_cmd_colors_off(nrf_cli_t const * p_cli, size_t argc, char **argv)
+{
+ if (nrf_cli_build_in_cmd_common_executed(p_cli, (argc != 1), NULL, 0))
+ {
+ return;
+ }
+ p_cli->p_ctx->internal.flag.use_colors = 0;
+}
+
+static void nrf_cli_cmd_colors_on(nrf_cli_t const * p_cli, size_t argc, char **argv)
+{
+ if (nrf_cli_build_in_cmd_common_executed(p_cli, (argc != 1), NULL, 0))
+ {
+ return;
+ }
+ p_cli->p_ctx->internal.flag.use_colors = 1;
+}
+
+static void nrf_cli_cmd_colors(nrf_cli_t const * p_cli, size_t argc, char **argv)
+{
+ ASSERT(p_cli);
+ ASSERT(p_cli->p_ctx && p_cli->p_iface && p_cli->p_name);
+
+ if (argc == 1)
+ {
+ nrf_cli_help_print(p_cli, NULL, 0);
+ return;
+ }
+
+ if (nrf_cli_build_in_cmd_common_executed(p_cli, (argc != 2), NULL, 0))
+ {
+ return;
+ }
+
+ nrf_cli_fprintf(p_cli,
+ NRF_CLI_ERROR,
+ "%s:%s%s\r\n",
+ argv[0],
+ NRF_CLI_MSG_UNKNOWN_PARAMETER,
+ argv[1]);
+}
+#endif // NRF_MODULE_ENABLED(NRF_CLI_VT100_COLORS)
+
+static void nrf_cli_cmd_echo(nrf_cli_t const * p_cli, size_t argc, char **argv)
+{
+ if (nrf_cli_build_in_cmd_common_executed(p_cli, (argc > 2), NULL, 0))
+ {
+ return;
+ }
+
+ if (argc == 2)
+ {
+ nrf_cli_fprintf(p_cli,
+ NRF_CLI_ERROR,
+ "%s:%s%s\r\n",
+ argv[0],
+ NRF_CLI_MSG_UNKNOWN_PARAMETER,
+ argv[1]);
+ return;
+ }
+
+ nrf_cli_fprintf(p_cli,
+ NRF_CLI_NORMAL,
+ "Echo status: %s\r\n",
+ cli_flag_echo_is_set(p_cli) ? "on" : "off");
+}
+
+static void nrf_cli_cmd_echo_off(nrf_cli_t const * p_cli, size_t argc, char **argv)
+{
+ if (nrf_cli_build_in_cmd_common_executed(p_cli, (argc != 1), NULL, 0))
+ {
+ return;
+ }
+
+ cli_flag_echo_clear(p_cli);
+}
+
+static void nrf_cli_cmd_echo_on(nrf_cli_t const * p_cli, size_t argc, char **argv)
+{
+ if (nrf_cli_build_in_cmd_common_executed(p_cli, (argc != 1), NULL, 0))
+ {
+ return;
+ }
+
+ cli_flag_echo_set(p_cli);
+}
+
+#if NRF_MODULE_ENABLED(NRF_CLI_HISTORY)
+static void nrf_cli_cmd_history(nrf_cli_t const * p_cli, size_t argc, char **argv)
+{
+ ASSERT(p_cli);
+ ASSERT(p_cli->p_ctx && p_cli->p_iface && p_cli->p_name);
+
+ if (nrf_cli_build_in_cmd_common_executed(p_cli, (argc != 1), NULL, 0))
+ {
+ return;
+ }
+
+ size_t i = 0;
+ nrf_memobj_t const * p_cmd_list = p_cli->p_ctx->p_cmd_list_tail;
+ nrf_cli_memobj_header_t header;
+
+ while (1)
+ {
+ if ((p_cmd_list == NULL) || (i >= NRF_CLI_HISTORY_ELEMENT_COUNT))
+ {
+ break;
+ }
+ nrf_memobj_read((nrf_memobj_t * )p_cmd_list,
+ &header,
+ NRF_CLI_HISTORY_HEADER_SIZE,
+ (uint32_t)0);
+ nrf_memobj_read((nrf_memobj_t * )p_cmd_list,
+ p_cli->p_ctx->temp_buff,
+ header.cmd_len + 1,
+ (uint32_t)NRF_CLI_HISTORY_HEADER_SIZE);
+ p_cmd_list = header.p_next;
+ nrf_cli_fprintf(p_cli, NRF_CLI_NORMAL, "[%3d] %s\r\n", i++, p_cli->p_ctx->temp_buff);
+ }
+ p_cli->p_ctx->temp_buff[0] = '\0';
+}
+#endif // NRF_MODULE_ENABLED(NRF_CLI_HISTORY)
+
+#if NRF_MODULE_ENABLED(NRF_CLI_STATISTICS)
+void nrf_cli_cmd_cli_stats(nrf_cli_t const * p_cli, size_t argc, char **argv)
+{
+ if (argc == 1)
+ {
+ nrf_cli_help_print(p_cli, NULL, 0);
+ return;
+ }
+
+ if (argc == 2)
+ {
+ nrf_cli_fprintf(p_cli,
+ NRF_CLI_ERROR,
+ "%s:%s%s\r\n",
+ argv[0],
+ NRF_CLI_MSG_UNKNOWN_PARAMETER,
+ argv[1]);
+ return;
+ }
+
+ UNUSED_RETURN_VALUE(nrf_cli_build_in_cmd_common_executed(p_cli, (argc > 2), NULL, 0));
+}
+
+void nrf_cli_cmd_cli_stats_show(nrf_cli_t const * p_cli, size_t argc, char **argv)
+{
+ if (nrf_cli_build_in_cmd_common_executed(p_cli, (argc != 1), NULL, 0))
+ {
+ return;
+ }
+
+ uint8_t max_util = nrf_queue_max_utilization_get(p_cli->p_log_backend->p_queue);
+ uint8_t utilization = (uint8_t)(max_util * 100ul / p_cli->p_log_backend->p_queue->size);
+
+ nrf_cli_fprintf(p_cli,
+ NRF_CLI_NORMAL,
+ "Lost logs: %u\r\n"
+ "Max log queue utilization: %u%% [%u/%u]\r\n",
+ p_cli->p_ctx->statistics.log_lost_cnt,
+ utilization,
+ max_util,
+ p_cli->p_log_backend->p_queue->size);
+}
+
+void nrf_cli_cmd_cli_stats_reset(nrf_cli_t const * p_cli, size_t argc, char **argv)
+{
+ if (nrf_cli_build_in_cmd_common_executed(p_cli, (argc != 1), NULL, 0))
+ {
+ return;
+ }
+
+ p_cli->p_ctx->statistics.log_lost_cnt = 0;
+ nrf_queue_max_utilization_reset(p_cli->p_log_backend->p_queue);
+}
+#endif // NRF_MODULE_ENABLED(NRF_CLI_STATISTICS)
+
+static void nrf_cli_cmd_resize_default(nrf_cli_t const * p_cli, size_t argc, char **argv)
+{
+ if (nrf_cli_build_in_cmd_common_executed(p_cli, (argc != 1), NULL, 0))
+ {
+ return;
+ }
+
+ NRF_CLI_VT100_CMD(p_cli, NRF_CLI_VT100_SETCOL_80);
+ p_cli->p_ctx->vt100_ctx.cons.terminal_wid = NRF_CLI_DEFAULT_TERMINAL_WIDTH;
+ p_cli->p_ctx->vt100_ctx.cons.terminal_hei = NRF_CLI_DEFAULT_TERMINAL_HEIGHT;
+}
+
+static void nrf_cli_cmd_resize(nrf_cli_t const * p_cli, size_t argc, char **argv)
+{
+ ASSERT(p_cli);
+ ASSERT(p_cli->p_ctx && p_cli->p_iface && p_cli->p_name);
+
+ if (argc == 1)
+ {
+ if (terminal_size_get(p_cli,
+ &p_cli->p_ctx->vt100_ctx.cons.terminal_wid,
+ &p_cli->p_ctx->vt100_ctx.cons.terminal_hei) != NRF_SUCCESS)
+ {
+ p_cli->p_ctx->vt100_ctx.cons.terminal_wid = NRF_CLI_DEFAULT_TERMINAL_WIDTH;
+ p_cli->p_ctx->vt100_ctx.cons.terminal_hei = NRF_CLI_DEFAULT_TERMINAL_HEIGHT;
+ nrf_cli_fprintf(p_cli,
+ NRF_CLI_WARNING,
+ "No response from the terminal, assumed 80x24 screen size\r\n");
+ }
+ return;
+ }
+
+ if (nrf_cli_build_in_cmd_common_executed(p_cli, (argc > 2), NULL, 0))
+ {
+ return;
+ }
+
+ nrf_cli_fprintf(p_cli,
+ NRF_CLI_ERROR,
+ "%s:%s%s\r\n",
+ argv[0],
+ NRF_CLI_MSG_UNKNOWN_PARAMETER,
+ argv[1]);
+}
+
+#if NRF_MODULE_ENABLED(NRF_CLI_VT100_COLORS)
+NRF_CLI_CREATE_STATIC_SUBCMD_SET(m_sub_colors)
+{
+ NRF_CLI_CMD(off, NULL, NRF_CLI_HELP_COLORS_OFF, nrf_cli_cmd_colors_off),
+ NRF_CLI_CMD(on, NULL, NRF_CLI_HELP_COLORS_ON, nrf_cli_cmd_colors_on),
+ NRF_CLI_SUBCMD_SET_END
+};
+#endif
+
+NRF_CLI_CREATE_STATIC_SUBCMD_SET(m_sub_echo)
+{
+ NRF_CLI_CMD(off, NULL, NRF_CLI_HELP_ECHO_OFF, nrf_cli_cmd_echo_off),
+ NRF_CLI_CMD(on, NULL, NRF_CLI_HELP_ECHO_ON, nrf_cli_cmd_echo_on),
+ NRF_CLI_SUBCMD_SET_END
+};
+
+#if NRF_MODULE_ENABLED(NRF_CLI_STATISTICS)
+NRF_CLI_CREATE_STATIC_SUBCMD_SET(m_sub_cli_stats)
+{
+ NRF_CLI_CMD(reset, NULL, NRF_CLI_HELP_STATISTICS_RESET, nrf_cli_cmd_cli_stats_reset),
+ NRF_CLI_CMD(show, NULL, NRF_CLI_HELP_STATISTICS_SHOW, nrf_cli_cmd_cli_stats_show),
+ NRF_CLI_SUBCMD_SET_END
+};
+#endif // NRF_MODULE_ENABLED(NRF_CLI_STATISTICS)
+
+NRF_CLI_CREATE_STATIC_SUBCMD_SET(m_sub_cli)
+{
+#if NRF_MODULE_ENABLED(NRF_CLI_VT100_COLORS)
+ NRF_CLI_CMD(colors, &m_sub_colors, NRF_CLI_HELP_COLORS, nrf_cli_cmd_colors),
+#endif
+ NRF_CLI_CMD(echo, &m_sub_echo, NRF_CLI_HELP_ECHO, nrf_cli_cmd_echo),
+#if NRF_MODULE_ENABLED(NRF_CLI_STATISTICS)
+ NRF_CLI_CMD(stats, &m_sub_cli_stats, NRF_CLI_HELP_STATISTICS, nrf_cli_cmd_cli_stats),
+#endif
+ NRF_CLI_SUBCMD_SET_END
+};
+
+NRF_CLI_CREATE_STATIC_SUBCMD_SET(m_sub_resize)
+{
+ NRF_CLI_CMD(default, NULL, NRF_CLI_HELP_RESIZE_DEFAULT, nrf_cli_cmd_resize_default),
+ NRF_CLI_SUBCMD_SET_END
+};
+
+NRF_CLI_CMD_REGISTER(clear, NULL, NRF_CLI_HELP_CLEAR, nrf_cli_cmd_clear);
+NRF_CLI_CMD_REGISTER(cli, &m_sub_cli, NRF_CLI_HELP_CLI, nrf_cli_cmd_cli);
+#if NRF_MODULE_ENABLED(NRF_CLI_HISTORY)
+NRF_CLI_CMD_REGISTER(history, NULL, NRF_CLI_HELP_HISTORY, nrf_cli_cmd_history);
+#endif
+NRF_CLI_CMD_REGISTER(resize, &m_sub_resize, NRF_CLI_HELP_RESIZE, nrf_cli_cmd_resize);
+
+#endif // NRF_MODULE_ENABLED(NRF_CLI_BUILD_IN_CMDS)
+
+#endif // NRF_MODULE_ENABLED(NRF_CLI)
+
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/cli/nrf_cli.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/cli/nrf_cli.h
new file mode 100644
index 0000000..480b453
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/cli/nrf_cli.h
@@ -0,0 +1,636 @@
+/**
+ * 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#ifndef NRF_CLI_H__
+#define NRF_CLI_H__
+
+#include "sdk_common.h"
+#include "nrf_cli_types.h"
+#include "nrf_section.h"
+#include "nrf_log_backend_interface.h"
+#include "nrf_queue.h"
+#include "nrf_log_ctrl.h"
+#include "app_util_platform.h"
+
+#if NRF_MODULE_ENABLED(NRF_CLI_USES_TASK_MANAGER)
+#include "task_manager.h"
+#endif
+
+#include "nrf_fprintf.h"
+#include "nrf_fprintf_format.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define NRF_CLI_RX_BUFF_SIZE 16
+
+/* CLI reserves top task manager flags, bits 0...18 are available for application. */
+#define NRF_CLI_TRANSPORT_TX_RDY_TASK_EVT (1UL << 19)
+#define NRF_CLI_TRANSPORT_RX_RDY_TASK_EVT (1UL << 20)
+#define NRF_CLI_LOG_PENDING_TASK_EVT (1UL << 21)
+#define NRF_CLI_CMD_EXECUTE_EVT (1UL << 22)
+#define NRF_CLI_KILL_TASK_EVT (1UL << 23)
+
+#define NRF_CLI_TASK_EVTS (NRF_CLI_TRANSPORT_TX_RDY_TASK_EVT | \
+ NRF_CLI_TRANSPORT_RX_RDY_TASK_EVT | \
+ NRF_CLI_LOG_PENDING_TASK_EVT | \
+ NRF_CLI_CMD_EXECUTE_EVT | \
+ NRF_CLI_KILL_TASK_EVT)
+/**
+ * @defgroup nrf_cli Command Line Interface
+ * @ingroup app_common
+ *
+ * @brief Module for unified command line handling.
+ *
+ * @{
+ */
+
+/**
+ * @brief Aliases to: @ref nrf_cli, @ref nrf_cli_cmd_entry, and @ref nrf_cli_static_entry.
+ * Must be created here to satisfy module declaration order dependencies.
+ */
+typedef struct nrf_cli nrf_cli_t;
+typedef struct nrf_cli_cmd_entry nrf_cli_cmd_entry_t;
+typedef struct nrf_cli_static_entry nrf_cli_static_entry_t;
+
+/**
+ * @brief CLI dynamic command descriptor.
+ *
+ * @details Function shall fill the received @ref nrf_cli_static_entry structure with requested (idx)
+ * dynamic subcommand data. If there is more than one dynamic subcommand available,
+ * the function shall ensure that the returned commands: p_static->p_syntax are sorted in
+ * alphabetical order. If idx exceeds the available dynamic subcommands, the function must write
+ * to p_static->p_syntax NULL value. This will indicate to the CLI module that
+ * there are no more dynamic commands to read.
+ */
+typedef void (*nrf_cli_dynamic_get)(size_t idx, nrf_cli_static_entry_t * p_static);
+
+/**
+ * @brief CLI command descriptor.
+ */
+struct nrf_cli_cmd_entry
+{
+ bool is_dynamic;
+ union
+ {
+ nrf_cli_dynamic_get p_dynamic_get; //!< Pointer to function returning dynamic commands.
+ nrf_cli_static_entry_t const * p_static; //!< Pointer to array of static commands.
+ } u;
+};
+
+/**
+ * @brief CLI command handler prototype.
+ */
+typedef void (*nrf_cli_cmd_handler)(nrf_cli_t const * p_cli, size_t argc, char **argv);
+
+/**
+ * @brief CLI static command descriptor.
+ */
+struct nrf_cli_static_entry
+{
+ char const * p_syntax; //!< Command syntax strings.
+ char const * p_help; //!< Command help string.
+
+ nrf_cli_cmd_entry_t const * p_subcmd; //!< Pointer to subcommand.
+
+ nrf_cli_cmd_handler handler; //!< Command handler.
+};
+
+/**
+ * @brief Macro for defining and adding a root command (level 0).
+ *
+ * @note Each root command shall have unique syntax.
+ *
+ * @param[in] p_syntax Command syntax (for example: history).
+ * @param[in] p_subcmd Pointer to a subcommands array.
+ * @param[in] p_help Pointer to a command help string.
+ * @param[in] p_handler Pointer to a function handler.
+ */
+#define NRF_CLI_CMD_REGISTER(p_syntax, p_subcmd, p_help, p_handler) \
+ nrf_cli_static_entry_t const CONCAT_3(nrf_cli_, p_syntax, _raw) = \
+ NRF_CLI_CMD(p_syntax, p_subcmd, p_help, p_handler); \
+ NRF_SECTION_ITEM_REGISTER(cli_command, \
+ nrf_cli_cmd_entry_t const CONCAT_3(nrf_cli_, p_syntax, _const)) = { \
+ .is_dynamic = false, \
+ .u.p_static = &CONCAT_3(nrf_cli_, p_syntax, _raw) \
+ }; \
+ NRF_SECTION_ITEM_REGISTER(cli_sorted_cmd_ptrs, char const * CONCAT_2(p_syntax, _str_ptr))
+
+/**
+ * @brief Macro for creating a subcommand set. It must be used outside of any function body.
+ *
+ * @param[in] name Name of the subcommand set.
+ */
+#define NRF_CLI_CREATE_STATIC_SUBCMD_SET(name) \
+ /*lint -save -e85 -e31*/ \
+ static nrf_cli_static_entry_t const CONCAT_2(name, _raw)[]; \
+ static nrf_cli_cmd_entry_t const name = { \
+ .is_dynamic = false, \
+ .u.p_static = CONCAT_2(name, _raw) \
+ }; \
+ static nrf_cli_static_entry_t const CONCAT_2(name, _raw)[] = /*lint -restore*/
+
+/**
+ * @brief Define ending subcommands set.
+ *
+ */
+#define NRF_CLI_SUBCMD_SET_END {NULL}
+
+/**
+ * @brief Macro for creating a dynamic entry.
+ *
+ * @param[in] name Name of the dynamic entry.
+ * @param[in] p_get Pointer to the function returning dynamic commands array @ref nrf_cli_dynamic_get.
+ */
+#define NRF_CLI_CREATE_DYNAMIC_CMD(name, p_get) \
+ /*lint -save -e19*/ \
+ static nrf_cli_cmd_entry_t const name = { \
+ .is_dynamic = true, \
+ .u.p_dynamic_get = p_get \
+}; /*lint -restore*/
+
+/**
+ * @brief Initializes a CLI command (@ref nrf_cli_static_entry).
+ *
+ * @param[in] _p_syntax Command syntax (for example: history).
+ * @param[in] _p_subcmd Pointer to a subcommands array.
+ * @param[in] _p_help Pointer to a command help string.
+ * @param[in] _p_handler Pointer to a function handler.
+ */
+#define NRF_CLI_CMD(_p_syntax, _p_subcmd, _p_help, _p_handler) { \
+ .p_syntax = (const char *) STRINGIFY(_p_syntax), \
+ .p_subcmd = _p_subcmd, \
+ .p_help = (const char *) _p_help, \
+ .handler = _p_handler \
+}
+
+/**
+ * @internal @brief Internal CLI state in response to data received from the terminal.
+ */
+typedef enum
+{
+ NRF_CLI_RECEIVE_DEFAULT,
+ NRF_CLI_RECEIVE_ESC,
+ NRF_CLI_RECEIVE_ESC_SEQ
+} nrf_cli_receive_t;
+
+
+/**
+ * @internal @brief Internal CLI state.
+ */
+typedef enum
+{
+ NRF_CLI_STATE_UNINITIALIZED, //!< State uninitialized.
+ NRF_CLI_STATE_INITIALIZED, //!< State initialized but not active.
+ NRF_CLI_STATE_ACTIVE, //!< State active.
+ NRF_CLI_STATE_PANIC_MODE_ACTIVE, //!< State panic mode activated.
+ NRF_CLI_STATE_PANIC_MODE_INACTIVE //!< State panic mode requested but not supported.
+} nrf_cli_state_t;
+
+/**
+ * @brief Event type from CLI transport.
+ */
+typedef enum
+{
+ NRF_CLI_TRANSPORT_EVT_RX_RDY,
+ NRF_CLI_TRANSPORT_EVT_TX_RDY
+} nrf_cli_transport_evt_t;
+
+typedef void (*nrf_cli_transport_handler_t)(nrf_cli_transport_evt_t evt_type, void * p_context);
+
+typedef struct nrf_cli_transport_s nrf_cli_transport_t;
+
+/**
+ * @brief Unified CLI transport interface.
+ */
+typedef struct
+{
+ /**
+ * @brief Function for initializing the CLI transport interface.
+ *
+ * @param[in] p_transport Pointer to the transfer instance.
+ * @param[in] p_config Pointer to instance configuration.
+ * @param[in] evt_handler Event handler.
+ * @param[in] p_context Pointer to the context passed to event handler.
+ *
+ * @return Standard error code.
+ */
+ ret_code_t (*init)(nrf_cli_transport_t const * p_transport,
+ void const * p_config,
+ nrf_cli_transport_handler_t evt_handler,
+ void * p_context);
+
+ /**
+ * @brief Function for uninitializing the CLI transport interface.
+ *
+ * @param[in] p_transport Pointer to the transfer instance.
+ *
+ * @return Standard error code.
+ */
+ ret_code_t (*uninit)(nrf_cli_transport_t const * p_transport);
+
+ /**
+ * @brief Function for reconfiguring the transport to work in blocking mode.
+ *
+ * @param p_transport Pointer to the transfer instance.
+ * @param blocking If true, the transport is enabled in blocking mode.
+ *
+ * @return NRF_SUCCESS on successful enabling, error otherwise (also if not supported).
+ */
+ ret_code_t (*enable)(nrf_cli_transport_t const * p_transport,
+ bool blocking);
+
+ /**
+ * @brief Function for writing data to the transport interface.
+ *
+ * @param[in] p_transport Pointer to the transfer instance.
+ * @param[in] p_data Pointer to the source buffer.
+ * @param[in] length Source buffer length.
+ * @param[in] p_cnt Pointer to the sent bytes counter.
+ *
+ * @return Standard error code.
+ */
+ ret_code_t (*write)(nrf_cli_transport_t const * p_transport,
+ const void * p_data,
+ size_t length,
+ size_t * p_cnt);
+
+ /**
+ * @brief Function for reading data from the transport interface.
+ *
+ * @param[in] p_transport Pointer to the transfer instance.
+ * @param[in] p_data Pointer to the destination buffer.
+ * @param[in] length Destination buffer length.
+ * @param[in] p_cnt Pointer to the received bytes counter.
+ *
+ * @return Standard error code.
+ */
+ ret_code_t (*read)(nrf_cli_transport_t const * p_transport,
+ void * p_data,
+ size_t length,
+ size_t * p_cnt);
+
+} nrf_cli_transport_api_t;
+
+struct nrf_cli_transport_s
+{
+ nrf_cli_transport_api_t const * p_api;
+};
+
+#if NRF_MODULE_ENABLED(NRF_CLI_HISTORY)
+/**
+ * @brief CLI history object header.
+ */
+typedef PACKED_STRUCT
+{
+ nrf_memobj_t * p_prev; //!< Pointer to the next object.
+ nrf_memobj_t * p_next; //!< Pointer to the previous object.
+ nrf_cli_cmd_len_t cmd_len; //!< Command length.
+} nrf_cli_memobj_header_t;
+#endif
+
+#if NRF_MODULE_ENABLED(NRF_CLI_STATISTICS)
+typedef struct
+{
+ uint32_t log_lost_cnt; //!< Lost log counter.
+} nrf_cli_statistics_t;
+#endif
+
+/**
+ * @internal @brief Flags for internal CLI usage.
+ */
+typedef struct
+{
+ uint32_t insert_mode : 1; //!< Enables or disables console insert mode for text introduction.
+ uint32_t show_help : 1; //!< Shows help if the command was called with -h or --help parameter.
+ uint32_t use_colors : 1; //!< Enables or disables colored syntax.
+ uint32_t echo : 1; //!< Enables or disables CLI echo.
+ uint32_t processing : 1; //!< CLI is executing process function.
+ uint32_t tx_rdy : 1;
+} nrf_cli_flag_t;
+STATIC_ASSERT(sizeof(nrf_cli_flag_t) == sizeof(uint32_t));
+
+/**
+ * @internal @brief Union for internal CLI usage.
+ */
+typedef union
+{
+ uint32_t value;
+ nrf_cli_flag_t flag;
+} nrf_cli_internal_t;
+
+/**
+ * @brief CLI instance context.
+ */
+typedef struct
+{
+ nrf_cli_state_t state; //!< Internal module state.
+ nrf_cli_receive_t receive_state; //!< Escape sequence indicator.
+
+ nrf_cli_static_entry_t const * p_current_stcmd; //!< Currently executed command.
+
+ nrf_cli_vt100_ctx_t vt100_ctx; //!< VT100 color and cursor position, terminal width.
+
+ nrf_cli_cmd_len_t cmd_buff_len; //!< Command length.
+ nrf_cli_cmd_len_t cmd_buff_pos; //!< Command buffer cursor position.
+
+#if NRF_MODULE_ENABLED(NRF_CLI_WILDCARD)
+ nrf_cli_cmd_len_t cmd_tmp_buff_len; //!< Command length in tmp buffer
+#endif
+
+ char cmd_buff[NRF_CLI_CMD_BUFF_SIZE]; //!< Command input buffer.
+ char temp_buff[NRF_CLI_CMD_BUFF_SIZE]; //!< Temporary buffer used by various functions.
+ char printf_buff[NRF_CLI_PRINTF_BUFF_SIZE]; //!< Printf buffer size.
+
+#if NRF_MODULE_ENABLED(NRF_CLI_STATISTICS)
+ nrf_cli_statistics_t statistics; //!< CLI statistics.
+#endif
+
+#if NRF_MODULE_ENABLED(NRF_CLI_USES_TASK_MANAGER)
+ task_id_t task_id;
+#endif
+
+#if NRF_MODULE_ENABLED(NRF_CLI_HISTORY)
+ nrf_memobj_t * p_cmd_list_head; //!< Pointer to the head of history list.
+ nrf_memobj_t * p_cmd_list_tail; //!< Pointer to the tail of history list.
+ nrf_memobj_t * p_cmd_list_element; //!< Pointer to an element of history list.
+#endif
+ volatile nrf_cli_internal_t internal; //!< Internal CLI data
+} nrf_cli_ctx_t;
+
+extern const nrf_log_backend_api_t nrf_log_backend_cli_api;
+
+typedef struct
+{
+ nrf_log_backend_t backend;
+ nrf_queue_t const * p_queue;
+ void * p_context;
+ nrf_cli_t const * p_cli;
+} nrf_cli_log_backend_t;
+
+#if NRF_CLI_LOG_BACKEND && NRF_MODULE_ENABLED(NRF_LOG)
+#define NRF_LOG_BACKEND_CLI_DEF(_name_, _queue_size_) \
+ NRF_QUEUE_DEF(nrf_log_entry_t, \
+ CONCAT_2(_name_, _queue),_queue_size_, NRF_QUEUE_MODE_NO_OVERFLOW); \
+ static nrf_cli_log_backend_t _name_ = { \
+ .backend = {.p_api = &nrf_log_backend_cli_api}, \
+ .p_queue = &CONCAT_2(_name_, _queue), \
+ }
+
+#define NRF_CLI_BACKEND_PTR(_name_) &CONCAT_2(_name_, _log_backend)
+#else
+#define NRF_LOG_BACKEND_CLI_DEF(_name_, _queue_sz_)
+#define NRF_CLI_BACKEND_PTR(_name_) NULL
+#endif
+
+#if NRF_MODULE_ENABLED(NRF_CLI_HISTORY)
+/* Header consists memory for cmd length and pointer to: prev and next element. */
+#define NRF_CLI_HISTORY_HEADER_SIZE (sizeof(nrf_cli_memobj_header_t))
+
+#define NRF_CLI_HISTORY_MEM_OBJ(name) \
+ NRF_MEMOBJ_POOL_DEF(CONCAT_2(name, _cmd_hist_memobj), \
+ NRF_CLI_HISTORY_HEADER_SIZE + \
+ NRF_CLI_HISTORY_ELEMENT_SIZE, \
+ NRF_CLI_HISTORY_ELEMENT_COUNT)
+
+#define NRF_CLI_MEMOBJ_PTR(_name_) &CONCAT_2(_name_, _cmd_hist_memobj)
+#else
+#define NRF_CLI_MEMOBJ_PTR(_name_) NULL
+#define NRF_CLI_HISTORY_MEM_OBJ(name)
+#endif
+
+/**
+ * @brief CLI instance internals.
+ *
+ * @ref nrf_cli_t
+ */
+struct nrf_cli
+{
+ char const * const p_name; //!< Terminal name.
+
+ nrf_cli_transport_t const * p_iface; //!< Transport interface.
+ nrf_cli_ctx_t * p_ctx; //!< Internal context.
+ nrf_cli_log_backend_t * p_log_backend; //!< Logger backend.
+ nrf_fprintf_ctx_t * p_fprintf_ctx; //!< fprintf context.
+ nrf_memobj_pool_t const * p_cmd_hist_mempool; //!< Memory reserved for commands history.
+ char const newline_char; //!< New line character, only allowed values: \\n and \\r.
+};
+
+/**
+ * @brief Macro for defining a command line interface instance.
+ *
+ * @param[in] name Instance name.
+ * @param[in] cli_prefix CLI prefix string.
+ * @param[in] p_transport_iface Pointer to the transport interface.
+ * @param[in] newline_ch New line character - only allowed values are '\\n' or '\\r'.
+ * @param[in] log_queue_size Logger processing queue size.
+ */
+#define NRF_CLI_DEF(name, cli_prefix, p_transport_iface, newline_ch, log_queue_size) \
+ static nrf_cli_t const name; \
+ static nrf_cli_ctx_t CONCAT_2(name, _ctx); \
+ NRF_FPRINTF_DEF(CONCAT_2(name, _fprintf_ctx), \
+ &name, \
+ CONCAT_2(name, _ctx).printf_buff, \
+ NRF_CLI_PRINTF_BUFF_SIZE, \
+ false, \
+ nrf_cli_print_stream); \
+ NRF_LOG_BACKEND_CLI_DEF(CONCAT_2(name, _log_backend), log_queue_size); \
+ NRF_CLI_HISTORY_MEM_OBJ(name); \
+ /*lint -save -e31*/ \
+ static nrf_cli_t const name = { \
+ .p_name = cli_prefix, \
+ .p_iface = p_transport_iface, \
+ .p_ctx = &CONCAT_2(name, _ctx), \
+ .p_log_backend = NRF_CLI_BACKEND_PTR(name), \
+ .p_fprintf_ctx = &CONCAT_2(name, _fprintf_ctx), \
+ .p_cmd_hist_mempool = NRF_CLI_MEMOBJ_PTR(name), \
+ .newline_char = newline_ch \
+ } /*lint -restore*/
+
+/**
+ * @brief Function for initializing a transport layer and internal CLI state.
+ *
+ * @param[in] p_cli Pointer to CLI instance.
+ * @param[in] p_transport_config Configuration forwarded to the transport during initialization.
+ * @param[in] use_colors Enables colored prints.
+ * @param[in] log_backend If true, the console will be used as logger backend.
+ * @param[in] init_lvl Default severity level for the logger.
+ *
+ * @return Standard error code.
+ */
+ret_code_t nrf_cli_init(nrf_cli_t const * p_cli,
+ void const * p_transport_config,
+ bool use_colors,
+ bool log_backend,
+ nrf_log_severity_t init_lvl);
+
+ret_code_t nrf_cli_task_create(nrf_cli_t const * p_cli);
+
+/**
+ * @brief Function for uninitializing a transport layer and internal CLI state.
+ * If function returns NRF_ERROR_BUSY, you must call @ref nrf_cli_process before calling
+ * nrf_cli_uninit again.
+ *
+ * @param p_cli Pointer to CLI instance.
+ *
+ * @return Standard error code.
+ */
+ret_code_t nrf_cli_uninit(nrf_cli_t const * p_cli);
+
+/**
+ * @brief Function for starting CLI processing.
+ *
+ * @param p_cli Pointer to the CLI instance.
+ *
+ * @return Standard error code.
+ */
+ret_code_t nrf_cli_start(nrf_cli_t const * p_cli);
+
+/**
+ * @brief Function for stopping CLI processing.
+ *
+ * @param p_cli Pointer to CLI instance.
+ *
+ * @return Standard error code.
+ */
+ret_code_t nrf_cli_stop(nrf_cli_t const * p_cli);
+
+/**
+ * @brief CLI colors for @ref nrf_cli_fprintf function.
+ */
+#define NRF_CLI_DEFAULT NRF_CLI_VT100_COLOR_DEFAULT /**< Turn off character attributes. */
+#define NRF_CLI_NORMAL NRF_CLI_VT100_COLOR_WHITE /**< Normal color printf. */
+#define NRF_CLI_INFO NRF_CLI_VT100_COLOR_GREEN /**< Info color printf. */
+#define NRF_CLI_OPTION NRF_CLI_VT100_COLOR_CYAN /**< Option color printf. */
+#define NRF_CLI_WARNING NRF_CLI_VT100_COLOR_YELLOW /**< Warning color printf. */
+#define NRF_CLI_ERROR NRF_CLI_VT100_COLOR_RED /**< Error color printf. */
+
+/**
+ * @brief Printf-like function which sends formatted data stream to the CLI.
+ * This function shall not be used outside of the CLI module or CLI command context.
+ *
+ * @param[in] p_cli Pointer to the CLI instance.
+ * @param[in] color Printf color.
+ * @param[in] p_fmt Format string.
+ * @param[in] ... List of parameters to print.
+ */
+void nrf_cli_fprintf(nrf_cli_t const * p_cli,
+ nrf_cli_vt100_color_t color,
+ char const * p_fmt,
+ ...);
+
+/**
+ * @brief Process function, which should be executed when data is ready in the transport interface.
+ *
+ * @param[in] p_cli Pointer to the CLI instance.
+ */
+void nrf_cli_process(nrf_cli_t const * p_cli);
+
+
+/**
+ * @brief Option descriptor.
+ */
+typedef struct nrf_cli_getopt_option
+{
+ char const * p_optname; //!< Option long name.
+ char const * p_optname_short; //!< Option short name.
+ char const * p_optname_help; //!< Option help string.
+} nrf_cli_getopt_option_t;
+
+
+/**
+ * @brief Option structure initializer @ref nrf_cli_getopt_option.
+ *
+ * @param[in] _p_optname Option name long.
+ * @param[in] _p_shortname Option name short.
+ * @param[in] _p_help Option help string.
+ */
+#define NRF_CLI_OPT(_p_optname, _p_shortname, _p_help) { \
+ .p_optname = _p_optname, \
+ .p_optname_short = _p_shortname, \
+ .p_optname_help = _p_help, \
+}
+
+/**
+ * @brief Informs that a command has been called with -h or --help option.
+ *
+ * @param[in] p_cli Pointer to the CLI instance.
+ *
+ * @return True if help has been requested.
+ */
+__STATIC_INLINE bool nrf_cli_help_requested(nrf_cli_t const * p_cli);
+
+#ifndef SUPPRESS_INLINE_IMPLEMENTATION
+__STATIC_INLINE bool nrf_cli_help_requested(nrf_cli_t const * p_cli)
+{
+ return p_cli->p_ctx->internal.flag.show_help;
+}
+#endif
+
+/**
+ * @brief Prints the current command help.
+ * @details Function will print a help string with: the currently entered command, its options,
+ * and subcommands (if they exist).
+ *
+ * @param[in] p_cli Pointer to the CLI instance.
+ * @param[in] p_opt Pointer to the optional option array.
+ * @param[in] opt_len Option array size.
+ */
+void nrf_cli_help_print(nrf_cli_t const * p_cli,
+ nrf_cli_getopt_option_t const * p_opt,
+ size_t opt_len);
+
+/**
+ * @internal @brief This function shall not be used directly, it is required by the
+ * nrf_fprintf module.
+ *
+ * @param[in] p_user_ctx Pointer to the context for the CLI instance.
+ * @param[in] p_data Pointer to the data buffer.
+ * @param[in] data_len Data buffer size.
+ */
+void nrf_cli_print_stream(void const * p_user_ctx, char const * p_data, size_t data_len);
+
+/** @} */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* NRF_CLI_H__ */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/cli/nrf_cli_types.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/cli/nrf_cli_types.h
new file mode 100644
index 0000000..ca4ca75
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/cli/nrf_cli_types.h
@@ -0,0 +1,102 @@
+/**
+ * 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#ifndef NRF_CLI_TYPES_H__
+#define NRF_CLI_TYPES_H__
+
+#include <inttypes.h>
+#include "sdk_config.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#if (NRF_CLI_CMD_BUFF_SIZE > 65535)
+ typedef uint32_t nrf_cli_cmd_len_t;
+#elif (NRF_CLI_CMD_BUFF_SIZE > 255)
+ typedef uint16_t nrf_cli_cmd_len_t;
+#else
+ typedef uint8_t nrf_cli_cmd_len_t;
+#endif
+
+typedef enum
+{
+ NRF_CLI_VT100_COLOR_DEFAULT,
+ NRF_CLI_VT100_COLOR_BLACK,
+ NRF_CLI_VT100_COLOR_RED,
+ NRF_CLI_VT100_COLOR_GREEN,
+ NRF_CLI_VT100_COLOR_YELLOW,
+ NRF_CLI_VT100_COLOR_BLUE,
+ NRF_CLI_VT100_COLOR_MAGENTA,
+ NRF_CLI_VT100_COLOR_CYAN,
+ NRF_CLI_VT100_COLOR_WHITE,
+
+ VT100_COLOR_END
+} nrf_cli_vt100_color_t;
+
+typedef struct
+{
+ nrf_cli_vt100_color_t col; // text color
+ nrf_cli_vt100_color_t bgcol; // background color
+} nrf_cli_vt100_colors_t;
+
+typedef struct
+{
+ nrf_cli_cmd_len_t cur_x; // horizontal cursor position in edited command line
+ nrf_cli_cmd_len_t cur_x_end; // horizontal cursor position at the end of command
+ nrf_cli_cmd_len_t cur_y; // vertical cursor position in edited command
+ nrf_cli_cmd_len_t cur_y_end; // vertical cursor position at the end of command
+ nrf_cli_cmd_len_t terminal_hei; // terminal screen height
+ nrf_cli_cmd_len_t terminal_wid; // terminal screen width
+ uint8_t name_len; // console name length
+} nrf_cli_multiline_cons_t;
+
+typedef struct
+{
+ nrf_cli_multiline_cons_t cons;
+ nrf_cli_vt100_colors_t col;
+ nrf_cli_cmd_len_t printed_cmd; // printed commands counter
+} nrf_cli_vt100_ctx_t;
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* NRF_CLI_TYPES_H__ */
+
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/cli/nrf_cli_vt100.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/cli/nrf_cli_vt100.h
new file mode 100644
index 0000000..d581423
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/cli/nrf_cli_vt100.h
@@ -0,0 +1,625 @@
+/**
+ * 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#ifndef NRF_CLI_VT100_H__
+#define NRF_CLI_VT100_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define NRF_CLI_VT100_ASCII_ESC (0x1b)
+#define NRF_CLI_VT100_ASCII_DEL (0x7F)
+#define NRF_CLI_VT100_ASCII_BSPACE (0x08)
+
+#define NRF_CLI_VT100_SETNL \
+ { \
+ NRF_CLI_VT100_ASCII_ESC, '[', '2', '0', 'h', '\0' \
+ } /* Set new line mode */
+#define NRF_CLI_VT100_SETAPPL \
+ { \
+ NRF_CLI_VT100_ASCII_ESC, '[', '?', '1', 'h', '\0' \
+ } /* Set cursor key to application */
+#define NRF_CLI_VT100_SETCOL_132 \
+ { \
+ NRF_CLI_VT100_ASCII_ESC, '[', '?', '3', 'h', '\0' \
+ } /* Set number of columns to 132 */
+#define NRF_CLI_VT100_SETSMOOTH \
+ { \
+ NRF_CLI_VT100_ASCII_ESC, '[', '?', '4', 'h', '\0' \
+ } /* Set smooth scrolling */
+#define NRF_CLI_VT100_SETREVSCRN \
+ { \
+ NRF_CLI_VT100_ASCII_ESC, '[', '?', '5', 'h', '\0' \
+ } /* Set reverse video on screen */
+#define NRF_CLI_VT100_SETORGREL \
+ { \
+ NRF_CLI_VT100_ASCII_ESC, '[', '?', '6', 'h', '\0' \
+ } /* Set origin to relative */
+#define NRF_CLI_VT100_SETWRAP_ON \
+ { \
+ NRF_CLI_VT100_ASCII_ESC, '[', '?', '7', 'h', '\0' \
+ } /* Set auto-wrap mode */
+#define NRF_CLI_VT100_SETWRAP_OFF \
+ { \
+ NRF_CLI_VT100_ASCII_ESC, '[', '?', '7', 'l', '\0' \
+ } /* Set auto-wrap mode */
+
+#define NRF_CLI_VT100_SETREP \
+ { \
+ NRF_CLI_VT100_ASCII_ESC, '[', '?', '8', 'h', '\0' \
+ } /* Set auto-repeat mode */
+#define NRF_CLI_VT100_SETINTER \
+ { \
+ NRF_CLI_VT100_ASCII_ESC, '[', '?', '9', 'h', '\0' \
+ } /* Set interlacing mode */
+
+#define NRF_CLI_VT100_SETLF \
+ { \
+ NRF_CLI_VT100_ASCII_ESC, '[', '2', '0', 'l', '\0' \
+ } /* Set line feed mode */
+#define NRF_CLI_VT100_SETCURSOR \
+ { \
+ NRF_CLI_VT100_ASCII_ESC, '[', '?', '1', 'l', '\0' \
+ } /* Set cursor key to cursor */
+#define NRF_CLI_VT100_SETVT52 \
+ { \
+ NRF_CLI_VT100_ASCII_ESC, '[', '?', '2', 'l', '\0' \
+ } /* Set VT52 (versus ANSI) */
+#define NRF_CLI_VT100_SETCOL_80 \
+ { \
+ NRF_CLI_VT100_ASCII_ESC, '[', '?', '3', 'l', '\0' \
+ } /* Set number of columns to 80 */
+#define NRF_CLI_VT100_SETJUMP \
+ { \
+ NRF_CLI_VT100_ASCII_ESC, '[', '?', '4', 'l', '\0' \
+ } /* Set jump scrolling */
+#define NRF_CLI_VT100_SETNORMSCRN \
+ { \
+ NRF_CLI_VT100_ASCII_ESC, '[', '?', '5', 'l', '\0' \
+ } /* Set normal video on screen */
+#define NRF_CLI_VT100_SETORGABS \
+ { \
+ NRF_CLI_VT100_ASCII_ESC, '[', '?', '6', 'l', '\0' \
+ } /* Set origin to absolute */
+#define NRF_CLI_VT100_RESETWRAP \
+ { \
+ NRF_CLI_VT100_ASCII_ESC, '[', '?', '7', 'l', '\0' \
+ } /* Reset auto-wrap mode */
+#define NRF_CLI_VT100_RESETREP \
+ { \
+ NRF_CLI_VT100_ASCII_ESC, '[', '?', '8', 'l', '\0' \
+ } /* Reset auto-repeat mode */
+#define NRF_CLI_VT100_RESETINTER \
+ { \
+ NRF_CLI_VT100_ASCII_ESC, '[', '?', '9', 'l', '\0' \
+ } /* Reset interlacing mode */
+
+#define NRF_CLI_VT100_ALTKEYPAD \
+ { \
+ NRF_CLI_VT100_ASCII_ESC, '=', '\0' \
+ } /* Set alternate keypad mode */
+#define NRF_CLI_VT100_NUMKEYPAD \
+ { \
+ NRF_CLI_VT100_ASCII_ESC, '>', '\0' \
+ } /* Set numeric keypad mode */
+
+#define NRF_CLI_VT100_SETUKG0 \
+ { \
+ NRF_CLI_VT100_ASCII_ESC, '(', 'A', '\0' \
+ } /* Set United Kingdom G0 character set */
+#define NRF_CLI_VT100_SETUKG1 \
+ { \
+ NRF_CLI_VT100_ASCII_ESC, ')', 'A', '\0' \
+ } /* Set United Kingdom G1 character set */
+#define NRF_CLI_VT100_SETUSG0 \
+ { \
+ NRF_CLI_VT100_ASCII_ESC, '(', 'B', '\0' \
+ } /* Set United States G0 character set */
+#define NRF_CLI_VT100_SETUSG1 \
+ { \
+ NRF_CLI_VT100_ASCII_ESC, ')', 'B', '\0' \
+ } /* Set United States G1 character set */
+#define NRF_CLI_VT100_SETSPECG0 \
+ { \
+ NRF_CLI_VT100_ASCII_ESC, '(', '0', '\0' \
+ } /* Set G0 special chars. & line set */
+#define NRF_CLI_VT100_SETSPECG1 \
+ { \
+ NRF_CLI_VT100_ASCII_ESC, ')', '0', '\0' \
+ } /* Set G1 special chars. & line set */
+#define NRF_CLI_VT100_SETALTG0 \
+ { \
+ NRF_CLI_VT100_ASCII_ESC, '(', '1', '\0' \
+ } /* Set G0 alternate character ROM */
+#define NRF_CLI_VT100_SETALTG1 \
+ { \
+ NRF_CLI_VT100_ASCII_ESC, ')', '1', '\0' \
+ } /* Set G1 alternate character ROM */
+#define NRF_CLI_VT100_SETALTSPECG0 \
+ { \
+ NRF_CLI_VT100_ASCII_ESC, '(', '2', '\0' \
+ } /* Set G0 alt char ROM and spec. graphics */
+#define NRF_CLI_VT100_SETALTSPECG1 \
+ { \
+ NRF_CLI_VT100_ASCII_ESC, ')', '2', '\0' \
+ } /* Set G1 alt char ROM and spec. graphics */
+
+#define NRF_CLI_VT100_SETSS2 \
+ { \
+ NRF_CLI_VT100_ASCII_ESC, 'N', '\0' \
+ } /* Set single shift 2 */
+#define NRF_CLI_VT100_SETSS3 \
+ { \
+ NRF_CLI_VT100_ASCII_ESC, 'O', '\0' \
+ } /* Set single shift 3 */
+
+#define NRF_CLI_VT100_MODESOFF \
+ { \
+ NRF_CLI_VT100_ASCII_ESC, '[', 'm', '\0' \
+ } /* Turn off character attributes */
+#define NRF_CLI_VT100_MODESOFF_ \
+ { \
+ NRF_CLI_VT100_ASCII_ESC, '[', '0', 'm', '\0' \
+ } /* Turn off character attributes */
+#define NRF_CLI_VT100_BOLD \
+ { \
+ NRF_CLI_VT100_ASCII_ESC, '[', '1', 'm', '\0' \
+ } /* Turn bold mode on */
+#define NRF_CLI_VT100_LOWINT \
+ { \
+ NRF_CLI_VT100_ASCII_ESC, '[', '2', 'm', '\0' \
+ } /* Turn low intensity mode on */
+#define NRF_CLI_VT100_UNDERLINE \
+ { \
+ NRF_CLI_VT100_ASCII_ESC, '[', '4', 'm', '\0' \
+ } /* Turn underline mode on */
+#define NRF_CLI_VT100_BLINK \
+ { \
+ NRF_CLI_VT100_ASCII_ESC, '[', '5', 'm', '\0' \
+ } /* Turn blinking mode on */
+#define NRF_CLI_VT100_REVERSE \
+ { \
+ NRF_CLI_VT100_ASCII_ESC, '[', '7', 'm', '\0' \
+ } /* Turn reverse video on */
+#define NRF_CLI_VT100_INVISIBLE \
+ { \
+ NRF_CLI_VT100_ASCII_ESC, '[', '8', 'm', '\0' \
+ } /* Turn invisible text mode on */
+
+#define NRF_CLI_VT100_SETWIN(t, b) \
+ { \
+ NRF_CLI_VT100_ASCII_ESC, '[', (t), ';', (b), 'r', '\0' \
+ } /* Set top and bottom line#s of a window */
+
+#define NRF_CLI_VT100_CURSORUP(n) \
+ { \
+ NRF_CLI_VT100_ASCII_ESC, '[', (n), 'A', '\0' \
+ } /* Move cursor up n lines */
+#define NRF_CLI_VT100_CURSORDN(n) \
+ { \
+ NRF_CLI_VT100_ASCII_ESC, '[', (n), 'B', '\0' \
+ } /* Move cursor down n lines */
+#define NRF_CLI_VT100_CURSORRT(n) \
+ { \
+ NRF_CLI_VT100_ASCII_ESC, '[', (n), 'C', '\0' \
+ } /* Move cursor right n lines */
+#define NRF_CLI_VT100_CURSORLF(n) \
+ { \
+ NRF_CLI_VT100_ASCII_ESC, '[', (n), 'D', '\0' \
+ } /* Move cursor left n lines */
+#define NRF_CLI_VT100_CURSORHOME \
+ { \
+ NRF_CLI_VT100_ASCII_ESC, '[', 'H', '\0' \
+ } /* Move cursor to upper left corner */
+#define NRF_CLI_VT100_CURSORHOME_ \
+ { \
+ NRF_CLI_VT100_ASCII_ESC, '[', ';', 'H', '\0' \
+ } /* Move cursor to upper left corner */
+#define NRF_CLI_VT100_CURSORPOS(v, h) \
+ { \
+ NRF_CLI_VT100_ASCII_ESC, '[', (v), ';', (h), 'H', '\0' \
+ } /* Move cursor to screen location v,h */
+
+#define NRF_CLI_VT100_HVHOME \
+ { \
+ NRF_CLI_VT100_ASCII_ESC, '[', 'f', '\0' \
+ } /* Move cursor to upper left corner */
+#define NRF_CLI_VT100_HVHOME_ \
+ { \
+ NRF_CLI_VT100_ASCII_ESC, '[', ';', 'f', '\0' \
+ } /* Move cursor to upper left corner */
+#define NRF_CLI_VT100_HVPOS(v, h) \
+ { \
+ NRF_CLI_VT100_ASCII_ESC, '[', (v), ';', (h), 'f', '\0' \
+ } /* Move cursor to screen location v,h */
+#define NRF_CLI_VT100_INDEX \
+ { \
+ NRF_CLI_VT100_ASCII_ESC, 'D', '\0' \
+ } /* Move/scroll window up one line */
+#define NRF_CLI_VT100_REVINDEX \
+ { \
+ NRF_CLI_VT100_ASCII_ESC, 'M', '\0' \
+ } /* Move/scroll window down one line */
+#define NRF_CLI_VT100_NEXTLINE \
+ { \
+ NRF_CLI_VT100_ASCII_ESC, 'E', '\0' \
+ } /* Move to next line */
+#define NRF_CLI_VT100_SAVECURSOR \
+ { \
+ NRF_CLI_VT100_ASCII_ESC, '7', '\0' \
+ } /* Save cursor position and attributes */
+#define NRF_CLI_VT100_RESTORECURSOR \
+ { \
+ NRF_CLI_VT100_ASCII_ESC, '8', '\0' \
+ } /* Restore cursor position and attribute */
+
+#define NRF_CLI_VT100_TABSET \
+ { \
+ NRF_CLI_VT100_ASCII_ESC, 'H', '\0' \
+ } /* Set a tab at the current column */
+#define NRF_CLI_VT100_TABCLR \
+ { \
+ NRF_CLI_VT100_ASCII_ESC, '[', 'g', '\0' \
+ } /* Clear a tab at the current column */
+#define NRF_CLI_VT100_TABCLR_ \
+ { \
+ NRF_CLI_VT100_ASCII_ESC, '[', '0', 'g', '\0' \
+ } /* Clear a tab at the current column */
+#define NRF_CLI_VT100_TABCLRALL \
+ { \
+ NRF_CLI_VT100_ASCII_ESC, '[', '3', 'g', '\0' \
+ } /* Clear all tabs */
+
+#define NRF_CLI_VT100_DHTOP \
+ { \
+ NRF_CLI_VT100_ASCII_ESC, '#', '3', '\0' \
+ } /* Double-height letters, top half */
+#define NRF_CLI_VT100_DHBOT \
+ { \
+ NRF_CLI_VT100_ASCII_ESC, '#', '4', '\0' \
+ } /* Double-height letters, bottom hal */
+#define NRF_CLI_VT100_SWSH \
+ { \
+ NRF_CLI_VT100_ASCII_ESC, '#', '5', '\0' \
+ } /* Single width, single height letters */
+#define NRF_CLI_VT100_DWSH \
+ { \
+ NRF_CLI_VT100_ASCII_ESC, '#', '6', '\0' \
+ } /* Double width, single height letters */
+
+#define NRF_CLI_VT100_CLEAREOL \
+ { \
+ NRF_CLI_VT100_ASCII_ESC, '[', 'K', '\0' \
+ } /* Clear line from cursor right */
+#define NRF_CLI_VT100_CLEAREOL_ \
+ { \
+ NRF_CLI_VT100_ASCII_ESC, '[', '0', 'K', '\0' \
+ } /* Clear line from cursor right */
+#define NRF_CLI_VT100_CLEARBOL \
+ { \
+ NRF_CLI_VT100_ASCII_ESC, '[', '1', 'K', '\0' \
+ } /* Clear line from cursor left */
+#define NRF_CLI_VT100_CLEARLINE \
+ { \
+ NRF_CLI_VT100_ASCII_ESC, '[', '2', 'K', '\0' \
+ } /* Clear entire line */
+
+#define NRF_CLI_VT100_CLEAREOS \
+ { \
+ NRF_CLI_VT100_ASCII_ESC, '[', 'J', '\0' \
+ } /* Clear screen from cursor down */
+#define NRF_CLI_VT100_CLEAREOS_ \
+ { \
+ NRF_CLI_VT100_ASCII_ESC, '[', '0', 'J', '\0' \
+ } /* Clear screen from cursor down */
+#define NRF_CLI_VT100_CLEARBOS \
+ { \
+ NRF_CLI_VT100_ASCII_ESC, '[', '1', 'J', '\0' \
+ } /* Clear screen from cursor up */
+#define NRF_CLI_VT100_CLEARSCREEN \
+ { \
+ NRF_CLI_VT100_ASCII_ESC, '[', '2', 'J', '\0' \
+ } /* Clear entire screen */
+
+#define NRF_CLI_VT100_DEVSTAT \
+ { \
+ NRF_CLI_VT100_ASCII_ESC, '5', 'n', '\0' \
+ } /* Device status report */
+#define NRF_CLI_VT100_TERMOK \
+ { \
+ NRF_CLI_VT100_ASCII_ESC, '0', 'n', '\0' \
+ } /* Response: terminal is OK */
+#define NRF_CLI_VT100_TERMNOK \
+ { \
+ NRF_CLI_VT100_ASCII_ESC, '3', 'n', '\0' \
+ } /* Response: terminal is not OK */
+
+#define NRF_CLI_VT100_GETCURSOR \
+ { \
+ NRF_CLI_VT100_ASCII_ESC, '[', '6', 'n', '\0' \
+ } /* Get cursor position */
+#define NRF_CLI_VT100_CURSORPOSAT \
+ { \
+ NRF_CLI_VT100_ASCII_ESC, (v), ';', (h), 'R', '\0' \
+ } /* Response: cursor is at v,h */
+
+#define NRF_CLI_VT100_IDENT \
+ { \
+ NRF_CLI_VT100_ASCII_ESC, '[', 'c', '\0' \
+ } /* Identify what terminal type */
+#define NRF_CLI_VT100_IDENT_ \
+ { \
+ NRF_CLI_VT100_ASCII_ESC, '[', '0', 'c', '\0' \
+ } /* Identify what terminal type */
+#define NRF_CLI_VT100_GETTYPE \
+ { \
+ NRF_CLI_VT100_ASCII_ESC, '[', '?', '1', ';', (n), '0', 'c', '\0'\
+ } /* Response: terminal type code n */
+
+#define NRF_CLI_VT100_RESET \
+ { \
+ NRF_CLI_VT100_ASCII_ESC, 'c', '\0' \
+ } /* Reset terminal to initial state */
+
+#define NRF_CLI_VT100_ALIGN \
+ { \
+ NRF_CLI_VT100_ASCII_ESC, '#', '8', '\0' \
+ } /* Screen alignment display */
+#define NRF_CLI_VT100_TESTPU \
+ { \
+ NRF_CLI_VT100_ASCII_ESC, '[', '2', ';', '1', 'y', '\0' \
+ } /* Confidence power up test */
+#define NRF_CLI_VT100_TESTLB \
+ { \
+ NRF_CLI_VT100_ASCII_ESC, '[', '2', ';', '2', 'y', '\0' \
+ } /* Confidence loopback test */
+#define NRF_CLI_VT100_TESTPUREP \
+ { \
+ NRF_CLI_VT100_ASCII_ESC, '[', '2', ';', '9', 'y', '\0' \
+ } /* Repeat power up test */
+#define NRF_CLI_VT100_TESTLBREP \
+ { \
+ NRF_CLI_VT100_ASCII_ESC, '[', '2', ';', '1', '0', 'y', '\0' \
+ } /* Repeat loopback test */
+
+#define NRF_CLI_VT100_LEDSOFF \
+ { \
+ NRF_CLI_VT100_ASCII_ESC, '[', '0', 'q', '\0' \
+ } /* Turn off all four leds */
+#define NRF_CLI_VT100_LED1 \
+ { \
+ NRF_CLI_VT100_ASCII_ESC, '[', '1', 'q', '\0' \
+ } /* Turn on LED #1 */
+#define NRF_CLI_VT100_LED2 \
+ { \
+ NRF_CLI_VT100_ASCII_ESC, '[', '2', 'q', '\0' \
+ } /* Turn on LED #2 */
+#define NRF_CLI_VT100_LED3 \
+ { \
+ NRF_CLI_VT100_ASCII_ESC, '[', '3', 'q', '\0' \
+ } /* Turn on LED #3 */
+#define NRF_CLI_VT100_LED4 \
+ { \
+ NRF_CLI_VT100_ASCII_ESC, '[', '4', 'q', '\0' \
+ } /* Turn on LED #4 */
+
+/* Function Keys */
+
+#define NRF_CLI_VT100_PF1 \
+ { \
+ NRF_CLI_VT100_ASCII_ESC, 'O', 'P', '\0' \
+ }
+#define NRF_CLI_VT100_PF2 \
+ { \
+ NRF_CLI_VT100_ASCII_ESC, 'O', 'Q', '\0' \
+ }
+#define NRF_CLI_VT100_PF3 \
+ { \
+ NRF_CLI_VT100_ASCII_ESC, 'O', 'R', '\0' \
+ }
+#define NRF_CLI_VT100_PF4 \
+ { \
+ NRF_CLI_VT100_ASCII_ESC, 'O', 'S', '\0' \
+ }
+
+/* Arrow keys */
+
+#define NRF_CLI_VT100_UP_RESET \
+ { \
+ NRF_CLI_VT100_ASCII_ESC, 'A', '\0' \
+ }
+#define NRF_CLI_VT100_UP_SET \
+ { \
+ NRF_CLI_VT100_ASCII_ESC, 'O', 'A', '\0' \
+ }
+#define NRF_CLI_VT100_DOWN_RESET \
+ { \
+ NRF_CLI_VT100_ASCII_ESC, 'B', '\0' \
+ }
+#define NRF_CLI_VT100_DOWN_SET \
+ { \
+ NRF_CLI_VT100_ASCII_ESC, 'O', 'B', '\0' \
+ }
+#define NRF_CLI_VT100_RIGHT_RESET \
+ { \
+ NRF_CLI_VT100_ASCII_ESC, 'C', '\0' \
+ }
+#define NRF_CLI_VT100_RIGHT_SET \
+ { \
+ NRF_CLI_VT100_ASCII_ESC, 'O', 'C', '\0' \
+ }
+#define NRF_CLI_VT100_LEFT_RESET \
+ { \
+ NRF_CLI_VT100_ASCII_ESC, 'D', '\0' \
+ }
+#define NRF_CLI_VT100_LEFT_SET \
+ { \
+ NRF_CLI_VT100_ASCII_ESC, 'O', 'D', '\0' \
+ }
+
+/* Numeric Keypad Keys */
+
+#define NRF_CLI_VT100_NUMERIC_0 \
+ { \
+ '0', '\0' \
+ }
+#define NRF_CLI_VT100_ALT_0 \
+ { \
+ NRF_CLI_VT100_ASCII_ESC, 'O', 'p', '\0' \
+ }
+#define NRF_CLI_VT100_NUMERIC_1 \
+ { \
+ '1', '\0' \
+ }
+#define NRF_CLI_VT100_ALT_1 \
+ { \
+ NRF_CLI_VT100_ASCII_ESC, 'O', 'q', '\0' \
+ }
+#define NRF_CLI_VT100_NUMERIC_2 \
+ { \
+ '2', '\0' \
+ }
+#define NRF_CLI_VT100_ALT_2 \
+ { \
+ NRF_CLI_VT100_ASCII_ESC, 'O', 'r', '\0' \
+ }
+#define NRF_CLI_VT100_NUMERIC_3 \
+ { \
+ '3', '\0' \
+ }
+#define NRF_CLI_VT100_ALT_3 \
+ { \
+ NRF_CLI_VT100_ASCII_ESC, 'O', 's', '\0' \
+ }
+#define NRF_CLI_VT100_NUMERIC_4 \
+ { \
+ '4', '\0' \
+ }
+#define NRF_CLI_VT100_ALT_4 \
+ { \
+ NRF_CLI_VT100_ASCII_ESC, 'O', 't', '\0' \
+ }
+#define NRF_CLI_VT100_NUMERIC_5 \
+ { \
+ '5', '\0' \
+ }
+#define NRF_CLI_VT100_ALT_5 \
+ { \
+ NRF_CLI_VT100_ASCII_ESC, 'O', 'u', '\0' \
+ }
+#define NRF_CLI_VT100_NUMERIC_6 \
+ { \
+ '6', '\0' \
+ }
+#define NRF_CLI_VT100_ALT_6 \
+ { \
+ NRF_CLI_VT100_ASCII_ESC, 'O', 'v', '\0' \
+ }
+#define NRF_CLI_VT100_NUMERIC_7 \
+ { \
+ '7', '\0' \
+ }
+#define NRF_CLI_VT100_ALT_7 \
+ { \
+ NRF_CLI_VT100_ASCII_ESC, 'O', 'w', '\0' \
+ }
+#define NRF_CLI_VT100_NUMERIC_8 \
+ { \
+ '8', '\0' \
+ }
+#define NRF_CLI_VT100_ALT_8 \
+ { \
+ NRF_CLI_VT100_ASCII_ESC, 'O', 'x', '\0' \
+ }
+#define NRF_CLI_VT100_NUMERIC_9 \
+ { \
+ '9', '\0'
+#define NRF_CLI_VT100_ALT_9 \
+ { \
+ NRF_CLI_VT100_ASCII_ESC, 'O', 'y' \
+ }
+#define NRF_CLI_VT100_NUMERIC_MINUS \
+ { \
+ '-', '\0' \
+ }
+#define NRF_CLI_VT100_ALT_MINUS \
+ { \
+ NRF_CLI_VT100_ASCII_ESC, 'O', 'm', '\0' \
+ }
+#define NRF_CLI_VT100_NUMERIC_COMMA \
+ { \
+ ',', '\0' \
+ }
+#define NRF_CLI_VT100_ALT_COMMA \
+ { \
+ NRF_CLI_VT100_ASCII_ESC, 'O', 'l', '\0' \
+ }
+#define NRF_CLI_VT100_NUMERIC_PERIOD \
+ { \
+ '.', '\0' \
+ }
+#define NRF_CLI_VT100_ALT_PERIOD \
+ { \
+ NRF_CLI_VT100_ASCII_ESC, 'O', 'n', '\0' \
+ }
+#define NRF_CLI_VT100_NUMERIC_ENTER \
+ { \
+ ASCII_CR \
+ }
+#define NRF_CLI_VT100_ALT_ENTER \
+ { \
+ NRF_CLI_VT100_ASCII_ESC, 'O', 'M', '\0' \
+ }
+
+#define NRF_CLI_VT100_COLOR(__col) \
+ { \
+ NRF_CLI_VT100_ASCII_ESC, '[', '1', ';', '3', '0' + (__col), 'm', '\0' \
+ }
+#define NRF_CLI_VT100_BGCOLOR(__col) \
+ { \
+ NRF_CLI_VT100_ASCII_ESC, '[', '4', '0' + (__col), 'm', '\0' \
+ }
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* NRF_CLI_VT100_H__ */
+
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/cli/rtt/nrf_cli_rtt.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/cli/rtt/nrf_cli_rtt.c
new file mode 100644
index 0000000..badcd04
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/cli/rtt/nrf_cli_rtt.c
@@ -0,0 +1,223 @@
+/**
+ * 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+
+#include "sdk_common.h"
+#if NRF_MODULE_ENABLED(NRF_CLI_RTT)
+#include <SEGGER_RTT_Conf.h>
+#include <SEGGER_RTT.h>
+#include "nrf_cli_rtt.h"
+#include "nrf_assert.h"
+#include "nrf_delay.h"
+
+#define RTT_RX_TIMEOUT 100
+
+static bool m_host_present;
+
+static void timer_handler(void * p_context)
+{
+ nrf_cli_rtt_internal_t * p_internal = (nrf_cli_rtt_internal_t *)p_context;
+ if (SEGGER_RTT_HasData(0))
+ {
+ p_internal->p_cb->handler(NRF_CLI_TRANSPORT_EVT_RX_RDY, p_internal->p_cb->p_context);
+ }
+ p_internal->p_cb->handler(NRF_CLI_TRANSPORT_EVT_TX_RDY, p_internal->p_cb->p_context);
+
+ ret_code_t err_code = app_timer_start(*p_internal->p_timer,
+ APP_TIMER_TICKS(RTT_RX_TIMEOUT),
+ p_context);
+ ASSERT(err_code == NRF_SUCCESS);
+ UNUSED_VARIABLE(err_code);
+}
+
+static ret_code_t cli_rtt_init(nrf_cli_transport_t const * p_transport,
+ void const * p_config,
+ nrf_cli_transport_handler_t evt_handler,
+ void * p_context)
+{
+ UNUSED_PARAMETER(p_config);
+
+ nrf_cli_rtt_internal_t * p_internal =
+ CONTAINER_OF(p_transport, nrf_cli_rtt_internal_t, transport);
+ p_internal->p_cb->handler = evt_handler;
+ p_internal->p_cb->p_context = p_context;
+ p_internal->p_cb->timer_created = false;
+
+ SEGGER_RTT_Init();
+
+ m_host_present = true;
+
+ return NRF_SUCCESS;
+}
+
+static ret_code_t cli_rtt_uninit(nrf_cli_transport_t const * p_transport)
+{
+ nrf_cli_rtt_internal_t * p_internal =
+ CONTAINER_OF(p_transport, nrf_cli_rtt_internal_t, transport);
+
+ return app_timer_stop(*p_internal->p_timer);
+}
+
+static ret_code_t cli_rtt_enable(nrf_cli_transport_t const * p_transport,
+ bool blocking)
+{
+ nrf_cli_rtt_internal_t * p_internal =
+ CONTAINER_OF(p_transport, nrf_cli_rtt_internal_t, transport);
+ ret_code_t err_code = NRF_SUCCESS;
+
+ if (p_internal->p_cb->timer_created)
+ {
+ err_code = app_timer_stop(*p_internal->p_timer); //Timer may be running or inactive
+ if ((err_code != NRF_SUCCESS) && (err_code != NRF_ERROR_INVALID_STATE))
+ {
+ return err_code;
+ }
+ else
+ {
+ err_code = NRF_SUCCESS;
+ }
+ }
+ if (!blocking)
+ {
+ if (!p_internal->p_cb->timer_created)
+ {
+ err_code = app_timer_create(p_internal->p_timer,
+ APP_TIMER_MODE_SINGLE_SHOT,
+ timer_handler);
+ p_internal->p_cb->timer_created = true;
+ }
+ if (err_code == NRF_SUCCESS)
+ {
+ err_code = app_timer_start(*p_internal->p_timer,
+ APP_TIMER_TICKS(RTT_RX_TIMEOUT),
+ p_internal);
+ SEGGER_RTT_Init();
+ }
+ }
+ return err_code;
+}
+static ret_code_t cli_rtt_read(nrf_cli_transport_t const * p_transport,
+ void * p_data,
+ size_t length,
+ size_t * p_cnt)
+{
+ ASSERT(p_cnt);
+ UNUSED_PARAMETER(p_transport);
+
+ size_t rcnt = SEGGER_RTT_Read(NRF_CLI_RTT_TERMINAL_ID, p_data, length);
+ *p_cnt = rcnt;
+
+ return NRF_SUCCESS;
+}
+
+static ret_code_t cli_rtt_write(nrf_cli_transport_t const * p_transport,
+ const void * p_data,
+ size_t length,
+ size_t * p_cnt)
+{
+ ASSERT(p_cnt);
+ UNUSED_PARAMETER(p_transport);
+
+ if (!(CoreDebug->DHCSR & CoreDebug_DHCSR_C_DEBUGEN_Msk))
+ {
+ /* If an RTT session is not active, but the RTT console is processed, the program may hang.
+ * Workaround: If the debugger is not connected, always return NRF_SUCCESS.
+ */
+ *p_cnt = length;
+ return NRF_SUCCESS;
+ }
+
+ size_t idx = 0;
+ uint32_t processed;
+ uint32_t watchdog_counter = NRF_CLI_RTT_TX_RETRY_CNT;
+ const uint8_t * p_buffer = (const uint8_t *)p_data;
+ do {
+ processed = SEGGER_RTT_Write(NRF_CLI_RTT_TERMINAL_ID, &p_buffer[idx], length);
+ if (processed == 0)
+ {
+ /* There are two possible reasons for not writing any data to RTT:
+ * - The host is not connected and not reading the data.
+ * - The buffer got full and will be read by the host.
+ * These two situations are distinguished using the following algorithm.
+ * At the begining, the module assumes that the host is active,
+ * so when no data is read, it busy waits and retries.
+ * If, after retrying, the host reads the data, the module assumes that the host is active.
+ * If it fails, the module assumes that the host is inactive and stores that information. On next
+ * call, only one attempt takes place. The host is marked as active if the attempt is successful.
+ */
+ if (!m_host_present)
+ {
+ break;
+ }
+ else
+ {
+ nrf_delay_ms(NRF_CLI_RTT_TX_RETRY_DELAY_MS);
+ watchdog_counter--;
+ if (watchdog_counter == 0)
+ {
+ m_host_present = false;
+ break;
+ }
+ }
+ }
+ m_host_present = true;
+ idx += processed;
+ length -= processed;
+ } while (length);
+
+ if (idx > 0)
+ {
+ *p_cnt = idx;
+ }
+ else
+ {
+ *p_cnt = length;
+ }
+ return NRF_SUCCESS;
+}
+
+const nrf_cli_transport_api_t nrf_cli_rtt_transport_api = {
+ .init = cli_rtt_init,
+ .uninit = cli_rtt_uninit,
+ .enable = cli_rtt_enable,
+ .read = cli_rtt_read,
+ .write = cli_rtt_write,
+};
+
+#endif
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/cli/rtt/nrf_cli_rtt.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/cli/rtt/nrf_cli_rtt.h
new file mode 100644
index 0000000..4cb44e1
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/cli/rtt/nrf_cli_rtt.h
@@ -0,0 +1,100 @@
+/**
+ * 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#ifndef NRF_CLI_RTT_H__
+#define NRF_CLI_RTT_H__
+
+#include "nrf_cli.h"
+#include "app_timer.h"
+#include "nordic_common.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**@file
+ *
+ * @defgroup nrf_cli_rtt RTT command line interface transport layer
+ * @ingroup nrf_cli
+ *
+ * @{
+ *
+ */
+
+/**
+ * @brief Command line interface transport.
+ */
+extern const nrf_cli_transport_api_t nrf_cli_rtt_transport_api;
+
+/**
+ * @brief CLI RTT transport control block structure.
+ */
+typedef struct {
+ nrf_cli_transport_handler_t handler; //!< Event handler
+ void * p_context; //!< User context.
+ bool timer_created;//!< Flag indicating whether a timer is created.
+} nrf_cli_rtt_internal_cb_t;
+
+/**
+ * @brief CLI RTT transport instance structure.
+ */
+typedef struct {
+ nrf_cli_transport_t transport; //!< Transport structure.
+ nrf_cli_rtt_internal_cb_t * p_cb; //!< Pointer to the instance control block.
+ app_timer_id_t const * p_timer; //!< Pointer to the app_timer instance.
+} nrf_cli_rtt_internal_t;
+
+/**@brief CLI RTT transport definition */
+#define NRF_CLI_RTT_DEF(_name_) \
+ APP_TIMER_DEF(CONCAT_2(_name_, _timer)); \
+ static nrf_cli_rtt_internal_cb_t CONCAT_2(_name_, _cb); \
+ static const nrf_cli_rtt_internal_t _name_ = { \
+ .transport = {.p_api = &nrf_cli_rtt_transport_api}, \
+ .p_cb = &CONCAT_2(_name_, _cb), \
+ .p_timer = &CONCAT_2(_name_, _timer) \
+ }
+
+/** @} */
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* NRF_CLI_RTT_H__ */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/cli/uart/nrf_cli_uart.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/cli/uart/nrf_cli_uart.c
new file mode 100644
index 0000000..d38941a
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/cli/uart/nrf_cli_uart.c
@@ -0,0 +1,308 @@
+/**
+ * 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#include "sdk_common.h"
+#if NRF_MODULE_ENABLED(NRF_CLI_UART)
+#include "nrf_cli_uart.h"
+#include "nrf_drv_uart.h"
+#include "nrf_assert.h"
+
+#define NRF_LOG_MODULE_NAME cli_uart
+
+#define NRF_LOG_LEVEL (NRF_CLI_UART_CONFIG_LOG_ENABLED ? NRF_CLI_UART_CONFIG_LOG_LEVEL : 0)
+#define NRF_LOG_INFO_COLOR NRF_CLI_UART_CONFIG_INFO_COLOR
+#define NRF_LOG_DEBUG_COLOR NRF_CLI_UART_CONFIG_DEBUG_COLOR
+
+#include "nrf_log.h"
+NRF_LOG_MODULE_REGISTER();
+
+#define CLI_UART_RX_TIMEOUT 100
+
+static ret_code_t rx_try(nrf_cli_uart_internal_t * p_internal)
+{
+ ret_code_t err_code;
+ size_t len = 255;
+ uint8_t * p_data;
+
+ err_code = nrf_ringbuf_alloc(p_internal->p_rx_ringbuf, &p_data, &len, true);
+ ASSERT(err_code == NRF_SUCCESS);
+
+ if ((err_code == NRF_SUCCESS) && len)
+ {
+ err_code = nrf_drv_uart_rx(p_internal->p_uart, p_data, len);
+
+ if (err_code == NRF_SUCCESS)
+ {
+ err_code = app_timer_start(*p_internal->p_timer,
+ APP_TIMER_TICKS(CLI_UART_RX_TIMEOUT),
+ p_internal);
+ }
+ }
+
+ return err_code;
+}
+
+static void uart_event_handler(nrf_drv_uart_event_t * p_event, void * p_context)
+{
+ nrf_cli_uart_internal_t * p_internal = (nrf_cli_uart_internal_t *)p_context;
+ ret_code_t err_code = NRF_SUCCESS;
+ UNUSED_VARIABLE(err_code);
+ uint8_t * p_data;
+ size_t len = 255;
+ switch (p_event->type)
+ {
+ case NRF_DRV_UART_EVT_ERROR:
+ NRF_LOG_WARNING("id:%d, evt: ERROR:%d",
+ p_internal->p_uart->inst_idx,
+ p_event->data.error.error_mask);
+ err_code = nrf_ringbuf_put(p_internal->p_rx_ringbuf, p_event->data.error.rxtx.bytes);
+ ASSERT((err_code == NRF_SUCCESS) || (err_code == NRF_ERROR_NO_MEM));
+ err_code = rx_try(p_internal);
+ ASSERT(err_code == NRF_SUCCESS);
+
+ break;
+
+ case NRF_DRV_UART_EVT_RX_DONE:
+ err_code = nrf_ringbuf_put(p_internal->p_rx_ringbuf, p_event->data.rxtx.bytes);
+ ASSERT((err_code == NRF_SUCCESS) || (err_code == NRF_ERROR_NO_MEM));
+
+ if (p_event->data.rxtx.bytes)
+ {
+ NRF_LOG_INFO("id:%d, evt: RXRDY len:%d",
+ p_internal->p_uart->inst_idx,
+ p_event->data.rxtx.bytes);
+ NRF_LOG_HEXDUMP_DEBUG(p_event->data.rxtx.p_data, p_event->data.rxtx.bytes);
+ p_internal->p_cb->handler(NRF_CLI_TRANSPORT_EVT_RX_RDY,
+ p_internal->p_cb->p_context);
+ }
+ err_code = rx_try(p_internal);
+ ASSERT(err_code == NRF_SUCCESS);
+
+ break;
+
+ case NRF_DRV_UART_EVT_TX_DONE:
+ err_code = nrf_ringbuf_free(p_internal->p_tx_ringbuf, p_event->data.rxtx.bytes);
+ ASSERT(err_code == NRF_SUCCESS);
+ len = 255;
+ err_code = nrf_ringbuf_get(p_internal->p_tx_ringbuf, &p_data, &len, true);
+ ASSERT(err_code == NRF_SUCCESS);
+ if (len)
+ {
+ NRF_LOG_INFO("id:%d, evt uart_tx, len:%d", p_internal->p_uart->inst_idx, len);
+ err_code = nrf_drv_uart_tx(p_internal->p_uart, p_data, len);
+ ASSERT(err_code == NRF_SUCCESS);
+ }
+ p_internal->p_cb->handler(NRF_CLI_TRANSPORT_EVT_TX_RDY, p_internal->p_cb->p_context);
+ NRF_LOG_INFO("id:%d, evt: TXRDY, len:%d",
+ p_internal->p_uart->inst_idx,
+ p_event->data.rxtx.bytes);
+ break;
+
+ default:
+ NRF_LOG_ERROR("Unknown event");
+ ASSERT(false);
+ }
+}
+
+static void timer_handler(void * p_context)
+{
+ nrf_cli_uart_internal_t * p_internal = (nrf_cli_uart_internal_t *)p_context;
+ NRF_LOG_DEBUG("id:%d, evt: Timeout", p_internal->p_uart->inst_idx);
+ nrf_drv_uart_rx_abort(p_internal->p_uart);
+}
+
+static ret_code_t cli_uart_init(nrf_cli_transport_t const * p_transport,
+ void const * p_config,
+ nrf_cli_transport_handler_t evt_handler,
+ void * p_context)
+{
+ nrf_cli_uart_internal_t * p_internal =
+ CONTAINER_OF(p_transport,
+ nrf_cli_uart_internal_t,
+ transport);
+ p_internal->p_cb->handler = evt_handler;
+ p_internal->p_cb->p_context = p_context;
+ p_internal->p_cb->timer_created = false;
+ p_internal->p_cb->blocking = false;
+
+ nrf_drv_uart_config_t * p_uart_config = (nrf_drv_uart_config_t *)p_config;
+ memcpy(&p_internal->p_cb->uart_config, p_uart_config, sizeof(nrf_drv_uart_config_t));
+ p_uart_config->p_context = (void *)p_internal;
+ ret_code_t err_code = nrf_drv_uart_init(p_internal->p_uart,
+ p_uart_config,
+ uart_event_handler);
+ if (err_code == NRF_SUCCESS)
+ {
+ nrf_ringbuf_init(p_internal->p_rx_ringbuf);
+ nrf_ringbuf_init(p_internal->p_tx_ringbuf);
+ }
+ return err_code;
+}
+
+static ret_code_t cli_uart_uninit(nrf_cli_transport_t const * p_transport)
+{
+ nrf_cli_uart_internal_t * p_internal =
+ CONTAINER_OF(p_transport,
+ nrf_cli_uart_internal_t,
+ transport);
+
+ nrf_drv_uart_uninit(p_internal->p_uart);
+
+ return app_timer_stop(*p_internal->p_timer);
+}
+
+static ret_code_t cli_uart_enable(nrf_cli_transport_t const * p_transport,
+ bool blocking)
+{
+ nrf_cli_uart_internal_t * p_internal =
+ CONTAINER_OF(p_transport,
+ nrf_cli_uart_internal_t,
+ transport);
+ ret_code_t err_code = NRF_SUCCESS;
+
+ if (p_internal->p_cb->timer_created)
+ {
+ err_code = app_timer_stop(*p_internal->p_timer); //Timer may be running or inactive
+ if ((err_code != NRF_SUCCESS) && (err_code != NRF_ERROR_INVALID_STATE))
+ {
+ return err_code;
+ }
+ else
+ {
+ err_code = NRF_SUCCESS;
+ }
+ }
+
+ if (blocking)
+ {
+ nrf_drv_uart_uninit(p_internal->p_uart);
+ err_code = nrf_drv_uart_init(p_internal->p_uart, &p_internal->p_cb->uart_config, NULL);
+ if (err_code == NRF_SUCCESS)
+ {
+ p_internal->p_cb->blocking = true;
+ return NRF_SUCCESS;
+ }
+ else
+ {
+ return NRF_ERROR_NOT_SUPPORTED;
+ }
+ }
+ else
+ {
+ if (!p_internal->p_cb->timer_created)
+ {
+ err_code = app_timer_create(p_internal->p_timer,
+ APP_TIMER_MODE_SINGLE_SHOT,
+ timer_handler);
+ p_internal->p_cb->timer_created = true;
+ }
+ if (err_code == NRF_SUCCESS)
+ {
+ err_code = rx_try(p_internal);
+ }
+ }
+ return err_code;
+}
+
+static ret_code_t cli_uart_read(nrf_cli_transport_t const * p_transport,
+ void * p_data,
+ size_t length,
+ size_t * p_cnt)
+{
+ ASSERT(p_cnt);
+ nrf_cli_uart_internal_t * p_instance =
+ CONTAINER_OF(p_transport, nrf_cli_uart_internal_t, transport);
+
+ *p_cnt = length;
+ ret_code_t err_code = nrf_ringbuf_cpy_get(p_instance->p_rx_ringbuf, p_data, p_cnt);
+
+ if (*p_cnt)
+ {
+ NRF_LOG_INFO("id:%d, read:%d", p_instance->p_uart->inst_idx, *p_cnt);
+ }
+
+ return err_code;
+}
+
+static ret_code_t cli_uart_write(nrf_cli_transport_t const * p_transport,
+ void const * p_data,
+ size_t length,
+ size_t * p_cnt)
+{
+ ASSERT(p_cnt);
+ nrf_cli_uart_internal_t * p_instance =
+ CONTAINER_OF(p_transport, nrf_cli_uart_internal_t, transport);
+ ret_code_t err_code;
+ *p_cnt = length;
+ err_code = nrf_ringbuf_cpy_put(p_instance->p_tx_ringbuf, p_data, p_cnt);
+ if (err_code == NRF_SUCCESS)
+ {
+ NRF_LOG_INFO("id:%d, write, req:%d, done:%d",
+ p_instance->p_uart->inst_idx,
+ length,
+ *p_cnt);
+
+ if (!nrf_drv_uart_tx_in_progress(p_instance->p_uart))
+ {
+ uint8_t * p_buf;
+ size_t len = 255;
+ if (nrf_ringbuf_get(p_instance->p_tx_ringbuf, &p_buf, &len, true) == NRF_SUCCESS)
+ {
+ NRF_LOG_INFO("id:%d, uart_tx, len:%d", p_instance->p_uart->inst_idx, len);
+
+ err_code = nrf_drv_uart_tx(p_instance->p_uart, p_buf, len);
+ if (p_instance->p_cb->blocking && (err_code == NRF_SUCCESS))
+ {
+ (void)nrf_ringbuf_free(p_instance->p_tx_ringbuf, len);
+ }
+ }
+ }
+ }
+ return err_code;
+}
+
+const nrf_cli_transport_api_t nrf_cli_uart_transport_api = {
+ .init = cli_uart_init,
+ .uninit = cli_uart_uninit,
+ .enable = cli_uart_enable,
+ .read = cli_uart_read,
+ .write = cli_uart_write,
+};
+
+#endif
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/cli/uart/nrf_cli_uart.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/cli/uart/nrf_cli_uart.h
new file mode 100644
index 0000000..1a827a4
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/cli/uart/nrf_cli_uart.h
@@ -0,0 +1,115 @@
+/**
+ * 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#ifndef NRF_CLI_UART_H__
+#define NRF_CLI_UART_H__
+
+#include "nrf_cli.h"
+#include "nrf_drv_uart.h"
+#include "nrf_ringbuf.h"
+#include "app_timer.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**@file
+ *
+ * @defgroup nrf_cli_uart UART command line interface transport layer
+ * @ingroup nrf_cli
+ *
+ * @{
+ *
+ */
+
+/**
+ * @brief Command line interface transport.
+ */
+extern const nrf_cli_transport_api_t nrf_cli_uart_transport_api;
+
+typedef struct nrf_cli_uart_internal_s nrf_cli_uart_internal_t;
+
+typedef struct {
+ nrf_cli_transport_handler_t handler;
+ void * p_context;
+ nrf_drv_uart_config_t uart_config;
+ bool timer_created;
+ bool blocking;
+} nrf_cli_uart_internal_cb_t;
+
+struct nrf_cli_uart_internal_s {
+ nrf_cli_transport_t transport;
+ nrf_cli_uart_internal_cb_t * p_cb;
+ app_timer_id_t const * p_timer;
+ nrf_ringbuf_t const * p_rx_ringbuf;
+ nrf_ringbuf_t const * p_tx_ringbuf;
+ nrf_drv_uart_t const * p_uart;
+};
+
+typedef nrf_drv_uart_config_t nrf_cli_uart_config_t;
+
+/**@brief CLI UART transport definition.
+ *
+ * @param _name Name of the instance.
+ * @param _uart_id UART instance ID.
+ * @param _tx_buf_sz Size of TX ring buffer.
+ * @param _rx_buf_sz Size of RX ring buffer.
+ */
+#define NRF_CLI_UART_DEF(_name, _uart_id, _tx_buf_sz, _rx_buf_sz) \
+ APP_TIMER_DEF(CONCAT_2(_name, _timer)); \
+ NRF_RINGBUF_DEF(CONCAT_2(_name,_tx_ringbuf), _tx_buf_sz); \
+ NRF_RINGBUF_DEF(CONCAT_2(_name,_rx_ringbuf), _rx_buf_sz); \
+ static const nrf_drv_uart_t CONCAT_2(_name,_uart) = \
+ NRF_DRV_UART_INSTANCE(_uart_id); \
+ static nrf_cli_uart_internal_cb_t CONCAT_2(_name, _cb); \
+ static const nrf_cli_uart_internal_t _name = { \
+ .transport = {.p_api = &nrf_cli_uart_transport_api}, \
+ .p_cb = &CONCAT_2(_name, _cb), \
+ .p_timer = &CONCAT_2(_name, _timer), \
+ .p_rx_ringbuf = &CONCAT_2(_name,_rx_ringbuf), \
+ .p_tx_ringbuf = &CONCAT_2(_name,_tx_ringbuf), \
+ .p_uart = &CONCAT_2(_name,_uart), \
+ }
+/** @} */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* NRF_CLI_UART_H__ */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crc16/crc16.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crc16/crc16.c
new file mode 100644
index 0000000..6e44955
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crc16/crc16.c
@@ -0,0 +1,61 @@
+/**
+ * Copyright (c) 2013 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#include "sdk_common.h"
+#if NRF_MODULE_ENABLED(CRC16)
+#include "crc16.h"
+
+#include <stdlib.h>
+
+uint16_t crc16_compute(uint8_t const * p_data, uint32_t size, uint16_t const * p_crc)
+{
+ uint16_t crc = (p_crc == NULL) ? 0xFFFF : *p_crc;
+
+ for (uint32_t i = 0; i < size; i++)
+ {
+ crc = (uint8_t)(crc >> 8) | (crc << 8);
+ crc ^= p_data[i];
+ crc ^= (uint8_t)(crc & 0xFF) >> 4;
+ crc ^= (crc << 8) << 4;
+ crc ^= ((crc & 0xFF) << 4) << 1;
+ }
+
+ return crc;
+}
+#endif //NRF_MODULE_ENABLED(CRC16)
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crc16/crc16.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crc16/crc16.h
new file mode 100644
index 0000000..79aac66
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crc16/crc16.h
@@ -0,0 +1,80 @@
+/**
+ * Copyright (c) 2013 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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
+ *
+ * @defgroup crc16 CRC16 compute
+ * @{
+ * @ingroup hci_transport
+ *
+ * @brief This module implements CRC-16-CCITT (polynomial 0x1021) with 0xFFFF initial value.
+ * The data can be passed in multiple blocks.
+ */
+
+#ifndef CRC16_H__
+#define CRC16_H__
+
+#include <stdint.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**@brief Function for calculating CRC-16 in blocks.
+ *
+ * Feed each consecutive data block into this function, along with the current value of p_crc as
+ * returned by the previous call of this function. The first call of this function should pass NULL
+ * as the initial value of the crc in p_crc.
+ *
+ * @param[in] p_data The input data block for computation.
+ * @param[in] size The size of the input data block in bytes.
+ * @param[in] p_crc The previous calculated CRC-16 value or NULL if first call.
+ *
+ * @return The updated CRC-16 value, based on the input supplied.
+ */
+uint16_t crc16_compute(uint8_t const * p_data, uint32_t size, uint16_t const * p_crc);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // CRC16_H__
+
+/** @} */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crc32/crc32.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crc32/crc32.c
new file mode 100644
index 0000000..68d0c14
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crc32/crc32.c
@@ -0,0 +1,61 @@
+/**
+ * Copyright (c) 2013 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#include "sdk_common.h"
+#if NRF_MODULE_ENABLED(CRC32)
+#include "crc32.h"
+
+#include <stdlib.h>
+
+uint32_t crc32_compute(uint8_t const * p_data, uint32_t size, uint32_t const * p_crc)
+{
+ uint32_t crc;
+
+ crc = (p_crc == NULL) ? 0xFFFFFFFF : ~(*p_crc);
+ for (uint32_t i = 0; i < size; i++)
+ {
+ crc = crc ^ p_data[i];
+ for (uint32_t j = 8; j > 0; j--)
+ {
+ crc = (crc >> 1) ^ (0xEDB88320U & ((crc & 1) ? 0xFFFFFFFF : 0));
+ }
+ }
+ return ~crc;
+}
+#endif //NRF_MODULE_ENABLED(CRC32)
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crc32/crc32.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crc32/crc32.h
new file mode 100644
index 0000000..d01cc8e
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crc32/crc32.h
@@ -0,0 +1,79 @@
+/**
+ * Copyright (c) 2015 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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
+ *
+ * @defgroup crc32 CRC32 compute
+ * @{
+ * @ingroup hci_transport
+ *
+ * @brief This module implements the CRC-32 calculation in the blocks.
+ */
+
+#ifndef CRC32_H__
+#define CRC32_H__
+
+#include <stdint.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**@brief Function for calculating CRC-32 in blocks.
+ *
+ * Feed each consecutive data block into this function, along with the current value of p_crc as
+ * returned by the previous call of this function. The first call of this function should pass NULL
+ * as the initial value of the crc in p_crc.
+ *
+ * @param[in] p_data The input data block for computation.
+ * @param[in] size The size of the input data block in bytes.
+ * @param[in] p_crc The previous calculated CRC-32 value or NULL if first call.
+ *
+ * @return The updated CRC-32 value, based on the input supplied.
+ */
+uint32_t crc32_compute(uint8_t const * p_data, uint32_t size, uint32_t const * p_crc);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // CRC32_H__
+
+/** @} */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/cc310/cc310_backend_aes.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/cc310/cc310_backend_aes.c
new file mode 100644
index 0000000..66de4bb
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/cc310/cc310_backend_aes.c
@@ -0,0 +1,887 @@
+/**
+ * Copyright (c) 2018 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+
+#include "sdk_common.h"
+#include <drivers/nrfx_common.h>
+#if NRF_MODULE_ENABLED(NRF_CRYPTO)
+
+#include <stdbool.h>
+#include "ssi_aes_error.h"
+#include "cc310_backend_aes.h"
+#include "cc310_backend_mutex.h"
+#include "cc310_backend_shared.h"
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_CC310_AES)
+
+/**@internal @brief Type declarations of templates matching all possible context sizes
+ * for this backend.
+ */
+typedef struct
+{
+ nrf_crypto_aes_internal_context_t header; /**< Common header for context. */
+ SaSiAesUserContext_t context; /**< AES context internal to mbed TLS. */
+ nrf_crypto_backend_aes_ctx_t backend; /**< Backend-specific internal context. */
+} nrf_crypto_backend_cc310_aes_any_context_t;
+
+/**@internal @brief Type declarations of templates matching all possible context sizes
+ * for this backend.
+ */
+typedef union
+{
+ nrf_crypto_backend_cc310_aes_any_context_t any; /**< Common for all contexts. */
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_CC310_AES_ECB)
+ nrf_crypto_backend_aes_ecb_context_t ecb;
+#endif
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_CC310_AES_CBC)
+ nrf_crypto_backend_aes_cbc_context_t cbc;
+#endif
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_CC310_AES_CTR)
+ nrf_crypto_backend_aes_ctr_context_t ctr;
+#endif
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_CC310_AES_CBC_MAC)
+ nrf_crypto_backend_aes_cbc_mac_context_t cbc_mac;
+#endif
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_CC310_AES_CMAC)
+ nrf_crypto_backend_aes_cmac_context_t cmac;
+#endif
+} nrf_crypto_backend_cc310_aes_context_t;
+
+
+static ret_code_t result_get(SaSiError_t error)
+{
+ ret_code_t ret_val;
+ switch (error)
+ {
+ case SASI_SUCCESS:
+ ret_val = NRF_SUCCESS;
+ break;
+
+ case SASI_AES_INVALID_USER_CONTEXT_POINTER_ERROR:
+ ret_val = NRF_ERROR_CRYPTO_CONTEXT_NULL;
+ break;
+
+ case SASI_AES_ILLEGAL_KEY_SIZE_ERROR:
+ case SASI_AES_DATA_IN_SIZE_ILLEGAL:
+ case SASI_AES_DATA_IN_BUFFER_SIZE_ERROR:
+ ret_val = NRF_ERROR_CRYPTO_INPUT_LENGTH;
+ break;
+
+ case SASI_AES_INVALID_IV_OR_TWEAK_PTR_ERROR:
+ case SASI_AES_INVALID_KEY_POINTER_ERROR:
+ case SASI_AES_DATA_IN_POINTER_INVALID_ERROR:
+ ret_val = NRF_ERROR_CRYPTO_INPUT_NULL;
+ break;
+
+ case SASI_AES_ILLEGAL_OPERATION_MODE_ERROR:
+ case SASI_AES_KEY_TYPE_NOT_SUPPORTED_ERROR:
+ case SASI_AES_INVALID_ENCRYPT_MODE_ERROR:
+ case SASI_AES_ILLEGAL_PADDING_TYPE_ERROR:
+ case SASI_AES_INCORRECT_PADDING_ERROR:
+ case SASI_AES_DECRYPTION_NOT_ALLOWED_ON_THIS_MODE:
+ case SASI_AES_ADDITIONAL_BLOCK_NOT_PERMITTED_ERROR:
+ case SASI_AES_IS_NOT_SUPPORTED:
+ ret_val = NRF_ERROR_CRYPTO_FEATURE_UNAVAILABLE;
+ break;
+
+ case SASI_AES_DATA_OUT_BUFFER_SIZE_ERROR:
+ ret_val = NRF_ERROR_CRYPTO_OUTPUT_LENGTH;
+ break;
+
+ case SASI_AES_DATA_OUT_POINTER_INVALID_ERROR:
+ case SASI_AES_DATA_OUT_SIZE_POINTER_INVALID_ERROR:
+ ret_val = NRF_ERROR_CRYPTO_OUTPUT_NULL;
+ break;
+
+ case SASI_AES_CTX_SIZES_ERROR:
+ default:
+ ret_val = NRF_ERROR_CRYPTO_INTERNAL;
+ break;
+ }
+ return ret_val;
+}
+
+static ret_code_t params_validate(nrf_crypto_backend_cc310_aes_context_t const * const p_ctx,
+ SaSiAesOperationMode_t * p_mode,
+ nrf_crypto_operation_t operation)
+{
+ ret_code_t ret_val = NRF_SUCCESS;
+
+ switch (p_ctx->any.header.p_info->mode)
+ {
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_CC310_AES_ECB)
+ case NRF_CRYPTO_AES_MODE_ECB:
+ case NRF_CRYPTO_AES_MODE_ECB_PAD_PCKS7:
+ *p_mode = SASI_AES_MODE_ECB;
+ break;
+#endif
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_CC310_AES_CBC)
+ case NRF_CRYPTO_AES_MODE_CBC:
+ case NRF_CRYPTO_AES_MODE_CBC_PAD_PCKS7:
+ *p_mode = SASI_AES_MODE_CBC;
+ break;
+#endif
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_CC310_AES_CTR)
+ case NRF_CRYPTO_AES_MODE_CTR:
+ *p_mode = SASI_AES_MODE_CTR;
+ break;
+#endif
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_CC310_AES_CBC_MAC)
+ case NRF_CRYPTO_AES_MODE_CBC_MAC:
+ case NRF_CRYPTO_AES_MODE_CBC_MAC_PAD_PCKS7:
+ *p_mode = SASI_AES_MODE_CBC_MAC;
+ VERIFY_TRUE((operation == NRF_CRYPTO_MAC_CALCULATE), NRF_ERROR_CRYPTO_INVALID_PARAM);
+ break;
+#endif
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_CC310_AES_CMAC)
+ case NRF_CRYPTO_AES_MODE_CMAC:
+ *p_mode = SASI_AES_MODE_CMAC;
+ VERIFY_TRUE((operation == NRF_CRYPTO_MAC_CALCULATE), NRF_ERROR_CRYPTO_INVALID_PARAM);
+ break;
+#endif
+
+ default:
+ ret_val = NRF_ERROR_CRYPTO_FEATURE_UNAVAILABLE;
+ break;
+ }
+
+ return ret_val;
+}
+
+static ret_code_t backend_cc310_init(void * const p_context, nrf_crypto_operation_t operation)
+{
+ SaSiError_t result;
+ ret_code_t ret_val;
+ bool mutex_locked;
+
+ SaSiAesOperationMode_t mode;
+ SaSiAesEncryptMode_t operation_cc310;
+
+ nrf_crypto_backend_cc310_aes_context_t * p_ctx =
+ (nrf_crypto_backend_cc310_aes_context_t *)p_context;
+
+ mutex_locked = cc310_backend_mutex_trylock();
+ VERIFY_TRUE(mutex_locked, NRF_ERROR_CRYPTO_BUSY);
+
+ if (!nrfx_is_in_ram(&p_ctx->any.context))
+ {
+ ret_val = NRF_ERROR_CRYPTO_INPUT_LOCATION;
+ goto exit;
+ }
+ if (p_ctx->any.header.p_info->key_size != NRF_CRYPTO_KEY_SIZE_128)
+ {
+ ret_val = NRF_ERROR_CRYPTO_KEY_SIZE;
+ goto exit;
+ }
+
+ ret_val = params_validate(p_ctx, &mode, operation);
+
+ if (ret_val != NRF_SUCCESS)
+ {
+ goto exit;
+ }
+
+ if (operation == NRF_CRYPTO_DECRYPT)
+ {
+ operation_cc310 = SASI_AES_DECRYPT;
+ }
+ else if ((operation == NRF_CRYPTO_ENCRYPT) || (operation == NRF_CRYPTO_MAC_CALCULATE))
+ {
+ operation_cc310 = SASI_AES_ENCRYPT;
+ }
+ else
+ {
+ ret_val = NRF_ERROR_CRYPTO_INVALID_PARAM;
+ goto exit;
+ }
+ p_ctx->any.backend.operation = operation;
+
+ result = SaSi_AesInit(&p_ctx->any.context,
+ operation_cc310,
+ mode,
+ SASI_AES_PADDING_NONE); /* CC310 does not support padding */
+ ret_val = result_get(result);
+
+exit:
+ cc310_backend_mutex_unlock();
+ return ret_val;
+}
+
+static ret_code_t backend_cc310_uninit(void * const p_context)
+{
+ SaSiError_t result;
+ ret_code_t ret_val;
+
+ nrf_crypto_backend_cc310_aes_context_t * p_ctx =
+ (nrf_crypto_backend_cc310_aes_context_t *)p_context;
+
+ bool mutex_locked = cc310_backend_mutex_trylock();
+ VERIFY_TRUE(mutex_locked, NRF_ERROR_CRYPTO_BUSY);
+
+ result = SaSi_AesFree(&p_ctx->any.context);
+ ret_val = result_get(result);
+
+ cc310_backend_mutex_unlock();
+ return ret_val;
+}
+
+static ret_code_t backend_cc310_key_set(void * const p_context, uint8_t * p_key)
+{
+ SaSiError_t result;
+ ret_code_t ret_val;
+ bool mutex_locked;
+
+ SaSiAesUserKeyData_t key_data;
+
+ nrf_crypto_backend_cc310_aes_context_t * p_ctx =
+ (nrf_crypto_backend_cc310_aes_context_t *)p_context;
+
+ mutex_locked = cc310_backend_mutex_trylock();
+ VERIFY_TRUE(mutex_locked, NRF_ERROR_CRYPTO_BUSY);
+
+ if (!nrfx_is_in_ram(p_key))
+ {
+ ret_val = NRF_ERROR_CRYPTO_INPUT_LOCATION;
+ goto exit;
+ }
+
+ key_data.pKey = p_key;
+ key_data.keySize = (p_ctx->any.header.p_info->key_size) >> 3; // change bits to bytes
+
+ result = SaSi_AesSetKey(&p_ctx->any.context,
+ SASI_AES_USER_KEY,
+ &key_data,
+ sizeof(key_data));
+ ret_val = result_get(result);
+
+exit:
+ cc310_backend_mutex_unlock();
+ return ret_val;
+}
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_CC310_AES_CBC) || \
+ NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_CC310_AES_CTR) || \
+ NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_CC310_AES_CBC_MAC)
+static ret_code_t backend_cc310_iv_set(void * const p_context, uint8_t * p_iv)
+{
+ SaSiError_t result;
+ ret_code_t ret_val;
+ bool mutex_locked;
+
+ nrf_crypto_backend_cc310_aes_context_t * p_ctx =
+ (nrf_crypto_backend_cc310_aes_context_t *)p_context;
+
+ mutex_locked = cc310_backend_mutex_trylock();
+ VERIFY_TRUE(mutex_locked, NRF_ERROR_CRYPTO_BUSY);
+
+ if (!nrfx_is_in_ram(p_iv))
+ {
+ ret_val = NRF_ERROR_CRYPTO_INPUT_LOCATION;
+ goto exit;
+ }
+
+ result = SaSi_AesSetIv(&p_ctx->any.context, p_iv);
+ ret_val = result_get(result);
+
+exit:
+ cc310_backend_mutex_unlock();
+ return ret_val;
+}
+
+static ret_code_t backend_cc310_iv_get(void * const p_context, uint8_t * p_iv)
+{
+ SaSiError_t result;
+ ret_code_t ret_val = NRF_ERROR_CRYPTO_INTERNAL;
+ bool mutex_locked;
+
+ nrf_crypto_backend_cc310_aes_context_t * p_ctx =
+ (nrf_crypto_backend_cc310_aes_context_t *)p_context;
+
+ mutex_locked = cc310_backend_mutex_trylock();
+ VERIFY_TRUE(mutex_locked, NRF_ERROR_CRYPTO_BUSY);
+
+ if (!nrfx_is_in_ram(p_iv))
+ {
+ ret_val = NRF_ERROR_CRYPTO_INPUT_LOCATION;
+ goto exit;
+ }
+
+ result = SaSi_AesGetIv(&p_ctx->any.context, p_iv);
+
+ /* Below code allows to read IV after calling nrf_crypto_aes_finalize */
+ if (result == SASI_AES_ILLEGAL_OPERATION_MODE_ERROR)
+ {
+ if (p_ctx->any.header.init_value == NRF_CRYPTO_AES_UNINIT_MAGIC_VALUE)
+ {
+ memcpy(p_iv, p_ctx->any.backend.iv, NRF_CRYPTO_MBEDTLS_AES_IV_SIZE);
+ ret_val = NRF_SUCCESS;
+ }
+ }
+ else
+ {
+ ret_val = result_get(result);
+ }
+
+exit:
+ cc310_backend_mutex_unlock();
+ return ret_val;
+}
+#endif
+
+static ret_code_t backend_cc310_update(void * const p_context,
+ uint8_t * p_data_in,
+ size_t data_size,
+ uint8_t * p_data_out)
+{
+ SaSiError_t result;
+ ret_code_t ret_val;
+ bool mutex_locked;
+ size_t size;
+ size_t offset = 0;
+
+ nrf_crypto_backend_cc310_aes_context_t * p_ctx =
+ (nrf_crypto_backend_cc310_aes_context_t *)p_context;
+
+ mutex_locked = cc310_backend_mutex_trylock();
+ VERIFY_TRUE(mutex_locked, NRF_ERROR_CRYPTO_BUSY);
+
+ if (!nrfx_is_in_ram(p_data_in) || !nrfx_is_in_ram(p_data_out))
+ {
+ ret_val = NRF_ERROR_CRYPTO_INPUT_LOCATION;
+ goto exit;
+ }
+
+ do
+ {
+ /* CC310 allows only 64kB blocks, operation must be devided */
+ if (data_size > CC310_MAX_LENGTH_DMA_AES_OPERATIONS)
+ {
+ size = CC310_MAX_LENGTH_DMA_AES_OPERATIONS;
+ data_size -= CC310_MAX_LENGTH_DMA_AES_OPERATIONS;
+ }
+ else
+ {
+ size = data_size;
+ data_size = 0;
+ }
+
+ cc310_backend_enable();
+
+ if (p_ctx->any.backend.operation == NRF_CRYPTO_MAC_CALCULATE)
+ {
+ result = SaSi_AesBlock(&p_ctx->any.context,
+ p_data_in + offset,
+ size,
+ p_data_out);
+ }
+ else
+ {
+ result = SaSi_AesBlock(&p_ctx->any.context,
+ p_data_in + offset,
+ size,
+ p_data_out + offset);
+ }
+
+ cc310_backend_disable();
+
+ offset += size;
+ ret_val = result_get(result);
+
+ } while ((data_size > 0) && (ret_val == NRF_SUCCESS));
+
+exit:
+ cc310_backend_mutex_unlock();
+ return ret_val;
+}
+
+static ret_code_t backend_cc310_finalize(void * const p_context,
+ uint8_t * p_data_in,
+ size_t data_size,
+ uint8_t * p_data_out,
+ size_t * p_data_out_size)
+{
+ SaSiError_t result;
+ ret_code_t ret_val;
+ bool mutex_locked;
+ size_t size;
+ size_t offset = 0;
+
+ nrf_crypto_backend_cc310_aes_context_t * p_ctx =
+ (nrf_crypto_backend_cc310_aes_context_t *)p_context;
+
+ mutex_locked = cc310_backend_mutex_trylock();
+ VERIFY_TRUE(mutex_locked, NRF_ERROR_CRYPTO_BUSY);
+
+ if (*p_data_out_size < data_size)
+ {
+ ret_val = NRF_ERROR_CRYPTO_OUTPUT_LENGTH;
+ goto exit;
+ }
+
+ /* This function does not support padding */
+ if (((data_size & 0xF) != 0) &&
+ (p_ctx->any.header.p_info->mode != NRF_CRYPTO_AES_MODE_CTR))
+ {
+ ret_val = NRF_ERROR_CRYPTO_INPUT_LENGTH;
+ goto exit;
+ }
+
+ if (!nrfx_is_in_ram(p_data_in) || !nrfx_is_in_ram(p_data_out))
+ {
+ ret_val = NRF_ERROR_CRYPTO_INPUT_LOCATION;
+ goto exit;
+ }
+
+ /* CC310 allows only 64kB blocks, operation must be devided */
+ while (data_size > CC310_MAX_LENGTH_DMA_AES_OPERATIONS)
+ {
+ size = CC310_MAX_LENGTH_DMA_AES_OPERATIONS;
+ data_size -= CC310_MAX_LENGTH_DMA_AES_OPERATIONS;
+
+ cc310_backend_enable();
+
+ result = SaSi_AesBlock(&p_ctx->any.context,
+ p_data_in + offset,
+ size,
+ p_data_out + offset);
+
+ cc310_backend_disable();
+
+ offset += size;
+ ret_val = result_get(result);
+
+ if (ret_val != NRF_SUCCESS)
+ {
+ goto exit;
+ }
+ }
+
+ /* Calculate space in the output buffer */
+ *p_data_out_size -= offset;
+
+ cc310_backend_enable();
+
+ result = SaSi_AesFinish(&p_ctx->any.context,
+ data_size,
+ p_data_in + offset,
+ data_size,
+ p_data_out + offset,
+ p_data_out_size);
+
+ cc310_backend_disable();
+
+ ret_val = result_get(result);
+
+ if (ret_val == NRF_SUCCESS)
+ {
+ /* update information about size of encrypted data */
+ *p_data_out_size += offset;
+ }
+
+ /* Store IV value in case it will be needed after finalize operation */
+ if ((p_ctx->any.header.p_info->mode == NRF_CRYPTO_AES_MODE_CBC) ||
+ (p_ctx->any.header.p_info->mode == NRF_CRYPTO_AES_MODE_CTR))
+ {
+ result = SaSi_AesGetIv(&p_ctx->any.context, &p_ctx->any.backend.iv[0]);
+ ret_val = result_get(result);
+ }
+
+exit:
+ cc310_backend_mutex_unlock();
+ return ret_val;
+}
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_CC310_AES_CMAC) || \
+ NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_CC310_AES_CBC_MAC)
+static ret_code_t backend_cc310_mac_finalize(void * const p_context,
+ uint8_t * p_data_in,
+ size_t data_size,
+ uint8_t * p_data_out,
+ size_t * p_data_out_size)
+{
+ SaSiError_t result;
+ ret_code_t ret_val;
+ bool mutex_locked;
+ size_t size;
+ size_t offset = 0;
+
+ nrf_crypto_backend_cc310_aes_context_t * p_ctx =
+ (nrf_crypto_backend_cc310_aes_context_t *)p_context;
+
+ mutex_locked = cc310_backend_mutex_trylock();
+ VERIFY_TRUE(mutex_locked, NRF_ERROR_CRYPTO_BUSY);
+
+ if (*p_data_out_size < NRF_CRYPTO_AES_BLOCK_SIZE)
+ {
+ ret_val = NRF_ERROR_CRYPTO_OUTPUT_LENGTH;
+ goto exit;
+ }
+
+ if (!nrfx_is_in_ram(p_data_in) || !nrfx_is_in_ram(p_data_out))
+ {
+ ret_val = NRF_ERROR_CRYPTO_INPUT_LOCATION;
+ goto exit;
+ }
+
+ /* This function does not support padding for CBC-MAC */
+ if (((data_size & 0xF) != 0) &&
+ (NRF_CRYPTO_AES_MODE_CBC_MAC == p_ctx->any.header.p_info->mode))
+ {
+ ret_val = NRF_ERROR_CRYPTO_INPUT_LENGTH;
+ goto exit;
+ }
+
+ /* CC310 allows only 64kB blocks, operation must be devided */
+ while (data_size > CC310_MAX_LENGTH_DMA_AES_OPERATIONS)
+ {
+ size = CC310_MAX_LENGTH_DMA_AES_OPERATIONS;
+ data_size -= CC310_MAX_LENGTH_DMA_AES_OPERATIONS;
+
+ cc310_backend_enable();
+
+ result = SaSi_AesBlock(&p_ctx->any.context,
+ p_data_in + offset,
+ size,
+ p_data_out);
+
+ cc310_backend_disable();
+
+ offset += size;
+ ret_val = result_get(result);
+
+ if (ret_val != NRF_SUCCESS)
+ {
+ goto exit;
+ }
+ }
+
+ cc310_backend_enable();
+
+ result = SaSi_AesFinish(&p_ctx->any.context,
+ data_size,
+ p_data_in + offset,
+ data_size,
+ p_data_out,
+ p_data_out_size);
+
+ cc310_backend_disable();
+
+ ret_val = result_get(result);
+
+ if (ret_val == NRF_SUCCESS)
+ {
+ /* update information about size of encrypted data */
+ *p_data_out_size = NRF_CRYPTO_AES_BLOCK_SIZE;
+ }
+
+ /* Store IV value in case it will be needed after finalize operation */
+ if (p_ctx->any.header.p_info->mode == NRF_CRYPTO_AES_MODE_CBC_MAC_PAD_PCKS7)
+ {
+ result = SaSi_AesGetIv(&p_ctx->any.context, &p_ctx->any.backend.iv[0]);
+ ret_val = result_get(result);
+ }
+
+exit:
+ cc310_backend_mutex_unlock();
+ return ret_val;
+}
+#endif
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_CC310_AES_CBC_MAC)
+static ret_code_t backend_cc310_cbc_mac_padding_finalize(void * const p_context,
+ uint8_t * p_data_in,
+ size_t data_size,
+ uint8_t * p_data_out,
+ size_t * p_data_out_size)
+{
+ ret_code_t ret_val;
+ uint8_t padding_buffer[NRF_CRYPTO_AES_BLOCK_SIZE] = {0};
+ uint8_t msg_ending = (uint8_t)(data_size & (size_t)0x0F);
+
+ if (*p_data_out_size < NRF_CRYPTO_AES_BLOCK_SIZE)
+ {
+ /* output buffer too small */
+ return NRF_ERROR_CRYPTO_OUTPUT_LENGTH;
+ }
+
+ data_size -= msg_ending;
+
+ if (data_size > 0)
+ {
+ ret_val = backend_cc310_update(p_context,
+ p_data_in,
+ data_size,
+ p_data_out);
+ VERIFY_SUCCESS(ret_val);
+ }
+
+ ret_val = padding_pkcs7_add(&padding_buffer[0],
+ p_data_in + data_size,
+ msg_ending);
+ VERIFY_SUCCESS(ret_val);
+
+ ret_val = backend_cc310_mac_finalize(p_context,
+ &padding_buffer[0],
+ NRF_CRYPTO_AES_BLOCK_SIZE,
+ p_data_out,
+ p_data_out_size);
+ VERIFY_SUCCESS(ret_val);
+
+ return ret_val;
+}
+#endif
+
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_CC310_AES_CBC) || \
+ NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_CC310_AES_ECB)
+static ret_code_t backend_cc310_padding_finalize(void * const p_context,
+ uint8_t * p_data_in,
+ size_t data_size,
+ uint8_t * p_data_out,
+ size_t * p_data_out_size)
+{
+ SaSiError_t result;
+ ret_code_t ret_val;
+ uint8_t padding_buffer[NRF_CRYPTO_AES_BLOCK_SIZE] = {0};
+ uint8_t msg_ending = (uint8_t)(data_size & (size_t)0x0F);
+ size_t buff_out_size;
+
+ nrf_crypto_backend_cc310_aes_context_t * p_ctx =
+ (nrf_crypto_backend_cc310_aes_context_t *)p_context;
+
+ if (p_ctx->any.backend.operation == NRF_CRYPTO_DECRYPT)
+ {
+ ret_val = backend_cc310_finalize(p_context,
+ p_data_in,
+ data_size,
+ p_data_out,
+ p_data_out_size);
+ VERIFY_SUCCESS(ret_val);
+
+
+ ret_val = padding_pkcs7_remove(p_data_out,
+ p_data_out_size);
+ return ret_val;
+ }
+
+ /* -------------- ENCRYPTION --------------*/
+ data_size -= msg_ending;
+
+ if (*p_data_out_size < (data_size + NRF_CRYPTO_AES_BLOCK_SIZE))
+ {
+ /* no space for padding */
+ return NRF_ERROR_CRYPTO_OUTPUT_LENGTH;
+ }
+
+ if (data_size > 0)
+ {
+ ret_val = backend_cc310_update(p_context,
+ p_data_in,
+ data_size,
+ p_data_out);
+ VERIFY_SUCCESS(ret_val);
+ }
+
+ ret_val = padding_pkcs7_add(&padding_buffer[0],
+ p_data_in + data_size,
+ msg_ending);
+ VERIFY_SUCCESS(ret_val);
+
+ buff_out_size = *p_data_out_size - data_size;
+
+ ret_val = backend_cc310_finalize(p_context,
+ &padding_buffer[0],
+ NRF_CRYPTO_AES_BLOCK_SIZE,
+ p_data_out + data_size,
+ &buff_out_size);
+ VERIFY_SUCCESS(ret_val);
+
+ *p_data_out_size = buff_out_size + data_size;
+
+ /* Store IV value in case it will be needed after finalize operation */
+ if (p_ctx->any.header.p_info->mode == NRF_CRYPTO_AES_MODE_CBC_PAD_PCKS7)
+ {
+ result = SaSi_AesGetIv(&p_ctx->any.context, &p_ctx->any.backend.iv[0]);
+ ret_val = result_get(result);
+ }
+
+ return ret_val;
+}
+#endif
+
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_CC310_AES_CBC)
+nrf_crypto_aes_info_t const g_nrf_crypto_aes_cbc_128_info =
+{
+ .mode = NRF_CRYPTO_AES_MODE_CBC,
+ .key_size = NRF_CRYPTO_KEY_SIZE_128,
+ .context_size = sizeof(nrf_crypto_backend_aes_cbc_context_t),
+
+ .init_fn = backend_cc310_init,
+ .uninit_fn = backend_cc310_uninit,
+ .key_set_fn = backend_cc310_key_set,
+ .iv_set_fn = backend_cc310_iv_set,
+ .iv_get_fn = backend_cc310_iv_get,
+ .update_fn = backend_cc310_update,
+ .finalize_fn = backend_cc310_finalize
+};
+
+nrf_crypto_aes_info_t const g_nrf_crypto_aes_cbc_128_pad_pkcs7_info =
+{
+ .mode = NRF_CRYPTO_AES_MODE_CBC_PAD_PCKS7,
+ .key_size = NRF_CRYPTO_KEY_SIZE_128,
+ .context_size = sizeof(nrf_crypto_backend_aes_cbc_context_t),
+
+ .init_fn = backend_cc310_init,
+ .uninit_fn = backend_cc310_uninit,
+ .key_set_fn = backend_cc310_key_set,
+ .iv_set_fn = backend_cc310_iv_set,
+ .iv_get_fn = backend_cc310_iv_get,
+ .update_fn = backend_cc310_update,
+ .finalize_fn = backend_cc310_padding_finalize
+};
+#endif
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_CC310_AES_CTR)
+nrf_crypto_aes_info_t const g_nrf_crypto_aes_ctr_128_info =
+{
+ .mode = NRF_CRYPTO_AES_MODE_CTR,
+ .key_size = NRF_CRYPTO_KEY_SIZE_128,
+ .context_size = sizeof(nrf_crypto_backend_aes_ctr_context_t),
+
+ .init_fn = backend_cc310_init,
+ .uninit_fn = backend_cc310_uninit,
+ .key_set_fn = backend_cc310_key_set,
+ .iv_set_fn = backend_cc310_iv_set,
+ .iv_get_fn = backend_cc310_iv_get,
+ .update_fn = backend_cc310_update,
+ .finalize_fn = backend_cc310_finalize
+};
+#endif
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_CC310_AES_ECB)
+nrf_crypto_aes_info_t const g_nrf_crypto_aes_ecb_128_info =
+{
+ .mode = NRF_CRYPTO_AES_MODE_ECB,
+ .key_size = NRF_CRYPTO_KEY_SIZE_128,
+ .context_size = sizeof(nrf_crypto_backend_aes_ecb_context_t),
+
+ .init_fn = backend_cc310_init,
+ .uninit_fn = backend_cc310_uninit,
+ .key_set_fn = backend_cc310_key_set,
+ .iv_set_fn = NULL,
+ .iv_get_fn = NULL,
+ .update_fn = backend_cc310_update,
+ .finalize_fn = backend_cc310_finalize
+};
+
+nrf_crypto_aes_info_t const g_nrf_crypto_aes_ecb_128_pad_pkcs7_info =
+{
+ .mode = NRF_CRYPTO_AES_MODE_ECB_PAD_PCKS7,
+ .key_size = NRF_CRYPTO_KEY_SIZE_128,
+ .context_size = sizeof(nrf_crypto_backend_aes_ecb_context_t),
+
+ .init_fn = backend_cc310_init,
+ .uninit_fn = backend_cc310_uninit,
+ .key_set_fn = backend_cc310_key_set,
+ .iv_set_fn = NULL,
+ .iv_get_fn = NULL,
+ .update_fn = backend_cc310_update,
+ .finalize_fn = backend_cc310_padding_finalize
+};
+#endif
+
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_CC310_AES_CBC_MAC)
+nrf_crypto_aes_info_t const g_nrf_crypto_aes_cbc_mac_128_info =
+{
+ .mode = NRF_CRYPTO_AES_MODE_CBC_MAC,
+ .key_size = NRF_CRYPTO_KEY_SIZE_128,
+ .context_size = sizeof(nrf_crypto_backend_aes_cbc_mac_context_t),
+
+ .init_fn = backend_cc310_init,
+ .uninit_fn = backend_cc310_uninit,
+ .key_set_fn = backend_cc310_key_set,
+ .iv_set_fn = backend_cc310_iv_set,
+ .iv_get_fn = backend_cc310_iv_get,
+ .update_fn = backend_cc310_update,
+ .finalize_fn = backend_cc310_mac_finalize
+};
+
+nrf_crypto_aes_info_t const g_nrf_crypto_aes_cbc_mac_128_pad_pkcs7_info =
+{
+ .mode = NRF_CRYPTO_AES_MODE_CBC_MAC_PAD_PCKS7,
+ .key_size = NRF_CRYPTO_KEY_SIZE_128,
+ .context_size = sizeof(nrf_crypto_backend_aes_cbc_mac_context_t),
+
+ .init_fn = backend_cc310_init,
+ .uninit_fn = backend_cc310_uninit,
+ .key_set_fn = backend_cc310_key_set,
+ .iv_set_fn = backend_cc310_iv_set,
+ .iv_get_fn = backend_cc310_iv_get,
+ .update_fn = backend_cc310_update,
+ .finalize_fn = backend_cc310_cbc_mac_padding_finalize
+};
+#endif
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_CC310_AES_CMAC)
+nrf_crypto_aes_info_t const g_nrf_crypto_aes_cmac_128_info =
+{
+ .mode = NRF_CRYPTO_AES_MODE_CMAC,
+ .key_size = NRF_CRYPTO_KEY_SIZE_128,
+ .context_size = sizeof(nrf_crypto_backend_aes_cmac_context_t),
+
+ .init_fn = backend_cc310_init,
+ .uninit_fn = backend_cc310_uninit,
+ .key_set_fn = backend_cc310_key_set,
+ .iv_set_fn = NULL,
+ .iv_get_fn = NULL,
+ .update_fn = backend_cc310_update,
+ .finalize_fn = backend_cc310_mac_finalize
+};
+#endif
+
+#endif // NRF_MODULE_ENABLED(NRF_CRYPTO_AES_BACKEND_CC310)
+#endif // NRF_MODULE_ENABLED(NRF_CRYPTO)
+
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/cc310/cc310_backend_aes.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/cc310/cc310_backend_aes.h
new file mode 100644
index 0000000..e7127a3
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/cc310/cc310_backend_aes.h
@@ -0,0 +1,187 @@
+/**
+ * Copyright (c) 2018 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+
+#ifndef CC310_BACKEND_AES_H__
+#define CC310_BACKEND_AES_H__
+
+/** @file
+ *
+ * @defgroup nrf_crypto_cc310_backend_aes nrf_crypto CC310 backend AES
+ * @{
+ * @ingroup nrf_crypto_cc310_backend
+ *
+ * @brief AES functionality provided by the nrf_crypto CC310 backend.
+ */
+
+#include "sdk_config.h"
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_CC310) || defined(__SDK_DOXYGEN__)
+
+#include "ssi_aes.h"
+#include "nrf_crypto_error.h"
+#include "nrf_crypto_types.h"
+#include "nrf_crypto_aes_shared.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+/* AES CBC */
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_CC310_AES_CBC)
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_AES_CBC)
+#error "Duplicate definition of AES CBC mode. More than one backend enabled");
+#endif
+#define NRF_CRYPTO_AES_CBC_ENABLED 1
+#undef NRF_CRYPTO_AES_ENABLED
+#define NRF_CRYPTO_AES_ENABLED 1 // Flag that nrf_crypto_aes frontend can be compiled
+#undef NRF_CRYPTO_CC310_AES_ENABLED
+#define NRF_CRYPTO_CC310_AES_ENABLED 1
+
+/* define for test purposes */
+#define NRF_CRYPTO_AES_CBC_128_ENABLED 1
+
+typedef struct
+{
+ nrf_crypto_aes_internal_context_t header; /**< Common header for context. */
+ SaSiAesUserContext_t context; /**< AES context internal to CC310. */
+ nrf_crypto_backend_aes_ctx_t backend;
+} nrf_crypto_backend_aes_cbc_context_t;
+#endif
+
+/* AES CTR */
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_CC310_AES_CTR)
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_AES_CTR)
+#error "Duplicate definition of AES CTR mode. More than one backend enabled");
+#endif
+#define NRF_CRYPTO_AES_CTR_ENABLED 1
+#undef NRF_CRYPTO_AES_ENABLED
+#define NRF_CRYPTO_AES_ENABLED 1 // Flag that nrf_crypto_aes frontend can be compiled
+#undef NRF_CRYPTO_CC310_AES_ENABLED
+#define NRF_CRYPTO_CC310_AES_ENABLED 1
+
+/* define for test purposes */
+#define NRF_CRYPTO_AES_CTR_128_ENABLED 1
+
+typedef struct
+{
+ nrf_crypto_aes_internal_context_t header; /**< Common header for context. */
+ SaSiAesUserContext_t context; /**< AES context internal to CC310. */
+ nrf_crypto_backend_aes_ctx_t backend;
+} nrf_crypto_backend_aes_ctr_context_t;
+#endif
+
+/* AES ECB */
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_CC310_AES_ECB)
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_AES_ECB)
+#error "Duplicate definition of AES ECB mode. More than one backend enabled");
+#endif
+#define NRF_CRYPTO_AES_ECB_ENABLED 1
+#undef NRF_CRYPTO_AES_ENABLED
+#define NRF_CRYPTO_AES_ENABLED 1 // Flag that nrf_crypto_aes frontend can be compiled
+#undef NRF_CRYPTO_CC310_AES_ENABLED
+#define NRF_CRYPTO_CC310_AES_ENABLED 1
+
+/* define for test purposes */
+#define NRF_CRYPTO_AES_ECB_128_ENABLED 1
+
+typedef struct
+{
+ nrf_crypto_aes_internal_context_t header; /**< Common header for context. */
+ SaSiAesUserContext_t context; /**< AES context internal to CC310. */
+ nrf_crypto_backend_no_iv_aes_ctx_t backend;
+} nrf_crypto_backend_aes_ecb_context_t;
+#endif
+
+
+/* AES CBC_MAC */
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_CC310_AES_CBC_MAC)
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_AES_CBC_MAC)
+#error "Duplicate definition of AES CBC_MAC mode. More than one backend enabled");
+#endif
+#define NRF_CRYPTO_AES_CBC_MAC_ENABLED 1
+#undef NRF_CRYPTO_AES_ENABLED
+#define NRF_CRYPTO_AES_ENABLED 1 // Flag that nrf_crypto_aes frontend can be compiled
+#undef NRF_CRYPTO_CC310_AES_ENABLED
+#define NRF_CRYPTO_CC310_AES_ENABLED 1
+
+/* define for test purposes */
+#define NRF_CRYPTO_AES_CBC_MAC_128_ENABLED 1
+
+typedef struct
+{
+ nrf_crypto_aes_internal_context_t header; /**< Common header for context. */
+ SaSiAesUserContext_t context; /**< AES context internal to CC310. */
+ nrf_crypto_backend_aes_ctx_t backend;
+} nrf_crypto_backend_aes_cbc_mac_context_t;
+#endif
+
+/* AES CMAC */
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_CC310_AES_CMAC)
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_AES_CMAC)
+#error "Duplicate definition of AES CMAC mode. More than one backend enabled");
+#endif
+#define NRF_CRYPTO_AES_CMAC_ENABLED 1
+#undef NRF_CRYPTO_AES_ENABLED
+#define NRF_CRYPTO_AES_ENABLED 1 // Flag that nrf_crypto_aes frontend can be compiled
+#undef NRF_CRYPTO_CC310_AES_ENABLED
+#define NRF_CRYPTO_CC310_AES_ENABLED 1
+
+/* define for test purposes */
+#define NRF_CRYPTO_AES_CMAC_128_ENABLED 1
+
+typedef struct
+{
+ nrf_crypto_aes_internal_context_t header; /**< Common header for context. */
+ SaSiAesUserContext_t context; /**< AES context internal to CC310. */
+ nrf_crypto_backend_no_iv_aes_ctx_t backend;
+} nrf_crypto_backend_aes_cmac_context_t;
+
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_CC310)
+
+/** @} */
+
+#endif // CC310_BACKEND_AES_H__
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/cc310/cc310_backend_aes_aead.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/cc310/cc310_backend_aes_aead.c
new file mode 100644
index 0000000..e8e312e
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/cc310/cc310_backend_aes_aead.c
@@ -0,0 +1,366 @@
+/**
+ * Copyright (c) 2018 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+
+#include "sdk_common.h"
+#include <drivers/nrfx_common.h>
+#if NRF_MODULE_ENABLED(NRF_CRYPTO)
+
+#include <stdbool.h>
+#include "crys_aesccm_error.h"
+#include "cc310_backend_aes_aead.h"
+#include "cc310_backend_mutex.h"
+#include "cc310_backend_shared.h"
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_CC310_AES_AEAD)
+
+/**@internal @brief Type declaration of a template suiting all possible context sizes
+ * for this backend.
+ */
+typedef struct
+{
+ nrf_crypto_aead_internal_context_t header; /**< Common header for context. */
+ CRYS_AESCCM_UserContext_t context;
+ uint8_t key[16]; /**< Only supported key size by CC310 is 128 bit */
+} nrf_crypto_backend_cc310_aes_aead_context_t;
+
+static ret_code_t result_get(CRYSError_t error)
+{
+ ret_code_t ret_val;
+
+ switch (error)
+ {
+ case CRYS_OK:
+ ret_val = NRF_SUCCESS;
+ break;
+
+ case CRYS_AESCCM_INVALID_USER_CONTEXT_POINTER_ERROR:
+ ret_val = NRF_ERROR_CRYPTO_CONTEXT_NULL;
+ break;
+
+ case CRYS_AESCCM_ILLEGAL_KEY_SIZE_ERROR:
+ ret_val = NRF_ERROR_CRYPTO_KEY_SIZE;
+ break;
+
+ case CRYS_AESCCM_ILLEGAL_TAG_SIZE_ERROR:
+ ret_val = NRF_ERROR_CRYPTO_AEAD_MAC_SIZE;
+ break;
+
+ case CRYS_AESCCM_ILLEGAL_NONCE_SIZE_ERROR:
+ ret_val = NRF_ERROR_CRYPTO_AEAD_NONCE_SIZE;
+ break;
+
+ case CRYS_AESCCM_ILLEGAL_PARAMETER_SIZE_ERROR:
+ case CRYS_AESCCM_DATA_IN_SIZE_ILLEGAL:
+ ret_val = NRF_ERROR_CRYPTO_INPUT_LENGTH;
+ break;
+
+ case CRYS_AESCCM_INVALID_KEY_POINTER_ERROR:
+ case CRYS_AESCCM_ILLEGAL_PARAMETER_PTR_ERROR:
+ case CRYS_AESCCM_DATA_IN_POINTER_INVALID_ERROR:
+ ret_val = NRF_ERROR_CRYPTO_INPUT_NULL;
+ break;
+
+ case CRYS_AESCCM_IS_NOT_SUPPORTED:
+ case CRYS_AESCCM_INVALID_ENCRYPT_MODE_ERROR:
+ ret_val = NRF_ERROR_CRYPTO_FEATURE_UNAVAILABLE;
+ break;
+
+ case CRYS_AESCCM_DATA_OUT_SIZE_INVALID_ERROR:
+ ret_val = NRF_ERROR_CRYPTO_OUTPUT_LENGTH;
+ break;
+
+ case CRYS_AESCCM_DATA_OUT_POINTER_INVALID_ERROR:
+ ret_val = NRF_ERROR_CRYPTO_OUTPUT_NULL;
+ break;
+
+ case CRYS_AESCCM_ILLEGAL_PARAMETER_ERROR:
+ ret_val = NRF_ERROR_CRYPTO_INVALID_PARAM;
+ break;
+
+ case CRYS_AESCCM_CCM_MAC_INVALID_ERROR:
+ ret_val = NRF_ERROR_CRYPTO_AEAD_INVALID_MAC;
+ break;
+
+ case CRYS_AESCCM_CTX_SIZES_ERROR:
+ default:
+ ret_val = NRF_ERROR_CRYPTO_INTERNAL;
+ break;
+ }
+ return ret_val;
+}
+
+static ret_code_t backend_cc310_init(void * const p_context, uint8_t * p_key)
+{
+ ret_code_t ret_val;
+
+ nrf_crypto_backend_cc310_aes_aead_context_t * p_ctx =
+ (nrf_crypto_backend_cc310_aes_aead_context_t *)p_context;
+
+ if (!nrfx_is_in_ram(p_ctx))
+ {
+ return NRF_ERROR_CRYPTO_INPUT_LOCATION;
+ }
+ if (p_ctx->header.p_info->key_size != NRF_CRYPTO_KEY_SIZE_128)
+ {
+ return NRF_ERROR_CRYPTO_KEY_SIZE;
+ }
+
+ switch (p_ctx->header.p_info->mode)
+ {
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_CC310_AES_CCM)
+ case NRF_CRYPTO_AEAD_MODE_AES_CCM:
+ ret_val = NRF_SUCCESS;
+ break;
+#endif
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_CC310_AES_CCM_STAR)
+ case NRF_CRYPTO_AEAD_MODE_AES_CCM_STAR:
+ ret_val = NRF_SUCCESS;
+ break;
+#endif
+
+ default:
+ return NRF_ERROR_CRYPTO_FEATURE_UNAVAILABLE;
+ }
+
+ memcpy(p_ctx->key, p_key, sizeof(p_ctx->key));
+
+ return ret_val;
+}
+
+static ret_code_t backend_cc310_uninit(void * const p_context)
+{
+ nrf_crypto_backend_cc310_aes_aead_context_t * p_ctx =
+ (nrf_crypto_backend_cc310_aes_aead_context_t *)p_context;
+
+ memset(&p_ctx->context, 0, sizeof(CRYS_AESCCM_UserContext_t));
+
+ return NRF_SUCCESS;
+}
+
+static ret_code_t backend_cc310_crypt(void * const p_context,
+ nrf_crypto_operation_t operation,
+ uint8_t * p_nonce,
+ uint8_t nonce_size,
+ uint8_t * p_adata,
+ size_t adata_size,
+ uint8_t * p_data_in,
+ size_t data_in_size,
+ uint8_t * p_data_out,
+ uint8_t * p_mac,
+ uint8_t mac_size)
+
+{
+ uint32_t mode;
+ CRYSError_t result;
+ ret_code_t ret_val;
+ bool mutex_locked;
+
+ SaSiAesEncryptMode_t operation_cc310;
+ CRYS_AESCCM_Mac_Res_t mac_buffer;
+
+ nrf_crypto_backend_cc310_aes_aead_context_t * p_ctx =
+ (nrf_crypto_backend_cc310_aes_aead_context_t *)p_context;
+
+ mutex_locked = cc310_backend_mutex_trylock();
+ VERIFY_TRUE(mutex_locked, NRF_ERROR_CRYPTO_BUSY);
+
+ if (!nrfx_is_in_ram(p_adata) && (adata_size > 0))
+ {
+ ret_val = NRF_ERROR_CRYPTO_INPUT_LOCATION;
+ goto exit;
+ }
+
+ /* CC310 supports: CCM & CCM*, where nonce_size must be > 0, so p_nonce must always
+ point to RAM. */
+ if (!nrfx_is_in_ram(p_nonce) ||
+ !nrfx_is_in_ram(p_data_in) ||
+ !nrfx_is_in_ram(p_data_out) ||
+ !nrfx_is_in_ram(p_mac))
+ {
+ ret_val = NRF_ERROR_CRYPTO_INPUT_LOCATION;
+ goto exit;
+ }
+
+ if (operation == NRF_CRYPTO_DECRYPT)
+ {
+ operation_cc310 = SASI_AES_DECRYPT;
+ }
+ else if (operation == NRF_CRYPTO_ENCRYPT)
+ {
+ operation_cc310 = SASI_AES_ENCRYPT;
+ }
+ else
+ {
+ ret_val = NRF_ERROR_CRYPTO_INVALID_PARAM;
+ goto exit;
+ }
+
+ if (p_ctx->header.p_info->mode == NRF_CRYPTO_AEAD_MODE_AES_CCM)
+ {
+ mode = CRYS_AESCCM_MODE_CCM;
+
+ /* Allowed MAC size in CCM mode: [4, 6, 8, 10, 12, 14, 16] */
+ if ((mac_size < NRF_CRYPTO_AES_CCM_MAC_MIN) ||
+ (mac_size > NRF_CRYPTO_AES_CCM_MAC_MAX) ||
+ ((mac_size & 0x01) != 0))
+ {
+ ret_val = NRF_ERROR_CRYPTO_AEAD_MAC_SIZE;
+ goto exit;
+ }
+
+ if ((nonce_size < NRF_CRYPTO_AES_CCM_NONCE_SIZE_MIN) ||
+ (nonce_size > NRF_CRYPTO_AES_CCM_NONCE_SIZE_MAX))
+ {
+ ret_val = NRF_ERROR_CRYPTO_AEAD_NONCE_SIZE;
+ goto exit;
+ }
+ }
+ else
+ {
+ mode = CRYS_AESCCM_MODE_STAR;
+
+ /* Allowed MAC size in CCM* mode: [0, 4, 8, 16] */
+ if ((mac_size | NRF_CRYPTO_AES_CCM_STAR_MAC_BITMASK) != NRF_CRYPTO_AES_CCM_STAR_MAC_BITMASK)
+ {
+ ret_val = NRF_ERROR_CRYPTO_AEAD_MAC_SIZE;
+ goto exit;
+ }
+
+ /* Allowed nonce size in CCM* mode: [13] */
+ if (nonce_size != NRF_CRYPTO_AES_CCM_STAR_NONCE_SIZE)
+ {
+ ret_val = NRF_ERROR_CRYPTO_AEAD_NONCE_SIZE;
+ goto exit;
+ }
+ }
+
+ cc310_backend_enable();
+
+ result = CC_AESCCM_Init(&p_ctx->context,
+ operation_cc310,
+ p_ctx->key,
+ CRYS_AES_Key128BitSize, // the only allowed key size for CC310
+ (uint32_t)adata_size,
+ (uint32_t)data_in_size,
+ p_nonce,
+ nonce_size,
+ mac_size,
+ mode);
+
+ cc310_backend_disable();
+
+ ret_val = result_get(result);
+
+ if (ret_val != NRF_SUCCESS)
+ {
+ goto exit;
+ }
+
+ if ((adata_size > 0) && (p_adata != NULL))
+ {
+ cc310_backend_enable();
+
+ result = CRYS_AESCCM_BlockAdata(&p_ctx->context,
+ p_adata,
+ (uint32_t)adata_size);
+
+ cc310_backend_disable();
+
+ ret_val = result_get(result);
+
+ if (ret_val != NRF_SUCCESS)
+ {
+ goto exit;
+ }
+ }
+
+ /* CC310 backend always needs 16 bytes buffer for MAC calculation. */
+ memcpy(mac_buffer, p_mac, mac_size);
+
+ cc310_backend_enable();
+
+ result = CRYS_AESCCM_Finish(&p_ctx->context,
+ p_data_in,
+ (uint32_t)data_in_size,
+ p_data_out,
+ mac_buffer,
+ &mac_size);
+
+ cc310_backend_disable();
+
+ ret_val = result_get(result);
+ if (ret_val == NRF_SUCCESS)
+ {
+ memcpy(p_mac, mac_buffer, mac_size);
+ }
+
+exit:
+ cc310_backend_mutex_unlock();
+ return ret_val;
+}
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_CC310_AES_CCM)
+nrf_crypto_aead_info_t const g_nrf_crypto_aes_ccm_128_info =
+{
+ .key_size = NRF_CRYPTO_KEY_SIZE_128,
+ .mode = NRF_CRYPTO_AEAD_MODE_AES_CCM,
+
+ .init_fn = backend_cc310_init,
+ .uninit_fn = backend_cc310_uninit,
+ .crypt_fn = backend_cc310_crypt
+};
+#endif
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_CC310_AES_CCM_STAR)
+nrf_crypto_aead_info_t const g_nrf_crypto_aes_ccm_star_128_info =
+{
+ .key_size = NRF_CRYPTO_KEY_SIZE_128,
+ .mode = NRF_CRYPTO_AEAD_MODE_AES_CCM_STAR,
+
+ .init_fn = backend_cc310_init,
+ .uninit_fn = backend_cc310_uninit,
+ .crypt_fn = backend_cc310_crypt
+};
+#endif
+
+#endif // NRF_MODULE_ENABLED(NRF_CRYPTO_CC310_AES_AEAD)
+#endif // NRF_MODULE_ENABLED(NRF_CRYPTO)
+
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/cc310/cc310_backend_aes_aead.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/cc310/cc310_backend_aes_aead.h
new file mode 100644
index 0000000..34622d9
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/cc310/cc310_backend_aes_aead.h
@@ -0,0 +1,124 @@
+/**
+ * Copyright (c) 2018 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+
+#ifndef CC310_BACKEND_AES_AEAD_H__
+#define CC310_BACKEND_AES_AEAD_H__
+
+/** @file
+ *
+ * @defgroup nrf_crypto_cc310_backend_aes_aead nrf_crypto CC310 backend AES AEAD
+ * @{
+ * @ingroup nrf_crypto_cc310_backend
+ *
+ * @brief AES AEAD functionality provided by the nrf_crypto CC310 backend.
+ */
+
+#include "sdk_config.h"
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_CC310)
+
+#include "crys_aesccm.h"
+#include "nrf_crypto_error.h"
+#include "nrf_crypto_types.h"
+#include "nrf_crypto_aead_shared.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define NRF_CRYPTO_CC310_AES_BACKEND_KEY_SIZE (16)
+
+
+/* AES CCM */
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_CC310_AES_CCM)
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_AES_CCM)
+#error "Duplicate definition of AES CCM mode. More than one backend enabled");
+#endif
+#define NRF_CRYPTO_AES_CCM_ENABLED 1
+#undef NRF_CRYPTO_AEAD_ENABLED
+#define NRF_CRYPTO_AEAD_ENABLED 1 // Flag that nrf_crypto_aead frontend can be compiled
+#undef NRF_CRYPTO_CC310_AES_AEAD_ENABLED
+#define NRF_CRYPTO_CC310_AES_AEAD_ENABLED 1 // aead backend for cc310 can be compiled
+
+/* define for test purposes */
+#define NRF_CRYPTO_AES_CCM_128_ENABLED 1
+
+typedef struct
+{
+ nrf_crypto_aead_internal_context_t header; /**< Common header for context. */
+ CRYS_AESCCM_UserContext_t context; /**< AES CCM context internal to CC310. */
+
+ uint8_t key[NRF_CRYPTO_CC310_AES_BACKEND_KEY_SIZE];
+} nrf_crypto_backend_aes_ccm_context_t;
+#endif
+
+/* AES CCM* (CCM STAR) */
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_CC310_AES_CCM_STAR)
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_AES_CCM_STAR)
+#error "Duplicate definition of AES CCM* (star) mode. More than one backend enabled");
+#endif
+#define NRF_CRYPTO_AES_CCM_STAR_ENABLED 1
+#undef NRF_CRYPTO_AEAD_ENABLED
+#define NRF_CRYPTO_AEAD_ENABLED 1 // Flag that nrf_crypto_aes_aead frontend can be compiled
+#undef NRF_CRYPTO_CC310_AES_AEAD_ENABLED
+#define NRF_CRYPTO_CC310_AES_AEAD_ENABLED 1 // aead backend for cc310 can be compiled
+
+/* define for test purposes */
+#define NRF_CRYPTO_AES_CCM_STAR_128_ENABLED 1
+
+typedef struct
+{
+ nrf_crypto_aead_internal_context_t header; /**< Common header for context. */
+ CRYS_AESCCM_UserContext_t context; /**< AES CCM context internal to CC310. */
+
+ uint8_t key[NRF_CRYPTO_CC310_AES_BACKEND_KEY_SIZE];
+} nrf_crypto_backend_aes_ccm_star_context_t;
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_CC310)
+
+/** @} */
+
+#endif // CC310_BACKEND_AES_AEAD_H__
+
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/cc310/cc310_backend_chacha_poly_aead.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/cc310/cc310_backend_chacha_poly_aead.c
new file mode 100644
index 0000000..16ca026
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/cc310/cc310_backend_chacha_poly_aead.c
@@ -0,0 +1,214 @@
+/**
+ * Copyright (c) 2018 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+
+#include "sdk_common.h"
+#if NRF_MODULE_ENABLED(NRF_CRYPTO)
+
+#include <drivers/nrfx_common.h>
+#include <stdbool.h>
+#include "cc310_backend_mutex.h"
+#include "crys_chacha_poly_error.h"
+#include "cc310_backend_chacha_poly_aead.h"
+#include "cc310_backend_shared.h"
+#include "cc310_backend_shared.h"
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_CC310_CHACHA_POLY_AEAD)
+
+static ret_code_t result_get(CRYSError_t error)
+{
+ ret_code_t ret_val;
+
+ switch (error)
+ {
+ case CRYS_OK:
+ ret_val = NRF_SUCCESS;
+ break;
+
+ /*! Invalid Additional data. */
+ case CRYS_CHACHA_POLY_DATA_INVALID_ERROR:
+ case CRYS_CHACHA_POLY_ADATA_INVALID_ERROR:
+ ret_val = NRF_ERROR_CRYPTO_INPUT_NULL;
+ break;
+
+ /*! Illegal encryption mode. */
+ case CRYS_CHACHA_POLY_ENC_MODE_INVALID_ERROR:
+ ret_val = NRF_ERROR_CRYPTO_INVALID_PARAM;
+ break;
+
+ /*! Illegal data size. */
+ case CRYS_CHACHA_POLY_DATA_SIZE_INVALID_ERROR:
+ ret_val = NRF_ERROR_CRYPTO_INPUT_LENGTH;
+ break;
+
+ /*! MAC comparison error. */
+ case CRYS_CHACHA_POLY_MAC_ERROR:
+ ret_val = NRF_ERROR_CRYPTO_AEAD_INVALID_MAC;
+ break;
+
+ default:
+ ret_val = NRF_ERROR_CRYPTO_INTERNAL;
+ break;
+ }
+ return ret_val;
+}
+
+static ret_code_t backend_cc310_init(void * const p_context, uint8_t * p_key)
+{
+ nrf_crypto_backend_chacha_poly_context_t * p_ctx =
+ (nrf_crypto_backend_chacha_poly_context_t *)p_context;
+
+ if (!nrfx_is_in_ram(p_ctx))
+ {
+ return NRF_ERROR_CRYPTO_INPUT_LOCATION;
+ }
+
+ if (p_ctx->header.p_info->key_size != NRF_CRYPTO_KEY_SIZE_256)
+ {
+ return NRF_ERROR_CRYPTO_KEY_SIZE;
+ }
+
+ memcpy(p_ctx->key, p_key, sizeof(p_ctx->key));
+ return NRF_SUCCESS;
+}
+
+static inline ret_code_t backend_cc310_uninit(void * const p_context)
+{
+ return NRF_SUCCESS;
+}
+
+static ret_code_t backend_cc310_crypt(void * const p_context,
+ nrf_crypto_operation_t operation,
+ uint8_t * p_nonce,
+ uint8_t nonce_size,
+ uint8_t * p_adata,
+ size_t adata_size,
+ uint8_t * p_data_in,
+ size_t data_in_size,
+ uint8_t * p_data_out,
+ uint8_t * p_mac,
+ uint8_t mac_size)
+
+{
+ CRYSError_t result;
+ ret_code_t ret_val;
+ bool mutex_locked;
+
+ CRYS_CHACHA_EncryptMode_t operation_cc310;
+
+ nrf_crypto_backend_chacha_poly_context_t * p_ctx =
+ (nrf_crypto_backend_chacha_poly_context_t *)p_context;
+
+ mutex_locked = cc310_backend_mutex_trylock();
+ VERIFY_TRUE(mutex_locked, NRF_ERROR_CRYPTO_BUSY);
+
+ if ((adata_size == 0) || (data_in_size == 0))
+ {
+ ret_val = NRF_ERROR_CRYPTO_INPUT_LENGTH;
+ goto exit;
+ }
+
+ if (mac_size != NRF_CRYPTO_CHACHA_POLY_MAC_SIZE)
+ {
+ ret_val = NRF_ERROR_CRYPTO_AEAD_MAC_SIZE;
+ goto exit;
+ }
+
+ if (nonce_size != NRF_CRYPTO_CHACHA_POLY_NONCE_SIZE)
+ {
+ ret_val = NRF_ERROR_CRYPTO_AEAD_NONCE_SIZE;
+ goto exit;
+ }
+
+ if (!nrfx_is_in_ram(p_data_in) || !nrfx_is_in_ram(p_data_out) ||
+ !nrfx_is_in_ram(p_mac) || !nrfx_is_in_ram(p_adata) ||
+ !nrfx_is_in_ram(p_nonce))
+ {
+ ret_val = NRF_ERROR_CRYPTO_INPUT_LOCATION;
+ goto exit;
+ }
+
+ if (operation == NRF_CRYPTO_DECRYPT)
+ {
+ operation_cc310 = CRYS_CHACHA_Decrypt;
+ }
+ else if (operation == NRF_CRYPTO_ENCRYPT)
+ {
+ operation_cc310 = CRYS_CHACHA_Encrypt;
+ }
+ else
+ {
+ ret_val = NRF_ERROR_CRYPTO_INVALID_PARAM;
+ goto exit;
+ }
+
+ cc310_backend_enable();
+
+ result = CRYS_CHACHA_POLY(p_nonce,
+ p_ctx->key,
+ operation_cc310,
+ p_adata,
+ adata_size,
+ p_data_in,
+ data_in_size,
+ p_data_out,
+ (uint32_t *)p_mac);
+ cc310_backend_disable();
+
+ ret_val = result_get(result);
+
+exit:
+ cc310_backend_mutex_unlock();
+ return ret_val;
+}
+
+nrf_crypto_aead_info_t const g_nrf_crypto_chacha_poly_256_info =
+{
+ .key_size = NRF_CRYPTO_KEY_SIZE_256,
+ .mode = NRF_CRYPTO_AEAD_MODE_CHACHA_POLY,
+
+ .init_fn = backend_cc310_init,
+ .uninit_fn = backend_cc310_uninit,
+ .crypt_fn = backend_cc310_crypt
+};
+
+
+#endif // NRF_MODULE_ENABLED(NRF_CRYPTO_CC310_CHACHA_POLY_AEAD)
+#endif // NRF_MODULE_ENABLED(NRF_CRYPTO)
+
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/cc310/cc310_backend_chacha_poly_aead.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/cc310/cc310_backend_chacha_poly_aead.h
new file mode 100644
index 0000000..4c1edf9
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/cc310/cc310_backend_chacha_poly_aead.h
@@ -0,0 +1,99 @@
+/**
+ * Copyright (c) 2018 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+
+#ifndef CC310_BACKEND_CHACHA_POLY_AEAD_H__
+#define CC310_BACKEND_CHACHA_POLY_AEAD_H__
+
+/** @file
+ *
+ * @defgroup nrf_crypto_cc310_backend_chacha_poly_aead nrf_crypto CC310 backend CHACHA_POLY AEAD
+ * @{
+ * @ingroup nrf_crypto_cc310_backend
+ *
+ * @brief CHACHA_POLY AEAD functionality provided by the nrf_crypto CC310 backend.
+ */
+
+#include "sdk_config.h"
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_CC310)
+
+#include "crys_chacha_poly.h"
+#include "nrf_crypto_error.h"
+#include "nrf_crypto_types.h"
+#include "nrf_crypto_aead_shared.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define NRF_CRYPTO_CC310_CHACHA_POLY_BACKEND_KEY_SIZE (32)
+
+/* CHACHA-POLY */
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_CC310_CHACHA_POLY)
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_CHACHA_POLY)
+#error "Duplicate definition of CHACHA-POLY mode. More than one backend enabled");
+#endif
+#define NRF_CRYPTO_CHACHA_POLY_ENABLED 1
+#undef NRF_CRYPTO_AEAD_ENABLED
+#define NRF_CRYPTO_AEAD_ENABLED 1 // Flag that nrf_crypto_aead frontend can be compiled
+#undef NRF_CRYPTO_CC310_CHACHA_POLY_AEAD_ENABLED
+#define NRF_CRYPTO_CC310_CHACHA_POLY_AEAD_ENABLED 1 // aead backend for cc310 can be compiled
+
+/* defines for test purposes */
+#define NRF_CRYPTO_CHACHA_POLY_256_ENABLED 1
+
+typedef struct
+{
+ nrf_crypto_aead_internal_context_t header; /**< Common header for context. */
+
+ uint8_t key[NRF_CRYPTO_CC310_CHACHA_POLY_BACKEND_KEY_SIZE];
+} nrf_crypto_backend_chacha_poly_context_t;
+#endif
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_CC310)
+
+/** @} */
+
+#endif // CC310_BACKEND_CHACHA_POLY_AEAD_H__
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/cc310/cc310_backend_ecc.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/cc310/cc310_backend_ecc.c
new file mode 100644
index 0000000..e93230c
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/cc310/cc310_backend_ecc.c
@@ -0,0 +1,464 @@
+/**
+ * Copyright (c) 2018 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+
+#include "sdk_config.h"
+#include "nordic_common.h"
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO) && NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_CC310)
+
+#include <string.h>
+
+#include "nrf_crypto_mem.h"
+#include "nrf_crypto_ecc.h"
+#include "cc310_backend_ecc.h"
+#include "cc310_backend_shared.h"
+#include "cc310_backend_mutex.h"
+#include "crys_ecpki_kg.h"
+#include "crys_ecpki_domain.h"
+#include "crys_ecpki_build.h"
+#include "crys_ecpki_error.h"
+#include "crys_rnd_error.h"
+
+
+#define CC310_UNCOMPRESSED_PUBLIC_KEY_ID_BYTE 0x04 /**< @brief @internal Byte value used by CC310 library to prefix uncompressed public key. */
+
+
+ret_code_t nrf_crypto_backend_cc310_ecc_error_convert(uint32_t crys_error)
+{
+ switch (crys_error)
+ {
+ case CRYS_OK:
+ return NRF_SUCCESS;
+
+ case CRYS_ECDSA_VERIFY_INCONSISTENT_VERIFY_ERROR:
+ return NRF_ERROR_CRYPTO_ECDSA_INVALID_SIGNATURE;
+
+ case CRYS_RND_INSTANTIATION_NOT_DONE_ERROR:
+ return NRF_ERROR_CRYPTO_CONTEXT_NOT_INITIALIZED;
+
+ default:
+ return NRF_ERROR_CRYPTO_INTERNAL;
+ }
+}
+
+
+/** @internal @brief Returns domain value from @ref CRYS_ECPKI_DomainID_t enum based on
+ * value from info structure.
+ *
+ * @param[in] p_info Curve info.
+ * @returns Pointer to CC310 domain.
+ */
+static CRYS_ECPKI_Domain_t const * get_domain(nrf_crypto_ecc_curve_info_t const * p_info)
+{
+ CRYS_ECPKI_DomainID_t domain_id = (CRYS_ECPKI_DomainID_t)(intptr_t)p_info->p_backend_data;
+ const CRYS_ECPKI_Domain_t * domain = CRYS_ECPKI_GetEcDomain(domain_id);
+ return domain;
+}
+
+
+ret_code_t nrf_crypto_backend_cc310_ecc_public_key_convert(
+ nrf_crypto_backend_cc310_ecc_public_key_t * p_pub,
+ CRYS_ECPKI_BUILD_TempData_t * p_temp_data)
+{
+ ret_code_t result;
+ CRYSError_t crys_error;
+ CRYS_ECPKI_Domain_t const * p_domain;
+ uint8_t ucompressed_key[NRF_CRYPTO_ECC_RAW_PUBLIC_KEY_MAX_SIZE + 1];
+ bool mutex_locked;
+
+ nrf_crypto_ecc_curve_info_t const * p_info = p_pub->header.p_info;
+
+ if (p_pub->key_converted)
+ {
+ return NRF_SUCCESS;
+ }
+
+ p_domain = get_domain(p_info);
+
+ // Tell CC310 library that this is raw public key in uncompressed format.
+ ucompressed_key[0] = CC310_UNCOMPRESSED_PUBLIC_KEY_ID_BYTE;
+ memcpy(&ucompressed_key[1], p_pub->key.raw_public_key, p_info->raw_public_key_size);
+
+ mutex_locked = cc310_backend_mutex_trylock();
+ if (!mutex_locked)
+ {
+ return NRF_ERROR_CRYPTO_BUSY;
+ }
+
+ cc310_backend_enable();
+
+ crys_error = CRYS_ECPKI_BuildPublKeyFullCheck(p_domain,
+ ucompressed_key,
+ p_info->raw_public_key_size + 1,
+ &p_pub->key.cc310_public_key,
+ p_temp_data);
+
+ cc310_backend_disable();
+
+ cc310_backend_mutex_unlock();
+
+ result = nrf_crypto_backend_cc310_ecc_error_convert(crys_error);
+ if (result == NRF_SUCCESS)
+ {
+ p_pub->key_converted = true;
+ }
+ else
+ {
+ memcpy(p_pub->key.raw_public_key, &ucompressed_key[1], p_info->raw_public_key_size);
+ }
+
+ return result;
+}
+
+
+ret_code_t nrf_crypto_backend_cc310_key_pair_generate(
+ void * p_context,
+ void * p_private_key,
+ void * p_public_key)
+{
+ ret_code_t result;
+ CRYSError_t crys_error;
+ CRYS_ECPKI_Domain_t const * p_domain;
+ bool mutex_locked;
+
+ nrf_crypto_backend_cc310_key_pair_generate_context_t * p_ctx =
+ (nrf_crypto_backend_cc310_key_pair_generate_context_t *)p_context;
+
+ nrf_crypto_backend_cc310_ecc_private_key_t * p_prv =
+ (nrf_crypto_backend_cc310_ecc_private_key_t *)p_private_key;
+
+ nrf_crypto_backend_cc310_ecc_public_key_t * p_pub =
+ (nrf_crypto_backend_cc310_ecc_public_key_t *)p_public_key;
+
+ p_domain = get_domain(p_prv->header.p_info);
+
+ mutex_locked = cc310_backend_mutex_trylock();
+ VERIFY_TRUE(mutex_locked, NRF_ERROR_CRYPTO_BUSY);
+
+ cc310_backend_enable();
+
+ crys_error = CRYS_ECPKI_GenKeyPair(p_context,
+ nrf_crypto_backend_cc310_rng,
+ p_domain,
+ &p_prv->private_key,
+ &p_pub->key.cc310_public_key,
+ &p_ctx->temp_data,
+ NULL);
+ cc310_backend_disable();
+
+ cc310_backend_mutex_unlock();
+
+ p_pub->key_converted = true;
+
+ result = nrf_crypto_backend_cc310_ecc_error_convert(crys_error);
+ return result;
+}
+
+
+ret_code_t nrf_crypto_backend_cc310_private_key_from_raw(
+ void * p_private_key,
+ uint8_t const * p_raw_data)
+{
+ ret_code_t result;
+ CRYSError_t crys_error;
+ CRYS_ECPKI_Domain_t const * p_domain;
+ bool mutex_locked;
+
+ nrf_crypto_backend_cc310_ecc_private_key_t * p_prv =
+ (nrf_crypto_backend_cc310_ecc_private_key_t *)p_private_key;
+
+ nrf_crypto_ecc_curve_info_t const * p_info = p_prv->header.p_info;
+
+ p_domain = get_domain(p_info);
+
+ mutex_locked = cc310_backend_mutex_trylock();
+ VERIFY_TRUE(mutex_locked, NRF_ERROR_CRYPTO_BUSY);
+
+ crys_error = CRYS_ECPKI_BuildPrivKey(p_domain,
+ p_raw_data,
+ p_info->raw_private_key_size,
+ &p_prv->private_key);
+
+ cc310_backend_mutex_unlock();
+
+ result = nrf_crypto_backend_cc310_ecc_error_convert(crys_error);
+ return result;
+}
+
+
+ret_code_t nrf_crypto_backend_cc310_private_key_to_raw(
+ void const * p_private_key,
+ uint8_t * p_raw_data)
+{
+ ret_code_t result;
+ CRYSError_t crys_error;
+ uint32_t key_size;
+
+ nrf_crypto_backend_cc310_ecc_private_key_t * p_prv =
+ (nrf_crypto_backend_cc310_ecc_private_key_t *)p_private_key;
+
+ nrf_crypto_ecc_curve_info_t const * p_info = p_prv->header.p_info;
+
+ key_size = p_info->raw_private_key_size;
+
+ crys_error = CRYS_ECPKI_ExportPrivKey(&p_prv->private_key,
+ p_raw_data,
+ &key_size);
+
+ if (key_size != p_info->raw_private_key_size)
+ {
+ return NRF_ERROR_CRYPTO_INTERNAL;
+ }
+
+ result = nrf_crypto_backend_cc310_ecc_error_convert(crys_error);
+
+ return result;
+}
+
+
+ret_code_t nrf_crypto_backend_cc310_public_key_from_raw(
+ void * p_public_key,
+ uint8_t const * p_raw_data)
+{
+ nrf_crypto_backend_cc310_ecc_public_key_t * p_pub =
+ (nrf_crypto_backend_cc310_ecc_public_key_t *)p_public_key;
+
+ nrf_crypto_ecc_curve_info_t const * p_info = p_pub->header.p_info;
+
+ memcpy(p_pub->key.raw_public_key, p_raw_data, p_info->raw_public_key_size);
+ p_pub->key_converted = false;
+
+ return NRF_SUCCESS;
+}
+
+
+ret_code_t nrf_crypto_backend_cc310_public_key_to_raw(
+ void const * p_public_key,
+ uint8_t * p_raw_data)
+{
+ ret_code_t result;
+ CRYSError_t crys_error;
+ uint8_t ucompressed_key[NRF_CRYPTO_ECC_RAW_PUBLIC_KEY_MAX_SIZE + 1];
+ uint32_t key_size;
+ bool mutex_locked;
+
+ nrf_crypto_backend_cc310_ecc_public_key_t * p_pub =
+ (nrf_crypto_backend_cc310_ecc_public_key_t *)p_public_key;
+
+ nrf_crypto_ecc_curve_info_t const * p_info = p_pub->header.p_info;
+
+ if (!p_pub->key_converted)
+ {
+ memcpy(p_raw_data, p_pub->key.raw_public_key, p_info->raw_public_key_size);
+ return NRF_SUCCESS;
+ }
+
+ mutex_locked = cc310_backend_mutex_trylock();
+ if (!mutex_locked)
+ {
+ return NRF_ERROR_CRYPTO_BUSY;
+ }
+
+ key_size = p_info->raw_public_key_size + 1;
+
+ crys_error = CRYS_ECPKI_ExportPublKey(&p_pub->key.cc310_public_key,
+ CRYS_EC_PointUncompressed,
+ ucompressed_key,
+ &key_size);
+
+ cc310_backend_mutex_unlock();
+
+ if ((key_size != p_info->raw_public_key_size + 1)
+ || (ucompressed_key[0] != CC310_UNCOMPRESSED_PUBLIC_KEY_ID_BYTE))
+ {
+ return NRF_ERROR_CRYPTO_INTERNAL;
+ }
+
+ memcpy(p_raw_data, &ucompressed_key[1], p_info->raw_public_key_size);
+
+ result = nrf_crypto_backend_cc310_ecc_error_convert(crys_error);
+ return result;
+}
+
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_CC310_ECC_SECP160R1)
+const nrf_crypto_ecc_curve_info_t g_nrf_crypto_ecc_secp160r1_curve_info =
+{
+ .public_key_size = sizeof(nrf_crypto_backend_cc310_ecc_public_key_t),
+ .private_key_size = sizeof(nrf_crypto_backend_cc310_ecc_private_key_t),
+ .curve_type = NRF_CRYPTO_ECC_SECP160R1_CURVE_TYPE,
+ .raw_private_key_size = NRF_CRYPTO_ECC_SECP160R1_RAW_PRIVATE_KEY_SIZE,
+ .raw_public_key_size = NRF_CRYPTO_ECC_SECP160R1_RAW_PUBLIC_KEY_SIZE,
+ .p_backend_data = (void *)CRYS_ECPKI_DomainID_secp160r1,
+};
+#endif
+
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_CC310_ECC_SECP160R2)
+const nrf_crypto_ecc_curve_info_t g_nrf_crypto_ecc_secp160r2_curve_info =
+{
+ .public_key_size = sizeof(nrf_crypto_backend_cc310_ecc_public_key_t),
+ .private_key_size = sizeof(nrf_crypto_backend_cc310_ecc_private_key_t),
+ .curve_type = NRF_CRYPTO_ECC_SECP160R2_CURVE_TYPE,
+ .raw_private_key_size = NRF_CRYPTO_ECC_SECP160R2_RAW_PRIVATE_KEY_SIZE,
+ .raw_public_key_size = NRF_CRYPTO_ECC_SECP160R2_RAW_PUBLIC_KEY_SIZE,
+ .p_backend_data = (void *)CRYS_ECPKI_DomainID_secp160r2,
+};
+#endif
+
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_CC310_ECC_SECP192R1)
+const nrf_crypto_ecc_curve_info_t g_nrf_crypto_ecc_secp192r1_curve_info =
+{
+ .public_key_size = sizeof(nrf_crypto_backend_cc310_ecc_public_key_t),
+ .private_key_size = sizeof(nrf_crypto_backend_cc310_ecc_private_key_t),
+ .curve_type = NRF_CRYPTO_ECC_SECP192R1_CURVE_TYPE,
+ .raw_private_key_size = NRF_CRYPTO_ECC_SECP192R1_RAW_PRIVATE_KEY_SIZE,
+ .raw_public_key_size = NRF_CRYPTO_ECC_SECP192R1_RAW_PUBLIC_KEY_SIZE,
+ .p_backend_data = (void *)CRYS_ECPKI_DomainID_secp192r1,
+};
+#endif
+
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_CC310_ECC_SECP224R1)
+const nrf_crypto_ecc_curve_info_t g_nrf_crypto_ecc_secp224r1_curve_info =
+{
+ .public_key_size = sizeof(nrf_crypto_backend_cc310_ecc_public_key_t),
+ .private_key_size = sizeof(nrf_crypto_backend_cc310_ecc_private_key_t),
+ .curve_type = NRF_CRYPTO_ECC_SECP224R1_CURVE_TYPE,
+ .raw_private_key_size = NRF_CRYPTO_ECC_SECP224R1_RAW_PRIVATE_KEY_SIZE,
+ .raw_public_key_size = NRF_CRYPTO_ECC_SECP224R1_RAW_PUBLIC_KEY_SIZE,
+ .p_backend_data = (void *)CRYS_ECPKI_DomainID_secp224r1,
+};
+#endif
+
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_CC310_ECC_SECP256R1)
+const nrf_crypto_ecc_curve_info_t g_nrf_crypto_ecc_secp256r1_curve_info =
+{
+ .public_key_size = sizeof(nrf_crypto_backend_cc310_ecc_public_key_t),
+ .private_key_size = sizeof(nrf_crypto_backend_cc310_ecc_private_key_t),
+ .curve_type = NRF_CRYPTO_ECC_SECP256R1_CURVE_TYPE,
+ .raw_private_key_size = NRF_CRYPTO_ECC_SECP256R1_RAW_PRIVATE_KEY_SIZE,
+ .raw_public_key_size = NRF_CRYPTO_ECC_SECP256R1_RAW_PUBLIC_KEY_SIZE,
+ .p_backend_data = (void *)CRYS_ECPKI_DomainID_secp256r1,
+};
+#endif
+
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_CC310_ECC_SECP384R1)
+const nrf_crypto_ecc_curve_info_t g_nrf_crypto_ecc_secp384r1_curve_info =
+{
+ .public_key_size = sizeof(nrf_crypto_backend_cc310_ecc_public_key_t),
+ .private_key_size = sizeof(nrf_crypto_backend_cc310_ecc_private_key_t),
+ .curve_type = NRF_CRYPTO_ECC_SECP384R1_CURVE_TYPE,
+ .raw_private_key_size = NRF_CRYPTO_ECC_SECP384R1_RAW_PRIVATE_KEY_SIZE,
+ .raw_public_key_size = NRF_CRYPTO_ECC_SECP384R1_RAW_PUBLIC_KEY_SIZE,
+ .p_backend_data = (void *)CRYS_ECPKI_DomainID_secp384r1,
+};
+#endif
+
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_CC310_ECC_SECP521R1)
+const nrf_crypto_ecc_curve_info_t g_nrf_crypto_ecc_secp521r1_curve_info =
+{
+ .public_key_size = sizeof(nrf_crypto_backend_cc310_ecc_public_key_t),
+ .private_key_size = sizeof(nrf_crypto_backend_cc310_ecc_private_key_t),
+ .curve_type = NRF_CRYPTO_ECC_SECP521R1_CURVE_TYPE,
+ .raw_private_key_size = NRF_CRYPTO_ECC_SECP521R1_RAW_PRIVATE_KEY_SIZE,
+ .raw_public_key_size = NRF_CRYPTO_ECC_SECP521R1_RAW_PUBLIC_KEY_SIZE,
+ .p_backend_data = (void *)CRYS_ECPKI_DomainID_secp521r1,
+};
+#endif
+
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_CC310_ECC_SECP160K1)
+const nrf_crypto_ecc_curve_info_t g_nrf_crypto_ecc_secp160k1_curve_info =
+{
+ .public_key_size = sizeof(nrf_crypto_backend_cc310_ecc_public_key_t),
+ .private_key_size = sizeof(nrf_crypto_backend_cc310_ecc_private_key_t),
+ .curve_type = NRF_CRYPTO_ECC_SECP160K1_CURVE_TYPE,
+ .raw_private_key_size = NRF_CRYPTO_ECC_SECP160K1_RAW_PRIVATE_KEY_SIZE,
+ .raw_public_key_size = NRF_CRYPTO_ECC_SECP160K1_RAW_PUBLIC_KEY_SIZE,
+ .p_backend_data = (void *)CRYS_ECPKI_DomainID_secp160k1,
+};
+#endif
+
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_CC310_ECC_SECP192K1)
+const nrf_crypto_ecc_curve_info_t g_nrf_crypto_ecc_secp192k1_curve_info =
+{
+ .public_key_size = sizeof(nrf_crypto_backend_cc310_ecc_public_key_t),
+ .private_key_size = sizeof(nrf_crypto_backend_cc310_ecc_private_key_t),
+ .curve_type = NRF_CRYPTO_ECC_SECP192K1_CURVE_TYPE,
+ .raw_private_key_size = NRF_CRYPTO_ECC_SECP192K1_RAW_PRIVATE_KEY_SIZE,
+ .raw_public_key_size = NRF_CRYPTO_ECC_SECP192K1_RAW_PUBLIC_KEY_SIZE,
+ .p_backend_data = (void *)CRYS_ECPKI_DomainID_secp192k1,
+};
+#endif
+
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_CC310_ECC_SECP224K1)
+const nrf_crypto_ecc_curve_info_t g_nrf_crypto_ecc_secp224k1_curve_info =
+{
+ .public_key_size = sizeof(nrf_crypto_backend_cc310_ecc_public_key_t),
+ .private_key_size = sizeof(nrf_crypto_backend_cc310_ecc_private_key_t),
+ .curve_type = NRF_CRYPTO_ECC_SECP224K1_CURVE_TYPE,
+ .raw_private_key_size = NRF_CRYPTO_ECC_SECP224K1_RAW_PRIVATE_KEY_SIZE,
+ .raw_public_key_size = NRF_CRYPTO_ECC_SECP224K1_RAW_PUBLIC_KEY_SIZE,
+ .p_backend_data = (void *)CRYS_ECPKI_DomainID_secp224k1,
+};
+#endif
+
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_CC310_ECC_SECP256K1)
+const nrf_crypto_ecc_curve_info_t g_nrf_crypto_ecc_secp256k1_curve_info =
+{
+ .public_key_size = sizeof(nrf_crypto_backend_cc310_ecc_public_key_t),
+ .private_key_size = sizeof(nrf_crypto_backend_cc310_ecc_private_key_t),
+ .curve_type = NRF_CRYPTO_ECC_SECP256K1_CURVE_TYPE,
+ .raw_private_key_size = NRF_CRYPTO_ECC_SECP256K1_RAW_PRIVATE_KEY_SIZE,
+ .raw_public_key_size = NRF_CRYPTO_ECC_SECP256K1_RAW_PUBLIC_KEY_SIZE,
+ .p_backend_data = (void *)CRYS_ECPKI_DomainID_secp256k1,
+};
+#endif
+
+
+#endif // NRF_MODULE_ENABLED(NRF_CRYPTO) && NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_CC310)
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/cc310/cc310_backend_ecc.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/cc310/cc310_backend_ecc.h
new file mode 100644
index 0000000..f9f20e2
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/cc310/cc310_backend_ecc.h
@@ -0,0 +1,548 @@
+/**
+ * Copyright (c) 2018 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+
+#ifndef CC310_BACKEND_ECC_H__
+#define CC310_BACKEND_ECC_H__
+
+#include "sdk_config.h"
+#include "nordic_common.h"
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO) && NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_CC310)
+
+#include <stdbool.h>
+#include "nrf_crypto_ecc_shared.h"
+#include "crys_ecpki_kg.h"
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** @internal @brief Common structure holding private key for CC310.
+ */
+typedef struct
+{
+ nrf_crypto_internal_ecc_key_header_t header; /**< @internal @brief Common ECC key header */
+ CRYS_ECPKI_UserPrivKey_t private_key; /**< @internal @brief CC310 specific key representation */
+} nrf_crypto_backend_cc310_ecc_private_key_t;
+
+
+/** @internal @brief Common structure holding public key for CC310.
+ */
+typedef struct
+{
+ nrf_crypto_internal_ecc_key_header_t header; /**< @internal @brief Common ECC key header */
+ bool key_converted; /**< @internal @brief True if key was already converted from raw_public_key to cc310_public_key */
+ union
+ {
+ CRYS_ECPKI_UserPublKey_t cc310_public_key; /**< @internal @brief CC310 specific key representation */
+ uint8_t raw_public_key[132]; /**< @internal @brief raw key representation */
+ } key;
+} nrf_crypto_backend_cc310_ecc_public_key_t;
+
+
+/** @internal @brief Common structure holding context for key pair generation.
+ */
+typedef struct
+{
+ CRYS_ECPKI_KG_TempData_t temp_data; /**< @internal @brief Temporary buffer for CC310 internal storage */
+} nrf_crypto_backend_cc310_key_pair_generate_context_t;
+
+
+/** @internal See @ref nrf_crypto_backend_ecc_key_pair_generate_fn_t.
+ */
+ret_code_t nrf_crypto_backend_cc310_key_pair_generate(
+ void * p_context,
+ void * p_private_key,
+ void * p_public_key);
+
+
+/** @internal See @ref nrf_crypto_backend_ecc_private_key_from_raw_fn_t.
+*/
+ret_code_t nrf_crypto_backend_cc310_private_key_from_raw(
+ void * p_private_key,
+ uint8_t const * p_raw_data);
+
+
+/** @internal See @ref nrf_crypto_backend_ecc_private_key_to_raw_fn_t.
+*/
+ret_code_t nrf_crypto_backend_cc310_private_key_to_raw(
+ void const * p_private_key,
+ uint8_t * p_raw_data);
+
+
+/** @internal See @ref nrf_crypto_backend_ecc_public_key_from_raw_fn_t.
+*/
+ret_code_t nrf_crypto_backend_cc310_public_key_from_raw(
+ void * p_public_key,
+ uint8_t const * p_raw_data);
+
+
+/** @internal See @ref nrf_crypto_backend_ecc_public_key_to_raw_fn_t.
+*/
+ret_code_t nrf_crypto_backend_cc310_public_key_to_raw(
+ void const * p_public_key,
+ uint8_t * p_raw_data);
+
+
+/** @internal @brief Convert error code from CC310 to nrf_crypto error code.
+ *
+ * @param[in] crys_error CC310 error code.
+ * @return nrf_crypto error code.
+ */
+ret_code_t nrf_crypto_backend_cc310_ecc_error_convert(uint32_t crys_error);
+
+
+/** @internal @brief Converts public key from raw to CC310 representation if not converted already.
+ *
+ * Data are read from p_pub->key.raw_public_key to stored into p_pub->cc310_public_key.
+ *
+ * @param[in] p_pub Public key to convert.
+ * @param[in] p_temp_data Buffer for temporary data used by CC310 lib.
+ * @return nrf_crypto error code.
+ */
+ret_code_t nrf_crypto_backend_cc310_ecc_public_key_convert(
+ nrf_crypto_backend_cc310_ecc_public_key_t * p_pub,
+ CRYS_ECPKI_BUILD_TempData_t * p_temp_data);
+
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_CC310_ECC_SECP160R1)
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_ECC_SECP160R1)
+#error "More than one backend enabled for secp160r1 (NIST 160-bit).");
+#endif
+#define NRF_CRYPTO_ECC_SECP160R1_ENABLED 1
+
+// Aliases for one common CC310 implementation
+#define nrf_crypto_backend_secp160r1_key_pair_generate nrf_crypto_backend_cc310_key_pair_generate
+#define nrf_crypto_backend_secp160r1_public_key_calculate NULL
+#define nrf_crypto_backend_secp160r1_private_key_from_raw nrf_crypto_backend_cc310_private_key_from_raw
+#define nrf_crypto_backend_secp160r1_private_key_to_raw nrf_crypto_backend_cc310_private_key_to_raw
+#define nrf_crypto_backend_secp160r1_public_key_from_raw nrf_crypto_backend_cc310_public_key_from_raw
+#define nrf_crypto_backend_secp160r1_public_key_to_raw nrf_crypto_backend_cc310_public_key_to_raw
+#define nrf_crypto_backend_secp160r1_private_key_free NULL
+#define nrf_crypto_backend_secp160r1_public_key_free NULL
+
+// Context sizes required by CC310
+#define NRF_CRYPTO_BACKEND_SECP160R1_KEY_PAIR_GENERATE_CONTEXT_SIZE \
+ sizeof(nrf_crypto_backend_cc310_key_pair_generate_context_t)
+#define NRF_CRYPTO_BACKEND_SECP160R1_PUBLIC_KEY_CALCULATE_CONTEXT_SIZE 0
+
+// All CC310 curve types share the same data structures for keys
+typedef nrf_crypto_backend_cc310_ecc_private_key_t nrf_crypto_backend_secp160r1_private_key_t;
+typedef nrf_crypto_backend_cc310_ecc_public_key_t nrf_crypto_backend_secp160r1_public_key_t;
+
+// All CC310 curve types share the same data structures for context
+typedef nrf_crypto_backend_cc310_key_pair_generate_context_t
+ nrf_crypto_backend_secp160r1_key_pair_generate_context_t;
+
+// Dummy typedef for unused context
+typedef uint32_t nrf_crypto_backend_secp160r1_public_key_calculate_context_t;
+
+#endif // NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_CC310_ECC_SECP160R1)
+
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_CC310_ECC_SECP160R2)
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_ECC_SECP160R2)
+#error "More than one backend enabled for secp160r2 (NIST 160-bit).");
+#endif
+#define NRF_CRYPTO_ECC_SECP160R2_ENABLED 1
+
+// Aliases for one common CC310 implementation
+#define nrf_crypto_backend_secp160r2_key_pair_generate nrf_crypto_backend_cc310_key_pair_generate
+#define nrf_crypto_backend_secp160r2_public_key_calculate NULL
+#define nrf_crypto_backend_secp160r2_private_key_from_raw nrf_crypto_backend_cc310_private_key_from_raw
+#define nrf_crypto_backend_secp160r2_private_key_to_raw nrf_crypto_backend_cc310_private_key_to_raw
+#define nrf_crypto_backend_secp160r2_public_key_from_raw nrf_crypto_backend_cc310_public_key_from_raw
+#define nrf_crypto_backend_secp160r2_public_key_to_raw nrf_crypto_backend_cc310_public_key_to_raw
+#define nrf_crypto_backend_secp160r2_private_key_free NULL
+#define nrf_crypto_backend_secp160r2_public_key_free NULL
+
+// Context sizes required by CC310
+#define NRF_CRYPTO_BACKEND_SECP160R2_KEY_PAIR_GENERATE_CONTEXT_SIZE \
+ sizeof(nrf_crypto_backend_cc310_key_pair_generate_context_t)
+#define NRF_CRYPTO_BACKEND_SECP160R2_PUBLIC_KEY_CALCULATE_CONTEXT_SIZE 0
+
+// All CC310 curve types share the same data structures for keys
+typedef nrf_crypto_backend_cc310_ecc_private_key_t nrf_crypto_backend_secp160r2_private_key_t;
+typedef nrf_crypto_backend_cc310_ecc_public_key_t nrf_crypto_backend_secp160r2_public_key_t;
+
+// All CC310 curve types share the same data structures for context
+typedef nrf_crypto_backend_cc310_key_pair_generate_context_t
+ nrf_crypto_backend_secp160r2_key_pair_generate_context_t;
+
+// Dummy typedef for unused context
+typedef uint32_t nrf_crypto_backend_secp160r2_public_key_calculate_context_t;
+
+#endif // NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_CC310_ECC_SECP160R2)
+
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_CC310_ECC_SECP192R1)
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_ECC_SECP192R1)
+#error "More than one backend enabled for secp192r1 (NIST 192-bit).");
+#endif
+#define NRF_CRYPTO_ECC_SECP192R1_ENABLED 1
+
+// Aliases for one common CC310 implementation
+#define nrf_crypto_backend_secp192r1_key_pair_generate nrf_crypto_backend_cc310_key_pair_generate
+#define nrf_crypto_backend_secp192r1_public_key_calculate NULL
+#define nrf_crypto_backend_secp192r1_private_key_from_raw nrf_crypto_backend_cc310_private_key_from_raw
+#define nrf_crypto_backend_secp192r1_private_key_to_raw nrf_crypto_backend_cc310_private_key_to_raw
+#define nrf_crypto_backend_secp192r1_public_key_from_raw nrf_crypto_backend_cc310_public_key_from_raw
+#define nrf_crypto_backend_secp192r1_public_key_to_raw nrf_crypto_backend_cc310_public_key_to_raw
+#define nrf_crypto_backend_secp192r1_private_key_free NULL
+#define nrf_crypto_backend_secp192r1_public_key_free NULL
+
+// Context sizes required by CC310
+#define NRF_CRYPTO_BACKEND_SECP192R1_KEY_PAIR_GENERATE_CONTEXT_SIZE \
+ sizeof(nrf_crypto_backend_cc310_key_pair_generate_context_t)
+#define NRF_CRYPTO_BACKEND_SECP192R1_PUBLIC_KEY_CALCULATE_CONTEXT_SIZE 0
+
+// All CC310 curve types share the same data structures for keys
+typedef nrf_crypto_backend_cc310_ecc_private_key_t nrf_crypto_backend_secp192r1_private_key_t;
+typedef nrf_crypto_backend_cc310_ecc_public_key_t nrf_crypto_backend_secp192r1_public_key_t;
+
+// All CC310 curve types share the same data structures for context
+typedef nrf_crypto_backend_cc310_key_pair_generate_context_t
+ nrf_crypto_backend_secp192r1_key_pair_generate_context_t;
+
+// Dummy typedef for unused context
+typedef uint32_t nrf_crypto_backend_secp192r1_public_key_calculate_context_t;
+
+#endif // NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_CC310_ECC_SECP192R1)
+
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_CC310_ECC_SECP224R1)
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_ECC_SECP224R1)
+#error "More than one backend enabled for secp224r1 (NIST 224-bit).");
+#endif
+#define NRF_CRYPTO_ECC_SECP224R1_ENABLED 1
+
+// Aliases for one common CC310 implementation
+#define nrf_crypto_backend_secp224r1_key_pair_generate nrf_crypto_backend_cc310_key_pair_generate
+#define nrf_crypto_backend_secp224r1_public_key_calculate NULL
+#define nrf_crypto_backend_secp224r1_private_key_from_raw nrf_crypto_backend_cc310_private_key_from_raw
+#define nrf_crypto_backend_secp224r1_private_key_to_raw nrf_crypto_backend_cc310_private_key_to_raw
+#define nrf_crypto_backend_secp224r1_public_key_from_raw nrf_crypto_backend_cc310_public_key_from_raw
+#define nrf_crypto_backend_secp224r1_public_key_to_raw nrf_crypto_backend_cc310_public_key_to_raw
+#define nrf_crypto_backend_secp224r1_private_key_free NULL
+#define nrf_crypto_backend_secp224r1_public_key_free NULL
+
+// Context sizes required by CC310
+#define NRF_CRYPTO_BACKEND_SECP224R1_KEY_PAIR_GENERATE_CONTEXT_SIZE \
+ sizeof(nrf_crypto_backend_cc310_key_pair_generate_context_t)
+#define NRF_CRYPTO_BACKEND_SECP224R1_PUBLIC_KEY_CALCULATE_CONTEXT_SIZE 0
+
+// All CC310 curve types share the same data structures for keys
+typedef nrf_crypto_backend_cc310_ecc_private_key_t nrf_crypto_backend_secp224r1_private_key_t;
+typedef nrf_crypto_backend_cc310_ecc_public_key_t nrf_crypto_backend_secp224r1_public_key_t;
+
+// All CC310 curve types share the same data structures for context
+typedef nrf_crypto_backend_cc310_key_pair_generate_context_t
+ nrf_crypto_backend_secp224r1_key_pair_generate_context_t;
+
+// Dummy typedef for unused context
+typedef uint32_t nrf_crypto_backend_secp224r1_public_key_calculate_context_t;
+
+#endif // NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_CC310_ECC_SECP224R1)
+
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_CC310_ECC_SECP256R1)
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_ECC_SECP256R1)
+#error "More than one backend enabled for secp256r1 (NIST 256-bit).");
+#endif
+#define NRF_CRYPTO_ECC_SECP256R1_ENABLED 1
+
+// Aliases for one common CC310 implementation
+#define nrf_crypto_backend_secp256r1_key_pair_generate nrf_crypto_backend_cc310_key_pair_generate
+#define nrf_crypto_backend_secp256r1_public_key_calculate NULL
+#define nrf_crypto_backend_secp256r1_private_key_from_raw nrf_crypto_backend_cc310_private_key_from_raw
+#define nrf_crypto_backend_secp256r1_private_key_to_raw nrf_crypto_backend_cc310_private_key_to_raw
+#define nrf_crypto_backend_secp256r1_public_key_from_raw nrf_crypto_backend_cc310_public_key_from_raw
+#define nrf_crypto_backend_secp256r1_public_key_to_raw nrf_crypto_backend_cc310_public_key_to_raw
+#define nrf_crypto_backend_secp256r1_private_key_free NULL
+#define nrf_crypto_backend_secp256r1_public_key_free NULL
+
+// Context sizes required by CC310
+#define NRF_CRYPTO_BACKEND_SECP256R1_KEY_PAIR_GENERATE_CONTEXT_SIZE \
+ sizeof(nrf_crypto_backend_cc310_key_pair_generate_context_t)
+#define NRF_CRYPTO_BACKEND_SECP256R1_PUBLIC_KEY_CALCULATE_CONTEXT_SIZE 0
+
+// All CC310 curve types share the same data structures for keys
+typedef nrf_crypto_backend_cc310_ecc_private_key_t nrf_crypto_backend_secp256r1_private_key_t;
+typedef nrf_crypto_backend_cc310_ecc_public_key_t nrf_crypto_backend_secp256r1_public_key_t;
+
+// All CC310 curve types share the same data structures for context
+typedef nrf_crypto_backend_cc310_key_pair_generate_context_t
+ nrf_crypto_backend_secp256r1_key_pair_generate_context_t;
+
+// Dummy typedef for unused context
+typedef uint32_t nrf_crypto_backend_secp256r1_public_key_calculate_context_t;
+
+#endif // NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_CC310_ECC_SECP256R1)
+
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_CC310_ECC_SECP384R1)
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_ECC_SECP384R1)
+#error "More than one backend enabled for secp384r1 (NIST 384-bit).");
+#endif
+#define NRF_CRYPTO_ECC_SECP384R1_ENABLED 1
+
+// Aliases for one common CC310 implementation
+#define nrf_crypto_backend_secp384r1_key_pair_generate nrf_crypto_backend_cc310_key_pair_generate
+#define nrf_crypto_backend_secp384r1_public_key_calculate NULL
+#define nrf_crypto_backend_secp384r1_private_key_from_raw nrf_crypto_backend_cc310_private_key_from_raw
+#define nrf_crypto_backend_secp384r1_private_key_to_raw nrf_crypto_backend_cc310_private_key_to_raw
+#define nrf_crypto_backend_secp384r1_public_key_from_raw nrf_crypto_backend_cc310_public_key_from_raw
+#define nrf_crypto_backend_secp384r1_public_key_to_raw nrf_crypto_backend_cc310_public_key_to_raw
+#define nrf_crypto_backend_secp384r1_private_key_free NULL
+#define nrf_crypto_backend_secp384r1_public_key_free NULL
+
+// Context sizes required by CC310
+#define NRF_CRYPTO_BACKEND_SECP384R1_KEY_PAIR_GENERATE_CONTEXT_SIZE \
+ sizeof(nrf_crypto_backend_cc310_key_pair_generate_context_t)
+#define NRF_CRYPTO_BACKEND_SECP384R1_PUBLIC_KEY_CALCULATE_CONTEXT_SIZE 0
+
+// All CC310 curve types share the same data structures for keys
+typedef nrf_crypto_backend_cc310_ecc_private_key_t nrf_crypto_backend_secp384r1_private_key_t;
+typedef nrf_crypto_backend_cc310_ecc_public_key_t nrf_crypto_backend_secp384r1_public_key_t;
+
+// All CC310 curve types share the same data structures for context
+typedef nrf_crypto_backend_cc310_key_pair_generate_context_t
+ nrf_crypto_backend_secp384r1_key_pair_generate_context_t;
+
+// Dummy typedef for unused context
+typedef uint32_t nrf_crypto_backend_secp384r1_public_key_calculate_context_t;
+
+#endif // NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_CC310_ECC_SECP384R1)
+
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_CC310_ECC_SECP521R1)
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_ECC_SECP521R1)
+#error "More than one backend enabled for secp521r1 (NIST 521-bit).");
+#endif
+#define NRF_CRYPTO_ECC_SECP521R1_ENABLED 1
+
+// Aliases for one common CC310 implementation
+#define nrf_crypto_backend_secp521r1_key_pair_generate nrf_crypto_backend_cc310_key_pair_generate
+#define nrf_crypto_backend_secp521r1_public_key_calculate NULL
+#define nrf_crypto_backend_secp521r1_private_key_from_raw nrf_crypto_backend_cc310_private_key_from_raw
+#define nrf_crypto_backend_secp521r1_private_key_to_raw nrf_crypto_backend_cc310_private_key_to_raw
+#define nrf_crypto_backend_secp521r1_public_key_from_raw nrf_crypto_backend_cc310_public_key_from_raw
+#define nrf_crypto_backend_secp521r1_public_key_to_raw nrf_crypto_backend_cc310_public_key_to_raw
+#define nrf_crypto_backend_secp521r1_private_key_free NULL
+#define nrf_crypto_backend_secp521r1_public_key_free NULL
+
+// Context sizes required by CC310
+#define NRF_CRYPTO_BACKEND_SECP521R1_KEY_PAIR_GENERATE_CONTEXT_SIZE \
+ sizeof(nrf_crypto_backend_cc310_key_pair_generate_context_t)
+#define NRF_CRYPTO_BACKEND_SECP521R1_PUBLIC_KEY_CALCULATE_CONTEXT_SIZE 0
+
+// All CC310 curve types share the same data structures for keys
+typedef nrf_crypto_backend_cc310_ecc_private_key_t nrf_crypto_backend_secp521r1_private_key_t;
+typedef nrf_crypto_backend_cc310_ecc_public_key_t nrf_crypto_backend_secp521r1_public_key_t;
+
+// All CC310 curve types share the same data structures for context
+typedef nrf_crypto_backend_cc310_key_pair_generate_context_t
+ nrf_crypto_backend_secp521r1_key_pair_generate_context_t;
+
+// Dummy typedef for unused context
+typedef uint32_t nrf_crypto_backend_secp521r1_public_key_calculate_context_t;
+
+#endif // NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_CC310_ECC_SECP521R1)
+
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_CC310_ECC_SECP160K1)
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_ECC_SECP160K1)
+#error "More than one backend enabled for secp160k1 (Koblitz 160-bit).");
+#endif
+#define NRF_CRYPTO_ECC_SECP160K1_ENABLED 1
+
+// Aliases for one common CC310 implementation
+#define nrf_crypto_backend_secp160k1_key_pair_generate nrf_crypto_backend_cc310_key_pair_generate
+#define nrf_crypto_backend_secp160k1_public_key_calculate NULL
+#define nrf_crypto_backend_secp160k1_private_key_from_raw nrf_crypto_backend_cc310_private_key_from_raw
+#define nrf_crypto_backend_secp160k1_private_key_to_raw nrf_crypto_backend_cc310_private_key_to_raw
+#define nrf_crypto_backend_secp160k1_public_key_from_raw nrf_crypto_backend_cc310_public_key_from_raw
+#define nrf_crypto_backend_secp160k1_public_key_to_raw nrf_crypto_backend_cc310_public_key_to_raw
+#define nrf_crypto_backend_secp160k1_private_key_free NULL
+#define nrf_crypto_backend_secp160k1_public_key_free NULL
+
+// Context sizes required by CC310
+#define NRF_CRYPTO_BACKEND_SECP160K1_KEY_PAIR_GENERATE_CONTEXT_SIZE \
+ sizeof(nrf_crypto_backend_cc310_key_pair_generate_context_t)
+#define NRF_CRYPTO_BACKEND_SECP160K1_PUBLIC_KEY_CALCULATE_CONTEXT_SIZE 0
+
+// All CC310 curve types share the same data structures for keys
+typedef nrf_crypto_backend_cc310_ecc_private_key_t nrf_crypto_backend_secp160k1_private_key_t;
+typedef nrf_crypto_backend_cc310_ecc_public_key_t nrf_crypto_backend_secp160k1_public_key_t;
+
+// All CC310 curve types share the same data structures for context
+typedef nrf_crypto_backend_cc310_key_pair_generate_context_t
+ nrf_crypto_backend_secp160k1_key_pair_generate_context_t;
+
+// Dummy typedef for unused context
+typedef uint32_t nrf_crypto_backend_secp160k1_public_key_calculate_context_t;
+
+#endif // NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_CC310_ECC_SECP160K1)
+
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_CC310_ECC_SECP192K1)
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_ECC_SECP192K1)
+#error "More than one backend enabled for secp192k1 (Koblitz 192-bit).");
+#endif
+#define NRF_CRYPTO_ECC_SECP192K1_ENABLED 1
+
+// Aliases for one common CC310 implementation
+#define nrf_crypto_backend_secp192k1_key_pair_generate nrf_crypto_backend_cc310_key_pair_generate
+#define nrf_crypto_backend_secp192k1_public_key_calculate NULL
+#define nrf_crypto_backend_secp192k1_private_key_from_raw nrf_crypto_backend_cc310_private_key_from_raw
+#define nrf_crypto_backend_secp192k1_private_key_to_raw nrf_crypto_backend_cc310_private_key_to_raw
+#define nrf_crypto_backend_secp192k1_public_key_from_raw nrf_crypto_backend_cc310_public_key_from_raw
+#define nrf_crypto_backend_secp192k1_public_key_to_raw nrf_crypto_backend_cc310_public_key_to_raw
+#define nrf_crypto_backend_secp192k1_private_key_free NULL
+#define nrf_crypto_backend_secp192k1_public_key_free NULL
+
+// Context sizes required by CC310
+#define NRF_CRYPTO_BACKEND_SECP192K1_KEY_PAIR_GENERATE_CONTEXT_SIZE \
+ sizeof(nrf_crypto_backend_cc310_key_pair_generate_context_t)
+#define NRF_CRYPTO_BACKEND_SECP192K1_PUBLIC_KEY_CALCULATE_CONTEXT_SIZE 0
+
+// All CC310 curve types share the same data structures for keys
+typedef nrf_crypto_backend_cc310_ecc_private_key_t nrf_crypto_backend_secp192k1_private_key_t;
+typedef nrf_crypto_backend_cc310_ecc_public_key_t nrf_crypto_backend_secp192k1_public_key_t;
+
+// All CC310 curve types share the same data structures for context
+typedef nrf_crypto_backend_cc310_key_pair_generate_context_t
+ nrf_crypto_backend_secp192k1_key_pair_generate_context_t;
+
+// Dummy typedef for unused context
+typedef uint32_t nrf_crypto_backend_secp192k1_public_key_calculate_context_t;
+
+#endif // NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_CC310_ECC_SECP192K1)
+
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_CC310_ECC_SECP224K1)
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_ECC_SECP224K1)
+#error "More than one backend enabled for secp224k1 (Koblitz 224-bit).");
+#endif
+#define NRF_CRYPTO_ECC_SECP224K1_ENABLED 1
+
+// Aliases for one common CC310 implementation
+#define nrf_crypto_backend_secp224k1_key_pair_generate nrf_crypto_backend_cc310_key_pair_generate
+#define nrf_crypto_backend_secp224k1_public_key_calculate NULL
+#define nrf_crypto_backend_secp224k1_private_key_from_raw nrf_crypto_backend_cc310_private_key_from_raw
+#define nrf_crypto_backend_secp224k1_private_key_to_raw nrf_crypto_backend_cc310_private_key_to_raw
+#define nrf_crypto_backend_secp224k1_public_key_from_raw nrf_crypto_backend_cc310_public_key_from_raw
+#define nrf_crypto_backend_secp224k1_public_key_to_raw nrf_crypto_backend_cc310_public_key_to_raw
+#define nrf_crypto_backend_secp224k1_private_key_free NULL
+#define nrf_crypto_backend_secp224k1_public_key_free NULL
+
+// Context sizes required by CC310
+#define NRF_CRYPTO_BACKEND_SECP224K1_KEY_PAIR_GENERATE_CONTEXT_SIZE \
+ sizeof(nrf_crypto_backend_cc310_key_pair_generate_context_t)
+#define NRF_CRYPTO_BACKEND_SECP224K1_PUBLIC_KEY_CALCULATE_CONTEXT_SIZE 0
+
+// All CC310 curve types share the same data structures for keys
+typedef nrf_crypto_backend_cc310_ecc_private_key_t nrf_crypto_backend_secp224k1_private_key_t;
+typedef nrf_crypto_backend_cc310_ecc_public_key_t nrf_crypto_backend_secp224k1_public_key_t;
+
+// All CC310 curve types share the same data structures for context
+typedef nrf_crypto_backend_cc310_key_pair_generate_context_t
+ nrf_crypto_backend_secp224k1_key_pair_generate_context_t;
+
+// Dummy typedef for unused context
+typedef uint32_t nrf_crypto_backend_secp224k1_public_key_calculate_context_t;
+
+#endif // NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_CC310_ECC_SECP224K1)
+
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_CC310_ECC_SECP256K1)
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_ECC_SECP256K1)
+#error "More than one backend enabled for secp256k1 (Koblitz 256-bit).");
+#endif
+#define NRF_CRYPTO_ECC_SECP256K1_ENABLED 1
+
+// Aliases for one common CC310 implementation
+#define nrf_crypto_backend_secp256k1_key_pair_generate nrf_crypto_backend_cc310_key_pair_generate
+#define nrf_crypto_backend_secp256k1_public_key_calculate NULL
+#define nrf_crypto_backend_secp256k1_private_key_from_raw nrf_crypto_backend_cc310_private_key_from_raw
+#define nrf_crypto_backend_secp256k1_private_key_to_raw nrf_crypto_backend_cc310_private_key_to_raw
+#define nrf_crypto_backend_secp256k1_public_key_from_raw nrf_crypto_backend_cc310_public_key_from_raw
+#define nrf_crypto_backend_secp256k1_public_key_to_raw nrf_crypto_backend_cc310_public_key_to_raw
+#define nrf_crypto_backend_secp256k1_private_key_free NULL
+#define nrf_crypto_backend_secp256k1_public_key_free NULL
+
+// Context sizes required by CC310
+#define NRF_CRYPTO_BACKEND_SECP256K1_KEY_PAIR_GENERATE_CONTEXT_SIZE \
+ sizeof(nrf_crypto_backend_cc310_key_pair_generate_context_t)
+#define NRF_CRYPTO_BACKEND_SECP256K1_PUBLIC_KEY_CALCULATE_CONTEXT_SIZE 0
+
+// All CC310 curve types share the same data structures for keys
+typedef nrf_crypto_backend_cc310_ecc_private_key_t nrf_crypto_backend_secp256k1_private_key_t;
+typedef nrf_crypto_backend_cc310_ecc_public_key_t nrf_crypto_backend_secp256k1_public_key_t;
+
+// All CC310 curve types share the same data structures for context
+typedef nrf_crypto_backend_cc310_key_pair_generate_context_t
+ nrf_crypto_backend_secp256k1_key_pair_generate_context_t;
+
+// Dummy typedef for unused context
+typedef uint32_t nrf_crypto_backend_secp256k1_public_key_calculate_context_t;
+
+#endif // NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_CC310_ECC_SECP256K1)
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // NRF_MODULE_ENABLED(NRF_CRYPTO) && NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_CC310)
+
+#endif // CC310_BACKEND_ECC_H__
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/cc310/cc310_backend_ecdh.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/cc310/cc310_backend_ecdh.c
new file mode 100644
index 0000000..48c2e5c
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/cc310/cc310_backend_ecdh.c
@@ -0,0 +1,131 @@
+/**
+ * Copyright (c) 2018 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+
+#include "sdk_config.h"
+#include "nordic_common.h"
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO) && NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_CC310)
+
+#include <string.h>
+
+#include "nrf_crypto_ecc_shared.h"
+#include "nrf_crypto_ecdh_shared.h"
+#include "nrf_crypto_ecdh.h"
+#include "nrf_crypto_mem.h"
+#include "cc310_backend_mutex.h"
+#include "cc310_backend_shared.h"
+#include "cc310_backend_ecdh.h"
+
+
+ret_code_t nrf_crypto_backend_cc310_ecdh_compute(
+ void * p_context,
+ void const * p_private_key,
+ void const * p_public_key,
+ uint8_t * p_shared_secret)
+{
+ ret_code_t result;
+ CRYSError_t crys_error;
+ uint32_t shared_secret_size;
+ uint8_t aligned_buffer[(NRF_CRYPTO_ECDH_SHARED_SECRET_MAX_SIZE + 3) & ~3];
+ uint8_t * p_output_buffer;
+ bool mutex_locked;
+
+ nrf_crypto_backend_cc310_ecdh_compute_context_t * p_ctx =
+ (nrf_crypto_backend_cc310_ecdh_compute_context_t *)p_context;
+
+ nrf_crypto_backend_cc310_ecc_private_key_t * p_prv =
+ (nrf_crypto_backend_cc310_ecc_private_key_t *)p_private_key;
+
+ nrf_crypto_backend_cc310_ecc_public_key_t * p_pub =
+ (nrf_crypto_backend_cc310_ecc_public_key_t *)p_public_key;
+
+ nrf_crypto_ecc_curve_info_t const * p_info = p_prv->header.p_info;
+
+ result = nrf_crypto_backend_cc310_ecc_public_key_convert(p_pub, &p_ctx->key_build_temp_data);
+ if (result != NRF_SUCCESS)
+ {
+ return result;
+ }
+
+ shared_secret_size = p_info->raw_private_key_size;
+
+ if ((shared_secret_size & 3) != 0) // Check if shared_secret_size is word aligned
+ {
+ shared_secret_size = (shared_secret_size + 3) & ~3;
+ p_output_buffer = &aligned_buffer[0];
+ }
+ else
+ {
+ p_output_buffer = p_shared_secret;
+ }
+
+ mutex_locked = cc310_backend_mutex_trylock();
+ if (!mutex_locked)
+ {
+ return NRF_ERROR_CRYPTO_BUSY;
+ }
+
+ cc310_backend_enable();
+
+ crys_error = CRYS_ECDH_SVDP_DH(&p_pub->key.cc310_public_key,
+ &p_prv->private_key,
+ p_output_buffer,
+ &shared_secret_size,
+ &p_ctx->temp_data);
+
+ cc310_backend_disable();
+
+ cc310_backend_mutex_unlock();
+
+ if (p_output_buffer != p_shared_secret)
+ {
+ //lint -save -e645 (Symbol 'aligned_buffer' may not have been initialized)
+ memcpy(p_shared_secret,
+ &aligned_buffer[3 - ((p_info->raw_private_key_size + 3) & 3)], // Bytes at the beginning that were added during padding are now skipped
+ p_info->raw_private_key_size);
+ //lint -restore
+ }
+
+ result = nrf_crypto_backend_cc310_ecc_error_convert(crys_error);
+ return result;
+}
+
+
+#endif // NRF_MODULE_ENABLED(NRF_CRYPTO) && NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_CC310)
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/cc310/cc310_backend_ecdh.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/cc310/cc310_backend_ecdh.h
new file mode 100644
index 0000000..0fe1dc4
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/cc310/cc310_backend_ecdh.h
@@ -0,0 +1,182 @@
+/**
+ * Copyright (c) 2018 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+
+#ifndef CC310_BACKEND_ECDH_H__
+#define CC310_BACKEND_ECDH_H__
+
+#include "sdk_config.h"
+#include "nordic_common.h"
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO) && NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_CC310)
+
+#include "nrf_crypto_ecc.h"
+#include "nrf_crypto_ecdh_shared.h"
+#include "crys_ecpki_dh.h"
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+/** @internal @brief Common structure holding context for ECDH.
+ */
+typedef union
+{
+ CRYS_ECDH_TempData_t temp_data; /**< @internal @brief Temporary buffer for CC310 internal storage */
+ CRYS_ECPKI_BUILD_TempData_t key_build_temp_data; /**< @internal @brief Temporary buffer for CC310 public key build */
+} nrf_crypto_backend_cc310_ecdh_compute_context_t;
+
+
+/** @internal See @ref nrf_crypto_backend_ecdh_compute_fn_t.
+ */
+ret_code_t nrf_crypto_backend_cc310_ecdh_compute(
+ void * p_context,
+ void const * p_private_key,
+ void const * p_public_key,
+ uint8_t * p_shared_secret);
+
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_CC310_ECC_SECP160R1)
+// Aliases for one common CC310 implementation
+#define nrf_crypto_backend_secp160r1_ecdh_compute nrf_crypto_backend_cc310_ecdh_compute
+#define NRF_CRYPTO_BACKEND_SECP160R1_ECDH_CONTEXT_SIZE \
+ sizeof(nrf_crypto_backend_cc310_ecdh_compute_context_t)
+typedef nrf_crypto_backend_cc310_ecdh_compute_context_t nrf_crypto_backend_secp160r1_ecdh_context_t;
+#endif // NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_CC310_ECC_SECP160R1)
+
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_CC310_ECC_SECP160R2)
+// Aliases for one common CC310 implementation
+#define nrf_crypto_backend_secp160r2_ecdh_compute nrf_crypto_backend_cc310_ecdh_compute
+#define NRF_CRYPTO_BACKEND_SECP160R2_ECDH_CONTEXT_SIZE \
+ sizeof(nrf_crypto_backend_cc310_ecdh_compute_context_t)
+typedef nrf_crypto_backend_cc310_ecdh_compute_context_t nrf_crypto_backend_secp160r2_ecdh_context_t;
+#endif // NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_CC310_ECC_SECP160R2)
+
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_CC310_ECC_SECP192R1)
+// Aliases for one common CC310 implementation
+#define nrf_crypto_backend_secp192r1_ecdh_compute nrf_crypto_backend_cc310_ecdh_compute
+#define NRF_CRYPTO_BACKEND_SECP192R1_ECDH_CONTEXT_SIZE \
+ sizeof(nrf_crypto_backend_cc310_ecdh_compute_context_t)
+typedef nrf_crypto_backend_cc310_ecdh_compute_context_t nrf_crypto_backend_secp192r1_ecdh_context_t;
+#endif // NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_CC310_ECC_SECP192R1)
+
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_CC310_ECC_SECP224R1)
+// Aliases for one common CC310 implementation
+#define nrf_crypto_backend_secp224r1_ecdh_compute nrf_crypto_backend_cc310_ecdh_compute
+#define NRF_CRYPTO_BACKEND_SECP224R1_ECDH_CONTEXT_SIZE \
+ sizeof(nrf_crypto_backend_cc310_ecdh_compute_context_t)
+typedef nrf_crypto_backend_cc310_ecdh_compute_context_t nrf_crypto_backend_secp224r1_ecdh_context_t;
+#endif // NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_CC310_ECC_SECP224R1)
+
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_CC310_ECC_SECP256R1)
+// Aliases for one common CC310 implementation
+#define nrf_crypto_backend_secp256r1_ecdh_compute nrf_crypto_backend_cc310_ecdh_compute
+#define NRF_CRYPTO_BACKEND_SECP256R1_ECDH_CONTEXT_SIZE \
+ sizeof(nrf_crypto_backend_cc310_ecdh_compute_context_t)
+typedef nrf_crypto_backend_cc310_ecdh_compute_context_t nrf_crypto_backend_secp256r1_ecdh_context_t;
+#endif // NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_CC310_ECC_SECP256R1)
+
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_CC310_ECC_SECP384R1)
+// Aliases for one common CC310 implementation
+#define nrf_crypto_backend_secp384r1_ecdh_compute nrf_crypto_backend_cc310_ecdh_compute
+#define NRF_CRYPTO_BACKEND_SECP384R1_ECDH_CONTEXT_SIZE \
+ sizeof(nrf_crypto_backend_cc310_ecdh_compute_context_t)
+typedef nrf_crypto_backend_cc310_ecdh_compute_context_t nrf_crypto_backend_secp384r1_ecdh_context_t;
+#endif // NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_CC310_ECC_SECP384R1)
+
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_CC310_ECC_SECP521R1)
+// Aliases for one common CC310 implementation
+#define nrf_crypto_backend_secp521r1_ecdh_compute nrf_crypto_backend_cc310_ecdh_compute
+#define NRF_CRYPTO_BACKEND_SECP521R1_ECDH_CONTEXT_SIZE \
+ sizeof(nrf_crypto_backend_cc310_ecdh_compute_context_t)
+typedef nrf_crypto_backend_cc310_ecdh_compute_context_t nrf_crypto_backend_secp521r1_ecdh_context_t;
+#endif // NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_CC310_ECC_SECP521R1)
+
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_CC310_ECC_SECP160K1)
+// Aliases for one common CC310 implementation
+#define nrf_crypto_backend_secp160k1_ecdh_compute nrf_crypto_backend_cc310_ecdh_compute
+#define NRF_CRYPTO_BACKEND_SECP160K1_ECDH_CONTEXT_SIZE \
+ sizeof(nrf_crypto_backend_cc310_ecdh_compute_context_t)
+typedef nrf_crypto_backend_cc310_ecdh_compute_context_t nrf_crypto_backend_secp160k1_ecdh_context_t;
+#endif // NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_CC310_ECC_SECP160K1)
+
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_CC310_ECC_SECP192K1)
+// Aliases for one common CC310 implementation
+#define nrf_crypto_backend_secp192k1_ecdh_compute nrf_crypto_backend_cc310_ecdh_compute
+#define NRF_CRYPTO_BACKEND_SECP192K1_ECDH_CONTEXT_SIZE \
+ sizeof(nrf_crypto_backend_cc310_ecdh_compute_context_t)
+typedef nrf_crypto_backend_cc310_ecdh_compute_context_t nrf_crypto_backend_secp192k1_ecdh_context_t;
+#endif // NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_CC310_ECC_SECP192K1)
+
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_CC310_ECC_SECP224K1)
+// Aliases for one common CC310 implementation
+#define nrf_crypto_backend_secp224k1_ecdh_compute nrf_crypto_backend_cc310_ecdh_compute
+#define NRF_CRYPTO_BACKEND_SECP224K1_ECDH_CONTEXT_SIZE \
+ sizeof(nrf_crypto_backend_cc310_ecdh_compute_context_t)
+typedef nrf_crypto_backend_cc310_ecdh_compute_context_t nrf_crypto_backend_secp224k1_ecdh_context_t;
+#endif // NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_CC310_ECC_SECP224K1)
+
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_CC310_ECC_SECP256K1)
+// Aliases for one common CC310 implementation
+#define nrf_crypto_backend_secp256k1_ecdh_compute nrf_crypto_backend_cc310_ecdh_compute
+#define NRF_CRYPTO_BACKEND_SECP256K1_ECDH_CONTEXT_SIZE \
+ sizeof(nrf_crypto_backend_cc310_ecdh_compute_context_t)
+typedef nrf_crypto_backend_cc310_ecdh_compute_context_t nrf_crypto_backend_secp256k1_ecdh_context_t;
+#endif // NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_CC310_ECC_SECP256K1)
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // NRF_MODULE_ENABLED(NRF_CRYPTO) && NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_CC310)
+
+#endif // CC310_BACKEND_ECDH_H__
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/cc310/cc310_backend_ecdsa.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/cc310/cc310_backend_ecdsa.c
new file mode 100644
index 0000000..69a1a86
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/cc310/cc310_backend_ecdsa.c
@@ -0,0 +1,223 @@
+/**
+ * Copyright (c) 2018 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+
+#include "sdk_config.h"
+#include "nordic_common.h"
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO) && NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_CC310)
+
+#include <string.h>
+#include "ssi_pal_types.h"
+#include "ssi_pal_mem.h"
+#include "sns_silib.h"
+#include "crys_rnd.h"
+#include "crys_ecpki_ecdsa.h"
+#include "crys_ecpki_error.h"
+#include "crys_kdf_error.h"
+#include "crys_hash_error.h"
+#include "nrf_crypto_error.h"
+#include "nrf_crypto_ecc_shared.h"
+#include "nrf_crypto_ecdsa_shared.h"
+#include "nrf_crypto_ecdsa.h"
+#include "cc310_backend_ecdsa.h"
+#include "cc310_backend_shared.h"
+#include "cc310_backend_mutex.h"
+
+
+#define CC310_SHA1_DIGEST_SIZE (160 / 8) /**< @internal @brief Digest size of SHA-1 */
+#define CC310_SHA224_DIGEST_SIZE (224 / 8) /**< @internal @brief Digest size of SHA-224 */
+#define CC310_SHA256_DIGEST_SIZE (256 / 8) /**< @internal @brief Digest size of SHA-256 */
+#define CC310_SHA384_DIGEST_SIZE (384 / 8) /**< @internal @brief Digest size of SHA-384 */
+#define CC310_SHA512_DIGEST_SIZE (512 / 8) /**< @internal @brief Digest size of SHA-512 */
+
+
+/** @internal @brief Returns enum value of @ref CRYS_ECPKI_HASH_OpMode_t based on provided hash size.
+ *
+ * @param[in] data_size Hash size
+ * @return Value from @ref CRYS_ECPKI_HASH_OpMode_t or CRYS_ECPKI_HASH_OpModeLast if
+ * cannot find implemented hash with provided size.
+ */
+static CRYS_ECPKI_HASH_OpMode_t hash_mode_from_size(uint32_t data_size)
+{
+ CRYS_ECPKI_HASH_OpMode_t hash_mode;
+
+ switch (data_size)
+ {
+ case CC310_SHA1_DIGEST_SIZE:
+ hash_mode = CRYS_ECPKI_AFTER_HASH_SHA1_mode;
+ break;
+
+ case CC310_SHA224_DIGEST_SIZE:
+ hash_mode = CRYS_ECPKI_AFTER_HASH_SHA224_mode;
+ break;
+
+ case CC310_SHA256_DIGEST_SIZE:
+ hash_mode = CRYS_ECPKI_AFTER_HASH_SHA256_mode;
+ break;
+
+ case CC310_SHA384_DIGEST_SIZE:
+ hash_mode = CRYS_ECPKI_AFTER_HASH_SHA384_mode;
+ break;
+
+ case CC310_SHA512_DIGEST_SIZE:
+ hash_mode = CRYS_ECPKI_AFTER_HASH_SHA512_mode;
+ break;
+
+ default:
+ hash_mode = CRYS_ECPKI_HASH_OpModeLast;
+ break;
+ }
+
+ return hash_mode;
+}
+
+
+ret_code_t nrf_crypto_backend_cc310_sign(
+ void * p_context,
+ void const * p_private_key,
+ uint8_t const * p_data,
+ size_t data_size,
+ uint8_t * p_signature)
+{
+ ret_code_t result;
+ CRYSError_t crys_error;
+ uint32_t signature_size;
+ CRYS_ECPKI_HASH_OpMode_t hash_mode = hash_mode_from_size(data_size);
+ bool mutex_locked;
+
+ nrf_crypto_backend_cc310_sign_context_t * p_ctx =
+ (nrf_crypto_backend_cc310_sign_context_t *)p_context;
+
+ nrf_crypto_backend_cc310_ecc_private_key_t * p_prv =
+ (nrf_crypto_backend_cc310_ecc_private_key_t *)p_private_key;
+
+ nrf_crypto_ecc_curve_info_t const * p_info = p_prv->header.p_info;
+
+ if (hash_mode == CRYS_ECPKI_HASH_OpModeLast)
+ {
+ return NRF_ERROR_CRYPTO_INPUT_LENGTH;
+ }
+
+ signature_size = p_info->raw_public_key_size;
+
+ mutex_locked = cc310_backend_mutex_trylock();
+ VERIFY_TRUE(mutex_locked, NRF_ERROR_CRYPTO_BUSY);
+
+ cc310_backend_enable();
+
+ crys_error = CRYS_ECDSA_Sign(p_context,
+ nrf_crypto_backend_cc310_rng,
+ &p_ctx->user_context,
+ &p_prv->private_key,
+ hash_mode,
+ (uint8_t *)p_data,
+ data_size,
+ p_signature,
+ &signature_size);
+
+ cc310_backend_disable();
+
+ cc310_backend_mutex_unlock();
+
+ result = nrf_crypto_backend_cc310_ecc_error_convert(crys_error);
+
+ if (result == NRF_SUCCESS && signature_size != p_info->raw_public_key_size)
+ {
+ return NRF_ERROR_CRYPTO_INTERNAL;
+ }
+
+ return result;
+}
+
+
+ret_code_t nrf_crypto_backend_cc310_verify(
+ void * p_context,
+ void const * p_public_key,
+ uint8_t const * p_data,
+ size_t data_size,
+ uint8_t const * p_signature)
+{
+ ret_code_t result;
+ CRYSError_t crys_error;
+ CRYS_ECPKI_HASH_OpMode_t hash_mode = hash_mode_from_size(data_size);
+ bool mutex_locked;
+
+ nrf_crypto_backend_cc310_verify_context_t * p_ctx =
+ (nrf_crypto_backend_cc310_verify_context_t *)p_context;
+
+ nrf_crypto_backend_cc310_ecc_public_key_t * p_pub =
+ (nrf_crypto_backend_cc310_ecc_public_key_t *)p_public_key;
+
+ nrf_crypto_ecc_curve_info_t const * p_info = p_pub->header.p_info;
+
+ result = nrf_crypto_backend_cc310_ecc_public_key_convert(p_pub, &p_ctx->key_build_temp_data);
+ if (result != NRF_SUCCESS)
+ {
+ return result;
+ }
+
+ if (hash_mode == CRYS_ECPKI_HASH_OpModeLast)
+ {
+ return NRF_ERROR_CRYPTO_INPUT_LENGTH;
+ }
+
+ mutex_locked = cc310_backend_mutex_trylock();
+ VERIFY_TRUE(mutex_locked, NRF_ERROR_CRYPTO_BUSY);
+
+ cc310_backend_enable();
+
+ crys_error = CRYS_ECDSA_Verify(&p_ctx->user_context,
+ &p_pub->key.cc310_public_key,
+ hash_mode,
+ (uint8_t *)p_signature,
+ p_info->raw_public_key_size,
+ (uint8_t *)p_data,
+ data_size);
+
+ cc310_backend_disable();
+
+ cc310_backend_mutex_unlock();
+
+ result = nrf_crypto_backend_cc310_ecc_error_convert(crys_error);
+ return result;
+}
+
+
+#endif // NRF_MODULE_ENABLED(NRF_CRYPTO) && NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_CC310)
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/cc310/cc310_backend_ecdsa.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/cc310/cc310_backend_ecdsa.h
new file mode 100644
index 0000000..b57c18e
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/cc310/cc310_backend_ecdsa.h
@@ -0,0 +1,234 @@
+/**
+ * Copyright (c) 2018 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+
+#ifndef CC310_BACKEND_ECDSA_H__
+#define CC310_BACKEND_ECDSA_H__
+
+#include "sdk_config.h"
+#include "nordic_common.h"
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO) && NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_CC310)
+
+#include "nrf_crypto_ecc_shared.h"
+#include "nrf_crypto_ecdsa_shared.h"
+#include "crys_ecpki_types.h"
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+/** @internal @brief Common structure holding context for ECDSA sign.
+ */
+typedef struct
+{
+ CRYS_ECDSA_SignUserContext_t user_context; /**< @internal @brief Temporary buffer for CC310 internal storage */
+} nrf_crypto_backend_cc310_sign_context_t;
+
+
+/** @internal @brief Common structure holding context for ECDSA verify.
+ */
+typedef union
+{
+ CRYS_ECDSA_VerifyUserContext_t user_context; /**< @internal @brief Temporary buffer for CC310 internal storage */
+ CRYS_ECPKI_BUILD_TempData_t key_build_temp_data; /**< @internal @brief Temporary buffer for CC310 public key build */
+} nrf_crypto_backend_cc310_verify_context_t;
+
+
+/** @internal See @ref nrf_crypto_backend_ecdsa_sign_fn_t.
+ */
+ret_code_t nrf_crypto_backend_cc310_sign(
+ void * p_context,
+ void const * p_private_key,
+ uint8_t const * p_data,
+ size_t data_size,
+ uint8_t * p_signature);
+
+
+/** @internal See @ref nrf_crypto_backend_ecdsa_verify_fn_t.
+ */
+ret_code_t nrf_crypto_backend_cc310_verify(
+ void * p_context,
+ void const * p_public_key,
+ uint8_t const * p_data,
+ size_t data_size,
+ uint8_t const * p_signature);
+
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_CC310_ECC_SECP160R1)
+#define NRF_CRYPTO_BACKEND_SECP160R1_SIGN_CONTEXT_SIZE \
+ sizeof(nrf_crypto_backend_cc310_sign_context_t)
+#define NRF_CRYPTO_BACKEND_SECP160R1_VERIFY_CONTEXT_SIZE \
+ sizeof(nrf_crypto_backend_cc310_verify_context_t)
+typedef nrf_crypto_backend_cc310_sign_context_t nrf_crypto_backend_secp160r1_sign_context_t;
+typedef nrf_crypto_backend_cc310_verify_context_t nrf_crypto_backend_secp160r1_verify_context_t;
+#define nrf_crypto_backend_secp160r1_sign nrf_crypto_backend_cc310_sign
+#define nrf_crypto_backend_secp160r1_verify nrf_crypto_backend_cc310_verify
+#endif
+
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_CC310_ECC_SECP160R2)
+#define NRF_CRYPTO_BACKEND_SECP160R2_SIGN_CONTEXT_SIZE \
+ sizeof(nrf_crypto_backend_cc310_sign_context_t)
+#define NRF_CRYPTO_BACKEND_SECP160R2_VERIFY_CONTEXT_SIZE \
+ sizeof(nrf_crypto_backend_cc310_verify_context_t)
+typedef nrf_crypto_backend_cc310_sign_context_t nrf_crypto_backend_secp160r2_sign_context_t;
+typedef nrf_crypto_backend_cc310_verify_context_t nrf_crypto_backend_secp160r2_verify_context_t;
+#define nrf_crypto_backend_secp160r2_sign nrf_crypto_backend_cc310_sign
+#define nrf_crypto_backend_secp160r2_verify nrf_crypto_backend_cc310_verify
+#endif
+
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_CC310_ECC_SECP192R1)
+#define NRF_CRYPTO_BACKEND_SECP192R1_SIGN_CONTEXT_SIZE \
+ sizeof(nrf_crypto_backend_cc310_sign_context_t)
+#define NRF_CRYPTO_BACKEND_SECP192R1_VERIFY_CONTEXT_SIZE \
+ sizeof(nrf_crypto_backend_cc310_verify_context_t)
+typedef nrf_crypto_backend_cc310_sign_context_t nrf_crypto_backend_secp192r1_sign_context_t;
+typedef nrf_crypto_backend_cc310_verify_context_t nrf_crypto_backend_secp192r1_verify_context_t;
+#define nrf_crypto_backend_secp192r1_sign nrf_crypto_backend_cc310_sign
+#define nrf_crypto_backend_secp192r1_verify nrf_crypto_backend_cc310_verify
+#endif
+
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_CC310_ECC_SECP224R1)
+#define NRF_CRYPTO_BACKEND_SECP224R1_SIGN_CONTEXT_SIZE \
+ sizeof(nrf_crypto_backend_cc310_sign_context_t)
+#define NRF_CRYPTO_BACKEND_SECP224R1_VERIFY_CONTEXT_SIZE \
+ sizeof(nrf_crypto_backend_cc310_verify_context_t)
+typedef nrf_crypto_backend_cc310_sign_context_t nrf_crypto_backend_secp224r1_sign_context_t;
+typedef nrf_crypto_backend_cc310_verify_context_t nrf_crypto_backend_secp224r1_verify_context_t;
+#define nrf_crypto_backend_secp224r1_sign nrf_crypto_backend_cc310_sign
+#define nrf_crypto_backend_secp224r1_verify nrf_crypto_backend_cc310_verify
+#endif
+
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_CC310_ECC_SECP256R1)
+#define NRF_CRYPTO_BACKEND_SECP256R1_SIGN_CONTEXT_SIZE \
+ sizeof(nrf_crypto_backend_cc310_sign_context_t)
+#define NRF_CRYPTO_BACKEND_SECP256R1_VERIFY_CONTEXT_SIZE \
+ sizeof(nrf_crypto_backend_cc310_verify_context_t)
+typedef nrf_crypto_backend_cc310_sign_context_t nrf_crypto_backend_secp256r1_sign_context_t;
+typedef nrf_crypto_backend_cc310_verify_context_t nrf_crypto_backend_secp256r1_verify_context_t;
+#define nrf_crypto_backend_secp256r1_sign nrf_crypto_backend_cc310_sign
+#define nrf_crypto_backend_secp256r1_verify nrf_crypto_backend_cc310_verify
+#endif
+
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_CC310_ECC_SECP384R1)
+#define NRF_CRYPTO_BACKEND_SECP384R1_SIGN_CONTEXT_SIZE \
+ sizeof(nrf_crypto_backend_cc310_sign_context_t)
+#define NRF_CRYPTO_BACKEND_SECP384R1_VERIFY_CONTEXT_SIZE \
+ sizeof(nrf_crypto_backend_cc310_verify_context_t)
+typedef nrf_crypto_backend_cc310_sign_context_t nrf_crypto_backend_secp384r1_sign_context_t;
+typedef nrf_crypto_backend_cc310_verify_context_t nrf_crypto_backend_secp384r1_verify_context_t;
+#define nrf_crypto_backend_secp384r1_sign nrf_crypto_backend_cc310_sign
+#define nrf_crypto_backend_secp384r1_verify nrf_crypto_backend_cc310_verify
+#endif
+
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_CC310_ECC_SECP521R1)
+#define NRF_CRYPTO_BACKEND_SECP521R1_SIGN_CONTEXT_SIZE \
+ sizeof(nrf_crypto_backend_cc310_sign_context_t)
+#define NRF_CRYPTO_BACKEND_SECP521R1_VERIFY_CONTEXT_SIZE \
+ sizeof(nrf_crypto_backend_cc310_verify_context_t)
+typedef nrf_crypto_backend_cc310_sign_context_t nrf_crypto_backend_secp521r1_sign_context_t;
+typedef nrf_crypto_backend_cc310_verify_context_t nrf_crypto_backend_secp521r1_verify_context_t;
+#define nrf_crypto_backend_secp521r1_sign nrf_crypto_backend_cc310_sign
+#define nrf_crypto_backend_secp521r1_verify nrf_crypto_backend_cc310_verify
+#endif
+
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_CC310_ECC_SECP160K1)
+#define NRF_CRYPTO_BACKEND_SECP160K1_SIGN_CONTEXT_SIZE \
+ sizeof(nrf_crypto_backend_cc310_sign_context_t)
+#define NRF_CRYPTO_BACKEND_SECP160K1_VERIFY_CONTEXT_SIZE \
+ sizeof(nrf_crypto_backend_cc310_verify_context_t)
+typedef nrf_crypto_backend_cc310_sign_context_t nrf_crypto_backend_secp160k1_sign_context_t;
+typedef nrf_crypto_backend_cc310_verify_context_t nrf_crypto_backend_secp160k1_verify_context_t;
+#define nrf_crypto_backend_secp160k1_sign nrf_crypto_backend_cc310_sign
+#define nrf_crypto_backend_secp160k1_verify nrf_crypto_backend_cc310_verify
+#endif
+
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_CC310_ECC_SECP192K1)
+#define NRF_CRYPTO_BACKEND_SECP192K1_SIGN_CONTEXT_SIZE \
+ sizeof(nrf_crypto_backend_cc310_sign_context_t)
+#define NRF_CRYPTO_BACKEND_SECP192K1_VERIFY_CONTEXT_SIZE \
+ sizeof(nrf_crypto_backend_cc310_verify_context_t)
+typedef nrf_crypto_backend_cc310_sign_context_t nrf_crypto_backend_secp192k1_sign_context_t;
+typedef nrf_crypto_backend_cc310_verify_context_t nrf_crypto_backend_secp192k1_verify_context_t;
+#define nrf_crypto_backend_secp192k1_sign nrf_crypto_backend_cc310_sign
+#define nrf_crypto_backend_secp192k1_verify nrf_crypto_backend_cc310_verify
+#endif
+
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_CC310_ECC_SECP224K1)
+#define NRF_CRYPTO_BACKEND_SECP224K1_SIGN_CONTEXT_SIZE \
+ sizeof(nrf_crypto_backend_cc310_sign_context_t)
+#define NRF_CRYPTO_BACKEND_SECP224K1_VERIFY_CONTEXT_SIZE \
+ sizeof(nrf_crypto_backend_cc310_verify_context_t)
+typedef nrf_crypto_backend_cc310_sign_context_t nrf_crypto_backend_secp224k1_sign_context_t;
+typedef nrf_crypto_backend_cc310_verify_context_t nrf_crypto_backend_secp224k1_verify_context_t;
+#define nrf_crypto_backend_secp224k1_sign nrf_crypto_backend_cc310_sign
+#define nrf_crypto_backend_secp224k1_verify nrf_crypto_backend_cc310_verify
+#endif
+
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_CC310_ECC_SECP256K1)
+#define NRF_CRYPTO_BACKEND_SECP256K1_SIGN_CONTEXT_SIZE \
+ sizeof(nrf_crypto_backend_cc310_sign_context_t)
+#define NRF_CRYPTO_BACKEND_SECP256K1_VERIFY_CONTEXT_SIZE \
+ sizeof(nrf_crypto_backend_cc310_verify_context_t)
+typedef nrf_crypto_backend_cc310_sign_context_t nrf_crypto_backend_secp256k1_sign_context_t;
+typedef nrf_crypto_backend_cc310_verify_context_t nrf_crypto_backend_secp256k1_verify_context_t;
+#define nrf_crypto_backend_secp256k1_sign nrf_crypto_backend_cc310_sign
+#define nrf_crypto_backend_secp256k1_verify nrf_crypto_backend_cc310_verify
+#endif
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // NRF_MODULE_ENABLED(NRF_CRYPTO) && NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_CC310)
+
+#endif // CC310_BACKEND_ECDSA_H__
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/cc310/cc310_backend_hash.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/cc310/cc310_backend_hash.c
new file mode 100644
index 0000000..b1f91e1
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/cc310/cc310_backend_hash.c
@@ -0,0 +1,311 @@
+/**
+ * Copyright (c) 2018 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+
+#include "sdk_common.h"
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO) && NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_CC310)
+
+#include "nrf.h"
+#include "cc310_backend_hash.h"
+#include "crys_hash.h"
+#include "crys_hash_error.h"
+#include "nrf_crypto_init.h"
+#include "nrf_crypto_types.h"
+#include "nrf_crypto_error.h"
+#include "nrf_crypto_hash_shared.h"
+#include "sdk_macros.h"
+#include "nrf_log.h"
+#include "nrf_assert.h"
+#include "cc310_backend_mutex.h"
+#include "cc310_backend_shared.h"
+#include <drivers/nrfx_common.h>
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_CC310_HASH_SHA256) || \
+ NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_CC310_HASH_SHA512)
+
+static ret_code_t hash_result_get(CRYSError_t error)
+{
+ ret_code_t ret_val;
+
+ switch (error)
+ {
+ case CRYS_OK:
+ ret_val = NRF_SUCCESS;
+ break;
+
+ case CRYS_HASH_INVALID_USER_CONTEXT_POINTER_ERROR:
+ ret_val = NRF_ERROR_CRYPTO_CONTEXT_NULL;
+ break;
+
+ case CRYS_HASH_ILLEGAL_OPERATION_MODE_ERROR:
+ ret_val = NRF_ERROR_CRYPTO_FEATURE_UNAVAILABLE;
+ break;
+
+ case CRYS_HASH_USER_CONTEXT_CORRUPTED_ERROR:
+ ret_val = NRF_ERROR_CRYPTO_CONTEXT_NOT_INITIALIZED;
+ break;
+
+ // May be added to specialized errors for hash.
+ case CRYS_HASH_LAST_BLOCK_ALREADY_PROCESSED_ERROR:
+ ret_val = NRF_ERROR_CRYPTO_INTERNAL;
+ break;
+
+ case CRYS_HASH_IS_NOT_SUPPORTED:
+ ret_val = NRF_ERROR_CRYPTO_FEATURE_UNAVAILABLE;
+ break;
+
+ default:
+ ret_val = NRF_ERROR_CRYPTO_INTERNAL;
+ break;
+ }
+
+ return ret_val;
+}
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_CC310_HASH_SHA256)
+
+static ret_code_t cc310_backend_hash_sha256_init(void * const p_context)
+{
+ uint32_t ret_val;
+ CRYSError_t crys_error;
+ CRYS_HASH_OperationMode_t hash_mode = CRYS_HASH_SHA256_mode;
+
+ // No parameter testing on this level.
+ // This has been done on upper level.
+
+ CRYS_HASHUserContext_t * const p_backend_context
+ = &(((nrf_crypto_backend_hash_sha256_context_t *)p_context)->context);
+
+ crys_error = CRYS_HASH_Init(p_backend_context, hash_mode);
+
+ ret_val = hash_result_get(crys_error);
+
+ return ret_val;
+}
+
+
+static ret_code_t cc310_backend_hash_sha256_update(void * const p_context,
+ uint8_t const * p_data,
+ size_t size)
+{
+ ret_code_t ret_val;
+ CRYSError_t crys_error;
+ bool mutex_locked;
+ size_t cur_len;
+ size_t len_left = size;
+ uint8_t const * p_cur = p_data;
+
+ // Limited parameter testing on this level.
+ // This has been done on upper level.
+
+ CRYS_HASHUserContext_t * const p_backend_context
+ = &(((nrf_crypto_backend_hash_sha256_context_t *)p_context)->context);
+
+ // Data in flash could lead to silently calculating wrong Hash.
+ VERIFY_TRUE(nrfx_is_in_ram(p_data), NRF_ERROR_CRYPTO_INPUT_LOCATION);
+
+ mutex_locked = cc310_backend_mutex_trylock();
+ VERIFY_TRUE(mutex_locked, NRF_ERROR_CRYPTO_BUSY);
+
+ cc310_backend_enable();
+
+ // If the input is larger than CC310_MAX_LENGTH_DMA_OPERATIONS, split into smaller
+ do
+ {
+ cur_len = (len_left > CC310_MAX_LENGTH_DMA_OPERATIONS) ?
+ CC310_MAX_LENGTH_DMA_OPERATIONS : len_left;
+
+ crys_error = CRYS_HASH_Update(p_backend_context, (uint8_t *)p_cur, cur_len);
+
+ len_left -= cur_len;
+ p_cur += cur_len;
+
+ } while (crys_error == CRYS_OK && len_left > 0);
+
+ cc310_backend_disable();
+
+ cc310_backend_mutex_unlock();
+
+ ret_val = hash_result_get(crys_error);
+
+
+ return ret_val;
+}
+
+
+static ret_code_t cc310_backend_hash_sha256_finalize(void * const p_context,
+ uint8_t * p_digest,
+ size_t * const p_digest_size)
+{
+ ret_code_t ret_val;
+ CRYSError_t crys_error;
+ bool mutex_locked;
+ CRYS_HASH_Result_t * p_int_digest = (CRYS_HASH_Result_t *)p_digest;
+
+ // Limited parameter testing on this level.
+ // This has been done on upper level.
+
+ CRYS_HASHUserContext_t * const p_backend_context
+ = &(((nrf_crypto_backend_hash_sha256_context_t * )p_context)->context);
+
+ mutex_locked = cc310_backend_mutex_trylock();
+ VERIFY_TRUE(mutex_locked, NRF_ERROR_CRYPTO_BUSY);
+
+ // Do the hash finalize calculation
+ cc310_backend_enable();
+
+ crys_error = CRYS_HASH_Finish(p_backend_context, *p_int_digest);
+
+ cc310_backend_disable();
+
+ cc310_backend_mutex_unlock();
+
+ ret_val = hash_result_get(crys_error);
+ if (ret_val == NRF_SUCCESS)
+ {
+ *p_digest_size = NRF_CRYPTO_HASH_SIZE_SHA256;
+ }
+
+ return ret_val;
+}
+
+
+const nrf_crypto_hash_info_t g_nrf_crypto_hash_sha256_info =
+{
+ .init_fn = cc310_backend_hash_sha256_init,
+ .update_fn = cc310_backend_hash_sha256_update,
+ .finalize_fn = cc310_backend_hash_sha256_finalize,
+ .digest_size = NRF_CRYPTO_HASH_SIZE_SHA256,
+ .context_size = sizeof(nrf_crypto_backend_hash_sha256_context_t),
+ .hash_mode = NRF_CRYPTO_HASH_MODE_SHA256
+};
+
+#endif // NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_CC310_HASH_SHA256)
+
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_CC310_HASH_SHA512)
+
+// SHA-512 does not use CC310 hardware and therefore will not use a mutex lock
+
+static ret_code_t cc310_backend_hash_sha512_init(void * p_context)
+{
+ uint32_t ret_val;
+ CRYSError_t crys_error;
+ CRYS_HASH_OperationMode_t hash_mode = CRYS_HASH_SHA512_mode;
+
+ // No parameter testing on this level.
+ // This has been done on upper level.
+
+ CRYS_HASHUserContext_t * const p_backend_context
+ = &(((nrf_crypto_backend_hash_sha512_context_t * ) p_context)->context);
+
+ crys_error = CRYS_HASH_Init(p_backend_context, hash_mode);
+ ret_val = hash_result_get(crys_error);
+
+ return ret_val;
+}
+
+
+static ret_code_t cc310_backend_hash_sha512_update(void * const p_context,
+ uint8_t const * p_data,
+ size_t size)
+{
+ ret_code_t ret_val;
+ CRYSError_t crys_error;
+
+ // Limited parameter testing on this level.
+ // This has been done on upper level.
+
+ CRYS_HASHUserContext_t * const p_backend_context
+ = &(((nrf_crypto_backend_hash_sha512_context_t *)p_context)->context);
+
+ // Data in flash could lead to silently calculating wrong Hash.
+ VERIFY_TRUE(nrfx_is_in_ram(p_data), NRF_ERROR_CRYPTO_INPUT_LOCATION);
+
+ crys_error = CRYS_HASH_Update(p_backend_context, (uint8_t *)p_data, size);
+
+ ret_val = hash_result_get(crys_error);
+
+ return ret_val;
+}
+
+
+static ret_code_t cc310_backend_hash_sha512_finalize(void * const p_context,
+ uint8_t * p_digest,
+ size_t * const p_digest_size)
+{
+ ret_code_t ret_val;
+ CRYSError_t crys_error;
+ CRYS_HASH_Result_t * p_int_digest = (CRYS_HASH_Result_t *)p_digest;
+
+ // Limited parameter testing on this level.
+ // This has been done on upper level.
+
+ CRYS_HASHUserContext_t * const p_backend_context
+ = &(((nrf_crypto_backend_hash_sha512_context_t *) p_context)->context);
+
+ crys_error = CRYS_HASH_Finish(p_backend_context, *p_int_digest);
+ ret_val = hash_result_get(crys_error);
+
+ if (ret_val == NRF_SUCCESS)
+ {
+ *p_digest_size = NRF_CRYPTO_HASH_SIZE_SHA512;
+ }
+
+ return ret_val;
+}
+
+
+const nrf_crypto_hash_info_t g_nrf_crypto_hash_sha512_info =
+{
+ .init_fn = cc310_backend_hash_sha512_init,
+ .update_fn = cc310_backend_hash_sha512_update,
+ .finalize_fn = cc310_backend_hash_sha512_finalize,
+ .digest_size = NRF_CRYPTO_HASH_SIZE_SHA512,
+ .context_size = sizeof(nrf_crypto_backend_hash_sha512_context_t),
+ .hash_mode = NRF_CRYPTO_HASH_MODE_SHA512
+};
+
+
+#endif // NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_CC310_HASH_SHA512)
+
+#endif // NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_CC310_HASH_SHA256) || NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_CC310_HASH_SHA512)
+
+#endif // NRF_MODULE_ENABLED(NRF_CRYPTO) && #if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_CC310)
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/cc310/cc310_backend_hash.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/cc310/cc310_backend_hash.h
new file mode 100644
index 0000000..3da4dd3
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/cc310/cc310_backend_hash.h
@@ -0,0 +1,122 @@
+/**
+ * Copyright (c) 2018 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+
+#ifndef CC310_BACKEND_HASH_H__
+#define CC310_BACKEND_HASH_H__
+
+/** @file
+ *
+ * @defgroup nrf_crypto_cc310_backend_hash nrf_crypto CC310 backend hash
+ * @{
+ * @ingroup nrf_crypto_cc310_backend
+ *
+ * @brief Hash functionality provided by the nrf_crypto CC310 backend.
+ */
+
+#include "sdk_common.h"
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_CC310)
+
+#include "sdk_errors.h"
+#include "nrf_crypto_hash_shared.h"
+#include "crys_hash.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_CC310_HASH_SHA256)
+
+// Flag that nrf_crypto_hash frontend can be compiled
+#undef NRF_CRYPTO_HASH_ENABLED
+#define NRF_CRYPTO_HASH_ENABLED 1
+
+// Flag that SHA-256 is enabled in backend
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_HASH_SHA256)
+#error "Duplicate definition of SHA-256. More than one backend enabled");
+#endif
+#define NRF_CRYPTO_HASH_SHA256_ENABLED 1
+
+
+/**@internal @brief nrf_crypto_hash context for SHA-256 in nrf_crypto CC310 backend. */
+typedef struct
+{
+ nrf_crypto_hash_internal_context_t header; /**< Common header for context. */
+ CRYS_HASHUserContext_t context; /**< Hash context internal to CC310. */
+} nrf_crypto_backend_hash_sha256_context_t;
+
+
+#endif // NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_CC310_HASH_SHA256)
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_CC310_HASH_SHA512)
+
+// Flag that nrf_crypto_hash frontend can be compiled
+#undef NRF_CRYPTO_HASH_ENABLED
+#define NRF_CRYPTO_HASH_ENABLED 1
+
+// Duplicate backend enabled test for SHA-512
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_HASH_SHA512)
+#error "Duplicate definition of SHA-512. More than one backend enabled");
+#endif
+
+// Flag that SHA-512 is enabled in backend
+#define NRF_CRYPTO_HASH_SHA512_ENABLED 1
+
+
+/**@internal @brief nrf_crypto_hash context for SHA-512 in nrf_crypto CC310 backend. */
+typedef struct
+{
+ nrf_crypto_hash_internal_context_t header; /**< Common header for context. */
+ CRYS_HASHUserContext_t context; /**< Hash context internal to CC310. */
+} nrf_crypto_backend_hash_sha512_context_t;
+
+
+#endif // NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_CC310_HASH_SHA512)
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_CC310)
+
+/**@} */
+
+#endif // CC310_BACKEND_HASH_H__
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/cc310/cc310_backend_hmac.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/cc310/cc310_backend_hmac.c
new file mode 100644
index 0000000..2e909f9
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/cc310/cc310_backend_hmac.c
@@ -0,0 +1,273 @@
+/**
+ * Copyright (c) 2018 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+
+#include "sdk_common.h"
+#if NRF_MODULE_ENABLED(NRF_CRYPTO) && NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_CC310)
+
+#include "sdk_common.h"
+#include "nrf_log.h"
+#include "nrf_crypto_hmac_shared.h"
+#include "cc310_backend_hmac.h"
+#include "nrf_crypto_error.h"
+#include "nrf_crypto_types.h"
+#include <drivers/nrfx_common.h>
+#include "crys_hmac.h"
+#include "crys_hmac_defs.h"
+#include "crys_hmac_error.h"
+#include "crys_hash.h"
+#include "cc310_backend_mutex.h"
+#include "cc310_backend_shared.h"
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_CC310_HMAC_SHA256) || \
+ NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_CC310_HMAC_SHA512)
+
+static ret_code_t result_get(CRYSError_t err_code)
+{
+ ret_code_t ret_val;
+
+ switch (err_code)
+ {
+ case CRYS_OK:
+ ret_val = NRF_SUCCESS;
+ break;
+
+ case CRYS_HMAC_INVALID_USER_CONTEXT_POINTER_ERROR:
+ ret_val = NRF_ERROR_CRYPTO_CONTEXT_NULL;
+ break;
+
+ case CRYS_HMAC_USER_CONTEXT_CORRUPTED_ERROR:
+ ret_val = NRF_ERROR_CRYPTO_CONTEXT_NOT_INITIALIZED;
+ break;
+
+ case CRYS_HMAC_DATA_IN_POINTER_INVALID_ERROR:
+ case CRYS_HMAC_INVALID_KEY_POINTER_ERROR:
+ ret_val = NRF_ERROR_CRYPTO_INPUT_NULL;
+ break;
+
+ case CRYS_HMAC_INVALID_RESULT_BUFFER_POINTER_ERROR:
+ ret_val = NRF_ERROR_CRYPTO_OUTPUT_NULL;
+ break;
+
+ case CRYS_HMAC_ILLEGAL_PARAMS_ERROR:
+ ret_val = NRF_ERROR_CRYPTO_INVALID_PARAM;
+ break;
+
+ case CRYS_HMAC_UNVALID_KEY_SIZE_ERROR:
+ case CRYS_HMAC_DATA_SIZE_ILLEGAL:
+ ret_val = NRF_ERROR_CRYPTO_INPUT_LENGTH;
+ break;
+
+ case CRYS_HMAC_ILLEGAL_OPERATION_MODE_ERROR:
+ case CRYS_HMAC_LAST_BLOCK_ALREADY_PROCESSED_ERROR:
+ case CRYS_HMAC_IS_NOT_SUPPORTED:
+ case CRYS_HMAC_CTX_SIZES_ERROR:
+ default:
+ ret_val = NRF_ERROR_CRYPTO_INTERNAL;
+ break;
+ }
+ return ret_val;
+}
+
+
+static ret_code_t cc310_backend_hmac_init(void * const p_context,
+ uint8_t const * p_key,
+ size_t key_size)
+{
+ CRYSError_t err_code;
+ CRYS_HASH_OperationMode_t hash_mode;
+ ret_code_t ret_val;
+ bool mutex_locked;
+
+
+ nrf_crypto_backend_cc310_hmac_context_t * p_ctx =
+ (nrf_crypto_backend_cc310_hmac_context_t *)p_context;
+
+ switch (p_ctx->header.p_info->type)
+ {
+ case NRF_CRYPTO_HMAC_SHA256_TYPE:
+ {
+ hash_mode = CRYS_HASH_SHA256_mode;
+ } break;
+ case NRF_CRYPTO_HMAC_SHA512_TYPE:
+ {
+ hash_mode = CRYS_HASH_SHA512_mode;
+ } break;
+ default:
+ {
+ NRF_LOG_ERROR("Hash algorithm not supported by CC310 backend wrapper");
+ return NRF_ERROR_CRYPTO_FEATURE_UNAVAILABLE;
+ }
+ }
+
+ // Key in flash could lead to silently calculating wrong HMAC.
+ VERIFY_TRUE(nrfx_is_in_ram(p_key), NRF_ERROR_CRYPTO_INPUT_LOCATION);
+
+ mutex_locked = cc310_backend_mutex_trylock();
+ VERIFY_TRUE(mutex_locked, NRF_ERROR_CRYPTO_BUSY);
+
+ cc310_backend_enable();
+
+ err_code = CRYS_HMAC_Init(&p_ctx->crys_context, hash_mode, (uint8_t *)p_key, key_size);
+
+ cc310_backend_disable();
+
+ cc310_backend_mutex_unlock();
+
+ ret_val = result_get(err_code);
+
+ return ret_val;
+}
+
+
+static ret_code_t cc310_backend_hmac_update(void * const p_context,
+ uint8_t const * p_data,
+ size_t size)
+{
+ CRYSError_t err_code;
+ ret_code_t ret_val;
+ bool mutex_locked;
+ size_t cur_len;
+ size_t len_left = size;
+ uint8_t const * p_cur = p_data;
+
+ nrf_crypto_backend_cc310_hmac_context_t * p_ctx =
+ (nrf_crypto_backend_cc310_hmac_context_t *)p_context;
+
+ // Data in flash could lead to silently calculating wrong HMAC.
+ VERIFY_TRUE(nrfx_is_in_ram(p_data), NRF_ERROR_CRYPTO_INPUT_LOCATION);
+
+ mutex_locked = cc310_backend_mutex_trylock();
+ VERIFY_TRUE(mutex_locked, NRF_ERROR_CRYPTO_BUSY);
+
+ cc310_backend_enable();
+
+ // If the input is larger than CC310_MAX_LENGTH_DMA_OPERATIONS, split into smaller
+ do
+ {
+ cur_len = (len_left > CC310_MAX_LENGTH_DMA_OPERATIONS) ?
+ CC310_MAX_LENGTH_DMA_OPERATIONS : len_left;
+
+ err_code = CRYS_HMAC_Update(&p_ctx->crys_context, (uint8_t *)p_cur, cur_len);
+
+ len_left -= cur_len;
+ p_cur += cur_len;
+
+ } while (err_code == CRYS_OK && len_left > 0);
+
+ cc310_backend_disable();
+
+ cc310_backend_mutex_unlock();
+
+ ret_val = result_get(err_code);
+
+ return ret_val;
+}
+
+
+static ret_code_t cc310_backend_hmac_finalize(void * const p_context,
+ uint8_t * p_digest,
+ size_t * const p_size)
+{
+ CRYSError_t err_code;
+ ret_code_t ret_val;
+ bool mutex_locked;
+
+ nrf_crypto_backend_cc310_hmac_context_t * p_ctx =
+ (nrf_crypto_backend_cc310_hmac_context_t *)p_context;
+
+ // Set the digest length to 0 so that this is used in case of any error.
+ *p_size = 0;
+
+ mutex_locked = cc310_backend_mutex_trylock();
+ VERIFY_TRUE(mutex_locked, NRF_ERROR_CRYPTO_BUSY);
+
+ cc310_backend_enable();
+
+ err_code = CRYS_HMAC_Finish(&p_ctx->crys_context, p_ctx->crys_result);
+
+ cc310_backend_disable();
+
+ cc310_backend_mutex_unlock();
+
+ ret_val = result_get(err_code);
+ if (err_code != NRF_SUCCESS)
+ {
+ return ret_val;
+ }
+
+ *p_size = p_ctx->header.p_info->digest_size;
+
+ memcpy(p_digest, p_ctx->crys_result, *p_size);
+
+ return ret_val;
+}
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_CC310_HMAC_SHA256)
+
+// Information structure for HMAC SHA256 using CC310 backend.
+const nrf_crypto_hmac_info_t g_nrf_crypto_hmac_sha256_info =
+{
+ .init_fn = cc310_backend_hmac_init,
+ .update_fn = cc310_backend_hmac_update,
+ .finalize_fn = cc310_backend_hmac_finalize,
+ .digest_size = NRF_CRYPTO_HASH_SIZE_SHA256,
+ .context_size = sizeof(nrf_crypto_backend_hmac_sha256_context_t),
+ .type = NRF_CRYPTO_HMAC_SHA256_TYPE,
+};
+
+#endif // NRF_CRYPTO_BACKEND_CC310_HMAC_SHA256_ENABLED
+
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_CC310_HMAC_SHA512)
+
+// Information structure for HMAC SHA512 using CC310 backend.
+const nrf_crypto_hmac_info_t g_nrf_crypto_hmac_sha512_info =
+{
+ .init_fn = cc310_backend_hmac_init,
+ .update_fn = cc310_backend_hmac_update,
+ .finalize_fn = cc310_backend_hmac_finalize,
+ .digest_size = NRF_CRYPTO_HASH_SIZE_SHA512,
+ .context_size = sizeof(nrf_crypto_backend_hmac_sha512_context_t),
+ .type = NRF_CRYPTO_HMAC_SHA512_TYPE,
+};
+
+#endif // NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_CC310_HMAC_SHA512)
+#endif // NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_CC310_HMAC_SHA256) || NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_CC310_HMAC_SHA512)
+#endif // NRF_MODULE_ENABLED(NRF_CRYPTO) && NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_CC310)
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/cc310/cc310_backend_hmac.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/cc310/cc310_backend_hmac.h
new file mode 100644
index 0000000..ea065f1
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/cc310/cc310_backend_hmac.h
@@ -0,0 +1,123 @@
+/**
+ * Copyright (c) 2018 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+
+#ifndef CC310_BACKEND_HMAC_H__
+#define CC310_BACKEND_HMAC_H__
+
+/** @file
+ *
+ * @defgroup nrf_crypto_cc310_backend_hmac CC310 backend for HMAC
+ * @{
+ * @ingroup nrf_crypto_cc310_backend
+ *
+ * @brief Backend wrapper for CryptoCell (CC310). None of these types should be used directly by the
+ * application.
+ */
+
+#include "sdk_common.h"
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_CC310) && \
+ ( NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_CC310_HMAC_SHA256) || \
+ NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_CC310_HMAC_SHA512) )
+
+#include "nrf_crypto_hmac_shared.h"
+#include "crys_hmac.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#undef NRF_CRYPTO_HMAC_ENABLED
+#define NRF_CRYPTO_HMAC_ENABLED 1
+
+
+/**
+ * @internal @brief Internal context object used by the CC310 backend wrapper.
+ *
+ * @details The same type is used for all variants (hash types).
+ *
+ * @note This should never be used directly. Use @ref nrf_crypto_backend_hmac_sha256_context_t or
+ * @ref nrf_crypto_backend_hmac_sha512_context_t instead.
+ */
+typedef struct
+{
+ nrf_crypto_hmac_internal_context_t header; //!< Internal nrf_crypto_hmac context header.
+ CRYS_HMACUserContext_t crys_context; //!< CC310 context object.
+ CRYS_HASH_Result_t crys_result; //!< Temporary result buffer needed as CC310 always requires a result buffer of 64 bytes, even when actual result is smaller.
+} nrf_crypto_backend_cc310_hmac_context_t;
+
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_CC310_HMAC_SHA256)
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_HMAC_SHA256)
+#error "Duplicate definition of HMAC SHA-256. More than one backend enabled"
+#endif // NRF_CRYPTO_HMAC_SHA256_ENABLED
+#define NRF_CRYPTO_HMAC_SHA256_ENABLED 1
+
+/**
+ * @internal @brief Context for HMAC SHA256 using CC310 backend.
+ */
+typedef nrf_crypto_backend_cc310_hmac_context_t nrf_crypto_backend_hmac_sha256_context_t;
+
+#endif // NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_CC310_HMAC_SHA256)
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_CC310_HMAC_SHA512)
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_HMAC_SHA512)
+#error "Duplicate definition of HMAC SHA-512. More than one backend enabled"
+#endif // NRF_CRYPTO_HMAC_SHA512_ENABLED
+#define NRF_CRYPTO_HMAC_SHA512_ENABLED 1
+
+/**
+ * @internal @brief Context for HMAC SHA512 using CC310 backend.
+ */
+typedef nrf_crypto_backend_cc310_hmac_context_t nrf_crypto_backend_hmac_sha512_context_t;
+
+#endif // NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_CC310_HMAC_SHA256)
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_CC310) && ( NRF_MODULE_ENABLED((NRF_CRYPTO_BACKEND_CC310_HMAC_SHA256) || NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_CC310_HMAC_SHA512) )
+
+/**@} */
+
+#endif // CC310_BACKEND_HMAC_H__
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/cc310/cc310_backend_init.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/cc310/cc310_backend_init.c
new file mode 100644
index 0000000..d930436
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/cc310/cc310_backend_init.c
@@ -0,0 +1,151 @@
+/**
+ * Copyright (c) 2018 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+
+#include "sdk_common.h"
+#if NRF_MODULE_ENABLED(NRF_CRYPTO) && NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_CC310)
+
+#include "nrf.h"
+#include "nrf_crypto_init.h"
+#include "cc310_backend_shared.h"
+#include "sns_silib.h"
+#include "cc310_backend_mutex.h"
+#include "nrf_crypto_rng.h"
+
+/**@internal @brief Function to enable CC310 (in HW)
+ */
+void cc310_backend_enable(void);
+
+
+/**@internal @brief Function to disable CC310 (in HW)
+ */
+void cc310_backend_disable(void);
+
+static uint32_t init_result_get(uint32_t crys_error)
+{
+ uint32_t ret_val = NRF_ERROR_INTERNAL;
+ switch (crys_error)
+ {
+ case CRYS_OK:
+ ret_val = NRF_SUCCESS;
+ break;
+
+ default:
+ ret_val = NRF_ERROR_INTERNAL;
+ break;
+ }
+
+ return ret_val;
+}
+
+static ret_code_t cc310_backend_init(void)
+{
+ uint32_t ret_val;
+ CRYSError_t crys_error;
+
+ cc310_backend_mutex_init();
+
+ // Enable the CC310 HW.
+ NRF_CRYPTOCELL->ENABLE = 1;
+
+ // Initialize the CC310 run-time library
+ crys_error = SaSi_LibInit();
+
+ // Shut down CC310 after initialization.
+ NRF_CRYPTOCELL->ENABLE = 0;
+
+ ret_val = init_result_get(crys_error);
+ VERIFY_SUCCESS(ret_val);
+
+#if defined(NRF_CRYPTO_RNG_AUTO_INIT_ENABLED) && (NRF_CRYPTO_RNG_AUTO_INIT_ENABLED == 1)
+
+ ret_val = nrf_crypto_rng_init(NULL, NULL);
+ VERIFY_SUCCESS(ret_val);
+
+#elif defined(NRF_CRYPTO_RNG_AUTO_INIT_ENABLED) && (NRF_CRYPTO_RNG_AUTO_INIT_ENABLED == 0)
+
+ // Do nothing
+
+#else
+
+ #warning NRF_CRYPTO_RNG_AUTO_INIT_ENABLED define not found in sdk_config.h (Is the sdk_config.h valid?).
+
+#endif // NRF_CRYPTO_RNG_AUTO_INIT_ENABLED
+
+ return ret_val;
+}
+
+
+static ret_code_t cc310_backend_uninit(void)
+{
+#if defined(NRF_CRYPTO_RNG_AUTO_INIT_ENABLED) && (NRF_CRYPTO_RNG_AUTO_INIT_ENABLED == 1)
+
+ uint32_t ret_val;
+ ret_val = nrf_crypto_rng_init(NULL, NULL);
+ VERIFY_SUCCESS(ret_val);
+
+#elif defined(NRF_CRYPTO_RNG_AUTO_INIT_ENABLED) && (NRF_CRYPTO_RNG_AUTO_INIT_ENABLED == 0)
+
+ // Do nothing
+
+#else
+
+ #warning NRF_CRYPTO_RNG_AUTO_INIT_ENABLED define not found in sdk_config.h (Is the sdk_config.h valid?).
+
+#endif // NRF_CRYPTO_RNG_AUTO_INIT_ENABLED
+
+ // Initialize the CC310 HW to do shutdown.
+ NRF_CRYPTOCELL->ENABLE = 1;
+
+ SaSi_LibFini();
+
+ // Shut down CC310 after shutdown.
+ NRF_CRYPTOCELL->ENABLE = 0;
+
+ return NRF_SUCCESS;
+}
+
+
+CRYPTO_BACKEND_REGISTER(nrf_crypto_backend_info_t const cc310_backend) =
+{
+ .init_fn = cc310_backend_init,
+ .uninit_fn = cc310_backend_uninit,
+};
+
+#endif // NRF_MODULE_ENABLED(NRF_CRYPTO) && NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_CC310)
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/cc310/cc310_backend_mutex.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/cc310/cc310_backend_mutex.c
new file mode 100644
index 0000000..f383251
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/cc310/cc310_backend_mutex.c
@@ -0,0 +1,53 @@
+/**
+ * Copyright (c) 2018 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+
+#include "sdk_common.h"
+#include <drivers/nrfx_common.h>
+#if NRF_MODULE_ENABLED(NRF_CRYPTO)
+
+#include <stdbool.h>
+#include "cc310_backend_mutex.h"
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_CC310)
+
+nrf_mtx_t g_cc310_mutex;
+
+#endif // NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_CC310)
+#endif // NRF_MODULE_ENABLED(NRF_CRYPTO)
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/cc310/cc310_backend_mutex.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/cc310/cc310_backend_mutex.h
new file mode 100644
index 0000000..3cd6241
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/cc310/cc310_backend_mutex.h
@@ -0,0 +1,111 @@
+/**
+ * Copyright (c) 2018 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+
+#ifndef CC310_BACKEND_MUTEX_H__
+#define CC310_BACKEND_MUTEX_H__
+
+/** @file
+ *
+ * @defgroup nrf_crypto_cc310_backend_mutex nrf_crypto CC310 backend mutex.
+ * @{
+ * @ingroup nrf_crypto_cc310_backend
+ *
+ * @brief Mutex control for the nrf_crypto CC310 backend.
+ */
+
+#include "sdk_config.h"
+#include "nrf_mtx.h"
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_CC310) || NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_CC310_BL)
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+extern nrf_mtx_t g_cc310_mutex;
+
+__STATIC_INLINE void cc310_backend_mutex_init(void);
+__STATIC_INLINE bool cc310_backend_mutex_trylock(void);
+__STATIC_INLINE void cc310_backend_mutex_unlock(void);
+
+#ifndef SUPPRESS_INLINE_IMPLEMENTATION
+/**@internal @brief Function initializing CC310 mutex.
+ *
+ * This function _must_ be called before other mutex operations.
+ */
+__STATIC_INLINE void cc310_backend_mutex_init(void)
+{
+ nrf_mtx_init(&g_cc310_mutex);
+}
+
+/**@internal @brief Function try to lock a CC310 mutex.
+ *
+ * @return true if lock was acquired, false if not.
+ */
+__STATIC_INLINE bool cc310_backend_mutex_trylock(void)
+{
+ return nrf_mtx_trylock(&g_cc310_mutex);
+}
+
+
+/**@internal @brief Unlock a CC310 mutex.
+ *
+ * This function _must_ only be called when holding the lock. Unlocking a mutex which you do not
+ * hold will give undefined behavior.
+ *
+ */
+__STATIC_INLINE void cc310_backend_mutex_unlock(void)
+{
+ nrf_mtx_unlock(&g_cc310_mutex);
+}
+
+#endif // SUPPRESS_INLINE_IMPLEMENTATION
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_CC310) || NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_CC310_BL)
+
+/** @} */
+
+#endif // CC310_BACKEND_MUTEX_H__
+
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/cc310/cc310_backend_rng.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/cc310/cc310_backend_rng.c
new file mode 100644
index 0000000..25fd96e
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/cc310/cc310_backend_rng.c
@@ -0,0 +1,272 @@
+/**
+ * Copyright (c) 2018 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+
+#include "sdk_common.h"
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO)
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_CC310)
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_CC310_RNG)
+
+#include "nrf_crypto_error.h"
+#include "nrf_log.h"
+#include "cc310_backend_mutex.h"
+#include "cc310_backend_rng.h"
+#include "crys_rnd.h"
+#include "crys_rnd_error.h"
+#include "cc310_backend_shared.h"
+
+static ret_code_t result_get(CRYSError_t err_code)
+{
+ ret_code_t ret_val;
+
+ switch (err_code)
+ {
+ case CRYS_OK:
+ ret_val = NRF_SUCCESS;
+ break;
+
+ case CRYS_RND_ILLEGAL_PARAMETER_ERROR:
+ ret_val = NRF_ERROR_CRYPTO_INVALID_PARAM;
+ break;
+
+ case CRYS_RND_INIT_FAILED:
+ case CRYS_RND_STARTUP_FAILED:
+ case CRYS_RND_INSTANTIATION_ERROR:
+ ret_val = NRF_ERROR_CRYPTO_RNG_INIT_FAILED;
+ break;
+
+ case CRYS_RND_IS_NOT_SUPPORTED:
+ case CRYS_RND_CAN_NOT_GENERATE_RAND_IN_RANGE:
+ case CRYS_RND_TRNG_KAT_NOT_SUPPORTED_ERROR:
+ case CRYS_RND_SRAM_NOT_SUPPORTED_ERROR:
+ case CRYS_RND_OPERATION_IS_NOT_SUPPORTED_ERROR:
+ ret_val = NRF_ERROR_CRYPTO_FEATURE_UNAVAILABLE;
+ break;
+
+ case CRYS_RND_DATA_OUT_POINTER_INVALID_ERROR:
+ case CRYS_RND_VECTOR_OUT_PTR_ERROR:
+ ret_val = NRF_ERROR_CRYPTO_OUTPUT_NULL;
+ break;
+
+ case CRYS_RND_ADDITIONAL_INPUT_BUFFER_NULL:
+ case CRYS_RND_WORK_BUFFER_PTR_INVALID_ERROR:
+ case CRYS_RND_ILLEGAL_DATA_PTR_ERROR:
+ ret_val = NRF_ERROR_CRYPTO_INPUT_NULL;
+ break;
+
+ case CRYS_RND_DATA_SIZE_OVERFLOW_ERROR:
+ case CRYS_RND_ADDITIONAL_INPUT_SIZE_ERROR:
+ case CRYS_RND_ILLEGAL_DATA_SIZE_ERROR:
+ case CRYS_RND_MAX_VECTOR_IS_TOO_SMALL_ERROR:
+ ret_val = NRF_ERROR_CRYPTO_INPUT_LENGTH;
+ break;
+
+ case CRYS_RND_ILLEGAL_AES_KEY_SIZE_ERROR:
+ case CRYS_RND_VECTOR_OUT_SIZE_ERROR:
+ case CRYS_RND_VECTOR_SIZE_ERROR:
+ ret_val = NRF_ERROR_CRYPTO_OUTPUT_LENGTH;
+ break;
+
+ case CRYS_RND_CONTEXT_PTR_INVALID_ERROR:
+ case CRYS_RND_STATE_PTR_INVALID_ERROR:
+ ret_val = NRF_ERROR_CRYPTO_CONTEXT_NULL;
+ break;
+
+ case CRYS_RND_INSTANTIATION_NOT_DONE_ERROR:
+ ret_val = NRF_ERROR_CRYPTO_CONTEXT_NOT_INITIALIZED;
+ break;
+
+ case CRYS_RND_RESEED_COUNTER_OVERFLOW_ERROR:
+ ret_val = NRF_ERROR_CRYPTO_RNG_RESEED_REQUIRED;
+ break;
+
+ case CRYS_RND_CPRNG_TEST_FAIL_ERROR:
+ case CRYS_RND_TRNG_LOSS_SAMPLES_ERROR:
+ case CRYS_RND_TRNG_TIME_EXCEED_ERROR:
+ case CRYS_RND_TRNG_LOSS_SAMPLES_AND_TIME_EXCEED_ERROR:
+ case CRYS_RND_IS_KAT_MODE_ERROR:
+ case CRYS_RND_STATE_VALIDATION_TAG_ERROR:
+ case CRYS_RND_GEN_VECTOR_FUNC_ERROR:
+ case CRYS_RND_TRNG_ERRORS_ERROR:
+ case CRYS_RND_KAT_DATA_PARAMS_ERROR:
+ case CRYS_RND_AES_ERROR:
+ default:
+ ret_val = NRF_ERROR_CRYPTO_INTERNAL;
+ break;
+ }
+ return ret_val;
+}
+
+
+ret_code_t nrf_crypto_rng_backend_init(void * const p_context,
+ void * const p_temp_buffer)
+{
+ bool mutex_locked;
+ CRYSError_t err_code;
+ ret_code_t ret_val;
+ CRYS_RND_WorkBuff_t * p_work_buffer = (CRYS_RND_WorkBuff_t *)p_temp_buffer;
+ nrf_crypto_backend_rng_context_t * p_ctx = (nrf_crypto_backend_rng_context_t *)p_context;
+
+ // Save time by not reinitializing an already valid CC310 RNG context.
+ // (Useful for example in case the context was stored in retained memory during system OFF.)
+ if (p_ctx->header.init_value == NRF_CRYPTO_RNG_CONTEXT_INIT_MAGIC_VALUE)
+ {
+ return NRF_SUCCESS;
+ }
+
+ mutex_locked = cc310_backend_mutex_trylock();
+ VERIFY_TRUE(mutex_locked, NRF_ERROR_CRYPTO_BUSY);
+
+ cc310_backend_enable();
+
+ err_code = CRYS_RndInit(&p_ctx->crys_rnd_state, p_work_buffer);
+ ret_val = result_get(err_code);
+
+ cc310_backend_disable();
+
+ cc310_backend_mutex_unlock();
+
+ return ret_val;
+}
+
+
+ret_code_t nrf_crypto_rng_backend_uninit(void * const p_context)
+{
+ bool mutex_locked;
+ CRYSError_t err_code;
+ ret_code_t ret_val;
+ CRYS_RND_State_t * p_crys_rnd_state =
+ &((nrf_crypto_backend_rng_context_t *)p_context)->crys_rnd_state;
+
+
+ mutex_locked = cc310_backend_mutex_trylock();
+ VERIFY_TRUE(mutex_locked, NRF_ERROR_CRYPTO_BUSY);
+
+ cc310_backend_enable();
+
+ err_code = CRYS_RND_UnInstantiation(p_crys_rnd_state);
+
+ cc310_backend_disable();
+
+ ret_val = result_get(err_code);
+
+ cc310_backend_mutex_unlock();
+
+ return ret_val;
+}
+
+
+ret_code_t nrf_crypto_rng_backend_vector_generate(void * const p_context,
+ uint8_t * const p_target,
+ size_t size,
+ bool use_mutex)
+{
+ bool mutex_locked;
+ CRYSError_t err_code;
+ ret_code_t ret_val;
+ CRYS_RND_State_t * p_crys_rnd_state =
+ &((nrf_crypto_backend_rng_context_t *)p_context)->crys_rnd_state;
+
+ if (use_mutex)
+ {
+ mutex_locked = cc310_backend_mutex_trylock();
+ VERIFY_TRUE(mutex_locked, NRF_ERROR_CRYPTO_BUSY);
+ }
+
+ cc310_backend_enable();
+
+ err_code = CRYS_RND_GenerateVector(p_crys_rnd_state, size, p_target);
+
+ cc310_backend_disable();
+
+ ret_val = result_get(err_code);
+
+ if (use_mutex)
+ {
+ cc310_backend_mutex_unlock();
+ }
+
+ return ret_val;
+}
+
+
+ret_code_t nrf_crypto_rng_backend_reseed(void * const p_context,
+ void * p_temp_buffer,
+ uint8_t * p_input_data,
+ size_t size)
+{
+ bool mutex_locked;
+ CRYSError_t err_code;
+ ret_code_t ret_val = NRF_SUCCESS;
+ CRYS_RND_WorkBuff_t * p_work_buffer = (CRYS_RND_WorkBuff_t *)p_temp_buffer;
+ CRYS_RND_State_t * p_crys_rnd_state =
+ &((nrf_crypto_backend_rng_context_t *)p_context)->crys_rnd_state;
+
+ VERIFY_TRUE(size <= CRYS_RND_ADDITINAL_INPUT_MAX_SIZE_WORDS, NRF_ERROR_CRYPTO_INPUT_LENGTH);
+ VERIFY_TRUE((size & 0x3) == 0, NRF_ERROR_CRYPTO_INTERNAL);
+
+ mutex_locked = cc310_backend_mutex_trylock();
+ VERIFY_TRUE(mutex_locked, NRF_ERROR_CRYPTO_BUSY);
+
+ cc310_backend_enable();
+
+ if (size > 0)
+ {
+ err_code = CRYS_RND_AddAdditionalInput(p_crys_rnd_state, p_input_data, size);
+ ret_val = result_get(err_code);
+ if (ret_val != NRF_SUCCESS)
+ {
+ goto exit;
+ }
+ }
+
+ err_code = CRYS_RND_Reseeding(p_crys_rnd_state, p_work_buffer);
+ ret_val = result_get(err_code);
+
+exit:
+ cc310_backend_disable();
+ cc310_backend_mutex_unlock();
+ return ret_val;
+}
+
+
+#endif // NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_CC310_RNG)
+#endif // NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_CC310)
+#endif // NRF_MODULE_ENABLED(NRF_CRYPTO)
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/cc310/cc310_backend_rng.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/cc310/cc310_backend_rng.h
new file mode 100644
index 0000000..ab1806a
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/cc310/cc310_backend_rng.h
@@ -0,0 +1,97 @@
+/**
+ * Copyright (c) 2018 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+
+#ifndef CC310_BACKEND_RNG_H__
+#define CC310_BACKEND_RNG_H__
+
+/** @file
+ *
+ * @defgroup nrf_crypto_cc310_backend_rng nRF Crypto CC310 RNG backend
+ * @{
+ * @ingroup nrf_crypto_cc310_backend
+ *
+ * @brief RNG functionality provided by the nrf_crypto CC310 backend.
+ */
+
+#include "sdk_common.h"
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_CC310)
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_CC310_RNG)
+
+#include "nrf_crypto_rng_shared.h"
+#include "crys_rnd.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_RNG)
+#error "More than one RNG backend enabled."
+#endif // NRF_MODULE_ENABLED(NRF_CRYPTO_RNG)
+#define NRF_CRYPTO_RNG_ENABLED 1
+
+
+/**
+ * @internal @brief Internal context for CC310 RNG.
+ */
+typedef struct
+{
+ nrf_crypto_rng_internal_context_t header; //!< Internal common context header.
+ CRYS_RND_State_t crys_rnd_state; //!< CC310 RNG context
+} nrf_crypto_backend_rng_context_t;
+
+
+/**
+ * @internal @brief Temporary work buffer needed during initialization of the CC310 backend.
+ */
+typedef CRYS_RND_WorkBuff_t nrf_crypto_backend_rng_temp_buffer_t;
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_CC310_RNG)
+#endif // NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_CC310)
+
+/**@} */
+
+#endif // CC310_BACKEND_RNG_H__
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/cc310/cc310_backend_shared.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/cc310/cc310_backend_shared.c
new file mode 100644
index 0000000..d5f2351
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/cc310/cc310_backend_shared.c
@@ -0,0 +1,115 @@
+/**
+ * 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+
+#include "sdk_common.h"
+#if NRF_MODULE_ENABLED(NRF_CRYPTO) && NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_CC310)
+
+#include "nrf.h"
+#include "cc310_backend_shared.h"
+#include "nrf_crypto_error.h"
+#include "nrf_crypto_rng.h"
+#include "crys_rnd_error.h"
+#include "nrf_crypto_shared.h"
+#include "cc310_backend_shared.h"
+
+
+static uint32_t m_use_count = 0;
+
+void cc310_backend_enable(void)
+{
+ m_use_count++;
+
+ if (m_use_count == 1)
+ {
+ // Enable the CryptoCell hardware
+ NRF_CRYPTOCELL->ENABLE = 1;
+
+ // Enable the CryptoCell IRQ
+ NVIC_EnableIRQ(CRYPTOCELL_IRQn);
+ }
+}
+
+void cc310_backend_disable(void)
+{
+ m_use_count--;
+
+ // If no more users. Disable HW/IRQ
+ if (m_use_count == 0)
+ {
+ // Disable the CryptoCell hardware
+ NRF_CRYPTOCELL->ENABLE = 0;
+
+ // Disable the CryptoCell IRQ
+ NVIC_DisableIRQ(CRYPTOCELL_IRQn);
+ }
+}
+
+
+uint32_t nrf_crypto_backend_cc310_rng(void * p_state, uint16_t size, uint8_t * p_data)
+{
+#if defined(NRF_CRYPTO_RNG_ENABLED) && (NRF_CRYPTO_RNG_ENABLED == 1)
+
+ ret_code_t result = nrf_crypto_rng_vector_generate_no_mutex(p_data, (size_t)size);
+ if (result == NRF_SUCCESS)
+ {
+ return CRYS_OK;
+ }
+ else if (result == NRF_ERROR_CRYPTO_CONTEXT_NOT_INITIALIZED)
+ {
+ return CRYS_RND_INSTANTIATION_NOT_DONE_ERROR;
+ }
+ else
+ {
+ return CRYS_RND_IS_NOT_SUPPORTED;
+ }
+
+#elif defined(NRF_CRYPTO_RNG_ENABLED) && (NRF_CRYPTO_RNG_ENABLED == 0)
+
+ return NRF_ERROR_CRYPTO_FEATURE_UNAVAILABLE;
+
+#else
+
+ #warning NRF_CRYPTO_RNG_ENABLED define not found in sdk_config.h (Is the sdk_config.h valid?).
+
+#endif // NRF_CRYPTO_RNG_ENABLED
+}
+
+
+#endif // NRF_MODULE_ENABLED(NRF_CRYPTO) && NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_CC310)
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/cc310/cc310_backend_shared.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/cc310/cc310_backend_shared.h
new file mode 100644
index 0000000..56fae0e
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/cc310/cc310_backend_shared.h
@@ -0,0 +1,87 @@
+/**
+ * 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+
+#ifndef CC310_BACKEND_SHARED_H__
+#define CC310_BACKEND_SHARED_H__
+
+/** @file
+ *
+ * @defgroup nrf_crypto_cc310_backend_shared nrf_crypto CC310 backend shared
+ * @{
+ * @ingroup nrf_crypto_cc310_backend
+ *
+ * @brief Shared functionality for the nrf_crypto CC310 backend.
+ */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**@internal @brief Macro definition for largest possible input data on CC310 DMA. */
+#define CC310_MAX_LENGTH_DMA_OPERATIONS (0xFFFF)
+#define CC310_MAX_LENGTH_DMA_AES_OPERATIONS (0xFFF0)
+
+
+/**@internal @brief Function to enable CC310 (in HW)
+ */
+void cc310_backend_enable(void);
+
+
+/**@internal @brief Function to disable CC310 (in HW)
+ */
+void cc310_backend_disable(void);
+
+
+/**@internal @brief Function to pass to CC310 library API as random number generator. It uses
+ * nrf_crypto libary frontend API to generate random number.
+ * @param[in,out] p_state Unused. Required by CC310 library API.
+ * @param[in] size Number of bytes in generated vector.
+ * @param[out] p_data Place where generated bytes will be written.
+ */
+uint32_t nrf_crypto_backend_cc310_rng(void * p_state, uint16_t size, uint8_t * p_data);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+/**@} */
+
+#endif // CC310_BACKEND_SHARED_H__
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/cc310_bl/cc310_bl_backend_ecc.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/cc310_bl/cc310_bl_backend_ecc.c
new file mode 100644
index 0000000..cec2ec7
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/cc310_bl/cc310_bl_backend_ecc.c
@@ -0,0 +1,165 @@
+/**
+ * Copyright (c) 2018 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+
+#include "sdk_config.h"
+#include "nordic_common.h"
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO) && NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_CC310_BL)
+
+#include <string.h>
+
+#include "nrf_crypto_mem.h"
+#include "nrf_crypto_ecc.h"
+#include "nrf_crypto_shared.h"
+#include "cc310_bl_backend_ecc.h"
+
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_CC310_BL_ECC_LITTLE_ENDIAN)
+#define ENDIAN_MEM_COPY nrf_crypto_internal_swap_endian
+#else
+#define ENDIAN_MEM_COPY memcpy
+#endif
+
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_CC310_BL_ECC_SECP224R1)
+
+
+ret_code_t nrf_crypto_backend_secp224r1_public_key_from_raw(
+ void * p_public_key,
+ uint8_t const * p_raw_data)
+{
+ nrf_crypto_backend_secp224r1_public_key_t * p_pub =
+ (nrf_crypto_backend_secp224r1_public_key_t *)p_public_key;
+
+ ENDIAN_MEM_COPY(&p_pub->public_key.x[0],
+ &p_raw_data[0],
+ NRF_CRYPTO_ECC_SECP224R1_RAW_PRIVATE_KEY_SIZE);
+ ENDIAN_MEM_COPY(&p_pub->public_key.y[0],
+ &p_raw_data[NRF_CRYPTO_ECC_SECP224R1_RAW_PRIVATE_KEY_SIZE],
+ NRF_CRYPTO_ECC_SECP224R1_RAW_PRIVATE_KEY_SIZE);
+
+ return NRF_SUCCESS;
+}
+
+
+ret_code_t nrf_crypto_backend_secp224r1_public_key_to_raw(
+ void const * p_public_key,
+ uint8_t * p_raw_data)
+{
+ nrf_crypto_backend_secp224r1_public_key_t const * p_pub =
+ (nrf_crypto_backend_secp224r1_public_key_t const *)p_public_key;
+
+ ENDIAN_MEM_COPY(&p_raw_data[0],
+ &p_pub->public_key.x[0],
+ NRF_CRYPTO_ECC_SECP224R1_RAW_PRIVATE_KEY_SIZE);
+ ENDIAN_MEM_COPY(&p_raw_data[NRF_CRYPTO_ECC_SECP224R1_RAW_PRIVATE_KEY_SIZE],
+ &p_pub->public_key.y[0],
+ NRF_CRYPTO_ECC_SECP224R1_RAW_PRIVATE_KEY_SIZE);
+
+ return NRF_SUCCESS;
+}
+
+
+nrf_crypto_ecc_curve_info_t const g_nrf_crypto_ecc_secp224r1_curve_info =
+{
+ .public_key_size = sizeof(nrf_crypto_backend_secp224r1_public_key_t),
+ .private_key_size = 0,
+ .curve_type = NRF_CRYPTO_ECC_SECP224R1_CURVE_TYPE,
+ .raw_private_key_size = NRF_CRYPTO_ECC_SECP224R1_RAW_PRIVATE_KEY_SIZE,
+ .raw_public_key_size = NRF_CRYPTO_ECC_SECP224R1_RAW_PUBLIC_KEY_SIZE,
+};
+
+
+#endif // NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_CC310_BL_ECC_SECP224R1)
+
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_CC310_BL_ECC_SECP256R1)
+
+
+ret_code_t nrf_crypto_backend_secp256r1_public_key_from_raw(
+ void * p_public_key,
+ uint8_t const * p_raw_data)
+{
+ nrf_crypto_backend_secp256r1_public_key_t * p_pub =
+ (nrf_crypto_backend_secp256r1_public_key_t *)p_public_key;
+
+ ENDIAN_MEM_COPY(&p_pub->public_key.x[0],
+ &p_raw_data[0],
+ NRF_CRYPTO_ECC_SECP256R1_RAW_PRIVATE_KEY_SIZE);
+ ENDIAN_MEM_COPY(&p_pub->public_key.y[0],
+ &p_raw_data[NRF_CRYPTO_ECC_SECP256R1_RAW_PRIVATE_KEY_SIZE],
+ NRF_CRYPTO_ECC_SECP256R1_RAW_PRIVATE_KEY_SIZE);
+
+ return NRF_SUCCESS;
+}
+
+
+ret_code_t nrf_crypto_backend_secp256r1_public_key_to_raw(
+ void const * p_public_key,
+ uint8_t * p_raw_data)
+{
+ nrf_crypto_backend_secp256r1_public_key_t const * p_pub =
+ (nrf_crypto_backend_secp256r1_public_key_t const *)p_public_key;
+
+ ENDIAN_MEM_COPY(&p_raw_data[0],
+ &p_pub->public_key.x[0],
+ NRF_CRYPTO_ECC_SECP256R1_RAW_PRIVATE_KEY_SIZE);
+ ENDIAN_MEM_COPY(&p_raw_data[NRF_CRYPTO_ECC_SECP256R1_RAW_PRIVATE_KEY_SIZE],
+ &p_pub->public_key.y[0],
+ NRF_CRYPTO_ECC_SECP256R1_RAW_PRIVATE_KEY_SIZE);
+
+ return NRF_SUCCESS;
+}
+
+
+nrf_crypto_ecc_curve_info_t const g_nrf_crypto_ecc_secp256r1_curve_info =
+{
+ .public_key_size = sizeof(nrf_crypto_backend_secp256r1_public_key_t),
+ .private_key_size = 0,
+ .curve_type = NRF_CRYPTO_ECC_SECP256R1_CURVE_TYPE,
+ .raw_private_key_size = NRF_CRYPTO_ECC_SECP256R1_RAW_PRIVATE_KEY_SIZE,
+ .raw_public_key_size = NRF_CRYPTO_ECC_SECP256R1_RAW_PUBLIC_KEY_SIZE,
+};
+
+
+#endif // NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_CC310_BL_ECC_SECP256R1)
+
+
+#endif // NRF_MODULE_ENABLED(NRF_CRYPTO) && NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_CC310_BL)
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/cc310_bl/cc310_bl_backend_ecc.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/cc310_bl/cc310_bl_backend_ecc.h
new file mode 100644
index 0000000..381c642
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/cc310_bl/cc310_bl_backend_ecc.h
@@ -0,0 +1,155 @@
+/**
+ * Copyright (c) 2018 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+
+#ifndef CC310_BL_BACKEND_ECC_H__
+#define CC310_BL_BACKEND_ECC_H__
+
+#include "sdk_config.h"
+#include "nordic_common.h"
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO) && NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_CC310_BL)
+
+#include "nrf_crypto_ecc_shared.h"
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_CC310_BL_ECC_SECP224R1)
+#include "nrf_cc310_bl_ecdsa_verify_secp224r1.h"
+#endif
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_CC310_BL_ECC_SECP256R1)
+#include "nrf_cc310_bl_ecdsa_verify_secp256r1.h"
+#endif
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_CC310_BL_ECC_SECP224R1)
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_ECC_SECP224R1)
+#error "More than one backend enabled for secp224r1 (NIST 224-bit).");
+#endif
+#define NRF_CRYPTO_ECC_SECP224R1_ENABLED 1
+
+typedef struct
+{
+ nrf_crypto_internal_ecc_key_header_t header; /**< @internal @brief Common ECC key header */
+ nrf_cc310_bl_ecc_public_key_secp224r1_t public_key; /**< @internal @brief CC310_BL specific key representation */
+} nrf_crypto_backend_secp224r1_public_key_t;
+
+/** @internal See @ref nrf_crypto_backend_ecc_public_key_from_raw_fn_t.
+*/
+ret_code_t nrf_crypto_backend_secp224r1_public_key_from_raw(
+ void * p_public_key,
+ uint8_t const * p_raw_data);
+
+/** @internal See @ref nrf_crypto_backend_ecc_public_key_to_raw_fn_t.
+*/
+ret_code_t nrf_crypto_backend_secp224r1_public_key_to_raw(
+ void const * p_public_key,
+ uint8_t * p_raw_data);
+
+// Dummy and empty definitions for unused symbols
+#define nrf_crypto_backend_secp224r1_key_pair_generate NULL
+#define nrf_crypto_backend_secp224r1_public_key_calculate NULL
+#define nrf_crypto_backend_secp224r1_private_key_from_raw NULL
+#define nrf_crypto_backend_secp224r1_private_key_to_raw NULL
+#define nrf_crypto_backend_secp224r1_private_key_free NULL
+#define nrf_crypto_backend_secp224r1_public_key_free NULL
+
+#define NRF_CRYPTO_BACKEND_SECP224R1_KEY_PAIR_GENERATE_CONTEXT_SIZE 0
+#define NRF_CRYPTO_BACKEND_SECP224R1_PUBLIC_KEY_CALCULATE_CONTEXT_SIZE 0
+
+typedef uint32_t nrf_crypto_backend_secp224r1_private_key_t;
+typedef uint32_t nrf_crypto_backend_secp224r1_key_pair_generate_context_t;
+typedef uint32_t nrf_crypto_backend_secp224r1_public_key_calculate_context_t;
+
+#endif // NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_CC310_BL_ECC_SECP224R1)
+
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_CC310_BL_ECC_SECP256R1)
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_ECC_SECP256R1)
+#error "More than one backend enabled for secp256r1 (NIST 256-bit).");
+#endif
+#define NRF_CRYPTO_ECC_SECP256R1_ENABLED 1
+
+typedef struct
+{
+ nrf_crypto_internal_ecc_key_header_t header; /**< @internal @brief Common ECC key header */
+ nrf_cc310_bl_ecc_public_key_secp256r1_t public_key; /**< @internal @brief CC310_BL specific key representation */
+} nrf_crypto_backend_secp256r1_public_key_t;
+
+/** @internal See @ref nrf_crypto_backend_ecc_public_key_from_raw_fn_t.
+*/
+ret_code_t nrf_crypto_backend_secp256r1_public_key_from_raw(
+ void * p_public_key,
+ uint8_t const * p_raw_data);
+
+/** @internal See @ref nrf_crypto_backend_ecc_public_key_to_raw_fn_t.
+*/
+ret_code_t nrf_crypto_backend_secp256r1_public_key_to_raw(
+ void const * p_public_key,
+ uint8_t * p_raw_data);
+
+// Dummy and empty definitions for unused symbols
+#define nrf_crypto_backend_secp256r1_key_pair_generate NULL
+#define nrf_crypto_backend_secp256r1_public_key_calculate NULL
+#define nrf_crypto_backend_secp256r1_private_key_from_raw NULL
+#define nrf_crypto_backend_secp256r1_private_key_to_raw NULL
+#define nrf_crypto_backend_secp256r1_private_key_free NULL
+#define nrf_crypto_backend_secp256r1_public_key_free NULL
+
+#define NRF_CRYPTO_BACKEND_SECP256R1_KEY_PAIR_GENERATE_CONTEXT_SIZE 0
+#define NRF_CRYPTO_BACKEND_SECP256R1_PUBLIC_KEY_CALCULATE_CONTEXT_SIZE 0
+
+typedef uint32_t nrf_crypto_backend_secp256r1_private_key_t;
+typedef uint32_t nrf_crypto_backend_secp256r1_key_pair_generate_context_t;
+typedef uint32_t nrf_crypto_backend_secp256r1_public_key_calculate_context_t;
+
+#endif // NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_CC310_BL_ECC_SECP256R1)
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // NRF_MODULE_ENABLED(NRF_CRYPTO) && NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_CC310_BL)
+
+#endif // CC310_BL_BACKEND_ECC_H__
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/cc310_bl/cc310_bl_backend_ecdh.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/cc310_bl/cc310_bl_backend_ecdh.h
new file mode 100644
index 0000000..ce52194
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/cc310_bl/cc310_bl_backend_ecdh.h
@@ -0,0 +1,75 @@
+/**
+ * Copyright (c) 2018 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+
+#ifndef CC310_BL_BACKEND_ECDH_H__
+#define CC310_BL_BACKEND_ECDH_H__
+
+#include "sdk_config.h"
+#include "nordic_common.h"
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO) && NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_CC310_BL)
+
+#include "nrf_crypto_ecc.h"
+#include "nrf_crypto_ecdh_shared.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_CC310_BL_ECC_SECP224R1)
+#define nrf_crypto_backend_secp224r1_ecdh_compute NULL
+typedef uint32_t nrf_crypto_backend_secp224r1_ecdh_context_t;
+#define NRF_CRYPTO_BACKEND_SECP224R1_ECDH_CONTEXT_SIZE 0
+#endif // NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_CC310_BL_ECC_SECP224R1)
+
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_CC310_BL_ECC_SECP256R1)
+#define nrf_crypto_backend_secp256r1_ecdh_compute NULL
+typedef uint32_t nrf_crypto_backend_secp256r1_ecdh_context_t;
+#define NRF_CRYPTO_BACKEND_SECP256R1_ECDH_CONTEXT_SIZE 0
+#endif // NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_CC310_BL_ECC_SECP256R1)
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // NRF_MODULE_ENABLED(NRF_CRYPTO) && NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_CC310_BL)
+
+#endif // CC310_BL_BACKEND_ECDH_H__
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/cc310_bl/cc310_bl_backend_ecdsa.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/cc310_bl/cc310_bl_backend_ecdsa.c
new file mode 100644
index 0000000..5b99a83
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/cc310_bl/cc310_bl_backend_ecdsa.c
@@ -0,0 +1,267 @@
+/**
+ * Copyright (c) 2018 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+
+#include "sdk_config.h"
+#include "nordic_common.h"
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO) && NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_CC310_BL)
+
+#include <string.h>
+#include "app_util.h"
+#include "nrf_crypto_error.h"
+#include "nrf_crypto_mem.h"
+#include "nrf_crypto_shared.h"
+#include "cc310_bl_backend_ecdsa.h"
+#include "cc310_bl_backend_shared.h"
+#include "cc310_backend_mutex.h"
+#include "crys_ecpki_error.h"
+
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_CC310_BL_ECC_SECP224R1) || \
+ NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_CC310_BL_ECC_SECP256R1)
+
+static ret_code_t crys_error_to_ret_code(CRYSError_t crys_error)
+{
+ switch (crys_error)
+ {
+ case CRYS_OK:
+ return NRF_SUCCESS;
+
+ case CRYS_ECDSA_VERIFY_INCONSISTENT_VERIFY_ERROR:
+ return NRF_ERROR_CRYPTO_ECDSA_INVALID_SIGNATURE;
+
+ default:
+ break;
+ }
+
+ return NRF_ERROR_CRYPTO_INTERNAL;
+}
+
+#endif
+
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_CC310_BL_ECC_SECP224R1)
+
+STATIC_ASSERT(offsetof(nrf_cc310_bl_ecc_signature_secp224r1_t, r) == 0,
+ "Offset of r in nrf_cc310_bl_ecc_signature_secp224r1_t is unexpected");
+STATIC_ASSERT(offsetof(nrf_cc310_bl_ecc_signature_secp224r1_t, s) ==
+ NRF_CRYPTO_ECC_SECP224R1_RAW_PRIVATE_KEY_SIZE,
+ "Offset of s in nrf_cc310_bl_ecc_signature_secp224r1_t is unexpected");
+
+
+ret_code_t nrf_crypto_backend_secp224r1_verify(
+ void * p_context,
+ void const * p_public_key,
+ uint8_t const * p_data,
+ size_t data_size,
+ uint8_t const * p_signature)
+{
+ ret_code_t result;
+ CRYSError_t crys_error;
+ bool mutex_locked;
+
+ nrf_crypto_backend_secp224r1_verify_context_t * p_ctx =
+ (nrf_crypto_backend_secp224r1_verify_context_t *)p_context;
+
+ nrf_crypto_backend_secp224r1_public_key_t * p_pub =
+ (nrf_crypto_backend_secp224r1_public_key_t *)p_public_key;
+
+ p_ctx->user_context.init_val = NRF_CC310_BL_ECDSA_CONTEXT_INITIALIZED;
+
+#if defined(NRF_CRYPTO_BACKEND_CC310_BL_ECC_LITTLE_ENDIAN_ENABLED) && (NRF_CRYPTO_BACKEND_CC310_BL_ECC_LITTLE_ENDIAN_ENABLED == 1)
+
+ size_t hash_size = MIN(data_size, NRF_CRYPTO_ECC_SECP224R1_RAW_PRIVATE_KEY_SIZE);
+ uint8_t * p_hash_and_sig_le =
+ NRF_CRYPTO_ALLOC(hash_size + 2 * NRF_CRYPTO_ECC_SECP224R1_RAW_PRIVATE_KEY_SIZE);
+
+ if (p_hash_and_sig_le == NULL)
+ {
+ return NRF_ERROR_CRYPTO_ALLOC_FAILED;
+ }
+
+ nrf_crypto_internal_swap_endian(p_hash_and_sig_le, p_data, hash_size);
+
+ nrf_crypto_internal_double_swap_endian(&p_hash_and_sig_le[hash_size],
+ p_signature,
+ NRF_CRYPTO_ECC_SECP224R1_RAW_PRIVATE_KEY_SIZE);
+
+ mutex_locked = cc310_backend_mutex_trylock();
+ VERIFY_TRUE(mutex_locked, NRF_ERROR_CRYPTO_BUSY);
+
+ cc310_bl_backend_enable();
+
+ crys_error = nrf_cc310_bl_ecdsa_verify_secp224r1(
+ &p_ctx->user_context,
+ &p_pub->public_key,
+ (nrf_cc310_bl_ecc_signature_secp224r1_t const *)&p_hash_and_sig_le[hash_size],
+ p_hash_and_sig_le,
+ hash_size);
+
+ cc310_bl_backend_disable();
+
+ cc310_backend_mutex_unlock();
+
+ NRF_CRYPTO_FREE(p_hash_and_sig_le);
+
+#elif defined(NRF_CRYPTO_BACKEND_CC310_BL_ECC_LITTLE_ENDIAN_ENABLED) && (NRF_CRYPTO_BACKEND_CC310_BL_ECC_LITTLE_ENDIAN_ENABLED == 0)
+
+ mutex_locked = cc310_backend_mutex_trylock();
+ VERIFY_TRUE(mutex_locked, NRF_ERROR_CRYPTO_BUSY);
+
+ cc310_bl_backend_enable();
+
+ crys_error = nrf_cc310_bl_ecdsa_verify_secp224r1(
+ &p_ctx->user_context,
+ &p_pub->public_key,
+ (nrf_cc310_bl_ecc_signature_secp224r1_t const *)p_signature,
+ p_data,
+ data_size);
+
+ cc310_bl_backend_disable();
+
+ cc310_backend_mutex_unlock();
+
+#else
+
+ #error NRF_CRYPTO_BACKEND_CC310_BL_ECC_LITTLE_ENDIAN_ENABLED define not found in sdk_config.h Inalid sdk_config.h!
+
+#endif
+
+ result = crys_error_to_ret_code(crys_error);
+
+ return result;
+}
+
+
+#endif // NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_CC310_BL_ECC_SECP224R1)
+
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_CC310_BL_ECC_SECP256R1)
+
+
+STATIC_ASSERT(offsetof(nrf_cc310_bl_ecc_signature_secp256r1_t, r) == 0,
+ "Offset of r in nrf_cc310_bl_ecc_signature_secp256r1_t is unexpected");
+
+STATIC_ASSERT(offsetof(nrf_cc310_bl_ecc_signature_secp256r1_t, s) ==
+ NRF_CRYPTO_ECC_SECP256R1_RAW_PRIVATE_KEY_SIZE,
+ "Offset of s in nrf_cc310_bl_ecc_signature_secp256r1_t is unexpected");
+
+
+ret_code_t nrf_crypto_backend_secp256r1_verify(
+ void * p_context,
+ void const * p_public_key,
+ uint8_t const * p_data,
+ size_t data_size,
+ uint8_t const * p_signature)
+{
+ ret_code_t result;
+ CRYSError_t crys_error;
+ bool mutex_locked;
+
+
+ nrf_crypto_backend_secp256r1_verify_context_t * p_ctx =
+ (nrf_crypto_backend_secp256r1_verify_context_t *)p_context;
+
+ nrf_crypto_backend_secp256r1_public_key_t * p_pub =
+ (nrf_crypto_backend_secp256r1_public_key_t *)p_public_key;
+
+ p_ctx->user_context.init_val = NRF_CC310_BL_ECDSA_CONTEXT_INITIALIZED;
+
+#if defined(NRF_CRYPTO_BACKEND_CC310_BL_ECC_LITTLE_ENDIAN_ENABLED) && (NRF_CRYPTO_BACKEND_CC310_BL_ECC_LITTLE_ENDIAN_ENABLED == 1)
+
+ uint8_t hash_le[NRF_CRYPTO_HASH_SIZE_SHA256];
+ uint8_t signature_le[NRF_CRYPTO_ECC_SECP256R1_RAW_PRIVATE_KEY_SIZE * 2];
+ size_t hash_size = MIN(data_size, NRF_CRYPTO_HASH_SIZE_SHA256);
+
+ nrf_crypto_internal_swap_endian(hash_le, p_data, hash_size);
+
+ nrf_crypto_internal_double_swap_endian(signature_le,
+ p_signature,
+ NRF_CRYPTO_ECC_SECP256R1_RAW_PRIVATE_KEY_SIZE);
+
+ mutex_locked = cc310_backend_mutex_trylock();
+ VERIFY_TRUE(mutex_locked, NRF_ERROR_CRYPTO_BUSY);
+
+ cc310_bl_backend_enable();
+
+ crys_error = nrf_cc310_bl_ecdsa_verify_secp256r1(
+ &p_ctx->user_context,
+ &p_pub->public_key,
+ (nrf_cc310_bl_ecc_signature_secp256r1_t const *)signature_le,
+ hash_le,
+ hash_size);
+
+ cc310_bl_backend_disable();
+
+ cc310_backend_mutex_unlock();
+
+#elif defined(NRF_CRYPTO_BACKEND_CC310_BL_ECC_LITTLE_ENDIAN_ENABLED) && (NRF_CRYPTO_BACKEND_CC310_BL_ECC_LITTLE_ENDIAN_ENABLED == 0)
+
+ mutex_locked = cc310_backend_mutex_trylock();
+ VERIFY_TRUE(mutex_locked, NRF_ERROR_CRYPTO_BUSY);
+
+ cc310_bl_backend_enable();
+
+ crys_error = nrf_cc310_bl_ecdsa_verify_secp256r1(
+ &p_ctx->user_context,
+ &p_pub->public_key,
+ (nrf_cc310_bl_ecc_signature_secp256r1_t const *)p_signature,
+ p_data,
+ data_size);
+
+ cc310_bl_backend_disable();
+
+ cc310_backend_mutex_unlock();
+
+#else
+
+ #error NRF_CRYPTO_BACKEND_CC310_BL_ECC_LITTLE_ENDIAN_ENABLED define not found in sdk_config.h. Invalid sdk_config.file!
+
+#endif
+
+ result = crys_error_to_ret_code(crys_error);
+
+ return result;
+}
+
+
+#endif // NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_CC310_BL_ECC_SECP256R1)
+
+#endif // NRF_MODULE_ENABLED(NRF_CRYPTO) && NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_CC310_BL)
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/cc310_bl/cc310_bl_backend_ecdsa.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/cc310_bl/cc310_bl_backend_ecdsa.h
new file mode 100644
index 0000000..f75a035
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/cc310_bl/cc310_bl_backend_ecdsa.h
@@ -0,0 +1,124 @@
+/**
+ * Copyright (c) 2018 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+
+#ifndef CC310_BL_BACKEND_ECDSA_H__
+#define CC310_BL_BACKEND_ECDSA_H__
+
+#include "sdk_config.h"
+#include "nordic_common.h"
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO) && NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_CC310_BL)
+
+#include "nrf_crypto_ecc_shared.h"
+#include "nrf_crypto_ecdsa_shared.h"
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_CC310_BL_ECC_SECP224R1)
+#include "nrf_cc310_bl_ecdsa_verify_secp224r1.h"
+#endif
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_CC310_BL_ECC_SECP256R1)
+#include "nrf_cc310_bl_ecdsa_verify_secp256r1.h"
+#endif
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_CC310_BL_ECC_SECP224R1)
+
+/** @internal @brief Common structure holding context for ECDSA verify.
+ */
+typedef struct
+{
+ nrf_cc310_bl_ecdsa_verify_context_secp224r1_t user_context; /**< @internal @brief Temporary buffer for CC310_BL internal storage */
+} nrf_crypto_backend_secp224r1_verify_context_t;
+
+#define NRF_CRYPTO_BACKEND_SECP224R1_VERIFY_CONTEXT_SIZE \
+ sizeof(nrf_crypto_backend_secp224r1_verify_context_t)
+
+ret_code_t nrf_crypto_backend_secp224r1_verify(
+ void * p_context,
+ void const * p_public_key,
+ uint8_t const * p_data,
+ size_t data_size,
+ uint8_t const * p_signature);
+
+// Dummy and empty definitions for unused symbols
+#define NRF_CRYPTO_BACKEND_SECP224R1_SIGN_CONTEXT_SIZE 0
+typedef uint32_t nrf_crypto_backend_secp224r1_sign_context_t;
+#define nrf_crypto_backend_secp224r1_sign NULL
+
+#endif // NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_CC310_BL_ECC_SECP224R1)
+
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_CC310_BL_ECC_SECP256R1)
+
+/** @internal @brief Common structure holding context for ECDSA verify.
+ */
+typedef struct
+{
+ nrf_cc310_bl_ecdsa_verify_context_secp256r1_t user_context; /**< @internal @brief Temporary buffer for CC310_BL internal storage */
+} nrf_crypto_backend_secp256r1_verify_context_t;
+
+#define NRF_CRYPTO_BACKEND_SECP256R1_VERIFY_CONTEXT_SIZE \
+ sizeof(nrf_crypto_backend_secp256r1_verify_context_t)
+
+ret_code_t nrf_crypto_backend_secp256r1_verify(
+ void * p_context,
+ void const * p_public_key,
+ uint8_t const * p_data,
+ size_t data_size,
+ uint8_t const * p_signature);
+
+// Dummy and empty definitions for unused symbols
+#define NRF_CRYPTO_BACKEND_SECP256R1_SIGN_CONTEXT_SIZE 0
+typedef uint32_t nrf_crypto_backend_secp256r1_sign_context_t;
+#define nrf_crypto_backend_secp256r1_sign NULL
+
+#endif // NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_CC310_BL_ECC_SECP256R1)
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // NRF_MODULE_ENABLED(NRF_CRYPTO) && NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_CC310_BL)
+
+#endif // CC310_BL_BACKEND_ECDSA_H__
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/cc310_bl/cc310_bl_backend_hash.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/cc310_bl/cc310_bl_backend_hash.c
new file mode 100644
index 0000000..59010f5
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/cc310_bl/cc310_bl_backend_hash.c
@@ -0,0 +1,281 @@
+/**
+ * Copyright (c) 2018 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#include "sdk_common.h"
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO) && NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_CC310_BL)
+
+#include "nrf.h"
+#include "cc310_bl_backend_hash.h"
+#include "cc310_bl_backend_shared.h"
+#include "cc310_backend_mutex.h"
+#include "cc310_backend_shared.h"
+#include "nrf_cc310_bl_hash_sha256.h"
+#include "crys_hash_error.h"
+#include "nrf_crypto_init.h"
+#include "nrf_crypto_types.h"
+#include "nrf_crypto_error.h"
+#include "nrf_crypto_shared.h"
+#include "nrf_crypto_hash_shared.h"
+#include "sdk_macros.h"
+#include "nrf_log.h"
+#include "nrf_assert.h"
+#include <drivers/nrfx_common.h>
+
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_CC310_BL_HASH_SHA256)
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_CC310_BL_HASH_AUTOMATIC_RAM_BUFFER)
+
+__ALIGN(4) static uint8_t m_hash_buffer[NRF_CRYPTO_BACKEND_CC310_BL_HASH_AUTOMATIC_RAM_BUFFER_SIZE];
+
+#endif // NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_CC310_BL_HASH_AUTOMATIC_RAM_BUFFER)
+
+
+static ret_code_t hash_result_get(CRYSError_t error)
+{
+ ret_code_t ret_val;
+
+ switch (error)
+ {
+ case CRYS_OK:
+ ret_val = NRF_SUCCESS;
+ break;
+
+ case CRYS_HASH_INVALID_USER_CONTEXT_POINTER_ERROR:
+ ret_val = NRF_ERROR_CRYPTO_CONTEXT_NULL;
+ break;
+
+ case CRYS_HASH_ILLEGAL_OPERATION_MODE_ERROR:
+ ret_val = NRF_ERROR_CRYPTO_FEATURE_UNAVAILABLE;
+ break;
+
+ case CRYS_HASH_USER_CONTEXT_CORRUPTED_ERROR:
+ ret_val = NRF_ERROR_CRYPTO_CONTEXT_NOT_INITIALIZED;
+ break;
+
+ // May be added to specialized errors for hash.
+ case CRYS_HASH_LAST_BLOCK_ALREADY_PROCESSED_ERROR:
+ ret_val = NRF_ERROR_CRYPTO_INTERNAL;
+ break;
+
+ case CRYS_HASH_IS_NOT_SUPPORTED:
+ ret_val = NRF_ERROR_CRYPTO_FEATURE_UNAVAILABLE;
+ break;
+
+ default:
+ ret_val = NRF_ERROR_CRYPTO_INTERNAL;
+ break;
+ }
+
+ return ret_val;
+}
+
+
+static ret_code_t cc310_bl_backend_hash_sha256_init(void * const p_context)
+{
+ uint32_t ret_val;
+ CRYSError_t crys_error;
+
+ // Limited parameter testing on this level.
+ // This has been done on upper level.
+
+ nrf_cc310_bl_hash_context_sha256_t * const p_backend_context
+ = &(((nrf_crypto_backend_hash_sha256_context_t *)p_context)->context);
+
+ crys_error = nrf_cc310_bl_hash_sha256_init(p_backend_context);
+
+ ret_val = hash_result_get(crys_error);
+
+ return ret_val;
+}
+
+
+static uint32_t cc310_bl_backend_hash_sha256_update(void * const p_context,
+ uint8_t const * p_data,
+ size_t size)
+{
+ ret_code_t ret_val;
+ CRYSError_t crys_error;
+ uint32_t cur_size;
+ uint32_t size_left;
+ uint8_t * p_cur;
+ bool mutex_locked;
+
+ // Limited parameter testing on this level.
+ // This has been done on upper level.
+
+ nrf_cc310_bl_hash_context_sha256_t * const p_backend_context
+ = &(((nrf_crypto_backend_hash_sha256_context_t *)p_context)->context);
+
+ p_cur = (uint8_t *)p_data;
+ size_left = size;
+
+ mutex_locked = cc310_backend_mutex_trylock();
+ VERIFY_TRUE(mutex_locked, NRF_ERROR_CRYPTO_BUSY);
+
+ cc310_bl_backend_enable();
+
+#if defined (NRF_CRYPTO_BACKEND_CC310_BL_HASH_AUTOMATIC_RAM_BUFFER_ENABLED) && (NRF_CRYPTO_BACKEND_CC310_BL_HASH_AUTOMATIC_RAM_BUFFER_ENABLED == 1)
+
+ do
+ {
+ // Copy a block from FLASH to RAM for use in CC310
+ cur_size = (size_left > NRF_CRYPTO_BACKEND_CC310_BL_HASH_AUTOMATIC_RAM_BUFFER_SIZE) ?
+ NRF_CRYPTO_BACKEND_CC310_BL_HASH_AUTOMATIC_RAM_BUFFER_SIZE : size_left;
+
+ // Copy from FLASH to ram
+ memcpy(m_hash_buffer, p_cur, cur_size);
+
+ // Update the hash with current input.
+ crys_error = nrf_cc310_bl_hash_sha256_update(p_backend_context, m_hash_buffer, cur_size);
+
+ size_left -= cur_size;
+ p_cur += cur_size;
+
+ } while(crys_error == SASI_OK && size_left > 0);
+
+#elif defined(NRF_CRYPTO_BACKEND_CC310_BL_HASH_AUTOMATIC_RAM_BUFFER_ENABLED) && (NRF_CRYPTO_BACKEND_CC310_BL_HASH_AUTOMATIC_RAM_BUFFER_ENABLED == 0)
+
+ // Verify that the data is in RAM (required for CC310 hashing)
+ VERIFY_TRUE(nrfx_is_in_ram(p_data), NRF_ERROR_CRYPTO_INPUT_LOCATION);
+
+ do
+ {
+ // Get the largest block that can sent to the CC310 through DMA
+ cur_size = (size_left > CC310_MAX_LENGTH_DMA_OPERATIONS) ?
+ CC310_MAX_LENGTH_DMA_OPERATIONS : size_left;
+
+ crys_error = nrf_cc310_bl_hash_sha256_update(p_backend_context, p_cur, cur_size);
+
+ size_left -= cur_size;
+ p_cur += cur_size;
+ } while(crys_error == SASI_OK && size_left > 0);
+
+#else
+
+ UNUSED_PARAMETER(p_backend_context);
+ UNUSED_PARAMETER(cur_size);
+ UNUSED_PARAMETER(size_left);
+ UNUSED_PARAMETER(p_cur);
+
+ #warning NRF_CRYPTO_BACKEND_CC310_BL_HASH_AUTOMATIC_RAM_BUFFER_ENABLED define not found in sdk_config.h (Is the sdk_config.h valid?).
+
+#endif
+
+ cc310_bl_backend_disable();
+
+ cc310_backend_mutex_unlock();
+
+ ret_val = hash_result_get(crys_error);
+
+ return ret_val;
+}
+
+
+static uint32_t cc310_bl_backend_hash_sha256_finalize(void * const p_context,
+ uint8_t * p_digest,
+ size_t * const p_digest_size)
+{
+ ret_code_t ret_val;
+ CRYSError_t crys_error;
+ bool mutex_locked;
+
+ // Limited parameter testing on this level.
+ // This has been done on upper level.
+
+ nrf_cc310_bl_hash_context_sha256_t * const p_backend_context
+ = &(((nrf_crypto_backend_hash_sha256_context_t * )p_context)->context);
+
+ nrf_cc310_bl_hash_digest_sha256_t * p_int_digest
+ = (nrf_cc310_bl_hash_digest_sha256_t *)p_digest;
+
+ if (NRF_CRYPTO_HASH_SIZE_SHA256 > *p_digest_size)
+ {
+ return NRF_ERROR_CRYPTO_OUTPUT_LENGTH;
+ }
+
+ mutex_locked = cc310_backend_mutex_trylock();
+ VERIFY_TRUE(mutex_locked, NRF_ERROR_CRYPTO_BUSY);
+
+ cc310_bl_backend_enable();
+
+ // Do the hash finalize calculation
+ crys_error = nrf_cc310_bl_hash_sha256_finalize(p_backend_context, p_int_digest);
+
+ cc310_bl_backend_disable();
+
+ cc310_backend_mutex_unlock();
+
+ ret_val = hash_result_get(crys_error);
+
+ if (ret_val == NRF_SUCCESS)
+ {
+ *p_digest_size = NRF_CRYPTO_HASH_SIZE_SHA256;
+ }
+
+#if defined(NRF_CRYPTO_BACKEND_CC310_BL_HASH_LITTLE_ENDIAN_DIGEST_ENABLED) && (NRF_CRYPTO_BACKEND_CC310_BL_HASH_LITTLE_ENDIAN_DIGEST_ENABLED == 1)
+
+ nrf_crypto_internal_swap_endian_in_place(p_digest, NRF_CRYPTO_HASH_SIZE_SHA256);
+
+#elif defined(NRF_CRYPTO_BACKEND_CC310_BL_HASH_LITTLE_ENDIAN_DIGEST_ENABLED) && (NRF_CRYPTO_BACKEND_CC310_BL_HASH_LITTLE_ENDIAN_DIGEST_ENABLED == 0)
+
+ // Do nothing
+
+#else
+
+ #warning NRF_CRYPTO_BACKEND_CC310_BL_HASH_LITTLE_ENDIAN_DIGEST_ENABLED define not found in sdk_config.h (Is the sdk_config.h valid?).
+
+#endif
+
+ return ret_val;
+}
+
+const nrf_crypto_hash_info_t g_nrf_crypto_hash_sha256_info =
+{
+ .init_fn = cc310_bl_backend_hash_sha256_init,
+ .update_fn = cc310_bl_backend_hash_sha256_update,
+ .finalize_fn = cc310_bl_backend_hash_sha256_finalize,
+ .digest_size = NRF_CRYPTO_HASH_SIZE_SHA256,
+ .hash_mode = NRF_CRYPTO_HASH_MODE_SHA256
+};
+
+#endif // NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_CC310_BL_HASH_SHA256)
+
+#endif // NRF_MODULE_ENABLED(NRF_CRYPTO) && #if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_CC310_BL)
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/cc310_bl/cc310_bl_backend_hash.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/cc310_bl/cc310_bl_backend_hash.h
new file mode 100644
index 0000000..6882c04
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/cc310_bl/cc310_bl_backend_hash.h
@@ -0,0 +1,97 @@
+/**
+ * Copyright (c) 2018 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+
+#ifndef CC310_BL_BACKEND_HASH_H__
+#define CC310_BL_BACKEND_HASH_H__
+
+/** @file
+ *
+ * @defgroup nrf_crypto_cc310_bl_backend_hash nrf_crypto CC310_BL backend hash
+ * @{
+ * @ingroup nrf_crypto_cc310_bl_backend
+ *
+ * @brief Hash functionality provided by the nrf_crypto CC310_BL backend.
+ */
+
+#include "sdk_common.h"
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_CC310_BL)
+
+#include "sdk_errors.h"
+#include "nrf_crypto_hash_shared.h"
+#include "nrf_cc310_bl_hash_sha256.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_CC310_BL_HASH_SHA256)
+
+// Flag that nrf_crypto_hash frontend can be compiled
+#undef NRF_CRYPTO_HASH_ENABLED
+#define NRF_CRYPTO_HASH_ENABLED 1
+
+// Flag that SHA-256 is enabled in backend
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_HASH_SHA256)
+#error "Duplicate definition of SHA-256. More than one backend enabled");
+#endif
+#define NRF_CRYPTO_HASH_SHA256_ENABLED 1
+
+
+/**@internal @brief nrf_crypto_hash context for SHA-256 in nrf_crypto CC310_BL backend. */
+typedef struct
+{
+ nrf_crypto_hash_internal_context_t header; /**< Common header for context. */
+ nrf_cc310_bl_hash_context_sha256_t context; /**< Hash context internal to CC310_BL. */
+} nrf_crypto_backend_hash_sha256_context_t;
+
+
+#endif // NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_CC310_BL_HASH_SHA256)
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_CC310_BL)
+
+/**@} */
+
+#endif // CC310_BL_BACKEND_HASH_H__
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/cc310_bl/cc310_bl_backend_init.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/cc310_bl/cc310_bl_backend_init.c
new file mode 100644
index 0000000..38f440c
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/cc310_bl/cc310_bl_backend_init.c
@@ -0,0 +1,115 @@
+/**
+ * Copyright (c) 2018 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+
+#include "sdk_common.h"
+#if NRF_MODULE_ENABLED(NRF_CRYPTO) && NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_CC310_BL)
+
+#include "nrf.h"
+#include "nrf_crypto_init.h"
+#include "nrf_crypto_error.h"
+
+#include "cc310_bl_backend_shared.h"
+#include "cc310_backend_mutex.h"
+#include "sns_silib.h"
+#include "nrf_cc310_bl_init.h"
+
+/**@brief Mutex to ensure single access to nrf_cc310_bl resources */
+nrf_mtx_t g_cc310_mutex;
+
+static uint32_t init_result_get(uint32_t crys_error)
+{
+ uint32_t ret_val = NRF_ERROR_INTERNAL;
+ switch (crys_error)
+ {
+ case SA_SILIB_RET_OK:
+ ret_val = NRF_SUCCESS;
+ break;
+
+ case SA_SILIB_RET_EINVAL_HW_VERSION:
+ ret_val = NRF_ERROR_CRYPTO_FEATURE_UNAVAILABLE;
+ break;
+
+ default:
+ ret_val = NRF_ERROR_INTERNAL;
+ break;
+ }
+
+ return ret_val;
+}
+
+
+static ret_code_t cc310_bl_backend_init(void)
+{
+ uint32_t ret_val;
+ CRYSError_t crys_error;
+
+ cc310_backend_mutex_init();
+
+ // Enable the CC310 HW.
+ NRF_CRYPTOCELL->ENABLE = 1;
+
+ // Initialize the CC310_BL run-time library
+ crys_error = nrf_cc310_bl_init();
+
+ // Disable the CC310 HW after initialization.
+ NRF_CRYPTOCELL->ENABLE = 0;
+
+ ret_val = init_result_get(crys_error);
+
+ return ret_val;
+}
+
+
+static ret_code_t cc310_bl_backend_uninit(void)
+{
+ // Disable the CC310 HW.
+ NRF_CRYPTOCELL->ENABLE = 0;
+
+ return NRF_SUCCESS;
+}
+
+
+CRYPTO_BACKEND_REGISTER(nrf_crypto_backend_info_t const cc310_bl_backend) =
+{
+ .init_fn = cc310_bl_backend_init,
+ .uninit_fn = cc310_bl_backend_uninit
+};
+
+#endif // NRF_MODULE_ENABLED(NRF_CRYPTO) && NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_CC310_BL)
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/cc310_bl/cc310_bl_backend_shared.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/cc310_bl/cc310_bl_backend_shared.c
new file mode 100644
index 0000000..520a116
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/cc310_bl/cc310_bl_backend_shared.c
@@ -0,0 +1,68 @@
+/**
+ * Copyright (c) 2018 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#include "sdk_common.h"
+#if NRF_MODULE_ENABLED(NRF_CRYPTO) && NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_CC310_BL)
+
+#include "nrf.h"
+#include "cc310_bl_backend_shared.h"
+#include "nrf_crypto_error.h"
+
+
+void cc310_bl_backend_enable(void)
+{
+ // Enable the cryptocell hardware
+ NRF_CRYPTOCELL->ENABLE = 1;
+
+ // Enable the CryptoCell IRQ
+ NVIC_EnableIRQ(CRYPTOCELL_IRQn);
+}
+
+
+void cc310_bl_backend_disable(void)
+{
+ // Enable the cryptocell hardware
+ NRF_CRYPTOCELL->ENABLE = 0;
+
+ // Disable the CryptoCell IRQ
+ NVIC_DisableIRQ(CRYPTOCELL_IRQn);
+}
+
+
+#endif // NRF_MODULE_ENABLED(NRF_CRYPTO) && NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_CC310_BL)
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/cc310_bl/cc310_bl_backend_shared.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/cc310_bl/cc310_bl_backend_shared.h
new file mode 100644
index 0000000..db7c933
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/cc310_bl/cc310_bl_backend_shared.h
@@ -0,0 +1,83 @@
+/**
+ * Copyright (c) 2018 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+
+#ifndef CC310_BL_BACKEND_SHARED_H__
+#define CC310_BL_BACKEND_SHARED_H__
+
+/** @file
+ *
+ * @defgroup nrf_crypto_cc310_bl_backend_shared nrf_crypto CC310_BL backend shared
+ * @{
+ * @ingroup nrf_crypto_cc310_bl_backend
+ *
+ * @brief Shared functionality for the nrf_crypto CC310_BL backend.
+ */
+
+#include "sdk_common.h"
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO) && NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_CC310_BL)
+
+#include "sdk_errors.h"
+#include "nrf_crypto_hash_shared.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+/**@internal @brief Function to enable CC310 (in HW)
+ */
+void cc310_bl_backend_enable(void);
+
+
+/**@internal @brief Function to disable CC310 (in HW)
+ */
+void cc310_bl_backend_disable(void);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // NRF_MODULE_ENABLED(NRF_CRYPTO) && NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_CC310_BL)
+
+/**@} */
+
+#endif // CC310_BL_BACKEND_SHARED_H__
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/cifra/cifra_backend_aes_aead.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/cifra/cifra_backend_aes_aead.c
new file mode 100644
index 0000000..23b3cb6
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/cifra/cifra_backend_aes_aead.c
@@ -0,0 +1,205 @@
+/**
+ * Copyright (c) 2018 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+
+#include "sdk_common.h"
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO)
+
+#include <stdbool.h>
+#include "cifra_backend_aes_aead.h"
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_CIFRA_AES_AEAD)
+
+/**@internal @brief Type declaration of a template matching all possible context sizes
+ * for this backend.
+ */
+typedef struct
+{
+ nrf_crypto_aead_internal_context_t header; /**< Common header for context. */
+ cf_aes_context context;
+} nrf_crypto_backend_cifra_aes_aead_context_t;
+
+
+static ret_code_t result_get(int error)
+{
+ switch (error)
+ {
+ case 0:
+ return NRF_SUCCESS;
+
+ case 1:
+ return NRF_ERROR_CRYPTO_AEAD_INVALID_MAC;
+
+ default:
+ return NRF_ERROR_CRYPTO_INTERNAL;
+ }
+}
+
+static ret_code_t backend_cifra_init(void * const p_context, uint8_t * p_key)
+{
+ nrf_crypto_backend_cifra_aes_aead_context_t * p_ctx =
+ (nrf_crypto_backend_cifra_aes_aead_context_t *)p_context;
+
+ if ((p_ctx->header.p_info->key_size != NRF_CRYPTO_KEY_SIZE_128) &&
+ (p_ctx->header.p_info->key_size != NRF_CRYPTO_KEY_SIZE_192) &&
+ (p_ctx->header.p_info->key_size != NRF_CRYPTO_KEY_SIZE_256))
+ {
+ return NRF_ERROR_CRYPTO_KEY_SIZE;
+ }
+
+ VERIFY_TRUE((p_ctx->header.p_info->mode == NRF_CRYPTO_AEAD_MODE_AES_EAX),
+ NRF_ERROR_CRYPTO_FEATURE_UNAVAILABLE);
+
+ cf_aes_init(&p_ctx->context,
+ p_key,
+ (p_ctx->header.p_info->key_size)>>3); // >>3: changes bits to bytes
+
+ return NRF_SUCCESS;
+}
+
+
+static ret_code_t backend_cifra_uninit(void * const p_context)
+{
+ nrf_crypto_backend_cifra_aes_aead_context_t * p_ctx =
+ (nrf_crypto_backend_cifra_aes_aead_context_t *)p_context;
+
+ cf_aes_finish(&p_ctx->context);
+
+ return NRF_SUCCESS;
+}
+
+static ret_code_t backend_cifra_crypt(void * const p_context,
+ nrf_crypto_operation_t operation,
+ uint8_t * p_nonce,
+ uint8_t nonce_size,
+ uint8_t * p_adata,
+ size_t adata_size,
+ uint8_t * p_data_in,
+ size_t data_in_size,
+ uint8_t * p_data_out,
+ uint8_t * p_mac,
+ uint8_t mac_size)
+{
+
+ int result;
+ ret_code_t ret_val;
+
+ nrf_crypto_backend_cifra_aes_aead_context_t * p_ctx =
+ (nrf_crypto_backend_cifra_aes_aead_context_t *)p_context;
+
+ ret_val = NRF_SUCCESS;
+
+ /* EAX mode allows following mac size: [1 ... 16] */
+ if ((mac_size < 1) || (mac_size > NRF_CRYPTO_AES_BLOCK_SIZE))
+ {
+ return NRF_ERROR_CRYPTO_AEAD_MAC_SIZE;
+ }
+
+ if (operation == NRF_CRYPTO_ENCRYPT)
+ {
+ cf_eax_encrypt(&cf_aes,
+ &p_ctx->context,
+ p_data_in,
+ data_in_size,
+ p_adata,
+ adata_size,
+ p_nonce,
+ (size_t)nonce_size,
+ p_data_out,
+ p_mac,
+ mac_size);
+ }
+ else if (operation == NRF_CRYPTO_DECRYPT)
+ {
+ result = cf_eax_decrypt(&cf_aes,
+ &p_ctx->context,
+ p_data_in,
+ data_in_size,
+ p_adata,
+ adata_size,
+ p_nonce,
+ (size_t)nonce_size,
+ p_mac,
+ mac_size,
+ p_data_out);
+ ret_val = result_get(result);
+ }
+ else
+ {
+ return NRF_ERROR_CRYPTO_INVALID_PARAM;
+ }
+
+ return ret_val;
+}
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_CIFRA_AES_EAX)
+nrf_crypto_aead_info_t const g_nrf_crypto_aes_eax_128_info =
+{
+ .key_size = NRF_CRYPTO_KEY_SIZE_128,
+ .mode = NRF_CRYPTO_AEAD_MODE_AES_EAX,
+
+ .init_fn = backend_cifra_init,
+ .uninit_fn = backend_cifra_uninit,
+ .crypt_fn = backend_cifra_crypt
+};
+
+nrf_crypto_aead_info_t const g_nrf_crypto_aes_eax_192_info =
+{
+ .key_size = NRF_CRYPTO_KEY_SIZE_192,
+ .mode = NRF_CRYPTO_AEAD_MODE_AES_EAX,
+
+ .init_fn = backend_cifra_init,
+ .uninit_fn = backend_cifra_uninit,
+ .crypt_fn = backend_cifra_crypt
+};
+
+nrf_crypto_aead_info_t const g_nrf_crypto_aes_eax_256_info =
+{
+ .key_size = NRF_CRYPTO_KEY_SIZE_256,
+ .mode = NRF_CRYPTO_AEAD_MODE_AES_EAX,
+
+ .init_fn = backend_cifra_init,
+ .uninit_fn = backend_cifra_uninit,
+ .crypt_fn = backend_cifra_crypt
+};
+#endif
+
+#endif // MODULE_ENABLED(NRF_CRYPTO_AES_CCM_BACKEND_MBEDTLS)
+#endif // MODULE_ENABLED(NRF_CRYPTO)
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/cifra/cifra_backend_aes_aead.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/cifra/cifra_backend_aes_aead.h
new file mode 100644
index 0000000..d0575ac
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/cifra/cifra_backend_aes_aead.h
@@ -0,0 +1,98 @@
+/**
+ * Copyright (c) 2018 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+
+#ifndef CIFRA_BACKEND_AES_AEAD_H__
+#define CIFRA_BACKEND_AES_AEAD_H__
+
+/** @file
+ *
+ * @defgroup nrf_crypto_cifra_backend_aes_aead nrf_crypto Cifra backend AES AEAD
+ * @{
+ * @ingroup nrf_crypto_cifra_backend
+ *
+ * @brief AES AEAD functionality provided by the nrf_crypto Cifra backend.
+ */
+
+#include "sdk_config.h"
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_CIFRA)
+
+#include "modes.h"
+#include "cifra_eax_aes.h"
+#include "nrf_crypto_error.h"
+#include "nrf_crypto_types.h"
+#include "nrf_crypto_aead_shared.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* AES EAX */
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_CIFRA_AES_EAX)
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_AES_EAX)
+#error "Duplicate definition of AES EAX mode. More than one backend enabled");
+#endif
+#define NRF_CRYPTO_AES_EAX_ENABLED 1
+#undef NRF_CRYPTO_AEAD_ENABLED
+#define NRF_CRYPTO_AEAD_ENABLED 1 // Flag that nrf_crypto_aes_aead frontend can be compiled
+#undef NRF_CRYPTO_CIFRA_AES_AEAD_ENABLED
+#define NRF_CRYPTO_CIFRA_AES_AEAD_ENABLED 1 // aes_aead backend cifra can be compiled
+
+/* defines for test purposes */
+#define NRF_CRYPTO_AES_EAX_128_ENABLED 1
+#define NRF_CRYPTO_AES_EAX_192_ENABLED 1
+#define NRF_CRYPTO_AES_EAX_256_ENABLED 1
+
+typedef struct
+{
+ nrf_crypto_aead_internal_context_t header; /**< Common header for context. */
+ cf_aes_context context; /**< AES EAX context internal to Cifra. */
+} nrf_crypto_backend_aes_eax_context_t;
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+#endif // NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_CIFRA)
+
+/** @} */
+
+#endif // CIFRA_BACKEND_AES_AEAD_H__
+
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/mbedtls/mbedtls_backend_aes.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/mbedtls/mbedtls_backend_aes.c
new file mode 100644
index 0000000..9433471
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/mbedtls/mbedtls_backend_aes.c
@@ -0,0 +1,1213 @@
+/**
+ * Copyright (c) 2018 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+
+#include "sdk_common.h"
+#if NRF_MODULE_ENABLED(NRF_CRYPTO)
+
+/*lint -save -e????*/
+#include "mbedtls/md.h"
+#include "mbedtls/aes.h"
+#include "mbedtls/cipher.h"
+/*lint -restore*/
+#include "nrf_crypto_error.h"
+#include "mbedtls_backend_aes.h"
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_MBEDTLS_AES)
+
+/* macro changing bits to bytes */
+#define BITS_TO_BYTES(bits) ((bits)>>3)
+#define BACKEND_ERROR_CHECK(error) \
+ do { \
+ if ((error) != 0) \
+ { \
+ return result_get((error)); \
+ } \
+ } while (0);
+
+/**@internal @brief Type declarations of templates matching all possible context sizes
+ * for this backend.
+ */
+typedef struct
+{
+ nrf_crypto_aes_internal_context_t header; /**< Common header for context. */
+ nrf_crypto_backend_aes_ctx_t backend; /**< Backend-specific internal context. */
+ uint32_t context[1]; /**< AES context internal to mbed TLS. */
+} nrf_crypto_backend_mbedtls_aes_any_context_t;
+
+/**@internal @brief Type declarations of templates matching all possible context sizes
+ * for this backend.
+ */
+typedef union
+{
+ nrf_crypto_backend_mbedtls_aes_any_context_t any; /**< Common for all contexts. */
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_MBEDTLS_AES_ECB)
+ nrf_crypto_backend_aes_ecb_context_t ecb;
+#endif
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_MBEDTLS_AES_CBC)
+ nrf_crypto_backend_aes_cbc_context_t cbc;
+#endif
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_MBEDTLS_AES_CTR)
+ nrf_crypto_backend_aes_ctr_context_t ctr;
+#endif
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_MBEDTLS_AES_CFB)
+ nrf_crypto_backend_aes_cfb_context_t cfb;
+#endif
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_MBEDTLS_AES_CBC_MAC)
+ nrf_crypto_backend_aes_cbc_mac_context_t cbc_mac;
+#endif
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_MBEDTLS_AES_CMAC)
+ nrf_crypto_backend_aes_cmac_context_t cmac;
+#endif
+} nrf_crypto_backend_mbedtls_aes_context_t;
+
+
+static ret_code_t result_get(int error)
+{
+ ret_code_t ret_val;
+ switch (error)
+ {
+ case 0:
+ ret_val = NRF_SUCCESS;
+ break;
+
+ case MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH:
+ ret_val = NRF_ERROR_CRYPTO_INPUT_LENGTH;
+ break;
+
+ case MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA:
+ ret_val = NRF_ERROR_CRYPTO_INPUT_LENGTH;
+ break;
+
+ case MBEDTLS_ERR_CIPHER_ALLOC_FAILED:
+ ret_val = NRF_ERROR_CRYPTO_ALLOC_FAILED;
+ break;
+
+ case MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE:
+ ret_val = NRF_ERROR_CRYPTO_FEATURE_UNAVAILABLE;
+ break;
+
+ case MBEDTLS_ERR_MD_BAD_INPUT_DATA:
+ ret_val = NRF_ERROR_CRYPTO_INVALID_PARAM;
+ break;
+
+ default:
+ ret_val = NRF_ERROR_CRYPTO_INTERNAL;
+ break;
+ }
+
+ return ret_val;
+}
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_MBEDTLS_AES_CMAC)
+static ret_code_t backend_cmac_init(nrf_crypto_backend_aes_cmac_context_t * const p_cmac_ctx)
+{
+ int error;
+
+ mbedtls_cipher_type_t cipher_type;
+ mbedtls_cipher_info_t const * p_cipher_info;
+
+ mbedtls_cipher_init(&p_cmac_ctx->context);
+
+ switch (p_cmac_ctx->header.p_info->key_size)
+ {
+ case NRF_CRYPTO_KEY_SIZE_128:
+ cipher_type = MBEDTLS_CIPHER_AES_128_ECB;
+ break;
+
+ case NRF_CRYPTO_KEY_SIZE_192:
+ cipher_type = MBEDTLS_CIPHER_AES_192_ECB;
+ break;
+
+ case NRF_CRYPTO_KEY_SIZE_256:
+ cipher_type = MBEDTLS_CIPHER_AES_256_ECB;
+ break;
+
+ default:
+ return NRF_ERROR_CRYPTO_CONTEXT_NOT_INITIALIZED;
+ }
+
+ p_cipher_info = mbedtls_cipher_info_from_type(cipher_type);
+
+ if (p_cipher_info == NULL)
+ {
+ return NRF_ERROR_CRYPTO_INTERNAL;
+ }
+
+ error = mbedtls_cipher_setup(&p_cmac_ctx->context, p_cipher_info);
+ BACKEND_ERROR_CHECK(error);
+
+ return NRF_SUCCESS;
+}
+#endif
+
+static ret_code_t backend_mbedtls_init(void * const p_context, nrf_crypto_operation_t operation)
+{
+ ret_code_t ret_val = NRF_SUCCESS;
+
+ nrf_crypto_backend_mbedtls_aes_context_t * p_ctx =
+ (nrf_crypto_backend_mbedtls_aes_context_t *)p_context;
+
+ switch (p_ctx->any.header.p_info->key_size)
+ {
+ case NRF_CRYPTO_KEY_SIZE_128:
+ case NRF_CRYPTO_KEY_SIZE_192:
+ case NRF_CRYPTO_KEY_SIZE_256:
+ break;
+
+ default:
+ return NRF_ERROR_CRYPTO_KEY_SIZE;
+ }
+
+ switch (p_ctx->any.header.p_info->mode)
+ {
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_MBEDTLS_AES_CBC)
+ case NRF_CRYPTO_AES_MODE_CBC:
+ case NRF_CRYPTO_AES_MODE_CBC_PAD_PCKS7:
+ VERIFY_FALSE(((operation != NRF_CRYPTO_ENCRYPT) && (operation != NRF_CRYPTO_DECRYPT)),
+ NRF_ERROR_CRYPTO_INVALID_PARAM);
+ memset(&p_ctx->cbc.backend, 0, sizeof(p_ctx->cbc.backend));
+
+ mbedtls_aes_init(&p_ctx->cbc.context);
+ break;
+#endif
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_MBEDTLS_AES_CTR)
+ case NRF_CRYPTO_AES_MODE_CTR:
+ VERIFY_FALSE(((operation != NRF_CRYPTO_ENCRYPT) && (operation != NRF_CRYPTO_DECRYPT)),
+ NRF_ERROR_CRYPTO_INVALID_PARAM);
+ memset(&p_ctx->ctr.backend, 0, sizeof(p_ctx->ctr.backend));
+
+ mbedtls_aes_init(&p_ctx->ctr.context);
+ break;
+#endif
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_MBEDTLS_AES_CFB)
+ case NRF_CRYPTO_AES_MODE_CFB:
+ VERIFY_FALSE(((operation != NRF_CRYPTO_ENCRYPT) && (operation != NRF_CRYPTO_DECRYPT)),
+ NRF_ERROR_CRYPTO_INVALID_PARAM);
+ memset(&p_ctx->cfb.backend, 0, sizeof(p_ctx->cfb.backend));
+
+ mbedtls_aes_init(&p_ctx->cfb.context);
+ break;
+#endif
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_MBEDTLS_AES_ECB)
+ case NRF_CRYPTO_AES_MODE_ECB:
+ case NRF_CRYPTO_AES_MODE_ECB_PAD_PCKS7:
+ VERIFY_FALSE(((operation != NRF_CRYPTO_ENCRYPT) && (operation != NRF_CRYPTO_DECRYPT)),
+ NRF_ERROR_CRYPTO_INVALID_PARAM);
+ memset(&p_ctx->ecb.backend, 0, sizeof(p_ctx->ecb.backend));
+
+ mbedtls_aes_init(&p_ctx->ecb.context);
+ break;
+#endif
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_MBEDTLS_AES_CBC_MAC)
+ case NRF_CRYPTO_AES_MODE_CBC_MAC:
+ case NRF_CRYPTO_AES_MODE_CBC_MAC_PAD_PCKS7:
+ VERIFY_TRUE((operation == NRF_CRYPTO_MAC_CALCULATE), NRF_ERROR_CRYPTO_INVALID_PARAM);
+ memset(&p_ctx->cbc_mac.backend, 0, sizeof(p_ctx->cbc_mac.backend));
+
+ mbedtls_aes_init(&p_ctx->cbc_mac.context);
+ break;
+#endif
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_MBEDTLS_AES_CMAC)
+ case NRF_CRYPTO_AES_MODE_CMAC:
+ VERIFY_TRUE((operation == NRF_CRYPTO_MAC_CALCULATE), NRF_ERROR_CRYPTO_INVALID_PARAM);
+
+ ret_val = backend_cmac_init(&p_ctx->cmac);
+ break;
+#endif
+ default:
+ ret_val = NRF_ERROR_CRYPTO_FEATURE_UNAVAILABLE;
+ break;
+ }
+
+ p_ctx->any.backend.operation = operation;
+
+ return ret_val;
+}
+
+static ret_code_t backend_mbedtls_uninit(void * const p_context)
+{
+ nrf_crypto_backend_mbedtls_aes_context_t * p_ctx =
+ (nrf_crypto_backend_mbedtls_aes_context_t *)p_context;
+
+ switch (p_ctx->any.header.p_info->mode)
+ {
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_MBEDTLS_AES_CBC)
+ case NRF_CRYPTO_AES_MODE_CBC:
+ case NRF_CRYPTO_AES_MODE_CBC_PAD_PCKS7:
+ mbedtls_aes_free(&p_ctx->cbc.context);
+ break;
+#endif
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_MBEDTLS_AES_CTR)
+ case NRF_CRYPTO_AES_MODE_CTR:
+ mbedtls_aes_free(&p_ctx->ctr.context);
+ break;
+#endif
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_MBEDTLS_AES_CFB)
+ case NRF_CRYPTO_AES_MODE_CFB:
+ mbedtls_aes_free(&p_ctx->cfb.context);
+ break;
+#endif
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_MBEDTLS_AES_ECB)
+ case NRF_CRYPTO_AES_MODE_ECB:
+ case NRF_CRYPTO_AES_MODE_ECB_PAD_PCKS7:
+ mbedtls_aes_free(&p_ctx->ecb.context);
+ break;
+#endif
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_MBEDTLS_AES_CBC_MAC)
+ case NRF_CRYPTO_AES_MODE_CBC_MAC:
+ case NRF_CRYPTO_AES_MODE_CBC_MAC_PAD_PCKS7:
+ mbedtls_aes_free(&p_ctx->cbc_mac.context);
+ break;
+#endif
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_MBEDTLS_AES_CMAC)
+ case NRF_CRYPTO_AES_MODE_CMAC:
+ mbedtls_cipher_free(&p_ctx->cmac.context);
+ break;
+#endif
+
+ default:
+ return NRF_ERROR_CRYPTO_FEATURE_UNAVAILABLE;
+ }
+
+ return NRF_SUCCESS;
+}
+
+static ret_code_t backend_mbedtls_key_set(void * const p_context, uint8_t * p_key)
+{
+ int error;
+ ret_code_t ret_val;
+
+ nrf_crypto_backend_mbedtls_aes_context_t * p_ctx =
+ (nrf_crypto_backend_mbedtls_aes_context_t *)p_context;
+
+ switch (p_ctx->any.header.p_info->mode)
+ {
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_MBEDTLS_AES_CBC)
+ case NRF_CRYPTO_AES_MODE_CBC:
+ case NRF_CRYPTO_AES_MODE_CBC_PAD_PCKS7:
+ if (p_ctx->cbc.backend.operation == NRF_CRYPTO_ENCRYPT)
+ {
+ error = mbedtls_aes_setkey_enc(&p_ctx->cbc.context,
+ (uint8_t const *)p_key,
+ p_ctx->cbc.header.p_info->key_size);
+ }
+ else
+ {
+ error = mbedtls_aes_setkey_dec(&p_ctx->cbc.context,
+ (uint8_t const *)p_key,
+ p_ctx->cbc.header.p_info->key_size);
+ }
+ break;
+#endif
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_MBEDTLS_AES_CTR)
+ case NRF_CRYPTO_AES_MODE_CTR:
+ /* Due to the nature of CFB / CTR, you should use the same key schedule for both
+ encryption and decryption.*/
+ error = mbedtls_aes_setkey_enc(&p_ctx->ctr.context,
+ (uint8_t const *)p_key,
+ p_ctx->ctr.header.p_info->key_size);
+ break;
+#endif
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_MBEDTLS_AES_CFB)
+ case NRF_CRYPTO_AES_MODE_CFB:
+ /* Due to the nature of CFB / CTR, you should use the same key schedule for both
+ encryption and decryption.*/
+ error = mbedtls_aes_setkey_enc(&p_ctx->cfb.context,
+ (uint8_t const *)p_key,
+ p_ctx->cfb.header.p_info->key_size);
+ break;
+#endif
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_MBEDTLS_AES_ECB)
+ case NRF_CRYPTO_AES_MODE_ECB:
+ case NRF_CRYPTO_AES_MODE_ECB_PAD_PCKS7:
+ if (p_ctx->ecb.backend.operation == NRF_CRYPTO_ENCRYPT)
+ {
+ error = mbedtls_aes_setkey_enc(&p_ctx->ecb.context,
+ (uint8_t const *)p_key,
+ p_ctx->ecb.header.p_info->key_size);
+ }
+ else
+ {
+ error = mbedtls_aes_setkey_dec(&p_ctx->ecb.context,
+ (uint8_t const *)p_key,
+ p_ctx->ecb.header.p_info->key_size);
+ }
+ break;
+#endif
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_MBEDTLS_AES_CBC_MAC)
+ case NRF_CRYPTO_AES_MODE_CBC_MAC:
+ case NRF_CRYPTO_AES_MODE_CBC_MAC_PAD_PCKS7:
+ error = mbedtls_aes_setkey_enc(&p_ctx->cbc_mac.context,
+ (uint8_t const *)p_key,
+ p_ctx->cbc_mac.header.p_info->key_size);
+ break;
+#endif
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_MBEDTLS_AES_CMAC)
+ case NRF_CRYPTO_AES_MODE_CMAC:
+ error = mbedtls_cipher_cmac_starts(&p_ctx->cmac.context,
+ p_key,
+ p_ctx->cmac.header.p_info->key_size);
+ break;
+#endif
+
+ default:
+ return NRF_ERROR_CRYPTO_FEATURE_UNAVAILABLE;
+ }
+
+ ret_val = result_get(error);
+
+ return ret_val;
+}
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_MBEDTLS_AES_CBC) || \
+ NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_MBEDTLS_AES_CTR) || \
+ NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_MBEDTLS_AES_CFB) || \
+ NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_MBEDTLS_AES_CBC_MAC)
+static ret_code_t backend_mbedtls_iv_set(void * const p_context, uint8_t * p_iv)
+{
+ nrf_crypto_backend_mbedtls_aes_context_t * p_ctx =
+ (nrf_crypto_backend_mbedtls_aes_context_t *)p_context;
+
+ memcpy(&p_ctx->any.backend.iv[0], p_iv, sizeof(p_ctx->any.backend.iv));
+
+ return NRF_SUCCESS;
+}
+
+static ret_code_t backend_mbedtls_iv_get(void * const p_context, uint8_t * p_iv)
+{
+ nrf_crypto_backend_mbedtls_aes_context_t * p_ctx =
+ (nrf_crypto_backend_mbedtls_aes_context_t *)p_context;
+
+ memcpy(p_iv, p_ctx->any.backend.iv, sizeof(p_ctx->any.backend.iv));
+
+ return NRF_SUCCESS;
+}
+#endif
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_MBEDTLS_AES_ECB)
+/* Function extending mbedtls_aes_crypt_ecb functionality. It allows to process more than 1
+ data block. It is returning MBEDTLS error type. */
+static int backend_mbedtls_ecb_crypt(nrf_crypto_backend_aes_ecb_context_t * const p_ctx,
+ uint8_t * p_text_in,
+ uint8_t * p_text_out,
+ size_t text_size)
+{
+ int error = 0;
+ size_t crypted_text = 0;
+
+ if ((text_size & 0x0F) != 0)
+ {
+ return MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH;
+ }
+
+ while (crypted_text < text_size)
+ {
+ error = mbedtls_aes_crypt_ecb(&p_ctx->context,
+ (int)p_ctx->backend.operation,
+ p_text_in + crypted_text,
+ p_text_out + crypted_text);
+ if (error != 0)
+ {
+ break;
+ }
+ crypted_text += NRF_CRYPTO_AES_BLOCK_SIZE;
+ }
+
+ return error;
+}
+#endif
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_MBEDTLS_AES_CBC_MAC)
+static int backend_mbedtls_cbc_mac_update(void * const p_context,
+ uint8_t * p_data_in,
+ size_t data_size,
+ uint8_t * p_data_out)
+{
+ int error = 0;
+
+ nrf_crypto_backend_mbedtls_aes_context_t * p_ctx =
+ (nrf_crypto_backend_mbedtls_aes_context_t *)p_context;
+
+ for (size_t i = 0; i < data_size; i += NRF_CRYPTO_AES_BLOCK_SIZE)
+ {
+ error = mbedtls_aes_crypt_cbc(&p_ctx->cbc_mac.context,
+ MBEDTLS_AES_ENCRYPT,
+ NRF_CRYPTO_AES_BLOCK_SIZE,
+ p_ctx->cbc_mac.backend.iv,
+ (uint8_t const *)p_data_in + i,
+ p_data_out);
+ if (error != 0)
+ {
+ return error;
+ }
+ }
+
+ return error;
+}
+
+static ret_code_t backend_mbedtls_cbc_mac_finalize(void * const p_context,
+ uint8_t * p_data_in,
+ size_t data_size,
+ uint8_t * p_data_out,
+ size_t * p_data_out_size)
+{
+ int error;
+
+ if (*p_data_out_size < NRF_CRYPTO_AES_BLOCK_SIZE)
+ {
+ return NRF_ERROR_CRYPTO_OUTPUT_LENGTH;
+ }
+
+ /* this function does not support padding */
+ if ((data_size & 0xF) != 0)
+ {
+ return NRF_ERROR_CRYPTO_INPUT_LENGTH;
+ }
+
+ error = backend_mbedtls_cbc_mac_update(p_context, p_data_in, data_size, p_data_out);
+ BACKEND_ERROR_CHECK(error);
+
+ *p_data_out_size = NRF_CRYPTO_AES_BLOCK_SIZE;
+
+ return NRF_SUCCESS;
+}
+
+static ret_code_t backend_mbedtls_cbc_mac_padding_finalize(void * const p_context,
+ uint8_t * p_data_in,
+ size_t data_size,
+ uint8_t * p_data_out,
+ size_t * p_data_out_size)
+{
+ ret_code_t ret_val;
+ uint8_t padding_buffer[NRF_CRYPTO_AES_BLOCK_SIZE] = {0};
+ uint8_t msg_ending = (uint8_t)(data_size & (size_t)0x0F);
+
+ if (*p_data_out_size < NRF_CRYPTO_AES_BLOCK_SIZE)
+ {
+ /* output buffer too small */
+ return NRF_ERROR_CRYPTO_OUTPUT_LENGTH;
+ }
+
+ data_size -= msg_ending;
+
+ if (data_size > 0)
+ {
+ ret_val = backend_mbedtls_cbc_mac_update(p_context,
+ p_data_in,
+ data_size,
+ p_data_out);
+ VERIFY_SUCCESS(ret_val);
+ }
+
+ ret_val = padding_pkcs7_add(&padding_buffer[0],
+ p_data_in + data_size,
+ msg_ending);
+ VERIFY_SUCCESS(ret_val);
+
+ ret_val = backend_mbedtls_cbc_mac_finalize(p_context,
+ &padding_buffer[0],
+ NRF_CRYPTO_AES_BLOCK_SIZE,
+ p_data_out,
+ p_data_out_size);
+ VERIFY_SUCCESS(ret_val);
+
+ return ret_val;
+}
+#endif
+
+static ret_code_t backend_mbedtls_update(void * const p_context,
+ uint8_t * p_data_in,
+ size_t data_size,
+ uint8_t * p_data_out)
+{
+ int error;
+
+ nrf_crypto_backend_mbedtls_aes_context_t * p_ctx =
+ (nrf_crypto_backend_mbedtls_aes_context_t *)p_context;
+
+ switch (p_ctx->any.header.p_info->mode)
+ {
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_MBEDTLS_AES_CBC)
+ case NRF_CRYPTO_AES_MODE_CBC:
+ case NRF_CRYPTO_AES_MODE_CBC_PAD_PCKS7:
+ error = mbedtls_aes_crypt_cbc(&p_ctx->cbc.context,
+ (int)p_ctx->cbc.backend.operation,
+ data_size,
+ p_ctx->cbc.backend.iv,
+ (uint8_t const *)p_data_in,
+ p_data_out);
+ break;
+#endif
+
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_MBEDTLS_AES_CTR)
+ case NRF_CRYPTO_AES_MODE_CTR:
+ {
+ size_t nc_off = 0;
+ uint8_t stream_block[NRF_CRYPTO_AES_BLOCK_SIZE];
+
+ error = mbedtls_aes_crypt_ctr(&p_ctx->ctr.context,
+ data_size,
+ &nc_off,
+ p_ctx->ctr.backend.iv,
+ stream_block,
+ (uint8_t const *)p_data_in,
+ p_data_out);
+ break;
+ }
+#endif
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_MBEDTLS_AES_CFB)
+ case NRF_CRYPTO_AES_MODE_CFB:
+ error = mbedtls_aes_crypt_cfb8(&p_ctx->cfb.context,
+ (int)p_ctx->cfb.backend.operation,
+ data_size,
+ p_ctx->cfb.backend.iv,
+ (uint8_t const *)p_data_in,
+ p_data_out);
+ break;
+#endif
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_MBEDTLS_AES_ECB)
+ case NRF_CRYPTO_AES_MODE_ECB:
+ case NRF_CRYPTO_AES_MODE_ECB_PAD_PCKS7:
+ error = backend_mbedtls_ecb_crypt(&p_ctx->ecb, p_data_in, p_data_out, data_size);
+ break;
+#endif
+
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_MBEDTLS_AES_CBC_MAC)
+ case NRF_CRYPTO_AES_MODE_CBC_MAC:
+ case NRF_CRYPTO_AES_MODE_CBC_MAC_PAD_PCKS7:
+ error = backend_mbedtls_cbc_mac_update(p_context, p_data_in, data_size, p_data_out);
+ break;
+#endif
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_MBEDTLS_AES_CMAC)
+ case NRF_CRYPTO_AES_MODE_CMAC:
+ error = mbedtls_cipher_cmac_update(&p_ctx->cmac.context,
+ p_data_in,
+ data_size);
+ break;
+#endif
+
+ default:
+ return NRF_ERROR_CRYPTO_CONTEXT_NOT_INITIALIZED;
+ }
+ BACKEND_ERROR_CHECK(error);
+
+ return NRF_SUCCESS;
+}
+
+static ret_code_t backend_mbedtls_finalize(void * const p_context,
+ uint8_t * p_data_in,
+ size_t data_size,
+ uint8_t * p_data_out,
+ size_t * p_data_out_size)
+{
+ ret_code_t ret_val;
+
+ nrf_crypto_backend_mbedtls_aes_context_t * p_ctx =
+ (nrf_crypto_backend_mbedtls_aes_context_t *)p_context;
+
+ if (*p_data_out_size < data_size)
+ {
+ return NRF_ERROR_CRYPTO_OUTPUT_LENGTH;
+ }
+
+ /* data is not multiple of 16 bytes */
+ if ((data_size & 0x0F) != 0)
+ {
+ if ((p_ctx->any.header.p_info->mode != NRF_CRYPTO_AES_MODE_CTR) &&
+ (p_ctx->any.header.p_info->mode != NRF_CRYPTO_AES_MODE_CFB))
+ {
+ /* There are separate handlers for AES modes with padding and for MAC modes. */
+ return NRF_ERROR_CRYPTO_INPUT_LENGTH;
+ }
+ }
+
+ ret_val = backend_mbedtls_update(p_context, p_data_in, data_size, p_data_out);
+ VERIFY_SUCCESS(ret_val);
+
+ *p_data_out_size = data_size;
+
+ return ret_val;
+}
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_MBEDTLS_AES_CMAC)
+static ret_code_t backend_mbedtls_cmac_finalize(void * const p_context,
+ uint8_t * p_data_in,
+ size_t data_size,
+ uint8_t * p_data_out,
+ size_t * p_data_out_size)
+{
+ int error;
+
+ nrf_crypto_backend_mbedtls_aes_context_t * p_ctx =
+ (nrf_crypto_backend_mbedtls_aes_context_t *)p_context;
+
+ if (*p_data_out_size < NRF_CRYPTO_AES_BLOCK_SIZE)
+ {
+ return NRF_ERROR_CRYPTO_OUTPUT_LENGTH;
+ }
+
+ error = mbedtls_cipher_cmac_update(&p_ctx->cmac.context, p_data_in, data_size);
+ BACKEND_ERROR_CHECK(error);
+
+ error = mbedtls_cipher_cmac_finish(&p_ctx->cmac.context, p_data_out);
+ BACKEND_ERROR_CHECK(error);
+
+ *p_data_out_size = NRF_CRYPTO_AES_BLOCK_SIZE;
+
+ return NRF_SUCCESS;
+}
+#endif
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_MBEDTLS_AES_CBC) || \
+ NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_MBEDTLS_AES_ECB)
+static ret_code_t backend_mbedtls_padding_finalize(void * const p_context,
+ uint8_t * p_data_in,
+ size_t data_size,
+ uint8_t * p_data_out,
+ size_t * p_data_out_size)
+{
+ ret_code_t ret_val;
+ size_t buff_out_size;
+ uint8_t padding_buffer[NRF_CRYPTO_AES_BLOCK_SIZE] = {0};
+ uint8_t msg_ending = (uint8_t)(data_size & (size_t)0x0F);
+
+ nrf_crypto_backend_mbedtls_aes_context_t * p_ctx =
+ (nrf_crypto_backend_mbedtls_aes_context_t *)p_context;
+
+ if (p_ctx->any.backend.operation == NRF_CRYPTO_DECRYPT)
+ {
+ ret_val = backend_mbedtls_finalize(p_context,
+ p_data_in,
+ data_size,
+ p_data_out,
+ p_data_out_size);
+ VERIFY_SUCCESS(ret_val);
+
+ ret_val = padding_pkcs7_remove(p_data_out,
+ p_data_out_size);
+ return ret_val;
+ }
+
+ /* -------------- ENCRYPTION --------------*/
+ data_size -= msg_ending;
+
+ if (*p_data_out_size < (data_size + NRF_CRYPTO_AES_BLOCK_SIZE))
+ {
+ /* no space for padding */
+ return NRF_ERROR_CRYPTO_OUTPUT_LENGTH;
+ }
+
+ if (data_size > 0)
+ {
+ /* Encrypt 16 byte blocks */
+ ret_val = backend_mbedtls_update(p_context,
+ p_data_in,
+ data_size,
+ p_data_out);
+ VERIFY_SUCCESS(ret_val);
+ }
+
+ ret_val = padding_pkcs7_add(&padding_buffer[0],
+ p_data_in + data_size,
+ msg_ending);
+ VERIFY_SUCCESS(ret_val);
+
+ buff_out_size = *p_data_out_size - data_size;
+
+ ret_val = backend_mbedtls_finalize(p_context,
+ &padding_buffer[0],
+ NRF_CRYPTO_AES_BLOCK_SIZE,
+ p_data_out + data_size,
+ &buff_out_size);
+ VERIFY_SUCCESS(ret_val);
+
+ *p_data_out_size = buff_out_size + data_size;
+
+ return ret_val;
+}
+#endif
+
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_MBEDTLS_AES_CBC)
+nrf_crypto_aes_info_t const g_nrf_crypto_aes_cbc_128_info =
+{
+ .mode = NRF_CRYPTO_AES_MODE_CBC,
+ .key_size = NRF_CRYPTO_KEY_SIZE_128,
+ .context_size = sizeof(nrf_crypto_backend_aes_cbc_context_t),
+
+ .init_fn = backend_mbedtls_init,
+ .uninit_fn = backend_mbedtls_uninit,
+ .key_set_fn = backend_mbedtls_key_set,
+ .iv_set_fn = backend_mbedtls_iv_set,
+ .iv_get_fn = backend_mbedtls_iv_get,
+ .update_fn = backend_mbedtls_update,
+ .finalize_fn = backend_mbedtls_finalize
+};
+
+nrf_crypto_aes_info_t const g_nrf_crypto_aes_cbc_192_info =
+{
+ .mode = NRF_CRYPTO_AES_MODE_CBC,
+ .key_size = NRF_CRYPTO_KEY_SIZE_192,
+ .context_size = sizeof(nrf_crypto_backend_aes_cbc_context_t),
+
+ .init_fn = backend_mbedtls_init,
+ .uninit_fn = backend_mbedtls_uninit,
+ .key_set_fn = backend_mbedtls_key_set,
+ .iv_set_fn = backend_mbedtls_iv_set,
+ .iv_get_fn = backend_mbedtls_iv_get,
+ .update_fn = backend_mbedtls_update,
+ .finalize_fn = backend_mbedtls_finalize
+};
+
+nrf_crypto_aes_info_t const g_nrf_crypto_aes_cbc_256_info =
+{
+ .mode = NRF_CRYPTO_AES_MODE_CBC,
+ .key_size = NRF_CRYPTO_KEY_SIZE_256,
+ .context_size = sizeof(nrf_crypto_backend_aes_cbc_context_t),
+
+ .init_fn = backend_mbedtls_init,
+ .uninit_fn = backend_mbedtls_uninit,
+ .key_set_fn = backend_mbedtls_key_set,
+ .iv_set_fn = backend_mbedtls_iv_set,
+ .iv_get_fn = backend_mbedtls_iv_get,
+ .update_fn = backend_mbedtls_update,
+ .finalize_fn = backend_mbedtls_finalize
+};
+
+nrf_crypto_aes_info_t const g_nrf_crypto_aes_cbc_128_pad_pkcs7_info =
+{
+ .mode = NRF_CRYPTO_AES_MODE_CBC_PAD_PCKS7,
+ .key_size = NRF_CRYPTO_KEY_SIZE_128,
+ .context_size = sizeof(nrf_crypto_backend_aes_cbc_context_t),
+
+ .init_fn = backend_mbedtls_init,
+ .uninit_fn = backend_mbedtls_uninit,
+ .key_set_fn = backend_mbedtls_key_set,
+ .iv_set_fn = backend_mbedtls_iv_set,
+ .iv_get_fn = backend_mbedtls_iv_get,
+ .update_fn = backend_mbedtls_update,
+ .finalize_fn = backend_mbedtls_padding_finalize
+};
+
+nrf_crypto_aes_info_t const g_nrf_crypto_aes_cbc_192_pad_pkcs7_info =
+{
+ .mode = NRF_CRYPTO_AES_MODE_CBC_PAD_PCKS7,
+ .key_size = NRF_CRYPTO_KEY_SIZE_192,
+ .context_size = sizeof(nrf_crypto_backend_aes_cbc_context_t),
+
+ .init_fn = backend_mbedtls_init,
+ .uninit_fn = backend_mbedtls_uninit,
+ .key_set_fn = backend_mbedtls_key_set,
+ .iv_set_fn = backend_mbedtls_iv_set,
+ .iv_get_fn = backend_mbedtls_iv_get,
+ .update_fn = backend_mbedtls_update,
+ .finalize_fn = backend_mbedtls_padding_finalize
+};
+
+nrf_crypto_aes_info_t const g_nrf_crypto_aes_cbc_256_pad_pkcs7_info =
+{
+ .mode = NRF_CRYPTO_AES_MODE_CBC_PAD_PCKS7,
+ .key_size = NRF_CRYPTO_KEY_SIZE_256,
+ .context_size = sizeof(nrf_crypto_backend_aes_cbc_context_t),
+
+ .init_fn = backend_mbedtls_init,
+ .uninit_fn = backend_mbedtls_uninit,
+ .key_set_fn = backend_mbedtls_key_set,
+ .iv_set_fn = backend_mbedtls_iv_set,
+ .iv_get_fn = backend_mbedtls_iv_get,
+ .update_fn = backend_mbedtls_update,
+ .finalize_fn = backend_mbedtls_padding_finalize
+};
+#endif
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_MBEDTLS_AES_CTR)
+nrf_crypto_aes_info_t const g_nrf_crypto_aes_ctr_128_info =
+{
+ .mode = NRF_CRYPTO_AES_MODE_CTR,
+ .key_size = NRF_CRYPTO_KEY_SIZE_128,
+ .context_size = sizeof(nrf_crypto_backend_aes_ctr_context_t),
+
+ .init_fn = backend_mbedtls_init,
+ .uninit_fn = backend_mbedtls_uninit,
+ .key_set_fn = backend_mbedtls_key_set,
+ .iv_set_fn = backend_mbedtls_iv_set,
+ .iv_get_fn = backend_mbedtls_iv_get,
+ .update_fn = backend_mbedtls_update,
+ .finalize_fn = backend_mbedtls_finalize
+};
+
+nrf_crypto_aes_info_t const g_nrf_crypto_aes_ctr_192_info =
+{
+ .mode = NRF_CRYPTO_AES_MODE_CTR,
+ .key_size = NRF_CRYPTO_KEY_SIZE_192,
+ .context_size = sizeof(nrf_crypto_backend_aes_ctr_context_t),
+
+ .init_fn = backend_mbedtls_init,
+ .uninit_fn = backend_mbedtls_uninit,
+ .key_set_fn = backend_mbedtls_key_set,
+ .iv_set_fn = backend_mbedtls_iv_set,
+ .iv_get_fn = backend_mbedtls_iv_get,
+ .update_fn = backend_mbedtls_update,
+ .finalize_fn = backend_mbedtls_finalize
+};
+
+nrf_crypto_aes_info_t const g_nrf_crypto_aes_ctr_256_info =
+{
+ .mode = NRF_CRYPTO_AES_MODE_CTR,
+ .key_size = NRF_CRYPTO_KEY_SIZE_256,
+ .context_size = sizeof(nrf_crypto_backend_aes_ctr_context_t),
+
+ .init_fn = backend_mbedtls_init,
+ .uninit_fn = backend_mbedtls_uninit,
+ .key_set_fn = backend_mbedtls_key_set,
+ .iv_set_fn = backend_mbedtls_iv_set,
+ .iv_get_fn = backend_mbedtls_iv_get,
+ .update_fn = backend_mbedtls_update,
+ .finalize_fn = backend_mbedtls_finalize
+};
+#endif
+
+// CFB
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_MBEDTLS_AES_CFB)
+nrf_crypto_aes_info_t const g_nrf_crypto_aes_cfb_128_info =
+{
+ .mode = NRF_CRYPTO_AES_MODE_CFB,
+ .key_size = NRF_CRYPTO_KEY_SIZE_128,
+ .context_size = sizeof(nrf_crypto_backend_aes_cfb_context_t),
+
+ .init_fn = backend_mbedtls_init,
+ .uninit_fn = backend_mbedtls_uninit,
+ .key_set_fn = backend_mbedtls_key_set,
+ .iv_set_fn = backend_mbedtls_iv_set,
+ .iv_get_fn = backend_mbedtls_iv_get,
+ .update_fn = backend_mbedtls_update,
+ .finalize_fn = backend_mbedtls_finalize
+};
+
+nrf_crypto_aes_info_t const g_nrf_crypto_aes_cfb_192_info =
+{
+ .mode = NRF_CRYPTO_AES_MODE_CFB,
+ .key_size = NRF_CRYPTO_KEY_SIZE_192,
+ .context_size = sizeof(nrf_crypto_backend_aes_cfb_context_t),
+
+ .init_fn = backend_mbedtls_init,
+ .uninit_fn = backend_mbedtls_uninit,
+ .key_set_fn = backend_mbedtls_key_set,
+ .iv_set_fn = backend_mbedtls_iv_set,
+ .iv_get_fn = backend_mbedtls_iv_get,
+ .update_fn = backend_mbedtls_update,
+ .finalize_fn = backend_mbedtls_finalize
+};
+
+nrf_crypto_aes_info_t const g_nrf_crypto_aes_cfb_256_info =
+{
+ .mode = NRF_CRYPTO_AES_MODE_CFB,
+ .key_size = NRF_CRYPTO_KEY_SIZE_256,
+ .context_size = sizeof(nrf_crypto_backend_aes_cfb_context_t),
+
+ .init_fn = backend_mbedtls_init,
+ .uninit_fn = backend_mbedtls_uninit,
+ .key_set_fn = backend_mbedtls_key_set,
+ .iv_set_fn = backend_mbedtls_iv_set,
+ .iv_get_fn = backend_mbedtls_iv_get,
+ .update_fn = backend_mbedtls_update,
+ .finalize_fn = backend_mbedtls_finalize
+};
+#endif
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_MBEDTLS_AES_ECB)
+nrf_crypto_aes_info_t const g_nrf_crypto_aes_ecb_128_info =
+{
+ .mode = NRF_CRYPTO_AES_MODE_ECB,
+ .key_size = NRF_CRYPTO_KEY_SIZE_128,
+ .context_size = sizeof(nrf_crypto_backend_aes_ecb_context_t),
+
+ .init_fn = backend_mbedtls_init,
+ .uninit_fn = backend_mbedtls_uninit,
+ .key_set_fn = backend_mbedtls_key_set,
+ .iv_set_fn = NULL,
+ .iv_get_fn = NULL,
+ .update_fn = backend_mbedtls_update,
+ .finalize_fn = backend_mbedtls_finalize
+};
+
+nrf_crypto_aes_info_t const g_nrf_crypto_aes_ecb_192_info =
+{
+ .mode = NRF_CRYPTO_AES_MODE_ECB,
+ .key_size = NRF_CRYPTO_KEY_SIZE_192,
+ .context_size = sizeof(nrf_crypto_backend_aes_ecb_context_t),
+
+ .init_fn = backend_mbedtls_init,
+ .uninit_fn = backend_mbedtls_uninit,
+ .key_set_fn = backend_mbedtls_key_set,
+ .iv_set_fn = NULL,
+ .iv_get_fn = NULL,
+ .update_fn = backend_mbedtls_update,
+ .finalize_fn = backend_mbedtls_finalize
+};
+
+nrf_crypto_aes_info_t const g_nrf_crypto_aes_ecb_256_info =
+{
+ .mode = NRF_CRYPTO_AES_MODE_ECB,
+ .key_size = NRF_CRYPTO_KEY_SIZE_256,
+ .context_size = sizeof(nrf_crypto_backend_aes_ecb_context_t),
+
+ .init_fn = backend_mbedtls_init,
+ .uninit_fn = backend_mbedtls_uninit,
+ .key_set_fn = backend_mbedtls_key_set,
+ .iv_set_fn = NULL,
+ .iv_get_fn = NULL,
+ .update_fn = backend_mbedtls_update,
+ .finalize_fn = backend_mbedtls_finalize
+};
+
+nrf_crypto_aes_info_t const g_nrf_crypto_aes_ecb_128_pad_pkcs7_info =
+{
+ .mode = NRF_CRYPTO_AES_MODE_ECB_PAD_PCKS7,
+ .key_size = NRF_CRYPTO_KEY_SIZE_128,
+ .context_size = sizeof(nrf_crypto_backend_aes_ecb_context_t),
+
+ .init_fn = backend_mbedtls_init,
+ .uninit_fn = backend_mbedtls_uninit,
+ .key_set_fn = backend_mbedtls_key_set,
+ .iv_set_fn = NULL,
+ .iv_get_fn = NULL,
+ .update_fn = backend_mbedtls_update,
+ .finalize_fn = backend_mbedtls_padding_finalize
+};
+
+nrf_crypto_aes_info_t const g_nrf_crypto_aes_ecb_192_pad_pkcs7_info =
+{
+ .mode = NRF_CRYPTO_AES_MODE_ECB_PAD_PCKS7,
+ .key_size = NRF_CRYPTO_KEY_SIZE_192,
+ .context_size = sizeof(nrf_crypto_backend_aes_ecb_context_t),
+
+ .init_fn = backend_mbedtls_init,
+ .uninit_fn = backend_mbedtls_uninit,
+ .key_set_fn = backend_mbedtls_key_set,
+ .iv_set_fn = NULL,
+ .iv_get_fn = NULL,
+ .update_fn = backend_mbedtls_update,
+ .finalize_fn = backend_mbedtls_padding_finalize
+};
+
+nrf_crypto_aes_info_t const g_nrf_crypto_aes_ecb_256_pad_pkcs7_info =
+{
+ .mode = NRF_CRYPTO_AES_MODE_ECB_PAD_PCKS7,
+ .key_size = NRF_CRYPTO_KEY_SIZE_256,
+ .context_size = sizeof(nrf_crypto_backend_aes_ecb_context_t),
+
+ .init_fn = backend_mbedtls_init,
+ .uninit_fn = backend_mbedtls_uninit,
+ .key_set_fn = backend_mbedtls_key_set,
+ .iv_set_fn = NULL,
+ .iv_get_fn = NULL,
+ .update_fn = backend_mbedtls_update,
+ .finalize_fn = backend_mbedtls_padding_finalize
+};
+#endif
+
+
+// CBC MAC
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_MBEDTLS_AES_CBC_MAC)
+nrf_crypto_aes_info_t const g_nrf_crypto_aes_cbc_mac_128_info =
+{
+ .mode = NRF_CRYPTO_AES_MODE_CBC_MAC,
+ .key_size = NRF_CRYPTO_KEY_SIZE_128,
+ .context_size = sizeof(nrf_crypto_backend_aes_cbc_mac_context_t),
+
+ .init_fn = backend_mbedtls_init,
+ .uninit_fn = backend_mbedtls_uninit,
+ .key_set_fn = backend_mbedtls_key_set,
+ .iv_set_fn = backend_mbedtls_iv_set,
+ .iv_get_fn = backend_mbedtls_iv_get,
+ .update_fn = backend_mbedtls_update,
+ .finalize_fn = backend_mbedtls_cbc_mac_finalize
+};
+
+nrf_crypto_aes_info_t const g_nrf_crypto_aes_cbc_mac_192_info =
+{
+ .mode = NRF_CRYPTO_AES_MODE_CBC_MAC,
+ .key_size = NRF_CRYPTO_KEY_SIZE_192,
+ .context_size = sizeof(nrf_crypto_backend_aes_cbc_mac_context_t),
+
+ .init_fn = backend_mbedtls_init,
+ .uninit_fn = backend_mbedtls_uninit,
+ .key_set_fn = backend_mbedtls_key_set,
+ .iv_set_fn = backend_mbedtls_iv_set,
+ .iv_get_fn = backend_mbedtls_iv_get,
+ .update_fn = backend_mbedtls_update,
+ .finalize_fn = backend_mbedtls_cbc_mac_finalize
+};
+
+nrf_crypto_aes_info_t const g_nrf_crypto_aes_cbc_mac_256_info =
+{
+ .mode = NRF_CRYPTO_AES_MODE_CBC_MAC,
+ .key_size = NRF_CRYPTO_KEY_SIZE_256,
+ .context_size = sizeof(nrf_crypto_backend_aes_cbc_mac_context_t),
+
+ .init_fn = backend_mbedtls_init,
+ .uninit_fn = backend_mbedtls_uninit,
+ .key_set_fn = backend_mbedtls_key_set,
+ .iv_set_fn = backend_mbedtls_iv_set,
+ .iv_get_fn = backend_mbedtls_iv_get,
+ .update_fn = backend_mbedtls_update,
+ .finalize_fn = backend_mbedtls_cbc_mac_finalize
+};
+
+nrf_crypto_aes_info_t const g_nrf_crypto_aes_cbc_mac_128_pad_pkcs7_info =
+{
+ .mode = NRF_CRYPTO_AES_MODE_CBC_MAC_PAD_PCKS7,
+ .key_size = NRF_CRYPTO_KEY_SIZE_128,
+ .context_size = sizeof(nrf_crypto_backend_aes_cbc_mac_context_t),
+
+ .init_fn = backend_mbedtls_init,
+ .uninit_fn = backend_mbedtls_uninit,
+ .key_set_fn = backend_mbedtls_key_set,
+ .iv_set_fn = backend_mbedtls_iv_set,
+ .iv_get_fn = backend_mbedtls_iv_get,
+ .update_fn = backend_mbedtls_update,
+ .finalize_fn = backend_mbedtls_cbc_mac_padding_finalize
+};
+
+nrf_crypto_aes_info_t const g_nrf_crypto_aes_cbc_mac_192_pad_pkcs7_info =
+{
+ .mode = NRF_CRYPTO_AES_MODE_CBC_MAC_PAD_PCKS7,
+ .key_size = NRF_CRYPTO_KEY_SIZE_192,
+ .context_size = sizeof(nrf_crypto_backend_aes_cbc_mac_context_t),
+
+ .init_fn = backend_mbedtls_init,
+ .uninit_fn = backend_mbedtls_uninit,
+ .key_set_fn = backend_mbedtls_key_set,
+ .iv_set_fn = backend_mbedtls_iv_set,
+ .iv_get_fn = backend_mbedtls_iv_get,
+ .update_fn = backend_mbedtls_update,
+ .finalize_fn = backend_mbedtls_cbc_mac_padding_finalize
+};
+
+nrf_crypto_aes_info_t const g_nrf_crypto_aes_cbc_mac_256_pad_pkcs7_info =
+{
+ .mode = NRF_CRYPTO_AES_MODE_CBC_MAC_PAD_PCKS7,
+ .key_size = NRF_CRYPTO_KEY_SIZE_256,
+ .context_size = sizeof(nrf_crypto_backend_aes_cbc_mac_context_t),
+
+ .init_fn = backend_mbedtls_init,
+ .uninit_fn = backend_mbedtls_uninit,
+ .key_set_fn = backend_mbedtls_key_set,
+ .iv_set_fn = backend_mbedtls_iv_set,
+ .iv_get_fn = backend_mbedtls_iv_get,
+ .update_fn = backend_mbedtls_update,
+ .finalize_fn = backend_mbedtls_cbc_mac_padding_finalize
+};
+
+#endif
+
+// CMAC
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_MBEDTLS_AES_CMAC)
+nrf_crypto_aes_info_t const g_nrf_crypto_aes_cmac_128_info =
+{
+ .mode = NRF_CRYPTO_AES_MODE_CMAC,
+ .key_size = NRF_CRYPTO_KEY_SIZE_128,
+ .context_size = sizeof(nrf_crypto_backend_aes_cmac_context_t),
+
+ .init_fn = backend_mbedtls_init,
+ .uninit_fn = backend_mbedtls_uninit,
+ .key_set_fn = backend_mbedtls_key_set,
+ .iv_set_fn = NULL,
+ .iv_get_fn = NULL,
+ .update_fn = backend_mbedtls_update,
+ .finalize_fn = backend_mbedtls_cmac_finalize
+};
+
+nrf_crypto_aes_info_t const g_nrf_crypto_aes_cmac_192_info =
+{
+ .mode = NRF_CRYPTO_AES_MODE_CMAC,
+ .key_size = NRF_CRYPTO_KEY_SIZE_192,
+ .context_size = sizeof(nrf_crypto_backend_aes_cmac_context_t),
+
+ .init_fn = backend_mbedtls_init,
+ .uninit_fn = backend_mbedtls_uninit,
+ .key_set_fn = backend_mbedtls_key_set,
+ .iv_set_fn = NULL,
+ .iv_get_fn = NULL,
+ .update_fn = backend_mbedtls_update,
+ .finalize_fn = backend_mbedtls_cmac_finalize
+};
+
+nrf_crypto_aes_info_t const g_nrf_crypto_aes_cmac_256_info =
+{
+ .mode = NRF_CRYPTO_AES_MODE_CMAC,
+ .key_size = NRF_CRYPTO_KEY_SIZE_256,
+ .context_size = sizeof(nrf_crypto_backend_aes_cmac_context_t),
+
+ .init_fn = backend_mbedtls_init,
+ .uninit_fn = backend_mbedtls_uninit,
+ .key_set_fn = backend_mbedtls_key_set,
+ .iv_set_fn = NULL,
+ .iv_get_fn = NULL,
+ .update_fn = backend_mbedtls_update,
+ .finalize_fn = backend_mbedtls_cmac_finalize
+};
+#endif
+
+#endif // #if NRF_MODULE_ENABLED(NRF_CRYPTO_MBEDTLS_AES)
+#endif // MODULE_ENABLED(NRF_CRYPTO)
+
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/mbedtls/mbedtls_backend_aes.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/mbedtls/mbedtls_backend_aes.h
new file mode 100644
index 0000000..3813eb3
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/mbedtls/mbedtls_backend_aes.h
@@ -0,0 +1,227 @@
+/**
+ * Copyright (c) 2018 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+
+#ifndef MBEDTLS_BACKEND_AES_H__
+#define MBEDTLS_BACKEND_AES_H__
+
+/** @file
+ *
+ * @defgroup nrf_crypto_mbedtls_backend_aes nrf_crypto mbed TLS backend AES
+ * @{
+ * @ingroup nrf_crypto_mbedtls_backend
+ *
+ * @brief AES functionality provided by the nrf_crypto mbed TLS backend.
+ */
+
+#include "sdk_config.h"
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_MBEDTLS)
+
+/*lint -save -e????*/
+#include "mbedtls/aes.h"
+#include "mbedtls/cmac.h"
+#include "mbedtls/platform.h"
+/*lint -restore*/
+#include "nrf_crypto_error.h"
+#include "nrf_crypto_types.h"
+#include "nrf_crypto_aes_shared.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* AES CBC */
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_MBEDTLS_AES_CBC)
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_AES_CBC)
+#error "Duplicate definition of AES CBC mode. More than one backend enabled");
+#endif
+/* Flag that AES CBC is enabled in backend */
+#define NRF_CRYPTO_AES_CBC_ENABLED 1
+#undef NRF_CRYPTO_AES_ENABLED
+#define NRF_CRYPTO_AES_ENABLED 1 // Flag that nrf_crypto_aes frontend can be compiled
+#undef NRF_CRYPTO_MBEDTLS_AES_ENABLED
+#define NRF_CRYPTO_MBEDTLS_AES_ENABLED 1
+
+/* defines for test purposes */
+#define NRF_CRYPTO_AES_CBC_128_ENABLED 1
+#define NRF_CRYPTO_AES_CBC_192_ENABLED 1
+#define NRF_CRYPTO_AES_CBC_256_ENABLED 1
+
+typedef struct
+{
+ nrf_crypto_aes_internal_context_t header; /**< Common header for context. */
+ nrf_crypto_backend_aes_ctx_t backend; /**< Backend-specific internal context. */
+ mbedtls_aes_context context; /**< AES context internal to mbed TLS. */
+} nrf_crypto_backend_aes_cbc_context_t;
+#endif
+
+
+/* AES CTR */
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_MBEDTLS_AES_CTR)
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_AES_CTR)
+#error "Duplicate definition of AES CTR mode. More than one backend enabled");
+#endif
+#define NRF_CRYPTO_AES_CTR_ENABLED 1
+#undef NRF_CRYPTO_AES_ENABLED
+#define NRF_CRYPTO_AES_ENABLED 1 // Flag that nrf_crypto_aes frontend can be compiled
+#undef NRF_CRYPTO_MBEDTLS_AES_ENABLED
+#define NRF_CRYPTO_MBEDTLS_AES_ENABLED 1
+
+/* defines for test purposes */
+#define NRF_CRYPTO_AES_CTR_128_ENABLED 1
+#define NRF_CRYPTO_AES_CTR_192_ENABLED 1
+#define NRF_CRYPTO_AES_CTR_256_ENABLED 1
+
+typedef struct
+{
+ nrf_crypto_aes_internal_context_t header; /**< Common header for context. */
+ nrf_crypto_backend_aes_ctx_t backend; /**< Backend-specific internal context. */
+ mbedtls_aes_context context; /**< AES context internal to mbed TLS. */
+} nrf_crypto_backend_aes_ctr_context_t;
+#endif
+
+/* AES CFB */
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_MBEDTLS_AES_CFB)
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_AES_CFB)
+#error "Duplicate definition of AES CFB mode. More than one backend enabled");
+#endif
+#define NRF_CRYPTO_AES_CFB_ENABLED 1
+#undef NRF_CRYPTO_AES_ENABLED
+#define NRF_CRYPTO_AES_ENABLED 1 // Flag that nrf_crypto_aes frontend can be compiled
+#undef NRF_CRYPTO_MBEDTLS_AES_ENABLED
+#define NRF_CRYPTO_MBEDTLS_AES_ENABLED 1
+
+/* defines for test purposes */
+#define NRF_CRYPTO_AES_CFB_128_ENABLED 1
+#define NRF_CRYPTO_AES_CFB_192_ENABLED 1
+#define NRF_CRYPTO_AES_CFB_256_ENABLED 1
+
+typedef struct
+{
+ nrf_crypto_aes_internal_context_t header; /**< Common header for context. */
+ nrf_crypto_backend_aes_ctx_t backend; /**< Backend-specific internal context. */
+ mbedtls_aes_context context; /**< AES context internal to mbed TLS. */
+} nrf_crypto_backend_aes_cfb_context_t;
+#endif
+
+/* AES ECB */
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_MBEDTLS_AES_ECB)
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_AES_ECB)
+#error "Duplicate definition of AES ECB mode. More than one backend enabled");
+#endif
+#define NRF_CRYPTO_AES_ECB_ENABLED 1
+#undef NRF_CRYPTO_AES_ENABLED
+#define NRF_CRYPTO_AES_ENABLED 1
+#undef NRF_CRYPTO_MBEDTLS_AES_ENABLED
+#define NRF_CRYPTO_MBEDTLS_AES_ENABLED 1
+
+/* defines for test purposes */
+#define NRF_CRYPTO_AES_ECB_128_ENABLED 1
+#define NRF_CRYPTO_AES_ECB_192_ENABLED 1
+#define NRF_CRYPTO_AES_ECB_256_ENABLED 1
+
+typedef struct
+{
+ nrf_crypto_aes_internal_context_t header; /**< Common header for context. */
+ nrf_crypto_backend_no_iv_aes_ctx_t backend; /**< Backend-specific internal context. */
+ mbedtls_aes_context context; /**< AES context internal to mbed TLS. */
+} nrf_crypto_backend_aes_ecb_context_t;
+#endif
+
+
+/* AES CBC MAC */
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_MBEDTLS_AES_CBC_MAC)
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_AES_CBC_MAC)
+#error "Duplicate definition of AES CBC MAC mode. More than one backend enabled");
+#endif
+/* Flag that AES CBC MAC is enabled in backend */
+#define NRF_CRYPTO_AES_CBC_MAC_ENABLED 1
+#undef NRF_CRYPTO_AES_ENABLED
+#define NRF_CRYPTO_AES_ENABLED 1 // Flag that nrf_crypto_aes frontend can be compiled
+#undef NRF_CRYPTO_MBEDTLS_AES_ENABLED
+#define NRF_CRYPTO_MBEDTLS_AES_ENABLED 1
+
+/* defines for test purposes */
+#define NRF_CRYPTO_AES_CBC_MAC_128_ENABLED 1
+#define NRF_CRYPTO_AES_CBC_MAC_192_ENABLED 1
+#define NRF_CRYPTO_AES_CBC_MAC_256_ENABLED 1
+
+typedef struct
+{
+ nrf_crypto_aes_internal_context_t header; /**< Common header for context. */
+ nrf_crypto_backend_aes_ctx_t backend; /**< Backend-specific internal context. */
+ mbedtls_aes_context context; /**< AES context internal to mbed TLS. */
+} nrf_crypto_backend_aes_cbc_mac_context_t;
+#endif
+
+
+/* AES CMAC */
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_MBEDTLS_AES_CMAC)
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_AES_CMAC)
+#error "Duplicate definition of AES CMAC mode. More than one backend enabled");
+#endif
+#define NRF_CRYPTO_AES_CMAC_ENABLED 1
+#undef NRF_CRYPTO_AES_ENABLED
+#define NRF_CRYPTO_AES_ENABLED 1 // Flag that nrf_crypto_aes frontend can be compiled
+#undef NRF_CRYPTO_MBEDTLS_AES_ENABLED
+#define NRF_CRYPTO_MBEDTLS_AES_ENABLED 1
+
+/* defines for test purposes */
+#define NRF_CRYPTO_AES_CMAC_128_ENABLED 1
+#define NRF_CRYPTO_AES_CMAC_192_ENABLED 1
+#define NRF_CRYPTO_AES_CMAC_256_ENABLED 1
+
+typedef struct
+{
+ nrf_crypto_aes_internal_context_t header; /**< Common header for context. */
+ nrf_crypto_backend_no_iv_aes_ctx_t backend; /**< Backend-specific internal context. */
+ mbedtls_cipher_context_t context; /**< AES context internal to mbedtls. */
+} nrf_crypto_backend_aes_cmac_context_t;
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_MBEDTLS)
+
+/** @} */
+
+#endif // MBEDTLS_BACKEND_AES_H__
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/mbedtls/mbedtls_backend_aes_aead.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/mbedtls/mbedtls_backend_aes_aead.c
new file mode 100644
index 0000000..eb0319e
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/mbedtls/mbedtls_backend_aes_aead.c
@@ -0,0 +1,384 @@
+/**
+ * Copyright (c) 2018 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+
+#include "sdk_common.h"
+#include <drivers/nrfx_common.h>
+#if NRF_MODULE_ENABLED(NRF_CRYPTO)
+
+#include "nrf_crypto_error.h"
+#include "mbedtls_backend_aes_aead.h"
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_MBEDTLS_AES_AEAD)
+
+/**@internal @brief Type declaration of a template suiting all possible context sizes
+ * for this backend.
+ */
+typedef union
+{
+ nrf_crypto_aead_internal_context_t header; /**< Common header for context. */
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_MBEDTLS_AES_CCM)
+ nrf_crypto_backend_aes_ccm_context_t ccm;
+#endif
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_MBEDTLS_AES_GCM)
+ nrf_crypto_backend_aes_gcm_context_t gcm;
+#endif
+} nrf_crypto_backend_mbedtls_aes_aead_context_t;
+
+
+static ret_code_t result_get(int error)
+{
+ ret_code_t ret_val;
+
+ switch (error)
+ {
+ case 0:
+ ret_val = NRF_SUCCESS;
+ break;
+
+ case MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA:
+ ret_val = NRF_ERROR_CRYPTO_INPUT_LENGTH;
+ break;
+
+ case MBEDTLS_ERR_CIPHER_ALLOC_FAILED:
+ ret_val = NRF_ERROR_CRYPTO_ALLOC_FAILED;
+ break;
+
+ case MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE:
+ ret_val = NRF_ERROR_CRYPTO_FEATURE_UNAVAILABLE;
+ break;
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_MBEDTLS_AES_CCM)
+ case MBEDTLS_ERR_CCM_BAD_INPUT:
+ ret_val = NRF_ERROR_CRYPTO_INVALID_PARAM;
+ break;
+
+ case MBEDTLS_ERR_CCM_AUTH_FAILED:
+ ret_val = NRF_ERROR_CRYPTO_AEAD_INVALID_MAC;
+ break;
+#endif
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_MBEDTLS_AES_GCM)
+ case MBEDTLS_ERR_GCM_BAD_INPUT:
+ ret_val = NRF_ERROR_CRYPTO_INVALID_PARAM;
+ break;
+
+ case MBEDTLS_ERR_GCM_AUTH_FAILED:
+ ret_val = NRF_ERROR_CRYPTO_AEAD_INVALID_MAC;
+ break;
+#endif
+
+ default:
+ ret_val = NRF_ERROR_CRYPTO_INTERNAL;
+ break;
+ }
+ return ret_val;
+}
+
+static ret_code_t backend_mbedtls_init(void * const p_context, uint8_t * p_key)
+{
+ int result;
+ ret_code_t ret_val;
+
+ nrf_crypto_backend_mbedtls_aes_aead_context_t * p_ctx =
+ (nrf_crypto_backend_mbedtls_aes_aead_context_t *)p_context;
+
+ if ((p_ctx->header.p_info->key_size != NRF_CRYPTO_KEY_SIZE_128) &&
+ (p_ctx->header.p_info->key_size != NRF_CRYPTO_KEY_SIZE_192) &&
+ (p_ctx->header.p_info->key_size != NRF_CRYPTO_KEY_SIZE_256))
+ {
+ return NRF_ERROR_CRYPTO_KEY_SIZE;
+ }
+
+ switch (p_ctx->header.p_info->mode)
+ {
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_MBEDTLS_AES_CCM)
+ case NRF_CRYPTO_AEAD_MODE_AES_CCM:
+ mbedtls_ccm_init(&p_ctx->ccm.context);
+
+ result = mbedtls_ccm_setkey(&p_ctx->ccm.context,
+ MBEDTLS_CIPHER_ID_AES,
+ p_key,
+ p_ctx->header.p_info->key_size);
+ break;
+#endif
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_MBEDTLS_AES_GCM)
+ case NRF_CRYPTO_AEAD_MODE_AES_GCM:
+ mbedtls_gcm_init(&p_ctx->gcm.context);
+
+ result = mbedtls_gcm_setkey(&p_ctx->gcm.context,
+ MBEDTLS_CIPHER_ID_AES,
+ p_key,
+ p_ctx->header.p_info->key_size);
+ break;
+#endif
+
+ default:
+ return NRF_ERROR_CRYPTO_FEATURE_UNAVAILABLE;
+ }
+
+ if (result != 0)
+ {
+ ret_val = result_get(result);
+ return ret_val;
+ }
+
+ return NRF_SUCCESS;
+}
+
+static ret_code_t backend_mbedtls_uninit(void * const p_context)
+{
+ nrf_crypto_backend_mbedtls_aes_aead_context_t * p_ctx =
+ (nrf_crypto_backend_mbedtls_aes_aead_context_t *)p_context;
+
+ if (p_ctx->header.p_info->mode == NRF_CRYPTO_AEAD_MODE_AES_CCM)
+ {
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_MBEDTLS_AES_CCM)
+ mbedtls_ccm_free(&p_ctx->ccm.context);
+#endif
+ }
+ else
+ {
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_MBEDTLS_AES_GCM)
+ mbedtls_gcm_free(&p_ctx->gcm.context);
+#endif
+ }
+
+ return NRF_SUCCESS;
+}
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_MBEDTLS_AES_CCM)
+static ret_code_t backend_mbedtls_ccm_crypt(void * const p_context,
+ nrf_crypto_operation_t operation,
+ uint8_t * p_nonce,
+ uint8_t nonce_size,
+ uint8_t * p_adata,
+ size_t adata_size,
+ uint8_t * p_data_in,
+ size_t data_in_size,
+ uint8_t * p_data_out,
+ uint8_t * p_mac,
+ uint8_t mac_size)
+{
+ int result;
+ ret_code_t ret_val;
+
+ nrf_crypto_backend_mbedtls_aes_aead_context_t * p_ctx =
+ (nrf_crypto_backend_mbedtls_aes_aead_context_t *)p_context;
+
+ /* CCM mode allows following MAC sizes: [4, 6, 8, 10, 12, 14, 16] */
+ if ((mac_size < NRF_CRYPTO_AES_CCM_MAC_MIN) || (mac_size > NRF_CRYPTO_AES_CCM_MAC_MAX) ||
+ ((mac_size & 0x01) != 0))
+ {
+ return NRF_ERROR_CRYPTO_AEAD_MAC_SIZE;
+ }
+
+ if ((nonce_size < NRF_CRYPTO_AES_CCM_NONCE_SIZE_MIN) ||
+ (nonce_size > NRF_CRYPTO_AES_CCM_NONCE_SIZE_MAX))
+ {
+ return NRF_ERROR_CRYPTO_AEAD_NONCE_SIZE;
+ }
+
+ if (operation == NRF_CRYPTO_ENCRYPT)
+ {
+ result = mbedtls_ccm_encrypt_and_tag(&p_ctx->ccm.context,
+ data_in_size,
+ p_nonce,
+ nonce_size,
+ p_adata,
+ adata_size,
+ p_data_in,
+ p_data_out,
+ p_mac,
+ (size_t)mac_size);
+ }
+ else if (operation == NRF_CRYPTO_DECRYPT)
+ {
+ result = mbedtls_ccm_auth_decrypt(&p_ctx->ccm.context,
+ data_in_size,
+ p_nonce,
+ nonce_size,
+ p_adata,
+ adata_size,
+ p_data_in,
+ p_data_out,
+ p_mac,
+ (size_t)mac_size);
+ }
+ else
+ {
+ return NRF_ERROR_CRYPTO_INVALID_PARAM;
+ }
+
+ ret_val = result_get(result);
+
+ return ret_val;
+}
+#endif
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_MBEDTLS_AES_GCM)
+static ret_code_t backend_mbedtls_gcm_crypt(void * const p_context,
+ nrf_crypto_operation_t operation,
+ uint8_t * p_nonce,
+ uint8_t nonce_size,
+ uint8_t * p_adata,
+ size_t adata_size,
+ uint8_t * p_data_in,
+ size_t data_in_size,
+ uint8_t * p_data_out,
+ uint8_t * p_mac,
+ uint8_t mac_size)
+{
+ int result;
+ ret_code_t ret_val;
+
+ nrf_crypto_backend_mbedtls_aes_aead_context_t * p_ctx =
+ (nrf_crypto_backend_mbedtls_aes_aead_context_t *)p_context;
+
+ /* GCM allows following MAC size: [4 ... 16] */
+ if ((mac_size < NRF_CRYPTO_AES_GCM_MAC_MIN) || (mac_size > NRF_CRYPTO_AES_GCM_MAC_MAX))
+ {
+ return NRF_ERROR_CRYPTO_AEAD_MAC_SIZE;
+ }
+
+ if (operation == NRF_CRYPTO_ENCRYPT)
+ {
+ result = mbedtls_gcm_crypt_and_tag(&p_ctx->gcm.context,
+ MBEDTLS_GCM_ENCRYPT,
+ data_in_size,
+ p_nonce,
+ nonce_size,
+ p_adata,
+ adata_size,
+ p_data_in,
+ p_data_out,
+ (size_t)mac_size,
+ p_mac);
+ ret_val = result_get(result);
+ }
+ else if (operation == NRF_CRYPTO_DECRYPT)
+ {
+ result = mbedtls_gcm_auth_decrypt(&p_ctx->gcm.context,
+ data_in_size,
+ p_nonce,
+ nonce_size,
+ p_adata,
+ adata_size,
+ p_mac,
+ (size_t)mac_size,
+ p_data_in,
+ p_data_out);
+ ret_val = result_get(result);
+ }
+ else
+ {
+ return NRF_ERROR_CRYPTO_INVALID_PARAM;
+ }
+
+ return ret_val;
+}
+#endif
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_MBEDTLS_AES_CCM)
+nrf_crypto_aead_info_t const g_nrf_crypto_aes_ccm_128_info =
+{
+ .key_size = NRF_CRYPTO_KEY_SIZE_128,
+ .mode = NRF_CRYPTO_AEAD_MODE_AES_CCM,
+
+ .init_fn = backend_mbedtls_init,
+ .uninit_fn = backend_mbedtls_uninit,
+ .crypt_fn = backend_mbedtls_ccm_crypt
+};
+
+nrf_crypto_aead_info_t const g_nrf_crypto_aes_ccm_192_info =
+{
+ .key_size = NRF_CRYPTO_KEY_SIZE_192,
+ .mode = NRF_CRYPTO_AEAD_MODE_AES_CCM,
+
+ .init_fn = backend_mbedtls_init,
+ .uninit_fn = backend_mbedtls_uninit,
+ .crypt_fn = backend_mbedtls_ccm_crypt
+};
+
+nrf_crypto_aead_info_t const g_nrf_crypto_aes_ccm_256_info =
+{
+ .key_size = NRF_CRYPTO_KEY_SIZE_256,
+ .mode = NRF_CRYPTO_AEAD_MODE_AES_CCM,
+
+ .init_fn = backend_mbedtls_init,
+ .uninit_fn = backend_mbedtls_uninit,
+ .crypt_fn = backend_mbedtls_ccm_crypt
+};
+#endif
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_MBEDTLS_AES_GCM)
+nrf_crypto_aead_info_t const g_nrf_crypto_aes_gcm_128_info =
+{
+ .key_size = NRF_CRYPTO_KEY_SIZE_128,
+ .mode = NRF_CRYPTO_AEAD_MODE_AES_GCM,
+
+ .init_fn = backend_mbedtls_init,
+ .uninit_fn = backend_mbedtls_uninit,
+ .crypt_fn = backend_mbedtls_gcm_crypt
+};
+
+nrf_crypto_aead_info_t const g_nrf_crypto_aes_gcm_192_info =
+{
+ .key_size = NRF_CRYPTO_KEY_SIZE_192,
+ .mode = NRF_CRYPTO_AEAD_MODE_AES_GCM,
+
+ .init_fn = backend_mbedtls_init,
+ .uninit_fn = backend_mbedtls_uninit,
+ .crypt_fn = backend_mbedtls_gcm_crypt
+};
+
+nrf_crypto_aead_info_t const g_nrf_crypto_aes_gcm_256_info =
+{
+ .key_size = NRF_CRYPTO_KEY_SIZE_256,
+ .mode = NRF_CRYPTO_AEAD_MODE_AES_GCM,
+
+ .init_fn = backend_mbedtls_init,
+ .uninit_fn = backend_mbedtls_uninit,
+ .crypt_fn = backend_mbedtls_gcm_crypt
+};
+#endif
+
+#endif // MODULE_ENABLED(NRF_CRYPTO_MBEDTLS_AES_AEAD)
+#endif // MODULE_ENABLED(NRF_CRYPTO)
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/mbedtls/mbedtls_backend_aes_aead.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/mbedtls/mbedtls_backend_aes_aead.h
new file mode 100644
index 0000000..05f24f5
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/mbedtls/mbedtls_backend_aes_aead.h
@@ -0,0 +1,123 @@
+/**
+ * Copyright (c) 2018 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+
+#ifndef MBEDTLS_BACKEND_AES_AEAD_H__
+#define MBEDTLS_BACKEND_AES_AEAD_H__
+
+/** @file
+ *
+ * @defgroup nrf_crypto_mbedtls_backend_aes_aead nrf_crypto mbed TLS backend AES AEAD
+ * @{
+ * @ingroup nrf_crypto_mbedtls_backend
+ *
+ * @brief AES AEAD functionality provided by the nrf_crypto mbed TLS backend.
+ */
+
+#include "sdk_config.h"
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_MBEDTLS)
+/*lint -save -e????*/
+#include "mbedtls/ccm.h"
+#include "mbedtls/gcm.h"
+#include "mbedtls/platform.h"
+/*lint -restore*/
+#include "nrf_crypto_error.h"
+#include "nrf_crypto_aead_shared.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* AES CCM */
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_MBEDTLS_AES_CCM)
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_AES_CCM)
+#error "Duplicate definition of AES CCM mode. More than one backend enabled");
+#endif
+#define NRF_CRYPTO_AES_CCM_ENABLED 1
+#undef NRF_CRYPTO_AEAD_ENABLED
+#define NRF_CRYPTO_AEAD_ENABLED 1
+#undef NRF_CRYPTO_MBEDTLS_AES_AEAD_ENABLED
+#define NRF_CRYPTO_MBEDTLS_AES_AEAD_ENABLED 1
+
+/* defines for test purposes */
+#define NRF_CRYPTO_AES_CCM_128_ENABLED 1
+#define NRF_CRYPTO_AES_CCM_192_ENABLED 1
+#define NRF_CRYPTO_AES_CCM_256_ENABLED 1
+
+typedef struct
+{
+ nrf_crypto_aead_internal_context_t header; /**< Common header for context. */
+ mbedtls_ccm_context context; /**< AES CCM context internal to mbed TLS. */
+} nrf_crypto_backend_aes_ccm_context_t;
+#endif
+
+/* AES GCM */
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_MBEDTLS_AES_GCM)
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_AES_GCM)
+#error "Duplicate definition of AES GCM mode. More than one backend enabled");
+#endif
+#define NRF_CRYPTO_AES_GCM_ENABLED 1
+#undef NRF_CRYPTO_AEAD_ENABLED
+#define NRF_CRYPTO_AEAD_ENABLED 1
+#undef NRF_CRYPTO_MBEDTLS_AES_AEAD_ENABLED
+#define NRF_CRYPTO_MBEDTLS_AES_AEAD_ENABLED 1
+
+/* defines for test purposes */
+#define NRF_CRYPTO_AES_GCM_128_ENABLED 1
+#define NRF_CRYPTO_AES_GCM_192_ENABLED 1
+#define NRF_CRYPTO_AES_GCM_256_ENABLED 1
+
+typedef struct
+{
+ nrf_crypto_aead_internal_context_t header; /**< Common header for context. */
+ mbedtls_gcm_context context; /**< AES GCM context internal to mbed TLS. */
+} nrf_crypto_backend_aes_gcm_context_t;
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_MBEDTLS)
+
+/** @} */
+
+#endif // MBEDTLS_BACKEND_AES_AEAD_H__
+
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/mbedtls/mbedtls_backend_ecc.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/mbedtls/mbedtls_backend_ecc.c
new file mode 100644
index 0000000..a69ab7c
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/mbedtls/mbedtls_backend_ecc.c
@@ -0,0 +1,531 @@
+/**
+ * Copyright (c) 2018 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+
+#include "sdk_config.h"
+#include "nordic_common.h"
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO) && NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_MBEDTLS)
+
+#include <stdbool.h>
+#include <string.h>
+
+#include "nrf_crypto_ecc.h"
+#include "nrf_crypto_ecdh.h"
+#include "nrf_crypto_mem.h"
+#include "nrf_crypto_rng.h"
+#include "nrf_assert.h"
+#include "mbedtls_backend_ecc.h"
+
+/*lint -save -e????*/
+#if !defined(MBEDTLS_CONFIG_FILE)
+#include "mbedtls/config.h"
+#else
+#include MBEDTLS_CONFIG_FILE
+#endif
+#include "mbedtls/ecp.h"
+#include "mbedtls/bignum.h"
+/*lint -restore*/
+
+
+bool nrf_crypto_backend_mbedtls_ecc_group_load(
+ mbedtls_ecp_group * p_group,
+ struct nrf_crypto_ecc_curve_info_s const * p_info)
+{
+ int result;
+
+ mbedtls_ecp_group_init(p_group);
+ result = mbedtls_ecp_group_load(p_group,
+ (mbedtls_ecp_group_id)(intptr_t)p_info->p_backend_data);
+
+ if (result != 0)
+ {
+ return false;
+ }
+ return true;
+}
+
+
+int nrf_crypto_backend_mbedtls_ecc_mbedtls_rng(void * p_param, unsigned char * p_data, size_t size)
+{
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_RNG)
+
+ ret_code_t result;
+
+ result = nrf_crypto_rng_vector_generate(p_data, size);
+
+ if (result != NRF_SUCCESS)
+ {
+ return MBEDTLS_ERR_ECP_RANDOM_FAILED;
+ }
+ return 0;
+
+#else
+ return MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE;
+#endif
+}
+
+
+ret_code_t nrf_crypto_backend_mbedtls_key_pair_generate(
+ void * p_context,
+ void * p_private_key,
+ void * p_public_key)
+{
+ int result;
+ mbedtls_ecp_group group;
+
+ nrf_crypto_backend_mbedtls_ecc_private_key_t * p_prv =
+ (nrf_crypto_backend_mbedtls_ecc_private_key_t *)p_private_key;
+
+ nrf_crypto_backend_mbedtls_ecc_public_key_t * p_pub =
+ (nrf_crypto_backend_mbedtls_ecc_public_key_t *)p_public_key;
+
+ nrf_crypto_ecc_curve_info_t const * p_info = p_pub->header.p_info;
+
+ if (!nrf_crypto_backend_mbedtls_ecc_group_load(&group, p_info))
+ {
+ return NRF_ERROR_CRYPTO_INTERNAL;
+ }
+
+ mbedtls_ecp_point_init(&p_pub->key);
+ mbedtls_mpi_init(&p_prv->key);
+ result = mbedtls_ecp_gen_keypair(&group,
+ &p_prv->key,
+ &p_pub->key,
+ nrf_crypto_backend_mbedtls_ecc_mbedtls_rng,
+ NULL);
+
+ mbedtls_ecp_group_free(&group);
+
+ if (result != 0)
+ {
+ mbedtls_mpi_free(&p_prv->key);
+ mbedtls_ecp_point_free(&p_pub->key);
+ return NRF_ERROR_CRYPTO_INTERNAL;
+ }
+ return NRF_SUCCESS;
+}
+
+
+ret_code_t nrf_crypto_backend_mbedtls_public_key_calculate(
+ void * p_context,
+ void const * p_private_key,
+ void * p_public_key)
+{
+ int result;
+ mbedtls_ecp_group group;
+
+ nrf_crypto_backend_mbedtls_ecc_private_key_t const * p_prv =
+ (nrf_crypto_backend_mbedtls_ecc_private_key_t const *)p_private_key;
+
+ nrf_crypto_backend_mbedtls_ecc_public_key_t * p_pub =
+ (nrf_crypto_backend_mbedtls_ecc_public_key_t *)p_public_key;
+
+ nrf_crypto_ecc_curve_info_t const * p_info = p_pub->header.p_info;
+
+ if (!nrf_crypto_backend_mbedtls_ecc_group_load(&group, p_info))
+ {
+ return NRF_ERROR_CRYPTO_INTERNAL;
+ }
+
+ mbedtls_ecp_point_init(&p_pub->key);
+ result = mbedtls_ecp_mul(&group,
+ &p_pub->key,
+ &p_prv->key,
+ &group.G,
+ nrf_crypto_backend_mbedtls_ecc_mbedtls_rng,
+ NULL);
+
+ mbedtls_ecp_group_free(&group);
+
+ if (result != 0)
+ {
+ mbedtls_ecp_point_free(&p_pub->key);
+ return NRF_ERROR_CRYPTO_INTERNAL;
+ }
+ return NRF_SUCCESS;
+}
+
+
+ret_code_t nrf_crypto_backend_mbedtls_private_key_from_raw(
+ void * p_private_key,
+ uint8_t const * p_raw_data)
+{
+ int result;
+ mbedtls_ecp_group group;
+
+ nrf_crypto_backend_mbedtls_ecc_private_key_t * p_prv =
+ (nrf_crypto_backend_mbedtls_ecc_private_key_t *)p_private_key;
+
+ nrf_crypto_ecc_curve_info_t const * p_info = p_prv->header.p_info;
+
+ if (!nrf_crypto_backend_mbedtls_ecc_group_load(&group, p_info))
+ {
+ return NRF_ERROR_CRYPTO_INTERNAL;
+ }
+
+ mbedtls_mpi_init(&p_prv->key);
+ result = mbedtls_mpi_read_binary(&p_prv->key, p_raw_data, p_info->raw_private_key_size);
+
+ if (result == 0)
+ {
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_MBEDTLS_ECC_CURVE25519)
+ // Update bits in Curve25519 private key
+ if (p_prv->header.p_info->curve_type == NRF_CRYPTO_ECC_CURVE25519_CURVE_TYPE)
+ {
+ result = mbedtls_mpi_set_bit(&p_prv->key, 0, 0);
+ ASSERT(result == 0);
+ result = mbedtls_mpi_set_bit(&p_prv->key, 1, 0);
+ ASSERT(result == 0);
+ result = mbedtls_mpi_set_bit(&p_prv->key, 2, 0);
+ ASSERT(result == 0);
+ result = mbedtls_mpi_set_bit(&p_prv->key, 254, 1);
+ ASSERT(result == 0);
+ result = mbedtls_mpi_set_bit(&p_prv->key, 255, 0);
+ ASSERT(result == 0);
+ }
+#endif
+ if (mbedtls_ecp_check_privkey(&group, &p_prv->key) != 0)
+ {
+ result = MBEDTLS_ERR_ECP_INVALID_KEY;
+ }
+ }
+
+ mbedtls_ecp_group_free(&group);
+
+ if (result != 0)
+ {
+ mbedtls_mpi_free(&p_prv->key);
+ return NRF_ERROR_CRYPTO_INTERNAL;
+ }
+ return NRF_SUCCESS;
+}
+
+
+ret_code_t nrf_crypto_backend_mbedtls_private_key_to_raw(
+ void const * p_private_key,
+ uint8_t * p_raw_data)
+{
+ int result;
+
+ nrf_crypto_backend_mbedtls_ecc_private_key_t const * p_prv =
+ (nrf_crypto_backend_mbedtls_ecc_private_key_t const *)p_private_key;
+
+ nrf_crypto_ecc_curve_info_t const * p_info = p_prv->header.p_info;
+
+ result = mbedtls_mpi_write_binary(&p_prv->key, p_raw_data, p_info->raw_private_key_size);
+
+ if (result != 0)
+ {
+ return NRF_ERROR_CRYPTO_INTERNAL;
+ }
+ return NRF_SUCCESS;
+}
+
+
+ret_code_t nrf_crypto_backend_mbedtls_public_key_from_raw(
+ void * p_public_key,
+ uint8_t const * p_raw_data)
+{
+ int result;
+ mbedtls_ecp_group group;
+
+ nrf_crypto_backend_mbedtls_ecc_public_key_t * p_pub =
+ (nrf_crypto_backend_mbedtls_ecc_public_key_t *)p_public_key;
+
+ nrf_crypto_ecc_curve_info_t const * p_info = p_pub->header.p_info;
+
+ mbedtls_ecp_point_init(&p_pub->key);
+
+ result = mbedtls_mpi_read_binary(&p_pub->key.X,
+ p_raw_data,
+ p_info->raw_private_key_size);
+ if (result != 0)
+ {
+ goto error_exit;
+ }
+
+ if (p_info->raw_public_key_size > p_info->raw_private_key_size)
+ {
+ result = mbedtls_mpi_read_binary(&p_pub->key.Y,
+ &p_raw_data[p_info->raw_private_key_size],
+ p_info->raw_private_key_size);
+ }
+
+ if (result != 0)
+ {
+ goto error_exit;
+ }
+
+ result = mbedtls_mpi_lset(&p_pub->key.Z, 1);
+
+ if (result == 0)
+ {
+ if (!nrf_crypto_backend_mbedtls_ecc_group_load(&group, p_info))
+ {
+ goto error_exit;
+ }
+ result = mbedtls_ecp_check_pubkey(&group, &p_pub->key);
+ mbedtls_ecp_group_free(&group);
+ }
+
+ if (result != 0)
+ {
+ goto error_exit;
+ }
+ return NRF_SUCCESS;
+
+error_exit:
+ mbedtls_ecp_point_free(&p_pub->key);
+ return NRF_ERROR_CRYPTO_INTERNAL;
+}
+
+
+ret_code_t nrf_crypto_backend_mbedtls_public_key_to_raw(
+ void const * p_public_key,
+ uint8_t * p_raw_data)
+{
+ int result;
+
+ nrf_crypto_backend_mbedtls_ecc_public_key_t const * p_pub =
+ (nrf_crypto_backend_mbedtls_ecc_public_key_t const *)p_public_key;
+
+ nrf_crypto_ecc_curve_info_t const * p_info = p_pub->header.p_info;
+
+ result = mbedtls_mpi_write_binary(&p_pub->key.X,
+ p_raw_data,
+ p_info->raw_private_key_size);
+ if (result != 0)
+ {
+ return NRF_ERROR_CRYPTO_INTERNAL;
+ }
+
+ if (p_info->raw_public_key_size > p_info->raw_private_key_size)
+ {
+ result = mbedtls_mpi_write_binary(&p_pub->key.Y,
+ &p_raw_data[p_info->raw_private_key_size],
+ p_info->raw_private_key_size);
+ }
+
+ if (result != 0)
+ {
+ return NRF_ERROR_CRYPTO_INTERNAL;
+ }
+ return NRF_SUCCESS;
+}
+
+
+ret_code_t nrf_crypto_backend_mbedtls_private_key_free(
+ void * p_private_key)
+{
+ nrf_crypto_backend_mbedtls_ecc_private_key_t * p_prv =
+ (nrf_crypto_backend_mbedtls_ecc_private_key_t *)p_private_key;
+
+ mbedtls_mpi_free(&p_prv->key);
+ return NRF_SUCCESS;
+}
+
+ret_code_t nrf_crypto_backend_mbedtls_public_key_free(
+ void * p_public_key)
+{
+ nrf_crypto_backend_mbedtls_ecc_public_key_t * p_pub =
+ (nrf_crypto_backend_mbedtls_ecc_public_key_t *)p_public_key;
+
+ mbedtls_ecp_point_free(&p_pub->key);
+ return NRF_SUCCESS;
+}
+
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_MBEDTLS_ECC_SECP192R1)
+const nrf_crypto_ecc_curve_info_t g_nrf_crypto_ecc_secp192r1_curve_info =
+{
+ .public_key_size = sizeof(nrf_crypto_backend_mbedtls_ecc_public_key_t),
+ .private_key_size = sizeof(nrf_crypto_backend_mbedtls_ecc_private_key_t),
+ .curve_type = NRF_CRYPTO_ECC_SECP192R1_CURVE_TYPE,
+ .raw_private_key_size = NRF_CRYPTO_ECC_SECP192R1_RAW_PRIVATE_KEY_SIZE,
+ .raw_public_key_size = NRF_CRYPTO_ECC_SECP192R1_RAW_PUBLIC_KEY_SIZE,
+ .p_backend_data = (void *)MBEDTLS_ECP_DP_SECP192R1,
+};
+#endif
+
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_MBEDTLS_ECC_SECP224R1)
+const nrf_crypto_ecc_curve_info_t g_nrf_crypto_ecc_secp224r1_curve_info =
+{
+ .public_key_size = sizeof(nrf_crypto_backend_mbedtls_ecc_public_key_t),
+ .private_key_size = sizeof(nrf_crypto_backend_mbedtls_ecc_private_key_t),
+ .curve_type = NRF_CRYPTO_ECC_SECP224R1_CURVE_TYPE,
+ .raw_private_key_size = NRF_CRYPTO_ECC_SECP224R1_RAW_PRIVATE_KEY_SIZE,
+ .raw_public_key_size = NRF_CRYPTO_ECC_SECP224R1_RAW_PUBLIC_KEY_SIZE,
+ .p_backend_data = (void *)MBEDTLS_ECP_DP_SECP224R1,
+};
+#endif
+
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_MBEDTLS_ECC_SECP256R1)
+const nrf_crypto_ecc_curve_info_t g_nrf_crypto_ecc_secp256r1_curve_info =
+{
+ .public_key_size = sizeof(nrf_crypto_backend_mbedtls_ecc_public_key_t),
+ .private_key_size = sizeof(nrf_crypto_backend_mbedtls_ecc_private_key_t),
+ .curve_type = NRF_CRYPTO_ECC_SECP256R1_CURVE_TYPE,
+ .raw_private_key_size = NRF_CRYPTO_ECC_SECP256R1_RAW_PRIVATE_KEY_SIZE,
+ .raw_public_key_size = NRF_CRYPTO_ECC_SECP256R1_RAW_PUBLIC_KEY_SIZE,
+ .p_backend_data = (void *)MBEDTLS_ECP_DP_SECP256R1,
+};
+#endif
+
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_MBEDTLS_ECC_SECP384R1)
+const nrf_crypto_ecc_curve_info_t g_nrf_crypto_ecc_secp384r1_curve_info =
+{
+ .public_key_size = sizeof(nrf_crypto_backend_mbedtls_ecc_public_key_t),
+ .private_key_size = sizeof(nrf_crypto_backend_mbedtls_ecc_private_key_t),
+ .curve_type = NRF_CRYPTO_ECC_SECP384R1_CURVE_TYPE,
+ .raw_private_key_size = NRF_CRYPTO_ECC_SECP384R1_RAW_PRIVATE_KEY_SIZE,
+ .raw_public_key_size = NRF_CRYPTO_ECC_SECP384R1_RAW_PUBLIC_KEY_SIZE,
+ .p_backend_data = (void *)MBEDTLS_ECP_DP_SECP384R1,
+};
+#endif
+
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_MBEDTLS_ECC_SECP521R1)
+const nrf_crypto_ecc_curve_info_t g_nrf_crypto_ecc_secp521r1_curve_info =
+{
+ .public_key_size = sizeof(nrf_crypto_backend_mbedtls_ecc_public_key_t),
+ .private_key_size = sizeof(nrf_crypto_backend_mbedtls_ecc_private_key_t),
+ .curve_type = NRF_CRYPTO_ECC_SECP521R1_CURVE_TYPE,
+ .raw_private_key_size = NRF_CRYPTO_ECC_SECP521R1_RAW_PRIVATE_KEY_SIZE,
+ .raw_public_key_size = NRF_CRYPTO_ECC_SECP521R1_RAW_PUBLIC_KEY_SIZE,
+ .p_backend_data = (void *)MBEDTLS_ECP_DP_SECP521R1,
+};
+#endif
+
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_MBEDTLS_ECC_SECP192K1)
+const nrf_crypto_ecc_curve_info_t g_nrf_crypto_ecc_secp192k1_curve_info =
+{
+ .public_key_size = sizeof(nrf_crypto_backend_mbedtls_ecc_public_key_t),
+ .private_key_size = sizeof(nrf_crypto_backend_mbedtls_ecc_private_key_t),
+ .curve_type = NRF_CRYPTO_ECC_SECP192K1_CURVE_TYPE,
+ .raw_private_key_size = NRF_CRYPTO_ECC_SECP192K1_RAW_PRIVATE_KEY_SIZE,
+ .raw_public_key_size = NRF_CRYPTO_ECC_SECP192K1_RAW_PUBLIC_KEY_SIZE,
+ .p_backend_data = (void *)MBEDTLS_ECP_DP_SECP192K1,
+};
+#endif
+
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_MBEDTLS_ECC_SECP224K1)
+const nrf_crypto_ecc_curve_info_t g_nrf_crypto_ecc_secp224k1_curve_info =
+{
+ .public_key_size = sizeof(nrf_crypto_backend_mbedtls_ecc_public_key_t),
+ .private_key_size = sizeof(nrf_crypto_backend_mbedtls_ecc_private_key_t),
+ .curve_type = NRF_CRYPTO_ECC_SECP224K1_CURVE_TYPE,
+ .raw_private_key_size = NRF_CRYPTO_ECC_SECP224K1_RAW_PRIVATE_KEY_SIZE,
+ .raw_public_key_size = NRF_CRYPTO_ECC_SECP224K1_RAW_PUBLIC_KEY_SIZE,
+ .p_backend_data = (void *)MBEDTLS_ECP_DP_SECP224K1,
+};
+#endif
+
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_MBEDTLS_ECC_SECP256K1)
+const nrf_crypto_ecc_curve_info_t g_nrf_crypto_ecc_secp256k1_curve_info =
+{
+ .public_key_size = sizeof(nrf_crypto_backend_mbedtls_ecc_public_key_t),
+ .private_key_size = sizeof(nrf_crypto_backend_mbedtls_ecc_private_key_t),
+ .curve_type = NRF_CRYPTO_ECC_SECP256K1_CURVE_TYPE,
+ .raw_private_key_size = NRF_CRYPTO_ECC_SECP256K1_RAW_PRIVATE_KEY_SIZE,
+ .raw_public_key_size = NRF_CRYPTO_ECC_SECP256K1_RAW_PUBLIC_KEY_SIZE,
+ .p_backend_data = (void *)MBEDTLS_ECP_DP_SECP256K1,
+};
+#endif
+
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_MBEDTLS_ECC_BP256R1)
+const nrf_crypto_ecc_curve_info_t g_nrf_crypto_ecc_bp256r1_curve_info =
+{
+ .public_key_size = sizeof(nrf_crypto_backend_mbedtls_ecc_public_key_t),
+ .private_key_size = sizeof(nrf_crypto_backend_mbedtls_ecc_private_key_t),
+ .curve_type = NRF_CRYPTO_ECC_BP256R1_CURVE_TYPE,
+ .raw_private_key_size = NRF_CRYPTO_ECC_BP256R1_RAW_PRIVATE_KEY_SIZE,
+ .raw_public_key_size = NRF_CRYPTO_ECC_BP256R1_RAW_PUBLIC_KEY_SIZE,
+ .p_backend_data = (void *)MBEDTLS_ECP_DP_BP256R1,
+};
+#endif
+
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_MBEDTLS_ECC_BP384R1)
+const nrf_crypto_ecc_curve_info_t g_nrf_crypto_ecc_bp384r1_curve_info =
+{
+ .public_key_size = sizeof(nrf_crypto_backend_mbedtls_ecc_public_key_t),
+ .private_key_size = sizeof(nrf_crypto_backend_mbedtls_ecc_private_key_t),
+ .curve_type = NRF_CRYPTO_ECC_BP384R1_CURVE_TYPE,
+ .raw_private_key_size = NRF_CRYPTO_ECC_BP384R1_RAW_PRIVATE_KEY_SIZE,
+ .raw_public_key_size = NRF_CRYPTO_ECC_BP384R1_RAW_PUBLIC_KEY_SIZE,
+ .p_backend_data = (void *)MBEDTLS_ECP_DP_BP384R1,
+};
+#endif
+
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_MBEDTLS_ECC_BP512R1)
+const nrf_crypto_ecc_curve_info_t g_nrf_crypto_ecc_bp512r1_curve_info =
+{
+ .public_key_size = sizeof(nrf_crypto_backend_mbedtls_ecc_public_key_t),
+ .private_key_size = sizeof(nrf_crypto_backend_mbedtls_ecc_private_key_t),
+ .curve_type = NRF_CRYPTO_ECC_BP512R1_CURVE_TYPE,
+ .raw_private_key_size = NRF_CRYPTO_ECC_BP512R1_RAW_PRIVATE_KEY_SIZE,
+ .raw_public_key_size = NRF_CRYPTO_ECC_BP512R1_RAW_PUBLIC_KEY_SIZE,
+ .p_backend_data = (void *)MBEDTLS_ECP_DP_BP512R1,
+};
+#endif
+
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_MBEDTLS_ECC_CURVE25519)
+const nrf_crypto_ecc_curve_info_t g_nrf_crypto_ecc_curve25519_curve_info =
+{
+ .public_key_size = sizeof(nrf_crypto_backend_mbedtls_ecc_public_key_t),
+ .private_key_size = sizeof(nrf_crypto_backend_mbedtls_ecc_private_key_t),
+ .curve_type = NRF_CRYPTO_ECC_CURVE25519_CURVE_TYPE,
+ .raw_private_key_size = NRF_CRYPTO_ECC_CURVE25519_RAW_PRIVATE_KEY_SIZE,
+ .raw_public_key_size = NRF_CRYPTO_ECC_CURVE25519_RAW_PUBLIC_KEY_SIZE,
+ .p_backend_data = (void *)MBEDTLS_ECP_DP_CURVE25519,
+};
+#endif
+
+
+#endif // NRF_MODULE_ENABLED(NRF_CRYPTO) && NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_MBEDTLS)
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/mbedtls/mbedtls_backend_ecc.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/mbedtls/mbedtls_backend_ecc.h
new file mode 100644
index 0000000..288c39c
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/mbedtls/mbedtls_backend_ecc.h
@@ -0,0 +1,519 @@
+/**
+ * Copyright (c) 2018 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+
+#ifndef MBEDTLS_BACKEND_ECC_H__
+#define MBEDTLS_BACKEND_ECC_H__
+
+#include "sdk_config.h"
+#include "nordic_common.h"
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO) && NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_MBEDTLS)
+
+#include <stdint.h>
+#include <stdbool.h>
+#include "nrf_crypto_ecc_shared.h"
+
+/*lint -save -e????*/
+#if !defined(MBEDTLS_CONFIG_FILE)
+#include "mbedtls/config.h"
+#else
+#include MBEDTLS_CONFIG_FILE
+#endif
+#include "mbedtls/ecp.h"
+/*lint -restore*/
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+/** @internal @brief Common structure holding private key for mbed TLS.
+ */
+typedef struct
+{
+ nrf_crypto_internal_ecc_key_header_t header; /**< @internal @brief Common ECC key header */
+ mbedtls_mpi key; /**< @internal @brief mbed TLS specific key representation */
+} nrf_crypto_backend_mbedtls_ecc_private_key_t;
+
+
+/** @internal @brief Common structure holding public key for mbed TLS.
+ */
+typedef struct
+{
+ nrf_crypto_internal_ecc_key_header_t header; /**< @internal @brief Common ECC key header */
+ mbedtls_ecp_point key; /**< @internal @brief mbed TLS specific key representation */
+} nrf_crypto_backend_mbedtls_ecc_public_key_t;
+
+
+/** @internal See @ref nrf_crypto_backend_ecc_key_pair_generate_fn_t.
+ */
+ret_code_t nrf_crypto_backend_mbedtls_key_pair_generate(
+ void * p_context,
+ void * p_private_key,
+ void * p_public_key);
+
+
+/** @internal See @ref nrf_crypto_backend_ecc_public_key_calculate_fn_t.
+*/
+ret_code_t nrf_crypto_backend_mbedtls_public_key_calculate(
+ void * p_context,
+ void const * p_private_key,
+ void * p_public_key);
+
+
+/** @internal See @ref nrf_crypto_backend_ecc_private_key_from_raw_fn_t.
+*/
+ret_code_t nrf_crypto_backend_mbedtls_private_key_from_raw(
+ void * p_private_key,
+ uint8_t const * p_raw_data);
+
+
+/** @internal See @ref nrf_crypto_backend_ecc_private_key_to_raw_fn_t.
+*/
+ret_code_t nrf_crypto_backend_mbedtls_private_key_to_raw(
+ void const * p_private_key,
+ uint8_t * p_raw_data);
+
+
+/** @internal See @ref nrf_crypto_backend_ecc_public_key_from_raw_fn_t.
+*/
+ret_code_t nrf_crypto_backend_mbedtls_public_key_from_raw(
+ void * p_public_key,
+ uint8_t const * p_raw_data);
+
+
+/** @internal See @ref nrf_crypto_backend_ecc_public_key_to_raw_fn_t.
+*/
+ret_code_t nrf_crypto_backend_mbedtls_public_key_to_raw(
+ void const * p_public_key,
+ uint8_t * p_raw_data);
+
+
+/** @internal See @ref nrf_crypto_backend_ecc_key_free_fn_t.
+*/
+ret_code_t nrf_crypto_backend_mbedtls_private_key_free(
+ void * p_private_key);
+
+
+/** @internal See @ref nrf_crypto_backend_ecc_key_free_fn_t.
+*/
+ret_code_t nrf_crypto_backend_mbedtls_public_key_free(
+ void * p_public_key);
+
+
+/** @internal @brief Loads mbed TLS ECC group of specified curve type.
+ *
+ * @param[out] p_group Pointer to place where to load a group. Data have to be later deallocated.
+ * @param[in] curve_type ECC curve type from enum @ref nrf_crypto_ecc_curve_type_t.
+ * @returns true on success, false if curve is not supported or no found in mbed TLS.
+ */
+bool nrf_crypto_backend_mbedtls_ecc_group_load(
+ mbedtls_ecp_group * p_group,
+ struct nrf_crypto_ecc_curve_info_s const * p_info);
+
+
+/** @internal @brief Function that can be used as a parameter to mbed TLS functions requiring random
+ * number generator.
+ *
+ * It uses RNG from libary front end to generate random numbers.
+ *
+ * @param[in] p_param Opaque pointer passed by mbed TLS. Unused by this implementation.
+ * @param[out] p_data Pointer where to put random number.
+ * @returns 0 on success, mbed TLS error code on error.
+ */
+int nrf_crypto_backend_mbedtls_ecc_mbedtls_rng(void * p_param, unsigned char * p_data, size_t size);
+
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_MBEDTLS_ECC_SECP192R1)
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_ECC_SECP192R1)
+#error "More than one backend enabled for secp192r1 (NIST 192-bit).");
+#endif
+#define NRF_CRYPTO_ECC_SECP192R1_ENABLED 1
+
+// Aliases for one common MBEDTLS implementation
+#define nrf_crypto_backend_secp192r1_key_pair_generate nrf_crypto_backend_mbedtls_key_pair_generate
+#define nrf_crypto_backend_secp192r1_public_key_calculate nrf_crypto_backend_mbedtls_public_key_calculate
+#define nrf_crypto_backend_secp192r1_private_key_from_raw nrf_crypto_backend_mbedtls_private_key_from_raw
+#define nrf_crypto_backend_secp192r1_private_key_to_raw nrf_crypto_backend_mbedtls_private_key_to_raw
+#define nrf_crypto_backend_secp192r1_public_key_from_raw nrf_crypto_backend_mbedtls_public_key_from_raw
+#define nrf_crypto_backend_secp192r1_public_key_to_raw nrf_crypto_backend_mbedtls_public_key_to_raw
+#define nrf_crypto_backend_secp192r1_private_key_free nrf_crypto_backend_mbedtls_private_key_free
+#define nrf_crypto_backend_secp192r1_public_key_free nrf_crypto_backend_mbedtls_public_key_free
+// mbed TLS does not require context, so its size is 0.
+#define NRF_CRYPTO_BACKEND_SECP192R1_KEY_PAIR_GENERATE_CONTEXT_SIZE 0
+#define NRF_CRYPTO_BACKEND_SECP192R1_PUBLIC_KEY_CALCULATE_CONTEXT_SIZE 0
+// All MBEDTLS curve types share the same data structures
+typedef nrf_crypto_backend_mbedtls_ecc_private_key_t nrf_crypto_backend_secp192r1_private_key_t;
+typedef nrf_crypto_backend_mbedtls_ecc_public_key_t nrf_crypto_backend_secp192r1_public_key_t;
+// Dummy typedef for unused context
+typedef uint32_t nrf_crypto_backend_secp192r1_key_pair_generate_context_t;
+typedef uint32_t nrf_crypto_backend_secp192r1_public_key_calculate_context_t;
+
+#endif // NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_MBEDTLS_ECC_SECP192R1)
+
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_MBEDTLS_ECC_SECP224R1)
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_ECC_SECP224R1)
+#error "More than one backend enabled for secp224r1 (NIST 224-bit).");
+#endif
+#define NRF_CRYPTO_ECC_SECP224R1_ENABLED 1
+
+// Aliases for one common MBEDTLS implementation
+#define nrf_crypto_backend_secp224r1_key_pair_generate nrf_crypto_backend_mbedtls_key_pair_generate
+#define nrf_crypto_backend_secp224r1_public_key_calculate nrf_crypto_backend_mbedtls_public_key_calculate
+#define nrf_crypto_backend_secp224r1_private_key_from_raw nrf_crypto_backend_mbedtls_private_key_from_raw
+#define nrf_crypto_backend_secp224r1_private_key_to_raw nrf_crypto_backend_mbedtls_private_key_to_raw
+#define nrf_crypto_backend_secp224r1_public_key_from_raw nrf_crypto_backend_mbedtls_public_key_from_raw
+#define nrf_crypto_backend_secp224r1_public_key_to_raw nrf_crypto_backend_mbedtls_public_key_to_raw
+#define nrf_crypto_backend_secp224r1_private_key_free nrf_crypto_backend_mbedtls_private_key_free
+#define nrf_crypto_backend_secp224r1_public_key_free nrf_crypto_backend_mbedtls_public_key_free
+// mbed TLS does not require context, so its size is 0.
+#define NRF_CRYPTO_BACKEND_SECP224R1_KEY_PAIR_GENERATE_CONTEXT_SIZE 0
+#define NRF_CRYPTO_BACKEND_SECP224R1_PUBLIC_KEY_CALCULATE_CONTEXT_SIZE 0
+// All MBEDTLS curve types share the same data structures
+typedef nrf_crypto_backend_mbedtls_ecc_private_key_t nrf_crypto_backend_secp224r1_private_key_t;
+typedef nrf_crypto_backend_mbedtls_ecc_public_key_t nrf_crypto_backend_secp224r1_public_key_t;
+// Dummy typedef for unused context
+typedef uint32_t nrf_crypto_backend_secp224r1_key_pair_generate_context_t;
+typedef uint32_t nrf_crypto_backend_secp224r1_public_key_calculate_context_t;
+
+#endif // NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_MBEDTLS_ECC_SECP224R1)
+
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_MBEDTLS_ECC_SECP256R1)
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_ECC_SECP256R1)
+#error "More than one backend enabled for secp256r1 (NIST 256-bit).");
+#endif
+#define NRF_CRYPTO_ECC_SECP256R1_ENABLED 1
+
+// Aliases for one common MBEDTLS implementation
+#define nrf_crypto_backend_secp256r1_key_pair_generate nrf_crypto_backend_mbedtls_key_pair_generate
+#define nrf_crypto_backend_secp256r1_public_key_calculate nrf_crypto_backend_mbedtls_public_key_calculate
+#define nrf_crypto_backend_secp256r1_private_key_from_raw nrf_crypto_backend_mbedtls_private_key_from_raw
+#define nrf_crypto_backend_secp256r1_private_key_to_raw nrf_crypto_backend_mbedtls_private_key_to_raw
+#define nrf_crypto_backend_secp256r1_public_key_from_raw nrf_crypto_backend_mbedtls_public_key_from_raw
+#define nrf_crypto_backend_secp256r1_public_key_to_raw nrf_crypto_backend_mbedtls_public_key_to_raw
+#define nrf_crypto_backend_secp256r1_private_key_free nrf_crypto_backend_mbedtls_private_key_free
+#define nrf_crypto_backend_secp256r1_public_key_free nrf_crypto_backend_mbedtls_public_key_free
+// mbed TLS does not require context, so its size is 0.
+#define NRF_CRYPTO_BACKEND_SECP256R1_KEY_PAIR_GENERATE_CONTEXT_SIZE 0
+#define NRF_CRYPTO_BACKEND_SECP256R1_PUBLIC_KEY_CALCULATE_CONTEXT_SIZE 0
+// All MBEDTLS curve types share the same data structures
+typedef nrf_crypto_backend_mbedtls_ecc_private_key_t nrf_crypto_backend_secp256r1_private_key_t;
+typedef nrf_crypto_backend_mbedtls_ecc_public_key_t nrf_crypto_backend_secp256r1_public_key_t;
+// Dummy typedef for unused context
+typedef uint32_t nrf_crypto_backend_secp256r1_key_pair_generate_context_t;
+typedef uint32_t nrf_crypto_backend_secp256r1_public_key_calculate_context_t;
+
+#endif // NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_MBEDTLS_ECC_SECP256R1)
+
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_MBEDTLS_ECC_SECP384R1)
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_ECC_SECP384R1)
+#error "More than one backend enabled for secp384r1 (NIST 384-bit).");
+#endif
+#define NRF_CRYPTO_ECC_SECP384R1_ENABLED 1
+
+// Aliases for one common MBEDTLS implementation
+#define nrf_crypto_backend_secp384r1_key_pair_generate nrf_crypto_backend_mbedtls_key_pair_generate
+#define nrf_crypto_backend_secp384r1_public_key_calculate nrf_crypto_backend_mbedtls_public_key_calculate
+#define nrf_crypto_backend_secp384r1_private_key_from_raw nrf_crypto_backend_mbedtls_private_key_from_raw
+#define nrf_crypto_backend_secp384r1_private_key_to_raw nrf_crypto_backend_mbedtls_private_key_to_raw
+#define nrf_crypto_backend_secp384r1_public_key_from_raw nrf_crypto_backend_mbedtls_public_key_from_raw
+#define nrf_crypto_backend_secp384r1_public_key_to_raw nrf_crypto_backend_mbedtls_public_key_to_raw
+#define nrf_crypto_backend_secp384r1_private_key_free nrf_crypto_backend_mbedtls_private_key_free
+#define nrf_crypto_backend_secp384r1_public_key_free nrf_crypto_backend_mbedtls_public_key_free
+// mbed TLS does not require context, so its size is 0.
+#define NRF_CRYPTO_BACKEND_SECP384R1_KEY_PAIR_GENERATE_CONTEXT_SIZE 0
+#define NRF_CRYPTO_BACKEND_SECP384R1_PUBLIC_KEY_CALCULATE_CONTEXT_SIZE 0
+// All MBEDTLS curve types share the same data structures
+typedef nrf_crypto_backend_mbedtls_ecc_private_key_t nrf_crypto_backend_secp384r1_private_key_t;
+typedef nrf_crypto_backend_mbedtls_ecc_public_key_t nrf_crypto_backend_secp384r1_public_key_t;
+// Dummy typedef for unused context
+typedef uint32_t nrf_crypto_backend_secp384r1_key_pair_generate_context_t;
+typedef uint32_t nrf_crypto_backend_secp384r1_public_key_calculate_context_t;
+
+#endif // NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_MBEDTLS_ECC_SECP384R1)
+
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_MBEDTLS_ECC_SECP521R1)
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_ECC_SECP521R1)
+#error "More than one backend enabled for secp521r1 (NIST 521-bit).");
+#endif
+#define NRF_CRYPTO_ECC_SECP521R1_ENABLED 1
+
+// Aliases for one common MBEDTLS implementation
+#define nrf_crypto_backend_secp521r1_key_pair_generate nrf_crypto_backend_mbedtls_key_pair_generate
+#define nrf_crypto_backend_secp521r1_public_key_calculate nrf_crypto_backend_mbedtls_public_key_calculate
+#define nrf_crypto_backend_secp521r1_private_key_from_raw nrf_crypto_backend_mbedtls_private_key_from_raw
+#define nrf_crypto_backend_secp521r1_private_key_to_raw nrf_crypto_backend_mbedtls_private_key_to_raw
+#define nrf_crypto_backend_secp521r1_public_key_from_raw nrf_crypto_backend_mbedtls_public_key_from_raw
+#define nrf_crypto_backend_secp521r1_public_key_to_raw nrf_crypto_backend_mbedtls_public_key_to_raw
+#define nrf_crypto_backend_secp521r1_private_key_free nrf_crypto_backend_mbedtls_private_key_free
+#define nrf_crypto_backend_secp521r1_public_key_free nrf_crypto_backend_mbedtls_public_key_free
+// mbed TLS does not require context, so its size is 0.
+#define NRF_CRYPTO_BACKEND_SECP521R1_KEY_PAIR_GENERATE_CONTEXT_SIZE 0
+#define NRF_CRYPTO_BACKEND_SECP521R1_PUBLIC_KEY_CALCULATE_CONTEXT_SIZE 0
+// All MBEDTLS curve types share the same data structures
+typedef nrf_crypto_backend_mbedtls_ecc_private_key_t nrf_crypto_backend_secp521r1_private_key_t;
+typedef nrf_crypto_backend_mbedtls_ecc_public_key_t nrf_crypto_backend_secp521r1_public_key_t;
+// Dummy typedef for unused context
+typedef uint32_t nrf_crypto_backend_secp521r1_key_pair_generate_context_t;
+typedef uint32_t nrf_crypto_backend_secp521r1_public_key_calculate_context_t;
+
+#endif // NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_MBEDTLS_ECC_SECP521R1)
+
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_MBEDTLS_ECC_SECP192K1)
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_ECC_SECP192K1)
+#error "More than one backend enabled for secp192k1 (Koblitz 192-bit).");
+#endif
+#define NRF_CRYPTO_ECC_SECP192K1_ENABLED 1
+
+// Aliases for one common MBEDTLS implementation
+#define nrf_crypto_backend_secp192k1_key_pair_generate nrf_crypto_backend_mbedtls_key_pair_generate
+#define nrf_crypto_backend_secp192k1_public_key_calculate nrf_crypto_backend_mbedtls_public_key_calculate
+#define nrf_crypto_backend_secp192k1_private_key_from_raw nrf_crypto_backend_mbedtls_private_key_from_raw
+#define nrf_crypto_backend_secp192k1_private_key_to_raw nrf_crypto_backend_mbedtls_private_key_to_raw
+#define nrf_crypto_backend_secp192k1_public_key_from_raw nrf_crypto_backend_mbedtls_public_key_from_raw
+#define nrf_crypto_backend_secp192k1_public_key_to_raw nrf_crypto_backend_mbedtls_public_key_to_raw
+#define nrf_crypto_backend_secp192k1_private_key_free nrf_crypto_backend_mbedtls_private_key_free
+#define nrf_crypto_backend_secp192k1_public_key_free nrf_crypto_backend_mbedtls_public_key_free
+// mbed TLS does not require context, so its size is 0.
+#define NRF_CRYPTO_BACKEND_SECP192K1_KEY_PAIR_GENERATE_CONTEXT_SIZE 0
+#define NRF_CRYPTO_BACKEND_SECP192K1_PUBLIC_KEY_CALCULATE_CONTEXT_SIZE 0
+// All MBEDTLS curve types share the same data structures
+typedef nrf_crypto_backend_mbedtls_ecc_private_key_t nrf_crypto_backend_secp192k1_private_key_t;
+typedef nrf_crypto_backend_mbedtls_ecc_public_key_t nrf_crypto_backend_secp192k1_public_key_t;
+// Dummy typedef for unused context
+typedef uint32_t nrf_crypto_backend_secp192k1_key_pair_generate_context_t;
+typedef uint32_t nrf_crypto_backend_secp192k1_public_key_calculate_context_t;
+
+#endif // NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_MBEDTLS_ECC_SECP192K1)
+
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_MBEDTLS_ECC_SECP224K1)
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_ECC_SECP224K1)
+#error "More than one backend enabled for secp224k1 (Koblitz 224-bit).");
+#endif
+#define NRF_CRYPTO_ECC_SECP224K1_ENABLED 1
+
+// Aliases for one common MBEDTLS implementation
+#define nrf_crypto_backend_secp224k1_key_pair_generate nrf_crypto_backend_mbedtls_key_pair_generate
+#define nrf_crypto_backend_secp224k1_public_key_calculate nrf_crypto_backend_mbedtls_public_key_calculate
+#define nrf_crypto_backend_secp224k1_private_key_from_raw nrf_crypto_backend_mbedtls_private_key_from_raw
+#define nrf_crypto_backend_secp224k1_private_key_to_raw nrf_crypto_backend_mbedtls_private_key_to_raw
+#define nrf_crypto_backend_secp224k1_public_key_from_raw nrf_crypto_backend_mbedtls_public_key_from_raw
+#define nrf_crypto_backend_secp224k1_public_key_to_raw nrf_crypto_backend_mbedtls_public_key_to_raw
+#define nrf_crypto_backend_secp224k1_private_key_free nrf_crypto_backend_mbedtls_private_key_free
+#define nrf_crypto_backend_secp224k1_public_key_free nrf_crypto_backend_mbedtls_public_key_free
+// mbed TLS does not require context, so its size is 0.
+#define NRF_CRYPTO_BACKEND_SECP224K1_KEY_PAIR_GENERATE_CONTEXT_SIZE 0
+#define NRF_CRYPTO_BACKEND_SECP224K1_PUBLIC_KEY_CALCULATE_CONTEXT_SIZE 0
+// All MBEDTLS curve types share the same data structures
+typedef nrf_crypto_backend_mbedtls_ecc_private_key_t nrf_crypto_backend_secp224k1_private_key_t;
+typedef nrf_crypto_backend_mbedtls_ecc_public_key_t nrf_crypto_backend_secp224k1_public_key_t;
+// Dummy typedef for unused context
+typedef uint32_t nrf_crypto_backend_secp224k1_key_pair_generate_context_t;
+typedef uint32_t nrf_crypto_backend_secp224k1_public_key_calculate_context_t;
+
+#endif // NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_MBEDTLS_ECC_SECP224K1)
+
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_MBEDTLS_ECC_SECP256K1)
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_ECC_SECP256K1)
+#error "More than one backend enabled for secp256k1 (Koblitz 256-bit).");
+#endif
+#define NRF_CRYPTO_ECC_SECP256K1_ENABLED 1
+
+// Aliases for one common MBEDTLS implementation
+#define nrf_crypto_backend_secp256k1_key_pair_generate nrf_crypto_backend_mbedtls_key_pair_generate
+#define nrf_crypto_backend_secp256k1_public_key_calculate nrf_crypto_backend_mbedtls_public_key_calculate
+#define nrf_crypto_backend_secp256k1_private_key_from_raw nrf_crypto_backend_mbedtls_private_key_from_raw
+#define nrf_crypto_backend_secp256k1_private_key_to_raw nrf_crypto_backend_mbedtls_private_key_to_raw
+#define nrf_crypto_backend_secp256k1_public_key_from_raw nrf_crypto_backend_mbedtls_public_key_from_raw
+#define nrf_crypto_backend_secp256k1_public_key_to_raw nrf_crypto_backend_mbedtls_public_key_to_raw
+#define nrf_crypto_backend_secp256k1_private_key_free nrf_crypto_backend_mbedtls_private_key_free
+#define nrf_crypto_backend_secp256k1_public_key_free nrf_crypto_backend_mbedtls_public_key_free
+// mbed TLS does not require context, so its size is 0.
+#define NRF_CRYPTO_BACKEND_SECP256K1_KEY_PAIR_GENERATE_CONTEXT_SIZE 0
+#define NRF_CRYPTO_BACKEND_SECP256K1_PUBLIC_KEY_CALCULATE_CONTEXT_SIZE 0
+// All MBEDTLS curve types share the same data structures
+typedef nrf_crypto_backend_mbedtls_ecc_private_key_t nrf_crypto_backend_secp256k1_private_key_t;
+typedef nrf_crypto_backend_mbedtls_ecc_public_key_t nrf_crypto_backend_secp256k1_public_key_t;
+// Dummy typedef for unused context
+typedef uint32_t nrf_crypto_backend_secp256k1_key_pair_generate_context_t;
+typedef uint32_t nrf_crypto_backend_secp256k1_public_key_calculate_context_t;
+
+#endif // NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_MBEDTLS_ECC_SECP256K1)
+
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_MBEDTLS_ECC_BP256R1)
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_ECC_BP256R1)
+#error "More than one backend enabled for bp256r1 (Brainpool 256-bit).");
+#endif
+#define NRF_CRYPTO_ECC_BP256R1_ENABLED 1
+
+// Aliases for one common MBEDTLS implementation
+#define nrf_crypto_backend_bp256r1_key_pair_generate nrf_crypto_backend_mbedtls_key_pair_generate
+#define nrf_crypto_backend_bp256r1_public_key_calculate nrf_crypto_backend_mbedtls_public_key_calculate
+#define nrf_crypto_backend_bp256r1_private_key_from_raw nrf_crypto_backend_mbedtls_private_key_from_raw
+#define nrf_crypto_backend_bp256r1_private_key_to_raw nrf_crypto_backend_mbedtls_private_key_to_raw
+#define nrf_crypto_backend_bp256r1_public_key_from_raw nrf_crypto_backend_mbedtls_public_key_from_raw
+#define nrf_crypto_backend_bp256r1_public_key_to_raw nrf_crypto_backend_mbedtls_public_key_to_raw
+#define nrf_crypto_backend_bp256r1_private_key_free nrf_crypto_backend_mbedtls_private_key_free
+#define nrf_crypto_backend_bp256r1_public_key_free nrf_crypto_backend_mbedtls_public_key_free
+// mbed TLS does not require context, so its size is 0.
+#define NRF_CRYPTO_BACKEND_BP256R1_KEY_PAIR_GENERATE_CONTEXT_SIZE 0
+#define NRF_CRYPTO_BACKEND_BP256R1_PUBLIC_KEY_CALCULATE_CONTEXT_SIZE 0
+// All MBEDTLS curve types share the same data structures
+typedef nrf_crypto_backend_mbedtls_ecc_private_key_t nrf_crypto_backend_bp256r1_private_key_t;
+typedef nrf_crypto_backend_mbedtls_ecc_public_key_t nrf_crypto_backend_bp256r1_public_key_t;
+// Dummy typedef for unused context
+typedef uint32_t nrf_crypto_backend_bp256r1_key_pair_generate_context_t;
+typedef uint32_t nrf_crypto_backend_bp256r1_public_key_calculate_context_t;
+
+#endif // NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_MBEDTLS_ECC_BP256R1)
+
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_MBEDTLS_ECC_BP384R1)
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_ECC_BP384R1)
+#error "More than one backend enabled for bp384r1 (Brainpool 384-bit).");
+#endif
+#define NRF_CRYPTO_ECC_BP384R1_ENABLED 1
+
+// Aliases for one common MBEDTLS implementation
+#define nrf_crypto_backend_bp384r1_key_pair_generate nrf_crypto_backend_mbedtls_key_pair_generate
+#define nrf_crypto_backend_bp384r1_public_key_calculate nrf_crypto_backend_mbedtls_public_key_calculate
+#define nrf_crypto_backend_bp384r1_private_key_from_raw nrf_crypto_backend_mbedtls_private_key_from_raw
+#define nrf_crypto_backend_bp384r1_private_key_to_raw nrf_crypto_backend_mbedtls_private_key_to_raw
+#define nrf_crypto_backend_bp384r1_public_key_from_raw nrf_crypto_backend_mbedtls_public_key_from_raw
+#define nrf_crypto_backend_bp384r1_public_key_to_raw nrf_crypto_backend_mbedtls_public_key_to_raw
+#define nrf_crypto_backend_bp384r1_private_key_free nrf_crypto_backend_mbedtls_private_key_free
+#define nrf_crypto_backend_bp384r1_public_key_free nrf_crypto_backend_mbedtls_public_key_free
+// mbed TLS does not require context, so its size is 0.
+#define NRF_CRYPTO_BACKEND_BP384R1_KEY_PAIR_GENERATE_CONTEXT_SIZE 0
+#define NRF_CRYPTO_BACKEND_BP384R1_PUBLIC_KEY_CALCULATE_CONTEXT_SIZE 0
+// All MBEDTLS curve types share the same data structures
+typedef nrf_crypto_backend_mbedtls_ecc_private_key_t nrf_crypto_backend_bp384r1_private_key_t;
+typedef nrf_crypto_backend_mbedtls_ecc_public_key_t nrf_crypto_backend_bp384r1_public_key_t;
+// Dummy typedef for unused context
+typedef uint32_t nrf_crypto_backend_bp384r1_key_pair_generate_context_t;
+typedef uint32_t nrf_crypto_backend_bp384r1_public_key_calculate_context_t;
+
+#endif // NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_MBEDTLS_ECC_BP384R1)
+
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_MBEDTLS_ECC_BP512R1)
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_ECC_BP512R1)
+#error "More than one backend enabled for bp512r1 (Brainpool 512-bit).");
+#endif
+#define NRF_CRYPTO_ECC_BP512R1_ENABLED 1
+
+// Aliases for one common MBEDTLS implementation
+#define nrf_crypto_backend_bp512r1_key_pair_generate nrf_crypto_backend_mbedtls_key_pair_generate
+#define nrf_crypto_backend_bp512r1_public_key_calculate nrf_crypto_backend_mbedtls_public_key_calculate
+#define nrf_crypto_backend_bp512r1_private_key_from_raw nrf_crypto_backend_mbedtls_private_key_from_raw
+#define nrf_crypto_backend_bp512r1_private_key_to_raw nrf_crypto_backend_mbedtls_private_key_to_raw
+#define nrf_crypto_backend_bp512r1_public_key_from_raw nrf_crypto_backend_mbedtls_public_key_from_raw
+#define nrf_crypto_backend_bp512r1_public_key_to_raw nrf_crypto_backend_mbedtls_public_key_to_raw
+#define nrf_crypto_backend_bp512r1_private_key_free nrf_crypto_backend_mbedtls_private_key_free
+#define nrf_crypto_backend_bp512r1_public_key_free nrf_crypto_backend_mbedtls_public_key_free
+// mbed TLS does not require context, so its size is 0.
+#define NRF_CRYPTO_BACKEND_BP512R1_KEY_PAIR_GENERATE_CONTEXT_SIZE 0
+#define NRF_CRYPTO_BACKEND_BP512R1_PUBLIC_KEY_CALCULATE_CONTEXT_SIZE 0
+// All MBEDTLS curve types share the same data structures
+typedef nrf_crypto_backend_mbedtls_ecc_private_key_t nrf_crypto_backend_bp512r1_private_key_t;
+typedef nrf_crypto_backend_mbedtls_ecc_public_key_t nrf_crypto_backend_bp512r1_public_key_t;
+// Dummy typedef for unused context
+typedef uint32_t nrf_crypto_backend_bp512r1_key_pair_generate_context_t;
+typedef uint32_t nrf_crypto_backend_bp512r1_public_key_calculate_context_t;
+
+#endif // NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_MBEDTLS_ECC_BP512R1)
+
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_MBEDTLS_ECC_CURVE25519)
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_ECC_CURVE25519)
+#error "More than one backend enabled for Curve25519.");
+#endif
+#define NRF_CRYPTO_ECC_CURVE25519_ENABLED 1
+
+// Aliases for one common MBEDTLS implementation
+#define nrf_crypto_backend_curve25519_key_pair_generate nrf_crypto_backend_mbedtls_key_pair_generate
+#define nrf_crypto_backend_curve25519_public_key_calculate nrf_crypto_backend_mbedtls_public_key_calculate
+#define nrf_crypto_backend_curve25519_private_key_from_raw nrf_crypto_backend_mbedtls_private_key_from_raw
+#define nrf_crypto_backend_curve25519_private_key_to_raw nrf_crypto_backend_mbedtls_private_key_to_raw
+#define nrf_crypto_backend_curve25519_public_key_from_raw nrf_crypto_backend_mbedtls_public_key_from_raw
+#define nrf_crypto_backend_curve25519_public_key_to_raw nrf_crypto_backend_mbedtls_public_key_to_raw
+#define nrf_crypto_backend_curve25519_private_key_free nrf_crypto_backend_mbedtls_private_key_free
+#define nrf_crypto_backend_curve25519_public_key_free nrf_crypto_backend_mbedtls_public_key_free
+// mbed TLS does not require context, so its size is 0.
+#define NRF_CRYPTO_BACKEND_CURVE25519_KEY_PAIR_GENERATE_CONTEXT_SIZE 0
+#define NRF_CRYPTO_BACKEND_CURVE25519_PUBLIC_KEY_CALCULATE_CONTEXT_SIZE 0
+// All MBEDTLS curve types share the same data structures
+typedef nrf_crypto_backend_mbedtls_ecc_private_key_t nrf_crypto_backend_curve25519_private_key_t;
+typedef nrf_crypto_backend_mbedtls_ecc_public_key_t nrf_crypto_backend_curve25519_public_key_t;
+// Dummy typedef for unused context
+typedef uint32_t nrf_crypto_backend_curve25519_key_pair_generate_context_t;
+typedef uint32_t nrf_crypto_backend_curve25519_public_key_calculate_context_t;
+
+#endif // NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_MBEDTLS_ECC_CURVE25519)
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // NRF_MODULE_ENABLED(NRF_CRYPTO) && NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_MBEDTLS)
+
+#endif // MBEDTLS_BACKEND_ECC_H__
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/mbedtls/mbedtls_backend_ecdh.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/mbedtls/mbedtls_backend_ecdh.c
new file mode 100644
index 0000000..02de8d7
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/mbedtls/mbedtls_backend_ecdh.c
@@ -0,0 +1,113 @@
+/**
+ * Copyright (c) 2018 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+
+#include "sdk_config.h"
+#include "nordic_common.h"
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO) && NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_MBEDTLS)
+
+#include <string.h>
+
+#include "nrf_crypto_ecc_shared.h"
+#include "nrf_crypto_ecdh_shared.h"
+#include "nrf_crypto_ecdh.h"
+
+/*lint -save -e????*/
+#if !defined(MBEDTLS_CONFIG_FILE)
+#include "mbedtls/config.h"
+#else
+#include MBEDTLS_CONFIG_FILE
+#endif
+#include "mbedtls/ecp.h"
+#include "mbedtls/ecdh.h"
+/*lint -restore*/
+
+
+ret_code_t nrf_crypto_backend_mbedtls_ecdh_compute(
+ void * p_context,
+ void const * p_private_key,
+ void const * p_public_key,
+ uint8_t * p_shared_secret)
+{
+ int result;
+ mbedtls_mpi shared_secret_mpi;
+ mbedtls_ecp_group group;
+
+ nrf_crypto_backend_mbedtls_ecc_private_key_t const * p_prv =
+ (nrf_crypto_backend_mbedtls_ecc_private_key_t const *)p_private_key;
+
+ nrf_crypto_backend_mbedtls_ecc_public_key_t const * p_pub =
+ (nrf_crypto_backend_mbedtls_ecc_public_key_t const *)p_public_key;
+
+ nrf_crypto_ecc_curve_info_t const * p_info = p_prv->header.p_info;
+
+ if (!nrf_crypto_backend_mbedtls_ecc_group_load(&group, p_info))
+ {
+ return NRF_ERROR_CRYPTO_INTERNAL;
+ }
+
+ mbedtls_mpi_init(&shared_secret_mpi);
+ result = mbedtls_ecdh_compute_shared(&group,
+ &shared_secret_mpi,
+ &p_pub->key,
+ &p_prv->key,
+ nrf_crypto_backend_mbedtls_ecc_mbedtls_rng,
+ NULL);
+
+ if (result == 0)
+ {
+ result = mbedtls_mpi_write_binary(&shared_secret_mpi,
+ p_shared_secret,
+ p_info->raw_private_key_size);
+ }
+
+ mbedtls_mpi_free(&shared_secret_mpi);
+ mbedtls_ecp_group_free(&group);
+
+ if (result != 0)
+ {
+ return NRF_ERROR_CRYPTO_INTERNAL;
+ }
+ return NRF_SUCCESS;
+}
+
+
+#endif // NRF_MODULE_ENABLED(NRF_CRYPTO) && NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_MBEDTLS)
+
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/mbedtls/mbedtls_backend_ecdh.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/mbedtls/mbedtls_backend_ecdh.h
new file mode 100644
index 0000000..fac0e83
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/mbedtls/mbedtls_backend_ecdh.h
@@ -0,0 +1,169 @@
+/**
+ * Copyright (c) 2018 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+
+#ifndef MBEDTLS_BACKEND_ECDH_H__
+#define MBEDTLS_BACKEND_ECDH_H__
+
+#include "sdk_config.h"
+#include "nordic_common.h"
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO) && NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_MBEDTLS)
+
+#include "nrf_crypto_ecc.h"
+#include "nrf_crypto_ecdh_shared.h"
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+/** @internal See @ref nrf_crypto_backend_ecdh_compute_fn_t.
+ */
+ret_code_t nrf_crypto_backend_mbedtls_ecdh_compute(
+ void * p_context,
+ void const * p_private_key,
+ void const * p_public_key,
+ uint8_t * p_shared_secret);
+
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_MBEDTLS_ECC_SECP192R1)
+// Aliases for one common MBEDTLS implementation
+#define nrf_crypto_backend_secp192r1_ecdh_compute nrf_crypto_backend_mbedtls_ecdh_compute
+typedef uint32_t nrf_crypto_backend_secp192r1_ecdh_context_t;
+#define NRF_CRYPTO_BACKEND_SECP192R1_ECDH_CONTEXT_SIZE 0
+#endif // NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_MBEDTLS_ECC_SECP192R1)
+
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_MBEDTLS_ECC_SECP224R1)
+// Aliases for one common MBEDTLS implementation
+#define nrf_crypto_backend_secp224r1_ecdh_compute nrf_crypto_backend_mbedtls_ecdh_compute
+typedef uint32_t nrf_crypto_backend_secp224r1_ecdh_context_t;
+#define NRF_CRYPTO_BACKEND_SECP224R1_ECDH_CONTEXT_SIZE 0
+#endif // NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_MBEDTLS_ECC_SECP224R1)
+
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_MBEDTLS_ECC_SECP256R1)
+// Aliases for one common MBEDTLS implementation
+#define nrf_crypto_backend_secp256r1_ecdh_compute nrf_crypto_backend_mbedtls_ecdh_compute
+typedef uint32_t nrf_crypto_backend_secp256r1_ecdh_context_t;
+#define NRF_CRYPTO_BACKEND_SECP256R1_ECDH_CONTEXT_SIZE 0
+#endif // NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_MBEDTLS_ECC_SECP256R1)
+
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_MBEDTLS_ECC_SECP384R1)
+// Aliases for one common MBEDTLS implementation
+#define nrf_crypto_backend_secp384r1_ecdh_compute nrf_crypto_backend_mbedtls_ecdh_compute
+typedef uint32_t nrf_crypto_backend_secp384r1_ecdh_context_t;
+#define NRF_CRYPTO_BACKEND_SECP384R1_ECDH_CONTEXT_SIZE 0
+#endif // NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_MBEDTLS_ECC_SECP384R1)
+
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_MBEDTLS_ECC_SECP521R1)
+// Aliases for one common MBEDTLS implementation
+#define nrf_crypto_backend_secp521r1_ecdh_compute nrf_crypto_backend_mbedtls_ecdh_compute
+typedef uint32_t nrf_crypto_backend_secp521r1_ecdh_context_t;
+#define NRF_CRYPTO_BACKEND_SECP521R1_ECDH_CONTEXT_SIZE 0
+#endif // NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_MBEDTLS_ECC_SECP521R1)
+
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_MBEDTLS_ECC_SECP192K1)
+// Aliases for one common MBEDTLS implementation
+#define nrf_crypto_backend_secp192k1_ecdh_compute nrf_crypto_backend_mbedtls_ecdh_compute
+typedef uint32_t nrf_crypto_backend_secp192k1_ecdh_context_t;
+#define NRF_CRYPTO_BACKEND_SECP192K1_ECDH_CONTEXT_SIZE 0
+#endif // NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_MBEDTLS_ECC_SECP192K1)
+
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_MBEDTLS_ECC_SECP224K1)
+// Aliases for one common MBEDTLS implementation
+#define nrf_crypto_backend_secp224k1_ecdh_compute nrf_crypto_backend_mbedtls_ecdh_compute
+typedef uint32_t nrf_crypto_backend_secp224k1_ecdh_context_t;
+#define NRF_CRYPTO_BACKEND_SECP224K1_ECDH_CONTEXT_SIZE 0
+#endif // NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_MBEDTLS_ECC_SECP224K1)
+
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_MBEDTLS_ECC_SECP256K1)
+// Aliases for one common MBEDTLS implementation
+#define nrf_crypto_backend_secp256k1_ecdh_compute nrf_crypto_backend_mbedtls_ecdh_compute
+typedef uint32_t nrf_crypto_backend_secp256k1_ecdh_context_t;
+#define NRF_CRYPTO_BACKEND_SECP256K1_ECDH_CONTEXT_SIZE 0
+#endif // NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_MBEDTLS_ECC_SECP256K1)
+
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_MBEDTLS_ECC_BP256R1)
+// Aliases for one common MBEDTLS implementation
+#define nrf_crypto_backend_bp256r1_ecdh_compute nrf_crypto_backend_mbedtls_ecdh_compute
+typedef uint32_t nrf_crypto_backend_bp256r1_ecdh_context_t;
+#define NRF_CRYPTO_BACKEND_BP256R1_ECDH_CONTEXT_SIZE 0
+#endif // NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_MBEDTLS_ECC_BP256R1)
+
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_MBEDTLS_ECC_BP384R1)
+// Aliases for one common MBEDTLS implementation
+#define nrf_crypto_backend_bp384r1_ecdh_compute nrf_crypto_backend_mbedtls_ecdh_compute
+typedef uint32_t nrf_crypto_backend_bp384r1_ecdh_context_t;
+#define NRF_CRYPTO_BACKEND_BP384R1_ECDH_CONTEXT_SIZE 0
+#endif // NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_MBEDTLS_ECC_BP384R1)
+
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_MBEDTLS_ECC_BP512R1)
+// Aliases for one common MBEDTLS implementation
+#define nrf_crypto_backend_bp512r1_ecdh_compute nrf_crypto_backend_mbedtls_ecdh_compute
+typedef uint32_t nrf_crypto_backend_bp512r1_ecdh_context_t;
+#define NRF_CRYPTO_BACKEND_BP512R1_ECDH_CONTEXT_SIZE 0
+#endif // NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_MBEDTLS_ECC_BP512R1)
+
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_MBEDTLS_ECC_CURVE25519)
+// Aliases for one common MBEDTLS implementation
+#define nrf_crypto_backend_curve25519_ecdh_compute nrf_crypto_backend_mbedtls_ecdh_compute
+typedef uint32_t nrf_crypto_backend_curve25519_ecdh_context_t;
+#define NRF_CRYPTO_BACKEND_CURVE25519_ECDH_CONTEXT_SIZE 0
+#endif // NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_MBEDTLS_ECC_CURVE25519)
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // NRF_MODULE_ENABLED(NRF_CRYPTO) && NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_MBEDTLS)
+
+#endif // MBEDTLS_BACKEND_ECDH_H__
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/mbedtls/mbedtls_backend_ecdsa.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/mbedtls/mbedtls_backend_ecdsa.c
new file mode 100644
index 0000000..04a5a90
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/mbedtls/mbedtls_backend_ecdsa.c
@@ -0,0 +1,176 @@
+/**
+ * Copyright (c) 2018 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+
+#include "sdk_config.h"
+#include "nordic_common.h"
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO) && NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_MBEDTLS)
+
+#include <stdint.h>
+#include <stdbool.h>
+#include <string.h>
+
+#include "nrf_crypto_ecc.h"
+#include "nrf_crypto_ecdsa.h"
+
+/*lint -save -e????*/
+#if !defined(MBEDTLS_CONFIG_FILE)
+#include "mbedtls/config.h"
+#else
+#include MBEDTLS_CONFIG_FILE
+#endif
+#include "mbedtls/ecp.h"
+#include "mbedtls/ecdsa.h"
+#include "mbedtls/sha256.h"
+#include "mbedtls/sha512.h"
+/*lint -restore*/
+
+
+ret_code_t nrf_crypto_backend_mbedtls_sign(
+ void * p_context,
+ void const * p_private_key,
+ uint8_t const * p_data,
+ size_t data_size,
+ uint8_t * p_signature)
+{
+ int result;
+ mbedtls_mpi r_mpi;
+ mbedtls_mpi s_mpi;
+ mbedtls_ecp_group group;
+
+ nrf_crypto_backend_mbedtls_ecc_private_key_t const * p_prv =
+ (nrf_crypto_backend_mbedtls_ecc_private_key_t const *)p_private_key;
+
+ nrf_crypto_ecc_curve_info_t const * p_info = p_prv->header.p_info;
+
+ if (!nrf_crypto_backend_mbedtls_ecc_group_load(&group, p_info))
+ {
+ return NRF_ERROR_CRYPTO_INTERNAL;
+ }
+
+ mbedtls_mpi_init(&r_mpi);
+ mbedtls_mpi_init(&s_mpi);
+ result = mbedtls_ecdsa_sign(&group,
+ &r_mpi,
+ &s_mpi,
+ &p_prv->key,
+ p_data,
+ data_size,
+ nrf_crypto_backend_mbedtls_ecc_mbedtls_rng,
+ NULL);
+
+ mbedtls_ecp_group_free(&group);
+
+ if (result == 0)
+ {
+ result = mbedtls_mpi_write_binary(&r_mpi, p_signature, p_info->raw_private_key_size);
+ if (result == 0)
+ {
+ result = mbedtls_mpi_write_binary(&s_mpi,
+ &p_signature[p_info->raw_private_key_size],
+ p_info->raw_private_key_size);
+ }
+ }
+
+ mbedtls_mpi_free(&r_mpi);
+ mbedtls_mpi_free(&s_mpi);
+
+ if (result != 0)
+ {
+ return NRF_ERROR_CRYPTO_INTERNAL;
+ }
+ return NRF_SUCCESS;
+}
+
+
+ret_code_t nrf_crypto_backend_mbedtls_verify(
+ void * p_context,
+ void const * p_public_key,
+ uint8_t const * p_data,
+ size_t data_size,
+ uint8_t const * p_signature)
+{
+ int result;
+ mbedtls_mpi r_mpi;
+ mbedtls_mpi s_mpi;
+ mbedtls_ecp_group group;
+
+ nrf_crypto_backend_mbedtls_ecc_public_key_t const * p_pub =
+ (nrf_crypto_backend_mbedtls_ecc_public_key_t const *)p_public_key;
+
+ nrf_crypto_ecc_curve_info_t const * p_info = p_pub->header.p_info;
+
+ if (!nrf_crypto_backend_mbedtls_ecc_group_load(&group, p_info))
+ {
+ return NRF_ERROR_CRYPTO_INTERNAL;
+ }
+
+ mbedtls_mpi_init(&r_mpi);
+ mbedtls_mpi_init(&s_mpi);
+
+ result = mbedtls_mpi_read_binary(&r_mpi, p_signature, p_info->raw_private_key_size);
+ if (result == 0)
+ {
+ result = mbedtls_mpi_read_binary(&s_mpi,
+ &p_signature[p_info->raw_private_key_size],
+ p_info->raw_private_key_size);
+ if (result == 0)
+ {
+ result = mbedtls_ecdsa_verify(&group, p_data, data_size, &p_pub->key, &r_mpi, &s_mpi);
+ }
+ }
+
+ mbedtls_ecp_group_free(&group);
+ mbedtls_mpi_free(&r_mpi);
+ mbedtls_mpi_free(&s_mpi);
+
+ if (result == MBEDTLS_ERR_ECP_VERIFY_FAILED)
+ {
+ return NRF_ERROR_CRYPTO_ECDSA_INVALID_SIGNATURE;
+ }
+ else if (result != 0)
+ {
+ return NRF_ERROR_CRYPTO_INTERNAL;
+ }
+ return NRF_SUCCESS;
+}
+
+
+#endif // NRF_MODULE_ENABLED(NRF_CRYPTO) && NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_MBEDTLS)
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/mbedtls/mbedtls_backend_ecdsa.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/mbedtls/mbedtls_backend_ecdsa.h
new file mode 100644
index 0000000..7ad85a9
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/mbedtls/mbedtls_backend_ecdsa.h
@@ -0,0 +1,240 @@
+/**
+ * Copyright (c) 2018 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+
+#ifndef MBEDTLS_BACKEND_ECDSA_H__
+#define MBEDTLS_BACKEND_ECDSA_H__
+
+#include "sdk_config.h"
+#include "nordic_common.h"
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO) && NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_MBEDTLS)
+
+#include "nrf_crypto_ecc_shared.h"
+#include "nrf_crypto_ecdsa_shared.h"
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+/** @internal See @ref nrf_crypto_backend_ecdsa_sign_fn_t.
+ */
+ret_code_t nrf_crypto_backend_mbedtls_sign(
+ void * p_context,
+ void const * p_private_key,
+ uint8_t const * p_data,
+ size_t data_size,
+ uint8_t * p_signature);
+
+
+/** @internal See @ref nrf_crypto_backend_ecdsa_verify_fn_t.
+ */
+ret_code_t nrf_crypto_backend_mbedtls_verify(
+ void * p_context,
+ void const * p_public_key,
+ uint8_t const * p_data,
+ size_t data_size,
+ uint8_t const * p_signature);
+
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_MBEDTLS_ECC_SECP192R1)
+// Context is not used by mbed TLS, so its size is 0
+#define NRF_CRYPTO_BACKEND_SECP192R1_SIGN_CONTEXT_SIZE 0
+#define NRF_CRYPTO_BACKEND_SECP192R1_VERIFY_CONTEXT_SIZE 0
+// Dummy typedefs for unused contexts
+typedef uint32_t nrf_crypto_backend_secp192r1_sign_context_t;
+typedef uint32_t nrf_crypto_backend_secp192r1_verify_context_t;
+// Alias for common mbed TLS
+#define nrf_crypto_backend_secp192r1_sign nrf_crypto_backend_mbedtls_sign
+#define nrf_crypto_backend_secp192r1_verify nrf_crypto_backend_mbedtls_verify
+#endif
+
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_MBEDTLS_ECC_SECP224R1)
+// Context is not used by mbed TLS, so its size is 0
+#define NRF_CRYPTO_BACKEND_SECP224R1_SIGN_CONTEXT_SIZE 0
+#define NRF_CRYPTO_BACKEND_SECP224R1_VERIFY_CONTEXT_SIZE 0
+// Dummy typedefs for unused contexts
+typedef uint32_t nrf_crypto_backend_secp224r1_sign_context_t;
+typedef uint32_t nrf_crypto_backend_secp224r1_verify_context_t;
+// Alias for common mbed TLS
+#define nrf_crypto_backend_secp224r1_sign nrf_crypto_backend_mbedtls_sign
+#define nrf_crypto_backend_secp224r1_verify nrf_crypto_backend_mbedtls_verify
+#endif
+
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_MBEDTLS_ECC_SECP256R1)
+// Context is not used by mbed TLS, so its size is 0
+#define NRF_CRYPTO_BACKEND_SECP256R1_SIGN_CONTEXT_SIZE 0
+#define NRF_CRYPTO_BACKEND_SECP256R1_VERIFY_CONTEXT_SIZE 0
+// Dummy typedefs for unused contexts
+typedef uint32_t nrf_crypto_backend_secp256r1_sign_context_t;
+typedef uint32_t nrf_crypto_backend_secp256r1_verify_context_t;
+// Alias for common mbed TLS
+#define nrf_crypto_backend_secp256r1_sign nrf_crypto_backend_mbedtls_sign
+#define nrf_crypto_backend_secp256r1_verify nrf_crypto_backend_mbedtls_verify
+#endif
+
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_MBEDTLS_ECC_SECP384R1)
+// Context is not used by mbed TLS, so its size is 0
+#define NRF_CRYPTO_BACKEND_SECP384R1_SIGN_CONTEXT_SIZE 0
+#define NRF_CRYPTO_BACKEND_SECP384R1_VERIFY_CONTEXT_SIZE 0
+// Dummy typedefs for unused contexts
+typedef uint32_t nrf_crypto_backend_secp384r1_sign_context_t;
+typedef uint32_t nrf_crypto_backend_secp384r1_verify_context_t;
+// Alias for common mbed TLS
+#define nrf_crypto_backend_secp384r1_sign nrf_crypto_backend_mbedtls_sign
+#define nrf_crypto_backend_secp384r1_verify nrf_crypto_backend_mbedtls_verify
+#endif
+
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_MBEDTLS_ECC_SECP521R1)
+// Context is not used by mbed TLS, so its size is 0
+#define NRF_CRYPTO_BACKEND_SECP521R1_SIGN_CONTEXT_SIZE 0
+#define NRF_CRYPTO_BACKEND_SECP521R1_VERIFY_CONTEXT_SIZE 0
+// Dummy typedefs for unused contexts
+typedef uint32_t nrf_crypto_backend_secp521r1_sign_context_t;
+typedef uint32_t nrf_crypto_backend_secp521r1_verify_context_t;
+// Alias for common mbed TLS
+#define nrf_crypto_backend_secp521r1_sign nrf_crypto_backend_mbedtls_sign
+#define nrf_crypto_backend_secp521r1_verify nrf_crypto_backend_mbedtls_verify
+#endif
+
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_MBEDTLS_ECC_SECP192K1)
+// Context is not used by mbed TLS, so its size is 0
+#define NRF_CRYPTO_BACKEND_SECP192K1_SIGN_CONTEXT_SIZE 0
+#define NRF_CRYPTO_BACKEND_SECP192K1_VERIFY_CONTEXT_SIZE 0
+// Dummy typedefs for unused contexts
+typedef uint32_t nrf_crypto_backend_secp192k1_sign_context_t;
+typedef uint32_t nrf_crypto_backend_secp192k1_verify_context_t;
+// Alias for common mbed TLS
+#define nrf_crypto_backend_secp192k1_sign nrf_crypto_backend_mbedtls_sign
+#define nrf_crypto_backend_secp192k1_verify nrf_crypto_backend_mbedtls_verify
+#endif
+
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_MBEDTLS_ECC_SECP224K1)
+// Context is not used by mbed TLS, so its size is 0
+#define NRF_CRYPTO_BACKEND_SECP224K1_SIGN_CONTEXT_SIZE 0
+#define NRF_CRYPTO_BACKEND_SECP224K1_VERIFY_CONTEXT_SIZE 0
+// Dummy typedefs for unused contexts
+typedef uint32_t nrf_crypto_backend_secp224k1_sign_context_t;
+typedef uint32_t nrf_crypto_backend_secp224k1_verify_context_t;
+// Alias for common mbed TLS
+#define nrf_crypto_backend_secp224k1_sign nrf_crypto_backend_mbedtls_sign
+#define nrf_crypto_backend_secp224k1_verify nrf_crypto_backend_mbedtls_verify
+#endif
+
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_MBEDTLS_ECC_SECP256K1)
+// Context is not used by mbed TLS, so its size is 0
+#define NRF_CRYPTO_BACKEND_SECP256K1_SIGN_CONTEXT_SIZE 0
+#define NRF_CRYPTO_BACKEND_SECP256K1_VERIFY_CONTEXT_SIZE 0
+// Dummy typedefs for unused contexts
+typedef uint32_t nrf_crypto_backend_secp256k1_sign_context_t;
+typedef uint32_t nrf_crypto_backend_secp256k1_verify_context_t;
+// Alias for common mbed TLS
+#define nrf_crypto_backend_secp256k1_sign nrf_crypto_backend_mbedtls_sign
+#define nrf_crypto_backend_secp256k1_verify nrf_crypto_backend_mbedtls_verify
+#endif
+
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_MBEDTLS_ECC_BP256R1)
+// Context is not used by mbed TLS, so its size is 0
+#define NRF_CRYPTO_BACKEND_BP256R1_SIGN_CONTEXT_SIZE 0
+#define NRF_CRYPTO_BACKEND_BP256R1_VERIFY_CONTEXT_SIZE 0
+// Dummy typedefs for unused contexts
+typedef uint32_t nrf_crypto_backend_bp256r1_sign_context_t;
+typedef uint32_t nrf_crypto_backend_bp256r1_verify_context_t;
+// Alias for common mbed TLS
+#define nrf_crypto_backend_bp256r1_sign nrf_crypto_backend_mbedtls_sign
+#define nrf_crypto_backend_bp256r1_verify nrf_crypto_backend_mbedtls_verify
+#endif
+
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_MBEDTLS_ECC_BP384R1)
+// Context is not used by mbed TLS, so its size is 0
+#define NRF_CRYPTO_BACKEND_BP384R1_SIGN_CONTEXT_SIZE 0
+#define NRF_CRYPTO_BACKEND_BP384R1_VERIFY_CONTEXT_SIZE 0
+// Dummy typedefs for unused contexts
+typedef uint32_t nrf_crypto_backend_bp384r1_sign_context_t;
+typedef uint32_t nrf_crypto_backend_bp384r1_verify_context_t;
+// Alias for common mbed TLS
+#define nrf_crypto_backend_bp384r1_sign nrf_crypto_backend_mbedtls_sign
+#define nrf_crypto_backend_bp384r1_verify nrf_crypto_backend_mbedtls_verify
+#endif
+
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_MBEDTLS_ECC_BP512R1)
+// Context is not used by mbed TLS, so its size is 0
+#define NRF_CRYPTO_BACKEND_BP512R1_SIGN_CONTEXT_SIZE 0
+#define NRF_CRYPTO_BACKEND_BP512R1_VERIFY_CONTEXT_SIZE 0
+// Dummy typedefs for unused contexts
+typedef uint32_t nrf_crypto_backend_bp512r1_sign_context_t;
+typedef uint32_t nrf_crypto_backend_bp512r1_verify_context_t;
+// Alias for common mbed TLS
+#define nrf_crypto_backend_bp512r1_sign nrf_crypto_backend_mbedtls_sign
+#define nrf_crypto_backend_bp512r1_verify nrf_crypto_backend_mbedtls_verify
+#endif
+
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_MBEDTLS_ECC_CURVE25519)
+// Context is not used by mbed TLS, so its size is 0
+#define NRF_CRYPTO_BACKEND_CURVE25519_SIGN_CONTEXT_SIZE 0
+#define NRF_CRYPTO_BACKEND_CURVE25519_VERIFY_CONTEXT_SIZE 0
+// Dummy typedefs for unused contexts
+typedef uint32_t nrf_crypto_backend_curve25519_sign_context_t;
+typedef uint32_t nrf_crypto_backend_curve25519_verify_context_t;
+// No ECDSA implementation for Curve25519
+#define nrf_crypto_backend_curve25519_sign NULL
+#define nrf_crypto_backend_curve25519_verify NULL
+#endif
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // NRF_MODULE_ENABLED(NRF_CRYPTO) && NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_MBEDTLS)
+
+#endif // MBEDTLS_BACKEND_ECDSA_H__
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/mbedtls/mbedtls_backend_hash.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/mbedtls/mbedtls_backend_hash.c
new file mode 100644
index 0000000..b244e0a
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/mbedtls/mbedtls_backend_hash.c
@@ -0,0 +1,196 @@
+/**
+ * Copyright (c) 2018 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+
+#include "sdk_common.h"
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO) && NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_MBEDTLS)
+
+#include "mbedtls_backend_hash.h"
+#include "nrf_crypto_init.h"
+#include "nrf_crypto_types.h"
+#include "nrf_crypto_error.h"
+#include "nrf_crypto_hash_shared.h"
+#include "sdk_macros.h"
+#include "nrf_log.h"
+#include "nrf_assert.h"
+
+/*lint -save -e????*/
+#if !defined(MBEDTLS_CONFIG_FILE)
+#include "mbedtls/config.h"
+#else
+#include MBEDTLS_CONFIG_FILE
+#endif
+
+#include "mbedtls/md.h"
+#include "mbedtls/sha256.h"
+#include "mbedtls/sha512.h"
+/*lint -restore*/
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_MBEDTLS_HASH_SHA256)
+
+static ret_code_t mbedtls_backend_hash_sha256_init(void * const p_context)
+{
+ // No parameter testing on this level.
+ // This has been done on upper level.
+
+ mbedtls_sha256_context * p_backend_context
+ = &(((nrf_crypto_backend_hash_sha256_context_t *)p_context)->context);
+
+ mbedtls_sha256_init(p_backend_context);
+
+ mbedtls_sha256_starts(p_backend_context, 0);
+
+ return NRF_SUCCESS;
+}
+
+static uint32_t mbedtls_backend_hash_sha256_update(void * const p_context,
+ uint8_t const * p_data,
+ size_t size)
+{
+ // Limited parameter testing on this level.
+ // This has been done on upper level.
+
+ mbedtls_sha256_context * p_backend_context
+ = &(((nrf_crypto_backend_hash_sha256_context_t *)p_context)->context);
+
+ mbedtls_sha256_update(p_backend_context, p_data, size);
+
+ return NRF_SUCCESS;
+}
+
+
+static uint32_t mbedtls_backend_hash_sha256_finalize(void * const p_context,
+ uint8_t * p_digest,
+ size_t * const p_digest_size)
+{
+ // Limited parameter testing on this level.
+ // This has been done on upper level.
+
+ mbedtls_sha256_context * p_backend_context
+ = &(((nrf_crypto_backend_hash_sha256_context_t *)p_context)->context);
+
+ mbedtls_sha256_finish(p_backend_context, p_digest);
+
+ *p_digest_size = NRF_CRYPTO_HASH_SIZE_SHA256;
+
+ return NRF_SUCCESS;
+}
+
+
+const nrf_crypto_hash_info_t g_nrf_crypto_hash_sha256_info =
+{
+ .init_fn = mbedtls_backend_hash_sha256_init,
+ .update_fn = mbedtls_backend_hash_sha256_update,
+ .finalize_fn = mbedtls_backend_hash_sha256_finalize,
+ .digest_size = NRF_CRYPTO_HASH_SIZE_SHA256,
+ .context_size = sizeof(nrf_crypto_backend_hash_sha256_context_t),
+ .hash_mode = NRF_CRYPTO_HASH_MODE_SHA256
+};
+
+
+#endif // NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_MBEDTLS_HASH_SHA256)
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_MBEDTLS_HASH_SHA512)
+
+
+static ret_code_t mbedtls_backend_hash_sha512_init(void * p_context)
+{
+ // No parameter testing on this level.
+ // This has been done on upper level.
+
+ mbedtls_sha512_context * p_backend_context
+ = &(((nrf_crypto_backend_hash_sha512_context_t *)p_context)->context);
+
+ mbedtls_sha512_init(p_backend_context);
+
+ mbedtls_sha512_starts(p_backend_context, 0);
+
+ return NRF_SUCCESS;
+}
+
+
+static ret_code_t mbedtls_backend_hash_sha512_update(void * const p_context,
+ uint8_t const * p_data,
+ size_t size)
+{
+ // Limited parameter testing on this level.
+ // This has been done on upper level.
+
+ mbedtls_sha512_context * p_backend_context
+ = &(((nrf_crypto_backend_hash_sha512_context_t *)p_context)->context);
+
+ mbedtls_sha512_update(p_backend_context, p_data, size);
+
+ return NRF_SUCCESS;
+}
+
+
+static ret_code_t mbedtls_backend_hash_sha512_finalize(void * const p_context,
+ uint8_t * p_digest,
+ size_t * const p_digest_size)
+{
+ // Limited parameter testing on this level.
+ // This has been done on upper level.
+
+ mbedtls_sha512_context * p_backend_context
+ = &(((nrf_crypto_backend_hash_sha512_context_t *)p_context)->context);
+
+ mbedtls_sha512_finish(p_backend_context, p_digest);
+
+ *p_digest_size = NRF_CRYPTO_HASH_SIZE_SHA512;
+
+ return NRF_SUCCESS;
+}
+
+
+const nrf_crypto_hash_info_t g_nrf_crypto_hash_sha512_info =
+{
+ .init_fn = mbedtls_backend_hash_sha512_init,
+ .update_fn = mbedtls_backend_hash_sha512_update,
+ .finalize_fn = mbedtls_backend_hash_sha512_finalize,
+ .digest_size = NRF_CRYPTO_HASH_SIZE_SHA512,
+ .context_size = sizeof(nrf_crypto_backend_hash_sha512_context_t),
+ .hash_mode = NRF_CRYPTO_HASH_MODE_SHA512
+};
+
+
+#endif // NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_MBEDTLS_HASH_SHA512)
+
+#endif // NRF_MODULE_ENABLED(NRF_CRYPTO) && NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_MBEDTLS)
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/mbedtls/mbedtls_backend_hash.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/mbedtls/mbedtls_backend_hash.h
new file mode 100644
index 0000000..f69be9b
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/mbedtls/mbedtls_backend_hash.h
@@ -0,0 +1,128 @@
+/**
+ * Copyright (c) 2018 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+
+#ifndef MBEDTLS_BACKEND_HASH_H__
+#define MBEDTLS_BACKEND_HASH_H__
+
+/** @file
+ *
+ * @defgroup nrf_crypto_mbedtls_backend_hash nrf_crypto mbedtls backend hash
+ * @{
+ * @ingroup nrf_crypto_mbedtls_backend
+ *
+ * @brief Hash functionality provided by the nrf_crypto mbedtls backend.
+ */
+
+#include "sdk_common.h"
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_MBEDTLS)
+
+#include "sdk_errors.h"
+#include "nrf_crypto_hash_shared.h"
+
+/*lint -save -e????*/
+#include "mbedtls/sha256.h"
+#include "mbedtls/sha512.h"
+/*lint -restore*/
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_MBEDTLS_HASH_SHA256)
+
+// Flag that nrf_crypto_hash frontend can be compiled
+#undef NRF_CRYPTO_HASH_ENABLED
+#define NRF_CRYPTO_HASH_ENABLED 1
+
+// Duplicate backend enabled test for SHA-256
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_HASH_SHA256)
+#error "Duplicate definition of SHA-256. More than one backend enabled");
+#endif
+
+// Flag that SHA-256 is enabled in backend
+#define NRF_CRYPTO_HASH_SHA256_ENABLED 1
+
+
+/**brief nrf_crypto_hash context for SHA-256 in nrf_crypto mbedtls backend. */
+typedef struct
+{
+ nrf_crypto_hash_internal_context_t header; /**< Common header for context. */
+ mbedtls_sha256_context context; /**< Hash context internal to mbedtls. */
+} nrf_crypto_backend_hash_sha256_context_t;
+
+
+#endif // NRF_CRYPTO_BACKEND_MBEDTLS_HASH_SHA256_ENABLED
+
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_MBEDTLS_HASH_SHA512)
+
+// Flag that nrf_crypto_hash frontend can be compiled
+#undef NRF_CRYPTO_HASH_ENABLED
+#define NRF_CRYPTO_HASH_ENABLED 1
+
+// Duplicate backend enabled test for SHA-512
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_HASH_SHA512)
+#error "Duplicate definition of SHA-512. More than one backend enabled");
+#endif
+
+// Flag that SHA-512 is enabled in backend
+#define NRF_CRYPTO_HASH_SHA512_ENABLED 1
+
+
+/**brief nrf_crypto_hash context for SHA-512 in nrf_crypto mbedtls backend. */
+typedef struct
+{
+ nrf_crypto_hash_internal_context_t header; /**< Common header for context. */
+ mbedtls_sha512_context context; /**< Hash context internal to mbedtls. */
+} nrf_crypto_backend_hash_sha512_context_t;
+
+
+#endif // NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_MBEDTLS_HASH_SHA512)
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_MBEDTLS)
+
+/**@} */
+
+#endif //MBEDTLS_BACKEND_HASH_H__
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/mbedtls/mbedtls_backend_hmac.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/mbedtls/mbedtls_backend_hmac.c
new file mode 100644
index 0000000..0a6658c
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/mbedtls/mbedtls_backend_hmac.c
@@ -0,0 +1,230 @@
+/**
+ * Copyright (c) 2018 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+
+#include "sdk_common.h"
+#if NRF_MODULE_ENABLED(NRF_CRYPTO) && NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_MBEDTLS)
+
+#include "nrf_log.h"
+#include "nrf_crypto_error.h"
+#include "nrf_crypto_types.h"
+#include "mbedtls_backend_hmac.h"
+
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_MBEDTLS_HMAC_SHA256)
+
+static ret_code_t mbedtls_backend_hmac_init_sha256(void * const p_context,
+ uint8_t const * p_key,
+ size_t key_size)
+{
+ int err_code;
+ nrf_crypto_backend_mbedtls_hmac_sha256_context_t * p_ctx =
+ (nrf_crypto_backend_mbedtls_hmac_sha256_context_t *)p_context;
+
+ // Memset context to 0. This is equevalend with a call to mbedtls_md_init().
+ memset(p_ctx->md_ctx_buffer, 0, sizeof(p_ctx->md_ctx_buffer));
+ memset(p_ctx->hmac_ctx_buffer, 0, sizeof(p_ctx->hmac_ctx_buffer));
+
+ // Set info and context pointers to buffer allocated by user.
+ // This is Normally handled by mbedtls_md_setup(), but has to be done here in order
+ // to avoid dynamic allocation of memory inside mbed TLS.
+ p_ctx->mbedtls_ctx.md_info = mbedtls_md_info_from_type(MBEDTLS_MD_SHA256);
+ p_ctx->mbedtls_ctx.md_ctx = p_ctx->md_ctx_buffer;
+ p_ctx->mbedtls_ctx.hmac_ctx = p_ctx->hmac_ctx_buffer;
+
+ // Enter key to start
+ err_code = mbedtls_md_hmac_starts(&p_ctx->mbedtls_ctx,
+ p_key,
+ key_size);
+
+ if (err_code != 0)
+ {
+ NRF_LOG_ERROR("Error in mbedtls_md_hmac_starts: %u", err_code);
+ return NRF_ERROR_CRYPTO_INTERNAL;
+ }
+
+ return NRF_SUCCESS;
+}
+
+
+static ret_code_t mbedtls_backend_hmac_update_sha256(void * const p_context,
+ uint8_t const * p_data,
+ size_t size)
+{
+ int err_code;
+ nrf_crypto_backend_mbedtls_hmac_sha256_context_t * p_ctx =
+ (nrf_crypto_backend_mbedtls_hmac_sha256_context_t *)p_context;
+
+ err_code = mbedtls_md_hmac_update(&p_ctx->mbedtls_ctx, p_data, size);
+ if (err_code != 0)
+ {
+ NRF_LOG_ERROR("Error in mbedtls_md_hmac_update: %u", err_code);
+ return NRF_ERROR_CRYPTO_INTERNAL;
+ }
+
+ return NRF_SUCCESS;
+}
+
+
+static ret_code_t mbedtls_backend_hmac_finalize_sha256(void * const p_context,
+ uint8_t * p_digest,
+ size_t * const p_size)
+{
+ int err_code;
+ nrf_crypto_backend_mbedtls_hmac_sha256_context_t * const p_ctx =
+ (nrf_crypto_backend_mbedtls_hmac_sha256_context_t *)p_context;
+
+ // Set the digest length to 0 so that this is used in case of any error.
+ *p_size = 0;
+
+ err_code = mbedtls_md_hmac_finish(&p_ctx->mbedtls_ctx, p_digest);
+ if (err_code != 0)
+ {
+ NRF_LOG_ERROR("Error in mbedtls_md_hmac_finish: %u", err_code);
+ return NRF_ERROR_CRYPTO_INTERNAL;
+ }
+
+ *p_size = p_ctx->header.p_info->digest_size;
+
+ return NRF_SUCCESS;
+}
+
+
+// Information structure for HMAC SHA256 using mbed TLS backend.
+const nrf_crypto_hmac_info_t g_nrf_crypto_hmac_sha256_info =
+{
+ .init_fn = mbedtls_backend_hmac_init_sha256,
+ .update_fn = mbedtls_backend_hmac_update_sha256,
+ .finalize_fn = mbedtls_backend_hmac_finalize_sha256,
+ .digest_size = NRF_CRYPTO_HASH_SIZE_SHA256,
+ .context_size = sizeof(nrf_crypto_backend_hmac_sha256_context_t),
+ .type = NRF_CRYPTO_HMAC_SHA256_TYPE
+};
+
+#endif // NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_MBEDTLS_HMAC_SHA256)
+
+
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_MBEDTLS_HMAC_SHA512)
+
+static ret_code_t mbedtls_backend_hmac_init_sha512(void * const p_context,
+ uint8_t const * p_key,
+ size_t key_size)
+{
+ int err_code;
+ nrf_crypto_backend_mbedtls_hmac_sha512_context_t * p_ctx =
+ (nrf_crypto_backend_mbedtls_hmac_sha512_context_t *)p_context;
+
+ // Memset context to 0. This is equevalend with a call to mbedtls_md_init().
+ memset(p_ctx->md_ctx_buffer, 0, sizeof(p_ctx->md_ctx_buffer));
+ memset(p_ctx->hmac_ctx_buffer, 0, sizeof(p_ctx->hmac_ctx_buffer));
+
+ // Set info and context pointers to buffer allocated by user.
+ // (Normally handled by mbedtls_md_setup())
+ p_ctx->mbedtls_ctx.md_info = mbedtls_md_info_from_type(MBEDTLS_MD_SHA512);
+ p_ctx->mbedtls_ctx.md_ctx = p_ctx->md_ctx_buffer;
+ p_ctx->mbedtls_ctx.hmac_ctx = p_ctx->hmac_ctx_buffer;
+
+ // Enter key to start
+ err_code = mbedtls_md_hmac_starts(&p_ctx->mbedtls_ctx, p_key, key_size);
+ if (err_code != 0)
+ {
+ NRF_LOG_ERROR("Error in mbedtls_md_hmac_starts: %u", err_code);
+ return NRF_ERROR_CRYPTO_INTERNAL;
+ }
+
+ return NRF_SUCCESS;
+}
+
+
+static ret_code_t mbedtls_backend_hmac_update_sha512(void * const p_context,
+ uint8_t const * p_data,
+ size_t size)
+{
+ int err_code;
+ nrf_crypto_backend_mbedtls_hmac_sha512_context_t * p_ctx =
+ (nrf_crypto_backend_mbedtls_hmac_sha512_context_t *)p_context;
+
+ err_code = mbedtls_md_hmac_update(&p_ctx->mbedtls_ctx, p_data, size);
+ if (err_code != 0)
+ {
+ NRF_LOG_ERROR("Error in mbedtls_md_hmac_update: %u", err_code);
+ return NRF_ERROR_CRYPTO_INTERNAL;
+ }
+
+ return NRF_SUCCESS;
+}
+
+
+static ret_code_t mbedtls_backend_hmac_finalize_sha512(void * const p_context,
+ uint8_t * p_digest,
+ size_t * const p_size)
+{
+ int err_code;
+ nrf_crypto_backend_mbedtls_hmac_sha512_context_t * p_ctx =
+ (nrf_crypto_backend_mbedtls_hmac_sha512_context_t *)p_context;
+
+ // Set the digest length to 0 so that this is used in case of any error.
+ *p_size = 0;
+
+ err_code = mbedtls_md_hmac_finish(&p_ctx->mbedtls_ctx, p_digest);
+ if (err_code != 0)
+ {
+ NRF_LOG_ERROR("Error in mbedtls_md_hmac_finish: %u", err_code);
+ return NRF_ERROR_CRYPTO_INTERNAL; }
+
+ *p_size = p_ctx->header.p_info->digest_size;
+
+ return NRF_SUCCESS;
+}
+
+
+// Information structure for HMAC SHA512 using mbed TLS backend.
+const nrf_crypto_hmac_info_t g_nrf_crypto_hmac_sha512_info =
+{
+ .init_fn = mbedtls_backend_hmac_init_sha512,
+ .update_fn = mbedtls_backend_hmac_update_sha512,
+ .finalize_fn = mbedtls_backend_hmac_finalize_sha512,
+ .digest_size = NRF_CRYPTO_HASH_SIZE_SHA512,
+ .context_size = sizeof(nrf_crypto_backend_hmac_sha512_context_t),
+ .type = NRF_CRYPTO_HMAC_SHA512_TYPE
+};
+
+#endif // NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_MBEDTLS_HMAC_SHA512)
+#endif // NRF_MODULE_ENABLED(NRF_CRYPTO) && NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_MBEDTLS)
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/mbedtls/mbedtls_backend_hmac.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/mbedtls/mbedtls_backend_hmac.h
new file mode 100644
index 0000000..2645bba
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/mbedtls/mbedtls_backend_hmac.h
@@ -0,0 +1,140 @@
+/**
+ * Copyright (c) 2018 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+
+#ifndef MBEDTLS_BACKEND_HMAC_H__
+#define MBEDTLS_BACKEND_HMAC_H__
+
+/** @file
+ *
+ * @defgroup nrf_crypto_mbedtls_backend_hmac mbed TLS backend for HMAC
+ * @{
+ * @ingroup nrf_crypto_mbedtls_backend
+ *
+ * @brief Backend wrapper for mbed TLS. None of these types should be used directly by the
+ * application.
+ */
+
+#include "sdk_common.h"
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_MBEDTLS) && \
+ ( NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_MBEDTLS_HMAC_SHA256) || \
+ NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_MBEDTLS_HMAC_SHA512) )
+
+#include "nrf_crypto_hmac_shared.h"
+/*lint -save -e????*/
+#include "mbedtls/md.h"
+#include "mbedtls/sha256.h"
+#include "mbedtls/sha512.h"
+/*lint -restore*/
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#undef NRF_CRYPTO_HMAC_ENABLED
+#define NRF_CRYPTO_HMAC_ENABLED 1
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_MBEDTLS_HMAC_SHA256)
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_HMAC_SHA256)
+#error "Duplicate definition of HMAC SHA-256. More than one backend enabled"
+#endif // NRF_CRYPTO_HMAC_SHA256_ENABLED
+#define NRF_CRYPTO_HMAC_SHA256_ENABLED 1
+
+/**
+ * @internal @brief Internal context object used by the mbed TLS backend wrapper for HMAC SHA256.
+ *
+ * @note This should never be used directly. Use @ref nrf_crypto_backend_hmac_sha256_context_t
+ * instead.
+ */
+typedef struct
+{
+ nrf_crypto_hmac_internal_context_t header; //!< Internal nrf_crypto_hmac context.
+ mbedtls_md_context_t mbedtls_ctx; //!< Mbed TLS context object.
+ uint8_t md_ctx_buffer[sizeof(mbedtls_sha256_context)]; //!< Message digest buffer for mbed TLS.
+ uint16_t hmac_ctx_buffer[64]; //!< Hash buffer for mbed TLS of size defined in mbedtls_sha256_info in md_internal.h.
+} nrf_crypto_backend_mbedtls_hmac_sha256_context_t;
+
+/**
+ * @internal @brief Context for HMAC SHA256 using mbed TLS backend.
+ */
+typedef nrf_crypto_backend_mbedtls_hmac_sha256_context_t nrf_crypto_backend_hmac_sha256_context_t;
+
+
+#endif // NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_MBEDTLS_HMAC_SHA256)
+
+
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_MBEDTLS_HMAC_SHA512)
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_HMAC_SHA512)
+#error "Duplicate definition of HMAC SHA-512. More than one backend enabled"
+#endif // NRF_CRYPTO_HMAC_SHA512_ENABLED
+#define NRF_CRYPTO_HMAC_SHA512_ENABLED 1
+
+/**
+ * @internal @brief Internal context object used by the mbed TLS backend wrapper for HMAC SHA512.
+ *
+ * @note This should never be used directly. Use @ref nrf_crypto_backend_hmac_sha512_context_t
+ * instead.
+ */
+typedef struct
+{
+ nrf_crypto_hmac_internal_context_t header; //!< Internal nrf_crypto_hmac context header.
+ mbedtls_md_context_t mbedtls_ctx; //!< Mbed TLS context object.
+ uint8_t md_ctx_buffer[sizeof(mbedtls_sha512_context)]; //!< Message digest buffer for mbed TLS.
+ uint16_t hmac_ctx_buffer[128]; //!< Hash buffer for mbed TLS of size defined in mbedtls_sha512_info in md_internal.h.
+} nrf_crypto_backend_mbedtls_hmac_sha512_context_t;
+
+/**
+ * @internal @brief Context for HMAC SHA512 using mbed TLS backend.
+ */
+typedef nrf_crypto_backend_mbedtls_hmac_sha512_context_t nrf_crypto_backend_hmac_sha512_context_t;
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_MBEDTLS_HMAC_SHA512)
+#endif // NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_MBEDTLS) && ( NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_MBEDTLS_HMAC_SHA256) || NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_MBEDTLS_HMAC_SHA512) )
+
+/**@} */
+
+#endif // MBEDTLS_BACKEND_HMAC_H__
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/mbedtls/mbedtls_backend_init.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/mbedtls/mbedtls_backend_init.c
new file mode 100644
index 0000000..aa37d67
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/mbedtls/mbedtls_backend_init.c
@@ -0,0 +1,106 @@
+/**
+ * Copyright (c) 2018 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+
+#include "sdk_common.h"
+#include "sdk_config.h"
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO) && NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_MBEDTLS)
+
+#include <string.h>
+#include <stdint.h>
+#include "nrf_crypto_init.h"
+#include "nrf_crypto_mem.h"
+/*lint -save -e????*/
+#include "mbedtls/platform.h"
+/*lint -restore*/
+
+
+#if NRF_CRYPTO_ALLOC_ON_STACK
+#error "MBED TLS backend does not support memory allocation on stack. Use different allocator."
+#endif
+
+
+/** @internal @brief Function to use NRF_CRYPTO_ALLOC for MBED TLS memory allocation.
+ */
+static void * mbedtls_backend_calloc(size_t count, size_t size)
+{
+ size_t total_size = count * size;
+ void * p_data = NRF_CRYPTO_ALLOC(total_size);
+ if (p_data != NULL)
+ {
+ memset(p_data, 0, total_size);
+ }
+ return p_data;
+}
+
+
+/** @internal @brief Function to use NRF_CRYPTO_FREE for MBED TLS memory deallocation.
+ */
+static void mbedtls_backend_free(void * p_data)
+{
+ NRF_CRYPTO_FREE(p_data);
+}
+
+
+/** @internal @brief Function to initialize MBED TLS backend - setup memory management for.
+ */
+static ret_code_t mbedtls_backend_init(void)
+{
+ (void)mbedtls_platform_set_calloc_free(mbedtls_backend_calloc, mbedtls_backend_free);
+ return NRF_SUCCESS;
+}
+
+
+/** @internal @brief Function to uninitialize MBED TLS backend - currently no implementation is required.
+ */
+static ret_code_t mbedtls_backend_uninit(void)
+{
+ // Empty implementation
+ return NRF_SUCCESS;
+}
+
+
+CRYPTO_BACKEND_REGISTER(nrf_crypto_backend_info_t const mbedtls_backend) =
+{
+ .init_fn = mbedtls_backend_init,
+ .uninit_fn = mbedtls_backend_uninit,
+};
+
+#endif // NRF_MODULE_ENABLED(NRF_CRYPTO) && NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_MBEDTLS)
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/micro_ecc/micro_ecc_backend_ecc.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/micro_ecc/micro_ecc_backend_ecc.c
new file mode 100644
index 0000000..534d756
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/micro_ecc/micro_ecc_backend_ecc.c
@@ -0,0 +1,352 @@
+/**
+ * Copyright (c) 2018 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+
+#include "sdk_config.h"
+#include "nordic_common.h"
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO) && NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_MICRO_ECC)
+
+#include <stdbool.h>
+#include <string.h>
+#include <stddef.h>
+
+#include "app_util.h"
+#include "nrf_crypto_ecc.h"
+#include "nrf_crypto_rng.h"
+#include "nrf_crypto_shared.h"
+#include "micro_ecc_backend_ecc.h"
+#include "micro_ecc_backend_shared.h"
+#include "uECC.h"
+
+
+typedef uECC_Curve (*micro_ecc_curve_fn_t)(void);
+
+
+int nrf_crypto_backend_micro_ecc_rng_callback(uint8_t * dest, unsigned size)
+{
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_RNG)
+
+ ret_code_t result;
+
+ result = nrf_crypto_rng_vector_generate(dest, size);
+
+ // Return values compatible with mbed TLS
+ if (result != NRF_SUCCESS)
+ {
+ return 0;
+ }
+ return 1;
+
+#else
+ UNUSED_PARAMETER(dest);
+ UNUSED_PARAMETER(size);
+ return 0;
+#endif
+}
+
+
+uECC_Curve nrf_crypto_backend_micro_ecc_curve_get(
+ nrf_crypto_backend_micro_ecc_common_key_t const * p_key)
+{
+ nrf_crypto_internal_ecc_key_header_t const * p_key_header =
+ (nrf_crypto_internal_ecc_key_header_t const *)p_key;
+
+ //lint -save -e611 (Suspicious cast)
+ micro_ecc_curve_fn_t micro_ecc_curve_fn =
+ (micro_ecc_curve_fn_t)p_key_header->p_info->p_backend_data;
+ //lint -restore
+
+ uECC_Curve p_micro_ecc_curve = micro_ecc_curve_fn();
+
+ return p_micro_ecc_curve;
+}
+
+
+ret_code_t nrf_crypto_backend_micro_ecc_key_pair_generate(
+ void * p_context,
+ void * p_private_key,
+ void * p_public_key)
+{
+ int result;
+
+ nrf_crypto_backend_micro_ecc_common_key_t * p_prv =
+ (nrf_crypto_backend_micro_ecc_common_key_t *)p_private_key;
+ nrf_crypto_backend_micro_ecc_common_key_t * p_pub =
+ (nrf_crypto_backend_micro_ecc_common_key_t *)p_public_key;
+
+ uECC_Curve p_micro_ecc_curve = nrf_crypto_backend_micro_ecc_curve_get(p_prv);
+
+ uECC_set_rng(nrf_crypto_backend_micro_ecc_rng_callback);
+
+ result = uECC_make_key((uint8_t *)(&p_pub->key[0]),
+ (uint8_t *)(&p_prv->key[0]),
+ p_micro_ecc_curve);
+
+ if (result == 0)
+ {
+ return NRF_ERROR_CRYPTO_INTERNAL;
+ }
+ return NRF_SUCCESS;
+}
+
+
+ret_code_t nrf_crypto_backend_micro_ecc_public_key_calculate(
+ void * p_context,
+ void const * p_private_key,
+ void * p_public_key)
+{
+ int result;
+
+ nrf_crypto_backend_micro_ecc_common_key_t const * p_prv =
+ (nrf_crypto_backend_micro_ecc_common_key_t const *)p_private_key;
+ nrf_crypto_backend_micro_ecc_common_key_t * p_pub =
+ (nrf_crypto_backend_micro_ecc_common_key_t *)p_public_key;
+
+ uECC_Curve p_micro_ecc_curve = nrf_crypto_backend_micro_ecc_curve_get(p_prv);
+
+ result = uECC_compute_public_key((uint8_t *)(&p_prv->key[0]),
+ (uint8_t *)(&p_pub->key[0]),
+ p_micro_ecc_curve);
+
+ if (result == 0)
+ {
+ return NRF_ERROR_CRYPTO_INTERNAL;
+ }
+ return NRF_SUCCESS;
+}
+
+
+ret_code_t nrf_crypto_backend_micro_ecc_private_key_from_raw(
+ void * p_private_key,
+ uint8_t const * p_raw_data)
+{
+ nrf_crypto_backend_micro_ecc_common_key_t * p_prv =
+ (nrf_crypto_backend_micro_ecc_common_key_t *)p_private_key;
+
+ nrf_crypto_ecc_curve_info_t const * p_info = p_prv->header.p_info;
+
+#if ECC_BACKEND_SWAP_BYTES
+ nrf_crypto_internal_swap_endian((uint8_t *)(&p_prv->key[0]),
+ p_raw_data,
+ p_info->raw_private_key_size);
+#else
+ memcpy(&p_prv->key[0], p_raw_data, p_info->raw_private_key_size);
+#endif
+
+ return NRF_SUCCESS;
+}
+
+
+ret_code_t nrf_crypto_backend_micro_ecc_private_key_to_raw(
+ void const * p_private_key,
+ uint8_t * p_raw_data)
+{
+ nrf_crypto_backend_micro_ecc_common_key_t const * p_prv =
+ (nrf_crypto_backend_micro_ecc_common_key_t const *)p_private_key;
+
+ nrf_crypto_ecc_curve_info_t const * p_info = p_prv->header.p_info;
+
+#if ECC_BACKEND_SWAP_BYTES
+ nrf_crypto_internal_swap_endian(p_raw_data,
+ (uint8_t *)(&p_prv->key[0]),
+ p_info->raw_private_key_size);
+#else
+ memcpy(p_raw_data, &p_prv->key[0], p_info->raw_private_key_size);
+#endif
+
+ return NRF_SUCCESS;
+}
+
+
+ret_code_t nrf_crypto_backend_micro_ecc_public_key_from_raw(
+ void * p_public_key,
+ uint8_t const * p_raw_data)
+{
+ nrf_crypto_backend_micro_ecc_common_key_t * p_pub =
+ (nrf_crypto_backend_micro_ecc_common_key_t *)p_public_key;
+
+ nrf_crypto_ecc_curve_info_t const * p_info = p_pub->header.p_info;
+
+ uECC_Curve p_micro_ecc_curve = nrf_crypto_backend_micro_ecc_curve_get(p_pub);
+
+#if ECC_BACKEND_SWAP_BYTES
+ nrf_crypto_internal_double_swap_endian((uint8_t *)(&p_pub->key[0]),
+ p_raw_data,
+ p_info->raw_private_key_size);
+#else
+ memcpy(&p_pub->key[0], p_raw_data, p_info->raw_public_key_size);
+#endif
+
+#if !NRF_CRYPTO_BACKEND_MICRO_ECC_PUBLIC_KEY_TRUSTED_ENABLED
+ if (!uECC_valid_public_key((uint8_t *)(&p_pub->key[0]), p_micro_ecc_curve))
+ {
+ return NRF_ERROR_CRYPTO_ECC_INVALID_KEY;
+ }
+#else
+ UNUSED_PARAMETER(p_micro_ecc_curve);
+#endif
+
+ return NRF_SUCCESS;
+}
+
+
+ret_code_t nrf_crypto_backend_micro_ecc_public_key_to_raw(
+ void const * p_public_key,
+ uint8_t * p_raw_data)
+{
+ nrf_crypto_backend_micro_ecc_common_key_t const * p_pub =
+ (nrf_crypto_backend_micro_ecc_common_key_t const *)p_public_key;
+
+ nrf_crypto_ecc_curve_info_t const * p_info = p_pub->header.p_info;
+
+#if ECC_BACKEND_SWAP_BYTES
+ nrf_crypto_internal_double_swap_endian(p_raw_data,
+ (uint8_t *)(&p_pub->key[0]),
+ p_info->raw_private_key_size);
+#else
+ memcpy(p_raw_data, &p_pub->key[0], p_info->raw_public_key_size);
+#endif
+
+ return NRF_SUCCESS;
+}
+
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_MICRO_ECC_ECC_SECP192R1)
+
+// Make sure that common key structure match secp192r1 (NIST 192-bit) key structure to safely cast types.
+STATIC_ASSERT(offsetof(nrf_crypto_backend_micro_ecc_common_key_t, key) ==
+ offsetof(nrf_crypto_backend_secp192r1_private_key_t, key),
+ "Common uECC private key structure does not match secp192r1 (NIST 192-bit) one.");
+STATIC_ASSERT(offsetof(nrf_crypto_backend_micro_ecc_common_key_t, key) ==
+ offsetof(nrf_crypto_backend_secp192r1_public_key_t, key),
+ "Common ECC public key structure does not match secp192r1 (NIST 192-bit) one.");
+
+const nrf_crypto_ecc_curve_info_t g_nrf_crypto_ecc_secp192r1_curve_info =
+{
+ .public_key_size = sizeof(nrf_crypto_backend_secp192r1_private_key_t),
+ .private_key_size = sizeof(nrf_crypto_backend_secp192r1_public_key_t),
+ .curve_type = NRF_CRYPTO_ECC_SECP192R1_CURVE_TYPE,
+ .raw_private_key_size = NRF_CRYPTO_ECC_SECP192R1_RAW_PRIVATE_KEY_SIZE,
+ .raw_public_key_size = NRF_CRYPTO_ECC_SECP192R1_RAW_PUBLIC_KEY_SIZE,
+ //lint -save -e611 -e546 (Suspicious cast, Suspicious use of &)
+ .p_backend_data = (void *)&uECC_secp192r1,
+ //lint -restore
+};
+
+#endif
+
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_MICRO_ECC_ECC_SECP224R1)
+
+// Make sure that common key structure match secp224r1 (NIST 224-bit) key structure to safely cast types.
+STATIC_ASSERT(offsetof(nrf_crypto_backend_micro_ecc_common_key_t, key) ==
+ offsetof(nrf_crypto_backend_secp224r1_private_key_t, key),
+ "Common uECC private key structure does not match secp224r1 (NIST 224-bit) one.");
+STATIC_ASSERT(offsetof(nrf_crypto_backend_micro_ecc_common_key_t, key) ==
+ offsetof(nrf_crypto_backend_secp224r1_public_key_t, key),
+ "Common ECC public key structure does not match secp224r1 (NIST 224-bit) one.");
+
+const nrf_crypto_ecc_curve_info_t g_nrf_crypto_ecc_secp224r1_curve_info =
+{
+ .public_key_size = sizeof(nrf_crypto_backend_secp224r1_private_key_t),
+ .private_key_size = sizeof(nrf_crypto_backend_secp224r1_public_key_t),
+ .curve_type = NRF_CRYPTO_ECC_SECP224R1_CURVE_TYPE,
+ .raw_private_key_size = NRF_CRYPTO_ECC_SECP224R1_RAW_PRIVATE_KEY_SIZE,
+ .raw_public_key_size = NRF_CRYPTO_ECC_SECP224R1_RAW_PUBLIC_KEY_SIZE,
+ //lint -save -e611 -e546 (Suspicious cast, Suspicious use of &)
+ .p_backend_data = (void *)&uECC_secp224r1,
+ //lint -restore
+};
+
+#endif
+
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_MICRO_ECC_ECC_SECP256R1)
+
+// Make sure that common key structure match secp256r1 (NIST 256-bit) key structure to safely cast types.
+STATIC_ASSERT(offsetof(nrf_crypto_backend_micro_ecc_common_key_t, key) ==
+ offsetof(nrf_crypto_backend_secp256r1_private_key_t, key),
+ "Common uECC private key structure does not match secp256r1 (NIST 256-bit) one.");
+STATIC_ASSERT(offsetof(nrf_crypto_backend_micro_ecc_common_key_t, key) ==
+ offsetof(nrf_crypto_backend_secp256r1_public_key_t, key),
+ "Common ECC public key structure does not match secp256r1 (NIST 256-bit) one.");
+
+const nrf_crypto_ecc_curve_info_t g_nrf_crypto_ecc_secp256r1_curve_info =
+{
+ .public_key_size = sizeof(nrf_crypto_backend_secp256r1_private_key_t),
+ .private_key_size = sizeof(nrf_crypto_backend_secp256r1_public_key_t),
+ .curve_type = NRF_CRYPTO_ECC_SECP256R1_CURVE_TYPE,
+ .raw_private_key_size = NRF_CRYPTO_ECC_SECP256R1_RAW_PRIVATE_KEY_SIZE,
+ .raw_public_key_size = NRF_CRYPTO_ECC_SECP256R1_RAW_PUBLIC_KEY_SIZE,
+ //lint -save -e611 -e546 (Suspicious cast, Suspicious use of &)
+ .p_backend_data = (void *)&uECC_secp256r1,
+ //lint -restore
+};
+
+#endif
+
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_MICRO_ECC_ECC_SECP256K1)
+
+// Make sure that common key structure match secp256k1 (Koblitz 256-bit) key structure to safely cast types.
+STATIC_ASSERT(offsetof(nrf_crypto_backend_micro_ecc_common_key_t, key) ==
+ offsetof(nrf_crypto_backend_secp256k1_private_key_t, key),
+ "Common uECC private key structure does not match secp256k1 (Koblitz 256-bit) one.");
+STATIC_ASSERT(offsetof(nrf_crypto_backend_micro_ecc_common_key_t, key) ==
+ offsetof(nrf_crypto_backend_secp256k1_public_key_t, key),
+ "Common ECC public key structure does not match secp256k1 (Koblitz 256-bit) one.");
+
+
+const nrf_crypto_ecc_curve_info_t g_nrf_crypto_ecc_secp256k1_curve_info =
+{
+ .public_key_size = sizeof(nrf_crypto_backend_secp256k1_private_key_t),
+ .private_key_size = sizeof(nrf_crypto_backend_secp256k1_public_key_t),
+ .curve_type = NRF_CRYPTO_ECC_SECP256K1_CURVE_TYPE,
+ .raw_private_key_size = NRF_CRYPTO_ECC_SECP256K1_RAW_PRIVATE_KEY_SIZE,
+ .raw_public_key_size = NRF_CRYPTO_ECC_SECP256K1_RAW_PUBLIC_KEY_SIZE,
+ //lint -save -e611 -e546 (Suspicious cast, Suspicious use of &)
+ .p_backend_data = (void *)&uECC_secp256k1,
+ //lint -restore
+};
+
+#endif
+
+
+#endif // NRF_MODULE_ENABLED(NRF_CRYPTO) && NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_MICRO_ECC)
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/micro_ecc/micro_ecc_backend_ecc.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/micro_ecc/micro_ecc_backend_ecc.h
new file mode 100644
index 0000000..cafa506
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/micro_ecc/micro_ecc_backend_ecc.h
@@ -0,0 +1,303 @@
+/**
+ * Copyright (c) 2018 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+
+#ifndef MICRO_ECC_BACKEND_ECC_H__
+#define MICRO_ECC_BACKEND_ECC_H__
+
+#include "sdk_config.h"
+#include "nordic_common.h"
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO) && NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_MICRO_ECC)
+
+#include <stdint.h>
+#include <stdbool.h>
+#include "nrf_crypto_ecc_shared.h"
+#include "uECC.h"
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+/** @internal See @ref nrf_crypto_backend_ecc_key_pair_generate_fn_t.
+ */
+ret_code_t nrf_crypto_backend_micro_ecc_key_pair_generate(
+ void * p_context,
+ void * p_private_key,
+ void * p_public_key);
+
+
+/** @internal See @ref nrf_crypto_backend_ecc_public_key_calculate_fn_t.
+*/
+ret_code_t nrf_crypto_backend_micro_ecc_public_key_calculate(
+ void * p_context,
+ void const * p_private_key,
+ void * p_public_key);
+
+
+/** @internal See @ref nrf_crypto_backend_ecc_private_key_from_raw_fn_t.
+*/
+ret_code_t nrf_crypto_backend_micro_ecc_private_key_from_raw(
+ void * p_private_key,
+ uint8_t const * p_raw_data);
+
+
+/** @internal See @ref nrf_crypto_backend_ecc_private_key_to_raw_fn_t.
+*/
+ret_code_t nrf_crypto_backend_micro_ecc_private_key_to_raw(
+ void const * p_private_key,
+ uint8_t * p_raw_data);
+
+
+/** @internal See @ref nrf_crypto_backend_ecc_public_key_from_raw_fn_t.
+*/
+ret_code_t nrf_crypto_backend_micro_ecc_public_key_from_raw(
+ void * p_public_key,
+ uint8_t const * p_raw_data);
+
+
+/** @internal See @ref nrf_crypto_backend_ecc_public_key_to_raw_fn_t.
+*/
+ret_code_t nrf_crypto_backend_micro_ecc_public_key_to_raw(
+ void const * p_public_key,
+ uint8_t * p_raw_data);
+
+
+/** @internal @brief Represents common uECC backend key structure.
+ */
+typedef struct
+{
+ nrf_crypto_internal_ecc_key_header_t header; /**< @internal @brief Common ECC key header */
+ uint32_t key[1]; /**< @internal @brief micro-ecc specific key representation */
+} nrf_crypto_backend_micro_ecc_common_key_t;
+
+
+/** @internal @brief Callback RNG function that can be provided to uECC API.
+ * @param dest Destination buffer.
+ * @param size Size of the buffer.
+ * @return 1 on success, 0 on error.
+ */
+int nrf_crypto_backend_micro_ecc_rng_callback(uint8_t * dest, unsigned size);
+
+
+/** @internal @brief Gets uECC type based on provided key.
+ * @param p_key uECC backend key (public or private).
+ * @return uECC specific value representing a curve.
+ */
+uECC_Curve nrf_crypto_backend_micro_ecc_curve_get(
+ nrf_crypto_backend_micro_ecc_common_key_t const * p_key);
+
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_MICRO_ECC_ECC_SECP192R1)
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_ECC_SECP192R1)
+#error "More than one backend enabled for secp192r1 (NIST 192-bit).");
+#endif
+#define NRF_CRYPTO_ECC_SECP192R1_ENABLED 1
+
+/** @internal @brief Structure holding private key for secp192r1 (NIST 192-bit) in micro-ecc.
+ */
+typedef struct
+{
+ nrf_crypto_internal_ecc_key_header_t header; /**< @internal @brief Common ECC key header */
+ uint32_t key[192 / 32]; /**< @internal @brief micro-ecc specific key representation */
+} nrf_crypto_backend_secp192r1_private_key_t;
+
+/** @internal @brief Structure holding public key for secp192r1 (NIST 192-bit) in micro-ecc.
+ */
+typedef struct
+{
+ nrf_crypto_internal_ecc_key_header_t header; /**< @internal @brief Common ECC key header */
+ uint32_t key[2 * 192 / 32]; /**< @internal @brief micro-ecc specific key representation */
+} nrf_crypto_backend_secp192r1_public_key_t;
+
+// Aliases for one common micro-ecc implementation
+#define nrf_crypto_backend_secp192r1_key_pair_generate nrf_crypto_backend_micro_ecc_key_pair_generate
+#define nrf_crypto_backend_secp192r1_public_key_calculate nrf_crypto_backend_micro_ecc_public_key_calculate
+#define nrf_crypto_backend_secp192r1_private_key_from_raw nrf_crypto_backend_micro_ecc_private_key_from_raw
+#define nrf_crypto_backend_secp192r1_private_key_to_raw nrf_crypto_backend_micro_ecc_private_key_to_raw
+#define nrf_crypto_backend_secp192r1_public_key_from_raw nrf_crypto_backend_micro_ecc_public_key_from_raw
+#define nrf_crypto_backend_secp192r1_public_key_to_raw nrf_crypto_backend_micro_ecc_public_key_to_raw
+#define nrf_crypto_backend_secp192r1_private_key_free NULL
+#define nrf_crypto_backend_secp192r1_public_key_free NULL
+#define NRF_CRYPTO_BACKEND_SECP192R1_KEY_PAIR_GENERATE_CONTEXT_SIZE 0
+#define NRF_CRYPTO_BACKEND_SECP192R1_PUBLIC_KEY_CALCULATE_CONTEXT_SIZE 0
+
+// Dummy typedef for unused context
+typedef uint32_t nrf_crypto_backend_secp192r1_key_pair_generate_context_t;
+typedef uint32_t nrf_crypto_backend_secp192r1_public_key_calculate_context_t;
+
+#endif // NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_MICRO_ECC_ECC_SECP192R1)
+
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_MICRO_ECC_ECC_SECP224R1)
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_ECC_SECP224R1)
+#error "More than one backend enabled for secp224r1 (NIST 224-bit).");
+#endif
+#define NRF_CRYPTO_ECC_SECP224R1_ENABLED 1
+
+/** @internal @brief Structure holding private key for secp224r1 (NIST 224-bit) in micro-ecc.
+ */
+typedef struct
+{
+ nrf_crypto_internal_ecc_key_header_t header; /**< @internal @brief Common ECC key header */
+ uint32_t key[224 / 32]; /**< @internal @brief micro-ecc specific key representation */
+} nrf_crypto_backend_secp224r1_private_key_t;
+
+/** @internal @brief Structure holding public key for secp224r1 (NIST 224-bit) in micro-ecc.
+ */
+typedef struct
+{
+ nrf_crypto_internal_ecc_key_header_t header; /**< @internal @brief Common ECC key header */
+ uint32_t key[2 * 224 / 32]; /**< @internal @brief micro-ecc specific key representation */
+} nrf_crypto_backend_secp224r1_public_key_t;
+
+// Aliases for one common micro-ecc implementation
+#define nrf_crypto_backend_secp224r1_key_pair_generate nrf_crypto_backend_micro_ecc_key_pair_generate
+#define nrf_crypto_backend_secp224r1_public_key_calculate nrf_crypto_backend_micro_ecc_public_key_calculate
+#define nrf_crypto_backend_secp224r1_private_key_from_raw nrf_crypto_backend_micro_ecc_private_key_from_raw
+#define nrf_crypto_backend_secp224r1_private_key_to_raw nrf_crypto_backend_micro_ecc_private_key_to_raw
+#define nrf_crypto_backend_secp224r1_public_key_from_raw nrf_crypto_backend_micro_ecc_public_key_from_raw
+#define nrf_crypto_backend_secp224r1_public_key_to_raw nrf_crypto_backend_micro_ecc_public_key_to_raw
+#define nrf_crypto_backend_secp224r1_private_key_free NULL
+#define nrf_crypto_backend_secp224r1_public_key_free NULL
+#define NRF_CRYPTO_BACKEND_SECP224R1_KEY_PAIR_GENERATE_CONTEXT_SIZE 0
+#define NRF_CRYPTO_BACKEND_SECP224R1_PUBLIC_KEY_CALCULATE_CONTEXT_SIZE 0
+
+// Dummy typedef for unused context
+typedef uint32_t nrf_crypto_backend_secp224r1_key_pair_generate_context_t;
+typedef uint32_t nrf_crypto_backend_secp224r1_public_key_calculate_context_t;
+
+#endif // NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_MICRO_ECC_ECC_SECP224R1)
+
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_MICRO_ECC_ECC_SECP256R1)
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_ECC_SECP256R1)
+#error "More than one backend enabled for secp256r1 (NIST 256-bit).");
+#endif
+#define NRF_CRYPTO_ECC_SECP256R1_ENABLED 1
+
+/** @internal @brief Structure holding private key for secp256r1 (NIST 256-bit) in micro-ecc.
+ */
+typedef struct
+{
+ nrf_crypto_internal_ecc_key_header_t header; /**< @internal @brief Common ECC key header */
+ uint32_t key[256 / 32]; /**< @internal @brief micro-ecc specific key representation */
+} nrf_crypto_backend_secp256r1_private_key_t;
+
+/** @internal @brief Structure holding public key for secp256r1 (NIST 256-bit) in micro-ecc.
+ */
+typedef struct
+{
+ nrf_crypto_internal_ecc_key_header_t header; /**< @internal @brief Common ECC key header */
+ uint32_t key[2 * 256 / 32]; /**< @internal @brief micro-ecc specific key representation */
+} nrf_crypto_backend_secp256r1_public_key_t;
+
+// Aliases for one common micro-ecc implementation
+#define nrf_crypto_backend_secp256r1_key_pair_generate nrf_crypto_backend_micro_ecc_key_pair_generate
+#define nrf_crypto_backend_secp256r1_public_key_calculate nrf_crypto_backend_micro_ecc_public_key_calculate
+#define nrf_crypto_backend_secp256r1_private_key_from_raw nrf_crypto_backend_micro_ecc_private_key_from_raw
+#define nrf_crypto_backend_secp256r1_private_key_to_raw nrf_crypto_backend_micro_ecc_private_key_to_raw
+#define nrf_crypto_backend_secp256r1_public_key_from_raw nrf_crypto_backend_micro_ecc_public_key_from_raw
+#define nrf_crypto_backend_secp256r1_public_key_to_raw nrf_crypto_backend_micro_ecc_public_key_to_raw
+#define nrf_crypto_backend_secp256r1_private_key_free NULL
+#define nrf_crypto_backend_secp256r1_public_key_free NULL
+#define NRF_CRYPTO_BACKEND_SECP256R1_KEY_PAIR_GENERATE_CONTEXT_SIZE 0
+#define NRF_CRYPTO_BACKEND_SECP256R1_PUBLIC_KEY_CALCULATE_CONTEXT_SIZE 0
+
+// Dummy typedef for unused context
+typedef uint32_t nrf_crypto_backend_secp256r1_key_pair_generate_context_t;
+typedef uint32_t nrf_crypto_backend_secp256r1_public_key_calculate_context_t;
+
+#endif // NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_MICRO_ECC_ECC_SECP256R1)
+
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_MICRO_ECC_ECC_SECP256K1)
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_ECC_SECP256K1)
+#error "More than one backend enabled for secp256k1 (Koblitz 256-bit).");
+#endif
+#define NRF_CRYPTO_ECC_SECP256K1_ENABLED 1
+
+/** @internal @brief Structure holding private key for secp256k1 (Koblitz 256-bit) in micro-ecc.
+ */
+typedef struct
+{
+ nrf_crypto_internal_ecc_key_header_t header; /**< @internal @brief Common ECC key header */
+ uint32_t key[256 / 32]; /**< @internal @brief micro-ecc specific key representation */
+} nrf_crypto_backend_secp256k1_private_key_t;
+
+/** @internal @brief Structure holding public key for secp256k1 (Koblitz 256-bit) in micro-ecc.
+ */
+typedef struct
+{
+ nrf_crypto_internal_ecc_key_header_t header; /**< @internal @brief Common ECC key header */
+ uint32_t key[2 * 256 / 32]; /**< @internal @brief micro-ecc specific key representation */
+} nrf_crypto_backend_secp256k1_public_key_t;
+
+// Aliases for one common micro-ecc implementation
+#define nrf_crypto_backend_secp256k1_key_pair_generate nrf_crypto_backend_micro_ecc_key_pair_generate
+#define nrf_crypto_backend_secp256k1_public_key_calculate nrf_crypto_backend_micro_ecc_public_key_calculate
+#define nrf_crypto_backend_secp256k1_private_key_from_raw nrf_crypto_backend_micro_ecc_private_key_from_raw
+#define nrf_crypto_backend_secp256k1_private_key_to_raw nrf_crypto_backend_micro_ecc_private_key_to_raw
+#define nrf_crypto_backend_secp256k1_public_key_from_raw nrf_crypto_backend_micro_ecc_public_key_from_raw
+#define nrf_crypto_backend_secp256k1_public_key_to_raw nrf_crypto_backend_micro_ecc_public_key_to_raw
+#define nrf_crypto_backend_secp256k1_private_key_free NULL
+#define nrf_crypto_backend_secp256k1_public_key_free NULL
+#define NRF_CRYPTO_BACKEND_SECP256K1_KEY_PAIR_GENERATE_CONTEXT_SIZE 0
+#define NRF_CRYPTO_BACKEND_SECP256K1_PUBLIC_KEY_CALCULATE_CONTEXT_SIZE 0
+
+// Dummy typedef for unused context
+typedef uint32_t nrf_crypto_backend_secp256k1_key_pair_generate_context_t;
+typedef uint32_t nrf_crypto_backend_secp256k1_public_key_calculate_context_t;
+
+#endif // NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_MICRO_ECC_ECC_SECP256K1)
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // NRF_MODULE_ENABLED(NRF_CRYPTO) && NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_MICRO_ECC)
+
+#endif // MICRO_ECC_BACKEND_ECC_H__
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/micro_ecc/micro_ecc_backend_ecdh.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/micro_ecc/micro_ecc_backend_ecdh.c
new file mode 100644
index 0000000..a63307e
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/micro_ecc/micro_ecc_backend_ecdh.c
@@ -0,0 +1,93 @@
+/**
+ * Copyright (c) 2018 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+
+#include "sdk_config.h"
+#include "nordic_common.h"
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO) && NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_MICRO_ECC)
+
+#include <string.h>
+
+#include "nrf_crypto_ecc_shared.h"
+#include "nrf_crypto_ecdh_shared.h"
+#include "nrf_crypto_ecdh.h"
+#include "nrf_crypto_shared.h"
+#include "micro_ecc_backend_ecc.h"
+#include "micro_ecc_backend_shared.h"
+#include "uECC.h"
+
+
+ret_code_t nrf_crypto_backend_micro_ecc_ecdh_compute(
+ void * p_context,
+ void const * p_private_key,
+ void const * p_public_key,
+ uint8_t * p_shared_secret)
+{
+ int result;
+
+ nrf_crypto_backend_micro_ecc_common_key_t const * p_prv =
+ (nrf_crypto_backend_micro_ecc_common_key_t const *)p_private_key;
+ nrf_crypto_backend_micro_ecc_common_key_t const * p_pub =
+ (nrf_crypto_backend_micro_ecc_common_key_t const *)p_public_key;
+
+ nrf_crypto_ecc_curve_info_t const * p_info = p_prv->header.p_info;
+
+ uECC_Curve p_micro_ecc_curve = nrf_crypto_backend_micro_ecc_curve_get(p_prv);
+
+ result = uECC_shared_secret((uint8_t const *)(&p_pub->key[0]),
+ (uint8_t const *)(&p_prv->key[0]),
+ p_shared_secret,
+ p_micro_ecc_curve);
+
+#if ECC_BACKEND_SWAP_BYTES
+ nrf_crypto_internal_swap_endian_in_place(p_shared_secret, p_info->raw_private_key_size);
+#else
+ UNUSED_PARAMETER(p_info);
+#endif
+
+ if (result == 0)
+ {
+ return NRF_ERROR_CRYPTO_INTERNAL;
+ }
+ return NRF_SUCCESS;
+}
+
+
+#endif // NRF_MODULE_ENABLED(NRF_CRYPTO) && NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_MICRO_ECC)
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/micro_ecc/micro_ecc_backend_ecdh.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/micro_ecc/micro_ecc_backend_ecdh.h
new file mode 100644
index 0000000..cdf366b
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/micro_ecc/micro_ecc_backend_ecdh.h
@@ -0,0 +1,105 @@
+/**
+ * Copyright (c) 2018 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+
+#ifndef MICRO_ECC_BACKEND_ECDH_H__
+#define MICRO_ECC_BACKEND_ECDH_H__
+
+#include "sdk_config.h"
+#include "nordic_common.h"
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO) && NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_MICRO_ECC)
+
+#include "nrf_crypto_ecc.h"
+#include "nrf_crypto_ecdh_shared.h"
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+/** @internal See @ref nrf_crypto_backend_ecdh_compute_fn_t.
+ */
+ret_code_t nrf_crypto_backend_micro_ecc_ecdh_compute(
+ void * p_context,
+ void const * p_private_key,
+ void const * p_public_key,
+ uint8_t * p_shared_secret);
+
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_MICRO_ECC_ECC_SECP192R1)
+// Aliases for one common MICRO_ECC implementation
+#define nrf_crypto_backend_secp192r1_ecdh_compute nrf_crypto_backend_micro_ecc_ecdh_compute
+typedef uint32_t nrf_crypto_backend_secp192r1_ecdh_context_t;
+#define NRF_CRYPTO_BACKEND_SECP192R1_ECDH_CONTEXT_SIZE 0
+#endif // NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_MICRO_ECC_ECC_SECP192R1)
+
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_MICRO_ECC_ECC_SECP224R1)
+// Aliases for one common MICRO_ECC implementation
+#define nrf_crypto_backend_secp224r1_ecdh_compute nrf_crypto_backend_micro_ecc_ecdh_compute
+typedef uint32_t nrf_crypto_backend_secp224r1_ecdh_context_t;
+#define NRF_CRYPTO_BACKEND_SECP224R1_ECDH_CONTEXT_SIZE 0
+#endif // NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_MICRO_ECC_ECC_SECP224R1)
+
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_MICRO_ECC_ECC_SECP256R1)
+// Aliases for one common MICRO_ECC implementation
+#define nrf_crypto_backend_secp256r1_ecdh_compute nrf_crypto_backend_micro_ecc_ecdh_compute
+typedef uint32_t nrf_crypto_backend_secp256r1_ecdh_context_t;
+#define NRF_CRYPTO_BACKEND_SECP256R1_ECDH_CONTEXT_SIZE 0
+#endif // NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_MICRO_ECC_ECC_SECP256R1)
+
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_MICRO_ECC_ECC_SECP256K1)
+// Aliases for one common MICRO_ECC implementation
+#define nrf_crypto_backend_secp256k1_ecdh_compute nrf_crypto_backend_micro_ecc_ecdh_compute
+typedef uint32_t nrf_crypto_backend_secp256k1_ecdh_context_t;
+#define NRF_CRYPTO_BACKEND_SECP256K1_ECDH_CONTEXT_SIZE 0
+#endif // NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_MICRO_ECC_ECC_SECP256K1)
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // NRF_MODULE_ENABLED(NRF_CRYPTO) && NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_MICRO_ECC)
+
+#endif // MICRO_ECC_BACKEND_ECDH_H__
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/micro_ecc/micro_ecc_backend_ecdsa.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/micro_ecc/micro_ecc_backend_ecdsa.c
new file mode 100644
index 0000000..f72e6dc
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/micro_ecc/micro_ecc_backend_ecdsa.c
@@ -0,0 +1,166 @@
+/**
+ * Copyright (c) 2018 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+
+#include "sdk_config.h"
+#include "nordic_common.h"
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO) && NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_MICRO_ECC)
+
+#include <stdint.h>
+#include <stdbool.h>
+#include <string.h>
+
+#include "nrf_crypto_ecc.h"
+#include "nrf_crypto_ecdsa.h"
+#include "nrf_crypto_shared.h"
+#include "nrf_crypto_mem.h"
+#include "micro_ecc_backend_ecc.h"
+#include "micro_ecc_backend_shared.h"
+#include "uECC.h"
+
+
+ret_code_t nrf_crypto_backend_micro_ecc_sign(
+ void * p_context,
+ void const * p_private_key,
+ uint8_t const * p_data,
+ size_t data_size,
+ uint8_t * p_signature)
+{
+ int result;
+
+ nrf_crypto_backend_micro_ecc_common_key_t const * p_prv =
+ (nrf_crypto_backend_micro_ecc_common_key_t const *)p_private_key;
+
+ uECC_Curve p_micro_ecc_curve = nrf_crypto_backend_micro_ecc_curve_get(p_prv);
+
+#if ECC_BACKEND_SWAP_BYTES
+
+ nrf_crypto_ecc_curve_info_t const * p_info = p_prv->header.p_info;
+
+ size_t hash_size = MIN(data_size, p_info->raw_private_key_size);
+ uint8_t hash_le[NRF_CRYPTO_ECC_RAW_PRIVATE_KEY_MAX_SIZE];
+
+ nrf_crypto_internal_swap_endian(hash_le, p_data, hash_size);
+
+ uECC_set_rng(nrf_crypto_backend_micro_ecc_rng_callback);
+
+ result = uECC_sign((uint8_t const *)(&p_prv->key[0]),
+ hash_le,
+ hash_size,
+ p_signature,
+ p_micro_ecc_curve);
+
+ nrf_crypto_internal_double_swap_endian_in_place(p_signature, p_info->raw_private_key_size);
+
+#else
+
+ uECC_set_rng(nrf_crypto_backend_micro_ecc_rng_callback);
+
+ result = uECC_sign((uint8_t const *)(&p_prv->key[0]),
+ p_data,
+ data_size,
+ p_signature,
+ p_micro_ecc_curve);
+
+#endif
+
+ if (result == 0)
+ {
+ return NRF_ERROR_CRYPTO_INTERNAL;
+ }
+ return NRF_SUCCESS;
+}
+
+
+ret_code_t nrf_crypto_backend_micro_ecc_verify(
+ void * p_context,
+ void const * p_public_key,
+ uint8_t const * p_data,
+ size_t data_size,
+ uint8_t const * p_signature)
+{
+ int result;
+
+ nrf_crypto_backend_micro_ecc_common_key_t const * p_pub =
+ (nrf_crypto_backend_micro_ecc_common_key_t const *)p_public_key;
+
+ uECC_Curve p_micro_ecc_curve = nrf_crypto_backend_micro_ecc_curve_get(p_pub);
+
+#if ECC_BACKEND_SWAP_BYTES
+
+ nrf_crypto_ecc_curve_info_t const * p_info = p_pub->header.p_info;
+
+ size_t hash_size = MIN(data_size, p_info->raw_private_key_size);
+ uint8_t hash_le [NRF_CRYPTO_ECC_RAW_PRIVATE_KEY_MAX_SIZE];
+ uint8_t signature_le[NRF_CRYPTO_ECDSA_SIGNATURE_MAX_SIZE];
+
+ nrf_crypto_internal_swap_endian(hash_le, p_data, hash_size);
+
+ nrf_crypto_internal_double_swap_endian(signature_le,
+ p_signature,
+ p_info->raw_private_key_size);
+
+ result = uECC_verify((uint8_t const *)(&p_pub->key[0]),
+ hash_le,
+ hash_size,
+ signature_le,
+ p_micro_ecc_curve);
+
+#else
+
+ result = uECC_verify((uint8_t const *)(&p_pub->key[0]),
+ p_data,
+ data_size,
+ p_signature,
+ p_micro_ecc_curve);
+
+#endif
+
+ if (result == 0)
+ {
+ return NRF_ERROR_CRYPTO_ECDSA_INVALID_SIGNATURE;
+ }
+
+ return NRF_SUCCESS;
+}
+
+
+#endif // NRF_MODULE_ENABLED(NRF_CRYPTO) && NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_MICRO_ECC)
+
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/micro_ecc/micro_ecc_backend_ecdsa.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/micro_ecc/micro_ecc_backend_ecdsa.h
new file mode 100644
index 0000000..a52d193
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/micro_ecc/micro_ecc_backend_ecdsa.h
@@ -0,0 +1,124 @@
+/**
+ * Copyright (c) 2018 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+
+#ifndef MICRO_ECC_BACKEND_ECDSA_H__
+#define MICRO_ECC_BACKEND_ECDSA_H__
+
+#include "sdk_config.h"
+#include "nordic_common.h"
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO) && NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_MICRO_ECC)
+
+#include "nrf_crypto_ecc_shared.h"
+#include "nrf_crypto_ecdsa_shared.h"
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+/** @internal See @ref nrf_crypto_backend_ecdsa_sign_fn_t.
+ */
+ret_code_t nrf_crypto_backend_micro_ecc_sign(
+ void * p_context,
+ void const * p_private_key,
+ uint8_t const * p_data,
+ size_t data_size,
+ uint8_t * p_signature);
+
+
+/** @internal See @ref nrf_crypto_backend_ecdsa_verify_fn_t.
+ */
+ret_code_t nrf_crypto_backend_micro_ecc_verify(
+ void * p_context,
+ void const * p_public_key,
+ uint8_t const * p_data,
+ size_t data_size,
+ uint8_t const * p_signature);
+
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_MICRO_ECC_ECC_SECP192R1)
+#define NRF_CRYPTO_BACKEND_SECP192R1_SIGN_CONTEXT_SIZE 0
+#define NRF_CRYPTO_BACKEND_SECP192R1_VERIFY_CONTEXT_SIZE 0
+typedef uint32_t nrf_crypto_backend_secp192r1_sign_context_t;
+typedef uint32_t nrf_crypto_backend_secp192r1_verify_context_t;
+#define nrf_crypto_backend_secp192r1_sign nrf_crypto_backend_micro_ecc_sign
+#define nrf_crypto_backend_secp192r1_verify nrf_crypto_backend_micro_ecc_verify
+#endif
+
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_MICRO_ECC_ECC_SECP224R1)
+#define NRF_CRYPTO_BACKEND_SECP224R1_SIGN_CONTEXT_SIZE 0
+#define NRF_CRYPTO_BACKEND_SECP224R1_VERIFY_CONTEXT_SIZE 0
+typedef uint32_t nrf_crypto_backend_secp224r1_sign_context_t;
+typedef uint32_t nrf_crypto_backend_secp224r1_verify_context_t;
+#define nrf_crypto_backend_secp224r1_sign nrf_crypto_backend_micro_ecc_sign
+#define nrf_crypto_backend_secp224r1_verify nrf_crypto_backend_micro_ecc_verify
+#endif
+
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_MICRO_ECC_ECC_SECP256R1)
+#define NRF_CRYPTO_BACKEND_SECP256R1_SIGN_CONTEXT_SIZE 0
+#define NRF_CRYPTO_BACKEND_SECP256R1_VERIFY_CONTEXT_SIZE 0
+typedef uint32_t nrf_crypto_backend_secp256r1_sign_context_t;
+typedef uint32_t nrf_crypto_backend_secp256r1_verify_context_t;
+#define nrf_crypto_backend_secp256r1_sign nrf_crypto_backend_micro_ecc_sign
+#define nrf_crypto_backend_secp256r1_verify nrf_crypto_backend_micro_ecc_verify
+#endif
+
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_MICRO_ECC_ECC_SECP256K1)
+#define NRF_CRYPTO_BACKEND_SECP256K1_SIGN_CONTEXT_SIZE 0
+#define NRF_CRYPTO_BACKEND_SECP256K1_VERIFY_CONTEXT_SIZE 0
+typedef uint32_t nrf_crypto_backend_secp256k1_sign_context_t;
+typedef uint32_t nrf_crypto_backend_secp256k1_verify_context_t;
+#define nrf_crypto_backend_secp256k1_sign nrf_crypto_backend_micro_ecc_sign
+#define nrf_crypto_backend_secp256k1_verify nrf_crypto_backend_micro_ecc_verify
+#endif
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // NRF_MODULE_ENABLED(NRF_CRYPTO) && NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_MICRO_ECC)
+
+#endif // MICRO_ECC_BACKEND_ECDSA_H__
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/micro_ecc/micro_ecc_backend_shared.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/micro_ecc/micro_ecc_backend_shared.h
new file mode 100644
index 0000000..019f280
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/micro_ecc/micro_ecc_backend_shared.h
@@ -0,0 +1,67 @@
+/**
+ * Copyright (c) 2018 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#ifndef MICRO_ECC_BACKEND_SHARED_H__
+#define MICRO_ECC_BACKEND_SHARED_H__
+
+#include "sdk_config.h"
+#include "nordic_common.h"
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO) && NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_MICRO_ECC)
+
+#include "uECC.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_MICRO_ECC_LITTLE_ENDIAN)
+#define ECC_BACKEND_SWAP_BYTES (!uECC_VLI_NATIVE_LITTLE_ENDIAN)
+#else
+#define ECC_BACKEND_SWAP_BYTES uECC_VLI_NATIVE_LITTLE_ENDIAN
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // NRF_MODULE_ENABLED(NRF_CRYPTO) && NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_MICRO_ECC)
+
+#endif // MICRO_ECC_BACKEND_ECDSA_H__
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/nrf_hw/nrf_hw_backend_init.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/nrf_hw/nrf_hw_backend_init.c
new file mode 100644
index 0000000..d202f35
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/nrf_hw/nrf_hw_backend_init.c
@@ -0,0 +1,95 @@
+/**
+ * Copyright (c) 2018 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+
+#include "sdk_common.h"
+#if NRF_MODULE_ENABLED(NRF_CRYPTO) && NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_NRF_HW_RNG)
+
+#include "nrf.h"
+#include "nrf_crypto_init.h"
+#include "nrf_crypto_rng.h"
+
+
+static ret_code_t nrf_hw_backend_init(void)
+{
+#if defined(NRF_CRYPTO_RNG_AUTO_INIT_ENABLED) && (NRF_CRYPTO_RNG_AUTO_INIT_ENABLED == 1)
+
+ uint32_t ret_val;
+ ret_val = nrf_crypto_rng_init(NULL, NULL);
+ return ret_val;
+
+#elif defined(NRF_CRYPTO_RNG_AUTO_INIT_ENABLED) && (NRF_CRYPTO_RNG_AUTO_INIT_ENABLED == 0)
+
+ return NRF_SUCCESS;
+
+#else
+
+ #warning NRF_CRYPTO_RNG_AUTO_INIT_ENABLED define not found in sdk_config.h (Is the sdk_config.h valid?).
+
+#endif // NRF_CRYPTO_RNG_AUTO_INIT_ENABLED
+}
+
+
+static ret_code_t nrf_hw_backend_uninit(void)
+{
+#if defined(NRF_CRYPTO_RNG_AUTO_INIT_ENABLED) && (NRF_CRYPTO_RNG_AUTO_INIT_ENABLED == 1)
+
+ uint32_t ret_val;
+ ret_val = nrf_crypto_rng_uninit();
+ return ret_val;
+
+#elif defined(NRF_CRYPTO_RNG_AUTO_INIT_ENABLED) && (NRF_CRYPTO_RNG_AUTO_INIT_ENABLED == 0)
+
+ return NRF_SUCCESS;
+
+#else
+
+ #warning NRF_CRYPTO_RNG_AUTO_INIT_ENABLED define not found in sdk_config.h (Is the sdk_config.h valid?).
+
+#endif // NRF_MODULE_ENABLED(NRF_CRYPTO_RNG_AUTO_INIT)
+}
+
+
+CRYPTO_BACKEND_REGISTER(nrf_crypto_backend_info_t const nrf_hw_backend) =
+{
+ .init_fn = nrf_hw_backend_init,
+ .uninit_fn = nrf_hw_backend_uninit
+};
+
+#endif // NRF_MODULE_ENABLED(NRF_CRYPTO) && NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_NRF_HW_RNG)
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/nrf_hw/nrf_hw_backend_rng.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/nrf_hw/nrf_hw_backend_rng.c
new file mode 100644
index 0000000..e8331e1
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/nrf_hw/nrf_hw_backend_rng.c
@@ -0,0 +1,101 @@
+/**
+ * Copyright (c) 2018 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+
+#include "sdk_common.h"
+#if NRF_MODULE_ENABLED(NRF_CRYPTO) && \
+ NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_NRF_HW_RNG) && \
+ !NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_NRF_HW_RNG_MBEDTLS_CTR_DRBG)
+
+#include "nrf_crypto_rng.h"
+#include "nrf_drv_rng.h"
+
+
+ret_code_t nrf_crypto_rng_backend_init(void * const p_context,
+ void * const p_temp_buffer)
+{
+ ret_code_t ret_val;
+
+ UNUSED_PARAMETER(p_context);
+ UNUSED_PARAMETER(p_temp_buffer);
+
+ ret_val = nrf_drv_rng_init(NULL);
+
+ return ret_val;
+}
+
+
+ret_code_t nrf_crypto_rng_backend_uninit(void * const p_context)
+{
+ UNUSED_PARAMETER(p_context);
+
+ nrf_drv_rng_uninit();
+
+ return NRF_SUCCESS;
+}
+
+
+ret_code_t nrf_crypto_rng_backend_vector_generate(void * const p_context,
+ uint8_t * const p_target,
+ size_t size,
+ bool use_mutex)
+{
+ UNUSED_PARAMETER(use_mutex);
+ UNUSED_PARAMETER(p_context);
+
+ nrf_drv_rng_block_rand(p_target, size);
+
+ return NRF_SUCCESS;
+}
+
+
+ret_code_t nrf_crypto_rng_backend_reseed(void * const p_context,
+ void * p_temp_buffer,
+ uint8_t * p_input_data,
+ size_t size)
+{
+ UNUSED_PARAMETER(p_context);
+ UNUSED_PARAMETER(p_temp_buffer);
+ UNUSED_PARAMETER(p_input_data);
+ UNUSED_PARAMETER(size);
+
+ return NRF_ERROR_CRYPTO_FEATURE_UNAVAILABLE;
+}
+
+#endif //NRF_MODULE_ENABLED(NRF_CRYPTO) && NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_NRF_HW_RNG) && !NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_NRF_HW_RNG_MBEDTLS_CTR_DRBG)
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/nrf_hw/nrf_hw_backend_rng.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/nrf_hw/nrf_hw_backend_rng.h
new file mode 100644
index 0000000..fcf6b8d
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/nrf_hw/nrf_hw_backend_rng.h
@@ -0,0 +1,104 @@
+/**
+ * Copyright (c) 2018 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+
+#ifndef NRF_HW_BACKEND_RNG_H__
+#define NRF_HW_BACKEND_RNG_H__
+
+/** @file
+ *
+ * @defgroup nrf_crypto_nrf_hw_backend_rng nrf_crypto HW RNG backend
+ * @{
+ * @ingroup nrf_crypto_backends
+ *
+ * @brief RNG functionality provided by the nrf_crypto nRF HW RNG backend.
+ */
+
+#include "sdk_common.h"
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_NRF_HW_RNG) && \
+ !NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_NRF_HW_RNG_MBEDTLS_CTR_DRBG)
+
+#if !NRF_MODULE_ENABLED(RNG)
+#error Enable RNG_ENABLED in sdk_config.h.
+#endif
+
+#if !NRFX_RNG_CONFIG_ERROR_CORRECTION
+#error Enable NRFX_RNG_CONFIG_ERROR_CORRECTION and RNG_CONFIG_ERROR_CORRECTION in sdk_config.h.
+#endif
+
+#include "nrf_crypto_rng_shared.h"
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_RNG)
+#error "More than one RNG backend enabled."
+#endif // NRF_MODULE_ENABLED(NRF_CRYPTO_RNG)
+#define NRF_CRYPTO_RNG_ENABLED 1
+
+
+/**
+ * @internal @brief Context for nRF RNG peripheral.
+ */
+typedef struct
+{
+ nrf_crypto_rng_internal_context_t header; //!< Internal common context header.
+} nrf_crypto_backend_rng_context_t;
+
+/**
+ * @internal @brief Dummy temp buffer for nRF RNG peripheral.
+ */
+typedef struct
+{
+ uint32_t reserved;
+} nrf_crypto_backend_rng_temp_buffer_t;
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_NRF_HW_RNG) && !NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_NRF_HW_RNG_MBEDTLS_CTR_DRBG)
+
+/**@} */
+
+#endif // NRF_HW_BACKEND_RNG_H__
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/nrf_hw/nrf_hw_backend_rng_mbedtls.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/nrf_hw/nrf_hw_backend_rng_mbedtls.c
new file mode 100644
index 0000000..649904b
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/nrf_hw/nrf_hw_backend_rng_mbedtls.c
@@ -0,0 +1,168 @@
+/**
+ * Copyright (c) 2018 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+
+#include "sdk_common.h"
+#if NRF_MODULE_ENABLED(NRF_CRYPTO) && \
+ NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_NRF_HW_RNG) && \
+ NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_NRF_HW_RNG_MBEDTLS_CTR_DRBG)
+
+#include "nrf_crypto_rng.h"
+#include "nrf_drv_rng.h"
+#include "nrf_hw_backend_rng_mbedtls.h"
+
+
+// Function to convert mbedtls error codes to ret_code_t.
+static ret_code_t result_get(int mbedtls_ret_val)
+{
+ ret_code_t ret_val;
+ switch (mbedtls_ret_val)
+ {
+ case 0:
+ ret_val = NRF_SUCCESS;
+ break;
+
+ case MBEDTLS_ERR_CTR_DRBG_INPUT_TOO_BIG:
+ ret_val = NRF_ERROR_CRYPTO_INPUT_LENGTH;
+ break;
+
+ case MBEDTLS_ERR_CTR_DRBG_REQUEST_TOO_BIG:
+ ret_val = NRF_ERROR_CRYPTO_OUTPUT_LENGTH;
+ break;
+
+ case MBEDTLS_ERR_CTR_DRBG_ENTROPY_SOURCE_FAILED:
+ default:
+ ret_val = NRF_ERROR_CRYPTO_INTERNAL;
+ break;
+ }
+
+ return ret_val;
+}
+
+
+// Callback function used by mbed TLS to seed and reseed.
+static int entropy_callback(void * p_entropy, unsigned char * p_buffer, size_t size)
+{
+ UNUSED_PARAMETER(p_entropy);
+
+ nrf_drv_rng_block_rand(p_buffer, size);
+
+ return 0;
+}
+
+
+ret_code_t nrf_crypto_rng_backend_init(void * const p_context, void * const p_temp_buffer)
+{
+ ret_code_t ret_val;
+ int mbedtls_ret_val;
+ mbedtls_ctr_drbg_context * p_mbedtls_context =
+ &((nrf_crypto_backend_rng_context_t *)p_context)->mbedtls_context;
+
+ UNUSED_PARAMETER(p_temp_buffer);
+
+ ret_val = nrf_drv_rng_init(NULL);
+
+ if (ret_val != NRF_SUCCESS)
+ {
+ return ret_val;
+ }
+
+ mbedtls_ctr_drbg_init(p_mbedtls_context);
+
+ // Initial seeding. The nrf_crypto_rng API does not support additional entropy in the initial
+ // seeding. Additional entropy can be provided using nrf_crypto_rng_backend_reseed(),
+ // which calls mbedtls_ctr_drbg_reseed().
+ mbedtls_ret_val = mbedtls_ctr_drbg_seed(p_mbedtls_context,
+ entropy_callback,
+ NULL,
+ NULL,
+ 0);
+
+ ret_val = result_get(mbedtls_ret_val);
+
+ return ret_val;
+}
+
+
+ret_code_t nrf_crypto_rng_backend_uninit(void * const p_context)
+{
+ mbedtls_ctr_drbg_context * p_mbedtls_context =
+ &((nrf_crypto_backend_rng_context_t *)p_context)->mbedtls_context;
+
+ mbedtls_ctr_drbg_free(p_mbedtls_context);
+ nrf_drv_rng_uninit();
+
+ return NRF_SUCCESS;
+}
+
+
+ret_code_t nrf_crypto_rng_backend_vector_generate(void * const p_context,
+ uint8_t * const p_target,
+ size_t size,
+ bool use_mutex)
+{
+ int mbedtls_ret_val;
+ mbedtls_ctr_drbg_context * p_mbedtls_context =
+ &((nrf_crypto_backend_rng_context_t *)p_context)->mbedtls_context;
+
+ UNUSED_PARAMETER(use_mutex);
+
+ mbedtls_ret_val = mbedtls_ctr_drbg_random(p_mbedtls_context, p_target, size);
+
+ return result_get(mbedtls_ret_val);
+}
+
+
+ret_code_t nrf_crypto_rng_backend_reseed(void * const p_context,
+ void * p_temp_buffer,
+ uint8_t * p_input_data,
+ size_t size)
+{
+ int mbedtls_ret_val;
+ mbedtls_ctr_drbg_context * p_mbedtls_context =
+ &((nrf_crypto_backend_rng_context_t *)p_context)->mbedtls_context;
+
+ UNUSED_PARAMETER(p_temp_buffer);
+
+ mbedtls_ret_val = mbedtls_ctr_drbg_reseed(p_mbedtls_context, p_input_data, size);
+
+ return result_get(mbedtls_ret_val);
+}
+
+#endif //NRF_MODULE_ENABLED(NRF_CRYPTO) && NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_NRF_HW_RNG) && NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_NRF_HW_RNG_MBEDTLS_CTR_DRBG)
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/nrf_hw/nrf_hw_backend_rng_mbedtls.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/nrf_hw/nrf_hw_backend_rng_mbedtls.h
new file mode 100644
index 0000000..53daba0
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/nrf_hw/nrf_hw_backend_rng_mbedtls.h
@@ -0,0 +1,108 @@
+/**
+ * Copyright (c) 2018 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+
+#ifndef NRF_HW_BACKEND_RNG_MBEDTLS_H__
+#define NRF_HW_BACKEND_RNG_MBEDTLS_H__
+
+/** @file
+ *
+ * @defgroup nrf_crypto_nrf_hw_backend_rng_mbedtls nrf_crypto HW RNG backend using mbedtls CTR-DRBG
+ * @{
+ * @ingroup nrf_crypto_nrf_hw_backend_rng
+ *
+ * @brief RNG functionality provided by the nrf_crypto nRF HW RNG backend and mbedtls CTR-DRBG.
+ */
+
+#include "sdk_common.h"
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_NRF_HW_RNG) && \
+ NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_NRF_HW_RNG_MBEDTLS_CTR_DRBG)
+
+#if !NRF_MODULE_ENABLED(RNG)
+#error Enable RNG_ENABLED in sdk_config.h.
+#endif
+
+#if !NRFX_RNG_CONFIG_ERROR_CORRECTION
+#error Enable NRFX_RNG_CONFIG_ERROR_CORRECTION and RNG_CONFIG_ERROR_CORRECTION in sdk_config.h.
+#endif
+
+/*lint -save -e????*/
+#include "mbedtls/ctr_drbg.h"
+/*lint -restore*/
+#include "nrf_crypto_rng_shared.h"
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_RNG)
+#error "More than one RNG backend enabled."
+#endif // NRF_MODULE_ENABLED(NRF_CRYPTO_RNG)
+#define NRF_CRYPTO_RNG_ENABLED 1
+
+
+/**
+ * @internal @brief Context for nRF RNG peripheral with mbed tls CTR-DRBG.
+ */
+typedef struct
+{
+ nrf_crypto_rng_internal_context_t header; //!< Internal common context header.
+ mbedtls_ctr_drbg_context mbedtls_context; //!< mbed TLS CTR-DRBG context.
+} nrf_crypto_backend_rng_context_t;
+
+/**
+ * @internal @brief Dummy temp buffer for nRF RNG peripheral with mbed tls CTR-DRBG.
+ */
+typedef struct
+{
+ uint32_t reserved;
+} nrf_crypto_backend_rng_temp_buffer_t;
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_NRF_HW_RNG) && NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_NRF_HW_RNG_MBEDTLS_CTR_DRBG)
+
+/**@} */
+
+#endif // NRF_HW_BACKEND_RNG_MBEDTLS_H__
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/nrf_sw/nrf_sw_backend_hash.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/nrf_sw/nrf_sw_backend_hash.c
new file mode 100644
index 0000000..1360662
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/nrf_sw/nrf_sw_backend_hash.c
@@ -0,0 +1,149 @@
+/**
+ * Copyright (c) 2018 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+
+#include "sdk_common.h"
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO) && NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_NRF_SW)
+
+#include "nrf_sw_backend_hash.h"
+#include "sha256.h"
+#include "nrf_crypto_types.h"
+#include "nrf_crypto_error.h"
+#include "nrf_crypto_hash_shared.h"
+#include "sdk_macros.h"
+#include "nrf_log.h"
+#include "nrf_assert.h"
+
+#if defined(NRF_CRYPTO_BACKEND_NRF_SW_HASH_LITTLE_ENDIAN_DIGEST_ENABLED) && \
+ (NRF_CRYPTO_BACKEND_NRF_SW_HASH_LITTLE_ENDIAN_DIGEST_ENABLED == 1)
+
+ #define LITTLE_ENDIAN_HASH (true)
+
+#elif defined(NRF_CRYPTO_BACKEND_NRF_SW_HASH_LITTLE_ENDIAN_DIGEST_ENABLED) && \
+ (NRF_CRYPTO_BACKEND_NRF_SW_HASH_LITTLE_ENDIAN_DIGEST_ENABLED == 0)
+
+ #define LITTLE_ENDIAN_HASH (false)
+
+#else
+
+ #define LITTLE_ENDIAN_HASH (false)
+
+ #warning NRF_CRYPTO_BACKEND_NRF_SW_HASH_LITTLE_ENDIAN_DIGEST define not found in sdk_config.h (Is the sdk_config.h valid?).
+
+#endif
+
+static ret_code_t nrf_sw_backend_hash_sha256_init(void * const p_context)
+{
+ ret_code_t ret_val;
+
+ // No parameter testing on this level.
+ // This has been done on upper level.
+
+ sha256_context_t * p_backend_context
+ = &(((nrf_crypto_backend_hash_sha256_context_t *) p_context)->context);
+
+ ret_val = sha256_init(p_backend_context);
+
+ return ret_val;
+}
+
+static uint32_t nrf_sw_backend_hash_sha256_update(void * const p_context,
+ uint8_t const * p_data,
+ size_t len)
+{
+ ret_code_t ret_val;
+
+ // Limited parameter testing on this level.
+ // This has been done on upper level.
+
+ sha256_context_t * p_backend_context
+ = &(((nrf_crypto_backend_hash_sha256_context_t * ) p_context)->context);
+
+ ret_val = sha256_update(p_backend_context, p_data, len);
+
+ return ret_val;
+}
+
+
+static uint32_t nrf_sw_backend_hash_sha256_finalize(void * const p_context,
+ uint8_t * p_digest,
+ size_t * const p_digest_len)
+{
+ ret_code_t ret_val;
+
+ // Limited parameter testing on this level.
+ // This has been done on upper level.
+
+ sha256_context_t * p_backend_context
+ = &(((nrf_crypto_backend_hash_sha256_context_t * )p_context)->context);
+
+ if (NRF_CRYPTO_HASH_SIZE_SHA256 > *p_digest_len)
+ {
+ return NRF_ERROR_CRYPTO_OUTPUT_LENGTH;
+ }
+
+
+ ret_val = sha256_final(p_backend_context, p_digest, LITTLE_ENDIAN_HASH);
+
+ if (ret_val != NRF_SUCCESS)
+ {
+ return ret_val;
+ }
+
+ *p_digest_len = NRF_CRYPTO_HASH_SIZE_SHA256;
+
+ return NRF_SUCCESS;
+
+}
+
+
+const nrf_crypto_hash_info_t g_nrf_crypto_hash_sha256_info =
+{
+ .init_fn = nrf_sw_backend_hash_sha256_init,
+ .update_fn = nrf_sw_backend_hash_sha256_update,
+ .finalize_fn = nrf_sw_backend_hash_sha256_finalize,
+ .digest_size = NRF_CRYPTO_HASH_SIZE_SHA256,
+ .context_size = sizeof(nrf_crypto_backend_hash_sha256_context_t),
+ .hash_mode = NRF_CRYPTO_HASH_MODE_SHA256
+};
+
+
+
+#endif // NRF_MODULE_ENABLED(NRF_CRYPTO) && NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_NRF_SW)
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/nrf_sw/nrf_sw_backend_hash.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/nrf_sw/nrf_sw_backend_hash.h
new file mode 100644
index 0000000..b5c025c
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/nrf_sw/nrf_sw_backend_hash.h
@@ -0,0 +1,99 @@
+/**
+ * Copyright (c) 2018 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+
+#ifndef NRF_SW_BACKEND_HASH_H__
+#define NRF_SW_BACKEND_HASH_H__
+
+/** @file
+ *
+ * @defgroup nrf_crypto_nrf_sw_backend_hash nrf_crypto nRF SW backend hash
+ * @{
+ * @ingroup nrf_crypto_nrf_sw_backend
+ *
+ * @brief Legacy hash functionality for bootloader use in nRFx devices
+ */
+
+#include "sdk_common.h"
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_NRF_SW)
+
+#include "sha256.h"
+#include "nrf_crypto_error.h"
+#include "nrf_crypto_types.h"
+#include "nrf_crypto_hash_shared.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_NRF_SW_HASH_SHA256)
+
+// Flag that nrf_crypto_hash frontend can be compiled
+#undef NRF_CRYPTO_HASH_ENABLED
+#define NRF_CRYPTO_HASH_ENABLED 1
+
+// Duplicate backend enabled test for SHA-256
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_HASH_SHA256)
+#error "Duplicate definition of SHA-256. More than one backend enabled");
+#endif
+
+// Flag that SHA-256 is enabled in backend
+#define NRF_CRYPTO_HASH_SHA256_ENABLED 1
+
+#endif // NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_NRF_SW_HASH_SHA256)
+
+
+/**@brief nrf_crypto_hash context for SHA-256 in nrf_crypto nrf_sw backend. */
+typedef struct
+{
+ nrf_crypto_hash_internal_context_t header; /**< Common header for context. */
+ sha256_context_t context; /**< Hash context internal to nrf_sw. */
+} nrf_crypto_backend_hash_sha256_context_t;
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_NRF_SW)
+
+/**@} */
+
+#endif // NRF_SW_BACKEND_HASH_H__
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/oberon/oberon_backend_chacha_poly_aead.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/oberon/oberon_backend_chacha_poly_aead.c
new file mode 100644
index 0000000..14588d8
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/oberon/oberon_backend_chacha_poly_aead.c
@@ -0,0 +1,153 @@
+/**
+ * Copyright (c) 2018 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+
+#include "sdk_common.h"
+#if NRF_MODULE_ENABLED(NRF_CRYPTO)
+
+#include <stdbool.h>
+#include "oberon_backend_chacha_poly_aead.h"
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_OBERON_CHACHA_POLY_AEAD)
+
+static ret_code_t backend_cc310_init(void * const p_context, uint8_t * p_key)
+{
+ nrf_crypto_backend_chacha_poly_context_t * p_ctx =
+ (nrf_crypto_backend_chacha_poly_context_t *)p_context;
+
+
+ if (p_ctx->header.p_info->key_size != NRF_CRYPTO_KEY_SIZE_256)
+ {
+ return NRF_ERROR_CRYPTO_KEY_SIZE;
+ }
+
+ memcpy(p_ctx->key, p_key, sizeof(p_ctx->key));
+
+ return NRF_SUCCESS;
+}
+
+static inline ret_code_t backend_cc310_uninit(void * const p_context)
+{
+ return NRF_SUCCESS;
+}
+
+static ret_code_t backend_cc310_crypt(void * const p_context,
+ nrf_crypto_operation_t operation,
+ uint8_t * p_nonce,
+ uint8_t nonce_size,
+ uint8_t * p_adata,
+ size_t adata_size,
+ uint8_t * p_data_in,
+ size_t data_in_size,
+ uint8_t * p_data_out,
+ uint8_t * p_mac,
+ uint8_t mac_size)
+
+{
+ int result;
+
+ nrf_crypto_backend_chacha_poly_context_t * p_ctx =
+ (nrf_crypto_backend_chacha_poly_context_t *)p_context;
+
+ if ((adata_size == 0) || (data_in_size == 0))
+ {
+ return NRF_ERROR_CRYPTO_INPUT_LENGTH;
+ }
+
+ if (mac_size != NRF_CRYPTO_CHACHA_POLY_MAC_SIZE)
+ {
+ return NRF_ERROR_CRYPTO_AEAD_MAC_SIZE;
+ }
+
+ if (nonce_size != NRF_CRYPTO_CHACHA_POLY_NONCE_SIZE)
+ {
+ return NRF_ERROR_CRYPTO_AEAD_NONCE_SIZE;
+ }
+
+ if (operation == NRF_CRYPTO_ENCRYPT)
+ {
+ occ_chacha20_poly1305_encrypt_aad(p_mac,
+ p_data_out,
+ p_data_in,
+ data_in_size,
+ p_adata,
+ adata_size,
+ p_nonce,
+ (size_t)nonce_size,
+ p_ctx->key);
+ }
+ else if (operation == NRF_CRYPTO_DECRYPT)
+ {
+ result = occ_chacha20_poly1305_decrypt_aad(p_mac,
+ p_data_out,
+ p_data_in,
+ data_in_size,
+ p_adata,
+ adata_size,
+ p_nonce,
+ (size_t)nonce_size,
+ p_ctx->key);
+
+ if (result != 0)
+ {
+ return NRF_ERROR_CRYPTO_AEAD_INVALID_MAC;
+ }
+ }
+ else
+ {
+ return NRF_ERROR_CRYPTO_INVALID_PARAM;
+ }
+
+ return NRF_SUCCESS;
+}
+
+nrf_crypto_aead_info_t const g_nrf_crypto_chacha_poly_256_info =
+{
+ .key_size = NRF_CRYPTO_KEY_SIZE_256,
+ .mode = NRF_CRYPTO_AEAD_MODE_CHACHA_POLY,
+
+ .init_fn = backend_cc310_init,
+ .uninit_fn = backend_cc310_uninit,
+ .crypt_fn = backend_cc310_crypt
+};
+
+
+#endif // NRF_MODULE_ENABLED(NRF_CRYPTO_CC310_CHACHA_POLY_AEAD)
+#endif // NRF_MODULE_ENABLED(NRF_CRYPTO)
+
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/oberon/oberon_backend_chacha_poly_aead.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/oberon/oberon_backend_chacha_poly_aead.h
new file mode 100644
index 0000000..990db3e
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/oberon/oberon_backend_chacha_poly_aead.h
@@ -0,0 +1,100 @@
+/**
+ * Copyright (c) 2018 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+
+#ifndef OBERON_BACKEND_CHACHA_POLY_AEAD_H__
+#define OBERON_BACKEND_CHACHA_POLY_AEAD_H__
+
+/** @file
+ *
+ * @defgroup nrf_crypto_oberon_backend_chacha_poly_aead nrf_crypto Oberon backend CHACHA_POLY AEAD
+ * @{
+ * @ingroup nrf_crypto_oberon_backend
+ *
+ * @brief AES AEAD functionality provided by the nrf_crypto Oberon backend.
+ */
+
+#include "sdk_config.h"
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_OBERON)
+
+#include "nrf_crypto_aead_shared.h"
+#include "occ_chacha20_poly1305.h"
+#include "nrf_crypto_error.h"
+#include "nrf_crypto_types.h"
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define NRF_CRYPTO_OBERON_CHACHA_POLY_BACKEND_KEY_SIZE (32)
+
+/* CHACHA-POLY */
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_OBERON_CHACHA_POLY)
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_CHACHA_POLY)
+#error "Duplicate definition of CHACHA-POLY mode. More than one backend enabled");
+#endif
+#define NRF_CRYPTO_CHACHA_POLY_ENABLED 1
+#undef NRF_CRYPTO_AEAD_ENABLED
+#define NRF_CRYPTO_AEAD_ENABLED 1 // Flag that nrf_crypto_aead frontend can be compiled
+#undef NRF_CRYPTO_OBERON_CHACHA_POLY_AEAD_ENABLED
+#define NRF_CRYPTO_OBERON_CHACHA_POLY_AEAD_ENABLED 1 // aead backend for Oberon can be compiled
+
+/* defines for test purposes */
+#define NRF_CRYPTO_AES_CHACHA_POLY_256_ENABLED 1
+
+typedef struct
+{
+ nrf_crypto_aead_internal_context_t header; /**< Common header for context. */
+
+ uint8_t key[NRF_CRYPTO_OBERON_CHACHA_POLY_BACKEND_KEY_SIZE];
+} nrf_crypto_backend_chacha_poly_context_t;
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_OBERON)
+
+/** @} */
+
+#endif // OBERON_BACKEND_CHACHA_POLY_AEAD_H__
+
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/oberon/oberon_backend_ecc.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/oberon/oberon_backend_ecc.c
new file mode 100644
index 0000000..ed8f510
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/oberon/oberon_backend_ecc.c
@@ -0,0 +1,458 @@
+/**
+ * Copyright (c) 2018 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+
+#include "sdk_config.h"
+#include "nordic_common.h"
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO) && NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_OBERON)
+
+#include <stdbool.h>
+#include <string.h>
+#include <stddef.h>
+
+#include "app_util.h"
+#include "nrf_crypto_ecc.h"
+#include "nrf_crypto_mem.h"
+#include "nrf_crypto_rng.h"
+#include "nrf_crypto_shared.h"
+#include "oberon_backend_ecc.h"
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_OBERON_ECC_SECP256R1)
+#include "occ_ecdh_p256.h"
+#endif
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_OBERON_ECC_CURVE25519)
+#include "occ_curve25519.h"
+#endif
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_OBERON_ECC_ED25519)
+#include "occ_ed25519.h"
+#endif
+
+
+/** @internal @brief Structure holding private key common to all curves implemented by the Oberon.
+ */
+typedef struct
+{
+ nrf_crypto_internal_ecc_key_header_t header; /**< @internal @brief Common ECC key header. */
+ uint8_t key[32]; /**< @internal @brief Raw key. */
+} nrf_crypto_backend_oberon_private_key_t;
+
+
+/** @internal @brief Structure holding public key common to all curves implemented by the Oberon.
+ */
+typedef struct
+{
+ nrf_crypto_internal_ecc_key_header_t header; /**< @internal @brief Common ECC key header. */
+ uint8_t key[64]; /**< @internal @brief Raw key. */
+} nrf_crypto_backend_oberon_public_key_t;
+
+
+/** @internal @brief Function to hold copy function (can be simple mem copy or copy with endian swap).
+ */
+typedef void (*copy_fn_t)(void * p_dest, void const * p_src, size_t size);
+
+
+ret_code_t nrf_crypto_backend_oberon_private_key_to_raw(
+ void const * p_private_key,
+ uint8_t * p_raw_data)
+{
+ nrf_crypto_backend_oberon_private_key_t const * p_prv =
+ (nrf_crypto_backend_oberon_private_key_t const *)p_private_key;
+
+ //lint -save -e611 (Suspicious cast)
+ copy_fn_t copy_fn = (copy_fn_t)p_prv->header.p_info->p_backend_data;
+ //lint -restore
+
+ copy_fn(p_raw_data, p_prv->key, p_prv->header.p_info->raw_private_key_size);
+
+ return NRF_SUCCESS;
+}
+
+
+ret_code_t nrf_crypto_backend_oberon_public_key_from_raw(
+ void * p_public_key,
+ uint8_t const * p_raw_data)
+{
+ nrf_crypto_backend_oberon_public_key_t * p_pub =
+ (nrf_crypto_backend_oberon_public_key_t *)p_public_key;
+
+ //lint -save -e611 (Suspicious cast)
+ copy_fn_t copy_fn = (copy_fn_t)p_pub->header.p_info->p_backend_data;
+ //lint -restore
+
+ copy_fn(p_pub->key, p_raw_data, p_pub->header.p_info->raw_public_key_size);
+
+ return NRF_SUCCESS;
+}
+
+
+ret_code_t nrf_crypto_backend_oberon_public_key_to_raw(
+ void const * p_public_key,
+ uint8_t * p_raw_data)
+{
+ nrf_crypto_backend_oberon_public_key_t const * p_pub =
+ (nrf_crypto_backend_oberon_public_key_t const *)p_public_key;
+
+ //lint -save -e611 (Suspicious cast)
+ copy_fn_t copy_fn = (copy_fn_t)p_pub->header.p_info->p_backend_data;
+ //lint -restore
+
+ copy_fn(p_raw_data, p_pub->key, p_pub->header.p_info->raw_public_key_size);
+
+ return NRF_SUCCESS;
+}
+
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_OBERON_ECC_SECP256R1) \
+ || NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_OBERON_ECC_CURVE25519)
+
+
+ret_code_t nrf_crypto_backend_oberon_private_key_from_raw(
+ void * p_private_key,
+ uint8_t const * p_raw_data)
+{
+ nrf_crypto_backend_oberon_private_key_t * p_prv =
+ (nrf_crypto_backend_oberon_private_key_t *)p_private_key;
+
+ //lint -save -e611 (Suspicious cast)
+ copy_fn_t copy_fn = (copy_fn_t)p_prv->header.p_info->p_backend_data;
+ //lint -restore
+
+ copy_fn(p_prv->key, p_raw_data, p_prv->header.p_info->raw_private_key_size);
+
+ return NRF_SUCCESS;
+}
+
+
+#endif //NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_OBERON_ECC_SECP256R1) || NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_OBERON_ECC_CURVE25519)
+
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_OBERON_ECC_CURVE25519) \
+ || NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_OBERON_ECC_ED25519)
+
+
+static ret_code_t oberon_vector_generate(uint8_t * p_data, size_t size)
+{
+#if defined(NRF_CRYPTO_RNG_ENABLED) && (NRF_CRYPTO_RNG_ENABLED == 1)
+
+ return nrf_crypto_rng_vector_generate(p_data, size);
+
+#elif defined(NRF_CRYPTO_RNG_ENABLED) && (NRF_CRYPTO_RNG_ENABLED == 0)
+
+ return NRF_ERROR_CRYPTO_FEATURE_UNAVAILABLE;
+
+#else
+
+ #warning NRF_CRYPTO_RNG_ENABLED define not found in sdk_config.h (Is the sdk_config.h valid?).
+
+#endif
+}
+
+
+#endif //NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_OBERON_ECC_CURVE25519) || NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_OBERON_ECC_ED25519)
+
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_OBERON_ECC_SECP256R1)
+
+
+// Make sure that common key structure match secp256r1 key structure to safely cast types.
+STATIC_ASSERT(offsetof(nrf_crypto_backend_oberon_private_key_t, key) ==
+ offsetof(nrf_crypto_backend_secp256r1_private_key_t, key),
+ "Common Oberon private key structure does not match secp256r1 one.");
+STATIC_ASSERT(offsetof(nrf_crypto_backend_oberon_public_key_t, key) ==
+ offsetof(nrf_crypto_backend_secp256r1_public_key_t, key),
+ "Common Oberon public key structure does not match secp256r1 one.");
+
+
+ret_code_t nrf_crypto_backend_oberon_ecc_secp256r1_rng(uint8_t data[32])
+{
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_RNG)
+
+ static const uint8_t min_value[32] =
+ {
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
+ };
+ static const uint8_t max_value[32] =
+ {
+ 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xBC, 0xE6, 0xFA, 0xAD, 0xA7, 0x17, 0x9E, 0x84, 0xF3, 0xB9, 0xCA, 0xC2, 0xFC, 0x63, 0x25, 0x50,
+ };
+ return nrf_crypto_rng_vector_generate_in_range(data, min_value, max_value, 32);
+
+#else
+ return NRF_ERROR_CRYPTO_FEATURE_UNAVAILABLE;
+#endif
+}
+
+
+ret_code_t nrf_crypto_backend_secp256r1_key_pair_generate(
+ void * p_context,
+ void * p_private_key,
+ void * p_public_key)
+{
+ int result;
+
+ nrf_crypto_backend_secp256r1_private_key_t * p_prv =
+ (nrf_crypto_backend_secp256r1_private_key_t *)p_private_key;
+
+ nrf_crypto_backend_secp256r1_public_key_t * p_pub =
+ (nrf_crypto_backend_secp256r1_public_key_t *)p_public_key;
+
+ result = nrf_crypto_backend_oberon_ecc_secp256r1_rng(p_prv->key);
+
+ if (result != NRF_SUCCESS)
+ {
+ return result;
+ }
+
+ result = occ_ecdh_p256_public_key(p_pub->key, p_prv->key);
+
+ if (result != 0)
+ {
+ return NRF_ERROR_CRYPTO_INTERNAL;
+ }
+ return NRF_SUCCESS;
+}
+
+
+ret_code_t nrf_crypto_backend_secp256r1_public_key_calculate(
+ void * p_context,
+ void const * p_private_key,
+ void * p_public_key)
+{
+ int result;
+
+ nrf_crypto_backend_secp256r1_private_key_t const * p_prv =
+ (nrf_crypto_backend_secp256r1_private_key_t const *)p_private_key;
+
+ nrf_crypto_backend_secp256r1_public_key_t * p_pub =
+ (nrf_crypto_backend_secp256r1_public_key_t *)p_public_key;
+
+ result = occ_ecdh_p256_public_key(p_pub->key, p_prv->key);
+
+ if (result != 0)
+ {
+ return NRF_ERROR_CRYPTO_INTERNAL;
+ }
+ return NRF_SUCCESS;
+}
+
+
+const nrf_crypto_ecc_curve_info_t g_nrf_crypto_ecc_secp256r1_curve_info =
+{
+ .public_key_size = sizeof(nrf_crypto_backend_secp256r1_public_key_t),
+ .private_key_size = sizeof(nrf_crypto_backend_secp256r1_private_key_t),
+ .curve_type = NRF_CRYPTO_ECC_SECP256R1_CURVE_TYPE,
+ .raw_private_key_size = NRF_CRYPTO_ECC_SECP256R1_RAW_PRIVATE_KEY_SIZE,
+ .raw_public_key_size = NRF_CRYPTO_ECC_SECP256R1_RAW_PUBLIC_KEY_SIZE,
+ //lint -save -e611 -e546 (Suspicious cast, Suspicious use of &)
+ .p_backend_data = (void *)&memcpy,
+ //lint -restore
+};
+
+
+#endif // NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_OBERON_ECC_SECP256R1)
+
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_OBERON_ECC_CURVE25519)
+
+
+// Make sure that common key structure match Curve25519 key structure to safely cast types.
+STATIC_ASSERT(offsetof(nrf_crypto_backend_oberon_private_key_t, key) ==
+ offsetof(nrf_crypto_backend_curve25519_private_key_t, key),
+ "Common Oberon private key structure does not match Curve25519 one.");
+STATIC_ASSERT(offsetof(nrf_crypto_backend_oberon_public_key_t, key) ==
+ offsetof(nrf_crypto_backend_curve25519_public_key_t, key),
+ "Common Oberon public key structure does not match Curve25519 one.");
+
+
+ret_code_t nrf_crypto_backend_curve25519_key_pair_generate(
+ void * p_context,
+ void * p_private_key,
+ void * p_public_key)
+{
+ ret_code_t result;
+
+ nrf_crypto_backend_curve25519_private_key_t * p_prv =
+ (nrf_crypto_backend_curve25519_private_key_t *)p_private_key;
+
+ nrf_crypto_backend_curve25519_public_key_t * p_pub =
+ (nrf_crypto_backend_curve25519_public_key_t *)p_public_key;
+
+ result = oberon_vector_generate(p_prv->key, sizeof(p_prv->key));
+
+ if (result != NRF_SUCCESS)
+ {
+ return result;
+ }
+
+ p_prv->key[0] &= 0xF8; // Private key is multiply of 8 (by definition), so lower 3 bits are 0.
+ p_prv->key[31] &= 0x7F; // Highest bit has to be 0, because private key is 255-bit long.
+ p_prv->key[31] |= 0x40; // Bit 254 has to be 1 (by definition)
+
+ occ_curve25519_scalarmult_base(p_pub->key, p_prv->key);
+
+ return NRF_SUCCESS;
+}
+
+
+ret_code_t nrf_crypto_backend_curve25519_public_key_calculate(
+ void * p_context,
+ void const * p_private_key,
+ void * p_public_key)
+{
+ nrf_crypto_backend_curve25519_private_key_t * p_prv =
+ (nrf_crypto_backend_curve25519_private_key_t *)p_private_key;
+
+ nrf_crypto_backend_curve25519_public_key_t * p_pub =
+ (nrf_crypto_backend_curve25519_public_key_t *)p_public_key;
+
+ // Private key bit fixing is done inside Oberon library.
+ occ_curve25519_scalarmult_base(p_pub->key, p_prv->key);
+
+ return NRF_SUCCESS;
+}
+
+
+const nrf_crypto_ecc_curve_info_t g_nrf_crypto_ecc_curve25519_curve_info =
+{
+ .public_key_size = sizeof(nrf_crypto_backend_curve25519_public_key_t),
+ .private_key_size = sizeof(nrf_crypto_backend_curve25519_private_key_t),
+ .curve_type = NRF_CRYPTO_ECC_CURVE25519_CURVE_TYPE,
+ .raw_private_key_size = NRF_CRYPTO_ECC_CURVE25519_RAW_PRIVATE_KEY_SIZE,
+ .raw_public_key_size = NRF_CRYPTO_ECC_CURVE25519_RAW_PUBLIC_KEY_SIZE,
+ //lint -save -e611 -e546 (Suspicious cast, Suspicious use of &)
+ .p_backend_data = (void *)&nrf_crypto_internal_swap_endian,
+ //lint -restore
+};
+
+
+#endif // NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_OBERON_ECC_CURVE25519)
+
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_OBERON_ECC_ED25519)
+
+
+// Make sure that common key structure match Ed25519 key structure to safely cast types.
+STATIC_ASSERT(offsetof(nrf_crypto_backend_oberon_private_key_t, key) ==
+ offsetof(nrf_crypto_backend_ed25519_private_key_t, private_part),
+ "Common Oberon private key structure does not match Ed25519 one.");
+STATIC_ASSERT(offsetof(nrf_crypto_backend_oberon_public_key_t, key) ==
+ offsetof(nrf_crypto_backend_ed25519_public_key_t, key),
+ "Common Oberon public key structure does not match Ed25519 one.");
+
+
+ret_code_t nrf_crypto_backend_ed25519_private_key_from_raw(
+ void * p_private_key,
+ uint8_t const * p_raw_data)
+{
+ nrf_crypto_backend_ed25519_private_key_t * p_prv =
+ (nrf_crypto_backend_ed25519_private_key_t *)p_private_key;
+
+ memcpy(p_prv->private_part, p_raw_data, sizeof(p_prv->private_part));
+
+ occ_ed25519_public_key(p_prv->public_part, p_prv->private_part);
+
+ return NRF_SUCCESS;
+}
+
+
+ret_code_t nrf_crypto_backend_ed25519_key_pair_generate(
+ void * p_context,
+ void * p_private_key,
+ void * p_public_key)
+{
+ ret_code_t result;
+
+ nrf_crypto_backend_ed25519_private_key_t * p_prv =
+ (nrf_crypto_backend_ed25519_private_key_t *)p_private_key;
+
+ nrf_crypto_backend_ed25519_public_key_t * p_pub =
+ (nrf_crypto_backend_ed25519_public_key_t *)p_public_key;
+
+ result = oberon_vector_generate(p_prv->private_part, sizeof(p_prv->private_part));
+
+ if (result != NRF_SUCCESS)
+ {
+ return result;
+ }
+
+ occ_ed25519_public_key(p_prv->public_part, p_prv->private_part);
+
+ memcpy(p_pub->key, p_prv->public_part, sizeof(p_pub->key));
+
+ return NRF_SUCCESS;
+}
+
+
+ret_code_t nrf_crypto_backend_ed25519_public_key_calculate(
+ void * p_context,
+ void const * p_private_key,
+ void * p_public_key)
+{
+ nrf_crypto_backend_ed25519_private_key_t * p_prv =
+ (nrf_crypto_backend_ed25519_private_key_t *)p_private_key;
+
+ nrf_crypto_backend_ed25519_public_key_t * p_pub =
+ (nrf_crypto_backend_ed25519_public_key_t *)p_public_key;
+
+ memcpy(p_pub->key, p_prv->public_part, sizeof(p_pub->key));
+
+ return NRF_SUCCESS;
+}
+
+
+const nrf_crypto_ecc_curve_info_t g_nrf_crypto_ecc_ed25519_curve_info =
+{
+ .public_key_size = sizeof(nrf_crypto_backend_ed25519_public_key_t),
+ .private_key_size = sizeof(nrf_crypto_backend_ed25519_private_key_t),
+ .curve_type = NRF_CRYPTO_ECC_ED25519_CURVE_TYPE,
+ .raw_private_key_size = NRF_CRYPTO_ECC_ED25519_RAW_PRIVATE_KEY_SIZE,
+ .raw_public_key_size = NRF_CRYPTO_ECC_ED25519_RAW_PUBLIC_KEY_SIZE,
+ //lint -save -e611 -e546 (Suspicious cast, Suspicious use of &)
+ .p_backend_data = (void *)&memcpy,
+ //lint -restore
+};
+
+
+#endif // NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_OBERON_ECC_ED25519)
+
+
+#endif // NRF_MODULE_ENABLED(NRF_CRYPTO) && NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_OBERON)
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/oberon/oberon_backend_ecc.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/oberon/oberon_backend_ecc.h
new file mode 100644
index 0000000..2fa7d1e
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/oberon/oberon_backend_ecc.h
@@ -0,0 +1,314 @@
+/**
+ * Copyright (c) 2018 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+
+#ifndef OBERON_BACKEND_ECC_H__
+#define OBERON_BACKEND_ECC_H__
+
+#include "sdk_config.h"
+#include "nordic_common.h"
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO) && NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_OBERON)
+
+#include <stdint.h>
+#include <stdbool.h>
+#include "nrf_crypto_ecc_shared.h"
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+/** @internal See @ref nrf_crypto_backend_ecc_private_key_from_raw_fn_t.
+*/
+ret_code_t nrf_crypto_backend_oberon_private_key_from_raw(
+ void * p_private_key,
+ uint8_t const * p_raw_data);
+
+
+/** @internal See @ref nrf_crypto_backend_ecc_private_key_to_raw_fn_t.
+*/
+ret_code_t nrf_crypto_backend_oberon_private_key_to_raw(
+ void const * p_private_key,
+ uint8_t * p_raw_data);
+
+
+/** @internal See @ref nrf_crypto_backend_ecc_public_key_from_raw_fn_t.
+*/
+ret_code_t nrf_crypto_backend_oberon_public_key_from_raw(
+ void * p_public_key,
+ uint8_t const * p_raw_data);
+
+
+/** @internal See @ref nrf_crypto_backend_ecc_public_key_to_raw_fn_t.
+*/
+ret_code_t nrf_crypto_backend_oberon_public_key_to_raw(
+ void const * p_public_key,
+ uint8_t * p_raw_data);
+
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_OBERON_ECC_SECP256R1)
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_ECC_SECP256R1)
+#error "More than one backend enabled for secp256r1 (NIST 256-bit).");
+#endif
+#define NRF_CRYPTO_ECC_SECP256R1_ENABLED 1
+
+
+/** @internal @brief Generates random number that can be used as a private key for secp256r1.
+ *
+ * It uses RNG from libary frontend to generate random numbers.
+ *
+ * @param[out] data Array where generated random number will be placed.
+ * @returns NRF_SUCCESS or error code passed from RNG frontend.
+ */
+ret_code_t nrf_crypto_backend_oberon_ecc_secp256r1_rng(uint8_t data[32]);
+
+
+/** @internal @brief Structure holding private key for Oberon's secp256r1.
+ */
+typedef struct
+{
+ nrf_crypto_internal_ecc_key_header_t header; /**< @internal @brief Common ECC key header. */
+ uint8_t key[32]; /**< @internal @brief Raw key. */
+} nrf_crypto_backend_secp256r1_private_key_t;
+
+
+/** @internal @brief Structure holding public key for Oberon's secp256r1.
+ */
+typedef struct
+{
+ nrf_crypto_internal_ecc_key_header_t header; /**< @internal @brief Common ECC key header. */
+ uint8_t key[64]; /**< @internal @brief Raw key. */
+} nrf_crypto_backend_secp256r1_public_key_t;
+
+
+/** @internal See @ref nrf_crypto_backend_ecc_key_pair_generate_fn_t.
+ */
+ret_code_t nrf_crypto_backend_secp256r1_key_pair_generate(
+ void * p_context,
+ void * p_private_key,
+ void * p_public_key);
+
+
+/** @internal See @ref nrf_crypto_backend_ecc_public_key_calculate_fn_t.
+*/
+ret_code_t nrf_crypto_backend_secp256r1_public_key_calculate(
+ void * p_context,
+ void const * p_private_key,
+ void * p_public_key);
+
+
+// Common key conversion functions
+#define nrf_crypto_backend_secp256r1_private_key_from_raw \
+ nrf_crypto_backend_oberon_private_key_from_raw
+#define nrf_crypto_backend_secp256r1_private_key_to_raw \
+ nrf_crypto_backend_oberon_private_key_to_raw
+#define nrf_crypto_backend_secp256r1_public_key_from_raw \
+ nrf_crypto_backend_oberon_public_key_from_raw
+#define nrf_crypto_backend_secp256r1_public_key_to_raw \
+ nrf_crypto_backend_oberon_public_key_to_raw
+
+// Free is not required for oberon keys
+#define nrf_crypto_backend_secp256r1_private_key_free NULL
+#define nrf_crypto_backend_secp256r1_public_key_free NULL
+
+// Context is not used in oberon functions
+#define NRF_CRYPTO_BACKEND_SECP256R1_KEY_PAIR_GENERATE_CONTEXT_SIZE 0
+#define NRF_CRYPTO_BACKEND_SECP256R1_PUBLIC_KEY_CALCULATE_CONTEXT_SIZE 0
+
+// Dummy typedef for unused context
+typedef uint32_t nrf_crypto_backend_secp256r1_key_pair_generate_context_t;
+typedef uint32_t nrf_crypto_backend_secp256r1_public_key_calculate_context_t;
+
+
+#endif // NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_OBERON_ECC_SECP256R1)
+
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_OBERON_ECC_CURVE25519)
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_ECC_CURVE25519)
+#error "More than one backend enabled for Curve25519.");
+#endif
+#define NRF_CRYPTO_ECC_CURVE25519_ENABLED 1
+
+
+/** @internal @brief Structure holding private key for Oberon's Curve25519.
+ */
+typedef struct
+{
+ nrf_crypto_internal_ecc_key_header_t header; /**< @internal @brief Common ECC key header. */
+ uint8_t key[32]; /**< @internal @brief Raw key in little endian order. */
+} nrf_crypto_backend_curve25519_private_key_t;
+
+
+/** @internal @brief Structure holding public key for Oberon's Curve25519.
+ */
+typedef struct
+{
+ nrf_crypto_internal_ecc_key_header_t header; /**< @internal @brief Common ECC key header. */
+ uint8_t key[32]; /**< @internal @brief Raw key in little endian order. */
+} nrf_crypto_backend_curve25519_public_key_t;
+
+
+/** @internal See @ref nrf_crypto_backend_ecc_key_pair_generate_fn_t.
+ */
+ret_code_t nrf_crypto_backend_curve25519_key_pair_generate(
+ void * p_context,
+ void * p_private_key,
+ void * p_public_key);
+
+
+/** @internal See @ref nrf_crypto_backend_ecc_public_key_calculate_fn_t.
+*/
+ret_code_t nrf_crypto_backend_curve25519_public_key_calculate(
+ void * p_context,
+ void const * p_private_key,
+ void * p_public_key);
+
+
+// Common key conversion functions
+#define nrf_crypto_backend_curve25519_private_key_from_raw \
+ nrf_crypto_backend_oberon_private_key_from_raw
+#define nrf_crypto_backend_curve25519_private_key_to_raw \
+ nrf_crypto_backend_oberon_private_key_to_raw
+#define nrf_crypto_backend_curve25519_public_key_from_raw \
+ nrf_crypto_backend_oberon_public_key_from_raw
+#define nrf_crypto_backend_curve25519_public_key_to_raw \
+ nrf_crypto_backend_oberon_public_key_to_raw
+
+// Free is not required for oberon keys
+#define nrf_crypto_backend_curve25519_private_key_free NULL
+#define nrf_crypto_backend_curve25519_public_key_free NULL
+
+// Context is not used in oberon functions
+#define NRF_CRYPTO_BACKEND_CURVE25519_KEY_PAIR_GENERATE_CONTEXT_SIZE 0
+#define NRF_CRYPTO_BACKEND_CURVE25519_PUBLIC_KEY_CALCULATE_CONTEXT_SIZE 0
+
+// Dummy typedef for unused context
+typedef uint32_t nrf_crypto_backend_curve25519_key_pair_generate_context_t;
+typedef uint32_t nrf_crypto_backend_curve25519_public_key_calculate_context_t;
+
+
+#endif // NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_OBERON_ECC_CURVE25519)
+
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_OBERON_ECC_ED25519)
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_ECC_ED25519)
+#error "More than one backend enabled for Ed25519.");
+#endif
+#define NRF_CRYPTO_ECC_ED25519_ENABLED 1
+
+
+
+/** @internal @brief Structure holding private key for Oberon's Ed25519.
+ */
+typedef struct
+{
+ nrf_crypto_internal_ecc_key_header_t header; /**< @internal @brief Common ECC key header. */
+ uint8_t private_part[32]; /**< @internal @brief Raw private key. */
+ uint8_t public_part[32]; /**< @internal @brief Raw public key. It is also required for Ed25519 signing. */
+} nrf_crypto_backend_ed25519_private_key_t;
+
+
+/** @internal @brief Structure holding private key for Oberon's Ed25519.
+ */
+typedef struct
+{
+ nrf_crypto_internal_ecc_key_header_t header; /**< @internal @brief Common ECC key header. */
+ uint8_t key[32]; /**< @internal @brief Raw key. */
+} nrf_crypto_backend_ed25519_public_key_t;
+
+
+/** @internal See @ref nrf_crypto_backend_ecc_private_key_from_raw_fn_t.
+*/
+ret_code_t nrf_crypto_backend_ed25519_private_key_from_raw(
+ void * p_private_key,
+ uint8_t const * p_raw_data);
+
+
+/** @internal See @ref nrf_crypto_backend_ecc_key_pair_generate_fn_t.
+ */
+ret_code_t nrf_crypto_backend_ed25519_key_pair_generate(
+ void * p_context,
+ void * p_private_key,
+ void * p_public_key);
+
+
+/** @internal See @ref nrf_crypto_backend_ecc_public_key_calculate_fn_t.
+*/
+ret_code_t nrf_crypto_backend_ed25519_public_key_calculate(
+ void * p_context,
+ void const * p_private_key,
+ void * p_public_key);
+
+
+// Common key conversion functions
+#define nrf_crypto_backend_ed25519_private_key_to_raw \
+ nrf_crypto_backend_oberon_private_key_to_raw
+#define nrf_crypto_backend_ed25519_public_key_from_raw \
+ nrf_crypto_backend_oberon_public_key_from_raw
+#define nrf_crypto_backend_ed25519_public_key_to_raw \
+ nrf_crypto_backend_oberon_public_key_to_raw
+
+// Free is not required for oberon keys
+#define nrf_crypto_backend_ed25519_private_key_free NULL
+#define nrf_crypto_backend_ed25519_public_key_free NULL
+
+// Context is not used in oberon functions
+#define NRF_CRYPTO_BACKEND_ED25519_KEY_PAIR_GENERATE_CONTEXT_SIZE 0
+#define NRF_CRYPTO_BACKEND_ED25519_PUBLIC_KEY_CALCULATE_CONTEXT_SIZE 0
+
+// Dummy typedef for unused context
+typedef uint32_t nrf_crypto_backend_ed25519_key_pair_generate_context_t;
+typedef uint32_t nrf_crypto_backend_ed25519_public_key_calculate_context_t;
+
+
+#endif // NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_OBERON_ECC_ED25519)
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // NRF_MODULE_ENABLED(NRF_CRYPTO) && NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_OBERON)
+
+#endif // OBERON_BACKEND_ECC_H__
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/oberon/oberon_backend_ecdh.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/oberon/oberon_backend_ecdh.c
new file mode 100644
index 0000000..9dcba96
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/oberon/oberon_backend_ecdh.c
@@ -0,0 +1,114 @@
+/**
+ * Copyright (c) 2018 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+
+#include "sdk_config.h"
+#include "nordic_common.h"
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO) && NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_OBERON)
+
+#include <stdint.h>
+
+#include "nrf_crypto_ecc.h"
+#include "nrf_crypto_ecdh.h"
+#include "nrf_crypto_shared.h"
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_OBERON_ECC_SECP256R1)
+#include "occ_ecdh_p256.h"
+#endif
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_OBERON_ECC_CURVE25519)
+#include "occ_curve25519.h"
+#endif
+
+
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_OBERON_ECC_SECP256R1)
+
+ret_code_t nrf_crypto_backend_secp256r1_ecdh_compute(
+ void * p_context,
+ void const * p_private_key,
+ void const * p_public_key,
+ uint8_t * p_shared_secret)
+{
+ int result;
+
+ nrf_crypto_backend_secp256r1_private_key_t const * p_prv =
+ (nrf_crypto_backend_secp256r1_private_key_t const *)p_private_key;
+
+ nrf_crypto_backend_secp256r1_public_key_t const * p_pub =
+ (nrf_crypto_backend_secp256r1_public_key_t const *)p_public_key;
+
+ result = occ_ecdh_p256_common_secret(p_shared_secret, p_prv->key, p_pub->key);
+
+ if (result != 0)
+ {
+ return NRF_ERROR_CRYPTO_INTERNAL;
+ }
+ return NRF_SUCCESS;
+}
+
+#endif // NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_OBERON_ECC_SECP256R1)
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_OBERON_ECC_CURVE25519)
+
+ret_code_t nrf_crypto_backend_curve25519_ecdh_compute(
+ void * p_context,
+ void const * p_private_key,
+ void const * p_public_key,
+ uint8_t * p_shared_secret)
+{
+ nrf_crypto_backend_curve25519_private_key_t const * p_prv =
+ (nrf_crypto_backend_curve25519_private_key_t const *)p_private_key;
+
+ nrf_crypto_backend_curve25519_public_key_t const * p_pub =
+ (nrf_crypto_backend_curve25519_public_key_t const *)p_public_key;
+
+ // Private key can be completely random at this point.
+ // Oberon library updates bits in the key according to Curve25519 specification before use.
+ occ_curve25519_scalarmult(p_shared_secret, p_prv->key, p_pub->key);
+
+ nrf_crypto_internal_swap_endian_in_place(p_shared_secret,
+ NRF_CRYPTO_ECDH_CURVE25519_SHARED_SECRET_SIZE);
+
+ return NRF_SUCCESS;
+}
+
+#endif // NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_OBERON_ECC_CURVE25519)
+
+#endif // NRF_MODULE_ENABLED(NRF_CRYPTO) && NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_OBERON)
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/oberon/oberon_backend_ecdh.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/oberon/oberon_backend_ecdh.h
new file mode 100644
index 0000000..85dd0d0
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/oberon/oberon_backend_ecdh.h
@@ -0,0 +1,108 @@
+/**
+ * Copyright (c) 2018 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+
+#ifndef OBERON_BACKEND_ECDH_H__
+#define OBERON_BACKEND_ECDH_H__
+
+#include "sdk_config.h"
+#include "nordic_common.h"
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO) && NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_OBERON)
+
+#include <stdint.h>
+#include "nrf_crypto_ecc.h"
+#include "nrf_crypto_ecdh_shared.h"
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_OBERON_ECC_SECP256R1)
+
+
+/** @internal See @ref nrf_crypto_backend_ecdh_compute_fn_t.
+ */
+ret_code_t nrf_crypto_backend_secp256r1_ecdh_compute(
+ void * p_context,
+ void const * p_private_key,
+ void const * p_public_key,
+ uint8_t * p_shared_secret);
+
+// Context in not used in OBERON backend
+typedef uint32_t nrf_crypto_backend_secp256r1_ecdh_context_t;
+#define NRF_CRYPTO_BACKEND_SECP256R1_ECDH_CONTEXT_SIZE 0
+
+#endif // NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_OBERON_ECC_SECP256R1)
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_OBERON_ECC_CURVE25519)
+
+/** @internal See @ref nrf_crypto_backend_ecdh_compute_fn_t.
+ */
+ret_code_t nrf_crypto_backend_curve25519_ecdh_compute(
+ void * p_context,
+ void const * p_private_key,
+ void const * p_public_key,
+ uint8_t * p_shared_secret);
+
+// Context in not used in OBERON backend
+typedef uint32_t nrf_crypto_backend_curve25519_ecdh_context_t;
+#define NRF_CRYPTO_BACKEND_CURVE25519_ECDH_CONTEXT_SIZE 0
+
+#endif // NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_OBERON_ECC_CURVE25519)
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_OBERON_ECC_ED25519)
+
+// ECDH is not possible for Ed25519
+#define nrf_crypto_backend_ed25519_ecdh_compute NULL
+typedef uint32_t nrf_crypto_backend_ed25519_ecdh_context_t;
+#define NRF_CRYPTO_BACKEND_ED25519_ECDH_CONTEXT_SIZE 0
+
+#endif // NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_OBERON_ECC_ED25519)
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // NRF_MODULE_ENABLED(NRF_CRYPTO) && NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_OBERON)
+
+#endif // OBERON_BACKEND_ECDH_H__
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/oberon/oberon_backend_ecdsa.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/oberon/oberon_backend_ecdsa.c
new file mode 100644
index 0000000..5bbfc18
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/oberon/oberon_backend_ecdsa.c
@@ -0,0 +1,166 @@
+/**
+ * Copyright (c) 2018 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+
+#include "sdk_config.h"
+#include "nordic_common.h"
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO) && NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_OBERON)
+
+#include <stdint.h>
+#include <stdbool.h>
+#include <string.h>
+
+#include "nrf_crypto_ecc.h"
+#include "nrf_crypto_rng.h"
+#include "nrf_crypto_ecdsa.h"
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_OBERON_ECC_SECP256R1)
+
+#include "occ_ecdsa_p256.h"
+
+
+#define OBERON_HASH_SIZE_FOR_SECP256R1 (256 / 8)
+
+
+ret_code_t nrf_crypto_backend_secp256r1_sign(
+ void * p_context,
+ void const * p_private_key,
+ uint8_t const * p_data,
+ size_t data_size,
+ uint8_t * p_signature)
+{
+ int result;
+ uint8_t session_key[32];
+
+ nrf_crypto_backend_secp256r1_private_key_t const * p_prv =
+ (nrf_crypto_backend_secp256r1_private_key_t const *)p_private_key;
+
+ if (data_size < OBERON_HASH_SIZE_FOR_SECP256R1)
+ {
+ return NRF_ERROR_CRYPTO_INPUT_LENGTH;
+ }
+
+ result = nrf_crypto_backend_oberon_ecc_secp256r1_rng(session_key);
+ if (result != NRF_SUCCESS)
+ {
+ return result;
+ }
+
+ result = occ_ecdsa_p256_sign_hash(p_signature, p_data, p_prv->key, session_key);
+
+ return result == 0 ? NRF_SUCCESS : NRF_ERROR_CRYPTO_INTERNAL;
+}
+
+
+ret_code_t nrf_crypto_backend_secp256r1_verify(
+ void * p_context,
+ void const * p_public_key,
+ uint8_t const * p_data,
+ size_t data_size,
+ uint8_t const * p_signature)
+{
+ int result;
+
+ nrf_crypto_backend_secp256r1_public_key_t const * p_pub =
+ (nrf_crypto_backend_secp256r1_public_key_t const *)p_public_key;
+
+ if (data_size < OBERON_HASH_SIZE_FOR_SECP256R1)
+ {
+ return NRF_ERROR_CRYPTO_INPUT_LENGTH;
+ }
+
+ result = occ_ecdsa_p256_verify_hash(p_signature, p_data, p_pub->key);
+
+ if (result != 0)
+ {
+ return NRF_ERROR_CRYPTO_ECDSA_INVALID_SIGNATURE;
+ }
+ return NRF_SUCCESS;
+}
+
+
+#endif // NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_OBERON_ECC_SECP256R1)
+
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_OBERON_ECC_ED25519)
+
+#include "occ_ed25519.h"
+
+
+ret_code_t nrf_crypto_backend_ed25519_sign(
+ void * p_context,
+ void const * p_private_key,
+ uint8_t const * p_data,
+ size_t data_size,
+ uint8_t * p_signature)
+{
+ nrf_crypto_backend_ed25519_private_key_t const * p_prv =
+ (nrf_crypto_backend_ed25519_private_key_t const *)p_private_key;
+
+ occ_ed25519_sign(p_signature, p_data, data_size, p_prv->private_part, p_prv->public_part);
+
+ return NRF_SUCCESS;
+}
+
+ret_code_t nrf_crypto_backend_ed25519_verify(
+ void * p_context,
+ void const * p_public_key,
+ uint8_t const * p_data,
+ size_t data_size,
+ uint8_t const * p_signature)
+{
+ int result;
+
+ nrf_crypto_backend_ed25519_public_key_t const * p_pub =
+ (nrf_crypto_backend_ed25519_public_key_t const *)p_public_key;
+
+ result = occ_ed25519_verify(p_signature, p_data, data_size, p_pub->key);
+
+ if (result != 0)
+ {
+ return NRF_ERROR_CRYPTO_ECDSA_INVALID_SIGNATURE;
+ }
+ return NRF_SUCCESS;
+}
+
+#endif // NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_OBERON_ECC_ED25519)
+
+#endif // NRF_MODULE_ENABLED(NRF_CRYPTO) && NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_OBERON)
+
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/oberon/oberon_backend_ecdsa.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/oberon/oberon_backend_ecdsa.h
new file mode 100644
index 0000000..070a8cf
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/oberon/oberon_backend_ecdsa.h
@@ -0,0 +1,141 @@
+/**
+ * Copyright (c) 2018 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+
+#ifndef OBERON_BACKEND_ECDSA_H__
+#define OBERON_BACKEND_ECDSA_H__
+
+#include "sdk_config.h"
+#include "nordic_common.h"
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO) && NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_OBERON)
+
+#include <stdint.h>
+#include "nrf_crypto_ecc_shared.h"
+#include "nrf_crypto_ecdsa_shared.h"
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_OBERON_ECC_SECP256R1)
+
+
+/** @internal See @ref nrf_crypto_backend_ecdsa_sign_fn_t.
+ */
+ret_code_t nrf_crypto_backend_secp256r1_sign(
+ void * p_context,
+ void const * p_private_key,
+ uint8_t const * p_data,
+ size_t data_size,
+ uint8_t * p_signature);
+
+
+/** @internal See @ref nrf_crypto_backend_ecdsa_verify_fn_t.
+ */
+ret_code_t nrf_crypto_backend_secp256r1_verify(
+ void * p_context,
+ void const * p_public_key,
+ uint8_t const * p_data,
+ size_t data_size,
+ uint8_t const * p_signature);
+
+
+#define NRF_CRYPTO_BACKEND_SECP256R1_SIGN_CONTEXT_SIZE 0
+#define NRF_CRYPTO_BACKEND_SECP256R1_VERIFY_CONTEXT_SIZE 0
+typedef uint32_t nrf_crypto_backend_secp256r1_sign_context_t;
+typedef uint32_t nrf_crypto_backend_secp256r1_verify_context_t;
+
+#endif
+
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_OBERON_ECC_CURVE25519)
+
+// Curve25519 is not designed for ECDSA
+#define NRF_CRYPTO_BACKEND_CURVE25519_SIGN_CONTEXT_SIZE 0
+#define NRF_CRYPTO_BACKEND_CURVE25519_VERIFY_CONTEXT_SIZE 0
+typedef uint32_t nrf_crypto_backend_curve25519_sign_context_t;
+typedef uint32_t nrf_crypto_backend_curve25519_verify_context_t;
+#define nrf_crypto_backend_curve25519_sign NULL
+#define nrf_crypto_backend_curve25519_verify NULL
+
+#endif
+
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_OBERON_ECC_ED25519)
+
+
+/** @internal See @ref nrf_crypto_backend_ecdsa_sign_fn_t.
+ */
+ret_code_t nrf_crypto_backend_ed25519_sign(
+ void * p_context,
+ void const * p_private_key,
+ uint8_t const * p_data,
+ size_t data_size,
+ uint8_t * p_signature);
+
+
+/** @internal See @ref nrf_crypto_backend_ecdsa_verify_fn_t.
+ */
+ret_code_t nrf_crypto_backend_ed25519_verify(
+ void * p_context,
+ void const * p_public_key,
+ uint8_t const * p_data,
+ size_t data_size,
+ uint8_t const * p_signature);
+
+
+#define NRF_CRYPTO_BACKEND_ED25519_SIGN_CONTEXT_SIZE 0
+#define NRF_CRYPTO_BACKEND_ED25519_VERIFY_CONTEXT_SIZE 0
+typedef uint32_t nrf_crypto_backend_ed25519_sign_context_t;
+typedef uint32_t nrf_crypto_backend_ed25519_verify_context_t;
+
+
+#endif
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // NRF_MODULE_ENABLED(NRF_CRYPTO) && NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_OBERON)
+
+#endif // OBERON_BACKEND_ECDSA_H__
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/oberon/oberon_backend_hash.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/oberon/oberon_backend_hash.c
new file mode 100644
index 0000000..cf90e51
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/oberon/oberon_backend_hash.c
@@ -0,0 +1,184 @@
+/**
+ * Copyright (c) 2018 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+
+#include "sdk_common.h"
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO) && NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_OBERON)
+
+#include "oberon_backend_hash.h"
+#include "crys_hash.h"
+#include "crys_hash_error.h"
+#include "nrf_crypto_init.h"
+#include "nrf_crypto_types.h"
+#include "nrf_crypto_error.h"
+#include "nrf_crypto_hash_shared.h"
+#include "sdk_macros.h"
+#include "occ_sha256.h"
+#include "occ_sha512.h"
+#include "nrf_log.h"
+#include "nrf_assert.h"
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_OBERON_HASH_SHA256)
+
+static ret_code_t oberon_backend_hash_sha256_init(void * const p_context)
+{
+ // No parameter testing on this level.
+ // This has been done on upper level.
+
+ occ_sha256_ctx * p_backend_context
+ = &(((nrf_crypto_backend_hash_sha256_context_t *)p_context)->context);
+
+ occ_sha256_init(p_backend_context);
+
+ return NRF_SUCCESS;
+}
+
+
+static uint32_t oberon_backend_hash_sha256_update(void * const p_context,
+ uint8_t const * p_data,
+ size_t size)
+{
+ // Limited parameter testing on this level.
+ // This has been done on upper level.
+
+ occ_sha256_ctx * p_backend_context
+ = &(((nrf_crypto_backend_hash_sha256_context_t *)p_context)->context);
+
+ occ_sha256_update(p_backend_context, p_data, size);
+
+ return NRF_SUCCESS;
+}
+
+
+static uint32_t oberon_backend_hash_sha256_finalize(void * const p_context,
+ uint8_t * p_digest,
+ size_t * const p_digest_size)
+{
+ // Limited parameter testing on this level.
+ // This has been done on upper level.
+
+ occ_sha256_ctx * p_backend_context
+ = &(((nrf_crypto_backend_hash_sha256_context_t *)p_context)->context);
+
+ occ_sha256_final(p_digest, p_backend_context);
+
+ *p_digest_size = NRF_CRYPTO_HASH_SIZE_SHA256;
+
+ return NRF_SUCCESS;
+}
+
+
+const nrf_crypto_hash_info_t g_nrf_crypto_hash_sha256_info =
+{
+ .init_fn = oberon_backend_hash_sha256_init,
+ .update_fn = oberon_backend_hash_sha256_update,
+ .finalize_fn = oberon_backend_hash_sha256_finalize,
+ .digest_size = NRF_CRYPTO_HASH_SIZE_SHA256,
+ .context_size = sizeof(nrf_crypto_backend_hash_sha256_context_t),
+ .hash_mode = NRF_CRYPTO_HASH_MODE_SHA256
+};
+
+
+#endif // NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_OBERON_HASH_SHA256)
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_OBERON_HASH_SHA512)
+
+
+static ret_code_t oberon_backend_hash_sha512_init(void * p_context)
+{
+ // No parameter testing on this level.
+ // This has been done on upper level.
+
+ occ_sha512_ctx * p_backend_context
+ = &(((nrf_crypto_backend_hash_sha512_context_t *)p_context)->context);
+
+ occ_sha512_init(p_backend_context);
+
+ return NRF_SUCCESS;
+}
+
+
+static ret_code_t oberon_backend_hash_sha512_update(void * const p_context,
+ uint8_t const * p_data,
+ size_t size)
+{
+ // Limited parameter testing on this level.
+ // This has been done on upper level.
+
+ occ_sha512_ctx * p_backend_context
+ = &(((nrf_crypto_backend_hash_sha512_context_t *)p_context)->context);
+
+ occ_sha512_update(p_backend_context, p_data, size);
+
+ return NRF_SUCCESS;
+}
+
+
+static ret_code_t oberon_backend_hash_sha512_finalize(void * const p_context,
+ uint8_t * p_digest,
+ size_t * const p_digest_size)
+{
+ // Limited parameter testing on this level.
+ // This has been done on upper level.
+
+ occ_sha512_ctx * p_backend_context
+ = &(((nrf_crypto_backend_hash_sha512_context_t *)p_context)->context);
+
+ occ_sha512_final(p_digest, p_backend_context);
+
+ *p_digest_size = NRF_CRYPTO_HASH_SIZE_SHA512;
+
+ return NRF_SUCCESS;
+}
+
+
+const nrf_crypto_hash_info_t g_nrf_crypto_hash_sha512_info =
+{
+ .init_fn = oberon_backend_hash_sha512_init,
+ .update_fn = oberon_backend_hash_sha512_update,
+ .finalize_fn = oberon_backend_hash_sha512_finalize,
+ .digest_size = NRF_CRYPTO_HASH_SIZE_SHA512,
+ .context_size = sizeof(nrf_crypto_backend_hash_sha512_context_t),
+ .hash_mode = NRF_CRYPTO_HASH_MODE_SHA512
+};
+
+#endif // NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_OBERON_HASH_SHA512)
+
+#endif // NRF_MODULE_ENABLED(NRF_CRYPTO) && NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_OBERON)
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/oberon/oberon_backend_hash.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/oberon/oberon_backend_hash.h
new file mode 100644
index 0000000..534f0ca
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/oberon/oberon_backend_hash.h
@@ -0,0 +1,123 @@
+/**
+ * Copyright (c) 2018 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+
+#ifndef OBERON_BACKEND_HASH_H__
+#define OBERON_BACKEND_HASH_H__
+
+/** @file
+ *
+ * @defgroup nrf_crypto_oberon_backend_hash Oberon backend hash
+ * @{
+ * @ingroup nrf_crypto_oberon_backend
+ *
+ * @brief Hash functionality provided by the Oberon nrf_crypto backend.
+ */
+#include "sdk_common.h"
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_OBERON)
+
+#include "sdk_errors.h"
+#include "nrf_crypto_hash_shared.h"
+#include "occ_sha256.h"
+#include "occ_sha512.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_OBERON_HASH_SHA256)
+
+// Flag that nrf_crypto_hash frontend can be compiled
+#undef NRF_CRYPTO_HASH_ENABLED
+#define NRF_CRYPTO_HASH_ENABLED 1
+
+// Duplicate backend enabled test for SHA-256
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_HASH_SHA256)
+#error "Duplicate definition of SHA-256. More than one backend enabled");
+#endif
+
+// Flag that SHA-256 is enabled in backend
+#define NRF_CRYPTO_HASH_SHA256_ENABLED 1
+
+
+/**@brief nrf_crypto_hash context for SHA-256 in nrf_crypto Oberon backend. */
+typedef struct
+{
+ nrf_crypto_hash_internal_context_t header; /**< Common header for context. */
+ occ_sha256_ctx context; /**< Hash context internal to Oberon. */
+} nrf_crypto_backend_hash_sha256_context_t;
+
+
+#endif // NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_OBERON_HASH_SHA256)
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_OBERON_HASH_SHA512)
+
+// Flag that nrf_crypto_hash frontend can be compiled
+#undef NRF_CRYPTO_HASH_ENABLED
+#define NRF_CRYPTO_HASH_ENABLED 1
+
+// Duplicate backend enabled test for SHA-512
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_HASH_SHA512)
+#error "Duplicate definition of SHA-512. More than one backend enabled");
+#endif
+
+// Flag that SHA-512 is enabled in backend
+#define NRF_CRYPTO_HASH_SHA512_ENABLED 1
+
+
+/**@brief nrf_crypto_hash context for SHA-512 in nrf_crypto Oberon backend. */
+typedef struct
+{
+ nrf_crypto_hash_internal_context_t header; /**< Common header for context. */
+ occ_sha512_ctx context; /**< Hash context internal to Oberon. */
+} nrf_crypto_backend_hash_sha512_context_t;
+
+
+#endif // NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_OBERON_HASH_SHA512)
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_OBERON)
+
+/**@} */
+
+#endif // OBERON_BACKEND_HASH_H__
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/oberon/oberon_backend_hmac.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/oberon/oberon_backend_hmac.c
new file mode 100644
index 0000000..a89c4ac
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/oberon/oberon_backend_hmac.c
@@ -0,0 +1,169 @@
+/**
+ * Copyright (c) 2018 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+
+#include "sdk_common.h"
+#if NRF_MODULE_ENABLED(NRF_CRYPTO) && NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_OBERON)
+
+#include "nrf_log.h"
+#include "nrf_crypto_error.h"
+#include "nrf_crypto_types.h"
+#include "oberon_backend_hmac.h"
+
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_OBERON_HMAC_SHA256)
+
+#define HMAC_SHA256_BLOCK_SIZE 64
+
+static ret_code_t oberon_backend_hmac_init_sha256(void * const p_context,
+ uint8_t const * p_key,
+ size_t key_size)
+{
+ nrf_crypto_backend_oberon_hmac_sha256_context_t * p_ctx =
+ (nrf_crypto_backend_oberon_hmac_sha256_context_t *)p_context;
+
+ occ_hmac_sha256_init(&p_ctx->oberon_ctx, p_key, key_size);
+
+ return NRF_SUCCESS;
+}
+
+
+static ret_code_t oberon_backend_hmac_update_sha256(void * const p_context,
+ uint8_t const * p_data,
+ size_t size)
+{
+ nrf_crypto_backend_oberon_hmac_sha256_context_t * p_ctx =
+ (nrf_crypto_backend_oberon_hmac_sha256_context_t *)p_context;
+
+ occ_hmac_sha256_update(&p_ctx->oberon_ctx, p_data, size);
+
+ return NRF_SUCCESS;
+}
+
+
+static ret_code_t oberon_backend_hmac_finalize_sha256(void * const p_context,
+ uint8_t * p_digest,
+ size_t * const p_size)
+{
+ nrf_crypto_backend_oberon_hmac_sha256_context_t * const p_ctx =
+ (nrf_crypto_backend_oberon_hmac_sha256_context_t *)p_context;
+
+ occ_hmac_sha256_final(p_digest, &p_ctx->oberon_ctx);
+
+ // Assume operation was successful and update the digest size accordingly.
+ *p_size = p_ctx->header.p_info->digest_size;
+
+ return NRF_SUCCESS;
+}
+
+
+// Information structure for HMAC SHA256 using Oberon backend.
+const nrf_crypto_hmac_info_t g_nrf_crypto_hmac_sha256_info =
+{
+ .init_fn = oberon_backend_hmac_init_sha256,
+ .update_fn = oberon_backend_hmac_update_sha256,
+ .finalize_fn = oberon_backend_hmac_finalize_sha256,
+ .digest_size = NRF_CRYPTO_HASH_SIZE_SHA256,
+ .context_size = sizeof(nrf_crypto_backend_oberon_hmac_sha256_context_t),
+ .type = NRF_CRYPTO_HMAC_SHA256_TYPE
+};
+
+#endif // NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_OBERON_HMAC_SHA256)
+
+
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_OBERON_HMAC_SHA512)
+
+#define HMAC_SHA512_BLOCK_SIZE 128
+
+static ret_code_t oberon_backend_hmac_init_sha512(void * const p_context,
+ uint8_t const * p_key,
+ size_t key_size)
+{
+ nrf_crypto_backend_oberon_hmac_sha512_context_t * p_ctx =
+ (nrf_crypto_backend_oberon_hmac_sha512_context_t *)p_context;
+
+ occ_hmac_sha512_init(&p_ctx->oberon_ctx, p_key, key_size);
+
+ return NRF_SUCCESS;
+}
+
+
+static ret_code_t oberon_backend_hmac_update_sha512(void * const p_context,
+ uint8_t const * p_data,
+ size_t size)
+{
+ nrf_crypto_backend_oberon_hmac_sha512_context_t * p_ctx =
+ (nrf_crypto_backend_oberon_hmac_sha512_context_t *)p_context;
+
+ occ_hmac_sha512_update(&p_ctx->oberon_ctx, p_data, size);
+
+ return NRF_SUCCESS;
+}
+
+
+static ret_code_t oberon_backend_hmac_finalize_sha512(void * const p_context,
+ uint8_t * p_digest,
+ size_t * const p_size)
+{
+ nrf_crypto_backend_oberon_hmac_sha512_context_t * const p_ctx =
+ (nrf_crypto_backend_oberon_hmac_sha512_context_t *)p_context;
+
+ occ_hmac_sha512_final(p_digest, &p_ctx->oberon_ctx);
+
+ // Assume operation was successful and update the digest size accordingly.
+ *p_size = p_ctx->header.p_info->digest_size;
+
+ return NRF_SUCCESS;
+}
+
+
+// Information structure for HMAC SHA512 using Oberon backend.
+const nrf_crypto_hmac_info_t g_nrf_crypto_hmac_sha512_info =
+{
+ .init_fn = oberon_backend_hmac_init_sha512,
+ .update_fn = oberon_backend_hmac_update_sha512,
+ .finalize_fn = oberon_backend_hmac_finalize_sha512,
+ .digest_size = NRF_CRYPTO_HASH_SIZE_SHA512,
+ .context_size = sizeof(nrf_crypto_backend_oberon_hmac_sha512_context_t),
+ .type = NRF_CRYPTO_HMAC_SHA512_TYPE
+};
+
+#endif // NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_OBERON_HMAC_SHA512)
+#endif // NRF_MODULE_ENABLED(NRF_CRYPTO) && NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_OBERON)
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/oberon/oberon_backend_hmac.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/oberon/oberon_backend_hmac.h
new file mode 100644
index 0000000..d32274f
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/backend/oberon/oberon_backend_hmac.h
@@ -0,0 +1,136 @@
+/**
+ * Copyright (c) 2018 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+
+#ifndef OBERON_BACKEND_HMAC_H__
+#define OBERON_BACKEND_HMAC_H__
+
+/** @file
+ *
+ * @defgroup nrf_crypto_oberon_backend_hmac Oberon backend for HMAC
+ * @{
+ * @ingroup nrf_crypto_oberon_backend
+ *
+ * @brief Backend wrapper for Oberon. None of these types should be used directly by the
+ * application.
+ */
+
+#include "sdk_common.h"
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_OBERON) && \
+ ( NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_OBERON_HMAC_SHA256) || \
+ NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_OBERON_HMAC_SHA512) )
+
+#include "nrf_crypto_hmac_shared.h"
+#include "occ_hmac_sha256.h"
+#include "occ_hmac_sha512.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#undef NRF_CRYPTO_HMAC_ENABLED
+#define NRF_CRYPTO_HMAC_ENABLED 1
+
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_OBERON_HMAC_SHA256)
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_HMAC_SHA256)
+#error "Duplicate definition of HMAC SHA-256. More than one backend enabled"
+#endif // NRF_CRYPTO_HMAC_SHA256_ENABLED
+#define NRF_CRYPTO_HMAC_SHA256_ENABLED 1
+
+/**
+ * @internal @brief Internal context object used by the Oberon backend wrapper for HMAC SHA256.
+ *
+ * @note This should never be used directly. Use @ref nrf_crypto_backend_hmac_sha256_context_t
+ * instead.
+ */
+typedef struct
+{
+ nrf_crypto_hmac_internal_context_t header; //!< Internal nrf_crypto_hmac context.
+ occ_hmac_sha256_ctx oberon_ctx; //!< Oberon context object.
+} nrf_crypto_backend_oberon_hmac_sha256_context_t;
+
+
+/**
+ * @internal @brief Context for HMAC SHA256 using Oberon backend.
+ */
+typedef nrf_crypto_backend_oberon_hmac_sha256_context_t nrf_crypto_backend_hmac_sha256_context_t;
+
+
+#endif // NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_OBERON_HMAC_SHA256)
+
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_OBERON_HMAC_SHA512)
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_HMAC_SHA512)
+#error "Duplicate definition of HMAC SHA-512. More than one backend enabled"
+#endif // NRF_CRYPTO_HMAC_SHA512_ENABLED
+#define NRF_CRYPTO_HMAC_SHA512_ENABLED 1
+
+/**
+ * @internal @brief Internal context object used by the Oberon backend wrapper for HMAC SHA512.
+ *
+ * @note This should never be used directly. Use @ref nrf_crypto_backend_hmac_sha512_context_t
+ * instead.
+ */
+typedef struct
+{
+ nrf_crypto_hmac_internal_context_t header; //!< Internal nrf_crypto_hmac context header.
+ occ_hmac_sha512_ctx oberon_ctx; //!< Oberon context object.
+} nrf_crypto_backend_oberon_hmac_sha512_context_t;
+
+/**
+ * @internal @brief Context for HMAC SHA512 using Oberon backend.
+ */
+typedef nrf_crypto_backend_oberon_hmac_sha512_context_t nrf_crypto_backend_hmac_sha512_context_t;
+
+
+#endif // NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_OBERON_HMAC_SHA512)
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_OBERON && ( NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_OBERON_HMAC_SHA256 || NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_OBERON_HMAC_SHA512) )
+
+/**@} */
+
+#endif // OBERON_BACKEND_HMAC_H__
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/nrf_crypto.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/nrf_crypto.h
new file mode 100644
index 0000000..e03ab04
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/nrf_crypto.h
@@ -0,0 +1,77 @@
+/**
+ * Copyright (c) 2016 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+
+#ifndef NRF_CRYPTO_H__
+#define NRF_CRYPTO_H__
+
+/**
+ * @defgroup nrf_crypto Cryptography library
+ * @ingroup app_common
+ * @{
+ *
+ * @brief Cryptography library (nrf_crypto).
+ *
+ * @details The cryptography library provides cryptographic functionality in a portable way.
+ *
+ * @note The functions in this API can run in software or hardware, depending on the supported features of your SoC and the configuration of nrf_crypto backend in the application.
+ * See @ref lib_crypto_config for details on changing the nrf_crypto backend.
+ *
+ * @}
+ *
+ */
+
+
+
+#include <stdint.h>
+#include "nrf_crypto_init.h"
+#include "nrf_crypto_types.h"
+#include "nrf_crypto_mem.h"
+#include "nrf_crypto_ecc.h"
+#include "nrf_crypto_hash.h"
+#include "nrf_crypto_ecdsa.h"
+#include "nrf_crypto_ecdh.h"
+#include "nrf_crypto_rng.h"
+#include "nrf_crypto_aes.h"
+#include "nrf_crypto_aead.h"
+#include "nrf_crypto_hmac.h"
+#include "nrf_crypto_hkdf.h"
+
+
+#endif // NRF_CRYPTO_H__
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/nrf_crypto_aead.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/nrf_crypto_aead.c
new file mode 100644
index 0000000..9459bc6
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/nrf_crypto_aead.c
@@ -0,0 +1,159 @@
+/**
+ * Copyright (c) 2018 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+
+#include "sdk_common.h"
+#if NRF_MODULE_ENABLED(NRF_CRYPTO)
+
+#include "nrf_crypto_error.h"
+#include "nrf_crypto_aead.h"
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_AEAD)
+
+static ret_code_t context_verify(nrf_crypto_aead_internal_context_t const * p_context)
+{
+ VERIFY_TRUE((p_context != NULL), NRF_ERROR_CRYPTO_CONTEXT_NULL);
+
+ VERIFY_TRUE((p_context->init_value == NRF_CRYPTO_AEAD_INIT_MAGIC_VALUE),
+ NRF_ERROR_CRYPTO_CONTEXT_NOT_INITIALIZED);
+
+ return NRF_SUCCESS;
+}
+
+
+ret_code_t nrf_crypto_aead_init(nrf_crypto_aead_context_t * const p_context,
+ nrf_crypto_aead_info_t const * const p_info,
+ uint8_t * p_key)
+{
+ ret_code_t ret_val;
+
+ nrf_crypto_aead_internal_context_t * p_int_context =
+ (nrf_crypto_aead_internal_context_t *)p_context;
+
+ VERIFY_TRUE((p_info != NULL), NRF_ERROR_CRYPTO_INPUT_NULL);
+
+ VERIFY_TRUE((p_key != NULL), NRF_ERROR_CRYPTO_INPUT_NULL);
+
+ ret_val = context_verify(p_int_context);
+ VERIFY_TRUE((ret_val == NRF_SUCCESS) || (ret_val == NRF_ERROR_CRYPTO_CONTEXT_NOT_INITIALIZED),
+ ret_val);
+
+ p_int_context->init_value = NRF_CRYPTO_AEAD_INIT_MAGIC_VALUE;
+ p_int_context->p_info = p_info;
+
+ ret_val = p_info->init_fn(p_context, p_key);
+
+ if (ret_val != NRF_SUCCESS)
+ {
+ p_int_context->init_value = 0;
+ }
+
+ return ret_val;
+}
+
+ret_code_t nrf_crypto_aead_uninit(void * const p_context)
+{
+ ret_code_t ret_val;
+
+ nrf_crypto_aead_internal_context_t * p_int_context =
+ (nrf_crypto_aead_internal_context_t *)p_context;
+
+ ret_val = context_verify(p_int_context);
+ VERIFY_SUCCESS(ret_val);
+
+ ret_val = p_int_context->p_info->uninit_fn(p_context);
+
+ p_int_context->init_value = 0;
+
+ return ret_val;
+}
+
+ret_code_t nrf_crypto_aead_crypt(nrf_crypto_aead_context_t * const p_context,
+ nrf_crypto_operation_t operation,
+ uint8_t * p_nonce,
+ uint8_t nonce_size,
+ uint8_t * p_adata,
+ size_t adata_size,
+ uint8_t * p_data_in,
+ size_t data_in_size,
+ uint8_t * p_data_out,
+ uint8_t * p_mac,
+ uint8_t mac_size)
+{
+ ret_code_t ret_val;
+
+ nrf_crypto_aead_internal_context_t * p_int_context =
+ (nrf_crypto_aead_internal_context_t *)p_context;
+
+ ret_val = context_verify(p_int_context);
+ VERIFY_SUCCESS(ret_val);
+
+ VERIFY_FALSE(((p_nonce == NULL) && (nonce_size != 0)),
+ NRF_ERROR_CRYPTO_INPUT_NULL);
+
+ /* If mac_size == 0 MAC is updated and not stored under p_mac */
+ VERIFY_FALSE(((p_mac == NULL) && (mac_size != 0)),
+ NRF_ERROR_CRYPTO_INPUT_NULL);
+
+ VERIFY_FALSE(((p_adata == NULL) && (adata_size != 0)),
+ NRF_ERROR_CRYPTO_INPUT_NULL);
+
+ VERIFY_FALSE(((p_data_in == NULL) && (data_in_size != 0)),
+ NRF_ERROR_CRYPTO_INPUT_NULL);
+
+ VERIFY_FALSE(((p_data_out == NULL) && (data_in_size != 0)),
+ NRF_ERROR_CRYPTO_OUTPUT_NULL);
+
+ ret_val = p_int_context->p_info->crypt_fn(p_context,
+ operation,
+ p_nonce,
+ nonce_size,
+ p_adata,
+ adata_size,
+ p_data_in,
+ data_in_size,
+ p_data_out,
+ p_mac,
+ mac_size);
+ return ret_val;
+}
+
+#endif // NRF_MODULE_ENABLED(NRF_CRYPTO_AEAD)
+#endif // NRF_MODULE_ENABLED(NRF_CRYPTO)
+
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/nrf_crypto_aead.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/nrf_crypto_aead.h
new file mode 100644
index 0000000..a0de689
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/nrf_crypto_aead.h
@@ -0,0 +1,235 @@
+/**
+ * Copyright (c) 2018 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+
+#ifndef NRF_CRYPTO_AEAD_H__
+#define NRF_CRYPTO_AEAD_H__
+
+/** @file
+ *
+ * @defgroup nrf_crypto_aead AEAD (Authenticated Encryption with Associated Data) related
+ * functions.
+ * @{
+ * @ingroup nrf_crypto
+ *
+ * @brief Provides AEAD related functionality through nrf_crypto.
+ */
+
+#include "sdk_common.h"
+#if NRF_MODULE_ENABLED(NRF_CRYPTO) || defined(__SDK_DOXYGEN__)
+
+#include <stdint.h>
+#include "nrf_crypto_types.h"
+#include "nrf_crypto_aead_shared.h"
+#include "nrf_crypto_aead_backend.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**@brief External variable declaration to the info structure for AES CCM mode with a 128-bit key.
+*
+* @note The variable is defined in the nrf_crypto backend that is enabled in the @c sdk_config file.
+*
+*/
+extern const nrf_crypto_aead_info_t g_nrf_crypto_aes_ccm_128_info;
+
+/**@brief External variable declaration to the info structure for AES CCM mode with a 192-bit key.
+*
+* @note The variable is defined in the nrf_crypto backend that is enabled in the @c sdk_config file.
+*
+*/
+extern const nrf_crypto_aead_info_t g_nrf_crypto_aes_ccm_192_info;
+
+/**@brief External variable declaration to the info structure for AES CCM mode with a 256-bit key.
+*
+* @note The variable is defined in the nrf_crypto backend that is enabled in the @c sdk_config file.
+*
+*/
+extern const nrf_crypto_aead_info_t g_nrf_crypto_aes_ccm_256_info;
+
+/**@brief External variable declaration to the info structure for AES CCM* mode with a 128-bit key.
+*
+* @note The variable is defined in the nrf_crypto backend that is enabled in the @c sdk_config file.
+*
+*/
+extern const nrf_crypto_aead_info_t g_nrf_crypto_aes_ccm_star_128_info;
+
+/**@brief External variable declaration to the info structure for AES EAX mode with a 128-bit key.
+*
+* @note The variable is defined in the nrf_crypto backend that is enabled in the @c sdk_config file.
+*
+*/
+extern const nrf_crypto_aead_info_t g_nrf_crypto_aes_eax_128_info;
+
+/**@brief External variable declaration to the info structure for AES EAX mode with a 192-bit key.
+*
+* @note The variable is defined in the nrf_crypto backend that is enabled in the @c sdk_config file.
+*
+*/
+extern const nrf_crypto_aead_info_t g_nrf_crypto_aes_eax_192_info;
+
+/**@brief External variable declaration to the info structure for AES EAX mode with a 256-bit key.
+*
+* @note The variable is defined in the nrf_crypto backend that is enabled in the @c sdk_config file.
+*
+*/
+extern const nrf_crypto_aead_info_t g_nrf_crypto_aes_eax_256_info;
+
+/**@brief External variable declaration to the info structure for AES GCM mode with a 128-bit key.
+*
+* @note The variable is defined in the nrf_crypto backend that is enabled in the @ref sdk_config.
+*
+*/
+extern const nrf_crypto_aead_info_t g_nrf_crypto_aes_gcm_128_info;
+
+/**@brief External variable declaration to the info structure for AES GCM mode with a 192-bit key.
+*
+* @note The variable is defined in the nrf_crypto backend that is enabled in the @ref sdk_config.
+*
+*/
+extern const nrf_crypto_aead_info_t g_nrf_crypto_aes_gcm_192_info;
+
+/**@brief External variable declaration to the info structure for AES GCM mode with a 256-bit key.
+*
+* @note The variable is defined in the nrf_crypto backend that is enabled in the @ref sdk_config.
+*
+*/
+extern const nrf_crypto_aead_info_t g_nrf_crypto_aes_gcm_256_info;
+
+/**@brief External variable declaration to the info structure for CHACHA-POLY mode with a 256-bit
+* key.
+*
+* @note The variable is defined in the nrf_crypto backend that is enabled in the @ref sdk_config.
+*
+*/
+extern const nrf_crypto_aead_info_t g_nrf_crypto_chacha_poly_256_info;
+
+
+/**
+ * @brief Context type for AEAD.
+ *
+ * @note The size of this type is scaled for the largest AEAD backend context that is
+ * enabled in @ref sdk_config.
+ */
+typedef nrf_crypto_backend_aead_context_t nrf_crypto_aead_context_t;
+
+
+/**@brief Function for initializing the AEAD calculation context.
+ *
+ * @param[in] p_context Pointer to the context object. It must be a context type associated with
+ * the object provided in the p_info parameter or other memory that can
+ * hold that context type.
+ * @param[in] p_info Pointer to structure holding information about: selected AES AEAD mode,
+ * and key size.
+ * @param[in] p_key Pointer to AEAD mode key.
+ *
+ * @retval NRF_SUCCESS Context was successfully initialized.
+ */
+ret_code_t nrf_crypto_aead_init(nrf_crypto_aead_context_t * const p_context,
+ nrf_crypto_aead_info_t const * const p_info,
+ uint8_t * p_key);
+
+/**@brief Function for uninitializing the AEAD calculation context.
+ *
+ * @param[in] p_context Pointer to the context object. It must be initialized before function call.
+ *
+ * @retval NRF_SUCCESS Context was successfully uninitialized.
+ */
+ret_code_t nrf_crypto_aead_uninit(void * const p_context);
+
+/**@brief Integrated encryption / decryption function.
+ *
+ * @param[in] p_context Context object. Must be initialized before the call.
+ * @param[in] operation Parameter indicating whether an encrypt (NRF_CRYPTO_ENCRYPT) or
+ * a decrypt (NRF_CRYPTO_DECRYPT) operation shall be performed.
+ * @param[in] p_nonce Pointer to nonce. For nonce_size == 0 p_nonce can be NULL.
+ * @param[in] nonce_size Nonce byte size. Valid values for supported modes:
+ * - CCM [7 ... 13]
+ * - CCM* [13]
+ * - EAX nonce size can be any length
+ * - GCM nonce size can be any length
+ * - CHACHA-POLY [12]
+ * @param[in] p_adata Pointer to additional authenticated data (adata).
+ * @param[in] adata_size Length of additional authenticated data in bytes.
+ * For CHACHA-POLY mode must be > 0.
+ * @param[in] p_data_in Pointer to the input data buffer for encryption or decryption.
+ * @param[in] data_in_size Length of the data in p_data_in buffer in bytes. Size of the
+ * p_data_out buffer must not be smaller than this value.
+ * When selecting CC310 backend data_in_size value shall be limited
+ * to 65535 bytes. Data out buffer must be at least the same length.
+ * @param[out] p_data_out Pointer to the output buffer where encrypted or decrypted data
+ * will be stored. Must be at least 'data_in_size' bytes wide.
+ * - GCM: On encryption, the p_data_out buffer can be the same as
+ * the p_data_in buffer.
+ * On decryption, the p_data_out buffer cannot be the same
+ * as p_data_in buffer. If buffers overlap, the p_data_out
+ * buffer must trail at least 8 bytes behind the p_data_in
+ * buffer.
+ * @param[out] p_mac Pointer to the MAC result buffer. Fo mac_size == 0 p_mac can be NULL.
+ * @param[in] mac_size MAC byte size. Valid values for supported modes:
+ * -CCM [4, 6, 8, 10, 12, 14, 16]
+ * -CCM* [0, 4, 8, 16]
+ * -EAX [1 ... 16]
+ * -GCM [4 ... 16]
+ * -CHACHA-POLY [16]
+ *
+ * @retval NRF_SUCCESS Message was successfully encrypted.
+ */
+ret_code_t nrf_crypto_aead_crypt(nrf_crypto_aead_context_t * const p_context,
+ nrf_crypto_operation_t operation,
+ uint8_t * p_nonce,
+ uint8_t nonce_size,
+ uint8_t * p_adata,
+ size_t adata_size,
+ uint8_t * p_data_in,
+ size_t data_in_size,
+ uint8_t * p_data_out,
+ uint8_t * p_mac,
+ uint8_t mac_size);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // #if NRF_MODULE_ENABLED(NRF_CRYPTO) || defined(__SDK_DOXYGEN__)
+
+/** @} */
+
+#endif // NRF_CRYPTO_AEAD_H__
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/nrf_crypto_aead_backend.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/nrf_crypto_aead_backend.h
new file mode 100644
index 0000000..fd792dd
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/nrf_crypto_aead_backend.h
@@ -0,0 +1,100 @@
+/**
+ * Copyright (c) 2018 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+
+#ifndef NRF_CRYPTO_AEAD_BACKEND_H__
+#define NRF_CRYPTO_AEAD_BACKEND_H__
+
+#include "cc310_backend_aes_aead.h"
+#include "cc310_backend_chacha_poly_aead.h"
+#include "cifra_backend_aes_aead.h"
+#include "mbedtls_backend_aes_aead.h"
+#include "oberon_backend_chacha_poly_aead.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**@internal @brief Fallback type for AES CCM context (if no backend is enabled).
+ */
+#if !NRF_MODULE_ENABLED(NRF_CRYPTO_AES_CCM)
+typedef nrf_crypto_aead_internal_context_t nrf_crypto_backend_aes_ccm_context_t;
+#endif
+
+/**@internal @brief Fallback type for AES CCM* context (if no backend is enabled).
+ */
+#if !NRF_MODULE_ENABLED(NRF_CRYPTO_AES_CCM_STAR)
+typedef nrf_crypto_aead_internal_context_t nrf_crypto_backend_aes_ccm_star_context_t;
+#endif
+
+/**@internal @brief Fallback type for AES EAX context (if no backend is enabled).
+ */
+#if !NRF_MODULE_ENABLED(NRF_CRYPTO_AES_EAX)
+typedef nrf_crypto_aead_internal_context_t nrf_crypto_backend_aes_eax_context_t;
+#endif
+
+/**@internal @brief Fallback type for AES GCM context (if no backend is enabled).
+ */
+#if !NRF_MODULE_ENABLED(NRF_CRYPTO_AES_GCM)
+typedef nrf_crypto_aead_internal_context_t nrf_crypto_backend_aes_gcm_context_t;
+#endif
+
+/**@internal @brief Fallback type for CHACHA-POLY context (if no backend is enabled).
+ */
+#if !NRF_MODULE_ENABLED(NRF_CRYPTO_CHACHA_POLY)
+typedef nrf_crypto_aead_internal_context_t nrf_crypto_backend_chacha_poly_context_t;
+#endif
+
+/** @internal @brief Union holding a AEAD context. */
+typedef union
+{
+ nrf_crypto_backend_aes_ccm_context_t ccm_context; /**< @brief Holds context for AES CCM. */
+ nrf_crypto_backend_aes_ccm_star_context_t ccm_star_context; /**< @brief Holds context for AES CCM*. */
+ nrf_crypto_backend_aes_eax_context_t eax_context; /**< @brief Holds context for AES EAX. */
+ nrf_crypto_backend_aes_gcm_context_t gcm_context; /**< @brief Holds context for AES GCM. */
+
+ nrf_crypto_backend_chacha_poly_context_t chacha_poly_context; /**< @brief Holds context for ChaCha-Poly. */
+} nrf_crypto_backend_aead_context_t;
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // NRF_CRYPTO_AEAD_BACKEND_H__
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/nrf_crypto_aead_shared.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/nrf_crypto_aead_shared.h
new file mode 100644
index 0000000..f847c1e
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/nrf_crypto_aead_shared.h
@@ -0,0 +1,147 @@
+/**
+ * Copyright (c) 2018 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+
+#ifndef NRF_CRYPTO_AEAD_SHARED_H__
+#define NRF_CRYPTO_AEAD_SHARED_H__
+
+/** @file
+ *
+ * @defgroup nrf_crypto_aead_shared AEAD related functions
+ * @{
+ * @ingroup nrf_crypto
+ *
+ * @brief Provides AEAD related functionality through nrf_crypto.
+ */
+
+#include <stdint.h>
+#include "nrf_crypto_types.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**@internal @brief Magic value to signal that the nrf_crypto_hash context structure is initialized.
+ */
+#define NRF_CRYPTO_AEAD_INIT_MAGIC_VALUE (0x44414541) // ASCII "AEAD"
+
+#define NRF_CRYPTO_AES_CCM_STAR_MAC_BITMASK (0x1C) /* [0, 4, 8, 16] allowed MAC size in CCM mode */
+#define NRF_CRYPTO_AES_CCM_MAC_MIN (4u) /* MAC min value in CCM mode */
+#define NRF_CRYPTO_AES_CCM_MAC_MAX (16u) /* MAC max value in CCM mode */
+#define NRF_CRYPTO_AES_GCM_MAC_MIN (4u) /* MAC min value in GCM mode */
+#define NRF_CRYPTO_AES_GCM_MAC_MAX (16u) /* MAC max value in GCM mode */
+#define NRF_CRYPTO_AES_CCM_NONCE_SIZE_MIN (7u) /* [7...13] allowed nonce size in CCM mode */
+#define NRF_CRYPTO_AES_CCM_NONCE_SIZE_MAX (13u) /* [7...13] allowed nonce size in CCM mode */
+#define NRF_CRYPTO_AES_CCM_STAR_NONCE_SIZE (13u) /* [13] allowed nonce size in CCM* mode */
+#define NRF_CRYPTO_CHACHA_POLY_NONCE_SIZE (12u) /* [12] allowed nonce size in chacha-poly mode */
+#define NRF_CRYPTO_CHACHA_POLY_MAC_SIZE (16u) /* [16] allowed MAC size in chacha-poly mode */
+
+/**@internal @brief Enumeration of supported modes of operation in nrf_crypto_aead.
+ */
+typedef enum
+{
+ NRF_CRYPTO_AEAD_MODE_AES_CCM, // supported by: MBEDTLS & CC310
+ NRF_CRYPTO_AEAD_MODE_AES_CCM_STAR, // supported by: CC310
+ NRF_CRYPTO_AEAD_MODE_AES_EAX, // supported by: CIFRA
+ NRF_CRYPTO_AEAD_MODE_AES_GCM, // supported by: MBEDTLS
+ NRF_CRYPTO_AEAD_MODE_CHACHA_POLY // supported by: CC310 & OBERON
+} nrf_crypto_aead_mode_t;
+
+
+/**@internal @brief Type declaration to perform AEAD initialization in the nrf_crypto backend.
+ *
+ * This is internal API. See @ref nrf_crypto_aead_init for documentation.
+ */
+typedef ret_code_t (*aead_init_fn_t)(void * const p_context, uint8_t * p_key);
+
+/**@internal @brief Type declaration to perform AEAD uninitialization in the nrf_crypto backend.
+ *
+ * This is internal API. See @ref nrf_crypto_aead_uninit for documentation.
+ */
+typedef ret_code_t (*aead_uninit_fn_t)(void * const p_context);
+
+/**@internal @brief Type declaration to perform AEAD encryption in nrf_crypto backend.
+ *
+ * This is internal API. See @ref nrf_crypto_aead_crypt for documentation.
+ */
+typedef ret_code_t (*aead_crypt_fn_t)(void * const p_context,
+ nrf_crypto_operation_t operation,
+ uint8_t * p_nonce,
+ uint8_t nonce_size,
+ uint8_t * p_adata,
+ size_t adata_size,
+ uint8_t * p_data_in,
+ size_t data_in_size,
+ uint8_t * p_data_out,
+ uint8_t * p_mac,
+ uint8_t mac_size);
+
+/**@internal @brief Type declaration for the nrf_crypto_aead info structure.
+ *
+ * @details This structure contains the calling interface and any metadata required
+ * to call the nrf_crypto_aead API functions.
+ */
+typedef struct
+{
+ nrf_crypto_aead_mode_t const mode;
+ nrf_crypto_key_size_id_t const key_size;
+
+ aead_init_fn_t const init_fn;
+ aead_uninit_fn_t const uninit_fn;
+ aead_crypt_fn_t const crypt_fn;
+} nrf_crypto_aead_info_t;
+
+/**@internal @brief Type declaration of internal representation of an AEAD context structure.
+ *
+ * @details This is an internal type that should not be used directly.
+ */
+typedef struct
+{
+ uint32_t init_value;
+ nrf_crypto_aead_info_t const * p_info;
+} nrf_crypto_aead_internal_context_t;
+
+/** @} */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // #ifndef NRF_CRYPTO_AEAD_SHARED_H__
+
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/nrf_crypto_aes.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/nrf_crypto_aes.c
new file mode 100644
index 0000000..f2ac8ae
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/nrf_crypto_aes.c
@@ -0,0 +1,319 @@
+/**
+ * Copyright (c) 2018 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+
+#include "sdk_common.h"
+#if NRF_MODULE_ENABLED(NRF_CRYPTO)
+
+#include "nrf_crypto_aes.h"
+#include "nrf_crypto_mem.h"
+#include "nrf_crypto_error.h"
+#include "nrf_crypto_shared.h"
+#include "nrf_crypto_aes_shared.h"
+#include "nrf_crypto_aes_backend.h"
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_AES)
+
+static ret_code_t context_verify(nrf_crypto_aes_internal_context_t const * p_context)
+{
+ if (p_context == NULL)
+ {
+ return NRF_ERROR_CRYPTO_CONTEXT_NULL;
+ }
+
+ if (p_context->init_value != NRF_CRYPTO_AES_INIT_MAGIC_VALUE)
+ {
+ return NRF_ERROR_CRYPTO_CONTEXT_NOT_INITIALIZED;
+ }
+
+ return NRF_SUCCESS;
+}
+
+ret_code_t nrf_crypto_aes_init(nrf_crypto_aes_context_t * const p_context,
+ nrf_crypto_aes_info_t const * const p_info,
+ nrf_crypto_operation_t operation)
+{
+ ret_code_t ret_val;
+
+ nrf_crypto_aes_internal_context_t * p_int_context =
+ (nrf_crypto_aes_internal_context_t *)p_context;
+
+ ret_val = context_verify(p_int_context);
+ VERIFY_TRUE((ret_val == NRF_SUCCESS) || (ret_val == NRF_ERROR_CRYPTO_CONTEXT_NOT_INITIALIZED),
+ ret_val);
+
+ VERIFY_TRUE(p_info != NULL, NRF_ERROR_CRYPTO_INPUT_NULL);
+
+ p_int_context->p_info = p_info;
+
+ ret_val = p_info->init_fn(p_context, operation);
+
+ if (ret_val == NRF_SUCCESS)
+ {
+ p_int_context->init_value = NRF_CRYPTO_AES_INIT_MAGIC_VALUE;
+ }
+
+ return ret_val;
+}
+
+ret_code_t nrf_crypto_aes_uninit(nrf_crypto_aes_context_t * const p_context)
+{
+ ret_code_t ret_val;
+
+ nrf_crypto_aes_internal_context_t * p_int_context =
+ (nrf_crypto_aes_internal_context_t *)p_context;
+
+ ret_val = context_verify(p_int_context);
+
+ if (ret_val == NRF_ERROR_CRYPTO_CONTEXT_NOT_INITIALIZED)
+ {
+ /* If context was uninitialized with function nrf_crypto_aes_finalize it shall be still
+ possible to clear init_value */
+ if (p_int_context->init_value == NRF_CRYPTO_AES_UNINIT_MAGIC_VALUE)
+ {
+ ret_val = NRF_SUCCESS;
+ }
+ }
+ VERIFY_SUCCESS(ret_val);
+
+ ret_val = p_int_context->p_info->uninit_fn(p_context);
+
+ p_int_context->init_value = 0;
+
+ return ret_val;
+}
+
+ret_code_t nrf_crypto_aes_key_set(nrf_crypto_aes_context_t * const p_context, uint8_t * p_key)
+{
+ ret_code_t ret_val;
+
+ nrf_crypto_aes_internal_context_t * p_int_context =
+ (nrf_crypto_aes_internal_context_t *)p_context;
+
+ ret_val = context_verify(p_int_context);
+ VERIFY_SUCCESS(ret_val);
+
+ VERIFY_TRUE((p_key != NULL), NRF_ERROR_CRYPTO_INPUT_NULL);
+
+ ret_val = p_int_context->p_info->key_set_fn(p_context, p_key);
+
+ return ret_val;
+}
+
+ret_code_t nrf_crypto_aes_iv_set(nrf_crypto_aes_context_t * const p_context, uint8_t * p_iv)
+{
+ ret_code_t ret_val;
+
+ nrf_crypto_aes_internal_context_t * p_int_context =
+ (nrf_crypto_aes_internal_context_t *)p_context;
+
+ ret_val = context_verify(p_int_context);
+ VERIFY_SUCCESS(ret_val);
+
+ VERIFY_TRUE((p_int_context->p_info->iv_set_fn != NULL), NRF_ERROR_CRYPTO_FEATURE_UNAVAILABLE);
+
+ VERIFY_TRUE((p_iv != NULL), NRF_ERROR_CRYPTO_INPUT_NULL);
+
+ ret_val = p_int_context->p_info->iv_set_fn(p_context, p_iv);
+
+ return ret_val;
+}
+
+ret_code_t nrf_crypto_aes_iv_get(nrf_crypto_aes_context_t * const p_context, uint8_t * p_iv)
+{
+ ret_code_t ret_val;
+
+ nrf_crypto_aes_internal_context_t * p_int_context =
+ (nrf_crypto_aes_internal_context_t *)p_context;
+
+ ret_val = context_verify(p_int_context);
+ if (ret_val == NRF_ERROR_CRYPTO_CONTEXT_NOT_INITIALIZED)
+ {
+ /* If context was uninitialized with function nrf_crypto_aes_finalize it shall be still
+ possible to read IV value */
+ if (p_int_context->init_value == NRF_CRYPTO_AES_UNINIT_MAGIC_VALUE)
+ {
+ ret_val = NRF_SUCCESS;
+ }
+ }
+ VERIFY_SUCCESS(ret_val);
+
+ VERIFY_TRUE((p_iv != NULL), NRF_ERROR_CRYPTO_INPUT_NULL);
+
+ VERIFY_TRUE((p_int_context->p_info->iv_get_fn != NULL), NRF_ERROR_CRYPTO_FEATURE_UNAVAILABLE);
+
+ ret_val = p_int_context->p_info->iv_get_fn(p_context, p_iv);
+
+ return ret_val;
+}
+
+ret_code_t nrf_crypto_aes_update(nrf_crypto_aes_context_t * const p_context,
+ uint8_t * p_data_in,
+ size_t data_size,
+ uint8_t * p_data_out)
+{
+ ret_code_t ret_val;
+
+ nrf_crypto_aes_internal_context_t * p_int_context =
+ (nrf_crypto_aes_internal_context_t *)p_context;
+
+ ret_val = context_verify(p_int_context);
+ VERIFY_SUCCESS(ret_val);
+
+ VERIFY_TRUE((data_size != 0), NRF_ERROR_CRYPTO_INPUT_LENGTH);
+
+ VERIFY_TRUE((p_data_in != NULL), NRF_ERROR_CRYPTO_INPUT_NULL);
+
+ VERIFY_TRUE((p_data_out != NULL), NRF_ERROR_CRYPTO_OUTPUT_NULL);
+
+ if ((data_size & 0xF) != 0)
+ {
+ VERIFY_TRUE((p_int_context->p_info->mode == NRF_CRYPTO_AES_MODE_CFB),
+ NRF_ERROR_CRYPTO_INPUT_LENGTH);
+ }
+
+ ret_val = p_int_context->p_info->update_fn(p_context,
+ p_data_in,
+ data_size,
+ p_data_out);
+
+ return ret_val;
+}
+
+ret_code_t nrf_crypto_aes_finalize(nrf_crypto_aes_context_t * const p_context,
+ uint8_t * p_data_in,
+ size_t data_size,
+ uint8_t * p_data_out,
+ size_t * p_data_out_size)
+{
+ ret_code_t ret_val;
+
+ nrf_crypto_aes_internal_context_t * p_int_context =
+ (nrf_crypto_aes_internal_context_t *)p_context;
+
+ ret_val = context_verify(p_int_context);
+ VERIFY_SUCCESS(ret_val);
+
+ VERIFY_TRUE((p_data_in != NULL), NRF_ERROR_CRYPTO_INPUT_NULL);
+
+ VERIFY_TRUE((p_data_out != NULL), NRF_ERROR_CRYPTO_OUTPUT_NULL);
+
+ VERIFY_TRUE((p_data_out_size != NULL), NRF_ERROR_CRYPTO_OUTPUT_NULL);
+
+ ret_val = p_int_context->p_info->finalize_fn(p_context,
+ p_data_in,
+ data_size,
+ p_data_out,
+ p_data_out_size);
+
+ VERIFY_TRUE((ret_val == NRF_SUCCESS), ret_val);
+
+ ret_val = nrf_crypto_aes_uninit(p_context);
+
+ if (ret_val == NRF_SUCCESS)
+ {
+ /* This line will allow to read IV for AES supporting IV get function. */
+ p_int_context->init_value = NRF_CRYPTO_AES_UNINIT_MAGIC_VALUE;
+ }
+
+ return ret_val;
+}
+
+ret_code_t nrf_crypto_aes_crypt(nrf_crypto_aes_context_t * const p_context,
+ nrf_crypto_aes_info_t const * const p_info,
+ nrf_crypto_operation_t operation,
+ uint8_t * p_key,
+ uint8_t * p_iv,
+ uint8_t * p_data_in,
+ size_t data_size,
+ uint8_t * p_data_out,
+ size_t * p_data_out_size)
+{
+ ret_code_t ret_val;
+ void * p_allocated_context = NULL;
+
+ nrf_crypto_aes_context_t * p_ctx = p_context;
+
+ VERIFY_TRUE(p_info != NULL, NRF_ERROR_CRYPTO_INPUT_NULL);
+
+ if (p_ctx == NULL)
+ {
+ p_allocated_context = NRF_CRYPTO_ALLOC(p_info->context_size);
+ if (p_allocated_context == NULL)
+ {
+ return NRF_ERROR_CRYPTO_ALLOC_FAILED;
+ }
+ p_ctx = (nrf_crypto_aes_context_t *)p_allocated_context;
+ }
+
+ ret_val = nrf_crypto_aes_init(p_ctx, p_info, operation);
+ NRF_CRYPTO_VERIFY_SUCCESS_DEALLOCATE(ret_val, p_allocated_context);
+
+ ret_val = nrf_crypto_aes_key_set(p_ctx, p_key);
+ NRF_CRYPTO_VERIFY_SUCCESS_DEALLOCATE(ret_val, p_allocated_context);
+
+ ret_val = nrf_crypto_aes_iv_set(p_ctx, p_iv);
+ /* not all AES modes support IV */
+ if (ret_val != NRF_ERROR_CRYPTO_FEATURE_UNAVAILABLE)
+ {
+ NRF_CRYPTO_VERIFY_SUCCESS_DEALLOCATE(ret_val, p_allocated_context);
+ }
+
+ ret_val = nrf_crypto_aes_finalize(p_ctx,
+ p_data_in,
+ data_size,
+ p_data_out,
+ p_data_out_size);
+ if (ret_val != NRF_SUCCESS)
+ {
+ /* Context was not successfully deinitialized in nrf_crypto_aes_finalize */
+ UNUSED_RETURN_VALUE(nrf_crypto_aes_uninit(p_ctx));
+ }
+
+ if (p_allocated_context != NULL)
+ {
+ NRF_CRYPTO_FREE(p_allocated_context);
+ }
+
+ return ret_val;
+}
+
+#endif // NRF_MODULE_ENABLED(NRF_CRYPTO_AES)
+#endif // NRF_MODULE_ENABLED(NRF_CRYPTO)
+
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/nrf_crypto_aes.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/nrf_crypto_aes.h
new file mode 100644
index 0000000..bb02700
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/nrf_crypto_aes.h
@@ -0,0 +1,481 @@
+/**
+ * Copyright (c) 2018 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+
+#ifndef NRF_CRYPTO_AES_H__
+#define NRF_CRYPTO_AES_H__
+
+/** @file
+ *
+ * @defgroup nrf_crypto_aes AES related functions
+ * @{
+ * @ingroup nrf_crypto
+ *
+ * @brief Provides AES related functionality through nrf_crypto.
+ */
+#include "sdk_common.h"
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO) || defined(__SDK_DOXYGEN__)
+
+#include <stdint.h>
+#include "nrf_crypto_types.h"
+#include "nrf_crypto_aes_shared.h"
+#include "nrf_crypto_aes_backend.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**@brief External variable declaration to the info structure for AES CBC mode with a 128-bit key.
+* No padding.
+*
+* @note The variable is defined in the nrf_crypto backend that is
+* enabled in the @c sdk_config file.
+*
+*/
+extern const nrf_crypto_aes_info_t g_nrf_crypto_aes_cbc_128_info;
+
+/**@brief External variable declaration to the info structure for AES CBC mode with a 192-bit key.
+* No padding.
+*
+* @note The variable is defined in the nrf_crypto backend that is
+* enabled in the @c sdk_config file.
+*
+*/
+extern const nrf_crypto_aes_info_t g_nrf_crypto_aes_cbc_192_info;
+
+/**@brief External variable declaration to the info structure for AES CBC mode with a 256-bit key.
+* No padding.
+*
+* @note The variable is defined in the nrf_crypto backend that is
+* enabled in the @c sdk_config file.
+*
+*/
+extern const nrf_crypto_aes_info_t g_nrf_crypto_aes_cbc_256_info;
+
+/**@brief External variable declaration to the info structure for AES CBC mode with a 128-bit key.
+* Padding pkcs7 enabled.
+*
+* @note The variable is defined in the nrf_crypto backend that is
+* enabled in the @c sdk_config file.
+*
+*/
+extern const nrf_crypto_aes_info_t g_nrf_crypto_aes_cbc_128_pad_pkcs7_info;
+
+/**@brief External variable declaration to the info structure for AES CBC mode with a 192-bit key.
+* Padding pkcs7 enabled.
+*
+* @note The variable is defined in the nrf_crypto backend that is
+* enabled in the @c sdk_config file.
+*
+*/
+extern const nrf_crypto_aes_info_t g_nrf_crypto_aes_cbc_192_pad_pkcs7_info;
+
+/**@brief External variable declaration to the info structure for AES CBC mode with a 256-bit key.
+* Padding pkcs7 enabled.
+*
+* @note The variable is defined in the nrf_crypto backend that is
+* enabled in the @c sdk_config file.
+*
+*/
+extern const nrf_crypto_aes_info_t g_nrf_crypto_aes_cbc_256_pad_pkcs7_info;
+
+/**@brief External variable declaration to the info structure for AES CTR mode with a 128-bit key.
+*
+* @note The variable is defined in the nrf_crypto backend that is
+* enabled in the @c sdk_config file.
+*
+*/
+extern const nrf_crypto_aes_info_t g_nrf_crypto_aes_ctr_128_info;
+
+/**@brief External variable declaration to the info structure for AES CTR mode with a 192-bit key.
+*
+* @note The variable is defined in the nrf_crypto backend that is
+* enabled in the @c sdk_config file.
+*
+*/
+extern const nrf_crypto_aes_info_t g_nrf_crypto_aes_ctr_192_info;
+
+/**@brief External variable declaration to the info structure for AES CTR mode with a 256-bit key.
+*
+* @note The variable is defined in the nrf_crypto backend that is
+* enabled in the @c sdk_config file.
+*
+*/
+extern const nrf_crypto_aes_info_t g_nrf_crypto_aes_ctr_256_info;
+
+/**@brief External variable declaration to the info structure for AES CFB mode with a 128-bit key.
+*
+* @note The variable is defined in the nrf_crypto backend that is
+* enabled in the @c sdk_config file.
+*
+*/
+extern const nrf_crypto_aes_info_t g_nrf_crypto_aes_cfb_128_info;
+
+/**@brief External variable declaration to the info structure for AES CFB mode with a 192-bit key.
+*
+* @note The variable is defined in the nrf_crypto backend that is
+* enabled in the @c sdk_config file.
+*
+*/
+extern const nrf_crypto_aes_info_t g_nrf_crypto_aes_cfb_192_info;
+
+/**@brief External variable declaration to the info structure for AES CFB mode with a 256-bit key.
+*
+* @note The variable is defined in the nrf_crypto backend that is
+* enabled in the @c sdk_config file.
+*
+*/
+extern const nrf_crypto_aes_info_t g_nrf_crypto_aes_cfb_256_info;
+
+/**@brief External variable declaration to the info structure for AES ECB mode with a 128-bit key.
+* No padding.
+*
+* @note The variable is defined in the nrf_crypto backend that is
+* enabled in the @c sdk_config file.
+*
+*/
+extern const nrf_crypto_aes_info_t g_nrf_crypto_aes_ecb_128_info;
+
+/**@brief External variable declaration to the info structure for AES ECB mode with a 192-bit key.
+* No padding.
+*
+* @note The variable is defined in the nrf_crypto backend that is
+* enabled in the @c sdk_config file.
+*
+*/
+extern const nrf_crypto_aes_info_t g_nrf_crypto_aes_ecb_192_info;
+
+/**@brief External variable declaration to the info structure for AES ECB mode with a 256-bit key.
+* No padding.
+*
+* @note The variable is defined in the nrf_crypto backend that is
+* enabled in the @c sdk_config file.
+*
+*/
+extern const nrf_crypto_aes_info_t g_nrf_crypto_aes_ecb_256_info;
+
+/**@brief External variable declaration to the info structure for AES ECB mode with a 128-bit key.
+* Padding pkcs7 enabled.
+*
+* @note The variable is defined in the nrf_crypto backend that is
+* enabled in the @c sdk_config file.
+*
+*/
+extern const nrf_crypto_aes_info_t g_nrf_crypto_aes_ecb_128_pad_pkcs7_info;
+
+/**@brief External variable declaration to the info structure for AES ECB mode with a 192-bit key.
+* Padding pkcs7 enabled.
+*
+* @note The variable is defined in the nrf_crypto backend that is
+* enabled in the @c sdk_config file.
+*
+*/
+extern const nrf_crypto_aes_info_t g_nrf_crypto_aes_ecb_192_pad_pkcs7_info;
+
+/**@brief External variable declaration to the info structure for AES ECB mode with a 256-bit key.
+* Padding pkcs7 enabled.
+*
+* @note The variable is defined in the nrf_crypto backend that is
+* enabled in the @c sdk_config file.
+*
+*/
+extern const nrf_crypto_aes_info_t g_nrf_crypto_aes_ecb_256_pad_pkcs7_info;
+
+/**@brief External variable declaration to the info structure for AES CBC MAC mode with a 128-bit
+* key.
+*
+* @note The variable is defined in the nrf_crypto backend that is
+* enabled in the @c sdk_config file.
+*
+*/
+extern const nrf_crypto_aes_info_t g_nrf_crypto_aes_cbc_mac_128_info;
+
+/**@brief External variable declaration to the info structure for AES CBC MAC mode with a 192-bit
+* key.
+*
+* @note The variable is defined in the nrf_crypto backend that is
+* enabled in the @c sdk_config file.
+*
+*/
+extern const nrf_crypto_aes_info_t g_nrf_crypto_aes_cbc_mac_192_info;
+
+/**@brief External variable declaration to the info structure for AES CBC MAC mode with a 256-bit
+* key.
+*
+* @note The variable is defined in the nrf_crypto backend that is
+* enabled in the @c sdk_config file.
+*
+*/
+extern const nrf_crypto_aes_info_t g_nrf_crypto_aes_cbc_mac_256_info;
+
+/**@brief External variable declaration to the info structure for AES CBC MAC mode with a 128-bit
+* key.
+* Padding pkcs7 enabled.
+*
+* @note The variable is defined in the nrf_crypto backend that is
+* enabled in the @c sdk_config file.
+*
+*/
+extern const nrf_crypto_aes_info_t g_nrf_crypto_aes_cbc_mac_128_pad_pkcs7_info;
+
+/**@brief External variable declaration to the info structure for AES CBC MAC mode with a 192-bit
+* key.
+* Padding pkcs7 enabled.
+*
+* @note The variable is defined in the nrf_crypto backend that is
+* enabled in the @c sdk_config file.
+*
+*/
+extern const nrf_crypto_aes_info_t g_nrf_crypto_aes_cbc_mac_192_pad_pkcs7_info;
+
+/**@brief External variable declaration to the info structure for AES CBC MAC mode with a 256-bit
+* key.
+* Padding pkcs7 enabled.
+*
+* @note The variable is defined in the nrf_crypto backend that is
+* enabled in the @c sdk_config file.
+*
+*/
+extern const nrf_crypto_aes_info_t g_nrf_crypto_aes_cbc_mac_256_pad_pkcs7_info;
+
+
+/**@brief External variable declaration to the info structure for AES CMAC mode with a 128-bit key.
+*
+* @note The variable is defined in the nrf_crypto backend that is
+* enabled in the @c sdk_config file.
+*
+*/
+extern const nrf_crypto_aes_info_t g_nrf_crypto_aes_cmac_128_info;
+
+/**@brief External variable declaration to the info structure for AES CMAC mode with a 192-bit key.
+*
+* @note The variable is defined in the nrf_crypto backend that is
+* enabled in the @c sdk_config file.
+*
+*/
+extern const nrf_crypto_aes_info_t g_nrf_crypto_aes_cmac_192_info;
+
+/**@brief External variable declaration to the info structure for AES CMAC mode with a 256-bit key.
+*
+* @note The variable is defined in the nrf_crypto backend that is
+* enabled in the @c sdk_config file.
+*
+*/
+extern const nrf_crypto_aes_info_t g_nrf_crypto_aes_cmac_256_info;
+
+/**
+ * @brief Context type for AES.
+ *
+ * @note The size of this type is scaled for the largest AES backend context that is
+ * enabled in @ref sdk_config.
+ */
+typedef nrf_crypto_backend_aes_context_t nrf_crypto_aes_context_t;
+
+/**@brief Function for initializing the AES context.
+ *
+ * @param[in] p_context Pointer to the context object. It must be a context type associated
+ * with the object provided in the p_info parameter or other memory
+ * that can hold that context type.
+ * @param[in] p_info Pointer to structure holding information about: selected AES mode,
+ * key size, and padding.
+ * @param[in] operation Parameter indicating whether an encrypt (NRF_CRYPTO_ENCRYPT),
+ * a decrypt (NRF_CRYPTO_DECRYPT) or MAC calculation
+ * (NRF_CRYPTO_MAC_CALCULATE) operation shall be performed.
+ *
+ * @return NRF_SUCCESS on success.
+ */
+ret_code_t nrf_crypto_aes_init(nrf_crypto_aes_context_t * const p_context,
+ nrf_crypto_aes_info_t const * const p_info,
+ nrf_crypto_operation_t operation);
+
+/**@brief Internal function for uninitializing the AES context.
+ *
+ * @param[in] p_context Context object. Must be initialized before the call.
+ *
+ * @return NRF_SUCCESS on success.
+ */
+ret_code_t nrf_crypto_aes_uninit(nrf_crypto_aes_context_t * const p_context);
+
+/**@brief Function for setting the AES key.
+ *
+ * @param[in] p_context Context object. Must be initialized before the call.
+ * @param[in] p_key Pointer to the AES key. This buffer will be copied and there is no need
+ * to keep it by the user.
+ *
+ * @return NRF_SUCCESS on success.
+ */
+ret_code_t nrf_crypto_aes_key_set(nrf_crypto_aes_context_t * const p_context, uint8_t * p_key);
+
+/**@brief Function for setting an AES IV or a counter for AES modes which are using it.
+ *
+ * @param[in] p_context Context object. Must be initialized before the call.
+ * @param[in] p_iv Pointer to a buffer of the IV or a counter. This buffer will be copied
+ * and there is no need to keep it by the user.
+ *
+ * @return NRF_SUCCESS on success.
+ */
+ret_code_t nrf_crypto_aes_iv_set(nrf_crypto_aes_context_t * const p_context, uint8_t * p_iv);
+
+/**@brief Function for getting an AES IV or a counter for mode which is supporting it.
+ *
+ * @param[in] p_context Context object. Must be initialized before the call.
+ * @param[out] p_iv Pointer to a buffer of the IV or a counter.
+ *
+ * @return NRF_SUCCESS on success.
+ */
+ret_code_t nrf_crypto_aes_iv_get(nrf_crypto_aes_context_t * const p_context, uint8_t * p_iv);
+
+/**@brief AES update function for encryption, decryption and MAC calculation. It can be called once
+ * on the whole data block, or as many times as needed, until all the input data is processed.
+ * Functions: @ref nrf_crypto_aes_init, @ref nrf_crypto_aes_key_set, and, for some ciphers,
+ * @ref nrf_crypto_aes_iv_set, must be called before call to this API with the same context.
+
+ *
+ * @param[in] p_context Context object. Must be initialized before the call.
+ * @param[in] p_data_in Pointer to the input buffer to the AES.
+ * @param[in] data_size Size of the data to be processed in bytes.
+ * For all modes except CFB it must be multiple of 16 bytes.
+ * @param[out] p_data_out Pointer to the output buffer.
+ *
+ * @return NRF_SUCCESS on success.
+ */
+ret_code_t nrf_crypto_aes_update(nrf_crypto_aes_context_t * const p_context,
+ uint8_t * p_data_in,
+ size_t data_size,
+ uint8_t * p_data_out);
+
+
+/**@brief Function processes the last data block if needed and finalizes the AES operation (ie. adds
+ * padding) and produces operation results (for MAC operations).
+ * Functions: @ref nrf_crypto_aes_init, @ref nrf_crypto_aes_key_set, and, for some ciphers,
+ * @ref nrf_crypto_aes_iv_set, must be called before call to this API with the same context.
+ *
+ * Upon successful operation function will deinitialize the context but for some ciphers it will be
+ * possible to read IV. In order to fully deinitialize context you must call
+ * @ref nrf_crypto_aes_uninit.
+ *
+ * @param[in] p_context Context object. Must be initialized before the call.
+ * @param[in] p_data_in Pointer to the input buffer to the AES.
+ * @param[in] data_size Size of the data to be processed in bytes.
+ * @param[out] p_data_out Pointer to the output buffer.
+ * When padding is set:
+ * - The size of p_data_out buffer must have extra space for
+ * padding. Otherwise, the function will return an error:
+ * NRF_ERROR_CRYPTO_OUTPUT_LENGTH.
+ * - When text_size is multiple of 16 bytes, p_text_out must be
+ * allocated with size equal to text_size + an additional block
+ * (i.e 16 bytes for padding).
+ * - When text_size is not a multiple of 16 bytes, p_text_out
+ * must be allocated with size aligned to the next full 16
+ * bytes block (i.e. 1 - 15 bytes for padding).
+ * @param[in,out] p_data_out_size IN:
+ * Size of the p_data_out buffer.
+ * OUT:
+ * Upon successfull function execution value will be updated
+ * with number of signifacnt bytes in p_data_out buffer.
+ * On decryption with padding function will result in a value
+ * without padded bytes.
+ *
+ * @return NRF_SUCCESS on success.
+ */
+ret_code_t nrf_crypto_aes_finalize(nrf_crypto_aes_context_t * const p_context,
+ uint8_t * p_data_in,
+ size_t data_size,
+ uint8_t * p_data_out,
+ size_t * p_data_out_size);
+
+
+
+
+/**@brief AES integrated function for encryption, decryption and MAC calculation.
+ * It should be called once on the whole data block.
+ *
+ * @param[in] p_context Context object. If NULL, memory will be dynamically allocated.
+ * @param[in] p_info Pointer to structure holding information about: selected AES
+ * mode, key size, and padding.
+ * @param[in] operation Parameter indicating whether an encrypt (NRF_CRYPTO_ENCRYPT),
+ * a decrypt (NRF_CRYPTO_DECRYPT) or MAC calculation
+ * (NRF_CRYPTO_MAC_CALCULATE) operation shall be performed.
+ * @param[in] p_key Pointer to the AES key. This buffer will be copied and there is
+ * no need to keep it by the user.
+ * @param[in] p_iv Pointer to a buffer of the IV or a counter. This buffer will be
+ * copied and there is no need to keep it by the user.
+ * Can be NULL for ECB and CMAC.
+ * @param[in] p_data_in Pointer to the input buffer to the AES.
+ * @param[in] data_size Size of the data to be processed in bytes.
+ * @param[out] p_data_out Pointer to the output buffer.
+ * When padding is set:
+ * - The size of p_data_out buffer must have extra space for
+ * padding. Otherwise, the function will return an error:
+ * NRF_ERROR_CRYPTO_OUTPUT_LENGTH.
+ * - When text_size is multiple of 16 bytes, p_text_out must be
+ * allocated with size equal to text_size + an additional block
+ * (i.e 16 bytes for padding).
+ * - When text_size is not a multiple of 16 bytes, p_text_out
+ * must be allocated with size aligned to the next full 16
+ * bytes block (i.e. 1 - 15 bytes for padding).
+ * @param[in,out] p_data_out_size IN:
+ * Size of the p_data_out buffer.
+ * OUT:
+ * Upon successfull function execution value will be updated
+ * with number of signifacnt bytes in p_data_out buffer.
+ * On decryption function will result in a value without padded
+ * bytes.
+ *
+ * @return NRF_SUCCESS on success.
+ */
+ret_code_t nrf_crypto_aes_crypt(nrf_crypto_aes_context_t * const p_context,
+ nrf_crypto_aes_info_t const * const p_info,
+ nrf_crypto_operation_t operation,
+ uint8_t * p_key,
+ uint8_t * p_iv,
+ uint8_t * p_data_in,
+ size_t data_size,
+ uint8_t * p_data_out,
+ size_t * p_data_out_size);
+#ifdef __cplusplus
+}
+#endif
+
+#endif // #if NRF_MODULE_ENABLED(NRF_CRYPTO) || defined(__SDK_DOXYGEN__)
+
+/** @} */
+
+#endif // #ifndef NRF_CRYPTO_AES_H__
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/nrf_crypto_aes_backend.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/nrf_crypto_aes_backend.h
new file mode 100644
index 0000000..5c34476
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/nrf_crypto_aes_backend.h
@@ -0,0 +1,112 @@
+/**
+ * Copyright (c) 2018 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+
+#ifndef NRF_CRYPTO_AES_BACKEND_H__
+#define NRF_CRYPTO_AES_BACKEND_H__
+
+#include "cc310_backend_aes.h"
+#include "mbedtls_backend_aes.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**@internal @brief Fallback type for AES CBC context (if no backend is enabled).
+ */
+#if !NRF_MODULE_ENABLED(NRF_CRYPTO_AES_CBC)
+typedef nrf_crypto_aes_internal_context_t nrf_crypto_backend_aes_cbc_context_t;
+#endif
+
+/**@internal @brief Fallback type for AES CFB context (if no backend is enabled).
+ */
+#if !NRF_MODULE_ENABLED(NRF_CRYPTO_AES_CFB)
+typedef nrf_crypto_aes_internal_context_t nrf_crypto_backend_aes_cfb_context_t;
+#endif
+
+/**@internal @brief Fallback type for AES CTR context (if no backend is enabled).
+ */
+#if !NRF_MODULE_ENABLED(NRF_CRYPTO_AES_CTR)
+typedef nrf_crypto_aes_internal_context_t nrf_crypto_backend_aes_ctr_context_t;
+#endif
+
+/**@internal @brief Fallback type for AES ECB context (if no backend is enabled).
+ */
+#if !NRF_MODULE_ENABLED(NRF_CRYPTO_AES_ECB)
+typedef nrf_crypto_aes_internal_context_t nrf_crypto_backend_aes_ecb_context_t;
+#endif
+
+
+/**@internal @brief Fallback type for AES CBC_MAC context (if no backend is enabled).
+ */
+#if !NRF_MODULE_ENABLED(NRF_CRYPTO_AES_CBC_MAC)
+typedef nrf_crypto_aes_internal_context_t nrf_crypto_backend_aes_cbc_mac_context_t;
+#endif
+
+/**@internal @brief Fallback type for AES CMAC context (if no backend is enabled).
+ */
+#if !NRF_MODULE_ENABLED(NRF_CRYPTO_AES_CMAC)
+typedef nrf_crypto_aes_internal_context_t nrf_crypto_backend_aes_cmac_context_t;
+#endif
+
+/**@internal @brief Fallback type for AES CMAC_PRF128 context (if no backend is enabled).
+ */
+#if !NRF_MODULE_ENABLED(NRF_CRYPTO_AES_CMAC_PRF128)
+typedef nrf_crypto_aes_internal_context_t nrf_crypto_backend_aes_cmac_prf128_context_t;
+#endif
+
+
+/** @internal @brief Union holding a AES context. */
+typedef union
+{
+ nrf_crypto_backend_aes_cbc_context_t cbc_context; /**< @brief Holds context for AES CBC. */
+ nrf_crypto_backend_aes_cfb_context_t cfb_context; /**< @brief Holds context for AES CFB. */
+ nrf_crypto_backend_aes_ctr_context_t ctr_context; /**< @brief Holds context for AES CFB. */
+ nrf_crypto_backend_aes_ecb_context_t ecb_context; /**< @brief Holds context for AES ECB. */
+
+ nrf_crypto_backend_aes_cbc_mac_context_t cbc_mac_context; /**< @brief Holds context for CBC-MAC. */
+ nrf_crypto_backend_aes_cmac_context_t cmac_context; /**< @brief Holds context for CMAC. */
+ nrf_crypto_backend_aes_cmac_prf128_context_t cmac_prf128_context; /**< @brief Holds context for CMAC_PRF128. */
+} nrf_crypto_backend_aes_context_t;
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // NRF_CRYPTO_AES_BACKEND_H__
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/nrf_crypto_aes_shared.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/nrf_crypto_aes_shared.c
new file mode 100644
index 0000000..615b236
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/nrf_crypto_aes_shared.c
@@ -0,0 +1,121 @@
+/**
+ * Copyright (c) 2018 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+
+#include "sdk_common.h"
+#if NRF_MODULE_ENABLED(NRF_CRYPTO)
+
+#include "nrf_crypto_error.h"
+#include "sdk_config.h"
+#include "nrf_crypto_types.h"
+
+
+ret_code_t padding_pkcs7_add(uint8_t * p_padding_buff,
+ uint8_t * p_message_buff,
+ uint8_t msg_ending_len)
+{
+ uint8_t padding_count;
+
+ if ((p_padding_buff == NULL) || (p_message_buff == NULL))
+ {
+ return NRF_ERROR_CRYPTO_INPUT_NULL;
+ }
+
+ if (msg_ending_len >= NRF_CRYPTO_AES_BLOCK_SIZE)
+ {
+ return NRF_ERROR_CRYPTO_INVALID_PARAM;
+ }
+
+ /* Creating padding buffer in two steps */
+ /* step 1 add remaining message */
+ memcpy(p_padding_buff, p_message_buff, msg_ending_len);
+
+ /* step 2: add padding */
+ padding_count = NRF_CRYPTO_AES_BLOCK_SIZE - msg_ending_len;
+ p_padding_buff += msg_ending_len;
+
+ for (size_t i = 0; i < padding_count; i++)
+ {
+ p_padding_buff[i] = padding_count;
+ }
+
+ return NRF_SUCCESS;
+}
+
+ret_code_t padding_pkcs7_remove(uint8_t * p_padded_message,
+ size_t * p_message_len)
+{
+ if (p_padded_message == NULL)
+ {
+ return NRF_ERROR_CRYPTO_INPUT_NULL;
+ }
+ if (p_message_len == NULL)
+ {
+ return NRF_ERROR_CRYPTO_OUTPUT_NULL;
+ }
+
+ /* padded_msg_len must be multiple of 16 */
+ if ((*p_message_len == 0) || ((*p_message_len & 0x0F) != 0))
+ {
+ return NRF_ERROR_CRYPTO_INVALID_PARAM;
+ }
+
+ size_t padded_bytes = p_padded_message[*p_message_len - 1];
+
+ if ((padded_bytes == 0) || (padded_bytes > NRF_CRYPTO_AES_BLOCK_SIZE))
+ {
+ return NRF_ERROR_CRYPTO_AES_INVALID_PADDING;
+ }
+
+ /* i = 2: 1 for valid string and 1 for already checked *p_message_len - 1 */
+ for (size_t i = 2; i < padded_bytes; i++)
+ {
+ if (p_padded_message[*p_message_len - i] != padded_bytes)
+ {
+ return NRF_ERROR_CRYPTO_AES_INVALID_PADDING;
+ }
+ }
+
+ *p_message_len -= padded_bytes;
+
+ return NRF_SUCCESS;
+}
+
+#endif // NRF_MODULE_ENABLED(NRF_CRYPTO)
+
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/nrf_crypto_aes_shared.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/nrf_crypto_aes_shared.h
new file mode 100644
index 0000000..9878bcb
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/nrf_crypto_aes_shared.h
@@ -0,0 +1,218 @@
+/**
+ * Copyright (c) 2018 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+
+#ifndef NRF_CRYPTO_AES_SHARED_H__
+#define NRF_CRYPTO_AES_SHARED_H__
+
+/** @file
+ *
+ * @defgroup nrf_crypto_aes AES related functions
+ * @{
+ * @ingroup nrf_crypto
+ *
+ * @brief Provides AES related functionality through nrf_crypto.
+ */
+
+#include <stdint.h>
+#include "nrf_crypto_types.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+/**@internal @brief Magic value to signal that the nrf_crypto_hash context structure is initialized.
+ */
+#define NRF_CRYPTO_AES_INIT_MAGIC_VALUE (0x53454163) // ASCII "cAES"
+#define NRF_CRYPTO_AES_UNINIT_MAGIC_VALUE (0x63414553) // ASCII "SEAc"
+
+#define NRF_CRYPTO_MBEDTLS_AES_IV_SIZE (16)
+
+
+/** @internal @brief Enumeration of supported modes of operation in nrf_crypto_aes.
+ */
+typedef enum
+{
+ NRF_CRYPTO_AES_MODE_CBC, // supported by: MBEDTLS & CC310
+ NRF_CRYPTO_AES_MODE_CBC_PAD_PCKS7, // supported by: MBEDTLS & CC310
+ NRF_CRYPTO_AES_MODE_CFB, // supported by: MBEDTLS
+ NRF_CRYPTO_AES_MODE_CTR, // supported by: MBEDTLS & CC310
+ NRF_CRYPTO_AES_MODE_ECB, // supported by: MBEDTLS & CC310
+ NRF_CRYPTO_AES_MODE_ECB_PAD_PCKS7, // supported by: MBEDTLS & CC310
+
+ // Authentication modes
+ NRF_CRYPTO_AES_MODE_CBC_MAC, // supported by: MBEDTLS & CC310
+ NRF_CRYPTO_AES_MODE_CBC_MAC_PAD_PCKS7, // supported by: MBEDTLS & CC310
+ NRF_CRYPTO_AES_MODE_CMAC, // supported by: MBEDTLS & CC310
+} nrf_crypto_aes_mode_t;
+
+/**@internal @brief Type declaration to perform AES initialization in the nrf_crypto backend.
+ *
+ * This is internal API. See @ref nrf_crypto_aes_init for documentation.
+ */
+typedef ret_code_t (*aes_init_fn_t)(void * const p_context, nrf_crypto_operation_t operation);
+
+/**@internal @brief Type declaration to perform AES uninitialization in the nrf_crypto backend.
+ *
+ * This is internal API. See @ref nrf_crypto_aes_uninit for documentation.
+ */
+typedef ret_code_t (*aes_uninit_fn_t)(void * const p_context);
+
+/**@internal @brief Type declaration to set an AES key in the nrf_crypto backend.
+ *
+ * This is internal API. See @ref nrf_crypto_aes_key_set for documentation.
+ */
+typedef ret_code_t (*aes_key_set_fn_t)(void * const p_context, uint8_t * p_key);
+
+/**@internal @brief Type declaration to set an AES IV in the nrf_crypto backend.
+ *
+ * This is internal API. See @ref nrf_crypto_aes_iv_set for documentation.
+ */
+typedef ret_code_t (*aes_iv_set_fn_t)(void * const p_context, uint8_t * p_iv);
+
+/**@internal @brief Type declaration to get an AES IV in the nrf_crypto backend.
+ *
+ * This is internal API. See @ref nrf_crypto_aes_iv_get for documentation.
+ */
+typedef ret_code_t (*aes_iv_get_fn_t)(void * const p_context, uint8_t * p_iv);
+
+/**@internal @brief Type declaration to perform AES block operation in the nrf_crypto backend.
+ *
+ * This is internal API. See @ref nrf_crypto_aes_update for documentation.
+ */
+typedef ret_code_t (*aes_update_fn_t)(void * const p_context,
+ uint8_t * p_data_in,
+ size_t data_size,
+ uint8_t * p_data_out);
+
+/**@internal @brief Type declaration to finalize AES operation in the nrf_crypto backend.
+ *
+ * This is internal API. See @ref nrf_crypto_aes_finalize for documentation.
+ */
+typedef ret_code_t (*aes_finalize_fn_t)(void * const p_context,
+ uint8_t * p_data_in,
+ size_t data_size,
+ uint8_t * p_data_out,
+ size_t * p_data_out_size);
+
+/**@internal @brief Type declaration for an nrf_crypto_aes info structure.
+ *
+ * @details This structure contains the calling interface and any metadata required
+ * to call the nrf_crypto_aes API functions.
+ */
+typedef struct
+{
+ nrf_crypto_aes_mode_t const mode;
+ nrf_crypto_key_size_id_t const key_size;
+ size_t const context_size;
+
+ aes_init_fn_t const init_fn;
+ aes_uninit_fn_t const uninit_fn;
+ aes_key_set_fn_t const key_set_fn;
+ aes_iv_set_fn_t const iv_set_fn;
+ aes_iv_get_fn_t const iv_get_fn;
+ aes_update_fn_t const update_fn;
+ aes_finalize_fn_t const finalize_fn;
+} nrf_crypto_aes_info_t;
+
+/**@internal @brief Type declaration of internal representation of an AES context structure.
+ *
+ * @details This is an internal type that should not be used directly.
+ */
+typedef struct
+{
+ uint32_t init_value;
+ nrf_crypto_aes_info_t const * p_info;
+} nrf_crypto_aes_internal_context_t;
+
+
+/**@internal @brief Type declaration of internal representation of an AES backend context structure.
+ * with initialization vector.
+ *
+ * @details This is an internal type that should not be used directly.
+ */
+typedef struct
+{
+ nrf_crypto_operation_t operation;
+
+ uint8_t iv[NRF_CRYPTO_MBEDTLS_AES_IV_SIZE]; // space for 128-bit initialization vector
+} nrf_crypto_backend_aes_ctx_t;
+
+/**@internal @brief Type declaration of internal representation of an AES backend context structure
+ * without initialization vector.
+ *
+ * @details This is an internal type that should not be used directly.
+ */
+typedef struct
+{
+ nrf_crypto_operation_t operation;
+} nrf_crypto_backend_no_iv_aes_ctx_t;
+
+
+/**@internal @brief Function copies remainders (msg_ending_len) from p_message_buff to the
+ * p_padding_buff. Next it adds pkcs7-padding to have a 16 bytes p_padding_buff.
+ *
+ * @param[in] p_padding_buff Pointer the buffer with padded message.
+ * @param[in] p_message_buff Pointer to the buffer with message that must be padded.
+ * @param[in] msg_ending_len Message remainders length.
+ *
+ */
+ret_code_t padding_pkcs7_add(uint8_t * p_padding_buff,
+ uint8_t * p_message_buff,
+ uint8_t msg_ending_len);
+
+
+/**@internal @brief Function calculate message length without padding.
+ *
+ * @param[in] p_padded_message Pointer the buffer with padded message.
+ * @param[in/out] p_message_len IN: padded message length
+ * OUT: message length without padding
+ */
+ret_code_t padding_pkcs7_remove(uint8_t * p_padded_message,
+ size_t * p_message_len);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+/** @} */
+
+#endif // #ifndef NRF_CRYPTO_AES_SHARED_H__
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/nrf_crypto_ecc.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/nrf_crypto_ecc.c
new file mode 100644
index 0000000..8bff9a7
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/nrf_crypto_ecc.c
@@ -0,0 +1,1314 @@
+/**
+ * Copyright (c) 2018 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+
+#include <stdbool.h>
+#include <stdint.h>
+
+#include "nordic_common.h"
+#include "nrf_crypto_error.h"
+#include "nrf_crypto_mem.h"
+#include "nrf_crypto_ecc.h"
+#include "app_util.h"
+#include "sdk_macros.h"
+
+
+#if NRF_CRYPTO_ECC_ENABLED
+
+
+#if NRF_CRYPTO_ECC_IMPLEMENTED_CURVES_COUNT > 1
+
+
+static const nrf_crypto_backend_ecc_key_pair_generate_fn_t key_pair_generate_impl[] =
+{
+#if NRF_CRYPTO_ECC_SECP160R1_ENABLED
+ nrf_crypto_backend_secp160r1_key_pair_generate,
+#endif
+#if NRF_CRYPTO_ECC_SECP160R2_ENABLED
+ nrf_crypto_backend_secp160r2_key_pair_generate,
+#endif
+#if NRF_CRYPTO_ECC_SECP192R1_ENABLED
+ nrf_crypto_backend_secp192r1_key_pair_generate,
+#endif
+#if NRF_CRYPTO_ECC_SECP224R1_ENABLED
+ nrf_crypto_backend_secp224r1_key_pair_generate,
+#endif
+#if NRF_CRYPTO_ECC_SECP256R1_ENABLED
+ nrf_crypto_backend_secp256r1_key_pair_generate,
+#endif
+#if NRF_CRYPTO_ECC_SECP384R1_ENABLED
+ nrf_crypto_backend_secp384r1_key_pair_generate,
+#endif
+#if NRF_CRYPTO_ECC_SECP521R1_ENABLED
+ nrf_crypto_backend_secp521r1_key_pair_generate,
+#endif
+#if NRF_CRYPTO_ECC_SECP160K1_ENABLED
+ nrf_crypto_backend_secp160k1_key_pair_generate,
+#endif
+#if NRF_CRYPTO_ECC_SECP192K1_ENABLED
+ nrf_crypto_backend_secp192k1_key_pair_generate,
+#endif
+#if NRF_CRYPTO_ECC_SECP224K1_ENABLED
+ nrf_crypto_backend_secp224k1_key_pair_generate,
+#endif
+#if NRF_CRYPTO_ECC_SECP256K1_ENABLED
+ nrf_crypto_backend_secp256k1_key_pair_generate,
+#endif
+#if NRF_CRYPTO_ECC_BP256R1_ENABLED
+ nrf_crypto_backend_bp256r1_key_pair_generate,
+#endif
+#if NRF_CRYPTO_ECC_BP384R1_ENABLED
+ nrf_crypto_backend_bp384r1_key_pair_generate,
+#endif
+#if NRF_CRYPTO_ECC_BP512R1_ENABLED
+ nrf_crypto_backend_bp512r1_key_pair_generate,
+#endif
+#if NRF_CRYPTO_ECC_CURVE25519_ENABLED
+ nrf_crypto_backend_curve25519_key_pair_generate,
+#endif
+#if NRF_CRYPTO_ECC_ED25519_ENABLED
+ nrf_crypto_backend_ed25519_key_pair_generate,
+#endif
+};
+
+
+static const uint16_t key_pair_generate_context_size[] =
+{
+#if NRF_CRYPTO_ECC_SECP160R1_ENABLED
+ NRF_CRYPTO_BACKEND_SECP160R1_KEY_PAIR_GENERATE_CONTEXT_SIZE,
+#endif
+#if NRF_CRYPTO_ECC_SECP160R2_ENABLED
+ NRF_CRYPTO_BACKEND_SECP160R2_KEY_PAIR_GENERATE_CONTEXT_SIZE,
+#endif
+#if NRF_CRYPTO_ECC_SECP192R1_ENABLED
+ NRF_CRYPTO_BACKEND_SECP192R1_KEY_PAIR_GENERATE_CONTEXT_SIZE,
+#endif
+#if NRF_CRYPTO_ECC_SECP224R1_ENABLED
+ NRF_CRYPTO_BACKEND_SECP224R1_KEY_PAIR_GENERATE_CONTEXT_SIZE,
+#endif
+#if NRF_CRYPTO_ECC_SECP256R1_ENABLED
+ NRF_CRYPTO_BACKEND_SECP256R1_KEY_PAIR_GENERATE_CONTEXT_SIZE,
+#endif
+#if NRF_CRYPTO_ECC_SECP384R1_ENABLED
+ NRF_CRYPTO_BACKEND_SECP384R1_KEY_PAIR_GENERATE_CONTEXT_SIZE,
+#endif
+#if NRF_CRYPTO_ECC_SECP521R1_ENABLED
+ NRF_CRYPTO_BACKEND_SECP521R1_KEY_PAIR_GENERATE_CONTEXT_SIZE,
+#endif
+#if NRF_CRYPTO_ECC_SECP160K1_ENABLED
+ NRF_CRYPTO_BACKEND_SECP160K1_KEY_PAIR_GENERATE_CONTEXT_SIZE,
+#endif
+#if NRF_CRYPTO_ECC_SECP192K1_ENABLED
+ NRF_CRYPTO_BACKEND_SECP192K1_KEY_PAIR_GENERATE_CONTEXT_SIZE,
+#endif
+#if NRF_CRYPTO_ECC_SECP224K1_ENABLED
+ NRF_CRYPTO_BACKEND_SECP224K1_KEY_PAIR_GENERATE_CONTEXT_SIZE,
+#endif
+#if NRF_CRYPTO_ECC_SECP256K1_ENABLED
+ NRF_CRYPTO_BACKEND_SECP256K1_KEY_PAIR_GENERATE_CONTEXT_SIZE,
+#endif
+#if NRF_CRYPTO_ECC_BP256R1_ENABLED
+ NRF_CRYPTO_BACKEND_BP256R1_KEY_PAIR_GENERATE_CONTEXT_SIZE,
+#endif
+#if NRF_CRYPTO_ECC_BP384R1_ENABLED
+ NRF_CRYPTO_BACKEND_BP384R1_KEY_PAIR_GENERATE_CONTEXT_SIZE,
+#endif
+#if NRF_CRYPTO_ECC_BP512R1_ENABLED
+ NRF_CRYPTO_BACKEND_BP512R1_KEY_PAIR_GENERATE_CONTEXT_SIZE,
+#endif
+#if NRF_CRYPTO_ECC_CURVE25519_ENABLED
+ NRF_CRYPTO_BACKEND_CURVE25519_KEY_PAIR_GENERATE_CONTEXT_SIZE,
+#endif
+#if NRF_CRYPTO_ECC_ED25519_ENABLED
+ NRF_CRYPTO_BACKEND_ED25519_KEY_PAIR_GENERATE_CONTEXT_SIZE,
+#endif
+};
+
+
+static const nrf_crypto_backend_ecc_public_key_calculate_fn_t public_key_calculate_impl[] =
+{
+#if NRF_CRYPTO_ECC_SECP160R1_ENABLED
+ nrf_crypto_backend_secp160r1_public_key_calculate,
+#endif
+#if NRF_CRYPTO_ECC_SECP160R2_ENABLED
+ nrf_crypto_backend_secp160r2_public_key_calculate,
+#endif
+#if NRF_CRYPTO_ECC_SECP192R1_ENABLED
+ nrf_crypto_backend_secp192r1_public_key_calculate,
+#endif
+#if NRF_CRYPTO_ECC_SECP224R1_ENABLED
+ nrf_crypto_backend_secp224r1_public_key_calculate,
+#endif
+#if NRF_CRYPTO_ECC_SECP256R1_ENABLED
+ nrf_crypto_backend_secp256r1_public_key_calculate,
+#endif
+#if NRF_CRYPTO_ECC_SECP384R1_ENABLED
+ nrf_crypto_backend_secp384r1_public_key_calculate,
+#endif
+#if NRF_CRYPTO_ECC_SECP521R1_ENABLED
+ nrf_crypto_backend_secp521r1_public_key_calculate,
+#endif
+#if NRF_CRYPTO_ECC_SECP160K1_ENABLED
+ nrf_crypto_backend_secp160k1_public_key_calculate,
+#endif
+#if NRF_CRYPTO_ECC_SECP192K1_ENABLED
+ nrf_crypto_backend_secp192k1_public_key_calculate,
+#endif
+#if NRF_CRYPTO_ECC_SECP224K1_ENABLED
+ nrf_crypto_backend_secp224k1_public_key_calculate,
+#endif
+#if NRF_CRYPTO_ECC_SECP256K1_ENABLED
+ nrf_crypto_backend_secp256k1_public_key_calculate,
+#endif
+#if NRF_CRYPTO_ECC_BP256R1_ENABLED
+ nrf_crypto_backend_bp256r1_public_key_calculate,
+#endif
+#if NRF_CRYPTO_ECC_BP384R1_ENABLED
+ nrf_crypto_backend_bp384r1_public_key_calculate,
+#endif
+#if NRF_CRYPTO_ECC_BP512R1_ENABLED
+ nrf_crypto_backend_bp512r1_public_key_calculate,
+#endif
+#if NRF_CRYPTO_ECC_CURVE25519_ENABLED
+ nrf_crypto_backend_curve25519_public_key_calculate,
+#endif
+#if NRF_CRYPTO_ECC_ED25519_ENABLED
+ nrf_crypto_backend_ed25519_public_key_calculate,
+#endif
+};
+
+
+static const uint16_t public_key_calculate_context_size[] =
+{
+#if NRF_CRYPTO_ECC_SECP160R1_ENABLED
+ NRF_CRYPTO_BACKEND_SECP160R1_PUBLIC_KEY_CALCULATE_CONTEXT_SIZE,
+#endif
+#if NRF_CRYPTO_ECC_SECP160R2_ENABLED
+ NRF_CRYPTO_BACKEND_SECP160R2_PUBLIC_KEY_CALCULATE_CONTEXT_SIZE,
+#endif
+#if NRF_CRYPTO_ECC_SECP192R1_ENABLED
+ NRF_CRYPTO_BACKEND_SECP192R1_PUBLIC_KEY_CALCULATE_CONTEXT_SIZE,
+#endif
+#if NRF_CRYPTO_ECC_SECP224R1_ENABLED
+ NRF_CRYPTO_BACKEND_SECP224R1_PUBLIC_KEY_CALCULATE_CONTEXT_SIZE,
+#endif
+#if NRF_CRYPTO_ECC_SECP256R1_ENABLED
+ NRF_CRYPTO_BACKEND_SECP256R1_PUBLIC_KEY_CALCULATE_CONTEXT_SIZE,
+#endif
+#if NRF_CRYPTO_ECC_SECP384R1_ENABLED
+ NRF_CRYPTO_BACKEND_SECP384R1_PUBLIC_KEY_CALCULATE_CONTEXT_SIZE,
+#endif
+#if NRF_CRYPTO_ECC_SECP521R1_ENABLED
+ NRF_CRYPTO_BACKEND_SECP521R1_PUBLIC_KEY_CALCULATE_CONTEXT_SIZE,
+#endif
+#if NRF_CRYPTO_ECC_SECP160K1_ENABLED
+ NRF_CRYPTO_BACKEND_SECP160K1_PUBLIC_KEY_CALCULATE_CONTEXT_SIZE,
+#endif
+#if NRF_CRYPTO_ECC_SECP192K1_ENABLED
+ NRF_CRYPTO_BACKEND_SECP192K1_PUBLIC_KEY_CALCULATE_CONTEXT_SIZE,
+#endif
+#if NRF_CRYPTO_ECC_SECP224K1_ENABLED
+ NRF_CRYPTO_BACKEND_SECP224K1_PUBLIC_KEY_CALCULATE_CONTEXT_SIZE,
+#endif
+#if NRF_CRYPTO_ECC_SECP256K1_ENABLED
+ NRF_CRYPTO_BACKEND_SECP256K1_PUBLIC_KEY_CALCULATE_CONTEXT_SIZE,
+#endif
+#if NRF_CRYPTO_ECC_BP256R1_ENABLED
+ NRF_CRYPTO_BACKEND_BP256R1_PUBLIC_KEY_CALCULATE_CONTEXT_SIZE,
+#endif
+#if NRF_CRYPTO_ECC_BP384R1_ENABLED
+ NRF_CRYPTO_BACKEND_BP384R1_PUBLIC_KEY_CALCULATE_CONTEXT_SIZE,
+#endif
+#if NRF_CRYPTO_ECC_BP512R1_ENABLED
+ NRF_CRYPTO_BACKEND_BP512R1_PUBLIC_KEY_CALCULATE_CONTEXT_SIZE,
+#endif
+#if NRF_CRYPTO_ECC_CURVE25519_ENABLED
+ NRF_CRYPTO_BACKEND_CURVE25519_PUBLIC_KEY_CALCULATE_CONTEXT_SIZE,
+#endif
+#if NRF_CRYPTO_ECC_ED25519_ENABLED
+ NRF_CRYPTO_BACKEND_ED25519_PUBLIC_KEY_CALCULATE_CONTEXT_SIZE,
+#endif
+};
+
+
+static const nrf_crypto_backend_ecc_private_key_from_raw_fn_t private_key_from_raw_impl[] =
+{
+#if NRF_CRYPTO_ECC_SECP160R1_ENABLED
+ nrf_crypto_backend_secp160r1_private_key_from_raw,
+#endif
+#if NRF_CRYPTO_ECC_SECP160R2_ENABLED
+ nrf_crypto_backend_secp160r2_private_key_from_raw,
+#endif
+#if NRF_CRYPTO_ECC_SECP192R1_ENABLED
+ nrf_crypto_backend_secp192r1_private_key_from_raw,
+#endif
+#if NRF_CRYPTO_ECC_SECP224R1_ENABLED
+ nrf_crypto_backend_secp224r1_private_key_from_raw,
+#endif
+#if NRF_CRYPTO_ECC_SECP256R1_ENABLED
+ nrf_crypto_backend_secp256r1_private_key_from_raw,
+#endif
+#if NRF_CRYPTO_ECC_SECP384R1_ENABLED
+ nrf_crypto_backend_secp384r1_private_key_from_raw,
+#endif
+#if NRF_CRYPTO_ECC_SECP521R1_ENABLED
+ nrf_crypto_backend_secp521r1_private_key_from_raw,
+#endif
+#if NRF_CRYPTO_ECC_SECP160K1_ENABLED
+ nrf_crypto_backend_secp160k1_private_key_from_raw,
+#endif
+#if NRF_CRYPTO_ECC_SECP192K1_ENABLED
+ nrf_crypto_backend_secp192k1_private_key_from_raw,
+#endif
+#if NRF_CRYPTO_ECC_SECP224K1_ENABLED
+ nrf_crypto_backend_secp224k1_private_key_from_raw,
+#endif
+#if NRF_CRYPTO_ECC_SECP256K1_ENABLED
+ nrf_crypto_backend_secp256k1_private_key_from_raw,
+#endif
+#if NRF_CRYPTO_ECC_BP256R1_ENABLED
+ nrf_crypto_backend_bp256r1_private_key_from_raw,
+#endif
+#if NRF_CRYPTO_ECC_BP384R1_ENABLED
+ nrf_crypto_backend_bp384r1_private_key_from_raw,
+#endif
+#if NRF_CRYPTO_ECC_BP512R1_ENABLED
+ nrf_crypto_backend_bp512r1_private_key_from_raw,
+#endif
+#if NRF_CRYPTO_ECC_CURVE25519_ENABLED
+ nrf_crypto_backend_curve25519_private_key_from_raw,
+#endif
+#if NRF_CRYPTO_ECC_ED25519_ENABLED
+ nrf_crypto_backend_ed25519_private_key_from_raw,
+#endif
+};
+
+
+static const nrf_crypto_backend_ecc_private_key_to_raw_fn_t private_key_to_raw_impl[] =
+{
+#if NRF_CRYPTO_ECC_SECP160R1_ENABLED
+ nrf_crypto_backend_secp160r1_private_key_to_raw,
+#endif
+#if NRF_CRYPTO_ECC_SECP160R2_ENABLED
+ nrf_crypto_backend_secp160r2_private_key_to_raw,
+#endif
+#if NRF_CRYPTO_ECC_SECP192R1_ENABLED
+ nrf_crypto_backend_secp192r1_private_key_to_raw,
+#endif
+#if NRF_CRYPTO_ECC_SECP224R1_ENABLED
+ nrf_crypto_backend_secp224r1_private_key_to_raw,
+#endif
+#if NRF_CRYPTO_ECC_SECP256R1_ENABLED
+ nrf_crypto_backend_secp256r1_private_key_to_raw,
+#endif
+#if NRF_CRYPTO_ECC_SECP384R1_ENABLED
+ nrf_crypto_backend_secp384r1_private_key_to_raw,
+#endif
+#if NRF_CRYPTO_ECC_SECP521R1_ENABLED
+ nrf_crypto_backend_secp521r1_private_key_to_raw,
+#endif
+#if NRF_CRYPTO_ECC_SECP160K1_ENABLED
+ nrf_crypto_backend_secp160k1_private_key_to_raw,
+#endif
+#if NRF_CRYPTO_ECC_SECP192K1_ENABLED
+ nrf_crypto_backend_secp192k1_private_key_to_raw,
+#endif
+#if NRF_CRYPTO_ECC_SECP224K1_ENABLED
+ nrf_crypto_backend_secp224k1_private_key_to_raw,
+#endif
+#if NRF_CRYPTO_ECC_SECP256K1_ENABLED
+ nrf_crypto_backend_secp256k1_private_key_to_raw,
+#endif
+#if NRF_CRYPTO_ECC_BP256R1_ENABLED
+ nrf_crypto_backend_bp256r1_private_key_to_raw,
+#endif
+#if NRF_CRYPTO_ECC_BP384R1_ENABLED
+ nrf_crypto_backend_bp384r1_private_key_to_raw,
+#endif
+#if NRF_CRYPTO_ECC_BP512R1_ENABLED
+ nrf_crypto_backend_bp512r1_private_key_to_raw,
+#endif
+#if NRF_CRYPTO_ECC_CURVE25519_ENABLED
+ nrf_crypto_backend_curve25519_private_key_to_raw,
+#endif
+#if NRF_CRYPTO_ECC_ED25519_ENABLED
+ nrf_crypto_backend_ed25519_private_key_to_raw,
+#endif
+};
+
+
+static const nrf_crypto_backend_ecc_public_key_from_raw_fn_t public_key_from_raw_impl[] =
+{
+#if NRF_CRYPTO_ECC_SECP160R1_ENABLED
+ nrf_crypto_backend_secp160r1_public_key_from_raw,
+#endif
+#if NRF_CRYPTO_ECC_SECP160R2_ENABLED
+ nrf_crypto_backend_secp160r2_public_key_from_raw,
+#endif
+#if NRF_CRYPTO_ECC_SECP192R1_ENABLED
+ nrf_crypto_backend_secp192r1_public_key_from_raw,
+#endif
+#if NRF_CRYPTO_ECC_SECP224R1_ENABLED
+ nrf_crypto_backend_secp224r1_public_key_from_raw,
+#endif
+#if NRF_CRYPTO_ECC_SECP256R1_ENABLED
+ nrf_crypto_backend_secp256r1_public_key_from_raw,
+#endif
+#if NRF_CRYPTO_ECC_SECP384R1_ENABLED
+ nrf_crypto_backend_secp384r1_public_key_from_raw,
+#endif
+#if NRF_CRYPTO_ECC_SECP521R1_ENABLED
+ nrf_crypto_backend_secp521r1_public_key_from_raw,
+#endif
+#if NRF_CRYPTO_ECC_SECP160K1_ENABLED
+ nrf_crypto_backend_secp160k1_public_key_from_raw,
+#endif
+#if NRF_CRYPTO_ECC_SECP192K1_ENABLED
+ nrf_crypto_backend_secp192k1_public_key_from_raw,
+#endif
+#if NRF_CRYPTO_ECC_SECP224K1_ENABLED
+ nrf_crypto_backend_secp224k1_public_key_from_raw,
+#endif
+#if NRF_CRYPTO_ECC_SECP256K1_ENABLED
+ nrf_crypto_backend_secp256k1_public_key_from_raw,
+#endif
+#if NRF_CRYPTO_ECC_BP256R1_ENABLED
+ nrf_crypto_backend_bp256r1_public_key_from_raw,
+#endif
+#if NRF_CRYPTO_ECC_BP384R1_ENABLED
+ nrf_crypto_backend_bp384r1_public_key_from_raw,
+#endif
+#if NRF_CRYPTO_ECC_BP512R1_ENABLED
+ nrf_crypto_backend_bp512r1_public_key_from_raw,
+#endif
+#if NRF_CRYPTO_ECC_CURVE25519_ENABLED
+ nrf_crypto_backend_curve25519_public_key_from_raw,
+#endif
+#if NRF_CRYPTO_ECC_ED25519_ENABLED
+ nrf_crypto_backend_ed25519_public_key_from_raw,
+#endif
+};
+
+
+static const nrf_crypto_backend_ecc_public_key_to_raw_fn_t public_key_to_raw_impl[] =
+{
+#if NRF_CRYPTO_ECC_SECP160R1_ENABLED
+ nrf_crypto_backend_secp160r1_public_key_to_raw,
+#endif
+#if NRF_CRYPTO_ECC_SECP160R2_ENABLED
+ nrf_crypto_backend_secp160r2_public_key_to_raw,
+#endif
+#if NRF_CRYPTO_ECC_SECP192R1_ENABLED
+ nrf_crypto_backend_secp192r1_public_key_to_raw,
+#endif
+#if NRF_CRYPTO_ECC_SECP224R1_ENABLED
+ nrf_crypto_backend_secp224r1_public_key_to_raw,
+#endif
+#if NRF_CRYPTO_ECC_SECP256R1_ENABLED
+ nrf_crypto_backend_secp256r1_public_key_to_raw,
+#endif
+#if NRF_CRYPTO_ECC_SECP384R1_ENABLED
+ nrf_crypto_backend_secp384r1_public_key_to_raw,
+#endif
+#if NRF_CRYPTO_ECC_SECP521R1_ENABLED
+ nrf_crypto_backend_secp521r1_public_key_to_raw,
+#endif
+#if NRF_CRYPTO_ECC_SECP160K1_ENABLED
+ nrf_crypto_backend_secp160k1_public_key_to_raw,
+#endif
+#if NRF_CRYPTO_ECC_SECP192K1_ENABLED
+ nrf_crypto_backend_secp192k1_public_key_to_raw,
+#endif
+#if NRF_CRYPTO_ECC_SECP224K1_ENABLED
+ nrf_crypto_backend_secp224k1_public_key_to_raw,
+#endif
+#if NRF_CRYPTO_ECC_SECP256K1_ENABLED
+ nrf_crypto_backend_secp256k1_public_key_to_raw,
+#endif
+#if NRF_CRYPTO_ECC_BP256R1_ENABLED
+ nrf_crypto_backend_bp256r1_public_key_to_raw,
+#endif
+#if NRF_CRYPTO_ECC_BP384R1_ENABLED
+ nrf_crypto_backend_bp384r1_public_key_to_raw,
+#endif
+#if NRF_CRYPTO_ECC_BP512R1_ENABLED
+ nrf_crypto_backend_bp512r1_public_key_to_raw,
+#endif
+#if NRF_CRYPTO_ECC_CURVE25519_ENABLED
+ nrf_crypto_backend_curve25519_public_key_to_raw,
+#endif
+#if NRF_CRYPTO_ECC_ED25519_ENABLED
+ nrf_crypto_backend_ed25519_public_key_to_raw,
+#endif
+};
+
+
+static const nrf_crypto_backend_ecc_key_free_fn_t private_key_free_impl[] =
+{
+#if NRF_CRYPTO_ECC_SECP160R1_ENABLED
+ nrf_crypto_backend_secp160r1_private_key_free,
+#endif
+#if NRF_CRYPTO_ECC_SECP160R2_ENABLED
+ nrf_crypto_backend_secp160r2_private_key_free,
+#endif
+#if NRF_CRYPTO_ECC_SECP192R1_ENABLED
+ nrf_crypto_backend_secp192r1_private_key_free,
+#endif
+#if NRF_CRYPTO_ECC_SECP224R1_ENABLED
+ nrf_crypto_backend_secp224r1_private_key_free,
+#endif
+#if NRF_CRYPTO_ECC_SECP256R1_ENABLED
+ nrf_crypto_backend_secp256r1_private_key_free,
+#endif
+#if NRF_CRYPTO_ECC_SECP384R1_ENABLED
+ nrf_crypto_backend_secp384r1_private_key_free,
+#endif
+#if NRF_CRYPTO_ECC_SECP521R1_ENABLED
+ nrf_crypto_backend_secp521r1_private_key_free,
+#endif
+#if NRF_CRYPTO_ECC_SECP160K1_ENABLED
+ nrf_crypto_backend_secp160k1_private_key_free,
+#endif
+#if NRF_CRYPTO_ECC_SECP192K1_ENABLED
+ nrf_crypto_backend_secp192k1_private_key_free,
+#endif
+#if NRF_CRYPTO_ECC_SECP224K1_ENABLED
+ nrf_crypto_backend_secp224k1_private_key_free,
+#endif
+#if NRF_CRYPTO_ECC_SECP256K1_ENABLED
+ nrf_crypto_backend_secp256k1_private_key_free,
+#endif
+#if NRF_CRYPTO_ECC_BP256R1_ENABLED
+ nrf_crypto_backend_bp256r1_private_key_free,
+#endif
+#if NRF_CRYPTO_ECC_BP384R1_ENABLED
+ nrf_crypto_backend_bp384r1_private_key_free,
+#endif
+#if NRF_CRYPTO_ECC_BP512R1_ENABLED
+ nrf_crypto_backend_bp512r1_private_key_free,
+#endif
+#if NRF_CRYPTO_ECC_CURVE25519_ENABLED
+ nrf_crypto_backend_curve25519_private_key_free,
+#endif
+#if NRF_CRYPTO_ECC_ED25519_ENABLED
+ nrf_crypto_backend_ed25519_private_key_free,
+#endif
+};
+
+
+static const nrf_crypto_backend_ecc_key_free_fn_t public_key_free_impl[] =
+{
+#if NRF_CRYPTO_ECC_SECP160R1_ENABLED
+ nrf_crypto_backend_secp160r1_public_key_free,
+#endif
+#if NRF_CRYPTO_ECC_SECP160R2_ENABLED
+ nrf_crypto_backend_secp160r2_public_key_free,
+#endif
+#if NRF_CRYPTO_ECC_SECP192R1_ENABLED
+ nrf_crypto_backend_secp192r1_public_key_free,
+#endif
+#if NRF_CRYPTO_ECC_SECP224R1_ENABLED
+ nrf_crypto_backend_secp224r1_public_key_free,
+#endif
+#if NRF_CRYPTO_ECC_SECP256R1_ENABLED
+ nrf_crypto_backend_secp256r1_public_key_free,
+#endif
+#if NRF_CRYPTO_ECC_SECP384R1_ENABLED
+ nrf_crypto_backend_secp384r1_public_key_free,
+#endif
+#if NRF_CRYPTO_ECC_SECP521R1_ENABLED
+ nrf_crypto_backend_secp521r1_public_key_free,
+#endif
+#if NRF_CRYPTO_ECC_SECP160K1_ENABLED
+ nrf_crypto_backend_secp160k1_public_key_free,
+#endif
+#if NRF_CRYPTO_ECC_SECP192K1_ENABLED
+ nrf_crypto_backend_secp192k1_public_key_free,
+#endif
+#if NRF_CRYPTO_ECC_SECP224K1_ENABLED
+ nrf_crypto_backend_secp224k1_public_key_free,
+#endif
+#if NRF_CRYPTO_ECC_SECP256K1_ENABLED
+ nrf_crypto_backend_secp256k1_public_key_free,
+#endif
+#if NRF_CRYPTO_ECC_BP256R1_ENABLED
+ nrf_crypto_backend_bp256r1_public_key_free,
+#endif
+#if NRF_CRYPTO_ECC_BP384R1_ENABLED
+ nrf_crypto_backend_bp384r1_public_key_free,
+#endif
+#if NRF_CRYPTO_ECC_BP512R1_ENABLED
+ nrf_crypto_backend_bp512r1_public_key_free,
+#endif
+#if NRF_CRYPTO_ECC_CURVE25519_ENABLED
+ nrf_crypto_backend_curve25519_public_key_free,
+#endif
+#if NRF_CRYPTO_ECC_ED25519_ENABLED
+ nrf_crypto_backend_ed25519_public_key_free,
+#endif
+};
+
+
+#define BACKEND_IMPL_GET(table, curve_type) (table)[(uint32_t)(curve_type)]
+
+
+#else
+
+
+#if NRF_CRYPTO_ECC_SECP160R1_ENABLED
+#define key_pair_generate_impl nrf_crypto_backend_secp160r1_key_pair_generate
+#define public_key_calculate_impl nrf_crypto_backend_secp160r1_public_key_calculate
+#define private_key_from_raw_impl nrf_crypto_backend_secp160r1_private_key_from_raw
+#define private_key_to_raw_impl nrf_crypto_backend_secp160r1_private_key_to_raw
+#define public_key_from_raw_impl nrf_crypto_backend_secp160r1_public_key_from_raw
+#define public_key_to_raw_impl nrf_crypto_backend_secp160r1_public_key_to_raw
+#define private_key_free_impl nrf_crypto_backend_secp160r1_private_key_free
+#define public_key_free_impl nrf_crypto_backend_secp160r1_public_key_free
+#define key_pair_generate_context_size \
+ NRF_CRYPTO_BACKEND_SECP160R1_KEY_PAIR_GENERATE_CONTEXT_SIZE
+#define public_key_calculate_context_size \
+ NRF_CRYPTO_BACKEND_SECP160R1_PUBLIC_KEY_CALCULATE_CONTEXT_SIZE
+#elif NRF_CRYPTO_ECC_SECP160R2_ENABLED
+#define key_pair_generate_impl nrf_crypto_backend_secp160r2_key_pair_generate
+#define public_key_calculate_impl nrf_crypto_backend_secp160r2_public_key_calculate
+#define private_key_from_raw_impl nrf_crypto_backend_secp160r2_private_key_from_raw
+#define private_key_to_raw_impl nrf_crypto_backend_secp160r2_private_key_to_raw
+#define public_key_from_raw_impl nrf_crypto_backend_secp160r2_public_key_from_raw
+#define public_key_to_raw_impl nrf_crypto_backend_secp160r2_public_key_to_raw
+#define private_key_free_impl nrf_crypto_backend_secp160r2_private_key_free
+#define public_key_free_impl nrf_crypto_backend_secp160r2_public_key_free
+#define key_pair_generate_context_size \
+ NRF_CRYPTO_BACKEND_SECP160R2_KEY_PAIR_GENERATE_CONTEXT_SIZE
+#define public_key_calculate_context_size \
+ NRF_CRYPTO_BACKEND_SECP160R2_PUBLIC_KEY_CALCULATE_CONTEXT_SIZE
+#elif NRF_CRYPTO_ECC_SECP192R1_ENABLED
+#define key_pair_generate_impl nrf_crypto_backend_secp192r1_key_pair_generate
+#define public_key_calculate_impl nrf_crypto_backend_secp192r1_public_key_calculate
+#define private_key_from_raw_impl nrf_crypto_backend_secp192r1_private_key_from_raw
+#define private_key_to_raw_impl nrf_crypto_backend_secp192r1_private_key_to_raw
+#define public_key_from_raw_impl nrf_crypto_backend_secp192r1_public_key_from_raw
+#define public_key_to_raw_impl nrf_crypto_backend_secp192r1_public_key_to_raw
+#define private_key_free_impl nrf_crypto_backend_secp192r1_private_key_free
+#define public_key_free_impl nrf_crypto_backend_secp192r1_public_key_free
+#define key_pair_generate_context_size \
+ NRF_CRYPTO_BACKEND_SECP192R1_KEY_PAIR_GENERATE_CONTEXT_SIZE
+#define public_key_calculate_context_size \
+ NRF_CRYPTO_BACKEND_SECP192R1_PUBLIC_KEY_CALCULATE_CONTEXT_SIZE
+#elif NRF_CRYPTO_ECC_SECP224R1_ENABLED
+#define key_pair_generate_impl nrf_crypto_backend_secp224r1_key_pair_generate
+#define public_key_calculate_impl nrf_crypto_backend_secp224r1_public_key_calculate
+#define private_key_from_raw_impl nrf_crypto_backend_secp224r1_private_key_from_raw
+#define private_key_to_raw_impl nrf_crypto_backend_secp224r1_private_key_to_raw
+#define public_key_from_raw_impl nrf_crypto_backend_secp224r1_public_key_from_raw
+#define public_key_to_raw_impl nrf_crypto_backend_secp224r1_public_key_to_raw
+#define private_key_free_impl nrf_crypto_backend_secp224r1_private_key_free
+#define public_key_free_impl nrf_crypto_backend_secp224r1_public_key_free
+#define key_pair_generate_context_size \
+ NRF_CRYPTO_BACKEND_SECP224R1_KEY_PAIR_GENERATE_CONTEXT_SIZE
+#define public_key_calculate_context_size \
+ NRF_CRYPTO_BACKEND_SECP224R1_PUBLIC_KEY_CALCULATE_CONTEXT_SIZE
+#elif NRF_CRYPTO_ECC_SECP256R1_ENABLED
+#define key_pair_generate_impl nrf_crypto_backend_secp256r1_key_pair_generate
+#define public_key_calculate_impl nrf_crypto_backend_secp256r1_public_key_calculate
+#define private_key_from_raw_impl nrf_crypto_backend_secp256r1_private_key_from_raw
+#define private_key_to_raw_impl nrf_crypto_backend_secp256r1_private_key_to_raw
+#define public_key_from_raw_impl nrf_crypto_backend_secp256r1_public_key_from_raw
+#define public_key_to_raw_impl nrf_crypto_backend_secp256r1_public_key_to_raw
+#define private_key_free_impl nrf_crypto_backend_secp256r1_private_key_free
+#define public_key_free_impl nrf_crypto_backend_secp256r1_public_key_free
+#define key_pair_generate_context_size \
+ NRF_CRYPTO_BACKEND_SECP256R1_KEY_PAIR_GENERATE_CONTEXT_SIZE
+#define public_key_calculate_context_size \
+ NRF_CRYPTO_BACKEND_SECP256R1_PUBLIC_KEY_CALCULATE_CONTEXT_SIZE
+#elif NRF_CRYPTO_ECC_SECP384R1_ENABLED
+#define key_pair_generate_impl nrf_crypto_backend_secp384r1_key_pair_generate
+#define public_key_calculate_impl nrf_crypto_backend_secp384r1_public_key_calculate
+#define private_key_from_raw_impl nrf_crypto_backend_secp384r1_private_key_from_raw
+#define private_key_to_raw_impl nrf_crypto_backend_secp384r1_private_key_to_raw
+#define public_key_from_raw_impl nrf_crypto_backend_secp384r1_public_key_from_raw
+#define public_key_to_raw_impl nrf_crypto_backend_secp384r1_public_key_to_raw
+#define private_key_free_impl nrf_crypto_backend_secp384r1_private_key_free
+#define public_key_free_impl nrf_crypto_backend_secp384r1_public_key_free
+#define key_pair_generate_context_size \
+ NRF_CRYPTO_BACKEND_SECP384R1_KEY_PAIR_GENERATE_CONTEXT_SIZE
+#define public_key_calculate_context_size \
+ NRF_CRYPTO_BACKEND_SECP384R1_PUBLIC_KEY_CALCULATE_CONTEXT_SIZE
+#elif NRF_CRYPTO_ECC_SECP521R1_ENABLED
+#define key_pair_generate_impl nrf_crypto_backend_secp521r1_key_pair_generate
+#define public_key_calculate_impl nrf_crypto_backend_secp521r1_public_key_calculate
+#define private_key_from_raw_impl nrf_crypto_backend_secp521r1_private_key_from_raw
+#define private_key_to_raw_impl nrf_crypto_backend_secp521r1_private_key_to_raw
+#define public_key_from_raw_impl nrf_crypto_backend_secp521r1_public_key_from_raw
+#define public_key_to_raw_impl nrf_crypto_backend_secp521r1_public_key_to_raw
+#define private_key_free_impl nrf_crypto_backend_secp521r1_private_key_free
+#define public_key_free_impl nrf_crypto_backend_secp521r1_public_key_free
+#define key_pair_generate_context_size \
+ NRF_CRYPTO_BACKEND_SECP521R1_KEY_PAIR_GENERATE_CONTEXT_SIZE
+#define public_key_calculate_context_size \
+ NRF_CRYPTO_BACKEND_SECP521R1_PUBLIC_KEY_CALCULATE_CONTEXT_SIZE
+#elif NRF_CRYPTO_ECC_SECP160K1_ENABLED
+#define key_pair_generate_impl nrf_crypto_backend_secp160k1_key_pair_generate
+#define public_key_calculate_impl nrf_crypto_backend_secp160k1_public_key_calculate
+#define private_key_from_raw_impl nrf_crypto_backend_secp160k1_private_key_from_raw
+#define private_key_to_raw_impl nrf_crypto_backend_secp160k1_private_key_to_raw
+#define public_key_from_raw_impl nrf_crypto_backend_secp160k1_public_key_from_raw
+#define public_key_to_raw_impl nrf_crypto_backend_secp160k1_public_key_to_raw
+#define private_key_free_impl nrf_crypto_backend_secp160k1_private_key_free
+#define public_key_free_impl nrf_crypto_backend_secp160k1_public_key_free
+#define key_pair_generate_context_size \
+ NRF_CRYPTO_BACKEND_SECP160K1_KEY_PAIR_GENERATE_CONTEXT_SIZE
+#define public_key_calculate_context_size \
+ NRF_CRYPTO_BACKEND_SECP160K1_PUBLIC_KEY_CALCULATE_CONTEXT_SIZE
+#elif NRF_CRYPTO_ECC_SECP192K1_ENABLED
+#define key_pair_generate_impl nrf_crypto_backend_secp192k1_key_pair_generate
+#define public_key_calculate_impl nrf_crypto_backend_secp192k1_public_key_calculate
+#define private_key_from_raw_impl nrf_crypto_backend_secp192k1_private_key_from_raw
+#define private_key_to_raw_impl nrf_crypto_backend_secp192k1_private_key_to_raw
+#define public_key_from_raw_impl nrf_crypto_backend_secp192k1_public_key_from_raw
+#define public_key_to_raw_impl nrf_crypto_backend_secp192k1_public_key_to_raw
+#define private_key_free_impl nrf_crypto_backend_secp192k1_private_key_free
+#define public_key_free_impl nrf_crypto_backend_secp192k1_public_key_free
+#define key_pair_generate_context_size \
+ NRF_CRYPTO_BACKEND_SECP192K1_KEY_PAIR_GENERATE_CONTEXT_SIZE
+#define public_key_calculate_context_size \
+ NRF_CRYPTO_BACKEND_SECP192K1_PUBLIC_KEY_CALCULATE_CONTEXT_SIZE
+#elif NRF_CRYPTO_ECC_SECP224K1_ENABLED
+#define key_pair_generate_impl nrf_crypto_backend_secp224k1_key_pair_generate
+#define public_key_calculate_impl nrf_crypto_backend_secp224k1_public_key_calculate
+#define private_key_from_raw_impl nrf_crypto_backend_secp224k1_private_key_from_raw
+#define private_key_to_raw_impl nrf_crypto_backend_secp224k1_private_key_to_raw
+#define public_key_from_raw_impl nrf_crypto_backend_secp224k1_public_key_from_raw
+#define public_key_to_raw_impl nrf_crypto_backend_secp224k1_public_key_to_raw
+#define private_key_free_impl nrf_crypto_backend_secp224k1_private_key_free
+#define public_key_free_impl nrf_crypto_backend_secp224k1_public_key_free
+#define key_pair_generate_context_size \
+ NRF_CRYPTO_BACKEND_SECP224K1_KEY_PAIR_GENERATE_CONTEXT_SIZE
+#define public_key_calculate_context_size \
+ NRF_CRYPTO_BACKEND_SECP224K1_PUBLIC_KEY_CALCULATE_CONTEXT_SIZE
+#elif NRF_CRYPTO_ECC_SECP256K1_ENABLED
+#define key_pair_generate_impl nrf_crypto_backend_secp256k1_key_pair_generate
+#define public_key_calculate_impl nrf_crypto_backend_secp256k1_public_key_calculate
+#define private_key_from_raw_impl nrf_crypto_backend_secp256k1_private_key_from_raw
+#define private_key_to_raw_impl nrf_crypto_backend_secp256k1_private_key_to_raw
+#define public_key_from_raw_impl nrf_crypto_backend_secp256k1_public_key_from_raw
+#define public_key_to_raw_impl nrf_crypto_backend_secp256k1_public_key_to_raw
+#define private_key_free_impl nrf_crypto_backend_secp256k1_private_key_free
+#define public_key_free_impl nrf_crypto_backend_secp256k1_public_key_free
+#define key_pair_generate_context_size \
+ NRF_CRYPTO_BACKEND_SECP256K1_KEY_PAIR_GENERATE_CONTEXT_SIZE
+#define public_key_calculate_context_size \
+ NRF_CRYPTO_BACKEND_SECP256K1_PUBLIC_KEY_CALCULATE_CONTEXT_SIZE
+#elif NRF_CRYPTO_ECC_BP256R1_ENABLED
+#define key_pair_generate_impl nrf_crypto_backend_bp256r1_key_pair_generate
+#define public_key_calculate_impl nrf_crypto_backend_bp256r1_public_key_calculate
+#define private_key_from_raw_impl nrf_crypto_backend_bp256r1_private_key_from_raw
+#define private_key_to_raw_impl nrf_crypto_backend_bp256r1_private_key_to_raw
+#define public_key_from_raw_impl nrf_crypto_backend_bp256r1_public_key_from_raw
+#define public_key_to_raw_impl nrf_crypto_backend_bp256r1_public_key_to_raw
+#define private_key_free_impl nrf_crypto_backend_bp256r1_private_key_free
+#define public_key_free_impl nrf_crypto_backend_bp256r1_public_key_free
+#define key_pair_generate_context_size \
+ NRF_CRYPTO_BACKEND_BP256R1_KEY_PAIR_GENERATE_CONTEXT_SIZE
+#define public_key_calculate_context_size \
+ NRF_CRYPTO_BACKEND_BP256R1_PUBLIC_KEY_CALCULATE_CONTEXT_SIZE
+#elif NRF_CRYPTO_ECC_BP384R1_ENABLED
+#define key_pair_generate_impl nrf_crypto_backend_bp384r1_key_pair_generate
+#define public_key_calculate_impl nrf_crypto_backend_bp384r1_public_key_calculate
+#define private_key_from_raw_impl nrf_crypto_backend_bp384r1_private_key_from_raw
+#define private_key_to_raw_impl nrf_crypto_backend_bp384r1_private_key_to_raw
+#define public_key_from_raw_impl nrf_crypto_backend_bp384r1_public_key_from_raw
+#define public_key_to_raw_impl nrf_crypto_backend_bp384r1_public_key_to_raw
+#define private_key_free_impl nrf_crypto_backend_bp384r1_private_key_free
+#define public_key_free_impl nrf_crypto_backend_bp384r1_public_key_free
+#define key_pair_generate_context_size \
+ NRF_CRYPTO_BACKEND_BP384R1_KEY_PAIR_GENERATE_CONTEXT_SIZE
+#define public_key_calculate_context_size \
+ NRF_CRYPTO_BACKEND_BP384R1_PUBLIC_KEY_CALCULATE_CONTEXT_SIZE
+#elif NRF_CRYPTO_ECC_BP512R1_ENABLED
+#define key_pair_generate_impl nrf_crypto_backend_bp512r1_key_pair_generate
+#define public_key_calculate_impl nrf_crypto_backend_bp512r1_public_key_calculate
+#define private_key_from_raw_impl nrf_crypto_backend_bp512r1_private_key_from_raw
+#define private_key_to_raw_impl nrf_crypto_backend_bp512r1_private_key_to_raw
+#define public_key_from_raw_impl nrf_crypto_backend_bp512r1_public_key_from_raw
+#define public_key_to_raw_impl nrf_crypto_backend_bp512r1_public_key_to_raw
+#define private_key_free_impl nrf_crypto_backend_bp512r1_private_key_free
+#define public_key_free_impl nrf_crypto_backend_bp512r1_public_key_free
+#define key_pair_generate_context_size \
+ NRF_CRYPTO_BACKEND_BP512R1_KEY_PAIR_GENERATE_CONTEXT_SIZE
+#define public_key_calculate_context_size \
+ NRF_CRYPTO_BACKEND_BP512R1_PUBLIC_KEY_CALCULATE_CONTEXT_SIZE
+#elif NRF_CRYPTO_ECC_CURVE25519_ENABLED
+#define key_pair_generate_impl nrf_crypto_backend_curve25519_key_pair_generate
+#define public_key_calculate_impl nrf_crypto_backend_curve25519_public_key_calculate
+#define private_key_from_raw_impl nrf_crypto_backend_curve25519_private_key_from_raw
+#define private_key_to_raw_impl nrf_crypto_backend_curve25519_private_key_to_raw
+#define public_key_from_raw_impl nrf_crypto_backend_curve25519_public_key_from_raw
+#define public_key_to_raw_impl nrf_crypto_backend_curve25519_public_key_to_raw
+#define private_key_free_impl nrf_crypto_backend_curve25519_private_key_free
+#define public_key_free_impl nrf_crypto_backend_curve25519_public_key_free
+#define key_pair_generate_context_size \
+ NRF_CRYPTO_BACKEND_CURVE25519_KEY_PAIR_GENERATE_CONTEXT_SIZE
+#define public_key_calculate_context_size \
+ NRF_CRYPTO_BACKEND_CURVE25519_PUBLIC_KEY_CALCULATE_CONTEXT_SIZE
+#elif NRF_CRYPTO_ECC_ED25519_ENABLED
+#define key_pair_generate_impl nrf_crypto_backend_ed25519_key_pair_generate
+#define public_key_calculate_impl nrf_crypto_backend_ed25519_public_key_calculate
+#define private_key_from_raw_impl nrf_crypto_backend_ed25519_private_key_from_raw
+#define private_key_to_raw_impl nrf_crypto_backend_ed25519_private_key_to_raw
+#define public_key_from_raw_impl nrf_crypto_backend_ed25519_public_key_from_raw
+#define public_key_to_raw_impl nrf_crypto_backend_ed25519_public_key_to_raw
+#define private_key_free_impl nrf_crypto_backend_ed25519_private_key_free
+#define public_key_free_impl nrf_crypto_backend_ed25519_public_key_free
+#define key_pair_generate_context_size \
+ NRF_CRYPTO_BACKEND_ED25519_KEY_PAIR_GENERATE_CONTEXT_SIZE
+#define public_key_calculate_context_size \
+ NRF_CRYPTO_BACKEND_ED25519_PUBLIC_KEY_CALCULATE_CONTEXT_SIZE
+#else
+#define key_pair_generate_impl NULL
+#define public_key_calculate_impl NULL
+#define private_key_from_raw_impl NULL
+#define private_key_to_raw_impl NULL
+#define public_key_from_raw_impl NULL
+#define public_key_to_raw_impl NULL
+#define private_key_free_impl NULL
+#define public_key_free_impl NULL
+#define key_pair_generate_context_size 0
+#define public_key_calculate_context_size 0
+#endif
+
+
+#define BACKEND_IMPL_GET(function, curve_type) (function)
+
+
+#endif
+
+
+ret_code_t nrf_crypto_internal_ecc_key_output_prepare(
+ nrf_crypto_ecc_curve_info_t const * p_curve_info,
+ nrf_crypto_internal_ecc_key_header_t * p_key_header)
+{
+ // Check NULL pointers
+ VERIFY_TRUE(p_curve_info != NULL, NRF_ERROR_CRYPTO_INPUT_NULL);
+ VERIFY_TRUE(p_key_header != NULL, NRF_ERROR_CRYPTO_OUTPUT_NULL);
+
+ // Clear init value to indicate that this key is not valid yet.
+ p_key_header->init_value = 0;
+ // Save curve info inside the header
+ p_key_header->p_info = p_curve_info;
+
+ return NRF_SUCCESS;
+}
+
+
+ret_code_t nrf_crypto_internal_ecc_key_input_check(
+ nrf_crypto_internal_ecc_key_header_t const * p_key_header,
+ uint32_t init_value)
+{
+ // Check NULL pointer
+ VERIFY_TRUE(p_key_header != NULL, NRF_ERROR_CRYPTO_INPUT_NULL);
+ // Check init value
+ VERIFY_TRUE(p_key_header->init_value == init_value, NRF_ERROR_CRYPTO_ECC_KEY_NOT_INITIALIZED);
+
+ return NRF_SUCCESS;
+}
+
+
+ret_code_t nrf_crypto_internal_ecc_raw_output_prepare(
+ uint8_t * p_raw_data,
+ size_t * p_raw_data_size,
+ size_t expected_size)
+{
+ // Check NULL pointer
+ VERIFY_TRUE(p_raw_data != NULL, NRF_ERROR_CRYPTO_OUTPUT_NULL);
+
+ if (p_raw_data_size != NULL) // User can provide NULL as p_raw_data_size to skip size checking
+ {
+ // Check if data fits into buffer
+ VERIFY_TRUE(*p_raw_data_size >= expected_size, NRF_ERROR_CRYPTO_OUTPUT_LENGTH);
+ // Provide actual data size
+ *p_raw_data_size = expected_size;
+ }
+
+ return NRF_SUCCESS;
+}
+
+
+ret_code_t nrf_crypto_internal_ecc_raw_input_check(
+ uint8_t const * p_raw_data,
+ size_t raw_data_size,
+ size_t expected_size)
+{
+ VERIFY_TRUE(p_raw_data != NULL, NRF_ERROR_CRYPTO_INPUT_NULL);
+ VERIFY_TRUE(raw_data_size == expected_size, NRF_ERROR_CRYPTO_INPUT_LENGTH);
+
+ return NRF_SUCCESS;
+}
+
+
+ret_code_t nrf_crypto_ecc_key_pair_generate(
+ nrf_crypto_ecc_key_pair_generate_context_t * p_context,
+ nrf_crypto_ecc_curve_info_t const * p_curve_info,
+ nrf_crypto_ecc_private_key_t * p_private_key,
+ nrf_crypto_ecc_public_key_t * p_public_key)
+{
+ ret_code_t result;
+ void * p_allocated_context = NULL;
+ nrf_crypto_backend_ecc_key_pair_generate_fn_t backend_implementation;
+ size_t context_size;
+
+ // Get pointer to header for each key
+ nrf_crypto_internal_ecc_key_header_t * p_private_key_header =
+ (nrf_crypto_internal_ecc_key_header_t *)p_private_key;
+ nrf_crypto_internal_ecc_key_header_t * p_public_key_header =
+ (nrf_crypto_internal_ecc_key_header_t *)p_public_key;
+
+ // Check and prepare parameters
+ result = nrf_crypto_internal_ecc_key_output_prepare(p_curve_info, p_private_key_header);
+ VERIFY_SUCCESS(result);
+ result = nrf_crypto_internal_ecc_key_output_prepare(p_curve_info, p_public_key_header);
+ VERIFY_SUCCESS(result);
+
+ // Get backend specific information
+ backend_implementation = BACKEND_IMPL_GET(key_pair_generate_impl, p_curve_info->curve_type);
+ context_size = BACKEND_IMPL_GET(key_pair_generate_context_size, p_curve_info->curve_type);
+ VERIFY_TRUE(backend_implementation != NULL, NRF_ERROR_CRYPTO_FEATURE_UNAVAILABLE);
+
+ // Allocate context if not provided
+ if (p_context == NULL && context_size > 0)
+ {
+ p_allocated_context = NRF_CRYPTO_ALLOC(context_size);
+ VERIFY_TRUE(p_allocated_context != NULL, NRF_ERROR_CRYPTO_ALLOC_FAILED);
+ p_context = p_allocated_context;
+ }
+
+ // Execute backend implementation
+ result = backend_implementation(p_context, p_private_key, p_public_key);
+
+ // Set init values to indicate valid key
+ if (result == NRF_SUCCESS)
+ {
+ p_private_key_header->init_value = NRF_CRYPTO_INTERNAL_ECC_PRIVATE_KEY_INIT_VALUE;
+ p_public_key_header->init_value = NRF_CRYPTO_INTERNAL_ECC_PUBLIC_KEY_INIT_VALUE;
+ }
+
+ // Deallocate context if allocated
+ if (p_allocated_context != NULL)
+ {
+ NRF_CRYPTO_FREE(p_allocated_context);
+ }
+
+ return result;
+}
+
+
+ret_code_t nrf_crypto_ecc_public_key_calculate(
+ nrf_crypto_ecc_public_key_calculate_context_t * p_context,
+ nrf_crypto_ecc_private_key_t const * p_private_key,
+ nrf_crypto_ecc_public_key_t * p_public_key)
+{
+ ret_code_t result;
+ void * p_allocated_context = NULL;
+ nrf_crypto_backend_ecc_public_key_calculate_fn_t backend_implementation;
+ size_t context_size;
+ nrf_crypto_ecc_curve_info_t const * p_info;
+
+ // Get pointer to header for each key
+ nrf_crypto_internal_ecc_key_header_t const * p_private_key_header =
+ (nrf_crypto_internal_ecc_key_header_t const *)p_private_key;
+ nrf_crypto_internal_ecc_key_header_t * p_public_key_header =
+ (nrf_crypto_internal_ecc_key_header_t *)p_public_key;
+
+ // Check and prepare parameters
+ result = nrf_crypto_internal_ecc_key_input_check(
+ p_private_key_header,
+ NRF_CRYPTO_INTERNAL_ECC_PRIVATE_KEY_INIT_VALUE);
+ VERIFY_SUCCESS(result);
+ p_info = p_private_key_header->p_info;
+ result = nrf_crypto_internal_ecc_key_output_prepare(p_info, p_public_key_header);
+ VERIFY_SUCCESS(result);
+
+ // Get backend specific information
+ backend_implementation = BACKEND_IMPL_GET(public_key_calculate_impl, p_info->curve_type);
+ context_size = BACKEND_IMPL_GET(public_key_calculate_context_size, p_info->curve_type);
+ VERIFY_TRUE(backend_implementation != NULL, NRF_ERROR_CRYPTO_FEATURE_UNAVAILABLE);
+
+ // Allocate context if not provided
+ if (p_context == NULL && context_size > 0)
+ {
+ p_allocated_context = NRF_CRYPTO_ALLOC(context_size);
+ VERIFY_TRUE(p_allocated_context != NULL, NRF_ERROR_CRYPTO_ALLOC_FAILED);
+ p_context = p_allocated_context;
+ }
+
+ // Execute backend implementation
+ result = backend_implementation(p_context, p_private_key, p_public_key);
+
+ // Set init values to indicate valid key
+ if (result == NRF_SUCCESS)
+ {
+ p_public_key_header->init_value = NRF_CRYPTO_INTERNAL_ECC_PUBLIC_KEY_INIT_VALUE;
+ }
+
+ // Deallocate context if allocated
+ if (p_allocated_context != NULL)
+ {
+ NRF_CRYPTO_FREE(p_allocated_context);
+ }
+
+ return result;
+}
+
+
+ret_code_t nrf_crypto_ecc_private_key_from_raw(
+ nrf_crypto_ecc_curve_info_t const * p_curve_info,
+ nrf_crypto_ecc_private_key_t * p_private_key,
+ uint8_t const * p_raw_data,
+ size_t raw_data_size)
+{
+ ret_code_t result;
+ nrf_crypto_backend_ecc_private_key_from_raw_fn_t backend_implementation;
+
+ // Get pointer to header
+ nrf_crypto_internal_ecc_key_header_t * p_private_key_header =
+ (nrf_crypto_internal_ecc_key_header_t *)p_private_key;
+
+ // Check and prepare parameters
+ result = nrf_crypto_internal_ecc_key_output_prepare(p_curve_info,
+ p_private_key_header);
+ VERIFY_SUCCESS(result);
+ result = nrf_crypto_internal_ecc_raw_input_check(p_raw_data,
+ raw_data_size,
+ p_curve_info->raw_private_key_size);
+ VERIFY_SUCCESS(result);
+
+ // Get backend specific information
+ backend_implementation = BACKEND_IMPL_GET(private_key_from_raw_impl, p_curve_info->curve_type);
+ VERIFY_TRUE(backend_implementation != NULL, NRF_ERROR_CRYPTO_FEATURE_UNAVAILABLE);
+
+ // Execute backend implementation
+ result = backend_implementation(p_private_key, p_raw_data);
+
+ // Set init value to indicate valid key
+ if (result == NRF_SUCCESS)
+ {
+ p_private_key_header->init_value = NRF_CRYPTO_INTERNAL_ECC_PRIVATE_KEY_INIT_VALUE;
+ }
+
+ return result;
+}
+
+
+ret_code_t nrf_crypto_ecc_private_key_to_raw(
+ nrf_crypto_ecc_private_key_t const * p_private_key,
+ uint8_t * p_raw_data,
+ size_t * p_raw_data_size)
+{
+ ret_code_t result;
+ nrf_crypto_ecc_curve_info_t const * p_info;
+ nrf_crypto_backend_ecc_private_key_to_raw_fn_t backend_implementation;
+
+ // Get pointer to header
+ nrf_crypto_internal_ecc_key_header_t const * p_private_key_header =
+ (nrf_crypto_internal_ecc_key_header_t const *)p_private_key;
+
+ // Check and prepare parameters
+ result = nrf_crypto_internal_ecc_key_input_check(
+ p_private_key_header,
+ NRF_CRYPTO_INTERNAL_ECC_PRIVATE_KEY_INIT_VALUE);
+ VERIFY_SUCCESS(result);
+ p_info = p_private_key_header->p_info;
+ result = nrf_crypto_internal_ecc_raw_output_prepare(p_raw_data,
+ p_raw_data_size,
+ p_info->raw_private_key_size);
+ VERIFY_SUCCESS(result);
+
+ // Get backend specific information
+ backend_implementation = BACKEND_IMPL_GET(private_key_to_raw_impl, p_info->curve_type);
+ VERIFY_TRUE(backend_implementation != NULL, NRF_ERROR_CRYPTO_FEATURE_UNAVAILABLE);
+
+ // Execute backend implementation
+ result = backend_implementation(p_private_key, p_raw_data);
+
+ return result;
+}
+
+
+ret_code_t nrf_crypto_ecc_public_key_from_raw(
+ nrf_crypto_ecc_curve_info_t const * p_curve_info,
+ nrf_crypto_ecc_public_key_t * p_public_key,
+ uint8_t const * p_raw_data,
+ size_t raw_data_size)
+{
+ ret_code_t result;
+ nrf_crypto_backend_ecc_private_key_from_raw_fn_t backend_implementation;
+
+ // Get pointer to header
+ nrf_crypto_internal_ecc_key_header_t * p_public_key_header =
+ (nrf_crypto_internal_ecc_key_header_t *)p_public_key;
+
+ // Check and prepare parameters
+ result = nrf_crypto_internal_ecc_key_output_prepare(p_curve_info,
+ p_public_key_header);
+ VERIFY_SUCCESS(result);
+ result = nrf_crypto_internal_ecc_raw_input_check(p_raw_data,
+ raw_data_size,
+ p_curve_info->raw_public_key_size);
+ VERIFY_SUCCESS(result);
+
+ // Get backend specific information
+ backend_implementation = BACKEND_IMPL_GET(public_key_from_raw_impl, p_curve_info->curve_type);
+ VERIFY_TRUE(backend_implementation != NULL, NRF_ERROR_CRYPTO_FEATURE_UNAVAILABLE);
+
+ // Execute backend implementation
+ result = backend_implementation(p_public_key, p_raw_data);
+
+ // Set init value to indicate valid key
+ if (result == NRF_SUCCESS)
+ {
+ p_public_key_header->init_value = NRF_CRYPTO_INTERNAL_ECC_PUBLIC_KEY_INIT_VALUE;
+ }
+
+ return result;
+}
+
+
+ret_code_t nrf_crypto_ecc_public_key_to_raw(
+ nrf_crypto_ecc_public_key_t const * p_public_key,
+ uint8_t * p_raw_data,
+ size_t * p_raw_data_size)
+{
+ ret_code_t result;
+ nrf_crypto_ecc_curve_info_t const * p_info;
+ nrf_crypto_backend_ecc_public_key_to_raw_fn_t backend_implementation;
+
+ // Get pointer to header
+ nrf_crypto_internal_ecc_key_header_t const * p_public_key_header =
+ (nrf_crypto_internal_ecc_key_header_t const *)p_public_key;
+
+ // Check and prepare parameters
+ result = nrf_crypto_internal_ecc_key_input_check(
+ p_public_key_header,
+ NRF_CRYPTO_INTERNAL_ECC_PUBLIC_KEY_INIT_VALUE);
+ VERIFY_SUCCESS(result);
+ p_info = p_public_key_header->p_info;
+ result = nrf_crypto_internal_ecc_raw_output_prepare(p_raw_data,
+ p_raw_data_size,
+ p_info->raw_public_key_size);
+ VERIFY_SUCCESS(result);
+
+ // Get backend specific information
+ backend_implementation = BACKEND_IMPL_GET(public_key_to_raw_impl, p_info->curve_type);
+ VERIFY_TRUE(backend_implementation != NULL, NRF_ERROR_CRYPTO_FEATURE_UNAVAILABLE);
+
+ // Execute backend implementation
+ result = backend_implementation(p_public_key, p_raw_data);
+
+ return result;
+}
+
+
+ret_code_t nrf_crypto_ecc_private_key_free(
+ nrf_crypto_ecc_private_key_t * p_private_key)
+{
+ ret_code_t result;
+ nrf_crypto_ecc_curve_info_t const * p_info;
+ nrf_crypto_backend_ecc_key_free_fn_t backend_implementation;
+
+ // Get pointer to header
+ nrf_crypto_internal_ecc_key_header_t * p_private_key_header =
+ (nrf_crypto_internal_ecc_key_header_t *)p_private_key;
+
+ // Check and prepare parameters
+ result = nrf_crypto_internal_ecc_key_input_check(
+ p_private_key_header,
+ NRF_CRYPTO_INTERNAL_ECC_PRIVATE_KEY_INIT_VALUE);
+ VERIFY_SUCCESS(result);
+ p_info = p_private_key_header->p_info;
+
+ UNUSED_PARAMETER(p_info); // Is some situations BACKEND_IMPL_GET() macro may not use second parameter
+
+ // Get backend specific information
+ backend_implementation = BACKEND_IMPL_GET(private_key_free_impl, p_info->curve_type);
+
+ if (backend_implementation != NULL)
+ {
+ // Execute backend implementation
+ result = backend_implementation(p_private_key);
+ }
+ else
+ {
+ // Free is not implemented by the backend, so nothing have to deallocated.
+ result = NRF_SUCCESS;
+ }
+
+ // Clear init value to indicate invalid key
+ p_private_key_header->init_value = 0;
+
+ return result;
+}
+
+
+ret_code_t nrf_crypto_ecc_public_key_free(
+ nrf_crypto_ecc_public_key_t * p_public_key)
+{
+ ret_code_t result;
+ nrf_crypto_ecc_curve_info_t const * p_info;
+ nrf_crypto_backend_ecc_key_free_fn_t backend_implementation;
+
+ // Get pointer to header
+ nrf_crypto_internal_ecc_key_header_t * p_public_key_header =
+ (nrf_crypto_internal_ecc_key_header_t *)p_public_key;
+
+ // Check and prepare parameters
+ result = nrf_crypto_internal_ecc_key_input_check(
+ p_public_key_header,
+ NRF_CRYPTO_INTERNAL_ECC_PUBLIC_KEY_INIT_VALUE);
+ VERIFY_SUCCESS(result);
+ p_info = p_public_key_header->p_info;
+
+ UNUSED_PARAMETER(p_info); // Is some situations BACKEND_IMPL_GET() macro may not use second parameter
+
+ // Get backend specific information
+ backend_implementation = BACKEND_IMPL_GET(public_key_free_impl, p_info->curve_type);
+
+ if (backend_implementation != NULL)
+ {
+ // Execute backend implementation
+ result = backend_implementation(p_public_key);
+ }
+ else
+ {
+ // Free is not implemented by the backend, so nothing have to deallocated.
+ result = NRF_SUCCESS;
+ }
+
+ // Clear init value to indicate invalid key
+ p_public_key_header->init_value = 0;
+
+ return result;
+}
+
+
+ret_code_t nrf_crypto_ecc_curve_info_get(
+ void const * p_key,
+ nrf_crypto_ecc_curve_info_t const ** pp_curve_info)
+{
+ ret_code_t result;
+
+ // Get pointer to header
+ nrf_crypto_internal_ecc_key_header_t const * p_key_header =
+ (nrf_crypto_internal_ecc_key_header_t const *)p_key;
+
+ // Check and prepare parameters
+ VERIFY_TRUE(pp_curve_info != NULL, NRF_ERROR_CRYPTO_INPUT_NULL);
+ result = nrf_crypto_internal_ecc_key_input_check(
+ p_key_header,
+ NRF_CRYPTO_INTERNAL_ECC_PRIVATE_KEY_INIT_VALUE);
+ if (result != NRF_SUCCESS)
+ {
+ // p_key can be private or public key, so check second case here
+ result = nrf_crypto_internal_ecc_key_input_check(
+ p_key_header,
+ NRF_CRYPTO_INTERNAL_ECC_PUBLIC_KEY_INIT_VALUE);
+ }
+ VERIFY_SUCCESS(result);
+
+ // Write output parameter
+ *pp_curve_info = p_key_header->p_info;
+
+ return NRF_SUCCESS;
+}
+
+
+ret_code_t nrf_crypto_ecc_byte_order_invert(
+ nrf_crypto_ecc_curve_info_t const * p_curve_info,
+ uint8_t const * p_raw_input,
+ uint8_t * p_raw_output,
+ size_t raw_data_size)
+{
+ uint8_t temp;
+ size_t from_index;
+ size_t to_index;
+ size_t integer_size;
+
+ if (p_curve_info == NULL)
+ {
+ integer_size = raw_data_size;
+ }
+ else
+ {
+ integer_size = p_curve_info->raw_private_key_size;
+ }
+
+ VERIFY_TRUE(p_raw_input != NULL, NRF_ERROR_CRYPTO_INPUT_NULL);
+ VERIFY_TRUE(p_raw_output != NULL, NRF_ERROR_CRYPTO_OUTPUT_NULL);
+
+ // Loop over each big integer of the input
+ while (raw_data_size >= integer_size)
+ {
+ // Swap byte by byte in current integer
+ from_index = 0;
+ to_index = integer_size - 1;
+ while (from_index <= to_index)
+ {
+ // Swap bytes from source to destination, this may be the same buffer, so use temporary variable
+ temp = p_raw_input[from_index];
+ p_raw_output[from_index] = p_raw_input[to_index];
+ p_raw_output[to_index] = temp;
+ // Go to next pair of bytes
+ from_index++;
+ to_index--;
+ }
+ // Go to next integer
+ raw_data_size -= integer_size;
+ p_raw_input += integer_size;
+ p_raw_output += integer_size;
+ }
+
+ if (raw_data_size != 0)
+ {
+ // Input size is not a multiple of big integer size, so it is invalid
+ return NRF_ERROR_CRYPTO_INPUT_LENGTH;
+ }
+
+ return NRF_SUCCESS;
+}
+
+
+#endif // NRF_CRYPTO_ECC_ENABLED
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/nrf_crypto_ecc.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/nrf_crypto_ecc.h
new file mode 100644
index 0000000..8fa825b
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/nrf_crypto_ecc.h
@@ -0,0 +1,999 @@
+/**
+ * Copyright (c) 2018 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+
+#ifndef NRF_CRYPTO_ECC_H__
+#define NRF_CRYPTO_ECC_H__
+
+/** @addtogroup nrf_crypto
+ * @{
+ * @addtogroup nrf_crypto_ecc Elliptic Curve Cryptography Key Management
+ * @{
+ * @brief Provides elliptic curve cryptography API for public and private key management.
+ *
+ * @addtogroup nrf_crypto_ecc_secp160r1 Definitions specific to secp160r1 (NIST 160-bit)
+ * @addtogroup nrf_crypto_ecc_secp160r2 Definitions specific to secp160r2 (NIST 160-bit)
+ * @addtogroup nrf_crypto_ecc_secp192r1 Definitions specific to secp192r1 (NIST 192-bit)
+ * @addtogroup nrf_crypto_ecc_secp224r1 Definitions specific to secp224r1 (NIST 224-bit)
+ * @addtogroup nrf_crypto_ecc_secp256r1 Definitions specific to secp256r1 (NIST 256-bit)
+ * @addtogroup nrf_crypto_ecc_secp384r1 Definitions specific to secp384r1 (NIST 384-bit)
+ * @addtogroup nrf_crypto_ecc_secp521r1 Definitions specific to secp521r1 (NIST 521-bit)
+ * @addtogroup nrf_crypto_ecc_secp160k1 Definitions specific to secp160k1 (Koblitz 160-bit)
+ * @addtogroup nrf_crypto_ecc_secp192k1 Definitions specific to secp192k1 (Koblitz 192-bit)
+ * @addtogroup nrf_crypto_ecc_secp224k1 Definitions specific to secp224k1 (Koblitz 224-bit)
+ * @addtogroup nrf_crypto_ecc_secp256k1 Definitions specific to secp256k1 (Koblitz 256-bit)
+ * @addtogroup nrf_crypto_ecc_bp256r1 Definitions specific to bp256r1 (Brainpool 256-bit)
+ * @addtogroup nrf_crypto_ecc_bp384r1 Definitions specific to bp384r1 (Brainpool 384-bit)
+ * @addtogroup nrf_crypto_ecc_bp512r1 Definitions specific to bp512r1 (Brainpool 512-bit)
+ * @addtogroup nrf_crypto_ecc_curve25519 Definitions specific to Curve25519
+ * @addtogroup nrf_crypto_ecc_ed25519 Definitions specific to Ed25519
+ */
+
+#include <stdint.h>
+#include <stddef.h>
+
+#include "nrf_crypto_error.h"
+#include "nrf_crypto_ecc_shared.h"
+#include "nrf_crypto_ecc_backend.h"
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+#if defined(__SDK_DOXYGEN__)
+#define NRF_CRYPTO_ECC_SECP160R1_ENABLED 1 /**< @brief Defined as 1 if secp160r1 (NIST 160-bit) is enabled in any of the backends and it is usable in the API, 0 otherwise. @ingroup nrf_crypto_ecc_secp160r1 */
+#define NRF_CRYPTO_ECC_SECP160R2_ENABLED 1 /**< @brief Defined as 1 if secp160r2 (NIST 160-bit) is enabled in any of the backends and it is usable in the API, 0 otherwise. @ingroup nrf_crypto_ecc_secp160r2 */
+#define NRF_CRYPTO_ECC_SECP192R1_ENABLED 1 /**< @brief Defined as 1 if secp192r1 (NIST 192-bit) is enabled in any of the backends and it is usable in the API, 0 otherwise. @ingroup nrf_crypto_ecc_secp192r1 */
+#define NRF_CRYPTO_ECC_SECP224R1_ENABLED 1 /**< @brief Defined as 1 if secp224r1 (NIST 224-bit) is enabled in any of the backends and it is usable in the API, 0 otherwise. @ingroup nrf_crypto_ecc_secp224r1 */
+#define NRF_CRYPTO_ECC_SECP256R1_ENABLED 1 /**< @brief Defined as 1 if secp256r1 (NIST 256-bit) is enabled in any of the backends and it is usable in the API, 0 otherwise. @ingroup nrf_crypto_ecc_secp256r1 */
+#define NRF_CRYPTO_ECC_SECP384R1_ENABLED 1 /**< @brief Defined as 1 if secp384r1 (NIST 384-bit) is enabled in any of the backends and it is usable in the API, 0 otherwise. @ingroup nrf_crypto_ecc_secp384r1 */
+#define NRF_CRYPTO_ECC_SECP521R1_ENABLED 1 /**< @brief Defined as 1 if secp521r1 (NIST 521-bit) is enabled in any of the backends and it is usable in the API, 0 otherwise. @ingroup nrf_crypto_ecc_secp521r1 */
+#define NRF_CRYPTO_ECC_SECP160K1_ENABLED 1 /**< @brief Defined as 1 if secp160k1 (Koblitz 160-bit) is enabled in any of the backends and it is usable in the API, 0 otherwise. @ingroup nrf_crypto_ecc_secp160k1 */
+#define NRF_CRYPTO_ECC_SECP192K1_ENABLED 1 /**< @brief Defined as 1 if secp192k1 (Koblitz 192-bit) is enabled in any of the backends and it is usable in the API, 0 otherwise. @ingroup nrf_crypto_ecc_secp192k1 */
+#define NRF_CRYPTO_ECC_SECP224K1_ENABLED 1 /**< @brief Defined as 1 if secp224k1 (Koblitz 224-bit) is enabled in any of the backends and it is usable in the API, 0 otherwise. @ingroup nrf_crypto_ecc_secp224k1 */
+#define NRF_CRYPTO_ECC_SECP256K1_ENABLED 1 /**< @brief Defined as 1 if secp256k1 (Koblitz 256-bit) is enabled in any of the backends and it is usable in the API, 0 otherwise. @ingroup nrf_crypto_ecc_secp256k1 */
+#define NRF_CRYPTO_ECC_BP256R1_ENABLED 1 /**< @brief Defined as 1 if bp256r1 (Brainpool 256-bit) is enabled in any of the backends and it is usable in the API, 0 otherwise. @ingroup nrf_crypto_ecc_bp256r1 */
+#define NRF_CRYPTO_ECC_BP384R1_ENABLED 1 /**< @brief Defined as 1 if bp384r1 (Brainpool 384-bit) is enabled in any of the backends and it is usable in the API, 0 otherwise. @ingroup nrf_crypto_ecc_bp384r1 */
+#define NRF_CRYPTO_ECC_BP512R1_ENABLED 1 /**< @brief Defined as 1 if bp512r1 (Brainpool 512-bit) is enabled in any of the backends and it is usable in the API, 0 otherwise. @ingroup nrf_crypto_ecc_bp512r1 */
+#define NRF_CRYPTO_ECC_CURVE25519_ENABLED 1 /**< @brief Defined as 1 if Curve25519 is enabled in any of the backends and it is usable in the API, 0 otherwise. @ingroup nrf_crypto_ecc_curve25519 */
+#define NRF_CRYPTO_ECC_ED25519_ENABLED 1 /**< @brief Defined as 1 if Ed25519 is enabled in any of the backends and it is usable in the API, 0 otherwise. @ingroup nrf_crypto_ecc_ed25519 */
+#endif
+
+
+#define NRF_CRYPTO_ECC_SECP160R1_RAW_PRIVATE_KEY_SIZE (160 / 8) /**< @brief Raw private key size for secp160r1 (NIST 160-bit). @ingroup nrf_crypto_ecc_secp160r1 */
+#define NRF_CRYPTO_ECC_SECP160R2_RAW_PRIVATE_KEY_SIZE (160 / 8) /**< @brief Raw private key size for secp160r2 (NIST 160-bit). @ingroup nrf_crypto_ecc_secp160r2 */
+#define NRF_CRYPTO_ECC_SECP192R1_RAW_PRIVATE_KEY_SIZE (192 / 8) /**< @brief Raw private key size for secp192r1 (NIST 192-bit). @ingroup nrf_crypto_ecc_secp192r1 */
+#define NRF_CRYPTO_ECC_SECP224R1_RAW_PRIVATE_KEY_SIZE (224 / 8) /**< @brief Raw private key size for secp224r1 (NIST 224-bit). @ingroup nrf_crypto_ecc_secp224r1 */
+#define NRF_CRYPTO_ECC_SECP256R1_RAW_PRIVATE_KEY_SIZE (256 / 8) /**< @brief Raw private key size for secp256r1 (NIST 256-bit). @ingroup nrf_crypto_ecc_secp256r1 */
+#define NRF_CRYPTO_ECC_SECP384R1_RAW_PRIVATE_KEY_SIZE (384 / 8) /**< @brief Raw private key size for secp384r1 (NIST 384-bit). @ingroup nrf_crypto_ecc_secp384r1 */
+#define NRF_CRYPTO_ECC_SECP521R1_RAW_PRIVATE_KEY_SIZE (528 / 8) /**< @brief Raw private key size for secp521r1 (NIST 521-bit). @ingroup nrf_crypto_ecc_secp521r1 */
+#define NRF_CRYPTO_ECC_SECP160K1_RAW_PRIVATE_KEY_SIZE (160 / 8) /**< @brief Raw private key size for secp160k1 (Koblitz 160-bit). @ingroup nrf_crypto_ecc_secp160k1 */
+#define NRF_CRYPTO_ECC_SECP192K1_RAW_PRIVATE_KEY_SIZE (192 / 8) /**< @brief Raw private key size for secp192k1 (Koblitz 192-bit). @ingroup nrf_crypto_ecc_secp192k1 */
+#define NRF_CRYPTO_ECC_SECP224K1_RAW_PRIVATE_KEY_SIZE (224 / 8) /**< @brief Raw private key size for secp224k1 (Koblitz 224-bit). @ingroup nrf_crypto_ecc_secp224k1 */
+#define NRF_CRYPTO_ECC_SECP256K1_RAW_PRIVATE_KEY_SIZE (256 / 8) /**< @brief Raw private key size for secp256k1 (Koblitz 256-bit). @ingroup nrf_crypto_ecc_secp256k1 */
+#define NRF_CRYPTO_ECC_BP256R1_RAW_PRIVATE_KEY_SIZE (256 / 8) /**< @brief Raw private key size for bp256r1 (Brainpool 256-bit). @ingroup nrf_crypto_ecc_bp256r1 */
+#define NRF_CRYPTO_ECC_BP384R1_RAW_PRIVATE_KEY_SIZE (384 / 8) /**< @brief Raw private key size for bp384r1 (Brainpool 384-bit). @ingroup nrf_crypto_ecc_bp384r1 */
+#define NRF_CRYPTO_ECC_BP512R1_RAW_PRIVATE_KEY_SIZE (512 / 8) /**< @brief Raw private key size for bp512r1 (Brainpool 512-bit). @ingroup nrf_crypto_ecc_bp512r1 */
+#define NRF_CRYPTO_ECC_CURVE25519_RAW_PRIVATE_KEY_SIZE (256 / 8) /**< @brief Raw private key size for Curve25519. @ingroup nrf_crypto_ecc_curve25519 */
+#define NRF_CRYPTO_ECC_ED25519_RAW_PRIVATE_KEY_SIZE (256 / 8) /**< @brief Raw private key size for Ed25519. @ingroup nrf_crypto_ecc_ed25519 */
+
+
+#define NRF_CRYPTO_ECC_SECP160R1_RAW_PUBLIC_KEY_SIZE (2 * 160 / 8) /**< @brief Raw public key size for curve secp160r1 (NIST 160-bit). @ingroup nrf_crypto_ecc_secp160r1 */
+#define NRF_CRYPTO_ECC_SECP160R2_RAW_PUBLIC_KEY_SIZE (2 * 160 / 8) /**< @brief Raw public key size for curve secp160r2 (NIST 160-bit). @ingroup nrf_crypto_ecc_secp160r2 */
+#define NRF_CRYPTO_ECC_SECP192R1_RAW_PUBLIC_KEY_SIZE (2 * 192 / 8) /**< @brief Raw public key size for curve secp192r1 (NIST 192-bit). @ingroup nrf_crypto_ecc_secp192r1 */
+#define NRF_CRYPTO_ECC_SECP224R1_RAW_PUBLIC_KEY_SIZE (2 * 224 / 8) /**< @brief Raw public key size for curve secp224r1 (NIST 224-bit). @ingroup nrf_crypto_ecc_secp224r1 */
+#define NRF_CRYPTO_ECC_SECP256R1_RAW_PUBLIC_KEY_SIZE (2 * 256 / 8) /**< @brief Raw public key size for curve secp256r1 (NIST 256-bit). @ingroup nrf_crypto_ecc_secp256r1 */
+#define NRF_CRYPTO_ECC_SECP384R1_RAW_PUBLIC_KEY_SIZE (2 * 384 / 8) /**< @brief Raw public key size for curve secp384r1 (NIST 384-bit). @ingroup nrf_crypto_ecc_secp384r1 */
+#define NRF_CRYPTO_ECC_SECP521R1_RAW_PUBLIC_KEY_SIZE (2 * 528 / 8) /**< @brief Raw public key size for curve secp521r1 (NIST 521-bit). @ingroup nrf_crypto_ecc_secp521r1 */
+#define NRF_CRYPTO_ECC_SECP160K1_RAW_PUBLIC_KEY_SIZE (2 * 160 / 8) /**< @brief Raw public key size for curve secp160k1 (Koblitz 160-bit). @ingroup nrf_crypto_ecc_secp160k1 */
+#define NRF_CRYPTO_ECC_SECP192K1_RAW_PUBLIC_KEY_SIZE (2 * 192 / 8) /**< @brief Raw public key size for curve secp192k1 (Koblitz 192-bit). @ingroup nrf_crypto_ecc_secp192k1 */
+#define NRF_CRYPTO_ECC_SECP224K1_RAW_PUBLIC_KEY_SIZE (2 * 224 / 8) /**< @brief Raw public key size for curve secp224k1 (Koblitz 224-bit). @ingroup nrf_crypto_ecc_secp224k1 */
+#define NRF_CRYPTO_ECC_SECP256K1_RAW_PUBLIC_KEY_SIZE (2 * 256 / 8) /**< @brief Raw public key size for curve secp256k1 (Koblitz 256-bit). @ingroup nrf_crypto_ecc_secp256k1 */
+#define NRF_CRYPTO_ECC_BP256R1_RAW_PUBLIC_KEY_SIZE (2 * 256 / 8) /**< @brief Raw public key size for curve bp256r1 (Brainpool 256-bit). @ingroup nrf_crypto_ecc_bp256r1 */
+#define NRF_CRYPTO_ECC_BP384R1_RAW_PUBLIC_KEY_SIZE (2 * 384 / 8) /**< @brief Raw public key size for curve bp384r1 (Brainpool 384-bit). @ingroup nrf_crypto_ecc_bp384r1 */
+#define NRF_CRYPTO_ECC_BP512R1_RAW_PUBLIC_KEY_SIZE (2 * 512 / 8) /**< @brief Raw public key size for curve bp512r1 (Brainpool 512-bit). @ingroup nrf_crypto_ecc_bp512r1 */
+#define NRF_CRYPTO_ECC_CURVE25519_RAW_PUBLIC_KEY_SIZE (256 / 8) /**< @brief Raw public key size for curve Curve25519. @ingroup nrf_crypto_ecc_curve25519 */
+#define NRF_CRYPTO_ECC_ED25519_RAW_PUBLIC_KEY_SIZE (256 / 8) /**< @brief Raw public key size for curve Ed25519. @ingroup nrf_crypto_ecc_ed25519 */
+
+
+#define NRF_CRYPTO_ECC_RAW_PRIVATE_KEY_MAX_SIZE NRF_CRYPTO_BACKEND_ECC_RAW_PRIVATE_KEY_MAX_SIZE /**< @brief Maximum size of a raw private key for all enabled curves. */
+#define NRF_CRYPTO_ECC_RAW_PUBLIC_KEY_MAX_SIZE NRF_CRYPTO_BACKEND_ECC_RAW_PUBLIC_KEY_MAX_SIZE /**< @brief Maximum size of a raw public key for all enabled curves. */
+
+
+/** @brief Defines type of ECC curve.
+ */
+typedef enum
+{
+#if NRF_CRYPTO_ECC_SECP160R1_ENABLED
+ NRF_CRYPTO_ECC_SECP160R1_CURVE_TYPE, /**< secp160r1 (NIST 160-bit) */
+#endif
+#if NRF_CRYPTO_ECC_SECP160R2_ENABLED
+ NRF_CRYPTO_ECC_SECP160R2_CURVE_TYPE, /**< secp160r2 (NIST 160-bit) */
+#endif
+#if NRF_CRYPTO_ECC_SECP192R1_ENABLED
+ NRF_CRYPTO_ECC_SECP192R1_CURVE_TYPE, /**< secp192r1 (NIST 192-bit) */
+#endif
+#if NRF_CRYPTO_ECC_SECP224R1_ENABLED
+ NRF_CRYPTO_ECC_SECP224R1_CURVE_TYPE, /**< secp224r1 (NIST 224-bit) */
+#endif
+#if NRF_CRYPTO_ECC_SECP256R1_ENABLED
+ NRF_CRYPTO_ECC_SECP256R1_CURVE_TYPE, /**< secp256r1 (NIST 256-bit) */
+#endif
+#if NRF_CRYPTO_ECC_SECP384R1_ENABLED
+ NRF_CRYPTO_ECC_SECP384R1_CURVE_TYPE, /**< secp384r1 (NIST 384-bit) */
+#endif
+#if NRF_CRYPTO_ECC_SECP521R1_ENABLED
+ NRF_CRYPTO_ECC_SECP521R1_CURVE_TYPE, /**< secp521r1 (NIST 521-bit) */
+#endif
+#if NRF_CRYPTO_ECC_SECP160K1_ENABLED
+ NRF_CRYPTO_ECC_SECP160K1_CURVE_TYPE, /**< secp160k1 (Koblitz 160-bit) */
+#endif
+#if NRF_CRYPTO_ECC_SECP192K1_ENABLED
+ NRF_CRYPTO_ECC_SECP192K1_CURVE_TYPE, /**< secp192k1 (Koblitz 192-bit) */
+#endif
+#if NRF_CRYPTO_ECC_SECP224K1_ENABLED
+ NRF_CRYPTO_ECC_SECP224K1_CURVE_TYPE, /**< secp224k1 (Koblitz 224-bit) */
+#endif
+#if NRF_CRYPTO_ECC_SECP256K1_ENABLED
+ NRF_CRYPTO_ECC_SECP256K1_CURVE_TYPE, /**< secp256k1 (Koblitz 256-bit) */
+#endif
+#if NRF_CRYPTO_ECC_BP256R1_ENABLED
+ NRF_CRYPTO_ECC_BP256R1_CURVE_TYPE, /**< bp256r1 (Brainpool 256-bit) */
+#endif
+#if NRF_CRYPTO_ECC_BP384R1_ENABLED
+ NRF_CRYPTO_ECC_BP384R1_CURVE_TYPE, /**< bp384r1 (Brainpool 384-bit) */
+#endif
+#if NRF_CRYPTO_ECC_BP512R1_ENABLED
+ NRF_CRYPTO_ECC_BP512R1_CURVE_TYPE, /**< bp512r1 (Brainpool 512-bit) */
+#endif
+#if NRF_CRYPTO_ECC_CURVE25519_ENABLED
+ NRF_CRYPTO_ECC_CURVE25519_CURVE_TYPE, /**< Curve25519 */
+#endif
+#if NRF_CRYPTO_ECC_ED25519_ENABLED
+ NRF_CRYPTO_ECC_ED25519_CURVE_TYPE, /**< Ed25519 */
+#endif
+#if !NRF_CRYPTO_ECC_SECP160R1_ENABLED
+ NRF_CRYPTO_ECC_SECP160R1_CURVE_TYPE, /**< secp160r1 (NIST 160-bit) */
+#endif
+#if !NRF_CRYPTO_ECC_SECP160R2_ENABLED
+ NRF_CRYPTO_ECC_SECP160R2_CURVE_TYPE, /**< secp160r2 (NIST 160-bit) */
+#endif
+#if !NRF_CRYPTO_ECC_SECP192R1_ENABLED
+ NRF_CRYPTO_ECC_SECP192R1_CURVE_TYPE, /**< secp192r1 (NIST 192-bit) */
+#endif
+#if !NRF_CRYPTO_ECC_SECP224R1_ENABLED
+ NRF_CRYPTO_ECC_SECP224R1_CURVE_TYPE, /**< secp224r1 (NIST 224-bit) */
+#endif
+#if !NRF_CRYPTO_ECC_SECP256R1_ENABLED
+ NRF_CRYPTO_ECC_SECP256R1_CURVE_TYPE, /**< secp256r1 (NIST 256-bit) */
+#endif
+#if !NRF_CRYPTO_ECC_SECP384R1_ENABLED
+ NRF_CRYPTO_ECC_SECP384R1_CURVE_TYPE, /**< secp384r1 (NIST 384-bit) */
+#endif
+#if !NRF_CRYPTO_ECC_SECP521R1_ENABLED
+ NRF_CRYPTO_ECC_SECP521R1_CURVE_TYPE, /**< secp521r1 (NIST 521-bit) */
+#endif
+#if !NRF_CRYPTO_ECC_SECP160K1_ENABLED
+ NRF_CRYPTO_ECC_SECP160K1_CURVE_TYPE, /**< secp160k1 (Koblitz 160-bit) */
+#endif
+#if !NRF_CRYPTO_ECC_SECP192K1_ENABLED
+ NRF_CRYPTO_ECC_SECP192K1_CURVE_TYPE, /**< secp192k1 (Koblitz 192-bit) */
+#endif
+#if !NRF_CRYPTO_ECC_SECP224K1_ENABLED
+ NRF_CRYPTO_ECC_SECP224K1_CURVE_TYPE, /**< secp224k1 (Koblitz 224-bit) */
+#endif
+#if !NRF_CRYPTO_ECC_SECP256K1_ENABLED
+ NRF_CRYPTO_ECC_SECP256K1_CURVE_TYPE, /**< secp256k1 (Koblitz 256-bit) */
+#endif
+#if !NRF_CRYPTO_ECC_BP256R1_ENABLED
+ NRF_CRYPTO_ECC_BP256R1_CURVE_TYPE, /**< bp256r1 (Brainpool 256-bit) */
+#endif
+#if !NRF_CRYPTO_ECC_BP384R1_ENABLED
+ NRF_CRYPTO_ECC_BP384R1_CURVE_TYPE, /**< bp384r1 (Brainpool 384-bit) */
+#endif
+#if !NRF_CRYPTO_ECC_BP512R1_ENABLED
+ NRF_CRYPTO_ECC_BP512R1_CURVE_TYPE, /**< bp512r1 (Brainpool 512-bit) */
+#endif
+#if !NRF_CRYPTO_ECC_CURVE25519_ENABLED
+ NRF_CRYPTO_ECC_CURVE25519_CURVE_TYPE, /**< Curve25519 */
+#endif
+#if !NRF_CRYPTO_ECC_ED25519_ENABLED
+ NRF_CRYPTO_ECC_ED25519_CURVE_TYPE, /**< Ed25519 */
+#endif
+} nrf_crypto_ecc_curve_type_t;
+
+
+/** @brief Structure holding information on a specific curve.
+ *
+ * @note This structure cannot be used to create a new variable. Only the variables defined by this
+ * library can be used, e.g. @ref g_nrf_crypto_ecc_secp256r1_curve_info.
+ */
+typedef struct nrf_crypto_ecc_curve_info_s
+{
+ uint16_t public_key_size; /**< @brief Size of a structure holding internal public key. */
+ uint16_t private_key_size; /**< @brief Size of a structure holding internal private key. */
+ nrf_crypto_ecc_curve_type_t curve_type; /**< @brief Type of the curve. */
+ uint8_t raw_private_key_size; /**< @brief Size of a buffer containing raw private key. */
+ uint8_t raw_public_key_size; /**< @brief Size of a buffer containing raw public key. */
+ void * p_backend_data; /**< @brief Field to hold backend specific internal data. */
+} nrf_crypto_ecc_curve_info_t;
+
+
+/** @addtogroup nrf_crypto_ecc_secp160r1
+ * @{ */
+
+typedef nrf_crypto_backend_secp160r1_key_pair_generate_context_t
+ nrf_crypto_ecc_secp160r1_key_pair_generate_context_t; /**< @brief Context structure for key generation using secp160r1 (NIST 160-bit). */
+typedef nrf_crypto_backend_secp160r1_public_key_calculate_context_t
+ nrf_crypto_ecc_secp160r1_public_key_calculate_context_t; /**< @brief Context structure for public key calculation using secp160r1 (NIST 160-bit). */
+typedef nrf_crypto_backend_secp160r1_private_key_t
+ nrf_crypto_ecc_secp160r1_private_key_t; /**< @brief Structure holding internal representation of a private key for secp160r1 (NIST 160-bit) */
+typedef nrf_crypto_backend_secp160r1_public_key_t
+ nrf_crypto_ecc_secp160r1_public_key_t; /**< @brief Structure holding internal representation of a public key for secp160r1 (NIST 160-bit) */
+typedef uint8_t nrf_crypto_ecc_secp160r1_raw_private_key_t
+ [NRF_CRYPTO_ECC_SECP160R1_RAW_PRIVATE_KEY_SIZE]; /**< @brief Array holding raw private key for secp160r1 (NIST 160-bit) */
+typedef uint8_t nrf_crypto_ecc_secp160r1_raw_public_key_t
+ [NRF_CRYPTO_ECC_SECP160R1_RAW_PUBLIC_KEY_SIZE]; /**< @brief Array holding raw public key for secp160r1 (NIST 160-bit) */
+
+
+#if NRF_CRYPTO_ECC_SECP160R1_ENABLED
+
+/** @brief Variable containing information on secp160r1 (NIST 160-bit).
+ *
+ * It can be used as a parameter for the functions creating secp160r1 (NIST 160-bit) keys.
+ */
+extern const nrf_crypto_ecc_curve_info_t g_nrf_crypto_ecc_secp160r1_curve_info;
+
+#endif
+
+/** @} */
+
+
+/** @addtogroup nrf_crypto_ecc_secp160r2
+ * @{ */
+
+typedef nrf_crypto_backend_secp160r2_key_pair_generate_context_t
+ nrf_crypto_ecc_secp160r2_key_pair_generate_context_t; /**< @brief Context structure for key generation using secp160r2 (NIST 160-bit). */
+typedef nrf_crypto_backend_secp160r2_public_key_calculate_context_t
+ nrf_crypto_ecc_secp160r2_public_key_calculate_context_t; /**< @brief Context structure for public key calculation using secp160r2 (NIST 160-bit). */
+typedef nrf_crypto_backend_secp160r2_private_key_t
+ nrf_crypto_ecc_secp160r2_private_key_t; /**< @brief Structure holding internal representation of a private key for secp160r2 (NIST 160-bit) */
+typedef nrf_crypto_backend_secp160r2_public_key_t
+ nrf_crypto_ecc_secp160r2_public_key_t; /**< @brief Structure holding internal representation of a public key for secp160r2 (NIST 160-bit) */
+typedef uint8_t nrf_crypto_ecc_secp160r2_raw_private_key_t
+ [NRF_CRYPTO_ECC_SECP160R2_RAW_PRIVATE_KEY_SIZE]; /**< @brief Array holding raw private key for secp160r2 (NIST 160-bit) */
+typedef uint8_t nrf_crypto_ecc_secp160r2_raw_public_key_t
+ [NRF_CRYPTO_ECC_SECP160R2_RAW_PUBLIC_KEY_SIZE]; /**< @brief Array holding raw public key for secp160r2 (NIST 160-bit) */
+
+
+#if NRF_CRYPTO_ECC_SECP160R2_ENABLED
+
+/** @brief Variable containing information on secp160r2 (NIST 160-bit).
+ *
+ * It can be used as a parameter for the functions creating secp160r2 (NIST 160-bit) keys.
+ */
+extern const nrf_crypto_ecc_curve_info_t g_nrf_crypto_ecc_secp160r2_curve_info;
+
+#endif
+
+/** @} */
+
+
+/** @addtogroup nrf_crypto_ecc_secp192r1
+ * @{ */
+
+typedef nrf_crypto_backend_secp192r1_key_pair_generate_context_t
+ nrf_crypto_ecc_secp192r1_key_pair_generate_context_t; /**< @brief Context structure for key generation using secp192r1 (NIST 192-bit). */
+typedef nrf_crypto_backend_secp192r1_public_key_calculate_context_t
+ nrf_crypto_ecc_secp192r1_public_key_calculate_context_t; /**< @brief Context structure for public key calculation using secp192r1 (NIST 192-bit). */
+typedef nrf_crypto_backend_secp192r1_private_key_t
+ nrf_crypto_ecc_secp192r1_private_key_t; /**< @brief Structure holding internal representation of a private key for secp192r1 (NIST 192-bit) */
+typedef nrf_crypto_backend_secp192r1_public_key_t
+ nrf_crypto_ecc_secp192r1_public_key_t; /**< @brief Structure holding internal representation of a public key for secp192r1 (NIST 192-bit) */
+typedef uint8_t nrf_crypto_ecc_secp192r1_raw_private_key_t
+ [NRF_CRYPTO_ECC_SECP192R1_RAW_PRIVATE_KEY_SIZE]; /**< @brief Array holding raw private key for secp192r1 (NIST 192-bit) */
+typedef uint8_t nrf_crypto_ecc_secp192r1_raw_public_key_t
+ [NRF_CRYPTO_ECC_SECP192R1_RAW_PUBLIC_KEY_SIZE]; /**< @brief Array holding raw public key for secp192r1 (NIST 192-bit) */
+
+
+#if NRF_CRYPTO_ECC_SECP192R1_ENABLED
+
+/** @brief Variable containing information on secp192r1 (NIST 192-bit).
+ *
+ * It can be used as a parameter for the functions creating secp192r1 (NIST 192-bit) keys.
+ */
+extern const nrf_crypto_ecc_curve_info_t g_nrf_crypto_ecc_secp192r1_curve_info;
+
+#endif
+
+/** @} */
+
+
+/** @addtogroup nrf_crypto_ecc_secp224r1
+ * @{ */
+
+typedef nrf_crypto_backend_secp224r1_key_pair_generate_context_t
+ nrf_crypto_ecc_secp224r1_key_pair_generate_context_t; /**< @brief Context structure for key generation using secp224r1 (NIST 224-bit). */
+typedef nrf_crypto_backend_secp224r1_public_key_calculate_context_t
+ nrf_crypto_ecc_secp224r1_public_key_calculate_context_t; /**< @brief Context structure for public key calculation using secp224r1 (NIST 224-bit). */
+typedef nrf_crypto_backend_secp224r1_private_key_t
+ nrf_crypto_ecc_secp224r1_private_key_t; /**< @brief Structure holding internal representation of a private key for secp224r1 (NIST 224-bit) */
+typedef nrf_crypto_backend_secp224r1_public_key_t
+ nrf_crypto_ecc_secp224r1_public_key_t; /**< @brief Structure holding internal representation of a public key for secp224r1 (NIST 224-bit) */
+typedef uint8_t nrf_crypto_ecc_secp224r1_raw_private_key_t
+ [NRF_CRYPTO_ECC_SECP224R1_RAW_PRIVATE_KEY_SIZE]; /**< @brief Array holding raw private key for secp224r1 (NIST 224-bit) */
+typedef uint8_t nrf_crypto_ecc_secp224r1_raw_public_key_t
+ [NRF_CRYPTO_ECC_SECP224R1_RAW_PUBLIC_KEY_SIZE]; /**< @brief Array holding raw public key for secp224r1 (NIST 224-bit) */
+
+
+#if NRF_CRYPTO_ECC_SECP224R1_ENABLED
+
+/** @brief Variable containing information on secp224r1 (NIST 224-bit).
+ *
+ * It can be used as a parameter for the functions creating secp224r1 (NIST 224-bit) keys.
+ */
+extern const nrf_crypto_ecc_curve_info_t g_nrf_crypto_ecc_secp224r1_curve_info;
+
+#endif
+
+/** @} */
+
+
+/** @addtogroup nrf_crypto_ecc_secp256r1
+ * @{ */
+
+typedef nrf_crypto_backend_secp256r1_key_pair_generate_context_t
+ nrf_crypto_ecc_secp256r1_key_pair_generate_context_t; /**< @brief Context structure for key generation using secp256r1 (NIST 256-bit). */
+typedef nrf_crypto_backend_secp256r1_public_key_calculate_context_t
+ nrf_crypto_ecc_secp256r1_public_key_calculate_context_t; /**< @brief Context structure for public key calculation using secp256r1 (NIST 256-bit). */
+typedef nrf_crypto_backend_secp256r1_private_key_t
+ nrf_crypto_ecc_secp256r1_private_key_t; /**< @brief Structure holding internal representation of a private key for secp256r1 (NIST 256-bit) */
+typedef nrf_crypto_backend_secp256r1_public_key_t
+ nrf_crypto_ecc_secp256r1_public_key_t; /**< @brief Structure holding internal representation of a public key for secp256r1 (NIST 256-bit) */
+typedef uint8_t nrf_crypto_ecc_secp256r1_raw_private_key_t
+ [NRF_CRYPTO_ECC_SECP256R1_RAW_PRIVATE_KEY_SIZE]; /**< @brief Array holding raw private key for secp256r1 (NIST 256-bit) */
+typedef uint8_t nrf_crypto_ecc_secp256r1_raw_public_key_t
+ [NRF_CRYPTO_ECC_SECP256R1_RAW_PUBLIC_KEY_SIZE]; /**< @brief Array holding raw public key for secp256r1 (NIST 256-bit) */
+
+
+#if NRF_CRYPTO_ECC_SECP256R1_ENABLED
+
+/** @brief Variable containing information on secp256r1 (NIST 256-bit).
+ *
+ * It can be used as a parameter for the functions creating secp256r1 (NIST 256-bit) keys.
+ */
+extern const nrf_crypto_ecc_curve_info_t g_nrf_crypto_ecc_secp256r1_curve_info;
+
+#endif
+
+/** @} */
+
+
+/** @addtogroup nrf_crypto_ecc_secp384r1
+ * @{ */
+
+typedef nrf_crypto_backend_secp384r1_key_pair_generate_context_t
+ nrf_crypto_ecc_secp384r1_key_pair_generate_context_t; /**< @brief Context structure for key generation using secp384r1 (NIST 384-bit). */
+typedef nrf_crypto_backend_secp384r1_public_key_calculate_context_t
+ nrf_crypto_ecc_secp384r1_public_key_calculate_context_t; /**< @brief Context structure for public key calculation using secp384r1 (NIST 384-bit). */
+typedef nrf_crypto_backend_secp384r1_private_key_t
+ nrf_crypto_ecc_secp384r1_private_key_t; /**< @brief Structure holding internal representation of a private key for secp384r1 (NIST 384-bit) */
+typedef nrf_crypto_backend_secp384r1_public_key_t
+ nrf_crypto_ecc_secp384r1_public_key_t; /**< @brief Structure holding internal representation of a public key for secp384r1 (NIST 384-bit) */
+typedef uint8_t nrf_crypto_ecc_secp384r1_raw_private_key_t
+ [NRF_CRYPTO_ECC_SECP384R1_RAW_PRIVATE_KEY_SIZE]; /**< @brief Array holding raw private key for secp384r1 (NIST 384-bit) */
+typedef uint8_t nrf_crypto_ecc_secp384r1_raw_public_key_t
+ [NRF_CRYPTO_ECC_SECP384R1_RAW_PUBLIC_KEY_SIZE]; /**< @brief Array holding raw public key for secp384r1 (NIST 384-bit) */
+
+
+#if NRF_CRYPTO_ECC_SECP384R1_ENABLED
+
+/** @brief Variable containing information on secp384r1 (NIST 384-bit).
+ *
+ * It can be used as a parameter for the functions creating secp384r1 (NIST 384-bit) keys.
+ */
+extern const nrf_crypto_ecc_curve_info_t g_nrf_crypto_ecc_secp384r1_curve_info;
+
+#endif
+
+/** @} */
+
+
+/** @addtogroup nrf_crypto_ecc_secp521r1
+ * @{ */
+
+typedef nrf_crypto_backend_secp521r1_key_pair_generate_context_t
+ nrf_crypto_ecc_secp521r1_key_pair_generate_context_t; /**< @brief Context structure for key generation using secp521r1 (NIST 521-bit). */
+typedef nrf_crypto_backend_secp521r1_public_key_calculate_context_t
+ nrf_crypto_ecc_secp521r1_public_key_calculate_context_t; /**< @brief Context structure for public key calculation using secp521r1 (NIST 521-bit). */
+typedef nrf_crypto_backend_secp521r1_private_key_t
+ nrf_crypto_ecc_secp521r1_private_key_t; /**< @brief Structure holding internal representation of a private key for secp521r1 (NIST 521-bit) */
+typedef nrf_crypto_backend_secp521r1_public_key_t
+ nrf_crypto_ecc_secp521r1_public_key_t; /**< @brief Structure holding internal representation of a public key for secp521r1 (NIST 521-bit) */
+typedef uint8_t nrf_crypto_ecc_secp521r1_raw_private_key_t
+ [NRF_CRYPTO_ECC_SECP521R1_RAW_PRIVATE_KEY_SIZE]; /**< @brief Array holding raw private key for secp521r1 (NIST 521-bit) */
+typedef uint8_t nrf_crypto_ecc_secp521r1_raw_public_key_t
+ [NRF_CRYPTO_ECC_SECP521R1_RAW_PUBLIC_KEY_SIZE]; /**< @brief Array holding raw public key for secp521r1 (NIST 521-bit) */
+
+
+#if NRF_CRYPTO_ECC_SECP521R1_ENABLED
+
+/** @brief Variable containing information on secp521r1 (NIST 521-bit).
+ *
+ * It can be used as a parameter for the functions creating secp521r1 (NIST 521-bit) keys.
+ */
+extern const nrf_crypto_ecc_curve_info_t g_nrf_crypto_ecc_secp521r1_curve_info;
+
+#endif
+
+/** @} */
+
+
+/** @addtogroup nrf_crypto_ecc_secp160k1
+ * @{ */
+
+typedef nrf_crypto_backend_secp160k1_key_pair_generate_context_t
+ nrf_crypto_ecc_secp160k1_key_pair_generate_context_t; /**< @brief Context structure for key generation using secp160k1 (Koblitz 160-bit). */
+typedef nrf_crypto_backend_secp160k1_public_key_calculate_context_t
+ nrf_crypto_ecc_secp160k1_public_key_calculate_context_t; /**< @brief Context structure for public key calculation using secp160k1 (Koblitz 160-bit). */
+typedef nrf_crypto_backend_secp160k1_private_key_t
+ nrf_crypto_ecc_secp160k1_private_key_t; /**< @brief Structure holding internal representation of a private key for secp160k1 (Koblitz 160-bit) */
+typedef nrf_crypto_backend_secp160k1_public_key_t
+ nrf_crypto_ecc_secp160k1_public_key_t; /**< @brief Structure holding internal representation of a public key for secp160k1 (Koblitz 160-bit) */
+typedef uint8_t nrf_crypto_ecc_secp160k1_raw_private_key_t
+ [NRF_CRYPTO_ECC_SECP160K1_RAW_PRIVATE_KEY_SIZE]; /**< @brief Array holding raw private key for secp160k1 (Koblitz 160-bit) */
+typedef uint8_t nrf_crypto_ecc_secp160k1_raw_public_key_t
+ [NRF_CRYPTO_ECC_SECP160K1_RAW_PUBLIC_KEY_SIZE]; /**< @brief Array holding raw public key for secp160k1 (Koblitz 160-bit) */
+
+
+#if NRF_CRYPTO_ECC_SECP160K1_ENABLED
+
+/** @brief Variable containing information on secp160k1 (Koblitz 160-bit).
+ *
+ * It can be used as a parameter for the functions creating secp160k1 (Koblitz 160-bit) keys.
+ */
+extern const nrf_crypto_ecc_curve_info_t g_nrf_crypto_ecc_secp160k1_curve_info;
+
+#endif
+
+/** @} */
+
+
+/** @addtogroup nrf_crypto_ecc_secp192k1
+ * @{ */
+
+typedef nrf_crypto_backend_secp192k1_key_pair_generate_context_t
+ nrf_crypto_ecc_secp192k1_key_pair_generate_context_t; /**< @brief Context structure for key generation using secp192k1 (Koblitz 192-bit). */
+typedef nrf_crypto_backend_secp192k1_public_key_calculate_context_t
+ nrf_crypto_ecc_secp192k1_public_key_calculate_context_t; /**< @brief Context structure for public key calculation using secp192k1 (Koblitz 192-bit). */
+typedef nrf_crypto_backend_secp192k1_private_key_t
+ nrf_crypto_ecc_secp192k1_private_key_t; /**< @brief Structure holding internal representation of a private key for secp192k1 (Koblitz 192-bit) */
+typedef nrf_crypto_backend_secp192k1_public_key_t
+ nrf_crypto_ecc_secp192k1_public_key_t; /**< @brief Structure holding internal representation of a public key for secp192k1 (Koblitz 192-bit) */
+typedef uint8_t nrf_crypto_ecc_secp192k1_raw_private_key_t
+ [NRF_CRYPTO_ECC_SECP192K1_RAW_PRIVATE_KEY_SIZE]; /**< @brief Array holding raw private key for secp192k1 (Koblitz 192-bit) */
+typedef uint8_t nrf_crypto_ecc_secp192k1_raw_public_key_t
+ [NRF_CRYPTO_ECC_SECP192K1_RAW_PUBLIC_KEY_SIZE]; /**< @brief Array holding raw public key for secp192k1 (Koblitz 192-bit) */
+
+
+#if NRF_CRYPTO_ECC_SECP192K1_ENABLED
+
+/** @brief Variable containing information on secp192k1 (Koblitz 192-bit).
+ *
+ * It can be used as a parameter for the functions creating secp192k1 (Koblitz 192-bit) keys.
+ */
+extern const nrf_crypto_ecc_curve_info_t g_nrf_crypto_ecc_secp192k1_curve_info;
+
+#endif
+
+/** @} */
+
+
+/** @addtogroup nrf_crypto_ecc_secp224k1
+ * @{ */
+
+typedef nrf_crypto_backend_secp224k1_key_pair_generate_context_t
+ nrf_crypto_ecc_secp224k1_key_pair_generate_context_t; /**< @brief Context structure for key generation using secp224k1 (Koblitz 224-bit). */
+typedef nrf_crypto_backend_secp224k1_public_key_calculate_context_t
+ nrf_crypto_ecc_secp224k1_public_key_calculate_context_t; /**< @brief Context structure for public key calculation using secp224k1 (Koblitz 224-bit). */
+typedef nrf_crypto_backend_secp224k1_private_key_t
+ nrf_crypto_ecc_secp224k1_private_key_t; /**< @brief Structure holding internal representation of a private key for secp224k1 (Koblitz 224-bit) */
+typedef nrf_crypto_backend_secp224k1_public_key_t
+ nrf_crypto_ecc_secp224k1_public_key_t; /**< @brief Structure holding internal representation of a public key for secp224k1 (Koblitz 224-bit) */
+typedef uint8_t nrf_crypto_ecc_secp224k1_raw_private_key_t
+ [NRF_CRYPTO_ECC_SECP224K1_RAW_PRIVATE_KEY_SIZE]; /**< @brief Array holding raw private key for secp224k1 (Koblitz 224-bit) */
+typedef uint8_t nrf_crypto_ecc_secp224k1_raw_public_key_t
+ [NRF_CRYPTO_ECC_SECP224K1_RAW_PUBLIC_KEY_SIZE]; /**< @brief Array holding raw public key for secp224k1 (Koblitz 224-bit) */
+
+
+#if NRF_CRYPTO_ECC_SECP224K1_ENABLED
+
+/** @brief Variable containing information on secp224k1 (Koblitz 224-bit).
+ *
+ * It can be used as a parameter for the functions creating secp224k1 (Koblitz 224-bit) keys.
+ */
+extern const nrf_crypto_ecc_curve_info_t g_nrf_crypto_ecc_secp224k1_curve_info;
+
+#endif
+
+/** @} */
+
+
+/** @addtogroup nrf_crypto_ecc_secp256k1
+ * @{ */
+
+typedef nrf_crypto_backend_secp256k1_key_pair_generate_context_t
+ nrf_crypto_ecc_secp256k1_key_pair_generate_context_t; /**< @brief Context structure for key generation using secp256k1 (Koblitz 256-bit). */
+typedef nrf_crypto_backend_secp256k1_public_key_calculate_context_t
+ nrf_crypto_ecc_secp256k1_public_key_calculate_context_t; /**< @brief Context structure for public key calculation using secp256k1 (Koblitz 256-bit). */
+typedef nrf_crypto_backend_secp256k1_private_key_t
+ nrf_crypto_ecc_secp256k1_private_key_t; /**< @brief Structure holding internal representation of a private key for secp256k1 (Koblitz 256-bit) */
+typedef nrf_crypto_backend_secp256k1_public_key_t
+ nrf_crypto_ecc_secp256k1_public_key_t; /**< @brief Structure holding internal representation of a public key for secp256k1 (Koblitz 256-bit) */
+typedef uint8_t nrf_crypto_ecc_secp256k1_raw_private_key_t
+ [NRF_CRYPTO_ECC_SECP256K1_RAW_PRIVATE_KEY_SIZE]; /**< @brief Array holding raw private key for secp256k1 (Koblitz 256-bit) */
+typedef uint8_t nrf_crypto_ecc_secp256k1_raw_public_key_t
+ [NRF_CRYPTO_ECC_SECP256K1_RAW_PUBLIC_KEY_SIZE]; /**< @brief Array holding raw public key for secp256k1 (Koblitz 256-bit) */
+
+
+#if NRF_CRYPTO_ECC_SECP256K1_ENABLED
+
+/** @brief Variable containing information on secp256k1 (Koblitz 256-bit).
+ *
+ * It can be used as a parameter for the functions creating secp256k1 (Koblitz 256-bit) keys.
+ */
+extern const nrf_crypto_ecc_curve_info_t g_nrf_crypto_ecc_secp256k1_curve_info;
+
+#endif
+
+/** @} */
+
+
+/** @addtogroup nrf_crypto_ecc_bp256r1
+ * @{ */
+
+typedef nrf_crypto_backend_bp256r1_key_pair_generate_context_t
+ nrf_crypto_ecc_bp256r1_key_pair_generate_context_t; /**< @brief Context structure for key generation using bp256r1 (Brainpool 256-bit). */
+typedef nrf_crypto_backend_bp256r1_public_key_calculate_context_t
+ nrf_crypto_ecc_bp256r1_public_key_calculate_context_t; /**< @brief Context structure for public key calculation using bp256r1 (Brainpool 256-bit). */
+typedef nrf_crypto_backend_bp256r1_private_key_t
+ nrf_crypto_ecc_bp256r1_private_key_t; /**< @brief Structure holding internal representation of a private key for bp256r1 (Brainpool 256-bit) */
+typedef nrf_crypto_backend_bp256r1_public_key_t
+ nrf_crypto_ecc_bp256r1_public_key_t; /**< @brief Structure holding internal representation of a public key for bp256r1 (Brainpool 256-bit) */
+typedef uint8_t nrf_crypto_ecc_bp256r1_raw_private_key_t
+ [NRF_CRYPTO_ECC_BP256R1_RAW_PRIVATE_KEY_SIZE]; /**< @brief Array holding raw private key for bp256r1 (Brainpool 256-bit) */
+typedef uint8_t nrf_crypto_ecc_bp256r1_raw_public_key_t
+ [NRF_CRYPTO_ECC_BP256R1_RAW_PUBLIC_KEY_SIZE]; /**< @brief Array holding raw public key for bp256r1 (Brainpool 256-bit) */
+
+
+#if NRF_CRYPTO_ECC_BP256R1_ENABLED
+
+/** @brief Variable containing information on bp256r1 (Brainpool 256-bit).
+ *
+ * It can be used as a parameter for the functions creating bp256r1 (Brainpool 256-bit) keys.
+ */
+extern const nrf_crypto_ecc_curve_info_t g_nrf_crypto_ecc_bp256r1_curve_info;
+
+#endif
+
+/** @} */
+
+
+/** @addtogroup nrf_crypto_ecc_bp384r1
+ * @{ */
+
+typedef nrf_crypto_backend_bp384r1_key_pair_generate_context_t
+ nrf_crypto_ecc_bp384r1_key_pair_generate_context_t; /**< @brief Context structure for key generation using bp384r1 (Brainpool 384-bit). */
+typedef nrf_crypto_backend_bp384r1_public_key_calculate_context_t
+ nrf_crypto_ecc_bp384r1_public_key_calculate_context_t; /**< @brief Context structure for public key calculation using bp384r1 (Brainpool 384-bit). */
+typedef nrf_crypto_backend_bp384r1_private_key_t
+ nrf_crypto_ecc_bp384r1_private_key_t; /**< @brief Structure holding internal representation of a private key for bp384r1 (Brainpool 384-bit) */
+typedef nrf_crypto_backend_bp384r1_public_key_t
+ nrf_crypto_ecc_bp384r1_public_key_t; /**< @brief Structure holding internal representation of a public key for bp384r1 (Brainpool 384-bit) */
+typedef uint8_t nrf_crypto_ecc_bp384r1_raw_private_key_t
+ [NRF_CRYPTO_ECC_BP384R1_RAW_PRIVATE_KEY_SIZE]; /**< @brief Array holding raw private key for bp384r1 (Brainpool 384-bit) */
+typedef uint8_t nrf_crypto_ecc_bp384r1_raw_public_key_t
+ [NRF_CRYPTO_ECC_BP384R1_RAW_PUBLIC_KEY_SIZE]; /**< @brief Array holding raw public key for bp384r1 (Brainpool 384-bit) */
+
+
+#if NRF_CRYPTO_ECC_BP384R1_ENABLED
+
+/** @brief Variable containing information on bp384r1 (Brainpool 384-bit).
+ *
+ * It can be used as a parameter for the functions creating bp384r1 (Brainpool 384-bit) keys.
+ */
+extern const nrf_crypto_ecc_curve_info_t g_nrf_crypto_ecc_bp384r1_curve_info;
+
+#endif
+
+/** @} */
+
+
+/** @addtogroup nrf_crypto_ecc_bp512r1
+ * @{ */
+
+typedef nrf_crypto_backend_bp512r1_key_pair_generate_context_t
+ nrf_crypto_ecc_bp512r1_key_pair_generate_context_t; /**< @brief Context structure for key generation using bp512r1 (Brainpool 512-bit). */
+typedef nrf_crypto_backend_bp512r1_public_key_calculate_context_t
+ nrf_crypto_ecc_bp512r1_public_key_calculate_context_t; /**< @brief Context structure for public key calculation using bp512r1 (Brainpool 512-bit). */
+typedef nrf_crypto_backend_bp512r1_private_key_t
+ nrf_crypto_ecc_bp512r1_private_key_t; /**< @brief Structure holding internal representation of a private key for bp512r1 (Brainpool 512-bit) */
+typedef nrf_crypto_backend_bp512r1_public_key_t
+ nrf_crypto_ecc_bp512r1_public_key_t; /**< @brief Structure holding internal representation of a public key for bp512r1 (Brainpool 512-bit) */
+typedef uint8_t nrf_crypto_ecc_bp512r1_raw_private_key_t
+ [NRF_CRYPTO_ECC_BP512R1_RAW_PRIVATE_KEY_SIZE]; /**< @brief Array holding raw private key for bp512r1 (Brainpool 512-bit) */
+typedef uint8_t nrf_crypto_ecc_bp512r1_raw_public_key_t
+ [NRF_CRYPTO_ECC_BP512R1_RAW_PUBLIC_KEY_SIZE]; /**< @brief Array holding raw public key for bp512r1 (Brainpool 512-bit) */
+
+
+#if NRF_CRYPTO_ECC_BP512R1_ENABLED
+
+/** @brief Variable containing information on bp512r1 (Brainpool 512-bit).
+ *
+ * It can be used as a parameter for the functions creating bp512r1 (Brainpool 512-bit) keys.
+ */
+extern const nrf_crypto_ecc_curve_info_t g_nrf_crypto_ecc_bp512r1_curve_info;
+
+#endif
+
+/** @} */
+
+
+/** @addtogroup nrf_crypto_ecc_curve25519
+ * @{ */
+
+typedef nrf_crypto_backend_curve25519_key_pair_generate_context_t
+ nrf_crypto_ecc_curve25519_key_pair_generate_context_t; /**< @brief Context structure for key generation using Curve25519. */
+typedef nrf_crypto_backend_curve25519_public_key_calculate_context_t
+ nrf_crypto_ecc_curve25519_public_key_calculate_context_t; /**< @brief Context structure for public key calculation using Curve25519. */
+typedef nrf_crypto_backend_curve25519_private_key_t
+ nrf_crypto_ecc_curve25519_private_key_t; /**< @brief Structure holding internal representation of a private key for Curve25519 */
+typedef nrf_crypto_backend_curve25519_public_key_t
+ nrf_crypto_ecc_curve25519_public_key_t; /**< @brief Structure holding internal representation of a public key for Curve25519 */
+typedef uint8_t nrf_crypto_ecc_curve25519_raw_private_key_t
+ [NRF_CRYPTO_ECC_CURVE25519_RAW_PRIVATE_KEY_SIZE]; /**< @brief Array holding raw private key for Curve25519 */
+typedef uint8_t nrf_crypto_ecc_curve25519_raw_public_key_t
+ [NRF_CRYPTO_ECC_CURVE25519_RAW_PUBLIC_KEY_SIZE]; /**< @brief Array holding raw public key for Curve25519 */
+
+
+#if NRF_CRYPTO_ECC_CURVE25519_ENABLED
+
+/** @brief Variable containing information on Curve25519.
+ *
+ * It can be used as a parameter for the functions creating Curve25519 keys.
+ */
+extern const nrf_crypto_ecc_curve_info_t g_nrf_crypto_ecc_curve25519_curve_info;
+
+#endif
+
+/** @} */
+
+
+/** @addtogroup nrf_crypto_ecc_ed25519
+ * @{ */
+
+typedef nrf_crypto_backend_ed25519_key_pair_generate_context_t
+ nrf_crypto_ecc_ed25519_key_pair_generate_context_t; /**< @brief Context structure for key generation using Ed25519. */
+typedef nrf_crypto_backend_ed25519_public_key_calculate_context_t
+ nrf_crypto_ecc_ed25519_public_key_calculate_context_t; /**< @brief Context structure for public key calculation using Ed25519. */
+typedef nrf_crypto_backend_ed25519_private_key_t
+ nrf_crypto_ecc_ed25519_private_key_t; /**< @brief Structure holding internal representation of a private key for Ed25519 */
+typedef nrf_crypto_backend_ed25519_public_key_t
+ nrf_crypto_ecc_ed25519_public_key_t; /**< @brief Structure holding internal representation of a public key for Ed25519 */
+typedef uint8_t nrf_crypto_ecc_ed25519_raw_private_key_t
+ [NRF_CRYPTO_ECC_ED25519_RAW_PRIVATE_KEY_SIZE]; /**< @brief Array holding raw private key for Ed25519 */
+typedef uint8_t nrf_crypto_ecc_ed25519_raw_public_key_t
+ [NRF_CRYPTO_ECC_ED25519_RAW_PUBLIC_KEY_SIZE]; /**< @brief Array holding raw public key for Ed25519 */
+
+
+#if NRF_CRYPTO_ECC_ED25519_ENABLED
+
+/** @brief Variable containing information on Ed25519.
+ *
+ * It can be used as a parameter for the functions creating Ed25519 keys.
+ */
+extern const nrf_crypto_ecc_curve_info_t g_nrf_crypto_ecc_ed25519_curve_info;
+
+#endif
+
+/** @} */
+
+
+typedef uint8_t nrf_crypto_ecc_raw_private_key_t[NRF_CRYPTO_ECC_RAW_PRIVATE_KEY_MAX_SIZE]; /**< @brief Type big enough to hold a raw private key for any the enabled curves. */
+typedef uint8_t nrf_crypto_ecc_raw_public_key_t [NRF_CRYPTO_ECC_RAW_PUBLIC_KEY_MAX_SIZE]; /**< @brief Type big enough to hold a raw public key for any the enabled curves. */
+
+
+/** @brief Union holding a context for a key pair generation.
+ */
+typedef union
+{
+ nrf_crypto_ecc_secp160r1_key_pair_generate_context_t context_secp160r1; /**< @brief Holds context for secp160r1 (NIST 160-bit). */
+ nrf_crypto_ecc_secp160r2_key_pair_generate_context_t context_secp160r2; /**< @brief Holds context for secp160r2 (NIST 160-bit). */
+ nrf_crypto_ecc_secp192r1_key_pair_generate_context_t context_secp192r1; /**< @brief Holds context for secp192r1 (NIST 192-bit). */
+ nrf_crypto_ecc_secp224r1_key_pair_generate_context_t context_secp224r1; /**< @brief Holds context for secp224r1 (NIST 224-bit). */
+ nrf_crypto_ecc_secp256r1_key_pair_generate_context_t context_secp256r1; /**< @brief Holds context for secp256r1 (NIST 256-bit). */
+ nrf_crypto_ecc_secp384r1_key_pair_generate_context_t context_secp384r1; /**< @brief Holds context for secp384r1 (NIST 384-bit). */
+ nrf_crypto_ecc_secp521r1_key_pair_generate_context_t context_secp521r1; /**< @brief Holds context for secp521r1 (NIST 521-bit). */
+ nrf_crypto_ecc_secp160k1_key_pair_generate_context_t context_secp160k1; /**< @brief Holds context for secp160k1 (Koblitz 160-bit). */
+ nrf_crypto_ecc_secp192k1_key_pair_generate_context_t context_secp192k1; /**< @brief Holds context for secp192k1 (Koblitz 192-bit). */
+ nrf_crypto_ecc_secp224k1_key_pair_generate_context_t context_secp224k1; /**< @brief Holds context for secp224k1 (Koblitz 224-bit). */
+ nrf_crypto_ecc_secp256k1_key_pair_generate_context_t context_secp256k1; /**< @brief Holds context for secp256k1 (Koblitz 256-bit). */
+ nrf_crypto_ecc_bp256r1_key_pair_generate_context_t context_bp256r1; /**< @brief Holds context for bp256r1 (Brainpool 256-bit). */
+ nrf_crypto_ecc_bp384r1_key_pair_generate_context_t context_bp384r1; /**< @brief Holds context for bp384r1 (Brainpool 384-bit). */
+ nrf_crypto_ecc_bp512r1_key_pair_generate_context_t context_bp512r1; /**< @brief Holds context for bp512r1 (Brainpool 512-bit). */
+ nrf_crypto_ecc_curve25519_key_pair_generate_context_t context_curve25519; /**< @brief Holds context for Curve25519. */
+ nrf_crypto_ecc_ed25519_key_pair_generate_context_t context_ed25519; /**< @brief Holds context for Ed25519. */
+} nrf_crypto_ecc_key_pair_generate_context_t;
+
+
+/** @brief Union holding a context for a public key calculation.
+ */
+typedef union
+{
+ nrf_crypto_ecc_secp160r1_public_key_calculate_context_t context_secp160r1; /**< @brief Holds context for secp160r1 (NIST 160-bit). */
+ nrf_crypto_ecc_secp160r2_public_key_calculate_context_t context_secp160r2; /**< @brief Holds context for secp160r2 (NIST 160-bit). */
+ nrf_crypto_ecc_secp192r1_public_key_calculate_context_t context_secp192r1; /**< @brief Holds context for secp192r1 (NIST 192-bit). */
+ nrf_crypto_ecc_secp224r1_public_key_calculate_context_t context_secp224r1; /**< @brief Holds context for secp224r1 (NIST 224-bit). */
+ nrf_crypto_ecc_secp256r1_public_key_calculate_context_t context_secp256r1; /**< @brief Holds context for secp256r1 (NIST 256-bit). */
+ nrf_crypto_ecc_secp384r1_public_key_calculate_context_t context_secp384r1; /**< @brief Holds context for secp384r1 (NIST 384-bit). */
+ nrf_crypto_ecc_secp521r1_public_key_calculate_context_t context_secp521r1; /**< @brief Holds context for secp521r1 (NIST 521-bit). */
+ nrf_crypto_ecc_secp160k1_public_key_calculate_context_t context_secp160k1; /**< @brief Holds context for secp160k1 (Koblitz 160-bit). */
+ nrf_crypto_ecc_secp192k1_public_key_calculate_context_t context_secp192k1; /**< @brief Holds context for secp192k1 (Koblitz 192-bit). */
+ nrf_crypto_ecc_secp224k1_public_key_calculate_context_t context_secp224k1; /**< @brief Holds context for secp224k1 (Koblitz 224-bit). */
+ nrf_crypto_ecc_secp256k1_public_key_calculate_context_t context_secp256k1; /**< @brief Holds context for secp256k1 (Koblitz 256-bit). */
+ nrf_crypto_ecc_bp256r1_public_key_calculate_context_t context_bp256r1; /**< @brief Holds context for bp256r1 (Brainpool 256-bit). */
+ nrf_crypto_ecc_bp384r1_public_key_calculate_context_t context_bp384r1; /**< @brief Holds context for bp384r1 (Brainpool 384-bit). */
+ nrf_crypto_ecc_bp512r1_public_key_calculate_context_t context_bp512r1; /**< @brief Holds context for bp512r1 (Brainpool 512-bit). */
+ nrf_crypto_ecc_curve25519_public_key_calculate_context_t context_curve25519; /**< @brief Holds context for Curve25519. */
+ nrf_crypto_ecc_ed25519_public_key_calculate_context_t context_ed25519; /**< @brief Holds context for Ed25519. */
+} nrf_crypto_ecc_public_key_calculate_context_t;
+
+
+/** @brief Union holding representation of a private key for any curve type.
+ */
+typedef union
+{
+ nrf_crypto_ecc_secp160r1_private_key_t key_secp160r1; /**< @brief Holds internal representation of a private key for secp160r1 (NIST 160-bit). */
+ nrf_crypto_ecc_secp160r2_private_key_t key_secp160r2; /**< @brief Holds internal representation of a private key for secp160r2 (NIST 160-bit). */
+ nrf_crypto_ecc_secp192r1_private_key_t key_secp192r1; /**< @brief Holds internal representation of a private key for secp192r1 (NIST 192-bit). */
+ nrf_crypto_ecc_secp224r1_private_key_t key_secp224r1; /**< @brief Holds internal representation of a private key for secp224r1 (NIST 224-bit). */
+ nrf_crypto_ecc_secp256r1_private_key_t key_secp256r1; /**< @brief Holds internal representation of a private key for secp256r1 (NIST 256-bit). */
+ nrf_crypto_ecc_secp384r1_private_key_t key_secp384r1; /**< @brief Holds internal representation of a private key for secp384r1 (NIST 384-bit). */
+ nrf_crypto_ecc_secp521r1_private_key_t key_secp521r1; /**< @brief Holds internal representation of a private key for secp521r1 (NIST 521-bit). */
+ nrf_crypto_ecc_secp160k1_private_key_t key_secp160k1; /**< @brief Holds internal representation of a private key for secp160k1 (Koblitz 160-bit). */
+ nrf_crypto_ecc_secp192k1_private_key_t key_secp192k1; /**< @brief Holds internal representation of a private key for secp192k1 (Koblitz 192-bit). */
+ nrf_crypto_ecc_secp224k1_private_key_t key_secp224k1; /**< @brief Holds internal representation of a private key for secp224k1 (Koblitz 224-bit). */
+ nrf_crypto_ecc_secp256k1_private_key_t key_secp256k1; /**< @brief Holds internal representation of a private key for secp256k1 (Koblitz 256-bit). */
+ nrf_crypto_ecc_bp256r1_private_key_t key_bp256r1; /**< @brief Holds internal representation of a private key for bp256r1 (Brainpool 256-bit). */
+ nrf_crypto_ecc_bp384r1_private_key_t key_bp384r1; /**< @brief Holds internal representation of a private key for bp384r1 (Brainpool 384-bit). */
+ nrf_crypto_ecc_bp512r1_private_key_t key_bp512r1; /**< @brief Holds internal representation of a private key for bp512r1 (Brainpool 512-bit). */
+ nrf_crypto_ecc_curve25519_private_key_t key_curve25519; /**< @brief Holds internal representation of a private key for Curve25519. */
+ nrf_crypto_ecc_ed25519_private_key_t key_ed25519; /**< @brief Holds internal representation of a private key for Ed25519. */
+} nrf_crypto_ecc_private_key_t;
+
+
+/** @brief Union holding representation of a public key for any curve type.
+ */
+typedef union
+{
+ nrf_crypto_ecc_secp160r1_public_key_t key_secp160r1; /**< @brief Holds internal representation of a public key for secp160r1 (NIST 160-bit). */
+ nrf_crypto_ecc_secp160r2_public_key_t key_secp160r2; /**< @brief Holds internal representation of a public key for secp160r2 (NIST 160-bit). */
+ nrf_crypto_ecc_secp192r1_public_key_t key_secp192r1; /**< @brief Holds internal representation of a public key for secp192r1 (NIST 192-bit). */
+ nrf_crypto_ecc_secp224r1_public_key_t key_secp224r1; /**< @brief Holds internal representation of a public key for secp224r1 (NIST 224-bit). */
+ nrf_crypto_ecc_secp256r1_public_key_t key_secp256r1; /**< @brief Holds internal representation of a public key for secp256r1 (NIST 256-bit). */
+ nrf_crypto_ecc_secp384r1_public_key_t key_secp384r1; /**< @brief Holds internal representation of a public key for secp384r1 (NIST 384-bit). */
+ nrf_crypto_ecc_secp521r1_public_key_t key_secp521r1; /**< @brief Holds internal representation of a public key for secp521r1 (NIST 521-bit). */
+ nrf_crypto_ecc_secp160k1_public_key_t key_secp160k1; /**< @brief Holds internal representation of a public key for secp160k1 (Koblitz 160-bit). */
+ nrf_crypto_ecc_secp192k1_public_key_t key_secp192k1; /**< @brief Holds internal representation of a public key for secp192k1 (Koblitz 192-bit). */
+ nrf_crypto_ecc_secp224k1_public_key_t key_secp224k1; /**< @brief Holds internal representation of a public key for secp224k1 (Koblitz 224-bit). */
+ nrf_crypto_ecc_secp256k1_public_key_t key_secp256k1; /**< @brief Holds internal representation of a public key for secp256k1 (Koblitz 256-bit). */
+ nrf_crypto_ecc_bp256r1_public_key_t key_bp256r1; /**< @brief Holds internal representation of a public key for bp256r1 (Brainpool 256-bit). */
+ nrf_crypto_ecc_bp384r1_public_key_t key_bp384r1; /**< @brief Holds internal representation of a public key for bp384r1 (Brainpool 384-bit). */
+ nrf_crypto_ecc_bp512r1_public_key_t key_bp512r1; /**< @brief Holds internal representation of a public key for bp512r1 (Brainpool 512-bit). */
+ nrf_crypto_ecc_curve25519_public_key_t key_curve25519; /**< @brief Holds internal representation of a public key for Curve25519. */
+ nrf_crypto_ecc_ed25519_public_key_t key_ed25519; /**< @brief Holds internal representation of a public key for Ed25519. */
+} nrf_crypto_ecc_public_key_t;
+
+
+/** @brief Generate a new pair of a public key and a private key.
+ *
+ * Generated keys have to deallocated using @ref nrf_crypto_ecc_private_key_free and
+ * @ref nrf_crypto_ecc_public_key_free.
+ * @param[in] p_context Pointer to temporary structure holding context information.
+ * If it is NULL, necessary data will be allocated with
+ * @ref NRF_CRYPTO_ALLOC and freed at the end of the function.
+ * @param[in] p_curve_info Pointer to information on selected curve. Use only global variables
+ * defined by nrf_crypto, e.g. @ref g_nrf_crypto_ecc_secp256r1_curve_info.
+ * @param[out] p_private_key Pointer to structure where newly generated private key will be put.
+ * @param[out] p_public_key Pointer to structure where newly generated public key will be put.
+ */
+ret_code_t nrf_crypto_ecc_key_pair_generate(
+ nrf_crypto_ecc_key_pair_generate_context_t * p_context,
+ nrf_crypto_ecc_curve_info_t const * p_curve_info,
+ nrf_crypto_ecc_private_key_t * p_private_key,
+ nrf_crypto_ecc_public_key_t * p_public_key);
+
+
+/** @brief Calculate public key associated with provided private key.
+ *
+ * Calculated public key has to be deallocated using @ref nrf_crypto_ecc_public_key_free.
+ * @param[in] p_context Pointer to temporary structure holding context information.
+ * If it is NULL, necessary data will be allocated with
+ * @ref NRF_CRYPTO_ALLOC and freed at the end of the function.
+ * @param[in] p_private_key Pointer to structure holding a private key that will be used for computation.
+ * @param[out] p_public_key Pointer to structure where newly generated public key will be put.
+ */
+ret_code_t nrf_crypto_ecc_public_key_calculate(
+ nrf_crypto_ecc_public_key_calculate_context_t * p_context,
+ nrf_crypto_ecc_private_key_t const * p_private_key,
+ nrf_crypto_ecc_public_key_t * p_public_key);
+
+
+/** @brief Create a private key from a raw data.
+ *
+ * Generated private key has to be deallocated using @ref nrf_crypto_ecc_private_key_free.
+ * @param[in] p_curve_info Pointer to information on selected curve. Use only global variables
+ * defined by nrf_crypto, e.g. @ref g_nrf_crypto_ecc_secp256r1_curve_info.
+ * @param[out] p_private_key Pointer to structure where newly converted private key will be put.
+ * @param[in] p_raw_data Pointer to buffer containing a big endian raw data.
+ * @param[in] raw_data_size Number of bytes of a raw data. Correct size for selected curve can be found in
+ * @p p_curve_info and it is also defined by the preprocessor definitions, e.g.
+ * @ref NRF_CRYPTO_ECC_SECP256R1_RAW_PRIVATE_KEY_SIZE.
+ */
+ret_code_t nrf_crypto_ecc_private_key_from_raw(
+ nrf_crypto_ecc_curve_info_t const * p_curve_info,
+ nrf_crypto_ecc_private_key_t * p_private_key,
+ uint8_t const * p_raw_data,
+ size_t raw_data_size);
+
+
+/** @brief Convert a private key to a raw data.
+ *
+ * @param[in] p_private_key Pointer to structure holding private key that will be convert.
+ * @param[out] p_raw_data Pointer to buffer containing a big endian raw data.
+ * @param[in,out] p_raw_data_size Maximum number of bytes that @p p_raw_data buffer can hold on input
+ * and the actual number of bytes used by the raw data on output.
+ * Actual size for selected curve can be found in
+ * @ref nrf_crypto_ecc_curve_info_t and it is also defined by
+ * the preprocessor definitions, e.g.
+ * @ref NRF_CRYPTO_ECC_SECP256R1_RAW_PRIVATE_KEY_SIZE.
+ */
+ret_code_t nrf_crypto_ecc_private_key_to_raw(
+ nrf_crypto_ecc_private_key_t const * p_private_key,
+ uint8_t * p_raw_data,
+ size_t * p_raw_data_size);
+
+
+/** @brief Create a public key from a raw data.
+ *
+ * Generated public key has to be deallocated using @ref nrf_crypto_ecc_public_key_free.
+ * @param[in] p_curve_info Pointer to information on selected curve. Use only global variables
+ * defined by nrf_crypto, e.g. @ref g_nrf_crypto_ecc_secp256r1_curve_info.
+ * @param[out] p_public_key Pointer to structure where newly converted public key will be put.
+ * @param[in] p_raw_data Pointer to buffer containing a big endian raw data.
+ * @param[in] raw_data_size Number of bytes of a raw data. Correct size for selected curve can be found in
+ * @p p_curve_info and it is also defined by the preprocessor definitions, e.g.
+ * @ref NRF_CRYPTO_ECC_SECP256R1_RAW_PUBLIC_KEY_SIZE.
+ */
+ret_code_t nrf_crypto_ecc_public_key_from_raw(
+ nrf_crypto_ecc_curve_info_t const * p_curve_info,
+ nrf_crypto_ecc_public_key_t * p_public_key,
+ uint8_t const * p_raw_data,
+ size_t raw_data_size);
+
+
+/** @brief Convert a public key to a raw data.
+ *
+ * @param[in] p_public_key Pointer to structure holding public key that will be convert.
+ * @param[out] p_raw_data Pointer to buffer containing a big endian raw data.
+ * @param[in,out] p_raw_data_size Maximum number of bytes that @p p_raw_data buffer can hold on input
+ * and the actual number of bytes used by the raw data on output.
+ * Actual size for selected curve can be found in
+ * @ref nrf_crypto_ecc_curve_info_t and it is also defined by
+ * the preprocessor definitions, e.g.
+ * @ref NRF_CRYPTO_ECC_SECP256R1_RAW_PUBLIC_KEY_SIZE.
+ */
+ret_code_t nrf_crypto_ecc_public_key_to_raw(
+ nrf_crypto_ecc_public_key_t const * p_public_key,
+ uint8_t * p_raw_data,
+ size_t * p_raw_data_size);
+
+
+/** @brief Release resources taken by a private key.
+ *
+ * @param[in] p_private_key Pointer to structure holding private key to release.
+ */
+ret_code_t nrf_crypto_ecc_private_key_free(
+ nrf_crypto_ecc_private_key_t * p_private_key);
+
+
+/** @brief Release resources taken by a public key.
+ *
+ * @param[in] p_public_key Pointer to structure holding public key to release.
+ */
+ret_code_t nrf_crypto_ecc_public_key_free(
+ nrf_crypto_ecc_public_key_t * p_public_key);
+
+
+/** @brief Gets curve information structure from provided key (private or public).
+ *
+ * @param[in] p_key Pointer to structure holding private or public key.
+ * @param[out] pp_curve_info Pointer to location where put retrieved pointer to curve information structure.
+ */
+ret_code_t nrf_crypto_ecc_curve_info_get(
+ void const * p_key,
+ nrf_crypto_ecc_curve_info_t const ** pp_curve_info);
+
+
+/** @brief Inverts byte order of a big integers contained in a raw data.
+ *
+ * All the ECC API accepts only data with big endian integers, so this function have to be used
+ * if little endian is required. If input is in little endian byte order it will be converted
+ * to big endian. If input is in big endian byte order it will be converted to little endian.
+ * It works for ECC raw private key, raw public key, signature and shared secret. If raw data
+ * contains two big integers (e.g. R, S, or X, Y) each integer is inverted separately.
+ * If @p p_curve_info is NULL then all bytes in buffer will be inverted regardless what is the
+ * content of the buffer.
+ *
+ * @param[in] p_curve_info Pointer to information on selected curve. Use only global variables
+ * defined by nrf_crypto, e.g. @ref g_nrf_crypto_ecc_secp256r1_curve_info.
+ * @param[in] p_raw_input Pointer to buffer holding source data.
+ * @param[out] p_raw_output Pointer to buffer that will be filled with inverted byte order.
+ * This parameter can be the same as @p p_raw_input, otherwise the
+ * buffers cannot overlap.
+ * @param[in] raw_data_size Size of input and output buffer.
+ */
+ret_code_t nrf_crypto_ecc_byte_order_invert(
+ nrf_crypto_ecc_curve_info_t const * p_curve_info,
+ uint8_t const * p_raw_input,
+ uint8_t * p_raw_output,
+ size_t raw_data_size);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+/** @}
+ * @}
+ */
+
+#endif // NRF_CRYPTO_ECC_H__
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/nrf_crypto_ecc_backend.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/nrf_crypto_ecc_backend.h
new file mode 100644
index 0000000..7ec1563
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/nrf_crypto_ecc_backend.h
@@ -0,0 +1,352 @@
+/**
+ * Copyright (c) 2018 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+
+#ifndef NRF_CRYPTO_ECC_BACKEND_H__
+#define NRF_CRYPTO_ECC_BACKEND_H__
+#if !defined(__SDK_DOXYGEN__)
+
+#include <stdint.h>
+#include <stddef.h>
+
+#include "sdk_config.h"
+#include "nordic_common.h"
+#include "nrf_crypto_error.h"
+#include "nrf_crypto_ecc_shared.h"
+
+// Include all backends
+#include "cc310_backend_ecc.h"
+#include "cc310_bl_backend_ecc.h"
+#include "mbedtls_backend_ecc.h"
+#include "oberon_backend_ecc.h"
+#include "micro_ecc_backend_ecc.h"
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+// Make sure that all required defines are defined
+#if !defined(NRF_CRYPTO_ECC_SECP160R1_ENABLED)
+#define NRF_CRYPTO_ECC_SECP160R1_ENABLED 0
+#endif
+#if !defined(NRF_CRYPTO_ECC_SECP160R2_ENABLED)
+#define NRF_CRYPTO_ECC_SECP160R2_ENABLED 0
+#endif
+#if !defined(NRF_CRYPTO_ECC_SECP192R1_ENABLED)
+#define NRF_CRYPTO_ECC_SECP192R1_ENABLED 0
+#endif
+#if !defined(NRF_CRYPTO_ECC_SECP224R1_ENABLED)
+#define NRF_CRYPTO_ECC_SECP224R1_ENABLED 0
+#endif
+#if !defined(NRF_CRYPTO_ECC_SECP256R1_ENABLED)
+#define NRF_CRYPTO_ECC_SECP256R1_ENABLED 0
+#endif
+#if !defined(NRF_CRYPTO_ECC_SECP384R1_ENABLED)
+#define NRF_CRYPTO_ECC_SECP384R1_ENABLED 0
+#endif
+#if !defined(NRF_CRYPTO_ECC_SECP521R1_ENABLED)
+#define NRF_CRYPTO_ECC_SECP521R1_ENABLED 0
+#endif
+#if !defined(NRF_CRYPTO_ECC_SECP160K1_ENABLED)
+#define NRF_CRYPTO_ECC_SECP160K1_ENABLED 0
+#endif
+#if !defined(NRF_CRYPTO_ECC_SECP192K1_ENABLED)
+#define NRF_CRYPTO_ECC_SECP192K1_ENABLED 0
+#endif
+#if !defined(NRF_CRYPTO_ECC_SECP224K1_ENABLED)
+#define NRF_CRYPTO_ECC_SECP224K1_ENABLED 0
+#endif
+#if !defined(NRF_CRYPTO_ECC_SECP256K1_ENABLED)
+#define NRF_CRYPTO_ECC_SECP256K1_ENABLED 0
+#endif
+#if !defined(NRF_CRYPTO_ECC_BP256R1_ENABLED)
+#define NRF_CRYPTO_ECC_BP256R1_ENABLED 0
+#endif
+#if !defined(NRF_CRYPTO_ECC_BP384R1_ENABLED)
+#define NRF_CRYPTO_ECC_BP384R1_ENABLED 0
+#endif
+#if !defined(NRF_CRYPTO_ECC_BP512R1_ENABLED)
+#define NRF_CRYPTO_ECC_BP512R1_ENABLED 0
+#endif
+#if !defined(NRF_CRYPTO_ECC_CURVE25519_ENABLED)
+#define NRF_CRYPTO_ECC_CURVE25519_ENABLED 0
+#endif
+#if !defined(NRF_CRYPTO_ECC_ED25519_ENABLED)
+#define NRF_CRYPTO_ECC_ED25519_ENABLED 0
+#endif
+
+
+/** @internal @brief Definition to detect if ECC submodule is enabled. It will be enabled if any
+ * curve of any of the backends is enabled.
+ */
+#define NRF_CRYPTO_ECC_ENABLED ( \
+ NRF_MODULE_ENABLED(NRF_CRYPTO) && ( \
+ NRF_CRYPTO_ECC_SECP160R1_ENABLED | \
+ NRF_CRYPTO_ECC_SECP160R2_ENABLED | \
+ NRF_CRYPTO_ECC_SECP192R1_ENABLED | \
+ NRF_CRYPTO_ECC_SECP224R1_ENABLED | \
+ NRF_CRYPTO_ECC_SECP256R1_ENABLED | \
+ NRF_CRYPTO_ECC_SECP384R1_ENABLED | \
+ NRF_CRYPTO_ECC_SECP521R1_ENABLED | \
+ NRF_CRYPTO_ECC_SECP160K1_ENABLED | \
+ NRF_CRYPTO_ECC_SECP192K1_ENABLED | \
+ NRF_CRYPTO_ECC_SECP224K1_ENABLED | \
+ NRF_CRYPTO_ECC_SECP256K1_ENABLED | \
+ NRF_CRYPTO_ECC_BP256R1_ENABLED | \
+ NRF_CRYPTO_ECC_BP384R1_ENABLED | \
+ NRF_CRYPTO_ECC_BP512R1_ENABLED | \
+ NRF_CRYPTO_ECC_CURVE25519_ENABLED | \
+ NRF_CRYPTO_ECC_ED25519_ENABLED))
+
+
+/** @internal @brief Definition containing number of enabled curves.
+ */
+#define NRF_CRYPTO_ECC_IMPLEMENTED_CURVES_COUNT ( \
+ NRF_CRYPTO_ECC_SECP160R1_ENABLED + \
+ NRF_CRYPTO_ECC_SECP160R2_ENABLED + \
+ NRF_CRYPTO_ECC_SECP192R1_ENABLED + \
+ NRF_CRYPTO_ECC_SECP224R1_ENABLED + \
+ NRF_CRYPTO_ECC_SECP256R1_ENABLED + \
+ NRF_CRYPTO_ECC_SECP384R1_ENABLED + \
+ NRF_CRYPTO_ECC_SECP521R1_ENABLED + \
+ NRF_CRYPTO_ECC_SECP160K1_ENABLED + \
+ NRF_CRYPTO_ECC_SECP192K1_ENABLED + \
+ NRF_CRYPTO_ECC_SECP224K1_ENABLED + \
+ NRF_CRYPTO_ECC_SECP256K1_ENABLED + \
+ NRF_CRYPTO_ECC_BP256R1_ENABLED + \
+ NRF_CRYPTO_ECC_BP384R1_ENABLED + \
+ NRF_CRYPTO_ECC_BP512R1_ENABLED + \
+ NRF_CRYPTO_ECC_CURVE25519_ENABLED + \
+ NRF_CRYPTO_ECC_ED25519_ENABLED)
+
+
+#if !NRF_CRYPTO_ECC_SECP160R1_ENABLED
+// Dummy typedefs for disabled contexts
+typedef uint32_t nrf_crypto_backend_secp160r1_key_pair_generate_context_t;
+typedef uint32_t nrf_crypto_backend_secp160r1_public_key_calculate_context_t;
+// Dummy typedefs for disabled keys
+typedef nrf_crypto_internal_ecc_key_header_t nrf_crypto_backend_secp160r1_private_key_t;
+typedef nrf_crypto_internal_ecc_key_header_t nrf_crypto_backend_secp160r1_public_key_t;
+#endif
+
+#if !NRF_CRYPTO_ECC_SECP160R2_ENABLED
+// Dummy typedefs for disabled contexts
+typedef uint32_t nrf_crypto_backend_secp160r2_key_pair_generate_context_t;
+typedef uint32_t nrf_crypto_backend_secp160r2_public_key_calculate_context_t;
+// Dummy typedefs for disabled keys
+typedef nrf_crypto_internal_ecc_key_header_t nrf_crypto_backend_secp160r2_private_key_t;
+typedef nrf_crypto_internal_ecc_key_header_t nrf_crypto_backend_secp160r2_public_key_t;
+#endif
+
+#if !NRF_CRYPTO_ECC_SECP192R1_ENABLED
+// Dummy typedefs for disabled contexts
+typedef uint32_t nrf_crypto_backend_secp192r1_key_pair_generate_context_t;
+typedef uint32_t nrf_crypto_backend_secp192r1_public_key_calculate_context_t;
+// Dummy typedefs for disabled keys
+typedef nrf_crypto_internal_ecc_key_header_t nrf_crypto_backend_secp192r1_private_key_t;
+typedef nrf_crypto_internal_ecc_key_header_t nrf_crypto_backend_secp192r1_public_key_t;
+#endif
+
+#if !NRF_CRYPTO_ECC_SECP224R1_ENABLED
+// Dummy typedefs for disabled contexts
+typedef uint32_t nrf_crypto_backend_secp224r1_key_pair_generate_context_t;
+typedef uint32_t nrf_crypto_backend_secp224r1_public_key_calculate_context_t;
+// Dummy typedefs for disabled keys
+typedef nrf_crypto_internal_ecc_key_header_t nrf_crypto_backend_secp224r1_private_key_t;
+typedef nrf_crypto_internal_ecc_key_header_t nrf_crypto_backend_secp224r1_public_key_t;
+#endif
+
+#if !NRF_CRYPTO_ECC_SECP256R1_ENABLED
+// Dummy typedefs for disabled contexts
+typedef uint32_t nrf_crypto_backend_secp256r1_key_pair_generate_context_t;
+typedef uint32_t nrf_crypto_backend_secp256r1_public_key_calculate_context_t;
+// Dummy typedefs for disabled keys
+typedef nrf_crypto_internal_ecc_key_header_t nrf_crypto_backend_secp256r1_private_key_t;
+typedef nrf_crypto_internal_ecc_key_header_t nrf_crypto_backend_secp256r1_public_key_t;
+#endif
+
+#if !NRF_CRYPTO_ECC_SECP384R1_ENABLED
+// Dummy typedefs for disabled contexts
+typedef uint32_t nrf_crypto_backend_secp384r1_key_pair_generate_context_t;
+typedef uint32_t nrf_crypto_backend_secp384r1_public_key_calculate_context_t;
+// Dummy typedefs for disabled keys
+typedef nrf_crypto_internal_ecc_key_header_t nrf_crypto_backend_secp384r1_private_key_t;
+typedef nrf_crypto_internal_ecc_key_header_t nrf_crypto_backend_secp384r1_public_key_t;
+#endif
+
+#if !NRF_CRYPTO_ECC_SECP521R1_ENABLED
+// Dummy typedefs for disabled contexts
+typedef uint32_t nrf_crypto_backend_secp521r1_key_pair_generate_context_t;
+typedef uint32_t nrf_crypto_backend_secp521r1_public_key_calculate_context_t;
+// Dummy typedefs for disabled keys
+typedef nrf_crypto_internal_ecc_key_header_t nrf_crypto_backend_secp521r1_private_key_t;
+typedef nrf_crypto_internal_ecc_key_header_t nrf_crypto_backend_secp521r1_public_key_t;
+#endif
+
+#if !NRF_CRYPTO_ECC_SECP160K1_ENABLED
+// Dummy typedefs for disabled contexts
+typedef uint32_t nrf_crypto_backend_secp160k1_key_pair_generate_context_t;
+typedef uint32_t nrf_crypto_backend_secp160k1_public_key_calculate_context_t;
+// Dummy typedefs for disabled keys
+typedef nrf_crypto_internal_ecc_key_header_t nrf_crypto_backend_secp160k1_private_key_t;
+typedef nrf_crypto_internal_ecc_key_header_t nrf_crypto_backend_secp160k1_public_key_t;
+#endif
+
+#if !NRF_CRYPTO_ECC_SECP192K1_ENABLED
+// Dummy typedefs for disabled contexts
+typedef uint32_t nrf_crypto_backend_secp192k1_key_pair_generate_context_t;
+typedef uint32_t nrf_crypto_backend_secp192k1_public_key_calculate_context_t;
+// Dummy typedefs for disabled keys
+typedef nrf_crypto_internal_ecc_key_header_t nrf_crypto_backend_secp192k1_private_key_t;
+typedef nrf_crypto_internal_ecc_key_header_t nrf_crypto_backend_secp192k1_public_key_t;
+#endif
+
+#if !NRF_CRYPTO_ECC_SECP224K1_ENABLED
+// Dummy typedefs for disabled contexts
+typedef uint32_t nrf_crypto_backend_secp224k1_key_pair_generate_context_t;
+typedef uint32_t nrf_crypto_backend_secp224k1_public_key_calculate_context_t;
+// Dummy typedefs for disabled keys
+typedef nrf_crypto_internal_ecc_key_header_t nrf_crypto_backend_secp224k1_private_key_t;
+typedef nrf_crypto_internal_ecc_key_header_t nrf_crypto_backend_secp224k1_public_key_t;
+#endif
+
+#if !NRF_CRYPTO_ECC_SECP256K1_ENABLED
+// Dummy typedefs for disabled contexts
+typedef uint32_t nrf_crypto_backend_secp256k1_key_pair_generate_context_t;
+typedef uint32_t nrf_crypto_backend_secp256k1_public_key_calculate_context_t;
+// Dummy typedefs for disabled keys
+typedef nrf_crypto_internal_ecc_key_header_t nrf_crypto_backend_secp256k1_private_key_t;
+typedef nrf_crypto_internal_ecc_key_header_t nrf_crypto_backend_secp256k1_public_key_t;
+#endif
+
+#if !NRF_CRYPTO_ECC_BP256R1_ENABLED
+// Dummy typedefs for disabled contexts
+typedef uint32_t nrf_crypto_backend_bp256r1_key_pair_generate_context_t;
+typedef uint32_t nrf_crypto_backend_bp256r1_public_key_calculate_context_t;
+// Dummy typedefs for disabled keys
+typedef nrf_crypto_internal_ecc_key_header_t nrf_crypto_backend_bp256r1_private_key_t;
+typedef nrf_crypto_internal_ecc_key_header_t nrf_crypto_backend_bp256r1_public_key_t;
+#endif
+
+#if !NRF_CRYPTO_ECC_BP384R1_ENABLED
+// Dummy typedefs for disabled contexts
+typedef uint32_t nrf_crypto_backend_bp384r1_key_pair_generate_context_t;
+typedef uint32_t nrf_crypto_backend_bp384r1_public_key_calculate_context_t;
+// Dummy typedefs for disabled keys
+typedef nrf_crypto_internal_ecc_key_header_t nrf_crypto_backend_bp384r1_private_key_t;
+typedef nrf_crypto_internal_ecc_key_header_t nrf_crypto_backend_bp384r1_public_key_t;
+#endif
+
+#if !NRF_CRYPTO_ECC_BP512R1_ENABLED
+// Dummy typedefs for disabled contexts
+typedef uint32_t nrf_crypto_backend_bp512r1_key_pair_generate_context_t;
+typedef uint32_t nrf_crypto_backend_bp512r1_public_key_calculate_context_t;
+// Dummy typedefs for disabled keys
+typedef nrf_crypto_internal_ecc_key_header_t nrf_crypto_backend_bp512r1_private_key_t;
+typedef nrf_crypto_internal_ecc_key_header_t nrf_crypto_backend_bp512r1_public_key_t;
+#endif
+
+#if !NRF_CRYPTO_ECC_CURVE25519_ENABLED
+// Dummy typedefs for disabled contexts
+typedef uint32_t nrf_crypto_backend_curve25519_key_pair_generate_context_t;
+typedef uint32_t nrf_crypto_backend_curve25519_public_key_calculate_context_t;
+// Dummy typedefs for disabled keys
+typedef nrf_crypto_internal_ecc_key_header_t nrf_crypto_backend_curve25519_private_key_t;
+typedef nrf_crypto_internal_ecc_key_header_t nrf_crypto_backend_curve25519_public_key_t;
+#endif
+
+#if !NRF_CRYPTO_ECC_ED25519_ENABLED
+// Dummy typedefs for disabled contexts
+typedef uint32_t nrf_crypto_backend_ed25519_key_pair_generate_context_t;
+typedef uint32_t nrf_crypto_backend_ed25519_public_key_calculate_context_t;
+// Dummy typedefs for disabled keys
+typedef nrf_crypto_internal_ecc_key_header_t nrf_crypto_backend_ed25519_private_key_t;
+typedef nrf_crypto_internal_ecc_key_header_t nrf_crypto_backend_ed25519_public_key_t;
+#endif
+
+
+// Find biggest raw private and public key size that is currently enabled
+#if NRF_CRYPTO_ECC_SECP521R1_ENABLED
+# define NRF_CRYPTO_BACKEND_ECC_RAW_PRIVATE_KEY_MAX_SIZE (66)
+#elif NRF_CRYPTO_ECC_BP512R1_ENABLED
+# define NRF_CRYPTO_BACKEND_ECC_RAW_PRIVATE_KEY_MAX_SIZE (64)
+#elif NRF_CRYPTO_ECC_BP384R1_ENABLED || NRF_CRYPTO_ECC_SECP384R1_ENABLED
+# define NRF_CRYPTO_BACKEND_ECC_RAW_PRIVATE_KEY_MAX_SIZE (48)
+#elif NRF_CRYPTO_ECC_BP256R1_ENABLED || NRF_CRYPTO_ECC_SECP256K1_ENABLED || NRF_CRYPTO_ECC_CURVE25519_ENABLED || NRF_CRYPTO_ECC_ED25519_ENABLED || NRF_CRYPTO_ECC_SECP256R1_ENABLED
+# define NRF_CRYPTO_BACKEND_ECC_RAW_PRIVATE_KEY_MAX_SIZE (32)
+#elif NRF_CRYPTO_ECC_SECP224K1_ENABLED || NRF_CRYPTO_ECC_SECP224R1_ENABLED
+# define NRF_CRYPTO_BACKEND_ECC_RAW_PRIVATE_KEY_MAX_SIZE (28)
+#elif NRF_CRYPTO_ECC_SECP192K1_ENABLED || NRF_CRYPTO_ECC_SECP192R1_ENABLED
+# define NRF_CRYPTO_BACKEND_ECC_RAW_PRIVATE_KEY_MAX_SIZE (24)
+#elif NRF_CRYPTO_ECC_SECP160K1_ENABLED || NRF_CRYPTO_ECC_SECP160R1_ENABLED || NRF_CRYPTO_ECC_SECP160R2_ENABLED
+# define NRF_CRYPTO_BACKEND_ECC_RAW_PRIVATE_KEY_MAX_SIZE (20)
+#else
+# define NRF_CRYPTO_BACKEND_ECC_RAW_PRIVATE_KEY_MAX_SIZE (1)
+#endif
+
+#if NRF_CRYPTO_ECC_SECP521R1_ENABLED
+# define NRF_CRYPTO_BACKEND_ECC_RAW_PUBLIC_KEY_MAX_SIZE (2 * 66)
+#elif NRF_CRYPTO_ECC_BP512R1_ENABLED
+# define NRF_CRYPTO_BACKEND_ECC_RAW_PUBLIC_KEY_MAX_SIZE (2 * 64)
+#elif NRF_CRYPTO_ECC_BP384R1_ENABLED || NRF_CRYPTO_ECC_SECP384R1_ENABLED
+# define NRF_CRYPTO_BACKEND_ECC_RAW_PUBLIC_KEY_MAX_SIZE (2 * 48)
+#elif NRF_CRYPTO_ECC_BP256R1_ENABLED || NRF_CRYPTO_ECC_SECP256K1_ENABLED || NRF_CRYPTO_ECC_SECP256R1_ENABLED
+# define NRF_CRYPTO_BACKEND_ECC_RAW_PUBLIC_KEY_MAX_SIZE (2 * 32)
+#elif NRF_CRYPTO_ECC_SECP224K1_ENABLED || NRF_CRYPTO_ECC_SECP224R1_ENABLED
+# define NRF_CRYPTO_BACKEND_ECC_RAW_PUBLIC_KEY_MAX_SIZE (2 * 28)
+#elif NRF_CRYPTO_ECC_SECP192K1_ENABLED || NRF_CRYPTO_ECC_SECP192R1_ENABLED
+# define NRF_CRYPTO_BACKEND_ECC_RAW_PUBLIC_KEY_MAX_SIZE (2 * 24)
+#elif NRF_CRYPTO_ECC_SECP160K1_ENABLED || NRF_CRYPTO_ECC_SECP160R1_ENABLED || NRF_CRYPTO_ECC_SECP160R2_ENABLED
+# define NRF_CRYPTO_BACKEND_ECC_RAW_PUBLIC_KEY_MAX_SIZE (2 * 20)
+#elif NRF_CRYPTO_ECC_CURVE25519_ENABLED || NRF_CRYPTO_ECC_ED25519_ENABLED
+# define NRF_CRYPTO_BACKEND_ECC_RAW_PUBLIC_KEY_MAX_SIZE (32)
+#else
+# define NRF_CRYPTO_BACKEND_ECC_RAW_PUBLIC_KEY_MAX_SIZE (1)
+#endif
+
+
+#ifdef __cplusplus
+}
+#endif
+
+
+#endif // !defined(__SDK_DOXYGEN__)
+#endif // NRF_CRYPTO_ECC_BACKEND_H__
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/nrf_crypto_ecc_shared.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/nrf_crypto_ecc_shared.h
new file mode 100644
index 0000000..33fd37f
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/nrf_crypto_ecc_shared.h
@@ -0,0 +1,229 @@
+/**
+ * Copyright (c) 2018 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+
+#ifndef NRF_CRYPTO_ECC_SHARED_H__
+#define NRF_CRYPTO_ECC_SHARED_H__
+#if !defined(__SDK_DOXYGEN__)
+
+#include <stdint.h>
+#include <stddef.h>
+#include <stdbool.h>
+
+#include "sdk_errors.h"
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+#define NRF_CRYPTO_INTERNAL_ECC_PRIVATE_KEY_INIT_VALUE (0x4D465276) /**< @internal @brief Init value for all ECC private keys. ASCII "nRFv". */
+#define NRF_CRYPTO_INTERNAL_ECC_PUBLIC_KEY_INIT_VALUE (0x4D465270) /**< @internal @brief Init value for all ECC public keys. ASCII "nRFp". */
+
+
+// Forward declaration only
+struct nrf_crypto_ecc_curve_info_s;
+
+
+/** @brief Header structure at the beginning of each key structure.
+ */
+typedef struct
+{
+ uint32_t init_value; /**< @internal @brief Init value to check if key was correctly initialized. */
+ struct nrf_crypto_ecc_curve_info_s const * p_info; /**< @internal @brief Points to information structure of an associated curve type. */
+} nrf_crypto_internal_ecc_key_header_t;
+
+
+/** @internal @brief Function pointer for backend implementation of a key pair garatarion.
+ *
+ * @note All parameters provided to the backend are vefified in frontend. Verification includes
+ * checking of NULL pointers, buffer size, initialization values. Front end also take full care of
+ * common ECC key hearder @ref nrf_crypto_internal_ecc_key_header_t.
+ *
+ * @param[in] p_context Pointer to context.
+ * @param[out] p_private_key Pointer where to put new private key.
+ * @param[out] p_public_key Pointer where to put new public key.
+ */
+typedef ret_code_t (*nrf_crypto_backend_ecc_key_pair_generate_fn_t)(
+ void * p_context,
+ void * p_private_key,
+ void * p_public_key);
+
+
+/** @internal @brief Function pointer for backend implementation of a public key calculation.
+ *
+ * @note All parameters provided to the backend are vefified in frontend. Verification includes
+ * checking of NULL pointers, buffer size, initialization values. Front end also take full care of
+ * common ECC key hearder @ref nrf_crypto_internal_ecc_key_header_t.
+ *
+ * @param[in] p_context Pointer to context.
+ * @param[in] p_private_key Pointer to private key.
+ * @param[out] p_public_key Pointer where to put new public key.
+ */
+typedef ret_code_t (*nrf_crypto_backend_ecc_public_key_calculate_fn_t)(
+ void * p_context,
+ void const * p_private_key,
+ void * p_public_key);
+
+
+/** @internal @brief Function pointer for backend implementation of raw to private key conversion.
+ *
+ * @note All parameters provided to the backend are vefified in frontend. Verification includes
+ * checking of NULL pointers, buffer size, initialization values. Front end also take full care of
+ * common ECC key hearder @ref nrf_crypto_internal_ecc_key_header_t.
+ *
+ * @param[out] p_private_key Pointer where to put new private key.
+ * @param[in] p_raw_data Pointer to raw data.
+ */
+typedef ret_code_t (*nrf_crypto_backend_ecc_private_key_from_raw_fn_t)(
+ void * p_private_key,
+ uint8_t const * p_raw_data);
+
+
+/** @internal @brief Function pointer for backend implementation of private key to raw conversion.
+ *
+ * @note All parameters provided to the backend are vefified in frontend. Verification includes
+ * checking of NULL pointers, buffer size, initialization values. Front end also take full care of
+ * common ECC key hearder @ref nrf_crypto_internal_ecc_key_header_t.
+ *
+ * @param[in] p_private_key Pointer to private key.
+ * @param[out] p_raw_data Pointer where to put raw data.
+ */
+typedef ret_code_t (*nrf_crypto_backend_ecc_private_key_to_raw_fn_t)(
+ void const * p_private_key,
+ uint8_t * p_raw_data);
+
+
+/** @internal @brief Function pointer for backend implementation of raw to public key conversion.
+ *
+ * @note All parameters provided to the backend are vefified in frontend. Verification includes
+ * checking of NULL pointers, buffer size, initialization values. Front end also take full care of
+ * common ECC key hearder @ref nrf_crypto_internal_ecc_key_header_t.
+ *
+ * @param[out] p_public_key Pointer where to put new public key.
+ * @param[in] p_raw_data Pointer to raw data.
+ */
+typedef ret_code_t (*nrf_crypto_backend_ecc_public_key_from_raw_fn_t)(
+ void * p_public_key,
+ uint8_t const * p_raw_data);
+
+
+/** @internal @brief Function pointer for backend implementation of public key to raw conversion.
+ *
+ * @note All parameters provided to the backend are vefified in frontend. Verification includes
+ * checking of NULL pointers, buffer size, initialization values. Front end also take full care of
+ * common ECC key hearder @ref nrf_crypto_internal_ecc_key_header_t.
+ *
+ * @param[in] p_public_key Pointer to public key.
+ * @param[out] p_raw_data Pointer where to put raw data.
+ */
+typedef ret_code_t (*nrf_crypto_backend_ecc_public_key_to_raw_fn_t)(
+ void const * p_public_key,
+ uint8_t * p_raw_data);
+
+
+/** @internal @brief Function pointer for backend implementation of key (public or private) deallocation.
+ *
+ * @note All parameters provided to the backend are vefified in frontend. Verification includes
+ * checking of NULL pointers, buffer size, initialization values. Front end also take full care of
+ * common ECC key hearder @ref nrf_crypto_internal_ecc_key_header_t.
+ *
+ * @param[in] p_key Pointer to public or private key.
+ */
+typedef ret_code_t (*nrf_crypto_backend_ecc_key_free_fn_t)(
+ void * p_key);
+
+
+/** @internal @brief Function for checking and preparing ECC key output parameter.
+ *
+ * @param[in] p_curve_info Curve info provided by user that will be used to create a new key.
+ * @param[out] p_key_header Key header that have to be prepared.
+ * @return NRF_SUCCESS if parameters are valid, error otherwise.
+ */
+ret_code_t nrf_crypto_internal_ecc_key_output_prepare(
+ struct nrf_crypto_ecc_curve_info_s const * p_curve_info,
+ nrf_crypto_internal_ecc_key_header_t * p_key_header);
+
+
+/** @internal @brief Function for checking ECC key input parameter.
+ *
+ * @param[in] p_key_header Key header that have to be checked.
+ * @param[in] init_value Expected init value in this key.
+ * @return NRF_SUCCESS if parameter is valid, error otherwise.
+ */
+ret_code_t nrf_crypto_internal_ecc_key_input_check(
+ nrf_crypto_internal_ecc_key_header_t const * p_key_header,
+ uint32_t init_value);
+
+
+/** @internal @brief Function for checking and preparing raw data output parameter.
+ *
+ * @param[out] p_raw_data Buffer where output will be written.
+ * @param[in,out] p_raw_data_size Pointer to size of the data. On input this is size of provided by
+ * the user buffer. On output is equal @p expected_size. This pointer
+ * can be NULL if used does not want to do size checking.
+ * @param[in] expected_size Size of output data that will be written to the buffer.
+ * @return NRF_SUCCESS if parameters are valid, error otherwise.
+ */
+ret_code_t nrf_crypto_internal_ecc_raw_output_prepare(
+ uint8_t * p_raw_data,
+ size_t * p_raw_data_size,
+ size_t expected_size);
+
+
+/** @internal @brief Function for checking raw data input parameter.
+ *
+ * @param[in] p_raw_data Buffer where data is located.
+ * @param[in] raw_data_size Size of the data.Function will fail if it is different than @p expected_size.
+ * @param[in] expected_size Expected size of the data.
+ * @return NRF_SUCCESS if parameters are valid, error otherwise.
+ */
+ret_code_t nrf_crypto_internal_ecc_raw_input_check(
+ uint8_t const * p_raw_data,
+ size_t raw_data_size,
+ size_t expected_size);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // !defined(__SDK_DOXYGEN__)
+#endif // NRF_CRYPTO_ECC_SHARED_H__
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/nrf_crypto_ecdh.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/nrf_crypto_ecdh.c
new file mode 100644
index 0000000..3d7d798
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/nrf_crypto_ecdh.c
@@ -0,0 +1,286 @@
+/**
+ * Copyright (c) 2018 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+
+#include "nrf_crypto_error.h"
+#include "nrf_crypto_mem.h"
+#include "nrf_crypto_ecc.h"
+#include "nrf_crypto_ecdh.h"
+#include "app_util.h"
+#include "sdk_macros.h"
+
+
+#if NRF_CRYPTO_ECC_ENABLED
+
+
+#if NRF_CRYPTO_ECC_IMPLEMENTED_CURVES_COUNT > 1
+
+
+static const nrf_crypto_backend_ecdh_compute_fn_t compute_impl[] =
+{
+#if NRF_CRYPTO_ECC_SECP160R1_ENABLED
+ nrf_crypto_backend_secp160r1_ecdh_compute,
+#endif
+#if NRF_CRYPTO_ECC_SECP160R2_ENABLED
+ nrf_crypto_backend_secp160r2_ecdh_compute,
+#endif
+#if NRF_CRYPTO_ECC_SECP192R1_ENABLED
+ nrf_crypto_backend_secp192r1_ecdh_compute,
+#endif
+#if NRF_CRYPTO_ECC_SECP224R1_ENABLED
+ nrf_crypto_backend_secp224r1_ecdh_compute,
+#endif
+#if NRF_CRYPTO_ECC_SECP256R1_ENABLED
+ nrf_crypto_backend_secp256r1_ecdh_compute,
+#endif
+#if NRF_CRYPTO_ECC_SECP384R1_ENABLED
+ nrf_crypto_backend_secp384r1_ecdh_compute,
+#endif
+#if NRF_CRYPTO_ECC_SECP521R1_ENABLED
+ nrf_crypto_backend_secp521r1_ecdh_compute,
+#endif
+#if NRF_CRYPTO_ECC_SECP160K1_ENABLED
+ nrf_crypto_backend_secp160k1_ecdh_compute,
+#endif
+#if NRF_CRYPTO_ECC_SECP192K1_ENABLED
+ nrf_crypto_backend_secp192k1_ecdh_compute,
+#endif
+#if NRF_CRYPTO_ECC_SECP224K1_ENABLED
+ nrf_crypto_backend_secp224k1_ecdh_compute,
+#endif
+#if NRF_CRYPTO_ECC_SECP256K1_ENABLED
+ nrf_crypto_backend_secp256k1_ecdh_compute,
+#endif
+#if NRF_CRYPTO_ECC_BP256R1_ENABLED
+ nrf_crypto_backend_bp256r1_ecdh_compute,
+#endif
+#if NRF_CRYPTO_ECC_BP384R1_ENABLED
+ nrf_crypto_backend_bp384r1_ecdh_compute,
+#endif
+#if NRF_CRYPTO_ECC_BP512R1_ENABLED
+ nrf_crypto_backend_bp512r1_ecdh_compute,
+#endif
+#if NRF_CRYPTO_ECC_CURVE25519_ENABLED
+ nrf_crypto_backend_curve25519_ecdh_compute,
+#endif
+#if NRF_CRYPTO_ECC_ED25519_ENABLED
+ nrf_crypto_backend_ed25519_ecdh_compute,
+#endif
+};
+
+
+static const uint16_t compute_impl_context_size[] =
+{
+#if NRF_CRYPTO_ECC_SECP160R1_ENABLED
+ NRF_CRYPTO_BACKEND_SECP160R1_ECDH_CONTEXT_SIZE,
+#endif
+#if NRF_CRYPTO_ECC_SECP160R2_ENABLED
+ NRF_CRYPTO_BACKEND_SECP160R2_ECDH_CONTEXT_SIZE,
+#endif
+#if NRF_CRYPTO_ECC_SECP192R1_ENABLED
+ NRF_CRYPTO_BACKEND_SECP192R1_ECDH_CONTEXT_SIZE,
+#endif
+#if NRF_CRYPTO_ECC_SECP224R1_ENABLED
+ NRF_CRYPTO_BACKEND_SECP224R1_ECDH_CONTEXT_SIZE,
+#endif
+#if NRF_CRYPTO_ECC_SECP256R1_ENABLED
+ NRF_CRYPTO_BACKEND_SECP256R1_ECDH_CONTEXT_SIZE,
+#endif
+#if NRF_CRYPTO_ECC_SECP384R1_ENABLED
+ NRF_CRYPTO_BACKEND_SECP384R1_ECDH_CONTEXT_SIZE,
+#endif
+#if NRF_CRYPTO_ECC_SECP521R1_ENABLED
+ NRF_CRYPTO_BACKEND_SECP521R1_ECDH_CONTEXT_SIZE,
+#endif
+#if NRF_CRYPTO_ECC_SECP160K1_ENABLED
+ NRF_CRYPTO_BACKEND_SECP160K1_ECDH_CONTEXT_SIZE,
+#endif
+#if NRF_CRYPTO_ECC_SECP192K1_ENABLED
+ NRF_CRYPTO_BACKEND_SECP192K1_ECDH_CONTEXT_SIZE,
+#endif
+#if NRF_CRYPTO_ECC_SECP224K1_ENABLED
+ NRF_CRYPTO_BACKEND_SECP224K1_ECDH_CONTEXT_SIZE,
+#endif
+#if NRF_CRYPTO_ECC_SECP256K1_ENABLED
+ NRF_CRYPTO_BACKEND_SECP256K1_ECDH_CONTEXT_SIZE,
+#endif
+#if NRF_CRYPTO_ECC_BP256R1_ENABLED
+ NRF_CRYPTO_BACKEND_BP256R1_ECDH_CONTEXT_SIZE,
+#endif
+#if NRF_CRYPTO_ECC_BP384R1_ENABLED
+ NRF_CRYPTO_BACKEND_BP384R1_ECDH_CONTEXT_SIZE,
+#endif
+#if NRF_CRYPTO_ECC_BP512R1_ENABLED
+ NRF_CRYPTO_BACKEND_BP512R1_ECDH_CONTEXT_SIZE,
+#endif
+#if NRF_CRYPTO_ECC_CURVE25519_ENABLED
+ NRF_CRYPTO_BACKEND_CURVE25519_ECDH_CONTEXT_SIZE,
+#endif
+#if NRF_CRYPTO_ECC_ED25519_ENABLED
+ NRF_CRYPTO_BACKEND_ED25519_ECDH_CONTEXT_SIZE,
+#endif
+};
+
+#define BACKEND_IMPL_GET(table, curve_type) (table)[(uint32_t)(curve_type)]
+
+#else
+
+
+#if NRF_CRYPTO_ECC_SECP160R1_ENABLED
+#define compute_impl nrf_crypto_backend_secp160r1_ecdh_compute
+#define compute_impl_context_size NRF_CRYPTO_BACKEND_SECP160R1_ECDH_CONTEXT_SIZE
+#elif NRF_CRYPTO_ECC_SECP160R2_ENABLED
+#define compute_impl nrf_crypto_backend_secp160r2_ecdh_compute
+#define compute_impl_context_size NRF_CRYPTO_BACKEND_SECP160R2_ECDH_CONTEXT_SIZE
+#elif NRF_CRYPTO_ECC_SECP192R1_ENABLED
+#define compute_impl nrf_crypto_backend_secp192r1_ecdh_compute
+#define compute_impl_context_size NRF_CRYPTO_BACKEND_SECP192R1_ECDH_CONTEXT_SIZE
+#elif NRF_CRYPTO_ECC_SECP224R1_ENABLED
+#define compute_impl nrf_crypto_backend_secp224r1_ecdh_compute
+#define compute_impl_context_size NRF_CRYPTO_BACKEND_SECP224R1_ECDH_CONTEXT_SIZE
+#elif NRF_CRYPTO_ECC_SECP256R1_ENABLED
+#define compute_impl nrf_crypto_backend_secp256r1_ecdh_compute
+#define compute_impl_context_size NRF_CRYPTO_BACKEND_SECP256R1_ECDH_CONTEXT_SIZE
+#elif NRF_CRYPTO_ECC_SECP384R1_ENABLED
+#define compute_impl nrf_crypto_backend_secp384r1_ecdh_compute
+#define compute_impl_context_size NRF_CRYPTO_BACKEND_SECP384R1_ECDH_CONTEXT_SIZE
+#elif NRF_CRYPTO_ECC_SECP521R1_ENABLED
+#define compute_impl nrf_crypto_backend_secp521r1_ecdh_compute
+#define compute_impl_context_size NRF_CRYPTO_BACKEND_SECP521R1_ECDH_CONTEXT_SIZE
+#elif NRF_CRYPTO_ECC_SECP160K1_ENABLED
+#define compute_impl nrf_crypto_backend_secp160k1_ecdh_compute
+#define compute_impl_context_size NRF_CRYPTO_BACKEND_SECP160K1_ECDH_CONTEXT_SIZE
+#elif NRF_CRYPTO_ECC_SECP192K1_ENABLED
+#define compute_impl nrf_crypto_backend_secp192k1_ecdh_compute
+#define compute_impl_context_size NRF_CRYPTO_BACKEND_SECP192K1_ECDH_CONTEXT_SIZE
+#elif NRF_CRYPTO_ECC_SECP224K1_ENABLED
+#define compute_impl nrf_crypto_backend_secp224k1_ecdh_compute
+#define compute_impl_context_size NRF_CRYPTO_BACKEND_SECP224K1_ECDH_CONTEXT_SIZE
+#elif NRF_CRYPTO_ECC_SECP256K1_ENABLED
+#define compute_impl nrf_crypto_backend_secp256k1_ecdh_compute
+#define compute_impl_context_size NRF_CRYPTO_BACKEND_SECP256K1_ECDH_CONTEXT_SIZE
+#elif NRF_CRYPTO_ECC_BP256R1_ENABLED
+#define compute_impl nrf_crypto_backend_bp256r1_ecdh_compute
+#define compute_impl_context_size NRF_CRYPTO_BACKEND_BP256R1_ECDH_CONTEXT_SIZE
+#elif NRF_CRYPTO_ECC_BP384R1_ENABLED
+#define compute_impl nrf_crypto_backend_bp384r1_ecdh_compute
+#define compute_impl_context_size NRF_CRYPTO_BACKEND_BP384R1_ECDH_CONTEXT_SIZE
+#elif NRF_CRYPTO_ECC_BP512R1_ENABLED
+#define compute_impl nrf_crypto_backend_bp512r1_ecdh_compute
+#define compute_impl_context_size NRF_CRYPTO_BACKEND_BP512R1_ECDH_CONTEXT_SIZE
+#elif NRF_CRYPTO_ECC_CURVE25519_ENABLED
+#define compute_impl nrf_crypto_backend_curve25519_ecdh_compute
+#define compute_impl_context_size NRF_CRYPTO_BACKEND_CURVE25519_ECDH_CONTEXT_SIZE
+#elif NRF_CRYPTO_ECC_ED25519_ENABLED
+#define compute_impl nrf_crypto_backend_ed25519_ecdh_compute
+#define compute_impl_context_size NRF_CRYPTO_BACKEND_ED25519_ECDH_CONTEXT_SIZE
+#else
+#define compute_impl NULL
+#define compute_impl_context_size 0
+#endif
+
+#define BACKEND_IMPL_GET(function, curve_type) (function)
+
+#endif
+
+
+ret_code_t nrf_crypto_ecdh_compute(
+ nrf_crypto_ecdh_context_t * p_context,
+ nrf_crypto_ecc_private_key_t const * p_private_key,
+ nrf_crypto_ecc_public_key_t const * p_public_key,
+ uint8_t * p_shared_secret,
+ size_t * p_shared_secret_size)
+{
+ ret_code_t result;
+ void * p_allocated_context = NULL;
+ nrf_crypto_backend_ecdh_compute_fn_t backend_implementation;
+ size_t context_size;
+ nrf_crypto_ecc_curve_info_t const * p_info;
+
+ // Get pointer to header for each key
+ nrf_crypto_internal_ecc_key_header_t const * p_private_key_header =
+ (nrf_crypto_internal_ecc_key_header_t const *)p_private_key;
+ nrf_crypto_internal_ecc_key_header_t const * p_public_key_header =
+ (nrf_crypto_internal_ecc_key_header_t const *)p_public_key;
+
+ // Check and prepare parameters
+ result = nrf_crypto_internal_ecc_key_input_check(
+ p_private_key_header,
+ NRF_CRYPTO_INTERNAL_ECC_PRIVATE_KEY_INIT_VALUE);
+ VERIFY_SUCCESS(result);
+ result = nrf_crypto_internal_ecc_key_input_check(
+ p_public_key_header,
+ NRF_CRYPTO_INTERNAL_ECC_PUBLIC_KEY_INIT_VALUE);
+ VERIFY_SUCCESS(result);
+ VERIFY_TRUE(p_private_key_header->p_info == p_public_key_header->p_info,
+ NRF_ERROR_CRYPTO_ECDH_CURVE_MISMATCH);
+ p_info = p_private_key_header->p_info;
+ result = nrf_crypto_internal_ecc_raw_output_prepare(
+ p_shared_secret,
+ p_shared_secret_size,
+ p_info->raw_private_key_size);
+ VERIFY_SUCCESS(result);
+
+ // Get backend specific information
+ backend_implementation = BACKEND_IMPL_GET(compute_impl, p_info->curve_type);
+ context_size = BACKEND_IMPL_GET(compute_impl_context_size, p_info->curve_type);
+ VERIFY_TRUE(backend_implementation != NULL, NRF_ERROR_CRYPTO_FEATURE_UNAVAILABLE);
+
+ // Allocate context if not provided
+ if (p_context == NULL && context_size > 0)
+ {
+ p_allocated_context = NRF_CRYPTO_ALLOC(context_size);
+ VERIFY_TRUE(p_allocated_context != NULL, NRF_ERROR_CRYPTO_ALLOC_FAILED);
+ p_context = p_allocated_context;
+ }
+
+ // Execute backend implementation
+ result = backend_implementation(p_context, p_private_key, p_public_key, p_shared_secret);
+
+ // Deallocate context if allocated
+ if (p_allocated_context != NULL)
+ {
+ NRF_CRYPTO_FREE(p_allocated_context);
+ }
+
+ return result;
+}
+
+
+#endif // NRF_CRYPTO_ECC_ENABLED
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/nrf_crypto_ecdh.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/nrf_crypto_ecdh.h
new file mode 100644
index 0000000..7b177ef
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/nrf_crypto_ecdh.h
@@ -0,0 +1,207 @@
+/**
+ * Copyright (c) 2018 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+
+#ifndef NRF_CRYPTO_ECDH_H__
+#define NRF_CRYPTO_ECDH_H__
+
+/** @addtogroup nrf_crypto
+ * @{
+ * @addtogroup nrf_crypto_ecdh Elliptic Curve Diffie-Hellman (ECDH)
+ * @{
+ * @brief Provides elliptic curve cryptography functions for Diffie-Hellman shared secret exchange.
+ *
+ * @addtogroup nrf_crypto_ecdh_secp160r1 Definitions specific to secp160r1 (NIST 160-bit)
+ * @addtogroup nrf_crypto_ecdh_secp160r2 Definitions specific to secp160r2 (NIST 160-bit)
+ * @addtogroup nrf_crypto_ecdh_secp192r1 Definitions specific to secp192r1 (NIST 192-bit)
+ * @addtogroup nrf_crypto_ecdh_secp224r1 Definitions specific to secp224r1 (NIST 224-bit)
+ * @addtogroup nrf_crypto_ecdh_secp256r1 Definitions specific to secp256r1 (NIST 256-bit)
+ * @addtogroup nrf_crypto_ecdh_secp384r1 Definitions specific to secp384r1 (NIST 384-bit)
+ * @addtogroup nrf_crypto_ecdh_secp521r1 Definitions specific to secp521r1 (NIST 521-bit)
+ * @addtogroup nrf_crypto_ecdh_secp160k1 Definitions specific to secp160k1 (Koblitz 160-bit)
+ * @addtogroup nrf_crypto_ecdh_secp192k1 Definitions specific to secp192k1 (Koblitz 192-bit)
+ * @addtogroup nrf_crypto_ecdh_secp224k1 Definitions specific to secp224k1 (Koblitz 224-bit)
+ * @addtogroup nrf_crypto_ecdh_secp256k1 Definitions specific to secp256k1 (Koblitz 256-bit)
+ * @addtogroup nrf_crypto_ecdh_bp256r1 Definitions specific to bp256r1 (Brainpool 256-bit)
+ * @addtogroup nrf_crypto_ecdh_bp384r1 Definitions specific to bp384r1 (Brainpool 384-bit)
+ * @addtogroup nrf_crypto_ecdh_bp512r1 Definitions specific to bp512r1 (Brainpool 512-bit)
+ * @addtogroup nrf_crypto_ecdh_curve25519 Definitions specific to Curve25519
+ * @addtogroup nrf_crypto_ecdh_ed25519 Definitions specific to Ed25519
+ */
+
+#include <stdint.h>
+#include <stddef.h>
+
+#include "nrf_crypto_error.h"
+#include "nrf_crypto_ecc.h"
+#include "nrf_crypto_ecdh_shared.h"
+#include "nrf_crypto_ecdh_backend.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+#define NRF_CRYPTO_ECDH_SECP160R1_SHARED_SECRET_SIZE (160 / 8) /**< @brief Number of bytes in a shared secret using secp160r1 (NIST 160-bit). @ingroup nrf_crypto_ecdh_secp160r1 */
+#define NRF_CRYPTO_ECDH_SECP160R2_SHARED_SECRET_SIZE (160 / 8) /**< @brief Number of bytes in a shared secret using secp160r2 (NIST 160-bit). @ingroup nrf_crypto_ecdh_secp160r2 */
+#define NRF_CRYPTO_ECDH_SECP192R1_SHARED_SECRET_SIZE (192 / 8) /**< @brief Number of bytes in a shared secret using secp192r1 (NIST 192-bit). @ingroup nrf_crypto_ecdh_secp192r1 */
+#define NRF_CRYPTO_ECDH_SECP224R1_SHARED_SECRET_SIZE (224 / 8) /**< @brief Number of bytes in a shared secret using secp224r1 (NIST 224-bit). @ingroup nrf_crypto_ecdh_secp224r1 */
+#define NRF_CRYPTO_ECDH_SECP256R1_SHARED_SECRET_SIZE (256 / 8) /**< @brief Number of bytes in a shared secret using secp256r1 (NIST 256-bit). @ingroup nrf_crypto_ecdh_secp256r1 */
+#define NRF_CRYPTO_ECDH_SECP384R1_SHARED_SECRET_SIZE (384 / 8) /**< @brief Number of bytes in a shared secret using secp384r1 (NIST 384-bit). @ingroup nrf_crypto_ecdh_secp384r1 */
+#define NRF_CRYPTO_ECDH_SECP521R1_SHARED_SECRET_SIZE (528 / 8) /**< @brief Number of bytes in a shared secret using secp521r1 (NIST 521-bit). @ingroup nrf_crypto_ecdh_secp521r1 */
+#define NRF_CRYPTO_ECDH_SECP160K1_SHARED_SECRET_SIZE (160 / 8) /**< @brief Number of bytes in a shared secret using secp160k1 (Koblitz 160-bit). @ingroup nrf_crypto_ecdh_secp160k1 */
+#define NRF_CRYPTO_ECDH_SECP192K1_SHARED_SECRET_SIZE (192 / 8) /**< @brief Number of bytes in a shared secret using secp192k1 (Koblitz 192-bit). @ingroup nrf_crypto_ecdh_secp192k1 */
+#define NRF_CRYPTO_ECDH_SECP224K1_SHARED_SECRET_SIZE (224 / 8) /**< @brief Number of bytes in a shared secret using secp224k1 (Koblitz 224-bit). @ingroup nrf_crypto_ecdh_secp224k1 */
+#define NRF_CRYPTO_ECDH_SECP256K1_SHARED_SECRET_SIZE (256 / 8) /**< @brief Number of bytes in a shared secret using secp256k1 (Koblitz 256-bit). @ingroup nrf_crypto_ecdh_secp256k1 */
+#define NRF_CRYPTO_ECDH_BP256R1_SHARED_SECRET_SIZE (256 / 8) /**< @brief Number of bytes in a shared secret using bp256r1 (Brainpool 256-bit). @ingroup nrf_crypto_ecdh_bp256r1 */
+#define NRF_CRYPTO_ECDH_BP384R1_SHARED_SECRET_SIZE (384 / 8) /**< @brief Number of bytes in a shared secret using bp384r1 (Brainpool 384-bit). @ingroup nrf_crypto_ecdh_bp384r1 */
+#define NRF_CRYPTO_ECDH_BP512R1_SHARED_SECRET_SIZE (512 / 8) /**< @brief Number of bytes in a shared secret using bp512r1 (Brainpool 512-bit). @ingroup nrf_crypto_ecdh_bp512r1 */
+#define NRF_CRYPTO_ECDH_CURVE25519_SHARED_SECRET_SIZE (256 / 8) /**< @brief Number of bytes in a shared secret using Curve25519. @ingroup nrf_crypto_ecdh_curve25519 */
+#define NRF_CRYPTO_ECDH_ED25519_SHARED_SECRET_SIZE (256 / 8) /**< @brief Number of bytes in a shared secret using Ed25519. @ingroup nrf_crypto_ecdh_ed25519 */
+#define NRF_CRYPTO_ECDH_SHARED_SECRET_MAX_SIZE NRF_CRYPTO_ECC_RAW_PRIVATE_KEY_MAX_SIZE /**< @brief Maximum size of a shared secret in bytes for all enabled curves. */
+
+
+typedef nrf_crypto_backend_secp160r1_ecdh_context_t nrf_crypto_ecdh_secp160r1_context_t; /**< @brief Context used to store temporary data during computing ECDH for curve secp160r1 (NIST 160-bit). @ingroup nrf_crypto_ecdh_secp160r1 */
+typedef nrf_crypto_backend_secp160r2_ecdh_context_t nrf_crypto_ecdh_secp160r2_context_t; /**< @brief Context used to store temporary data during computing ECDH for curve secp160r2 (NIST 160-bit). @ingroup nrf_crypto_ecdh_secp160r2 */
+typedef nrf_crypto_backend_secp192r1_ecdh_context_t nrf_crypto_ecdh_secp192r1_context_t; /**< @brief Context used to store temporary data during computing ECDH for curve secp192r1 (NIST 192-bit). @ingroup nrf_crypto_ecdh_secp192r1 */
+typedef nrf_crypto_backend_secp224r1_ecdh_context_t nrf_crypto_ecdh_secp224r1_context_t; /**< @brief Context used to store temporary data during computing ECDH for curve secp224r1 (NIST 224-bit). @ingroup nrf_crypto_ecdh_secp224r1 */
+typedef nrf_crypto_backend_secp256r1_ecdh_context_t nrf_crypto_ecdh_secp256r1_context_t; /**< @brief Context used to store temporary data during computing ECDH for curve secp256r1 (NIST 256-bit). @ingroup nrf_crypto_ecdh_secp256r1 */
+typedef nrf_crypto_backend_secp384r1_ecdh_context_t nrf_crypto_ecdh_secp384r1_context_t; /**< @brief Context used to store temporary data during computing ECDH for curve secp384r1 (NIST 384-bit). @ingroup nrf_crypto_ecdh_secp384r1 */
+typedef nrf_crypto_backend_secp521r1_ecdh_context_t nrf_crypto_ecdh_secp521r1_context_t; /**< @brief Context used to store temporary data during computing ECDH for curve secp521r1 (NIST 521-bit). @ingroup nrf_crypto_ecdh_secp521r1 */
+typedef nrf_crypto_backend_secp160k1_ecdh_context_t nrf_crypto_ecdh_secp160k1_context_t; /**< @brief Context used to store temporary data during computing ECDH for curve secp160k1 (Koblitz 160-bit). @ingroup nrf_crypto_ecdh_secp160k1 */
+typedef nrf_crypto_backend_secp192k1_ecdh_context_t nrf_crypto_ecdh_secp192k1_context_t; /**< @brief Context used to store temporary data during computing ECDH for curve secp192k1 (Koblitz 192-bit). @ingroup nrf_crypto_ecdh_secp192k1 */
+typedef nrf_crypto_backend_secp224k1_ecdh_context_t nrf_crypto_ecdh_secp224k1_context_t; /**< @brief Context used to store temporary data during computing ECDH for curve secp224k1 (Koblitz 224-bit). @ingroup nrf_crypto_ecdh_secp224k1 */
+typedef nrf_crypto_backend_secp256k1_ecdh_context_t nrf_crypto_ecdh_secp256k1_context_t; /**< @brief Context used to store temporary data during computing ECDH for curve secp256k1 (Koblitz 256-bit). @ingroup nrf_crypto_ecdh_secp256k1 */
+typedef nrf_crypto_backend_bp256r1_ecdh_context_t nrf_crypto_ecdh_bp256r1_context_t; /**< @brief Context used to store temporary data during computing ECDH for curve bp256r1 (Brainpool 256-bit). @ingroup nrf_crypto_ecdh_bp256r1 */
+typedef nrf_crypto_backend_bp384r1_ecdh_context_t nrf_crypto_ecdh_bp384r1_context_t; /**< @brief Context used to store temporary data during computing ECDH for curve bp384r1 (Brainpool 384-bit). @ingroup nrf_crypto_ecdh_bp384r1 */
+typedef nrf_crypto_backend_bp512r1_ecdh_context_t nrf_crypto_ecdh_bp512r1_context_t; /**< @brief Context used to store temporary data during computing ECDH for curve bp512r1 (Brainpool 512-bit). @ingroup nrf_crypto_ecdh_bp512r1 */
+typedef nrf_crypto_backend_curve25519_ecdh_context_t nrf_crypto_ecdh_curve25519_context_t; /**< @brief Context used to store temporary data during computing ECDH for curve Curve25519. @ingroup nrf_crypto_ecdh_curve25519 */
+typedef nrf_crypto_backend_ed25519_ecdh_context_t nrf_crypto_ecdh_ed25519_context_t; /**< @brief Context used to store temporary data during computing ECDH for curve Ed25519. @ingroup nrf_crypto_ecdh_ed25519 */
+
+
+typedef uint8_t nrf_crypto_ecdh_secp160r1_shared_secret_t
+ [NRF_CRYPTO_ECDH_SECP160R1_SHARED_SECRET_SIZE]; /**< @brief Array type of a shared secret for curve secp160r1 (NIST 160-bit). @ingroup nrf_crypto_ecdh_secp160r1 */
+typedef uint8_t nrf_crypto_ecdh_secp160r2_shared_secret_t
+ [NRF_CRYPTO_ECDH_SECP160R2_SHARED_SECRET_SIZE]; /**< @brief Array type of a shared secret for curve secp160r2 (NIST 160-bit). @ingroup nrf_crypto_ecdh_secp160r2 */
+typedef uint8_t nrf_crypto_ecdh_secp192r1_shared_secret_t
+ [NRF_CRYPTO_ECDH_SECP192R1_SHARED_SECRET_SIZE]; /**< @brief Array type of a shared secret for curve secp192r1 (NIST 192-bit). @ingroup nrf_crypto_ecdh_secp192r1 */
+typedef uint8_t nrf_crypto_ecdh_secp224r1_shared_secret_t
+ [NRF_CRYPTO_ECDH_SECP224R1_SHARED_SECRET_SIZE]; /**< @brief Array type of a shared secret for curve secp224r1 (NIST 224-bit). @ingroup nrf_crypto_ecdh_secp224r1 */
+typedef uint8_t nrf_crypto_ecdh_secp256r1_shared_secret_t
+ [NRF_CRYPTO_ECDH_SECP256R1_SHARED_SECRET_SIZE]; /**< @brief Array type of a shared secret for curve secp256r1 (NIST 256-bit). @ingroup nrf_crypto_ecdh_secp256r1 */
+typedef uint8_t nrf_crypto_ecdh_secp384r1_shared_secret_t
+ [NRF_CRYPTO_ECDH_SECP384R1_SHARED_SECRET_SIZE]; /**< @brief Array type of a shared secret for curve secp384r1 (NIST 384-bit). @ingroup nrf_crypto_ecdh_secp384r1 */
+typedef uint8_t nrf_crypto_ecdh_secp521r1_shared_secret_t
+ [NRF_CRYPTO_ECDH_SECP521R1_SHARED_SECRET_SIZE]; /**< @brief Array type of a shared secret for curve secp521r1 (NIST 521-bit). @ingroup nrf_crypto_ecdh_secp521r1 */
+typedef uint8_t nrf_crypto_ecdh_secp160k1_shared_secret_t
+ [NRF_CRYPTO_ECDH_SECP160K1_SHARED_SECRET_SIZE]; /**< @brief Array type of a shared secret for curve secp160k1 (Koblitz 160-bit). @ingroup nrf_crypto_ecdh_secp160k1 */
+typedef uint8_t nrf_crypto_ecdh_secp192k1_shared_secret_t
+ [NRF_CRYPTO_ECDH_SECP192K1_SHARED_SECRET_SIZE]; /**< @brief Array type of a shared secret for curve secp192k1 (Koblitz 192-bit). @ingroup nrf_crypto_ecdh_secp192k1 */
+typedef uint8_t nrf_crypto_ecdh_secp224k1_shared_secret_t
+ [NRF_CRYPTO_ECDH_SECP224K1_SHARED_SECRET_SIZE]; /**< @brief Array type of a shared secret for curve secp224k1 (Koblitz 224-bit). @ingroup nrf_crypto_ecdh_secp224k1 */
+typedef uint8_t nrf_crypto_ecdh_secp256k1_shared_secret_t
+ [NRF_CRYPTO_ECDH_SECP256K1_SHARED_SECRET_SIZE]; /**< @brief Array type of a shared secret for curve secp256k1 (Koblitz 256-bit). @ingroup nrf_crypto_ecdh_secp256k1 */
+typedef uint8_t nrf_crypto_ecdh_bp256r1_shared_secret_t
+ [NRF_CRYPTO_ECDH_BP256R1_SHARED_SECRET_SIZE]; /**< @brief Array type of a shared secret for curve bp256r1 (Brainpool 256-bit). @ingroup nrf_crypto_ecdh_bp256r1 */
+typedef uint8_t nrf_crypto_ecdh_bp384r1_shared_secret_t
+ [NRF_CRYPTO_ECDH_BP384R1_SHARED_SECRET_SIZE]; /**< @brief Array type of a shared secret for curve bp384r1 (Brainpool 384-bit). @ingroup nrf_crypto_ecdh_bp384r1 */
+typedef uint8_t nrf_crypto_ecdh_bp512r1_shared_secret_t
+ [NRF_CRYPTO_ECDH_BP512R1_SHARED_SECRET_SIZE]; /**< @brief Array type of a shared secret for curve bp512r1 (Brainpool 512-bit). @ingroup nrf_crypto_ecdh_bp512r1 */
+typedef uint8_t nrf_crypto_ecdh_curve25519_shared_secret_t
+ [NRF_CRYPTO_ECDH_CURVE25519_SHARED_SECRET_SIZE]; /**< @brief Array type of a shared secret for curve Curve25519. @ingroup nrf_crypto_ecdh_curve25519 */
+typedef uint8_t nrf_crypto_ecdh_ed25519_shared_secret_t
+ [NRF_CRYPTO_ECDH_ED25519_SHARED_SECRET_SIZE]; /**< @brief Array type of a shared secret for curve Ed25519. @ingroup nrf_crypto_ecdh_ed25519 */
+typedef uint8_t nrf_crypto_ecdh_shared_secret_t
+ [NRF_CRYPTO_ECDH_SHARED_SECRET_MAX_SIZE]; /**< @brief Array type of a shared secret for any of the enabled curves. */
+
+
+/** @brief Union holding a context for ECDH computation.
+ */
+typedef union
+{
+ nrf_crypto_ecdh_secp160r1_context_t context_secp160r1; /**< @brief Occupies space for secp160r1 (NIST 160-bit). */
+ nrf_crypto_ecdh_secp160r2_context_t context_secp160r2; /**< @brief Occupies space for secp160r2 (NIST 160-bit). */
+ nrf_crypto_ecdh_secp192r1_context_t context_secp192r1; /**< @brief Occupies space for secp192r1 (NIST 192-bit). */
+ nrf_crypto_ecdh_secp224r1_context_t context_secp224r1; /**< @brief Occupies space for secp224r1 (NIST 224-bit). */
+ nrf_crypto_ecdh_secp256r1_context_t context_secp256r1; /**< @brief Occupies space for secp256r1 (NIST 256-bit). */
+ nrf_crypto_ecdh_secp384r1_context_t context_secp384r1; /**< @brief Occupies space for secp384r1 (NIST 384-bit). */
+ nrf_crypto_ecdh_secp521r1_context_t context_secp521r1; /**< @brief Occupies space for secp521r1 (NIST 521-bit). */
+ nrf_crypto_ecdh_secp160k1_context_t context_secp160k1; /**< @brief Occupies space for secp160k1 (Koblitz 160-bit). */
+ nrf_crypto_ecdh_secp192k1_context_t context_secp192k1; /**< @brief Occupies space for secp192k1 (Koblitz 192-bit). */
+ nrf_crypto_ecdh_secp224k1_context_t context_secp224k1; /**< @brief Occupies space for secp224k1 (Koblitz 224-bit). */
+ nrf_crypto_ecdh_secp256k1_context_t context_secp256k1; /**< @brief Occupies space for secp256k1 (Koblitz 256-bit). */
+ nrf_crypto_ecdh_bp256r1_context_t context_bp256r1; /**< @brief Occupies space for bp256r1 (Brainpool 256-bit). */
+ nrf_crypto_ecdh_bp384r1_context_t context_bp384r1; /**< @brief Occupies space for bp384r1 (Brainpool 384-bit). */
+ nrf_crypto_ecdh_bp512r1_context_t context_bp512r1; /**< @brief Occupies space for bp512r1 (Brainpool 512-bit). */
+ nrf_crypto_ecdh_curve25519_context_t context_curve25519; /**< @brief Occupies space for Curve25519. */
+ nrf_crypto_ecdh_ed25519_context_t context_ed25519; /**< @brief Occupies space for Ed25519. */
+} nrf_crypto_ecdh_context_t;
+
+
+/** @brief Computes shared secret using ECC Diffie-Hellman.
+ *
+ * @param[in] p_context Pointer to temporary structure holding context information.
+ * If it is NULL, necessary data will be allocated with
+ * @ref NRF_CRYPTO_ALLOC and freed at the end of the function.
+ * @param[in] p_private_key Pointer to structure holding a private key.
+ * @param[in] p_public_key Pointer to structure holding a public key received from the other party.
+ * @param[out] p_shared_secret Pointer to buffer where shared secret will be put.
+ * @param[in,out] p_shared_secret_size Maximum number of bytes that @p p_shared_secret buffer can hold on input
+ * and the actual number of bytes used by the data on output.
+ * Actual size for selected curve is defined by
+ * the preprocessor definitions, e.g.
+ * @ref NRF_CRYPTO_ECDH_SECP256R1_SHARED_SECRET_SIZE.
+ */
+ret_code_t nrf_crypto_ecdh_compute(
+ nrf_crypto_ecdh_context_t * p_context,
+ nrf_crypto_ecc_private_key_t const * p_private_key,
+ nrf_crypto_ecc_public_key_t const * p_public_key,
+ uint8_t * p_shared_secret,
+ size_t * p_shared_secret_size);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+/** @}
+ * @}
+ */
+
+#endif // NRF_CRYPTO_ECDH_H__
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/nrf_crypto_ecdh_backend.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/nrf_crypto_ecdh_backend.h
new file mode 100644
index 0000000..3b6f692
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/nrf_crypto_ecdh_backend.h
@@ -0,0 +1,184 @@
+/**
+ * Copyright (c) 2018 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+
+#ifndef NRF_CRYPTO_ECDH_BACKEND_H__
+#define NRF_CRYPTO_ECDH_BACKEND_H__
+#if !defined(__SDK_DOXYGEN__)
+
+#include <stdint.h>
+#include <stddef.h>
+
+#include "sdk_errors.h"
+#include "sdk_config.h"
+#include "nrf_crypto_ecc.h"
+#include "nrf_crypto_ecdh_shared.h"
+
+// Include all backends
+#include "cc310_backend_ecdh.h"
+#include "cc310_bl_backend_ecdh.h"
+#include "mbedtls_backend_ecdh.h"
+#include "oberon_backend_ecdh.h"
+#include "micro_ecc_backend_ecdh.h"
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+#if !NRF_CRYPTO_ECC_SECP160R1_ENABLED
+// Dummy typedef for disabled context
+typedef uint32_t nrf_crypto_backend_secp160r1_ecdh_context_t;
+// Backend implementation is NULL to indicate feature not supported
+#define nrf_crypto_backend_secp160r1_ecdh_compute NULL
+#endif
+
+#if !NRF_CRYPTO_ECC_SECP160R2_ENABLED
+// Dummy typedef for disabled context
+typedef uint32_t nrf_crypto_backend_secp160r2_ecdh_context_t;
+// Backend implementation is NULL to indicate feature not supported
+#define nrf_crypto_backend_secp160r2_ecdh_compute NULL
+#endif
+
+#if !NRF_CRYPTO_ECC_SECP192R1_ENABLED
+// Dummy typedef for disabled context
+typedef uint32_t nrf_crypto_backend_secp192r1_ecdh_context_t;
+// Backend implementation is NULL to indicate feature not supported
+#define nrf_crypto_backend_secp192r1_ecdh_compute NULL
+#endif
+
+#if !NRF_CRYPTO_ECC_SECP224R1_ENABLED
+// Dummy typedef for disabled context
+typedef uint32_t nrf_crypto_backend_secp224r1_ecdh_context_t;
+// Backend implementation is NULL to indicate feature not supported
+#define nrf_crypto_backend_secp224r1_ecdh_compute NULL
+#endif
+
+#if !NRF_CRYPTO_ECC_SECP256R1_ENABLED
+// Dummy typedef for disabled context
+typedef uint32_t nrf_crypto_backend_secp256r1_ecdh_context_t;
+// Backend implementation is NULL to indicate feature not supported
+#define nrf_crypto_backend_secp256r1_ecdh_compute NULL
+#endif
+
+#if !NRF_CRYPTO_ECC_SECP384R1_ENABLED
+// Dummy typedef for disabled context
+typedef uint32_t nrf_crypto_backend_secp384r1_ecdh_context_t;
+// Backend implementation is NULL to indicate feature not supported
+#define nrf_crypto_backend_secp384r1_ecdh_compute NULL
+#endif
+
+#if !NRF_CRYPTO_ECC_SECP521R1_ENABLED
+// Dummy typedef for disabled context
+typedef uint32_t nrf_crypto_backend_secp521r1_ecdh_context_t;
+// Backend implementation is NULL to indicate feature not supported
+#define nrf_crypto_backend_secp521r1_ecdh_compute NULL
+#endif
+
+#if !NRF_CRYPTO_ECC_SECP160K1_ENABLED
+// Dummy typedef for disabled context
+typedef uint32_t nrf_crypto_backend_secp160k1_ecdh_context_t;
+// Backend implementation is NULL to indicate feature not supported
+#define nrf_crypto_backend_secp160k1_ecdh_compute NULL
+#endif
+
+#if !NRF_CRYPTO_ECC_SECP192K1_ENABLED
+// Dummy typedef for disabled context
+typedef uint32_t nrf_crypto_backend_secp192k1_ecdh_context_t;
+// Backend implementation is NULL to indicate feature not supported
+#define nrf_crypto_backend_secp192k1_ecdh_compute NULL
+#endif
+
+#if !NRF_CRYPTO_ECC_SECP224K1_ENABLED
+// Dummy typedef for disabled context
+typedef uint32_t nrf_crypto_backend_secp224k1_ecdh_context_t;
+// Backend implementation is NULL to indicate feature not supported
+#define nrf_crypto_backend_secp224k1_ecdh_compute NULL
+#endif
+
+#if !NRF_CRYPTO_ECC_SECP256K1_ENABLED
+// Dummy typedef for disabled context
+typedef uint32_t nrf_crypto_backend_secp256k1_ecdh_context_t;
+// Backend implementation is NULL to indicate feature not supported
+#define nrf_crypto_backend_secp256k1_ecdh_compute NULL
+#endif
+
+#if !NRF_CRYPTO_ECC_BP256R1_ENABLED
+// Dummy typedef for disabled context
+typedef uint32_t nrf_crypto_backend_bp256r1_ecdh_context_t;
+// Backend implementation is NULL to indicate feature not supported
+#define nrf_crypto_backend_bp256r1_ecdh_compute NULL
+#endif
+
+#if !NRF_CRYPTO_ECC_BP384R1_ENABLED
+// Dummy typedef for disabled context
+typedef uint32_t nrf_crypto_backend_bp384r1_ecdh_context_t;
+// Backend implementation is NULL to indicate feature not supported
+#define nrf_crypto_backend_bp384r1_ecdh_compute NULL
+#endif
+
+#if !NRF_CRYPTO_ECC_BP512R1_ENABLED
+// Dummy typedef for disabled context
+typedef uint32_t nrf_crypto_backend_bp512r1_ecdh_context_t;
+// Backend implementation is NULL to indicate feature not supported
+#define nrf_crypto_backend_bp512r1_ecdh_compute NULL
+#endif
+
+#if !NRF_CRYPTO_ECC_CURVE25519_ENABLED
+// Dummy typedef for disabled context
+typedef uint32_t nrf_crypto_backend_curve25519_ecdh_context_t;
+// Backend implementation is NULL to indicate feature not supported
+#define nrf_crypto_backend_curve25519_ecdh_compute NULL
+#endif
+
+#if !NRF_CRYPTO_ECC_ED25519_ENABLED
+// Dummy typedef for disabled context
+typedef uint32_t nrf_crypto_backend_ed25519_ecdh_context_t;
+// Backend implementation is NULL to indicate feature not supported
+#define nrf_crypto_backend_ed25519_ecdh_compute NULL
+#endif
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // !defined(__SDK_DOXYGEN__)
+#endif // NRF_CRYPTO_ECDH_BACKEND_H__
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/nrf_crypto_ecdh_shared.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/nrf_crypto_ecdh_shared.h
new file mode 100644
index 0000000..7d25cb1
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/nrf_crypto_ecdh_shared.h
@@ -0,0 +1,79 @@
+/**
+ * Copyright (c) 2018 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+
+#ifndef NRF_CRYPTO_ECDH_SHARED_H__
+#define NRF_CRYPTO_ECDH_SHARED_H__
+#if !defined(__SDK_DOXYGEN__)
+
+#include <stdint.h>
+#include <stddef.h>
+
+#include "sdk_errors.h"
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+/** @internal @brief Function pointer for backend implementation of ECDH.
+ *
+ * @note All parameters provided to the backend are vefified in frontend. Verification includes
+ * checking of NULL pointers, buffer size, initialization values. Front end also take full care of
+ * common ECC key hearder @ref nrf_crypto_internal_ecc_key_header_t.
+ *
+ * @param[in] p_context Pointer to context.
+ * @param[in] p_private_key Pointer to private key.
+ * @param[in] p_public_key Pointer to public key.
+ * @param[out] p_shared_secret Pointer where to put generated shared secret.
+ */
+typedef ret_code_t (*nrf_crypto_backend_ecdh_compute_fn_t)(
+ void * p_context,
+ void const * p_private_key,
+ void const * p_public_key,
+ uint8_t * p_shared_secret);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // !defined(__SDK_DOXYGEN__)
+#endif // NRF_CRYPTO_ECDH_SHARED_H__
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/nrf_crypto_ecdsa.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/nrf_crypto_ecdsa.c
new file mode 100644
index 0000000..6258cb2
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/nrf_crypto_ecdsa.c
@@ -0,0 +1,471 @@
+/**
+ * Copyright (c) 2018 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+
+#include "nrf_crypto_error.h"
+#include "nrf_crypto_ecc.h"
+#include "nrf_crypto_ecdsa.h"
+#include "nrf_crypto_mem.h"
+#include "app_util.h"
+#include "sdk_macros.h"
+
+
+#if NRF_CRYPTO_ECC_ENABLED
+
+
+#if NRF_CRYPTO_ECC_IMPLEMENTED_CURVES_COUNT > 1
+
+
+static const nrf_crypto_backend_ecdsa_sign_fn_t sign_impl[] =
+{
+#if NRF_CRYPTO_ECC_SECP160R1_ENABLED
+ nrf_crypto_backend_secp160r1_sign,
+#endif
+#if NRF_CRYPTO_ECC_SECP160R2_ENABLED
+ nrf_crypto_backend_secp160r2_sign,
+#endif
+#if NRF_CRYPTO_ECC_SECP192R1_ENABLED
+ nrf_crypto_backend_secp192r1_sign,
+#endif
+#if NRF_CRYPTO_ECC_SECP224R1_ENABLED
+ nrf_crypto_backend_secp224r1_sign,
+#endif
+#if NRF_CRYPTO_ECC_SECP256R1_ENABLED
+ nrf_crypto_backend_secp256r1_sign,
+#endif
+#if NRF_CRYPTO_ECC_SECP384R1_ENABLED
+ nrf_crypto_backend_secp384r1_sign,
+#endif
+#if NRF_CRYPTO_ECC_SECP521R1_ENABLED
+ nrf_crypto_backend_secp521r1_sign,
+#endif
+#if NRF_CRYPTO_ECC_SECP160K1_ENABLED
+ nrf_crypto_backend_secp160k1_sign,
+#endif
+#if NRF_CRYPTO_ECC_SECP192K1_ENABLED
+ nrf_crypto_backend_secp192k1_sign,
+#endif
+#if NRF_CRYPTO_ECC_SECP224K1_ENABLED
+ nrf_crypto_backend_secp224k1_sign,
+#endif
+#if NRF_CRYPTO_ECC_SECP256K1_ENABLED
+ nrf_crypto_backend_secp256k1_sign,
+#endif
+#if NRF_CRYPTO_ECC_BP256R1_ENABLED
+ nrf_crypto_backend_bp256r1_sign,
+#endif
+#if NRF_CRYPTO_ECC_BP384R1_ENABLED
+ nrf_crypto_backend_bp384r1_sign,
+#endif
+#if NRF_CRYPTO_ECC_BP512R1_ENABLED
+ nrf_crypto_backend_bp512r1_sign,
+#endif
+#if NRF_CRYPTO_ECC_CURVE25519_ENABLED
+ nrf_crypto_backend_curve25519_sign,
+#endif
+#if NRF_CRYPTO_ECC_ED25519_ENABLED
+ nrf_crypto_backend_ed25519_sign,
+#endif
+};
+
+static const uint16_t sign_impl_context_size[] =
+{
+#if NRF_CRYPTO_ECC_SECP160R1_ENABLED
+ NRF_CRYPTO_BACKEND_SECP160R1_SIGN_CONTEXT_SIZE,
+#endif
+#if NRF_CRYPTO_ECC_SECP160R2_ENABLED
+ NRF_CRYPTO_BACKEND_SECP160R2_SIGN_CONTEXT_SIZE,
+#endif
+#if NRF_CRYPTO_ECC_SECP192R1_ENABLED
+ NRF_CRYPTO_BACKEND_SECP192R1_SIGN_CONTEXT_SIZE,
+#endif
+#if NRF_CRYPTO_ECC_SECP224R1_ENABLED
+ NRF_CRYPTO_BACKEND_SECP224R1_SIGN_CONTEXT_SIZE,
+#endif
+#if NRF_CRYPTO_ECC_SECP256R1_ENABLED
+ NRF_CRYPTO_BACKEND_SECP256R1_SIGN_CONTEXT_SIZE,
+#endif
+#if NRF_CRYPTO_ECC_SECP384R1_ENABLED
+ NRF_CRYPTO_BACKEND_SECP384R1_SIGN_CONTEXT_SIZE,
+#endif
+#if NRF_CRYPTO_ECC_SECP521R1_ENABLED
+ NRF_CRYPTO_BACKEND_SECP521R1_SIGN_CONTEXT_SIZE,
+#endif
+#if NRF_CRYPTO_ECC_SECP160K1_ENABLED
+ NRF_CRYPTO_BACKEND_SECP160K1_SIGN_CONTEXT_SIZE,
+#endif
+#if NRF_CRYPTO_ECC_SECP192K1_ENABLED
+ NRF_CRYPTO_BACKEND_SECP192K1_SIGN_CONTEXT_SIZE,
+#endif
+#if NRF_CRYPTO_ECC_SECP224K1_ENABLED
+ NRF_CRYPTO_BACKEND_SECP224K1_SIGN_CONTEXT_SIZE,
+#endif
+#if NRF_CRYPTO_ECC_SECP256K1_ENABLED
+ NRF_CRYPTO_BACKEND_SECP256K1_SIGN_CONTEXT_SIZE,
+#endif
+#if NRF_CRYPTO_ECC_BP256R1_ENABLED
+ NRF_CRYPTO_BACKEND_BP256R1_SIGN_CONTEXT_SIZE,
+#endif
+#if NRF_CRYPTO_ECC_BP384R1_ENABLED
+ NRF_CRYPTO_BACKEND_BP384R1_SIGN_CONTEXT_SIZE,
+#endif
+#if NRF_CRYPTO_ECC_BP512R1_ENABLED
+ NRF_CRYPTO_BACKEND_BP512R1_SIGN_CONTEXT_SIZE,
+#endif
+#if NRF_CRYPTO_ECC_CURVE25519_ENABLED
+ NRF_CRYPTO_BACKEND_CURVE25519_SIGN_CONTEXT_SIZE,
+#endif
+#if NRF_CRYPTO_ECC_ED25519_ENABLED
+ NRF_CRYPTO_BACKEND_ED25519_SIGN_CONTEXT_SIZE,
+#endif
+};
+
+static const nrf_crypto_backend_ecdsa_verify_fn_t verify_impl[] =
+{
+#if NRF_CRYPTO_ECC_SECP160R1_ENABLED
+ nrf_crypto_backend_secp160r1_verify,
+#endif
+#if NRF_CRYPTO_ECC_SECP160R2_ENABLED
+ nrf_crypto_backend_secp160r2_verify,
+#endif
+#if NRF_CRYPTO_ECC_SECP192R1_ENABLED
+ nrf_crypto_backend_secp192r1_verify,
+#endif
+#if NRF_CRYPTO_ECC_SECP224R1_ENABLED
+ nrf_crypto_backend_secp224r1_verify,
+#endif
+#if NRF_CRYPTO_ECC_SECP256R1_ENABLED
+ nrf_crypto_backend_secp256r1_verify,
+#endif
+#if NRF_CRYPTO_ECC_SECP384R1_ENABLED
+ nrf_crypto_backend_secp384r1_verify,
+#endif
+#if NRF_CRYPTO_ECC_SECP521R1_ENABLED
+ nrf_crypto_backend_secp521r1_verify,
+#endif
+#if NRF_CRYPTO_ECC_SECP160K1_ENABLED
+ nrf_crypto_backend_secp160k1_verify,
+#endif
+#if NRF_CRYPTO_ECC_SECP192K1_ENABLED
+ nrf_crypto_backend_secp192k1_verify,
+#endif
+#if NRF_CRYPTO_ECC_SECP224K1_ENABLED
+ nrf_crypto_backend_secp224k1_verify,
+#endif
+#if NRF_CRYPTO_ECC_SECP256K1_ENABLED
+ nrf_crypto_backend_secp256k1_verify,
+#endif
+#if NRF_CRYPTO_ECC_BP256R1_ENABLED
+ nrf_crypto_backend_bp256r1_verify,
+#endif
+#if NRF_CRYPTO_ECC_BP384R1_ENABLED
+ nrf_crypto_backend_bp384r1_verify,
+#endif
+#if NRF_CRYPTO_ECC_BP512R1_ENABLED
+ nrf_crypto_backend_bp512r1_verify,
+#endif
+#if NRF_CRYPTO_ECC_CURVE25519_ENABLED
+ nrf_crypto_backend_curve25519_verify,
+#endif
+#if NRF_CRYPTO_ECC_ED25519_ENABLED
+ nrf_crypto_backend_ed25519_verify,
+#endif
+};
+
+static const uint16_t verify_impl_context_size[] =
+{
+#if NRF_CRYPTO_ECC_SECP160R1_ENABLED
+ NRF_CRYPTO_BACKEND_SECP160R1_VERIFY_CONTEXT_SIZE,
+#endif
+#if NRF_CRYPTO_ECC_SECP160R2_ENABLED
+ NRF_CRYPTO_BACKEND_SECP160R2_VERIFY_CONTEXT_SIZE,
+#endif
+#if NRF_CRYPTO_ECC_SECP192R1_ENABLED
+ NRF_CRYPTO_BACKEND_SECP192R1_VERIFY_CONTEXT_SIZE,
+#endif
+#if NRF_CRYPTO_ECC_SECP224R1_ENABLED
+ NRF_CRYPTO_BACKEND_SECP224R1_VERIFY_CONTEXT_SIZE,
+#endif
+#if NRF_CRYPTO_ECC_SECP256R1_ENABLED
+ NRF_CRYPTO_BACKEND_SECP256R1_VERIFY_CONTEXT_SIZE,
+#endif
+#if NRF_CRYPTO_ECC_SECP384R1_ENABLED
+ NRF_CRYPTO_BACKEND_SECP384R1_VERIFY_CONTEXT_SIZE,
+#endif
+#if NRF_CRYPTO_ECC_SECP521R1_ENABLED
+ NRF_CRYPTO_BACKEND_SECP521R1_VERIFY_CONTEXT_SIZE,
+#endif
+#if NRF_CRYPTO_ECC_SECP160K1_ENABLED
+ NRF_CRYPTO_BACKEND_SECP160K1_VERIFY_CONTEXT_SIZE,
+#endif
+#if NRF_CRYPTO_ECC_SECP192K1_ENABLED
+ NRF_CRYPTO_BACKEND_SECP192K1_VERIFY_CONTEXT_SIZE,
+#endif
+#if NRF_CRYPTO_ECC_SECP224K1_ENABLED
+ NRF_CRYPTO_BACKEND_SECP224K1_VERIFY_CONTEXT_SIZE,
+#endif
+#if NRF_CRYPTO_ECC_SECP256K1_ENABLED
+ NRF_CRYPTO_BACKEND_SECP256K1_VERIFY_CONTEXT_SIZE,
+#endif
+#if NRF_CRYPTO_ECC_BP256R1_ENABLED
+ NRF_CRYPTO_BACKEND_BP256R1_VERIFY_CONTEXT_SIZE,
+#endif
+#if NRF_CRYPTO_ECC_BP384R1_ENABLED
+ NRF_CRYPTO_BACKEND_BP384R1_VERIFY_CONTEXT_SIZE,
+#endif
+#if NRF_CRYPTO_ECC_BP512R1_ENABLED
+ NRF_CRYPTO_BACKEND_BP512R1_VERIFY_CONTEXT_SIZE,
+#endif
+#if NRF_CRYPTO_ECC_CURVE25519_ENABLED
+ NRF_CRYPTO_BACKEND_CURVE25519_VERIFY_CONTEXT_SIZE,
+#endif
+#if NRF_CRYPTO_ECC_ED25519_ENABLED
+ NRF_CRYPTO_BACKEND_ED25519_VERIFY_CONTEXT_SIZE,
+#endif
+};
+
+#define BACKEND_IMPL_GET(table, curve_type) (table)[(uint32_t)(curve_type)]
+
+#else
+
+#if NRF_CRYPTO_ECC_SECP160R1_ENABLED
+#define sign_impl nrf_crypto_backend_secp160r1_sign
+#define sign_impl_context_size NRF_CRYPTO_BACKEND_SECP160R1_SIGN_CONTEXT_SIZE
+#define verify_impl nrf_crypto_backend_secp160r1_verify
+#define verify_impl_context_size NRF_CRYPTO_BACKEND_SECP160R1_VERIFY_CONTEXT_SIZE
+#elif NRF_CRYPTO_ECC_SECP160R2_ENABLED
+#define sign_impl nrf_crypto_backend_secp160r2_sign
+#define sign_impl_context_size NRF_CRYPTO_BACKEND_SECP160R2_SIGN_CONTEXT_SIZE
+#define verify_impl nrf_crypto_backend_secp160r2_verify
+#define verify_impl_context_size NRF_CRYPTO_BACKEND_SECP160R2_VERIFY_CONTEXT_SIZE
+#elif NRF_CRYPTO_ECC_SECP192R1_ENABLED
+#define sign_impl nrf_crypto_backend_secp192r1_sign
+#define sign_impl_context_size NRF_CRYPTO_BACKEND_SECP192R1_SIGN_CONTEXT_SIZE
+#define verify_impl nrf_crypto_backend_secp192r1_verify
+#define verify_impl_context_size NRF_CRYPTO_BACKEND_SECP192R1_VERIFY_CONTEXT_SIZE
+#elif NRF_CRYPTO_ECC_SECP224R1_ENABLED
+#define sign_impl nrf_crypto_backend_secp224r1_sign
+#define sign_impl_context_size NRF_CRYPTO_BACKEND_SECP224R1_SIGN_CONTEXT_SIZE
+#define verify_impl nrf_crypto_backend_secp224r1_verify
+#define verify_impl_context_size NRF_CRYPTO_BACKEND_SECP224R1_VERIFY_CONTEXT_SIZE
+#elif NRF_CRYPTO_ECC_SECP256R1_ENABLED
+#define sign_impl nrf_crypto_backend_secp256r1_sign
+#define sign_impl_context_size NRF_CRYPTO_BACKEND_SECP256R1_SIGN_CONTEXT_SIZE
+#define verify_impl nrf_crypto_backend_secp256r1_verify
+#define verify_impl_context_size NRF_CRYPTO_BACKEND_SECP256R1_VERIFY_CONTEXT_SIZE
+#elif NRF_CRYPTO_ECC_SECP384R1_ENABLED
+#define sign_impl nrf_crypto_backend_secp384r1_sign
+#define sign_impl_context_size NRF_CRYPTO_BACKEND_SECP384R1_SIGN_CONTEXT_SIZE
+#define verify_impl nrf_crypto_backend_secp384r1_verify
+#define verify_impl_context_size NRF_CRYPTO_BACKEND_SECP384R1_VERIFY_CONTEXT_SIZE
+#elif NRF_CRYPTO_ECC_SECP521R1_ENABLED
+#define sign_impl nrf_crypto_backend_secp521r1_sign
+#define sign_impl_context_size NRF_CRYPTO_BACKEND_SECP521R1_SIGN_CONTEXT_SIZE
+#define verify_impl nrf_crypto_backend_secp521r1_verify
+#define verify_impl_context_size NRF_CRYPTO_BACKEND_SECP521R1_VERIFY_CONTEXT_SIZE
+#elif NRF_CRYPTO_ECC_SECP160K1_ENABLED
+#define sign_impl nrf_crypto_backend_secp160k1_sign
+#define sign_impl_context_size NRF_CRYPTO_BACKEND_SECP160K1_SIGN_CONTEXT_SIZE
+#define verify_impl nrf_crypto_backend_secp160k1_verify
+#define verify_impl_context_size NRF_CRYPTO_BACKEND_SECP160K1_VERIFY_CONTEXT_SIZE
+#elif NRF_CRYPTO_ECC_SECP192K1_ENABLED
+#define sign_impl nrf_crypto_backend_secp192k1_sign
+#define sign_impl_context_size NRF_CRYPTO_BACKEND_SECP192K1_SIGN_CONTEXT_SIZE
+#define verify_impl nrf_crypto_backend_secp192k1_verify
+#define verify_impl_context_size NRF_CRYPTO_BACKEND_SECP192K1_VERIFY_CONTEXT_SIZE
+#elif NRF_CRYPTO_ECC_SECP224K1_ENABLED
+#define sign_impl nrf_crypto_backend_secp224k1_sign
+#define sign_impl_context_size NRF_CRYPTO_BACKEND_SECP224K1_SIGN_CONTEXT_SIZE
+#define verify_impl nrf_crypto_backend_secp224k1_verify
+#define verify_impl_context_size NRF_CRYPTO_BACKEND_SECP224K1_VERIFY_CONTEXT_SIZE
+#elif NRF_CRYPTO_ECC_SECP256K1_ENABLED
+#define sign_impl nrf_crypto_backend_secp256k1_sign
+#define sign_impl_context_size NRF_CRYPTO_BACKEND_SECP256K1_SIGN_CONTEXT_SIZE
+#define verify_impl nrf_crypto_backend_secp256k1_verify
+#define verify_impl_context_size NRF_CRYPTO_BACKEND_SECP256K1_VERIFY_CONTEXT_SIZE
+#elif NRF_CRYPTO_ECC_BP256R1_ENABLED
+#define sign_impl nrf_crypto_backend_bp256r1_sign
+#define sign_impl_context_size NRF_CRYPTO_BACKEND_BP256R1_SIGN_CONTEXT_SIZE
+#define verify_impl nrf_crypto_backend_bp256r1_verify
+#define verify_impl_context_size NRF_CRYPTO_BACKEND_BP256R1_VERIFY_CONTEXT_SIZE
+#elif NRF_CRYPTO_ECC_BP384R1_ENABLED
+#define sign_impl nrf_crypto_backend_bp384r1_sign
+#define sign_impl_context_size NRF_CRYPTO_BACKEND_BP384R1_SIGN_CONTEXT_SIZE
+#define verify_impl nrf_crypto_backend_bp384r1_verify
+#define verify_impl_context_size NRF_CRYPTO_BACKEND_BP384R1_VERIFY_CONTEXT_SIZE
+#elif NRF_CRYPTO_ECC_BP512R1_ENABLED
+#define sign_impl nrf_crypto_backend_bp512r1_sign
+#define sign_impl_context_size NRF_CRYPTO_BACKEND_BP512R1_SIGN_CONTEXT_SIZE
+#define verify_impl nrf_crypto_backend_bp512r1_verify
+#define verify_impl_context_size NRF_CRYPTO_BACKEND_BP512R1_VERIFY_CONTEXT_SIZE
+#elif NRF_CRYPTO_ECC_CURVE25519_ENABLED
+#define sign_impl nrf_crypto_backend_curve25519_sign
+#define sign_impl_context_size NRF_CRYPTO_BACKEND_CURVE25519_SIGN_CONTEXT_SIZE
+#define verify_impl nrf_crypto_backend_curve25519_verify
+#define verify_impl_context_size NRF_CRYPTO_BACKEND_CURVE25519_VERIFY_CONTEXT_SIZE
+#elif NRF_CRYPTO_ECC_ED25519_ENABLED
+#define sign_impl nrf_crypto_backend_ed25519_sign
+#define sign_impl_context_size NRF_CRYPTO_BACKEND_ED25519_SIGN_CONTEXT_SIZE
+#define verify_impl nrf_crypto_backend_ed25519_verify
+#define verify_impl_context_size NRF_CRYPTO_BACKEND_ED25519_VERIFY_CONTEXT_SIZE
+#else
+#define sign_impl NULL
+#define sign_impl_context_size 0
+#define verify_impl NULL
+#define verify_impl_context_size 0
+#endif
+
+#define BACKEND_IMPL_GET(function, curve_type) (function)
+
+#endif
+
+
+ret_code_t nrf_crypto_ecdsa_sign(
+ nrf_crypto_ecdsa_sign_context_t * p_context,
+ nrf_crypto_ecc_private_key_t const * p_private_key,
+ uint8_t const * p_hash,
+ size_t hash_size,
+ uint8_t * p_signature,
+ size_t * p_signature_size)
+{
+ ret_code_t result;
+ void * p_allocated_context = NULL;
+ nrf_crypto_backend_ecdsa_sign_fn_t backend_implementation;
+ size_t context_size;
+ nrf_crypto_ecc_curve_info_t const * p_info;
+
+ // Get pointer to header
+ nrf_crypto_internal_ecc_key_header_t const * p_private_key_header =
+ (nrf_crypto_internal_ecc_key_header_t const *)p_private_key;
+
+ // Check and prepare parameters
+ VERIFY_TRUE(p_hash != NULL, NRF_ERROR_CRYPTO_INPUT_NULL);
+ result = nrf_crypto_internal_ecc_key_input_check(
+ p_private_key_header,
+ NRF_CRYPTO_INTERNAL_ECC_PRIVATE_KEY_INIT_VALUE);
+ VERIFY_SUCCESS(result);
+ p_info = p_private_key_header->p_info;
+ result = nrf_crypto_internal_ecc_raw_output_prepare(p_signature,
+ p_signature_size,
+ 2 * p_info->raw_private_key_size);
+ VERIFY_SUCCESS(result);
+
+ // Get backend specific information
+ backend_implementation = BACKEND_IMPL_GET(sign_impl, p_info->curve_type);
+ context_size = BACKEND_IMPL_GET(sign_impl_context_size, p_info->curve_type);
+ VERIFY_TRUE(backend_implementation != NULL, NRF_ERROR_CRYPTO_FEATURE_UNAVAILABLE);
+
+ // Allocate context if not provided
+ if (p_context == NULL && context_size > 0)
+ {
+ p_allocated_context = NRF_CRYPTO_ALLOC(context_size);
+ VERIFY_TRUE(p_allocated_context != NULL, NRF_ERROR_CRYPTO_ALLOC_FAILED);
+ p_context = p_allocated_context;
+ }
+
+ // Execute backend implementation
+ result = backend_implementation(p_context, p_private_key, p_hash, hash_size, p_signature);
+
+ // Deallocate context if allocated
+ if (p_allocated_context != NULL)
+ {
+ NRF_CRYPTO_FREE(p_allocated_context);
+ }
+
+ return result;
+}
+
+
+ret_code_t nrf_crypto_ecdsa_verify(
+ nrf_crypto_ecdsa_verify_context_t * p_context,
+ nrf_crypto_ecc_public_key_t const * p_public_key,
+ uint8_t const * p_hash,
+ size_t hash_size,
+ uint8_t const * p_signature,
+ size_t signature_size)
+{
+ ret_code_t result;
+ void * p_allocated_context = NULL;
+ nrf_crypto_backend_ecdsa_verify_fn_t backend_implementation;
+ size_t context_size;
+ nrf_crypto_ecc_curve_info_t const * p_info;
+
+ // Get pointer to header
+ nrf_crypto_internal_ecc_key_header_t const * p_public_key_header =
+ (nrf_crypto_internal_ecc_key_header_t const *)p_public_key;
+
+ // Check and prepare parameters
+ result = nrf_crypto_internal_ecc_key_input_check(
+ p_public_key_header,
+ NRF_CRYPTO_INTERNAL_ECC_PUBLIC_KEY_INIT_VALUE);
+ VERIFY_SUCCESS(result);
+ p_info = p_public_key_header->p_info;
+ result = nrf_crypto_internal_ecc_raw_input_check(p_signature,
+ signature_size,
+ 2 * p_info->raw_private_key_size);
+ VERIFY_SUCCESS(result);
+ VERIFY_TRUE(p_hash != NULL, NRF_ERROR_CRYPTO_INPUT_NULL);
+
+ // Get backend specific information
+ backend_implementation = BACKEND_IMPL_GET(verify_impl, p_info->curve_type);
+ context_size = BACKEND_IMPL_GET(verify_impl_context_size, p_info->curve_type);
+ VERIFY_TRUE(backend_implementation != NULL, NRF_ERROR_CRYPTO_FEATURE_UNAVAILABLE);
+
+ // Allocate context if not provided
+ if (p_context == NULL && context_size > 0)
+ {
+ p_allocated_context = NRF_CRYPTO_ALLOC(context_size);
+ VERIFY_TRUE(p_allocated_context != NULL, NRF_ERROR_CRYPTO_ALLOC_FAILED);
+ p_context = p_allocated_context;
+ }
+
+ // Execute backend implementation
+ result = backend_implementation(p_context, p_public_key, p_hash, hash_size, p_signature);
+
+ // Deallocate context if allocated
+ if (p_allocated_context != NULL)
+ {
+ NRF_CRYPTO_FREE(p_allocated_context);
+ }
+
+ return result;
+}
+
+
+#endif // NRF_CRYPTO_ECC_ENABLED
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/nrf_crypto_ecdsa.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/nrf_crypto_ecdsa.h
new file mode 100644
index 0000000..a7726a5
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/nrf_crypto_ecdsa.h
@@ -0,0 +1,252 @@
+/**
+ * Copyright (c) 2018 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+
+#ifndef NRF_CRYPTO_ECDSA_H__
+#define NRF_CRYPTO_ECDSA_H__
+
+/** @addtogroup nrf_crypto
+ * @{
+ * @addtogroup nrf_crypto_ecdsa Elliptic Curve Digital Signature (ECDSA)
+ * @{
+ * @brief Provides elliptic curve cryptography functions for digital signature.
+ *
+ * @addtogroup nrf_crypto_ecdsa_secp160r1 Definitions specific to secp160r1 (NIST 160-bit)
+ * @addtogroup nrf_crypto_ecdsa_secp160r2 Definitions specific to secp160r2 (NIST 160-bit)
+ * @addtogroup nrf_crypto_ecdsa_secp192r1 Definitions specific to secp192r1 (NIST 192-bit)
+ * @addtogroup nrf_crypto_ecdsa_secp224r1 Definitions specific to secp224r1 (NIST 224-bit)
+ * @addtogroup nrf_crypto_ecdsa_secp256r1 Definitions specific to secp256r1 (NIST 256-bit)
+ * @addtogroup nrf_crypto_ecdsa_secp384r1 Definitions specific to secp384r1 (NIST 384-bit)
+ * @addtogroup nrf_crypto_ecdsa_secp521r1 Definitions specific to secp521r1 (NIST 521-bit)
+ * @addtogroup nrf_crypto_ecdsa_secp160k1 Definitions specific to secp160k1 (Koblitz 160-bit)
+ * @addtogroup nrf_crypto_ecdsa_secp192k1 Definitions specific to secp192k1 (Koblitz 192-bit)
+ * @addtogroup nrf_crypto_ecdsa_secp224k1 Definitions specific to secp224k1 (Koblitz 224-bit)
+ * @addtogroup nrf_crypto_ecdsa_secp256k1 Definitions specific to secp256k1 (Koblitz 256-bit)
+ * @addtogroup nrf_crypto_ecdsa_bp256r1 Definitions specific to bp256r1 (Brainpool 256-bit)
+ * @addtogroup nrf_crypto_ecdsa_bp384r1 Definitions specific to bp384r1 (Brainpool 384-bit)
+ * @addtogroup nrf_crypto_ecdsa_bp512r1 Definitions specific to bp512r1 (Brainpool 512-bit)
+ * @addtogroup nrf_crypto_ecdsa_curve25519 Definitions specific to Curve25519
+ * @addtogroup nrf_crypto_ecdsa_ed25519 Definitions specific to Ed25519
+ */
+
+#include <stdint.h>
+#include <stddef.h>
+
+#include "nrf_crypto_error.h"
+#include "nrf_crypto_ecc.h"
+#include "nrf_crypto_ecdsa_shared.h"
+#include "nrf_crypto_ecdsa_backend.h"
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define NRF_CRYPTO_ECDSA_SECP160R1_SIGNATURE_SIZE (2 * 160 / 8) /**< @brief Size of a signature for secp160r1 (NIST 160-bit) curve. @ingroup nrf_crypto_ecdsa_secp160r1 */
+#define NRF_CRYPTO_ECDSA_SECP160R2_SIGNATURE_SIZE (2 * 160 / 8) /**< @brief Size of a signature for secp160r2 (NIST 160-bit) curve. @ingroup nrf_crypto_ecdsa_secp160r2 */
+#define NRF_CRYPTO_ECDSA_SECP192R1_SIGNATURE_SIZE (2 * 192 / 8) /**< @brief Size of a signature for secp192r1 (NIST 192-bit) curve. @ingroup nrf_crypto_ecdsa_secp192r1 */
+#define NRF_CRYPTO_ECDSA_SECP224R1_SIGNATURE_SIZE (2 * 224 / 8) /**< @brief Size of a signature for secp224r1 (NIST 224-bit) curve. @ingroup nrf_crypto_ecdsa_secp224r1 */
+#define NRF_CRYPTO_ECDSA_SECP256R1_SIGNATURE_SIZE (2 * 256 / 8) /**< @brief Size of a signature for secp256r1 (NIST 256-bit) curve. @ingroup nrf_crypto_ecdsa_secp256r1 */
+#define NRF_CRYPTO_ECDSA_SECP384R1_SIGNATURE_SIZE (2 * 384 / 8) /**< @brief Size of a signature for secp384r1 (NIST 384-bit) curve. @ingroup nrf_crypto_ecdsa_secp384r1 */
+#define NRF_CRYPTO_ECDSA_SECP521R1_SIGNATURE_SIZE (2 * 528 / 8) /**< @brief Size of a signature for secp521r1 (NIST 521-bit) curve. @ingroup nrf_crypto_ecdsa_secp521r1 */
+#define NRF_CRYPTO_ECDSA_SECP160K1_SIGNATURE_SIZE (2 * 160 / 8) /**< @brief Size of a signature for secp160k1 (Koblitz 160-bit) curve. @ingroup nrf_crypto_ecdsa_secp160k1 */
+#define NRF_CRYPTO_ECDSA_SECP192K1_SIGNATURE_SIZE (2 * 192 / 8) /**< @brief Size of a signature for secp192k1 (Koblitz 192-bit) curve. @ingroup nrf_crypto_ecdsa_secp192k1 */
+#define NRF_CRYPTO_ECDSA_SECP224K1_SIGNATURE_SIZE (2 * 224 / 8) /**< @brief Size of a signature for secp224k1 (Koblitz 224-bit) curve. @ingroup nrf_crypto_ecdsa_secp224k1 */
+#define NRF_CRYPTO_ECDSA_SECP256K1_SIGNATURE_SIZE (2 * 256 / 8) /**< @brief Size of a signature for secp256k1 (Koblitz 256-bit) curve. @ingroup nrf_crypto_ecdsa_secp256k1 */
+#define NRF_CRYPTO_ECDSA_BP256R1_SIGNATURE_SIZE (2 * 256 / 8) /**< @brief Size of a signature for bp256r1 (Brainpool 256-bit) curve. @ingroup nrf_crypto_ecdsa_bp256r1 */
+#define NRF_CRYPTO_ECDSA_BP384R1_SIGNATURE_SIZE (2 * 384 / 8) /**< @brief Size of a signature for bp384r1 (Brainpool 384-bit) curve. @ingroup nrf_crypto_ecdsa_bp384r1 */
+#define NRF_CRYPTO_ECDSA_BP512R1_SIGNATURE_SIZE (2 * 512 / 8) /**< @brief Size of a signature for bp512r1 (Brainpool 512-bit) curve. @ingroup nrf_crypto_ecdsa_bp512r1 */
+#define NRF_CRYPTO_ECDSA_CURVE25519_SIGNATURE_SIZE (2 * 256 / 8) /**< @brief Size of a signature for Curve25519 curve. @ingroup nrf_crypto_ecdsa_curve25519 */
+#define NRF_CRYPTO_ECDSA_ED25519_SIGNATURE_SIZE (2 * 256 / 8) /**< @brief Size of a signature for Ed25519 curve. @ingroup nrf_crypto_ecdsa_ed25519 */
+#define NRF_CRYPTO_ECDSA_SIGNATURE_MAX_SIZE (2 * NRF_CRYPTO_ECC_RAW_PRIVATE_KEY_MAX_SIZE) /**< @brief Maximum size of a signature for all enabled curves. */
+
+
+typedef uint8_t nrf_crypto_ecdsa_secp160r1_signature_t [NRF_CRYPTO_ECDSA_SECP160R1_SIGNATURE_SIZE]; /**< @brief Type to hold signature output for secp160r1 (NIST 160-bit) curve. @ingroup nrf_crypto_ecdsa_secp160r1 */
+typedef uint8_t nrf_crypto_ecdsa_secp160r2_signature_t [NRF_CRYPTO_ECDSA_SECP160R2_SIGNATURE_SIZE]; /**< @brief Type to hold signature output for secp160r2 (NIST 160-bit) curve. @ingroup nrf_crypto_ecdsa_secp160r2 */
+typedef uint8_t nrf_crypto_ecdsa_secp192r1_signature_t [NRF_CRYPTO_ECDSA_SECP192R1_SIGNATURE_SIZE]; /**< @brief Type to hold signature output for secp192r1 (NIST 192-bit) curve. @ingroup nrf_crypto_ecdsa_secp192r1 */
+typedef uint8_t nrf_crypto_ecdsa_secp224r1_signature_t [NRF_CRYPTO_ECDSA_SECP224R1_SIGNATURE_SIZE]; /**< @brief Type to hold signature output for secp224r1 (NIST 224-bit) curve. @ingroup nrf_crypto_ecdsa_secp224r1 */
+typedef uint8_t nrf_crypto_ecdsa_secp256r1_signature_t [NRF_CRYPTO_ECDSA_SECP256R1_SIGNATURE_SIZE]; /**< @brief Type to hold signature output for secp256r1 (NIST 256-bit) curve. @ingroup nrf_crypto_ecdsa_secp256r1 */
+typedef uint8_t nrf_crypto_ecdsa_secp384r1_signature_t [NRF_CRYPTO_ECDSA_SECP384R1_SIGNATURE_SIZE]; /**< @brief Type to hold signature output for secp384r1 (NIST 384-bit) curve. @ingroup nrf_crypto_ecdsa_secp384r1 */
+typedef uint8_t nrf_crypto_ecdsa_secp521r1_signature_t [NRF_CRYPTO_ECDSA_SECP521R1_SIGNATURE_SIZE]; /**< @brief Type to hold signature output for secp521r1 (NIST 521-bit) curve. @ingroup nrf_crypto_ecdsa_secp521r1 */
+typedef uint8_t nrf_crypto_ecdsa_secp160k1_signature_t [NRF_CRYPTO_ECDSA_SECP160K1_SIGNATURE_SIZE]; /**< @brief Type to hold signature output for secp160k1 (Koblitz 160-bit) curve. @ingroup nrf_crypto_ecdsa_secp160k1 */
+typedef uint8_t nrf_crypto_ecdsa_secp192k1_signature_t [NRF_CRYPTO_ECDSA_SECP192K1_SIGNATURE_SIZE]; /**< @brief Type to hold signature output for secp192k1 (Koblitz 192-bit) curve. @ingroup nrf_crypto_ecdsa_secp192k1 */
+typedef uint8_t nrf_crypto_ecdsa_secp224k1_signature_t [NRF_CRYPTO_ECDSA_SECP224K1_SIGNATURE_SIZE]; /**< @brief Type to hold signature output for secp224k1 (Koblitz 224-bit) curve. @ingroup nrf_crypto_ecdsa_secp224k1 */
+typedef uint8_t nrf_crypto_ecdsa_secp256k1_signature_t [NRF_CRYPTO_ECDSA_SECP256K1_SIGNATURE_SIZE]; /**< @brief Type to hold signature output for secp256k1 (Koblitz 256-bit) curve. @ingroup nrf_crypto_ecdsa_secp256k1 */
+typedef uint8_t nrf_crypto_ecdsa_bp256r1_signature_t [NRF_CRYPTO_ECDSA_BP256R1_SIGNATURE_SIZE]; /**< @brief Type to hold signature output for bp256r1 (Brainpool 256-bit) curve. @ingroup nrf_crypto_ecdsa_bp256r1 */
+typedef uint8_t nrf_crypto_ecdsa_bp384r1_signature_t [NRF_CRYPTO_ECDSA_BP384R1_SIGNATURE_SIZE]; /**< @brief Type to hold signature output for bp384r1 (Brainpool 384-bit) curve. @ingroup nrf_crypto_ecdsa_bp384r1 */
+typedef uint8_t nrf_crypto_ecdsa_bp512r1_signature_t [NRF_CRYPTO_ECDSA_BP512R1_SIGNATURE_SIZE]; /**< @brief Type to hold signature output for bp512r1 (Brainpool 512-bit) curve. @ingroup nrf_crypto_ecdsa_bp512r1 */
+typedef uint8_t nrf_crypto_ecdsa_curve25519_signature_t [NRF_CRYPTO_ECDSA_CURVE25519_SIGNATURE_SIZE]; /**< @brief Type to hold signature output for Curve25519 curve. @ingroup nrf_crypto_ecdsa_curve25519 */
+typedef uint8_t nrf_crypto_ecdsa_ed25519_signature_t [NRF_CRYPTO_ECDSA_ED25519_SIGNATURE_SIZE]; /**< @brief Type to hold signature output for Ed25519 curve. @ingroup nrf_crypto_ecdsa_ed25519 */
+typedef uint8_t nrf_crypto_ecdsa_signature_t [NRF_CRYPTO_ECDSA_SIGNATURE_MAX_SIZE]; /**< @brief Type big enough to hold signature output for any curve type. */
+
+
+typedef nrf_crypto_backend_secp160r1_sign_context_t nrf_crypto_ecdsa_secp160r1_sign_context_t; /**< @brief Context used to store temporary data during signing with curve secp160r1 (NIST 160-bit). @ingroup nrf_crypto_ecdsa_secp160r1 */
+typedef nrf_crypto_backend_secp160r2_sign_context_t nrf_crypto_ecdsa_secp160r2_sign_context_t; /**< @brief Context used to store temporary data during signing with curve secp160r2 (NIST 160-bit). @ingroup nrf_crypto_ecdsa_secp160r2 */
+typedef nrf_crypto_backend_secp192r1_sign_context_t nrf_crypto_ecdsa_secp192r1_sign_context_t; /**< @brief Context used to store temporary data during signing with curve secp192r1 (NIST 192-bit). @ingroup nrf_crypto_ecdsa_secp192r1 */
+typedef nrf_crypto_backend_secp224r1_sign_context_t nrf_crypto_ecdsa_secp224r1_sign_context_t; /**< @brief Context used to store temporary data during signing with curve secp224r1 (NIST 224-bit). @ingroup nrf_crypto_ecdsa_secp224r1 */
+typedef nrf_crypto_backend_secp256r1_sign_context_t nrf_crypto_ecdsa_secp256r1_sign_context_t; /**< @brief Context used to store temporary data during signing with curve secp256r1 (NIST 256-bit). @ingroup nrf_crypto_ecdsa_secp256r1 */
+typedef nrf_crypto_backend_secp384r1_sign_context_t nrf_crypto_ecdsa_secp384r1_sign_context_t; /**< @brief Context used to store temporary data during signing with curve secp384r1 (NIST 384-bit). @ingroup nrf_crypto_ecdsa_secp384r1 */
+typedef nrf_crypto_backend_secp521r1_sign_context_t nrf_crypto_ecdsa_secp521r1_sign_context_t; /**< @brief Context used to store temporary data during signing with curve secp521r1 (NIST 521-bit). @ingroup nrf_crypto_ecdsa_secp521r1 */
+typedef nrf_crypto_backend_secp160k1_sign_context_t nrf_crypto_ecdsa_secp160k1_sign_context_t; /**< @brief Context used to store temporary data during signing with curve secp160k1 (Koblitz 160-bit). @ingroup nrf_crypto_ecdsa_secp160k1 */
+typedef nrf_crypto_backend_secp192k1_sign_context_t nrf_crypto_ecdsa_secp192k1_sign_context_t; /**< @brief Context used to store temporary data during signing with curve secp192k1 (Koblitz 192-bit). @ingroup nrf_crypto_ecdsa_secp192k1 */
+typedef nrf_crypto_backend_secp224k1_sign_context_t nrf_crypto_ecdsa_secp224k1_sign_context_t; /**< @brief Context used to store temporary data during signing with curve secp224k1 (Koblitz 224-bit). @ingroup nrf_crypto_ecdsa_secp224k1 */
+typedef nrf_crypto_backend_secp256k1_sign_context_t nrf_crypto_ecdsa_secp256k1_sign_context_t; /**< @brief Context used to store temporary data during signing with curve secp256k1 (Koblitz 256-bit). @ingroup nrf_crypto_ecdsa_secp256k1 */
+typedef nrf_crypto_backend_bp256r1_sign_context_t nrf_crypto_ecdsa_bp256r1_sign_context_t; /**< @brief Context used to store temporary data during signing with curve bp256r1 (Brainpool 256-bit). @ingroup nrf_crypto_ecdsa_bp256r1 */
+typedef nrf_crypto_backend_bp384r1_sign_context_t nrf_crypto_ecdsa_bp384r1_sign_context_t; /**< @brief Context used to store temporary data during signing with curve bp384r1 (Brainpool 384-bit). @ingroup nrf_crypto_ecdsa_bp384r1 */
+typedef nrf_crypto_backend_bp512r1_sign_context_t nrf_crypto_ecdsa_bp512r1_sign_context_t; /**< @brief Context used to store temporary data during signing with curve bp512r1 (Brainpool 512-bit). @ingroup nrf_crypto_ecdsa_bp512r1 */
+typedef nrf_crypto_backend_curve25519_sign_context_t nrf_crypto_ecdsa_curve25519_sign_context_t; /**< @brief Context used to store temporary data during signing with curve Curve25519. @ingroup nrf_crypto_ecdsa_curve25519 */
+typedef nrf_crypto_backend_ed25519_sign_context_t nrf_crypto_ecdsa_ed25519_sign_context_t; /**< @brief Context used to store temporary data during signing with curve Ed25519. @ingroup nrf_crypto_ecdsa_ed25519 */
+
+
+typedef nrf_crypto_backend_secp160r1_verify_context_t nrf_crypto_ecdsa_secp160r1_verify_context_t; /**< @brief Context used to store temporary data during verifying with curve secp160r1 (NIST 160-bit). @ingroup nrf_crypto_ecdsa_secp160r1 */
+typedef nrf_crypto_backend_secp160r2_verify_context_t nrf_crypto_ecdsa_secp160r2_verify_context_t; /**< @brief Context used to store temporary data during verifying with curve secp160r2 (NIST 160-bit). @ingroup nrf_crypto_ecdsa_secp160r2 */
+typedef nrf_crypto_backend_secp192r1_verify_context_t nrf_crypto_ecdsa_secp192r1_verify_context_t; /**< @brief Context used to store temporary data during verifying with curve secp192r1 (NIST 192-bit). @ingroup nrf_crypto_ecdsa_secp192r1 */
+typedef nrf_crypto_backend_secp224r1_verify_context_t nrf_crypto_ecdsa_secp224r1_verify_context_t; /**< @brief Context used to store temporary data during verifying with curve secp224r1 (NIST 224-bit). @ingroup nrf_crypto_ecdsa_secp224r1 */
+typedef nrf_crypto_backend_secp256r1_verify_context_t nrf_crypto_ecdsa_secp256r1_verify_context_t; /**< @brief Context used to store temporary data during verifying with curve secp256r1 (NIST 256-bit). @ingroup nrf_crypto_ecdsa_secp256r1 */
+typedef nrf_crypto_backend_secp384r1_verify_context_t nrf_crypto_ecdsa_secp384r1_verify_context_t; /**< @brief Context used to store temporary data during verifying with curve secp384r1 (NIST 384-bit). @ingroup nrf_crypto_ecdsa_secp384r1 */
+typedef nrf_crypto_backend_secp521r1_verify_context_t nrf_crypto_ecdsa_secp521r1_verify_context_t; /**< @brief Context used to store temporary data during verifying with curve secp521r1 (NIST 521-bit). @ingroup nrf_crypto_ecdsa_secp521r1 */
+typedef nrf_crypto_backend_secp160k1_verify_context_t nrf_crypto_ecdsa_secp160k1_verify_context_t; /**< @brief Context used to store temporary data during verifying with curve secp160k1 (Koblitz 160-bit). @ingroup nrf_crypto_ecdsa_secp160k1 */
+typedef nrf_crypto_backend_secp192k1_verify_context_t nrf_crypto_ecdsa_secp192k1_verify_context_t; /**< @brief Context used to store temporary data during verifying with curve secp192k1 (Koblitz 192-bit). @ingroup nrf_crypto_ecdsa_secp192k1 */
+typedef nrf_crypto_backend_secp224k1_verify_context_t nrf_crypto_ecdsa_secp224k1_verify_context_t; /**< @brief Context used to store temporary data during verifying with curve secp224k1 (Koblitz 224-bit). @ingroup nrf_crypto_ecdsa_secp224k1 */
+typedef nrf_crypto_backend_secp256k1_verify_context_t nrf_crypto_ecdsa_secp256k1_verify_context_t; /**< @brief Context used to store temporary data during verifying with curve secp256k1 (Koblitz 256-bit). @ingroup nrf_crypto_ecdsa_secp256k1 */
+typedef nrf_crypto_backend_bp256r1_verify_context_t nrf_crypto_ecdsa_bp256r1_verify_context_t; /**< @brief Context used to store temporary data during verifying with curve bp256r1 (Brainpool 256-bit). @ingroup nrf_crypto_ecdsa_bp256r1 */
+typedef nrf_crypto_backend_bp384r1_verify_context_t nrf_crypto_ecdsa_bp384r1_verify_context_t; /**< @brief Context used to store temporary data during verifying with curve bp384r1 (Brainpool 384-bit). @ingroup nrf_crypto_ecdsa_bp384r1 */
+typedef nrf_crypto_backend_bp512r1_verify_context_t nrf_crypto_ecdsa_bp512r1_verify_context_t; /**< @brief Context used to store temporary data during verifying with curve bp512r1 (Brainpool 512-bit). @ingroup nrf_crypto_ecdsa_bp512r1 */
+typedef nrf_crypto_backend_curve25519_verify_context_t nrf_crypto_ecdsa_curve25519_verify_context_t; /**< @brief Context used to store temporary data during verifying with curve Curve25519. @ingroup nrf_crypto_ecdsa_curve25519 */
+typedef nrf_crypto_backend_ed25519_verify_context_t nrf_crypto_ecdsa_ed25519_verify_context_t; /**< @brief Context used to store temporary data during verifying with curve Ed25519. @ingroup nrf_crypto_ecdsa_ed25519 */
+
+
+/** @brief Union holding a context for ECDSA hash sign.
+ */
+typedef union
+{
+ nrf_crypto_ecdsa_secp160r1_sign_context_t context_secp160r1; /**< @brief Occupies space for secp160r1 (NIST 160-bit). */
+ nrf_crypto_ecdsa_secp160r2_sign_context_t context_secp160r2; /**< @brief Occupies space for secp160r2 (NIST 160-bit). */
+ nrf_crypto_ecdsa_secp192r1_sign_context_t context_secp192r1; /**< @brief Occupies space for secp192r1 (NIST 192-bit). */
+ nrf_crypto_ecdsa_secp224r1_sign_context_t context_secp224r1; /**< @brief Occupies space for secp224r1 (NIST 224-bit). */
+ nrf_crypto_ecdsa_secp256r1_sign_context_t context_secp256r1; /**< @brief Occupies space for secp256r1 (NIST 256-bit). */
+ nrf_crypto_ecdsa_secp384r1_sign_context_t context_secp384r1; /**< @brief Occupies space for secp384r1 (NIST 384-bit). */
+ nrf_crypto_ecdsa_secp521r1_sign_context_t context_secp521r1; /**< @brief Occupies space for secp521r1 (NIST 521-bit). */
+ nrf_crypto_ecdsa_secp160k1_sign_context_t context_secp160k1; /**< @brief Occupies space for secp160k1 (Koblitz 160-bit). */
+ nrf_crypto_ecdsa_secp192k1_sign_context_t context_secp192k1; /**< @brief Occupies space for secp192k1 (Koblitz 192-bit). */
+ nrf_crypto_ecdsa_secp224k1_sign_context_t context_secp224k1; /**< @brief Occupies space for secp224k1 (Koblitz 224-bit). */
+ nrf_crypto_ecdsa_secp256k1_sign_context_t context_secp256k1; /**< @brief Occupies space for secp256k1 (Koblitz 256-bit). */
+ nrf_crypto_ecdsa_bp256r1_sign_context_t context_bp256r1; /**< @brief Occupies space for bp256r1 (Brainpool 256-bit). */
+ nrf_crypto_ecdsa_bp384r1_sign_context_t context_bp384r1; /**< @brief Occupies space for bp384r1 (Brainpool 384-bit). */
+ nrf_crypto_ecdsa_bp512r1_sign_context_t context_bp512r1; /**< @brief Occupies space for bp512r1 (Brainpool 512-bit). */
+ nrf_crypto_ecdsa_curve25519_sign_context_t context_curve25519; /**< @brief Occupies space for Curve25519. */
+ nrf_crypto_ecdsa_ed25519_sign_context_t context_ed25519; /**< @brief Occupies space for Ed25519. */
+} nrf_crypto_ecdsa_sign_context_t;
+
+
+/** @brief Union holding a context for ECDSA hash verify.
+ */
+typedef union
+{
+ nrf_crypto_ecdsa_secp160r1_verify_context_t context_secp160r1; /**< @brief Occupies spece for secp160r1 (NIST 160-bit). */
+ nrf_crypto_ecdsa_secp160r2_verify_context_t context_secp160r2; /**< @brief Occupies spece for secp160r2 (NIST 160-bit). */
+ nrf_crypto_ecdsa_secp192r1_verify_context_t context_secp192r1; /**< @brief Occupies spece for secp192r1 (NIST 192-bit). */
+ nrf_crypto_ecdsa_secp224r1_verify_context_t context_secp224r1; /**< @brief Occupies spece for secp224r1 (NIST 224-bit). */
+ nrf_crypto_ecdsa_secp256r1_verify_context_t context_secp256r1; /**< @brief Occupies spece for secp256r1 (NIST 256-bit). */
+ nrf_crypto_ecdsa_secp384r1_verify_context_t context_secp384r1; /**< @brief Occupies spece for secp384r1 (NIST 384-bit). */
+ nrf_crypto_ecdsa_secp521r1_verify_context_t context_secp521r1; /**< @brief Occupies spece for secp521r1 (NIST 521-bit). */
+ nrf_crypto_ecdsa_secp160k1_verify_context_t context_secp160k1; /**< @brief Occupies spece for secp160k1 (Koblitz 160-bit). */
+ nrf_crypto_ecdsa_secp192k1_verify_context_t context_secp192k1; /**< @brief Occupies spece for secp192k1 (Koblitz 192-bit). */
+ nrf_crypto_ecdsa_secp224k1_verify_context_t context_secp224k1; /**< @brief Occupies spece for secp224k1 (Koblitz 224-bit). */
+ nrf_crypto_ecdsa_secp256k1_verify_context_t context_secp256k1; /**< @brief Occupies spece for secp256k1 (Koblitz 256-bit). */
+ nrf_crypto_ecdsa_bp256r1_verify_context_t context_bp256r1; /**< @brief Occupies spece for bp256r1 (Brainpool 256-bit). */
+ nrf_crypto_ecdsa_bp384r1_verify_context_t context_bp384r1; /**< @brief Occupies spece for bp384r1 (Brainpool 384-bit). */
+ nrf_crypto_ecdsa_bp512r1_verify_context_t context_bp512r1; /**< @brief Occupies spece for bp512r1 (Brainpool 512-bit). */
+ nrf_crypto_ecdsa_curve25519_verify_context_t context_curve25519; /**< @brief Occupies spece for Curve25519. */
+ nrf_crypto_ecdsa_ed25519_verify_context_t context_ed25519; /**< @brief Occupies spece for Ed25519. */
+} nrf_crypto_ecdsa_verify_context_t;
+
+
+/** @brief Sign a hash of a message.
+ *
+ * @param[in] p_context Pointer to temporary structure holding context information.
+ * If it is NULL, necessary data will be allocated with
+ * @ref NRF_CRYPTO_ALLOC and freed at the end of the function.
+ * @param[in] p_private_key Pointer to structure holding a private key.
+ * @param[in] p_hash Pointer to hash to sign.
+ * @param[in] hash_size Number of bytes in p_hash.
+ * @param[out] p_signature Pointer to buffer where digital signature will be put.
+ * @param[in,out] p_signature_size Maximum number of bytes that @p p_signature buffer can hold on input
+ * and the actual number of bytes used by the data on output.
+ * Actual size for selected curve is defined by
+ * the preprocessor definitions, e.g.
+ * @ref NRF_CRYPTO_ECDSA_SECP256R1_SIGNATURE_SIZE.
+ */
+ret_code_t nrf_crypto_ecdsa_sign(
+ nrf_crypto_ecdsa_sign_context_t * p_context,
+ nrf_crypto_ecc_private_key_t const * p_private_key,
+ uint8_t const * p_hash,
+ size_t hash_size,
+ uint8_t * p_signature,
+ size_t * p_signature_size);
+
+
+/** @brief Verify a signature using a hash of a message.
+ *
+ * @param[in] p_context Pointer to temporary structure holding context information.
+ * If it is NULL, necessary data will be allocated with
+ * @ref NRF_CRYPTO_ALLOC and freed at the end of the function.
+ * @param[in] p_public_key Pointer to structure holding a public key.
+ * @param[in] p_hash Pointer to hash to verify.
+ * @param[in] hash_size Number of bytes in p_hash.
+ * @param[in] p_signature Pointer to buffer containing digital signature.
+ * @param[in,out] signature_size Number of bytes in p_signature.
+ */
+ret_code_t nrf_crypto_ecdsa_verify(
+ nrf_crypto_ecdsa_verify_context_t * p_context,
+ nrf_crypto_ecc_public_key_t const * p_public_key,
+ uint8_t const * p_hash,
+ size_t hash_size,
+ uint8_t const * p_signature,
+ size_t signature_size);
+
+#ifdef __cplusplus
+}
+#endif
+
+/** @}
+ * @}
+ */
+
+#endif // NRF_CRYPTO_ECDSA_H__
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/nrf_crypto_ecdsa_backend.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/nrf_crypto_ecdsa_backend.h
new file mode 100644
index 0000000..78bd2a0
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/nrf_crypto_ecdsa_backend.h
@@ -0,0 +1,262 @@
+/**
+ * Copyright (c) 2018 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+
+#ifndef NRF_CRYPTO_ECDSA_BACKEND_H__
+#define NRF_CRYPTO_ECDSA_BACKEND_H__
+#if !defined(__SDK_DOXYGEN__)
+
+#include <stdint.h>
+#include <stddef.h>
+
+#include "sdk_config.h"
+#include "nrf_crypto_ecdsa_shared.h"
+
+// Include all backends
+#include "cc310_backend_ecdsa.h"
+#include "cc310_bl_backend_ecdsa.h"
+#include "mbedtls_backend_ecdsa.h"
+#include "oberon_backend_ecdsa.h"
+#include "micro_ecc_backend_ecdsa.h"
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+#if !NRF_CRYPTO_ECC_SECP160R1_ENABLED
+// Context sizes are zero for disabled functionality
+#define NRF_CRYPTO_BACKEND_SECP160R1_SIGN_CONTEXT_SIZE 0
+#define NRF_CRYPTO_BACKEND_SECP160R1_VERIFY_CONTEXT_SIZE 0
+// Dummy typedefs for disabled contexts
+typedef uint8_t nrf_crypto_backend_secp160r1_sign_context_t;
+typedef uint8_t nrf_crypto_backend_secp160r1_verify_context_t;
+// Backend implementation is NULL to indicate feature not supported
+#define nrf_crypto_backend_secp160r1_sign NULL
+#define nrf_crypto_backend_secp160r1_verify NULL
+#endif
+
+#if !NRF_CRYPTO_ECC_SECP160R2_ENABLED
+// Context sizes are zero for disabled functionality
+#define NRF_CRYPTO_BACKEND_SECP160R2_SIGN_CONTEXT_SIZE 0
+#define NRF_CRYPTO_BACKEND_SECP160R2_VERIFY_CONTEXT_SIZE 0
+// Dummy typedefs for disabled contexts
+typedef uint8_t nrf_crypto_backend_secp160r2_sign_context_t;
+typedef uint8_t nrf_crypto_backend_secp160r2_verify_context_t;
+// Backend implementation is NULL to indicate feature not supported
+#define nrf_crypto_backend_secp160r2_sign NULL
+#define nrf_crypto_backend_secp160r2_verify NULL
+#endif
+
+#if !NRF_CRYPTO_ECC_SECP192R1_ENABLED
+// Context sizes are zero for disabled functionality
+#define NRF_CRYPTO_BACKEND_SECP192R1_SIGN_CONTEXT_SIZE 0
+#define NRF_CRYPTO_BACKEND_SECP192R1_VERIFY_CONTEXT_SIZE 0
+// Dummy typedefs for disabled contexts
+typedef uint8_t nrf_crypto_backend_secp192r1_sign_context_t;
+typedef uint8_t nrf_crypto_backend_secp192r1_verify_context_t;
+// Backend implementation is NULL to indicate feature not supported
+#define nrf_crypto_backend_secp192r1_sign NULL
+#define nrf_crypto_backend_secp192r1_verify NULL
+#endif
+
+#if !NRF_CRYPTO_ECC_SECP224R1_ENABLED
+// Context sizes are zero for disabled functionality
+#define NRF_CRYPTO_BACKEND_SECP224R1_SIGN_CONTEXT_SIZE 0
+#define NRF_CRYPTO_BACKEND_SECP224R1_VERIFY_CONTEXT_SIZE 0
+// Dummy typedefs for disabled contexts
+typedef uint8_t nrf_crypto_backend_secp224r1_sign_context_t;
+typedef uint8_t nrf_crypto_backend_secp224r1_verify_context_t;
+// Backend implementation is NULL to indicate feature not supported
+#define nrf_crypto_backend_secp224r1_sign NULL
+#define nrf_crypto_backend_secp224r1_verify NULL
+#endif
+
+#if !NRF_CRYPTO_ECC_SECP256R1_ENABLED
+// Context sizes are zero for disabled functionality
+#define NRF_CRYPTO_BACKEND_SECP256R1_SIGN_CONTEXT_SIZE 0
+#define NRF_CRYPTO_BACKEND_SECP256R1_VERIFY_CONTEXT_SIZE 0
+// Dummy typedefs for disabled contexts
+typedef uint8_t nrf_crypto_backend_secp256r1_sign_context_t;
+typedef uint8_t nrf_crypto_backend_secp256r1_verify_context_t;
+// Backend implementation is NULL to indicate feature not supported
+#define nrf_crypto_backend_secp256r1_sign NULL
+#define nrf_crypto_backend_secp256r1_verify NULL
+#endif
+
+#if !NRF_CRYPTO_ECC_SECP384R1_ENABLED
+// Context sizes are zero for disabled functionality
+#define NRF_CRYPTO_BACKEND_SECP384R1_SIGN_CONTEXT_SIZE 0
+#define NRF_CRYPTO_BACKEND_SECP384R1_VERIFY_CONTEXT_SIZE 0
+// Dummy typedefs for disabled contexts
+typedef uint8_t nrf_crypto_backend_secp384r1_sign_context_t;
+typedef uint8_t nrf_crypto_backend_secp384r1_verify_context_t;
+// Backend implementation is NULL to indicate feature not supported
+#define nrf_crypto_backend_secp384r1_sign NULL
+#define nrf_crypto_backend_secp384r1_verify NULL
+#endif
+
+#if !NRF_CRYPTO_ECC_SECP521R1_ENABLED
+// Context sizes are zero for disabled functionality
+#define NRF_CRYPTO_BACKEND_SECP521R1_SIGN_CONTEXT_SIZE 0
+#define NRF_CRYPTO_BACKEND_SECP521R1_VERIFY_CONTEXT_SIZE 0
+// Dummy typedefs for disabled contexts
+typedef uint8_t nrf_crypto_backend_secp521r1_sign_context_t;
+typedef uint8_t nrf_crypto_backend_secp521r1_verify_context_t;
+// Backend implementation is NULL to indicate feature not supported
+#define nrf_crypto_backend_secp521r1_sign NULL
+#define nrf_crypto_backend_secp521r1_verify NULL
+#endif
+
+#if !NRF_CRYPTO_ECC_SECP160K1_ENABLED
+// Context sizes are zero for disabled functionality
+#define NRF_CRYPTO_BACKEND_SECP160K1_SIGN_CONTEXT_SIZE 0
+#define NRF_CRYPTO_BACKEND_SECP160K1_VERIFY_CONTEXT_SIZE 0
+// Dummy typedefs for disabled contexts
+typedef uint8_t nrf_crypto_backend_secp160k1_sign_context_t;
+typedef uint8_t nrf_crypto_backend_secp160k1_verify_context_t;
+// Backend implementation is NULL to indicate feature not supported
+#define nrf_crypto_backend_secp160k1_sign NULL
+#define nrf_crypto_backend_secp160k1_verify NULL
+#endif
+
+#if !NRF_CRYPTO_ECC_SECP192K1_ENABLED
+// Context sizes are zero for disabled functionality
+#define NRF_CRYPTO_BACKEND_SECP192K1_SIGN_CONTEXT_SIZE 0
+#define NRF_CRYPTO_BACKEND_SECP192K1_VERIFY_CONTEXT_SIZE 0
+// Dummy typedefs for disabled contexts
+typedef uint8_t nrf_crypto_backend_secp192k1_sign_context_t;
+typedef uint8_t nrf_crypto_backend_secp192k1_verify_context_t;
+// Backend implementation is NULL to indicate feature not supported
+#define nrf_crypto_backend_secp192k1_sign NULL
+#define nrf_crypto_backend_secp192k1_verify NULL
+#endif
+
+#if !NRF_CRYPTO_ECC_SECP224K1_ENABLED
+// Context sizes are zero for disabled functionality
+#define NRF_CRYPTO_BACKEND_SECP224K1_SIGN_CONTEXT_SIZE 0
+#define NRF_CRYPTO_BACKEND_SECP224K1_VERIFY_CONTEXT_SIZE 0
+// Dummy typedefs for disabled contexts
+typedef uint8_t nrf_crypto_backend_secp224k1_sign_context_t;
+typedef uint8_t nrf_crypto_backend_secp224k1_verify_context_t;
+// Backend implementation is NULL to indicate feature not supported
+#define nrf_crypto_backend_secp224k1_sign NULL
+#define nrf_crypto_backend_secp224k1_verify NULL
+#endif
+
+#if !NRF_CRYPTO_ECC_SECP256K1_ENABLED
+// Context sizes are zero for disabled functionality
+#define NRF_CRYPTO_BACKEND_SECP256K1_SIGN_CONTEXT_SIZE 0
+#define NRF_CRYPTO_BACKEND_SECP256K1_VERIFY_CONTEXT_SIZE 0
+// Dummy typedefs for disabled contexts
+typedef uint8_t nrf_crypto_backend_secp256k1_sign_context_t;
+typedef uint8_t nrf_crypto_backend_secp256k1_verify_context_t;
+// Backend implementation is NULL to indicate feature not supported
+#define nrf_crypto_backend_secp256k1_sign NULL
+#define nrf_crypto_backend_secp256k1_verify NULL
+#endif
+
+#if !NRF_CRYPTO_ECC_BP256R1_ENABLED
+// Context sizes are zero for disabled functionality
+#define NRF_CRYPTO_BACKEND_BP256R1_SIGN_CONTEXT_SIZE 0
+#define NRF_CRYPTO_BACKEND_BP256R1_VERIFY_CONTEXT_SIZE 0
+// Dummy typedefs for disabled contexts
+typedef uint8_t nrf_crypto_backend_bp256r1_sign_context_t;
+typedef uint8_t nrf_crypto_backend_bp256r1_verify_context_t;
+// Backend implementation is NULL to indicate feature not supported
+#define nrf_crypto_backend_bp256r1_sign NULL
+#define nrf_crypto_backend_bp256r1_verify NULL
+#endif
+
+#if !NRF_CRYPTO_ECC_BP384R1_ENABLED
+// Context sizes are zero for disabled functionality
+#define NRF_CRYPTO_BACKEND_BP384R1_SIGN_CONTEXT_SIZE 0
+#define NRF_CRYPTO_BACKEND_BP384R1_VERIFY_CONTEXT_SIZE 0
+// Dummy typedefs for disabled contexts
+typedef uint8_t nrf_crypto_backend_bp384r1_sign_context_t;
+typedef uint8_t nrf_crypto_backend_bp384r1_verify_context_t;
+// Backend implementation is NULL to indicate feature not supported
+#define nrf_crypto_backend_bp384r1_sign NULL
+#define nrf_crypto_backend_bp384r1_verify NULL
+#endif
+
+#if !NRF_CRYPTO_ECC_BP512R1_ENABLED
+// Context sizes are zero for disabled functionality
+#define NRF_CRYPTO_BACKEND_BP512R1_SIGN_CONTEXT_SIZE 0
+#define NRF_CRYPTO_BACKEND_BP512R1_VERIFY_CONTEXT_SIZE 0
+// Dummy typedefs for disabled contexts
+typedef uint8_t nrf_crypto_backend_bp512r1_sign_context_t;
+typedef uint8_t nrf_crypto_backend_bp512r1_verify_context_t;
+// Backend implementation is NULL to indicate feature not supported
+#define nrf_crypto_backend_bp512r1_sign NULL
+#define nrf_crypto_backend_bp512r1_verify NULL
+#endif
+
+#if !NRF_CRYPTO_ECC_CURVE25519_ENABLED
+// Context sizes are zero for disabled functionality
+#define NRF_CRYPTO_BACKEND_CURVE25519_SIGN_CONTEXT_SIZE 0
+#define NRF_CRYPTO_BACKEND_CURVE25519_VERIFY_CONTEXT_SIZE 0
+// Dummy typedefs for disabled contexts
+typedef uint8_t nrf_crypto_backend_curve25519_sign_context_t;
+typedef uint8_t nrf_crypto_backend_curve25519_verify_context_t;
+// Backend implementation is NULL to indicate feature not supported
+#define nrf_crypto_backend_curve25519_sign NULL
+#define nrf_crypto_backend_curve25519_verify NULL
+#endif
+
+#if !NRF_CRYPTO_ECC_ED25519_ENABLED
+// Context sizes are zero for disabled functionality
+#define NRF_CRYPTO_BACKEND_ED25519_SIGN_CONTEXT_SIZE 0
+#define NRF_CRYPTO_BACKEND_ED25519_VERIFY_CONTEXT_SIZE 0
+// Dummy typedefs for disabled contexts
+typedef uint8_t nrf_crypto_backend_ed25519_sign_context_t;
+typedef uint8_t nrf_crypto_backend_ed25519_verify_context_t;
+// Backend implementation is NULL to indicate feature not supported
+#define nrf_crypto_backend_ed25519_sign NULL
+#define nrf_crypto_backend_ed25519_verify NULL
+#endif
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // !defined(__SDK_DOXYGEN__)
+#endif // NRF_CRYPTO_ECDSA_BACKEND_H__
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/nrf_crypto_ecdsa_shared.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/nrf_crypto_ecdsa_shared.h
new file mode 100644
index 0000000..70d81ac
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/nrf_crypto_ecdsa_shared.h
@@ -0,0 +1,103 @@
+/**
+ * Copyright (c) 2018 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+
+#ifndef NRF_CRYPTO_ECDSA_SHARED_H__
+#define NRF_CRYPTO_ECDSA_SHARED_H__
+
+#include <stdint.h>
+
+#include "nordic_common.h"
+#include "nrf_crypto_ecc.h"
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+/** @internal @brief Function pointer for backend implementation of ECDSA sign.
+ *
+ * @note All parameters provided to the backend are vefified in frontend. Verification includes
+ * checking of NULL pointers, buffer size, initialization values. Front end also take full care of
+ * common ECC key hearder @ref nrf_crypto_internal_ecc_key_header_t.
+ *
+ * @param[in] p_context Pointer to context.
+ * @param[in] p_private_key Pointer to private key.
+ * @param[in] p_data Pointer to data to sign. Data can be a message or a hash. It depends
+ * on which version of signing functions is pointed by this function
+ * pointer.
+ * @param[in] data_size Size of @p p_data.
+ * @param[out] p_signature Pointer where to put generated signature.
+ */
+typedef ret_code_t (*nrf_crypto_backend_ecdsa_sign_fn_t)(
+ void * p_context,
+ void const * p_private_key,
+ uint8_t const * p_data,
+ size_t data_size,
+ uint8_t * p_signature);
+
+
+/** @internal @brief Function pointer for backend implementation of ECDSA verify.
+ *
+ * @note All parameters provided to the backend are vefified in frontend. Verification includes
+ * checking of NULL pointers, buffer size, initialization values. Front end also take full care of
+ * common ECC key hearder @ref nrf_crypto_internal_ecc_key_header_t.
+ *
+ * @param[in] p_context Pointer to context.
+ * @param[in] p_public_key Pointer to public key.
+ * @param[in] p_data Pointer to data to verify. Data can be a message or a hash. It depends
+ * on which version of signing functions is pointed by this function
+ * pointer.
+ * @param[in] data_size Size of @p p_data.
+ * @param[in] p_signature Pointer to signature to verify.
+ */
+typedef ret_code_t (*nrf_crypto_backend_ecdsa_verify_fn_t)(
+ void * p_context,
+ void const * p_public_key,
+ uint8_t const * p_data,
+ size_t data_size,
+ uint8_t const * p_signature);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // NRF_CRYPTO_ECDSA_SHARED_H__
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/nrf_crypto_error.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/nrf_crypto_error.c
new file mode 100644
index 0000000..9a37b01
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/nrf_crypto_error.c
@@ -0,0 +1,102 @@
+/**
+ * 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+
+#include "sdk_common.h"
+#if NRF_MODULE_ENABLED(NRF_CRYPTO)
+
+#include "nordic_common.h"
+#include "nrf_crypto_error.h"
+
+typedef struct
+{
+ ret_code_t error;
+ const char * p_text;
+} error_code_pair;
+
+static const error_code_pair m_crypto_error[] =
+{
+ { NRF_ERROR_CRYPTO_NOT_INITIALIZED, "nrf_crypto_init was not called prior to this crypto function" },
+ { NRF_ERROR_CRYPTO_CONTEXT_NULL, "A null pointer was provided for the context structure" },
+ { NRF_ERROR_CRYPTO_CONTEXT_NOT_INITIALIZED, "The context was not initialized prior to this call or it was corrupted. Please call the corresponding init function for the algorithm to initialize it" },
+ { NRF_ERROR_CRYPTO_FEATURE_UNAVAILABLE, "The function was called with a feature that is unavailable" },
+ { NRF_ERROR_CRYPTO_BUSY, "The function could not be called because the crypto backend was busy. Please rerun the cryptographic routine at a later time" },
+ { NRF_ERROR_CRYPTO_INPUT_NULL, "One or more of the input arguments for this function was NULL" },
+ { NRF_ERROR_CRYPTO_INPUT_LENGTH, "The length of one or more of the input arguments was invalid" },
+ { NRF_ERROR_CRYPTO_INPUT_LOCATION, "Input data not in RAM" },
+ { NRF_ERROR_CRYPTO_OUTPUT_NULL, "One or more of the output arguments for this function was NULL" },
+ { NRF_ERROR_CRYPTO_OUTPUT_LENGTH, "The length of the one or more output arguments was too small" },
+ { NRF_ERROR_CRYPTO_ALLOC_FAILED, "A required memory allocation failed" },
+ { NRF_ERROR_CRYPTO_INTERNAL, "An internal error occurred when calling this function" },
+ { NRF_ERROR_CRYPTO_INVALID_PARAM, "Invalid combination of input parameters" },
+ { NRF_ERROR_CRYPTO_KEY_SIZE, "Size of the key is not supported by choosen backend" },
+ { NRF_ERROR_CRYPTO_STACK_OVERFLOW, "Stack overflow detected" },
+ { NRF_ERROR_CRYPTO_ECC_KEY_NOT_INITIALIZED, "ECC key was not initialized" },
+ { NRF_ERROR_CRYPTO_ECDH_CURVE_MISMATCH, "Public and private key provided to ECDH have different types of curves" },
+ { NRF_ERROR_CRYPTO_ECDSA_INVALID_SIGNATURE, "Signature verification check reported invalid signature" },
+ { NRF_ERROR_CRYPTO_ECC_INVALID_KEY, "Provided key is invalid" },
+ { NRF_ERROR_CRYPTO_AES_INVALID_PADDING, "Message padding is corrupted." },
+ { NRF_ERROR_CRYPTO_AEAD_INVALID_MAC, "MAC not matching encrypted text" },
+ { NRF_ERROR_CRYPTO_AEAD_NONCE_SIZE, "Size of the nonce is not supported in this AEAD mode" },
+ { NRF_ERROR_CRYPTO_AEAD_MAC_SIZE, "Size of the MAC (tag) is not supported in this AEAD mode" },
+ { NRF_ERROR_CRYPTO_RNG_INIT_FAILED, "Initialization or startup of RNG failed" },
+ { NRF_ERROR_CRYPTO_RNG_RESEED_REQUIRED, "Reseed required (reseed counter overflowed)" },
+};
+
+char const * nrf_crypto_error_string_get(ret_code_t error)
+{
+ if (error == NRF_SUCCESS)
+ {
+ return "No error";
+ }
+ else
+ {
+ uint32_t i;
+ for (i = 0; i < ARRAY_SIZE(m_crypto_error); i++)
+ {
+ if (m_crypto_error[i].error == error)
+ {
+ return m_crypto_error[i].p_text;
+ }
+ }
+ }
+ return "Error not related to nrf_crypto library";
+}
+
+#endif // NRF_MODULE_ENABLED(NRF_CRYPTO)
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/nrf_crypto_error.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/nrf_crypto_error.h
new file mode 100644
index 0000000..970f5fb
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/nrf_crypto_error.h
@@ -0,0 +1,113 @@
+/**
+ * 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+
+#ifndef NRF_CRYPTO_ERROR_H__
+#define NRF_CRYPTO_ERROR_H__
+
+/**@file
+ *
+ * @defgroup nrf_crypto_error nrf_crypto error codes
+ * @{
+ * @ingroup nrf_crypto
+ *
+ * @details This is the standardized error codes provided when calling nrf_crypto APIs.
+ * The error codes provided here are enumerated based on @ref NRF_ERROR_CRYPTO_ERR_BASE.
+ *
+ * @note Success code, NRF_SUCCESS, is used if the nrf_crypto operation was successful.
+ *
+ */
+
+#include "sdk_errors.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define NRF_ERROR_CRYPTO_NOT_INITIALIZED (NRF_ERROR_CRYPTO_ERR_BASE + 0x00) /**< @ref nrf_crypto_init was not called prior to this crypto function. */
+#define NRF_ERROR_CRYPTO_CONTEXT_NULL (NRF_ERROR_CRYPTO_ERR_BASE + 0x01) /**< A null pointer was provided for the context structure. */
+#define NRF_ERROR_CRYPTO_CONTEXT_NOT_INITIALIZED (NRF_ERROR_CRYPTO_ERR_BASE + 0x02) /**< The context was not initialized prior to this call or it was corrupted. Call the corresponding init function for the algorithm to initialize it. */
+#define NRF_ERROR_CRYPTO_FEATURE_UNAVAILABLE (NRF_ERROR_CRYPTO_ERR_BASE + 0x03) /**< The function was called with a feature that is unavailable. */
+#define NRF_ERROR_CRYPTO_BUSY (NRF_ERROR_CRYPTO_ERR_BASE + 0x04) /**< The function could not be called because the crypto backend was busy. Rerun the cryptographic routine at a later time. */
+
+#define NRF_ERROR_CRYPTO_INPUT_NULL (NRF_ERROR_CRYPTO_ERR_BASE + 0x10) /**< One or more of the input arguments for this function were NULL. */
+#define NRF_ERROR_CRYPTO_INPUT_LENGTH (NRF_ERROR_CRYPTO_ERR_BASE + 0x11) /**< The length of one or more of the input arguments was invalid. */
+#define NRF_ERROR_CRYPTO_INPUT_LOCATION (NRF_ERROR_CRYPTO_ERR_BASE + 0x12) /**< Input data not in RAM. */
+#define NRF_ERROR_CRYPTO_OUTPUT_NULL (NRF_ERROR_CRYPTO_ERR_BASE + 0x13) /**< One or more of the output arguments for this function were NULL. */
+#define NRF_ERROR_CRYPTO_OUTPUT_LENGTH (NRF_ERROR_CRYPTO_ERR_BASE + 0x14) /**< The length of one or more output arguments was too small. */
+#define NRF_ERROR_CRYPTO_ALLOC_FAILED (NRF_ERROR_CRYPTO_ERR_BASE + 0x15) /**< A required memory allocation failed. */
+#define NRF_ERROR_CRYPTO_INTERNAL (NRF_ERROR_CRYPTO_ERR_BASE + 0x16) /**< An internal error occurred when calling this function. */
+#define NRF_ERROR_CRYPTO_INVALID_PARAM (NRF_ERROR_CRYPTO_ERR_BASE + 0x17) /**< Invalid combination of input parameters. */
+#define NRF_ERROR_CRYPTO_KEY_SIZE (NRF_ERROR_CRYPTO_ERR_BASE + 0x18) /**< Size of the key is not supported by choosen backend. */
+#define NRF_ERROR_CRYPTO_STACK_OVERFLOW (NRF_ERROR_CRYPTO_ERR_BASE + 0x19) /**< Stack overflow detected. */
+
+#define NRF_ERROR_CRYPTO_ECC_ERR_BASE (NRF_ERROR_CRYPTO_ERR_BASE + 0x40) /**< Base error code for ECC. */
+#define NRF_ERROR_CRYPTO_ECC_KEY_NOT_INITIALIZED (NRF_ERROR_CRYPTO_ECC_ERR_BASE + 0x00) /**< The key was not initialized. */
+#define NRF_ERROR_CRYPTO_ECDH_CURVE_MISMATCH (NRF_ERROR_CRYPTO_ECC_ERR_BASE + 0x01) /**< Public and private key provided to ECDH have different types of curves. */
+#define NRF_ERROR_CRYPTO_ECDSA_INVALID_SIGNATURE (NRF_ERROR_CRYPTO_ECC_ERR_BASE + 0x02) /**< Signature verification check reported invalid signature. */
+#define NRF_ERROR_CRYPTO_ECC_INVALID_KEY (NRF_ERROR_CRYPTO_ECC_ERR_BASE + 0x03) /**< Provided key is invalid. */
+
+#define NRF_ERROR_CRYPTO_AES_ERR_BASE (NRF_ERROR_CRYPTO_ERR_BASE + 0x50) /**< Base error code for all AES modes. */
+#define NRF_ERROR_CRYPTO_AES_INVALID_PADDING (NRF_ERROR_CRYPTO_AES_ERR_BASE + 0x00) /**< Message padding is corrupted. */
+
+#define NRF_ERROR_CRYPTO_AEAD_ERR_BASE (NRF_ERROR_CRYPTO_ERR_BASE + 0x60) /**< Base error code for all AEAD modes. */
+#define NRF_ERROR_CRYPTO_AEAD_INVALID_MAC (NRF_ERROR_CRYPTO_AEAD_ERR_BASE + 0x00) /**< MAC not matching encrypted text. */
+#define NRF_ERROR_CRYPTO_AEAD_NONCE_SIZE (NRF_ERROR_CRYPTO_AEAD_ERR_BASE + 0x01) /**< Size of the nonce is not supported in this AEAD mode. */
+#define NRF_ERROR_CRYPTO_AEAD_MAC_SIZE (NRF_ERROR_CRYPTO_AEAD_ERR_BASE + 0x02) /**< Size of the MAC (tag) is not supported in this AEAD mode. */
+
+#define NRF_ERROR_CRYPTO_RNG_ERR_BASE (NRF_ERROR_CRYPTO_ERR_BASE + 0x70) /**< Base error code for all RNG modes. */
+#define NRF_ERROR_CRYPTO_RNG_INIT_FAILED (NRF_ERROR_CRYPTO_RNG_ERR_BASE + 0x00) /**< Initialization or startup of RNG failed. */
+#define NRF_ERROR_CRYPTO_RNG_RESEED_REQUIRED (NRF_ERROR_CRYPTO_RNG_ERR_BASE + 0x01) /**< Reseed required (reseed counter overflowed). */
+
+/**
+ * @brief Function for converting an nrf_crypto error to a printable string pointer.
+ *
+ * @param[in] error Error code.
+ *
+ * @return Pointer to string explaining nrf_crypto error.
+ * */
+char const * nrf_crypto_error_string_get(ret_code_t error);
+
+#ifdef __cplusplus
+}
+#endif
+
+/** @} */
+
+#endif // NRF_CRYPTO_ERROR_H__
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/nrf_crypto_hash.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/nrf_crypto_hash.c
new file mode 100644
index 0000000..a03a9ff
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/nrf_crypto_hash.c
@@ -0,0 +1,205 @@
+/**
+ * Copyright (c) 2018 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+
+#include "sdk_common.h"
+#if NRF_MODULE_ENABLED(NRF_CRYPTO)
+
+#include "nrf_crypto_error.h"
+#include "nrf_crypto_hash.h"
+#include "nrf_crypto_mem.h"
+#include "nrf_crypto_hash_backend.h"
+#include "nrf_crypto_hash_shared.h"
+#include "nrf_crypto_shared.h"
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_HASH)
+
+static ret_code_t verify_context(nrf_crypto_hash_internal_context_t * const p_context)
+{
+ if (p_context == NULL)
+ {
+ return NRF_ERROR_CRYPTO_CONTEXT_NULL;
+ }
+
+ if (p_context->init_val != NRF_CRYPTO_HASH_INIT_VALUE)
+ {
+ return NRF_ERROR_CRYPTO_CONTEXT_NOT_INITIALIZED;
+ }
+
+ return NRF_SUCCESS;
+}
+
+
+ret_code_t nrf_crypto_hash_init(nrf_crypto_hash_context_t * const p_context,
+ nrf_crypto_hash_info_t const * p_info)
+{
+ ret_code_t ret_val;
+ nrf_crypto_hash_internal_context_t * p_int_context;
+
+ VERIFY_TRUE(p_context != NULL, NRF_ERROR_CRYPTO_CONTEXT_NULL);
+ VERIFY_TRUE(p_info != NULL, NRF_ERROR_CRYPTO_INPUT_NULL);
+
+ p_int_context = (nrf_crypto_hash_internal_context_t *) p_context;
+ p_int_context->p_info = p_info;
+
+ ret_val = p_info->init_fn(p_context);
+ if (ret_val != NRF_SUCCESS)
+ {
+ return ret_val;
+ }
+
+ p_int_context->init_val = NRF_CRYPTO_HASH_INIT_VALUE;
+
+ return NRF_SUCCESS;
+}
+
+
+ret_code_t nrf_crypto_hash_update(nrf_crypto_hash_context_t * const p_context,
+ uint8_t const * p_data,
+ size_t data_size)
+{
+ ret_code_t ret_val;
+ nrf_crypto_hash_internal_context_t * p_int_context
+ = (nrf_crypto_hash_internal_context_t *) p_context;
+
+ ret_val = verify_context(p_int_context);
+ if (ret_val != NRF_SUCCESS)
+ {
+ return ret_val;
+ }
+
+ VERIFY_TRUE(p_data != NULL, NRF_ERROR_CRYPTO_INPUT_NULL);
+
+ // Allow zero size input
+ if (data_size == 0)
+ {
+ return NRF_SUCCESS;
+ }
+
+ ret_val = p_int_context->p_info->update_fn(p_context, p_data, data_size);
+
+ return ret_val;
+}
+
+
+ret_code_t nrf_crypto_hash_finalize(nrf_crypto_hash_context_t * const p_context,
+ uint8_t * p_digest,
+ size_t * const p_digest_size)
+{
+ ret_code_t ret_val;
+ nrf_crypto_hash_internal_context_t * p_int_context
+ = (nrf_crypto_hash_internal_context_t *) p_context;
+
+ ret_val = verify_context(p_int_context);
+ if (ret_val != NRF_SUCCESS)
+ {
+ return ret_val;
+ }
+
+ VERIFY_TRUE(p_digest != NULL, NRF_ERROR_CRYPTO_OUTPUT_NULL);
+ VERIFY_TRUE(*p_digest_size >= p_int_context->p_info->digest_size, NRF_ERROR_CRYPTO_OUTPUT_LENGTH);
+
+ ret_val = p_int_context->p_info->finalize_fn(p_context, p_digest, p_digest_size);
+
+ return ret_val;
+}
+
+
+ret_code_t nrf_crypto_hash_calculate(nrf_crypto_hash_context_t * const p_context,
+ nrf_crypto_hash_info_t const * p_info,
+ uint8_t const * p_data,
+ size_t data_size,
+ uint8_t * p_digest,
+ size_t * const p_digest_size)
+{
+ ret_code_t ret_val;
+ nrf_crypto_hash_context_t * p_ctx = (nrf_crypto_hash_context_t *)p_context;
+ void * p_allocated_context = NULL;
+
+// Internal allocation of context not available for CC310_BL in order to save code size.
+#if defined(NRF_CRYPTO_BACKEND_CC310_BL_HASH_SHA256_ENABLED) && (NRF_CRYPTO_BACKEND_CC310_BL_HASH_SHA256_ENABLED == 1)
+
+ // Do nothing
+
+#elif defined(NRF_CRYPTO_BACKEND_CC310_BL_HASH_SHA256_ENABLED) && (NRF_CRYPTO_BACKEND_CC310_BL_HASH_SHA256_ENABLED == 0)
+
+ // Validate input. Only validate input parameters that are used locally, others are validated
+ // in the init, update and/or finalize functions.
+ VERIFY_TRUE(p_info != NULL, NRF_ERROR_CRYPTO_INPUT_NULL);
+
+ // Allocate context if needed (not provided by the user).
+ if (p_context == NULL)
+ {
+ p_allocated_context = NRF_CRYPTO_ALLOC(p_info->context_size);
+ if (p_allocated_context == NULL)
+ {
+ return NRF_ERROR_CRYPTO_ALLOC_FAILED;
+ }
+ p_ctx = (nrf_crypto_hash_context_t *)p_allocated_context;
+ }
+
+#else
+
+ #warning NRF_CRYPTO_BACKEND_CC310_BL_HASH_SHA256_ENABLED define not found in sdk_config.h (Is the sdk_config.h valid?).
+
+#endif // NRF_CRYPTO_BACKEND_CC310_BL_HASH_SHA256_ENABLED
+
+ ret_val = nrf_crypto_hash_init(p_ctx, p_info);
+ NRF_CRYPTO_VERIFY_SUCCESS_DEALLOCATE(ret_val, p_allocated_context);
+
+ ret_val = nrf_crypto_hash_update(p_ctx, p_data, data_size);
+ NRF_CRYPTO_VERIFY_SUCCESS_DEALLOCATE(ret_val, p_allocated_context);
+
+ ret_val = nrf_crypto_hash_finalize(p_ctx, p_digest, p_digest_size);
+ NRF_CRYPTO_VERIFY_SUCCESS_DEALLOCATE(ret_val, p_allocated_context);
+
+#if !NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_CC310_BL_HASH_SHA256)
+ // Free context if allocated internally
+ if (p_allocated_context != NULL)
+ {
+ NRF_CRYPTO_FREE(p_allocated_context);
+ }
+#endif // !NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_CC310_BL_HASH_SHA256)
+
+ return NRF_SUCCESS;
+}
+
+#endif // NRF_MODULE_ENABLED(NRF_CRYPTO_HASH)
+
+#endif // NRF_MODULE_ENABLED(NRF_CRYPTO)
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/nrf_crypto_hash.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/nrf_crypto_hash.h
new file mode 100644
index 0000000..66159b4
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/nrf_crypto_hash.h
@@ -0,0 +1,268 @@
+/**
+ * Copyright (c) 2018 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+
+#ifndef NRF_CRYPTO_HASH_H__
+#define NRF_CRYPTO_HASH_H__
+
+/** @file
+ *
+ * @defgroup nrf_crypto_hash Cryptographic hash related functions
+ * @{
+ * @ingroup nrf_crypto
+ *
+ * @brief Provides cryptographic hash related functionality through nrf_crypto.
+ */
+
+#include <stdint.h>
+#include "nrf_crypto_types.h"
+#include "nrf_crypto_hash_shared.h"
+#include "nrf_crypto_hash_backend.h"
+#include "app_util.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**@brief External variable declaration to info structure for SHA-256
+ *
+ * @note The variable is defined in the nrf_crypto backend that is
+ * enabled in the @ref sdk_config.
+ *
+ */
+extern const nrf_crypto_hash_info_t g_nrf_crypto_hash_sha256_info;
+
+
+ /**@brief External variable declaration to info structure for SHA-512
+ *
+ * @note The variable is defined in the nrf_crypto backend that is
+ * enabled in the @ref sdk_config.
+ *
+ */
+extern const nrf_crypto_hash_info_t g_nrf_crypto_hash_sha512_info;
+
+
+/**
+ * @brief Context type for Hash.
+ *
+ * @note The size of this type is scaled for the largest Hash backend context that is
+ * enabled in @ref sdk_config.
+ */
+typedef nrf_crypto_backend_hash_context_t nrf_crypto_hash_context_t;
+
+
+/** @brief Type definition for an array holding a SHA-256 hash digest. */
+typedef uint8_t nrf_crypto_hash_sha256_digest_t[NRF_CRYPTO_HASH_SIZE_SHA256];
+
+
+/** @brief Type definition for an array holding a SHA-512 hash digest. */
+typedef uint8_t nrf_crypto_hash_sha512_digest_t[NRF_CRYPTO_HASH_SIZE_SHA512];
+
+
+/**@brief Function for initializing the context structure required to compute a hash digest from
+ * arbitrary input data.
+ *
+ * @note The context structure is assumed to be an opaque type defined by the
+ * nrf_crypto backend.
+ *
+ * @note The return codes @ref NRF_ERROR_CRYPTO_FEATURE_UNAVAILABLE and
+ * NRF_ERROR_CRYPTO_INTERNAL only happens in cc310 backend.
+ *
+ * @param[in,out] p_context Pointer to structure holding context information for
+ * the hash calculation.
+ * @param[in] p_info Pointer to structure holding info about the hash algorithm
+ * used to do the computed hash.
+ *
+ * @retval NRF_SUCCESS The hash initialization was successful.
+ * @retval NRF_ERROR_CRYPTO_NOT_INITIALIZED @ref nrf_crypto_init was not called prior to
+ * this crypto function.
+ * @retval NRF_ERROR_CRYPTO_CONTEXT_NULL A NULL pointer was provided for the context
+ * structure.
+ * @retval NRF_ERROR_CRYPTO_INPUT_NULL The pointer to the info structure was NULL.
+ * @retval NRF_ERROR_CRYPTO_FEATURE_UNAVAILABLE The function was called with a hash mode that
+ * is unavailable.
+ * @retval NRF_ERROR_CRYPTO_INTERNAL An internal error occurred when initializing
+ * the constext in the nrf_crypto backend.
+ */
+ret_code_t nrf_crypto_hash_init(nrf_crypto_hash_context_t * const p_context,
+ nrf_crypto_hash_info_t const * p_info);
+
+
+/**@brief Function for updating the hash calculation with partial arbitrary data.
+ *
+ * @details This function should be called one or more times until all arbituary input data
+ * required for the hash calcuation is provided.
+ *
+ * @note @ref nrf_crypto_hash_init must be called prior to this function to configure the
+ * context structure used as input parameter to this function.
+ *
+ * @note @ref nrf_crypto_hash_finalize must be called after all arbitruary input data
+ * has been provided to get the calculated hash digest.
+ *
+ * @note The context object is assumed to be an opaque type defined by the
+ * nrf_crypto backend.
+ *
+ * @note The return values @ref NRF_ERROR_CRYPTO_BUSY, @ref NRF_ERROR_CRYPTO_INPUT_LOCATION
+ * and @ref NRF_ERROR_CRYPTO_INPUT_LOCATION can only occur in CC310 backend.
+ *
+ * @param[in,out] p_context Pointer to structure holding context information for
+ * the hash calculation.
+ * @param[in] p_data Pointer to data to be hashed.
+ * @param[in] data_size Length of the data to be hashed.
+ *
+ * @retval NRF_SUCCESS The hash digest was computed successfully.
+ * @retval NRF_ERROR_CRYPTO_NOT_INITIALIZED @ref nrf_crypto_init was not called prior to
+ * this crypto function.
+ * @retval NRF_ERROR_CRYPTO_CONTEXT_NOT_INITIALIZED The context was not initialized prior to
+ * this call or it was corrupted. Please call
+ * @ref nrf_crypto_hash_init to initialize it.
+ * @retval NRF_ERROR_CRYPTO_CONTEXT_NULL A NULL pointer was provided for the context
+ * structure.
+ * @retval NRF_ERROR_CRYPTO_INPUT_NULL p_data was NULL.
+ * @retval NRF_ERROR_CRYPTO_INPUT_LOCATION Input data not in RAM.
+ * @retval NRF_ERROR_CRYPTO_BUSY The function could not be called because the
+ * nrf_crypto backend was busy. Please rerun the
+ * cryptographic routine at a later time.
+ * @retval NRF_ERROR_CRYPTO_INTERNAL An internal error occurred in the nrf_crypto
+ * backend.
+ */
+ret_code_t nrf_crypto_hash_update(nrf_crypto_hash_context_t * const p_context,
+ uint8_t const * p_data,
+ size_t data_size);
+
+/**@brief Function for finalizing computation of a hash digest from arbitrary data.
+ *
+ * @details This function is called to get the calculated
+ *
+ * @note @ref nrf_crypto_hash_init must be called prior to this function to configure the
+ * context structure used as input parameter to this function.
+ *
+ * @note The input data for the calculated hash digest must be provided by calling
+ * @ref nrf_crypto_hash_update one or more times.
+ *
+ * @note The context object is assumed to be an opaque type defined by the
+ * nrf_crypto backend.
+ *
+ * @note The return values @ref NRF_ERROR_CRYPTO_BUSY and @ref NRF_ERROR_CRYPTO_INPUT_LOCATION
+ * can only occur in CC310 backend.
+ *
+ *
+ * @param[in] p_context Pointer to structure holding context information for
+ * the hash calculation.
+ * @param[out] p_digest Pointer to buffer holding the calculated hash digest.
+ * @param[in,out] p_digest_size Pointer to a variable holding the length of the calculated hash.
+ * Set this to the length of buffer that p_digest is pointing to.
+ *
+ * @retval NRF_SUCCESS The hash digest was computed successfully.
+ * @retval NRF_ERROR_CRYPTO_NOT_INITIALIZED @ref nrf_crypto_init was not called prior to
+ * this crypto function.
+ * @retval NRF_ERROR_CRYPTO_CONTEXT_NOT_INITIALIZED The context was not initialized prior to
+ * this call or it was corrupted. Please call
+ * @ref nrf_crypto_hash_init to initialize it.
+ * @retval NRF_ERROR_CRYPTO_CONTEXT_NULL A NULL pointer was provided for the context
+ * structure.
+ * @retval NRF_ERROR_CRYPTO_OUTPUT_NULL p_digest or p_digest_size was NULL.
+ * @retval NRF_ERROR_CRYPTO_OUTPUT_LENGTH The length of p_digest was too small for
+ * the hash digest result.
+ * @retval NRF_ERROR_CRYPTO_BUSY The function could not be called because the
+ * nrf_crypto backend was busy. Please rerun the
+ * cryptographic routine at a later time.
+ * @retval NRF_ERROR_CRYPTO_INTERNAL An internal error occurred in the nrf_crypto
+ * backend.
+ */
+ret_code_t nrf_crypto_hash_finalize(nrf_crypto_hash_context_t * const p_context,
+ uint8_t * p_digest,
+ size_t * const p_digest_size);
+
+
+/**@brief Function for computing a hash from arbitrary data in a single integrated step.
+ *
+ * @details This function calculates the hash digest from arbitruary data in a single integrated step.
+ * This means calling init, update and finalize in one step.
+ *
+ * @note The context object is assumed to be an opaque type defined by the
+ * nrf_crypto backend.
+ *
+ * @note The return values @ref NRF_ERROR_CRYPTO_BUSY, @ref NRF_ERROR_CRYPTO_INPUT_LOCATION
+ * and @ref NRF_ERROR_CRYPTO_INPUT_LOCATION can only occur in CC310 backend.
+ *
+ * @param[in,out] p_context Pointer to structure holding context information for
+ * the hash calculation. If this
+ * is set to NULL, it will be allocated by the user configurable
+ * allocate/free function @ref NRF_CRYPTO_ALLOC and
+ * @ref NRF_CRYPTO_FREE.
+ * @param[in] p_info Pointer to structure holding info about hash algorithm
+ * for the computed hash.
+ * @param[in] p_data Pointer to data to be hashed.
+ * @param[in] data_size Length of the data to be hashed.
+ * @param[out] p_digest Pointer to buffer holding the calculated hash digest.
+ * @param[in,out] p_digest_size Pointer to a variable holding the length of the calculated hash.
+ * Set this to the length of buffer that p_digest is pointing to.
+ *
+ * @retval NRF_SUCCESS The hash initialization was successful.
+ * @retval NRF_ERROR_CRYPTO_NOT_INITIALIZED @ref nrf_crypto_init was not called prior to
+ * this crypto function.
+ * @retval NRF_ERROR_CRYPTO_CONTEXT_NULL A NULL pointer was provided for the context
+ * structure.
+ * @retval NRF_ERROR_CRYPTO_INPUT_NULL p_info or p_data was NULL.
+ * @retval NRF_ERROR_CRYPTO_INPUT_LOCATION Input data not in RAM.
+ * @retval NRF_ERROR_CRYPTO_OUTPUT_NULL p_digest or p_digest_size was NULL.
+ * @retval NRF_ERROR_CRYPTO_OUTPUT_LENGTH The length of p_digest was too small for
+ * the hash digest result.
+ * @retval NRF_ERROR_CRYPTO_BUSY The function could not be called because the
+ * nrf_crypto backend was busy. Please rerun the
+ * cryptographic routine at a later time.
+ * @retval NRF_ERROR_CRYPTO_ALLOC_FAILED Unable to allocate memory for the context.
+ * @retval NRF_ERROR_CRYPTO_INTERNAL An internal error occurred in the nrf_crypto
+ * backend.
+ */
+ret_code_t nrf_crypto_hash_calculate(nrf_crypto_hash_context_t * const p_context,
+ nrf_crypto_hash_info_t const * p_info,
+ uint8_t const * p_data,
+ size_t data_size,
+ uint8_t * p_digest,
+ size_t * const p_digest_size);
+
+#ifdef __cplusplus
+}
+#endif
+
+/**@} */
+
+#endif // NRF_CRYPTO_HASH_H__
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/nrf_crypto_hash_backend.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/nrf_crypto_hash_backend.h
new file mode 100644
index 0000000..2fbac07
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/nrf_crypto_hash_backend.h
@@ -0,0 +1,84 @@
+/**
+ * Copyright (c) 2018 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+
+#ifndef NRF_CRYPTO_HASH_BACKEND_H__
+#define NRF_CRYPTO_HASH_BACKEND_H__
+
+#include "sdk_common.h"
+#include "cc310_backend_hash.h"
+#include "mbedtls_backend_hash.h"
+#include "oberon_backend_hash.h"
+#include "cc310_bl_backend_hash.h"
+#include "nrf_sw_backend_hash.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#if !NRF_MODULE_ENABLED(NRF_CRYPTO_HASH_SHA256)
+
+/**@internal @brief Fallback type for SHA-256 hash context (if no backend is enabled).
+ */
+typedef nrf_crypto_hash_internal_context_t nrf_crypto_backend_hash_sha256_context_t;
+
+#endif
+
+#if !NRF_MODULE_ENABLED(NRF_CRYPTO_HASH_SHA512)
+
+/**@internal @brief Fallback type for SHA-512 hash context (if no backend is enabled).
+ */
+typedef nrf_crypto_hash_internal_context_t nrf_crypto_backend_hash_sha512_context_t;
+
+#endif
+
+
+/** @internal @brief Union holding a hash context. */
+typedef union
+{
+ nrf_crypto_backend_hash_sha256_context_t hash_sha256_context; /**< @brief Holds context for SHA-256. */
+ nrf_crypto_backend_hash_sha512_context_t hash_sha512_context; /**< @brief Holds context for SHA-512. */
+} nrf_crypto_backend_hash_context_t;
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // NRF_CRYPTO_HASH_BACKEND_H__
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/nrf_crypto_hash_shared.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/nrf_crypto_hash_shared.h
new file mode 100644
index 0000000..14205d0
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/nrf_crypto_hash_shared.h
@@ -0,0 +1,120 @@
+/**
+ * Copyright (c) 2018 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+
+#ifndef NRF_CRYPTO_HASH_SHARED_H__
+#define NRF_CRYPTO_HASH_SHARED_H__
+
+#include "stdint.h"
+#include "stddef.h"
+#include "sdk_errors.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define NRF_CRYPTO_HASH_INIT_VALUE (0x4846526E) //!< Magic value to signal that the nrf_crypto_hash context structure is initialized.
+
+/**@brief Enumeration of supported modes of operation in nrf_crypto_hash
+ */
+typedef enum
+{
+ NRF_CRYPTO_HASH_MODE_SHA256,
+ NRF_CRYPTO_HASH_MODE_SHA512
+} nrf_crypto_hash_mode_t;
+
+
+/**@internal @brief Type declaration to do hash initialization in nrf_crypto backend.
+ *
+ * This is an internal API. See @ref nrf_crypto_hash_init for documentation.
+ */
+typedef ret_code_t (*nrf_crypto_hash_init_fn_t)(void * const p_context);
+
+
+/**@internal @brief Type declaration to do hash update in nrf_crypto backend.
+ *
+ * This is an internal API. See @ref nrf_crypto_hash_init for documentation.
+ */
+typedef ret_code_t (*nrf_crypto_hash_update_fn_t)(void * const p_context,
+ uint8_t const * p_data,
+ size_t size);
+
+
+/**@internal @brief Type declaration to do hash finalize in nrf_crypto backend.
+ *
+ * This is an internal API. See @ref nrf_crypto_hash_finalize for documentation.
+ */
+typedef ret_code_t (*nrf_crypto_hash_finalize_fn_t)(void * const p_context,
+ uint8_t * p_digest,
+ size_t * const p_digest_size);
+
+
+/**@internal @brief Type declaration to for a nrf_crypto_hash info strucure
+ *
+ * @details This structure contains the calling interface and any meta data required
+ * to call the nrf_crypto_hash API functions.
+ */
+typedef struct
+{
+ nrf_crypto_hash_init_fn_t const init_fn; /**< Function pointer to call to initialize nrf_crypto_hash context in backend. */
+ nrf_crypto_hash_update_fn_t const update_fn; /**< Function pointer to call to add data in the hash calculation. */
+ nrf_crypto_hash_finalize_fn_t const finalize_fn; /**< Function pointer to call to finalize the hash calculation and return the result. */
+ size_t const digest_size; /**< Size of the digest. */
+ size_t const context_size; /**< Size of the context type. */
+ nrf_crypto_hash_mode_t const hash_mode; /**< Mode of hash operation. */
+} nrf_crypto_hash_info_t;
+
+
+/**@internal @brief Type declaration of internal representation of a hash context structure.
+ *
+ * @details This is an internal type that should not be used directly.
+ */
+typedef struct
+{
+ uint32_t init_val; /**< Value that is set to NRF_CRYPTO_HASH_INIT_VALUE when context has been initialized. */
+ nrf_crypto_hash_info_t const * p_info; /**< Pointer to an nrf_crypto_hash info structure. */
+
+} nrf_crypto_hash_internal_context_t;
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // NRF_CRYPTO_HASH_SHARED_H__
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/nrf_crypto_hkdf.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/nrf_crypto_hkdf.c
new file mode 100644
index 0000000..00c6c7b
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/nrf_crypto_hkdf.c
@@ -0,0 +1,225 @@
+/**
+ * Copyright (c) 2018 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+
+#include "sdk_common.h"
+#if NRF_MODULE_ENABLED(NRF_CRYPTO)
+
+#include "stddef.h"
+#include "nrf_assert.h"
+#include "nrf_crypto_hmac.h"
+#include "nrf_crypto_hkdf.h"
+#include "nrf_crypto_error.h"
+#include "nrf_crypto_mem.h"
+#include "nrf_crypto_shared.h"
+#include "nrf_crypto_hmac_shared.h"
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_HMAC)
+
+static ret_code_t hkdf_expand(nrf_crypto_hmac_context_t * const p_context,
+ nrf_crypto_hmac_info_t const * p_info,
+ uint8_t * const p_output_key,
+ size_t output_key_size,
+ uint8_t const * const p_ainfo,
+ size_t ainfo_size,
+ uint8_t * const p_temp,
+ uint8_t const * const p_prk,
+ size_t prk_size)
+{
+ size_t const hash_digest_size = p_info->digest_size;
+ uint32_t const n_iterations = (output_key_size + hash_digest_size - 1) / hash_digest_size;
+ ret_code_t err_code = NRF_SUCCESS;
+ size_t temp_size;
+ uint8_t n_current;
+ int write_offset;
+
+ VERIFY_TRUE(n_iterations <= 255, NRF_ERROR_CRYPTO_OUTPUT_LENGTH);
+
+ write_offset = 0;
+ for (uint32_t i = 0; i < n_iterations; i++)
+ {
+ n_current = i + 1;
+
+ err_code = nrf_crypto_hmac_init(p_context, p_info, p_prk, prk_size);
+ VERIFY_SUCCESS(err_code);
+
+ if (i != 0)
+ {
+ err_code = nrf_crypto_hmac_update(p_context, p_temp, hash_digest_size);
+ VERIFY_SUCCESS(err_code);
+ }
+
+ if (p_ainfo != NULL)
+ {
+ err_code = nrf_crypto_hmac_update(p_context, p_ainfo, ainfo_size);
+ VERIFY_SUCCESS(err_code);
+ }
+
+ err_code = nrf_crypto_hmac_update(p_context, &n_current, 1);
+ VERIFY_SUCCESS(err_code);
+
+ temp_size = hash_digest_size;
+ err_code = nrf_crypto_hmac_finalize(p_context, p_temp, &temp_size);
+ VERIFY_SUCCESS(err_code);
+
+ memcpy(p_output_key + write_offset,
+ p_temp,
+ (n_current != n_iterations) ? hash_digest_size : (output_key_size - write_offset));
+
+ write_offset += hash_digest_size;
+ }
+
+ return err_code;
+}
+
+
+ret_code_t nrf_crypto_hkdf_calculate(nrf_crypto_hmac_context_t * const p_context,
+ nrf_crypto_hmac_info_t const * p_info,
+ uint8_t * const p_output_key,
+ size_t * const p_output_key_size,
+ uint8_t const * const p_input_key,
+ size_t input_key_size,
+ uint8_t const * p_salt,
+ size_t salt_size,
+ uint8_t const * const p_ainfo,
+ size_t ainfo_size,
+ nrf_crypto_hkdf_mode_t mode)
+{
+ uint8_t prk[NRF_CRYPTO_HASH_SIZE_SHA512]; // Scaled for the largest supported hash size.
+ uint8_t temp[NRF_CRYPTO_HASH_SIZE_SHA512]; // Scaled for the largest supported hash size.
+ void * p_ctx = NULL;
+ void * p_allocated_context = NULL;
+ size_t prk_size = sizeof(prk);
+ size_t output_key_size = *p_output_key_size;
+ ret_code_t err_code;
+
+ VERIFY_TRUE(p_info != NULL, NRF_ERROR_CRYPTO_INPUT_NULL);
+ VERIFY_TRUE(p_output_key != NULL, NRF_ERROR_CRYPTO_OUTPUT_NULL);
+ VERIFY_TRUE(*p_output_key_size > 0, NRF_ERROR_CRYPTO_OUTPUT_LENGTH);
+ VERIFY_TRUE(p_input_key != NULL, NRF_ERROR_CRYPTO_INPUT_NULL);
+ VERIFY_TRUE(input_key_size > 0, NRF_ERROR_CRYPTO_INPUT_LENGTH);
+
+ if (p_salt != NULL)
+ {
+ VERIFY_TRUE(salt_size > 0, NRF_ERROR_CRYPTO_INPUT_LENGTH);
+ }
+
+ if (p_ainfo != NULL)
+ {
+ VERIFY_TRUE(ainfo_size > 0, NRF_ERROR_CRYPTO_INPUT_LENGTH);
+ }
+
+ *p_output_key_size = 0; // Set output length to 0 as default value (in case of error).
+
+ // Allocate context internally if p_context is NULL
+ if (p_context == NULL)
+ {
+ p_allocated_context = NRF_CRYPTO_ALLOC(p_info->context_size);
+ if (p_allocated_context == NULL)
+ {
+ return NRF_ERROR_CRYPTO_ALLOC_FAILED;
+ }
+ p_ctx = p_allocated_context;
+ }
+ else
+ {
+ p_ctx = p_context;
+ }
+
+ if (mode == NRF_CRYPTO_HKDF_EXTRACT_AND_EXPAND)
+ {
+ if (p_salt == NULL)
+ {
+ // Use default salt defined in RFC 5869: String of zeros of hash length.
+ salt_size = p_info->digest_size;
+ ASSERT(sizeof(temp) >= salt_size);
+ memset(temp, 0, salt_size);
+ p_salt = temp;
+ }
+
+ // Step 1: Extract
+ err_code = nrf_crypto_hmac_calculate(p_context,
+ p_info,
+ prk,
+ &prk_size,
+ p_salt,
+ salt_size,
+ p_input_key,
+ input_key_size);
+ NRF_CRYPTO_VERIFY_SUCCESS_DEALLOCATE(err_code, p_allocated_context);
+
+ // Step 2: Expand
+ err_code = hkdf_expand(p_ctx,
+ p_info,
+ p_output_key,
+ output_key_size,
+ p_ainfo,
+ ainfo_size,
+ temp,
+ prk,
+ prk_size);
+ NRF_CRYPTO_VERIFY_SUCCESS_DEALLOCATE(err_code, p_allocated_context);
+ }
+ else // NRF_CRYPTO_HKDF_EXPAND_ONLY
+ {
+ err_code = hkdf_expand(p_ctx,
+ p_info,
+ p_output_key,
+ output_key_size,
+ p_ainfo,
+ ainfo_size,
+ temp,
+ p_input_key,
+ input_key_size);
+ NRF_CRYPTO_VERIFY_SUCCESS_DEALLOCATE(err_code, p_allocated_context);
+ }
+
+ if (p_allocated_context != NULL)
+ {
+ NRF_CRYPTO_FREE(p_allocated_context);
+ }
+
+ *p_output_key_size = output_key_size;
+
+ return NRF_SUCCESS;
+}
+
+
+#endif // NRF_MODULE_ENABLED(NRF_CRYPTO_HMAC)
+#endif // NRF_MODULE_ENABLED(NRF_CRYPTO)
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/nrf_crypto_hkdf.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/nrf_crypto_hkdf.h
new file mode 100644
index 0000000..7c84615
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/nrf_crypto_hkdf.h
@@ -0,0 +1,141 @@
+/**
+ * Copyright (c) 2018 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+
+#ifndef NRF_CRYPTO_HKDF_H__
+#define NRF_CRYPTO_HKDF_H__
+
+/** @file
+ *
+ * @defgroup nrf_crypto_hkdf HMAC based Key Derivation Function (HKDF) related functions
+ * @{
+ * @ingroup nrf_crypto
+ *
+ * @brief Provides functions to generate HMAC based Key Derivation Function (HKDF).
+ *
+ * @details Provides functions to generate HMAC based Key Derivation Function (HKDF) using
+ * one of the supported hash algorithms. This layer is independent of backend crypto library.
+ * The HKDF module does not have a backend configuration, as it uses the nrf_crypto_hmac API,
+ * including the backend configured for HMAC in @ref sdk_config.
+ */
+
+
+#include <stdint.h>
+#include "sdk_common.h"
+#include "nrf_crypto_hmac.h"
+#include "nrf_crypto_hkdf.h"
+#include "nrf_crypto_types.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+/**
+ * @brief Enumeration of HKDF modes.
+ */
+typedef enum
+{
+ NRF_CRYPTO_HKDF_EXTRACT_AND_EXPAND, //!< HKDF Extract and expand mode (normal).
+ NRF_CRYPTO_HKDF_EXPAND_ONLY //!< HKDF Expand only mode.
+} nrf_crypto_hkdf_mode_t;
+
+
+/**
+ * @brief Integrated HKDF calculation function
+ *
+ * @details This HKDF calculation function uses the nrf_crypto HMAC frontend directly.
+ * The backend is selected by configuring the HMAC backend in @ref sdk_config.
+ *
+ * @param[in,out] p_context Pointer to context structure. Context memory will be
+ * allocated internally if the context pointer is NULL.
+ * @param[in] p_info Pointer to static info structure. This defines the algorithm.
+ * This should be either @ref g_nrf_crypto_hmac_sha256_info or
+ * @ref g_nrf_crypto_hmac_sha512_info.
+ * @param[out] p_output_key Pointer to buffer to hold the output key material.
+ * @param[in,out] p_output_key_size Pointer to the length of the wanted output key material as input
+ * and actual length of the output material as output. Can be any
+ * number between 1 and the hash digest size multiplied by 255
+ * (65280 for SHA-256 or 130560 for SHA-512). The p_output_key
+ * buffer must be large enough to hold this value.
+ * @param[in] p_input_key Pointer to buffer holding the input key material.
+ * @param[in] input_key_size Length of the input key material.
+ * @param[in] p_salt Pointer to buffer of nonsecret random salt data. Set to NULL in
+ * order to use the default salt defined by RFC 5869 (all zero
+ * array of hash digest size) or if salt is not used (expand only).
+ * @param[in] salt_size Length of the salt. Must be > 0 unless default salt is used, or
+ * in case mode is set to @ref NRF_CRYPTO_HKDF_EXPAND_ONLY.
+ * @param[in] p_ainfo Pointer to optional application specific information.
+ * (set to NULL and set ainfo_size to 0 if unused).
+ * @param[in] ainfo_size Length of the additional information.
+ * @param[in] mode Set to @ref NRF_CRYPTO_HKDF_EXTRACT_AND_EXPAND for normal mode.
+ * Alternatively, set to @ref NRF_CRYPTO_HKDF_EXPAND_ONLY to skip
+ * the extraction step.
+ *
+ * @retval NRF_SUCCESS Output key material hash was successfully calculated.
+ * @retval NRF_ERROR_CRYPTO_INPUT_NULL If p_input_key was NULL.
+ * @retval NRF_ERROR_CRYPTO_INPUT_LENGTH If input_key_size or salt_size was invalid.
+ * @retval NRF_ERROR_CRYPTO_OUTPUT_NULL If p_output_key_sizen was NULL.
+ * @retval NRF_ERROR_CRYPTO_OUTPUT_LENGTH If *p_output_key_size is 0.
+ * @retval NRF_ERROR_CRYPTO_ALLOC_FAILED Unable to allocate memory for the context.
+ * @retval NRF_ERROR_CRYPTO_INTERNAL An error occurred in the crypto backend.
+ * @retval NRF_ERROR_CRYPTO_BUSY The function could not be called because the
+ * nrf_crypto backend was busy. Please rerun the
+ * cryptographic routine at a later time. CC310 only.
+ */
+ret_code_t nrf_crypto_hkdf_calculate(nrf_crypto_hmac_context_t * const p_context,
+ nrf_crypto_hmac_info_t const * p_info,
+ uint8_t * const p_output_key,
+ size_t * const p_output_key_size,
+ uint8_t const * const p_input_key,
+ size_t input_key_size,
+ uint8_t const * p_salt,
+ size_t salt_size,
+ uint8_t const * const p_ainfo,
+ size_t ainfo_size,
+ nrf_crypto_hkdf_mode_t mode);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+/**@} */
+
+#endif // #ifndef NRF_CRYPTO_HKDF_H__
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/nrf_crypto_hmac.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/nrf_crypto_hmac.c
new file mode 100644
index 0000000..4bd1546
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/nrf_crypto_hmac.c
@@ -0,0 +1,203 @@
+/**
+ * Copyright (c) 2018 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+
+#include "sdk_common.h"
+#if NRF_MODULE_ENABLED(NRF_CRYPTO)
+
+#include "stddef.h"
+#include "nrf_log.h"
+#include "nrf_crypto_hmac.h"
+#include "nrf_crypto_hmac_shared.h"
+#include "nrf_crypto_error.h"
+#include "nrf_crypto_init.h"
+#include "nrf_crypto_mem.h"
+#include "nrf_crypto_shared.h"
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_HMAC)
+
+// Magic word that is set when initializing the context and checked by functions that use it.
+#define NRF_CRYPTO_HMAC_INIT_MAGIC_VALUE 0xBADEBA11
+
+
+static ret_code_t verify_context_valid(nrf_crypto_hmac_internal_context_t * const p_context)
+{
+ if (p_context == NULL)
+ {
+ return NRF_ERROR_CRYPTO_CONTEXT_NULL;
+ }
+ else if (p_context->init_value != NRF_CRYPTO_HMAC_INIT_MAGIC_VALUE)
+ {
+ return NRF_ERROR_CRYPTO_CONTEXT_NOT_INITIALIZED;
+ }
+ else
+ {
+ return NRF_SUCCESS;
+ }
+}
+
+
+ret_code_t nrf_crypto_hmac_init(nrf_crypto_hmac_context_t * const p_context,
+ nrf_crypto_hmac_info_t const * p_info,
+ uint8_t const * p_key,
+ size_t key_size)
+{
+ ret_code_t err_code;
+ nrf_crypto_hmac_internal_context_t * p_ctx = (nrf_crypto_hmac_internal_context_t *)p_context;
+
+ VERIFY_TRUE(nrf_crypto_is_initialized(), NRF_ERROR_CRYPTO_NOT_INITIALIZED);
+
+ // Validate input
+ VERIFY_TRUE(p_ctx != NULL, NRF_ERROR_CRYPTO_CONTEXT_NULL);
+ VERIFY_TRUE(p_info != NULL, NRF_ERROR_CRYPTO_INPUT_NULL);
+ VERIFY_TRUE(p_key != NULL, NRF_ERROR_CRYPTO_INPUT_NULL);
+ VERIFY_TRUE(key_size > 0, NRF_ERROR_CRYPTO_INPUT_LENGTH);
+
+ // Initialize generic part of the context
+ p_ctx->p_info = p_info;
+
+ // Do backend specific initialization by calling the backend init function pointed
+ // to in the configuration struct in the context (nrf_crypto_hmac_config_t)
+ err_code = p_ctx->p_info->init_fn(p_context, p_key, key_size);
+ if (err_code == NRF_SUCCESS)
+ {
+ p_ctx->init_value = NRF_CRYPTO_HMAC_INIT_MAGIC_VALUE;
+ }
+
+ return err_code;
+}
+
+
+ret_code_t nrf_crypto_hmac_update(nrf_crypto_hmac_context_t * const p_context,
+ uint8_t const * p_data,
+ size_t data_size)
+{
+ ret_code_t err_code;
+
+ // The context header by definition has to be the first element of the context struct.
+ nrf_crypto_hmac_internal_context_t * p_ctx = (nrf_crypto_hmac_internal_context_t *)p_context;
+
+ // Validate input
+ err_code = verify_context_valid(p_ctx);
+ VERIFY_SUCCESS(err_code);
+ VERIFY_TRUE(p_data != NULL, NRF_ERROR_CRYPTO_INPUT_NULL);
+ VERIFY_TRUE(data_size > 0, NRF_ERROR_CRYPTO_INPUT_LENGTH);
+
+ // Call backend specific update function (pointed to by config struct in context)
+ err_code = p_ctx->p_info->update_fn(p_context, p_data, data_size);
+
+ return err_code;
+}
+
+
+ret_code_t nrf_crypto_hmac_finalize(nrf_crypto_hmac_context_t * const p_context,
+ uint8_t * p_digest,
+ size_t * const p_digest_size)
+{
+ ret_code_t err_code;
+
+ // The context header by definition has to be the first element of the context struct.
+ nrf_crypto_hmac_internal_context_t * p_ctx = (nrf_crypto_hmac_internal_context_t *)p_context;
+
+ // Validate input
+ err_code = verify_context_valid(p_ctx);
+ VERIFY_SUCCESS(err_code);
+ VERIFY_TRUE(p_digest != NULL, NRF_ERROR_CRYPTO_OUTPUT_NULL);
+ VERIFY_TRUE(*p_digest_size >= p_ctx->p_info->digest_size, NRF_ERROR_CRYPTO_OUTPUT_LENGTH);
+
+ // Call backend specific finish function (pointed to by config struct in context)
+ err_code = p_ctx->p_info->finalize_fn(p_context, p_digest, p_digest_size);
+
+ return err_code;
+}
+
+
+ret_code_t nrf_crypto_hmac_calculate(nrf_crypto_hmac_context_t * const p_context,
+ nrf_crypto_hmac_info_t const * p_info,
+ uint8_t * p_digest,
+ size_t * const p_digest_size,
+ uint8_t const * p_key,
+ size_t key_size,
+ uint8_t const * p_data,
+ size_t data_size)
+{
+ ret_code_t err_code;
+ nrf_crypto_hmac_context_t * p_ctx;
+ void * p_allocated_context = NULL;
+
+ // Validate input. Only validate input parameters that are used locally, others are validated
+ // in the init, update and/or finalize functions.
+ VERIFY_TRUE(p_info != NULL, NRF_ERROR_CRYPTO_INPUT_NULL);
+
+ // Allocate context if needed (not provided by the user).
+ if (p_context == NULL)
+ {
+ p_allocated_context = NRF_CRYPTO_ALLOC(p_info->context_size);
+ if (p_allocated_context == NULL)
+ {
+ return NRF_ERROR_CRYPTO_ALLOC_FAILED;
+ }
+ p_ctx = (nrf_crypto_hmac_context_t *)p_allocated_context;
+ }
+ else
+ {
+ p_ctx = (nrf_crypto_hmac_context_t *)p_context;
+ }
+
+ // Perform integrated HMAC calculation by caling the frontend functions defined in this file
+ err_code = nrf_crypto_hmac_init(p_ctx, p_info, p_key, key_size);
+ NRF_CRYPTO_VERIFY_SUCCESS_DEALLOCATE(err_code, p_allocated_context);
+
+ err_code = nrf_crypto_hmac_update(p_ctx, p_data, data_size);
+ NRF_CRYPTO_VERIFY_SUCCESS_DEALLOCATE(err_code, p_allocated_context);
+
+ err_code = nrf_crypto_hmac_finalize(p_ctx, p_digest, p_digest_size);
+ NRF_CRYPTO_VERIFY_SUCCESS_DEALLOCATE(err_code, p_allocated_context);
+
+ // Free context if allocated internally
+ if (p_allocated_context != NULL)
+ {
+ NRF_CRYPTO_FREE(p_allocated_context);
+ }
+
+ return err_code;
+}
+
+#endif // NRF_MODULE_ENABLED(NRF_CRYPTO_HMAC)
+#endif // NRF_MODULE_ENABLED(NRF_CRYPTO)
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/nrf_crypto_hmac.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/nrf_crypto_hmac.h
new file mode 100644
index 0000000..3a0340f
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/nrf_crypto_hmac.h
@@ -0,0 +1,226 @@
+/**
+ * Copyright (c) 2018 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+
+#ifndef NRF_CRYPTO_HMAC_H__
+#define NRF_CRYPTO_HMAC_H__
+
+/** @file
+ *
+ * @defgroup nrf_crypto_hmac Hash-based message authentication code (HMAC) related functions
+ * @{
+ * @ingroup nrf_crypto
+ *
+ * @brief Provides functions to generate Hash-based message authentication code (HMAC).
+ *
+ * @details Provides functions to generate Hash-based message authentication code (HMAC) using
+ * one of the supported hash algorithms. This layer is independent of backend crypto library.
+ */
+
+#include <stdint.h>
+#include "sdk_common.h"
+#include "nrf_crypto_types.h"
+#include "nrf_crypto_hmac_backend.h"
+#include "nrf_crypto_hmac_shared.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+/**
+ * @brief Information structures used to select the specific algorithm (SHA-256)
+ *
+ * @details The information structure is used in a generic way but is populated by the backend,
+ * and contains backend specific data. */
+extern const nrf_crypto_hmac_info_t g_nrf_crypto_hmac_sha256_info;
+
+
+/**
+ * @brief Information structures used to select the specific algorithm (SHA-512)
+ *
+ * @details The information structure is used in a generic way but is populated by the backend,
+ * and contains backend specific data.
+ */
+extern const nrf_crypto_hmac_info_t g_nrf_crypto_hmac_sha512_info;
+
+
+/**
+ * @brief Context type for HMAC.
+ *
+ * @note The size of this type is scaled for the largest HMAC backend context that is
+ * enabled in @ref sdk_config.
+ */
+typedef nrf_crypto_backend_hmac_context_t nrf_crypto_hmac_context_t;
+
+/**
+ * @brief Initialize context object for HMAC
+ *
+ * @details Use to initialize a context once it has been allocated.
+ *
+ * @note Must be called before @ref nrf_crypto_hmac_update. Can also be called after
+ * @ref nrf_crypto_hmac_finalize order to start a new HMAC calculation re-using an
+ * existing context object.
+ *
+ * @param[in,out] p_context Pointer to context structure.
+ * @param[in] p_info Pointer to static info structure. This defines the algorithm.
+ * This should be either @ref g_nrf_crypto_hmac_sha256_info or
+ * @ref g_nrf_crypto_hmac_sha512_info.
+ * @param[in] p_key HMAC key.
+ * @param[in] key_size Length of the HMAC key in bytes.
+ *
+ * @retval NRF_SUCCESS Data successfully consumed.
+ * @retval NRF_ERROR_CRYPTO_CONTEXT_NULL If p_context has not been initialized.
+ * @retval NRF_ERROR_CRYPTO_INPUT_NULL If p_info or p_key was NULL.
+ * @retval NRF_ERROR_CRYPTO_INPUT_LENGTH If key_size was invalid.
+ * @retval NRF_ERROR_CRYPTO_INPUT_LOCATION Input data not in RAM (CC310 only).
+ * @retval NRF_ERROR_CRYPTO_INTERNAL An error occurred in the crypto backend.
+ * @retval NRF_ERROR_CRYPTO_BUSY The function could not be called because the
+ * nrf_crypto backend was busy. Please rerun
+ * the cryptographic routine at a later time.
+ * CC310 only.
+ */
+ret_code_t nrf_crypto_hmac_init(nrf_crypto_hmac_context_t * const p_context,
+ nrf_crypto_hmac_info_t const * p_info,
+ uint8_t const * p_key,
+ size_t key_size);
+
+
+/**
+ * @brief Feed data to HMAC algorithm.
+ *
+ * @note Must be called after @ref nrf_crypto_hmac_init and before @ref nrf_crypto_hmac_finalize.
+ * Can be called repeatedly to consume data as it arrives.
+ *
+ * @param[in,out] p_context Context pointer.
+ * @param[in] p_data Pointer to input data buffer.
+ * @param[in] data_size Length of input data.
+ *
+ * @retval NRF_SUCCESS Data successfully consumed.
+ * @retval NRF_ERROR_CRYPTO_CONTEXT_NULL If p_context has not been initialized.
+ * @retval NRF_ERROR_CRYPTO_CONTEXT_NOT_INITIALIZED If p_data was NULL.
+ * @retval NRF_ERROR_CRYPTO_INPUT_NULL If p_data was NULL.
+ * @retval NRF_ERROR_CRYPTO_INPUT_LENGTH If size was invalid.
+ * @retval NRF_ERROR_CRYPTO_INPUT_LOCATION Input data not in RAM (CC310 only).
+ * @retval NRF_ERROR_CRYPTO_INTERNAL An error occurred in the crypto backend.
+ * @retval NRF_ERROR_CRYPTO_BUSY The function could not be called because the
+ * nrf_crypto backend was busy. Please rerun
+ * the cryptographic routine at a later time.
+ * CC310 only.
+ */
+ret_code_t nrf_crypto_hmac_update(nrf_crypto_hmac_context_t * const p_context,
+ uint8_t const * p_data,
+ size_t data_size);
+
+
+/**
+ * @brief Calculate HMAC
+ *
+ * @note @ref nrf_crypto_hmac_update must be called at least once before calling this.
+ *
+ * @param[in,out] p_context Context pointer.
+ * @param[out] p_digest Pointer to HMAC digest (result) buffer. Must be large enough to
+ * hold the digest (32 byte for SHA-256 and 64 byte for SHA-512).
+ * @param[in,out] p_digest_size Length of buffer as input. Length of digest as output.
+ *
+ * @retval NRF_SUCCESS HMAC hash was successfully calculated.
+ * @retval NRF_ERROR_CRYPTO_CONTEXT_NULL If p_context was NULL.
+ * @retval NRF_ERROR_CRYPTO_CONTEXT_NOT_INITIALIZED If p_context has not been initialized.
+ * @retval NRF_ERROR_CRYPTO_OUTPUT_NULL If p_digest was NULL.
+ * @retval NRF_ERROR_CRYPTO_OUTPUT_LENGTH If p_size is not enough to hold the digest.
+ * @retval NRF_ERROR_CRYPTO_INTERNAL An error occurred in the crypto backend.
+ * @retval NRF_ERROR_CRYPTO_BUSY The function could not be called because the
+ * nrf_crypto backend was busy. Please rerun
+ * the cryptographic routine at a later time.
+ * CC310 only.
+ */
+ret_code_t nrf_crypto_hmac_finalize(nrf_crypto_hmac_context_t * const p_context,
+ uint8_t * p_digest,
+ size_t * const p_digest_size);
+
+
+/**
+ * @brief Integrated HMAC wrapper function
+ *
+ * @note This is an integrated wrapper functions that can be used instead of calling other HMAC
+ * functions individually.
+ *
+ * @param[in,out] p_context Optional pointer to context structure.
+ * Context memory will be allocated internally if the pointer is NULL.
+ * @param[in] p_info Pointer to static info structure. This defines the algorithm.
+ * This should be either @ref g_nrf_crypto_hmac_sha256_info or
+ * @ref g_nrf_crypto_hmac_sha512_info.
+ * @param[out] p_digest Pointer to HMAC digest.
+ * Buffer must be large enough to hold the digest.
+ * @param[in,out] p_digest_size Length of digest (result) buffer as input.
+ * Length of digest as output.
+ * @param[in] p_key Pointer to HMAC key.
+ * @param[in] key_size Lenth of the HMAC key in bytes.
+ * @param[in] p_data Pointer to input data.
+ * @param[in] data_size Length of input data.
+ *
+ * @retval NRF_SUCCESS HMAC hash was successfully calculated.
+ * @retval NRF_ERROR_CRYPTO_INPUT_NULL If p_key or p_data was NULL.
+ * @retval NRF_ERROR_CRYPTO_INPUT_LOCATION Input data not in RAM (CC310 only).
+ * @retval NRF_ERROR_CRYPTO_INPUT_LENGTH If key_size or data_size was invalid.
+ * @retval NRF_ERROR_CRYPTO_OUTPUT_NULL If data_size was NULL.
+ * @retval NRF_ERROR_CRYPTO_OUTPUT_LENGTH If data_size is not enough to hold the digest.
+ * @retval NRF_ERROR_CRYPTO_ALLOC_FAILED Unable to allocate memory for the context.
+ * @retval NRF_ERROR_CRYPTO_INTERNAL An error occurred in the crypto backend.
+ * @retval NRF_ERROR_CRYPTO_BUSY The function could not be called because the
+ * nrf_crypto backend was busy. Please rerun the
+ * cryptographic routine at a later time. CC310 only.
+ */
+ret_code_t nrf_crypto_hmac_calculate(nrf_crypto_hmac_context_t * const p_context,
+ nrf_crypto_hmac_info_t const * p_info,
+ uint8_t * p_digest,
+ size_t * const p_digest_size,
+ uint8_t const * p_key,
+ size_t key_size,
+ uint8_t const * p_data,
+ size_t data_size);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+/**@} */
+
+#endif // #ifndef NRF_CRYPTO_HMAC_H__
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/nrf_crypto_hmac_backend.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/nrf_crypto_hmac_backend.h
new file mode 100644
index 0000000..4547a8d
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/nrf_crypto_hmac_backend.h
@@ -0,0 +1,93 @@
+/**
+ * Copyright (c) 2018 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+
+#ifndef NRF_CRYPTO_HMAC_BACKEND_H__
+#define NRF_CRYPTO_HMAC_BACKEND_H__
+
+/** @file
+ *
+ * @defgroup nrf_crypto_hmac_backend Meta backend.
+ * @{
+ * @ingroup nrf_crypto_hmac
+ *
+ * @brief Includes all backends definitions.
+ *
+ * @details This file includes all backend definitions, and provide a dummy context in case no
+ * backend is enabled. This is needed so that any project including HMAC headers will still
+ * compile when HMAC is not used/enabled.
+ */
+
+#include "sdk_common.h"
+#include "nrf_crypto_hmac_shared.h"
+#include "mbedtls_backend_hmac.h"
+#include "cc310_backend_hmac.h"
+#include "oberon_backend_hmac.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+#ifndef NRF_CRYPTO_HMAC_SHA256_ENABLED
+// /** @internal @brief Fallback context type for HMAC SHA256 in case no backend is selected. */
+typedef nrf_crypto_hmac_internal_context_t nrf_crypto_backend_hmac_sha256_context_t;
+#endif // #ifndef NRF_CRYPTO_HMAC_SHA256_ENABLED
+
+#ifndef NRF_CRYPTO_HMAC_SHA512_ENABLED
+/** @internal @brief Fallback context type for HMAC SHA512 in case no backend is selected. */
+typedef nrf_crypto_hmac_internal_context_t nrf_crypto_backend_hmac_sha512_context_t;
+#endif // #ifndef NRF_CRYPTO_HMAC_SHA512_ENABLED
+
+
+/** @internal @brief Union holding a HMAC context. */
+typedef union
+{
+ nrf_crypto_backend_hmac_sha256_context_t hmac_sha256_context; /**< @brief Holds context for HMAC SHA-256. */
+ nrf_crypto_backend_hmac_sha512_context_t hmac_sha512_context; /**< @brief Holds context for HMAC SHA-512. */
+} nrf_crypto_backend_hmac_context_t;
+
+
+#ifdef __cplusplus
+}
+#endif
+
+/**@} */
+
+#endif // NRF_CRYPTO_HMAC_BACKEND_H__
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/nrf_crypto_hmac_shared.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/nrf_crypto_hmac_shared.h
new file mode 100644
index 0000000..c8527f6
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/nrf_crypto_hmac_shared.h
@@ -0,0 +1,150 @@
+/**
+ * Copyright (c) 2018 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+
+#ifndef NRF_CRYPTO_HMAC_SHARED_H__
+#define NRF_CRYPTO_HMAC_SHARED_H__
+
+/** @file
+ *
+ * @defgroup nrf_crypto_hmac_shared Types shared between all @ref nrf_crypto_hmac backends.
+ * @{
+ * @ingroup nrf_crypto_hmac
+ *
+ * @brief Types shared between all @ref nrf_crypto_hmac backends.
+ *
+ * @details These types should not be used directly by the application.
+ */
+
+#include <stdint.h>
+#include "sdk_common.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @internal @brief HMAC algorithm type.
+ */
+typedef enum {
+ NRF_CRYPTO_HMAC_SHA256_TYPE, //!< HMAC using hash algorithm SHA256
+ NRF_CRYPTO_HMAC_SHA512_TYPE, //!< HMAC using hash algorithm SHA512
+} nrf_crypto_hmac_type_t;
+
+
+/**
+ * @internal @brief Function pointer type for HMAC backend init function.
+ *
+ * @note The backend function should never be called directly.
+ * Use @ref nrf_crypto_hmac_init instead.
+ *
+ * @param[in,out] p_context Context pointer.
+ * @param[in] p_key HMAC key.
+ * @param[in] key_size Length of the HMAC key in bytes.
+*/
+typedef ret_code_t (*nrf_crypto_hmac_init_fn_t)(void * const p_context,
+ uint8_t const * p_key,
+ size_t key_size);
+
+
+/**
+ * @internal @brief Function pointer type for HMAC backend update function.
+ *
+ * @note The backend function should never be called directly.
+ * Use @ref nrf_crypto_hmac_update instead.
+ *
+ * @param[in,out] p_context Context pointer.
+ * @param[in] p_data Pointer to input data buffer.
+ * @param[in] size Length of input data.
+*/
+typedef ret_code_t (*nrf_crypto_hmac_update_fn_t)(void * const p_context,
+ uint8_t const * p_data,
+ size_t size);
+
+
+/**
+ * @internal @brief Function pointer type for HMAC backend finalize function.
+ *
+ * @note The backend function should never be called directly.
+ * Use @ref nrf_crypto_hmac_finalize instead.
+ *
+ * @param[in,out] p_context Context pointer.
+ * @param[out] p_digest HMAC digest (result) buffer.
+ * @param[in,out] p_size Length of buffer as input. Length of digest as output.
+*/
+typedef ret_code_t (*nrf_crypto_hmac_finalize_fn_t)(void * const p_context,
+ uint8_t * const p_digest,
+ size_t * p_size);
+
+
+/**
+ * @internal @brief structure holding the configuration of each particular algorithm.
+ *
+ * @details This is an internal type that should not be used directly.
+ */
+typedef struct
+{
+ nrf_crypto_hmac_init_fn_t const init_fn; //!< Pointer to update function for specific backend.
+ nrf_crypto_hmac_update_fn_t const update_fn; //!< Pointer to update function for specific backend.
+ nrf_crypto_hmac_finalize_fn_t const finalize_fn; //!< Pointer to finalize function for specific backend.
+ size_t const digest_size; //!< Size of the digest of the HMAC operation.
+ size_t const context_size; //!< Size of the context type.
+ nrf_crypto_hmac_type_t const type; //!< HMAC algorithm type.
+} nrf_crypto_hmac_info_t;
+
+
+/**
+ * @internal @brief Common header for each HMAC context structures
+ *
+ * @details This is an internal type that should not be used directly.
+ */
+typedef struct
+{
+ uint32_t init_value; //!< Contains NRF_CRYPTO_HMAC_INIT_MAGIC_VALUE if it is correctly initialized.
+ nrf_crypto_hmac_info_t const * p_info; //!< Points to information object related to selected algorithm.
+} nrf_crypto_hmac_internal_context_t;
+
+
+#ifdef __cplusplus
+}
+#endif
+
+/**@} */
+
+#endif // NRF_CRYPTO_HMAC_SHARED_H__
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/nrf_crypto_init.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/nrf_crypto_init.c
new file mode 100644
index 0000000..f86d5e2
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/nrf_crypto_init.c
@@ -0,0 +1,122 @@
+/**
+ * Copyright (c) 2016 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+
+#include "sdk_common.h"
+#if NRF_MODULE_ENABLED(NRF_CRYPTO)
+
+#include "nrf_crypto_init.h"
+#include "nrf_section.h"
+
+
+// Create a named section for crypto backend data
+NRF_SECTION_DEF(crypto_data, const nrf_crypto_backend_info_t);
+
+
+#define NRF_CRYPTO_BACKEND_SECTION_ITEM_GET(i) NRF_SECTION_ITEM_GET(crypto_data, nrf_crypto_backend_info_t, (i))
+#define NRF_CRYPTO_BACKEND_SECTION_ITEM_COUNT NRF_SECTION_ITEM_COUNT(crypto_data, nrf_crypto_backend_info_t)
+
+typedef enum
+{
+ UNINITIALIZED,
+ INITIALIZING,
+ INITIALIZED,
+} nrf_crypto_state_t;
+
+static volatile nrf_crypto_state_t m_state = UNINITIALIZED;
+
+
+ret_code_t nrf_crypto_init(void)
+{
+ ret_code_t ret_val;
+ size_t const num_backends = NRF_CRYPTO_BACKEND_SECTION_ITEM_COUNT;
+
+ m_state = INITIALIZING;
+
+ // Iterate through each backends to call the init function
+ for (size_t i = 0; i < num_backends; i++)
+ {
+ nrf_crypto_backend_info_t const * p_backend = NRF_CRYPTO_BACKEND_SECTION_ITEM_GET(i);
+ ret_val = p_backend->init_fn();
+ if (ret_val != NRF_SUCCESS)
+ {
+ return ret_val;
+ }
+ }
+
+ // Set nrf_crypto to initialized
+ m_state = INITIALIZED;
+ return NRF_SUCCESS;
+}
+
+
+ret_code_t nrf_crypto_uninit(void)
+{
+ ret_code_t ret_val;
+ size_t const num_backends = NRF_CRYPTO_BACKEND_SECTION_ITEM_COUNT;
+
+ // Iterate through each backends to call the uninit function
+ for (size_t i = 0; i < num_backends; i++)
+ {
+ nrf_crypto_backend_info_t const * p_backend = NRF_CRYPTO_BACKEND_SECTION_ITEM_GET(i);
+ ret_val = p_backend->uninit_fn();
+ if (ret_val != NRF_SUCCESS)
+ {
+ return ret_val;
+ }
+ }
+
+ // Set nrf_crypto to uninitialized
+ m_state = UNINITIALIZED;
+ return NRF_SUCCESS;
+}
+
+
+bool nrf_crypto_is_initialized(void)
+{
+ return (m_state == INITIALIZED);
+}
+
+
+bool nrf_crypto_is_initializing(void)
+{
+ return ((m_state == INITIALIZED) || m_state == INITIALIZING);
+}
+
+#endif // NRF_MODULE_ENABLED(NRF_CRYPTO)
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/nrf_crypto_init.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/nrf_crypto_init.h
new file mode 100644
index 0000000..a10fdde
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/nrf_crypto_init.h
@@ -0,0 +1,145 @@
+/**
+ * Copyright (c) 2018 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+
+#ifndef NRF_CRYPTO_INIT_H__
+#define NRF_CRYPTO_INIT_H__
+
+/** @file
+ *
+ * @defgroup nrf_crypto_initialization Initialization
+ * @{
+ * @ingroup nrf_crypto
+ *
+ * @brief Initialization related functions for nrf_crypto .
+ *
+ * @details @ref lib_crypto is responsible for global initialization of the nrf_crypto
+ * frontend and backends that are enabled in @ref sdk_config.
+ */
+
+#include <stdint.h>
+#include <stdbool.h>
+#include "nrf_section.h"
+#include "sdk_errors.h"
+#include "nrf_crypto_types.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+/**@internal @brief Macro for registering a nrf_crypto backend for initialization by using
+ * nrf_section.
+ *
+ * @details This macro places a variable in a section named "crypto_data", which
+ * is initialized by @ref nrf_crypto_init.
+ *
+ * @note This macro is used internally based on sdk_config.h configurations for nrf_crypto
+ */
+#define CRYPTO_BACKEND_REGISTER(crypto_var) NRF_SECTION_ITEM_REGISTER(crypto_data, crypto_var)
+
+/**@internal @brief Type definition of function pointer to initialize the nrf_crypto backend.
+ *
+ * This function type is used internally. See @nrf_crypto_init for documentation.
+ */
+typedef ret_code_t (*nrf_crypto_backend_init_fn_t)(void);
+
+
+/**@internal @brief Type definition of function pointer to uninitialize the nrf_crypto backend.
+ *
+ * This function type is used internally. Please see @nrf_crypto_uninit for documentation.
+ */
+typedef ret_code_t (*nrf_crypto_backend_uninit_fn_t)(void);
+
+
+
+/**@internal @brief Type definition for structure holding the calling interface to
+ * init, uninit, enable, or disable an nrf_crypto_backend
+ *
+ * @note Some backends require no expressive init, uninit, enable, or disable.
+ * In this case, the backend will not use this structure type or only select
+ * to implement
+ */
+typedef struct
+{
+ nrf_crypto_backend_init_fn_t const init_fn;
+ nrf_crypto_backend_uninit_fn_t const uninit_fn;
+} nrf_crypto_backend_info_t;
+
+
+/**@brief Function for initializing nrf_crypto and all registered backends.
+ *
+ * @details Must always be called before any other @ref nrf_crypto function.
+ *
+ * @retval NRF_SUCCESS The initialization was successful.
+ * @retval NRF_ERROR_INTERNAL An internal error occured in the nrf_crypt backend init.
+ */
+ret_code_t nrf_crypto_init(void);
+
+
+/**@brief Function for uninitializing nrf_crypto and all registered backends.
+ *
+ * @retval NRF_SUCCESS If unititialization was successful.
+ * @retval NRF_ERROR_INTERNAL If an internal error occured in the nrf_crypt backend init.
+ */
+ret_code_t nrf_crypto_uninit(void);
+
+
+/**@brief Function reporting if nrf_crypto has been initialized.
+ *
+ * @retval True If cryptographic library is initialized.
+ * @retval False If cryptographic library is not initialized.
+ */
+bool nrf_crypto_is_initialized(void);
+
+
+/**@brief Function reporting if nrf_crypto is initialized or is in the process of being initialized.
+ *
+ * @retval True If cryptographic library is initializing or already initialized.
+ * @retval False If cryptographic library is not initialized.
+ */
+bool nrf_crypto_is_initializing(void);
+
+#ifdef __cplusplus
+}
+#endif
+
+/**@} */
+
+#endif // NRF_CRYPTO_INIT_H__
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/nrf_crypto_mem.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/nrf_crypto_mem.h
new file mode 100644
index 0000000..0e2d163
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/nrf_crypto_mem.h
@@ -0,0 +1,185 @@
+/**
+ * Copyright (c) 2018 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+
+#ifndef NRF_CRYPTO_MEM_H__
+#define NRF_CRYPTO_MEM_H__
+
+/** @file
+ *
+ * @defgroup nrf_crypto_mem Dynamic memory management module
+ * @{
+ * @ingroup nrf_crypto
+ *
+ * @brief Module to manage dynamically allocated memory used by nrf_crypto APIs.
+ *
+ * @ref NRF_CRYPTO_ALLOCATOR definition is used to configure this module.
+ */
+
+#include <stdint.h>
+#include "sdk_common.h"
+#include "sdk_config.h"
+#include "nrf_crypto_types.h"
+#include "sdk_alloca.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+#ifndef __SDK_DOXYGEN__
+
+
+#define NRF_CRYPTO_ALLOCATOR_DEFAULT 0 /**< @internal @brief Value for NRF_CRYPTO_ALLOCATOR to select default memory allocation. */
+#define NRF_CRYPTO_ALLOCATOR_USER 1 /**< @internal @brief Value for NRF_CRYPTO_ALLOCATOR to select user defined memory allocation. */
+#define NRF_CRYPTO_ALLOCATOR_ALLOCA 2 /**< @internal @brief Value for NRF_CRYPTO_ALLOCATOR to select stack based memory allocation. */
+#define NRF_CRYPTO_ALLOCATOR_MALLOC 3 /**< @internal @brief Value for NRF_CRYPTO_ALLOCATOR to select stdlib's dynamic memory allocation. */
+#define NRF_CRYPTO_ALLOCATOR_NRF_MALLOC 4 /**< @internal @brief Value for NRF_CRYPTO_ALLOCATOR to select mem_manager for memory allocation. */
+
+
+#ifndef NRF_CRYPTO_ALLOCATOR
+#define NRF_CRYPTO_ALLOCATOR NRF_CRYPTO_ALLOCATOR_DEFAULT
+#endif
+
+
+#if NRF_CRYPTO_ALLOCATOR == NRF_CRYPTO_ALLOCATOR_DEFAULT
+#undef NRF_CRYPTO_ALLOCATOR
+#if SDK_ALLOCA_DEFINED && !NRF_MODULE_ENABLED(NRF_CRYPTO_BACKEND_MBEDTLS)
+#define NRF_CRYPTO_ALLOCATOR NRF_CRYPTO_ALLOCATOR_ALLOCA
+#else
+#define NRF_CRYPTO_ALLOCATOR NRF_CRYPTO_ALLOCATOR_NRF_MALLOC
+#endif
+#endif
+
+
+#if NRF_CRYPTO_ALLOCATOR == NRF_CRYPTO_ALLOCATOR_USER
+
+#include "nrf_crypto_allocator.h"
+#ifndef NRF_CRYPTO_ALLOC
+#error "User defined allocator for nrf_crypto does not define NRF_CRYPTO_ALLOC"
+#endif
+#ifndef NRF_CRYPTO_FREE
+#error "User defined allocator for nrf_crypto does not define NRF_CRYPTO_FREE"
+#endif
+#ifndef NRF_CRYPTO_ALLOC_ON_STACK
+#error "User defined allocator for nrf_crypto does not define NRF_CRYPTO_ALLOC_ON_STACK"
+#endif
+
+#elif NRF_CRYPTO_ALLOCATOR == NRF_CRYPTO_ALLOCATOR_ALLOCA
+
+#if !SDK_ALLOCA_DEFINED
+#warning "Stack based allocation is selected, but alloca() is not supported on this platform"
+#endif
+#define NRF_CRYPTO_ALLOC(size) (alloca((size_t)(size)))
+#define NRF_CRYPTO_FREE(p_buffer) // Empty
+#define NRF_CRYPTO_ALLOC_ON_STACK 1
+
+#elif NRF_CRYPTO_ALLOCATOR == NRF_CRYPTO_ALLOCATOR_MALLOC
+
+#include "stdlib.h"
+#define NRF_CRYPTO_ALLOC(size) (malloc((size_t)(size)))
+#define NRF_CRYPTO_FREE(p_buffer) (free((void *)(p_buffer)))
+#define NRF_CRYPTO_ALLOC_ON_STACK 0
+
+#elif NRF_CRYPTO_ALLOCATOR == NRF_CRYPTO_ALLOCATOR_NRF_MALLOC
+
+#include "mem_manager.h"
+#define NRF_CRYPTO_ALLOC(size) (nrf_malloc((uint32_t)(size)))
+#define NRF_CRYPTO_FREE(p_buffer) (nrf_free((void *)(p_buffer)))
+#define NRF_CRYPTO_ALLOC_ON_STACK 0
+
+#else
+
+#error "Invalid NRF_CRYPTO_ALLOCATOR configuration value"
+
+#endif
+
+
+#else // __SDK_DOXYGEN__
+
+
+/** @brief Defines memory allocation function for nrf_crypto.
+ *
+ * This macro is used internally by nrf_crypto library to allocate temporary memory. It is not
+ * intended to be used outside nrf_crypto library. How memory is actually allocated is configured
+ * by @ref NRF_CRYPTO_ALLOCATOR definition.
+ *
+ * If user macros are selected by @ref NRF_CRYPTO_ALLOCATOR then this macro have to be defined by
+ * the user in "nrf_crypto_allocator.h" file. The file will be included into "nrf_crypto_mem.h".
+ *
+ * If @ref NRF_CRYPTO_ALLOC_ON_STACK is 1 then this function will allocate data on stack,
+ * so make sure that returned pointer is not used outside the caller function.
+ *
+ * @param size Number of bytes to allocate.
+ * @returns Pointer to newly allocated memory or NULL on error.
+ */
+#define NRF_CRYPTO_ALLOC(size)
+
+/** @brief Defines memory deallocation function for nrf_crypto.
+ *
+ * This macro is used internally by nrf_crypto library to deallocate temporary memory. It is not
+ * intended to be used outside nrf_crypto library.
+ *
+ * If user macros are selected by @ref NRF_CRYPTO_ALLOCATOR then this macro have to be defined by
+ * the user in "nrf_crypto_allocator.h" file. The file will be included into "nrf_crypto_mem.h".
+ *
+ * @param p_buffer Pointer to memory buffer for deallocation.
+ */
+#define NRF_CRYPTO_FREE(p_buffer)
+
+/** @brief Contains 1 if memory allocated by @ref NRF_CRYPTO_ALLOC is on stack or 0 otherwise.
+ *
+ * This definition is used internally by nrf_crypto library. It is not intended to be used outside
+ * nrf_crypto library.
+ *
+ * If user macros are selected by @ref NRF_CRYPTO_ALLOCATOR then this macro have to be defined by
+ * the user in "nrf_crypto_allocator.h" file. The file will be included into "nrf_crypto_mem.h".
+ */
+#define NRF_CRYPTO_ALLOC_ON_STACK
+
+
+#endif // __SDK_DOXYGEN__
+
+#ifdef __cplusplus
+}
+#endif
+
+/**@} */
+
+ #endif // NRF_CRYPTO_MEM_H__
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/nrf_crypto_rng.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/nrf_crypto_rng.c
new file mode 100644
index 0000000..97532a5
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/nrf_crypto_rng.c
@@ -0,0 +1,430 @@
+/**
+ * Copyright (c) 2018 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+
+#include "sdk_common.h"
+#if NRF_MODULE_ENABLED(NRF_CRYPTO)
+
+#include "nrf_crypto_init.h"
+#include "nrf_log.h"
+#include "nrf_crypto_mem.h"
+#include "nrf_crypto_rng.h"
+#include "nrf_crypto_rng_shared.h"
+#include "nrf_crypto_rng_backend.h"
+#include "nrf_stack_info.h"
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_RNG)
+
+#define NRF_CRYPTO_RNG_MODULE_INIT_MAGIC_VALUE (0x4be57265)
+
+static nrf_crypto_backend_rng_context_t * mp_allocated_context = NULL;
+static nrf_crypto_backend_rng_context_t * mp_context = NULL;
+static uint32_t m_initialized = 0;
+
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_RNG_STATIC_MEMORY_BUFFERS)
+static nrf_crypto_backend_rng_context_t m_context;
+static nrf_crypto_rng_temp_buffer_t m_temp_buffer;
+#endif // NRF_MODULE_ENABLED(NRF_CRYPTO_RNG_STATIC_MEMORY_BUFFERS)
+
+
+static bool is_vector_greater_or_equal(uint8_t const * const p_vector,
+ uint8_t const * const p_min,
+ size_t size)
+{
+ for (size_t i = 0; i < size; i++)
+ {
+ if (p_vector[i] != p_min[i])
+ {
+ if (p_vector[i] > p_min[i])
+ {
+ return true;
+ }
+ else
+ {
+ return false;
+ }
+ }
+ }
+
+ return true;
+}
+
+
+// Return true if value p_vector is between (including) p_min and p_max.
+static bool is_vector_in_range(uint8_t const * const p_vector,
+ uint8_t const * const p_min,
+ uint8_t const * const p_max,
+ size_t size)
+{
+ if (!is_vector_greater_or_equal(p_vector, p_min, size))
+ {
+ return false;
+ }
+
+ if (!is_vector_greater_or_equal(p_max, p_vector, size))
+ {
+ return false;
+ }
+
+ return true;
+}
+
+
+static uint32_t count_leading_zeros(uint8_t const * const p_vector, size_t size)
+{
+ uint32_t leading_zeros = 0;
+ uint32_t nonzero_byte = 0xFF;
+
+ // Find leading all-zero elements.
+ for (uint32_t i = 0; i < size; i++)
+ {
+ if (p_vector[i] == 0)
+ {
+ leading_zeros += 8;
+ }
+ else
+ {
+ nonzero_byte = p_vector[i];
+ break;
+ }
+ }
+
+ // Find leading zeros in non-zero element.
+ for (uint32_t i = 0; i < 8; i++)
+ {
+ nonzero_byte <<= 1;
+
+ if ((nonzero_byte & ~0xff) > 0)
+ {
+ break;
+ }
+
+ leading_zeros ++;
+ }
+
+ return leading_zeros;
+}
+
+
+static ret_code_t generate(uint8_t * const p_target, size_t size, bool use_mutex)
+{
+ ret_code_t ret_code;
+
+ VERIFY_TRUE(p_target != NULL, NRF_ERROR_CRYPTO_OUTPUT_NULL);
+ VERIFY_TRUE(size > 0, NRF_ERROR_CRYPTO_OUTPUT_LENGTH);
+
+ VERIFY_TRUE(m_initialized == NRF_CRYPTO_RNG_MODULE_INIT_MAGIC_VALUE,
+ NRF_ERROR_CRYPTO_CONTEXT_NOT_INITIALIZED);
+
+ ret_code = nrf_crypto_rng_backend_vector_generate(mp_context, p_target, size, use_mutex);
+
+ // Reseed internally and try again if reseed is required by the backend.
+ // (CC310 only as mbed TLS handles reseeding internally.)
+ if (ret_code == NRF_ERROR_CRYPTO_RNG_RESEED_REQUIRED)
+ {
+ ret_code = nrf_crypto_rng_reseed(NULL, NULL, 0);
+
+ if (ret_code != NRF_SUCCESS)
+ {
+ return ret_code;
+ }
+
+ ret_code = nrf_crypto_rng_backend_vector_generate(mp_context, p_target, size, use_mutex);
+ }
+
+ return ret_code;
+}
+
+
+static ret_code_t generate_in_range(uint8_t * const p_target,
+ uint8_t const * const p_min,
+ uint8_t const * const p_max,
+ size_t size,
+ bool use_mutex)
+{
+ uint32_t const max_leading_zeros = count_leading_zeros(p_max, size);
+ ret_code_t ret_code;
+
+ VERIFY_TRUE(p_target != NULL, NRF_ERROR_CRYPTO_OUTPUT_NULL);
+ VERIFY_TRUE(size > 0, NRF_ERROR_CRYPTO_OUTPUT_LENGTH);
+ VERIFY_TRUE(p_min != NULL, NRF_ERROR_CRYPTO_INPUT_NULL);
+ VERIFY_TRUE(p_max != NULL, NRF_ERROR_CRYPTO_INPUT_NULL);
+ VERIFY_TRUE(is_vector_greater_or_equal(p_max, p_min, size), NRF_ERROR_CRYPTO_INVALID_PARAM);
+
+ do
+ {
+ ret_code = nrf_crypto_rng_backend_vector_generate(mp_context, p_target, size, use_mutex);
+
+ if (ret_code != NRF_SUCCESS)
+ {
+ return ret_code;
+ }
+
+ // Mask leading zeros in generated vector instead of always discarding a too large vectors.
+ memset(p_target, 0, max_leading_zeros / 8);
+ if ((max_leading_zeros & 0x07) > 0)
+ {
+ p_target[max_leading_zeros / 8] =
+ p_target[max_leading_zeros / 8] & (0xff >> (max_leading_zeros & 0x07));
+ }
+ } while (!is_vector_in_range(p_target, p_min, p_max, size));
+
+ return NRF_SUCCESS;
+}
+
+
+ret_code_t nrf_crypto_rng_vector_generate(uint8_t * const p_target, size_t size)
+{
+ ret_code_t ret_code;
+
+ ret_code = generate(p_target, size, true);
+
+ return ret_code;
+}
+
+
+ret_code_t nrf_crypto_rng_vector_generate_in_range(uint8_t * const p_target,
+ uint8_t const * const p_min,
+ uint8_t const * const p_max,
+ size_t size)
+{
+ ret_code_t ret_code;
+
+ ret_code = generate_in_range(p_target, p_min, p_max, size, true);
+
+ return ret_code;
+}
+
+
+ret_code_t nrf_crypto_rng_vector_generate_no_mutex(uint8_t * const p_target, size_t size)
+{
+ ret_code_t ret_code;
+
+ ret_code = generate(p_target, size, false);
+
+ return ret_code;
+}
+
+
+ret_code_t nrf_crypto_rng_vector_generate_in_range_no_mutex(uint8_t * const p_target,
+ uint8_t const * const p_min,
+ uint8_t const * const p_max,
+ size_t size)
+{
+ ret_code_t ret_code;
+
+ ret_code = generate_in_range(p_target, p_min, p_max, size, false);
+
+ return ret_code;
+}
+
+
+ret_code_t nrf_crypto_rng_init(nrf_crypto_rng_context_t * p_context,
+ nrf_crypto_rng_temp_buffer_t * p_temp_buffer)
+{
+ ret_code_t ret_code;
+ nrf_crypto_rng_temp_buffer_t * p_allocated_temp_buffer = NULL;
+
+ // Check if the stack has overflowed. This can typically happen if the application has put the
+ // ~6 kB large temp buffer for CC310 on the stack.
+ if (nrf_stack_info_overflowed())
+ {
+ NRF_LOG_ERROR("Stack overflow detected.");
+ return NRF_ERROR_CRYPTO_STACK_OVERFLOW;
+ }
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_RNG_AUTO_INIT)
+ VERIFY_TRUE(nrf_crypto_is_initializing(), NRF_ERROR_CRYPTO_NOT_INITIALIZED);
+#else
+ VERIFY_TRUE(nrf_crypto_is_initialized(), NRF_ERROR_CRYPTO_NOT_INITIALIZED);
+#endif // NRF_MODULE_ENABLED(NRF_CRYPTO_RNG_AUTO_INIT)
+
+ // Do nothing if RNG module is already initialized.
+ if (mp_context != 0 && (m_initialized == NRF_CRYPTO_RNG_MODULE_INIT_MAGIC_VALUE))
+ {
+ return NRF_SUCCESS;
+ }
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_RNG_STATIC_MEMORY_BUFFERS)
+
+ VERIFY_TRUE(p_context == NULL, NRF_ERROR_CRYPTO_INVALID_PARAM);
+ VERIFY_TRUE(p_temp_buffer == NULL, NRF_ERROR_CRYPTO_INVALID_PARAM);
+
+ mp_context = &m_context;
+ p_temp_buffer = &m_temp_buffer;
+
+#else // !NRF_MODULE_ENABLED(NRF_CRYPTO_RNG_STATIC_MEMORY_BUFFERS)
+
+ if (p_context == NULL)
+ {
+ if (NRF_CRYPTO_ALLOC_ON_STACK)
+ {
+ NRF_LOG_ERROR("RNG context cannot be allocated on the stack.");
+ return NRF_ERROR_CRYPTO_ALLOC_FAILED;
+ }
+ else
+ {
+ mp_allocated_context = NRF_CRYPTO_ALLOC(sizeof(nrf_crypto_backend_rng_context_t));
+ if (mp_allocated_context == NULL)
+ {
+ return NRF_ERROR_CRYPTO_ALLOC_FAILED;
+ }
+ mp_context = mp_allocated_context;
+ }
+ }
+ else
+ {
+ mp_context = p_context;
+ }
+
+#endif // NRF_MODULE_ENABLED(NRF_CRYPTO_RNG_STATIC_MEMORY_BUFFERS)
+
+ // Allocate temporary buffer internally if not statically allocated or provided by the user.
+ if (p_temp_buffer == NULL)
+ {
+ p_allocated_temp_buffer = NRF_CRYPTO_ALLOC(sizeof(nrf_crypto_rng_temp_buffer_t));
+
+ if (p_allocated_temp_buffer == NULL)
+ {
+ if (mp_allocated_context != NULL)
+ {
+ NRF_CRYPTO_FREE(mp_allocated_context);
+ }
+
+ return NRF_ERROR_CRYPTO_ALLOC_FAILED;
+ }
+
+ p_temp_buffer = p_allocated_temp_buffer;
+ }
+
+ ret_code = nrf_crypto_rng_backend_init(mp_context, p_temp_buffer);
+ if (ret_code == NRF_SUCCESS)
+ {
+ m_initialized = NRF_CRYPTO_RNG_MODULE_INIT_MAGIC_VALUE;
+ mp_context->header.init_value = NRF_CRYPTO_RNG_CONTEXT_INIT_MAGIC_VALUE;
+ }
+
+ if (p_allocated_temp_buffer != NULL)
+ {
+ NRF_CRYPTO_FREE(p_allocated_temp_buffer);
+ }
+
+ return ret_code;
+}
+
+
+ret_code_t nrf_crypto_rng_uninit(void)
+{
+ ret_code_t ret_code;
+
+ VERIFY_TRUE(m_initialized == NRF_CRYPTO_RNG_MODULE_INIT_MAGIC_VALUE,
+ NRF_ERROR_CRYPTO_CONTEXT_NOT_INITIALIZED);
+
+ VERIFY_TRUE(mp_context->header.init_value == NRF_CRYPTO_RNG_CONTEXT_INIT_MAGIC_VALUE,
+ NRF_ERROR_CRYPTO_CONTEXT_NOT_INITIALIZED);
+
+ mp_context->header.init_value = 0;
+ m_initialized = 0;
+
+ ret_code = nrf_crypto_rng_backend_uninit(mp_context);
+
+ if (mp_allocated_context != NULL)
+ {
+ NRF_CRYPTO_FREE(mp_allocated_context);
+ }
+
+ return ret_code;
+}
+
+
+ret_code_t nrf_crypto_rng_reseed(nrf_crypto_rng_temp_buffer_t * p_temp_buffer,
+ uint8_t * p_input_data,
+ size_t size)
+{
+ ret_code_t ret_code;
+ void * p_allocated_temp_buffer = NULL;
+
+ // Check if the stack has overflowed. This can typically happen if the application has put the
+ // ~6 kB large temp buffer for CC310 on the stack.
+ if (nrf_stack_info_overflowed())
+ {
+ NRF_LOG_ERROR("Stack overflow detected.");
+ return NRF_ERROR_CRYPTO_STACK_OVERFLOW;
+ }
+
+ if (size > 0)
+ {
+ VERIFY_TRUE(p_input_data != NULL, NRF_ERROR_CRYPTO_INPUT_NULL);
+ }
+
+ VERIFY_TRUE(m_initialized == NRF_CRYPTO_RNG_MODULE_INIT_MAGIC_VALUE,
+ NRF_ERROR_CRYPTO_CONTEXT_NOT_INITIALIZED);
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO_RNG_STATIC_MEMORY_BUFFERS)
+
+ VERIFY_TRUE(p_temp_buffer == NULL, NRF_ERROR_CRYPTO_INVALID_PARAM);
+ p_temp_buffer = &m_temp_buffer;
+
+#endif // NRF_MODULE_ENABLED(NRF_CRYPTO_RNG_STATIC_MEMORY_BUFFERS)
+
+ // Allocate temporary buffer internally if not statically allocated or provided by the user.
+ if (p_temp_buffer == NULL)
+ {
+ p_allocated_temp_buffer = NRF_CRYPTO_ALLOC(sizeof(nrf_crypto_rng_temp_buffer_t));
+ if (p_allocated_temp_buffer == NULL)
+ {
+ return NRF_ERROR_CRYPTO_ALLOC_FAILED;
+ }
+ p_temp_buffer = (nrf_crypto_rng_temp_buffer_t *)p_allocated_temp_buffer;
+ }
+
+ ret_code = nrf_crypto_rng_backend_reseed(mp_context, p_temp_buffer, p_input_data, size);
+
+ if (p_allocated_temp_buffer != NULL)
+ {
+ NRF_CRYPTO_FREE(p_allocated_temp_buffer);
+ }
+
+ return ret_code;
+}
+
+
+#endif // NRF_MODULE_ENABLED(NRF_CRYPTO_RNG)
+#endif // NRF_MODULE_ENABLED(NRF_CRYPTO)
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/nrf_crypto_rng.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/nrf_crypto_rng.h
new file mode 100644
index 0000000..bb50218
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/nrf_crypto_rng.h
@@ -0,0 +1,285 @@
+/**
+ * Copyright (c) 2018 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+
+#ifndef NRF_CRYPTO_RNG_H__
+#define NRF_CRYPTO_RNG_H__
+
+/** @file
+ *
+ * @defgroup nrf_crypto_rng RNG related functions
+ * @{
+ * @ingroup nrf_crypto
+ *
+ * @brief RNG related functions
+ *
+ * @details There are two available RNG backends:
+ * - ARM CryptoCell CC310 (default for devices with CC310).
+ * - nRF HW RNG peripheral.
+ * * CTR-DRBG mode - nRF HW RNG used for seeding mbed TLS CTR-DRBG (default for
+ * devices without CC310).
+ * * Raw mode - all data is generated by the nRF HW RNG.
+ *
+ * The CC310 backend meets the standards NIST 800-90B3 and AIS-31 (Class “P2 Highâ€), and
+ * should be preferred in most cases on devices that includes the CC310 core. Devices that
+ * do not include CC310 should normally use the nRF HW RNG with mbed TLS CTR-DRBG. The
+ * mbed TLS CTR-DRBG code is standardized by NIST (SP 800-90A Rev. 1).
+ */
+
+#include "sdk_common.h"
+#include "nrf_crypto_error.h"
+#include "nrf_crypto_rng_shared.h"
+#include "nrf_crypto_rng_backend.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+/**
+ * @brief Context type for RNG.
+ *
+ * @note The actual type depend on the backend in use.
+ */
+typedef nrf_crypto_backend_rng_context_t nrf_crypto_rng_context_t;
+
+
+/**
+ * @brief Temporary work buffer type for RNG.
+ *
+ * @details Only needed during initializing. Can be freed when @ref nrf_crypto_rng_init has
+ * returned. Not needed if @ref NRF_CRYPTO_RNG_STATIC_MEMORY_BUFFERS_ENABLED is enabled
+ * in @ref sdk_config.
+ *
+ * @note The actual type depend on the backend in use.
+ */
+typedef nrf_crypto_backend_rng_temp_buffer_t nrf_crypto_rng_temp_buffer_t;
+
+
+/**@brief Initialize the random number generator.
+ *
+ * @details This function has no effect when @ref NRF_CRYPTO_RNG_AUTO_INIT_ENABLED is enabled.
+ *
+ * @warning The p_temp_buffer is 6112 bytes when using the CC310 backend. Ensure that stack size
+ * is sufficient if allocated on stack. Applications that use nRF HW RNG as backend or are
+ * not RAM constrained can use internal static allocation of context and temporary buffers
+ * (@ref NRF_CRYPTO_RNG_STATIC_MEMORY_BUFFERS_ENABLED).
+ *
+ * @note The context object can be reused without the need for a full reinitialization of the
+ * backend in case of for example wakeup from system OFF, provided that the context is
+ * located in a memory block that is retained. This only apply to the CC310 backend, and when
+ * the context is allocated manually (NRF_CRYPTO_RNG_STATIC_MEMORY_BUFFERS_ENABLED disabled).
+ *
+ * @param[in] p_context Pointer to context memory. The context will be managed
+ * internally, and the pointer is not used for subsequent calls to
+ * the nrf_crypto_rng API. The context memory is needed until
+ * @ref nrf_crypto_rng_uninit is called, so it should normally not
+ * be on the stack. Use NULL if
+ * @ref NRF_CRYPTO_RNG_STATIC_MEMORY_BUFFERS_ENABLED is enabled
+ * in @ref sdk_config (recommended for most applications).
+ *
+ * @param[in,out] p_temp_buffer Temporary buffer needed during initialization of the backend. It
+ * is not used after the return of this function, and can be freed
+ * at that point. Buffer is allocated internally if the pointer is
+ * NULL, using the allocated defined by @ref NRF_CRYPTO_ALLOCATOR
+ * in @c sdk_config.h. Use NULL if
+ * @ref NRF_CRYPTO_RNG_STATIC_MEMORY_BUFFERS_ENABLED is enabled
+ * in @ref sdk_config (recommended for most applications).
+ *
+ * @retval NRF_SUCCESS If random number generator was initialized
+ * successfully.
+ * @retval NRF_ERROR_CRYPTO_NOT_INITIALIZED @ref nrf_crypto_init was not called prior to this
+ * function.
+ * @retval NRF_ERROR_CRYPTO_CONTEXT_NULL p_context was NULL.
+ * @retval NRF_ERROR_CRYPTO_INTERNAL If an internal error occurred in the nrf_crypto
+ * backend.
+ * @retval NRF_ERROR_CRYPTO_ALLOC_FAILED Unable to allocate memory for the context or work
+ * buffer.
+ * @retval NRF_ERROR_CRYPTO_STACK_OVERFLOW Stack overflow detected. Typically caused by
+ * allocating an instance of
+ * @ref nrf_crypto_rng_temp_buffer_t
+ * on the stack when using CC310 backend.
+ * @retval NRF_ERROR_CRYPTO_BUSY RNG is busy. Rerun at a later time.
+ */
+ret_code_t nrf_crypto_rng_init(nrf_crypto_rng_context_t * p_context,
+ nrf_crypto_rng_temp_buffer_t * p_temp_buffer);
+
+
+/**@brief Uninitialize the random number generator.
+ *
+ * @retval NRF_SUCCESS If RNG was uninitialized successfully.
+ * @retval NRF_ERROR_CRYPTO_CONTEXT_NOT_INITIALIZED RNG has not been initialized.
+ * @retval NRF_ERROR_CRYPTO_INTERNAL If an internal error occurred in the
+ * nrf_crypto backend.
+ * @retval NRF_ERROR_CRYPTO_BUSY RNG is busy. Rerun at a later time.
+ */
+ret_code_t nrf_crypto_rng_uninit(void);
+
+
+/**@brief Generate random data of given size.
+ *
+ * @details @ref nrf_crypto_rng_init must be called prior to this function unless
+ * @ref NRF_CRYPTO_RNG_AUTO_INIT_ENABLED is enabled in @ref sdk_config.
+ *
+ * @param[in,out] p_target Buffer to hold the random generated data.
+ * This buffer must be at least as large as the size parameter.
+ * @param[in] size Length (in bytes) to generate random data for.
+ *
+ * @retval NRF_SUCCESS Data was generated successfully.
+ * @retval NRF_ERROR_CRYPTO_NOT_INITIALIZED @ref nrf_crypto_init was not called prior to
+ * this function.
+ * @retval NRF_ERROR_CRYPTO_CONTEXT_NOT_INITIALIZED @ref nrf_crypto_rng_init was not called
+ * prior to this function and
+ * @ref NRF_CRYPTO_RNG_AUTO_INIT_ENABLED is
+ * disabled.
+ * @retval NRF_ERROR_CRYPTO_OUTPUT_NULL p_target was NULL.
+ * @retval NRF_ERROR_CRYPTO_OUTPUT_LENGTH Size was 0 or larger than the backend
+ * supports.
+ * @retval NRF_ERROR_CRYPTO_INTERNAL If an internal error occurred in the
+ * backend.
+ * @retval NRF_ERROR_CRYPTO_STACK_OVERFLOW Stack overflow detected in
+ * @ref nrf_crypto_rng_init when using auto
+ * initialization. Typically caused by
+ * allocating an instance of
+ * @ref nrf_crypto_rng_temp_buffer_t
+ * on the stack when using CC310 backend.
+ * @retval NRF_ERROR_CRYPTO_BUSY RNG is busy. Rerun at a later time.
+ */
+ret_code_t nrf_crypto_rng_vector_generate(uint8_t * const p_target, size_t size);
+
+
+/**@brief Generate a vector of constrained random data of given size, between the specified min
+ * and max values.
+ *
+ * @details @ref nrf_crypto_rng_init must be called prior to this function unless
+ * @ref NRF_CRYPTO_RNG_AUTO_INIT_ENABLED is enabled in @ref sdk_config.
+ *
+ * All vectors are in big-endian format, with the most significant byte as the first
+ * element / lowest address.
+ *
+ * @note This function may execute for a long time if the window between p_min and p_max is small.
+ *
+ * @param[in,out] p_target Buffer to hold the random generated data.
+ * This buffer must be at least as large as the size parameter.
+ * @param[in] p_min Byte array defining the lower limit of the random vector.
+ * @param[in] p_max Byte array defining the upper limit of the random vector.
+ * @param[in] size Length (in bytes) to generate random data for. Note that all three
+ * buffers (p_target, p_min and p_max) must be of this size.
+ *
+ * @retval NRF_SUCCESS Data was generated successfully.
+ * @retval NRF_ERROR_CRYPTO_NOT_INITIALIZED @ref nrf_crypto_init was not called prior to
+ * this function.
+ * @retval NRF_ERROR_CRYPTO_CONTEXT_NOT_INITIALIZED @ref nrf_crypto_rng_init was not called
+ * prior to this function and
+ * @ref NRF_CRYPTO_RNG_AUTO_INIT_ENABLED is
+ * disabled.
+ * @retval NRF_ERROR_CRYPTO_OUTPUT_NULL p_target was NULL.
+ * @retval NRF_ERROR_CRYPTO_INPUT_NULL p_min or p_max was NULL.
+ * @retval NRF_ERROR_CRYPTO_OUTPUT_LENGTH Size was 0 or larger than the backend
+ * supports.
+ * @retval NRF_ERROR_CRYPTO_INTERNAL If an internal error occurred in the
+ * backend.
+ * @retval NRF_ERROR_CRYPTO_STACK_OVERFLOW Stack overflow detected in
+ * @ref nrf_crypto_rng_init when using auto
+ * initialization. Typically caused by
+ * allocating an instance of
+ * @ref nrf_crypto_rng_temp_buffer_t
+ * on the stack when using CC310 backend.
+ * @retval NRF_ERROR_CRYPTO_BUSY RNG is busy. Rerun at a later time.
+ */
+ret_code_t nrf_crypto_rng_vector_generate_in_range(uint8_t * const p_target,
+ uint8_t const * const p_min,
+ uint8_t const * const p_max,
+ size_t size);
+
+
+/**
+ * @brief This function is used for reseeding the RNG with additional entropy.
+ *
+ * @details The backends will reseed automatically when required. This function can be used to
+ * reseed at specific times and to provide additional data that is used to add personalized
+ * randomness.
+ *
+ * @note Reseeding is not supported if using the nRF HW RNG backend without mbed TLS CTR-DRBG
+ * (NRF_CRYPTO_BACKEND_NRF_HW_RNG_MBEDTLS_CTR_DRBG_ENABLED disabled in sdk_config.h).
+ *
+ * @warning The p_temp_buffer is 6112 bytes when the CC310 backend is used. Ensure that stack size
+ * is sufficient if allocated on stack.
+ *
+ * @param[in,out] p_temp_buffer Temporary buffer needed during reseeding. It
+ * is not used after the return of this function, and can be freed
+ * at that point. Buffer is allocated internally if the pointer is
+ * NULL, using the allocated defined by @ref NRF_CRYPTO_ALLOCATOR
+ * in @c sdk_config.h. Use NULL if
+ * @ref NRF_CRYPTO_RNG_STATIC_MEMORY_BUFFERS_ENABLED is enabled
+ * in @ref sdk_config (recommended for most applications).
+ * @param[in] p_input_data Optional input data used to increase the entropy.
+ * @param[in] size Length of input data. Must be 0, 4, 8 or 12 for CC310.
+ *
+ * @retval NRF_SUCCESS Data was generated successfully.
+ * @retval NRF_ERROR_CRYPTO_NOT_INITIALIZED @ref nrf_crypto_init was not called prior to
+ * this function.
+ * @retval NRF_ERROR_CRYPTO_CONTEXT_NOT_INITIALIZED @ref nrf_crypto_rng_init was not called
+ * prior to this function and
+ * @ref NRF_CRYPTO_RNG_AUTO_INIT_ENABLED is
+ * disabled.
+ * @retval NRF_ERROR_CRYPTO_INPUT_NULL p_temp_buffer was NULL or p_input_data was
+ * NULL and size > 0 .
+ * @retval NRF_ERROR_CRYPTO_INPUT_LENGTH Invalid input data size.
+ * @retval NRF_ERROR_CRYPTO_FEATURE_UNAVAILABLE Reseeding not supported by backend.
+ * @retval NRF_ERROR_CRYPTO_INTERNAL If an internal error occurred in the
+ * backend.
+ * @retval NRF_ERROR_CRYPTO_STACK_OVERFLOW Stack overflow detected. Typically caused by
+ * allocating an instance of
+ * @ref nrf_crypto_rng_temp_buffer_t
+ * on the stack when using CC310 backend.
+ * @retval NRF_ERROR_CRYPTO_BUSY RNG is busy. Rerun at a later time.
+ */
+ret_code_t nrf_crypto_rng_reseed(nrf_crypto_rng_temp_buffer_t * p_temp_buffer,
+ uint8_t * p_input_data,
+ size_t size);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+/**@} */
+
+#endif // NRF_CRYPTO_RNG_H__
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/nrf_crypto_rng_backend.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/nrf_crypto_rng_backend.h
new file mode 100644
index 0000000..0fd900f
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/nrf_crypto_rng_backend.h
@@ -0,0 +1,82 @@
+/**
+ * Copyright (c) 2018 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+
+#ifndef NRF_CRYPTO_RNG_BACKEND_H__
+#define NRF_CRYPTO_RNG_BACKEND_H__
+
+/** @file
+ *
+ * @defgroup nrf_crypto_rng_backend Meta RNG backend.
+ * @{
+ * @ingroup nrf_crypto_rng
+ *
+ * @brief Includes all backends definitions.
+ *
+ * @details This file includes all backend definitions.
+ */
+
+#include "cc310_backend_rng.h"
+#include "nrf_hw_backend_rng.h"
+#include "nrf_hw_backend_rng_mbedtls.h"
+
+#if !NRF_MODULE_ENABLED(NRF_CRYPTO_RNG)
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** @internal @brief Fallback dummy context type in case no backend is selected */
+typedef nrf_crypto_rng_internal_context_t nrf_crypto_backend_rng_context_t;
+
+/** @internal @brief Fallback dummy temp buffer type in case no backend is selected . */
+typedef struct
+{
+ uint32_t reserved;
+} nrf_crypto_backend_rng_temp_buffer_t;
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // !NRF_MODULE_ENABLED(NRF_CRYPTO_RNG)
+
+/**@} */
+
+#endif // NRF_CRYPTO_RNG_BACKEND_H__
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/nrf_crypto_rng_shared.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/nrf_crypto_rng_shared.h
new file mode 100644
index 0000000..bbf7fd3
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/nrf_crypto_rng_shared.h
@@ -0,0 +1,142 @@
+/**
+ * Copyright (c) 2018 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+
+#ifndef NRF_CRYPTO_RNG_SHARED_H__
+#define NRF_CRYPTO_RNG_SHARED_H__
+
+/** @file
+ *
+ * @defgroup nrf_crypto_rng_shared Types shared between all @ref nrf_crypto_rng backends.
+ * @{
+ * @ingroup nrf_crypto_rng
+ *
+ * @brief Types shared between all @ref nrf_crypto_rng backends.
+ *
+ * @details These types should not be used directly by the application.
+ */
+
+#include "sdk_common.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+#define NRF_CRYPTO_RNG_CONTEXT_INIT_MAGIC_VALUE (0x4d616961)
+
+
+/**
+ * @internal @brief Common header for each RNG backend context.
+ *
+ * @details This is an internal type that should not be used directly.
+ */
+typedef struct
+{
+ uint32_t init_value; //!< Contains NRF_CRYPTO_RNG_CONTEXT_INIT_MAGIC_VALUE if initialized.
+} nrf_crypto_rng_internal_context_t;
+
+
+/**
+ * @internal @brief Function for initializing the RNG backend.
+ *
+ * @note The backend function should never be called directly.
+ * Use @ref nrf_crypto_rng_init instead.
+ *
+ * @param[in,out] p_context Pointer to context structure.
+ * @param[in,out] p_temp_buffer Temporary buffer needed during initialization of the backend.
+ * @param[in] use_mutex Use mutex to prevent simultanious usage of backend resources.
+ */
+ret_code_t nrf_crypto_rng_backend_init(void * const p_context,
+ void * const p_temp_buffer);
+
+
+/**
+ * @internal @brief Function for uninitializing the RNG backend.
+ *
+ * @note The backend function should never be called directly.
+ * Use @ref nrf_crypto_rng_uninit instead.
+ *
+ * @param[in,out] p_context Pointer to context structure.
+ * @param[in] use_mutex Use mutex to prevent simultanious usage of backend resources.
+ */
+ret_code_t nrf_crypto_rng_backend_uninit(void * const p_context);
+
+
+/**
+ * @internal @brief Function for retrieving a random vector from the RNG backend.
+ *
+ * @note The backend function should never be called directly.
+ * Use @ref nrf_crypto_rng_vector_generate instead.
+ *
+ * @param[in,out] p_context Pointer to context structure.
+ * @param[out] p_target Buffer to hold the random generated data.
+ * @param[in] size Length (in bytes) to generate random data for.
+ * @param[in] use_mutex Use mutex to prevent simultanious usage of backend resources.
+ */
+ret_code_t nrf_crypto_rng_backend_vector_generate(void * const p_context,
+ uint8_t * const p_target,
+ size_t size,
+ bool use_mutex);
+
+
+/**
+ * @internal @brief This function is used for reseeding the RNG with additional entropy.
+ *
+ * @note The backend function should never be called directly.
+ * Use @ref nrf_crypto_rng_reseed instead.
+ *
+ * @param[in,out] p_context Pointer to context structure.
+ * @param[in,out] p_temp_buffer Temporary buffer needed during initialization of the backend.
+ * @param[in] p_input_data Input data used to increase the entropy.
+ * @param[in] size Length of input data.
+ */
+ret_code_t nrf_crypto_rng_backend_reseed(void * const p_context,
+ void * p_temp_buffer,
+ uint8_t * p_input_data,
+ size_t size);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+/**@} */
+
+#endif // NRF_CRYPTO_RNG_SHARED_H__
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/nrf_crypto_shared.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/nrf_crypto_shared.c
new file mode 100644
index 0000000..689ee48
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/nrf_crypto_shared.c
@@ -0,0 +1,97 @@
+/**
+ * Copyright (c) 2018 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+
+#include "sdk_config.h"
+#include "nordic_common.h"
+#include "nrf_crypto_shared.h"
+
+
+#if NRF_MODULE_ENABLED(NRF_CRYPTO)
+
+
+void nrf_crypto_internal_swap_endian_in_place(uint8_t * p_buffer, size_t size)
+{
+ ASSERT(p_buffer != NULL);
+
+ uint8_t temp;
+ uint8_t * p_first = p_buffer;
+ uint8_t * p_last = p_buffer + size - 1;
+ while (p_last >= p_first)
+ {
+ temp = *p_first;
+ *p_first = *p_last;
+ *p_last = temp;
+ p_first++;
+ p_last--;
+ }
+}
+
+
+void nrf_crypto_internal_swap_endian(uint8_t * p_out, uint8_t const * p_in, size_t size)
+{
+ ASSERT(p_out != NULL);
+ ASSERT(p_in != NULL);
+
+ uint8_t const * p_first = p_in;
+ uint8_t * p_last = p_out + size - 1;
+ while (p_last >= p_out)
+ {
+ *p_last = *p_first;
+ p_first++;
+ p_last--;
+ }
+}
+
+
+void nrf_crypto_internal_double_swap_endian(uint8_t * p_out, uint8_t const * p_in, size_t part_size)
+{
+ nrf_crypto_internal_swap_endian(p_out, p_in, part_size);
+ nrf_crypto_internal_swap_endian(&p_out[part_size], &p_in[part_size], part_size);
+}
+
+
+void nrf_crypto_internal_double_swap_endian_in_place(uint8_t * p_buffer, size_t part_size)
+{
+ nrf_crypto_internal_swap_endian_in_place(p_buffer, part_size);
+ nrf_crypto_internal_swap_endian_in_place(&p_buffer[part_size], part_size);
+}
+
+
+#endif
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/nrf_crypto_shared.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/nrf_crypto_shared.h
new file mode 100644
index 0000000..3e6dae3
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/nrf_crypto_shared.h
@@ -0,0 +1,189 @@
+/**
+ * Copyright (c) 2018 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+
+#ifndef NRF_CRYPTO_SHARED_H__
+#define NRF_CRYPTO_SHARED_H__
+
+/** @internal @file
+ *
+ * @defgroup nrf_crypto_shared Shared macros for nrf_crypto
+ * @{
+ * @ingroup nrf_crypto
+ *
+ * @brief Module containing shared macros for nrf_crypto.
+ */
+
+#include "sdk_macros.h"
+#include "nrf_crypto_mem.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** @internal @brief Macro for verifying statement to be true. It will cause the exterior function
+ * to return err_code if the statement is not true, but only after freeing the
+ * memory pointed to by p_memory if p_memory is not NULL.
+ *
+ * @param[in] statement Statement to test.
+ * @param[in] err_code Error value to return if test was invalid.
+ * @param[in] p_memory The memory block to be freed in case of error.
+ *
+ * @retval nothing, but will cause the exterior function to return @p err_code if @p statement
+ * is false.
+ */
+#define NRF_CRYPTO_VERIFY_TRUE_DEALLOCATE(statement, err_code, p_memory) \
+do \
+{ \
+ if (!(statement)) \
+ { \
+ if (p_memory != NULL) \
+ { \
+ NRF_CRYPTO_FREE(p_memory); \
+ } \
+ return err_code; \
+ } \
+} while (0)
+
+
+/**
+ * @internal @brief Macro for verifying that a function returned NRF_SUCCESS. It will cause the
+ * exterior function to return err_code if the err_code is not @ref NRF_SUCCESS,
+ * but only after freeing the memory pointed to by p_memory if p_memory is not
+ * NULL.
+ *
+ * @param[in] err_code The error code to check.
+ * @param[in] p_memory The memory block to be freed in case of error.
+ */
+#ifdef DISABLE_PARAM_CHECK
+#define NRF_CRYPTO_VERIFY_SUCCESS_DEALLOCATE()
+#else
+#define NRF_CRYPTO_VERIFY_SUCCESS_DEALLOCATE(err_code, p_memory) \
+ NRF_CRYPTO_VERIFY_TRUE_DEALLOCATE((err_code) == NRF_SUCCESS, (err_code), p_memory)
+#endif /* DISABLE_PARAM_CHECK */
+
+
+/**
+ * @internal @brief Generate a vector with random data of given size.
+ *
+ * @details This function does not check or lock the CC310 mutex, and should only be used
+ *
+ * @note Only for internal use in nrf_crypto.
+ *
+ * @param[in,out] p_target Buffer to hold the random generated data.
+ * This buffer must be at least as large as the size parameter.
+ * @param[in] size Length (in bytes) to generate random data for.
+ *
+ * @retval See return values for @ref nrf_crypto_rng_vector_generate.
+ */
+ret_code_t nrf_crypto_rng_vector_generate_no_mutex(uint8_t * const p_target, size_t size);
+
+
+/**
+ * @internal @brief Generate a vector of constrained random data of given size, between the
+ * specified min and max values.
+ *
+ * @details This function does not check or lock the CC310 mutex, and should only be used
+ *
+ * @note Only for internal use in nrf_crypto.
+ *
+ * @param[in,out] p_target Buffer to hold the random generated data.
+ * This buffer must be at least as large as the size parameter.
+ * @param[in] p_min Byte array defining the lower limit of the random vector.
+ * @param[in] p_max Byte array defining the upper limit of the random vector.
+ * @param[in] size Length (in bytes) to generate random data for. Note that all three
+ * buffers (p_target, p_min and p_max) must be of this size.
+ *
+ * @retval See return values for @ref nrf_crypto_rng_vector_generate_in_range.
+ */
+ret_code_t nrf_crypto_rng_vector_generate_in_range_no_mutex(uint8_t * const p_target,
+ uint8_t const * const p_min,
+ uint8_t const * const p_max,
+ size_t size);
+
+
+/** @internal @brief Swap bytes order inside provided buffer (in place).
+ *
+ * @note Only for internal use in nrf_crypto.
+ *
+ * @param[in,out] p_buffer Buffer with data to swap.
+ * @param[in] size Number of bytes in @p p_buffer.
+ */
+void nrf_crypto_internal_swap_endian_in_place(uint8_t * p_buffer, size_t size);
+
+
+/** @internal @brief Copy from one buffer to another and swap byte order.
+ *
+ * @note Only for internal use in nrf_crypto.
+ *
+ * @param[out] p_out Buffer with source data.
+ * @param[in] p_in Destination buffer with swapped bytes.
+ * @param[in] size Number of bytes in @p p_out and @p p_in.
+ */
+void nrf_crypto_internal_swap_endian(uint8_t * p_out, uint8_t const * p_in, size_t size);
+
+
+/** @internal @brief Swap bytes order inside buffer containing two integers (in place).
+ *
+ * @note Only for internal use in nrf_crypto.
+ *
+ * @param[in,out] p_buffer Buffer with data to swap.
+ * @param[in] part_size Number of bytes in single integer which is half of size of @p p_buffer.
+ */
+void nrf_crypto_internal_double_swap_endian_in_place(uint8_t * p_buffer, size_t part_size);
+
+
+/** @internal @brief Copy from one buffer containing two integers to another and swap byte order of each integer.
+ *
+ * @note Only for internal use in nrf_crypto.
+ *
+ * @param[out] p_out Buffer with source data.
+ * @param[in] p_in Destination buffer with swapped bytes.
+ * @param[in] part_size Number of bytes in single integer which is half of size of @p p_out and @p p_in.
+ */
+void nrf_crypto_internal_double_swap_endian(uint8_t * p_out, uint8_t const * p_in, size_t part_size);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+/**@} */
+
+#endif // NRF_CRYPTO_SHARED_H__
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/nrf_crypto_svc.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/nrf_crypto_svc.c
new file mode 100644
index 0000000..c80f141
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/nrf_crypto_svc.c
@@ -0,0 +1,93 @@
+/**
+ * Copyright (c) 2016 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+
+#include "nrf_svc_function.h"
+#include "nrf_error.h"
+#include "sdk_common.h"
+
+/* use direct calls */
+#define SVC_INTERFACE_CALL_AS_NORMAL_FUNCTION
+#include "nrf_crypto.h"
+
+#ifndef NRF51
+
+SVC_REGISTER_FUNCTION(const nrf_svc_func_reg_t nrf_crypto_svci_init) =
+{
+ .svc_num = NRF_SVCI_SVC_NUM,
+ .svci_num = NRF_CRYPTO_SVCI_INIT,
+ .func_ptr = (nrf_svc_func_t)&nrf_crypto_init
+};
+
+SVC_REGISTER_FUNCTION(const nrf_svc_func_reg_t nrf_crypto_svci_public_key_compute) =
+{
+ .svc_num = NRF_SVCI_SVC_NUM,
+ .svci_num = NRF_CRYPTO_SVCI_PUBLIC_KEY_COMPUTE,
+ .func_ptr = (nrf_svc_func_t)&nrf_crypto_public_key_compute
+};
+
+SVC_REGISTER_FUNCTION(const nrf_svc_func_reg_t nrf_crypto_svci_shared_secret_compute) =
+{
+ .svc_num = NRF_SVCI_SVC_NUM,
+ .svci_num = NRF_CRYPTO_SVCI_SHARED_SECRET_COMPUTE,
+ .func_ptr = (nrf_svc_func_t)&nrf_crypto_shared_secret_compute
+};
+
+SVC_REGISTER_FUNCTION(const nrf_svc_func_reg_t nrf_crypto_svci_sign) =
+{
+ .svc_num = NRF_SVCI_SVC_NUM,
+ .svci_num = NRF_CRYPTO_SVCI_SIGN,
+ .func_ptr = (nrf_svc_func_t)&nrf_crypto_sign
+};
+
+#endif // #ifndef NRF51
+
+SVC_REGISTER_FUNCTION(const nrf_svc_func_reg_t nrf_crypto_svci_verify) =
+{
+ .svc_num = NRF_SVCI_SVC_NUM,
+ .svci_num = NRF_CRYPTO_SVCI_VERIFY,
+ .func_ptr = (nrf_svc_func_t)&nrf_crypto_verify
+};
+
+SVC_REGISTER_FUNCTION(const nrf_svc_func_reg_t nrf_crypto_svci_hash_compute) =
+{
+ .svc_num = NRF_SVCI_SVC_NUM,
+ .svci_num = NRF_CRYPTO_SVCI_HASH_COMPUTE,
+ .func_ptr = &nrf_crypto_hash_compute
+};
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/nrf_crypto_types.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/nrf_crypto_types.h
new file mode 100644
index 0000000..9d428b1
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/crypto/nrf_crypto_types.h
@@ -0,0 +1,113 @@
+/**
+ * Copyright (c) 2016 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+
+#ifndef NRF_CRYPTO_TYPES_H__
+#define NRF_CRYPTO_TYPES_H__
+
+/** @file
+ *
+ * @defgroup nrf_crypto_types Commonly shared types
+ * @{
+ * @ingroup nrf_crypto
+ *
+ * @brief Provides definitions of commonly shared cryptographic types like hashes and curves used in the nrf_crypto APIs.
+ */
+
+#include <stdint.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** @brief Hashing algorithms that are available through nrf_crypto.
+ *
+ * @note All cryptographic hash types may not be available through the nrf_crypto backend.
+ */
+typedef enum
+{
+ NRF_CRYPTO_HASH_TYPE_INVALID = 0x00, //!< Invalid hashing algorithm.
+ NRF_CRYPTO_HASH_TYPE_MD5 = 0x01, //!< MD5.
+ NRF_CRYPTO_HASH_TYPE_SHA1 = 0x03, //!< SHA-1.
+ NRF_CRYPTO_HASH_TYPE_SHA224 = 0x04, //!< SHA-224 (SHA-2).
+ NRF_CRYPTO_HASH_TYPE_SHA256 = 0x05, //!< SHA-256 (SHA-2).
+ NRF_CRYPTO_HASH_TYPE_SHA384 = 0x06, //!< SHA-384 (SHA-2).
+ NRF_CRYPTO_HASH_TYPE_SHA512 = 0x07, //!< SHA-512 (SHA-2).
+
+} nrf_hash_type_t;
+
+/**@defgroup NRF_CRYPTO_HASH_SIZES Cryptographic hash sizes
+ * @brief Sizes of different cryptographic hashes.
+ * @{ */
+#define NRF_CRYPTO_HASH_SIZE_MD5 (20)
+#define NRF_CRYPTO_HASH_SIZE_SHA1 (20)
+#define NRF_CRYPTO_HASH_SIZE_SHA224 (28)
+#define NRF_CRYPTO_HASH_SIZE_SHA256 (32)
+#define NRF_CRYPTO_HASH_SIZE_SHA384 (48)
+#define NRF_CRYPTO_HASH_SIZE_SHA512 (64)
+/** @} */
+
+
+/**@brief Type definition for key size.
+ */
+typedef enum
+{
+ NRF_CRYPTO_KEY_SIZE_128 = 128,
+ NRF_CRYPTO_KEY_SIZE_192 = 192,
+ NRF_CRYPTO_KEY_SIZE_256 = 256
+} nrf_crypto_key_size_id_t;
+
+/**@brief Type specifying whether decrypt or encrypt operation shall be performed.
+ */
+typedef enum
+{
+ NRF_CRYPTO_DECRYPT = 0,
+ NRF_CRYPTO_ENCRYPT = 1,
+ NRF_CRYPTO_MAC_CALCULATE = 2
+} nrf_crypto_operation_t;
+
+#define NRF_CRYPTO_AES_BLOCK_SIZE (16u) // 16 bytes
+
+#ifdef __cplusplus
+}
+#endif
+
+/**@} */
+
+#endif // #ifndef NRF_CRYPTO_TYPES_H__
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/csense/nrf_csense.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/csense/nrf_csense.c
new file mode 100644
index 0000000..d2b2d6d
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/csense/nrf_csense.c
@@ -0,0 +1,662 @@
+/**
+ * Copyright (c) 2016 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#include "sdk_common.h"
+
+#if NRF_MODULE_ENABLED(NRF_CSENSE)
+
+#include <string.h>
+
+#include <nrfx.h>
+#include "nrf_csense.h"
+#include "nrf_peripherals.h"
+#include "nrf_assert.h"
+
+#if defined(__CC_ARM)
+#elif defined(__ICCARM__)
+#elif defined(__GNUC__)
+ #ifndef __CLZ
+ #define __CLZ(x) __builtin_clz(x)
+ #endif
+#endif
+
+APP_TIMER_DEF(nrf_csense_timer);
+
+typedef struct
+{
+ nrf_csense_event_handler_t event_handler; //!< Event handler for module.
+ nrfx_drv_state_t state; //!< State of module.
+ uint32_t ticks; //!< Timeout ticks of app_timer instance controlling csense module.
+ uint16_t raw_analog_values[MAX_ANALOG_INPUTS]; //!< Raw values of measurements.
+ uint8_t enabled_analog_channels_mask; //!< Mask of enabled channels.
+} nrf_csense_t;
+
+/* Module instance. */
+static nrf_csense_t m_nrf_csense;
+
+/* First of touch elements instances that creates linked list. */
+static nrf_csense_instance_t * mp_nrf_csense_instance_head;
+
+/* Buffer for values got from measurements. */
+static uint16_t m_values_buffer[NRF_CSENSE_MAX_PADS_NUMBER];
+
+/**
+ * @brief Function for handling time-outs.
+ *
+ * @param[in] p_context General purpose pointer. Will be passed to the time-out handler
+ * when the timer expires.
+ */
+static void csense_timer_handler(void * p_context)
+{
+ if (m_nrf_csense.state != NRFX_DRV_STATE_POWERED_ON)
+ {
+ return;
+ }
+
+ if (nrf_drv_csense_sample() == NRF_ERROR_BUSY)
+ {
+ return;
+ }
+}
+
+
+/**
+ * @brief Function for updating maximum or minimum value.
+ *
+ * @param [in] p_instance Pointer to csense instance.
+ * @param [in] p_pad Pointer to pad which should be checked for minimum or maximum value.
+ */
+__STATIC_INLINE void min_or_max_update(nrf_csense_instance_t const * p_instance,
+ nrf_csense_pad_t * p_pad)
+{
+ uint16_t val = m_nrf_csense.raw_analog_values[p_pad->analog_input_number];
+
+ if (p_instance->min_max[p_pad->pad_index].min_value > val)
+ {
+ p_instance->min_max[p_pad->pad_index].min_value = val;
+ }
+
+ if (p_instance->min_max[p_pad->pad_index].max_value < val)
+ {
+ p_instance->min_max[p_pad->pad_index].max_value = val;
+ }
+}
+
+
+/**
+ * @brief Function for calculating proportions on slider pad.
+ *
+ * @note This function help to self calibrate the pads.
+ *
+ * @param [in] p_instance Pointer to csense instance.
+ * @param [in] p_pad Pointer to pad to calculate ratio for.
+ *
+ * @return Difference between maximum and minimum values read on pads or 0 if minimum is bigger than maximum.
+ *
+ */
+__STATIC_INLINE uint16_t ratio_calculate(nrf_csense_instance_t const * p_instance,
+ nrf_csense_pad_t * p_pad)
+{
+ if (p_instance->min_max[p_pad->pad_index].max_value > p_instance->min_max[p_pad->pad_index].min_value)
+ {
+ uint16_t scale;
+ scale = (uint16_t)(p_instance->min_max[p_pad->pad_index].max_value -
+ p_instance->min_max[p_pad->pad_index].min_value);
+ return scale;
+ }
+ else
+ {
+ return 0;
+ }
+}
+
+
+/**
+ * @brief Function for calculating step.
+ *
+ * Function calculates step for slider basing on index of touched pads and values measured on
+ * them and neighboring pads.
+ *
+ * @param[in] p_instance Pointer to csense instance.
+ * @param[in] pad_index Index of the pad.
+ *
+ * @return Detected touched step.
+ */
+static uint16_t calculate_step(nrf_csense_instance_t * p_instance,
+ uint8_t pad_index)
+{
+ uint16_t step = 0;
+ uint32_t values_sum;
+ uint32_t values_product;
+
+ pad_index += 1;
+
+ values_sum = m_values_buffer[pad_index] + m_values_buffer[pad_index - 1] +
+ m_values_buffer[pad_index + 1];
+ values_product = (uint32_t)(p_instance->steps-1) *
+ (m_values_buffer[pad_index - 1] * (pad_index - 2)
+ + m_values_buffer[pad_index] * (pad_index - 1)
+ + m_values_buffer[pad_index + 1] * (pad_index));
+ step = 1 + ROUNDED_DIV(values_product, (values_sum * (p_instance->number_of_pads - 1))); // Add 1 to the result of the division
+ // to get the appropriate range of values.
+ memset((void*)m_values_buffer, 0, sizeof(m_values_buffer));
+
+ return step;
+}
+
+
+/**
+ * @brief Function for finding mask of touched pads.
+ *
+ * @param [in] p_instance Pointer to csense instance.
+ *
+ * @return Mask of touched pads.
+ */
+static uint32_t find_touched_mask(nrf_csense_instance_t const * p_instance)
+{
+ uint32_t touched_mask = 0;
+ uint16_t max_value = 0;
+ uint16_t ratio;
+ nrf_csense_pad_t * p_pad;
+
+ for (p_pad = p_instance->p_nrf_csense_pad; NULL != p_pad; p_pad = p_pad->p_next_pad) // run through all pads and look for those with biggest value
+ {
+ min_or_max_update(p_instance, p_pad);
+
+ ratio = ratio_calculate(p_instance, p_pad);
+ if (ratio == 0)
+ {
+ return 0;
+ }
+ uint16_t val =
+ (uint16_t)(((uint32_t)(m_nrf_csense.raw_analog_values[p_pad->analog_input_number] -
+ p_instance->min_max[p_pad->pad_index].min_value) *
+ NRF_CSENSE_MAX_VALUE) / ratio);
+ m_values_buffer[p_pad->pad_index+1] = val;
+
+ if (val > max_value)
+ {
+ max_value = val;
+ touched_mask = (1UL << (p_pad->pad_index));
+ }
+ else if (val == max_value)
+ {
+ max_value = val;
+ touched_mask |= (1UL << (p_pad->pad_index));
+ }
+ }
+
+ return touched_mask;
+}
+
+
+/**
+ * @brief Function for finding touched pad.
+ *
+ * If there is more than one pad connected to an analog channel this functions which one was actually touched. This is done by
+ * comparing values of neighboring pads.
+ *
+ * @param [in] instance Pointer to csense instance.
+ * @param [in] touched_mask Mask of touched pads.
+ *
+ * @return Touched pad.
+ */
+static uint16_t find_touched_pad(nrf_csense_instance_t const * p_instance,
+ uint32_t touched_mask)
+{
+ uint8_t i;
+ uint8_t biggest_deviation = 0;
+ uint8_t temp_biggest = 0;
+ uint16_t pad = UINT16_MAX;
+ static uint16_t previous_pad = 0;
+
+ for (i = 0; i < (p_instance->number_of_pads); i++)
+ {
+ if ((1UL << i) & touched_mask)
+ {
+ temp_biggest = m_values_buffer[i];
+ temp_biggest += m_values_buffer[i + 2];
+
+ if ((i != 0) && (i != ((p_instance->number_of_pads-1))))
+ {
+ temp_biggest /= 2;
+ }
+
+ if ((temp_biggest > NRF_CSENSE_PAD_DEVIATION) &&
+ (temp_biggest > biggest_deviation))
+ {
+ biggest_deviation = temp_biggest;
+ pad = i;
+ }
+ }
+ }
+
+ if (pad == UINT16_MAX)
+ {
+ pad = previous_pad;
+ }
+ else
+ {
+ previous_pad = pad;
+ }
+
+ return pad;
+}
+
+
+/**
+ * @brief Function for finding touched step.
+ *
+ * @param [in] instance Pointer to csense instance.
+ *
+ * @return Detected touched step.
+ */
+static uint16_t find_touched_step(nrf_csense_instance_t * p_instance)
+{
+ uint32_t touched_mask = 0;
+ uint16_t pad = 0;
+ uint16_t step;
+
+ touched_mask = find_touched_mask(p_instance);
+
+ if (touched_mask == 0)
+ {
+ return UINT16_MAX;
+ }
+
+ if ((touched_mask & (-(int32_t)touched_mask)) == touched_mask) // Check if there is only one pad with greatest value.
+ {
+ pad = 31 - __CLZ(touched_mask);
+ }
+ else
+ {
+ pad = find_touched_pad(p_instance, touched_mask);
+ }
+
+ step = calculate_step(p_instance, pad);
+ return step;
+}
+
+
+/**
+ * @brief Event handler for csense.
+ *
+ * param [in] p_event_struct Pointer to event structure.
+ */
+static void csense_event_handler(nrf_drv_csense_evt_t * p_event_struct)
+{
+ nrf_csense_evt_t event;
+ static uint16_t prev_analog_values[MAX_ANALOG_INPUTS];
+ bool touched = false;
+ nrf_csense_instance_t * instance;
+ uint8_t i;
+
+ if ((m_nrf_csense.enabled_analog_channels_mask & (1UL << (p_event_struct->analog_channel))) == 0)
+ {
+ return;
+ }
+
+ m_nrf_csense.raw_analog_values[p_event_struct->analog_channel] = p_event_struct->read_value;
+
+ if (nrf_drv_csense_is_busy())
+ {
+ return;
+ }
+
+ for (instance = mp_nrf_csense_instance_head; instance != NULL;
+ instance = instance->p_next_instance) // run through all instances
+ {
+ if (instance->is_active)
+ {
+ event.p_instance = instance;
+ nrf_csense_pad_t * p_pad = instance->p_nrf_csense_pad;
+
+ for (i = 0; i < MAX_ANALOG_INPUTS; i++)
+ {
+ if ((m_nrf_csense.raw_analog_values[i] <
+ (prev_analog_values[i] - NRF_CSENSE_PAD_HYSTERESIS)) ||
+ (m_nrf_csense.raw_analog_values[i] >
+ (prev_analog_values[i] + NRF_CSENSE_PAD_HYSTERESIS)))
+ {
+ touched = true;
+ break;
+ }
+ }
+
+ if (touched)
+ {
+ touched = false;
+
+ for (p_pad = instance->p_nrf_csense_pad; p_pad != NULL;
+ p_pad = p_pad->p_next_pad)
+ {
+ if (m_nrf_csense.raw_analog_values[p_pad->analog_input_number] >
+ p_pad->threshold)
+ {
+ touched = true;
+ break;
+ }
+ }
+ }
+ else
+ {
+ continue;
+ }
+
+ // Specify the event
+ if ((instance->is_touched) && touched)
+ {
+ // dragged
+ if (instance->number_of_pads > 1)
+ {
+ event.params.slider.step = find_touched_step(instance);
+ event.nrf_csense_evt_type = NRF_CSENSE_SLIDER_EVT_DRAGGED;
+
+ m_nrf_csense.event_handler(&event);
+ }
+ }
+ else if ((!(instance->is_touched)) && touched)
+ {
+ // pressed
+ if (instance->number_of_pads > 1)
+ {
+ event.params.slider.step = find_touched_step(instance);
+ event.nrf_csense_evt_type = NRF_CSENSE_SLIDER_EVT_PRESSED;
+ }
+ else
+ {
+ event.nrf_csense_evt_type = NRF_CSENSE_BTN_EVT_PRESSED;
+ }
+ instance->is_touched = true;
+
+ m_nrf_csense.event_handler(&event);
+ }
+ else if ((instance->is_touched) && (!touched))
+ {
+ // released
+ if (instance->number_of_pads > 1)
+ {
+ event.params.slider.step = find_touched_step(instance);
+ event.nrf_csense_evt_type = NRF_CSENSE_SLIDER_EVT_RELEASED;
+ }
+ else
+ {
+ event.nrf_csense_evt_type = NRF_CSENSE_BTN_EVT_RELEASED;
+ }
+ instance->is_touched = false;
+
+ m_nrf_csense.event_handler(&event);
+ }
+ else
+ {
+ // nothing changed
+ }
+ }
+
+ touched = false;
+ }
+
+ memset(m_values_buffer, 0, sizeof(m_values_buffer));
+ memcpy(prev_analog_values, m_nrf_csense.raw_analog_values,
+ sizeof(m_nrf_csense.raw_analog_values));
+}
+
+
+ret_code_t nrf_csense_init(nrf_csense_event_handler_t event_handler,
+ uint32_t ticks)
+{
+ ASSERT(event_handler != NULL);
+ ASSERT(m_nrf_csense.state == NRFX_DRV_STATE_UNINITIALIZED);
+
+ ret_code_t err_code;
+
+ static const nrf_drv_csense_config_t m_csense_config =
+ {
+ .output_pin = NRF_CSENSE_OUTPUT_PIN
+ };
+
+ m_nrf_csense.event_handler = event_handler;
+ m_nrf_csense.ticks = ticks;
+ mp_nrf_csense_instance_head = NULL;
+
+ err_code = app_timer_create(&nrf_csense_timer, APP_TIMER_MODE_REPEATED, csense_timer_handler);
+ if (err_code != NRF_SUCCESS)
+ {
+ return err_code;
+ }
+
+ err_code = nrf_drv_csense_init(&m_csense_config, csense_event_handler);
+ if (err_code != NRF_SUCCESS)
+ {
+ return err_code;
+ }
+
+ m_nrf_csense.state = NRFX_DRV_STATE_INITIALIZED;
+
+ return NRF_SUCCESS;
+}
+
+
+ret_code_t nrf_csense_uninit(void)
+{
+ ASSERT(m_nrf_csense.state != NRFX_DRV_STATE_UNINITIALIZED);
+
+ ret_code_t err_code;
+ nrf_csense_instance_t ** pp_instance = &mp_nrf_csense_instance_head;
+
+ err_code = nrf_drv_csense_uninit();
+ if (err_code != NRF_SUCCESS)
+ {
+ return err_code;
+ }
+
+ if (m_nrf_csense.enabled_analog_channels_mask != 0)
+ {
+ err_code = app_timer_stop(nrf_csense_timer);
+ if (err_code != NRF_SUCCESS)
+ {
+ return err_code;
+ }
+ }
+
+ while ((*pp_instance) != NULL)
+ {
+ nrf_csense_instance_t ** pp_instance_next = (&(*pp_instance)->p_next_instance);
+ (*pp_instance) = NULL;
+ pp_instance = pp_instance_next;
+ }
+
+ memset((void *)&m_nrf_csense, 0, sizeof(nrf_csense_t));
+
+ m_nrf_csense.state = NRFX_DRV_STATE_UNINITIALIZED;
+
+
+ return NRF_SUCCESS;
+}
+
+ret_code_t nrf_csense_add(nrf_csense_instance_t * const p_instance)
+{
+ ASSERT(m_nrf_csense.state != NRFX_DRV_STATE_UNINITIALIZED);
+ ASSERT(p_instance->p_next_instance == NULL);
+ ASSERT(p_instance != NULL);
+
+ ret_code_t err_code;
+
+ nrf_csense_instance_t ** pp_instance = &mp_nrf_csense_instance_head;
+
+ while ((*pp_instance) != NULL)
+ {
+ ASSERT((*pp_instance) != p_instance);
+ pp_instance = &((*pp_instance)->p_next_instance);
+ }
+
+ *pp_instance = p_instance;
+
+ err_code = nrf_csense_enable(p_instance);
+ return err_code;
+}
+
+ret_code_t nrf_csense_enable(nrf_csense_instance_t * const p_instance)
+{
+ ASSERT(m_nrf_csense.state != NRFX_DRV_STATE_UNINITIALIZED);
+ ASSERT(p_instance != NULL);
+
+ ret_code_t err_code;
+ nrf_csense_pad_t const * p_pad;
+ uint8_t analog_channels_mask = 0;
+
+ if (m_nrf_csense.enabled_analog_channels_mask == 0)
+ {
+ err_code = app_timer_start(nrf_csense_timer, m_nrf_csense.ticks, NULL);
+ if (err_code != NRF_SUCCESS)
+ {
+ return err_code;
+ }
+ }
+
+ p_instance->is_active = true;
+
+ for (p_pad = p_instance->p_nrf_csense_pad; p_pad != NULL; p_pad = p_pad->p_next_pad)
+ {
+ p_instance->min_max[p_pad->pad_index].min_value = UINT16_MAX;
+
+ // If channel was already enabled skip it.
+ if ((m_nrf_csense.enabled_analog_channels_mask & (1UL << (p_pad->analog_input_number))) == 0)
+ {
+ analog_channels_mask |= (1UL << (p_pad->analog_input_number));
+ m_nrf_csense.enabled_analog_channels_mask |= (1UL << (p_pad->analog_input_number));
+ }
+ }
+
+ m_nrf_csense.state = NRFX_DRV_STATE_POWERED_ON;
+ nrf_drv_csense_channels_enable(analog_channels_mask);
+
+ return NRF_SUCCESS;
+}
+
+
+ret_code_t nrf_csense_disable(nrf_csense_instance_t * const p_instance)
+{
+ ASSERT(m_nrf_csense.state == NRFX_DRV_STATE_POWERED_ON);
+
+ ret_code_t err_code;
+ nrf_csense_instance_t * p_instance_temp = mp_nrf_csense_instance_head;
+ nrf_csense_pad_t const * p_pad;
+ uint8_t channels_mask = 0;
+ uint8_t instance_channels_mask = 0;
+
+ for (p_instance_temp = mp_nrf_csense_instance_head; p_instance_temp != NULL;
+ p_instance_temp = p_instance_temp->p_next_instance)
+ {
+ for (p_pad = p_instance_temp->p_nrf_csense_pad; p_pad != NULL; p_pad = p_pad->p_next_pad)
+ {
+ if (p_instance_temp == p_instance)
+ {
+ instance_channels_mask |= (1UL << (p_pad->analog_input_number));
+ p_instance->is_active = false;
+ }
+ else
+ {
+ channels_mask |= (1UL << (p_pad->analog_input_number));
+ }
+ }
+ }
+
+ nrf_drv_csense_channels_disable((~channels_mask) & instance_channels_mask);
+
+ m_nrf_csense.enabled_analog_channels_mask = channels_mask;
+
+ if (m_nrf_csense.enabled_analog_channels_mask == 0)
+ {
+ err_code = app_timer_stop(nrf_csense_timer);
+ if (err_code != NRF_SUCCESS)
+ {
+ return err_code;
+ }
+ m_nrf_csense.state = NRFX_DRV_STATE_INITIALIZED;
+ }
+
+ return NRF_SUCCESS;
+}
+
+
+ret_code_t nrf_csense_ticks_set(uint32_t ticks)
+{
+ ASSERT(m_nrf_csense.state != NRFX_DRV_STATE_UNINITIALIZED);
+
+ ret_code_t err_code;
+
+ if (nrf_drv_csense_is_busy())
+ {
+ return NRF_ERROR_BUSY;
+ }
+
+ m_nrf_csense.ticks = ticks;
+
+ if (m_nrf_csense.state == NRFX_DRV_STATE_POWERED_ON)
+ {
+ err_code = app_timer_stop(nrf_csense_timer);
+ if (err_code != NRF_SUCCESS)
+ {
+ return err_code;
+ }
+
+ err_code = app_timer_start(nrf_csense_timer, ticks, NULL);
+ if (err_code != NRF_SUCCESS)
+ {
+ return err_code;
+ }
+ }
+
+ return NRF_SUCCESS;
+}
+
+
+ret_code_t nrf_csense_steps_set(nrf_csense_instance_t * const p_instance, uint16_t steps)
+{
+ if (p_instance->is_active)
+ {
+ return NRF_ERROR_INVALID_STATE;
+ }
+
+ p_instance->steps = steps;
+
+ return NRF_SUCCESS;
+}
+#endif //NRF_MODULE_ENABLED(NRF_CSENSE)
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/csense/nrf_csense.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/csense/nrf_csense.h
new file mode 100644
index 0000000..707d3ae
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/csense/nrf_csense.h
@@ -0,0 +1,344 @@
+/**
+ * Copyright (c) 2016 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#ifndef NRF_CSENSE_H__
+#define NRF_CSENSE_H__
+
+#include <stdint.h>
+#include "nrf.h"
+#include "sdk_errors.h"
+#include "app_timer.h"
+#include "nrf_drv_csense.h"
+#include "nrf_csense_macros.h"
+#include "app_util.h"
+
+/** @file
+ *
+ * @defgroup nrf_csense Capacitive sensor library
+ * @{
+ * @ingroup app_common
+ *
+ * @brief Module for using the capacitive sensor library with support for many instances of sliders, wheels, and buttons.
+ */
+
+/**
+ * @brief Macro for returning the address of a variable.
+ */
+#define NRF_CSENSE_GET_INSTANCE_ID(instance) (&instance)
+
+/**
+ * @brief Statically allocate memory for the instance of a capacitive sensor.
+ *
+ * @param[in,out] name Name of the capacitive sensor instance that will be created.
+ * @param[in] p1 Pair of two arguments: threshold and analog_input_number. Must be passed as (analog_input_number, threshold).
+ */
+#define NRF_CSENSE_BUTTON_DEF(name, p1) NRF_CSENSE_INTERNAL_BUTTON_DEF(name, p1)
+
+/**
+ * @brief Macro for creating a 2-pad slider instance.
+ *
+ * @param[in,out] name Name of the capacitive sensor instance that will be created.
+ * @param[in] steps_no Number of relative pads. It means that the slider in its handler will give values (1, steps_no).
+ * @param[in] p1 Pair of two arguments: threshold and analog_input_number. Must be passed as (analog_input_number, threshold).
+ * @param[in] p2 Pair of two arguments: threshold and analog_input_number. Must be passed as (analog_input_number, threshold).
+ */
+#define NRF_CSENSE_SLIDER_2_DEF(name, steps_no, p1, p2) NRF_CSENSE_INTERNAL_SLIDER_2_DEF(name, steps_no, p1, p2)
+
+/**
+ * @brief Macro for creating a 3-pad slider instance.
+ *
+ * @param[in,out] name Name of the capacitive sensor instance that will be created.
+ * @param[in] steps_no Number of relative pads. It means that the slider in its handler will give values (1, steps_no).
+ * @param[in] p1 Pair of two arguments: threshold and analog_input_number. Must be passed as (analog_input_number, threshold).
+ * @param[in] p2 Pair of two arguments: threshold and analog_input_number. Must be passed as (analog_input_number, threshold).
+ * @param[in] p3 Pair of two arguments: threshold and analog_input_number. Must be passed as (analog_input_number, threshold).
+ */
+#define NRF_CSENSE_SLIDER_3_DEF(name, steps_no, p1, p2, p3) NRF_CSENSE_INTERNAL_SLIDER_3_DEF(name, steps_no, p1, p2, p3)
+
+/**
+ * @brief Macro for creating a 4-pad slider instance.
+ *
+ * @param[in,out] name Name of the capacitive sensor instance that will be created.
+ * @param[in] steps_no Number of relative pads. It means that the slider in its handler will give values (1, steps_no).
+ * @param[in] p1 Pair of two arguments: threshold and analog_input_number. Must be passed as (analog_input_number, threshold).
+ * @param[in] p2 Pair of two arguments: threshold and analog_input_number. Must be passed as (analog_input_number, threshold).
+ * @param[in] p3 Pair of two arguments: threshold and analog_input_number. Must be passed as (analog_input_number, threshold).
+ * @param[in] p4 Pair of two arguments: threshold and analog_input_number. Must be passed as (analog_input_number, threshold).
+ */
+#define NRF_CSENSE_SLIDER_4_DEF(name, steps_no, p1, p2, p3, p4) NRF_CSENSE_INTERNAL_SLIDER_4_DEF(name, steps_no, p1, p2, p3, p4)
+
+/**
+ * @brief Macro for creating a 5-pad slider instance.
+ *
+ * @param[in,out] name Name of the capacitive sensor instance that will be created.
+ * @param[in] steps_no Number of relative pads. It means that the slider in its handler will give values (1, steps_no).
+ * @param[in] p1 Pair of two arguments: threshold and analog_input_number. Must be passed as (analog_input_number, threshold).
+ * @param[in] p2 Pair of two arguments: threshold and analog_input_number. Must be passed as (analog_input_number, threshold).
+ * @param[in] p3 Pair of two arguments: threshold and analog_input_number. Must be passed as (analog_input_number, threshold).
+ * @param[in] p4 Pair of two arguments: threshold and analog_input_number. Must be passed as (analog_input_number, threshold).
+ * @param[in] p5 Pair of two arguments: threshold and analog_input_number. Must be passed as (analog_input_number, threshold).
+ */
+#define NRF_CSENSE_SLIDER_5_DEF(name, steps_no, p1, p2, p3, p4, p5) NRF_CSENSE_INTERNAL_SLIDER_5_DEF(name, steps_no, p1, p2, p3, p4, p5)
+
+/**
+ * @brief Macro for creating a 3-pad wheel instance.
+ *
+ * @param[in,out] name Name of the capacitive sensor instance that will be created.
+ * @param[in] steps_no Number of relative pads. It means that the slider in its handler will give values (1, steps_no).
+ * @param[in] p1 Pair of two arguments: threshold and analog_input_number. Must be passed as (analog_input_number, threshold).
+ * @param[in] p2 Pair of two arguments: threshold and analog_input_number. Must be passed as (analog_input_number, threshold).
+ * @param[in] p3 Pair of two arguments: threshold and analog_input_number. Must be passed as (analog_input_number, threshold).
+ */
+#define NRF_CSENSE_WHEEL_3_DEF(name, steps_no, p1, p2, p3) NRF_CSENSE_INTERNAL_WHEEL_3_DEF(name, steps_no, p1, p2, p3)
+
+/**
+ * @brief Macro for creating a 4-pad wheel instance.
+ *
+ * @param[in,out] name Name of the capacitive sensor instance that will be created.
+ * @param[in] steps_no Number of relative pads. It means that the slider in its handler will give values (1, steps_no).
+ * @param[in] p1 Pair of two arguments: threshold and analog_input_number. Must be passed as (analog_input_number, threshold).
+ * @param[in] p2 Pair of two arguments: threshold and analog_input_number. Must be passed as (analog_input_number, threshold).
+ * @param[in] p3 Pair of two arguments: threshold and analog_input_number. Must be passed as (analog_input_number, threshold).
+ * @param[in] p4 Pair of two arguments: threshold and analog_input_number. Must be passed as (analog_input_number, threshold).
+ */
+#define NRF_CSENSE_WHEEL_4_DEF(name, steps_no, p1, p2, p3, p4) NRF_CSENSE_INTERNAL_WHEEL_4_DEF(name, steps_no, p1, p2, p3, p4)
+
+/**
+ * @brief Macro for creating a 5-pad wheel instance.
+ *
+ * @param[in,out] name Name of the capacitive sensor instance that will be created.
+ * @param[in] steps_no Number of relative pads. It means that the slider in its handler will give values (1, steps_no).
+ * @param[in] p1 Pair of two arguments: threshold and analog_input_number. Must be passed as (analog_input_number, threshold).
+ * @param[in] p2 Pair of two arguments: threshold and analog_input_number. Must be passed as (analog_input_number, threshold).
+ * @param[in] p3 Pair of two arguments: threshold and analog_input_number. Must be passed as (analog_input_number, threshold).
+ * @param[in] p4 Pair of two arguments: threshold and analog_input_number. Must be passed as (analog_input_number, threshold).
+ * @param[in] p5 Pair of two arguments: threshold and analog_input_number. Must be passed as (analog_input_number, threshold).
+ */
+#define NRF_CSENSE_WHEEL_5_DEF(name, steps_no, p1, p2, p3, p4, p5) NRF_CSENSE_INTERNAL_WHEEL_5_DEF(name, steps_no, p1, p2, p3, p4, p5)
+
+/**
+ * @cond (NODOX)
+ * @defgroup nrf_csense_internal Auxiliary internal types declarations
+ * @brief Module for internal usage inside the library only.
+ * @details These definitions are available to the user, but they should not
+ * be accessed directly. Use the API to access them.
+ * @{
+ *
+ */
+
+ /*
+ * @brief Forward declaration of capacitive sensor instance.
+ */
+ typedef struct nrf_csense_instance_s nrf_csense_instance_t;
+
+ /*
+ * @brief Forward declaration of a capacitive sensor pad.
+ */
+ typedef struct nrf_csense_pad_s nrf_csense_pad_t;
+
+ /**
+ * @brief Structure with pointer to min and max values measured on pads.
+ */
+ typedef struct
+ {
+ uint16_t max_value; //!< Max value measured on pads.
+ uint16_t min_value; //!< Min value measured on pads.
+ }nrf_csense_min_max_t;
+
+ /**
+ * @brief Structure with single instance parameters. This can be either a slider or a button.
+ */
+ struct nrf_csense_instance_s
+ {
+ nrf_csense_instance_t * p_next_instance; //!< Pointer to the next instance.
+ nrf_csense_pad_t * p_nrf_csense_pad; //!< Pointer to the first pad of the module.
+ nrf_csense_min_max_t * min_max; //!< Structure with pointers to min and max values measured on pads.
+ uint16_t steps; //!< Number of relative pads. It means that the slider in its handler will give values (1, steps_no).
+ uint8_t number_of_pads; //!< Number of pads that the instance is using.
+ bool is_active; //!< Flag to indicate if the instance is active.
+ bool is_touched; //!< Flag to indicate if the instance is touched.
+ void * p_context; //!< General purpose pointer.
+ };
+
+ /* Structure with single pad parameters used for initialization. */
+ struct nrf_csense_pad_s
+ {
+ nrf_csense_pad_t * p_next_pad; //!< Pointer to the next pad.
+ uint16_t threshold; //!< Threshold voltage on pad/time of charging to decide if the pad was touched.
+ uint8_t pad_index; //!< Index of the pad.
+ uint8_t analog_input_number; //!< Analog input connected to the pad.
+ };
+
+/** @}
+ * @endcond
+ */
+
+/**
+ * @brief Enum for nrf_csense events.
+ */
+typedef enum
+{
+ NRF_CSENSE_BTN_EVT_PRESSED, //!< Event for pad pressed.
+ NRF_CSENSE_BTN_EVT_RELEASED, //!< Event for pad released.
+ NRF_CSENSE_SLIDER_EVT_PRESSED, //!< Event for pad pressed.
+ NRF_CSENSE_SLIDER_EVT_RELEASED, //!< Event for pad released.
+ NRF_CSENSE_SLIDER_EVT_DRAGGED, //!< Event for pad dragged.
+}nrf_csense_evt_type_t;
+
+/**
+ * @brief Structure with slider event data including the measured step.
+ */
+typedef struct
+{
+ uint16_t step; //!< Measured step.
+} nrf_csense_slider_evt_t;
+
+/**
+ * @brief Event data union for nrf_csense events.
+ */
+typedef union
+{
+ nrf_csense_slider_evt_t slider; //!< Structure with slider event data including the measured step.
+} nrf_csense_evt_param_t;
+
+/**
+ * @brief Structure with event parameters.
+ */
+typedef struct
+{
+ nrf_csense_evt_type_t nrf_csense_evt_type; //!< Type of event.
+ nrf_csense_instance_t * p_instance; //!< Pointer to instance.
+ nrf_csense_evt_param_t params; //!< Event data union for nrf_csense events.
+}nrf_csense_evt_t;
+
+/**
+ * @brief Capacitive sensor handler type.
+ */
+typedef void (* nrf_csense_event_handler_t)(nrf_csense_evt_t * p_evt);
+
+/**
+ * @brief Function for setting a handler of the instance.
+ *
+ * @param [in] p_instance Pointer to the instance whose steps are going to be changed.
+ * @param [in] p_context General purpose pointer. Will be passed to the callback function.
+ */
+__STATIC_INLINE void nrf_csense_instance_context_set(nrf_csense_instance_t * const p_instance, void * p_context)
+{
+ p_instance->p_context = p_context;
+}
+
+/**
+ * @brief Function for initializing the module. After initialization, no instances are enabled.
+ *
+ * @param [in] event_handler Event handler for the Capacitive Sensor module.
+ * @param [in] ticks Time in app_timer ticks between next conversions.
+ *
+ * @retval NRF_ERROR_INVALID_PARAM If invalid parameter was provided.
+ * @retval NRF_ERROR_INVALID_STATE If one of the used modules is in invalid state.
+ * @retval NRF_ERROR_INTERNAL If an error occured while initializing one of the modules used by the capacitive sensor library.
+ * @retval NRF_SUCCESS If the module was initialized successfully.
+ */
+ret_code_t nrf_csense_init(nrf_csense_event_handler_t event_handler, uint32_t ticks);
+
+/**
+ * @brief Function for uninitializing the module.
+ *
+ * @return Values returned by @ref nrf_drv_csense_uninit and @ref app_timer_stop.
+ */
+ret_code_t nrf_csense_uninit(void);
+
+/**
+ * @brief Function for adding an instance of capacitive sensor to a linked list.
+ *
+ * The function calls @ref nrf_csense_enable to enable the instance that was added to the linked list.
+ *
+ * @param [in] p_instance Pointer to the capacitive sensor instance. It is saved by the module and is used whenever the instance is referred.
+ *
+ * @return Values returned by @ref nrf_csense_enable.
+ */
+ret_code_t nrf_csense_add(nrf_csense_instance_t * const p_instance);
+
+/**
+ * @brief Function for enabling a single instance.
+ *
+ * @param [in,out] p_instance Pointer to the capacitive sensor instance. It is saved by the module and is used whenever the instance is referred.
+ *
+ * @return Values returned by @ref app_timer_start.
+ */
+ret_code_t nrf_csense_enable(nrf_csense_instance_t * const p_instance);
+
+/**
+ * @brief Function for disabling an instance.
+ *
+ * @param [in] p_instance Pointer to the instance to be disabled.
+ *
+ * @retval NRF_ERROR_INVALID_PARAM If the instance was already disabled.
+ * @retval NRF_SUCCESS If the instance was disabled successfully.
+ */
+ret_code_t nrf_csense_disable(nrf_csense_instance_t * const p_instance);
+
+/**
+ * @brief Function for setting ticks between next measurements.
+ *
+ * @param [in] ticks New time between conversions in app_timer ticks.
+ *
+ * @retval NRF_ERROR_BUSY If the capacitive sensor was busy.
+ * @retval NRF_ERROR_INVALID_PARAM If an invalid parameter was provided.
+ * @retval NRF_ERROR_INVALID_STATE If app_timer was in invalid state.
+ * @retval NRF_SUCCESS If ticks were set successfully.
+ */
+ret_code_t nrf_csense_ticks_set(uint32_t ticks);
+
+/**
+ * @brief Function for setting steps of an instance.
+ *
+ * Note that you have do disable the instance before you can change its number of steps.
+ *
+ * @param [in] p_instance Pointer to the instance whose steps are going to be changed.
+ * @param [in] steps New steps value.
+ *
+ * @retval NRF_ERROR_BUSY If the capacitive sensor was busy.
+ * @retval NRF_SUCCESS If steps were set successfully.
+ */
+ret_code_t nrf_csense_steps_set(nrf_csense_instance_t * const p_instance, uint16_t steps);
+
+
+/** @} */
+
+#endif //NRF_CSENSE_H__
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/csense/nrf_csense_macros.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/csense/nrf_csense_macros.h
new file mode 100644
index 0000000..0e8a297
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/csense/nrf_csense_macros.h
@@ -0,0 +1,359 @@
+/**
+ * Copyright (c) 2016 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#ifndef NRF_CSENSE_MACROS_H__
+#define NRF_CSENSE_MACROS_H__
+
+/** @file
+ *
+ * @defgroup nrf_csense_macros Capacitive sensor macros
+ * @{
+ * @ingroup nrf_csense
+ *
+ * @brief A set of macros to facilitate creation of a new capacitive sensor instance.
+ */
+
+#define NRF_CSENSE_INTERNAL_BUTTON_DEF(name, p1) \
+ static nrf_csense_pad_t CONCAT_2(name, _pad) = \
+ { \
+ .p_next_pad = NULL, \
+ .threshold = GET_ARG_2 p1, \
+ .pad_index = 0, \
+ .analog_input_number = GET_ARG_1 p1 \
+ }; \
+ static nrf_csense_min_max_t CONCAT_2(name, _minmax); \
+ static nrf_csense_instance_t name = \
+ { \
+ .p_nrf_csense_pad = &CONCAT_2(name, _pad), \
+ .min_max = &CONCAT_2(name, _minmax), \
+ .steps = 1, \
+ .number_of_pads = 1, \
+ .is_active = false, \
+ .is_touched = false \
+ };
+
+#define NRF_CSENSE_INTERNAL_SLIDER_2_DEF(name, steps_no, p1, p2) \
+ static nrf_csense_pad_t CONCAT_2(name, _pad)[2] = \
+ { \
+ { \
+ .p_next_pad = &CONCAT_2(name, _pad)[1], \
+ .threshold = GET_ARG_2 p1, \
+ .pad_index = 0, \
+ .analog_input_number = GET_ARG_1 p1 \
+ }, \
+ { \
+ .p_next_pad = NULL, \
+ .threshold = GET_ARG_2 p2, \
+ .pad_index = 1, \
+ .analog_input_number = GET_ARG_1 p2 \
+ } \
+ }; \
+ \
+ static nrf_csense_min_max_t CONCAT_2(name, _minmax)[2]; \
+ static nrf_csense_instance_t name = \
+ { \
+ .p_nrf_csense_pad = CONCAT_2(name, _pad), \
+ .min_max = CONCAT_2(name, _minmax), \
+ .steps = steps_no, \
+ .number_of_pads = 2, \
+ .is_active = false, \
+ .is_touched = false \
+ };
+
+#define NRF_CSENSE_INTERNAL_SLIDER_3_DEF(name, steps_no, p1, p2, p3) \
+ static nrf_csense_pad_t CONCAT_2(name, _pad)[3] = \
+ { \
+ { \
+ .p_next_pad = &CONCAT_2(name, _pad)[1], \
+ .threshold = GET_ARG_2 p1, \
+ .pad_index = 0, \
+ .analog_input_number = GET_ARG_1 p1 \
+ }, \
+ { \
+ .p_next_pad = &CONCAT_2(name, _pad)[2], \
+ .threshold = GET_ARG_2 p2, \
+ .pad_index = 1, \
+ .analog_input_number = GET_ARG_1 p2 \
+ }, \
+ { \
+ .p_next_pad = NULL, \
+ .threshold = GET_ARG_2 p3, \
+ .pad_index = 2, \
+ .analog_input_number = GET_ARG_1 p3 \
+ } \
+ }; \
+ \
+ static nrf_csense_min_max_t CONCAT_2(name, _minmax)[3]; \
+ static nrf_csense_instance_t name = \
+ { \
+ .p_nrf_csense_pad = CONCAT_2(name, _pad), \
+ .min_max = CONCAT_2(name, _minmax), \
+ .steps = steps_no, \
+ .number_of_pads = 3, \
+ .is_active = false, \
+ .is_touched = false \
+ };
+
+#define NRF_CSENSE_INTERNAL_SLIDER_4_DEF(name, steps_no, p1, p2, p3, p4) \
+ static nrf_csense_pad_t CONCAT_2(name, _pad)[4] = \
+ { \
+ { \
+ .p_next_pad = &CONCAT_2(name, _pad)[1], \
+ .threshold = GET_ARG_2 p1, \
+ .pad_index = 0, \
+ .analog_input_number = GET_ARG_1 p1 \
+ }, \
+ { \
+ .p_next_pad = &CONCAT_2(name, _pad)[2], \
+ .threshold = GET_ARG_2 p2, \
+ .pad_index = 1, \
+ .analog_input_number = GET_ARG_1 p2 \
+ }, \
+ { \
+ .p_next_pad = &CONCAT_2(name, _pad)[3], \
+ .threshold = GET_ARG_2 p3, \
+ .pad_index = 2, \
+ .analog_input_number = GET_ARG_1 p3 \
+ }, \
+ { \
+ .p_next_pad = NULL, \
+ .threshold = GET_ARG_2 p4, \
+ .pad_index = 3, \
+ .analog_input_number = GET_ARG_1 p4 \
+ } \
+ }; \
+ static nrf_csense_min_max_t CONCAT_2(name, _minmax)[4]; \
+ static nrf_csense_instance_t name = \
+ { \
+ .p_nrf_csense_pad = CONCAT_2(name, _pad), \
+ .min_max = CONCAT_2(name, _minmax), \
+ .steps = steps_no, \
+ .number_of_pads = 4, \
+ .is_active = false, \
+ .is_touched = false \
+ };
+
+#define NRF_CSENSE_INTERNAL_SLIDER_5_DEF(name, steps_no, p1, p2, p3, p4, p5) \
+ static nrf_csense_pad_t CONCAT_2(name, _pad)[5] = \
+ { \
+ { \
+ .p_next_pad = &CONCAT_2(name, _pad)[1], \
+ .threshold = GET_ARG_2 p1, \
+ .pad_index = 0, \
+ .analog_input_number = GET_ARG_1 p1 \
+ }, \
+ { \
+ .p_next_pad = &CONCAT_2(name, _pad)[2], \
+ .threshold = GET_ARG_2 p2, \
+ .pad_index = 1, \
+ .analog_input_number = GET_ARG_1 p2 \
+ }, \
+ { \
+ .p_next_pad = &CONCAT_2(name, _pad)[3], \
+ .threshold = GET_ARG_2 p3, \
+ .pad_index = 2, \
+ .analog_input_number = GET_ARG_1 p3 \
+ }, \
+ { \
+ .p_next_pad = &CONCAT_2(name, _pad)[4], \
+ .threshold = GET_ARG_2 p4, \
+ .pad_index = 3, \
+ .analog_input_number = GET_ARG_1 p4 \
+ }, \
+ { \
+ .p_next_pad = NULL, \
+ .threshold = GET_ARG_2 p5, \
+ .pad_index = 4, \
+ .analog_input_number = GET_ARG_1 p5 \
+ } \
+ }; \
+ \
+ static nrf_csense_min_max_t CONCAT_2(name, _minmax)[5]; \
+ static nrf_csense_instance_t name = \
+ { \
+ .p_nrf_csense_pad = CONCAT_2(name, _pad), \
+ .min_max = CONCAT_2(name, _minmax), \
+ .steps = steps_no, \
+ .number_of_pads = 5, \
+ .is_active = false, \
+ .is_touched = false \
+ };
+
+#define NRF_CSENSE_INTERNAL_WHEEL_3_DEF(name, steps_no, p1, p2, p3) \
+ static nrf_csense_pad_t CONCAT_2(name, _pad)[4] = \
+ { \
+ { \
+ .p_next_pad = &CONCAT_2(name, _pad)[1], \
+ .threshold = GET_ARG_2 p1, \
+ .pad_index = 0, \
+ .analog_input_number = GET_ARG_1 p1 \
+ }, \
+ { \
+ .p_next_pad = &CONCAT_2(name, _pad)[2], \
+ .threshold = GET_ARG_2 p2, \
+ .pad_index = 1, \
+ .analog_input_number = GET_ARG_1 p2 \
+ }, \
+ { \
+ .p_next_pad = &CONCAT_2(name, _pad)[3], \
+ .threshold = GET_ARG_2 p3, \
+ .pad_index = 2, \
+ .analog_input_number = GET_ARG_1 p3 \
+ }, \
+ { \
+ .p_next_pad = NULL, \
+ .threshold = GET_ARG_2 p1, \
+ .pad_index = 3, \
+ .analog_input_number = GET_ARG_1 p1 \
+ } \
+ }; \
+ \
+ static nrf_csense_min_max_t CONCAT_2(name, _minmax)[4]; \
+ static nrf_csense_instance_t name = \
+ { \
+ .p_nrf_csense_pad = CONCAT_2(name, _pad), \
+ .min_max = CONCAT_2(name, _minmax), \
+ .steps = steps_no, \
+ .number_of_pads = 4, \
+ .is_active = false, \
+ .is_touched = false \
+ };
+
+
+#define NRF_CSENSE_INTERNAL_WHEEL_4_DEF(name, steps_no, p1, p2, p3, p4) \
+ static nrf_csense_pad_t CONCAT_2(name, _pad)[5] = \
+ { \
+ { \
+ .p_next_pad = &CONCAT_2(name, _pad)[1], \
+ .threshold = GET_ARG_2 p1, \
+ .pad_index = 0, \
+ .analog_input_number = GET_ARG_1 p1 \
+ }, \
+ { \
+ .p_next_pad = &CONCAT_2(name, _pad)[2], \
+ .threshold = GET_ARG_2 p2, \
+ .pad_index = 1, \
+ .analog_input_number = GET_ARG_1 p2 \
+ }, \
+ { \
+ .p_next_pad = &CONCAT_2(name, _pad)[3], \
+ .threshold = GET_ARG_2 p3, \
+ .pad_index = 2, \
+ .analog_input_number = GET_ARG_1 p3 \
+ }, \
+ { \
+ .p_next_pad = &CONCAT_2(name, _pad)[4], \
+ .threshold = GET_ARG_2 p4, \
+ .pad_index = 3, \
+ .analog_input_number = GET_ARG_1 p4 \
+ }, \
+ { \
+ .p_next_pad = NULL, \
+ .threshold = GET_ARG_2 p1, \
+ .pad_index = 4, \
+ .analog_input_number = GET_ARG_1 p1 \
+ } \
+ }; \
+ \
+ static nrf_csense_min_max_t CONCAT_2(name, _minmax)[5]; \
+ static nrf_csense_instance_t name = \
+ { \
+ .p_nrf_csense_pad = CONCAT_2(name, _pad), \
+ .min_max = CONCAT_2(name, _minmax), \
+ .steps = steps_no, \
+ .number_of_pads = 5, \
+ .is_active = false, \
+ .is_touched = false \
+ };
+
+#define NRF_CSENSE_INTERNAL_WHEEL_5_DEF(name, steps_no, p1, p2, p3, p4, p5)\
+ static nrf_csense_pad_t CONCAT_2(name, _pad)[6] = \
+ { \
+ { \
+ .p_next_pad = &CONCAT_2(name, _pad)[1], \
+ .threshold = GET_ARG_2 p1, \
+ .pad_index = 0, \
+ .analog_input_number = GET_ARG_1 p1 \
+ }, \
+ { \
+ .p_next_pad = &CONCAT_2(name, _pad)[2], \
+ .threshold = GET_ARG_2 p2, \
+ .pad_index = 1, \
+ .analog_input_number = GET_ARG_1 p2 \
+ }, \
+ { \
+ .p_next_pad = &CONCAT_2(name, _pad)[3], \
+ .threshold = GET_ARG_2 p3, \
+ .pad_index = 2, \
+ .analog_input_number = GET_ARG_1 p3 \
+ }, \
+ { \
+ .p_next_pad = &CONCAT_2(name, _pad)[4], \
+ .threshold = GET_ARG_2 p4, \
+ .pad_index = 3, \
+ .analog_input_number = GET_ARG_1 p4 \
+ }, \
+ { \
+ .p_next_pad = &CONCAT_2(name, _pad)[5], \
+ .threshold = GET_ARG_2 p5, \
+ .pad_index = 4, \
+ .analog_input_number = GET_ARG_1 p5 \
+ }, \
+ { \
+ .p_next_pad = NULL, \
+ .threshold = GET_ARG_2 p1, \
+ .pad_index = 5, \
+ .analog_input_number = GET_ARG_1 p1 \
+ } \
+ }; \
+ \
+ static nrf_csense_min_max_t CONCAT_2(name, _minmax)[6]; \
+ static nrf_csense_instance_t name = \
+ { \
+ .p_nrf_csense_pad = CONCAT_2(name, _pad), \
+ .min_max = CONCAT_2(name, _minmax), \
+ .steps = steps_no, \
+ .number_of_pads = 6, \
+ .is_active = false, \
+ .is_touched = false \
+ };
+
+/** @} */
+
+#endif // NRF_CSENSE_MACROS_H__
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/csense_drv/nrf_drv_csense.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/csense_drv/nrf_drv_csense.c
new file mode 100644
index 0000000..8adf52a
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/csense_drv/nrf_drv_csense.c
@@ -0,0 +1,633 @@
+/**
+ * Copyright (c) 2016 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#include "sdk_common.h"
+#if NRF_MODULE_ENABLED(NRF_DRV_CSENSE)
+#include "nrf_drv_csense.h"
+#include "nrf_peripherals.h"
+#include "nrf_gpio.h"
+#include "app_error.h"
+#include "app_util_platform.h"
+#include "nrf_assert.h"
+#include "string.h"
+#include <stdio.h>
+
+#if defined(__CORTEX_M) && (__CORTEX_M < 4)
+#ifndef ARM_MATH_CM0PLUS
+#define ARM_MATH_CM0PLUS
+#endif
+/*lint -save -e689 */
+#include "arm_math.h"
+/*lint -restore */
+#endif
+
+#if USE_COMP
+#include "nrf_drv_comp.h"
+#include "nrf_drv_ppi.h"
+#include "nrf_drv_timer.h"
+#endif //USE_COMP
+
+#if USE_COMP == 0
+#ifdef ADC_PRESENT
+#include "nrfx_adc.h"
+
+/**
+ * @defgroup adc_defines ADC defines to count input voltage.
+ * @{
+ */
+#define ADC_RES_10BIT 1024
+#define ADC_INPUT_PRESCALER 3
+#define ADC_REF_VBG_VOLTAGE 1.2
+/* @} */
+
+/* ADC channel used to call conversion. */
+static nrfx_adc_channel_t adc_channel = NRFX_ADC_DEFAULT_CHANNEL(NRF_ADC_CONFIG_INPUT_0);
+#elif defined(SAADC_PRESENT)
+#include "nrf_drv_saadc.h"
+
+/**
+ * @defgroup saadc_defines SAADC defines to count input voltage.
+ * @{
+ */
+#define SAADC_RES_10BIT 1024
+#define SAADC_INPUT_PRESCALER 3
+#define SAADC_REF_VBG_VOLTAGE 0.6
+/* @} */
+
+/* SAADC channel used to call conversion. */
+static nrf_saadc_channel_config_t saadc_channel = NRF_DRV_SAADC_DEFAULT_CHANNEL_CONFIG_SE(NRF_SAADC_INPUT_AIN0);
+#endif //ADC_PRESENT
+#endif //USE_COMP
+
+#if USE_COMP
+/* Number of channels required by PPI. */
+#define PPI_REQUIRED_CHANNELS 3
+
+/* Array of PPI channels. */
+static nrf_ppi_channel_t m_ppi_channels[PPI_REQUIRED_CHANNELS];
+
+
+/**
+ * @defgroup timer_instances Timer instances.
+ * @{
+ */
+static const nrf_drv_timer_t m_timer0 = NRF_DRV_TIMER_INSTANCE(TIMER0_FOR_CSENSE);
+static const nrf_drv_timer_t m_timer1 = NRF_DRV_TIMER_INSTANCE(TIMER1_FOR_CSENSE);
+/* @} */
+#endif //USE_COMP
+
+/* Configuration of the capacitive sensor module. */
+typedef struct
+{
+ volatile nrfx_drv_state_t module_state; /**< State of the module. */
+ nrf_drv_csense_event_handler_t event_handler; /**< Event handler for capacitor sensor events. */
+ uint16_t analog_values[MAX_ANALOG_INPUTS]; /**< Array containing analog values measured on the corresponding COMP/ADC channel. */
+ volatile bool busy; /**< Indicates state of module - busy if there are ongoing conversions. */
+ volatile uint8_t cur_chann_idx; /**< Current channel to be read if enabled. */
+ volatile uint8_t adc_channels_input_mask; /**< Enabled channels. */
+ uint8_t output_pin; /**< Pin to generate signal charging capacitors. */
+ uint8_t channels_to_read; /**< Mask of channels remaining to be read in the current measurement. */
+ volatile bool timers_powered_on; /**< Flag to indicate if timers were already started. */
+}csense_t;
+
+static csense_t m_csense;
+
+/**
+ * @brief Function for determining the next analog channel to be read.
+ */
+__STATIC_INLINE void calculate_next_channel(void)
+{
+ m_csense.cur_chann_idx = 31 - __CLZ(m_csense.channels_to_read);
+}
+
+/**
+ * @brief Function for handling conversion values.
+ *
+ * @param[in] val Value received from ADC or COMP.
+ */
+static void conversion_handler(uint16_t val)
+{
+ nrf_drv_csense_evt_t event_struct;
+
+#if USE_COMP == 0
+ nrf_gpio_pin_set(m_csense.output_pin);
+#endif //USE_COMP
+
+ m_csense.analog_values[m_csense.cur_chann_idx] = val;
+
+ event_struct.read_value = val;
+ event_struct.analog_channel = m_csense.cur_chann_idx;
+
+ m_csense.channels_to_read &= ~(1UL<<m_csense.cur_chann_idx);
+
+ // decide if there will be more conversions
+ if (m_csense.channels_to_read == 0)
+ {
+ m_csense.busy = false;
+#if USE_COMP == 0 && defined(SAADC_PRESENT)
+ nrf_saadc_disable();
+#endif
+ }
+
+ m_csense.event_handler(&event_struct);
+
+ if (m_csense.channels_to_read > 0) // Start new conversion.
+ {
+ ret_code_t err_code;
+ calculate_next_channel();
+ err_code = nrf_drv_csense_sample();
+ if (err_code != NRF_SUCCESS)
+ {
+ return;
+ }
+ }
+}
+
+#if USE_COMP
+/**
+ * @brief Timer0 interrupt handler.
+ *
+ * @param[in] event_type Timer event.
+ * @param[in] p_context General purpose parameter set during initialization of
+ * the timer. This parameter can be used to pass
+ * additional information to the handler function, for
+ * example, the timer ID.
+ */
+static void counter_compare_handler(nrf_timer_event_t event_type, void* p_context)
+{
+ if (event_type == NRF_TIMER_EVENT_COMPARE0)
+ {
+ uint16_t val = nrf_drv_timer_capture_get(&m_timer1, NRF_TIMER_CC_CHANNEL1);
+ nrf_drv_timer_pause(&m_timer1);
+ nrf_drv_timer_clear(&m_timer1);
+
+ /* Handle finished measurement. */
+ conversion_handler(val);
+ }
+}
+
+/**
+ * @brief Dummy handler.
+ *
+ * @param[in] event_type Timer event.
+ * @param[in] p_context General purpose parameter set during initialization of
+ * the timer. This parameter can be used to pass
+ * additional information to the handler function, for
+ * example, the timer ID.
+ */
+static void dummy_handler(nrf_timer_event_t event_type, void* p_context){}
+
+/**
+ * @brief Function for initializing timers.
+ *
+ * @retval NRF_ERROR_INTERNAL If there were error initializing timers.
+ * @retval NRF_SUCCESS If timers were initialized successfully.
+ */
+static ret_code_t timer_init(void)
+{
+ ret_code_t err_code;
+
+ //set first timer in timer mode to get period of relaxation oscillator
+ nrf_drv_timer_config_t timer_config = NRF_DRV_TIMER_DEFAULT_CONFIG;
+ timer_config.mode = NRF_TIMER_MODE_TIMER;
+ err_code = nrf_drv_timer_init(&m_timer1, &timer_config, dummy_handler);
+ if (err_code != NRF_SUCCESS)
+ {
+ return NRF_ERROR_INTERNAL;
+ }
+
+ //set second timer in counter mode and generate event on tenth period
+ timer_config.mode = NRF_TIMER_MODE_COUNTER;
+ err_code = nrf_drv_timer_init(&m_timer0, &timer_config, counter_compare_handler);
+ if (err_code != NRF_SUCCESS)
+ {
+ return NRF_ERROR_INTERNAL;
+ }
+ nrf_drv_timer_extended_compare(&m_timer0, NRF_TIMER_CC_CHANNEL0, MEASUREMENT_PERIOD, (nrf_timer_short_mask_t)(NRF_TIMER_SHORT_COMPARE0_CLEAR_MASK | NRF_TIMER_SHORT_COMPARE0_STOP_MASK), true);
+
+ return NRF_SUCCESS;
+}
+
+/**
+ * @brief Function for initializing and enabling PPI channels.
+ *
+ * @retval NRF_ERROR_INTERNAL If there were error initializing or enabling PPI channels.
+ * @retval NRF_SUCCESS If PPI channels were initialized and enabled successfully.
+ */
+static ret_code_t ppi_init(void)
+{
+ ret_code_t err_code;
+ uint8_t i;
+
+ err_code = nrf_drv_ppi_init();
+ if ((err_code != NRF_SUCCESS) && (err_code != NRF_ERROR_MODULE_ALREADY_INITIALIZED))
+ {
+ return NRF_ERROR_INTERNAL;
+ }
+
+ for (i = 0; i < PPI_REQUIRED_CHANNELS ; i++)
+ {
+ err_code = nrf_drv_ppi_channel_alloc(&m_ppi_channels[i]);
+ if (NRF_SUCCESS != err_code)
+ {
+ return NRF_ERROR_INTERNAL;
+ }
+ }
+
+ err_code = nrf_drv_ppi_channel_assign(m_ppi_channels[0], nrf_drv_comp_event_address_get(NRF_COMP_EVENT_CROSS), nrf_drv_timer_task_address_get(&m_timer0, NRF_TIMER_TASK_COUNT));
+ if (NRF_SUCCESS != err_code)
+ {
+ return NRF_ERROR_INTERNAL;
+ }
+ err_code = nrf_drv_ppi_channel_assign(m_ppi_channels[1], nrf_drv_timer_event_address_get(&m_timer0, NRF_TIMER_EVENT_COMPARE0), nrf_drv_timer_task_address_get(&m_timer1, NRF_TIMER_TASK_CAPTURE1));
+ if (NRF_SUCCESS != err_code)
+ {
+ return NRF_ERROR_INTERNAL;
+ }
+ err_code = nrf_drv_ppi_channel_fork_assign(m_ppi_channels[1], nrf_drv_comp_task_address_get(NRF_COMP_TASK_STOP));
+ if (NRF_SUCCESS != err_code)
+ {
+ return NRF_ERROR_INTERNAL;
+ }
+ err_code = nrf_drv_ppi_channel_assign(m_ppi_channels[2], nrf_drv_comp_event_address_get(NRF_COMP_EVENT_READY), nrf_drv_timer_task_address_get(&m_timer0, NRF_TIMER_TASK_CLEAR));
+ if (NRF_SUCCESS != err_code)
+ {
+ return NRF_ERROR_INTERNAL;
+ }
+ err_code = nrf_drv_ppi_channel_fork_assign(m_ppi_channels[2], nrf_drv_timer_task_address_get(&m_timer1, NRF_TIMER_TASK_CLEAR));
+ if (NRF_SUCCESS != err_code)
+ {
+ return NRF_ERROR_INTERNAL;
+ }
+
+ for (i = 0; i < PPI_REQUIRED_CHANNELS ; i++)
+ {
+ err_code = nrf_drv_ppi_channel_enable(m_ppi_channels[i]);
+ if (NRF_SUCCESS != err_code)
+ {
+ return NRF_ERROR_INTERNAL;
+ }
+ }
+
+ return NRF_SUCCESS;
+}
+
+/**
+ * @brief Dummy handler for COMP events.
+ *
+ * @param[in] event COMP event.
+ */
+static void comp_event_handler(nrf_comp_event_t event){}
+
+/**
+ * @brief Function for initializing COMP module in relaxation oscillator mode.
+ *
+ * @note The frequency of the oscillator depends on threshold voltages, current source and capacitance of pad and can be calculated as f_OSC = I_SOURCE / (2C·(VUP-VDOWN) ).
+ *
+ * @retval NRF_ERROR_INTERNAL If there were error while initializing COMP driver.
+ * @retval NRF_SUCCESS If the COMP driver initialization was successful.
+ */
+static ret_code_t comp_init(void)
+{
+ ret_code_t err_code;
+ nrf_drv_comp_config_t m_comp_config = NRF_DRV_COMP_DEFAULT_CONFIG(NRF_COMP_INPUT_0);
+
+ /* Workaround for Errata 12 "COMP: Reference ladder is not correctly calibrated" found at the Errata document
+ for your device located at https://infocenter.nordicsemi.com/ */
+ *(volatile uint32_t *)0x40013540 = (*(volatile uint32_t *)0x10000324 & 0x00001F00) >> 8;
+
+ m_comp_config.isource = NRF_COMP_ISOURCE_Ien10uA;
+
+ err_code = nrf_drv_comp_init(&m_comp_config, comp_event_handler);
+ if (err_code != NRF_SUCCESS)
+ {
+ return NRF_ERROR_INTERNAL;
+ }
+
+ return NRF_SUCCESS;
+}
+#endif //USE_COMP
+
+#if USE_COMP == 0
+#ifdef ADC_PRESENT
+/**
+ * @brief ADC handler.
+ *
+ * @param[in] p_event Pointer to analog-to-digital converter driver event.
+ */
+void adc_handler(nrfx_adc_evt_t const * p_event)
+{
+ nrf_gpio_pin_set(m_csense.output_pin);
+ uint16_t val;
+ val = (uint16_t)(p_event->data.sample.sample *
+ ADC_REF_VBG_VOLTAGE * 1000 *
+ ADC_INPUT_PRESCALER / ADC_RES_10BIT);
+ conversion_handler(val);
+}
+
+/**
+ * @brief Function for initializing ADC.
+ */
+static ret_code_t adc_init(void)
+{
+ ret_code_t err_code;
+
+ adc_channel.config.config.input = NRF_ADC_CONFIG_SCALING_INPUT_ONE_THIRD;
+
+ nrfx_adc_config_t const adc_config = NRFX_ADC_DEFAULT_CONFIG;
+ err_code = nrfx_adc_init(&adc_config, adc_handler);
+ if (err_code != NRF_SUCCESS)
+ {
+ return NRF_ERROR_INTERNAL;
+ }
+
+ nrf_gpio_pin_set(m_csense.output_pin);
+
+ return NRF_SUCCESS;
+}
+#elif defined(SAADC_PRESENT)
+/**
+ * @brief SAADC handler.
+ *
+ * @param[in] p_event Pointer to analog-to-digital converter driver event.
+ */
+void saadc_handler(nrf_drv_saadc_evt_t const * p_event)
+{
+ nrf_gpio_pin_set(m_csense.output_pin);
+ uint16_t val;
+ (void)nrf_drv_saadc_buffer_convert(p_event->data.done.p_buffer, 1);
+ val = (uint16_t)(*p_event->data.done.p_buffer *
+ SAADC_REF_VBG_VOLTAGE * 1000 *
+ SAADC_INPUT_PRESCALER / SAADC_RES_10BIT);
+ conversion_handler(val);
+}
+
+/**
+ * @brief Function for initializing SAADC.
+ */
+static ret_code_t saadc_init(void)
+{
+ ret_code_t err_code;
+ static nrf_saadc_value_t saadc_value;
+
+ saadc_channel.gain = NRF_SAADC_GAIN1_3;
+
+ err_code = nrf_drv_saadc_init(NULL, saadc_handler);
+ if (err_code != NRF_SUCCESS)
+ {
+ return NRF_ERROR_INTERNAL;
+ }
+
+ nrf_gpio_pin_set(m_csense.output_pin);
+
+ err_code = nrf_drv_saadc_channel_init(0, &saadc_channel);
+ if (err_code != NRF_SUCCESS)
+ {
+ return NRF_ERROR_INTERNAL;
+ }
+
+ err_code = nrf_drv_saadc_buffer_convert(&saadc_value, 1);
+ if (err_code != NRF_SUCCESS)
+ {
+ return NRF_ERROR_INTERNAL;
+ }
+
+ nrf_saadc_disable();
+
+ return NRF_SUCCESS;
+}
+#endif //ADC_PRESENT
+#endif //USE_COMP
+
+ret_code_t nrf_drv_csense_init(nrf_drv_csense_config_t const * p_config, nrf_drv_csense_event_handler_t event_handler)
+{
+ ASSERT(m_csense.module_state == NRFX_DRV_STATE_UNINITIALIZED);
+ ASSERT(p_config->output_pin <= NUMBER_OF_PINS);
+
+ ret_code_t err_code;
+
+ if (p_config == NULL)
+ {
+ return NRF_ERROR_INVALID_PARAM;
+ }
+
+ if (event_handler == NULL)
+ {
+ return NRF_ERROR_INVALID_PARAM;
+ }
+
+ m_csense.busy = false;
+
+#if USE_COMP == 0
+ m_csense.output_pin = p_config->output_pin;
+ nrf_gpio_cfg_output(m_csense.output_pin);
+ nrf_gpio_pin_set(m_csense.output_pin);
+#endif //COMP_PRESENT
+
+ m_csense.event_handler = event_handler;
+
+#if USE_COMP
+ err_code = comp_init();
+ if (err_code != NRF_SUCCESS)
+ {
+ return err_code;
+ }
+ err_code = timer_init();
+ if (err_code != NRF_SUCCESS)
+ {
+ return err_code;
+ }
+ err_code = ppi_init();
+ if (err_code != NRF_SUCCESS)
+ {
+ return err_code;
+ }
+#else
+#ifdef ADC_PRESENT
+ err_code = adc_init();
+ if (err_code != NRF_SUCCESS)
+ {
+ return err_code;
+ }
+#elif defined(SAADC_PRESENT)
+ err_code = saadc_init();
+ if (err_code != NRF_SUCCESS)
+ {
+ return err_code;
+ }
+#endif //ADC_PRESENT
+#endif //USE_COMP
+
+ m_csense.module_state = NRFX_DRV_STATE_INITIALIZED;
+
+ return NRF_SUCCESS;
+}
+
+ret_code_t nrf_drv_csense_uninit(void)
+{
+ ASSERT(m_csense.module_state != NRFX_DRV_STATE_UNINITIALIZED);
+
+ nrf_drv_csense_channels_disable(0xFF);
+
+#if USE_COMP
+ ret_code_t err_code;
+ uint8_t i;
+
+ nrf_drv_timer_uninit(&m_timer0);
+ nrf_drv_timer_uninit(&m_timer1);
+ nrf_drv_comp_uninit();
+ for (i =0; i < 3; i++)
+ {
+ err_code = nrf_drv_ppi_channel_free(m_ppi_channels[i]);
+ if (err_code != NRF_SUCCESS)
+ {
+ return err_code;
+ }
+ }
+ err_code = nrf_drv_ppi_uninit();
+ if (err_code != NRF_SUCCESS)
+ {
+ return err_code;
+ }
+#else
+#ifdef ADC_PRESENT
+ nrfx_adc_uninit();
+#elif defined(SAADC_PRESENT)
+ nrf_drv_saadc_uninit();
+#endif //ADC_PRESENT
+#endif //USE_COMP
+
+ m_csense.module_state = NRFX_DRV_STATE_UNINITIALIZED;
+
+ memset((void*)&m_csense, 0, sizeof(m_csense));
+
+ return NRF_SUCCESS;
+}
+
+void nrf_drv_csense_channels_enable(uint8_t channels_mask)
+{
+ ASSERT(m_csense.module_state != NRFX_DRV_STATE_UNINITIALIZED);
+
+ m_csense.busy = true;
+
+ m_csense.module_state = NRFX_DRV_STATE_POWERED_ON;
+
+ m_csense.adc_channels_input_mask |= channels_mask;
+
+ m_csense.busy = false;
+}
+
+void nrf_drv_csense_channels_disable(uint8_t channels_mask)
+{
+ ASSERT(m_csense.module_state == NRFX_DRV_STATE_POWERED_ON);
+
+ m_csense.adc_channels_input_mask &= ~channels_mask;
+
+ if (m_csense.adc_channels_input_mask == 0)
+ {
+ m_csense.module_state = NRFX_DRV_STATE_INITIALIZED;
+ }
+}
+
+uint16_t nrf_drv_csense_channel_read(uint8_t csense_channel)
+{
+ return m_csense.analog_values[csense_channel];
+}
+
+ret_code_t nrf_drv_csense_sample(void)
+{
+ ASSERT(m_csense.module_state == NRFX_DRV_STATE_POWERED_ON);
+
+ if (m_csense.adc_channels_input_mask != 0)
+ {
+ if (m_csense.channels_to_read == 0)
+ {
+#if USE_COMP == 0 && defined(SAADC_PRESENT)
+ nrf_saadc_enable();
+#endif
+ if (nrf_drv_csense_is_busy() == true)
+ {
+ return NRF_ERROR_BUSY;
+ }
+ m_csense.busy = true;
+ m_csense.channels_to_read = m_csense.adc_channels_input_mask;
+ calculate_next_channel();
+ }
+
+#if USE_COMP
+ if (!m_csense.timers_powered_on)
+ {
+ nrf_drv_timer_enable(&m_timer0);
+ nrf_drv_timer_enable(&m_timer1);
+ m_csense.timers_powered_on = true;
+ }
+ else
+ {
+ nrf_drv_timer_resume(&m_timer0);
+ nrf_drv_timer_resume(&m_timer1);
+ }
+ nrf_drv_comp_pin_select((nrf_comp_input_t)m_csense.cur_chann_idx);
+ nrf_drv_comp_start(0, 0);
+#else
+ ret_code_t err_code;
+#ifdef ADC_PRESENT
+ adc_channel.config.config.ain = (nrf_adc_config_input_t)(1<<m_csense.cur_chann_idx);
+ nrf_gpio_pin_clear(m_csense.output_pin);
+ err_code = nrfx_adc_sample_convert(&adc_channel, NULL);
+#elif defined(SAADC_PRESENT)
+ saadc_channel.pin_p = (nrf_saadc_input_t)(m_csense.cur_chann_idx + 1);
+ nrf_saadc_channel_input_set(0, saadc_channel.pin_p, NRF_SAADC_INPUT_DISABLED);
+ nrf_gpio_pin_clear(m_csense.output_pin);
+ err_code = nrf_drv_saadc_sample();
+#endif //ADC_PRESENT
+ if (err_code != NRF_SUCCESS)
+ {
+ return err_code;
+ }
+#endif //USE_COMP
+ }
+
+ return NRF_SUCCESS;
+}
+
+bool nrf_drv_csense_is_busy(void)
+{
+ return m_csense.busy;
+}
+#endif //NRF_MODULE_ENABLED(NRF_DRV_CSENSE)
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/csense_drv/nrf_drv_csense.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/csense_drv/nrf_drv_csense.h
new file mode 100644
index 0000000..e60bd9d
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/csense_drv/nrf_drv_csense.h
@@ -0,0 +1,150 @@
+/**
+ * Copyright (c) 2016 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#ifndef NRF_DRV_CSENSE_H__
+#define NRF_DRV_CSENSE_H__
+
+#include <stdint.h>
+#include "sdk_errors.h"
+#include "app_timer.h"
+
+/** @file
+ *
+ * @defgroup nrf_drv_csense Capacitive sensor low-level library
+ * @{
+ * @ingroup app_common
+ *
+ * @brief Module for using the capacitive sensor on low-energy level.
+ */
+
+/** @brief Maximum number of analog inputs. */
+#define MAX_ANALOG_INPUTS 8
+
+/**
+ * @brief Module initializing structure.
+ */
+typedef struct
+{
+ uint8_t output_pin; /**< Pin on which to generate voltage for charging the capacitors. */
+}nrf_drv_csense_config_t;
+
+/**
+ * @brief Structure holding event parameters.
+ */
+typedef struct
+{
+ uint16_t read_value; /**< Value which was read on the analog channel. For nRF51, this value is voltage in millivolts. For nRF52, it is time in ticks of 10 periods of the relaxation oscillator. Voltage corresponds to capacitance of the pad attached to analog channel and gets higher once it
+ is touched. Period of relaxation also corresponds to the pad capacitance and increases its value when capacitance gets
+ higher. */
+ uint8_t analog_channel; /**< Index of the analog channel from which the value was read. */
+}nrf_drv_csense_evt_t;
+
+/**
+ * @brief Capacitive sensor event handler. Called from conversion handler.
+ *
+ * @param[in] event_struct Structure holding event parameters.
+ */
+typedef void (* nrf_drv_csense_event_handler_t) (nrf_drv_csense_evt_t * p_event_struct);
+
+/**
+ * @brief Function for initializing the module.
+ *
+ * @details After calling this function, the module is in initialized state and all channels are disabled. The @ref nrf_drv_csense_channels_enable
+ * function must be called. This function initializes all modules required by the capacitive sensor library: ADC for (nRF51) or TIMERs, PPIs, and COMP (for nRF52).
+ *
+ * @param[in] p_config Structure for initializing the module.
+ * @param[in] event_handler Event handler for capacitive sensor events.
+ *
+ * @retval NRF_ERROR_INVALID_PARAM Invalid parameter.
+ * @retval NRF_ERROR_NO_MEM Timer operations queue was full.
+ * @retval NRF_ERROR_INTERNAL Error occurred during timers, PPI's, or COMP initialization.
+ * @retval NRF_SUCCESS Module was initialized successfully.
+ *
+ * @sa nrf_drv_csense_channels_enable
+ */
+ret_code_t nrf_drv_csense_init(nrf_drv_csense_config_t const * p_config, nrf_drv_csense_event_handler_t event_handler);
+
+/**
+ * @brief Function for unintializing the capacitive sensor. Clears the mask of enabled channels.
+ *
+ * @return Values returned by @ref nrf_drv_ppi_channel_free.
+ */
+ret_code_t nrf_drv_csense_uninit(void);
+
+/**
+ * @brief Function for enabling analog channels for the capacitive sensor.
+ *
+ * @param[in] channels_mask Mask of analog channels to be enabled.
+ */
+void nrf_drv_csense_channels_enable(uint8_t channels_mask);
+
+/**
+ * @brief Function for disabling analog channels of the capacitive sensor.
+ *
+ * @param[in] channels_mask Mask of analog channels to be disabled.
+ */
+void nrf_drv_csense_channels_disable(uint8_t channels_mask);
+
+/**
+ * @brief Function for getting the last read value from an analog channel.
+ *
+ * @param[in] csense_channel Number of the channel to get the value from.
+ *
+ * @return Analog value measured on the channel.
+ */
+uint16_t nrf_drv_csense_channel_read(uint8_t csense_channel);
+
+/**
+ * @brief Function for triggering a measurement on all enabled analog channels. The handler will be called on every completed measurement.
+ *
+ * @retval NRF_ERROR_BUSY If the module was busy or SAADC module is in use and was busy.
+ * @retval NRF_SUCCESS If the measurement was triggered successfully.
+ */
+ret_code_t nrf_drv_csense_sample(void);
+
+/**
+ * @brief Function for checking if the module is busy.
+ *
+ * @return True if busy or false if not busy.
+ */
+bool nrf_drv_csense_is_busy(void);
+
+/** @} */
+
+#endif //NRF_DRV_CSENSE_H__
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/delay/nrf_delay.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/delay/nrf_delay.h
new file mode 100644
index 0000000..2a6faf2
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/delay/nrf_delay.h
@@ -0,0 +1,80 @@
+/**
+ * Copyright (c) 2011 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+
+#ifndef _NRF_DELAY_H
+#define _NRF_DELAY_H
+
+#include <nrfx.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @brief Function for delaying execution for a number of microseconds.
+ *
+ * @param us_time Number of microseconds to wait.
+ */
+#define nrf_delay_us(us_time) NRFX_DELAY_US(us_time)
+
+
+/**
+ * @brief Function for delaying execution for a number of milliseconds.
+ *
+ * @param ms_time Number of milliseconds to wait.
+ */
+
+__STATIC_INLINE void nrf_delay_ms(uint32_t ms_time)
+{
+ if (ms_time == 0)
+ {
+ return;
+ }
+
+ do {
+ nrf_delay_us(1000);
+ } while (--ms_time);
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/ecc/ecc.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/ecc/ecc.c
new file mode 100644
index 0000000..cbc3d9d
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/ecc/ecc.c
@@ -0,0 +1,206 @@
+/**
+ * Copyright (c) 2016 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 Elliptic Curve Cryptography Interface
+ *
+ */
+
+#include <stdint.h>
+#include <stdio.h>
+#include <string.h>
+#include "nordic_common.h"
+#include "app_timer.h"
+#include "app_util.h"
+#include "nrf_log.h"
+#include "nrf_drv_rng.h"
+#include "ecc.h"
+
+#include "uECC.h"
+
+
+static int ecc_rng(uint8_t *dest, unsigned size)
+{
+ nrf_drv_rng_block_rand(dest, (uint32_t) size);
+ return 1;
+}
+
+void ecc_init(bool rng)
+{
+ if (rng)
+ {
+ uECC_set_rng(ecc_rng);
+ }
+}
+
+ret_code_t ecc_p256_keypair_gen(uint8_t *p_le_sk, uint8_t *p_le_pk)
+{
+ const struct uECC_Curve_t * p_curve;
+
+ if (!p_le_sk || !p_le_pk)
+ {
+ return NRF_ERROR_NULL;
+ }
+
+ if (!is_word_aligned(p_le_sk) || !is_word_aligned(p_le_pk))
+ {
+ return NRF_ERROR_INVALID_ADDR;
+ }
+
+ p_curve = uECC_secp256r1();
+
+ int ret = uECC_make_key((uint8_t *) p_le_pk, (uint8_t *) p_le_sk, p_curve);
+ if (!ret)
+ {
+ return NRF_ERROR_INTERNAL;
+ }
+
+ return NRF_SUCCESS;
+}
+
+ret_code_t ecc_p256_public_key_compute(uint8_t const *p_le_sk, uint8_t *p_le_pk)
+{
+ const struct uECC_Curve_t * p_curve;
+
+ if (!p_le_sk || !p_le_pk)
+ {
+ return NRF_ERROR_NULL;
+ }
+
+ if (!is_word_aligned(p_le_sk) || !is_word_aligned(p_le_pk))
+ {
+ return NRF_ERROR_INVALID_ADDR;
+ }
+
+ p_curve = uECC_secp256r1();
+
+ //NRF_LOG_INFO("uECC_compute_public_key");
+ int ret = uECC_compute_public_key((uint8_t *) p_le_sk, (uint8_t *) p_le_pk, p_curve);
+ if (!ret)
+ {
+ return NRF_ERROR_INTERNAL;
+ }
+
+ //NRF_LOG_INFO("uECC_compute_public_key complete: %d", ret);
+ return NRF_SUCCESS;
+}
+
+ret_code_t ecc_p256_shared_secret_compute(uint8_t const *p_le_sk, uint8_t const *p_le_pk, uint8_t *p_le_ss)
+{
+ const struct uECC_Curve_t * p_curve;
+
+ if (!p_le_sk || !p_le_pk || !p_le_ss)
+ {
+ return NRF_ERROR_NULL;
+ }
+
+ if (!is_word_aligned(p_le_sk) || !is_word_aligned(p_le_pk) || !is_word_aligned(p_le_ss))
+ {
+ return NRF_ERROR_INVALID_ADDR;
+ }
+
+ p_curve = uECC_secp256r1();
+
+ //NRF_LOG_INFO("uECC_shared_secret");
+ int ret = uECC_shared_secret((uint8_t *) p_le_pk, (uint8_t *) p_le_sk, p_le_ss, p_curve);
+ if (!ret)
+ {
+ return NRF_ERROR_INTERNAL;
+ }
+
+ //NRF_LOG_INFO("uECC_shared_secret complete: %d", ret);
+ return NRF_SUCCESS;
+}
+
+ret_code_t ecc_p256_sign(uint8_t const *p_le_sk, uint8_t const * p_le_hash, uint32_t hlen, uint8_t *p_le_sig)
+{
+ const struct uECC_Curve_t * p_curve;
+
+ if (!p_le_sk || !p_le_hash || !p_le_sig)
+ {
+ return NRF_ERROR_NULL;
+ }
+
+ if (!is_word_aligned(p_le_sk) || !is_word_aligned(p_le_hash) || !is_word_aligned(p_le_sig))
+ {
+ return NRF_ERROR_INVALID_ADDR;
+ }
+
+ p_curve = uECC_secp256r1();
+
+ //NRF_LOG_INFO("uECC_sign");
+ int ret = uECC_sign((const uint8_t *) p_le_sk, (const uint8_t *) p_le_hash, (unsigned) hlen, (uint8_t *) p_le_sig, p_curve);
+ if (!ret)
+ {
+ return NRF_ERROR_INTERNAL;
+ }
+
+ //NRF_LOG_INFO("uECC_sign complete: %d", ret);
+ return NRF_SUCCESS;
+}
+
+ret_code_t ecc_p256_verify(uint8_t const *p_le_pk, uint8_t const * p_le_hash, uint32_t hlen, uint8_t const *p_le_sig)
+{
+ const struct uECC_Curve_t * p_curve;
+
+ if (!p_le_pk || !p_le_hash || !p_le_sig)
+ {
+ return NRF_ERROR_NULL;
+ }
+
+ if (!is_word_aligned(p_le_pk) || !is_word_aligned(p_le_hash) || !is_word_aligned(p_le_sig))
+ {
+ return NRF_ERROR_INVALID_ADDR;
+ }
+
+ p_curve = uECC_secp256r1();
+
+ //NRF_LOG_INFO("uECC_verify");
+ int ret = uECC_verify((const uint8_t *) p_le_pk, (const uint8_t *) p_le_hash, (unsigned) hlen, (uint8_t *) p_le_sig, p_curve);
+ if (!ret)
+ {
+ return NRF_ERROR_INVALID_DATA;
+ }
+
+ //NRF_LOG_INFO("uECC_verify complete: %d", ret);
+ return NRF_SUCCESS;
+
+}
+
+
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/ecc/ecc.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/ecc/ecc.h
new file mode 100644
index 0000000..95983ec
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/ecc/ecc.h
@@ -0,0 +1,143 @@
+/**
+ * Copyright (c) 2016 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+/**
+ * @defgroup ecc Elliptic Curve Cryptography interface
+ * @{
+ * @ingroup app_common
+ * @brief Elliptic Curve Cryptography interface
+ */
+
+#ifndef ECC_H__
+#define ECC_H__
+
+#include <stdint.h>
+#include <stdbool.h>
+#include "nordic_common.h"
+#include "nrf_error.h"
+#include "sdk_errors.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define ECC_P256_SK_LEN 32
+#define ECC_P256_PK_LEN 64
+
+/**@brief Initialize the ECC module.
+ *
+ * @param[in] rng Use a random number generator.
+ *
+ * */
+void ecc_init(bool rng);
+
+/**@brief Create a public/private key pair.
+ *
+ * @param[out] p_le_sk Private key. Pointer must be aligned to a 4-byte boundary.
+ * @param[out] p_le_pk Public key. Pointer must be aligned to a 4-byte boundary.
+ *
+ * @retval NRF_SUCCESS Key pair successfuly created.
+ * @retval NRF_ERROR_NULL NULL pointer provided.
+ * @retval NRF_ERROR_INVALID_ADDR Unaligned pointer provided.
+ * @retval NRF_ERROR_INTERNAL Internal error during key generation.
+ */
+ret_code_t ecc_p256_keypair_gen(uint8_t *p_le_sk, uint8_t* p_le_pk);
+
+/**@brief Create a public key from a provided private key.
+ *
+ * @param[in] p_le_sk Private key. Pointer must be aligned to a 4-byte boundary.
+ * @param[out] p_le_pk Public key. Pointer must be aligned to a 4-byte boundary.
+ *
+ * @retval NRF_SUCCESS Public key successfuly created.
+ * @retval NRF_ERROR_NULL NULL pointer provided.
+ * @retval NRF_ERROR_INVALID_ADDR Unaligned pointer provided.
+ * @retval NRF_ERROR_INTERNAL Internal error during key generation.
+ */
+ret_code_t ecc_p256_public_key_compute(uint8_t const *p_le_sk, uint8_t* p_le_pk);
+
+/**@brief Create a shared secret from a provided public/private key pair.
+ *
+ * @param[in] p_le_sk Private key. Pointer must be aligned to a 4-byte boundary.
+ * @param[in] p_le_pk Public key. Pointer must be aligned to a 4-byte boundary.
+ * @param[out] p_le_ss Shared secret. Pointer must be aligned to a 4-byte boundary.
+ *
+ * @retval NRF_SUCCESS Shared secret successfuly created.
+ * @retval NRF_ERROR_NULL NULL pointer provided.
+ * @retval NRF_ERROR_INVALID_ADDR Unaligned pointer provided.
+ * @retval NRF_ERROR_INTERNAL Internal error during key generation.
+ */
+ret_code_t ecc_p256_shared_secret_compute(uint8_t const *p_le_sk, uint8_t const * p_le_pk, uint8_t *p_le_ss);
+
+/**@brief Sign a hash or digest using a private key.
+ *
+ * @param[in] p_le_sk Private key. Pointer must be aligned to a 4-byte boundary.
+ * @param[in] p_le_hash Hash. Pointer must be aligned to a 4-byte boundary.
+ * @param[in] hlen Hash length in bytes.
+ * @param[out] p_le_sig Signature. Pointer must be aligned to a 4-byte boundary.
+ *
+ * @retval NRF_SUCCESS Signature successfuly created.
+ * @retval NRF_ERROR_NULL NULL pointer provided.
+ * @retval NRF_ERROR_INVALID_ADDR Unaligned pointer provided.
+ * @retval NRF_ERROR_INTERNAL Internal error during signature generation.
+ */
+ret_code_t ecc_p256_sign(uint8_t const *p_le_sk, uint8_t const * p_le_hash, uint32_t hlen, uint8_t *p_le_sig);
+
+/**@brief Verify a signature using a public key.
+ *
+ * @param[in] p_le_pk Public key. Pointer must be aligned to a 4-byte boundary.
+ * @param[in] p_le_hash Hash. Pointer must be aligned to a 4-byte boundary.
+ * @param[in] hlen Hash length in bytes.
+ * @param[in] p_le_sig Signature. Pointer must be aligned to a 4-byte boundary.
+ *
+ * @retval NRF_SUCCESS Signature verified.
+ * @retval NRF_ERROR_INVALID_DATA Signature failed verification.
+ * @retval NRF_ERROR_NULL NULL pointer provided.
+ * @retval NRF_ERROR_INVALID_ADDR Unaligned pointer provided.
+ * @retval NRF_ERROR_INTERNAL Internal error during signature verification.
+ */
+ret_code_t ecc_p256_verify(uint8_t const *p_le_pk, uint8_t const * p_le_hash, uint32_t hlen, uint8_t const *p_le_sig);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // ECC_H__
+
+/** @} */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/experimental_libuarte/nrf_libuarte.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/experimental_libuarte/nrf_libuarte.c
new file mode 100644
index 0000000..6f44d0b
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/experimental_libuarte/nrf_libuarte.c
@@ -0,0 +1,578 @@
+/**
+ * Copyright (c) 2018 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#include "sdk_config.h"
+#include "nrf_libuarte.h"
+#include "nrfx_ppi.h"
+#include "nrf_uarte.h"
+#include "nrf_gpio.h"
+#include "nrfx_timer.h"
+
+
+
+#define NRF_LOG_MODULE_NAME libUARTE
+#if NRF_LIBUARTE_CONFIG_LOG_ENABLED
+#define NRF_LOG_LEVEL NRF_LIBUARTE_CONFIG_LOG_LEVEL
+#define NRF_LOG_INFO_COLOR NRF_LIBUARTE_CONFIG_INFO_COLOR
+#define NRF_LOG_DEBUG_COLOR NRF_LIBUARTE_CONFIG_DEBUG_COLOR
+#else // NRF_LIBUARTE_CONFIG_LOG_ENABLED
+#define NRF_LOG_LEVEL 0
+#endif // NRF_LIBUARTE_CONFIG_LOG_ENABLED
+#include "nrf_log.h"
+NRF_LOG_MODULE_REGISTER();
+
+
+#define INTERRUPTS_MASK \
+ (NRF_UARTE_INT_ENDRX_MASK | NRF_UARTE_INT_RXSTARTED_MASK | NRF_UARTE_INT_ERROR_MASK | \
+ NRF_UARTE_INT_ENDTX_MASK | NRF_UARTE_INT_TXSTOPPED_MASK)
+
+#define UART_DRV_UARTE CONCAT_2(NRF_UARTE, NRF_LIBUARTE_CONFIG_UARTE_USED)
+
+#if NRF_LIBUARTE_CONFIG_UARTE_USED == 0
+#define UART_DRV_IRQn UARTE0_UART0_IRQn
+#define UART_DRV_IRQHandler UARTE0_UART0_IRQHandler
+#define MAX_DMA_XFER_LEN (1<<UARTE0_EASYDMA_MAXCNT_SIZE)
+#elif NRF_LIBUARTE_CONFIG_UARTE_USED == 1
+#define UART_DRV_IRQn UARTE1_UART1_IRQn
+#define UART_DRV_IRQHandler UARTE1_IRQHandler
+#define MAX_DMA_XFER_LEN (1<<UARTE1_EASYDMA_MAXCNT_SIZE)
+#endif
+
+typedef enum
+{
+ PPI_CH_EXT_TRIGGER_STARTRX_EN_ENDRX_STARTX,
+ PPI_CH_RXSTARTED_EXT_TSK,
+ PPI_CH_EXT_STOP_STOPRX,
+ PPI_CH_EXT_STOP_GROUPS_EN,
+ PPI_CH_RXRDY_TIMER_COUNT,
+
+ PPI_CH_RX_MAX,
+ PPI_CH_ENDRX_STARTRX = PPI_CH_RX_MAX,
+ PPI_CH_ENDRX_EXT_TSK,
+
+ PPI_CH_RX_GROUP_MAX,
+
+ PPI_CH_ENDTX_STARTTX = PPI_CH_RX_GROUP_MAX,
+
+ PPI_CH_MAX
+} nrf_libuarte_ppi_channel_t;
+
+typedef enum
+{
+ PPI_GROUP_ENDRX_STARTRX,
+ PPI_GROUP_ENDRX_EXT_RXDONE_TSK,
+ PPI_GROUP_MAX
+} nrf_libuarte_ppi_group_t;
+
+static nrfx_timer_t m_timer = NRFX_TIMER_INSTANCE(NRF_LIBUARTE_CONFIG_TIMER_USED);
+
+#if CONCAT_3(NRFX_TIMER, NRF_LIBUARTE_CONFIG_TIMER_USED,_ENABLED) == 0
+#error "Timer instance not enabled"
+#endif
+
+static nrf_ppi_channel_t m_ppi_channels[PPI_CH_MAX];
+static nrf_ppi_channel_group_t m_ppi_groups[PPI_GROUP_MAX];
+
+static uint8_t * mp_tx;
+static size_t m_tx_len;
+static size_t m_tx_cur_idx;
+
+static uint8_t * mp_cur_rx;
+static uint8_t * mp_next_rx;
+static uint8_t * mp_next_next_rx;
+static nrf_libuarte_evt_handler_t m_evt_handler;
+static uint32_t m_last_rx_byte_cnt;
+static uint32_t m_last_pin_rx_byte_cnt;
+static uint8_t m_tx_chunk8;
+static uint32_t m_chunk_size;
+
+#define PPI_CH_SETUP(_ch, _evt, _tsk, _fork) \
+ ret = nrfx_ppi_channel_assign(m_ppi_channels[_ch], _evt, _tsk); \
+ if (ret != NRF_SUCCESS) \
+ { \
+ return NRF_ERROR_INTERNAL; \
+ } \
+ if (_fork) \
+ { \
+ ret = nrfx_ppi_channel_fork_assign(m_ppi_channels[_ch], _fork); \
+ if (ret != NRF_SUCCESS) \
+ { \
+ return NRF_ERROR_INTERNAL; \
+ } \
+ }
+
+#define PPI_GROUP_SETUP(_ch, _group, _en_tsk, _dis_tsk) \
+ ret = nrfx_ppi_channel_include_in_group(m_ppi_channels[_ch], \
+ m_ppi_groups[_group]); \
+ if (ret != NRF_SUCCESS) \
+ { \
+ return NRF_ERROR_INTERNAL; \
+ } \
+ _en_tsk = nrfx_ppi_task_addr_group_enable_get(m_ppi_groups[_group]); \
+ _dis_tsk = nrfx_ppi_task_addr_group_disable_get(m_ppi_groups[_group]);
+
+
+static ret_code_t ppi_configure(nrf_libuarte_config_t * p_config)
+{
+ ret_code_t ret;
+
+/*lint -save -e666 */
+
+ ///////////////////////////////////////////////////////////////////////////////
+ uint32_t group1_en_tsk;
+ uint32_t group1_dis_tsk;
+
+ PPI_GROUP_SETUP(PPI_CH_ENDRX_STARTRX, PPI_GROUP_ENDRX_STARTRX, group1_en_tsk, group1_dis_tsk);
+
+ PPI_CH_SETUP(PPI_CH_ENDRX_STARTRX,
+ nrf_uarte_event_address_get(UART_DRV_UARTE, NRF_UARTE_EVENT_ENDRX),
+ nrf_uarte_task_address_get(UART_DRV_UARTE, NRF_UARTE_TASK_STARTRX),
+ nrfx_timer_capture_task_address_get(&m_timer, 0));
+
+
+ ///////////////////////////////////////////////////////////////////////////////
+ uint32_t group2_en_tsk;
+ uint32_t group2_dis_tsk;
+
+ PPI_GROUP_SETUP(PPI_CH_ENDRX_EXT_TSK, PPI_GROUP_ENDRX_EXT_RXDONE_TSK, group2_en_tsk, group2_dis_tsk);
+
+ PPI_CH_SETUP(PPI_CH_ENDRX_EXT_TSK,
+ nrf_uarte_event_address_get(UART_DRV_UARTE, NRF_UARTE_EVENT_ENDRX),
+ nrfx_timer_capture_task_address_get(&m_timer, 0),
+ p_config->rxdone_tsk);
+
+ ///////////////////////////////////////////////////////////////////////////////
+ PPI_CH_SETUP(PPI_CH_EXT_TRIGGER_STARTRX_EN_ENDRX_STARTX,
+ p_config->startrx_evt,
+ group1_en_tsk,
+ nrf_uarte_task_address_get(UART_DRV_UARTE, NRF_UARTE_TASK_STARTRX));
+
+ ///////////////////////////////////////////////////////////////////////////////
+ PPI_CH_SETUP(PPI_CH_RXSTARTED_EXT_TSK,
+ nrf_uarte_event_address_get(UART_DRV_UARTE, NRF_UARTE_EVENT_RXSTARTED),
+ group2_dis_tsk,
+ p_config->rxstarted_tsk);
+
+ if (p_config->endrx_evt)
+ {
+ ///////////////////////////////////////////////////////////////////////////////
+ PPI_CH_SETUP(PPI_CH_EXT_STOP_STOPRX,
+ p_config->endrx_evt,
+ nrf_uarte_task_address_get(UART_DRV_UARTE, NRF_UARTE_TASK_STOPRX),
+ group2_en_tsk);
+
+ ///////////////////////////////////////////////////////////////////////////////
+ PPI_CH_SETUP(PPI_CH_EXT_STOP_GROUPS_EN,
+ p_config->endrx_evt,
+ group1_dis_tsk,
+ nrfx_timer_capture_task_address_get(&m_timer, 1));
+ }
+
+ ////////////////////////////////TX///////////////////////////////////////////////
+ PPI_CH_SETUP(PPI_CH_ENDTX_STARTTX,
+ nrf_uarte_event_address_get(UART_DRV_UARTE, NRF_UARTE_EVENT_ENDTX),
+ nrf_uarte_task_address_get(UART_DRV_UARTE, NRF_UARTE_TASK_STARTTX),
+ 0);
+
+ ////////////////////////////////TX///////////////////////////////////////////////
+ PPI_CH_SETUP(PPI_CH_RXRDY_TIMER_COUNT,
+ nrf_uarte_event_address_get(UART_DRV_UARTE, NRF_UARTE_EVENT_RXDRDY),
+ nrfx_timer_task_address_get(&m_timer, NRF_TIMER_TASK_COUNT),
+ 0);
+
+ if (ret != NRFX_SUCCESS)
+ {
+ return NRF_ERROR_INTERNAL;
+ }
+ return NRF_SUCCESS;
+/*lint -restore */
+}
+
+void tmr_evt_handler(nrf_timer_event_t event_type, void * p_context)
+{
+ UNUSED_PARAMETER(event_type);
+ UNUSED_PARAMETER(p_context);
+}
+
+ret_code_t nrf_libuarte_init(nrf_libuarte_config_t * p_config, nrf_libuarte_evt_handler_t evt_handler)
+{
+ ret_code_t ret;
+ m_evt_handler = evt_handler;
+ mp_cur_rx = NULL;
+ mp_next_rx = NULL;
+ mp_next_next_rx = NULL;
+ mp_tx = NULL;
+
+ //UART init
+ nrf_gpio_pin_set(p_config->tx_pin);
+ nrf_gpio_cfg_output(p_config->tx_pin);
+ nrf_gpio_cfg_input(p_config->rx_pin, NRF_GPIO_PIN_NOPULL);
+ nrf_uarte_baudrate_set(UART_DRV_UARTE, p_config->baudrate);
+ nrf_uarte_configure(UART_DRV_UARTE, p_config->parity, p_config->hwfc);
+ nrf_uarte_txrx_pins_set(UART_DRV_UARTE, p_config->tx_pin, p_config->rx_pin);
+
+ if (p_config->hwfc == NRF_UARTE_HWFC_ENABLED)
+ {
+ if (p_config->cts_pin != NRF_UARTE_PSEL_DISCONNECTED)
+ {
+ nrf_gpio_cfg_input(p_config->cts_pin, NRF_GPIO_PIN_NOPULL);
+ }
+ if (p_config->rts_pin != NRF_UARTE_PSEL_DISCONNECTED)
+ {
+ nrf_gpio_pin_set(p_config->rts_pin);
+ nrf_gpio_cfg_output(p_config->rts_pin);
+ }
+ nrf_uarte_hwfc_pins_set(UART_DRV_UARTE, p_config->rts_pin, p_config->cts_pin);
+ }
+
+ nrf_uarte_int_enable(UART_DRV_UARTE, INTERRUPTS_MASK);
+
+ NVIC_SetPriority(UART_DRV_IRQn, p_config->irq_priority);
+ NVIC_ClearPendingIRQ(UART_DRV_IRQn);
+ NVIC_EnableIRQ(UART_DRV_IRQn);
+
+ nrf_uarte_enable(UART_DRV_UARTE);
+
+ nrfx_timer_config_t tmr_config = NRFX_TIMER_DEFAULT_CONFIG;
+ tmr_config.mode = NRF_TIMER_MODE_COUNTER;
+ tmr_config.bit_width = NRF_TIMER_BIT_WIDTH_32;
+ ret = nrfx_timer_init(&m_timer, &tmr_config, tmr_evt_handler);
+ if (ret != NRFX_SUCCESS)
+ {
+ return NRF_ERROR_INTERNAL;
+ }
+ nrfx_timer_enable(&m_timer);
+ nrfx_timer_clear(&m_timer);
+ m_last_rx_byte_cnt = 0;
+ m_last_pin_rx_byte_cnt = 0;
+
+ uint32_t i;
+ for (i = 0; i < PPI_CH_MAX; i++)
+ {
+ ret = nrfx_ppi_channel_alloc(&m_ppi_channels[i]);
+ if (ret != NRFX_SUCCESS)
+ {
+ //we don't free already allocated channels, system is wrongly configured.
+ return NRF_ERROR_INTERNAL;
+ }
+ }
+
+ for (i = 0; i < PPI_GROUP_MAX; i++)
+ {
+ ret = nrfx_ppi_group_alloc(&m_ppi_groups[i]);
+ if (ret != NRFX_SUCCESS)
+ {
+ //we don't free already allocated channels, system is wrongly configured.
+ return NRF_ERROR_INTERNAL;
+ }
+ }
+
+ return ppi_configure(p_config);
+}
+
+void nrf_libuarte_uninit(void)
+{
+ NVIC_DisableIRQ(UART_DRV_IRQn);
+ nrf_uarte_int_disable(UART_DRV_UARTE, 0xFFFFFFFF);
+ nrf_uarte_disable(UART_DRV_UARTE);
+
+ nrfx_timer_disable(&m_timer);
+ nrfx_timer_uninit(&m_timer);
+
+ uint32_t i;
+ ret_code_t ret;
+ for (i = 0; i < PPI_CH_MAX; i++)
+ {
+ ret = nrfx_ppi_channel_disable(m_ppi_channels[i]);
+ ASSERT(ret == NRFX_SUCCESS)
+ ret = nrfx_ppi_channel_free(m_ppi_channels[i]);
+ ASSERT(ret == NRFX_SUCCESS)
+ }
+
+ for (i = 0; i < PPI_GROUP_MAX; i++)
+ {
+ ret = nrfx_ppi_group_free(m_ppi_groups[i]);
+ ASSERT(ret == NRFX_SUCCESS)
+ }
+
+}
+
+ret_code_t nrf_libuarte_tx(uint8_t * p_data, size_t len)
+{
+ if (mp_tx)
+ {
+ return NRF_ERROR_BUSY;
+ }
+ mp_tx = p_data;
+ m_tx_len = len;
+ m_tx_cur_idx = 0;
+ uint8_t first_chunk;
+
+ if (len <= MAX_DMA_XFER_LEN)
+ {
+ first_chunk = len;
+ m_tx_chunk8 = 0;
+ }
+ else
+ {
+ uint32_t num_of_chunks = CEIL_DIV(len, MAX_DMA_XFER_LEN);
+ m_tx_chunk8 = len/num_of_chunks;
+ first_chunk = m_tx_chunk8 + len%m_tx_chunk8;
+ }
+
+ NRF_LOG_DEBUG("Started TX total length:%d, first chunk:%d", len, first_chunk);
+ nrf_uarte_tx_buffer_set(UART_DRV_UARTE, p_data, first_chunk);
+ nrf_uarte_event_clear(UART_DRV_UARTE, NRF_UARTE_EVENT_TXSTARTED);
+ nrf_uarte_task_trigger(UART_DRV_UARTE, NRF_UARTE_TASK_STARTTX);
+
+ if (len > MAX_DMA_XFER_LEN)
+ {
+ while(nrf_uarte_event_check(UART_DRV_UARTE, NRF_UARTE_EVENT_TXSTARTED) == 0)
+ {
+ }
+ nrf_uarte_event_clear(UART_DRV_UARTE, NRF_UARTE_EVENT_TXSTARTED);
+ nrfx_err_t err = nrfx_ppi_channel_enable(m_ppi_channels[PPI_CH_ENDTX_STARTTX]);
+ if (err != NRFX_SUCCESS)
+ {
+ return NRF_ERROR_INTERNAL;
+ }
+
+ nrf_uarte_tx_buffer_set(UART_DRV_UARTE, &p_data[first_chunk], m_tx_chunk8);
+ }
+ return NRF_SUCCESS;
+}
+
+ret_code_t nrf_libuarte_rx_start(uint8_t * p_data, size_t len, bool ext_trigger_en)
+{
+
+ m_chunk_size = len;
+
+ uint32_t i;
+ for (i = 0; i < PPI_CH_RX_MAX; i++)
+ {
+ nrfx_err_t err = nrfx_ppi_channel_enable(m_ppi_channels[i]);
+ if (err != NRFX_SUCCESS)
+ {
+ return NRF_ERROR_INTERNAL;
+ }
+ }
+
+ ASSERT(len <= MAX_DMA_XFER_LEN);
+
+ if (p_data)
+ {
+ mp_cur_rx = p_data;
+ nrf_uarte_rx_buffer_set(UART_DRV_UARTE, p_data, len);
+ }
+
+ nrf_uarte_event_clear(UART_DRV_UARTE, NRF_UARTE_EVENT_ENDRX);
+ nrf_uarte_event_clear(UART_DRV_UARTE, NRF_UARTE_EVENT_RXSTARTED);
+ if (ext_trigger_en)
+ {
+ }
+ else
+ {
+
+ *(uint32_t *)nrfx_ppi_task_addr_group_enable_get(m_ppi_groups[PPI_GROUP_ENDRX_STARTRX]) = 1;
+ nrf_uarte_task_trigger(UART_DRV_UARTE, NRF_UARTE_TASK_STARTRX);
+ }
+ NRF_LOG_DEBUG("Start continues RX. Provided buffer:0x%08X", p_data);
+ return NRF_SUCCESS;
+}
+
+void nrf_libuarte_rx_buf_rsp(uint8_t * p_data, size_t len)
+{
+ if (mp_next_rx == NULL)
+ {
+ mp_next_rx = p_data;
+ NRF_LOG_DEBUG("RX buf response (next). Provided buffer:0x%08X", p_data);
+ nrf_uarte_rx_buffer_set(UART_DRV_UARTE, p_data, len);
+ }
+ else
+ {
+ NRF_LOG_DEBUG("RX buf response (mp_next_rx not NULL:0x%08X), Provided buffer:0x%08X",
+ mp_next_rx,
+ p_data);
+ mp_next_next_rx = p_data;
+ }
+}
+
+void nrf_libuarte_rx_stop(void)
+{
+ uint32_t i;
+ for (i = 0; i < PPI_CH_RX_MAX; i++)
+ {
+ nrfx_err_t err = nrfx_ppi_channel_disable(m_ppi_channels[i]);
+ ASSERT(err == NRFX_SUCCESS);
+ }
+
+ NRF_LOG_DEBUG("RX stopped.");
+ nrf_uarte_task_trigger(UART_DRV_UARTE, NRF_UARTE_TASK_STOPRX);
+}
+
+void UART_DRV_IRQHandler(void)
+{
+ if (nrf_uarte_event_check(UART_DRV_UARTE, NRF_UARTE_EVENT_ERROR))
+ {
+ nrf_uarte_event_clear(UART_DRV_UARTE, NRF_UARTE_EVENT_ERROR);
+ nrf_libuarte_evt_t evt = {
+ .type = NRF_LIBUARTE_EVT_ERROR
+ };
+ m_evt_handler(&evt);
+ }
+
+ if (nrf_uarte_event_check(UART_DRV_UARTE, NRF_UARTE_EVENT_RXSTARTED))
+ {
+ nrf_uarte_event_clear(UART_DRV_UARTE, NRF_UARTE_EVENT_RXSTARTED);
+
+ nrf_libuarte_evt_t evt = {
+ .type = NRF_LIBUARTE_EVT_RX_BUF_REQ,
+ };
+ m_evt_handler(&evt);
+ }
+
+ if (nrf_uarte_event_check(UART_DRV_UARTE, NRF_UARTE_EVENT_ENDRX))
+ {
+ nrf_uarte_event_clear(UART_DRV_UARTE, NRF_UARTE_EVENT_ENDRX);
+
+ uint32_t endrx_byte_cnt = nrfx_timer_capture_get(&m_timer, NRF_TIMER_CC_CHANNEL0);
+ uint32_t stop_byte_cnt = nrfx_timer_capture_get(&m_timer, NRF_TIMER_CC_CHANNEL1);
+
+ uint32_t dma_amount = endrx_byte_cnt - m_last_rx_byte_cnt;
+ uint32_t pin_amount = stop_byte_cnt - m_last_pin_rx_byte_cnt;
+ NRF_LOG_DEBUG("(evt) RX dma_cnt:%d, endrx_cnt:%d, stop_cnt:%d",
+ dma_amount,
+ endrx_byte_cnt,
+ stop_byte_cnt);
+ m_last_rx_byte_cnt = endrx_byte_cnt;
+ m_last_pin_rx_byte_cnt = stop_byte_cnt;
+
+ if (dma_amount || pin_amount)
+ {
+ uint32_t chunk0 = (dma_amount > m_chunk_size) ? m_chunk_size : dma_amount;
+ uint32_t chunk1 = dma_amount - chunk0;
+
+ NRF_LOG_DEBUG("RX END chunk0:%d, chunk1:%d, data[0]=%d %d",
+ chunk0,
+ chunk1,
+ mp_cur_rx[0],
+ mp_cur_rx[1]);
+ nrf_libuarte_evt_t evt = {
+ .type = NRF_LIBUARTE_EVT_RX_DATA,
+ .data = {
+ .rxtx = {
+ .p_data = mp_cur_rx,
+ .length = chunk0
+ }
+ }
+ };
+ mp_cur_rx = mp_next_rx;
+ mp_next_rx = NULL;
+ if (mp_next_next_rx)
+ {
+ mp_next_rx = mp_next_next_rx;
+ mp_next_next_rx = NULL;
+ nrf_uarte_rx_buffer_set(UART_DRV_UARTE, mp_next_rx, m_chunk_size);
+ }
+ m_evt_handler(&evt);
+
+ if ( chunk1 ||
+ ((dma_amount == m_chunk_size) && (endrx_byte_cnt == stop_byte_cnt)))
+ {
+ NRF_LOG_WARNING("RX END Chunk1:%d", chunk1);
+
+ evt.data.rxtx.length = chunk1;
+ evt.data.rxtx.p_data = mp_cur_rx;
+
+ mp_cur_rx = mp_next_rx;
+ mp_next_rx = NULL;
+ m_evt_handler(&evt);
+ }
+ }
+ }
+
+ if (nrf_uarte_event_check(UART_DRV_UARTE, NRF_UARTE_EVENT_TXSTOPPED))
+ {
+ nrf_uarte_event_clear(UART_DRV_UARTE, NRF_UARTE_EVENT_TXSTOPPED);
+ nrf_libuarte_evt_t evt = {
+ .type = NRF_LIBUARTE_EVT_TX_DONE,
+ .data = {
+ .rxtx = {
+ .p_data = mp_tx,
+ .length = m_tx_len
+ }
+ }
+ };
+ mp_tx = NULL;
+ m_evt_handler(&evt);
+ }
+
+ if (nrf_uarte_event_check(UART_DRV_UARTE, NRF_UARTE_EVENT_ENDTX))
+ {
+ nrf_uarte_event_clear(UART_DRV_UARTE, NRF_UARTE_EVENT_ENDTX);
+ uint8_t amount = nrf_uarte_tx_amount_get(UART_DRV_UARTE);
+ NRF_LOG_DEBUG("(evt) TX completed (%d)", amount);
+ m_tx_cur_idx += amount;
+ if (m_tx_cur_idx == m_tx_len)
+ {
+ nrf_uarte_event_clear(UART_DRV_UARTE, NRF_UARTE_EVENT_TXSTOPPED);
+ nrf_uarte_task_trigger(UART_DRV_UARTE, NRF_UARTE_TASK_STOPTX);
+ }
+ else
+ {
+ size_t rem_len = (m_tx_len - m_tx_cur_idx);
+ if ( rem_len <= MAX_DMA_XFER_LEN)
+ {
+ nrfx_err_t err = nrfx_ppi_channel_disable(m_ppi_channels[PPI_CH_ENDTX_STARTTX]);
+ ASSERT(err == NRFX_SUCCESS);
+ }
+ else
+ {
+ if (nrf_uarte_event_check(UART_DRV_UARTE, NRF_UARTE_EVENT_TXSTARTED) == 0)
+ {
+ NRF_LOG_ERROR("Tx not started yet!");
+ ASSERT(false);
+ }
+ nrf_uarte_event_clear(UART_DRV_UARTE, NRF_UARTE_EVENT_TXSTARTED);
+ nrf_uarte_tx_buffer_set(UART_DRV_UARTE, &mp_tx[m_tx_cur_idx + m_tx_chunk8], m_tx_chunk8);
+ }
+ }
+
+ }
+}
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/experimental_libuarte/nrf_libuarte.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/experimental_libuarte/nrf_libuarte.h
new file mode 100644
index 0000000..0c9d97b
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/experimental_libuarte/nrf_libuarte.h
@@ -0,0 +1,153 @@
+/**
+ * Copyright (c) 2018 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#ifndef NRF_LIBUARTE_H
+#define NRF_LIBUARTE_H
+
+#include "sdk_errors.h"
+#include "nrf_uarte.h"
+#include <stdint.h>
+#include <stdbool.h>
+
+/**
+ * @defgroup nrf_libuarte libUARTE
+ * @ingroup app_common
+ *
+ * @brief Module for reliable communication over UARTE.
+ *
+ * @{
+ */
+
+typedef enum
+{
+ NRF_LIBUARTE_EVT_RX_DATA, ///< Data received.
+ NRF_LIBUARTE_EVT_RX_BUF_REQ, ///< Requesting new buffer for receiving data.
+ NRF_LIBUARTE_EVT_TX_DONE, ///< Requested TX transfer completed.
+ NRF_LIBUARTE_EVT_ERROR ///< Error reported by the UARTE peripheral.
+} nrf_libuarte_evt_type_t;
+
+typedef struct
+{
+ uint8_t * p_data; ///< Pointer to the data to be sent or received.
+ size_t length; ///< Length of the data.
+} nrf_libuarte_data_t;
+
+typedef struct
+{
+ nrf_libuarte_evt_type_t type; ///< Event type.
+ union {
+ nrf_libuarte_data_t rxtx; ///< Data provided for transfer completion events.
+ } data;
+} nrf_libuarte_evt_t;
+
+typedef struct {
+ uint32_t tx_pin; ///< TXD pin number.
+ uint32_t rx_pin; ///< RXD pin number.
+ uint32_t cts_pin; ///< CTS pin number.
+ uint32_t rts_pin; ///< RTS pin number.
+ uint32_t startrx_evt; ///< Event to trigger STARTRX task in UARTE.
+ uint32_t endrx_evt; ///< Event to trigger STOPRX task in UARTE.
+ uint32_t rxstarted_tsk; ///< Task to be triggered when RXSTARTED UARTE event occurs.
+ uint32_t rxdone_tsk; ///< Task to be triggered when ENDRX UARTE event occurs.
+ nrf_uarte_hwfc_t hwfc; ///< Flow control configuration.
+ nrf_uarte_parity_t parity; ///< Parity configuration.
+ nrf_uarte_baudrate_t baudrate; ///< Baud rate.
+ uint8_t irq_priority; ///< Interrupt priority.
+} nrf_libuarte_config_t;
+
+typedef void (*nrf_libuarte_evt_handler_t)(nrf_libuarte_evt_t * p_evt);
+
+/**
+ * @brief Function for initializing the libUARTE library.
+ *
+ * @param[in] p_config Pointer to the structure with initial configuration.
+ * @param[in] evt_handler Event handler provided by the user. Must not be NULL.
+ *
+ * @return NRF_SUCCESS when properly initialized. NRF_ERROR_INTERNAL otherwise.
+ */
+ret_code_t nrf_libuarte_init(nrf_libuarte_config_t * p_config, nrf_libuarte_evt_handler_t evt_handler);
+
+/** @brief Function for uninitializing the libUARTE library. */
+void nrf_libuarte_uninit(void);
+
+/**
+ * @brief Function for sending data over UARTE using EasyDMA.
+ *
+ * @param[in] p_data Pointer to data.
+ * @param[in] len Number of bytes to send.
+ *
+ * @retval NRF_ERROR_BUSY Data is transferring.
+ * @retval NRF_ERROR_INTERNAL Error during PPI channel configuration.
+ * @retval NRF_SUCCESS Buffer set for sending.
+ */
+ret_code_t nrf_libuarte_tx(uint8_t * p_data, size_t len);
+
+/**
+ * @brief Function for starting receiving data with additional configuration of external
+ * trigger to start receiving.
+ *
+ * @param p_data Pointer to data.
+ * @param len Number of bytes to receive. Maximum possible length is
+ * dependent on the used SoC (see the MAXCNT register
+ * description in the Product Specification). The library
+ * checks it with an assertion.
+ * @param ext_trigger_en True to disable immediate start.
+ *
+ * @retval NRF_ERROR_INTERNAL Error during PPI channel configuration.
+ * @retval NRF_SUCCESS Buffer set for receiving.
+ */
+ret_code_t nrf_libuarte_rx_start(uint8_t * p_data, size_t len, bool ext_trigger_en);
+
+/**
+ * @brief Function for setting a buffer for data that will be later received in UARTE.
+ *
+ * @param p_data Pointer to data.
+ * @param len Number of bytes to receive. Maximum possible length is
+ * dependent on the used SoC (see the MAXCNT register
+ * description in the Product Specification). The library
+ * checks it with an assertion.
+ */
+void nrf_libuarte_rx_buf_rsp(uint8_t * p_data, size_t len);
+
+/** @brief Function for stopping receiving data over UARTE. */
+void nrf_libuarte_rx_stop(void);
+
+/** @} */
+
+#endif //NRF_libuarte_H
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/experimental_libuarte/nrf_libuarte_async.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/experimental_libuarte/nrf_libuarte_async.c
new file mode 100644
index 0000000..5c5a639
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/experimental_libuarte/nrf_libuarte_async.c
@@ -0,0 +1,365 @@
+/**
+ * Copyright (c) 2018 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#include "sdk_config.h"
+#include "nrf_libuarte_async.h"
+#include "nrf_libuarte.h"
+#include "app_error.h"
+#include "nrf_balloc.h"
+#include "nrfx_timer.h"
+#include "nrfx_ppi.h"
+#include "nrf_uart.h"
+#include "nrf_queue.h"
+
+#define NRF_LOG_MODULE_NAME libUARTE_async
+#if NRF_LIBUARTE_CONFIG_LOG_ENABLED
+#define NRF_LOG_LEVEL NRF_LIBUARTE_CONFIG_LOG_LEVEL
+#define NRF_LOG_INFO_COLOR NRF_LIBUARTE_CONFIG_INFO_COLOR
+#define NRF_LOG_DEBUG_COLOR NRF_LIBUARTE_CONFIG_DEBUG_COLOR
+#else // NRF_LIBUARTE_CONFIG_LOG_ENABLED
+#define NRF_LOG_LEVEL 0
+#endif // NRF_LIBUARTE_CONFIG_LOG_ENABLED
+#include "nrf_log.h"
+NRF_LOG_MODULE_REGISTER();
+
+static nrf_libuarte_async_evt_handler m_evt_handler;
+#define POOL_SZ 3UL
+#define MAX_CHUNK_SZ 255UL
+
+NRF_BALLOC_DEF(m_rx_pool, MAX_CHUNK_SZ, POOL_SZ);
+
+NRF_QUEUE_DEF(uint8_t *, m_rxdata_queue, 3, NRF_QUEUE_MODE_NO_OVERFLOW);
+
+#define UART_DRV_TIMER CONCAT_2(NRF_TIMER, NRF_LIBUARTE_CONFIG_TIMER_USED)
+#define UART_DRV_UARTE CONCAT_2(NRF_UARTE, NRF_LIBUARTE_CONFIG_UARTE_USED)
+
+static nrfx_timer_t m_timer = NRFX_TIMER_INSTANCE(NRF_LIBUARTE_ASYNC_CONFIG_TIMER_USED);
+
+#if CONCAT_3(NRFX_TIMER, NRF_LIBUARTE_ASYNC_CONFIG_TIMER_USED,_ENABLED) == 0
+#error "Timer instance not enabled"
+#endif
+
+typedef enum
+{
+ PPI_CH_RXRDY_CLEAR,
+ PPI_CH_COMPARE_SHUTDOWN,
+ PPI_CH_MAX
+} nrf_libuarte_async_ppi_channel_t;
+
+static nrf_ppi_channel_t m_ppi_channels[PPI_CH_MAX];
+static int32_t m_alloc_cnt;
+static uint32_t m_rx_count;
+static uint32_t m_sub_rx_count;
+static uint8_t * mp_curr_rx_buf;
+static uint32_t m_rx_free_cnt;
+static size_t m_rx_chunk_size;
+
+#define PPI_CH_SETUP(_ch, _evt, _tsk, _fork) \
+ ret = nrfx_ppi_channel_assign(m_ppi_channels[_ch], _evt, _tsk); \
+ if (ret != NRF_SUCCESS) \
+ { \
+ return NRF_ERROR_INTERNAL; \
+ } \
+ if (_fork) \
+ { \
+ ret = nrfx_ppi_channel_fork_assign(m_ppi_channels[_ch], _fork); \
+ if (ret != NRF_SUCCESS) \
+ { \
+ return NRF_ERROR_INTERNAL; \
+ } \
+ }
+
+static void uart_evt_handler(nrf_libuarte_evt_t * p_evt)
+{
+ ret_code_t ret;
+ switch (p_evt->type)
+ {
+ case NRF_LIBUARTE_EVT_TX_DONE:
+ {
+ NRF_LOG_DEBUG("(evt) TX completed (%d)", p_evt->data.rxtx.length);
+ nrf_libuarte_async_evt_t evt = {
+ .type = NRF_LIBUARTE_ASYNC_EVT_TX_DONE,
+ .data.rxtx.p_data = p_evt->data.rxtx.p_data,
+ .data.rxtx.length = p_evt->data.rxtx.length,
+ };
+ m_evt_handler(&evt);
+ break;
+ }
+ case NRF_LIBUARTE_EVT_RX_BUF_REQ:
+ {
+ uint8_t * p_data = nrf_balloc_alloc(&m_rx_pool);
+ if (p_data)
+ {
+ ret = nrf_queue_push(&m_rxdata_queue, &p_data);
+ if (ret != NRF_SUCCESS)
+ {
+ NRF_LOG_ERROR("(evt) RX buffer queue full.");
+ APP_ERROR_CHECK_BOOL(false);
+ }
+
+ m_alloc_cnt++;
+ nrf_libuarte_rx_buf_rsp(p_data, m_rx_chunk_size);
+ }
+ else
+ {
+ NRF_LOG_ERROR("(evt) Failed to allocate buffer for RX.");
+ APP_ERROR_CHECK_BOOL(false);
+ }
+ break;
+ }
+ case NRF_LIBUARTE_EVT_RX_DATA:
+ {
+
+ uint32_t rx_amount = p_evt->data.rxtx.length - m_sub_rx_count;
+ if (rx_amount)
+ {
+ m_rx_count += rx_amount;
+ nrf_libuarte_async_evt_t evt = {
+ .type = NRF_LIBUARTE_ASYNC_EVT_RX_DATA,
+ .data.rxtx.p_data = &p_evt->data.rxtx.p_data[m_sub_rx_count],
+ .data.rxtx.length = rx_amount,
+ };
+ NRF_LOG_DEBUG("(evt) RX: %d (addr:0x%08X, internal index: %d)",
+ rx_amount,
+ p_evt->data.rxtx.p_data,
+ m_sub_rx_count);
+
+ m_sub_rx_count = 0;
+
+ if(p_evt->data.rxtx.p_data != mp_curr_rx_buf)
+ {
+ NRF_LOG_ERROR("(evt) RX buffer address mismatch");
+ }
+
+ ret = nrf_queue_pop(&m_rxdata_queue, &mp_curr_rx_buf);
+ if (ret != NRF_SUCCESS)
+ {
+ NRF_LOG_ERROR("RX buffer queue empty.");
+ APP_ERROR_CHECK_BOOL(false);
+ }
+
+ m_evt_handler(&evt);
+ }
+ else
+ {
+ NRF_LOG_ERROR("(evt) RX with 0 length: 0x%08X", p_evt->data.rxtx.p_data);
+ //zero length packet is freed immediately and not forwarded to the application.
+ APP_ERROR_CHECK_BOOL(false);
+ }
+ break;
+ }
+ default:
+ APP_ERROR_CHECK_BOOL(false);
+ break;
+ }
+}
+
+static void tmr_evt_handler(nrf_timer_event_t event_type, void * p_context)
+{
+ uint32_t capt_rx_count = UART_DRV_TIMER->CC[2];
+
+ if (capt_rx_count > m_rx_count)
+ {
+ uint32_t rx_amount = capt_rx_count - m_rx_count;
+ nrf_libuarte_async_evt_t evt = {
+ .type = NRF_LIBUARTE_ASYNC_EVT_RX_DATA,
+ .data.rxtx.p_data = &mp_curr_rx_buf[m_sub_rx_count],
+ .data.rxtx.length = rx_amount,
+ };
+ NRF_LOG_DEBUG("(tmr evt) RX: %d (addr:0x%08X, internal index: %d)",
+ rx_amount,
+ evt.data.rxtx.p_data,
+ m_sub_rx_count);
+
+ m_sub_rx_count += rx_amount;
+ m_rx_count = capt_rx_count;
+ m_evt_handler(&evt);
+ }
+}
+
+ret_code_t nrf_libuarte_async_init(nrf_libuarte_async_config_t const * p_config, nrf_libuarte_async_evt_handler evt_handler)
+{
+ ret_code_t ret;
+
+ m_evt_handler = evt_handler;
+ m_rx_count = 0;
+ mp_curr_rx_buf = NULL;
+ m_rx_free_cnt = 0;
+ m_sub_rx_count = 0;
+ m_alloc_cnt = 0;
+
+ nrfx_timer_config_t tmr_config = NRFX_TIMER_DEFAULT_CONFIG;
+ tmr_config.frequency = NRF_TIMER_FREQ_1MHz;
+ ret = nrfx_timer_init(&m_timer, &tmr_config, tmr_evt_handler);
+ if (ret != NRFX_SUCCESS)
+ {
+ return NRF_ERROR_INTERNAL;
+ }
+ nrfx_timer_compare(&m_timer, NRF_TIMER_CC_CHANNEL0, p_config->timeout_us, true);
+
+ uint32_t i;
+ for (i = 0; i < PPI_CH_MAX; i++)
+ {
+ ret = nrfx_ppi_channel_alloc(&m_ppi_channels[i]);
+ if (ret != NRFX_SUCCESS)
+ {
+ //we don't free already allocated channels, system is wrongly configured.
+ return NRF_ERROR_INTERNAL;
+ }
+ }
+
+/*lint -save -e666 */
+ PPI_CH_SETUP(m_ppi_channels[PPI_CH_RXRDY_CLEAR],
+ nrf_uarte_event_address_get(UART_DRV_UARTE, NRF_UARTE_EVENT_RXDRDY),
+ nrfx_timer_task_address_get(&m_timer, NRF_TIMER_TASK_START),
+ nrfx_timer_task_address_get(&m_timer, NRF_TIMER_TASK_CLEAR));
+
+ PPI_CH_SETUP(m_ppi_channels[PPI_CH_COMPARE_SHUTDOWN],
+ nrfx_timer_compare_event_address_get(&m_timer, 0),
+ nrfx_timer_task_address_get(&m_timer, NRF_TIMER_TASK_SHUTDOWN),
+ (uint32_t)&UART_DRV_TIMER->TASKS_CAPTURE[2]);
+
+/*lint -restore */
+
+ nrf_libuarte_config_t uart_config = {
+ .tx_pin = p_config->tx_pin,
+ .rx_pin = p_config->rx_pin,
+ .cts_pin = p_config->cts_pin,
+ .rts_pin = p_config->rts_pin,
+ .startrx_evt = nrf_uarte_event_address_get(UART_DRV_UARTE, NRF_UARTE_EVENT_ENDRX),
+ .endrx_evt = 0,
+ .rxstarted_tsk = 0,
+ .rxdone_tsk = 0,
+ .hwfc = p_config->hwfc,
+ .parity = p_config->parity,
+ .baudrate = p_config->baudrate,
+ .irq_priority = 7,
+ };
+
+ ret = nrf_libuarte_init(&uart_config, uart_evt_handler);
+ if (ret != NRF_SUCCESS)
+ {
+ return ret;
+ }
+
+ ret = nrf_balloc_init(&m_rx_pool);
+ if (ret != NRF_SUCCESS)
+ {
+ return ret;
+ }
+
+ nrf_queue_reset(&m_rxdata_queue);
+
+ return ret;
+}
+
+void nrf_libuarte_async_uninit(void)
+{
+ nrfx_err_t err = nrfx_ppi_channel_disable(m_ppi_channels[PPI_CH_RXRDY_CLEAR]);
+ APP_ERROR_CHECK_BOOL(err == NRFX_SUCCESS);
+ nrf_libuarte_uninit();
+ nrfx_timer_disable(&m_timer);
+ nrfx_timer_uninit(&m_timer);
+
+ uint32_t i;
+ ret_code_t ret;
+ for (i = 0; i < PPI_CH_MAX; i++)
+ {
+ ret = nrfx_ppi_channel_disable(m_ppi_channels[i]);
+ ASSERT(ret == NRF_SUCCESS)
+ ret = nrfx_ppi_channel_free(m_ppi_channels[i]);
+ ASSERT(ret == NRF_SUCCESS)
+ }
+}
+
+void nrf_libuarte_async_enable(size_t chunk_size)
+{
+ ASSERT(chunk_size <= MAX_CHUNK_SZ);
+ uint8_t * p_data;
+ p_data = nrf_balloc_alloc(&m_rx_pool);
+ m_alloc_cnt++;
+ if (p_data == NULL)
+ {
+ APP_ERROR_CHECK_BOOL(false);
+ }
+ nrfx_timer_clear(&m_timer);
+ nrfx_err_t err = nrfx_ppi_channel_enable(m_ppi_channels[PPI_CH_RXRDY_CLEAR]);
+ APP_ERROR_CHECK_BOOL(err == NRFX_SUCCESS);
+ err = nrfx_ppi_channel_enable(m_ppi_channels[PPI_CH_COMPARE_SHUTDOWN]);
+ APP_ERROR_CHECK_BOOL(err == NRFX_SUCCESS);
+
+ mp_curr_rx_buf = p_data;
+ m_rx_chunk_size = chunk_size;
+ ret_code_t ret = nrf_libuarte_rx_start(p_data, chunk_size, false);
+ APP_ERROR_CHECK_BOOL(ret == NRF_SUCCESS);
+}
+
+ret_code_t nrf_libuarte_async_tx(uint8_t * p_data, size_t length)
+{
+ return nrf_libuarte_tx(p_data, length);
+}
+
+void nrf_libuarte_async_rx_free(uint8_t * p_data, size_t length)
+{
+ m_rx_free_cnt += length;
+ if (m_rx_free_cnt == m_rx_chunk_size)
+ {
+ p_data -= (m_rx_free_cnt - length);
+ m_rx_free_cnt = 0;
+ nrf_balloc_free(&m_rx_pool, p_data);
+
+ m_alloc_cnt--;
+ if (m_alloc_cnt<0)
+ {
+ NRF_LOG_ERROR("Freeing more RX buffers than allocated.");
+ APP_ERROR_CHECK_BOOL(false);
+ }
+ NRF_LOG_INFO("Freeing full buffer 0x%08X, %d, (currently allocated:%d).",p_data, length, m_alloc_cnt);
+ }
+ else if (m_rx_free_cnt > m_rx_chunk_size)
+ {
+ NRF_LOG_ERROR("Unexpected RX free input parameter.")
+ APP_ERROR_CHECK_BOOL(false);
+ }
+ else
+ {
+ NRF_LOG_INFO("Freeing partial buffer: 0x%08X, length:%d", p_data, length)
+ }
+
+}
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/experimental_libuarte/nrf_libuarte_async.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/experimental_libuarte/nrf_libuarte_async.h
new file mode 100644
index 0000000..9930a81
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/experimental_libuarte/nrf_libuarte_async.h
@@ -0,0 +1,135 @@
+/**
+ * Copyright (c) 2018 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#ifndef UART_ASYNC_H
+#define UART_ASYNC_H
+#include <stdint.h>
+#include "sdk_errors.h"
+#include <hal/nrf_uarte.h>
+
+/** @brief Types of libuarte driver events. */
+typedef enum
+{
+ NRF_LIBUARTE_ASYNC_EVT_RX_DATA, ///< Requested TX transfer completed.
+ NRF_LIBUARTE_ASYNC_EVT_TX_DONE, ///< Requested RX transfer completed.
+ NRF_LIBUARTE_ASYNC_EVT_ERROR ///< Error reported by UARTE peripheral.
+} nrf_libuarte_async_evt_type_t;
+
+/** @brief Structure for libuarte async transfer completion event. */
+typedef struct
+{
+ uint8_t * p_data; ///< Pointer to memory used for transfer.
+ size_t length; ///< Number of bytes transfered.
+} nrf_libuarte_async_data_t;
+
+/** @brief Structure for libuarte async configuration. */
+typedef struct
+{
+ uint32_t rx_pin; ///< RXD pin number.
+ uint32_t tx_pin; ///< TXD pin number.
+ uint32_t cts_pin; ///< CTS pin number.
+ uint32_t rts_pin; ///< RTS pin number.
+ uint32_t timeout_us; ///< Receiver timeout in us unit.
+ nrf_uarte_hwfc_t hwfc; ///< Flow control configuration.
+ nrf_uarte_parity_t parity; ///< Parity configuration.
+ nrf_uarte_baudrate_t baudrate; ///< Baudrate.
+} nrf_libuarte_async_config_t;
+
+/** @brief Structure for libuarte error event. */
+typedef struct
+{
+ nrf_libuarte_async_evt_type_t type; ///< Event type.
+ union {
+ nrf_libuarte_async_data_t rxtx; ///< RXD/TXD data.
+ } data; ///< Union with data.
+} nrf_libuarte_async_evt_t;
+
+/**
+ * @brief Interrupt event handler.
+ *
+ * @param[in] p_evt Pointer to event structure. Event is allocated on the stack so it is available
+ * only within the context of the event handler.
+ */
+typedef void (*nrf_libuarte_async_evt_handler)(nrf_libuarte_async_evt_t * p_evt);
+
+/**
+ * @brief Function for initializing the libuarte async library.
+ *
+ * @param[in] p_config Pointer to the structure with initial configuration.
+ * @param[in] evt_handler Event handler provided by the user. Must not be NULL.
+ *
+ * @return NRF_SUCCESS when properly initialized. NRF_ERROR_INTERNAL otherwise.
+ */
+ret_code_t nrf_libuarte_async_init(nrf_libuarte_async_config_t const * p_config,
+ nrf_libuarte_async_evt_handler evt_handler);
+
+/** @brief Function for uninitializing the libuarte async library */
+void nrf_libuarte_async_uninit(void);
+
+/**
+ * @brief Funtrion for setting buffer and its size for received data.
+ *
+ * @param chunk_size Number of bytes in chunk of data
+ */
+void nrf_libuarte_async_enable(size_t chunk_size);
+
+/**
+ * @brief Function for sending data asynchronously over UARTE.
+ *
+ * @param[in] p_data Pointer to data.
+ * @param[in] length Number of bytes to send. Maximum possible length is
+ * dependent on the used SoC (see the MAXCNT register
+ * description in the Product Specification). The library
+ * checks it with assertion.
+ *
+ * @retval NRF_ERROR_BUSY Data is transferring.
+ * @retval NRF_ERROR_INTERNAL Error during configuration.
+ * @retval NRF_SUCCESS Buffer set for sending.
+ */
+ret_code_t nrf_libuarte_async_tx(uint8_t * p_data, size_t length);
+
+/**
+ * @brief Function for deallocating received buffer data.
+ *
+ * @param[in] p_data Pointer to data.
+ * @param[in] length Number of bytes to free.
+ */
+void nrf_libuarte_async_rx_free(uint8_t * p_data, size_t length);
+
+#endif //UART_ASYNC_H
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/experimental_log/nrf_log.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/experimental_log/nrf_log.h
new file mode 100644
index 0000000..d709d23
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/experimental_log/nrf_log.h
@@ -0,0 +1,291 @@
+/**
+ * Copyright (c) 2016 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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
+ *
+ * @defgroup nrf_log Logger module
+ * @{
+ * @ingroup app_common
+ *
+ * @brief The nrf_log module interface.
+ */
+
+#ifndef NRF_LOG_H_
+#define NRF_LOG_H_
+
+#include "sdk_common.h"
+#include "nrf_section.h"
+#if NRF_MODULE_ENABLED(NRF_LOG)
+#include "nrf_strerror.h"
+#define NRF_LOG_ERROR_STRING_GET(code) nrf_strerror_get(code)
+#else
+#define NRF_LOG_ERROR_STRING_GET(code) ""
+#endif
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** @brief Severity level for the module.
+ *
+ * The severity level can be defined in a module to override the default.
+ */
+#ifndef NRF_LOG_LEVEL
+ #define NRF_LOG_LEVEL NRF_LOG_DEFAULT_LEVEL
+#endif
+
+/** @brief Initial severity if filtering is enabled.
+ */
+#ifndef NRF_LOG_INITIAL_LEVEL
+ #define NRF_LOG_INITIAL_LEVEL NRF_LOG_LEVEL
+#endif
+
+
+#include "nrf_log_internal.h"
+
+/** @def NRF_LOG_ERROR
+ * @brief Macro for logging error messages. It takes a printf-like, formatted
+ * string with up to seven arguments.
+ *
+ * @details This macro is compiled only if @ref NRF_LOG_LEVEL includes error logs.
+ */
+
+/** @def NRF_LOG_WARNING
+ * @brief Macro for logging error messages. It takes a printf-like, formatted
+ * string with up to seven arguments.
+ *
+ * @details This macro is compiled only if @ref NRF_LOG_LEVEL includes warning logs.
+ */
+
+/** @def NRF_LOG_INFO
+ * @brief Macro for logging error messages. It takes a printf-like, formatted
+ * string with up to seven arguments.
+ *
+ * @details This macro is compiled only if @ref NRF_LOG_LEVEL includes info logs.
+ */
+
+/** @def NRF_LOG_DEBUG
+ * @brief Macro for logging error messages. It takes a printf-like, formatted
+ * string with up to seven arguments.
+ *
+ * @details This macro is compiled only if @ref NRF_LOG_LEVEL includes debug logs.
+ */
+
+#define NRF_LOG_ERROR(...) NRF_LOG_INTERNAL_ERROR(__VA_ARGS__)
+#define NRF_LOG_WARNING(...) NRF_LOG_INTERNAL_WARNING( __VA_ARGS__)
+#define NRF_LOG_INFO(...) NRF_LOG_INTERNAL_INFO( __VA_ARGS__)
+#define NRF_LOG_DEBUG(...) NRF_LOG_INTERNAL_DEBUG( __VA_ARGS__)
+
+/** @def NRF_LOG_INST_ERROR
+ * @brief Macro for logging error messages for a given module instance. It takes a printf-like, formatted
+ * string with up to seven arguments.
+ *
+ * @param p_inst Pointer to the instance with logging support.
+ *
+ * @details This macro is compiled only if @ref NRF_LOG_LEVEL includes error logs.
+ */
+
+/** @def NRF_LOG_INST_WARNING
+ * @brief Macro for logging error messages for a given module instance. It takes a printf-like, formatted
+ * string with up to seven arguments.
+ *
+ * @param p_inst Pointer to the instance with logging support.
+ *
+ * @details This macro is compiled only if @ref NRF_LOG_LEVEL includes error logs.
+ */
+
+/** @def NRF_LOG_INST_INFO
+ * @brief Macro for logging error messages for a given module instance. It takes a printf-like, formatted
+ * string with up to seven arguments.
+ *
+ * @param p_inst Pointer to the instance with logging support.
+ *
+ * @details This macro is compiled only if @ref NRF_LOG_LEVEL includes error logs.
+ */
+
+/** @def NRF_LOG_INST_DEBUG
+ * @brief Macro for logging error messages for given module instance. It takes a printf-like, formatted
+ * string with up to seven arguments.
+ *
+ * @param p_inst Pointer to the instance with logging support.
+ *
+ * @details This macro is compiled only if @ref NRF_LOG_LEVEL includes error logs.
+ */
+#define NRF_LOG_INST_ERROR(p_inst,...) NRF_LOG_INTERNAL_INST_ERROR(p_inst,__VA_ARGS__)
+#define NRF_LOG_INST_WARNING(p_inst,...) NRF_LOG_INTERNAL_INST_WARNING(p_inst,__VA_ARGS__)
+#define NRF_LOG_INST_INFO(p_inst,...) NRF_LOG_INTERNAL_INST_INFO(p_inst, __VA_ARGS__)
+#define NRF_LOG_INST_DEBUG(p_inst,...) NRF_LOG_INTERNAL_INST_DEBUG(p_inst, __VA_ARGS__)
+
+/**
+ * @brief Macro for logging a formatted string without any prefix or timestamp.
+ */
+#define NRF_LOG_RAW_INFO(...) NRF_LOG_INTERNAL_RAW_INFO( __VA_ARGS__)
+
+/** @def NRF_LOG_HEXDUMP_ERROR
+ * @brief Macro for logging raw bytes.
+ * @details This macro is compiled only if @ref NRF_LOG_LEVEL includes error logs.
+ *
+ * @param p_data Pointer to data.
+ * @param len Data length in bytes.
+ */
+/** @def NRF_LOG_HEXDUMP_WARNING
+ * @brief Macro for logging raw bytes.
+ * @details This macro is compiled only if @ref NRF_LOG_LEVEL includes warning logs.
+ *
+ * @param p_data Pointer to data.
+ * @param len Data length in bytes.
+ */
+/** @def NRF_LOG_HEXDUMP_INFO
+ * @brief Macro for logging raw bytes.
+ * @details This macro is compiled only if @ref NRF_LOG_LEVEL includes info logs.
+ *
+ * @param p_data Pointer to data.
+ * @param len Data length in bytes.
+ */
+/** @def NRF_LOG_HEXDUMP_DEBUG
+ * @brief Macro for logging raw bytes.
+ * @details This macro is compiled only if @ref NRF_LOG_LEVEL includes debug logs.
+ *
+ * @param p_data Pointer to data.
+ * @param len Data length in bytes.
+ */
+#define NRF_LOG_HEXDUMP_ERROR(p_data, len) NRF_LOG_INTERNAL_HEXDUMP_ERROR(p_data, len)
+#define NRF_LOG_HEXDUMP_WARNING(p_data, len) NRF_LOG_INTERNAL_HEXDUMP_WARNING(p_data, len)
+#define NRF_LOG_HEXDUMP_INFO(p_data, len) NRF_LOG_INTERNAL_HEXDUMP_INFO(p_data, len)
+#define NRF_LOG_HEXDUMP_DEBUG(p_data, len) NRF_LOG_INTERNAL_HEXDUMP_DEBUG(p_data, len)
+
+/** @def NRF_LOG_HEXDUMP_INST_ERROR
+ * @brief Macro for logging raw bytes for a specific module instance.
+ * @details This macro is compiled only if @ref NRF_LOG_LEVEL includes error logs.
+ *
+ * @param p_inst Pointer to the instance with logging support.
+ * @param p_data Pointer to data.
+ * @param len Data length in bytes.
+ */
+/** @def NRF_LOG_HEXDUMP_INST_WARNING
+ * @brief Macro for logging raw bytes for a specific module instance.
+ * @details This macro is compiled only if @ref NRF_LOG_LEVEL includes error logs.
+ *
+ * @param p_inst Pointer to the instance with logging support.
+ * @param p_data Pointer to data.
+ * @param len Data length in bytes.
+ */
+/** @def NRF_LOG_HEXDUMP_INST_INFO
+ * @brief Macro for logging raw bytes for a specific module instance.
+ * @details This macro is compiled only if @ref NRF_LOG_LEVEL includes error logs.
+ *
+ * @param p_inst Pointer to the instance with logging support.
+ * @param p_data Pointer to data.
+ * @param len Data length in bytes.
+ */
+/** @def NRF_LOG_HEXDUMP_INST_DEBUG
+ * @brief Macro for logging raw bytes for a specific module instance.
+ * @details This macro is compiled only if @ref NRF_LOG_LEVEL includes error logs.
+ *
+ * @param p_inst Pointer to the instance with logging support.
+ * @param p_data Pointer to data.
+ * @param len Data length in bytes.
+ */
+#define NRF_LOG_HEXDUMP_INST_ERROR(p_inst, p_data, len) NRF_LOG_INTERNAL_HEXDUMP_INST_ERROR(p_inst, p_data, len)
+#define NRF_LOG_HEXDUMP_INST_WARNING(p_inst, p_data, len) NRF_LOG_INTERNAL_HEXDUMP_INST_WARNING(p_inst, p_data, len)
+#define NRF_LOG_HEXDUMP_INST_INFO(p_inst, p_data, len) NRF_LOG_INTERNAL_HEXDUMP_INST_INFO(p_inst, p_data, len)
+#define NRF_LOG_HEXDUMP_INST_DEBUG(p_inst, p_data, len) NRF_LOG_INTERNAL_HEXDUMP_INST_DEBUG(p_inst, p_data, len)
+
+/**
+ * @brief Macro for logging hexdump without any prefix or timestamp.
+ */
+#define NRF_LOG_RAW_HEXDUMP_INFO(p_data, len) NRF_LOG_INTERNAL_RAW_HEXDUMP_INFO(p_data, len)
+
+
+/**
+ * @brief Macro for copying a string to internal logger buffer if logs are deferred.
+ *
+ * @param _str String.
+ */
+#define NRF_LOG_PUSH(_str) NRF_LOG_INTERNAL_LOG_PUSH(_str)
+
+/**
+ * @brief Function for copying a string to the internal logger buffer if logs are deferred.
+ *
+ * Use this function to store a string that is volatile (for example allocated
+ * on stack) or that may change before the deferred logs are processed. Such string is copied
+ * into the internal logger buffer and is persistent until the log is processed.
+ *
+ * @note If the logs are not deferred, then this function returns the input parameter.
+ *
+ * @param p_str Pointer to the user string.
+ *
+ * @return Address to the location where the string is stored in the internal logger buffer.
+ */
+uint32_t nrf_log_push(char * const p_str);
+
+/**
+ * @brief Macro to be used in a formatted string to a pass float number to the log.
+ *
+ * Use this macro in a formatted string instead of the %f specifier together with
+ * @ref NRF_LOG_FLOAT macro.
+ * Example: NRF_LOG_INFO("My float number" NRF_LOG_FLOAT_MARKER "\r\n", NRF_LOG_FLOAT(f)))
+ */
+#define NRF_LOG_FLOAT_MARKER "%s%d.%02d"
+
+/**
+ * @brief Macro for dissecting a float number into two numbers (integer and residuum).
+ */
+#define NRF_LOG_FLOAT(val) (uint32_t)(((val) < 0 && (val) > -1.0) ? "-" : ""), \
+ (int32_t)(val), \
+ (int32_t)((((val) > 0) ? (val) - (int32_t)(val) \
+ : (int32_t)(val) - (val))*100)
+
+
+/**
+ * @brief Macro for registering an independent module.
+ *
+ * Registration creates set of dynamic (RAM) and constant variables associated with the module.
+ */
+#define NRF_LOG_MODULE_REGISTER() NRF_LOG_INTERNAL_MODULE_REGISTER()
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // NRF_LOG_H_
+
+/** @} */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/experimental_log/nrf_log_backend_flash.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/experimental_log/nrf_log_backend_flash.h
new file mode 100644
index 0000000..c93ae35
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/experimental_log/nrf_log_backend_flash.h
@@ -0,0 +1,129 @@
+/**
+ * Copyright (c) 2018 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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
+ *
+ * @defgroup nrf_log_backend_flash Flash logger backend
+ * @{
+ * @ingroup nrf_log
+ * @brief Flash logger backend.
+ */
+
+#ifndef NRF_LOG_BACKEND_FLASH_H
+#define NRF_LOG_BACKEND_FLASH_H
+
+#include "nrf_log_backend_interface.h"
+#include "nrf_fstorage.h"
+#include "nrf_log_internal.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** @brief Flashlog logger backend API. */
+extern const nrf_log_backend_api_t nrf_log_backend_flashlog_api;
+
+/** @brief Crashlog logger backend API. */
+extern const nrf_log_backend_api_t nrf_log_backend_crashlog_api;
+
+/** @brief Flashlog logger backend structure. */
+typedef struct {
+ nrf_log_backend_t backend;
+} nrf_log_backend_flashlog_t;
+
+/** @brief Crashlog logger backend structure. */
+typedef struct {
+ nrf_log_backend_t backend;
+} nrf_log_backend_crashlog_t;
+
+/** @brief Macro for creating an instance of the flashlog logger backend. */
+#define NRF_LOG_BACKEND_FLASHLOG_DEF(name) \
+ static nrf_log_backend_flashlog_t name = { \
+ .backend = {.p_api = &nrf_log_backend_flashlog_api}, \
+ }
+
+/** @brief Macro for creating an instance of the crashlog logger backend. */
+#define NRF_LOG_BACKEND_CRASHLOG_DEF(name) \
+ static nrf_log_backend_crashlog_t name = { \
+ .backend = {.p_api = &nrf_log_backend_crashlog_api}, \
+ }
+
+/**
+ * @brief Function for initializing the flash logger backend.
+ *
+ * Flash logger backend consists of two logical backends: flashlog and crashlog. Since both
+ * backends write to the same flash area, the initialization is common.
+ *
+ * @param p_fs_api fstorage API to be used.
+ *
+ * @return NRF_SUCCESS or error code returned by @ref nrf_fstorage_init.
+ */
+ret_code_t nrf_log_backend_flash_init(nrf_fstorage_api_t const * p_fs_api);
+
+/**
+ * @brief Function for getting a log entry stored in flash.
+ *
+ * Log messages stored in flash can be read one by one starting from the oldest one.
+ *
+ * @param[in, out] p_token Token reused between consecutive readings of log entries.
+ * Token must be set to 0 to read the first entry.
+ * @param[out] pp_header Pointer to the entry header.
+ * @param[out] pp_data Pointer to the data part of the entry (arguments or data in case of hexdump).
+ *
+ * @retval NRF_SUCCESS Entry was successfully read.
+ * @retval NRF_ERROR_NOT_SUPPORTED fstorage API does not support direct reading.
+ * @retval NRF_ERROR_NOT_FOUND Entry not found. Last entry was already reached or area is empty.
+ */
+ret_code_t nrf_log_backend_flash_next_entry_get(uint32_t * p_token,
+ nrf_log_header_t * * pp_header,
+ uint8_t * * pp_data);
+
+/**
+ * @brief Function for erasing flash area dedicated for the flash logger backend.
+ */
+ret_code_t nrf_log_backend_flash_erase(void);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif //NRF_LOG_BACKEND_UART_H
+
+/** @} */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/experimental_log/nrf_log_backend_interface.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/experimental_log/nrf_log_backend_interface.h
new file mode 100644
index 0000000..9d1af51
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/experimental_log/nrf_log_backend_interface.h
@@ -0,0 +1,220 @@
+/**
+ * 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#ifndef NRF_LOG_BACKEND_INTERFACE_H
+#define NRF_LOG_BACKEND_INTERFACE_H
+
+/**@file
+ * @addtogroup nrf_log Logger module
+ * @ingroup app_common
+ *
+ * @defgroup nrf_log_backend_interface Logger backend interface
+ * @{
+ * @ingroup nrf_log
+ * @brief The nrf_log backend interface.
+ */
+
+#include "nrf_memobj.h"
+#include <stdint.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+/**
+ * @brief nrf_log entry.
+ */
+typedef nrf_memobj_t nrf_log_entry_t;
+
+/* Forward declaration of the nrf_log_backend_t type. */
+typedef struct nrf_log_backend_s nrf_log_backend_t;
+
+/**
+ * @brief Logger backend API.
+ */
+typedef struct
+{
+ /**
+ * @brief @ref nrf_log_backend_put
+ */
+ void (*put)(nrf_log_backend_t const * p_backend, nrf_log_entry_t * p_entry);
+
+ /**
+ * @brief @ref nrf_log_backend_panic_set
+ */
+ void (*panic_set)(nrf_log_backend_t const * p_backend);
+
+ /**
+ * @brief @ref nrf_log_backend_flush
+ */
+ void (*flush)(nrf_log_backend_t const * p_backend);
+} nrf_log_backend_api_t;
+
+/**
+ * @brief Logger backend structure.
+ */
+struct nrf_log_backend_s
+{
+ nrf_log_backend_api_t const * p_api; //!< Pointer to interface.
+ nrf_log_backend_t * p_next; //!< Pointer to next backend added to the logger.
+ uint8_t id; //!< Backend id.
+ bool enabled;//!< Flag indicating backend status.
+};
+
+/**
+ * @brief Function for putting message with log entry to the backend.
+ *
+ * @param[in] p_backend Pointer to the backend instance.
+ * @param[in] p_msg Pointer to message with log entry.
+ */
+__STATIC_INLINE void nrf_log_backend_put(nrf_log_backend_t const * p_backend,
+ nrf_log_entry_t * p_msg);
+
+/**
+ * @brief Function for reconfiguring backend to panic mode.
+ *
+ * @param[in] p_backend Pointer to the backend instance.
+ */
+__STATIC_INLINE void nrf_log_backend_panic_set(nrf_log_backend_t const * p_backend);
+
+/**
+ * @brief Function for flushing backend.
+ *
+ * On flushing request backend should release log message(s).
+ *
+ * @param[in] p_backend Pointer to the backend instance.
+ */
+__STATIC_INLINE void nrf_log_backend_flush(nrf_log_backend_t const * p_backend);
+
+
+/**
+ * @brief Function for setting backend id.
+ *
+ * @note It is used internally by the logger.
+ *
+ * @param[in] p_backend Pointer to the backend instance.
+ * @param[in] id Id.
+ */
+__STATIC_INLINE void nrf_log_backend_id_set(nrf_log_backend_t * p_backend, uint8_t id);
+
+/**
+ * @brief Function for getting backend id.
+ *
+ * @note It is used internally by the logger.
+ *
+ * @param[in] p_backend Pointer to the backend instance.
+ * @return Id.
+ */
+__STATIC_INLINE uint8_t nrf_log_backend_id_get(nrf_log_backend_t const * p_backend);
+
+/**
+ * @brief Function for enabling backend.
+ *
+ * @param[in] p_backend Pointer to the backend instance.
+ */
+__STATIC_INLINE void nrf_log_backend_enable(nrf_log_backend_t * p_backend);
+
+/**
+ * @brief Function for disabling backend.
+ *
+ * @param[in] p_backend Pointer to the backend instance.
+ */
+__STATIC_INLINE void nrf_log_backend_disable(nrf_log_backend_t * p_backend);
+
+/**
+ * @brief Function for checking state of the backend.
+ *
+ * @param[in] p_backend Pointer to the backend instance.
+ *
+ * @return True if backend is enabled, false otherwise.
+ */
+__STATIC_INLINE bool nrf_log_backend_is_enabled(nrf_log_backend_t const * p_backend);
+
+#ifndef SUPPRESS_INLINE_IMPLEMENTATION
+__STATIC_INLINE void nrf_log_backend_put(nrf_log_backend_t const * p_backend,
+ nrf_log_entry_t * p_msg)
+{
+ p_backend->p_api->put(p_backend, p_msg);
+}
+
+__STATIC_INLINE void nrf_log_backend_panic_set(nrf_log_backend_t const * p_backend)
+{
+ p_backend->p_api->panic_set(p_backend);
+}
+
+__STATIC_INLINE void nrf_log_backend_flush(nrf_log_backend_t const * p_backend)
+{
+ p_backend->p_api->flush(p_backend);
+}
+
+__STATIC_INLINE void nrf_log_backend_id_set(nrf_log_backend_t * p_backend, uint8_t id)
+{
+ p_backend->id = id;
+}
+
+__STATIC_INLINE uint8_t nrf_log_backend_id_get(nrf_log_backend_t const * p_backend)
+{
+ return p_backend->id;
+}
+
+__STATIC_INLINE void nrf_log_backend_enable(nrf_log_backend_t * p_backend)
+{
+ p_backend->enabled = true;
+}
+
+__STATIC_INLINE void nrf_log_backend_disable(nrf_log_backend_t * p_backend)
+{
+ p_backend->enabled = false;
+}
+
+__STATIC_INLINE bool nrf_log_backend_is_enabled(nrf_log_backend_t const * p_backend)
+{
+ return p_backend->enabled;
+}
+
+#endif // SUPPRESS_INLINE_IMPLEMENTATION
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif //NRF_LOG_BACKEND_INTERFACE_H
+
+/** @} */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/experimental_log/nrf_log_backend_rtt.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/experimental_log/nrf_log_backend_rtt.h
new file mode 100644
index 0000000..efa1032
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/experimental_log/nrf_log_backend_rtt.h
@@ -0,0 +1,82 @@
+/**
+ * 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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
+ *
+ * @defgroup nrf_log_backend_rtt Log RTT backend
+ * @{
+ * @ingroup nrf_log
+ * @brief Log RTT backend.
+ */
+
+#ifndef NRF_LOG_BACKEND_RTT_H
+#define NRF_LOG_BACKEND_RTT_H
+
+#include "nrf_log_backend_interface.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+extern const nrf_log_backend_api_t nrf_log_backend_rtt_api;
+
+typedef struct {
+ nrf_log_backend_t backend;
+} nrf_log_backend_rtt_t;
+
+/**
+ * @brief RTT backend definition
+ *
+ * @param _name Name of the instance.
+ */
+#define NRF_LOG_BACKEND_RTT_DEF(_name) \
+ static nrf_log_backend_rtt_t _name = { \
+ .backend = {.p_api = &nrf_log_backend_rtt_api}, \
+ }
+
+void nrf_log_backend_rtt_init(void);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif //NRF_LOG_BACKEND_RTT_H
+
+/** @} */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/experimental_log/nrf_log_backend_uart.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/experimental_log/nrf_log_backend_uart.h
new file mode 100644
index 0000000..2743e29
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/experimental_log/nrf_log_backend_uart.h
@@ -0,0 +1,77 @@
+/**
+ * Copyright (c) 2016 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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
+ *
+ * @defgroup nrf_log_backend_uart Log UART backend
+ * @{
+ * @ingroup nrf_log
+ * @brief Log UART backend.
+ */
+
+#ifndef NRF_LOG_BACKEND_UART_H
+#define NRF_LOG_BACKEND_UART_H
+
+#include "nrf_log_backend_interface.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+extern const nrf_log_backend_api_t nrf_log_backend_uart_api;
+
+typedef struct {
+ nrf_log_backend_t backend;
+} nrf_log_backend_uart_t;
+
+#define NRF_LOG_BACKEND_UART_DEF(name) \
+ static nrf_log_backend_uart_t name = { \
+ .backend = {.p_api = &nrf_log_backend_uart_api}, \
+ }
+
+void nrf_log_backend_uart_init(void);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif //NRF_LOG_BACKEND_UART_H
+
+/** @} */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/experimental_log/nrf_log_ctrl.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/experimental_log/nrf_log_ctrl.h
new file mode 100644
index 0000000..828f1f7
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/experimental_log/nrf_log_ctrl.h
@@ -0,0 +1,226 @@
+/**
+ * Copyright (c) 2016 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#ifndef NRF_LOG_CTRL_H
+#define NRF_LOG_CTRL_H
+
+/**@file
+ * @addtogroup nrf_log Logger module
+ * @ingroup app_common
+ *
+ * @defgroup nrf_log_ctrl Functions for controlling nrf_log
+ * @{
+ * @ingroup nrf_log
+ * @brief The nrf_log control interface.
+ */
+
+#include "sdk_config.h"
+#include "sdk_errors.h"
+#include <stdint.h>
+#include <stdbool.h>
+#include "nrf_log_types.h"
+#include "nrf_log_ctrl_internal.h"
+#include "nrf_log_backend_interface.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @brief Timestamp function prototype.
+ *
+ * @return Timestamp value.
+ */
+typedef uint32_t (*nrf_log_timestamp_func_t)(void);
+
+/**@brief Macro for initializing the logs.
+ *
+ * Macro has one or two parameters. First parameter (obligatory) is the timestamp function (@ref nrf_log_timestamp_func_t).
+ * Additionally, as the second parameter timestamp frequency in Hz can be provided. If not provided then default
+ * frequency is used (@ref NRF_LOG_TIMESTAMP_DEFAULT_FREQUENCY). Frequency is used to format timestamp prefix if
+ * @ref NRF_LOG_STR_FORMATTER_TIMESTAMP_FORMAT_ENABLED is set.
+ *
+ * @return NRF_SUCCESS after successful initialization, otherwise an error code.
+ */
+#define NRF_LOG_INIT(...) NRF_LOG_INTERNAL_INIT(__VA_ARGS__)
+
+
+/**@brief Macro for processing a single log entry from a queue of deferred logs.
+ *
+ * You can call this macro from the main context or from the error handler to process
+ * log entries one by one.
+ *
+ * @note If logs are not deferred, this call has no use and is defined as 'false'.
+ *
+ * @retval true There are more logs to process in the buffer.
+ * @retval false No more logs in the buffer.
+ */
+#define NRF_LOG_PROCESS() NRF_LOG_INTERNAL_PROCESS()
+
+/** @brief Macro for processing all log entries from the buffer.
+ * It blocks until all buffered entries are processed by the backend.
+ *
+ * @note If logs are not deferred, this call has no use and is empty.
+ */
+#define NRF_LOG_FLUSH() NRF_LOG_INTERNAL_FLUSH()
+
+/** @brief Macro for flushing log data before reset.
+ *
+ * @note If logs are not deferred, this call has no use and is empty.
+ *
+ * @note If RTT is used, then a breakpoint is hit once flushed.
+ */
+#define NRF_LOG_FINAL_FLUSH() NRF_LOG_INTERNAL_FINAL_FLUSH()
+
+/**
+ * @brief Function for initializing the frontend and the default backend.
+ *
+ * @ref NRF_LOG_INIT calls this function to initialize the frontend and the backend.
+ * If custom backend is used, then @ref NRF_LOG_INIT should not be called.
+ * Instead, frontend and user backend should be verbosely initialized.
+ *
+ * @param timestamp_func Function for getting a 32-bit timestamp.
+ * @param timestamp_freq Frequency of the timestamp.
+ *
+ * @return Error status.
+ *
+ */
+ret_code_t nrf_log_init(nrf_log_timestamp_func_t timestamp_func, uint32_t timestamp_freq);
+
+/**
+ * @brief Function for adding new backend interface to the logger.
+ *
+ * @param p_backend Pointer to the backend interface.
+ * @param severity Initial value of severity level for each module forwarded to the backend. This
+ * option is only applicable if @ref NRF_LOG_FILTERS_ENABLED is set.
+ * @return -1 if backend cannot be added or positive number (backend ID).
+ */
+int32_t nrf_log_backend_add(nrf_log_backend_t * p_backend, nrf_log_severity_t severity);
+
+/**
+ * @brief Function for removing backend from the logger.
+ *
+ * @param p_backend Pointer to the backend interface.
+ *
+ */
+void nrf_log_backend_remove(nrf_log_backend_t * p_backend);
+
+/**
+ * @brief Function for setting logger backends into panic mode.
+ *
+ * When this function is called all attached backends are informed about panic state of the system.
+ * It is up to the backend to react properly (hold or process logs in blocking mode, etc.)
+ */
+void nrf_log_panic(void);
+
+/**
+ * @brief Function for handling a single log entry.
+ *
+ * Use this function only if the logs are buffered. It takes a single entry from the
+ * buffer and attempts to process it.
+ *
+ * @retval true If there are more entries to process.
+ * @retval false If there are no more entries to process.
+ */
+bool nrf_log_frontend_dequeue(void);
+
+/**
+ * @brief Function for getting number of independent log modules registered into the logger.
+ *
+ * @return Number of registered modules.
+ */
+uint32_t nrf_log_module_cnt_get(void);
+
+/**
+ * @brief Function for getting module name.
+ *
+ * @param module_id Module ID.
+ * @param is_ordered_idx Module ID is given is index in alphabetically sorted list of modules.
+ * @return Pointer to string with module name.
+ */
+const char * nrf_log_module_name_get(uint32_t module_id, bool is_ordered_idx);
+
+/**
+ * @brief Function for getting coloring of specific logs.
+ *
+ * @param module_id Module ID.
+ * @param severity Log severity.
+ *
+ * @return ID of the color.
+ */
+uint8_t nrf_log_color_id_get(uint32_t module_id, nrf_log_severity_t severity);
+
+/**
+ * @brief Function for configuring filtering ofs logs in the module.
+ *
+ * Filtering of logs in modules is independent for each backend.
+ *
+ * @param backend_id Backend ID which want to chenge its configuration.
+ * @param module_id Module ID which logs will be reconfigured.
+ * @param severity New severity filter.
+ */
+void nrf_log_module_filter_set(uint32_t backend_id,
+ uint32_t module_id,
+ nrf_log_severity_t severity);
+
+/**
+ * @brief Function for getting module severity level.
+ *
+ * @param backend_id Backend ID.
+ * @param module_id Module ID.
+ * @param is_ordered_idx Module ID is given is index in alphabetically sorted list of modules.
+ * @param dynamic It true current filter for given backend is returned. If false then
+ * compiled-in level is returned (maximum available). If this parameter is
+ * false then backend_id parameter is not used.
+ *
+ * @return Severity.
+ */
+nrf_log_severity_t nrf_log_module_filter_get(uint32_t backend_id,
+ uint32_t module_id,
+ bool is_ordered_idx,
+ bool dynamic);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // NRF_LOG_CTRL_H
+
+/**
+ *@}
+ **/
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/experimental_log/nrf_log_default_backends.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/experimental_log/nrf_log_default_backends.h
new file mode 100644
index 0000000..8ad3da4
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/experimental_log/nrf_log_default_backends.h
@@ -0,0 +1,81 @@
+/**
+ * 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#ifndef NRF_LOG_DEFAULT_BACKENDS_H__
+#define NRF_LOG_DEFAULT_BACKENDS_H__
+
+/**@file
+ * @addtogroup nrf_log Logger module
+ * @ingroup app_common
+ *
+ * @defgroup nrf_log_default_backends Functions for initializing and adding default backends
+ * @{
+ * @ingroup nrf_log
+ * @brief The nrf_log default backends.
+ */
+
+#include "sdk_config.h"
+#include "sdk_errors.h"
+#include <stdbool.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @def NRF_LOG_DEFAULT_BACKENDS_INIT
+ * @brief Macro for initializing default backends.
+ *
+ * Each backend enabled in configuration is initialized and added as a backend to the logger.
+ */
+#if NRF_LOG_ENABLED
+#define NRF_LOG_DEFAULT_BACKENDS_INIT() nrf_log_default_backends_init()
+#else
+#define NRF_LOG_DEFAULT_BACKENDS_INIT()
+#endif
+
+void nrf_log_default_backends_init(void);
+
+#ifdef __cplusplus
+}
+#endif
+
+/** @} */
+
+#endif // NRF_LOG_DEFAULT_BACKENDS_H__
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/experimental_log/nrf_log_instance.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/experimental_log/nrf_log_instance.h
new file mode 100644
index 0000000..a4ba83d
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/experimental_log/nrf_log_instance.h
@@ -0,0 +1,135 @@
+/**
+ * Copyright (c) 2018 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#ifndef NRF_LOG_INSTANCE_H
+#define NRF_LOG_INSTANCE_H
+
+#include "sdk_config.h"
+#include "nrf_section.h"
+#include "nrf_log_types.h"
+#include <stdint.h>
+/*
+ * For GCC, sections are sorted in the group by the linker. For IAR and KEIL, it is assumed that linker will sort
+ * dynamic and const section in the same order (but in different locations). Proper message formatting
+ * is based on that assumption.
+ */
+#if defined(__GNUC__)
+#define NRF_LOG_DYNAMIC_SECTION_NAME(_module_name) CONCAT_2(log_dynamic_data_,_module_name)
+#define NRF_LOG_CONST_SECTION_NAME(_module_name) CONCAT_2(log_const_data_,_module_name)
+#else
+#define NRF_LOG_DYNAMIC_SECTION_NAME(_module_name) log_dynamic_data
+#define NRF_LOG_CONST_SECTION_NAME(_module_name) log_const_data
+#endif
+
+#define NRF_LOG_ITEM_DATA(_name) CONCAT_3(m_nrf_log_,_name,_logs_data)
+#define NRF_LOG_ITEM_DATA_DYNAMIC(_name) CONCAT_2(NRF_LOG_ITEM_DATA(_name),_dynamic)
+#define NRF_LOG_ITEM_DATA_CONST(_name) CONCAT_2(NRF_LOG_ITEM_DATA(_name),_const)
+
+#ifdef UNIT_TEST
+#define _CONST
+#else
+#define _CONST const
+#endif
+
+#if NRF_LOG_FILTERS_ENABLED
+#define NRF_LOG_DYNAMIC_STRUCT_NAME nrf_log_module_dynamic_data_t
+#else
+#define NRF_LOG_DYNAMIC_STRUCT_NAME nrf_log_module_reduced_dynamic_data_t
+#endif
+
+#define NRF_LOG_INTERNAL_ITEM_REGISTER( \
+ _name, _str_name, _info_color, _debug_color, _initial_lvl, _compiled_lvl) \
+ NRF_SECTION_ITEM_REGISTER(NRF_LOG_CONST_SECTION_NAME(_name), \
+ _CONST nrf_log_module_const_data_t NRF_LOG_ITEM_DATA_CONST(_name)) = { \
+ .p_module_name = _str_name, \
+ .info_color_id = (_info_color), \
+ .debug_color_id = (_debug_color), \
+ .compiled_lvl = (nrf_log_severity_t)(_compiled_lvl), \
+ .initial_lvl = (nrf_log_severity_t)(_initial_lvl), \
+ }; \
+ NRF_SECTION_ITEM_REGISTER(NRF_LOG_DYNAMIC_SECTION_NAME(_name), \
+ NRF_LOG_DYNAMIC_STRUCT_NAME NRF_LOG_ITEM_DATA_DYNAMIC(_name))
+
+/**@file
+ *
+ * @defgroup nrf_log_instance Macros for logging on instance level
+ * @{
+ * @ingroup nrf_log
+ *
+ * @brief Macros for logging on instance level
+ */
+
+/** @def NRF_LOG_INSTANCE_PTR_DECLARE
+ * @brief Macro for declaring a logger instance pointer in the module stucture.
+ */
+
+/** @def NRF_LOG_INSTANCE_REGISTER
+ * @brief Macro for creating an independent module instance.
+ *
+ * Module instance provides filtering of logs on instance level instead of module level.
+ */
+
+/** @def NRF_LOG_INSTANCE_PTR_INIT
+ * @brief Macro for initializing a pointer to the logger instance.
+ */
+
+
+ /** @} */
+#if NRF_LOG_ENABLED
+#define NRF_LOG_INSTANCE_PTR_DECLARE(_p_name) NRF_LOG_DYNAMIC_STRUCT_NAME * _p_name;
+
+#define NRF_LOG_INSTANCE_REGISTER( \
+ _module_name, _inst_name, _info_color, _debug_color, _initial_lvl, _compiled_lvl) \
+ NRF_LOG_INTERNAL_ITEM_REGISTER(CONCAT_3(_module_name,_,_inst_name), \
+ STRINGIFY(_module_name._inst_name), \
+ _info_color, \
+ _debug_color, \
+ _initial_lvl, \
+ _compiled_lvl)
+
+#define NRF_LOG_INSTANCE_PTR_INIT(_p_name, _module_name, _inst_name) \
+ ._p_name = &NRF_LOG_ITEM_DATA_DYNAMIC(CONCAT_3(_module_name,_,_inst_name)),
+
+#else
+#define NRF_LOG_INSTANCE_PTR_DECLARE(_p_name)
+#define NRF_LOG_INSTANCE_REGISTER(_module_name, _inst_name, info_color, debug_color, _initial_lvl, compiled_lvl)
+#define NRF_LOG_INSTANCE_PTR_INIT(_p_name, _module_name, _inst_name)
+#endif
+
+#endif //NRF_LOG_INSTANCE_H
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/experimental_log/nrf_log_str_formatter.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/experimental_log/nrf_log_str_formatter.h
new file mode 100644
index 0000000..b651183
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/experimental_log/nrf_log_str_formatter.h
@@ -0,0 +1,86 @@
+/**
+ * Copyright (c) 2016 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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
+ *
+ * @defgroup nrf_log_str_formatter String formatter for the logger messages
+ * @{
+ * @ingroup nrf_log
+ */
+
+#ifndef NRF_LOG_STR_FORMATTER_H
+#define NRF_LOG_STR_FORMATTER_H
+
+#include <stdint.h>
+#include "nrf_fprintf.h"
+#include "nrf_log_ctrl.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef struct
+{
+ uint32_t timestamp;
+ uint16_t module_id;
+ uint16_t dropped;
+ nrf_log_severity_t severity;
+ uint8_t use_colors;
+} nrf_log_str_formatter_entry_params_t;
+
+
+void nrf_log_std_entry_process(char const * p_str,
+ uint32_t const * p_args,
+ uint32_t nargs,
+ nrf_log_str_formatter_entry_params_t * p_params,
+ nrf_fprintf_ctx_t * p_ctx);
+
+void nrf_log_hexdump_entry_process(uint8_t * p_data,
+ uint32_t data_len,
+ nrf_log_str_formatter_entry_params_t * p_params,
+ nrf_fprintf_ctx_t * p_ctx);
+
+void nrf_log_str_formatter_timestamp_freq_set(uint32_t freq);
+#ifdef __cplusplus
+}
+#endif
+
+#endif //NRF_LOG_STR_FORMATTER_H
+/** @} */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/experimental_log/nrf_log_types.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/experimental_log/nrf_log_types.h
new file mode 100644
index 0000000..2ae08d3
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/experimental_log/nrf_log_types.h
@@ -0,0 +1,97 @@
+/**
+ * Copyright (c) 2018 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#ifndef NRF_LOG_TYPES_H
+#define NRF_LOG_TYPES_H
+
+#include <stdint.h>
+
+/**
+ * @brief Logger severity levels.
+ */
+typedef enum
+{
+ NRF_LOG_SEVERITY_NONE,
+ NRF_LOG_SEVERITY_ERROR,
+ NRF_LOG_SEVERITY_WARNING,
+ NRF_LOG_SEVERITY_INFO,
+ NRF_LOG_SEVERITY_DEBUG,
+ NRF_LOG_SEVERITY_INFO_RAW, /* Artificial level to pass information about skipping string postprocessing.*/
+} nrf_log_severity_t;
+
+/**
+ * @brief Structure holding dynamic data associated with a module or instance if filtering is enabled (@ref NRF_LOG_FILTERS_ENABLED).
+ *
+ * See @ref NRF_LOG_MODULE_REGISTER and @ref NRF_LOG_INSTANCE_REGISTER.
+ */
+typedef struct
+{
+ uint16_t module_id; ///< Module ID assigned during initialization.
+ uint16_t order_idx; ///< Ordered index of the module (used for auto-completion).
+ uint32_t filter; ///< Current highest severity level accepted (redundant to @ref nrf_log_module_dynamic_data_t::filter_lvls, used for optimization)
+ uint32_t filter_lvls; ///< Current severity levels for each backend (3 bits per backend).
+} nrf_log_module_dynamic_data_t;
+
+/**
+ * @brief Structure holding dynamic data associated with a module or instance if filtering is disabled (@ref NRF_LOG_FILTERS_ENABLED).
+ *
+ * See @ref NRF_LOG_MODULE_REGISTER and @ref NRF_LOG_INSTANCE_REGISTER.
+ */
+typedef struct
+{
+ uint16_t module_id; ///< Module ID assigned during initialization.
+ uint16_t padding; ///< Padding to fit in word.
+} nrf_log_module_reduced_dynamic_data_t;
+
+
+/**
+ * @brief Structure holding constant data associated with a module or instance.
+ *
+ * See @ref NRF_LOG_MODULE_REGISTER and @ref NRF_LOG_INSTANCE_REGISTER.
+ */
+typedef struct
+{
+ const char * p_module_name; ///< Module or instance name.
+ uint8_t info_color_id; ///< Color code of info messages.
+ uint8_t debug_color_id; ///< Color code of debug messages.
+ nrf_log_severity_t compiled_lvl; ///< Compiled highest severity level.
+ nrf_log_severity_t initial_lvl; ///< Severity level for given module or instance set on backend initialization.
+} nrf_log_module_const_data_t;
+
+#endif //NRF_LOG_TYPES_H
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/experimental_log/src/nrf_log_backend_flash.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/experimental_log/src/nrf_log_backend_flash.c
new file mode 100644
index 0000000..0efd5d8
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/experimental_log/src/nrf_log_backend_flash.c
@@ -0,0 +1,739 @@
+/**
+ * Copyright (c) 2016 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#include "sdk_common.h"
+#if NRF_MODULE_ENABLED(NRF_LOG) && NRF_MODULE_ENABLED(NRF_LOG_BACKEND_FLASH)
+#include "nrf_log_backend_flash.h"
+#include "nrf_log_str_formatter.h"
+#include "nrf_fstorage_nvmc.h"
+#include "nrf_log.h"
+#include "nrf_atomic.h"
+#include "nrf_queue.h"
+#include "app_error.h"
+#include <stdbool.h>
+
+#if (NRF_LOG_BACKEND_FLASHLOG_ENABLED == 0) && (NRF_LOG_BACKEND_CRASHLOG_ENABLED == 0)
+#error "No flash backend enabled."
+#endif
+
+/** @brief Maximum logger message payload (arguments or data in hexdump) which can be stored. */
+#define FLASH_LOG_MAX_PAYLOAD_SIZE (NRF_LOG_BACKEND_FLASH_SER_BUFFER_SIZE - sizeof(nrf_log_header_t))
+
+/** @brief Size of serialization buffer in words. */
+#define FLASH_LOG_SER_BUFFER_WORDS (NRF_LOG_BACKEND_FLASH_SER_BUFFER_SIZE/sizeof(uint32_t))
+
+/** @brief Length of logger header. */
+#define LOG_HEADER_LEN (sizeof(nrf_log_header_t))
+
+/** @brief Length of logger header given in 32 bit words. */
+#define LOG_HEADER_LEN_WORDS (LOG_HEADER_LEN/sizeof(uint32_t))
+
+/** @brief Maximum possible length of standard log message. */
+#define STD_LOG_MSG_MAX_LEN (LOG_HEADER_LEN + NRF_LOG_MAX_NUM_OF_ARGS*sizeof(uint32_t))
+
+/* Buffer must be multiple of 4. */
+STATIC_ASSERT((NRF_LOG_BACKEND_FLASH_SER_BUFFER_SIZE % sizeof(uint32_t)) == 0);
+
+/* Buffer must fit standard log message. */
+STATIC_ASSERT(NRF_LOG_BACKEND_FLASH_SER_BUFFER_SIZE >= STD_LOG_MSG_MAX_LEN);
+
+/** @brief Flash page size in bytes. */
+#define CODE_PAGE_SIZE 4096
+
+/** @brief Start address of the area dedicated for flash log. */
+#define FLASH_LOG_START_ADDR (NRF_LOG_BACKEND_FLASH_START_PAGE * CODE_PAGE_SIZE)
+
+/** @brief End address of the area dedicated for flash log. */
+#define FLASH_LOG_END_ADDR (FLASH_LOG_START_ADDR + (NRF_LOG_BACKEND_PAGES * CODE_PAGE_SIZE) - 1)
+
+/** @brief Size of the area dedicated for flash log. */
+#define FLASH_LOG_SIZE (NRF_LOG_BACKEND_PAGES * CODE_PAGE_SIZE)
+
+/** @brief Start address determined in runtime.
+ *
+ * If configuration indicates that flash log should be placed after application.
+ * */
+#if defined ( __CC_ARM )
+#define RUNTIME_START_ADDR \
+ _Pragma("diag_suppress 170") \
+ ((NRF_LOG_BACKEND_FLASH_START_PAGE == 0) ? \
+ (CODE_PAGE_SIZE*CEIL_DIV((uint32_t)CODE_END, CODE_PAGE_SIZE)) : FLASH_LOG_START_ADDR) \
+ _Pragma("diag_default 170")
+#else
+#define RUNTIME_START_ADDR ((NRF_LOG_BACKEND_FLASH_START_PAGE == 0) ? \
+ (CODE_PAGE_SIZE*CEIL_DIV((uint32_t)CODE_END, CODE_PAGE_SIZE)) : FLASH_LOG_START_ADDR)
+#endif
+static void fstorage_evt_handler(nrf_fstorage_evt_t * p_evt);
+
+/** @brief Message queue for run time flash log. */
+#if NRF_LOG_BACKEND_FLASHLOG_ENABLED
+NRF_QUEUE_DEF(nrf_log_entry_t *,
+ m_flashlog_queue,
+ NRF_LOG_BACKEND_FLASHLOG_QUEUE_SIZE,
+ NRF_QUEUE_MODE_NO_OVERFLOW);
+static const nrf_queue_t * mp_flashlog_queue = &m_flashlog_queue;
+#else
+static const nrf_queue_t * mp_flashlog_queue = NULL;
+#endif
+
+
+/** @brief Message FIFO for crash log. */
+#if NRF_LOG_BACKEND_CRASHLOG_ENABLED
+NRF_QUEUE_DEF(nrf_log_entry_t *,
+ m_crashlog_queue,
+ NRF_LOG_BACKEND_CRASHLOG_FIFO_SIZE,
+ NRF_QUEUE_MODE_NO_OVERFLOW);
+static const nrf_queue_t * mp_crashlog_queue = &m_crashlog_queue;
+#else
+static const nrf_queue_t * mp_crashlog_queue = NULL;
+#endif
+
+
+/** @brief Fstorage instance used for flash log. */
+NRF_FSTORAGE_DEF(nrf_fstorage_t m_log_flash_fstorage) =
+{
+ /* Set a handler for fstorage events. */
+ .evt_handler = fstorage_evt_handler,
+ .start_addr = FLASH_LOG_START_ADDR,
+ .end_addr = FLASH_LOG_END_ADDR,
+};
+
+/** @brief Flash log state. */
+typedef enum
+{
+ LOG_BACKEND_FLASH_ACTIVE, /**< Flash backend is active. */
+ LOG_BACKEND_FLASH_INACTIVE, /**< Flash backend is inactive. All incoming requests are skipped. */
+ LOG_BACKEND_FLASH_IN_PANIC, /**< Flash backend is in panic mode. Incoming messages are written to flash in synchronous mode. */
+} log_backend_flash_state_t;
+
+static log_backend_flash_state_t m_state; /**< Flash logger backend state. */
+static nrf_atomic_flag_t m_busy_flag; /**< Flag indicating if module performs flash writing. */
+static uint32_t m_flash_buf[FLASH_LOG_SER_BUFFER_WORDS]; /**< Buffer used for serializing messages. */
+static uint32_t m_curr_addr; /**< Address of free spot in the storage area. */
+static size_t m_curr_len; /**< Length of current message being written. */
+static uint32_t m_dropped; /**< Number of dropped messages. */
+
+/** @brief Log message string injected when entering panic mode. */
+static const char crashlog_str[] = "-----------CRASHLOG------------\r\n";
+
+/** @brief Function saturates input to maximum possible length and rounds up value to be multiple
+ * of word size.
+ *
+ * @param length Length value.
+ *
+ * @return Modified input length.
+ */
+static uint32_t saturate_align_length(uint32_t length)
+{
+ length = (length > FLASH_LOG_MAX_PAYLOAD_SIZE) ? FLASH_LOG_MAX_PAYLOAD_SIZE : length; //saturate
+ length = CEIL_DIV(length, sizeof(uint32_t))*sizeof(uint32_t);
+ return length;
+}
+
+
+/**
+ * @brief Function for copying logger message to the buffer.
+ *
+ * @param[in] p_msg Logger message.
+ * @param[out] p_buf Output buffer where serialized message is placed.
+ * @param[in,out] p_len Buffer size as input, length of prepared data as output.
+ *
+ * @return True if message fits into the buffer, false otherwise
+ */
+static bool msg_to_buf(nrf_log_entry_t * p_msg, uint8_t * p_buf, size_t * p_len)
+{
+ uint32_t data_len;
+ nrf_log_header_t header = {0};
+ uint32_t memobj_offset = HEADER_SIZE*sizeof(uint32_t);
+
+ nrf_memobj_read(p_msg, &header, HEADER_SIZE*sizeof(uint32_t), 0);
+
+ memcpy(p_buf, &header, sizeof(nrf_log_header_t));
+ p_buf += sizeof(nrf_log_header_t);
+
+ switch (header.base.generic.type)
+ {
+ case HEADER_TYPE_STD:
+ {
+ data_len = header.base.std.nargs * sizeof(uint32_t);
+ break;
+ }
+ case HEADER_TYPE_HEXDUMP:
+ {
+ data_len = saturate_align_length(header.base.hexdump.len);
+ break;
+ }
+ default:
+ *p_len = 0;
+ return false;
+ }
+ nrf_memobj_read(p_msg, p_buf, data_len, memobj_offset);
+
+ if (*p_len >= sizeof(nrf_log_header_t) + data_len)
+ {
+ *p_len = sizeof(nrf_log_header_t) + data_len;
+ return true;
+ }
+ else
+ {
+ return false;
+ }
+}
+
+/**
+ * @brief Function for getting logger message stored in flash.
+ *
+ * @param[in] p_buf Pointer to the location where message is stored.
+ * @param[out] pp_header Pointer to the log message header.
+ * @param[out] pp_data Pointer to the log message data (arguments or data in case of hexdump).
+ *
+ * @return True if message was successfully fetched, false otherwise.
+ */
+static bool msg_from_buf(uint32_t * p_buf,
+ nrf_log_header_t * * pp_header,
+ uint8_t * * pp_data,
+ uint32_t * p_len)
+{
+ *pp_header = (nrf_log_header_t *)p_buf;
+ *pp_data = (uint8_t *)&p_buf[LOG_HEADER_LEN_WORDS];
+
+ uint32_t data_len;
+
+ switch ((*pp_header)->base.generic.type)
+ {
+ case HEADER_TYPE_STD:
+ {
+ data_len = ((*pp_header)->base.std.nargs)*sizeof(uint32_t);
+ break;
+ }
+ case HEADER_TYPE_HEXDUMP:
+ {
+
+ data_len = saturate_align_length((*pp_header)->base.hexdump.len);
+ break;
+ }
+ default:
+ return false;
+ }
+
+ *p_len = LOG_HEADER_LEN + data_len;
+ return true;
+}
+
+/**
+ * @brief Function for processing log message queue.
+ *
+ * If writing to flash is synchronous then function drains the queue and writes all messages to flash.
+ * If writing to flash is asynchronous then function starts single write operation. In asynchronous mode
+ * function is called when new message is put into the queue from from flash operation callback.
+ *
+ * Function detects the situation that flash module reports attempt to write outside dedicated area.
+ * In that case flash backend stops writing any new messages.
+ *
+ * @param p_queue Queue will log messages
+ * @param fstorage_blocking If true it indicates that flash operations are blocking, event handler is not used.
+ */
+static void log_msg_queue_process(nrf_queue_t const * p_queue, bool fstorage_blocking)
+{
+ nrf_log_entry_t * p_msg;
+ bool busy = false;
+ while (nrf_queue_pop(p_queue, &p_msg) == NRF_SUCCESS)
+ {
+ ret_code_t err_code;
+
+ m_curr_len = sizeof(m_flash_buf);
+ if (!msg_to_buf(p_msg, (uint8_t *)m_flash_buf, &m_curr_len))
+ {
+ continue;
+ }
+
+ err_code = nrf_fstorage_write(&m_log_flash_fstorage, m_curr_addr, m_flash_buf, m_curr_len, p_msg);
+
+ if (err_code == NRF_SUCCESS)
+ {
+ if (fstorage_blocking)
+ {
+ m_curr_addr += m_curr_len;
+
+ nrf_memobj_put(p_msg);
+ }
+ else
+ {
+ busy = true;
+ break;
+ }
+ }
+ else if (!fstorage_blocking && (err_code == NRF_ERROR_NO_MEM))
+ {
+ // fstorage queue got full. Drop entry.
+ nrf_memobj_put(p_msg);
+ m_dropped++;
+ break;
+ }
+ else if (err_code == NRF_ERROR_INVALID_ADDR)
+ {
+ // Trying to write outside the area, flash log is full. Skip any new writes.
+ nrf_memobj_put(p_msg);
+ m_state = LOG_BACKEND_FLASH_INACTIVE;
+ }
+ else
+ {
+ ASSERT(false);
+ }
+ }
+
+ if (!busy)
+ {
+ UNUSED_RETURN_VALUE(nrf_atomic_flag_clear(&m_busy_flag));
+ }
+}
+
+static void queue_element_drop(nrf_queue_t const * p_queue)
+{
+ nrf_log_entry_t * p_msg;
+ if (nrf_queue_pop(p_queue, &p_msg) == NRF_SUCCESS)
+ {
+ m_dropped++;
+ nrf_memobj_put(p_msg);
+ }
+}
+
+static void fstorage_evt_handler(nrf_fstorage_evt_t * p_evt)
+{
+ if (m_state == LOG_BACKEND_FLASH_ACTIVE)
+ {
+ switch (p_evt->id)
+ {
+ case NRF_FSTORAGE_EVT_WRITE_RESULT:
+ {
+ if (p_evt->result == NRF_SUCCESS)
+ {
+ m_curr_addr += m_curr_len;
+ m_curr_len = 0;
+ log_msg_queue_process(mp_flashlog_queue, false);
+ }
+ else
+ {
+ m_dropped++;
+ }
+
+ if (p_evt->p_param)
+ {
+ nrf_memobj_put((nrf_log_entry_t *)p_evt->p_param);
+ }
+ break;
+ }
+ default:
+ break;
+ }
+ }
+ else if ((m_state == LOG_BACKEND_FLASH_INACTIVE) &&
+ (p_evt->id == NRF_FSTORAGE_EVT_ERASE_RESULT) &&
+ (p_evt->addr == RUNTIME_START_ADDR))
+ {
+ m_state = LOG_BACKEND_FLASH_ACTIVE;
+ }
+}
+
+/**
+ * @brief Function for enqueueing new message.
+ *
+ * If queue is full then the oldest message is freed.
+ *
+ * @param p_queue Queue.
+ * @param p_msg Message.
+ *
+ * @return Number of dropped messages
+ */
+static uint32_t message_enqueue(nrf_queue_t const * p_queue, nrf_log_entry_t * p_msg)
+{
+ uint32_t dropped = 0;
+
+ //flag was set, busy so enqueue message
+ while (nrf_queue_push(p_queue, &p_msg) != NRF_SUCCESS)
+ {
+
+ nrf_log_entry_t * p_old_msg;
+ if (nrf_queue_pop(p_queue, &p_old_msg) == NRF_SUCCESS)
+ {
+ nrf_memobj_put(p_old_msg);
+ dropped++;
+ }
+ }
+
+ return dropped;
+}
+
+
+void nrf_log_backend_flashlog_put(nrf_log_backend_t const * p_backend,
+ nrf_log_entry_t * p_msg)
+{
+ if (m_state == LOG_BACKEND_FLASH_ACTIVE)
+ {
+ nrf_memobj_get(p_msg);
+
+ m_dropped += message_enqueue(mp_flashlog_queue, p_msg);
+
+ if (nrf_atomic_flag_set_fetch(&m_busy_flag) == 0)
+ {
+ log_msg_queue_process(mp_flashlog_queue, false);
+ }
+ }
+}
+
+
+void nrf_log_backend_crashlog_put(nrf_log_backend_t const * p_backend,
+ nrf_log_entry_t * p_msg)
+{
+ if (m_state != LOG_BACKEND_FLASH_INACTIVE)
+ {
+ nrf_memobj_get(p_msg);
+
+ UNUSED_RETURN_VALUE(message_enqueue(mp_crashlog_queue, p_msg));
+ }
+
+ if (m_state == LOG_BACKEND_FLASH_IN_PANIC)
+ {
+ log_msg_queue_process(mp_crashlog_queue, true);
+ }
+}
+
+void nrf_log_backend_flashlog_flush(nrf_log_backend_t const * p_backend)
+{
+ queue_element_drop(mp_flashlog_queue);
+}
+
+void nrf_log_backend_crashlog_flush(nrf_log_backend_t const * p_backend)
+{
+ queue_element_drop(mp_crashlog_queue);
+}
+
+void nrf_log_backend_flashlog_panic_set(nrf_log_backend_t const * p_backend)
+{
+ /* Empty */
+}
+
+/**
+ * @brief Function for injecting log message which will indicate start of crash log.
+ */
+static void crashlog_marker_inject(void)
+{
+ nrf_log_header_t crashlog_marker_hdr = {
+ .base = {
+ .std = {
+ .type = HEADER_TYPE_STD,
+ .severity = NRF_LOG_SEVERITY_INFO_RAW,
+ .nargs = 0,
+ .addr = (uint32_t)crashlog_str & STD_ADDR_MASK
+ }
+ },
+ .module_id = 0,
+ .timestamp = 0,
+ };
+ m_flash_buf[0] = crashlog_marker_hdr.base.raw;
+ m_flash_buf[1] = crashlog_marker_hdr.module_id;
+ m_flash_buf[2] = crashlog_marker_hdr.timestamp;
+ (void)nrf_fstorage_write(&m_log_flash_fstorage, m_curr_addr, m_flash_buf, LOG_HEADER_LEN, NULL);
+ m_curr_addr += LOG_HEADER_LEN;
+}
+
+
+void nrf_log_backend_crashlog_panic_set(nrf_log_backend_t const * p_backend)
+{
+ if (nrf_fstorage_init(&m_log_flash_fstorage, &nrf_fstorage_nvmc, NULL) == NRF_SUCCESS)
+ {
+ m_state = LOG_BACKEND_FLASH_IN_PANIC;
+
+ /* In case of Softdevice MWU may protect access to NVMC. */
+ NVIC_DisableIRQ(MWU_IRQn);
+
+ log_msg_queue_process(mp_flashlog_queue, true);
+
+ crashlog_marker_inject();
+
+ log_msg_queue_process(mp_crashlog_queue, true);
+ }
+ else
+ {
+ m_state = LOG_BACKEND_FLASH_INACTIVE;
+ }
+}
+
+/**
+ * @brief Function for determining first empty location in area dedicated for flash logger backend.
+ */
+static uint32_t empty_addr_get(void)
+{
+ uint32_t token = 0;
+ nrf_log_header_t * p_dummy_header;
+ uint8_t * p_dummy_data;
+
+ while(nrf_log_backend_flash_next_entry_get(&token, &p_dummy_header, &p_dummy_data) == NRF_SUCCESS)
+ {
+
+ }
+
+ return token;
+}
+
+
+ret_code_t nrf_log_backend_flash_init(nrf_fstorage_api_t const * p_fs_api)
+{
+ ret_code_t err_code;
+
+
+ uint32_t start_addr = RUNTIME_START_ADDR;
+ uint32_t end_addr = start_addr + FLASH_LOG_SIZE - 1;
+
+ m_log_flash_fstorage.start_addr = start_addr;
+ m_log_flash_fstorage.end_addr = end_addr;
+
+ err_code = nrf_fstorage_init(&m_log_flash_fstorage, p_fs_api, NULL);
+ if (err_code != NRF_SUCCESS)
+ {
+ return err_code;
+ }
+
+ m_curr_addr = empty_addr_get();
+ m_state = LOG_BACKEND_FLASH_ACTIVE;
+
+ return err_code;
+}
+
+
+ret_code_t nrf_log_backend_flash_next_entry_get(uint32_t * p_token,
+ nrf_log_header_t * * pp_header,
+ uint8_t * * pp_data)
+{
+ uint32_t * p_addr = p_token;
+ uint32_t len;
+
+ *p_addr = (*p_addr == 0) ? RUNTIME_START_ADDR : *p_addr;
+
+ if (nrf_fstorage_rmap(&m_log_flash_fstorage, *p_addr) == NULL)
+ {
+ //Supports only memories which can be mapped for reading.
+ return NRF_ERROR_NOT_SUPPORTED;
+ }
+
+ if (msg_from_buf((uint32_t *)*p_addr, pp_header, pp_data, &len))
+ {
+ *p_addr += len;
+ return NRF_SUCCESS;
+ }
+ else
+ {
+ return NRF_ERROR_NOT_FOUND;
+ }
+}
+
+
+ret_code_t nrf_log_backend_flash_erase(void)
+{
+ ret_code_t err_code;
+
+ m_state = LOG_BACKEND_FLASH_INACTIVE;
+ err_code = nrf_fstorage_erase(&m_log_flash_fstorage, RUNTIME_START_ADDR, NRF_LOG_BACKEND_PAGES, NULL);
+
+ m_curr_addr = RUNTIME_START_ADDR;
+
+ return err_code;
+}
+
+#if NRF_LOG_BACKEND_FLASHLOG_ENABLED
+const nrf_log_backend_api_t nrf_log_backend_flashlog_api = {
+ .put = nrf_log_backend_flashlog_put,
+ .flush = nrf_log_backend_flashlog_flush,
+ .panic_set = nrf_log_backend_flashlog_panic_set,
+};
+#endif
+
+#if NRF_LOG_BACKEND_CRASHLOG_ENABLED
+const nrf_log_backend_api_t nrf_log_backend_crashlog_api = {
+ .put = nrf_log_backend_crashlog_put,
+ .flush = nrf_log_backend_crashlog_flush,
+ .panic_set = nrf_log_backend_crashlog_panic_set,
+};
+#endif
+
+#if NRF_LOG_BACKEND_FLASH_CLI_CMDS
+#include "nrf_cli.h"
+
+static uint8_t m_buffer[64];
+static nrf_cli_t const * mp_cli;
+
+static void cli_tx(void const * p_context, char const * p_buffer, size_t len);
+
+static nrf_fprintf_ctx_t m_fprintf_ctx =
+{
+ .p_io_buffer = (char *)m_buffer,
+ .io_buffer_size = sizeof(m_buffer)-1,
+ .io_buffer_cnt = 0,
+ .auto_flush = true,
+ .p_user_ctx = &mp_cli,
+ .fwrite = cli_tx
+};
+
+
+static void flashlog_clear_cmd(nrf_cli_t const * p_cli, size_t argc, char ** argv)
+{
+ if (nrf_cli_help_requested(p_cli))
+ {
+ nrf_cli_help_print(p_cli, NULL, 0);
+ }
+
+ UNUSED_RETURN_VALUE(nrf_log_backend_flash_erase());
+}
+
+#include "nrf_delay.h"
+static void cli_tx(void const * p_context, char const * p_buffer, size_t len)
+{
+ nrf_cli_t * * pp_cli = (nrf_cli_t * *)p_context;
+ char * p_strbuf = (char *)&p_buffer[len];
+ *p_strbuf = '\0';
+ nrf_cli_fprintf((nrf_cli_t const *)*pp_cli, NRF_CLI_DEFAULT, p_buffer);
+ // nrf_delay_ms(10);
+}
+
+
+static void entry_process(nrf_cli_t const * p_cli, nrf_log_header_t * p_header, uint8_t * p_data)
+{
+ mp_cli = p_cli;
+
+ nrf_log_str_formatter_entry_params_t params =
+ {
+ .timestamp = p_header->timestamp,
+ .module_id = p_header->module_id,
+ .use_colors = 0,
+ };
+
+ switch (p_header->base.generic.type)
+ {
+ case HEADER_TYPE_STD:
+ {
+ params.severity = (nrf_log_severity_t)p_header->base.std.severity;
+ nrf_log_std_entry_process((const char *)((uint32_t)p_header->base.std.addr),
+ (uint32_t *)p_data,
+ p_header->base.std.nargs,
+ &params,
+ &m_fprintf_ctx);
+ break;
+ }
+ case HEADER_TYPE_HEXDUMP:
+ {
+ params.severity = (nrf_log_severity_t)p_header->base.hexdump.severity;
+
+ nrf_log_hexdump_entry_process(p_data,
+ p_header->base.hexdump.len,
+ &params,
+ &m_fprintf_ctx);
+ break;
+ }
+ default:
+ ASSERT(0);
+ }
+
+}
+
+
+static void flashlog_read_cmd(nrf_cli_t const * p_cli, size_t argc, char ** argv)
+{
+ if (nrf_cli_help_requested(p_cli))
+ {
+ nrf_cli_help_print(p_cli, NULL, 0);
+ }
+
+ uint32_t token = 0;
+ uint8_t * p_data = NULL;
+ bool empty = true;
+ nrf_log_header_t * p_header;
+
+ while (1)
+ {
+ if (nrf_log_backend_flash_next_entry_get(&token, &p_header, &p_data) == NRF_SUCCESS)
+ {
+ entry_process(p_cli, p_header, p_data);
+ empty = false;
+ }
+ else
+ {
+ break;
+ }
+ }
+
+ if (empty)
+ {
+ nrf_cli_fprintf(p_cli, NRF_CLI_ERROR, "Flash log empty\r\n");
+ }
+}
+
+
+static void flashlog_status_cmd(nrf_cli_t const * p_cli, size_t argc, char ** argv)
+{
+ if (nrf_cli_help_requested(p_cli))
+ {
+ nrf_cli_help_print(p_cli, NULL, 0);
+ }
+
+ nrf_cli_fprintf(p_cli, NRF_CLI_NORMAL, "Flash log status:\r\n");
+ nrf_cli_fprintf(p_cli, NRF_CLI_NORMAL, "\t\t- Location (address: 0x%08X, length: %d)\r\n",
+ RUNTIME_START_ADDR, FLASH_LOG_SIZE);
+ nrf_cli_fprintf(p_cli, NRF_CLI_NORMAL, "\t\t- Current usage:%d%% (%d of %d bytes used)\r\n",
+ 100ul * (m_curr_addr - RUNTIME_START_ADDR)/FLASH_LOG_SIZE,
+ m_curr_addr - RUNTIME_START_ADDR,
+ FLASH_LOG_SIZE);
+ nrf_cli_fprintf(p_cli, NRF_CLI_NORMAL, "\t\t- Dropped logs: %d\r\n", m_dropped);
+
+
+}
+
+
+NRF_CLI_CREATE_STATIC_SUBCMD_SET(m_flashlog_cmd)
+{
+ NRF_CLI_CMD(clear, NULL, "Remove logs", flashlog_clear_cmd),
+ NRF_CLI_CMD(read, NULL, "Read stored logs", flashlog_read_cmd),
+ NRF_CLI_CMD(status, NULL, "Flash log status", flashlog_status_cmd),
+ NRF_CLI_SUBCMD_SET_END
+};
+
+NRF_CLI_CMD_REGISTER(flashlog, &m_flashlog_cmd, "Commands for reading logs stored in non-volatile memory", NULL);
+
+#endif //NRF_LOG_BACKEND_FLASH_CLI_CMDS
+
+#endif //NRF_MODULE_ENABLED(NRF_LOG) && NRF_MODULE_ENABLED(NRF_LOG_BACKEND_FLASH)
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/experimental_log/src/nrf_log_backend_rtt.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/experimental_log/src/nrf_log_backend_rtt.c
new file mode 100644
index 0000000..1ff3a26
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/experimental_log/src/nrf_log_backend_rtt.c
@@ -0,0 +1,123 @@
+/**
+ * Copyright (c) 2016 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#include "sdk_common.h"
+#if NRF_MODULE_ENABLED(NRF_LOG) && NRF_MODULE_ENABLED(NRF_LOG_BACKEND_RTT)
+#include "nrf_log_backend_rtt.h"
+#include "nrf_log_backend_serial.h"
+#include "nrf_log_str_formatter.h"
+#include "nrf_log_internal.h"
+#include "nrf_delay.h"
+#include <SEGGER_RTT_Conf.h>
+#include <SEGGER_RTT.h>
+
+static bool m_host_present;
+
+static uint8_t m_string_buff[NRF_LOG_BACKEND_RTT_TEMP_BUFFER_SIZE];
+
+void nrf_log_backend_rtt_init(void)
+{
+ SEGGER_RTT_Init();
+}
+
+static void serial_tx(void const * p_context, char const * buffer, size_t len)
+{
+ if (len)
+ {
+ uint32_t idx = 0;
+ uint32_t processed;
+ uint32_t watchdog_counter = NRF_LOG_BACKEND_RTT_TX_RETRY_CNT;
+ do
+ {
+ processed = SEGGER_RTT_WriteNoLock(0, &buffer[idx], len);
+ idx += processed;
+ len -= processed;
+ if (processed == 0)
+ {
+ /* There are two possible reasons for not writing any data to RTT:
+ * - The host is not connected and not reading the data.
+ * - The buffer got full and will be read by the host.
+ * These two situations are distinguished using the following algorithm.
+ * At the begining, the module assumes that the host is active,
+ * so when no data is read, it busy waits and retries.
+ * If, after retrying, the host reads the data, the module assumes that the host is active.
+ * If it fails, the module assumes that the host is inactive and stores that information. On next
+ * call, only one attempt takes place. The host is marked as active if the attempt is successful.
+ */
+ if (!m_host_present)
+ {
+ break;
+ }
+ else
+ {
+ nrf_delay_ms(NRF_LOG_BACKEND_RTT_TX_RETRY_DELAY_MS);
+ watchdog_counter--;
+ if (watchdog_counter == 0)
+ {
+ m_host_present = false;
+ break;
+ }
+ }
+ }
+ m_host_present = true;
+ } while (len);
+ }
+}
+static void nrf_log_backend_rtt_put(nrf_log_backend_t const * p_backend,
+ nrf_log_entry_t * p_msg)
+{
+ nrf_log_backend_serial_put(p_backend, p_msg, m_string_buff, NRF_LOG_BACKEND_RTT_TEMP_BUFFER_SIZE, serial_tx);
+}
+
+static void nrf_log_backend_rtt_flush(nrf_log_backend_t const * p_backend)
+{
+
+}
+
+static void nrf_log_backend_rtt_panic_set(nrf_log_backend_t const * p_backend)
+{
+
+}
+
+const nrf_log_backend_api_t nrf_log_backend_rtt_api = {
+ .put = nrf_log_backend_rtt_put,
+ .flush = nrf_log_backend_rtt_flush,
+ .panic_set = nrf_log_backend_rtt_panic_set,
+};
+#endif //NRF_MODULE_ENABLED(NRF_LOG) && NRF_MODULE_ENABLED(NRF_LOG_BACKEND_RTT)
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/experimental_log/src/nrf_log_backend_serial.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/experimental_log/src/nrf_log_backend_serial.c
new file mode 100644
index 0000000..7db0074
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/experimental_log/src/nrf_log_backend_serial.c
@@ -0,0 +1,115 @@
+/**
+ * Copyright (c) 2016 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#include "sdk_common.h"
+#if NRF_MODULE_ENABLED(NRF_LOG)
+#include "nrf_log_backend_serial.h"
+#include "nrf_log_str_formatter.h"
+#include "nrf_log_internal.h"
+
+void nrf_log_backend_serial_put(nrf_log_backend_t const * p_backend,
+ nrf_log_entry_t * p_msg,
+ uint8_t * p_buffer,
+ uint32_t length,
+ nrf_fprintf_fwrite tx_func)
+{
+ nrf_memobj_get(p_msg);
+
+ nrf_fprintf_ctx_t fprintf_ctx = {
+ .p_io_buffer = (char *)p_buffer,
+ .io_buffer_size = length,
+ .io_buffer_cnt = 0,
+ .auto_flush = false,
+ .p_user_ctx = NULL,
+ .fwrite = tx_func
+ };
+
+ nrf_log_str_formatter_entry_params_t params;
+
+ nrf_log_header_t header;
+ uint32_t memobj_offset = 0;
+ nrf_memobj_read(p_msg, &header, HEADER_SIZE*sizeof(uint32_t), memobj_offset);
+ memobj_offset = HEADER_SIZE*sizeof(uint32_t);
+
+ params.timestamp = header.timestamp;
+ params.module_id = header.module_id;
+ params.dropped = header.dropped;
+ params.use_colors = NRF_LOG_USES_COLORS;
+
+ /*lint -save -e438*/
+ if (header.base.generic.type == HEADER_TYPE_STD)
+ {
+ char const * p_log_str = (char const *)((uint32_t)header.base.std.addr);
+ params.severity = (nrf_log_severity_t)header.base.std.severity;
+ uint32_t nargs = header.base.std.nargs;
+ uint32_t args[NRF_LOG_MAX_NUM_OF_ARGS];
+
+ nrf_memobj_read(p_msg, args, nargs*sizeof(uint32_t), memobj_offset);
+ memobj_offset += (nargs*sizeof(uint32_t));
+
+ nrf_log_std_entry_process(p_log_str,
+ args,
+ nargs,
+ &params,
+ &fprintf_ctx);
+
+ }
+ else if (header.base.generic.type == HEADER_TYPE_HEXDUMP)
+ {
+ uint32_t data_len = header.base.hexdump.len;
+ params.severity = (nrf_log_severity_t)header.base.hexdump.severity;
+ uint8_t data_buf[8];
+ uint32_t chunk_len;
+ do
+ {
+ chunk_len = sizeof(data_buf) > data_len ? data_len : sizeof(data_buf);
+ nrf_memobj_read(p_msg, data_buf, chunk_len, memobj_offset);
+ memobj_offset += chunk_len;
+ data_len -= chunk_len;
+
+ nrf_log_hexdump_entry_process(data_buf,
+ chunk_len,
+ &params,
+ &fprintf_ctx);
+ } while (data_len > 0);
+ }
+ nrf_memobj_put(p_msg);
+ /*lint -restore*/
+}
+#endif //NRF_LOG_ENABLED
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/experimental_log/src/nrf_log_backend_serial.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/experimental_log/src/nrf_log_backend_serial.h
new file mode 100644
index 0000000..22d26f5
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/experimental_log/src/nrf_log_backend_serial.h
@@ -0,0 +1,77 @@
+/**
+ * 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#ifndef NRF_LOG_BACKEND_SERIAL_H
+#define NRF_LOG_BACKEND_SERIAL_H
+/**@file
+ * @addtogroup nrf_log Logger module
+ * @ingroup app_common
+ *
+ * @defgroup nrf_log_backend_serial Common part of serial backends
+ * @{
+ * @ingroup nrf_log
+ * @brief The nrf_log serial backend common put function.
+ */
+
+
+#include "nrf_log_backend_interface.h"
+#include "nrf_fprintf.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @brief A function for processing logger entry with simple serial interface as output.
+ *
+ *
+ */
+void nrf_log_backend_serial_put(nrf_log_backend_t const * p_backend,
+ nrf_log_entry_t * p_msg,
+ uint8_t * p_buffer,
+ uint32_t length,
+ nrf_fprintf_fwrite tx_func);
+
+#endif //NRF_LOG_BACKEND_SERIAL_H
+
+#ifdef __cplusplus
+}
+#endif
+
+/** @} */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/experimental_log/src/nrf_log_backend_uart.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/experimental_log/src/nrf_log_backend_uart.c
new file mode 100644
index 0000000..76dad8a
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/experimental_log/src/nrf_log_backend_uart.c
@@ -0,0 +1,116 @@
+/**
+ * Copyright (c) 2016 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#include "sdk_common.h"
+#if NRF_MODULE_ENABLED(NRF_LOG) && NRF_MODULE_ENABLED(NRF_LOG_BACKEND_UART)
+#include "nrf_log_backend_uart.h"
+#include "nrf_log_backend_serial.h"
+#include "nrf_log_internal.h"
+#include "nrf_drv_uart.h"
+#include "app_error.h"
+
+nrf_drv_uart_t m_uart = NRF_DRV_UART_INSTANCE(0);
+
+static uint8_t m_string_buff[NRF_LOG_BACKEND_UART_TEMP_BUFFER_SIZE];
+static volatile bool m_xfer_done;
+static bool m_async_mode;
+static void uart_evt_handler(nrf_drv_uart_event_t * p_event, void * p_context)
+{
+ m_xfer_done = true;
+}
+
+static void uart_init(bool async_mode)
+{
+ nrf_drv_uart_config_t config = NRF_DRV_UART_DEFAULT_CONFIG;
+ config.pseltxd = NRF_LOG_BACKEND_UART_TX_PIN;
+ config.pselrxd = NRF_UART_PSEL_DISCONNECTED;
+ config.pselcts = NRF_UART_PSEL_DISCONNECTED;
+ config.pselrts = NRF_UART_PSEL_DISCONNECTED;
+ config.baudrate = (nrf_uart_baudrate_t)NRF_LOG_BACKEND_UART_BAUDRATE;
+ ret_code_t err_code = nrf_drv_uart_init(&m_uart, &config, async_mode ? uart_evt_handler : NULL);
+ APP_ERROR_CHECK(err_code);
+
+ m_async_mode = async_mode;
+}
+
+void nrf_log_backend_uart_init(void)
+{
+ bool async_mode = NRF_LOG_DEFERRED ? true : false;
+ uart_init(async_mode);
+}
+
+static void serial_tx(void const * p_context, char const * p_buffer, size_t len)
+{
+ uint8_t len8 = (uint8_t)(len & 0x000000FF);
+ m_xfer_done = false;
+ ret_code_t err_code = nrf_drv_uart_tx(&m_uart, (uint8_t *)p_buffer, len8);
+ APP_ERROR_CHECK(err_code);
+ /* wait for completion since buffer is reused*/
+ while (m_async_mode && (m_xfer_done == false))
+ {
+
+ }
+
+}
+
+static void nrf_log_backend_uart_put(nrf_log_backend_t const * p_backend,
+ nrf_log_entry_t * p_msg)
+{
+ nrf_log_backend_serial_put(p_backend, p_msg, m_string_buff,
+ NRF_LOG_BACKEND_UART_TEMP_BUFFER_SIZE, serial_tx);
+}
+
+static void nrf_log_backend_uart_flush(nrf_log_backend_t const * p_backend)
+{
+
+}
+
+static void nrf_log_backend_uart_panic_set(nrf_log_backend_t const * p_backend)
+{
+ nrf_drv_uart_uninit(&m_uart);
+
+ uart_init(false);
+}
+
+const nrf_log_backend_api_t nrf_log_backend_uart_api = {
+ .put = nrf_log_backend_uart_put,
+ .flush = nrf_log_backend_uart_flush,
+ .panic_set = nrf_log_backend_uart_panic_set,
+};
+#endif //NRF_MODULE_ENABLED(NRF_LOG) && NRF_MODULE_ENABLED(NRF_LOG_BACKEND_UART)
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/experimental_log/src/nrf_log_ctrl_internal.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/experimental_log/src/nrf_log_ctrl_internal.h
new file mode 100644
index 0000000..ba8a574
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/experimental_log/src/nrf_log_ctrl_internal.h
@@ -0,0 +1,80 @@
+/**
+ * Copyright (c) 2016 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#ifndef NRF_LOG_CTRL_INTERNAL_H
+#define NRF_LOG_CTRL_INTERNAL_H
+/**
+ * @cond (NODOX)
+ * @defgroup nrf_log_ctrl_internal Auxiliary internal types declarations
+ * @{
+ * @internal
+ */
+
+#include "sdk_common.h"
+#if NRF_MODULE_ENABLED(NRF_LOG)
+#define NRF_LOG_INTERNAL_INIT(...) \
+ nrf_log_init(GET_VA_ARG_1(__VA_ARGS__), \
+ GET_VA_ARG_1(GET_ARGS_AFTER_1(__VA_ARGS__, NRF_LOG_TIMESTAMP_DEFAULT_FREQUENCY)))
+
+#define NRF_LOG_INTERNAL_PROCESS() nrf_log_frontend_dequeue()
+#define NRF_LOG_INTERNAL_FLUSH() \
+ do { \
+ while (NRF_LOG_INTERNAL_PROCESS()); \
+ } while (0)
+
+#define NRF_LOG_INTERNAL_FINAL_FLUSH() \
+ do { \
+ nrf_log_panic(); \
+ NRF_LOG_INTERNAL_FLUSH(); \
+ } while (0)
+
+
+#else // NRF_MODULE_ENABLED(NRF_LOG)
+#define NRF_LOG_INTERNAL_PROCESS() false
+#define NRF_LOG_INTERNAL_FLUSH()
+#define NRF_LOG_INTERNAL_INIT(timestamp_func) NRF_SUCCESS
+#define NRF_LOG_INTERNAL_HANDLERS_SET(default_handler, bytes_handler) \
+ UNUSED_PARAMETER(default_handler); UNUSED_PARAMETER(bytes_handler)
+#define NRF_LOG_INTERNAL_FINAL_FLUSH()
+#endif // NRF_MODULE_ENABLED(NRF_LOG)
+
+/** @}
+ * @endcond
+ */
+#endif // NRF_LOG_CTRL_INTERNAL_H
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/experimental_log/src/nrf_log_default_backends.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/experimental_log/src/nrf_log_default_backends.c
new file mode 100644
index 0000000..c844f2e
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/experimental_log/src/nrf_log_default_backends.c
@@ -0,0 +1,76 @@
+/**
+ * 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+
+#include "sdk_common.h"
+#if NRF_MODULE_ENABLED(NRF_LOG)
+#include "nrf_log_default_backends.h"
+#include "nrf_log_ctrl.h"
+#include "nrf_log_internal.h"
+#include "nrf_assert.h"
+
+#if defined(NRF_LOG_BACKEND_RTT_ENABLED) && NRF_LOG_BACKEND_RTT_ENABLED
+#include "nrf_log_backend_rtt.h"
+NRF_LOG_BACKEND_RTT_DEF(rtt_log_backend);
+#endif
+
+#if defined(NRF_LOG_BACKEND_UART_ENABLED) && NRF_LOG_BACKEND_UART_ENABLED
+#include "nrf_log_backend_uart.h"
+NRF_LOG_BACKEND_UART_DEF(uart_log_backend);
+#endif
+
+void nrf_log_default_backends_init(void)
+{
+ int32_t backend_id = -1;
+ (void)backend_id;
+#if defined(NRF_LOG_BACKEND_RTT_ENABLED) && NRF_LOG_BACKEND_RTT_ENABLED
+ nrf_log_backend_rtt_init();
+ backend_id = nrf_log_backend_add(&rtt_log_backend.backend, NRF_LOG_SEVERITY_DEBUG);
+ ASSERT(backend_id >= 0);
+ nrf_log_backend_enable(&rtt_log_backend.backend);
+#endif
+
+#if defined(NRF_LOG_BACKEND_UART_ENABLED) && NRF_LOG_BACKEND_UART_ENABLED
+ nrf_log_backend_uart_init();
+ backend_id = nrf_log_backend_add(&uart_log_backend.backend, NRF_LOG_SEVERITY_DEBUG);
+ ASSERT(backend_id >= 0);
+ nrf_log_backend_enable(&uart_log_backend.backend);
+#endif
+}
+#endif
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/experimental_log/src/nrf_log_frontend.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/experimental_log/src/nrf_log_frontend.c
new file mode 100644
index 0000000..4e65702
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/experimental_log/src/nrf_log_frontend.c
@@ -0,0 +1,1245 @@
+/**
+ * Copyright (c) 2016 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#include "sdk_common.h"
+#if NRF_MODULE_ENABLED(NRF_LOG)
+#include "app_util.h"
+#include "app_util_platform.h"
+#include "nrf_log.h"
+#include "nrf_log_internal.h"
+#include "nrf_log_ctrl.h"
+#include "nrf_log_str_formatter.h"
+#include "nrf_section.h"
+#include "nrf_memobj.h"
+#include "nrf_atomic.h"
+#include <string.h>
+
+STATIC_ASSERT((NRF_LOG_BUFSIZE % 4) == 0);
+STATIC_ASSERT(IS_POWER_OF_TWO(NRF_LOG_BUFSIZE));
+
+#define NRF_LOG_BUF_WORDS (NRF_LOG_BUFSIZE/4)
+
+#if NRF_LOG_BUF_WORDS < 32
+#warning "NRF_LOG_BUFSIZE too small, significant number of logs may be lost."
+#endif
+
+NRF_MEMOBJ_POOL_DEF(log_mempool, NRF_LOG_MSGPOOL_ELEMENT_SIZE, NRF_LOG_MSGPOOL_ELEMENT_COUNT);
+
+#define NRF_LOG_BACKENDS_FULL 0xFF
+#define NRF_LOG_FILTER_BITS_PER_BACKEND 3
+#define NRF_LOG_MAX_BACKENDS (32/NRF_LOG_FILTER_BITS_PER_BACKEND)
+#define NRF_LOG_MAX_HEXDUMP (NRF_LOG_MSGPOOL_ELEMENT_SIZE*NRF_LOG_MSGPOOL_ELEMENT_COUNT/2)
+
+/**
+ * brief An internal control block of the logger
+ *
+ * @note Circular buffer is using never cleared indexes and a mask. It means
+ * that logger may break when indexes overflows. However, it is quite unlikely.
+ * With rate of 1000 log entries with 2 parameters per second such situation
+ * would happen after 12 days.
+ */
+typedef struct
+{
+ uint32_t wr_idx; // Current write index (never reset)
+ uint32_t rd_idx; // Current read index (never_reset)
+ uint32_t mask; // Size of buffer (must be power of 2) presented as mask
+ uint32_t buffer[NRF_LOG_BUF_WORDS];
+ nrf_log_timestamp_func_t timestamp_func; // A pointer to function that returns timestamp
+ nrf_log_backend_t * p_backend_head;
+ nrf_atomic_flag_t log_skipping;
+ nrf_atomic_flag_t log_skipped;
+ nrf_atomic_u32_t log_dropped_cnt;
+ bool autoflush;
+} log_data_t;
+
+static log_data_t m_log_data;
+
+/*lint -save -esym(526,log_const_data*) -esym(526,log_dynamic_data*)*/
+NRF_SECTION_DEF(log_dynamic_data, NRF_LOG_DYNAMIC_STRUCT_NAME);
+NRF_SECTION_DEF(log_const_data, nrf_log_module_const_data_t);
+/*lint -restore*/
+NRF_LOG_MODULE_REGISTER();
+// Helper macros for section variables.
+#define NRF_LOG_DYNAMIC_SECTION_VARS_GET(i) NRF_SECTION_ITEM_GET(log_dynamic_data, NRF_LOG_DYNAMIC_STRUCT_NAME, (i))
+
+#define NRF_LOG_CONST_SECTION_VARS_GET(i) NRF_SECTION_ITEM_GET(log_const_data, nrf_log_module_const_data_t, (i))
+#define NRF_LOG_CONST_SECTION_VARS_COUNT NRF_SECTION_ITEM_COUNT(log_const_data, nrf_log_module_const_data_t)
+
+#define PUSHED_HEADER_FILL(P_HDR, OFFSET, LENGTH) \
+ (P_HDR)->base.raw = 0; \
+ (P_HDR)->base.pushed.type = HEADER_TYPE_PUSHED; \
+ (P_HDR)->base.pushed.offset = OFFSET; \
+ (P_HDR)->base.pushed.len = LENGTH
+
+
+ret_code_t nrf_log_init(nrf_log_timestamp_func_t timestamp_func, uint32_t timestamp_freq)
+{
+ if (NRF_LOG_USES_TIMESTAMP && (timestamp_func == NULL))
+ {
+ return NRF_ERROR_INVALID_PARAM;
+ }
+
+ m_log_data.mask = NRF_LOG_BUF_WORDS - 1;
+ m_log_data.wr_idx = 0;
+ m_log_data.rd_idx = 0;
+ m_log_data.log_skipped = 0;
+ m_log_data.log_skipping = 0;
+ m_log_data.autoflush = NRF_LOG_DEFERRED ? false : true;
+ if (NRF_LOG_USES_TIMESTAMP)
+ {
+ nrf_log_str_formatter_timestamp_freq_set(timestamp_freq);
+ m_log_data.timestamp_func = timestamp_func;
+ }
+
+ ret_code_t err_code = nrf_memobj_pool_init(&log_mempool);
+ if (err_code != NRF_SUCCESS)
+ {
+ return err_code;
+ }
+
+ uint32_t modules_cnt = NRF_LOG_CONST_SECTION_VARS_COUNT;
+ uint32_t i;
+ if (NRF_LOG_FILTERS_ENABLED)
+ {
+ uint32_t j;
+ //sort modules by name
+ for (i = 0; i < modules_cnt; i++)
+ {
+ uint32_t idx = 0;
+
+ for (j = 0; j < modules_cnt; j++)
+ {
+ if (i != j)
+ {
+ char const * p_name0 = NRF_LOG_CONST_SECTION_VARS_GET(i)->p_module_name;
+ char const * p_name1 = NRF_LOG_CONST_SECTION_VARS_GET(j)->p_module_name;
+ if (strncmp(p_name0, p_name1, 20) > 0)
+ {
+ idx++;
+ }
+ }
+
+ }
+ nrf_log_module_dynamic_data_t * p_module_ddata =
+ (nrf_log_module_dynamic_data_t *)NRF_LOG_DYNAMIC_SECTION_VARS_GET(i);
+ p_module_ddata->filter = 0;
+ p_module_ddata->module_id = i;
+ p_module_ddata->order_idx = idx;
+ }
+ }
+ else
+ {
+ for(i = 0; i < modules_cnt; i++)
+ {
+ nrf_log_module_reduced_dynamic_data_t * p_module_ddata =
+ (nrf_log_module_reduced_dynamic_data_t *)NRF_LOG_DYNAMIC_SECTION_VARS_GET(i);
+ p_module_ddata->module_id = i;
+ }
+ }
+
+ return NRF_SUCCESS;
+}
+
+uint32_t nrf_log_module_cnt_get(void)
+{
+ return NRF_LOG_CONST_SECTION_VARS_COUNT;
+}
+
+static ret_code_t module_idx_get(uint32_t * p_idx, bool ordered_idx)
+{
+ if (ordered_idx)
+ {
+ uint32_t module_cnt = nrf_log_module_cnt_get();
+ uint32_t i;
+ for (i = 0; i < module_cnt; i++)
+ {
+ nrf_log_module_dynamic_data_t * p_module_data =
+ (nrf_log_module_dynamic_data_t *)NRF_LOG_DYNAMIC_SECTION_VARS_GET(i);
+ if (p_module_data->order_idx == *p_idx)
+ {
+ *p_idx = i;
+ return NRF_SUCCESS;
+ }
+ }
+ return NRF_ERROR_NOT_FOUND;
+ }
+ else
+ {
+ return NRF_SUCCESS;
+ }
+}
+const char * nrf_log_module_name_get(uint32_t module_id, bool ordered_idx)
+{
+ if (module_idx_get(&module_id, ordered_idx) == NRF_SUCCESS)
+ {
+ nrf_log_module_const_data_t * p_module_data = NRF_LOG_CONST_SECTION_VARS_GET(module_id);
+ return p_module_data->p_module_name;
+ }
+ else
+ {
+ return NULL;
+ }
+}
+
+uint8_t nrf_log_color_id_get(uint32_t module_id, nrf_log_severity_t severity)
+{
+ nrf_log_module_const_data_t * p_module_data = NRF_LOG_CONST_SECTION_VARS_GET(module_id);
+ uint8_t color_id;
+ switch (severity)
+ {
+ case NRF_LOG_SEVERITY_ERROR:
+ color_id = NRF_LOG_ERROR_COLOR;
+ break;
+ case NRF_LOG_SEVERITY_WARNING:
+ color_id = NRF_LOG_WARNING_COLOR;
+ break;
+ case NRF_LOG_SEVERITY_INFO:
+ color_id = p_module_data->info_color_id;
+ break;
+ case NRF_LOG_SEVERITY_DEBUG:
+ color_id = p_module_data->debug_color_id;
+ break;
+ default:
+ color_id = 0;
+ break;
+ }
+ return color_id;
+}
+
+static uint32_t higher_lvl_get(uint32_t lvls)
+{
+ uint32_t top_lvl = 0;
+ uint32_t tmp_lvl;
+ uint32_t i;
+
+ //Find highest level enabled by backends
+ for (i = 0; i < (32/NRF_LOG_LEVEL_BITS); i+=NRF_LOG_LEVEL_BITS)
+ {
+ tmp_lvl = BF_GET(lvls,NRF_LOG_LEVEL_BITS, i);
+ if (tmp_lvl > top_lvl)
+ {
+ top_lvl = tmp_lvl;
+ }
+ }
+ return top_lvl;
+}
+
+void nrf_log_module_filter_set(uint32_t backend_id, uint32_t module_id, nrf_log_severity_t severity)
+{
+ if (NRF_LOG_FILTERS_ENABLED)
+ {
+ nrf_log_module_dynamic_data_t * p_module_filter =
+ (nrf_log_module_dynamic_data_t *)NRF_LOG_DYNAMIC_SECTION_VARS_GET(module_id);
+ p_module_filter->filter_lvls &= ~(NRF_LOG_LEVEL_MASK << (NRF_LOG_LEVEL_BITS * backend_id));
+ p_module_filter->filter_lvls |= (severity & NRF_LOG_LEVEL_MASK) << (NRF_LOG_LEVEL_BITS * backend_id);
+ p_module_filter->filter = higher_lvl_get(p_module_filter->filter_lvls);
+ }
+}
+
+static nrf_log_severity_t nrf_log_module_init_filter_get(uint32_t module_id)
+{
+ nrf_log_module_const_data_t * p_module_data =
+ NRF_LOG_CONST_SECTION_VARS_GET(module_id);
+ return NRF_LOG_FILTERS_ENABLED ? p_module_data->initial_lvl : p_module_data->compiled_lvl;
+}
+
+nrf_log_severity_t nrf_log_module_filter_get(uint32_t backend_id,
+ uint32_t module_id,
+ bool ordered_idx,
+ bool dynamic)
+{
+ nrf_log_severity_t severity = NRF_LOG_SEVERITY_NONE;
+ if (NRF_LOG_FILTERS_ENABLED && dynamic)
+ {
+ if (module_idx_get(&module_id, ordered_idx) == NRF_SUCCESS)
+ {
+ nrf_log_module_dynamic_data_t * p_module_filter =
+ (nrf_log_module_dynamic_data_t *)NRF_LOG_DYNAMIC_SECTION_VARS_GET(module_id);
+ severity = (nrf_log_severity_t)((p_module_filter->filter_lvls >> (NRF_LOG_LEVEL_BITS * backend_id)) &
+ NRF_LOG_LEVEL_MASK);
+ }
+ }
+ else if (!dynamic)
+ {
+ if (module_idx_get(&module_id, ordered_idx) == NRF_SUCCESS)
+ {
+ nrf_log_module_const_data_t * p_module_data =
+ NRF_LOG_CONST_SECTION_VARS_GET(module_id);
+ severity = (nrf_log_severity_t)p_module_data->compiled_lvl;
+ }
+ }
+ return severity;
+}
+/**
+ * Function examines current header and omits pushed strings and packets which are in progress.
+ */
+static bool invalid_packets_pushed_str_omit(nrf_log_header_t const * p_header, uint32_t * p_rd_idx)
+{
+ bool ret = false;
+ if ((p_header->base.generic.type == HEADER_TYPE_PUSHED) || (p_header->base.generic.in_progress == 1))
+ {
+ if (p_header->base.generic.in_progress == 1)
+ {
+ switch (p_header->base.generic.type)
+ {
+ case HEADER_TYPE_STD:
+ *p_rd_idx += (HEADER_SIZE + p_header->base.std.nargs);
+ break;
+ case HEADER_TYPE_HEXDUMP:
+ *p_rd_idx += (HEADER_SIZE + p_header->base.hexdump.len);
+ break;
+ default:
+ ASSERT(0);
+ break;
+ }
+ }
+ else
+ {
+ *p_rd_idx +=
+ (PUSHED_HEADER_SIZE + p_header->base.pushed.len + p_header->base.pushed.offset);
+ }
+ ret = true;
+ }
+ return ret;
+}
+/**
+ * @brief Skips the oldest, not pushed logs to make space for new logs.
+ * @details This function moves forward read index to prepare space for new logs.
+ */
+
+static uint32_t log_skip(void)
+{
+ uint16_t dropped = 0;
+
+ (void)nrf_atomic_flag_set(&m_log_data.log_skipped);
+ (void)nrf_atomic_flag_set(&m_log_data.log_skipping);
+
+ uint32_t rd_idx = m_log_data.rd_idx;
+ uint32_t mask = m_log_data.mask;
+ nrf_log_header_t * p_header = (nrf_log_header_t *)&m_log_data.buffer[rd_idx & mask];
+ nrf_log_header_t header;
+
+ // Skip any string that is pushed to the circular buffer.
+ do {
+ if (invalid_packets_pushed_str_omit(p_header, &rd_idx))
+ {
+ //something was omitted. Point to new header and try again.
+ p_header = (nrf_log_header_t *)&m_log_data.buffer[rd_idx & mask];
+ }
+ else
+ {
+ break;
+ }
+ } while (true);
+
+ uint32_t i;
+ for (i = 0; i < HEADER_SIZE; i++)
+ {
+ ((uint32_t*)&header)[i] = m_log_data.buffer[rd_idx++ & mask];
+ }
+
+ switch (header.base.generic.type)
+ {
+ case HEADER_TYPE_HEXDUMP:
+ dropped = header.dropped;
+ rd_idx += CEIL_DIV(header.base.hexdump.len, sizeof(uint32_t));
+ break;
+ case HEADER_TYPE_STD:
+ dropped = header.dropped;
+ rd_idx += header.base.std.nargs;
+ break;
+ default:
+ ASSERT(false);
+ break;
+ }
+
+ uint32_t log_skipping_tmp = nrf_atomic_flag_clear_fetch(&m_log_data.log_skipping);
+ //update read index only if log_skip was not interrupted by another log skip
+ if (log_skipping_tmp)
+ {
+ m_log_data.rd_idx = rd_idx;
+ }
+
+ return (uint32_t)dropped;
+}
+
+/**
+ * @brief Function for getting number of dropped logs. Dropped counter is reset after reading.
+ *
+ * @return Number of dropped logs saturated to 16 bits.
+ */
+static inline uint32_t dropped_sat16_get(void)
+{
+ uint32_t dropped = nrf_atomic_u32_fetch_store(&m_log_data.log_dropped_cnt, 0);
+ return __USAT(dropped, 16); //Saturate to 16 bits
+}
+
+
+static inline void std_header_set(uint32_t severity_mid,
+ char const * const p_str,
+ uint32_t nargs,
+ uint32_t wr_idx,
+ uint32_t mask)
+{
+
+
+ //Prepare header - in reverse order to ensure that packet type is validated (set to STD as last action)
+ uint32_t module_id = severity_mid >> NRF_LOG_MODULE_ID_POS;
+ uint32_t dropped = dropped_sat16_get();
+ ASSERT(module_id < nrf_log_module_cnt_get());
+ m_log_data.buffer[(wr_idx + 1) & mask] = module_id | (dropped << 16);
+
+ if (NRF_LOG_USES_TIMESTAMP)
+ {
+ m_log_data.buffer[(wr_idx + 2) & mask] = m_log_data.timestamp_func();
+ }
+
+ nrf_log_header_t * p_header = (nrf_log_header_t *)&m_log_data.buffer[wr_idx & mask];
+ p_header->base.std.severity = severity_mid & NRF_LOG_LEVEL_MASK;
+ p_header->base.std.nargs = nargs;
+ p_header->base.std.addr = ((uint32_t)(p_str) & STD_ADDR_MASK);
+ p_header->base.std.type = HEADER_TYPE_STD;
+ p_header->base.std.in_progress = 0;
+}
+
+/**
+ * @brief Allocates chunk in a buffer for one entry and injects overflow if
+ * there is no room for requested entry.
+ *
+ * @param content_len Number of 32bit arguments. In case of allocating for hex dump it
+ * is the size of the buffer in 32bit words (ceiled).
+ * @param p_wr_idx Pointer to write index.
+ *
+ * @return True if successful allocation, false otherwise.
+ *
+ */
+static inline bool buf_prealloc(uint32_t content_len, uint32_t * p_wr_idx, bool std)
+{
+ uint32_t req_len = content_len + HEADER_SIZE;
+ bool ret = true;
+ CRITICAL_REGION_ENTER();
+ *p_wr_idx = m_log_data.wr_idx;
+ uint32_t available_words = (m_log_data.mask + 1) - (m_log_data.wr_idx - m_log_data.rd_idx);
+ while (req_len > available_words)
+ {
+ UNUSED_RETURN_VALUE(nrf_atomic_u32_add(&m_log_data.log_dropped_cnt, 1));
+ if (NRF_LOG_ALLOW_OVERFLOW)
+ {
+ uint32_t dropped_in_skip = log_skip();
+ UNUSED_RETURN_VALUE(nrf_atomic_u32_add(&m_log_data.log_dropped_cnt, dropped_in_skip));
+ available_words = (m_log_data.mask + 1) - (m_log_data.wr_idx - m_log_data.rd_idx);
+ }
+ else
+ {
+ ret = false;
+ break;
+ }
+ }
+
+ if (ret)
+ {
+ nrf_log_main_header_t invalid_header;
+ invalid_header.raw = 0;
+
+ if (std)
+ {
+ invalid_header.std.type = HEADER_TYPE_STD;
+ invalid_header.std.in_progress = 1;
+ invalid_header.std.nargs = content_len;
+ }
+ else
+ {
+ invalid_header.hexdump.type = HEADER_TYPE_HEXDUMP;
+ invalid_header.hexdump.in_progress = 1;
+ invalid_header.hexdump.len = content_len;
+ }
+
+ nrf_log_main_header_t * p_header = (nrf_log_main_header_t *)&m_log_data.buffer[m_log_data.wr_idx & m_log_data.mask];
+
+ p_header->raw = invalid_header.raw;
+
+ m_log_data.wr_idx += req_len;
+ }
+
+ CRITICAL_REGION_EXIT();
+ return ret;
+}
+
+
+/**
+ * @brief Function for preallocating a continuous chunk of memory from circular buffer.
+ *
+ * If buffer does not fit starting from current position it will be allocated at
+ * the beginning of the circular buffer and offset will be returned indicating
+ * how much memory has been ommited at the end of the buffer. Function is
+ * using critical section.
+ *
+ * @param len32 Length of buffer to allocate. Given in words.
+ * @param p_offset Offset of the buffer.
+ * @param p_wr_idx Pointer to write index.
+ *
+ * @return A pointer to the allocated buffer. NULL if allocation failed.
+ */
+static inline uint32_t * cont_buf_prealloc(uint32_t len32,
+ uint32_t * p_offset,
+ uint32_t * p_wr_idx)
+{
+ //allocation algorithm relies on that assumption
+ STATIC_ASSERT(PUSHED_HEADER_SIZE == 1);
+ uint32_t * p_buf = NULL;
+
+ len32 += PUSHED_HEADER_SIZE; // Increment because 32bit header is needed to be stored.
+
+ CRITICAL_REGION_ENTER();
+ *p_wr_idx = m_log_data.wr_idx;
+ uint32_t available_words = (m_log_data.mask + 1) -
+ (m_log_data.wr_idx - m_log_data.rd_idx);
+ uint32_t tail_words = (m_log_data.mask + 1) - (m_log_data.wr_idx & m_log_data.mask);
+
+ //available space is continuous
+ uint32_t curr_pos_available = (available_words <= tail_words) ? available_words : tail_words;
+ uint32_t start_pos_available = (available_words <= tail_words) ? 0 : (available_words - tail_words);
+
+ if ((len32 <= curr_pos_available) ||
+ ((len32 - PUSHED_HEADER_SIZE) <= start_pos_available))
+ {
+ // buffer will fit in the tail or in the begining
+ // non zero offset is set if string is put at the beginning of the buffer
+ *p_offset = (len32 <= curr_pos_available) ? 0 : (tail_words - PUSHED_HEADER_SIZE);
+ uint32_t str_start_idx =
+ (m_log_data.wr_idx + PUSHED_HEADER_SIZE + *p_offset) & m_log_data.mask;
+ p_buf = &m_log_data.buffer[str_start_idx];
+ // index is incremented by payload and offset
+ m_log_data.wr_idx += (len32 + *p_offset);
+ }
+
+ CRITICAL_REGION_EXIT();
+
+ return p_buf;
+}
+
+
+uint32_t nrf_log_push(char * const p_str)
+{
+ if ((m_log_data.autoflush) || (p_str == NULL))
+ {
+ return (uint32_t)p_str;
+ }
+
+ uint32_t mask = m_log_data.mask;
+ uint32_t slen = strlen(p_str) + 1;
+ uint32_t buflen = CEIL_DIV(slen, sizeof(uint32_t));
+ uint32_t offset = 0;
+ uint32_t wr_idx;
+ char * p_dst_str = (char *)cont_buf_prealloc(buflen, &offset, &wr_idx);
+ if (p_dst_str)
+ {
+ nrf_log_header_t * p_header = (nrf_log_header_t *)&m_log_data.buffer[wr_idx & mask];
+ PUSHED_HEADER_FILL(p_header, offset, buflen);
+ memcpy(p_dst_str, p_str, slen);
+ }
+ return (uint32_t)p_dst_str;
+}
+
+static inline void std_n(uint32_t severity_mid, char const * const p_str, uint32_t const * args, uint32_t nargs)
+{
+ uint32_t mask = m_log_data.mask;
+ uint32_t wr_idx;
+
+ if (buf_prealloc(nargs, &wr_idx, true))
+ {
+ // Proceed only if buffer was successfully preallocated.
+
+ uint32_t data_idx = wr_idx + HEADER_SIZE;
+ uint32_t i;
+ for (i = 0; i < nargs; i++)
+ {
+ m_log_data.buffer[data_idx++ & mask] =args[i];
+ }
+ std_header_set(severity_mid, p_str, nargs, wr_idx, mask);
+ }
+ if (m_log_data.autoflush)
+ {
+ NRF_LOG_FLUSH();
+ }
+
+}
+
+void nrf_log_frontend_std_0(uint32_t severity_mid, char const * const p_str)
+{
+ std_n(severity_mid, p_str, NULL, 0);
+}
+
+
+void nrf_log_frontend_std_1(uint32_t severity_mid,
+ char const * const p_str,
+ uint32_t val0)
+{
+ uint32_t args[] = {val0};
+ std_n(severity_mid, p_str, args, ARRAY_SIZE(args));
+}
+
+
+void nrf_log_frontend_std_2(uint32_t severity_mid,
+ char const * const p_str,
+ uint32_t val0,
+ uint32_t val1)
+{
+ uint32_t args[] = {val0, val1};
+ std_n(severity_mid, p_str, args, ARRAY_SIZE(args));
+}
+
+
+void nrf_log_frontend_std_3(uint32_t severity_mid,
+ char const * const p_str,
+ uint32_t val0,
+ uint32_t val1,
+ uint32_t val2)
+{
+ uint32_t args[] = {val0, val1, val2};
+ std_n(severity_mid, p_str, args, ARRAY_SIZE(args));
+}
+
+
+void nrf_log_frontend_std_4(uint32_t severity_mid,
+ char const * const p_str,
+ uint32_t val0,
+ uint32_t val1,
+ uint32_t val2,
+ uint32_t val3)
+{
+ uint32_t args[] = {val0, val1, val2, val3};
+ std_n(severity_mid, p_str, args, ARRAY_SIZE(args));
+}
+
+
+void nrf_log_frontend_std_5(uint32_t severity_mid,
+ char const * const p_str,
+ uint32_t val0,
+ uint32_t val1,
+ uint32_t val2,
+ uint32_t val3,
+ uint32_t val4)
+{
+ uint32_t args[] = {val0, val1, val2, val3, val4};
+ std_n(severity_mid, p_str, args, ARRAY_SIZE(args));
+}
+
+
+void nrf_log_frontend_std_6(uint32_t severity_mid,
+ char const * const p_str,
+ uint32_t val0,
+ uint32_t val1,
+ uint32_t val2,
+ uint32_t val3,
+ uint32_t val4,
+ uint32_t val5)
+{
+ uint32_t args[] = {val0, val1, val2, val3, val4, val5};
+ std_n(severity_mid, p_str, args, ARRAY_SIZE(args));
+}
+
+
+void nrf_log_frontend_hexdump(uint32_t severity_mid,
+ const void * const p_data,
+ uint16_t length)
+{
+ uint32_t mask = m_log_data.mask;
+
+ uint32_t wr_idx;
+ if (buf_prealloc(CEIL_DIV(length, sizeof(uint32_t)), &wr_idx, false))
+ {
+ uint32_t header_wr_idx = wr_idx;
+ wr_idx += HEADER_SIZE;
+
+ uint32_t space0 = sizeof(uint32_t) * (m_log_data.mask + 1 - (wr_idx & mask));
+ if (length <= space0)
+ {
+ memcpy(&m_log_data.buffer[wr_idx & mask], p_data, length);
+ }
+ else
+ {
+ memcpy(&m_log_data.buffer[wr_idx & mask], p_data, space0);
+ memcpy(&m_log_data.buffer[0], &((uint8_t *)p_data)[space0], length - space0);
+ }
+
+ //Prepare header - in reverse order to ensure that packet type is validated (set to HEXDUMP as last action)
+ if (NRF_LOG_USES_TIMESTAMP)
+ {
+ m_log_data.buffer[(header_wr_idx + 2) & mask] = m_log_data.timestamp_func();
+ }
+
+ uint32_t module_id = severity_mid >> NRF_LOG_MODULE_ID_POS;
+ uint32_t dropped = dropped_sat16_get();
+ m_log_data.buffer[(header_wr_idx + 1) & mask] = module_id | (dropped << 16);
+ //Header prepare
+ nrf_log_header_t * p_header = (nrf_log_header_t *)&m_log_data.buffer[header_wr_idx & mask];
+ p_header->base.hexdump.severity = severity_mid & NRF_LOG_LEVEL_MASK;
+ p_header->base.hexdump.offset = 0;
+ p_header->base.hexdump.len = length;
+ p_header->base.hexdump.type = HEADER_TYPE_HEXDUMP;
+ p_header->base.hexdump.in_progress = 0;
+
+
+
+ }
+
+ if (m_log_data.autoflush)
+ {
+ NRF_LOG_FLUSH();
+ }
+}
+
+
+bool buffer_is_empty(void)
+{
+ return (m_log_data.rd_idx == m_log_data.wr_idx);
+}
+
+bool nrf_log_frontend_dequeue(void)
+{
+
+ if (buffer_is_empty())
+ {
+ return false;
+ }
+ m_log_data.log_skipped = 0;
+ //It has to be ensured that reading rd_idx occurs after skipped flag is cleared.
+ __DSB();
+ uint32_t rd_idx = m_log_data.rd_idx;
+ uint32_t mask = m_log_data.mask;
+ nrf_log_header_t * p_header = (nrf_log_header_t *)&m_log_data.buffer[rd_idx & mask];
+ nrf_log_header_t header;
+ nrf_memobj_t * p_msg_buf = NULL;
+ uint32_t memobj_offset = 0;
+ uint32_t severity = 0;
+
+ // Skip any string that is pushed to the circular buffer.
+ do {
+ if (invalid_packets_pushed_str_omit(p_header, &rd_idx))
+ {
+ //Check if end of data is not reached.
+ if (rd_idx >= m_log_data.wr_idx)
+ {
+ m_log_data.rd_idx = m_log_data.wr_idx;
+ return false;
+ }
+ //something was omitted. Point to new header and try again.
+ p_header = (nrf_log_header_t *)&m_log_data.buffer[rd_idx & mask];
+ }
+ else
+ {
+ break;
+ }
+ } while (true);
+
+ uint32_t i;
+ for (i = 0; i < HEADER_SIZE; i++)
+ {
+ ((uint32_t*)&header)[i] = m_log_data.buffer[rd_idx++ & mask];
+ }
+
+ if (header.base.generic.type == HEADER_TYPE_HEXDUMP)
+ {
+ uint32_t orig_data_len = header.base.hexdump.len;
+ uint32_t data_len = MIN(header.base.hexdump.len, NRF_LOG_MAX_HEXDUMP); //limit the data
+ header.base.hexdump.len = data_len;
+ uint32_t msg_buf_size8 = sizeof(uint32_t)*HEADER_SIZE + data_len;
+ severity = header.base.hexdump.severity;
+ p_msg_buf = nrf_memobj_alloc(&log_mempool, msg_buf_size8);
+
+ if (p_msg_buf)
+ {
+ nrf_memobj_get(p_msg_buf);
+ nrf_memobj_write(p_msg_buf, &header, HEADER_SIZE*sizeof(uint32_t), memobj_offset);
+ memobj_offset += HEADER_SIZE*sizeof(uint32_t);
+
+ uint32_t space0 = sizeof(uint32_t) * (mask + 1 - (rd_idx & mask));
+ if (data_len > space0)
+ {
+ uint8_t * ptr0 = space0 ?
+ (uint8_t *)&m_log_data.buffer[rd_idx & mask] :
+ (uint8_t *)&m_log_data.buffer[0];
+ uint8_t len0 = space0 ? space0 : data_len;
+ uint8_t * ptr1 = space0 ?
+ (uint8_t *)&m_log_data.buffer[0] : NULL;
+ uint8_t len1 = space0 ? data_len - space0 : 0;
+
+ nrf_memobj_write(p_msg_buf, ptr0, len0, memobj_offset);
+ memobj_offset += len0;
+ if (ptr1)
+ {
+ nrf_memobj_write(p_msg_buf, ptr1, len1, memobj_offset);
+ }
+ }
+ else
+ {
+ uint8_t * p_data = (uint8_t *)&m_log_data.buffer[rd_idx & mask];
+ nrf_memobj_write(p_msg_buf, p_data, data_len, memobj_offset);
+ }
+ rd_idx += CEIL_DIV(orig_data_len, 4);
+ }
+ }
+ else if (header.base.generic.type == HEADER_TYPE_STD) // standard entry
+ {
+ header.base.std.nargs = MIN(header.base.std.nargs, NRF_LOG_MAX_NUM_OF_ARGS);
+ uint32_t msg_buf_size32 = HEADER_SIZE + header.base.std.nargs;
+ severity = header.base.std.severity;
+
+ p_msg_buf = nrf_memobj_alloc(&log_mempool, msg_buf_size32*sizeof(uint32_t));
+
+ if (p_msg_buf)
+ {
+ nrf_memobj_get(p_msg_buf);
+ nrf_memobj_write(p_msg_buf, &header, HEADER_SIZE*sizeof(uint32_t), memobj_offset);
+ memobj_offset += HEADER_SIZE*sizeof(uint32_t);
+
+ for (i = 0; i < header.base.std.nargs; i++)
+ {
+ nrf_memobj_write(p_msg_buf, &m_log_data.buffer[rd_idx++ & mask],
+ sizeof(uint32_t), memobj_offset);
+ memobj_offset += sizeof(uint32_t);
+ }
+ }
+ }
+ else
+ {
+ //Do nothing. In case of log overflow buffer can contain corrupted data.
+ }
+
+ if (p_msg_buf)
+ {
+ nrf_log_backend_t * p_backend = m_log_data.p_backend_head;
+ if (NRF_LOG_ALLOW_OVERFLOW && m_log_data.log_skipped)
+ {
+ // Check if any log was skipped during log processing. Do not forward log if skipping
+ // occured because data may be invalid.
+ nrf_memobj_put(p_msg_buf);
+ }
+ else
+ {
+ while (p_backend)
+ {
+ bool entry_accepted = false;
+ if (nrf_log_backend_is_enabled(p_backend) == true)
+ {
+ if (NRF_LOG_FILTERS_ENABLED)
+ {
+ uint8_t backend_id = nrf_log_backend_id_get(p_backend);
+ nrf_log_module_dynamic_data_t * p_module_filter =
+ (nrf_log_module_dynamic_data_t *)NRF_LOG_DYNAMIC_SECTION_VARS_GET(header.module_id);
+ uint32_t filter_lvls = p_module_filter->filter_lvls;
+ uint32_t backend_lvl = (filter_lvls >> (backend_id*NRF_LOG_LEVEL_BITS))
+ & NRF_LOG_LEVEL_MASK;
+ //Degrade INFO_RAW level to INFO.
+ severity = (severity == NRF_LOG_SEVERITY_INFO_RAW) ? NRF_LOG_SEVERITY_INFO : severity;
+ if (backend_lvl >= severity)
+ {
+ entry_accepted = true;
+ }
+ }
+ else
+ {
+ (void)severity;
+ entry_accepted = true;
+ }
+ }
+ if (entry_accepted)
+ {
+ nrf_log_backend_put(p_backend, p_msg_buf);
+ }
+ p_backend = p_backend->p_next;
+ }
+
+ nrf_memobj_put(p_msg_buf);
+
+ if (NRF_LOG_ALLOW_OVERFLOW)
+ {
+ // Read index can be moved forward only if dequeueing process was not interrupt by
+ // skipping procedure. If NRF_LOG_ALLOW_OVERFLOW is set then in case of buffer gets full
+ // and new logger entry occurs, oldest entry is removed. In that case read index is
+ // changed and updating it here would corrupt the internal circular buffer.
+ CRITICAL_REGION_ENTER();
+ if (m_log_data.log_skipped == 0)
+ {
+ m_log_data.rd_idx = rd_idx;
+ }
+ CRITICAL_REGION_EXIT();
+ }
+ else
+ {
+ m_log_data.rd_idx = rd_idx;
+ }
+ }
+ }
+ else
+ {
+ //Could not allocate memobj - backends are not freeing them on time.
+ nrf_log_backend_t * p_backend = m_log_data.p_backend_head;
+ //Flush all backends
+ while (p_backend)
+ {
+ nrf_log_backend_flush(p_backend);
+ p_backend = p_backend->p_next;
+ }
+ NRF_LOG_WARNING("Backends flushed");
+ }
+
+ return buffer_is_empty() ? false : true;
+}
+
+static int32_t backend_id_assign(void)
+{
+ int32_t candidate_id;
+ nrf_log_backend_t * p_backend;
+ bool id_available;
+ for (candidate_id = 0; candidate_id < NRF_LOG_MAX_BACKENDS; candidate_id++)
+ {
+ p_backend = m_log_data.p_backend_head;
+ id_available = true;
+ while (p_backend)
+ {
+ if (nrf_log_backend_id_get(p_backend) == candidate_id)
+ {
+ id_available = false;
+ break;
+ }
+ p_backend = p_backend->p_next;
+ }
+ if (id_available)
+ {
+ return candidate_id;
+ }
+ }
+ return -1;
+}
+
+int32_t nrf_log_backend_add(nrf_log_backend_t * p_backend, nrf_log_severity_t severity)
+{
+ int32_t id = backend_id_assign();
+ if (id == -1)
+ {
+ return id;
+ }
+
+ nrf_log_backend_id_set(p_backend, id);
+ //add to list
+ if (m_log_data.p_backend_head == NULL)
+ {
+ m_log_data.p_backend_head = p_backend;
+ p_backend->p_next = NULL;
+ }
+ else
+ {
+ p_backend->p_next = m_log_data.p_backend_head->p_next;
+ m_log_data.p_backend_head->p_next = p_backend;
+ }
+
+ if (NRF_LOG_FILTERS_ENABLED)
+ {
+ uint32_t i;
+ for (i = 0; i < nrf_log_module_cnt_get(); i++)
+ {
+ nrf_log_severity_t buildin_lvl = nrf_log_module_init_filter_get(i);
+ nrf_log_severity_t actual_severity = MIN(buildin_lvl, severity);
+ nrf_log_module_filter_set(nrf_log_backend_id_get(p_backend), i, actual_severity);
+ }
+ }
+
+ return id;
+}
+
+void nrf_log_backend_remove(nrf_log_backend_t * p_backend)
+{
+ nrf_log_backend_t * p_curr = m_log_data.p_backend_head;
+ nrf_log_backend_t * p_prev = NULL;
+ while (p_curr != p_backend)
+ {
+ p_prev = p_curr;
+ p_curr = p_curr->p_next;
+ }
+
+ if (p_prev)
+ {
+ p_prev->p_next = p_backend->p_next;
+ }
+ else
+ {
+ m_log_data.p_backend_head = NULL;
+ }
+}
+
+void nrf_log_panic(void)
+{
+ nrf_log_backend_t * p_backend = m_log_data.p_backend_head;
+ m_log_data.autoflush = true;
+ while (p_backend)
+ {
+ nrf_log_backend_enable(p_backend);
+ nrf_log_backend_panic_set(p_backend);
+ p_backend = p_backend->p_next;
+ }
+}
+
+#if NRF_LOG_CLI_CMDS
+#include "nrf_cli.h"
+
+static const char * m_severity_lvls[] = {
+ "none",
+ "error",
+ "warning",
+ "info",
+ "debug",
+};
+
+static const char * m_severity_lvls_sorted[] = {
+ "debug",
+ "error",
+ "info",
+ "none",
+ "warning",
+};
+
+static void log_status(nrf_cli_t const * p_cli, size_t argc, char **argv)
+{
+ uint32_t modules_cnt = nrf_log_module_cnt_get();
+ uint32_t backend_id = p_cli->p_log_backend->backend.id;
+ uint32_t i;
+
+ if (!nrf_log_backend_is_enabled(&p_cli->p_log_backend->backend))
+ {
+ nrf_cli_fprintf(p_cli, NRF_CLI_ERROR, "Logs are halted!\r\n");
+ }
+ nrf_cli_fprintf(p_cli, NRF_CLI_NORMAL, "%-40s | current | built-in \r\n", "module_name");
+ nrf_cli_fprintf(p_cli, NRF_CLI_NORMAL, "----------------------------------------------------------\r\n");
+ for (i = 0; i < modules_cnt; i++)
+ {
+ nrf_log_severity_t module_dynamic_lvl = nrf_log_module_filter_get(backend_id, i, true, true);
+ nrf_log_severity_t module_compiled_lvl = nrf_log_module_filter_get(backend_id, i, true, false);
+ nrf_log_severity_t actual_compiled_lvl = MIN(module_compiled_lvl, (nrf_log_severity_t)NRF_LOG_DEFAULT_LEVEL);
+ nrf_cli_fprintf(p_cli, NRF_CLI_NORMAL, "%-40s | %-7s | %s%s\r\n",
+ nrf_log_module_name_get(i, true),
+ m_severity_lvls[module_dynamic_lvl],
+ m_severity_lvls[actual_compiled_lvl],
+ actual_compiled_lvl < module_compiled_lvl ? "*" : "");
+ }
+}
+
+static bool module_id_get(const char * p_name, uint32_t * p_id)
+{
+ uint32_t modules_cnt = nrf_log_module_cnt_get();
+ const char * p_tmp_name;
+ uint32_t j;
+ for (j = 0; j < modules_cnt; j++)
+ {
+ p_tmp_name = nrf_log_module_name_get(j, false);
+ if (strncmp(p_tmp_name, p_name, 32) == 0)
+ {
+ *p_id = j;
+ break;
+ }
+ }
+ return (j != modules_cnt);
+}
+
+static bool module_id_filter_set(uint32_t backend_id,
+ uint32_t module_id,
+ nrf_log_severity_t lvl)
+{
+ nrf_log_severity_t buildin_lvl = nrf_log_module_filter_get(backend_id, module_id, false, false);
+ if (lvl > buildin_lvl)
+ {
+ return false;
+ }
+ else
+ {
+ nrf_log_module_filter_set(backend_id, module_id, lvl);
+ return true;
+ }
+}
+
+static void log_ctrl(nrf_cli_t const * p_cli, size_t argc, char **argv)
+{
+ uint32_t backend_id = p_cli->p_log_backend->backend.id;
+ nrf_log_severity_t lvl;
+ uint32_t first_m_name_idx;
+ uint32_t i;
+ bool all_modules = false;
+
+ if (argc > 0)
+ {
+ if (strncmp(argv[0], "enable", 7) == 0)
+ {
+ if (argc == 1)
+ {
+ nrf_cli_fprintf(p_cli, NRF_CLI_ERROR, "Bad parameter count.\r\n");
+ return;
+ }
+
+ if (argc == 2)
+ {
+ all_modules = true;
+ }
+
+ for (i = 0; i < ARRAY_SIZE(m_severity_lvls); i++)
+ {
+ if (strncmp(argv[1], m_severity_lvls[i], 10) == 0)
+ {
+ break;
+ }
+ }
+
+ if (i == ARRAY_SIZE(m_severity_lvls))
+ {
+ nrf_cli_fprintf(p_cli, NRF_CLI_ERROR, "Unknown severity level: %s\r\n", argv[1]);
+ return;
+ }
+
+ lvl = (nrf_log_severity_t)i;
+ first_m_name_idx = 2;
+
+ }
+ else if (strncmp(argv[0], "disable", 8) == 0)
+ {
+ if (argc == 1)
+ {
+ all_modules = true;
+ }
+ lvl = NRF_LOG_SEVERITY_NONE;
+ first_m_name_idx = 1;
+ }
+ else
+ {
+ nrf_cli_fprintf(p_cli, NRF_CLI_ERROR, "Unknown option: %s\r\n", argv[0]);
+ return;
+ }
+
+ if (all_modules)
+ {
+ for (i = 0; i < nrf_log_module_cnt_get(); i++)
+ {
+ if (module_id_filter_set(backend_id, i, lvl) == false)
+ {
+ nrf_cli_fprintf(p_cli, NRF_CLI_ERROR, "Level unavailable for module: %s\r\n", nrf_log_module_name_get(i, false));
+ }
+ }
+ }
+ else
+ {
+ for (i = first_m_name_idx; i < argc; i++)
+ {
+ uint32_t module_id = 0;
+ if (module_id_get(argv[i], &module_id) == false)
+ {
+ nrf_cli_fprintf(p_cli, NRF_CLI_ERROR, "Unknown module:%s\r\n", argv[i]);
+ }
+
+ if (module_id_filter_set(backend_id, module_id, lvl) == false)
+ {
+ nrf_cli_fprintf(p_cli, NRF_CLI_ERROR, "Level unavailable for module: %s\r\n", nrf_log_module_name_get(module_id, false));
+ }
+ }
+ }
+ }
+}
+static void module_name_get(size_t idx, nrf_cli_static_entry_t * p_static);
+
+NRF_CLI_CREATE_DYNAMIC_CMD(m_module_name, module_name_get);
+
+static void module_name_get(size_t idx, nrf_cli_static_entry_t * p_static)
+{
+ p_static->handler = NULL;
+ p_static->p_help = NULL;
+ p_static->p_subcmd = &m_module_name;
+ p_static->p_syntax = nrf_log_module_name_get(idx, true);
+}
+
+static void severity_lvl_get(size_t idx, nrf_cli_static_entry_t * p_static)
+{
+ p_static->handler = NULL;
+ p_static->p_help = NULL;
+ p_static->p_subcmd = &m_module_name;
+ p_static->p_syntax = (idx < ARRAY_SIZE(m_severity_lvls_sorted)) ?
+ m_severity_lvls_sorted[idx] : NULL;
+}
+
+NRF_CLI_CREATE_DYNAMIC_CMD(m_severity_lvl, severity_lvl_get);
+
+static void log_halt(nrf_cli_t const * p_cli, size_t argc, char **argv)
+{
+ nrf_log_backend_disable(&p_cli->p_log_backend->backend);
+}
+
+static void log_go(nrf_cli_t const * p_cli, size_t argc, char **argv)
+{
+ nrf_log_backend_enable(&p_cli->p_log_backend->backend);
+}
+
+NRF_CLI_CREATE_STATIC_SUBCMD_SET(m_sub_log_stat)
+{
+ NRF_CLI_CMD(disable, &m_module_name,
+ "'log disable <module_0> .. <module_n>' disables logs in specified "
+ "modules (all if no modules specified).",
+ log_ctrl),
+ NRF_CLI_CMD(enable, &m_severity_lvl,
+ "'log enable <level> <module_0> ... <module_n>' enables logs up to given level in "
+ "specified modules (all if no modules specified).",
+ log_ctrl),
+ NRF_CLI_CMD(go, NULL, "Resume logging", log_go),
+ NRF_CLI_CMD(halt, NULL, "Halt logging", log_halt),
+ NRF_CLI_CMD(status, NULL, "Logger status", log_status),
+ NRF_CLI_SUBCMD_SET_END
+};
+
+static void log_cmd(nrf_cli_t const * p_cli, size_t argc, char **argv)
+{
+ if ((argc == 1) || nrf_cli_help_requested(p_cli))
+ {
+ nrf_cli_help_print(p_cli, NULL, 0);
+ return;
+ }
+
+ nrf_cli_fprintf(p_cli, NRF_CLI_ERROR, "%s:%s%s\r\n", argv[0], " unknown parameter: ", argv[1]);
+}
+
+NRF_CLI_CMD_REGISTER(log, &m_sub_log_stat, "Commands for controlling logger", log_cmd);
+
+#endif //NRF_LOG_CLI_CMDS
+
+#endif // NRF_MODULE_ENABLED(NRF_LOG)
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/experimental_log/src/nrf_log_internal.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/experimental_log/src/nrf_log_internal.h
new file mode 100644
index 0000000..7c5246f
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/experimental_log/src/nrf_log_internal.h
@@ -0,0 +1,529 @@
+/**
+ * Copyright (c) 2016 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#ifndef NRF_LOG_INTERNAL_H__
+#define NRF_LOG_INTERNAL_H__
+#include "sdk_common.h"
+#include "nrf.h"
+#include "nrf_error.h"
+#include "app_util.h"
+#include <stdint.h>
+#include <stdbool.h>
+#include "nrf_log_instance.h"
+#include "nrf_log_types.h"
+
+#ifndef NRF_LOG_ERROR_COLOR
+ #define NRF_LOG_ERROR_COLOR NRF_LOG_COLOR_DEFAULT
+#endif
+
+#ifndef NRF_LOG_WARNING_COLOR
+ #define NRF_LOG_WARNING_COLOR NRF_LOG_COLOR_DEFAULT
+#endif
+
+#ifndef NRF_LOG_INFO_COLOR
+ #define NRF_LOG_INFO_COLOR NRF_LOG_COLOR_DEFAULT
+#endif
+
+#ifndef NRF_LOG_DEBUG_COLOR
+ #define NRF_LOG_DEBUG_COLOR NRF_LOG_COLOR_DEFAULT
+#endif
+
+
+#ifndef NRF_LOG_COLOR_DEFAULT
+#define NRF_LOG_COLOR_DEFAULT 0
+#endif
+
+#ifndef NRF_LOG_DEFAULT_LEVEL
+#define NRF_LOG_DEFAULT_LEVEL 0
+#endif
+
+#ifndef NRF_LOG_USES_COLORS
+#define NRF_LOG_USES_COLORS 0
+#endif
+
+#ifndef NRF_LOG_USES_TIMESTAMP
+#define NRF_LOG_USES_TIMESTAMP 0
+#endif
+
+#ifndef NRF_LOG_FILTERS_ENABLED
+#define NRF_LOG_FILTERS_ENABLED 0
+#endif
+
+#ifndef NRF_LOG_MODULE_NAME
+ #define NRF_LOG_MODULE_NAME app
+#endif
+
+#define NRF_LOG_LEVEL_BITS 3
+#define NRF_LOG_LEVEL_MASK ((1UL << NRF_LOG_LEVEL_BITS) - 1)
+#define NRF_LOG_MODULE_ID_BITS 16
+#define NRF_LOG_MODULE_ID_POS 16
+
+
+#define NRF_LOG_MAX_NUM_OF_ARGS 6
+
+
+#if NRF_LOG_FILTERS_ENABLED && NRF_LOG_ENABLED
+ #define NRF_LOG_FILTER NRF_LOG_ITEM_DATA_DYNAMIC(NRF_LOG_MODULE_NAME).filter
+ #define NRF_LOG_INST_FILTER(p_inst) (p_inst)->filter
+#else
+ #undef NRF_LOG_FILTER
+ #define NRF_LOG_FILTER NRF_LOG_SEVERITY_DEBUG
+ #define NRF_LOG_INST_FILTER(p_inst) NRF_LOG_SEVERITY_DEBUG
+#endif
+
+#if NRF_LOG_ENABLED
+#define NRF_LOG_MODULE_ID NRF_LOG_ITEM_DATA_DYNAMIC(NRF_LOG_MODULE_NAME).module_id
+#define NRF_LOG_INST_ID(p_inst) (p_inst)->module_id
+#else
+#define NRF_LOG_MODULE_ID 0
+#define NRF_LOG_INST_ID(p_inst) 0
+#endif
+
+
+#define LOG_INTERNAL_X(N, ...) CONCAT_2(LOG_INTERNAL_, N) (__VA_ARGS__)
+#define LOG_INTERNAL(type, ...) LOG_INTERNAL_X(NUM_VA_ARGS_LESS_1( \
+ __VA_ARGS__), type, __VA_ARGS__)
+#if NRF_LOG_ENABLED
+#define NRF_LOG_INTERNAL_LOG_PUSH(_str) nrf_log_push(_str)
+#define LOG_INTERNAL_0(type, str) \
+ nrf_log_frontend_std_0(type, str)
+#define LOG_INTERNAL_1(type, str, arg0) \
+ /*lint -save -e571*/nrf_log_frontend_std_1(type, str, (uint32_t)(arg0))/*lint -restore*/
+#define LOG_INTERNAL_2(type, str, arg0, arg1) \
+ /*lint -save -e571*/nrf_log_frontend_std_2(type, str, (uint32_t)(arg0), \
+ (uint32_t)(arg1))/*lint -restore*/
+#define LOG_INTERNAL_3(type, str, arg0, arg1, arg2) \
+ /*lint -save -e571*/nrf_log_frontend_std_3(type, str, (uint32_t)(arg0), \
+ (uint32_t)(arg1), (uint32_t)(arg2))/*lint -restore*/
+#define LOG_INTERNAL_4(type, str, arg0, arg1, arg2, arg3) \
+ /*lint -save -e571*/nrf_log_frontend_std_4(type, str, (uint32_t)(arg0), \
+ (uint32_t)(arg1), (uint32_t)(arg2), (uint32_t)(arg3))/*lint -restore*/
+#define LOG_INTERNAL_5(type, str, arg0, arg1, arg2, arg3, arg4) \
+ /*lint -save -e571*/nrf_log_frontend_std_5(type, str, (uint32_t)(arg0), \
+ (uint32_t)(arg1), (uint32_t)(arg2), (uint32_t)(arg3), (uint32_t)(arg4))/*lint -restore*/
+#define LOG_INTERNAL_6(type, str, arg0, arg1, arg2, arg3, arg4, arg5) \
+ /*lint -save -e571*/nrf_log_frontend_std_6(type, str, (uint32_t)(arg0), \
+ (uint32_t)(arg1), (uint32_t)(arg2), (uint32_t)(arg3), (uint32_t)(arg4), (uint32_t)(arg5))/*lint -restore*/
+
+
+#else //NRF_LOG_ENABLED
+#define NRF_LOG_INTERNAL_LOG_PUSH(_str) (void)(_str)
+#define LOG_INTERNAL_0(_type, _str) \
+ (void)(_type); (void)(_str)
+#define LOG_INTERNAL_1(_type, _str, _arg0) \
+ (void)(_type); (void)(_str); (void)(_arg0)
+#define LOG_INTERNAL_2(_type, _str, _arg0, _arg1) \
+ (void)(_type); (void)(_str); (void)(_arg0); (void)(_arg1)
+#define LOG_INTERNAL_3(_type, _str, _arg0, _arg1, _arg2) \
+ (void)(_type); (void)(_str); (void)(_arg0); (void)(_arg1); (void)(_arg2)
+#define LOG_INTERNAL_4(_type, _str, _arg0, _arg1, _arg2, _arg3) \
+ (void)(_type); (void)(_str); (void)(_arg0); (void)(_arg1); (void)(_arg2); (void)(_arg3)
+#define LOG_INTERNAL_5(_type, _str, _arg0, _arg1, _arg2, _arg3, _arg4) \
+ (void)(_type); (void)(_str); (void)(_arg0); (void)(_arg1); (void)(_arg2); (void)(_arg3); (void)(_arg4)
+#define LOG_INTERNAL_6(_type, _str, _arg0, _arg1, _arg2, _arg3, _arg4, _arg5) \
+ (void)(_type); (void)(_str); (void)(_arg0); (void)(_arg1); (void)(_arg2); (void)(_arg3); (void)(_arg4); (void)(_arg5)
+#endif //NRF_LOG_ENABLED
+
+#define LOG_SEVERITY_MOD_ID(severity) ((severity) | NRF_LOG_MODULE_ID << NRF_LOG_MODULE_ID_POS)
+#define LOG_SEVERITY_INST_ID(severity,p_inst) ((severity) | NRF_LOG_INST_ID(p_inst) << NRF_LOG_MODULE_ID_POS)
+
+#if NRF_LOG_ENABLED
+#define LOG_HEXDUMP(_severity, _p_data, _length) \
+ nrf_log_frontend_hexdump((_severity), (_p_data), (_length))
+#else
+#define LOG_HEXDUMP(_severity, _p_data, _length) \
+ (void)(_severity); (void)(_p_data); (void)_length
+#endif
+
+#define NRF_LOG_INTERNAL_INST(level, level_id, p_inst, ...) \
+ if (NRF_LOG_ENABLED && (NRF_LOG_LEVEL >= level) && \
+ (level <= NRF_LOG_DEFAULT_LEVEL)) \
+ { \
+ if (NRF_LOG_INST_FILTER(p_inst) >= level) \
+ { \
+ LOG_INTERNAL(LOG_SEVERITY_INST_ID(level_id, p_inst), __VA_ARGS__); \
+ } \
+ }
+
+#define NRF_LOG_INTERNAL_MODULE(level, level_id, ...) \
+ if (NRF_LOG_ENABLED && (NRF_LOG_LEVEL >= level) && \
+ (level <= NRF_LOG_DEFAULT_LEVEL)) \
+ { \
+ if (NRF_LOG_FILTER >= level) \
+ { \
+ LOG_INTERNAL(LOG_SEVERITY_MOD_ID(level_id), __VA_ARGS__); \
+ } \
+ }
+
+#define NRF_LOG_INTERNAL_HEXDUMP_INST(level, level_id, p_inst, p_data, len) \
+ if (NRF_LOG_ENABLED && (NRF_LOG_LEVEL >= level) && \
+ (level <= NRF_LOG_DEFAULT_LEVEL)) \
+ { \
+ if (NRF_LOG_INST_FILTER(p_inst) >= level) \
+ { \
+ LOG_HEXDUMP(LOG_SEVERITY_INST_ID(level_id, p_inst), \
+ (p_data), (len)); \
+ } \
+ }
+
+#define NRF_LOG_INTERNAL_HEXDUMP_MODULE(level, level_id, p_data, len) \
+ if (NRF_LOG_ENABLED && (NRF_LOG_LEVEL >= level) && \
+ (level <= NRF_LOG_DEFAULT_LEVEL)) \
+ { \
+ if (NRF_LOG_FILTER >= level) \
+ { \
+ LOG_HEXDUMP(LOG_SEVERITY_MOD_ID(level_id), \
+ (p_data), (len)); \
+ } \
+ }
+
+#define NRF_LOG_INTERNAL_INST_ERROR(p_inst, ...) \
+ NRF_LOG_INTERNAL_INST(NRF_LOG_SEVERITY_ERROR, NRF_LOG_SEVERITY_ERROR, p_inst, __VA_ARGS__)
+
+#define NRF_LOG_INTERNAL_ERROR(...) \
+ NRF_LOG_INTERNAL_MODULE(NRF_LOG_SEVERITY_ERROR, NRF_LOG_SEVERITY_ERROR,__VA_ARGS__)
+
+#define NRF_LOG_INTERNAL_HEXDUMP_INST_ERROR(p_inst, p_data, len) \
+ NRF_LOG_INTERNAL_HEXDUMP_INST(NRF_LOG_SEVERITY_ERROR, NRF_LOG_SEVERITY_ERROR, p_inst, p_data, len)
+
+#define NRF_LOG_INTERNAL_HEXDUMP_ERROR(p_data, len) \
+ NRF_LOG_INTERNAL_HEXDUMP_MODULE(NRF_LOG_SEVERITY_ERROR, NRF_LOG_SEVERITY_ERROR, p_data, len)
+
+#define NRF_LOG_INTERNAL_INST_WARNING(p_inst, ...) \
+ NRF_LOG_INTERNAL_INST(NRF_LOG_SEVERITY_WARNING, NRF_LOG_SEVERITY_WARNING, p_inst, __VA_ARGS__)
+
+#define NRF_LOG_INTERNAL_WARNING(...) \
+ NRF_LOG_INTERNAL_MODULE(NRF_LOG_SEVERITY_WARNING, NRF_LOG_SEVERITY_WARNING,__VA_ARGS__)
+
+#define NRF_LOG_INTERNAL_HEXDUMP_INST_WARNING(p_inst, p_data, len) \
+ NRF_LOG_INTERNAL_HEXDUMP_INST(NRF_LOG_SEVERITY_WARNING, NRF_LOG_SEVERITY_WARNING, p_inst, p_data, len)
+
+#define NRF_LOG_INTERNAL_HEXDUMP_WARNING(p_data, len) \
+ NRF_LOG_INTERNAL_HEXDUMP_(NRF_LOG_SEVERITY_WARNING, NRF_LOG_SEVERITY_WARNING, p_data, len)
+
+#define NRF_LOG_INTERNAL_INST_INFO(p_inst, ...) \
+ NRF_LOG_INTERNAL_INST(NRF_LOG_SEVERITY_INFO, NRF_LOG_SEVERITY_INFO, p_inst, __VA_ARGS__)
+
+#define NRF_LOG_INTERNAL_INFO(...) \
+ NRF_LOG_INTERNAL_MODULE(NRF_LOG_SEVERITY_INFO, NRF_LOG_SEVERITY_INFO, __VA_ARGS__)
+
+#define NRF_LOG_INTERNAL_HEXDUMP_INST_INFO(p_inst, p_data, len) \
+ NRF_LOG_INTERNAL_HEXDUMP_INST(NRF_LOG_SEVERITY_INFO, NRF_LOG_SEVERITY_INFO, p_inst, p_data, len)
+
+#define NRF_LOG_INTERNAL_HEXDUMP_INFO(p_data, len) \
+ NRF_LOG_INTERNAL_HEXDUMP_MODULE(NRF_LOG_SEVERITY_INFO, NRF_LOG_SEVERITY_INFO, p_data, len)
+
+#define NRF_LOG_INTERNAL_RAW_INFO(...) \
+ NRF_LOG_INTERNAL_MODULE(NRF_LOG_SEVERITY_INFO, NRF_LOG_SEVERITY_INFO_RAW, __VA_ARGS__)
+
+#define NRF_LOG_INTERNAL_RAW_HEXDUMP_INFO(p_data, len) \
+ NRF_LOG_INTERNAL_HEXDUMP_MODULE(NRF_LOG_SEVERITY_INFO, NRF_LOG_SEVERITY_INFO_RAW, p_data, len)
+
+#define NRF_LOG_INTERNAL_INST_DEBUG(p_inst, ...) \
+ NRF_LOG_INTERNAL_INST(NRF_LOG_SEVERITY_DEBUG, NRF_LOG_SEVERITY_DEBUG, p_inst, __VA_ARGS__)
+
+#define NRF_LOG_INTERNAL_DEBUG(...) \
+ NRF_LOG_INTERNAL_MODULE(NRF_LOG_SEVERITY_DEBUG, NRF_LOG_SEVERITY_DEBUG, __VA_ARGS__)
+
+#define NRF_LOG_INTERNAL_HEXDUMP_INST_DEBUG(p_inst, p_data, len) \
+ NRF_LOG_INTERNAL_HEXDUMP_INST(NRF_LOG_SEVERITY_DEBUG, NRF_LOG_SEVERITY_DEBUG, p_inst, p_data, len)
+
+#define NRF_LOG_INTERNAL_HEXDUMP_DEBUG(p_data, len) \
+ NRF_LOG_INTERNAL_HEXDUMP_MODULE(NRF_LOG_SEVERITY_DEBUG, NRF_LOG_SEVERITY_DEBUG, p_data, len)
+
+
+#if NRF_LOG_ENABLED
+
+#ifdef UNIT_TEST
+#define COMPILED_LOG_LEVEL 4
+#else
+#define COMPILED_LOG_LEVEL NRF_LOG_LEVEL
+#endif
+
+
+#define NRF_LOG_INTERNAL_MODULE_REGISTER() \
+ NRF_LOG_INTERNAL_ITEM_REGISTER(NRF_LOG_MODULE_NAME, \
+ STRINGIFY(NRF_LOG_MODULE_NAME), \
+ NRF_LOG_INFO_COLOR, \
+ NRF_LOG_DEBUG_COLOR, \
+ NRF_LOG_INITIAL_LEVEL, \
+ COMPILED_LOG_LEVEL)
+
+#else
+#define NRF_LOG_INTERNAL_MODULE_REGISTER() /*lint -save -e19*/ /*lint -restore*/
+#endif
+
+extern NRF_LOG_DYNAMIC_STRUCT_NAME NRF_LOG_ITEM_DATA_DYNAMIC(NRF_LOG_MODULE_NAME);
+
+/**
+ * Set of macros for encoding and decoding header for log entries.
+ * There are 3 types of entries:
+ * 1. Standard entry (STD)
+ * An entry consists of header, pointer to string and values. Header contains
+ * severity leveland determines number of arguments and thus size of the entry.
+ * Since flash address space starts from 0x00000000 and is limited to kB rather
+ * than MB 22 bits are used to store the address (4MB). It is used that way to
+ * save one RAM memory.
+ *
+ * --------------------------------
+ * |TYPE|SEVERITY|NARGS| P_STR |
+ * |------------------------------|
+ * | Module_ID (optional) |
+ * |------------------------------|
+ * | TIMESTAMP (optional) |
+ * |------------------------------|
+ * | ARG0 |
+ * |------------------------------|
+ * | .... |
+ * |------------------------------|
+ * | ARG(nargs-1) |
+ * --------------------------------
+ *
+ * 2. Hexdump entry (HEXDUMP) is used for dumping raw data. An entry consists of
+ * header, optional timestamp, pointer to string and data. A header contains
+ * length (10bit) and offset which is updated after backend processes part of
+ * data.
+ *
+ * --------------------------------
+ * |TYPE|SEVERITY|NARGS|OFFSET|LEN|
+ * |------------------------------|
+ * | Module_ID (optional) |
+ * |------------------------------|
+ * | TIMESTAMP (optional) |
+ * |------------------------------|
+ * | P_STR |
+ * |------------------------------|
+ * | data |
+ * |------------------------------|
+ * | data | dummy |
+ * --------------------------------
+ *
+ * 3. Pushed string. If string is pushed into the logger internal buffer it is
+ * stored as PUSHED entry. It consists of header, unused data (optional) and
+ * string. Unused data is present if string does not not fit into a buffer
+ * without wrapping (and string cannot be wrapped). In that case header
+ * contains information about offset.
+ *
+ * --------------------------------
+ * |TYPE| OFFSET | LEN |
+ * |------------------------------|
+ * | OFFSET |
+ * |------------------------------|
+ * end| OFFSET |
+ * 0|------------------------------|
+ * | STRING |
+ * |------------------------------|
+ * | STRING | dummy |
+ * --------------------------------
+ */
+
+#define STD_ADDR_MASK ((uint32_t)(1U << 22) - 1U)
+#define HEADER_TYPE_STD 1U
+#define HEADER_TYPE_HEXDUMP 2U
+#define HEADER_TYPE_PUSHED 0U
+#define HEADER_TYPE_INVALID 3U
+
+typedef struct
+{
+ uint32_t type : 2;
+ uint32_t in_progress: 1;
+ uint32_t data : 29;
+} nrf_log_generic_header_t;
+
+typedef struct
+{
+ uint32_t type : 2;
+ uint32_t in_progress: 1;
+ uint32_t severity : 3;
+ uint32_t nargs : 4;
+ uint32_t addr : 22;
+} nrf_log_std_header_t;
+
+typedef struct
+{
+ uint32_t type : 2;
+ uint32_t in_progress: 1;
+ uint32_t severity : 3;
+ uint32_t offset : 10;
+ uint32_t reserved : 6;
+ uint32_t len : 10;
+} nrf_log_hexdump_header_t;
+
+typedef struct
+{
+ uint32_t type : 2;
+ uint32_t reserved0 : 4;
+ uint32_t offset : 10;
+ uint32_t reserved1 : 6;
+ uint32_t len : 10;
+} nrf_log_pushed_header_t;
+
+typedef union
+{
+ nrf_log_generic_header_t generic;
+ nrf_log_std_header_t std;
+ nrf_log_hexdump_header_t hexdump;
+ nrf_log_pushed_header_t pushed;
+ uint32_t raw;
+} nrf_log_main_header_t;
+
+typedef struct
+{
+ nrf_log_main_header_t base;
+ uint16_t module_id;
+ uint16_t dropped;
+ uint32_t timestamp;
+} nrf_log_header_t;
+
+#define HEADER_SIZE (sizeof(nrf_log_header_t)/sizeof(uint32_t) - \
+ (NRF_LOG_USES_TIMESTAMP ? 0 : 1))
+
+#define PUSHED_HEADER_SIZE (sizeof(nrf_log_pushed_header_t)/sizeof(uint32_t))
+
+//Implementation assumes that pushed header has one word.
+STATIC_ASSERT(PUSHED_HEADER_SIZE == 1);
+/**
+ * @brief A function for logging raw string.
+ *
+ * @param severity_mid Severity.
+ * @param p_str A pointer to a string.
+ */
+void nrf_log_frontend_std_0(uint32_t severity_mid, char const * const p_str);
+
+/**
+ * @brief A function for logging a formatted string with one argument.
+ *
+ * @param severity_mid Severity.
+ * @param p_str A pointer to a formatted string.
+ * @param val0 An argument.
+ */
+void nrf_log_frontend_std_1(uint32_t severity_mid,
+ char const * const p_str,
+ uint32_t val0);
+
+/**
+ * @brief A function for logging a formatted string with 2 arguments.
+ *
+ * @param severity_mid Severity.
+ * @param p_str A pointer to a formatted string.
+ * @param val0, val1 Arguments for formatting string.
+ */
+void nrf_log_frontend_std_2(uint32_t severity_mid,
+ char const * const p_str,
+ uint32_t val0,
+ uint32_t val1);
+
+/**
+ * @brief A function for logging a formatted string with 3 arguments.
+ *
+ * @param severity_mid Severity.
+ * @param p_str A pointer to a formatted string.
+ * @param val0, val1, val2 Arguments for formatting string.
+ */
+void nrf_log_frontend_std_3(uint32_t severity_mid,
+ char const * const p_str,
+ uint32_t val0,
+ uint32_t val1,
+ uint32_t val2);
+
+/**
+ * @brief A function for logging a formatted string with 4 arguments.
+ *
+ * @param severity_mid Severity.
+ * @param p_str A pointer to a formatted string.
+ * @param val0, val1, val2, val3 Arguments for formatting string.
+ */
+void nrf_log_frontend_std_4(uint32_t severity_mid,
+ char const * const p_str,
+ uint32_t val0,
+ uint32_t val1,
+ uint32_t val2,
+ uint32_t val3);
+
+/**
+ * @brief A function for logging a formatted string with 5 arguments.
+ *
+ * @param severity_mid Severity.
+ * @param p_str A pointer to a formatted string.
+ * @param val0, val1, val2, val3, val4 Arguments for formatting string.
+ */
+void nrf_log_frontend_std_5(uint32_t severity_mid,
+ char const * const p_str,
+ uint32_t val0,
+ uint32_t val1,
+ uint32_t val2,
+ uint32_t val3,
+ uint32_t val4);
+
+/**
+ * @brief A function for logging a formatted string with 6 arguments.
+ *
+ * @param severity_mid Severity.
+ * @param p_str A pointer to a formatted string.
+ * @param val0, val1, val2, val3, val4, val5 Arguments for formatting string.
+ */
+void nrf_log_frontend_std_6(uint32_t severity_mid,
+ char const * const p_str,
+ uint32_t val0,
+ uint32_t val1,
+ uint32_t val2,
+ uint32_t val3,
+ uint32_t val4,
+ uint32_t val5);
+
+/**
+ * @brief A function for logging raw data.
+ *
+ * @param severity_mid Severity.
+ * @param p_str A pointer to a string which is prefixing the data.
+ * @param p_data A pointer to data to be dumped.
+ * @param length Length of data (in bytes).
+ *
+ */
+void nrf_log_frontend_hexdump(uint32_t severity_mid,
+ const void * const p_data,
+ uint16_t length);
+
+/**
+ * @brief A function for reading a byte from log backend.
+ *
+ * @return Byte.
+ */
+uint8_t nrf_log_getchar(void);
+#endif // NRF_LOG_INTERNAL_H__
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/experimental_log/src/nrf_log_str_formatter.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/experimental_log/src/nrf_log_str_formatter.c
new file mode 100644
index 0000000..fa548f3
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/experimental_log/src/nrf_log_str_formatter.c
@@ -0,0 +1,256 @@
+/**
+ * Copyright (c) 2016 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#include "sdk_common.h"
+#if NRF_MODULE_ENABLED(NRF_LOG)
+#include "nrf_log_str_formatter.h"
+#include "nrf_log_internal.h"
+#include "nrf_log_ctrl.h"
+#include "nrf_fprintf.h"
+#include <ctype.h>
+
+#define NRF_LOG_COLOR_CODE_DEFAULT "\x1B[0m"
+#define NRF_LOG_COLOR_CODE_BLACK "\x1B[1;30m"
+#define NRF_LOG_COLOR_CODE_RED "\x1B[1;31m"
+#define NRF_LOG_COLOR_CODE_GREEN "\x1B[1;32m"
+#define NRF_LOG_COLOR_CODE_YELLOW "\x1B[1;33m"
+#define NRF_LOG_COLOR_CODE_BLUE "\x1B[1;34m"
+#define NRF_LOG_COLOR_CODE_MAGENTA "\x1B[1;35m"
+#define NRF_LOG_COLOR_CODE_CYAN "\x1B[1;36m"
+#define NRF_LOG_COLOR_CODE_WHITE "\x1B[1;37m"
+
+static const char * severity_names[] = {
+ NULL,
+ "error",
+ "warning",
+ "info",
+ "debug"
+};
+
+static const char * m_colors[] = {
+ NRF_LOG_COLOR_CODE_DEFAULT,
+ NRF_LOG_COLOR_CODE_BLACK,
+ NRF_LOG_COLOR_CODE_RED,
+ NRF_LOG_COLOR_CODE_GREEN,
+ NRF_LOG_COLOR_CODE_YELLOW,
+ NRF_LOG_COLOR_CODE_BLUE,
+ NRF_LOG_COLOR_CODE_MAGENTA,
+ NRF_LOG_COLOR_CODE_CYAN,
+ NRF_LOG_COLOR_CODE_WHITE,
+};
+
+static uint32_t m_freq;
+static uint32_t m_timestamp_div;
+
+static void timestamp_print(nrf_fprintf_ctx_t * p_ctx, uint32_t timestamp)
+{
+ if (NRF_LOG_USES_TIMESTAMP)
+ {
+ if (NRF_LOG_STR_FORMATTER_TIMESTAMP_FORMAT_ENABLED)
+ {
+ timestamp /= m_timestamp_div;
+ uint32_t seconds = timestamp/m_freq;
+ uint32_t hours = seconds/3600;
+ seconds -= hours * 3600;
+ uint32_t mins = seconds/60;
+ seconds -= mins * 60;
+
+ uint32_t reminder = timestamp % m_freq;
+ uint32_t ms = (reminder * 1000)/m_freq;
+ uint32_t us = (1000*(1000*reminder - (ms * m_freq)))/m_freq;
+
+ nrf_fprintf(p_ctx, "[%02d:%02d:%02d.%03d,%03d] ", hours, mins, seconds, ms, us);
+ }
+ else
+ {
+ nrf_fprintf(p_ctx, "[%08lu] ", timestamp);
+ }
+ }
+}
+static void prefix_process(nrf_log_str_formatter_entry_params_t * p_params,
+ nrf_fprintf_ctx_t * p_ctx)
+{
+ if (p_params->dropped)
+ {
+ nrf_fprintf(p_ctx,
+ "%sLogs dropped (%d)%s\r\n",
+ NRF_LOG_COLOR_CODE_RED,
+ p_params->dropped,
+ NRF_LOG_COLOR_CODE_DEFAULT);
+ }
+
+ if (!(p_params->severity == NRF_LOG_SEVERITY_INFO_RAW))
+ {
+ if (p_params->use_colors)
+ {
+ nrf_fprintf(p_ctx, "%s",
+ m_colors[nrf_log_color_id_get( p_params->module_id, p_params->severity)]);
+ }
+ timestamp_print(p_ctx, p_params->timestamp);
+
+ nrf_fprintf(p_ctx, "<%s> %s: ",
+ severity_names[p_params->severity], nrf_log_module_name_get(p_params->module_id, false));
+ }
+}
+
+static void postfix_process(nrf_log_str_formatter_entry_params_t * p_params,
+ nrf_fprintf_ctx_t * p_ctx,
+ bool newline)
+{
+ if (!(p_params->severity == NRF_LOG_SEVERITY_INFO_RAW))
+ {
+ if (p_params->use_colors)
+ {
+ nrf_fprintf(p_ctx, "%s", m_colors[0]);
+ }
+ nrf_fprintf(p_ctx, "\r\n");
+ }
+ else if (newline)
+ {
+ nrf_fprintf(p_ctx, "\r\n");
+ }
+ nrf_fprintf_buffer_flush(p_ctx);
+}
+
+void nrf_log_std_entry_process(char const * p_str,
+ uint32_t const * p_args,
+ uint32_t nargs,
+ nrf_log_str_formatter_entry_params_t * p_params,
+ nrf_fprintf_ctx_t * p_ctx)
+{
+ bool auto_flush = p_ctx->auto_flush;
+ p_ctx->auto_flush = false;
+
+ prefix_process(p_params, p_ctx);
+
+ switch (nargs)
+ {
+ case 0:
+ nrf_fprintf(p_ctx, p_str);
+ break;
+ case 1:
+ nrf_fprintf(p_ctx, p_str, p_args[0]);
+ break;
+ case 2:
+ nrf_fprintf(p_ctx, p_str, p_args[0], p_args[1]);
+ break;
+ case 3:
+ nrf_fprintf(p_ctx, p_str, p_args[0], p_args[1], p_args[2]);
+ break;
+ case 4:
+ nrf_fprintf(p_ctx, p_str, p_args[0], p_args[1], p_args[2], p_args[3]);
+ break;
+ case 5:
+ nrf_fprintf(p_ctx, p_str, p_args[0], p_args[1], p_args[2], p_args[3], p_args[4]);
+ break;
+ case 6:
+ nrf_fprintf(p_ctx, p_str, p_args[0], p_args[1], p_args[2], p_args[3], p_args[4], p_args[5]);
+ break;
+
+ default:
+ break;
+ }
+
+ postfix_process(p_params, p_ctx, false);
+ p_ctx->auto_flush = auto_flush;
+}
+
+#define HEXDUMP_BYTES_IN_LINE 8
+
+void nrf_log_hexdump_entry_process(uint8_t * p_data,
+ uint32_t data_len,
+ nrf_log_str_formatter_entry_params_t * p_params,
+ nrf_fprintf_ctx_t * p_ctx)
+{
+ if (data_len > HEXDUMP_BYTES_IN_LINE)
+ {
+ return;
+ }
+ bool auto_flush = p_ctx->auto_flush;
+ p_ctx->auto_flush = false;
+
+ prefix_process(p_params, p_ctx);
+
+ uint32_t i;
+
+ for (i = 0; i < HEXDUMP_BYTES_IN_LINE; i++)
+ {
+ if (i < data_len)
+ {
+ nrf_fprintf(p_ctx, " %02x", p_data[i]);
+ }
+ else
+ {
+ nrf_fprintf(p_ctx, " ");
+ }
+ }
+ nrf_fprintf(p_ctx, "|");
+
+ for (i = 0; i < HEXDUMP_BYTES_IN_LINE; i++)
+ {
+ if (i < data_len)
+ {
+ char c = (char)p_data[i];
+ nrf_fprintf(p_ctx, "%c", isprint((int)c) ? c :'.');
+ }
+ else
+ {
+ nrf_fprintf(p_ctx, " ");
+ }
+ }
+
+ postfix_process(p_params, p_ctx, true);
+
+ p_ctx->auto_flush = auto_flush;
+}
+
+void nrf_log_str_formatter_timestamp_freq_set(uint32_t freq)
+{
+ m_timestamp_div = 1;
+ /* There is no point to have frequency higher than 1MHz (ns are not printed) and too high
+ * frequency leads to overflows in calculations.
+ */
+ while (freq > 1000000)
+ {
+ freq /= 2;
+ m_timestamp_div *= 2;
+ }
+ m_freq = freq;
+}
+#endif //NRF_LOG_ENABLED
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/experimental_memobj/nrf_memobj.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/experimental_memobj/nrf_memobj.c
new file mode 100644
index 0000000..44b44fc
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/experimental_memobj/nrf_memobj.c
@@ -0,0 +1,231 @@
+/**
+ * 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+
+#include "nrf_memobj.h"
+#include "nrf_atomic.h"
+#include "nrf_assert.h"
+
+typedef struct memobj_elem_s memobj_elem_t;
+
+typedef struct
+{
+ memobj_elem_t * p_next;
+} memobj_header_t;
+
+typedef struct
+{
+ uint8_t user_cnt;
+ uint8_t chunk_cnt;
+ uint16_t chunk_size;
+} memobj_head_header_fields_t;
+
+typedef struct
+{
+ union
+ {
+ nrf_atomic_u32_t atomic_user_cnt;
+ memobj_head_header_fields_t fields;
+ } data;
+} memobj_head_header_t;
+
+typedef struct
+{
+ memobj_header_t header;
+ memobj_head_header_t head_header;
+ uint8_t data[1];
+} memobj_head_t;
+
+STATIC_ASSERT(sizeof(memobj_header_t) == NRF_MEMOBJ_STD_HEADER_SIZE);
+
+struct memobj_elem_s
+{
+ memobj_header_t header;
+ uint8_t data[1];
+};
+
+ret_code_t nrf_memobj_pool_init(nrf_memobj_pool_t const * p_pool)
+{
+ return nrf_balloc_init((nrf_balloc_t const *)p_pool);
+}
+
+nrf_memobj_t * nrf_memobj_alloc(nrf_memobj_pool_t const * p_pool,
+ size_t size)
+{
+ uint32_t bsize = (uint32_t)NRF_BALLOC_ELEMENT_SIZE((nrf_balloc_t const *)p_pool) - sizeof(memobj_header_t);
+ uint8_t num_of_chunks = (uint8_t)CEIL_DIV(size + sizeof(memobj_head_header_t), bsize);
+
+ memobj_head_t * p_head = nrf_balloc_alloc((nrf_balloc_t const *)p_pool);
+ if (p_head == NULL)
+ {
+ return NULL;
+ }
+ p_head->head_header.data.fields.user_cnt = 0;
+ p_head->head_header.data.fields.chunk_cnt = 1;
+ p_head->head_header.data.fields.chunk_size = bsize;
+
+ memobj_header_t * p_prev = (memobj_header_t *)p_head;
+ memobj_header_t * p_curr;
+ uint32_t i;
+ uint32_t chunk_less1 = (uint32_t)num_of_chunks - 1;
+
+ p_prev->p_next = (memobj_elem_t *)p_pool;
+ for (i = 0; i < chunk_less1; i++)
+ {
+ p_curr = (memobj_header_t *)nrf_balloc_alloc((nrf_balloc_t const *)p_pool);
+ if (p_curr)
+ {
+ (p_head->head_header.data.fields.chunk_cnt)++;
+ p_prev->p_next = (memobj_elem_t *)p_curr;
+ p_curr->p_next = (memobj_elem_t *)p_pool;
+ p_prev = p_curr;
+ }
+ else
+ {
+ //Couldn't allocate all requested buffers
+ nrf_memobj_free((nrf_memobj_t *)p_head);
+ return NULL;
+ }
+ }
+ return (nrf_memobj_t *)p_head;
+}
+
+void nrf_memobj_free(nrf_memobj_t * p_obj)
+{
+ memobj_head_t * p_head = (memobj_head_t *)p_obj;
+ uint8_t chunk_cnt = p_head->head_header.data.fields.chunk_cnt;
+ uint32_t i;
+ memobj_header_t * p_curr = (memobj_header_t *)p_obj;
+ memobj_header_t * p_next;
+ uint32_t chunk_less1 = (uint32_t)chunk_cnt - 1;
+
+ for (i = 0; i < chunk_less1; i++)
+ {
+ p_curr = (memobj_header_t *)p_curr->p_next;
+ }
+ nrf_balloc_t const * p_pool2 = (nrf_balloc_t const *)p_curr->p_next;
+
+ p_curr = (memobj_header_t *)p_obj;
+ for (i = 0; i < chunk_cnt; i++)
+ {
+ p_next = (memobj_header_t *)p_curr->p_next;
+ nrf_balloc_free(p_pool2, p_curr);
+ p_curr = p_next;
+ }
+}
+
+void nrf_memobj_get(nrf_memobj_t const * p_obj)
+{
+ memobj_head_t * p_head = (memobj_head_t *)p_obj;
+ (void)nrf_atomic_u32_add(&p_head->head_header.data.atomic_user_cnt, 1);
+}
+
+void nrf_memobj_put(nrf_memobj_t * p_obj)
+{
+ memobj_head_t * p_head = (memobj_head_t *)p_obj;
+ uint32_t user_cnt = nrf_atomic_u32_sub(&p_head->head_header.data.atomic_user_cnt, 1);
+ memobj_head_header_fields_t * p_fields = (memobj_head_header_fields_t *)&user_cnt;
+ if (p_fields->user_cnt == 0)
+ {
+ nrf_memobj_free(p_obj);
+ }
+}
+
+static void memobj_op(nrf_memobj_t * p_obj,
+ void * p_data,
+ uint32_t len,
+ uint32_t offset,
+ bool read)
+{
+
+ memobj_head_t * p_head = (memobj_head_t *)p_obj;
+ uint32_t space_in_chunk = p_head->head_header.data.fields.chunk_size;
+ memobj_elem_t * p_curr_chunk = (memobj_elem_t *)p_obj;
+ uint32_t chunk_idx = (offset + sizeof(memobj_head_header_fields_t))/space_in_chunk;
+ uint32_t chunk_offset = (offset + sizeof(memobj_head_header_fields_t)) % space_in_chunk;
+
+ uint8_t chunks_expected = CEIL_DIV((offset + sizeof(memobj_head_header_fields_t) + len),
+ space_in_chunk);
+ UNUSED_VARIABLE(chunks_expected);
+ ASSERT(p_head->head_header.data.fields.chunk_cnt >= chunks_expected);
+
+ while (chunk_idx > 0)
+ {
+ p_curr_chunk = p_curr_chunk->header.p_next;
+ chunk_idx--;
+ }
+
+ uint32_t src_offset = 0;
+ uint32_t curr_cpy_size = space_in_chunk-chunk_offset;
+ curr_cpy_size = curr_cpy_size > len ? len : curr_cpy_size;
+
+ while (len)
+ {
+ if (read)
+ {
+ memcpy(&((uint8_t *)p_data)[src_offset], &p_curr_chunk->data[chunk_offset], curr_cpy_size);
+ }
+ else
+ {
+ memcpy(&p_curr_chunk->data[chunk_offset], &((uint8_t *)p_data)[src_offset], curr_cpy_size);
+ }
+ chunk_offset = 0;
+ p_curr_chunk = p_curr_chunk->header.p_next;
+ len -= curr_cpy_size;
+ src_offset += curr_cpy_size;
+ curr_cpy_size = (space_in_chunk > len) ? len : space_in_chunk;
+ }
+}
+
+void nrf_memobj_write(nrf_memobj_t * p_obj,
+ void * p_data,
+ uint32_t len,
+ uint32_t offset)
+{
+
+ memobj_op(p_obj, p_data, len, offset, false);
+}
+
+void nrf_memobj_read(nrf_memobj_t * p_obj,
+ void * p_data,
+ uint32_t len,
+ uint32_t offset)
+{
+ memobj_op(p_obj, p_data, len, offset, true);
+}
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/experimental_memobj/nrf_memobj.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/experimental_memobj/nrf_memobj.h
new file mode 100644
index 0000000..06740db
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/experimental_memobj/nrf_memobj.h
@@ -0,0 +1,198 @@
+/**
+ * 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+
+#ifndef NRF_MEMOBJ_H
+#define NRF_MEMOBJ_H
+
+/**
+* @defgroup nrf_memobj Memory Object module
+* @{
+* @ingroup app_common
+* @brief Functions for controlling memory object
+*/
+#include <stdint.h>
+#include <stdlib.h>
+#include "sdk_errors.h"
+#include "nrf_balloc.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * Memory object can consist of multiple object with the same size. Each object has header and data
+ * part. First element in memory object is memory object head which has special header, remaining objects
+ * has the same header. Model of memory object is presented below.
+ *
+ * |---------------------| |---------------------| |---------------------|
+ * | head header (u32): | --->| std header - p_next |------->| p_memobj_pool |
+ * | num_of_chunks, | | |---------------------| |---------------------|
+ * | ref counter | | | | | |
+ * |---------------------| | | | | |
+ * | std header - p_next |-| | | .... | |
+ * |---------------------| | data | | data |
+ * | | | | | |
+ * | data | | | | |
+ * | | | | | |
+ * |---------------------| |---------------------| |---------------------|
+ * head mid_element last_element
+ *
+ *
+ */
+#define NRF_MEMOBJ_STD_HEADER_SIZE sizeof(uint32_t)
+
+/**
+ * @brief Macro for creating a nrf_memobj pool.
+ *
+ * Macro declares nrf_balloc object. Element in the pool contains user defined data part and
+ * memobj header.
+ */
+#define NRF_MEMOBJ_POOL_DEF(_name, _element_size, _pool_size) \
+ NRF_BALLOC_DEF(_name, ((_element_size)+NRF_MEMOBJ_STD_HEADER_SIZE), (_pool_size))
+
+/**
+ * @brief Pool of memobj.
+ */
+typedef nrf_balloc_t nrf_memobj_pool_t;
+
+/**
+ * @brief Memobj handle.
+ */
+typedef void * nrf_memobj_t;
+
+/**
+ * @brief Function for initializing the memobj pool instance.
+ *
+ * This function initializes the pool.
+ *
+ * @param[in] p_pool Pointer to the memobj pool instance structure.
+ *
+ * @return NRF_SUCCESS on success, otherwise error code.
+ */
+ret_code_t nrf_memobj_pool_init(nrf_memobj_pool_t const * p_pool);
+
+/**
+ * @brief Function for allocating memobj with requested size.
+ *
+ * Fixed length elements in the pool are linked together to provide amount of memory requested by
+ * the user. If memory object is successfully allocated then user can use memory however it is
+ * fragmented into multiple object so it has to be access through the API: @ref nrf_memobj_write,
+ * @ref nrf_memobj_read.
+ *
+ * This function initializes the pool.
+ *
+ * @param[in] p_pool Pointer to the memobj pool instance structure.
+ * @param[in] size Data size of requested object.
+ *
+ * @return Pointer to memory object or NULL if requested size cannot be allocated.
+ */
+nrf_memobj_t * nrf_memobj_alloc(nrf_memobj_pool_t const * p_pool,
+ size_t size);
+
+/**
+ * @brief Function for indicating that memory object is used and cannot be freed.
+ *
+ * Memory object can be shared and reused between multiple modules and this mechanism ensures that
+ * object is freed when no longer used by any module. Memory object has a counter which is incremented
+ * whenever this function is called. @ref nrf_memobj_put function decrements the counter.
+ *
+ * @param[in] p_obj Pointer to memory object.
+ */
+void nrf_memobj_get(nrf_memobj_t const * p_obj);
+
+
+/**
+ * @brief Function for indicated that memory object is no longer used by the module and can be freed
+ * if no other module is using it.
+ *
+ * Memory object is returned to the pool if internal counter reaches 0 after decrementing. It means
+ * that no other module is needing it anymore.
+ *
+ * @note Memory object holds pointer to the pool which was used to allocate it so it does not have
+ * to be provided explicitly to this function.
+ *
+ * @param[in] p_obj Pointer to memory object.
+ */
+void nrf_memobj_put(nrf_memobj_t * p_obj);
+
+
+/**
+ * @brief Function for forcing freeing of the memory object.
+ *
+ * @note This function should be use with caution because it can lead to undefined behavior of the
+ * modules since modules using the memory object are not aware that it has been freed.
+ *
+ * @param[in] p_obj Pointer to memory object.
+ */
+void nrf_memobj_free(nrf_memobj_t * p_obj);
+
+/**
+ * @brief Function for writing data to the memory object.
+ *
+ * @param[in] p_obj Pointer to memory object.
+ * @param[in] p_data Pointer to data to be written to the memory object.
+ * @param[in] len Amount of data to be written to the memory object.
+ * @param[in] offset Offset.
+ */
+void nrf_memobj_write(nrf_memobj_t * p_obj,
+ void * p_data,
+ uint32_t len,
+ uint32_t offset);
+
+/**
+ * @brief Function for reading data from the memory object.
+ *
+ * @param[in] p_obj Pointer to memory object.
+ * @param[in] p_data Pointer to the destination buffer.
+ * @param[in] len Amount of data to be read from the memory object.
+ * @param[in] offset Offset.
+ */
+void nrf_memobj_read(nrf_memobj_t * p_obj,
+ void * p_data,
+ uint32_t len,
+ uint32_t offset);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif //NRF_MEMOBJ_H
+
+/** @} */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/experimental_mpu/nrf_mpu.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/experimental_mpu/nrf_mpu.c
new file mode 100644
index 0000000..9db2aef
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/experimental_mpu/nrf_mpu.c
@@ -0,0 +1,442 @@
+/**
+ * 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+
+#include <stdint.h>
+#include "nrf.h"
+#include "nrf_mpu.h"
+#include "app_util_platform.h"
+#include "sdk_config.h"
+
+#if NRF_MPU_CLI_CMDS
+#include "nrf_cli.h"
+#endif
+
+#define NRF_LOG_MODULE_NAME nrf_mpu
+
+#if NRF_MPU_CONFIG_LOG_ENABLED
+#define NRF_LOG_LEVEL NRF_MPU_CONFIG_LOG_LEVEL
+#define NRF_LOG_INFO_COLOR NRF_MPU_CONFIG_INFO_COLOR
+#define NRF_LOG_DEBUG_COLOR NRF_MPU_CONFIG_DEBUG_COLOR
+#else
+#define NRF_LOG_LEVEL 0
+#endif
+#include "nrf_log.h"
+NRF_LOG_MODULE_REGISTER();
+
+// Check module requirements.
+STATIC_ASSERT(__MPU_PRESENT);
+STATIC_ASSERT(__CORTEX_M == 4);
+
+/**@brief Return number of unified regions avaiable in MPU. */
+__STATIC_INLINE unsigned int nrf_mpu_get_number_of_regions(void)
+{
+ return (MPU->TYPE & MPU_TYPE_DREGION_Msk) >> MPU_TYPE_DREGION_Pos;
+}
+
+/**@brief Extract human-readable memory type from attributes. */
+static const char *nrf_mpu_mem_type(uint32_t attributes)
+{
+ attributes &= MPU_RASR_TEX_Msk | MPU_RASR_C_Msk | MPU_RASR_B_Msk | MPU_RASR_S_Msk;
+
+ switch (attributes)
+ {
+ case (0x00 << MPU_RASR_TEX_Pos) | (0 << MPU_RASR_C_Pos) | (0 << MPU_RASR_B_Pos) | (0 << MPU_RASR_S_Pos):
+ case (0x00 << MPU_RASR_TEX_Pos) | (0 << MPU_RASR_C_Pos) | (0 << MPU_RASR_B_Pos) | (1 << MPU_RASR_S_Pos):
+ return "Strongly-ordered, Shareable";
+
+ case (0x00 << MPU_RASR_TEX_Pos) | (0 << MPU_RASR_C_Pos) | (1 << MPU_RASR_B_Pos) | (0 << MPU_RASR_S_Pos):
+ case (0x00 << MPU_RASR_TEX_Pos) | (0 << MPU_RASR_C_Pos) | (1 << MPU_RASR_B_Pos) | (1 << MPU_RASR_S_Pos):
+ return "Device, Shareable";
+
+ case (0x00 << MPU_RASR_TEX_Pos) | (1 << MPU_RASR_C_Pos) | (0 << MPU_RASR_B_Pos) | (0 << MPU_RASR_S_Pos):
+ case (0x00 << MPU_RASR_TEX_Pos) | (1 << MPU_RASR_C_Pos) | (1 << MPU_RASR_B_Pos) | (0 << MPU_RASR_S_Pos):
+ case (0x01 << MPU_RASR_TEX_Pos) | (0 << MPU_RASR_C_Pos) | (0 << MPU_RASR_B_Pos) | (0 << MPU_RASR_S_Pos):
+ case (0x01 << MPU_RASR_TEX_Pos) | (1 << MPU_RASR_C_Pos) | (1 << MPU_RASR_B_Pos) | (0 << MPU_RASR_S_Pos):
+ return "Normal";
+
+ case (0x00 << MPU_RASR_TEX_Pos) | (1 << MPU_RASR_C_Pos) | (0 << MPU_RASR_B_Pos) | (1 << MPU_RASR_S_Pos):
+ case (0x00 << MPU_RASR_TEX_Pos) | (1 << MPU_RASR_C_Pos) | (1 << MPU_RASR_B_Pos) | (1 << MPU_RASR_S_Pos):
+ case (0x01 << MPU_RASR_TEX_Pos) | (0 << MPU_RASR_C_Pos) | (0 << MPU_RASR_B_Pos) | (1 << MPU_RASR_S_Pos):
+ case (0x01 << MPU_RASR_TEX_Pos) | (1 << MPU_RASR_C_Pos) | (1 << MPU_RASR_B_Pos) | (1 << MPU_RASR_S_Pos):
+ return "Normal, Shareable";
+
+ case (0x02 << MPU_RASR_TEX_Pos) | (0 << MPU_RASR_C_Pos) | (0 << MPU_RASR_B_Pos) | (0 << MPU_RASR_S_Pos):
+ case (0x02 << MPU_RASR_TEX_Pos) | (0 << MPU_RASR_C_Pos) | (0 << MPU_RASR_B_Pos) | (1 << MPU_RASR_S_Pos):
+ return "Device";
+
+ default:
+ if (((attributes & MPU_RASR_TEX_Msk) >> MPU_RASR_TEX_Pos) >= 0x04)
+ {
+ return (attributes & MPU_RASR_S_Msk) ? "Normal, Shareable" : "Normal";
+ }
+ else
+ {
+ return "Reserved or Implementation Defined";
+ }
+ }
+
+ // Not reached.
+}
+
+/**@brief Extract human-readable access level from attributes. */
+static const char *nrf_mpu_mem_access(uint32_t attributes)
+{
+ switch ((attributes & MPU_RASR_AP_Msk) >> MPU_RASR_AP_Pos)
+ {
+ case 0x00:
+ return "--/--";
+
+ case 0x01:
+ return "RW/--";
+
+ case 0x02:
+ return "RW/RO";
+
+ case 0x03:
+ return "RW/RW";
+
+ case 0x04:
+ return "\?\?/\?\?";
+
+ case 0x05:
+ return "RO/--";
+
+ case 0x06:
+ case 0x07:
+ return "RO/RO";
+
+ default:
+ return "Unknown";
+ }
+
+ // Not reached.
+}
+
+ret_code_t nrf_mpu_init(void)
+{
+ unsigned int i, regions;
+
+ // Make sure that MPU uses unified regions. Separate are not supported.
+ if ((MPU->TYPE & MPU_TYPE_SEPARATE_Msk) >> MPU_TYPE_SEPARATE_Pos)
+ {
+ NRF_LOG_ERROR("Non-unified MPU is not supported!");
+ return NRF_ERROR_NOT_SUPPORTED;
+ }
+
+ // Make sure that we can handle all avaiable regions.
+ regions = nrf_mpu_get_number_of_regions();
+ if (regions > ((1 << (8 * sizeof(nrf_mpu_region_t))) - 1))
+ {
+ NRF_LOG_ERROR("MPU with %u regions is not supported!", regions);
+ return NRF_ERROR_NOT_SUPPORTED;
+ }
+
+ // Disable MPU.
+ MPU->CTRL = 0;
+
+ // Clear all regions.
+ for (i = 0; i < regions; i++)
+ {
+ MPU->RNR = i;
+ MPU->RASR = 0;
+ MPU->RBAR = 0;
+ }
+
+ /* Enable MPU */
+ MPU->CTRL = (1 << MPU_CTRL_ENABLE_Pos) |
+ (1 << MPU_CTRL_PRIVDEFENA_Pos);
+
+ // Make sure that configuration changes are active.
+ __DSB();
+
+ NRF_LOG_INFO("MPU Initalized. %u unified regions avaiable.", regions);
+
+ return NRF_SUCCESS;
+}
+
+ret_code_t nrf_mpu_region_create(nrf_mpu_region_t *p_region,
+ void *address,
+ size_t size,
+ uint32_t attributes)
+{
+ unsigned long addr = (unsigned long)(address);
+ unsigned int i, regions = nrf_mpu_get_number_of_regions();
+
+ // Size must be power of 2 greather than or equal to 32
+ if ((size & (size - 1)) || (size < 32))
+ {
+ NRF_LOG_ERROR("Cannot create MPU region 0x%08X-0x%08X: Region size is not valid!", addr, addr + size - 1);
+ return NRF_ERROR_INVALID_PARAM;
+ }
+
+ // Region must be aligned to it's size.
+ if (addr & (size - 1))
+ {
+ NRF_LOG_ERROR("Cannot create MPU region 0x%08X-0x%08X: Region alignment is not valid!", addr, addr + size - 1);
+ return NRF_ERROR_INVALID_PARAM;
+ }
+
+ // Check if attributes are valid.
+ if (attributes & ~MPU_RASR_ATTRS_Msk)
+ {
+ NRF_LOG_ERROR("Cannot create MPU region 0x%08X-0x%08X: Region attributes are not valid!", addr, addr + size - 1);
+ return NRF_ERROR_INVALID_PARAM;
+ }
+
+ NRF_LOG_DEBUG("MPU region creating (location: 0x%08X-0x%08X)",
+ addr,
+ addr + size - 1);
+ // Create region.
+ CRITICAL_REGION_ENTER();
+ for (i = 0; i < regions; i++)
+ {
+ MPU->RNR = i;
+ if (MPU->RASR & MPU_RASR_ENABLE_Msk)
+ {
+ continue;
+ }
+
+ MPU->RBAR = addr;
+ MPU->RASR = attributes |
+ (1 << MPU_RASR_ENABLE_Pos) |
+ ((31 - __CLZ(size) - 1) << MPU_RASR_SIZE_Pos);
+
+ break;
+ }
+ CRITICAL_REGION_EXIT();
+
+ if (i >= regions)
+ {
+ NRF_LOG_ERROR("Cannot create MPU region 0x%08X-0x%08X: No free region found!", addr, addr + size - 1);
+ return NRF_ERROR_NO_MEM;
+ }
+
+ // Apply changes.
+ __DSB();
+
+ // Save region number;
+ *p_region = i;
+
+ NRF_LOG_DEBUG("MPU region %u created (location: 0x%08X-0x%08X, access: %s, type: %s, flags: %s).",
+ i,
+ addr,
+ addr + size - 1,
+ (uint32_t)nrf_mpu_mem_access(attributes),
+ (uint32_t)nrf_mpu_mem_type(attributes),
+ (uint32_t)((attributes & MPU_RASR_XN_Msk) ? "XN" : "--"));
+
+ return NRF_SUCCESS;
+}
+
+ret_code_t nrf_mpu_region_destroy(nrf_mpu_region_t region)
+{
+ if (region >= nrf_mpu_get_number_of_regions())
+ {
+ NRF_LOG_ERROR("Cannot destroy MPU region %u: Invaid region!", region);
+ return NRF_ERROR_INVALID_PARAM;
+ }
+
+ CRITICAL_REGION_ENTER();
+ MPU->RNR = region;
+ MPU->RASR = 0;
+ MPU->RBAR = 0;
+ CRITICAL_REGION_EXIT();
+
+ // Apply changes.
+ __DSB();
+
+ NRF_LOG_DEBUG("MPU region %u destroyed.", region);
+
+ return NRF_SUCCESS;
+}
+
+#if NRF_MPU_CLI_CMDS
+
+/**@brief Extract human-readable caching policy from attributes. */
+static const char *nrf_mpu_mem_caching(uint32_t attributes)
+{
+ static const char *caching[] =
+ {
+ "--/--", "WBWA/--", "WT/--", "WB/--",
+ "--/WBWA", "WBWA/WBWA","WT/WBWA", "WB/WBWA",
+ "--/WT", "WBWA/WT", "WT/WT", "WB/WT",
+ "--/WB", "WBWA/WB", "WT/WB", "WB/WB",
+ };
+
+ uint32_t tex = (attributes & MPU_RASR_TEX_Msk) >> MPU_RASR_TEX_Pos;
+ uint32_t c = (attributes & MPU_RASR_C_Msk) >> MPU_RASR_C_Pos;
+ uint32_t b = (attributes & MPU_RASR_B_Msk) >> MPU_RASR_B_Pos;
+
+ attributes &= MPU_RASR_TEX_Msk | MPU_RASR_C_Msk | MPU_RASR_B_Msk | MPU_RASR_S_Msk;
+
+ switch (attributes)
+ {
+ case (0x00 << MPU_RASR_TEX_Pos) | (0 << MPU_RASR_C_Pos) | (0 << MPU_RASR_B_Pos) | (0 << MPU_RASR_S_Pos):
+ case (0x00 << MPU_RASR_TEX_Pos) | (0 << MPU_RASR_C_Pos) | (0 << MPU_RASR_B_Pos) | (1 << MPU_RASR_S_Pos):
+ case (0x00 << MPU_RASR_TEX_Pos) | (0 << MPU_RASR_C_Pos) | (1 << MPU_RASR_B_Pos) | (0 << MPU_RASR_S_Pos):
+ case (0x00 << MPU_RASR_TEX_Pos) | (0 << MPU_RASR_C_Pos) | (1 << MPU_RASR_B_Pos) | (1 << MPU_RASR_S_Pos):
+ case (0x00 << MPU_RASR_TEX_Pos) | (1 << MPU_RASR_C_Pos) | (0 << MPU_RASR_B_Pos) | (1 << MPU_RASR_S_Pos):
+ case (0x00 << MPU_RASR_TEX_Pos) | (1 << MPU_RASR_C_Pos) | (1 << MPU_RASR_B_Pos) | (1 << MPU_RASR_S_Pos):
+ case (0x01 << MPU_RASR_TEX_Pos) | (0 << MPU_RASR_C_Pos) | (0 << MPU_RASR_B_Pos) | (0 << MPU_RASR_S_Pos):
+ case (0x01 << MPU_RASR_TEX_Pos) | (0 << MPU_RASR_C_Pos) | (0 << MPU_RASR_B_Pos) | (1 << MPU_RASR_S_Pos):
+ case (0x01 << MPU_RASR_TEX_Pos) | (1 << MPU_RASR_C_Pos) | (1 << MPU_RASR_B_Pos) | (1 << MPU_RASR_S_Pos):
+ case (0x02 << MPU_RASR_TEX_Pos) | (0 << MPU_RASR_C_Pos) | (0 << MPU_RASR_B_Pos) | (0 << MPU_RASR_S_Pos):
+ case (0x02 << MPU_RASR_TEX_Pos) | (0 << MPU_RASR_C_Pos) | (0 << MPU_RASR_B_Pos) | (1 << MPU_RASR_S_Pos):
+ return "--/--";
+
+ case (0x00 << MPU_RASR_TEX_Pos) | (1 << MPU_RASR_C_Pos) | (0 << MPU_RASR_B_Pos) | (0 << MPU_RASR_S_Pos):
+ return "WT/WT";
+
+ case (0x00 << MPU_RASR_TEX_Pos) | (1 << MPU_RASR_C_Pos) | (1 << MPU_RASR_B_Pos) | (0 << MPU_RASR_S_Pos):
+ return "WB/WB";
+
+ case (0x01 << MPU_RASR_TEX_Pos) | (1 << MPU_RASR_C_Pos) | (1 << MPU_RASR_B_Pos) | (0 << MPU_RASR_S_Pos):
+ return "WBWA/WBWA";
+
+ default:
+ if (tex >= 0x04)
+ {
+ return caching[((tex & 0x03) << 2) | ((c & 0x01) << 1) | (b & 0x01)];
+ }
+ break;
+ }
+
+ return "Unknown";
+}
+/**@brief Implementation of "mpu info" command. */
+static void nrf_mpu_cmd_info(nrf_cli_t const *p_cli, size_t argc, char **argv)
+{
+ if (nrf_cli_help_requested(p_cli))
+ {
+ nrf_cli_help_print(p_cli, NULL, 0);
+ return;
+ }
+
+ unsigned int i, regions = nrf_mpu_get_number_of_regions();
+
+ nrf_cli_fprintf(p_cli, NRF_CLI_NORMAL, "MPU State: %s, %u unified regions aviable.\r\n\r\n",
+ (MPU->CTRL & MPU_CTRL_ENABLE_Msk) ? "Enabled" : "Disabled",
+ regions);
+
+
+ for (i = 0; i < regions; i++)
+ {
+ uint32_t rasr, rbar;
+ uint32_t size;
+
+ CRITICAL_REGION_ENTER();
+ MPU->RNR = i;
+ rasr = MPU->RASR;
+ rbar = MPU->RBAR;
+ CRITICAL_REGION_EXIT();
+
+ if ((rasr & MPU_RASR_ENABLE_Msk) == 0)
+ {
+ nrf_cli_fprintf(p_cli, NRF_CLI_NORMAL, "Region %u: Disabled\r\n", i);
+ continue;
+ }
+
+ nrf_cli_fprintf(p_cli, NRF_CLI_NORMAL, "Region %u: Enabled\r\n", i);
+
+ size = 1ul << (((rasr & MPU_RASR_SIZE_Msk) >> MPU_RASR_SIZE_Pos) + 1);
+ nrf_cli_fprintf(p_cli, NRF_CLI_NORMAL, "\t- Location:\t0x%08X-0x%08X (size: %u bytes)\r\n",
+ rbar,
+ rbar + size - 1,
+ size);
+
+ nrf_cli_fprintf(p_cli, NRF_CLI_NORMAL, "\t- Access:\t%s\r\n", nrf_mpu_mem_access(rasr));
+ nrf_cli_fprintf(p_cli, NRF_CLI_NORMAL, "\t- Type:\t\t%s\r\n", nrf_mpu_mem_type(rasr));
+ nrf_cli_fprintf(p_cli, NRF_CLI_NORMAL, "\t- Caching:\t%s\r\n", nrf_mpu_mem_caching(rasr));
+ nrf_cli_fprintf(p_cli, NRF_CLI_NORMAL, "\t- Flags:\t%s\r\n\r\n", (rasr & MPU_RASR_XN_Msk) ? "XN" : "--");
+ }
+}
+
+/**@brief Implementation of "mpu dump" command. */
+static void nrf_mpu_cmd_dump(nrf_cli_t const *p_cli, size_t argc, char **argv)
+{
+ unsigned int i, regions = nrf_mpu_get_number_of_regions();
+
+ if (nrf_cli_help_requested(p_cli))
+ {
+ nrf_cli_help_print(p_cli, NULL, 0);
+ return;
+ }
+
+ nrf_cli_fprintf(p_cli, NRF_CLI_NORMAL, "MPU_TYPE:\t0x%08X\r\n", MPU->TYPE);
+ nrf_cli_fprintf(p_cli, NRF_CLI_NORMAL, "MPU_CTRL:\t0x%08X\r\n", MPU->CTRL);
+
+ for (i = 0; i < regions; i++)
+ {
+ uint32_t rasr, rbar;
+
+ CRITICAL_REGION_ENTER();
+ MPU->RNR = i;
+ rasr = MPU->RASR;
+ rbar = MPU->RBAR;
+ CRITICAL_REGION_EXIT();
+
+ nrf_cli_fprintf(p_cli, NRF_CLI_NORMAL, "\r\nMPU_RBAR[%u]:\t0x%08X\r\n", i, rbar);
+ nrf_cli_fprintf(p_cli, NRF_CLI_NORMAL, "MPU_RASR[%u]:\t0x%08X\r\n", i, rasr);
+ }
+}
+
+/**@brief Implementation of "mpu" command. */
+static void nrf_mpu_cmd_unknown(nrf_cli_t const * p_cli, size_t argc, char **argv)
+{
+ if ((argc == 1) || nrf_cli_help_requested(p_cli))
+ {
+ nrf_cli_help_print(p_cli, NULL, 0);
+ return;
+ }
+
+ nrf_cli_fprintf(p_cli, NRF_CLI_ERROR, "%s: unknown parameter: %s\r\n", argv[0], argv[1]);
+}
+
+// Register "mpu" command and it's subcommands in CLI.
+NRF_CLI_CREATE_STATIC_SUBCMD_SET(nrf_mpu_commands)
+{
+ NRF_CLI_CMD(dump, NULL, "Dump MPU registers.", nrf_mpu_cmd_dump),
+ NRF_CLI_CMD(info, NULL, "Print information about MPU state.", nrf_mpu_cmd_info),
+ NRF_CLI_SUBCMD_SET_END
+};
+
+NRF_CLI_CMD_REGISTER(mpu, &nrf_mpu_commands, "Commands for MPU management", nrf_mpu_cmd_unknown);
+
+#endif //NRF_MPU_CLI_CMDS
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/experimental_mpu/nrf_mpu.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/experimental_mpu/nrf_mpu.h
new file mode 100644
index 0000000..2ba309f
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/experimental_mpu/nrf_mpu.h
@@ -0,0 +1,94 @@
+/**
+ * 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+
+#ifndef __NRF_MPU_H
+#define __NRF_MPU_H
+
+/**
+* @defgroup nrf_mpu MPU (Memory Protection Unit) driver
+* @{
+* @ingroup app_common
+* @brief Functions for controlling MPU
+*/
+#include <stdint.h>
+#include <stdlib.h>
+#include "sdk_errors.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**@brief MPU region handle. */
+typedef uint8_t nrf_mpu_region_t;
+
+/**@brief Initialize MPU and driver.
+ *
+ * @return NRF_SUCCESS on success, otherwise error code.
+ */
+ret_code_t nrf_mpu_init(void);
+
+/**@brief Create new MPU region.
+ *
+ * @param[out] p_region Region handle.
+ * @param[in] address Region base address.
+ * @param[in] size Region size,
+ * @param[in] attributes Region attributes.
+ *
+ * @return NRF_SUCCESS on success, otherwise error code.
+ */
+ret_code_t nrf_mpu_region_create(nrf_mpu_region_t *p_region,
+ void *address,
+ size_t size,
+ uint32_t attributes);
+
+/**@brief Destroy MPU region.
+ *
+ * @param[in] region Region handle.
+ *
+ * @return NRF_SUCCESS on success, otherwise error code.
+ */
+ret_code_t nrf_mpu_region_destroy(nrf_mpu_region_t region);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __NRF_MPU_H */
+/** @} */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/experimental_ringbuf/nrf_ringbuf.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/experimental_ringbuf/nrf_ringbuf.c
new file mode 100644
index 0000000..0198179
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/experimental_ringbuf/nrf_ringbuf.c
@@ -0,0 +1,238 @@
+/**
+ * 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#include "nrf_ringbuf.h"
+#include "app_util_platform.h"
+#include "nrf_assert.h"
+
+#define WR_OFFSET 0
+#define RD_OFFSET 1
+
+void nrf_ringbuf_init(nrf_ringbuf_t const * p_ringbuf)
+{
+ p_ringbuf->p_cb->wr_idx = 0;
+ p_ringbuf->p_cb->rd_idx = 0;
+ p_ringbuf->p_cb->tmp_rd_idx = 0;
+ p_ringbuf->p_cb->tmp_wr_idx = 0;
+ p_ringbuf->p_cb->rd_flag = 0;
+ p_ringbuf->p_cb->wr_flag = 0;
+}
+
+ret_code_t nrf_ringbuf_alloc(nrf_ringbuf_t const * p_ringbuf, uint8_t * * pp_data, size_t * p_length, bool start)
+{
+ ASSERT(pp_data);
+ ASSERT(p_length);
+
+ if (start)
+ {
+ if (nrf_atomic_flag_set_fetch(&p_ringbuf->p_cb->wr_flag))
+ {
+ return NRF_ERROR_BUSY;
+ }
+ }
+
+ if (p_ringbuf->p_cb->tmp_wr_idx - p_ringbuf->p_cb->rd_idx == p_ringbuf->bufsize_mask + 1)
+ {
+ *p_length = 0;
+ if (start)
+ {
+ UNUSED_RETURN_VALUE(nrf_atomic_flag_clear(&p_ringbuf->p_cb->wr_flag));
+ }
+ return NRF_SUCCESS;
+ }
+
+ uint32_t wr_idx = p_ringbuf->p_cb->tmp_wr_idx & p_ringbuf->bufsize_mask;
+ uint32_t rd_idx = p_ringbuf->p_cb->rd_idx & p_ringbuf->bufsize_mask;
+ uint32_t available = (wr_idx >= rd_idx) ? p_ringbuf->bufsize_mask + 1 - wr_idx :
+ p_ringbuf->p_cb->rd_idx - p_ringbuf->p_cb->tmp_wr_idx;
+ *p_length = *p_length < available ? *p_length : available;
+
+ *pp_data = &p_ringbuf->p_buffer[wr_idx];
+ p_ringbuf->p_cb->tmp_wr_idx += *p_length;
+
+ return NRF_SUCCESS;
+}
+
+ret_code_t nrf_ringbuf_put(nrf_ringbuf_t const * p_ringbuf, size_t length)
+{
+ uint32_t available = p_ringbuf->bufsize_mask + 1 -
+ (p_ringbuf->p_cb->wr_idx - p_ringbuf->p_cb->rd_idx);
+ if (length > available)
+ {
+ return NRF_ERROR_NO_MEM;
+ }
+
+ p_ringbuf->p_cb->wr_idx += length;
+ p_ringbuf->p_cb->tmp_wr_idx = p_ringbuf->p_cb->wr_idx;
+ if (nrf_atomic_flag_clear_fetch(&p_ringbuf->p_cb->wr_flag) == 0)
+ {
+ /* Flag was already cleared. Suggests misuse. */
+ return NRF_ERROR_INVALID_STATE;
+ }
+ return NRF_SUCCESS;
+}
+
+ret_code_t nrf_ringbuf_cpy_put(nrf_ringbuf_t const * p_ringbuf,
+ uint8_t const * p_data,
+ size_t * p_length)
+{
+ ASSERT(p_data);
+ ASSERT(p_length);
+
+ if (nrf_atomic_flag_set_fetch(&p_ringbuf->p_cb->wr_flag))
+ {
+ return NRF_ERROR_BUSY;
+ }
+
+ uint32_t available = p_ringbuf->bufsize_mask + 1 -
+ (p_ringbuf->p_cb->wr_idx - p_ringbuf->p_cb->rd_idx);
+ *p_length = available > *p_length ? *p_length : available;
+ size_t length = *p_length;
+ uint32_t masked_wr_idx = (p_ringbuf->p_cb->wr_idx & p_ringbuf->bufsize_mask);
+ uint32_t trail = p_ringbuf->bufsize_mask + 1 - masked_wr_idx;
+
+ if (length > trail)
+ {
+ memcpy(&p_ringbuf->p_buffer[masked_wr_idx], p_data, trail);
+ length -= trail;
+ masked_wr_idx = 0;
+ p_data += trail;
+ }
+ memcpy(&p_ringbuf->p_buffer[masked_wr_idx], p_data, length);
+ p_ringbuf->p_cb->wr_idx += *p_length;
+
+ UNUSED_RETURN_VALUE(nrf_atomic_flag_clear(&p_ringbuf->p_cb->wr_flag));
+
+ return NRF_SUCCESS;
+}
+
+ret_code_t nrf_ringbuf_get(nrf_ringbuf_t const * p_ringbuf, uint8_t * * pp_data, size_t * p_length, bool start)
+{
+ ASSERT(pp_data);
+ ASSERT(p_length);
+
+ if (start)
+ {
+ if (nrf_atomic_flag_set_fetch(&p_ringbuf->p_cb->rd_flag))
+ {
+ return NRF_ERROR_BUSY;
+ }
+ }
+
+ uint32_t available = p_ringbuf->p_cb->wr_idx - p_ringbuf->p_cb->tmp_rd_idx;
+ if (available == 0)
+ {
+ *p_length = 0;
+ if (start)
+ {
+ UNUSED_RETURN_VALUE(nrf_atomic_flag_clear(&p_ringbuf->p_cb->rd_flag));
+ }
+ return NRF_SUCCESS;
+ }
+
+ uint32_t masked_tmp_rd_idx = p_ringbuf->p_cb->tmp_rd_idx & p_ringbuf->bufsize_mask;
+ uint32_t masked_wr_idx = p_ringbuf->p_cb->wr_idx & p_ringbuf->bufsize_mask;
+
+ if ((masked_wr_idx > masked_tmp_rd_idx) && (available < *p_length))
+ {
+ *p_length = available;
+ }
+ else if (masked_wr_idx <= masked_tmp_rd_idx)
+ {
+ uint32_t trail = p_ringbuf->bufsize_mask + 1 - masked_tmp_rd_idx;
+ if (*p_length > trail)
+ {
+ *p_length = trail;
+ }
+ }
+ *pp_data = &p_ringbuf->p_buffer[masked_tmp_rd_idx];
+ p_ringbuf->p_cb->tmp_rd_idx += *p_length;
+
+ return NRF_SUCCESS;
+}
+
+ret_code_t nrf_ringbuf_cpy_get(nrf_ringbuf_t const * p_ringbuf,
+ uint8_t * p_data,
+ size_t * p_length)
+{
+ ASSERT(p_data);
+ ASSERT(p_length);
+
+ if (nrf_atomic_flag_set_fetch(&p_ringbuf->p_cb->rd_flag))
+ {
+ return NRF_ERROR_BUSY;
+ }
+
+ uint32_t available = p_ringbuf->p_cb->wr_idx - p_ringbuf->p_cb->rd_idx;
+ *p_length = available > *p_length ? *p_length : available;
+ size_t length = *p_length;
+ uint32_t masked_rd_idx = (p_ringbuf->p_cb->rd_idx & p_ringbuf->bufsize_mask);
+ uint32_t masked_wr_idx = (p_ringbuf->p_cb->wr_idx & p_ringbuf->bufsize_mask);
+ uint32_t trail = (masked_wr_idx > masked_rd_idx) ? masked_wr_idx - masked_rd_idx :
+ p_ringbuf->bufsize_mask + 1 - masked_rd_idx;
+
+ if (length > trail)
+ {
+ memcpy(&p_ringbuf->p_buffer[masked_rd_idx], p_data, trail);
+ length -= trail;
+ masked_rd_idx = 0;
+ p_data += trail;
+ }
+ memcpy(p_data, &p_ringbuf->p_buffer[masked_rd_idx], length);
+ p_ringbuf->p_cb->rd_idx += *p_length;
+
+ UNUSED_RETURN_VALUE(nrf_atomic_flag_clear(&p_ringbuf->p_cb->rd_flag));
+
+ return NRF_SUCCESS;
+}
+
+ret_code_t nrf_ringbuf_free(nrf_ringbuf_t const * p_ringbuf, size_t length)
+{
+ uint32_t available = (p_ringbuf->p_cb->wr_idx - p_ringbuf->p_cb->rd_idx);
+ if (length > available)
+ {
+ return NRF_ERROR_NO_MEM;
+ }
+
+ p_ringbuf->p_cb->rd_idx += length;
+ p_ringbuf->p_cb->tmp_rd_idx = p_ringbuf->p_cb->rd_idx;
+ UNUSED_RETURN_VALUE(nrf_atomic_flag_clear(&p_ringbuf->p_cb->rd_flag));
+
+ return NRF_SUCCESS;
+}
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/experimental_ringbuf/nrf_ringbuf.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/experimental_ringbuf/nrf_ringbuf.h
new file mode 100644
index 0000000..0da5c73
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/experimental_ringbuf/nrf_ringbuf.h
@@ -0,0 +1,206 @@
+/**
+ * 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#ifndef NRF_RINGBUF_H
+#define NRF_RINGBUF_H
+
+/**
+* @defgroup nrf_ringbuf Ring buffer
+* @{
+* @ingroup app_common
+* @brief Functions for controlling ring buffer.
+*/
+
+#include <stdint.h>
+#include "nrf_atomic.h"
+#include "sdk_errors.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+/**
+ * @brief ring buffer instance control block.
+ * */
+typedef struct
+{
+ nrf_atomic_flag_t wr_flag; //!< Protection flag.
+ nrf_atomic_flag_t rd_flag; //!< Protection flag.
+ uint32_t wr_idx; //!< Write index (updated when putting).
+ uint32_t tmp_wr_idx; //!< Temporary write index (updated when allocating).
+ uint32_t rd_idx; //!< Read index (updated when freeing).
+ uint32_t tmp_rd_idx; //!< Temporary read index (updated when getting).
+} nrf_ringbuf_cb_t;
+
+/**
+ * @brief ring buffer instance structure.
+ * */
+typedef struct
+{
+ uint8_t * p_buffer; //!< Pointer to memory used by the ring buffer.
+ uint32_t bufsize_mask; //!< Buffer size mask (buffer size must be power of 2).
+ nrf_ringbuf_cb_t * p_cb; //!< Pointer to instance control block.
+} nrf_ringbuf_t;
+
+/**
+ * @brief Macro for defining a ring buffer instance.
+ *
+ * @param _name Instance name.
+ * @param _size Size of ring buffer (must be power of 2).
+ * */
+#define NRF_RINGBUF_DEF(_name, _size) \
+ STATIC_ASSERT(IS_POWER_OF_TWO(_size)); \
+ static uint8_t CONCAT_2(_name,_buf)[_size]; \
+ static nrf_ringbuf_cb_t CONCAT_2(_name,_cb); \
+ static const nrf_ringbuf_t _name = { \
+ .p_buffer = CONCAT_2(_name,_buf), \
+ .bufsize_mask = _size - 1, \
+ .p_cb = &CONCAT_2(_name,_cb), \
+ }
+
+/**
+ * @brief Initializes a ring buffer instance.
+ *
+ * @param p_ringbuf Pointer to Ring buffer instance.
+ *
+ * */
+void nrf_ringbuf_init(nrf_ringbuf_t const * p_ringbuf);
+
+/**
+ * @brief Function for allocating memory from a ring buffer.
+ *
+ * Function attempts to allocate amount of memory requested by the user, or smaller amount if
+ * requested amount is not available. If start flag is set then exclusive access to allocation
+ * is established. @ref nrf_ringbuf_put frees access to allocation. If start flag is not set then
+ * exclusive access check is omitted.
+ *
+ * @param[in] p_ringbuf Pointer to Ring buffer instance.
+ * @param[in] pp_data Pointer to pointer to the allocated buffer.
+ * @param[in, out] p_length Pointer to length. Length is set to requested amount and filled
+ * by the function with actually allocated amount.
+ * @param[in] start Set to true if exclusive access should be controlled.
+ *
+ * @retval NRF_SUCCESS Successful allocation (can be smaller amount than requested).
+ * NRF_ERROR_BUSY Ring buffer allocation process (alloc-put) is ongoing.
+ *
+ * */
+ret_code_t nrf_ringbuf_alloc(nrf_ringbuf_t const * p_ringbuf, uint8_t * * pp_data, size_t * p_length, bool start);
+
+/**
+ * @brief Function for commiting data to a ring buffer.
+ *
+ * When allocated buffer (see @ref nrf_ringbuf_alloc) has been filled with data it must be committed
+ * to make it available for @ref nrf_ringbuf_get and @ref nrf_ringbuf_cpy_get. This function commits
+ * the data (can be smaller amount than allocated).
+ *
+ * @param[in] p_ringbuf Pointer to Ring buffer instance.
+ * @param[in] length Amount of bytes to put.
+
+ * @return NRF_SUCCESS on successful put or error.
+ * */
+ret_code_t nrf_ringbuf_put(nrf_ringbuf_t const * p_ringbuf, size_t length);
+
+/**
+ * @brief Function for copying data directly into the ring buffer.
+ *
+ * This function is copying user buffer to the ring buffer.
+ *
+ * @param[in] p_ringbuf Pointer to Ring buffer instance.
+ * @param[in] p_data Pointer to the input buffer.
+ * @param[in, out] p_length Amount of bytes to copy. Amount of bytes copied.
+
+ * @return NRF_SUCCESS on successful put or error.
+ * */
+ret_code_t nrf_ringbuf_cpy_put(nrf_ringbuf_t const * p_ringbuf,
+ uint8_t const* p_data,
+ size_t * p_length);
+
+
+/**
+ * Function for getting data from the ring buffer.
+ *
+ * Function attempts to get requested amount of data from the ring buffer. If start flag is set then
+ * exclusive access to getting data from the ring buffer is established. @ref nrf_ringbuf_free frees
+ * access to getting data from the ring buffer. If start flag is not set then
+ * exclusive access check is omitted.
+ *
+ * @param[in] p_ringbuf Pointer to Ring buffer instance.
+ * @param[in] pp_data Pointer to pointer to the buffer with data.
+ * @param[in, out] p_length Pointer to length. Length is set to requested amount and filled
+ * by the function with actual amount.
+ * @param[in] start Set to true if exclusive access should be controlled.
+ *
+ * @retval NRF_SUCCESS Successful getting (can be smaller amount than requested).
+ * NRF_ERROR_BUSY Ring buffer getting process (get-free) is ongoing.
+ */
+ret_code_t nrf_ringbuf_get(nrf_ringbuf_t const * p_ringbuf, uint8_t * * pp_data, size_t * p_length, bool start);
+
+/**
+ * @brief Function for freeing buffer back to a ring buffer.
+ *
+ * When buffer with data taken from the ring buffer (see @ref nrf_ringbuf_get) has been processed it
+ * must be freed to make it available for further use. This function frees the buffer (can be smaller
+ * amount than get).
+ *
+ * @param[in] p_ringbuf Pointer to Ring buffer instance.
+ * @param[in] length Amount of bytes to free.
+
+ * @return NRF_SUCCESS on successful put or error.
+ * */
+ret_code_t nrf_ringbuf_free(nrf_ringbuf_t const * p_ringbuf, size_t length);
+
+/**
+ * @brief Function for copying data directly out of the ring buffer.
+ *
+ * This function is copying available data from the ring buffer to user buffer.
+ *
+ * @param[in] p_ringbuf Pointer to Ring buffer instance.
+ * @param[in] p_data Pointer to the input buffer.
+ * @param[in, out] p_length Amount of bytes to copy. Amount of bytes copied.
+
+ * @return NRF_SUCCESS on successful put or error.
+ * */
+ret_code_t nrf_ringbuf_cpy_get(nrf_ringbuf_t const * p_ringbuf,
+ uint8_t * p_data,
+ size_t * p_length);
+#ifdef __cplusplus
+}
+#endif
+
+#endif //NRF_RINGBUF_H
+/** @} */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/experimental_section_vars/nrf_section.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/experimental_section_vars/nrf_section.h
new file mode 100644
index 0000000..62eda64
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/experimental_section_vars/nrf_section.h
@@ -0,0 +1,191 @@
+/**
+ * Copyright (c) 2016 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#ifndef NRF_SECTION_H__
+#define NRF_SECTION_H__
+
+#include "nordic_common.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @defgroup section_vars Section variables
+ * @ingroup app_common
+ * @{
+ *
+ * @brief Section variables.
+ */
+
+//lint -save -e27 -esym(526,*)
+
+#if defined(__ICCARM__)
+// Enable IAR language extensions
+#pragma language=extended
+#endif
+
+/**@brief Macro for obtaining the address of the beginning of a section.
+ *
+ * param[in] section_name Name of the section.
+ * @hideinitializer
+ */
+#if defined(__CC_ARM)
+#define NRF_SECTION_START_ADDR(section_name) &CONCAT_2(section_name, $$Base)
+
+#elif defined(__GNUC__)
+#define NRF_SECTION_START_ADDR(section_name) &CONCAT_2(__start_, section_name)
+
+#elif defined(__ICCARM__)
+#define NRF_SECTION_START_ADDR(section_name) __section_begin(STRINGIFY(section_name))
+#endif
+
+
+/**@brief Macro for obtaining the address of the end of a section.
+ *
+ * @param[in] section_name Name of the section.
+ * @hideinitializer
+ */
+#if defined(__CC_ARM)
+#define NRF_SECTION_END_ADDR(section_name) &CONCAT_2(section_name, $$Limit)
+
+#elif defined(__GNUC__)
+#define NRF_SECTION_END_ADDR(section_name) &CONCAT_2(__stop_, section_name)
+
+#elif defined(__ICCARM__)
+#define NRF_SECTION_END_ADDR(section_name) __section_end(STRINGIFY(section_name))
+#endif
+
+
+/**@brief Macro for retrieving the length of a given section, in bytes.
+ *
+ * @param[in] section_name Name of the section.
+ * @hideinitializer
+ */
+#define NRF_SECTION_LENGTH(section_name) \
+ ((size_t)NRF_SECTION_END_ADDR(section_name) - \
+ (size_t)NRF_SECTION_START_ADDR(section_name))
+
+
+/**@brief Macro for creating a section.
+ *
+ * @param[in] section_name Name of the section.
+ * @param[in] data_type Data type of the variables to be registered in the section.
+ *
+ * @warning Data type must be word aligned to prevent padding.
+ * @hideinitializer
+ */
+#if defined(__CC_ARM)
+#define NRF_SECTION_DEF(section_name, data_type) \
+ extern data_type * CONCAT_2(section_name, $$Base); \
+ extern void * CONCAT_2(section_name, $$Limit)
+
+#elif defined(__GNUC__)
+#define NRF_SECTION_DEF(section_name, data_type) \
+ extern data_type * CONCAT_2(__start_, section_name); \
+ extern void * CONCAT_2(__stop_, section_name)
+
+#elif defined(__ICCARM__)
+#define NRF_SECTION_DEF(section_name, data_type) \
+ _Pragma(STRINGIFY(section = STRINGIFY(section_name)));
+
+#endif
+
+
+/**@brief Macro for declaring a variable and registering it in a section.
+ *
+ * @details Declares a variable and registers it in a named section. This macro ensures that the
+ * variable is not stripped away when using optimizations.
+ *
+ * @note The order in which variables are placed in a section is dependent on the order in
+ * which the linker script encounters the variables during linking.
+ *
+ * @param[in] section_name Name of the section.
+ * @param[in] section_var Variable to register in the given section.
+ * @hideinitializer
+ */
+#if defined(__CC_ARM)
+#define NRF_SECTION_ITEM_REGISTER(section_name, section_var) \
+ section_var __attribute__ ((section(STRINGIFY(section_name)))) __attribute__((used))
+
+#elif defined(__GNUC__)
+#define NRF_SECTION_ITEM_REGISTER(section_name, section_var) \
+ section_var __attribute__ ((section("." STRINGIFY(section_name)))) __attribute__((used))
+
+#elif defined(__ICCARM__)
+#define NRF_SECTION_ITEM_REGISTER(section_name, section_var) \
+ __root section_var @ STRINGIFY(section_name)
+#endif
+
+
+/**@brief Macro for retrieving a variable from a section.
+ *
+ * @warning The stored symbol can only be resolved using this macro if the
+ * type of the data is word aligned. The operation of acquiring
+ * the stored symbol relies on the size of the stored type. No
+ * padding can exist in the named section in between individual
+ * stored items or this macro will fail.
+ *
+ * @param[in] section_name Name of the section.
+ * @param[in] data_type Data type of the variable.
+ * @param[in] i Index of the variable in section.
+ * @hideinitializer
+ */
+#define NRF_SECTION_ITEM_GET(section_name, data_type, i) \
+ ((data_type*)NRF_SECTION_START_ADDR(section_name) + (i))
+
+
+/**@brief Macro for getting the number of variables in a section.
+ *
+ * @param[in] section_name Name of the section.
+ * @param[in] data_type Data type of the variables in the section.
+ * @hideinitializer
+ */
+#define NRF_SECTION_ITEM_COUNT(section_name, data_type) \
+ NRF_SECTION_LENGTH(section_name) / sizeof(data_type)
+
+/** @} */
+
+//lint -restore
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // NRF_SECTION_H__
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/experimental_section_vars/nrf_section_iter.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/experimental_section_vars/nrf_section_iter.c
new file mode 100644
index 0000000..ea8b02f
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/experimental_section_vars/nrf_section_iter.c
@@ -0,0 +1,125 @@
+/**
+ * Copyright (c) 2016 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+
+#include "sdk_common.h"
+
+#if NRF_MODULE_ENABLED(NRF_SECTION_ITER)
+
+#include "nrf_section_iter.h"
+
+
+#if !defined(__GNUC__)
+static void nrf_section_iter_item_set(nrf_section_iter_t * p_iter)
+{
+ ASSERT(p_iter != NULL);
+ ASSERT(p_iter->p_set != NULL);
+ ASSERT(p_iter->p_section != NULL);
+
+ while (true)
+ {
+ if (p_iter->p_section == p_iter->p_set->p_last)
+ {
+ // End of the section set.
+ p_iter->p_item = NULL;
+ return;
+ }
+
+ if (p_iter->p_section->p_start != p_iter->p_section->p_end)
+ {
+ // Not empty section.
+ p_iter->p_item = p_iter->p_section->p_start;
+ return;
+ }
+
+ // Next section.
+ p_iter->p_section++;
+ }
+}
+#endif
+
+
+void nrf_section_iter_init(nrf_section_iter_t * p_iter, nrf_section_set_t const * p_set)
+{
+ ASSERT(p_iter != NULL);
+ ASSERT(p_set != NULL);
+
+ p_iter->p_set = p_set;
+
+#if defined(__GNUC__)
+ p_iter->p_item = p_iter->p_set->section.p_start;
+ if (p_iter->p_item == p_iter->p_set->section.p_end)
+ {
+ p_iter->p_item = NULL;
+ }
+#else
+ p_iter->p_section = p_set->p_first;
+ nrf_section_iter_item_set(p_iter);
+#endif
+}
+
+void nrf_section_iter_next(nrf_section_iter_t * p_iter)
+{
+ ASSERT(p_iter != NULL);
+ ASSERT(p_iter->p_set != NULL);
+
+ if (p_iter->p_item == NULL)
+ {
+ return;
+ }
+
+ p_iter->p_item = (void *)((size_t)(p_iter->p_item) + p_iter->p_set->item_size);
+
+#if defined(__GNUC__)
+ if (p_iter->p_item == p_iter->p_set->section.p_end)
+ {
+ p_iter->p_item = NULL;
+ }
+#else
+ ASSERT(p_iter->p_section != NULL);
+ // End of current section reached?
+ if (p_iter->p_item == p_iter->p_section->p_end)
+ {
+ p_iter->p_section++;
+ nrf_section_iter_item_set(p_iter);
+ }
+#endif
+}
+
+#endif // NRF_MODULE_ENABLED(NRF_SECTION_ITER)
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/experimental_section_vars/nrf_section_iter.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/experimental_section_vars/nrf_section_iter.h
new file mode 100644
index 0000000..2f9be61
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/experimental_section_vars/nrf_section_iter.h
@@ -0,0 +1,206 @@
+/**
+ * Copyright (c) 2016 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+
+#ifndef NRF_SECTION_ITER_H__
+#define NRF_SECTION_ITER_H__
+
+#include <stddef.h>
+#include "nrf_section.h"
+#include "nrf_assert.h"
+#include "app_util.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+/**
+ * @defgroup nrf_section_iter Section variables iterator
+ * @ingroup app_common
+ * @{
+ */
+
+/**@brief Single section description structure. */
+typedef struct
+{
+ void * p_start; //!< Pointer to the start of section.
+ void * p_end; //!< Pointer to the end of section.
+} nrf_section_t;
+
+
+/**@brief Set of the sections description structure. */
+typedef struct
+{
+#if defined(__GNUC__)
+ nrf_section_t section; //!< Description of the set of sections.
+ /**<
+ * In case of GCC all sections in the set are sorted and
+ * placed in contiguous area, because they are treated as
+ * one section.
+ */
+#else
+ nrf_section_t const * p_first; //!< Pointer to the first section in the set.
+ nrf_section_t const * p_last; //!< Pointer to the last section in the set.
+#endif
+ size_t item_size; //!< Size of the single item in the section.
+} nrf_section_set_t;
+
+
+/**@brief Section iterator structure. */
+typedef struct
+{
+ nrf_section_set_t const * p_set; //!< Pointer to the appropriate section set.
+#if !defined(__GNUC__)
+ nrf_section_t const * p_section; //!< Pointer to the selected section.
+ /**<
+ * In case of GCC all sections in the set are sorted and
+ * placed in contiguous area, because they are treated
+ * as one section.
+ */
+#endif
+ void * p_item; //!< Pointer to the selected item in the section.
+} nrf_section_iter_t;
+
+
+/**@brief Create a set of sections.
+ *
+ * @note This macro reserves memory for the given set of sections.
+ *
+ * @details A set of sections, is an ordered collections of sections.
+ *
+ * @param[in] _name Name of the set.
+ * @param[in] _type Type of the elements stored in the sections.
+ * @param[in] _count Number of the sections in the set. This parameter is ignored in case of GCC.
+ * @hideinitializer
+ */
+#if defined(__GNUC__)
+
+#define NRF_SECTION_SET_DEF(_name, _type, _count) \
+ \
+ NRF_SECTION_DEF(_name, _type); \
+ static nrf_section_set_t const _name = \
+ { \
+ .section = \
+ { \
+ .p_start = NRF_SECTION_START_ADDR(_name), \
+ .p_end = NRF_SECTION_END_ADDR(_name), \
+ }, \
+ .item_size = sizeof(_type), \
+ }
+
+#else
+
+#define NRF_SECTION_SET_DEF(_name, _type, _count) \
+/*lint -save -emacro(14, MACRO_REPEAT_FOR*) */ \
+MACRO_REPEAT_FOR(_count, NRF_SECTION_DEF_, _name, _type) \
+static nrf_section_t const CONCAT_2(_name, _array)[] = \
+{ \
+ MACRO_REPEAT_FOR(_count, NRF_SECTION_SET_DEF_, _name) \
+}; \
+/*lint -restore */ \
+static nrf_section_set_t const _name = \
+{ \
+ .p_first = CONCAT_2(_name, _array), \
+ .p_last = CONCAT_2(_name, _array) + ARRAY_SIZE(CONCAT_2(_name, _array)), \
+ .item_size = sizeof(_type), \
+}
+
+#ifndef DOXYGEN
+#define NRF_SECTION_DEF_(_priority, _name, _type) \
+NRF_SECTION_DEF(CONCAT_2(_name, _priority), _type);
+
+#define NRF_SECTION_SET_DEF_(_priority, _name) \
+{ \
+ .p_start = NRF_SECTION_START_ADDR(CONCAT_2(_name, _priority)), \
+ .p_end = NRF_SECTION_END_ADDR(CONCAT_2(_name, _priority)), \
+},
+#endif // DOXYGEN
+#endif // __GNUC__
+
+
+/**@brief Macro to declare a variable and register it in the section set.
+ *
+ * @note The order of the section in the set is based on the priority. The order with which
+ * variables are placed in a section is dependant on the order with which the linker
+ * encouters the variables during linking.
+ *
+ * @param[in] _name Name of the section set.
+ * @param[in] _priority Priority of the desired section.
+ * @param[in] _var The variable to register in the given section.
+ * @hideinitializer
+ */
+#define NRF_SECTION_SET_ITEM_REGISTER(_name, _priority, _var) \
+ NRF_SECTION_ITEM_REGISTER(CONCAT_2(_name, _priority), _var)
+
+
+/**@brief Function for initializing the section set iterator.
+ *
+ * @param[in] p_iter Pointer to the iterator.
+ * @param[in] p_set Pointer to the sections set.
+ */
+void nrf_section_iter_init(nrf_section_iter_t * p_iter, nrf_section_set_t const * p_set);
+
+
+/**@brief Function for incrementing iterator.
+ *
+ * @param[in] p_iter Pointer to the iterator.
+ */
+void nrf_section_iter_next(nrf_section_iter_t * p_iter);
+
+
+/**@brief Function for getting the element pointed to by the iterator.
+ *
+ * @param[in] p_iter Pointer to the iterator.
+ *
+ * @retval Pointer to the element or NULL if iterator points end of the set.
+ */
+static inline void * nrf_section_iter_get(nrf_section_iter_t const * p_iter)
+{
+ ASSERT(p_iter);
+ return p_iter->p_item;
+}
+
+/** @} */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // NRF_SECTION_ITER_H__
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/experimental_stack_guard/nrf_stack_guard.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/experimental_stack_guard/nrf_stack_guard.c
new file mode 100644
index 0000000..344da2f
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/experimental_stack_guard/nrf_stack_guard.c
@@ -0,0 +1,92 @@
+/**
+ * Copyright (c) 2016 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+
+#include <stdint.h>
+#include "nrf.h"
+#include "nrf_assert.h"
+#include "nrf_strerror.h"
+#include "nrf_mpu.h"
+#include "nrf_stack_guard.h"
+
+#define NRF_LOG_MODULE_NAME stack_guard
+
+#if NRF_STACK_GUARD_CONFIG_LOG_ENABLED
+#define NRF_LOG_LEVEL NRF_STACK_GUARD_CONFIG_LOG_LEVEL
+#define NRF_LOG_INFO_COLOR NRF_STACK_GUARD_CONFIG_INFO_COLOR
+#define NRF_LOG_DEBUG_COLOR NRF_STACK_GUARD_CONFIG_DEBUG_COLOR
+#endif
+#include "nrf_log.h"
+NRF_LOG_MODULE_REGISTER();
+
+#if NRF_STACK_GUARD_ENABLED
+STATIC_ASSERT(STACK_GUARD_SIZE >= 32);
+
+ret_code_t nrf_stack_guard_init(void)
+{
+ nrf_mpu_region_t region;
+ uint32_t attributes;
+ ret_code_t status;
+
+ ASSERT((STACK_GUARD_BASE + STACK_GUARD_SIZE) < (uint32_t)((void *)(STACK_TOP)));
+
+ attributes = (0x05 << MPU_RASR_TEX_Pos) | (1 << MPU_RASR_B_Pos) | /* Normal memory, WBWA/WBWA */
+ (0x07 << MPU_RASR_AP_Pos) | (1 << MPU_RASR_XN_Pos); /* Access: RO/RO, XN */
+
+ status = nrf_mpu_region_create(&region,
+ (void *)(STACK_GUARD_BASE),
+ STACK_GUARD_SIZE,
+ attributes);
+
+ if (status == NRF_SUCCESS)
+ {
+ NRF_LOG_INFO("Stack Guard: 0x%08X-0x%08X (usable stack area: %u bytes)",
+ STACK_GUARD_BASE,
+ STACK_GUARD_BASE + STACK_GUARD_SIZE - 1,
+ REAL_STACK_SIZE);
+ }
+ else
+ {
+ NRF_LOG_ERROR("Cannot create stack guard page! Error: %u [%s]", status, (uint32_t)nrf_strerror_get(status));
+ }
+
+ return status;
+}
+
+#endif /* NRF_STACK_GUARD_ENABLED */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/experimental_stack_guard/nrf_stack_guard.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/experimental_stack_guard/nrf_stack_guard.h
new file mode 100644
index 0000000..d5f9f18
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/experimental_stack_guard/nrf_stack_guard.h
@@ -0,0 +1,80 @@
+/**
+ * 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+
+#ifndef __NRF_STACK_GUARD_H__
+#define __NRF_STACK_GUARD_H__
+
+/**
+* @defgroup nrf_stack_guard Stack guard
+* @{
+* @ingroup app_common
+* @brief Functions for enabling stack violation control
+*/
+#include "sdk_config.h"
+#include "app_util.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#if NRF_STACK_GUARD_ENABLED
+#define STACK_GUARD_SIZE (1ul << NRF_STACK_GUARD_CONFIG_SIZE)
+#define STACK_GUARD_BASE (((uint32_t)((void *)(STACK_BASE)) + STACK_GUARD_SIZE - 1) \
+ & ~(STACK_GUARD_SIZE - 1))
+#define REAL_STACK_SIZE (((int32_t)(STACK_TOP)) - (int32_t)(STACK_GUARD_BASE + STACK_GUARD_SIZE))
+#else /* !NRF_STACK_GUARD_ENABLED */
+#define REAL_STACK_SIZE (((int32_t)(STACK_TOP)) - (int32_t)((void *)(STACK_BASE)))
+#endif /* NRF_STACK_GUARD_ENABLED */
+
+/**@brief Initialize Stack Guard Page */
+ret_code_t nrf_stack_guard_init(void);
+
+#if NRF_STACK_GUARD_ENABLED
+#define NRF_STACK_GUARD_INIT() nrf_stack_guard_init()
+#else
+#define NRF_STACK_GUARD_INIT() NRF_SUCCESS
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif //__NRF_STACK_GUARD_H__
+/** @} */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/experimental_task_manager/task_manager.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/experimental_task_manager/task_manager.c
new file mode 100644
index 0000000..d61497b
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/experimental_task_manager/task_manager.c
@@ -0,0 +1,543 @@
+/**
+ * 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#include "sdk_common.h"
+#if NRF_MODULE_ENABLED(TASK_MANAGER)
+#include "nrf_mpu.h"
+#include "nrf_atomic.h"
+#include "app_util_platform.h"
+#include "task_manager.h"
+
+#if TASK_MANAGER_CLI_CMDS
+#include "nrf_cli.h"
+#endif
+
+#define NRF_LOG_MODULE_NAME task_manager
+
+#if TASK_MANAGER_CONFIG_LOG_ENABLED
+#define NRF_LOG_LEVEL TASK_MANAGER_CONFIG_LOG_LEVEL
+#define NRF_LOG_INFO_COLOR TASK_MANAGER_CONFIG_INFO_COLOR
+#define NRF_LOG_DEBUG_COLOR TASK_MANAGER_CONFIG_DEBUG_COLOR
+#endif
+#include "nrf_log.h"
+NRF_LOG_MODULE_REGISTER();
+
+#if TASK_MANAGER_CONFIG_STACK_GUARD
+#define STACK_GUARD_SIZE (1 << (TASK_MANAGER_CONFIG_STACK_GUARD + 1))
+STATIC_ASSERT((TASK_MANAGER_CONFIG_STACK_SIZE % STACK_GUARD_SIZE) == 0);
+#endif
+
+STATIC_ASSERT((TASK_MANAGER_CONFIG_MAX_TASKS) > 0);
+STATIC_ASSERT((TASK_MANAGER_CONFIG_STACK_SIZE % 8) == 0);
+
+// Support older CMSIS avaiable in Keil 4
+#if (__CORTEX_M == 4)
+# ifndef CONTROL_FPCA_Pos
+# define CONTROL_FPCA_Pos 2u
+# define CONTROL_FPCA_Msk (1ul << CONTROL_FPCA_Pos)
+# endif
+
+# ifndef CONTROL_SPSEL_Pos
+# define CONTROL_SPSEL_Pos 1u
+# define CONTROL_SPSEL_Msk (1ul << CONTROL_SPSEL_Pos)
+# endif
+#endif
+
+/*lint -save -esym(526,task_switch)*/
+// Declare task switching function.
+extern void task_switch(void);
+/*lint -restore*/
+
+/**@brief Idle Task ID */
+#define IDLE_TASK_ID TASK_MANAGER_CONFIG_MAX_TASKS
+#define TASK_STACK_MAGIC_WORD 0xDEADD00E
+#define TASK_FLAG_SIGNAL_MASK 0x00FFFFFF
+#define TASK_FLAG_DESTROY 0x80000000
+
+/** @brief Total number of tasks includes user configuration and idle task. */
+#define TOTAL_NUM_OF_TASKS (TASK_MANAGER_CONFIG_MAX_TASKS + 1)
+
+/**@brief Task stack with saved task state (does not include FPU state). */
+typedef struct
+{
+ uint32_t r0;
+ uint32_t r4;
+ uint32_t r5;
+ uint32_t r6;
+ uint32_t r7;
+ uint32_t r8;
+ uint32_t r9;
+ uint32_t r10;
+ uint32_t r11;
+ uint32_t r12;
+ uint32_t lr;
+ uint32_t control;
+} task_stack_t;
+
+/**@brief Task State */
+typedef struct
+{
+ void *p_stack; /**< Pointer to task stack. NULL if task does not exist. */
+ const char *p_task_name;
+ nrf_atomic_u32_t flags; /**< Task flags */
+} task_state_t;
+
+/* Allocate space for task stacks:
+ *
+ * Layout:
+ * +---------------+
+ * | Idle Task |
+ * +---------------+
+ * | Stack Guard |
+ * +---------------+
+ * | Task N |
+ * +---------------+
+ * | Stack Guard |
+ * +---------------+
+ * | ... |
+ * +---------------+
+ * | Task 0 |
+ * +---------------+
+ * | Stack Guard |
+ * +---------------+
+ */
+
+typedef struct
+{
+#if TASK_MANAGER_CONFIG_STACK_GUARD
+ uint8_t guard[STACK_GUARD_SIZE];
+#endif
+ uint8_t stack[TASK_MANAGER_CONFIG_STACK_SIZE];
+} task_manager_stack_t;
+
+/**@brief Stack space for tasks */
+#if TASK_MANAGER_CONFIG_STACK_GUARD
+/**@brief Handle to MPU region used as a guard */
+static nrf_mpu_region_t s_guard_region;
+__ALIGN(STACK_GUARD_SIZE)
+#else
+__ALIGN(8)
+#endif
+static task_manager_stack_t s_task_stacks[TOTAL_NUM_OF_TASKS];
+
+/**@brief Task States
+ * Addtional state reserved for idle task which is mandatory.
+ * */
+static task_state_t s_task_state[TOTAL_NUM_OF_TASKS];
+
+/**@brief Mask indicating which tasks are runnable */
+static nrf_atomic_u32_t s_runnable_tasks_mask;
+
+/**@brief ID of currently executed task */
+static task_id_t s_current_task_id;
+
+/**@brief Guard page attributes: Normal memory, WBWA/WBWA, RO/RO, XN */
+#define TASK_GUARD_ATTRIBUTES ((0x05 << MPU_RASR_TEX_Pos) | (1 << MPU_RASR_B_Pos) | \
+ (0x07 << MPU_RASR_AP_Pos) | (1 << MPU_RASR_XN_Pos))
+
+
+/**@brief Macro for getting pointer to bottom of stack for given task id */
+#define BOTTOM_OF_TASK_STACK(_task_id) ((void *)(&s_task_stacks[(_task_id)].stack[0]))
+
+/**@brief Macro for getting pointer to top of stack for given task id */
+#define TOP_OF_TASK_STACK(_task_id) ((void *)(&s_task_stacks[(_task_id)].stack[TASK_MANAGER_CONFIG_STACK_SIZE]))
+
+/**@brief Macro for getting pointer to base of stack guard for given task id */
+#define TASK_STACK_GUARD_BASE(_task_id) ((void *)(&s_task_stacks[(_task_id)].guard[0]))
+
+#define TASK_ID_TO_MASK(_task_id) (0x80000000 >> (_task_id))
+
+/**@brief Puts task in RUNNABLE state */
+#define TASK_STATE_RUNNABLE(_task_id) \
+ (void)nrf_atomic_u32_or(&s_runnable_tasks_mask, TASK_ID_TO_MASK(_task_id))
+
+/**@brief Puts task in SUSPENDED state */
+#define TASK_STATE_SUSPENDED(_task_id) \
+ (void)nrf_atomic_u32_and(&s_runnable_tasks_mask, ~TASK_ID_TO_MASK(_task_id));
+
+static void task_stack_poison(task_id_t task_id)
+{
+#if TASK_MANAGER_CONFIG_STACK_PROFILER_ENABLED
+ unsigned int i = TASK_MANAGER_CONFIG_STACK_SIZE / sizeof(uint32_t);
+ uint32_t *p_stack_top = TOP_OF_TASK_STACK(task_id);
+
+ while (i--)
+ {
+ *(--p_stack_top) = TASK_STACK_MAGIC_WORD;
+ }
+#endif
+}
+
+static void task_stack_protect(task_id_t task_id)
+{
+#if TASK_MANAGER_CONFIG_STACK_GUARD
+ APP_ERROR_CHECK(nrf_mpu_region_create(&s_guard_region,
+ TASK_STACK_GUARD_BASE(task_id),
+ STACK_GUARD_SIZE,
+ TASK_GUARD_ATTRIBUTES));
+#endif
+}
+
+PRAGMA_OPTIMIZATION_FORCE_START
+void task_manager_start(task_main_t idle_task, void *p_idle_task_context)
+{
+ unsigned long control;
+
+ // Idle task must be specified.
+ ASSERT(idle_task != NULL);
+
+ // Make sure that we are in privledged thread level using MSP stack.
+ ASSERT((__get_IPSR() & IPSR_ISR_Msk) == 0);
+ ASSERT((__get_CONTROL() & CONTROL_nPRIV_Msk) == 0);
+ ASSERT((__get_CONTROL() & CONTROL_SPSEL_Msk) == 0);
+
+ // Prepare task state structure.
+ s_current_task_id = IDLE_TASK_ID;
+ s_task_state[s_current_task_id].p_task_name = "Idle Task";
+
+ // Prepare stack instrumentation and protection.
+ task_stack_poison(s_current_task_id);
+ task_stack_protect(s_current_task_id);
+
+ NRF_LOG_INFO("Task %u created (name: '%s', stack: 0x%08X-0x%08X).",
+ s_current_task_id,
+ s_task_state[s_current_task_id].p_task_name,
+ (uint32_t)BOTTOM_OF_TASK_STACK(s_current_task_id),
+ (uint32_t)TOP_OF_TASK_STACK(s_current_task_id) - 1);
+
+ // Prepare context for idle task. This must be done with all interrupts disabled.
+ __disable_irq();
+
+ // Set process and exception stacks.
+ __set_PSP((uint32_t)(TOP_OF_TASK_STACK(s_current_task_id)));
+ __set_MSP((uint32_t)(STACK_TOP));
+
+ // Update CONTROL register.
+ control = __get_CONTROL();
+ control &= CONTROL_FPCA_Msk; // Clear FPCA since FPU state does not need to be preserved.
+ control |= CONTROL_SPSEL_Msk; // Use MSP only for excpetions, leaving PSP for tasks.
+ __set_CONTROL(control);
+
+ // Context is ready. Enable interrupts.
+ __enable_irq();
+
+ // Perform task switch to run non-idle tasks as soon as possible.
+ task_switch();
+
+ // Jump to idle task.
+ idle_task(p_idle_task_context);
+
+ // This should be never reached.
+ APP_ERROR_CHECK_BOOL(false);
+}
+PRAGMA_OPTIMIZATION_FORCE_END
+
+task_id_t task_create(task_main_t task, char const * p_task_name, void *p_context)
+{
+ task_state_t *p_state = NULL;
+ task_stack_t *p_stack;
+ task_id_t task_id;
+
+ // Check arguments.
+ if (task == NULL)
+ {
+ return TASK_ID_INVALID;
+ }
+
+ // Find free task state structure.
+ CRITICAL_REGION_ENTER();
+ for (task_id = 0; task_id < TASK_MANAGER_CONFIG_MAX_TASKS; task_id++)
+ {
+ if (s_task_state[task_id].p_stack == NULL)
+ {
+ p_state = &s_task_state[task_id];
+ p_state->p_stack = TOP_OF_TASK_STACK(task_id);
+ break;
+ }
+ }
+ CRITICAL_REGION_EXIT();
+
+ // Return invalid Task ID if new task cannot be created.
+ if (p_state == NULL)
+ {
+ return TASK_ID_INVALID;
+ }
+
+ // Prepare initial stack for the task.
+ task_stack_poison(task_id);
+
+ p_state->p_stack = (uint8_t *)(p_state->p_stack) - sizeof(*p_stack);
+ p_state->p_task_name = (char *)p_task_name;
+ p_state->flags = 0;
+
+ p_stack = p_state->p_stack;
+
+ p_stack->control = CONTROL_SPSEL_Msk;
+ p_stack->lr = (uint32_t)(task); // Start from this function.
+ p_stack->r0 = (uint32_t)(p_context); // Pass p_context as first argument.
+
+ // Mark task as ready to run.
+ TASK_STATE_RUNNABLE(task_id);
+
+ NRF_LOG_INFO("Task %u created (name: '%s', stack: 0x%08X-0x%08X).",
+ task_id,
+ p_task_name,
+ (uint32_t)BOTTOM_OF_TASK_STACK(task_id),
+ (uint32_t)TOP_OF_TASK_STACK(task_id) - 1);
+
+ return task_id;
+}
+
+/**@brief Task scheduler.
+ *
+ * @param[in] Pointer to task stack with saved task state.
+ * @return Pointer to new task stack with saved task state.
+ */
+void *task_schedule(void *p_stack)
+{
+ uint32_t runnable_tasks_mask;
+
+#if TASK_MANAGER_CONFIG_STACK_GUARD
+ // Destroy stack guard allocated for current task.
+ APP_ERROR_CHECK(nrf_mpu_region_destroy(s_guard_region));
+#endif
+
+ // Save current task state if task if switching from valid task.
+ if ((s_task_state[s_current_task_id].flags & TASK_FLAG_DESTROY) == 0)
+ {
+ s_task_state[s_current_task_id].p_stack = p_stack;
+ }
+ else
+ {
+ TASK_STATE_SUSPENDED(s_current_task_id);
+ s_task_state[s_current_task_id].p_stack = NULL;
+
+ NRF_LOG_INFO("Task %u terminated (name: '%s').",
+ s_current_task_id,
+ s_task_state[s_current_task_id].p_task_name);
+ }
+
+ // Atomically fetch list of runnable tasks.
+ runnable_tasks_mask = s_runnable_tasks_mask;
+
+ // Check if there are any tasks to execute.
+ if (runnable_tasks_mask != 0)
+ {
+ // Check if we could continue this round.
+ if ((runnable_tasks_mask << (s_current_task_id + 1)) != 0)
+ {
+ // There are tasks to execute in this round. Select next runnable task:
+ s_current_task_id += 1 + __CLZ((runnable_tasks_mask << (s_current_task_id + 1)));
+ }
+ else
+ {
+ // No more tasks in this round. Select first avaiable task:
+ s_current_task_id = __CLZ(runnable_tasks_mask);
+ }
+ }
+ else
+ {
+ // Fall back to idle task if other tasks cannot be run.
+ s_current_task_id = IDLE_TASK_ID;
+ }
+
+ task_stack_protect(s_current_task_id);
+
+ // Switch to new task.
+ return s_task_state[s_current_task_id].p_stack;
+}
+
+void task_yield(void)
+{
+ // Make sure that we are in privledged thread level using PSP stack.
+ ASSERT((__get_IPSR() & IPSR_ISR_Msk) == 0);
+ ASSERT((__get_CONTROL() & CONTROL_nPRIV_Msk) == 0);
+ ASSERT((__get_CONTROL() & CONTROL_SPSEL_Msk) != 0);
+
+ // Perform task switch.
+ task_switch();
+}
+
+uint32_t task_events_wait(uint32_t evt_mask)
+{
+ uint32_t current_events;
+
+ ASSERT((evt_mask & ~TASK_FLAG_SIGNAL_MASK) == 0);
+
+ for (;;)
+ {
+ current_events = s_task_state[s_current_task_id].flags & evt_mask;
+ if (current_events != 0)
+ {
+ (void)nrf_atomic_u32_and(&s_task_state[s_current_task_id].flags, ~current_events);
+ break;
+ }
+
+ TASK_STATE_SUSPENDED(s_current_task_id);
+ task_yield();
+ }
+
+ return current_events;
+}
+
+void task_events_set(task_id_t task_id, uint32_t evt_mask)
+{
+ ASSERT((task_id != TASK_ID_INVALID) && (task_id < TASK_MANAGER_CONFIG_MAX_TASKS));
+ ASSERT((evt_mask & ~TASK_FLAG_SIGNAL_MASK) == 0);
+ ASSERT(s_task_state[task_id].p_stack != NULL);
+
+ (void)nrf_atomic_u32_or(&s_task_state[task_id].flags, evt_mask);
+ TASK_STATE_RUNNABLE(task_id);
+}
+
+void task_exit(void)
+{
+ // Make sure that we are in privledged thread level using PSP stack.
+ ASSERT((__get_IPSR() & IPSR_ISR_Msk) == 0);
+ ASSERT((__get_CONTROL() & CONTROL_nPRIV_Msk) == 0);
+ ASSERT((__get_CONTROL() & CONTROL_SPSEL_Msk) != 0);
+
+ s_task_state[s_current_task_id].flags = TASK_FLAG_DESTROY;
+ task_switch();
+}
+
+task_id_t task_id_get(void)
+{
+ // Make sure that we are in privledged thread level using PSP stack.
+ ASSERT((__get_IPSR() & IPSR_ISR_Msk) == 0);
+ ASSERT((__get_CONTROL() & CONTROL_nPRIV_Msk) == 0);
+ ASSERT((__get_CONTROL() & CONTROL_SPSEL_Msk) != 0);
+
+ return s_current_task_id;
+}
+
+uint32_t task_stack_max_usage_get(task_id_t task_id)
+{
+#if TASK_MANAGER_CONFIG_STACK_PROFILER_ENABLED
+ unsigned int stack_usage;
+ uint32_t *p_stack, *p_stack_top;
+
+ ASSERT((task_id != TASK_ID_INVALID) || (task_id < TASK_MANAGER_CONFIG_MAX_TASKS));
+ ASSERT(s_task_state[task_id].p_stack != NULL);
+
+ p_stack_top = TOP_OF_TASK_STACK(task_id);
+ p_stack = BOTTOM_OF_TASK_STACK(task_id);
+ stack_usage = TASK_MANAGER_CONFIG_STACK_SIZE;
+
+ while (p_stack < p_stack_top)
+ {
+ if (*(p_stack++) != TASK_STACK_MAGIC_WORD)
+ {
+ break;
+ }
+
+ stack_usage -= sizeof(*p_stack);
+ }
+
+ return stack_usage;
+#else
+ return 0;
+#endif
+}
+
+#if TASK_MANAGER_CLI_CMDS
+static void task_mnanager_info(nrf_cli_t const * p_cli, size_t argc, char **argv)
+{
+ task_id_t task_id;
+
+ for (task_id = 0; task_id < TOTAL_NUM_OF_TASKS; task_id++)
+ {
+ const char *p_task_name = NULL;
+
+ CRITICAL_REGION_ENTER();
+ if (s_task_state[task_id].p_stack != NULL)
+ {
+ p_task_name = (s_task_state[task_id].p_task_name) ? s_task_state[task_id].p_task_name
+ : "<NULL>";
+ }
+ CRITICAL_REGION_EXIT();
+
+ if (p_task_name)
+ {
+ uint32_t stack_usage = task_stack_max_usage_get(task_id);
+
+ nrf_cli_fprintf(p_cli, NRF_CLI_NORMAL, "Task %u:\r\n", task_id);
+ nrf_cli_fprintf(p_cli, NRF_CLI_NORMAL, "\tName:\t'%s'\r\n", p_task_name);
+
+ if (stack_usage)
+ {
+ nrf_cli_fprintf(p_cli, NRF_CLI_NORMAL, "\tStack:\t0x%08X-0x%08X used in %u%% (%u out of %u bytes)\r\n",
+ (uint32_t)BOTTOM_OF_TASK_STACK(task_id),
+ (uint32_t)TOP_OF_TASK_STACK(task_id) - 1,
+ 100 * stack_usage / TASK_MANAGER_CONFIG_STACK_SIZE,
+ stack_usage,
+ TASK_MANAGER_CONFIG_STACK_SIZE);
+ }
+ else
+ {
+ nrf_cli_fprintf(p_cli, NRF_CLI_NORMAL, "\tStack:\t0x%08X-0x%08X\r\n",
+ (uint32_t)BOTTOM_OF_TASK_STACK(task_id),
+ (uint32_t)TOP_OF_TASK_STACK(task_id) - 1);
+ }
+
+ nrf_cli_fprintf(p_cli, NRF_CLI_NORMAL, "\tState:\t%s\r\n",
+ (s_current_task_id == task_id) ? "Running" :
+ (s_runnable_tasks_mask & TASK_ID_TO_MASK(task_id)) ? "Runnable" : "Suspended");
+
+ nrf_cli_fprintf(p_cli, NRF_CLI_NORMAL, "\tFlags:\t0x%08X\r\n\r\n",
+ s_task_state[task_id].flags);
+
+ }
+ }
+}
+
+NRF_CLI_CREATE_STATIC_SUBCMD_SET(m_sub_task_mngr)
+{
+ NRF_CLI_CMD(info, NULL, "tasks info", task_mnanager_info),
+ NRF_CLI_SUBCMD_SET_END
+};
+
+NRF_CLI_CMD_REGISTER(task_manager, &m_sub_task_mngr, "commands for task manager", NULL);
+#endif //TASK_MANAGER_CLI_CMDS
+#else //TASK_MANAGER_ENABLED
+void *task_schedule(void *p_stack)
+{
+ return (void *)0;
+}
+#endif //TASK_MANAGER_ENABLED
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/experimental_task_manager/task_manager.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/experimental_task_manager/task_manager.h
new file mode 100644
index 0000000..54c3930
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/experimental_task_manager/task_manager.h
@@ -0,0 +1,143 @@
+/**
+ * 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#ifndef __TASK_MANAGER_H__
+#define __TASK_MANAGER_H__
+
+
+/**
+* @defgroup task_manager Task manager (Cooperative Scheduler)
+* @{
+* @ingroup app_common
+* @brief Functions for managing tasks
+*/
+
+#include <stdbool.h>
+#include <stdint.h>
+
+#include "nrf.h"
+#include "sdk_errors.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**@brief Main function of the task. */
+typedef void (* task_main_t)(void * p_context);
+
+/**@brief Task ID */
+typedef uint8_t task_id_t;
+
+/**@brief Invalid task ID */
+#define TASK_ID_INVALID ((task_id_t)(-1))
+
+/**@brief Start task manager.
+ *
+ * @details This function starts the task manager and configures given function as idle task.
+ * This function never returns.
+ *
+ * @param[in] idle_task Main function of the task scheduled when no other tasks could be run.
+ * @param[in] p_idle_task_context Context passed to idle task.
+ */
+void task_manager_start(task_main_t idle_task, void * p_idle_task_context);
+
+/**@brief Create new task.
+ *
+ * @param[in] task Function which become main procedure of new task.
+ * @param[in] p_task_name Task name.
+ * @param[in] p_context Context passed to task procedure.
+ *
+ * @return ID of the task on success, otherwise TASK_ID_INVALID.
+ */
+task_id_t task_create(task_main_t task, char const * p_task_name, void * p_context);
+
+/**@brief Yield CPU to other tasks.
+ */
+void task_yield(void);
+
+/**@brief Complete current task.
+ *
+ * Task stack returns to the pool of available stacks.
+ */
+void task_exit(void);
+
+/**@brief Wait for events. Set events are cleared after this function returns.
+ *
+ * @param[in] evt_mask Mask of events to wait
+ *
+ * @return Mask with set events (can be a subset of evt_mask).
+ */
+uint32_t task_events_wait(uint32_t evt_mask);
+
+/**@brief Set events for given task.
+ *
+ * @param[in] task_id Id of the task which shall receive events.
+ * @param[in] evt_mask Events for the task.
+ *
+ */
+void task_events_set(task_id_t task_id, uint32_t evt_mask);
+
+/**@brief Returns maximum depth of task stack.
+ *
+ * @param[in] task_id Id of the task (use @ref TASK_ID_INVALID for current task).
+ * @return Number of bytes ever used on task stack.
+ */
+uint32_t task_stack_max_usage_get(task_id_t task_id);
+
+/**@brief Returns ID of currently running task.
+ *
+ * @return ID of active task.
+ */
+task_id_t task_id_get(void);
+
+/**@brief Set events for given task.
+ *
+ * @param[in] task_id Id of the task which name will be returned.
+ * @return Task name
+ *
+ */
+char const * task_name_get(task_id_t task_id);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __TASK_MANAGER_H__ */
+/** @} */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/experimental_task_manager/task_manager_core_armgcc.S b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/experimental_task_manager/task_manager_core_armgcc.S
new file mode 100644
index 0000000..393e878
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/experimental_task_manager/task_manager_core_armgcc.S
@@ -0,0 +1,89 @@
+/**
+ * Copyright (c) 2017 - 2017, 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+
+ .syntax unified
+ .arch armv7-m
+
+ .text
+ .thumb
+ .thumb_func
+ .align 1
+ .global task_switch
+ .type task_switch, %function
+
+task_switch:
+ .fnstart
+ MRS R0, CONTROL /* Fetch CONTROL register to R0 */
+
+#ifdef FLOAT_ABI_HARD
+ TST R0, #(1 << 2) /* Check FPCA flag. */
+ ITTT NE
+ VMRSNE R1, FPSCR /* If FPCA set, fetch FPSCR. */
+ STMDBNE SP!, {R0, R1} /* If FPCA set, save FPSCR (also pad stack to 8-byte alignment) */
+ VSTMDBNE SP!, {S0-S31} /* If FPCA set, save FPU registers. */
+#endif
+
+ STMDB SP!, {R0} /* Save CONTROL register. */
+ AND R0, R0, #~(1 << 2) /* Clear FPCA bit. */
+ MSR CONTROL, R0 /* Update CONTROL register. */
+
+ STMDB SP!, {R0, R4-R12, LR} /* Save CPU registers. Reserve space for R0, needed to pass argument to new task. */
+
+ MOV R0, SP /* Call task scheduler with current stack pointer as argument. */
+ LDR R1, =task_schedule
+ BLX R1
+
+ MOV SP, R0 /* Switch to new stack, returned by task scheduler. */
+
+ LDMIA SP!, {R3, R4-R12, LR} /* Restore CPU registers. Argument to new task is in R3. */
+ LDMIA SP!, {R0} /* Restore CONTROL register. */
+ MSR CONTROL, R0 /* Update CONTROL register. */
+
+#ifdef FLOAT_ABI_HARD
+ TST R0, #(1 << 2) /* Check FPCA flag. */
+ ITTT NE
+ VLDMIANE SP!, {S0-S31} /* If FPCA set, restore FPU registers. */
+ LDMIANE SP!, {R0, R1} /* If FPCA set, restore FPSCR (also remove padding). */
+ VMSRNE FPSCR, R1 /* If FPCA set, update FPSCR */
+#endif
+
+ MOV R0, R3 /* Place optional task argument in R0. */
+ BX LR /* Return to new task. */
+
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/experimental_task_manager/task_manager_core_iar.s b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/experimental_task_manager/task_manager_core_iar.s
new file mode 100644
index 0000000..8205d73
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/experimental_task_manager/task_manager_core_iar.s
@@ -0,0 +1,83 @@
+; Copyright (c) 2017 - 2017, 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, except as embedded into a Nordic
+; Semiconductor ASA integrated circuit in a product or a software update for
+; such product, 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.
+;
+; 4. This software, with or without modification, must only be used with a
+; Nordic Semiconductor ASA integrated circuit.
+;
+; 5. Any software provided in binary form under this license must not be reverse
+; engineered, decompiled, modified and/or disassembled.
+;
+; THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+; OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+; OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+; DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+;
+
+ SECTION .text:CODE:REORDER:NOROOT(2)
+ THUMB
+
+ PUBLIC task_switch
+ EXTERN task_schedule
+
+task_switch
+ MRS R0, CONTROL ; Fetch CONTROL register to R0
+
+#ifdef FLOAT_ABI_HARD
+ TST R0, #(1 << 2) ; Check FPCA flag.
+ ITTT NE
+ VMRSNE R1, FPSCR ; If FPCA set, fetch FPSCR.
+ STMDBNE SP!, {R0, R1} ; If FPCA set, save FPSCR (also pad stack to 8-byte alignment)
+ VSTMDBNE SP!, {S0-S31} ; If FPCA set, save FPU registers.
+#endif
+
+ STMDB SP!, {R0} ; Save CONTROL register.
+ AND R0, R0, #~(1 << 2) ; Clear FPCA bit.
+ MSR CONTROL, R0 ; Update CONTROL register.
+
+ STMDB SP!, {R0, R4-R12, LR} ; Save CPU registers. Reserve space for R0, needed to pass argument to new task.
+
+ MOV R0, SP ; Call task scheduler with current stack pointer as argument.
+ LDR R1, =task_schedule ;
+ BLX R1 ;
+
+ MOV SP, R0 ; Switch to new stack, returned by task scheduler.
+
+ LDMIA SP!, {R3, R4-R12, LR} ; Restore CPU registers. Argument to new task is in R3.
+ LDMIA SP!, {R0} ; Restore CONTROL register.
+ MSR CONTROL, R0 ; Update CONTROL register.
+
+#ifdef FLOAT_ABI_HARD
+ TST R0, #(1 << 2) ; Check FPCA flag.
+ ITTT NE
+ VLDMIANE SP!, {S0-S31} ; If FPCA set, restore FPU registers.
+ LDMIANE SP!, {R0, R1} ; If FPCA set, restore FPSCR (also remove padding).
+ VMSRNE FPSCR, R1 ; If FPCA set, update FPSCR
+#endif
+
+ MOV R0, R3 ; Place optional task argument in R0.
+ BX LR ; Return to new task.
+
+ END
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/experimental_task_manager/task_manager_core_keil.s b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/experimental_task_manager/task_manager_core_keil.s
new file mode 100644
index 0000000..874b84d
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/experimental_task_manager/task_manager_core_keil.s
@@ -0,0 +1,85 @@
+; Copyright (c) 2017 - 2017, 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, except as embedded into a Nordic
+; Semiconductor ASA integrated circuit in a product or a software update for
+; such product, 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.
+;
+; 4. This software, with or without modification, must only be used with a
+; Nordic Semiconductor ASA integrated circuit.
+;
+; 5. Any software provided in binary form under this license must not be reverse
+; engineered, decompiled, modified and/or disassembled.
+;
+; THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+; OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+; OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+; DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+;
+
+ PRESERVE8
+ THUMB
+ AREA |.text|, CODE, READONLY
+
+task_switch PROC
+ EXPORT task_switch
+ IMPORT task_schedule
+
+ MRS R0, CONTROL ; Fetch CONTROL register to R0
+
+ IF :DEF: FLOAT_ABI_HARD
+ TST R0, #(1 << 2) ; Check FPCA flag.
+ ITTT NE
+ VMRSNE R1, FPSCR ; If FPCA set, fetch FPSCR.
+ STMDBNE SP!, {R0, R1} ; If FPCA set, save FPSCR (also pad stack to 8-byte alignment)
+ VSTMDBNE SP!, {S0-S31} ; If FPCA set, save FPU registers.
+ ENDIF
+
+ STMDB SP!, {R0} ; Save CONTROL register.
+ AND R0, R0, #~(1 << 2) ; Clear FPCA bit.
+ MSR CONTROL, R0 ; Update CONTROL register.
+
+ STMDB SP!, {R0, R4-R12, LR} ; Save CPU registers. Reserve space for R0, needed to pass argument to new task.
+
+ MOV R0, SP ; Call task scheduler with current stack pointer as argument.
+ LDR R1, =task_schedule ;
+ BLX R1 ;
+
+ MOV SP, R0 ; Switch to new stack, returned by task scheduler.
+
+ LDMIA SP!, {R3, R4-R12, LR} ; Restore CPU registers. Argument to new task is in R3.
+ LDMIA SP!, {R0} ; Restore CONTROL register.
+ MSR CONTROL, R0 ; Update CONTROL register.
+
+ IF :DEF: FLOAT_ABI_HARD
+ TST R0, #(1 << 2) ; Check FPCA flag.
+ ITTT NE
+ VLDMIANE SP!, {S0-S31} ; If FPCA set, restore FPU registers.
+ LDMIANE SP!, {R0, R1} ; If FPCA set, restore FPSCR (also remove padding).
+ VMSRNE FPSCR, R1 ; If FPCA set, update FPSCR
+ ENDIF
+
+ MOV R0, R3 ; Place optional task argument in R0.
+ BX LR ; Return to new task.
+
+ ENDP
+ END
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/fds/fds.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/fds/fds.c
new file mode 100644
index 0000000..99ddc66
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/fds/fds.c
@@ -0,0 +1,2164 @@
+/**
+ * Copyright (c) 2015 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#include "sdk_common.h"
+#if NRF_MODULE_ENABLED(FDS)
+#include "fds.h"
+#include "fds_internal_defs.h"
+
+#include <stdint.h>
+#include <string.h>
+#include <stdbool.h>
+#include "nrf_error.h"
+#include "nrf_atomic.h"
+#include "nrf_atfifo.h"
+
+#include "nrf_fstorage.h"
+#if (FDS_BACKEND == NRF_FSTORAGE_SD)
+#include "nrf_fstorage_sd.h"
+#elif (FDS_BACKEND == NRF_FSTORAGE_NVMC)
+#include "nrf_fstorage_nvmc.h"
+#else
+#error Invalid FDS backend.
+#endif
+
+#if (FDS_CRC_CHECK_ON_READ)
+#include "crc16.h"
+#endif
+
+
+static void fs_event_handler(nrf_fstorage_evt_t * evt);
+
+NRF_FSTORAGE_DEF(nrf_fstorage_t m_fs) =
+{
+ // The flash area boundaries are set in fds_init().
+ .evt_handler = fs_event_handler,
+};
+
+// Internal status flags.
+static struct
+{
+ bool volatile initialized;
+ nrf_atomic_flag_t initializing;
+} m_flags;
+
+// The number of queued operations.
+// Incremented by queue_start() and decremented by queue_has_next().
+static nrf_atomic_u32_t m_queued_op_cnt;
+
+// The number of registered users and their callback functions.
+static nrf_atomic_u32_t m_users;
+static fds_cb_t m_cb_table[FDS_MAX_USERS];
+
+// The latest (largest) record ID written so far.
+static nrf_atomic_u32_t m_latest_rec_id;
+
+// Queue of fds operations.
+NRF_ATFIFO_DEF(m_queue, fds_op_t, FDS_OP_QUEUE_SIZE);
+
+// Structures used to hold informations about virtual pages.
+static fds_page_t m_pages[FDS_DATA_PAGES];
+static fds_swap_page_t m_swap_page;
+
+// Garbage collection data.
+static fds_gc_data_t m_gc;
+
+
+static void event_send(fds_evt_t const * const p_evt)
+{
+ for (uint32_t user = 0; user < FDS_MAX_USERS; user++)
+ {
+ if (m_cb_table[user] != NULL)
+ {
+ m_cb_table[user](p_evt);
+ }
+ }
+}
+
+
+static void event_prepare(fds_op_t const * const p_op, fds_evt_t * const p_evt)
+{
+ switch (p_op->op_code)
+ {
+ case FDS_OP_INIT:
+ p_evt->id = FDS_EVT_INIT;
+ break;
+
+ case FDS_OP_WRITE:
+ p_evt->id = FDS_EVT_WRITE;
+ p_evt->write.file_id = p_op->write.header.file_id;
+ p_evt->write.record_key = p_op->write.header.record_key;
+ p_evt->write.record_id = p_op->write.header.record_id;
+ p_evt->write.is_record_updated = 0;
+ break;
+
+ case FDS_OP_UPDATE:
+ p_evt->id = FDS_EVT_UPDATE;
+ p_evt->write.file_id = p_op->write.header.file_id;
+ p_evt->write.record_key = p_op->write.header.record_key;
+ p_evt->write.record_id = p_op->write.header.record_id;
+ p_evt->write.is_record_updated = (p_op->write.step == FDS_OP_WRITE_DONE);
+ break;
+
+ case FDS_OP_DEL_RECORD:
+ p_evt->id = FDS_EVT_DEL_RECORD;
+ p_evt->del.file_id = p_op->del.file_id;
+ p_evt->del.record_key = p_op->del.record_key;
+ p_evt->del.record_id = p_op->del.record_to_delete;
+ break;
+
+ case FDS_OP_DEL_FILE:
+ p_evt->id = FDS_EVT_DEL_FILE;
+ p_evt->del.file_id = p_op->del.file_id;
+ p_evt->del.record_key = FDS_RECORD_KEY_DIRTY;
+ p_evt->del.record_id = 0;
+ break;
+
+ case FDS_OP_GC:
+ p_evt->id = FDS_EVT_GC;
+ break;
+
+ default:
+ // Should not happen.
+ break;
+ }
+}
+
+
+static bool header_has_next(fds_header_t const * p_hdr, uint32_t const * p_page_end)
+{
+ uint32_t const * const p_hdr32 = (uint32_t*)p_hdr;
+ return ( ( p_hdr32 < p_page_end)
+ && (*p_hdr32 != FDS_ERASED_WORD)); // Check last to be on the safe side (dereference)
+}
+
+
+// Jump to the next header.
+static fds_header_t const * header_jump(fds_header_t const * const p_hdr)
+{
+ return (fds_header_t*)((uint32_t*)p_hdr + FDS_HEADER_SIZE + p_hdr->length_words);
+}
+
+
+static fds_header_status_t header_check(fds_header_t const * p_hdr, uint32_t const * p_page_end)
+{
+ if (((uint32_t*)header_jump(p_hdr) > p_page_end))
+ {
+ // The length field would jump across the page boundary.
+ // FDS won't allow writing such a header, therefore it has been corrupted.
+ return FDS_HEADER_CORRUPT;
+ }
+
+ if ( (p_hdr->file_id == FDS_FILE_ID_INVALID)
+ || (p_hdr->record_key == FDS_RECORD_KEY_DIRTY))
+ {
+ return FDS_HEADER_DIRTY;
+ }
+
+ return FDS_HEADER_VALID;
+}
+
+
+static bool address_is_valid(uint32_t const * const p_addr)
+{
+ return ((p_addr != NULL) &&
+ (p_addr >= (uint32_t*)m_fs.start_addr) &&
+ (p_addr <= (uint32_t*)m_fs.end_addr) &&
+ (is_word_aligned(p_addr)));
+}
+
+
+// Reads a page tag, and determines if the page is used to store data or as swap.
+static fds_page_type_t page_identify(uint32_t const * const p_page_addr)
+{
+ if ( (p_page_addr == NULL) // Should never happen.
+ || (p_page_addr[FDS_PAGE_TAG_WORD_0] != FDS_PAGE_TAG_MAGIC))
+ {
+ return FDS_PAGE_UNDEFINED;
+ }
+
+ switch (p_page_addr[FDS_PAGE_TAG_WORD_1])
+ {
+ case FDS_PAGE_TAG_SWAP:
+ return FDS_PAGE_SWAP;
+
+ case FDS_PAGE_TAG_DATA:
+ return FDS_PAGE_DATA;
+
+ default:
+ return FDS_PAGE_UNDEFINED;
+ }
+}
+
+
+static bool page_is_erased(uint32_t const * const p_page_addr)
+{
+ for (uint32_t i = 0; i < FDS_PAGE_SIZE; i++)
+ {
+ if (*(p_page_addr + i) != FDS_ERASED_WORD)
+ {
+ return false;
+ }
+ }
+
+ return true;
+}
+
+
+// NOTE: Must be called from within a critical section.
+static bool page_has_space(uint16_t page, uint16_t length_words)
+{
+ length_words += m_pages[page].write_offset;
+ length_words += m_pages[page].words_reserved;
+ return (length_words < FDS_PAGE_SIZE);
+}
+
+
+// Given a pointer to a record, find the index of the page on which it is stored.
+// Returns FDS_SUCCESS if the page is found, FDS_ERR_NOT_FOUND otherwise.
+static ret_code_t page_from_record(uint16_t * const p_page, uint32_t const * const p_rec)
+{
+ ret_code_t ret = FDS_ERR_NOT_FOUND;
+
+ CRITICAL_SECTION_ENTER();
+ for (uint16_t i = 0; i < FDS_DATA_PAGES; i++)
+ {
+ if ((p_rec > m_pages[i].p_addr) &&
+ (p_rec < m_pages[i].p_addr + FDS_PAGE_SIZE))
+ {
+ ret = FDS_SUCCESS;
+ *p_page = i;
+ break;
+ }
+ }
+ CRITICAL_SECTION_EXIT();
+
+ return ret;
+}
+
+
+// Scan a page to determine how many words have been written to it.
+// This information is used to set the page write offset during initialization.
+// Additionally, this function updates the latest record ID as it proceeds.
+// If an invalid record header is found, the can_gc argument is set to true.
+static void page_scan(uint32_t const * p_addr,
+ uint16_t * const words_written,
+ bool * const can_gc)
+{
+ uint32_t const * const p_page_end = p_addr + FDS_PAGE_SIZE;
+
+ p_addr += FDS_PAGE_TAG_SIZE;
+ *words_written = FDS_PAGE_TAG_SIZE;
+
+ fds_header_t const * p_header = (fds_header_t*)p_addr;
+
+ while (header_has_next(p_header, p_page_end))
+ {
+ fds_header_status_t hdr = header_check(p_header, p_page_end);
+
+ if (hdr == FDS_HEADER_VALID)
+ {
+ // Update the latest (largest) record ID.
+ if (p_header->record_id > m_latest_rec_id)
+ {
+ m_latest_rec_id = p_header->record_id;
+ }
+ }
+ else
+ {
+ if (can_gc != NULL)
+ {
+ *can_gc = true;
+ }
+
+ if (hdr == FDS_HEADER_CORRUPT)
+ {
+ // It could happen that a record has a corrupt header which would set a
+ // wrong offset for this page. In such cases, update this value to its maximum,
+ // to ensure that no new records will be written to this page and to enable
+ // correct statistics reporting by fds_stat().
+ *words_written = FDS_PAGE_SIZE;
+
+ // We can't continue to scan this page.
+ return;
+ }
+ }
+
+ *words_written += (FDS_HEADER_SIZE + p_header->length_words);
+ p_header = header_jump(p_header);
+ }
+}
+
+
+static void page_offsets_update(fds_page_t * const p_page, fds_op_t const * p_op)
+{
+ // If the first part of the header has been written correctly, update the offset as normal.
+ // Even if the record has not been written completely, fds is still able to continue normal
+ // operation. Incomplete records will be deleted the next time garbage collection is run.
+ // If we failed at the very beginning of the write operation, restore the offset
+ // to the previous value so that no holes will be left in the flash.
+ if (p_op->write.step > FDS_OP_WRITE_RECORD_ID)
+ {
+ p_page->write_offset += (FDS_HEADER_SIZE + p_op->write.header.length_words);
+ }
+
+ p_page->words_reserved -= (FDS_HEADER_SIZE + p_op->write.header.length_words);
+}
+
+
+// Tags a page as swap, i.e., reserved for GC.
+static ret_code_t page_tag_write_swap(void)
+{
+ // The tag needs to be statically allocated since it is not buffered by fstorage.
+ static uint32_t const page_tag_swap[] = {FDS_PAGE_TAG_MAGIC, FDS_PAGE_TAG_SWAP};
+ return nrf_fstorage_write(&m_fs, (uint32_t)m_swap_page.p_addr, page_tag_swap, FDS_PAGE_TAG_SIZE * sizeof(uint32_t), NULL);
+}
+
+
+// Tags a page as data, i.e, ready for storage.
+static ret_code_t page_tag_write_data(uint32_t const * const p_page_addr)
+{
+ // The tag needs to be statically allocated since it is not buffered by fstorage.
+ static uint32_t const page_tag_data[] = {FDS_PAGE_TAG_MAGIC, FDS_PAGE_TAG_DATA};
+ return nrf_fstorage_write(&m_fs, (uint32_t)p_page_addr, page_tag_data, FDS_PAGE_TAG_SIZE * sizeof(uint32_t), NULL);
+}
+
+
+// Reserve space on a page.
+// NOTE: this function takes into the account the space required for the record header.
+static ret_code_t write_space_reserve(uint16_t length_words, uint16_t * p_page)
+{
+ bool space_reserved = false;
+ uint16_t const total_len_words = length_words + FDS_HEADER_SIZE;
+
+ if (total_len_words >= FDS_PAGE_SIZE - FDS_PAGE_TAG_SIZE)
+ {
+ return FDS_ERR_RECORD_TOO_LARGE;
+ }
+
+ CRITICAL_SECTION_ENTER();
+ for (uint16_t page = 0; page < FDS_DATA_PAGES; page++)
+ {
+ if ((m_pages[page].page_type == FDS_PAGE_DATA) &&
+ (page_has_space(page, total_len_words)))
+ {
+ space_reserved = true;
+ *p_page = page;
+
+ m_pages[page].words_reserved += total_len_words;
+ break;
+ }
+ }
+ CRITICAL_SECTION_EXIT();
+
+ return (space_reserved) ? FDS_SUCCESS : FDS_ERR_NO_SPACE_IN_FLASH;
+}
+
+
+// Undo a write_space_reserve() call.
+// NOTE: Must be called within a critical section.
+static void write_space_free(uint16_t length_words, uint16_t page)
+{
+ m_pages[page].words_reserved -= (length_words + FDS_HEADER_SIZE);
+}
+
+
+static uint32_t record_id_new(void)
+{
+ return nrf_atomic_u32_add(&m_latest_rec_id, 1);
+}
+
+
+// Given a page and a record, find the next valid record on that page.
+// If p_record is NULL, search from the beginning of the page,
+// otherwise, resume searching from p_record.
+// Return true if a record is found, false otherwise.
+// If no record is found, p_record is unchanged.
+static bool record_find_next(uint16_t page, uint32_t const ** p_record)
+{
+ uint32_t const * p_page_end = (m_pages[page].p_addr + FDS_PAGE_SIZE);
+
+ // If this is the first call on this page, start searching from its beginning.
+ // Otherwise, jump to the next record.
+ fds_header_t const * p_header = (fds_header_t*)(*p_record);
+
+ if (p_header != NULL)
+ {
+ p_header = header_jump(p_header);
+ }
+ else
+ {
+ p_header = (fds_header_t*)(m_pages[page].p_addr + FDS_PAGE_TAG_SIZE);
+ }
+
+ // Read records from the page until:
+ // - a valid record is found or
+ // - the last record on a page is found
+
+ while (header_has_next(p_header, p_page_end))
+ {
+ switch (header_check(p_header, p_page_end))
+ {
+ case FDS_HEADER_VALID:
+ *p_record = (uint32_t*)p_header;
+ return true;
+
+ case FDS_HEADER_DIRTY:
+ p_header = header_jump(p_header);
+ break;
+
+ case FDS_HEADER_CORRUPT:
+ // We can't reliably jump over this record.
+ // There is nothing more we can do on this page.
+ return false;
+ }
+ }
+
+ // No more valid records on this page.
+ return false;
+}
+
+
+// Find a record given its descriptor and retrive the page in which the record is stored.
+// NOTE: Do not pass NULL as an argument for p_page.
+static bool record_find_by_desc(fds_record_desc_t * const p_desc, uint16_t * const p_page)
+{
+ // If the gc_run_count field in the descriptor matches our counter, then the record has
+ // not been moved. If the address is valid, and the record ID matches, there is no need
+ // to find the record again. Only lookup the page in which the record is stored.
+
+ if ((address_is_valid(p_desc->p_record)) &&
+ (p_desc->gc_run_count == m_gc.run_count) &&
+ (p_desc->record_id == ((fds_header_t*)p_desc->p_record)->record_id))
+ {
+ return (page_from_record(p_page, p_desc->p_record) == FDS_SUCCESS);
+ }
+
+ // Otherwise, find the record in flash.
+ for (*p_page = 0; *p_page < FDS_DATA_PAGES; (*p_page)++)
+ {
+ // Set p_record to NULL to make record_find_next() search from the beginning of the page.
+ uint32_t const * p_record = NULL;
+
+ while (record_find_next(*p_page, &p_record))
+ {
+ fds_header_t const * const p_header = (fds_header_t*)p_record;
+ if (p_header->record_id == p_desc->record_id)
+ {
+ p_desc->p_record = p_record;
+ p_desc->gc_run_count = m_gc.run_count;
+ return true;
+ }
+ }
+ }
+
+ return false;
+}
+
+
+// Search for a record and return its descriptor.
+// If p_file_id is NULL, only the record key will be used for matching.
+// If p_record_key is NULL, only the file ID will be used for matching.
+// If both are NULL, it will iterate through all records.
+static ret_code_t record_find(uint16_t const * p_file_id,
+ uint16_t const * p_record_key,
+ fds_record_desc_t * p_desc,
+ fds_find_token_t * p_token)
+{
+ if (!m_flags.initialized)
+ {
+ return FDS_ERR_NOT_INITIALIZED;
+ }
+
+ if (p_desc == NULL || p_token == NULL)
+ {
+ return FDS_ERR_NULL_ARG;
+ }
+
+ // Begin (or resume) searching for a record.
+ for (; p_token->page < FDS_DATA_PAGES; p_token->page++)
+ {
+ if (m_pages[p_token->page].page_type != FDS_PAGE_DATA)
+ {
+ // It might be that the page is FDS_PAGE_UNDEFINED.
+ // Skip this page.
+ continue;
+ }
+
+ while (record_find_next(p_token->page, &p_token->p_addr))
+ {
+ fds_header_t const * p_header = (fds_header_t*)p_token->p_addr;
+
+ // A valid record was found, check its header for a match.
+ if ((p_file_id != NULL) &&
+ (p_header->file_id != *p_file_id))
+ {
+ continue;
+ }
+
+ if ((p_record_key != NULL) &&
+ (p_header->record_key != *p_record_key))
+ {
+ continue;
+ }
+
+ // Record found; update the descriptor.
+ p_desc->record_id = p_header->record_id;
+ p_desc->p_record = p_token->p_addr;
+ p_desc->gc_run_count = m_gc.run_count;
+
+ return FDS_SUCCESS;
+ }
+
+ // We have scanned an entire page. Set the address in the token to NULL
+ // so that it will be updated in the next iteration.
+ p_token->p_addr = NULL;
+ }
+
+ return FDS_ERR_NOT_FOUND;
+}
+
+
+// Retrieve statistics about dirty records on a page.
+static void records_stat(uint16_t page,
+ uint16_t * p_valid_records,
+ uint16_t * p_dirty_records,
+ uint16_t * p_freeable_words,
+ bool * p_corruption)
+{
+ fds_header_t const * p_header = (fds_header_t*)(m_pages[page].p_addr + FDS_PAGE_TAG_SIZE);
+ uint32_t const * const p_page_end = (m_pages[page].p_addr + FDS_PAGE_SIZE);
+
+ while (header_has_next(p_header, p_page_end))
+ {
+ switch (header_check(p_header, p_page_end))
+ {
+ case FDS_HEADER_DIRTY:
+ *p_dirty_records += 1;
+ *p_freeable_words += FDS_HEADER_SIZE + p_header->length_words;
+ p_header = header_jump(p_header);
+ break;
+
+ case FDS_HEADER_VALID:
+ *p_valid_records += 1;
+ p_header = header_jump(p_header);
+ break;
+
+ case FDS_HEADER_CORRUPT:
+ {
+ *p_dirty_records += 1;
+ *p_freeable_words += (p_page_end - (uint32_t*)p_header);
+ *p_corruption = true;
+ // We can't continue on this page.
+ return;
+ }
+
+ default:
+ break;
+ }
+ }
+}
+
+
+// Get a buffer on the queue of operations.
+static fds_op_t * queue_buf_get(nrf_atfifo_item_put_t * p_iput_ctx)
+{
+ fds_op_t * const p_op = (fds_op_t*) nrf_atfifo_item_alloc(m_queue, p_iput_ctx);
+
+ memset(p_op, 0x00, sizeof(fds_op_t));
+ return p_op;
+}
+
+
+// Commit a buffer to the queue of operations.
+static void queue_buf_store(nrf_atfifo_item_put_t * p_iput_ctx)
+{
+ (void) nrf_atfifo_item_put(m_queue, p_iput_ctx);
+}
+
+
+// Load the next operation from the queue.
+static fds_op_t * queue_load(nrf_atfifo_item_get_t * p_iget_ctx)
+{
+ return (fds_op_t*) nrf_atfifo_item_get(m_queue, p_iget_ctx);
+}
+
+
+// Free the currently loaded operation.
+static void queue_free(nrf_atfifo_item_get_t * p_iget_ctx)
+{
+ // Free the current queue element.
+ (void) nrf_atfifo_item_free(m_queue, p_iget_ctx);
+}
+
+
+static bool queue_has_next(void)
+{
+ // Decrement the number of queued operations.
+ ASSERT(m_queued_op_cnt != 0);
+ return nrf_atomic_u32_sub(&m_queued_op_cnt, 1);
+}
+
+
+// This function is called during initialization to setup the page structure (m_pages) and
+// provide additional information regarding eventual further initialization steps.
+static fds_init_opts_t pages_init(void)
+{
+ uint32_t ret = NO_PAGES;
+ uint16_t page = 0;
+ uint16_t total_pages_available = FDS_VIRTUAL_PAGES;
+ bool swap_set_but_not_found = false;
+
+ for (uint16_t i = 0; i < FDS_VIRTUAL_PAGES; i++)
+ {
+ uint32_t const * const p_page_addr = (uint32_t*)m_fs.start_addr + (i * FDS_PAGE_SIZE);
+ fds_page_type_t const page_type = page_identify(p_page_addr);
+
+ switch (page_type)
+ {
+ case FDS_PAGE_UNDEFINED:
+ {
+ if (page_is_erased(p_page_addr))
+ {
+ if (m_swap_page.p_addr != NULL)
+ {
+ // If a swap page is already set, flag the page as erased (in m_pages)
+ // and try to tag it as data (in flash) later on during initialization.
+ m_pages[page].page_type = FDS_PAGE_ERASED;
+ m_pages[page].p_addr = p_page_addr;
+ m_pages[page].write_offset = FDS_PAGE_TAG_SIZE;
+
+ // This is a candidate for a potential new swap page, in case the
+ // current swap is going to be promoted to complete a GC instance.
+ m_gc.cur_page = page;
+ page++;
+ }
+ else
+ {
+ // If there is no swap page yet, use this one.
+ m_swap_page.p_addr = p_page_addr;
+ m_swap_page.write_offset = FDS_PAGE_TAG_SIZE;
+ swap_set_but_not_found = true;
+ }
+
+ ret |= PAGE_ERASED;
+ }
+ else
+ {
+ // The page contains non-FDS data.
+ // Do not initialize or use this page.
+ total_pages_available--;
+ m_pages[page].p_addr = p_page_addr;
+ m_pages[page].page_type = FDS_PAGE_UNDEFINED;
+ page++;
+ }
+ } break;
+
+ case FDS_PAGE_DATA:
+ {
+ m_pages[page].page_type = FDS_PAGE_DATA;
+ m_pages[page].p_addr = p_page_addr;
+
+ // Scan the page to compute its write offset and determine whether or not the page
+ // can be garbage collected. Additionally, update the latest kwown record ID.
+ page_scan(p_page_addr, &m_pages[page].write_offset, &m_pages[page].can_gc);
+
+ ret |= PAGE_DATA;
+ page++;
+ } break;
+
+ case FDS_PAGE_SWAP:
+ {
+ if (swap_set_but_not_found)
+ {
+ m_pages[page].page_type = FDS_PAGE_ERASED;
+ m_pages[page].p_addr = m_swap_page.p_addr;
+ m_pages[page].write_offset = FDS_PAGE_TAG_SIZE;
+
+ page++;
+ }
+
+ m_swap_page.p_addr = p_page_addr;
+ // If the swap is promoted, this offset should be kept, otherwise,
+ // it should be set to FDS_PAGE_TAG_SIZE.
+ page_scan(p_page_addr, &m_swap_page.write_offset, NULL);
+
+ ret |= (m_swap_page.write_offset == FDS_PAGE_TAG_SIZE) ?
+ PAGE_SWAP_CLEAN : PAGE_SWAP_DIRTY;
+ } break;
+
+ default:
+ // Shouldn't happen.
+ break;
+ }
+ }
+
+ if (total_pages_available < 2)
+ {
+ ret &= NO_PAGES;
+ }
+
+ return (fds_init_opts_t)ret;
+}
+
+
+// Write the first part of a record header (the key and length).
+static ret_code_t record_header_write_begin(fds_op_t * const p_op, uint32_t * const p_addr)
+{
+ ret_code_t ret;
+
+ // Write the record ID next.
+ p_op->write.step = FDS_OP_WRITE_RECORD_ID;
+
+ ret = nrf_fstorage_write(&m_fs, (uint32_t)(p_addr + FDS_OFFSET_TL),
+ &p_op->write.header.record_key, FDS_HEADER_SIZE_TL * sizeof(uint32_t), NULL);
+
+ return (ret == NRF_SUCCESS) ? FDS_SUCCESS : FDS_ERR_BUSY;
+}
+
+
+static ret_code_t record_header_write_id(fds_op_t * const p_op, uint32_t * const p_addr)
+{
+ ret_code_t ret;
+
+ // If this record has no data, write the last part of the header directly.
+ // Otherwise, write the record data next.
+ p_op->write.step = (p_op->write.p_data != NULL) ?
+ FDS_OP_WRITE_DATA : FDS_OP_WRITE_HEADER_FINALIZE;
+
+ ret = nrf_fstorage_write(&m_fs, (uint32_t)(p_addr + FDS_OFFSET_ID),
+ &p_op->write.header.record_id, FDS_HEADER_SIZE_ID * sizeof(uint32_t), NULL);
+
+ return (ret == NRF_SUCCESS) ? FDS_SUCCESS : FDS_ERR_BUSY;
+}
+
+
+static ret_code_t record_header_write_finalize(fds_op_t * const p_op, uint32_t * const p_addr)
+{
+ ret_code_t ret;
+
+ // If this is a simple write operation, then this is the last step.
+ // If this is an update instead, delete the old record next.
+ p_op->write.step = (p_op->op_code == FDS_OP_UPDATE) ?
+ FDS_OP_WRITE_FLAG_DIRTY : FDS_OP_WRITE_DONE;
+
+ ret = nrf_fstorage_write(&m_fs, (uint32_t)(p_addr + FDS_OFFSET_IC),
+ &p_op->write.header.file_id, FDS_HEADER_SIZE_IC * sizeof(uint32_t), NULL);
+
+ return (ret == NRF_SUCCESS) ? FDS_SUCCESS : FDS_ERR_BUSY;
+}
+
+
+static ret_code_t record_header_flag_dirty(uint32_t * const p_record, uint16_t page_to_gc)
+{
+ // Used to flag a record as dirty, i.e. ready for garbage collection.
+ // Must be statically allocated since it will be written to flash.
+ __ALIGN(4) static uint32_t const dirty_header = {0xFFFF0000};
+
+ // Flag the record as dirty.
+ ret_code_t ret;
+
+ ret = nrf_fstorage_write(&m_fs, (uint32_t)p_record,
+ &dirty_header, FDS_HEADER_SIZE_TL * sizeof(uint32_t), NULL);
+
+ if (ret != NRF_SUCCESS)
+ {
+ return FDS_ERR_BUSY;
+ }
+
+ m_pages[page_to_gc].can_gc = true;
+
+ return FDS_SUCCESS;
+}
+
+
+static ret_code_t record_find_and_delete(fds_op_t * const p_op)
+{
+ ret_code_t ret;
+ uint16_t page;
+ fds_record_desc_t desc = {0};
+
+ desc.record_id = p_op->del.record_to_delete;
+
+ if (record_find_by_desc(&desc, &page))
+ {
+ fds_header_t const * const p_header = (fds_header_t const *)desc.p_record;
+
+ // Copy the record key and file ID, so that they can be returned in the event.
+ // In case this function is run as part of an update, there is no need to copy
+ // the file ID and record key since they are present in the header stored
+ // in the queue element.
+
+ p_op->del.file_id = p_header->file_id;
+ p_op->del.record_key = p_header->record_key;
+
+ // Flag the record as dirty.
+ ret = record_header_flag_dirty((uint32_t*)desc.p_record, page);
+ }
+ else
+ {
+ // The record never existed, or it has already been deleted.
+ ret = FDS_ERR_NOT_FOUND;
+ }
+
+ return ret;
+}
+
+
+// Finds a record within a file and flags it as dirty.
+static ret_code_t file_find_and_delete(fds_op_t * const p_op)
+{
+ ret_code_t ret;
+ fds_record_desc_t desc;
+
+ // This token must persist across calls.
+ static fds_find_token_t tok = {0};
+
+ // Pass NULL to ignore the record key.
+ ret = record_find(&p_op->del.file_id, NULL, &desc, &tok);
+
+ if (ret == FDS_SUCCESS)
+ {
+ // A record was found: flag it as dirty.
+ ret = record_header_flag_dirty((uint32_t*)desc.p_record, tok.page);
+ }
+ else // FDS_ERR_NOT_FOUND
+ {
+ // No more records were found. Zero the token, so that it can be reused.
+ memset(&tok, 0x00, sizeof(fds_find_token_t));
+ }
+
+ return ret;
+}
+
+
+// Writes record data to flash.
+static ret_code_t record_write_data(fds_op_t * const p_op, uint32_t * const p_addr)
+{
+ ret_code_t ret;
+
+ p_op->write.step = FDS_OP_WRITE_HEADER_FINALIZE;
+
+ ret = nrf_fstorage_write(&m_fs, (uint32_t)(p_addr + FDS_OFFSET_DATA),
+ p_op->write.p_data, p_op->write.header.length_words * sizeof(uint32_t), NULL);
+
+ return (ret == NRF_SUCCESS) ? FDS_SUCCESS : FDS_ERR_BUSY;
+}
+
+
+#if (FDS_CRC_CHECK_ON_READ)
+static bool crc_verify_success(uint16_t crc, uint16_t len_words, uint32_t const * const p_data)
+{
+ uint16_t computed_crc;
+
+ // The CRC is computed on the entire record, except the CRC field itself.
+ // The record header is 12 bytes, out of these we have to skip bytes 6 to 8 where the
+ // CRC itself is stored. Then we compute the CRC for the rest of the record, from byte 8 of
+ // the header (where the record ID begins) to the end of the record data.
+ computed_crc = crc16_compute((uint8_t const *)p_data, 6, NULL);
+ computed_crc = crc16_compute((uint8_t const *)p_data + 8,
+ (FDS_HEADER_SIZE_ID + len_words) * sizeof(uint32_t),
+ &computed_crc);
+
+ return (computed_crc == crc);
+}
+#endif
+
+
+static void gc_init(void)
+{
+ m_gc.run_count++;
+ m_gc.cur_page = 0;
+ m_gc.resume = false;
+
+ // Setup which pages to GC. Defer checking for open records and the can_gc flag,
+ // as other operations might change those while GC is running.
+ for (uint16_t i = 0; i < FDS_DATA_PAGES; i++)
+ {
+ m_gc.do_gc_page[i] = (m_pages[i].page_type == FDS_PAGE_DATA);
+ }
+}
+
+
+// Obtain the next page to be garbage collected.
+// Returns true if there are pages left to garbage collect, returns false otherwise.
+static bool gc_page_next(uint16_t * const p_next_page)
+{
+ bool ret = false;
+
+ for (uint16_t i = 0; i < FDS_DATA_PAGES; i++)
+ {
+ if (m_gc.do_gc_page[i])
+ {
+ // Do not attempt to GC this page again.
+ m_gc.do_gc_page[i] = false;
+
+ // Only GC pages with no open records and with some records which have been deleted.
+ if ((m_pages[i].records_open == 0) && (m_pages[i].can_gc == true))
+ {
+ *p_next_page = i;
+ ret = true;
+ break;
+ }
+ }
+ }
+
+ return ret;
+}
+
+
+static ret_code_t gc_swap_erase(void)
+{
+ m_gc.state = GC_DISCARD_SWAP;
+ m_swap_page.write_offset = FDS_PAGE_TAG_SIZE;
+
+ return nrf_fstorage_erase(&m_fs, (uint32_t)m_swap_page.p_addr, FDS_PHY_PAGES_IN_VPAGE, NULL);
+}
+
+
+// Erase the page being garbage collected, or erase the swap in case there are any open
+// records on the page being garbage collected.
+static ret_code_t gc_page_erase(void)
+{
+ uint32_t ret;
+ uint16_t const gc = m_gc.cur_page;
+
+ if (m_pages[gc].records_open == 0)
+ {
+ m_gc.state = GC_ERASE_PAGE;
+
+ ret = nrf_fstorage_erase(&m_fs, (uint32_t)m_pages[gc].p_addr, FDS_PHY_PAGES_IN_VPAGE, NULL);
+ }
+ else
+ {
+ // If there are open records, stop garbage collection on this page.
+ // Discard the swap and try to garbage collect another page.
+ ret = gc_swap_erase();
+ }
+
+ return ret;
+}
+
+
+// Copy the current record to swap.
+static ret_code_t gc_record_copy(void)
+{
+ fds_header_t const * const p_header = (fds_header_t*)m_gc.p_record_src;
+ uint32_t const * const p_dest = m_swap_page.p_addr + m_swap_page.write_offset;
+ uint16_t const record_len = FDS_HEADER_SIZE + p_header->length_words;
+
+ m_gc.state = GC_COPY_RECORD;
+
+ // Copy the record to swap; it is guaranteed to fit in the destination page,
+ // so there is no need to check its size. This will either succeed or timeout.
+ return nrf_fstorage_write(&m_fs, (uint32_t)p_dest, m_gc.p_record_src,
+ record_len * sizeof(uint32_t),
+ NULL);
+}
+
+
+static ret_code_t gc_record_find_next(void)
+{
+ ret_code_t ret;
+
+ // Find the next valid record to copy.
+ if (record_find_next(m_gc.cur_page, &m_gc.p_record_src))
+ {
+ ret = gc_record_copy();
+ }
+ else
+ {
+ // No more records left to copy on this page; swap pages.
+ ret = gc_page_erase();
+ }
+
+ return ret;
+}
+
+
+// Promote the swap by tagging it as a data page.
+static ret_code_t gc_swap_promote(void)
+{
+ m_gc.state = GC_PROMOTE_SWAP;
+ return page_tag_write_data(m_pages[m_gc.cur_page].p_addr);
+}
+
+
+// Tag the page just garbage collected as swap.
+static ret_code_t gc_tag_new_swap(void)
+{
+ m_gc.state = GC_TAG_NEW_SWAP;
+ m_gc.p_record_src = NULL;
+ return page_tag_write_swap();
+}
+
+
+static ret_code_t gc_next_page(void)
+{
+ if (!gc_page_next(&m_gc.cur_page))
+ {
+ // No pages left to GC; GC has terminated. Reset the state.
+ m_gc.state = GC_BEGIN;
+ m_gc.cur_page = 0;
+ m_gc.p_record_src = NULL;
+
+ return FDS_OP_COMPLETED;
+ }
+
+ return gc_record_find_next();
+}
+
+
+// Update the swap page offeset after a record has been successfully copied to it.
+static void gc_update_swap_offset(void)
+{
+ fds_header_t const * const p_header = (fds_header_t*)m_gc.p_record_src;
+ uint16_t const record_len = FDS_HEADER_SIZE + p_header->length_words;
+
+ m_swap_page.write_offset += record_len;
+}
+
+
+static void gc_swap_pages(void)
+{
+ // The page being garbage collected will be the new swap page,
+ // and the current swap will be used as a data page (promoted).
+ uint32_t const * const p_addr = m_swap_page.p_addr;
+
+ m_swap_page.p_addr = m_pages[m_gc.cur_page].p_addr;
+ m_pages[m_gc.cur_page].p_addr = p_addr;
+
+ // Keep the offset for this page, but reset it for the swap.
+ m_pages[m_gc.cur_page].write_offset = m_swap_page.write_offset;
+ m_swap_page.write_offset = FDS_PAGE_TAG_SIZE;
+}
+
+
+static void gc_state_advance(void)
+{
+ switch (m_gc.state)
+ {
+ case GC_BEGIN:
+ gc_init();
+ m_gc.state = GC_NEXT_PAGE;
+ break;
+
+ // A record was successfully copied.
+ case GC_COPY_RECORD:
+ gc_update_swap_offset();
+ m_gc.state = GC_FIND_NEXT_RECORD;
+ break;
+
+ // A page was successfully erased. Prepare to promote the swap.
+ case GC_ERASE_PAGE:
+ gc_swap_pages();
+ m_gc.state = GC_PROMOTE_SWAP;
+ break;
+
+ // Swap was discarded because the page being GC'ed had open records.
+ case GC_DISCARD_SWAP:
+ // Swap was successfully promoted.
+ case GC_PROMOTE_SWAP:
+ // Prepare to tag the page just GC'ed as swap.
+ m_gc.state = GC_TAG_NEW_SWAP;
+ break;
+
+ case GC_TAG_NEW_SWAP:
+ m_gc.state = GC_NEXT_PAGE;
+ break;
+
+ default:
+ // Should not happen.
+ break;
+ }
+}
+
+
+// Initialize the filesystem.
+static ret_code_t init_execute(uint32_t prev_ret, fds_op_t * const p_op)
+{
+ ret_code_t ret = FDS_ERR_INTERNAL;
+
+ if (prev_ret != NRF_SUCCESS)
+ {
+ // A previous operation has timed out.
+ m_flags.initializing = false;
+ return FDS_ERR_OPERATION_TIMEOUT;
+ }
+
+ switch (p_op->init.step)
+ {
+ case FDS_OP_INIT_TAG_SWAP:
+ {
+ // The page write offset was determined previously by pages_init().
+ p_op->init.step = FDS_OP_INIT_TAG_DATA;
+ ret = page_tag_write_swap();
+ } break;
+
+ case FDS_OP_INIT_TAG_DATA:
+ {
+ // Tag remaining erased pages as data.
+ bool write_reqd = false;
+ for (uint16_t i = 0; i < FDS_DATA_PAGES; i++)
+ {
+ if (m_pages[i].page_type == FDS_PAGE_ERASED)
+ {
+ m_pages[i].page_type = FDS_PAGE_DATA;
+ write_reqd = true;
+ ret = page_tag_write_data(m_pages[i].p_addr);
+ break;
+ }
+ }
+ if (!write_reqd)
+ {
+ m_flags.initialized = true;
+ m_flags.initializing = false;
+ return FDS_OP_COMPLETED;
+ }
+ } break;
+
+ case FDS_OP_INIT_ERASE_SWAP:
+ {
+ // If the swap is going to be discarded then reset its write_offset.
+ p_op->init.step = FDS_OP_INIT_TAG_SWAP;
+ m_swap_page.write_offset = FDS_PAGE_TAG_SIZE;
+
+ ret = nrf_fstorage_erase(&m_fs, (uint32_t)m_swap_page.p_addr, FDS_PHY_PAGES_IN_VPAGE, NULL);
+ } break;
+
+ case FDS_OP_INIT_PROMOTE_SWAP:
+ {
+ p_op->init.step = FDS_OP_INIT_TAG_SWAP;
+
+ // When promoting the swap, keep the write_offset set by pages_init().
+ ret = page_tag_write_data(m_swap_page.p_addr);
+
+ uint16_t const gc = m_gc.cur_page;
+ uint32_t const * const p_old_swap = m_swap_page.p_addr;
+
+ // Execute the swap.
+ m_swap_page.p_addr = m_pages[gc].p_addr;
+ m_pages[gc].p_addr = p_old_swap;
+
+ // Copy the offset from the swap to the new page.
+ m_pages[gc].write_offset = m_swap_page.write_offset;
+ m_swap_page.write_offset = FDS_PAGE_TAG_SIZE;
+
+ m_pages[gc].page_type = FDS_PAGE_DATA;
+ } break;
+
+ default:
+ // Should not happen.
+ break;
+ }
+
+ if (ret != FDS_SUCCESS)
+ {
+ // fstorage queue was full.
+ m_flags.initializing = false;
+ return FDS_ERR_BUSY;
+ }
+
+ return FDS_OP_EXECUTING;
+}
+
+
+// Executes write and update operations.
+static ret_code_t write_execute(uint32_t prev_ret, fds_op_t * const p_op)
+{
+ ret_code_t ret;
+ uint32_t * p_write_addr;
+ fds_page_t * const p_page = &m_pages[p_op->write.page];
+
+ // This must persist across calls.
+ static fds_record_desc_t desc = {0};
+ // When a record is updated, this variable will hold the page where the old
+ // copy was stored. This will be used to set the can_gc flag when the header is
+ // invalidated (FDS_OP_WRITE_FLAG_DIRTY).
+ static uint16_t page;
+
+ if (prev_ret != NRF_SUCCESS)
+ {
+ // The previous operation has timed out, update offsets.
+ page_offsets_update(p_page, p_op);
+ return FDS_ERR_OPERATION_TIMEOUT;
+ }
+
+ // Compute the address where to write data.
+ p_write_addr = (uint32_t*)(p_page->p_addr + p_page->write_offset);
+
+ // Execute the current step of the operation, and set one to be executed next.
+ switch (p_op->write.step)
+ {
+ case FDS_OP_WRITE_FIND_RECORD:
+ {
+ // The first step of updating a record constists of locating the copy to be deleted.
+ // If the old copy couldn't be found for any reason then the update should fail.
+ // This prevents duplicates when queuing multiple updates of the same record.
+ desc.p_record = NULL;
+ desc.record_id = p_op->write.record_to_delete;
+
+ if (!record_find_by_desc(&desc, &page))
+ {
+ return FDS_ERR_NOT_FOUND;
+ }
+ // Setting the step is redundant since we are falling through.
+ }
+ // Fallthrough to FDS_OP_WRITE_HEADER_BEGIN.
+
+ case FDS_OP_WRITE_HEADER_BEGIN:
+ ret = record_header_write_begin(p_op, p_write_addr);
+ break;
+
+ case FDS_OP_WRITE_RECORD_ID:
+ ret = record_header_write_id(p_op, p_write_addr);
+ break;
+
+ case FDS_OP_WRITE_DATA:
+ ret = record_write_data(p_op, p_write_addr);
+ break;
+
+ case FDS_OP_WRITE_HEADER_FINALIZE:
+ ret = record_header_write_finalize(p_op, p_write_addr);
+ break;
+
+ case FDS_OP_WRITE_FLAG_DIRTY:
+ p_op->write.step = FDS_OP_WRITE_DONE;
+ ret = record_header_flag_dirty((uint32_t*)desc.p_record, page);
+ break;
+
+ case FDS_OP_WRITE_DONE:
+ ret = FDS_OP_COMPLETED;
+
+#if (FDS_CRC_CHECK_ON_WRITE)
+ if (!crc_verify_success(p_op->write.header.crc16,
+ p_op->write.header.length_words,
+ p_write_addr))
+ {
+ ret = FDS_ERR_CRC_CHECK_FAILED;
+ }
+#endif
+ break;
+
+ default:
+ ret = FDS_ERR_INTERNAL;
+ break;
+ }
+
+ // An operation has either completed or failed. It may have failed because fstorage
+ // ran out of memory, or because the user tried to delete a record which did not exist.
+ if (ret != FDS_OP_EXECUTING)
+ {
+ // There won't be another callback for this operation, so update the page offset now.
+ page_offsets_update(p_page, p_op);
+ }
+
+ return ret;
+}
+
+
+static ret_code_t delete_execute(uint32_t prev_ret, fds_op_t * const p_op)
+{
+ ret_code_t ret;
+
+ if (prev_ret != NRF_SUCCESS)
+ {
+ return FDS_ERR_OPERATION_TIMEOUT;
+ }
+
+ switch (p_op->del.step)
+ {
+ case FDS_OP_DEL_RECORD_FLAG_DIRTY:
+ p_op->del.step = FDS_OP_DEL_DONE;
+ ret = record_find_and_delete(p_op);
+ break;
+
+ case FDS_OP_DEL_FILE_FLAG_DIRTY:
+ ret = file_find_and_delete(p_op);
+ if (ret == FDS_ERR_NOT_FOUND)
+ {
+ // No more records could be found.
+ // There won't be another callback for this operation, so return now.
+ ret = FDS_OP_COMPLETED;
+ }
+ break;
+
+ case FDS_OP_DEL_DONE:
+ ret = FDS_OP_COMPLETED;
+ break;
+
+ default:
+ ret = FDS_ERR_INTERNAL;
+ break;
+ }
+
+ return ret;
+}
+
+
+static ret_code_t gc_execute(uint32_t prev_ret)
+{
+ ret_code_t ret;
+
+ if (prev_ret != NRF_SUCCESS)
+ {
+ return FDS_ERR_OPERATION_TIMEOUT;
+ }
+
+ if (m_gc.resume)
+ {
+ m_gc.resume = false;
+ }
+ else
+ {
+ gc_state_advance();
+ }
+
+ switch (m_gc.state)
+ {
+ case GC_NEXT_PAGE:
+ ret = gc_next_page();
+ break;
+
+ case GC_FIND_NEXT_RECORD:
+ ret = gc_record_find_next();
+ break;
+
+ case GC_COPY_RECORD:
+ ret = gc_record_copy();
+ break;
+
+ case GC_ERASE_PAGE:
+ ret = gc_page_erase();
+ break;
+
+ case GC_PROMOTE_SWAP:
+ ret = gc_swap_promote();
+ break;
+
+ case GC_TAG_NEW_SWAP:
+ ret = gc_tag_new_swap();
+ break;
+
+ default:
+ // Should not happen.
+ ret = FDS_ERR_INTERNAL;
+ break;
+ }
+
+ // Either FDS_OP_EXECUTING, FDS_OP_COMPLETED, FDS_ERR_BUSY or FDS_ERR_INTERNAL.
+ return ret;
+}
+
+
+static void queue_process(ret_code_t result)
+{
+ static fds_op_t * m_p_cur_op; // Current fds operation.
+ static nrf_atfifo_item_get_t m_iget_ctx; // Queue context for the current operation.
+
+ while (true)
+ {
+ if (m_p_cur_op == NULL)
+ {
+ // Load the next from the queue if no operation is being executed.
+ m_p_cur_op = queue_load(&m_iget_ctx);
+ }
+
+ /* We can reach here in three ways:
+ * from queue_start(): something was just queued
+ * from the fstorage event handler: an operation is being executed
+ * looping: we only loop if there are operations still in the queue
+ *
+ * In all these three cases, m_p_cur_op != NULL.
+ */
+ ASSERT(m_p_cur_op != NULL);
+
+ switch (m_p_cur_op->op_code)
+ {
+ case FDS_OP_INIT:
+ result = init_execute(result, m_p_cur_op);
+ break;
+
+ case FDS_OP_WRITE:
+ case FDS_OP_UPDATE:
+ result = write_execute(result, m_p_cur_op);
+ break;
+
+ case FDS_OP_DEL_RECORD:
+ case FDS_OP_DEL_FILE:
+ result = delete_execute(result, m_p_cur_op);
+ break;
+
+ case FDS_OP_GC:
+ result = gc_execute(result);
+ break;
+
+ default:
+ result = FDS_ERR_INTERNAL;
+ break;
+ }
+
+ if (result == FDS_OP_EXECUTING)
+ {
+ // The operation has not completed yet. Wait for the next system event.
+ break;
+ }
+
+ // The operation has completed (either successfully or with an error).
+ // - send an event to the user
+ // - free the operation buffer
+ // - execute any other queued operations
+
+ fds_evt_t evt =
+ {
+ // The operation might have failed for one of the following reasons:
+ // FDS_ERR_BUSY - flash subsystem can't accept the operation
+ // FDS_ERR_OPERATION_TIMEOUT - flash subsystem timed out
+ // FDS_ERR_CRC_CHECK_FAILED - a CRC check failed
+ // FDS_ERR_NOT_FOUND - no record found (delete/update)
+ .result = (result == FDS_OP_COMPLETED) ? FDS_SUCCESS : result,
+ };
+
+ event_prepare(m_p_cur_op, &evt);
+ event_send(&evt);
+
+ // Zero the pointer to the current operation so that this function
+ // will fetch a new one from the queue next time it is run.
+ m_p_cur_op = NULL;
+
+ // The result of the operation must be reset upon re-entering the loop to ensure
+ // the next operation won't be affected by eventual errors in previous operations.
+ result = NRF_SUCCESS;
+
+ // Free the queue element used by the current operation.
+ queue_free(&m_iget_ctx);
+
+ if (!queue_has_next())
+ {
+ // No more elements left. Nothing to do.
+ break;
+ }
+ }
+}
+
+
+static void queue_start(void)
+{
+ if (!nrf_atomic_u32_fetch_add(&m_queued_op_cnt, 1))
+ {
+ queue_process(NRF_SUCCESS);
+ }
+}
+
+
+static void fs_event_handler(nrf_fstorage_evt_t * p_evt)
+{
+ queue_process(p_evt->result);
+}
+
+
+// Enqueues write and update operations.
+static ret_code_t write_enqueue(fds_record_desc_t * const p_desc,
+ fds_record_t const * const p_record,
+ fds_reserve_token_t const * const p_tok,
+ fds_op_code_t op_code)
+{
+ ret_code_t ret;
+ uint16_t page;
+ uint16_t crc = 0;
+ uint16_t length_words = 0;
+ fds_op_t * p_op;
+ nrf_atfifo_item_put_t iput_ctx;
+
+ if (!m_flags.initialized)
+ {
+ return FDS_ERR_NOT_INITIALIZED;
+ }
+
+ if (p_record == NULL)
+ {
+ return FDS_ERR_NULL_ARG;
+ }
+
+ if ((p_record->file_id == FDS_FILE_ID_INVALID) ||
+ (p_record->key == FDS_RECORD_KEY_DIRTY))
+ {
+ return FDS_ERR_INVALID_ARG;
+ }
+
+ if (!is_word_aligned(p_record->data.p_data))
+ {
+ return FDS_ERR_UNALIGNED_ADDR;
+ }
+
+ // No space was previously reserved in flash for this operation.
+ if (p_tok == NULL)
+ {
+ // Find a page where to write data.
+ length_words = p_record->data.length_words;
+ ret = write_space_reserve(length_words, &page);
+
+ if (ret != FDS_SUCCESS)
+ {
+ // There is either not enough space in flash (FDS_ERR_NO_SPACE_IN_FLASH) or
+ // the record exceeds the size of virtual page (FDS_ERR_RECORD_TOO_LARGE).
+ return ret;
+ }
+ }
+ else
+ {
+ page = p_tok->page;
+ length_words = p_tok->length_words;
+ }
+
+ // Get a buffer on the queue of operations.
+ p_op = queue_buf_get(&iput_ctx);
+ if (p_op == NULL)
+ {
+ CRITICAL_SECTION_ENTER();
+ write_space_free(length_words, page);
+ CRITICAL_SECTION_EXIT();
+ return FDS_ERR_NO_SPACE_IN_QUEUES;
+ }
+
+ // Initialize the operation.
+ p_op->op_code = op_code;
+ p_op->write.step = FDS_OP_WRITE_HEADER_BEGIN;
+ p_op->write.page = page;
+ p_op->write.p_data = p_record->data.p_data;
+ p_op->write.header.record_id = record_id_new();
+ p_op->write.header.file_id = p_record->file_id;
+ p_op->write.header.record_key = p_record->key;
+ p_op->write.header.length_words = length_words;
+
+ if (op_code == FDS_OP_UPDATE)
+ {
+ p_op->write.step = FDS_OP_WRITE_FIND_RECORD;
+ // Save the record ID of the record to be updated.
+ p_op->write.record_to_delete = p_desc->record_id;
+ }
+
+#if (FDS_CRC_CHECK_ON_READ)
+ // First, compute the CRC for the first 6 bytes of the header which contain the
+ // record key, length and file ID, then, compute the CRC of the record ID (4 bytes).
+ crc = crc16_compute((uint8_t*)&p_op->write.header, 6, NULL);
+ crc = crc16_compute((uint8_t*)&p_op->write.header.record_id, 4, &crc);
+
+ // Compute the CRC for the record data.
+ crc = crc16_compute((uint8_t*)p_record->data.p_data,
+ p_record->data.length_words * sizeof(uint32_t), &crc);
+#endif
+
+ p_op->write.header.crc16 = crc;
+
+ queue_buf_store(&iput_ctx);
+
+ // Initialize the record descriptor, if provided.
+ if (p_desc != NULL)
+ {
+ p_desc->p_record = NULL;
+ // Don't invoke record_id_new() again !
+ p_desc->record_id = p_op->write.header.record_id;
+ p_desc->record_is_open = false;
+ p_desc->gc_run_count = m_gc.run_count;
+ }
+
+ // Start processing the queue, if necessary.
+ queue_start();
+
+ return FDS_SUCCESS;
+}
+
+
+ret_code_t fds_register(fds_cb_t cb)
+{
+ ret_code_t ret;
+
+ if (m_users == FDS_MAX_USERS)
+ {
+ ret = FDS_ERR_USER_LIMIT_REACHED;
+ }
+ else
+ {
+ m_cb_table[m_users] = cb;
+ (void) nrf_atomic_u32_add(&m_users, 1);
+
+ ret = FDS_SUCCESS;
+ }
+
+ return ret;
+}
+
+
+static uint32_t flash_end_addr(void)
+{
+ uint32_t const bootloader_addr = NRF_UICR->NRFFW[0];
+ uint32_t const page_sz = NRF_FICR->CODEPAGESIZE;
+#ifndef NRF52810_XXAA
+ uint32_t const code_sz = NRF_FICR->CODESIZE;
+#else
+ // Number of flash pages, necessary to emulate the NRF52810 on NRF52832.
+ uint32_t const code_sz = 48;
+#endif
+
+ return (bootloader_addr != 0xFFFFFFFF) ? bootloader_addr : (code_sz * page_sz);
+}
+
+
+static void flash_bounds_set(void)
+{
+ uint32_t flash_size = (FDS_PHY_PAGES * FDS_PHY_PAGE_SIZE * sizeof(uint32_t));
+ m_fs.end_addr = flash_end_addr();
+ m_fs.start_addr = m_fs.end_addr - flash_size;
+}
+
+
+static ret_code_t flash_subsystem_init(void)
+{
+ flash_bounds_set();
+
+ #if (FDS_BACKEND == NRF_FSTORAGE_SD)
+ return nrf_fstorage_init(&m_fs, &nrf_fstorage_sd, NULL);
+ #elif (FDS_BACKEND == NRF_FSTORAGE_NVMC)
+ return nrf_fstorage_init(&m_fs, &nrf_fstorage_nvmc, NULL);
+ #else
+ #error Invalid FDS_BACKEND.
+ #endif
+}
+
+
+static void queue_init(void)
+{
+ (void) NRF_ATFIFO_INIT(m_queue);
+}
+
+
+ret_code_t fds_init(void)
+{
+ ret_code_t ret;
+ fds_evt_t const evt_success =
+ {
+ .id = FDS_EVT_INIT,
+ .result = FDS_SUCCESS,
+ };
+
+ if (m_flags.initialized)
+ {
+ // No initialization is necessary. Notify the application immediately.
+ event_send(&evt_success);
+ return FDS_SUCCESS;
+ }
+
+ if (nrf_atomic_flag_set_fetch(&m_flags.initializing))
+ {
+ // If we were already initializing, return.
+ return FDS_SUCCESS;
+ }
+
+ // Otherwise, the flag is set and we proceed to initialization.
+
+ ret = flash_subsystem_init();
+ if (ret != NRF_SUCCESS)
+ {
+ return ret;
+ }
+
+ queue_init();
+
+ // Initialize the page structure (m_pages), and determine which
+ // initialization steps are required given the current state of the filesystem.
+
+ fds_init_opts_t init_opts = pages_init();
+
+ switch (init_opts)
+ {
+ case NO_PAGES:
+ case NO_SWAP:
+ return FDS_ERR_NO_PAGES;
+
+ case ALREADY_INSTALLED:
+ {
+ // No initialization is necessary. Notify the application immediately.
+ m_flags.initialized = true;
+ m_flags.initializing = false;
+ event_send(&evt_success);
+ return FDS_SUCCESS;
+ }
+
+ default:
+ break;
+ }
+
+ // A write operation is necessary to initialize the fileystem.
+
+ nrf_atfifo_item_put_t iput_ctx;
+
+ fds_op_t * p_op = queue_buf_get(&iput_ctx);
+ if (p_op == NULL)
+ {
+ return FDS_ERR_NO_SPACE_IN_QUEUES;
+ }
+
+ p_op->op_code = FDS_OP_INIT;
+
+ switch (init_opts)
+ {
+ case FRESH_INSTALL:
+ case TAG_SWAP:
+ p_op->init.step = FDS_OP_INIT_TAG_SWAP;
+ break;
+
+ case PROMOTE_SWAP:
+ case PROMOTE_SWAP_INST:
+ p_op->init.step = FDS_OP_INIT_PROMOTE_SWAP;
+ break;
+
+ case DISCARD_SWAP:
+ p_op->init.step = FDS_OP_INIT_ERASE_SWAP;
+ break;
+
+ case TAG_DATA:
+ case TAG_DATA_INST:
+ p_op->init.step = FDS_OP_INIT_TAG_DATA;
+ break;
+
+ default:
+ // Should not happen.
+ break;
+ }
+
+ queue_buf_store(&iput_ctx);
+ queue_start();
+
+ return FDS_SUCCESS;
+}
+
+
+ret_code_t fds_record_open(fds_record_desc_t * const p_desc,
+ fds_flash_record_t * const p_flash_rec)
+{
+ uint16_t page;
+
+ if ((p_desc == NULL) || (p_flash_rec == NULL))
+ {
+ return FDS_ERR_NULL_ARG;
+ }
+
+ // Find the record if necessary.
+ if (record_find_by_desc(p_desc, &page))
+ {
+ fds_header_t const * const p_header = (fds_header_t*)p_desc->p_record;
+
+#if (FDS_CRC_CHECK_ON_READ)
+ if (!crc_verify_success(p_header->crc16,
+ p_header->length_words,
+ p_desc->p_record))
+ {
+ return FDS_ERR_CRC_CHECK_FAILED;
+ }
+#endif
+
+ (void) nrf_atomic_u32_add(&m_pages[page].records_open, 1);
+
+ // Initialize p_flash_rec.
+ p_flash_rec->p_header = p_header;
+ p_flash_rec->p_data = (p_desc->p_record + FDS_HEADER_SIZE);
+
+ // Set the record as open in the descriptor.
+ p_desc->record_is_open = true;
+
+ return FDS_SUCCESS;
+ }
+
+ // The record could not be found.
+ // It either never existed or it has been deleted.
+ return FDS_ERR_NOT_FOUND;
+}
+
+
+ret_code_t fds_record_close(fds_record_desc_t * const p_desc)
+{
+ ret_code_t ret;
+ uint16_t page;
+
+ if (p_desc == NULL)
+ {
+ return FDS_ERR_NULL_ARG;
+ }
+
+ if (record_find_by_desc((fds_record_desc_t*)p_desc, &page))
+ {
+ CRITICAL_SECTION_ENTER();
+ if ((m_pages[page].records_open > 0) && (p_desc->record_is_open))
+ {
+
+ m_pages[page].records_open--;
+ p_desc->record_is_open = false;
+
+ ret = FDS_SUCCESS;
+ }
+ else
+ {
+ ret = FDS_ERR_NO_OPEN_RECORDS;
+ }
+ CRITICAL_SECTION_EXIT();
+ }
+ else
+ {
+ ret = FDS_ERR_NOT_FOUND;
+ }
+
+ return ret;
+}
+
+
+ret_code_t fds_reserve(fds_reserve_token_t * const p_tok, uint16_t length_words)
+{
+ ret_code_t ret;
+ uint16_t page;
+
+ if (!m_flags.initialized)
+ {
+ return FDS_ERR_NOT_INITIALIZED;
+ }
+
+ if (p_tok == NULL)
+ {
+ return FDS_ERR_NULL_ARG;
+ }
+
+ ret = write_space_reserve(length_words, &page);
+
+ if (ret == FDS_SUCCESS)
+ {
+ p_tok->page = page;
+ p_tok->length_words = length_words;
+ }
+
+ return ret;
+}
+
+
+ret_code_t fds_reserve_cancel(fds_reserve_token_t * const p_tok)
+{
+ ret_code_t ret;
+
+ if (!m_flags.initialized)
+ {
+ return FDS_ERR_NOT_INITIALIZED;
+ }
+
+ if (p_tok == NULL)
+ {
+ return FDS_ERR_NULL_ARG;
+ }
+
+ if (p_tok->page > FDS_DATA_PAGES)
+ {
+ // The page does not exist. This shouldn't happen.
+ return FDS_ERR_INVALID_ARG;
+ }
+
+ fds_page_t const * const p_page = &m_pages[p_tok->page];
+
+ CRITICAL_SECTION_ENTER();
+ if ((FDS_HEADER_SIZE + p_tok->length_words) <= p_page->words_reserved)
+ {
+ // Free reserved space.
+ write_space_free(p_tok->length_words, p_tok->page);
+
+ // Clean the token.
+ p_tok->page = 0;
+ p_tok->length_words = 0;
+ ret = FDS_SUCCESS;
+ }
+ else
+ {
+ // We are trying to cancel a reservation of more words than how many are
+ // currently reserved on the page. Clearly, this shouldn't happen.
+ ret = FDS_ERR_INVALID_ARG;
+ }
+ CRITICAL_SECTION_EXIT();
+
+ return ret;
+}
+
+
+ret_code_t fds_record_write(fds_record_desc_t * const p_desc,
+ fds_record_t const * const p_record)
+{
+ return write_enqueue(p_desc, p_record, NULL, FDS_OP_WRITE);
+}
+
+
+ret_code_t fds_record_write_reserved(fds_record_desc_t * const p_desc,
+ fds_record_t const * const p_record,
+ fds_reserve_token_t const * const p_tok)
+{
+ // A NULL token is not allowed when writing to a reserved space.
+ if (p_tok == NULL)
+ {
+ return FDS_ERR_NULL_ARG;
+ }
+
+ return write_enqueue(p_desc, p_record, p_tok, FDS_OP_WRITE);
+}
+
+
+ret_code_t fds_record_update(fds_record_desc_t * const p_desc,
+ fds_record_t const * const p_record)
+{
+ // A NULL descriptor is not allowed when updating a record.
+ if (p_desc == NULL)
+ {
+ return FDS_ERR_NULL_ARG;
+ }
+
+ return write_enqueue(p_desc, p_record, NULL, FDS_OP_UPDATE);
+}
+
+
+ret_code_t fds_record_delete(fds_record_desc_t * const p_desc)
+{
+ fds_op_t * p_op;
+ nrf_atfifo_item_put_t iput_ctx;
+
+ if (!m_flags.initialized)
+ {
+ return FDS_ERR_NOT_INITIALIZED;
+ }
+
+ if (p_desc == NULL)
+ {
+ return FDS_ERR_NULL_ARG;
+ }
+
+ p_op = queue_buf_get(&iput_ctx);
+ if (p_op == NULL)
+ {
+ return FDS_ERR_NO_SPACE_IN_QUEUES;
+ }
+
+ p_op->op_code = FDS_OP_DEL_RECORD;
+ p_op->del.step = FDS_OP_DEL_RECORD_FLAG_DIRTY;
+ p_op->del.record_to_delete = p_desc->record_id;
+
+ queue_buf_store(&iput_ctx);
+ queue_start();
+
+ return FDS_SUCCESS;
+}
+
+
+ret_code_t fds_file_delete(uint16_t file_id)
+{
+ fds_op_t * p_op;
+ nrf_atfifo_item_put_t iput_ctx;
+
+ if (!m_flags.initialized)
+ {
+ return FDS_ERR_NOT_INITIALIZED;
+ }
+
+ if (file_id == FDS_FILE_ID_INVALID)
+ {
+ return FDS_ERR_INVALID_ARG;
+ }
+
+ p_op = queue_buf_get(&iput_ctx);
+ if (p_op == NULL)
+ {
+ return FDS_ERR_NO_SPACE_IN_QUEUES;
+ }
+
+ p_op->op_code = FDS_OP_DEL_FILE;
+ p_op->del.step = FDS_OP_DEL_FILE_FLAG_DIRTY;
+ p_op->del.file_id = file_id;
+
+ queue_buf_store(&iput_ctx);
+ queue_start();
+
+ return FDS_SUCCESS;
+}
+
+
+ret_code_t fds_gc(void)
+{
+ fds_op_t * p_op;
+ nrf_atfifo_item_put_t iput_ctx;
+
+ if (!m_flags.initialized)
+ {
+ return FDS_ERR_NOT_INITIALIZED;
+ }
+
+ p_op = queue_buf_get(&iput_ctx);
+ if (p_op == NULL)
+ {
+ return FDS_ERR_NO_SPACE_IN_QUEUES;
+ }
+
+ p_op->op_code = FDS_OP_GC;
+
+ queue_buf_store(&iput_ctx);
+
+ if (m_gc.state != GC_BEGIN)
+ {
+ // Resume GC by retrying the last step.
+ m_gc.resume = true;
+ }
+
+ queue_start();
+
+ return FDS_SUCCESS;
+}
+
+
+ret_code_t fds_record_iterate(fds_record_desc_t * const p_desc,
+ fds_find_token_t * const p_token)
+{
+ return record_find(NULL, NULL, p_desc, p_token);
+}
+
+
+ret_code_t fds_record_find(uint16_t file_id,
+ uint16_t record_key,
+ fds_record_desc_t * const p_desc,
+ fds_find_token_t * const p_token)
+{
+ return record_find(&file_id, &record_key, p_desc, p_token);
+}
+
+
+ret_code_t fds_record_find_by_key(uint16_t record_key,
+ fds_record_desc_t * const p_desc,
+ fds_find_token_t * const p_token)
+{
+ return record_find(NULL, &record_key, p_desc, p_token);
+}
+
+
+ret_code_t fds_record_find_in_file(uint16_t file_id,
+ fds_record_desc_t * const p_desc,
+ fds_find_token_t * const p_token)
+{
+ return record_find(&file_id, NULL, p_desc, p_token);
+}
+
+
+ret_code_t fds_descriptor_from_rec_id(fds_record_desc_t * const p_desc,
+ uint32_t record_id)
+{
+ if (p_desc == NULL)
+ {
+ return FDS_ERR_NULL_ARG;
+ }
+
+ // Zero the descriptor and set the record_id field.
+ memset(p_desc, 0x00, sizeof(fds_record_desc_t));
+ p_desc->record_id = record_id;
+
+ return FDS_SUCCESS;
+}
+
+
+ret_code_t fds_record_id_from_desc(fds_record_desc_t const * const p_desc,
+ uint32_t * const p_record_id)
+{
+ if ((p_desc == NULL) || (p_record_id == NULL))
+ {
+ return FDS_ERR_NULL_ARG;
+ }
+
+ *p_record_id = p_desc->record_id;
+
+ return FDS_SUCCESS;
+}
+
+
+ret_code_t fds_stat(fds_stat_t * const p_stat)
+{
+ uint16_t const words_in_page = FDS_PAGE_SIZE;
+ // The largest number of free contiguous words on any page.
+ uint16_t contig_words = 0;
+
+ if (!m_flags.initialized)
+ {
+ return FDS_ERR_NOT_INITIALIZED;
+ }
+
+ if (p_stat == NULL)
+ {
+ return FDS_ERR_NULL_ARG;
+ }
+
+ memset(p_stat, 0x00, sizeof(fds_stat_t));
+
+ p_stat->pages_available = FDS_VIRTUAL_PAGES;
+
+ for (uint16_t page = 0; page < FDS_DATA_PAGES; page++)
+ {
+ uint16_t const words_used = m_pages[page].write_offset + m_pages[page].words_reserved;
+
+ if (page_identify(m_pages[page].p_addr) == FDS_PAGE_UNDEFINED)
+ {
+ p_stat->pages_available--;
+ }
+
+ p_stat->open_records += m_pages[page].records_open;
+ p_stat->words_reserved += m_pages[page].words_reserved;
+ p_stat->words_used += words_used;
+
+ contig_words = (words_in_page - words_used);
+ if (contig_words > p_stat->largest_contig)
+ {
+ p_stat->largest_contig = contig_words;
+ }
+
+ records_stat(page,
+ &p_stat->valid_records,
+ &p_stat->dirty_records,
+ &p_stat->freeable_words,
+ &p_stat->corruption);
+ }
+
+ return FDS_SUCCESS;
+}
+
+#endif //NRF_MODULE_ENABLED(FDS)
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/fds/fds.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/fds/fds.h
new file mode 100644
index 0000000..09d1eea
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/fds/fds.h
@@ -0,0 +1,700 @@
+/**
+ * Copyright (c) 2015 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#ifndef FDS_H__
+#define FDS_H__
+
+/**
+ * @defgroup fds Flash Data Storage
+ * @ingroup app_common
+ * @{
+ *
+ * @brief Flash Data Storage (FDS).
+ *
+ * @details Flash Data Storage is a minimalistic, record-oriented file system for the on-chip
+ * flash. Files are stored as a collection of records of variable length. FDS supports
+ * synchronous read operations and asynchronous write operations (write, update,
+ * and delete). FDS can be used from multiple threads.
+ */
+
+#include <stdint.h>
+#include <stdbool.h>
+#include "sdk_errors.h"
+#include "app_util_platform.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+/**@brief Invalid file ID.
+ *
+ * This value must not be used as a file ID by the application.
+ */
+#define FDS_FILE_ID_INVALID (0xFFFF)
+
+
+/**@brief Record key for deleted records.
+ *
+ * This key is used to flag a record as "dirty", which means that it should be removed during
+ * the next garbage collection. This value must not be used as a record key by the application.
+ */
+#define FDS_RECORD_KEY_DIRTY (0x0000)
+
+
+/**@brief FDS return values.
+ */
+enum
+{
+ FDS_SUCCESS = NRF_SUCCESS, //!< The operation completed successfully.
+ FDS_ERR_OPERATION_TIMEOUT, //!< Error. The operation timed out.
+ FDS_ERR_NOT_INITIALIZED, //!< Error. The module has not been initialized.
+ FDS_ERR_UNALIGNED_ADDR, //!< Error. The input data is not aligned to a word boundary.
+ FDS_ERR_INVALID_ARG, //!< Error. The parameter contains invalid data.
+ FDS_ERR_NULL_ARG, //!< Error. The parameter is NULL.
+ FDS_ERR_NO_OPEN_RECORDS, //!< Error. The record is not open, so it cannot be closed.
+ FDS_ERR_NO_SPACE_IN_FLASH, //!< Error. There is no space in flash memory.
+ FDS_ERR_NO_SPACE_IN_QUEUES, //!< Error. There is no space in the internal queues.
+ FDS_ERR_RECORD_TOO_LARGE, //!< Error. The record exceeds the maximum allowed size.
+ FDS_ERR_NOT_FOUND, //!< Error. The record was not found.
+ FDS_ERR_NO_PAGES, //!< Error. No flash pages are available.
+ FDS_ERR_USER_LIMIT_REACHED, //!< Error. The maximum number of users has been reached.
+ FDS_ERR_CRC_CHECK_FAILED, //!< Error. The CRC check failed.
+ FDS_ERR_BUSY, //!< Error. The underlying flash subsystem was busy.
+ FDS_ERR_INTERNAL, //!< Error. An internal error occurred.
+};
+
+
+/**@brief The record metadata as stored in flash.
+ * @warning Do not edit or reorder the fields in this structure.
+ */
+typedef struct
+{
+ uint16_t record_key; //!< The record key.
+ uint16_t length_words; //!< The length of the record data (in 4-byte words).
+ uint16_t file_id; //!< The ID of the file that the record belongs to.
+ uint16_t crc16; //!< CRC16-CCITT check value.
+ /* The CRC is calculated over the entire record as stored in flash,
+ * including the record metadata except the CRC field itself.
+ */
+ uint32_t record_id; //!< The unique record ID (32 bits).
+} fds_header_t;
+
+
+/**@brief The record descriptor structure that is used to manipulate records.
+ *
+ * This structure is used by the FDS module. You must provide the descriptor to the module when
+ * you manipulate existing records. However, you should never modify it or use any of its fields.
+ *
+ * @note Never reuse the same descriptor for different records.
+ */
+typedef struct
+{
+ uint32_t record_id; //!< The unique record ID.
+ uint32_t const * p_record; //!< The last known location of the record in flash.
+ uint16_t gc_run_count; //!< Number of times garbage collection has been run.
+ bool record_is_open; //!< Whether the record is currently open.
+} fds_record_desc_t;
+
+
+/**@brief Structure that can be used to read the contents of a record stored in flash.
+ *
+ * This structure does not reflect the physical layout of a record in flash, but it points
+ * to the locations where the record header (metadata) and the record data are stored.
+ */
+typedef struct
+{
+ fds_header_t const * p_header; //!< Location of the record header in flash.
+ void const * p_data; //!< Location of the record data in flash.
+} fds_flash_record_t;
+
+
+/**@brief A record to be written to flash. */
+typedef struct
+{
+ uint16_t file_id; //!< The ID of the file that the record belongs to.
+ uint16_t key; //!< The record key.
+ struct
+ {
+ void const * p_data;
+ uint32_t length_words;
+ } data;
+} fds_record_t;
+
+
+/**@brief A token to a reserved space in flash, created by @ref fds_reserve.
+ *
+ * This token can be used to write the record in the reserved space (@ref fds_record_write_reserved)
+ * or to cancel the reservation (@ref fds_reserve_cancel).
+ */
+typedef struct
+{
+ uint16_t page; //!< The logical ID of the page where space was reserved.
+ uint16_t length_words; //!< The amount of space reserved (in 4-byte words).
+} fds_reserve_token_t;
+
+
+/**@brief A token to keep information about the progress of @ref fds_record_find,
+ * @ref fds_record_find_by_key, and @ref fds_record_find_in_file.
+ *
+ * @note Always zero-initialize the token before using it for the first time.
+ * @note Never reuse the same token to search for different records.
+ */
+typedef struct
+{
+ uint32_t const * p_addr;
+ uint16_t page;
+} fds_find_token_t;
+
+
+/**@brief FDS event IDs.
+ */
+typedef enum
+{
+ FDS_EVT_INIT, //!< Event for @ref fds_init.
+ FDS_EVT_WRITE, //!< Event for @ref fds_record_write and @ref fds_record_write_reserved.
+ FDS_EVT_UPDATE, //!< Event for @ref fds_record_update.
+ FDS_EVT_DEL_RECORD, //!< Event for @ref fds_record_delete.
+ FDS_EVT_DEL_FILE, //!< Event for @ref fds_file_delete.
+ FDS_EVT_GC //!< Event for @ref fds_gc.
+} fds_evt_id_t;
+
+
+ANON_UNIONS_ENABLE;
+
+/**@brief An FDS event. */
+typedef struct
+{
+ fds_evt_id_t id; //!< The event ID. See @ref fds_evt_id_t.
+ ret_code_t result; //!< The result of the operation related to this event.
+ union
+ {
+ struct
+ {
+ uint32_t record_id;
+ uint16_t file_id;
+ uint16_t record_key;
+ bool is_record_updated;
+ } write; //!< Information for @ref FDS_EVT_WRITE and @ref FDS_EVT_UPDATE events.
+ struct
+ {
+ uint32_t record_id;
+ uint16_t file_id;
+ uint16_t record_key;
+ } del; //!< Information for @ref FDS_EVT_DEL_RECORD and @ref FDS_EVT_DEL_FILE events.
+ };
+} fds_evt_t;
+
+ANON_UNIONS_DISABLE;
+
+
+/**@brief File system statistics. */
+typedef struct
+{
+ uint16_t pages_available; //!< The number of pages available.
+ uint16_t open_records; //!< The number of open records.
+ uint16_t valid_records; //!< The number of valid records.
+ uint16_t dirty_records; //!< The number of deleted ("dirty") records.
+ uint16_t words_reserved; //!< The number of words reserved by @ref fds_reserve().
+
+ /**@brief The number of words written to flash, including those reserved for future writes. */
+ uint16_t words_used;
+
+ /**@brief The largest number of free contiguous words in the file system.
+ *
+ * This number indicates the largest record that can be stored by FDS.
+ * It takes into account all reservations for future writes.
+ */
+ uint16_t largest_contig;
+
+ /**@brief The largest number of words that can be reclaimed by garbage collection.
+ *
+ * The actual amount of space freed by garbage collection might be less than this value if
+ * records are open while garbage collection is run.
+ */
+ uint16_t freeable_words;
+
+ /**@brief Filesystem corruption has been detected.
+ *
+ * One or more corrupted records were detected. FDS will heal the filesystem automatically
+ * next time garbage collection is run, but some data may be lost.
+ *
+ * @note: This flag is unrelated to CRC failures.
+ */
+ bool corruption;
+} fds_stat_t;
+
+
+/**@brief FDS event handler function prototype.
+ *
+ * @param p_evt The event.
+ */
+typedef void (*fds_cb_t)(fds_evt_t const * p_evt);
+
+
+/**@brief Function for registering an FDS event handler.
+ *
+ * The maximum amount of handlers that can be registered can be configured by changing the value
+ * of @ref FDS_MAX_USERS in fds_config.h.
+ *
+ * @param[in] cb The event handler function.
+ *
+ * @retval FDS_SUCCESS If the event handler was registered successfully.
+ * @retval FDS_ERR_USER_LIMIT_REACHED If the maximum number of registered callbacks is reached.
+ */
+ret_code_t fds_register(fds_cb_t cb);
+
+
+/**@brief Function for initializing the module.
+ *
+ * This function initializes the module and installs the file system (unless it is installed
+ * already).
+ *
+ * This function is asynchronous. Completion is reported through an event. Make sure to call
+ * @ref fds_register before calling @ref fds_init so that you receive the completion event.
+ *
+ * @retval FDS_SUCCESS If the operation was queued successfully.
+ * @retval FDS_ERR_NO_PAGES If there is no space available in flash memory to install the
+ * file system.
+ */
+ret_code_t fds_init(void);
+
+
+/**@brief Function for writing a record to flash.
+ *
+ * There are no restrictions on the file ID and the record key, except that the record key must be
+ * different from @ref FDS_RECORD_KEY_DIRTY and the file ID must be different from
+ * @ref FDS_FILE_ID_INVALID. In particular, no restrictions are made regarding the uniqueness of
+ * the file ID or the record key. All records with the same file ID are grouped into one file.
+ * If no file with the specified ID exists, it is created. There can be multiple records with the
+ * same record key in a file.
+ *
+ * Some modules need exclusive use of certain file IDs and record keys.
+ * See @ref lib_fds_functionality_keys for details.
+ *
+ * Record data can consist of multiple chunks. The data must be aligned to a 4 byte boundary, and
+ * because it is not buffered internally, it must be kept in memory until the callback for the
+ * operation has been received. The length of the data must not exceed @ref FDS_VIRTUAL_PAGE_SIZE
+ * words minus 14 bytes.
+ *
+ * This function is asynchronous. Completion is reported through an event that is sent to
+ * the registered event handler function.
+ *
+ * @param[out] p_desc The descriptor of the record that was written. Pass NULL if you do not
+ * need the descriptor.
+ * @param[in] p_record The record to be written to flash.
+ *
+ * @retval FDS_SUCCESS If the operation was queued successfully.
+ * @retval FDS_ERR_NOT_INITIALIZED If the module is not initialized.
+ * @retval FDS_ERR_NULL_ARG If @p p_record is NULL.
+ * @retval FDS_ERR_INVALID_ARG If the file ID or the record key is invalid.
+ * @retval FDS_ERR_UNALIGNED_ADDR If the record data is not aligned to a 4 byte boundary.
+ * @retval FDS_ERR_RECORD_TOO_LARGE If the record data exceeds the maximum length.
+ * @retval FDS_ERR_NO_SPACE_IN_QUEUES If the operation queue is full or there are more record
+ * chunks than can be buffered.
+ * @retval FDS_ERR_NO_SPACE_IN_FLASH If there is not enough free space in flash to store the
+ * record.
+ */
+ret_code_t fds_record_write(fds_record_desc_t * p_desc,
+ fds_record_t const * p_record);
+
+
+/**@brief Function for reserving space in flash.
+ *
+ * This function can be used to reserve space in flash memory. To write a record into the reserved
+ * space, use @ref fds_record_write_reserved. Alternatively, use @ref fds_reserve_cancel to cancel
+ * a reservation.
+ *
+ * Note that this function does not write any data to flash.
+ *
+ * @param[out] p_token A token that can be used to write a record in the reserved space or
+ * cancel the reservation.
+ * @param[in] length_words The length of the record data (in 4-byte words).
+ *
+ * @retval FDS_SUCCESS If the flash space was reserved successfully.
+ * @retval FDS_ERR_NOT_INITIALIZED If the module is not initialized.
+ * @retval FDS_ERR_NULL_ARG If @p p_token is NULL instead of a valid token address.
+ * @retval FDS_ERR_RECORD_TOO_LARGE If the record length exceeds the maximum length.
+ * @retval FDS_ERR_NO_SPACE_IN_FLASH If there is not enough free space in flash to store the
+ * record.
+ */
+ret_code_t fds_reserve(fds_reserve_token_t * p_token, uint16_t length_words);
+
+
+/**@brief Function for canceling an @ref fds_reserve operation.
+ *
+ * @param[in] p_token The token that identifies the reservation, produced by @ref fds_reserve.
+ *
+ * @retval FDS_SUCCESS If the reservation was canceled.
+ * @retval FDS_ERR_NOT_INITIALIZED If the module is not initialized.
+ * @retval FDS_ERR_NULL_ARG If @p p_token is NULL instead of a valid token address.
+ * @retval FDS_ERR_INVALID_ARG If @p p_token contains invalid data.
+ */
+ret_code_t fds_reserve_cancel(fds_reserve_token_t * p_token);
+
+
+/**@brief Function for writing a record to a space in flash that was reserved using
+ * @ref fds_reserve.
+ *
+ * There are no restrictions on the file ID and the record key, except that the record key must be
+ * different from @ref FDS_RECORD_KEY_DIRTY and the file ID must be different from
+ * @ref FDS_FILE_ID_INVALID. In particular, no restrictions are made regarding the uniqueness of
+ * the file ID or the record key. All records with the same file ID are grouped into one file.
+ * If no file with the specified ID exists, it is created. There can be multiple records with the
+ * same record key in a file.
+ *
+ * Record data can consist of multiple chunks. The data must be aligned to a 4 byte boundary, and
+ * because it is not buffered internally, it must be kept in memory until the callback for the
+ * operation has been received. The length of the data must not exceed @ref FDS_VIRTUAL_PAGE_SIZE
+ * words minus 14 bytes.
+ *
+ * This function is asynchronous. Completion is reported through an event that is sent to the
+ * registered event handler function.
+ *
+ * @note
+ * This function behaves similarly to @ref fds_record_write, with the exception that it never
+ * fails with the error @ref FDS_ERR_NO_SPACE_IN_FLASH.
+ *
+ * @param[out] p_desc The descriptor of the record that was written. Pass NULL if you do not
+ * need the descriptor.
+ * @param[in] p_record The record to be written to flash.
+ * @param[in] p_token The token that identifies the space reserved in flash.
+ *
+ * @retval FDS_SUCCESS If the operation was queued successfully.
+ * @retval FDS_ERR_NOT_INITIALIZED If the module is not initialized.
+ * @retval FDS_ERR_NULL_ARG If @p p_token is NULL instead of a valid token address.
+ * @retval FDS_ERR_INVALID_ARG If the file ID or the record key is invalid.
+ * @retval FDS_ERR_UNALIGNED_ADDR If the record data is not aligned to a 4 byte boundary.
+ * @retval FDS_ERR_RECORD_TOO_LARGE If the record data exceeds the maximum length.
+ * @retval FDS_ERR_NO_SPACE_IN_QUEUES If the operation queue is full or there are more record
+ * chunks than can be buffered.
+ */
+ret_code_t fds_record_write_reserved(fds_record_desc_t * p_desc,
+ fds_record_t const * p_record,
+ fds_reserve_token_t const * p_token);
+
+
+/**@brief Function for deleting a record.
+ *
+ * Deleted records cannot be located using @ref fds_record_find, @ref fds_record_find_by_key, or
+ * @ref fds_record_find_in_file. Additionally, they can no longer be opened using
+ * @ref fds_record_open.
+ *
+ * Note that deleting a record does not free the space it occupies in flash memory.
+ * To reclaim flash space used by deleted records, call @ref fds_gc to run garbage collection.
+ *
+ * This function is asynchronous. Completion is reported through an event that is sent to the
+ * registered event handler function.
+ *
+ * @param[in] p_desc The descriptor of the record that should be deleted.
+ *
+ * @retval FDS_SUCCESS If the operation was queued successfully.
+ * @retval FDS_ERR_NOT_INITIALIZED If the module is not initialized.
+ * @retval FDS_ERR_NULL_ARG If the specified record descriptor @p p_desc is NULL.
+ * @retval FDS_ERR_NO_SPACE_IN_QUEUES If the operation queue is full.
+ */
+ret_code_t fds_record_delete(fds_record_desc_t * p_desc);
+
+
+/**@brief Function for deleting all records in a file.
+ *
+ * This function deletes a file, including all its records. Deleted records cannot be located
+ * using @ref fds_record_find, @ref fds_record_find_by_key, or @ref fds_record_find_in_file.
+ * Additionally, they can no longer be opened using @ref fds_record_open.
+ *
+ * Note that deleting records does not free the space they occupy in flash memory.
+ * To reclaim flash space used by deleted records, call @ref fds_gc to run garbage collection.
+ *
+ * This function is asynchronous. Completion is reported through an event that is sent to the
+ * registered event handler function.
+ *
+ * @param[in] file_id The ID of the file to be deleted.
+ *
+ * @retval FDS_SUCCESS If the operation was queued successfully.
+ * @retval FDS_ERR_NOT_INITIALIZED If the module is not initialized.
+ * @retval FDS_ERR_INVALID_ARG If the specified @p file_id is invalid.
+ * @retval FDS_ERR_NO_SPACE_IN_QUEUES If the operation queue is full.
+ */
+ret_code_t fds_file_delete(uint16_t file_id);
+
+
+/**@brief Function for updating a record.
+ *
+ * Updating a record first writes a new record (@p p_record) to flash and then deletes the
+ * old record (identified by @p p_desc).
+ *
+ * There are no restrictions on the file ID and the record key, except that the record key must be
+ * different from @ref FDS_RECORD_KEY_DIRTY and the file ID must be different from
+ * @ref FDS_FILE_ID_INVALID. In particular, no restrictions are made regarding the uniqueness of
+ * the file ID or the record key. All records with the same file ID are grouped into one file.
+ * If no file with the specified ID exists, it is created. There can be multiple records with the
+ * same record key in a file.
+ *
+ * Record data can consist of multiple chunks. The data must be aligned to a 4 byte boundary, and
+ * because it is not buffered internally, it must be kept in memory until the callback for the
+ * operation has been received. The length of the data must not exceed @ref FDS_VIRTUAL_PAGE_SIZE
+ * words minus 14 bytes.
+ *
+ * This function is asynchronous. Completion is reported through an event that is sent to the
+ * registered event handler function.
+ *
+ * @param[in, out] p_desc The descriptor of the record to update. When the function
+ * returns with FDS_SUCCESS, this parameter contains the
+ * descriptor of the newly written record.
+ * @param[in] p_record The updated record to be written to flash.
+ *
+ * @retval FDS_SUCCESS If the operation was queued successfully.
+ * @retval FDS_ERR_NOT_INITIALIZED If the module is not initialized.
+ * @retval FDS_ERR_INVALID_ARG If the file ID or the record key is invalid.
+ * @retval FDS_ERR_UNALIGNED_ADDR If the record data is not aligned to a 4 byte boundary.
+ * @retval FDS_ERR_RECORD_TOO_LARGE If the record data exceeds the maximum length.
+ * @retval FDS_ERR_NO_SPACE_IN_QUEUES If the operation queue is full or there are more record
+ * chunks than can be buffered.
+ * @retval FDS_ERR_NO_SPACE_IN_FLASH If there is not enough free space in flash to store the
+ * updated record.
+ */
+ret_code_t fds_record_update(fds_record_desc_t * p_desc,
+ fds_record_t const * p_record);
+
+
+/**@brief Function for iterating through all records in flash.
+ *
+ * To search for the next record, call the function again and supply the same @ref fds_find_token_t
+ * structure to resume searching from the last record that was found.
+ *
+ * Note that the order with which records are iterated is not defined.
+ *
+ * @param[out] p_desc The descriptor of the record that was found.
+ * @param[out] p_token A token containing information about the progress of the operation.
+ *
+ * @retval FDS_SUCCESS If a record was found.
+ * @retval FDS_ERR_NOT_INITIALIZED If the module is not initialized.
+ * @retval FDS_ERR_NULL_ARG If @p p_desc or @p p_token is NULL.
+ * @retval FDS_ERR_NOT_FOUND If no matching record was found.
+ */
+ret_code_t fds_record_iterate(fds_record_desc_t * p_desc,
+ fds_find_token_t * p_token);
+
+
+/**@brief Function for searching for records with a given record key in a file.
+ *
+ * This function finds the first record in a file that has the given record key. To search for the
+ * next record with the same key in the file, call the function again and supply the same
+ * @ref fds_find_token_t structure to resume searching from the last record that was found.
+ *
+ * @param[in] file_id The file ID.
+ * @param[in] record_key The record key.
+ * @param[out] p_desc The descriptor of the record that was found.
+ * @param[out] p_token A token containing information about the progress of the operation.
+ *
+ * @retval FDS_SUCCESS If a record was found.
+ * @retval FDS_ERR_NOT_INITIALIZED If the module is not initialized.
+ * @retval FDS_ERR_NULL_ARG If @p p_desc or @p p_token is NULL.
+ * @retval FDS_ERR_NOT_FOUND If no matching record was found.
+ */
+ret_code_t fds_record_find(uint16_t file_id,
+ uint16_t record_key,
+ fds_record_desc_t * p_desc,
+ fds_find_token_t * p_token);
+
+
+/**@brief Function for searching for records with a given record key.
+ *
+ * This function finds the first record with a given record key, independent of the file it
+ * belongs to. To search for the next record with the same key, call the function again and supply
+ * the same @ref fds_find_token_t structure to resume searching from the last record that was found.
+ *
+ * @param[in] record_key The record key.
+ * @param[out] p_desc The descriptor of the record that was found.
+ * @param[out] p_token A token containing information about the progress of the operation.
+ *
+ * @retval FDS_SUCCESS If a record was found.
+ * @retval FDS_ERR_NOT_INITIALIZED If the module is not initialized.
+ * @retval FDS_ERR_NULL_ARG If @p p_desc or @p p_token is NULL.
+ * @retval FDS_ERR_NOT_FOUND If no record with the given key was found.
+ */
+ret_code_t fds_record_find_by_key(uint16_t record_key,
+ fds_record_desc_t * p_desc,
+ fds_find_token_t * p_token);
+
+
+/**@brief Function for searching for any record in a file.
+ *
+ * This function finds the first record in a file, independent of its record key.
+ * To search for the next record in the same file, call the function again and supply the same
+ * @ref fds_find_token_t structure to resume searching from the last record that was found.
+ *
+ * @param[in] file_id The file ID.
+ * @param[out] p_desc The descriptor of the record that was found.
+ * @param[out] p_token A token containing information about the progress of the operation.
+ *
+ * @retval FDS_SUCCESS If a record was found.
+ * @retval FDS_ERR_NOT_INITIALIZED If the module is not initialized.
+ * @retval FDS_ERR_NULL_ARG If @p p_desc or @p p_token is NULL.
+ * @retval FDS_ERR_NOT_FOUND If no matching record was found.
+ */
+ret_code_t fds_record_find_in_file(uint16_t file_id,
+ fds_record_desc_t * p_desc,
+ fds_find_token_t * p_token);
+
+
+/**@brief Function for opening a record for reading.
+ *
+ * This function opens a record that is stored in flash, so that it can be read. The function
+ * initializes an @ref fds_flash_record_t structure, which can be used to access the record data as
+ * well as its associated metadata. The pointers provided in the @ref fds_flash_record_t structure
+ * are pointers to flash memory.
+ *
+ * Opening a record with @ref fds_record_open prevents garbage collection to run on the virtual
+ * flash page in which record is stored, so that the contents of the memory pointed by fields in
+ * @ref fds_flash_record_t are guaranteed to remain unmodified as long as the record is kept open.
+ *
+ * When you are done reading a record, call @ref fds_record_close to close it. Garbage collection
+ * can then reclaim space on the virtual page where the record is stored. Note that you must
+ * provide the same descriptor for @ref fds_record_close as you did for this function.
+ *
+ * @param[in] p_desc The descriptor of the record to open.
+ * @param[out] p_flash_record The record, as stored in flash.
+ *
+ * @retval FDS_SUCCESS If the record was opened successfully.
+ * @retval FDS_ERR_NULL_ARG If @p p_desc or @p p_flash_record is NULL.
+ * @retval FDS_ERR_NOT_FOUND If the record was not found. It might have been deleted, or
+ * it might not have been written yet.
+ * @retval FDS_ERR_CRC_CHECK_FAILED If the CRC check for the record failed.
+ */
+ret_code_t fds_record_open(fds_record_desc_t * p_desc,
+ fds_flash_record_t * p_flash_record);
+
+
+/**@brief Function for closing a record.
+ *
+ * Closing a record allows garbage collection to run on the virtual page in which the record is
+ * stored (if no other records remain open on that page). The descriptor passed as an argument
+ * must be the same as the one used to open the record using @ref fds_record_open.
+ *
+ * Note that closing a record does not invalidate its descriptor. You can still supply the
+ * descriptor to all functions that accept a record descriptor as a parameter.
+ *
+ * @param[in] p_desc The descriptor of the record to close.
+ *
+ * @retval FDS_SUCCESS If the record was closed successfully.
+ * @retval FDS_ERR_NULL_ARG If @p p_desc is NULL.
+ * @retval FDS_ERR_NO_OPEN_RECORDS If the record is not open.
+ * @retval FDS_ERR_NOT_FOUND If the record could not be found.
+ */
+ret_code_t fds_record_close(fds_record_desc_t * p_desc);
+
+
+/**@brief Function for running garbage collection.
+ *
+ * Garbage collection reclaims the flash space that is occupied by records that have been deleted,
+ * or that failed to be completely written due to, for example, a power loss.
+ *
+ * This function is asynchronous. Completion is reported through an event that is sent to the
+ * registered event handler function.
+ *
+ * @retval FDS_SUCCESS If the operation was queued successfully.
+ * @retval FDS_ERR_NOT_INITIALIZED If the module is not initialized.
+ * @retval FDS_ERR_NO_SPACE_IN_QUEUES If the operation queue is full.
+ */
+ret_code_t fds_gc(void);
+
+
+/**@brief Function for obtaining a descriptor from a record ID.
+ *
+ * This function can be used to reconstruct a descriptor from a record ID, like the one that is
+ * passed to the callback function.
+ *
+ * @note
+ * This function does not check whether a record with the given record ID exists.
+ * If a non-existing record ID is supplied, the resulting descriptor is invalid and will cause
+ * other functions to fail when it is supplied as parameter.
+ *
+ * @param[out] p_desc The descriptor of the record with the given record ID.
+ * @param[in] record_id The record ID for which a descriptor should be returned.
+ *
+ * @retval FDS_SUCCESS If a descriptor was returned.
+ * @retval FDS_ERR_NULL_ARG If @p p_desc is NULL.
+ */
+ret_code_t fds_descriptor_from_rec_id(fds_record_desc_t * p_desc,
+ uint32_t record_id);
+
+
+/**@brief Function for obtaining a record ID from a record descriptor.
+ *
+ * This function can be used to extract a record ID from a descriptor. For example, you could use
+ * it in the callback function to compare the record ID of an event to the record IDs of the
+ * records for which you have a descriptor.
+ *
+ * @warning
+ * This function does not check whether the record descriptor is valid. If the descriptor is not
+ * initialized or has been tampered with, the resulting record ID might be invalid.
+ *
+ * @param[in] p_desc The descriptor from which the record ID should be extracted.
+ * @param[out] p_record_id The record ID that is contained in the given descriptor.
+ *
+ * @retval FDS_SUCCESS If a record ID was returned.
+ * @retval FDS_ERR_NULL_ARG If @p p_desc or @p p_record_id is NULL.
+ */
+ret_code_t fds_record_id_from_desc(fds_record_desc_t const * p_desc,
+ uint32_t * p_record_id);
+
+
+/**@brief Function for retrieving file system statistics.
+ *
+ * This function retrieves file system statistics, such as the number of open records, the space
+ * that can be reclaimed by garbage collection, and others.
+ *
+ * @param[out] p_stat File system statistics.
+ *
+ * @retval FDS_SUCCESS If the statistics were returned successfully.
+ * @retval FDS_ERR_NOT_INITIALIZED If the module is not initialized.
+ * @retval FDS_ERR_NULL_ARG If @p p_stat is NULL.
+ */
+ret_code_t fds_stat(fds_stat_t * p_stat);
+
+
+/** @} */
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // FDS_H__
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/fds/fds_internal_defs.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/fds/fds_internal_defs.h
new file mode 100644
index 0000000..7502b43
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/fds/fds_internal_defs.h
@@ -0,0 +1,327 @@
+/**
+ * Copyright (c) 2015 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#ifndef FDS_INTERNAL_DEFS_H__
+#define FDS_INTERNAL_DEFS_H__
+#include "sdk_config.h"
+#include <stdint.h>
+#include <stdbool.h>
+
+#if defined (FDS_THREADS)
+ #include "nrf_soc.h"
+ #include "app_util_platform.h"
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define FDS_PAGE_TAG_SIZE (2) // Page tag size, in 4-byte words.
+#define FDS_PAGE_TAG_WORD_0 (0) // Offset of the first word in the page tag from the page address.
+#define FDS_PAGE_TAG_WORD_1 (1) // Offset of the second word in the page tag from the page address.
+
+// Page tag constants
+#define FDS_PAGE_TAG_MAGIC (0xDEADC0DE)
+#define FDS_PAGE_TAG_SWAP (0xF11E01FF)
+#define FDS_PAGE_TAG_DATA (0xF11E01FE)
+
+#define FDS_ERASED_WORD (0xFFFFFFFF)
+
+#define FDS_OFFSET_TL (0) // Offset of TL from the record base address, in 4-byte words.
+#define FDS_OFFSET_IC (1) // Offset of IC from the record base address, in 4-byte words.
+#define FDS_OFFSET_ID (2) // Offset of ID from the record base address, in 4-byte words.
+#define FDS_OFFSET_DATA (3) // Offset of the data from the record base address, in 4-byte words.
+
+#define FDS_HEADER_SIZE_TL (1) // Size of the TL part of the header, in 4-byte words.
+#define FDS_HEADER_SIZE_IC (1) // Size of the IC part of the header, in 4-byte words.
+#define FDS_HEADER_SIZE_ID (1) // Size of the record ID in the header, in 4-byte words.
+#define FDS_HEADER_SIZE (3) // Size of the whole header, in 4-byte words.
+
+#define FDS_OP_EXECUTING (NRF_SUCCESS)
+#define FDS_OP_COMPLETED (0x1D1D)
+
+#define NRF_FSTORAGE_NVMC 1
+#define NRF_FSTORAGE_SD 2
+
+// The size of a physical page, in 4-byte words.
+#if defined(NRF51)
+ #define FDS_PHY_PAGE_SIZE (256)
+#else
+ #define FDS_PHY_PAGE_SIZE (1024)
+#endif
+
+// The number of physical pages to be used. This value is configured indirectly.
+#define FDS_PHY_PAGES ((FDS_VIRTUAL_PAGES * FDS_VIRTUAL_PAGE_SIZE) / FDS_PHY_PAGE_SIZE)
+
+// The size of a virtual page, in number of physical pages.
+#define FDS_PHY_PAGES_IN_VPAGE (FDS_VIRTUAL_PAGE_SIZE / FDS_PHY_PAGE_SIZE)
+
+// The number of pages available to store data; which is the total minus one (the swap).
+#define FDS_DATA_PAGES (FDS_VIRTUAL_PAGES - 1)
+
+ // Just a shorter name for the size, in words, of a virtual page.
+#define FDS_PAGE_SIZE (FDS_VIRTUAL_PAGE_SIZE)
+
+
+#if (FDS_VIRTUAL_PAGE_SIZE % FDS_PHY_PAGE_SIZE != 0)
+ #error "FDS_VIRTUAL_PAGE_SIZE must be a multiple of the size of a physical page."
+#endif
+
+#if (FDS_VIRTUAL_PAGES < 2)
+ #error "FDS requires at least two virtual pages."
+#endif
+
+
+// Page types.
+typedef enum
+{
+ FDS_PAGE_DATA, // Page is ready for storage.
+ FDS_PAGE_SWAP, // Page is reserved for garbage collection.
+ FDS_PAGE_ERASED, // Page is erased.
+ FDS_PAGE_UNDEFINED, // Undefined page type.
+} fds_page_type_t;
+
+
+typedef enum
+{
+ FDS_HEADER_VALID, // Valid header.
+ FDS_HEADER_DIRTY, // Header is incomplete, or record has been deleted.
+ FDS_HEADER_CORRUPT // Header contains corrupt information, not related to CRC.
+} fds_header_status_t;
+
+
+typedef struct
+{
+ fds_page_type_t page_type; // The page type.
+ uint32_t const * p_addr; // The address of the page.
+ uint16_t write_offset; // The page write offset, in 4-byte words.
+ uint16_t words_reserved; // The amount of words reserved.
+ uint32_t volatile records_open; // The number of open records.
+ bool can_gc; // Indicates that there are some records that have been deleted.
+} fds_page_t;
+
+
+typedef struct
+{
+ uint32_t const * p_addr;
+ uint16_t write_offset;
+} fds_swap_page_t;
+
+
+// FDS op-codes.
+typedef enum
+{
+ FDS_OP_NONE,
+ FDS_OP_INIT, // Initialize the module.
+ FDS_OP_WRITE, // Write a record to flash.
+ FDS_OP_UPDATE, // Update a record.
+ FDS_OP_DEL_RECORD, // Delete a record.
+ FDS_OP_DEL_FILE, // Delete a file.
+ FDS_OP_GC // Run garbage collection.
+} fds_op_code_t;
+
+
+typedef enum
+{
+ FDS_OP_INIT_TAG_SWAP,
+ FDS_OP_INIT_TAG_DATA,
+ FDS_OP_INIT_ERASE_SWAP,
+ FDS_OP_INIT_PROMOTE_SWAP,
+} fds_init_step_t;
+
+
+typedef enum
+{
+ FDS_OP_WRITE_HEADER_BEGIN, // Write the record key and length.
+ FDS_OP_WRITE_HEADER_FINALIZE, // Write the file ID and CRC.
+ FDS_OP_WRITE_RECORD_ID, // Write the record ID.
+ FDS_OP_WRITE_DATA, // Write the record data.
+ FDS_OP_WRITE_FIND_RECORD,
+ FDS_OP_WRITE_FLAG_DIRTY, // Flag a record as dirty (as part of an update operation).
+ FDS_OP_WRITE_DONE,
+} fds_write_step_t;
+
+
+typedef enum
+{
+ FDS_OP_DEL_RECORD_FLAG_DIRTY, // Flag a record as dirty.
+ FDS_OP_DEL_FILE_FLAG_DIRTY, // Flag multiple records as dirty.
+ FDS_OP_DEL_DONE,
+} fds_delete_step_t;
+
+
+#if defined(__CC_ARM)
+ #pragma push
+ #pragma anon_unions
+#elif defined(__ICCARM__)
+ #pragma language=extended
+#elif defined(__GNUC__)
+ // anonymous unions are enabled by default
+#endif
+
+typedef struct
+{
+ fds_op_code_t op_code; // The opcode for the operation.
+ union
+ {
+ struct
+ {
+ fds_init_step_t step; // The current step the operation is at.
+ } init;
+ struct
+ {
+ fds_header_t header;
+ void const * p_data;
+ uint16_t page; // The page the flash space for this command was reserved.
+ fds_write_step_t step; // The current step the operation is at.
+ uint32_t record_to_delete; // The record to delete in case this is an update.
+ } write;
+ struct
+ {
+ fds_delete_step_t step;
+ uint16_t file_id;
+ uint16_t record_key;
+ uint32_t record_to_delete;
+ } del;
+ };
+} fds_op_t;
+
+#if defined(__CC_ARM)
+ #pragma pop
+#elif defined(__ICCARM__)
+ // leave anonymous unions enabled
+#elif defined(__GNUC__)
+ // anonymous unions are enabled by default
+#endif
+
+
+enum
+{
+ PAGE_ERASED = 0x1, // One or more erased pages found.
+ PAGE_DATA = 0x2, // One or more data pages found.
+ PAGE_SWAP_CLEAN = 0x4, // A clean (empty) swap page was found.
+ PAGE_SWAP_DIRTY = 0x8, // A dirty (non-empty) swap page was found.
+};
+
+
+typedef enum
+{
+ // No erased pages or FDS pages found.
+ // This is a fatal error.
+ NO_PAGES,
+
+ // The filesystem can not be garbage collected.
+ // This is a fatal error.
+ NO_SWAP = (PAGE_DATA),
+
+ // Perform a fresh installation.
+ FRESH_INSTALL = (PAGE_ERASED),
+
+ // Tag an erased page as swap.
+ TAG_SWAP = (PAGE_ERASED | PAGE_DATA),
+
+ // Tag all erased pages as data.
+ TAG_DATA = (PAGE_ERASED | PAGE_SWAP_CLEAN),
+
+ // Tag all remaining erased pages as data.
+ TAG_DATA_INST = (PAGE_ERASED | PAGE_DATA | PAGE_SWAP_CLEAN),
+
+ // The swap is dirty, likely because the device powered off during GC.
+ // Because there is also an erased page, assume that that page has been garbage collected.
+ // Hence, tag the swap as data (promote), an erased page as swap and remaining pages as data.
+ PROMOTE_SWAP = (PAGE_ERASED | PAGE_SWAP_DIRTY),
+
+ // Tag the swap as data (promote), an erased page as swap and remaining pages as data.
+ PROMOTE_SWAP_INST = (PAGE_ERASED | PAGE_DATA | PAGE_SWAP_DIRTY),
+
+ // The swap is dirty (written) and there are no erased pages. It is likely that the device
+ // powered off during GC. It is safe to discard (erase) the swap, since data that was
+ // swapped out still lies in one of the valid pages.
+ DISCARD_SWAP = (PAGE_DATA | PAGE_SWAP_DIRTY),
+
+ // Do nothing.
+ ALREADY_INSTALLED = (PAGE_DATA | PAGE_SWAP_CLEAN),
+
+} fds_init_opts_t;
+
+
+typedef enum
+{
+ GC_BEGIN, // Begin GC.
+ GC_NEXT_PAGE, // GC a page.
+ GC_FIND_NEXT_RECORD, // Find a valid record to copy.
+ GC_COPY_RECORD, // Copy a valid record to swap.
+ GC_ERASE_PAGE, // Erase the page being garbage collected.
+ GC_DISCARD_SWAP, // Erase (discard) the swap page.
+ GC_PROMOTE_SWAP, // Tag the swap as valid.
+ GC_TAG_NEW_SWAP // Tag a freshly erased (GCed) page as swap.
+} fds_gc_state_t;
+
+
+// Holds garbage collection status and related data.
+typedef struct
+{
+ fds_gc_state_t state; // The current GC step.
+ uint16_t cur_page; // The current page being garbage collected.
+ uint32_t const * p_record_src; // The current record being copied to swap.
+ uint16_t run_count; // Total number of times GC was run.
+ bool do_gc_page[FDS_DATA_PAGES]; // Controls which pages to garbage collect.
+ bool resume; // Whether or not GC should be resumed.
+} fds_gc_data_t;
+
+
+// Macros to enable and disable application interrupts.
+#if defined (FDS_THREADS)
+
+ #define CRITICAL_SECTION_ENTER() CRITICAL_REGION_ENTER()
+ #define CRITICAL_SECTION_EXIT() CRITICAL_REGION_EXIT()
+
+#else
+
+ #define CRITICAL_SECTION_ENTER()
+ #define CRITICAL_SECTION_EXIT()
+
+#endif
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // FDS_INTERNAL_DEFS_H__
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/fifo/app_fifo.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/fifo/app_fifo.c
new file mode 100644
index 0000000..b14a159
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/fifo/app_fifo.c
@@ -0,0 +1,214 @@
+/**
+ * Copyright (c) 2013 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#include "sdk_common.h"
+#if NRF_MODULE_ENABLED(APP_FIFO)
+#include "app_fifo.h"
+
+static __INLINE uint32_t fifo_length(app_fifo_t * p_fifo)
+{
+ uint32_t tmp = p_fifo->read_pos;
+ return p_fifo->write_pos - tmp;
+}
+
+
+#define FIFO_LENGTH() fifo_length(p_fifo) /**< Macro for calculating the FIFO length. */
+
+
+/**@brief Put one byte to the FIFO. */
+static __INLINE void fifo_put(app_fifo_t * p_fifo, uint8_t byte)
+{
+ p_fifo->p_buf[p_fifo->write_pos & p_fifo->buf_size_mask] = byte;
+ p_fifo->write_pos++;
+}
+
+
+/**@brief Look at one byte in the FIFO. */
+static __INLINE void fifo_peek(app_fifo_t * p_fifo, uint16_t index, uint8_t * p_byte)
+{
+ *p_byte = p_fifo->p_buf[(p_fifo->read_pos + index) & p_fifo->buf_size_mask];
+}
+
+
+/**@brief Get one byte from the FIFO. */
+static __INLINE void fifo_get(app_fifo_t * p_fifo, uint8_t * p_byte)
+{
+ fifo_peek(p_fifo, 0, p_byte);
+ p_fifo->read_pos++;
+}
+
+
+uint32_t app_fifo_init(app_fifo_t * p_fifo, uint8_t * p_buf, uint16_t buf_size)
+{
+ // Check buffer for null pointer.
+ if (p_buf == NULL)
+ {
+ return NRF_ERROR_NULL;
+ }
+
+ // Check that the buffer size is a power of two.
+ if (!IS_POWER_OF_TWO(buf_size))
+ {
+ return NRF_ERROR_INVALID_LENGTH;
+ }
+
+ p_fifo->p_buf = p_buf;
+ p_fifo->buf_size_mask = buf_size - 1;
+ p_fifo->read_pos = 0;
+ p_fifo->write_pos = 0;
+
+ return NRF_SUCCESS;
+}
+
+
+uint32_t app_fifo_put(app_fifo_t * p_fifo, uint8_t byte)
+{
+ if (FIFO_LENGTH() <= p_fifo->buf_size_mask)
+ {
+ fifo_put(p_fifo, byte);
+ return NRF_SUCCESS;
+ }
+
+ return NRF_ERROR_NO_MEM;
+}
+
+
+uint32_t app_fifo_get(app_fifo_t * p_fifo, uint8_t * p_byte)
+{
+ if (FIFO_LENGTH() != 0)
+ {
+ fifo_get(p_fifo, p_byte);
+ return NRF_SUCCESS;
+ }
+
+ return NRF_ERROR_NOT_FOUND;
+
+}
+
+
+uint32_t app_fifo_peek(app_fifo_t * p_fifo, uint16_t index, uint8_t * p_byte)
+{
+ if (FIFO_LENGTH() > index)
+ {
+ fifo_peek(p_fifo, index, p_byte);
+ return NRF_SUCCESS;
+ }
+
+ return NRF_ERROR_NOT_FOUND;
+}
+
+
+uint32_t app_fifo_flush(app_fifo_t * p_fifo)
+{
+ p_fifo->read_pos = p_fifo->write_pos;
+ return NRF_SUCCESS;
+}
+
+
+uint32_t app_fifo_read(app_fifo_t * p_fifo, uint8_t * p_byte_array, uint32_t * p_size)
+{
+ VERIFY_PARAM_NOT_NULL(p_fifo);
+ VERIFY_PARAM_NOT_NULL(p_size);
+
+ const uint32_t byte_count = fifo_length(p_fifo);
+ const uint32_t requested_len = (*p_size);
+ uint32_t index = 0;
+ uint32_t read_size = MIN(requested_len, byte_count);
+
+ (*p_size) = byte_count;
+
+ // Check if the FIFO is empty.
+ if (byte_count == 0)
+ {
+ return NRF_ERROR_NOT_FOUND;
+ }
+
+ // Check if application has requested only the size.
+ if (p_byte_array == NULL)
+ {
+ return NRF_SUCCESS;
+ }
+
+ // Fetch bytes from the FIFO.
+ while (index < read_size)
+ {
+ fifo_get(p_fifo, &p_byte_array[index++]);
+ }
+
+ (*p_size) = read_size;
+
+ return NRF_SUCCESS;
+}
+
+
+uint32_t app_fifo_write(app_fifo_t * p_fifo, uint8_t const * p_byte_array, uint32_t * p_size)
+{
+ VERIFY_PARAM_NOT_NULL(p_fifo);
+ VERIFY_PARAM_NOT_NULL(p_size);
+
+ const uint32_t available_count = p_fifo->buf_size_mask - fifo_length(p_fifo) + 1;
+ const uint32_t requested_len = (*p_size);
+ uint32_t index = 0;
+ uint32_t write_size = MIN(requested_len, available_count);
+
+ (*p_size) = available_count;
+
+ // Check if the FIFO is FULL.
+ if (available_count == 0)
+ {
+ return NRF_ERROR_NO_MEM;
+ }
+
+ // Check if application has requested only the size.
+ if (p_byte_array == NULL)
+ {
+ return NRF_SUCCESS;
+ }
+
+ //Fetch bytes from the FIFO.
+ while (index < write_size)
+ {
+ fifo_put(p_fifo, p_byte_array[index++]);
+ }
+
+ (*p_size) = write_size;
+
+ return NRF_SUCCESS;
+}
+#endif //NRF_MODULE_ENABLED(APP_FIFO)
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/fifo/app_fifo.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/fifo/app_fifo.h
new file mode 100644
index 0000000..8123227
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/fifo/app_fifo.h
@@ -0,0 +1,181 @@
+/**
+ * Copyright (c) 2013 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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
+ *
+ * @defgroup app_fifo FIFO implementation
+ * @{
+ * @ingroup app_common
+ *
+ * @brief FIFO implementation.
+ */
+
+#ifndef APP_FIFO_H__
+#define APP_FIFO_H__
+
+#include <stdint.h>
+#include <stdlib.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**@brief A FIFO instance structure.
+ * @details Keeps track of which bytes to read and write next.
+ * Also, it keeps the information about which memory is allocated for the buffer
+ * and its size. This structure must be initialized by app_fifo_init() before use.
+ */
+typedef struct
+{
+ uint8_t * p_buf; /**< Pointer to FIFO buffer memory. */
+ uint16_t buf_size_mask; /**< Read/write index mask. Also used for size checking. */
+ volatile uint32_t read_pos; /**< Next read position in the FIFO buffer. */
+ volatile uint32_t write_pos; /**< Next write position in the FIFO buffer. */
+} app_fifo_t;
+
+/**@brief Function for initializing the FIFO.
+ *
+ * @param[out] p_fifo FIFO object.
+ * @param[in] p_buf FIFO buffer for storing data. The buffer size must be a power of two.
+ * @param[in] buf_size Size of the FIFO buffer provided. This size must be a power of two.
+ *
+ * @retval NRF_SUCCESS If initialization was successful.
+ * @retval NRF_ERROR_NULL If a NULL pointer is provided as buffer.
+ * @retval NRF_ERROR_INVALID_LENGTH If size of buffer provided is not a power of two.
+ */
+uint32_t app_fifo_init(app_fifo_t * p_fifo, uint8_t * p_buf, uint16_t buf_size);
+
+/**@brief Function for adding an element to the FIFO.
+ *
+ * @param[in] p_fifo Pointer to the FIFO.
+ * @param[in] byte Data byte to add to the FIFO.
+ *
+ * @retval NRF_SUCCESS If an element has been successfully added to the FIFO.
+ * @retval NRF_ERROR_NO_MEM If the FIFO is full.
+ */
+uint32_t app_fifo_put(app_fifo_t * p_fifo, uint8_t byte);
+
+/**@brief Function for getting the next element from the FIFO.
+ *
+ * @param[in] p_fifo Pointer to the FIFO.
+ * @param[out] p_byte Byte fetched from the FIFO.
+ *
+ * @retval NRF_SUCCESS If an element was returned.
+ * @retval NRF_ERROR_NOT_FOUND If there are no more elements in the queue.
+ */
+uint32_t app_fifo_get(app_fifo_t * p_fifo, uint8_t * p_byte);
+
+/**@brief Function for looking at an element in the FIFO, without consuming it.
+ *
+ * @param[in] p_fifo Pointer to the FIFO.
+ * @param[in] index Which element to look at. The lower the index, the earlier it was put.
+ * @param[out] p_byte Byte fetched from the FIFO.
+ *
+ * @retval NRF_SUCCESS If an element was returned.
+ * @retval NRF_ERROR_NOT_FOUND If there are no more elements in the queue, or the index was
+ * too large.
+ */
+uint32_t app_fifo_peek(app_fifo_t * p_fifo, uint16_t index, uint8_t * p_byte);
+
+/**@brief Function for flushing the FIFO.
+ *
+ * @param[in] p_fifo Pointer to the FIFO.
+ *
+ * @retval NRF_SUCCESS If the FIFO was flushed successfully.
+ */
+uint32_t app_fifo_flush(app_fifo_t * p_fifo);
+
+/**@brief Function for reading bytes from the FIFO.
+ *
+ * This function can also be used to get the number of bytes in the FIFO.
+ *
+ * @param[in] p_fifo Pointer to the FIFO. Must not be NULL.
+ * @param[out] p_byte_array Memory pointer where the read bytes are fetched from the FIFO.
+ * Can be NULL. If NULL, the number of bytes that can be read in the FIFO
+ * are returned in the p_size parameter.
+ * @param[inout] p_size Address to memory indicating the maximum number of bytes to be read.
+ * The provided memory is overwritten with the actual number of bytes
+ * read if the procedure was successful. This field must not be NULL.
+ * If p_byte_array is set to NULL by the application, this parameter
+ * returns the number of bytes in the FIFO.
+ *
+ * @retval NRF_SUCCESS If the procedure is successful. The actual number of bytes read might
+ * be less than the requested maximum, depending on how many elements exist
+ * in the FIFO. Even if less bytes are returned, the procedure is considered
+ * successful.
+ * @retval NRF_ERROR_NULL If a NULL parameter was passed for a parameter that must not
+ * be NULL.
+ * @retval NRF_ERROR_NOT_FOUND If the FIFO is empty.
+ */
+uint32_t app_fifo_read(app_fifo_t * p_fifo, uint8_t * p_byte_array, uint32_t * p_size);
+
+/**@brief Function for writing bytes to the FIFO.
+ *
+ * This function can also be used to get the available size on the FIFO.
+ *
+ * @param[in] p_fifo Pointer to the FIFO. Must not be NULL.
+ * @param[in] p_byte_array Memory pointer containing the bytes to be written to the FIFO.
+ * Can be NULL. If NULL, this function returns the number of bytes
+ * that can be written to the FIFO.
+ * @param[inout] p_size Address to memory indicating the maximum number of bytes to be written.
+ * The provided memory is overwritten with the number of bytes that were actually
+ * written if the procedure is successful. This field must not be NULL.
+ * If p_byte_array is set to NULL by the application, this parameter
+ * returns the number of bytes available in the FIFO.
+ *
+ * @retval NRF_SUCCESS If the procedure is successful. The actual number of bytes written might
+ * be less than the requested maximum, depending on how much room there is in
+ * the FIFO. Even if less bytes are written, the procedure is considered
+ * successful. If the write was partial, the application should use
+ * subsequent calls to attempt writing the data again.
+ * @retval NRF_ERROR_NULL If a NULL parameter was passed for a parameter that must not
+ * be NULL.
+ * @retval NRF_ERROR_NO_MEM If the FIFO is full.
+ *
+ */
+uint32_t app_fifo_write(app_fifo_t * p_fifo, uint8_t const * p_byte_array, uint32_t * p_size);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // APP_FIFO_H__
+
+/** @} */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/fstorage/nrf_fstorage.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/fstorage/nrf_fstorage.c
new file mode 100644
index 0000000..d96abce
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/fstorage/nrf_fstorage.c
@@ -0,0 +1,244 @@
+/**
+ * Copyright (c) 2016 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#include "sdk_config.h"
+
+#if NRF_FSTORAGE_ENABLED
+
+#include "nrf_fstorage.h"
+#include <stddef.h>
+#include <stdint.h>
+#include "sdk_errors.h"
+#include "sdk_macros.h"
+#include "nrf_section.h"
+
+#define NRF_LOG_MODULE_NAME nrf_fstorage
+#include "nrf_log.h"
+NRF_LOG_MODULE_REGISTER();
+
+
+/* Create the section "fs_data". */
+NRF_SECTION_DEF(fs_data, nrf_fstorage_t);
+
+
+/**@brief Macro to handle user input validation.
+ *
+ * If @p _cond evaluates to true, does nothing. Otherwise,
+ * if the NRF_FSTORAGE_PARAM_CHECK_DISABLED is not set, logs an error message and returns @p _err.
+ * If the NRF_FSTORAGE_PARAM_CHECK_DISABLED is set, behaves like the @ref ASSERT macro.
+ *
+ * Parameter checking implemented using this macro can be optionally turned off for release code.
+ * Only disable runtime parameter checks if size if a major concern.
+ *
+ * @param _cond The condition to be evaluated.
+ * @param _err The error code to be returned.
+ */
+#define NRF_FSTORAGE_PARAM_CHECK(_cond, _err) \
+ NRF_PARAM_CHECK(NRF_FSTORAGE, _cond, _err, NRF_LOG_ERROR)
+
+
+static bool addr_is_aligned32(uint32_t addr);
+static bool addr_is_page_aligned(nrf_fstorage_t const * p_fs, uint32_t addr);
+static bool addr_is_within_bounds(nrf_fstorage_t const * p_fs, uint32_t addr, uint32_t len);
+
+
+ret_code_t nrf_fstorage_init(nrf_fstorage_t * p_fs,
+ nrf_fstorage_api_t * p_api,
+ void * p_param)
+{
+ NRF_FSTORAGE_PARAM_CHECK(p_fs, NRF_ERROR_NULL);
+ NRF_FSTORAGE_PARAM_CHECK(p_api, NRF_ERROR_NULL);
+
+ p_fs->p_api = p_api;
+
+ return (p_fs->p_api)->init(p_fs, p_param);
+}
+
+
+ret_code_t nrf_fstorage_uninit(nrf_fstorage_t * p_fs,
+ void * p_param)
+{
+ ret_code_t rc;
+
+ NRF_FSTORAGE_PARAM_CHECK(p_fs, NRF_ERROR_NULL);
+ NRF_FSTORAGE_PARAM_CHECK(p_fs->p_api, NRF_ERROR_INVALID_STATE);
+
+ rc = (p_fs->p_api)->uninit(p_fs, p_param);
+
+ /* Uninitialize the API. */
+ p_fs->p_api = NULL;
+ p_fs->p_flash_info = NULL;
+
+ return rc;
+}
+
+
+ret_code_t nrf_fstorage_read(nrf_fstorage_t const * p_fs,
+ uint32_t src,
+ void * p_dest,
+ uint32_t len)
+{
+ NRF_FSTORAGE_PARAM_CHECK(p_fs, NRF_ERROR_NULL);
+ NRF_FSTORAGE_PARAM_CHECK(p_dest, NRF_ERROR_NULL);
+ NRF_FSTORAGE_PARAM_CHECK(p_fs->p_api, NRF_ERROR_INVALID_STATE);
+ NRF_FSTORAGE_PARAM_CHECK(len, NRF_ERROR_INVALID_LENGTH);
+
+ /* Source addres must be word-aligned. */
+ NRF_FSTORAGE_PARAM_CHECK(addr_is_aligned32(src), NRF_ERROR_INVALID_ADDR);
+ NRF_FSTORAGE_PARAM_CHECK(addr_is_within_bounds(p_fs, src, len), NRF_ERROR_INVALID_ADDR);
+
+ return (p_fs->p_api)->read(p_fs, src, p_dest, len);
+}
+
+
+ret_code_t nrf_fstorage_write(nrf_fstorage_t const * p_fs,
+ uint32_t dest,
+ void const * p_src,
+ uint32_t len,
+ void * p_context)
+{
+ NRF_FSTORAGE_PARAM_CHECK(p_fs, NRF_ERROR_NULL);
+ NRF_FSTORAGE_PARAM_CHECK(p_src, NRF_ERROR_NULL);
+ NRF_FSTORAGE_PARAM_CHECK(p_fs->p_api, NRF_ERROR_INVALID_STATE);
+ NRF_FSTORAGE_PARAM_CHECK(len, NRF_ERROR_INVALID_LENGTH);
+
+ /* Length must be a multiple of the program unit. */
+ NRF_FSTORAGE_PARAM_CHECK(!(len % p_fs->p_flash_info->program_unit), NRF_ERROR_INVALID_LENGTH);
+
+ /* Source and destination addresses must be word-aligned. */
+ NRF_FSTORAGE_PARAM_CHECK(addr_is_aligned32(dest), NRF_ERROR_INVALID_ADDR);
+ NRF_FSTORAGE_PARAM_CHECK(addr_is_aligned32((uint32_t)p_src), NRF_ERROR_INVALID_ADDR);
+ NRF_FSTORAGE_PARAM_CHECK(addr_is_within_bounds(p_fs, dest, len), NRF_ERROR_INVALID_ADDR);
+
+ return (p_fs->p_api)->write(p_fs, dest, p_src, len, p_context);
+}
+
+
+ret_code_t nrf_fstorage_erase(nrf_fstorage_t const * p_fs,
+ uint32_t page_addr,
+ uint32_t len,
+ void * p_context)
+{
+ NRF_FSTORAGE_PARAM_CHECK(p_fs, NRF_ERROR_NULL);
+ NRF_FSTORAGE_PARAM_CHECK(p_fs->p_api, NRF_ERROR_INVALID_STATE);
+ NRF_FSTORAGE_PARAM_CHECK(len, NRF_ERROR_INVALID_LENGTH);
+
+ /* Address must be aligned to a page boundary. */
+ NRF_FSTORAGE_PARAM_CHECK(addr_is_page_aligned(p_fs, page_addr), NRF_ERROR_INVALID_ADDR);
+
+ NRF_FSTORAGE_PARAM_CHECK(
+ addr_is_within_bounds(p_fs, page_addr, (len * p_fs->p_flash_info->erase_unit)),
+ NRF_ERROR_INVALID_ADDR
+ );
+
+ return (p_fs->p_api)->erase(p_fs, page_addr, len, p_context);
+}
+
+
+uint8_t const * nrf_fstorage_rmap(nrf_fstorage_t const * p_fs, uint32_t addr)
+{
+ if ((p_fs == NULL) || (p_fs->p_api == NULL))
+ {
+ return NULL;
+ }
+
+ return (p_fs->p_api)->rmap(p_fs, addr);
+}
+
+
+uint8_t * nrf_fstorage_wmap(nrf_fstorage_t const * p_fs, uint32_t addr)
+{
+ if ((p_fs == NULL) || (p_fs->p_api == NULL))
+ {
+ return NULL;
+ }
+
+ return (p_fs->p_api)->wmap(p_fs, addr);
+}
+
+
+bool nrf_fstorage_is_busy(nrf_fstorage_t const * p_fs)
+{
+ /* If a NULL instance is provided, return true if any instance is busy.
+ * Uninitialized instances are considered not busy. */
+ if ((p_fs == NULL) || (p_fs->p_api == NULL))
+ {
+ for (uint32_t i = 0; i < NRF_FSTORAGE_INSTANCE_CNT; i++)
+ {
+ p_fs = NRF_FSTORAGE_INSTANCE_GET(i); /* cannot be NULL. */
+ if (p_fs->p_api != NULL)
+ {
+ /* p_api->is_busy() cannot be NULL. */
+ if (p_fs->p_api->is_busy(p_fs))
+ {
+ return true;
+ }
+ }
+ }
+
+ return false;
+ }
+
+ return p_fs->p_api->is_busy(p_fs);
+}
+
+
+static bool addr_is_within_bounds(nrf_fstorage_t const * p_fs,
+ uint32_t addr,
+ uint32_t len)
+{
+ return ( (addr >= p_fs->start_addr)
+ && (addr + len - 1 <= p_fs->end_addr));
+}
+
+
+static bool addr_is_aligned32(uint32_t addr)
+{
+ return !(addr & 0x03);
+}
+
+
+static bool addr_is_page_aligned(nrf_fstorage_t const * p_fs,
+ uint32_t addr)
+{
+ return (addr & (p_fs->p_flash_info->erase_unit - 1)) == 0;
+}
+
+
+#endif // NRF_FSTORAGE_ENABLED
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/fstorage/nrf_fstorage.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/fstorage/nrf_fstorage.h
new file mode 100644
index 0000000..b678950
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/fstorage/nrf_fstorage.h
@@ -0,0 +1,341 @@
+/**
+ * Copyright (c) 2016 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#ifndef NRF_FSTORAGE_H__
+#define NRF_FSTORAGE_H__
+
+/**
+ * @file
+ *
+ * @defgroup nrf_fstorage Flash storage (fstorage)
+ * @ingroup app_common
+ * @{
+ *
+ * @brief Flash abstraction library that provides basic read, write, and erase operations.
+ *
+ * @details The fstorage library can be implemented in different ways. Two implementations are provided:
+ * - The @ref nrf_fstorage_sd implements flash access through the SoftDevice.
+ * - The @ref nrf_fstorage_nvmc implements flash access through the non-volatile memory controller.
+ *
+ * You can select the implementation that should be used independently for each instance of fstorage.
+ */
+
+#include <stdint.h>
+#include <stdbool.h>
+#include "sdk_errors.h"
+#include "nrf_section.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+/**@brief Macro for defining an fstorage instance.
+ *
+ * Users of fstorage must define an instance variable by using this macro.
+ * Each instance is tied to an API implementation and contains information such
+ * as the program and erase units for the target flash peripheral.
+ * Instance variables are placed in the "fs_data" section of the binary.
+ *
+ * @param[in] inst A definition of an @ref nrf_fstorage_t variable.
+ */
+#define NRF_FSTORAGE_DEF(inst) NRF_SECTION_ITEM_REGISTER(fs_data, inst)
+
+/**@brief Macro for retrieving an fstorage instance. */
+#define NRF_FSTORAGE_INSTANCE_GET(i) NRF_SECTION_ITEM_GET(fs_data, nrf_fstorage_t, (i))
+
+/**@brief Macro for retrieving the total number of fstorage instances. */
+#define NRF_FSTORAGE_INSTANCE_CNT NRF_SECTION_ITEM_COUNT(fs_data, nrf_fstorage_t)
+
+
+/**@brief Event IDs. */
+typedef enum
+{
+ NRF_FSTORAGE_EVT_READ_RESULT,
+ NRF_FSTORAGE_EVT_WRITE_RESULT, //!< Event for @ref nrf_fstorage_write.
+ NRF_FSTORAGE_EVT_ERASE_RESULT //!< Event for @ref nrf_fstorage_erase.
+} nrf_fstorage_evt_id_t;
+
+
+/**@brief An fstorage event. */
+typedef struct
+{
+ nrf_fstorage_evt_id_t id; //!< The event ID.
+ ret_code_t result; //!< Result of the operation.
+ uint32_t addr; //!< Address at which the operation was performed.
+ void const * p_src; //!< Buffer written to flash.
+ uint32_t len; //!< Length of the operation.
+ void * p_param; //!< User-defined parameter passed to the event handler.
+} nrf_fstorage_evt_t;
+
+
+/**@brief Event handler function prototype.
+ *
+ * @param[in] p_evt The event.
+ */
+typedef void (*nrf_fstorage_evt_handler_t)(nrf_fstorage_evt_t * p_evt);
+
+
+/**@brief Information about the implementation and the flash peripheral. */
+typedef struct
+{
+ uint32_t erase_unit; //!< Size of a flash page (in bytes). A flash page is the smallest unit that can be erased.
+ uint32_t program_unit; //!< Size of the smallest programmable unit (in bytes).
+ bool rmap; //!< The device address space is memory mapped to the MCU address space.
+ bool wmap; //!< The device address space is memory mapped to a writable MCU address space.
+} const nrf_fstorage_info_t;
+
+
+/* Necessary forward declaration. */
+struct nrf_fstorage_api_s;
+
+
+/**@brief An fstorage instance.
+ *
+ * @details Use the @ref NRF_FSTORAGE_DEF macro to define an fstorage instance.
+ *
+ * An instance is tied to an API implementation and contains information about the flash device,
+ * such as the program and erase units as well and implementation-specific functionality.
+ */
+typedef struct
+{
+ /**@brief The API implementation used by this instance. */
+ struct nrf_fstorage_api_s const * p_api;
+
+ /**@brief Information about the implementation functionality and the flash peripheral. */
+ nrf_fstorage_info_t * p_flash_info;
+
+ /**@brief The event handler function.
+ *
+ * If set to NULL, no events will be sent.
+ */
+ nrf_fstorage_evt_handler_t evt_handler;
+
+ /**@brief The beginning of the flash space on which this fstorage instance should operate.
+ * All flash operations must be within the address specified in
+ * this field and @ref end_addr.
+ *
+ * This field must be set manually.
+ */
+ uint32_t start_addr;
+
+ /**@brief The last address (exclusive) of flash on which this fstorage instance should operate.
+ * All flash operations must be within the address specified in
+ * this field and @ref start_addr.
+ *
+ * This field must be set manually.
+ */
+ uint32_t end_addr;
+} nrf_fstorage_t;
+
+
+/**@brief Functions provided by the API implementation. */
+typedef struct nrf_fstorage_api_s
+{
+ /**@brief Initialize the flash peripheral. */
+ ret_code_t (*init)(nrf_fstorage_t * p_fs, void * p_param);
+ /**@brief Uninitialize the flash peripheral. */
+ ret_code_t (*uninit)(nrf_fstorage_t * p_fs, void * p_param);
+ /**@brief Read data from flash. */
+ ret_code_t (*read)(nrf_fstorage_t const * p_fs, uint32_t src, void * p_dest, uint32_t len);
+ /**@brief Write bytes to flash. */
+ ret_code_t (*write)(nrf_fstorage_t const * p_fs, uint32_t dest, void const * p_src, uint32_t len, void * p_param);
+ /**@brief Erase flash pages. */
+ ret_code_t (*erase)(nrf_fstorage_t const * p_fs, uint32_t addr, uint32_t len, void * p_param);
+ /**@brief Map a device address to a readable address within the MCU address space. */
+ uint8_t const * (*rmap)(nrf_fstorage_t const * p_fs, uint32_t addr);
+ /**@brief Map a device address to a writable address within the MCU address space. */
+ uint8_t * (*wmap)(nrf_fstorage_t const * p_fs, uint32_t addr);
+ /**@brief Check if there are any pending flash operations. */
+ bool (*is_busy)(nrf_fstorage_t const * p_fs);
+} const nrf_fstorage_api_t;
+
+
+/**@brief Function for initializing fstorage.
+ *
+ * @param[in] p_fs The fstorage instance to initialize.
+ * @param[in] p_api The API implementation to use.
+ * @param[in] p_param An optional parameter to pass to the implementation-specific API call.
+ *
+ * @retval NRF_SUCCESS If initialization was successful.
+ * @retval NRF_ERROR_NULL If @p p_fs or @p p_api field in @p p_fs is NULL.
+ * @retval NRF_ERROR_INTERNAL If another error occurred.
+ */
+ret_code_t nrf_fstorage_init(nrf_fstorage_t * p_fs,
+ nrf_fstorage_api_t * p_api,
+ void * p_param);
+
+
+/**@brief Function for uninitializing an fstorage instance.
+ *
+ * @param[in] p_fs The fstorage instance to uninitialize.
+ * @param[in] p_param An optional parameter to pass to the implementation-specific API call.
+ *
+ * @retval NRF_SUCCESS If uninitialization was successful.
+ * @retval NRF_ERROR_NULL If @p p_fs is NULL.
+ * @retval NRF_ERROR_INVALID_STATE If the module is not initialized.
+ * @retval NRF_ERROR_INTERNAL If another error occurred.
+ */
+ret_code_t nrf_fstorage_uninit(nrf_fstorage_t * p_fs, void * p_param);
+
+
+/**@brief Function for reading data from flash.
+ *
+ * Copy @p len bytes from @p addr to @p p_dest.
+ *
+ * @param[in] p_fs The fstorage instance.
+ * @param[in] addr Address in flash where to read from.
+ * @param[in] p_dest Buffer where the data should be copied.
+ * @param[in] len Length of the data to be copied (in bytes).
+ *
+ * @retval NRF_SUCCESS If the operation was successful.
+ * @retval NRF_ERROR_NULL If @p p_fs or @p p_dest is NULL.
+ * @retval NRF_ERROR_INVALID_STATE If the module is not initialized.
+ * @retval NRF_ERROR_INVALID_LENGTH If @p len is zero or otherwise invalid.
+ * @retval NRF_ERROR_INVALID_ADDR If the address @p addr is outside the flash memory
+ * boundaries specified in @p p_fs, or if it is unaligned.
+ */
+ret_code_t nrf_fstorage_read(nrf_fstorage_t const * p_fs,
+ uint32_t addr,
+ void * p_dest,
+ uint32_t len);
+
+
+/**@brief Function for writing data to flash.
+ *
+ * Write @p len bytes from @p p_src to @p dest.
+ *
+ * When using @ref nrf_fstorage_sd, the data is written by several calls to @ref sd_flash_write if
+ * the length of the data exceeds @ref NRF_FSTORAGE_SD_MAX_WRITE_SIZE bytes.
+ * Only one event is sent upon completion.
+ *
+ * @note The data to be written to flash must be kept in memory until the operation has
+ * terminated and an event is received.
+ *
+ * @param[in] p_fs The fstorage instance.
+ * @param[in] dest Address in flash memory where to write the data.
+ * @param[in] p_src Data to be written.
+ * @param[in] len Length of the data (in bytes).
+ * @param[in] p_param User-defined parameter passed to the event handler (may be NULL).
+ *
+ * @retval NRF_SUCCESS If the operation was accepted.
+ * @retval NRF_ERROR_NULL If @p p_fs or @p p_src is NULL.
+ * @retval NRF_ERROR_INVALID_STATE If the module is not initialized.
+ * @retval NRF_ERROR_INVALID_LENGTH If @p len is zero or not a multiple of the program unit,
+ * or if it is otherwise invalid.
+ * @retval NRF_ERROR_INVALID_ADDR If the address @p dest is outside the flash memory
+ * boundaries specified in @p p_fs, or if it is unaligned.
+ * @retval NRF_ERROR_NO_MEM If no memory is available to accept the operation.
+ * When using the @ref nrf_fstorage_sd, this error
+ * indicates that the internal queue of operations is full.
+ */
+ret_code_t nrf_fstorage_write(nrf_fstorage_t const * p_fs,
+ uint32_t dest,
+ void const * p_src,
+ uint32_t len,
+ void * p_param);
+
+
+/**@brief Function for erasing flash pages.
+ *
+ * @details This function erases @p len pages starting from the page at address @p page_addr.
+ * The erase operation must be initiated on a page boundary.
+ *
+ * @param[in] p_fs The fstorage instance.
+ * @param[in] page_addr Address of the page to erase.
+ * @param[in] len Number of pages to erase.
+ * @param[in] p_param User-defined parameter passed to the event handler (may be NULL).
+ *
+ * @retval NRF_SUCCESS If the operation was accepted.
+ * @retval NRF_ERROR_NULL If @p p_fs is NULL.
+ * @retval NRF_ERROR_INVALID_STATE If the module is not initialized.
+ * @retval NRF_ERROR_INVALID_LENGTH If @p len is zero.
+ * @retval NRF_ERROR_INVALID_ADDR If the address @p page_addr is outside the flash memory
+ * boundaries specified in @p p_fs, or if it is unaligned.
+ * @retval NRF_ERROR_NO_MEM If no memory is available to accept the operation.
+ * When using the @ref nrf_fstorage_sd, this error
+ * indicates that the internal queue of operations is full.
+ */
+ret_code_t nrf_fstorage_erase(nrf_fstorage_t const * p_fs,
+ uint32_t page_addr,
+ uint32_t len,
+ void * p_param);
+
+
+/**@brief Map a flash address to a pointer in the MCU address space that can be dereferenced.
+ *
+ * @param p_fs The fstorage instance.
+ * @param addr The address to map.
+ *
+ * @retval A pointer to the specified address,
+ * or @c NULL if the address cannot be mapped or if @p p_fs is @c NULL.
+ */
+uint8_t const * nrf_fstorage_rmap(nrf_fstorage_t const * p_fs, uint32_t addr);
+
+
+/**@brief Map a flash address to a pointer in the MCU address space that can be written to.
+ *
+ * @param p_fs The fstorage instance.
+ * @param addr The address to map.
+ *
+ * @retval A pointer to the specified address,
+ * or @c NULL if the address cannot be mapped or if @p p_fs is @c NULL.
+ */
+uint8_t * nrf_fstorage_wmap(nrf_fstorage_t const * p_fs, uint32_t addr);
+
+
+/**@brief Function for querying the status of fstorage.
+ *
+ * @details An uninitialized instance of fstorage is treated as not busy.
+ *
+ * @param[in] p_fs The fstorage instance. Pass NULL to query all instances.
+ *
+ * @returns If @p p_fs is @c NULL, this function returns true if any fstorage instance is busy or false otherwise.
+ * @returns If @p p_fs is not @c NULL, this function returns true if the fstorage instance is busy or false otherwise.
+ */
+ bool nrf_fstorage_is_busy(nrf_fstorage_t const * p_fs);
+
+/** @} */
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // NRF_FSTORAGE_H__
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/fstorage/nrf_fstorage_nvmc.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/fstorage/nrf_fstorage_nvmc.c
new file mode 100644
index 0000000..14b1859
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/fstorage/nrf_fstorage_nvmc.c
@@ -0,0 +1,217 @@
+/**
+ * Copyright (c) 2016 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#include "sdk_common.h"
+
+#if NRF_MODULE_ENABLED(NRF_FSTORAGE)
+
+#include "nrf_fstorage_nvmc.h"
+#include <stdint.h>
+#include <string.h>
+#include <stdbool.h>
+#include "nrf_nvmc.h"
+#include "nrf_atomic.h"
+
+
+static nrf_fstorage_info_t m_flash_info =
+{
+#if defined(NRF51)
+ .erase_unit = 1024,
+#elif defined(NRF52_SERIES)
+ .erase_unit = 4096,
+#endif
+ .program_unit = 4,
+ .rmap = true,
+ .wmap = false,
+};
+
+
+ /* An operation initiated by fstorage is ongoing. */
+static nrf_atomic_flag_t m_flash_operation_ongoing;
+
+
+/* Send event to the event handler. */
+static void event_send(nrf_fstorage_t const * p_fs,
+ nrf_fstorage_evt_id_t evt_id,
+ void const * p_src,
+ uint32_t addr,
+ uint32_t len,
+ void * p_param)
+{
+ if (p_fs->evt_handler == NULL)
+ {
+ /* Nothing to do. */
+ return;
+ }
+
+ nrf_fstorage_evt_t evt =
+ {
+ .result = NRF_SUCCESS,
+ .id = evt_id,
+ .addr = addr,
+ .p_src = p_src,
+ .len = len,
+ .p_param = p_param,
+ };
+
+ p_fs->evt_handler(&evt);
+}
+
+
+static ret_code_t init(nrf_fstorage_t * p_fs, void * p_param)
+{
+ UNUSED_PARAMETER(p_param);
+
+ p_fs->p_flash_info = &m_flash_info;
+
+ return NRF_SUCCESS;
+}
+
+
+static ret_code_t uninit(nrf_fstorage_t * p_fs, void * p_param)
+{
+ UNUSED_PARAMETER(p_fs);
+ UNUSED_PARAMETER(p_param);
+
+ (void) nrf_atomic_flag_clear(&m_flash_operation_ongoing);
+
+ return NRF_SUCCESS;
+}
+
+
+static ret_code_t read(nrf_fstorage_t const * p_fs, uint32_t src, void * p_dest, uint32_t len)
+{
+ UNUSED_PARAMETER(p_fs);
+
+ memcpy(p_dest, (uint32_t*)src, len);
+
+ return NRF_SUCCESS;
+}
+
+
+static ret_code_t write(nrf_fstorage_t const * p_fs,
+ uint32_t dest,
+ void const * p_src,
+ uint32_t len,
+ void * p_param)
+{
+ if (nrf_atomic_flag_set_fetch(&m_flash_operation_ongoing))
+ {
+ return NRF_ERROR_BUSY;
+ }
+
+ nrf_nvmc_write_words(dest, (uint32_t*)p_src, (len / m_flash_info.program_unit));
+
+ /* Clear the flag before sending the event, to allow API calls in the event context. */
+ (void) nrf_atomic_flag_clear(&m_flash_operation_ongoing);
+
+ event_send(p_fs, NRF_FSTORAGE_EVT_WRITE_RESULT, p_src, dest, len, p_param);
+
+ return NRF_SUCCESS;
+}
+
+
+static ret_code_t erase(nrf_fstorage_t const * p_fs,
+ uint32_t page_addr,
+ uint32_t len,
+ void * p_param)
+{
+ uint32_t progress = 0;
+
+ if (nrf_atomic_flag_set_fetch(&m_flash_operation_ongoing))
+ {
+ return NRF_ERROR_BUSY;
+ }
+
+ while (progress != len)
+ {
+ nrf_nvmc_page_erase(page_addr + (progress * m_flash_info.erase_unit));
+ progress++;
+ }
+
+ /* Clear the flag before sending the event, to allow API calls in the event context. */
+ (void) nrf_atomic_flag_clear(&m_flash_operation_ongoing);
+
+ event_send(p_fs, NRF_FSTORAGE_EVT_ERASE_RESULT, NULL, page_addr, len, p_param);
+
+ return NRF_SUCCESS;
+}
+
+
+static uint8_t const * rmap(nrf_fstorage_t const * p_fs, uint32_t addr)
+{
+ UNUSED_PARAMETER(p_fs);
+
+ return (uint8_t*)addr;
+}
+
+
+static uint8_t * wmap(nrf_fstorage_t const * p_fs, uint32_t addr)
+{
+ UNUSED_PARAMETER(p_fs);
+ UNUSED_PARAMETER(addr);
+
+ /* Not supported. */
+ return NULL;
+}
+
+
+static bool is_busy(nrf_fstorage_t const * p_fs)
+{
+ UNUSED_PARAMETER(p_fs);
+
+ return m_flash_operation_ongoing;
+}
+
+
+/* The exported API. */
+nrf_fstorage_api_t nrf_fstorage_nvmc =
+{
+ .init = init,
+ .uninit = uninit,
+ .read = read,
+ .write = write,
+ .erase = erase,
+ .rmap = rmap,
+ .wmap = wmap,
+ .is_busy = is_busy
+};
+
+
+#endif // NRF_FSTORAGE_ENABLED
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/fstorage/nrf_fstorage_nvmc.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/fstorage/nrf_fstorage_nvmc.h
new file mode 100644
index 0000000..bacd745
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/fstorage/nrf_fstorage_nvmc.h
@@ -0,0 +1,75 @@
+/**
+ * Copyright (c) 2016 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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
+ *
+ * @defgroup nrf_fstorage_nvmc NVMC implementation
+ * @ingroup nrf_fstorage
+ * @{
+ *
+ * @brief API implementation of fstorage that uses the non-volatile memory controller (NVMC).
+*/
+
+#ifndef NRF_FSTORAGE_NVMC_H__
+#define NRF_FSTORAGE_NVMC_H__
+
+#include "nrf_fstorage.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+/**@brief API implementation that uses the non-volatile memory controller.
+ *
+ * @details An fstorage instance with this API implementation can be initialized by providing
+ * this structure as a parameter to @ref nrf_fstorage_init.
+ * The structure is defined in @c nrf_fstorage_nvmc.c.
+ */
+extern nrf_fstorage_api_t nrf_fstorage_nvmc;
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // NRF_FSTORAGE_NVMC_H__
+/** @} */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/fstorage/nrf_fstorage_sd.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/fstorage/nrf_fstorage_sd.c
new file mode 100644
index 0000000..ef5f6b8
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/fstorage/nrf_fstorage_sd.c
@@ -0,0 +1,624 @@
+/**
+ * Copyright (c) 2016 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+
+#include "sdk_common.h"
+
+#if NRF_MODULE_ENABLED(NRF_FSTORAGE)
+
+#include "nrf_fstorage_sd.h"
+#include <stdint.h>
+#include <string.h>
+#include <stdbool.h>
+#include "nordic_common.h"
+#include "nrf_soc.h"
+#include "nrf_sdh.h"
+#include "nrf_sdh_soc.h"
+#include "nrf_atomic.h"
+#include "nrf_atfifo.h"
+#include "app_util_platform.h"
+
+
+#if (NRF_FSTORAGE_SD_MAX_WRITE_SIZE % 4)
+#error NRF_FSTORAGE_SD_MAX_WRITE_SIZE must be a multiple of the word size.
+#endif
+
+
+/**@brief fstorage operation codes. */
+typedef enum
+{
+ NRF_FSTORAGE_OP_WRITE, //!< Write bytes to flash.
+ NRF_FSTORAGE_OP_ERASE //!< Erase flash pages.
+} nrf_fstorage_sd_opcode_t;
+
+ANON_UNIONS_ENABLE;
+/**@brief fstorage operation queue element. */
+typedef struct
+{
+ nrf_fstorage_t const * p_fs; //!< The fstorage instance that requested the operation.
+ nrf_fstorage_sd_opcode_t op_code; //!< Requested operation.
+ void * p_param; //!< User-defined parameter passed to the event handler.
+ union
+ {
+ struct
+ {
+ void const * p_src; //!< Data to be written to flash.
+ uint32_t dest; //!< Destination of the data in flash.
+ uint32_t len; //!< Length of the data to be written (in bytes).
+ uint32_t offset; //!< Write offset.
+ } write;
+ struct
+ {
+ uint32_t page; //!< Physical page number.
+ uint32_t progress; //!< Number of pages erased.
+ uint32_t pages_to_erase; //!< Total number of pages to erase.
+ } erase;
+ };
+} nrf_fstorage_sd_op_t;
+ANON_UNIONS_DISABLE;
+
+typedef enum
+{
+ NRF_FSTORAGE_STATE_IDLE, //!< No operations requested to the SoftDevice.
+ NRF_FSTORAGE_STATE_OP_PENDING, //!< A non-fstorage operation is pending.
+ NRF_FSTORAGE_STATE_OP_EXECUTING, //!< An fstorage operation is executing.
+} nrf_fstorage_sd_state_t;
+
+/**@brief Internal state. */
+typedef struct
+{
+ nrf_atomic_flag_t initialized; //!< fstorage is initalized.
+ nrf_atomic_flag_t queue_running; //!< The queue is running.
+ /** Prevent API calls from entering queue_process(). */
+ nrf_fstorage_sd_state_t state; //!< Internal fstorage state.
+ uint32_t retries; //!< Number of times an operation has been retried on timeout.
+ bool sd_enabled; //!< The SoftDevice is enabled.
+ bool paused; //!< A SoftDevice state change is impending.
+ /** Do not load a new operation when the last one completes. */
+} nrf_fstorage_sd_work_t;
+
+
+void nrf_fstorage_sys_evt_handler(uint32_t, void *);
+bool nrf_fstorage_sdh_req_handler(nrf_sdh_req_evt_t, void *);
+void nrf_fstorage_sdh_state_handler(nrf_sdh_state_evt_t, void *);
+
+
+/* Flash device information. */
+static nrf_fstorage_info_t m_flash_info =
+{
+#if defined(NRF51)
+ .erase_unit = 1024,
+#elif defined(NRF52_SERIES)
+ .erase_unit = 4096,
+#endif
+ .program_unit = 4,
+ .rmap = true,
+ .wmap = false,
+};
+
+/* Queue of fstorage operations. */
+NRF_ATFIFO_DEF(m_fifo, nrf_fstorage_sd_op_t, NRF_FSTORAGE_SD_QUEUE_SIZE);
+
+/* Define a nrf_sdh_soc event observer to receive SoftDevice system events. */
+NRF_SDH_SOC_OBSERVER(m_sys_obs, 0, nrf_fstorage_sys_evt_handler, NULL);
+
+/* nrf_sdh request observer. */
+NRF_SDH_REQUEST_OBSERVER(m_req_obs, 0) =
+{
+ .handler = nrf_fstorage_sdh_req_handler,
+};
+
+/* nrf_sdh state observer. */
+NRF_SDH_STATE_OBSERVER(m_state_obs, 0) =
+{
+ .handler = nrf_fstorage_sdh_state_handler,
+};
+
+static nrf_fstorage_sd_work_t m_flags; /* Internal status. */
+static nrf_fstorage_sd_op_t * m_p_cur_op; /* The current operation being executed. */
+static nrf_atfifo_item_get_t m_iget_ctx; /* Context for nrf_atfifo_item_get() and nrf_atfifo_item_free(). */
+
+
+/* Send events to the application. */
+static void event_send(nrf_fstorage_sd_op_t const * p_op, ret_code_t result)
+{
+ if (p_op->p_fs->evt_handler == NULL)
+ {
+ /* Nothing to do. */
+ return;
+ }
+
+ nrf_fstorage_evt_t evt =
+ {
+ .result = result,
+ .p_param = p_op->p_param,
+ };
+
+ switch (p_op->op_code)
+ {
+ case NRF_FSTORAGE_OP_WRITE:
+ evt.id = NRF_FSTORAGE_EVT_WRITE_RESULT;
+ evt.addr = p_op->write.dest;
+ evt.p_src = p_op->write.p_src;
+ evt.len = p_op->write.len;
+ break;
+
+ case NRF_FSTORAGE_OP_ERASE:
+ evt.id = NRF_FSTORAGE_EVT_ERASE_RESULT;
+ evt.addr = (p_op->erase.page * m_flash_info.erase_unit);
+ evt.len = p_op->erase.pages_to_erase;
+ break;
+
+ default:
+ /* Should not happen. */
+ break;
+ }
+
+ p_op->p_fs->evt_handler(&evt);
+}
+
+
+/* Write to flash. */
+static uint32_t write_execute(nrf_fstorage_sd_op_t const * p_op)
+{
+ uint32_t chunk_len;
+
+ chunk_len = MIN(p_op->write.len - p_op->write.offset, NRF_FSTORAGE_SD_MAX_WRITE_SIZE);
+ chunk_len = MAX(1, chunk_len / m_flash_info.program_unit);
+
+ /* Cast to p_src to uint32_t to perform arithmetic. */
+ uint32_t * p_dest = (uint32_t*)(p_op->write.dest + p_op->write.offset);
+ uint32_t const * p_src = (uint32_t*)((uint32_t)p_op->write.p_src + p_op->write.offset);
+
+ return sd_flash_write(p_dest, p_src, chunk_len);
+}
+
+
+/* Erase flash page(s). */
+static uint32_t erase_execute(nrf_fstorage_sd_op_t const * p_op)
+{
+ return sd_flash_page_erase(p_op->erase.page + p_op->erase.progress);
+}
+
+
+/* Free the current queue element. */
+static void queue_free(void)
+{
+ (void) nrf_atfifo_item_free(m_fifo, &m_iget_ctx);
+}
+
+
+/* Load a new operation from the queue. */
+static bool queue_load_next(void)
+{
+ m_p_cur_op = nrf_atfifo_item_get(m_fifo, &m_iget_ctx);
+
+ return (m_p_cur_op != NULL);
+}
+
+
+/* Execute an operation in the queue. */
+static void queue_process(void)
+{
+ uint32_t rc;
+
+ if (m_flags.state == NRF_FSTORAGE_STATE_IDLE)
+ {
+ if (!queue_load_next())
+ {
+ /* No more operations, nothing to do. */
+ m_flags.queue_running = false;
+ return;
+ }
+ }
+
+ m_flags.state = NRF_FSTORAGE_STATE_OP_EXECUTING;
+
+ switch (m_p_cur_op->op_code)
+ {
+ case NRF_FSTORAGE_OP_WRITE:
+ rc = write_execute(m_p_cur_op);
+ break;
+
+ case NRF_FSTORAGE_OP_ERASE:
+ rc = erase_execute(m_p_cur_op);
+ break;
+
+ default:
+ rc = NRF_ERROR_INTERNAL;
+ break;
+ }
+
+ switch (rc)
+ {
+ case NRF_SUCCESS:
+ {
+ /* The operation was accepted by the SoftDevice.
+ * If the SoftDevice is enabled, wait for a system event. Otherwise,
+ * the SoftDevice call is synchronous and will not send an event so we simulate it. */
+ if (!m_flags.sd_enabled)
+ {
+ nrf_fstorage_sys_evt_handler(NRF_EVT_FLASH_OPERATION_SUCCESS, NULL);
+ }
+ } break;
+
+ case NRF_ERROR_BUSY:
+ {
+ /* The SoftDevice is executing a flash operation that was not requested by fstorage.
+ * Stop processing the queue until a system event is received. */
+ m_flags.state = NRF_FSTORAGE_STATE_OP_PENDING;
+ } break;
+
+ default:
+ {
+ /* An error has occurred. We cannot proceed further with this operation. */
+ event_send(m_p_cur_op, NRF_ERROR_INTERNAL);
+ /* Reset the internal state so we can accept other operations. */
+ m_flags.state = NRF_FSTORAGE_STATE_IDLE;
+ m_flags.queue_running = false;
+ /* Free the current queue element. */
+ queue_free();
+ } break;
+ }
+}
+
+
+/* Start processing the queue if it is not running and fstorage is not paused. */
+static void queue_start(void)
+{
+ if ( (!nrf_atomic_flag_set_fetch(&m_flags.queue_running))
+ && (!m_flags.paused))
+ {
+ queue_process();
+ }
+}
+
+
+/* Flash operation success callback. Keeps track of the progress of an operation. */
+static bool on_operation_success(nrf_fstorage_sd_op_t * const p_op)
+{
+ /* Reset the retry counter on success. */
+ m_flags.retries = 0;
+
+ switch (p_op->op_code)
+ {
+ case NRF_FSTORAGE_OP_WRITE:
+ {
+ /* Update the offset only if the operation is successful
+ * so that it can be retried in case it times out. */
+ uint32_t const chunk_len = MIN(p_op->write.len - p_op->write.offset,
+ NRF_FSTORAGE_SD_MAX_WRITE_SIZE);
+
+ p_op->write.offset += chunk_len;
+
+ if (p_op->write.offset == p_op->write.len)
+ {
+ return true;
+ }
+ } break;
+
+ case NRF_FSTORAGE_OP_ERASE:
+ {
+ p_op->erase.progress++;
+
+ if (p_op->erase.progress == p_op->erase.pages_to_erase)
+ {
+ return true;
+ }
+ } break;
+
+ default:
+ /* Should not happen. */
+ break;
+ }
+
+ return false;
+}
+
+
+/* Flash operation failure callback. */
+static bool on_operation_failure(nrf_fstorage_sd_op_t const * p_op)
+{
+ UNUSED_PARAMETER(p_op);
+
+ m_flags.retries++;
+
+ if (m_flags.retries > NRF_FSTORAGE_SD_MAX_RETRIES)
+ {
+ /* Maximum amount of retries reached. Give up. */
+ m_flags.retries = 0;
+ return true;
+ }
+
+ return false;
+}
+
+
+static ret_code_t init(nrf_fstorage_t * p_fs, void * p_param)
+{
+ UNUSED_PARAMETER(p_param);
+
+ p_fs->p_flash_info = &m_flash_info;
+
+ if (!nrf_atomic_flag_set_fetch(&m_flags.initialized))
+ {
+#if NRF_SDH_ENABLED
+ m_flags.sd_enabled = nrf_sdh_is_enabled();
+#endif
+ (void) NRF_ATFIFO_INIT(m_fifo);
+ }
+
+ return NRF_SUCCESS;
+}
+
+
+static ret_code_t uninit(nrf_fstorage_t * p_fs, void * p_param)
+{
+ UNUSED_PARAMETER(p_fs);
+ UNUSED_PARAMETER(p_param);
+
+ /* The state is re-initialized upon init().
+ * The common uninitialization code is run by the caller. */
+
+ memset(&m_flags, 0x00, sizeof(m_flags));
+
+ (void) nrf_atfifo_clear(m_fifo);
+
+ return NRF_SUCCESS;
+}
+
+
+static ret_code_t write(nrf_fstorage_t const * p_fs,
+ uint32_t dest,
+ void const * p_src,
+ uint32_t len,
+ void * p_param)
+{
+ nrf_fstorage_sd_op_t * p_op;
+ nrf_atfifo_item_put_t iput_ctx;
+
+ /* Get a free queue element. */
+ p_op = nrf_atfifo_item_alloc(m_fifo, &iput_ctx);
+
+ if (p_op == NULL)
+ {
+ return NRF_ERROR_NO_MEM;
+ }
+
+ /* Initialize the operation. */
+ memset(p_op, 0x00, sizeof(nrf_fstorage_sd_op_t));
+
+ p_op->op_code = NRF_FSTORAGE_OP_WRITE;
+ p_op->p_fs = p_fs;
+ p_op->p_param = p_param;
+ p_op->write.dest = dest;
+ p_op->write.p_src = p_src;
+ p_op->write.len = len;
+
+ /* Put the operation on the queue. */
+ (void) nrf_atfifo_item_put(m_fifo, &iput_ctx);
+
+ queue_start();
+
+ return NRF_SUCCESS;
+}
+
+
+static ret_code_t read(nrf_fstorage_t const * p_fs, uint32_t src, void * p_dest, uint32_t len)
+{
+ memcpy(p_dest, (uint32_t*)src, len);
+
+ return NRF_SUCCESS;
+}
+
+
+static ret_code_t erase(nrf_fstorage_t const * p_fs,
+ uint32_t page_addr,
+ uint32_t len,
+ void * p_param)
+{
+ nrf_fstorage_sd_op_t * p_op;
+ nrf_atfifo_item_put_t iput_ctx;
+
+ /* Get a free queue element. */
+ p_op = nrf_atfifo_item_alloc(m_fifo, &iput_ctx);
+
+ if (p_op == NULL)
+ {
+ return NRF_ERROR_NO_MEM;
+ }
+
+ /* Initialize the operation. */
+ memset(p_op, 0x00, sizeof(nrf_fstorage_sd_op_t));
+
+ p_op->op_code = NRF_FSTORAGE_OP_ERASE;
+ p_op->p_fs = p_fs;
+ p_op->p_param = p_param;
+ p_op->erase.page = (page_addr / m_flash_info.erase_unit);
+ p_op->erase.pages_to_erase = len;
+
+ /* Put the operation on the queue. */
+ (void) nrf_atfifo_item_put(m_fifo, &iput_ctx);
+
+ queue_start();
+
+ return NRF_SUCCESS;
+}
+
+
+static uint8_t const * rmap(nrf_fstorage_t const * p_fs, uint32_t addr)
+{
+ UNUSED_PARAMETER(p_fs);
+
+ return (uint8_t*)addr;
+}
+
+
+static uint8_t * wmap(nrf_fstorage_t const * p_fs, uint32_t addr)
+{
+ UNUSED_PARAMETER(p_fs);
+ UNUSED_PARAMETER(addr);
+
+ /* Not supported. */
+ return NULL;
+}
+
+
+static bool is_busy(nrf_fstorage_t const * p_fs)
+{
+ UNUSED_PARAMETER(p_fs);
+
+ return (m_flags.state != NRF_FSTORAGE_STATE_IDLE);
+}
+
+
+void nrf_fstorage_sys_evt_handler(uint32_t sys_evt, void * p_context)
+{
+ UNUSED_PARAMETER(p_context);
+
+ if ( (sys_evt != NRF_EVT_FLASH_OPERATION_SUCCESS)
+ && (sys_evt != NRF_EVT_FLASH_OPERATION_ERROR))
+ {
+ /* Ignore any non-flash events. */
+ return;
+ }
+
+ switch (m_flags.state)
+ {
+ case NRF_FSTORAGE_STATE_IDLE:
+ /* Ignore flash events if no flash operation was requested. */
+ return;
+
+ case NRF_FSTORAGE_STATE_OP_PENDING:
+ /* The SoftDevice has completed a flash operation that was not requested by fstorage.
+ * It should be possible to request an operation now.
+ * Process the queue at the end of this function. */
+ break;
+
+ case NRF_FSTORAGE_STATE_OP_EXECUTING:
+ {
+ /* Handle the result of a flash operation initiated by this module. */
+ bool operation_finished = false;
+
+ switch (sys_evt)
+ {
+ case NRF_EVT_FLASH_OPERATION_SUCCESS:
+ operation_finished = on_operation_success(m_p_cur_op);
+ break;
+
+ case NRF_EVT_FLASH_OPERATION_ERROR:
+ operation_finished = on_operation_failure(m_p_cur_op);
+ break;
+
+ default:
+ break;
+ }
+
+ if (operation_finished)
+ {
+ /* The operation has finished. Change state to NRF_FSTORAGE_STATE_IDLE
+ * so that queue_process() will fetch a new operation from the queue. */
+ m_flags.state = NRF_FSTORAGE_STATE_IDLE;
+
+ event_send(m_p_cur_op, (sys_evt == NRF_EVT_FLASH_OPERATION_SUCCESS) ?
+ NRF_SUCCESS : NRF_ERROR_TIMEOUT);
+
+ /* Free the queue element after sending out the event to prevent API calls made
+ * in the event context to queue elements indefinitely, without this function
+ * ever returning in case the SoftDevice calls are synchronous. */
+ queue_free();
+ }
+ } break;
+ }
+
+ if (!m_flags.paused)
+ {
+ queue_process();
+ }
+ else
+ {
+ /* A flash operation has completed. Let the SoftDevice change state. */
+ (void) nrf_sdh_request_continue();
+ }
+}
+
+
+bool nrf_fstorage_sdh_req_handler(nrf_sdh_req_evt_t req, void * p_context)
+{
+ UNUSED_PARAMETER(req);
+ UNUSED_PARAMETER(p_context);
+
+ m_flags.paused = true;
+
+ /* If there are any operations ongoing, pause the SoftDevice state change. */
+ return (m_flags.state == NRF_FSTORAGE_STATE_IDLE);
+}
+
+
+void nrf_fstorage_sdh_state_handler(nrf_sdh_state_evt_t state, void * p_context)
+{
+ UNUSED_PARAMETER(p_context);
+
+ if ( (state == NRF_SDH_EVT_STATE_ENABLED)
+ || (state == NRF_SDH_EVT_STATE_DISABLED))
+ {
+ m_flags.paused = false;
+ m_flags.sd_enabled = (state == NRF_SDH_EVT_STATE_ENABLED);
+
+ /* Execute any operations still in the queue. */
+ queue_process();
+ }
+}
+
+
+/* Exported API implementation. */
+nrf_fstorage_api_t nrf_fstorage_sd =
+{
+ .init = init,
+ .uninit = uninit,
+ .read = read,
+ .write = write,
+ .erase = erase,
+ .rmap = rmap,
+ .wmap = wmap,
+ .is_busy = is_busy
+};
+
+
+#endif // NRF_FSTORAGE_ENABLED
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/fstorage/nrf_fstorage_sd.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/fstorage/nrf_fstorage_sd.h
new file mode 100644
index 0000000..b35d15f
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/fstorage/nrf_fstorage_sd.h
@@ -0,0 +1,75 @@
+/**
+ * Copyright (c) 2016 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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
+ *
+ * @defgroup nrf_fstorage_sd SoftDevice implementation
+ * @ingroup nrf_fstorage
+ * @{
+ *
+ * @brief API implementation of fstorage that uses the SoftDevice.
+*/
+
+#ifndef NRF_FSTORAGE_SD_H__
+#define NRF_FSTORAGE_SD_H__
+
+#include "nrf_fstorage.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+/**@brief API implementation that uses the SoftDevice.
+ *
+ * @details An fstorage instance with this API implementation can be initialized by providing
+ * this structure as a parameter to @ref nrf_fstorage_init.
+ * The structure is defined in @c nrf_fstorage_sd.c.
+ */
+extern nrf_fstorage_api_t nrf_fstorage_sd;
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // NRF_FSTORAGE_SD_H__
+/** @} */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/gfx/nrf_gfx.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/gfx/nrf_gfx.c
new file mode 100644
index 0000000..bd8aedc
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/gfx/nrf_gfx.c
@@ -0,0 +1,628 @@
+/**
+ * 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+
+#include "sdk_common.h"
+
+#if NRF_MODULE_ENABLED(NRF_GFX)
+
+#include "nrf_gfx.h"
+#include <stdlib.h>
+#include "app_util_platform.h"
+#include "nrf_assert.h"
+
+#define NRF_LOG_MODULE_NAME gfx
+#include "nrf_log.h"
+NRF_LOG_MODULE_REGISTER();
+
+static inline void pixel_draw(nrf_lcd_t const * p_instance,
+ uint16_t x,
+ uint16_t y,
+ uint32_t color)
+{
+ uint16_t lcd_width = nrf_gfx_width_get(p_instance);
+ uint16_t lcd_height = nrf_gfx_height_get(p_instance);
+
+ if ((x >= lcd_width) || (y >= lcd_height))
+ {
+ return;
+ }
+
+ p_instance->lcd_pixel_draw(x, y, color);
+}
+
+static void rect_draw(nrf_lcd_t const * p_instance,
+ uint16_t x,
+ uint16_t y,
+ uint16_t width,
+ uint16_t height,
+ uint32_t color)
+{
+ uint16_t lcd_width = nrf_gfx_width_get(p_instance);
+ uint16_t lcd_height = nrf_gfx_height_get(p_instance);
+
+ if ((x >= lcd_width) || (y >= lcd_height))
+ {
+ return;
+ }
+
+ if (width > (lcd_width - x))
+ {
+ width = lcd_width - x;
+ }
+
+ if (height > (lcd_height - y))
+ {
+ height = lcd_height - y;
+ }
+
+ p_instance->lcd_rect_draw(x, y, width, height, color);
+}
+
+static void line_draw(nrf_lcd_t const * p_instance,
+ uint16_t x_0,
+ uint16_t y_0,
+ uint16_t x_1,
+ int16_t y_1,
+ uint32_t color)
+{
+ uint16_t x = x_0;
+ uint16_t y = y_0;
+ int16_t d;
+ int16_t d_1;
+ int16_t d_2;
+ int16_t ai;
+ int16_t bi;
+ int16_t xi = (x_0 < x_1) ? 1 : (-1);
+ int16_t yi = (y_0 < y_1) ? 1 : (-1);
+ bool swapped = false;
+
+ d_1 = abs(x_1 - x_0);
+ d_2 = abs(y_1 - y_0);
+
+ pixel_draw(p_instance, x, y, color);
+
+ if (d_1 < d_2)
+ {
+ d_1 = d_1 ^ d_2;
+ d_2 = d_1 ^ d_2;
+ d_1 = d_2 ^ d_1;
+ swapped = true;
+ }
+
+ ai = (d_2 - d_1) * 2;
+ bi = d_2 * 2;
+ d = bi - d_1;
+
+ while ((y != y_1) || (x != x_1))
+ {
+ if (d >= 0)
+ {
+ x += xi;
+ y += yi;
+ d += ai;
+ }
+ else
+ {
+ d += bi;
+ if (swapped)
+ {
+ y += yi;
+ }
+ else
+ {
+ x += xi;
+ }
+ }
+ pixel_draw(p_instance, x, y, color);
+ }
+}
+
+static void write_character(nrf_lcd_t const * p_instance,
+ nrf_gfx_font_desc_t const * p_font,
+ uint8_t character,
+ uint16_t * p_x,
+ uint16_t y,
+ uint16_t font_color)
+{
+ uint8_t char_idx = character - p_font->startChar;
+ uint16_t bytes_in_line = CEIL_DIV(p_font->charInfo[char_idx].widthBits, 8);
+
+ if (character == ' ')
+ {
+ *p_x += p_font->height / 2;
+ return;
+ }
+
+ for (uint16_t i = 0; i < p_font->height; i++)
+ {
+ for (uint16_t j = 0; j < bytes_in_line; j++)
+ {
+ for (uint8_t k = 0; k < 8; k++)
+ {
+ if ((1 << (7 - k)) &
+ p_font->data[p_font->charInfo[char_idx].offset + i * bytes_in_line + j])
+ {
+ pixel_draw(p_instance, *p_x + j * 8 + k, y + i, font_color);
+ }
+ }
+ }
+ }
+
+ *p_x += p_font->charInfo[char_idx].widthBits + p_font->spacePixels;
+}
+
+ret_code_t nrf_gfx_init(nrf_lcd_t const * p_instance)
+{
+ ASSERT(p_instance != NULL);
+ ASSERT(p_instance->p_lcd_cb->state == NRFX_DRV_STATE_UNINITIALIZED);
+ ASSERT(p_instance->lcd_init != NULL);
+ ASSERT(p_instance->lcd_uninit != NULL);
+ ASSERT(p_instance->lcd_pixel_draw != NULL);
+ ASSERT(p_instance->lcd_rect_draw != NULL);
+ ASSERT(p_instance->lcd_display != NULL);
+ ASSERT(p_instance->lcd_rotation_set != NULL);
+ ASSERT(p_instance->lcd_display_invert != NULL);
+ ASSERT(p_instance->p_lcd_cb != NULL);
+
+ ret_code_t err_code;
+
+ err_code = p_instance->lcd_init();
+
+ if (err_code == NRF_SUCCESS)
+ {
+ p_instance->p_lcd_cb->state = NRFX_DRV_STATE_INITIALIZED;
+ }
+
+ return err_code;
+}
+
+void nrf_gfx_uninit(nrf_lcd_t const * p_instance)
+{
+ ASSERT(p_instance != NULL);
+ ASSERT(p_instance->p_lcd_cb->state != NRFX_DRV_STATE_UNINITIALIZED);
+
+ p_instance->p_lcd_cb->state = NRFX_DRV_STATE_UNINITIALIZED;
+
+ p_instance->lcd_uninit();
+}
+
+void nrf_gfx_point_draw(nrf_lcd_t const * p_instance,
+ nrf_gfx_point_t const * p_point,
+ uint32_t color)
+{
+ ASSERT(p_instance != NULL);
+ ASSERT(p_instance->p_lcd_cb->state != NRFX_DRV_STATE_UNINITIALIZED);
+ ASSERT(p_point != NULL);
+
+ pixel_draw(p_instance, p_point->x, p_point->y, color);
+}
+
+ret_code_t nrf_gfx_line_draw(nrf_lcd_t const * p_instance,
+ nrf_gfx_line_t const * p_line,
+ uint32_t color)
+{
+ ASSERT(p_instance != NULL);
+ ASSERT(p_instance->p_lcd_cb->state != NRFX_DRV_STATE_UNINITIALIZED);
+ ASSERT(p_line != NULL);
+
+ uint16_t x_thick = 0;
+ uint16_t y_thick = 0;
+
+ if (((p_line->x_start > nrf_gfx_width_get(p_instance)) &&
+ (p_line->x_end > nrf_gfx_height_get(p_instance))) ||
+ ((p_line->y_start > nrf_gfx_width_get(p_instance)) &&
+ (p_line->y_end > nrf_gfx_height_get(p_instance))))
+ {
+ return NRF_ERROR_INVALID_PARAM;
+ }
+
+ if (abs(p_line->x_start - p_line->x_end) > abs(p_line->y_start - p_line->y_end))
+ {
+ y_thick = p_line->thickness;
+ }
+ else
+ {
+ x_thick = p_line->thickness;
+ }
+
+ if ((p_line->x_start == p_line->x_end) || (p_line->y_start == p_line->y_end))
+ {
+ rect_draw(p_instance,
+ p_line->x_start,
+ p_line->y_start,
+ abs(p_line->x_end - p_line->x_start) + x_thick,
+ abs(p_line->y_end - p_line->y_start) + y_thick,
+ color);
+ }
+ else
+ {
+ if (x_thick > 0)
+ {
+ for (uint16_t i = 0; i < p_line->thickness; i++)
+ {
+ line_draw(p_instance,
+ p_line->x_start + i,
+ p_line->y_start,
+ p_line->x_end + i,
+ p_line->y_end,
+ color);
+ }
+ }
+ else if (y_thick > 0)
+ {
+ for (uint16_t i = 0; i < p_line->thickness; i++)
+ {
+ line_draw(p_instance,
+ p_line->x_start,
+ p_line->y_start + i,
+ p_line->x_end,
+ p_line->y_end + i,
+ color);
+ }
+ }
+ else
+ {
+ line_draw(p_instance,
+ p_line->x_start + x_thick,
+ p_line->y_start + y_thick,
+ p_line->x_end + x_thick,
+ p_line->y_end + y_thick,
+ color);
+ }
+ }
+
+ return NRF_SUCCESS;
+}
+
+ret_code_t nrf_gfx_circle_draw(nrf_lcd_t const * p_instance,
+ nrf_gfx_circle_t const * p_circle,
+ uint32_t color,
+ bool fill)
+{
+ ASSERT(p_instance != NULL);
+ ASSERT(p_instance->p_lcd_cb->state != NRFX_DRV_STATE_UNINITIALIZED);
+ ASSERT(p_circle != NULL);
+
+ int16_t y = 0;
+ int16_t err = 0;
+ int16_t x = p_circle->r;
+
+ if ((p_circle->x - p_circle->r > nrf_gfx_width_get(p_instance)) ||
+ (p_circle->y - p_circle->r > nrf_gfx_height_get(p_instance)))
+ {
+ return NRF_ERROR_INVALID_PARAM;
+ }
+
+ while (x >= y)
+ {
+ if (fill)
+ {
+ if ((-y + p_circle->x < 0) || (-x + p_circle->x < 0))
+ {
+ rect_draw(p_instance, 0, (-x + p_circle->y), (y + p_circle->x + 1), 1, color);
+ rect_draw(p_instance, 0, (-y + p_circle->y), (x + p_circle->x + 1), 1, color);
+ rect_draw(p_instance, 0, (y + p_circle->y), (x + p_circle->x + 1), 1, color);
+ rect_draw(p_instance, 0, (x + p_circle->y), (y + p_circle->x + 1), 1, color);
+ }
+ else
+ {
+ rect_draw(p_instance, (-y + p_circle->x), (-x + p_circle->y), (2 * y + 1), 1, color);
+ rect_draw(p_instance, (-x + p_circle->x), (-y + p_circle->y), (2 * x + 1), 1, color);
+ rect_draw(p_instance, (-x + p_circle->x), (y + p_circle->y), (2 * x + 1), 1, color);
+ rect_draw(p_instance, (-y + p_circle->x), (x + p_circle->y), (2 * y + 1), 1, color);
+ }
+ }
+ else
+ {
+ pixel_draw(p_instance, (y + p_circle->x), (x + p_circle->y), color);
+ pixel_draw(p_instance, (-y + p_circle->x), (x + p_circle->y), color);
+ pixel_draw(p_instance, (x + p_circle->x), (y + p_circle->y), color);
+ pixel_draw(p_instance, (-x + p_circle->x), (y + p_circle->y), color);
+ pixel_draw(p_instance, (-y + p_circle->x), (-x + p_circle->y), color);
+ pixel_draw(p_instance, (y + p_circle->x), (-x + p_circle->y), color);
+ pixel_draw(p_instance, (-x + p_circle->x), (-y + p_circle->y), color);
+ pixel_draw(p_instance, (x + p_circle->x), (-y + p_circle->y), color);
+ }
+
+ if (err <= 0)
+ {
+ y += 1;
+ err += 2 * y + 1;
+ }
+ if (err > 0)
+ {
+ x -= 1;
+ err -= 2 * x + 1;
+ }
+ }
+
+ return NRF_SUCCESS;
+}
+
+ret_code_t nrf_gfx_rect_draw(nrf_lcd_t const * p_instance,
+ nrf_gfx_rect_t const * p_rect,
+ uint16_t thickness,
+ uint32_t color,
+ bool fill)
+{
+ ASSERT(p_instance != NULL);
+ ASSERT(p_instance->p_lcd_cb->state != NRFX_DRV_STATE_UNINITIALIZED);
+ ASSERT(p_rect != NULL);
+
+ uint16_t rect_width = p_rect->width - thickness;
+ uint16_t rect_height = p_rect->height - thickness;
+
+ if ((p_rect->width == 1) ||
+ (p_rect->height == 1) ||
+ (thickness * 2 > p_rect->width) ||
+ (thickness * 2 > p_rect->height) ||
+ ((p_rect->x > nrf_gfx_width_get(p_instance)) &&
+ (p_rect->y > nrf_gfx_height_get(p_instance))))
+ {
+ return NRF_ERROR_INVALID_PARAM;
+ }
+
+
+ if (fill)
+ {
+ rect_draw(p_instance,
+ p_rect->x,
+ p_rect->y,
+ p_rect->width,
+ p_rect->height,
+ color);
+ }
+ else
+ {
+ nrf_gfx_line_t line;
+
+ // Top horizontal line.
+ line.x_start = p_rect->x;
+ line.y_start = p_rect->y;
+ line.x_end = p_rect->x + p_rect->width;
+ line.y_end = p_rect->y;
+ line.thickness = thickness;
+ (void)nrf_gfx_line_draw(p_instance, &line, color);
+ // Bottom horizontal line.
+ line.x_start = p_rect->x;
+ line.y_start = p_rect->y + rect_height;
+ line.x_end = p_rect->x + p_rect->width;
+ line.y_end = p_rect->y + rect_height;
+ (void)nrf_gfx_line_draw(p_instance, &line, color);
+ // Left vertical line.
+ line.x_start = p_rect->x;
+ line.y_start = p_rect->y + thickness;
+ line.x_end = p_rect->x;
+ line.y_end = p_rect->y + rect_height;
+ (void)nrf_gfx_line_draw(p_instance, &line, color);
+ // Right vertical line.
+ line.x_start = p_rect->x + rect_width;
+ line.y_start = p_rect->y + thickness;
+ line.x_end = p_rect->x + rect_width;
+ line.y_end = p_rect->y + rect_height;
+ (void)nrf_gfx_line_draw(p_instance, &line, color);
+ }
+
+ return NRF_SUCCESS;
+}
+
+void nrf_gfx_screen_fill(nrf_lcd_t const * p_instance, uint32_t color)
+{
+ rect_draw(p_instance, 0, 0, nrf_gfx_width_get(p_instance), nrf_gfx_height_get(p_instance), color);
+}
+
+ret_code_t nrf_gfx_bmp565_draw(nrf_lcd_t const * p_instance,
+ nrf_gfx_rect_t const * p_rect,
+ uint16_t const * img_buf)
+{
+ ASSERT(p_instance != NULL);
+ ASSERT(p_instance->p_lcd_cb->state != NRFX_DRV_STATE_UNINITIALIZED);
+ ASSERT(p_rect != NULL);
+ ASSERT(img_buf != NULL);
+
+ if ((p_rect->x > nrf_gfx_width_get(p_instance)) || (p_rect->y > nrf_gfx_height_get(p_instance)))
+ {
+ return NRF_ERROR_INVALID_PARAM;
+ }
+
+ size_t idx;
+ uint16_t pixel;
+ uint8_t padding = p_rect->width % 2;
+
+ for (int32_t i = 0; i < p_rect->height; i++)
+ {
+ for (uint32_t j = 0; j < p_rect->width; j++)
+ {
+ idx = (uint32_t)((p_rect->height - i - 1) * (p_rect->width + padding) + j);
+
+ pixel = (img_buf[idx] >> 8) | (img_buf[idx] << 8);
+
+ pixel_draw(p_instance, p_rect->x + j, p_rect->y + i, pixel);
+ }
+ }
+
+ return NRF_SUCCESS;
+}
+
+void nrf_gfx_background_set(nrf_lcd_t const * p_instance, uint16_t const * img_buf)
+{
+ ASSERT(p_instance != NULL);
+ ASSERT(p_instance->p_lcd_cb->state != NRFX_DRV_STATE_UNINITIALIZED);
+ ASSERT(img_buf != NULL);
+
+ const nrf_gfx_rect_t rectangle =
+ {
+ .x = 0,
+ .y = 0,
+ .width = nrf_gfx_width_get(p_instance),
+ .height = nrf_gfx_height_get(p_instance)
+ };
+
+ (void)nrf_gfx_bmp565_draw(p_instance, &rectangle, img_buf);
+}
+
+void nrf_gfx_display(nrf_lcd_t const * p_instance)
+{
+ ASSERT(p_instance != NULL);
+
+ p_instance->lcd_display();
+}
+
+void nrf_gfx_rotation_set(nrf_lcd_t const * p_instance, nrf_lcd_rotation_t rotation)
+{
+ ASSERT(p_instance != NULL);
+ ASSERT(p_instance->p_lcd_cb->state != NRFX_DRV_STATE_UNINITIALIZED);
+
+ bool rotated = (bool)(p_instance->p_lcd_cb->rotation % 2);
+
+ uint16_t height = !rotated ? nrf_gfx_height_get(p_instance) :
+ nrf_gfx_width_get(p_instance);
+ uint16_t width = !rotated ? nrf_gfx_width_get(p_instance) :
+ nrf_gfx_height_get(p_instance);
+
+ p_instance->p_lcd_cb->rotation = rotation;
+
+ switch (rotation) {
+ case NRF_LCD_ROTATE_0:
+ p_instance->p_lcd_cb->height = height;
+ p_instance->p_lcd_cb->width = width;
+ break;
+ case NRF_LCD_ROTATE_90:
+ p_instance->p_lcd_cb->height = width;
+ p_instance->p_lcd_cb->width = height;
+ break;
+ case NRF_LCD_ROTATE_180:
+ p_instance->p_lcd_cb->height = height;
+ p_instance->p_lcd_cb->width = width;
+ break;
+ case NRF_LCD_ROTATE_270:
+ p_instance->p_lcd_cb->height = width;
+ p_instance->p_lcd_cb->width = height;
+ break;
+ default:
+ break;
+ }
+
+ p_instance->lcd_rotation_set(rotation);
+}
+
+void nrf_gfx_invert(nrf_lcd_t const * p_instance, bool invert)
+{
+ ASSERT(p_instance != NULL);
+
+ p_instance->lcd_display_invert(invert);
+}
+
+ret_code_t nrf_gfx_print(nrf_lcd_t const * p_instance,
+ nrf_gfx_point_t const * p_point,
+ uint16_t font_color,
+ const char * string,
+ const nrf_gfx_font_desc_t * p_font,
+ bool wrap)
+{
+ ASSERT(p_instance != NULL);
+ ASSERT(p_instance->p_lcd_cb->state != NRFX_DRV_STATE_UNINITIALIZED);
+ ASSERT(p_point != NULL);
+ ASSERT(string != NULL);
+ ASSERT(p_font != NULL);
+
+ uint16_t x = p_point->x;
+ uint16_t y = p_point->y;
+
+ if (y > (nrf_gfx_height_get(p_instance) - p_font->height))
+ {
+ // Not enough space to write even single char.
+ return NRF_ERROR_INVALID_PARAM;
+ }
+
+ for (size_t i = 0; string[i] != '\0' ; i++)
+ {
+ if (string[i] == '\n')
+ {
+ x = p_point->x;
+ y += p_font->height + p_font->height / 10;
+ }
+ else
+ {
+ write_character(p_instance, p_font, (uint8_t)string[i], &x, y, font_color);
+ }
+
+ uint8_t char_idx = string[i] - p_font->startChar;
+ uint16_t char_width = string[i] == ' ' ? (p_font->height / 2) :
+ p_font->charInfo[char_idx].widthBits;
+
+ if (x > (nrf_gfx_width_get(p_instance) - char_width))
+ {
+ if (wrap)
+ {
+ x = p_point->x;
+ y += p_font->height + p_font->height / 10;
+ }
+ else
+ {
+ break;
+ }
+
+ if (y > (nrf_gfx_height_get(p_instance) - p_font->height))
+ {
+ break;
+ }
+ }
+ }
+
+ return NRF_SUCCESS;
+}
+
+uint16_t nrf_gfx_height_get(nrf_lcd_t const * p_instance)
+{
+ ASSERT(p_instance != NULL);
+
+ return p_instance->p_lcd_cb->height;
+}
+
+uint16_t nrf_gfx_width_get(nrf_lcd_t const * p_instance)
+{
+ ASSERT(p_instance != NULL);
+
+ return p_instance->p_lcd_cb->width;
+}
+
+#endif //NRF_MODULE_ENABLED(NRF_GFX)
+
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/gfx/nrf_gfx.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/gfx/nrf_gfx.h
new file mode 100644
index 0000000..dcc4e77
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/gfx/nrf_gfx.h
@@ -0,0 +1,320 @@
+/**
+ * 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+
+#ifndef NRF_GFX_H__
+#define NRF_GFX_H__
+
+#include <stdint.h>
+#include <stdbool.h>
+#include "sdk_errors.h"
+#include "nrf_lcd.h"
+#include "nrf_font.h"
+
+/** @file
+ *
+ * @addtogroup ili9341_config
+ * @ingroup ext_drivers
+ *
+ * @addtogroup st7735_config
+ * @ingroup ext_drivers
+ *
+ * @defgroup nrf_gfx GFX Library
+ * @{
+ * @ingroup app_common
+ *
+ * @brief Module for drawing graphical objects like lines, circles, and rectangles.
+ Provides support for different fonts.
+ */
+
+/**
+ * @brief GFX point object structure.
+ */
+typedef struct
+{
+ uint16_t x; /**< Horizontal coordinate of the point where to start drawing the object. */
+ uint16_t y; /**< Vertical coordinate of the point where to start drawing the object. */
+}nrf_gfx_point_t;
+
+/**
+ * @brief GFX line object structure.
+ */
+typedef struct
+{
+ uint16_t x_start; /**< Horizontal coordinate of the point where to start drawing the object. */
+ uint16_t y_start; /**< Vertical coordinate of the point where to start drawing the object. */
+ uint16_t x_end; /**< Horizontal coordinate of the point where to end drawing the object. */
+ uint16_t y_end; /**< Vertical coordinate of the point where to end drawing the object. */
+ uint16_t thickness; /**< Thickness of the border of the object. */
+}nrf_gfx_line_t;
+
+/**
+ * @brief GFX circle object structure.
+ */
+typedef struct
+{
+ uint16_t x; /**< Horizontal coordinate of the centre of the object. */
+ uint16_t y; /**< Vertical coordinate of the centre of the object. */
+ uint16_t r; /**< Radius of the object. */
+}nrf_gfx_circle_t;
+
+/**
+ * @brief GFX rectangle object structure.
+ */
+typedef struct
+{
+ uint16_t x; /**< Horizontal coordinate of the point where to start drawing the object. */
+ uint16_t y; /**< Vertical coordinate of the point where to start drawing the object. */
+ uint16_t width; /**< Width of the object. */
+ uint16_t height; /**< Height of the object. */
+}nrf_gfx_rect_t;
+
+/**
+ * @defgroup nrf_gfx_macros Macros for defining new graphic objects
+ * @{
+ */
+#define NRF_GFX_POINT(_x, _y) \
+ { \
+ .x = (_x), \
+ .y = (_y) \
+ }
+
+#define NRF_GFX_LINE(_x_0, _y_0, _x_1, _y_1, _thickness) \
+ { \
+ .x_start = (_x_0), \
+ .y_start = (_y_0), \
+ .x_end = (_x_1), \
+ .y_end = (_y_1), \
+ .thickness = (_thickness) \
+ }
+
+#define NRF_GFX_CIRCLE(_x, _y, _radius) \
+ { \
+ .x = (_x), \
+ .y = (_y), \
+ .r = (_radius) \
+ }
+
+#define NRF_GFX_RECT(_x, _y, _width, _height) \
+ { \
+ .x = (_x), \
+ .y = (_y), \
+ .width = (_width), \
+ .height = (_height) \
+ }
+/* @} */
+
+/**
+ * @brief Font descriptor type.
+ */
+typedef FONT_INFO nrf_gfx_font_desc_t;
+
+/**
+ * @brief Function for initializing the GFX library.
+ *
+ * @param[in] p_instance Pointer to the LCD instance.
+ *
+ * @return Values returned by @ref nrf_lcd_t::lcd_init.
+ */
+ret_code_t nrf_gfx_init(nrf_lcd_t const * p_instance);
+
+/**
+ * @brief Function for uninitializing the GFX library.
+ *
+ * @param[in] p_instance Pointer to the LCD instance.
+ *
+ * @return Values returned by @ref nrf_lcd_t::lcd_uninit.
+ */
+void nrf_gfx_uninit(nrf_lcd_t const * p_instance);
+
+/**
+ * @brief Function for drawing a point.
+ *
+ * @param[in] p_instance Pointer to the LCD instance.
+ * @param[in] p_point Pointer to the point object.
+ * @param[in] color Color of the object in the display accepted format.
+ */
+void nrf_gfx_point_draw(nrf_lcd_t const * p_instance, nrf_gfx_point_t const * p_point, uint32_t color);
+
+/**
+ * @brief Function for drawing a line.
+ *
+ * @param[in] p_instance Pointer to the LCD instance.
+ * @param[in] p_line Pointer to the line object.
+ * @param[in] color Color of the object in the display accepted format.
+ *
+ * @retval NRF_ERROR_INVALID_PARAM If object position is not on the screen.
+ * @retval NRF_SUCCESS If object was successfully drawn.
+ */
+ret_code_t nrf_gfx_line_draw(nrf_lcd_t const * p_instance, nrf_gfx_line_t const * p_line, uint32_t color);
+
+/**
+ * @brief Function for drawing a circle.
+ *
+ * @param[in] p_instance Pointer to the LCD instance.
+ * @param[in] p_circle Pointer to the circle object.
+ * @param[in] color Color of the object in the display accepted format.
+ * @param[in] fill If true, the circle will be filled.
+ *
+ * @retval NRF_ERROR_INVALID_PARAM If object position is not on the screen.
+ * @retval NRF_SUCCESS If object was successfully drawn.
+ *
+ * @note The height and width of the drawn circle are determined by: radius * 2 + 1.
+ *
+ */
+ret_code_t nrf_gfx_circle_draw(nrf_lcd_t const * p_instance,
+ nrf_gfx_circle_t const * p_circle,
+ uint32_t color,
+ bool fill);
+
+/**
+ * @brief Function for drawing a rectangle.
+ *
+ * @param[in] p_instance Pointer to the LCD instance.
+ * @param[in] p_rect Pointer to the rectangle object.
+ * @param[in] thickness Thickness of the rectangle border.
+ * @param[in] color Color of the object in the display accepted format.
+ * @param[in] fill If true, the rectangle will be filled.
+ *
+ * @retval NRF_ERROR_INVALID_PARAM If object position is not on the screen.
+ * @retval NRF_SUCCESS If object was successfully drawn.
+ */
+ret_code_t nrf_gfx_rect_draw(nrf_lcd_t const * p_instance,
+ nrf_gfx_rect_t const * p_rect,
+ uint16_t thickness,
+ uint32_t color,
+ bool fill);
+
+/**
+ * @brief Function for filling the screen with selected color.
+ *
+ * @param[in] p_instance Pointer to the LCD instance.
+ * @param[in] color Color of the screen in the display accepted format.
+ */
+void nrf_gfx_screen_fill(nrf_lcd_t const * p_instance, uint32_t color);
+
+/**
+ * @brief Function for drawing an image from a .bmp file.
+ *
+ * Data in img_buf is expected to be stored in 2-byte samples, little endianness, RGB565 format.
+ * Pointer should skip the header and point to the first byte of data.
+ *
+ * @param[in] p_instance Pointer to the LCD instance.
+ * @param[in] p_rect Pointer to the rectangle object.
+ * @param[in] img_buf Pointer to data from the .bmp file.
+ *
+ * @note Only compatible with displays that accept pixels in RGB565 format.
+ */
+ret_code_t nrf_gfx_bmp565_draw(nrf_lcd_t const * p_instance,
+ nrf_gfx_rect_t const * p_rect,
+ uint16_t const * img_buf);
+
+/**
+ * @brief Function for drawing an image from a .bmp file.
+ *
+ * Data in img_buf is expected to be stored in 2-byte samples, little endianness, RGB565 format.
+ * Pointer should skip the header and point to the first byte of data.
+ *
+ * @param[in] p_instance Pointer to the LCD instance.
+ * @param[in] img_buf Pointer to data from the .bmp file.
+ *
+ * @note Only compatible with displays that accept pixels in RGB565 format.
+ */
+void nrf_gfx_background_set(nrf_lcd_t const * p_instance, uint16_t const * img_buf);
+
+/**
+ * @brief Function for displaying data from an internal frame buffer.
+ *
+ * @param[in] p_instance Pointer to the LCD instance.
+ */
+void nrf_gfx_display(nrf_lcd_t const * p_instance);
+
+/**
+ * @brief Function for setting screen rotation.
+ *
+ * @param[in] p_instance Pointer to the LCD instance.
+ * @param[in] rotation Rotation to be made.
+ */
+void nrf_gfx_rotation_set(nrf_lcd_t const * p_instance, nrf_lcd_rotation_t rotation);
+
+/**
+ * @brief Function for setting inversion of colors.
+ *
+ * @param[in] p_instance Pointer to the LCD instance.
+ * @param[in] invert If true, inversion will be set.
+ */
+void nrf_gfx_invert(nrf_lcd_t const * p_instance, bool invert);
+
+/**
+ * @brief Function for printing a string to the screen.
+ *
+ * @param[in] p_instance Pointer to the LCD instance.
+ * @param[in] p_point Pointer to the point where to start drawing the object.
+ * @param[in] font_color Color of the font in the display accepted format.
+ * @param[in] p_string Pointer to the string.
+ * @param[in] p_font Pointer to the font descriptor.
+ * @param[in] wrap If true, the string will be wrapped to the new line.
+ */
+ret_code_t nrf_gfx_print(nrf_lcd_t const * p_instance,
+ nrf_gfx_point_t const * p_point,
+ uint16_t font_color,
+ const char * p_string,
+ const nrf_gfx_font_desc_t * p_font,
+ bool wrap);
+
+/**
+ * @brief Function for getting the height of the screen.
+ *
+ * @param[in] p_instance Pointer to the LCD instance.
+ *
+ */
+uint16_t nrf_gfx_height_get(nrf_lcd_t const * p_instance);
+
+/**
+ * @brief Function for getting the width of the screen.
+ *
+ * @param[in] p_instance Pointer to the LCD instance.
+ *
+ */
+uint16_t nrf_gfx_width_get(nrf_lcd_t const * p_instance);
+
+/* @} */
+
+#endif //NRF_GFX_H__
+
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/gfx/nrf_lcd.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/gfx/nrf_lcd.h
new file mode 100644
index 0000000..04202c5
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/gfx/nrf_lcd.h
@@ -0,0 +1,144 @@
+/**
+ * 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+
+#ifndef NRF_LCD_H__
+#define NRF_LCD_H__
+
+#include <nrfx.h>
+
+/** @file
+ *
+ * @defgroup nrf_lcd LCD Library
+ * @{
+ * @ingroup nrf_gfx
+ *
+ * @brief This module defines generic API for LCDs.
+ */
+
+/**
+ * @brief Enumerator with available rotations.
+ */
+typedef enum{
+ NRF_LCD_ROTATE_0 = 0, /**< Rotate 0 degrees, clockwise. */
+ NRF_LCD_ROTATE_90, /**< Rotate 90 degrees, clockwise. */
+ NRF_LCD_ROTATE_180, /**< Rotate 180 degrees, clockwise. */
+ NRF_LCD_ROTATE_270 /**< Rotate 270 degrees, clockwise. */
+}nrf_lcd_rotation_t;
+
+/**
+ * @brief LCD instance control block.
+ */
+typedef struct
+{
+ nrfx_drv_state_t state; /**< State of LCD instance. */
+ uint16_t height; /**< LCD height. */
+ uint16_t width; /**< LCD width. */
+ nrf_lcd_rotation_t rotation; /**< LCD rotation. */
+}lcd_cb_t;
+
+/**
+ * @brief LCD instance type.
+ *
+ * This structure provides generic API for LCDs.
+ */
+typedef struct
+{
+ /**
+ * @brief Function for initializing the LCD controller.
+ */
+ ret_code_t (* lcd_init)(void);
+
+ /**
+ * @brief Function for uninitializing the LCD controller.
+ */
+ void (* lcd_uninit)(void);
+
+ /**
+ * @brief Function for drawing a single pixel.
+ *
+ * @param[in] x Horizontal coordinate of the pixel.
+ * @param[in] y Vertical coordinate of the pixel.
+ * @param[in] color Color of the pixel in LCD accepted format.
+ */
+ void (* lcd_pixel_draw)(uint16_t x, uint16_t y, uint32_t color);
+
+ /**
+ * @brief Function for drawing a filled rectangle.
+ *
+ * @param[in] x Horizontal coordinate of the point where to start drawing the rectangle.
+ * @param[in] y Vertical coordinate of the point where to start drawing the rectangle.
+ * @param[in] width Width of the image.
+ * @param[in] height Height of the image.
+ * @param[in] color Color with which to fill the rectangle in LCD accepted format.
+ */
+ void (* lcd_rect_draw)(uint16_t x, uint16_t y, uint16_t width, uint16_t height, uint32_t color);
+
+ /**
+ * @brief Function for displaying data from an internal frame buffer.
+ *
+ * This function may be used when functions for drawing do not write directly to
+ * LCD but to an internal frame buffer. It could be implemented to write data from this
+ * buffer to LCD.
+ */
+ void (* lcd_display)(void);
+
+ /**
+ * @brief Function for rotating the screen.
+ *
+ * @param[in] rotation Rotation as enumerated value.
+ */
+ void (* lcd_rotation_set)(nrf_lcd_rotation_t rotation);
+
+ /**
+ * @brief Function for setting inversion of colors on the screen.
+ *
+ * @param[in] invert If true, inversion will be set.
+ */
+ void (* lcd_display_invert)(bool invert);
+
+ /**
+ * @brief Pointer to the LCD instance control block.
+ */
+ lcd_cb_t * p_lcd_cb;
+}nrf_lcd_t;
+
+/* @} */
+
+#endif // NRF_LCD_H__
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/gpiote/app_gpiote.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/gpiote/app_gpiote.c
new file mode 100644
index 0000000..4457ca6
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/gpiote/app_gpiote.c
@@ -0,0 +1,352 @@
+/**
+ * Copyright (c) 2015 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#include "sdk_common.h"
+#if NRF_MODULE_ENABLED(APP_GPIOTE)
+#include "app_gpiote.h"
+#include "nrf_bitmask.h"
+#define MODULE_INITIALIZED (mp_users != NULL) /**< Macro designating whether the module has been initialized properly. */
+
+/**@brief GPIOTE user type. */
+typedef struct
+{
+ uint32_t pins_mask[GPIO_COUNT]; /**< Mask defining which pins user wants to monitor. */
+ uint32_t pins_low_to_high_mask[GPIO_COUNT]; /**< Mask defining which pins will generate events to this user when toggling low->high. */
+ uint32_t pins_high_to_low_mask[GPIO_COUNT]; /**< Mask defining which pins will generate events to this user when toggling high->low. */
+ uint32_t sense_high_pins[GPIO_COUNT]; /**< Mask defining which pins are configured to generate GPIOTE interrupt on transition to high level. */
+ app_gpiote_event_handler_t event_handler; /**< Pointer to function to be executed when an event occurs. */
+ bool enabled; /**< Flag indicating whether user is enabled. */
+} gpiote_user_t;
+
+STATIC_ASSERT(sizeof(gpiote_user_t) <= GPIOTE_USER_NODE_SIZE);
+STATIC_ASSERT(sizeof(gpiote_user_t) % 4 == 0);
+
+static uint8_t m_user_array_size; /**< Size of user array. */
+static uint8_t m_user_count; /**< Number of registered users. */
+static gpiote_user_t * mp_users = NULL; /**< Array of GPIOTE users. */
+static uint32_t m_pins[GPIO_COUNT]; /**< Mask of initialized pins. */
+static uint32_t m_last_pins_state[GPIO_COUNT]; /**< Most recent state of pins. */
+
+void gpiote_handler(nrf_drv_gpiote_pin_t pin, nrf_gpiote_polarity_t action)
+{
+ int i;
+ uint32_t pin_mask[GPIO_COUNT] = {0};
+ uint32_t empty_pin_mask[GPIO_COUNT] = {0};
+ nrf_bitmask_bit_set(pin, pin_mask);
+ bool hitolo = nrf_bitmask_bit_is_set(pin, m_last_pins_state);
+ nrf_gpio_ports_read(0, GPIO_COUNT, m_last_pins_state);
+
+ for (i = 0; i < m_user_count; i++)
+ {
+ if (mp_users[i].enabled && nrf_bitmask_bit_is_set(pin, mp_users[i].pins_mask))
+ {
+ if (
+ nrf_bitmask_bit_is_set(pin, mp_users[i].pins_high_to_low_mask)
+ && hitolo)
+ {
+ mp_users[i].event_handler(empty_pin_mask,pin_mask);
+ }
+ else if (
+ nrf_bitmask_bit_is_set(pin, mp_users[i].pins_low_to_high_mask)
+ && !hitolo)
+ {
+ mp_users[i].event_handler(pin_mask,empty_pin_mask);
+ }
+ }
+ }
+}
+
+uint32_t app_gpiote_init(uint8_t max_users, void * p_buffer)
+{
+ uint32_t ret_code = NRF_SUCCESS;
+
+ if (p_buffer == NULL)
+ {
+ return NRF_ERROR_INVALID_PARAM;
+ }
+
+ // Check that buffer is correctly aligned.
+ if (!is_word_aligned(p_buffer))
+ {
+ return NRF_ERROR_INVALID_PARAM;
+ }
+
+ // Initialize file globals.
+ mp_users = (gpiote_user_t *)p_buffer;
+ m_user_array_size = max_users;
+ m_user_count = 0;
+ memset(m_pins,0, sizeof(m_pins));
+
+ memset(mp_users, 0, m_user_array_size * sizeof(gpiote_user_t));
+
+ if (nrf_drv_gpiote_is_init()==false)
+ {
+ ret_code = nrf_drv_gpiote_init();
+ }
+
+ return ret_code;
+}
+
+uint32_t app_gpiote_user_register(app_gpiote_user_id_t * p_user_id,
+ uint32_t const * p_pins_low_to_high_mask,
+ uint32_t const * p_pins_high_to_low_mask,
+ app_gpiote_event_handler_t event_handler)
+{
+ uint32_t user_pin_mask[GPIO_COUNT];
+ ASSERT(event_handler != NULL);
+
+ // Check state and parameters.
+ VERIFY_MODULE_INITIALIZED();
+
+ if (m_user_count >= m_user_array_size)
+ {
+ return NRF_ERROR_NO_MEM;
+ }
+
+ nrf_bitmask_masks_or(p_pins_low_to_high_mask, p_pins_high_to_low_mask,
+ user_pin_mask, sizeof(user_pin_mask));
+ // Allocate new user.
+ mp_users[m_user_count].enabled = false;
+ mp_users[m_user_count].event_handler = event_handler;
+
+ memcpy(mp_users[m_user_count].pins_mask,
+ user_pin_mask,
+ sizeof(mp_users[m_user_count].pins_mask));
+ memcpy(mp_users[m_user_count].pins_low_to_high_mask,
+ p_pins_low_to_high_mask,
+ sizeof(mp_users[m_user_count].pins_low_to_high_mask));
+ memcpy(mp_users[m_user_count].pins_high_to_low_mask,
+ p_pins_high_to_low_mask,
+ sizeof(mp_users[m_user_count].pins_high_to_low_mask));
+
+ uint32_t i;
+ const nrf_drv_gpiote_in_config_t config = GPIOTE_CONFIG_IN_SENSE_TOGGLE(false);
+
+ uint32_t num_of_pins = NUMBER_OF_PINS ;
+ for (i = 0; i < num_of_pins; i++)
+ {
+ if (nrf_bitmask_bit_is_set(i, user_pin_mask) &&
+ !nrf_bitmask_bit_is_set(i, m_pins))
+ {
+ uint32_t ret_val = nrf_drv_gpiote_in_init(i, &config, gpiote_handler);
+ VERIFY_SUCCESS(ret_val);
+ nrf_bitmask_bit_set(i, m_pins);
+ }
+ }
+
+ /* Success - return user id and increment counter */
+ *p_user_id = m_user_count++;
+ return NRF_SUCCESS;
+}
+
+uint32_t app_gpiote_user_register_ex(app_gpiote_user_id_t * p_user_id,
+ app_gpiote_user_pin_config_t const * p_pins_config,
+ size_t pin_count,
+ app_gpiote_event_handler_t event_handler)
+{
+ ASSERT(event_handler != NULL);
+
+ // Check state and parameters.
+ VERIFY_MODULE_INITIALIZED();
+ if (m_user_count >= m_user_array_size)
+ {
+ return NRF_ERROR_NO_MEM;
+ }
+ /* Prepare user structure */
+ gpiote_user_t * p_user = &mp_users[m_user_count];
+
+ p_user->enabled = false;
+ memset(p_user, 0, sizeof(gpiote_user_t));
+ mp_users[m_user_count].event_handler = event_handler;
+
+ for (; pin_count != 0; --pin_count, ++p_pins_config)
+ {
+ nrfx_gpiote_pin_t pin = (nrfx_gpiote_pin_t)p_pins_config->pin_number;
+ const nrf_drv_gpiote_in_config_t config = GPIOTE_RAW_CONFIG_IN_SENSE_TOGGLE(false);
+ if (!nrf_bitmask_bit_is_set(pin, m_pins))
+ {
+ uint32_t ret_val = nrf_drv_gpiote_in_init(pin, &config, gpiote_handler);
+ VERIFY_SUCCESS(ret_val);
+ nrf_bitmask_bit_set(pin, m_pins);
+ }
+
+ //lint -save -e650 Lint seems not properly support bitfields that uses enum as a base type
+ if ((p_pins_config->sense == NRF_GPIOTE_POLARITY_LOTOHI) ||
+ (p_pins_config->sense == NRF_GPIOTE_POLARITY_TOGGLE))
+ {
+ nrf_bitmask_bit_set(pin, p_user->pins_low_to_high_mask);
+ }
+ if ((p_pins_config->sense == NRF_GPIOTE_POLARITY_HITOLO) ||
+ (p_pins_config->sense == NRF_GPIOTE_POLARITY_TOGGLE))
+ {
+ nrf_bitmask_bit_set(pin, p_user->pins_high_to_low_mask);
+ }
+ //lint -restore
+ }
+ /* Mark all pins used by the selected user */
+ nrf_bitmask_masks_or(
+ p_user->pins_low_to_high_mask,
+ p_user->pins_high_to_low_mask,
+ p_user->pins_mask,
+ sizeof(p_user->pins_mask));
+ /* Success - return user id and increment counter */
+ *p_user_id = m_user_count++;
+
+ return NRF_SUCCESS;
+}
+
+__STATIC_INLINE uint32_t error_check(app_gpiote_user_id_t user_id)
+{
+ // Check state and parameters.
+ VERIFY_MODULE_INITIALIZED();
+
+ if (user_id >= m_user_count)
+ {
+ return NRF_ERROR_INVALID_PARAM;
+ }
+ return NRF_SUCCESS;
+}
+/**
+ * @brief Function for enabling event on pin (if not yet enabled) or disabling the event if no other
+ * user requires it.
+ *
+ * @param pin Pin to enable
+ * @param enable If true function will attempt to enable the pin else it will attempt to disable it.
+ */
+static void pin_event_enable(uint32_t pin, bool enable)
+{
+ uint32_t i;
+ bool enabled = false;
+ //search if any user already enabled given pin
+ for (i = 0; i < m_user_count; i++)
+ {
+ if (mp_users[i].enabled &&
+ nrf_bitmask_bit_is_set(pin, mp_users[i].pins_mask))
+ {
+ enabled = true;
+ break;
+ }
+ }
+ if (!enabled)
+ {
+ if (enable)
+ {
+ nrf_gpio_ports_read(0, GPIO_COUNT, m_last_pins_state);
+ nrf_drv_gpiote_in_event_enable(pin, true);
+ }
+ else
+ {
+ nrf_drv_gpiote_in_event_disable(pin);
+ }
+ }
+}
+
+/**
+ * @brief Function for enabling or disabling events for pins used by the user.
+ *
+ * Function will enable pin events only if they are not yet enabled. Function will disable pin
+ * events only if there is no other enabled user that is using them.
+ *
+ * @param user_id User id.
+ * @param enable If true function will attempt to enable the pin else it will attempt to disable it.
+ */
+static uint32_t user_enable(app_gpiote_user_id_t user_id, bool enable)
+{
+ uint32_t ret_code = error_check(user_id);
+
+ if (ret_code == NRF_SUCCESS)
+ {
+ uint32_t i;
+ for (i = 0; i < NUMBER_OF_PINS; i++)
+ {
+ if (nrf_bitmask_bit_is_set(i, mp_users[user_id].pins_mask))
+ {
+ pin_event_enable(i, enable);
+ }
+ }
+ }
+ return ret_code;
+}
+
+uint32_t app_gpiote_user_enable(app_gpiote_user_id_t user_id)
+{
+ uint32_t ret_code = NRF_SUCCESS;
+
+ if (mp_users[user_id].enabled == false)
+ {
+ ret_code = user_enable(user_id, true);
+ VERIFY_SUCCESS(ret_code);
+
+ mp_users[user_id].enabled = true;
+ return ret_code;
+ }
+ else
+ {
+ return ret_code;
+ }
+}
+
+uint32_t app_gpiote_user_disable(app_gpiote_user_id_t user_id)
+{
+ uint32_t ret_code = NRF_SUCCESS;
+
+ if (mp_users[user_id].enabled)
+ {
+ mp_users[user_id].enabled = false;
+ ret_code = user_enable(user_id, false);
+ }
+
+ return ret_code;
+}
+
+uint32_t app_gpiote_pins_state_get(app_gpiote_user_id_t user_id, uint32_t * p_pins)
+{
+ gpiote_user_t * p_user;
+ uint32_t ret_code = error_check(user_id);
+
+ if (ret_code == NRF_SUCCESS)
+ {
+ p_user = &mp_users[user_id];
+
+ nrf_gpio_ports_read(0, GPIO_COUNT, p_pins);
+ nrf_bitmask_masks_and(p_pins, p_user->pins_mask, p_pins, sizeof(p_user->pins_mask));
+ }
+ return ret_code;
+}
+#endif //NRF_MODULE_ENABLED(APP_GPIOTE)
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/gpiote/app_gpiote.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/gpiote/app_gpiote.h
new file mode 100644
index 0000000..2cac21e
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/gpiote/app_gpiote.h
@@ -0,0 +1,266 @@
+/**
+ * Copyright (c) 2012 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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
+ *
+ * @defgroup app_gpiote GPIOTE Handler
+ * @{
+ * @ingroup app_common
+ *
+ * @brief GPIOTE handler module.
+ *
+ * @details The GPIOTE handler allows several modules ("users") to share the GPIOTE interrupt,
+ * each user defining a set of pins able to generate events to the user.
+ * When a GPIOTE interrupt occurs, the GPIOTE interrupt handler will call the event handler
+ * of each user for which at least one of the pins generated an event.
+ *
+ * The GPIOTE users are responsible for configuring all their corresponding pins, except
+ * the SENSE field, which should be initialized to GPIO_PIN_CNF_SENSE_Disabled.
+ * The SENSE field will be updated by the GPIOTE module when it is enabled or disabled,
+ * and also while it is enabled.
+ *
+ * The module specifies on which pins events should be generated if the pin(s) goes
+ * from low->high or high->low or both directions.
+ *
+ * @note Even if the application is using the @ref app_scheduler, the GPIOTE event handlers will
+ * be called directly from the GPIOTE interrupt handler.
+ *
+ * @warning If multiple users registers for the same pins the behavior for those pins are undefined.
+ */
+
+#ifndef APP_GPIOTE_H__
+#define APP_GPIOTE_H__
+
+#include <stdint.h>
+#include <stdbool.h>
+#include "nrf.h"
+#include "nrf_drv_gpiote.h"
+#include "app_error.h"
+#include "app_util.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define GPIOTE_USER_NODE_SIZE ((4*sizeof(uint32_t)*GPIO_COUNT)+8) /**< Size of app_gpiote.gpiote_user_t (only for use inside APP_GPIOTE_BUF_SIZE()). */
+
+/**@brief Compute number of bytes required to hold the GPIOTE data structures.
+ *
+ * @param[in] MAX_USERS Maximum number of GPIOTE users.
+ *
+ * @retval Required buffer size (in bytes).
+ */
+#define APP_GPIOTE_BUF_SIZE(MAX_USERS) ((MAX_USERS) * GPIOTE_USER_NODE_SIZE)
+
+typedef uint8_t app_gpiote_user_id_t;
+
+/**@brief GPIOTE event handler type. */
+typedef void (*app_gpiote_event_handler_t)(uint32_t const * p_event_pins_low_to_high,
+ uint32_t const * p_event_pins_high_to_low);
+
+/**@brief GPIOTE input event handler type. */
+typedef void (*app_gpiote_input_event_handler_t)(void);
+
+
+/* Make the pin config descriptor packed */
+#pragma pack(push, 1)
+
+/**
+ * @brief Single pin configuration
+ *
+ * Structure used to describe single pin configuration
+ * when registering user.
+ * @sa app_gpiote_user_register_ex
+ */
+typedef struct
+{
+ /** Pin number to observe */
+ uint32_t pin_number : VBITS(NRF_GPIO_PIN_MAP(GPIO_COUNT - 1, 31));
+ /** Transition to observe */
+ nrf_gpiote_polarity_t sense : 2;
+} app_gpiote_user_pin_config_t;
+
+// Check if we can fitt all the nrf_gpiote_polarity_t values into 2 bits field
+STATIC_ASSERT(NRF_GPIOTE_POLARITY_LOTOHI <= 3);
+STATIC_ASSERT(NRF_GPIOTE_POLARITY_HITOLO <= 3);
+STATIC_ASSERT(NRF_GPIOTE_POLARITY_TOGGLE <= 3);
+
+#pragma pack(pop)
+
+/**@brief Macro for initializing the GPIOTE module.
+ *
+ * @details It will handle dimensioning and allocation of the memory buffer required by the module,
+ * making sure that the buffer is correctly aligned.
+ *
+ * @param[in] MAX_USERS Maximum number of GPIOTE users.
+ *
+ * @note Since this macro allocates a buffer, it must only be called once (it is OK to call it
+ * several times as long as it is from the same location, e.g. to do a reinitialization).
+ */
+/*lint -emacro(506, APP_GPIOTE_INIT) */ /* Suppress "Constant value Boolean */
+#define APP_GPIOTE_INIT(MAX_USERS) \
+ do \
+ { \
+ static uint32_t app_gpiote_buf[CEIL_DIV(APP_GPIOTE_BUF_SIZE(MAX_USERS), sizeof(uint32_t))];\
+ uint32_t ERR_CODE = app_gpiote_init((MAX_USERS), app_gpiote_buf); \
+ APP_ERROR_CHECK(ERR_CODE); \
+ } while (0)
+
+/**@brief Function for initializing the GPIOTE module.
+ *
+ * @note Normally initialization should be done using the APP_GPIOTE_INIT() macro, as that will
+ * allocate the buffer needed by the GPIOTE module (including aligning the buffer correctly).
+ *
+ * @param[in] max_users Maximum number of GPIOTE users.
+ * @param[in] p_buffer Pointer to memory buffer for internal use in the app_gpiote
+ * module. The size of the buffer can be computed using the
+ * APP_GPIOTE_BUF_SIZE() macro. The buffer must be aligned to
+ * a 4 byte boundary.
+ *
+ * @retval NRF_SUCCESS Successful initialization.
+ * @retval NRF_ERROR_INVALID_PARAM Invalid parameter (buffer not aligned to a 4 byte
+ * boundary).
+ */
+uint32_t app_gpiote_init(uint8_t max_users, void * p_buffer);
+
+/**@brief Function for registering a GPIOTE user.
+ *
+ * @param[out] p_user_id Id for the new GPIOTE user.
+ * @param[in] p_pins_low_to_high_mask Pointer to word array with mask defining which pins
+ * will generate events to this user when state is changed
+ * from low->high. Size of array depends on number of ports
+ * in the device.
+ * @param[in] p_pins_high_to_low_mask Pointer to word array with mask defining which pins
+ * will generate events to this user when state is changed
+ * from high->low. Size of array depends on number of ports
+ * in the device.
+ * @param[in] event_handler Pointer to function to be executed when an event occurs.
+ * Cannot be NULL.
+ *
+ * @retval NRF_SUCCESS Successful initialization.
+ * @retval NRF_ERROR_INALID_STATE If @ref app_gpiote_init has not been called on the GPIOTE
+ * module.
+ * @retval NRF_ERROR_NO_MEM Returned if the application tries to register more users
+ * than defined when the GPIOTE module was initialized in
+ * @ref app_gpiote_init.
+ *
+ * @note The function can also return error codes from internally
+ * called @ref nrf_drv_gpiote_in_init
+ *
+ * @sa app_gpiote_user_register_ex
+ */
+uint32_t app_gpiote_user_register(app_gpiote_user_id_t * p_user_id,
+ uint32_t const * p_pins_low_to_high_mask,
+ uint32_t const * p_pins_high_to_low_mask,
+ app_gpiote_event_handler_t event_handler);
+
+/**@brief Function for registering GPIOTE user using pins configuration list.
+ *
+ * Function for registering GPIOTE user that uses array of pins configuration.
+ * This function do not change pins configuration.
+ * Pins must be configured before calling this function.
+ *
+ * @param[out] p_user_id Id for the new GPIOTE user.
+ * @param[in] p_pins_config Pointer to the array of pins configuration for the user.
+ * @param[in] pin_count Number of pins to configure for the user.
+ * @param[in] event_handler Pointer to function to be executed when an event occurs.
+ * Cannot be NULL.
+ *
+ * @retval NRF_SUCCESS Successful user registration.
+ * @retval NRF_ERROR_INVALID_STATE If @ref app_gpiote_init has not been called before calling
+ * this function.
+ * @retval NRF_ERROR_NO_MEM Returned if the application tries to register more users
+ * than defined when the GPIOTE module was initialized in
+ * @ref app_gpiote_init.
+ *
+ * @note The function can also return error codes from internally
+ * called @ref nrf_drv_gpiote_in_init
+ *
+ * @sa app_gpiote_user_register
+ */
+uint32_t app_gpiote_user_register_ex(app_gpiote_user_id_t * p_user_id,
+ app_gpiote_user_pin_config_t const * p_pins_config,
+ size_t pin_count,
+ app_gpiote_event_handler_t event_handler);
+
+/**@brief Function for informing the GPIOTE module that the specified user wants to use the GPIOTE module.
+ *
+ * @param[in] user_id Id of user to enable.
+ *
+ * @retval NRF_SUCCESS On success.
+ * @retval NRF_ERROR_INVALID_PARAM Invalid user_id provided, No a valid user.
+ * @retval NRF_ERROR_INALID_STATE If @ref app_gpiote_init has not been called on the GPIOTE
+ * module.
+ */
+uint32_t app_gpiote_user_enable(app_gpiote_user_id_t user_id);
+
+/**@brief Function for informing the GPIOTE module that the specified user is done using the GPIOTE module.
+ *
+ * @param[in] user_id Id of user to enable.
+ *
+ * @retval NRF_SUCCESS On success.
+ * @retval NRF_ERROR_INVALID_PARAM Invalid user_id provided, No a valid user.
+ * @retval NRF_ERROR_INALID_STATE If @ref app_gpiote_init has not been called on the GPIOTE
+ * module.
+ */
+uint32_t app_gpiote_user_disable(app_gpiote_user_id_t user_id);
+
+/**@brief Function for getting the state of the pins which are registered for the specified user.
+ *
+ * @param[in] user_id Id of user to check.
+ * @param[out] p_pins Pointer to array of words with bit mask corresponding to the pins
+ * configured to generate events to the specified user. All bits
+ * corresponding to pins in the state 'high' will have value '1',
+ * all others will have value '0'. Size of array depends on number
+ * of ports in the device.
+ *
+ * @retval NRF_SUCCESS On success.
+ * @retval NRF_ERROR_INVALID_PARAM Invalid user_id provided, No a valid user.
+ * @retval NRF_ERROR_INALID_STATE If @ref app_gpiote_init has not been called on the GPIOTE
+ * module.
+ */
+uint32_t app_gpiote_pins_state_get(app_gpiote_user_id_t user_id, uint32_t * p_pins);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // APP_GPIOTE_H__
+
+/** @} */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/hardfault/hardfault.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/hardfault/hardfault.h
new file mode 100644
index 0000000..2333623
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/hardfault/hardfault.h
@@ -0,0 +1,96 @@
+/**
+ * Copyright (c) 2015 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#ifndef HARDFAULT_H__
+#define HARDFAULT_H__
+#include <stdint.h>
+#include <stddef.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+/**
+ * @defgroup hardfault_default HardFault exception
+ * @{
+ * @brief Default HardFault exception implementation.
+ * @ingroup app_common
+ */
+
+/**
+ * @brief Contents of the stack.
+ *
+ * This structure is used to re-create the stack layout after a HardFault exception was raised.
+ */
+typedef struct HardFault_stack
+{
+ uint32_t r0; ///< R0 register.
+ uint32_t r1; ///< R1 register.
+ uint32_t r2; ///< R2 register.
+ uint32_t r3; ///< R3 register.
+ uint32_t r12; ///< R12 register.
+ uint32_t lr; ///< Link register.
+ uint32_t pc; ///< Program counter.
+ uint32_t psr; ///< Program status register.
+} HardFault_stack_t;
+
+/**
+ * @brief Function for processing HardFault exceptions.
+ *
+ * An application that needs to process HardFault exceptions should provide an implementation of this function.
+ * It will be called from the HardFault handler.
+ * If no implementation is provided, the library uses a default one, which just restarts the MCU.
+ *
+ * @note If the DEBUG_NRF macro is defined, the software breakpoint is set just before the call
+ * to this function.
+ *
+ * @param p_stack Pointer to the stack bottom.
+ * This pointer might be NULL if the HardFault was called when the main stack was
+ * the active stack and a stack overrun is detected.
+ * In such a situation, the stack pointer is reinitialized to the default position,
+ * and the stack content is lost.
+ */
+void HardFault_process(HardFault_stack_t * p_stack);
+
+/** @} */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* HARDFAULT_H__ */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/hardfault/hardfault_genhf.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/hardfault/hardfault_genhf.h
new file mode 100644
index 0000000..37e3183
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/hardfault/hardfault_genhf.h
@@ -0,0 +1,165 @@
+/**
+ * Copyright (c) 2015 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#ifndef HARDFAULT_GENHF_H__
+#define HARDFAULT_GENHF_H__
+
+#include "compiler_abstraction.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+/**
+ * @defgroup hardfault_genhf Generating HardFaults for testing
+ * @{
+ * @brief Macros and functions used to generate a HardFault in a selected place.
+ * @ingroup hardfault_default
+ *
+ * This functionality is meant to be used while testing the @ref hardfault_default library functionality.
+ */
+
+/**
+ * @brief Function for generating an invalid function pointer HardFault.
+ *
+ * Function tries to jump into illegal address.
+ */
+static inline void hardfault_genhf_invalid_fp(void);
+
+/**
+ * @brief Function for generating an undefined instruction HardFault.
+ *
+ * This function places the value in the code area that is not the legal instruction.
+ */
+static inline void hardfault_genhf_undefined_instr(void);
+
+/**
+ * @brief Function for generating an unaligned LDM access HardFault.
+ *
+ * This function generates fault exception loading values from an unaligned address.
+ */
+static inline void hardfault_genhf_ldm_align(void);
+
+#if defined( __CC_ARM )
+
+static inline __ASM void hardfault_genhf_invalid_fp(void)
+{
+ MOVS r0, #0
+ BLX r0
+}
+
+static inline __ASM void hardfault_genhf_undefined_instr(void)
+{
+ DCI 0xf123
+ DCI 0x4567
+}
+
+static inline __ASM void hardfault_genhf_ldm_align(void)
+{
+ MOVS r0, #1
+ LDM r0!, {r1-r2}
+}
+
+#elif defined( __ICCARM__ )
+
+#pragma inline=forced
+static inline void hardfault_genhf_invalid_fp(void)
+{
+ __ASM volatile(
+ " movs r0, #0 \n"
+ " blx r0 \n"
+ );
+}
+
+#pragma inline=forced
+static inline void hardfault_genhf_undefined_instr(void)
+{
+ __ASM volatile(
+ "DATA \n"
+ " DC16 0xf123 \n"
+ " DC16 0x4567 \n"
+ );
+}
+
+#pragma inline=forced
+static inline void hardfault_genhf_ldm_align(void)
+{
+ __ASM volatile(
+ " movs r0, #1 \n"
+ " ldm r0!, {r1-r2} \n"
+ );
+}
+
+#elif defined( __GNUC__ )
+
+static inline void hardfault_genhf_invalid_fp(void)
+{
+ __ASM volatile(
+ " .syntax unified \n"
+ " movs r0, #0 \n"
+ " blx r0 \n"
+ );
+}
+
+static inline void hardfault_genhf_undefined_instr(void)
+{
+ __ASM volatile(
+ " .hword 0xf123 \n"
+ " .hword 0x4567 \n"
+ );
+}
+
+static inline void hardfault_genhf_ldm_align(void)
+{
+ __ASM volatile(
+ " .syntax unified \n"
+ " movs r0, #1 \n"
+ " ldm r0!, {r1-r2} \n"
+ );
+}
+
+#else
+#error "Unsupported compiler"
+#endif
+
+/** @} */
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* HARDFAULT_GENHF_H__ */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/hardfault/hardfault_implementation.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/hardfault/hardfault_implementation.c
new file mode 100644
index 0000000..02f3ed7
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/hardfault/hardfault_implementation.c
@@ -0,0 +1,158 @@
+/**
+ * Copyright (c) 2015 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#include "sdk_common.h"
+#if NRF_MODULE_ENABLED(HARDFAULT_HANDLER)
+#include "hardfault.h"
+#include "nrf.h"
+#include "compiler_abstraction.h"
+#include "app_util_platform.h"
+#ifdef SOFTDEVICE_PRESENT
+#include "nrf_soc.h"
+#endif
+#define NRF_LOG_MODULE_NAME hardfault
+#include "nrf_log.h"
+#include "nrf_log_ctrl.h"
+NRF_LOG_MODULE_REGISTER();
+
+#if defined(DEBUG_NRF)
+/**
+ * @brief Pointer to the last received stack pointer.
+ *
+ * This pointer is set in the debug version of the HardFault handler.
+ * It helps to debug HardFault reasons.
+ */
+volatile HardFault_stack_t * HardFault_p_stack;
+#endif
+
+/*lint -save -e14 */
+__WEAK void HardFault_process(HardFault_stack_t * p_stack)
+{
+ // Restart the system by default
+ NVIC_SystemReset();
+}
+/*lint -restore */
+
+void HardFault_c_handler(uint32_t * p_stack_address)
+{
+ NRF_LOG_FINAL_FLUSH();
+
+#if (__CORTEX_M == 0x04)
+
+#ifndef CFSR_MMARVALID
+ #define CFSR_MMARVALID (1 << (0 + 7))
+#endif
+
+#ifndef CFSR_BFARVALID
+ #define CFSR_BFARVALID (1 << (8 + 7))
+#endif
+
+ #if defined(DEBUG)
+
+ HardFault_stack_t * p_stack = (HardFault_stack_t *)p_stack_address;
+ static const char *cfsr_msgs[] = {
+ [0] = "The processor has attempted to execute an undefined instruction",
+ [1] = "The processor attempted a load or store at a location that does not permit the operation",
+ [2] = NULL,
+ [3] = "Unstack for an exception return has caused one or more access violations",
+ [4] = "Stacking for an exception entry has caused one or more access violations",
+ [5] = "A MemManage fault occurred during floating-point lazy state preservation",
+ [6] = NULL,
+ [7] = NULL,
+ [8] = "Instruction bus error",
+ [9] = "Data bus error (PC value stacked for the exception return points to the instruction that caused the fault)",
+ [10] = "Data bus error (return address in the stack frame is not related to the instruction that caused the error)",
+ [11] = "Unstack for an exception return has caused one or more BusFaults",
+ [12] = "Stacking for an exception entry has caused one or more BusFaults",
+ [13] = "A bus fault occurred during floating-point lazy state preservation",
+ [14] = NULL,
+ [15] = NULL,
+ [16] = "The processor has attempted to execute an undefined instruction",
+ [17] = "The processor has attempted to execute an instruction that makes illegal use of the EPSR",
+ [18] = "The processor has attempted an illegal load of EXC_RETURN to the PC, as a result of an invalid context, or an invalid EXC_RETURN value",
+ [19] = "The processor has attempted to access a coprocessor",
+ [20] = NULL,
+ [21] = NULL,
+ [22] = NULL,
+ [23] = NULL,
+ [24] = "The processor has made an unaligned memory access",
+ [25] = "The processor has executed an SDIV or UDIV instruction with a divisor of 0",
+ };
+
+ uint32_t cfsr = SCB->CFSR;
+
+ // Print information about error.
+ NRF_LOG_ERROR("HARD FAULT at 0x%08X", p_stack->pc);
+ NRF_LOG_ERROR(" R0: 0x%08X R1: 0x%08X R2: 0x%08X R3: 0x%08X",
+ p_stack->r0, p_stack->r1, p_stack->r2, p_stack->r3);
+ NRF_LOG_ERROR(" R12: 0x%08X LR: 0x%08X PSR: 0x%08X",
+ p_stack->r12, p_stack->lr, p_stack->psr);
+
+ if (SCB->HFSR & SCB_HFSR_VECTTBL_Msk)
+ {
+ NRF_LOG_ERROR("Cause: BusFault on a vector table read during exception processing.");
+ }
+
+ for (uint32_t i = 0; i < sizeof(cfsr_msgs) / sizeof(cfsr_msgs[0]); i++)
+ {
+ if (((cfsr & (1 << i)) != 0) && (cfsr_msgs[i] != NULL))
+ {
+ NRF_LOG_ERROR("Cause: %s.", (uint32_t)cfsr_msgs[i]);
+ }
+ }
+
+ if (cfsr & CFSR_MMARVALID)
+ {
+ NRF_LOG_ERROR("MemManage Fault Address: 0x%08X", SCB->MMFAR);
+ }
+
+ if (cfsr & CFSR_BFARVALID)
+ {
+ NRF_LOG_ERROR("Bus Fault Address: 0x%08X", SCB->BFAR);
+ }
+
+ NRF_BREAKPOINT_COND;
+
+ #endif // defined (DEBUG)
+
+#endif // __CORTEX_M == 0x04
+
+ HardFault_process((HardFault_stack_t *)p_stack_address);
+}
+#endif //NRF_MODULE_ENABLED(HARDFAULT_HANDLER)
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/hardfault/nrf51/handler/hardfault_handler_gcc.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/hardfault/nrf51/handler/hardfault_handler_gcc.c
new file mode 100644
index 0000000..85db240
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/hardfault/nrf51/handler/hardfault_handler_gcc.c
@@ -0,0 +1,87 @@
+/**
+ * Copyright (c) 2015 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#include "sdk_common.h"
+#if NRF_MODULE_ENABLED(HARDFAULT_HANDLER)
+#include <stdint.h>
+#include "compiler_abstraction.h"
+
+extern void HardFault_c_handler(uint32_t *);
+
+void HardFault_Handler(void) __attribute__(( naked ));
+
+void HardFault_Handler(void)
+{
+ __ASM volatile(
+ " .syntax unified \n"
+
+ " ldr r0, =0xFFFFFFFD \n"
+ " cmp r0, lr \n"
+ " bne HardFault_Handler_ChooseMSP \n"
+ /* Reading PSP into R0 */
+ " mrs r0, PSP \n"
+ " b HardFault_Handler_Continue \n"
+ "HardFault_Handler_ChooseMSP: \n"
+ /* Reading MSP into R0 */
+ " mrs r0, MSP \n"
+ /* -----------------------------------------------------------------
+ * If we have selected MSP check if we may use stack safetly.
+ * If not - reset the stack to the initial value. */
+ " ldr r1, =__StackTop \n"
+ " ldr r2, =__StackLimit \n"
+
+ /* MSP is in the range of the stack area */
+ " cmp r0, r1 \n"
+ " bhi HardFault_MoveSP \n"
+ " cmp r0, r2 \n"
+ " bhi HardFault_Handler_Continue \n"
+ /* ----------------------------------------------------------------- */
+ "HardFault_MoveSP: \n"
+ " mov SP, r1 \n"
+ " movs r0, #0 \n"
+
+ "HardFault_Handler_Continue: \n"
+ " ldr r3, =%0 \n"
+ " bx r3 \n"
+
+ " .ltorg \n"
+ : : "X"(HardFault_c_handler)
+ );
+}
+#endif //NRF_MODULE_ENABLED(HARDFAULT_HANDLER)
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/hardfault/nrf51/handler/hardfault_handler_iar.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/hardfault/nrf51/handler/hardfault_handler_iar.c
new file mode 100644
index 0000000..6c4e5a2
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/hardfault/nrf51/handler/hardfault_handler_iar.c
@@ -0,0 +1,98 @@
+/**
+ * Copyright (c) 2015 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#include "sdk_common.h"
+#if NRF_MODULE_ENABLED(HARDFAULT_HANDLER)
+#include <stdint.h>
+#include "compiler_abstraction.h"
+
+#pragma section = "CSTACK"
+extern void HardFault_c_handler( uint32_t * );
+
+__stackless void HardFault_Handler(void);
+
+__stackless void HardFault_Handler(void)
+{
+ __ASM volatile(
+ " ldr r0, 100f \n"
+ " cmp r0, lr \n"
+ " bne 1f \n"
+ /* Reading PSP into R0 */
+ " mrs r0, PSP \n"
+ " b 3f \n"
+ "1: \n"
+ /* Reading MSP into R0 */
+ " mrs r0, MSP \n"
+ /* -----------------------------------------------------------------
+ * If we have selected MSP check if we may use stack safetly.
+ * If not - reset the stack to the initial value. */
+ " ldr r1, 101f \n"
+ " ldr r2, 102f \n"
+
+ /* MSP is in the range of the stack area */
+ " cmp r0, r1 \n"
+ " bhi 2f \n"
+ " cmp r0, r2 \n"
+ " bhi 3f \n"
+ /* ----------------------------------------------------------------- */
+ "2: \n"
+ " mov SP, r1 \n"
+ " movs r0, #0 \n"
+
+ "3: \n"
+ " ldr r3, 103f \n"
+ " bx r3 \n"
+
+ "DATA \n"
+ "100: \n"
+ " DC32 0xFFFFFFFD \n"
+ "101: \n"
+ " DC32 %c0 \n"
+ "102: \n"
+ " DC32 %c1 \n"
+ "103: \n"
+ " DC32 %c2 \n"
+ : /* Outputs */
+ : /* Inputs */
+ "i"(__section_end("CSTACK")),
+ "i"(__section_begin("CSTACK")),
+ "i"(&HardFault_c_handler)
+ );
+}
+#endif //NRF_MODULE_ENABLED(HARDFAULT_HANDLER)
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/hardfault/nrf51/handler/hardfault_handler_keil.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/hardfault/nrf51/handler/hardfault_handler_keil.c
new file mode 100644
index 0000000..a1dcd3e
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/hardfault/nrf51/handler/hardfault_handler_keil.c
@@ -0,0 +1,88 @@
+/**
+ * Copyright (c) 2015 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#include "sdk_common.h"
+#if NRF_MODULE_ENABLED(HARDFAULT_HANDLER)
+#include <stdint.h>
+#include "compiler_abstraction.h"
+
+
+//lint -save -e27
+
+__ASM void HardFault_Handler(void)
+{
+ PRESERVE8
+ EXTERN HardFault_c_handler
+ EXTERN |STACK$$Base|
+ EXTERN |STACK$$Limit|
+
+ ldr r0, =0xFFFFFFFD
+ cmp r0, lr
+ bne HardFault_Handler_ChooseMSP
+ /* Reading PSP into R0 */
+ mrs r0, PSP
+ b HardFault_Handler_Continue
+HardFault_Handler_ChooseMSP
+ /* Reading MSP into R0 */
+ mrs r0, MSP
+ /* -----------------------------------------------------------------
+ * If we have selected MSP, check if we may use stack safely.
+ * If not - reset the stack to the initial value. */
+ ldr r1, =|STACK$$Limit|
+ ldr r2, =|STACK$$Base|
+
+ /* MSP is in the range of the stack area */
+ cmp r0, r1
+ bhi HardFault_MoveSP
+ cmp r0, r2
+ bhi HardFault_Handler_Continue
+ /* ----------------------------------------------------------------- */
+HardFault_MoveSP
+ mov SP, r1
+ movs r0, #0
+
+HardFault_Handler_Continue
+ ldr r3, =HardFault_c_handler
+ bx r3
+
+ ALIGN
+}
+
+//lint -restore
+#endif //NRF_MODULE_ENABLED(HARDFAULT_HANDLER)
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/hardfault/nrf52/handler/hardfault_handler_gcc.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/hardfault/nrf52/handler/hardfault_handler_gcc.c
new file mode 100644
index 0000000..13d5a1b
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/hardfault/nrf52/handler/hardfault_handler_gcc.c
@@ -0,0 +1,100 @@
+/**
+ * Copyright (c) 2015 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#include "sdk_common.h"
+#if NRF_MODULE_ENABLED(HARDFAULT_HANDLER)
+#include <stdint.h>
+#include "compiler_abstraction.h"
+
+extern void HardFault_c_handler(uint32_t *);
+
+void HardFault_Handler(void) __attribute__(( naked ));
+
+void HardFault_Handler(void)
+{
+ __ASM volatile(
+ " tst lr, #4 \n"
+
+ /* PSP is quite simple and does not require additional handler */
+ " itt ne \n"
+ " mrsne r0, psp \n"
+ /* Jump to the handler, do not store LR - returning from handler just exits exception */
+ " bne HardFault_Handler_Continue \n"
+
+ /* Processing MSP requires stack checking */
+ " mrs r0, msp \n"
+
+ " ldr r1, =__StackTop \n"
+ " ldr r2, =__StackLimit \n"
+
+ /* MSP is in the range of the stack area */
+ " cmp r0, r1 \n"
+ " bhi HardFault_MoveSP \n"
+ " cmp r0, r2 \n"
+ " bhi HardFault_Handler_Continue \n"
+
+ "HardFault_MoveSP: \n"
+ " mov sp, r1 \n"
+ " mov r0, #0 \n"
+
+ "HardFault_Handler_Continue: \n"
+#if HARDFAULT_HANDLER_GDB_PSP_BACKTRACE
+ " mov r3, sp \n" /* Remember old SP */
+ " mov sp, r0 \n" /* SP changed the pointer when hardfault was generated - we cannot just switch to PSP in exception */
+ " push {r3,lr} \n" /* Save old SP and LR on the task stack */
+#if !defined(__SES_ARM)
+ " .cfi_def_cfa_offset 8 \n"
+ " .cfi_offset 14, -4 \n"
+#endif
+ /* No information about saved SP above (no .cfi_offset 13, -8).
+ * In other case this would direct us back to using always MSP while backtracking */
+ " ldr r3, =%0 \n"
+ " blx r3 \n"
+ " pop {r3,lr} \n"
+ " mov sp, r3 \n"
+ " bx lr \n"
+#else // HARDFAULT_HANDLER_GDB_PSP_BACKTRACE
+ " ldr r3, =%0 \n"
+ " bx r3 \n"
+#endif
+ " .ltorg \n"
+ : : "X"(HardFault_c_handler)
+ );
+}
+#endif //NRF_MODULE_ENABLED(HARDFAULT_HANDLER)
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/hardfault/nrf52/handler/hardfault_handler_iar.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/hardfault/nrf52/handler/hardfault_handler_iar.c
new file mode 100644
index 0000000..03a40bf
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/hardfault/nrf52/handler/hardfault_handler_iar.c
@@ -0,0 +1,97 @@
+/**
+ * Copyright (c) 2015 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#include "sdk_common.h"
+#if NRF_MODULE_ENABLED(HARDFAULT_HANDLER)
+#include <stdint.h>
+#include "compiler_abstraction.h"
+
+#pragma section = "CSTACK"
+extern void HardFault_c_handler( uint32_t * );
+
+__stackless void HardFault_Handler(void);
+
+__stackless void HardFault_Handler(void)
+{
+ __ASM volatile(
+ " ldr.n r3, 103f \n"
+ " tst lr, #4 \n"
+
+ /* PSP is quite simple and does not require additional handler */
+ " itt ne \n"
+ " mrsne r0, psp \n"
+ /* Jump to the handler, do not store LR - returning from handler just exits exception */
+ " bxne r3 \n"
+
+ /* Processing MSP requires stack checking */
+ " mrs r0, msp \n"
+
+ " ldr.n r1, 101f \n"
+ " ldr.n r2, 102f \n"
+
+ /* MSP is in the range of the stack area */
+ " cmp r0, r1 \n"
+ " bhi.n 1f \n"
+ " cmp r0, r2 \n"
+ " bhi.n 2f \n"
+
+ "1: \n"
+ " mov sp, r1 \n"
+ " mov r0, #0 \n"
+
+ "2: \n"
+ " bx r3 \n"
+ /* Data alignment if required */
+ " nop \n"
+
+ "DATA \n"
+ "101: \n"
+ " DC32 %c0 \n"
+ "102: \n"
+ " DC32 %c1 \n"
+ "103: \n"
+ " DC32 %c2 \n"
+ : /* Outputs */
+ : /* Inputs */
+ "i"(__section_end("CSTACK")),
+ "i"(__section_begin("CSTACK")),
+ "i"(&HardFault_c_handler)
+ );
+}
+#endif //NRF_MODULE_ENABLED(HARDFAULT_HANDLER)
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/hardfault/nrf52/handler/hardfault_handler_keil.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/hardfault/nrf52/handler/hardfault_handler_keil.c
new file mode 100644
index 0000000..2752489
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/hardfault/nrf52/handler/hardfault_handler_keil.c
@@ -0,0 +1,87 @@
+/**
+ * Copyright (c) 2015 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#include "sdk_common.h"
+#if NRF_MODULE_ENABLED(HARDFAULT_HANDLER)
+#include <stdint.h>
+#include "compiler_abstraction.h"
+
+
+//lint -save -e27
+
+__ASM void HardFault_Handler(void)
+{
+ PRESERVE8
+ EXTERN HardFault_c_handler
+ EXTERN |STACK$$Base|
+ EXTERN |STACK$$Limit|
+
+ ldr r3, =HardFault_c_handler
+ tst lr, #4
+
+ /* PSP is quite simple and does not require additional handler */
+ itt ne
+ mrsne r0, psp
+ /* Jump to the handler, do not store LR - returning from handler just exits exception */
+ bxne r3
+
+ /* Processing MSP requires stack checking */
+ mrs r0, msp
+
+ ldr r1, =|STACK$$Limit|
+ ldr r2, =|STACK$$Base|
+
+ /* MSP is in the range of the stack area */
+ cmp r0, r1
+ bhi HardFault_MoveSP
+ cmp r0, r2
+ bhi HardFault_Handler_Continue
+
+HardFault_MoveSP
+ mov sp, r1
+ mov r0, #0
+
+HardFault_Handler_Continue
+ bx r3
+
+ ALIGN
+}
+
+//lint -restore
+#endif //NRF_MODULE_ENABLED(HARDFAULT_HANDLER)
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/hci/hci_mem_pool.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/hci/hci_mem_pool.c
new file mode 100644
index 0000000..ec97aa6
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/hci/hci_mem_pool.c
@@ -0,0 +1,264 @@
+/**
+ * Copyright (c) 2013 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#include "sdk_common.h"
+#if NRF_MODULE_ENABLED(HCI_MEM_POOL)
+#include "hci_mem_pool.h"
+#include <stdbool.h>
+#include <stdio.h>
+
+/**@brief RX buffer element instance structure.
+ */
+typedef struct
+{
+ uint8_t rx_buffer[HCI_RX_BUF_SIZE]; /**< RX buffer memory array. */
+ uint32_t length; /**< Length of the RX buffer memory array. */
+} rx_buffer_elem_t;
+
+/**@brief RX buffer queue element instance structure.
+ */
+typedef struct
+{
+ rx_buffer_elem_t * p_buffer; /**< Pointer to RX buffer element. */
+ uint32_t free_window_count; /**< Free space element count. */
+ uint32_t free_available_count; /**< Free area element count. */
+ uint32_t read_available_count; /**< Read area element count. */
+ uint32_t write_index; /**< Write position index. */
+ uint32_t read_index; /**< Read position index. */
+ uint32_t free_index; /**< Free position index. */
+} rx_buffer_queue_t;
+
+static bool m_is_tx_allocated; /**< Boolean value to determine if the TX buffer is allocated. */
+static rx_buffer_elem_t m_rx_buffer_elem_queue[HCI_RX_BUF_QUEUE_SIZE]; /**< RX buffer element instances. */
+static rx_buffer_queue_t m_rx_buffer_queue; /**< RX buffer queue element instance. */
+
+
+uint32_t hci_mem_pool_open(void)
+{
+ m_is_tx_allocated = false;
+ m_rx_buffer_queue.p_buffer = m_rx_buffer_elem_queue;
+ m_rx_buffer_queue.free_window_count = HCI_RX_BUF_QUEUE_SIZE;
+ m_rx_buffer_queue.free_available_count = 0;
+ m_rx_buffer_queue.read_available_count = 0;
+ m_rx_buffer_queue.write_index = 0;
+ m_rx_buffer_queue.read_index = 0;
+ m_rx_buffer_queue.free_index = 0;
+
+ return NRF_SUCCESS;
+}
+
+
+uint32_t hci_mem_pool_close(void)
+{
+ return NRF_SUCCESS;
+}
+
+
+uint32_t hci_mem_pool_tx_alloc(void ** pp_buffer)
+{
+ static uint8_t tx_buffer[HCI_TX_BUF_SIZE];
+
+ uint32_t err_code;
+
+ if (pp_buffer == NULL)
+ {
+ return NRF_ERROR_NULL;
+ }
+
+ if (!m_is_tx_allocated)
+ {
+ m_is_tx_allocated = true;
+ *pp_buffer = tx_buffer;
+ err_code = NRF_SUCCESS;
+ }
+ else
+ {
+ err_code = NRF_ERROR_NO_MEM;
+ }
+
+ return err_code;
+}
+
+
+uint32_t hci_mem_pool_tx_free(void)
+{
+ m_is_tx_allocated = false;
+
+ return NRF_SUCCESS;
+}
+
+
+uint32_t hci_mem_pool_rx_produce(uint32_t length, void ** pp_buffer)
+{
+ uint32_t err_code;
+
+ if (pp_buffer == NULL)
+ {
+ return NRF_ERROR_NULL;
+ }
+ *pp_buffer = NULL;
+
+ if (m_rx_buffer_queue.free_window_count != 0)
+ {
+ if (length <= HCI_RX_BUF_SIZE)
+ {
+ --(m_rx_buffer_queue.free_window_count);
+ ++(m_rx_buffer_queue.read_available_count);
+
+ *pp_buffer =
+ m_rx_buffer_queue.p_buffer[m_rx_buffer_queue.write_index].rx_buffer;
+
+ m_rx_buffer_queue.free_index |= (1u << m_rx_buffer_queue.write_index);
+
+ // @note: Adjust the write_index making use of the fact that the buffer size is of
+ // power of two and two's complement arithmetic. For details refer example to book
+ // "Making embedded systems: Elicia White".
+ m_rx_buffer_queue.write_index =
+ (m_rx_buffer_queue.write_index + 1u) & (HCI_RX_BUF_QUEUE_SIZE - 1u);
+
+ err_code = NRF_SUCCESS;
+ }
+ else
+ {
+ err_code = NRF_ERROR_DATA_SIZE;
+ }
+ }
+ else
+ {
+ err_code = NRF_ERROR_NO_MEM;
+ }
+
+ return err_code;
+}
+
+
+uint32_t hci_mem_pool_rx_consume(uint8_t * p_buffer)
+{
+ uint32_t err_code;
+ uint32_t consume_index;
+ uint32_t start_index;
+
+ if (m_rx_buffer_queue.free_available_count != 0)
+ {
+ // Find the buffer that has been freed -
+ // Start at read_index minus free_available_count and then increment until read index.
+ err_code = NRF_ERROR_INVALID_ADDR;
+ consume_index = (m_rx_buffer_queue.read_index - m_rx_buffer_queue.free_available_count) &
+ (HCI_RX_BUF_QUEUE_SIZE - 1u);
+ start_index = consume_index;
+
+ do
+ {
+ if (m_rx_buffer_queue.p_buffer[consume_index].rx_buffer == p_buffer)
+ {
+ m_rx_buffer_queue.free_index ^= (1u << consume_index);
+ err_code = NRF_SUCCESS;
+ break;
+ }
+ else
+ {
+ consume_index = (consume_index + 1u) & (HCI_RX_BUF_QUEUE_SIZE - 1u);
+ }
+ }
+ while (consume_index != m_rx_buffer_queue.read_index);
+
+ while (!(m_rx_buffer_queue.free_index & (1 << start_index)) &&
+ (m_rx_buffer_queue.free_available_count != 0))
+ {
+ --(m_rx_buffer_queue.free_available_count);
+ ++(m_rx_buffer_queue.free_window_count);
+ start_index = (consume_index + 1u) & (HCI_RX_BUF_QUEUE_SIZE - 1u);
+ }
+ }
+ else
+ {
+ err_code = NRF_ERROR_NO_MEM;
+ }
+
+ return err_code;
+}
+
+
+uint32_t hci_mem_pool_rx_data_size_set(uint32_t length)
+{
+ // @note: Adjust the write_index making use of the fact that the buffer size is of power
+ // of two and two's complement arithmetic. For details refer example to book
+ // "Making embedded systems: Elicia White".
+ const uint32_t index = (m_rx_buffer_queue.write_index - 1u) & (HCI_RX_BUF_QUEUE_SIZE - 1u);
+ m_rx_buffer_queue.p_buffer[index].length = length;
+
+ return NRF_SUCCESS;
+}
+
+
+uint32_t hci_mem_pool_rx_extract(uint8_t ** pp_buffer, uint32_t * p_length)
+{
+ uint32_t err_code;
+
+ if ((pp_buffer == NULL) || (p_length == NULL))
+ {
+ return NRF_ERROR_NULL;
+ }
+
+ if (m_rx_buffer_queue.read_available_count != 0)
+ {
+ --(m_rx_buffer_queue.read_available_count);
+ ++(m_rx_buffer_queue.free_available_count);
+
+ *pp_buffer =
+ m_rx_buffer_queue.p_buffer[m_rx_buffer_queue.read_index].rx_buffer;
+ *p_length =
+ m_rx_buffer_queue.p_buffer[m_rx_buffer_queue.read_index].length;
+
+ // @note: Adjust the write_index making use of the fact that the buffer size is of power
+ // of two and two's complement arithmetic. For details refer example to book
+ // "Making embedded systems: Elicia White".
+ m_rx_buffer_queue.read_index =
+ (m_rx_buffer_queue.read_index + 1u) & (HCI_RX_BUF_QUEUE_SIZE - 1u);
+
+ err_code = NRF_SUCCESS;
+ }
+ else
+ {
+ err_code = NRF_ERROR_NO_MEM;
+ }
+
+ return err_code;
+}
+#endif //NRF_MODULE_ENABLED(HCI_MEM_POOL)
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/hci/hci_mem_pool.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/hci/hci_mem_pool.h
new file mode 100644
index 0000000..9b1bf7e
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/hci/hci_mem_pool.h
@@ -0,0 +1,168 @@
+/**
+ * Copyright (c) 2013 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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
+ *
+ * @defgroup hci_mem_pool Memory pool
+ * @{
+ * @ingroup app_common
+ *
+ * @brief Memory pool implementation
+ *
+ * Memory pool implementation, based on circular buffer data structure, which supports asynchronous
+ * processing of RX data. The current default implementation supports 1 TX buffer and 4 RX buffers.
+ * The memory managed by the pool is allocated from static storage instead of heap. The internal
+ * design of the circular buffer implementing the RX memory layout is illustrated in the picture
+ * below.
+ *
+ * @image html memory_pool.svg "Circular buffer design"
+ *
+ * The expected call order for the RX APIs is as follows:
+ * - hci_mem_pool_rx_produce
+ * - hci_mem_pool_rx_data_size_set
+ * - hci_mem_pool_rx_extract
+ * - hci_mem_pool_rx_consume
+ *
+ * @warning If the above mentioned expected call order is violated the end result can be undefined.
+ *
+ * \par Component specific configuration options
+ *
+ * The following compile time configuration options are available to suit various implementations:
+ * - TX_BUF_SIZE TX buffer size in bytes.
+ * - RX_BUF_SIZE RX buffer size in bytes.
+ * - RX_BUF_QUEUE_SIZE RX buffer element size.
+ */
+
+#ifndef HCI_MEM_POOL_H__
+#define HCI_MEM_POOL_H__
+
+#include <stdint.h>
+#include "nrf_error.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**@brief Function for opening the module.
+ *
+ * @retval NRF_SUCCESS Operation success.
+ */
+uint32_t hci_mem_pool_open(void);
+
+/**@brief Function for closing the module.
+ *
+ * @retval NRF_SUCCESS Operation success.
+ */
+uint32_t hci_mem_pool_close(void);
+
+/**@brief Function for allocating requested amount of TX memory.
+ *
+ * @param[out] pp_buffer Pointer to the allocated memory.
+ *
+ * @retval NRF_SUCCESS Operation success. Memory was allocated.
+ * @retval NRF_ERROR_NO_MEM Operation failure. No memory available for allocation.
+ * @retval NRF_ERROR_NULL Operation failure. NULL pointer supplied.
+ */
+uint32_t hci_mem_pool_tx_alloc(void ** pp_buffer);
+
+/**@brief Function for freeing previously allocated TX memory.
+ *
+ * @note Memory management follows the FIFO principle meaning that free() order must match the
+ * alloc(...) order, which is the reason for omitting exact memory block identifier as an
+ * input parameter.
+ *
+ * @retval NRF_SUCCESS Operation success. Memory was freed.
+ */
+uint32_t hci_mem_pool_tx_free(void);
+
+/**@brief Function for producing a free RX memory block for usage.
+ *
+ * @note Upon produce request amount being 0, NRF_SUCCESS is returned.
+ *
+ * @param[in] length Amount, in bytes, of free memory to be produced.
+ * @param[out] pp_buffer Pointer to the allocated memory.
+ *
+ * @retval NRF_SUCCESS Operation success. Free RX memory block produced.
+ * @retval NRF_ERROR_NO_MEM Operation failure. No suitable memory available for allocation.
+ * @retval NRF_ERROR_DATA_SIZE Operation failure. Request size exceeds limit.
+ * @retval NRF_ERROR_NULL Operation failure. NULL pointer supplied.
+ */
+uint32_t hci_mem_pool_rx_produce(uint32_t length, void ** pp_buffer);
+
+/**@brief Function for setting the length of the last produced RX memory block.
+ *
+ * @warning If call to this API is omitted the end result is that the following call to
+ * mem_pool_rx_extract will return incorrect data in the p_length output parameter.
+ *
+ * @param[in] length Amount, in bytes, of actual memory used.
+ *
+ * @retval NRF_SUCCESS Operation success. Length was set.
+ */
+uint32_t hci_mem_pool_rx_data_size_set(uint32_t length);
+
+/**@brief Function for extracting a packet, which has been filled with read data, for further
+ * processing.
+ *
+ * @param[out] pp_buffer Pointer to the packet data.
+ * @param[out] p_length Length of packet data in bytes.
+ *
+ * @retval NRF_SUCCESS Operation success.
+ * @retval NRF_ERROR_NO_MEM Operation failure. No packet available to extract.
+ * @retval NRF_ERROR_NULL Operation failure. NULL pointer supplied.
+ */
+uint32_t hci_mem_pool_rx_extract(uint8_t ** pp_buffer, uint32_t * p_length);
+
+/**@brief Function for freeing previously extracted packet, which has been filled with read data.
+ *
+ * @param[in] p_buffer Pointer to consumed buffer.
+ *
+ * @retval NRF_SUCCESS Operation success.
+ * @retval NRF_ERROR_NO_MEM Operation failure. No packet available to free.
+ * @retval NRF_ERROR_INVALID_ADDR Operation failure. Not a valid pointer.
+ */
+uint32_t hci_mem_pool_rx_consume(uint8_t * p_buffer);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // HCI_MEM_POOL_H__
+
+/** @} */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/hci/hci_slip.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/hci/hci_slip.c
new file mode 100644
index 0000000..ab70b82
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/hci/hci_slip.c
@@ -0,0 +1,457 @@
+/**
+ * Copyright (c) 2013 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#include "sdk_common.h"
+#if NRF_MODULE_ENABLED(HCI_SLIP)
+#include "hci_slip.h"
+#include <stdlib.h>
+#include "app_uart.h"
+#include "nrf_error.h"
+
+#define APP_SLIP_END 0xC0 /**< SLIP code for identifying the beginning and end of a packet frame.. */
+#define APP_SLIP_ESC 0xDB /**< SLIP escape code. This code is used to specify that the following character is specially encoded. */
+#define APP_SLIP_ESC_END 0xDC /**< SLIP special code. When this code follows 0xDB, this character is interpreted as payload data 0xC0.. */
+#define APP_SLIP_ESC_ESC 0xDD /**< SLIP special code. When this code follows 0xDB, this character is interpreted as payload data 0xDB. */
+
+/** @brief States for the SLIP state machine. */
+typedef enum
+{
+ SLIP_OFF, /**< SLIP state OFF. */
+ SLIP_READY, /**< SLIP state ON. */
+ SLIP_TRANSMITTING, /**< SLIP state is transmitting indicating write() has been called but data transmission has not completed. */
+} slip_states_t;
+
+static slip_states_t m_current_state = SLIP_OFF; /** Current state for the SLIP TX state machine. */
+
+static hci_slip_event_handler_t m_slip_event_handler; /** Event callback function for handling of SLIP events, @ref hci_slip_evt_type_t . */
+
+static const uint8_t * mp_tx_buffer; /** Pointer to the current TX buffer that is in transmission. */
+static uint32_t m_tx_buffer_length; /** Length of the current TX buffer that is in transmission. */
+static volatile uint32_t m_tx_buffer_index; /** Current index for next byte to transmit in the mp_tx_buffer. */
+
+static uint8_t * mp_rx_buffer; /** Pointer to the current RX buffer where the next SLIP decoded packet will be stored. */
+static uint32_t m_rx_buffer_length; /** Length of the current RX buffer. */
+static uint32_t m_rx_received_count; /** Number of SLIP decoded bytes received and stored in mp_rx_buffer. */
+
+
+/**@brief Function for parsing bytes received on the UART until a SLIP escape byte is received.
+ *
+ * @param[in] byte Byte received in UART module.
+ */
+static void handle_rx_byte_default(uint8_t byte);
+
+/**@brief Function for parsing bytes received on the UART until SLIP end byte is received.
+ *
+ * @param[in] byte Byte received in UART module.
+ */
+static void handle_rx_byte_wait_start(uint8_t byte);
+
+/**@brief Function for decoding a received SLIP escape byte.
+ * It will ensure correct decoding of the byte following the SLIP escape byte.
+ *
+ * @param[in] byte Byte received in UART module.
+ */
+static void handle_rx_byte_esc(uint8_t byte);
+
+/**@brief Function pointer for parsing and decoding SLIP bytes from the UART module.
+ *
+ * @param[in] byte Byte received in UART module.
+ */
+static void (*handle_rx_byte) (uint8_t byte) = handle_rx_byte_wait_start;
+
+/**@brief Function pointer for sending a byte through the UART module.
+ */
+static uint32_t send_tx_byte_default(void);
+
+/**@brief Function for transferring a SLIP escape byte (0xDB) when special bytes are transferred,
+ * that is 0xC0 and 0xDB.
+ */
+static uint32_t send_tx_byte_esc(void);
+
+/**@brief Function for transferring a byte when it collides with SLIP commands and follows the SLIP
+ * escape byte, that is 0xC0 => 0xDC and 0xDB => 0xDD.
+ */
+static uint32_t send_tx_byte_encoded(void);
+
+/**@brief Function for transferring the SLIP end frame byte, 0xC0.
+ */
+static uint32_t send_tx_byte_end(void);
+
+/**@brief Function pointer for sending a byte through the UART module.
+ */
+uint32_t (*send_tx_byte) (void) = send_tx_byte_default;
+
+
+static uint32_t send_tx_byte_end(void)
+{
+ uint32_t err_code = app_uart_put(APP_SLIP_END);
+
+ if ((err_code == NRF_SUCCESS) && (m_tx_buffer_index == 0))
+ {
+ // Packet transmission started.
+ send_tx_byte = send_tx_byte_default;
+ }
+
+ return err_code;
+}
+
+
+static uint32_t send_tx_byte_default(void)
+{
+ uint32_t err_code = app_uart_put(mp_tx_buffer[m_tx_buffer_index]);
+
+ if (err_code == NRF_SUCCESS)
+ {
+ m_tx_buffer_index++;
+ }
+
+ return err_code;
+}
+
+
+static uint32_t send_tx_byte_encoded(void)
+{
+ uint32_t err_code;
+
+ switch (mp_tx_buffer[m_tx_buffer_index])
+ {
+ case APP_SLIP_END:
+ err_code = app_uart_put(APP_SLIP_ESC_END);
+ break;
+
+ case APP_SLIP_ESC:
+ err_code = app_uart_put(APP_SLIP_ESC_ESC);
+ break;
+
+ default:
+ err_code = NRF_ERROR_NO_MEM;
+ break;
+ }
+
+ if (err_code == NRF_SUCCESS)
+ {
+ m_tx_buffer_index++;
+ send_tx_byte = send_tx_byte_default;
+ }
+
+ return err_code;
+}
+
+
+static uint32_t send_tx_byte_esc(void)
+{
+ uint32_t err_code = app_uart_put(APP_SLIP_ESC);
+
+ if (err_code == NRF_SUCCESS)
+ {
+ send_tx_byte = send_tx_byte_encoded;
+ }
+
+ return err_code;
+}
+
+
+/** @brief Function for transferring the content of the mp_tx_buffer to the UART.
+ * It continues to transfer bytes until the UART buffer is full or the complete buffer is
+ * transferred.
+ */
+static void transmit_buffer(void)
+{
+ uint32_t err_code = NRF_SUCCESS;
+
+ while (m_tx_buffer_index < m_tx_buffer_length)
+ {
+ if ((mp_tx_buffer[m_tx_buffer_index] == APP_SLIP_END ||
+ mp_tx_buffer[m_tx_buffer_index] == APP_SLIP_ESC) &&
+ send_tx_byte == send_tx_byte_default)
+ {
+ send_tx_byte = send_tx_byte_esc;
+ }
+
+ err_code = send_tx_byte();
+
+ if (err_code == NRF_ERROR_NO_MEM || err_code == NRF_ERROR_BUSY)
+ {
+ // No memory left in UART TX buffer. Abort and wait for APP_UART_TX_EMPTY to continue.
+ return;
+ }
+ }
+
+ send_tx_byte = send_tx_byte_end;
+
+ err_code = send_tx_byte();
+
+ if (err_code == NRF_SUCCESS)
+ {
+ // Packet transmission ended. Notify higher level.
+ m_current_state = SLIP_READY;
+
+ if (m_slip_event_handler != NULL)
+ {
+ hci_slip_evt_t event = {HCI_SLIP_TX_DONE, mp_tx_buffer, m_tx_buffer_index};
+
+ m_slip_event_handler(event);
+ }
+ }
+}
+
+
+/** @brief Function for handling the reception of a SLIP end byte.
+ * If the number of bytes received is greater than zero it will call m_slip_event_handler
+ * with number of bytes received and invalidate the mp_rx_buffer to protect against data
+ * corruption.
+ * No new bytes can be received until a new RX buffer is supplied.
+ */
+static void handle_slip_end(void)
+{
+ if (m_rx_received_count > 0)
+ {
+ // Full packet received, push it up.
+ if (m_slip_event_handler != NULL)
+ {
+ hci_slip_evt_t event = {HCI_SLIP_RX_RDY, mp_rx_buffer, m_rx_received_count};
+
+ m_rx_received_count = 0;
+ mp_rx_buffer = NULL;
+
+ m_slip_event_handler(event);
+ }
+ }
+}
+
+
+static void handle_rx_byte_esc(uint8_t byte)
+{
+ switch (byte)
+ {
+ case APP_SLIP_END:
+ handle_slip_end();
+ break;
+
+ case APP_SLIP_ESC_END:
+ mp_rx_buffer[m_rx_received_count++] = APP_SLIP_END;
+ break;
+
+ case APP_SLIP_ESC_ESC:
+ mp_rx_buffer[m_rx_received_count++] = APP_SLIP_ESC;
+ break;
+
+ default:
+ mp_rx_buffer[m_rx_received_count++] = byte;
+ break;
+ }
+
+ handle_rx_byte = handle_rx_byte_default;
+}
+
+
+static void handle_rx_byte_default(uint8_t byte)
+{
+ switch (byte)
+ {
+ case APP_SLIP_END:
+ handle_slip_end();
+ break;
+
+ case APP_SLIP_ESC:
+ handle_rx_byte = handle_rx_byte_esc;
+ break;
+
+ default:
+ mp_rx_buffer[m_rx_received_count++] = byte;
+ break;
+ }
+}
+
+
+static void handle_rx_byte_wait_start(uint8_t byte)
+{
+ if (byte == APP_SLIP_END)
+ {
+ handle_rx_byte = handle_rx_byte_default;
+ }
+}
+
+
+/** @brief Function for checking the current index and length of the RX buffer to determine if the
+ * buffer is full. If an event handler has been registered, the callback function will
+ * be executed..
+ *
+ * @retval true If RX buffer has overflowed.
+ * @retval false otherwise.
+ *
+ */
+static bool rx_buffer_overflowed(void)
+{
+ if (mp_rx_buffer == NULL || m_rx_received_count >= m_rx_buffer_length)
+ {
+ if (m_slip_event_handler != NULL)
+ {
+ hci_slip_evt_t event = {HCI_SLIP_RX_OVERFLOW, mp_rx_buffer, m_rx_received_count};
+ m_slip_event_handler(event);
+ }
+
+ return true;
+ }
+
+ return false;
+}
+
+
+/** @brief Function for handling the UART module event. It parses events from the UART when
+ * bytes are received/transmitted.
+ *
+ * @param[in] uart_event Event received from app_uart module.
+ */
+static void slip_uart_eventhandler(app_uart_evt_t * uart_event)
+{
+ if (uart_event->evt_type == APP_UART_TX_EMPTY && m_current_state == SLIP_TRANSMITTING)
+ {
+ transmit_buffer();
+ }
+
+ if ((uart_event->evt_type == APP_UART_DATA) && (!rx_buffer_overflowed()))
+ {
+ handle_rx_byte(uart_event->data.value);
+ }
+}
+
+
+/** @brief Function for enabling the UART module when the SLIP layer is opened.
+ */
+static uint32_t slip_uart_open(void)
+{
+ uint32_t err_code;
+
+ app_uart_comm_params_t comm_params =
+ {
+ HCI_UART_RX_PIN,
+ HCI_UART_TX_PIN,
+ HCI_UART_RTS_PIN,
+ HCI_UART_CTS_PIN,
+ (app_uart_flow_control_t)HCI_UART_FLOW_CONTROL,
+ false,
+ HCI_UART_BAUDRATE
+ };
+
+ err_code = app_uart_init(&comm_params,
+ NULL,
+ slip_uart_eventhandler,
+ APP_IRQ_PRIORITY_LOWEST);
+
+ if (err_code == NRF_SUCCESS)
+ {
+ m_current_state = SLIP_READY;
+ }
+
+ return err_code;
+}
+
+
+uint32_t hci_slip_evt_handler_register(hci_slip_event_handler_t event_handler)
+{
+ m_slip_event_handler = event_handler;
+
+ return NRF_SUCCESS;
+}
+
+
+uint32_t hci_slip_open()
+{
+ switch (m_current_state)
+ {
+ case SLIP_OFF:
+ return slip_uart_open();
+
+ default:
+ // Do nothing.
+ break;
+ }
+
+ return NRF_SUCCESS;
+}
+
+
+uint32_t hci_slip_close()
+{
+ m_current_state = SLIP_OFF;
+ uint32_t err_code = app_uart_close();
+
+ return err_code;
+}
+
+
+uint32_t hci_slip_write(const uint8_t * p_buffer, uint32_t length)
+{
+ if (p_buffer == NULL)
+ {
+ return NRF_ERROR_INVALID_ADDR;
+ }
+
+ switch (m_current_state)
+ {
+ case SLIP_READY:
+ m_tx_buffer_index = 0;
+ m_tx_buffer_length = length;
+ mp_tx_buffer = p_buffer;
+ m_current_state = SLIP_TRANSMITTING;
+ send_tx_byte = send_tx_byte_end;
+
+ transmit_buffer();
+ return NRF_SUCCESS;
+
+ case SLIP_TRANSMITTING:
+ return NRF_ERROR_NO_MEM;
+
+ case SLIP_OFF:
+ default:
+ return NRF_ERROR_INVALID_STATE;
+ }
+}
+
+
+uint32_t hci_slip_rx_buffer_register(uint8_t * p_buffer, uint32_t length)
+{
+ mp_rx_buffer = p_buffer;
+ m_rx_buffer_length = length;
+ m_rx_received_count = 0;
+ handle_rx_byte = handle_rx_byte_wait_start;
+ return NRF_SUCCESS;
+}
+#endif //NRF_MODULE_ENABLED(HCI_SLIP)
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/hci/hci_slip.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/hci/hci_slip.h
new file mode 100644
index 0000000..7741319
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/hci/hci_slip.h
@@ -0,0 +1,165 @@
+/**
+ * Copyright (c) 2013 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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
+ *
+ * @defgroup hci_slip SLIP module
+ * @{
+ * @ingroup app_common
+ *
+ * @brief SLIP layer for supporting packet framing in HCI transport.
+ *
+ * @details This module implements SLIP packet framing as described in the Bluetooth Core
+ * Specification 4.0, Volume 4, Part D, Chapter 3 SLIP Layer.
+ *
+ * SLIP framing ensures that all packets sent on the UART are framed as:
+ * <0xC0> SLIP packet 1 <0xC0> <0xC0> SLIP packet 2 <0xC0>.
+ *
+ * The SLIP layer uses events to notify the upper layer when data transmission is complete
+ * and when a SLIP packet is received.
+ */
+
+#ifndef HCI_SLIP_H__
+#define HCI_SLIP_H__
+
+#include <stdint.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**@brief Event types from the SLIP Layer. */
+typedef enum
+{
+ HCI_SLIP_RX_RDY, /**< An event indicating that an RX packet is ready to be read. */
+ HCI_SLIP_TX_DONE, /**< An event indicating write completion of the TX packet provided in the function call \ref hci_slip_write . */
+ HCI_SLIP_RX_OVERFLOW, /**< An event indicating that RX data has been discarded due to lack of free RX memory. */
+ HCI_SLIP_ERROR, /**< An event indicating that an unrecoverable error has occurred. */
+ HCI_SLIP_EVT_TYPE_MAX /**< Enumeration upper bound. */
+} hci_slip_evt_type_t;
+
+/**@brief Structure containing an event from the SLIP layer.
+ */
+typedef struct
+{
+ hci_slip_evt_type_t evt_type; /**< Type of event. */
+ const uint8_t * packet; /**< This field contains a pointer to the packet for which the event relates, i.e. SLIP_TX_DONE: the packet transmitted, SLIP_RX_RDY: the packet received, SLIP_RX_OVERFLOW: The packet which overflow/or NULL if no receive buffer is available. */
+ uint32_t packet_length; /**< Packet length, i.e. SLIP_TX_DONE: Bytes transmitted, SLIP_RX_RDY: Bytes received, SLIP_RX_OVERFLOW: index at which the packet overflowed. */
+} hci_slip_evt_t;
+
+/**@brief Function for the SLIP layer event callback.
+ */
+typedef void (*hci_slip_event_handler_t)(hci_slip_evt_t event);
+
+/**@brief Function for registering the event handler provided as parameter and this event handler
+ * will be used by SLIP layer to send events described in \ref hci_slip_evt_type_t.
+ *
+ * @note Multiple registration requests will overwrite any existing registration.
+ *
+ * @param[in] event_handler This function is called by the SLIP layer upon an event.
+ *
+ * @retval NRF_SUCCESS Operation success.
+ */
+uint32_t hci_slip_evt_handler_register(hci_slip_event_handler_t event_handler);
+
+/**@brief Function for opening the SLIP layer. This function must be called before
+ * \ref hci_slip_write and before any data can be received.
+ *
+ * @note Can be called multiple times.
+ *
+ * @retval NRF_SUCCESS Operation success.
+ *
+ * The SLIP layer module will propagate errors from underlying sub-modules.
+ * This implementation is using UART module as a physical transmission layer, and hci_slip_open
+ * executes \ref app_uart_init . For an extended error list, please refer to \ref app_uart_init .
+ */
+uint32_t hci_slip_open(void);
+
+/**@brief Function for closing the SLIP layer. After this function is called no data can be
+ * transmitted or received in this layer.
+ *
+ * @note This function can be called multiple times and also for an unopened channel.
+ *
+ * @retval NRF_SUCCESS Operation success.
+ */
+uint32_t hci_slip_close(void);
+
+/**@brief Function for writing a packet with SLIP encoding. Packet transmission is confirmed when
+ * the HCI_SLIP_TX_DONE event is received by the function caller.
+ *
+ * @param[in] p_buffer Pointer to the packet to transmit.
+ * @param[in] length Packet length, in bytes.
+ *
+ * @retval NRF_SUCCESS Operation success. Packet was encoded and added to the
+ * transmission queue and an event will be sent upon transmission
+ * completion.
+ * @retval NRF_ERROR_NO_MEM Operation failure. Transmission queue is full and packet was not
+ * added to the transmission queue. Application shall wait for
+ * the \ref HCI_SLIP_TX_DONE event. After HCI_SLIP_TX_DONE this
+ * function can be executed for transmission of next packet.
+ * @retval NRF_ERROR_INVALID_ADDR If a NULL pointer is provided.
+ * @retval NRF_ERROR_INVALID_STATE Operation failure. Module is not open.
+ */
+uint32_t hci_slip_write(const uint8_t * p_buffer, uint32_t length);
+
+/**@brief Function for registering a receive buffer. The receive buffer will be used for storage of
+ * received and SLIP decoded data.
+ * No data can be received by the SLIP layer until a receive buffer has been registered.
+ *
+ * @note The lifetime of the buffer must be valid during complete reception of data. A static
+ * buffer is recommended.
+ *
+ * @warning Multiple registration requests will overwrite any existing registration.
+ *
+ * @param[in] p_buffer Pointer to receive buffer. The received and SLIP decoded packet
+ * will be placed in this buffer.
+ * @param[in] length Buffer length, in bytes.
+ *
+ * @retval NRF_SUCCESS Operation success.
+ */
+uint32_t hci_slip_rx_buffer_register(uint8_t * p_buffer, uint32_t length);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // HCI_SLIP_H__
+
+/** @} */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/hci/hci_transport.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/hci/hci_transport.c
new file mode 100644
index 0000000..f4d6c02
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/hci/hci_transport.c
@@ -0,0 +1,808 @@
+/**
+ * Copyright (c) 2013 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#include "sdk_common.h"
+#if NRF_MODULE_ENABLED(HCI_TRANSPORT)
+#include "hci_transport.h"
+#include "hci_slip.h"
+#include "crc16.h"
+#include "hci_mem_pool.h"
+#include "app_timer.h"
+#include "app_error.h"
+#include <stdio.h>
+
+#define PKT_HDR_SIZE 4u /**< Packet header size in number of bytes. */
+#define PKT_CRC_SIZE 2u /**< Packet CRC size in number of bytes. */
+#define PKT_TYPE_VENDOR_SPECIFIC 14u /**< Packet type vendor specific. */
+#define PKT_TYPE_ACK 0 /**< Packet type acknowledgement. */
+#define DATA_INTEGRITY_MASK (1u << 6u) /**< Mask for data integrity bit in the packet header. */
+#define RELIABLE_PKT_MASK (1u << 7u) /**< Mask for reliable packet bit in the packet header. */
+#define INITIAL_ACK_NUMBER_EXPECTED 1u /**< Initial acknowledge number expected. */
+#define INITIAL_ACK_NUMBER_TX INITIAL_ACK_NUMBER_EXPECTED /**< Initial acknowledge number transmitted. */
+#define INVALID_PKT_TYPE 0xFFFFFFFFu /**< Internal invalid packet type value. */
+#define HCI_UART_REG_VALUE_TO_BAUDRATE(BAUDRATE) ((BAUDRATE)/268) /**< Estimated relation between UART baudrate register value and actual baudrate */
+#define MAX_TRANSMISSION_TIME \
+ (ROUNDED_DIV((HCI_MAX_PACKET_SIZE_IN_BITS * 1000u), \
+ HCI_UART_REG_VALUE_TO_BAUDRATE(HCI_UART_BAUDRATE))) /**< Max transmission time of a single application packet over UART in units of mseconds. */
+#define RETRANSMISSION_TIMEOUT_IN_MS (3u * MAX_TRANSMISSION_TIME) /**< Retransmission timeout for application packet in units of mseconds. */
+#define RETRANSMISSION_TIMEOUT_IN_TICKS APP_TIMER_TICKS(RETRANSMISSION_TIMEOUT_IN_MS) /**< Retransmission timeout for application packet in units of timer ticks. */
+#define MAX_RETRY_COUNT 5u /**< Max retransmission retry count for application packets. */
+#define ACK_BUF_SIZE 5u /**< Length of module internal RX buffer which is big enough to hold an acknowledgement packet. */
+
+/**@brief States of the TX state machine. */
+typedef enum
+{
+ TX_STATE_IDLE, /**< State for: no application transmission packet processing in progress. */
+ TX_STATE_PENDING, /**< State for: TX in progress in slip layer and TX-done event is waited for to signal the end of transmission. */
+ TX_STATE_ACTIVE /**< State for: application packet has been delivered to slip for transmission and peer transport entity acknowledgement packet is waited for. */
+} tx_state_t;
+
+/**@brief TX state machine events. */
+typedef enum
+{
+ TX_EVENT_STATE_ENTRY, /**< Event for: state entry use case. */
+ TX_EVENT_SLIP_TX_DONE, /**< Event for: HCI_SLIP_TX_DONE event use case. */
+ TX_EVENT_TIMEOUT, /**< Event for: retransmission timeout use case. */
+ TX_EVENT_VALID_RX_ACK /**< Event for: valid acknowledgement received for TX packet use case. */
+} tx_event_t;
+
+static void tx_sm_state_change(tx_state_t new_state);
+
+static tx_state_t m_tx_state; /**< Current TX state. */
+static hci_transport_tx_done_handler_t m_transport_tx_done_handle; /**< TX done event callback function. */
+static hci_transport_event_handler_t m_transport_event_handle; /**< Event handler callback function. */
+static uint8_t * mp_slip_used_rx_buffer; /**< Reference to RX buffer used by the slip layer. */
+static uint32_t m_packet_expected_seq_number; /**< Sequence number counter of the packet expected to be received . */
+static uint32_t m_packet_transmit_seq_number; /**< Sequence number counter of the transmitted packet for which acknowledgement packet is waited for. */
+static uint8_t * mp_tx_buffer; /**< Pointer to TX application buffer to be transmitted. */
+static uint32_t m_tx_buffer_length; /**< Length of application TX packet data to be transmitted in bytes. */
+static bool m_is_slip_decode_ready; /**< Boolean to determine has slip decode been completed or not. */
+APP_TIMER_DEF(m_app_timer_id); /**< Application timer id. */
+static uint32_t m_tx_retry_counter; /**< Application packet retransmission counter. */
+static hci_transport_tx_done_result_t m_tx_done_result_code; /**< TX done event callback function result code. */
+static uint8_t m_rx_ack_buffer[ACK_BUF_SIZE];/**< RX buffer big enough to hold an acknowledgement packet and which is taken in use upon receiving HCI_SLIP_RX_OVERFLOW event. */
+
+
+/**@brief Function for validating a received packet.
+ *
+ * @param[in] p_buffer Pointer to the packet data.
+ * @param[in] length Length of packet data in bytes.
+ *
+ * @return true if received packet is valid, false in other case.
+ */
+static bool is_rx_pkt_valid(const uint8_t * p_buffer, uint32_t length)
+{
+ // Executed packet filtering algorithm order:
+ // - verify packet overall length
+ // - verify data integrity bit set
+ // - verify reliable packet bit set
+ // - verify supported packet type
+ // - verify header checksum
+ // - verify payload length field
+ // - verify CRC
+ if (length <= PKT_HDR_SIZE)
+ {
+ return false;
+ }
+
+ if (!(p_buffer[0] & DATA_INTEGRITY_MASK))
+ {
+ return false;
+ }
+
+ if (!(p_buffer[0] & RELIABLE_PKT_MASK))
+ {
+ return false;
+ }
+
+ if ((p_buffer[1] & 0x0Fu) != PKT_TYPE_VENDOR_SPECIFIC)
+ {
+ return false;
+ }
+
+ const uint32_t expected_checksum =
+ ((p_buffer[0] + p_buffer[1] + p_buffer[2] + p_buffer[3])) & 0xFFu;
+ if (expected_checksum != 0)
+ {
+ return false;
+ }
+
+ const uint16_t crc_calculated = crc16_compute(p_buffer, (length - PKT_CRC_SIZE), NULL);
+ const uint16_t crc_received = uint16_decode(&p_buffer[length - PKT_CRC_SIZE]);
+ if (crc_calculated != crc_received)
+ {
+ return false;
+ }
+
+ return true;
+}
+
+
+/**@brief Function for getting the sequence number of the next reliable packet expected.
+ *
+ * @return sequence number of the next reliable packet expected.
+ */
+static __INLINE uint8_t packet_number_expected_get(void)
+{
+ return (uint8_t) m_packet_expected_seq_number;
+}
+
+
+/**@brief Function for calculating a packet header checksum.
+ *
+ * @param[in] p_hdr Pointer to the packet header.
+ *
+ * @return Calculated checksum.
+ */
+static uint8_t header_checksum_calculate(const uint8_t * p_hdr)
+{
+ // @note: no pointer validation check needed as already checked by calling function.
+ uint32_t checksum;
+
+ checksum = p_hdr[0];
+ checksum += p_hdr[1];
+ checksum += p_hdr[2];
+ checksum &= 0xFFu;
+ checksum = (~checksum + 1u);
+
+ return (uint8_t)checksum;
+}
+
+
+/**@brief Function for writing an acknowledgment packet for transmission.
+ */
+static void ack_transmit(void)
+{
+ static uint8_t ack_packet[PKT_HDR_SIZE];
+
+ // TX ACK packet format:
+ // - Unreliable Packet type
+ // - Payload Length set to 0
+ // - Sequence Number set to 0
+ // - Header checksum calculated
+ // - Acknowledge Number set correctly
+ ack_packet[0] = (packet_number_expected_get() << 3u);
+ ack_packet[1] = 0;
+ ack_packet[2] = 0;
+ ack_packet[3] = header_checksum_calculate(ack_packet);
+
+ // @note: no return value check needed for hci_slip_write(...) call as acknowledgement packets
+ // are considered to be from system design point of view unreliable packets.Use case where
+ // underlying slip layer does not accept a packet for transmission is managed either by:
+ // - acknowledged by possible future application packet as acknowledgement number header field
+ // is included
+ // - protocol peer entity will retransmit the packet
+ UNUSED_VARIABLE(hci_slip_write(ack_packet, sizeof(ack_packet)));
+}
+
+
+/**@brief Function for validating a received packet.
+ *
+ * @param[in] p_buffer Pointer to the packet data.
+ *
+ * @return sequence number field of the packet header with unrelated data masked out.
+ */
+static __INLINE uint8_t packet_seq_nmbr_extract(const uint8_t * p_buffer)
+{
+ return (p_buffer[0] & 0x07u);
+}
+
+
+/**@brief Function for incrementing the sequence number counter for next reliable packet expected.
+ */
+static __INLINE void packet_number_expected_inc(void)
+{
+ ++m_packet_expected_seq_number;
+ m_packet_expected_seq_number &= 0x07u;
+}
+
+
+/**@brief Function for decoding a packet type field.
+ *
+ * @param[in] p_buffer Pointer to the packet data.
+ * @param[in] length Length of packet data in bytes.
+ *
+ * @return Packet type field or INVALID_PKT_TYPE in case of decode error.
+ */
+static __INLINE uint32_t packet_type_decode(const uint8_t * p_buffer, uint32_t length)
+{
+ // @note: no pointer validation check needed as allready checked by calling function.
+ uint32_t return_value;
+
+ if (length >= PKT_HDR_SIZE)
+ {
+ return_value = (p_buffer[1] & 0x0Fu);
+ }
+ else
+ {
+ return_value = INVALID_PKT_TYPE;
+ }
+
+ return return_value;
+}
+
+
+/**@brief Function for processing a received vendor specific packet.
+ *
+ * @param[in] p_buffer Pointer to the packet data.
+ * @param[in] length Length of packet data in bytes.
+ */
+static void rx_vendor_specific_pkt_type_handle(const uint8_t * p_buffer, uint32_t length)
+{
+ // @note: no pointer validation check needed as allready checked by calling function.
+ uint32_t err_code;
+
+ if (is_rx_pkt_valid(p_buffer, length))
+ {
+ // RX packet is valid: validate sequence number.
+ const uint8_t rx_seq_number = packet_seq_nmbr_extract(p_buffer);
+ if (packet_number_expected_get() == rx_seq_number)
+ {
+ // Sequence number is valid: transmit acknowledgement.
+ packet_number_expected_inc();
+ ack_transmit();
+
+ m_is_slip_decode_ready = true;
+
+ err_code = hci_mem_pool_rx_data_size_set(length);
+ APP_ERROR_CHECK(err_code);
+
+ err_code = hci_mem_pool_rx_produce(HCI_RX_BUF_SIZE, (void **)&mp_slip_used_rx_buffer);
+ APP_ERROR_CHECK_BOOL((err_code == NRF_SUCCESS) || (err_code == NRF_ERROR_NO_MEM));
+
+ // If memory pool RX buffer produce succeeded we register that buffer to slip layer
+ // otherwise we register the internal acknowledgement buffer.
+ err_code = hci_slip_rx_buffer_register(
+ (err_code == NRF_SUCCESS) ? mp_slip_used_rx_buffer : m_rx_ack_buffer,
+ (err_code == NRF_SUCCESS) ? HCI_RX_BUF_SIZE : ACK_BUF_SIZE);
+
+ APP_ERROR_CHECK(err_code);
+
+ if (m_transport_event_handle != NULL)
+ {
+ // Send application event of RX packet reception.
+ const hci_transport_evt_t evt = {HCI_TRANSPORT_RX_RDY};
+ m_transport_event_handle(evt);
+ }
+ }
+ else
+ {
+ // RX packet discarded: sequence number not valid, set the same buffer to slip layer in
+ // order to avoid buffer overrun.
+ err_code = hci_slip_rx_buffer_register(mp_slip_used_rx_buffer, HCI_RX_BUF_SIZE);
+ APP_ERROR_CHECK(err_code);
+
+ // As packet did not have expected sequence number: send acknowledgement with the
+ // current expected sequence number.
+ ack_transmit();
+ }
+ }
+ else
+ {
+ // RX packet discarded: reset the same buffer to slip layer in order to avoid buffer
+ // overrun.
+ err_code = hci_slip_rx_buffer_register(mp_slip_used_rx_buffer, HCI_RX_BUF_SIZE);
+ APP_ERROR_CHECK(err_code);
+ }
+}
+
+
+/**@brief Function for getting the sequence number of a reliable TX packet for which peer protocol
+ * entity acknowledgment is pending.
+ *
+ * @return sequence number of a reliable TX packet for which peer protocol entity acknowledgement
+ * is pending.
+ */
+static __INLINE uint8_t packet_number_to_transmit_get(void)
+{
+ return m_packet_transmit_seq_number;
+}
+
+
+/**@brief Function for getting the expected acknowledgement number.
+ *
+ * @return expected acknowledgement number.
+ */
+static __INLINE uint8_t expected_ack_number_get(void)
+{
+ uint8_t seq_nmbr = packet_number_to_transmit_get();
+ ++seq_nmbr;
+ seq_nmbr &= 0x07u;
+
+ return seq_nmbr;
+}
+
+
+/**@brief Function for processing a received acknowledgement packet.
+ *
+ * Verifies does the received acknowledgement packet has the expected acknowledgement number and
+ * that the header checksum is correct.
+ *
+ * @param[in] p_buffer Pointer to the packet data.
+ *
+ * @return true if valid acknowledgement packet received.
+ */
+static __INLINE bool rx_ack_pkt_type_handle(const uint8_t * p_buffer)
+{
+ // @note: no pointer validation check needed as allready checked by calling function.
+
+ // Verify header checksum.
+ const uint32_t expected_checksum =
+ ((p_buffer[0] + p_buffer[1] + p_buffer[2] + p_buffer[3])) & 0xFFu;
+ if (expected_checksum != 0)
+ {
+ return false;
+ }
+
+ const uint8_t ack_number = (p_buffer[0] >> 3u) & 0x07u;
+
+ // Verify expected acknowledgment number.
+ return (ack_number == expected_ack_number_get());
+}
+
+
+/**@brief Function for incrementing the sequence number counter of the TX packet.
+ */
+static __INLINE void packet_number_tx_inc(void)
+{
+ ++m_packet_transmit_seq_number;
+ m_packet_transmit_seq_number &= 0x07u;
+}
+
+
+/**@brief Function for TX state machine event processing in a state centric manner.
+ *
+ * @param[in] event Type of event occurred.
+ */
+static void tx_sm_event_handle(tx_event_t event)
+{
+ uint32_t err_code;
+
+ switch (m_tx_state)
+ {
+ case TX_STATE_IDLE:
+ if (event == TX_EVENT_STATE_ENTRY)
+ {
+ err_code = app_timer_stop(m_app_timer_id);
+ APP_ERROR_CHECK(err_code);
+
+ // Send TX-done event if registered handler exists.
+ if (m_transport_tx_done_handle != NULL)
+ {
+ m_transport_tx_done_handle(m_tx_done_result_code);
+ }
+ }
+ break;
+
+ case TX_STATE_PENDING:
+ if (event == TX_EVENT_SLIP_TX_DONE)
+ {
+ // @note: this call should always succeed as called from HCI_SLIP_TX_DONE context
+ // and error cases are managed by dedicated error event from the slip layer.
+ err_code = hci_slip_write(mp_tx_buffer,
+ (m_tx_buffer_length + PKT_HDR_SIZE + PKT_CRC_SIZE));
+ APP_ERROR_CHECK(err_code);
+ tx_sm_state_change(TX_STATE_ACTIVE);
+ }
+ break;
+
+ case TX_STATE_ACTIVE:
+ switch (event)
+ {
+ case TX_EVENT_VALID_RX_ACK:
+ // Tx sequence number counter incremented as packet transmission
+ // acknowledged by peer transport entity.
+ packet_number_tx_inc();
+ tx_sm_state_change(TX_STATE_IDLE);
+ break;
+
+ case TX_EVENT_STATE_ENTRY:
+ m_tx_retry_counter = 0;
+ err_code = app_timer_start(m_app_timer_id,
+ RETRANSMISSION_TIMEOUT_IN_TICKS,
+ NULL);
+ APP_ERROR_CHECK(err_code);
+ break;
+
+ case TX_EVENT_TIMEOUT:
+ if (m_tx_retry_counter != MAX_RETRY_COUNT)
+ {
+ ++m_tx_retry_counter;
+ // @note: no return value check done for hci_slip_write(...) call as current
+ // system design allows use case where retransmission is not accepted by the
+ // slip layer due to existing acknowledgement packet transmission in the
+ // slip layer.
+ UNUSED_VARIABLE(hci_slip_write(mp_tx_buffer,
+ (m_tx_buffer_length +
+ PKT_HDR_SIZE +
+ PKT_CRC_SIZE)));
+ }
+ else
+ {
+ // Application packet retransmission count reached:
+ // - set correct TX done event callback function result code
+ // - execute state change
+ // @note: m_tx_retry_counter is reset in TX_STATE_ACTIVE state entry.
+ m_tx_done_result_code = HCI_TRANSPORT_TX_DONE_FAILURE;
+ tx_sm_state_change(TX_STATE_IDLE);
+ }
+ break;
+
+ default:
+ // No implementation needed.
+ break;
+ }
+ break;
+
+ default:
+ // No implementation needed.
+ break;
+ }
+}
+
+
+/**@brief Function for changing the state of the TX state machine.
+ *
+ * @param[in] new_state State TX state machine transits to.
+ */
+static void tx_sm_state_change(tx_state_t new_state)
+{
+ m_tx_state = new_state;
+ tx_sm_event_handle(TX_EVENT_STATE_ENTRY);
+}
+
+
+/**@brief Function for handling slip events.
+ *
+ * @param[in] event The event structure.
+ */
+void slip_event_handle(hci_slip_evt_t event)
+{
+ uint32_t return_code;
+ uint32_t err_code;
+
+ switch (event.evt_type)
+ {
+ case HCI_SLIP_TX_DONE:
+ tx_sm_event_handle(TX_EVENT_SLIP_TX_DONE);
+ break;
+
+ case HCI_SLIP_RX_RDY:
+ return_code = packet_type_decode(event.packet, event.packet_length);
+
+ switch (return_code)
+ {
+ case PKT_TYPE_VENDOR_SPECIFIC:
+ rx_vendor_specific_pkt_type_handle(event.packet, event.packet_length);
+ break;
+
+ case PKT_TYPE_ACK:
+ if (rx_ack_pkt_type_handle(event.packet))
+ {
+ // Valid expected acknowledgement packet received: set correct TX done event
+ // callback function result code and execute state change.
+ m_tx_done_result_code = HCI_TRANSPORT_TX_DONE_SUCCESS;
+ tx_sm_event_handle(TX_EVENT_VALID_RX_ACK);
+ }
+
+ /* fall-through */
+ default:
+ // RX packet dropped: reset memory buffer to slip in order to avoid RX buffer
+ // overflow.
+ // If existing mem pool produced RX buffer exists reuse that one. If existing
+ // mem pool produced RX buffer does not exist try to produce new one. If
+ // producing fails use the internal acknowledgement buffer.
+ if (mp_slip_used_rx_buffer != NULL)
+ {
+ err_code = hci_slip_rx_buffer_register(mp_slip_used_rx_buffer, HCI_RX_BUF_SIZE);
+ APP_ERROR_CHECK(err_code);
+ }
+ else
+ {
+ err_code = hci_mem_pool_rx_produce(HCI_RX_BUF_SIZE,
+ (void **)&mp_slip_used_rx_buffer);
+ APP_ERROR_CHECK_BOOL((err_code == NRF_SUCCESS) ||
+ (err_code == NRF_ERROR_NO_MEM));
+
+ err_code = hci_slip_rx_buffer_register(
+ (err_code == NRF_SUCCESS) ? mp_slip_used_rx_buffer : m_rx_ack_buffer,
+ (err_code == NRF_SUCCESS) ? HCI_RX_BUF_SIZE : ACK_BUF_SIZE);
+ APP_ERROR_CHECK(err_code);
+ }
+ break;
+ }
+ break;
+
+ case HCI_SLIP_RX_OVERFLOW:
+ err_code = hci_slip_rx_buffer_register(m_rx_ack_buffer, ACK_BUF_SIZE);
+ APP_ERROR_CHECK(err_code);
+ break;
+
+ case HCI_SLIP_ERROR:
+ APP_ERROR_HANDLER(event.evt_type);
+ break;
+
+ default:
+ APP_ERROR_HANDLER(event.evt_type);
+ break;
+ }
+}
+
+
+uint32_t hci_transport_evt_handler_reg(hci_transport_event_handler_t event_handler)
+{
+ uint32_t err_code;
+
+ m_transport_event_handle = event_handler;
+ err_code = hci_slip_evt_handler_register(slip_event_handle);
+ APP_ERROR_CHECK(err_code);
+
+ return (event_handler != NULL) ? NRF_SUCCESS : NRF_ERROR_NULL;
+}
+
+
+uint32_t hci_transport_tx_done_register(hci_transport_tx_done_handler_t event_handler)
+{
+ uint32_t err_code;
+
+ m_transport_tx_done_handle = event_handler;
+ err_code = hci_slip_evt_handler_register(slip_event_handle);
+ APP_ERROR_CHECK(err_code);
+
+ return (event_handler != NULL) ? NRF_SUCCESS : NRF_ERROR_NULL;
+}
+
+
+/**@brief Function for handling the application packet retransmission timeout.
+ *
+ * This function is registered in the @ref app_timer module when a timer is created on
+ * @ref hci_transport_open.
+ *
+ * @note This function must be executed in APP-LO context otherwise retransmission behaviour is
+ * undefined, see @ref nrf51_system_integration_serialization.
+ *
+ * @param[in] p_context The timeout context.
+ */
+void hci_transport_timeout_handle(void * p_context)
+{
+ tx_sm_event_handle(TX_EVENT_TIMEOUT);
+}
+
+
+uint32_t hci_transport_open(void)
+{
+ mp_tx_buffer = NULL;
+ m_tx_buffer_length = 0;
+ m_tx_retry_counter = 0;
+ m_is_slip_decode_ready = false;
+ m_tx_state = TX_STATE_IDLE;
+ m_packet_expected_seq_number = INITIAL_ACK_NUMBER_EXPECTED;
+ m_packet_transmit_seq_number = INITIAL_ACK_NUMBER_TX;
+ m_tx_done_result_code = HCI_TRANSPORT_TX_DONE_FAILURE;
+
+ uint32_t err_code = app_timer_create(&m_app_timer_id,
+ APP_TIMER_MODE_REPEATED,
+ hci_transport_timeout_handle);
+ if (err_code != NRF_SUCCESS)
+ {
+ // @note: conduct required interface adjustment.
+ return NRF_ERROR_INTERNAL;
+ }
+
+ err_code = hci_mem_pool_open();
+ VERIFY_SUCCESS(err_code);
+
+ err_code = hci_slip_open();
+ VERIFY_SUCCESS(err_code);
+
+ err_code = hci_mem_pool_rx_produce(HCI_RX_BUF_SIZE, (void **)&mp_slip_used_rx_buffer);
+ if (err_code != NRF_SUCCESS)
+ {
+ // @note: conduct required interface adjustment.
+ return NRF_ERROR_INTERNAL;
+ }
+
+ err_code = hci_slip_rx_buffer_register(mp_slip_used_rx_buffer, HCI_RX_BUF_SIZE);
+
+ return err_code;
+}
+
+
+uint32_t hci_transport_close(void)
+{
+ uint32_t err_code;
+
+ m_transport_tx_done_handle = NULL;
+ m_transport_event_handle = NULL;
+
+ err_code = hci_mem_pool_close();
+ APP_ERROR_CHECK(err_code);
+ err_code = hci_slip_close();
+ APP_ERROR_CHECK(err_code);
+
+ // @note: NRF_ERROR_NO_MEM is the only return value which should never be returned.
+ err_code = app_timer_stop(m_app_timer_id);
+ APP_ERROR_CHECK_BOOL(err_code != NRF_ERROR_NO_MEM);
+
+ return NRF_SUCCESS;
+}
+
+
+uint32_t hci_transport_tx_alloc(uint8_t ** pp_memory)
+{
+ const uint32_t err_code = hci_mem_pool_tx_alloc((void **)pp_memory);
+ if (err_code == NRF_SUCCESS)
+ {
+ // @note: no need to validate pp_memory against null as validation has already been done
+ // by hci_mem_pool_tx_alloc(...) and visible to us from the method return code.
+ //lint -e(413) "Likely use of null pointer"
+ *pp_memory += PKT_HDR_SIZE;
+ }
+
+ return err_code;
+}
+
+
+uint32_t hci_transport_tx_free(void)
+{
+ return hci_mem_pool_tx_free();
+}
+
+
+/**@brief Function for constructing 1st byte of the packet header of the packet to be transmitted.
+ *
+ * @return 1st byte of the packet header of the packet to be transmitted
+ */
+static __INLINE uint8_t tx_packet_byte_zero_construct(void)
+{
+ const uint32_t value = DATA_INTEGRITY_MASK |
+ RELIABLE_PKT_MASK |
+ (packet_number_expected_get() << 3u) |
+ packet_number_to_transmit_get();
+
+ return (uint8_t) value;
+}
+
+
+/**@brief Function for handling the application packet write request in tx-idle state.
+ */
+static uint32_t pkt_write_handle(void)
+{
+ uint32_t err_code;
+
+ // Set packet header fields.
+
+ mp_tx_buffer -= PKT_HDR_SIZE;
+ mp_tx_buffer[0] = tx_packet_byte_zero_construct();
+
+ const uint16_t type_and_length_fields = ((m_tx_buffer_length << 4u) | PKT_TYPE_VENDOR_SPECIFIC);
+ // @note: no use case for uint16_encode(...) return value.
+ UNUSED_VARIABLE(uint16_encode(type_and_length_fields, &(mp_tx_buffer[1])));
+ mp_tx_buffer[3] = header_checksum_calculate(mp_tx_buffer);
+
+ // Calculate, append CRC to the packet and write it.
+
+ const uint16_t crc = crc16_compute(mp_tx_buffer, (PKT_HDR_SIZE + m_tx_buffer_length), NULL);
+ // @note: no use case for uint16_encode(...) return value.
+ UNUSED_VARIABLE(uint16_encode(crc, &(mp_tx_buffer[PKT_HDR_SIZE + m_tx_buffer_length])));
+ err_code = hci_slip_write(mp_tx_buffer, (m_tx_buffer_length + PKT_HDR_SIZE + PKT_CRC_SIZE));
+ switch (err_code)
+ {
+ case NRF_SUCCESS:
+ tx_sm_state_change(TX_STATE_ACTIVE);
+ break;
+
+ case NRF_ERROR_NO_MEM:
+ tx_sm_state_change(TX_STATE_PENDING);
+ err_code = NRF_SUCCESS;
+ break;
+
+ default:
+ // No implementation needed.
+ break;
+ }
+
+ return err_code;
+}
+
+
+uint32_t hci_transport_pkt_write(const uint8_t * p_buffer, uint16_t length)
+{
+ uint32_t err_code;
+
+ if (p_buffer)
+ {
+ switch (m_tx_state)
+ {
+ case TX_STATE_IDLE:
+ mp_tx_buffer = (uint8_t *)p_buffer;
+ m_tx_buffer_length = length;
+ err_code = pkt_write_handle();
+ break;
+
+ default:
+ err_code = NRF_ERROR_NO_MEM;
+ break;
+ }
+ }
+ else
+ {
+ err_code = NRF_ERROR_NULL;
+ }
+
+ return err_code;
+}
+
+
+uint32_t hci_transport_rx_pkt_extract(uint8_t ** pp_buffer, uint16_t * p_length)
+{
+ uint32_t err_code;
+
+ if (pp_buffer != NULL && p_length != NULL)
+ {
+ uint32_t length = 0;
+
+ if (m_is_slip_decode_ready)
+ {
+ m_is_slip_decode_ready = false;
+ err_code = hci_mem_pool_rx_extract(pp_buffer, &length);
+ length -= (PKT_HDR_SIZE + PKT_CRC_SIZE);
+
+ *p_length = (uint16_t)length;
+ *pp_buffer += PKT_HDR_SIZE;
+ }
+ else
+ {
+ err_code = NRF_ERROR_NO_MEM;
+ }
+ }
+ else
+ {
+ err_code = NRF_ERROR_NULL;
+ }
+
+ return err_code;
+}
+
+
+uint32_t hci_transport_rx_pkt_consume(uint8_t * p_buffer)
+{
+ return (hci_mem_pool_rx_consume(p_buffer - PKT_HDR_SIZE));
+}
+#endif //NRF_MODULE_ENABLED(HCI_TRANSPORT)
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/hci/hci_transport.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/hci/hci_transport.h
new file mode 100644
index 0000000..df5df35
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/hci/hci_transport.h
@@ -0,0 +1,256 @@
+/**
+ * Copyright (c) 2013 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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
+ *
+ * @defgroup hci_transport HCI Transport
+ * @{
+ * @ingroup app_common
+ *
+ * @brief HCI transport module implementation.
+ *
+ * This module implements certain specific features from the three-wire UART transport layer,
+ * defined by the Bluetooth specification version 4.0 [Vol 4] part D.
+ *
+ * \par Features supported
+ * - Transmission and reception of Vendor Specific HCI packet type application packets.
+ * - Transmission and reception of reliable packets: defined by chapter 6 of the specification.
+ *
+ * \par Features not supported
+ * - Link establishment procedure: defined by chapter 8 of the specification.
+ * - Low power: defined by chapter 9 of the specification.
+ *
+ * \par Implementation specific behaviour
+ * - As Link establishment procedure is not supported following static link configuration parameters
+ * are used:
+ * + TX window size is 1.
+ * + 16 bit CCITT-CRC must be used.
+ * + Out of frame software flow control not supported.
+ * + Parameters specific for resending reliable packets are compile time configurable (clarifed
+ * later in this document).
+ * + Acknowledgement packet transmissions are not timeout driven , meaning they are delivered for
+ * transmission within same context which the corresponding application packet was received.
+ *
+ * \par Implementation specific limitations
+ * Current implementation has the following limitations which will have impact to system wide
+ * behaviour:
+ * - Delayed acknowledgement scheduling not implemented:
+ * There exists a possibility that acknowledgement TX packet and application TX packet will collide
+ * in the TX pipeline having the end result that acknowledgement packet will be excluded from the TX
+ * pipeline which will trigger the retransmission algorithm within the peer protocol entity.
+ * - Delayed retransmission scheduling not implemented:
+ * There exists a possibility that retransmitted application TX packet and acknowledgement TX packet
+ * will collide in the TX pipeline having the end result that retransmitted application TX packet
+ * will be excluded from the TX pipeline.
+ * - Processing of the acknowledgement number from RX application packets:
+ * Acknowledgement number is not processed from the RX application packets having the end result
+ * that unnecessary application packet retransmissions can occur.
+ *
+ * The application TX packet processing flow is illustrated by the statemachine below.
+ *
+ * @image html hci_transport_tx_sm.svg "TX - application packet statemachine"
+ *
+ * \par Component specific configuration options
+ *
+ * The following compile time configuration options are available, and used to configure the
+ * application TX packet retransmission interval, in order to suite various application specific
+ * implementations:
+ * - MAC_PACKET_SIZE_IN_BITS Maximum size of a single application packet in bits.
+ * - USED_BAUD_RATE Used uart baudrate.
+ *
+ * The following compile time configuration option is available to configure module specific
+ * behaviour:
+ * - MAX_RETRY_COUNT Max retransmission retry count for applicaton packets.
+ */
+
+#ifndef HCI_TRANSPORT_H__
+#define HCI_TRANSPORT_H__
+
+#include <stdint.h>
+#include "nrf_error.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**@brief Generic event callback function events. */
+typedef enum
+{
+ HCI_TRANSPORT_RX_RDY, /**< An event indicating that RX packet is ready for read. */
+ HCI_TRANSPORT_EVT_TYPE_MAX /**< Enumeration upper bound. */
+} hci_transport_evt_type_t;
+
+/**@brief Struct containing events from the Transport layer.
+ */
+typedef struct
+{
+ hci_transport_evt_type_t evt_type; /**< Type of event. */
+} hci_transport_evt_t;
+
+/**@brief Transport layer generic event callback function type.
+ *
+ * @param[in] event Transport layer event.
+ */
+typedef void (*hci_transport_event_handler_t)(hci_transport_evt_t event);
+
+/**@brief TX done event callback function result codes. */
+typedef enum
+{
+ HCI_TRANSPORT_TX_DONE_SUCCESS, /**< Transmission success, peer transport entity has acknowledged the transmission. */
+ HCI_TRANSPORT_TX_DONE_FAILURE /**< Transmission failure. */
+} hci_transport_tx_done_result_t;
+
+/**@brief Transport layer TX done event callback function type.
+ *
+ * @param[in] result TX done event result code.
+ */
+typedef void (*hci_transport_tx_done_handler_t)(hci_transport_tx_done_result_t result);
+
+/**@brief Function for registering a generic event handler.
+ *
+ * @note Multiple registration requests will overwrite any possible existing registration.
+ *
+ * @param[in] event_handler The function to be called by the transport layer upon an event.
+ *
+ * @retval NRF_SUCCESS Operation success.
+ * @retval NRF_ERROR_NULL Operation failure. NULL pointer supplied.
+ */
+uint32_t hci_transport_evt_handler_reg(hci_transport_event_handler_t event_handler);
+
+/**@brief Function for registering a handler for TX done event.
+ *
+ * @note Multiple registration requests will overwrite any possible existing registration.
+ *
+ * @param[in] event_handler The function to be called by the transport layer upon TX done
+ * event.
+ *
+ * @retval NRF_SUCCESS Operation success.
+ * @retval NRF_ERROR_NULL Operation failure. NULL pointer supplied.
+ */
+uint32_t hci_transport_tx_done_register(hci_transport_tx_done_handler_t event_handler);
+
+/**@brief Function for opening the transport channel and initializing the transport layer.
+ *
+ * @warning Must not be called for a channel which has been allready opened.
+ *
+ * @retval NRF_SUCCESS Operation success.
+ * @retval NRF_ERROR_INTERNAL Operation failure. Internal error ocurred.
+ */
+uint32_t hci_transport_open(void);
+
+/**@brief Function for closing the transport channel.
+ *
+ * @note Can be called multiple times and also for not opened channel.
+ *
+ * @retval NRF_SUCCESS Operation success.
+ */
+uint32_t hci_transport_close(void);
+
+/**@brief Function for allocating tx packet memory.
+ *
+ * @param[out] pp_memory Pointer to the packet data.
+ *
+ * @retval NRF_SUCCESS Operation success. Memory was allocated.
+ * @retval NRF_ERROR_NO_MEM Operation failure. No memory available.
+ * @retval NRF_ERROR_NULL Operation failure. NULL pointer supplied.
+ */
+uint32_t hci_transport_tx_alloc(uint8_t ** pp_memory);
+
+/**@brief Function for freeing tx packet memory.
+ *
+ * @note Memory management works in FIFO principle meaning that free order must match the alloc
+ * order.
+ *
+ * @retval NRF_SUCCESS Operation success. Memory was freed.
+ */
+uint32_t hci_transport_tx_free(void);
+
+/**@brief Function for writing a packet.
+ *
+ * @note Completion of this method does not guarantee that actual peripheral transmission would
+ * have completed.
+ *
+ * @note In case of 0 byte packet length write request, message will consist of only transport
+ * module specific headers.
+ *
+ * @retval NRF_SUCCESS Operation success. Packet was added to the transmission queue
+ * and an event will be send upon transmission completion.
+ * @retval NRF_ERROR_NO_MEM Operation failure. Transmission queue is full and packet was not
+ * added to the transmission queue. User should wait for
+ * a appropriate event prior issuing this operation again.
+ * @retval NRF_ERROR_DATA_SIZE Operation failure. Packet size exceeds limit.
+ * @retval NRF_ERROR_NULL Operation failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_STATE Operation failure. Channel is not open.
+ */
+uint32_t hci_transport_pkt_write(const uint8_t * p_buffer, uint16_t length);
+
+/**@brief Function for extracting received packet.
+ *
+ * @note Extracted memory can't be reused by the underlying transport layer untill freed by call to
+ * hci_transport_rx_pkt_consume().
+ *
+ * @param[out] pp_buffer Pointer to the packet data.
+ * @param[out] p_length Length of packet data in bytes.
+ *
+ * @retval NRF_SUCCESS Operation success. Packet was extracted.
+ * @retval NRF_ERROR_NO_MEM Operation failure. No packet available to extract.
+ * @retval NRF_ERROR_NULL Operation failure. NULL pointer supplied.
+ */
+uint32_t hci_transport_rx_pkt_extract(uint8_t ** pp_buffer, uint16_t * p_length);
+
+/**@brief Function for consuming extracted packet described by p_buffer.
+ *
+ * RX memory pointed to by p_buffer is freed and can be reused by the underlying transport layer.
+ *
+ * @param[in] p_buffer Pointer to the buffer that has been consumed.
+ *
+ * @retval NRF_SUCCESS Operation success.
+ * @retval NRF_ERROR_NO_MEM Operation failure. No packet available to consume.
+ * @retval NRF_ERROR_INVALID_ADDR Operation failure. Not a valid pointer.
+ */
+uint32_t hci_transport_rx_pkt_consume(uint8_t * p_buffer);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // HCI_TRANSPORT_H__
+
+/** @} */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/led_softblink/led_softblink.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/led_softblink/led_softblink.c
new file mode 100644
index 0000000..8156b96
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/led_softblink/led_softblink.c
@@ -0,0 +1,232 @@
+/**
+ * Copyright (c) 2015 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#include "sdk_common.h"
+#if NRF_MODULE_ENABLED(LED_SOFTBLINK)
+#include <string.h>
+#include "led_softblink.h"
+#include "nrf_gpio.h"
+#include "app_timer.h"
+#include "nrf_assert.h"
+#include "low_power_pwm.h"
+
+/* Period for LED softblink PWM. */
+#define PWM_PERIOD UINT8_MAX
+
+/**@bref Structure to handle timer time-outs
+ *
+ */
+typedef struct
+{
+ bool leds_is_on; /**< Flag for indicating if LEDs are on. */
+ bool is_counting_up; /**< Flag for indicating if counter is incrementing or decrementing. */
+ nrfx_drv_state_t led_sb_state; /**< Indicates current state of instance. */
+ uint16_t duty_cycle; /**< Current pulse width. */
+ uint32_t bit_mask; /**< Mask of used pins. */
+ led_sb_init_params_t params; /**< Structure holding initialization parameters. */
+ low_power_pwm_config_t pwm_config; /**< Structure holding parameters for initializing low level layer. */
+ low_power_pwm_t pwm_instance; /**< Structure holding low-power PWM instance parameters. */
+}led_sb_context_t;
+
+APP_TIMER_DEF(m_led_softblink_timer);
+
+static led_sb_context_t m_led_sb = {0};
+
+/**@brief Timer event handler for softblink.
+ *
+ * @param[in] p_context General purpose pointer. Will be passed to the time-out handler
+ * when the timer expires.
+ *
+ */
+static void led_softblink_on_timeout(void * p_context)
+{
+ static int32_t pause_ticks;
+ ASSERT(m_led_sb.led_sb_state != NRFX_DRV_STATE_UNINITIALIZED);
+ ret_code_t err_code;
+
+ if (pause_ticks <= 0)
+ {
+ if (m_led_sb.is_counting_up)
+ {
+ if (m_led_sb.duty_cycle >= (m_led_sb.params.duty_cycle_max - m_led_sb.params.duty_cycle_step))
+ {
+ // Max PWM duty cycle is reached, start decrementing.
+ m_led_sb.is_counting_up = false;
+ m_led_sb.duty_cycle = m_led_sb.params.duty_cycle_max;
+ pause_ticks = m_led_sb.params.on_time_ticks ? m_led_sb.params.on_time_ticks + APP_TIMER_MIN_TIMEOUT_TICKS : 0;
+ }
+ else
+ {
+ m_led_sb.duty_cycle += m_led_sb.params.duty_cycle_step;
+ }
+ }
+ else
+ {
+ if (m_led_sb.duty_cycle <= (m_led_sb.params.duty_cycle_min + m_led_sb.params.duty_cycle_step))
+ {
+ // Min PWM duty cycle is reached, start incrementing.
+ m_led_sb.is_counting_up = true;
+ m_led_sb.duty_cycle = m_led_sb.params.duty_cycle_min;
+ pause_ticks = m_led_sb.params.off_time_ticks ? m_led_sb.params.off_time_ticks + APP_TIMER_MIN_TIMEOUT_TICKS : 0;
+ }
+ else
+ {
+ m_led_sb.duty_cycle -= m_led_sb.params.duty_cycle_step;
+ }
+ }
+ }
+ else
+ {
+ pause_ticks -= PWM_PERIOD;
+ }
+
+ err_code = low_power_pwm_duty_set(&m_led_sb.pwm_instance, m_led_sb.duty_cycle);
+
+ APP_ERROR_CHECK(err_code);
+}
+
+
+ret_code_t led_softblink_init(led_sb_init_params_t const * p_init_params)
+{
+ ret_code_t err_code;
+
+ ASSERT(m_led_sb.led_sb_state == NRFX_DRV_STATE_UNINITIALIZED);
+ ASSERT(p_init_params);
+
+ if ( (p_init_params->duty_cycle_max == 0) ||
+ (p_init_params->duty_cycle_max <= p_init_params->duty_cycle_min) ||
+ (p_init_params->duty_cycle_step == 0) ||
+ (p_init_params->leds_pin_bm == 0))
+ {
+ return NRF_ERROR_INVALID_PARAM;
+ }
+
+
+
+ memset(&m_led_sb, 0, sizeof(led_sb_context_t));
+ memcpy(&m_led_sb.params, p_init_params, sizeof(led_sb_init_params_t));
+
+ m_led_sb.is_counting_up = true;
+ m_led_sb.duty_cycle = p_init_params->duty_cycle_min + p_init_params->duty_cycle_step;
+ m_led_sb.leds_is_on = false;
+ m_led_sb.bit_mask = p_init_params->leds_pin_bm;
+
+ m_led_sb.pwm_config.active_high = m_led_sb.params.active_high;
+ m_led_sb.pwm_config.bit_mask = p_init_params->leds_pin_bm;
+ m_led_sb.pwm_config.p_port = p_init_params->p_leds_port;
+ m_led_sb.pwm_config.period = PWM_PERIOD;
+ m_led_sb.pwm_config.p_timer_id = &m_led_softblink_timer;
+
+ err_code = low_power_pwm_init( &m_led_sb.pwm_instance, &m_led_sb.pwm_config, led_softblink_on_timeout);
+
+ if (err_code == NRF_SUCCESS)
+ {
+ m_led_sb.led_sb_state = NRFX_DRV_STATE_INITIALIZED;
+ }
+ else
+ {
+ return err_code;
+ }
+
+ err_code = low_power_pwm_duty_set( &m_led_sb.pwm_instance, p_init_params->duty_cycle_min + p_init_params->duty_cycle_step);
+
+ return err_code;
+}
+
+
+ret_code_t led_softblink_start(uint32_t leds_pin_bit_mask)
+{
+ ret_code_t err_code;
+
+ ASSERT(m_led_sb.led_sb_state == NRFX_DRV_STATE_INITIALIZED);
+
+ err_code = low_power_pwm_start(&m_led_sb.pwm_instance, leds_pin_bit_mask);
+
+ return err_code;
+}
+
+
+ret_code_t led_softblink_stop(void)
+{
+ ret_code_t err_code;
+
+ err_code = low_power_pwm_stop(&m_led_sb.pwm_instance);
+
+ return err_code;
+}
+
+
+void led_softblink_off_time_set(uint32_t off_time_ticks)
+{
+ ASSERT(m_led_sb.led_sb_state != NRFX_DRV_STATE_UNINITIALIZED);
+
+ m_led_sb.params.off_time_ticks = off_time_ticks;
+}
+
+
+void led_softblink_on_time_set(uint32_t on_time_ticks)
+{
+ ASSERT(m_led_sb.led_sb_state != NRFX_DRV_STATE_UNINITIALIZED);
+
+ m_led_sb.params.on_time_ticks = on_time_ticks;
+}
+
+
+ret_code_t led_softblink_uninit(void)
+{
+ ASSERT(m_led_sb.led_sb_state != NRFX_DRV_STATE_UNINITIALIZED);
+
+ ret_code_t err_code;
+
+ err_code = led_softblink_stop();
+
+ if (err_code == NRF_SUCCESS)
+ {
+ m_led_sb.led_sb_state = NRFX_DRV_STATE_UNINITIALIZED;
+ }
+ else
+ {
+ return err_code;
+ }
+
+ memset(&m_led_sb, 0, sizeof(m_led_sb));
+
+ return NRF_SUCCESS;
+}
+#endif //NRF_MODULE_ENABLED(LED_SOFTBLINK)
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/led_softblink/led_softblink.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/led_softblink/led_softblink.h
new file mode 100644
index 0000000..936edba
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/led_softblink/led_softblink.h
@@ -0,0 +1,171 @@
+/**
+ * Copyright (c) 2015 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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
+ *
+ * @defgroup led_softblink LED softblink
+ * @{
+ * @ingroup app_common
+ *
+ * @brief Module for generating a changing pulse-width modulated output signal that is used to smoothly blink LEDs.
+ *
+ * @details This module provides an LED softblink implementation using timers and GPIO.
+ *
+ * LED softblink needs one timer. It can use any number of output channels that are available.
+ *
+ * Only one instance of LED softblink can run at a time.
+ */
+
+#ifndef LED_SOFTBLINK_H__
+#define LED_SOFTBLINK_H__
+
+#include <stdbool.h>
+#include <stdint.h>
+#include "sdk_errors.h"
+#include "nrf_gpio.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @brief Structure holding the initialization parameters.
+ */
+typedef struct
+{
+ bool active_high; /**< Activate negative polarity. */
+ uint8_t duty_cycle_max; /**< Maximum impulse width. */
+ uint8_t duty_cycle_min; /**< Minimum impulse width. */
+ uint8_t duty_cycle_step; /**< Cycle step. */
+ uint32_t off_time_ticks; /**< Ticks to stay in low impulse state. */
+ uint32_t on_time_ticks; /**< Ticks to stay in high impulse state. */
+ uint32_t leds_pin_bm; /**< Mask of used LEDs. */
+ NRF_GPIO_Type * p_leds_port; /**< Port of used LEDs mask. */
+}led_sb_init_params_t;
+
+/**
+ * @name Default settings
+ * @brief Default settings for LED softblink.
+ * @{
+ */
+#define LED_SB_INIT_PARAMS_ACTIVE_HIGH false
+#define LED_SB_INIT_PARAMS_DUTY_CYCLE_MAX 220
+#define LED_SB_INIT_PARAMS_DUTY_CYCLE_MIN 0
+#define LED_SB_INIT_PARAMS_DUTY_CYCLE_STEP 5
+#define LED_SB_INIT_PARAMS_OFF_TIME_TICKS 65536
+#define LED_SB_INIT_PARAMS_ON_TIME_TICKS 0
+#define LED_SB_INIT_PARAMS_LEDS_PIN_BM(mask) (mask)
+#define LED_SB_INIT_PARAMS_LEDS_PORT NRF_GPIO
+/** @} */
+
+/**
+ * @brief LED softblink default configuration.
+ */
+#define LED_SB_INIT_DEFAULT_PARAMS(mask) \
+{ \
+ .active_high = LED_SB_INIT_PARAMS_ACTIVE_HIGH, \
+ .duty_cycle_max = LED_SB_INIT_PARAMS_DUTY_CYCLE_MAX, \
+ .duty_cycle_min = LED_SB_INIT_PARAMS_DUTY_CYCLE_MIN, \
+ .duty_cycle_step = LED_SB_INIT_PARAMS_DUTY_CYCLE_STEP, \
+ .off_time_ticks = LED_SB_INIT_PARAMS_OFF_TIME_TICKS, \
+ .on_time_ticks = LED_SB_INIT_PARAMS_ON_TIME_TICKS, \
+ .leds_pin_bm = LED_SB_INIT_PARAMS_LEDS_PIN_BM(mask), \
+ .p_leds_port = LED_SB_INIT_PARAMS_LEDS_PORT \
+}
+
+/**
+ * @brief Function for initializing LED softblink.
+ *
+ * @param[in] p_init_params Pointer to the initialization structure.
+ *
+ * @return Values returned by @ref app_timer_create.
+ */
+ret_code_t led_softblink_init(led_sb_init_params_t const * p_init_params);
+
+/**
+ * @brief Function for starting to blink LEDs.
+ *
+ * @param[in] leds_pin_bit_mask Bit mask containing the pins for the LEDs to be blinked.
+ *
+ * @return Values returned by @ref app_timer_start.
+ */
+ret_code_t led_softblink_start(uint32_t leds_pin_bit_mask);
+
+/**
+ * @brief Function for stopping to blink LEDs.
+ *
+ * @return Values returned by @ref app_timer_stop.
+ */
+ret_code_t led_softblink_stop(void);
+
+/**
+ * @brief Function for setting the off time.
+ *
+ * This function configures the time that the LEDs will be off between each blink.
+ *
+ * @param[in] off_time_ticks Off time in ticks.
+ *
+ */
+void led_softblink_off_time_set(uint32_t off_time_ticks);
+
+/**
+ * @brief Function for setting the on time.
+ *
+ * This function configures the time that the LEDs will be on between each blink.
+ *
+ * @param[in] on_time_ticks On time in ticks.
+ *
+ */
+void led_softblink_on_time_set(uint32_t on_time_ticks);
+
+/**
+ * @brief Function for uninitializing LED softblink.
+ *
+ * @retval NRF_SUCCESS If LED softblink was uninitialized successfully.
+ */
+ret_code_t led_softblink_uninit(void);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // LED_SOFTBLINK_H__
+
+/** @} */
+
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/low_power_pwm/low_power_pwm.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/low_power_pwm/low_power_pwm.c
new file mode 100644
index 0000000..1331a25
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/low_power_pwm/low_power_pwm.c
@@ -0,0 +1,258 @@
+/**
+ * Copyright (c) 2015 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#include "sdk_common.h"
+#if NRF_MODULE_ENABLED(LOW_POWER_PWM)
+#include <string.h>
+#include "low_power_pwm.h"
+#include "nrf_gpio.h"
+#include "app_timer.h"
+#include "nrf_assert.h"
+
+/**
+ * @brief Function for turning on pins.
+ *
+ * Sets the pin high state according to active_high parameter.
+ *
+ * @param[in] p_pwm_instance Pointer to instance of low-power PWM.
+ */
+__STATIC_INLINE void pin_on(low_power_pwm_t * p_pwm_instance)
+{
+ if (p_pwm_instance->active_high)
+ {
+ nrf_gpio_port_out_set(p_pwm_instance->p_port, p_pwm_instance->bit_mask_toggle);
+ }
+ else
+ {
+ nrf_gpio_port_out_clear(p_pwm_instance->p_port, p_pwm_instance->bit_mask_toggle);
+ }
+ p_pwm_instance->pin_is_on = true;
+}
+
+
+/**
+ * @brief Function for turning off pins.
+ *
+ * Sets the pin low state according to active_high parameter.
+ *
+ * @param[in] p_pwm_instance Pointer to instance of low-power PWM.
+ */
+__STATIC_INLINE void pin_off(low_power_pwm_t * p_pwm_instance)
+{
+ if (p_pwm_instance->active_high)
+ {
+ nrf_gpio_port_out_clear(p_pwm_instance->p_port, p_pwm_instance->bit_mask_toggle);
+ }
+ else
+ {
+ nrf_gpio_port_out_set(p_pwm_instance->p_port, p_pwm_instance->bit_mask_toggle);
+ }
+ p_pwm_instance->pin_is_on = false;
+}
+
+
+/**
+ * @brief Timer event handler for PWM.
+ *
+ * @param[in] p_context General purpose pointer. Will be passed to the time-out handler
+ * when the timer expires.
+ *
+ */
+static void pwm_timeout_handler(void * p_context)
+{
+ ret_code_t err_code;
+ uint8_t duty_cycle;
+
+ low_power_pwm_t * p_pwm_instance = (low_power_pwm_t *)p_context;
+
+ if (p_pwm_instance->evt_type == LOW_POWER_PWM_EVENT_PERIOD)
+ {
+ if (p_pwm_instance->handler)
+ {
+ p_pwm_instance->handler(p_pwm_instance);
+
+ if (p_pwm_instance->pwm_state != NRFX_DRV_STATE_POWERED_ON)
+ {
+ return;
+ }
+ }
+
+ duty_cycle = p_pwm_instance->duty_cycle;
+
+ if (duty_cycle == p_pwm_instance->period) // Process duty cycle 100%
+ {
+ pin_on(p_pwm_instance);
+ p_pwm_instance->timeout_ticks = p_pwm_instance->period + APP_TIMER_MIN_TIMEOUT_TICKS;
+ }
+ else if (duty_cycle == 0) // Process duty cycle 0%
+ {
+ pin_off(p_pwm_instance);
+ p_pwm_instance->timeout_ticks = p_pwm_instance->period + APP_TIMER_MIN_TIMEOUT_TICKS;
+ }
+ else // Process any other duty cycle than 0 or 100%
+ {
+ pin_on(p_pwm_instance);
+ p_pwm_instance->timeout_ticks = ((duty_cycle * p_pwm_instance->period)>>8) +
+ APP_TIMER_MIN_TIMEOUT_TICKS;
+ // setting next state
+ p_pwm_instance->evt_type = LOW_POWER_PWM_EVENT_DUTY_CYCLE;
+ }
+ }
+ else
+ {
+ pin_off(p_pwm_instance);
+ p_pwm_instance->evt_type = LOW_POWER_PWM_EVENT_PERIOD;
+ p_pwm_instance->timeout_ticks = (((p_pwm_instance->period - p_pwm_instance->duty_cycle) *
+ p_pwm_instance->period)>>8) + APP_TIMER_MIN_TIMEOUT_TICKS;
+ }
+
+ if (p_pwm_instance->pwm_state == NRFX_DRV_STATE_POWERED_ON)
+ {
+ err_code = app_timer_start(*p_pwm_instance->p_timer_id, p_pwm_instance->timeout_ticks, p_pwm_instance);
+ APP_ERROR_CHECK(err_code);
+ }
+}
+
+
+ret_code_t low_power_pwm_init(low_power_pwm_t * p_pwm_instance,
+ low_power_pwm_config_t const * p_pwm_config,
+ app_timer_timeout_handler_t handler)
+{
+ ASSERT(p_pwm_instance->pwm_state == NRFX_DRV_STATE_UNINITIALIZED);
+ ASSERT(p_pwm_config->bit_mask != 0);
+ ASSERT(p_pwm_config->p_port != NULL);
+ ASSERT(p_pwm_config->period != 0);
+
+ ret_code_t err_code;
+ uint32_t bit_mask;
+ uint32_t pin_number = 0;
+
+ p_pwm_instance->handler = handler;
+
+ bit_mask = p_pwm_config->bit_mask;
+
+ p_pwm_instance->active_high = p_pwm_config->active_high;
+ p_pwm_instance->bit_mask = p_pwm_config->bit_mask;
+ p_pwm_instance->bit_mask_toggle = p_pwm_config->bit_mask;
+ p_pwm_instance->p_port = p_pwm_config->p_port;
+ p_pwm_instance->period = p_pwm_config->period;
+ p_pwm_instance->p_timer_id = p_pwm_config->p_timer_id;
+
+ err_code = app_timer_create(p_pwm_instance->p_timer_id, APP_TIMER_MODE_SINGLE_SHOT, pwm_timeout_handler);
+
+ if (err_code != NRF_SUCCESS)
+ {
+ return err_code;
+ }
+
+ while (bit_mask)
+ {
+ if (bit_mask & 0x1UL)
+ {
+ nrf_gpio_cfg_output(pin_number);
+ }
+
+ pin_number++;
+ bit_mask >>= 1UL;
+ }
+
+ pin_off(p_pwm_instance);
+ p_pwm_instance->pwm_state = NRFX_DRV_STATE_INITIALIZED;
+
+ return NRF_SUCCESS;
+}
+
+
+ret_code_t low_power_pwm_start(low_power_pwm_t * p_pwm_instance,
+ uint32_t pin_bit_mask)
+{
+ ASSERT(p_pwm_instance->pwm_state != NRFX_DRV_STATE_UNINITIALIZED);
+ ASSERT(((p_pwm_instance->bit_mask) & pin_bit_mask) != 0x00);
+
+ p_pwm_instance->pwm_state = NRFX_DRV_STATE_POWERED_ON;
+ p_pwm_instance->bit_mask_toggle = pin_bit_mask;
+
+ pin_off(p_pwm_instance);
+
+ p_pwm_instance->bit_mask |= pin_bit_mask;
+ p_pwm_instance->evt_type = LOW_POWER_PWM_EVENT_PERIOD;
+
+ app_timer_timeout_handler_t handler = p_pwm_instance->handler;
+ p_pwm_instance->handler = NULL;
+ pwm_timeout_handler(p_pwm_instance);
+ p_pwm_instance->handler = handler;
+
+ return NRF_SUCCESS;
+}
+
+
+ret_code_t low_power_pwm_stop(low_power_pwm_t * p_pwm_instance)
+{
+ ASSERT(p_pwm_instance->pwm_state == NRFX_DRV_STATE_POWERED_ON);
+
+ ret_code_t err_code;
+
+ err_code = app_timer_stop(*p_pwm_instance->p_timer_id);
+
+ pin_off(p_pwm_instance);
+
+ if (err_code != NRF_SUCCESS)
+ {
+ return err_code;
+ }
+
+ p_pwm_instance->pwm_state = NRFX_DRV_STATE_INITIALIZED;
+
+
+ return NRF_SUCCESS;
+}
+
+
+ret_code_t low_power_pwm_duty_set(low_power_pwm_t * p_pwm_instance, uint8_t duty_cycle)
+{
+ if ( p_pwm_instance->period < duty_cycle)
+ {
+ return NRF_ERROR_INVALID_PARAM;
+ }
+
+ p_pwm_instance->duty_cycle = duty_cycle;
+
+ return NRF_SUCCESS;
+}
+#endif //NRF_MODULE_ENABLED(LOW_POWER_PWM)
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/low_power_pwm/low_power_pwm.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/low_power_pwm/low_power_pwm.h
new file mode 100644
index 0000000..8a9421e
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/low_power_pwm/low_power_pwm.h
@@ -0,0 +1,209 @@
+/**
+ * Copyright (c) 2015 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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
+ *
+ * @defgroup low_power_pwm Low-power PWM
+ * @{
+ * @ingroup app_common
+ *
+ * @brief Module for generating a low-power pulse-width modulated output signal.
+ *
+ * This module provides a low-power PWM implementation using app_timers and GPIO.
+ *
+ * Each low-power PWM instance utilizes one app_timer. This means it runs on RTC
+ * and does not require HFCLK to be running. There can be any number of output
+ * channels per instance.
+ */
+
+#ifndef LOW_POWER_PWM_H__
+#define LOW_POWER_PWM_H__
+
+#include <nrfx.h>
+#include "app_timer.h"
+#include "sdk_errors.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @brief Event types.
+ */
+typedef enum
+{
+ LOW_POWER_PWM_EVENT_PERIOD = 0,
+ LOW_POWER_PWM_EVENT_DUTY_CYCLE
+}low_power_pwm_evt_type_t;
+
+/**@brief Application time-out handler type. */
+typedef void (*low_power_pwm_timeout_user)(void * p_context, low_power_pwm_evt_type_t evt_type);
+
+/**
+ * @brief Structure holding the initialization parameters.
+ */
+typedef struct
+{
+ bool active_high; /**< Activate negative polarity. */
+ uint8_t period; /**< Width of the low_power_pwm period. */
+ NRF_GPIO_Type * p_port; /**< Port used to work on selected mask. */
+ uint32_t bit_mask; /**< Pins to be initialized. */
+ app_timer_id_t const * p_timer_id; /**< Pointer to the timer ID of low_power_pwm. */
+} low_power_pwm_config_t;
+
+
+/**
+ * @name Default settings
+ * @{
+ *
+ * @brief Default parameters for the @ref low_power_pwm_config_t structure.
+ *
+ */
+#define LOW_POWER_PWM_CONFIG_ACTIVE_HIGH false
+#define LOW_POWER_PWM_CONFIG_PERIOD UINT8_MAX
+#define LOW_POWER_PWM_CONFIG_PORT NRF_GPIO
+#define LOW_POWER_PWM_CONFIG_BIT_MASK(mask) (mask)
+/** @} */
+
+/**
+ * @brief Low-power PWM default configuration.
+ */
+#define LOW_POWER_PWM_DEFAULT_CONFIG(mask) \
+{ \
+ .active_high = LOW_POWER_PWM_CONFIG_ACTIVE_HIGH , \
+ .period = LOW_POWER_PWM_CONFIG_PERIOD , \
+ .p_port = LOW_POWER_PWM_CONFIG_PORT, \
+ .bit_mask = LOW_POWER_PWM_CONFIG_BIT_MASK(mask) \
+}
+/**
+ * @cond (NODOX)
+ * @defgroup low_power_pwm_internal Auxiliary internal types declarations
+ * @brief Module for internal usage inside the library only.
+ * @details These definitions are available to the user, but they should not
+ * be accessed directly. Use @ref low_power_pwm_duty_set instead.
+ * @{
+ *
+ */
+
+ /**
+ * @brief Structure holding parameters of a given low-power PWM instance.
+ */
+ struct low_power_pwm_s
+ {
+ bool active_high; /**< Activate negative polarity. */
+ bool pin_is_on; /**< Indicates the current state of the pin. */
+ uint8_t period; /**< Width of the low_power_pwm period. */
+ uint8_t duty_cycle; /**< Width of high pulse. */
+ nrfx_drv_state_t pwm_state; /**< Indicates the current state of the PWM instance. */
+ uint32_t bit_mask; /**< Pins to be initialized. */
+ uint32_t bit_mask_toggle; /**< Pins to be toggled. */
+ uint32_t timeout_ticks; /**< Value to start the next app_timer. */
+ low_power_pwm_evt_type_t evt_type; /**< Slope that triggered time-out. */
+ app_timer_timeout_handler_t handler; /**< User handler to be called in the time-out handler. */
+ app_timer_id_t const * p_timer_id; /**< Pointer to the timer ID of low_power_pwm. */
+ NRF_GPIO_Type * p_port; /**< Port used with pin bit mask. */
+ };
+
+/** @}
+ * @endcond
+ */
+
+/**
+ * @brief Internal structure holding parameters of a low-power PWM instance.
+ */
+typedef struct low_power_pwm_s low_power_pwm_t;
+
+
+/**
+ * @brief Function for initializing a low-power PWM instance.
+ *
+ * @param[in] p_pwm_instance Pointer to the instance to be started.
+ * @param[in] p_pwm_config Pointer to the configuration structure.
+ * @param[in] handler User function to be called in case of time-out.
+ *
+ * @return Values returned by @ref app_timer_create.
+ */
+ret_code_t low_power_pwm_init(low_power_pwm_t * p_pwm_instance,
+ low_power_pwm_config_t const * p_pwm_config,
+ app_timer_timeout_handler_t handler);
+
+
+/**
+ * @brief Function for starting a low-power PWM instance.
+ *
+ * @param[in] p_pwm_instance Pointer to the instance to be started.
+ * @param[in] pins_bit_mask Bit mask of pins to be started.
+ *
+ * @return Values returned by @ref app_timer_start.
+ */
+ret_code_t low_power_pwm_start(low_power_pwm_t * p_pwm_instance,
+ uint32_t pins_bit_mask);
+
+
+/**
+ * @brief Function for stopping a low-power PWM instance.
+ *
+ * @param[in] p_pwm_instance Pointer to the instance to be stopped.
+ *
+ * @return Values returned by @ref app_timer_stop.
+ */
+ret_code_t low_power_pwm_stop(low_power_pwm_t * p_pwm_instance);
+
+
+/**
+ * @brief Function for setting a new high pulse width for a given instance.
+ *
+ * This function can be called from the timer handler.
+ *
+ * @param[in] p_pwm_instance Pointer to the instance to be changed.
+ * @param[in] duty_cycle New high pulse width. 0 means that the pin is always off. 255 means that it is always on.
+ *
+ * @retval NRF_SUCCESS If the function completed successfully.
+ * @retval NRF_ERROR_INVALID_PARAM If the function returned an error because of invalid parameters.
+ */
+ret_code_t low_power_pwm_duty_set(low_power_pwm_t * p_pwm_instance, uint8_t duty_cycle);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // LOW_POWER_PWM_H__
+
+/** @} */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/mem_manager/mem_manager.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/mem_manager/mem_manager.c
new file mode 100644
index 0000000..a64b198
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/mem_manager/mem_manager.c
@@ -0,0 +1,931 @@
+/**
+ * Copyright (c) 2014 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#include "sdk_common.h"
+#if NRF_MODULE_ENABLED(MEM_MANAGER)
+#include "mem_manager.h"
+#include "nrf_assert.h"
+
+#define NRF_LOG_MODULE_NAME mem_mngr
+
+#if MEM_MANAGER_CONFIG_LOG_ENABLED
+#define NRF_LOG_LEVEL MEM_MANAGER_CONFIG_LOG_LEVEL
+#define NRF_LOG_INFO_COLOR MEM_MANAGER_CONFIG_INFO_COLOR
+#define NRF_LOG_DEBUG_COLOR MEM_MANAGER_CONFIG_DEBUG_COLOR
+#else //MEM_MANAGER_CONFIG_LOG_ENABLED
+#define NRF_LOG_LEVEL 0
+#endif //MEM_MANAGER_CONFIG_LOG_ENABLED
+#include "nrf_log.h"
+NRF_LOG_MODULE_REGISTER();
+
+/**
+ * @defgroup memory_manager_mutex_lock_unlock Module's Mutex Lock/Unlock Macros.
+ *
+ * @details Macros used to lock and unlock modules. Currently the SDK does not use mutexes but
+ * framework is provided in case need arises to use an alternative architecture.
+ * @{
+ */
+#define MM_MUTEX_LOCK() SDK_MUTEX_LOCK(m_mm_mutex) /**< Lock module using mutex. */
+#define MM_MUTEX_UNLOCK() SDK_MUTEX_UNLOCK(m_mm_mutex) /**< Unlock module using mutex. */
+/** @} */
+
+#undef NULL_PARAM_CHECK
+#undef NULL_PARAM_CHECK_VOID
+#undef VERIFY_MODULE_INITIALIZED
+#undef VERIFY_MODULE_INITIALIZED_VOID
+#undef VERIFY_REQUESTED_SIZE
+#undef VERIFY_REQUESTED_SIZE_VOID
+
+#if (MEM_MANAGER_DISABLE_API_PARAM_CHECK == 0)
+
+/**
+ * @brief Macro for verifying NULL parameters.
+ * Returning with an appropriate error code on failure.
+ *
+ * @param[in] PARAM Parameter checked for NULL.
+ *
+ * @retval (NRF_ERROR_NULL | NRF_ERROR_MEMORY_MANAGER_ERR_BASE) when @ref PARAM is NULL.
+ */
+#define NULL_PARAM_CHECK(PARAM) \
+ if ((PARAM) == NULL) \
+ { \
+ return (NRF_ERROR_NULL | NRF_ERROR_MEMORY_MANAGER_ERR_BASE); \
+ }
+
+/**
+ * @brief Macro for verifying NULL parameters are not passed to API and returning on failure.
+ *
+ * @param[in] PARAM Parameter checked for NULL.
+ */
+#define NULL_PARAM_CHECK_VOID(PARAM) \
+ if ((PARAM) == NULL) \
+ { \
+ return; \
+ }
+
+
+/**
+ * @brief Macro for verifying module's initialization status.
+ * Returning with an appropriate error code on failure.
+ *
+ * @retval (NRF_ERROR_INVALID_STATE | NRF_ERROR_MEMORY_MANAGER_ERR_BASE) module is uninitialized.
+ */
+#define VERIFY_MODULE_INITIALIZED() \
+ do \
+ { \
+ if (!m_module_initialized) \
+ { \
+ return (NRF_ERROR_INVALID_STATE | NRF_ERROR_MEMORY_MANAGER_ERR_BASE); \
+ } \
+ } while (0)
+
+/**
+ * @brief Macro for verifying module's initialization status and returning on failure.
+ */
+#define VERIFY_MODULE_INITIALIZED_VOID() \
+ do \
+ { \
+ if (!m_module_initialized) \
+ { \
+ return; \
+ } \
+ } while (0)
+
+
+/**
+ * @brief Macro for verifying requested size of memory does not exceed maximum block
+ * size supported by the module. Returning with appropriate error code on failure.
+ *
+ * @param[in] SIZE Requested size to be allocated.
+ *
+ * @retval (NRF_ERROR_INVALID_PARAM | NRF_ERROR_MEMORY_MANAGER_ERR_BASE) if requested size is greater
+ * than the largest block size managed by the module.
+ */
+#define VERIFY_REQUESTED_SIZE(SIZE) \
+ do \
+ { \
+ if (((SIZE) == 0) ||((SIZE) > MAX_MEM_SIZE)) \
+ { \
+ return (NRF_ERROR_INVALID_PARAM | NRF_ERROR_MEMORY_MANAGER_ERR_BASE); \
+ } \
+ } while (0)
+
+
+/**
+ * @brief Macro for verifying requested size of memory does not exceed maximum block
+ * size supported by the module. Returns on failure.
+ *
+ * @param[in] SIZE Requested size to be allocated.
+ */
+#define VERIFY_REQUESTED_SIZE_VOID(SIZE) \
+ do \
+ { \
+ if (((SIZE) == 0) ||((SIZE) > MAX_MEM_SIZE)) \
+ { \
+ return; \
+ } \
+ } while (0)
+
+
+/**@} */
+#else //MEM_MANAGER_DISABLE_API_PARAM_CHECK
+
+#define NULL_PARAM_CHECK(PARAM)
+#define VERIFY_MODULE_INITIALIZED()
+#define VERIFY_REQUESTED_SIZE(SIZE)
+
+#endif //MEM_MANAGER_DISABLE_API_PARAM_CHECK
+
+
+/**@brief Setting defaults in case XXSmall block not used by application. */
+#ifndef MEMORY_MANAGER_XXSMALL_BLOCK_COUNT
+ #define MEMORY_MANAGER_XXSMALL_BLOCK_COUNT 0
+ #define MEMORY_MANAGER_XXSMALL_BLOCK_SIZE 0
+ #define XXSMALL_BLOCK_START 0
+ #define XXSMALL_BLOCK_END 0
+ #define XXSMALL_MEMORY_START 0
+#endif // MEMORY_MANAGER_XXSMALL_BLOCK_SIZE
+
+
+/**@brief Setting defaults in case XSmall block not used by application. */
+#ifndef MEMORY_MANAGER_XSMALL_BLOCK_COUNT
+ #define MEMORY_MANAGER_XSMALL_BLOCK_COUNT 0
+ #define MEMORY_MANAGER_XSMALL_BLOCK_SIZE 0
+ #define XSMALL_BLOCK_START 0
+ #define XSMALL_BLOCK_END 0
+ #define XSMALL_MEMORY_START 0
+#endif // MEMORY_MANAGER_XSMALL_BLOCK_SIZE
+
+
+/**@brief Setting defaults in case Small block not used by application. */
+#ifndef MEMORY_MANAGER_SMALL_BLOCK_COUNT
+ #define MEMORY_MANAGER_SMALL_BLOCK_COUNT 0
+ #define MEMORY_MANAGER_SMALL_BLOCK_SIZE 0
+ #define SMALL_BLOCK_START 0
+ #define SMALL_BLOCK_END 0
+ #define SMALL_MEMORY_START 0
+#endif // MEMORY_MANAGER_SMALL_BLOCK_COUNT
+
+
+/**@brief Setting defaults in case Medium block not used by application. */
+#ifndef MEMORY_MANAGER_MEDIUM_BLOCK_COUNT
+ #define MEMORY_MANAGER_MEDIUM_BLOCK_COUNT 0
+ #define MEMORY_MANAGER_MEDIUM_BLOCK_SIZE 0
+ #define MEDIUM_BLOCK_START 0
+ #define MEDIUM_BLOCK_END 0
+ #define MEDIUM_MEMORY_START 0
+#endif // MEMORY_MANAGER_MEDIUM_BLOCK_COUNT
+
+
+/**@brief Setting defaults in case Large block not used by application. */
+#ifndef MEMORY_MANAGER_LARGE_BLOCK_COUNT
+ #define MEMORY_MANAGER_LARGE_BLOCK_COUNT 0
+ #define MEMORY_MANAGER_LARGE_BLOCK_SIZE 0
+ #define LARGE_BLOCK_START 0
+ #define LARGE_BLOCK_END 0
+ #define LARGE_MEMORY_START 0
+#endif // MEMORY_MANAGER_LARGE_BLOCK_COUNT
+
+
+/**@brief Setting defaults in case XLarge block not used by application. */
+#ifndef MEMORY_MANAGER_XLARGE_BLOCK_COUNT
+ #define MEMORY_MANAGER_XLARGE_BLOCK_COUNT 0
+ #define MEMORY_MANAGER_XLARGE_BLOCK_SIZE 0
+ #define XLARGE_BLOCK_START 0
+ #define XLARGE_BLOCK_END 0
+ #define XLARGE_MEMORY_START 0
+#endif // MEMORY_MANAGER_XLARGE_BLOCK_COUNT
+
+
+/**@brief Setting defaults in case XXLarge block not used by application. */
+#ifndef MEMORY_MANAGER_XXLARGE_BLOCK_COUNT
+ #define MEMORY_MANAGER_XXLARGE_BLOCK_COUNT 0
+ #define MEMORY_MANAGER_XXLARGE_BLOCK_SIZE 0
+ #define XXLARGE_BLOCK_START 0
+ #define XXLARGE_BLOCK_END 0
+ #define XXLARGE_MEMORY_START 0
+#endif // MEMORY_MANAGER_XXLARGE_BLOCK_COUNT
+
+
+/**@brief Based on which blocks are defined, MAX_MEM_SIZE is determined.
+ *
+ * @note Also, in case none of these are defined, a compile time error is indicated.
+ */
+#if (MEMORY_MANAGER_XXLARGE_BLOCK_COUNT != 0)
+ #define MAX_MEM_SIZE MEMORY_MANAGER_XXLARGE_BLOCK_SIZE
+#elif (MEMORY_MANAGER_XLARGE_BLOCK_COUNT != 0)
+ #define MAX_MEM_SIZE MEMORY_MANAGER_XLARGE_BLOCK_SIZE
+#elif (MEMORY_MANAGER_LARGE_BLOCK_COUNT != 0)
+ #define MAX_MEM_SIZE MEMORY_MANAGER_LARGE_BLOCK_SIZE
+#elif (MEMORY_MANAGER_MEDIUM_BLOCK_COUNT != 0)
+ #define MAX_MEM_SIZE MEMORY_MANAGER_MEDIUM_BLOCK_SIZE
+#elif (MEMORY_MANAGER_SMALL_BLOCK_COUNT != 0)
+ #define MAX_MEM_SIZE MEMORY_MANAGER_SMALL_BLOCK_SIZE
+#elif (MEMORY_MANAGER_XSMALL_BLOCK_COUNT != 0)
+ #define MAX_MEM_SIZE MEMORY_MANAGER_XSMALL_BLOCK_SIZE
+#elif (MEMORY_MANAGER_XXSMALL_BLOCK_COUNT != 0)
+ #define MAX_MEM_SIZE MEMORY_MANAGER_XXSMALL_BLOCK_SIZE
+#else
+ #err "One of MEMORY_MANAGER_SMALL_BLOCK_COUNT, MEMORY_MANAGER_MEDIUM_BLOCK_COUNT or \
+ or MEMORY_MANAGER_LARGE_BLOCK_COUNT should be defined."
+#endif
+
+/**@brief XXSmall block start index in case XXSmall Block is defined. */
+#ifndef XXSMALL_BLOCK_START
+#define XXSMALL_BLOCK_START 0
+#endif // XXSMALL_BLOCK_START
+
+
+/**@brief XSmall block start index in case XSmall Block is defined. */
+#ifndef XSMALL_BLOCK_START
+#define XSMALL_BLOCK_START (XXSMALL_BLOCK_START + MEMORY_MANAGER_XXSMALL_BLOCK_COUNT)
+#endif // XSMALL_BLOCK_START
+
+
+/**@brief Small block start index in case Small Block is defined. */
+#ifndef SMALL_BLOCK_START
+#define SMALL_BLOCK_START (XSMALL_BLOCK_START + MEMORY_MANAGER_XSMALL_BLOCK_COUNT)
+#endif // SMALL_BLOCK_START
+
+
+/**@brief Medium block start index in case Medium Block is defined. */
+#ifndef MEDIUM_BLOCK_START
+#define MEDIUM_BLOCK_START (SMALL_BLOCK_START + MEMORY_MANAGER_SMALL_BLOCK_COUNT)
+#endif // MEDIUM_BLOCK_START
+
+
+/**@brief Large block start index in case Large Block is defined. */
+#ifndef LARGE_BLOCK_START
+#define LARGE_BLOCK_START (MEDIUM_BLOCK_START + MEMORY_MANAGER_MEDIUM_BLOCK_COUNT)
+#endif // LARGE_BLOCK_START
+
+
+/**@brief XLarge block start index in case XLarge Block is defined. */
+#ifndef XLARGE_BLOCK_START
+#define XLARGE_BLOCK_START (LARGE_BLOCK_START + MEMORY_MANAGER_LARGE_BLOCK_COUNT)
+#endif // XLARGE_BLOCK_START
+
+/**@brief XXLarge block start index in case XXLarge Block is defined. */
+#ifndef XXLARGE_BLOCK_START
+#define XXLARGE_BLOCK_START (XLARGE_BLOCK_START + MEMORY_MANAGER_XLARGE_BLOCK_COUNT)
+#endif //XXLARGE_BLOCK_START
+
+
+/**@brief XXSmall block end index in case XXSmall Block is defined. */
+#ifndef XXSMALL_BLOCK_END
+#define XXSMALL_BLOCK_END (XXSMALL_BLOCK_START + MEMORY_MANAGER_XXSMALL_BLOCK_COUNT)
+#endif // XXSMALL_BLOCK_END
+
+/**@brief XSmall block end index in case XSmall Block is defined. */
+#ifndef XSMALL_BLOCK_END
+#define XSMALL_BLOCK_END (XSMALL_BLOCK_START + MEMORY_MANAGER_XSMALL_BLOCK_COUNT)
+#endif // XSMALL_BLOCK_END
+
+
+/**@brief Small block end index in case Small Block is defined. */
+#ifndef SMALL_BLOCK_END
+#define SMALL_BLOCK_END (SMALL_BLOCK_START + MEMORY_MANAGER_SMALL_BLOCK_COUNT)
+#endif // SMALL_BLOCK_END
+
+
+/**@brief Medium block end index in case Medium Block is defined. */
+#ifndef MEDIUM_BLOCK_END
+#define MEDIUM_BLOCK_END (MEDIUM_BLOCK_START + MEMORY_MANAGER_MEDIUM_BLOCK_COUNT)
+#endif // MEDIUM_BLOCK_END
+
+
+/**@brief Large block end index in case Large Block is defined. */
+#ifndef LARGE_BLOCK_END
+#define LARGE_BLOCK_END (LARGE_BLOCK_START + MEMORY_MANAGER_LARGE_BLOCK_COUNT)
+#endif // LARGE_BLOCK_END
+
+
+/**@brief XLarge block end index in case XLarge Block is defined. */
+#ifndef XLARGE_BLOCK_END
+#define XLARGE_BLOCK_END (XLARGE_BLOCK_START + MEMORY_MANAGER_XLARGE_BLOCK_COUNT)
+#endif // XLARGE_BLOCK_END
+
+
+/**@brief XXLarge block end index in case XXLarge Block is defined. */
+#ifndef XXLARGE_BLOCK_END
+#define XXLARGE_BLOCK_END (XXLARGE_BLOCK_START + MEMORY_MANAGER_XXLARGE_BLOCK_COUNT)
+#endif //XXLARGE_BLOCK_END
+
+
+#define XXSMALL_MEMORY_SIZE (MEMORY_MANAGER_XXSMALL_BLOCK_COUNT * MEMORY_MANAGER_XXSMALL_BLOCK_SIZE)
+#define XSMALL_MEMORY_SIZE (MEMORY_MANAGER_XSMALL_BLOCK_COUNT * MEMORY_MANAGER_XSMALL_BLOCK_SIZE)
+#define SMALL_MEMORY_SIZE (MEMORY_MANAGER_SMALL_BLOCK_COUNT * MEMORY_MANAGER_SMALL_BLOCK_SIZE)
+#define MEDIUM_MEMORY_SIZE (MEMORY_MANAGER_MEDIUM_BLOCK_COUNT * MEMORY_MANAGER_MEDIUM_BLOCK_SIZE)
+#define LARGE_MEMORY_SIZE (MEMORY_MANAGER_LARGE_BLOCK_COUNT * MEMORY_MANAGER_LARGE_BLOCK_SIZE)
+#define XLARGE_MEMORY_SIZE (MEMORY_MANAGER_XLARGE_BLOCK_COUNT * MEMORY_MANAGER_XLARGE_BLOCK_SIZE)
+#define XXLARGE_MEMORY_SIZE (MEMORY_MANAGER_XXLARGE_BLOCK_COUNT * MEMORY_MANAGER_XXLARGE_BLOCK_SIZE)
+
+
+/**@brief XXSmall memory start index in case XXSmall Block is defined. */
+#ifndef XXSMALL_MEMORY_START
+#define XXSMALL_MEMORY_START 0
+#endif // XXSMALL_MEMORY_START
+
+
+/**@brief XSmall memory start index in case XSmall Block is defined. */
+#ifndef XSMALL_MEMORY_START
+#define XSMALL_MEMORY_START (XXSMALL_MEMORY_START + XXSMALL_MEMORY_SIZE)
+#endif // XSMALL_MEMORY_START
+
+
+/**@brief Small memory start index in case Small Block is defined. */
+#ifndef SMALL_MEMORY_START
+#define SMALL_MEMORY_START (XSMALL_MEMORY_START + XSMALL_MEMORY_SIZE)
+#endif // SMALL_MEMORY_START
+
+
+/**@brief Medium memory start index in case Medium Block is defined. */
+#ifndef MEDIUM_MEMORY_START
+#define MEDIUM_MEMORY_START (SMALL_MEMORY_START + SMALL_MEMORY_SIZE)
+#endif // MEDIUM_MEMORY_START
+
+
+/**@brief Large memory start index in case Large Block is defined. */
+#ifndef LARGE_MEMORY_START
+#define LARGE_MEMORY_START (MEDIUM_MEMORY_START + MEDIUM_MEMORY_SIZE)
+#endif // LARGE_MEMORY_START
+
+
+/**@brief XLarge memory start index in case XLarge Block is defined. */
+#ifndef XLARGE_MEMORY_START
+#define XLARGE_MEMORY_START (LARGE_MEMORY_START + LARGE_MEMORY_SIZE)
+#endif // XLARGE_MEMORY_START
+
+
+/**@brief XXLarge memory start index in case XXLarge Block is defined. */
+#ifndef XXLARGE_MEMORY_START
+#define XXLARGE_MEMORY_START (XLARGE_MEMORY_START + XLARGE_MEMORY_SIZE)
+#endif // XLARGE_MEMORY_START
+
+
+/**@brief Total count of block managed by the module. */
+#define TOTAL_BLOCK_COUNT (MEMORY_MANAGER_XXSMALL_BLOCK_COUNT + \
+ MEMORY_MANAGER_XSMALL_BLOCK_COUNT + \
+ MEMORY_MANAGER_SMALL_BLOCK_COUNT + \
+ MEMORY_MANAGER_MEDIUM_BLOCK_COUNT + \
+ MEMORY_MANAGER_LARGE_BLOCK_COUNT + \
+ MEMORY_MANAGER_XLARGE_BLOCK_COUNT + \
+ MEMORY_MANAGER_XXLARGE_BLOCK_COUNT)
+
+
+/**@brief Total memory managed by the module. */
+#define TOTAL_MEMORY_SIZE (XXSMALL_MEMORY_SIZE + \
+ XSMALL_MEMORY_SIZE + \
+ SMALL_MEMORY_SIZE + \
+ MEDIUM_MEMORY_SIZE + \
+ LARGE_MEMORY_SIZE + \
+ XLARGE_MEMORY_SIZE + \
+ XXLARGE_MEMORY_SIZE)
+
+
+#define BLOCK_CAT_COUNT 7 /**< Block category count is 7 (xxsmall, xsmall, small, medium, large, xlarge, xxlarge). Having one of the block count to zero has no impact on this count. */
+#define BLOCK_CAT_XXS 0 /**< Extra Extra Small category identifier. */
+#define BLOCK_CAT_XS 1 /**< Extra Small category identifier. */
+#define BLOCK_CAT_SMALL 2 /**< Small category identifier. */
+#define BLOCK_CAT_MEDIUM 3 /**< Medium category identifier. */
+#define BLOCK_CAT_LARGE 4 /**< Large category identifier. */
+#define BLOCK_CAT_XL 5 /**< Extra Large category identifier. */
+#define BLOCK_CAT_XXL 6 /**< Extra Extra Large category identifier. */
+
+#define BITMAP_SIZE 32 /**< Bitmap size for each word used to contain block information. */
+#define BLOCK_BITMAP_ARRAY_SIZE CEIL_DIV(TOTAL_BLOCK_COUNT, BITMAP_SIZE) /**< Determines number of blocks needed for book keeping availability status of all blocks. */
+
+
+/**@brief Lookup table for maximum memory size per block category. */
+static const uint32_t m_block_size[BLOCK_CAT_COUNT] =
+{
+ MEMORY_MANAGER_XXSMALL_BLOCK_SIZE,
+ MEMORY_MANAGER_XSMALL_BLOCK_SIZE,
+ MEMORY_MANAGER_SMALL_BLOCK_SIZE,
+ MEMORY_MANAGER_MEDIUM_BLOCK_SIZE,
+ MEMORY_MANAGER_LARGE_BLOCK_SIZE,
+ MEMORY_MANAGER_XLARGE_BLOCK_SIZE,
+ MEMORY_MANAGER_XXLARGE_BLOCK_SIZE
+};
+
+/**@brief Lookup table for block start index for each block category. */
+static const uint32_t m_block_start[BLOCK_CAT_COUNT] =
+{
+ XXSMALL_BLOCK_START,
+ XSMALL_BLOCK_START,
+ SMALL_BLOCK_START,
+ MEDIUM_BLOCK_START,
+ LARGE_BLOCK_START,
+ XLARGE_BLOCK_START,
+ XXLARGE_BLOCK_START
+};
+
+/**@brief Lookup table for last block index for each block category. */
+static const uint32_t m_block_end[BLOCK_CAT_COUNT] =
+{
+ XXSMALL_BLOCK_END,
+ XSMALL_BLOCK_END,
+ SMALL_BLOCK_END,
+ MEDIUM_BLOCK_END,
+ LARGE_BLOCK_END,
+ XLARGE_BLOCK_END,
+ XXLARGE_BLOCK_END
+};
+
+/**@brief Lookup table for memory start range for each block category. */
+static const uint32_t m_block_mem_start[BLOCK_CAT_COUNT] =
+{
+ XXSMALL_MEMORY_START,
+ XSMALL_MEMORY_START,
+ SMALL_MEMORY_START,
+ MEDIUM_MEMORY_START,
+ LARGE_MEMORY_START,
+ XLARGE_MEMORY_START,
+ XXLARGE_MEMORY_START
+};
+
+static uint8_t m_memory[TOTAL_MEMORY_SIZE]; /**< Memory managed by the module. */
+static uint32_t m_mem_pool[BLOCK_BITMAP_ARRAY_SIZE]; /**< Bitmap used for book-keeping availability of all blocks managed by the module. */
+
+#ifdef MEM_MANAGER_ENABLE_DIAGNOSTICS
+
+/**@brief Lookup table for descriptive strings for each block category. */
+static const char * m_block_desc_str[BLOCK_CAT_COUNT] =
+{
+ "XXSmall",
+ "XSmall",
+ "Small",
+ "Medium",
+ "Large",
+ "XLarge",
+ "XXLarge"
+};
+
+/**@brief Table for book keeping smallest size allocated in each block range. */
+static uint32_t m_min_size[BLOCK_CAT_COUNT] =
+{
+ MEMORY_MANAGER_XXSMALL_BLOCK_SIZE,
+ MEMORY_MANAGER_XSMALL_BLOCK_SIZE,
+ MEMORY_MANAGER_SMALL_BLOCK_SIZE,
+ MEMORY_MANAGER_MEDIUM_BLOCK_SIZE,
+ MEMORY_MANAGER_LARGE_BLOCK_SIZE,
+ MEMORY_MANAGER_XLARGE_BLOCK_SIZE,
+ MEMORY_MANAGER_XXLARGE_BLOCK_SIZE
+};
+
+/**@brief Table for book keeping largest size allocated in each block range. */
+static uint32_t m_max_size[BLOCK_CAT_COUNT];
+
+/**@brief Global pointing to minimum size holder for block type being allocated. */
+static uint32_t * p_min_size;
+
+/**@brief Global pointing to maximum size holder for block type being allocated. */
+static uint32_t * p_max_size;
+
+/**@brief Lookup table for count of block available in each block category. */
+static uint32_t m_block_count[BLOCK_CAT_COUNT] =
+{
+ MEMORY_MANAGER_XXSMALL_BLOCK_COUNT,
+ MEMORY_MANAGER_XSMALL_BLOCK_COUNT,
+ MEMORY_MANAGER_SMALL_BLOCK_COUNT,
+ MEMORY_MANAGER_MEDIUM_BLOCK_COUNT,
+ MEMORY_MANAGER_LARGE_BLOCK_COUNT,
+ MEMORY_MANAGER_XLARGE_BLOCK_COUNT,
+ MEMORY_MANAGER_XXLARGE_BLOCK_COUNT
+};
+
+#endif // MEM_MANAGER_ENABLE_DIAGNOSTICS
+
+SDK_MUTEX_DEFINE(m_mm_mutex) /**< Mutex variable. Currently unused, this declaration does not occupy any space in RAM. */
+#if (MEM_MANAGER_DISABLE_API_PARAM_CHECK == 0)
+static bool m_module_initialized = false; /**< State indicating if module is initialized or not. */
+#endif // MEM_MANAGER_DISABLE_API_PARAM_CHECK
+
+
+/**@brief Function to get X and Y coordinates.
+ *
+ * @details Function to get X and Y co-ordinates for the block identified by index.
+ * Here, X determines relevant word for the block. Y determines the actual bit in the word.
+ *
+ * @param[in] index Identifies the block.
+ * @param[out] p_x Points to the word that contains the bit representing the block.
+ * @param[out] p_y Contains the bitnumber in the the word 'X' relevant to the block.
+ */
+static __INLINE void get_block_coordinates(uint32_t block_index, uint32_t * p_x, uint32_t * p_y)
+{
+ // Determine position of the block in the bitmap.
+ // X determines relevant word for the block. Y determines the actual bit in the word.
+ const uint32_t x = block_index / BITMAP_SIZE;
+ const uint32_t y = (block_index - x * BITMAP_SIZE);
+
+ (*p_x) = x;
+ (*p_y) = y;
+}
+
+
+/**@brief Initializes the block by setting it to be free. */
+static void block_init (uint32_t block_index)
+{
+ uint32_t x;
+ uint32_t y;
+
+ // Determine position of the block in the bitmap.
+ // X determines relevant word for the block. Y determines the actual bit in the word.
+ get_block_coordinates(block_index, &x, &y);
+
+ // Set bit related to the block to indicate that the block is free.
+ SET_BIT(m_mem_pool[x], y);
+}
+
+
+/**@brief Function to get the category of the block of size 'size' or block number 'block_index'.*/
+static __INLINE uint32_t get_block_cat(uint32_t size, uint32_t block_index)
+{
+ for (uint32_t block_cat = 0; block_cat < BLOCK_CAT_COUNT; block_cat++)
+ {
+ if (((size != 0) && (size <= m_block_size[block_cat]) &&
+ (m_block_end[block_cat] != m_block_start[block_cat])) ||
+ (block_index < m_block_end[block_cat]))
+ {
+ return block_cat;
+ }
+ }
+
+ return 0;
+}
+
+
+/**@brief Function to get the size of the block number 'block_index'. */
+static __INLINE uint32_t get_block_size(uint32_t block_index)
+{
+ const uint32_t block_cat = get_block_cat(0, block_index);
+
+ #ifdef MEM_MANAGER_ENABLE_DIAGNOSTICS
+ p_min_size = &m_min_size[block_cat];
+ p_max_size = &m_max_size[block_cat];
+ #endif // MEM_MANAGER_ENABLE_DIAGNOSTICS
+
+ return m_block_size[block_cat];
+}
+
+
+/**@brief Function to free the block identified by block number 'block_index'. */
+static bool is_block_free(uint32_t block_index)
+{
+ uint32_t x;
+ uint32_t y;
+
+ // Determine position of the block in the bitmap.
+ // X determines relevant word for the block. Y determines the actual bit in the word.
+ get_block_coordinates(block_index, &x, &y);
+
+ return IS_SET(m_mem_pool[x], y);
+}
+
+
+/**@brief Function to allocate the block identified by block number 'block_index'. */
+static void block_allocate(uint32_t block_index)
+{
+ uint32_t x;
+ uint32_t y;
+
+ // Determine position of the block in the bitmap.
+ // X determines relevant word for the block. Y determines the actual bit in the word.
+ get_block_coordinates(block_index, &x, &y);
+
+ CLR_BIT(m_mem_pool[x], y);
+}
+
+
+uint32_t nrf_mem_init(void)
+{
+ NRF_LOG_DEBUG(">> %s.", (uint32_t)__func__);
+
+ SDK_MUTEX_INIT(m_mm_mutex);
+
+ MM_MUTEX_LOCK();
+
+ uint32_t block_index = 0;
+
+ for (block_index = 0; block_index < TOTAL_BLOCK_COUNT; block_index++)
+ {
+ block_init(block_index);
+ }
+
+#if (MEM_MANAGER_DISABLE_API_PARAM_CHECK == 0)
+ m_module_initialized = true;
+#endif // MEM_MANAGER_DISABLE_API_PARAM_CHECK
+
+#ifdef MEM_MANAGER_ENABLE_DIAGNOSTICS
+ nrf_mem_diagnose();
+#endif // MEM_MANAGER_ENABLE_DIAGNOSTICS
+
+ MM_MUTEX_UNLOCK();
+
+ NRF_LOG_DEBUG("<< %s.", (uint32_t)__func__);
+
+ return NRF_SUCCESS;
+}
+
+
+uint32_t nrf_mem_reserve(uint8_t ** pp_buffer, uint32_t * p_size)
+{
+ VERIFY_MODULE_INITIALIZED();
+ NULL_PARAM_CHECK(pp_buffer);
+ NULL_PARAM_CHECK(p_size);
+
+ const uint32_t requested_size = (*p_size);
+
+ VERIFY_REQUESTED_SIZE(requested_size);
+
+ NRF_LOG_DEBUG(">> %s, size 0x%04lX.", (uint32_t)__func__, requested_size);
+
+ MM_MUTEX_LOCK();
+
+ const uint32_t block_cat = get_block_cat(requested_size, TOTAL_BLOCK_COUNT);
+ uint32_t block_index = m_block_start[block_cat];
+ uint32_t memory_index = m_block_mem_start[block_cat];
+ uint32_t err_code = (NRF_ERROR_NO_MEM | NRF_ERROR_MEMORY_MANAGER_ERR_BASE);
+
+ NRF_LOG_DEBUG("Start index for the pool = 0x%08lX, total block count 0x%08X",
+ block_index,
+ TOTAL_BLOCK_COUNT);
+
+ for (; block_index < TOTAL_BLOCK_COUNT; block_index++)
+ {
+ uint32_t block_size = get_block_size(block_index);
+
+ if (is_block_free(block_index) == true)
+ {
+ NRF_LOG_DEBUG("Reserving block 0x%08lX", block_index);
+
+ // Search succeeded, found free block.
+ err_code = NRF_SUCCESS;
+
+ // Allocate block.
+ block_allocate(block_index);
+
+ (*pp_buffer) = &m_memory[memory_index];
+ (*p_size) = block_size;
+
+ #ifdef MEM_MANAGER_ENABLE_DIAGNOSTICS
+ (*p_min_size) = MIN((*p_min_size), requested_size);
+ (*p_max_size) = MAX((*p_max_size), requested_size);
+ #endif // MEM_MANAGER_ENABLE_DIAGNOSTICS
+
+ break;
+ }
+ memory_index += block_size;
+ }
+ if (err_code != NRF_SUCCESS)
+ {
+ NRF_LOG_DEBUG("Memory reservation result %d, memory %p, size %d!",
+ err_code,
+ (uint32_t)(*pp_buffer),
+ (*p_size));
+
+ #ifdef MEM_MANAGER_ENABLE_DIAGNOSTICS
+ nrf_mem_diagnose();
+ #endif // MEM_MANAGER_ENABLE_DIAGNOSTICS
+ }
+
+ MM_MUTEX_UNLOCK();
+
+ NRF_LOG_DEBUG("<< %s %p, result 0x%08lX.", (uint32_t)__func__,
+ (uint32_t)(*pp_buffer), err_code);
+
+ return err_code;
+}
+
+
+void * nrf_malloc(uint32_t size)
+{
+ uint8_t * buffer = NULL;
+ uint32_t allocated_size = size;
+
+ uint32_t retval = nrf_mem_reserve(&buffer, &allocated_size);
+
+ if (retval != NRF_SUCCESS)
+ {
+ buffer = NULL;
+ }
+
+ return buffer;
+}
+
+
+void * nrf_calloc(uint32_t count, uint32_t size)
+{
+ uint8_t * buffer = NULL;
+ uint32_t allocated_size = (size * count);
+
+ NRF_LOG_DEBUG("[%s]: Requested size %d, count %d", (uint32_t)__func__, allocated_size, count);
+
+ uint32_t retval = nrf_mem_reserve(&buffer, &allocated_size);
+ if (retval == NRF_SUCCESS)
+ {
+ NRF_LOG_DEBUG("[%s]: buffer %p, total size %d", (uint32_t)__func__, (uint32_t)buffer, allocated_size);
+ memset(buffer,0, allocated_size);
+ }
+ else
+ {
+ NRF_LOG_DEBUG("[%s]: Failed to allocate memory %d", (uint32_t)__func__, allocated_size);
+ buffer = NULL;
+ }
+
+ return buffer;
+}
+
+
+void nrf_free(void * p_mem)
+{
+ VERIFY_MODULE_INITIALIZED_VOID();
+ NULL_PARAM_CHECK_VOID(p_mem);
+
+ NRF_LOG_DEBUG(">> %s %p.", (uint32_t)__func__, (uint32_t)p_mem);
+
+ MM_MUTEX_LOCK();
+
+ uint32_t index;
+ uint32_t memory_index = 0;
+
+ for (index = 0; index < TOTAL_BLOCK_COUNT; index++)
+ {
+ if (&m_memory[memory_index] == p_mem)
+ {
+ // Found a free block of memory, assign.
+ NRF_LOG_DEBUG("<< Freeing block %d.", index);
+ block_init(index);
+ break;
+ }
+ memory_index += get_block_size(index);
+ }
+
+ MM_MUTEX_UNLOCK();
+
+ NRF_LOG_DEBUG("<< %s.", (uint32_t)__func__);
+ return;
+}
+
+
+void * nrf_realloc(void * p_mem, uint32_t size)
+{
+ return p_mem;
+}
+
+
+#ifdef MEM_MANAGER_ENABLE_DIAGNOSTICS
+
+/**@brief Function to format and print information with respect to each block.
+ *
+ * @details Internal function that formats and prints information related to the block category
+ * identified by 'block_cat'. This function also appends the number of bytes in use to
+ * p_mem_in_use based on current count of block in the category.
+ *
+ * @param[in] block_cat Identifies the category of block.
+ * @param[out] p_mem_in_use Updates the memory in use based on count in use.
+ */
+void print_block_info(uint32_t block_cat, uint32_t * p_mem_in_use)
+{
+ #define PRINT_COLUMN_WIDTH 13
+ #define PRINT_BUFFER_SIZE 80
+ #define ASCII_VALUE_FOR_SPACE 32
+
+ char print_buffer[PRINT_BUFFER_SIZE];
+ const uint32_t total_count = (m_block_start[block_cat] + m_block_count[block_cat]);
+ uint32_t in_use = 0;
+ uint32_t num_of_blocks = 0;
+ uint32_t index = m_block_start[block_cat];
+ uint32_t column_number;
+
+ // No statistic provided in case block category is not included.
+ if (m_block_count[block_cat] != 0)
+ {
+ memset(print_buffer, ASCII_VALUE_FOR_SPACE, PRINT_BUFFER_SIZE);
+
+ for (; index < total_count; index++)
+ {
+ if (is_block_free(index) == false)
+ {
+ num_of_blocks++;
+ in_use += m_block_size[block_cat];
+ }
+ }
+
+ column_number = 0;
+ snprintf(&print_buffer[column_number * PRINT_COLUMN_WIDTH],
+ PRINT_COLUMN_WIDTH,
+ "| %s",
+ m_block_desc_str[block_cat]);
+
+ column_number++;
+ snprintf(&print_buffer[column_number * PRINT_COLUMN_WIDTH],
+ PRINT_COLUMN_WIDTH,
+ "| %d",
+ m_block_size[block_cat]);
+
+ column_number++;
+ snprintf(&print_buffer[column_number * PRINT_COLUMN_WIDTH],
+ PRINT_COLUMN_WIDTH,
+ "| %d",
+ m_block_count[block_cat]);
+
+ column_number++;
+ snprintf(&print_buffer[column_number * PRINT_COLUMN_WIDTH],
+ PRINT_COLUMN_WIDTH,
+ "| %d",
+ num_of_blocks);
+
+ column_number++;
+ snprintf(&print_buffer[column_number * PRINT_COLUMN_WIDTH],
+ PRINT_COLUMN_WIDTH,
+ "| %d",
+ m_min_size[block_cat]);
+
+ column_number++;
+ snprintf(&print_buffer[column_number * PRINT_COLUMN_WIDTH],
+ PRINT_COLUMN_WIDTH,
+ "| %d",
+ m_max_size[block_cat]);
+
+ column_number++;
+ const uint32_t column_end = (column_number * PRINT_COLUMN_WIDTH);
+
+ for (int j = 0; j < column_end; j ++)
+ {
+ if (print_buffer[j] == 0)
+ {
+ print_buffer[j] = 0x20;
+ }
+ }
+ snprintf(&print_buffer[column_end], 2, "|");
+
+ NRF_LOG_BYTES_DEBUG(print_buffer, strlen(print_buffer));
+
+ (*p_mem_in_use) += in_use;
+ }
+}
+
+
+void nrf_mem_diagnose(void)
+{
+ uint32_t in_use = 0;
+
+ NRF_LOG_DEBUG("");
+ NRF_LOG_DEBUG("+------------+------------+------------+------------+------------+------------+");
+ NRF_LOG_DEBUG("| Block | Size | Total | In Use | Min Alloc | Max Alloc |");
+ NRF_LOG_DEBUG("+------------+------------+------------+------------+------------+------------+");
+
+ print_block_info(BLOCK_CAT_XXS, &in_use);
+ print_block_info(BLOCK_CAT_XS, &in_use);
+ print_block_info(BLOCK_CAT_SMALL, &in_use);
+ print_block_info(BLOCK_CAT_MEDIUM, &in_use);
+ print_block_info(BLOCK_CAT_LARGE, &in_use);
+ print_block_info(BLOCK_CAT_XL, &in_use);
+ print_block_info(BLOCK_CAT_XXL, &in_use);
+
+ NRF_LOG_DEBUG("+------------+------------+------------+------------+------------+------------+");
+ NRF_LOG_DEBUG("| Total | %d | %d | %d",
+ TOTAL_MEMORY_SIZE, TOTAL_BLOCK_COUNT,in_use);
+ NRF_LOG_DEBUG("+------------+------------+------------+------------+------------+------------+");
+}
+
+#endif // MEM_MANAGER_ENABLE_DIAGNOSTICS
+/** @} */
+#endif //NRF_MODULE_ENABLED(MEM_MANAGER)
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/mem_manager/mem_manager.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/mem_manager/mem_manager.h
new file mode 100644
index 0000000..5030578
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/mem_manager/mem_manager.h
@@ -0,0 +1,175 @@
+/**
+ * Copyright (c) 2014 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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
+ *
+ * @defgroup mem_manager Memory Manager
+ * @{
+ * @ingroup app_common
+ * @brief Memory Manager for the @nRFXX SDK
+ *
+ * @details This module allows for dynamic use of memory. Currently,
+ * this module can be used only to allocate and free memory in the RAM.
+ *
+ * The Memory Manager manages static memory blocks of fixed sizes. These blocks can be requested for
+ * usage, and freed when the application no longer needs them. A maximum of seven block categories
+ * can be managed by the module. These block categories are identified by xxsmall, xmall, small,
+ * medium, large, xlarge, and xxlarge. They are ordered in increasing block sizes.
+ * The size and the count of each of the block categories can be configured based on the application
+ * requirements in the configuration file @c sdk_config.h.
+ * To use fewer than seven buffer pools, do not define the count for the unwanted block
+ * or explicitly set it to zero. At least one block category must be configured
+ * for this module to function as expected.
+ */
+
+#ifndef MEM_MANAGER_H__
+#define MEM_MANAGER_H__
+
+#include "sdk_common.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+/**@brief Initializes Memory Manager.
+ *
+ * @details API to initialize the Memory Manager. Always call this API before using any of the other
+ * APIs of the module. This API should be called only once.
+ *
+ * @retval NRF_SUCCESS If initialization was successful.
+ * Otherwise, an error code that indicates the reason for the failure is returned.
+ *
+ * @warning If this API fails, the application shall not proceed with using other APIs of this
+ * module.
+ */
+uint32_t nrf_mem_init(void);
+
+
+/**@brief Reserves a block of memory for the application.
+ *
+ * @details API to request a contiguous memory block of the given length. If
+ * the memory allocation succeeds, pp_buffer points to the memory block. If
+ * the memory allocation fails, pp_buffer points to NULL and the return value of
+ * the API indicates the reason for the failure. The memory block reserved using this API can
+ * be freed using the @ref nrf_free function.
+ *
+ * @param[out] pp_buffer Pointer to the allocated memory block if memory allocation
+ * succeeds; otherwise points to NULL.
+ * @param[inout] p_size Requested memory size. This parameter returns the actual size
+ * allocated. If the procedure was successful, the actual size
+ * returned is always greater than or equal to requested size,
+ * never less.
+ *
+ * @retval NRF_SUCCESS If memory was successfully allocated.
+ * Otherwise, an error code indicating the reason for failure.
+ * @retval NRF_ERROR_INVALID_PARAM If the requested memory size is zero or greater than the
+ * largest memory block that the module is configured to
+ * support.
+ * @retval NRF_ERROR_NO_MEM If there is no memory available of the requested size.
+ */
+uint32_t nrf_mem_reserve(uint8_t ** pp_buffer, uint32_t * p_size);
+
+
+/**@brief 'malloc' styled memory allocation function.
+ *
+ * @details API to allocate memory, same as nrf_mem_reserve but uses malloc signature.
+ *
+ * @param[in] size Requested memory size.
+ *
+ * @retval Valid memory location if the procedure was successful, else, NULL.
+ */
+void * nrf_malloc(uint32_t size);
+
+
+/**@brief 'calloc' styled memory allocation function.
+ *
+ * @details API to allocate zero-initialized memory of size count*size.
+ *
+ * @param[in] nmemb Number of elements of 'size' bytes.
+ * @param[in] size Size of each element allocated.
+ *
+ * @retval Valid, zero-initialized memory location if the procedure was successful, else, NULL.
+ */
+void * nrf_calloc(uint32_t nmemb, uint32_t size);
+
+
+/**@brief Free allocated memory - standard 'free' styles API.
+ *
+ * @details API to resubmit memory allocated, same in functionality nrf_free.
+ *
+ * @param[out] p_buffer Pointer to the memory block that is being freed.
+ */
+void nrf_free(void * p_buffer);
+
+
+/**@brief Memory reallocation (trim) function.
+ *
+ * @details API to reallocate memory or to trim it. Trim is mentioned here to avoid use of API to
+ * request memory size larger than original memory allocated.
+ *
+ * @param[in] p_buffer Pointer to the memory block that needs to be trimmed.
+ * @param[in] size Size of memory at the beginning of the buffer to be left untrimmed.
+ *
+ * @retval Pointer to memory location with trimmed size, else, NULL.
+ */
+void * nrf_realloc(void *p_buffer, uint32_t size);
+
+#ifdef MEM_MANAGER_ENABLE_DIAGNOSTICS
+
+/**@brief Function to print statistics related to memory blocks managed by memory manager.
+ *
+ * @details This API prints information with respects to each block function, including size, total
+ * block count, number of blocks in use at the time of printing, smallest memory size
+ * allocated in the block and the largest one. This API is intended to help developers
+ * tune the block sizes to make optimal use of memory for the application.
+ * This functionality is never needed in final application and therefore, is disabled by
+ * default.
+ */
+void nrf_mem_diagnose(void);
+
+#endif // MEM_MANAGER_ENABLE_DIAGNOSTICS
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // MEM_MANAGER_H__
+/** @} */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/mutex/nrf_mtx.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/mutex/nrf_mtx.h
new file mode 100644
index 0000000..2e1b553
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/mutex/nrf_mtx.h
@@ -0,0 +1,159 @@
+/**
+ * Copyright (c) 2015 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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
+ * @defgroup nrf_mtx nRF Mutex
+ * @{
+ * @ingroup app_common
+ * @brief Mutex used for protecting resources.
+ *
+ * This module provides a mutex that can be used to ensure only one context may enter a critical
+ * section holding the lock.
+ */
+#ifndef NRF_MTX_H__
+#define NRF_MTX_H__
+
+#include <stdint.h>
+#include <stdbool.h>
+#include "nrf.h"
+#include "nrf_atomic.h"
+#include "nrf_assert.h"
+
+#define NRF_MTX_LOCKED 1
+#define NRF_MTX_UNLOCKED 0
+
+/**
+ * @brief Mutex data type.
+ *
+ * All fields in this struct are internal, and should never be modified outside of the nrf_mtx_*
+ * functions.
+ */
+typedef nrf_atomic_u32_t nrf_mtx_t;
+
+/**
+ * @brief Initialize mutex.
+ *
+ * This function _must_ be called before nrf_mtx_trylock() and nrf_mtx_unlock() functions.
+ *
+ * @param[in, out] p_mtx The mutex to be initialized.
+ */
+__STATIC_INLINE void nrf_mtx_init(nrf_mtx_t * p_mtx);
+
+
+/**
+ * @brief Destroy mutex.
+ *
+ * This function can be used in abort scenarios or when the mutex is no longer to be used.
+ *
+ * @param[in] p_mtx The mutex to be destroy.
+ */
+__STATIC_INLINE void nrf_mtx_destroy(nrf_mtx_t * p_mtx);
+
+/**
+ * @brief Try to lock a mutex.
+ *
+ * If the mutex is already held by another context, this function will return immediately.
+ *
+ * @param[in, out] p_mtx The mutex to be locked.
+ * @return true if lock was acquired, false if not
+ */
+__STATIC_INLINE bool nrf_mtx_trylock(nrf_mtx_t * p_mtx);
+
+/**
+ * @brief Unlock a mutex.
+ *
+ * This function _must_ only be called when holding the lock. Unlocking a mutex which you do not
+ * hold will give undefined behavior.
+ *
+ * @note Unlock must happen from the same context as the one used to lock the mutex.
+ *
+ * @param[in, out] p_mtx The mutex to be unlocked.
+ */
+__STATIC_INLINE void nrf_mtx_unlock(nrf_mtx_t * p_mtx);
+
+#ifndef SUPPRESS_INLINE_IMPLEMENTATION
+
+__STATIC_INLINE void nrf_mtx_init(nrf_mtx_t * p_mtx)
+{
+ ASSERT(p_mtx != NULL);
+
+ *p_mtx = NRF_MTX_UNLOCKED;
+ __DMB();
+}
+
+__STATIC_INLINE void nrf_mtx_destroy(nrf_mtx_t * p_mtx)
+{
+ ASSERT(p_mtx != NULL);
+
+ // Add memory barrier to ensure that any memory operations protected by the mutex complete
+ // before the mutex is destroyed.
+ __DMB();
+
+ *p_mtx = NRF_MTX_UNLOCKED;
+}
+
+__STATIC_INLINE bool nrf_mtx_trylock(nrf_mtx_t * p_mtx)
+{
+ ASSERT(p_mtx != NULL);
+
+ uint32_t old_val = nrf_atomic_u32_fetch_store(p_mtx, NRF_MTX_LOCKED);
+
+ // Add memory barrier to ensure that the mutex is locked before any memory operations protected
+ // by the mutex are started.
+ __DMB();
+
+ return (old_val == NRF_MTX_UNLOCKED);
+}
+
+__STATIC_INLINE void nrf_mtx_unlock(nrf_mtx_t * p_mtx)
+{
+ ASSERT(p_mtx != NULL);
+ ASSERT(*p_mtx == NRF_MTX_LOCKED);
+
+ // Add memory barrier to ensure that any memory operations protected by the mutex complete
+ // before the mutex is unlocked.
+ __DMB();
+
+ *p_mtx = NRF_MTX_UNLOCKED;
+}
+
+#endif //SUPPRESS_INLINE_IMPLEMENTATION
+
+#endif // NRF_MTX_H__
+/** @} */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/pwm/app_pwm.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/pwm/app_pwm.c
new file mode 100644
index 0000000..a549010
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/pwm/app_pwm.c
@@ -0,0 +1,1009 @@
+/**
+ * Copyright (c) 2015 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#include "sdk_common.h"
+#if NRF_MODULE_ENABLED(APP_PWM)
+#include "app_pwm.h"
+#include "nrf_drv_timer.h"
+#include "nrf_drv_ppi.h"
+#include "nrf_drv_gpiote.h"
+#include "nrf_gpiote.h"
+#include "nrf_gpio.h"
+#include "app_util_platform.h"
+#include "nrf_assert.h"
+
+#define APP_PWM_CHANNEL_INITIALIZED 1
+#define APP_PWM_CHANNEL_UNINITIALIZED 0
+
+#define APP_PWM_CHANNEL_ENABLED 1
+#define APP_PWM_CHANNEL_DISABLED 0
+
+#define TIMER_PRESCALER_MAX 9
+#define TIMER_MAX_PULSEWIDTH_US_ON_16M 4095
+
+#ifndef GPIOTE_SET_CLEAR_TASKS
+#define APP_PWM_REQUIRED_PPI_CHANNELS_PER_INSTANCE 2
+#endif
+#define APP_PWM_REQUIRED_PPI_CHANNELS_PER_CHANNEL 2
+
+#define UNALLOCATED 0xFFFFFFFFUL
+#define BUSY_STATE_CHANGING 0xFE
+#define BUSY_STATE_IDLE 0xFF
+
+#define PWM_MAIN_CC_CHANNEL 2
+#define PWM_SECONDARY_CC_CHANNEL 3
+
+#ifdef GPIOTE_SET_CLEAR_TASKS
+static bool m_use_ppi_delay_workaround;
+#endif
+
+
+/**
+ * @brief PWM busy status
+ *
+ * Stores the number of a channel being currently updated.
+ *
+ */
+static volatile uint8_t m_pwm_busy[TIMER_COUNT];
+
+
+/**
+ * @brief New duty cycle value
+ *
+ * When the channel duty cycle reaches this value, the update process is complete.
+ */
+static volatile uint32_t m_pwm_target_value[TIMER_COUNT];
+
+
+/**
+ * @brief PWM ready counter
+ *
+ * The value in this counter is decremented in every PWM cycle after initiating the update.
+ * If an event handler function was specified by the user, it is being called
+ * after two cycle events (at least one full PWM cycle).
+ */
+volatile uint8_t m_pwm_ready_counter[TIMER_COUNT][APP_PWM_CHANNELS_PER_INSTANCE];
+
+/**
+ * @brief Pointers to instances
+ *
+ * This array connects any active timer instance number with the pointer to the PWM instance.
+ * It is used by the interrupt runtime.
+ */
+static const app_pwm_t * m_instances[TIMER_COUNT];
+
+// Macros for getting the polarity of given instance/channel.
+#define POLARITY_ACTIVE(INST,CH) (( ((INST)->p_cb)->channels_cb[(CH)].polarity == \
+ APP_PWM_POLARITY_ACTIVE_LOW)?(0):(1))
+#define POLARITY_INACTIVE(INST,CH) (( ((INST)->p_cb)->channels_cb[(CH)].polarity == \
+ APP_PWM_POLARITY_ACTIVE_LOW)?(1):(0))
+
+//lint -save -e534
+
+
+/**
+ * @brief Workaround for PAN-73.
+ *
+ * @param[in] timer Timer.
+ * @param[in] enable Enable or disable.
+ */
+static void pan73_workaround(NRF_TIMER_Type * p_timer, bool enable)
+{
+#ifndef GPIOTE_SET_CLEAR_TASKS
+ if (p_timer == NRF_TIMER0)
+ {
+ *(uint32_t *)0x40008C0C = (enable ? 1 : 0);
+ }
+ else if (p_timer == NRF_TIMER1)
+ {
+ *(uint32_t *)0x40009C0C = (enable ? 1 : 0);
+ }
+ else if (p_timer == NRF_TIMER2)
+ {
+ *(uint32_t *)0x4000AC0C = (enable ? 1 : 0);
+ }
+#else
+ UNUSED_PARAMETER(p_timer);
+ UNUSED_PARAMETER(enable);
+#endif
+}
+
+bool app_pwm_busy_check(app_pwm_t const * const p_instance)
+{
+ uint8_t busy_state = (m_pwm_busy[p_instance->p_timer->instance_id]);
+ bool busy = true;
+ if (busy_state != BUSY_STATE_IDLE)
+ {
+ if (busy_state != BUSY_STATE_CHANGING)
+ {
+ if (nrf_drv_timer_capture_get(p_instance->p_timer, (nrf_timer_cc_channel_t) busy_state)
+ == m_pwm_target_value[p_instance->p_timer->instance_id])
+ {
+ m_pwm_busy[p_instance->p_timer->instance_id] = BUSY_STATE_IDLE;
+ busy = false;
+ }
+ }
+ }
+ else
+ {
+ busy = false;
+ }
+ return busy;
+}
+
+
+/**
+ * @brief Function for enabling the IRQ for a given PWM instance.
+ *
+ * @param[in] p_instance PWM instance.
+ */
+__STATIC_INLINE void pwm_irq_enable(app_pwm_t const * const p_instance)
+{
+ nrf_drv_timer_compare_int_enable(p_instance->p_timer, PWM_MAIN_CC_CHANNEL);
+}
+
+
+/**
+ * @brief Function for disabling the IRQ for a given PWM instance.
+ *
+ * @param[in] p_instance PWM instance.
+ */
+__STATIC_INLINE void pwm_irq_disable(app_pwm_t const * const p_instance)
+{
+ nrf_drv_timer_compare_int_disable(p_instance->p_timer, PWM_MAIN_CC_CHANNEL);
+}
+
+#ifndef GPIOTE_SET_CLEAR_TASKS
+/**
+ * @brief Function for disabling PWM channel PPI.
+ *
+ * @param[in] p_instance PWM instance.
+ */
+__STATIC_INLINE void pwm_channel_ppi_disable(app_pwm_t const * const p_instance, uint8_t channel)
+{
+ app_pwm_cb_t * p_cb = p_instance->p_cb;
+
+ nrf_drv_ppi_channel_disable(p_cb->channels_cb[channel].ppi_channels[0]);
+ nrf_drv_ppi_channel_disable(p_cb->channels_cb[channel].ppi_channels[1]);
+}
+
+
+/**
+ * @brief Function for disabling PWM PPI.
+ *
+ * @param[in] p_instance PWM instance.
+ */
+__STATIC_INLINE void pwm_ppi_disable(app_pwm_t const * const p_instance)
+{
+ app_pwm_cb_t * p_cb = p_instance->p_cb;
+
+ nrf_drv_ppi_channel_disable(p_cb->ppi_channels[0]);
+ nrf_drv_ppi_channel_disable(p_cb->ppi_channels[1]);
+}
+#endif
+
+/**
+ * @brief This function is called on interrupt after duty set.
+ *
+ * @param[in] timer Timer used by PWM.
+ * @param[in] timer_instance_id Timer index.
+ */
+void pwm_ready_tick(nrf_timer_event_t event_type, void * p_context)
+{
+ uint32_t timer_instance_id = (uint32_t)p_context;
+ uint8_t disable = 1;
+
+ for (uint8_t channel = 0; channel < APP_PWM_CHANNELS_PER_INSTANCE; ++channel)
+ {
+ if (m_pwm_ready_counter[timer_instance_id][channel])
+ {
+ --m_pwm_ready_counter[timer_instance_id][channel];
+ if (!m_pwm_ready_counter[timer_instance_id][channel])
+ {
+ app_pwm_cb_t * p_cb = m_instances[timer_instance_id]->p_cb;
+ p_cb->p_ready_callback(timer_instance_id);
+ }
+ else
+ {
+ disable = 0;
+ }
+ }
+ }
+
+ if (disable)
+ {
+ pwm_irq_disable(m_instances[timer_instance_id]);
+ }
+}
+
+
+/**
+ * @brief Function for resource de-allocation.
+ *
+ * @param[in] p_instance PWM instance.
+ */
+//lint -e{650}
+static void pwm_dealloc(app_pwm_t const * const p_instance)
+{
+ app_pwm_cb_t * p_cb = p_instance->p_cb;
+
+#ifdef GPIOTE_SET_CLEAR_TASKS
+ nrf_drv_ppi_channel_free(p_cb->ppi_channel);
+#else
+ for (uint8_t i = 0; i < APP_PWM_REQUIRED_PPI_CHANNELS_PER_INSTANCE; ++i)
+ {
+ if (p_cb->ppi_channels[i] != (nrf_ppi_channel_t)(uint8_t)(UNALLOCATED))
+ {
+ nrf_drv_ppi_channel_free(p_cb->ppi_channels[i]);
+ }
+ }
+ if (p_cb->ppi_group != (nrf_ppi_channel_group_t)UNALLOCATED)
+ {
+ nrf_drv_ppi_group_free(p_cb->ppi_group);
+ }
+#endif //GPIOTE_SET_CLEAR_TASKS
+ for (uint8_t ch = 0; ch < APP_PWM_CHANNELS_PER_INSTANCE; ++ch)
+ {
+ for (uint8_t i = 0; i < APP_PWM_REQUIRED_PPI_CHANNELS_PER_CHANNEL; ++i)
+ {
+ if (p_cb->channels_cb[ch].ppi_channels[i] != (nrf_ppi_channel_t)UNALLOCATED)
+ {
+ nrf_drv_ppi_channel_free(p_cb->channels_cb[ch].ppi_channels[i]);
+ p_cb->channels_cb[ch].ppi_channels[i] = (nrf_ppi_channel_t)UNALLOCATED;
+ }
+ }
+ if (p_cb->channels_cb[ch].gpio_pin != UNALLOCATED)
+ {
+ nrf_drv_gpiote_out_uninit(p_cb->channels_cb[ch].gpio_pin);
+ p_cb->channels_cb[ch].gpio_pin = UNALLOCATED;
+ }
+ p_cb->channels_cb[ch].initialized = APP_PWM_CHANNEL_UNINITIALIZED;
+ }
+ nrf_drv_timer_uninit(p_instance->p_timer);
+ return;
+}
+
+#ifndef GPIOTE_SET_CLEAR_TASKS
+/**
+ * @brief PWM state transition from (0%, 100%) to 0% or 100%.
+ *
+ * @param[in] p_instance PWM instance.
+ * @param[in] channel PWM channel number.
+ * @param[in] ticks Number of clock ticks.
+ */
+static void pwm_transition_n_to_0or100(app_pwm_t const * const p_instance,
+ uint8_t channel, uint16_t ticks)
+{
+ app_pwm_cb_t * p_cb = p_instance->p_cb;
+ app_pwm_channel_cb_t * p_ch_cb = &p_cb->channels_cb[channel];
+ nrf_ppi_channel_group_t p_ppigrp = p_cb->ppi_group;
+
+ pwm_ppi_disable(p_instance);
+ nrf_drv_ppi_group_clear(p_ppigrp);
+ nrf_drv_ppi_channels_include_in_group(
+ nrf_drv_ppi_channel_to_mask(p_ch_cb->ppi_channels[0]) |
+ nrf_drv_ppi_channel_to_mask(p_ch_cb->ppi_channels[1]),
+ p_ppigrp);
+
+ if (!ticks)
+ {
+ nrf_drv_ppi_channel_assign(p_cb->ppi_channels[0],
+ nrf_drv_timer_compare_event_address_get(p_instance->p_timer, channel),
+ nrf_drv_ppi_task_addr_group_disable_get(p_ppigrp));
+ nrf_drv_timer_compare(p_instance->p_timer, (nrf_timer_cc_channel_t) PWM_SECONDARY_CC_CHANNEL, 0, false);
+ m_pwm_target_value[p_instance->p_timer->instance_id] =
+ nrf_drv_timer_capture_get(p_instance->p_timer, (nrf_timer_cc_channel_t) channel);
+ nrf_drv_ppi_channel_assign(p_cb->ppi_channels[1],
+ nrf_drv_timer_compare_event_address_get(p_instance->p_timer, channel),
+ nrf_drv_timer_capture_task_address_get(p_instance->p_timer, PWM_SECONDARY_CC_CHANNEL));
+ }
+ else
+ {
+ ticks = p_cb->period;
+ nrf_drv_ppi_channel_assign(p_cb->ppi_channels[0],
+ nrf_drv_timer_compare_event_address_get(p_instance->p_timer, PWM_MAIN_CC_CHANNEL),
+ nrf_drv_ppi_task_addr_group_disable_get(p_ppigrp));
+ // Set secondary CC channel to non-zero value:
+ nrf_drv_timer_compare(p_instance->p_timer, (nrf_timer_cc_channel_t) PWM_SECONDARY_CC_CHANNEL, 1, false);
+ m_pwm_target_value[p_instance->p_timer->instance_id] = 0;
+ // The captured value will be equal to 0, because timer clear on main PWM CC channel compare is enabled.
+ nrf_drv_ppi_channel_assign(p_cb->ppi_channels[1],
+ nrf_drv_timer_compare_event_address_get(p_instance->p_timer, PWM_MAIN_CC_CHANNEL),
+ nrf_drv_timer_capture_task_address_get(p_instance->p_timer, PWM_SECONDARY_CC_CHANNEL));
+ }
+
+ nrf_drv_ppi_channel_enable(p_cb->ppi_channels[0]);
+ nrf_drv_ppi_channel_enable(p_cb->ppi_channels[1]);
+
+ p_ch_cb->pulsewidth = ticks;
+ m_pwm_busy[p_instance->p_timer->instance_id] = PWM_SECONDARY_CC_CHANNEL;
+}
+
+
+/**
+ * @brief PWM state transition from (0%, 100%) to (0%, 100%).
+ *
+ * @param[in] p_instance PWM instance.
+ * @param[in] channel PWM channel number.
+ * @param[in] ticks Number of clock ticks.
+ */
+static void pwm_transition_n_to_m(app_pwm_t const * const p_instance,
+ uint8_t channel, uint16_t ticks)
+{
+ app_pwm_cb_t * p_cb = p_instance->p_cb;
+ app_pwm_channel_cb_t * p_ch_cb = &p_cb->channels_cb[channel];
+ nrf_ppi_channel_group_t p_ppigrp = p_cb->ppi_group;
+
+ pwm_ppi_disable(p_instance);
+ nrf_drv_ppi_group_clear(p_ppigrp);
+ nrf_drv_ppi_channels_include_in_group(
+ nrf_drv_ppi_channel_to_mask(p_cb->ppi_channels[0]) |
+ nrf_drv_ppi_channel_to_mask(p_cb->ppi_channels[1]),
+ p_ppigrp);
+
+ nrf_drv_ppi_channel_assign(p_cb->ppi_channels[0],
+ nrf_drv_timer_compare_event_address_get(p_instance->p_timer, PWM_SECONDARY_CC_CHANNEL),
+ nrf_drv_timer_capture_task_address_get(p_instance->p_timer, channel));
+
+
+ if (ticks + ((nrf_timer_frequency_get(p_instance->p_timer->p_reg) == NRF_TIMER_FREQ_16MHz) ? 1 : 0)
+ < p_ch_cb->pulsewidth)
+ {
+ // For lower value, we need one more transition. Timer task delay is included.
+ // If prescaler is disabled, one tick must be added because of 1 PCLK16M clock cycle delay.
+ nrf_drv_ppi_channel_assign(p_cb->ppi_channels[1],
+ nrf_drv_timer_compare_event_address_get(p_instance->p_timer, PWM_SECONDARY_CC_CHANNEL),
+ nrf_drv_gpiote_out_task_addr_get(p_ch_cb->gpio_pin));
+ }
+ else
+ {
+ nrf_drv_ppi_channel_remove_from_group(p_cb->ppi_channels[1], p_ppigrp);
+ }
+ p_ch_cb->pulsewidth = ticks;
+ nrf_drv_timer_compare(p_instance->p_timer, (nrf_timer_cc_channel_t) PWM_SECONDARY_CC_CHANNEL, ticks, false);
+ nrf_drv_ppi_group_enable(p_ppigrp);
+
+ m_pwm_target_value[p_instance->p_timer->instance_id] = ticks;
+ m_pwm_busy[p_instance->p_timer->instance_id] = channel;
+}
+
+
+/**
+ * @brief PWM state transition from 0% or 100% to (0%, 100%).
+ *
+ * @param[in] p_instance PWM instance.
+ * @param[in] channel PWM channel number.
+ * @param[in] ticks Number of clock ticks.
+ */
+static void pwm_transition_0or100_to_n(app_pwm_t const * const p_instance,
+ uint8_t channel, uint16_t ticks)
+{
+ app_pwm_cb_t * p_cb = p_instance->p_cb;
+ app_pwm_channel_cb_t * p_ch_cb = &p_cb->channels_cb[channel];
+ nrf_ppi_channel_group_t p_ppigrp = p_cb->ppi_group;
+ nrf_timer_cc_channel_t pwm_ch_cc = (nrf_timer_cc_channel_t)(channel);
+
+ pwm_ppi_disable(p_instance);
+ pwm_channel_ppi_disable(p_instance, channel);
+
+ nrf_drv_timer_compare(p_instance->p_timer, pwm_ch_cc, ticks, false);
+ nrf_drv_ppi_group_clear(p_ppigrp);
+ nrf_drv_ppi_channels_include_in_group(
+ nrf_drv_ppi_channel_to_mask(p_ch_cb->ppi_channels[0])|
+ nrf_drv_ppi_channel_to_mask(p_ch_cb->ppi_channels[1]),
+ p_ppigrp);
+
+ if (!p_ch_cb->pulsewidth)
+ {
+ // Channel is at 0%.
+ nrf_drv_ppi_channel_assign(p_cb->ppi_channels[0],
+ nrf_drv_timer_compare_event_address_get(p_instance->p_timer, channel),
+ nrf_drv_ppi_task_addr_group_enable_get(p_ppigrp));
+ nrf_drv_timer_compare(p_instance->p_timer, (nrf_timer_cc_channel_t) PWM_SECONDARY_CC_CHANNEL, 0, false);
+ m_pwm_target_value[p_instance->p_timer->instance_id] =
+ nrf_drv_timer_capture_get(p_instance->p_timer, (nrf_timer_cc_channel_t) channel);
+ nrf_drv_ppi_channel_assign(p_cb->ppi_channels[1],
+ nrf_drv_timer_compare_event_address_get(p_instance->p_timer, channel),
+ nrf_drv_timer_capture_task_address_get(p_instance->p_timer, PWM_SECONDARY_CC_CHANNEL));
+
+ }
+ else
+ {
+ // Channel is at 100%.
+ nrf_drv_ppi_channel_assign(p_cb->ppi_channels[0],
+ nrf_drv_timer_compare_event_address_get(p_instance->p_timer, PWM_MAIN_CC_CHANNEL),
+ nrf_drv_ppi_task_addr_group_enable_get(p_ppigrp));
+ // Set secondary CC channel to non-zero value:
+ nrf_drv_timer_compare(p_instance->p_timer, (nrf_timer_cc_channel_t) PWM_SECONDARY_CC_CHANNEL, 1, false);
+ m_pwm_target_value[p_instance->p_timer->instance_id] = 0;
+ // The captured value will be equal to 0, because timer clear on main PWM CC channel compare is enabled.
+ nrf_drv_ppi_channel_assign(p_cb->ppi_channels[1],
+ nrf_drv_timer_compare_event_address_get(p_instance->p_timer, PWM_MAIN_CC_CHANNEL),
+ nrf_drv_timer_capture_task_address_get(p_instance->p_timer, PWM_SECONDARY_CC_CHANNEL));
+ }
+ nrf_drv_ppi_channel_enable(p_cb->ppi_channels[0]);
+ nrf_drv_ppi_channel_enable(p_cb->ppi_channels[1]);
+
+ p_ch_cb->pulsewidth = ticks;
+ m_pwm_busy[p_instance->p_timer->instance_id] = PWM_SECONDARY_CC_CHANNEL;
+}
+
+
+/**
+ * @brief PWM state transition from 0% or 100% to 0% or 100%.
+ *
+ * @param[in] p_instance PWM instance.
+ * @param[in] channel PWM channel number.
+ * @param[in] ticks Number of clock ticks.
+ */
+static void pwm_transition_0or100_to_0or100(app_pwm_t const * const p_instance,
+ uint8_t channel, uint16_t ticks)
+{
+ app_pwm_cb_t * p_cb = p_instance->p_cb;
+ app_pwm_channel_cb_t * p_ch_cb = &p_cb->channels_cb[channel];
+ nrf_timer_cc_channel_t pwm_ch_cc = (nrf_timer_cc_channel_t)(channel);
+
+ pwm_ppi_disable(p_instance);
+ pwm_channel_ppi_disable(p_instance, channel);
+ if (!ticks)
+ {
+ // Set to 0%.
+ nrf_drv_gpiote_out_task_force(p_ch_cb->gpio_pin, POLARITY_INACTIVE(p_instance, channel));
+ }
+ else if (ticks >= p_cb->period)
+ {
+ // Set to 100%.
+ ticks = p_cb->period;
+ nrf_drv_gpiote_out_task_force(p_ch_cb->gpio_pin, POLARITY_ACTIVE(p_instance, channel));
+ }
+ nrf_drv_timer_compare(p_instance->p_timer, pwm_ch_cc, ticks, false);
+ p_ch_cb->pulsewidth = ticks;
+
+ m_pwm_busy[p_instance->p_timer->instance_id] = BUSY_STATE_IDLE;
+ return;
+}
+
+static void pwm_transition(app_pwm_t const * const p_instance,
+ uint8_t channel, uint16_t ticks)
+{
+ app_pwm_cb_t * p_cb = p_instance->p_cb;
+ app_pwm_channel_cb_t * p_ch_cb = &p_instance->p_cb->channels_cb[channel];
+
+ // Pulse width change sequence:
+ if (!p_ch_cb->pulsewidth || p_ch_cb->pulsewidth >= p_cb->period)
+ {
+ // Channel is disabled (0%) or at 100%.
+ if (!ticks || ticks >= p_cb->period)
+ {
+ // Set to 0 or 100%.
+ pwm_transition_0or100_to_0or100(p_instance, channel, ticks);
+ }
+ else
+ {
+ // Other value.
+ pwm_transition_0or100_to_n(p_instance, channel, ticks);
+ }
+ }
+ else
+ {
+ // Channel is at other value.
+ if (!ticks || ticks >= p_cb->period)
+ {
+ // Disable channel (set to 0%) or set to 100%.
+ pwm_transition_n_to_0or100(p_instance, channel, ticks);
+ }
+ else
+ {
+ // Set to any other value.
+ pwm_transition_n_to_m(p_instance, channel, ticks);
+ }
+ }
+}
+#else //GPIOTE_SET_CLEAR_TASKS
+/**
+ * @brief PWM state transition.
+ *
+ * @param[in] p_instance PWM instance.
+ * @param[in] channel PWM channel number.
+ * @param[in] ticks Number of clock ticks.
+ */
+static void pwm_transition(app_pwm_t const * const p_instance,
+ uint8_t channel, uint16_t ticks)
+{
+ app_pwm_cb_t * p_cb = p_instance->p_cb;
+ app_pwm_channel_cb_t * p_ch_cb = &p_cb->channels_cb[channel];
+ nrf_timer_cc_channel_t pwm_ch_cc = (nrf_timer_cc_channel_t)(channel);
+
+ nrf_drv_ppi_channel_disable(p_cb->ppi_channel);
+
+ if (!ticks)
+ {
+ nrf_drv_ppi_channel_disable(p_ch_cb->ppi_channels[1]);
+ nrf_drv_ppi_channel_enable(p_ch_cb->ppi_channels[0]);
+ m_pwm_busy[p_instance->p_timer->instance_id] = BUSY_STATE_IDLE;
+ }
+ else if (ticks >= p_cb->period)
+ {
+ ticks = p_cb->period;
+ nrf_drv_ppi_channel_disable(p_ch_cb->ppi_channels[0]);
+ nrf_drv_ppi_channel_enable(p_ch_cb->ppi_channels[1]);
+ m_pwm_busy[p_instance->p_timer->instance_id] = BUSY_STATE_IDLE;
+ }
+ else
+ {
+ // Set to any other value.
+ if ((p_ch_cb->pulsewidth != p_cb->period) && (p_ch_cb->pulsewidth != 0) && (ticks < p_ch_cb->pulsewidth))
+ {
+ nrf_drv_timer_compare(p_instance->p_timer, (nrf_timer_cc_channel_t)PWM_SECONDARY_CC_CHANNEL, p_ch_cb->pulsewidth, false);
+ nrf_drv_ppi_channel_assign(p_cb->ppi_channel,
+ nrf_drv_timer_compare_event_address_get(p_instance->p_timer, (nrf_timer_cc_channel_t)PWM_SECONDARY_CC_CHANNEL),
+ p_ch_cb->polarity ? nrf_drv_gpiote_clr_task_addr_get(p_ch_cb->gpio_pin) : nrf_drv_gpiote_set_task_addr_get(p_ch_cb->gpio_pin));
+ nrf_drv_ppi_channel_enable(p_cb->ppi_channel);
+ m_pwm_busy[p_instance->p_timer->instance_id] = channel;
+ m_pwm_target_value[p_instance->p_timer->instance_id] = ticks;
+ }
+ else
+ {
+ m_pwm_busy[p_instance->p_timer->instance_id] = BUSY_STATE_IDLE;
+ }
+
+ nrf_drv_timer_compare(p_instance->p_timer, pwm_ch_cc, ticks, false);
+
+ nrf_drv_ppi_channel_enable(p_ch_cb->ppi_channels[0]);
+ nrf_drv_ppi_channel_enable(p_ch_cb->ppi_channels[1]);
+ }
+ p_ch_cb->pulsewidth = ticks;
+ return;
+}
+#endif //GPIOTE_SET_CLEAR_TASKS
+
+ret_code_t app_pwm_channel_duty_ticks_set(app_pwm_t const * const p_instance,
+ uint8_t channel,
+ uint16_t ticks)
+{
+ app_pwm_cb_t * p_cb = p_instance->p_cb;
+ app_pwm_channel_cb_t * p_ch_cb = &p_cb->channels_cb[channel];
+
+ ASSERT(channel < APP_PWM_CHANNELS_PER_INSTANCE);
+ ASSERT(p_ch_cb->initialized == APP_PWM_CHANNEL_INITIALIZED);
+
+ if (p_cb->state != NRFX_DRV_STATE_POWERED_ON)
+ {
+ return NRF_ERROR_INVALID_STATE;
+ }
+ if (ticks == p_ch_cb->pulsewidth)
+ {
+ if (p_cb->p_ready_callback)
+ {
+ p_cb->p_ready_callback(p_instance->p_timer->instance_id);
+ }
+ return NRF_SUCCESS; // No action required.
+ }
+ if (app_pwm_busy_check(p_instance))
+ {
+ return NRF_ERROR_BUSY; // PPI channels for synchronization are still in use.
+ }
+
+ m_pwm_busy[p_instance->p_timer->instance_id] = BUSY_STATE_CHANGING;
+
+ // Set new value.
+
+ pwm_transition(p_instance, channel, ticks);
+
+ if (p_instance->p_cb->p_ready_callback)
+ {
+ //PWM ready interrupt handler will be called after one full period.
+ m_pwm_ready_counter[p_instance->p_timer->instance_id][channel] = 2;
+ pwm_irq_enable(p_instance);
+ }
+ return NRF_SUCCESS;
+}
+
+uint16_t app_pwm_channel_duty_ticks_get(app_pwm_t const * const p_instance, uint8_t channel)
+{
+ app_pwm_cb_t * p_cb = p_instance->p_cb;
+ app_pwm_channel_cb_t * p_ch_cb = &p_cb->channels_cb[channel];
+
+ return p_ch_cb->pulsewidth;
+}
+
+uint16_t app_pwm_cycle_ticks_get(app_pwm_t const * const p_instance)
+{
+ app_pwm_cb_t * p_cb = p_instance->p_cb;
+
+ return (uint16_t)p_cb->period;
+}
+
+ret_code_t app_pwm_channel_duty_set(app_pwm_t const * const p_instance,
+ uint8_t channel, app_pwm_duty_t duty)
+{
+ uint32_t ticks = ((uint32_t)app_pwm_cycle_ticks_get(p_instance) * (uint32_t)duty) / 100UL;
+ return app_pwm_channel_duty_ticks_set(p_instance, channel, ticks);
+}
+
+
+app_pwm_duty_t app_pwm_channel_duty_get(app_pwm_t const * const p_instance, uint8_t channel)
+{
+ uint32_t value = ((uint32_t)app_pwm_channel_duty_ticks_get(p_instance, channel) * 100UL) \
+ / (uint32_t)app_pwm_cycle_ticks_get(p_instance);
+
+ return (app_pwm_duty_t)value;
+}
+
+
+/**
+ * @brief Function for initializing the PWM channel.
+ *
+ * @param[in] p_instance PWM instance.
+ * @param[in] channel Channel number.
+ * @param[in] pin GPIO pin number.
+ *
+ * @retval NRF_SUCCESS If initialization was successful.
+ * @retval NRF_ERROR_NO_MEM If there were not enough free resources.
+ * @retval NRF_ERROR_INVALID_STATE If the timer is already in use or initialization failed.
+ */
+static ret_code_t app_pwm_channel_init(app_pwm_t const * const p_instance, uint8_t channel,
+ uint32_t pin, app_pwm_polarity_t polarity)
+{
+ ASSERT(channel < APP_PWM_CHANNELS_PER_INSTANCE);
+ app_pwm_cb_t * p_cb = p_instance->p_cb;
+ app_pwm_channel_cb_t * p_channel_cb = &p_cb->channels_cb[channel];
+
+ if (p_cb->state != NRFX_DRV_STATE_UNINITIALIZED)
+ {
+ return NRF_ERROR_INVALID_STATE;
+ }
+
+ p_channel_cb->pulsewidth = 0;
+ p_channel_cb->polarity = polarity;
+ ret_code_t err_code;
+
+ /* GPIOTE setup: */
+ nrf_drv_gpiote_out_config_t out_cfg = GPIOTE_CONFIG_OUT_TASK_TOGGLE( POLARITY_INACTIVE(p_instance, channel) );
+ err_code = nrf_drv_gpiote_out_init((nrf_drv_gpiote_pin_t)pin,&out_cfg);
+ if (err_code != NRF_SUCCESS)
+ {
+ return NRF_ERROR_NO_MEM;
+ }
+ p_cb->channels_cb[channel].gpio_pin = pin;
+
+ // Set output to inactive state.
+ if (polarity)
+ {
+ nrf_gpio_pin_clear(pin);
+ }
+ else
+ {
+ nrf_gpio_pin_set(pin);
+ }
+
+ /* PPI setup: */
+ for (uint8_t i = 0; i < APP_PWM_REQUIRED_PPI_CHANNELS_PER_CHANNEL; ++i)
+ {
+ if (nrf_drv_ppi_channel_alloc(&p_channel_cb->ppi_channels[i]) != NRF_SUCCESS)
+ {
+ return NRF_ERROR_NO_MEM; // Resource de-allocation is done by callee.
+ }
+ }
+
+ nrf_drv_ppi_channel_disable(p_channel_cb->ppi_channels[0]);
+ nrf_drv_ppi_channel_disable(p_channel_cb->ppi_channels[1]);
+
+#ifdef GPIOTE_SET_CLEAR_TASKS
+ uint32_t deactivate_task_addr = polarity ? nrf_drv_gpiote_clr_task_addr_get(p_channel_cb->gpio_pin) : nrf_drv_gpiote_set_task_addr_get(p_channel_cb->gpio_pin);
+ uint32_t activate_task_addr = polarity ? nrf_drv_gpiote_set_task_addr_get(p_channel_cb->gpio_pin) : nrf_drv_gpiote_clr_task_addr_get(p_channel_cb->gpio_pin);
+
+ nrf_drv_ppi_channel_assign(p_channel_cb->ppi_channels[0],
+ nrf_drv_timer_compare_event_address_get(p_instance->p_timer, channel),
+ deactivate_task_addr);
+ nrf_drv_ppi_channel_assign(p_channel_cb->ppi_channels[1],
+ nrf_drv_timer_compare_event_address_get(p_instance->p_timer, PWM_MAIN_CC_CHANNEL),
+ activate_task_addr);
+#else //GPIOTE_SET_CLEAR_TASKS
+ nrf_drv_ppi_channel_assign(p_channel_cb->ppi_channels[0],
+ nrf_drv_timer_compare_event_address_get(p_instance->p_timer, channel),
+ nrf_drv_gpiote_out_task_addr_get(p_channel_cb->gpio_pin));
+ nrf_drv_ppi_channel_assign(p_channel_cb->ppi_channels[1],
+ nrf_drv_timer_compare_event_address_get(p_instance->p_timer, PWM_MAIN_CC_CHANNEL),
+ nrf_drv_gpiote_out_task_addr_get(p_channel_cb->gpio_pin));
+#endif //GPIOTE_SET_CLEAR_TASKS
+ p_channel_cb->initialized = APP_PWM_CHANNEL_INITIALIZED;
+ m_pwm_ready_counter[p_instance->p_timer->instance_id][channel] = 0;
+
+ return NRF_SUCCESS;
+}
+
+
+/**
+ * @brief Function for calculating target timer frequency, which will allow to set given period length.
+ *
+ * @param[in] period_us Desired period in microseconds.
+ *
+ * @retval Timer frequency.
+ */
+__STATIC_INLINE nrf_timer_frequency_t pwm_calculate_timer_frequency(uint32_t period_us)
+{
+ uint32_t f = (uint32_t) NRF_TIMER_FREQ_16MHz;
+ uint32_t min = (uint32_t) NRF_TIMER_FREQ_31250Hz;
+
+ while ((period_us > TIMER_MAX_PULSEWIDTH_US_ON_16M) && (f < min))
+ {
+ period_us >>= 1;
+ ++f;
+ }
+
+#ifdef GPIOTE_SET_CLEAR_TASKS
+ if ((m_use_ppi_delay_workaround) && (f == (uint32_t) NRF_TIMER_FREQ_16MHz))
+ {
+ f = (uint32_t) NRF_TIMER_FREQ_8MHz;
+ }
+#endif // GPIOTE_SET_CLEAR_TASKS
+
+ return (nrf_timer_frequency_t) f;
+}
+
+
+ret_code_t app_pwm_init(app_pwm_t const * const p_instance, app_pwm_config_t const * const p_config,
+ app_pwm_callback_t p_ready_callback)
+{
+ ASSERT(p_instance);
+
+ if (!p_config)
+ {
+ return NRF_ERROR_INVALID_DATA;
+ }
+
+ app_pwm_cb_t * p_cb = p_instance->p_cb;
+
+ if (p_cb->state != NRFX_DRV_STATE_UNINITIALIZED)
+ {
+ return NRF_ERROR_INVALID_STATE;
+ }
+
+ uint32_t err_code = nrf_drv_ppi_init();
+ if ((err_code != NRF_SUCCESS) && (err_code != NRF_ERROR_MODULE_ALREADY_INITIALIZED))
+ {
+ return NRF_ERROR_NO_MEM;
+ }
+
+
+ if (!nrf_drv_gpiote_is_init())
+ {
+ err_code = nrf_drv_gpiote_init();
+ if (err_code != NRF_SUCCESS)
+ {
+ return NRF_ERROR_INTERNAL;
+ }
+ }
+
+#ifdef GPIOTE_SET_CLEAR_TASKS
+ if (((*(uint32_t *)0xF0000FE8) & 0x000000F0) == 0x30)
+ {
+ m_use_ppi_delay_workaround = false;
+ }
+ else
+ {
+ m_use_ppi_delay_workaround = true;
+ }
+#endif
+
+ // Innitialize resource status:
+#ifdef GPIOTE_SET_CLEAR_TASKS
+ p_cb->ppi_channel = (nrf_ppi_channel_t)UNALLOCATED;
+#else
+ p_cb->ppi_channels[0] = (nrf_ppi_channel_t)UNALLOCATED;
+ p_cb->ppi_channels[1] = (nrf_ppi_channel_t)UNALLOCATED;
+ p_cb->ppi_group = (nrf_ppi_channel_group_t)UNALLOCATED;
+#endif //GPIOTE_SET_CLEAR_TASKS
+
+ for (uint8_t i = 0; i < APP_PWM_CHANNELS_PER_INSTANCE; ++i)
+ {
+ p_cb->channels_cb[i].initialized = APP_PWM_CHANNEL_UNINITIALIZED;
+ p_cb->channels_cb[i].ppi_channels[0] = (nrf_ppi_channel_t)UNALLOCATED;
+ p_cb->channels_cb[i].ppi_channels[1] = (nrf_ppi_channel_t)UNALLOCATED;
+ p_cb->channels_cb[i].gpio_pin = UNALLOCATED;
+ }
+
+ // Allocate PPI channels and groups:
+
+#ifdef GPIOTE_SET_CLEAR_TASKS
+ if (nrf_drv_ppi_channel_alloc(&p_cb->ppi_channel) != NRF_SUCCESS)
+ {
+ pwm_dealloc(p_instance);
+ return NRF_ERROR_NO_MEM;
+ }
+#else //GPIOTE_SET_CLEAR_TASKS
+ if (nrf_drv_ppi_group_alloc(&p_cb->ppi_group) != NRF_SUCCESS)
+ {
+ pwm_dealloc(p_instance);
+ return NRF_ERROR_NO_MEM;
+ }
+
+ for (uint8_t i = 0; i < APP_PWM_REQUIRED_PPI_CHANNELS_PER_INSTANCE; ++i)
+ {
+ if (nrf_drv_ppi_channel_alloc(&p_cb->ppi_channels[i]) != NRF_SUCCESS)
+ {
+ pwm_dealloc(p_instance);
+ return NRF_ERROR_NO_MEM;
+ }
+ }
+#endif //GPIOTE_SET_CLEAR_TASKS
+ // Initialize channels:
+ for (uint8_t i = 0; i < APP_PWM_CHANNELS_PER_INSTANCE; ++i)
+ {
+ if (p_config->pins[i] != APP_PWM_NOPIN)
+ {
+ err_code = app_pwm_channel_init(p_instance, i, p_config->pins[i], p_config->pin_polarity[i]);
+ if (err_code != NRF_SUCCESS)
+ {
+ pwm_dealloc(p_instance);
+ return err_code;
+ }
+ app_pwm_channel_duty_ticks_set(p_instance, i, 0);
+ }
+ }
+
+ // Initialize timer:
+ nrf_timer_frequency_t timer_freq = pwm_calculate_timer_frequency(p_config->period_us);
+ nrf_drv_timer_config_t timer_cfg = {
+ .frequency = timer_freq,
+ .mode = NRF_TIMER_MODE_TIMER,
+ .bit_width = NRF_TIMER_BIT_WIDTH_16,
+ .interrupt_priority = APP_IRQ_PRIORITY_LOWEST,
+ .p_context = (void *) (uint32_t) p_instance->p_timer->instance_id
+ };
+ err_code = nrf_drv_timer_init(p_instance->p_timer, &timer_cfg,
+ pwm_ready_tick);
+ if (err_code != NRF_SUCCESS)
+ {
+ pwm_dealloc(p_instance);
+ return err_code;
+ }
+
+ uint32_t ticks = nrf_drv_timer_us_to_ticks(p_instance->p_timer, p_config->period_us);
+ p_cb->period = ticks;
+ nrf_drv_timer_clear(p_instance->p_timer);
+ nrf_drv_timer_extended_compare(p_instance->p_timer, (nrf_timer_cc_channel_t) PWM_MAIN_CC_CHANNEL,
+ ticks, NRF_TIMER_SHORT_COMPARE2_CLEAR_MASK, true);
+ nrf_drv_timer_compare_int_disable(p_instance->p_timer, PWM_MAIN_CC_CHANNEL);
+
+ p_cb->p_ready_callback = p_ready_callback;
+ m_instances[p_instance->p_timer->instance_id] = p_instance;
+ m_pwm_busy[p_instance->p_timer->instance_id] = BUSY_STATE_IDLE;
+ p_cb->state = NRFX_DRV_STATE_INITIALIZED;
+
+ return NRF_SUCCESS;
+}
+
+
+void app_pwm_enable(app_pwm_t const * const p_instance)
+{
+ app_pwm_cb_t * p_cb = p_instance->p_cb;
+
+ ASSERT(p_cb->state != NRFX_DRV_STATE_UNINITIALIZED);
+
+ for (uint32_t channel = 0; channel < APP_PWM_CHANNELS_PER_INSTANCE; ++channel)
+ {
+ app_pwm_channel_cb_t * p_ch_cb = &p_cb->channels_cb[channel];
+ m_pwm_ready_counter[p_instance->p_timer->instance_id][channel] = 0;
+ if (p_ch_cb->initialized)
+ {
+ nrf_drv_gpiote_out_task_force(p_ch_cb->gpio_pin, POLARITY_INACTIVE(p_instance, channel));
+ nrf_drv_gpiote_out_task_enable(p_ch_cb->gpio_pin);
+ p_ch_cb->pulsewidth = 0;
+ }
+ }
+ m_pwm_busy[p_instance->p_timer->instance_id] = BUSY_STATE_IDLE;
+
+ pan73_workaround(p_instance->p_timer->p_reg, true);
+
+ nrf_drv_timer_clear(p_instance->p_timer);
+ nrf_drv_timer_enable(p_instance->p_timer);
+
+ p_cb->state = NRFX_DRV_STATE_POWERED_ON;
+ return;
+}
+
+
+void app_pwm_disable(app_pwm_t const * const p_instance)
+{
+ app_pwm_cb_t * p_cb = p_instance->p_cb;
+
+ ASSERT(p_cb->state != NRFX_DRV_STATE_UNINITIALIZED);
+
+ nrf_drv_timer_disable(p_instance->p_timer);
+ pwm_irq_disable(p_instance);
+
+#ifdef GPIOTE_SET_CLEAR_TASKS
+ nrf_drv_ppi_channel_disable(p_cb->ppi_channel);
+#else
+ for (uint8_t ppi_channel = 0; ppi_channel < APP_PWM_REQUIRED_PPI_CHANNELS_PER_INSTANCE; ++ppi_channel)
+ {
+ nrf_drv_ppi_channel_disable(p_cb->ppi_channels[ppi_channel]);
+ }
+#endif //GPIOTE_SET_CLEAR_TASKS
+
+ for (uint8_t channel = 0; channel < APP_PWM_CHANNELS_PER_INSTANCE; ++channel)
+ {
+ app_pwm_channel_cb_t * p_ch_cb = &p_cb->channels_cb[channel];
+ if (p_ch_cb->initialized)
+ {
+ uint8_t polarity = POLARITY_INACTIVE(p_instance, channel);
+ if (polarity)
+ {
+ nrf_gpio_pin_set(p_ch_cb->gpio_pin);
+ }
+ else
+ {
+ nrf_gpio_pin_clear(p_ch_cb->gpio_pin);
+ }
+ nrf_drv_gpiote_out_task_disable(p_ch_cb->gpio_pin);
+ nrf_drv_ppi_channel_disable(p_ch_cb->ppi_channels[0]);
+ nrf_drv_ppi_channel_disable(p_ch_cb->ppi_channels[1]);
+ }
+ }
+
+ pan73_workaround(p_instance->p_timer->p_reg, false);
+
+ p_cb->state = NRFX_DRV_STATE_INITIALIZED;
+ return;
+}
+
+
+ret_code_t app_pwm_uninit(app_pwm_t const * const p_instance)
+{
+ app_pwm_cb_t * p_cb = p_instance->p_cb;
+
+ if (p_cb->state == NRFX_DRV_STATE_POWERED_ON)
+ {
+ app_pwm_disable(p_instance);
+ }
+ else if (p_cb->state == NRFX_DRV_STATE_UNINITIALIZED)
+ {
+ return NRF_ERROR_INVALID_STATE;
+ }
+ pwm_dealloc(p_instance);
+
+ p_cb->state = NRFX_DRV_STATE_UNINITIALIZED;
+ return NRF_SUCCESS;
+}
+
+
+//lint -restore
+#endif //NRF_MODULE_ENABLED(APP_PWM)
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/pwm/app_pwm.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/pwm/app_pwm.h
new file mode 100644
index 0000000..3be066b
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/pwm/app_pwm.h
@@ -0,0 +1,338 @@
+/**
+ * Copyright (c) 2015 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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
+ *
+ * @defgroup app_pwm Pulse-width modulation (PWM)
+ * @{
+ * @ingroup app_common
+ *
+ * @brief Module for generating a pulse-width modulated output signal.
+ *
+ * @details This module provides a PWM implementation using timers, GPIOTE, and PPI.
+ *
+ * Resource usage:
+ * - 2 PPI channels per instance + 2 PPI channels per PWM channel.
+ * - 1 PPI group per instance.
+ * - 1 GPIOTE channel per PWM channel.
+ *
+ * For example, a PWM instance with two channels will consume 2 + 4 PPI channels, 1 PPI group, and 2 GPIOTE channels.
+ *
+ * The maximum number of PWM channels per instance is 2.
+ */
+
+#ifndef APP_PWM_H__
+#define APP_PWM_H__
+
+#include <stdint.h>
+#include "sdk_errors.h"
+#include "nrf_drv_timer.h"
+#include "nrf_drv_ppi.h"
+#include "nrf_peripherals.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#if defined(GPIOTE_FEATURE_SET_PRESENT) && defined(GPIOTE_FEATURE_CLR_PRESENT)
+#define GPIOTE_SET_CLEAR_TASKS
+#endif
+
+#define APP_PWM_NOPIN 0xFFFFFFFF
+
+/** @brief Number of channels for one timer instance (fixed to 2 due to timer properties).*/
+#define APP_PWM_CHANNELS_PER_INSTANCE 2
+
+/**@brief Macro for creating a PWM instance. */
+#define APP_PWM_INSTANCE(name, num) \
+ const nrf_drv_timer_t m_pwm_##name##_timer = NRF_DRV_TIMER_INSTANCE(num); \
+ app_pwm_cb_t m_pwm_##name##_cb; \
+ /*lint -e{545}*/ \
+ const app_pwm_t name = { \
+ .p_cb = &m_pwm_##name##_cb, \
+ .p_timer = &m_pwm_##name##_timer, \
+ }
+
+
+/**@brief PWM instance default configuration (1 channel). */
+#define APP_PWM_DEFAULT_CONFIG_1CH(period_in_us, pin) \
+ { \
+ .pins = {pin, APP_PWM_NOPIN}, \
+ .pin_polarity = {APP_PWM_POLARITY_ACTIVE_LOW, APP_PWM_POLARITY_ACTIVE_LOW}, \
+ .num_of_channels = 1, \
+ .period_us = period_in_us \
+ }
+
+/**@brief PWM instance default configuration (2 channels). */
+#define APP_PWM_DEFAULT_CONFIG_2CH(period_in_us, pin0, pin1) \
+ { \
+ .pins = {pin0, pin1}, \
+ .pin_polarity = {APP_PWM_POLARITY_ACTIVE_LOW, APP_PWM_POLARITY_ACTIVE_LOW}, \
+ .num_of_channels = 2, \
+ .period_us = period_in_us \
+ }
+
+typedef uint16_t app_pwm_duty_t;
+
+/**
+ * @brief PWM callback that is executed when a PWM duty change has been completed.
+ *
+ * @param[in] pwm_id PWM instance ID.
+ */
+typedef void (* app_pwm_callback_t)(uint32_t);
+
+/**
+ * @brief Channel polarity.
+ */
+typedef enum
+{
+ APP_PWM_POLARITY_ACTIVE_LOW = 0,
+ APP_PWM_POLARITY_ACTIVE_HIGH = 1
+} app_pwm_polarity_t;
+
+/**@brief PWM configuration structure used for initialization. */
+typedef struct
+{
+ uint32_t pins[APP_PWM_CHANNELS_PER_INSTANCE]; //!< Pins configured as PWM output.
+ app_pwm_polarity_t pin_polarity[APP_PWM_CHANNELS_PER_INSTANCE]; //!< Polarity of active state on pin.
+ uint32_t num_of_channels; //!< Number of channels that can be used.
+ uint32_t period_us; //!< PWM signal output period to configure (in microseconds).
+} app_pwm_config_t;
+
+
+/**
+ * @cond (NODOX)
+ * @defgroup app_pwm_internal Auxiliary internal types declarations
+ * @{
+ * @internal
+ *
+ * @brief Module for internal usage inside the library only
+ *
+ * There are some definitions that must be included in the header file because
+ * of the way the library is set up. In this way, the are accessible to the user.
+ * However, any functions and variables defined here may change at any time
+ * without a warning, so you should not access them directly.
+ */
+
+ /**
+ * @brief PWM channel instance
+ *
+ * This structure holds all data needed by a single PWM channel.
+ */
+ typedef struct
+ {
+ uint32_t gpio_pin; //!< Pin that is used by this PWM channel.
+ uint32_t pulsewidth; //!< The copy of duty currently set (in ticks).
+ nrf_ppi_channel_t ppi_channels[2]; //!< PPI channels used by the PWM channel to clear and set the output.
+ app_pwm_polarity_t polarity; //!< The active state of the pin.
+ uint8_t initialized; //!< The internal information if the selected channel was initialized.
+ } app_pwm_channel_cb_t;
+
+ /**
+ * @brief Variable part of PWM instance
+ *
+ * This structure holds instance data that may change.
+ */
+ typedef struct
+ {
+ app_pwm_channel_cb_t channels_cb[APP_PWM_CHANNELS_PER_INSTANCE]; //!< Channels data
+ uint32_t period; //!< Selected period in ticks
+ app_pwm_callback_t p_ready_callback; //!< Callback function called on PWM readiness
+#ifdef GPIOTE_SET_CLEAR_TASKS
+ nrf_ppi_channel_t ppi_channel; //!< PPI channel used temporary while changing duty
+#else
+ nrf_ppi_channel_t ppi_channels[2]; //!< PPI channels used temporary while changing duty
+ nrf_ppi_channel_group_t ppi_group; //!< PPI group used to synchronize changes on channels
+#endif
+ nrfx_drv_state_t state; //!< Current driver status
+ } app_pwm_cb_t;
+/** @}
+ * @endcond
+ */
+
+
+/**@brief PWM instance structure. */
+typedef struct
+{
+ app_pwm_cb_t *p_cb; //!< Pointer to control block internals.
+ nrf_drv_timer_t const * const p_timer; //!< Timer used by this PWM instance.
+} app_pwm_t;
+
+/**
+ * @brief Function for checking if the PWM instance is busy updating the duty cycle.
+ *
+ * @param[in] p_instance PWM instance.
+ *
+ * @retval True If the PWM instance is ready for duty cycle changes.
+ * @retval False If a change operation is in progress.
+ */
+bool app_pwm_busy_check(app_pwm_t const * const p_instance);
+
+/**
+ * @brief Function for initializing a PWM instance.
+ *
+ * @param[in] p_instance PWM instance.
+ * @param[in] p_config Initial configuration.
+ * @param[in] p_ready_callback Pointer to ready callback function (or NULL to disable).
+ *
+ * @retval NRF_SUCCESS If initialization was successful.
+ * @retval NRF_ERROR_NO_MEM If there were not enough free resources.
+ * @retval NRF_ERROR_INVALID_PARAM If an invalid configuration structure was passed.
+ * @retval NRF_ERROR_INVALID_STATE If the timer/PWM is already in use or if initialization failed.
+ */
+ret_code_t app_pwm_init(app_pwm_t const * const p_instance, app_pwm_config_t const * const p_config,
+ app_pwm_callback_t p_ready_callback);
+
+
+/**
+ * @brief Function for uninitializing a PWM instance and releasing the allocated resources.
+ *
+ * @param[in] p_instance PWM instance.
+ *
+ * @retval NRF_SUCCESS If uninitialization was successful.
+ * @retval NRF_ERROR_INVALID_STATE If the given instance was not initialized.
+ */
+ret_code_t app_pwm_uninit(app_pwm_t const * const p_instance);
+
+/**
+ * @brief Function for enabling a PWM instance after initialization.
+ *
+ * @param[in] p_instance PWM instance.
+ */
+void app_pwm_enable(app_pwm_t const * const p_instance);
+
+/**
+ * @brief Function for disabling a PWM instance after initialization.
+ *
+ * @param[in] p_instance PWM instance.
+ */
+void app_pwm_disable(app_pwm_t const * const p_instance);
+
+/**
+ * @brief Function for setting the PWM channel duty cycle in percents.
+ *
+ * A duty cycle change requires one full PWM clock period to finish.
+ * If another change is attempted for any channel of given instance before
+ * the current change is complete, the new attempt will result in the error
+ * NRF_ERROR_BUSY.
+ *
+ * @param[in] p_instance PWM instance.
+ * @param[in] channel Channel number.
+ * @param[in] duty Duty cycle (0 - 100).
+ *
+ * @retval NRF_SUCCESS If the operation was successful.
+ * @retval NRF_ERROR_BUSY If the PWM is not ready yet.
+ * @retval NRF_ERROR_INVALID_STATE If the given instance was not initialized.
+ *
+ */
+ret_code_t app_pwm_channel_duty_set(app_pwm_t const * const p_instance,
+ uint8_t channel, app_pwm_duty_t duty);
+
+/**
+ * @brief Function for retrieving the PWM channel duty cycle in percents.
+ *
+ * @param[in] p_instance PWM instance.
+ * @param[in] channel Channel number.
+ *
+ * @return Duty cycle value.
+ */
+app_pwm_duty_t app_pwm_channel_duty_get(app_pwm_t const * const p_instance, uint8_t channel);
+
+
+/**
+ * @name Functions accessing values in ticks
+ *
+ * Auxiliary functions that allow to get values in actual timer ticks.
+ * @{
+ */
+
+ /**
+ * @brief Function for setting PWM channel duty cycle in clock ticks.
+ *
+ * @note Duty cycle changes require one full PWM clock period to finish.
+ * Until that, the next change attempt (for any channel of given instance)
+ * will result in an NRF_ERROR_BUSY error.
+ *
+ * @param[in] p_instance PWM instance.
+ * @param[in] channel Channel number.
+ * @param[in] ticks Number of PWM clock ticks.
+ *
+ * @retval NRF_SUCCESS If the operation was successful.
+ * @retval NRF_ERROR_BUSY If PWM is not ready yet.
+ * @retval NRF_ERROR_INVALID_STATE If the given instance was not initialized.
+ */
+ ret_code_t app_pwm_channel_duty_ticks_set(app_pwm_t const * const p_instance,
+ uint8_t channel,
+ uint16_t ticks);
+
+
+ /**
+ * @brief Function for retrieving the PWM channel duty cycle in ticks.
+ *
+ * This function retrieves the real, currently set duty cycle in ticks.
+ * For one full PWM cycle the value might be different than the value set by the last
+ * @ref app_pwm_channel_duty_ticks_set function call.
+ *
+ * @param[in] p_instance PWM instance.
+ * @param[in] channel Channel number.
+ *
+ * @return Number of ticks set for selected channel.
+ *
+ */
+ uint16_t app_pwm_channel_duty_ticks_get(app_pwm_t const * const p_instance, uint8_t channel);
+
+ /**
+ * @brief Function for returning the number of ticks in a whole cycle.
+ *
+ * @param[in] p_instance PWM instance.
+ *
+ * @return Number of ticks that corresponds to 100% of the duty cycle.
+ */
+ uint16_t app_pwm_cycle_ticks_get(app_pwm_t const * const p_instance);
+/** @} */
+
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
+/** @} */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/pwr_mgmt/nrf_pwr_mgmt.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/pwr_mgmt/nrf_pwr_mgmt.c
new file mode 100644
index 0000000..8f36d40
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/pwr_mgmt/nrf_pwr_mgmt.c
@@ -0,0 +1,465 @@
+/**
+ * Copyright (c) 2016 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#include "sdk_common.h"
+#if NRF_MODULE_ENABLED(NRF_PWR_MGMT)
+
+#include "nrf_pwr_mgmt.h"
+#include "nrf.h"
+#include "nrf_mtx.h"
+#include "nrf_power.h"
+#include "app_error.h"
+#include "nrf_assert.h"
+#include "nrf_log_ctrl.h"
+#include "app_util_platform.h"
+
+#define NRF_LOG_MODULE_NAME pwr_mgmt
+#if NRF_PWR_MGMT_CONFIG_LOG_ENABLED
+ #define NRF_LOG_LEVEL NRF_PWR_MGMT_CONFIG_LOG_LEVEL
+ #define NRF_LOG_INFO_COLOR NRF_PWR_MGMT_CONFIG_INFO_COLOR
+ #define NRF_LOG_DEBUG_COLOR NRF_PWR_MGMT_CONFIG_DEBUG_COLOR
+#else
+ #define NRF_LOG_LEVEL 0
+#endif // NRF_PWR_MGMT_CONFIG_LOG_ENABLED
+#include "nrf_log.h"
+NRF_LOG_MODULE_REGISTER();
+
+#ifdef SOFTDEVICE_PRESENT
+ #include "nrf_soc.h"
+ #include "nrf_sdh.h"
+#endif // SOFTDEVICE_PRESENT
+
+
+#if NRF_PWR_MGMT_CONFIG_USE_SCHEDULER
+ #if (APP_SCHEDULER_ENABLED != 1)
+ #error "APP_SCHEDULER is required."
+ #endif
+ #include "app_scheduler.h"
+#endif // NRF_PWR_MGMT_CONFIG_USE_SCHEDULER
+
+
+// Create section "pwr_mgmt_data".
+NRF_SECTION_SET_DEF(pwr_mgmt_data,
+ nrf_pwr_mgmt_shutdown_handler_t,
+ NRF_PWR_MGMT_CONFIG_HANDLER_PRIORITY_COUNT);
+
+static nrf_pwr_mgmt_evt_t m_pwr_mgmt_evt; /**< Event type which will be passed to the shutdown
+ handlers.*/
+static nrf_mtx_t m_sysoff_mtx; /**< Module API lock.*/
+static bool m_shutdown_started; /**< True if application started the shutdown preparation. */
+static nrf_section_iter_t m_handlers_iter; /**< Shutdown handlers iterator. */
+
+#if (NRF_PWR_MGMT_CONFIG_FPU_SUPPORT_ENABLED && __FPU_PRESENT)
+ #define PWR_MGMT_FPU_SLEEP_PREPARE() pwr_mgmt_fpu_sleep_prepare()
+
+ __STATIC_INLINE void pwr_mgmt_fpu_sleep_prepare(void)
+ {
+ uint32_t fpscr;
+ CRITICAL_REGION_ENTER();
+ fpscr = __get_FPSCR();
+ /*
+ * Clear FPU exceptions.
+ * Without this step, the FPU interrupt is marked as pending,
+ * preventing system from sleeping. Exceptions cleared:
+ * - IOC - Invalid Operation cumulative exception bit.
+ * - DZC - Division by Zero cumulative exception bit.
+ * - OFC - Overflow cumulative exception bit.
+ * - UFC - Underflow cumulative exception bit.
+ * - IXC - Inexact cumulative exception bit.
+ * - IDC - Input Denormal cumulative exception bit.
+ */
+ __set_FPSCR(fpscr & ~0x9Fu);
+ __DMB();
+ NVIC_ClearPendingIRQ(FPU_IRQn);
+ CRITICAL_REGION_EXIT();
+
+ /*
+ * Assert no critical FPU exception is signaled:
+ * - IOC - Invalid Operation cumulative exception bit.
+ * - DZC - Division by Zero cumulative exception bit.
+ * - OFC - Overflow cumulative exception bit.
+ */
+ ASSERT((fpscr & 0x07) == 0);
+ }
+#else
+ #define PWR_MGMT_FPU_SLEEP_PREPARE()
+#endif // NRF_PWR_MGMT_CONFIG_FPU_SUPPORT_ENABLED
+
+
+#if NRF_PWR_MGMT_CONFIG_DEBUG_PIN_ENABLED
+ #undef PWR_MGMT_SLEEP_IN_CRITICAL_SECTION_REQUIRED
+ #define PWR_MGMT_SLEEP_IN_CRITICAL_SECTION_REQUIRED
+
+ #include "nrf_gpio.h"
+ #define PWR_MGMT_DEBUG_PINS_INIT() pwr_mgmt_debug_pins_init()
+ #define PWR_MGMT_DEBUG_PIN_CLEAR() nrf_gpio_pin_clear(NRF_PWR_MGMT_SLEEP_DEBUG_PIN)
+ #define PWR_MGMT_DEBUG_PIN_SET() nrf_gpio_pin_set(NRF_PWR_MGMT_SLEEP_DEBUG_PIN)
+
+ __STATIC_INLINE void pwr_mgmt_debug_pins_init(void)
+ {
+ nrf_gpio_pin_clear(NRF_PWR_MGMT_SLEEP_DEBUG_PIN);
+ nrf_gpio_cfg_output(NRF_PWR_MGMT_SLEEP_DEBUG_PIN);
+ }
+
+#else
+ #define PWR_MGMT_DEBUG_PIN_CLEAR()
+ #define PWR_MGMT_DEBUG_PIN_SET()
+ #define PWR_MGMT_DEBUG_PINS_INIT()
+#endif
+
+
+#if NRF_PWR_MGMT_CONFIG_CPU_USAGE_MONITOR_ENABLED
+ #undef PWR_MGMT_SLEEP_IN_CRITICAL_SECTION_REQUIRED
+ #define PWR_MGMT_SLEEP_IN_CRITICAL_SECTION_REQUIRED
+
+ #undef PWR_MGMT_TIMER_REQUIRED
+ #define PWR_MGMT_TIMER_REQUIRED
+ #include "app_timer.h"
+
+ #define PWR_MGMT_CPU_USAGE_MONITOR_INIT() pwr_mgmt_cpu_usage_monitor_init()
+ #define PWR_MGMT_CPU_USAGE_MONITOR_UPDATE() pwr_mgmt_cpu_usage_monitor_update()
+ #define PWR_MGMT_CPU_USAGE_MONITOR_SUMMARY() NRF_LOG_INFO("Maximum CPU usage: %u%%", \
+ m_max_cpu_usage)
+ #define PWR_MGMT_CPU_USAGE_MONITOR_SECTION_ENTER() \
+ { \
+ uint32_t sleep_start = app_timer_cnt_get()
+
+ #define PWR_MGMT_CPU_USAGE_MONITOR_SECTION_EXIT() \
+ uint32_t sleep_end = app_timer_cnt_get(); \
+ uint32_t sleep_duration; \
+ sleep_duration = app_timer_cnt_diff_compute(sleep_end, \
+ sleep_start); \
+ m_ticks_sleeping += sleep_duration; \
+ }
+
+ static uint32_t m_ticks_sleeping; /**< Number of ticks spent in sleep mode (__WFE()). */
+ static uint32_t m_ticks_last; /**< Number of ticks from the last CPU usage computation. */
+ static uint8_t m_max_cpu_usage; /**< Maximum observed CPU usage (0 - 100%). */
+
+ __STATIC_INLINE void pwr_mgmt_cpu_usage_monitor_init(void)
+ {
+ m_ticks_sleeping = 0;
+ m_ticks_last = 0;
+ m_max_cpu_usage = 0;
+ }
+
+ __STATIC_INLINE void pwr_mgmt_cpu_usage_monitor_update(void)
+ {
+ uint32_t delta;
+ uint32_t ticks;
+ uint8_t cpu_usage;
+
+ ticks = app_timer_cnt_get();
+ delta = app_timer_cnt_diff_compute(ticks, m_ticks_last);
+ cpu_usage = 100 * (delta - m_ticks_sleeping) / delta;
+
+ NRF_LOG_INFO("CPU Usage: %u%%", cpu_usage);
+ if (m_max_cpu_usage < cpu_usage)
+ {
+ m_max_cpu_usage = cpu_usage;
+ }
+
+ m_ticks_last = ticks;
+ m_ticks_sleeping = 0;
+ }
+
+#else
+ #define PWR_MGMT_CPU_USAGE_MONITOR_INIT()
+ #define PWR_MGMT_CPU_USAGE_MONITOR_UPDATE()
+ #define PWR_MGMT_CPU_USAGE_MONITOR_SUMMARY()
+ #define PWR_MGMT_CPU_USAGE_MONITOR_SECTION_ENTER()
+ #define PWR_MGMT_CPU_USAGE_MONITOR_SECTION_EXIT()
+#endif // NRF_PWR_MGMT_CONFIG_CPU_USAGE_MONITOR_ENABLED
+
+
+#if NRF_PWR_MGMT_CONFIG_STANDBY_TIMEOUT_ENABLED
+ #undef PWR_MGMT_TIMER_REQUIRED
+ #define PWR_MGMT_TIMER_REQUIRED
+
+ #define PWR_MGMT_STANDBY_TIMEOUT_INIT() pwr_mgmt_standby_timeout_clear()
+ #define PWR_MGMT_STANDBY_TIMEOUT_CLEAR() pwr_mgmt_standby_timeout_clear()
+ #define PWR_MGMT_STANDBY_TIMEOUT_CHECK() pwr_mgmt_standby_timeout_check()
+
+ static uint16_t m_standby_counter; /**< Number of seconds from the last activity
+ (@ref pwr_mgmt_feed). */
+
+ __STATIC_INLINE void pwr_mgmt_standby_timeout_clear(void)
+ {
+ m_standby_counter = 0;
+ }
+
+ __STATIC_INLINE void pwr_mgmt_standby_timeout_check(void)
+ {
+ if (m_standby_counter < NRF_PWR_MGMT_CONFIG_STANDBY_TIMEOUT_S)
+ {
+ m_standby_counter++;
+ }
+ else if (m_shutdown_started == false)
+ {
+ nrf_pwr_mgmt_shutdown(NRF_PWR_MGMT_SHUTDOWN_GOTO_SYSOFF);
+ }
+ }
+
+#else
+ #define PWR_MGMT_STANDBY_TIMEOUT_INIT()
+ #define PWR_MGMT_STANDBY_TIMEOUT_CLEAR()
+ #define PWR_MGMT_STANDBY_TIMEOUT_CHECK()
+#endif // NRF_PWR_MGMT_CONFIG_STANDBY_TIMEOUT_ENABLED
+
+
+#if NRF_PWR_MGMT_CONFIG_AUTO_SHUTDOWN_RETRY
+ #undef PWR_MGMT_TIMER_REQUIRED
+ #define PWR_MGMT_TIMER_REQUIRED
+
+ #define PWR_MGMT_AUTO_SHUTDOWN_RETRY() pwr_mgmt_auto_shutdown_retry()
+
+ __STATIC_INLINE void pwr_mgmt_auto_shutdown_retry(void)
+ {
+ if (m_shutdown_started)
+ {
+ // Try to continue the shutdown procedure.
+ nrf_pwr_mgmt_shutdown(NRF_PWR_MGMT_SHUTDOWN_CONTINUE);
+ }
+ }
+
+#else
+ #define PWR_MGMT_AUTO_SHUTDOWN_RETRY()
+#endif // NRF_PWR_MGMT_CONFIG_AUTO_SHUTDOWN_RETRY
+
+
+#ifdef PWR_MGMT_SLEEP_IN_CRITICAL_SECTION_REQUIRED
+ #define PWR_MGMT_SLEEP_INIT() pwr_mgmt_sleep_init()
+ #define PWR_MGMT_SLEEP_LOCK_ACQUIRE() CRITICAL_REGION_ENTER()
+ #define PWR_MGMT_SLEEP_LOCK_RELEASE() CRITICAL_REGION_EXIT()
+
+ __STATIC_INLINE void pwr_mgmt_sleep_init(void)
+ {
+ #ifdef SOFTDEVICE_PRESENT
+ ASSERT(current_int_priority_get() >= APP_IRQ_PRIORITY_LOW);
+ #endif
+ SCB->SCR |= SCB_SCR_SEVONPEND_Msk;
+ }
+
+#else
+ #define PWR_MGMT_SLEEP_INIT()
+ #define PWR_MGMT_SLEEP_LOCK_ACQUIRE()
+ #define PWR_MGMT_SLEEP_LOCK_RELEASE()
+#endif // PWR_MGMT_SLEEP_IN_CRITICAL_SECTION_REQUIRED
+
+
+#ifdef PWR_MGMT_TIMER_REQUIRED
+ #include "app_timer.h"
+ #define PWR_MGMT_TIMER_CREATE() pwr_mgmt_timer_create()
+
+ APP_TIMER_DEF(m_pwr_mgmt_timer); /**< Timer used by this module. */
+
+ /**@brief Handle events from m_pwr_mgmt_timer.
+ */
+ static void nrf_pwr_mgmt_timeout_handler(void * p_context)
+ {
+ PWR_MGMT_CPU_USAGE_MONITOR_UPDATE();
+ PWR_MGMT_AUTO_SHUTDOWN_RETRY();
+ PWR_MGMT_STANDBY_TIMEOUT_CHECK();
+ }
+
+ __STATIC_INLINE ret_code_t pwr_mgmt_timer_create(void)
+ {
+ ret_code_t ret_code = app_timer_create(&m_pwr_mgmt_timer,
+ APP_TIMER_MODE_REPEATED,
+ nrf_pwr_mgmt_timeout_handler);
+ if (ret_code != NRF_SUCCESS)
+ {
+ return ret_code;
+ }
+
+ return app_timer_start(m_pwr_mgmt_timer, APP_TIMER_TICKS(1000), NULL);
+ }
+#else
+ #define PWR_MGMT_TIMER_CREATE() NRF_SUCCESS
+#endif // PWR_MGMT_TIMER_REQUIRED
+
+ret_code_t nrf_pwr_mgmt_init(void)
+{
+ NRF_LOG_INFO("Init");
+
+ m_shutdown_started = false;
+ nrf_mtx_init(&m_sysoff_mtx);
+ nrf_section_iter_init(&m_handlers_iter, &pwr_mgmt_data);
+
+ PWR_MGMT_SLEEP_INIT();
+ PWR_MGMT_DEBUG_PINS_INIT();
+ PWR_MGMT_STANDBY_TIMEOUT_INIT();
+ PWR_MGMT_CPU_USAGE_MONITOR_INIT();
+
+ return PWR_MGMT_TIMER_CREATE();
+}
+
+void nrf_pwr_mgmt_run(void)
+{
+ PWR_MGMT_FPU_SLEEP_PREPARE();
+ PWR_MGMT_SLEEP_LOCK_ACQUIRE();
+ PWR_MGMT_CPU_USAGE_MONITOR_SECTION_ENTER();
+ PWR_MGMT_DEBUG_PIN_SET();
+
+ // Wait for an event.
+#ifdef SOFTDEVICE_PRESENT
+ if (nrf_sdh_is_enabled())
+ {
+ ret_code_t ret_code = sd_app_evt_wait();
+ ASSERT((ret_code == NRF_SUCCESS) || (ret_code == NRF_ERROR_SOFTDEVICE_NOT_ENABLED));
+ UNUSED_VARIABLE(ret_code);
+ }
+ else
+#endif // SOFTDEVICE_PRESENT
+ {
+ // Wait for an event.
+ __WFE();
+ // Clear the internal event register.
+ __SEV();
+ __WFE();
+ }
+
+ PWR_MGMT_DEBUG_PIN_CLEAR();
+ PWR_MGMT_CPU_USAGE_MONITOR_SECTION_EXIT();
+ PWR_MGMT_SLEEP_LOCK_RELEASE();
+}
+
+void nrf_pwr_mgmt_feed(void)
+{
+ NRF_LOG_DEBUG("Feed");
+ // It does not stop started shutdown process.
+ PWR_MGMT_STANDBY_TIMEOUT_CLEAR();
+}
+
+/**@brief Function runs the shutdown procedure.
+ */
+static void shutdown_process(void)
+{
+ NRF_LOG_INFO("Shutdown started. Type %d", m_pwr_mgmt_evt);
+ // Executing all callbacks.
+ for (/* m_handlers_iter is initialized in nrf_pwr_mgmt_init(). Thanks to that each handler is
+ called only once.*/;
+ nrf_section_iter_get(&m_handlers_iter) != NULL;
+ nrf_section_iter_next(&m_handlers_iter))
+ {
+ nrf_pwr_mgmt_shutdown_handler_t * p_handler =
+ (nrf_pwr_mgmt_shutdown_handler_t *) nrf_section_iter_get(&m_handlers_iter);
+ if ((*p_handler)(m_pwr_mgmt_evt))
+ {
+ NRF_LOG_INFO("SysOff handler 0x%08X => ready", (unsigned int)*p_handler);
+ }
+ else
+ {
+ // One of the modules is not ready.
+ NRF_LOG_INFO("SysOff handler 0x%08X => blocking", (unsigned int)*p_handler);
+ return;
+ }
+ }
+
+ PWR_MGMT_CPU_USAGE_MONITOR_SUMMARY();
+ NRF_LOG_INFO("Shutdown complete.");
+ NRF_LOG_FINAL_FLUSH();
+
+ if ((m_pwr_mgmt_evt == NRF_PWR_MGMT_EVT_PREPARE_RESET)
+ || (m_pwr_mgmt_evt == NRF_PWR_MGMT_EVT_PREPARE_DFU))
+ {
+ NVIC_SystemReset();
+ }
+ else
+ {
+ // Enter System OFF.
+#ifdef SOFTDEVICE_PRESENT
+ if (nrf_sdh_is_enabled())
+ {
+ ret_code_t ret_code = sd_power_system_off();
+ ASSERT((ret_code == NRF_SUCCESS) || (ret_code == NRF_ERROR_SOFTDEVICE_NOT_ENABLED));
+ UNUSED_VARIABLE(ret_code);
+ }
+#endif // SOFTDEVICE_PRESENT
+ nrf_power_system_off();
+ }
+}
+
+#if NRF_PWR_MGMT_CONFIG_USE_SCHEDULER
+/**@brief Handle events from app_scheduler.
+ */
+static void scheduler_shutdown_handler(void * p_event_data, uint16_t event_size)
+{
+ UNUSED_PARAMETER(p_event_data);
+ UNUSED_PARAMETER(event_size);
+ shutdown_process();
+}
+#endif // NRF_PWR_MGMT_CONFIG_USE_SCHEDULER
+
+void nrf_pwr_mgmt_shutdown(nrf_pwr_mgmt_shutdown_t shutdown_type)
+{
+ // Check if shutdown procedure is not started.
+ if (!nrf_mtx_trylock(&m_sysoff_mtx))
+ {
+ return;
+ }
+
+ if (shutdown_type != NRF_PWR_MGMT_SHUTDOWN_CONTINUE)
+ {
+ if (m_shutdown_started)
+ {
+ nrf_mtx_unlock(&m_sysoff_mtx);
+ return;
+ }
+ else
+ {
+ m_pwr_mgmt_evt = (nrf_pwr_mgmt_evt_t)shutdown_type;
+ m_shutdown_started = true;
+ }
+ }
+
+ ASSERT(m_shutdown_started);
+ NRF_LOG_INFO("Shutdown request %d", shutdown_type);
+
+#if NRF_PWR_MGMT_CONFIG_USE_SCHEDULER
+ ret_code_t ret_code = app_sched_event_put(NULL, 0, scheduler_shutdown_handler);
+ APP_ERROR_CHECK(ret_code);
+#else
+ shutdown_process();
+#endif // NRF_PWR_MGMT_CONFIG_USE_SCHEDULER
+
+ nrf_mtx_unlock(&m_sysoff_mtx);
+}
+
+#endif // NRF_MODULE_ENABLED(NRF_PWR_MGMT)
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/pwr_mgmt/nrf_pwr_mgmt.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/pwr_mgmt/nrf_pwr_mgmt.h
new file mode 100644
index 0000000..3f6eb56
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/pwr_mgmt/nrf_pwr_mgmt.h
@@ -0,0 +1,150 @@
+/**
+ * Copyright (c) 2016 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+/**
+ * @defgroup nrf_pwr_mgmt Power management
+ * @ingroup app_common
+ * @{
+ * @brief This module handles power management features.
+ *
+ */
+#ifndef NRF_PWR_MGMT_H__
+#define NRF_PWR_MGMT_H__
+
+#include <stdbool.h>
+#include <stdint.h>
+#include <sdk_errors.h>
+#include "nrf_section_iter.h"
+
+/**@brief Power management shutdown types. */
+typedef enum
+{
+ NRF_PWR_MGMT_SHUTDOWN_GOTO_SYSOFF,
+ //!< Go to System OFF.
+
+ NRF_PWR_MGMT_SHUTDOWN_STAY_IN_SYSOFF,
+ //!< Go to System OFF and stay there.
+ /**<
+ * Useful when battery level is dangerously low, for example.
+ */
+
+ NRF_PWR_MGMT_SHUTDOWN_GOTO_DFU,
+ //!< Go to DFU mode.
+
+ NRF_PWR_MGMT_SHUTDOWN_RESET,
+ //!< Reset chip.
+
+ NRF_PWR_MGMT_SHUTDOWN_CONTINUE
+ //!< Continue shutdown.
+ /**<
+ * This should be used by modules that block the shutdown process, when they become ready for
+ * shutdown.
+ */
+} nrf_pwr_mgmt_shutdown_t;
+
+/**@brief Shutdown event types. */
+typedef enum
+{
+ NRF_PWR_MGMT_EVT_PREPARE_WAKEUP = NRF_PWR_MGMT_SHUTDOWN_GOTO_SYSOFF,
+ //!< Application will prepare the wakeup mechanism.
+
+ NRF_PWR_MGMT_EVT_PREPARE_SYSOFF = NRF_PWR_MGMT_SHUTDOWN_STAY_IN_SYSOFF,
+ //!< Application will prepare to stay in System OFF state.
+
+ NRF_PWR_MGMT_EVT_PREPARE_DFU = NRF_PWR_MGMT_SHUTDOWN_GOTO_DFU,
+ //!< Application will prepare to enter DFU mode.
+
+ NRF_PWR_MGMT_EVT_PREPARE_RESET = NRF_PWR_MGMT_SHUTDOWN_RESET,
+ //!< Application will prepare to chip reset.
+} nrf_pwr_mgmt_evt_t;
+
+/**@brief Shutdown callback.
+ * @param[in] event Type of shutdown process.
+ *
+ * @retval true System OFF / Enter DFU preparation successful. Process will be continued.
+ * @retval false System OFF / Enter DFU preparation failed. @ref NRF_PWR_MGMT_SHUTDOWN_CONTINUE
+ * should be used to continue the shutdown process.
+ */
+typedef bool (*nrf_pwr_mgmt_shutdown_handler_t)(nrf_pwr_mgmt_evt_t event);
+
+/**@brief Macro for registering a shutdown handler. Modules that want to get events
+ * from this module must register the handler using this macro.
+ *
+ * @details This macro places the handler in a section named "pwr_mgmt_data".
+ *
+ * @param[in] _handler Event handler (@ref nrf_pwr_mgmt_shutdown_handler_t).
+ * @param[in] _priority Priority of the given handler.
+ */
+#define NRF_PWR_MGMT_HANDLER_REGISTER(_handler, _priority) \
+ STATIC_ASSERT(_priority < NRF_PWR_MGMT_CONFIG_HANDLER_PRIORITY_COUNT); \
+ /*lint -esym(528,*_handler_function) -esym(529,*_handler_function) : Symbol not referenced. */ \
+ NRF_SECTION_SET_ITEM_REGISTER(pwr_mgmt_data, _priority, \
+ static nrf_pwr_mgmt_shutdown_handler_t const CONCAT_2(_handler, _handler_function)) = (_handler)
+
+/**@brief Function for initializing power management.
+ *
+ * @warning Depending on configuration, this function sets SEVONPEND in System Control Block (SCB).
+ * This operation is unsafe with the SoftDevice from interrupt priority higher than SVC.
+ *
+ * @retval NRF_SUCCESS
+ */
+ret_code_t nrf_pwr_mgmt_init(void);
+
+/**@brief Function for running power management. Should run in the main loop.
+ */
+void nrf_pwr_mgmt_run(void);
+
+/**@brief Function for indicating activity.
+ *
+ * @details Call this function whenever doing something that constitutes "activity".
+ * For example, whenever sending data, call this function to indicate that the application
+ * is active and should not disconnect any ongoing communication links.
+ */
+void nrf_pwr_mgmt_feed(void);
+
+/**@brief Function for shutting down the system.
+ *
+ * @param[in] shutdown_type Type of operation.
+ *
+ * @details All callbacks will be executed prior to shutdown.
+ */
+void nrf_pwr_mgmt_shutdown(nrf_pwr_mgmt_shutdown_t shutdown_type);
+
+#endif // NRF_PWR_MGMT_H__
+/** @} */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/queue/nrf_queue.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/queue/nrf_queue.c
new file mode 100644
index 0000000..9afc16c
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/queue/nrf_queue.c
@@ -0,0 +1,547 @@
+/**
+ * Copyright (c) 2016 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#include "sdk_common.h"
+#if NRF_MODULE_ENABLED(NRF_QUEUE)
+#include "nrf_queue.h"
+#include "app_util_platform.h"
+
+#if NRF_QUEUE_CONFIG_LOG_ENABLED
+ #define NRF_LOG_LEVEL NRF_QUEUE_CONFIG_LOG_LEVEL
+ #define NRF_LOG_INIT_FILTER_LEVEL NRF_QUEUE_CONFIG_LOG_INIT_FILTER_LEVEL
+ #define NRF_LOG_INFO_COLOR NRF_QUEUE_CONFIG_INFO_COLOR
+ #define NRF_LOG_DEBUG_COLOR NRF_QUEUE_CONFIG_DEBUG_COLOR
+#else
+ #define NRF_LOG_LEVEL 0
+#endif // NRF_QUEUE_CONFIG_LOG_ENABLED
+#include "nrf_log.h"
+
+NRF_SECTION_DEF(nrf_queue, nrf_queue_t);
+
+#if NRF_QUEUE_CLI_CMDS
+#include "nrf_cli.h"
+
+static void nrf_queue_status(nrf_cli_t const * p_cli, size_t argc, char **argv)
+{
+ UNUSED_PARAMETER(argv);
+
+ if (nrf_cli_help_requested(p_cli))
+ {
+ nrf_cli_help_print(p_cli, NULL, 0);
+ return;
+ }
+
+ if (argc > 1)
+ {
+ nrf_cli_fprintf(p_cli, NRF_CLI_ERROR, "Bad argument count");
+ return;
+ }
+
+ uint32_t num_of_instances = NRF_SECTION_ITEM_COUNT(nrf_queue, nrf_queue_t);
+ uint32_t i;
+
+ for (i = 0; i < num_of_instances; i++)
+ {
+ const nrf_queue_t * p_instance = NRF_SECTION_ITEM_GET(nrf_queue, nrf_queue_t, i);
+
+ uint32_t element_size = p_instance->element_size;
+ uint32_t size = p_instance->size;
+ uint32_t max_util = nrf_queue_max_utilization_get(p_instance);
+ uint32_t util = nrf_queue_utilization_get(p_instance);
+ const char * p_name = p_instance->p_name;
+ nrf_cli_fprintf(p_cli, NRF_CLI_NORMAL,
+ "%s\r\n\t- Element size:\t%d\r\n"
+ "\t- Usage:\t%u%% (%u out of %u elements)\r\n"
+ "\t- Maximum:\t%u%% (%u out of %u elements)\r\n"
+ "\t- Mode:\t\t%s\r\n\r\n",
+ p_name, element_size,
+ 100ul * util/size, util,size,
+ 100ul * max_util/size, max_util,size,
+ (p_instance->mode == NRF_QUEUE_MODE_OVERFLOW) ? "Overflow" : "No overflow");
+
+ }
+}
+// Register "queue" command and its subcommands in CLI.
+NRF_CLI_CREATE_STATIC_SUBCMD_SET(nrf_queue_commands)
+{
+ NRF_CLI_CMD(status, NULL, "Print status of queue instances.", nrf_queue_status),
+ NRF_CLI_SUBCMD_SET_END
+};
+
+NRF_CLI_CMD_REGISTER(queue, &nrf_queue_commands, "Commands for BALLOC management", nrf_queue_status);
+#endif //NRF_QUEUE_CLI_CMDS
+
+/**@brief Get next element index.
+ *
+ * @param[in] p_queue Pointer to the queue instance.
+ * @param[in] idx Current index.
+ *
+ * @return Next element index.
+ */
+__STATIC_INLINE size_t nrf_queue_next_idx(nrf_queue_t const * p_queue, size_t idx)
+{
+ ASSERT(p_queue != NULL);
+ return (idx < p_queue->size) ? (idx + 1) : 0;
+}
+
+/**@brief Get current queue utilization. This function assumes that this process will not be interrupted.
+ *
+ * @param[in] p_queue Pointer to the queue instance.
+ *
+ * @return Current queue utilization.
+ */
+__STATIC_INLINE size_t queue_utilization_get(nrf_queue_t const * p_queue)
+{
+ size_t front = p_queue->p_cb->front;
+ size_t back = p_queue->p_cb->back;
+ return (back >= front) ? (back - front) : (p_queue->size + 1 - front + back);
+}
+
+bool nrf_queue_is_full(nrf_queue_t const * p_queue)
+{
+ ASSERT(p_queue != NULL);
+ size_t front = p_queue->p_cb->front;
+ size_t back = p_queue->p_cb->back;
+
+ return (nrf_queue_next_idx(p_queue, back) == front);
+}
+
+ret_code_t nrf_queue_push(nrf_queue_t const * p_queue, void const * p_element)
+{
+ ret_code_t status = NRF_SUCCESS;
+
+ ASSERT(p_queue != NULL);
+ ASSERT(p_element != NULL);
+
+ CRITICAL_REGION_ENTER();
+ bool is_full = nrf_queue_is_full(p_queue);
+
+ if (!is_full || (p_queue->mode == NRF_QUEUE_MODE_OVERFLOW))
+ {
+ // Get write position.
+ size_t write_pos = p_queue->p_cb->back;
+ p_queue->p_cb->back = nrf_queue_next_idx(p_queue, p_queue->p_cb->back);
+ if (is_full)
+ {
+ // Overwrite the oldest element.
+ NRF_LOG_INST_WARNING(p_queue->p_log, "Queue full. Overwriting oldest element.");
+ p_queue->p_cb->front = nrf_queue_next_idx(p_queue, p_queue->p_cb->front);
+ }
+
+ // Write a new element.
+ switch (p_queue->element_size)
+ {
+ case sizeof(uint8_t):
+ ((uint8_t *)p_queue->p_buffer)[write_pos] = *((uint8_t *)p_element);
+ break;
+
+ case sizeof(uint16_t):
+ ((uint16_t *)p_queue->p_buffer)[write_pos] = *((uint16_t *)p_element);
+ break;
+
+ case sizeof(uint32_t):
+ ((uint32_t *)p_queue->p_buffer)[write_pos] = *((uint32_t *)p_element);
+ break;
+
+ case sizeof(uint64_t):
+ ((uint64_t *)p_queue->p_buffer)[write_pos] = *((uint64_t *)p_element);
+ break;
+
+ default:
+ memcpy((void *)((size_t)p_queue->p_buffer + write_pos * p_queue->element_size),
+ p_element,
+ p_queue->element_size);
+ break;
+ }
+
+ // Update utilization.
+ size_t utilization = queue_utilization_get(p_queue);
+ if (p_queue->p_cb->max_utilization < utilization)
+ {
+ p_queue->p_cb->max_utilization = utilization;
+ }
+ }
+ else
+ {
+ status = NRF_ERROR_NO_MEM;
+ }
+
+ CRITICAL_REGION_EXIT();
+
+ NRF_LOG_INST_DEBUG(p_queue->p_log, "pushed element 0x%08X, status:%d", p_element, status);
+ return status;
+}
+
+ret_code_t nrf_queue_generic_pop(nrf_queue_t const * p_queue,
+ void * p_element,
+ bool just_peek)
+{
+ ret_code_t status = NRF_SUCCESS;
+
+ ASSERT(p_queue != NULL);
+ ASSERT(p_element != NULL);
+
+ CRITICAL_REGION_ENTER();
+
+ if (!nrf_queue_is_empty(p_queue))
+ {
+ // Get read position.
+ size_t read_pos = p_queue->p_cb->front;
+
+ // Update next read position.
+ if (!just_peek)
+ {
+ p_queue->p_cb->front = nrf_queue_next_idx(p_queue, p_queue->p_cb->front);
+ }
+
+ // Read element.
+ switch (p_queue->element_size)
+ {
+ case sizeof(uint8_t):
+ *((uint8_t *)p_element) = ((uint8_t *)p_queue->p_buffer)[read_pos];
+ break;
+
+ case sizeof(uint16_t):
+ *((uint16_t *)p_element) = ((uint16_t *)p_queue->p_buffer)[read_pos];
+ break;
+
+ case sizeof(uint32_t):
+ *((uint32_t *)p_element) = ((uint32_t *)p_queue->p_buffer)[read_pos];
+ break;
+
+ case sizeof(uint64_t):
+ *((uint64_t *)p_element) = ((uint64_t *)p_queue->p_buffer)[read_pos];
+ break;
+
+ default:
+ memcpy(p_element,
+ (void const *)((size_t)p_queue->p_buffer + read_pos * p_queue->element_size),
+ p_queue->element_size);
+ break;
+ }
+ }
+ else
+ {
+ status = NRF_ERROR_NOT_FOUND;
+ }
+
+ CRITICAL_REGION_EXIT();
+ NRF_LOG_INST_DEBUG(p_queue->p_log, "%s element 0x%08X, status:%d",
+ just_peek ? "peeked" : "popped", p_element, status);
+ return status;
+}
+
+/**@brief Write elements to the queue. This function assumes that there is enough room in the queue
+ * to write the requested number of elements and that this process will not be interrupted.
+ *
+ * @param[in] p_queue Pointer to the nrf_queue_t instance.
+ * @param[in] p_data Pointer to the buffer with elements to write.
+ * @param[in] element_count Number of elements to write.
+ */
+static void queue_write(nrf_queue_t const * p_queue, void const * p_data, uint32_t element_count)
+{
+ size_t prev_available = nrf_queue_available_get(p_queue);
+ size_t continuous = p_queue->size + 1 - p_queue->p_cb->back;
+ void * p_write_ptr = (void *)((size_t)p_queue->p_buffer
+ + p_queue->p_cb->back * p_queue->element_size);
+ if (element_count <= continuous)
+ {
+ memcpy(p_write_ptr,
+ p_data,
+ element_count * p_queue->element_size);
+
+ p_queue->p_cb->back = ((p_queue->p_cb->back + element_count) <= p_queue->size)
+ ? (p_queue->p_cb->back + element_count)
+ : 0;
+ }
+ else
+ {
+ size_t first_write_length = continuous * p_queue->element_size;
+ memcpy(p_write_ptr,
+ p_data,
+ first_write_length);
+
+ size_t elements_left = element_count - continuous;
+ memcpy(p_queue->p_buffer,
+ (void const *)((size_t)p_data + first_write_length),
+ elements_left * p_queue->element_size);
+
+ p_queue->p_cb->back = elements_left;
+ if (prev_available < element_count)
+ {
+ // Overwrite the oldest elements.
+ p_queue->p_cb->front = nrf_queue_next_idx(p_queue, p_queue->p_cb->back);
+ }
+ }
+
+ // Update utilization.
+ size_t utilization = queue_utilization_get(p_queue);
+ if (p_queue->p_cb->max_utilization < utilization)
+ {
+ p_queue->p_cb->max_utilization = utilization;
+ }
+}
+
+ret_code_t nrf_queue_write(nrf_queue_t const * p_queue,
+ void const * p_data,
+ size_t element_count)
+{
+ ret_code_t status = NRF_SUCCESS;
+
+ ASSERT(p_queue != NULL);
+ ASSERT(p_data != NULL);
+ ASSERT(element_count <= p_queue->size);
+
+ if (element_count == 0)
+ {
+ return NRF_SUCCESS;
+ }
+
+ CRITICAL_REGION_ENTER();
+
+ if ((nrf_queue_available_get(p_queue) >= element_count)
+ || (p_queue->mode == NRF_QUEUE_MODE_OVERFLOW))
+ {
+ queue_write(p_queue, p_data, element_count);
+ }
+ else
+ {
+ status = NRF_ERROR_NO_MEM;
+ }
+
+ CRITICAL_REGION_EXIT();
+
+ NRF_LOG_INST_DEBUG(p_queue->p_log, "Write %d elements (start address: 0x%08X), status:%d",
+ element_count, p_data, status);
+ return status;
+}
+
+
+size_t nrf_queue_in(nrf_queue_t const * p_queue,
+ void const * p_data,
+ size_t element_count)
+{
+ ASSERT(p_queue != NULL);
+ ASSERT(p_data != NULL);
+
+ size_t req_element_count = element_count;
+
+ if (element_count == 0)
+ {
+ return 0;
+ }
+
+ CRITICAL_REGION_ENTER();
+
+ if (p_queue->mode == NRF_QUEUE_MODE_OVERFLOW)
+ {
+ element_count = MIN(element_count, p_queue->size);
+ }
+ else
+ {
+ size_t available = nrf_queue_available_get(p_queue);
+ element_count = MIN(element_count, available);
+ }
+
+ queue_write(p_queue, p_data, element_count);
+
+ CRITICAL_REGION_EXIT();
+
+ NRF_LOG_INST_DEBUG(p_queue->p_log, "Put in %d elements (start address: 0x%08X), requested :%d",
+ element_count, p_data, req_element_count);
+
+ return element_count;
+}
+
+/**@brief Read elements from the queue. This function assumes that there are enough elements
+ * in the queue to read and that this process will not be interrupted.
+ *
+ * @param[in] p_queue Pointer to the nrf_queue_t instance.
+ * @param[out] p_data Pointer to the buffer where elements will be copied.
+ * @param[in] element_count Number of elements to read.
+ */
+static void queue_read(nrf_queue_t const * p_queue, void * p_data, uint32_t element_count)
+{
+ size_t front = p_queue->p_cb->front;
+ size_t back = p_queue->p_cb->back;
+ size_t continuous = (front <= back) ? (back - front) : (p_queue->size + 1 - front);
+ void const * p_read_ptr = (void const *)((size_t)p_queue->p_buffer
+ + front * p_queue->element_size);
+
+ if (element_count <= continuous)
+ {
+ memcpy(p_data,
+ p_read_ptr,
+ element_count * p_queue->element_size);
+
+ p_queue->p_cb->front = ((front + element_count) <= p_queue->size)
+ ? (front + element_count)
+ : 0;
+ }
+ else
+ {
+ size_t first_read_length = continuous * p_queue->element_size;
+ memcpy(p_data,
+ p_read_ptr,
+ first_read_length);
+
+ size_t elements_left = element_count - continuous;
+ memcpy((void *)((size_t)p_data + first_read_length),
+ p_queue->p_buffer,
+ elements_left * p_queue->element_size);
+
+ p_queue->p_cb->front = elements_left;
+ }
+}
+
+ret_code_t nrf_queue_read(nrf_queue_t const * p_queue,
+ void * p_data,
+ size_t element_count)
+{
+ ret_code_t status = NRF_SUCCESS;
+
+ ASSERT(p_queue != NULL);
+ ASSERT(p_data != NULL);
+
+ if (element_count == 0)
+ {
+ return NRF_SUCCESS;
+ }
+
+ CRITICAL_REGION_ENTER();
+
+ if (element_count <= queue_utilization_get(p_queue))
+ {
+ queue_read(p_queue, p_data, element_count);
+ }
+ else
+ {
+ status = NRF_ERROR_NOT_FOUND;
+ }
+
+ CRITICAL_REGION_EXIT();
+
+ NRF_LOG_INST_DEBUG(p_queue->p_log, "Read %d elements (start address: 0x%08X), status :%d",
+ element_count, p_data, status);
+ return status;
+}
+
+size_t nrf_queue_out(nrf_queue_t const * p_queue,
+ void * p_data,
+ size_t element_count)
+{
+ ASSERT(p_queue != NULL);
+ ASSERT(p_data != NULL);
+
+ size_t req_element_count = element_count;
+
+ if (element_count == 0)
+ {
+ return 0;
+ }
+
+ CRITICAL_REGION_ENTER();
+
+ size_t utilization = queue_utilization_get(p_queue);
+ element_count = MIN(element_count, utilization);
+
+ queue_read(p_queue, p_data, element_count);
+
+ CRITICAL_REGION_EXIT();
+
+ NRF_LOG_INST_DEBUG(p_queue->p_log, "Out %d elements (start address: 0x%08X), requested :%d",
+ element_count, p_data, req_element_count);
+ return element_count;
+}
+
+void nrf_queue_reset(nrf_queue_t const * p_queue)
+{
+ ASSERT(p_queue != NULL);
+
+ CRITICAL_REGION_ENTER();
+
+ memset(p_queue->p_cb, 0, sizeof(nrf_queue_cb_t));
+
+ CRITICAL_REGION_EXIT();
+
+ NRF_LOG_INST_DEBUG(p_queue->p_log, "Reset");
+}
+
+size_t nrf_queue_utilization_get(nrf_queue_t const * p_queue)
+{
+ size_t utilization;
+ ASSERT(p_queue != NULL);
+
+ CRITICAL_REGION_ENTER();
+
+ utilization = queue_utilization_get(p_queue);
+
+ CRITICAL_REGION_EXIT();
+
+ return utilization;
+}
+
+bool nrf_queue_is_empty(nrf_queue_t const * p_queue)
+{
+ ASSERT(p_queue != NULL);
+ size_t front = p_queue->p_cb->front;
+ size_t back = p_queue->p_cb->back;
+ return (front == back);
+}
+
+size_t nrf_queue_available_get(nrf_queue_t const * p_queue)
+{
+ ASSERT(p_queue != NULL);
+ return p_queue->size - nrf_queue_utilization_get(p_queue);
+}
+
+size_t nrf_queue_max_utilization_get(nrf_queue_t const * p_queue)
+{
+ ASSERT(p_queue != NULL);
+ return p_queue->p_cb->max_utilization;
+}
+
+void nrf_queue_max_utilization_reset(nrf_queue_t const * p_queue)
+{
+ ASSERT(p_queue != NULL);
+ p_queue->p_cb->max_utilization = 0;
+}
+
+
+#endif // NRF_MODULE_ENABLED(NRF_QUEUE)
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/queue/nrf_queue.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/queue/nrf_queue.h
new file mode 100644
index 0000000..1ba2a92
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/queue/nrf_queue.h
@@ -0,0 +1,429 @@
+/**
+ * Copyright (c) 2016 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+/**
+* @defgroup nrf_queue Queue module
+* @{
+* @ingroup app_common
+* @brief Functions that handle the queue instances.
+*/
+
+#ifndef NRF_QUEUE_H__
+#define NRF_QUEUE_H__
+
+#include <stdint.h>
+#include <stdint.h>
+#include <string.h>
+#include "nrf_assert.h"
+#include "sdk_errors.h"
+#include "app_util.h"
+#include "app_util_platform.h"
+#include "nrf_log_instance.h"
+#include "nrf_section.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** @brief Name of the module used for logger messaging.
+ */
+#define NRF_QUEUE_LOG_NAME queue
+
+/**@brief Queue control block. */
+typedef struct
+{
+ volatile size_t front; //!< Queue front index.
+ volatile size_t back; //!< Queue back index.
+ size_t max_utilization; //!< Maximum utilization of the queue.
+} nrf_queue_cb_t;
+
+/**@brief Supported queue modes. */
+typedef enum
+{
+ NRF_QUEUE_MODE_OVERFLOW, //!< If the queue is full, new element will overwrite the oldest.
+ NRF_QUEUE_MODE_NO_OVERFLOW, //!< If the queue is full, new element will not be accepted.
+} nrf_queue_mode_t;
+
+/**@brief Instance of the queue. */
+typedef struct
+{
+ nrf_queue_cb_t * p_cb; //!< Pointer to the instance control block.
+ void * p_buffer; //!< Pointer to the memory that is used as storage.
+ size_t size; //!< Size of the queue.
+ size_t element_size; //!< Size of one element.
+ nrf_queue_mode_t mode; //!< Mode of the queue.
+#if NRF_QUEUE_CLI_CMDS
+ const char * p_name; //!< Pointer to string with queue name.
+#endif
+ NRF_LOG_INSTANCE_PTR_DECLARE(p_log) //!< Pointer to instance of the logger object (Conditionally compiled).
+} nrf_queue_t;
+
+#if NRF_QUEUE_CLI_CMDS
+#define __NRF_QUEUE_ASSIGN_POOL_NAME(_name) .p_name = STRINGIFY(_name),
+#else
+#define __NRF_QUEUE_ASSIGN_POOL_NAME(_name)
+#endif
+/**@brief Create a queue instance.
+ *
+ * @note This macro reserves memory for the given queue instance.
+ *
+ * @param[in] _type Type which is stored.
+ * @param[in] _name Name of the queue.
+ * @param[in] _size Size of the queue.
+ * @param[in] _mode Mode of the queue.
+ */
+#define NRF_QUEUE_DEF(_type, _name, _size, _mode) \
+ static _type CONCAT_2(_name, _nrf_queue_buffer[(_size) + 1]); \
+ static nrf_queue_cb_t CONCAT_2(_name, _nrf_queue_cb); \
+ NRF_LOG_INSTANCE_REGISTER(NRF_QUEUE_LOG_NAME, _name, \
+ NRF_QUEUE_CONFIG_INFO_COLOR, \
+ NRF_QUEUE_CONFIG_DEBUG_COLOR, \
+ NRF_QUEUE_CONFIG_LOG_INIT_FILTER_LEVEL, \
+ NRF_QUEUE_CONFIG_LOG_ENABLED ? \
+ NRF_QUEUE_CONFIG_LOG_LEVEL : NRF_LOG_SEVERITY_NONE); \
+ NRF_SECTION_ITEM_REGISTER(nrf_queue, const nrf_queue_t _name) = \
+ { \
+ .p_cb = &CONCAT_2(_name, _nrf_queue_cb), \
+ .p_buffer = CONCAT_2(_name,_nrf_queue_buffer), \
+ .size = (_size), \
+ .element_size = sizeof(_type), \
+ .mode = _mode, \
+ __NRF_QUEUE_ASSIGN_POOL_NAME(_name) \
+ NRF_LOG_INSTANCE_PTR_INIT(p_log, NRF_QUEUE_LOG_NAME, _name) \
+ }
+
+/**@brief Declare a queue interface.
+ *
+ * @param[in] _type Type which is stored.
+ * @param[in] _name Name of the queue.
+ */
+#define NRF_QUEUE_INTERFACE_DEC(_type, _name) \
+ ret_code_t _name##_push(_type const * p_element); \
+ ret_code_t _name##_pop(_type * p_element); \
+ ret_code_t _name##_peek(_type * p_element); \
+ ret_code_t _name##_write(_type const * p_data, \
+ size_t element_count); \
+ ret_code_t _name##_read(_type * p_data, \
+ size_t element_count); \
+ size_t _name##_out(_type * p_data, \
+ size_t element_count); \
+ size_t _name##_in(_type const * p_data, \
+ size_t element_count); \
+ bool _name##_is_full(void); \
+ bool _name##_is_empty(void); \
+ size_t _name##_utilization_get(void); \
+ size_t _name##_available_get(void); \
+ size_t _name##_max_utilization_get(void); \
+ void _name##_reset(void)
+
+/**@brief Define a queue interface.
+ *
+ * @param[in] _type Type which is stored.
+ * @param[in] _name Name of the queue.
+ * @param[in] _p_queue Queue instance.
+ */
+#define NRF_QUEUE_INTERFACE_DEF(_type, _name, _p_queue) \
+ ret_code_t _name##_push(_type const * p_element) \
+ { \
+ GCC_PRAGMA("GCC diagnostic push") \
+ GCC_PRAGMA("GCC diagnostic ignored \"-Waddress\"") \
+ ASSERT((_p_queue) != NULL); \
+ ASSERT((_p_queue)->element_size == sizeof(_type)); \
+ GCC_PRAGMA("GCC diagnostic pop") \
+ return nrf_queue_push((_p_queue), p_element); \
+ } \
+ ret_code_t _name##_pop(_type * p_element) \
+ { \
+ GCC_PRAGMA("GCC diagnostic push") \
+ GCC_PRAGMA("GCC diagnostic ignored \"-Waddress\"") \
+ ASSERT((_p_queue) != NULL); \
+ ASSERT((_p_queue)->element_size == sizeof(_type)); \
+ GCC_PRAGMA("GCC diagnostic pop") \
+ return nrf_queue_pop((_p_queue), p_element); \
+ } \
+ ret_code_t _name##_peek(_type * p_element) \
+ { \
+ GCC_PRAGMA("GCC diagnostic push") \
+ GCC_PRAGMA("GCC diagnostic ignored \"-Waddress\"") \
+ ASSERT((_p_queue) != NULL); \
+ ASSERT((_p_queue)->element_size == sizeof(_type)); \
+ GCC_PRAGMA("GCC diagnostic pop") \
+ return nrf_queue_peek((_p_queue), p_element); \
+ } \
+ ret_code_t _name##_write(_type const * p_data, \
+ size_t element_count) \
+ { \
+ GCC_PRAGMA("GCC diagnostic push") \
+ GCC_PRAGMA("GCC diagnostic ignored \"-Waddress\"") \
+ ASSERT((_p_queue) != NULL); \
+ ASSERT((_p_queue)->element_size == sizeof(_type)); \
+ GCC_PRAGMA("GCC diagnostic pop") \
+ return nrf_queue_write((_p_queue), p_data, element_count); \
+ } \
+ ret_code_t _name##_read(_type * p_data, \
+ size_t element_count) \
+ { \
+ GCC_PRAGMA("GCC diagnostic push") \
+ GCC_PRAGMA("GCC diagnostic ignored \"-Waddress\"") \
+ ASSERT((_p_queue) != NULL); \
+ ASSERT((_p_queue)->element_size == sizeof(_type)); \
+ GCC_PRAGMA("GCC diagnostic pop") \
+ return nrf_queue_read((_p_queue), p_data, element_count); \
+ } \
+ size_t _name##_in(_type const * p_data, \
+ size_t element_count) \
+ { \
+ GCC_PRAGMA("GCC diagnostic push") \
+ GCC_PRAGMA("GCC diagnostic ignored \"-Waddress\"") \
+ ASSERT((_p_queue) != NULL); \
+ ASSERT((_p_queue)->element_size == sizeof(_type)); \
+ GCC_PRAGMA("GCC diagnostic pop") \
+ return nrf_queue_in((_p_queue), p_data, element_count); \
+ } \
+ size_t _name##_out(_type * p_data, \
+ size_t element_count) \
+ { \
+ GCC_PRAGMA("GCC diagnostic push") \
+ GCC_PRAGMA("GCC diagnostic ignored \"-Waddress\"") \
+ ASSERT((_p_queue) != NULL); \
+ ASSERT((_p_queue)->element_size == sizeof(_type)); \
+ GCC_PRAGMA("GCC diagnostic pop") \
+ return nrf_queue_out((_p_queue), p_data, element_count); \
+ } \
+ bool _name##_is_full(void) \
+ { \
+ GCC_PRAGMA("GCC diagnostic push") \
+ GCC_PRAGMA("GCC diagnostic ignored \"-Waddress\"") \
+ ASSERT((_p_queue) != NULL); \
+ return nrf_queue_is_full(_p_queue); \
+ GCC_PRAGMA("GCC diagnostic pop") \
+ } \
+ bool _name##_is_empty(void) \
+ { \
+ GCC_PRAGMA("GCC diagnostic push") \
+ GCC_PRAGMA("GCC diagnostic ignored \"-Waddress\"") \
+ ASSERT((_p_queue) != NULL); \
+ GCC_PRAGMA("GCC diagnostic pop") \
+ return nrf_queue_is_empty(_p_queue); \
+ } \
+ size_t _name##_utilization_get(void) \
+ { \
+ GCC_PRAGMA("GCC diagnostic push") \
+ GCC_PRAGMA("GCC diagnostic ignored \"-Waddress\"") \
+ ASSERT((_p_queue) != NULL); \
+ GCC_PRAGMA("GCC diagnostic pop") \
+ return nrf_queue_utilization_get(_p_queue); \
+ } \
+ size_t _name##_available_get(void) \
+ { \
+ GCC_PRAGMA("GCC diagnostic push") \
+ GCC_PRAGMA("GCC diagnostic ignored \"-Waddress\"") \
+ ASSERT((_p_queue) != NULL); \
+ GCC_PRAGMA("GCC diagnostic pop") \
+ return nrf_queue_available_get(_p_queue); \
+ } \
+ size_t _name##_max_utilization_get(void) \
+ { \
+ GCC_PRAGMA("GCC diagnostic push") \
+ GCC_PRAGMA("GCC diagnostic ignored \"-Waddress\"") \
+ ASSERT((_p_queue) != NULL); \
+ GCC_PRAGMA("GCC diagnostic pop") \
+ return nrf_queue_max_utilization_get(_p_queue); \
+ } \
+ void _name##_reset(void) \
+ { \
+ GCC_PRAGMA("GCC diagnostic push") \
+ GCC_PRAGMA("GCC diagnostic ignored \"-Waddress\"") \
+ ASSERT((_p_queue) != NULL); \
+ GCC_PRAGMA("GCC diagnostic pop") \
+ nrf_queue_reset(_p_queue); \
+ }
+
+/**@brief Function for pushing an element to the end of queue.
+ *
+ * @param[in] p_queue Pointer to the nrf_queue_t instance.
+ * @param[in] p_element Pointer to the element that will be stored in the queue.
+ *
+ * @return NRF_SUCCESS If an element has been successfully added.
+ * @return NRF_ERROR_NO_MEM If the queue is full (only in @ref NRF_QUEUE_MODE_NO_OVERFLOW).
+ */
+ret_code_t nrf_queue_push(nrf_queue_t const * p_queue, void const * p_element);
+
+/**@brief Generic pop implementation.
+ *
+ * @param[in] p_queue Pointer to the nrf_queue_t instance.
+ * @param[out] p_element Pointer where the element will be copied.
+ * @param[out] just_peek If true, the returned element will not be removed from queue.
+ *
+ * @return NRF_SUCCESS If an element was returned.
+ * @return NRF_ERROR_NOT_FOUND If there are no more elements in the queue.
+ */
+ret_code_t nrf_queue_generic_pop(nrf_queue_t const * p_queue,
+ void * p_element,
+ bool just_peek);
+
+/**@brief Pop element from the front of the queue.
+ *
+ * @param[in] _p_queue Pointer to the nrf_queue_t instance.
+ * @param[out] _p_element Pointer where the element will be copied.
+ *
+ * @return NRF_SUCCESS If an element was returned.
+ * @return NRF_ERROR_NOT_FOUND If there are no more elements in the queue.
+ */
+#define nrf_queue_pop(_p_queue, _p_element) nrf_queue_generic_pop((_p_queue), (_p_element), false)
+
+/**@brief Peek element from the front of the queue.
+ *
+ * @param[in] _p_queue Pointer to the nrf_queue_t instance.
+ * @param[out] _p_element Pointer where the element will be copied.
+ *
+ * @return NRF_SUCCESS If an element was returned.
+ * @return NRF_ERROR_NOT_FOUND If there are no more elements in the queue.
+ */
+#define nrf_queue_peek(_p_queue, _p_element) nrf_queue_generic_pop((_p_queue), (_p_element), true)
+
+/**@brief Function for writing elements to the queue.
+ *
+ * @param[in] p_queue Pointer to the nrf_queue_t instance.
+ * @param[in] p_data Pointer to the buffer with elements to write.
+ * @param[in] element_count Number of elements to write.
+ *
+ * @return NRF_SUCCESS If an element was written.
+ * @return NRF_ERROR_NO_MEM There is not enough space in the queue. No element was written.
+ */
+ret_code_t nrf_queue_write(nrf_queue_t const * p_queue,
+ void const * p_data,
+ size_t element_count);
+
+/**@brief Function for writing a portion of elements to the queue.
+ *
+ * @param[in] p_queue Pointer to the nrf_queue_t instance.
+ * @param[in] p_data Pointer to the buffer with elements to write.
+ * @param[in] element_count Number of elements to write.
+ *
+ * @return The number of added elements.
+ */
+size_t nrf_queue_in(nrf_queue_t const * p_queue,
+ void const * p_data,
+ size_t element_count);
+
+/**@brief Function for reading elements from the queue.
+ *
+ * @param[in] p_queue Pointer to the nrf_queue_t instance.
+ * @param[out] p_data Pointer to the buffer where elements will be copied.
+ * @param[in] element_count Number of elements to read.
+ *
+ * @return NRF_SUCCESS If an element was returned.
+ * @return NRF_ERROR_NOT_FOUND There is not enough elements in the queue.
+ */
+ret_code_t nrf_queue_read(nrf_queue_t const * p_queue,
+ void * p_data,
+ size_t element_count);
+
+/**@brief Function for reading a portion of elements from the queue.
+ *
+ * @param[in] p_queue Pointer to the nrf_queue_t instance.
+ * @param[out] p_data Pointer to the buffer where elements will be copied.
+ * @param[in] element_count Number of elements to read.
+ *
+ * @return The number of read elements.
+ */
+size_t nrf_queue_out(nrf_queue_t const * p_queue,
+ void * p_data,
+ size_t element_count);
+
+/**@brief Function for checking if the queue is full.
+ *
+ * @param[in] p_queue Pointer to the queue instance.
+ *
+ * @return True if the queue is full.
+ */
+bool nrf_queue_is_full(nrf_queue_t const * p_queue);
+
+/**@brief Function for checking if the queue is empty.
+ *
+ * @param[in] p_queue Pointer to the queue instance.
+ *
+ * @return True if the queue is empty.
+ */
+bool nrf_queue_is_empty(nrf_queue_t const * p_queue);
+
+/**@brief Function for getting the current queue utilization.
+ *
+ * @param[in] p_queue Pointer to the queue instance.
+ *
+ * @return Current queue utilization.
+ */
+size_t nrf_queue_utilization_get(nrf_queue_t const * p_queue);
+
+/**@brief Function for getting the size of available space.
+ *
+ * @param[in] p_queue Pointer to the queue instance.
+ *
+ * @return Size of available space.
+ */
+size_t nrf_queue_available_get(nrf_queue_t const * p_queue);
+
+/**@brief Function for getting the maximal queue utilization.
+ *
+ * @param[in] p_queue Pointer to the queue instance.
+ *
+ * @return Maximal queue utilization.
+ */
+size_t nrf_queue_max_utilization_get(nrf_queue_t const * p_queue);
+
+/**@brief Function for resetting the maximal queue utilization.
+ *
+ * @param[in] p_queue Pointer to the queue instance.
+ *
+ */
+void nrf_queue_max_utilization_reset(nrf_queue_t const * p_queue);
+
+/**@brief Function for resetting the queue state.
+ *
+ * @param[in] p_queue Pointer to the queue instance.
+ */
+void nrf_queue_reset(nrf_queue_t const * p_queue);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // NRF_QUEUE_H__
+/** @} */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/scheduler/app_scheduler.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/scheduler/app_scheduler.c
new file mode 100644
index 0000000..d5357ca
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/scheduler/app_scheduler.c
@@ -0,0 +1,288 @@
+/**
+ * Copyright (c) 2012 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#include "sdk_common.h"
+#if NRF_MODULE_ENABLED(APP_SCHEDULER)
+#include "app_scheduler.h"
+#include <stdlib.h>
+#include <stdint.h>
+#include <string.h>
+#include "nrf_soc.h"
+#include "nrf_assert.h"
+#include "app_util_platform.h"
+
+/**@brief Structure for holding a scheduled event header. */
+typedef struct
+{
+ app_sched_event_handler_t handler; /**< Pointer to event handler to receive the event. */
+ uint16_t event_data_size; /**< Size of event data. */
+} event_header_t;
+
+STATIC_ASSERT(sizeof(event_header_t) <= APP_SCHED_EVENT_HEADER_SIZE);
+
+static event_header_t * m_queue_event_headers; /**< Array for holding the queue event headers. */
+static uint8_t * m_queue_event_data; /**< Array for holding the queue event data. */
+static volatile uint8_t m_queue_start_index; /**< Index of queue entry at the start of the queue. */
+static volatile uint8_t m_queue_end_index; /**< Index of queue entry at the end of the queue. */
+static uint16_t m_queue_event_size; /**< Maximum event size in queue. */
+static uint16_t m_queue_size; /**< Number of queue entries. */
+
+#if APP_SCHEDULER_WITH_PROFILER
+static uint16_t m_max_queue_utilization; /**< Maximum observed queue utilization. */
+#endif
+
+#if APP_SCHEDULER_WITH_PAUSE
+static uint32_t m_scheduler_paused_counter = 0; /**< Counter storing the difference between pausing
+ and resuming the scheduler. */
+#endif
+
+/**@brief Function for incrementing a queue index, and handle wrap-around.
+ *
+ * @param[in] index Old index.
+ *
+ * @return New (incremented) index.
+ */
+static __INLINE uint8_t next_index(uint8_t index)
+{
+ return (index < m_queue_size) ? (index + 1) : 0;
+}
+
+
+static __INLINE uint8_t app_sched_queue_full()
+{
+ uint8_t tmp = m_queue_start_index;
+ return next_index(m_queue_end_index) == tmp;
+}
+
+/**@brief Macro for checking if a queue is full. */
+#define APP_SCHED_QUEUE_FULL() app_sched_queue_full()
+
+
+static __INLINE uint8_t app_sched_queue_empty()
+{
+ uint8_t tmp = m_queue_start_index;
+ return m_queue_end_index == tmp;
+}
+
+/**@brief Macro for checking if a queue is empty. */
+#define APP_SCHED_QUEUE_EMPTY() app_sched_queue_empty()
+
+
+uint32_t app_sched_init(uint16_t event_size, uint16_t queue_size, void * p_event_buffer)
+{
+ uint16_t data_start_index = (queue_size + 1) * sizeof(event_header_t);
+
+ // Check that buffer is correctly aligned
+ if (!is_word_aligned(p_event_buffer))
+ {
+ return NRF_ERROR_INVALID_PARAM;
+ }
+
+ // Initialize event scheduler
+ m_queue_event_headers = p_event_buffer;
+ m_queue_event_data = &((uint8_t *)p_event_buffer)[data_start_index];
+ m_queue_end_index = 0;
+ m_queue_start_index = 0;
+ m_queue_event_size = event_size;
+ m_queue_size = queue_size;
+
+#if APP_SCHEDULER_WITH_PROFILER
+ m_max_queue_utilization = 0;
+#endif
+
+ return NRF_SUCCESS;
+}
+
+
+uint16_t app_sched_queue_space_get()
+{
+ uint16_t start = m_queue_start_index;
+ uint16_t end = m_queue_end_index;
+ uint16_t free_space = m_queue_size - ((end >= start) ?
+ (end - start) : (m_queue_size + 1 - start + end));
+ return free_space;
+}
+
+
+#if APP_SCHEDULER_WITH_PROFILER
+static void queue_utilization_check(void)
+{
+ uint16_t start = m_queue_start_index;
+ uint16_t end = m_queue_end_index;
+ uint16_t queue_utilization = (end >= start) ? (end - start) :
+ (m_queue_size + 1 - start + end);
+
+ if (queue_utilization > m_max_queue_utilization)
+ {
+ m_max_queue_utilization = queue_utilization;
+ }
+}
+
+uint16_t app_sched_queue_utilization_get(void)
+{
+ return m_max_queue_utilization;
+}
+#endif // APP_SCHEDULER_WITH_PROFILER
+
+
+uint32_t app_sched_event_put(void const * p_event_data,
+ uint16_t event_data_size,
+ app_sched_event_handler_t handler)
+{
+ uint32_t err_code;
+
+ if (event_data_size <= m_queue_event_size)
+ {
+ uint16_t event_index = 0xFFFF;
+
+ CRITICAL_REGION_ENTER();
+
+ if (!APP_SCHED_QUEUE_FULL())
+ {
+ event_index = m_queue_end_index;
+ m_queue_end_index = next_index(m_queue_end_index);
+
+ #if APP_SCHEDULER_WITH_PROFILER
+ // This function call must be protected with critical region because
+ // it modifies 'm_max_queue_utilization'.
+ queue_utilization_check();
+ #endif
+ }
+
+ CRITICAL_REGION_EXIT();
+
+ if (event_index != 0xFFFF)
+ {
+ // NOTE: This can be done outside the critical region since the event consumer will
+ // always be called from the main loop, and will thus never interrupt this code.
+ m_queue_event_headers[event_index].handler = handler;
+ if ((p_event_data != NULL) && (event_data_size > 0))
+ {
+ memcpy(&m_queue_event_data[event_index * m_queue_event_size],
+ p_event_data,
+ event_data_size);
+ m_queue_event_headers[event_index].event_data_size = event_data_size;
+ }
+ else
+ {
+ m_queue_event_headers[event_index].event_data_size = 0;
+ }
+
+ err_code = NRF_SUCCESS;
+ }
+ else
+ {
+ err_code = NRF_ERROR_NO_MEM;
+ }
+ }
+ else
+ {
+ err_code = NRF_ERROR_INVALID_LENGTH;
+ }
+
+ return err_code;
+}
+
+
+#if APP_SCHEDULER_WITH_PAUSE
+void app_sched_pause(void)
+{
+ CRITICAL_REGION_ENTER();
+
+ if (m_scheduler_paused_counter < UINT32_MAX)
+ {
+ m_scheduler_paused_counter++;
+ }
+ CRITICAL_REGION_EXIT();
+}
+
+void app_sched_resume(void)
+{
+ CRITICAL_REGION_ENTER();
+
+ if (m_scheduler_paused_counter > 0)
+ {
+ m_scheduler_paused_counter--;
+ }
+ CRITICAL_REGION_EXIT();
+}
+#endif //APP_SCHEDULER_WITH_PAUSE
+
+
+/**@brief Function for checking if scheduler is paused which means that should break processing
+ * events.
+ *
+ * @return Boolean value - true if scheduler is paused, false otherwise.
+ */
+static __INLINE bool is_app_sched_paused(void)
+{
+#if APP_SCHEDULER_WITH_PAUSE
+ return (m_scheduler_paused_counter > 0);
+#else
+ return false;
+#endif
+}
+
+
+void app_sched_execute(void)
+{
+ while (!is_app_sched_paused() && !APP_SCHED_QUEUE_EMPTY())
+ {
+ // Since this function is only called from the main loop, there is no
+ // need for a critical region here, however a special care must be taken
+ // regarding update of the queue start index (see the end of the loop).
+ uint16_t event_index = m_queue_start_index;
+
+ void * p_event_data;
+ uint16_t event_data_size;
+ app_sched_event_handler_t event_handler;
+
+ p_event_data = &m_queue_event_data[event_index * m_queue_event_size];
+ event_data_size = m_queue_event_headers[event_index].event_data_size;
+ event_handler = m_queue_event_headers[event_index].handler;
+
+ event_handler(p_event_data, event_data_size);
+
+ // Event processed, now it is safe to move the queue start index,
+ // so the queue entry occupied by this event can be used to store
+ // a next one.
+ m_queue_start_index = next_index(m_queue_start_index);
+ }
+}
+#endif //NRF_MODULE_ENABLED(APP_SCHEDULER)
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/scheduler/app_scheduler.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/scheduler/app_scheduler.h
new file mode 100644
index 0000000..f55f389
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/scheduler/app_scheduler.h
@@ -0,0 +1,211 @@
+/**
+ * Copyright (c) 2012 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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
+ *
+ * @defgroup app_scheduler Scheduler
+ * @{
+ * @ingroup app_common
+ *
+ * @brief The scheduler is used for transferring execution from the interrupt context to the main
+ * context.
+ *
+ * @details See @ref seq_diagrams_sched for sequence diagrams illustrating the flow of events
+ * when using the Scheduler.
+ *
+ * @section app_scheduler_req Requirements:
+ *
+ * @subsection main_context_logic Logic in main context:
+ *
+ * - Define an event handler for each type of event expected.
+ * - Initialize the scheduler by calling the APP_SCHED_INIT() macro before entering the
+ * application main loop.
+ * - Call app_sched_execute() from the main loop each time the application wakes up because of an
+ * event (typically when sd_app_evt_wait() returns).
+ *
+ * @subsection int_context_logic Logic in interrupt context:
+ *
+ * - In the interrupt handler, call app_sched_event_put()
+ * with the appropriate data and event handler. This will insert an event into the
+ * scheduler's queue. The app_sched_execute() function will pull this event and call its
+ * handler in the main context.
+ *
+ * @if (PERIPHERAL)
+ * For an example usage of the scheduler, see the implementations of
+ * @ref ble_sdk_app_hids_mouse and @ref ble_sdk_app_hids_keyboard.
+ * @endif
+ *
+ * @image html scheduler_working.svg The high level design of the scheduler
+ */
+
+#ifndef APP_SCHEDULER_H__
+#define APP_SCHEDULER_H__
+
+#include "sdk_config.h"
+#include <stdint.h>
+#include "app_error.h"
+#include "app_util.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define APP_SCHED_EVENT_HEADER_SIZE 8 /**< Size of app_scheduler.event_header_t (only for use inside APP_SCHED_BUF_SIZE()). */
+
+/**@brief Compute number of bytes required to hold the scheduler buffer.
+ *
+ * @param[in] EVENT_SIZE Maximum size of events to be passed through the scheduler.
+ * @param[in] QUEUE_SIZE Number of entries in scheduler queue (i.e. the maximum number of events
+ * that can be scheduled for execution).
+ *
+ * @return Required scheduler buffer size (in bytes).
+ */
+#define APP_SCHED_BUF_SIZE(EVENT_SIZE, QUEUE_SIZE) \
+ (((EVENT_SIZE) + APP_SCHED_EVENT_HEADER_SIZE) * ((QUEUE_SIZE) + 1))
+
+/**@brief Scheduler event handler type. */
+typedef void (*app_sched_event_handler_t)(void * p_event_data, uint16_t event_size);
+
+/**@brief Macro for initializing the event scheduler.
+ *
+ * @details It will also handle dimensioning and allocation of the memory buffer required by the
+ * scheduler, making sure the buffer is correctly aligned.
+ *
+ * @param[in] EVENT_SIZE Maximum size of events to be passed through the scheduler.
+ * @param[in] QUEUE_SIZE Number of entries in scheduler queue (i.e. the maximum number of events
+ * that can be scheduled for execution).
+ *
+ * @note Since this macro allocates a buffer, it must only be called once (it is OK to call it
+ * several times as long as it is from the same location, e.g. to do a reinitialization).
+ */
+#define APP_SCHED_INIT(EVENT_SIZE, QUEUE_SIZE) \
+ do \
+ { \
+ static uint32_t APP_SCHED_BUF[CEIL_DIV(APP_SCHED_BUF_SIZE((EVENT_SIZE), (QUEUE_SIZE)), \
+ sizeof(uint32_t))]; \
+ uint32_t ERR_CODE = app_sched_init((EVENT_SIZE), (QUEUE_SIZE), APP_SCHED_BUF); \
+ APP_ERROR_CHECK(ERR_CODE); \
+ } while (0)
+
+/**@brief Function for initializing the Scheduler.
+ *
+ * @details It must be called before entering the main loop.
+ *
+ * @param[in] max_event_size Maximum size of events to be passed through the scheduler.
+ * @param[in] queue_size Number of entries in scheduler queue (i.e. the maximum number of
+ * events that can be scheduled for execution).
+ * @param[in] p_evt_buffer Pointer to memory buffer for holding the scheduler queue. It must
+ * be dimensioned using the APP_SCHED_BUFFER_SIZE() macro. The buffer
+ * must be aligned to a 4 byte boundary.
+ *
+ * @note Normally initialization should be done using the APP_SCHED_INIT() macro, as that will both
+ * allocate the scheduler buffer, and also align the buffer correctly.
+ *
+ * @retval NRF_SUCCESS Successful initialization.
+ * @retval NRF_ERROR_INVALID_PARAM Invalid parameter (buffer not aligned to a 4 byte
+ * boundary).
+ */
+uint32_t app_sched_init(uint16_t max_event_size, uint16_t queue_size, void * p_evt_buffer);
+
+/**@brief Function for executing all scheduled events.
+ *
+ * @details This function must be called from within the main loop. It will execute all events
+ * scheduled since the last time it was called.
+ */
+void app_sched_execute(void);
+
+/**@brief Function for scheduling an event.
+ *
+ * @details Puts an event into the event queue.
+ *
+ * @param[in] p_event_data Pointer to event data to be scheduled.
+ * @param[in] event_size Size of event data to be scheduled.
+ * @param[in] handler Event handler to receive the event.
+ *
+ * @return NRF_SUCCESS on success, otherwise an error code.
+ */
+uint32_t app_sched_event_put(void const * p_event_data,
+ uint16_t event_size,
+ app_sched_event_handler_t handler);
+
+/**@brief Function for getting the maximum observed queue utilization.
+ *
+ * Function for tuning the module and determining QUEUE_SIZE value and thus module RAM usage.
+ *
+ * @note @ref APP_SCHEDULER_WITH_PROFILER must be enabled to use this functionality.
+ *
+ * @return Maximum number of events in queue observed so far.
+ */
+uint16_t app_sched_queue_utilization_get(void);
+
+/**@brief Function for getting the current amount of free space in the queue.
+ *
+ * @details The real amount of free space may be less if entries are being added from an interrupt.
+ * To get the sxact value, this function should be called from the critical section.
+ *
+ * @return Amount of free space in the queue.
+ */
+uint16_t app_sched_queue_space_get(void);
+
+/**@brief A function to pause the scheduler.
+ *
+ * @details When the scheduler is paused events are not pulled from the scheduler queue for
+ * processing. The function can be called multiple times. To unblock the scheduler the
+ * function @ref app_sched_resume has to be called the same number of times.
+ *
+ * @note @ref APP_SCHEDULER_WITH_PAUSE must be enabled to use this functionality.
+ */
+void app_sched_pause(void);
+
+/**@brief A function to resume a scheduler.
+ *
+ * @details To unblock the scheduler this function has to be called the same number of times as
+ * @ref app_sched_pause function.
+ *
+ * @note @ref APP_SCHEDULER_WITH_PAUSE must be enabled to use this functionality.
+ */
+void app_sched_resume(void);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // APP_SCHEDULER_H__
+
+/** @} */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/scheduler/app_scheduler_serconn.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/scheduler/app_scheduler_serconn.c
new file mode 100644
index 0000000..a4a5bf6
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/scheduler/app_scheduler_serconn.c
@@ -0,0 +1,298 @@
+/**
+ * Copyright (c) 2012 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#include "app_scheduler.h"
+#include <stdlib.h>
+#include <stdint.h>
+#include <string.h>
+#include "nrf_soc.h"
+#include "nrf_assert.h"
+#include "app_util.h"
+#include "app_util_platform.h"
+
+/**@brief Structure for holding a scheduled event header. */
+typedef struct
+{
+ app_sched_event_handler_t handler; /**< Pointer to event handler to receive the event. */
+ uint16_t event_data_size; /**< Size of event data. */
+} event_header_t;
+
+STATIC_ASSERT(sizeof (event_header_t) <= APP_SCHED_EVENT_HEADER_SIZE);
+
+static event_header_t * m_queue_event_headers; /**< Array for holding the queue event headers. */
+static uint8_t * m_queue_event_data; /**< Array for holding the queue event data. */
+static volatile uint8_t m_queue_start_index; /**< Index of queue entry at the start of the queue. */
+static volatile uint8_t m_queue_end_index; /**< Index of queue entry at the end of the queue. */
+static uint16_t m_queue_event_size; /**< Maximum event size in queue. */
+static uint16_t m_queue_size; /**< Number of queue entries. */
+
+#if APP_SCHEDULER_WITH_PROFILER
+static uint16_t m_max_queue_utilization; /**< Maximum observed queue utilization. */
+#endif
+
+static uint32_t m_scheduler_paused_counter = 0; /**< Counter storing the difference between pausing
+ and resuming the scheduler. */
+
+/**@brief Function for incrementing a queue index, and handle wrap-around.
+ *
+ * @param[in] index Old index.
+ *
+ * @return New (incremented) index.
+ */
+static __INLINE uint8_t next_index(uint8_t index)
+{
+ return (index < m_queue_size) ? (index + 1) : 0;
+}
+
+static __INLINE uint8_t app_sched_queue_full(void)
+{
+ uint8_t tmp = m_queue_start_index;
+ return next_index(m_queue_end_index) == tmp;
+}
+
+/**@brief Macro for checking if a queue is full. */
+#define APP_SCHED_QUEUE_FULL() app_sched_queue_full()
+
+static __INLINE uint8_t app_sched_queue_empty(void)
+{
+ uint8_t tmp = m_queue_start_index;
+ return m_queue_end_index == tmp;
+}
+
+/**@brief Macro for checking if a queue is empty. */
+#define APP_SCHED_QUEUE_EMPTY() app_sched_queue_empty()
+
+
+uint32_t app_sched_init(uint16_t event_size, uint16_t queue_size, void * p_event_buffer)
+{
+ uint16_t data_start_index = (queue_size + 1) * sizeof (event_header_t);
+
+ //Check that buffer is correctly aligned
+ if (!is_word_aligned(p_event_buffer))
+ {
+ return NRF_ERROR_INVALID_PARAM;
+ }
+
+ //Initialize event scheduler
+ m_queue_event_headers = p_event_buffer;
+ m_queue_event_data = &((uint8_t *)p_event_buffer)[data_start_index];
+ m_queue_end_index = 0;
+ m_queue_start_index = 0;
+ m_queue_event_size = event_size;
+ m_queue_size = queue_size;
+
+#if APP_SCHEDULER_WITH_PROFILER
+ m_max_queue_utilization = 0;
+#endif
+
+ return NRF_SUCCESS;
+}
+
+
+uint16_t app_sched_queue_space_get()
+{
+ uint16_t start = m_queue_start_index;
+ uint16_t end = m_queue_end_index;
+ uint16_t free_space = m_queue_size - ((end >= start) ?
+ (end - start) : (m_queue_size + 1 - start + end));
+ return free_space;
+}
+
+
+#if APP_SCHEDULER_WITH_PROFILER
+static __INLINE void check_queue_utilization(void)
+{
+ uint16_t start = m_queue_start_index;
+ uint16_t end = m_queue_end_index;
+ uint16_t queue_utilization = (end >= start) ? (end - start) :
+ (m_queue_size + 1 - start + end);
+
+ if (queue_utilization > m_max_queue_utilization)
+ {
+ m_max_queue_utilization = queue_utilization;
+ }
+}
+
+uint16_t app_sched_queue_utilization_get(void)
+{
+ return m_max_queue_utilization;
+}
+#endif // APP_SCHEDULER_WITH_PROFILER
+
+
+uint32_t app_sched_event_put(void * p_event_data,
+ uint16_t event_data_size,
+ app_sched_event_handler_t handler)
+{
+ uint32_t err_code;
+
+ if (event_data_size <= m_queue_event_size)
+ {
+ uint16_t event_index = 0xFFFF;
+
+ CRITICAL_REGION_ENTER();
+
+ if (!APP_SCHED_QUEUE_FULL())
+ {
+ event_index = m_queue_end_index;
+ m_queue_end_index = next_index(m_queue_end_index);
+ }
+
+ CRITICAL_REGION_EXIT();
+
+ if (event_index != 0xFFFF)
+ {
+ //NOTE: This can be done outside the critical region since the event consumer will
+ //always be called from the main loop, and will thus never interrupt this code.
+ m_queue_event_headers[event_index].handler = handler;
+
+ if ((p_event_data != NULL) && (event_data_size > 0))
+ {
+ memcpy(&m_queue_event_data[event_index * m_queue_event_size],
+ p_event_data,
+ event_data_size);
+ m_queue_event_headers[event_index].event_data_size = event_data_size;
+ }
+ else
+ {
+ m_queue_event_headers[event_index].event_data_size = 0;
+ }
+
+ #if APP_SCHEDULER_WITH_PROFILER
+ check_queue_utilization();
+ #endif
+
+ err_code = NRF_SUCCESS;
+ }
+ else
+ {
+ err_code = NRF_ERROR_NO_MEM;
+ }
+ }
+ else
+ {
+ err_code = NRF_ERROR_INVALID_LENGTH;
+ }
+
+ return err_code;
+}
+
+
+/**@brief Function for reading the next event from specified event queue.
+ *
+ * @param[out] pp_event_data Pointer to pointer to event data.
+ * @param[out] p_event_data_size Pointer to size of event data.
+ * @param[out] p_event_handler Pointer to event handler function pointer.
+ *
+ * @return NRF_SUCCESS if new event, NRF_ERROR_NOT_FOUND if event queue is empty.
+ */
+static uint32_t app_sched_event_get(void * * pp_event_data,
+ uint16_t * p_event_data_size,
+ app_sched_event_handler_t * p_event_handler)
+{
+ uint32_t err_code = NRF_ERROR_NOT_FOUND;
+
+ if (!APP_SCHED_QUEUE_EMPTY())
+ {
+ uint16_t event_index;
+
+ //NOTE: There is no need for a critical region here, as this function will only be called
+ //from app_sched_execute() from inside the main loop, so it will never interrupt
+ //app_sched_event_put(). Also, updating of (i.e. writing to) the start index will be
+ //an atomic operation.
+ event_index = m_queue_start_index;
+ m_queue_start_index = next_index(m_queue_start_index);
+
+ *pp_event_data = &m_queue_event_data[event_index * m_queue_event_size];
+ *p_event_data_size = m_queue_event_headers[event_index].event_data_size;
+ *p_event_handler = m_queue_event_headers[event_index].handler;
+
+ err_code = NRF_SUCCESS;
+ }
+
+ return err_code;
+}
+
+
+void app_sched_pause(void)
+{
+ CRITICAL_REGION_ENTER();
+
+ if (m_scheduler_paused_counter < UINT32_MAX)
+ {
+ m_scheduler_paused_counter++;
+ }
+ CRITICAL_REGION_EXIT();
+}
+
+
+void app_sched_resume(void)
+{
+ CRITICAL_REGION_ENTER();
+
+ if (m_scheduler_paused_counter > 0)
+ {
+ m_scheduler_paused_counter--;
+ }
+ CRITICAL_REGION_EXIT();
+}
+
+/**@brief Function for checking if scheduler is paused which means that should break processing
+ * events.
+ *
+ * @return Boolean value - true if scheduler is paused, false otherwise.
+ */
+static __INLINE bool is_app_sched_paused(void)
+{
+ return (m_scheduler_paused_counter > 0);
+}
+
+void app_sched_execute(void)
+{
+ void * p_event_data;
+ uint16_t event_data_size;
+ app_sched_event_handler_t event_handler;
+
+ //Get next event (if any), and execute handler
+ while ((!is_app_sched_paused()) &&
+ (app_sched_event_get(&p_event_data, &event_data_size, &event_handler) == NRF_SUCCESS))
+ {
+ event_handler(p_event_data, event_data_size);
+ }
+}
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/sdcard/app_sdcard.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/sdcard/app_sdcard.c
new file mode 100644
index 0000000..763bf60
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/sdcard/app_sdcard.c
@@ -0,0 +1,1179 @@
+/**
+ * Copyright (c) 2016 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#include "sdk_config.h"
+#if APP_SDCARD_ENABLED
+
+#include "app_sdcard.h"
+#include "nrf_gpio.h"
+#include "nrf_drv_spi.h"
+#include "app_error.h"
+#include "nrf_assert.h"
+
+#include "nrf_pt.h"
+
+#define CMD_MASK 0x40
+#define ACMD_MASK 0x80
+#define CMD0 (CMD_MASK | 0) /**< SDC/MMC command 0: GO_IDLE_STATE. */
+#define CMD1 (CMD_MASK | 1) /**< SDC/MMC command 1: SEND_OP_COND (MMC). */
+#define CMD8 (CMD_MASK | 8) /**< SDC/MMC command 8: SEND_IF_COND. */
+#define CMD9 (CMD_MASK | 9) /**< SDC/MMC command 9: SEND_CSD. */
+#define CMD10 (CMD_MASK | 10) /**< SDC/MMC command 10: SEND_CID. */
+#define CMD12 (CMD_MASK | 12) /**< SDC/MMC command 12: STOP_TRANSMISSION. */
+#define CMD16 (CMD_MASK | 16) /**< SDC/MMC command 16: SET_BLOCKLEN. */
+#define CMD17 (CMD_MASK | 17) /**< SDC/MMC command 17: READ_SINGLE_BLOCK. */
+#define CMD18 (CMD_MASK | 18) /**< SDC/MMC command 18: READ_MULTIPLE_BLOCK. */
+#define CMD23 (CMD_MASK | 23) /**< SDC/MMC command 23: SET_BLOCK_COUNT (MMC). */
+#define CMD24 (CMD_MASK | 24) /**< SDC/MMC command 24: WRITE_BLOCK. */
+#define CMD25 (CMD_MASK | 25) /**< SDC/MMC command 25: WRITE_MULTIPLE_BLOCK. */
+#define CMD32 (CMD_MASK | 32) /**< SDC/MMC command 32: ERASE_ER_BLK_START. */
+#define CMD33 (CMD_MASK | 33) /**< SDC/MMC command 33: ERASE_ER_BLK_END. */
+#define CMD38 (CMD_MASK | 38) /**< SDC/MMC command 38: ERASE. */
+#define CMD55 (CMD_MASK | 55) /**< SDC/MMC command 55: APP_CMD. */
+#define CMD58 (CMD_MASK | 58) /**< SDC/MMC command 58: READ_OCR. */
+#define ACMD13 (ACMD_MASK | CMD_MASK | 13) /**< SDC application command 13: SD_STATUS. */
+#define ACMD23 (ACMD_MASK | CMD_MASK | 23) /**< SDC application command 23: SET_WR_BLK_ERASE_COUNT. */
+#define ACMD41 (ACMD_MASK | CMD_MASK | 41) /**< SDC application command 41: SEND_OP_COND. */
+
+#define IS_ACMD(CMD) ((CMD) & ACMD_MASK) /**< Check if command is an application command (ACMD). */
+
+#define SDC_COMMAND_LEN 6 /**< Length of a command structure sent to the card. */
+#define SDC_COMMAND_POS 0 /**< Position of a command field inside the command structure. */
+#define SDC_COMMAND_MASK 0x7F /**< Bit mask of a command field. */
+#define SDC_COMMAND_ARG_POS 1 /**< Position of a 32-bit argument inside the command structure. */
+#define SDC_COMMAND_CRC_POS 5 /**< Position of a CRC field inside the command structure. */
+
+#define SDC_MAX_NCR 8 /**< Maximum number of "busy" bytes sent before command response. */
+#define SDC_R1_LEN 1 /**< Length of R1 format response. */
+#define SDC_R3_LEN 5 /**< Length of R3 format response. */
+#define SDC_R7_LEN 5 /**< Length of R7 format response. */
+#define SDC_R_MAX_LEN 5 /**< Maximum length of command response. */
+
+#define SDC_FLAG_IN_IDLE_STATE 0x01 /**< R1 response flag bit mask: idle state. */
+#define SDC_FLAG_ERASE_RESET 0x02 /**< R1 response flag bit mask: erase reset. */
+#define SDC_FLAG_ILLEGAL_COMMAND 0x04 /**< R1 response flag bit mask: illegal command. */
+#define SDC_FLAG_COM_CRC_ERROR 0x08 /**< R1 response flag bit mask: CRC error. */
+#define SDC_FLAG_ERASE_SEQUENCE_ERROR 0x10 /**< R1 response flag bit mask: erase sequence error. */
+#define SDC_FLAG_ADDRESS_ERROR 0x20 /**< R1 response flag bit mask: address error. */
+#define SDC_FLAG_PARAMETER_ERROR 0x40 /**< R1 response flag bit mask: parameter error. */
+
+#define SDC_HCS_FLAG_MASK (1uL << 30) /**< High capacity support bit mask. */
+
+#define SDC_EMPTY_BYTE 0xFF /**< Idle state token. */
+#define SDC_BUSY_BYTE 0x00 /**< Busy byte token. */
+#define SDC_TOKEN_START_BLOCK 0xFE /**< Data block start token. */
+#define SDC_TOKEN_START_BLOCK_MULT 0xFC /**< Data block start token for multiple write operation. */
+#define SDC_TOKEN_DATA_RESP_MASK 0x1F /**< Data response token mask. */
+#define SDC_TOKEN_DATA_RESP_ACCEPTED 0x05 /**< Data response message: accepted. */
+#define SDC_TOKEN_DATA_RESP_CRC_ERR 0x0B /**< Data response message: CRC error. */
+#define SDC_TOKEN_DATA_RESP_DATA_ERR 0x0D /**< Data response message: data error. */
+#define SDC_TOKEN_STOP_TRAN 0xFD /**< Stop transmission token. */
+
+#define SDC_MAX_RETRY_COUNT_INIT 2000 /**< Maximum number of retries while card is busy (identification stage). */
+#define SDC_MAX_RETRY_COUNT 20000 /**< Maximum number of retries while card is busy. */
+#define SDC_SPI_MTU 240 /**< Maximum number of bytes in one SPI transaction. */
+#define SDC_CRC_CMD0 0x95 /**< Fixed CRC for reset command. */
+#define SDC_CRC_CMD8 0x87 /**< Fixed CRC for CMD8. */
+#define SDC_CRC_DUMMY 0xFF /**< Dummy CRC value. */
+
+#define SDC_CMD_BUF_LEN 16 /**< Size of a buffer for storing SDC commands. */
+#define SDC_WORK_BUF_LEN 16 /**< Size of a working buffer. */
+#define SDC_DATA_WAIT_TX_SIZE 16 /**< Number of bytes sent during data / busy wait. */
+
+#define SDC_CS_ASSERT() do { nrf_gpio_pin_clear(m_cb.cs_pin); } while (0) /**< Set CS pin to active state. */
+#define SDC_CS_DEASSERT() do { nrf_gpio_pin_set(m_cb.cs_pin); } while (0) /**< Set CS pin to inactive state. */
+
+#define SDC_PT &m_cb.state.pt /**< Macro for getting SDC task structure pointer (Protothread). */
+#define SDC_PT_SUB &m_cb.state.pt_sub /**< Macro for getting SDC sub-task structure pointer (Protothread). */
+
+/** Break current task (Protothread). */
+#define SDC_BREAK(PT, EXIT_CODE) do { \
+ *p_exit_code = (EXIT_CODE); \
+ PT_EXIT(PT); \
+ } while (0)
+
+/**< Check the value of R1 response and break current task on error. */
+#define SDC_RESP_CHECK(PT, R1) do { \
+ if ((R1) & ~(SDC_FLAG_IN_IDLE_STATE | SDC_FLAG_ERASE_RESET)) \
+ { \
+ SDC_BREAK((PT), SDC_ERROR_COMMUNICATION); \
+ } \
+ } while (0)
+
+/**< Check the result of an SDC operation and break on failure. */
+#define SDC_RESULT_CHECK(PT, RESULT) do { \
+ if ((RESULT) != SDC_SUCCESS) \
+ { \
+ SDC_BREAK((PT), RESULT); \
+ } \
+ } while (0);
+
+
+static const nrf_drv_spi_t m_spi = NRF_DRV_SPI_INSTANCE(APP_SDCARD_SPI_INSTANCE); /**< SPI instance. */
+
+/**
+ * @brief SDC response type.
+ */
+typedef enum {
+ SDC_RNONE = 0,
+ SDC_R1,
+ SDC_R3,
+ SDC_R7
+} sdc_response_t;
+
+/**
+ * @brief SDC operation state.
+ */
+typedef enum {
+ SDC_UNINITIALIZED = 0, ///< Card not initialized.
+ SDC_OP_RESET = 1, ///< Reset state.
+ SDC_OP_IDENTIFICATION = 2, ///< Identification procedure.
+ SDC_OP_IDLE = 3, ///< Idle state.
+ SDC_OP_READ = 4, ///< Data read procedure.
+ SDC_OP_WRITE = 5 ///< Data write procedure.
+} sdc_op_t;
+
+/**
+ * @brief SDC data bus state.
+ */
+typedef enum {
+ SDC_BUS_IDLE = 0, ///< Idle state, no active transfer.
+ SDC_BUS_CMD = 1, ///< Command is being transfered.
+ SDC_BUS_ACMD = 2, ///< Application command header transfer.
+ SDC_BUS_DATA_WAIT = 3, ///< Data wait state.
+ SDC_BUS_DATA = 4 ///< Data block transfer in progress.
+} sdc_bus_state_t;
+
+/**
+ * @brief Current read/write operation state structure.
+ */
+typedef struct {
+ uint8_t * buffer; ///< Local data buffer.
+ uint32_t address; ///< Data block address.
+ uint16_t block_count; ///< Total number of blocks in read/write operation.
+ uint16_t blocks_left; ///< Blocks left in current read/write operation.
+ uint16_t position; ///< Number of blocks left to read/write.
+} sdc_rw_op_t;
+
+/**
+ * @brief SDC state structure.
+ */
+typedef struct {
+ sdc_rw_op_t rw_op; ///< Read/write operation state.
+ pt_t pt; ///< Current task (Protothread) state.
+ pt_t pt_sub; ///< Current sub-task (Protothread) state.
+ uint16_t retry_count; ///< Number of retries left.
+ volatile sdc_op_t op; ///< Current operation.
+ sdc_bus_state_t bus_state; ///< Current data bud state.
+ uint8_t rsp_len; ///< Expected response length.
+} sdc_state_t;
+
+/**
+ * @beirf SDC control block.
+ */
+typedef struct {
+ sdc_event_handler_t handler; ///< Event handler.
+ app_sdc_info_t info; ///< Card information structure.
+ sdc_state_t state; ///< Card state structure
+ uint8_t cmd_buf[SDC_CMD_BUF_LEN]; ///< Command buffer.
+ uint8_t rsp_buf[SDC_CMD_BUF_LEN]; ///< Card response buffer.
+ uint8_t work_buf[SDC_WORK_BUF_LEN]; ///< Working buffer
+ uint8_t cs_pin; ///< Chip select pin number.
+} sdc_cb_t;
+
+static sdc_cb_t m_cb; ///< SDC control block.
+
+
+/**
+ * @brief Function for requesting the SPI transaction.
+ *
+ * The SPI bus must be initialized prior to use of this function.
+ *
+ * @param[in] p_txb Pointer to the TX buffer.
+ * @param[in] tx_len TX buffer length.
+ * @param[out] p_rxb Pointer to the RX buffer.
+ * @param[in] tx_len RX buffer length.
+ */
+__STATIC_INLINE void sdc_spi_transfer(uint8_t const * const p_txb,
+ uint8_t tx_len,
+ uint8_t * const p_rxb,
+ uint8_t rx_len)
+{
+ SDC_CS_ASSERT();
+ ret_code_t err_code = nrf_drv_spi_transfer(&m_spi, p_txb, tx_len, p_rxb, rx_len);
+ APP_ERROR_CHECK(err_code);
+}
+
+
+/**
+ * @brief Function for switching the SPI clock to high speed mode.
+ */
+__STATIC_INLINE void sdc_spi_hispeed(void)
+{
+#ifdef SPI_PRESENT
+ nrf_spi_frequency_set(m_spi.u.spi.p_reg,
+ (nrf_spi_frequency_t) APP_SDCARD_FREQ_DATA);
+#else
+ nrf_spim_frequency_set(m_spi.u.spim.p_reg,
+ (nrf_spi_frequency_t) APP_SDCARD_FREQ_DATA);
+#endif
+}
+
+
+/**
+ * @brief Function for extracting the number of data block from the CSD structure.
+ *
+ * @param[in] p_csd Pointer to the card CSD structure.
+ *
+ * @return Number of data blocks or 0 if unsupported / invalid structure was provided.
+ */
+static uint32_t sdc_calculate_size(uint8_t const * const p_csd)
+{
+ // Values are calculated as stated in SD Specifications, chapter 5.3.
+ uint8_t csd_version = p_csd[0] >> 6;
+
+ switch (csd_version)
+ {
+ case 0:
+ case 2:
+ {
+ // SD Standard Capacity or MMC.
+ uint32_t c_size = ((uint32_t) p_csd[8] >> 6) + (((uint32_t) p_csd[7]) << 2)
+ + ((uint32_t)(p_csd[6] & 0x03) << 10);
+ uint32_t read_bl_len = p_csd[5] & 0x0F;
+ uint32_t c_size_mult = ((p_csd[10] & 0x80) >> 7) + ((p_csd[9] & 0x03) << 1);
+
+ // Block size in this implementation is set to 512, so the resulting number of bytes
+ // is divided by 512 (2^9)
+ return (c_size + 1) << (read_bl_len + c_size_mult + 2 - 9);
+ }
+ case 1:
+ {
+ // SD High Capacity.
+ uint32_t c_size = (uint32_t) p_csd[9] + ((uint32_t) p_csd[8] << 8)
+ + (((uint32_t) p_csd[7] & 0x3F) << 16);
+
+ // According to SD 2.0 Specifications, capacity = (C_SIZE + 1) * 512KByte.
+ // Block size is equal to 512, so the result is divided by 512.
+ return (c_size + 1) * 1024uL;
+ }
+ default:
+ break;
+ }
+ return 0;
+}
+
+
+/**
+ * @brief Non-blocking function for sending a command to the card.
+ *
+ * @param[in] cmd SDC command ID.
+ * @param[in] arg 32-bit command argument.
+ * @param[in] rsp_type Expected command response format.
+ *
+ * @retval NRF_SUCCESS If command transmission was started successfully.
+ * @retval NRF_ERROR_BUSY If the card is not in idle state.
+ */
+static ret_code_t sdc_cmd(uint8_t cmd, uint32_t arg, sdc_response_t rsp_type)
+{
+ if (m_cb.state.bus_state != SDC_BUS_IDLE)
+ {
+ return NRF_ERROR_BUSY;
+ }
+
+ uint8_t offset = 0;
+
+ m_cb.state.bus_state = SDC_BUS_CMD;
+ if (IS_ACMD(cmd))
+ {
+ // ACMD is a combination of CMD55 and the requested command,
+ // which will be placed next in the command buffer.
+ offset = SDC_COMMAND_LEN;
+ m_cb.state.bus_state = SDC_BUS_ACMD;
+ m_cb.cmd_buf[SDC_COMMAND_POS] = CMD55;
+ m_cb.cmd_buf[SDC_COMMAND_ARG_POS] = 0;
+ m_cb.cmd_buf[SDC_COMMAND_ARG_POS + 1] = 0;
+ m_cb.cmd_buf[SDC_COMMAND_ARG_POS + 2] = 0;
+ m_cb.cmd_buf[SDC_COMMAND_ARG_POS + 3] = 0;
+ m_cb.cmd_buf[SDC_COMMAND_CRC_POS] = SDC_CRC_DUMMY;
+ }
+
+ m_cb.cmd_buf[SDC_COMMAND_POS + offset] = cmd & SDC_COMMAND_MASK;
+ m_cb.cmd_buf[SDC_COMMAND_ARG_POS + offset] = (uint8_t)(arg >> 24);
+ m_cb.cmd_buf[SDC_COMMAND_ARG_POS + 1 + offset] = (uint8_t)(arg >> 16);
+ m_cb.cmd_buf[SDC_COMMAND_ARG_POS + 2 + offset] = (uint8_t)(arg >> 8);
+ m_cb.cmd_buf[SDC_COMMAND_ARG_POS + 3 + offset] = (uint8_t)(arg);
+
+ // Use predefined CRC values and omit the crc calculation if not required.
+ uint8_t crc;
+ switch (cmd)
+ {
+ case CMD0:
+ crc = SDC_CRC_CMD0;
+ break;
+ case CMD8:
+ crc = SDC_CRC_CMD8;
+ break;
+ default:
+ crc = SDC_CRC_DUMMY;
+ break;
+ }
+ m_cb.cmd_buf[SDC_COMMAND_CRC_POS + offset] = crc;
+
+ switch (rsp_type)
+ {
+ case SDC_R3:
+ m_cb.state.rsp_len = SDC_R3_LEN;
+ break;
+ case SDC_R7:
+ m_cb.state.rsp_len = SDC_R7_LEN;
+ break;
+ default:
+ m_cb.state.rsp_len = SDC_R1_LEN;
+ break;
+ }
+
+ uint8_t response_len = (IS_ACMD(cmd)) ? SDC_R1_LEN : m_cb.state.rsp_len;
+ sdc_spi_transfer(m_cb.cmd_buf,
+ SDC_COMMAND_LEN,
+ m_cb.rsp_buf,
+ SDC_COMMAND_LEN + SDC_MAX_NCR + response_len);
+
+ return NRF_SUCCESS;
+}
+
+
+/**
+ * @brief Data block read subroutine.
+ *
+ * @param[in] p_rx_data Pointer to the data received in last transation.
+ * @param[in] rx_length Received data length.
+ * @param[in] block_len Size of a data block to read.
+ * @param[out] p_exit_code Pointer to the subroutine exit code variable. Valid only if the thread has exited.
+ *
+ * @return Protothread exit code. Zero if protothread is running and non-zero if exited.
+ */
+static PT_THREAD(sdc_pt_sub_data_read(uint8_t * p_rx_data,
+ uint8_t rx_length,
+ uint16_t block_len,
+ sdc_result_t * p_exit_code))
+{
+ PT_BEGIN(SDC_PT_SUB);
+ while (1)
+ {
+ ASSERT(block_len);
+ ASSERT(m_cb.state.rw_op.block_count);
+
+ m_cb.state.rw_op.blocks_left = m_cb.state.rw_op.block_count;
+
+ while (m_cb.state.rw_op.blocks_left)
+ {
+ m_cb.state.retry_count = 0;
+ m_cb.cmd_buf[0] = 0xFF;
+ m_cb.state.rw_op.position = 0;
+ m_cb.state.bus_state = SDC_BUS_DATA_WAIT;
+
+ while (m_cb.state.bus_state == SDC_BUS_DATA_WAIT)
+ {
+ ++m_cb.state.retry_count;
+ if (m_cb.state.retry_count > SDC_MAX_RETRY_COUNT)
+ {
+ SDC_BREAK(SDC_PT_SUB, SDC_ERROR_TIMEOUT);
+ }
+
+ // Search for the first token.
+ while (rx_length && p_rx_data[0] == SDC_EMPTY_BYTE)
+ {
+ ++p_rx_data;
+ --rx_length;
+ }
+
+ if (rx_length)
+ {
+ // A token has been found.
+ if (p_rx_data[0] == SDC_TOKEN_START_BLOCK)
+ {
+ // Expected data start token found.
+ // Copy the data bytes left in rx buffer into user buffer.
+ ++p_rx_data;
+ --rx_length;
+ m_cb.state.bus_state = SDC_BUS_DATA;
+ uint16_t copy_len = (rx_length > block_len) ? block_len : rx_length;
+ for (uint32_t i = 0; i < copy_len; ++i)
+ {
+ m_cb.state.rw_op.buffer[i] = p_rx_data[i];
+ }
+ m_cb.state.rw_op.position = copy_len;
+ m_cb.state.rw_op.buffer += copy_len;
+ }
+ else
+ {
+ // Data error.
+ SDC_BREAK(SDC_PT_SUB, SDC_ERROR_DATA);
+ }
+ }
+ else
+ {
+ // Continue transfer until token is received.
+ sdc_spi_transfer(m_cb.cmd_buf, 1, m_cb.rsp_buf, SDC_DATA_WAIT_TX_SIZE);
+ PT_YIELD(SDC_PT_SUB);
+ }
+ }
+
+ while (m_cb.state.rw_op.position < block_len)
+ {
+ {
+ uint16_t chunk_size = block_len - m_cb.state.rw_op.position;
+ if (chunk_size > SDC_SPI_MTU)
+ {
+ chunk_size = SDC_SPI_MTU;
+ }
+
+ sdc_spi_transfer(m_cb.cmd_buf, 1,
+ m_cb.state.rw_op.buffer, chunk_size);
+ m_cb.state.rw_op.buffer += chunk_size;
+ m_cb.state.rw_op.position += chunk_size;
+ }
+ PT_YIELD(SDC_PT_SUB);
+ }
+
+ // Get the CRC.
+ --m_cb.state.rw_op.blocks_left;
+ sdc_spi_transfer(m_cb.cmd_buf, 1,
+ m_cb.rsp_buf, 2);
+ PT_YIELD(SDC_PT_SUB);
+
+
+
+ // Set rx length to 0 to force "busy check" transmission before next data block.
+ rx_length = 0;
+ }
+
+ // Send padding bytes.
+ m_cb.cmd_buf[0] = SDC_EMPTY_BYTE;
+ sdc_spi_transfer(m_cb.cmd_buf, 1,
+ m_cb.rsp_buf, 2);
+ PT_YIELD(SDC_PT_SUB);
+
+ m_cb.state.bus_state = SDC_BUS_IDLE;
+ SDC_BREAK(SDC_PT_SUB, SDC_SUCCESS);
+ }
+ PT_END(SDC_PT_SUB)
+}
+
+
+/**
+ * @brief Card identification co-routine.
+ *
+ * @param[in] p_rx_data Pointer to the data received in last transation.
+ * @param[in] rx_length Received data length.
+ * @param[out] p_exit_code Pointer to the routine exit code variable. Valid only if the thread has exited.
+ *
+ * @return Protothread exit code. Zero if protothread is running and non-zero if exited.
+ */
+static PT_THREAD(sdc_pt_identification(uint8_t * p_rx_data,
+ uint8_t rx_length,
+ sdc_result_t * p_exit_code))
+{
+ uint8_t r1 = p_rx_data[0];
+ uint32_t rsp = ((uint32_t)p_rx_data[1] << 24)
+ | ((uint32_t)p_rx_data[2] << 16)
+ | ((uint32_t)p_rx_data[3] << 8)
+ | ((uint32_t)p_rx_data[4]);
+ uint32_t arg;
+ ret_code_t err_code;
+ sdc_result_t sub_exit_code;
+
+ PT_BEGIN(SDC_PT);
+ while (1)
+ {
+ err_code = sdc_cmd(CMD0, 0, SDC_R1);
+ APP_ERROR_CHECK(err_code);
+ PT_YIELD(SDC_PT);
+ err_code = sdc_cmd(CMD0, 0, SDC_R1);
+ APP_ERROR_CHECK(err_code);
+ PT_YIELD(SDC_PT);
+
+ SDC_RESP_CHECK(SDC_PT, r1);
+ // Send CMD8 with fixed argument - 0x01AA.
+ err_code = sdc_cmd(CMD8, 0x1AA, SDC_R7);
+ APP_ERROR_CHECK(err_code);
+ PT_YIELD(SDC_PT);
+
+ if (!(r1 & SDC_FLAG_ILLEGAL_COMMAND))
+ {
+ // CMD8 was accepted - SD v2 card.
+ m_cb.info.type.version = SDC_TYPE_SDV2;
+ SDC_RESP_CHECK(SDC_PT, r1);
+ }
+
+ m_cb.state.retry_count = 0;
+ arg = (m_cb.info.type.version == SDC_TYPE_SDV2) ? SDC_HCS_FLAG_MASK : 0;
+ err_code = sdc_cmd(ACMD41, arg, SDC_R3);
+ APP_ERROR_CHECK(err_code);
+ PT_YIELD(SDC_PT);
+
+ if (r1 & SDC_FLAG_ILLEGAL_COMMAND)
+ {
+ // ACMD41 was rejected - MMC card.
+ m_cb.info.type.version = SDC_TYPE_MMCV3;
+ r1 &= ~SDC_FLAG_ILLEGAL_COMMAND;
+
+ do
+ {
+ ++m_cb.state.retry_count;
+ if (m_cb.state.retry_count > SDC_MAX_RETRY_COUNT_INIT)
+ {
+ SDC_BREAK(SDC_PT, SDC_ERROR_TIMEOUT);
+ }
+
+ err_code = sdc_cmd(CMD1, 0, SDC_R3);
+ APP_ERROR_CHECK(err_code);
+ PT_YIELD(SDC_PT);
+ SDC_RESP_CHECK(SDC_PT, r1);
+ }
+ while (r1 & SDC_FLAG_IN_IDLE_STATE);
+ }
+ else
+ {
+ // SDv1 or SDv2 card. Send CMD58 or retry ACMD41 if not ready.
+ SDC_RESP_CHECK(SDC_PT, r1);
+
+ while (r1 & SDC_FLAG_IN_IDLE_STATE)
+ {
+ ++m_cb.state.retry_count;
+ if (m_cb.state.retry_count > SDC_MAX_RETRY_COUNT_INIT)
+ {
+ SDC_BREAK(SDC_PT, SDC_ERROR_TIMEOUT);
+ }
+
+ arg = (m_cb.info.type.version == SDC_TYPE_SDV2) ? SDC_HCS_FLAG_MASK : 0;
+ err_code = sdc_cmd(ACMD41, arg, SDC_R3);
+ APP_ERROR_CHECK(err_code);
+ PT_YIELD(SDC_PT);
+ SDC_RESP_CHECK(SDC_PT, r1);
+ }
+
+ err_code = sdc_cmd(CMD58, 0, SDC_R3);
+ APP_ERROR_CHECK(err_code);
+ PT_YIELD(SDC_PT);
+ SDC_RESP_CHECK(SDC_PT, r1);
+
+ if (rsp & SDC_HCS_FLAG_MASK)
+ {
+ m_cb.info.type.sdhc = 1;
+ }
+ }
+
+ if (m_cb.info.type.version != SDC_TYPE_SDV2)
+ {
+ // Set block length to 512 (SDv1 and MMC cards only.)
+ err_code = sdc_cmd(CMD16, SDC_SECTOR_SIZE, SDC_R1);
+ APP_ERROR_CHECK(err_code);
+ PT_YIELD(SDC_PT);
+ SDC_RESP_CHECK(SDC_PT, r1);
+ }
+
+ // Setup the read operation and get the contents of 128-bit CSD register.
+ m_cb.state.rw_op.buffer = m_cb.work_buf;
+ m_cb.state.rw_op.block_count = 1;
+
+ err_code = sdc_cmd(CMD9, 0, SDC_R1);
+ APP_ERROR_CHECK(err_code);
+ PT_YIELD(SDC_PT);
+ SDC_RESP_CHECK(SDC_PT, r1);
+
+ p_rx_data += SDC_R1_LEN;
+ rx_length -= SDC_R1_LEN;
+ PT_SPAWN(SDC_PT, SDC_PT_SUB, sdc_pt_sub_data_read(p_rx_data, rx_length, \
+ 16, &sub_exit_code));
+ SDC_RESULT_CHECK(SDC_PT, sub_exit_code);
+
+ m_cb.info.num_blocks = sdc_calculate_size(m_cb.work_buf);
+ m_cb.info.block_len = SDC_SECTOR_SIZE;
+
+ SDC_BREAK(SDC_PT, SDC_SUCCESS);
+ }
+ PT_END(SDC_PT)
+}
+
+
+/**
+ * @brief Data read co-routine.
+ *
+ * @param[in] p_rx_data Pointer to the data received in last transaction.
+ * @param[in] rx_length Received data length.
+ * @param[out] p_exit_code Pointer to the routine exit code variable. Valid only if the thread has exited.
+ *
+ * @return Protothread exit code. Zero if protothread is running and non-zero if exited.
+ */
+static PT_THREAD(sdc_pt_read(uint8_t * p_rx_data,
+ uint8_t rx_length,
+ sdc_result_t * p_exit_code))
+{
+ uint8_t r1;
+ ret_code_t err_code;
+ sdc_result_t sub_exit_code;
+
+ PT_BEGIN(SDC_PT);
+ while (1)
+ {
+ r1 = p_rx_data[0];
+ SDC_RESP_CHECK(SDC_PT, r1);
+
+ p_rx_data += SDC_R1_LEN;
+ rx_length -= SDC_R1_LEN;
+
+ // Run the block read subroutine.
+ PT_SPAWN(SDC_PT, SDC_PT_SUB, sdc_pt_sub_data_read(p_rx_data, rx_length,
+ SDC_SECTOR_SIZE,
+ &sub_exit_code));
+ SDC_RESULT_CHECK(SDC_PT, sub_exit_code);
+
+ if (m_cb.state.rw_op.block_count > 1)
+ {
+ // Send the STOP_TRANSMISSION command in multiple block read mode.
+ err_code = sdc_cmd(CMD12, 0, SDC_R1);
+ APP_ERROR_CHECK(err_code);
+ PT_YIELD(SDC_PT);
+ }
+
+ SDC_BREAK(SDC_PT, SDC_SUCCESS);
+ }
+ PT_END(SDC_PT)
+}
+
+
+/**
+ * @brief Data write co-routine.
+ *
+ * @param[in] p_rx_data Pointer to the data received in last transation.
+ * @param[in] rx_length Received data length.
+ * @param[out] p_exit_code Pointer to the routine exit code variable. Valid only if the thread has exited.
+ *
+ * @return Protothread exit code. Zero if protothread is running and non-zero if exited.
+ */
+static PT_THREAD(sdc_pt_write(uint8_t * rx_data,
+ uint8_t rx_length,
+ sdc_result_t * p_exit_code))
+{
+ ret_code_t err_code;
+ PT_BEGIN(SDC_PT);
+ while (1)
+ {
+ uint8_t r1;
+ r1 = rx_data[0];
+ SDC_RESP_CHECK(SDC_PT, r1);
+ if (m_cb.info.type.version != SDC_TYPE_MMCV3 && m_cb.state.rw_op.block_count > 1)
+ {
+ err_code = sdc_cmd(CMD25, m_cb.state.rw_op.address, SDC_R1);
+ APP_ERROR_CHECK(err_code);
+ PT_YIELD(SDC_PT);
+ r1 = rx_data[0];
+ SDC_RESP_CHECK(SDC_PT, r1);
+ }
+
+ m_cb.state.rw_op.blocks_left = m_cb.state.rw_op.block_count;
+ while (m_cb.state.rw_op.blocks_left)
+ {
+ m_cb.state.rw_op.position = 0;
+ m_cb.state.bus_state = SDC_BUS_DATA;
+
+ // Send block start token.
+ m_cb.cmd_buf[0] = SDC_EMPTY_BYTE;
+ m_cb.cmd_buf[1] = (m_cb.state.rw_op.block_count > 1) ? SDC_TOKEN_START_BLOCK_MULT
+ : SDC_TOKEN_START_BLOCK;
+ sdc_spi_transfer(m_cb.cmd_buf, 2, m_cb.rsp_buf, 2);
+ PT_YIELD(SDC_PT);
+
+ // Send the data block.
+ while (m_cb.state.rw_op.position < SDC_SECTOR_SIZE)
+ {
+ {
+ uint16_t chunk_size = SDC_SECTOR_SIZE - m_cb.state.rw_op.position;
+ if (chunk_size > SDC_SPI_MTU)
+ {
+ chunk_size = SDC_SPI_MTU;
+ }
+ sdc_spi_transfer(&m_cb.state.rw_op.buffer[m_cb.state.rw_op.position],
+ chunk_size,
+ m_cb.rsp_buf,
+ 1);
+ m_cb.state.rw_op.position += chunk_size;
+ }
+ PT_YIELD(SDC_PT);
+ }
+ m_cb.state.rw_op.buffer += SDC_SECTOR_SIZE;
+
+ // Send the dummy CRC (2 bytes) and receive data response token (1 byte).
+ m_cb.state.bus_state = SDC_BUS_DATA_WAIT;
+ sdc_spi_transfer(m_cb.cmd_buf, 1,
+ m_cb.rsp_buf, 3);
+ PT_YIELD(SDC_PT);
+
+ {
+ uint8_t token = m_cb.rsp_buf[2] & SDC_TOKEN_DATA_RESP_MASK;
+ if (token != SDC_TOKEN_DATA_RESP_ACCEPTED)
+ {
+ if (token == SDC_TOKEN_DATA_RESP_CRC_ERR
+ || token == SDC_TOKEN_DATA_RESP_DATA_ERR)
+ {
+ SDC_BREAK(SDC_PT, SDC_ERROR_DATA);
+ }
+ else
+ {
+ SDC_BREAK(SDC_PT, SDC_ERROR_COMMUNICATION);
+ }
+ }
+ }
+
+ // Wait for the card to complete the write process.
+ m_cb.state.retry_count = 0;
+ while (m_cb.state.bus_state == SDC_BUS_DATA_WAIT)
+ {
+ ++m_cb.state.retry_count;
+ if (m_cb.state.retry_count > SDC_MAX_RETRY_COUNT)
+ {
+ SDC_BREAK(SDC_PT, SDC_ERROR_TIMEOUT);
+ }
+
+ sdc_spi_transfer(m_cb.cmd_buf, 1,
+ m_cb.rsp_buf, SDC_DATA_WAIT_TX_SIZE);
+ PT_YIELD(SDC_PT);
+
+ for (uint32_t i = 0; i < rx_length; ++i)
+ {
+ if (rx_data[i] != 0x00)
+ {
+ m_cb.state.bus_state = SDC_BUS_IDLE;
+ break;
+ }
+ }
+ }
+
+ --m_cb.state.rw_op.blocks_left;
+ }
+
+ if (m_cb.state.rw_op.block_count > 1)
+ {
+ // Send STOP_TRAN token + padding byte when writing multiple blocks.
+ m_cb.cmd_buf[0] = SDC_EMPTY_BYTE;
+ m_cb.cmd_buf[1] = SDC_TOKEN_STOP_TRAN;
+ sdc_spi_transfer(m_cb.cmd_buf, 2,
+ m_cb.rsp_buf, 3);
+ PT_YIELD(SDC_PT);
+
+ m_cb.state.retry_count = 0;
+ m_cb.state.bus_state = SDC_BUS_DATA_WAIT;
+
+ // Wait for the card to complete the write process.
+ while (m_cb.state.bus_state == SDC_BUS_DATA_WAIT)
+ {
+ ++m_cb.state.retry_count;
+ if (m_cb.state.retry_count > SDC_MAX_RETRY_COUNT)
+ {
+ SDC_BREAK(SDC_PT, SDC_ERROR_TIMEOUT);
+ }
+
+ sdc_spi_transfer(m_cb.cmd_buf, 1,
+ m_cb.rsp_buf, SDC_DATA_WAIT_TX_SIZE);
+ PT_YIELD(SDC_PT);
+
+ for (uint32_t i = 0; i < rx_length; ++i)
+ {
+ if (rx_data[i] != 0x00)
+ {
+ m_cb.state.bus_state = SDC_BUS_IDLE;
+ break;
+ }
+ }
+ }
+ }
+
+ SDC_BREAK(SDC_PT, SDC_SUCCESS);
+ }
+ PT_END(SDC_PT)
+}
+
+
+/**
+ * @brief SPI event handler.
+ *
+ * @param[in] p_event Pointer to the SPI event structure.
+ */
+static void spi_handler(nrf_drv_spi_evt_t const * p_event,
+ void * p_context)
+{
+ uint8_t * rx_data = p_event->data.done.p_rx_buffer;
+ uint8_t rx_length = p_event->data.done.rx_length;
+
+ if (!m_cb.state.rw_op.blocks_left)
+ {
+ // Deassert CS pin if not in active data transfer.
+ SDC_CS_DEASSERT();
+ }
+
+ if (m_cb.state.bus_state == SDC_BUS_ACMD || m_cb.state.bus_state == SDC_BUS_CMD)
+ {
+ // Find the beginning of a response.
+ ASSERT(rx_length > SDC_COMMAND_LEN);
+ rx_length -= SDC_COMMAND_LEN;
+ rx_data += SDC_COMMAND_LEN;
+
+ if (p_event->data.done.p_tx_buffer[0] == CMD12)
+ {
+ // Ignore the first byte if CMD12 was sent.
+ if (rx_length)
+ {
+ --rx_length;
+ ++rx_data;
+ }
+ }
+
+ while (rx_length && rx_data[0] == SDC_EMPTY_BYTE)
+ {
+ --rx_length;
+ ++rx_data;
+ }
+ if (rx_length == 0)
+ {
+ if (p_event->data.done.p_tx_buffer[0] == CMD12)
+ {
+ // Ignore invalid reply on CMD12.
+ ++rx_length;
+ --rx_data;
+ }
+ else
+ {
+ rx_data = NULL;
+ }
+ }
+
+ if (!rx_data && m_cb.state.op != SDC_OP_RESET)
+ {
+ // Command response missing.
+ sdc_evt_t evt;
+ evt.result = SDC_ERROR_NOT_RESPONDING;
+ switch (m_cb.state.op)
+ {
+ case SDC_OP_RESET:
+ case SDC_OP_IDENTIFICATION:
+ evt.type = SDC_EVT_INIT;
+ m_cb.state.op = SDC_OP_IDLE;
+ APP_ERROR_CHECK(app_sdc_uninit());
+ break;
+ case SDC_OP_READ:
+ evt.type = SDC_EVT_READ;
+ break;
+ case SDC_OP_WRITE:
+ evt.type = SDC_EVT_WRITE;
+ break;
+ default:
+ APP_ERROR_CHECK(NRF_ERROR_INTERNAL);
+ break;
+ }
+
+ SDC_CS_DEASSERT();
+ m_cb.state.op = SDC_OP_IDLE;
+ m_cb.handler(&evt);
+ return;
+ }
+
+ if (m_cb.state.bus_state == SDC_BUS_ACMD)
+ {
+ // Check the status of CMD55 and send the scheduled command if no errors has been reported.
+ m_cb.state.bus_state = SDC_BUS_CMD;
+ uint8_t r1 = rx_data[0];
+ if (!(r1 & (~SDC_FLAG_IN_IDLE_STATE)))
+ {
+ sdc_spi_transfer(m_cb.cmd_buf + SDC_COMMAND_LEN, SDC_COMMAND_LEN,
+ m_cb.rsp_buf, SDC_COMMAND_LEN + SDC_MAX_NCR + m_cb.state.rsp_len);
+ return;
+ }
+ }
+ m_cb.state.bus_state = SDC_BUS_IDLE;
+ }
+
+ sdc_result_t exit_code = SDC_ERROR_INTERNAL;
+ sdc_evt_t evt;
+ switch (m_cb.state.op)
+ {
+ case SDC_OP_RESET:
+ m_cb.state.op = SDC_OP_IDENTIFICATION;
+ PT_INIT(SDC_PT);
+ //lint -e{616}
+ case SDC_OP_IDENTIFICATION:
+ if (!PT_SCHEDULE(sdc_pt_identification(rx_data, rx_length, &exit_code)))
+ {
+ evt.type = SDC_EVT_INIT;
+ evt.result = exit_code;
+ m_cb.state.op = SDC_OP_IDLE;
+ SDC_CS_DEASSERT();
+ if (exit_code != SDC_SUCCESS)
+ {
+ // Initialization process failed. Roll back to uninitialized state.
+ APP_ERROR_CHECK(app_sdc_uninit());
+ }
+ sdc_spi_hispeed();
+ m_cb.handler(&evt);
+ }
+ break;
+ case SDC_OP_READ:
+ if (!PT_SCHEDULE(sdc_pt_read(rx_data, rx_length, &exit_code)))
+ {
+ evt.type = SDC_EVT_READ;
+ evt.result = exit_code;
+ m_cb.state.op = SDC_OP_IDLE;
+ m_cb.state.rw_op.block_count = 0;
+ m_cb.state.rw_op.blocks_left = 0;
+ m_cb.state.bus_state = SDC_BUS_IDLE;
+ SDC_CS_DEASSERT();
+ m_cb.handler(&evt);
+ }
+ break;
+ case SDC_OP_WRITE:
+ if (!PT_SCHEDULE(sdc_pt_write(rx_data, rx_length, &exit_code)))
+ {
+ evt.type = SDC_EVT_WRITE;
+ evt.result = exit_code;
+ m_cb.state.op = SDC_OP_IDLE;
+ m_cb.state.bus_state = SDC_BUS_IDLE;
+ m_cb.state.rw_op.block_count = 0;
+ m_cb.state.rw_op.blocks_left = 0;
+ SDC_CS_DEASSERT();
+ m_cb.handler(&evt);
+ }
+ break;
+ default:
+ APP_ERROR_CHECK(NRF_ERROR_INTERNAL);
+ break;
+ }
+
+ return;
+}
+
+
+ret_code_t app_sdc_block_read(uint8_t * p_buf, uint32_t block_address, uint16_t block_count)
+{
+ ASSERT(p_buf);
+
+ if (m_cb.state.op == SDC_UNINITIALIZED)
+ {
+ return NRF_ERROR_INVALID_STATE;
+ }
+ if (m_cb.state.op != SDC_OP_IDLE)
+ {
+ return NRF_ERROR_BUSY;
+ }
+ if (block_count == 0)
+ {
+ return NRF_ERROR_INVALID_PARAM;
+ }
+
+ m_cb.state.op = SDC_OP_READ;
+
+ if (!m_cb.info.type.sdhc)
+ {
+ m_cb.state.rw_op.address = block_address * SDC_SECTOR_SIZE;
+ }
+ else
+ {
+ m_cb.state.rw_op.address = block_address;
+ }
+ m_cb.state.rw_op.buffer = p_buf;
+ m_cb.state.rw_op.block_count = block_count;
+ m_cb.state.rw_op.blocks_left = block_count;
+
+ PT_INIT(&m_cb.state.pt);
+ uint8_t command = (block_count > 1) ? CMD18 : CMD17;
+ ret_code_t err_code = sdc_cmd(command, m_cb.state.rw_op.address, SDC_R1);
+ APP_ERROR_CHECK(err_code);
+
+ return NRF_SUCCESS;
+}
+
+
+ret_code_t app_sdc_block_write(uint8_t const * p_buf, uint32_t block_address, uint16_t block_count)
+{
+ ASSERT(p_buf);
+
+ if (m_cb.state.op == SDC_UNINITIALIZED)
+ {
+ return NRF_ERROR_INVALID_STATE;
+ }
+ if (m_cb.state.op != SDC_OP_IDLE)
+ {
+ return NRF_ERROR_BUSY;
+ }
+ if (block_count == 0)
+ {
+ return NRF_ERROR_INVALID_PARAM;
+ }
+ m_cb.state.op = SDC_OP_WRITE;
+
+ if (!m_cb.info.type.sdhc)
+ {
+ m_cb.state.rw_op.address = block_address * 512uL;
+ }
+ else
+ {
+ m_cb.state.rw_op.address = block_address;
+ }
+ m_cb.state.rw_op.buffer = (uint8_t *) p_buf;
+ m_cb.state.rw_op.block_count = block_count;
+ m_cb.state.rw_op.blocks_left = block_count;
+
+ PT_INIT(&m_cb.state.pt);
+
+ ret_code_t err_code;
+ if (block_count == 1)
+ {
+ err_code = sdc_cmd(CMD24, m_cb.state.rw_op.address, SDC_R1);
+
+ APP_ERROR_CHECK(err_code);
+ return NRF_SUCCESS;
+ }
+
+ if (m_cb.info.type.version == SDC_TYPE_MMCV3)
+ {
+ // Start multiple block write.
+ err_code = sdc_cmd(CMD25, m_cb.state.rw_op.address, SDC_R1);
+ }
+ else
+ {
+ // Set pre-erase for SD cards before sending CMD25.
+ err_code = sdc_cmd(ACMD23, block_count, SDC_R1);
+ }
+
+ APP_ERROR_CHECK(err_code);
+ return NRF_SUCCESS;
+}
+
+
+ret_code_t app_sdc_init(app_sdc_config_t const * const p_config, sdc_event_handler_t event_handler)
+{
+ if (m_cb.state.op != SDC_UNINITIALIZED)
+ {
+ return NRF_ERROR_INVALID_STATE;
+ }
+ if ((!event_handler)
+ || (p_config->cs_pin == NRF_DRV_SPI_PIN_NOT_USED)
+ || (p_config->miso_pin == NRF_DRV_SPI_PIN_NOT_USED)
+ || (p_config->mosi_pin == NRF_DRV_SPI_PIN_NOT_USED)
+ || (p_config->sck_pin == NRF_DRV_SPI_PIN_NOT_USED))
+ {
+ return NRF_ERROR_INVALID_PARAM;
+ }
+
+ ret_code_t err_code;
+ ASSERT(p_config->cs_pin && p_config->miso_pin
+ && p_config->mosi_pin && p_config->sck_pin);
+
+ // Configure chip select pin.
+ m_cb.cs_pin = p_config->cs_pin;
+ nrf_gpio_cfg_output(m_cb.cs_pin);
+ SDC_CS_DEASSERT();
+
+ const nrf_drv_spi_config_t spi_cfg = {
+ .sck_pin = p_config->sck_pin,
+ .mosi_pin = p_config->mosi_pin,
+ .miso_pin = p_config->miso_pin,
+ .ss_pin = NRF_DRV_SPI_PIN_NOT_USED,
+ .irq_priority = SPI_DEFAULT_CONFIG_IRQ_PRIORITY,
+ .orc = 0xFF,
+ .frequency = (nrf_drv_spi_frequency_t) APP_SDCARD_FREQ_INIT,
+ .mode = NRF_DRV_SPI_MODE_0,
+ .bit_order = NRF_DRV_SPI_BIT_ORDER_MSB_FIRST,
+ };
+ err_code = nrf_drv_spi_init(&m_spi, &spi_cfg, spi_handler, NULL);
+ APP_ERROR_CHECK(err_code);
+
+ m_cb.handler = event_handler;
+ m_cb.state.op = SDC_OP_RESET;
+ m_cb.info.type.version = SDC_TYPE_UNKNOWN;
+ m_cb.info.type.sdhc = 0;
+ m_cb.state.bus_state = SDC_BUS_IDLE;
+
+ // Send 80 clocks with CS inactive to switch into SPI mode.
+ m_cb.cmd_buf[0] = 0xFF;
+ err_code = nrf_drv_spi_transfer(&m_spi, m_cb.cmd_buf, 1,
+ m_cb.rsp_buf, 10);
+ APP_ERROR_CHECK(err_code);
+
+ return NRF_SUCCESS;
+}
+
+
+ret_code_t app_sdc_uninit(void)
+{
+ if (m_cb.state.op == SDC_UNINITIALIZED)
+ {
+ return NRF_ERROR_INVALID_STATE;
+ }
+ if (m_cb.state.op != SDC_OP_IDLE)
+ {
+ return NRF_ERROR_BUSY;
+ }
+
+ nrf_drv_spi_uninit(&m_spi);
+ nrf_gpio_cfg_input(m_cb.cs_pin, NRF_GPIO_PIN_NOPULL);
+
+ m_cb.state.bus_state = SDC_BUS_IDLE;
+ m_cb.state.op = SDC_UNINITIALIZED;
+
+ return NRF_SUCCESS;
+}
+
+
+bool app_sdc_busy_check(void)
+{
+ return ((m_cb.state.op != SDC_OP_IDLE) && (m_cb.state.op != SDC_UNINITIALIZED));
+}
+
+
+app_sdc_info_t const * app_sdc_info_get(void)
+{
+ if (m_cb.state.op >= SDC_OP_IDLE)
+ {
+ return &m_cb.info;
+ }
+ return NULL;
+}
+
+#endif //APP_SDCARD_ENABLED
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/sdcard/app_sdcard.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/sdcard/app_sdcard.h
new file mode 100644
index 0000000..3621771
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/sdcard/app_sdcard.h
@@ -0,0 +1,209 @@
+/**
+ * Copyright (c) 2016 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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
+ *
+ * @defgroup app_sdcard SD card library
+ * @{
+ * @ingroup app_common
+ *
+ * @brief Asynchronous Secure Digital card (SDC) and MultiMedia card (MMC) library.
+ */
+
+
+#ifndef APP_SDCARD_H_
+#define APP_SDCARD_H_
+
+#include "app_util_platform.h"
+#include "sdk_config.h"
+
+#define SDC_SECTOR_SIZE 512 ///< Size of a single SD card block in bytes.
+
+#define APP_SDCARD_CONFIG(MOSI_PIN, MISO_PIN, SCK_PIN, CS_PIN) { \
+ .mosi_pin = MOSI_PIN, \
+ .miso_pin = MISO_PIN, \
+ .sck_pin = SCK_PIN, \
+ .cs_pin = CS_PIN \
+ }
+
+/**
+ * @brief SDC operation result.
+ */
+typedef enum {
+ SDC_SUCCESS = 0, ///< Operation successful.
+ SDC_ERROR_NOT_RESPONDING, ///< Card is not responding or not present.
+ SDC_ERROR_TIMEOUT, ///< Card response timeout.
+ SDC_ERROR_NOT_SUPPORTED, ///< Operation not supported.
+ SDC_ERROR_COMMUNICATION, ///< Communication error.
+ SDC_ERROR_DATA, ///< Data read/write error.
+ SDC_ERROR_INTERNAL, ///< Internal error.
+} sdc_result_t;
+
+/**
+ * @brief SDC event type.
+ */
+typedef enum {
+ SDC_EVT_INIT = 0, ///< Initialization procedure.
+ SDC_EVT_READ, ///< Data read procedure.
+ SDC_EVT_WRITE ///< Data write procedure.
+} sdc_evt_type_t;
+
+/**
+ * @brief SDC event structure.
+ */
+typedef struct {
+ sdc_evt_type_t type; ///< Event type.
+ sdc_result_t result; ///< Operation result.
+} sdc_evt_t;
+
+/**
+ * @brief SDC type and version.
+ */
+typedef enum {
+ SDC_TYPE_UNKNOWN = 0, ///< Unknown / uninitialized card.
+ SDC_TYPE_MMCV3, ///< MultiMedia card (MMC) version 3.
+ SDC_TYPE_SDV1, ///< Secure Digital card (SDC) version 1.0.
+ SDC_TYPE_SDV2 ///< Secure Digital card (SDC) version 2.0.
+} sdc_version_t;
+
+/**
+ * @brief SDC type information structure.
+ */
+typedef struct {
+ sdc_version_t version : 3; ///< Card type and version (SD or MMC).
+ uint8_t sdhc : 1; ///< Standard Capacity or High Capacity card.
+} sdc_type_t;
+
+/**
+ * @brief SDC configuration structure.
+ */
+typedef struct {
+ uint8_t mosi_pin; ///< Serial data in (MOSI / DI) pin number.
+ uint8_t miso_pin; ///< Serial data out (MISO / DO) pin number.
+ uint8_t sck_pin; ///< Serial clock (SCK) pin number.
+ uint8_t cs_pin; ///< Chip select (CS) pin number.
+} app_sdc_config_t;
+
+/**
+ * @brief SDC information structure.
+ */
+typedef struct {
+ uint32_t num_blocks; ///< Number of available data blocks.
+ uint16_t block_len; ///< Length (in bytes) of a single data block.
+ sdc_type_t type; ///< Card type information structure.
+} app_sdc_info_t;
+
+/**
+ * @brief SDC event handler type.
+ */
+typedef void (*sdc_event_handler_t)(sdc_evt_t const * p_event);
+
+
+/**
+ * @brief Function for initializing the card.
+ *
+ * @param[in] p_config Pointer to the SDC configuration structure.
+ * @param[in] event_handler Pointer to the event handler function.
+ *
+ * @retval NRF_SUCCESS If initialization process was started succesfully.
+ * @retval NRF_ERROR_INVALID_STATE If the card is already initialized or the initialization is in progress.
+ * @retval NRF_ERROR_INVALID_PARAM If invalid parameters were specified.
+ */
+ret_code_t app_sdc_init(app_sdc_config_t const * const p_config, sdc_event_handler_t event_handler);
+
+
+/**
+ * @brief Function for uninitializing the card.
+ *
+ * @retval NRF_SUCCESS If card was uninitialized succesfully.
+ * @retval NRF_ERROR_INVALID_STATE If the card is not initialized.
+ * @retval NRF_ERROR_BUSY If there is an operation in progress.
+ */
+ret_code_t app_sdc_uninit(void);
+
+
+/**
+ * @brief Function for retrieving the card busy state.
+ *
+ * @retval true If there is an operation in progress.
+ * @retval false If the card is in idle state.
+ */
+bool app_sdc_busy_check(void);
+
+
+/**
+ * @brief Function for reading the data blocks from the card.
+ *
+ * @param[out] p_buf Pointer to the data buffer. Must not be null.
+ * @param[in] block_address Number of the first block to be read.
+ * @param[in] block_count Number of blocks to read. Must be greater than 0.
+ *
+ * @retval NRF_SUCCESS If block read operation was started succesfully.
+ * @retval NRF_ERROR_INVALID_STATE If the card is not initialized.
+ * @retval NRF_ERROR_BUSY If there is already an operation active.
+ * @retval NRF_ERROR_INVALID_PARAM If invalid parameters were specified.
+ */
+ret_code_t app_sdc_block_read(uint8_t * p_buf, uint32_t block_address, uint16_t block_count);
+
+
+/**
+ * @brief Function for writing the data blocks to the card.
+ *
+ * @param[out] p_buf Pointer to the data to be written. Must not be null.
+ * @param[in] block_address Number of the first block to write.
+ * @param[in] block_count Number of blocks to write. Must be greater than 0.
+ *
+ * @retval NRF_SUCCESS If block write operation was started succesfully.
+ * @retval NRF_ERROR_INVALID_STATE If the card is not initialized.
+ * @retval NRF_ERROR_BUSY If there is already an operation active.
+ * @retval NRF_ERROR_INVALID_PARAM If invalid parameters were specified.
+ */
+ret_code_t app_sdc_block_write(uint8_t const * p_buf, uint32_t block_address, uint16_t block_count);
+
+
+/**
+ * @brief Function for retrieving the card information structure.
+ *
+ * @return Pointer to the card information structure or NULL if card is not initialized.
+ */
+app_sdc_info_t const * app_sdc_info_get(void);
+
+
+#endif //APP_SDC_H_
+/** @} */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/sensorsim/sensorsim.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/sensorsim/sensorsim.c
new file mode 100644
index 0000000..c422a79
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/sensorsim/sensorsim.c
@@ -0,0 +1,100 @@
+/**
+ * Copyright (c) 2012 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#include "sensorsim.h"
+
+
+void sensorsim_init(sensorsim_state_t * p_state,
+ const sensorsim_cfg_t * p_cfg)
+{
+ if (p_cfg->start_at_max)
+ {
+ p_state->current_val = p_cfg->max;
+ p_state->is_increasing = false;
+ }
+ else
+ {
+ p_state->current_val = p_cfg->min;
+ p_state->is_increasing = true;
+ }
+}
+
+
+uint32_t sensorsim_measure(sensorsim_state_t * p_state,
+ const sensorsim_cfg_t * p_cfg)
+{
+ if (p_state->is_increasing)
+ {
+ sensorsim_increment(p_state, p_cfg);
+ }
+ else
+ {
+ sensorsim_decrement(p_state, p_cfg);
+ }
+ return p_state->current_val;
+}
+
+void sensorsim_increment(sensorsim_state_t * p_state,
+ const sensorsim_cfg_t * p_cfg)
+{
+ if (p_cfg->max - p_state->current_val > p_cfg->incr)
+ {
+ p_state->current_val += p_cfg->incr;
+ }
+ else
+ {
+ p_state->current_val = p_cfg->max;
+ p_state->is_increasing = false;
+ }
+}
+
+
+void sensorsim_decrement(sensorsim_state_t * p_state,
+ const sensorsim_cfg_t * p_cfg)
+{
+ if (p_state->current_val - p_cfg->min > p_cfg->incr)
+ {
+ p_state->current_val -= p_cfg->incr;
+ }
+ else
+ {
+ p_state->current_val = p_cfg->min;
+ p_state->is_increasing = true;
+ }
+}
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/sensorsim/sensorsim.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/sensorsim/sensorsim.h
new file mode 100644
index 0000000..af5e1cd
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/sensorsim/sensorsim.h
@@ -0,0 +1,121 @@
+/**
+ * Copyright (c) 2012 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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
+ *
+ * @defgroup ble_sdk_lib_sensorsim Sensor Data Simulator
+ * @{
+ * @ingroup ble_sdk_lib
+ * @brief Functions for simulating sensor data.
+ *
+ * @details Currently only a triangular waveform simulator is implemented.
+ */
+
+#ifndef SENSORSIM_H__
+#define SENSORSIM_H__
+
+#include <stdint.h>
+#include <stdbool.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**@brief Triangular waveform sensor simulator configuration. */
+typedef struct
+{
+ uint32_t min; /**< Minimum simulated value. */
+ uint32_t max; /**< Maximum simulated value. */
+ uint32_t incr; /**< Increment between each measurement. */
+ bool start_at_max; /**< TRUE is measurement is to start at the maximum value, FALSE if it is to start at the minimum. */
+} sensorsim_cfg_t;
+
+/**@brief Triangular waveform sensor simulator state. */
+typedef struct
+{
+ uint32_t current_val; /**< Current sensor value. */
+ bool is_increasing; /**< TRUE if the simulator is in increasing state, FALSE otherwise. */
+} sensorsim_state_t;
+
+/**@brief Function for initializing a triangular waveform sensor simulator.
+ *
+ * @param[out] p_state Current state of simulator.
+ * @param[in] p_cfg Simulator configuration.
+ */
+void sensorsim_init(sensorsim_state_t * p_state,
+ const sensorsim_cfg_t * p_cfg);
+
+/**@brief Function for generating a simulated sensor measurement using a triangular waveform generator.
+ *
+ * @param[in,out] p_state Current state of simulator.
+ * @param[in] p_cfg Simulator configuration.
+ *
+ * @return Simulator output.
+ */
+uint32_t sensorsim_measure(sensorsim_state_t * p_state,
+ const sensorsim_cfg_t * p_cfg);
+
+/**@brief Function for incrementing a simulated sensor measurement value.
+ *
+ * @param[in,out] p_state Current state of simulator.
+ * @param[in] p_cfg Simulator configuration.
+ *
+ * @return Simulator output.
+ */
+void sensorsim_increment(sensorsim_state_t * p_state,
+ const sensorsim_cfg_t * p_cfg);
+
+/**@brief Function for decrementing a simulated sensor measurement value.
+ *
+ * @param[in,out] p_state Current state of simulator.
+ * @param[in] p_cfg Simulator configuration.
+ *
+ * @return Simulator output.
+ */
+void sensorsim_decrement(sensorsim_state_t * p_state,
+ const sensorsim_cfg_t * p_cfg);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // SENSORSIM_H__
+
+/** @} */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/serial/nrf_serial.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/serial/nrf_serial.c
new file mode 100644
index 0000000..9cf89b8
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/serial/nrf_serial.c
@@ -0,0 +1,675 @@
+/**
+ * Copyright (c) 2016 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#include "sdk_common.h"
+#if NRF_MODULE_ENABLED(NRF_SERIAL)
+#include "nrf_serial.h"
+
+#if defined (UART_PRESENT)
+
+static void event_handler(nrf_serial_t const * p_serial,
+ nrf_serial_event_t event)
+{
+ if (p_serial->p_ctx->p_config->ev_handler)
+ {
+ p_serial->p_ctx->p_config->ev_handler(p_serial, event);
+ }
+}
+
+static void sleep_handler(nrf_serial_t const * p_serial)
+{
+ if (p_serial->p_ctx->p_config->mode == NRF_SERIAL_MODE_POLLING)
+ {
+ return;
+ }
+
+ if (p_serial->p_ctx->p_config->sleep_handler)
+ {
+ p_serial->p_ctx->p_config->sleep_handler();
+ }
+}
+
+static size_t serial_rx(nrf_serial_t const * p_serial,
+ uint8_t * p_buff,
+ size_t length)
+{
+ if (p_serial->p_ctx->p_config->mode == NRF_SERIAL_MODE_POLLING)
+ {
+ size_t rx_len = MIN(length, UINT8_MAX);
+ size_t len = rx_len;
+
+ while (nrf_drv_uart_rx_ready(&p_serial->instance) && len)
+ {
+ ret_code_t ret = nrf_drv_uart_rx(&p_serial->instance, p_buff, 1);
+ if (ret != NRF_SUCCESS)
+ {
+ break;
+ }
+ p_buff++;
+ len--;
+ }
+
+ return rx_len - len;
+ }
+
+ nrf_queue_t const * p_rxq = p_serial->p_ctx->p_config->p_queues->p_rxq;
+ return nrf_queue_out(p_rxq, p_buff, length);
+}
+
+static size_t serial_tx(nrf_serial_t const * p_serial,
+ uint8_t const * p_buff,
+ size_t length)
+{
+ size_t tx_len = 0;
+
+ if (p_serial->p_ctx->p_config->mode == NRF_SERIAL_MODE_POLLING)
+ {
+ tx_len = MIN(length, UINT8_MAX);
+ ret_code_t ret = nrf_drv_uart_tx(&p_serial->instance, p_buff, tx_len);
+ ASSERT(ret == NRF_SUCCESS)
+ return tx_len;
+ }
+
+ nrf_queue_t const * p_txq = p_serial->p_ctx->p_config->p_queues->p_txq;
+ nrf_serial_buffers_t const * p_buffs = p_serial->p_ctx->p_config->p_buffers;
+
+ /* Try to enqueue data. */
+ size_t queue_in_len = nrf_queue_in(p_txq, p_buff, length);
+ if (nrf_drv_uart_tx_in_progress(&p_serial->instance))
+ {
+ return queue_in_len;
+ }
+
+ size_t len = nrf_queue_out(p_txq, p_buffs->p_txb, p_buffs->tx_size);
+ ASSERT(len > 0);
+ ret_code_t ret = nrf_drv_uart_tx(&p_serial->instance, p_buffs->p_txb, len);
+ ASSERT(ret == NRF_SUCCESS);
+
+ return queue_in_len;
+}
+
+static void uart_event_handler(nrf_drv_uart_event_t * p_event, void * p_context)
+{
+ uint32_t ret;
+ nrf_serial_t const * p_serial = p_context;
+
+ switch (p_event->type)
+ {
+ case NRF_DRV_UART_EVT_RX_DONE:
+ {
+ nrf_queue_t const * p_rxq =
+ p_serial->p_ctx->p_config->p_queues->p_rxq;
+ size_t len = nrf_queue_in(p_rxq,
+ p_event->data.rxtx.p_data,
+ p_event->data.rxtx.bytes);
+
+ if (len < p_event->data.rxtx.bytes)
+ {
+ event_handler(p_serial, NRF_SERIAL_EVENT_FIFO_ERR);
+ break;
+ }
+
+ event_handler(p_serial, NRF_SERIAL_EVENT_RX_DATA);
+ nrf_serial_buffers_t const * p_buffs =
+ p_serial->p_ctx->p_config->p_buffers;
+
+ ret = nrf_drv_uart_rx(&p_serial->instance,
+ p_buffs->p_rxb,
+ p_buffs->rx_size);
+ ASSERT(ret == NRF_SUCCESS);
+ break;
+ }
+ case NRF_DRV_UART_EVT_ERROR:
+ {
+ event_handler(p_serial, NRF_SERIAL_EVENT_DRV_ERR);
+ break;
+ }
+ case NRF_DRV_UART_EVT_TX_DONE:
+ {
+ nrf_queue_t const * p_txq =
+ p_serial->p_ctx->p_config->p_queues->p_txq;
+ nrf_serial_buffers_t const * p_buffs =
+ p_serial->p_ctx->p_config->p_buffers;
+
+ event_handler(p_serial, NRF_SERIAL_EVENT_TX_DONE);
+ size_t len = nrf_queue_out(p_txq, p_buffs->p_txb, p_buffs->tx_size);
+ if (len == 0)
+ {
+ break;
+ }
+
+ ret = nrf_drv_uart_tx(&p_serial->instance, p_buffs->p_txb, len);
+ ASSERT(ret == NRF_SUCCESS);
+ break;
+ }
+ default:
+ break;
+ }
+}
+
+ret_code_t nrf_serial_init(nrf_serial_t const * p_serial,
+ nrf_drv_uart_config_t const * p_drv_uart_config,
+ nrf_serial_config_t const * p_config)
+{
+ ret_code_t ret;
+ ASSERT(p_serial && p_drv_uart_config && p_config);
+
+ if (p_serial->p_ctx->p_config)
+ {
+ /*Already initialized.*/
+ return NRF_ERROR_MODULE_ALREADY_INITIALIZED;
+ }
+
+ if (p_config->mode != NRF_SERIAL_MODE_POLLING)
+ {
+ ASSERT(p_config->p_queues && p_config->p_buffers);
+ }
+
+ nrf_drv_uart_config_t drv_config;
+ memcpy(&drv_config, p_drv_uart_config, sizeof(nrf_drv_uart_config_t));
+ drv_config.p_context = (void *)p_serial;
+#if defined(UARTE_PRESENT) && defined(UART_PRESENT)
+ drv_config.use_easy_dma = (p_config->mode == NRF_SERIAL_MODE_DMA);
+#endif
+ ret = nrf_drv_uart_init(&p_serial->instance,
+ &drv_config,
+ p_config->mode == NRF_SERIAL_MODE_POLLING ?
+ NULL : uart_event_handler);
+ if (ret != NRF_SUCCESS)
+ {
+ return ret;
+ }
+
+ p_serial->p_ctx->p_config = p_config;
+
+ if (p_serial->p_ctx->p_config->p_queues)
+ {
+ nrf_queue_reset(p_serial->p_ctx->p_config->p_queues->p_txq);
+ nrf_queue_reset(p_serial->p_ctx->p_config->p_queues->p_rxq);
+ }
+
+ nrf_mtx_init(&p_serial->p_ctx->read_lock);
+ nrf_mtx_init(&p_serial->p_ctx->write_lock);
+
+ p_serial->p_ctx->flags = NRF_SERIAL_RX_ENABLED_FLAG |
+ NRF_SERIAL_TX_ENABLED_FLAG;
+
+ if (drv_config.pseltxd == NRF_UART_PSEL_DISCONNECTED)
+ {
+ p_serial->p_ctx->flags &= ~NRF_SERIAL_TX_ENABLED_FLAG;
+ }
+
+ if (drv_config.pselrxd == NRF_UART_PSEL_DISCONNECTED)
+ {
+ p_serial->p_ctx->flags &= ~NRF_SERIAL_RX_ENABLED_FLAG;
+ return NRF_SUCCESS;
+ }
+
+ if (p_serial->p_ctx->p_config->mode != NRF_SERIAL_MODE_DMA)
+ {
+ nrf_drv_uart_rx_enable(&p_serial->instance);
+ if (p_serial->p_ctx->p_config->mode == NRF_SERIAL_MODE_POLLING)
+ {
+ return NRF_SUCCESS;
+ }
+ }
+
+ return nrf_drv_uart_rx(&p_serial->instance,
+ p_serial->p_ctx->p_config->p_buffers->p_rxb,
+ p_serial->p_ctx->p_config->p_buffers->rx_size);
+}
+
+ret_code_t nrf_serial_uninit(nrf_serial_t const * p_serial)
+{
+ ASSERT(p_serial);
+
+ if (!p_serial->p_ctx->p_config)
+ {
+ /*Already uninitialized.*/
+ return NRF_ERROR_MODULE_NOT_INITIALIZED;
+ }
+
+ if (!nrf_mtx_trylock(&p_serial->p_ctx->write_lock))
+ {
+ return NRF_ERROR_BUSY;
+ }
+ if (!nrf_mtx_trylock(&p_serial->p_ctx->read_lock))
+ {
+ nrf_mtx_unlock(&p_serial->p_ctx->write_lock);
+ return NRF_ERROR_BUSY;
+ }
+
+ nrf_drv_uart_uninit(&p_serial->instance);
+ if (p_serial->p_ctx->p_config->p_queues)
+ {
+ nrf_queue_reset(p_serial->p_ctx->p_config->p_queues->p_txq);
+ nrf_queue_reset(p_serial->p_ctx->p_config->p_queues->p_rxq);
+ }
+
+ memset(p_serial->p_ctx, 0, sizeof(nrf_serial_ctx_t));
+ return NRF_SUCCESS;
+}
+
+typedef struct {
+ volatile bool expired;
+} nrf_serial_timeout_ctx_t;
+
+static void serial_timeout_handler(void * p_context)
+{
+ nrf_serial_timeout_ctx_t * p_tout_ctx = p_context;
+ p_tout_ctx->expired = true;
+}
+
+
+static ret_code_t timeout_setup(nrf_serial_t const * p_serial,
+ app_timer_id_t const * p_timer_id,
+ uint32_t timeout_ms,
+ nrf_serial_timeout_ctx_t * p_tout_ctx)
+{
+ uint32_t ticks = APP_TIMER_TICKS(timeout_ms);
+
+ if (ticks < APP_TIMER_MIN_TIMEOUT_TICKS)
+ {
+ p_tout_ctx->expired = true;
+ return NRF_SUCCESS;
+ }
+
+ ret_code_t ret = app_timer_create(p_timer_id,
+ APP_TIMER_MODE_SINGLE_SHOT,
+ serial_timeout_handler);
+ if (ret != NRF_SUCCESS)
+ {
+ return ret;
+ }
+
+ return app_timer_start(*p_timer_id, ticks, p_tout_ctx);
+}
+
+ret_code_t nrf_serial_write(nrf_serial_t const * p_serial,
+ void const * p_data,
+ size_t size,
+ size_t * p_written,
+ uint32_t timeout_ms)
+{
+ ret_code_t ret;
+
+ ASSERT(p_serial);
+ if (!p_serial->p_ctx->p_config)
+ {
+ return NRF_ERROR_MODULE_NOT_INITIALIZED;
+ }
+
+ if (!(p_serial->p_ctx->flags & NRF_SERIAL_TX_ENABLED_FLAG))
+ {
+ return NRF_ERROR_INVALID_STATE;
+ }
+
+ if (size == 0)
+ {
+ return NRF_SUCCESS;
+ }
+
+ if (!nrfx_is_in_ram(p_data) &&
+ p_serial->p_ctx->p_config->mode == NRF_SERIAL_MODE_DMA)
+ {
+ return NRF_ERROR_INVALID_ADDR;
+ }
+
+ if (!nrf_mtx_trylock(&p_serial->p_ctx->write_lock))
+ {
+ return NRF_ERROR_BUSY;
+ }
+
+ nrf_serial_timeout_ctx_t tout_ctx = {
+ .expired = false,
+ };
+
+ if (timeout_ms != NRF_SERIAL_MAX_TIMEOUT)
+ {
+ ret = timeout_setup(p_serial,
+ p_serial->p_tx_timer,
+ timeout_ms,
+ &tout_ctx);
+ if (ret != NRF_SUCCESS)
+ {
+ nrf_mtx_unlock(&p_serial->p_ctx->write_lock);
+ return ret;
+ }
+ }
+
+ size_t left = size;
+ uint8_t const * p_buff = p_data;
+
+ do
+ {
+ size_t wcnt = serial_tx(p_serial, p_buff, left);
+ left -= wcnt;
+ p_buff += wcnt;
+ if (!left)
+ {
+ break;
+ }
+
+ sleep_handler(p_serial);
+ } while (!tout_ctx.expired);
+
+ if (p_written)
+ {
+ *p_written = size - left;
+ }
+
+ if (!tout_ctx.expired && (timeout_ms != NRF_SERIAL_MAX_TIMEOUT))
+ {
+ (void)app_timer_stop(*p_serial->p_tx_timer);
+ }
+
+ nrf_mtx_unlock(&p_serial->p_ctx->write_lock);
+ if (left && tout_ctx.expired)
+ {
+ return NRF_ERROR_TIMEOUT;
+ }
+
+ return NRF_SUCCESS;
+}
+
+ret_code_t nrf_serial_read(nrf_serial_t const * p_serial,
+ void * p_data,
+ size_t size,
+ size_t * p_read,
+ uint32_t timeout_ms)
+{
+ ret_code_t ret;
+
+ ASSERT(p_serial);
+ if (!p_serial->p_ctx->p_config)
+ {
+ return NRF_ERROR_MODULE_NOT_INITIALIZED;
+ }
+
+ if (!(p_serial->p_ctx->flags & NRF_SERIAL_RX_ENABLED_FLAG))
+ {
+ return NRF_ERROR_INVALID_STATE;
+ }
+
+ if (size == 0)
+ {
+ return NRF_SUCCESS;
+ }
+
+ if (!nrf_mtx_trylock(&p_serial->p_ctx->read_lock))
+ {
+ return NRF_ERROR_BUSY;
+ }
+
+ nrf_serial_timeout_ctx_t tout_ctx = {
+ .expired = false,
+ };
+
+ if (timeout_ms != NRF_SERIAL_MAX_TIMEOUT)
+ {
+ ret = timeout_setup(p_serial,
+ p_serial->p_rx_timer,
+ timeout_ms,
+ &tout_ctx);
+
+ if (ret != NRF_SUCCESS)
+ {
+ nrf_mtx_unlock(&p_serial->p_ctx->read_lock);
+ return ret;
+ }
+ }
+
+ size_t left = size;
+ uint8_t * p_buff = p_data;
+ do
+ {
+ size_t rcnt = serial_rx(p_serial, p_buff, left);
+ left -= rcnt;
+ p_buff += rcnt;
+ if (!left)
+ {
+ break;
+ }
+
+ if (tout_ctx.expired)
+ {
+ if (p_serial->p_ctx->p_config->mode != NRF_SERIAL_MODE_POLLING)
+ {
+ nrf_drv_uart_rx_abort(&p_serial->instance);
+ }
+ break;
+ }
+
+ sleep_handler(p_serial);
+ } while (1);
+
+ if (p_read)
+ {
+ *p_read = size - left;
+ }
+
+ if (!tout_ctx.expired && (timeout_ms != NRF_SERIAL_MAX_TIMEOUT))
+ {
+ (void)app_timer_stop(*p_serial->p_rx_timer);
+ }
+
+ nrf_mtx_unlock(&p_serial->p_ctx->read_lock);
+ if (left && tout_ctx.expired)
+ {
+ return NRF_ERROR_TIMEOUT;
+ }
+
+ return NRF_SUCCESS;
+}
+
+ret_code_t nrf_serial_flush(nrf_serial_t const * p_serial, uint32_t timeout_ms)
+{
+
+ ret_code_t ret;
+
+ ASSERT(p_serial);
+ if (!p_serial->p_ctx->p_config)
+ {
+ return NRF_ERROR_MODULE_NOT_INITIALIZED;
+ }
+
+ if (!(p_serial->p_ctx->flags & NRF_SERIAL_TX_ENABLED_FLAG))
+ {
+ return NRF_ERROR_INVALID_STATE;
+ }
+
+ if (p_serial->p_ctx->p_config->mode == NRF_SERIAL_MODE_POLLING)
+ {
+ return NRF_SUCCESS;
+ }
+
+ if (!nrf_mtx_trylock(&p_serial->p_ctx->write_lock))
+ {
+ return NRF_ERROR_BUSY;
+ }
+
+ nrf_serial_timeout_ctx_t tout_ctx = {
+ .expired = false,
+ };
+
+ if (timeout_ms != NRF_SERIAL_MAX_TIMEOUT)
+ {
+ ret = timeout_setup(p_serial,
+ p_serial->p_tx_timer,
+ timeout_ms,
+ &tout_ctx);
+ if (ret != NRF_SUCCESS)
+ {
+ nrf_mtx_unlock(&p_serial->p_ctx->write_lock);
+ return ret;
+ }
+ }
+
+ bool empty;
+ do
+ {
+ empty = nrf_queue_is_empty(p_serial->p_ctx->p_config->p_queues->p_txq)
+ && !nrf_drv_uart_tx_in_progress(&p_serial->instance);
+ if (empty)
+ {
+ break;
+ }
+
+ sleep_handler(p_serial);
+ } while (!tout_ctx.expired);
+
+ if (!tout_ctx.expired && (timeout_ms != NRF_SERIAL_MAX_TIMEOUT))
+ {
+ (void)app_timer_stop(*p_serial->p_tx_timer);
+ }
+
+ nrf_mtx_unlock(&p_serial->p_ctx->write_lock);
+ if (!empty && tout_ctx.expired)
+ {
+ return NRF_ERROR_TIMEOUT;
+ }
+
+ return NRF_SUCCESS;
+}
+
+ret_code_t nrf_serial_tx_abort(nrf_serial_t const * p_serial)
+{
+ ASSERT(p_serial);
+ if (!p_serial->p_ctx->p_config)
+ {
+ return NRF_ERROR_MODULE_NOT_INITIALIZED;
+ }
+
+ if (!(p_serial->p_ctx->flags & NRF_SERIAL_TX_ENABLED_FLAG))
+ {
+ return NRF_ERROR_INVALID_STATE;
+ }
+
+ if (!nrf_mtx_trylock(&p_serial->p_ctx->write_lock))
+ {
+ return NRF_ERROR_BUSY;
+ }
+
+ nrf_drv_uart_tx_abort(&p_serial->instance);
+ if (p_serial->p_ctx->p_config->p_queues->p_txq)
+ {
+ nrf_queue_reset(p_serial->p_ctx->p_config->p_queues->p_txq);
+ }
+
+ nrf_mtx_unlock(&p_serial->p_ctx->write_lock);
+ return NRF_SUCCESS;
+}
+
+ret_code_t nrf_serial_rx_drain(nrf_serial_t const * p_serial)
+{
+ ASSERT(p_serial);
+ if (!p_serial->p_ctx->p_config)
+ {
+ return NRF_ERROR_MODULE_NOT_INITIALIZED;
+ }
+
+ if (!(p_serial->p_ctx->flags & NRF_SERIAL_RX_ENABLED_FLAG))
+ {
+ return NRF_ERROR_INVALID_STATE;
+ }
+
+ if (!nrf_mtx_trylock(&p_serial->p_ctx->read_lock))
+ {
+ return NRF_ERROR_BUSY;
+ }
+
+ uint8_t c;
+ /*Drain HW FIFO*/
+ while (serial_rx(p_serial, &c, sizeof(c)))
+ {
+
+ }
+
+ /*Drain SW FIFO*/
+ if (p_serial->p_ctx->p_config->p_queues->p_rxq)
+ {
+ nrf_queue_reset(p_serial->p_ctx->p_config->p_queues->p_rxq);
+ }
+ nrf_mtx_unlock(&p_serial->p_ctx->read_lock);
+ return NRF_SUCCESS;
+}
+#else
+ret_code_t nrf_serial_init(nrf_serial_t const * p_serial,
+ nrf_drv_uart_config_t const * p_drv_uart_config,
+ nrf_serial_config_t const * p_config)
+{
+ return NRF_ERROR_NOT_SUPPORTED;
+}
+
+ret_code_t nrf_serial_uninit(nrf_serial_t const * p_serial)
+{
+ return NRF_ERROR_NOT_SUPPORTED;
+}
+ret_code_t nrf_serial_write(nrf_serial_t const * p_serial,
+ void const * p_data,
+ size_t size,
+ size_t * p_written,
+ uint32_t timeout_ms)
+{
+ return NRF_ERROR_NOT_SUPPORTED;
+}
+ret_code_t nrf_serial_read(nrf_serial_t const * p_serial,
+ void * p_data,
+ size_t size,
+ size_t * p_read,
+ uint32_t timeout_ms)
+{
+ return NRF_ERROR_NOT_SUPPORTED;
+}
+ret_code_t nrf_serial_flush(nrf_serial_t const * p_serial, uint32_t timeout_ms)
+{
+ return NRF_ERROR_NOT_SUPPORTED;
+}
+ret_code_t nrf_serial_tx_abort(nrf_serial_t const * p_serial)
+{
+ return NRF_ERROR_NOT_SUPPORTED;
+}
+ret_code_t nrf_serial_rx_drain(nrf_serial_t const * p_serial)
+{
+ return NRF_ERROR_NOT_SUPPORTED;
+}
+
+#endif // UART_PRESENT
+#endif //NRF_MODULE_ENABLED(NRF_SERIAL)
+
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/serial/nrf_serial.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/serial/nrf_serial.h
new file mode 100644
index 0000000..167e373
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/serial/nrf_serial.h
@@ -0,0 +1,397 @@
+/**
+ * Copyright (c) 2016 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#ifndef NRF_SERIAL_H__
+#define NRF_SERIAL_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <stdint.h>
+#include <stdbool.h>
+
+#include "nrf_drv_uart.h"
+#include "nrf_queue.h"
+#include "nrf_mtx.h"
+#include "app_timer.h"
+
+/**@file
+ *
+ * @defgroup nrf_serial Serial port abstraction layer
+ * @{
+ * @ingroup app_common
+ *
+ * @brief Serial module interface.
+ * @details This module is more sophisticated than @ref nrf_drv_uart. It internally uses
+ * mutex, queues, and app_timer. You can configure it to work in three different modes
+ * (polling, interrupt, DMA). API can be configured to work in synchronous mode. Both read and write
+ * methods have a timeout parameter. Asynchronous mode is available by passing 0 as the
+ * timeout parameter.
+ * @warning Do not use synchronous API (timeout_ms parameter > 0) in IRQ
+ * context. It may lead to a deadlock because the timeout interrupt cannot
+ * preempt the current IRQ context.
+ */
+
+typedef struct nrf_serial_s nrf_serial_t;
+
+/**
+ * @brief Serial port mode.
+ * */
+typedef enum {
+ NRF_SERIAL_MODE_POLLING, /**< Polling mode.*/
+ NRF_SERIAL_MODE_IRQ, /**< Interrupt mode.*/
+ NRF_SERIAL_MODE_DMA, /**< DMA mode.*/
+} nrf_serial_mode_t;
+
+
+
+/**
+ * @brief Creates an instance of @ref nrf_drv_uart_config_t.
+ *
+ * @param _name Instance name.
+ * @param _rx_pin RX pin number.
+ * @param _tx_pin TX pin number.
+ * @param _rts_pin RTS pin number.
+ * @param _cts_pin CTS pin number.
+ * @param _flow_control Flow control enable/disable (@ref nrf_uart_hwfc_t).
+ * @param _parity Parity enable/disable (@ref nrf_uart_parity_t).
+ * @param _baud_rate Baud rate (@ref nrf_uart_baudrate_t).
+ * @param _irq_prio Interrupt priority.
+ *
+ * */
+#define NRF_SERIAL_DRV_UART_CONFIG_DEF(_name, \
+ _rx_pin, \
+ _tx_pin, \
+ _rts_pin, \
+ _cts_pin, \
+ _flow_control, \
+ _parity, \
+ _baud_rate, \
+ _irq_prio) \
+ static const nrf_drv_uart_config_t _name = { \
+ .pselrxd = _rx_pin, \
+ .pseltxd = _tx_pin, \
+ .pselrts = _rts_pin, \
+ .pselcts = _cts_pin, \
+ .hwfc = _flow_control, \
+ .parity = _parity, \
+ .baudrate = _baud_rate, \
+ .interrupt_priority = _irq_prio, \
+ }
+
+/**
+ * @brief Serial port RX and TX queues.
+ *
+ * @note Use the @ref NRF_SERIAL_QUEUES_DEF macro to create an instance of this
+ * structure.
+ * */
+typedef struct {
+ nrf_queue_t const * p_rxq; //!< Receive queue handle.
+ nrf_queue_t const * p_txq; //!< Transmit queue handle.
+} nrf_serial_queues_t;
+
+/**
+ * @brief Creates an instance of serial port queues.
+ *
+ * @param _name Instance name.
+ * @param _tx_size TX queue size.
+ * @param _rx_size RX queue size.
+ * */
+#define NRF_SERIAL_QUEUES_DEF(_name, _tx_size, _rx_size) \
+ NRF_QUEUE_DEF(uint8_t, _name##_rxq, _rx_size, NRF_QUEUE_MODE_NO_OVERFLOW); \
+ NRF_QUEUE_DEF(uint8_t, _name##_txq, _tx_size, NRF_QUEUE_MODE_NO_OVERFLOW); \
+ static const nrf_serial_queues_t _name = { \
+ .p_rxq = &_name##_rxq, \
+ .p_txq = &_name##_txq, \
+ }
+
+/**
+ * @brief Serial buffers. Data slices used by @ref nrf_drv_uart_tx and
+ * @ref nrf_drv_uart_rx.
+ *
+ * @note Use the @ref NRF_SERIAL_BUFFERS_DEF macro to create an instance of this
+ * structure.
+ * */
+typedef struct {
+ void * p_txb; //!< TX buffer.
+ void * p_rxb; //!< RX buffer.
+ uint8_t tx_size; //!< TX buffer size.
+ uint8_t rx_size; //!< RX buffer size.
+} nrf_serial_buffers_t;
+
+/**
+ * @brief Creates an instance of serial port buffers.
+ *
+ * @param _name Instance name.
+ * @param _tx_size TX buffer size.
+ * @param _rx_size RX buffer size.
+ * */
+#define NRF_SERIAL_BUFFERS_DEF(_name, _tx_size, _rx_size) \
+ STATIC_ASSERT((_tx_size) <= UINT8_MAX); \
+ STATIC_ASSERT((_rx_size) <= UINT8_MAX); \
+ static uint8_t _name##_txb[_tx_size]; \
+ static uint8_t _name##_rxb[_rx_size]; \
+ static const nrf_serial_buffers_t _name = { \
+ .p_txb = _name##_txb, \
+ .p_rxb = _name##_rxb, \
+ .tx_size = sizeof(_name##_txb), \
+ .rx_size = sizeof(_name##_rxb), \
+ }
+
+/**
+ * @brief Events generated by this module.
+ * */
+typedef enum {
+ NRF_SERIAL_EVENT_TX_DONE, //!< Chunk of data has been sent.
+ NRF_SERIAL_EVENT_RX_DATA, //!< New chunk of data has been received.
+ NRF_SERIAL_EVENT_DRV_ERR, //!< Internal driver error.
+ NRF_SERIAL_EVENT_FIFO_ERR, //!< RX FIFO overrun.
+} nrf_serial_event_t;
+
+/**
+ * @brief Event handler type.
+ * */
+typedef void (*nrf_serial_evt_handler_t)(struct nrf_serial_s const * p_serial,
+ nrf_serial_event_t event);
+
+/**
+ * @brief Sleep handler type.
+ * */
+typedef void (*nrf_serial_sleep_handler_t)(void);
+
+/**
+ * @brief Configuration of UART serial interface.
+ *
+ * @note Use the @ref NRF_SERIAL_CONFIG_DEF macro to create an instance of this
+ * structure.
+ *
+ */
+typedef struct {
+ nrf_serial_mode_t mode; //!< Serial port mode.
+
+ nrf_serial_queues_t const * p_queues; //!< Serial port queues.
+ nrf_serial_buffers_t const * p_buffers; //!< DMA buffers.
+ nrf_serial_evt_handler_t ev_handler; //!< Event handler.
+ nrf_serial_sleep_handler_t sleep_handler; //!< Sleep mode handler.
+} nrf_serial_config_t;
+
+/**
+ * @brief Creates an instance of serial port configuration.
+ *
+ * @param _name Instance name.
+ * @param _mode Serial port mode.
+ * @param _queues Serial port queues. NULL can be passed in @ref NRF_SERIAL_MODE_POLLING mode.
+ * @param _buffers Serial port buffers. NULL can be passed in @ref NRF_SERIAL_MODE_POLLING mode.
+ * @param _ev_handler Serial port event handler. NULL can be passed in any mode.
+ * @param _sleep Serial port sleep handler. NULL can be passed in any mode.
+ * */
+#define NRF_SERIAL_CONFIG_DEF(_name, _mode, _queues, _buffers, _ev_handler, _sleep) \
+ static const nrf_serial_config_t _name = { \
+ .mode = _mode, \
+ .p_queues = _queues, \
+ .p_buffers = _buffers, \
+ .ev_handler = _ev_handler, \
+ .sleep_handler = _sleep, \
+ }
+
+#define NRF_SERIAL_RX_ENABLED_FLAG (1u << 0) //!< Receiver enable flag.
+#define NRF_SERIAL_TX_ENABLED_FLAG (1u << 1) //!< Transmitter enable flag.
+
+/**
+ * @brief Serial port context. Contains all data structures that need
+ * to be stored in RAM memory.
+ * */
+typedef struct {
+ nrf_serial_config_t const * p_config; //!< Serial port configuration.
+
+ nrf_mtx_t write_lock; //!< Write operation lock.
+ nrf_mtx_t read_lock; //!< Read operation lock.
+
+ uint8_t flags; //!< Transmitter/receiver enable flags.
+} nrf_serial_ctx_t;
+
+/**
+ * @brief Serial port instance declaration.
+ *
+ * @note Use @ref NRF_SERIAL_UART_DEF macro to create an instance of this
+ * structure.
+ * */
+struct nrf_serial_s {
+ nrf_drv_uart_t instance; //!< Driver instance.
+ nrf_serial_ctx_t * p_ctx; //!< Driver context.
+
+ app_timer_id_t const * p_tx_timer; //!< TX timeout timer.
+ app_timer_id_t const * p_rx_timer; //!< RX timeout timer.
+};
+
+/**
+ * @brief Creates an instance of a serial port.
+ *
+ * @param _name Instance name.
+ * @param _instance_number Driver instance number (@ref NRF_DRV_UART_INSTANCE).
+ * */
+#define NRF_SERIAL_UART_DEF(_name, _instance_number) \
+ APP_TIMER_DEF(_name##_rx_timer); \
+ APP_TIMER_DEF(_name##_tx_timer); \
+ static nrf_serial_ctx_t _name##_ctx; \
+ static const nrf_serial_t _name = { \
+ .instance = NRF_DRV_UART_INSTANCE(_instance_number), \
+ .p_ctx = &_name##_ctx, \
+ .p_tx_timer = &_name##_tx_timer, \
+ .p_rx_timer = &_name##_rx_timer, \
+ }
+
+
+/**
+ * @brief Maximum value of timeout. API might be blocked indefinitely if this value is
+ * not set.*/
+#define NRF_SERIAL_MAX_TIMEOUT UINT32_MAX
+
+/**
+ * @brief Function for initializing a serial port. Serial port can be initialized
+ * in various modes that are defined by nrf_serial_mode_t.
+ * - NRF_SERIAL_MODE_POLLING - Simple polling mode. API calls will be
+ * synchronous. There is no need to define queues or buffers.
+ * No events will be generated.
+ * - NRF_SERIAL_MODE_IRQ - Interrupt mode. API can be set to work in synchronous or
+ * asynchronous mode. Queues and buffers must be passed
+ * during initialization. Events will be generated if
+ * a non NULL handler is passed as the ev_handler parameter.
+ * - NRF_SERIAL_MODE_DMA - Similar to @ref NRF_SERIAL_MODE_IRQ. Uses EasyDMA.
+ *
+ *
+ * @param p_serial Serial port instance.
+ * @param p_drv_uart_config UART driver configuration. Cannot be NULL.
+ * @param p_config Serial port configuration. Cannot be NULL. This object must be created
+ * using the @ref NRF_SERIAL_CONFIG_DEF macro.
+ *
+ * @return Standard error code.
+ * */
+ret_code_t nrf_serial_init(nrf_serial_t const * p_serial,
+ nrf_drv_uart_config_t const * p_drv_uart_config,
+ nrf_serial_config_t const * p_config);
+
+
+/**
+ * @brief Function for uninitializing a serial port.
+ *
+ * @param p_serial Serial port instance.
+ *
+ * @return Standard error code.
+ * */
+ret_code_t nrf_serial_uninit(nrf_serial_t const * p_serial);
+
+
+/**
+ * @brief Function for writing to a serial port.
+ *
+ * @param p_serial Serial port instance.
+ * @param p_data Transmit buffer pointer.
+ * @param size Transmit buffer size.
+ * @param p_written Amount of data actually written to the serial port.
+ * NULL pointer can be passed.
+ * @param timeout_ms Operation timeout, in milliseconds. Pass 0 to operate in
+ * non blocking mode.
+ *
+ * @return Standard error code.
+ * */
+ret_code_t nrf_serial_write(nrf_serial_t const * p_serial,
+ void const * p_data,
+ size_t size,
+ size_t * p_written,
+ uint32_t timeout_ms);
+
+/**
+ * @brief Function for reading from a serial port.
+ *
+ * @param p_serial Serial port instance.
+ * @param p_data Receive buffer pointer.
+ * @param size Receive buffer size.
+ * @param p_read Amount of data actually read from the serial port.
+ * NULL pointer can be passed.
+ * @param timeout_ms Operation timeout, in milliseconds. Pass 0 to operate in
+ * non blocking mode.
+ *
+ * @return Standard error code.
+ * */
+ret_code_t nrf_serial_read(nrf_serial_t const * p_serial,
+ void * p_data,
+ size_t size,
+ size_t * p_read,
+ uint32_t timeout_ms);
+
+/**
+ * @brief Function for flushing a serial port TX queue.
+ *
+ * @param p_serial Serial port instance.
+ * @param timeout_ms Operation timeout, in milliseconds. Pass 0 to operate in
+ * non blocking mode.
+ * @return Standard error code.
+ * */
+ret_code_t nrf_serial_flush(nrf_serial_t const * p_serial, uint32_t timeout_ms);
+
+
+/**
+ * @brief Function for aborting a serial port transmission.
+ * Aborts the current ongoing transmission and resets TX FIFO.
+ *
+ * @param p_serial Serial port instance.
+ *
+ * @return Standard error code.
+ * */
+ret_code_t nrf_serial_tx_abort(nrf_serial_t const * p_serial);
+
+/**
+ * @brief Function for draining the serial port receive RX FIFO.
+ * Drains HW FIFO and resets RX FIFO.
+ *
+ * @param p_serial Serial port instance.
+ *
+ * @return Standard error code.
+ * */
+ret_code_t nrf_serial_rx_drain(nrf_serial_t const * p_serial);
+
+/** @} */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* NRF_SERIAL_H__ */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/sha256/sha256.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/sha256/sha256.c
new file mode 100644
index 0000000..8cc6b76
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/sha256/sha256.c
@@ -0,0 +1,225 @@
+/**
+ * Copyright (c) 2015 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#include <stdlib.h>
+#include "sha256.h"
+#include "sdk_errors.h"
+#include "sdk_common.h"
+
+
+#define ROTLEFT(a,b) (((a) << (b)) | ((a) >> (32 - (b))))
+#define ROTRIGHT(a,b) (((a) >> (b)) | ((a) << (32 - (b))))
+
+#define CH(x,y,z) (((x) & (y)) ^ (~(x) & (z)))
+#define MAJ(x,y,z) (((x) & (y)) ^ ((x) & (z)) ^ ((y) & (z)))
+#define EP0(x) (ROTRIGHT(x,2) ^ ROTRIGHT(x,13) ^ ROTRIGHT(x,22))
+#define EP1(x) (ROTRIGHT(x,6) ^ ROTRIGHT(x,11) ^ ROTRIGHT(x,25))
+#define SIG0(x) (ROTRIGHT(x,7) ^ ROTRIGHT(x,18) ^ ((x) >> 3))
+#define SIG1(x) (ROTRIGHT(x,17) ^ ROTRIGHT(x,19) ^ ((x) >> 10))
+
+
+static const uint32_t k[64] = {
+ 0x428a2f98,0x71374491,0xb5c0fbcf,0xe9b5dba5,0x3956c25b,0x59f111f1,0x923f82a4,0xab1c5ed5,
+ 0xd807aa98,0x12835b01,0x243185be,0x550c7dc3,0x72be5d74,0x80deb1fe,0x9bdc06a7,0xc19bf174,
+ 0xe49b69c1,0xefbe4786,0x0fc19dc6,0x240ca1cc,0x2de92c6f,0x4a7484aa,0x5cb0a9dc,0x76f988da,
+ 0x983e5152,0xa831c66d,0xb00327c8,0xbf597fc7,0xc6e00bf3,0xd5a79147,0x06ca6351,0x14292967,
+ 0x27b70a85,0x2e1b2138,0x4d2c6dfc,0x53380d13,0x650a7354,0x766a0abb,0x81c2c92e,0x92722c85,
+ 0xa2bfe8a1,0xa81a664b,0xc24b8b70,0xc76c51a3,0xd192e819,0xd6990624,0xf40e3585,0x106aa070,
+ 0x19a4c116,0x1e376c08,0x2748774c,0x34b0bcb5,0x391c0cb3,0x4ed8aa4a,0x5b9cca4f,0x682e6ff3,
+ 0x748f82ee,0x78a5636f,0x84c87814,0x8cc70208,0x90befffa,0xa4506ceb,0xbef9a3f7,0xc67178f2
+};
+
+
+/**@brief Function for calculating the hash of a 64-byte section of data.
+ *
+ * @param[in,out] ctx Hash instance.
+ * @param[in] data Aray with data to be hashed. Assumed to be 64 bytes long.
+ */
+void sha256_transform(sha256_context_t *ctx, const uint8_t * data)
+{
+ uint32_t a, b, c, d, e, f, g, h, i, j, t1, t2, m[64];
+
+ for (i = 0, j = 0; i < 16; ++i, j += 4)
+ m[i] = (data[j] << 24) | (data[j + 1] << 16) | (data[j + 2] << 8) | (data[j + 3]);
+ for ( ; i < 64; ++i)
+ m[i] = SIG1(m[i - 2]) + m[i - 7] + SIG0(m[i - 15]) + m[i - 16];
+
+ a = ctx->state[0];
+ b = ctx->state[1];
+ c = ctx->state[2];
+ d = ctx->state[3];
+ e = ctx->state[4];
+ f = ctx->state[5];
+ g = ctx->state[6];
+ h = ctx->state[7];
+
+ for (i = 0; i < 64; ++i) {
+ t1 = h + EP1(e) + CH(e,f,g) + k[i] + m[i];
+ t2 = EP0(a) + MAJ(a,b,c);
+ h = g;
+ g = f;
+ f = e;
+ e = d + t1;
+ d = c;
+ c = b;
+ b = a;
+ a = t1 + t2;
+ }
+
+ ctx->state[0] += a;
+ ctx->state[1] += b;
+ ctx->state[2] += c;
+ ctx->state[3] += d;
+ ctx->state[4] += e;
+ ctx->state[5] += f;
+ ctx->state[6] += g;
+ ctx->state[7] += h;
+}
+
+
+ret_code_t sha256_init(sha256_context_t *ctx)
+{
+ VERIFY_PARAM_NOT_NULL(ctx);
+
+ ctx->datalen = 0;
+ ctx->bitlen = 0;
+ ctx->state[0] = 0x6a09e667;
+ ctx->state[1] = 0xbb67ae85;
+ ctx->state[2] = 0x3c6ef372;
+ ctx->state[3] = 0xa54ff53a;
+ ctx->state[4] = 0x510e527f;
+ ctx->state[5] = 0x9b05688c;
+ ctx->state[6] = 0x1f83d9ab;
+ ctx->state[7] = 0x5be0cd19;
+
+ return NRF_SUCCESS;
+}
+
+
+ret_code_t sha256_update(sha256_context_t *ctx, const uint8_t * data, size_t len)
+{
+ VERIFY_PARAM_NOT_NULL(ctx);
+ if (((len > 0) && (data == NULL)))
+ {
+ return NRF_ERROR_NULL;
+ }
+
+ uint32_t i;
+
+ for (i = 0; i < len; ++i) {
+ ctx->data[ctx->datalen] = data[i];
+ ctx->datalen++;
+ if (ctx->datalen == 64) {
+ sha256_transform(ctx, ctx->data);
+ ctx->bitlen += 512;
+ ctx->datalen = 0;
+ }
+ }
+
+ return NRF_SUCCESS;
+}
+
+
+ret_code_t sha256_final(sha256_context_t *ctx, uint8_t * hash, uint8_t le)
+{
+ uint32_t i;
+
+ VERIFY_PARAM_NOT_NULL(ctx);
+ VERIFY_PARAM_NOT_NULL(hash);
+
+ i = ctx->datalen;
+
+ // Pad whatever data is left in the buffer.
+ if (ctx->datalen < 56) {
+ ctx->data[i++] = 0x80;
+ while (i < 56)
+ ctx->data[i++] = 0x00;
+ }
+ else {
+ ctx->data[i++] = 0x80;
+ while (i < 64)
+ ctx->data[i++] = 0x00;
+ sha256_transform(ctx, ctx->data);
+ memset(ctx->data, 0, 56);
+ }
+
+ // Append to the padding the total message's length in bits and transform.
+ ctx->bitlen += (uint64_t)ctx->datalen * 8;
+ ctx->data[63] = ctx->bitlen;
+ ctx->data[62] = ctx->bitlen >> 8;
+ ctx->data[61] = ctx->bitlen >> 16;
+ ctx->data[60] = ctx->bitlen >> 24;
+ ctx->data[59] = ctx->bitlen >> 32;
+ ctx->data[58] = ctx->bitlen >> 40;
+ ctx->data[57] = ctx->bitlen >> 48;
+ ctx->data[56] = ctx->bitlen >> 56;
+ sha256_transform(ctx, ctx->data);
+
+ if (le)
+ {
+ for (i = 0; i < 4; ++i) {
+ hash[i] = (ctx->state[7] >> (i * 8)) & 0x000000ff;
+ hash[i + 4] = (ctx->state[6] >> (i * 8)) & 0x000000ff;
+ hash[i + 8] = (ctx->state[5] >> (i * 8)) & 0x000000ff;
+ hash[i + 12] = (ctx->state[4] >> (i * 8)) & 0x000000ff;
+ hash[i + 16] = (ctx->state[3] >> (i * 8)) & 0x000000ff;
+ hash[i + 20] = (ctx->state[2] >> (i * 8)) & 0x000000ff;
+ hash[i + 24] = (ctx->state[1] >> (i * 8)) & 0x000000ff;
+ hash[i + 28] = (ctx->state[0] >> (i * 8)) & 0x000000ff;
+ }
+ }
+ else
+ {
+
+ // Since this implementation uses little endian uint8_t ordering and SHA uses big endian,
+ // reverse all the uint8_ts when copying the final state to the output hash.
+ for (i = 0; i < 4; ++i) {
+ hash[i] = (ctx->state[0] >> (24 - i * 8)) & 0x000000ff;
+ hash[i + 4] = (ctx->state[1] >> (24 - i * 8)) & 0x000000ff;
+ hash[i + 8] = (ctx->state[2] >> (24 - i * 8)) & 0x000000ff;
+ hash[i + 12] = (ctx->state[3] >> (24 - i * 8)) & 0x000000ff;
+ hash[i + 16] = (ctx->state[4] >> (24 - i * 8)) & 0x000000ff;
+ hash[i + 20] = (ctx->state[5] >> (24 - i * 8)) & 0x000000ff;
+ hash[i + 24] = (ctx->state[6] >> (24 - i * 8)) & 0x000000ff;
+ hash[i + 28] = (ctx->state[7] >> (24 - i * 8)) & 0x000000ff;
+ }
+ }
+
+ return NRF_SUCCESS;
+}
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/sha256/sha256.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/sha256/sha256.h
new file mode 100644
index 0000000..8be5786
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/sha256/sha256.h
@@ -0,0 +1,127 @@
+/**
+ * Copyright (c) 2015 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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
+ *
+ * @defgroup sha256 SHA-256 hash library
+ * @{
+ * @ingroup app_common
+ *
+ * @brief This module calculates SHA-256 (SHA-2, FIPS-180) hashes.
+ *
+ * @details To use this module, first call @ref sha256_init on a @ref sha256_context_t instance. Then call @ref
+ * sha256_update with the data to be hashed. This step can optionally be done with multiple
+ * calls to @ref sha256_update, each with a section of the data (in the correct order).
+ * After all data has been passed to @ref sha256_update, call @ref sha256_final to finalize
+ * and extract the hash value.
+ *
+ * This code is adapted from code by Brad Conte, retrieved from
+ * https://github.com/B-Con/crypto-algorithms.
+ *
+ */
+
+#ifndef SHA256_H
+#define SHA256_H
+
+
+#include <stdint.h>
+#include "sdk_errors.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+/**@brief Current state of a hash operation.
+ */
+typedef struct {
+ uint8_t data[64];
+ uint32_t datalen;
+ uint64_t bitlen;
+ uint32_t state[8];
+} sha256_context_t;
+
+
+/**@brief Function for initializing a @ref sha256_context_t instance.
+ *
+ * @param[out] ctx Context instance to be initialized.
+ *
+ * @retval NRF_SUCCESS If the instance was successfully initialized.
+ * @retval NRF_ERROR_NULL If the parameter was NULL.
+ */
+ret_code_t sha256_init(sha256_context_t *ctx);
+
+/**@brief Function for calculating the hash of an array of uint8_t data.
+ *
+ * @details This function can be called multiple times in sequence. This is equivalent to calling
+ * the function once on a concatenation of the data from the different calls.
+ *
+ * @param[in,out] ctx Hash instance.
+ * @param[in] data Data to be hashed.
+ * @param[in] len Length of the data to be hashed.
+ *
+ * @retval NRF_SUCCESS If the data was successfully hashed.
+ * @retval NRF_ERROR_NULL If the ctx parameter was NULL or the data parameter was NULL, while the len parameter was not zero.
+ */
+ret_code_t sha256_update(sha256_context_t *ctx, const uint8_t * data, const size_t len);
+
+/**@brief Function for extracting the hash value from a hash instance.
+ *
+ * @details This function should be called after all data to be hashed has been passed to the hash
+ * instance (by one or more calls to @ref sha256_update).
+ *
+ * Do not call @ref sha256_update again after @ref sha256_final has been called.
+ *
+ * @param[in,out] ctx Hash instance.
+ * @param[out] hash Array to hold the extracted hash value (assumed to be 32 bytes long).
+ * @param[in] le Store the hash in little-endian.
+ *
+ * @retval NRF_SUCCESS If the has value was successfully extracted.
+ * @retval NRF_ERROR_NULL If a parameter was NULL.
+ */
+ret_code_t sha256_final(sha256_context_t *ctx, uint8_t * hash, uint8_t le);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // SHA256_H
+
+/** @} */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/simple_timer/app_simple_timer.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/simple_timer/app_simple_timer.c
new file mode 100644
index 0000000..f353f06
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/simple_timer/app_simple_timer.c
@@ -0,0 +1,191 @@
+/**
+ * Copyright (c) 2015 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#include "sdk_common.h"
+#if NRF_MODULE_ENABLED(SIMPLE_TIMER)
+#include "app_simple_timer.h"
+#include "nrf.h"
+#include "app_util_platform.h"
+#include "app_error.h"
+#include "nrf_timer.h"
+#include "nrf_drv_timer.h"
+
+/**@brief States of simple timer state machine.
+ */
+typedef enum
+{
+ SIMPLE_TIMER_STATE_IDLE = 0,
+ SIMPLE_TIMER_STATE_INITIALIZED,
+ SIMPLE_TIMER_STATE_STOPPED,
+ SIMPLE_TIMER_STATE_STARTED
+}simple_timer_states_t;
+
+static app_simple_timer_mode_t m_mode; /**< Registered timer mode. */
+static app_simple_timer_timeout_handler_t m_timeout_handler = NULL; /**< Registered time-out handler. */
+static void * mp_timeout_handler_context = NULL; /**< Registered time-out handler context. */
+static simple_timer_states_t m_simple_timer_state = SIMPLE_TIMER_STATE_IDLE; /**< State machine state. */
+
+const nrf_drv_timer_t SIMPLE_TIMER = NRF_DRV_TIMER_INSTANCE(SIMPLE_TIMER_CONFIG_INSTANCE);
+
+/**
+ * @brief Handler for timer events.
+ */
+static void app_simple_timer_event_handler(nrf_timer_event_t event_type, void * p_context)
+{
+ switch (event_type)
+ {
+ case NRF_TIMER_EVENT_COMPARE0:
+ if (m_mode == APP_SIMPLE_TIMER_MODE_SINGLE_SHOT)
+ {
+ m_simple_timer_state = SIMPLE_TIMER_STATE_STOPPED;
+ }
+
+ //@note: No NULL check required as performed in timer_start(...).
+ m_timeout_handler(mp_timeout_handler_context);
+ break;
+
+ default:
+ //Do nothing.
+ break;
+ }
+}
+
+uint32_t app_simple_timer_init(void)
+{
+ uint32_t err_code = NRF_SUCCESS;
+ nrf_drv_timer_config_t t_cfg = NRF_DRV_TIMER_DEFAULT_CONFIG;
+ t_cfg.mode = NRF_TIMER_MODE_TIMER;
+ t_cfg.bit_width = NRF_TIMER_BIT_WIDTH_16;
+ t_cfg.frequency = (nrf_timer_frequency_t)SIMPLE_TIMER_CONFIG_FREQUENCY;
+ err_code = nrf_drv_timer_init(&SIMPLE_TIMER, &t_cfg, app_simple_timer_event_handler);
+
+ if (NRF_SUCCESS == err_code)
+ {
+ m_simple_timer_state = SIMPLE_TIMER_STATE_INITIALIZED;
+ }
+
+ return err_code;
+}
+
+uint32_t app_simple_timer_start(app_simple_timer_mode_t mode,
+ app_simple_timer_timeout_handler_t timeout_handler,
+ uint16_t timeout_ticks,
+ void * p_context)
+{
+ uint32_t err_code = NRF_SUCCESS;
+ nrf_timer_short_mask_t timer_short;
+
+ VERIFY_PARAM_NOT_NULL(timeout_handler);
+
+ if (APP_SIMPLE_TIMER_MODE_REPEATED == mode)
+ {
+ timer_short = NRF_TIMER_SHORT_COMPARE0_CLEAR_MASK;
+ }
+ else if (APP_SIMPLE_TIMER_MODE_SINGLE_SHOT == mode)
+ {
+ timer_short = NRF_TIMER_SHORT_COMPARE0_STOP_MASK;
+ }
+ else
+ {
+ return NRF_ERROR_INVALID_PARAM;
+ }
+
+ if (SIMPLE_TIMER_STATE_IDLE == m_simple_timer_state)
+ {
+ return NRF_ERROR_INVALID_STATE;
+ }
+
+ if (SIMPLE_TIMER_STATE_STARTED == m_simple_timer_state)
+ {
+ err_code = app_simple_timer_stop();
+ APP_ERROR_CHECK(err_code);
+ }
+
+ if (SIMPLE_TIMER_STATE_STOPPED == m_simple_timer_state)
+ {
+ nrf_drv_timer_clear(&SIMPLE_TIMER);
+ }
+
+ m_mode = mode;
+ m_timeout_handler = timeout_handler;
+ mp_timeout_handler_context = p_context;
+
+ nrf_drv_timer_extended_compare(
+ &SIMPLE_TIMER, NRF_TIMER_CC_CHANNEL0, (uint32_t)timeout_ticks, timer_short, true);
+
+ if (m_simple_timer_state == SIMPLE_TIMER_STATE_STOPPED)
+ {
+ nrf_drv_timer_resume(&SIMPLE_TIMER);
+ }
+ else
+ {
+ nrf_drv_timer_enable(&SIMPLE_TIMER);
+ }
+
+
+ m_simple_timer_state = SIMPLE_TIMER_STATE_STARTED;
+
+ return NRF_SUCCESS;
+}
+
+uint32_t app_simple_timer_stop(void)
+{
+ if (SIMPLE_TIMER_STATE_STARTED == m_simple_timer_state)
+ {
+ nrf_drv_timer_pause(&SIMPLE_TIMER);
+
+ m_simple_timer_state = SIMPLE_TIMER_STATE_STOPPED;
+ }
+
+ return NRF_SUCCESS;
+}
+
+uint32_t app_simple_timer_uninit(void)
+{
+ uint32_t err_code = NRF_SUCCESS;
+
+ if (SIMPLE_TIMER_STATE_IDLE != m_simple_timer_state)
+ {
+ nrf_drv_timer_uninit(&SIMPLE_TIMER);
+ m_simple_timer_state = SIMPLE_TIMER_STATE_IDLE;
+ }
+
+ return err_code;
+}
+#endif //NRF_MODULE_ENABLED(SIMPLE_TIMER)
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/simple_timer/app_simple_timer.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/simple_timer/app_simple_timer.h
new file mode 100644
index 0000000..f67191f
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/simple_timer/app_simple_timer.h
@@ -0,0 +1,132 @@
+/**
+ * Copyright (c) 2015 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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
+ *
+ * @defgroup app_simple_timer Simple Timer
+ * @{
+ * @ingroup app_common
+ *
+ * @brief Simple timer module.
+ *
+ * Supported features and limitations:
+ * - Two modes: single shot mode and repeated mode.
+ * - No more than one timer can run simultaneously.
+ * - The timer is hard-coded to use the TIMER1 peripheral and compare channel 0.
+ */
+
+#ifndef TIMER_H__
+#define TIMER_H__
+
+#include <stdint.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**@brief Timer time-out handler type. */
+typedef void (*app_simple_timer_timeout_handler_t)(void * p_context);
+
+/**@brief Timer modes. */
+typedef enum
+{
+ APP_SIMPLE_TIMER_MODE_SINGLE_SHOT, /**< The timer will expire only once. */
+ APP_SIMPLE_TIMER_MODE_REPEATED /**< The timer will restart each time it expires. */
+} app_simple_timer_mode_t;
+
+/**@brief Function for configuring and setting up the timer hardware.
+ *
+ * @note Timer frequency is configured statically.
+ *
+ * @retval NRF_SUCCESS If the operation is successful.
+ * @retval NRF_ERROR_INVALID_STATE If the operation fails because the timer is already initialized.
+ * @retval NRF_ERROR_INVALID_PARAM If the operation fails because some configuration parameter is
+ * not valid.
+ */
+uint32_t app_simple_timer_init(void);
+
+/**@brief Function for starting a timer.
+ *
+ * @note If this function is called for a timer that is already running, the currently running
+ * timer is stopped before starting the new one.
+ *
+ * @param[in] mode Timer mode (see @ref app_simple_timer_mode_t).
+ * @param[in] timeout_handler Function to be executed when the timer expires
+ * (see @ref app_simple_timer_timeout_handler_t).
+ * @param[in] timeout_ticks Number of timer ticks to time-out event.
+ * @param[in] p_context General purpose pointer. Will be passed to the time-out handler
+ * when the timer expires.
+ *
+ * @retval NRF_SUCCESS If the operation is successful.
+ * @retval NRF_ERROR_INVALID_STATE If the operation fails because @ref app_simple_timer_init has not
+ * been called and the operation is not allowed in this state.
+ * @retval NRF_ERROR_NULL If the operation fails because timeout_handler is NULL.
+ * @retval NRF_ERROR_INVALID_PARAM If the operation fails because "mode" parameter is not valid.
+ */
+
+uint32_t app_simple_timer_start(app_simple_timer_mode_t mode,
+ app_simple_timer_timeout_handler_t timeout_handler,
+ uint16_t timeout_ticks,
+ void * p_context);
+
+/**@brief Function for stopping the timer.
+ *
+ * @retval NRF_SUCCESS If the operation is successful.
+ */
+uint32_t app_simple_timer_stop(void);
+
+/**@brief Function for uninitializing the timer. Should be called also when the timer is not used
+ * anymore to reach lowest power consumption in system.
+ *
+ * @note The function switches off the internal core of the timer to reach lowest power consumption
+ * in system. The startup time from this state may be longer compared to starting the timer
+ * from the stopped state.
+ *
+ * @retval NRF_SUCCESS If the operation is successful.
+ */
+uint32_t app_simple_timer_uninit(void);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // TIMER_H__
+
+/** @} */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/slip/slip.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/slip/slip.c
new file mode 100644
index 0000000..5e6e41b
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/slip/slip.c
@@ -0,0 +1,150 @@
+/**
+ * Copyright (c) 2015 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#include "sdk_common.h"
+#if NRF_MODULE_ENABLED(SLIP)
+#include "slip.h"
+
+#include <string.h>
+
+
+#define SLIP_BYTE_END 0300 /* indicates end of packet */
+#define SLIP_BYTE_ESC 0333 /* indicates byte stuffing */
+#define SLIP_BYTE_ESC_END 0334 /* ESC ESC_END means END data byte */
+#define SLIP_BYTE_ESC_ESC 0335 /* ESC ESC_ESC means ESC data byte */
+
+
+ret_code_t slip_encode(uint8_t * p_output, uint8_t * p_input, uint32_t input_length, uint32_t * p_output_buffer_length)
+{
+ if (p_output == NULL || p_input == NULL || p_output_buffer_length == NULL)
+ {
+ return NRF_ERROR_NULL;
+ }
+
+ *p_output_buffer_length = 0;
+ uint32_t input_index;
+
+ for (input_index = 0; input_index < input_length; input_index++)
+ {
+ switch (p_input[input_index])
+ {
+ case SLIP_BYTE_END:
+ p_output[(*p_output_buffer_length)++] = SLIP_BYTE_ESC;
+ p_output[(*p_output_buffer_length)++] = SLIP_BYTE_ESC_END;
+ break;
+
+ case SLIP_BYTE_ESC:
+ p_output[(*p_output_buffer_length)++] = SLIP_BYTE_ESC;
+ p_output[(*p_output_buffer_length)++] = SLIP_BYTE_ESC_ESC;
+ break;
+
+ default:
+ p_output[(*p_output_buffer_length)++] = p_input[input_index];
+ }
+ }
+ p_output[(*p_output_buffer_length)++] = SLIP_BYTE_END;
+
+ return NRF_SUCCESS;
+}
+
+ret_code_t slip_decode_add_byte(slip_t * p_slip, uint8_t c)
+{
+ if (p_slip == NULL)
+ {
+ return NRF_ERROR_NULL;
+ }
+
+ if (p_slip->current_index == p_slip->buffer_len)
+ {
+ return NRF_ERROR_NO_MEM;
+ }
+
+ switch (p_slip->state)
+ {
+ case SLIP_STATE_DECODING:
+ switch (c)
+ {
+ case SLIP_BYTE_END:
+ // finished reading packet
+ return NRF_SUCCESS;
+
+ case SLIP_BYTE_ESC:
+ // wait for
+ p_slip->state = SLIP_STATE_ESC_RECEIVED;
+ break;
+
+ default:
+ // add byte to buffer
+ p_slip->p_buffer[p_slip->current_index++] = c;
+ break;
+ }
+ break;
+
+ case SLIP_STATE_ESC_RECEIVED:
+ switch (c)
+ {
+ case SLIP_BYTE_ESC_END:
+ p_slip->p_buffer[p_slip->current_index++] = SLIP_BYTE_END;
+ p_slip->state = SLIP_STATE_DECODING;
+ break;
+
+ case SLIP_BYTE_ESC_ESC:
+ p_slip->p_buffer[p_slip->current_index++] = SLIP_BYTE_ESC;
+ p_slip->state = SLIP_STATE_DECODING;
+ break;
+
+ default:
+ // protocol violation
+ p_slip->state = SLIP_STATE_CLEARING_INVALID_PACKET;
+ return NRF_ERROR_INVALID_DATA;
+ }
+ break;
+
+ case SLIP_STATE_CLEARING_INVALID_PACKET:
+ if (c == SLIP_BYTE_END)
+ {
+ p_slip->state = SLIP_STATE_DECODING;
+ p_slip->current_index = 0;
+ }
+ break;
+ }
+
+ return NRF_ERROR_BUSY;
+}
+#endif //NRF_MODULE_ENABLED(SLIP)
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/slip/slip.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/slip/slip.h
new file mode 100644
index 0000000..23791c0
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/slip/slip.h
@@ -0,0 +1,117 @@
+/**
+ * Copyright (c) 2015 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#ifndef SLIP_H__
+#define SLIP_H__
+
+#include <stdint.h>
+#include "sdk_errors.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** @file
+ *
+ * @defgroup slip SLIP encoding and decoding
+ * @{
+ * @ingroup app_common
+ *
+ * @brief This module encodes and decodes SLIP packages.
+ *
+ * @details The SLIP protocol is described in @linkSLIP.
+ */
+
+/** @brief Status information that is used while receiving and decoding a packet. */
+typedef enum
+{
+ SLIP_STATE_DECODING, //!< Ready to receive the next byte.
+ SLIP_STATE_ESC_RECEIVED, //!< An ESC byte has been received and the next byte must be decoded differently.
+ SLIP_STATE_CLEARING_INVALID_PACKET //!< The received data is invalid and transfer must be restarted.
+} slip_read_state_t;
+
+ /** @brief Representation of a SLIP packet. */
+typedef struct
+{
+ slip_read_state_t state; //!< Current state of the packet (see @ref slip_read_state_t).
+
+ uint8_t * p_buffer; //!< Decoded data.
+ uint32_t current_index; //!< Current length of the packet that has been received.
+ uint32_t buffer_len; //!< Size of the buffer that is available.
+} slip_t;
+
+/**@brief Function for encoding a SLIP packet.
+ *
+ * The maximum size of the output data is (2*input size + 1) bytes. Ensure that the provided buffer is large enough.
+ *
+ * @param[in,out] p_output The buffer where the encoded SLIP packet is stored. Ensure that it is large enough.
+ * @param[in,out] p_input The buffer to be encoded.
+ * @param[in,out] input_length The length of the input buffer.
+ * @param[out] p_output_buffer_length The length of the output buffer after the input has been encoded.
+ *
+ * @retval NRF_SUCCESS If the input was successfully encoded into output.
+ * @retval NRF_ERROR_NULL If one of the provided parameters is NULL.
+ */
+ret_code_t slip_encode(uint8_t * p_output, uint8_t * p_input, uint32_t input_length, uint32_t * p_output_buffer_length);
+
+/**@brief Function for decoding a SLIP packet.
+ *
+ * The decoded packet is put into @p p_slip::p_buffer. The index and buffer state is updated.
+ *
+ * Ensure that @p p_slip is properly initialized. The initial state must be set to @ref SLIP_STATE_DECODING.
+ *
+ * @param[in,out] p_slip State of the decoding process.
+ * @param[in] c Byte to decode.
+ *
+ * @retval NRF_SUCCESS If a packet has been parsed. The received packet can be retrieved from @p p_slip.
+ * @retval NRF_ERROR_NULL If @p p_slip is NULL.
+ * @retval NRF_ERROR_NO_MEM If there is no more room in the buffer provided by @p p_slip.
+ * @retval NRF_ERROR_BUSY If the packet has not been parsed completely yet.
+ * @retval NRF_ERROR_INVALID_DATA If the packet is encoded wrong. In this case, @p p_slip::state is set to @ref SLIP_STATE_CLEARING_INVALID_PACKET,
+ * and decoding will stay in this state until the END byte is received.
+ */
+ret_code_t slip_decode_add_byte(slip_t * p_slip, uint8_t c);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // SLIP_H__
+
+/** @} */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/sortlist/nrf_sortlist.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/sortlist/nrf_sortlist.c
new file mode 100644
index 0000000..b1cdd13
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/sortlist/nrf_sortlist.c
@@ -0,0 +1,126 @@
+/**
+ * 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#include "sdk_common.h"
+#if NRF_MODULE_ENABLED(NRF_SORTLIST)
+#include "nrf_sortlist.h"
+#include "nrf_assert.h"
+
+#define NRF_LOG_MODULE_NAME sortlist
+#if NRF_SORTLIST_CONFIG_LOG_ENABLED
+ #define NRF_LOG_LEVEL NRF_SORTLIST_CONFIG_LOG_LEVEL
+ #define NRF_LOG_INFO_COLOR NRF_SORTLIST_CONFIG_INFO_COLOR
+ #define NRF_LOG_DEBUG_COLOR NRF_SORTLIST_CONFIG_DEBUG_COLOR
+#else
+ #define NRF_LOG_LEVEL 0
+#endif // NRF_SORTLIST_CONFIG_LOG_ENABLED
+#include "nrf_log.h"
+NRF_LOG_MODULE_REGISTER();
+
+void nrf_sortlist_add(nrf_sortlist_t const * p_list, nrf_sortlist_item_t * p_item)
+{
+ ASSERT(p_list);
+ ASSERT(p_item);
+
+ nrf_sortlist_item_t ** pp_curr = &(p_list->p_cb->p_head);
+
+ while(*pp_curr != NULL)
+ {
+ if(!(p_list->compare_func(*pp_curr, p_item)))
+ {
+ break;
+ }
+ pp_curr = &((*pp_curr)->p_next);
+ }
+
+ p_item->p_next = *pp_curr;
+ *pp_curr = p_item;
+
+ NRF_LOG_INFO("List:%s, adding element:%08X after:%08X, before:%08X",
+ p_list->p_name, p_item, *pp_curr, p_item->p_next);
+}
+
+nrf_sortlist_item_t * nrf_sortlist_pop(nrf_sortlist_t const * p_list)
+{
+ ASSERT(p_list);
+ nrf_sortlist_item_t * ret = p_list->p_cb->p_head;
+ if (p_list->p_cb->p_head != NULL)
+ {
+ p_list->p_cb->p_head = p_list->p_cb->p_head->p_next;
+ }
+ NRF_LOG_INFO("List:%s, poping element:%08X", p_list->p_name, ret);
+ return ret;
+}
+
+nrf_sortlist_item_t const * nrf_sortlist_peek(nrf_sortlist_t const * p_list)
+{
+ ASSERT(p_list);
+ return p_list->p_cb->p_head;
+}
+
+nrf_sortlist_item_t const * nrf_sortlist_next(nrf_sortlist_item_t const * p_item)
+{
+ ASSERT(p_item);
+ return p_item->p_next;
+}
+
+bool nrf_sortlist_remove(nrf_sortlist_t const * p_list, nrf_sortlist_item_t * p_item)
+{
+ ASSERT(p_list);
+ ASSERT(p_item);
+ bool ret = false;
+
+ nrf_sortlist_item_t ** pp_curr = &(p_list->p_cb->p_head);
+
+ while(*pp_curr != NULL)
+ {
+ if(*pp_curr == p_item)
+ {
+ *pp_curr = p_item->p_next;
+ ret = true;
+ break;
+ }
+ pp_curr = &((*pp_curr)->p_next);
+ }
+
+ NRF_LOG_INFO("List:%s, removing element:%08X %s",
+ p_list->p_name, p_item, ret ? "succeeded" : "not found");
+ return ret;
+}
+#endif //NRF_SORTLIST_ENABLED
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/sortlist/nrf_sortlist.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/sortlist/nrf_sortlist.h
new file mode 100644
index 0000000..17de64a
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/sortlist/nrf_sortlist.h
@@ -0,0 +1,179 @@
+/**
+ * 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#ifndef NRF_SORTLIST_H
+#define NRF_SORTLIST_H
+
+#include "sdk_config.h"
+#include <stdint.h>
+#include <stdbool.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+/**
+ * @defgroup nrf_sortlist Sorted list
+ * @{
+ * @ingroup app_common
+ * @brief Module for storing items in the ordered list.
+ */
+
+/**
+ * @brief Forward declaration of sorted list item.
+ */
+typedef struct nrf_sortlist_item_s nrf_sortlist_item_t;
+
+/** @brief Prototype of a function which compares two elements.
+ *
+ * @param p_item0 Item 0.
+ * @param p_item1 Item 1.
+ *
+ * @return True if Item 0 should be higher than Item 1 and false otherwise.
+ *
+ */
+typedef bool (*nrf_sortlist_compare_func_t)(nrf_sortlist_item_t * p_item0, nrf_sortlist_item_t * p_item1);
+
+/**
+ * @brief A structure for item in the sorted list.
+ */
+struct nrf_sortlist_item_s
+{
+ nrf_sortlist_item_t * p_next; /* Pointer to the next item in the list. */
+};
+
+/**
+ * @brief Sorted list instance control block.
+ *
+ * Control block contains instance data which must be located in read/write memory.
+ */
+typedef struct
+{
+ nrf_sortlist_item_t * p_head; /* List head.*/
+} nrf_sortlist_cb_t;
+/**
+ * @brief Structure for sorted list instance.
+ *
+ * Instance can be placed in read only memory.
+ */
+typedef struct
+{
+ char * p_name; /* List name. */
+ nrf_sortlist_cb_t * p_cb; /* List head.*/
+ nrf_sortlist_compare_func_t compare_func; /* Function used for comparison. */
+} nrf_sortlist_t;
+
+/**
+ * @brief Macro for conditionally including instance name.
+ *
+ * @param _name Instance name.
+ */
+#define NRF_SORTLIST_INST_NAME(_name) (NRF_LOG_ENABLED && NRF_SORTLIST_CONFIG_LOG_ENABLED) ? \
+ STRINGIFY(_name) : NULL
+/**
+ * @brief Macro for defining a sorted list instance.
+ *
+ * @param _name Instance name.
+ * @param _compare_func Pointer to a compare function.
+ */
+#define NRF_SORTLIST_DEF(_name, _compare_func) \
+ static nrf_sortlist_cb_t CONCAT_2(_name,_sortlist_cb) = { \
+ .p_head = NULL \
+ }; \
+ static const nrf_sortlist_t _name = { \
+ .p_name = NRF_SORTLIST_INST_NAME(_name), \
+ .p_cb = &CONCAT_2(_name,_sortlist_cb), \
+ .compare_func = _compare_func, \
+ }
+
+/**
+ * @brief Function for adding an element into a list.
+ *
+ * New item will be placed in the queue based on the compare function.
+ *
+ * @param p_list List instance.
+ * @param p_item Item.
+ */
+void nrf_sortlist_add(nrf_sortlist_t const * p_list, nrf_sortlist_item_t * p_item);
+
+/**
+ * @brief Function for removing an item from the list head.
+ *
+ * @param p_list List instance.
+ *
+ * @return Pointer to the item which was on the list head.
+ */
+nrf_sortlist_item_t * nrf_sortlist_pop(nrf_sortlist_t const * p_list);
+
+/**
+ * @brief Function for getting (without removing) an item from the list head.
+ *
+ * @param p_list List instance.
+ *
+ * @return Pointer to the item which is on the list head.
+ */
+nrf_sortlist_item_t const * nrf_sortlist_peek(nrf_sortlist_t const * p_list);
+
+/**
+ * @brief Function for iterating over the list.
+ *
+ * @param p_item Item in the list.
+ *
+ * @return Pointer to the next item in the list.
+ */
+nrf_sortlist_item_t const * nrf_sortlist_next(nrf_sortlist_item_t const * p_item);
+
+/**
+ * @brief Function for removing an item from the queue.
+ *
+ * @param p_list List instance.
+ * @param p_item Item.
+ *
+ * @retval true Item was found and removed.
+ * @retval false Item not found in the list.
+ */
+bool nrf_sortlist_remove(nrf_sortlist_t const * p_list, nrf_sortlist_item_t * p_item);
+
+/** @} */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif //NRF_SORTLIST_H
+
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/spi_mngr/nrf_spi_mngr.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/spi_mngr/nrf_spi_mngr.c
new file mode 100644
index 0000000..b66dfbb
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/spi_mngr/nrf_spi_mngr.c
@@ -0,0 +1,348 @@
+/**
+ * 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#include "sdk_common.h"
+
+#if NRF_MODULE_ENABLED(NRF_SPI_MNGR)
+#include "nrf_spi_mngr.h"
+#include "nrf_assert.h"
+#include "app_util_platform.h"
+
+typedef volatile struct
+{
+ bool transaction_in_progress;
+ uint8_t transaction_result;
+} nrf_spi_mngr_cb_data_t;
+
+static ret_code_t start_transfer(nrf_spi_mngr_t const * p_nrf_spi_mngr)
+{
+ ASSERT(p_nrf_spi_mngr != NULL);
+
+ // use a local variable to avoid using two volatile variables in one
+ // expression
+ uint8_t curr_transfer_idx = p_nrf_spi_mngr->p_nrf_spi_mngr_cb->current_transfer_idx;
+ nrf_spi_mngr_transfer_t const * p_transfer =
+ &p_nrf_spi_mngr->p_nrf_spi_mngr_cb->p_current_transaction->p_transfers[curr_transfer_idx];
+
+ return nrf_drv_spi_transfer(&p_nrf_spi_mngr->spi,
+ p_transfer->p_tx_data, p_transfer->tx_length,
+ p_transfer->p_rx_data, p_transfer->rx_length);
+}
+
+
+static void transaction_begin_signal(nrf_spi_mngr_t const * p_nrf_spi_mngr)
+{
+ ASSERT(p_nrf_spi_mngr != NULL);
+
+ nrf_spi_mngr_transaction_t const * p_current_transaction =
+ p_nrf_spi_mngr->p_nrf_spi_mngr_cb->p_current_transaction;
+
+
+ if (p_current_transaction->begin_callback != NULL)
+ {
+ void * p_user_data = p_current_transaction->p_user_data;
+ p_current_transaction->begin_callback(p_user_data);
+ }
+}
+
+
+static void transaction_end_signal(nrf_spi_mngr_t const * p_nrf_spi_mngr,
+ ret_code_t result)
+{
+ ASSERT(p_nrf_spi_mngr != NULL);
+
+ nrf_spi_mngr_transaction_t const * p_current_transaction =
+ p_nrf_spi_mngr->p_nrf_spi_mngr_cb->p_current_transaction;
+
+ if (p_current_transaction->end_callback != NULL)
+ {
+ void * p_user_data = p_current_transaction->p_user_data;
+ p_current_transaction->end_callback(result, p_user_data);
+ }
+}
+
+
+static void spi_event_handler(nrf_drv_spi_evt_t const * p_event,
+ void * p_context);
+
+
+// This function starts pending transaction if there is no current one or
+// when 'switch_transaction' parameter is set to true. It is important to
+// switch to new transaction without setting 'p_nrf_spi_mngr->p_curr_transaction'
+// to NULL in between, since this pointer is used to check idle status - see
+// 'nrf_spi_mngr_is_idle()'.
+static void start_pending_transaction(nrf_spi_mngr_t const * p_nrf_spi_mngr,
+ bool switch_transaction)
+{
+ ASSERT(p_nrf_spi_mngr != NULL);
+
+ while (1)
+ {
+ bool start_transaction = false;
+ nrf_spi_mngr_cb_t * p_cb = p_nrf_spi_mngr->p_nrf_spi_mngr_cb;
+
+ CRITICAL_REGION_ENTER();
+ if (switch_transaction || nrf_spi_mngr_is_idle(p_nrf_spi_mngr))
+ {
+ if (nrf_queue_pop(p_nrf_spi_mngr->p_queue,
+ (void *)(&p_cb->p_current_transaction))
+ == NRF_SUCCESS)
+ {
+ start_transaction = true;
+ }
+ else
+ {
+ p_cb->p_current_transaction = NULL;
+ }
+ }
+ CRITICAL_REGION_EXIT();
+
+ if (!start_transaction)
+ {
+ return;
+ }
+
+ nrf_drv_spi_config_t const * p_instance_cfg;
+ if (p_cb->p_current_transaction->p_required_spi_cfg == NULL)
+ {
+ p_instance_cfg = &p_cb->default_configuration;
+ }
+ else
+ {
+ p_instance_cfg = p_cb->p_current_transaction->p_required_spi_cfg;
+ }
+
+ ret_code_t result;
+
+ if (memcmp(p_cb->p_current_configuration, p_instance_cfg, sizeof(*p_instance_cfg)) != 0)
+ {
+ nrf_drv_spi_uninit(&p_nrf_spi_mngr->spi);
+ result = nrf_drv_spi_init(&p_nrf_spi_mngr->spi,
+ p_instance_cfg,
+ spi_event_handler,
+ (void *)p_nrf_spi_mngr);
+ ASSERT(result == NRF_SUCCESS);
+ p_cb->p_current_configuration = p_instance_cfg;
+ }
+
+ // Try to start first transfer for this new transaction.
+ p_cb->current_transfer_idx = 0;
+
+ // Execute user code if available before starting transaction
+ transaction_begin_signal(p_nrf_spi_mngr);
+ result = start_transfer(p_nrf_spi_mngr);
+
+ // If transaction started successfully there is nothing more to do here now.
+ if (result == NRF_SUCCESS)
+ {
+ return;
+ }
+
+ // Transfer failed to start - notify user that this transaction
+ // cannot be started and try with next one (in next iteration of
+ // the loop).
+ transaction_end_signal(p_nrf_spi_mngr, result);
+
+ switch_transaction = true;
+ }
+}
+
+
+// This function shall be called to handle SPI events. It shall be mainly used by SPI IRQ for
+// finished tranfer.
+static void spi_event_handler(nrf_drv_spi_evt_t const * p_event,
+ void * p_context)
+{
+ ASSERT(p_event != NULL);
+ ASSERT(p_context != NULL);
+
+ ret_code_t result;
+ nrf_spi_mngr_cb_t * p_cb = ((nrf_spi_mngr_t const *)p_context)->p_nrf_spi_mngr_cb;
+
+ // This callback should be called only during transaction.
+ ASSERT(p_cb->p_current_transaction != NULL);
+
+ if (p_event->type == NRF_DRV_SPI_EVENT_DONE)
+ {
+ result = NRF_SUCCESS;
+
+ // Transfer finished successfully. If there is another one to be
+ // performed in the current transaction, start it now.
+ // use a local variable to avoid using two volatile variables in one
+ // expression
+ uint8_t curr_transfer_idx = p_cb->current_transfer_idx;
+ ++curr_transfer_idx;
+ if (curr_transfer_idx < p_cb->p_current_transaction->number_of_transfers)
+ {
+ p_cb->current_transfer_idx = curr_transfer_idx;
+
+ result = start_transfer(((nrf_spi_mngr_t const *)p_context));
+
+ if (result == NRF_SUCCESS)
+ {
+ // The current transaction is running and its next transfer
+ // has been successfully started. There is nothing more to do.
+ return;
+ }
+ // if the next transfer could not be started due to some error
+ // we finish the transaction with this error code as the result
+ }
+ }
+ else
+ {
+ result = NRF_ERROR_INTERNAL;
+ }
+
+ // The current transaction has been completed or interrupted by some error.
+ // Notify the user and start next one (if there is any).
+ transaction_end_signal(((nrf_spi_mngr_t const *)p_context), result);
+ // we switch transactions here ('p_nrf_spi_mngr->p_current_transaction' is set
+ // to NULL only if there is nothing more to do) in order to not generate
+ // spurious idle status (even for a moment)
+ start_pending_transaction(((nrf_spi_mngr_t const *)p_context), true);
+}
+
+
+ret_code_t nrf_spi_mngr_init(nrf_spi_mngr_t const * p_nrf_spi_mngr,
+ nrf_drv_spi_config_t const * p_default_spi_config)
+{
+ ASSERT(p_nrf_spi_mngr != NULL);
+ ASSERT(p_nrf_spi_mngr->p_queue != NULL);
+ ASSERT(p_nrf_spi_mngr->p_queue->size > 0);
+ ASSERT(p_default_spi_config != NULL);
+
+ ret_code_t err_code;
+
+ err_code = nrf_drv_spi_init(&p_nrf_spi_mngr->spi,
+ p_default_spi_config,
+ spi_event_handler,
+ (void *)p_nrf_spi_mngr);
+
+ if (err_code == NRF_SUCCESS)
+ {
+ nrf_spi_mngr_cb_t * p_cb = p_nrf_spi_mngr->p_nrf_spi_mngr_cb;
+
+ p_cb->p_current_transaction = NULL;
+ p_cb->default_configuration = *p_default_spi_config;
+ p_cb->p_current_configuration = &p_cb->default_configuration;
+ }
+
+ return err_code;
+}
+
+
+void nrf_spi_mngr_uninit(nrf_spi_mngr_t const * p_nrf_spi_mngr)
+{
+ ASSERT(p_nrf_spi_mngr != NULL);
+
+ nrf_drv_spi_uninit(&p_nrf_spi_mngr->spi);
+
+ p_nrf_spi_mngr->p_nrf_spi_mngr_cb->p_current_transaction = NULL;
+}
+
+
+ret_code_t nrf_spi_mngr_schedule(nrf_spi_mngr_t const * p_nrf_spi_mngr,
+ nrf_spi_mngr_transaction_t const * p_transaction)
+{
+ ASSERT(p_nrf_spi_mngr != NULL);
+ ASSERT(p_transaction != NULL);
+ ASSERT(p_transaction->p_transfers != NULL);
+ ASSERT(p_transaction->number_of_transfers != 0);
+
+ ret_code_t result = nrf_queue_push(p_nrf_spi_mngr->p_queue, (void *)(&p_transaction));
+ if (result == NRF_SUCCESS)
+ {
+ // New transaction has been successfully added to queue,
+ // so if we are currently idle it's time to start the job.
+ start_pending_transaction(p_nrf_spi_mngr, false);
+ }
+
+ return result;
+}
+
+
+static void spi_internal_transaction_cb(ret_code_t result, void * p_user_data)
+{
+ nrf_spi_mngr_cb_data_t * p_cb_data = (nrf_spi_mngr_cb_data_t *)p_user_data;
+
+ p_cb_data->transaction_result = result;
+ p_cb_data->transaction_in_progress = false;
+}
+
+ret_code_t nrf_spi_mngr_perform(nrf_spi_mngr_t const * p_nrf_spi_mngr,
+ nrf_drv_spi_config_t const * p_config,
+ nrf_spi_mngr_transfer_t const * p_transfers,
+ uint8_t number_of_transfers,
+ void (* user_function)(void))
+{
+ ASSERT(p_nrf_spi_mngr != NULL);
+ ASSERT(p_transfers != NULL);
+ ASSERT(number_of_transfers != 0);
+
+ nrf_spi_mngr_cb_data_t cb_data =
+ {
+ .transaction_in_progress = true
+ };
+
+ nrf_spi_mngr_transaction_t internal_transaction =
+ {
+ .begin_callback = NULL,
+ .end_callback = spi_internal_transaction_cb,
+ .p_user_data = (void *)&cb_data,
+ .p_transfers = p_transfers,
+ .number_of_transfers = number_of_transfers,
+ .p_required_spi_cfg = p_config
+ };
+
+ ret_code_t result = nrf_spi_mngr_schedule(p_nrf_spi_mngr, &internal_transaction);
+ VERIFY_SUCCESS(result);
+
+ while (cb_data.transaction_in_progress)
+ {
+ if (user_function)
+ {
+ user_function();
+ }
+ }
+
+ return cb_data.transaction_result;
+}
+
+#endif //NRF_MODULE_ENABLED(NRF_SPI_MNGR)
+
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/spi_mngr/nrf_spi_mngr.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/spi_mngr/nrf_spi_mngr.h
new file mode 100644
index 0000000..434c950
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/spi_mngr/nrf_spi_mngr.h
@@ -0,0 +1,310 @@
+/**
+ * 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#ifndef NRF_SPI_MNGR_H__
+#define NRF_SPI_MNGR_H__
+
+#include <stdint.h>
+#include "nrf_drv_spi.h"
+#include "sdk_errors.h"
+#include "nrf_queue.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*lint -save -e491*/
+#ifndef NRF_SPI_MNGR_BUFFERS_IN_RAM
+ #define NRF_SPI_MNGR_BUFFERS_IN_RAM defined(SPIM_PRESENT)
+#endif
+
+#if NRF_SPI_MNGR_BUFFERS_IN_RAM
+ #define NRF_SPI_MNGR_BUFFER_LOC_IND
+#else
+ #define NRF_SPI_MNGR_BUFFER_LOC_IND const
+#endif
+/*lint -restore*/
+
+/**
+ * @defgroup nrf_spi_mngr SPI transaction manager
+ * @{
+ * @ingroup app_common
+ *
+ * @brief Module for scheduling SPI transactions.
+ */
+
+
+/**
+ * @brief Macro for creating a simple SPI transfer.
+ *
+ * @param[in] _p_tx_data Pointer to the data to be sent.
+ * @param[in] _tx_length Number of bytes to send.
+ * @param[in] _p_rx_data Pointer to a buffer for received data.
+ * @param[in] _rx_length Number of bytes to receive.
+ */
+#define NRF_SPI_MNGR_TRANSFER(_p_tx_data, _tx_length, _p_rx_data, _rx_length) \
+{ \
+ .p_tx_data = (uint8_t const *)_p_tx_data, \
+ .tx_length = (uint8_t) _tx_length, \
+ .p_rx_data = (uint8_t *) _p_rx_data, \
+ .rx_length = (uint8_t) _rx_length, \
+}
+
+
+/**
+ * @brief SPI transaction end callback prototype.
+ *
+ * @param result Result of operation (NRF_SUCCESS on success,
+ * otherwise a relevant error code).
+ * @param[in] p_user_data Pointer to user data defined in transaction
+ * descriptor.
+ */
+typedef void (* nrf_spi_mngr_callback_end_t)(ret_code_t result, void * p_user_data);
+
+/**
+ * @brief SPI transaction begin callback prototype.
+ *
+ * @param[in] p_user_data Pointer to user data defined in transaction
+ * descriptor.
+ */
+typedef void (* nrf_spi_mngr_callback_begin_t)(void * p_user_data);
+
+
+/**
+ * @brief SPI transfer descriptor.
+ */
+typedef struct
+{
+ uint8_t const * p_tx_data; ///< Pointer to the data to be sent.
+ uint8_t tx_length; ///< Number of bytes to send.
+ uint8_t * p_rx_data; ///< Pointer to a buffer for received data.
+ uint8_t rx_length; ///< Number of bytes to receive.
+} nrf_spi_mngr_transfer_t;
+
+
+/**
+ * @brief SPI transaction descriptor.
+ */
+typedef struct
+{
+ nrf_spi_mngr_callback_begin_t begin_callback;
+ ///< User-specified function to be called before the transaction is started.
+
+ nrf_spi_mngr_callback_end_t end_callback;
+ ///< User-specified function to be called after the transaction is finished.
+
+ void * p_user_data;
+ ///< Pointer to user data to be passed to the end_callback.
+
+ nrf_spi_mngr_transfer_t const * p_transfers;
+ ///< Pointer to the array of transfers that make up the transaction.
+
+ uint8_t number_of_transfers;
+ ///< Number of transfers that make up the transaction.
+
+ nrf_drv_spi_config_t const * p_required_spi_cfg;
+ ///< Pointer to instance hardware configuration.
+} nrf_spi_mngr_transaction_t;
+
+
+/**
+ * @brief SPI instance control block.
+ */
+typedef struct
+{
+ nrf_spi_mngr_transaction_t const * volatile p_current_transaction;
+ ///< Currently realized transaction.
+
+ nrf_drv_spi_config_t default_configuration;
+ ///< Default hardware configuration.
+
+ nrf_drv_spi_config_t const * p_current_configuration;
+ ///< Pointer to current hardware configuration.
+
+ uint8_t volatile current_transfer_idx;
+ ///< Index of currently performed transfer (within current transaction).
+} nrf_spi_mngr_cb_t;
+
+
+/**
+ * @brief SPI transaction manager instance.
+ */
+typedef struct
+{
+ nrf_spi_mngr_cb_t * p_nrf_spi_mngr_cb;
+ ///< Control block of instance.
+
+ nrf_queue_t const * p_queue;
+ ///< Transaction queue.
+
+ nrf_drv_spi_t spi;
+ ///< Pointer to SPI master driver instance.
+} nrf_spi_mngr_t;
+
+
+/**
+ * @brief Macro for simplifying the defining of an SPI transaction manager
+ * instance.
+ *
+ * This macro allocates a static buffer for the transaction queue.
+ * Therefore, it should be used in only one place in the code for a given
+ * instance.
+ *
+ * @note The queue size is the maximum number of pending transactions
+ * not counting the one that is currently realized. This means that
+ * for an empty queue with size of for example 4 elements, it is
+ * possible to schedule up to 5 transactions.
+ *
+ * @param[in] _nrf_spi_mngr_name Name of instance to be created.
+ * @param[in] _queue_size Size of the transaction queue (maximum number
+ * of pending transactions).
+ * @param[in] _spi_idx Index of hardware SPI instance to be used.
+ */
+#define NRF_SPI_MNGR_DEF(_nrf_spi_mngr_name, _queue_size, _spi_idx) \
+ NRF_QUEUE_DEF(nrf_spi_mngr_transaction_t const *, \
+ _nrf_spi_mngr_name##_queue, \
+ (_queue_size), \
+ NRF_QUEUE_MODE_NO_OVERFLOW); \
+ static nrf_spi_mngr_cb_t CONCAT_2(_nrf_spi_mngr_name, _cb); \
+ static const nrf_spi_mngr_t _nrf_spi_mngr_name = \
+ { \
+ .p_nrf_spi_mngr_cb = &CONCAT_2(_nrf_spi_mngr_name, _cb), \
+ .p_queue = &_nrf_spi_mngr_name##_queue, \
+ .spi = NRF_DRV_SPI_INSTANCE(_spi_idx) \
+ }
+
+
+ /**
+ * @brief Function for initializing an SPI transaction manager instance.
+ *
+ * @param[in] p_nrf_spi_mngr Pointer to the instance to be initialized.
+ * @param[in] p_default_spi_config Pointer to the SPI driver configuration. This configuration
+ * will be used whenever the scheduled transaction will have
+ * p_spi_config set to NULL value.
+ *
+ * @return Values returned by the @ref nrf_drv_spi_init function.
+ */
+ret_code_t nrf_spi_mngr_init(nrf_spi_mngr_t const * p_nrf_spi_mngr,
+ nrf_drv_spi_config_t const * p_default_spi_config);
+
+
+/**
+ * @brief Function for uninitializing an SPI transaction manager instance.
+ *
+ * @param[in] p_nrf_spi_mngr Pointer to the instance to be uninitialized.
+ */
+void nrf_spi_mngr_uninit(nrf_spi_mngr_t const * p_nrf_spi_mngr);
+
+
+/**
+ * @brief Function for scheduling an SPI transaction.
+ *
+ * The transaction is enqueued and started as soon as the SPI bus is
+ * available, thus when all previously scheduled transactions have been
+ * finished (possibly immediately).
+ *
+ * @note If @ref nrf_spi_mngr_transaction_t::p_required_spi_cfg
+ * is set to a non-NULL value the module will compare it with
+ * @ref nrf_spi_mngr_cb_t::p_current_configuration and reinitialize hardware
+ * SPI instance with new parameters if any differences are found.
+ * If @ref nrf_spi_mngr_transaction_t::p_required_spi_cfg is set to NULL then
+ * it will treat it as it would be set to @ref nrf_spi_mngr_cb_t::default_configuration.
+ *
+ * @param[in] p_nrf_spi_mngr Pointer to the SPI transaction manager instance.
+ * @param[in] p_transaction Pointer to the descriptor of the transaction to be
+ * scheduled.
+ *
+ * @retval NRF_SUCCESS If the transaction has been successfully scheduled.
+ * @retval NRF_ERROR_NO_MEM If the queue is full (Only if queue in
+ * @ref NRF_QUEUE_MODE_NO_OVERFLOW).
+ */
+ret_code_t nrf_spi_mngr_schedule(nrf_spi_mngr_t const * p_nrf_spi_mngr,
+ nrf_spi_mngr_transaction_t const * p_transaction);
+
+
+/**
+ * @brief Function for scheduling a transaction and waiting until it is finished.
+ *
+ * This function schedules a transaction that consists of one or more transfers
+ * and waits until it is finished.
+ *
+ * @param[in] p_nrf_spi_mngr Pointer to the SPI transaction manager instance.
+ * @param[in] p_config Required SPI configuration.
+ * @param[in] p_transfers Pointer to an array of transfers to be performed.
+ * @param number_of_transfers Number of transfers to be performed.
+ * @param user_function User-specified function to be called while
+ * waiting. NULL if such functionality
+ * is not needed.
+ *
+ * @retval NRF_SUCCESS If the transfers have been successfully realized.
+ * @retval NRF_ERROR_BUSY If some transfers are already being performed.
+ * @retval - Other error codes mean that the transaction has failed
+ * with the error reported by @ref nrf_drv_spi_transfer().
+ */
+ret_code_t nrf_spi_mngr_perform(nrf_spi_mngr_t const * p_nrf_spi_mngr,
+ nrf_drv_spi_config_t const * p_config,
+ nrf_spi_mngr_transfer_t const * p_transfers,
+ uint8_t number_of_transfers,
+ void (* user_function)(void));
+
+
+/**
+ * @brief Function for getting the current state of an SPI transaction manager
+ * instance.
+ *
+ * @param[in] p_nrf_spi_mngr Pointer to the SPI transaction manager instance.
+ *
+ * @retval true If all scheduled transactions have been finished.
+ * @retval false Otherwise.
+ */
+__STATIC_INLINE bool nrf_spi_mngr_is_idle(nrf_spi_mngr_t const * p_nrf_spi_mngr)
+{
+ return (p_nrf_spi_mngr->p_nrf_spi_mngr_cb->p_current_transaction == NULL);
+}
+
+/**
+ *@}
+ **/
+//typedef int p_current_transaction;
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // NRF_SPI_MNGR_H__
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/stack_info/nrf_stack_info.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/stack_info/nrf_stack_info.h
new file mode 100644
index 0000000..cf7902a
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/stack_info/nrf_stack_info.h
@@ -0,0 +1,163 @@
+/**
+ * Copyright (c) 2018 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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
+ *
+ * @defgroup nrf_stack_info Stack info functions and definitions
+ * @{
+ * @ingroup app_common
+ *
+ * @brief Functions and definitions used to obtain information about the state of the stack.
+ */
+
+#ifndef NRF_STACK_INFO_H__
+#define NRF_STACK_INFO_H__
+
+#include <stddef.h>
+#include <stdbool.h>
+#include "compiler_abstraction.h"
+#include "app_util.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+/**
+ * @brief Top (highest) stack address.
+ */
+#define NRF_STACK_INFO_TOP ((uint32_t)STACK_TOP)
+
+
+/**
+ * @brief Base (lowest) stack address.
+ */
+#define NRF_STACK_INFO_BASE ((uint32_t)STACK_BASE)
+
+
+/**
+ * @brief Function to get the current stack pointer value.
+ *
+ * @return Current stack pointer value.
+ */
+#define NRF_STACK_INFO_GET_SP() ((uint32_t)GET_SP())
+
+
+__STATIC_INLINE size_t nrf_stack_info_get_available(void);
+__STATIC_INLINE size_t nrf_stack_info_get_depth(void);
+__STATIC_INLINE bool nrf_stack_info_overflowed(void);
+__STATIC_INLINE bool nrf_stack_info_is_on_stack(void const * const p_address);
+
+
+#ifndef SUPPRESS_INLINE_IMPLEMENTATION
+
+/**
+ * @brief Calculate the available (free) space on the stack.
+ *
+ * @return Number of available bytes on the stack.
+ */
+ __STATIC_INLINE size_t nrf_stack_info_get_available(void)
+{
+ uint32_t sp = NRF_STACK_INFO_GET_SP();
+ if (sp > NRF_STACK_INFO_BASE)
+ {
+ return (size_t)(sp - NRF_STACK_INFO_BASE);
+ }
+
+ // Stack overflow
+ return 0;
+}
+
+
+/**
+ * @brief Calculate the current stack depth (occupied space).
+ *
+ * @return Current stack depth in bytes.
+ */
+__STATIC_INLINE size_t nrf_stack_info_get_depth(void)
+{
+ return (size_t)(NRF_STACK_INFO_TOP - NRF_STACK_INFO_GET_SP());
+}
+
+
+/**
+ * @brief Function for checking if the stack is currently overflowed.
+ *
+ * @details This function checks if the stack is currently in an overflowed by comparing the stack
+ * pointer with the stack base address. Intended to be used to be used to ease debugging.
+ *
+ * @return true if stack is currently overflowed, false otherwise.
+ */
+ __STATIC_INLINE bool nrf_stack_info_overflowed(void)
+ {
+ if (NRF_STACK_INFO_GET_SP() < NRF_STACK_INFO_BASE)
+ {
+ return true;
+ }
+
+ return false;
+ }
+
+
+/**
+ * @brief Function for checking if provided address is located in stack space.
+ *
+ * @param[in] p_address Address to be checked.
+ *
+ * @return true if address is in stack space, false otherwise.
+ */
+__STATIC_INLINE bool nrf_stack_info_is_on_stack(void const * const p_address)
+{
+ if (((uint32_t)p_address >= NRF_STACK_INFO_BASE) && ((uint32_t)p_address < NRF_STACK_INFO_TOP))
+ {
+ return true;
+ }
+
+ return false;
+}
+
+#endif // SUPPRESS_INLINE_IMPLEMENTATION
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // NRF_STACK_INFO_H__
+
+/**@} */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/strerror/nrf_strerror.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/strerror/nrf_strerror.c
new file mode 100644
index 0000000..4824b6b
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/strerror/nrf_strerror.c
@@ -0,0 +1,161 @@
+/**
+ * Copyright (c) 2011 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+
+#include "sdk_common.h"
+#if NRF_MODULE_ENABLED(NRF_STRERROR)
+#include "nrf_strerror.h"
+
+/**
+ * @brief Macro for adding an entity to the description array.
+ *
+ * Macro that helps to create a single entity in the description array.
+ */
+#define NRF_STRERROR_ENTITY(mnemonic) {.code = mnemonic, .name = #mnemonic}
+
+/**
+ * @brief Array entity element that describes an error.
+ */
+typedef struct
+{
+ ret_code_t code; /**< Error code. */
+ char const * name; /**< Descriptive name (the same as the internal error mnemonic). */
+}nrf_strerror_desc_t;
+
+/**
+ * @brief Unknown error code.
+ *
+ * The constant string used by @ref nrf_strerror_get when the error description was not found.
+ */
+static char const m_unknown_str[] = "Unknown error code";
+
+/**
+ * @brief Array with error codes.
+ *
+ * Array that describes error codes.
+ *
+ * @note It is required for this array to have error codes placed in ascending order.
+ * This condition is checked in automatic unit test before the release.
+ */
+static nrf_strerror_desc_t const nrf_strerror_array[] =
+{
+ NRF_STRERROR_ENTITY(NRF_SUCCESS),
+ NRF_STRERROR_ENTITY(NRF_ERROR_SVC_HANDLER_MISSING),
+ NRF_STRERROR_ENTITY(NRF_ERROR_SOFTDEVICE_NOT_ENABLED),
+ NRF_STRERROR_ENTITY(NRF_ERROR_INTERNAL),
+ NRF_STRERROR_ENTITY(NRF_ERROR_NO_MEM),
+ NRF_STRERROR_ENTITY(NRF_ERROR_NOT_FOUND),
+ NRF_STRERROR_ENTITY(NRF_ERROR_NOT_SUPPORTED),
+ NRF_STRERROR_ENTITY(NRF_ERROR_INVALID_PARAM),
+ NRF_STRERROR_ENTITY(NRF_ERROR_INVALID_STATE),
+ NRF_STRERROR_ENTITY(NRF_ERROR_INVALID_LENGTH),
+ NRF_STRERROR_ENTITY(NRF_ERROR_INVALID_FLAGS),
+ NRF_STRERROR_ENTITY(NRF_ERROR_INVALID_DATA),
+ NRF_STRERROR_ENTITY(NRF_ERROR_DATA_SIZE),
+ NRF_STRERROR_ENTITY(NRF_ERROR_TIMEOUT),
+ NRF_STRERROR_ENTITY(NRF_ERROR_NULL),
+ NRF_STRERROR_ENTITY(NRF_ERROR_FORBIDDEN),
+ NRF_STRERROR_ENTITY(NRF_ERROR_INVALID_ADDR),
+ NRF_STRERROR_ENTITY(NRF_ERROR_BUSY),
+#ifdef NRF_ERROR_CONN_COUNT
+ NRF_STRERROR_ENTITY(NRF_ERROR_CONN_COUNT),
+#endif
+#ifdef NRF_ERROR_RESOURCES
+ NRF_STRERROR_ENTITY(NRF_ERROR_RESOURCES),
+#endif
+
+ /* SDK Common errors */
+ NRF_STRERROR_ENTITY(NRF_ERROR_MODULE_NOT_INITIALIZED),
+ NRF_STRERROR_ENTITY(NRF_ERROR_MUTEX_INIT_FAILED),
+ NRF_STRERROR_ENTITY(NRF_ERROR_MUTEX_LOCK_FAILED),
+ NRF_STRERROR_ENTITY(NRF_ERROR_MUTEX_UNLOCK_FAILED),
+ NRF_STRERROR_ENTITY(NRF_ERROR_MUTEX_COND_INIT_FAILED),
+ NRF_STRERROR_ENTITY(NRF_ERROR_MODULE_ALREADY_INITIALIZED),
+ NRF_STRERROR_ENTITY(NRF_ERROR_STORAGE_FULL),
+ NRF_STRERROR_ENTITY(NRF_ERROR_API_NOT_IMPLEMENTED),
+ NRF_STRERROR_ENTITY(NRF_ERROR_FEATURE_NOT_ENABLED),
+ NRF_STRERROR_ENTITY(NRF_ERROR_IO_PENDING),
+
+ /* TWI error codes */
+ NRF_STRERROR_ENTITY(NRF_ERROR_DRV_TWI_ERR_OVERRUN),
+ NRF_STRERROR_ENTITY(NRF_ERROR_DRV_TWI_ERR_ANACK),
+ NRF_STRERROR_ENTITY(NRF_ERROR_DRV_TWI_ERR_DNACK),
+
+ /* IPSP error codes */
+ NRF_STRERROR_ENTITY(NRF_ERROR_BLE_IPSP_RX_PKT_TRUNCATED),
+ NRF_STRERROR_ENTITY(NRF_ERROR_BLE_IPSP_CHANNEL_ALREADY_EXISTS),
+ NRF_STRERROR_ENTITY(NRF_ERROR_BLE_IPSP_LINK_DISCONNECTED),
+ NRF_STRERROR_ENTITY(NRF_ERROR_BLE_IPSP_PEER_REJECTED)
+};
+
+
+char const * nrf_strerror_get(ret_code_t code)
+{
+ char const * p_ret = nrf_strerror_find(code);
+ return (p_ret == NULL) ? m_unknown_str : p_ret;
+}
+
+char const * nrf_strerror_find(ret_code_t code)
+{
+ nrf_strerror_desc_t const * p_start;
+ nrf_strerror_desc_t const * p_end;
+ p_start = nrf_strerror_array;
+ p_end = nrf_strerror_array + ARRAY_SIZE(nrf_strerror_array);
+
+ while (p_start < p_end)
+ {
+ nrf_strerror_desc_t const * p_mid = p_start + ((p_end - p_start) / 2);
+ ret_code_t mid_c = p_mid->code;
+ if (mid_c > code)
+ {
+ p_end = p_mid;
+ }
+ else if (mid_c < code)
+ {
+ p_start = p_mid + 1;
+ }
+ else
+ {
+ return p_mid->name;
+ }
+ }
+ return NULL;
+}
+
+#endif /* NRF_STRERROR enabled */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/strerror/nrf_strerror.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/strerror/nrf_strerror.h
new file mode 100644
index 0000000..1a6542b
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/strerror/nrf_strerror.h
@@ -0,0 +1,89 @@
+/**
+ * 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+
+/**
+ * @defgroup nrf_strerror Error code to string converter
+ * @ingroup app_common
+ *
+ * @brief Module for converting error code into a printable string.
+ * @{
+ */
+#ifndef NRF_STRERROR_H__
+#define NRF_STRERROR_H__
+
+#include "sdk_errors.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @brief Function for getting a printable error string.
+ *
+ * @param code Error code to convert.
+ *
+ * @note This function cannot fail.
+ * For the function that may fail with error translation, see @ref nrf_strerror_find.
+ *
+ * @return Pointer to the printable string.
+ * If the string is not found,
+ * it returns a simple string that says that the error is unknown.
+ */
+char const * nrf_strerror_get(ret_code_t code);
+
+/**
+ * @brief Function for finding a printable error string.
+ *
+ * This function gets the error string in the same way as @ref nrf_strerror_get,
+ * but if the string is not found, it returns NULL.
+ *
+ * @param code Error code to convert.
+ * @return Pointer to the printable string.
+ * If the string is not found, NULL is returned.
+ */
+char const * nrf_strerror_find(ret_code_t code);
+
+/** @} */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* NRF_STRERROR_H__ */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/svc/nrf_svc_function.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/svc/nrf_svc_function.h
new file mode 100644
index 0000000..df03b4d
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/svc/nrf_svc_function.h
@@ -0,0 +1,146 @@
+/**
+ * Copyright (c) 2016 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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
+ *
+ * @defgroup sdk_nrf_svc_function Supervisor function
+ * @{
+ * @ingroup app_common
+ *
+ * @brief Macros to create Supervisor functions.
+ */
+
+#ifndef NRF_SVC_FUNCTION_H__
+#define NRF_SVC_FUNCTION_H__
+
+#include <stdint.h>
+#include "nrf_section.h"
+#include "app_util.h"
+#include "nrf_svci.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+/** @brief Function to be called from an SVC handler.
+ *
+ * @warning This function prototype has no arguments. It will be cast to a function prototype
+ * that has 0 to 4 arguments. 4 arguments is the highest number of allowed arguments in
+ * a Supervisor call.
+ *
+ * @warning The nrf_svc_func_t function prototype should not have void as parameter list as there
+ * will be 0 to 4 arguments after casting.
+ */
+typedef uint32_t (*nrf_svc_func_t)();
+
+/** @brief Type holding the SVC number, SVCI number, and the pointer to the corresponding handler
+ * function.
+ *
+ * @note The function that is pointed to must not change version.
+ */
+typedef struct
+{
+ uint32_t svc_num; /**< Supervisor call number (actually 8-bit, padded for alignment). */
+ uint32_t svci_num; /**< Supervisor call indirect number. */
+ nrf_svc_func_t func_ptr;
+} nrf_svc_func_reg_t;
+
+
+// Verify that the size of nrf_svc_func_t is aligned to make sure it can be used in nrf_section.
+STATIC_ASSERT(sizeof(nrf_svc_func_reg_t) % 4 == 0);
+
+
+/** @brief Macro for registering a structure holding SVC number and SVC handler
+ * function pointer.
+ *
+ * @details This macro places a variable in a section named "svc_data" that
+ * the SVC handler uses during regular operation.
+ *
+ * @note This macro must be invoked from a source file. There should only be one
+ * registration by a given SVC number. SVC number 0 (zero) is invalid input
+ * and will cause a compile time assertion.
+ *
+ * @param[in] name Name of the structure. Logically accessible from the source file.
+ * @param[in] svc_number SVC number to register.
+ * @param[in] func Function to call for a given SVC number.
+ *
+ * @retval Variable registration in @ref lib_section_vars named svc_data.
+ */
+#define NRF_SVC_FUNCTION_REGISTER(svc_number, name, func) \
+STATIC_ASSERT(svc_number != 0); \
+NRF_SECTION_ITEM_REGISTER(svc_data, nrf_svc_func_reg_t const name) = \
+{ \
+ .svc_num = svc_number, \
+ .svci_num = NRF_SVCI_SVC_NUM_INVALID, \
+ .func_ptr = (nrf_svc_func_t)func \
+}
+
+
+/** @brief Macro for registering a structure holding SVC number, SVCI number, and SVCI handler
+ * function pointer.
+ *
+ * @details This macro places a variable in a section named "svc_data" that
+ * the SVC handler uses during regular operation.
+ *
+ * @note This macro must be invoked from a source file. There should only be one registration
+ * for a given SVC indirect number.
+ *
+ * @param[in] name Name of the structure. Logically accessible from the source file.
+ * @param[in] svci_number SVC indirect number to register.
+ * @param[in] func Function to call for a given SVC indirect number.
+ *
+ * @retval Variable registration in @ref lib_section_vars named svc_data.
+ */
+#define NRF_SVCI_FUNCTION_REGISTER(svci_number, name, func) \
+NRF_SECTION_ITEM_REGISTER(svc_data, nrf_svc_func_reg_t const name) = \
+{ \
+ .svc_num = NRF_SVCI_SVC_NUM, \
+ .svci_num = svci_number, \
+ .func_ptr = (nrf_svc_func_t)func \
+}
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // NRF_SVC_FUNCTION_H__
+
+/** @} */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/svc/nrf_svc_handler.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/svc/nrf_svc_handler.c
new file mode 100644
index 0000000..2c7aaca
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/svc/nrf_svc_handler.c
@@ -0,0 +1,156 @@
+/**
+ * Copyright (c) 2016 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#include <stdbool.h>
+#include <stdint.h>
+#include "nrf_svc_function.h"
+#include "nrf_error.h"
+
+#include "nrf_log.h"
+
+//lint -esym(526, svc_dataBase) -esym(526, svc_dataLimit)
+NRF_SECTION_DEF(svc_data, const nrf_svc_func_t);
+#define SVC_DATA_SECTION_ITEM_GET(i) NRF_SECTION_ITEM_GET(svc_data, nrf_svc_func_reg_t, (i))
+#define SVC_DATA_SECTION_ITEM_COUNT NRF_SECTION_ITEM_COUNT(svc_data, nrf_svc_func_reg_t)
+
+
+#ifdef __GNUC__
+// Prevent GCC from removing this function (called from assembly branch)
+void nrf_svc_handler_c(uint32_t* p_svc_args) __attribute__((used));
+#endif
+
+
+
+/**@brief Function for handling second stage of Supervisor Calls (SVC).
+*
+* @details The function will use loop through the registered svc functions stored
+* in the named section "svc_data" and will call the registered function
+* if the svn_num corresponds with the registration.
+*
+* @param[in] p_svc_args Argument list for the SVC.
+*
+* @return This function returns by updating p_svc_arsg[0]. This will be reported back to the caller of SVC
+* @ref NRF_ERROR_SVC_HANDLER_MISSING is returned if no SVC handler is implemented for the
+* provided svc_num.
+*/
+void nrf_svc_handler_c(uint32_t* p_svc_args)
+{
+ uint32_t const num_funcs = SVC_DATA_SECTION_ITEM_COUNT;
+ bool handled = false;
+ uint8_t const svc_num = ((uint8_t *)p_svc_args[6])[-2];
+ uint32_t svci_num = NRF_SVCI_SVC_NUM_INVALID;
+
+ if (svc_num == NRF_SVCI_SVC_NUM)
+ {
+ // load the stacked R12 as the svci_num
+ svci_num = p_svc_args[4];
+ }
+
+ for (uint32_t i = 0; i < num_funcs; i++)
+ {
+ nrf_svc_func_reg_t const * func_reg = SVC_DATA_SECTION_ITEM_GET(i);
+ if (func_reg->svc_num != svc_num)
+ {
+ continue;
+ }
+
+ if (svci_num != NRF_SVCI_SVC_NUM_INVALID && func_reg->svci_num != svci_num)
+ {
+ continue;
+ }
+
+ // Return value is placed in R0
+ p_svc_args[0] = func_reg->func_ptr(p_svc_args[0], p_svc_args[1], p_svc_args[2], p_svc_args[3]);
+ handled = true;
+ break;
+ }
+
+ if (handled == false)
+ {
+ // Return value is placed in R0
+ p_svc_args[0] = NRF_ERROR_SVC_HANDLER_MISSING;
+ }
+}
+
+/**@brief Function for handling the first stage of Supervisor Calls (SVC) in assembly.
+*
+* @details The function will use the link register (LR) to determine the stack (PSP or MSP) to be
+* used and then decode the SVC number afterwards. After decoding the SVC number,
+* @ref C_SVC_Handler is called for further processing of the SVC.
+*/
+#if defined ( __CC_ARM )
+__ASM void SVC_Handler(void)
+{
+ tst lr, #4 ; Test bit 2 of EXT_RETURN to see if MSP or PSP is used
+ ite eq ;
+ mrseq r0, MSP ; If equal, copy stack pointer from MSP
+ mrsne r0, PSP ; If not equal, copy stack pointer from PSP
+ B __cpp(nrf_svc_handler_c) ; Call C-implementation of handler. Exception stack frame in R0
+ ALIGN 4 ; Protect with alignment
+}
+#elif defined ( __GNUC__ )
+void __attribute__((naked)) SVC_Handler(void)
+{
+ __ASM volatile
+ (
+ "tst lr, #4\t\n" // Test bit 2 of EXT_RETURN to see if MSP or PSP is used
+ "ite eq\t\n" //
+ "mrseq r0, MSP\t\n" // Move MSP into R0.
+ "mrsne r0, PSP\t\n" // Move PSP into R0.
+ "b nrf_svc_handler_c\t\n" // Call C-implementation of handler. Exception stack frame in R0
+ ".align\t\n" // Protect with alignment
+ );
+}
+#elif defined ( __ICCARM__ )
+void SVC_Handler(void)
+{
+ __ASM volatile
+ (
+ "tst lr, #4\t\n" // Test bit in link register responsible for stack indication.
+ "ite eq\t\n" // Test bit 2 of EXT_RETURN to see if MSP or PSP is used
+ "mrseq r0, MSP\t\n" // Move MSP into R0.
+ "mrsne r0, PSP\t\n" // Move PSP into R0.
+ "b nrf_svc_handler_c\t\n" : // Call C-implementation of handler. Exception stack frame in R0
+ );
+}
+#else
+
+#error Compiler not supported.
+
+#endif
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/svc/nrf_svci.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/svc/nrf_svci.h
new file mode 100644
index 0000000..38d54e3
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/svc/nrf_svci.h
@@ -0,0 +1,300 @@
+/**
+ * Copyright (c) 2016 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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
+ *
+ * @defgroup sdk_nrf_svci Supervisor instructions with indirect number
+ * @{
+ * @ingroup app_common
+ *
+ * @brief Macros to create Supervisor instructions using indirect number.
+ */
+
+#ifndef NRF_SVCI_H__
+#define NRF_SVCI_H__
+
+#include "stdint.h"
+#include "compiler_abstraction.h"
+#include "app_util.h"
+
+
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define NRF_SVCI_SVC_NUM 0 /**< SVC number used for all SVCI functions. */
+#define NRF_SVCI_SVC_NUM_INVALID (0xFFFFFFFF) /**< Invalid SVCI number. */
+
+#ifdef __cplusplus
+ #define GCC_CAST_CPP (uint8_t)
+#else
+ #define GCC_CAST_CPP
+#endif
+
+#if (__LINT__ != 1)
+
+#if defined (__CC_ARM)
+
+ #define SVCI_DECL(svci_num, return_type, function_name, ...) \
+ return_type __svc_indirect(NRF_SVCI_SVC_NUM) \
+ svci_ ## function_name(uint32_t _svci_num, ##__VA_ARGS__);
+
+ #define SVCI_DECL_0(svci_num, return_type, function_name) \
+ return_type __svc_indirect(NRF_SVCI_SVC_NUM) \
+ svci_ ## function_name(uint32_t _svci_num);
+
+ #define SVCI_0(svci_num, return_type, function_name) \
+ SVCI_DECL_0(svci_num, return_type, function_name) \
+ static __INLINE return_type function_name(void) \
+ { \
+ return svci_ ## function_name(svci_num); \
+ }
+
+ #define SVCI_1(svci_num, return_type, function_name, p0t, p0n) \
+ SVCI_DECL(svci_num, return_type, function_name, p0t p0n) \
+ static __INLINE return_type function_name(p0t p0n) \
+ { \
+ return svci_ ## function_name(svci_num, p0n); \
+ }
+
+ #define SVCI_2(svci_num, return_type, function_name, p0t, p0n, p1t, p1n) \
+ SVCI_DECL(svci_num, return_type, function_name, p0t p0n, p1t p1n) \
+ static __INLINE return_type function_name(p0t p0n, p1t p1n) \
+ { \
+ return svci_ ## function_name(svci_num, p0n, p1n); \
+ }
+
+ #define SVCI_3(svci_num, return_type, function_name, p0t, p0n, p1t, p1n, p2t, p2n) \
+ SVCI_DECL(svci_num, return_type, function_name, p0t p0n, p1t p1n, p2t p2n) \
+ static __INLINE return_type function_name(p0t p0n, p1t p1n, p2t p2n) \
+ { \
+ return svci_ ## function_name(svci_num, p0n, p1n, p2n); \
+ }
+
+ #define SVCI_4(svci_num, return_type, function_name, p0t, p0n, p1t, p1n, p2t, p2n, p3t, p3n) \
+ SVCI_DECL(svci_num, return_type, function_name, p0t p0n, p1t p1n, p2t p2n, p3t p3n) \
+ static __INLINE return_type function_name(p0t p0n, p1t p1n, p2t p2n, p3t p3n) \
+ { \
+ return svci_ ## function_name(svci_num, p0n, p1n, p2n, p3n); \
+ }
+
+#else
+
+#if defined (__GNUC__)
+
+ #define SVCI_DECL_0(svci_num, return_type, function_name) \
+ _Pragma("GCC diagnostic push") \
+ _Pragma("GCC diagnostic ignored \"-Wreturn-type\"") \
+ __attribute__((naked, unused)) \
+ static return_type svci_ ## function_name(void) \
+ { \
+ /* Do the SuperVisor call by using svc instruction with \
+ R12 containing the SVCI number */ \
+ __ASM __volatile \
+ ( \
+ " ldr r12, =%0 \n" \
+ " svc %1 \n" \
+ " bx lr \n" \
+ " .ltorg" \
+ : /* output */ \
+ : /* input */ \
+ "X"(svci_num), \
+ "I"(GCC_CAST_CPP NRF_SVCI_SVC_NUM) \
+ : /* clobbers */ \
+ "r12" \
+ ); \
+ } \
+ _Pragma("GCC diagnostic pop")
+
+ #define SVCI_DECL(svci_num, return_type, function_name, ...) \
+ _Pragma("GCC diagnostic push") \
+ _Pragma("GCC diagnostic ignored \"-Wreturn-type\"") \
+ __attribute__((naked, unused)) \
+ static return_type svci_ ## function_name(__VA_ARGS__) \
+ { \
+ /* Do the SuperVisor call by using svc instruction with \
+ R12 containing the SVCI number */ \
+ __ASM __volatile \
+ ( \
+ " ldr.w r12, =%0 \n" \
+ " svc %1 \n" \
+ " bx lr \n" \
+ " .ltorg" \
+ : /* output */ \
+ : /* input */ \
+ "X"(svci_num), \
+ "I"(GCC_CAST_CPP NRF_SVCI_SVC_NUM) \
+ : /* clobbers */ \
+ "r12" \
+ ); \
+ } \
+ _Pragma("GCC diagnostic pop")
+
+#elif defined (__ICCARM__)
+
+ #define SVCI_DECL_0(svci_num, return_type, function_name) \
+ /* Suppress return value warning. */ \
+ _Pragma("diag_suppress=Pe940") \
+ static __root return_type svci_ ## function_name(void) \
+ { \
+ /* Do the SuperVisor call by using svc instruction with \
+ R12 containing the SVCI number */ \
+ __ASM volatile \
+ ( \
+ " mov r12, %0 \n" \
+ " svc %1 \n" \
+ : /*no output*/ \
+ : "r" (svci_num), "I" (NRF_SVCI_SVC_NUM) \
+ : \
+ ); \
+ }
+
+ #define SVCI_DECL(svci_num, return_type, function_name, ...) \
+ /* Suppress return value warning. */ \
+ _Pragma("diag_suppress=Pe940") \
+ static __root return_type svci_ ## function_name(__VA_ARGS__) \
+ { \
+ /* We stack r0-r3 as r0 is used to set high register (r12) \
+ This CODE MUST BE IN ITS OWN __ASM BLOCK! */ \
+ __ASM volatile ( "push {r0, r1, r2, r3}\n\t" ); \
+ /* Set R12 to the svc_number, this will use r0 as indirect \
+ * storage. Pop r0-r3 to reset value before SVCI. */ \
+ __ASM volatile \
+ ( \
+ " mov r12, %0 \n" \
+ " pop {r0, r1, r2, r3} \n" \
+ : /*no output */ \
+ : "r" (svci_num) \
+ : \
+ ); \
+ /* Do the SuperVisor call by using svc instruction with \
+ R12 containing the SVCI number */ \
+ __ASM volatile \
+ ( \
+ " svc %0 \n" \
+ " bx lr \n" \
+ : /*no output*/ \
+ : "I" (NRF_SVCI_SVC_NUM) \
+ : \
+ ); \
+ }
+#else // Not defined (__ICCARM__) or defined (__GNUC__)
+
+ #error Unsupported compiler for SVCI interface
+
+#endif // Not defined (__ICCARM__) or defined (__GNUC__)
+
+ #define SVCI_0(svci_num, return_type, function_name) \
+ SVCI_DECL_0(svci_num, return_type, function_name) \
+ static __INLINE return_type function_name(void) \
+ { \
+ return svci_ ## function_name(); \
+ }
+
+ #define SVCI_1(svci_num, return_type, function_name, p0t, p0n) \
+ SVCI_DECL(svci_num, return_type, function_name, p0t p0n) \
+ static __INLINE return_type function_name(p0t p0n) \
+ { \
+ return svci_ ## function_name(p0n); \
+ }
+
+ #define SVCI_2(svci_num, return_type, function_name, p0t, p0n, p1t, p1n) \
+ SVCI_DECL(svci_num, return_type, function_name, p0t p0n, p1t p1n) \
+ static __INLINE return_type function_name(p0t p0n, p1t p1n) \
+ { \
+ return svci_ ## function_name(p0n, p1n); \
+ }
+
+ #define SVCI_3(svci_num, return_type, function_name, p0t, p0n, p1t, p1n, p2t, p2n) \
+ SVCI_DECL(svci_num, return_type, function_name, p0t p0n, p1t p1n, p2t p2n) \
+ static __INLINE return_type function_name(p0t p0n, p1t p1n, p2t p2n) \
+ { \
+ return svci_ ## function_name(p0n, p1n, p2n); \
+ }
+
+ #define SVCI_4(svci_num, return_type, function_name, p0t, p0n, p1t, p1n, p2t, p2n, p3t, p3n) \
+ SVCI_DECL(svci_num, return_type, function_name, p0t p0n, p1t p1n, p2t p2n, p3t p3n) \
+ static __INLINE return_type function_name(p0t p0n, p1t p1n, p2t p2n, p3t p3n) \
+ { \
+ return svci_ ## function_name(p0n, p1n, p2n, p3n); \
+ }
+
+#endif // Not __CC_ARM
+
+#define VA_NARGS_IMPL(_0, _1, _2, _3, _4, _5, _6, _7, _8, N, ...) N
+#define VA_NARGS(...) VA_NARGS_IMPL(__VA_ARGS__, 4, 4, 3, 3, 2, 2, 1, 1, 0)
+
+#ifdef SVCALL_INDIRECT_AS_NORMAL_FUNCTION
+
+#define SVCI(svci_num, return_type, function_name, ...) \
+ return_type function_name(##__VA_ARGS__)
+
+#else
+
+
+#define SVCI_IMPLI(count, svci_num, return_type, function_name, ...) \
+ SVCI##_##count (svci_num, return_type, function_name, ##__VA_ARGS__)
+
+#define SVCI_IMPL(count, svci_num, return_type, function_name, ...) \
+ SVCI_IMPLI(count, svci_num, return_type, function_name, ##__VA_ARGS__)
+
+#define SVCI(svci_num, return_type, function_name, ...) \
+ SVCI_IMPL(VA_NARGS(__VA_ARGS__), svci_num, return_type, function_name, ##__VA_ARGS__)
+
+
+#endif // SVCALL_INDIRECT_AS_NORMAL_FUNCTION
+
+#else // (__LINT__ == 1)
+ #define SVCI(svci_num, return_type, function_name, ...)
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+
+
+#endif // NRF_SVCI_H__
+
+
+
+
+/** @} */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/svc/nrf_svci_async_function.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/svc/nrf_svci_async_function.h
new file mode 100644
index 0000000..ca1f85a
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/svc/nrf_svci_async_function.h
@@ -0,0 +1,191 @@
+/**
+ * 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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
+ *
+ * @defgroup sdk_nrf_svci_async_function Asynchronous Supervisor function interface
+ * @{
+ * @ingroup app_common
+ *
+ * @brief Macros to create Asynchronous Supervisor interface functions.
+ */
+
+#ifndef NRF_SVC_ASYNC_FUNCTION_H__
+#define NRF_SVC_ASYNC_FUNCTION_H__
+
+#include "nrf_svci.h"
+#include "nrf_svci_async_handler.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**@brief Macro for creating type definition for SVCI interface init function.
+ *
+ * @warning Do not call this macro directly! Use @ref NRF_SVCI_ASYNC_FUNC_DECLARE instead.
+ *
+ * @param[in] name Name of async request function. Will be appended with _async_fn_t.
+ * @param[in] param_type Parameter type.
+ * @param[in] state_type State type.
+ *
+ * @retval Type definition a named SVCI async init function.
+ */
+#define NRF_SVCI_ACYNC_FUNC_TYPEDEF(name, param_type, state_type) \
+typedef uint32_t (* name ## _async_fn_t)(param_type * p_param, state_type * p_state)
+
+
+/**@brief Macro for creating type definition for SVCI interface event function.
+ *
+ * @warning Do not call this macro directly! Use @ref NRF_SVCI_ASYNC_FUNC_DECLARE instead.
+ *
+ * @details Calling this function with sys-events will report @ref NRF_ERROR_BUSY until
+ * the asynchronous calls is finished, at which time it will report either
+ * NRF_SUCCESS or any another error-message.
+ *
+ * @param[in] name Name of the event function. Will be appended with _event_fn_t
+ * @param[in] state_type Type parameter for the state.
+ *
+ * @retval Type definition for a named SVCI async event function.
+ */
+#define NRF_SVCI_ASYNC_EVENT_FUNC_TYPEDEF(name, state_type) \
+typedef uint32_t (* name ## _event_fn_t)(uint32_t sys_evt, state_type * p_state)
+
+
+/**@brief Macro for creating a declaration of a named async function for the SVCI interface.
+ *
+ * @details The async interface provides a method to call into a external application
+ * through the SVCI interface without relying on allocated or reserved memory inside the
+ * external application.
+ *
+ * This macro declares variables and function types in use by the async SVCI interface.
+ *
+ * @note This is intended to be invoked in a header file shared by both the
+ * caller and the recipient (handler).
+ *
+ * @param[in] svci_num SVC indirect number.
+ * @param[in] name Name of the async function.
+ * @param[in] param_type Type of the param used for the async interface.
+ * @param[in] state_type Type of the state used for the async interface.
+ *
+ * @retval A type definition of NAME_svc_async_t to be used for async access
+ * through the SVCI interface.
+ */
+#define NRF_SVCI_ASYNC_FUNC_DECLARE(svci_num, \
+ name, \
+ param_type, \
+ state_type) \
+/*lint --e{19} */ \
+NRF_SVCI_ACYNC_FUNC_TYPEDEF(name, param_type, state_type); \
+NRF_SVCI_ASYNC_EVENT_FUNC_TYPEDEF(name, state_type); \
+ \
+typedef struct \
+{ \
+ name ## _async_fn_t async_func; \
+ name ## _event_fn_t sys_evt_handler; \
+ state_type state; \
+} name ## _svci_async_t;
+
+
+
+//lint -save --e{10, 19, 40, 102} -esym(526, *_init) -esym(628, *_init)
+
+/**@brief Macro for defining a named SVCI async interface.
+ *
+ * @details The async interface provides a method to call into an external application
+ * through the SVCI interface without relying on allocated or reserved memory inside the
+ * external application.
+ *
+ * Running this macro creates a defintion of the structure that holds the
+ * information about the async function, the event handler, and the state.
+ *
+ * Running this macro also defines convenience functions to the SVCI interface.
+ *
+ * The available functions are:
+ * -NAME_init - Function to call to set up the async SVCI interface.
+ * -NAME - Function to call the async SVCI interface.
+ * -NAME_on_sys_event - Function to report sys events to the async
+ * SVCI interface.
+ * -NAME_is_initialized - Function to check if the async SVCI interface is
+ * initialized and ready to use.
+ *
+ * @note Invoking this macro is only possible in a source file as the macro creates
+ * a static variable for the async interface as well as static functions to call
+ * into the async interface.
+ *
+ * @param[in] svci_num SVC indirect number.
+ * @param[in] name Name of the async function.
+ * @param[in] param_type Type of the param used for the async interface.
+ *
+ * @retval Instance of the async SVCI interface and convenience functions for using it.
+ */
+#define NRF_SVCI_ASYNC_FUNC_DEFINE(svci_num, name, param_type) \
+ \
+SVCI(svci_num, uint32_t, name ## _svci_async_init, name ## _svci_async_t *, p_async); \
+static name ## _svci_async_t name ## _svci_async_def = {0}; \
+ \
+static __INLINE uint32_t name ## _init (void) \
+{ \
+ return name ## _svci_async_init(&name ## _svci_async_def); \
+} \
+ \
+static __INLINE uint32_t name(param_type * p_param) \
+{ \
+ return name ## _svci_async_def.async_func(p_param, &name ## _svci_async_def.state); \
+} \
+ \
+static __INLINE uint32_t name ## _on_sys_evt(uint32_t sys_evt) \
+{ \
+ return name ## _svci_async_def.sys_evt_handler(sys_evt, &name ## _svci_async_def.state); \
+} \
+ \
+static __INLINE uint32_t name ## _is_initialized(void) \
+{ \
+ return (name ## _svci_async_def.async_func != NULL && \
+ name ## _svci_async_def.sys_evt_handler != NULL ); \
+}
+
+//lint -restore
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // NRF_SVC_ASYNC_FUNCTION_H__
+
+/** @} */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/svc/nrf_svci_async_handler.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/svc/nrf_svci_async_handler.h
new file mode 100644
index 0000000..a1d2270
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/svc/nrf_svci_async_handler.h
@@ -0,0 +1,93 @@
+/**
+ * Copyright (c) 2016 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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
+ *
+ * @defgroup sdk_nrf_svci_async_handler Asynchronous Supervisor handler functions
+ * @{
+ * @ingroup app_common
+ *
+ * @brief Macros to create Asynchronous Supervisor interface handler functions.
+ */
+
+#ifndef NRF_SVCI_ASYNC_HANDLER_H__
+#define NRF_SVCI_ASYNC_HANDLER_H__
+
+#include "nrf_svc_function.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**@brief Macro for creating a registration for an async handler for the SVCI interface
+ *
+ * @details Calling this macro will register a SVCI function handler using @ref
+ * NRF_SVCI_FUNCTION_REGISTER
+ *
+ * @note This macro must be invoked from a source file as it declares static functions
+ * to be implemented and because it creates a @ref lib_section_vars registration to
+ * SVCI interface which is intended to be unique.
+ *
+ * @param[in] svci_num SVC indirect number.
+ * @param[in] name Name of the async function.
+ * @param[in] param_type Type of the param to send when running the async interface.
+ * @param[in] state_type Type of the state to be called together with sys_event.
+ *
+ * @retval Static declarations to handler functions to be implemented in the form NAME_handler
+ * NAME_on_call, and NAME_on_sys_event.
+ */
+#define NRF_SVCI_ASYNC_HANDLER_CREATE(svci_num, \
+ name, \
+ param_type, \
+ state_type) \
+ \
+static uint32_t name ## _handler(name ## _svci_async_t * p_async); \
+static uint32_t name ## _on_call(param_type * p_param, state_type * p_state); \
+static uint32_t name ## _on_sys_evt(uint32_t sys_event, state_type * p_state); \
+ \
+NRF_SVCI_FUNCTION_REGISTER(svci_num, name ## _var, name ## _handler)
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // NRF_SVCI_ASYNC_HANDLER_H__
+
+/** @} */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/timer/app_timer.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/timer/app_timer.c
new file mode 100644
index 0000000..0df49b7
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/timer/app_timer.c
@@ -0,0 +1,1075 @@
+/**
+ * Copyright (c) 2012 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#include "sdk_common.h"
+#if NRF_MODULE_ENABLED(APP_TIMER)
+#include "app_timer.h"
+#include <stdlib.h>
+#include "nrf.h"
+#include "nrf_peripherals.h"
+#include "nrf_soc.h"
+#include "app_error.h"
+#include "nrf_delay.h"
+#include "app_util_platform.h"
+#if APP_TIMER_CONFIG_USE_SCHEDULER
+#include "app_scheduler.h"
+#endif
+
+#define RTC1_IRQ_PRI APP_TIMER_CONFIG_IRQ_PRIORITY /**< Priority of the RTC1 interrupt (used for checking for timeouts and executing timeout handlers). */
+#define SWI_IRQ_PRI APP_TIMER_CONFIG_IRQ_PRIORITY /**< Priority of the SWI interrupt (used for updating the timer list). */
+
+// The current design assumes that both interrupt handlers run at the same interrupt level.
+// If this is to be changed, protection must be added to prevent them from interrupting each other
+// (e.g. by using guard/trigger flags).
+STATIC_ASSERT(RTC1_IRQ_PRI == SWI_IRQ_PRI);
+
+#define MAX_RTC_COUNTER_VAL 0x00FFFFFF /**< Maximum value of the RTC counter. */
+
+#define RTC_COMPARE_OFFSET_MIN 3 /**< Minimum offset between the current RTC counter value and the Capture Compare register. Although the nRF51 Series User Specification recommends this value to be 2, we use 3 to be safer.*/
+
+#define MAX_RTC_TASKS_DELAY 47 /**< Maximum delay until an RTC task is executed. */
+
+#ifdef EGU_PRESENT
+#define SWI_PART(_id) CONCAT_2(SWI,_id)
+#define EGU_PART(_id) CONCAT_2(_EGU,_id)
+#define SWI_IRQ_n(_id) CONCAT_3(SWI_PART(_id), EGU_PART(_id),_IRQn)
+#define SWI_IRQ_Handler_n(_id) CONCAT_3(SWI_PART(_id), EGU_PART(_id),_IRQHandler)
+#else //EGU_PRESENT
+#define SWI_IRQ_n(_id) CONCAT_3(SWI,_id,_IRQn)
+#define SWI_IRQ_Handler_n(_id) CONCAT_3(SWI,_id,_IRQHandler)
+#endif
+
+#define SWI_IRQn SWI_IRQ_n(APP_TIMER_CONFIG_SWI_NUMBER)
+#define SWI_IRQHandler SWI_IRQ_Handler_n(APP_TIMER_CONFIG_SWI_NUMBER)
+
+
+#define MODULE_INITIALIZED (m_op_queue.size != 0) /**< Macro designating whether the module has been initialized properly. */
+
+/**@brief Timer node type. The nodes will be used form a linked list of running timers. */
+typedef struct
+{
+ uint32_t ticks_to_expire; /**< Number of ticks from previous timer interrupt to timer expiry. */
+ uint32_t ticks_at_start; /**< Current RTC counter value when the timer was started. */
+ uint32_t ticks_first_interval; /**< Number of ticks in the first timer interval. */
+ uint32_t ticks_periodic_interval; /**< Timer period (for repeating timers). */
+ bool is_running; /**< True if timer is running, False otherwise. */
+ app_timer_mode_t mode; /**< Timer mode. */
+ app_timer_timeout_handler_t p_timeout_handler; /**< Pointer to function to be executed when the timer expires. */
+ void * p_context; /**< General purpose pointer. Will be passed to the timeout handler when the timer expires. */
+ void * next; /**< Pointer to the next node. */
+} timer_node_t;
+
+STATIC_ASSERT(sizeof(timer_node_t) == APP_TIMER_NODE_SIZE);
+
+/**@brief Set of available timer operation types. */
+typedef enum
+{
+ TIMER_USER_OP_TYPE_NONE, /**< Invalid timer operation type. */
+ TIMER_USER_OP_TYPE_START, /**< Timer operation type Start. */
+ TIMER_USER_OP_TYPE_STOP, /**< Timer operation type Stop. */
+ TIMER_USER_OP_TYPE_STOP_ALL /**< Timer operation type Stop All. */
+} timer_user_op_type_t;
+
+/**@brief Structure describing a timer start operation. */
+typedef struct
+{
+ uint32_t ticks_at_start; /**< Current RTC counter value when the timer was started. */
+ uint32_t ticks_first_interval; /**< Number of ticks in the first timer interval. */
+ uint32_t ticks_periodic_interval; /**< Timer period (for repeating timers). */
+ void * p_context; /**< General purpose pointer. Will be passed to the timeout handler when the timer expires. */
+} timer_user_op_start_t;
+
+/**@brief Structure describing a timer operation. */
+typedef struct
+{
+ timer_user_op_type_t op_type; /**< Id of timer on which the operation is to be performed. */
+ timer_node_t * p_node;
+ union
+ {
+ timer_user_op_start_t start; /**< Structure describing a timer start operation. */
+ } params;
+} timer_user_op_t;
+
+/**@brief Structure describing a timer operations queue.
+ *
+ * @details This queue will hold timer operations issued by the application
+ * until the timer interrupt handler processes these operations.
+ */
+typedef struct
+{
+ uint8_t first; /**< Index of first entry to have been inserted in the queue (i.e. the next entry to be executed). */
+ uint8_t last; /**< Index of last entry to have been inserted in the queue. */
+ uint8_t size; /**< Queue size. */
+ timer_user_op_t user_op_queue[APP_TIMER_CONFIG_OP_QUEUE_SIZE+1]; /**< Queue buffer. */
+} timer_op_queue_t;
+
+STATIC_ASSERT(sizeof(timer_op_queue_t) % 4 == 0);
+
+#define CONTEXT_QUEUE_SIZE_MAX (2)
+
+static timer_op_queue_t m_op_queue; /**< Timer operations queue. */
+static timer_node_t * mp_timer_id_head; /**< First timer in list of running timers. */
+static uint32_t m_ticks_latest; /**< Last known RTC counter value. */
+static uint32_t m_ticks_elapsed[CONTEXT_QUEUE_SIZE_MAX]; /**< Timer internal elapsed ticks queue. */
+static uint8_t m_ticks_elapsed_q_read_ind; /**< Timer internal elapsed ticks queue read index. */
+static uint8_t m_ticks_elapsed_q_write_ind; /**< Timer internal elapsed ticks queue write index. */
+static bool m_rtc1_running; /**< Boolean indicating if RTC1 is running. */
+static bool m_rtc1_reset; /**< Boolean indicating if RTC1 counter has been reset due to last timer removed from timer list during the timer list handling. */
+
+#if APP_TIMER_WITH_PROFILER
+static uint8_t m_max_user_op_queue_utilization; /**< Maximum observed timer user operations queue utilization. */
+#endif
+
+/**@brief Function for initializing the RTC1 counter.
+ *
+ * @param[in] prescaler Value of the RTC1 PRESCALER register. Set to 0 for no prescaling.
+ */
+static void rtc1_init(uint32_t prescaler)
+{
+ NRF_RTC1->PRESCALER = prescaler;
+ NVIC_SetPriority(RTC1_IRQn, RTC1_IRQ_PRI);
+}
+
+
+/**@brief Function for starting the RTC1 timer.
+ */
+static void rtc1_start(void)
+{
+ NRF_RTC1->EVTENSET = RTC_EVTEN_COMPARE0_Msk;
+ NRF_RTC1->INTENSET = RTC_INTENSET_COMPARE0_Msk;
+
+ NVIC_ClearPendingIRQ(RTC1_IRQn);
+ NVIC_EnableIRQ(RTC1_IRQn);
+
+ NRF_RTC1->TASKS_START = 1;
+ nrf_delay_us(MAX_RTC_TASKS_DELAY);
+
+ m_rtc1_running = true;
+}
+
+
+/**@brief Function for stopping the RTC1 timer.
+ */
+static void rtc1_stop(void)
+{
+ NVIC_DisableIRQ(RTC1_IRQn);
+
+ NRF_RTC1->EVTENCLR = RTC_EVTEN_COMPARE0_Msk;
+ NRF_RTC1->INTENCLR = RTC_INTENSET_COMPARE0_Msk;
+
+ NRF_RTC1->TASKS_STOP = 1;
+ nrf_delay_us(MAX_RTC_TASKS_DELAY);
+
+ NRF_RTC1->TASKS_CLEAR = 1;
+ m_ticks_latest = 0;
+ nrf_delay_us(MAX_RTC_TASKS_DELAY);
+
+ m_rtc1_running = false;
+}
+
+
+/**@brief Function for returning the current value of the RTC1 counter.
+ *
+ * @return Current value of the RTC1 counter.
+ */
+static __INLINE uint32_t rtc1_counter_get(void)
+{
+ return NRF_RTC1->COUNTER;
+}
+
+
+/**@brief Function for computing the difference between two RTC1 counter values.
+ *
+ * @return Number of ticks elapsed from ticks_old to ticks_now.
+ */
+static __INLINE uint32_t ticks_diff_get(uint32_t ticks_now, uint32_t ticks_old)
+{
+ return ((ticks_now - ticks_old) & MAX_RTC_COUNTER_VAL);
+}
+
+
+/**@brief Function for setting the RTC1 Capture Compare register 0, and enabling the corresponding
+ * event.
+ *
+ * @param[in] value New value of Capture Compare register 0.
+ */
+static __INLINE void rtc1_compare0_set(uint32_t value)
+{
+ NRF_RTC1->CC[0] = value;
+}
+
+
+/**@brief Function for inserting a timer in the timer list.
+ *
+ * @param[in] timer_id Id of timer to insert.
+ */
+static void timer_list_insert(timer_node_t * p_timer)
+{
+ if (mp_timer_id_head == NULL)
+ {
+ mp_timer_id_head = p_timer;
+ }
+ else
+ {
+ if (p_timer->ticks_to_expire <= mp_timer_id_head->ticks_to_expire)
+ {
+ mp_timer_id_head->ticks_to_expire -= p_timer->ticks_to_expire;
+
+ p_timer->next = mp_timer_id_head;
+ mp_timer_id_head = p_timer;
+ }
+ else
+ {
+ timer_node_t * p_previous;
+ timer_node_t * p_current;
+ uint32_t ticks_to_expire;
+
+ ticks_to_expire = p_timer->ticks_to_expire;
+ p_previous = mp_timer_id_head;
+ p_current = mp_timer_id_head;
+
+ while ((p_current != NULL) && (ticks_to_expire > p_current->ticks_to_expire))
+ {
+ ticks_to_expire -= p_current->ticks_to_expire;
+ p_previous = p_current;
+ p_current = p_current->next;
+ }
+
+ if (p_current != NULL)
+ {
+ p_current->ticks_to_expire -= ticks_to_expire;
+ }
+
+ p_timer->ticks_to_expire = ticks_to_expire;
+ p_timer->next = p_current;
+ p_previous->next = p_timer;
+ }
+ }
+}
+
+
+/**@brief Function for removing a timer from the timer queue.
+ *
+ * @param[in] timer_id Id of timer to remove.
+ *
+ * @return TRUE if Capture Compare register must be updated, FALSE otherwise.
+ */
+static bool timer_list_remove(timer_node_t * p_timer)
+{
+ timer_node_t * p_old_head;
+ timer_node_t * p_previous;
+ timer_node_t * p_current;
+ uint32_t timeout;
+
+ // Find the timer's position in timer list.
+ p_old_head = mp_timer_id_head;
+ p_previous = mp_timer_id_head;
+ p_current = p_previous;
+
+ while (p_current != NULL)
+ {
+ if (p_current == p_timer)
+ {
+ break;
+ }
+ p_previous = p_current;
+ p_current = p_current->next;
+ }
+
+ // Timer not in active list.
+ if (p_current == NULL)
+ {
+ return false;
+ }
+
+ // Timer is the first in the list
+ if (p_previous == p_current)
+ {
+ mp_timer_id_head = mp_timer_id_head->next;
+
+ // No more timers in the list. Reset RTC1 in case Start timer operations are present in the queue.
+ if (mp_timer_id_head == NULL)
+ {
+ NRF_RTC1->TASKS_CLEAR = 1;
+ m_ticks_latest = 0;
+ m_rtc1_reset = true;
+ nrf_delay_us(MAX_RTC_TASKS_DELAY);
+ }
+ }
+
+ // Remaining timeout between next timeout.
+ timeout = p_current->ticks_to_expire;
+
+ // Link previous timer with next of this timer, i.e. removing the timer from list.
+ p_previous->next = p_current->next;
+
+ // If this is not the last timer, increment the next timer by this timer timeout.
+ p_current = p_previous->next;
+ if (p_current != NULL)
+ {
+ p_current->ticks_to_expire += timeout;
+ }
+
+ return (p_old_head != mp_timer_id_head);
+}
+
+
+/**@brief Function for scheduling a check for timeouts by generating a RTC1 interrupt.
+ */
+static void timer_timeouts_check_sched(void)
+{
+ NVIC_SetPendingIRQ(RTC1_IRQn);
+}
+
+
+/**@brief Function for scheduling a timer list update by generating a SWI interrupt.
+ */
+static void timer_list_handler_sched(void)
+{
+ NVIC_SetPendingIRQ(SWI_IRQn);
+}
+
+#if APP_TIMER_CONFIG_USE_SCHEDULER
+static void timeout_handler_scheduled_exec(void * p_event_data, uint16_t event_size)
+{
+ APP_ERROR_CHECK_BOOL(event_size == sizeof(app_timer_event_t));
+ app_timer_event_t const * p_timer_event = (app_timer_event_t *)p_event_data;
+
+ p_timer_event->timeout_handler(p_timer_event->p_context);
+}
+#endif
+
+/**@brief Function for executing an application timeout handler, either by calling it directly, or
+ * by passing an event to the @ref app_scheduler.
+ *
+ * @param[in] p_timer Pointer to expired timer.
+ */
+static void timeout_handler_exec(timer_node_t * p_timer)
+{
+#if APP_TIMER_CONFIG_USE_SCHEDULER
+ app_timer_event_t timer_event;
+
+ timer_event.timeout_handler = p_timer->p_timeout_handler;
+ timer_event.p_context = p_timer->p_context;
+ uint32_t err_code = app_sched_event_put(&timer_event, sizeof(timer_event), timeout_handler_scheduled_exec);
+ APP_ERROR_CHECK(err_code);
+#else
+ p_timer->p_timeout_handler(p_timer->p_context);
+#endif
+}
+
+
+/**@brief Function for checking for expired timers.
+ */
+static void timer_timeouts_check(void)
+{
+ // Handle expired of timer
+ if (mp_timer_id_head != NULL)
+ {
+ timer_node_t * p_timer;
+ timer_node_t * p_previous_timer;
+ uint32_t ticks_elapsed;
+ uint32_t ticks_expired;
+
+ // Initialize actual elapsed ticks being consumed to 0.
+ ticks_expired = 0;
+
+ // ticks_elapsed is collected here, job will use it.
+ ticks_elapsed = ticks_diff_get(rtc1_counter_get(), m_ticks_latest);
+
+ // Auto variable containing the head of timers expiring.
+ p_timer = mp_timer_id_head;
+
+ // Expire all timers within ticks_elapsed and collect ticks_expired.
+ while (p_timer != NULL)
+ {
+ // Do nothing if timer did not expire.
+ if (ticks_elapsed < p_timer->ticks_to_expire)
+ {
+ break;
+ }
+
+ // Decrement ticks_elapsed and collect expired ticks.
+ ticks_elapsed -= p_timer->ticks_to_expire;
+ ticks_expired += p_timer->ticks_to_expire;
+
+ // Move to next timer.
+ p_previous_timer = p_timer;
+ p_timer = p_timer->next;
+
+ // Execute Task.
+ if (p_previous_timer->is_running)
+ {
+ p_previous_timer->is_running = false;
+ timeout_handler_exec(p_previous_timer);
+ }
+ }
+
+ // Prepare to queue the ticks expired in the m_ticks_elapsed queue.
+ if (m_ticks_elapsed_q_read_ind == m_ticks_elapsed_q_write_ind)
+ {
+ // The read index of the queue is equal to the write index. This means the new
+ // value of ticks_expired should be stored at a new location in the m_ticks_elapsed
+ // queue (which is implemented as a double buffer).
+
+ // Check if there will be a queue overflow.
+ if (++m_ticks_elapsed_q_write_ind == CONTEXT_QUEUE_SIZE_MAX)
+ {
+ // There will be a queue overflow. Hence the write index should point to the start
+ // of the queue.
+ m_ticks_elapsed_q_write_ind = 0;
+ }
+ }
+
+ // Queue the ticks expired.
+ m_ticks_elapsed[m_ticks_elapsed_q_write_ind] = ticks_expired;
+
+ timer_list_handler_sched();
+ }
+}
+
+
+/**@brief Function for acquiring the number of ticks elapsed.
+ *
+ * @param[out] p_ticks_elapsed Number of ticks elapsed.
+ *
+ * @return TRUE if elapsed ticks was read from queue, FALSE otherwise.
+ */
+static bool elapsed_ticks_acquire(uint32_t * p_ticks_elapsed)
+{
+ // Pick the elapsed value from queue.
+ if (m_ticks_elapsed_q_read_ind != m_ticks_elapsed_q_write_ind)
+ {
+ // Dequeue elapsed value.
+ m_ticks_elapsed_q_read_ind++;
+ if (m_ticks_elapsed_q_read_ind == CONTEXT_QUEUE_SIZE_MAX)
+ {
+ m_ticks_elapsed_q_read_ind = 0;
+ }
+
+ *p_ticks_elapsed = m_ticks_elapsed[m_ticks_elapsed_q_read_ind];
+
+ m_ticks_latest += *p_ticks_elapsed;
+ m_ticks_latest &= MAX_RTC_COUNTER_VAL;
+
+ return true;
+ }
+ else
+ {
+ // No elapsed value in queue.
+ *p_ticks_elapsed = 0;
+ return false;
+ }
+}
+
+
+/**@brief Function for updating the timer list for expired timers.
+ *
+ * @param[in] ticks_elapsed Number of elapsed ticks.
+ * @param[in] ticks_previous Previous known value of the RTC counter.
+ * @param[out] p_restart_list_head List of repeating timers to be restarted.
+ */
+static void expired_timers_handler(uint32_t ticks_elapsed,
+ uint32_t ticks_previous,
+ timer_node_t ** p_restart_list_head)
+{
+ uint32_t ticks_expired = 0;
+
+ while (mp_timer_id_head != NULL)
+ {
+ timer_node_t * p_timer;
+ timer_node_t * p_timer_expired;
+
+ // Auto variable for current timer node.
+ p_timer = mp_timer_id_head;
+
+ // Do nothing if timer did not expire
+ if (ticks_elapsed < p_timer->ticks_to_expire)
+ {
+ p_timer->ticks_to_expire -= ticks_elapsed;
+ break;
+ }
+
+ // Decrement ticks_elapsed and collect expired ticks.
+ ticks_elapsed -= p_timer->ticks_to_expire;
+ ticks_expired += p_timer->ticks_to_expire;
+
+ // Timer expired, set ticks_to_expire zero.
+ p_timer->ticks_to_expire = 0;
+
+ // Remove the expired timer from head.
+ p_timer_expired = mp_timer_id_head;
+ mp_timer_id_head = p_timer->next;
+
+ // Timer will be restarted if periodic.
+ if (p_timer->ticks_periodic_interval != 0)
+ {
+ p_timer->ticks_at_start = (ticks_previous + ticks_expired) & MAX_RTC_COUNTER_VAL;
+ p_timer->ticks_first_interval = p_timer->ticks_periodic_interval;
+ p_timer->next = *p_restart_list_head;
+ *p_restart_list_head = p_timer_expired;
+ }
+ }
+}
+
+
+/**@brief Function for handling timer list insertions.
+ *
+ * @param[in] p_restart_list_head List of repeating timers to be restarted.
+ *
+ * @return TRUE if Capture Compare register must be updated, FALSE otherwise.
+ */
+static bool list_insertions_handler(timer_node_t * p_restart_list_head)
+{
+ bool compare_update = false;
+
+ timer_node_t * p_timer_id_old_head;
+
+ // Remember the old head, so as to decide if new compare needs to be set.
+ p_timer_id_old_head = mp_timer_id_head;
+
+ // Handle insertions of timers.
+ while ((p_restart_list_head != NULL) || (m_op_queue.first != m_op_queue.last))
+ {
+ timer_node_t * p_timer;
+
+ if (p_restart_list_head != NULL)
+ {
+ p_timer = p_restart_list_head;
+ p_restart_list_head = p_timer->next;
+ }
+ else
+ {
+ timer_user_op_t * p_user_op = &m_op_queue.user_op_queue[m_op_queue.first];
+
+ m_op_queue.first++;
+ if (m_op_queue.first == m_op_queue.size)
+ {
+ m_op_queue.first = 0;
+ }
+
+ p_timer = p_user_op->p_node;
+
+ switch (p_user_op->op_type)
+ {
+ case TIMER_USER_OP_TYPE_STOP:
+ // Delete node if timer is running.
+ if (timer_list_remove(p_user_op->p_node))
+ {
+ compare_update = true;
+ }
+
+ p_timer->is_running = false;
+ continue;
+
+ case TIMER_USER_OP_TYPE_STOP_ALL:
+ // Delete list of running timers, and mark all timers as not running.
+ while (mp_timer_id_head != NULL)
+ {
+ timer_node_t * p_head = mp_timer_id_head;
+
+ p_head->is_running = false;
+ mp_timer_id_head = p_head->next;
+ }
+ continue;
+ case TIMER_USER_OP_TYPE_START:
+ break;
+ default:
+ // No implementation needed.
+ continue;
+ }
+
+ if (p_timer->is_running)
+ {
+ continue;
+ }
+
+ p_timer->ticks_at_start = p_user_op->params.start.ticks_at_start;
+ p_timer->ticks_first_interval = p_user_op->params.start.ticks_first_interval;
+ p_timer->ticks_periodic_interval = p_user_op->params.start.ticks_periodic_interval;
+ p_timer->p_context = p_user_op->params.start.p_context;
+
+ if (m_rtc1_reset)
+ {
+ p_timer->ticks_at_start = 0;
+ }
+ }
+
+ // Prepare the node to be inserted.
+ if (
+ ((p_timer->ticks_at_start - m_ticks_latest) & MAX_RTC_COUNTER_VAL)
+ <
+ (MAX_RTC_COUNTER_VAL / 2)
+ )
+ {
+ p_timer->ticks_to_expire = ticks_diff_get(p_timer->ticks_at_start, m_ticks_latest) +
+ p_timer->ticks_first_interval;
+ }
+ else
+ {
+ uint32_t delta_current_start;
+
+ delta_current_start = ticks_diff_get(m_ticks_latest, p_timer->ticks_at_start);
+ if (p_timer->ticks_first_interval > delta_current_start)
+ {
+ p_timer->ticks_to_expire = p_timer->ticks_first_interval - delta_current_start;
+ }
+ else
+ {
+ p_timer->ticks_to_expire = 0;
+ }
+ }
+
+ p_timer->ticks_at_start = 0;
+ p_timer->ticks_first_interval = 0;
+ p_timer->is_running = true;
+ p_timer->next = NULL;
+
+ // Insert into list
+ timer_list_insert(p_timer);
+ }
+
+ return (compare_update || (mp_timer_id_head != p_timer_id_old_head));
+}
+
+
+/**@brief Function for updating the Capture Compare register.
+ */
+static void compare_reg_update(timer_node_t * p_timer_id_head_old)
+{
+ // Setup the timeout for timers on the head of the list
+ if (mp_timer_id_head != NULL)
+ {
+ uint32_t ticks_to_expire = mp_timer_id_head->ticks_to_expire;
+ uint32_t pre_counter_val = rtc1_counter_get();
+ uint32_t cc = m_ticks_latest;
+ uint32_t ticks_elapsed = ticks_diff_get(pre_counter_val, cc) + RTC_COMPARE_OFFSET_MIN;
+
+ if (!m_rtc1_running)
+ {
+ // No timers were already running, start RTC
+ rtc1_start();
+ }
+
+ cc += (ticks_elapsed < ticks_to_expire) ? ticks_to_expire : ticks_elapsed;
+ cc &= MAX_RTC_COUNTER_VAL;
+
+ rtc1_compare0_set(cc);
+
+ uint32_t post_counter_val = rtc1_counter_get();
+
+ if (
+ (ticks_diff_get(post_counter_val, pre_counter_val) + RTC_COMPARE_OFFSET_MIN)
+ >
+ ticks_diff_get(cc, pre_counter_val)
+ )
+ {
+ // When this happens the COMPARE event may not be triggered by the RTC.
+ // The nRF51 Series User Specification states that if the COUNTER value is N
+ // (i.e post_counter_val = N), writing N or N + 1 to a CC register may not trigger a
+ // COMPARE event. Hence the RTC interrupt is forcefully pended by calling the following
+ // function.
+ rtc1_compare0_set(rtc1_counter_get()); // this should prevent CC to fire again in the background while the code is in RTC-ISR
+ nrf_delay_us(MAX_RTC_TASKS_DELAY);
+ timer_timeouts_check_sched();
+ }
+ }
+ else
+ {
+#if (APP_TIMER_KEEPS_RTC_ACTIVE == 0)
+ // No timers are running, stop RTC
+ rtc1_stop();
+#endif //(APP_TIMER_KEEPS_RTC_ACTIVE == 0)
+ }
+}
+
+
+/**@brief Function for handling changes to the timer list.
+ */
+static void timer_list_handler(void)
+{
+ timer_node_t * p_restart_list_head = NULL;
+
+ uint32_t ticks_elapsed;
+ uint32_t ticks_previous;
+ bool ticks_have_elapsed;
+ bool compare_update = false;
+ timer_node_t * p_timer_id_head_old;
+
+#if APP_TIMER_WITH_PROFILER
+ {
+ uint8_t size = m_op_queue.size;
+ uint8_t first = m_op_queue.first;
+ uint8_t last = m_op_queue.last;
+ uint8_t utilization = (first <= last) ? (last - first) : (size + 1 - first + last);
+
+ if (utilization > m_max_user_op_queue_utilization)
+ {
+ m_max_user_op_queue_utilization = utilization;
+ }
+ }
+#endif
+
+ // Back up the previous known tick and previous list head
+ ticks_previous = m_ticks_latest;
+ p_timer_id_head_old = mp_timer_id_head;
+
+ // Get number of elapsed ticks
+ ticks_have_elapsed = elapsed_ticks_acquire(&ticks_elapsed);
+
+ // Handle expired timers
+ if (ticks_have_elapsed)
+ {
+ expired_timers_handler(ticks_elapsed, ticks_previous, &p_restart_list_head);
+ compare_update = true;
+ }
+
+
+ // Handle list insertions
+ if (list_insertions_handler(p_restart_list_head))
+ {
+ compare_update = true;
+ }
+
+ // Update compare register if necessary
+ if (compare_update)
+ {
+ compare_reg_update(p_timer_id_head_old);
+ }
+ m_rtc1_reset = false;
+}
+
+
+/**@brief Function for enqueueing a new operations queue entry.
+ *
+ * @param[in] last_index Index of the next last index to be enqueued.
+ */
+static void user_op_enque(uint8_t last_index)
+{
+ m_op_queue.last = last_index;
+}
+
+
+/**@brief Function for allocating a new operations queue entry.
+ *
+ * @param[out] p_last_index Index of the next last index to be enqueued.
+ *
+ * @return Pointer to allocated queue entry, or NULL if queue is full.
+ */
+static timer_user_op_t * user_op_alloc( uint8_t * p_last_index)
+{
+ uint8_t last;
+ timer_user_op_t * p_user_op;
+
+ last = m_op_queue.last + 1;
+ if (last == m_op_queue.size)
+ {
+ // Overflow case.
+ last = 0;
+ }
+ if (last == m_op_queue.first)
+ {
+ // Queue is full.
+ return NULL;
+ }
+
+ *p_last_index = last;
+ p_user_op = &m_op_queue.user_op_queue[m_op_queue.last];
+
+ return p_user_op;
+}
+
+
+/**@brief Function for scheduling a Timer Start operation.
+ *
+ * @param[in] timer_id Id of timer to start.
+ * @param[in] timeout_initial Time (in ticks) to first timer expiry.
+ * @param[in] timeout_periodic Time (in ticks) between periodic expiries.
+ * @param[in] p_context General purpose pointer. Will be passed to the timeout handler when
+ * the timer expires.
+ * @return NRF_SUCCESS on success, otherwise an error code.
+ */
+
+static uint32_t timer_start_op_schedule(timer_node_t * p_node,
+ uint32_t timeout_initial,
+ uint32_t timeout_periodic,
+ void * p_context)
+{
+ uint8_t last_index;
+ uint32_t err_code = NRF_SUCCESS;
+
+ CRITICAL_REGION_ENTER();
+ timer_user_op_t * p_user_op = user_op_alloc(&last_index);
+ if (p_user_op == NULL)
+ {
+ err_code = NRF_ERROR_NO_MEM;
+ }
+ else
+ {
+ p_user_op->op_type = TIMER_USER_OP_TYPE_START;
+ p_user_op->p_node = p_node;
+ p_user_op->params.start.ticks_at_start = rtc1_counter_get();
+ p_user_op->params.start.ticks_first_interval = timeout_initial;
+ p_user_op->params.start.ticks_periodic_interval = timeout_periodic;
+ p_user_op->params.start.p_context = p_context;
+
+ user_op_enque(last_index);
+ }
+ CRITICAL_REGION_EXIT();
+
+ if (err_code == NRF_SUCCESS)
+ {
+ timer_list_handler_sched();
+ }
+
+ return err_code;
+}
+
+
+/**@brief Function for scheduling a Timer Stop operation.
+ *
+ * @param[in] timer_id Id of timer to stop.
+ * @param[in] op_type Type of stop operation
+ *
+ * @return NRF_SUCCESS on successful scheduling a timer stop operation. NRF_ERROR_NO_MEM when there
+ * is no memory left to schedule the timer stop operation.
+ */
+static uint32_t timer_stop_op_schedule(timer_node_t * p_node,
+ timer_user_op_type_t op_type)
+{
+ uint8_t last_index;
+ uint32_t err_code = NRF_SUCCESS;
+
+ CRITICAL_REGION_ENTER();
+ timer_user_op_t * p_user_op = user_op_alloc(&last_index);
+ if (p_user_op == NULL)
+ {
+ err_code = NRF_ERROR_NO_MEM;
+ }
+ else
+ {
+ p_user_op->op_type = op_type;
+ p_user_op->p_node = p_node;
+
+ user_op_enque(last_index);
+ }
+ CRITICAL_REGION_EXIT();
+
+ if (err_code == NRF_SUCCESS)
+ {
+ timer_list_handler_sched();
+ }
+
+ return err_code;
+}
+
+/**@brief Function for handling the RTC1 interrupt.
+ *
+ * @details Checks for timeouts, and executes timeout handlers for expired timers.
+ */
+void RTC1_IRQHandler(void)
+{
+ // Clear all events (also unexpected ones)
+ NRF_RTC1->EVENTS_COMPARE[0] = 0;
+ NRF_RTC1->EVENTS_COMPARE[1] = 0;
+ NRF_RTC1->EVENTS_COMPARE[2] = 0;
+ NRF_RTC1->EVENTS_COMPARE[3] = 0;
+ NRF_RTC1->EVENTS_TICK = 0;
+ NRF_RTC1->EVENTS_OVRFLW = 0;
+
+ // Check for expired timers
+ timer_timeouts_check();
+}
+
+
+/**@brief Function for handling the SWI interrupt.
+ *
+ * @details Performs all updates to the timer list.
+ */
+void SWI_IRQHandler(void)
+{
+ timer_list_handler();
+}
+
+
+ret_code_t app_timer_init(void)
+{
+ // Stop RTC to prevent any running timers from expiring (in case of reinitialization)
+ rtc1_stop();
+
+ // Initialize operation queue
+ m_op_queue.first = 0;
+ m_op_queue.last = 0;
+ m_op_queue.size = APP_TIMER_CONFIG_OP_QUEUE_SIZE+1;
+
+ mp_timer_id_head = NULL;
+ m_ticks_elapsed_q_read_ind = 0;
+ m_ticks_elapsed_q_write_ind = 0;
+
+#if APP_TIMER_WITH_PROFILER
+ m_max_user_op_queue_utilization = 0;
+#endif
+
+ NVIC_ClearPendingIRQ(SWI_IRQn);
+ NVIC_SetPriority(SWI_IRQn, SWI_IRQ_PRI);
+ NVIC_EnableIRQ(SWI_IRQn);
+
+ rtc1_init(APP_TIMER_CONFIG_RTC_FREQUENCY);
+
+ m_ticks_latest = rtc1_counter_get();
+
+ return NRF_SUCCESS;
+}
+
+
+ret_code_t app_timer_create(app_timer_id_t const * p_timer_id,
+ app_timer_mode_t mode,
+ app_timer_timeout_handler_t timeout_handler)
+{
+ // Check state and parameters
+ VERIFY_MODULE_INITIALIZED();
+
+ if (timeout_handler == NULL)
+ {
+ return NRF_ERROR_INVALID_PARAM;
+ }
+ if (p_timer_id == NULL)
+ {
+ return NRF_ERROR_INVALID_PARAM;
+ }
+ if (((timer_node_t*)*p_timer_id)->is_running)
+ {
+ return NRF_ERROR_INVALID_STATE;
+ }
+
+ timer_node_t * p_node = (timer_node_t *)*p_timer_id;
+ p_node->is_running = false;
+ p_node->mode = mode;
+ p_node->p_timeout_handler = timeout_handler;
+ return NRF_SUCCESS;
+}
+
+ret_code_t app_timer_start(app_timer_id_t timer_id, uint32_t timeout_ticks, void * p_context)
+{
+ uint32_t timeout_periodic;
+ timer_node_t * p_node = (timer_node_t*)timer_id;
+
+ // Check state and parameters
+ VERIFY_MODULE_INITIALIZED();
+
+ if (timer_id == 0)
+ {
+ return NRF_ERROR_INVALID_STATE;
+ }
+ if (timeout_ticks < APP_TIMER_MIN_TIMEOUT_TICKS)
+ {
+ return NRF_ERROR_INVALID_PARAM;
+ }
+ if (p_node->p_timeout_handler == NULL)
+ {
+ return NRF_ERROR_INVALID_STATE;
+ }
+
+ // Schedule timer start operation
+ timeout_periodic = (p_node->mode == APP_TIMER_MODE_REPEATED) ? timeout_ticks : 0;
+
+ return timer_start_op_schedule(p_node,
+ timeout_ticks,
+ timeout_periodic,
+ p_context);
+}
+
+
+ret_code_t app_timer_stop(app_timer_id_t timer_id)
+{
+ timer_node_t * p_node = (timer_node_t*)timer_id;
+ // Check state and parameters
+ VERIFY_MODULE_INITIALIZED();
+
+ if ((timer_id == NULL) || (p_node->p_timeout_handler == NULL))
+ {
+ return NRF_ERROR_INVALID_STATE;
+ }
+
+ p_node->is_running = false;
+
+ // Schedule timer stop operation
+ return timer_stop_op_schedule(p_node, TIMER_USER_OP_TYPE_STOP);
+}
+
+
+ret_code_t app_timer_stop_all(void)
+{
+ // Check state
+ VERIFY_MODULE_INITIALIZED();
+
+ return timer_stop_op_schedule(NULL, TIMER_USER_OP_TYPE_STOP_ALL);
+}
+
+
+uint32_t app_timer_cnt_get(void)
+{
+ return rtc1_counter_get();
+}
+
+
+uint32_t app_timer_cnt_diff_compute(uint32_t ticks_to,
+ uint32_t ticks_from)
+{
+ return ticks_diff_get(ticks_to, ticks_from);
+}
+
+#if APP_TIMER_WITH_PROFILER
+uint8_t app_timer_op_queue_utilization_get(void)
+{
+ return m_max_user_op_queue_utilization;
+}
+#endif
+
+void app_timer_pause(void)
+{
+ NRF_RTC1->TASKS_STOP = 1;
+}
+
+void app_timer_resume(void)
+{
+ NRF_RTC1->TASKS_START = 1;
+}
+
+#endif //NRF_MODULE_ENABLED(APP_TIMER)
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/timer/app_timer.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/timer/app_timer.h
new file mode 100644
index 0000000..64540a9
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/timer/app_timer.h
@@ -0,0 +1,313 @@
+/**
+ * Copyright (c) 2012 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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
+ *
+ * @defgroup app_timer Application Timer
+ * @{
+ * @ingroup app_common
+ *
+ * @brief Application timer functionality.
+ *
+ * @details This module enables the application to create multiple timer instances based on the RTC1
+ * peripheral. Checking for time-outs and invocation of user time-out handlers is performed
+ * in the RTC1 interrupt handler. List handling is done using a software interrupt (SWI0).
+ * Both interrupt handlers are running in APP_LOW priority level.
+ *
+ * @details When calling app_timer_start() or app_timer_stop(), the timer operation is just queued,
+ * and the software interrupt is triggered. The actual timer start/stop operation is
+ * executed by the SWI0 interrupt handler. Since the SWI0 interrupt is running in APP_LOW,
+ * if the application code calling the timer function is running in APP_LOW or APP_HIGH,
+ * the timer operation will not be performed until the application handler has returned.
+ * This will be the case, for example, when stopping a timer from a time-out handler when not using
+ * the scheduler.
+ *
+ * @details Use the USE_SCHEDULER parameter of the APP_TIMER_INIT() macro to select if the
+ * @ref app_scheduler should be used or not. Even if the scheduler is
+ * not used, app_timer.h will include app_scheduler.h, so when
+ * compiling, app_scheduler.h must be available in one of the compiler include paths.
+ */
+
+#ifndef APP_TIMER_H__
+#define APP_TIMER_H__
+#include "sdk_config.h"
+#include "app_error.h"
+#include "app_util.h"
+#include "compiler_abstraction.h"
+#include "nordic_common.h"
+#ifdef APP_TIMER_V2
+#include "nrf_log_instance.h"
+#include "nrf_sortlist.h"
+#endif
+#include <stdint.h>
+#include <stdbool.h>
+#include <stdio.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** @brief Name of the module used for logger messaging.
+ */
+#define APP_TIMER_LOG_NAME app_timer
+
+#define APP_TIMER_CLOCK_FREQ 32768 /**< Clock frequency of the RTC timer used to implement the app timer module. */
+#define APP_TIMER_MIN_TIMEOUT_TICKS 5 /**< Minimum value of the timeout_ticks parameter of app_timer_start(). */
+
+#ifdef RTX
+#define APP_TIMER_NODE_SIZE 40 /**< Size of app_timer.timer_node_t (used to allocate data). */
+#else
+#define APP_TIMER_NODE_SIZE 32 /**< Size of app_timer.timer_node_t (used to allocate data). */
+#endif // RTX
+
+#define APP_TIMER_SCHED_EVENT_DATA_SIZE sizeof(app_timer_event_t) /**< Size of event data when scheduler is used. */
+
+#define APP_TIMER_MAX_CNT_VAL RTC_COUNTER_COUNTER_Msk /**< Maximum counter value that can be returned by @ref app_timer_cnt_get. */
+
+/**@brief Convert milliseconds to timer ticks.
+ *
+ * This macro uses 64-bit integer arithmetic, but as long as the macro parameters are
+ * constants (i.e. defines), the computation will be done by the preprocessor.
+ *
+ * @param[in] MS Milliseconds.
+ *
+ * @return Number of timer ticks.
+ */
+#ifndef FREERTOS
+#define APP_TIMER_TICKS(MS) \
+ ((uint32_t)ROUNDED_DIV( \
+ (MS) * (uint64_t)APP_TIMER_CLOCK_FREQ, \
+ 1000 * (APP_TIMER_CONFIG_RTC_FREQUENCY + 1)))
+#else
+#include "FreeRTOSConfig.h"
+#define APP_TIMER_TICKS(MS) (uint32_t)ROUNDED_DIV((MS)*configTICK_RATE_HZ,1000)
+#endif
+
+
+/**
+ * @brief Create a timer identifier and statically allocate memory for the timer.
+ *
+ * @param timer_id Name of the timer identifier variable that will be used to control the timer.
+ */
+#define APP_TIMER_DEF(timer_id) _APP_TIMER_DEF(timer_id)
+
+/**@brief Application time-out handler type. */
+typedef void (*app_timer_timeout_handler_t)(void * p_context);
+
+#ifdef APP_TIMER_V2
+/**
+ * @brief app_timer control block
+ */
+typedef struct
+{
+ nrf_sortlist_item_t list_item; /**< Token used by sortlist. */
+ volatile uint32_t end_val; /**< RTC counter value when timer expires. */
+ uint32_t repeat_period; /**< Repeat period (0 if single shot mode). */
+ app_timer_timeout_handler_t handler; /**< User handler. */
+ void * p_context; /**< User context. */
+ NRF_LOG_INSTANCE_PTR_DECLARE(p_log) /**< Pointer to instance of the logger object (Conditionally compiled). */
+ volatile bool active; /**< Flag indicating that timer is active. */
+} app_timer_t;
+
+/**@brief Timer ID type.
+ * Never declare a variable of this type, but use the macro @ref APP_TIMER_DEF instead.*/
+typedef app_timer_t * app_timer_id_t;
+
+#define _APP_TIMER_DEF(timer_id) \
+ NRF_LOG_INSTANCE_REGISTER(APP_TIMER_LOG_NAME, timer_id, \
+ APP_TIMER_CONFIG_INFO_COLOR, \
+ APP_TIMER_CONFIG_DEBUG_COLOR, \
+ APP_TIMER_CONFIG_INITIAL_LOG_LEVEL, \
+ APP_TIMER_CONFIG_LOG_ENABLED ? \
+ APP_TIMER_CONFIG_LOG_LEVEL : NRF_LOG_SEVERITY_NONE); \
+ static app_timer_t CONCAT_2(timer_id,_data) = { \
+ .active = false, \
+ NRF_LOG_INSTANCE_PTR_INIT(p_log, APP_TIMER_LOG_NAME, timer_id) \
+ }; \
+ static const app_timer_id_t timer_id = &CONCAT_2(timer_id,_data)
+
+#else //APP_TIMER_V2
+typedef struct app_timer_t { uint32_t data[CEIL_DIV(APP_TIMER_NODE_SIZE, sizeof(uint32_t))]; } app_timer_t;
+
+/**@brief Timer ID type.
+ * Never declare a variable of this type, but use the macro @ref APP_TIMER_DEF instead.*/
+typedef app_timer_t * app_timer_id_t;
+
+#define _APP_TIMER_DEF(timer_id) \
+ static app_timer_t CONCAT_2(timer_id,_data) = { {0} }; \
+ static const app_timer_id_t timer_id = &CONCAT_2(timer_id,_data)
+
+#endif
+
+
+/**@brief Structure passed to app_scheduler. */
+typedef struct
+{
+ app_timer_timeout_handler_t timeout_handler;
+ void * p_context;
+} app_timer_event_t;
+
+/**@brief Timer modes. */
+typedef enum
+{
+ APP_TIMER_MODE_SINGLE_SHOT, /**< The timer will expire only once. */
+ APP_TIMER_MODE_REPEATED /**< The timer will restart each time it expires. */
+} app_timer_mode_t;
+
+/**@brief Function for initializing the timer module.
+ *
+ * @retval NRF_SUCCESS If the module was initialized successfully.
+ */
+ret_code_t app_timer_init(void);
+
+/**@brief Function for creating a timer instance.
+ *
+ * @param[in] p_timer_id Pointer to timer identifier.
+ * @param[in] mode Timer mode.
+ * @param[in] timeout_handler Function to be executed when the timer expires.
+ *
+ * @retval NRF_SUCCESS If the timer was successfully created.
+ * @retval NRF_ERROR_INVALID_PARAM If a parameter was invalid.
+ * @retval NRF_ERROR_INVALID_STATE If the application timer module has not been initialized or
+ * the timer is running.
+ *
+ * @note This function does the timer allocation in the caller's context. It is also not protected
+ * by a critical region. Therefore care must be taken not to call it from several interrupt
+ * levels simultaneously.
+ * @note The function can be called again on the timer instance and will re-initialize the instance if
+ * the timer is not running.
+ * @attention The FreeRTOS and RTX app_timer implementation does not allow app_timer_create to
+ * be called on the previously initialized instance.
+ */
+ret_code_t app_timer_create(app_timer_id_t const * p_timer_id,
+ app_timer_mode_t mode,
+ app_timer_timeout_handler_t timeout_handler);
+
+/**@brief Function for starting a timer.
+ *
+ * @param[in] timer_id Timer identifier.
+ * @param[in] timeout_ticks Number of ticks (of RTC1, including prescaling) to time-out event
+ * (minimum 5 ticks).
+ * @param[in] p_context General purpose pointer. Will be passed to the time-out handler when
+ * the timer expires.
+ *
+ * @retval NRF_SUCCESS If the timer was successfully started.
+ * @retval NRF_ERROR_INVALID_PARAM If a parameter was invalid.
+ * @retval NRF_ERROR_INVALID_STATE If the application timer module has not been initialized or the timer
+ * has not been created.
+ * @retval NRF_ERROR_NO_MEM If the timer operations queue was full.
+ *
+ * @note The minimum timeout_ticks value is 5.
+ * @note For multiple active timers, time-outs occurring in close proximity to each other (in the
+ * range of 1 to 3 ticks) will have a positive jitter of maximum 3 ticks.
+ * @note When calling this method on a timer that is already running, the second start operation
+ * is ignored.
+ */
+ret_code_t app_timer_start(app_timer_id_t timer_id, uint32_t timeout_ticks, void * p_context);
+
+/**@brief Function for stopping the specified timer.
+ *
+ * @param[in] timer_id Timer identifier.
+ *
+ * @retval NRF_SUCCESS If the timer was successfully stopped.
+ * @retval NRF_ERROR_INVALID_PARAM If a parameter was invalid.
+ * @retval NRF_ERROR_INVALID_STATE If the application timer module has not been initialized or the timer
+ * has not been created.
+ * @retval NRF_ERROR_NO_MEM If the timer operations queue was full.
+ */
+ret_code_t app_timer_stop(app_timer_id_t timer_id);
+
+/**@brief Function for stopping all running timers.
+ *
+ * @retval NRF_SUCCESS If all timers were successfully stopped.
+ * @retval NRF_ERROR_INVALID_STATE If the application timer module has not been initialized.
+ * @retval NRF_ERROR_NO_MEM If the timer operations queue was full.
+ */
+ret_code_t app_timer_stop_all(void);
+
+/**@brief Function for returning the current value of the RTC1 counter.
+ *
+ * @return Current value of the RTC1 counter.
+ */
+uint32_t app_timer_cnt_get(void);
+
+/**@brief Function for computing the difference between two RTC1 counter values.
+ *
+ * @param[in] ticks_to Value returned by app_timer_cnt_get().
+ * @param[in] ticks_from Value returned by app_timer_cnt_get().
+ *
+ * @return Number of ticks from ticks_from to ticks_to.
+ */
+uint32_t app_timer_cnt_diff_compute(uint32_t ticks_to,
+ uint32_t ticks_from);
+
+
+/**@brief Function for getting the maximum observed operation queue utilization.
+ *
+ * Function for tuning the module and determining OP_QUEUE_SIZE value and thus module RAM usage.
+ *
+ * @note APP_TIMER_WITH_PROFILER must be enabled to use this functionality.
+ *
+ * @return Maximum number of events in queue observed so far.
+ */
+uint8_t app_timer_op_queue_utilization_get(void);
+
+/**
+ * @brief Function for pausing RTC activity which drives app_timer.
+ *
+ * @note This function can be used for debugging purposes to ensure
+ * that application is halted when entering a breakpoint.
+ */
+void app_timer_pause(void);
+
+/**
+ * @brief Function for resuming RTC activity which drives app_timer.
+ *
+ * @note This function can be used for debugging purposes to resume
+ * application activity.
+ */
+void app_timer_resume(void);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // APP_TIMER_H__
+
+/** @} */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/timer/app_timer_freertos.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/timer/app_timer_freertos.c
new file mode 100644
index 0000000..bea64fd
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/timer/app_timer_freertos.c
@@ -0,0 +1,241 @@
+/**
+ * Copyright (c) 2014 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#include "sdk_common.h"
+#if NRF_MODULE_ENABLED(APP_TIMER)
+#include "FreeRTOS.h"
+#include "task.h"
+#include "timers.h"
+
+#include "app_timer.h"
+#include <stdlib.h>
+#include <string.h>
+#include "nrf.h"
+#include "app_error.h"
+
+/**
+ * Note that this implementation is made only for enable SDK components which interacts with app_timer to work with FreeRTOS.
+ * It is more suitable to use native FreeRTOS timer for other purposes.
+ */
+/* Check if RTC FreeRTOS version is used */
+#if configTICK_SOURCE != FREERTOS_USE_RTC
+#error app_timer in FreeRTOS variant have to be used with RTC tick source configuration. Default configuration have to be used in other case.
+#endif
+
+/**
+ * @brief Waiting time for the timer queue
+ *
+ * Number of system ticks to wait for the timer queue to put the message.
+ * It is strongly recommended to set this to the value bigger than 1.
+ * In other case if timer message queue is full - any operation on timer may fail.
+ * @note
+ * Timer functions called from interrupt context would never wait.
+ */
+#define APP_TIMER_WAIT_FOR_QUEUE 2
+
+/**@brief This structure keeps information about osTimer.*/
+typedef struct
+{
+ void * argument;
+ TimerHandle_t osHandle;
+ app_timer_timeout_handler_t func;
+ /**
+ * This member is to make sure that timer function is only called if timer is running.
+ * FreeRTOS may have timer running even after stop function is called,
+ * because it processes commands in Timer task and stopping function only puts command into the queue. */
+ bool active;
+}app_timer_info_t;
+
+
+/* Check if freeRTOS timers are activated */
+#if configUSE_TIMERS == 0
+ #error app_timer for freeRTOS requires configUSE_TIMERS option to be activated.
+#endif
+
+/* Check if app_timer_t variable type can held our app_timer_info_t structure */
+STATIC_ASSERT(sizeof(app_timer_info_t) <= sizeof(app_timer_t));
+
+
+/**
+ * @brief Internal callback function for the system timer
+ *
+ * Internal function that is called from the system timer.
+ * It gets our parameter from timer data and sends it to user function.
+ * @param[in] xTimer Timer handler
+ */
+static void app_timer_callback(TimerHandle_t xTimer)
+{
+ app_timer_info_t * pinfo = (app_timer_info_t*)(pvTimerGetTimerID(xTimer));
+ ASSERT(pinfo->osHandle == xTimer);
+ ASSERT(pinfo->func != NULL);
+
+ if (pinfo->active)
+ pinfo->func(pinfo->argument);
+}
+
+
+uint32_t app_timer_init(void)
+{
+ return NRF_SUCCESS;
+}
+
+
+uint32_t app_timer_create(app_timer_id_t const * p_timer_id,
+ app_timer_mode_t mode,
+ app_timer_timeout_handler_t timeout_handler)
+{
+ app_timer_info_t * pinfo = (app_timer_info_t*)(*p_timer_id);
+ uint32_t err_code = NRF_SUCCESS;
+ unsigned long timer_mode;
+
+ if ((timeout_handler == NULL) || (p_timer_id == NULL))
+ {
+ return NRF_ERROR_INVALID_PARAM;
+ }
+ if (pinfo->active)
+ {
+ return NRF_ERROR_INVALID_STATE;
+ }
+
+ if (pinfo->osHandle == NULL)
+ {
+ /* New timer is created */
+ memset(pinfo, 0, sizeof(app_timer_info_t));
+
+ if (mode == APP_TIMER_MODE_SINGLE_SHOT)
+ timer_mode = pdFALSE;
+ else
+ timer_mode = pdTRUE;
+
+ pinfo->func = timeout_handler;
+ pinfo->osHandle = xTimerCreate(" ", 1000, timer_mode, pinfo, app_timer_callback);
+
+ if (pinfo->osHandle == NULL)
+ err_code = NRF_ERROR_NULL;
+ }
+ else
+ {
+ /* Timer cannot be reinitialized using FreeRTOS API */
+ return NRF_ERROR_INVALID_STATE;
+ }
+
+ return err_code;
+}
+
+
+uint32_t app_timer_start(app_timer_id_t timer_id, uint32_t timeout_ticks, void * p_context)
+{
+ app_timer_info_t * pinfo = (app_timer_info_t*)(timer_id);
+ TimerHandle_t hTimer = pinfo->osHandle;
+
+ if (hTimer == NULL)
+ {
+ return NRF_ERROR_INVALID_STATE;
+ }
+ if (pinfo->active && (xTimerIsTimerActive(hTimer) != pdFALSE))
+ {
+ // Timer already running - exit silently
+ return NRF_SUCCESS;
+ }
+
+ pinfo->argument = p_context;
+
+ if (__get_IPSR() != 0)
+ {
+ BaseType_t yieldReq = pdFALSE;
+ if (xTimerChangePeriodFromISR(hTimer, timeout_ticks, &yieldReq) != pdPASS)
+ {
+ return NRF_ERROR_NO_MEM;
+ }
+
+ if ( xTimerStartFromISR(hTimer, &yieldReq) != pdPASS )
+ {
+ return NRF_ERROR_NO_MEM;
+ }
+
+ portYIELD_FROM_ISR(yieldReq);
+ }
+ else
+ {
+ if (xTimerChangePeriod(hTimer, timeout_ticks, APP_TIMER_WAIT_FOR_QUEUE) != pdPASS)
+ {
+ return NRF_ERROR_NO_MEM;
+ }
+
+ if (xTimerStart(hTimer, APP_TIMER_WAIT_FOR_QUEUE) != pdPASS)
+ {
+ return NRF_ERROR_NO_MEM;
+ }
+ }
+
+ pinfo->active = true;
+ return NRF_SUCCESS;
+}
+
+
+uint32_t app_timer_stop(app_timer_id_t timer_id)
+{
+ app_timer_info_t * pinfo = (app_timer_info_t*)(timer_id);
+ TimerHandle_t hTimer = pinfo->osHandle;
+ if (hTimer == NULL)
+ {
+ return NRF_ERROR_INVALID_STATE;
+ }
+
+ if (__get_IPSR() != 0)
+ {
+ BaseType_t yieldReq = pdFALSE;
+ if (xTimerStopFromISR(hTimer, &yieldReq) != pdPASS)
+ {
+ return NRF_ERROR_NO_MEM;
+ }
+ portYIELD_FROM_ISR(yieldReq);
+ }
+ else
+ {
+ if (xTimerStop(hTimer, APP_TIMER_WAIT_FOR_QUEUE) != pdPASS)
+ {
+ return NRF_ERROR_NO_MEM;
+ }
+ }
+
+ pinfo->active = false;
+ return NRF_SUCCESS;
+}
+#endif //NRF_MODULE_ENABLED(APP_TIMER)
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/timer/app_timer_rtx.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/timer/app_timer_rtx.c
new file mode 100644
index 0000000..b12982f
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/timer/app_timer_rtx.c
@@ -0,0 +1,278 @@
+/**
+ * Copyright (c) 2016 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#include "sdk_common.h"
+#if NRF_MODULE_ENABLED(APP_TIMER)
+#include "app_timer.h"
+#include <stdlib.h>
+#include "nrf.h"
+#include "nrf_soc.h"
+#include "app_error.h"
+#include "cmsis_os.h"
+#include "app_util_platform.h"
+
+#define RTC1_IRQ_PRI APP_IRQ_PRIORITY_LOWEST /**< Priority of the RTC1 interrupt. */
+
+#define MAX_RTC_COUNTER_VAL 0x00FFFFFF /**< Maximum value of the RTC counter. */
+
+/**@brief This structure keeps information about osTimer.*/
+typedef struct
+{
+ osTimerDef_t timerDef;
+ uint32_t buffer[6];
+ osTimerId id;
+}app_timer_info_t;
+
+/**@brief Store an array of timers with configuration. */
+typedef struct
+{
+ uint8_t max_timers; /**< The maximum number of timers*/
+ uint32_t prescaler;
+ app_timer_info_t * app_timers; /**< Pointer to table of timers*/
+}app_timer_control_t;
+
+app_timer_control_t app_timer_control;
+
+/**@brief This structure is defined by RTX. It keeps information about created osTimers. It is used in app_timer_start(). */
+typedef struct os_timer_cb_
+{
+ struct os_timer_cb_ * next; /**< Pointer to next active Timer */
+ uint8_t state; /**< Timer State */
+ uint8_t type; /**< Timer Type (Periodic/One-shot). */
+ uint16_t reserved; /**< Reserved. */
+ uint32_t tcnt; /**< Timer Delay Count. */
+ uint32_t icnt; /**< Timer Initial Count. */
+ void * arg; /**< Timer Function Argument. */
+ const osTimerDef_t * timer; /**< Pointer to Timer definition. */
+} os_timer_cb;
+
+/**@brief This functions are defined by RTX.*/
+//lint --save -e10 -e19 -e526
+extern osStatus svcTimerStop(osTimerId timer_id); /**< Used in app_timer_stop(). */
+extern osStatus svcTimerStart(osTimerId timer_id, uint32_t millisec); /**< Used in app_timer_start(). */
+// lint --restore
+static void * rt_id2obj (void *id) /**< Used in app_timer_start(). This function gives information if osTimerID is valid */
+{
+ if ((uint32_t)id & 3U)
+ {
+ return NULL;
+ }
+
+#ifdef OS_SECTIONS_LINK_INFO
+
+ if ((os_section_id$$Base != 0U) && (os_section_id$$Limit != 0U))
+ {
+ if (id < (void *)os_section_id$$Base)
+ {
+ return NULL;
+ }
+
+ if (id >= (void *)os_section_id$$Limit)
+ {
+ return NULL;
+ }
+ }
+#endif
+
+ return id;
+}
+
+
+
+ret_code_t app_timer_init(void)
+{
+ if (p_buffer == NULL)
+ {
+ return NRF_ERROR_INVALID_PARAM;
+ }
+
+ app_timer_control.app_timers = p_buffer;
+ NVIC_SetPriority(RTC1_IRQn, RTC1_IRQ_PRI);
+
+ return NRF_SUCCESS;
+}
+
+
+ret_code_t app_timer_create(app_timer_id_t const * p_timer_id,
+ app_timer_mode_t mode,
+ app_timer_timeout_handler_t timeout_handler)
+{
+
+ if ((timeout_handler == NULL) || (p_timer_id == NULL))
+ {
+ return NRF_ERROR_INVALID_PARAM;
+ }
+
+ app_timer_info_t * p_timer_info = (app_timer_info_t *)*p_timer_id;
+ p_timer_info->timerDef.timer = p_timer_info->buffer;
+ p_timer_info->timerDef.ptimer = (os_ptimer)timeout_handler;
+
+ p_timer_info->id = osTimerCreate(&(p_timer_info->timerDef), (os_timer_type)mode, NULL);
+
+ if (p_timer_info->id)
+ return NRF_SUCCESS;
+ else
+ {
+ return NRF_ERROR_INVALID_PARAM; // This error is unspecified by rtx
+ }
+}
+
+#define osTimerRunning 2
+ret_code_t app_timer_start(app_timer_id_t timer_id, uint32_t timeout_ticks, void * p_context)
+{
+ if ((timeout_ticks < APP_TIMER_MIN_TIMEOUT_TICKS))
+ {
+ return NRF_ERROR_INVALID_PARAM;
+ }
+ uint32_t timeout_ms =
+ ((uint32_t)ROUNDED_DIV(timeout_ticks * 1000 * (APP_TIMER_CONFIG_RTC_FREQUENCY + 1),
+ (uint32_t)APP_TIMER_CLOCK_FREQ));
+
+ app_timer_info_t * p_timer_info = (app_timer_info_t *)timer_id;
+ if (rt_id2obj((void *)p_timer_info->id) == NULL)
+ return NRF_ERROR_INVALID_PARAM;
+
+ // Pass p_context to timer_timeout_handler
+ ((os_timer_cb *)(p_timer_info->id))->arg = p_context;
+
+ if (((os_timer_cb *)(p_timer_info->id))->state == osTimerRunning)
+ {
+ return NRF_SUCCESS;
+ }
+ // osTimerStart() returns osErrorISR if it is called in interrupt routine.
+ switch (osTimerStart((osTimerId)p_timer_info->id, timeout_ms) )
+ {
+ case osOK:
+ return NRF_SUCCESS;
+
+ case osErrorISR:
+ break;
+
+ case osErrorParameter:
+ return NRF_ERROR_INVALID_PARAM;
+
+ default:
+ return NRF_ERROR_INVALID_PARAM;
+ }
+
+ // Start timer without svcCall
+ switch (svcTimerStart((osTimerId)p_timer_info->id, timeout_ms))
+ {
+ case osOK:
+ return NRF_SUCCESS;
+
+ case osErrorISR:
+ return NRF_ERROR_INVALID_STATE;
+
+ case osErrorParameter:
+ return NRF_ERROR_INVALID_PARAM;
+
+ default:
+ return NRF_ERROR_INVALID_PARAM;
+ }
+}
+
+ret_code_t app_timer_stop(app_timer_id_t timer_id)
+{
+ app_timer_info_t * p_timer_info = (app_timer_info_t *)timer_id;
+ switch (osTimerStop((osTimerId)p_timer_info->id) )
+ {
+ case osOK:
+ return NRF_SUCCESS;
+
+ case osErrorISR:
+ break;
+
+ case osErrorParameter:
+ return NRF_ERROR_INVALID_PARAM;
+
+ case osErrorResource:
+ return NRF_SUCCESS;
+
+ default:
+ return NRF_ERROR_INVALID_PARAM;
+ }
+
+ // Stop timer without svcCall
+ switch (svcTimerStop((osTimerId)p_timer_info->id))
+ {
+ case osOK:
+ return NRF_SUCCESS;
+
+ case osErrorISR:
+ return NRF_ERROR_INVALID_STATE;
+
+ case osErrorParameter:
+ return NRF_ERROR_INVALID_PARAM;
+
+ case osErrorResource:
+ return NRF_SUCCESS;
+
+ default:
+ return NRF_ERROR_INVALID_PARAM;
+ }
+}
+
+
+ret_code_t app_timer_stop_all(void)
+{
+ for (int i = 0; i < app_timer_control.max_timers; i++)
+ {
+ if (app_timer_control.app_timers[i].id)
+ {
+ (void)app_timer_stop((app_timer_id_t)app_timer_control.app_timers[i].id);
+ }
+ }
+ return 0;
+}
+
+
+extern uint32_t os_tick_val(void);
+uint32_t app_timer_cnt_get(void)
+{
+ return os_tick_val();
+}
+
+
+uint32_t app_timer_cnt_diff_compute(uint32_t ticks_to,
+ uint32_t ticks_from)
+{
+ return ((ticks_to - ticks_from) & MAX_RTC_COUNTER_VAL);
+}
+#endif //NRF_MODULE_ENABLED(APP_TIMER)
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/timer/experimental/app_timer2.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/timer/experimental/app_timer2.c
new file mode 100644
index 0000000..aefdb51
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/timer/experimental/app_timer2.c
@@ -0,0 +1,568 @@
+/**
+ * Copyright (c) 2018 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#include "app_timer.h"
+#include "nrf_atfifo.h"
+#include "nrf_sortlist.h"
+#include "nrf_delay.h"
+#if APP_TIMER_CONFIG_USE_SCHEDULER
+#include "app_scheduler.h"
+#endif
+#include <stddef.h>
+#define NRF_LOG_MODULE_NAME APP_TIMER_LOG_NAME
+#if APP_TIMER_CONFIG_LOG_ENABLED
+#define NRF_LOG_LEVEL APP_TIMER_CONFIG_LOG_LEVEL
+#define NRF_LOG_INFO_COLOR APP_TIMER_CONFIG_INFO_COLOR
+#define NRF_LOG_DEBUG_COLOR APP_TIMER_CONFIG_DEBUG_COLOR
+#else //APP_TIMER_CONFIG_LOG_ENABLED
+#define NRF_LOG_LEVEL 0
+#endif //APP_TIMER_CONFIG_LOG_ENABLED
+#include "nrf_log.h"
+NRF_LOG_MODULE_REGISTER();
+
+#include "drv_rtc.h"
+
+/**
+ * Maximum possible relative value is limited by safe window to detect cases when requested
+ * compare event has already occured.
+ */
+#define APP_TIMER_SAFE_WINDOW 1000
+
+#define APP_TIMER_RTC_MAX_VALUE (DRV_RTC_MAX_CNT - APP_TIMER_SAFE_WINDOW)
+
+static drv_rtc_t m_rtc_inst = DRV_RTC_INSTANCE(1);
+
+/**
+ * @brief Timer requests types.
+ */
+typedef enum
+{
+ TIMER_REQ_START,
+ TIMER_REQ_STOP,
+ TIMER_REQ_STOP_ALL
+} app_timer_req_type_t;
+
+/**
+ * @brief Operation request structure.
+ */
+typedef struct
+{
+ app_timer_req_type_t type; /**< Request type. */
+ app_timer_t * p_timer; /**< Timer instance. */
+} timer_req_t;
+
+static app_timer_t * volatile mp_active_timer; /**< Timer currently handled by RTC driver. */
+static bool m_global_active; /**< Flag used to globally disable all timers. */
+
+/* Request FIFO instance. */
+NRF_ATFIFO_DEF(m_req_fifo, timer_req_t, APP_TIMER_CONFIG_OP_QUEUE_SIZE);
+
+/* Sortlist instance. */
+static bool compare_func(nrf_sortlist_item_t * p_item0, nrf_sortlist_item_t *p_item1);
+NRF_SORTLIST_DEF(m_app_timer_sortlist, compare_func); /**< Sortlist used for storing queued timers. */
+
+/**
+ * @brief Function used for comparing items in sorted list.
+ */
+static inline bool compare_func(nrf_sortlist_item_t * p_item0, nrf_sortlist_item_t *p_item1)
+{
+ app_timer_t * p0 = CONTAINER_OF(p_item0, app_timer_t, list_item);
+ app_timer_t * p1 = CONTAINER_OF(p_item1, app_timer_t, list_item);
+
+ uint32_t p0_end = p0->end_val;
+ uint32_t p1_end = p1->end_val;
+ return (p0_end <= p1_end) ? true : false;
+}
+
+#if APP_TIMER_CONFIG_USE_SCHEDULER
+static void scheduled_timeout_handler(void * p_event_data, uint16_t event_size)
+{
+ ASSERT(event_size == sizeof(app_timer_event_t));
+ app_timer_event_t const * p_timer_event = (app_timer_event_t *)p_event_data;
+
+ p_timer_event->timeout_handler(p_timer_event->p_context);
+}
+#endif
+
+/**
+ * @brief Function called on timer expiration
+ *
+ * Function calls user handler if timer was not stopped before. If timer is in repeated mode then
+ * timer is rescheduled.
+ *
+ * @param p_timer Timer instance.
+ *
+ * @return True if reevaluation of sortlist needed (becasue it was updated).
+ */
+static bool timer_expire(app_timer_t * p_timer)
+{
+ ASSERT(p_timer->handler);
+ bool ret = false;
+ if (m_global_active == true && p_timer != NULL && p_timer->active)
+ {
+#if APP_TIMER_CONFIG_USE_SCHEDULER
+ app_timer_event_t timer_event;
+
+ timer_event.timeout_handler = p_timer->handler;
+ timer_event.p_context = p_timer->p_context;
+ uint32_t err_code = app_sched_event_put(&timer_event,
+ sizeof(timer_event),
+ scheduled_timeout_handler);
+ APP_ERROR_CHECK(err_code);
+#else
+ p_timer->handler(p_timer->p_context);
+#endif
+ if (p_timer->repeat_period && p_timer->active)
+ {
+ p_timer->end_val += p_timer->repeat_period;
+ nrf_sortlist_add(&m_app_timer_sortlist, &p_timer->list_item);
+ ret = true;
+ }
+ else
+ {
+ p_timer->active = false;
+ }
+ }
+ return ret;
+}
+
+/**
+ * @brief Function is configuring RTC driver to trigger timeout interrupt for given timer.
+ *
+ * It is possible that RTC driver will indicate that timeout already occured. In that case timer
+ * expires and function indicates that RTC was not configured.
+ *
+ * @param p_timer Timer instance.
+ * @param [in,out] p_rerun Flag indicating that sortlist reevaluation is required.
+ *
+ * @return True if RTC was successfully configured, false if timer already expired and RTC was not
+ * configured.
+ *
+ */
+static bool rtc_schedule(app_timer_t * p_timer, bool * p_rerun)
+{
+ ret_code_t ret = NRF_SUCCESS;
+ *p_rerun = false;
+ ret = drv_rtc_windowed_compare_set(&m_rtc_inst, 0, p_timer->end_val, APP_TIMER_SAFE_WINDOW);
+
+ if (ret == NRF_SUCCESS)
+ {
+ return true;
+ }
+ else if (ret == NRF_ERROR_TIMEOUT)
+ {
+ *p_rerun = timer_expire(p_timer);
+ }
+ else
+ {
+ ASSERT(0);
+ }
+ return false;
+}
+
+static inline app_timer_t * sortlist_pop(void)
+{
+ nrf_sortlist_item_t * p_next_item = nrf_sortlist_pop(&m_app_timer_sortlist);
+ return p_next_item ? CONTAINER_OF(p_next_item, app_timer_t, list_item) : NULL;
+}
+
+static inline app_timer_t * sortlist_peek(void)
+{
+ nrf_sortlist_item_t const * p_next_item = nrf_sortlist_peek(&m_app_timer_sortlist);
+ return p_next_item ? CONTAINER_OF(p_next_item, app_timer_t, list_item) : NULL;
+}
+
+static inline app_timer_t * sortlist_next(app_timer_t * p_item)
+{
+ nrf_sortlist_item_t const * p_next_item = nrf_sortlist_next(&p_item->list_item);
+ return p_next_item ? CONTAINER_OF(p_next_item, app_timer_t, list_item) : NULL;
+}
+/**
+ * @brief Function for deactivating all timers which are in the sorted list (active timers).
+ */
+static void sorted_list_stop_all(void)
+{
+ app_timer_t * p_next;
+ do
+ {
+ p_next = sortlist_pop();
+ if (p_next)
+ {
+ p_next->active = false;
+ }
+ } while (p_next);
+}
+
+/**
+ * @brief Function for handling RTC counter overflow.
+ *
+ * In case of overflow all active timers must have end value adjusted (reduced to 24 bit range).
+ */
+static void on_overflow_evt(void)
+{
+ NRF_LOG_DEBUG("Overflow EVT");
+ if (mp_active_timer)
+ {
+ uint32_t end_val = mp_active_timer->end_val;
+ mp_active_timer->end_val = end_val & RTC_COUNTER_COUNTER_Msk;
+ }
+
+ app_timer_t * p_next;
+ p_next = sortlist_peek();
+ while (p_next)
+ {
+ if (p_next->end_val <= RTC_COUNTER_COUNTER_Msk)
+ {
+ //If overflow occurs then all timers with value lower than max value expires immediately.
+ UNUSED_RETURN_VALUE(timer_expire(p_next));
+ }
+ else
+ {
+ p_next->end_val &= RTC_COUNTER_COUNTER_Msk;
+ }
+ p_next = sortlist_next(p_next);
+ }
+}
+
+/**
+ * #brief Function for handling RTC compare event - active timer expiration.
+ */
+static void on_compare_evt(void)
+{
+ if (mp_active_timer)
+ {
+ NRF_LOG_INST_DEBUG(mp_active_timer->p_log, "Compare EVT");
+ UNUSED_RETURN_VALUE(timer_expire(mp_active_timer));
+ mp_active_timer = NULL;
+ }
+ else
+ {
+ NRF_LOG_WARNING("Compare event but no active timer (already stopped?)");
+ }
+}
+
+/**
+ * @brief Function updates RTC.
+ *
+ * Function is called at the end of RTC interrupt when all new user request and/or timer expiration
+ * occured. It configures RTC if there is any pending timer, reconfigures if the are timers with
+ * shorted timeout than active one or stops RTC if there is no active timers.
+ */
+static void rtc_update(drv_rtc_t const * const p_instance)
+{
+ while(1)
+ {
+ app_timer_t * p_next = sortlist_peek();
+ bool rtc_reconf = false;
+ if (p_next) //Candidate for active timer
+ {
+ uint32_t next_end_val = p_next->end_val;
+ uint32_t active_end_val = mp_active_timer->end_val;
+ if (mp_active_timer == NULL)
+ {
+ //There is no active timer so candidate will become active timer.
+ rtc_reconf = true;
+ }
+ else if (mp_active_timer &&
+ (active_end_val > next_end_val))
+ {
+ //Candidate has shorter timeout than current active timer. Candidate will replace active timer.
+ //Active timer is put back into sorted list.
+ rtc_reconf = true;
+ if (mp_active_timer->active)
+ {
+ NRF_LOG_INST_DEBUG(mp_active_timer->p_log, "Timer preempted.");
+ nrf_sortlist_add(&m_app_timer_sortlist, &mp_active_timer->list_item);
+ }
+ }
+
+ if (rtc_reconf)
+ {
+ bool rerun;
+ p_next = sortlist_pop();
+ NRF_LOG_INST_DEBUG(p_next->p_log, "Activating timer (CC:%d).", next_end_val);
+ if (rtc_schedule(p_next, &rerun))
+ {
+ if (!APP_TIMER_KEEPS_RTC_ACTIVE && (mp_active_timer == NULL))
+ {
+ drv_rtc_start(p_instance);
+ }
+ mp_active_timer = p_next;
+
+ if (rerun == false)
+ {
+ //RTC was successfully updated and sortlist was not updated. Function can be terminated.
+ break;
+ }
+ }
+ else
+ {
+ //If RTC driver indicated that timeout already occured a new candidate will be taken from sorted list.
+ NRF_LOG_INST_DEBUG(p_next->p_log,"Timer expired before scheduled to RTC.");
+ }
+ }
+ else
+ {
+ //RTC will not be updated. Function can terminate.
+ break;
+ }
+ }
+ else //No candidate for active timer.
+ {
+ if (!APP_TIMER_KEEPS_RTC_ACTIVE && mp_active_timer == NULL)
+ {
+ drv_rtc_stop(p_instance);
+ }
+ break;
+ }
+ }
+}
+
+/**
+ * @brief Function for processing user requests.
+ *
+ * Function is called only in the context of RTC interrupt.
+ */
+static void timer_req_process(drv_rtc_t const * const p_instance)
+{
+ nrf_atfifo_item_get_t fifo_ctx;
+ timer_req_t * p_req = nrf_atfifo_item_get(m_req_fifo, &fifo_ctx);
+
+ while (p_req)
+ {
+ switch (p_req->type)
+ {
+ case TIMER_REQ_START:
+ if (!p_req->p_timer->active)
+ {
+ p_req->p_timer->active = true;
+ if (p_req->p_timer->end_val - drv_rtc_counter_get(p_instance) > APP_TIMER_RTC_MAX_VALUE)
+ {
+ //A little trick to handle case when timer was scheduled just before overflow.
+ p_req->p_timer->end_val &= RTC_COUNTER_COUNTER_Msk;
+ }
+ nrf_sortlist_add(&m_app_timer_sortlist, &(p_req->p_timer->list_item));
+ NRF_LOG_INST_DEBUG(p_req->p_timer->p_log,"Start request (CC:%d).",
+ p_req->p_timer->end_val);
+ }
+ break;
+ case TIMER_REQ_STOP:
+ if (p_req->p_timer == mp_active_timer)
+ {
+ mp_active_timer = NULL;
+ }
+ UNUSED_RETURN_VALUE(nrf_sortlist_remove(&m_app_timer_sortlist, &(p_req->p_timer->list_item)));
+ NRF_LOG_INST_DEBUG(p_req->p_timer->p_log,"Stop request.");
+ break;
+ case TIMER_REQ_STOP_ALL:
+ sorted_list_stop_all();
+ m_global_active = true;
+ NRF_LOG_INFO("Stop all request.");
+ break;
+ default:
+ break;
+ }
+ UNUSED_RETURN_VALUE(nrf_atfifo_item_free(m_req_fifo, &fifo_ctx));
+ p_req = nrf_atfifo_item_get(m_req_fifo, &fifo_ctx);
+ }
+}
+
+static void rtc_irq(drv_rtc_t const * const p_instance)
+{
+ if (drv_rtc_overflow_pending(p_instance))
+ {
+ on_overflow_evt();
+ }
+ if (drv_rtc_compare_pending(p_instance, 0))
+ {
+ on_compare_evt();
+ }
+ timer_req_process(p_instance);
+ rtc_update(p_instance);
+}
+
+/**
+ * @brief Function for triggering processing user requests.
+ *
+ * @note All user requests are processed in a single context - RTC interrupt.
+ */
+static inline void timer_request_proc_trigger(void)
+{
+ drv_rtc_irq_trigger(&m_rtc_inst);
+}
+
+/**
+ * @brief Function for putting user request into the request queue
+ */
+static ret_code_t timer_req_schedule(app_timer_req_type_t type, app_timer_t * p_timer)
+{
+ nrf_atfifo_item_put_t fifo_ctx;
+ timer_req_t * p_req = nrf_atfifo_item_alloc(m_req_fifo, &fifo_ctx);
+
+ if (p_req)
+ {
+ p_req->type = type;
+ p_req->p_timer = p_timer;
+ if (nrf_atfifo_item_put(m_req_fifo, &fifo_ctx))
+ {
+ timer_request_proc_trigger();
+ }
+ else
+ {
+ NRF_LOG_WARNING("Scheduling interrupted another scheduling.");
+ }
+ return NRF_SUCCESS;
+ }
+ else
+ {
+ return NRF_ERROR_NO_MEM;
+ }
+}
+
+ret_code_t app_timer_init(void)
+{
+ ret_code_t err_code;
+ drv_rtc_config_t config = {
+ .prescaler = APP_TIMER_CONFIG_RTC_FREQUENCY,
+ .interrupt_priority = APP_TIMER_CONFIG_IRQ_PRIORITY
+ };
+
+ err_code = NRF_ATFIFO_INIT(m_req_fifo);
+ if (err_code != NRFX_SUCCESS)
+ {
+ return err_code;
+ }
+
+ err_code = drv_rtc_init(&m_rtc_inst, &config, rtc_irq);
+ if (err_code != NRFX_SUCCESS)
+ {
+ return err_code;
+ }
+ drv_rtc_overflow_enable(&m_rtc_inst, true);
+ if (APP_TIMER_KEEPS_RTC_ACTIVE)
+ {
+ drv_rtc_start(&m_rtc_inst);
+ }
+
+ m_global_active = true;
+ return err_code;
+}
+
+ret_code_t app_timer_create(app_timer_id_t const * p_timer_id,
+ app_timer_mode_t mode,
+ app_timer_timeout_handler_t timeout_handler)
+{
+ ASSERT(p_timer_id);
+ ASSERT(timeout_handler);
+
+ if (timeout_handler == NULL)
+ {
+ return NRF_ERROR_INVALID_PARAM;
+ }
+
+ app_timer_t * p_t = (app_timer_t *) *p_timer_id;
+ p_t->handler = timeout_handler;
+ p_t->repeat_period = (mode == APP_TIMER_MODE_REPEATED) ? 1 : 0;
+ return NRF_SUCCESS;
+}
+
+ret_code_t app_timer_start(app_timer_t * p_timer, uint32_t timeout_ticks, void * p_context)
+{
+ ASSERT(p_timer);
+ app_timer_t * p_t = (app_timer_t *) p_timer;
+
+ if (timeout_ticks > APP_TIMER_RTC_MAX_VALUE)
+ {
+ return NRF_ERROR_INVALID_PARAM;
+ }
+ p_t->p_context = p_context;
+ p_t->end_val = drv_rtc_counter_get(&m_rtc_inst) + timeout_ticks;
+
+ if (p_t->repeat_period)
+ {
+ p_t->repeat_period = timeout_ticks;
+ }
+
+ return timer_req_schedule(TIMER_REQ_START, p_t);
+}
+
+
+ret_code_t app_timer_stop(app_timer_t * p_timer)
+{
+ ASSERT(p_timer);
+ app_timer_t * p_t = (app_timer_t *) p_timer;
+ p_t->active = false;
+
+ return timer_req_schedule(TIMER_REQ_STOP, p_t);
+}
+
+ret_code_t app_timer_stop_all(void)
+{
+ //block timer globally
+ m_global_active = false;
+
+ return timer_req_schedule(TIMER_REQ_STOP_ALL, NULL);
+}
+
+uint8_t app_timer_op_queue_utilization_get(void)
+{
+ /* Currently not supported by ATFIFO */
+ return 0;
+}
+
+uint32_t app_timer_cnt_diff_compute(uint32_t ticks_to,
+ uint32_t ticks_from)
+{
+ return ((ticks_to - ticks_from) & RTC_COUNTER_COUNTER_Msk);
+}
+
+uint32_t app_timer_cnt_get(void)
+{
+ return drv_rtc_counter_get(&m_rtc_inst);
+}
+
+void app_timer_pause(void)
+{
+ drv_rtc_stop(&m_rtc_inst);
+}
+
+void app_timer_resume(void)
+{
+ drv_rtc_start(&m_rtc_inst);
+}
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/timer/experimental/drv_rtc.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/timer/experimental/drv_rtc.c
new file mode 100644
index 0000000..8bda72d
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/timer/experimental/drv_rtc.c
@@ -0,0 +1,330 @@
+/**
+ * Copyright (c) 2018 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+
+#include <nrfx.h>
+#include <nrf_delay.h>
+#include <drv_rtc.h>
+
+/* Module is integral part of app_timer implementation. */
+#define NRF_LOG_MODULE_NAME app_timer
+#include <nrf_log.h>
+
+#define EVT_TO_STR(event) \
+ (event == NRF_RTC_EVENT_TICK ? "NRF_RTC_EVENT_TICK" : \
+ (event == NRF_RTC_EVENT_OVERFLOW ? "NRF_RTC_EVENT_OVERFLOW" : \
+ (event == NRF_RTC_EVENT_COMPARE_0 ? "NRF_RTC_EVENT_COMPARE_0" : \
+ (event == NRF_RTC_EVENT_COMPARE_1 ? "NRF_RTC_EVENT_COMPARE_1" : \
+ (event == NRF_RTC_EVENT_COMPARE_2 ? "NRF_RTC_EVENT_COMPARE_2" : \
+ (event == NRF_RTC_EVENT_COMPARE_3 ? "NRF_RTC_EVENT_COMPARE_3" : \
+ "UNKNOWN EVENT"))))))
+#if defined ( __ICCARM__ )
+/* IAR gives warning for offsetof with non-constant expression.*/
+#define CC_IDX_TO_CC_EVENT(_cc) \
+ ((nrf_rtc_event_t)(offsetof(NRF_RTC_Type, EVENTS_COMPARE[0]) + sizeof(uint32_t)*_cc))
+#else
+#define CC_IDX_TO_CC_EVENT(_cc) \
+ ((nrf_rtc_event_t)(offsetof(NRF_RTC_Type, EVENTS_COMPARE[_cc])))
+#endif
+
+/**@brief RTC driver instance control block structure. */
+typedef struct
+{
+ drv_rtc_t const * p_instance;
+ nrfx_drv_state_t state; /**< Instance state. */
+} drv_rtc_cb_t;
+
+// User callbacks local storage.
+static drv_rtc_handler_t m_handlers[DRV_RTC_ENABLED_COUNT];
+static drv_rtc_cb_t m_cb[DRV_RTC_ENABLED_COUNT];
+
+// According to Produce Specification RTC may not trigger COMPARE event if CC value set is equal to
+// COUNTER value or COUNTER+1.
+#define COUNTER_TO_CC_MIN_DISTANCE 2
+
+ret_code_t drv_rtc_init(drv_rtc_t const * const p_instance,
+ drv_rtc_config_t const * p_config,
+ drv_rtc_handler_t handler)
+{
+ ASSERT(p_instance);
+ ASSERT(p_config);
+ ASSERT(handler);
+
+ ret_code_t err_code;
+
+ m_handlers[p_instance->instance_id] = handler;
+
+ if (m_cb[p_instance->instance_id].state != NRFX_DRV_STATE_UNINITIALIZED)
+ {
+ err_code = NRF_ERROR_INVALID_STATE;
+ NRF_LOG_WARNING("RTC instance already initialized.");
+ return err_code;
+ }
+
+ nrf_rtc_prescaler_set(p_instance->p_reg, p_config->prescaler);
+ NRFX_IRQ_PRIORITY_SET(p_instance->irq, p_config->interrupt_priority);
+ NRFX_IRQ_ENABLE(p_instance->irq);
+
+ m_cb[p_instance->instance_id].state = NRFX_DRV_STATE_INITIALIZED;
+ m_cb[p_instance->instance_id].p_instance = p_instance;
+
+ err_code = NRF_SUCCESS;
+ NRF_LOG_INFO("RTC: initialized.");
+ return err_code;
+}
+
+void drv_rtc_uninit(drv_rtc_t const * const p_instance)
+{
+ ASSERT(p_instance);
+ uint32_t mask = NRF_RTC_INT_TICK_MASK |
+ NRF_RTC_INT_OVERFLOW_MASK |
+ NRF_RTC_INT_COMPARE0_MASK |
+ NRF_RTC_INT_COMPARE1_MASK |
+ NRF_RTC_INT_COMPARE2_MASK |
+ NRF_RTC_INT_COMPARE3_MASK;
+ ASSERT(m_cb[p_instance->instance_id].state != NRFX_DRV_STATE_UNINITIALIZED);
+
+ NRFX_IRQ_DISABLE(p_instance->irq);
+
+ drv_rtc_stop(p_instance);
+ nrf_rtc_event_disable(p_instance->p_reg, mask);
+ nrf_rtc_int_disable(p_instance->p_reg, mask);
+
+ m_cb[p_instance->instance_id].state = NRFX_DRV_STATE_UNINITIALIZED;
+ NRF_LOG_INFO("RTC: Uninitialized.");
+}
+
+void drv_rtc_start(drv_rtc_t const * const p_instance)
+{
+ ASSERT(p_instance);
+ nrf_rtc_task_trigger(p_instance->p_reg, NRF_RTC_TASK_START);
+}
+
+void drv_rtc_stop(drv_rtc_t const * const p_instance)
+{
+ ASSERT(p_instance);
+ nrf_rtc_task_trigger(p_instance->p_reg, NRF_RTC_TASK_STOP);
+}
+
+void drv_rtc_compare_set(drv_rtc_t const * const p_instance,
+ uint32_t cc,
+ uint32_t abs_value,
+ bool irq_enable)
+{
+ ASSERT(p_instance);
+ nrf_rtc_int_t cc_int_mask = (nrf_rtc_int_t)(NRF_RTC_INT_COMPARE0_MASK << cc);
+ nrf_rtc_event_t cc_evt = CC_IDX_TO_CC_EVENT(cc);
+ abs_value &= RTC_COUNTER_COUNTER_Msk;
+
+ nrf_rtc_int_disable(p_instance->p_reg, cc_int_mask);
+ nrf_rtc_event_disable(p_instance->p_reg, cc_int_mask);
+ nrf_rtc_event_clear(p_instance->p_reg, cc_evt);
+ nrf_rtc_cc_set(p_instance->p_reg, cc,abs_value);
+ nrf_rtc_event_enable(p_instance->p_reg, cc_int_mask);
+
+ if (irq_enable)
+ {
+ nrf_rtc_int_enable(p_instance->p_reg, cc_int_mask);
+ }
+}
+
+ret_code_t drv_rtc_windowed_compare_set(drv_rtc_t const * const p_instance,
+ uint32_t cc,
+ uint32_t abs_value,
+ uint16_t safe_window)
+{
+ ASSERT(p_instance);
+ uint32_t prev_cc_set;
+ uint32_t counter;
+ nrf_rtc_int_t cc_int_mask = (nrf_rtc_int_t)(NRF_RTC_INT_COMPARE0_MASK << cc);
+ nrf_rtc_event_t cc_evt = CC_IDX_TO_CC_EVENT(cc);;
+ abs_value &=RTC_COUNTER_COUNTER_Msk;
+
+ nrf_rtc_int_disable(p_instance->p_reg, cc_int_mask);
+ nrf_rtc_event_disable(p_instance->p_reg, cc_int_mask);
+
+ nrf_rtc_event_clear(p_instance->p_reg, cc_evt);
+ prev_cc_set = nrf_rtc_cc_get(p_instance->p_reg, cc);
+
+ nrf_rtc_cc_set(p_instance->p_reg, cc,abs_value);
+ /* If prev CC setting equals or is just in front of the counter then there is a risk that before
+ * new CC will be set after enabling event previous CC will generate COMPARE event. In such risk
+ * delay must be introduced between writting CC value and enabling the event.
+ */
+ counter = nrf_rtc_counter_get(p_instance->p_reg);
+ if (((prev_cc_set - counter) & RTC_COUNTER_COUNTER_Msk) == 1)
+ {
+ NRF_LOG_DEBUG("RTC: Delay introduced due to risk of pre-firing.");
+ nrf_delay_us(33);
+ }
+ nrf_rtc_event_enable(p_instance->p_reg, cc_int_mask);
+
+ counter = nrf_rtc_counter_get(p_instance->p_reg);
+ int32_t diff = (int32_t)abs_value - (int32_t)counter;
+
+ diff &= RTC_COUNTER_COUNTER_Msk;
+ diff = (diff & 0x800000) ? (diff | 0xFF000000) : diff;
+
+ /* If diff shows that abs_value is after the counter or up to 2 ticks before then it is assumed
+ * that compare channel was set to late. It is based on a assumption that abs_value will never
+ * be set to value bigger than maximum counter value - safe window. */
+ if ((diff > (int32_t)(-safe_window)) && (diff <= COUNTER_TO_CC_MIN_DISTANCE))
+ {
+ //set CC to something back in time to prevent event triggering on next compare set.
+ NRF_LOG_DEBUG("RTC: Windowed compare set timeout (abs_value:%d, counter:%d).",
+ abs_value, counter);
+ return NRF_ERROR_TIMEOUT;
+ }
+ else
+ {
+ nrf_rtc_int_enable(p_instance->p_reg, cc_int_mask);
+ }
+ return NRF_SUCCESS;
+}
+
+static void evt_enable(drv_rtc_t const * const p_instance, uint32_t mask, bool irq_enable)
+{
+ ASSERT(p_instance);
+ nrf_rtc_event_enable(p_instance->p_reg, mask);
+ if (irq_enable)
+ {
+ nrf_rtc_int_enable(p_instance->p_reg, mask);
+ }
+}
+
+static void evt_disable(drv_rtc_t const * const p_instance, uint32_t mask)
+{
+ ASSERT(p_instance);
+ nrf_rtc_event_disable(p_instance->p_reg, mask);
+ nrf_rtc_int_disable(p_instance->p_reg, mask);
+}
+
+static bool evt_pending(drv_rtc_t const * const p_instance, nrf_rtc_event_t event)
+{
+ ASSERT(p_instance);
+ if (nrf_rtc_event_pending(p_instance->p_reg, event))
+ {
+ nrf_rtc_event_clear(p_instance->p_reg, event);
+ return true;
+ }
+ return false;
+}
+
+void drv_rtc_overflow_enable(drv_rtc_t const * const p_instance, bool irq_enable)
+{
+ evt_enable(p_instance, NRF_RTC_INT_OVERFLOW_MASK, irq_enable);
+}
+
+void drv_rtc_overflow_disable(drv_rtc_t const * const p_instance)
+{
+ evt_disable(p_instance, NRF_RTC_INT_OVERFLOW_MASK);
+}
+
+bool drv_rtc_overflow_pending(drv_rtc_t const * const p_instance)
+{
+ return evt_pending(p_instance, NRF_RTC_EVENT_OVERFLOW);
+}
+
+void drv_rtc_tick_enable(drv_rtc_t const * const p_instance, bool irq_enable)
+{
+ evt_enable(p_instance, NRF_RTC_INT_TICK_MASK, irq_enable);
+}
+
+void drv_rtc_tick_disable(drv_rtc_t const * const p_instance)
+{
+ evt_disable(p_instance, NRF_RTC_INT_TICK_MASK);
+}
+
+bool drv_rtc_tick_pending(drv_rtc_t const * const p_instance)
+{
+ return evt_pending(p_instance, NRF_RTC_EVENT_TICK);
+}
+
+void drv_rtc_compare_enable(drv_rtc_t const * const p_instance,
+ uint32_t cc,
+ bool irq_enable)
+{
+ evt_enable(p_instance, (uint32_t)NRF_RTC_INT_COMPARE0_MASK << cc, irq_enable);
+}
+
+void drv_rtc_compare_disable(drv_rtc_t const * const p_instance, uint32_t cc)
+{
+ evt_disable(p_instance, (uint32_t)NRF_RTC_INT_COMPARE0_MASK << cc);
+}
+
+bool drv_rtc_compare_pending(drv_rtc_t const * const p_instance, uint32_t cc)
+{
+ nrf_rtc_event_t cc_evt = CC_IDX_TO_CC_EVENT(cc);
+ return evt_pending(p_instance, cc_evt);
+}
+
+uint32_t drv_rtc_counter_get(drv_rtc_t const * const p_instance)
+{
+ return nrf_rtc_counter_get(p_instance->p_reg);
+}
+
+void drv_rtc_irq_trigger(drv_rtc_t const * const p_instance)
+{
+ NVIC_SetPendingIRQ(p_instance->irq);
+}
+
+#define drv_rtc_rtc_0_irq_handler RTC0_IRQHandler
+#define drv_rtc_rtc_1_irq_handler RTC1_IRQHandler
+#define drv_rtc_rtc_2_irq_handler RTC2_IRQHandler
+
+#if defined(APP_TIMER_V2_RTC0_ENABLED)
+void drv_rtc_rtc_0_irq_handler(void)
+{
+ m_handlers[DRV_RTC_RTC0_INST_IDX](m_cb[DRV_RTC_RTC0_INST_IDX].p_instance);
+}
+#endif
+
+#if defined(APP_TIMER_V2_RTC1_ENABLED)
+void drv_rtc_rtc_1_irq_handler(void)
+{
+ m_handlers[DRV_RTC_RTC1_INST_IDX](m_cb[DRV_RTC_RTC1_INST_IDX].p_instance);
+}
+#endif
+
+#if defined(APP_TIMER_V2_RTC2_ENABLED)
+void drv_rtc_rtc_2_irq_handler(void)
+{
+ m_handlers[DRV_RTC_RTC2_INST_IDX](m_cb[DRV_RTC_RTC2_INST_IDX].p_instance);
+}
+#endif
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/timer/experimental/drv_rtc.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/timer/experimental/drv_rtc.h
new file mode 100644
index 0000000..3410460
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/timer/experimental/drv_rtc.h
@@ -0,0 +1,304 @@
+/**
+ * Copyright (c) 2018 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+
+#ifndef DRV_RTC_H__
+#define DRV_RTC_H__
+
+#include <nrfx.h>
+#include <hal/nrf_rtc.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @defgroup drv_rtc RTC driver
+ * @{
+ * @ingroup app_timer
+ * @brief Real Timer Counter (RTC) peripheral driver for app_timer.
+ */
+
+/** @brief Maximum RTC counter value. */
+#define DRV_RTC_MAX_CNT RTC_COUNTER_COUNTER_Msk
+
+/** @brief Time requires to update registers between RTC and MCU domains. */
+#define DRV_RTC_CONFIG_APPLY_TIME_US 33
+
+/**
+ * @brief Minimum delta value between set value and counter value.
+ *
+ * RTC peripheral requires two ticks to be sure that value it properly set in RTC value. Compare
+ * channel function requires additional one tick to avoid problematic situations (lack or additional
+ * unspecified event) when Compare Channel register is reseting or setting to N+2 value.
+ */
+#define DRV_RTC_MIN_TICK_HANDLED 3
+
+/** @brief Macro to convert microseconds into ticks. */
+#define DRV_RTC_US_TO_TICKS(us,freq) (us >= 2^17 ? \
+ ((((us)/1000)*(freq))/1000U) : (((us)*(freq))/1000000U) )
+
+
+/** @brief RTC driver instance structure. */
+typedef struct
+{
+ NRF_RTC_Type * p_reg; /**< Pointer to instance register set. */
+ IRQn_Type irq; /**< Instance IRQ ID. */
+ uint8_t instance_id; /**< Instance index. */
+ uint8_t cc_channel_count; /**< Number of capture/compare channels. */
+} drv_rtc_t;
+
+/** @brief Macro for creating RTC driver instance.*/
+#define DRV_RTC_INSTANCE(id) \
+{ \
+ .p_reg = NRFX_CONCAT_2(NRF_RTC, id), \
+ .irq = NRFX_CONCAT_3(RTC, id, _IRQn), \
+ .instance_id = NRFX_CONCAT_3(DRV_RTC_RTC, id, _INST_IDX), \
+ .cc_channel_count = NRF_RTC_CC_CHANNEL_COUNT(id), \
+}
+
+enum {
+#if defined(APP_TIMER_V2_RTC0_ENABLED)
+ DRV_RTC_RTC0_INST_IDX,
+#endif
+#if defined(APP_TIMER_V2_RTC1_ENABLED)
+ DRV_RTC_RTC1_INST_IDX,
+#endif
+#if defined(APP_TIMER_V2_RTC2_ENABLED)
+ DRV_RTC_RTC2_INST_IDX,
+#endif
+ DRV_RTC_ENABLED_COUNT
+};
+
+/** @brief RTC driver instance configuration structure. */
+typedef struct
+{
+ uint16_t prescaler; /**< Prescaler. */
+ uint8_t interrupt_priority; /**< Interrupt priority. */
+} drv_rtc_config_t;
+
+/** @brief RTC instance default configuration. */
+#define DRV_RTC_DEFAULT_CONFIG \
+{ \
+ .prescaler = RTC_FREQ_TO_PRESCALER(DRV_RTC_DEFAULT_CONFIG_FREQUENCY), \
+ .interrupt_priority = DRV_RTC_DEFAULT_CONFIG_IRQ_PRIORITY, \
+}
+
+/** @brief RTC driver instance handler type. */
+typedef void (*drv_rtc_handler_t)(drv_rtc_t const * const p_instance);
+
+/**
+ * @brief Function for initializing the RTC driver instance.
+ *
+ * After initialization, the instance is in power off state. The LFCLK (@ref nrfx_clock)
+ * has to be started before using @ref drv_rtc.
+ *
+ * @param[in] p_instance Pointer to the driver instance structure.
+ * @param[in] p_config Pointer to the structure with initial configuration.
+ * @param[in] handler Event handler provided by the user. Must not be NULL.
+ *
+ * @retval NRF_SUCCESS If successfully initialized.
+ * @retval NRF_ERROR_INVALID_STATE If the instance is already initialized.
+ */
+ret_code_t drv_rtc_init(drv_rtc_t const * const p_instance,
+ drv_rtc_config_t const * p_config,
+ drv_rtc_handler_t handler);
+
+/**
+ * @brief Function for uninitializing the RTC driver instance.
+ *
+ * After uninitialization, the instance is in idle state. The hardware should return to the state
+ * before initialization. The function asserts if the instance is in idle state.
+ *
+ * @param[in] p_instance Pointer to the driver instance structure.
+ */
+void drv_rtc_uninit(drv_rtc_t const * const p_instance);
+
+/**
+ * @brief Function for starting RTC clock.
+ *
+ * @param[in] p_instance Pointer to the driver instance structure.
+ */
+void drv_rtc_start(drv_rtc_t const * const p_instance);
+
+/**
+ * @brief Function for stopping RTC clock.
+ *
+ * @param[in] p_instance Pointer to the driver instance structure.
+ */
+void drv_rtc_stop(drv_rtc_t const * const p_instance);
+
+/**
+ * @brief Function for configuring compare channel.
+ *
+ * @note Function disables interrupts and only enable compare events. Remember to enable interrupt
+ * using @ref drv_rtc_compare_enable in case of using it.
+ *
+ * @param[in] p_instance Pointer to the driver instance structure.
+ * @param[in] cc Compare channel index.
+ * @param[in] abs_value Absolute value to be set in the compare register.
+ * @param[in] irq_enable True to enable interrupt.
+ */
+void drv_rtc_compare_set(drv_rtc_t const * const p_instance,
+ uint32_t cc,
+ uint32_t abs_value,
+ bool irq_enable);
+
+/**
+ * @brief Function for configuring compare channel with safe window.
+ *
+ * Maximum possible relative value is limited by safe window to detect
+ * cases when requested compare event has already occured.
+ *
+ * @param[in] p_instance Pointer to the driver instance structure.
+ * @param[in] cc Compare channel index.
+ * @param[in] abs_value Absolute value to be set in the compare register.
+ * @param[in] safe_window Width of the safe window.
+ *
+ * @retval NRF_ERROR_TIMEOUT If @par abs_value is in safe window of event occured before
+ * enabling compare channel intterupt.
+ * @retval NRF_SUCCESS If successfully set.
+ */
+ret_code_t drv_rtc_windowed_compare_set(drv_rtc_t const * const p_instance,
+ uint32_t cc,
+ uint32_t abs_value,
+ uint16_t safe_window);
+
+/**
+ * @brief Function for enabling overflow event and interrupt.
+ *
+ * @param[in] p_instance Pointer to the driver instance structure.
+ * @param[in] irq_enable True to enable interrupt.
+ */
+void drv_rtc_overflow_enable(drv_rtc_t const * const p_instance, bool irq_enable);
+
+/**
+ * @brief Function for diabling overflow event and interrupt.
+ *
+ * @param[in] p_instance Pointer to the driver instance structure.
+ */
+void drv_rtc_overflow_disable(drv_rtc_t const * const p_instance);
+
+/**
+ * @brief Function for checking if overflow event has occured.
+ *
+ * @note Event is cleared after reading.
+ *
+ * @param[in] p_instance Pointer to the driver instance structure.
+ *
+ * @return True if interrupt pending, false otherwise.
+ */
+bool drv_rtc_overflow_pending(drv_rtc_t const * const p_instance);
+
+/**
+ * @brief Function for enabling tick event and interrupt.
+ *
+ * @param[in] p_instance Pointer to the driver instance structure.
+ * @param[in] irq_enable True to enable interrupt.
+ */
+void drv_rtc_tick_enable(drv_rtc_t const * const p_instance, bool irq_enable);
+
+/**
+ * @brief Function for disabling tick event and interrupt.
+ *
+ * @param[in] p_instance Pointer to the driver instance structure.
+ */
+void drv_rtc_tick_disable(drv_rtc_t const * const p_instance);
+
+/**
+ * @brief Function for checking if tick event has occured.
+ *
+ * @param[in] p_instance Pointer to the driver instance structure.
+ *
+ * @return True if interrupt pending, false otherwise.
+ */
+bool drv_rtc_tick_pending(drv_rtc_t const * const p_instance);
+
+/**
+ * @brief Function for enabling compare channel event and interrupt.
+ *
+ * @param[in] p_instance Pointer to the driver instance structure.
+ * @param[in] cc Compare channel index.
+ * @param[in] irq_enable True to enable interrupt.
+ */
+void drv_rtc_compare_enable(drv_rtc_t const * const p_instance,
+ uint32_t cc,
+ bool irq_enable);
+
+/**
+ * @brief Function for disabling compare channel event and interrupt.
+ *
+ * @param[in] p_instance Pointer to the driver instance structure.
+ * @param[in] cc Compare channel index.
+ */
+void drv_rtc_compare_disable(drv_rtc_t const * const p_instance, uint32_t cc);
+
+/**
+ * @brief Function for checking if compare channel event has occured.
+ *
+ * @param[in] p_instance Pointer to the driver instance structure.
+ * @param[in] cc Compare channel index.
+ *
+ * @return True if interrupt pending, false otherwise.
+ */
+bool drv_rtc_compare_pending(drv_rtc_t const * const p_instance, uint32_t cc);
+
+/**
+ * @brief Function for getting current value of RTC counter.
+ *
+ * @param[in] p_instance Pointer to the driver instance structure.
+ *
+ * @return Counter value.
+ */
+uint32_t drv_rtc_counter_get(drv_rtc_t const * const p_instance);
+
+/**
+ * @brief Function for triggering RTC interrupt.
+ *
+ * @param[in] p_instance Pointer to the driver instance structure.
+ */
+void drv_rtc_irq_trigger(drv_rtc_t const * const p_instance);
+
+/** @} */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // DRV_RTC_H__
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/twi_mngr/nrf_twi_mngr.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/twi_mngr/nrf_twi_mngr.c
new file mode 100644
index 0000000..56a14e5
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/twi_mngr/nrf_twi_mngr.c
@@ -0,0 +1,366 @@
+/**
+ * Copyright (c) 2015 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#include "sdk_common.h"
+#if NRF_MODULE_ENABLED(NRF_TWI_MNGR)
+#include "nrf_twi_mngr.h"
+#include "nrf_assert.h"
+#include "app_util_platform.h"
+
+typedef volatile struct
+{
+ bool transaction_in_progress;
+ uint8_t transaction_result;
+} nrf_twi_mngr_cb_data_t;
+
+
+static ret_code_t start_transfer(nrf_twi_mngr_t const * p_nrf_twi_mngr)
+{
+ ASSERT(p_nrf_twi_mngr != NULL);
+
+ // Pointer for cleaner code.
+ nrf_twi_mngr_cb_t * p_cb = p_nrf_twi_mngr->p_nrf_twi_mngr_cb;
+
+ // [use a local variable to avoid using two volatile variables in one
+ // expression]
+ uint8_t current_transfer_idx = p_cb->current_transfer_idx;
+ nrf_twi_mngr_transfer_t const * p_transfer =
+ &p_cb->p_current_transaction->p_transfers[current_transfer_idx];
+ uint8_t address = NRF_TWI_MNGR_OP_ADDRESS(p_transfer->operation);
+
+ nrf_drv_twi_xfer_desc_t xfer_desc;
+ uint32_t flags;
+
+ xfer_desc.address = address;
+ xfer_desc.p_primary_buf = p_transfer->p_data;
+ xfer_desc.primary_length = p_transfer->length;
+
+ /* If it is possible try to bind two transfers together. They can be combined if:
+ * - there is no stop condition after current transfer.
+ * - current transfer is TX.
+ * - there is at least one more transfer in the transaction.
+ * - address of next transfer is the same as current transfer.
+ */
+ if ((p_transfer->flags & NRF_TWI_MNGR_NO_STOP) &&
+ !NRF_TWI_MNGR_IS_READ_OP(p_transfer->operation) &&
+ // Adding 1 to check if next transfer is from the same transaction.
+ ((current_transfer_idx + 1) < p_cb->p_current_transaction->number_of_transfers) &&
+ (NRF_TWI_MNGR_OP_ADDRESS(p_transfer->operation) ==
+ NRF_TWI_MNGR_OP_ADDRESS(p_cb->p_current_transaction->
+ p_transfers[current_transfer_idx + 1].operation)))
+ {
+ nrf_twi_mngr_transfer_t const * p_second_transfer =
+ &p_cb->p_current_transaction->p_transfers[current_transfer_idx + 1];
+ xfer_desc.p_secondary_buf = p_second_transfer->p_data;
+ xfer_desc.secondary_length = p_second_transfer->length;
+ xfer_desc.type = NRF_TWI_MNGR_IS_READ_OP(p_second_transfer->operation) ?
+ NRF_DRV_TWI_XFER_TXRX : NRF_DRV_TWI_XFER_TXTX;
+ flags = (p_second_transfer->flags & NRF_TWI_MNGR_NO_STOP) ? NRF_DRV_TWI_FLAG_TX_NO_STOP : 0;
+ p_cb->current_transfer_idx++;
+ }
+ else
+ {
+ xfer_desc.type = NRF_TWI_MNGR_IS_READ_OP(p_transfer->operation) ? NRF_DRV_TWI_XFER_RX :
+ NRF_DRV_TWI_XFER_TX;
+ xfer_desc.p_secondary_buf = NULL;
+ xfer_desc.secondary_length = 0;
+ flags = (p_transfer->flags & NRF_TWI_MNGR_NO_STOP) ? NRF_DRV_TWI_FLAG_TX_NO_STOP : 0;
+ }
+
+ return nrf_drv_twi_xfer(&p_nrf_twi_mngr->twi, &xfer_desc, flags);
+}
+
+
+static void transaction_end_signal(nrf_twi_mngr_t const * p_nrf_twi_mngr,
+ ret_code_t result)
+{
+ ASSERT(p_nrf_twi_mngr != NULL);
+
+ if (p_nrf_twi_mngr->p_nrf_twi_mngr_cb->p_current_transaction->callback)
+ {
+ // [use a local variable to avoid using two volatile variables in one
+ // expression]
+ void * p_user_data = p_nrf_twi_mngr->p_nrf_twi_mngr_cb->p_current_transaction->p_user_data;
+ p_nrf_twi_mngr->p_nrf_twi_mngr_cb->p_current_transaction->callback(result, p_user_data);
+ }
+}
+
+static void twi_event_handler(nrf_drv_twi_evt_t const * p_event,
+ void * p_context);
+
+// This function starts pending transaction if there is no current one or
+// when 'switch_transaction' parameter is set to true. It is important to
+// switch to new transaction without setting 'p_nrf_twi_mngr->p_current_transaction'
+// to NULL in between, since this pointer is used to check idle status - see
+// 'nrf_twi_mngr_is_idle()'.
+static void start_pending_transaction(nrf_twi_mngr_t const * p_nrf_twi_mngr,
+ bool switch_transaction)
+{
+ ASSERT(p_nrf_twi_mngr != NULL);
+
+ // Pointer for cleaner code.
+ nrf_twi_mngr_cb_t * p_cb = p_nrf_twi_mngr->p_nrf_twi_mngr_cb;
+
+ for (;;)
+ {
+ bool start_transaction = false;
+
+ CRITICAL_REGION_ENTER();
+ if (switch_transaction || nrf_twi_mngr_is_idle(p_nrf_twi_mngr))
+ {
+ if (nrf_queue_pop(p_nrf_twi_mngr->p_queue, (void *)(&p_cb->p_current_transaction))
+ == NRF_SUCCESS)
+ {
+ start_transaction = true;
+ }
+ else
+ {
+ p_cb->p_current_transaction = NULL;
+ }
+ }
+ CRITICAL_REGION_EXIT();
+
+ if (!start_transaction)
+ {
+ return;
+ }
+ else
+ {
+ ret_code_t result;
+
+ nrf_drv_twi_config_t const * p_instance_cfg =
+ p_cb->p_current_transaction->p_required_twi_cfg == NULL ?
+ &p_cb->default_configuration :
+ p_cb->p_current_transaction->p_required_twi_cfg;
+
+ if (memcmp(p_cb->p_current_configuration, p_instance_cfg, sizeof(*p_instance_cfg)) != 0)
+ {
+ ret_code_t err_code;
+ nrf_drv_twi_uninit(&p_nrf_twi_mngr->twi);
+ err_code = nrf_drv_twi_init(&p_nrf_twi_mngr->twi,
+ p_instance_cfg,
+ twi_event_handler,
+ (void *)p_nrf_twi_mngr);
+ ASSERT(err_code == NRF_SUCCESS);
+ nrf_drv_twi_enable(&p_nrf_twi_mngr->twi);
+ UNUSED_VARIABLE(err_code);
+ p_cb->p_current_configuration = p_instance_cfg;
+ }
+
+ // Try to start first transfer for this new transaction.
+ p_cb->current_transfer_idx = 0;
+ result = start_transfer(p_nrf_twi_mngr);
+
+ // If transaction started successfully there is nothing more to do here now.
+ if (result == NRF_SUCCESS)
+ {
+ return;
+ }
+
+ // Transfer failed to start - notify user that this transaction
+ // cannot be started and try with next one (in next iteration of
+ // the loop).
+ transaction_end_signal(p_nrf_twi_mngr, result);
+
+ switch_transaction = true;
+ }
+ }
+}
+
+
+static void twi_event_handler(nrf_drv_twi_evt_t const * p_event,
+ void * p_context)
+{
+ ASSERT(p_event != NULL);
+
+ nrf_twi_mngr_t * p_nrf_twi_mngr = (nrf_twi_mngr_t *)p_context;
+ ret_code_t result;
+
+ // This callback should be called only during transaction.
+ ASSERT(p_nrf_twi_mngr->p_nrf_twi_mngr_cb->p_current_transaction != NULL);
+
+ if (p_event->type == NRF_DRV_TWI_EVT_DONE)
+ {
+ result = NRF_SUCCESS;
+
+ // Transfer finished successfully. If there is another one to be
+ // performed in the current transaction, start it now.
+ // [use a local variable to avoid using two volatile variables in one
+ // expression]
+ uint8_t current_transfer_idx = p_nrf_twi_mngr->p_nrf_twi_mngr_cb->current_transfer_idx;
+ ++current_transfer_idx;
+ if (current_transfer_idx <
+ p_nrf_twi_mngr->p_nrf_twi_mngr_cb->p_current_transaction->number_of_transfers)
+ {
+ p_nrf_twi_mngr->p_nrf_twi_mngr_cb->current_transfer_idx = current_transfer_idx;
+
+ result = start_transfer(p_nrf_twi_mngr);
+
+ if (result == NRF_SUCCESS)
+ {
+ // The current transaction goes on and we've successfully
+ // started its next transfer -> there is nothing more to do.
+ return;
+ }
+
+ // [if the next transfer could not be started due to some error
+ // we finish the transaction with this error code as the result]
+ }
+ }
+ else
+ {
+ result = NRF_ERROR_INTERNAL;
+ }
+
+ // The current transaction has been completed or interrupted by some error.
+ // Notify the user and start next one (if there is any).
+ transaction_end_signal(p_nrf_twi_mngr, result);
+ // [we switch transactions here ('p_nrf_twi_mngr->p_current_transaction' is set
+ // to NULL only if there is nothing more to do) in order to not generate
+ // spurious idle status (even for a moment)]
+ start_pending_transaction(p_nrf_twi_mngr, true);
+}
+
+
+ret_code_t nrf_twi_mngr_init(nrf_twi_mngr_t const * p_nrf_twi_mngr,
+ nrf_drv_twi_config_t const * p_default_twi_config)
+{
+ ASSERT(p_nrf_twi_mngr != NULL);
+ ASSERT(p_nrf_twi_mngr->p_queue != NULL);
+ ASSERT(p_nrf_twi_mngr->p_queue->size > 0);
+ ASSERT(p_default_twi_config != NULL);
+
+ ret_code_t err_code;
+
+ err_code = nrf_drv_twi_init(&p_nrf_twi_mngr->twi,
+ p_default_twi_config,
+ twi_event_handler,
+ (void *)p_nrf_twi_mngr);
+ VERIFY_SUCCESS(err_code);
+
+ nrf_drv_twi_enable(&p_nrf_twi_mngr->twi);
+
+ p_nrf_twi_mngr->p_nrf_twi_mngr_cb->p_current_transaction = NULL;
+ p_nrf_twi_mngr->p_nrf_twi_mngr_cb->default_configuration = *p_default_twi_config;
+ p_nrf_twi_mngr->p_nrf_twi_mngr_cb->p_current_configuration =
+ &p_nrf_twi_mngr->p_nrf_twi_mngr_cb->default_configuration;
+
+ return NRF_SUCCESS;
+}
+
+
+void nrf_twi_mngr_uninit(nrf_twi_mngr_t const * p_nrf_twi_mngr)
+{
+ ASSERT(p_nrf_twi_mngr != NULL);
+
+ nrf_drv_twi_uninit(&p_nrf_twi_mngr->twi);
+
+ p_nrf_twi_mngr->p_nrf_twi_mngr_cb->p_current_transaction = NULL;
+}
+
+
+ret_code_t nrf_twi_mngr_schedule(nrf_twi_mngr_t const * p_nrf_twi_mngr,
+ nrf_twi_mngr_transaction_t const * p_transaction)
+{
+ ASSERT(p_nrf_twi_mngr != NULL);
+ ASSERT(p_transaction != NULL);
+ ASSERT(p_transaction->p_transfers != NULL);
+ ASSERT(p_transaction->number_of_transfers != 0);
+
+ ret_code_t result = NRF_SUCCESS;
+
+ result = nrf_queue_push(p_nrf_twi_mngr->p_queue, (void *)(&p_transaction));
+ if (result == NRF_SUCCESS)
+ {
+ // New transaction has been successfully added to queue,
+ // so if we are currently idle it's time to start the job.
+ start_pending_transaction(p_nrf_twi_mngr, false);
+ }
+
+ return result;
+}
+
+
+static void internal_transaction_cb(ret_code_t result, void * p_user_data)
+{
+ nrf_twi_mngr_cb_data_t *p_cb_data = (nrf_twi_mngr_cb_data_t *)p_user_data;
+
+ p_cb_data->transaction_result = result;
+ p_cb_data->transaction_in_progress = false;
+}
+
+
+ret_code_t nrf_twi_mngr_perform(nrf_twi_mngr_t const * p_nrf_twi_mngr,
+ nrf_drv_twi_config_t const * p_config,
+ nrf_twi_mngr_transfer_t const * p_transfers,
+ uint8_t number_of_transfers,
+ void (* user_function)(void))
+{
+ ASSERT(p_nrf_twi_mngr != NULL);
+ ASSERT(p_transfers != NULL);
+ ASSERT(number_of_transfers != 0);
+
+ nrf_twi_mngr_cb_data_t cb_data =
+ {
+ .transaction_in_progress = true
+ };
+
+ nrf_twi_mngr_transaction_t internal_transaction =
+ {
+ .callback = internal_transaction_cb,
+ .p_user_data = (void *)&cb_data,
+ .p_transfers = p_transfers,
+ .number_of_transfers = number_of_transfers,
+ .p_required_twi_cfg = p_config
+ };
+
+ ret_code_t result = nrf_twi_mngr_schedule(p_nrf_twi_mngr, &internal_transaction);
+ VERIFY_SUCCESS(result);
+
+ while (cb_data.transaction_in_progress)
+ {
+ if (user_function)
+ {
+ user_function();
+ }
+ }
+
+ return cb_data.transaction_result;
+}
+#endif //NRF_MODULE_ENABLED(NRF_TWI_MNGR)
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/twi_mngr/nrf_twi_mngr.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/twi_mngr/nrf_twi_mngr.h
new file mode 100644
index 0000000..a63803a
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/twi_mngr/nrf_twi_mngr.h
@@ -0,0 +1,342 @@
+/**
+ * Copyright (c) 2015 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#ifndef NRF_TWI_MNGR_H__
+#define NRF_TWI_MNGR_H__
+
+#include <stdint.h>
+#include "nrf_drv_twi.h"
+#include "sdk_errors.h"
+#include "nrf_queue.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @defgroup nrf_twi_mngr TWI transaction manager
+ * @{
+ * @ingroup app_common
+ *
+ * @brief Module for scheduling TWI transactions.
+ */
+
+//If TWIM is present buffers can only be in RAM
+/*lint -save -e491*/
+
+/**
+ * @brief Macro checking if buffers should be stored in RAM.
+ */
+#ifndef NRF_TWI_MNGR_BUFFERS_IN_RAM
+ #define NRF_TWI_MNGR_BUFFERS_IN_RAM defined(TWIM_PRESENT)
+#endif
+
+/**
+ * @brief Modifier used in array declaration for TWI Manager.
+ *
+ * @note For TWI peripheral array can be const, for TWIM array has to be located in RAM.
+ */
+#if NRF_TWI_MNGR_BUFFERS_IN_RAM
+ #define NRF_TWI_MNGR_BUFFER_LOC_IND
+#else
+ #define NRF_TWI_MNGR_BUFFER_LOC_IND const
+#endif
+/*lint -restore*/
+
+/**
+ * @brief Flag indicating that a given transfer should not be ended
+ * with a stop condition.
+ *
+ * Use this flag when a stop condition is undesirable between two transfers,
+ * for example, when the first transfer is a write that sets an address in the slave
+ * device and the second one is a read that fetches certain data using this
+ * address. In this case, the second transfer should follow directly after the
+ * first transfer, with a repeated start condition instead of a stop and then
+ * a new start condition.
+ */
+#define NRF_TWI_MNGR_NO_STOP 0x01
+
+/**
+ * @brief Macro for creating a write transfer.
+ *
+ * @param[in] address Slave address.
+ * @param[in] p_data Pointer to the data to be sent.
+ * @param[in] length Number of bytes to transfer.
+ * @param[in] flags Transfer flags (see @ref NRF_TWI_MNGR_NO_STOP).
+ */
+#define NRF_TWI_MNGR_WRITE(address, p_data, length, flags) \
+ NRF_TWI_MNGR_TRANSFER(NRF_TWI_MNGR_WRITE_OP(address), p_data, length, flags)
+
+/**
+ * @brief Macro for creating a read transfer.
+ *
+ * @param address Slave address.
+ * @param[in] p_data Pointer to the buffer where received data should be placed.
+ * @param length Number of bytes to transfer.
+ * @param flags Transfer flags (see @ref NRF_TWI_MNGR_NO_STOP).
+ */
+#define NRF_TWI_MNGR_READ(address, p_data, length, flags) \
+ NRF_TWI_MNGR_TRANSFER(NRF_TWI_MNGR_READ_OP(address), p_data, length, flags)
+
+/**
+ * @brief Helper macro, should not be used directly.
+ */
+#define NRF_TWI_MNGR_TRANSFER(_operation, _p_data, _length, _flags) \
+{ \
+ .p_data = (uint8_t *)(_p_data), \
+ .length = _length, \
+ .operation = _operation, \
+ .flags = _flags \
+}
+/**
+ * @brief Helper macro, should not be used directly.
+ */
+#define NRF_TWI_MNGR_WRITE_OP(address) (((address) << 1) | 0)
+/**
+ * @brief Helper macro, should not be used directly.
+ */
+#define NRF_TWI_MNGR_READ_OP(address) (((address) << 1) | 1)
+/**
+ * @brief Helper macro, should not be used directly.
+ */
+#define NRF_TWI_MNGR_IS_READ_OP(operation) ((operation) & 1)
+/**
+ * @brief Helper macro, should not be used directly.
+ */
+#define NRF_TWI_MNGR_OP_ADDRESS(operation) ((operation) >> 1)
+
+/**
+ * @brief TWI transaction callback prototype.
+ *
+ * @param result Result of operation (NRF_SUCCESS on success,
+ * otherwise a relevant error code).
+ * @param[in] p_user_data Pointer to user data defined in transaction
+ * descriptor.
+ */
+typedef void (* nrf_twi_mngr_callback_t)(ret_code_t result, void * p_user_data);
+
+/**
+ * @brief TWI transfer descriptor.
+ */
+typedef struct {
+ uint8_t * p_data; ///< Pointer to the buffer holding the data.
+ uint8_t length; ///< Number of bytes to transfer.
+ uint8_t operation; ///< Device address combined with transfer direction.
+ uint8_t flags; ///< Transfer flags (see @ref NRF_TWI_MNGR_NO_STOP).
+} nrf_twi_mngr_transfer_t;
+
+/**
+ * @brief TWI transaction descriptor.
+ */
+typedef struct {
+ nrf_twi_mngr_callback_t callback;
+ ///< User-specified function to be called after the transaction is finished.
+
+ void * p_user_data;
+ ///< Pointer to user data to be passed to the callback.
+
+ nrf_twi_mngr_transfer_t const * p_transfers;
+ ///< Pointer to the array of transfers that make up the transaction.
+
+ uint8_t number_of_transfers;
+ ///< Number of transfers that make up the transaction.
+
+ nrf_drv_twi_config_t const * p_required_twi_cfg;
+ ///< Pointer to instance hardware configuration.
+} nrf_twi_mngr_transaction_t;
+
+/**
+ * @brief TWI instance control block.
+ */
+typedef struct {
+ nrf_twi_mngr_transaction_t const * volatile p_current_transaction;
+ ///< Currently realized transaction.
+
+ nrf_drv_twi_config_t default_configuration;
+ ///< Default hardware configuration.
+
+ nrf_drv_twi_config_t const * p_current_configuration;
+ ///< Pointer to current hardware configuration.
+
+ uint8_t volatile current_transfer_idx;
+ ///< Index of currently performed transfer (within current transaction).
+} nrf_twi_mngr_cb_t;
+
+/**
+ * @brief TWI transaction manager instance.
+ */
+typedef struct {
+ nrf_twi_mngr_cb_t * p_nrf_twi_mngr_cb;
+ ///< Control block of instance.
+
+ nrf_queue_t const * p_queue;
+ ///< Transaction queue.
+
+ nrf_drv_twi_t twi;
+ ///< Pointer to TWI master driver instance.
+} nrf_twi_mngr_t;
+
+/**
+ * @brief Macro that simplifies defining a TWI transaction manager
+ * instance.
+ *
+ * This macro allocates a static buffer for the transaction queue.
+ * Therefore, it should be used in only one place in the code for a given
+ * instance.
+ *
+ * @note The queue size is the maximum number of pending transactions
+ * not counting the one that is currently realized. This means that
+ * for an empty queue with size of, for example, 4 elements, it is
+ * possible to schedule up to 5 transactions.
+ *
+ * @param[in] _nrf_twi_mngr_name Name of instance to be created.
+ * @param[in] _queue_size Size of the transaction queue (maximum number
+ * of pending transactions).
+ * @param[in] _twi_idx Index of hardware TWI instance to be used.
+ */
+#define NRF_TWI_MNGR_DEF(_nrf_twi_mngr_name, _queue_size, _twi_idx) \
+ NRF_QUEUE_DEF(nrf_twi_mngr_transaction_t const *, \
+ _nrf_twi_mngr_name##_queue, \
+ (_queue_size), \
+ NRF_QUEUE_MODE_NO_OVERFLOW); \
+ static nrf_twi_mngr_cb_t CONCAT_2(_nrf_twi_mngr_name, _cb); \
+ static const nrf_twi_mngr_t _nrf_twi_mngr_name = \
+ { \
+ .p_nrf_twi_mngr_cb = &CONCAT_2(_nrf_twi_mngr_name, _cb), \
+ .p_queue = &_nrf_twi_mngr_name##_queue, \
+ .twi = NRF_DRV_TWI_INSTANCE(_twi_idx) \
+ }
+
+/**
+ * @brief Function for initializing a TWI transaction manager instance.
+ *
+ * @param[in] p_nrf_twi_mngr Pointer to the instance to be initialized.
+ * @param[in] p_default_twi_config Pointer to the TWI master driver configuration. This configuration
+ * will be used whenever the scheduled transaction will have
+ * p_twi_configuration set to NULL value.
+ *
+ * @return Values returned by the @ref nrf_drv_twi_init function.
+ */
+ret_code_t nrf_twi_mngr_init(nrf_twi_mngr_t const * p_nrf_twi_mngr,
+ nrf_drv_twi_config_t const * p_default_twi_config);
+
+/**
+ * @brief Function for uninitializing a TWI transaction manager instance.
+ *
+ * @param[in] p_nrf_twi_mngr Pointer to the instance to be uninitialized.
+ */
+void nrf_twi_mngr_uninit(nrf_twi_mngr_t const * p_nrf_twi_mngr);
+
+/**
+ * @brief Function for scheduling a TWI transaction.
+ *
+ * The transaction is enqueued and started as soon as the TWI bus is
+ * available, thus when all previously scheduled transactions have been
+ * finished (possibly immediately).
+ *
+ * @note If @ref nrf_twi_mngr_transaction_t::p_required_twi_cfg
+ * is set to a non-NULL value the module will compare it with
+ * @ref nrf_twi_mngr_cb_t::p_current_configuration and reinitialize hardware
+ * TWI instance with new parameters if any differences are found.
+ * If @ref nrf_twi_mngr_transaction_t::p_required_twi_cfg is set to NULL then
+ * it will treat it as it would be set to @ref nrf_twi_mngr_cb_t::default_configuration.
+ *
+ * @param[in] p_nrf_twi_mngr Pointer to the TWI transaction manager instance.
+ * @param[in] p_transaction Pointer to the descriptor of the transaction to be
+ * scheduled.
+ *
+ * @retval NRF_SUCCESS If the transaction has been successfully scheduled.
+ * @retval NRF_ERROR_NO_MEM If the queue is full (Only if queue in
+ * @ref NRF_QUEUE_MODE_NO_OVERFLOW).
+ */
+ret_code_t nrf_twi_mngr_schedule(nrf_twi_mngr_t const * p_nrf_twi_mngr,
+ nrf_twi_mngr_transaction_t const * p_transaction);
+
+/**
+ * @brief Function for scheduling a transaction and waiting until it is finished.
+ *
+ * This function schedules a transaction that consists of one or more transfers
+ * and waits until it is finished.
+ *
+ * @param[in] p_nrf_twi_mngr Pointer to the TWI transaction manager instance.
+ * @param[in] p_config Required TWI configuration.
+ * @param[in] p_transfers Pointer to an array of transfers to be performed.
+ * @param number_of_transfers Number of transfers to be performed.
+ * @param user_function User-specified function to be called while
+ * waiting. NULL if such functionality
+ * is not needed.
+ *
+ * @retval NRF_SUCCESS If the transfers have been successfully realized.
+ * @retval NRF_ERROR_BUSY If some transfers are already being performed.
+ * @retval - Other error codes mean that the transaction has ended
+ * with the error that is specified in the error code.
+ */
+ret_code_t nrf_twi_mngr_perform(nrf_twi_mngr_t const * p_nrf_twi_mngr,
+ nrf_drv_twi_config_t const * p_config,
+ nrf_twi_mngr_transfer_t const * p_transfers,
+ uint8_t number_of_transfers,
+ void (* user_function)(void));
+
+/**
+ * @brief Function for getting the current state of a TWI transaction manager
+ * instance.
+ *
+ * @param[in] p_nrf_twi_mngr Pointer to the TWI transaction manager instance.
+ *
+ * @retval true If all scheduled transactions have been finished.
+ * @retval false Otherwise.
+ */
+__STATIC_INLINE bool nrf_twi_mngr_is_idle(nrf_twi_mngr_t const * p_nrf_twi_mngr);
+
+#ifndef SUPPRESS_INLINE_IMPLEMENTATION
+__STATIC_INLINE bool nrf_twi_mngr_is_idle(nrf_twi_mngr_t const * p_nrf_twi_mngr)
+{
+ return (p_nrf_twi_mngr->p_nrf_twi_mngr_cb->p_current_transaction == NULL);
+}
+#endif //SUPPRESS_INLINE_IMPLEMENTATION
+/**
+ *@}
+ **/
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // NRF_TWI_MNGR_H__
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/twi_sensor/nrf_twi_sensor.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/twi_sensor/nrf_twi_sensor.c
new file mode 100644
index 0000000..9c080bc
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/twi_sensor/nrf_twi_sensor.c
@@ -0,0 +1,220 @@
+/**
+ * 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#include "nrf_twi_sensor.h"
+#include <string.h>
+
+#define NRF_LOG_MODULE_NAME twi_sensor
+#if NRF_TWI_SENSOR_CONFIG_LOG_ENABLED
+ #define NRF_LOG_LEVEL NRF_TWI_SENSOR_CONFIG_LOG_LEVEL
+ #define NRF_LOG_INFO_COLOR NRF_TWI_SENSOR_CONFIG_INFO_COLOR
+ #define NRF_LOG_DEBUG_COLOR NRF_TWI_SENSOR_CONFIG_DEBUG_COLOR
+#else
+ #define NRF_LOG_LEVEL 0
+#endif // NRF_TWI_SENSOR_CONFIG_LOG_ENABLED
+#include "nrf_log.h"
+NRF_LOG_MODULE_REGISTER();
+
+
+ret_code_t nrf_twi_sensor_init(nrf_twi_sensor_t * p_twi_sensor)
+{
+ return nrf_balloc_init(p_twi_sensor->p_pool);
+}
+
+static void sensor_read_reg_cb(ret_code_t result, void * p_user_data)
+{
+ nrf_twi_sensor_read_cmd_t * p_cmd = &((nrf_twi_sensor_cmd_t *) p_user_data)->read;
+ NRF_LOG_INFO("Read cb reg addr: 0x%02X, result %d", p_cmd->reg_address, result);
+ NRF_LOG_DEBUG("\r\nCallback pointer: %p\r\nData:", p_cmd->user_cb);
+ NRF_LOG_HEXDUMP_DEBUG(p_cmd->transfers[1].p_data, p_cmd->transfers[1].length);
+
+ if (p_cmd->user_cb != NULL)
+ {
+ p_cmd->user_cb(result, (void*)p_cmd->transfers[1].p_data);
+ }
+ nrf_balloc_free(p_cmd->p_instance->p_pool, p_user_data);
+}
+
+ret_code_t nrf_twi_sensor_reg_read(nrf_twi_sensor_t const * p_instance,
+ uint8_t sensor_addr,
+ uint8_t reg_address,
+ nrf_twi_sensor_reg_cb_t user_cb,
+ uint8_t * p_data,
+ uint8_t length)
+{
+ ASSERT(p_instance != NULL);
+ ASSERT(p_data != NULL);
+ NRF_LOG_INFO("Sensor addr: 0x%02X"
+ "\r\nRead reg addr: 0x%02X, bytes %d",
+ sensor_addr,
+ reg_address,
+ length);
+
+ nrf_twi_sensor_read_cmd_t * p_cmd =
+ (nrf_twi_sensor_read_cmd_t *) nrf_balloc_alloc(p_instance->p_pool);
+ if (p_cmd == NULL)
+ {
+ NRF_LOG_WARNING("Memory not allocated.");
+ return NRF_ERROR_NO_MEM;
+ }
+
+ p_cmd->p_instance = p_instance;
+ p_cmd->user_cb = user_cb;
+ p_cmd->reg_address = reg_address;
+
+ p_cmd->transfers[0] = (nrf_twi_mngr_transfer_t) NRF_TWI_MNGR_WRITE(sensor_addr,
+ &p_cmd->reg_address,
+ 1,
+ NRF_TWI_MNGR_NO_STOP);
+
+ p_cmd->transfers[1] = (nrf_twi_mngr_transfer_t) NRF_TWI_MNGR_READ(sensor_addr,
+ p_data,
+ length,
+ NRF_TWI_MNGR_NO_STOP);
+
+ p_cmd->transaction = (nrf_twi_mngr_transaction_t) {
+ .callback = sensor_read_reg_cb,
+ .p_user_data = p_cmd,
+ .p_transfers = p_cmd->transfers,
+ .number_of_transfers = ARRAY_SIZE(p_cmd->transfers)
+ };
+
+ ret_code_t err_code = nrf_twi_mngr_schedule(p_instance->p_twi_mngr, &p_cmd->transaction);
+ if (err_code != NRF_SUCCESS)
+ {
+ NRF_LOG_WARNING("Transaction not scheduled.\r\nSensor addr: 0x%02X Error code: %d",
+ sensor_addr,
+ err_code);
+ nrf_balloc_free(p_instance->p_pool, p_cmd);
+ }
+ return err_code;
+}
+
+static void sensor_write_reg_cb(ret_code_t result, void * p_user_data)
+{
+ nrf_twi_sensor_write_cmd_t * p_cmd = &((nrf_twi_sensor_cmd_t *) p_user_data)->write;
+ NRF_LOG_INFO("Write cb reg addr: 0x%02X, result %d", p_cmd->send_msg[0], result);
+ nrf_balloc_free(p_cmd->p_instance->p_pool, p_user_data);
+}
+
+ret_code_t nrf_twi_sensor_write(nrf_twi_sensor_t const * p_instance,
+ uint8_t sensor_addr,
+ uint8_t const * p_data,
+ uint8_t length,
+ bool copy_flag)
+{
+ ASSERT(p_instance != NULL);
+ ASSERT(p_data != NULL);
+ NRF_LOG_INFO("Sensor addr: 0x%02X Write length %d", sensor_addr, length);
+ NRF_LOG_DEBUG("Data: ");
+ NRF_LOG_HEXDUMP_DEBUG(p_data, length);
+ nrf_twi_sensor_write_cmd_t * p_cmd =
+ (nrf_twi_sensor_write_cmd_t *) nrf_balloc_alloc(p_instance->p_pool);
+ if (p_cmd == NULL)
+ {
+ NRF_LOG_WARNING("Memory not allocated. Sensor addr: 0x%02X",
+ sensor_addr);
+ return NRF_ERROR_NO_MEM;
+ }
+
+ p_cmd->p_instance = p_instance;
+
+ p_cmd->transfer = (nrf_twi_mngr_transfer_t) NRF_TWI_MNGR_WRITE(sensor_addr,
+ p_data,
+ length,
+ 0);
+
+ if (copy_flag == true)
+ {
+ if (length > NRF_TWI_SENSOR_SEND_BUF_SIZE)
+ {
+ NRF_LOG_ERROR("Data too long to copy. Sensor addr: 0x%02X"
+ "\r\nRequested write length: %d, max length: %d",
+ sensor_addr,
+ length,
+ NRF_TWI_SENSOR_SEND_BUF_SIZE);
+ nrf_balloc_free(p_instance->p_pool, p_cmd);
+ return NRF_ERROR_INVALID_LENGTH;
+ }
+ memcpy(p_cmd->send_msg, p_data, length);
+ p_cmd->transfer.p_data = p_cmd->send_msg;
+ }
+
+ p_cmd->transaction = (nrf_twi_mngr_transaction_t) {
+ .callback = sensor_write_reg_cb,
+ .p_user_data = p_cmd,
+ .p_transfers = &p_cmd->transfer,
+ .number_of_transfers = 1
+ };
+
+ ret_code_t err_code = nrf_twi_mngr_schedule(p_instance->p_twi_mngr, &p_cmd->transaction);
+ if (err_code != NRF_SUCCESS)
+ {
+ NRF_LOG_WARNING("Transaction not scheduled.\r\nSensor addr: 0x%02X Error code: %d",
+ sensor_addr,
+ err_code);
+ nrf_balloc_free(p_instance->p_pool, p_cmd);
+ }
+ return err_code;
+}
+
+ret_code_t nrf_twi_sensor_reg_write(nrf_twi_sensor_t const * p_instance,
+ uint8_t sensor_addr,
+ uint8_t reg_address,
+ uint8_t * p_data,
+ uint8_t length)
+{
+ ASSERT(p_instance != NULL);
+ ASSERT(p_data != NULL);
+ NRF_LOG_INFO("Write register: 0x%02X", reg_address);
+ if (length > NRF_TWI_SENSOR_SEND_BUF_SIZE - 1) // Subtracting one byte for address
+ {
+ NRF_LOG_ERROR("Data too long to copy. Sensor addr: 0x%02X"
+ "\r\nRequested write length: %d, max length: %d",
+ sensor_addr,
+ length,
+ NRF_TWI_SENSOR_SEND_BUF_SIZE - 1);
+ return NRF_ERROR_INVALID_LENGTH;
+ }
+ uint8_t buf[NRF_TWI_SENSOR_SEND_BUF_SIZE];
+
+ buf[0] = reg_address;
+ memcpy(&buf[1], p_data, length);
+ return nrf_twi_sensor_write(p_instance, sensor_addr, buf, length + 1, true);
+}
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/twi_sensor/nrf_twi_sensor.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/twi_sensor/nrf_twi_sensor.h
new file mode 100644
index 0000000..adddff2
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/twi_sensor/nrf_twi_sensor.h
@@ -0,0 +1,314 @@
+/**
+ * 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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
+ *
+ * @defgroup nrf_twi_sensor TWI Sensor module.
+ * @{
+ * @ingroup app_common
+ */
+
+#ifndef NRF_TWI_SENSOR_H
+#define NRF_TWI_SENSOR_H
+
+#include "nrf_twi_mngr.h"
+#include "nrf_balloc.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @brief Internal write operation buffer length.
+ *
+ * Defines how many bytes can be stored internally.
+ * 16 bytes were selected so that nrf_twi_sensor_write_cmd_t size
+ * matches nrf_twi_sensor_read_cmd_t size.
+ */
+#define NRF_TWI_SENSOR_SEND_BUF_SIZE 16
+
+/**
+ * @brief Register read callback prototype.
+ *
+ * @param[in] result Return error code from TWI manager and underlying drivers.
+ * @param[in] p_register_data Pointer to register value.
+ */
+typedef void (* nrf_twi_sensor_reg_cb_t)(ret_code_t result, void * p_register_data);
+
+
+/**
+ * @brief Structure holding sensor instance
+ */
+typedef struct
+{
+ nrf_twi_mngr_t const * const p_twi_mngr;
+ nrf_balloc_t const * const p_pool;
+
+
+} nrf_twi_sensor_t;
+
+/**
+ * @brief Struct describing sensor read command.
+ *
+ * @note For internal use only.
+ */
+typedef struct
+{
+ uint8_t reg_address;
+ nrf_twi_mngr_transfer_t transfers[2];
+ nrf_twi_mngr_transaction_t transaction;
+ nrf_twi_sensor_reg_cb_t user_cb;
+ nrf_twi_sensor_t const * p_instance;
+} nrf_twi_sensor_read_cmd_t;
+
+/**
+ * @brief Struct describing sensor write command.
+ *
+ * @note For internal use only.
+ */
+typedef struct
+{
+ uint8_t send_msg[NRF_TWI_SENSOR_SEND_BUF_SIZE];
+ nrf_twi_mngr_transfer_t transfer;
+ nrf_twi_mngr_transaction_t transaction;
+ nrf_twi_sensor_t const * p_instance;
+} nrf_twi_sensor_write_cmd_t;
+
+/**
+ * @brief Union for sensor commands. Needed in buffer definition.
+ *
+ * @note For internal use only.
+ */
+typedef union
+{
+ nrf_twi_sensor_read_cmd_t read;
+ nrf_twi_sensor_write_cmd_t write;
+} nrf_twi_sensor_cmd_t;
+
+
+/**
+ * @brief Macro creating common twi sensor instance.
+ *
+ * Data in structure is used for basic communication with sensors.
+ * THere should be one instance per TWI bus.
+ *
+ * @param[in] twi_sensor_name TWI common sensor instance name.
+ * @param[in] p_nrf_twi_mngr Pointer to TWI Manager instance. @ref NRF_TWI_MNGR_DEF
+ * @param[in] msg_buff_size Size of buffer used in communication
+ *
+ * @note Buffer size should be less or equal to TWI manager queue size.
+ * Minimum buffer size can be found after checking utilization of sensor buffer.
+ */
+#define NRF_TWI_SENSOR_DEF(twi_sensor_name, p_nrf_twi_mngr, msg_buff_size) \
+ NRF_BALLOC_DEF(CONCAT_2(twi_sensor_name,_pool), sizeof(nrf_twi_sensor_cmd_t), msg_buff_size);\
+ static nrf_twi_sensor_t twi_sensor_name = \
+ { \
+ .p_twi_mngr = p_nrf_twi_mngr, \
+ .p_pool = &CONCAT_2(twi_sensor_name,_pool) \
+ }
+
+/**
+ * @brief Macro for defining TWI manager read transfer.
+ *
+ * @note For internal use only.
+ */
+#define NRF_TWI_SENSOR_READ(p_reg_addr, p_buffer, byte_cnt) \
+ NRF_TWI_MNGR_WRITE(0x00, p_reg_addr, 1, NRF_TWI_MNGR_NO_STOP), \
+ NRF_TWI_MNGR_READ (0x00, p_buffer, byte_cnt, 0)
+
+/**
+ * @brief Macro for defining TWI manager write transfer.
+ *
+ * @note For internal use only.
+ */
+#define NRF_TWI_SENSOR_WRITE(p_buffer, byte_cnt) \
+ NRF_TWI_MNGR_WRITE(0x00, p_buffer, byte_cnt, 0)
+
+
+/**
+ * @brief Macro for assigning sensor address to transfers.
+ *
+ * @param[in] _transfers Transfers array.
+ * @param[in] _sensor_addr Desired sensor address.
+ *
+ * @note For internal use only.
+ */
+#define NRF_TWI_SENSOR_ADDRESS_SET(_transfers, _sensor_addr) \
+ for (uint8_t i = 0; i < ARRAY_SIZE(_transfers); i++) \
+ { \
+ if (i % 2 == 0) \
+ { \
+ transfers[i].operation = NRF_TWI_MNGR_WRITE_OP(_sensor_addr); \
+ } \
+ else \
+ { \
+ transfers[i].operation = NRF_TWI_MNGR_READ_OP(_sensor_addr); \
+ } \
+ }
+
+/**
+ * @brief Macro for setting parameters in sensor register.
+ *
+ * @param[in,out] _register Register to be altered.
+ * @param[in] _msk Parameter mask.
+ * @param[in] _pos Parameter position.
+ * @param[in] _val Parameter value to be set.
+ */
+#define NRF_TWI_SENSOR_REG_SET(_register, _msk, _pos, _val) \
+ _register &= ~(_msk); \
+ _register |= ((_msk) & ((_val) << (_pos)))
+
+
+/**
+ * @brief Macro for getting parameters from sensor register.
+ *
+ * @param[in] _register Register to be processed.
+ * @param[in] _msk Parameter mask.
+ * @param[in] _pos Parameter position.
+ *
+ * @note For usage with registers read using nrf_twi_sensor_register_read function.
+ *
+ * @return Parameter value
+ */
+#define NRF_TWI_SENSOR_REG_VAL_GET(_register, _msk, _pos) \
+ (((_register) & (_msk)) >> (_pos))
+
+/**
+ * @brief Function for initialization of sensor common instance.
+ *
+ * @note TWI Manager should be initialized before @ref nrf_twi_mngr_init
+ * @param[in] p_twi_sensor Pointer to sensor common instance.
+ *
+ * @return Error code from nrf_balloc @ref nrf_balloc_init
+ */
+ret_code_t nrf_twi_sensor_init(nrf_twi_sensor_t * p_twi_sensor);
+
+/**
+ * @brief Function for reading sensor register.
+ *
+ * @param[in] p_instance Pointer to sensor instance.
+ * @param[in] sensor_addr Sensor address.
+ * @param[in] reg_address Register address.
+ * @param[in] user_cb User callback.
+ * @param[out] p_data Pointer to data save location.
+ * @param[in] length Number of bytes to read.
+ *
+ * @retval NRF_ERROR_NO_MEM If there is no memory in sensor buffer
+ * @retval NRF_SUCCESS If the operation was successful.
+ * @retval other Error code from TWI manager @ref nrf_twi_mngr_schedule.
+ */
+ret_code_t nrf_twi_sensor_reg_read(nrf_twi_sensor_t const * p_instance,
+ uint8_t sensor_addr,
+ uint8_t reg_address,
+ nrf_twi_sensor_reg_cb_t user_cb,
+ uint8_t * p_data,
+ uint8_t length);
+
+/**
+ * @brief Function for writing to sensor.
+ *
+ * @param[in] p_instance Pointer to sensor instance.
+ * @param[in] sensor_addr Sensor address.
+ * @param[in] p_data Pointer to data to be written.
+ * @param[in] length Number of bytes to write.
+ * @param[in] copy_flag If true, p_data is copied into internal static buffer.
+ *
+ * @note Most of the time, to write to sensors register, first byte in p_data has to be
+ * register address.
+ *
+ * @retval NRF_ERROR_NO_MEM If there is no memory in sensor buffer
+ * @retval NRF_ERROR_INVALID_LENGTH If trying to copy more bytes than
+ * NRF_TWI_SENSOR_SEND_BUF_SIZE.
+ * @retval NRF_SUCCESS If the operation was successful.
+ * @retval other Error code from TWI manager @ref nrf_twi_mngr_schedule.
+ */
+ret_code_t nrf_twi_sensor_write(nrf_twi_sensor_t const * p_instance,
+ uint8_t sensor_addr,
+ uint8_t const * p_data,
+ uint8_t length,
+ bool copy_flag);
+
+/**
+ * @brief Function for writing to sensor register.
+ *
+ * @param[in] p_instance Pointer to sensor instance.
+ * @param[in] sensor_addr Sensor address.
+ * @param[in] reg_address Register address.
+ * @param[in] p_data Pointer to data to be written.
+ * @param[in] length Number of bytes to write.
+ *
+ * @note Data is copied into internal buffer.
+ * Length has to be less than NRF_TWI_SENSOR_SEND_BUF_SIZE.
+ *
+ * @retval NRF_ERROR_NO_MEM If there is no memory in sensor buffer
+ * @retval NRF_ERROR_INVALID_LENGTH If trying to copy more bytes than
+ * NRF_TWI_SENSOR_SEND_BUF_SIZE - 1.
+ * One byte reserved for register address.
+ * @retval NRF_SUCCESS If the operation was successful.
+ * @retval other Error code from TWI manager @ref nrf_twi_mngr_schedule.
+ */
+ret_code_t nrf_twi_sensor_reg_write(nrf_twi_sensor_t const * p_instance,
+ uint8_t sensor_addr,
+ uint8_t reg_address,
+ uint8_t * p_data,
+ uint8_t length);
+
+/**
+ * @brief Function for getting maximum utilization of sensor buffer.
+ *
+ * @param[in] p_twi_sensor Pointer to sensor buffer.
+ *
+ * @return Maximum utilization.
+ */
+__STATIC_INLINE uint8_t nrf_twi_sensor_max_util_get(nrf_twi_sensor_t const * p_twi_sensor);
+#ifndef SUPPRESS_INLINE_IMPLEMENTATION
+__STATIC_INLINE uint8_t nrf_twi_sensor_max_util_get(nrf_twi_sensor_t const * p_twi_sensor)
+{
+ return nrf_balloc_max_utilization_get(p_twi_sensor->p_pool);
+}
+#endif //SUPPRESS_INLINE_IMPLEMENTATION
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // NRF_SENSOR_COMMON_H
+
+/** @} */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/uart/app_uart.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/uart/app_uart.c
new file mode 100644
index 0000000..a5dd337
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/uart/app_uart.c
@@ -0,0 +1,160 @@
+/**
+ * Copyright (c) 2015 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#include "sdk_common.h"
+#if NRF_MODULE_ENABLED(APP_UART)
+#include "app_uart.h"
+#include "nrf_drv_uart.h"
+#include "nrf_assert.h"
+
+static uint8_t tx_buffer[1];
+static uint8_t rx_buffer[1];
+static volatile bool rx_done;
+static app_uart_event_handler_t m_event_handler; /**< Event handler function. */
+static nrf_drv_uart_t app_uart_inst = NRF_DRV_UART_INSTANCE(APP_UART_DRIVER_INSTANCE);
+
+static void uart_event_handler(nrf_drv_uart_event_t * p_event, void* p_context)
+{
+ if (p_event->type == NRF_DRV_UART_EVT_RX_DONE)
+ {
+ app_uart_evt_t app_uart_event;
+ app_uart_event.evt_type = APP_UART_DATA;
+ app_uart_event.data.value = p_event->data.rxtx.p_data[0];
+ (void)nrf_drv_uart_rx(&app_uart_inst, rx_buffer, 1);
+ rx_done = true;
+ m_event_handler(&app_uart_event);
+ }
+ else if (p_event->type == NRF_DRV_UART_EVT_ERROR)
+ {
+ app_uart_evt_t app_uart_event;
+ app_uart_event.evt_type = APP_UART_COMMUNICATION_ERROR;
+ app_uart_event.data.error_communication = p_event->data.error.error_mask;
+ (void)nrf_drv_uart_rx(&app_uart_inst, rx_buffer, 1);
+ m_event_handler(&app_uart_event);
+ }
+ else if (p_event->type == NRF_DRV_UART_EVT_TX_DONE)
+ {
+ // Last byte from FIFO transmitted, notify the application.
+ // Notify that new data is available if this was first byte put in the buffer.
+ app_uart_evt_t app_uart_event;
+ app_uart_event.evt_type = APP_UART_TX_EMPTY;
+ m_event_handler(&app_uart_event);
+ }
+}
+
+uint32_t app_uart_init(const app_uart_comm_params_t * p_comm_params,
+ app_uart_buffers_t * p_buffers,
+ app_uart_event_handler_t event_handler,
+ app_irq_priority_t irq_priority)
+{
+ nrf_drv_uart_config_t config = NRF_DRV_UART_DEFAULT_CONFIG;
+ config.baudrate = (nrf_uart_baudrate_t)p_comm_params->baud_rate;
+ config.hwfc = (p_comm_params->flow_control == APP_UART_FLOW_CONTROL_DISABLED) ?
+ NRF_UART_HWFC_DISABLED : NRF_UART_HWFC_ENABLED;
+ config.interrupt_priority = irq_priority;
+ config.parity = p_comm_params->use_parity ? NRF_UART_PARITY_INCLUDED : NRF_UART_PARITY_EXCLUDED;
+ config.pselcts = p_comm_params->cts_pin_no;
+ config.pselrts = p_comm_params->rts_pin_no;
+ config.pselrxd = p_comm_params->rx_pin_no;
+ config.pseltxd = p_comm_params->tx_pin_no;
+
+ m_event_handler = event_handler;
+
+ rx_done = false;
+
+ uint32_t err_code = nrf_drv_uart_init(&app_uart_inst, &config, uart_event_handler);
+ VERIFY_SUCCESS(err_code);
+
+ // Turn on receiver if RX pin is connected
+ if (p_comm_params->rx_pin_no != UART_PIN_DISCONNECTED)
+ {
+ return nrf_drv_uart_rx(&app_uart_inst, rx_buffer,1);
+ }
+ else
+ {
+ return NRF_SUCCESS;
+ }
+}
+
+
+uint32_t app_uart_get(uint8_t * p_byte)
+{
+ ASSERT(p_byte);
+ uint32_t err_code = NRF_SUCCESS;
+ if (rx_done)
+ {
+ *p_byte = rx_buffer[0];
+ rx_done = false;
+ }
+ else
+ {
+ err_code = NRF_ERROR_NOT_FOUND;
+ }
+ return err_code;
+}
+
+uint32_t app_uart_put(uint8_t byte)
+{
+ tx_buffer[0] = byte;
+ ret_code_t ret = nrf_drv_uart_tx(&app_uart_inst, tx_buffer, 1);
+ if (NRF_ERROR_BUSY == ret)
+ {
+ return NRF_ERROR_NO_MEM;
+ }
+ else if (ret != NRF_SUCCESS)
+ {
+ return NRF_ERROR_INTERNAL;
+ }
+ else
+ {
+ return NRF_SUCCESS;
+ }
+}
+
+uint32_t app_uart_flush(void)
+{
+ return NRF_SUCCESS;
+}
+
+uint32_t app_uart_close(void)
+{
+ nrf_drv_uart_uninit(&app_uart_inst);
+ return NRF_SUCCESS;
+}
+#endif //NRF_MODULE_ENABLED(APP_UART)
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/uart/app_uart.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/uart/app_uart.h
new file mode 100644
index 0000000..1858267
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/uart/app_uart.h
@@ -0,0 +1,262 @@
+/**
+ * Copyright (c) 2013 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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
+ *
+ * @defgroup app_uart UART module
+ * @{
+ * @ingroup app_common
+ *
+ * @brief UART module interface.
+ */
+
+#ifndef APP_UART_H__
+#define APP_UART_H__
+
+#include <stdint.h>
+#include <stdbool.h>
+#include "app_util_platform.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define UART_PIN_DISCONNECTED 0xFFFFFFFF /**< Value indicating that no pin is connected to this UART register. */
+
+/**@brief UART Flow Control modes for the peripheral.
+ */
+typedef enum
+{
+ APP_UART_FLOW_CONTROL_DISABLED, /**< UART Hw Flow Control is disabled. */
+ APP_UART_FLOW_CONTROL_ENABLED, /**< Standard UART Hw Flow Control is enabled. */
+} app_uart_flow_control_t;
+
+/**@brief UART communication structure holding configuration settings for the peripheral.
+ */
+typedef struct
+{
+ uint32_t rx_pin_no; /**< RX pin number. */
+ uint32_t tx_pin_no; /**< TX pin number. */
+ uint32_t rts_pin_no; /**< RTS pin number, only used if flow control is enabled. */
+ uint32_t cts_pin_no; /**< CTS pin number, only used if flow control is enabled. */
+ app_uart_flow_control_t flow_control; /**< Flow control setting, if flow control is used, the system will use low power UART mode, based on CTS signal. */
+ bool use_parity; /**< Even parity if TRUE, no parity if FALSE. */
+ uint32_t baud_rate; /**< Baud rate configuration. */
+} app_uart_comm_params_t;
+
+/**@brief UART buffer for transmitting/receiving data.
+ */
+typedef struct
+{
+ uint8_t * rx_buf; /**< Pointer to the RX buffer. */
+ uint32_t rx_buf_size; /**< Size of the RX buffer. */
+ uint8_t * tx_buf; /**< Pointer to the TX buffer. */
+ uint32_t tx_buf_size; /**< Size of the TX buffer. */
+} app_uart_buffers_t;
+
+/**@brief Enumeration which defines events used by the UART module upon data reception or error.
+ *
+ * @details The event type is used to indicate the type of additional information in the event
+ * @ref app_uart_evt_t.
+ */
+typedef enum
+{
+ APP_UART_DATA_READY, /**< An event indicating that UART data has been received. The data is available in the FIFO and can be fetched using @ref app_uart_get. */
+ APP_UART_FIFO_ERROR, /**< An error in the FIFO module used by the app_uart module has occured. The FIFO error code is stored in app_uart_evt_t.data.error_code field. */
+ APP_UART_COMMUNICATION_ERROR, /**< An communication error has occured during reception. The error is stored in app_uart_evt_t.data.error_communication field. */
+ APP_UART_TX_EMPTY, /**< An event indicating that UART has completed transmission of all available data in the TX FIFO. */
+ APP_UART_DATA, /**< An event indicating that UART data has been received, and data is present in data field. This event is only used when no FIFO is configured. */
+} app_uart_evt_type_t;
+
+/**@brief Struct containing events from the UART module.
+ *
+ * @details The app_uart_evt_t is used to notify the application of asynchronous events when data
+ * are received on the UART peripheral or in case an error occured during data reception.
+ */
+typedef struct
+{
+ app_uart_evt_type_t evt_type; /**< Type of event. */
+ union
+ {
+ uint32_t error_communication; /**< Field used if evt_type is: APP_UART_COMMUNICATION_ERROR. This field contains the value in the ERRORSRC register for the UART peripheral. The UART_ERRORSRC_x defines from nrf5x_bitfields.h can be used to parse the error code. See also the \nRFXX Series Reference Manual for specification. */
+ uint32_t error_code; /**< Field used if evt_type is: NRF_ERROR_x. Additional status/error code if the error event type is APP_UART_FIFO_ERROR. This error code refer to errors defined in nrf_error.h. */
+ uint8_t value; /**< Field used if evt_type is: NRF_ERROR_x. Additional status/error code if the error event type is APP_UART_FIFO_ERROR. This error code refer to errors defined in nrf_error.h. */
+ } data;
+} app_uart_evt_t;
+
+/**@brief Function for handling app_uart event callback.
+ *
+ * @details Upon an event in the app_uart module this callback function will be called to notify
+ * the application about the event.
+ *
+ * @param[in] p_app_uart_event Pointer to UART event.
+ */
+typedef void (* app_uart_event_handler_t) (app_uart_evt_t * p_app_uart_event);
+
+/**@brief Macro for safe initialization of the UART module in a single user instance when using
+ * a FIFO together with UART.
+ *
+ * @param[in] P_COMM_PARAMS Pointer to a UART communication structure: app_uart_comm_params_t
+ * @param[in] RX_BUF_SIZE Size of desired RX buffer, must be a power of 2 or ZERO (No FIFO).
+ * @param[in] TX_BUF_SIZE Size of desired TX buffer, must be a power of 2 or ZERO (No FIFO).
+ * @param[in] EVT_HANDLER Event handler function to be called when an event occurs in the
+ * UART module.
+ * @param[in] IRQ_PRIO IRQ priority, app_irq_priority_t, for the UART module irq handler.
+ * @param[out] ERR_CODE The return value of the UART initialization function will be
+ * written to this parameter.
+ *
+ * @note Since this macro allocates a buffer and registers the module as a GPIOTE user when flow
+ * control is enabled, it must only be called once.
+ */
+#define APP_UART_FIFO_INIT(P_COMM_PARAMS, RX_BUF_SIZE, TX_BUF_SIZE, EVT_HANDLER, IRQ_PRIO, ERR_CODE) \
+ do \
+ { \
+ app_uart_buffers_t buffers; \
+ static uint8_t rx_buf[RX_BUF_SIZE]; \
+ static uint8_t tx_buf[TX_BUF_SIZE]; \
+ \
+ buffers.rx_buf = rx_buf; \
+ buffers.rx_buf_size = sizeof (rx_buf); \
+ buffers.tx_buf = tx_buf; \
+ buffers.tx_buf_size = sizeof (tx_buf); \
+ ERR_CODE = app_uart_init(P_COMM_PARAMS, &buffers, EVT_HANDLER, IRQ_PRIO); \
+ } while (0)
+
+/**@brief Macro for safe initialization of the UART module in a single user instance.
+ *
+ * @param[in] P_COMM_PARAMS Pointer to a UART communication structure: app_uart_comm_params_t
+ * @param[in] EVT_HANDLER Event handler function to be called when an event occurs in the
+ * UART module.
+ * @param[in] IRQ_PRIO IRQ priority, app_irq_priority_t, for the UART module irq handler.
+ * @param[out] ERR_CODE The return value of the UART initialization function will be
+ * written to this parameter.
+ *
+ * @note Since this macro allocates registers the module as a GPIOTE user when flow control is
+ * enabled, it must only be called once.
+ */
+#define APP_UART_INIT(P_COMM_PARAMS, EVT_HANDLER, IRQ_PRIO, ERR_CODE) \
+ do \
+ { \
+ ERR_CODE = app_uart_init(P_COMM_PARAMS, NULL, EVT_HANDLER, IRQ_PRIO); \
+ } while (0)
+
+/**@brief Function for initializing the UART module. Use this initialization when several instances of the UART
+ * module are needed.
+ *
+ *
+ * @note Normally single initialization should be done using the APP_UART_INIT() or
+ * APP_UART_INIT_FIFO() macro depending on whether the FIFO should be used by the UART, as
+ * that will allocate the buffers needed by the UART module (including aligning the buffer
+ * correctly).
+
+ * @param[in] p_comm_params Pin and communication parameters.
+ * @param[in] p_buffers RX and TX buffers, NULL is FIFO is not used.
+ * @param[in] error_handler Function to be called in case of an error.
+ * @param[in] irq_priority Interrupt priority level.
+ *
+ * @retval NRF_SUCCESS If successful initialization.
+ * @retval NRF_ERROR_INVALID_LENGTH If a provided buffer is not a power of two.
+ * @retval NRF_ERROR_NULL If one of the provided buffers is a NULL pointer.
+ *
+ * The below errors are propagated by the UART module to the caller upon registration when Hardware
+ * Flow Control is enabled. When Hardware Flow Control is not used, these errors cannot occur.
+ * @retval NRF_ERROR_INVALID_STATE The GPIOTE module is not in a valid state when registering
+ * the UART module as a user.
+ * @retval NRF_ERROR_INVALID_PARAM The UART module provides an invalid callback function when
+ * registering the UART module as a user.
+ * Or the value pointed to by *p_uart_uid is not a valid
+ * GPIOTE number.
+ * @retval NRF_ERROR_NO_MEM GPIOTE module has reached the maximum number of users.
+ */
+uint32_t app_uart_init(const app_uart_comm_params_t * p_comm_params,
+ app_uart_buffers_t * p_buffers,
+ app_uart_event_handler_t error_handler,
+ app_irq_priority_t irq_priority);
+
+/**@brief Function for getting a byte from the UART.
+ *
+ * @details This function will get the next byte from the RX buffer. If the RX buffer is empty
+ * an error code will be returned and the app_uart module will generate an event upon
+ * reception of the first byte which is added to the RX buffer.
+ *
+ * @param[out] p_byte Pointer to an address where next byte received on the UART will be copied.
+ *
+ * @retval NRF_SUCCESS If a byte has been received and pushed to the pointer provided.
+ * @retval NRF_ERROR_NOT_FOUND If no byte is available in the RX buffer of the app_uart module.
+ */
+uint32_t app_uart_get(uint8_t * p_byte);
+
+/**@brief Function for putting a byte on the UART.
+ *
+ * @details This call is non-blocking.
+ *
+ * @param[in] byte Byte to be transmitted on the UART.
+ *
+ * @retval NRF_SUCCESS If the byte was successfully put on the TX buffer for transmission.
+ * @retval NRF_ERROR_NO_MEM If no more space is available in the TX buffer.
+ * NRF_ERROR_NO_MEM may occur if flow control is enabled and CTS signal
+ * is high for a long period and the buffer fills up.
+ * @retval NRF_ERROR_INTERNAL If UART driver reported error.
+ */
+uint32_t app_uart_put(uint8_t byte);
+
+/**@brief Function for flushing the RX and TX buffers (Only valid if FIFO is used).
+ * This function does nothing if FIFO is not used.
+ *
+ * @retval NRF_SUCCESS Flushing completed (Current implementation will always succeed).
+ */
+uint32_t app_uart_flush(void);
+
+/**@brief Function for closing the UART module.
+ *
+ * @retval NRF_SUCCESS If successfully closed.
+ * @retval NRF_ERROR_INVALID_PARAM If an invalid user id is provided or the user id differs from
+ * the current active user.
+ */
+uint32_t app_uart_close(void);
+
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif //APP_UART_H__
+
+/** @} */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/uart/app_uart_fifo.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/uart/app_uart_fifo.c
new file mode 100644
index 0000000..7ff7bd8
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/uart/app_uart_fifo.c
@@ -0,0 +1,244 @@
+/**
+ * Copyright (c) 2015 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#include "sdk_common.h"
+#if NRF_MODULE_ENABLED(APP_UART)
+#include "app_uart.h"
+#include "app_fifo.h"
+#include "nrf_drv_uart.h"
+#include "nrf_assert.h"
+
+static nrf_drv_uart_t app_uart_inst = NRF_DRV_UART_INSTANCE(APP_UART_DRIVER_INSTANCE);
+
+static __INLINE uint32_t fifo_length(app_fifo_t * const fifo)
+{
+ uint32_t tmp = fifo->read_pos;
+ return fifo->write_pos - tmp;
+}
+
+#define FIFO_LENGTH(F) fifo_length(&F) /**< Macro to calculate length of a FIFO. */
+
+
+static app_uart_event_handler_t m_event_handler; /**< Event handler function. */
+static uint8_t tx_buffer[1];
+static uint8_t rx_buffer[1];
+static bool m_rx_ovf;
+
+static app_fifo_t m_rx_fifo; /**< RX FIFO buffer for storing data received on the UART until the application fetches them using app_uart_get(). */
+static app_fifo_t m_tx_fifo; /**< TX FIFO buffer for storing data to be transmitted on the UART when TXD is ready. Data is put to the buffer on using app_uart_put(). */
+
+static void uart_event_handler(nrf_drv_uart_event_t * p_event, void* p_context)
+{
+ app_uart_evt_t app_uart_event;
+ uint32_t err_code;
+
+ switch (p_event->type)
+ {
+ case NRF_DRV_UART_EVT_RX_DONE:
+ // Write received byte to FIFO.
+ err_code = app_fifo_put(&m_rx_fifo, p_event->data.rxtx.p_data[0]);
+ if (err_code != NRF_SUCCESS)
+ {
+ app_uart_event.evt_type = APP_UART_FIFO_ERROR;
+ app_uart_event.data.error_code = err_code;
+ m_event_handler(&app_uart_event);
+ }
+ // Notify that there are data available.
+ else if (FIFO_LENGTH(m_rx_fifo) != 0)
+ {
+ app_uart_event.evt_type = APP_UART_DATA_READY;
+ m_event_handler(&app_uart_event);
+ }
+
+ // Start new RX if size in buffer.
+ if (FIFO_LENGTH(m_rx_fifo) <= m_rx_fifo.buf_size_mask)
+ {
+ (void)nrf_drv_uart_rx(&app_uart_inst, rx_buffer, 1);
+ }
+ else
+ {
+ // Overflow in RX FIFO.
+ m_rx_ovf = true;
+ }
+
+ break;
+
+ case NRF_DRV_UART_EVT_ERROR:
+ app_uart_event.evt_type = APP_UART_COMMUNICATION_ERROR;
+ app_uart_event.data.error_communication = p_event->data.error.error_mask;
+ (void)nrf_drv_uart_rx(&app_uart_inst, rx_buffer, 1);
+ m_event_handler(&app_uart_event);
+ break;
+
+ case NRF_DRV_UART_EVT_TX_DONE:
+ // Get next byte from FIFO.
+ if (app_fifo_get(&m_tx_fifo, tx_buffer) == NRF_SUCCESS)
+ {
+ (void)nrf_drv_uart_tx(&app_uart_inst, tx_buffer, 1);
+ }
+ else
+ {
+ // Last byte from FIFO transmitted, notify the application.
+ app_uart_event.evt_type = APP_UART_TX_EMPTY;
+ m_event_handler(&app_uart_event);
+ }
+ break;
+
+ default:
+ break;
+ }
+}
+
+
+uint32_t app_uart_init(const app_uart_comm_params_t * p_comm_params,
+ app_uart_buffers_t * p_buffers,
+ app_uart_event_handler_t event_handler,
+ app_irq_priority_t irq_priority)
+{
+ uint32_t err_code;
+
+ m_event_handler = event_handler;
+
+ if (p_buffers == NULL)
+ {
+ return NRF_ERROR_INVALID_PARAM;
+ }
+
+ // Configure buffer RX buffer.
+ err_code = app_fifo_init(&m_rx_fifo, p_buffers->rx_buf, p_buffers->rx_buf_size);
+ VERIFY_SUCCESS(err_code);
+
+ // Configure buffer TX buffer.
+ err_code = app_fifo_init(&m_tx_fifo, p_buffers->tx_buf, p_buffers->tx_buf_size);
+ VERIFY_SUCCESS(err_code);
+
+ nrf_drv_uart_config_t config = NRF_DRV_UART_DEFAULT_CONFIG;
+ config.baudrate = (nrf_uart_baudrate_t)p_comm_params->baud_rate;
+ config.hwfc = (p_comm_params->flow_control == APP_UART_FLOW_CONTROL_DISABLED) ?
+ NRF_UART_HWFC_DISABLED : NRF_UART_HWFC_ENABLED;
+ config.interrupt_priority = irq_priority;
+ config.parity = p_comm_params->use_parity ? NRF_UART_PARITY_INCLUDED : NRF_UART_PARITY_EXCLUDED;
+ config.pselcts = p_comm_params->cts_pin_no;
+ config.pselrts = p_comm_params->rts_pin_no;
+ config.pselrxd = p_comm_params->rx_pin_no;
+ config.pseltxd = p_comm_params->tx_pin_no;
+
+ err_code = nrf_drv_uart_init(&app_uart_inst, &config, uart_event_handler);
+ VERIFY_SUCCESS(err_code);
+ m_rx_ovf = false;
+
+ // Turn on receiver if RX pin is connected
+ if (p_comm_params->rx_pin_no != UART_PIN_DISCONNECTED)
+ {
+ return nrf_drv_uart_rx(&app_uart_inst, rx_buffer,1);
+ }
+ else
+ {
+ return NRF_SUCCESS;
+ }
+}
+
+
+uint32_t app_uart_flush(void)
+{
+ uint32_t err_code;
+
+ err_code = app_fifo_flush(&m_rx_fifo);
+ VERIFY_SUCCESS(err_code);
+
+ err_code = app_fifo_flush(&m_tx_fifo);
+ VERIFY_SUCCESS(err_code);
+
+ return NRF_SUCCESS;
+}
+
+
+uint32_t app_uart_get(uint8_t * p_byte)
+{
+ ASSERT(p_byte);
+ bool rx_ovf = m_rx_ovf;
+
+ ret_code_t err_code = app_fifo_get(&m_rx_fifo, p_byte);
+
+ // If FIFO was full new request to receive one byte was not scheduled. Must be done here.
+ if (rx_ovf)
+ {
+ m_rx_ovf = false;
+ uint32_t uart_err_code = nrf_drv_uart_rx(&app_uart_inst, rx_buffer, 1);
+
+ // RX resume should never fail.
+ APP_ERROR_CHECK(uart_err_code);
+ }
+
+ return err_code;
+}
+
+
+uint32_t app_uart_put(uint8_t byte)
+{
+ uint32_t err_code;
+ err_code = app_fifo_put(&m_tx_fifo, byte);
+ if (err_code == NRF_SUCCESS)
+ {
+ // The new byte has been added to FIFO. It will be picked up from there
+ // (in 'uart_event_handler') when all preceding bytes are transmitted.
+ // But if UART is not transmitting anything at the moment, we must start
+ // a new transmission here.
+ if (!nrf_drv_uart_tx_in_progress(&app_uart_inst))
+ {
+ // This operation should be almost always successful, since we've
+ // just added a byte to FIFO, but if some bigger delay occurred
+ // (some heavy interrupt handler routine has been executed) since
+ // that time, FIFO might be empty already.
+ if (app_fifo_get(&m_tx_fifo, tx_buffer) == NRF_SUCCESS)
+ {
+ err_code = nrf_drv_uart_tx(&app_uart_inst, tx_buffer, 1);
+ }
+ }
+ }
+ return err_code;
+}
+
+
+uint32_t app_uart_close(void)
+{
+ nrf_drv_uart_uninit(&app_uart_inst);
+ return NRF_SUCCESS;
+}
+#endif //NRF_MODULE_ENABLED(APP_UART)
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/uart/retarget.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/uart/retarget.c
new file mode 100644
index 0000000..8e85bca
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/uart/retarget.c
@@ -0,0 +1,176 @@
+/**
+ * Copyright (c) 2014 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#include "sdk_common.h"
+/** @file
+ *
+ * @defgroup retarget Retarget layer for stdio functions
+ * @{
+ * @ingroup app_common
+ * @} */
+#if NRF_MODULE_ENABLED(RETARGET)
+#if !defined(NRF_LOG_USES_RTT) || NRF_LOG_USES_RTT != 1
+#if !defined(HAS_SIMPLE_UART_RETARGET)
+
+
+#include <stdio.h>
+#include <stdint.h>
+#include "app_uart.h"
+#include "nrf_error.h"
+
+
+#if defined(__CC_ARM)
+
+// This part is taken from MDK-ARM template file and is required here to prevent
+// linker from selecting libraries functions that use semihosting and failing
+// because of multiple definitions of fgetc() and fputc().
+// Refer to: http://www.keil.com/support/man/docs/gsac/gsac_retargetcortex.htm
+// -- BEGIN --
+struct __FILE { int handle; /* Add whatever you need here */ };
+FILE __stdout;
+FILE __stdin;
+// --- END ---
+
+int fgetc(FILE * p_file)
+{
+ uint8_t input;
+ while (app_uart_get(&input) == NRF_ERROR_NOT_FOUND)
+ {
+ // No implementation needed.
+ }
+ return input;
+}
+
+int fputc(int ch, FILE * p_file)
+{
+ UNUSED_PARAMETER(p_file);
+
+ UNUSED_VARIABLE(app_uart_put((uint8_t)ch));
+ return ch;
+}
+
+#elif defined(__GNUC__) && defined(__SES_ARM)
+
+int __getchar(FILE * p_file)
+{
+ uint8_t input;
+ while (app_uart_get(&input) == NRF_ERROR_NOT_FOUND)
+ {
+ // No implementation needed.
+ }
+ return input;
+}
+
+int __putchar(int ch, FILE * p_file)
+{
+ UNUSED_PARAMETER(p_file);
+
+ UNUSED_VARIABLE(app_uart_put((uint8_t)ch));
+ return ch;
+}
+
+#elif defined(__GNUC__) && !defined(__SES_ARM)
+
+int _write(int file, const char * p_char, int len)
+{
+ int i;
+
+ UNUSED_PARAMETER(file);
+
+ for (i = 0; i < len; i++)
+ {
+ UNUSED_VARIABLE(app_uart_put(*p_char++));
+ }
+
+ return len;
+}
+
+int _read(int file, char * p_char, int len)
+{
+ UNUSED_PARAMETER(file);
+ while (app_uart_get((uint8_t *)p_char) == NRF_ERROR_NOT_FOUND)
+ {
+ // No implementation needed.
+ }
+
+ return 1;
+}
+#elif defined(__ICCARM__)
+
+size_t __write(int handle, const unsigned char * buffer, size_t size)
+{
+ int i;
+ UNUSED_PARAMETER(handle);
+ for (i = 0; i < size; i++)
+ {
+ UNUSED_VARIABLE(app_uart_put(*buffer++));
+ }
+ return size;
+}
+
+size_t __read(int handle, unsigned char * buffer, size_t size)
+{
+ UNUSED_PARAMETER(handle);
+ UNUSED_PARAMETER(size);
+ while (app_uart_get((uint8_t *)buffer) == NRF_ERROR_NOT_FOUND)
+ {
+ // No implementation needed.
+ }
+
+ return 1;
+}
+
+long __lseek(int handle, long offset, int whence)
+{
+ return -1;
+}
+int __close(int handle)
+{
+ return 0;
+}
+int remove(const char * filename)
+{
+ return 0;
+}
+
+#endif
+
+#endif // !defined(HAS_SIMPLE_UART_RETARGET)
+#endif // NRF_LOG_USES_RTT != 1
+#endif //NRF_MODULE_ENABLED(RETARGET)
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/usbd/app_usbd.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/usbd/app_usbd.c
new file mode 100644
index 0000000..e5cbcf8
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/usbd/app_usbd.c
@@ -0,0 +1,1766 @@
+/**
+ * Copyright (c) 2016 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#include "sdk_common.h"
+#if NRF_MODULE_ENABLED(APP_USBD)
+
+#include "app_usbd.h"
+#include "app_usbd_core.h"
+#include "nrf_power.h"
+#include "nrf_drv_clock.h"
+#include "nrf_drv_power.h"
+#if APP_USBD_CONFIG_EVENT_QUEUE_ENABLE
+#include "nrf_atfifo.h"
+#include "nrf_atomic.h"
+#endif
+
+#define NRF_LOG_MODULE_NAME app_usbd
+
+#if APP_USBD_CONFIG_LOG_ENABLED
+#define NRF_LOG_LEVEL APP_USBD_CONFIG_LOG_LEVEL
+#define NRF_LOG_INFO_COLOR APP_USBD_CONFIG_INFO_COLOR
+#define NRF_LOG_DEBUG_COLOR APP_USBD_CONFIG_DEBUG_COLOR
+#else //APP_USBD_CONFIG_LOG_ENABLED
+#define NRF_LOG_LEVEL 0
+#endif //APP_USBD_CONFIG_LOG_ENABLED
+#include "nrf_log.h"
+NRF_LOG_MODULE_REGISTER();
+
+
+/* Base variables tests */
+
+/* Check event of app_usbd_event_type_t enumerator */
+STATIC_ASSERT((int32_t)APP_USBD_EVT_FIRST_POWER == (int32_t)NRF_DRV_USBD_EVT_CNT);
+STATIC_ASSERT(sizeof(app_usbd_event_type_t) == sizeof(nrf_drv_usbd_event_type_t));
+
+STATIC_ASSERT(sizeof(app_usbd_descriptor_header_t) == 2);
+STATIC_ASSERT(sizeof(app_usbd_descriptor_device_t) == 18);
+STATIC_ASSERT(sizeof(app_usbd_descriptor_configuration_t) == 9);
+STATIC_ASSERT(sizeof(app_usbd_descriptor_iface_t) == 9);
+STATIC_ASSERT(sizeof(app_usbd_descriptor_ep_t) == 7);
+STATIC_ASSERT(sizeof(app_usbd_descriptor_iad_t) == 8);
+
+STATIC_ASSERT(sizeof(app_usbd_setup_t) == sizeof(nrf_drv_usbd_setup_t));
+
+/**
+ * @internal
+ * @defgroup app_usbd_internals USBD library internals
+ * @ingroup app_usbd
+ *
+ * Internal variables, auxiliary macros and functions of USBD library.
+ * @{
+ */
+
+#if (APP_USBD_PROVIDE_SOF_TIMESTAMP) || defined(__SDK_DOXYGEN__)
+/**
+ * @brief The last received frame number.
+ */
+static uint16_t m_last_frame;
+#endif
+
+/**
+ * @brief Variable type for endpoint configuration
+ *
+ * Each endpoint would have assigned this type of configuration structure.
+ */
+typedef struct
+{
+ /**
+ * @brief The class instance
+ *
+ * The pointer to the class instance that is connected to the endpoint.
+ */
+ app_usbd_class_inst_t const * p_cinst;
+
+ /**
+ * @brief Endpoint event handler.
+ *
+ * Event handler for the endpoint.
+ * It is set to event handler for the class instance during connection by default,
+ * but it can be then updated for as a reaction for @ref APP_USBD_EVT_ATTACHED event.
+ * This way we can speed up the interpretation of endpoint related events.
+ */
+ app_usbd_ep_event_handler_t event_handler;
+}app_usbd_ep_conf_t;
+
+
+/**
+ * @brief Internal event with SOF counter.
+ */
+typedef struct
+{
+ app_usbd_internal_evt_t evt; //!< Internal event type
+
+#if (APP_USBD_CONFIG_SOF_HANDLING_MODE == APP_USBD_SOF_HANDLING_COMPRESS_QUEUE) \
+ || defined(__SDK_DOXYGEN__)
+ uint16_t sof_cnt; //!< Number of the SOF events that appears before current event
+ uint16_t start_frame; //!< Number of the SOF frame that starts this event
+#endif // (APP_USBD_CONFIG_SOF_HANDLING_MODE == APP_USBD_SOF_HANDLING_COMPRESS_QUEUE)
+
+} app_usbd_internal_queue_evt_t;
+
+#if (APP_USBD_CONFIG_EVENT_QUEUE_ENABLE) || defined(__SDK_DOXYGEN__)
+/**
+ * @brief Event queue
+ *
+ * The queue with events to be processed
+ */
+NRF_ATFIFO_DEF(m_event_queue, app_usbd_internal_queue_evt_t, APP_USBD_CONFIG_EVENT_QUEUE_SIZE);
+
+#if (APP_USBD_CONFIG_SOF_HANDLING_MODE == APP_USBD_SOF_HANDLING_COMPRESS_QUEUE) \
+ || defined(__SDK_DOXYGEN__)
+
+/** @brief SOF events counter */
+static nrf_atomic_u32_t m_sof_events_cnt;
+
+/** @brief SOF Frame counter */
+static uint16_t m_event_frame;
+
+// Limit of SOF events stacked until warning message.
+#define APP_USBD_SOF_WARNING_LIMIT 500
+#endif // (APP_USBD_CONFIG_SOF_HANDLING_MODE == APP_USBD_SOF_HANDLING_COMPRESS_QUEUE)
+ // || defined(__SDK_DOXYGEN__)
+
+#endif
+
+/**
+ * @brief Instances connected with IN endpoints
+ *
+ * Array of instance pointers connected with every IN endpoint.
+ * @sa m_epout_instances
+ */
+static app_usbd_ep_conf_t m_epin_conf[NRF_USBD_EPIN_CNT];
+
+/**
+ * @brief Instances connected with OUT endpoints
+ *
+ * Array of instance pointers connected with every OUT endpoint.
+ * @sa m_epin_instances
+ */
+static app_usbd_ep_conf_t m_epout_conf[NRF_USBD_EPIN_CNT];
+
+/**
+ * @brief Beginning of classes list
+ *
+ * All enabled in current configuration instances are connected into
+ * a single linked list chain.
+ * This variable points to first element.
+ * Core class instance (connected to endpoint 0) is not listed here.
+ */
+static app_usbd_class_inst_t const * m_p_first_cinst;
+
+/**
+ * @brief Classes list that requires SOF events
+ *
+ * @todo RK Implement and documentation
+ */
+static app_usbd_class_inst_t const * m_p_first_sof_cinst;
+
+/**
+ * @brief Default configuration (when NULL is passed to @ref app_usbd_init).
+ */
+static const app_usbd_config_t m_default_conf = {
+#if (!(APP_USBD_CONFIG_EVENT_QUEUE_ENABLE)) || defined(__SDK_DOXYGEN__)
+ .ev_handler = app_usbd_event_execute,
+#endif
+#if (APP_USBD_CONFIG_EVENT_QUEUE_ENABLE) || defined(__SDK_DOXYGEN__)
+ .ev_isr_handler = NULL,
+#endif
+ .ev_state_proc = NULL,
+ .enable_sof = false
+};
+
+/**
+ * @brief SUSPEND state machine states
+ *
+ * The enumeration of internal SUSPEND state machine states.
+ */
+typedef enum
+{
+ SUSTATE_STOPPED, /**< The USB driver was not started */
+ SUSTATE_STARTED, /**< The USB driver was started - waiting for USB RESET */
+ SUSTATE_ACTIVE, /**< Active state */
+ SUSTATE_SUSPENDING, /**< Suspending - waiting for the user to acknowledge */
+ SUSTATE_SUSPEND, /**< Suspended */
+ SUSTATE_RESUMING, /**< Resuming - waiting for clock */
+ SUSTATE_WAKINGUP_WAITING_HFCLK_WREQ, /**< Waking up - waiting for clock and WUREQ from driver */
+ SUSTATE_WAKINGUP_WAITING_HFCLK, /**< Waking up - waiting for HFCLK (WUREQ detected) */
+ SUSTATE_WAKINGUP_WAITING_WREQ, /**< Waking up - waiting for WREQ (HFCLK active) */
+}app_usbd_sustate_t;
+
+/**
+ * @brief Current suspend state
+ *
+ * The state of the suspend state machine
+ */
+static app_usbd_sustate_t m_sustate;
+
+/**
+ * @brief Remote wake-up register/unregister
+ *
+ * Counter incremented when appended instance required remote wake-up functionality.
+ * It should be decremented when the class is removed.
+ * When this counter is not zero, remote wake-up functionality is activated inside core.
+ */
+static uint8_t m_rwu_registered_counter;
+
+/**
+ * @brief Current configuration.
+ */
+static app_usbd_config_t m_current_conf;
+
+/**
+ * @brief Class interface call: event handler
+ *
+ * @ref app_usbd_class_interface_t::event_handler
+ *
+ * @param[in] p_cinst Class instance
+ * @param[in] p_event Event passed to class instance
+ *
+ * @return Standard error code @ref ret_code_t
+ * @retval NRF_SUCCESS event handled successfully
+ * @retval NRF_ERROR_NOT_SUPPORTED unsupported event
+ * */
+static inline ret_code_t class_event_handler(app_usbd_class_inst_t const * const p_cinst,
+ app_usbd_complex_evt_t const * const p_event)
+{
+ ASSERT(p_cinst != NULL);
+ ASSERT(p_cinst->p_class_methods != NULL);
+ ASSERT(p_cinst->p_class_methods->event_handler != NULL);
+ return p_cinst->p_class_methods->event_handler(p_cinst, p_event);
+}
+
+#if (APP_USBD_CONFIG_EVENT_QUEUE_ENABLE) || defined(__SDK_DOXYGEN__)
+/**
+ * @brief User event handler call (passed via configuration).
+ *
+ * @param p_event Handler of an event that is going to be added into queue.
+ * @param queued The event is visible in the queue.
+ */
+static inline void user_event_handler(app_usbd_internal_evt_t const * const p_event, bool queued)
+{
+ if ((m_current_conf.ev_isr_handler) != NULL)
+ {
+ m_current_conf.ev_isr_handler(p_event, queued);
+ }
+}
+#endif
+
+/**
+ * @brief User event processor call (passed via configuration)
+ *
+ * @param event Event type.
+ */
+static inline void user_event_state_proc(app_usbd_event_type_t event)
+{
+ if ((m_current_conf.ev_state_proc) != NULL)
+ {
+ m_current_conf.ev_state_proc(event);
+ }
+}
+
+/**
+ * @brief Find a specified descriptor
+ *
+ * @param[in] p_cinst Class instance
+ * @param[in] desc_type Descriptor type @ref app_usbd_descriptor_t
+ * @param[in] desc_index Descriptor index
+ * @param[out] p_desc Pointer to escriptor
+ * @param[out] p_desc_len Length of descriptor
+ *
+ * @return Standard error code @ref ret_code_t
+ * @retval NRF_SUCCESS descriptor successfully found
+ * @retval NRF_ERROR_NOT_FOUND descriptor not found
+ * */
+ret_code_t app_usbd_class_descriptor_find(app_usbd_class_inst_t const * const p_cinst,
+ uint8_t desc_type,
+ uint8_t desc_index,
+ uint8_t * p_desc,
+ size_t * p_desc_len)
+{
+ app_usbd_class_descriptor_ctx_t siz;
+ APP_USBD_CLASS_DESCRIPTOR_INIT(&siz);
+ uint32_t total_size = 0;
+ while(p_cinst->p_class_methods->feed_descriptors(&siz, p_cinst, NULL, sizeof(uint8_t)))
+ {
+ total_size++;
+ }
+
+ uint8_t cur_len = 0;
+ uint32_t cur_size = 0;
+
+ uint8_t index = 0;
+ app_usbd_class_descriptor_ctx_t descr;
+ APP_USBD_CLASS_DESCRIPTOR_INIT(&descr);
+
+ while(cur_size < total_size)
+ {
+ /* First byte of a descriptor is its size */
+ UNUSED_RETURN_VALUE(p_cinst->p_class_methods->feed_descriptors(&descr,
+ p_cinst,
+ &cur_len,
+ sizeof(uint8_t)));
+
+ /* Second byte is type of the descriptor */
+ uint8_t type;
+ UNUSED_RETURN_VALUE(p_cinst->p_class_methods->feed_descriptors(&descr,
+ p_cinst,
+ &type,
+ sizeof(uint8_t)));
+
+ if(type == desc_type)
+ {
+ if(index == desc_index)
+ {
+ /* Copy the length of descriptor to *p_desc_len */
+ *p_desc_len = cur_len;
+ /* Two first bytes of descriptor have already been fed - copy them to *p_desc */
+ *p_desc++ = cur_len;
+ *p_desc++ = desc_type;
+ /* Copy the rest of descriptor to *p_desc */
+ UNUSED_RETURN_VALUE(p_cinst->p_class_methods->feed_descriptors(&descr,
+ p_cinst,
+ p_desc,
+ cur_len-2));
+ return NRF_SUCCESS;
+ }
+ else
+ {
+ index++;
+ }
+ }
+ /* Fast-forward through unmatched descriptor */
+ UNUSED_RETURN_VALUE(p_cinst->p_class_methods->feed_descriptors(&descr,
+ p_cinst,
+ NULL,
+ cur_len-2));
+ cur_size += cur_len;
+ }
+ return NRF_ERROR_NOT_FOUND;
+}
+
+/**
+ * @brief Access into selected endpoint configuration structure
+ *
+ * @param ep Endpoint address
+ * @return A pointer to the endpoint configuration structure
+ *
+ * @note This function would assert when endpoint number is not correct and debugging is enabled.
+ */
+static app_usbd_ep_conf_t * app_usbd_ep_conf_access(nrf_drv_usbd_ep_t ep)
+{
+ if (NRF_USBD_EPIN_CHECK(ep))
+ {
+ uint8_t nr = NRF_USBD_EP_NR_GET(ep);
+ ASSERT(nr < NRF_USBD_EPIN_CNT);
+ return &m_epin_conf[nr];
+ }
+ else
+ {
+ uint8_t nr = NRF_USBD_EP_NR_GET(ep);
+ ASSERT(nr < NRF_USBD_EPOUT_CNT);
+ return &m_epout_conf[nr];
+ }
+}
+
+/**
+ * @brief Accessing instance connected with selected endpoint
+ *
+ * @param ep Endpoint number
+ *
+ * @return The pointer to the instance connected with endpoint
+ */
+static inline app_usbd_class_inst_t const * app_usbd_ep_instance_get(nrf_drv_usbd_ep_t ep)
+{
+ return app_usbd_ep_conf_access(ep)->p_cinst;
+}
+
+/**
+ * @brief Connect instance with selected endpoint
+ *
+ * This function configures instance connected to endpoint but also sets
+ * default event handler function pointer.
+ *
+ * @param ep Endpoint number
+ * @param p_cinst The instance to connect into the selected endpoint.
+ * NULL if endpoint is going to be disconnected.
+ *
+ * @note Disconnecting EP0 is not allowed and protected by assertion.
+ */
+static void app_usbd_ep_instance_set(nrf_drv_usbd_ep_t ep, app_usbd_class_inst_t const * p_cinst)
+{
+ app_usbd_ep_conf_t * p_ep_conf = app_usbd_ep_conf_access(ep);
+ /* Set instance and default event handler */
+ p_ep_conf->p_cinst = p_cinst;
+ if (p_cinst == NULL)
+ {
+ ASSERT((ep != NRF_DRV_USBD_EPOUT0) && (ep != NRF_DRV_USBD_EPIN0)); /* EP0 should never be disconnected */
+ p_ep_conf->event_handler = NULL;
+ }
+ else
+ {
+ p_ep_conf->event_handler = p_cinst->p_class_methods->event_handler;
+ }
+}
+
+/**
+ * @brief Call the core handler
+ *
+ * Core instance is special kind of instance that is connected only to endpoint 0.
+ * It is not present in instance list.
+ * This auxiliary function makes future changes easier.
+ * Just call the event instance for core module here.
+ */
+static inline ret_code_t app_usbd_core_handler_call(app_usbd_internal_evt_t const * const p_event)
+{
+ return m_epout_conf[0].event_handler(
+ m_epout_conf[0].p_cinst,
+ (app_usbd_complex_evt_t const *)p_event);
+}
+
+
+
+/**
+ * @brief Add event for execution
+ *
+ * Dependent on configuration event would be executed in place or would be added into queue
+ * to be executed later.
+ *
+ * @param p_event Event to be executed
+ */
+static inline void app_usbd_event_add(app_usbd_internal_evt_t const * const p_event)
+{
+#if (APP_USBD_CONFIG_EVENT_QUEUE_ENABLE)
+
+#if (APP_USBD_CONFIG_SOF_HANDLING_MODE == APP_USBD_SOF_HANDLING_COMPRESS_QUEUE)
+ if (p_event->app_evt.type == APP_USBD_EVT_DRV_SOF)
+ {
+ CRITICAL_REGION_ENTER();
+ if (m_sof_events_cnt == 0)
+ {
+ m_event_frame = p_event->drv_evt.data.sof.framecnt;
+ }
+ UNUSED_RETURN_VALUE(nrf_atomic_u32_add(&m_sof_events_cnt, 1));
+ CRITICAL_REGION_EXIT();
+
+ user_event_handler(p_event, true);
+ if (m_sof_events_cnt == APP_USBD_SOF_WARNING_LIMIT)
+ {
+ NRF_LOG_WARNING("Stacked over %d SOF events.", APP_USBD_SOF_WARNING_LIMIT);
+ }
+ return;
+ }
+#endif // (APP_USBD_CONFIG_SOF_HANDLING_MODE == APP_USBD_SOF_HANDLING_COMPRESS_QUEUE)
+
+ if (APP_USBD_CONFIG_SOF_HANDLING_MODE == APP_USBD_SOF_HANDLING_INTERRUPT)
+ {
+ if (p_event->app_evt.type == APP_USBD_EVT_DRV_SOF)
+ {
+ user_event_handler(p_event, false);
+ app_usbd_event_execute(p_event);
+ return;
+ }
+ }
+
+ nrf_atfifo_item_put_t cx;
+ app_usbd_internal_queue_evt_t * p_event_item = nrf_atfifo_item_alloc(m_event_queue, &cx);
+
+ if (NULL != p_event_item)
+ {
+ bool visible;
+ p_event_item->evt = *p_event;
+
+#if (APP_USBD_CONFIG_SOF_HANDLING_MODE == APP_USBD_SOF_HANDLING_COMPRESS_QUEUE)
+ CRITICAL_REGION_ENTER();
+ p_event_item->start_frame = m_event_frame - m_sof_events_cnt + 1;
+ p_event_item->sof_cnt = nrf_atomic_u32_fetch_store(&m_sof_events_cnt, 0);
+ CRITICAL_REGION_EXIT();
+#endif // (APP_USBD_CONFIG_SOF_HANDLING_MODE == APP_USBD_SOF_HANDLING_COMPRESS_QUEUE)
+
+ visible = nrf_atfifo_item_put(m_event_queue, &cx);
+ user_event_handler(p_event, visible);
+ }
+ else
+ {
+ NRF_LOG_ERROR("Event queue full.");
+ }
+#else
+ m_current_conf.ev_handler(p_event);
+#endif
+}
+
+/**
+ * @brief Power event handler
+ *
+ * The function that pushes power events into the queue
+ * @param p_event
+ */
+#if APP_USBD_CONFIG_POWER_EVENTS_PROCESS
+static void app_usbd_power_event_handler(nrf_drv_power_usb_evt_t event)
+{
+ switch(event)
+ {
+ case NRF_DRV_POWER_USB_EVT_DETECTED:
+ {
+ static const app_usbd_internal_evt_t ev = {
+ .type = APP_USBD_EVT_POWER_DETECTED
+ };
+ app_usbd_event_add(&ev);
+ break;
+ }
+ case NRF_DRV_POWER_USB_EVT_REMOVED:
+ {
+ static const app_usbd_internal_evt_t ev = {
+ .type = APP_USBD_EVT_POWER_REMOVED
+ };
+ app_usbd_event_add(&ev);
+ break;
+ }
+ case NRF_DRV_POWER_USB_EVT_READY:
+ {
+ static const app_usbd_internal_evt_t ev = {
+ .type = APP_USBD_EVT_POWER_READY
+ };
+ app_usbd_event_add(&ev);
+ break;
+ }
+ default:
+ ASSERT(false);
+ }
+}
+#endif
+
+/**
+ * @brief Event handler
+ *
+ * The function that pushes the event into the queue
+ * @param p_event
+ */
+static void app_usbd_event_handler(nrf_drv_usbd_evt_t const * const p_event)
+{
+ app_usbd_event_add((app_usbd_internal_evt_t const *)p_event);
+}
+
+/**
+ * @brief HF clock ready event handler
+ *
+ * Function that is called when high frequency clock is started
+ *
+ * @param event Event type that comes from clock driver
+ */
+static void app_usbd_hfclk_ready(nrf_drv_clock_evt_type_t event)
+{
+ ASSERT(NRF_DRV_CLOCK_EVT_HFCLK_STARTED == event);
+ static const app_usbd_evt_t evt_data = {
+ .type = APP_USBD_EVT_HFCLK_READY
+ };
+ app_usbd_event_add((app_usbd_internal_evt_t const * )&evt_data);
+}
+
+/**
+ * @brief Check if the HFCLK was requested in selected suspend state machine state
+ *
+ *
+ * @param sustate State to be checked
+ *
+ * @retval true High frequency clock was requested in selected state
+ * @retval false High frequency clock was released in selected state
+ */
+static inline bool app_usbd_sustate_with_requested_hfclk(app_usbd_sustate_t sustate)
+{
+ switch(sustate)
+ {
+ case SUSTATE_STOPPED: return false;
+ case SUSTATE_STARTED: return false;
+ case SUSTATE_ACTIVE: return true;
+ case SUSTATE_SUSPENDING: return false;
+ case SUSTATE_SUSPEND: return false;
+ case SUSTATE_RESUMING: return true;
+ case SUSTATE_WAKINGUP_WAITING_HFCLK_WREQ: return true;
+ case SUSTATE_WAKINGUP_WAITING_HFCLK: return true;
+ case SUSTATE_WAKINGUP_WAITING_WREQ: return true;
+ default:
+ return false;
+ }
+}
+
+/**
+ * @brief Check it the HFCLK is running in selected suspend state machine state
+ *
+ * @param sustate State to be checked
+ *
+ * @retval true High frequency clock is running in selected state
+ * @retval false High frequency clock is released in selected state
+ */
+static inline bool app_usbd_sustate_with_running_hfclk(app_usbd_sustate_t sustate)
+{
+ switch(sustate)
+ {
+ case SUSTATE_STOPPED: return false;
+ case SUSTATE_STARTED: return false;
+ case SUSTATE_ACTIVE: return true;
+ case SUSTATE_SUSPENDING: return false;
+ case SUSTATE_SUSPEND: return false;
+ case SUSTATE_RESUMING: return false;
+ case SUSTATE_WAKINGUP_WAITING_HFCLK_WREQ: return false;
+ case SUSTATE_WAKINGUP_WAITING_HFCLK: return false;
+ case SUSTATE_WAKINGUP_WAITING_WREQ: return true;
+ default:
+ return false;
+ }
+}
+
+/**
+ * @brief Get current suspend state machine state
+ *
+ * @return The state of the suspend state machine
+ */
+static inline app_usbd_sustate_t sustate_get(void)
+{
+ return m_sustate;
+}
+
+/**
+ * @brief Set current suspend state machine state
+ *
+ * @param sustate The requested state of the state machine
+ */
+static inline void sustate_set(app_usbd_sustate_t sustate)
+{
+ if (app_usbd_sustate_with_requested_hfclk(sustate) != app_usbd_sustate_with_requested_hfclk(m_sustate))
+ {
+ if (app_usbd_sustate_with_requested_hfclk(sustate))
+ {
+ static nrf_drv_clock_handler_item_t clock_handler_item =
+ {
+ .event_handler = app_usbd_hfclk_ready
+ };
+ nrf_drv_clock_hfclk_request(&clock_handler_item);
+ }
+ else
+ {
+ nrf_drv_clock_hfclk_release();
+ }
+ }
+ if (app_usbd_sustate_with_running_hfclk(sustate) != app_usbd_sustate_with_running_hfclk(m_sustate))
+ {
+ if (app_usbd_sustate_with_running_hfclk(sustate))
+ {
+ nrf_drv_usbd_active_irq_config();
+ }
+ else
+ {
+ nrf_drv_usbd_suspend_irq_config();
+ }
+ }
+ m_sustate = sustate;
+}
+
+/**
+ * @brief Default selection function for interface
+ *
+ * This function just enables and clears interface endpoints
+ *
+ * @param p_inst See the documentation for @ref app_usbd_iface_select
+ * @param iface_idx See the documentation for @ref app_usbd_iface_select
+ * @param alternate See the documentation for @ref app_usbd_iface_select
+ * @return
+ */
+static inline ret_code_t default_iface_select(
+ app_usbd_class_inst_t const * const p_inst,
+ uint8_t iface_idx,
+ uint8_t alternate)
+{
+ ASSERT(iface_idx <= app_usbd_class_iface_count_get(p_inst));
+
+ if (alternate != 0)
+ {
+ return NRF_ERROR_INVALID_PARAM;
+ }
+
+ app_usbd_class_iface_conf_t const * p_iface = app_usbd_class_iface_get(p_inst, iface_idx);
+ uint8_t ep_count = app_usbd_class_iface_ep_count_get(p_iface);
+
+ for (uint8_t i = 0; i < ep_count; ++i)
+ {
+ /* Enable every endpoint */
+ app_usbd_class_ep_conf_t const * p_ep = app_usbd_class_iface_ep_get(p_iface, i);
+ app_usbd_ep_enable(p_ep->address);
+ }
+ return NRF_SUCCESS;
+}
+
+/**
+ * @brief Default deselection function for interface
+ *
+ * This function just disables all interface endpoints.
+ *
+ * @param p_inst See the documentation for @ref app_usbd_iface_deselect
+ * @param iface_idx See the documentation for @ref app_usbd_iface_deselect
+ */
+static inline void default_iface_deselect(
+ app_usbd_class_inst_t const * const p_inst,
+ uint8_t iface_idx)
+{
+ ASSERT(iface_idx <= app_usbd_class_iface_count_get(p_inst));
+
+ app_usbd_class_iface_conf_t const * p_iface = app_usbd_class_iface_get(p_inst, iface_idx);
+ uint8_t ep_count = app_usbd_class_iface_ep_count_get(p_iface);
+
+ for (uint8_t i = 0; i < ep_count; ++i)
+ {
+ /* Disable every endpoint */
+ app_usbd_class_ep_conf_t const * p_ep = app_usbd_class_iface_ep_get(p_iface, i);
+ app_usbd_ep_disable(p_ep->address);
+ }
+}
+
+
+/** @} */
+
+#if (APP_USBD_PROVIDE_SOF_TIMESTAMP) || defined(__SDK_DOXYGEN__)
+uint32_t app_usbd_sof_timestamp_get(void)
+{
+ return m_last_frame;
+}
+#endif
+
+ret_code_t app_usbd_init(app_usbd_config_t const * p_config)
+{
+ ASSERT(nrf_drv_clock_init_check());
+ ret_code_t ret;
+
+#if (APP_USBD_CONFIG_EVENT_QUEUE_ENABLE) || defined(__SDK_DOXYGEN__)
+ ret = NRF_ATFIFO_INIT(m_event_queue);
+ if (NRF_SUCCESS != ret)
+ {
+ return NRF_ERROR_INTERNAL;
+ }
+#endif
+
+ /* This is called at the beginning to secure multiple calls to init function */
+ ret = nrf_drv_usbd_init(app_usbd_event_handler);
+ if (NRF_SUCCESS != ret)
+ {
+ return ret;
+ }
+
+ /* Clear the variables */
+ m_sustate = SUSTATE_STOPPED;
+ m_p_first_cinst = NULL;
+ m_p_first_sof_cinst = NULL;
+ memset(m_epin_conf , 0, sizeof(m_epin_conf ));
+ memset(m_epout_conf, 0, sizeof(m_epout_conf));
+ /* Save the new configuration */
+ if (p_config == NULL)
+ {
+ m_current_conf = m_default_conf;
+ }
+ else
+ {
+ m_current_conf = *p_config;
+ }
+
+#if (!(APP_USBD_CONFIG_EVENT_QUEUE_ENABLE))
+ if(m_current_conf.ev_handler == NULL)
+ {
+ m_current_conf.ev_handler = m_default_conf.ev_handler;
+ }
+#endif
+
+#if APP_USBD_CONFIG_POWER_EVENTS_PROCESS
+ ret = nrf_drv_power_init(NULL);
+ if ((ret != NRF_SUCCESS) && (ret != NRF_ERROR_MODULE_ALREADY_INITIALIZED))
+ {
+ /* This should never happen */
+ APP_ERROR_HANDLER(ret);
+ }
+#endif
+
+ /*Pin core class to required endpoints*/
+ uint8_t iface_idx;
+ app_usbd_class_iface_conf_t const * p_iface;
+ app_usbd_class_inst_t const * const p_inst = app_usbd_core_instance_access();
+ iface_idx = 0;
+ while ((p_iface = app_usbd_class_iface_get(p_inst, iface_idx++)) != NULL)
+ {
+ uint8_t ep_idx = 0;
+ app_usbd_class_ep_conf_t const * p_ep;
+ while ((p_ep = app_usbd_class_iface_ep_get(p_iface, ep_idx++)) != NULL)
+ {
+ app_usbd_ep_instance_set(app_usbd_class_ep_address_get(p_ep), p_inst);
+ }
+ }
+
+ /* Successfully attached */
+ const app_usbd_evt_t evt_data = {
+ .type = APP_USBD_EVT_INST_APPEND
+ };
+
+ ret = class_event_handler(p_inst, (app_usbd_complex_evt_t const *)(&evt_data));
+ if (NRF_SUCCESS != ret)
+ {
+ UNUSED_RETURN_VALUE(nrf_drv_usbd_uninit());
+ return ret;
+ }
+
+ return NRF_SUCCESS;
+}
+
+
+ret_code_t app_usbd_uninit(void)
+{
+#if APP_USBD_CONFIG_POWER_EVENTS_PROCESS
+ nrf_drv_power_usbevt_uninit();
+#endif
+
+ /* We get this error at very beginning but it would be used at the end of the function */
+ const ret_code_t ret = nrf_drv_usbd_uninit();
+
+ /* Unchain instance list */
+ app_usbd_class_inst_t const * * pp_inst;
+ pp_inst = &m_p_first_cinst;
+ while (NULL != (*pp_inst))
+ {
+ app_usbd_class_inst_t const * * pp_next = &app_usbd_class_data_access(*pp_inst)->p_next;
+ (*pp_inst) = NULL;
+ pp_inst = pp_next;
+ }
+
+ /* Unchain SOF list */
+ pp_inst = &m_p_first_sof_cinst;
+ while (NULL != (*pp_inst))
+ {
+ app_usbd_class_inst_t const * * pp_next = &app_usbd_class_data_access(*pp_inst)->p_sof_next;
+ (*pp_inst) = NULL;
+ pp_inst = pp_next;
+ }
+
+ /* Clear all endpoints configurations */
+ memset(m_epin_conf , 0, sizeof(m_epin_conf ));
+ memset(m_epout_conf, 0, sizeof(m_epout_conf));
+ /* Clear current configuration */
+ memset(&m_current_conf, 0, sizeof(m_current_conf));
+
+ return ret;
+}
+
+
+#if APP_USBD_CONFIG_POWER_EVENTS_PROCESS
+ret_code_t app_usbd_power_events_enable(void)
+{
+ if (!nrf_drv_usbd_is_initialized() || nrf_drv_usbd_is_enabled())
+ {
+ return NRF_ERROR_INVALID_STATE;
+ }
+
+ ASSERT((!APP_USBD_CONFIG_EVENT_QUEUE_ENABLE) || (USBD_CONFIG_IRQ_PRIORITY == POWER_CONFIG_IRQ_PRIORITY));
+
+ ret_code_t ret;
+ static const nrf_drv_power_usbevt_config_t config =
+ {
+ .handler = app_usbd_power_event_handler
+ };
+
+ ret = nrf_drv_power_usbevt_init(&config);
+ APP_ERROR_CHECK(ret);
+
+ return NRF_SUCCESS;
+}
+#endif /* APP_USBD_CONFIG_POWER_EVENTS_PROCESS */
+
+
+void app_usbd_enable(void)
+{
+ nrf_drv_usbd_enable();
+}
+
+
+void app_usbd_disable(void)
+{
+ ASSERT(!nrf_drv_usbd_is_started());
+ nrf_drv_usbd_disable();
+}
+
+
+void app_usbd_start(void)
+{
+ ASSERT(nrf_drv_usbd_is_enabled());
+
+ /* Check if interface numbers are in correct order */
+ if (APP_USBD_CONFIG_LOG_ENABLED)
+ {
+ uint8_t next_iface = 0;
+ for (app_usbd_class_inst_t const * * pp_inst = &m_p_first_cinst;
+ (*pp_inst) != NULL;
+ pp_inst = &(app_usbd_class_data_access(*pp_inst)->p_next))
+ {
+ uint8_t iface_idx = 0;
+ app_usbd_class_iface_conf_t const * p_iface;
+ while (NULL != (p_iface = app_usbd_class_iface_get(*pp_inst, iface_idx++)))
+ {
+ if (p_iface->number != next_iface)
+ {
+ NRF_LOG_WARNING("Unexpected interface number, expected %d, got %d",
+ next_iface,
+ p_iface->number);
+ }
+ ++next_iface;
+ }
+ }
+ }
+
+ /* Power should be already enabled - wait just in case if user calls
+ * app_usbd_start just after app_usbd_enable without waiting for the event. */
+ while (!nrf_power_usbregstatus_outrdy_get())
+ {
+ /* Wait for the power but terminate the function if USBD power disappears */
+ if (!nrf_power_usbregstatus_vbusdet_get())
+ return;
+ }
+
+ static const app_usbd_evt_t evt_data = {
+ .type = APP_USBD_EVT_START_REQ
+ };
+ app_usbd_event_add((app_usbd_internal_evt_t const * )&evt_data);
+}
+
+
+void app_usbd_stop(void)
+{
+ const app_usbd_evt_t evt_data = {
+ .type = APP_USBD_EVT_STOP_REQ
+ };
+ app_usbd_event_add((app_usbd_internal_evt_t const * )&evt_data);
+}
+
+void app_usbd_suspend_req(void)
+{
+ const app_usbd_evt_t evt_data = {
+ .type = APP_USBD_EVT_SUSPEND_REQ
+ };
+ app_usbd_event_add((app_usbd_internal_evt_t const * )&evt_data);
+}
+
+bool app_usbd_wakeup_req(void)
+{
+ ASSERT(app_usbd_class_rwu_enabled_check());
+ if (!app_usbd_core_feature_state_get(APP_USBD_SETUP_STDFEATURE_DEVICE_REMOTE_WAKEUP))
+ return false;
+
+ const app_usbd_evt_t evt_data = {
+ .type = APP_USBD_EVT_WAKEUP_REQ
+ };
+ app_usbd_event_add((app_usbd_internal_evt_t const * )&evt_data);
+ return true;
+}
+
+bool app_usbd_active_check(void)
+{
+ return (sustate_get() == SUSTATE_ACTIVE);
+}
+
+void app_usbd_event_execute(app_usbd_internal_evt_t const * const p_event)
+{
+ ASSERT(NULL != m_p_first_cinst);
+ /* If no event queue is implemented, it has to be ensured that this function is never called
+ * from the context higher than USB interrupt level
+ * If queue is implemented it would be called always from Thread level
+ * if the library is used correctly.
+ * NOTE: Higher interrupt level -> lower priority value.
+ */
+ ASSERT(USBD_CONFIG_IRQ_PRIORITY <= current_int_priority_get());
+
+ /* Note - there should never be situation that event is generated on disconnected endpoint */
+ switch (p_event->type)
+ {
+ case APP_USBD_EVT_START_REQ:
+ {
+ static const app_usbd_evt_t evt_data = {
+ .type = APP_USBD_EVT_STARTED
+ };
+
+ /* Send event to all classes */
+ UNUSED_RETURN_VALUE(app_usbd_core_handler_call((app_usbd_internal_evt_t const * )&evt_data));
+ app_usbd_all_call((app_usbd_complex_evt_t const *)&evt_data);
+ user_event_state_proc(APP_USBD_EVT_STARTED);
+
+ nrf_drv_usbd_start((NULL != m_p_first_sof_cinst) || (m_current_conf.enable_sof) || (APP_USBD_PROVIDE_SOF_TIMESTAMP));
+ app_usbd_all_iface_deselect();
+ sustate_set(SUSTATE_STARTED);
+ break;
+ }
+ case APP_USBD_EVT_STOP_REQ:
+ {
+ static const app_usbd_evt_t evt_data = {
+ .type = APP_USBD_EVT_STOPPED
+ };
+
+ app_usbd_all_iface_deselect();
+ nrf_drv_usbd_stop();
+ sustate_set(SUSTATE_STOPPED);
+
+ /* Send event to all classes */
+ app_usbd_all_call((app_usbd_complex_evt_t const * )&evt_data);
+ UNUSED_RETURN_VALUE(app_usbd_core_handler_call((app_usbd_internal_evt_t const *)&evt_data));
+ user_event_state_proc(APP_USBD_EVT_STOPPED);
+ if (app_usbd_sustate_with_requested_hfclk(sustate_get()))
+ {
+ nrf_drv_clock_hfclk_release();
+ }
+
+ break;
+ }
+ case APP_USBD_EVT_HFCLK_READY:
+ {
+ switch(sustate_get())
+ {
+ case SUSTATE_RESUMING:
+ {
+ sustate_set(SUSTATE_ACTIVE);
+ break;
+ }
+ case SUSTATE_WAKINGUP_WAITING_HFCLK_WREQ:
+ {
+ sustate_set(SUSTATE_WAKINGUP_WAITING_WREQ);
+ break;
+ }
+ case SUSTATE_WAKINGUP_WAITING_HFCLK:
+ {
+ sustate_set(SUSTATE_ACTIVE);
+ break;
+ }
+ default:
+ break; // Just ignore - it can happen in specyfic situation
+ }
+ break;
+ }
+ case APP_USBD_EVT_SUSPEND_REQ:
+ {
+ /* Suspend request can be only processed when we are in suspending state */
+ if (SUSTATE_SUSPENDING == sustate_get())
+ {
+ if (nrf_drv_usbd_suspend())
+ {
+ sustate_set(SUSTATE_SUSPEND);
+ }
+ }
+ break;
+ }
+ case APP_USBD_EVT_WAKEUP_REQ:
+ {
+ /* Suspend temporary if no suspend function was called from the application.
+ * This makes it possible to generate APP_USBD_EVT_DRV_WUREQ event from the driver */
+ if (sustate_get() == SUSTATE_SUSPENDING)
+ {
+ if (nrf_drv_usbd_suspend())
+ {
+ sustate_set(SUSTATE_SUSPEND);
+ }
+ }
+ if (nrf_drv_usbd_wakeup_req())
+ {
+ sustate_set(SUSTATE_WAKINGUP_WAITING_HFCLK_WREQ);
+ }
+ break;
+ }
+
+ case APP_USBD_EVT_DRV_SOF:
+ {
+#if (APP_USBD_PROVIDE_SOF_TIMESTAMP) || defined(__SDK_DOXYGEN__)
+ m_last_frame = p_event->drv_evt.data.sof.framecnt;
+#endif
+ user_event_state_proc(APP_USBD_EVT_DRV_SOF);
+
+ app_usbd_class_inst_t const * p_inst = app_usbd_class_sof_first_get();
+ while (NULL != p_inst)
+ {
+ ret_code_t r = class_event_handler(p_inst, (app_usbd_complex_evt_t const *)p_event);
+ UNUSED_VARIABLE(r);
+ p_inst = app_usbd_class_sof_next_get(p_inst);
+ }
+ break;
+ }
+
+ case APP_USBD_EVT_DRV_RESET:
+ {
+ app_usbd_all_iface_deselect();
+ sustate_set(SUSTATE_ACTIVE);
+ user_event_state_proc(APP_USBD_EVT_DRV_RESET);
+ /* Processing core interface (connected only to EP0) and then all instances from the list */
+ UNUSED_RETURN_VALUE(app_usbd_core_handler_call(p_event));
+ app_usbd_all_call((app_usbd_complex_evt_t const *)p_event);
+ break;
+ }
+ case APP_USBD_EVT_DRV_RESUME:
+ {
+ sustate_set(SUSTATE_RESUMING);
+ user_event_state_proc(APP_USBD_EVT_DRV_RESUME);
+ /* Processing core interface (connected only to EP0) and then all instances from the list */
+ UNUSED_RETURN_VALUE(app_usbd_core_handler_call(p_event));
+ app_usbd_all_call((app_usbd_complex_evt_t const *)p_event);
+ break;
+ }
+ case APP_USBD_EVT_DRV_WUREQ:
+ {
+ static const app_usbd_evt_t evt_data = {
+ .type = APP_USBD_EVT_DRV_RESUME
+ };
+ user_event_state_proc(APP_USBD_EVT_DRV_RESUME);
+ /* Processing core interface (connected only to EP0) and then all instances from the list */
+ UNUSED_RETURN_VALUE(app_usbd_core_handler_call((app_usbd_internal_evt_t const *)&evt_data));
+ app_usbd_all_call((app_usbd_complex_evt_t const *)&evt_data);
+
+ switch(sustate_get())
+ {
+ case SUSTATE_WAKINGUP_WAITING_HFCLK_WREQ:
+ sustate_set(SUSTATE_WAKINGUP_WAITING_HFCLK);
+ break;
+ case SUSTATE_WAKINGUP_WAITING_WREQ:
+ sustate_set(SUSTATE_ACTIVE);
+ break;
+ default:
+ {
+ // This should not happen - but try to recover by setting directly active state
+ NRF_LOG_WARNING("Unexpected state on WUREQ event (%u)", sustate_get());
+ sustate_set(SUSTATE_ACTIVE);
+ }
+ }
+ break;
+ }
+ case APP_USBD_EVT_DRV_SUSPEND:
+ {
+ sustate_set(SUSTATE_SUSPENDING);
+
+ user_event_state_proc(APP_USBD_EVT_DRV_SUSPEND);
+
+ /* Processing all instances from the list and then core interface (connected only to EP0) */
+ app_usbd_all_call((app_usbd_complex_evt_t const *)p_event);
+ UNUSED_RETURN_VALUE(app_usbd_core_handler_call(p_event));
+ break;
+ }
+
+ case APP_USBD_EVT_STATE_CHANGED:
+ {
+ user_event_state_proc(APP_USBD_EVT_STATE_CHANGED);
+ /* Processing all instances from the list and then core interface (connected only to EP0) */
+ app_usbd_all_call((app_usbd_complex_evt_t const *)p_event);
+ break;
+ }
+
+ case APP_USBD_EVT_DRV_SETUP:
+ {
+ UNUSED_RETURN_VALUE(app_usbd_core_handler_call(p_event));
+ break;
+ }
+
+ case APP_USBD_EVT_DRV_EPTRANSFER:
+ {
+ app_usbd_ep_conf_t const * p_ep_conf =
+ app_usbd_ep_conf_access(p_event->drv_evt.data.eptransfer.ep);
+ ASSERT(NULL != p_ep_conf->p_cinst);
+ ASSERT(NULL != p_ep_conf->event_handler);
+
+ if (NRF_SUCCESS != p_ep_conf->event_handler(p_ep_conf->p_cinst,
+ (app_usbd_complex_evt_t const *)p_event))
+ {
+ /* If error returned, every bulk/interrupt endpoint would be stalled */
+ if (!(0 == NRF_USBD_EP_NR_GET(p_event->drv_evt.data.eptransfer.ep) ||
+ NRF_USBD_EPISO_CHECK(p_event->drv_evt.data.eptransfer.ep)))
+ {
+ nrf_drv_usbd_ep_stall(p_event->drv_evt.data.eptransfer.ep);
+ }
+ }
+ break;
+ }
+#if APP_USBD_CONFIG_POWER_EVENTS_PROCESS
+ case APP_USBD_EVT_POWER_DETECTED:
+ {
+ user_event_state_proc(APP_USBD_EVT_POWER_DETECTED);
+ app_usbd_all_call((app_usbd_complex_evt_t const *)p_event);
+ break;
+ }
+ case APP_USBD_EVT_POWER_REMOVED:
+ {
+ user_event_state_proc(APP_USBD_EVT_POWER_REMOVED);
+ app_usbd_all_call((app_usbd_complex_evt_t const *)p_event);
+ break;
+ }
+ case APP_USBD_EVT_POWER_READY:
+ {
+ user_event_state_proc(APP_USBD_EVT_POWER_READY);
+ app_usbd_all_call((app_usbd_complex_evt_t const *)p_event);
+ break;
+ }
+#endif
+ default:
+ ASSERT(0);
+ break;
+ }
+}
+
+
+#if (APP_USBD_CONFIG_EVENT_QUEUE_ENABLE) || defined(__SDK_DOXYGEN__)
+bool app_usbd_event_queue_process(void)
+{
+#if (APP_USBD_CONFIG_SOF_HANDLING_MODE == APP_USBD_SOF_HANDLING_COMPRESS_QUEUE)
+ app_usbd_internal_evt_t sof_event = {
+ .app_evt.type = APP_USBD_EVT_DRV_SOF
+ };
+#endif // (APP_USBD_CONFIG_SOF_HANDLING_MODE == APP_USBD_SOF_HANDLING_COMPRESS_QUEUE)
+ static nrf_atfifo_item_get_t cx;
+ static app_usbd_internal_queue_evt_t * p_event_item = NULL;
+ if (NULL == p_event_item)
+ {
+ p_event_item = nrf_atfifo_item_get(m_event_queue, &cx);
+ }
+
+ if (NULL != p_event_item)
+ {
+
+#if (APP_USBD_CONFIG_SOF_HANDLING_MODE == APP_USBD_SOF_HANDLING_COMPRESS_QUEUE)
+ if (p_event_item->sof_cnt > 0)
+ {
+ if (p_event_item->start_frame > USBD_FRAMECNTR_FRAMECNTR_Msk)
+ {
+ p_event_item->start_frame = 0;
+ }
+ sof_event.drv_evt.data.sof.framecnt = (p_event_item->start_frame)++;
+ --(p_event_item->sof_cnt);
+ app_usbd_event_execute(&sof_event);
+ return true;
+ }
+#endif // (APP_USBD_CONFIG_SOF_HANDLING_MODE == APP_USBD_SOF_HANDLING_COMPRESS_QUEUE)
+
+ app_usbd_event_execute(&(p_event_item->evt));
+ UNUSED_RETURN_VALUE(nrf_atfifo_item_free(m_event_queue, &cx));
+ p_event_item = NULL;
+ return true;
+ }
+#if (APP_USBD_CONFIG_SOF_HANDLING_MODE == APP_USBD_SOF_HANDLING_COMPRESS_QUEUE)
+ else if (m_sof_events_cnt > 0)
+ {
+ CRITICAL_REGION_ENTER();
+ if (m_event_frame > USBD_FRAMECNTR_FRAMECNTR_Msk)
+ {
+ m_event_frame = 0;
+ }
+ sof_event.drv_evt.data.sof.framecnt = m_event_frame++;
+ UNUSED_RETURN_VALUE(nrf_atomic_u32_sub_hs(&m_sof_events_cnt, 1));
+ CRITICAL_REGION_EXIT();
+ app_usbd_event_execute(&sof_event);
+ return true;
+ }
+#endif // (APP_USBD_CONFIG_SOF_HANDLING_MODE == APP_USBD_SOF_HANDLING_COMPRESS_QUEUE)
+ else
+ {
+ return false;
+ }
+}
+#endif
+
+
+ret_code_t app_usbd_class_append(app_usbd_class_inst_t const * p_cinst)
+{
+ ASSERT(NULL != p_cinst);
+ ASSERT(NULL != p_cinst->p_class_methods);
+ ASSERT(NULL != p_cinst->p_class_methods->event_handler);
+ ASSERT(NULL == app_usbd_class_data_access(p_cinst)->p_next);
+
+ /* This should be only called if USBD is disabled
+ * We simply assume that USBD is enabled if its interrupts are */
+ ASSERT(!nrf_drv_usbd_is_enabled() && nrf_drv_usbd_is_initialized());
+
+ /* Check if all required endpoints are available
+ * Checking is splitted from setting to avoid situation that anything
+ * is modified and then operation finishes with error */
+ uint8_t iface_idx;
+ app_usbd_class_iface_conf_t const * p_iface;
+
+ iface_idx = 0;
+ while (NULL != (p_iface = app_usbd_class_iface_get(p_cinst, iface_idx++)))
+ {
+ uint8_t ep_idx = 0;
+ app_usbd_class_ep_conf_t const * p_ep;
+ while (NULL != (p_ep = app_usbd_class_iface_ep_get(p_iface, ep_idx++)))
+ {
+ if (NULL != app_usbd_ep_instance_get(app_usbd_class_ep_address_get(p_ep)))
+ {
+ return NRF_ERROR_BUSY;
+ }
+ }
+ }
+
+ /* Connecting all required endpoints */
+ iface_idx = 0;
+ while (NULL != (p_iface = app_usbd_class_iface_get(p_cinst, iface_idx++)))
+ {
+ uint8_t ep_idx = 0;
+ app_usbd_class_ep_conf_t const * p_ep;
+ while (NULL != (p_ep = app_usbd_class_iface_ep_get(p_iface, ep_idx++)))
+ {
+ app_usbd_ep_instance_set(app_usbd_class_ep_address_get(p_ep), p_cinst);
+ }
+ }
+
+ /* Adding pointer to this instance to the end of the chain */
+ app_usbd_class_inst_t const * * pp_last = &m_p_first_cinst;
+ while (NULL != (*pp_last))
+ {
+ ASSERT((*pp_last) != p_cinst);
+ pp_last = &(app_usbd_class_data_access(*pp_last)->p_next);
+ }
+ (*pp_last) = p_cinst;
+
+ /* Successfully attached */
+ const app_usbd_evt_t evt_data = {.type = APP_USBD_EVT_INST_APPEND };
+ return class_event_handler(p_cinst, (app_usbd_complex_evt_t const *)(&evt_data));
+}
+
+
+ret_code_t app_usbd_class_remove(app_usbd_class_inst_t const * p_cinst)
+{
+ ASSERT(NULL != p_cinst);
+ ASSERT(NULL != p_cinst->p_class_methods);
+ ASSERT(NULL != p_cinst->p_class_methods->event_handler);
+ /** This function should be only called if USBD is disabled */
+ ASSERT(!nrf_drv_usbd_is_enabled() && nrf_drv_usbd_is_initialized());
+ ret_code_t ret;
+ /* Remove this class from the chain */
+ app_usbd_class_inst_t const * * pp_last = &m_p_first_cinst;
+ while (NULL != (*pp_last))
+ {
+ if ((*pp_last) == p_cinst)
+ {
+ /* Inform class instance that removing process is going to be started */
+ const app_usbd_evt_t evt_data = {
+ .type = APP_USBD_EVT_INST_REMOVE
+ };
+ ret = class_event_handler(p_cinst, (app_usbd_complex_evt_t const *)(&evt_data));
+ if (ret != NRF_SUCCESS)
+ {
+ return ret;
+ }
+
+ /* Breaking chain */
+ (*pp_last) = (app_usbd_class_data_access(p_cinst)->p_next);
+ app_usbd_class_data_access(p_cinst)->p_next = NULL;
+
+ /* Disconnecting endpoints */
+ uint8_t ep_idx;
+ for (ep_idx = 0; ep_idx < NRF_USBD_EPIN_CNT; ++ep_idx)
+ {
+ nrf_drv_usbd_ep_t ep = NRF_DRV_USBD_EPIN(ep_idx);
+ if (app_usbd_ep_instance_get(ep) == p_cinst)
+ {
+ app_usbd_ep_instance_set(ep, NULL);
+ }
+ }
+ for (ep_idx = 0; ep_idx < NRF_USBD_EPOUT_CNT; ++ep_idx)
+ {
+ nrf_drv_usbd_ep_t ep = NRF_DRV_USBD_EPOUT(ep_idx);
+ if (app_usbd_ep_instance_get(ep) == p_cinst)
+ {
+ app_usbd_ep_instance_set(ep, NULL);
+ }
+ }
+
+ return NRF_SUCCESS;
+ }
+ pp_last = &(app_usbd_class_data_access(*pp_last)->p_next);
+ }
+
+ return NRF_ERROR_NOT_FOUND;
+}
+
+
+ret_code_t app_usbd_class_remove_all(void)
+{
+ ret_code_t ret = NRF_SUCCESS;
+ while (NULL != m_p_first_cinst)
+ {
+ ret = app_usbd_class_remove(m_p_first_cinst);
+ if (ret != NRF_SUCCESS)
+ {
+ break;
+ }
+ }
+
+ return ret;
+}
+
+
+ret_code_t app_usbd_ep_handler_set(app_usbd_class_inst_t const * const p_cinst,
+ nrf_drv_usbd_ep_t ep,
+ app_usbd_ep_event_handler_t handler)
+{
+ ASSERT(NULL != p_cinst);
+ ASSERT(NULL != handler);
+ /** This function should be only called if USBD is disabled */
+ ASSERT(!nrf_drv_usbd_is_enabled() && nrf_drv_usbd_is_initialized());
+
+ if (p_cinst != app_usbd_ep_instance_get(ep))
+ {
+ return NRF_ERROR_INVALID_PARAM;
+ }
+
+ (app_usbd_ep_conf_access(ep))->event_handler = handler;
+ return NRF_SUCCESS;
+}
+
+
+ret_code_t app_usbd_class_sof_register(app_usbd_class_inst_t const * p_cinst)
+{
+ ASSERT(NULL != p_cinst);
+ ASSERT(NULL != p_cinst->p_class_methods);
+ ASSERT(NULL != p_cinst->p_class_methods->event_handler);
+ /** This function should be only called if USBD is disabled */
+ ASSERT(!nrf_drv_usbd_is_enabled() && nrf_drv_usbd_is_initialized());
+
+ /* Next SOF event requiring instance have to be null now */
+ ASSERT(NULL == (app_usbd_class_data_access(p_cinst)->p_sof_next));
+
+ /* Adding pointer to this instance to the end of the chain */
+ app_usbd_class_inst_t const * * pp_last = &m_p_first_sof_cinst;
+ while (NULL != (*pp_last))
+ {
+
+ ASSERT((*pp_last) != p_cinst);
+ pp_last = &(app_usbd_class_data_access(*pp_last)->p_sof_next);
+ }
+ (*pp_last) = p_cinst;
+
+ return NRF_SUCCESS;
+}
+
+
+ret_code_t app_usbd_class_sof_unregister(app_usbd_class_inst_t const * p_cinst)
+{
+ ASSERT(NULL != p_cinst);
+ /** This function should be only called if USBD is disabled */
+ ASSERT(!nrf_drv_usbd_is_enabled() && nrf_drv_usbd_is_initialized());
+
+ app_usbd_class_inst_t const * * pp_last = &m_p_first_sof_cinst;
+ while (NULL != (*pp_last))
+ {
+ if ((*pp_last) == p_cinst)
+ {
+ /* Breaking chain */
+ (*pp_last) = (app_usbd_class_data_access(p_cinst)->p_sof_next);
+ app_usbd_class_data_access(p_cinst)->p_sof_next = NULL;
+
+ return NRF_SUCCESS;
+ }
+ pp_last = &(app_usbd_class_data_access(*pp_last)->p_sof_next);
+ }
+ return NRF_ERROR_NOT_FOUND;
+}
+
+
+ret_code_t app_usbd_class_rwu_register(app_usbd_class_inst_t const * const p_inst)
+{
+ ASSERT(p_inst != NULL);
+ ++m_rwu_registered_counter;
+ /*Overflow check*/
+ ASSERT(m_rwu_registered_counter != 0);
+
+ return NRF_SUCCESS;
+}
+
+
+ret_code_t app_usbd_class_rwu_unregister(app_usbd_class_inst_t const * const p_inst)
+{
+ ASSERT(p_inst != NULL);
+ /* Usage validation. If counter is 0 unregister is not possible.*/
+ ASSERT(m_rwu_registered_counter != 0);
+ --m_rwu_registered_counter;
+
+ return NRF_SUCCESS;
+}
+
+bool app_usbd_class_rwu_enabled_check(void)
+{
+ return (m_rwu_registered_counter != 0);
+}
+
+ret_code_t app_usbd_interface_ep_reset(app_usbd_class_inst_t const * const p_cinst,
+ uint8_t iface)
+{
+ uint8_t iface_count = app_usbd_class_iface_count_get(p_cinst);
+
+ app_usbd_class_iface_conf_t const * p_iface = NULL;
+ for (uint8_t j = 0; j < iface_count; ++j)
+ {
+ p_iface = app_usbd_class_iface_get(p_cinst, j);
+ if (app_usbd_class_iface_number_get(p_iface) == iface)
+ {
+ break;
+ }
+ }
+
+ if (p_iface == NULL)
+ {
+ return NRF_ERROR_NOT_SUPPORTED;
+ }
+
+ uint8_t ep_count = app_usbd_class_iface_ep_count_get(p_iface);
+
+ for (uint8_t j = 0; j < ep_count; ++j)
+ {
+ /*Clear stall for every endpoint*/
+ app_usbd_class_ep_conf_t const * p_ep = app_usbd_class_iface_ep_get(p_iface, j);
+
+ if (!NRF_USBD_EPISO_CHECK(p_ep->address))
+ {
+ nrf_drv_usbd_ep_dtoggle_clear(p_ep->address);
+ nrf_drv_usbd_ep_stall_clear(p_ep->address);
+ }
+
+ }
+
+ return NRF_SUCCESS;
+}
+
+void app_usbd_ep_enable(nrf_drv_usbd_ep_t ep)
+{
+ if (!NRF_USBD_EPISO_CHECK(ep))
+ {
+ nrf_drv_usbd_ep_dtoggle_clear(ep);
+ nrf_drv_usbd_ep_stall_clear(ep);
+ }
+ nrf_drv_usbd_ep_enable(ep);
+}
+
+void app_usbd_ep_disable(nrf_drv_usbd_ep_t ep)
+{
+ nrf_drv_usbd_ep_disable(ep);
+}
+
+
+app_usbd_class_inst_t const * app_usbd_class_first_get(void)
+{
+ return m_p_first_cinst;
+}
+
+app_usbd_class_inst_t const * app_usbd_class_sof_first_get(void)
+{
+ return m_p_first_sof_cinst;
+}
+
+app_usbd_class_inst_t const * app_usbd_iface_find(uint8_t iface, uint8_t * p_iface_idx)
+{
+ app_usbd_class_inst_t const * p_inst = app_usbd_class_first_get();
+ while (p_inst != NULL)
+ {
+ uint8_t iface_count = app_usbd_class_iface_count_get(p_inst);
+ /* Iterate over interfaces */
+ for (uint8_t i = 0; i < iface_count; ++i)
+ {
+ app_usbd_class_iface_conf_t const * p_iface;
+ p_iface = app_usbd_class_iface_get(p_inst, i);
+ if (app_usbd_class_iface_number_get(p_iface) == iface)
+ {
+ if (p_iface_idx != NULL)
+ {
+ (*p_iface_idx) = i;
+ }
+ return p_inst;
+ }
+ }
+ p_inst = app_usbd_class_next_get(p_inst);
+ }
+ return NULL;
+}
+
+ret_code_t app_usbd_iface_call(
+ app_usbd_class_inst_t const * const p_class_inst,
+ uint8_t iface_idx,
+ app_usbd_complex_evt_t const * const p_event)
+{
+ UNUSED_PARAMETER(iface_idx);
+ return class_event_handler(p_class_inst, p_event);
+}
+
+ret_code_t app_usbd_ep_call(nrf_drv_usbd_ep_t ep, app_usbd_complex_evt_t const * const p_event)
+{
+ if (NRF_USBD_EP_VALIDATE(ep))
+ {
+ app_usbd_class_inst_t const * p_inst = app_usbd_ep_conf_access(ep)->p_cinst;
+ if (p_inst != NULL)
+ {
+ return class_event_handler(p_inst, p_event);
+ }
+ }
+ return NRF_ERROR_INVALID_ADDR;
+}
+
+void app_usbd_all_call(app_usbd_complex_evt_t const * const p_event)
+{
+ app_usbd_class_inst_t const * p_inst;
+ for (p_inst = app_usbd_class_first_get(); NULL != p_inst;
+ p_inst = app_usbd_class_next_get(p_inst))
+ {
+ UNUSED_RETURN_VALUE(class_event_handler(p_inst, p_event));
+ }
+}
+
+ret_code_t app_usbd_all_until_served_call(app_usbd_complex_evt_t const * const p_event)
+{
+ app_usbd_class_inst_t const * p_inst;
+ ret_code_t ret = NRF_ERROR_NOT_SUPPORTED;
+ /* Try to process via every instance */
+ for (p_inst = app_usbd_class_first_get(); NULL != p_inst;
+ p_inst = app_usbd_class_next_get(p_inst))
+ {
+
+ ret = class_event_handler(p_inst, p_event);
+ if (NRF_ERROR_NOT_SUPPORTED != ret)
+ {
+ /* Processing finished */
+ break;
+ }
+ }
+
+ return ret;
+}
+
+ret_code_t app_usbd_ep_transfer(
+ nrf_drv_usbd_ep_t ep,
+ nrf_drv_usbd_transfer_t const * const p_transfer)
+{
+ if (!nrf_drv_usbd_ep_enable_check(ep))
+ {
+ return NRF_ERROR_INVALID_STATE;
+ }
+ if (m_sustate != SUSTATE_ACTIVE)
+ {
+ return NRF_ERROR_INVALID_STATE;
+ }
+ return nrf_drv_usbd_ep_transfer(ep, p_transfer);
+}
+
+ret_code_t app_usbd_ep_handled_transfer(
+ nrf_drv_usbd_ep_t ep,
+ nrf_drv_usbd_handler_desc_t const * const p_handler)
+{
+ if (!nrf_drv_usbd_ep_enable_check(ep))
+ {
+ return NRF_ERROR_INVALID_STATE;
+ }
+ if (m_sustate != SUSTATE_ACTIVE)
+ {
+ return NRF_ERROR_INVALID_STATE;
+ }
+ return nrf_drv_usbd_ep_handled_transfer(ep, p_handler);
+}
+
+ret_code_t app_usbd_iface_select(
+ app_usbd_class_inst_t const * const p_inst,
+ uint8_t iface_idx,
+ uint8_t alternate)
+{
+ ret_code_t ret = NRF_ERROR_NOT_SUPPORTED;
+
+ if (p_inst->p_class_methods->iface_select != NULL)
+ {
+ ret = p_inst->p_class_methods->iface_select(p_inst, iface_idx, alternate);
+ }
+
+ if(ret == NRF_ERROR_NOT_SUPPORTED)
+ {
+ ret = default_iface_select(p_inst, iface_idx, alternate);
+ }
+ return ret;
+}
+
+void app_usbd_iface_deselect(
+ app_usbd_class_inst_t const * const p_inst,
+ uint8_t iface_idx)
+{
+ if (p_inst->p_class_methods->iface_deselect != NULL)
+ {
+ p_inst->p_class_methods->iface_deselect(p_inst, iface_idx);
+ }
+ default_iface_deselect(p_inst, iface_idx);
+}
+
+uint8_t app_usbd_iface_selection_get(
+ app_usbd_class_inst_t const * const p_inst,
+ uint8_t iface_idx)
+{
+ uint8_t alt = 0;
+ if (p_inst->p_class_methods->iface_selection_get != NULL)
+ {
+ alt = p_inst->p_class_methods->iface_selection_get(p_inst, iface_idx);
+ }
+ return alt;
+}
+
+void app_usbd_all_iface_select_0(void)
+{
+ app_usbd_class_inst_t const * p_inst = app_usbd_class_first_get();
+ while (p_inst != NULL)
+ {
+ uint8_t iface_count = app_usbd_class_iface_count_get(p_inst);
+ for (uint8_t i = 0; i < iface_count; ++i)
+ {
+ ret_code_t ret;
+ ret = app_usbd_iface_select(p_inst, i, 0);
+ ASSERT(ret == NRF_SUCCESS);
+ UNUSED_VARIABLE(ret);
+ }
+ p_inst = app_usbd_class_next_get(p_inst);
+ }
+}
+
+void app_usbd_all_iface_deselect(void)
+{
+ app_usbd_class_inst_t const * p_inst = app_usbd_class_first_get();
+ while (p_inst != NULL)
+ {
+ uint8_t iface_count = app_usbd_class_iface_count_get(p_inst);
+ for (uint8_t i = 0; i < iface_count; ++i)
+ {
+ app_usbd_iface_deselect(p_inst, i);
+ }
+ p_inst = app_usbd_class_next_get(p_inst);
+ }
+}
+
+#endif //NRF_MODULE_ENABLED(APP_USBD)
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/usbd/app_usbd.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/usbd/app_usbd.h
new file mode 100644
index 0000000..f63e63c
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/usbd/app_usbd.h
@@ -0,0 +1,745 @@
+/**
+ * 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+
+#ifndef APP_USBD_H__
+#define APP_USBD_H__
+
+#include "nrf_drv_usbd.h"
+#include "app_usbd_types.h"
+#include "app_usbd_class_base.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @defgroup app_usbd USB Device high level library
+ * @ingroup app_common
+ *
+ * @brief @tagAPI52840 Module for easy support for any USB device configuration.
+ *
+ * This module manages class instances that would create the USB device,
+ * manages endpoints and interfaces transactions.
+ * @{
+ */
+
+/**
+ * @brief True if SOF timestamping is really provided.
+ *
+ * SOF timestamping is really provided if it was requested and if the logger is enabled.
+ */
+#if ((APP_USBD_CONFIG_SOF_TIMESTAMP_PROVIDE) && (NRF_LOG_ENABLED))
+#define APP_USBD_PROVIDE_SOF_TIMESTAMP 1
+#else
+#define APP_USBD_PROVIDE_SOF_TIMESTAMP 0
+#endif
+
+/**
+ * @brief SOF event handling modes.
+ */
+#define APP_USBD_SOF_HANDLING_NORMAL_QUEUE 0 //!< Push SOF events into event queue.
+#define APP_USBD_SOF_HANDLING_COMPRESS_QUEUE 1 //!< Compress SOF events.
+#define APP_USBD_SOF_HANDLING_INTERRUPT 2 //!< Handle SOF events in interrupt.
+
+/**
+ * @brief Configuration passed to @ref app_usbd_init.
+ */
+typedef struct {
+#if (!(APP_USBD_CONFIG_EVENT_QUEUE_ENABLE)) || defined(__SDK_DOXYGEN__)
+ /**
+ * @brief User defined event handler.
+ *
+ * This function is called on every event from the interrupt.
+ * It is prepared for external user function that would queue events to be processed
+ * from the main context.
+ * It should be used with operating systems with its own implementation of the queue.
+ *
+ * @param p_event The event structure pointer.
+ *
+ * @note This field is available only when USB internal queue is disabled
+ * (see @ref APP_USBD_CONFIG_EVENT_QUEUE_ENABLE).
+ */
+ void (*ev_handler)(app_usbd_internal_evt_t const * const p_event);
+#endif
+
+#if (APP_USBD_CONFIG_EVENT_QUEUE_ENABLE) || defined(__SDK_DOXYGEN__)
+ /**
+ * @brief User defined event handler.
+ *
+ * This function is called on every event from the interrupt.
+ *
+ * @param p_event The event structure pointer.
+ * @param queued The event is visible in the queue.
+ * If queue conflict is detected the event might not be accessible inside queue
+ * until all write operations finish.
+ * See @ref nrf_atfifo for more details.
+ *
+ * @note This field is available only when USBD internal queue is configured
+ * (see @ref APP_USBD_CONFIG_EVENT_QUEUE_ENABLE).
+ *
+ * @note If is set to NULL no event would be called from interrupt.
+ * @note This function is called before event is processed.
+ * It means that if the event type is @ref APP_USBD_EVT_DRV_SETUP,
+ * there would not be setup field present in the event structure.
+ */
+ void (*ev_isr_handler)(app_usbd_internal_evt_t const * const p_event, bool queued);
+#endif
+
+ /**
+ * @brief User defined event processor
+ *
+ * This function is called while state event is processed.
+ *
+ * * @note This field is available only when USBD internal queue is configured
+ * (see @ref APP_USBD_CONFIG_EVENT_QUEUE_ENABLE).
+ *
+ * @param event Event type.
+ * Only following events are sent into this function:
+ * - APP_USBD_EVT_DRV_SOF
+ * - APP_USBD_EVT_DRV_RESET - Note that it also exits suspend
+ * - APP_USBD_EVT_DRV_SUSPEND
+ * - APP_USBD_EVT_DRV_RESUME - It is also generated when remote wakeup is generated
+ * - APP_USBD_EVT_START
+ * - APP_USBD_EVT_STOP
+ * - APP_USBD_EVT_STATE_CHANGED
+ */
+ void (*ev_state_proc)(app_usbd_event_type_t event);
+
+ /**
+ * @brief SOF processing required by the user event processing
+ *
+ * This flag would enable SOF processing for the user events regardless of the fact if any
+ * of the implemented class requires SOF event.
+ *
+ * @note SOF event would be enabled anyway if any of the appended class requires SOF processing.
+ */
+ bool enable_sof;
+} app_usbd_config_t;
+
+
+#if (APP_USBD_PROVIDE_SOF_TIMESTAMP) || defined(__SDK_DOXYGEN__)
+/**
+ * @brief Timestamp function for the logger.
+ *
+ * @return Current frame number taken directly from the last processed SOF.
+ */
+uint32_t app_usbd_sof_timestamp_get(void);
+#endif
+
+/**
+ * @brief USB library initialization.
+ *
+ * Call this function before any configuration or class attachment.
+ * USBD peripheral would be ready to accept commands, and library would be ready,
+ * but it would not be connected to the bus.
+ * Call @ref app_usbd_enable to enable USBD communication with the host.
+ *
+ * @param p_config Configuration. NULL pointer might be passed here and default
+ * configuration will be applied then.
+ */
+ret_code_t app_usbd_init(app_usbd_config_t const * p_config);
+
+/**
+ * @brief USB library un-initialization
+ *
+ * @note Currently not supported
+ */
+ret_code_t app_usbd_uninit(void);
+
+#if (APP_USBD_CONFIG_POWER_EVENTS_PROCESS) || defined(__SDK_DOXYGEN__)
+/**
+ * @brief Function to start USB related power events processing
+ *
+ * This function should be called after @ref app_usbd_init and after all the
+ * required classes were appended (@ref app_usbd_class_append).
+ *
+ * @retval NRF_SUCCESS Power events successfully initialized
+ * @retval NRF_ERROR_INVALID_STATE The state of the driver does not allow to enable
+ * the power events processing.
+ */
+ret_code_t app_usbd_power_events_enable(void);
+#endif
+
+/**
+ * @brief Enable USBD
+ *
+ * USBD is enabled.
+ * Since now the high frequency clock may be requested when USB RESET would be detected.
+ */
+void app_usbd_enable(void);
+
+/**
+ * @brief Disable USBD
+ *
+ * Disabled USDB peripheral cannot be accessed but also stops requesting
+ * High Frequency clock and releases power regulator.
+ *
+ * @note This function cannot be called when USB is started. Stop it first.
+ */
+void app_usbd_disable(void);
+
+/**
+ * @brief Request USBD to start
+ *
+ * The function sends start request to the event queue.
+ * If the queue is enabled (@ref APP_USBD_CONFIG_EVENT_QUEUE_ENABLE) it would be processed
+ * when the queue is processed.
+ * If queue is disabled it would be processed immediately inside this function.
+ * It means that if queue is disabled this function cannot be called from interrupt with priority
+ * higher than USB interrupt.
+ *
+ * When start is processed it would:
+ * 1. Start library.
+ * 2. Enable interrupts.
+ * 3. Enable USB pull-ups.
+ *
+ * @note
+ * In some specific circumstances the library can be left not started and this function would
+ * silently exit.
+ * This may happen if some glitches appears on USB power line or if the plug was disconnected before
+ * whole starting process finishes.
+ * User would get the event from POWER peripheral then.
+ * Also no @ref APP_USBD_EVT_STARTED event would be generated to the classes and user event handler.
+ * For the safe code it is recommended to wait for @ref APP_USBD_EVT_STARTED event if anything
+ * has to be initialized after USB driver is started (just before enabling the interrupts).
+ * If library is properly started the @ref APP_USBD_EVT_STARTED event passed to the user handler
+ * from this function body.
+ */
+void app_usbd_start(void);
+
+/**
+ * @brief Stop USB to work
+ *
+ * The function sends stop request to the event queue.
+ * If the queue is enabled (@ref APP_USBD_CONFIG_EVENT_QUEUE_ENABLE) it would be processed
+ * when the queue is processed.
+ * If queue is disabled it would be processed immediately inside this function.
+ * It means that if queue is disabled this function cannot be called from interrupt with priority
+ * higher than USB interrupt.
+ *
+ * When the event is processed interrupts and USB pull-ups are disabled.
+ * The peripheral itself is left enabled so it can be programmed,
+ * but a HOST sees it as a peripheral disconnection.
+ *
+ * @note
+ * If the library is not started when this function is called it exits silently - also
+ * no @ref APP_USBD_EVT_STOPPED is generated.
+ */
+void app_usbd_stop(void);
+
+/**
+ * @brief Request library to suspend
+ *
+ * This function send suspend request to the event queue.
+ *
+ * @note This function should only be called after @ref APP_USBD_EVT_DRV_SUSPEND os received.
+ * Internal suspend request processing would give no effect if the bus is not in suspend state.
+ */
+void app_usbd_suspend_req(void);
+
+/**
+ * @brief Request library to wake-up
+ *
+ * This function send wakeup request to the event queue.
+ *
+ * @note Calling this function does not mean that peripheral is active - the wakeup request is sent
+ * into message queue and needs to be processed.
+ *
+ * @retval true Wakeup generation has been started.
+ * @retval false No wakeup would be generated becouse it is disabled by the host.
+ */
+bool app_usbd_wakeup_req(void);
+
+/**
+ * @brief Get information whether there is an active connection.
+ *
+ * Function to check if the communication with the bus is possible.
+ *
+ * @retval true The bus is active.
+ * @retval false There is no connection or bus is suspended.
+ */
+bool app_usbd_active_check(void);
+
+/**
+ * @brief USBD event processor
+ *
+ * Function to be called on each event to be processed by the library.
+ */
+void app_usbd_event_execute(app_usbd_internal_evt_t const * const p_event);
+
+
+#if (APP_USBD_CONFIG_EVENT_QUEUE_ENABLE) || defined(__SDK_DOXYGEN__)
+/**
+ * @brief Function that process events from the queue
+ *
+ * @note This function calls @ref app_usbd_event_execute internally.
+ *
+ * @retval true Event was processed
+ * @retval false The event queue is empty
+ */
+bool app_usbd_event_queue_process(void);
+#endif
+
+/**
+ * @brief Add class instance
+ *
+ * This function connects given instance into internal class instance chain and
+ * into all required endpoints.
+ * The instance event handler would be connected into endpoint by default,
+ * but this can be overwritten by @ref app_usbd_ep_handler_set.
+ *
+ * After successful attachment @ref APP_USBD_EVT_INST_APPEND would be passed to class instance.
+ *
+ * @note This function can only be called after USBD library is initialized but still disabled.
+ * Assertion would be generated otherwise.
+ *
+ * @param[in,out] p_cinst Instance to connect. Chain data would be written into writable instance data.
+ */
+ret_code_t app_usbd_class_append(app_usbd_class_inst_t const * p_cinst);
+
+/**
+ * @brief Remove class instance
+ *
+ * Instance is removed from instance chain.
+ * Instance and event handlers are removed also from endpoints.
+ * Endpoints used by by the class instance are left disabled.
+ *
+ * @note This function can only be called after USBD library is initialized but still disabled.
+ * Assertion would be generated otherwise.
+ *
+ * @param p_cinst Instance pointer to remove.
+ *
+ * @retval NRF_SUCCESS Instance successfully removed.
+ * @retval NRF_ERROR_NOT_FOUND Instance not found in the instance chain.
+ */
+ret_code_t app_usbd_class_remove(app_usbd_class_inst_t const * p_cinst);
+
+/**
+ * @brief Remove all class instances
+ *
+ * This function basically calls @ref app_usbd_class_remove
+ * on instances chain as long as there is any element left.
+ *
+ * @note This function can only be called after USBD library is initialized but still disabled.
+ * Assertion would be generated otherwise.
+ *
+ * @sa app_usbd_class_remove
+ *
+ * @return Is should always return @ref NRF_SUCCESS.
+ * Any error value returned would mean there is an error inside the library.
+ */
+ret_code_t app_usbd_class_remove_all(void);
+
+/**
+ * @brief Change endpoint handler
+ *
+ * This function may be called for the endpoint only if the class instance is
+ * already properly attached by the @ref app_usbd_class_append function.
+ *
+ * The endpoint event handler function can be only overwritten by the class instance
+ * that was connected into the endpoint.
+ *
+ * @note This function can only be called after USBD library is initialized but still disabled.
+ * Assertion would be generated otherwise.
+ *
+ * @param[in] p_cinst Instance of a class that wish to set new event handler.
+ * It has to match currently configured instance for the selected endpoint.
+ * In other situation error would be returned.
+ * @param[in] ep Endpoint address to configure.
+ * @param[in] handler Event handler function to set.
+ *
+ * @retval NRF_SUCCESS New handler successfully set
+ * @retval NRF_ERROR_INVALID_PARAM p_cinst is not the same as currently set for the endpoint
+ */
+ret_code_t app_usbd_ep_handler_set(app_usbd_class_inst_t const * p_cinst,
+ nrf_drv_usbd_ep_t ep,
+ app_usbd_ep_event_handler_t handler);
+
+/**
+ * @brief Register class instance as the one that requires SOF events
+ *
+ * This function should be called in reaction on APP_USBD_EVT_INST_APPEND event.
+ * Connect the class instance to the list of instances that requires SOF processing.
+ * If none of the appended instances requires SOF event - it is disabled.
+ *
+ * @param p_cinst Instance that requires SOF event.
+ *
+ * @retval NRF_SUCCESS Instance linked into SOF processing list.
+ *
+ * @sa app_usbd_class_sof_unregister
+ */
+ret_code_t app_usbd_class_sof_register(app_usbd_class_inst_t const * p_cinst);
+
+/**
+ * @brief Unregister class instance from SOF processing instances list
+ *
+ * Every class that calls @ref app_usbd_class_sof_register have to call also unregistering function
+ * in reaction to @ref APP_USBD_EVT_INST_REMOVE event.
+ *
+ * @param p_cinst Instance to be unregistered from SOF event processing list.
+ *
+ * @retval NRF_SUCCESS Instance linked into SOF processing list.
+ * @retval NRF_ERROR_NOT_FOUND Instance not found in the SOF processing list.
+ *
+ * @sa app_usbd_class_sof_register
+ */
+ret_code_t app_usbd_class_sof_unregister(app_usbd_class_inst_t const * p_cinst);
+
+/**
+ * @brief Register class on remote wake-up feature
+ *
+ * @param[in] p_inst Instance of the class
+ *
+ * @retval NRF_SUCCESS Instance that requires remote wake-up registered
+ */
+ret_code_t app_usbd_class_rwu_register(app_usbd_class_inst_t const * const p_inst);
+
+/**
+ * @brief Unregister class from remote wake-up feature
+ *
+ * @param[in] p_inst Instance of the class
+ *
+ * @retval NRF_SUCCESS Instance that requires remote wake-up removed
+ */
+ret_code_t app_usbd_class_rwu_unregister(app_usbd_class_inst_t const * const p_inst);
+
+/**
+ * @brief Check if there is any class with remote wakeup
+ *
+ * The function checks internal registered class with remote wakeup counter.
+ *
+ * @sa app_usbd_class_rwu_register, app_usbd_class_rwu_unregister
+ *
+ * @retval true The remote wakeup functionality is required by some class instance
+ * @retval false There is no class instance that requires wakeup functionality
+ */
+bool app_usbd_class_rwu_enabled_check(void);
+
+/**
+ * @brief Find a specified descriptor
+ *
+ * @param[in] p_cinst Class instance
+ * @param[in] desc_type Descriptor type @ref app_usbd_descriptor_t
+ * @param[in] desc_index Descriptor index
+ * @param[out] p_desc Pointer to escriptor
+ * @param[out] p_desc_len Length of descriptor
+ *
+ * @return Standard error code @ref ret_code_t
+ * @retval NRF_SUCCESS descriptor successfully found
+ * @retval NRF_ERROR_NOT_FOUND descriptor not found
+ * */
+ret_code_t app_usbd_class_descriptor_find(app_usbd_class_inst_t const * const p_cinst,
+ uint8_t desc_type,
+ uint8_t desc_index,
+ uint8_t * p_desc,
+ size_t * p_desc_len);
+
+/**
+ * @brief Standard set interface request handle
+ *
+ * This function should be called when processing SET_INTERFACE request.
+ *
+ * @param[in] p_cinst Instance of a class
+ * @param[in] iface Interface number
+ *
+ * @return Standard error code
+ *
+ * @note Selected interface to reset has to be part of given class.
+ * In other case
+ * */
+ret_code_t app_usbd_interface_ep_reset(app_usbd_class_inst_t const * const p_cinst,
+ uint8_t iface);
+
+
+/**
+ * @brief Enable selected endpoint
+ *
+ * Selected endpoint is enabled and cleared.
+ *
+ * @param ep Endpoint number
+ */
+void app_usbd_ep_enable(nrf_drv_usbd_ep_t ep);
+
+/**
+ * @brief Disable selected endpoint
+ *
+ * @param ep Endpoint number
+ */
+void app_usbd_ep_disable(nrf_drv_usbd_ep_t ep);
+
+/**
+ * @name Iterate through classes lists
+ *
+ * Functions that helps to iterate through internally chained classes.
+ * @{
+ */
+ /**
+ * @brief Get first class instance in the list
+ *
+ * Get first instance from the list of active class instances.
+ * That instance may be used then in @ref app_usbd_class_next_get function.
+ *
+ * @return First instance in the list or NULL if there are no instances available.
+ */
+ app_usbd_class_inst_t const * app_usbd_class_first_get(void);
+
+ /**
+ * @brief Get next instance in the list
+ *
+ * Get the next instance from the list of active instances.
+ * Used to iterate through all instances.
+ *
+ * @param[in] p_cinst The current instance from with next one is required.
+ *
+ * @return Next instance to the given one or NULL if there is no more instances in the list.
+ */
+ static inline app_usbd_class_inst_t const * app_usbd_class_next_get(
+ app_usbd_class_inst_t const * const p_cinst)
+ {
+ ASSERT(NULL != p_cinst);
+ return app_usbd_class_data_access(p_cinst)->p_next;
+ }
+
+ /**
+ * @brief Get first instance in SOF list
+ *
+ * Start iteration through the list of instances that requires SOF event processing.
+ *
+ * @return First instance in the list or NULL if the list is empty
+ *
+ * @sa app_usbd_class_first_get
+ */
+ app_usbd_class_inst_t const * app_usbd_class_sof_first_get(void);
+
+ /**
+ * @brief Get next instance in the SOF list
+ *
+ * Get the next instance from the list of instances requiring SOF event processing.
+ * Used to iterate through all SOF instances.
+ *
+ * @param p_cinst The current instance from with next one is required.
+ *
+ * @return Next instance to the given one or NULL if there is no more instances in the list.
+ */
+ static inline app_usbd_class_inst_t const * app_usbd_class_sof_next_get(
+ app_usbd_class_inst_t const * const p_cinst)
+ {
+ ASSERT(NULL != p_cinst);
+ return app_usbd_class_data_access(p_cinst)->p_sof_next;
+ }
+/** @} */
+
+/**
+ * @brief Search for selected interface
+ *
+ * Function searches for the given interface number and returns the class that contains it.
+ * Optionally it can return interface index inside class instance.
+ *
+ * @param[in] iface Interface number
+ * @param[out] p_iface_idx Pointer to a variable that would hold interface index inside returned
+ * class instance.
+ *
+ * @return Pointer to the class structure that cointain given interface or NULL if not found.
+ */
+app_usbd_class_inst_t const * app_usbd_iface_find(uint8_t iface, uint8_t * p_iface_idx);
+
+
+/**
+ * @name Communicate with interfaces, endpoints and instances inside usbd library
+ *
+ * @{
+ */
+
+ /**
+ * @brief Call interface event handler
+ *
+ * Call event handler for selected interface.
+ * @param[in,out] p_class_inst Class instance that holds selected interface
+ * @param[in] iface_idx Index of the interface in class structure
+ * @param[in] p_event Event structure to be processed
+ *
+ * @return Operation status
+ */
+ ret_code_t app_usbd_iface_call(
+ app_usbd_class_inst_t const * const p_class_inst,
+ uint8_t iface_idx,
+ app_usbd_complex_evt_t const * const p_event);
+
+ /**
+ * @brief Call endpoint event handler
+ *
+ * Call event handler for the selected endpoint.
+ * @param[in] ep Endpoint number
+ * @param[in] p_event Event structure to send
+ *
+ * @return Operation status
+ */
+ ret_code_t app_usbd_ep_call(nrf_drv_usbd_ep_t ep, app_usbd_complex_evt_t const * const p_event);
+
+ /**
+ * @brief Auxiliary function that process event by every instance in the list
+ *
+ * This function ignores the result of called handler.
+ *
+ * @param p_event Event to pass to every instance
+ */
+ void app_usbd_all_call(app_usbd_complex_evt_t const * const p_event);
+
+ /**
+ * @brief Call interface event handlers and stop when served
+ *
+ * Call event handlers from instances as long as we get result different than @ref NRF_ERROR_NOT_SUPPORTED
+ * @param[in] p_event Event structure to send
+ *
+ * @return Operation status or @ref NRF_ERROR_NOT_SUPPORTED if none of instances in the list can support given event.
+ */
+ ret_code_t app_usbd_all_until_served_call(app_usbd_complex_evt_t const * const p_event);
+/** @} */
+
+/**
+ * @brief Endpoint transfer
+ *
+ * @param ep Endpoint number
+ * @param p_transfer Description of the transfer to be performed.
+ * The direction of the transfer is determined by the
+ * endpoint number.
+ *
+ * @retval NRF_ERROR_INVALID_STATE The state of the USB device does not allow
+ * data transfer on the endpoint.
+ * @return Values returned by @ref nrf_drv_usbd_ep_transfer
+ *
+ * @sa app_usbd_ep_handled_transfer
+ */
+ret_code_t app_usbd_ep_transfer(
+ nrf_drv_usbd_ep_t ep,
+ nrf_drv_usbd_transfer_t const * const p_transfer);
+
+/**
+ * @brief Set up an endpoint handled transfer.
+ *
+ * Configures a transfer handled by the feedback function.
+ *
+ * @param ep Endpoint number.
+ * @param p_handler Function called when the next chunk of data is requested.
+ *
+ * @retval NRF_ERROR_INVALID_STATE The state of the USB device does not allow
+ * data transfer on the endpoint.
+ * @return Values returned by @ref nrf_drv_usbd_ep_handled_transfer.
+ */
+ret_code_t app_usbd_ep_handled_transfer(
+ nrf_drv_usbd_ep_t ep,
+ nrf_drv_usbd_handler_desc_t const * const p_handler);
+
+
+/**
+ * @brief Select interface
+ *
+ * Select the given interface.
+ * This function calls class interface selection function or default
+ * interface selection function.
+ *
+ * After calling this function interface should be functional.
+ *
+ * @param[in,out] p_inst Instance of the class
+ * @param[in] iface_idx Index of the interface inside class structure
+ * @param[in] alternate Alternate setting that should be selected
+ *
+ * @return Standard Error code
+ */
+ret_code_t app_usbd_iface_select(
+ app_usbd_class_inst_t const * const p_inst,
+ uint8_t iface_idx,
+ uint8_t alternate);
+
+
+/**
+ * @brief Deselect interface
+ *
+ * Disable the given interface.
+ * This function calls class interface deselection function or
+ * default interface selection function.
+ *
+ * After calling this function all the endpoints from the interface
+ * have to be disabled.
+ *
+ * @param[in,out] p_inst Instance of the class
+ * @param[in] iface_idx Index of the interface inside class structure
+ */
+void app_usbd_iface_deselect(
+ app_usbd_class_inst_t const * const p_inst,
+ uint8_t iface_idx);
+
+/**
+ * @brief Get selected interface
+ *
+ * Function retieves currently selected interface.
+ * If the class contains @ref app_usbd_class_methods_t::iface_selection_get it is called.
+ * It it does not contain this function this function would return default, 0 value.
+ *
+ * @param[in] p_inst Instance of the class
+ * @param[in] iface_idx Index of the interface inside class structure
+ *
+ * @return Selected alternate interface setting
+ */
+uint8_t app_usbd_iface_selection_get(
+ app_usbd_class_inst_t const * const p_inst,
+ uint8_t iface_idx);
+
+/**
+ * @brief Select alternate configuration 0 for all interfaces
+ *
+ * Auxiliary function that clears settings for all interfaces leaving them enabled.
+ */
+void app_usbd_all_iface_select_0(void);
+
+/**
+ * @brief Deselect all interfaces
+ *
+ * Auxiliary function to disable all interfaces.
+ */
+void app_usbd_all_iface_deselect(void);
+
+/** @} */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* APP_USBD_H__ */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/usbd/app_usbd_class_base.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/usbd/app_usbd_class_base.h
new file mode 100644
index 0000000..672ab28
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/usbd/app_usbd_class_base.h
@@ -0,0 +1,1094 @@
+/**
+ * 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+
+#ifndef APP_USBD_CLASS_BASE_H__
+#define APP_USBD_CLASS_BASE_H__
+
+#include <stdint.h>
+#include <stddef.h>
+
+#include "app_usbd_types.h"
+#include "nrf_drv_usbd.h"
+#include "nrf_assert.h"
+#include "app_util.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @defgroup app_usbd_class_base USBD Class Base module
+ * @ingroup app_usbd
+ *
+ * @brief @tagAPI52840 The base for any class instance is defined in this module.
+ *
+ * @details Any class instance must start from base class instance structure.
+ * This makes them compatible with USBD library independently of the
+ * implementation details.
+ * @{
+ */
+
+/**
+ * @brief Endpoint configuration
+ */
+typedef struct
+{
+ nrf_drv_usbd_ep_t address; //!< Endpoint address
+} app_usbd_class_ep_conf_t;
+
+/**
+ * @brief Interface configuration
+ */
+typedef struct
+{
+ uint8_t number; //!< Interface number
+ uint8_t ep_cnt; //!< Endpoint number
+ uint8_t ep_offset; //!< Offset of the first endpoint
+ /**< Offset in bytes of the first endpoint.
+ * The offset is calculated from the address of this interface structure
+ */
+} app_usbd_class_iface_conf_t;
+
+/**
+ * @brief Instance variable data
+ */
+typedef struct
+{
+ app_usbd_class_inst_t const * p_next; //!< Pointer to the next instance
+ app_usbd_class_inst_t const * p_sof_next; //!< Pointer to the next SOF event requiring instance
+} app_usbd_class_data_t;
+
+/**
+ * @brief Class descriptor context
+ */
+typedef struct
+{
+ uint32_t line; //!< Number of line to resume writing descriptors from
+ uint8_t data_buffer; //!< Data from last call of feeder
+} app_usbd_class_descriptor_ctx_t;
+
+/**
+ * @brief Class descriptor state
+ */
+typedef struct
+{
+ uint8_t * p_buffer; //!< Pointer to buffer
+ uint32_t current_size; //!< Current size of descriptor
+ uint32_t maximum_size; //!< Maximum size of descriptor
+ app_usbd_class_descriptor_ctx_t * p_context; //!< Pointer to context
+} app_usbd_class_descriptor_state_t;
+
+/**
+ * @brief Class interface function set
+ * */
+typedef struct {
+ /**
+ * @brief Instance callback function
+ *
+ * The function used by every class instance.
+ * @param[in,out] p_inst Instance of the class
+ * @param[in] p_event Event to process
+ *
+ * @return Standard error code
+ *
+ * @note If given event is not supported by class, return @ref NRF_ERROR_NOT_SUPPORTED
+ */
+ ret_code_t (* event_handler)(app_usbd_class_inst_t const * const p_inst,
+ app_usbd_complex_evt_t const * const p_event);
+
+ /**
+ * @brief Instance feed descriptors
+ *
+ * Feeds whole descriptor of the instance
+ * @param[in] p_ctx Class descriptor context
+ * @param[in,out] p_inst Instance of the class
+ * @param[out] p_buff Buffer for descriptor
+ * @param[in] max_size Requested size of the descriptor
+ *
+ * @return True if not finished feeding the descriptor, false if done
+ */
+ bool (* feed_descriptors)(app_usbd_class_descriptor_ctx_t * p_ctx,
+ app_usbd_class_inst_t const * p_inst,
+ uint8_t * p_buff,
+ size_t max_size);
+
+
+ /**
+ * @brief Select interface
+ *
+ * Function called when class interface has to be selected.
+ *
+ * This function would be called for every interface when:
+ * - SET_INTERFACE command is processed by the default handler
+ * - SET_CONFIG(1) command is processed by the default handler
+ *
+ * @note Remember to disable all the endpoints that are not used
+ * in the selected configuration.
+ * @note If this function pointer is NULL default procedure would
+ * just enable all the interface endpoints and selecting
+ * alternate configurations other than 0 would generate error.
+ * @note Calling the function with alternate setting 0 has to always succeed.
+ *
+ * @param[in,out] p_inst Instance of the class
+ * @param[in] iface_idx Index of the interface inside class structure
+ * @param[in] alternate Alternate setting that should be selected
+ *
+ * @return Function has to return @ref NRF_SUCCESS when it has successfully proceed
+ * interface selection.
+ * If it returns @ref NRF_ERROR_NOT_SUPPORTED, default function would be used
+ * to proceed the request - just like there would be NULL pointer in this field.
+ * Any other kind of error would make library to STALL the request.
+ */
+ ret_code_t (* iface_select)(app_usbd_class_inst_t const * const p_inst,
+ uint8_t iface_idx,
+ uint8_t alternate);
+
+ /**
+ * @brief Deselect interface
+ *
+ * Function called when the class interface has to be deselected.
+ *
+ * This function would be called for every interface when:
+ * - Library start internal event is processed by the default handler
+ * - RESET event is processed by the default handler
+ * - SET_ADDRESS is processed by the default handler
+ * - SET_CONFIG(0) is processed by the default handler
+ *
+ * @note Just after this function is called all the interface
+ * endpoints would be disabled.
+ * This function does not has to take care about it.
+ * @note If this function pointer is NULL default procedure would
+ * just disable all the interface endpoints.
+ *
+ * @param[in,out] p_inst Instance of the class
+ * @param[in] iface_idx Index of the interface inside class structure
+ */
+ void (* iface_deselect)(app_usbd_class_inst_t const * const p_inst, uint8_t iface_idx);
+
+ /**
+ * @brief Get current interface
+ *
+ * Function called when class interface has to return its alternate settings
+ * in reaction on GET_INTERFACE command.
+ * It should be defined in a pair with @ref app_usbd_class_methods_t::iface_select.
+ *
+ * @param[in] p_inst Instance of the class
+ * @param[in] iface_idx Index of the interface inside class structure
+ *
+ * @return Current alternate setting of the selected interface.
+ *
+ * @note For the classes that support this function, when an interface that has not alternate
+ * configurations has been selected this function has to return 0 - default alternate setting.
+ *
+ * @note If this function pointer it NULL default procedure would return alternate interface
+ * value 0.
+ */
+ uint8_t (* iface_selection_get)(app_usbd_class_inst_t const * const p_inst, uint8_t iface_idx);
+
+} app_usbd_class_methods_t;
+
+/**
+ * @brief The instance structure itself
+ *
+ * The structure of base class instance
+ */
+struct app_usbd_class_inst_s
+{
+ app_usbd_class_data_t * p_data; //!< Pointer to non-constant data
+ app_usbd_class_methods_t const * p_class_methods; //!< Class interface methods
+ struct
+ {
+ uint8_t cnt; //!< Number of defined interfaces
+ uint8_t config[]; //!< Interface configuration data followed by endpoint data
+ } iface; //!< Interface structure
+};
+
+
+/**
+ * @brief Get total number of interfaces
+ *
+ *
+ */
+static inline uint8_t app_usbd_class_iface_count_get(app_usbd_class_inst_t const * const p_inst)
+{
+ return p_inst->iface.cnt;
+}
+
+/**
+ * @brief Interface accessing function
+ *
+ * Get interface pointer.
+ * Interfaces creates continuous array in the memory so it is possible to get
+ * interface with index 0 and the just iterate to the next one.
+ *
+ * @param p_inst Pointer to the class instance
+ * @param iface_idx Index of the instance to get.
+ * This is not the interface identifier.
+ * Technically it is the index of the interface in the class description array.
+ * @return Pointer to the interface configuration parameters or NULL if given index is out of interface scope for given class.
+ */
+static inline app_usbd_class_iface_conf_t const * app_usbd_class_iface_get(
+ app_usbd_class_inst_t const * const p_inst,
+ uint8_t iface_idx)
+{
+ ASSERT(NULL != p_inst);
+ if (iface_idx >= (app_usbd_class_iface_count_get(p_inst)))
+ {
+ return NULL;
+ }
+
+ app_usbd_class_iface_conf_t const * p_interface =
+ (app_usbd_class_iface_conf_t const * )(p_inst->iface.config);
+ return &(p_interface[iface_idx]);
+}
+
+/**
+ * @brief Get interface number
+ *
+ * @param p_iface Pointer to interface structure
+ *
+ * @return Interface number from interface configuration structure
+ */
+static inline uint8_t app_usbd_class_iface_number_get(
+ app_usbd_class_iface_conf_t const * const p_iface)
+{
+ return p_iface->number;
+}
+
+/**
+ * @brief Get number of endpoints in interface
+ *
+ * @param p_iface Pointer to interface structure
+ *
+ * @return Number of endpoints used by given interface
+ */
+static inline uint8_t app_usbd_class_iface_ep_count_get(
+ app_usbd_class_iface_conf_t const * const p_iface)
+{
+ return p_iface->ep_cnt;
+}
+
+/**
+ * @brief Interface Endpoint accessing function
+ *
+ * @param p_iface Interface configuration pointer
+ * @param ep_idx Endpoint index
+ *
+ * @return Endpoint information structure pointer or NULL if given index is outside of endpoints for selected interface.
+ *
+ * @sa app_usbd_class_iface_get
+ */
+static inline app_usbd_class_ep_conf_t const * app_usbd_class_iface_ep_get(
+ app_usbd_class_iface_conf_t const * const p_iface,
+ uint8_t ep_idx)
+{
+ ASSERT(NULL != p_iface);
+ if (ep_idx >= p_iface->ep_cnt)
+ {
+ return NULL;
+ }
+
+ app_usbd_class_ep_conf_t const * p_ep =
+ (app_usbd_class_ep_conf_t const * )(((uint8_t const *)p_iface) + p_iface->ep_offset);
+ return &(p_ep[ep_idx]);
+}
+
+/**
+ * @brief Translate endpoint address to class index
+ *
+ * @param p_iface Interface configuration pointer
+ * @param ep_address Endpoint address
+ *
+ * @return Endpoint index or number of endpoints if not found
+ *
+ */
+static inline uint8_t app_usbd_class_iface_ep_idx_get(
+ app_usbd_class_iface_conf_t const * const p_iface,
+ nrf_drv_usbd_ep_t ep_address)
+{
+ ASSERT(NULL != p_iface);
+ app_usbd_class_ep_conf_t const * p_ep =
+ (app_usbd_class_ep_conf_t const * )(((uint8_t const *)p_iface) + p_iface->ep_offset);
+
+ uint8_t i;
+ for (i = 0; i < p_iface->ep_cnt; ++i)
+ {
+ if (ep_address == p_ep[i].address)
+ {
+ break;
+ }
+ }
+
+ return i;
+}
+
+/**
+ * @brief Get the selected endpoint address
+ *
+ * @param p_ep Endpoint configuration structure
+ *
+ * @return Endpoint address
+ */
+static inline nrf_drv_usbd_ep_t app_usbd_class_ep_address_get(app_usbd_class_ep_conf_t const * p_ep)
+{
+ return (nrf_drv_usbd_ep_t)p_ep->address;
+}
+
+/**
+ * @brief Get the pointer to the writable instance data
+ *
+ * @param p_inst Instance pointer
+ * @return Pointer to writable instance data
+ */
+static inline app_usbd_class_data_t * app_usbd_class_data_access(
+ app_usbd_class_inst_t const * const p_inst)
+{
+ return p_inst->p_data;
+}
+
+/**
+ * @name Internal macros for argument mapping
+ *
+ * Functions to be used as a mapping macro for @ref MACRO_MAP, @ref MACRO_MAP_FOR or @ref MACRO_MAP_FOR_PARAM
+ * @{
+ */
+ /**
+ * @brief Count the number of endpoints in given configuration
+ *
+ * Config should be given as a interface configuration in a brackets:
+ * @code
+ * (interface_nr, ep1, ep2, ep3)
+ * @endcode
+ * Number of endpoints may vary from 0 to a few (technically up to 16, but it seems not to make sense to use more than 4).
+ * Interface number is always present.
+ *
+ * @param iface_config Single interface configuration (in brackets)
+ *
+ * @return Number of endpoints in interface. This is computed value - can be used by compiler but not by preprocessor.
+ */
+ #define APP_USBD_CLASS_CONF_IFACE_EP_COUNT_(iface_config) \
+ (NUM_VA_ARGS(BRACKET_EXTRACT(iface_config)) - 1)
+
+ /**
+ * @brief Adds the number of endpoints in given config to the current value
+ *
+ * This is basically @ref APP_USBD_CLASS_CONF_IFACE_EP_COUNT_ with plus sign added.
+ *
+ * @param iface_config See parameters documentation in @ref APP_USBD_CLASS_CONF_IFACE_EP_COUNT_
+ *
+ * @return Plus sign followed by number of endpoints in interface.
+ *
+ * @sa APP_USBD_CLASS_CONF_IFACE_EP_COUNT_
+ */
+ #define APP_USBD_CLASS_CONF_IFACE_EP_PLUS_COUNT_(iface_config) \
+ + APP_USBD_CLASS_CONF_IFACE_EP_COUNT_(iface_config)
+
+ /**
+ * @brief Create variable for endpoint
+ */
+
+ /**
+ * @brief Extract endpoints given interface configuration
+ *
+ * This macro gets single endpoint configuration and extracts all the endpoints.
+ * It also adds comma on the end of extracted endpoints.
+ * This way when this macro is called few times it generates nice list of all endpoints
+ * that may be used to array initialization.
+ *
+ * @param iface_config Single interface configuration in brackets.
+ * The format should be similar like described in @ref APP_USBD_CLASS_CONF_IFACE_EP_COUNT_.
+ */
+ #define APP_USBD_CLASS_IFACE_EP_EXTRACT_(iface_config) \
+ CONCAT_2(APP_USBD_CLASS_IFACE_EP_EXTRACT_, \
+ NUM_VA_ARGS_IS_MORE_THAN_1(BRACKET_EXTRACT(iface_config))) \
+ (BRACKET_EXTRACT(iface_config))
+
+ /**
+ * @brief Auxiliary macro for @ref APP_USBD_CLASS_IFACE_EP_EXTRACT_
+ *
+ * This macro is called when interface has no endpoints
+ */
+ #define APP_USBD_CLASS_IFACE_EP_EXTRACT_0(iface_nr)
+
+ /**
+ * @brief Auxiliary macro for @ref APP_USBD_CLASS_IFACE_EP_EXTRACT_
+ *
+ * This macro is called when interface has at least one endpoint
+ */
+ #define APP_USBD_CLASS_IFACE_EP_EXTRACT_1(...) \
+ APP_USBD_CLASS_IFACE_EP_EXTRACT_1_(__VA_ARGS__)
+
+ #define APP_USBD_CLASS_IFACE_EP_EXTRACT_1_(iface_nr, ...) \
+ MACRO_MAP_REC(PARAM_CBRACE, __VA_ARGS__)
+
+ /**
+ * @brief Generate configuration for single interface
+ *
+ * This macro extract configuration for single interface.
+ * The configuration is inside curly brackets and comma is added on the end.
+ * This mean it can be directly used to init array of interface configurations.
+ *
+ * @param iface_config Single interface configuration
+ * @param N Currently processed configuration
+ * @param iface_configs All interfaces configuration in brackets
+ */
+ #define APP_USBD_CLASS_IFACE_CONFIG_EXTRACT_(iface_config, N, iface_configs) \
+ CONCAT_2(APP_USBD_CLASS_IFACE_CONFIG_EXTRACT_, \
+ NUM_VA_ARGS_IS_MORE_THAN_1(BRACKET_EXTRACT(iface_config))) \
+ (N, iface_configs, BRACKET_EXTRACT(iface_config))
+
+ #define APP_USBD_CLASS_IFACE_CONFIG_EXTRACT_x(iface_config, N, iface_configs) \
+ [N] = !!!iface_config!!!
+ /**
+ * @brief Auxiliary macro for @ref APP_USBD_CLASS_IFACE_CONFIG_EXTRACT_
+ *
+ * This macro is called when interface has no endpoints
+ */
+ #define APP_USBD_CLASS_IFACE_CONFIG_EXTRACT_0(N, iface_configs, iface_nr) \
+ APP_USBD_CLASS_IFACE_CONFIG_EXTRACT_0_(N, iface_configs, iface_nr)
+ #define APP_USBD_CLASS_IFACE_CONFIG_EXTRACT_0_(N, iface_configs, iface_nr) \
+ { .number = iface_nr, .ep_cnt = 0, .ep_offset = 0 },
+
+ /**
+ * @brief Auxiliary macro for @ref APP_USBD_CLASS_IFACE_CONFIG_EXTRACT_
+ *
+ * This macro is called when interface has at last one endpoint
+ */
+ #define APP_USBD_CLASS_IFACE_CONFIG_EXTRACT_1(N, iface_configs, ...) \
+ APP_USBD_CLASS_IFACE_CONFIG_EXTRACT_1_(N, iface_configs, __VA_ARGS__)
+ #define APP_USBD_CLASS_IFACE_CONFIG_EXTRACT_1_(N, iface_configs, iface_nr, ...) \
+ { .number = iface_nr, .ep_cnt = NUM_VA_ARGS(__VA_ARGS__), \
+ .ep_offset = APP_USBD_CLASS_CONF_TOTAL_EP_COUNT_N(N, iface_configs) * \
+ sizeof(app_usbd_class_ep_conf_t) \
+ + ((NUM_VA_ARGS(BRACKET_EXTRACT(iface_configs)) - N) * \
+ sizeof(app_usbd_class_iface_conf_t)) \
+ },
+
+/** @} */
+
+
+/**
+ * @name Macros that uses mapping macros internally
+ *
+ * Auxiliary macros that uses mapping macros to make some calculations or realize other functionality.
+ * Mapped here for easier unit testing and to hide complex mapping functions calling.
+ * @{
+ */
+
+/**
+ * @brief Count total number of endpoints
+ *
+ * @param iface_configs List of interface configurations like explained
+ * in documentation for @ref APP_USBD_CLASS_INSTANCE_TYPEDEF
+ *
+ * @return The equation to calculate the number of endpoints by compiler.
+ */
+#define APP_USBD_CLASS_CONF_TOTAL_EP_COUNT(iface_configs) \
+ (0 MACRO_MAP(APP_USBD_CLASS_CONF_IFACE_EP_PLUS_COUNT_, BRACKET_EXTRACT(iface_configs)))
+
+/**
+ * @brief Count total number of endpoint up-to interface index
+ *
+ * The version of @ref APP_USBD_CLASS_CONF_TOTAL_EP_COUNT macro which takes the
+ * number of interfaces to analyze.
+ *
+ * @param N Number of interfaces to analyze
+ * @param iface_configs List of interface configurations like explained
+ * in documentation for @ref APP_USBD_CLASS_INSTANCE_TYPEDEF
+ *
+ * @return The equation to calculate the number of endpoints by compiler.
+ */
+#define APP_USBD_CLASS_CONF_TOTAL_EP_COUNT_N(N, iface_configs) \
+ (0 MACRO_MAP_N(N, APP_USBD_CLASS_CONF_IFACE_EP_PLUS_COUNT_, BRACKET_EXTRACT(iface_configs)))
+
+/**
+ * @brief Extract configurations for interfaces
+ *
+ * This macro extracts the configurations for every interface.
+ * Basically uses the @ref APP_USBD_CLASS_IFACE_CONFIG_EXTRACT_ macro on every
+ * configuration found.
+ *
+ * This should generate interface configuration initialization data
+ * in comma separated initializers in curly braces.
+ *
+ * @param iface_configs List of interface configurations like explained
+ * in documentation for @ref APP_USBD_CLASS_INSTANCE_TYPEDEF
+ *
+ * @return Comma separated initialization data for all interfaces.
+ */
+/*lint -emacro( (40), APP_USBD_CLASS_IFACES_CONFIG_EXTRACT) */
+#define APP_USBD_CLASS_IFACES_CONFIG_EXTRACT(iface_configs) \
+ MACRO_MAP_FOR_PARAM(iface_configs, \
+ APP_USBD_CLASS_IFACE_CONFIG_EXTRACT_, \
+ BRACKET_EXTRACT(iface_configs))
+
+/**
+ * @brief Extract all endpoints
+ *
+ * Macro that extracts all endpoints from every interface
+ *
+ * @param iface_configs List of interface configurations like explained
+ * in documentation for @ref APP_USBD_CLASS_INSTANCE_TYPEDEF
+ *
+ * @return Comma separated list of endpoints
+ */
+/*lint -emacro( (40), APP_USBD_CLASS_IFACES_EP_EXTRACT) */
+#define APP_USBD_CLASS_IFACES_EP_EXTRACT(iface_configs) \
+ MACRO_MAP(APP_USBD_CLASS_IFACE_EP_EXTRACT_, BRACKET_EXTRACT(iface_configs))
+
+
+/** @} */
+
+
+/**
+ * @brief USBD instance of class mnemonic
+ *
+ * Macro that generates mnemonic for the name of the structure that describes instance for selected class.
+ *
+ * @param type_name The name of the instance without _t postfix
+ *
+ * @return The name with the right postfix to create the name for the type for the class.
+ */
+#define APP_USBD_CLASS_INSTANCE_TYPE(type_name) CONCAT_2(type_name, _t)
+
+/**
+ * @brief USBD data for instance class mnemonic
+ *
+ * The mnemonic of the variable type that holds writable part of the class instance.
+ *
+ * @param type_name The name of the instance without _t postfix
+ *
+ * @return The name with the right postfix to create the name for the data type for the class.
+ */
+#define APP_USBD_CLASS_DATA_TYPE(type_name) CONCAT_2(type_name, _data_t)
+
+/**
+ * @brief Declare class specific member of class instance
+ *
+ * @param type Type of the attached class configuration.
+ *
+ * @sa APP_USBD_CLASS_INSTANCE_TYPEDEF
+ */
+#define APP_USBD_CLASS_INSTANCE_SPECIFIC_DEC(type) type class_part;
+
+/**
+ * @brief Used if there is no class specific configuration
+ *
+ * This constant can be used if there is no specific configuration inside created instance
+ *
+ * @sa APP_USBD_CLASS_INSTANCE_TYPEDEF
+ */
+#define APP_USBD_CLASS_INSTANCE_SPECIFIC_DEC_NONE
+
+/**
+ * @brief Declare class specific member of class data
+ *
+ * @param type Type of the attached class data.
+ *
+ * @sa APP_USBD_CLASS_DATA_TYPEDEF
+ */
+#define APP_USBD_CLASS_DATA_SPECIFIC_DEC(type) APP_USBD_CLASS_INSTANCE_SPECIFIC_DEC(type)
+
+/**
+ * @brief Used if there is no class specific data
+ *
+ * This constant can be used if there is no specific writable data inside created instance
+ *
+ * @sa APP_USBD_CLASS_DATA_TYPEDEF
+ */
+#define APP_USBD_CLASS_DATA_SPECIFIC_DEC_NONE APP_USBD_CLASS_INSTANCE_SPECIFIC_DEC_NONE
+
+
+
+
+/**
+ * @brief Instance structure declaration
+ *
+ * The macro that declares a variable type that would be used to store given class instance.
+ * Class instance stores all the data from @ref app_usbd_class_inst_t and overlaid data for specified class.
+ *
+ * The structure of interface configuration data:
+ * @code
+ * (
+ * (iface1_nr, (ep1, ep2, ep3)),
+ (iface2_nr),
+ (iface3_nr, (ep4))
+ * )
+ * @endcode
+ *
+ * @param type_name The name of the instance without _t postfix.
+ * @param interfaces_configs List of interface configurations like explained above.
+ * @param class_config_dec Result of the macro
+ * @ref APP_USBD_CLASS_INSTANCE_SPECIFIC_DEC or
+ * @ref APP_USBD_CLASS_INSTANCE_SPECIFIC_DEC_NONE
+ *
+ * @return The definition of the structure type that holds all the required data.
+ *
+ * @note It should not be used directly in the final application. See @ref APP_USBD_CLASS_DATA_TYPEDEF instead.
+ *
+ * @note APP_USBD_CLASS_DATA_TYPEDEF has to be called first for the compilation to success.
+ *
+ * @sa APP_USBD_CLASS_TYPEDEF
+ */
+#define APP_USBD_CLASS_INSTANCE_TYPEDEF(type_name, interfaces_configs, class_config_dec) \
+ typedef union CONCAT_2(type_name, _u) \
+ { \
+ app_usbd_class_inst_t base; \
+ struct \
+ { \
+ APP_USBD_CLASS_DATA_TYPE(type_name) * p_data; \
+ app_usbd_class_methods_t const * p_class_methods; \
+ struct \
+ { \
+ uint8_t cnt; \
+ app_usbd_class_iface_conf_t \
+ config[NUM_VA_ARGS(BRACKET_EXTRACT(interfaces_configs))]; \
+ app_usbd_class_ep_conf_t \
+ ep[APP_USBD_CLASS_CONF_TOTAL_EP_COUNT(interfaces_configs)]; \
+ } iface; \
+ class_config_dec \
+ } specific; \
+ } APP_USBD_CLASS_INSTANCE_TYPE(type_name)
+
+/**
+ * @brief Same as @ref APP_USBD_CLASS_INSTANCE_TYPEDEF but for class with EP0 only.
+ */
+#define APP_USBD_CLASS_INSTANCE_NO_EP_TYPEDEF(type_name, interfaces_configs, class_config_dec) \
+ typedef union CONCAT_2(type_name, _u) \
+ { \
+ app_usbd_class_inst_t base; \
+ struct \
+ { \
+ APP_USBD_CLASS_DATA_TYPE(type_name) * p_data; \
+ app_usbd_class_methods_t const * p_class_methods; \
+ struct \
+ { \
+ uint8_t cnt; \
+ app_usbd_class_iface_conf_t \
+ config[NUM_VA_ARGS(BRACKET_EXTRACT(interfaces_configs))]; \
+ } iface; \
+ class_config_dec \
+ } specific; \
+ } APP_USBD_CLASS_INSTANCE_TYPE(type_name)
+
+/**
+ * @brief Writable data structure declaration
+ *
+ * The macro that declares a variable type that would be used to store given class writable data.
+ * Writable data contains base part of the type @ref app_usbd_class_data_t followed by
+ * class specific data.
+ *
+ * @param type_name The name of the type without _t postfix.
+ * @param class_data_dec Result of the macro
+ * @ref APP_USBD_CLASS_DATA_SPECIFIC_DEC or
+ * @ref APP_USBD_CLASS_DATA_SPECIFIC_DEC_NONE
+ *
+ * @return The definition of the structure type that holds all the required writable data
+ *
+ * @note It should not be used directly in the final application. See @ref APP_USBD_CLASS_DATA_TYPEDEF instead.
+ *
+ * @sa APP_USBD_CLASS_TYPEDEF
+ */
+#define APP_USBD_CLASS_DATA_TYPEDEF(type_name, class_data_dec) \
+ typedef struct \
+ { \
+ app_usbd_class_data_t base; \
+ class_data_dec \
+ }APP_USBD_CLASS_DATA_TYPE(type_name)
+
+
+/**
+ * @brief Declare all data types required by the class instance
+ *
+ * Macro that declares data type first and then instance type.
+ *
+ * @param type_name The name of the type without _t postfix.
+ * @param interface_configs List of interface configurations like in @ref APP_USBD_CLASS_INSTANCE_TYPEDEF.
+ * @param class_config_dec Result of the macro
+ * @ref APP_USBD_CLASS_INSTANCE_SPECIFIC_DEC or
+ * @ref APP_USBD_CLASS_INSTANCE_SPECIFIC_DEC_NONE
+ * @param class_data_dec Result of the macro
+ * @ref APP_USBD_CLASS_DATA_SPECIFIC_DEC or
+ * @ref APP_USBD_CLASS_DATA_SPECIFIC_DEC_NONE
+ *
+ * @return Declaration of the data type for the instance and instance itself.
+ *
+ * @sa APP_USBD_CLASS_DATA_TYPEDEF
+ * @sa APP_USBD_CLASS_INSTANCE_TYPEDEF
+ */
+#define APP_USBD_CLASS_TYPEDEF(type_name, interface_configs, class_config_dec, class_data_dec) \
+ APP_USBD_CLASS_DATA_TYPEDEF(type_name, class_data_dec); \
+ APP_USBD_CLASS_INSTANCE_TYPEDEF(type_name, interface_configs, class_config_dec)
+
+/**
+ * @brief Same as @ref APP_USBD_CLASS_TYPEDEF but for class with EP0 only.
+ */
+#define APP_USBD_CLASS_NO_EP_TYPEDEF(type_name, \
+ interface_configs, \
+ class_config_dec, \
+ class_data_dec) \
+ APP_USBD_CLASS_DATA_TYPEDEF(type_name, class_data_dec); \
+ APP_USBD_CLASS_INSTANCE_NO_EP_TYPEDEF(type_name, interface_configs, class_config_dec)
+
+/**
+ * @brief Forward declaration of type defined by @ref APP_USBD_CLASS_TYPEDEF
+ *
+ * @param type_name The name of the type without _t postfix.
+ * */
+#define APP_USBD_CLASS_FORWARD(type_name) union CONCAT_2(type_name, _u)
+
+/**
+ * @brief Generate the initialization data for
+ *
+ * Macro that generates the initialization data for instance.
+ *
+ * @param p_ram_data Pointer to writable instance data structure
+ * @param class_methods Class methods
+ * @param interfaces_configs Exactly the same interface config data that in @ref APP_USBD_CLASS_INSTANCE_TYPEDEF
+ * @param class_config_part Configuration part. The data should be inside brackets.
+ * Any data here would be removed from brackets and then put as an initialization
+ * data for class_part member of instance structure.
+ *
+ * @note It should not be used directly in the final application. See @ref APP_USBD_CLASS_INST_DEF instead.
+ */
+#define APP_USBD_CLASS_INSTANCE_INITVAL(p_ram_data, \
+ class_methods, \
+ interfaces_configs, \
+ class_config_part) \
+ { \
+ .specific = { \
+ .p_data = p_ram_data, \
+ .p_class_methods = class_methods, \
+ .iface = { \
+ .cnt = NUM_VA_ARGS(BRACKET_EXTRACT(interfaces_configs)), \
+ .config = { APP_USBD_CLASS_IFACES_CONFIG_EXTRACT(interfaces_configs) }, \
+ .ep = { APP_USBD_CLASS_IFACES_EP_EXTRACT(interfaces_configs) } \
+ }, \
+ BRACKET_EXTRACT(class_config_part) \
+ } \
+ }
+
+/**
+ * @brief Same as @ref APP_USBD_CLASS_INSTANCE_INITVAL but for class with EP0 only.
+ */
+#define APP_USBD_CLASS_INSTANCE_NO_EP_INITVAL(p_ram_data, \
+ class_methods, \
+ interfaces_configs, \
+ class_config_part) \
+ { \
+ .specific = { \
+ .p_data = p_ram_data, \
+ .p_class_methods = class_methods, \
+ .iface = { \
+ .cnt = NUM_VA_ARGS(BRACKET_EXTRACT(interfaces_configs)), \
+ .config = { APP_USBD_CLASS_IFACES_CONFIG_EXTRACT(interfaces_configs) } \
+ }, \
+ BRACKET_EXTRACT(class_config_part) \
+ } \
+ }
+
+/**
+ * @brief Define the base class instance
+ *
+ * Macro that defines whole instance variable and fill it with initialization data.
+ *
+ * The tricky part is @c class_config_part.
+ * The configuration data here has to be placed inside brackets.
+ * Then any type of values can be used depending on the type used in @ref APP_USBD_CLASS_TYPEDEF.
+ * If instance does not has any specyfic data, use just empty bracket here.
+ * @code
+ * APP_USBD_CLASS_TYPEDEF(
+ * some_base_class,
+ * CLASS_BASE_CONFIGURATION,
+ * APP_USBD_CLASS_INSTANCE_SPECIFIC_DEC_NONE,
+ * APP_USBD_CLASS_DATA_SPECIFIC_DEC_NONE
+ * );
+ * APP_USBD_CLASS_INST_DEF(
+ * some_base_class_inst,
+ * some_base_class,
+ * base_class_event_handler,
+ * CLASS_BASE_CONFIGURATION,
+ * () // Empty configuration
+ * );
+ * @endcode
+ *
+ * If the type of instance configuration is simple type, just provide initialization value:
+ * @code
+ * APP_USBD_CLASS_TYPEDEF(
+ * some_base_class,
+ * CLASS_BASE_CONFIGURATION,
+ * APP_USBD_CLASS_INSTANCE_SPECIFIC_DEC_NONE,
+ * APP_USBD_CLASS_DATA_SPECIFIC_DEC(uint8_t)
+ * );
+ * APP_USBD_CLASS_INST_DEF(
+ * some_base_class_inst,
+ * some_base_class,
+ * base_class_event_handler,
+ * CLASS_BASE_CONFIGURATION,
+ * (12) // Example values
+ * );
+ * @endcode
+ *
+ * If the type of instance configuration is structure, provide initialization value for the whole structure:
+ * @code
+ * typedef structure
+ * {
+ * uint32_t p1;
+ * uint8_t p2;
+ * }my_config_t;
+ *
+ * APP_USBD_CLASS_TYPEDEF(
+ * some_base_class,
+ * CLASS_BASE_CONFIGURATION,
+ * APP_USBD_CLASS_INSTANCE_SPECIFIC_DEC_NONE,
+ * APP_USBD_CLASS_DATA_SPECIFIC_DEC(my_config_t)
+ * );
+ * APP_USBD_CLASS_INST_DEF(
+ * some_base_class_inst,
+ * some_base_class,
+ * base_class_event_handler,
+ * CLASS_BASE_CONFIGURATION,
+ * ({12, 3}) // Example values
+ * );
+ * @endcode
+ *
+ * @param instance_name The name of created instance variable.
+ * It would be constant variable and its type would be app_usbd_class_inst_t.
+ * @param type_name The name of the variable type. It has to be the same type that was passed to
+ * @ref APP_USBD_CLASS_TYPEDEF
+ * @param class_methods Class unified interface.
+ * @param interfaces_configs The same configuration data that the one passed to @ref APP_USBD_CLASS_TYPEDEF
+ * @param class_config_part Configuration data to the type that was declared by class_data_dec when calling
+ * @ref APP_USBD_CLASS_TYPEDEF.
+ * Configuration data has to be provided in brackets.
+ * It would be extracted from brackets and placed in initialization part of configuration structure.
+ * See detailed description of this macro for more informations.
+ */
+#define APP_USBD_CLASS_INST_DEF(instance_name, \
+ type_name, \
+ class_methods, \
+ interfaces_configs, \
+ class_config_part) \
+ static APP_USBD_CLASS_DATA_TYPE(type_name) CONCAT_2(instance_name, _data); \
+ static const APP_USBD_CLASS_INSTANCE_TYPE(type_name) instance_name = \
+ APP_USBD_CLASS_INSTANCE_INITVAL( \
+ &CONCAT_2(instance_name, _data), \
+ class_methods, \
+ interfaces_configs, \
+ class_config_part)
+
+
+/**
+ * @brief Define the base class instance in global scope
+ *
+ * This is the same macro like @ref APP_USBD_CLASS_INST_DEF but it creates the instance
+ * without static keyword.
+ *
+ * @param instance_name See documentation for @ref APP_USBD_CLASS_INST_DEF
+ * @param type_name See documentation for @ref APP_USBD_CLASS_INST_DEF
+ * @param class_methods See documentation for @ref APP_USBD_CLASS_INST_DEF
+ * @param interfaces_configs See documentation for @ref APP_USBD_CLASS_INST_DEF
+ * @param class_config_part See documentation for @ref APP_USBD_CLASS_INST_DEF
+ */
+#define APP_USBD_CLASS_INST_GLOBAL_DEF(instance_name, \
+ type_name, \
+ class_methods, \
+ interfaces_configs, \
+ class_config_part) \
+ static APP_USBD_CLASS_DATA_TYPE(type_name) CONCAT_2(instance_name, _data); \
+ const APP_USBD_CLASS_INSTANCE_TYPE(type_name) instance_name = \
+ APP_USBD_CLASS_INSTANCE_INITVAL( \
+ &CONCAT_2(instance_name, _data), \
+ class_methods, \
+ interfaces_configs, \
+ class_config_part)
+
+/**
+ * @brief Same as @ref APP_USBD_CLASS_INST_GLOBAL_DEF but for class with EP0 only.
+ */
+#define APP_USBD_CLASS_INST_NO_EP_GLOBAL_DEF(instance_name, \
+ type_name, \
+ class_methods, \
+ interfaces_configs, \
+ class_config_part) \
+ static APP_USBD_CLASS_DATA_TYPE(type_name) CONCAT_2(instance_name, _data); \
+ const APP_USBD_CLASS_INSTANCE_TYPE(type_name) instance_name = \
+ APP_USBD_CLASS_INSTANCE_NO_EP_INITVAL( \
+ &CONCAT_2(instance_name, _data), \
+ class_methods, \
+ interfaces_configs, \
+ class_config_part)
+/**
+ * @brief Access class specific configuration
+ *
+ * Macro that returns class specific configuration.
+ *
+ * @param[in] p_inst Instance pointer
+ *
+ * @return A pointer for class specific part of the instance
+ *
+ * @note If macro is used on the instance that has no class specific configuration
+ * an error would be generated during compilation.
+ */
+#define APP_USBD_CLASS_GET_SPECIFIC_CONFIG(p_inst) (&((p_inst)->specific.class_part))
+
+/**
+ * @brief Access class specific data
+ *
+ * @param[in] p_inst Instance pointer
+ *
+ * @return A pointer for class specific part of writable data
+ *
+ * @note If macro is used on the instance that has no class specific data
+ * an error would be generated during compilation.
+ */
+#define APP_USBD_CLASS_GET_SPECIFIC_DATA(p_inst) (&(((p_inst)->specific.p_data)->class_part))
+
+/**
+ * @brief Macro to get base instance from class specific instance
+ *
+ * This macro may be used on class specific instance to get base instance that
+ * can be processed by base instance access functions.
+ * Class specific instance can be just casted to class base instance,
+ * but then we would totally lost type safety.
+ *
+ * A little more safe is to use pointer to base member of class instance.
+ * This would generate an error when used on any variable that has no base member
+ * and would generate also error if this base member is wrong type.
+ */
+#define APP_USBD_CLASS_BASE_INSTANCE(p_inst) (&((p_inst)->base))
+
+/*lint -emacro(142 438 616 646, APP_USBD_CLASS_DESCRIPTOR_INIT, APP_USBD_CLASS_DESCRIPTOR_BEGIN, APP_USBD_CLASS_DESCRIPTOR_YIELD, APP_USBD_CLASS_DESCRIPTOR_END, APP_USBD_CLASS_DESCRIPTOR_WRITE)*/
+
+/**
+ * @brief Initialize class descriptor
+ *
+ * @param[in] p_ctx Class descriptor context
+ */
+
+#define APP_USBD_CLASS_DESCRIPTOR_INIT(p_ctx) \
+ (p_ctx)->line = 0;
+
+/**
+ * @brief Begin class descriptor
+ *
+ * @param[in] p_ctx Class descriptor context
+ * @param[in] p_buff Buffer to write into
+ * @param[in] max_size Size of the buffer
+ */
+
+#define APP_USBD_CLASS_DESCRIPTOR_BEGIN(p_ctx, p_buff, max_size) \
+ ASSERT((p_ctx) != NULL); \
+ app_usbd_class_descriptor_state_t this_descriptor_feed; \
+ this_descriptor_feed.p_buffer = (p_buff); \
+ this_descriptor_feed.current_size = 0; \
+ this_descriptor_feed.maximum_size = (max_size); \
+ this_descriptor_feed.p_context = (p_ctx); \
+ switch ((this_descriptor_feed.p_context)->line) \
+ { \
+ case 0: \
+ ;
+
+/**
+ * @brief Yield class descriptor
+ *
+ */
+
+#define APP_USBD_CLASS_DESCRIPTOR_YIELD() \
+do \
+{ \
+ (this_descriptor_feed.p_context)->line = __LINE__; \
+ return true; \
+ case __LINE__: \
+ ; \
+} while (0)
+
+/*lint -emacro(438 527, APP_USBD_CLASS_DESCRIPTOR_END)*/
+
+/**
+ * @brief End class descriptor
+ *
+ * This function has to be called at the end of class descriptor feeder function.
+ * No other operations in feeder function can be done after calling it.
+ */
+
+#define APP_USBD_CLASS_DESCRIPTOR_END() \
+ APP_USBD_CLASS_DESCRIPTOR_YIELD(); \
+ } \
+ (this_descriptor_feed.p_context)->line = 0; \
+ return false;
+
+
+/**
+ * @brief Write descriptor using protothreads
+ *
+ * This function writes one byte to the buffer with offset. If buffer is full
+ * it yields.
+ *
+ * It is used by the class descriptor feeders internally.
+ *
+ * @ref APP_USBD_CLASS_DESCRIPTOR_BEGIN has to be called before using this function.
+ * @ref APP_USBD_CLASS_DESCRIPTOR_END has to be called after last use of this function.
+ *
+ * @param data Byte to be written to buffer
+ */
+#define APP_USBD_CLASS_DESCRIPTOR_WRITE(data) \
+do \
+{ \
+ (this_descriptor_feed.p_context)->data_buffer = (data); \
+ if (this_descriptor_feed.current_size >= this_descriptor_feed.maximum_size) \
+ { \
+ APP_USBD_CLASS_DESCRIPTOR_YIELD(); \
+ } \
+ if(this_descriptor_feed.p_buffer != NULL) \
+ { \
+ *(this_descriptor_feed.p_buffer + this_descriptor_feed.current_size) = \
+ (this_descriptor_feed.p_context)->data_buffer; \
+ } \
+ this_descriptor_feed.current_size++; \
+} while(0);
+
+/** @} */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* APP_USBD_CLASS_BASE_H__ */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/usbd/app_usbd_core.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/usbd/app_usbd_core.c
new file mode 100644
index 0000000..c2b02ce
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/usbd/app_usbd_core.c
@@ -0,0 +1,1222 @@
+/**
+ * Copyright (c) 2016 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#include "sdk_common.h"
+#if NRF_MODULE_ENABLED(APP_USBD)
+
+#include "app_usbd_core.h"
+#include "app_usbd.h"
+#include "app_usbd_request.h"
+#include "app_usbd_string_desc.h"
+#include "nrf.h"
+#include "nrf_atomic.h"
+#include "app_util_platform.h"
+#include "app_usbd.h"
+#include "app_usbd_class_base.h"
+
+#define NRF_LOG_MODULE_NAME app_usbd_core
+
+#if APP_USBD_CONFIG_LOG_ENABLED
+#define NRF_LOG_LEVEL APP_USBD_CONFIG_LOG_LEVEL
+#define NRF_LOG_INFO_COLOR APP_USBD_CONFIG_INFO_COLOR
+#define NRF_LOG_DEBUG_COLOR APP_USBD_CONFIG_DEBUG_COLOR
+#else //APP_USBD_CONFIG_LOG_ENABLED
+#define NRF_LOG_LEVEL 0
+#endif //APP_USBD_CONFIG_LOG_ENABLED
+#include "nrf_log.h"
+NRF_LOG_MODULE_REGISTER();
+
+/* Test if VID was configured */
+#ifndef APP_USBD_VID
+#error APP_USBD_VID not properly defined.
+#endif
+
+
+/* Device version checking */
+#if defined(APP_USBD_DEVICE_VER_MAJOR) && defined(APP_USBD_DEVICE_VER_MINOR)
+ #if ((APP_USBD_DEVICE_VER_MAJOR)) > 99 || ((APP_USBD_DEVICE_VER_MINOR) > 99)
+ #error Major and minor device version value have to be limited to 99.
+ #endif
+#else
+ #error The definition of a pair APP_USBD_DEVICE_VER_MAJOR and APP_USBD_DEVICE_VER_MINOR required.
+#endif
+
+/**
+ * @internal
+ * @defgroup app_usbd_core_internals USB Device high level library core module internals
+ * @ingroup app_usbd_core
+ *
+ * Internal variables, auxiliary macros and functions of USBD high level core module.
+ * @{
+ */
+
+/** @brief Make USB power value */
+#define APP_USBD_POWER_MAKE(ma) (((ma) + 1) / 2)
+
+/**
+ @brief Default device descriptor initializer @ref app_usbd_descriptor_device_t
+* */
+#define APP_USBD_CORE_DEVICE_DESCRIPTOR { \
+ .bLength = sizeof(app_usbd_descriptor_device_t), /* descriptor size */ \
+ .bDescriptorType = APP_USBD_DESCRIPTOR_DEVICE, /* descriptor type */ \
+ .bcdUSB = APP_USBD_BCD_VER_MAKE(2,0), /* USB BCD version: 2.0 */ \
+ .bDeviceClass = 0, /* device class: 0 - specified by interface */ \
+ .bDeviceSubClass = 0, /* device subclass: 0 - specified by interface */ \
+ .bDeviceProtocol = 0, /* device protocol: 0 - specified by interface */ \
+ .bMaxPacketSize0 = NRF_DRV_USBD_EPSIZE, /* endpoint size: fixed to: NRF_DRV_USBD_EPSIZE*/ \
+ .idVendor = APP_USBD_VID, /* Vendor ID*/ \
+ .idProduct = APP_USBD_PID, /* Product ID*/ \
+ .bcdDevice = APP_USBD_BCD_VER_MAKE( /* Device version BCD */ \
+ APP_USBD_DEVICE_VER_MAJOR, \
+ APP_USBD_DEVICE_VER_MINOR), \
+ .iManufacturer = APP_USBD_STRING_ID_MANUFACTURER, /* String ID: manufacturer */ \
+ .iProduct = APP_USBD_STRING_ID_PRODUCT, /* String ID: product */ \
+ .iSerialNumber = APP_USBD_STRING_ID_SERIAL, /* String ID: serial */ \
+ .bNumConfigurations = 1 /* Fixed value: only one configuration supported*/\
+}
+
+
+#define APP_USBD_CORE_CONFIGURATION_DESCRIPTOR { \
+ .bLength = sizeof(app_usbd_descriptor_configuration_t), \
+ .bDescriptorType = APP_USBD_DESCRIPTOR_CONFIGURATION, \
+ .wTotalLength = 0, /*Calculated dynamically*/ \
+ .bNumInterfaces = 0, /*Calculated dynamically*/ \
+ .bConfigurationValue = 1, /*Value passed to set configuration*/ \
+ .iConfiguration = 0, /*Configuration ID: fixed to 0*/ \
+ .bmAttributes = APP_USBD_DESCRIPTOR_CONFIGURATION_ATTRIBUTE_ALWAYS_SET_MASK | \
+ ((APP_USBD_CONFIG_SELF_POWERED) ? \
+ APP_USBD_DESCRIPTOR_CONFIGURATION_ATTRIBUTE_SELF_POWERED_MASK \
+ : \
+ 0), \
+ .bMaxPower = APP_USBD_POWER_MAKE(APP_USBD_CONFIG_MAX_POWER), \
+}
+
+/**
+ * @brief Device descriptor instance.
+ *
+ * @note
+ * Constant part of the device descriptor.
+ * Values that must be calculated are updated directly in the buffer
+ * just before the transmission.
+ */
+static const app_usbd_descriptor_device_t m_device_dsc =
+ APP_USBD_CORE_DEVICE_DESCRIPTOR;
+
+/**
+ * @brief Configuration descriptor instance.
+ *
+ * @note
+ * Constant part of the device descriptor.
+ * Values that must be calculated are updated directly in the buffer
+ * just before the transmission.
+ */
+static const app_usbd_descriptor_configuration_t m_configuration_dsc =
+ APP_USBD_CORE_CONFIGURATION_DESCRIPTOR;
+
+/* Required early declaration of event handler function */
+static ret_code_t app_usbd_core_event_handler(app_usbd_class_inst_t const * const p_inst,
+ app_usbd_complex_evt_t const * const p_event);
+
+/**
+ * @brief Current USB device state
+ *
+ * This variable is updated automatically by core library.
+ */
+static app_usbd_state_t m_app_usbd_state = APP_USBD_STATE_Disabled;
+
+/**
+ * @brief Active device features
+ *
+ * @note Only @ref APP_USBD_SETUP_STDFEATURE_DEVICE_REMOTE_WAKEUP is supported for device
+ */
+static uint8_t m_device_features_state;
+
+/**
+ * @brief Remote wake-up pending flag
+ */
+static nrf_atomic_flag_t m_rwu_pending;
+
+
+/**
+ * @brief Core class methods
+ *
+ * Base methods interface for core class.
+ * This is quite specific class - it would be only connected into endpoint 0.
+ * Not connected into instances list.
+ */
+static const app_usbd_class_methods_t m_core_methods = {
+ .event_handler = app_usbd_core_event_handler,
+ .feed_descriptors = NULL,
+};
+
+/**
+ * @brief Setup transfer buffer
+ */
+static uint8_t m_setup_transfer_buff[NRF_DRV_USBD_EPSIZE];
+
+
+/**
+ * @brief Handler for outgoing setup data
+ *
+ * @todo RK documentation
+ */
+static app_usbd_core_setup_data_handler_desc_t m_ep0_handler_desc;
+
+#define APP_USBD_CORE_CLASS_INSTANCE_CONFIG ()
+
+
+/*lint -u -save -e26 -e40 -e64 -e123 -e505 -e651*/
+
+/**
+ * @brief Core instance
+ *
+ * Create instance that would be connected into endpoints in USBD library.
+ */
+APP_USBD_CLASS_INST_GLOBAL_DEF(
+ app_usbd_core_inst,
+ app_usbd_core,
+ &m_core_methods,
+ APP_USBD_CORE_CLASS_CONFIGURATION,
+ () );
+/*lint -restore*/
+
+/**
+ * @brief Set the new USB state
+ *
+ * Function changes the internal status of the bus.
+ * If the bus status is different than the one configured, an event is passed to all
+ * the instances.
+ *
+ * @param state New state to be set
+ *
+ * @sa usbd_core_state_get
+ */
+static void usbd_core_state_set(app_usbd_state_t state)
+{
+ if (m_app_usbd_state != state)
+ {
+ m_app_usbd_state = state;
+ if(state != APP_USBD_STATE_Configured)
+ {
+ CLR_BIT(m_device_features_state, APP_USBD_SETUP_STDFEATURE_DEVICE_REMOTE_WAKEUP);
+ }
+ static const app_usbd_evt_t evt_data = {
+ .type = APP_USBD_EVT_STATE_CHANGED
+ };
+ app_usbd_event_execute((app_usbd_internal_evt_t const *)&evt_data);
+ }
+}
+
+/**
+ * @brief Get the current USB state - internal function
+ *
+ * This is just a wrapper for @ref app_usbd_core_state_get
+ * to make symmetrical function to the internal @ref usbd_core_state_set.
+ *
+ * @return Current USB state
+ *
+ * @sa usbd_core_state_set
+ * @sa app_usbd_core_state_get
+ */
+static inline app_usbd_state_t usbd_core_state_get(void)
+{
+ return m_app_usbd_state;
+}
+
+/**
+ * @brief Check current USBD power connection status
+ *
+ */
+static inline bool usbd_core_power_is_detected(void)
+{
+ return 0 != ( (NRF_POWER->USBREGSTATUS) & POWER_USBREGSTATUS_VBUSDETECT_Msk);
+}
+
+/**
+ * @brief Clear current EP0 handler
+ *
+ * Function just clears the EP0 handler without calling it
+ */
+static inline void usbd_core_ep0_handler_clear(void)
+{
+ m_ep0_handler_desc.handler = NULL;
+}
+
+/**
+ * @brief Safely call EP0 handler
+ *
+ * Function calls EP0 handler only if its pointer is non-zero.
+ *
+ * @param status Status to send as a handler parameter.
+ */
+static inline ret_code_t usbd_core_ep0_handler_call_and_clear(nrf_drv_usbd_ep_status_t status)
+{
+ app_usbd_core_setup_data_handler_t handler = m_ep0_handler_desc.handler;
+ if (NULL != handler)
+ {
+ usbd_core_ep0_handler_clear();
+ return handler(status, m_ep0_handler_desc.p_context);
+ }
+
+ return NRF_ERROR_NULL;
+}
+
+/**
+ * @brief Check if EP0 handler is configured
+ *
+ * EP0 handler is configured is any instance that has processed SETUP command
+ * expects some incoming / outgoing data.
+ *
+ * EP0 handler should be cleared automatically just before it is called
+ * (see @ref usbd_core_ep0_handler_call_and_clear).
+ * If instance requires more data - it has to setup EP0 handler once more time
+ * (see @ref app_usbd_core_setup_data_handler_set).
+ *
+ * This function adds small layer of abstraction for checking if EP0 handler
+ * is already configured.
+ *
+ * @retval true EP0 handler is set
+ * @retval false EP0 handler is cleared
+ */
+static inline bool usb_core_ep0_handler_check(void)
+{
+ return (NULL != m_ep0_handler_desc.handler);
+}
+
+/**
+ * @brief Empty data handler
+ *
+ * Data handler used only to mark that there is requested data during SETUP.
+ *
+ * @return Always NRF_SUCCESS
+ * @sa setup_empty_data_handler_desc
+ */
+static ret_code_t setup_data_handler_empty(nrf_drv_usbd_ep_status_t status, void * p_contex)
+{
+ UNUSED_PARAMETER(status);
+ UNUSED_PARAMETER(p_contex);
+ return NRF_SUCCESS;
+}
+
+/**
+ * @brief
+ *
+ * @todo RK Documentation
+ */
+static app_usbd_core_setup_data_handler_desc_t const m_setup_data_handler_empty_desc =
+{
+ .handler = setup_data_handler_empty,
+ .p_context = NULL
+};
+
+/**
+ * @brief Structure used as a context for descriptor feeder
+ *
+ * Structure with all the data required to process instances to generate descriptor
+ * data chunk.
+ */
+typedef struct
+{
+ app_usbd_class_inst_t const * p_cinst; //!< The class instance that is to be processed next.
+ const uint8_t * p_desc; //!< Pointer at current descriptor or NULL if finished.
+ /**<
+ * If the value passed by @ref p_desc is NULL on transfer function enter it means that ZLP is required.
+ * Or it is time to finish the transfer (depending on @c total_left).
+ */
+ size_t desc_left; //!< Number of bytes left in the current class descriptor to send
+ size_t total_left; //!< Number of bytes left that was requested by the host
+ app_usbd_class_descriptor_ctx_t feed_thread; //!< Class descriptor context
+} app_usbd_core_descriptor_conf_feed_data_t;
+
+/**
+ * @brief Default data used by the feeder
+ *
+ *
+ */
+static app_usbd_core_descriptor_conf_feed_data_t m_descriptor_conf_feed_data;
+
+/**
+ * @brief Descriptor feeder
+ *
+ * Descriptor feeder is used as an callback function when descriptors are
+ * transfered and buffer is ready for next data.
+ * It prepares next chunk of data to be sent.
+ *
+ * @param p_next See @ref nrf_drv_usbd_next_transfer_handler_t documentation.
+ * @param p_context Pointer to @ref app_usbd_core_descriptor_feed_data_t data type.
+ * @param ep_size The size of the endpoint.
+ *
+ * @return See @ref nrf_drv_usbd_next_transfer_handler_t documentation.
+ */
+static bool usbd_descriptor_conf_feeder(
+ nrf_drv_usbd_ep_transfer_t * p_next,
+ void * p_context,
+ size_t ep_size)
+{
+ bool continue_req = true;
+
+ app_usbd_core_descriptor_conf_feed_data_t * p_data = p_context;
+
+
+ if ((p_data->p_desc == NULL) && (app_usbd_class_next_get(p_data->p_cinst) == NULL)
+ && (p_data->desc_left == 0))
+ {
+ /* ZLP */
+ continue_req = false;
+ p_next->p_data.tx = NULL;
+ p_next->size = 0;
+ }
+ else
+ {
+ ASSERT(ep_size <= NRF_DRV_USBD_FEEDER_BUFFER_SIZE);
+ uint8_t * p_tx_buff;
+ size_t size = 0; /* Currently added number of bytes */
+ size_t tx_size; /* Number of bytes to send right now */
+ bool feeding = false;
+
+ /* Feeder function can use the USBD driver internal buffer */
+ p_tx_buff = nrf_drv_usbd_feeder_buffer_get();
+
+ tx_size = MIN(ep_size, p_data->total_left);
+
+ while (0 != tx_size)
+ {
+ size_t to_copy = MIN(tx_size, p_data->desc_left);
+
+ /* First transfer */
+ if (p_data->p_desc != NULL)
+ {
+ memcpy(p_tx_buff + size, p_data->p_desc, to_copy);
+ p_data->p_desc = NULL;
+ }
+ /* Starting with second transfer */
+ else if (0 < p_data->desc_left)
+ {
+ UNUSED_RETURN_VALUE(p_data->p_cinst->p_class_methods->feed_descriptors(
+ &p_data->feed_thread, p_data->p_cinst,
+ (uint8_t *)p_tx_buff + size, to_copy));
+ feeding = true;
+ }
+ else
+ {
+ ;
+ }
+
+ p_data->desc_left -= to_copy;
+ p_data->total_left -= to_copy;
+ tx_size -= to_copy;
+ size += to_copy;
+
+ /* Switch to next class if no descriptor left and first feeding was done */
+ if(p_data->desc_left == 0 && feeding)
+ {
+ p_data->p_cinst = app_usbd_class_next_get(p_data->p_cinst);
+ }
+
+ if (0 == p_data->total_left)
+ {
+ continue_req = false;
+ }
+ else if (0 == p_data->desc_left)
+ {
+ if (NULL == p_data->p_cinst)
+ {
+ p_data->p_desc = NULL;
+ /* No more data - check if ZLP is required */
+ if (size > 0)
+ {
+ if (size < ep_size)
+ {
+ continue_req = false;
+ }
+ }
+ break;
+ }
+ else
+ {
+ /* New class - count descriptor size and initialize feeding thread */
+ app_usbd_class_descriptor_ctx_t desiz;
+ APP_USBD_CLASS_DESCRIPTOR_INIT(&desiz);
+ while(p_data->p_cinst->p_class_methods->feed_descriptors(
+ &desiz, p_data->p_cinst, NULL, sizeof(uint8_t)))
+ {
+ p_data->desc_left++;
+ }
+ APP_USBD_CLASS_DESCRIPTOR_INIT(&p_data->feed_thread);
+ }
+ }
+ else
+ {
+ /* Nothing to do */
+ }
+ }
+ p_next->p_data.tx = p_tx_buff;
+ p_next->size = size;
+ }
+ return continue_req;
+}
+
+/**
+ * @brief Standard endpoint request handle
+ *
+ * @param[in] p_setup_ev Setup event
+ *
+ * @return Standard error code
+ */
+static ret_code_t setup_endpoint_req_std(app_usbd_setup_evt_t const * p_setup_ev)
+{
+ if (APP_USBD_SETUP_REQTYPE_STD != app_usbd_setup_req_typ(p_setup_ev->setup.bmRequestType))
+ {
+ return NRF_ERROR_NOT_SUPPORTED;
+ }
+
+ nrf_drv_usbd_ep_t ep_addr = (nrf_drv_usbd_ep_t)(p_setup_ev->setup.wIndex.lb);
+ app_usbd_state_t usb_state = usbd_core_state_get();
+
+ switch (p_setup_ev->setup.bmRequest)
+ {
+ case APP_USBD_SETUP_STDREQ_GET_STATUS:
+ {
+ if ((usb_state == APP_USBD_STATE_Configured) || (NRF_USBD_EP_NR_GET(ep_addr) == 0))
+ {
+ size_t tx_size;
+ uint16_t * p_tx_buff = app_usbd_core_setup_transfer_buff_get(&tx_size);
+
+ p_tx_buff[0] = nrf_drv_usbd_ep_stall_check(ep_addr) ? 1 : 0;
+ return app_usbd_core_setup_rsp(&(p_setup_ev->setup), p_tx_buff, sizeof(uint16_t));
+ }
+ else
+ {
+ return NRF_ERROR_INVALID_STATE;
+ }
+ }
+ case APP_USBD_SETUP_STDREQ_SET_FEATURE:
+ {
+ if ((!NRF_USBD_EPISO_CHECK(ep_addr)) &&
+ (p_setup_ev->setup.wValue.w == APP_USBD_SETUP_STDFEATURE_ENDPOINT_HALT))
+ {
+ if ((usb_state == APP_USBD_STATE_Configured) || (NRF_USBD_EP_NR_GET(ep_addr) == 0))
+ {
+ nrf_drv_usbd_ep_stall(ep_addr);
+ return NRF_SUCCESS;
+ }
+ else
+ {
+ return NRF_ERROR_INVALID_STATE;
+ }
+ }
+ break;
+ }
+ case APP_USBD_SETUP_STDREQ_CLEAR_FEATURE:
+ {
+ if ((!NRF_USBD_EPISO_CHECK(ep_addr)) &&
+ (p_setup_ev->setup.wValue.w == APP_USBD_SETUP_STDFEATURE_ENDPOINT_HALT))
+ {
+ if ((usb_state == APP_USBD_STATE_Configured) || (NRF_USBD_EP_NR_GET(ep_addr) == 0))
+ {
+ nrf_drv_usbd_ep_dtoggle_clear(ep_addr);
+ nrf_drv_usbd_ep_stall_clear(ep_addr);
+ return NRF_SUCCESS;
+ }
+ else
+ {
+ return NRF_ERROR_INVALID_STATE;
+ }
+ }
+ break;
+ }
+ default:
+ break;
+ }
+ return NRF_ERROR_NOT_SUPPORTED;
+}
+
+/**
+ * @brief Standard interface request handle
+ *
+ * @param[in,out] p_class_inst Class instance that holds selected interface
+ * @param[in] iface_idx Index of the interface in class structure
+ * @param[in] p_event Event structure to be processed
+ *
+ * @return Operation status
+ */
+static ret_code_t setup_interface_req_std_handle(
+ app_usbd_class_inst_t const * const p_class_inst,
+ uint8_t iface_idx,
+ app_usbd_setup_evt_t const * p_setup_ev)
+{
+ if (APP_USBD_SETUP_REQTYPE_STD != app_usbd_setup_req_typ(p_setup_ev->setup.bmRequestType))
+ {
+ return NRF_ERROR_NOT_SUPPORTED;
+ }
+
+ app_usbd_state_t usb_state = usbd_core_state_get();
+
+ if (app_usbd_setup_req_dir(p_setup_ev->setup.bmRequestType) == APP_USBD_SETUP_REQDIR_IN)
+ {
+ switch (p_setup_ev->setup.bmRequest)
+ {
+ case APP_USBD_SETUP_STDREQ_GET_STATUS:
+ {
+ if (!(usb_state == APP_USBD_STATE_Configured))
+ {
+ return NRF_ERROR_INVALID_STATE;
+ }
+ size_t tx_size;
+ uint16_t * p_tx_buff = app_usbd_core_setup_transfer_buff_get(&tx_size);
+ p_tx_buff[0] = 0;
+ return app_usbd_core_setup_rsp(&(p_setup_ev->setup), p_tx_buff, sizeof(uint16_t));
+ }
+ case APP_USBD_SETUP_STDREQ_GET_INTERFACE:
+ {
+ if (!(usb_state == APP_USBD_STATE_Configured))
+ {
+ return NRF_ERROR_INVALID_STATE;
+ }
+ size_t tx_size;
+ uint8_t * p_tx_buff = app_usbd_core_setup_transfer_buff_get(&tx_size);
+ p_tx_buff[0] = app_usbd_iface_selection_get(p_class_inst, iface_idx);
+ return app_usbd_core_setup_rsp(&(p_setup_ev->setup), p_tx_buff, sizeof(uint8_t));
+ }
+ }
+ }
+ else /* APP_USBD_SETUP_REQDIR_OUT */
+ {
+ switch (p_setup_ev->setup.bmRequest)
+ {
+ case APP_USBD_SETUP_STDREQ_SET_INTERFACE:
+ {
+ if (!(usb_state == APP_USBD_STATE_Configured))
+ {
+ return NRF_ERROR_INVALID_STATE;
+ }
+
+ if(p_setup_ev->setup.wValue.w > UINT8_MAX)
+ {
+ return NRF_ERROR_INVALID_PARAM;
+ }
+ uint8_t alt = p_setup_ev->setup.wValue.lb;
+ return app_usbd_iface_select(p_class_inst, iface_idx, alt);
+ }
+ default:
+ break;
+ }
+ }
+ return NRF_ERROR_NOT_SUPPORTED;
+}
+
+/**
+ * @brief
+ *
+ * @todo RK Documentation
+ */
+static const nrf_drv_usbd_handler_desc_t usbd_descriptor_feeder_desc =
+{
+ .handler = { .feeder = usbd_descriptor_conf_feeder },
+ .p_context = &m_descriptor_conf_feed_data
+};
+
+static ret_code_t setup_device_req_get_status(
+ app_usbd_class_inst_t const * const p_inst,
+ app_usbd_setup_evt_t const * const p_setup_ev)
+{
+ size_t max_size;
+ uint8_t * p_trans_buff = app_usbd_core_setup_transfer_buff_get(&max_size);
+ ASSERT(sizeof(uint16_t) <= max_size);
+
+ memset(p_trans_buff, 0, sizeof(uint16_t));
+ if (m_configuration_dsc.bmAttributes &
+ APP_USBD_DESCRIPTOR_CONFIGURATION_ATTRIBUTE_SELF_POWERED_MASK)
+ {
+ SET_BIT(p_trans_buff[0], 0);
+ }
+ if (IS_SET(m_device_features_state, APP_USBD_SETUP_STDFEATURE_DEVICE_REMOTE_WAKEUP))
+ {
+ SET_BIT(p_trans_buff[0], 1);
+ }
+ return app_usbd_core_setup_rsp(&(p_setup_ev->setup), p_trans_buff, sizeof(uint16_t));
+}
+
+static ret_code_t setup_device_req_get_descriptor(app_usbd_class_inst_t const * const p_inst,
+ app_usbd_setup_evt_t const * const p_setup_ev)
+{
+ switch (p_setup_ev->setup.wValue.hb)
+ {
+ case APP_USBD_DESCRIPTOR_DEVICE:
+ {
+ return app_usbd_core_setup_rsp(&(p_setup_ev->setup),
+ &m_device_dsc,
+ sizeof(m_device_dsc));
+ }
+ case APP_USBD_DESCRIPTOR_CONFIGURATION:
+ {
+ /* The size equals the size of configuration descriptor and all classes descriptors */
+ const size_t size = MIN(
+ sizeof(app_usbd_descriptor_configuration_t),
+ p_setup_ev->setup.wLength.w);
+ size_t total_length = sizeof(app_usbd_descriptor_configuration_t);
+ uint8_t iface_count = 0;
+
+ /* Iterate over all registered classes count descriptors and total size */
+ app_usbd_class_inst_t const * p_class;
+ for (p_class = app_usbd_class_first_get(); p_class != NULL;
+ p_class = app_usbd_class_next_get(p_class))
+ {
+ ASSERT(NULL != (p_class->p_class_methods));
+ ASSERT(NULL != (p_class->p_class_methods->feed_descriptors));
+ size_t dsc_size = 0;
+ app_usbd_class_descriptor_ctx_t siz_desc;
+ APP_USBD_CLASS_DESCRIPTOR_INIT(&siz_desc);
+ while(p_class->p_class_methods->feed_descriptors(&siz_desc,
+ p_class,
+ NULL,
+ sizeof(uint8_t))
+ )
+ {
+ dsc_size++;
+ }
+ total_length += dsc_size;
+ iface_count += app_usbd_class_iface_count_get(p_class);
+ }
+
+ /* Access transmission buffer */
+ size_t max_size;
+ app_usbd_descriptor_configuration_t * p_trans_buff =
+ app_usbd_core_setup_transfer_buff_get(&max_size);
+ /* Copy the configuration descriptor and update the fields that require it */
+ ASSERT(size <= max_size);
+ memcpy(p_trans_buff, &m_configuration_dsc, size);
+
+ p_trans_buff->bNumInterfaces = iface_count;
+ p_trans_buff->wTotalLength = total_length;
+ if (app_usbd_class_rwu_enabled_check())
+ {
+ p_trans_buff->bmAttributes |=
+ APP_USBD_DESCRIPTOR_CONFIGURATION_ATTRIBUTE_REMOTE_WAKEUP_MASK;
+ }
+
+
+ m_descriptor_conf_feed_data.p_cinst = app_usbd_class_first_get();
+ m_descriptor_conf_feed_data.p_desc = (void *)p_trans_buff;
+ m_descriptor_conf_feed_data.desc_left = size;
+ m_descriptor_conf_feed_data.total_left = p_setup_ev->setup.wLength.w;
+
+ /* Start first transfer */
+ ret_code_t ret;
+ CRITICAL_REGION_ENTER();
+
+ ret = app_usbd_ep_handled_transfer(
+ NRF_DRV_USBD_EPIN0,
+ &usbd_descriptor_feeder_desc);
+
+ if (NRF_SUCCESS == ret)
+ {
+ ret = app_usbd_core_setup_data_handler_set(
+ NRF_DRV_USBD_EPIN0,
+ &m_setup_data_handler_empty_desc);
+ }
+ CRITICAL_REGION_EXIT();
+
+ return ret;
+ }
+ case APP_USBD_DESCRIPTOR_STRING:
+ {
+ app_usbd_string_desc_idx_t id =
+ (app_usbd_string_desc_idx_t)(p_setup_ev->setup.wValue.lb);
+ uint16_t langid = p_setup_ev->setup.wIndex.w;
+ uint16_t const * p_string_dsc = app_usbd_string_desc_get(id, langid);
+ if (p_string_dsc == NULL)
+ {
+ return NRF_ERROR_NOT_SUPPORTED;
+ }
+
+ return app_usbd_core_setup_rsp(
+ &p_setup_ev->setup,
+ p_string_dsc,
+ app_usbd_string_desc_length(p_string_dsc));
+ }
+ default:
+ break;
+ }
+
+
+ return NRF_ERROR_NOT_SUPPORTED;
+}
+
+static ret_code_t setup_device_req_get_configuration(
+ app_usbd_class_inst_t const * const p_inst,
+ app_usbd_setup_evt_t const * const p_setup_ev)
+{
+ size_t max_size;
+ uint8_t * p_trans_buff = app_usbd_core_setup_transfer_buff_get(&max_size);
+ app_usbd_state_t usb_state = usbd_core_state_get();
+ if (usb_state == APP_USBD_STATE_Configured)
+ {
+ p_trans_buff[0] = 1;
+ }
+ else if (usb_state == APP_USBD_STATE_Addressed)
+ {
+ p_trans_buff[0] = 0;
+ }
+ else
+ {
+ return NRF_ERROR_NOT_SUPPORTED;
+ }
+
+ return app_usbd_core_setup_rsp(&p_setup_ev->setup, p_trans_buff, sizeof(p_trans_buff[0]));
+}
+
+static ret_code_t setup_device_req_set_configuration(
+ app_usbd_class_inst_t const * const p_inst,
+ app_usbd_setup_evt_t const * const p_setup_ev)
+{
+ app_usbd_state_t usb_state = usbd_core_state_get();
+ if (!((usb_state == APP_USBD_STATE_Configured) ||
+ (usb_state == APP_USBD_STATE_Addressed)))
+ {
+ return NRF_ERROR_INVALID_STATE;
+ }
+
+ if (p_setup_ev->setup.wValue.lb == 0)
+ {
+ app_usbd_all_iface_deselect();
+ usbd_core_state_set(APP_USBD_STATE_Addressed);
+ }
+ else if (p_setup_ev->setup.wValue.lb == 1)
+ {
+ /*Clear all bulk/interrupt endpoint status and set toggle to DATA0*/
+ app_usbd_all_iface_select_0();
+ usbd_core_state_set(APP_USBD_STATE_Configured);
+ }
+ else
+ {
+ /*In this driver only one configuration is supported.*/
+ return NRF_ERROR_INVALID_PARAM;
+ }
+
+ return NRF_SUCCESS;
+}
+
+/**
+ * @brief Internal SETUP event handler
+ * @param[in] p_inst Instance of the class
+ * @param[in] p_setup_ev Setup request
+ * @return Standard error code
+ * @retval NRF_SUCCESS if request handled correctly
+ * @retval NRF_ERROR_NOT_SUPPORTED if request is not supported
+ */
+static ret_code_t setup_device_req_std_handler(app_usbd_class_inst_t const * const p_inst,
+ app_usbd_setup_evt_t const * const p_setup_ev)
+{
+ ASSERT(p_inst != NULL);
+ ASSERT(p_setup_ev != NULL);
+
+ if (APP_USBD_SETUP_REQTYPE_STD != app_usbd_setup_req_typ(p_setup_ev->setup.bmRequestType))
+ {
+ return NRF_ERROR_NOT_SUPPORTED;
+ }
+
+ if (app_usbd_setup_req_dir(p_setup_ev->setup.bmRequestType) == APP_USBD_SETUP_REQDIR_IN)
+ {
+ switch (p_setup_ev->setup.bmRequest)
+ {
+ case APP_USBD_SETUP_STDREQ_GET_STATUS:
+ {
+ return setup_device_req_get_status(p_inst, p_setup_ev);
+ }
+ case APP_USBD_SETUP_STDREQ_GET_DESCRIPTOR:
+ {
+ return setup_device_req_get_descriptor(p_inst, p_setup_ev);
+ }
+ case APP_USBD_SETUP_STDREQ_GET_CONFIGURATION:
+ {
+ return setup_device_req_get_configuration(p_inst, p_setup_ev);
+ }
+ default:
+ /*Not supported*/
+ break;
+ }
+ return NRF_ERROR_NOT_SUPPORTED;
+ }
+ else /* APP_USBD_SETUP_REQDIR_OUT */
+ {
+ switch (p_setup_ev->setup.bmRequest)
+ {
+ case APP_USBD_SETUP_STDREQ_SET_ADDRESS:
+ {
+ app_usbd_state_t usb_state = usbd_core_state_get();
+ if ((usb_state != APP_USBD_STATE_Default) &&
+ (usb_state != APP_USBD_STATE_Addressed) &&
+ (usb_state != APP_USBD_STATE_Configured))
+ {
+ return NRF_ERROR_INVALID_STATE;
+ }
+ app_usbd_all_iface_deselect();
+ usbd_core_state_set(APP_USBD_STATE_Addressed);
+ return NRF_SUCCESS;
+ }
+ case APP_USBD_SETUP_STDREQ_SET_FEATURE:
+ {
+ if (p_setup_ev->setup.wValue.w == APP_USBD_SETUP_STDFEATURE_DEVICE_REMOTE_WAKEUP)
+ {
+ if (!app_usbd_class_rwu_enabled_check())
+ {
+ return NRF_ERROR_FORBIDDEN;
+ }
+ SET_BIT(m_device_features_state, APP_USBD_SETUP_STDFEATURE_DEVICE_REMOTE_WAKEUP);
+ return NRF_SUCCESS;
+ }
+ break;
+ }
+ case APP_USBD_SETUP_STDREQ_CLEAR_FEATURE:
+ {
+ if (p_setup_ev->setup.wValue.w == APP_USBD_SETUP_STDFEATURE_DEVICE_REMOTE_WAKEUP)
+ {
+ if (!app_usbd_class_rwu_enabled_check())
+ {
+ return NRF_ERROR_FORBIDDEN;
+ }
+ CLR_BIT(m_device_features_state, APP_USBD_SETUP_STDFEATURE_DEVICE_REMOTE_WAKEUP);
+ return NRF_SUCCESS;
+ }
+ break;
+ }
+ case APP_USBD_SETUP_STDREQ_SET_CONFIGURATION:
+ {
+ return setup_device_req_set_configuration(p_inst, p_setup_ev);
+ }
+ case APP_USBD_SETUP_STDREQ_SET_DESCRIPTOR:
+ {
+ /*Not supported yet.*/
+ break;
+ }
+ default:
+ /*Not supported*/
+ break;
+ }
+ return NRF_ERROR_NOT_SUPPORTED;
+ }
+}
+
+/**
+ * @brief Process SETUP command
+ *
+ * Auxiliary function for SETUP command processing
+ */
+static inline ret_code_t app_usbd_core_setup_req_handler(app_usbd_class_inst_t const * const p_inst)
+{
+ app_usbd_setup_evt_t setup_ev;
+ ret_code_t ret = NRF_ERROR_NOT_SUPPORTED; /* Final result of request processing function */
+
+ setup_ev.type = APP_USBD_EVT_DRV_SETUP;
+ nrf_drv_usbd_setup_get((nrf_drv_usbd_setup_t *)&(setup_ev.setup));
+
+ NRF_LOG_DEBUG("SETUP: t: 0x%.2x r: 0x%.2x",
+ setup_ev.setup.bmRequestType,
+ setup_ev.setup.bmRequest);
+ if (usb_core_ep0_handler_check())
+ {
+ NRF_LOG_WARNING("Previous setup not finished!");
+ }
+ /* Clear EP0 handler if there is anything in progress */
+ usbd_core_ep0_handler_clear();
+
+ switch (app_usbd_setup_req_rec(setup_ev.setup.bmRequestType))
+ {
+ case APP_USBD_SETUP_REQREC_DEVICE:
+ {
+ /* Endpoint 0 has core instance (that process device requests) connected */
+ ret = setup_device_req_std_handler(p_inst, &setup_ev);
+ if (ret == NRF_ERROR_NOT_SUPPORTED)
+ {
+ ret = app_usbd_all_until_served_call((app_usbd_complex_evt_t const *)&setup_ev);
+ }
+ break;
+ }
+ case APP_USBD_SETUP_REQREC_INTERFACE:
+ {
+ uint8_t const iface_number = setup_ev.setup.wIndex.lb;
+ uint8_t iface_idx;
+ app_usbd_class_inst_t const * p_inst_found = app_usbd_iface_find(
+ iface_number,
+ &iface_idx);
+ if (p_inst_found == NULL)
+ {
+ ret = NRF_ERROR_INVALID_ADDR;
+ }
+ else
+ {
+ ret = app_usbd_iface_call(
+ p_inst_found, iface_idx,
+ (app_usbd_complex_evt_t const *)&setup_ev);
+ if (ret == NRF_ERROR_NOT_SUPPORTED)
+ {
+ ret = setup_interface_req_std_handle(p_inst_found, iface_idx, &setup_ev);
+ }
+ }
+ break;
+ }
+ case APP_USBD_SETUP_REQREC_ENDPOINT:
+ {
+ ret = NRF_ERROR_NOT_SUPPORTED;
+ nrf_drv_usbd_ep_t ep = (nrf_drv_usbd_ep_t)setup_ev.setup.wIndex.lb;
+ if ((NRF_USBD_EP_NR_GET(ep) != 0)) /* For EP0 we would call this function again! */
+ {
+ ret = app_usbd_ep_call(ep, (app_usbd_complex_evt_t const *)&setup_ev);
+ }
+ if (ret == NRF_ERROR_NOT_SUPPORTED)
+ {
+ ret = setup_endpoint_req_std(&setup_ev);
+ }
+ break;
+ }
+ case APP_USBD_SETUP_REQREC_OTHER:
+ {
+ /* Try to process via every instance */
+ ret = app_usbd_all_until_served_call((app_usbd_complex_evt_t const *)&setup_ev);
+ break;
+ }
+ default:
+ break;
+ }
+
+ /* Processing result */
+ if (ret == NRF_SUCCESS)
+ {
+ if (usb_core_ep0_handler_check())
+ {
+ if (NRF_DRV_USBD_EPOUT0 == nrf_drv_usbd_last_setup_dir_get())
+ {
+ /* Request processed successfully and requires SETUP data */
+ nrf_drv_usbd_setup_data_clear();
+ }
+ }
+ else
+ {
+ /* Request processed successfully */
+ nrf_drv_usbd_setup_clear();
+ }
+ }
+ else
+ {
+ /* Request finished with error */
+ nrf_drv_usbd_setup_stall();
+ }
+ return ret;
+}
+
+/**
+ * @brief Event handler for core module
+ *
+ * The event handler that would process all events directed to device.
+ *
+ */
+static ret_code_t app_usbd_core_event_handler(app_usbd_class_inst_t const * const p_inst,
+ app_usbd_complex_evt_t const * const p_event)
+{
+ ret_code_t ret = NRF_ERROR_NOT_SUPPORTED;
+ switch (p_event->type)
+ {
+ case APP_USBD_EVT_DRV_RESET:
+ {
+ usbd_core_state_set(APP_USBD_STATE_Default);
+ break;
+ }
+ case APP_USBD_EVT_DRV_SUSPEND:
+ {
+ ret = NRF_SUCCESS;
+ break;
+ }
+ case APP_USBD_EVT_DRV_RESUME:
+ {
+ if (nrf_atomic_flag_clear_fetch(&m_rwu_pending) != 0)
+ {
+ nrf_usbd_task_trigger(NRF_USBD_TASK_NODRIVEDPDM);
+ }
+
+ ASSERT(usbd_core_state_get() >= APP_USBD_STATE_Unattached);
+ ret = NRF_SUCCESS;
+ break;
+ }
+ case APP_USBD_EVT_DRV_SETUP:
+ {
+ ret = app_usbd_core_setup_req_handler(p_inst);
+ break;
+ }
+ case APP_USBD_EVT_INST_APPEND:
+ {
+ ASSERT(usbd_core_state_get() == APP_USBD_STATE_Disabled);
+ ret = NRF_SUCCESS;
+ break;
+ }
+ case APP_USBD_EVT_INST_REMOVE:
+ {
+ ASSERT(usbd_core_state_get() == APP_USBD_STATE_Unattached);
+ usbd_core_state_set(APP_USBD_STATE_Disabled);
+ ret = NRF_SUCCESS;
+ break;
+ }
+ case APP_USBD_EVT_STARTED:
+ {
+ if (usbd_core_power_is_detected())
+ {
+ usbd_core_state_set(APP_USBD_STATE_Powered);
+ }
+ else
+ {
+ usbd_core_state_set(APP_USBD_STATE_Unattached);
+ }
+ ret = NRF_SUCCESS;
+ break;
+ }
+ case APP_USBD_EVT_STOPPED:
+ {
+ ASSERT(usbd_core_state_get() >= APP_USBD_STATE_Powered);
+ usbd_core_state_set(APP_USBD_STATE_Unattached);
+ ret = NRF_SUCCESS;
+ break;
+ }
+ /* Data transfer on endpoint 0 */
+ case APP_USBD_EVT_DRV_EPTRANSFER:
+ {
+ if (p_event->drv_evt.data.eptransfer.status == NRF_USBD_EP_ABORTED)
+ {
+ /* Just ignore aborting */
+ break;
+ }
+ /* This EPTRANSFER event has to be called only for EP0 */
+ ASSERT((p_event->drv_evt.data.eptransfer.ep == NRF_DRV_USBD_EPOUT0) ||
+ (p_event->drv_evt.data.eptransfer.ep == NRF_DRV_USBD_EPIN0));
+ ret = usbd_core_ep0_handler_call_and_clear(p_event->drv_evt.data.eptransfer.status);
+ /* Processing result */
+ if (ret == NRF_SUCCESS)
+ {
+ if (usb_core_ep0_handler_check())
+ {
+ if (p_event->drv_evt.data.eptransfer.ep == NRF_DRV_USBD_EPOUT0)
+ {
+ /* Request processed successfully and requires SETUP data */
+ nrf_drv_usbd_setup_data_clear();
+ }
+ }
+ else
+ {
+ if (!nrf_drv_usbd_errata_154())
+ {
+ nrf_drv_usbd_setup_clear();
+ }
+ }
+ }
+ else
+ {
+ /* Request finished with error */
+ nrf_drv_usbd_setup_stall();
+ }
+ break;
+ }
+ default:
+ break;
+ }
+
+ return ret;
+}
+
+/** @} */
+
+ret_code_t app_usbd_core_setup_rsp(app_usbd_setup_t const * p_setup,
+ void const * p_data,
+ size_t size)
+{
+ size_t req_size = p_setup->wLength.w;
+ size_t tx_size = MIN(req_size, size);
+ bool zlp_required = (size < req_size) &&
+ (0 == (size % nrf_drv_usbd_ep_max_packet_size_get(NRF_DRV_USBD_EPIN0)));
+
+ NRF_DRV_USBD_TRANSFER_IN_FLAGS(
+ transfer,
+ p_data,
+ tx_size,
+ zlp_required ? NRF_DRV_USBD_TRANSFER_ZLP_FLAG : 0);
+
+ ret_code_t ret;
+ CRITICAL_REGION_ENTER();
+ ret = app_usbd_ep_transfer(NRF_DRV_USBD_EPIN0, &transfer);
+ if (NRF_SUCCESS == ret)
+ {
+ ret = app_usbd_core_setup_data_handler_set(NRF_DRV_USBD_EPIN0,
+ &m_setup_data_handler_empty_desc);
+ }
+ CRITICAL_REGION_EXIT();
+
+ return ret;
+}
+
+ret_code_t app_usbd_core_setup_data_handler_set(
+ nrf_drv_usbd_ep_t ep,
+ app_usbd_core_setup_data_handler_desc_t const * const p_handler_desc)
+{
+ if (nrf_drv_usbd_last_setup_dir_get() != ep)
+ {
+ return NRF_ERROR_INVALID_ADDR;
+ }
+
+ m_ep0_handler_desc = *p_handler_desc;
+ return NRF_SUCCESS;
+}
+
+void * app_usbd_core_setup_transfer_buff_get(size_t * p_size)
+{
+ if (p_size != NULL)
+ *p_size = sizeof(m_setup_transfer_buff);
+
+ return m_setup_transfer_buff;
+}
+
+app_usbd_state_t app_usbd_core_state_get(void)
+{
+ return usbd_core_state_get();
+}
+
+
+bool app_usbd_core_feature_state_get(app_usbd_setup_stdfeature_t feature)
+{
+ return IS_SET(m_device_features_state, feature) ? true : false;
+}
+
+#endif //NRF_MODULE_ENABLED(APP_USBD)
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/usbd/app_usbd_core.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/usbd/app_usbd_core.h
new file mode 100644
index 0000000..7c6c12e
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/usbd/app_usbd_core.h
@@ -0,0 +1,206 @@
+/**
+ * Copyright (c) 2016 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+
+#ifndef APP_USBD_CORE_H__
+#define APP_USBD_CORE_H__
+
+#include <stdint.h>
+
+#include "sdk_common.h"
+#include "nrf_drv_usbd.h"
+#include "app_usbd_types.h"
+#include "app_usbd_class_base.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+/**
+ * @defgroup app_usbd_core USB Device high level library core module
+ * @ingroup app_usbd
+ *
+ * @brief @tagAPI52840 Core module that manages current USB state and process device requests.
+ * @{
+ */
+
+/**
+ * @brief Core interface configuration
+ *
+ * Core instance would have 2 endpoints (IN0 and OUT0).
+ * The interface number does not matter because it is not used.
+ */
+#define APP_USBD_CORE_CLASS_CONFIGURATION ((0, NRF_DRV_USBD_EPOUT0, NRF_DRV_USBD_EPIN0))
+
+/**
+ * @brief USB Device state
+ *
+ * Possible USB Device states according to specification.
+ */
+typedef enum
+{
+ APP_USBD_STATE_Disabled , /**< The whole USBD library is disabled */
+ APP_USBD_STATE_Unattached, /**< Device is currently not connected to the host */
+ APP_USBD_STATE_Powered , /**< Device is connected to the host but has not been enumerated */
+ APP_USBD_STATE_Default , /**< USB Reset condition detected, waiting for the address */
+ APP_USBD_STATE_Addressed , /**< Device has been addressed but has not been configured */
+ APP_USBD_STATE_Configured, /**< Device is addressed and configured */
+}app_usbd_state_t;
+
+/**
+ * @brief EP0 handler function pointer
+ *
+ * Type of the variable that would hold the pointer to the handler for
+ * endpoint 0 messages processing.
+ *
+ * @param p_contex Context variable configured with the transmission request.
+ */
+typedef ret_code_t (*app_usbd_core_setup_data_handler_t)(nrf_drv_usbd_ep_status_t status,
+ void * p_context);
+
+/**
+ * @brief Variable type used to register EP0 transfer handler
+ *
+ * EP0 messages are processed by core instance.
+ * Another class can register itself to receive messages from EP0 when requesting
+ * for Setup data transfer.
+ */
+typedef struct
+{
+ app_usbd_core_setup_data_handler_t handler; //!< Event handler to be called when transmission is ready
+ void * p_context; //!< Context pointer to be send to every called event.
+} app_usbd_core_setup_data_handler_desc_t;
+
+/*lint -save -e10 -e26 -e93 -e123 -e505 */
+/**
+ * @brief Declare Core instance type
+ *
+ * USBD core instance type definition.
+ */
+APP_USBD_CLASS_TYPEDEF(app_usbd_core,
+ APP_USBD_CORE_CLASS_CONFIGURATION,
+ APP_USBD_CLASS_INSTANCE_SPECIFIC_DEC_NONE,
+ APP_USBD_CLASS_DATA_SPECIFIC_DEC_NONE);
+/*lint -restore*/
+
+/**
+ * @brief Access to core instance
+ *
+ * Function that returns pointer to the USBD core instance.
+ *
+ * @return pointer to the core instance
+ */
+static inline app_usbd_class_inst_t const * app_usbd_core_instance_access(void)
+{
+ extern const APP_USBD_CLASS_INSTANCE_TYPE(app_usbd_core) app_usbd_core_inst;
+ return (app_usbd_class_inst_t const *)&app_usbd_core_inst;
+}
+
+/**
+ * @brief Default simple response to setup command
+ *
+ * This function generates default simple response.
+ * It sends ZLP when required and on takes care on allowing status stage when
+ * transfer is finished.
+ *
+ * @param p_setup Pointer to original setup message
+ * @param p_data Pointer to the response. This has to be globaly aviable data.
+ * @param size Total size of the answer - The function takes care about
+ * limiting the size of transfered data to the size required
+ * by setup command.
+ */
+ret_code_t app_usbd_core_setup_rsp(app_usbd_setup_t const * p_setup,
+ void const * p_data,
+ size_t size);
+
+/**
+ * @brief Configure the handler for the nearest setup data endpoint transfer
+ *
+ * This function would be called on incomming setup data.
+ * The correct place to set the handler for a data is when SETUP command
+ * was received.
+ *
+ * @param ep Endpoint number (only IN0 and OUT0) are supported.
+ * @param p_handler_desc Descriptor of the handler to be called.
+ *
+ * @retval NRF_SUCCESS Successfully configured
+ * @retval NRF_ERROR_INVALID_ADDR Last received setup direction does not match
+ * configured endpoint.
+ */
+ret_code_t app_usbd_core_setup_data_handler_set(
+ nrf_drv_usbd_ep_t ep,
+ app_usbd_core_setup_data_handler_desc_t const * const p_handler_desc);
+
+/**
+ * @brief Set up a data transfer buffer.
+ *
+ * Returns special internal buffer that can be used in setup transfer.
+ * @return Internal buffer pointer
+ */
+void * app_usbd_core_setup_transfer_buff_get(size_t * p_size);
+
+
+/**@brief Return internal USBD core state
+ *
+ * @return Check @ref app_usbd_state_t to find possible USBD core states
+ */
+app_usbd_state_t app_usbd_core_state_get(void);
+
+
+/**
+ * @brief Check current feature state
+ *
+ * Function checks the state of the selected feature that was configured by the host.
+ *
+ * @param feature Feature to check.
+ * Only features related to the device should be checked by this function.
+ *
+ * @retval true Selected feature is set
+ * @retval false Selected feature is cleared
+ */
+bool app_usbd_core_feature_state_get(app_usbd_setup_stdfeature_t feature);
+
+/** @} */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* APP_USBD_CORE_H__ */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/usbd/app_usbd_descriptor.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/usbd/app_usbd_descriptor.h
new file mode 100644
index 0000000..4d3dded
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/usbd/app_usbd_descriptor.h
@@ -0,0 +1,337 @@
+/**
+ * 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+
+#ifndef APP_USBD_DESCRIPTOR_H__
+#define APP_USBD_DESCRIPTOR_H__
+
+#include "nrf.h"
+#include "nrf_drv_usbd.h"
+#include "app_usbd_langid.h"
+#include "app_util_platform.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Compiler support for anonymous unions */
+ANON_UNIONS_ENABLE;
+
+/**
+ * @defgroup app_usbd_descriptor USB standard descriptors
+ * @ingroup app_usbd
+ *
+ * @brief @tagAPI52840 Module with types definitions used for standard descriptors.
+ * @{
+ */
+
+/**
+ * @brief Helper macro for translating unsigned 24 bit value to 2 byte raw descriptor
+ * */
+#define APP_USBD_U16_TO_RAW_DSC(val) (uint8_t)(val), \
+ (uint8_t)(((val) / (256)))
+
+/**
+ * @brief Helper macro for translating unsigned 24 bit value to 3 byte raw descriptor
+ * */
+#define APP_USBD_U24_TO_RAW_DSC(val) (uint8_t)(val), \
+ (uint8_t)(((val) / (256))), \
+ (uint8_t)(((val) / (256 * 256)))
+
+/**
+ * @brief Helper macro for translating unsigned 32 bit value to 4 byte raw descriptor
+ * */
+#define APP_USBD_U32_TO_RAW_DSC(val) (uint8_t)(val), \
+ (uint8_t)(((val) / (256))), \
+ (uint8_t)(((val) / (256 * 256))) \
+ (uint8_t)(((val) / (256 * 256 * 256)))
+/**
+ * @brief Descriptor types
+ *
+ * Descriptor types used in two situations:
+ * - when processing @ref APP_USBD_SETUP_STDREQ_GET_DESCRIPTOR SETUP request,
+ * the required descriptor type may be placed in wValue in HighByte.
+ * - As a descriptor identifier itself inside descriptor stream.
+ *
+ * According to chapter 9.6 of USB 2.0 specification, following descriptors may
+ * be requested directly by GetDescriptor method:
+ * - @ref APP_USBD_DESCRIPTOR_DEVICE
+ * - @ref APP_USBD_DESCRIPTOR_DEVICE_QUALIFIER (not used for FullSpeed only device)
+ * - @ref APP_USBD_DESCRIPTOR_CONFIGURATION
+ * - @ref APP_USBD_DESCRIPTOR_STRING
+ */
+typedef enum
+{
+ APP_USBD_DESCRIPTOR_DEVICE = 1, /**< Device descriptor. */
+ APP_USBD_DESCRIPTOR_CONFIGURATION = 2, /**<
+ * Specific configuration descriptor.
+ * Configuration descriptor is always followed by all the related interface
+ * and endpoints descriptors.
+ */
+ APP_USBD_DESCRIPTOR_STRING = 3, /**< String descriptor. */
+ APP_USBD_DESCRIPTOR_INTERFACE = 4, /**<
+ * Interface descriptor followed by all the related endpoints descriptors.
+ *
+ * @note It is returned together with @ref APP_USBD_DESCRIPTOR_CONFIGURATION.
+ * Cannot be accessed by GetDescriptor or SetDescriptor
+ */
+ APP_USBD_DESCRIPTOR_ENDPOINT = 5, /**<
+ * Endpoint descriptor.
+ *
+ * @note It is returned together with @ref APP_USBD_DESCRIPTOR_CONFIGURATION.
+ * Cannot be accessed by GetDescriptor or SetDescriptor
+ */
+ APP_USBD_DESCRIPTOR_DEVICE_QUALIFIER = 6, /**< @note Not supported - used only in HighSpeed capable devices. */
+ APP_USBD_DESCRIPTOR_OTHER_SPEED_CONFIGURATION = 7, /**< @note Not supported - our USB implementation supports only one speed. */
+ APP_USBD_DESCRIPTOR_INTERFACE_POWER = 8, /**< @note Not supported */
+ APP_USBD_DESCRIPTOR_OTG = 9, /**< @note Not supported - Our USB have not OTG functionality */
+ APP_USBD_DESCRIPTOR_DEBUG = 10, /**< Debug channel descriptor if available, can be only reached by GetDescriptor */
+ APP_USBD_DESCRIPTOR_INTERFACE_ASSOCIATION = 11, /**<
+ * Descriptor used to describe that two or more interfaces are associated to the same function.
+ *
+ * @note It is returned together with @ref APP_USBD_DESCRIPTOR_CONFIGURATION.
+ * Cannot be accessed by GetDescriptor or SetDescriptor
+ */
+ APP_USBD_DESCRIPTOR_REPORT = 34, /**< HID Report descriptor. */
+ APP_USBD_DESCRIPTOR_PHYSICAL = 35 /**< HID Physical descriptor. */
+
+} app_usbd_descriptor_t;
+
+/* Make all descriptors packed */
+#pragma pack(push, 1)
+
+/**
+ * @brief Common descriptor header
+ *
+ * The header that we can find on the beginning of all descriptors that contains
+ * the descriptor length and type.
+ */
+typedef struct
+{
+ uint8_t bLength; //!< Size of the descriptor in bytes.
+ uint8_t bDescriptorType; //!< Should equal one of @ref app_usbd_descriptor_t.
+ /** Class specific descriptors values are defined inside classes. */
+} app_usbd_descriptor_header_t;
+
+/**
+ * @brief Device descriptor
+ *
+ * Descriptor used for the whole device
+ */
+typedef struct
+{
+ uint8_t bLength; //!< Size of the descriptor in bytes.
+ uint8_t bDescriptorType; //!< Should equal to @ref APP_USBD_DESCRIPTOR_DEVICE.
+ uint16_t bcdUSB; //!< USB Specification Release Number in Binary-Coded Decimal
+ uint8_t bDeviceClass; //!< Device class code.
+ /**< If 0, each interface specifies its own class information.
+ * 0xFF for vendor-specific.
+ */
+ uint8_t bDeviceSubClass; //!< Subclass code.
+ /**< If bDevice Class is set to value other than 0xFF,
+ * all values here are reserved for assignment by USB-IF.
+ */
+ uint8_t bDeviceProtocol; //!< Subclass code.
+ /**< If 0, no specific protocol is defined on device basis.
+ * Each interface may define its own protocol then.
+ * If set to 0xFF, vendor-specific protocol is used.
+ */
+ uint8_t bMaxPacketSize0; //!< Maximum packet size for endpoint zero.
+ uint16_t idVendor; //!< Vendor ID (Assigned by the USB-IF).
+ uint16_t idProduct; //!< Product ID (assigned by manufacturer).
+ uint16_t bcdDevice; //!< Device release number in binary-coded decimal.
+ uint8_t iManufacturer; //!< Index of string descriptor in describing manufacturer.
+ uint8_t iProduct; //!< Index of string descriptor in describing product.
+ uint8_t iSerialNumber; //!< Index of string descriptor in describing the device's serial number.
+ uint8_t bNumConfigurations; //!< Number of possible configurations.
+} app_usbd_descriptor_device_t;
+
+/**
+ * @brief Attributes masks
+ *
+ * Masks used for attributes in configuration.
+ */
+typedef enum
+{
+ /** This is reserved descriptor that has always to be set */
+ APP_USBD_DESCRIPTOR_CONFIGURATION_ATTRIBUTE_ALWAYS_SET_MASK = 1U << 7,
+ /** Attribute that informs that device is self powered */
+ APP_USBD_DESCRIPTOR_CONFIGURATION_ATTRIBUTE_SELF_POWERED_MASK = 1U << 6,
+ /** Attribute that informs that device has Remove Wakeup functionality */
+ APP_USBD_DESCRIPTOR_CONFIGURATION_ATTRIBUTE_REMOTE_WAKEUP_MASK = 1U << 5
+} app_usbd_descriptor_configuration_attributes_t;
+
+/**
+ * @brief Configuration descriptor
+ *
+ * Descriptor used at the beginning of configuration response.
+ */
+typedef struct
+{
+ uint8_t bLength; //!< Size of the descriptor in bytes.
+ uint8_t bDescriptorType; //!< Should equal to @ref APP_USBD_DESCRIPTOR_DEVICE.
+ uint16_t wTotalLength; //!< Total length of configuration data, including all descriptors returned after configuration itself.
+ uint8_t bNumInterfaces; //!< Number of interfaces supportedf by this configuration
+ uint8_t bConfigurationValue; //!< Value to use as an argument to the SetConfiguration request.
+ uint8_t iConfiguration; //!< Index of string descriptor describing this configuration.
+ uint8_t bmAttributes; //!< Configuration characteristics.
+ uint8_t bMaxPower; //!< Maximum power consumption. Expressed in 2&nbsp;mA units.
+} app_usbd_descriptor_configuration_t;
+
+/**
+ * @brief Raw descriptor - String descriptor zero
+ *
+ * String descriptor sent only as a response for GetDescriptor.
+ */
+typedef struct
+{
+ uint8_t bLength; //!< Size of the descriptor in bytes.
+ uint8_t bDescriptorType; //!< Should equal to @ref APP_USBD_DESCRIPTOR_STRING.
+ uint16_t wLANGID[]; //!< The array of LANGID codes supported by the device.
+} app_usbd_descriptor_string0_t;
+
+/**
+ * @brief Raw descriptor - Any normal string
+ *
+ * String descriptor sent only as a response for GetDescriptor.
+ */
+typedef struct
+{
+ uint8_t bLength; //!< Size of the descriptor in bytes.
+ uint8_t bDescriptorType; //!< Should equal to @ref APP_USBD_DESCRIPTOR_STRING.
+ uint16_t bString[]; //!< UNICODE encoded string.
+} app_usbd_descriptor_string_t;
+
+
+/**
+ * @brief Interface descriptor
+ *
+ * Interface descriptor, returned as a part of configuration descriptor.
+ */
+typedef struct
+{
+ uint8_t bLength; //!< Size of the descriptor in bytes.
+ uint8_t bDescriptorType; //!< Should equal to @ref APP_USBD_DESCRIPTOR_INTERFACE.
+ uint8_t bInterfaceNumber; //!< Number of this interface.
+ uint8_t bAlternateSetting; //!< Value used to select this alternate setting.
+ uint8_t bNumEndpoints; //!< Number of endpoints used by this interface.
+ uint8_t bInterfaceClass; //!< Class code (assigned by the USB-IF). 0xff for vendor specific.
+ uint8_t bInterfaceSubClass; //!< Subclass code (assigned by the USB-IF).
+ uint8_t bInterfaceProtocol; //!< Protocol code (assigned by the USB-IF). 0xff for vendor specific.
+ uint8_t iInterface; //!< Index of string descriptor describing this interface.
+} app_usbd_descriptor_iface_t;
+
+/** Offset of endpoint type attribute bits */
+#define APP_USBD_DESCRIPTOR_EP_ATTR_TYPE_OFFSET 0
+/** Mask of endpoint type attribute bits */
+#define APP_USBD_DESCRIPTOR_EP_ATTR_TYPE_MASK BF_MASK(2, APP_USBD_DESCRIPTOR_EP_ATTR_TYPE_OFFSET)
+
+/** Offset of endpoint synchronization type attribute bits */
+#define APP_USBD_DESCRIPTOR_EP_ATTR_SYNC_OFFSET 2
+/** Mask of endpoint synchronization type attribute bits */
+#define APP_USBD_DESCRIPTOR_EP_ATTR_SYNC_MASK BF_MASK(2, APP_USBD_DESCRIPTOR_EP_ATTR_SYNC_OFFSET)
+
+/** Offset of endpoint usage type attribute bits */
+#define APP_USBD_DESCRIPTOR_EP_ATTR_USAGE_OFFSET 4
+/** Mask of endpoint usage type attribute bits */
+#define APP_USBD_DESCRIPTOR_EP_ATTR_USAGE_MASK BF_MASK(2, APP_USBD_DESCRIPTOR_EP_ATTR_USAGE_OFFSET)
+
+/**
+ * @brief Endpoint attributes mnemonics
+ *
+ * @sa APP_USBD_DESCRIPTOR_EP_ATTR_TYPE_OFFSET APP_USBD_DESCRIPTOR_EP_ATTR_TYPE_MASK
+ * @sa APP_USBD_DESCRIPTOR_EP_ATTR_SYNC_OFFSET APP_USBD_DESCRIPTOR_EP_ATTR_SYNC_MASK
+ * @sa APP_USBD_DESCRIPTOR_EP_ATTR_USAGE_OFFSET APP_USBD_DESCRIPTOR_EP_ATTR_USAGE_MASK
+ */
+typedef enum
+{
+ APP_USBD_DESCRIPTOR_EP_ATTR_TYPE_CONTROL = 0 << APP_USBD_DESCRIPTOR_EP_ATTR_TYPE_OFFSET,
+ APP_USBD_DESCRIPTOR_EP_ATTR_TYPE_ISOCHRONOUS = 1 << APP_USBD_DESCRIPTOR_EP_ATTR_TYPE_OFFSET,
+ APP_USBD_DESCRIPTOR_EP_ATTR_TYPE_BULK = 2 << APP_USBD_DESCRIPTOR_EP_ATTR_TYPE_OFFSET,
+ APP_USBD_DESCRIPTOR_EP_ATTR_TYPE_INTERRUPT = 3 << APP_USBD_DESCRIPTOR_EP_ATTR_TYPE_OFFSET,
+
+ APP_USBD_DESCRIPTOR_EP_ATTR_SYNC_NONE = 0 << APP_USBD_DESCRIPTOR_EP_ATTR_SYNC_OFFSET,
+ APP_USBD_DESCRIPTOR_EP_ATTR_SYNC_ASYNCHRONOUS = 1 << APP_USBD_DESCRIPTOR_EP_ATTR_SYNC_OFFSET,
+ APP_USBD_DESCRIPTOR_EP_ATTR_SYNC_ADAPTIVE = 2 << APP_USBD_DESCRIPTOR_EP_ATTR_SYNC_OFFSET,
+ APP_USBD_DESCRIPTOR_EP_ATTR_SYNC_SYNCHRONOUS = 3 << APP_USBD_DESCRIPTOR_EP_ATTR_SYNC_OFFSET,
+
+ APP_USBD_DESCRIPTOR_EP_ATTR_USAGE_DATA = 0 << APP_USBD_DESCRIPTOR_EP_ATTR_USAGE_OFFSET,
+ APP_USBD_DESCRIPTOR_EP_ATTR_USAGE_FEEDBACK = 1 << APP_USBD_DESCRIPTOR_EP_ATTR_USAGE_OFFSET,
+ APP_USBD_DESCRIPTOR_EP_ATTR_USAGE_IMPLICIT = 2 << APP_USBD_DESCRIPTOR_EP_ATTR_USAGE_OFFSET
+} app_usbd_descriptor_ep_attr_bitmap_t;
+
+/**
+ * @brief Endpoint descriptor
+ *
+ * Endpoint descriptor, returned as a part of configuration descriptor.
+ */
+typedef struct
+{
+ uint8_t bLength; //!< Size of the descriptor in bytes.
+ uint8_t bDescriptorType; //!< Should equal to @ref APP_USBD_DESCRIPTOR_ENDPOINT.
+ uint8_t bEndpointAddress; //!< Endpoint address
+ uint8_t bmAttributes; //!< Endpoint attributes
+ uint16_t wMaxPacketSize; //!< Maximum packet size this endpoint is capable of handling.
+ uint8_t bInterval; //!< Interval for pooling endpoint for data transfers.
+} app_usbd_descriptor_ep_t;
+
+/**
+ * @brief Interface association descriptor
+ */
+typedef struct
+{
+ uint8_t bLength; //!< size of this descriptor in bytes
+ uint8_t bDescriptorType; //!< INTERFACE descriptor type
+ uint8_t bFirstInterface; //!< Number of interface
+ uint8_t bInterfaceCount; //!< value to select alternate setting
+ uint8_t bFunctionClass; //!< Class code assigned by the USB
+ uint8_t bFunctionSubClass;//!< Sub-class code assigned by the USB
+ uint8_t bFunctionProtocol;//!< Protocol code assigned by the USB
+ uint8_t iFunction; //!< Index of string descriptor
+} app_usbd_descriptor_iad_t;
+
+#pragma pack(pop)
+ANON_UNIONS_DISABLE;
+
+#ifdef __cplusplus
+}
+#endif
+
+/** @} */
+#endif /* APP_USBD_DESCRIPTOR_H__ */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/usbd/app_usbd_langid.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/usbd/app_usbd_langid.h
new file mode 100644
index 0000000..0d08f14
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/usbd/app_usbd_langid.h
@@ -0,0 +1,286 @@
+/**
+ * Copyright (c) 2016 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+
+#ifndef APP_USBD_LANGID_H__
+#define APP_USBD_LANGID_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @file
+ * @brief This file contains LANGID variable type with all defined values
+ *
+ * This file was created using Language Identifiers (LANGIDs) 3/29/00 Version 1.0,
+ * available on USB web page:
+ * http://www.usb.org/developers/docs/USB_LANGIDs.pdf
+ *
+ * @note
+ * Do not include this file directly to the project.
+ * It is included by @file app_usbd_request.h.
+ */
+
+/**
+ * Offset of the lowest bit of primary language identifier
+ * @sa app_usbd_langid_t
+ */
+#define APP_USB_LANG_OFFSET 0
+
+/**
+ * Bitmask for a primary language identifier
+ * @sa app_usbd_langid_t
+ */
+#define APP_USB_LANG_MASK BF_MASK(10, APP_USB_LANG_OFFSET)
+
+/**
+ * Offset of the lowest bit of sub-language identifier
+ * @sa app_usbd_langid_t
+ */
+#define APP_USB_SUBLANG_OFFSET 10
+
+/**
+ * Bitmask for a sub-language identifier
+ * @sa app_usbd_langid_t
+ */
+#define APP_USB_SUBLANG_MASK BF_MASK(6, APP_USB_SUBLANG_OFFSET)
+
+/**
+ * @brief Primary language identifiers
+ *
+ * Mnemonics for primary language identifiers.
+ * This mnemonics can be combined using logical OR operator with @ref app_usbd_langid_sub_t.
+ */
+typedef enum
+{
+ APP_USBD_LANG_ARABIC = 0x01U << ( APP_USB_LANG_OFFSET ), /**< Arabic */
+ APP_USBD_LANG_BULGARIAN = 0x02U << ( APP_USB_LANG_OFFSET ), /**< Bulgarian */
+ APP_USBD_LANG_CATALAN = 0x03U << ( APP_USB_LANG_OFFSET ), /**< Catalan */
+ APP_USBD_LANG_CHINESE = 0x04U << ( APP_USB_LANG_OFFSET ), /**< Chinese */
+ APP_USBD_LANG_CZECH = 0x05U << ( APP_USB_LANG_OFFSET ), /**< Czech */
+ APP_USBD_LANG_DANISH = 0x06U << ( APP_USB_LANG_OFFSET ), /**< Danish */
+ APP_USBD_LANG_GERMAN = 0x07U << ( APP_USB_LANG_OFFSET ), /**< German */
+ APP_USBD_LANG_GREEK = 0x08U << ( APP_USB_LANG_OFFSET ), /**< Greek */
+ APP_USBD_LANG_ENGLISH = 0x09U << ( APP_USB_LANG_OFFSET ), /**< English */
+ APP_USBD_LANG_SPANISH = 0x0aU << ( APP_USB_LANG_OFFSET ), /**< Spanish */
+ APP_USBD_LANG_FINNISH = 0x0bU << ( APP_USB_LANG_OFFSET ), /**< Finnish */
+ APP_USBD_LANG_FRENCH = 0x0cU << ( APP_USB_LANG_OFFSET ), /**< French */
+ APP_USBD_LANG_HEBREW = 0x0dU << ( APP_USB_LANG_OFFSET ), /**< Hebrew */
+ APP_USBD_LANG_HUNGARIAN = 0x0eU << ( APP_USB_LANG_OFFSET ), /**< Hungarian */
+ APP_USBD_LANG_ICELANDIC = 0x0fU << ( APP_USB_LANG_OFFSET ), /**< Icelandic */
+ APP_USBD_LANG_ITALIAN = 0x10U << ( APP_USB_LANG_OFFSET ), /**< Italian */
+ APP_USBD_LANG_JAPANESE = 0x11U << ( APP_USB_LANG_OFFSET ), /**< Japanese */
+ APP_USBD_LANG_KOREAN = 0x12U << ( APP_USB_LANG_OFFSET ), /**< Korean */
+ APP_USBD_LANG_DUTCH = 0x13U << ( APP_USB_LANG_OFFSET ), /**< Dutch */
+ APP_USBD_LANG_NORWEGIAN = 0x14U << ( APP_USB_LANG_OFFSET ), /**< Norwegian */
+ APP_USBD_LANG_POLISH = 0x15U << ( APP_USB_LANG_OFFSET ), /**< Polish */
+ APP_USBD_LANG_PORTUGUESE = 0x16U << ( APP_USB_LANG_OFFSET ), /**< Portuguese */
+ APP_USBD_LANG_ROMANIAN = 0x18U << ( APP_USB_LANG_OFFSET ), /**< Romanian */
+ APP_USBD_LANG_RUSSIAN = 0x19U << ( APP_USB_LANG_OFFSET ), /**< Russian */
+ APP_USBD_LANG_CROATIAN = 0x1aU << ( APP_USB_LANG_OFFSET ), /**< Croatian */
+ APP_USBD_LANG_SERBIAN = 0x1aU << ( APP_USB_LANG_OFFSET ), /**< Serbian */
+ APP_USBD_LANG_SLOVAK = 0x1bU << ( APP_USB_LANG_OFFSET ), /**< Slovak */
+ APP_USBD_LANG_ALBANIAN = 0x1cU << ( APP_USB_LANG_OFFSET ), /**< Albanian */
+ APP_USBD_LANG_SWEDISH = 0x1dU << ( APP_USB_LANG_OFFSET ), /**< Swedish */
+ APP_USBD_LANG_THAI = 0x1eU << ( APP_USB_LANG_OFFSET ), /**< Thai */
+ APP_USBD_LANG_TURKISH = 0x1fU << ( APP_USB_LANG_OFFSET ), /**< Turkish */
+ APP_USBD_LANG_URDU = 0x20U << ( APP_USB_LANG_OFFSET ), /**< Urdu */
+ APP_USBD_LANG_INDONESIAN = 0x21U << ( APP_USB_LANG_OFFSET ), /**< Indonesian */
+ APP_USBD_LANG_UKRANIAN = 0x22U << ( APP_USB_LANG_OFFSET ), /**< Ukrainian */
+ APP_USBD_LANG_BELARUSIAN = 0x23U << ( APP_USB_LANG_OFFSET ), /**< Belarusian */
+ APP_USBD_LANG_SLOVENIAN = 0x24U << ( APP_USB_LANG_OFFSET ), /**< Slovenian */
+ APP_USBD_LANG_ESTONIAN = 0x25U << ( APP_USB_LANG_OFFSET ), /**< Estonian */
+ APP_USBD_LANG_LATVIAN = 0x26U << ( APP_USB_LANG_OFFSET ), /**< Latvian */
+ APP_USBD_LANG_LITHUANIAN = 0x27U << ( APP_USB_LANG_OFFSET ), /**< Lithuanian */
+ APP_USBD_LANG_FARSI = 0x29U << ( APP_USB_LANG_OFFSET ), /**< Farsi */
+ APP_USBD_LANG_VIETNAMESE = 0x2aU << ( APP_USB_LANG_OFFSET ), /**< Vietnamese */
+ APP_USBD_LANG_ARMENIAN = 0x2bU << ( APP_USB_LANG_OFFSET ), /**< Armenian */
+ APP_USBD_LANG_AZERI = 0x2cU << ( APP_USB_LANG_OFFSET ), /**< Azeri */
+ APP_USBD_LANG_BASQUE = 0x2dU << ( APP_USB_LANG_OFFSET ), /**< Basque */
+ APP_USBD_LANG_MACEDONIAN = 0x2fU << ( APP_USB_LANG_OFFSET ), /**< Macedonian */
+ APP_USBD_LANG_AFRIKAANS = 0x36U << ( APP_USB_LANG_OFFSET ), /**< Afrikaans */
+ APP_USBD_LANG_GEORGIAN = 0x37U << ( APP_USB_LANG_OFFSET ), /**< Georgian */
+ APP_USBD_LANG_FAEROESE = 0x38U << ( APP_USB_LANG_OFFSET ), /**< Faeroese */
+ APP_USBD_LANG_HINDI = 0x39U << ( APP_USB_LANG_OFFSET ), /**< Hindi */
+ APP_USBD_LANG_MALAY = 0x3eU << ( APP_USB_LANG_OFFSET ), /**< Malay */
+ APP_USBD_LANG_KAZAK = 0x3fU << ( APP_USB_LANG_OFFSET ), /**< Kazak */
+ APP_USBD_LANG_SWAHILI = 0x41U << ( APP_USB_LANG_OFFSET ), /**< Swahili */
+ APP_USBD_LANG_UZBEK = 0x43U << ( APP_USB_LANG_OFFSET ), /**< Uzbek */
+ APP_USBD_LANG_TATAR = 0x44U << ( APP_USB_LANG_OFFSET ), /**< Tatar */
+ APP_USBD_LANG_BENGALI = 0x45U << ( APP_USB_LANG_OFFSET ), /**< Bengali */
+ APP_USBD_LANG_PUNJABI = 0x46U << ( APP_USB_LANG_OFFSET ), /**< Punjabi */
+ APP_USBD_LANG_GUJARATI = 0x47U << ( APP_USB_LANG_OFFSET ), /**< Gujarati */
+ APP_USBD_LANG_ORIYA = 0x48U << ( APP_USB_LANG_OFFSET ), /**< Oriya */
+ APP_USBD_LANG_TAMIL = 0x49U << ( APP_USB_LANG_OFFSET ), /**< Tamil */
+ APP_USBD_LANG_TELUGU = 0x4aU << ( APP_USB_LANG_OFFSET ), /**< Telugu */
+ APP_USBD_LANG_KANNADA = 0x4bU << ( APP_USB_LANG_OFFSET ), /**< Kannada */
+ APP_USBD_LANG_MALAYALAM = 0x4cU << ( APP_USB_LANG_OFFSET ), /**< Malayalam */
+ APP_USBD_LANG_ASSAMESE = 0x4dU << ( APP_USB_LANG_OFFSET ), /**< Assamese */
+ APP_USBD_LANG_MARATHI = 0x4eU << ( APP_USB_LANG_OFFSET ), /**< Marathi */
+ APP_USBD_LANG_SANSKRIT = 0x4fU << ( APP_USB_LANG_OFFSET ), /**< Sanskrit */
+ APP_USBD_LANG_KONKANI = 0x57U << ( APP_USB_LANG_OFFSET ), /**< Konkani */
+ APP_USBD_LANG_MANIPURI = 0x58U << ( APP_USB_LANG_OFFSET ), /**< Manipuri */
+ APP_USBD_LANG_SINDHI = 0x59U << ( APP_USB_LANG_OFFSET ), /**< Sindhi */
+ APP_USBD_LANG_KASHMIRI = 0x60U << ( APP_USB_LANG_OFFSET ), /**< Kashmiri */
+ APP_USBD_LANG_NEPALI = 0x61U << ( APP_USB_LANG_OFFSET ), /**< Nepali */
+ APP_USBD_LANG_HID = 0xffU << ( APP_USB_LANG_OFFSET ), /**< Reserved for USB HID Class use */
+}app_usbd_langid_primary_t;
+
+/**
+ * @brief Sublanguage identifiers
+ *
+ * Mnemonics with sublanguage values.
+ * Use them in combination with @ref app_usbd_langid_primary_t.
+ */
+typedef enum
+{
+ APP_USBD_SUBLANG_ARABIC_SAUDI_ARABIA = 0x01U << ( APP_USB_LANG_OFFSET ), /**< Arabic (Saudi Arabia) */
+ APP_USBD_SUBLANG_ARABIC_IRAQ = 0x02U << ( APP_USB_LANG_OFFSET ), /**< Arabic (Iraq) */
+ APP_USBD_SUBLANG_ARABIC_EGYPT = 0x03U << ( APP_USB_LANG_OFFSET ), /**< Arabic (Egypt) */
+ APP_USBD_SUBLANG_ARABIC_LIBYA = 0x04U << ( APP_USB_LANG_OFFSET ), /**< Arabic (Libya) */
+ APP_USBD_SUBLANG_ARABIC_ALGERIA = 0x05U << ( APP_USB_LANG_OFFSET ), /**< Arabic (Algeria) */
+ APP_USBD_SUBLANG_ARABIC_MOROCCO = 0x06U << ( APP_USB_LANG_OFFSET ), /**< Arabic (Morocco) */
+ APP_USBD_SUBLANG_ARABIC_TUNISIA = 0x07U << ( APP_USB_LANG_OFFSET ), /**< Arabic (Tunisia) */
+ APP_USBD_SUBLANG_ARABIC_OMAN = 0x08U << ( APP_USB_LANG_OFFSET ), /**< Arabic (Oman) */
+ APP_USBD_SUBLANG_ARABIC_YEMEN = 0x09U << ( APP_USB_LANG_OFFSET ), /**< Arabic (Yemen) */
+ APP_USBD_SUBLANG_ARABIC_SYRIA = 0x10U << ( APP_USB_LANG_OFFSET ), /**< Arabic (Syria) */
+ APP_USBD_SUBLANG_ARABIC_JORDAN = 0x11U << ( APP_USB_LANG_OFFSET ), /**< Arabic (Jordan) */
+ APP_USBD_SUBLANG_ARABIC_LEBANON = 0x12U << ( APP_USB_LANG_OFFSET ), /**< Arabic (Lebanon) */
+ APP_USBD_SUBLANG_ARABIC_KUWAIT = 0x13U << ( APP_USB_LANG_OFFSET ), /**< Arabic (Kuwait) */
+ APP_USBD_SUBLANG_ARABIC_UAE = 0x14U << ( APP_USB_LANG_OFFSET ), /**< Arabic (U.A.E.) */
+ APP_USBD_SUBLANG_ARABIC_BAHRAIN = 0x15U << ( APP_USB_LANG_OFFSET ), /**< Arabic (Bahrain) */
+ APP_USBD_SUBLANG_ARABIC_QATAR = 0x16U << ( APP_USB_LANG_OFFSET ), /**< Arabic (Qatar) */
+ APP_USBD_SUBLANG_AZERI_CYRILLIC = 0x01U << ( APP_USB_LANG_OFFSET ), /**< Azeri (Cyrillic) */
+ APP_USBD_SUBLANG_AZERI_LATIN = 0x02U << ( APP_USB_LANG_OFFSET ), /**< Azeri (Latin) */
+ APP_USBD_SUBLANG_CHINESE_TRADITIONAL = 0x01U << ( APP_USB_LANG_OFFSET ), /**< Chinese (Traditional) */
+ APP_USBD_SUBLANG_CHINESE_SIMPLIFIED = 0x02U << ( APP_USB_LANG_OFFSET ), /**< Chinese (Simplified) */
+ APP_USBD_SUBLANG_CHINESE_HONGKONG = 0x03U << ( APP_USB_LANG_OFFSET ), /**< Chinese (Hong Kong SAR, PRC) */
+ APP_USBD_SUBLANG_CHINESE_SINGAPORE = 0x04U << ( APP_USB_LANG_OFFSET ), /**< Chinese (Singapore) */
+ APP_USBD_SUBLANG_CHINESE_MACAU = 0x05U << ( APP_USB_LANG_OFFSET ), /**< Chinese (Macau SAR) */
+ APP_USBD_SUBLANG_DUTCH = 0x01U << ( APP_USB_LANG_OFFSET ), /**< Dutch */
+ APP_USBD_SUBLANG_DUTCH_BELGIAN = 0x02U << ( APP_USB_LANG_OFFSET ), /**< Dutch (Belgian) */
+ APP_USBD_SUBLANG_ENGLISH_US = 0x01U << ( APP_USB_LANG_OFFSET ), /**< English (US) */
+ APP_USBD_SUBLANG_ENGLISH_UK = 0x02U << ( APP_USB_LANG_OFFSET ), /**< English (UK) */
+ APP_USBD_SUBLANG_ENGLISH_AUS = 0x03U << ( APP_USB_LANG_OFFSET ), /**< English (Australian) */
+ APP_USBD_SUBLANG_ENGLISH_CAN = 0x04U << ( APP_USB_LANG_OFFSET ), /**< English (Canadian) */
+ APP_USBD_SUBLANG_ENGLISH_NZ = 0x05U << ( APP_USB_LANG_OFFSET ), /**< English (New Zealand) */
+ APP_USBD_SUBLANG_ENGLISH_EIRE = 0x06U << ( APP_USB_LANG_OFFSET ), /**< English (Ireland) */
+ APP_USBD_SUBLANG_ENGLISH_SOUTH_AFRICA = 0x07U << ( APP_USB_LANG_OFFSET ), /**< English (South Africa) */
+ APP_USBD_SUBLANG_ENGLISH_JAMAICA = 0x08U << ( APP_USB_LANG_OFFSET ), /**< English (Jamaica) */
+ APP_USBD_SUBLANG_ENGLISH_CARIBBEAN = 0x09U << ( APP_USB_LANG_OFFSET ), /**< English (Caribbean) */
+ APP_USBD_SUBLANG_ENGLISH_BELIZE = 0x0aU << ( APP_USB_LANG_OFFSET ), /**< English (Belize) */
+ APP_USBD_SUBLANG_ENGLISH_TRINIDAD = 0x0bU << ( APP_USB_LANG_OFFSET ), /**< English (Trinidad) */
+ APP_USBD_SUBLANG_ENGLISH_PHILIPPINES = 0x0cU << ( APP_USB_LANG_OFFSET ), /**< English (Zimbabwe) */
+ APP_USBD_SUBLANG_ENGLISH_ZIMBABWE = 0x0dU << ( APP_USB_LANG_OFFSET ), /**< English (Philippines) */
+ APP_USBD_SUBLANG_FRENCH = 0x01U << ( APP_USB_LANG_OFFSET ), /**< French */
+ APP_USBD_SUBLANG_FRENCH_BELGIAN = 0x02U << ( APP_USB_LANG_OFFSET ), /**< French (Belgian) */
+ APP_USBD_SUBLANG_FRENCH_CANADIAN = 0x03U << ( APP_USB_LANG_OFFSET ), /**< French (Canadian) */
+ APP_USBD_SUBLANG_FRENCH_SWISS = 0x04U << ( APP_USB_LANG_OFFSET ), /**< French (Swiss) */
+ APP_USBD_SUBLANG_FRENCH_LUXEMBOURG = 0x05U << ( APP_USB_LANG_OFFSET ), /**< French (Luxembourg) */
+ APP_USBD_SUBLANG_FRENCH_MONACO = 0x06U << ( APP_USB_LANG_OFFSET ), /**< French (Monaco) */
+ APP_USBD_SUBLANG_GERMAN = 0x01U << ( APP_USB_LANG_OFFSET ), /**< German */
+ APP_USBD_SUBLANG_GERMAN_SWISS = 0x02U << ( APP_USB_LANG_OFFSET ), /**< German (Swiss) */
+ APP_USBD_SUBLANG_GERMAN_AUSTRIAN = 0x03U << ( APP_USB_LANG_OFFSET ), /**< German (Austrian) */
+ APP_USBD_SUBLANG_GERMAN_LUXEMBOURG = 0x04U << ( APP_USB_LANG_OFFSET ), /**< German (Luxembourg) */
+ APP_USBD_SUBLANG_GERMAN_LIECHTENSTEIN = 0x05U << ( APP_USB_LANG_OFFSET ), /**< German (Liechtenstein) */
+ APP_USBD_SUBLANG_ITALIAN = 0x01U << ( APP_USB_LANG_OFFSET ), /**< Italian */
+ APP_USBD_SUBLANG_ITALIAN_SWISS = 0x02U << ( APP_USB_LANG_OFFSET ), /**< Italian (Swiss) */
+ APP_USBD_SUBLANG_KASHMIRI_INDIA = 0x02U << ( APP_USB_LANG_OFFSET ), /**< Kashmiri (India) */
+ APP_USBD_SUBLANG_KOREAN = 0x01U << ( APP_USB_LANG_OFFSET ), /**< Korean */
+ APP_USBD_SUBLANG_LITHUANIAN = 0x01U << ( APP_USB_LANG_OFFSET ), /**< Lithuanian */
+ APP_USBD_SUBLANG_MALAY_MALAYSIA = 0x01U << ( APP_USB_LANG_OFFSET ), /**< Malay (Malaysia) */
+ APP_USBD_SUBLANG_MALAY_BRUNEI_DARUSSALAM = 0x02U << ( APP_USB_LANG_OFFSET ), /**< Malay (Brunei Darassalam) */
+ APP_USBD_SUBLANG_NEPALI_INDIA = 0x02U << ( APP_USB_LANG_OFFSET ), /**< Nepali (India) */
+ APP_USBD_SUBLANG_NORWEGIAN_BOKMAL = 0x01U << ( APP_USB_LANG_OFFSET ), /**< Norwegian (Bokmal) */
+ APP_USBD_SUBLANG_NORWEGIAN_NYNORSK = 0x02U << ( APP_USB_LANG_OFFSET ), /**< Norwegian (Nynorsk) */
+ APP_USBD_SUBLANG_PORTUGUESE = 0x01U << ( APP_USB_LANG_OFFSET ), /**< Portuguese (Brazilian) */
+ APP_USBD_SUBLANG_PORTUGUESE_BRAZILIAN = 0x02U << ( APP_USB_LANG_OFFSET ), /**< Portuguese */
+ APP_USBD_SUBLANG_SERBIAN_LATIN = 0x02U << ( APP_USB_LANG_OFFSET ), /**< Serbian (Latin) */
+ APP_USBD_SUBLANG_SERBIAN_CYRILLIC = 0x03U << ( APP_USB_LANG_OFFSET ), /**< Serbian (Cyrillic) */
+ APP_USBD_SUBLANG_SPANISH = 0x01U << ( APP_USB_LANG_OFFSET ), /**< Spanish (Castilian) */
+ APP_USBD_SUBLANG_SPANISH_MEXICAN = 0x02U << ( APP_USB_LANG_OFFSET ), /**< Spanish (Mexican) */
+ APP_USBD_SUBLANG_SPANISH_MODERN = 0x03U << ( APP_USB_LANG_OFFSET ), /**< Spanish (Modern) */
+ APP_USBD_SUBLANG_SPANISH_GUATEMALA = 0x04U << ( APP_USB_LANG_OFFSET ), /**< Spanish (Guatemala) */
+ APP_USBD_SUBLANG_SPANISH_COSTA_RICA = 0x05U << ( APP_USB_LANG_OFFSET ), /**< Spanish (Costa Rica) */
+ APP_USBD_SUBLANG_SPANISH_PANAMA = 0x06U << ( APP_USB_LANG_OFFSET ), /**< Spanish (Panama) */
+ APP_USBD_SUBLANG_SPANISH_DOMINICAN_REPUBLIC = 0x07U << ( APP_USB_LANG_OFFSET ), /**< Spanish (Dominican Republic) */
+ APP_USBD_SUBLANG_SPANISH_VENEZUELA = 0x08U << ( APP_USB_LANG_OFFSET ), /**< Spanish (Venezuela) */
+ APP_USBD_SUBLANG_SPANISH_COLOMBIA = 0x09U << ( APP_USB_LANG_OFFSET ), /**< Spanish (Colombia) */
+ APP_USBD_SUBLANG_SPANISH_PERU = 0x0aU << ( APP_USB_LANG_OFFSET ), /**< Spanish (Peru) */
+ APP_USBD_SUBLANG_SPANISH_ARGENTINA = 0x0bU << ( APP_USB_LANG_OFFSET ), /**< Spanish (Argentina) */
+ APP_USBD_SUBLANG_SPANISH_ECUADOR = 0x0cU << ( APP_USB_LANG_OFFSET ), /**< Spanish (Ecuador) */
+ APP_USBD_SUBLANG_SPANISH_CHILE = 0x0dU << ( APP_USB_LANG_OFFSET ), /**< Spanish (Chile) */
+ APP_USBD_SUBLANG_SPANISH_URUGUAY = 0x0eU << ( APP_USB_LANG_OFFSET ), /**< Spanish (Uruguay) */
+ APP_USBD_SUBLANG_SPANISH_PARAGUAY = 0x0fU << ( APP_USB_LANG_OFFSET ), /**< Spanish (Paraguay) */
+ APP_USBD_SUBLANG_SPANISH_BOLIVIA = 0x10U << ( APP_USB_LANG_OFFSET ), /**< Spanish (Bolivia) */
+ APP_USBD_SUBLANG_SPANISH_EL_SALVADOR = 0x11U << ( APP_USB_LANG_OFFSET ), /**< Spanish (El Salvador) */
+ APP_USBD_SUBLANG_SPANISH_HONDURAS = 0x12U << ( APP_USB_LANG_OFFSET ), /**< Spanish (Honduras) */
+ APP_USBD_SUBLANG_SPANISH_NICARAGUA = 0x13U << ( APP_USB_LANG_OFFSET ), /**< Spanish (Nicaragua) */
+ APP_USBD_SUBLANG_SPANISH_PUERTO_RICO = 0x14U << ( APP_USB_LANG_OFFSET ), /**< Spanish (Puerto Rico) */
+ APP_USBD_SUBLANG_SWEDISH = 0x01U << ( APP_USB_LANG_OFFSET ), /**< Swedish */
+ APP_USBD_SUBLANG_SWEDISH_FINLAND = 0x02U << ( APP_USB_LANG_OFFSET ), /**< Swedish (Finland) */
+ APP_USBD_SUBLANG_URDU_PAKISTAN = 0x01U << ( APP_USB_LANG_OFFSET ), /**< Urdu (Pakistan) */
+ APP_USBD_SUBLANG_URDU_INDIA = 0x02U << ( APP_USB_LANG_OFFSET ), /**< Urdu (India) */
+ APP_USBD_SUBLANG_UZBEK_LATIN = 0x01U << ( APP_USB_LANG_OFFSET ), /**< Uzbek (Latin) */
+ APP_USBD_SUBLANG_UZBEK_CYRILLIC = 0x02U << ( APP_USB_LANG_OFFSET ), /**< Uzbek (Cyrillic) */
+ APP_USBD_SUBLANG_HID_USAGE_DATA_DESCRIPTOR = 0x01U << ( APP_USB_LANG_OFFSET ), /**< HID (Usage Data Descriptor) */
+ APP_USBD_SUBLANG_HID_VENDOR_DEFINED_1 = 0x3cU << ( APP_USB_LANG_OFFSET ), /**< HID (Vendor Defined 1) */
+ APP_USBD_SUBLANG_HID_VENDOR_DEFINED_2 = 0x3dU << ( APP_USB_LANG_OFFSET ), /**< HID (Vendor Defined 2) */
+ APP_USBD_SUBLANG_HID_VENDOR_DEFINED_3 = 0x3eU << ( APP_USB_LANG_OFFSET ), /**< HID (Vendor Defined 3) */
+ APP_USBD_SUBLANG_HID_VENDOR_DEFINED_4 = 0x3fU << ( APP_USB_LANG_OFFSET ), /**< HID (Vendor Defined 4) */
+}app_usbd_langid_sub_t;
+
+/**
+ * @brief LANGID variable
+ *
+ * The LANGID value is composed from:
+ * - 10-bit (9-0) of Primary Language Identifiers
+ * - 6-bit (15-10) of Sublanguage Identifiers.
+ *
+ * @sa app_usbd_langid_primary_t
+ * @sa app_usbd_langid_sub_t
+ */
+typedef uint16_t app_usbd_langid_t;
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* APP_USBD_LANGID_H__ */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/usbd/app_usbd_request.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/usbd/app_usbd_request.h
new file mode 100644
index 0000000..d2f6f14
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/usbd/app_usbd_request.h
@@ -0,0 +1,356 @@
+/**
+ * Copyright (c) 2016 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+
+#ifndef APP_USBD_REQUEST_H__
+#define APP_USBD_REQUEST_H__
+
+#include "sdk_common.h"
+#include "nrf.h"
+#include "nrf_drv_usbd.h"
+#include "app_usbd_descriptor.h"
+#include "app_util_platform.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Compiler support for anonymous unions */
+ANON_UNIONS_ENABLE;
+
+#pragma pack(push, 1)
+
+/**
+ * @defgroup app_usbd_request USB standard requests
+ * @ingroup app_usbd
+ *
+ * @brief @tagAPI52840 Module with types definitions used for standard requests processing.
+ * @{
+ */
+
+/**
+ * @brief Recipient bit-field in request type
+ *
+ * Bits 4...0
+ */
+#define APP_USBD_SETUP_REQ_BF_REC BF_CX(5, 0)
+
+/**
+ * @brief Type bit-field in request type
+ *
+ * Bits 6...5
+ */
+#define APP_USBD_SETUP_REQ_BF_TYP BF_CX(2, 5)
+
+/**
+ * @brief Direction bit-field in request type
+ *
+ * Bit 7
+ */
+#define APP_USBD_SETUP_REQ_BF_DIR BF_CX(1, 7)
+
+/**
+ * @brief Recipient enumerator.
+ *
+ * @note It is part of @ref app_usbd_setup_reqtype_t variable type.
+ */
+typedef enum {
+ APP_USBD_SETUP_REQREC_DEVICE = 0x0, /**< The whole device is a request target */
+ APP_USBD_SETUP_REQREC_INTERFACE = 0x1, /**< Selected interface is a request target */
+ APP_USBD_SETUP_REQREC_ENDPOINT = 0x2, /**< Selected endpoint is a request target */
+ APP_USBD_SETUP_REQREC_OTHER = 0x3 /**< Other element is a request target */
+} app_usbd_setup_reqrec_t;
+
+/**
+ * @brief Request type enumerator.
+ *
+ * @note It is part of @ref app_usbd_setup_reqtype_t variable type.
+ */
+typedef enum {
+ APP_USBD_SETUP_REQTYPE_STD = 0x0, /**< Standard request */
+ APP_USBD_SETUP_REQTYPE_CLASS = 0x1, /**< Class specific request */
+ APP_USBD_SETUP_REQTYPE_VENDOR = 0x2 /**< Vendor specific request */
+} app_usbd_setup_reqtype_t;
+
+/**
+ * @brief Direction of setup command
+ *
+ * @note It is part of @ref app_usbd_setup_reqtype_t variable type.
+ */
+typedef enum {
+ APP_USBD_SETUP_REQDIR_OUT = 0x0, /**< Host to device */
+ APP_USBD_SETUP_REQDIR_IN = 0x1, /**< Device to host */
+} app_usbd_setup_reqdir_t;
+
+
+/**
+ * @brief Standard requests
+ *
+ * Enumerator for standard requests values
+ */
+typedef enum {
+ APP_USBD_SETUP_STDREQ_GET_STATUS = 0x00, /**<
+ * Targets: Device, Interface, Endpoint
+ * Expected SETUP frame format:
+ * - wValue: Zero
+ * - wIndex: Zero, (lb): Interface or Endpoint
+ * - wLength: 2
+ * - Data:2 bytes of data, depending on targets
+ * - Device:
+ * - D15..D2: Reserved (Reset to zero)
+ * - D1: Remove Wakeup
+ * - D0: Self Powered
+ * - Interface:
+ * - D15..D0: Reserved (Reset to zero)
+ * - Endpoint:
+ * - D15..D1: Reserved (Reset to zero)
+ * - D0: Halt
+ */
+ APP_USBD_SETUP_STDREQ_CLEAR_FEATURE = 0x01, /**<
+ * Targets: Device, Interface, Endpoint
+ * Expected SETUP frame format:
+ * - wValue: Feature selector (@ref app_usbd_setup_stdfeature_t)
+ * - wIndex: Zero, Interface or Endpoint
+ * - wLength: 0
+ * - Data: None
+ */
+ APP_USBD_SETUP_STDREQ_SET_FEATURE = 0x03, /**<
+ * Targets: Device, Interface, Endpoint
+ * Expected SETUP frame format:
+ * - wValue: Feature selector (@ref app_usbd_setup_stdfeature_t)
+ * - wIndex: Zero, Interface or Endpoint
+ * - wLength: 0
+ * - Data: None
+ */
+ APP_USBD_SETUP_STDREQ_SET_ADDRESS = 0x05, /**<
+ * @note This SETUP request is processed in hardware.
+ * Use it only to mark current USB state.
+ *
+ * Targets: Device
+ * Expected SETUP frame format:
+ * - wValue: New device address
+ * - wIndex: 0
+ * - wLength: 0
+ * - Data: None
+ */
+ APP_USBD_SETUP_STDREQ_GET_DESCRIPTOR = 0x06, /**<
+ * Targets: Device
+ * - wValue: (hb): Descriptor Type and (lb): Descriptor Index
+ * - wIndex: Zero of Language ID
+ * - wLength: Descriptor Length
+ * - Data: Descriptor
+ */
+ APP_USBD_SETUP_STDREQ_SET_DESCRIPTOR = 0x07, /**<
+ * Not supported - Stall when called.
+ */
+ APP_USBD_SETUP_STDREQ_GET_CONFIGURATION = 0x08, /**<
+ * Target: Device
+ * Expected SETUP frame format:
+ * - wValue: 0
+ * - wIndex: 0
+ * - wLength: 1
+ * - Data: Configuration value
+ */
+ APP_USBD_SETUP_STDREQ_SET_CONFIGURATION = 0x09, /**<
+ * Target: Device
+ * Expected SETUP frame format:
+ * - wValue: (lb): Configuration value
+ * - wIndex: 0
+ * - wLength: 0
+ * - Data: None
+ */
+ APP_USBD_SETUP_STDREQ_GET_INTERFACE = 0x0A, /**<
+ * Target: Interface
+ * Expected SETUP frame format:
+ * - wValue: 0
+ * - wIndex: Interface
+ * - wLength: 1
+ * - Data: Alternate setting
+ */
+ APP_USBD_SETUP_STDREQ_SET_INTERFACE = 0x0B, /**<
+ * Target: Interface
+ * Expected SETUP frame format:
+ * - wValue: Alternate setting
+ * - wIndex: Interface
+ * - wLength: 0
+ * - Data: None
+ */
+ APP_USBD_SETUP_STDREQ_SYNCH_FRAME = 0x0C /**<
+ * Target: Endpoint
+ * Expected SETUP frame format:
+ * - wValue: 0
+ * - wIndex: Endpoint
+ * - wLength: 2
+ * - Data: Frame Number
+ *
+ * @note
+ * This request is used only in connection with isochronous endpoints.
+ * This is rarely used and probably we would not need to support it.
+ */
+} app_usbd_setup_stdrequest_t;
+
+/**
+ * @brief Standard feature selectors
+ *
+ * Standard features that may be disabled or enabled by
+ * @ref APP_USBD_SETUP_STDREQ_CLEAR_FEATURE or @ref APP_USBD_SETUP_STDREQ_SET_FEATURE
+ */
+typedef enum {
+ APP_USBD_SETUP_STDFEATURE_DEVICE_REMOTE_WAKEUP = 1, /**<
+ * Remote wakeup feature.
+ * Target: Device only
+ */
+ APP_USBD_SETUP_STDFEATURE_ENDPOINT_HALT = 0, /**<
+ * Stall or clear the endpoint.
+ * Target: Endpoint different than default (0)
+ */
+ APP_USBD_SETUP_STDFEATURE_TEST_MODE = 2 /**<
+ * Upstream port test mode.
+ * Power has to be cycled to exit test mode.
+ * This feature cannot be cleared.
+ *
+ * Target: Device only
+ *
+ * @note
+ * It should only be supported by HighSpeed capable devices.
+ * Not supported in this library.
+ */
+} app_usbd_setup_stdfeature_t;
+
+
+/**
+ * @brief Universal way to access 16 bit values and its parts
+ */
+typedef union {
+ uint16_t w; //!< 16 bit access
+ struct
+ {
+ uint8_t lb; //!< Low byte access
+ uint8_t hb; //!< High byte access
+ };
+} app_usbd_setup_w_t;
+
+/**
+ * @brief Internal redefinition of setup structure
+ *
+ * Redefinition of the structure to simplify changes in the future
+ * if required - app_usbd API would present setup data using app_usbd_setup_t.
+ *
+ * The structure layout is always the same like @ref nrf_drv_usbd_setup_t
+ */
+typedef struct {
+ uint8_t bmRequestType; //!< Setup type bitfield
+ uint8_t bmRequest; //!< One of @ref app_usbd_setup_stdrequest_t values or class dependent one.
+ app_usbd_setup_w_t wValue; //!< byte 2, 3
+ app_usbd_setup_w_t wIndex; //!< byte 4, 5
+ app_usbd_setup_w_t wLength; //!< byte 6, 7
+} app_usbd_setup_t;
+
+#pragma pack(pop)
+
+
+/**
+ * @brief Extract recipient from request type
+ *
+ * @param[in] bmRequestType
+ *
+ * @return Extracted recipient field from request type value
+ */
+static inline app_usbd_setup_reqrec_t app_usbd_setup_req_rec(uint8_t bmRequestType)
+{
+ return (app_usbd_setup_reqrec_t)BF_CX_GET(bmRequestType, APP_USBD_SETUP_REQ_BF_REC);
+}
+
+/**
+ * @brief Extract type from request type
+ *
+ * @param[in] bmRequestType
+ *
+ * @return Extracted type field from request type value
+ */
+static inline app_usbd_setup_reqtype_t app_usbd_setup_req_typ(uint8_t bmRequestType)
+{
+ return (app_usbd_setup_reqtype_t)BF_CX_GET(bmRequestType, APP_USBD_SETUP_REQ_BF_TYP);
+}
+
+
+/**
+ * @brief Extract direction from request type
+ *
+ * @param[in] bmRequestType
+ *
+ * @return Extracted direction field from request type value
+ */
+static inline app_usbd_setup_reqdir_t app_usbd_setup_req_dir(uint8_t bmRequestType)
+{
+ return (app_usbd_setup_reqdir_t)BF_CX_GET(bmRequestType, APP_USBD_SETUP_REQ_BF_DIR);
+}
+
+/**
+ * @brief Make request type value
+ *
+ * @param[in] rec Recipient
+ * @param[in] typ Request type
+ * @param[in] dir Direction
+ *
+ * @return Assembled request type value
+ */
+static inline uint8_t app_usbd_setup_req_val(app_usbd_setup_reqrec_t rec,
+ app_usbd_setup_reqtype_t typ,
+ app_usbd_setup_reqdir_t dir)
+{
+ uint32_t bmRequestType = (
+ BF_CX_VAL(rec, APP_USBD_SETUP_REQ_BF_REC) |
+ BF_CX_VAL(typ, APP_USBD_SETUP_REQ_BF_TYP) |
+ BF_CX_VAL(dir, APP_USBD_SETUP_REQ_BF_DIR)
+ );
+
+ ASSERT(bmRequestType < 256U);
+ return (uint8_t)bmRequestType;
+}
+
+
+ANON_UNIONS_DISABLE;
+/** @} */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* APP_USBD_REQUEST_H__ */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/usbd/app_usbd_serial_num.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/usbd/app_usbd_serial_num.c
new file mode 100644
index 0000000..bec2f4e
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/usbd/app_usbd_serial_num.c
@@ -0,0 +1,87 @@
+/**
+ * Copyright (c) 2018 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#include "app_usbd_serial_num.h"
+
+#include <stdint.h>
+#include <stdio.h>
+#include <string.h>
+#include <inttypes.h>
+#include "app_usbd.h"
+
+#define SERIAL_NUMBER_STRING_SIZE (12)
+
+/**@brief Serial number generated
+ *
+ * Serial number generated by the @ref serial_number_string_create function
+ */
+uint16_t g_extern_serial_number[SERIAL_NUMBER_STRING_SIZE + 1];
+
+
+/**@brief Function for creating the serial number string from a regular C string.
+ *
+ * @param[in] p_serial_number_string The serial number string. Must be terminated with \0.
+ */
+static void string_create(char * p_serial_number_string)
+{
+ g_extern_serial_number[0] =
+ (uint16_t)APP_USBD_DESCRIPTOR_STRING << 8 | sizeof(g_extern_serial_number);
+
+ for (uint32_t i = 0; i < strlen(p_serial_number_string); i++)
+ {
+ g_extern_serial_number[i + 1] = (uint8_t)p_serial_number_string[i];
+ }
+}
+
+
+void app_usbd_serial_num_generate(void)
+{
+ char serial_number_string[SERIAL_NUMBER_STRING_SIZE + 1];
+ const uint16_t serial_num_high_bytes = (uint16_t)NRF_FICR->DEVICEADDR[1] | 0xC000; // The masking makes the address match the Random Static BLE address.
+ const uint32_t serial_num_low_bytes = NRF_FICR->DEVICEADDR[0];
+
+ (void)snprintf(serial_number_string,
+ SERIAL_NUMBER_STRING_SIZE + 1,
+ "%04"PRIX16"%08"PRIX32,
+ serial_num_high_bytes,
+ serial_num_low_bytes);
+
+ string_create(serial_number_string);
+}
+
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/usbd/app_usbd_serial_num.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/usbd/app_usbd_serial_num.h
new file mode 100644
index 0000000..ca0957c
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/usbd/app_usbd_serial_num.h
@@ -0,0 +1,75 @@
+/**
+ * Copyright (c) 2018 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+
+#ifndef APP_USBD_SERIAL_NUM_H__
+#define APP_USBD_SERIAL_NUM_H__
+
+#include <stdint.h>
+#include <stdio.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @defgroup app_usbd_serial_num USBD serial number generator
+ * @ingroup app_usbd
+ *
+ * @brief @tagAPI52840 Generate a standard USB serial number that is unique for each device.
+ * @{
+ */
+
+/**@brief Function for generating a default serial number string based on FIRC->DEVICEADDR.
+ *
+ * After calling this function, the serial number is ready for the USB driver.
+ *
+ * The generated serial number shows up as a 12-hexidecimal-digit string with no delimiters
+ * (e.g 123456ABCDEF). The byte string is also printed on the PCA10059 dongle. It is also used as
+ * the default advertising address in the SoftDevice.
+ */
+void app_usbd_serial_num_generate(void);
+
+/** @} */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // APP_USBD_SERIAL_NUM_H__
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/usbd/app_usbd_string_desc.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/usbd/app_usbd_string_desc.c
new file mode 100644
index 0000000..0893b45
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/usbd/app_usbd_string_desc.c
@@ -0,0 +1,188 @@
+/**
+ * Copyright (c) 2016 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#include "sdk_config.h"
+#if APP_USBD_ENABLED
+#include "app_usbd_string_desc.h"
+#include "app_usbd_langid.h"
+#include "app_usbd_core.h"
+#include "nordic_common.h"
+
+/**
+ * @defgroup app_usbd_string_desc
+ * @ingroup app_usbd
+ *
+ * USBD string descriptors management
+ * @{
+ */
+
+/**
+ * @brief Array with language identifiers
+ *
+ * This array would be used to search the proper string for selected language.
+ */
+static const uint16_t m_langids[] = { APP_USBD_STRINGS_LANGIDS };
+
+/**
+ * @brief Language ID descriptor
+ *
+ * Language
+ */
+
+
+/**
+ * @brief Mnemonics for the string positions in the array
+ *
+ * The mnemonics for the indexes of the strings inside the string array.
+ */
+enum {
+ APP_USBD_STRING_ID_LANGIDS_ARRAY_POS = 0, /**< Supported language identifiers */
+ APP_USBD_STRING_ID_MANUFACTURER_ARRAY_POS, /**< Manufacturer name */
+ APP_USBD_STRING_ID_PRODUCT_ARRAY_POS, /**< Product name */
+ APP_USBD_STRING_ID_SERIAL_ARRAY_POS, /**< Serial number */
+#define X(mnemonic, str_idx, ...) CONCAT_2(mnemonic, _ARRAY_POS),
+ APP_USBD_STRINGS_USER
+#undef X
+};
+
+/**
+ * @brief String index into internal array index conversion table
+ *
+ * The array that transforms the USB string indexes into internal array position.
+ * @note Value 0 used to mark non-existing string.
+ */
+static const uint8_t m_string_translation[APP_USBD_STRING_ID_CNT] =
+{
+ [APP_USBD_STRING_ID_LANGIDS ] = APP_USBD_STRING_ID_LANGIDS_ARRAY_POS,
+ [APP_USBD_STRING_ID_MANUFACTURER] = APP_USBD_STRING_ID_MANUFACTURER_ARRAY_POS,
+ [APP_USBD_STRING_ID_PRODUCT ] = APP_USBD_STRING_ID_PRODUCT_ARRAY_POS,
+ [APP_USBD_STRING_ID_SERIAL ] = APP_USBD_STRING_ID_SERIAL_ARRAY_POS,
+#define X(mnemonic, str_idx, ...) [mnemonic] = CONCAT_2(mnemonic, _ARRAY_POS),
+ APP_USBD_STRINGS_USER
+#undef X
+};
+
+#ifndef APP_USBD_STRINGS_MANUFACTURER_EXTERN
+#define APP_USBD_STRINGS_MANUFACTURER_EXTERN 0
+#endif
+
+#ifndef APP_USBD_STRINGS_PRODUCT_EXTERN
+#define APP_USBD_STRINGS_PRODUCT_EXTERN 0
+#endif
+
+#ifndef APP_USBD_STRING_SERIAL_EXTERN
+#define APP_USBD_STRING_SERIAL_EXTERN 0
+#endif
+
+#if APP_USBD_STRINGS_MANUFACTURER_EXTERN
+extern uint16_t APP_USBD_STRINGS_MANUFACTURER[];
+#endif
+
+#if APP_USBD_STRINGS_PRODUCT_EXTERN
+extern uint16_t APP_USBD_STRINGS_PRODUCT[];
+#endif
+
+#if APP_USBD_STRING_SERIAL_EXTERN
+extern uint16_t APP_USBD_STRING_SERIAL[];
+#endif
+
+
+/**
+ * @brief String descriptors table
+ * */
+static const uint16_t * m_string_dsc[APP_USBD_STRING_ID_CNT][ARRAY_SIZE(m_langids)] =
+{
+ [APP_USBD_STRING_ID_LANGIDS_ARRAY_POS] = { APP_USBD_STRING_DESC(APP_USBD_STRINGS_LANGIDS) },
+ [APP_USBD_STRING_ID_MANUFACTURER_ARRAY_POS] = { APP_USBD_STRINGS_MANUFACTURER },
+ [APP_USBD_STRING_ID_PRODUCT_ARRAY_POS] = { APP_USBD_STRINGS_PRODUCT },
+ [APP_USBD_STRING_ID_SERIAL_ARRAY_POS] = { APP_USBD_STRING_SERIAL },
+#define X(mnemonic, str_idx, ...) [CONCAT_2(mnemonic, _ARRAY_POS)] = { __VA_ARGS__ },
+ APP_USBD_STRINGS_USER
+#undef X
+};
+
+
+
+uint16_t const * app_usbd_string_desc_get(app_usbd_string_desc_idx_t idx, uint16_t langid)
+{
+ /* LANGID string */
+ if (APP_USBD_STRING_ID_LANGIDS == idx)
+ {
+ return m_string_dsc[APP_USBD_STRING_ID_LANGIDS_ARRAY_POS][0];
+ }
+
+ /* Searching for the language */
+ uint8_t lang_idx = 0;
+ if (ARRAY_SIZE(m_langids) > 1)
+ {
+ while (m_langids[lang_idx] != langid)
+ {
+ if (++lang_idx >= ARRAY_SIZE(m_langids))
+ {
+ return NULL;
+ }
+ }
+ }
+
+ /* Get the string index in array */
+ if (idx >= ARRAY_SIZE(m_string_translation))
+ {
+ return NULL;
+ }
+
+ uint8_t str_pos = m_string_translation[idx];
+ if (str_pos == 0)
+ {
+ return NULL;
+ }
+
+ uint16_t const * p_str = m_string_dsc[str_pos][lang_idx];
+ if ((ARRAY_SIZE(m_langids) > 1) && (lang_idx != 0))
+ {
+ if (p_str == NULL)
+ {
+ p_str = m_string_dsc[str_pos][0];
+ }
+ }
+
+ return p_str;
+}
+
+/** @} */
+#endif // APP_USBD_ENABLED
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/usbd/app_usbd_string_desc.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/usbd/app_usbd_string_desc.h
new file mode 100644
index 0000000..2a4888c
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/usbd/app_usbd_string_desc.h
@@ -0,0 +1,119 @@
+/**
+ * Copyright (c) 2016 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#ifndef APP_USBD_STRING_DESC_H__
+#define APP_USBD_STRING_DESC_H__
+
+#include <stdint.h>
+#include "sdk_common.h"
+#include "app_usbd.h"
+#include "app_usbd_string_config.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @defgroup app_usbd_string_desc USBD string descriptors
+ * @ingroup app_usbd
+ *
+ * @brief @tagAPI52840 USBD string descriptors management.
+ * @{
+ */
+
+/**
+ * @brief USB string initialization
+ *
+ * Macro that creates initialization values for USB string.
+ * The format contains header and string itself.
+ * The string should be declared as an array of uint16_t type.
+ *
+ * @param[in] ... Comma separated string letters or language ID.
+ * @return String descriptor initialization data.
+ */
+#define APP_USBD_STRING_DESC(...) (const uint16_t[]){ \
+ (0xff & (sizeof((uint16_t[]){__VA_ARGS__}) + 2)) | \
+ ((uint16_t)APP_USBD_DESCRIPTOR_STRING) << 8, \
+ __VA_ARGS__ }
+
+/**
+ * @brief USB string descriptors ID's
+ */
+typedef enum {
+ APP_USBD_STRING_ID_LANGIDS = 0, /**< Supported language identifiers */
+ APP_USBD_STRING_ID_MANUFACTURER, /**< Manufacturer name */
+ APP_USBD_STRING_ID_PRODUCT, /**< Product name */
+ APP_USBD_STRING_ID_SERIAL, /**< Serial number */
+
+#define X(mnemonic, str_idx, ...) mnemonic str_idx,
+ APP_USBD_STRINGS_USER
+#undef X
+
+ APP_USBD_STRING_ID_CNT /**< Total number of identifiers */
+} app_usbd_string_desc_idx_t;
+
+/**
+ * @brief Get string descriptor
+ *
+ * @param[in] idx String descriptor index
+ * @param[in] langid Selected language for the string
+ * @return String descriptor or NULL if not exist
+ * */
+uint16_t const * app_usbd_string_desc_get(app_usbd_string_desc_idx_t idx, uint16_t langid);
+
+/**
+ * @brief Get string length
+ *
+ * Function to get string length from descriptor (descriptor returned by @ref app_usbd_string_desc_get)
+ *
+ * @param[in] p_str String descriptor pointer
+ * @return Total descriptor length in bytes
+ */
+static inline size_t app_usbd_string_desc_length(uint16_t const * p_str)
+{
+ return ((const app_usbd_descriptor_string_t *)p_str)->bLength;
+}
+
+/** @} */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* APP_USBD_STRING_DESC_H__ */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/usbd/app_usbd_types.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/usbd/app_usbd_types.h
new file mode 100644
index 0000000..afb879b
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/usbd/app_usbd_types.h
@@ -0,0 +1,248 @@
+/**
+ * Copyright (c) 2016 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+
+#ifndef APP_USBD_TYPES_H__
+#define APP_USBD_TYPES_H__
+
+#include <stdint.h>
+
+#include "sdk_errors.h"
+#include "nrf_drv_usbd.h"
+#include "app_usbd_request.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @defgroup app_usbd_types USB Device high level library variable types definition
+ * @ingroup app_usbd
+ *
+ * @brief @tagAPI52840 All types used by @ref app_usbd are defined here.
+ * This helps to avoid cross referencing into types in different files.
+ * @{
+ */
+
+/**
+ * @brief Change given value to 2 digits in BCD notation
+ *
+ * @param[in] val The decimal value to be converted in the range from 0 to 99.
+ * @return Calculated BCD value.
+ */
+#define APP_USBD_BCD_2_MAKE(val) ( \
+ ((((val) % 100) / 10) * 0x10) + \
+ ((((val) % 10) / 1) * 0x1) \
+ )
+
+/**
+ * @brief Change given decimal version values to 4 digits in BCD notation
+ *
+ * USB specification uses 4 digits BCD version notation in many descriptors.
+ * This macro changes 2 values to 4 BCD digits (one 16 bit value)
+ * that describes version in USB standard.
+ *
+ * @param[in] major Major version
+ * @param[in] minor Minor version
+ *
+ * @return Calculated 16 bit value with BCD representation of the version
+ */
+#define APP_USBD_BCD_VER_MAKE(major, minor) \
+ ((APP_USBD_BCD_2_MAKE(major) << 8) | APP_USBD_BCD_2_MAKE(minor))
+
+/**
+ * @brief Events codes
+ *
+ * Redefined application event codes
+ */
+typedef enum
+{
+ APP_USBD_EVT_DRV_SOF = NRF_DRV_USBD_EVT_SOF, /**< See documentation for @ref NRF_DRV_USBD_EVT_SOF */
+ APP_USBD_EVT_DRV_RESET = NRF_DRV_USBD_EVT_RESET, /**< See documentation for @ref NRF_DRV_USBD_EVT_RESET */
+ APP_USBD_EVT_DRV_SUSPEND = NRF_DRV_USBD_EVT_SUSPEND, /**< See documentation for @ref NRF_DRV_USBD_EVT_SUSPEND */
+ APP_USBD_EVT_DRV_RESUME = NRF_DRV_USBD_EVT_RESUME, /**< See documentation for @ref NRF_DRV_USBD_EVT_RESUME */
+ APP_USBD_EVT_DRV_WUREQ = NRF_DRV_USBD_EVT_WUREQ, /**< See documentation for @ref NRF_DRV_USBD_EVT_WUREQ */
+ APP_USBD_EVT_DRV_SETUP = NRF_DRV_USBD_EVT_SETUP, /**< This event type has special structure. See @ref app_usbd_setup_evt_t */
+ APP_USBD_EVT_DRV_EPTRANSFER = NRF_DRV_USBD_EVT_EPTRANSFER, /**< See documentation for @ref NRF_DRV_USBD_EVT_EPTRANSFER */
+
+ APP_USBD_EVT_FIRST_POWER, /**< First power event code - for internal static assert checking */
+
+ APP_USBD_EVT_POWER_DETECTED, /**< See documentation for @ref NRF_DRV_POWER_USB_EVT_DETECTED */
+ APP_USBD_EVT_POWER_REMOVED, /**< See documentation for @ref NRF_DRV_POWER_USB_EVT_REMOVED */
+ APP_USBD_EVT_POWER_READY, /**< See documentation for @ref NRF_DRV_POWER_USB_EVT_READY */
+
+
+ APP_USBD_EVT_FIRST_APP, /**< First application event code - for internal static assert checking */
+
+ APP_USBD_EVT_INST_APPEND = APP_USBD_EVT_FIRST_APP, /**< The instance was attached to the library, any configuration action can be done now */
+ APP_USBD_EVT_INST_REMOVE, /**<
+ * The instance is going to be removed, this event is called just before removing the instance.
+ * This removing cannot be stopped.
+ */
+ APP_USBD_EVT_STARTED, /**< USBD library has just been started and functional - event passed to all instances, before USBD interrupts have been enabled */
+ APP_USBD_EVT_STOPPED, /**< USBD library has just been stopped and is not functional - event passed to all instances, after USBD interrupts have been disabled*/
+
+ APP_USBD_EVT_STATE_CHANGED, /**<
+ * Informs all the classes that base state has been changed.
+ * This event is processed before setup stage that caused the state change finishes (before acknowledging it).
+ */
+
+ APP_USBD_EVT_FIRST_INTERNAL = 0x80, /**< First internal event, used by the APP library internally. */
+
+ APP_USBD_EVT_HFCLK_READY = APP_USBD_EVT_FIRST_INTERNAL, /**< High frequency clock started */
+ APP_USBD_EVT_START_REQ, /**< Start requested */
+ APP_USBD_EVT_STOP_REQ, /**< Stop requested */
+ APP_USBD_EVT_SUSPEND_REQ, /**< Suspend request - HFCLK would be released and USBD peripheral clock would be disconnected */
+ APP_USBD_EVT_WAKEUP_REQ, /**< Wakeup request - start the whole wakeup generation. */
+
+} app_usbd_event_type_t;
+
+
+
+/**
+ * @brief Specific application event structure
+ *
+ * All the data required by the events that comes from the application level
+ */
+typedef struct
+{
+ app_usbd_event_type_t type; //!< Event type
+} app_usbd_evt_t;
+
+/**
+ * @brief Specific application event structure with setup structure included
+ *
+ * This event structure would be used when @ref APP_USBD_EVT_DRV_SETUP
+ * is passed to instance event handler
+ */
+typedef struct
+{
+ app_usbd_event_type_t type; //!< Event type
+ app_usbd_setup_t setup; //!< Setup structure
+} app_usbd_setup_evt_t;
+
+
+/**
+ * @brief Complex event variable type
+ *
+ * A variable that can store any kind of event.
+ */
+typedef union
+{
+ app_usbd_event_type_t type; //!< Event type
+ nrf_drv_usbd_evt_t drv_evt; //!< Events that comes directly from the driver.
+ /**< Use this event structure only for event
+ * type < @ref APP_USBD_EVT_FIRST_APP
+ */
+ app_usbd_setup_evt_t setup_evt; //!< Event structure with SETUP structure included.
+ /**< This structure is used in connection with
+ * @ref APP_USBD_EVT_DRV_SETUP
+ */
+ app_usbd_evt_t app_evt; //!< Events that comes from the application driver.
+ /**< Use this event structure only for event
+ * type >= @ref APP_USBD_EVT_FIRST_APP
+ */
+} app_usbd_complex_evt_t;
+
+
+/**
+ * @brief Internal event variable type
+ *
+ * The variable type used for internal event processing.
+ * This kind of event is the one that goes into the event queue.
+ *
+ * @note There is no setup event structure.
+ * This structure would be created when setup event is processed.
+ * The reason for that is the fact that setup event structure has high memory printout.
+ */
+typedef union
+{
+ app_usbd_event_type_t type; //!< Event type
+ nrf_drv_usbd_evt_t drv_evt; //!< Events that comes directly from the driver.
+ /**< Use this event structure only for event
+ * type < @ref APP_USBD_EVT_FIRST_APP
+ */
+ app_usbd_evt_t app_evt; //!< Events that comes from the application driver.
+ /**< Use this event structure only for event
+ * type >= @ref APP_USBD_EVT_FIRST_APP
+ */
+} app_usbd_internal_evt_t;
+
+
+#ifdef DOXYGEN
+/**
+ * @brief Base instance of a USBD class
+ *
+ * Any USBD class instance have to begin with this instance.
+ * This may then be followed by any implementation dependent data.
+ *
+ * For an instance it should be possible to put whole structure into FLASH.
+ *
+ * @note This type is early defined as incomplete type.
+ * This is required for function declaration that takes the pointer
+ * to this structure but in second hand - it is also placed inside
+ * the instance structure.
+ * @note The structure is defined in @file app_usbd_class_base.h.
+ */
+typedef struct {} app_usbd_class_inst_t;
+#else
+typedef struct app_usbd_class_inst_s app_usbd_class_inst_t;
+#endif
+/**
+ * @brief Endpoint callback function
+ *
+ * The function used by every class instance.
+ * @param[in,out] p_inst Instance of the class
+ * @param[in] p_event Event to process
+ *
+ * @note If given event is not supported by class, return @ref NRF_ERROR_NOT_SUPPORTED
+ */
+typedef ret_code_t (*app_usbd_ep_event_handler_t)(
+ app_usbd_class_inst_t const * const p_inst,
+ app_usbd_complex_evt_t const * const p_event
+ );
+
+
+/** @} */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* APP_USBD_TYPES_H__ */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/usbd/class/audio/app_usbd_audio.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/usbd/class/audio/app_usbd_audio.c
new file mode 100644
index 0000000..19e5a36
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/usbd/class/audio/app_usbd_audio.c
@@ -0,0 +1,813 @@
+/**
+ * Copyright (c) 2016 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#include "sdk_common.h"
+#if NRF_MODULE_ENABLED(APP_USBD_AUDIO)
+
+#include "app_usbd_audio.h"
+#include "app_util_platform.h"
+
+/**
+ * @defgroup app_usbd_audio_internals USBD Audio internals
+ * @{
+ * @ingroup app_usbd_audio
+ * @internal
+ */
+
+STATIC_ASSERT(sizeof(app_usbd_audio_ac_iface_header_desc_t) == 8);
+STATIC_ASSERT(sizeof(app_usbd_audio_input_terminal_desc_t) == 12);
+STATIC_ASSERT(sizeof(app_usbd_audio_output_terminal_desc_t) == 9);
+STATIC_ASSERT(sizeof(app_usbd_audio_feature_unit_desc_t) == 6);
+STATIC_ASSERT(sizeof(app_usbd_audio_as_iface_desc_t) == 7);
+STATIC_ASSERT(sizeof(app_usbd_audio_as_format_type_one_desc_t) == 8);
+STATIC_ASSERT(sizeof(app_usbd_audio_as_format_type_two_desc_t) == 9);
+STATIC_ASSERT(sizeof(app_usbd_audio_as_format_type_three_desc_t) == 8);
+STATIC_ASSERT(sizeof(app_usbd_audio_as_endpoint_desc_t) == 7);
+
+#define APP_USBD_AUDIO_CONTROL_IFACE_IDX 0 /**< Audio class control interface index */
+#define APP_USBD_AUDIO_STREAMING_IFACE_IDX 1 /**< Audio class streaming interface index */
+
+#define APP_USBD_CDC_AUDIO_STREAMING_EP_IDX 0 /**< Audio streaming isochronous endpoint index */
+
+/**
+ * @brief Auxiliary function to access audio class instance data
+ *
+ * @param[in] p_inst Class instance data
+ * @return Audio class instance data @ref app_usbd_audio_t
+ */
+static inline app_usbd_audio_t const * audio_get(app_usbd_class_inst_t const * p_inst)
+{
+ ASSERT(p_inst != NULL);
+ return (app_usbd_audio_t const *)p_inst;
+}
+
+
+/**
+ * @brief Auxiliary function to access audio class context data
+ *
+ * @param[in] p_audio Audio class instance data
+ * @return Audio class context data @ref app_usbd_audio_ctx_t
+ */
+static inline app_usbd_audio_ctx_t * audio_ctx_get(app_usbd_audio_t const * p_audio)
+{
+ ASSERT(p_audio != NULL);
+ ASSERT(p_audio->specific.p_data != NULL);
+ return &p_audio->specific.p_data->ctx;
+}
+
+
+/**
+ * @brief User event handler
+ *
+ * @param[in] p_inst Class instance
+ * @param[in] event user Event type @ref app_usbd_audio_user_event_t
+ */
+static inline void user_event_handler(
+ app_usbd_class_inst_t const * p_inst,
+ app_usbd_audio_user_event_t event)
+{
+ app_usbd_audio_t const * p_audio = audio_get(p_inst);
+
+ if (p_audio->specific.inst.user_ev_handler != NULL)
+ {
+ p_audio->specific.inst.user_ev_handler(p_inst, event);
+ }
+}
+
+
+/**
+ * @brief Select interface
+ *
+ * @param[in,out] p_inst Instance of the class
+ * @param[in] iface_idx Index of the interface inside class structure
+ * @param[in] alternate Alternate setting that should be selected
+ */
+static ret_code_t iface_select(
+ app_usbd_class_inst_t const * const p_inst,
+ uint8_t iface_idx,
+ uint8_t alternate)
+{
+ app_usbd_class_iface_conf_t const * p_iface = app_usbd_class_iface_get(p_inst, iface_idx);
+ /* Simple check if this is data interface */
+ uint8_t const ep_count = app_usbd_class_iface_ep_count_get(p_iface);
+
+ if (ep_count > 0)
+ {
+ if (alternate > 1)
+ {
+ return NRF_ERROR_INVALID_PARAM;
+ }
+ app_usbd_audio_t const * p_audio = audio_get(p_inst);
+ app_usbd_audio_ctx_t * p_audio_ctx = audio_ctx_get(p_audio);
+ p_audio_ctx->streaming = (alternate != 0);
+
+ uint8_t i;
+
+ for (i = 0; i < ep_count; ++i)
+ {
+ nrf_drv_usbd_ep_t ep_addr =
+ app_usbd_class_ep_address_get(app_usbd_class_iface_ep_get(p_iface, i));
+ if (alternate)
+ {
+ app_usbd_ep_enable(ep_addr);
+ }
+ else
+ {
+ app_usbd_ep_disable(ep_addr);
+ }
+ }
+ return NRF_SUCCESS;
+ }
+ return NRF_ERROR_NOT_SUPPORTED;
+}
+
+
+static void iface_deselect(
+ app_usbd_class_inst_t const * const p_inst,
+ uint8_t iface_idx)
+{
+ app_usbd_class_iface_conf_t const * p_iface = app_usbd_class_iface_get(p_inst, iface_idx);
+
+ /* Simple check if this is data interface */
+ if (p_iface->ep_cnt > 0)
+ {
+ app_usbd_audio_t const * p_audio = audio_get(p_inst);
+ app_usbd_audio_ctx_t * p_audio_ctx = audio_ctx_get(p_audio);
+ p_audio_ctx->streaming = false;
+ }
+ /* Note that all the interface endpoints would be disabled automatically after this function */
+}
+
+
+static uint8_t iface_selection_get(
+ app_usbd_class_inst_t const * const p_inst,
+ uint8_t iface_idx)
+{
+ app_usbd_class_iface_conf_t const * p_iface = app_usbd_class_iface_get(p_inst, iface_idx);
+ /* Simple check if this is data interface */
+ uint8_t const ep_count = app_usbd_class_iface_ep_count_get(p_iface);
+
+ if (ep_count > 0)
+ {
+ app_usbd_audio_t const * p_audio = audio_get(p_inst);
+ app_usbd_audio_ctx_t * p_audio_ctx = audio_ctx_get(p_audio);
+ return (p_audio_ctx->streaming) ? 1 : 0;
+ }
+ return 0;
+}
+
+
+/**
+ * @brief Internal SETUP standard IN request handler
+ *
+ * @param[in] p_inst Generic class instance
+ * @param[in] p_setup_ev Setup event
+ *
+ * @return Standard error code
+ * @retval NRF_SUCCESS if request handled correctly
+ * @retval NRF_ERROR_NOT_SUPPORTED if request is not supported
+ */
+static ret_code_t setup_req_std_in(app_usbd_class_inst_t const * p_inst,
+ app_usbd_setup_evt_t const * p_setup_ev)
+{
+ /* Only Get Descriptor standard IN request is supported by Audio class */
+ if ((app_usbd_setup_req_rec(p_setup_ev->setup.bmRequestType) == APP_USBD_SETUP_REQREC_INTERFACE)
+ &&
+ (p_setup_ev->setup.bmRequest == APP_USBD_SETUP_STDREQ_GET_DESCRIPTOR))
+ {
+ size_t dsc_len = 0;
+ size_t max_size;
+
+ uint8_t * p_trans_buff = app_usbd_core_setup_transfer_buff_get(&max_size);
+
+ /* Try to find descriptor in class internals*/
+ ret_code_t ret = app_usbd_class_descriptor_find(
+ p_inst,
+ p_setup_ev->setup.wValue.hb,
+ p_setup_ev->setup.wValue.lb,
+ p_trans_buff,
+ &dsc_len);
+
+ if (ret != NRF_ERROR_NOT_FOUND)
+ {
+ ASSERT(dsc_len < NRF_DRV_USBD_EPSIZE);
+ return app_usbd_core_setup_rsp(&(p_setup_ev->setup), p_trans_buff, dsc_len);
+ }
+ }
+
+ return NRF_ERROR_NOT_SUPPORTED;
+}
+
+
+/**
+ * @brief Internal SETUP class IN request handler
+ *
+ * @param[in] p_inst Generic class instance
+ * @param[in] p_setup_ev Setup event
+ *
+ * @return Standard error code
+ * @retval NRF_SUCCESS if request handled correctly
+ * @retval NRF_ERROR_NOT_SUPPORTED if request is not supported
+ */
+static ret_code_t setup_req_class_in(
+ app_usbd_class_inst_t const * p_inst,
+ app_usbd_setup_evt_t const * p_setup_ev)
+{
+ switch (p_setup_ev->setup.bmRequest)
+ {
+ case APP_USBD_AUDIO_REQ_GET_CUR:
+ case APP_USBD_AUDIO_REQ_GET_MIN:
+ case APP_USBD_AUDIO_REQ_GET_MAX:
+ case APP_USBD_AUDIO_REQ_SET_RES:
+ case APP_USBD_AUDIO_REQ_GET_MEM:
+ {
+ app_usbd_audio_t const * p_audio = audio_get(p_inst);
+ app_usbd_audio_ctx_t * p_audio_ctx = audio_ctx_get(p_audio);
+
+
+ p_audio_ctx->request.req_type = (app_usbd_audio_req_type_t)p_setup_ev->setup.bmRequest;
+ p_audio_ctx->request.control = p_setup_ev->setup.wValue.hb;
+ p_audio_ctx->request.channel = p_setup_ev->setup.wValue.lb;
+ p_audio_ctx->request.interface = p_setup_ev->setup.wIndex.hb;
+ p_audio_ctx->request.entity = p_setup_ev->setup.wIndex.lb;
+
+ p_audio_ctx->request.length = p_setup_ev->setup.wLength.w;
+
+ p_audio_ctx->request.req_target = APP_USBD_AUDIO_CLASS_REQ_IN;
+
+ app_usbd_setup_reqrec_t rec = app_usbd_setup_req_rec(p_setup_ev->setup.bmRequestType);
+ if (rec == APP_USBD_SETUP_REQREC_ENDPOINT)
+ {
+ p_audio_ctx->request.req_target = APP_USBD_AUDIO_EP_REQ_IN;
+ }
+
+ user_event_handler((app_usbd_class_inst_t const *)p_audio,
+ APP_USBD_AUDIO_USER_EVT_CLASS_REQ);
+
+ return app_usbd_core_setup_rsp(&p_setup_ev->setup,
+ p_audio_ctx->request.payload,
+ p_audio_ctx->request.length);
+ }
+
+ default:
+ break;
+ }
+
+ return NRF_ERROR_NOT_SUPPORTED;
+}
+
+
+static ret_code_t audio_req_out_data_cb(nrf_drv_usbd_ep_status_t status, void * p_context)
+{
+ if (status == NRF_USBD_EP_OK)
+ {
+ app_usbd_audio_t const * p_audio = p_context;
+
+ user_event_handler((app_usbd_class_inst_t const *)p_audio,
+ APP_USBD_AUDIO_USER_EVT_CLASS_REQ);
+ }
+
+ return NRF_SUCCESS;
+}
+
+
+static ret_code_t audio_req_out(
+ app_usbd_class_inst_t const * p_inst,
+ app_usbd_setup_evt_t const * p_setup_ev)
+{
+ app_usbd_audio_t const * p_audio = audio_get(p_inst);
+ app_usbd_audio_ctx_t * p_audio_ctx = audio_ctx_get(p_audio);
+
+
+ p_audio_ctx->request.req_type = (app_usbd_audio_req_type_t)p_setup_ev->setup.bmRequest;
+ p_audio_ctx->request.control = p_setup_ev->setup.wValue.hb;
+ p_audio_ctx->request.channel = p_setup_ev->setup.wValue.lb;
+ p_audio_ctx->request.interface = p_setup_ev->setup.wIndex.hb;
+ p_audio_ctx->request.entity = p_setup_ev->setup.wIndex.lb;
+
+ p_audio_ctx->request.length = p_setup_ev->setup.wLength.w;
+
+ p_audio_ctx->request.req_target = APP_USBD_AUDIO_CLASS_REQ_OUT;
+ if (app_usbd_setup_req_rec(p_setup_ev->setup.bmRequestType) == APP_USBD_SETUP_REQREC_ENDPOINT)
+ {
+ p_audio_ctx->request.req_target = APP_USBD_AUDIO_EP_REQ_OUT;
+ }
+
+ /*Request setup data*/
+ NRF_DRV_USBD_TRANSFER_OUT(transfer, p_audio_ctx->request.payload, p_audio_ctx->request.length);
+ ret_code_t ret;
+ CRITICAL_REGION_ENTER();
+ ret = app_usbd_ep_transfer(NRF_DRV_USBD_EPOUT0, &transfer);
+ if (ret == NRF_SUCCESS)
+ {
+ app_usbd_core_setup_data_handler_desc_t desc = {
+ .handler = audio_req_out_data_cb,
+ .p_context = (void *)p_audio
+ };
+
+ ret = app_usbd_core_setup_data_handler_set(NRF_DRV_USBD_EPOUT0, &desc);
+ }
+ CRITICAL_REGION_EXIT();
+
+ return ret;
+}
+
+
+/**
+ * @brief Internal SETUP class OUT request handler
+ *
+ * @param[in] p_inst Generic class instance
+ * @param[in] p_setup_ev Setup event
+ *
+ * @return Standard error code
+ * @retval NRF_SUCCESS if request handled correctly
+ * @retval NRF_ERROR_NOT_SUPPORTED if request is not supported
+ */
+static ret_code_t setup_req_class_out(
+ app_usbd_class_inst_t const * p_inst,
+ app_usbd_setup_evt_t const * p_setup_ev)
+{
+ switch (p_setup_ev->setup.bmRequest)
+ {
+ case APP_USBD_AUDIO_REQ_SET_CUR:
+ case APP_USBD_AUDIO_REQ_SET_MIN:
+ case APP_USBD_AUDIO_REQ_SET_MAX:
+ case APP_USBD_AUDIO_REQ_SET_RES:
+ case APP_USBD_AUDIO_REQ_SET_MEM:
+ return audio_req_out(p_inst, p_setup_ev);
+
+ default:
+ break;
+ }
+
+ return NRF_ERROR_NOT_SUPPORTED;
+}
+
+
+/**
+ * @brief Control endpoint handle
+ *
+ * @param[in] p_inst Generic class instance
+ * @param[in] p_setup_ev Setup event
+ *
+ * @return Standard error code
+ * @retval NRF_SUCCESS if request handled correctly
+ * @retval NRF_ERROR_NOT_SUPPORTED if request is not supported
+ */
+static ret_code_t setup_event_handler(
+ app_usbd_class_inst_t const * p_inst,
+ app_usbd_setup_evt_t const * p_setup_ev)
+{
+ ASSERT(p_inst != NULL);
+ ASSERT(p_setup_ev != NULL);
+
+ if (app_usbd_setup_req_dir(p_setup_ev->setup.bmRequestType) == APP_USBD_SETUP_REQDIR_IN)
+ {
+ switch (app_usbd_setup_req_typ(p_setup_ev->setup.bmRequestType))
+ {
+ case APP_USBD_SETUP_REQTYPE_STD:
+ return setup_req_std_in(p_inst, p_setup_ev);
+
+ case APP_USBD_SETUP_REQTYPE_CLASS:
+ return setup_req_class_in(p_inst, p_setup_ev);
+
+ default:
+ break;
+ }
+ }
+ else /*APP_USBD_SETUP_REQDIR_OUT*/
+ {
+ switch (app_usbd_setup_req_typ(p_setup_ev->setup.bmRequestType))
+ {
+ case APP_USBD_SETUP_REQTYPE_CLASS:
+ return setup_req_class_out(p_inst, p_setup_ev);
+
+ default:
+ break;
+ }
+ }
+
+ return NRF_ERROR_NOT_SUPPORTED;
+}
+
+
+/**
+ * @brief Endpoint IN event handler
+ *
+ * @param[in] p_inst Generic class instance
+ *
+ * @return Standard error code
+ * @retval NRF_SUCCESS if request handled correctly
+ * @retval NRF_ERROR_NOT_SUPPORTED if request is not supported
+ */
+static ret_code_t endpoint_in_event_handler(app_usbd_class_inst_t const * p_inst)
+{
+ user_event_handler(p_inst, APP_USBD_AUDIO_USER_EVT_TX_DONE);
+ return NRF_SUCCESS;
+}
+
+
+/**
+ * @brief Endpoint OUT event handler
+ *
+ * @param[in] p_inst Generic class instance
+ *
+ * @return Standard error code
+ * @retval NRF_SUCCESS if request handled correctly
+ * @retval NRF_ERROR_NOT_SUPPORTED if request is not supported
+ */
+static ret_code_t endpoint_out_event_handler(app_usbd_class_inst_t const * p_inst)
+{
+ user_event_handler(p_inst, APP_USBD_AUDIO_USER_EVT_RX_DONE);
+ return NRF_SUCCESS;
+}
+
+
+/**
+ * @brief Auxiliary function to access isochronous endpoint address
+ *
+ * @param[in] p_inst Class instance data
+ *
+ * @return ISO endpoint address
+ */
+static inline nrf_drv_usbd_ep_t ep_iso_addr_get(app_usbd_class_inst_t const * p_inst)
+{
+ app_usbd_class_iface_conf_t const * class_iface;
+
+ class_iface = app_usbd_class_iface_get(p_inst, APP_USBD_AUDIO_STREAMING_IFACE_IDX);
+
+ app_usbd_class_ep_conf_t const * ep_cfg;
+ ep_cfg = app_usbd_class_iface_ep_get(class_iface, APP_USBD_CDC_AUDIO_STREAMING_EP_IDX);
+
+ return app_usbd_class_ep_address_get(ep_cfg);
+}
+
+
+/**
+ * @brief @ref app_usbd_class_methods_t::event_handler
+ */
+static ret_code_t audio_event_handler(
+ app_usbd_class_inst_t const * p_inst,
+ app_usbd_complex_evt_t const * p_event)
+{
+ ASSERT(p_inst != NULL);
+ ASSERT(p_event != NULL);
+
+ ret_code_t ret = NRF_SUCCESS;
+
+ switch (p_event->app_evt.type)
+ {
+ case APP_USBD_EVT_DRV_RESET:
+ break;
+
+ case APP_USBD_EVT_DRV_SETUP:
+ ret = setup_event_handler(p_inst, (app_usbd_setup_evt_t const *)p_event);
+ break;
+
+ case APP_USBD_EVT_DRV_EPTRANSFER:
+ if (NRF_USBD_EPIN_CHECK(p_event->drv_evt.data.eptransfer.ep))
+ {
+ ret = endpoint_in_event_handler(p_inst);
+ }
+ else
+ {
+ ret = endpoint_out_event_handler(p_inst);
+ }
+ break;
+
+ case APP_USBD_EVT_DRV_SUSPEND:
+ break;
+
+ case APP_USBD_EVT_DRV_RESUME:
+ break;
+
+ case APP_USBD_EVT_INST_APPEND:
+ break;
+
+ case APP_USBD_EVT_INST_REMOVE:
+ break;
+
+ case APP_USBD_EVT_STARTED:
+ break;
+
+ case APP_USBD_EVT_STOPPED:
+ break;
+
+ default:
+ ret = NRF_ERROR_NOT_SUPPORTED;
+ break;
+ }
+
+ return ret;
+}
+
+
+static size_t audio_get_format_descriptor_size(app_usbd_class_inst_t const * p_inst)
+{
+ app_usbd_audio_t const * p_audio = audio_get(p_inst);
+
+ return p_audio->specific.inst.p_format_dsc->size;
+}
+
+
+static size_t audio_get_format_descriptor_data(app_usbd_class_inst_t const * p_inst,
+ uint32_t cur_byte)
+{
+ app_usbd_audio_t const * p_audio = audio_get(p_inst);
+
+ return p_audio->specific.inst.p_format_dsc->p_data[cur_byte];
+}
+
+
+static size_t audio_get_input_descriptor_size(app_usbd_class_inst_t const * p_inst)
+{
+ app_usbd_audio_t const * p_audio = audio_get(p_inst);
+
+ return p_audio->specific.inst.p_input_dsc->size;
+}
+
+
+static size_t audio_get_input_descriptor_data(app_usbd_class_inst_t const * p_inst,
+ uint32_t cur_byte)
+{
+ app_usbd_audio_t const * p_audio = audio_get(p_inst);
+
+ return p_audio->specific.inst.p_input_dsc->p_data[cur_byte];
+}
+
+
+static size_t audio_get_output_descriptor_size(app_usbd_class_inst_t const * p_inst)
+{
+ app_usbd_audio_t const * p_audio = audio_get(p_inst);
+
+ return p_audio->specific.inst.p_output_dsc->size;
+}
+
+
+static size_t audio_get_output_descriptor_data(app_usbd_class_inst_t const * p_inst,
+ uint32_t cur_byte)
+{
+ app_usbd_audio_t const * p_audio = audio_get(p_inst);
+
+ return p_audio->specific.inst.p_output_dsc->p_data[cur_byte];
+}
+
+
+static size_t audio_get_feature_descriptor_size(app_usbd_class_inst_t const * p_inst)
+{
+ app_usbd_audio_t const * p_audio = audio_get(p_inst);
+
+ return p_audio->specific.inst.p_feature_dsc->size;
+}
+
+
+static size_t audio_get_feature_descriptor_data(app_usbd_class_inst_t const * p_inst,
+ uint32_t cur_byte)
+{
+ app_usbd_audio_t const * p_audio = audio_get(p_inst);
+
+ return p_audio->specific.inst.p_feature_dsc->p_data[cur_byte];
+}
+
+
+static uint8_t audio_get_control_interface_number(app_usbd_class_inst_t const * p_inst)
+{
+ app_usbd_class_iface_conf_t const * ifce = 0;
+
+ ifce = app_usbd_class_iface_get(p_inst, 0);
+ return app_usbd_class_iface_number_get(ifce);
+}
+
+
+/**
+ * @brief @ref app_usbd_class_methods_t::feed_descriptors
+ */
+
+static bool audio_feed_descriptors(app_usbd_class_descriptor_ctx_t * p_ctx,
+ app_usbd_class_inst_t const * p_inst,
+ uint8_t * p_buff,
+ size_t max_size)
+{
+ static uint8_t ifaces = 0;
+ ifaces = app_usbd_class_iface_count_get(p_inst);
+ ASSERT(ifaces == 2);
+ app_usbd_audio_t const * p_audio = audio_get(p_inst);
+
+ APP_USBD_CLASS_DESCRIPTOR_BEGIN(p_ctx, p_buff, max_size);
+
+ /* CONTROL INTERFACE DESCRIPTOR */
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(0x09); // bLength
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(APP_USBD_DESCRIPTOR_INTERFACE); // bDescriptorType = Interface
+
+ static app_usbd_class_iface_conf_t const * p_cur_iface = NULL;
+ p_cur_iface = app_usbd_class_iface_get(p_inst, 0);
+
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(app_usbd_class_iface_number_get(p_cur_iface)); // bInterfaceNumber
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(0x00); // bAlternateSetting
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(app_usbd_class_iface_ep_count_get(p_cur_iface)); // bNumEndpoints
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(APP_USBD_AUDIO_CLASS); // bInterfaceClass = Audio
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(APP_USBD_AUDIO_SUBCLASS_AUDIOCONTROL); // bInterfaceSubclass (Audio Control)
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(APP_USBD_AUDIO_CLASS_PROTOCOL_UNDEFINED); // bInterfaceProtocol
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(0x00); // iInterface
+
+ /* HEADER INTERFACE */
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(0x09); // bLength
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(APP_USBD_AUDIO_DESCRIPTOR_INTERFACE); // bDescriptorType = Audio Interfaces
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(APP_USBD_AUDIO_AC_IFACE_SUBTYPE_HEADER); // bDescriptorSubtype = Header
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(LSB_16(0x0100)); // bcdADC LSB
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(MSB_16(0x0100)); // bcdADC MSB
+
+ static uint16_t header_desc_len = 0;
+ header_desc_len = 9 + audio_get_feature_descriptor_size(p_inst) +
+ audio_get_input_descriptor_size(p_inst) + audio_get_output_descriptor_size(
+ p_inst);
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(LSB_16(header_desc_len)); // wTotalLength LSB
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(MSB_16(header_desc_len)); // wTotalLength MSB
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(0x01); // bInCollection
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(audio_get_control_interface_number(p_inst) + 1); // baInterfaceNr(1)
+
+ /* INPUT TERMINAL DESCRIPTOR */
+ static uint32_t cur_byte = 0;
+ static size_t input_desc_size = 0;
+ input_desc_size = audio_get_input_descriptor_size(p_inst);
+
+ for (cur_byte = 0; cur_byte < input_desc_size; cur_byte++)
+ {
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(audio_get_input_descriptor_data(p_inst, cur_byte));
+ }
+
+ /* FEATURE UNIT DESCRIPTOR */
+ static size_t feature_desc_size = 0;
+ feature_desc_size = audio_get_feature_descriptor_size(p_inst);
+
+ for (cur_byte = 0; cur_byte < feature_desc_size; cur_byte++)
+ {
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(audio_get_feature_descriptor_data(p_inst, cur_byte));
+ }
+
+ /* OUTPUT TERMINAL DESCRIPTOR */
+ static size_t output_desc_size = 0;
+ output_desc_size = audio_get_output_descriptor_size(p_inst);
+
+ for (cur_byte = 0; cur_byte < output_desc_size; cur_byte++)
+ {
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(audio_get_output_descriptor_data(p_inst, cur_byte));
+ }
+
+ p_cur_iface++;
+
+ /* STREAM INTERFACE DESCRIPTOR ALT 0 */
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(0x09); // bLength
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(APP_USBD_DESCRIPTOR_INTERFACE); // bDescriptorType = Interface
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(audio_get_control_interface_number(p_inst) + 1); // bInterfaceNumber
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(0x00); // bAlternateSetting
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(0x00); // bNumEndpoints
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(APP_USBD_AUDIO_CLASS); // bInterfaceClass = Audio
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(p_audio->specific.inst.type_streaming); // bInterfaceSubclass (Audio Control)
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(APP_USBD_AUDIO_CLASS_PROTOCOL_UNDEFINED); // bInterfaceProtocol
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(0x00); // iInterface
+
+ /* STREAM INTERFACE DESCRIPTOR ALT 1 */
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(0x09); // bLength
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(APP_USBD_DESCRIPTOR_INTERFACE); // bDescriptorType = Interface
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(audio_get_control_interface_number(p_inst) + 1); // bInterfaceNumber
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(0x01); // bAlternateSetting
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(app_usbd_class_iface_ep_count_get(p_cur_iface)); // bNumEndpoints
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(APP_USBD_AUDIO_CLASS); // bInterfaceClass = Audio
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(p_audio->specific.inst.type_streaming); // bInterfaceSubclass (Audio Control)
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(APP_USBD_AUDIO_CLASS_PROTOCOL_UNDEFINED); // bInterfaceProtocol
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(0x00); // iInterface
+
+ /* AudioStreaming GENERAL DESCRIPTOR */
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(0x07); // bLength
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(APP_USBD_AUDIO_DESCRIPTOR_INTERFACE); // bDescriptorType = Audio Interface
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(APP_USBD_AUDIO_AS_IFACE_SUBTYPE_GENERAL); // bDescriptorSubtype = General
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(audio_get_control_interface_number(p_inst) + 1); // bTerminalLink
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(p_audio->specific.inst.delay); // bDelay
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(LSB_16(p_audio->specific.inst.format)); // wFormatTag LSB
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(MSB_16(p_audio->specific.inst.format)); // wFormatTag MSB
+
+ /* FORMAT DESCRIPTOR */
+ static size_t format_desc_size = 0;
+ format_desc_size = audio_get_format_descriptor_size(p_inst);
+
+ for (cur_byte = 0; cur_byte < format_desc_size; cur_byte++)
+ {
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(audio_get_format_descriptor_data(p_inst, cur_byte));
+ }
+
+ /* ENDPOINT GENERAL DESCRIPTOR */
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(0x07); // bLength
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(APP_USBD_AUDIO_DESCRIPTOR_ENDPOINT); // bDescriptorType = Audio Descriptor
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(APP_USBD_AUDIO_EP_SUBTYPE_GENERAL); // bDescriptorSubtype = EP General
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(0x00); // bmAttributes
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(0x00); // bLockDelayUnits
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(LSB_16(0x0000)); // wLockDelay LSB
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(MSB_16(0x0000)); // wLockDelay MSB
+
+ /* ENDPOINT ISO DESCRIPTOR */
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(0x09); // bLength
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(APP_USBD_DESCRIPTOR_ENDPOINT); // bDescriptorType = Endpoint
+
+ static app_usbd_class_ep_conf_t const * p_cur_ep = NULL;
+ p_cur_ep = app_usbd_class_iface_ep_get(p_cur_iface, 0);
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(app_usbd_class_ep_address_get(p_cur_ep)); // bEndpointAddress
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(APP_USBD_DESCRIPTOR_EP_ATTR_TYPE_ISOCHRONOUS); // bmAttributes
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(LSB_16(p_audio->specific.inst.ep_size)); // wMaxPacketSize LSB
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(MSB_16(p_audio->specific.inst.ep_size)); // wMaxPacketSize MSB
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(0x01); // bInterval
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(0x00); // bRefresh
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(0x00); // bSynchAddress
+
+ APP_USBD_CLASS_DESCRIPTOR_END();
+}
+
+/** @} */
+
+const app_usbd_class_methods_t app_usbd_audio_class_methods = {
+ .event_handler = audio_event_handler,
+ .feed_descriptors = audio_feed_descriptors,
+ .iface_select = iface_select,
+ .iface_deselect = iface_deselect,
+ .iface_selection_get = iface_selection_get,
+};
+
+
+size_t app_usbd_audio_class_rx_size_get(app_usbd_class_inst_t const * p_inst)
+{
+ nrf_drv_usbd_ep_t ep_addr;
+
+ ep_addr = ep_iso_addr_get(p_inst);
+ ASSERT(NRF_USBD_EPISO_CHECK(ep_addr));
+
+ return (size_t)nrf_drv_usbd_epout_size_get(ep_addr);
+}
+
+
+ret_code_t app_usbd_audio_class_rx_start(
+ app_usbd_class_inst_t const * p_inst,
+ void * p_buff,
+ size_t size)
+{
+ nrf_drv_usbd_ep_t ep_addr;
+
+ ep_addr = ep_iso_addr_get(p_inst);
+ ASSERT(NRF_USBD_EPISO_CHECK(ep_addr));
+
+ NRF_DRV_USBD_TRANSFER_OUT(transfer, p_buff, size);
+ return app_usbd_ep_transfer(ep_addr, &transfer);
+}
+
+
+ret_code_t app_usbd_audio_class_tx_start(
+ app_usbd_class_inst_t const * p_inst,
+ const void * p_buff,
+ size_t size)
+{
+ nrf_drv_usbd_ep_t ep_addr;
+
+ ep_addr = ep_iso_addr_get(p_inst);
+ ASSERT(NRF_USBD_EPISO_CHECK(ep_addr));
+
+ NRF_DRV_USBD_TRANSFER_IN(transfer, p_buff, size);
+ return app_usbd_ep_transfer(ep_addr, &transfer);
+}
+
+
+#endif //NRF_MODULE_ENABLED(APP_USBD_AUDIO)
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/usbd/class/audio/app_usbd_audio.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/usbd/class/audio/app_usbd_audio.h
new file mode 100644
index 0000000..f094bbb
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/usbd/class/audio/app_usbd_audio.h
@@ -0,0 +1,329 @@
+/**
+ * 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#ifndef APP_USBD_AUDIO_H__
+#define APP_USBD_AUDIO_H__
+
+#include <stdint.h>
+#include <stdbool.h>
+
+#include "nrf_drv_usbd.h"
+#include "app_usbd.h"
+#include "app_usbd_core.h"
+#include "app_usbd_class_base.h"
+#include "app_usbd_descriptor.h"
+
+#include "app_usbd_audio_types.h"
+#include "app_usbd_audio_desc.h"
+#include "app_usbd_audio_internal.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @defgroup app_usbd_audio USB AUDIO class
+ * @ingroup app_usbd
+ *
+ * @brief @tagAPI52840 Module with types, definitions, and API used by USB Audio class.
+ *
+ * @details Reference specifications:
+ * - "Universal Serial Bus Device Class Definition for Audio Devices"
+ * Release 1.0, March 18, 1998.
+ * - "Universal Serial Bus Device Class Definition for Audio Data Formats"
+ * Release 1.0, March 18, 1998.
+ * - "Universal Serial Bus Device Class Definition for Terminal Types"
+ * Release 1.0, March 18, 1998.
+ *
+ * @{
+ */
+
+
+#ifdef DOXYGEN
+/**
+ * @brief Audio class instance type
+ *
+ * @ref APP_USBD_CLASS_TYPEDEF
+ */
+typedef struct { } app_usbd_audio_t;
+#else
+/*lint -save -e10 -e26 -e123 -e505 */
+APP_USBD_CLASS_TYPEDEF(app_usbd_audio, \
+ APP_USBD_AUDIO_CONFIG(0, 1), \
+ APP_USBD_AUDIO_INSTANCE_SPECIFIC_DEC, \
+ APP_USBD_AUDIO_DATA_SPECIFIC_DEC \
+);
+/*lint -restore*/
+#endif
+
+
+/*lint -save -e407 */
+
+/**
+ * @brief Events passed to user event handler
+ *
+ * @note Example prototype of user event handler:
+ *
+ * @code
+ void audio_user_ev_handler(app_usbd_class_inst_t const * p_inst,
+ app_usbd_audio_user_event_t event);
+ * @endcode
+ */
+typedef enum app_usbd_audio_user_event_e {
+ APP_USBD_AUDIO_USER_EVT_CLASS_REQ, /**< User event CLASS_REQ */
+ APP_USBD_AUDIO_USER_EVT_RX_DONE, /**< User event RX_DONE */
+ APP_USBD_AUDIO_USER_EVT_TX_DONE, /**< User event TX_DONE */
+} app_usbd_audio_user_event_t;
+
+/*lint -restore*/
+
+/**
+ * @brief Global definition of app_usbd_audio_t class instance
+ *
+ * @param instance_name Name of global instance
+ * @param interfaces_configs Interfaces configurations
+ * @param user_ev_handler User event handler
+ * @param format_descriptor Audio class Format descriptor
+ * @param input_descriptor Audio class Input Terminal descriptor
+ * @param output_descriptor Audio class Output Terminal descriptor
+ * @param feature_descriptor Audio class Feature Unit descriptor
+ * @param delay Streaming delay
+ * @param format FormatTag (@ref app_usbd_audio_as_iface_format_tag_t)
+ * @param ep_size Endpoint size
+ * @param type_str Streaming type MIDISTREAMING/AUDIOSTREAMING
+ *
+ * @note This macro is just simplified version of @ref APP_USBD_AUDIO_GLOBAL_DEF_INTERNAL
+ *
+ */
+#define APP_USBD_AUDIO_GLOBAL_DEF(instance_name, \
+ interfaces_configs, \
+ user_ev_handler, \
+ format_descriptor, \
+ input_descriptor, \
+ output_descriptor, \
+ feature_descriptor, \
+ delay, \
+ format, \
+ ep_size, \
+ type_str) \
+ APP_USBD_AUDIO_GLOBAL_DEF_INTERNAL(instance_name, \
+ interfaces_configs, \
+ user_ev_handler, \
+ format_descriptor, \
+ input_descriptor, \
+ output_descriptor, \
+ feature_descriptor, \
+ delay, \
+ format, \
+ ep_size, \
+ type_str)
+
+
+/**
+ * @brief Initializer of Audio Format descriptor
+ *
+ * @param name Format descriptor name
+ * @param ... Format descriptor data
+*/
+
+#define APP_USBD_AUDIO_FORMAT_DESCRIPTOR(name, ...) \
+ static uint8_t const CONCAT_2(name, _data)[] = \
+ { \
+ __VA_ARGS__ \
+ }; \
+ static const app_usbd_audio_subclass_desc_t name = \
+ { \
+ sizeof(CONCAT_2(name, _data)), \
+ APP_USBD_AUDIO_AS_IFACE_SUBTYPE_FORMAT_TYPE, \
+ CONCAT_2(name,_data) \
+ }
+
+/**
+ * @brief Initializer of Audio Input descriptor
+ *
+ * @param name Input descriptor name
+ * @param ... Input descriptor data
+*/
+
+#define APP_USBD_AUDIO_INPUT_DESCRIPTOR(name, ...) \
+ static uint8_t const CONCAT_2(name, _data)[] = \
+ { \
+ __VA_ARGS__ \
+ }; \
+ static const app_usbd_audio_subclass_desc_t name = \
+ { \
+ sizeof(CONCAT_2(name, _data)), \
+ APP_USBD_AUDIO_AC_IFACE_SUBTYPE_INPUT_TERMINAL, \
+ CONCAT_2(name,_data) \
+ }
+
+/**
+ * @brief Initializer of Audio Output descriptor
+ *
+ * @param name Output descriptor name
+ * @param ... Output descriptor data
+*/
+
+#define APP_USBD_AUDIO_OUTPUT_DESCRIPTOR(name, ...) \
+ static uint8_t const CONCAT_2(name, _data)[] = \
+ { \
+ __VA_ARGS__ \
+ }; \
+ static const app_usbd_audio_subclass_desc_t name = \
+ { \
+ sizeof(CONCAT_2(name, _data)), \
+ APP_USBD_AUDIO_AC_IFACE_SUBTYPE_OUTPUT_TERNINAL, \
+ CONCAT_2(name,_data) \
+ }
+
+/**
+ * @brief Initializer of Feture Output descriptor
+ *
+ * @param name Feture descriptor name
+ * @param ... Feture descriptor data
+*/
+
+#define APP_USBD_AUDIO_FEATURE_DESCRIPTOR(name, ...) \
+ static uint8_t const CONCAT_2(name, _data)[] = \
+ { \
+ __VA_ARGS__ \
+ }; \
+ static const app_usbd_audio_subclass_desc_t name = \
+ { \
+ sizeof(CONCAT_2(name, _data)), \
+ APP_USBD_AUDIO_AC_IFACE_SUBTYPE_FEATURE_UNIT, \
+ CONCAT_2(name,_data) \
+ }
+
+/**
+ * @@brief Helper function to get class instance from Audio class
+ *
+ * @param[in] p_audio Audio class instance (declared by @ref APP_USBD_AUDIO_GLOBAL_DEF)
+ * @return Base class instance
+ */
+static inline app_usbd_class_inst_t const *
+app_usbd_audio_class_inst_get(app_usbd_audio_t const * p_audio)
+{
+ return &p_audio->base;
+}
+
+/**
+ * @brief Helper function to get audio specific request from audio class
+ *
+ * @param[in] p_audio Audio class instance (declared by @ref APP_USBD_AUDIO_GLOBAL_DEF)
+ * @return Audio class specific request
+ */
+static inline app_usbd_audio_req_t *
+app_usbd_audio_class_request_get(app_usbd_audio_t const * p_audio)
+{
+ return &p_audio->specific.p_data->ctx.request;
+}
+
+/**
+ * @brief Helper function to get audio from base class instance
+ *
+ * @param[in] p_inst Base class instance
+ * @return Audio class handle
+ */
+static inline app_usbd_audio_t const *
+app_usbd_audio_class_get(app_usbd_class_inst_t const * p_inst)
+{
+ return (app_usbd_audio_t const *)p_inst;
+}
+
+/**
+ * @brief Get the size of last received transfer.
+ *
+ * @note Call this function in reaction to a SOF event to check if there is any data to process.
+ *
+ * @param p_inst Base class instance.
+ *
+ * @return Number of bytes received in the last transmission.
+ */
+size_t app_usbd_audio_class_rx_size_get(app_usbd_class_inst_t const * p_inst);
+
+/**
+ * @brief Start audio data copying from the endpoint buffer.
+ *
+ * Function to be used to copy data from an audio OUT endpoint to a given buffer.
+ * When it finishes, an @ref APP_USBD_AUDIO_USER_EVT_RX_DONE event is generated.
+ *
+ * @param p_inst Base class instance.
+ * @param p_buff Target buffer.
+ * @param size Size of the requested data.
+ *
+ * @return Result of the endpoint transmission start.
+ *
+ * @sa app_usbd_audio_class_rx_size_get
+ *
+ * @note This function should be called in reaction to a SOF event.
+ * Isochronous endpoints are double buffered and they are automatically switched at every SOF.
+ */
+ret_code_t app_usbd_audio_class_rx_start(
+ app_usbd_class_inst_t const * p_inst,
+ void * p_buff,
+ size_t size);
+
+/**
+ * @brief Start copying audio data to the endpoint buffer.
+ *
+ * Function to be used to copy data to an audio IN endpoint from a given buffer.
+ * When it finishes, an @ref APP_USBD_AUDIO_USER_EVT_TX_DONE event is generated.
+ *
+ * @param p_inst Base class instance.
+ * @param p_buff Source buffer.
+ * @param size Size of the data to be sent.
+ *
+ * @return Result of the endpoint transsmision start.
+ *
+ * @note This function should be called in reaction to a SOF event.
+ * Isochronous endpoints are double buffered and they are automatically switched at every SOF.
+ */
+ret_code_t app_usbd_audio_class_tx_start(
+ app_usbd_class_inst_t const * p_inst,
+ const void * p_buff,
+ size_t size);
+
+/** @} */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* APP_USBD_AUDIO_H__ */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/usbd/class/audio/app_usbd_audio_desc.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/usbd/class/audio/app_usbd_audio_desc.h
new file mode 100644
index 0000000..dbc4d41
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/usbd/class/audio/app_usbd_audio_desc.h
@@ -0,0 +1,318 @@
+/**
+ * Copyright (c) 2016 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#ifndef APP_USBD_AUDIO_DESC_H__
+#define APP_USBD_AUDIO_DESC_H__
+
+#include "app_usbd_descriptor.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @defgroup app_usbd_audio_dsc USB Audio descriptors
+ * @brief @tagAPI52840 Descriptors used in the USB Audio class.
+ * @ingroup app_usbd_audio
+ * @{
+ */
+
+/**
+ * @brief Initializer of interface descriptor for AUDIO class
+ *
+ * @param interface_number Interface number
+ * @param alt_setting Interface alternate setting
+ * @param ep_num Number of endpoints
+ * @param subclass Audio subclass @ref app_usbd_audio_subclass_t
+ * */
+#define APP_USBD_AUDIO_INTERFACE_DSC(interface_number, alt_setting, ep_num, subclass) \
+ /*.bLength = */ sizeof(app_usbd_descriptor_iface_t), \
+ /*.bDescriptorType = */ APP_USBD_DESCRIPTOR_INTERFACE, \
+ /*.bInterfaceNumber = */ (interface_number), \
+ /*.bAlternateSetting = */ (alt_setting), \
+ /*.bNumEndpoints = */ (ep_num), \
+ /*.bInterfaceClass = */ APP_USBD_AUDIO_CLASS, \
+ /*.bInterfaceSubClass = */ (subclass), \
+ /*.bInterfaceProtocol = */ APP_USBD_AUDIO_CLASS_PROTOCOL_UNDEFINED, \
+ /*.iInterface = 0, */ 0x00, \
+
+/**
+ * @brief Initializer of isochronous endpoint descriptors for audio class
+ *
+ * @param ep ISO endpoint id: @ref NRF_DRV_USBD_EPIN8, @ref NRF_DRV_USBD_EPOUT8
+ * @param ep_size Endpoint size (bytes)
+ * @param interval Endpoint interval (milliseconds)
+ * @param refresh Refresh value (usually 0)
+ * @param synch_addr Synch address (usually 0)
+ * */
+#define APP_USBD_AUDIO_ISO_EP_DSC(ep, ep_size, interval, refresh, synch_addr) \
+ /*.bLength = */ sizeof(app_usbd_descriptor_ep_t) + 2, \
+ /*.bDescriptorType = */ APP_USBD_DESCRIPTOR_ENDPOINT, \
+ /*.bEndpointAddress = */ ep, \
+ /*.bmAttributes = */ APP_USBD_DESCRIPTOR_EP_ATTR_TYPE_ISOCHRONOUS, \
+ /*.wMaxPacketSize = */ APP_USBD_U16_TO_RAW_DSC(ep_size), \
+ /*.bInterval = */ (interval), \
+ /*.bRefresh = */ (refresh), \
+ /*.bInterval = */ (synch_addr), \
+
+/**
+ * @brief Simplified version of @ref APP_USBD_AUDIO_ISO_EP_DSC for ISO IN endpoint
+ */
+#define APP_USBD_AUDIO_ISO_EP_IN_DSC(ep_size) \
+ APP_USBD_AUDIO_ISO_EP_DSC(NRF_DRV_USBD_EPIN8, ep_size, 1, 0, 0)
+
+/**
+ * @brief Simplified version of @ref APP_USBD_AUDIO_ISO_EP_DSC for ISO OUT endpoint
+ */
+#define APP_USBD_AUDIO_ISO_EP_OUT_DSC(ep_size) \
+ APP_USBD_AUDIO_ISO_EP_DSC(NRF_DRV_USBD_EPOUT8, ep_size, 1, 0, 0)
+
+/**
+ * @brief Initializer of @ref app_usbd_audio_ac_iface_header_desc_t
+ *
+ * @param descriptor_list Descriptor list following audio interface header descriptor
+ * @param ... List of interfaces following audio control interface
+ * */
+#define APP_USBD_AUDIO_AC_IFACE_HEADER_DSC(descriptor_list, ...) \
+ /*.bLength = */ sizeof(app_usbd_audio_ac_iface_header_desc_t) + \
+ (NUM_VA_ARGS(__VA_ARGS__)), \
+ /*.bDescriptorType = */ APP_USBD_AUDIO_DESCRIPTOR_INTERFACE, \
+ /*.bDescriptorSubtype = */ APP_USBD_AUDIO_AC_IFACE_SUBTYPE_HEADER, \
+ /*.bcdADC = */ APP_USBD_U16_TO_RAW_DSC(0x0100), \
+ /*.wTotalLength = */ APP_USBD_U16_TO_RAW_DSC( \
+ sizeof((uint8_t[]){BRACKET_EXTRACT(descriptor_list)}) + \
+ sizeof(app_usbd_audio_ac_iface_header_desc_t) + \
+ (NUM_VA_ARGS(__VA_ARGS__))), \
+ /*.bInCollection = */ (NUM_VA_ARGS(__VA_ARGS__)), \
+ /*.baInterfaceNr[] = */ __VA_ARGS__, \
+
+
+/**
+ * @brief Initializer of @ref app_usbd_audio_input_terminal_desc_t
+ *
+ * @param terminal_id Terminal ID
+ * @param terminal_type Terminal type @ref app_usbd_audio_terminal_type_t
+ * @param nr_channels Number of channels
+ * @param ch_config CHannel config bitmask
+ * */
+#define APP_USBD_AUDIO_INPUT_TERMINAL_DSC(terminal_id, terminal_type, nr_channels, ch_config) \
+ /*.bLength = */ sizeof(app_usbd_audio_input_terminal_desc_t), \
+ /*.bDescriptorType = */ APP_USBD_AUDIO_DESCRIPTOR_INTERFACE, \
+ /*.bDescriptorSubtype = */ APP_USBD_AUDIO_AC_IFACE_SUBTYPE_INPUT_TERMINAL, \
+ /*.bTerminalID = */ (terminal_id), \
+ /*.wTerminalType = */ APP_USBD_U16_TO_RAW_DSC(terminal_type), \
+ /*.bAssocTerminal = */ 0, \
+ /*.bNrChannels = */ (nr_channels), \
+ /*.wChannelConfig = */ APP_USBD_U16_TO_RAW_DSC(ch_config), \
+ /*.iChannelNames = */ 0, \
+ /*.iTerminal = */ 0, \
+
+
+/**
+ * @brief Initializer of @ref app_usbd_audio_output_terminal_desc_t
+ *
+ * @param terminal_id Terminal ID
+ * @param terminal_type Terminal type @ref app_usbd_audio_terminal_type_t
+ * @param source_id Source ID
+ * */
+#define APP_USBD_AUDIO_OUTPUT_TERMINAL_DSC(terminal_id, terminal_type, source_id) \
+ /*.bLength = */ sizeof(app_usbd_audio_output_terminal_desc_t), \
+ /*.bDescriptorType = */ APP_USBD_AUDIO_DESCRIPTOR_INTERFACE, \
+ /*.bDescriptorSubtype = */ APP_USBD_AUDIO_AC_IFACE_SUBTYPE_OUTPUT_TERNINAL, \
+ /*.bTerminalID = */ (terminal_id), \
+ /*.wTerminalType = */ APP_USBD_U16_TO_RAW_DSC(terminal_type), \
+ /*.bAssocTerminal = */ 0, \
+ /*.bSourceID = */ (source_id), \
+ /*.iTerminal = */ 0, \
+
+
+/**
+ * @brief Initializer of @ref app_usbd_audio_feature_unit_desc_t
+ *
+ * @param unit_id Unit ID
+ * @param source_id Source ID
+ * @param ... List of controls
+ * */
+#define APP_USBD_AUDIO_FEATURE_UNIT_DSC(unit_id, source_id, ...) \
+ /*.bLength = */ sizeof(app_usbd_audio_feature_unit_desc_t) + \
+ 1 + (NUM_VA_ARGS(__VA_ARGS__)), \
+ /*.bDescriptorType = */ APP_USBD_AUDIO_DESCRIPTOR_INTERFACE, \
+ /*.bDescriptorSubtype = */ APP_USBD_AUDIO_AC_IFACE_SUBTYPE_FEATURE_UNIT, \
+ /*.bUnitID = */ (unit_id), \
+ /*.bSourceID = */ (source_id), \
+ /*.bControlSize = */ sizeof(uint16_t), \
+ /*.bmaControls[] = */ __VA_ARGS__, \
+ /*.iFeature = */ 0, \
+
+
+/**
+ * @brief Initializer of @ref app_usbd_audio_as_iface_desc_t
+ *
+ * @param terminal_link Terminal link
+ * @param delay Delay
+ * @param format_tag Format TAG
+ * */
+#define APP_USBD_AUDIO_AS_IFACE_DSC(terminal_link, delay, format_tag) \
+ /*.bLength = */ sizeof(app_usbd_audio_as_iface_desc_t), \
+ /*.bDescriptorType = */ APP_USBD_AUDIO_DESCRIPTOR_INTERFACE, \
+ /*.bDescriptorSubtype = */ APP_USBD_AUDIO_AS_IFACE_SUBTYPE_GENERAL, \
+ /*.bTerminalLink = */ (terminal_link), \
+ /*.bDelay = */ (delay), \
+ /*.wFormatTag = */ APP_USBD_U16_TO_RAW_DSC(format_tag), \
+
+/**
+ * @brief Initializer of @ref app_usbd_audio_as_format_type_one_desc_t
+ *
+ * @param nr_channels Number of channels
+ * @param subframe_size Subframe size
+ * @param resolution Bit resolution
+ * @param freq_type Frequency type
+ * @param ... List of frequencies
+ * */
+#define APP_USBD_AUDIO_AS_FORMAT_I_DSC(nr_channels, subframe_size, resolution, freq_type, ...) \
+ /*.bLength = */ sizeof(app_usbd_audio_as_format_type_one_desc_t) + \
+ (NUM_VA_ARGS(__VA_ARGS__)), \
+ /*.bDescriptorType = */ APP_USBD_AUDIO_DESCRIPTOR_INTERFACE, \
+ /*.bDescriptorSubtype = */ APP_USBD_AUDIO_AS_IFACE_SUBTYPE_FORMAT_TYPE, \
+ /*.bFormatType = */ (1), \
+ /*.bNrChannels = */ (nr_channels), \
+ /*.bSubframeSize = */ (subframe_size), \
+ /*.bBitResolution = */ (resolution), \
+ /*.bSamFreqType = */ (freq_type), \
+ /*.tSamFreq = */ __VA_ARGS__, \
+
+/**
+ * @brief Initializer of @ref app_usbd_audio_as_format_type_two_desc_t
+ *
+ * @param max_bitrate Maximum bitrate
+ * @param samples_per_frame Samples per frame
+ * @param freq_type Frequency type
+ * @param ... List of frequencies
+ * */
+#define APP_USBD_AUDIO_AS_FORMAT_II_DSC(max_bitrate, samples_per_frame, freq_type, ...) \
+ /*.bLength = */ sizeof(app_usbd_audio_as_format_type_two_desc_t) + \
+ (NUM_VA_ARGS(__VA_ARGS__)), \
+ /*.bDescriptorType = */ APP_USBD_AUDIO_DESCRIPTOR_INTERFACE, \
+ /*.bDescriptorSubtype = */ APP_USBD_AUDIO_AS_IFACE_SUBTYPE_FORMAT_TYPE, \
+ /*.bFormatType = */ (2), \
+ /*.wMaxBitRate = */ APP_USBD_U16_TO_RAW_DSC(max_bitrate), \
+ /*.wSamplesPerFrame = */ APP_USBD_U16_TO_RAW_DSC(samples_per_frame), \
+ /*.bSamFreqType = */ (freq_type), \
+ /*.tSamFreq = */ __VA_ARGS__, \
+
+/**
+* @brief Initializer of @ref app_usbd_audio_as_format_type_three_desc_t
+ *
+ * @param nr_channels Number of channels
+ * @param subframe_size Subframe size
+ * @param resolution Bit resolution
+ * @param freq_type Frequency type
+ * @param ... List of frequencies
+ * */
+#define APP_USBD_AUDIO_AS_FORMAT_III_DSC(nr_channels, subframe_size, resolution, freq_type, ...) \
+ /*.bLength = */ sizeof(app_usbd_audio_as_format_type_three_desc_t) + \
+ (NUM_VA_ARGS(__VA_ARGS__)), \
+ /*.bDescriptorType = */ APP_USBD_AUDIO_DESCRIPTOR_INTERFACE, \
+ /*.bDescriptorSubtype = */ APP_USBD_AUDIO_AS_IFACE_SUBTYPE_FORMAT_TYPE, \
+ /*.bFormatType = */ (3), \
+ /*.bNrChannels = */ (nr_channels), \
+ /*.bSubframeSize = */ (subframe_size), \
+ /*.bBitResolution = */ (resolution), \
+ /*.bSamFreqType = */ (freq_type), \
+ /*.tSamFreq = */ __VA_ARGS__, \
+
+
+/**
+ * @brief Initializer of @ref app_usbd_audio_as_endpoint_desc_t
+ *
+ * @param attributes Endpoint attributes
+ * @param lock_delay_units Lock delay units
+ * @param lock_delay Lock delay
+ * */
+#define APP_USBD_AUDIO_EP_GENERAL_DSC(attributes, lock_delay_units, lock_delay) \
+ /*.bLength = */ sizeof(app_usbd_audio_as_endpoint_desc_t), \
+ /*.bDescriptorType = */ APP_USBD_AUDIO_DESCRIPTOR_ENDPOINT, \
+ /*.bDescriptorSubtype = */ APP_USBD_AUDIO_EP_SUBTYPE_GENERAL, \
+ /*.bmAttributes = */ (attributes), \
+ /*.bLockDelayUnits = */ (lock_delay_units), \
+ /*.wLockDelay = */ APP_USBD_U16_TO_RAW_DSC(lock_delay), \
+
+/**
+ * @brief Macro to configure Audio Class control descriptor
+ *
+ * @param interface_number Interface number
+ * @param descriptor_list List of descriptors after Audio interface header descriptor
+ * @param interface_list List of interfaces passed to @ref APP_USBD_AUDIO_AC_IFACE_HEADER_DSC
+ * */
+#define APP_USBD_AUDIO_CONTROL_DSC(interface_number, descriptor_list, interface_list) \
+ APP_USBD_AUDIO_INTERFACE_DSC(interface_number, 0, 0, APP_USBD_AUDIO_SUBCLASS_AUDIOCONTROL) \
+ APP_USBD_AUDIO_AC_IFACE_HEADER_DSC(descriptor_list, BRACKET_EXTRACT(interface_list)) \
+ BRACKET_EXTRACT(descriptor_list)
+
+
+/**
+ * @brief Macro to configure Audio Class streaming descriptor
+ *
+ * @param interface_number Interface number
+ * @param alt_setting Alternate interface setting
+ * @param ep_num Number of endpoints
+ */
+#define APP_USBD_AUDIO_STREAMING_DSC(interface_number, alt_setting, ep_num) \
+ APP_USBD_AUDIO_INTERFACE_DSC(interface_number, alt_setting, ep_num, \
+ APP_USBD_AUDIO_SUBCLASS_AUDIOSTREAMING)
+
+/**
+ * @brief Macro to configure Audio Class MIDI streaming descriptor
+ *
+ * @param interface_number Interface number
+ * @param alt_setting Alternate interface setting
+ * @param ep_num Number of endpoints
+ */
+#define APP_USBD_AUDIO_MIDI_STREAMING_DSC(interface_number, alt_setting, ep_num) \
+ APP_USBD_AUDIO_INTERFACE_DSC(interface_number, alt_setting, ep_num, \
+ APP_USBD_AUDIO_SUBCLASS_MIDISTREAMING)
+
+
+/** @} */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* APP_USBD_AUDIO_DESC_H__ */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/usbd/class/audio/app_usbd_audio_internal.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/usbd/class/audio/app_usbd_audio_internal.h
new file mode 100644
index 0000000..c3371b2
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/usbd/class/audio/app_usbd_audio_internal.h
@@ -0,0 +1,284 @@
+/**
+ * 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#ifndef APP_USBD_AUDIO_INTERNAL_H__
+#define APP_USBD_AUDIO_INTERNAL_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @defgroup app_usbd_audio_internal USB Audio internals
+ * @brief @tagAPI52840 USB Audio class internals.
+ * @ingroup app_usbd_audio
+ * @{
+ */
+
+/**
+ * @brief Forward declaration of type defined by @ref APP_USBD_CLASS_TYPEDEF in audio class
+ *
+ */
+APP_USBD_CLASS_FORWARD(app_usbd_audio);
+
+/*lint -save -e165*/
+/**
+ * @brief Forward declaration of @ref app_usbd_audio_user_event_e
+ *
+ */
+enum app_usbd_audio_user_event_e;
+
+/*lint -restore*/
+
+/**
+ * @brief User event handler
+ *
+ * @param[in] p_inst Class instance
+ * @param[in] event User event
+ *
+ */
+typedef void (*app_usbd_audio_user_ev_handler_t)(app_usbd_class_inst_t const * p_inst,
+ enum app_usbd_audio_user_event_e event);
+
+
+/**
+* @brief Audio subclass descriptor.
+*/
+
+typedef struct {
+ size_t size;
+ uint8_t type;
+ uint8_t const * const p_data;
+} app_usbd_audio_subclass_desc_t;
+
+/**
+ * @brief Audio class part of class instance data
+ */
+typedef struct {
+
+ app_usbd_audio_subclass_desc_t const * const p_format_dsc; //!< Audio class Format descriptor
+ app_usbd_audio_subclass_desc_t const * const p_input_dsc; //!< Audio class Input Terminal descriptor
+ app_usbd_audio_subclass_desc_t const * const p_output_dsc; //!< Audio class Output Terminal descriptor
+ app_usbd_audio_subclass_desc_t const * const p_feature_dsc; //!< Audio class Feature Unit descriptor
+
+ uint8_t delay; //!< Streaming delay
+ uint16_t format; //!< FormatTag (@ref app_usbd_audio_as_iface_format_tag_t)
+ uint16_t ep_size; //!< Endpoint size
+
+ app_usbd_audio_subclass_t type_streaming; //Streaming type MIDISTREAMING/AUDIOSTREAMING (@ref app_usbd_audio_subclass_t)
+
+ app_usbd_audio_user_ev_handler_t user_ev_handler; //!< User event handler
+} app_usbd_audio_inst_t;
+
+/**
+ * @brief Audio class request target
+ */
+typedef enum {
+ APP_USBD_AUDIO_CLASS_REQ_IN, /**< Audio class request IN */
+ APP_USBD_AUDIO_CLASS_REQ_OUT, /**< Audio class request OUT */
+ APP_USBD_AUDIO_EP_REQ_IN, /**< Audio class endpoint request IN */
+ APP_USBD_AUDIO_EP_REQ_OUT, /**< Audio class endpoint request OUT */
+} app_usbd_audio_class_req_target_t;
+
+/**
+ * @brief Audio class specific request handled via control endpoint
+ */
+typedef struct {
+ app_usbd_audio_class_req_target_t req_target; //!< Request target
+ app_usbd_audio_req_type_t req_type; //!< Request type
+
+ uint8_t control; //!< Request control field
+ uint8_t channel; //!< Channel ID
+ uint8_t interface; //!< Interface ID
+ uint8_t entity; //!< Entity ID
+ uint16_t length; //!< Request payload length
+
+ uint8_t payload[64]; //!< Request payload
+} app_usbd_audio_req_t;
+
+
+/**
+ * @brief Audio class context
+ *
+ */
+typedef struct {
+ app_usbd_audio_req_t request; //!< Audio class request
+ bool streaming; //!< Streaming flag
+} app_usbd_audio_ctx_t;
+
+
+/**
+ * @brief Audio class configuration macro
+ *
+ * Used by @ref APP_USBD_AUDIO_GLOBAL_DEF
+ *
+ * @param iface_control Interface number of audio control
+ * @param iface_stream Interface number of audio stream
+ */
+#define APP_USBD_AUDIO_CONFIG(iface_control, iface_stream) \
+ ((iface_control), \
+ (iface_stream, 0))
+
+/**
+ * @brief Only IN audio stream configuration
+ *
+ * @param iface_control Interface number of audio control
+ * @param iface_stream_in Interface number of audio stream on IN endpoint
+ */
+#define APP_USBD_AUDIO_CONFIG_IN(iface_control, iface_stream_in) \
+ ((iface_control), (iface_stream_in, NRF_DRV_USBD_EPIN8))
+
+
+/**
+ * @brief Only OUT audio stream configuration
+ *
+ * @param iface_control Interface number of audio control
+ * @param iface_stream_out Interface number of audio stream on OUT endpoint
+ */
+#define APP_USBD_AUDIO_CONFIG_OUT(iface_control, iface_stream_out) \
+ ((iface_control), (iface_stream_out, NRF_DRV_USBD_EPOUT8))
+
+/**
+ * @brief Specific class constant data for audio class
+ *
+ * @ref app_usbd_audio_inst_t
+ */
+#define APP_USBD_AUDIO_INSTANCE_SPECIFIC_DEC app_usbd_audio_inst_t inst;
+
+/**
+ * @brief Configures audio class instance
+ *
+ * @param user_event_handler User event handler
+ * @param format_descriptor Audio class Format descriptor
+ * @param input_descriptor Audio class Input Terminal descriptor
+ * @param output_descriptor Audio class Output Terminal descriptor
+ * @param feature_descriptor Audio class Feature Unit descriptor
+ * @param dlay Streaming delay
+ * @param frmat FormatTag (@ref app_usbd_audio_as_iface_format_tag_t)
+ * @param ep_siz Endpoint size
+ * @param type_str Streaming type MIDISTREAMING/AUDIOSTREAMING
+ */
+ #define APP_USBD_AUDIO_INST_CONFIG(user_event_handler, \
+ format_descriptor, \
+ input_descriptor, \
+ output_descriptor, \
+ feature_descriptor, \
+ dlay, \
+ frmat, \
+ ep_siz, \
+ type_str) \
+ .inst = { \
+ .user_ev_handler = user_event_handler, \
+ .p_format_dsc = format_descriptor, \
+ .p_input_dsc = input_descriptor, \
+ .p_output_dsc = output_descriptor, \
+ .p_feature_dsc = feature_descriptor, \
+ .delay = dlay, \
+ .format = frmat, \
+ .ep_size = ep_siz, \
+ .type_streaming = type_str \
+ }
+
+/**
+ * @brief Specific class data for audio class
+ *
+ * @ref app_usbd_audio_ctx_t
+ */
+#define APP_USBD_AUDIO_DATA_SPECIFIC_DEC app_usbd_audio_ctx_t ctx;
+
+
+/**
+ * @brief Audio class descriptors config macro
+ *
+ * @param interface_number Interface number
+ * @param ... Extracted endpoint list
+ */
+#define APP_USBD_AUDIO_DSC_CONFIG(interface_number, ...) { \
+ APP_USBD_AUDIO_INTERFACE_DSC(interface_number, \
+ 0, \
+ 0, \
+ APP_USBD_AUDIO_SUBCLASS_AUDIOCONTROL) \
+ }
+
+/**
+ * @brief Public audio class interface
+ *
+ */
+extern const app_usbd_class_methods_t app_usbd_audio_class_methods;
+
+/**
+ * @brief Global definition of @ref app_usbd_audio_t class
+ *
+ */
+ #define APP_USBD_AUDIO_GLOBAL_DEF_INTERNAL(instance_name, \
+ interfaces_configs, \
+ user_ev_handler, \
+ format_descriptor, \
+ input_descriptor, \
+ output_descriptor, \
+ feature_descriptor, \
+ delay, \
+ format, \
+ ep_size, \
+ type_str) \
+ APP_USBD_CLASS_INST_GLOBAL_DEF( \
+ instance_name, \
+ app_usbd_audio, \
+ &app_usbd_audio_class_methods, \
+ interfaces_configs, \
+ (APP_USBD_AUDIO_INST_CONFIG(user_ev_handler, \
+ format_descriptor, \
+ input_descriptor, \
+ output_descriptor, \
+ feature_descriptor, \
+ delay, \
+ format, \
+ ep_size, \
+ type_str)) \
+ )
+
+
+/** @} */
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* APP_USBD_AUDIO_INTERNAL_H__ */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/usbd/class/audio/app_usbd_audio_types.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/usbd/class/audio/app_usbd_audio_types.h
new file mode 100644
index 0000000..57fd902
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/usbd/class/audio/app_usbd_audio_types.h
@@ -0,0 +1,382 @@
+/**
+ * Copyright (c) 2016 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#ifndef APP_USBD_AUDIO_TYPES_H__
+#define APP_USBD_AUDIO_TYPES_H__
+
+#include "app_util.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @defgroup app_usbd_audio_types USB Audio types
+ * @brief @tagAPI52840 Type definitions for the USB Audio class.
+ * @ingroup app_usbd_audio
+ * @{
+ */
+
+/** @brief Audio class definition in interface descriptor
+ *
+ * Fixed value, @ref app_usbd_descriptor_iface_t::bInterfaceClass
+ * */
+#define APP_USBD_AUDIO_CLASS 0x01
+
+/** @brief Audio class protocol definition in interface descriptor
+ *
+ * Fixed value, @ref app_usbd_descriptor_iface_t::bInterfaceProtocol
+ * */
+#define APP_USBD_AUDIO_CLASS_PROTOCOL_UNDEFINED 0x00
+
+/**
+ * @brief Audio subclass possible values
+ *
+ * @ref app_usbd_descriptor_iface_t::bInterfaceSubClass
+ */
+typedef enum {
+ APP_USBD_AUDIO_SUBCLASS_UNDEFINED = 0x00, /**< UNDEFINED subclass */
+ APP_USBD_AUDIO_SUBCLASS_AUDIOCONTROL, /**< AUDIOCONTROL subclass */
+ APP_USBD_AUDIO_SUBCLASS_AUDIOSTREAMING, /**< AUDIOSTREAMING subclass */
+ APP_USBD_AUDIO_SUBCLASS_MIDISTREAMING /**< MIDISTREAMING subclass */
+} app_usbd_audio_subclass_t;
+
+
+/**
+ * @brief Audio class specific descriptor types
+ */
+typedef enum {
+ APP_USBD_AUDIO_DESCRIPTOR_UNDEFINED = 0x20, /**< UNDEFINED descriptor type */
+ APP_USBD_AUDIO_DESCRIPTOR_DEVICE = 0x21, /**< DEVICE descriptor type */
+ APP_USBD_AUDIO_DESCRIPTOR_CONFIGURATION = 0x22, /**< CONFIGURATION descriptor type */
+ APP_USBD_AUDIO_DESCRIPTOR_STRING = 0x23, /**< STRING descriptor type */
+ APP_USBD_AUDIO_DESCRIPTOR_INTERFACE = 0x24, /**< INTERFACE descriptor type */
+ APP_USBD_AUDIO_DESCRIPTOR_ENDPOINT = 0x25, /**< ENDPOINT descriptor type */
+} app_usbd_audio_descriptor_type_t;
+
+
+/**
+ * @brief Audio control interface subtype
+ */
+typedef enum {
+ APP_USBD_AUDIO_AC_IFACE_SUBTYPE_UNDEFINED = 0x00, /**< Audio control interface subtype UNDEFINED */
+ APP_USBD_AUDIO_AC_IFACE_SUBTYPE_HEADER, /**< Audio control interface subtype HEADER */
+ APP_USBD_AUDIO_AC_IFACE_SUBTYPE_INPUT_TERMINAL, /**< Audio control interface subtype INPUT_TERMINAL */
+ APP_USBD_AUDIO_AC_IFACE_SUBTYPE_OUTPUT_TERNINAL, /**< Audio control interface subtype OUTPUT_TERNINAL */
+ APP_USBD_AUDIO_AC_IFACE_SUBTYPE_MIXER_UNIT, /**< Audio control interface subtype MIXER_UNIT */
+ APP_USBD_AUDIO_AC_IFACE_SUBTYPE_SELECTOR_UNIT, /**< Audio control interface subtype SELECTOR_UNIT */
+ APP_USBD_AUDIO_AC_IFACE_SUBTYPE_FEATURE_UNIT, /**< Audio control interface subtype FEATURE_UNIT */
+ APP_USBD_AUDIO_AC_IFACE_SUBTYPE_PROCESSING_UNIT, /**< Audio control interface subtype PROCESSING_UNIT */
+ APP_USBD_AUDIO_AC_IFACE_SUBTYPE_EXTENSION_UNIT, /**< Audio control interface subtype EXTENSION_UNIT */
+} app_usbd_audio_ac_iface_subtype_t;
+
+/**
+ * @brief Audio streaming interface subtype
+ */
+typedef enum {
+ APP_USBD_AUDIO_AS_IFACE_SUBTYPE_UNDEFINED = 0x00, /**< Audio streaming interface subtype UNDEFINED */
+ APP_USBD_AUDIO_AS_IFACE_SUBTYPE_GENERAL, /**< Audio streaming interface subtype GENERAL */
+ APP_USBD_AUDIO_AS_IFACE_SUBTYPE_FORMAT_TYPE, /**< Audio streaming interface subtype FORMAT_TYPE */
+ APP_USBD_AUDIO_AS_IFACE_SUBTYPE_FORMAT_SPECIFIC, /**< Audio streaming interface subtype FORMAT_SPECIFIC*/
+} app_usbd_audio_as_iface_subtype_t;
+
+
+/**
+ * @brief Audio class specific endpoint subtypes
+ */
+typedef enum {
+ APP_USBD_AUDIO_EP_SUBTYPE_UNDEFINED = 0x00, /**< APP_USBD_AUDIO_EP_SUBTYPE_UNDEFINED */
+ APP_USBD_AUDIO_EP_SUBTYPE_GENERAL, /**< APP_USBD_AUDIO_EP_SUBTYPE_GENERAL */
+} app_usbd_audio_ep_subtype_t;
+
+/**
+ * @brief Audio class specific requests
+ *
+ * @ref nrf_drv_usbd_setup_t::bmRequestType
+ */
+typedef enum {
+ APP_USBD_AUDIO_REQ_UNDEFINED = 0x00, /**< UNDEFINED request*/
+
+ APP_USBD_AUDIO_REQ_SET_CUR = 0x01, /**< SET_CUR request */
+ APP_USBD_AUDIO_REQ_SET_MIN = 0x02, /**< SET_MIN request */
+ APP_USBD_AUDIO_REQ_SET_MAX = 0x03, /**< SET_MAX request */
+ APP_USBD_AUDIO_REQ_SET_RES = 0x04, /**< SET_RES request */
+ APP_USBD_AUDIO_REQ_SET_MEM = 0x05, /**< SET_MEM request */
+
+ APP_USBD_AUDIO_REQ_GET_CUR = 0x81, /**< GET_CUR request */
+ APP_USBD_AUDIO_REQ_GET_MIN = 0x82, /**< GET_MIN request */
+ APP_USBD_AUDIO_REQ_GET_MAX = 0x83, /**< GET_MAX request */
+ APP_USBD_AUDIO_REQ_GET_RES = 0x84, /**< GET_RES request */
+ APP_USBD_AUDIO_REQ_GET_MEM = 0x85, /**< GET_MEM request */
+
+ APP_USBD_AUDIO_REQ_GET_STAT = 0xFF, /**< GET_STAT request */
+} app_usbd_audio_req_type_t;
+
+/**
+ * @brief Audio class terminal types
+ * */
+typedef enum {
+ /*USB terminals*/
+ APP_USBD_AUDIO_TERMINAL_USB_UNDEFINED = 0x0100, /**< USB_UNDEFINED*/
+ APP_USBD_AUDIO_TERMINAL_USB_STREAMING = 0x0101, /**< USB_STREAMING */
+ APP_USBD_AUDIO_TERMINAL_USB_VENDOR_SPEC = 0x01FF, /**< USB_VENDOR_SPEC*/
+
+ /*Input terminals*/
+ APP_USBD_AUDIO_TERMINAL_IN_UNDEFINED = 0x0200, /**< UNDEFINED */
+ APP_USBD_AUDIO_TERMINAL_IN_MICROPHONE = 0x0201, /**< MICROPHONE */
+ APP_USBD_AUDIO_TERMINAL_IN_DESKTOP_MIC = 0x0202, /**< DESKTOP_MIC */
+ APP_USBD_AUDIO_TERMINAL_IN_PERSONAL_MIC = 0x0203, /**< PERSONAL_MIC */
+ APP_USBD_AUDIO_TERMINAL_IN_OM_DIR_MIC = 0x0204, /**< OM_DIR_MIC */
+ APP_USBD_AUDIO_TERMINAL_IN_MIC_ARRAY = 0x0205, /**< MIC_ARRAY */
+ APP_USBD_AUDIO_TERMINAL_IN_PROC_MIC_ARRAY = 0x0205, /**< PROC_MIC_ARRAY */
+
+ /*Output terminals*/
+ APP_USBD_AUDIO_TERMINAL_OUT_UNDEFINED = 0x0300, /**< UNDEFINED */
+ APP_USBD_AUDIO_TERMINAL_OUT_SPEAKER = 0x0301, /**< SPEAKER */
+ APP_USBD_AUDIO_TERMINAL_OUT_HEADPHONES = 0x0302, /**< HEADPHONES */
+ APP_USBD_AUDIO_TERMINAL_OUT_HEAD_AUDIO = 0x0303, /**< HEAD_AUDIO */
+ APP_USBD_AUDIO_TERMINAL_OUT_DESKTOP_SPEAKER = 0x0304, /**< DESKTOP_SPEAKER */
+ APP_USBD_AUDIO_TERMINAL_OUT_ROOM_SPEAKER = 0x0305, /**< ROOM_SPEAKER */
+ APP_USBD_AUDIO_TERMINAL_OUT_COMM_SPEAKER = 0x0306, /**< COMM_SPEAKER */
+ APP_USBD_AUDIO_TERMINAL_OUT_LOW_FREQ_SPEAKER = 0x0307, /**< LOW_FREQ_SPEAKER */
+
+ /*Input/Output terminals*/
+ APP_USBD_AUDIO_TERMINAL_IO_UNDEFINED = 0x0400, /**< UNDEFINED */
+ APP_USBD_AUDIO_TERMINAL_IO_HANDSET = 0x0401, /**< HANDSET */
+ APP_USBD_AUDIO_TERMINAL_IO_HEADSET = 0x0402, /**< HEADSET */
+ APP_USBD_AUDIO_TERMINAL_IO_SPEAKERPHONE_ECHO_NONE = 0x0403, /**< SPEAKERPHONE_ECHO_NONE */
+ APP_USBD_AUDIO_TERMINAL_IO_SPEAKERPHONE_ECHO_SUP = 0x0404, /**< SPEAKERPHONE_ECHO_SUP */
+ APP_USBD_AUDIO_TERMINAL_IO_SPEAKERPHONE_ECHO_CAN = 0x0405, /**< SPEAKERPHONE_ECHO_CAN */
+} app_usbd_audio_terminal_type_t;
+
+/**
+ * @brief Audio class control interface header descriptor
+ */
+typedef struct {
+ uint8_t bLength; //!< Length of the descriptor
+ uint8_t bDescriptorType; //!< Descriptor type @ref APP_USBD_AUDIO_DESCRIPTOR_INTERFACE
+ uint8_t bDescriptorSubType; //!< Descriptor subtype @ref APP_USBD_AUDIO_AC_IFACE_SUBTYPE_HEADER
+ uint8_t bcdADC[2]; //!< BCD ADC
+ uint8_t wTotalLength[2]; //!< Total interfaces length
+ uint8_t bInCollection; //!< Input collection
+ uint8_t baInterfaceNr[]; //!< Interface number list
+} app_usbd_audio_ac_iface_header_desc_t;
+
+
+/**
+ * @brief Possible values of input terminal channel config
+ *
+ * @ref app_usbd_audio_input_terminal_desc_t::wChannelConfig
+ * */
+typedef enum {
+ APP_USBD_AUDIO_IN_TERM_CH_CONFIG_LEFT_FRONT = (1u << 0), /**< Channel config bit LEFT_FRONT */
+ APP_USBD_AUDIO_IN_TERM_CH_CONFIG_RIGHT_FRONT = (1u << 1), /**< Channel config bit RIGHT_FRONT */
+ APP_USBD_AUDIO_IN_TERM_CH_CONFIG_CENTER_FRONT = (1u << 2), /**< Channel config bit CENTER_FRONT */
+ APP_USBD_AUDIO_IN_TERM_CH_CONFIG_LOW_FREQ_ENH = (1u << 3), /**< Channel config bit LOW_FREQ_ENH */
+ APP_USBD_AUDIO_IN_TERM_CH_CONFIG_LEFT_SURROUND = (1u << 4), /**< Channel config bit LEFT_SURROUND */
+ APP_USBD_AUDIO_IN_TERM_CH_CONFIG_RIGHT_SURROUND = (1u << 5), /**< Channel config bit RIGHT_SURROUND */
+ APP_USBD_AUDIO_IN_TERM_CH_CONFIG_LEFT_OF_CENTER = (1u << 6), /**< Channel config bit LEFT_OF_CENTER */
+ APP_USBD_AUDIO_IN_TERM_CH_CONFIG_RIGHT_OF_CENTER = (1u << 7), /**< Channel config bit RIGHT_OF_CENTER */
+ APP_USBD_AUDIO_IN_TERM_CH_CONFIG_SURROUND = (1u << 8), /**< Channel config bit SURROUND */
+ APP_USBD_AUDIO_IN_TERM_CH_CONFIG_SIDE_LEFT = (1u << 9), /**< Channel config bit SIDE_LEFT */
+ APP_USBD_AUDIO_IN_TERM_CH_CONFIG_SIDE_RIGHT = (1u << 10), /**< Channel config bit SIDE_RIGHT */
+ APP_USBD_AUDIO_IN_TERM_CH_CONFIG_TOP = (1u << 11), /**< Channel config bit TOP */
+} app_usbd_audio_in_term_ch_config_t;
+
+/**
+ * @brief Audio class input terminal descriptor
+ */
+typedef struct {
+ uint8_t bLength; //!< Length of the descriptor
+ uint8_t bDescriptorType; //!< Descriptor type @ref APP_USBD_AUDIO_DESCRIPTOR_INTERFACE
+ uint8_t bDescriptorSubType; //!< Descriptor subtype @ref APP_USBD_AUDIO_AC_IFACE_SUBTYPE_INPUT_TERMINAL
+ uint8_t bTerminalID; //!< Terminal ID
+ uint8_t wTerminalType[2]; //!< Terminal type
+ uint8_t bAssocTerminal; //!< Association terminal
+ uint8_t bNrChannels; //!< Number of channels
+ uint8_t wChannelConfig[2]; //!< Channel config
+ uint8_t iChannelNames; //!< Channel names
+ uint8_t iTerminal; //!< Terminal string ID
+} app_usbd_audio_input_terminal_desc_t;
+
+/**
+ * @brief Audio class output terminal descriptor
+ */
+typedef struct {
+ uint8_t bLength; //!< Length of the descriptor
+ uint8_t bDescriptorType; //!< Descriptor type @ref APP_USBD_AUDIO_DESCRIPTOR_INTERFACE
+ uint8_t bDescriptorSubType; //!< Descriptor subtype @ref APP_USBD_AUDIO_AC_IFACE_SUBTYPE_OUTPUT_TERNINAL
+ uint8_t bTerminalID; //!< Terminal ID
+ uint8_t wTerminalType[2]; //!< Terminal type
+ uint8_t bAssocTerminal; //!< Association terminal
+ uint8_t bSourceID; //!< Source ID
+ uint8_t iTerminal; //!< Terminal string ID
+} app_usbd_audio_output_terminal_desc_t;
+
+/**
+ * @brief Possible values of feature unit control field*/
+typedef enum {
+ APP_USBD_AUDIO_FEATURE_UNIT_CONTROL_MUTE = (1u << 0), /**< Feature unit control bit MUTE */
+ APP_USBD_AUDIO_FEATURE_UNIT_CONTROL_VOLUME = (1u << 1), /**< Feature unit control bit VOLUME */
+ APP_USBD_AUDIO_FEATURE_UNIT_CONTROL_BASS = (1u << 2), /**< Feature unit control bit BASS */
+ APP_USBD_AUDIO_FEATURE_UNIT_CONTROL_MID = (1u << 3), /**< Feature unit control bit MID */
+ APP_USBD_AUDIO_FEATURE_UNIT_CONTROL_TREBLE = (1u << 4), /**< Feature unit control bit TREBLE */
+ APP_USBD_AUDIO_FEATURE_UNIT_CONTROL_GRAPH_EQ = (1u << 5), /**< Feature unit control bit GRAPH_EQ */
+ APP_USBD_AUDIO_FEATURE_UNIT_CONTROL_AUTO_GAIN = (1u << 6), /**< Feature unit control bit AUTO_GAIN */
+ APP_USBD_AUDIO_FEATURE_UNIT_CONTROL_DELAY = (1u << 7), /**< Feature unit control bit DELAY */
+ APP_USBD_AUDIO_FEATURE_UNIT_CONTROL_BASS_BOOST = (1u << 8), /**< Feature unit control bit BASS_BOOST*/
+ APP_USBD_AUDIO_FEATURE_UNIT_CONTROL_LOUDNESS = (1u << 9), /**< Feature unit control bit LOUDNESS */
+} app_usbd_audio_feature_unit_control_t;
+
+/**
+ * @brief Audio class feature unit descriptor
+ */
+typedef struct {
+ uint8_t bLength; //!< Length of the descriptor
+ uint8_t bDescriptorType; //!< Descriptor type @ref APP_USBD_AUDIO_DESCRIPTOR_INTERFACE
+ uint8_t bDescriptorSubType; //!< Descriptor subtype @ref APP_USBD_AUDIO_AC_IFACE_SUBTYPE_FEATURE_UNIT
+ uint8_t bUnitID; //!< Unit ID
+ uint8_t bSourceID; //!< Source ID
+ uint8_t bControlSize; //!< Control size
+ uint8_t bmaControls[]; //!< Controls array
+} app_usbd_audio_feature_unit_desc_t;
+
+/**
+ * @brief Format tag in audio streaming interface descriptor
+ *
+ * @ref app_usbd_audio_as_iface_desc_t::wFormatTag
+ * */
+typedef enum {
+ APP_USBD_AUDIO_AS_IFACE_FORMAT_TYPE_I_UNDEFINED = 0x0000, /**< AS format TYPE_I_UNDEFINED */
+ APP_USBD_AUDIO_AS_IFACE_FORMAT_PCM = 0x0001, /**< AS format PCM */
+ APP_USBD_AUDIO_AS_IFACE_FORMAT_PCM8 = 0x0002, /**< AS format PCM8 */
+ APP_USBD_AUDIO_AS_IFACE_FORMAT_IEEE_FLOAT = 0x0003, /**< AS format IEEE_FLOAT */
+ APP_USBD_AUDIO_AS_IFACE_FORMAT_ALAW = 0x0004, /**< AS format ALAW */
+ APP_USBD_AUDIO_AS_IFACE_FORMAT_MULAW = 0x0005, /**< AS format MULAW */
+
+ APP_USBD_AUDIO_AS_IFACE_FORMAT_TYPE_II_UNDEFINED = 0x1000, /**< AS format TYPE_II_UNDEFINED */
+ APP_USBD_AUDIO_AS_IFACE_FORMAT_MPEG = 0x1001, /**< AS format MPEG */
+ APP_USBD_AUDIO_AS_IFACE_FORMAT_AC3 = 0x1002, /**< AS format AC3 */
+
+ APP_USBD_AUDIO_AS_IFACE_FORMAT_TYPE_III_UNDEFINED = 0x2000, /**< AS format TYPE_III_UNDEFINED */
+ APP_USBD_AUDIO_AS_IFACE_FORMAT_IEC1937_AC_3 = 0x2001, /**< AS format IEC1937_AC_3 */
+ APP_USBD_AUDIO_AS_IFACE_FORMAT_IEC1937_MPEG_1_LAYER1 = 0x2002, /**< AS format IEC1937_MPEG_1_LAYER1 */
+ APP_USBD_AUDIO_AS_IFACE_FORMAT_IEC1937_MPEG_2_NOEXT = 0x2003, /**< AS format IEC1937_MPEG_2_NOEXT */
+ APP_USBD_AUDIO_AS_IFACE_FORMAT_IEC1937_MPEG_2_EXT = 0x2004, /**< AS format IEC1937_MPEG_2_EXT */
+ APP_USBD_AUDIO_AS_IFACE_FORMAT_IEC1937_MPEG_2_LAYER1_LS = 0x2005, /**< AS format IEC1937_MPEG_2_LAYER1_LS */
+ APP_USBD_AUDIO_AS_IFACE_FORMAT_IEC1937_MPEG_2_LAYER23_LS = 0x2005, /**< AS format IEC1937_MPEG_2_LAYER23_LS */
+} app_usbd_audio_as_iface_format_tag_t;
+
+/**
+ * @brief Audio class audio streaming interface descriptor
+ */
+typedef struct {
+ uint8_t bLength; //!< Length of the descriptor
+ uint8_t bDescriptorType; //!< Descriptor type @ref APP_USBD_AUDIO_DESCRIPTOR_INTERFACE
+ uint8_t bDescriptorSubType; //!< Descriptor subtype @ref app_usbd_audio_ac_iface_subtype_t
+ uint8_t bTerminalLink; //!< Terminal link
+ uint8_t bDelay; //!< Delay
+ uint8_t wFormatTag[2]; //!< Format TAG
+} app_usbd_audio_as_iface_desc_t;
+
+/**
+ * @brief Audio class audio streaming format type I descriptor
+ */
+typedef struct {
+ uint8_t bLength; //!< Length of the descriptor
+ uint8_t bDescriptorType; //!< Descriptor type @ref APP_USBD_AUDIO_DESCRIPTOR_INTERFACE
+ uint8_t bDescriptorSubType; //!< Descriptor subtype @ref app_usbd_audio_as_iface_subtype_t
+ uint8_t bFormatType; //!< Format type: fixed value 1
+ uint8_t bNrChannels; //!< Number of channels
+ uint8_t bSubframeSize; //!< Subframe size
+ uint8_t bBitResolution; //!< Bit resolution
+ uint8_t bSamFreqType; //!< Number of supported sampling frequencies
+ uint8_t tSamFreq[]; //!< Number of supported sampling frequencies table (24 bit entries)
+} app_usbd_audio_as_format_type_one_desc_t;
+
+
+/**
+ * @brief Audio class audio streaming format type II descriptor
+ */
+typedef struct {
+ uint8_t bLength; //!< Length of the descriptor
+ uint8_t bDescriptorType; //!< Descriptor type @ref APP_USBD_AUDIO_DESCRIPTOR_INTERFACE
+ uint8_t bDescriptorSubType; //!< Descriptor subtype @ref app_usbd_audio_as_iface_subtype_t
+ uint8_t bFormatType; //!< Format type: fixed value 2
+ uint8_t wMaxBitRate[2]; //!< Maximum bitrate
+ uint8_t wSamplesPerFrame[2]; //!< Samples per frame
+ uint8_t bSamFreqType; //!< Number of supported sampling frequencies
+ uint8_t tSamFreq[]; //!< Number of supported sampling frequencies table (24 bit entries)
+} app_usbd_audio_as_format_type_two_desc_t;
+
+/**
+ * @brief Audio class audio streaming format type III descriptor
+ */
+typedef struct {
+ uint8_t bLength; //!< Length of the descriptor
+ uint8_t bDescriptorType; //!< Descriptor type @ref APP_USBD_AUDIO_DESCRIPTOR_INTERFACE
+ uint8_t bDescriptorSubType; //!< Descriptor subtype @ref app_usbd_audio_as_iface_subtype_t
+ uint8_t bFormatType; //!< Format type: fixed value 1
+ uint8_t bNrChannels; //!< Number of channels
+ uint8_t bSubframeSize; //!< Subframe size
+ uint8_t bBitResolution; //!< Bit resolution
+ uint8_t bSamFreqType; //!< Number of supported sampling frequencies
+ uint8_t tSamFreq[]; //!< Number of supported sampling frequencies table (24 bit entries)
+} app_usbd_audio_as_format_type_three_desc_t;
+
+/**
+ * @brief Audio class audio endpoint descriptor
+ */
+typedef struct {
+ uint8_t bLength; //!< Length of the descriptor
+ uint8_t bDescriptorType; //!< Descriptor type @ref APP_USBD_AUDIO_DESCRIPTOR_ENDPOINT
+ uint8_t bDescriptorSubType; //!< Descriptor subtype @ref APP_USBD_AUDIO_EP_SUBTYPE_GENERAL
+ uint8_t bmAttributes; //!< Audio endpoint attributes
+ uint8_t bLockDelayUnits; //!< Lock delay units
+ uint8_t wLockDelay[2]; //!< Lock delay value
+} app_usbd_audio_as_endpoint_desc_t;
+
+/** @} */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* APP_USBD_AUDIO_TYPES_H__ */
+
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/usbd/class/cdc/acm/app_usbd_cdc_acm.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/usbd/class/cdc/acm/app_usbd_cdc_acm.c
new file mode 100644
index 0000000..3df941c
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/usbd/class/cdc/acm/app_usbd_cdc_acm.c
@@ -0,0 +1,1190 @@
+/**
+ * Copyright (c) 2016 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#include "sdk_common.h"
+#if NRF_MODULE_ENABLED(APP_USBD_CDC_ACM)
+
+#include "app_usbd_cdc_acm.h"
+#include <inttypes.h>
+
+/**
+ * @defgroup app_usbd_cdc_acm_internal CDC ACM internals
+ * @{
+ * @ingroup app_usbd_cdc
+ * @internal
+ */
+
+
+#define NRF_LOG_MODULE_NAME cdc_acm
+
+#if APP_USBD_CDC_ACM_CONFIG_LOG_ENABLED
+#define NRF_LOG_LEVEL APP_USBD_CDC_ACM_CONFIG_LOG_LEVEL
+#define NRF_LOG_INFO_COLOR APP_USBD_CDC_ACM_CONFIG_INFO_COLOR
+#define NRF_LOG_DEBUG_COLOR APP_USBD_CDC_ACM_CONFIG_DEBUG_COLOR
+#else //APP_USBD_CDC_ACM_CONFIG_LOG_ENABLED
+#define NRF_LOG_LEVEL 0
+#endif //APP_USBD_CDC_ACM_CONFIG_LOG_ENABLED
+#include "nrf_log.h"
+NRF_LOG_MODULE_REGISTER();
+
+#define APP_USBD_CDC_ACM_COMM_IFACE_IDX 0 /**< CDC ACM class comm interface index. */
+#define APP_USBD_CDC_ACM_DATA_IFACE_IDX 1 /**< CDC ACM class data interface index. */
+
+#define APP_USBD_CDC_ACM_COMM_EPIN_IDX 0 /**< CDC ACM comm class endpoint IN index. */
+#define APP_USBD_CDC_ACM_DATA_EPIN_IDX 0 /**< CDC ACM data class endpoint IN index. */
+#define APP_USBD_CDC_ACM_DATA_EPOUT_IDX 1 /**< CDC ACM data class endpoint OUT index. */
+
+/**
+ * @brief Auxiliary function to access cdc_acm class instance data.
+ *
+ * @param[in] p_inst Class instance data.
+ *
+ * @return CDC ACM class instance.
+ */
+static inline app_usbd_cdc_acm_t const * cdc_acm_get(app_usbd_class_inst_t const * p_inst)
+{
+ ASSERT(p_inst != NULL);
+ return (app_usbd_cdc_acm_t const *)p_inst;
+}
+
+/**
+ * @brief Auxiliary function to access cdc_acm class context data.
+ *
+ * @param[in] p_cdc_acm CDC ACM class instance data.
+ *
+ * @return CDC ACM class instance context.
+ */
+static inline app_usbd_cdc_acm_ctx_t * cdc_acm_ctx_get(app_usbd_cdc_acm_t const * p_cdc_acm)
+{
+ ASSERT(p_cdc_acm != NULL);
+ ASSERT(p_cdc_acm->specific.p_data != NULL);
+ return &p_cdc_acm->specific.p_data->ctx;
+}
+
+/**
+ * @brief User event handler.
+ *
+ * @param[in] p_inst Class instance.
+ * @param[in] event user Event type.
+ */
+static inline void user_event_handler(app_usbd_class_inst_t const * p_inst,
+ app_usbd_cdc_acm_user_event_t event)
+{
+ app_usbd_cdc_acm_t const * p_cdc_acm = cdc_acm_get(p_inst);
+ if (p_cdc_acm->specific.inst.user_ev_handler != NULL)
+ {
+ p_cdc_acm->specific.inst.user_ev_handler(p_inst, event);
+ }
+}
+
+/**
+ * @brief Auxiliary function to access CDC ACM COMM IN endpoint address.
+ *
+ * @param[in] p_inst Class instance data.
+ *
+ * @return IN endpoint address.
+ */
+static inline nrf_drv_usbd_ep_t comm_ep_in_addr_get(app_usbd_class_inst_t const * p_inst)
+{
+ app_usbd_class_iface_conf_t const * class_iface;
+ class_iface = app_usbd_class_iface_get(p_inst, APP_USBD_CDC_ACM_COMM_IFACE_IDX);
+
+ app_usbd_class_ep_conf_t const * ep_cfg;
+ ep_cfg = app_usbd_class_iface_ep_get(class_iface, APP_USBD_CDC_ACM_COMM_EPIN_IDX);
+
+ return app_usbd_class_ep_address_get(ep_cfg);
+}
+
+/**
+ * @brief Auxiliary function to access CDC ACM DATA IN endpoint address.
+ *
+ * @param[in] p_inst Class instance data.
+ *
+ * @return IN endpoint address.
+ */
+static inline nrf_drv_usbd_ep_t data_ep_in_addr_get(app_usbd_class_inst_t const * p_inst)
+{
+ app_usbd_class_iface_conf_t const * class_iface;
+ class_iface = app_usbd_class_iface_get(p_inst, APP_USBD_CDC_ACM_DATA_IFACE_IDX);
+
+ app_usbd_class_ep_conf_t const * ep_cfg;
+ ep_cfg = app_usbd_class_iface_ep_get(class_iface, APP_USBD_CDC_ACM_DATA_EPIN_IDX);
+
+ return app_usbd_class_ep_address_get(ep_cfg);
+}
+
+/**
+ * @brief Auxiliary function to access CDC ACM DATA OUT endpoint address.
+ *
+ * @param[in] p_inst Class instance data.
+ *
+ * @return OUT endpoint address.
+ */
+static inline nrf_drv_usbd_ep_t data_ep_out_addr_get(app_usbd_class_inst_t const * p_inst)
+{
+ app_usbd_class_iface_conf_t const * class_iface;
+ class_iface = app_usbd_class_iface_get(p_inst, APP_USBD_CDC_ACM_DATA_IFACE_IDX);
+
+ app_usbd_class_ep_conf_t const * ep_cfg;
+ ep_cfg = app_usbd_class_iface_ep_get(class_iface, APP_USBD_CDC_ACM_DATA_EPOUT_IDX);
+
+ return app_usbd_class_ep_address_get(ep_cfg);
+}
+
+/**
+ * @brief Internal SETUP standard IN request handler.
+ *
+ * @param[in] p_inst Generic class instance.
+ * @param[in] p_setup_ev Setup event.
+ *
+ * @return Standard error code.
+ */
+static ret_code_t setup_req_std_in(app_usbd_class_inst_t const * p_inst,
+ app_usbd_setup_evt_t const * p_setup_ev)
+{
+ /* Only Get Descriptor standard IN request is supported by CDC class */
+ if ((app_usbd_setup_req_rec(p_setup_ev->setup.bmRequestType) == APP_USBD_SETUP_REQREC_INTERFACE)
+ &&
+ (p_setup_ev->setup.bmRequest == APP_USBD_SETUP_STDREQ_GET_DESCRIPTOR))
+ {
+ size_t dsc_len = 0;
+ size_t max_size;
+
+ uint8_t * p_trans_buff = app_usbd_core_setup_transfer_buff_get(&max_size);
+
+ /* Try to find descriptor in class internals*/
+ ret_code_t ret = app_usbd_class_descriptor_find(
+ p_inst,
+ p_setup_ev->setup.wValue.hb,
+ p_setup_ev->setup.wValue.lb,
+ p_trans_buff,
+ &dsc_len);
+
+ if (ret != NRF_ERROR_NOT_FOUND)
+ {
+ ASSERT(dsc_len < NRF_DRV_USBD_EPSIZE);
+ return app_usbd_core_setup_rsp(&(p_setup_ev->setup), p_trans_buff, dsc_len);
+ }
+ }
+
+ return NRF_ERROR_NOT_SUPPORTED;
+}
+
+/**
+ * @brief Internal SETUP standard OUT request handler
+ *
+ * @param[in] p_inst Generic class instance
+ * @param[in] p_setup_ev Setup event
+ *
+ * @return Standard error code.
+ */
+static ret_code_t setup_req_std_out(app_usbd_class_inst_t const * p_inst,
+ app_usbd_setup_evt_t const * p_setup_ev)
+{
+
+ switch (p_setup_ev->setup.bmRequest)
+ {
+ default:
+ break;
+ }
+
+ return NRF_ERROR_NOT_SUPPORTED;
+}
+
+/**
+ * @brief Internal SETUP class IN request handler.
+ *
+ * @param[in] p_inst Generic class instance.
+ * @param[in] p_setup_ev Setup event.
+ *
+ * @return Standard error code.
+ */
+static ret_code_t setup_req_class_in(app_usbd_class_inst_t const * p_inst,
+ app_usbd_setup_evt_t const * p_setup_ev)
+{
+ app_usbd_cdc_acm_t const * p_cdc_acm = cdc_acm_get(p_inst);
+ app_usbd_cdc_acm_ctx_t * p_cdc_acm_ctx = cdc_acm_ctx_get(p_cdc_acm);
+
+ switch (p_setup_ev->setup.bmRequest)
+ {
+ case APP_USBD_CDC_REQ_GET_LINE_CODING:
+ {
+ if (p_setup_ev->setup.wLength.w != sizeof(app_usbd_cdc_line_coding_t))
+ {
+ return NRF_ERROR_NOT_SUPPORTED;
+ }
+
+ return app_usbd_core_setup_rsp(&p_setup_ev->setup,
+ &p_cdc_acm_ctx->line_coding,
+ sizeof(app_usbd_cdc_line_coding_t));
+ }
+ default:
+ break;
+ }
+
+ return NRF_ERROR_NOT_SUPPORTED;
+}
+
+/**
+ * @brief Class specific OUT request data callback.
+ *
+ * @param status Endpoint status.
+ * @param p_context Context of transfer (set by @ref app_usbd_core_setup_data_handler_set).
+ *
+ * @return Standard error code.
+ */
+static ret_code_t cdc_acm_req_out_data_cb(nrf_drv_usbd_ep_status_t status, void * p_context)
+{
+ if (status != NRF_USBD_EP_OK)
+ {
+ return NRF_ERROR_INTERNAL;
+ }
+
+ app_usbd_cdc_acm_t const * p_cdc_acm = p_context;
+ app_usbd_cdc_acm_ctx_t * p_cdc_acm_ctx = cdc_acm_ctx_get(p_cdc_acm);
+
+ switch (p_cdc_acm_ctx->request.type)
+ {
+ case APP_USBD_CDC_REQ_SET_LINE_CODING:
+ {
+ memcpy(&p_cdc_acm_ctx->line_coding,
+ &p_cdc_acm_ctx->request.payload.line_coding,
+ sizeof(app_usbd_cdc_line_coding_t));
+
+ NRF_LOG_INFO("REQ_SET_LINE_CODING: baudrate: %"PRIu32", databits: %u, "
+ "format: %u, parity: %u",
+ uint32_decode(p_cdc_acm_ctx->line_coding.dwDTERate),
+ p_cdc_acm_ctx->line_coding.bDataBits,
+ p_cdc_acm_ctx->line_coding.bCharFormat,
+ p_cdc_acm_ctx->line_coding.bParityType);
+ break;
+ }
+ default:
+ return NRF_ERROR_NOT_SUPPORTED;
+ }
+
+ return NRF_SUCCESS;
+}
+
+
+/**
+ * @brief Class specific request data stage setup.
+ *
+ * @param[in] p_inst Generic class instance.
+ * @param[in] p_setup_ev Setup event.
+ *
+ * @return Standard error code.
+ */
+static ret_code_t cdc_acm_req_out_datastage(app_usbd_class_inst_t const * p_inst,
+ app_usbd_setup_evt_t const * p_setup_ev)
+{
+ app_usbd_cdc_acm_t const * p_cdc_acm = cdc_acm_get(p_inst);
+ app_usbd_cdc_acm_ctx_t * p_cdc_acm_ctx = cdc_acm_ctx_get(p_cdc_acm);
+
+ p_cdc_acm_ctx->request.type = p_setup_ev->setup.bmRequest;
+ p_cdc_acm_ctx->request.len = p_setup_ev->setup.wLength.w;
+
+ /*Request setup data*/
+ NRF_DRV_USBD_TRANSFER_OUT(transfer,
+ &p_cdc_acm_ctx->request.payload,
+ p_cdc_acm_ctx->request.len);
+ ret_code_t ret;
+ CRITICAL_REGION_ENTER();
+ ret = app_usbd_ep_transfer(NRF_DRV_USBD_EPOUT0, &transfer);
+ if (ret == NRF_SUCCESS)
+ {
+ const app_usbd_core_setup_data_handler_desc_t desc = {
+ .handler = cdc_acm_req_out_data_cb,
+ .p_context = (void*)p_cdc_acm
+ };
+
+ ret = app_usbd_core_setup_data_handler_set(NRF_DRV_USBD_EPOUT0, &desc);
+ }
+ CRITICAL_REGION_EXIT();
+
+ return ret;
+}
+
+/**
+ * @brief Reset port to default state.
+ *
+ * @param p_inst Generic class instance.
+ */
+static void cdc_acm_reset_port(app_usbd_class_inst_t const * p_inst)
+{
+ app_usbd_cdc_acm_t const * p_cdc_acm = cdc_acm_get(p_inst);
+ app_usbd_cdc_acm_ctx_t * p_cdc_acm_ctx = cdc_acm_ctx_get(p_cdc_acm);
+
+ p_cdc_acm_ctx->line_state = 0;
+
+ // Set rx transfers configuration to default state.
+ p_cdc_acm_ctx->rx_transfer[0].p_buf = NULL;
+ p_cdc_acm_ctx->rx_transfer[1].p_buf = NULL;
+ p_cdc_acm_ctx->bytes_left = 0;
+ p_cdc_acm_ctx->bytes_read = 0;
+ p_cdc_acm_ctx->last_read = 0;
+ p_cdc_acm_ctx->cur_read = 0;
+ p_cdc_acm_ctx->p_copy_pos = p_cdc_acm_ctx->internal_rx_buf;
+}
+
+/**
+ * @brief Internal SETUP class OUT request handler.
+ *
+ * @param[in] p_inst Generic class instance.
+ * @param[in] p_setup_ev Setup event.
+ *
+ * @return Standard error code.
+ */
+static ret_code_t setup_req_class_out(app_usbd_class_inst_t const * p_inst,
+ app_usbd_setup_evt_t const * p_setup_ev)
+{
+ app_usbd_cdc_acm_t const * p_cdc_acm = cdc_acm_get(p_inst);
+ app_usbd_cdc_acm_ctx_t * p_cdc_acm_ctx = cdc_acm_ctx_get(p_cdc_acm);
+
+ switch (p_setup_ev->setup.bmRequest)
+ {
+ case APP_USBD_CDC_REQ_SET_LINE_CODING:
+ {
+ if (p_setup_ev->setup.wLength.w != sizeof(app_usbd_cdc_line_coding_t))
+ {
+ return NRF_ERROR_NOT_SUPPORTED;
+ }
+
+ return cdc_acm_req_out_datastage(p_inst, p_setup_ev);
+ }
+ case APP_USBD_CDC_REQ_SET_CONTROL_LINE_STATE:
+ {
+ if (p_setup_ev->setup.wLength.w != 0)
+ {
+ return NRF_ERROR_NOT_SUPPORTED;
+ }
+
+ NRF_LOG_INFO("REQ_SET_CONTROL_LINE_STATE: 0x%x", p_setup_ev->setup.wValue.w);
+
+ bool old_dtr = (p_cdc_acm_ctx->line_state & APP_USBD_CDC_ACM_LINE_STATE_DTR) ?
+ true : false;
+ p_cdc_acm_ctx->line_state = p_setup_ev->setup.wValue.w;
+
+ bool new_dtr = (p_cdc_acm_ctx->line_state & APP_USBD_CDC_ACM_LINE_STATE_DTR) ?
+ true : false;
+
+ if (old_dtr == new_dtr)
+ {
+ return NRF_SUCCESS;
+ }
+
+ const app_usbd_cdc_acm_user_event_t ev = new_dtr ?
+ APP_USBD_CDC_ACM_USER_EVT_PORT_OPEN : APP_USBD_CDC_ACM_USER_EVT_PORT_CLOSE;
+
+ user_event_handler(p_inst, ev);
+
+ if (!new_dtr)
+ {
+ /*Abort DATA endpoints on port close */
+ nrf_drv_usbd_ep_t ep;
+ ep = data_ep_in_addr_get(p_inst);
+ nrf_drv_usbd_ep_abort(ep);
+ ep = data_ep_out_addr_get(p_inst);
+ nrf_drv_usbd_ep_abort(ep);
+
+ // Set rx transfers configuration to default state.
+ p_cdc_acm_ctx->rx_transfer[0].p_buf = NULL;
+ p_cdc_acm_ctx->rx_transfer[1].p_buf = NULL;
+ p_cdc_acm_ctx->bytes_left = 0;
+ p_cdc_acm_ctx->bytes_read = 0;
+ p_cdc_acm_ctx->last_read = 0;
+ p_cdc_acm_ctx->cur_read = 0;
+ p_cdc_acm_ctx->p_copy_pos = p_cdc_acm_ctx->internal_rx_buf;
+ }
+
+ return NRF_SUCCESS;
+ }
+ default:
+ break;
+ }
+
+ return NRF_ERROR_NOT_SUPPORTED;
+}
+
+/**
+ * @brief Control endpoint handler.
+ *
+ * @param[in] p_inst Generic class instance.
+ * @param[in] p_setup_ev Setup event.
+ *
+ * @return Standard error code.
+ */
+static ret_code_t setup_event_handler(app_usbd_class_inst_t const * p_inst,
+ app_usbd_setup_evt_t const * p_setup_ev)
+{
+ ASSERT(p_inst != NULL);
+ ASSERT(p_setup_ev != NULL);
+
+ if (app_usbd_setup_req_dir(p_setup_ev->setup.bmRequestType) == APP_USBD_SETUP_REQDIR_IN)
+ {
+ switch (app_usbd_setup_req_typ(p_setup_ev->setup.bmRequestType))
+ {
+ case APP_USBD_SETUP_REQTYPE_STD:
+ return setup_req_std_in(p_inst, p_setup_ev);
+ case APP_USBD_SETUP_REQTYPE_CLASS:
+ return setup_req_class_in(p_inst, p_setup_ev);
+ default:
+ break;
+ }
+ }
+ else /*APP_USBD_SETUP_REQDIR_OUT*/
+ {
+ switch (app_usbd_setup_req_typ(p_setup_ev->setup.bmRequestType))
+ {
+ case APP_USBD_SETUP_REQTYPE_STD:
+ return setup_req_std_out(p_inst, p_setup_ev);
+ case APP_USBD_SETUP_REQTYPE_CLASS:
+ return setup_req_class_out(p_inst, p_setup_ev);
+ default:
+ break;
+ }
+ }
+
+ return NRF_ERROR_NOT_SUPPORTED;
+}
+
+
+/**
+ * @brief CDC ACM consumer
+ *
+ * @note See @ref nrf_drv_usbd_consumer_t
+ */
+static bool cdc_acm_consumer(nrf_drv_usbd_ep_transfer_t * p_next,
+ void * p_context,
+ size_t ep_size,
+ size_t data_size)
+{
+ app_usbd_cdc_acm_ctx_t * p_cdc_acm_ctx = (app_usbd_cdc_acm_ctx_t *) p_context;
+ p_next->size = data_size;
+
+ if (data_size <= p_cdc_acm_ctx->rx_transfer[0].read_left)
+ {
+ p_next->p_data.rx = p_cdc_acm_ctx->rx_transfer[0].p_buf;
+
+ p_cdc_acm_ctx->rx_transfer[0].p_buf += data_size;
+ p_cdc_acm_ctx->bytes_read += data_size;
+ p_cdc_acm_ctx->rx_transfer[0].read_left -= data_size;
+ NRF_LOG_DEBUG("Received %d bytes. Space left in user buffer: %d bytes.",
+ data_size,
+ p_cdc_acm_ctx->rx_transfer[0].read_left);
+ return (p_cdc_acm_ctx->rx_transfer[0].read_left) != 0;
+ }
+ else
+ {
+ p_next->p_data.rx = p_cdc_acm_ctx->internal_rx_buf;
+
+ p_cdc_acm_ctx->cur_read = data_size;
+ NRF_LOG_DEBUG("Received %d bytes. Stored in internal buffer.", data_size);
+ return false;
+ }
+}
+
+/**
+ * @brief CDC ACM single transfer consumer
+ *
+ * This function finalizes transfer after any received block
+ *
+ * @note See @ref nrf_drv_usbd_consumer_t
+ */
+static bool cdc_acm_single_shoot_consumer(nrf_drv_usbd_ep_transfer_t * p_next,
+ void * p_context,
+ size_t ep_size,
+ size_t data_size)
+{
+ app_usbd_cdc_acm_ctx_t * p_cdc_acm_ctx = (app_usbd_cdc_acm_ctx_t *) p_context;
+ p_next->size = data_size;
+
+ if (data_size <= p_cdc_acm_ctx->rx_transfer[0].read_left)
+ {
+ p_next->p_data.rx = p_cdc_acm_ctx->rx_transfer[0].p_buf;
+
+ p_cdc_acm_ctx->bytes_read = data_size;
+ p_cdc_acm_ctx->rx_transfer[0].read_left = data_size;
+ NRF_LOG_DEBUG("Received %d bytes. Space left in user buffer: %d bytes.",
+ data_size,
+ p_cdc_acm_ctx->rx_transfer[0].read_left);
+ }
+ else
+ {
+ p_next->p_data.rx = p_cdc_acm_ctx->internal_rx_buf;
+ p_cdc_acm_ctx->cur_read = data_size;
+ NRF_LOG_DEBUG("Received %d bytes. Stored in internal buffer.", data_size);
+ }
+
+ return false;
+}
+
+/**
+ * @brief Manage switching between user buffers and copying data from internal buffer.
+ *
+ * @param p_inst Generic USB class instance.
+ *
+ * @return Standard error code
+ */
+static ret_code_t cdc_acm_rx_block_finished(app_usbd_class_inst_t const * p_inst)
+{
+ app_usbd_cdc_acm_t const * p_cdc_acm = cdc_acm_get(p_inst);
+ app_usbd_cdc_acm_ctx_t * p_cdc_acm_ctx = cdc_acm_ctx_get(p_cdc_acm);
+ nrf_drv_usbd_ep_t ep = data_ep_out_addr_get(p_inst);
+
+ nrf_drv_usbd_handler_desc_t handler_desc = {
+ .handler.consumer = cdc_acm_consumer,
+ .p_context = p_cdc_acm_ctx
+ };
+
+ if (p_cdc_acm_ctx->rx_transfer[0].read_left == 0) // Buffer completely filled by consumer
+ {
+ p_cdc_acm_ctx->last_read = p_cdc_acm_ctx->bytes_read;
+ p_cdc_acm_ctx->bytes_read = 0;
+ p_cdc_acm_ctx->bytes_left = 0;
+
+ if (p_cdc_acm_ctx->rx_transfer[1].p_buf != NULL)
+ {
+ p_cdc_acm_ctx->rx_transfer[0] = p_cdc_acm_ctx->rx_transfer[1];
+ p_cdc_acm_ctx->rx_transfer[1].p_buf = NULL;
+ return app_usbd_ep_handled_transfer(ep, &handler_desc);
+ }
+ else
+ {
+ p_cdc_acm_ctx->rx_transfer[0].p_buf = NULL;
+ return NRF_SUCCESS;
+ }
+ }
+
+ size_t bytes_read = p_cdc_acm_ctx->cur_read;
+ size_t bytes_to_cpy = bytes_read;
+
+ if (bytes_read > p_cdc_acm_ctx->rx_transfer[0].read_left)
+ {
+ bytes_to_cpy = p_cdc_acm_ctx->rx_transfer[0].read_left;
+ }
+ memcpy(p_cdc_acm_ctx->rx_transfer[0].p_buf,
+ p_cdc_acm_ctx->internal_rx_buf,
+ bytes_to_cpy);
+
+ // First buffer is full
+ p_cdc_acm_ctx->last_read = p_cdc_acm_ctx->bytes_read + bytes_to_cpy;
+ p_cdc_acm_ctx->bytes_read = 0;
+ p_cdc_acm_ctx->bytes_left = bytes_read - bytes_to_cpy;
+ p_cdc_acm_ctx->p_copy_pos = p_cdc_acm_ctx->internal_rx_buf + bytes_to_cpy;
+
+ if (p_cdc_acm_ctx->rx_transfer[1].p_buf != NULL)
+ {
+ // If there is second transfer, copy it to first
+ p_cdc_acm_ctx->rx_transfer[0] = p_cdc_acm_ctx->rx_transfer[1];
+ p_cdc_acm_ctx->rx_transfer[1].p_buf = NULL;
+
+ while (p_cdc_acm_ctx->bytes_left > 0)
+ {
+
+ if (p_cdc_acm_ctx->bytes_left >= p_cdc_acm_ctx->rx_transfer[0].read_left)
+ {
+ // If there are enough bytes left in internal buffer to completely fill next transfer,
+ // we call user event handler to obtain next buffer and continue double buffering.
+ memcpy(p_cdc_acm_ctx->rx_transfer[0].p_buf,
+ p_cdc_acm_ctx->p_copy_pos,
+ p_cdc_acm_ctx->rx_transfer[0].read_left);
+
+ p_cdc_acm_ctx->bytes_left -= p_cdc_acm_ctx->rx_transfer[0].read_left;
+ p_cdc_acm_ctx->p_copy_pos += p_cdc_acm_ctx->rx_transfer[0].read_left;
+ p_cdc_acm_ctx->last_read = p_cdc_acm_ctx->rx_transfer[0].read_left;
+ user_event_handler(p_inst, APP_USBD_CDC_ACM_USER_EVT_RX_DONE);
+
+ if (p_cdc_acm_ctx->rx_transfer[1].p_buf != NULL)
+ {
+ p_cdc_acm_ctx->rx_transfer[0] = p_cdc_acm_ctx->rx_transfer[1];
+ p_cdc_acm_ctx->rx_transfer[1].p_buf = NULL;
+ }
+ else
+ {
+ // If user does not specify a second buffer, all data transfers are done
+ // and data left in internal buffer is lost.
+ p_cdc_acm_ctx->rx_transfer[0].p_buf = NULL;
+ break;
+ }
+ }
+ else
+ {
+ memcpy(p_cdc_acm_ctx->rx_transfer[0].p_buf,
+ p_cdc_acm_ctx->p_copy_pos,
+ p_cdc_acm_ctx->bytes_left);
+ p_cdc_acm_ctx->bytes_read = p_cdc_acm_ctx->bytes_left;
+
+ p_cdc_acm_ctx->rx_transfer[0].read_left -= p_cdc_acm_ctx->bytes_left;
+ p_cdc_acm_ctx->rx_transfer[0].p_buf += p_cdc_acm_ctx->bytes_left;
+ break;
+ }
+ }
+
+
+ }
+ else
+ {
+ p_cdc_acm_ctx->rx_transfer[0].p_buf = NULL;
+ }
+
+ if (p_cdc_acm_ctx->rx_transfer[0].p_buf != NULL)
+ {
+ return app_usbd_ep_handled_transfer(ep, &handler_desc);
+ }
+ return NRF_SUCCESS;
+}
+
+/**
+ * @brief Class specific endpoint transfer handler.
+ *
+ * @param[in] p_inst Generic class instance.
+ * @param[in] p_setup_ev Setup event.
+ *
+ * @return Standard error code.
+ */
+static ret_code_t cdc_acm_endpoint_ev(app_usbd_class_inst_t const * p_inst,
+ app_usbd_complex_evt_t const * p_event)
+{
+ if (comm_ep_in_addr_get(p_inst) == p_event->drv_evt.data.eptransfer.ep)
+ {
+ NRF_LOG_INFO("EPIN_COMM: notify");
+ return NRF_SUCCESS;
+ }
+ ret_code_t ret;
+ if (NRF_USBD_EPIN_CHECK(p_event->drv_evt.data.eptransfer.ep))
+ {
+ switch (p_event->drv_evt.data.eptransfer.status)
+ {
+ case NRF_USBD_EP_OK:
+ NRF_LOG_INFO("EPIN_DATA: %02x done", p_event->drv_evt.data.eptransfer.ep);
+ user_event_handler(p_inst, APP_USBD_CDC_ACM_USER_EVT_TX_DONE);
+ return NRF_SUCCESS;
+ case NRF_USBD_EP_ABORTED:
+ return NRF_SUCCESS;
+ default:
+ return NRF_ERROR_INTERNAL;
+ }
+ }
+
+ if (NRF_USBD_EPOUT_CHECK(p_event->drv_evt.data.eptransfer.ep))
+ {
+ switch (p_event->drv_evt.data.eptransfer.status)
+ {
+ case NRF_USBD_EP_OK:
+ ret = cdc_acm_rx_block_finished(p_inst);
+ NRF_LOG_INFO("EPOUT_DATA: %02x done", p_event->drv_evt.data.eptransfer.ep);
+ user_event_handler(p_inst, APP_USBD_CDC_ACM_USER_EVT_RX_DONE);
+ return ret;
+ case NRF_USBD_EP_WAITING:
+ case NRF_USBD_EP_ABORTED:
+ return NRF_SUCCESS;
+ default:
+ return NRF_ERROR_INTERNAL;
+ }
+ }
+
+ return NRF_ERROR_NOT_SUPPORTED;
+}
+
+
+/**
+ * @brief @ref app_usbd_class_methods_t::event_handler
+ */
+static ret_code_t cdc_acm_event_handler(app_usbd_class_inst_t const * p_inst,
+ app_usbd_complex_evt_t const * p_event)
+{
+ ASSERT(p_inst != NULL);
+ ASSERT(p_event != NULL);
+
+ ret_code_t ret = NRF_SUCCESS;
+ switch (p_event->app_evt.type)
+ {
+ case APP_USBD_EVT_DRV_SOF:
+ break;
+ case APP_USBD_EVT_DRV_RESET:
+ cdc_acm_reset_port(p_inst);
+ break;
+ case APP_USBD_EVT_DRV_SETUP:
+ ret = setup_event_handler(p_inst, (app_usbd_setup_evt_t const *)p_event);
+ break;
+ case APP_USBD_EVT_DRV_EPTRANSFER:
+ ret = cdc_acm_endpoint_ev(p_inst, p_event);
+ break;
+ case APP_USBD_EVT_DRV_SUSPEND:
+ break;
+ case APP_USBD_EVT_DRV_RESUME:
+ break;
+ case APP_USBD_EVT_INST_APPEND:
+ break;
+ case APP_USBD_EVT_INST_REMOVE:
+ break;
+ case APP_USBD_EVT_STARTED:
+ break;
+ case APP_USBD_EVT_STOPPED:
+ break;
+ case APP_USBD_EVT_POWER_REMOVED:
+ cdc_acm_reset_port(p_inst);
+ break;
+ default:
+ ret = NRF_ERROR_NOT_SUPPORTED;
+ break;
+ }
+
+ return ret;
+}
+
+
+static bool cdc_acm_feed_descriptors(app_usbd_class_descriptor_ctx_t * p_ctx,
+ app_usbd_class_inst_t const * p_inst,
+ uint8_t * p_buff,
+ size_t max_size)
+{
+ static uint8_t ifaces = 0;
+ ifaces = app_usbd_class_iface_count_get(p_inst);
+ app_usbd_cdc_acm_t const * p_cdc_acm = cdc_acm_get(p_inst);
+
+ APP_USBD_CLASS_DESCRIPTOR_BEGIN(p_ctx, p_buff, max_size);
+
+ /* INTERFACE ASSOCIATION DESCRIPTOR */
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(0x08); // bLength
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(APP_USBD_DESCRIPTOR_INTERFACE_ASSOCIATION); // bDescriptorType = Interface Association
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(p_cdc_acm->specific.inst.comm_interface); // bFirstInterface
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(0x02); // bInterfaceCount
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(APP_USBD_CDC_COMM_CLASS); // bFunctionClass
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(APP_USBD_CDC_SUBCLASS_ACM); // bFunctionSubClass
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(p_cdc_acm->specific.inst.protocol); // bFunctionProtocol
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(0x00); // iFunction
+
+ static uint8_t i = 0;
+
+ for (i = 0; i < ifaces; i++)
+ {
+ /* INTERFACE DESCRIPTOR */
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(0x09); // bLength
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(APP_USBD_DESCRIPTOR_INTERFACE); // bDescriptorType = Interface
+
+ static app_usbd_class_iface_conf_t const * p_cur_iface = NULL;
+ p_cur_iface = app_usbd_class_iface_get(p_inst, i);
+
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(app_usbd_class_iface_number_get(p_cur_iface)); // bInterfaceNumber
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(0x00); // bAlternateSetting
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(app_usbd_class_iface_ep_count_get(p_cur_iface)); // bNumEndpoints
+
+ if (p_cdc_acm->specific.inst.comm_interface == app_usbd_class_iface_number_get(p_cur_iface))
+ {
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(APP_USBD_CDC_COMM_CLASS); // bInterfaceClass = CDC COMM
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(APP_USBD_CDC_SUBCLASS_ACM); // bInterfaceSubclass
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(p_cdc_acm->specific.inst.protocol); // bInterfaceProtocol
+ }
+ else if (p_cdc_acm->specific.inst.data_interface ==
+ app_usbd_class_iface_number_get(p_cur_iface))
+ {
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(APP_USBD_CDC_DATA_CLASS); // bInterfaceClass = CDC DATA
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(0x00); // bInterfaceSubclass
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(0x00); // bInterfaceProtocol
+ }
+ else
+ {
+ ASSERT(0);
+ }
+
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(0x00); // iInterface
+
+ if (p_cdc_acm->specific.inst.comm_interface == app_usbd_class_iface_number_get(p_cur_iface))
+ {
+ /* HEADER DESCRIPTOR */
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(0x05); // bLength
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(APP_USBD_CDC_CS_INTERFACE); // bDescriptorType = Class Specific Interface
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(APP_USBD_CDC_SCS_HEADER); // bDescriptorSubtype = Header Functional Descriptor
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(0x10); // bcdCDC LSB
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(0x01); // bcdCDC MSB
+
+ /* CALL MANAGEMENT DESCRIPTOR */
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(0x05); // bLength
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(APP_USBD_CDC_CS_INTERFACE); // bDescriptorType = Class Specific Interface
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(APP_USBD_CDC_SCS_CALL_MGMT); // bDescriptorSubtype = Call Management Functional Descriptor
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(0x03); // bmCapabilities
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(p_cdc_acm->specific.inst.data_interface); // bDataInterface
+
+ /* ABSTRACT CONTROL MANAGEMENT DESCRIPTOR */
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(0x04); // bLength
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(APP_USBD_CDC_CS_INTERFACE); // bDescriptorType = Class Specific Interface
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(APP_USBD_CDC_SCS_ACM); // bDescriptorSubtype = Abstract Control Management Functional Descriptor
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(0x02); // bmCapabilities
+
+ /* UNION DESCRIPTOR */
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(0x05);
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(APP_USBD_CDC_CS_INTERFACE); // bDescriptorType = Class Specific Interface
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(APP_USBD_CDC_SCS_UNION); // bDescriptorSubtype = Union Functional Descriptor
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(p_cdc_acm->specific.inst.comm_interface); // bControlInterface
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(p_cdc_acm->specific.inst.data_interface); // bSubordinateInterface
+ }
+ else if (p_cdc_acm->specific.inst.data_interface ==
+ app_usbd_class_iface_number_get(p_cur_iface))
+ {
+ ;
+ }
+ else
+ {
+ ASSERT(0);
+ }
+
+ /* ENDPOINT DESCRIPTORS */
+ static uint8_t endpoints = 0;
+ endpoints = app_usbd_class_iface_ep_count_get(p_cur_iface);
+
+ static uint8_t j = 0;
+
+ for (j = 0; j < endpoints; j++)
+ {
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(0x07); // bLength
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(APP_USBD_DESCRIPTOR_ENDPOINT); // bDescriptorType = Endpoint
+
+ static app_usbd_class_ep_conf_t const * p_cur_ep = NULL;
+ p_cur_ep = app_usbd_class_iface_ep_get(p_cur_iface, j);
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(app_usbd_class_ep_address_get(p_cur_ep)); // bEndpointAddress
+
+ if (p_cdc_acm->specific.inst.comm_interface ==
+ app_usbd_class_iface_number_get(p_cur_iface))
+ {
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(APP_USBD_DESCRIPTOR_EP_ATTR_TYPE_INTERRUPT); // bmAttributes
+ }
+ else if (p_cdc_acm->specific.inst.data_interface ==
+ app_usbd_class_iface_number_get(p_cur_iface))
+ {
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(APP_USBD_DESCRIPTOR_EP_ATTR_TYPE_BULK); // bmAttributes
+ }
+ else
+ {
+ ASSERT(0);
+ }
+
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(LSB_16(NRF_DRV_USBD_EPSIZE)); // wMaxPacketSize LSB
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(MSB_16(NRF_DRV_USBD_EPSIZE)); // wMaxPacketSize MSB
+
+ if (p_cdc_acm->specific.inst.comm_interface ==
+ app_usbd_class_iface_number_get(p_cur_iface))
+ {
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(16); // bInterval
+ }
+ else if (p_cdc_acm->specific.inst.data_interface ==
+ app_usbd_class_iface_number_get(p_cur_iface))
+ {
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(0x00); // bInterval
+ }
+ else
+ {
+ ASSERT(0);
+ }
+
+ }
+
+ }
+
+ APP_USBD_CLASS_DESCRIPTOR_END();
+}
+
+/**
+ * @brief Public cdc_acm class interface
+ *
+ */
+const app_usbd_class_methods_t app_usbd_cdc_acm_class_methods = {
+ .event_handler = cdc_acm_event_handler,
+ .feed_descriptors = cdc_acm_feed_descriptors,
+};
+
+/** @} */
+
+ret_code_t app_usbd_cdc_acm_write(app_usbd_cdc_acm_t const * p_cdc_acm,
+ const void * p_buf,
+ size_t length)
+{
+ app_usbd_class_inst_t const * p_inst = app_usbd_cdc_acm_class_inst_get(p_cdc_acm);
+ app_usbd_cdc_acm_ctx_t * p_cdc_acm_ctx = cdc_acm_ctx_get(p_cdc_acm);
+
+ bool dtr_state = (p_cdc_acm_ctx->line_state & APP_USBD_CDC_ACM_LINE_STATE_DTR) ?
+ true : false;
+ if (!dtr_state)
+ {
+ /*Port is not opened*/
+ return NRF_ERROR_INVALID_STATE;
+ }
+
+ nrf_drv_usbd_ep_t ep = data_ep_in_addr_get(p_inst);
+ NRF_DRV_USBD_TRANSFER_IN(transfer, p_buf, length);
+ return app_usbd_ep_transfer(ep, &transfer);
+}
+
+size_t app_usbd_cdc_acm_rx_size(app_usbd_cdc_acm_t const * p_cdc_acm)
+{
+ app_usbd_cdc_acm_ctx_t * p_cdc_acm_ctx = cdc_acm_ctx_get(p_cdc_acm);
+
+ return p_cdc_acm_ctx->last_read;
+}
+
+size_t app_usbd_cdc_acm_bytes_stored(app_usbd_cdc_acm_t const * p_cdc_acm)
+{
+ app_usbd_cdc_acm_ctx_t * p_cdc_acm_ctx = cdc_acm_ctx_get(p_cdc_acm);
+
+ return p_cdc_acm_ctx->bytes_left;
+}
+
+ret_code_t app_usbd_cdc_acm_read(app_usbd_cdc_acm_t const * p_cdc_acm,
+ void * p_buf,
+ size_t length)
+{
+ ASSERT(p_buf != NULL);
+ ret_code_t ret;
+ app_usbd_cdc_acm_ctx_t * p_cdc_acm_ctx = cdc_acm_ctx_get(p_cdc_acm);
+
+ if (0U == (p_cdc_acm_ctx->line_state & APP_USBD_CDC_ACM_LINE_STATE_DTR))
+ {
+ /*Port is not opened*/
+ return NRF_ERROR_INVALID_STATE;
+ }
+
+#if (APP_USBD_CONFIG_EVENT_QUEUE_ENABLE == 0)
+ CRITICAL_REGION_ENTER();
+#endif // (APP_USBD_CONFIG_EVENT_QUEUE_ENABLE == 0)
+
+ if (p_cdc_acm_ctx->rx_transfer[0].p_buf == NULL)
+ {
+ if (p_cdc_acm_ctx->bytes_left >= length)
+ {
+ memcpy(p_buf, p_cdc_acm_ctx->p_copy_pos, length);
+ p_cdc_acm_ctx->bytes_left -= length;
+ p_cdc_acm_ctx->p_copy_pos += length;
+ p_cdc_acm_ctx->last_read = length;
+ ret = NRF_SUCCESS;
+ }
+ else
+ {
+ p_cdc_acm_ctx->rx_transfer[0].p_buf = p_buf;
+ p_cdc_acm_ctx->rx_transfer[0].read_left = length;
+ nrf_drv_usbd_ep_t ep = data_ep_out_addr_get(app_usbd_cdc_acm_class_inst_get(p_cdc_acm));
+ nrf_drv_usbd_handler_desc_t const handler_desc = {
+ .handler.consumer = cdc_acm_consumer,
+ .p_context = p_cdc_acm_ctx
+ };
+
+ if (p_cdc_acm_ctx->bytes_left > 0)
+ {
+ memcpy(p_cdc_acm_ctx->rx_transfer[0].p_buf,
+ p_cdc_acm_ctx->p_copy_pos,
+ p_cdc_acm_ctx->bytes_left);
+ p_cdc_acm_ctx->rx_transfer[0].read_left -= p_cdc_acm_ctx->bytes_left;
+ p_cdc_acm_ctx->rx_transfer[0].p_buf += p_cdc_acm_ctx->bytes_left;
+ p_cdc_acm_ctx->bytes_read = p_cdc_acm_ctx->bytes_left;
+ p_cdc_acm_ctx->bytes_left = 0;
+
+ }
+ ret = app_usbd_ep_handled_transfer(ep, &handler_desc);
+ if (ret == NRF_SUCCESS)
+ {
+ ret = NRF_ERROR_IO_PENDING;
+ }
+ }
+ }
+ else if (p_cdc_acm_ctx->rx_transfer[1].p_buf == NULL)
+ {
+ p_cdc_acm_ctx->rx_transfer[1].p_buf = p_buf;
+ p_cdc_acm_ctx->rx_transfer[1].read_left = length;
+ ret = NRF_ERROR_IO_PENDING;
+ }
+ else
+ {
+ ret = NRF_ERROR_BUSY;
+ }
+#if (APP_USBD_CONFIG_EVENT_QUEUE_ENABLE == 0)
+ CRITICAL_REGION_EXIT();
+#endif // (APP_USBD_CONFIG_EVENT_QUEUE_ENABLE == 0)
+
+ return ret;
+}
+
+ret_code_t app_usbd_cdc_acm_read_any(app_usbd_cdc_acm_t const * p_cdc_acm,
+ void * p_buf,
+ size_t length)
+{
+ ASSERT(p_buf != NULL);
+ ret_code_t ret;
+ app_usbd_cdc_acm_ctx_t * p_cdc_acm_ctx = cdc_acm_ctx_get(p_cdc_acm);
+
+ if (0U == (p_cdc_acm_ctx->line_state & APP_USBD_CDC_ACM_LINE_STATE_DTR))
+ {
+ /*Port is not opened*/
+ return NRF_ERROR_INVALID_STATE;
+ }
+
+#if (APP_USBD_CONFIG_EVENT_QUEUE_ENABLE == 0)
+ CRITICAL_REGION_ENTER();
+#endif // (APP_USBD_CONFIG_EVENT_QUEUE_ENABLE == 0)
+ if (p_cdc_acm_ctx->bytes_left > 0)
+ {
+ size_t to_copy = MIN(length, p_cdc_acm_ctx->bytes_left);
+ memcpy(p_buf, p_cdc_acm_ctx->p_copy_pos, to_copy);
+ p_cdc_acm_ctx->bytes_left -= to_copy;
+ p_cdc_acm_ctx->p_copy_pos += to_copy;
+ p_cdc_acm_ctx->last_read = to_copy;
+ ret = NRF_SUCCESS;
+ }
+ else
+ {
+ if (p_cdc_acm_ctx->rx_transfer[0].p_buf == NULL)
+ {
+ p_cdc_acm_ctx->rx_transfer[0].p_buf = p_buf;
+ p_cdc_acm_ctx->rx_transfer[0].read_left = length;
+ nrf_drv_usbd_ep_t ep = data_ep_out_addr_get(app_usbd_cdc_acm_class_inst_get(p_cdc_acm));
+ nrf_drv_usbd_handler_desc_t const handler_desc = {
+ .handler.consumer = cdc_acm_single_shoot_consumer,
+ .p_context = p_cdc_acm_ctx
+ };
+
+ ret = app_usbd_ep_handled_transfer(ep, &handler_desc);
+ if (ret == NRF_SUCCESS)
+ {
+ ret = NRF_ERROR_IO_PENDING;
+ }
+ }
+ else
+ {
+ ret = NRF_ERROR_BUSY;
+ }
+ }
+
+#if (APP_USBD_CONFIG_EVENT_QUEUE_ENABLE == 0)
+ CRITICAL_REGION_EXIT();
+#endif // (APP_USBD_CONFIG_EVENT_QUEUE_ENABLE == 0)
+
+ return ret;
+}
+
+static ret_code_t cdc_acm_serial_state_notify(app_usbd_cdc_acm_t const * p_cdc_acm)
+{
+ app_usbd_class_inst_t const * p_inst = app_usbd_cdc_acm_class_inst_get(p_cdc_acm);
+ app_usbd_cdc_acm_ctx_t * p_cdc_acm_ctx = cdc_acm_ctx_get(p_cdc_acm);
+
+ nrf_drv_usbd_ep_t ep = comm_ep_in_addr_get(p_inst);
+
+ NRF_DRV_USBD_TRANSFER_OUT(transfer,
+ &p_cdc_acm_ctx->request.payload,
+ sizeof(app_usbd_cdc_acm_notify_t));
+ return app_usbd_ep_transfer(ep, &transfer);
+}
+
+ret_code_t app_usbd_cdc_acm_serial_state_notify(app_usbd_cdc_acm_t const * p_cdc_acm,
+ app_usbd_cdc_acm_serial_state_t serial_state,
+ bool value)
+{
+ app_usbd_cdc_acm_ctx_t * p_cdc_acm_ctx = cdc_acm_ctx_get(p_cdc_acm);
+
+ ret_code_t ret;
+ CRITICAL_REGION_ENTER();
+ ret = NRF_SUCCESS;
+ switch (serial_state)
+ {
+ case APP_USBD_CDC_ACM_SERIAL_STATE_DCD:
+ case APP_USBD_CDC_ACM_SERIAL_STATE_DSR:
+ case APP_USBD_CDC_ACM_SERIAL_STATE_BREAK:
+ case APP_USBD_CDC_ACM_SERIAL_STATE_RING:
+ case APP_USBD_CDC_ACM_SERIAL_STATE_FRAMING:
+ case APP_USBD_CDC_ACM_SERIAL_STATE_PARITY:
+ case APP_USBD_CDC_ACM_SERIAL_STATE_OVERRUN:
+
+ if (value)
+ {
+ p_cdc_acm_ctx->serial_state |= serial_state;
+ }
+ else
+ {
+ p_cdc_acm_ctx->serial_state &= ~serial_state;
+ }
+
+ break;
+ default:
+ ret = NRF_ERROR_NOT_SUPPORTED;
+ break;
+ }
+
+ if (ret == NRF_SUCCESS)
+ {
+ app_usbd_cdc_acm_notify_t * notify = &p_cdc_acm_ctx->request.payload.notify;
+ notify->cdc_notify.bmRequestType = app_usbd_setup_req_val(APP_USBD_SETUP_REQREC_INTERFACE,
+ APP_USBD_SETUP_REQTYPE_CLASS,
+ APP_USBD_SETUP_REQDIR_IN);
+ notify->cdc_notify.bmRequest = APP_USBD_CDC_NOTIF_SERIAL_STATE;
+ notify->cdc_notify.wValue = 0;
+ notify->cdc_notify.wIndex = 0;
+ notify->cdc_notify.wLength = sizeof(notify->serial_state);
+
+ notify->serial_state = p_cdc_acm_ctx->serial_state;
+
+ ret = cdc_acm_serial_state_notify(p_cdc_acm);
+ }
+ CRITICAL_REGION_EXIT();
+
+ return ret;
+}
+
+ret_code_t app_usbd_cdc_acm_line_state_get(app_usbd_cdc_acm_t const * p_cdc_acm,
+ app_usbd_cdc_acm_line_state_t line_state,
+ uint32_t * value)
+{
+ app_usbd_cdc_acm_ctx_t * p_cdc_acm_ctx = cdc_acm_ctx_get(p_cdc_acm);
+
+ ret_code_t ret;
+ CRITICAL_REGION_ENTER();
+ ret = NRF_SUCCESS;
+ switch (line_state)
+ {
+ case APP_USBD_CDC_ACM_LINE_STATE_DTR:
+ case APP_USBD_CDC_ACM_LINE_STATE_RTS:
+ *value = (p_cdc_acm_ctx->line_state & line_state) != 0;
+ break;
+ default:
+ ret = NRF_ERROR_NOT_SUPPORTED;
+ break;
+ }
+ CRITICAL_REGION_EXIT();
+
+ return ret;
+}
+
+#endif //NRF_MODULE_ENABLED(APP_USBD_CDC_ACM)
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/usbd/class/cdc/acm/app_usbd_cdc_acm.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/usbd/class/cdc/acm/app_usbd_cdc_acm.h
new file mode 100644
index 0000000..5af0226
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/usbd/class/cdc/acm/app_usbd_cdc_acm.h
@@ -0,0 +1,362 @@
+/**
+ * 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#ifndef APP_USBD_CDC_ACM_H__
+#define APP_USBD_CDC_ACM_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <stdint.h>
+#include <stdbool.h>
+
+#include "nrf_drv_usbd.h"
+#include "app_usbd_class_base.h"
+#include "app_usbd.h"
+#include "app_usbd_core.h"
+#include "app_usbd_descriptor.h"
+
+#include "app_usbd_cdc_desc.h"
+#include "app_usbd_cdc_types.h"
+#include "app_usbd_cdc_acm_internal.h"
+
+/**
+ * @defgroup app_usbd_cdc_acm USB CDC ACM class
+ * @ingroup app_usbd
+ *
+ * @brief @tagAPI52840 Module with types, definitions and API used by CDC ACM class.
+ *
+ * @details References:
+ * - "Universal Serial Bus Class Definitions for Communications Devices"
+ * Revision 1.2, November 3, 2010
+ * - "Universal Serial Bus Communications Class Subclass Specification for PSTN Devices"
+ * Revision 1.2, February 9, 2007
+ *
+ * @{
+ */
+
+#ifdef DOXYGEN
+/**
+ * @brief CDC ACM class instance type
+ *
+ * @ref APP_USBD_CLASS_TYPEDEF
+ */
+typedef struct { } app_usbd_cdc_acm_t;
+#else
+/*lint -save -e10 -e26 -e123 -e505 */
+APP_USBD_CLASS_TYPEDEF(app_usbd_cdc_acm, \
+ APP_USBD_CDC_ACM_CONFIG(0, 0, 0, 0, 0), \
+ APP_USBD_CDC_ACM_INSTANCE_SPECIFIC_DEC, \
+ APP_USBD_CDC_ACM_DATA_SPECIFIC_DEC \
+);
+/*lint -restore*/
+#endif
+
+
+/*lint -save -e407 */
+
+/**
+ * @brief Events passed to user event handler.
+ *
+ * @note Example prototype of user event handler:
+ *
+ * @code
+ void cdc_acm_user_ev_handler(app_usbd_class_inst_t const * p_inst,
+ app_usbd_cdc_acm_user_event_t event);
+ * @endcode
+ */
+typedef enum app_usbd_cdc_acm_user_event_e {
+ APP_USBD_CDC_ACM_USER_EVT_RX_DONE, /**< User event RX_DONE. */
+ APP_USBD_CDC_ACM_USER_EVT_TX_DONE, /**< User event TX_DONE. */
+
+ APP_USBD_CDC_ACM_USER_EVT_PORT_OPEN, /**< User event PORT_OPEN. */
+ APP_USBD_CDC_ACM_USER_EVT_PORT_CLOSE, /**< User event PORT_CLOSE. */
+} app_usbd_cdc_acm_user_event_t;
+
+/*lint -restore*/
+
+/**
+ * @brief Default CDC ACM descriptors.
+ *
+ * @param comm_interface COMM interface number.
+ * @param comm_epin COMM interface IN endpoint.
+ * @param data_interface DATA interface number.
+ * @param data_epin DATA interface IN endpoint.
+ * @param data_epout DATA interface OUT endpoint.
+ */
+#define APP_USBD_CDC_ACM_DEFAULT_DESC(comm_interface, \
+ comm_epin, \
+ data_interface, \
+ data_epin, \
+ data_epout) \
+ APP_USBD_CDC_IAD_DSC(comm_interface, \
+ APP_USBD_CDC_SUBCLASS_ACM, \
+ APP_USBD_CDC_COMM_PROTOCOL_AT_V250) \
+ APP_USBD_CDC_COMM_INTERFACE_DSC(comm_interface, \
+ APP_USBD_CDC_SUBCLASS_ACM, \
+ APP_USBD_CDC_COMM_PROTOCOL_AT_V250) \
+ APP_USBD_CDC_HEADER_DSC(0x0110) \
+ APP_USBD_CDC_CALL_MGMT_DSC(0x03, data_interface) \
+ APP_USBD_CDC_ACM_DSC(0x02) \
+ APP_USBD_CDC_UNION_DSC(comm_interface, data_interface) \
+ APP_USBD_CDC_COM_EP_DSC(comm_epin, NRF_DRV_USBD_EPSIZE) \
+ APP_USBD_CDC_DATA_INTERFACE_DSC(data_interface, 0, 0) \
+ APP_USBD_CDC_DATA_EP_DSC(data_epin, data_epout, NRF_DRV_USBD_EPSIZE)
+
+/**
+ * @brief Global definition of app_usbd_cdc_acm_t class instance.
+ *
+ * @param instance_name Name of global instance.
+ * @param user_ev_handler User event handler (optional).
+ * @param comm_ifc Interface number of cdc_acm control.
+ * @param data_ifc Interface number of cdc_acm DATA.
+ * @param comm_ein COMM subclass IN endpoint.
+ * @param data_ein DATA subclass IN endpoint.
+ * @param data_eout DATA subclass OUT endpoint.
+ * @param cdc_protocol CDC protocol @ref app_usbd_cdc_comm_protocol_t
+ *
+ * @note This macro is just simplified version of @ref APP_USBD_CDC_ACM_GLOBAL_DEF_INTERNAL.
+ *
+ */
+#define APP_USBD_CDC_ACM_GLOBAL_DEF(instance_name, \
+ user_ev_handler, \
+ comm_ifc, \
+ data_ifc, \
+ comm_ein, \
+ data_ein, \
+ data_eout, \
+ cdc_protocol) \
+ APP_USBD_CDC_ACM_GLOBAL_DEF_INTERNAL(instance_name, \
+ user_ev_handler, \
+ comm_ifc, \
+ data_ifc, \
+ comm_ein, \
+ data_ein, \
+ data_eout, \
+ cdc_protocol) \
+
+/**
+ * @brief Helper function to get class instance from CDC ACM class.
+ *
+ * @param[in] p_cdc_acm CDC ACM class instance (defined by @ref APP_USBD_CDC_ACM_GLOBAL_DEF).
+ *
+ * @return Base class instance.
+ */
+static inline app_usbd_class_inst_t const *
+app_usbd_cdc_acm_class_inst_get(app_usbd_cdc_acm_t const * p_cdc_acm)
+{
+ return &p_cdc_acm->base;
+}
+
+/**
+ * @brief Helper function to get cdc_acm specific request from cdc_acm class.
+ *
+ * @param[in] p_cdc_acm CDC ACM class instance (defined by @ref APP_USBD_CDC_ACM_GLOBAL_DEF).
+ *
+ * @return CDC ACM class specific request.
+ */
+static inline app_usbd_cdc_acm_req_t *
+app_usbd_cdc_acm_class_request_get(app_usbd_cdc_acm_t const * p_cdc_acm)
+{
+ return &p_cdc_acm->specific.p_data->ctx.request;
+}
+
+/**
+ * @brief Helper function to get cdc_acm from base class instance.
+ *
+ * @param[in] p_inst Base class instance.
+ *
+ * @return CDC ACM class handle.
+ */
+static inline app_usbd_cdc_acm_t const *
+app_usbd_cdc_acm_class_get(app_usbd_class_inst_t const * p_inst)
+{
+ return (app_usbd_cdc_acm_t const *)p_inst;
+}
+
+
+/**
+ * @brief Writes data to CDC ACM serial port.
+ *
+ * This is asynchronous call. User should wait for @ref APP_USBD_CDC_ACM_USER_EVT_TX_DONE event
+ * to be sure that all data has been sent and input buffer could be accessed again.
+ *
+ * @param[in] p_cdc_acm CDC ACM class instance (defined by @ref APP_USBD_CDC_ACM_GLOBAL_DEF).
+ * @param[in] p_buf Input buffer.
+ * @param[in] length Input buffer length.
+ *
+ * @return Standard error code.
+ */
+ret_code_t app_usbd_cdc_acm_write(app_usbd_cdc_acm_t const * p_cdc_acm,
+ const void * p_buf,
+ size_t length);
+
+/**
+ * @brief Returns the amount of data that was read.
+ *
+ * This function should be used on @ref APP_USBD_CDC_ACM_USER_EVT_RX_DONE event to get
+ * information how many bytes have been transfered into user buffer.
+ *
+ * @param[in] p_cdc_acm CDC ACM class instance (defined by @ref APP_USBD_CDC_ACM_GLOBAL_DEF).
+ *
+ * @return Amount of data transfered.
+ */
+size_t app_usbd_cdc_acm_rx_size(app_usbd_cdc_acm_t const * p_cdc_acm);
+
+/**
+ * @brief Returns the amount of data that was stored into internal buffer
+ *
+ * This function should be used on @ref APP_USBD_CDC_ACM_USER_EVT_RX_DONE event to get
+ * information how many bytes are waiting in internal buffer.
+ *
+ * @param[in] p_cdc_acm CDC ACM class instance (defined by @ref APP_USBD_CDC_ACM_GLOBAL_DEF).
+ *
+ * @return Amount of data waiting.
+ */
+size_t app_usbd_cdc_acm_bytes_stored(app_usbd_cdc_acm_t const * p_cdc_acm);
+
+/**
+ * @brief Reads data from CDC ACM serial port.
+ *
+ * This function uses internal buffer and double buffering for continuous transmission.
+ *
+ * If there is enough data in internal buffer to fill user buffer, NRF_SUCCESS is
+ * returned and data is immediately available in the user buffer.
+ *
+ * If not, up to two user buffers can be scheduled, function returns NRF_ERROR_IO_PENDING
+ * when first buffer is filled and @ref APP_USBD_CDC_ACM_USER_EVT_RX_DONE event is generated.
+ *
+ * @sa app_usbd_cdc_acm_read_any
+ * @sa app_usbd_cdc_acm_rx_size
+ *
+ * @param[in] p_cdc_acm CDC ACM class instance (defined by @ref APP_USBD_CDC_ACM_GLOBAL_DEF).
+ * @param[out] p_buf Output buffer.
+ * @param[in] length Number of bytes to read.
+ *
+ * @retval NRF_SUCCESS Data is stored into user buffer.
+ * @retval NRF_ERROR_IO_PENDING Awaiting transmission, when data is stored into user buffer,
+ * @ref APP_USBD_CDC_ACM_USER_EVT_RX_DONE event will be raised.
+ * @retval NRF_ERROR_BUSY There are already 2 buffers queued for transfers.
+ * @retval other Standard error code.
+ */
+ret_code_t app_usbd_cdc_acm_read(app_usbd_cdc_acm_t const * p_cdc_acm,
+ void * p_buf,
+ size_t length);
+
+/**
+ * @brief Read any data from CDC ACM port up to given buffer size
+ *
+ * This function is very similar to the @ref app_usbd_cdc_acm_read but it returns
+ * data as quick as any data is available, even if the given buffer was not totally full.
+ *
+ * @note This function cannot use double buffering.
+ * @note To check the number of bytes really read use @ref app_usbd_cdc_acm_rx_size
+ * function.
+ *
+ * @sa app_usbd_cdc_acm_read
+ * @sa app_usbd_cdc_acm_rx_size
+ *
+ * @param p_cdc_acm CDC ACM class instance (defined by @ref APP_USBD_CDC_ACM_GLOBAL_DEF).
+ * @param[out] p_buf Output buffer.
+ * @param[in] length Maximum number of bytes to read.
+ *
+ * @retval NRF_SUCCESS Data is stored into user buffer.
+ * @retval NRF_ERROR_IO_PENDING Awaiting transmission, when data is stored into user buffer,
+ * @ref APP_USBD_CDC_ACM_USER_EVT_RX_DONE event will be raised.
+ * @retval NRF_ERROR_BUSY There is already buffer set for a transfer.
+ * @retval other Standard error code.
+ */
+ret_code_t app_usbd_cdc_acm_read_any(app_usbd_cdc_acm_t const * p_cdc_acm,
+ void * p_buf,
+ size_t length);
+
+/**
+ * @brief Serial state notifications.
+ * */
+typedef enum {
+ APP_USBD_CDC_ACM_SERIAL_STATE_DCD = (1u << 0), /**< Notification bit DCD. */
+ APP_USBD_CDC_ACM_SERIAL_STATE_DSR = (1u << 1), /**< Notification bit DSR. */
+ APP_USBD_CDC_ACM_SERIAL_STATE_BREAK = (1u << 2), /**< Notification bit BREAK. */
+ APP_USBD_CDC_ACM_SERIAL_STATE_RING = (1u << 3), /**< Notification bit RING. */
+ APP_USBD_CDC_ACM_SERIAL_STATE_FRAMING = (1u << 4), /**< Notification bit FRAMING.*/
+ APP_USBD_CDC_ACM_SERIAL_STATE_PARITY = (1u << 5), /**< Notification bit PARITY. */
+ APP_USBD_CDC_ACM_SERIAL_STATE_OVERRUN = (1u << 6), /**< Notification bit OVERRUN.*/
+} app_usbd_cdc_acm_serial_state_t;
+
+/**
+ * @brief Serial line state.
+ */
+typedef enum {
+ APP_USBD_CDC_ACM_LINE_STATE_DTR = (1u << 0), /**< Line state bit DTR.*/
+ APP_USBD_CDC_ACM_LINE_STATE_RTS = (1u << 1), /**< Line state bit RTS.*/
+} app_usbd_cdc_acm_line_state_t;
+
+/**
+ * @brief Serial state notification via IN interrupt endpoint.
+ *
+ * @param[in] p_cdc_acm CDC ACM class instance (defined by @ref APP_USBD_CDC_ACM_GLOBAL_DEF).
+ * @param[in] serial_state Serial state notification type.
+ * @param[in] value Serial state value.
+ *
+ * @return Standard error code.
+ */
+ret_code_t app_usbd_cdc_acm_serial_state_notify(app_usbd_cdc_acm_t const * p_cdc_acm,
+ app_usbd_cdc_acm_serial_state_t serial_state,
+ bool value);
+
+/**
+ * @brief Control line value get.
+ *
+ * @param[in] p_cdc_acm CDC ACM class instance (defined by @ref APP_USBD_CDC_ACM_GLOBAL_DEF).
+ * @param[in] line_state Line control value type.
+ * @param[out] value Line control value.
+ *
+ * @return Standard error code.
+ */
+ret_code_t app_usbd_cdc_acm_line_state_get(app_usbd_cdc_acm_t const * p_cdc_acm,
+ app_usbd_cdc_acm_line_state_t line_state,
+ uint32_t * value);
+
+/** @} */
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* APP_USBD_CDC_ACM_H__ */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/usbd/class/cdc/acm/app_usbd_cdc_acm_internal.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/usbd/class/cdc/acm/app_usbd_cdc_acm_internal.h
new file mode 100644
index 0000000..5e09249
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/usbd/class/cdc/acm/app_usbd_cdc_acm_internal.h
@@ -0,0 +1,268 @@
+/**
+ * Copyright (c) 2016 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#ifndef APP_USBD_CDC_ACM_INTERNAL_H__
+#define APP_USBD_CDC_ACM_INTERNAL_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+#include "app_util.h"
+
+/**
+ * @defgroup app_usbd_cdc_acm_internal USB CDC ACM internals
+ * @ingroup app_usbd_cdc_acm
+ * @brief @tagAPI52840 Internals of the USB ACM class implementation.
+ * @{
+ */
+
+/**
+ * @brief Forward declaration of type defined by @ref APP_USBD_CLASS_TYPEDEF in cdc_acm class.
+ *
+ */
+APP_USBD_CLASS_FORWARD(app_usbd_cdc_acm);
+
+/*lint -save -e165*/
+/**
+ * @brief Forward declaration of @ref app_usbd_cdc_acm_user_event_e.
+ *
+ */
+enum app_usbd_cdc_acm_user_event_e;
+
+/*lint -restore*/
+
+/**
+ * @brief User event handler.
+ *
+ * @param[in] p_inst Class instance.
+ * @param[in] event User event.
+ *
+ */
+typedef void (*app_usbd_cdc_acm_user_ev_handler_t)(app_usbd_class_inst_t const * p_inst,
+ enum app_usbd_cdc_acm_user_event_e event);
+
+/**
+ * @brief CDC ACM class part of class instance data.
+ */
+typedef struct {
+ uint8_t comm_interface; //!< Interface number of cdc_acm control.
+ uint8_t comm_epin; //!< COMM subclass IN endpoint.
+ uint8_t data_interface; //!< Interface number of cdc_acm DATA.
+ uint8_t data_epout; //!< DATA subclass OUT endpoint.
+ uint8_t data_epin; //!< DATA subclass IN endpoint.
+
+ app_usbd_cdc_comm_protocol_t protocol; //!< User specified CDC protocol.
+
+ app_usbd_cdc_acm_user_ev_handler_t user_ev_handler; //!< User event handler.
+} app_usbd_cdc_acm_inst_t;
+
+
+/**
+ * @brief CDC ACM serial state class notify
+ */
+typedef struct {
+ app_usbd_cdc_notify_t cdc_notify; //!< CDC notify.
+ uint16_t serial_state; //!< Serial port state.
+} app_usbd_cdc_acm_notify_t;
+
+/**
+ * @brief CDC ACM class specific request handled via control endpoint.
+ */
+typedef struct {
+ uint8_t type; //!< Request type.
+ uint8_t len; //!< Request length.
+
+ union {
+ app_usbd_cdc_line_coding_t line_coding; //!< CDC ACM current line coding.
+ app_usbd_cdc_acm_notify_t notify; //!< CDC ACM class notify.
+ } payload;
+} app_usbd_cdc_acm_req_t;
+
+/**
+ * @brief CDC ACM rx transfer buffer
+ */
+typedef struct {
+ uint8_t * p_buf; //!< User buffer pointer.
+ size_t read_left; //!< Bytes left to read into buffer.
+} cdc_rx_buffer_t;
+
+/**
+ * @brief CDC ACM class context
+ */
+typedef struct {
+ app_usbd_cdc_acm_req_t request; //!< CDC ACM class request.
+ app_usbd_cdc_line_coding_t line_coding; //!< CDC ACM current line coding.
+
+ uint16_t line_state; //!< CDC ACM line state bitmap, DTE side.
+ uint16_t serial_state; //!< CDC ACM serial state bitmap, DCE side.
+
+ cdc_rx_buffer_t rx_transfer[2]; //!< User receive transfers.
+
+ uint8_t internal_rx_buf[NRF_DRV_USBD_EPSIZE]; //!< Internal receive buffer.
+ uint8_t * p_copy_pos; //!< Current copy position from internal buffer.
+
+ size_t bytes_left; //!< Bytes left in internal buffer to copy.
+ size_t bytes_read; //!< Bytes currently written to user buffer.
+ size_t last_read; //!< Bytes read in last transfer.
+ size_t cur_read; //!< Bytes currently read to internal buffer.
+} app_usbd_cdc_acm_ctx_t;
+
+
+/**
+ * @brief CDC ACM class configuration macro.
+ *
+ * Used by @ref APP_USBD_CDC_ACM_GLOBAL_DEF
+ *
+ * @param iface_comm Interface number of cdc_acm control.
+ * @param epin_comm COMM subclass IN endpoint.
+ * @param iface_data Interface number of cdc_acm DATA.
+ * @param epin_data DATA subclass IN endpoint.
+ * @param epout_data DATA subclass OUT endpoint.
+ *
+ */
+#define APP_USBD_CDC_ACM_CONFIG(iface_comm, epin_comm, iface_data, epin_data, epout_data) \
+ ((iface_comm, epin_comm), \
+ (iface_data, epin_data, epout_data))
+
+
+/**
+ * @brief Specific class constant data for cdc_acm class.
+ *
+ * @ref app_usbd_cdc_acm_inst_t
+ */
+#define APP_USBD_CDC_ACM_INSTANCE_SPECIFIC_DEC app_usbd_cdc_acm_inst_t inst;
+
+
+/**
+ * @brief Configures cdc_acm class instance.
+ *
+ * @param user_event_handler User event handler.
+ * @param comm_ifc Interface number of cdc_acm control.
+ * @param comm_ein COMM subclass IN endpoint.
+ * @param data_ifc Interface number of cdc_acm DATA.
+ * @param data_ein DATA subclass IN endpoint.
+ * @param data_eout DATA subclass OUT endpoint.
+ * @param cdc_protocol CDC protocol.
+ */
+#define APP_USBD_CDC_ACM_INST_CONFIG(user_event_handler, comm_ifc, comm_ein, data_ifc, data_ein, \
+ data_eout, cdc_protocol) \
+ .inst = { \
+ .user_ev_handler = user_event_handler, \
+ .comm_interface = comm_ifc, \
+ .comm_epin = comm_ifc, \
+ .data_interface = data_ifc, \
+ .data_epin = data_ein, \
+ .data_epout = data_eout, \
+ .protocol = cdc_protocol \
+ }
+
+/**
+ * @brief Specific class data for cdc_acm class.
+ *
+ * @ref app_usbd_cdc_acm_ctx_t
+ */
+#define APP_USBD_CDC_ACM_DATA_SPECIFIC_DEC app_usbd_cdc_acm_ctx_t ctx;
+
+
+/**
+ * @brief CDC ACM class descriptors config macro.
+ *
+ * @param interface_number Interface number.
+ * @param ... Extracted endpoint list.
+ */
+#define APP_USBD_CDC_ACM_DSC_CONFIG(interface_number, ...) { \
+ APP_USBD_CDC_ACM_INTERFACE_DSC(interface_number, \
+ 0, \
+ 0, \
+ APP_USBD_CDC_ACM_SUBCLASS_CDC_ACMCONTROL) \
+}
+
+/**
+ * @brief Public cdc_acm class interface.
+ *
+ */
+extern const app_usbd_class_methods_t app_usbd_cdc_acm_class_methods;
+
+/**
+ * @brief Global definition of @ref app_usbd_cdc_acm_t class.
+ *
+ * @param instance_name Name of global instance.
+ * @param user_ev_handler User event handler.
+ * @param comm_ifc Interface number of cdc_acm control.
+ * @param data_ifc Interface number of cdc_acm DATA.
+ * @param comm_ein COMM subclass IN endpoint.
+ * @param data_ein DATA subclass IN endpoint.
+ * @param data_eout DATA subclass OUT endpoint.
+ * @param cdc_protocol CDC protocol @ref app_usbd_cdc_comm_protocol_t
+ */
+/*lint -save -emacro(26 64 123 505 651, APP_USBD_CDC_ACM_GLOBAL_DEF_INTERNAL)*/
+#define APP_USBD_CDC_ACM_GLOBAL_DEF_INTERNAL(instance_name, \
+ user_ev_handler, \
+ comm_ifc, \
+ data_ifc, \
+ comm_ein, \
+ data_ein, \
+ data_eout, \
+ cdc_protocol) \
+ APP_USBD_CLASS_INST_GLOBAL_DEF( \
+ instance_name, \
+ app_usbd_cdc_acm, \
+ &app_usbd_cdc_acm_class_methods, \
+ APP_USBD_CDC_ACM_CONFIG(comm_ifc, comm_ein, data_ifc, data_ein, data_eout), \
+ (APP_USBD_CDC_ACM_INST_CONFIG(user_ev_handler, \
+ comm_ifc, \
+ comm_ein, \
+ data_ifc, \
+ data_ein, \
+ data_eout, \
+ cdc_protocol)) \
+ )
+/*lint -restore*/
+
+/** @} */
+
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* APP_USBD_CDC_ACM_INTERNAL_H__ */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/usbd/class/cdc/app_usbd_cdc_desc.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/usbd/class/cdc/app_usbd_cdc_desc.h
new file mode 100644
index 0000000..091065d
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/usbd/class/cdc/app_usbd_cdc_desc.h
@@ -0,0 +1,208 @@
+/**
+ * Copyright (c) 2016 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#ifndef APP_USBD_CDC_DESC_H__
+#define APP_USBD_CDC_DESC_H__
+
+#include <stdint.h>
+#include <stdbool.h>
+
+#include "app_usbd_descriptor.h"
+#include "app_usbd_cdc_types.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @defgroup app_usbd_cdc_desc CDC class descriptors
+ * @brief @tagAPI52840 Descriptors used in the USB CDC class implementation.
+ * @ingroup app_usbd_cdc_acm
+ *
+ * A group of macros used to initialize CDC descriptors
+ * @{
+ */
+
+/**
+ * @brief Initializer of IAD descriptor for CDC class.
+ *
+ * @param interface_number Interface number.
+ * @param subclass Subclass, @ref app_usbd_cdc_subclass_t.
+ * @param protocol Protocol, @ref app_usbd_cdc_comm_protocol_t.
+ */
+#define APP_USBD_CDC_IAD_DSC(interface_number, subclass, protocol) \
+ /*.bLength = */ sizeof(app_usbd_descriptor_iad_t), \
+ /*.bDescriptorType = */ APP_USBD_DESCRIPTOR_INTERFACE_ASSOCIATION, \
+ /*.bFirstInterface = */ interface_number, \
+ /*.bInterfaceCount = */ 2, \
+ /*.bFunctionClass = */ APP_USBD_CDC_COMM_CLASS, \
+ /*.bFunctionSubClass = */ subclass, \
+ /*.bFunctionProtocol = */ protocol, \
+ /*.iFunction = */ 0, \
+
+/**
+ * @brief Initializer of interface descriptor for CDC COMM class.
+ *
+ * @param interface_number Interface number.
+ * @param subclass Subclass, @ref app_usbd_cdc_subclass_t.
+ * @param protocol Protocol, @ref app_usbd_cdc_comm_protocol_t.
+ */
+#define APP_USBD_CDC_COMM_INTERFACE_DSC(interface_number, subclass, protocol) \
+ /*.bLength = */ sizeof(app_usbd_descriptor_iface_t), \
+ /*.bDescriptorType = */ APP_USBD_DESCRIPTOR_INTERFACE, \
+ /*.bInterfaceNumber = */ interface_number, \
+ /*.bAlternateSetting = */ 0x00, \
+ /*.bNumEndpoints = */ 1, \
+ /*.bInterfaceClass = */ APP_USBD_CDC_COMM_CLASS, \
+ /*.bInterfaceSubClass = */ subclass, \
+ /*.bInterfaceProtocol = */ protocol, \
+ /*.iInterface = 0, */ 0x00, \
+
+
+/**
+ * @brief Initializer of interface descriptor for CDC DATA class.
+ *
+ * @param interface_number Interface number.
+ * @param subclass Subclass, @ref app_usbd_cdc_subclass_t.
+ * @param protocol Protocol, @ref app_usbd_cdc_data_protocol_t.
+ */
+#define APP_USBD_CDC_DATA_INTERFACE_DSC(interface_number, subclass, protocol) \
+ /*.bLength = */ sizeof(app_usbd_descriptor_iface_t), \
+ /*.bDescriptorType = */ APP_USBD_DESCRIPTOR_INTERFACE, \
+ /*.bInterfaceNumber = */ interface_number, \
+ /*.bAlternateSetting = */ 0x00, \
+ /*.bNumEndpoints = */ 2, \
+ /*.bInterfaceClass = */ APP_USBD_CDC_DATA_CLASS, \
+ /*.bInterfaceSubClass = */ subclass, \
+ /*.bInterfaceProtocol = */ protocol, \
+ /*.iInterface = 0, */ 0x00, \
+
+
+
+/**
+ * @brief Initializer of endpoint descriptor for CDC COM class.
+ *
+ * @param endpoint_in IN endpoint.
+ * @param ep_size Endpoint size.
+ */
+#define APP_USBD_CDC_COM_EP_DSC(endpoint_in, ep_size) \
+ /*.bLength = */ sizeof(app_usbd_descriptor_ep_t), \
+ /*.bDescriptorType = */ APP_USBD_DESCRIPTOR_ENDPOINT, \
+ /*.bEndpointAddress = */ endpoint_in, \
+ /*.bmAttributes = */ APP_USBD_DESCRIPTOR_EP_ATTR_TYPE_INTERRUPT, \
+ /*.wMaxPacketSize = */ APP_USBD_U16_TO_RAW_DSC(ep_size), \
+ /*.bInterval = */ 16, \
+
+/**
+ * @brief Initializer of endpoint descriptors for CDC DATA class.
+ *
+ * @param endpoint_in IN endpoint.
+ * @param endpoint_out OUT endpoint.
+ * @param ep_size Endpoint size.
+ */
+#define APP_USBD_CDC_DATA_EP_DSC(endpoint_in, endpoint_out, ep_size) \
+ /*.bLength = */ sizeof(app_usbd_descriptor_ep_t), \
+ /*.bDescriptorType = */ APP_USBD_DESCRIPTOR_ENDPOINT, \
+ /*.bEndpointAddress = */ endpoint_in, \
+ /*.bmAttributes = */ APP_USBD_DESCRIPTOR_EP_ATTR_TYPE_BULK, \
+ /*.wMaxPacketSize = */ APP_USBD_U16_TO_RAW_DSC(ep_size), \
+ /*.bInterval = */ 0, \
+ /*.bLength = */ sizeof(app_usbd_descriptor_ep_t), \
+ /*.bDescriptorType = */ APP_USBD_DESCRIPTOR_ENDPOINT, \
+ /*.bEndpointAddress = */ endpoint_out, \
+ /*.bmAttributes = */ APP_USBD_DESCRIPTOR_EP_ATTR_TYPE_BULK, \
+ /*.wMaxPacketSize = */ APP_USBD_U16_TO_RAW_DSC(ep_size), \
+ /*.bInterval = */ 0, \
+
+/**
+ * @brief Initializer of endpoint descriptors for CDC header descriptor.
+ *
+ * @param bcd_cdc BCD CDC version.
+ */
+#define APP_USBD_CDC_HEADER_DSC(bcd_cdc) \
+ /*.bLength = */ sizeof(app_usbd_cdc_desc_header_t), \
+ /*.bDescriptorType = */ APP_USBD_CDC_CS_INTERFACE, \
+ /*.bDescriptorSubtype = */ APP_USBD_CDC_SCS_HEADER, \
+ /*.bcdCDC = */ APP_USBD_U16_TO_RAW_DSC(bcd_cdc), \
+
+/**
+ * @brief Initializer of endpoint descriptors for CDC call management descriptor.
+ *
+ * @param capabilities Capabilities.
+ * @param data_interface Data interface.
+ */
+#define APP_USBD_CDC_CALL_MGMT_DSC(capabilities, data_interface) \
+ /*.bLength = */ sizeof(app_usbd_cdc_desc_call_mgmt_t), \
+ /*.bDescriptorType = */ APP_USBD_CDC_CS_INTERFACE, \
+ /*.bDescriptorSubtype = */ APP_USBD_CDC_SCS_CALL_MGMT, \
+ /*.bmCapabilities = */ capabilities, \
+ /*.bDataInterface = */ data_interface, \
+
+
+/**
+ * @brief Initializer of endpoint descriptors for CDC DATA class.
+ *
+ * @param capabilities Capabilities.
+ */
+#define APP_USBD_CDC_ACM_DSC(capabilities) \
+ /*.bLength = */ sizeof(app_usbd_cdc_desc_acm_t), \
+ /*.bDescriptorType = */ APP_USBD_CDC_CS_INTERFACE, \
+ /*.bDescriptorSubtype = */ APP_USBD_CDC_SCS_ACM, \
+ /*.bmCapabilities = */ capabilities, \
+
+/**
+ * @brief Initializer of endpoint descriptors for CDC DATA class.
+ *
+ * @param control_interface Control interface.
+ * @param ... Subordinate interfaces list.
+ */
+#define APP_USBD_CDC_UNION_DSC(control_interface, ...) \
+ /*.bLength = */ sizeof(app_usbd_cdc_desc_union_t) + (NUM_VA_ARGS(__VA_ARGS__)), \
+ /*.bDescriptorType = */ APP_USBD_CDC_CS_INTERFACE, \
+ /*.bDescriptorSubtype = */ APP_USBD_CDC_SCS_UNION, \
+ /*.bControlInterface = */ control_interface, \
+ /*.bSubordinateInterface = */ __VA_ARGS__, \
+
+/** @} */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* APP_USBD_CDC_H__ */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/usbd/class/cdc/app_usbd_cdc_types.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/usbd/class/cdc/app_usbd_cdc_types.h
new file mode 100644
index 0000000..9b8a482
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/usbd/class/cdc/app_usbd_cdc_types.h
@@ -0,0 +1,360 @@
+/**
+ * Copyright (c) 2016 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#ifndef APP_USBD_CDC_TYPES_H__
+#define APP_USBD_CDC_TYPES_H__
+
+#include <stdint.h>
+#include <stdbool.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+/**
+ * @defgroup app_usbd_cdc_types CDC class types
+ * @ingroup app_usbd_cdc_acm
+ *
+ * @brief @tagAPI52840 Variable types used by the CDC class implementation.
+ * @{
+ */
+
+/**
+ * @brief Communications Interface Class code.
+ *
+ * Used for control interface in communication class.
+ * @ref app_usbd_descriptor_iface_t::bInterfaceClass
+ */
+#define APP_USBD_CDC_COMM_CLASS 0x02
+
+/**
+ * @brief Data Class Interface code.
+ *
+ * Used for data interface in communication class.
+ * @ref app_usbd_descriptor_iface_t::bInterfaceClass
+ */
+#define APP_USBD_CDC_DATA_CLASS 0x0A
+
+/**
+ * @brief CDC subclass possible values.
+ *
+ * @ref app_usbd_descriptor_iface_t::bInterfaceSubClass
+ */
+typedef enum {
+ APP_USBD_CDC_SUBCLASS_RESERVED = 0x00, /**< Reserved in documentation. */
+ APP_USBD_CDC_SUBCLASS_DLCM = 0x01, /**< Direct Line Control Model. */
+ APP_USBD_CDC_SUBCLASS_ACM = 0x02, /**< Abstract Control Model. */
+ APP_USBD_CDC_SUBCLASS_TCM = 0x03, /**< Telephone Control Model. */
+ APP_USBD_CDC_SUBCLASS_MCCM = 0x04, /**< Multi-Channel Control Model. */
+ APP_USBD_CDC_SUBCLASS_CAPI = 0x05, /**< CAPI Control Model. */
+ APP_USBD_CDC_SUBCLASS_ENCM = 0x06, /**< Ethernet Networking Control Model. */
+ APP_USBD_CDC_SUBCLASS_ATM = 0x07, /**< ATM Networking Control Model. */
+ APP_USBD_CDC_SUBCLASS_WHCM = 0x08, /**< Wireless Handset Control Model. */
+ APP_USBD_CDC_SUBCLASS_DM = 0x09, /**< Device Management. */
+ APP_USBD_CDC_SUBCLASS_MDLM = 0x0A, /**< Mobile Direct Line Model. */
+ APP_USBD_CDC_SUBCLASS_OBEX = 0x0B, /**< OBEX. */
+ APP_USBD_CDC_SUBCLASS_EEM = 0x0C, /**< Ethernet Emulation Model. */
+ APP_USBD_CDC_SUBCLASS_NCM = 0x0D /**< Network Control Model. */
+} app_usbd_cdc_subclass_t;
+
+/**
+ * @brief CDC protocol possible values.
+ *
+ * @ref app_usbd_descriptor_iface_t::bInterfaceProtocol
+ */
+typedef enum {
+ APP_USBD_CDC_COMM_PROTOCOL_NONE = 0x00, /**< No class specific protocol required. */
+ APP_USBD_CDC_COMM_PROTOCOL_AT_V250 = 0x01, /**< AT Commands: V.250 etc. */
+ APP_USBD_CDC_COMM_PROTOCOL_AT_PCCA101 = 0x02, /**< AT Commands defined by PCCA-101. */
+ APP_USBD_CDC_COMM_PROTOCOL_AT_PCCA101_ANNEXO = 0x03, /**< AT Commands defined by PCCA-101 & Annex O. */
+ APP_USBD_CDC_COMM_PROTOCOL_AT_GSM707 = 0x04, /**< AT Commands defined by GSM 07.07. */
+ APP_USBD_CDC_COMM_PROTOCOL_AT_3GPP_27007 = 0x05, /**< AT Commands defined by 3GPP 27.007. */
+ APP_USBD_CDC_COMM_PROTOCOL_AT_CDMA = 0x06, /**< AT Commands defined by TIA for CDMA. */
+ APP_USBD_CDC_COMM_PROTOCOL_EEM = 0x07, /**< Ethernet Emulation Model. */
+ APP_USBD_CDC_COMM_PROTOCOL_EXTERNAL = 0xFE, /**< External Protocol: Commands defined by Command Set Functional Descriptor. */
+ APP_USBD_CDC_COMM_PROTOCOL_VENDOR = 0xFF /**< Vendor-specific. */
+} app_usbd_cdc_comm_protocol_t;
+
+/**
+ * @brief CDC data interface protocols possible values.
+ */
+typedef enum {
+ APP_USBD_CDC_DATA_PROTOCOL_NONE = 0x00, /**< No class specific protocol required. */
+ APP_USBD_CDC_DATA_PROTOCOL_NTB = 0x01, /**< Network Transfer Block. */
+ APP_USBD_CDC_DATA_PROTOCOL_ISDN_BRI = 0x30, /**< Physical interface protocol for ISDN BRI. */
+ APP_USBD_CDC_DATA_PROTOCOL_HDLC = 0x31, /**< HDLC. */
+ APP_USBD_CDC_DATA_PROTOCOL_TRANSPARENT = 0x32, /**< Transparent. */
+ APP_USBD_CDC_DATA_PROTOCOL_Q921M = 0x50, /**< Management protocol for Q.921 data link protocol. */
+ APP_USBD_CDC_DATA_PROTOCOL_Q921 = 0x51, /**< Data link protocol for Q.921. */
+ APP_USBD_CDC_DATA_PROTOCOL_Q921TM = 0x52, /**< TEI-multiplexor for Q.921 data link protocol. */
+ APP_USBD_CDC_DATA_PROTOCOL_V42BIS = 0x90, /**< Data compression procedures. */
+ APP_USBD_CDC_DATA_PROTOCOL_Q931 = 0x91, /**< Euro-ISDN protocol control. */
+ APP_USBD_CDC_DATA_PROTOCOL_V120 = 0x92, /**< V.24 rate adaptation to ISDN. */
+ APP_USBD_CDC_DATA_PROTOCOL_CAPI20 = 0x93, /**< CAPI Commands. */
+ APP_USBD_CDC_DATA_PROTOCOL_HOST = 0xFD, /**< Host based driver.
+ * @note This protocol code should only be used in messages
+ * between host and device to identify the host driver portion
+ * of a protocol stack.
+ */
+ APP_USBD_CDC_DATA_PROTOCOL_EXTERNAL = 0xFE, /**< The protocol(s) are described using a Protocol Unit Functional
+ * Descriptors on Communications Class Interface.
+ */
+ APP_USBD_CDC_DATA_PROTOCOL_VENDOR = 0xFF /**< Vendor-specific. */
+} app_usbd_cdc_data_protocol_t;
+
+/**
+ * @brief CDC Functional Descriptor types.
+ */
+typedef enum {
+ APP_USBD_CDC_CS_INTERFACE = 0x24, /**< Class specific interface descriptor type.*/
+ APP_USBD_CDC_CS_ENDPOINT = 0x25 /**< Class specific endpoint descriptor type.*/
+} app_usbd_cdc_func_type_t;
+
+/**
+ * @brief CDC Functional Descriptor subtypes
+ */
+typedef enum {
+ APP_USBD_CDC_SCS_HEADER = 0x00, /**< Header Functional Descriptor, which marks the beginning of the concatenated set of functional descriptors for the interface. */
+ APP_USBD_CDC_SCS_CALL_MGMT = 0x01, /**< Call Management Functional Descriptor. */
+ APP_USBD_CDC_SCS_ACM = 0x02, /**< Abstract Control Management Functional Descriptor. */
+ APP_USBD_CDC_SCS_DLM = 0x03, /**< Direct Line Management Functional Descriptor. */
+ APP_USBD_CDC_SCS_TEL_R = 0x04, /**< Telephone Ringer Functional Descriptor. */
+ APP_USBD_CDC_SCS_TEL_CAP = 0x05, /**< Telephone Call and Line State Reporting Capabilities Functional Descriptor. */
+ APP_USBD_CDC_SCS_UNION = 0x06, /**< Union Functional Descriptor. */
+ APP_USBD_CDC_SCS_COUNTRY_SEL = 0x07, /**< Country Selection Functional Descriptor. */
+ APP_USBD_CDC_SCS_TEL_OM = 0x08, /**< Telephone Operational Modes Functional Descriptor. */
+ APP_USBD_CDC_SCS_USB_TERM = 0x09, /**< USB Terminal Functional Descriptor. */
+ APP_USBD_CDC_SCS_NCT = 0x0A, /**< Network Channel Terminal Descriptor. */
+ APP_USBD_CDC_SCS_PU = 0x0B, /**< Protocol Unit Functional Descriptor. */
+ APP_USBD_CDC_SCS_EU = 0x0C, /**< Extension Unit Functional Descriptor. */
+ APP_USBD_CDC_SCS_MCM = 0x0D, /**< Multi-Channel Management Functional Descriptor. */
+ APP_USBD_CDC_SCS_CAPI = 0x0E, /**< CAPI Control Management Functional Descriptor. */
+ APP_USBD_CDC_SCS_ETH = 0x0F, /**< Ethernet Networking Functional Descriptor. */
+ APP_USBD_CDC_SCS_ATM = 0x10, /**< ATM Networking Functional Descriptor. */
+ APP_USBD_CDC_SCS_WHCM = 0x11, /**< Wireless Handset Control Model Functional Descriptor. */
+ APP_USBD_CDC_SCS_MDLM = 0x12, /**< Mobile Direct Line Model Functional Descriptor. */
+ APP_USBD_CDC_SCS_MDLM_DET = 0x13, /**< MDLM Detail Functional Descriptor. */
+ APP_USBD_CDC_SCS_DMM = 0x14, /**< Device Management Model Functional Descriptor. */
+ APP_USBD_CDC_SCS_OBEX = 0x15, /**< OBEX Functional Descriptor. */
+ APP_USBD_CDC_SCS_CS = 0x16, /**< Command Set Functional Descriptor. */
+ APP_USBD_CDC_SCS_CS_DET = 0x17, /**< Command Set Detail Functional Descriptor. */
+ APP_USBD_CDC_SCS_TEL_CM = 0x18, /**< Telephone Control Model Functional Descriptor. */
+ APP_USBD_CDC_SCS_OBEX_SI = 0x19, /**< OBEX Service Identifier Functional Descriptor. */
+ APP_USBD_CDC_SCS_NCM = 0x1A /**< NCM Functional Descriptor. */
+} app_usbd_cdc_func_subtype_t;
+
+/* Make all descriptors packed */
+#pragma pack(push, 1)
+
+/**
+ * @brief Header Functional Descriptor
+ */
+typedef struct {
+ uint8_t bFunctionLength; //!< Size of this descriptor in bytes.
+ uint8_t bDescriptorType; //!< @ref APP_USBD_CDC_CS_INTERFACE descriptor type.
+ uint8_t bDescriptorSubtype; //!< Descriptor subtype @ref APP_USBD_CDC_SCS_HEADER.
+ uint8_t bcdCDC[2]; //!< USB Class Definitions for Communications Devices Specification release number in binary-coded decimal.
+} app_usbd_cdc_desc_header_t;
+
+/**
+ * @brief Call management capabilities.
+ *
+ * @ref app_usbd_cdc_desc_call_mgmt_t::bmCapabilities bit
+ * */
+typedef enum {
+ APP_USBD_CDC_CALL_MGMT_SUPPORTED = (1 << 0), /**< Call management capability bit 0.*/
+ APP_USBD_CDC_CALL_MGMT_OVER_DCI = (1 << 1), /**< Call management capability bit 1.*/
+} app_subd_cdc_call_mgmt_cap_t;
+
+/**
+ * @brief CDC Call Management Functional Descriptor.
+ */
+typedef struct {
+ uint8_t bFunctionLength; //!< Size of this functional descriptor, in bytes.
+ uint8_t bDescriptorType; //!< Descriptor type @ref APP_USBD_CDC_CS_INTERFACE.
+ uint8_t bDescriptorSubtype; //!< Descriptor subtype @ref APP_USBD_CDC_SCS_CALL_MGMT.
+ uint8_t bmCapabilities; //!< Capabilities @ref app_subd_cdc_call_mgmt_cap_t.
+ uint8_t bDataInterface; //!< Data interface number.
+} app_usbd_cdc_desc_call_mgmt_t;
+
+/**
+ * @brief ACM capabilities.
+ *
+ * @ref app_usbd_cdc_desc_acm_t::bmCapabilities bit
+ * */
+typedef enum {
+ APP_USBD_CDC_ACM_FEATURE_REQUESTS = (1 << 0), /**< ACM capability bit FEATURE_REQUESTS. */
+ APP_USBD_CDC_ACM_LINE_REQUESTS = (1 << 1), /**< ACM capability bit LINE_REQUESTS. */
+ APP_USBD_CDC_ACM_SENDBREAK_REQUESTS = (1 << 2), /**< ACM capability bit SENDBREAK_REQUESTS.*/
+ APP_USBD_CDC_ACM_NOTIFY_REQUESTS = (1 << 3), /**< ACM capability bit NOTIFY_REQUESTS. */
+} app_subd_cdc_acm_cap_t;
+
+/**
+ * @brief CDC ACM Functional Descriptor.
+ */
+typedef struct {
+ uint8_t bFunctionLength; //!< Size of this functional descriptor, in bytes.
+ uint8_t bDescriptorType; //!< Descriptor type @ref APP_USBD_CDC_CS_INTERFACE.
+ uint8_t bDescriptorSubtype; //!< Descriptor subtype @ref APP_USBD_CDC_SCS_ACM.
+ uint8_t bmCapabilities; //!< Capabilities @ref app_subd_cdc_acm_cap_t.
+} app_usbd_cdc_desc_acm_t;
+
+/**
+ * @brief Union Functional Descriptor.
+ */
+typedef struct {
+ uint8_t bFunctionLength; //!< Size of this functional descriptor, in bytes.
+ uint8_t bDescriptorType; //!< Descriptor type @ref APP_USBD_CDC_CS_INTERFACE.
+ uint8_t bDescriptorSubtype; //!< Descriptor subtype @ref APP_USBD_CDC_SCS_UNION.
+ uint8_t bControlInterface; //!< The interface number of the Communications or Data Class interface, designated as the controlling interface for the union.
+ uint8_t bSubordinateInterface[]; //!< Interface number of subordinate interfaces in the union. Number of interfaced depends on descriptor size.
+} app_usbd_cdc_desc_union_t;
+
+/**
+ * @brief Country Selection Functional Descriptor.
+ */
+typedef struct {
+ uint8_t bFunctionLength; //!< Size of this functional descriptor, in bytes.
+ uint8_t bDescriptorType; //!< Descriptor type @ref APP_USBD_CDC_CS_INTERFACE.
+ uint8_t bDescriptorSubtype; //!< Descriptor subtype @ref APP_USBD_CDC_SCS_COUNTRY_SEL.
+ uint8_t iCountryCodeRelDate; //!< Index of a string giving the release date for the implemented ISO 3166 Country Codes.
+} app_usbd_cdc_desc_country_sel_t;
+
+/**
+ * @brief CDC Requests
+ *
+ */
+typedef enum {
+ /* CDC General */
+ APP_USBD_CDC_REQ_SEND_ENCAPSULATED_COMMAND = 0x00, /**< This request is used to issue a command in the format of the supported control protocol of the Communications Class interface. */
+ APP_USBD_CDC_REQ_GET_ENCAPSULATED_RESPONSE = 0x01, /**< This request is used to request a response in the format of the supported control protocol of the Communications Class interface. */
+ /* CDC PSTN */
+ APP_USBD_CDC_REQ_SET_COMM_FEATURE = 0x02, /**< This request controls the settings for a particular communications feature of a particular target. */
+ APP_USBD_CDC_REQ_GET_COMM_FEATURE = 0x03, /**< This request returns the current settings for the communications feature as selected. */
+ APP_USBD_CDC_REQ_CLEAR_COMM_FEATURE = 0x04, /**< This request controls the settings for a particular communications feature of a particular target, setting the selected feature to its default state. */
+ APP_USBD_CDC_REQ_SET_AUX_LINE_STATE = 0x10, /**< This request is used to connect or disconnect a secondary jack to POTS circuit or CODEC, depending on hook state. */
+ APP_USBD_CDC_REQ_SET_HOOK_STATE = 0x11, /**< This request is used to set the necessary PSTN line relay code for on-hook, off-hook, and caller ID states. */
+ APP_USBD_CDC_REQ_PULSE_SETUP = 0x12, /**< This request is used to prepare for a pulse-dialing cycle. */
+ APP_USBD_CDC_REQ_SEND_PULSE = 0x13, /**< This request is used to generate a specified number of make/break pulse cycles. */
+ APP_USBD_CDC_REQ_SET_PULSE_TIME = 0x14, /**< This request sets the timing of the make and break periods for pulse dialing. */
+ APP_USBD_CDC_REQ_RING_AUX_JACK = 0x15, /**< This request is used to generate a ring signal on a secondary phone jack. */
+ APP_USBD_CDC_REQ_SET_LINE_CODING = 0x20, /**< This request allows the host to specify typical asynchronous line-character formatting properties. */
+ APP_USBD_CDC_REQ_GET_LINE_CODING = 0x21, /**< This request allows the host to find out the currently configured line coding. */
+ APP_USBD_CDC_REQ_SET_CONTROL_LINE_STATE = 0x22, /**< This request generates RS-232/V.24 style control signals. */
+ APP_USBD_CDC_REQ_SEND_BREAK = 0x23, /**< This request sends special carrier modulation that generates an RS-232 style break. */
+ APP_USBD_CDC_REQ_SET_RINGER_PARMS = 0x30, /**< This request configures the ringer for the communications device. */
+ APP_USBD_CDC_REQ_GET_RINGER_PARMS = 0x31, /**< This request returns the ringer capabilities of the device and the current status of the device’s ringer. */
+ APP_USBD_CDC_REQ_SET_OPERATION_PARMS = 0x32, /**< Sets the operational mode for the device, between a simple mode, standalone mode and a host centric mode. */
+ APP_USBD_CDC_REQ_GET_OPERATION_PARMS = 0x33, /**< This request gets the current operational mode for the device. */
+ APP_USBD_CDC_REQ_SET_LINE_PARMS = 0x34, /**< This request is used to change the state of the line, corresponding to the interface or master interface of a union to which the command was sent. */
+ APP_USBD_CDC_REQ_GET_LINE_PARMS = 0x35, /**< This request is used to report the state of the line that corresponds to the interface or master interface of a union to which the command was sent. */
+ APP_USBD_CDC_REQ_DIAL_DIGITS = 0x36, /**< This request dials the DTMF digits over the specified line. */
+} app_usbd_cdc_req_id_t;
+
+/**
+ * @brief CDC Notifications.
+ */
+typedef enum {
+ /* CDC General */
+ APP_USBD_CDC_NOTIF_NETWORK_CONNECTION = 0x00, /**< This notification allows the device to notify the host about network connection status. */
+ APP_USBD_CDC_NOTIF_RESPONSE_AVAILABLE = 0x01, /**< This notification allows the device to notify the host that a response is available.
+ * This response can be retrieved with a subsequent GetEncapsulatedResponse request.
+ _ */
+ APP_USBD_CDC_NOTIF_CONNECTION_SPEED_CHANGE = 0x2A, /**< This notification allows the device to inform the host-networking driver
+ * that a change in either the up-link or the down-link bit rate of the connection has occurred.
+ */
+ /* CDC PSTN */
+ APP_USBD_CDC_NOTIF_AUX_JACK_HOOK_STATE = 0x08, /**< (DLM) This notification indicates the loop has changed on the auxiliary phone interface of the USB device. */
+ APP_USBD_CDC_NOTIF_RING_DETECT = 0x09, /**< (DLM) This notification indicates ring voltage on the POTS line interface of the USB device. */
+ APP_USBD_CDC_NOTIF_SERIAL_STATE = 0x20, /**< (ACM) This notification sends asynchronous notification of UART status. */
+ APP_USBD_CDC_NOTIF_CALL_STATE_CHANGE = 0x28, /**< (TCM) This notification identifies that a change has occurred to the state of a call on the line corresponding to the interface or union for the line. */
+ APP_USBD_CDC_NOTIF_LINE_STATE_CHANGE = 0x29 /**< (TCM) This notification identifies that a change has occurred to the state of the line corresponding to the interface or master interface of a union sending the notification message. */
+} app_usbd_cdc_notify_id_t;
+
+/**
+ * @brief Notification sent via CDC COMM endpoint.
+ * */
+typedef struct {
+ uint8_t bmRequestType; //!< Request type.
+ uint8_t bmRequest; //!< Request ID @ref app_usbd_cdc_req_id_t.
+ uint16_t wValue; //!< Value field.
+ uint16_t wIndex; //!< Index field.
+ uint16_t wLength; //!< Length of payload following.
+} app_usbd_cdc_notify_t;
+
+/**
+ * @brief CDC line coding structure.
+ */
+typedef struct {
+ uint8_t dwDTERate[4]; //!< Line baudrate.
+ uint8_t bCharFormat; //!< Character format @ref app_usbd_cdc_line_stopbit_t.
+ uint8_t bParityType; //!< Parity bits @ref app_usbd_cdc_line_parity_t.
+ uint8_t bDataBits; //!< Number of data bits.
+} app_usbd_cdc_line_coding_t;
+
+/**
+ * @brief Possible values of @ref app_usbd_cdc_line_coding_t::bCharFormat.
+ */
+typedef enum {
+ APP_USBD_CDC_LINE_STOPBIT_1 = 0, /**< 1 stop bit. */
+ APP_USBD_CDC_LINE_STOPBIT_1_5 = 1, /**< 1.5 stop bits. */
+ APP_USBD_CDC_LINE_STOPBIT_2 = 2, /**< 2 stop bits. */
+} app_usbd_cdc_line_stopbit_t;
+
+/**
+ * @brief Possible values of @ref app_usbd_cdc_line_coding_t::bParityType.
+ */
+typedef enum {
+ APP_USBD_CDC_LINE_PARITY_NONE = 0, /**< No parity. */
+ APP_USBD_CDC_LINE_PARITY_ODD = 1, /**< Odd parity. */
+ APP_USBD_CDC_LINE_PARITY_EVEN = 2, /**< Even parity. */
+ APP_USBD_CDC_LINE_PARITY_MARK = 3, /**< Parity forced to 0 (space).*/
+ APP_USBD_CDC_LINE_PARITY_SPACE = 4, /**< Parity forced to 1 (mark). */
+} app_usbd_cdc_line_parity_t;
+
+
+#pragma pack(pop)
+
+/** @} */
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* APP_USBD_TYPES_H__ */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/usbd/class/dummy/app_usbd_dummy.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/usbd/class/dummy/app_usbd_dummy.c
new file mode 100644
index 0000000..51d8721
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/usbd/class/dummy/app_usbd_dummy.c
@@ -0,0 +1,107 @@
+/**
+ * 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#include "sdk_common.h"
+#if NRF_MODULE_ENABLED(APP_USBD_DUMMY)
+
+#include <string.h>
+#include <ctype.h>
+#include "app_usbd.h"
+#include "app_usbd_dummy.h"
+#include "app_usbd_string_desc.h"
+#include "nrf_gpio.h"
+
+/**
+ * @defgroup app_usbd_dummy_internal USBD Dummy internals
+ * @{
+ * @ingroup app_usbd_dummy
+ * @internal
+ */
+
+#define NRF_LOG_MODULE_NAME usbd_dummy
+
+#if APP_USBD_DUMMY_CONFIG_LOG_ENABLED
+#define NRF_LOG_LEVEL APP_USBD_DUMMY_CONFIG_LOG_LEVEL
+#define NRF_LOG_INFO_COLOR APP_USBD_DUMMY_CONFIG_INFO_COLOR
+#define NRF_LOG_DEBUG_COLOR APP_USBD_DUMMY_CONFIG_DEBUG_COLOR
+#else //APP_USBD_DUMMY_CONFIG_LOG_ENABLED
+#define NRF_LOG_LEVEL 0
+#endif //APP_USBD_DUMMY_CONFIG_LOG_ENABLED
+#include "nrf_log.h"
+NRF_LOG_MODULE_REGISTER();
+
+/** @brief @ref app_usbd_class_methods_t::event_handler */
+static ret_code_t dummy_class_event_handler(app_usbd_class_inst_t const * p_inst,
+ app_usbd_complex_evt_t const * p_event)
+{
+ return NRF_ERROR_NOT_SUPPORTED;
+}
+
+/** @brief @ref app_usbd_class_methods_t::feed_descriptors */
+static bool dummy_class_feed_descriptors(app_usbd_class_descriptor_ctx_t * p_ctx,
+ app_usbd_class_inst_t const * p_inst,
+ uint8_t * p_buff,
+ size_t max_size)
+{
+ static app_usbd_class_iface_conf_t const * p_cur_iface = 0;
+ p_cur_iface = app_usbd_class_iface_get(p_inst, 0);
+
+ APP_USBD_CLASS_DESCRIPTOR_BEGIN(p_ctx, p_buff, max_size)
+
+ /* INTERFACE DESCRIPTOR */
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(sizeof(app_usbd_descriptor_iface_t)); // bLength
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(APP_USBD_DESCRIPTOR_INTERFACE); // bDescriptorType
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(app_usbd_class_iface_number_get(p_cur_iface)); // bInterfaceNumber
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(0x00); // bAlternateSetting
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(0); // bNumEndpoints
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(APP_USBD_DUMMY_CLASS); // bInterfaceClass
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(APP_USBD_DUMMY_SUBCLASS); // bInterfaceSubClass
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(APP_USBD_DUMMY_PROTOCOL); // bInterfaceProtocol
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(0x00); // iInterface
+
+ APP_USBD_CLASS_DESCRIPTOR_END();
+}
+
+const app_usbd_class_methods_t app_usbd_dummy_class_methods = {
+ .event_handler = dummy_class_event_handler,
+ .feed_descriptors = dummy_class_feed_descriptors,
+};
+
+
+#endif //NRF_MODULE_ENABLED(APP_USBD_DUMMY)
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/usbd/class/dummy/app_usbd_dummy.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/usbd/class/dummy/app_usbd_dummy.h
new file mode 100644
index 0000000..61fa819
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/usbd/class/dummy/app_usbd_dummy.h
@@ -0,0 +1,138 @@
+/**
+ * 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#ifndef APP_USBD_DUMMY_H__
+#define APP_USBD_DUMMY_H__
+
+#include <stdint.h>
+#include <stdbool.h>
+
+#include "nrf_drv_usbd.h"
+#include "nrf_block_dev.h"
+#include "app_usbd_class_base.h"
+#include "app_usbd.h"
+#include "app_usbd_core.h"
+#include "app_usbd_descriptor.h"
+
+#include "app_usbd_dummy_types.h"
+#include "app_usbd_dummy_internal.h"
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @defgroup app_usbd_dummy USB Dummy class
+ * @ingroup app_usbd
+ *
+ * @brief @tagAPI52840 Module with types, definitions,
+ * and API used by the USB Dummy class.
+ *
+ * @note Class is used as a filler to provide correct alignement of interfaces.
+ *
+ * @{
+ */
+
+#ifdef DOXYGEN
+/**
+ * @brief Dummy class instance type
+ *
+ * @ref APP_USBD_CLASS_TYPEDEF
+ */
+typedef struct { } app_usbd_dummy_t;
+#else
+/*lint -save -e10 -e26 -e123 -e505 */
+APP_USBD_CLASS_NO_EP_TYPEDEF(app_usbd_dummy, \
+ APP_USBD_DUMMY_CONFIG(0), \
+ APP_USBD_DUMMY_INSTANCE_SPECIFIC_DEC, \
+ APP_USBD_DUMMY_DATA_SPECIFIC_DEC \
+);
+#endif
+
+/*lint -restore*/
+
+/**
+ * @brief Global definition of app_usbd_dummy_t class
+ *
+ * @param instance_name Name of global instance
+ * @param interface_number Unique interface number
+ *
+ * @note This macro is just simplified version of @ref APP_USBD_DUMMY_GLOBAL_DEF_INTERNAL
+ *
+ */
+/*lint -save -emacro(26 64 123 505 651, APP_USBD_DUMMY_GLOBAL_DEF)*/
+#define APP_USBD_DUMMY_GLOBAL_DEF(instance_name, interface_number) \
+ APP_USBD_DUMMY_GLOBAL_DEF_INTERNAL(instance_name, interface_number)
+/*lint -restore*/
+
+/**
+ * @@brief Helper function to get class instance from dummy
+ *
+ * @param[in] p_dummy Dummy instance
+ * (declared by @ref APP_USBD_DUMMY_GLOBAL_DEF)
+ *
+ * @return Base class instance
+ */
+static inline app_usbd_class_inst_t const *
+app_usbd_dummy_class_inst_get(app_usbd_dummy_t const * p_dummy)
+{
+ return &p_dummy->base;
+}
+
+/**
+ * @brief Helper function to get dummy from base class instance
+ *
+ * @param[in] p_inst Base class instance
+ *
+ * @return Dummy class handle
+ */
+static inline app_usbd_dummy_t const *
+app_usbd_dummy_class_get( app_usbd_class_inst_t const * p_inst)
+{
+ return (app_usbd_dummy_t const *)p_inst;
+}
+
+/** @} */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* APP_USBD_DUMMY_H__ */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/usbd/class/dummy/app_usbd_dummy_internal.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/usbd/class/dummy/app_usbd_dummy_internal.h
new file mode 100644
index 0000000..5b48ae7
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/usbd/class/dummy/app_usbd_dummy_internal.h
@@ -0,0 +1,115 @@
+/**
+ * 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#ifndef APP_USBD_DUMMY_INTERNAL_H__
+#define APP_USBD_DUMMY_INTERNAL_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @defgroup app_usbd_dummy_internals USB Dummy internals
+ * @ingroup app_usbd_dummy
+ *
+ * @brief @tagAPI52840 Internals of the USB Dummy class.
+ * @{
+ */
+
+/** @brief Forward declaration of Dummy Class type */
+APP_USBD_CLASS_FORWARD(app_usbd_dummy);
+
+/** @brief Dummy part of class instance data */
+typedef struct {
+ uint8_t none;
+} app_usbd_dummy_inst_t;
+
+/** @brief Dummy context */
+typedef struct {
+ uint8_t none;
+} app_usbd_dummy_ctx_t;
+
+
+/**
+ * @brief Dummy configuration macro
+ *
+ * Used by @ref APP_USBD_DUMMY_GLOBAL_DEF
+ *
+ * @param iface Interface number
+ * */
+#define APP_USBD_DUMMY_CONFIG(iface) (iface)
+
+
+/**
+ * @brief Specific class constant data for Dummy
+ *
+ * @ref app_usbd_dummy_inst_t
+ */
+#define APP_USBD_DUMMY_INSTANCE_SPECIFIC_DEC app_usbd_dummy_inst_t inst;
+
+/**
+ * @brief Specific class data for Dummy
+ *
+ * @ref app_usbd_dummy_ctx_t
+ * */
+#define APP_USBD_DUMMY_DATA_SPECIFIC_DEC app_usbd_dummy_ctx_t ctx;
+
+
+/** @brief Public Dummy class interface */
+extern const app_usbd_class_methods_t app_usbd_dummy_class_methods;
+
+/** @brief Global definition of Dummy instance */
+#define APP_USBD_DUMMY_GLOBAL_DEF_INTERNAL(instance_name, interface_number) \
+ APP_USBD_CLASS_INST_NO_EP_GLOBAL_DEF( \
+ instance_name, \
+ app_usbd_dummy, \
+ &app_usbd_dummy_class_methods, \
+ APP_USBD_DUMMY_CONFIG((interface_number)), \
+ () \
+ )
+
+
+/** @} */
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* APP_USBD_DUMMY_INTERNAL_H__ */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/usbd/class/dummy/app_usbd_dummy_types.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/usbd/class/dummy/app_usbd_dummy_types.h
new file mode 100644
index 0000000..1a624a9
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/usbd/class/dummy/app_usbd_dummy_types.h
@@ -0,0 +1,75 @@
+/**
+ * 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#ifndef APP_USBD_DUMMY_TYPES_H__
+#define APP_USBD_DUMMY_TYPES_H__
+
+#include "app_util.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @defgroup app_usbd_dummy_types USB Dummy types
+ * @ingroup app_usbd_dummy
+ *
+ * @brief @tagAPI52840 Types used in the USB Dummy class.
+ * @{
+ */
+
+/** @brief Dummy class definition in interface descriptor
+ *
+ * @ref app_usbd_descriptor_iface_t::bInterfaceClass
+ * */
+#define APP_USBD_DUMMY_CLASS 0xFF
+
+/** @brief Dummy subclass value */
+#define APP_USBD_DUMMY_SUBCLASS 0x00
+
+/** @brief Dummy protocol value */
+#define APP_USBD_DUMMY_PROTOCOL 0x00
+
+/** @} */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* APP_USBD_DUMMY_TYPES_H__ */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/usbd/class/hid/app_usbd_hid.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/usbd/class/hid/app_usbd_hid.c
new file mode 100644
index 0000000..d8ff316
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/usbd/class/hid/app_usbd_hid.c
@@ -0,0 +1,508 @@
+/**
+ * Copyright (c) 2016 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#include "sdk_common.h"
+#if NRF_MODULE_ENABLED(APP_USBD_HID)
+
+#include "app_usbd.h"
+#include "app_usbd_core.h"
+#include "app_usbd_hid.h"
+
+/**
+ * @ingroup app_usbd_hid_internals USBD HID internals
+ * @{
+ * @ingroup app_usbd_hid
+ * @internal
+ */
+
+/**
+ * @brief Test whether SOF HID transfer is required.
+ *
+ * This function handles idle period IN transfer.
+ *
+ * @param[in,out] p_hid_ctx Internal HID context.
+ * @param framecnt SOF event frame counter.
+ *
+ * @retval true Idle transfer is required.
+ * @retval false Idle transfer is not required.
+ */
+static bool hid_sof_required(app_usbd_hid_ctx_t * p_hid_ctx, uint16_t framecnt)
+{
+ if (p_hid_ctx->idle_rate == 0)
+ {
+ /* Infinite idle rate */
+ return false;
+ }
+
+ /*Idle rate has 4ms units. Every SOF event is generated with 1ms period.*/
+ uint16_t rate_ms = p_hid_ctx->idle_rate * 4;
+ if ((framecnt % rate_ms) != 0)
+ {
+ /* Idle transfer not required yet*/
+ return false;
+ }
+
+ if (p_hid_ctx->access_lock)
+ {
+ /* Access to internal data locked. Buffer is BUSY.
+ * Don't send anything. Clear transfer flag. Next transfer will be triggered
+ * from API context.*/
+ app_usbd_hid_state_flag_clr(p_hid_ctx, APP_USBD_HID_STATE_FLAG_TRANS_IN_PROGRESS);
+ return false;
+ }
+
+ if (app_usbd_hid_trans_required(p_hid_ctx))
+ {
+ /*New transfer need to be triggered*/
+ return true;
+ }
+
+ return false;
+}
+
+/**
+ * @brief User event handler.
+ *
+ * @param[in] p_inst Class instance.
+ * @param[in] p_hinst HID class instance.
+ * @param[in] event user Event type.
+ */
+static inline void user_event_handler(app_usbd_class_inst_t const * p_inst,
+ app_usbd_hid_inst_t const * p_hinst,
+ app_usbd_hid_user_event_t event)
+{
+ if (p_hinst->user_event_handler != NULL)
+ {
+ p_hinst->user_event_handler(p_inst, event);
+ }
+}
+
+/**
+ * @brief Internal SETUP standard IN request handler.
+ *
+ * @param[in] p_inst Generic class instance.
+ * @param[in] p_hinst HID class instance.
+ * @param[in,out] p_hid_ctx HID context.
+ * @param[in] p_setup_ev Setup event.
+ *
+ * @return Standard error code.
+ */
+static ret_code_t setup_req_std_in(app_usbd_class_inst_t const * p_inst,
+ app_usbd_hid_inst_t const * p_hinst,
+ app_usbd_hid_ctx_t * p_hid_ctx,
+ app_usbd_setup_evt_t const * p_setup_ev)
+{
+ /* Only Get Descriptor standard IN request is supported by HID class */
+ if ((app_usbd_setup_req_rec(p_setup_ev->setup.bmRequestType) == APP_USBD_SETUP_REQREC_INTERFACE)
+ &&
+ (p_setup_ev->setup.bmRequest == APP_USBD_SETUP_STDREQ_GET_DESCRIPTOR))
+ {
+ size_t dsc_len = 0;
+ size_t max_size;
+
+ uint8_t * p_trans_buff = app_usbd_core_setup_transfer_buff_get(&max_size);
+
+ /* Try to find descriptor in class internals*/
+ ret_code_t ret = app_usbd_class_descriptor_find(
+ p_inst,
+ p_setup_ev->setup.wValue.hb,
+ p_setup_ev->setup.wValue.lb,
+ p_trans_buff,
+ &dsc_len);
+
+ if (ret != NRF_ERROR_NOT_FOUND)
+ {
+ ASSERT(dsc_len < NRF_DRV_USBD_EPSIZE);
+ return app_usbd_core_setup_rsp(&(p_setup_ev->setup), p_trans_buff, dsc_len);
+ }
+
+ /* HID specific descriptors*/
+
+ app_usbd_class_descriptor_ctx_t desiz;
+ APP_USBD_CLASS_DESCRIPTOR_INIT(&desiz);
+ uint32_t report_size = 0;
+
+ while(p_hinst->p_hid_methods->feed_subclass_descriptor(&desiz,
+ p_inst,
+ NULL,
+ sizeof(uint8_t),
+ p_setup_ev->setup.wValue.lb)
+ )
+ {
+ report_size++;
+ }
+
+ ASSERT(report_size <= max_size);
+
+ UNUSED_RETURN_VALUE(
+ p_hinst->p_hid_methods->feed_subclass_descriptor(&desiz,
+ p_inst,
+ p_trans_buff,
+ report_size,
+ p_setup_ev->setup.wValue.lb));
+
+ return app_usbd_core_setup_rsp(
+ &p_setup_ev->setup,
+ p_trans_buff,
+ report_size);
+ }
+
+ return NRF_ERROR_NOT_SUPPORTED;
+}
+
+/**
+ * @brief Internal SETUP standard OUT request handler.
+ *
+ * @param[in] p_inst Generic class instance.
+ * @param[in] p_hinst HID class instance.
+ * @param[in,out] p_hid_ctx HID context.
+ * @param[in] p_setup_ev Setup event.
+ *
+ * @return Standard error code.
+ */
+static ret_code_t setup_req_std_out(app_usbd_class_inst_t const * p_inst,
+ app_usbd_hid_inst_t const * p_hinst,
+ app_usbd_hid_ctx_t * p_hid_ctx,
+ app_usbd_setup_evt_t const * p_setup_ev)
+{
+ /*Only Set Descriptor standard OUT request is supported by HID class. However, it is optional
+ * and useless in HID cases.*/
+ return NRF_ERROR_NOT_SUPPORTED;
+}
+
+/**
+ * @brief Internal SETUP class IN request handler.
+ *
+ * @param[in] p_inst Generic class instance.
+ * @param[in] p_hinst HID class instance.
+ * @param[in,out] p_hid_ctx HID context.
+ * @param[in] p_setup_ev Setup event.
+ *
+ * @return Standard error code.
+ */
+static ret_code_t setup_req_class_in(app_usbd_class_inst_t const * p_inst,
+ app_usbd_hid_inst_t const * p_hinst,
+ app_usbd_hid_ctx_t * p_hid_ctx,
+ app_usbd_setup_evt_t const * p_setup_ev)
+{
+ switch (p_setup_ev->setup.bmRequest)
+ {
+ case APP_USBD_HID_REQ_GET_REPORT:
+ {
+ if ((p_setup_ev->setup.wValue.hb == APP_USBD_HID_REPORT_TYPE_INPUT) ||
+ (p_setup_ev->setup.wValue.hb == APP_USBD_HID_REPORT_TYPE_OUTPUT))
+ {
+ return p_hinst->p_hid_methods->on_get_report(p_inst, p_setup_ev);
+ }
+ else
+ {
+ break;
+ }
+ }
+ case APP_USBD_HID_REQ_GET_IDLE:
+ {
+ return app_usbd_core_setup_rsp(&p_setup_ev->setup,
+ &p_hid_ctx->idle_rate,
+ sizeof(p_hid_ctx->idle_rate));
+ }
+ case APP_USBD_HID_REQ_GET_PROTOCOL:
+ {
+ return app_usbd_core_setup_rsp(&p_setup_ev->setup,
+ &p_hid_ctx->boot_active,
+ sizeof(p_hid_ctx->boot_active));
+ }
+ default:
+ break;
+
+ }
+
+ return NRF_ERROR_NOT_SUPPORTED;
+}
+
+/**
+ * @brief Internal SETUP class OUT request handler.
+ *
+ * @param[in] p_inst Generic class instance.
+ * @param[in] p_hinst HID class instance.
+ * @param[in,out] p_hid_ctx HID context.
+ * @param[in] p_setup_ev Setup event.
+ *
+ * @return Standard error code.
+ */
+static ret_code_t setup_req_class_out(app_usbd_class_inst_t const * p_inst,
+ app_usbd_hid_inst_t const * p_hinst,
+ app_usbd_hid_ctx_t * p_hid_ctx,
+ app_usbd_setup_evt_t const * p_setup_ev)
+{
+ switch (p_setup_ev->setup.bmRequest)
+ {
+ case APP_USBD_HID_REQ_SET_REPORT:
+ if (p_setup_ev->setup.wValue.hb != APP_USBD_HID_REPORT_TYPE_OUTPUT)
+ {
+ break;
+ }
+
+ if (p_hinst->p_hid_methods->on_get_report == NULL)
+ {
+ break;
+ }
+
+ return p_hinst->p_hid_methods->on_set_report(p_inst, p_setup_ev);
+ case APP_USBD_HID_REQ_SET_IDLE:
+ p_hid_ctx->idle_rate = p_setup_ev->setup.wValue.hb;
+ return NRF_SUCCESS;
+ case APP_USBD_HID_REQ_SET_PROTOCOL:
+ p_hid_ctx->boot_active = p_setup_ev->setup.wValue.w;
+ {
+ app_usbd_hid_user_event_t ev = (p_hid_ctx->boot_active == 0) ?
+ APP_USBD_HID_USER_EVT_SET_BOOT_PROTO :
+ APP_USBD_HID_USER_EVT_SET_REPORT_PROTO;
+
+ user_event_handler(p_inst, p_hinst, ev);
+ }
+ return NRF_SUCCESS;
+ default:
+ break;
+ }
+
+ return NRF_ERROR_NOT_SUPPORTED;
+}
+
+/**
+ * @brief Internal SETUP event handler.
+ *
+ * @param[in] p_inst Generic class instance.
+ * @param[in] p_hinst HID class instance.
+ * @param[in,out] p_hid_ctx HID context.
+ * @param[in] p_setup_ev Setup event.
+ *
+ * @return Standard error code.
+ */
+static ret_code_t setup_event_handler(app_usbd_class_inst_t const * p_inst,
+ app_usbd_hid_inst_t const * p_hinst,
+ app_usbd_hid_ctx_t * p_hid_ctx,
+ app_usbd_setup_evt_t const * p_setup_ev)
+{
+ ASSERT(p_hinst != NULL);
+ ASSERT(p_hid_ctx != NULL);
+ ASSERT(p_setup_ev != NULL);
+
+ if (app_usbd_setup_req_dir(p_setup_ev->setup.bmRequestType) == APP_USBD_SETUP_REQDIR_IN)
+ {
+ switch (app_usbd_setup_req_typ(p_setup_ev->setup.bmRequestType))
+ {
+ case APP_USBD_SETUP_REQTYPE_STD:
+ return setup_req_std_in(p_inst, p_hinst, p_hid_ctx, p_setup_ev);
+ case APP_USBD_SETUP_REQTYPE_CLASS:
+ return setup_req_class_in(p_inst, p_hinst, p_hid_ctx, p_setup_ev);
+ default:
+ break;
+ }
+ }
+ else /*APP_USBD_SETUP_REQDIR_OUT*/
+ {
+ switch (app_usbd_setup_req_typ(p_setup_ev->setup.bmRequestType))
+ {
+ case APP_USBD_SETUP_REQTYPE_STD:
+ return setup_req_std_out(p_inst, p_hinst, p_hid_ctx, p_setup_ev);
+ case APP_USBD_SETUP_REQTYPE_CLASS:
+ return setup_req_class_out(p_inst, p_hinst, p_hid_ctx, p_setup_ev);
+ default:
+ break;
+ }
+ }
+
+ return NRF_ERROR_NOT_SUPPORTED;
+}
+
+/**
+ * @brief Endpoint IN event handler.
+ *
+ * @param[in] p_inst Generic class instance.
+ * @param[in] p_hinst HID class instance.
+ * @param[in,out] p_hid_ctx HID context.
+ * @param[in] p_setup_ev Setup event.
+ *
+ * @return Standard error code.
+ */
+static ret_code_t endpoint_in_event_handler(app_usbd_class_inst_t const * p_inst,
+ app_usbd_hid_inst_t const * p_hinst,
+ app_usbd_hid_ctx_t * p_hid_ctx,
+ app_usbd_complex_evt_t const * p_event)
+{
+
+ if (p_event->drv_evt.data.eptransfer.status == NRF_USBD_EP_OK)
+ {
+ /* Notify user about last successful transfer. */
+ user_event_handler(p_inst, p_hinst, APP_USBD_HID_USER_EVT_IN_REPORT_DONE);
+ }
+
+ if (app_usbd_hid_access_lock_test(p_hid_ctx))
+ {
+ /* Access to internal data locked. Buffer is BUSY.
+ * Don't send anything. Clear transfer flag. Next transfer will be triggered
+ * from main loop context.*/
+ app_usbd_hid_state_flag_clr(p_hid_ctx, APP_USBD_HID_STATE_FLAG_TRANS_IN_PROGRESS);
+ return NRF_SUCCESS;
+ }
+
+ return p_hinst->p_hid_methods->ep_transfer_in(p_inst);
+}
+
+/**
+ * @brief Endpoint OUT event handler.
+ *
+ * @param[in] p_inst Generic class instance.
+ * @param[in] p_hinst HID class instance.
+ * @param[in,out] p_hid_ctx HID context.
+ * @param[in] p_setup_ev Setup event.
+ *
+ * @return Standard error code.
+ */
+static ret_code_t endpoint_out_event_handler(app_usbd_class_inst_t const * p_inst,
+ app_usbd_hid_inst_t const * p_hinst,
+ app_usbd_hid_ctx_t * p_hid_ctx,
+ app_usbd_complex_evt_t const * p_event)
+{
+ if (p_hinst->p_hid_methods->ep_transfer_out == NULL)
+ {
+ return NRF_ERROR_NOT_SUPPORTED;
+ }
+
+ if (p_event->drv_evt.data.eptransfer.status == NRF_USBD_EP_OK)
+ {
+ /* Notify user about last successful transfer. */
+ user_event_handler(p_inst, p_hinst, APP_USBD_HID_USER_EVT_OUT_REPORT_READY);
+ }
+
+ return p_hinst->p_hid_methods->ep_transfer_out(p_inst);
+}
+
+/** @} */
+
+
+ret_code_t app_usbd_hid_event_handler(app_usbd_class_inst_t const * p_inst,
+ app_usbd_hid_inst_t const * p_hinst,
+ app_usbd_hid_ctx_t * p_hid_ctx,
+ app_usbd_complex_evt_t const * p_event)
+{
+ ret_code_t ret = NRF_SUCCESS;
+ switch (p_event->app_evt.type)
+ {
+ case APP_USBD_EVT_DRV_SOF:
+ if (!hid_sof_required(p_hid_ctx, p_event->drv_evt.data.sof.framecnt))
+ {
+ break;
+ }
+ ret = p_hinst->p_hid_methods->ep_transfer_in(p_inst);
+ break;
+ case APP_USBD_EVT_DRV_RESET:
+ app_usbd_hid_state_flag_clr(p_hid_ctx, APP_USBD_HID_STATE_FLAG_TRANS_IN_PROGRESS);
+ break;
+ case APP_USBD_EVT_DRV_SETUP:
+ ret = setup_event_handler(p_inst, p_hinst, p_hid_ctx, &p_event->setup_evt);
+ break;
+ case APP_USBD_EVT_DRV_EPTRANSFER:
+ if (NRF_USBD_EPIN_CHECK(p_event->drv_evt.data.eptransfer.ep))
+ {
+ ret = endpoint_in_event_handler(p_inst, p_hinst, p_hid_ctx, p_event);
+ }
+ else
+ {
+ ret = endpoint_out_event_handler(p_inst, p_hinst, p_hid_ctx, p_event);
+ }
+ break;
+ case APP_USBD_EVT_DRV_SUSPEND:
+ app_usbd_hid_state_flag_set(p_hid_ctx, APP_USBD_HID_STATE_FLAG_SUSPENDED);
+ break;
+ case APP_USBD_EVT_DRV_RESUME:
+ app_usbd_hid_state_flag_clr(p_hid_ctx, APP_USBD_HID_STATE_FLAG_SUSPENDED);
+
+ /* Always try to trigger transfer on resume event*/
+ ret = p_hinst->p_hid_methods->ep_transfer_in(p_inst);
+ break;
+ case APP_USBD_EVT_INST_APPEND:
+ /*SOF register: GetIdle/SetIdle support*/
+ ret = app_usbd_class_sof_register(p_inst);
+ if (ret != NRF_SUCCESS)
+ {
+ break;
+ }
+ ret = app_usbd_class_rwu_register(p_inst);
+ if (ret != NRF_SUCCESS)
+ {
+ break;
+ }
+ app_usbd_hid_state_flag_set(p_hid_ctx, APP_USBD_HID_STATE_FLAG_APPENDED);
+ break;
+ case APP_USBD_EVT_INST_REMOVE:
+ /*SOF unregister: GetIdle/SetIdle support*/
+ ret = app_usbd_class_sof_unregister(p_inst);
+ if (ret != NRF_SUCCESS)
+ {
+ break;
+ }
+ ret = app_usbd_class_rwu_unregister(p_inst);
+ if (ret != NRF_SUCCESS)
+ {
+ break;
+ }
+ app_usbd_hid_state_flag_clr(p_hid_ctx, APP_USBD_HID_STATE_FLAG_APPENDED);
+ break;
+ case APP_USBD_EVT_STARTED:
+ app_usbd_hid_state_flag_set(p_hid_ctx, APP_USBD_HID_STATE_FLAG_STARTED);
+ break;
+ case APP_USBD_EVT_STOPPED:
+ app_usbd_hid_state_flag_clr(p_hid_ctx, APP_USBD_HID_STATE_FLAG_STARTED);
+ break;
+ default:
+ ret = NRF_ERROR_NOT_SUPPORTED;
+ break;
+ }
+
+ return ret;
+}
+
+app_usbd_hid_report_buffer_t * app_usbd_hid_rep_buff_in_get(app_usbd_hid_inst_t const * p_hinst)
+{
+ ASSERT(p_hinst);
+ return p_hinst->p_rep_buffer_in;
+}
+
+#endif //NRF_MODULE_ENABLED(APP_USBD_HID)
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/usbd/class/hid/app_usbd_hid.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/usbd/class/hid/app_usbd_hid.h
new file mode 100644
index 0000000..c4638ab
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/usbd/class/hid/app_usbd_hid.h
@@ -0,0 +1,515 @@
+/**
+ * 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#ifndef APP_USBD_HID_H__
+#define APP_USBD_HID_H__
+
+#include <stdint.h>
+#include <stdbool.h>
+
+#include "sdk_common.h"
+#include "nrf_atomic.h"
+#include "app_usbd_hid_types.h"
+#include "app_usbd.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @defgroup app_usbd_hid USB HID class
+ * @ingroup app_usbd
+ *
+ * @brief @tagAPI52840 Module with generic HID event data processing.
+ * @{
+ */
+
+#define APP_USBD_HID_IFACE_IDX 0 /**< @brief HID instance interface index. */
+#define APP_USBD_HID_EPIN_IDX 0 /**< @brief HID instance endpoint IN index. */
+#define APP_USBD_HID_EPOUT_IDX 1 /**< @brief HID instance endpoint OUT index.*/
+
+/**
+ * @brief HID context state flags.
+ *
+ * Bit numbers in @ref app_usbd_hid_ctx_t::state_flags.
+ */
+typedef enum {
+ APP_USBD_HID_STATE_FLAG_APPENDED = 0, /**< State flag APPENDED. */
+ APP_USBD_HID_STATE_FLAG_STARTED = 1, /**< State flag STARTED. */
+ APP_USBD_HID_STATE_FLAG_SUSPENDED = 2, /**< State flag SUSPENDED. */
+ APP_USBD_HID_STATE_FLAG_TRANS_IN_PROGRESS = 3, /**< State flag TRANS_IN_PROGRESS. */
+} app_usbd_hid_state_flag_t;
+
+/**
+ * @brief Events passed to user event handler.
+ *
+ * @note Example prototype of user event handler:
+ @code
+ void hid_user_ev_handler(app_usbd_class_inst_t const * p_inst,
+ app_usbd_hid_mouse_user_event_t event);
+ @endcode
+ */
+typedef enum {
+ APP_USBD_HID_USER_EVT_SET_BOOT_PROTO, /**< Event SET_BOOT_PROTOCOL. */
+ APP_USBD_HID_USER_EVT_SET_REPORT_PROTO, /**< Event SET_REPORT_PROTOCOL.*/
+ APP_USBD_HID_USER_EVT_OUT_REPORT_READY, /**< Event OUT_REPORT_READY. */
+ APP_USBD_HID_USER_EVT_IN_REPORT_DONE, /**< Event IN_REPORT_DONE. */
+} app_usbd_hid_user_event_t;
+
+
+/**
+ * @brief User event handler.
+ *
+ * @param[in] p_inst Class instance.
+ * @param[in] event User event.
+ */
+typedef void (*app_usbd_hid_user_ev_handler_t)(app_usbd_class_inst_t const * p_inst,
+ app_usbd_hid_user_event_t event);
+
+/**@brief HID unified interface*/
+typedef struct {
+
+ /**
+ * @brief Function called on HID specific, GetReport request.
+ *
+ * This function should trigger data write to control pipe.
+ *
+ * @param[in] p_inst Class instance.
+ * @param[in] p_setup_ev Setup event.
+ *
+ * @return Standard error code.
+ */
+ ret_code_t (*on_get_report)(app_usbd_class_inst_t const * p_inst,
+ app_usbd_setup_evt_t const * p_setup_ev);
+
+ /**
+ * @brief Function called on HID specific, SetReport request.
+ *
+ * This function should trigger data read from control pipe. This function is not required and
+ * NULL could be pinned to this handler when output report is not defined in report descriptor.
+ *
+ * @param[in] p_inst Class instance.
+ * @param[in] p_setup_ev Setup event.
+ *
+ * @return Standard error code.
+ */
+ ret_code_t (*on_set_report)(app_usbd_class_inst_t const * p_inst,
+ app_usbd_setup_evt_t const * p_setup_ev);
+
+ /**
+ * @brief Function called on IN endpoint transfer.
+ *
+ * This function should trigger next endpoint IN transfer if required.
+ *
+ * @param[in] p_inst Class instance.
+ *
+ * @return Standard error code.
+ */
+ ret_code_t (*ep_transfer_in)(app_usbd_class_inst_t const * p_inst);
+
+ /**
+ * @brief Function called on OUT endpoint transfer.
+ *
+ * This function should should read data from OUT endpoint. This function is not required and
+ * NULL could be pinned to this handler when class doesn't have OUT endpoint.
+ *
+ * @param[in] p_inst Class instance.
+ *
+ * @return Standard error code.
+ */
+ ret_code_t (*ep_transfer_out)(app_usbd_class_inst_t const * p_inst);
+
+ /**
+ * @brief Instance feed subclass descriptor
+ *
+ * Feeds whole descriptor of the instance
+ * @param[in] p_ctx Class descriptor context
+ * @param[in,out] p_inst Instance of the class
+ * @param[out] buff Buffer for subclass descriptor
+ * @param[in] max_size Requested size of the subclass descriptor
+ * @param[in] index Index of the subclass descriptor
+ *
+ * @return True if not finished feeding the descriptor, false if done
+ */
+ bool (*feed_subclass_descriptor)(app_usbd_class_descriptor_ctx_t * p_ctx,
+ app_usbd_class_inst_t const * p_inst,
+ uint8_t * buff,
+ size_t max_size,
+ uint8_t index);
+} app_usbd_hid_methods_t;
+
+/**
+ * @brief HID report buffers.
+ */
+typedef struct {
+ uint8_t * p_buff;
+ size_t size;
+} app_usbd_hid_report_buffer_t;
+
+
+
+/**@brief Define OUT report buffer structure @ref app_usbd_hid_report_buffer_t.
+ *
+ * @param name Instance name.
+ * @param rep_size Output report size.
+ */
+#define APP_USBD_HID_GENERIC_GLOBAL_OUT_REP_DEF(name, rep_size) \
+ static uint8_t CONCAT_2(name, _buf)[(rep_size)]; \
+ const app_usbd_hid_report_buffer_t name = { \
+ .p_buff = CONCAT_2(name, _buf), \
+ .size = sizeof(CONCAT_2(name, _buf)), \
+ }
+
+/**
+ * @brief HID subclass descriptor.
+ */
+
+typedef struct {
+ size_t size;
+ app_usbd_descriptor_t type;
+ uint8_t const * const p_data;
+} app_usbd_hid_subclass_desc_t;
+
+/**
+ * @brief Initializer of HID report descriptor
+ *
+ * @param name Report descriptor name
+ * @param ... Report descriptor data
+ */
+
+#define APP_USBD_HID_GENERIC_SUBCLASS_REPORT_DESC(name, ...) \
+ static uint8_t const CONCAT_2(name, _data)[] = \
+ __VA_ARGS__ \
+ ; \
+ static const app_usbd_hid_subclass_desc_t name = \
+ { \
+ sizeof(CONCAT_2(name, _data)), \
+ APP_USBD_DESCRIPTOR_REPORT, \
+ CONCAT_2(name,_data) \
+ }
+
+/**
+ * @brief Initializer of HID physical descriptor
+ *
+ * @param name Physical descriptor name
+ * @param ... Physical descriptor data
+ */
+
+#define APP_USBD_HID_GENERIC_SUBCLASS_PHYSICAL_DESC(name, ...) \
+ static uint8_t const CONCAT_2(name, _data)[] = \
+ __VA_ARGS__ \
+ ; \
+ static const app_usbd_hid_subclass_desc_t name = \
+ { \
+ sizeof(CONCAT_2(name, _data)), \
+ APP_USBD_DESCRIPTOR_PHYSICAL, \
+ CONCAT_2(name,_data) \
+ }
+
+
+/**
+ * @brief USB HID instance.
+ */
+typedef struct {
+ app_usbd_hid_subclass_desc_t const ** const p_subclass_desc; //!< HID subclass descriptors array.
+ size_t subclass_desc_count; //!< HID subclass descriptors count.
+
+ app_usbd_hid_subclass_t subclass_boot; //!< Boot device (see HID definition)
+ app_usbd_hid_protocol_t protocol; //!< HID protocol (see HID definition)
+
+ app_usbd_hid_report_buffer_t * p_rep_buffer_in; //!< Report buffer IN.
+ app_usbd_hid_report_buffer_t const * p_rep_buffer_out; //!< Report buffer OUT (only one instance).
+ app_usbd_hid_methods_t const * p_hid_methods; //!< Hid interface methods.
+ app_usbd_hid_user_ev_handler_t user_event_handler; //!< User event handler.
+} app_usbd_hid_inst_t;
+
+
+/**
+ * @brief USB HID instance initializer @ref app_usbd_hid_inst_t.
+ *
+ * @param subclass_dsc HID subclass descriptors.
+ * @param sub_boot Subclass boot. (@ref app_usbd_hid_subclass_t)
+ * @param protocl HID protocol. (@ref app_usbd_hid_protocol_t)
+ * @param report_buff_in Input report buffer list.
+ * @param report_buff_out Output report buffer.
+ * @param user_ev_handler @ref app_usbd_hid_user_ev_handler_t.
+ @param hid_methods @ref app_usbd_hid_methods_t.
+ * */
+
+#define APP_USBD_HID_INST_CONFIG(subclass_dsc, \
+ sub_boot, \
+ protocl, \
+ report_buff_in, \
+ report_buff_out, \
+ user_ev_handler, \
+ hid_methods) \
+ { \
+ .p_subclass_desc = subclass_dsc, \
+ .subclass_desc_count = ARRAY_SIZE(subclass_dsc), \
+ .p_rep_buffer_in = report_buff_in, \
+ .p_rep_buffer_out = report_buff_out, \
+ .user_event_handler = user_ev_handler, \
+ .p_hid_methods = hid_methods, \
+ .subclass_boot = sub_boot, \
+ .protocol = protocl \
+ }
+
+/**
+ * @brief HID internal context.
+ * */
+typedef struct {
+ nrf_atomic_u32_t state_flags; //!< HID state flags @ref app_usbd_hid_state_flag_t.
+ nrf_atomic_flag_t access_lock; //!< Lock flag to internal data.
+ uint8_t idle_rate; //!< HID idle rate (4ms units).
+ uint8_t boot_active; //!< HID using boot protocol.
+} app_usbd_hid_ctx_t;
+
+
+/**
+ * @brief Locks internal hid context.
+ *
+ * Simple semaphore functionality to prevent concurrent access from application and
+ * interrupt to internal mouse data.
+ *
+ * @param[in] p_hid_ctx Internal hid context
+ */
+static inline void app_usbd_hid_access_lock(app_usbd_hid_ctx_t * p_hid_ctx)
+{
+ UNUSED_RETURN_VALUE(nrf_atomic_flag_set(&p_hid_ctx->access_lock));
+ __DSB();
+}
+
+
+/**
+ * @brief Unlocks internal hid context.
+ *
+ * Simple semaphore functionality to prevent concurrent access from application and
+ * interrupt to internal mouse data.
+ *
+ * @param[in] p_hid_ctx Internal hid context.
+ */
+static inline void app_usbd_hid_access_unlock(app_usbd_hid_ctx_t * p_hid_ctx)
+{
+ UNUSED_RETURN_VALUE(nrf_atomic_flag_clear(&p_hid_ctx->access_lock));
+ __DSB();
+}
+
+/**
+ * @brief Tests whether internal lock is acquired.
+ *
+ * @param[in] p_hid_ctx Internal HID context.
+ *
+ * @retval true Locked.
+ * @retval false Unlocked.
+ */
+static inline bool app_usbd_hid_access_lock_test(app_usbd_hid_ctx_t * p_hid_ctx)
+{
+ return p_hid_ctx->access_lock != 0;
+}
+
+/**
+ * @brief Set one of the HID internal state flags.
+ *
+ * @param[in] p_hid_ctx Internal HID context.
+ * @param[in] flag Flag to set.
+ */
+static inline void app_usbd_hid_state_flag_set(app_usbd_hid_ctx_t * p_hid_ctx,
+ app_usbd_hid_state_flag_t flag)
+{
+ UNUSED_RETURN_VALUE(nrf_atomic_u32_or(&p_hid_ctx->state_flags, 1u << flag));
+}
+
+/**
+ * @brief Clear one of the HID internal state flags.
+ *
+ * @param[in] p_hid_ctx Internal HID context.
+ * @param[in] flag Flag to clear.
+ */
+static inline void app_usbd_hid_state_flag_clr(app_usbd_hid_ctx_t * p_hid_ctx,
+ app_usbd_hid_state_flag_t flag)
+{
+ UNUSED_RETURN_VALUE(nrf_atomic_u32_and(&p_hid_ctx->state_flags, ~(1u << flag)));
+}
+
+
+/**
+ * @brief Test one of the HID internal state flags.
+ *
+ * @param[in] p_hid_ctx Internal HID context.
+ * @param[in] flag Flag to test.
+ *
+ * @retval true Flag is set.
+ * @retval false Flag is not set.
+ */
+static inline bool app_usbd_hid_state_flag_test(app_usbd_hid_ctx_t * p_hid_ctx,
+ app_usbd_hid_state_flag_t flag)
+{
+ return ((p_hid_ctx->state_flags >> flag) & 1) == 1;
+}
+
+/**
+ * @brief Checks whether HID endpoint transfer required.
+ *
+ * @param[in] p_hid_ctx Internal HID context.
+ *
+ * @retval true Input endpoint transfer required.
+ * @retval false Transfer in progress or not allowed.
+ */
+static inline bool app_usbd_hid_trans_required(app_usbd_hid_ctx_t * p_hid_ctx)
+{
+ if (app_usbd_hid_state_flag_test(p_hid_ctx, APP_USBD_HID_STATE_FLAG_SUSPENDED) != 0)
+ {
+ UNUSED_RETURN_VALUE(app_usbd_wakeup_req());
+ return false;
+ }
+
+ return app_usbd_hid_state_flag_test(p_hid_ctx, APP_USBD_HID_STATE_FLAG_TRANS_IN_PROGRESS) == 0;
+}
+
+/**
+ * @brief Validates internal hid state.
+ *
+ * HID Mouse has to receive some USBD events before functions from this module could be used.
+ *
+ * @param[in] p_hid_ctx Internal hid context.
+ *
+ * @retval true State is valid.
+ * @retval false State is invalid.
+ */
+static inline bool app_usbd_hid_state_valid(app_usbd_hid_ctx_t * p_hid_ctx)
+{
+ /*Check whether internal flags allow to enable mouse*/
+ if ((app_usbd_hid_state_flag_test(p_hid_ctx, APP_USBD_HID_STATE_FLAG_APPENDED) == 0) ||
+ (app_usbd_hid_state_flag_test(p_hid_ctx, APP_USBD_HID_STATE_FLAG_STARTED) == 0))
+ {
+ return false;
+ }
+
+ return true;
+}
+
+/**
+ * @brief HID generic event handler.
+ *
+ * This handler should process every class event after specific class handler.
+ * This approach allow to handle some events in the same way in all HID sub-classes.
+ *
+ * @param[in] p_inst Generic class instance.
+ * @param[in] p_hinst HID class instance.
+ * @param[in] p_hid_ctx HID context.
+ * @param[in] p_event Complex event structure.
+ *
+ * @return Standard error code.
+ */
+ret_code_t app_usbd_hid_event_handler(app_usbd_class_inst_t const * p_inst,
+ app_usbd_hid_inst_t const * p_hinst,
+ app_usbd_hid_ctx_t * p_hid_ctx,
+ app_usbd_complex_evt_t const * p_event);
+
+
+/**
+ * @brief Returns IN report buffer.
+ *
+ * @param[in] p_hinst HID class instance.
+ *
+ * @return Report buffer handle or NULL if report doesn't exist.
+ */
+app_usbd_hid_report_buffer_t * app_usbd_hid_rep_buff_in_get(app_usbd_hid_inst_t const * p_hinst);
+
+/**
+ * @brief Returns OUT report buffer.
+ *
+ * Output reports are handled in interrupt handler so only one buffer is required. Buffer returned by
+ * this function has predefined size, which should be equal (maximum OUTPUT report size + 1). To receive
+ * OUT report this function should be called on @ref APP_USBD_HID_USER_EVT_OUT_REPORT_READY event.
+ *
+ * @param[in] p_hinst HID class instance.
+ *
+ * @return Report buffer handle or NULL if report doesn't exist.
+ */
+static inline app_usbd_hid_report_buffer_t const *
+app_usbd_hid_rep_buff_out_get(app_usbd_hid_inst_t const * p_hinst)
+{
+ ASSERT(p_hinst);
+ return p_hinst->p_rep_buffer_out;
+}
+
+/**
+ * @brief Auxiliary function to access to HID IN endpoint address.
+ *
+ * @param[in] p_inst Class instance data.
+ *
+ * @return IN endpoint address.
+ */
+static inline nrf_drv_usbd_ep_t app_usbd_hid_epin_addr_get(app_usbd_class_inst_t const * p_inst)
+{
+ app_usbd_class_iface_conf_t const * class_iface;
+ class_iface = app_usbd_class_iface_get(p_inst, APP_USBD_HID_IFACE_IDX);
+
+ app_usbd_class_ep_conf_t const * ep_cfg;
+ ep_cfg = app_usbd_class_iface_ep_get(class_iface, APP_USBD_HID_EPIN_IDX);
+
+ return app_usbd_class_ep_address_get(ep_cfg);
+}
+
+/**
+ * @brief Auxiliary function to access to HID generic OUT endpoint address.
+ *
+ * @param[in] p_inst Class instance data.
+ *
+ * @return OUT endpoint address.
+ */
+static inline nrf_drv_usbd_ep_t app_usbd_hid_epout_addr_get(app_usbd_class_inst_t const * p_inst)
+{
+ app_usbd_class_iface_conf_t const * class_iface;
+ class_iface = app_usbd_class_iface_get(p_inst, APP_USBD_HID_IFACE_IDX);
+
+ app_usbd_class_ep_conf_t const * ep_cfg;
+ ep_cfg = app_usbd_class_iface_ep_get(class_iface, APP_USBD_HID_EPOUT_IDX);
+
+ return app_usbd_class_ep_address_get(ep_cfg);
+}
+
+/** @} */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* APP_USBD_HID_H__ */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/usbd/class/hid/app_usbd_hid_types.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/usbd/class/hid/app_usbd_hid_types.h
new file mode 100644
index 0000000..9fc3486
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/usbd/class/hid/app_usbd_hid_types.h
@@ -0,0 +1,281 @@
+/**
+ * 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#ifndef APP_USBD_HID_TYPES_H__
+#define APP_USBD_HID_TYPES_H__
+
+#include <stdint.h>
+
+#include "app_usbd_types.h"
+#include "sdk_common.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @defgroup app_usbd_hid_types USB HID class types
+ * @ingroup app_usbd_hid
+ *
+ * @brief @tagAPI52840 Module with types and definitions used by HID modules.
+ * @{
+ */
+
+/**
+ * @brief HID class definition in interface descriptor.
+ *
+ * @ref app_usbd_descriptor_iface_t::bInterfaceClass
+ * */
+#define APP_USBD_HID_CLASS 0x03
+
+/**
+ * @brief HID subclass definition.
+ *
+ * @see HID 1.11 specification: Chapter 4.2 Subclass.
+ * @ref app_usbd_descriptor_iface_t::bInterfaceSubClass
+ * */
+typedef enum {
+ APP_USBD_HID_SUBCLASS_NONE = 0x00, /**< Undefined subclass. */
+ APP_USBD_HID_SUBCLASS_BOOT = 0x01, /**< Boot subclass. */
+} app_usbd_hid_subclass_t;
+
+/**
+ * @brief HID protocol types defined by specification.
+ *
+ * Value need to be filled in interface descriptor.
+ * @ref app_usbd_descriptor_iface_t::bInterfaceProtocol
+ */
+typedef enum {
+ APP_USBD_HID_PROTO_GENERIC = 0x00, /**< GENERIC protocol. */
+ APP_USBD_HID_PROTO_KEYBOARD = 0x01, /**< KEYBOARD protocol. */
+ APP_USBD_HID_PROTO_MOUSE = 0x02, /**< MOUSE protocol. */
+ APP_USBD_HID_PROTO_MULTITOUCH = 0x03, /**< MULTITOUCH protocol. */
+} app_usbd_hid_protocol_t;
+
+
+/**
+ * @brief HID country code ID.
+ *
+ * Look into @ref app_usbd_hid_descriptor_t::bCountryCode.
+ */
+typedef enum {
+ APP_USBD_HID_COUNTRY_NOT_SUPPORTED = 0 , /**< NOT_SUPPORTED */
+ APP_USBD_HID_COUNTRY_ARABIC = 1 , /**< ARABIC */
+ APP_USBD_HID_COUNTRY_BELGIAN = 2 , /**< BELGIAN */
+ APP_USBD_HID_COUNTRY_CANADIAN_BILINGUAL= 3 , /**< CANADIAN_BILINGUAL */
+ APP_USBD_HID_COUNTRY_CANADIAN_FRENCH = 4 , /**< CANADIAN_FRENCH */
+ APP_USBD_HID_COUNTRY_CZECH_REPUBLIC = 5 , /**< CZECH_REPUBLIC */
+ APP_USBD_HID_COUNTRY_DANISH = 6 , /**< DANISH */
+ APP_USBD_HID_COUNTRY_FINNISH = 7 , /**< FINNISH */
+ APP_USBD_HID_COUNTRY_FRENCH = 8 , /**< FRENCH */
+ APP_USBD_HID_COUNTRY_GERMAN = 9 , /**< GERMAN */
+ APP_USBD_HID_COUNTRY_GREEK = 10, /**< GREEK */
+ APP_USBD_HID_COUNTRY_HEBREW = 11, /**< HEBREW */
+ APP_USBD_HID_COUNTRY_HUNGARY = 12, /**< HUNGARY */
+ APP_USBD_HID_COUNTRY_INTERNATIONAL_ISO = 13, /**< INTERNATIONAL_ISO */
+ APP_USBD_HID_COUNTRY_ITALIAN = 14, /**< ITALIAN */
+ APP_USBD_HID_COUNTRY_JAPAN_KATAKANA = 15, /**< JAPAN_KATAKANA */
+ APP_USBD_HID_COUNTRY_KOREAN = 16, /**< KOREAN */
+ APP_USBD_HID_COUNTRY_LATIN_AMERICAN = 17, /**< LATIN_AMERICAN */
+ APP_USBD_HID_COUNTRY_NETHERLANDS_DUTCH = 18, /**< NETHERLANDS_DUTCH */
+ APP_USBD_HID_COUNTRY_NORWEGIAN = 19, /**< NORWEGIAN */
+ APP_USBD_HID_COUNTRY_PERSIAN_FARSI = 20, /**< PERSIAN_FARSI */
+ APP_USBD_HID_COUNTRY_POLAND = 21, /**< POLAND */
+ APP_USBD_HID_COUNTRY_PORTUGUESE = 22, /**< PORTUGUESE */
+ APP_USBD_HID_COUNTRY_RUSSIA = 23, /**< RUSSIA */
+ APP_USBD_HID_COUNTRY_SLOVAKIA = 24, /**< SLOVAKIA */
+ APP_USBD_HID_COUNTRY_SPANISH = 25, /**< SPANISH */
+ APP_USBD_HID_COUNTRY_SWEDISH = 26, /**< SWEDISH */
+ APP_USBD_HID_COUNTRY_SWISS_FRENCH = 27, /**< SWISS_FRENCH */
+ APP_USBD_HID_COUNTRY_SWISS_GERMAN = 28, /**< SWISS_GERMAN */
+ APP_USBD_HID_COUNTRY_SWITZERLAND = 29, /**< SWITZERLAND */
+ APP_USBD_HID_COUNTRY_TAIWAN = 30, /**< TAIWAN */
+ APP_USBD_HID_COUNTRY_TURKISH_Q = 31, /**< TURKISH_Q */
+ APP_USBD_HID_COUNTRY_UK = 32, /**< UK */
+ APP_USBD_HID_COUNTRY_US = 33, /**< US */
+ APP_USBD_HID_COUNTRY_YUGOSLAVIA = 34, /**< YUGOSLAVIA */
+ APP_USBD_HID_COUNTRY_TURKISH_F = 35, /**< TURKISH_F */
+} app_usbd_hid_country_code_t;
+
+/**
+ * @brief HID descriptor types.
+ *
+ * @ref app_usbd_hid_descriptor_t::bRDescriptorType
+ */
+typedef enum {
+ APP_USBD_HID_DESCRIPTOR_HID = 0x21, /**< HID descriptor. */
+ APP_USBD_HID_DESCRIPTOR_REPORT = 0x22, /**< REPORT descriptor. */
+ APP_USBD_HID_DESCRIPTOR_PHYSICAL = 0x23, /**< PHYSICAL descriptor. */
+} app_usbd_hid_descriptor_type_t;
+
+#pragma pack(push, 1)
+
+/**
+ * @brief HID report descriptor entry at the end of HID descriptor.
+ *
+ * @param size Report descriptor size.
+ */
+#define APP_USBD_HID_REPORT_ITEM(size) \
+ APP_USBD_HID_DESCRIPTOR_REPORT, ((size) & 0xFF), ((size) / 256)
+
+
+/**
+ * @brief HID physical descriptor entry at the end of HID descriptor.
+ *
+ * @param size Physical descriptor size.
+ */
+#define APP_USBD_HID_PHYSICAL_ITEM(size) \
+ APP_USBD_HID_DESCRIPTOR_PHYSICAL, ((size) & 0xFF), ((size) / 256)
+
+
+/**
+ * @brief HID descriptor, binary layout.
+ */
+typedef union {
+ struct {
+ uint8_t bLength; //!< Length of descriptor.
+ uint8_t bDescriptorType; //!< Descriptor type @ref APP_USBD_HID_DESCRIPTOR_HID.
+ uint16_t bcdHID; //!< HID release number (BCD format, little endian).
+ uint8_t bCountryCode; //!< Country code.
+ uint8_t bNumDescriptors; //!< Number of class descriptors.
+ struct {
+ uint8_t bRDescriptorType; //!< Class descriptor type.
+ uint16_t wDescriptorLength; //!< Class descriptor length (little endian).
+ } reports[];
+ } raw;
+} app_usbd_hid_descriptor_t;
+
+#pragma pack(pop)
+
+
+/**
+ * @brief HID requests defined by specification.
+ */
+typedef enum {
+ APP_USBD_HID_REQ_GET_REPORT = 0x01, /**< REPORT: device -> host (required). */
+ APP_USBD_HID_REQ_GET_IDLE = 0x02, /**< IDLE: device -> host (not required). */
+ APP_USBD_HID_REQ_GET_PROTOCOL = 0x03, /**< PROTOCOL: device -> host (required for boot protocol). */
+ APP_USBD_HID_REQ_SET_REPORT = 0x09, /**< REPORT: host -> device (not required). */
+ APP_USBD_HID_REQ_SET_IDLE = 0x0A, /**< IDLE: no data stage (required for boot protocol). */
+ APP_USBD_HID_REQ_SET_PROTOCOL = 0x0B, /**< PROTOCOL: no data stage(required for boot protocol). */
+} app_usbd_hid_req_t;
+
+/**
+ * @brief HID report type.
+ */
+typedef enum {
+ APP_USBD_HID_REPORT_TYPE_INPUT = 0x01,/**< INPUT report type */
+ APP_USBD_HID_REPORT_TYPE_OUTPUT = 0x02,/**< OUTPUT report type */
+ APP_USBD_HID_REPORT_TYPE_FEATURE = 0x03,/**< FEATURE report type */
+} app_usbd_hid_report_type_t;
+
+
+/**
+ * @brief Hid version BCD value definition
+ *
+ * The version of the HID descriptors used.
+ */
+#define APP_USBD_HID_BCD_VER APP_USBD_BCD_VER_MAKE(1, 11)
+
+/**
+ * @brief HID version BCD value definition distributed into bytes
+ *
+ * This is a value written directly into @ref app_usbd_hid_descriptor_t::bcdHID.
+ * @sa APP_USBD_HID_BCD_VER
+ */
+#define APP_USBD_HID_BCD_VER_BYTES LSB_16(APP_USBD_HID_BCD_VER), MSB_16(APP_USBD_HID_BCD_VER)
+
+/**
+ * @brief Initializer of interface descriptor for HID classes.
+ *
+ * @param interface_number Interface number.
+ * @param endpoints_num Number of endpoints.
+ * @param subclass Subclass type @ref app_usbd_hid_subclass_t.
+ * @param protocol Protocol type @ref app_usbd_hid_protocol_t.
+ */
+#define APP_USBD_HID_INTERFACE_DSC(interface_number, endpoints_num, subclass, protocol) \
+ /*.bLength = */ sizeof(app_usbd_descriptor_iface_t), \
+ /*.bDescriptorType = */ APP_USBD_DESCRIPTOR_INTERFACE, \
+ /*.bInterfaceNumber = */ interface_number, \
+ /*.bAlternateSetting = */ 0x00, \
+ /*.bNumEndpoints = */ endpoints_num, \
+ /*.bInterfaceClass = */ APP_USBD_HID_CLASS, \
+ /*.bInterfaceSubClass = */ subclass, \
+ /*.bInterfaceProtocol = */ protocol, \
+ /*.iInterface = 0, */ 0x00, \
+
+
+/**
+ * @brief Initializer of HID descriptor for HID classes.
+ *
+ * @param ... Report/physical item list.
+ */
+#define APP_USBD_HID_HID_DSC(...) \
+ /*.bLength = */ sizeof(app_usbd_hid_descriptor_t) + 3 * (NUM_VA_ARGS(__VA_ARGS__)), \
+ /*.bDescriptorType = */ APP_USBD_HID_DESCRIPTOR_HID, \
+ /*.bcdHID = */ APP_USBD_HID_BCD_VER_BYTES, \
+ /*.bCountryCode = */ APP_USBD_HID_COUNTRY_NOT_SUPPORTED, \
+ /*.bNumDescriptors = */ (NUM_VA_ARGS(__VA_ARGS__)), \
+ /*.bRDescriptorType = */ APP_USBD_HID_REPORT_ITEM(sizeof(GET_VA_ARG_1_(__VA_ARGS__))), \
+ /*.wDescriptorLength = */
+
+/**
+ * @brief Initializer of endpoint descriptor for HID classes.
+ *
+ * @param endpoint Endpoint number.
+ * @param ep_size Endpoint size.
+ * @param ep_interval Endpoint interval (milliseconds).
+ */
+#define APP_USBD_HID_EP_DSC(endpoint, ep_size, ep_interval) \
+ /*.bLength = */ sizeof(app_usbd_descriptor_ep_t), \
+ /*.bDescriptorType = */ APP_USBD_DESCRIPTOR_ENDPOINT, \
+ /*.bEndpointAddress = */ endpoint, \
+ /*.bmAttributes = */ APP_USBD_DESCRIPTOR_EP_ATTR_TYPE_INTERRUPT, \
+ /*.wMaxPacketSize = */ APP_USBD_U16_TO_RAW_DSC(ep_size), \
+ /*.bInterval = */ ep_interval, \
+
+
+
+/** @} */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* APP_USBD_HID_TYPES_H__ */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/usbd/class/hid/generic/app_usbd_hid_generic.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/usbd/class/hid/generic/app_usbd_hid_generic.c
new file mode 100644
index 0000000..61dea15
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/usbd/class/hid/generic/app_usbd_hid_generic.c
@@ -0,0 +1,506 @@
+/**
+ * Copyright (c) 2016 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#include "sdk_common.h"
+#if NRF_MODULE_ENABLED(APP_USBD_HID_GENERIC)
+
+#include <string.h>
+#include "app_usbd_hid_generic.h"
+#include "app_util_platform.h"
+
+
+/**
+ * @ingroup app_usbd_hid_generic
+ *
+ * Module with types, definitions and API used by HID generic.
+ * @{
+ */
+
+/**
+ * @brief Auxiliary function to access HID generic context data.
+ *
+ * @param[in] p_generic HID generic instance.
+ *
+ * @return HID generic class instance data context.
+ */
+static inline app_usbd_hid_generic_ctx_t *
+hid_generic_ctx_get(app_usbd_hid_generic_t const * p_generic)
+{
+ ASSERT(p_generic != NULL);
+ ASSERT(p_generic->specific.p_data != NULL);
+ return &p_generic->specific.p_data->ctx;
+}
+
+
+/**
+ * @brief Auxiliary function to access HID generic instance data.
+ *
+ * @param[in] p_inst Class instance data.
+ *
+ * @return HID generic class instance data.
+ */
+static inline app_usbd_hid_generic_t const *
+hid_generic_get(app_usbd_class_inst_t const * p_inst)
+{
+ ASSERT(p_inst != NULL);
+ return (app_usbd_hid_generic_t const *)p_inst;
+}
+
+
+/**
+ * @brief Returns report ID buffer descriptor.
+ *
+ * @param[in] p_generic Internal HID generic context.
+ *
+ * @return HID report buffer.
+ */
+static inline app_usbd_hid_report_buffer_t *
+hid_generic_rep_buffer_get(app_usbd_hid_generic_t const * p_generic)
+{
+ ASSERT(p_generic != NULL);
+ app_usbd_hid_inst_t const * p_hinst = &p_generic->specific.inst.hid_inst;
+
+ return app_usbd_hid_rep_buff_in_get(p_hinst);
+}
+
+
+/**
+ * @brief Auxiliary function to prepare report transfer buffer to next transfer.
+ *
+ * @param[in] p_generic HID generic instance.
+ *
+ * @retval true Next transfer required.
+ * @retval false Next transfer not required.
+ */
+static inline bool hid_generic_transfer_next(app_usbd_hid_generic_t const * p_generic)
+{
+ nrf_queue_t const * p_rep_in_queue = p_generic->specific.inst.p_rep_in_queue;
+
+ return !nrf_queue_is_empty(p_rep_in_queue);
+}
+
+
+/**
+ * @brief Triggers IN endpoint transfer.
+ *
+ * @param[in] p_generic HID generic instance.
+ *
+ * @return Standard error code.
+ */
+static inline ret_code_t hid_generic_transfer_set(app_usbd_hid_generic_t const * p_generic)
+{
+ app_usbd_class_inst_t const * p_inst = (app_usbd_class_inst_t const *)p_generic;
+ app_usbd_hid_generic_ctx_t * p_generic_ctx = hid_generic_ctx_get(p_generic);
+
+ nrf_drv_usbd_ep_t ep_addr = app_usbd_hid_epin_addr_get(p_inst);
+
+ app_usbd_hid_state_flag_clr(&p_generic_ctx->hid_ctx,
+ APP_USBD_HID_STATE_FLAG_TRANS_IN_PROGRESS);
+
+ if (!hid_generic_transfer_next(p_generic))
+ {
+ return NRF_SUCCESS;
+ }
+
+ app_usbd_hid_report_buffer_t * p_rep_buff = hid_generic_rep_buffer_get(p_generic);
+ nrf_queue_t const * p_rep_in_queue = p_generic->specific.inst.p_rep_in_queue;
+
+ ret_code_t ret = nrf_queue_pop(p_rep_in_queue, p_rep_buff);
+ ASSERT(ret == NRF_SUCCESS);
+
+ NRF_DRV_USBD_TRANSFER_IN(transfer, p_rep_buff->p_buff, p_rep_buff->size);
+ CRITICAL_REGION_ENTER();
+ ret = app_usbd_ep_transfer(ep_addr, &transfer);
+ if (ret == NRF_SUCCESS)
+ {
+ app_usbd_hid_state_flag_set(&p_generic_ctx->hid_ctx,
+ APP_USBD_HID_STATE_FLAG_TRANS_IN_PROGRESS);
+ }
+ CRITICAL_REGION_EXIT();
+
+ return ret;
+}
+
+
+ret_code_t app_usbd_hid_generic_in_report_set(app_usbd_hid_generic_t const * p_generic,
+ const void * p_buff,
+ size_t size)
+{
+ app_usbd_hid_generic_ctx_t * p_generic_ctx = hid_generic_ctx_get(p_generic);
+ nrf_queue_t const * p_rep_in_queue = p_generic->specific.inst.p_rep_in_queue;
+ const app_usbd_hid_report_buffer_t rep_buff = {
+ .p_buff = (void *)p_buff,
+ .size = size,
+ };
+
+ if (nrf_queue_push(p_rep_in_queue, &rep_buff) != NRF_SUCCESS)
+ {
+ return NRF_ERROR_BUSY;
+ }
+
+ ret_code_t ret = NRF_SUCCESS;
+ if (app_usbd_hid_trans_required(&p_generic_ctx->hid_ctx))
+ {
+ ret = hid_generic_transfer_set(p_generic);
+ }
+
+ return ret;
+}
+
+
+const void * app_usbd_hid_generic_in_report_get(app_usbd_hid_generic_t const * p_generic,
+ size_t * p_size)
+{
+ app_usbd_hid_inst_t const * p_hinst = &p_generic->specific.inst.hid_inst;
+
+ *p_size = p_hinst->p_rep_buffer_in->size;
+ return p_hinst->p_rep_buffer_in->p_buff;
+}
+
+
+const void * app_usbd_hid_generic_out_report_get(app_usbd_hid_generic_t const * p_generic,
+ size_t * p_size)
+{
+ app_usbd_hid_inst_t const * p_hinst = &p_generic->specific.inst.hid_inst;
+
+ *p_size = p_hinst->p_rep_buffer_out->size;
+ return p_hinst->p_rep_buffer_out->p_buff;
+}
+
+
+/**
+ * @brief @ref app_usbd_hid_interface_t::on_get_report
+ */
+static ret_code_t hid_generic_on_get_report(app_usbd_class_inst_t const * p_inst,
+ app_usbd_setup_evt_t const * p_setup_ev)
+{
+ app_usbd_hid_generic_t const * p_hinst = hid_generic_get(p_inst);
+ uint8_t const * p_rep_buffer = NULL;
+ size_t buffer_size = 0;
+
+ if (p_setup_ev->setup.wValue.hb == APP_USBD_HID_REPORT_TYPE_INPUT)
+ {
+ p_rep_buffer = app_usbd_hid_generic_in_report_get(p_hinst, &buffer_size);
+ }
+ else if (p_setup_ev->setup.wValue.hb == APP_USBD_HID_REPORT_TYPE_OUTPUT)
+ {
+ p_rep_buffer = app_usbd_hid_generic_out_report_get(p_hinst, &buffer_size);
+ }
+ else
+ {
+ return NRF_ERROR_NOT_SUPPORTED;
+ }
+
+ return app_usbd_core_setup_rsp(&(p_setup_ev->setup), p_rep_buffer, buffer_size);
+}
+
+
+static ret_code_t hid_generic_on_set_report_data_cb(nrf_drv_usbd_ep_status_t status,
+ void * p_context)
+{
+ app_usbd_hid_user_ev_handler_t handler;
+ app_usbd_hid_generic_t const * p_generic = (app_usbd_hid_generic_t const *)p_context;
+
+ if (status != NRF_USBD_EP_OK)
+ {
+ return NRF_ERROR_INTERNAL;
+ }
+
+ handler = p_generic->specific.inst.hid_inst.user_event_handler;
+ handler((app_usbd_class_inst_t const *)p_generic,
+ APP_USBD_HID_USER_EVT_OUT_REPORT_READY);
+ return NRF_SUCCESS;
+}
+
+
+/**
+ * @brief @ref app_usbd_hid_interface_t::on_set_report
+ */
+static ret_code_t hid_generic_on_set_report(app_usbd_class_inst_t const * p_inst,
+ app_usbd_setup_evt_t const * p_setup_ev)
+{
+ app_usbd_hid_generic_t const * p_generic = hid_generic_get(p_inst);
+
+ /*Request setup data*/
+ app_usbd_hid_report_buffer_t const * p_rep_buff;
+
+ p_rep_buff = app_usbd_hid_rep_buff_out_get(&p_generic->specific.inst.hid_inst);
+
+ p_rep_buff->p_buff[0] = p_setup_ev->setup.wValue.lb;
+ NRF_DRV_USBD_TRANSFER_OUT(transfer, p_rep_buff->p_buff + 1, p_rep_buff->size - 1);
+
+ ret_code_t ret;
+ CRITICAL_REGION_ENTER();
+ ret = app_usbd_ep_transfer(NRF_DRV_USBD_EPOUT0, &transfer);
+ if (ret == NRF_SUCCESS)
+ {
+ app_usbd_core_setup_data_handler_desc_t desc = {
+ .handler = hid_generic_on_set_report_data_cb,
+ .p_context = (void *)p_generic
+ };
+
+ ret = app_usbd_core_setup_data_handler_set(NRF_DRV_USBD_EPOUT0, &desc);
+ }
+ CRITICAL_REGION_EXIT();
+
+ return ret;
+}
+
+
+/**
+ * @brief @ref app_usbd_hid_interface_t::ep_transfer_in
+ */
+static ret_code_t hid_generic_ep_transfer_in(app_usbd_class_inst_t const * p_inst)
+{
+ app_usbd_hid_generic_t const * p_generic = hid_generic_get(p_inst);
+ app_usbd_hid_generic_ctx_t * p_generic_ctx = hid_generic_ctx_get(p_generic);
+
+ nrf_queue_t const * p_rep_in_queue = p_generic->specific.inst.p_rep_in_queue;
+
+ if (nrf_queue_is_empty(p_rep_in_queue))
+ {
+ app_usbd_hid_state_flag_clr(&p_generic_ctx->hid_ctx,
+ APP_USBD_HID_STATE_FLAG_TRANS_IN_PROGRESS);
+ return NRF_SUCCESS;
+ }
+
+ /* Get next report to send */
+ return hid_generic_transfer_set((app_usbd_hid_generic_t const *)p_inst);
+}
+
+
+/**
+ * @brief @ref app_usbd_hid_interface_t::ep_transfer_out
+ */
+static ret_code_t hid_generic_ep_transfer_out(app_usbd_class_inst_t const * p_inst)
+{
+
+ app_usbd_hid_generic_t const * p_generic = hid_generic_get(p_inst);
+ nrf_drv_usbd_ep_t ep_addr = app_usbd_hid_epout_addr_get(p_inst);
+
+ /*Request setup data*/
+ app_usbd_hid_report_buffer_t const * p_rep_buff;
+
+ p_rep_buff = app_usbd_hid_rep_buff_out_get(&p_generic->specific.inst.hid_inst);
+ NRF_DRV_USBD_TRANSFER_OUT(transfer, p_rep_buff->p_buff, p_rep_buff->size);
+
+ return app_usbd_ep_transfer(ep_addr, &transfer);
+}
+
+
+/**
+ * @brief @ref app_usbd_class_interface_t::event_handler
+ */
+static ret_code_t hid_generic_event_handler(app_usbd_class_inst_t const * p_inst,
+ app_usbd_complex_evt_t const * p_event)
+{
+ ASSERT(p_inst != NULL);
+ ASSERT(p_event != NULL);
+
+ app_usbd_hid_generic_t const * p_generic = hid_generic_get(p_inst);
+ app_usbd_hid_inst_t const * p_hinst = &p_generic->specific.inst.hid_inst;
+ app_usbd_hid_generic_ctx_t * p_generic_ctx = hid_generic_ctx_get(p_generic);
+ app_usbd_hid_ctx_t * p_hid_ctx = &p_generic_ctx->hid_ctx;
+
+ /*Try handle event by generic HID event handler*/
+ return app_usbd_hid_event_handler(p_inst, p_hinst, p_hid_ctx, p_event);
+}
+
+
+static uint8_t hid_generic_get_class_descriptors_count(app_usbd_class_inst_t const * p_inst)
+{
+ app_usbd_hid_generic_t const * p_generic = hid_generic_get(p_inst);
+ app_usbd_hid_inst_t const * p_hinst = &p_generic->specific.inst.hid_inst;
+
+ return p_hinst->subclass_desc_count;
+}
+
+
+static app_usbd_descriptor_t hid_generic_get_class_descriptors_type(
+ app_usbd_class_inst_t const * p_inst,
+ uint8_t desc_num)
+{
+ app_usbd_hid_generic_t const * p_generic = hid_generic_get(p_inst);
+ app_usbd_hid_inst_t const * p_hinst = &p_generic->specific.inst.hid_inst;
+
+ return p_hinst->p_subclass_desc[desc_num]->type;
+}
+
+
+static size_t hid_generic_get_class_descriptors_length(app_usbd_class_inst_t const * p_inst,
+ uint8_t desc_num)
+{
+ app_usbd_hid_generic_t const * p_generic = hid_generic_get(p_inst);
+ app_usbd_hid_inst_t const * p_hinst = &p_generic->specific.inst.hid_inst;
+
+ return p_hinst->p_subclass_desc[desc_num]->size;
+}
+
+
+static uint8_t hid_generic_get_class_descriptors_data(app_usbd_class_inst_t const * p_inst,
+ uint8_t desc_num,
+ uint32_t cur_byte)
+{
+ app_usbd_hid_generic_t const * p_generic = hid_generic_get(p_inst);
+ app_usbd_hid_inst_t const * p_hinst = &p_generic->specific.inst.hid_inst;
+
+ return p_hinst->p_subclass_desc[desc_num]->p_data[cur_byte];
+}
+
+
+/**
+ * @brief @ref app_usbd_class_interface_t::feed_descriptors
+ */
+static bool hid_generic_feed_descriptors(app_usbd_class_descriptor_ctx_t * p_ctx,
+ app_usbd_class_inst_t const * p_inst,
+ uint8_t * p_buff,
+ size_t max_size)
+{
+ static uint8_t ifaces = 0;
+ ifaces = app_usbd_class_iface_count_get(p_inst);
+ app_usbd_hid_generic_t const * p_generic = hid_generic_get(p_inst);
+
+ APP_USBD_CLASS_DESCRIPTOR_BEGIN(p_ctx, p_buff, max_size);
+
+ static uint8_t i = 0;
+
+ for (i = 0; i < ifaces; i++)
+ {
+ /* INTERFACE DESCRIPTOR */
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(0x09); // bLength
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(APP_USBD_DESCRIPTOR_INTERFACE); // bDescriptorType = Interface
+
+ static app_usbd_class_iface_conf_t const * p_cur_iface = NULL;
+ p_cur_iface = app_usbd_class_iface_get(p_inst, i);
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(app_usbd_class_iface_number_get(p_cur_iface)); // bInterfaceNumber
+
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(0x00); // bAlternateSetting
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(app_usbd_class_iface_ep_count_get(p_cur_iface)); // bNumEndpoints
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(APP_USBD_HID_CLASS); // bInterfaceClass = HID
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(p_generic->specific.inst.hid_inst.subclass_boot); // bInterfaceSubclass (Boot Interface)
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(p_generic->specific.inst.hid_inst.protocol); // bInterfaceProtocol
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(0x00); // iInterface
+
+ /* HID DESCRIPTOR */
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(0x09); // bLength
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(APP_USBD_HID_DESCRIPTOR_HID); // bDescriptorType = HID
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(LSB_16(APP_USBD_HID_BCD_VER)); // bcdHID LSB
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(MSB_16(APP_USBD_HID_BCD_VER)); // bcdHID MSB
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(APP_USBD_HID_COUNTRY_NOT_SUPPORTED); // bCountryCode
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(hid_generic_get_class_descriptors_count(p_inst)); // bNumDescriptors
+
+ static uint8_t class_desc_cnt = 0;
+ class_desc_cnt = hid_generic_get_class_descriptors_count(p_inst);
+ static uint8_t j = 0;
+ static uint16_t class_desc_len = 0;
+
+ for (j = 0; j < class_desc_cnt; j++)
+ {
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(hid_generic_get_class_descriptors_type(p_inst, j)); // bDescriptorType
+
+ class_desc_len = hid_generic_get_class_descriptors_length(p_inst, j);
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(LSB_16(class_desc_len)); // wDescriptorLength LSB
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(MSB_16(class_desc_len)); // wDescriptorLength MSB
+ }
+
+ static uint8_t endpoints = 0;
+ endpoints = app_usbd_class_iface_ep_count_get(p_cur_iface);
+
+ for (j = 0; j < endpoints; j++)
+ {
+ /* ENDPOINT DESCRIPTOR */
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(0x07); // bLengths
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(APP_USBD_DESCRIPTOR_ENDPOINT); // bDescriptorType = Endpoint
+
+ static app_usbd_class_ep_conf_t const * p_cur_ep = NULL;
+ p_cur_ep = app_usbd_class_iface_ep_get(p_cur_iface, i);
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(app_usbd_class_ep_address_get(p_cur_ep)); // bEndpointAddress
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(APP_USBD_DESCRIPTOR_EP_ATTR_TYPE_INTERRUPT); // bmAttributes
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(LSB_16(NRF_DRV_USBD_EPSIZE)); // wMaxPacketSize LSB
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(MSB_16(NRF_DRV_USBD_EPSIZE)); // wMaxPacketSize MSB
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(0x01); // bInterval
+ }
+ }
+
+ APP_USBD_CLASS_DESCRIPTOR_END();
+}
+
+/**
+ * @brief @ref app_usbd_hid_interface_t::feed_subclass_descriptor
+ */
+
+static bool hid_generic_feed_subclass_descriptor(app_usbd_class_descriptor_ctx_t * p_ctx,
+ app_usbd_class_inst_t const * p_inst,
+ uint8_t * p_buff,
+ size_t max_size,
+ uint8_t index)
+{
+ APP_USBD_CLASS_DESCRIPTOR_BEGIN(p_ctx, p_buff, max_size);
+
+ /* PHYSICAL AND REPORT DESCRIPTORS */
+ static uint32_t cur_byte = 0;
+ static size_t sub_desc_size = 0;
+ sub_desc_size = hid_generic_get_class_descriptors_length(p_inst, index);
+
+ for (cur_byte = 0; cur_byte < sub_desc_size; cur_byte++)
+ {
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(hid_generic_get_class_descriptors_data(p_inst, index,
+ cur_byte));
+ }
+
+ APP_USBD_CLASS_DESCRIPTOR_END();
+}
+
+
+/** @} */
+
+const app_usbd_hid_methods_t app_usbd_hid_generic_methods = {
+ .on_get_report = hid_generic_on_get_report,
+ .on_set_report = hid_generic_on_set_report,
+ .ep_transfer_in = hid_generic_ep_transfer_in,
+ .ep_transfer_out = hid_generic_ep_transfer_out,
+ .feed_subclass_descriptor = hid_generic_feed_subclass_descriptor,
+};
+
+const app_usbd_class_methods_t app_usbd_generic_class_methods = {
+ .event_handler = hid_generic_event_handler,
+ .feed_descriptors = hid_generic_feed_descriptors,
+};
+
+#endif //NRF_MODULE_ENABLED(APP_USBD_HID_GENERIC)
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/usbd/class/hid/generic/app_usbd_hid_generic.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/usbd/class/hid/generic/app_usbd_hid_generic.h
new file mode 100644
index 0000000..3642b16
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/usbd/class/hid/generic/app_usbd_hid_generic.h
@@ -0,0 +1,223 @@
+/**
+ * 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#ifndef APP_USBD_HID_GENERIC_H__
+#define APP_USBD_HID_GENERIC_H__
+
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <stdint.h>
+#include <stdbool.h>
+
+#include "nrf_drv_usbd.h"
+#include "app_usbd_class_base.h"
+#include "app_usbd_hid_types.h"
+#include "app_usbd_hid.h"
+#include "app_usbd.h"
+#include "app_usbd_core.h"
+#include "app_usbd_descriptor.h"
+#include "app_usbd_hid_generic_desc.h"
+#include "app_usbd_hid_generic_internal.h"
+
+/**
+ * @defgroup app_usbd_hid_generic USB HID generic
+ * @ingroup app_usbd_hid
+ *
+ * @brief @tagAPI52840 Module with types, definitions, and API used by the HID generic class.
+ * @{
+ */
+
+
+#ifdef DOXYGEN
+/**
+ * @brief HID generic class instance type
+ *
+ * @ref APP_USBD_CLASS_TYPEDEF
+ */
+typedef struct { } app_usbd_hid_generic_t;
+#else
+/*lint -save -e10 -e26 -e123 -e505 */
+APP_USBD_CLASS_TYPEDEF(app_usbd_hid_generic, \
+ APP_USBD_HID_GENERIC_CONFIG(0, (NRF_DRV_USBD_EPIN1, NRF_DRV_USBD_EPOUT1)), \
+ APP_USBD_HID_GENERIC_INSTANCE_SPECIFIC_DEC, \
+ APP_USBD_HID_GENERIC_DATA_SPECIFIC_DEC \
+);
+/*lint -restore*/
+#endif
+
+/**
+ * @brief Global definition of app_usbd_hid_generic_t class.
+ *
+ * @param instance_name Name of global instance.
+ * @param interface_number Unique interface index.
+ * @param user_ev_handler User event handler (optional).
+ * @param endpoint_list Input endpoint list (@ref nrf_drv_usbd_ep_t).
+ * @param subclass_descriptors HID subclass descriptors.
+ * @param report_in_queue_size IN report queue size.
+ * @param report_out_maxsize Maximum output report size.
+ * @param subclass_boot Subclass boot. (@ref app_usbd_hid_subclass_t)
+ * @param protocol HID protocol. (@ref app_usbd_hid_protocol_t)
+ *
+ * @note This macro is just simplified version of @ref APP_USBD_HID_GENERIC_GLOBAL_DEF_INTERNAL.
+ *
+ * Example class definition:
+ * @code
+
+ APP_USBD_HID_GENERIC_SUBCLASS_REPORT_DESC(mouse_desc,APP_USBD_HID_MOUSE_REPORT_DSC_BUTTON(2));
+
+ static const app_usbd_hid_subclass_desc_t * reps[] = {&mouse_desc};
+
+ #define ENDPOINT_LIST \
+ ( \
+ NRF_DRV_USBD_EPIN1 \
+ )
+
+ #define REPORT_COUNT 1
+ #define REPORT_OUT_MAXSIZE 0
+
+ APP_USBD_HID_GENERIC_GLOBAL_DEF(m_app_hid_generic,
+ 0,
+ hid_user_ev_handler,
+ ENDPOINT_LIST(),
+ reps,
+ REPORT_IN_QUEUE_SIZE,
+ REPORT_OUT_MAXSIZE,
+ APP_USBD_HID_SUBCLASS_BOOT,
+ APP_USBD_HID_PROTO_MOUSE);
+ @endcode
+ *
+ */
+#define APP_USBD_HID_GENERIC_GLOBAL_DEF(instance_name, \
+ interface_number, \
+ user_ev_handler, \
+ endpoint_list, \
+ subclass_descriptors, \
+ report_in_queue_size, \
+ report_out_maxsize, \
+ subclass_boot, \
+ protocol) \
+ APP_USBD_HID_GENERIC_GLOBAL_DEF_INTERNAL(instance_name, \
+ interface_number, \
+ user_ev_handler, \
+ endpoint_list, \
+ subclass_descriptors, \
+ report_in_queue_size, \
+ report_out_maxsize, \
+ subclass_boot, \
+ protocol)
+
+
+/**
+ * @brief Helper function to get class instance from HID generic class.
+ *
+ * @param[in] p_generic HID generic class instance.
+ *
+ * @return Base class instance.
+ */
+static inline app_usbd_class_inst_t const *
+app_usbd_hid_generic_class_inst_get(app_usbd_hid_generic_t const * p_generic)
+{
+ return &p_generic->base;
+}
+
+/**
+ * @brief Helper function to get HID generic from base class instance.
+ *
+ * @param[in] p_inst Base class instance.
+ *
+ * @return HID generic class handle.
+ */
+static inline app_usbd_hid_generic_t const *
+app_usbd_hid_generic_class_get(app_usbd_class_inst_t const * p_inst)
+{
+ return (app_usbd_hid_generic_t const *)p_inst;
+}
+
+/**
+ * @brief New IN report trigger
+ *
+ *
+ * @param[in] p_generic HID generic class instance.
+ * @param[in] p_buff Report buffer.
+ * @param[in] size Report size.
+ *
+ * @return Standard error code.
+ */
+ret_code_t app_usbd_hid_generic_in_report_set(app_usbd_hid_generic_t const * p_generic,
+ const void * p_buff,
+ size_t size);
+
+/**
+ * @brief Returns last successful transfered IN report.
+ *
+ * @note Use this call only on @ref APP_USBD_HID_USER_EVT_IN_REPORT_DONE event.
+ *
+ * @param[in] p_generic HID generic class instance.
+ * @param[out] p_size Last transfered IN report size.
+ *
+ * @return Last transfered report ID.
+ */
+const void * app_usbd_hid_generic_in_report_get(app_usbd_hid_generic_t const * p_generic,
+ size_t * p_size);
+
+/**
+ * @brief Returns last successful transfered OUT report.
+ *
+ * @warning Use this call only on @ref APP_USBD_HID_USER_EVT_OUT_REPORT_READY event.
+ *
+ * @param[in] p_generic HID generic class instance.
+ * @param[out] p_size Last transfered OUT report size.
+ *
+ * @return Last transfered OUT report.
+ */
+const void * app_usbd_hid_generic_out_report_get(app_usbd_hid_generic_t const * p_generic,
+ size_t * p_size);
+
+
+/** @} */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* APP_USBD_HID_GENERIC_H__ */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/usbd/class/hid/generic/app_usbd_hid_generic_desc.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/usbd/class/hid/generic/app_usbd_hid_generic_desc.h
new file mode 100644
index 0000000..1ff4487
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/usbd/class/hid/generic/app_usbd_hid_generic_desc.h
@@ -0,0 +1,96 @@
+/**
+ * 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#ifndef APP_USBD_HID_GENERIC_DESC_H__
+#define APP_USBD_HID_GENERIC_DESC_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+/**
+ * @defgroup app_usbd_hid_generic_desc USB HID generic descriptors
+ * @ingroup app_usbd_hid_generic
+ *
+ * @brief @tagAPI52840 Module with descriptors used by the HID generic class.
+ * @{
+ */
+
+/**
+ * @brief Initializer of interface descriptor for HID generic class.
+ *
+ * @param interface_number Interface number.
+ * @param endpoints_num Number of endpoints.
+ * @param subclass Subclass type @ref app_usbd_hid_subclass_t.
+ * @param protocol Protocol type @ref app_usbd_hid_protocol_t.
+ */
+#define APP_USBD_HID_GENERIC_INTERFACE_DSC(interface_number, \
+ endpoints_num, \
+ subclass, \
+ protocol) \
+ APP_USBD_HID_INTERFACE_DSC(interface_number, \
+ endpoints_num, \
+ subclass, \
+ protocol) \
+
+/**
+ * @brief Initializer of HID descriptor for HID generic class.
+ *
+ * @param ... Report descriptor item.
+ */
+#define APP_USBD_HID_GENERIC_HID_DSC(...) \
+ APP_USBD_HID_HID_DSC(__VA_ARGS__)
+/**
+ * @brief Initializer of endpoint descriptor for HID generic class.
+ *
+ * @param endpoint Endpoint number.
+ */
+#define APP_USBD_HID_GENERIC_EP_DSC(endpoint) \
+ APP_USBD_HID_EP_DSC(endpoint, NRF_DRV_USBD_EPSIZE, 1)
+
+
+
+/** @} */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* APP_USBD_HID_GENERIC_DESC_H__ */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/usbd/class/hid/generic/app_usbd_hid_generic_internal.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/usbd/class/hid/generic/app_usbd_hid_generic_internal.h
new file mode 100644
index 0000000..4844fde
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/usbd/class/hid/generic/app_usbd_hid_generic_internal.h
@@ -0,0 +1,186 @@
+/**
+ * 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#ifndef APP_USBD_HID_GENERIC_INTERNAL_H__
+#define APP_USBD_HID_GENERIC_INTERNAL_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "app_usbd_hid.h"
+#include "nrf_queue.h"
+
+/**
+ * @defgroup app_usbd_hid_generic_internal USB HID generic internals
+ * @ingroup app_usbd_hid_generic
+ *
+ * @brief @tagAPI52840 Module with types, definitions, and API used by the HID generic protocol.
+ * @{
+ */
+
+
+/**
+ * @brief Forward declaration of HID generic class type.
+ *
+ */
+APP_USBD_CLASS_FORWARD(app_usbd_hid_generic);
+
+/**
+ * @brief HID generic part of class instance data.
+ *
+ */
+typedef struct {
+ app_usbd_hid_inst_t hid_inst; //!< HID instance data.
+ nrf_queue_t const * p_rep_in_queue; //!< Input report queue.
+} app_usbd_hid_generic_inst_t;
+
+/**
+ * @brief HID generic context
+ *
+ */
+typedef struct {
+ app_usbd_hid_ctx_t hid_ctx; //!< HID class context.
+} app_usbd_hid_generic_ctx_t;
+
+
+/**
+ * @brief HID generic configuration macro.
+ *
+ * Used by @ref APP_USBD_HID_GENERIC_GLOBAL_DEF.
+ *
+ * @param iface Interface number.
+ * @param endpoints Endpoint list.
+ */
+#define APP_USBD_HID_GENERIC_CONFIG(iface, endpoints) ((iface, BRACKET_EXTRACT(endpoints)))
+
+
+/**
+ * @brief Specific class constant data for HID generic class.
+ */
+#define APP_USBD_HID_GENERIC_INSTANCE_SPECIFIC_DEC app_usbd_hid_generic_inst_t inst;
+
+/**
+ * @brief Specific class data for HID generic class.
+ */
+#define APP_USBD_HID_GENERIC_DATA_SPECIFIC_DEC app_usbd_hid_generic_ctx_t ctx;
+
+/**
+ * @brief Configure internal part of HID generic instance.
+ *
+ * @param report_buff_in Input report buffers array.
+ * @param report_buff_out Output report buffer.
+ * @param user_ev_handler User event handler.
+ * @param in_report_queue IN report queue.
+ * @param subclass_descriptors HID subclass descriptors.
+ * @param subclass_boot Subclass boot. (@ref app_usbd_hid_subclass_t)
+ * @param protocol HID protocol. (@ref app_usbd_hid_protocol_t)
+ */
+#define APP_USBD_HID_GENERIC_INST_CONFIG(report_buff_in, \
+ report_buff_out, \
+ user_ev_handler, \
+ in_report_queue, \
+ subclass_descriptors, \
+ subclass_boot, \
+ protocol) \
+ .inst = { \
+ .hid_inst = APP_USBD_HID_INST_CONFIG(subclass_descriptors, \
+ subclass_boot, \
+ protocol, \
+ report_buff_in, \
+ report_buff_out, \
+ user_ev_handler, \
+ &app_usbd_hid_generic_methods), \
+ .p_rep_in_queue = in_report_queue, \
+ }
+
+/**
+ * @brief Public HID generic interface.
+ */
+extern const app_usbd_hid_methods_t app_usbd_hid_generic_methods;
+
+/**
+ * @brief Public HID generic class interface.
+ */
+extern const app_usbd_class_methods_t app_usbd_generic_class_methods;
+
+/**
+ * @brief Global definition of @ref app_usbd_hid_generic_t class.
+ *
+ * @ref APP_USBD_HID_GENERIC_GLOBAL_DEF
+ */
+#define APP_USBD_HID_GENERIC_GLOBAL_DEF_INTERNAL(instance_name, \
+ interface_number, \
+ user_ev_handler, \
+ endpoint_list, \
+ subclass_descriptors, \
+ report_in_queue_size, \
+ report_out_maxsize, \
+ subclass_boot, \
+ protocol) \
+ static app_usbd_hid_report_buffer_t CONCAT_2(instance_name, _in); \
+ APP_USBD_HID_GENERIC_GLOBAL_OUT_REP_DEF(CONCAT_2(instance_name, _out), \
+ report_out_maxsize + 1); \
+ NRF_QUEUE_DEF(app_usbd_hid_report_buffer_t, \
+ instance_name##_queue, \
+ report_in_queue_size, \
+ NRF_QUEUE_MODE_OVERFLOW); \
+ APP_USBD_CLASS_INST_GLOBAL_DEF( \
+ instance_name, \
+ app_usbd_hid_generic, \
+ &app_usbd_generic_class_methods, \
+ APP_USBD_HID_GENERIC_CONFIG(interface_number, endpoint_list), \
+ (APP_USBD_HID_GENERIC_INST_CONFIG(&CONCAT_2(instance_name, _in), \
+ &CONCAT_2(instance_name, _out), \
+ user_ev_handler, \
+ &instance_name##_queue, \
+ subclass_descriptors, \
+ subclass_boot, \
+ protocol)) \
+ )
+
+
+/** @} */
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* APP_USBD_HID_GENERIC_INTERNAL_H__ */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/usbd/class/hid/kbd/app_usbd_hid_kbd.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/usbd/class/hid/kbd/app_usbd_hid_kbd.c
new file mode 100644
index 0000000..53d03f5
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/usbd/class/hid/kbd/app_usbd_hid_kbd.c
@@ -0,0 +1,557 @@
+/**
+ * Copyright (c) 2016 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#include "sdk_common.h"
+#if NRF_MODULE_ENABLED(APP_USBD_HID_KBD)
+
+#include <string.h>
+#include "app_usbd_hid_kbd.h"
+#include "app_util_platform.h"
+
+
+/**
+ * @defgroup app_usbd_hid_kbd_internals USB HID keyboard internals
+ * @{
+ * @ingroup app_usbd_hid_kbd
+ * @internal
+ */
+
+STATIC_ASSERT(sizeof(app_usbd_hid_descriptor_t) == 6);
+
+/**
+ * @brief Auxiliary function to access HID keyboard context data.
+ *
+ * @param[in] p_inst class instance data.
+ *
+ * @return HID keyboard instance data context.
+ */
+static inline app_usbd_hid_kbd_ctx_t * hid_kbd_ctx_get(app_usbd_hid_kbd_t const * p_kbd)
+{
+ ASSERT(p_kbd != NULL);
+ ASSERT(p_kbd->specific.p_data != NULL);
+ return &p_kbd->specific.p_data->ctx;
+}
+
+
+/**
+ * @brief Auxiliary function to access HID keyboard instance data.
+ *
+ * @param[in] p_inst class instance data.
+ *
+ * @return HID keyboard instance data.
+ */
+static inline app_usbd_hid_kbd_t const * hid_kbd_get(app_usbd_class_inst_t const * p_inst)
+{
+ ASSERT(p_inst != NULL);
+ return (app_usbd_hid_kbd_t const *)p_inst;
+}
+
+
+/**
+ * @brief Returns keyboard report buffer handle.
+ *
+ * @param[in] p_kbd HID keyboard instance.
+ *
+ * @return HID report buffer.
+ */
+static inline
+app_usbd_hid_report_buffer_t const * hid_kbd_rep_buffer_get(app_usbd_hid_kbd_t const * p_kbd)
+{
+ ASSERT(p_kbd != NULL);
+ app_usbd_hid_inst_t const * p_hinst = &p_kbd->specific.inst.hid_inst;
+ app_usbd_hid_kbd_ctx_t * p_kbd_ctx = hid_kbd_ctx_get(p_kbd);
+ app_usbd_hid_report_buffer_t * p_rep_buff = app_usbd_hid_rep_buff_in_get(p_hinst);
+
+ p_rep_buff->p_buff = p_kbd_ctx->report_buff;
+ p_rep_buff->size = sizeof(p_kbd_ctx->report_buff);
+
+ /*Keyboard has only one report input/output report buffer */
+ return p_rep_buff;
+}
+
+
+/**
+ * @brief Auxiliary function to prepare report transfer buffer to next transfer.
+ *
+ * @param[in] p_kbd HID keyboard instance.
+ *
+ * @retval true Next transfer is required.
+ * @retval false Next transfer is not required.
+ */
+static inline bool hid_kbd_transfer_next(app_usbd_hid_kbd_t const * p_kbd)
+{
+ /*Send report only when state has changed*/
+ app_usbd_hid_report_buffer_t const * p_rep_buffer = hid_kbd_rep_buffer_get(p_kbd);
+ app_usbd_hid_kbd_ctx_t * p_kbd_ctx = hid_kbd_ctx_get(p_kbd);
+
+ if (memcmp(p_rep_buffer->p_buff, &p_kbd_ctx->rep, p_rep_buffer->size))
+ {
+ memcpy(p_rep_buffer->p_buff, &p_kbd_ctx->rep, p_rep_buffer->size);
+ return true;
+ }
+
+ return false;
+}
+
+
+/**
+ * @brief Triggers IN endpoint transfer.
+ *
+ * @param[in] p_kbd HID keyboard instance.
+ *
+ * @return Standard error code.
+ */
+static inline ret_code_t hid_kbd_transfer_set(app_usbd_hid_kbd_t const * p_kbd)
+{
+ app_usbd_class_inst_t const * p_inst = (app_usbd_class_inst_t const *)p_kbd;
+ app_usbd_hid_kbd_ctx_t * p_kbd_ctx = hid_kbd_ctx_get(p_kbd);
+
+ nrf_drv_usbd_ep_t ep_addr = app_usbd_hid_epin_addr_get(p_inst);
+
+ app_usbd_hid_state_flag_clr(&p_kbd_ctx->hid_ctx, APP_USBD_HID_STATE_FLAG_TRANS_IN_PROGRESS);
+
+ if (!hid_kbd_transfer_next(p_kbd))
+ {
+ /* Transfer buffer hasn't changed since last transfer. No need to setup
+ * next transfer.
+ * */
+ return NRF_SUCCESS;
+ }
+
+ app_usbd_hid_report_buffer_t const * p_rep_buffer = hid_kbd_rep_buffer_get(p_kbd);
+ NRF_DRV_USBD_TRANSFER_IN(transfer, p_rep_buffer->p_buff, p_rep_buffer->size);
+
+ ret_code_t ret;
+ CRITICAL_REGION_ENTER();
+ ret = app_usbd_ep_transfer(ep_addr, &transfer);
+ if (ret == NRF_SUCCESS)
+ {
+ app_usbd_hid_state_flag_set(&p_kbd_ctx->hid_ctx, APP_USBD_HID_STATE_FLAG_TRANS_IN_PROGRESS);
+ }
+ CRITICAL_REGION_EXIT();
+
+ return ret;
+}
+
+
+ret_code_t app_usbd_hid_kbd_modifier_state_set(app_usbd_hid_kbd_t const * p_kbd,
+ app_usbd_hid_kbd_modifier_t modifier,
+ bool state)
+{
+ app_usbd_hid_kbd_ctx_t * p_kbd_ctx = hid_kbd_ctx_get(p_kbd);
+ bool actual_state = (p_kbd_ctx->rep.modifier & modifier) != 0;
+
+ if (actual_state == state)
+ {
+ /*Modifier has already the same state*/
+ return NRF_SUCCESS;
+ }
+
+ app_usbd_hid_access_lock(&p_kbd_ctx->hid_ctx);
+
+ if (state)
+ {
+ p_kbd_ctx->rep.modifier |= modifier;
+ }
+ else
+ {
+ p_kbd_ctx->rep.modifier &= ~modifier;
+ }
+ app_usbd_hid_access_unlock(&p_kbd_ctx->hid_ctx);
+
+ if (app_usbd_hid_trans_required(&p_kbd_ctx->hid_ctx))
+ {
+ /*New transfer need to be triggered*/
+ return hid_kbd_transfer_set(p_kbd);
+ }
+
+ return NRF_SUCCESS;
+}
+
+
+ret_code_t app_usbd_hid_kbd_key_control(app_usbd_hid_kbd_t const * p_kbd,
+ app_usbd_hid_kbd_codes_t key,
+ bool press)
+{
+ app_usbd_hid_kbd_ctx_t * p_kbd_ctx = hid_kbd_ctx_get(p_kbd);
+ uint8_t * destination = NULL;
+
+ if (press)
+ {
+ for (size_t i = 0; i < ARRAY_SIZE(p_kbd_ctx->rep.key_table); ++i)
+ {
+ if (p_kbd_ctx->rep.key_table[i] == key)
+ {
+ /*Already pressed*/
+ return NRF_SUCCESS;
+ }
+
+ if ((destination == NULL) && (p_kbd_ctx->rep.key_table[i] == 0))
+ {
+ destination = &p_kbd_ctx->rep.key_table[i];
+ }
+ }
+
+ if (destination == NULL)
+ {
+ return NRF_ERROR_BUSY;
+ }
+ }
+ else
+ {
+ /*Find if key is pressed*/
+ for (size_t i = 0; i < ARRAY_SIZE(p_kbd_ctx->rep.key_table); ++i)
+ {
+ if (p_kbd_ctx->rep.key_table[i] == key)
+ {
+ destination = &p_kbd_ctx->rep.key_table[i];
+ break;
+ }
+ }
+
+ if (destination == NULL)
+ {
+ /*Key hasn't been pressed*/
+ return NRF_SUCCESS;
+ }
+ }
+
+ /*Save destination*/
+ app_usbd_hid_access_lock(&p_kbd_ctx->hid_ctx);
+ *destination = press ? key : 0;
+ app_usbd_hid_access_unlock(&p_kbd_ctx->hid_ctx);
+
+ if (app_usbd_hid_trans_required(&p_kbd_ctx->hid_ctx))
+ {
+ /*New transfer need to be triggered*/
+ return hid_kbd_transfer_set(p_kbd);
+ }
+
+ return NRF_SUCCESS;
+}
+
+
+bool app_usbd_hid_kbd_led_state_get(app_usbd_hid_kbd_t const * p_kbd,
+ app_usbd_hid_kbd_led_t led)
+{
+ app_usbd_hid_kbd_ctx_t * p_kbd_ctx = hid_kbd_ctx_get(p_kbd);
+
+ return (p_kbd_ctx->leds_state & led) != 0;
+}
+
+const void * app_usbd_hid_kbd_in_report_get(app_usbd_hid_kbd_t const * p_kbd,
+ size_t * p_size)
+{
+ app_usbd_hid_inst_t const * p_kinst = &p_kbd->specific.inst.hid_inst;
+ *p_size = p_kinst->p_rep_buffer_in->size;
+ return p_kinst->p_rep_buffer_in->p_buff;
+}
+
+const void * app_usbd_hid_kbd_out_report_get(app_usbd_hid_kbd_t const * p_kbd,
+ size_t * p_size)
+{
+ app_usbd_hid_inst_t const * p_kinst = &p_kbd->specific.inst.hid_inst;
+ *p_size = p_kinst->p_rep_buffer_out->size;
+ return p_kinst->p_rep_buffer_out->p_buff;
+}
+
+/**
+ * @brief @ref app_usbd_hid_interface_t::on_get_report
+ */
+static ret_code_t hid_kbd_on_get_report(app_usbd_class_inst_t const * p_inst,
+ app_usbd_setup_evt_t const * p_setup_ev)
+{
+ app_usbd_hid_kbd_t const * p_kinst = hid_kbd_get(p_inst);
+ uint8_t const * p_rep_buffer = NULL;
+ size_t buffer_size = 0;
+
+ if (p_setup_ev->setup.wValue.hb == APP_USBD_HID_REPORT_TYPE_INPUT)
+ {
+ p_rep_buffer = app_usbd_hid_kbd_in_report_get(p_kinst, &buffer_size);
+ }
+ else if (p_setup_ev->setup.wValue.hb == APP_USBD_HID_REPORT_TYPE_OUTPUT)
+ {
+ p_rep_buffer = app_usbd_hid_kbd_out_report_get(p_kinst, &buffer_size);
+ }
+ else
+ {
+ return NRF_ERROR_NOT_SUPPORTED;
+ }
+
+ /* Return LEDs state (only the second byte) */
+ return app_usbd_core_setup_rsp(&(p_setup_ev->setup), p_rep_buffer + 1, buffer_size - 1);
+}
+
+
+static ret_code_t hid_kbd_on_set_report_data_cb(nrf_drv_usbd_ep_status_t status, void * p_context)
+{
+ if (status != NRF_USBD_EP_OK)
+ {
+ return NRF_ERROR_INTERNAL;
+ }
+
+ app_usbd_hid_kbd_t const * p_kbd = p_context;
+ app_usbd_hid_report_buffer_t const * p_rep_buff;
+ p_rep_buff = app_usbd_hid_rep_buff_out_get(&p_kbd->specific.inst.hid_inst);
+
+ /*Update LEDs state*/
+ app_usbd_hid_kbd_ctx_t * p_kbd_ctx = hid_kbd_ctx_get(p_kbd);
+ p_kbd_ctx->leds_state = p_rep_buff->p_buff[1];
+
+ app_usbd_hid_user_ev_handler_t handler = p_kbd->specific.inst.hid_inst.user_event_handler;
+ handler((app_usbd_class_inst_t const *)(p_kbd), APP_USBD_HID_USER_EVT_OUT_REPORT_READY);
+ return NRF_SUCCESS;
+}
+
+
+/**
+ * @brief @ref app_usbd_hid_interface_t::hid_kbd_on_set_report
+ */
+static ret_code_t hid_kbd_on_set_report(app_usbd_class_inst_t const * p_inst,
+ app_usbd_setup_evt_t const * p_setup_ev)
+{
+ app_usbd_hid_kbd_t const * p_kbd = hid_kbd_get(p_inst);
+
+ /*Request setup data*/
+ app_usbd_hid_report_buffer_t const * p_rep_buff;
+
+ p_rep_buff = app_usbd_hid_rep_buff_out_get(&p_kbd->specific.inst.hid_inst);
+
+ p_rep_buff->p_buff[0] = 0;
+ NRF_DRV_USBD_TRANSFER_OUT(transfer, p_rep_buff->p_buff + 1, p_rep_buff->size - 1);
+
+ ret_code_t ret;
+ CRITICAL_REGION_ENTER();
+ ret = app_usbd_ep_transfer(NRF_DRV_USBD_EPOUT0, &transfer);
+ if (ret == NRF_SUCCESS)
+ {
+ app_usbd_core_setup_data_handler_desc_t desc = {
+ .handler = hid_kbd_on_set_report_data_cb,
+ .p_context = (app_usbd_hid_kbd_t *)p_kbd
+ };
+
+ ret = app_usbd_core_setup_data_handler_set(NRF_DRV_USBD_EPOUT0, &desc);
+ }
+ CRITICAL_REGION_EXIT();
+
+ return ret;
+}
+
+
+/**
+ * @brief @ref app_usbd_hid_interface_t::hid_kbd_ep_transfer_in
+ */
+static ret_code_t hid_kbd_ep_transfer_in(app_usbd_class_inst_t const * p_inst)
+{
+ return hid_kbd_transfer_set((app_usbd_hid_kbd_t const *)p_inst);
+}
+
+
+/**
+ * @brief @ref app_usbd_class_interface_t::event_handler
+ */
+static ret_code_t hid_kbd_event_handler(app_usbd_class_inst_t const * p_inst,
+ app_usbd_complex_evt_t const * p_event)
+{
+ ASSERT(p_inst != NULL);
+ ASSERT(p_event != NULL);
+
+ app_usbd_hid_kbd_t const * p_kbd = hid_kbd_get(p_inst);
+ app_usbd_hid_inst_t const * p_hinst = &p_kbd->specific.inst.hid_inst;
+
+ app_usbd_hid_kbd_ctx_t * p_kbd_ctx = hid_kbd_ctx_get(p_kbd);
+ app_usbd_hid_ctx_t * p_hid_ctx = &p_kbd_ctx->hid_ctx;
+
+ /*Try handle event by generic HID event handler*/
+ return app_usbd_hid_event_handler(p_inst, p_hinst, p_hid_ctx, p_event);
+}
+
+
+static uint8_t hid_kbd_get_class_descriptors_count(app_usbd_class_inst_t const * p_inst)
+{
+ app_usbd_hid_kbd_t const * p_kbd = hid_kbd_get(p_inst);
+ app_usbd_hid_inst_t const * p_hinst = &p_kbd->specific.inst.hid_inst;
+
+ return p_hinst->subclass_desc_count;
+}
+
+
+static app_usbd_descriptor_t hid_kbd_get_class_descriptors_type(
+ app_usbd_class_inst_t const * p_inst,
+ uint8_t desc_num)
+{
+ app_usbd_hid_kbd_t const * p_kbd = hid_kbd_get(p_inst);
+ app_usbd_hid_inst_t const * p_hinst = &p_kbd->specific.inst.hid_inst;
+
+ return p_hinst->p_subclass_desc[desc_num]->type;
+}
+
+
+static size_t hid_kbd_get_class_descriptors_length(app_usbd_class_inst_t const * p_inst,
+ uint8_t desc_num)
+{
+ app_usbd_hid_kbd_t const * p_kbd = hid_kbd_get(p_inst);
+ app_usbd_hid_inst_t const * p_hinst = &p_kbd->specific.inst.hid_inst;
+
+ return p_hinst->p_subclass_desc[desc_num]->size;
+}
+
+
+static uint8_t hid_kbd_get_class_descriptors_data(app_usbd_class_inst_t const * p_inst,
+ uint8_t desc_num,
+ uint32_t cur_byte)
+{
+ app_usbd_hid_kbd_t const * p_kbd = hid_kbd_get(p_inst);
+ app_usbd_hid_inst_t const * p_hinst = &p_kbd->specific.inst.hid_inst;
+
+ return p_hinst->p_subclass_desc[desc_num]->p_data[cur_byte];
+}
+
+
+static bool hid_kbd_feed_descriptors(app_usbd_class_descriptor_ctx_t * p_ctx,
+ app_usbd_class_inst_t const * p_inst,
+ uint8_t * p_buff,
+ size_t max_size)
+{
+ static uint8_t ifaces = 0;
+ ifaces = app_usbd_class_iface_count_get(p_inst);
+ app_usbd_hid_kbd_t const * p_kbd = hid_kbd_get(p_inst);
+
+ APP_USBD_CLASS_DESCRIPTOR_BEGIN(p_ctx, p_buff, max_size);
+
+ static uint8_t i = 0;
+
+ for (i = 0; i < ifaces; i++)
+ {
+ /* INTERFACE DESCRIPTOR */
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(0x09); // bLength
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(APP_USBD_DESCRIPTOR_INTERFACE); // bDescriptorType = Interface
+
+ static app_usbd_class_iface_conf_t const * p_cur_iface = NULL;
+ p_cur_iface = app_usbd_class_iface_get(p_inst, i);
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(app_usbd_class_iface_number_get(p_cur_iface)); // bInterfaceNumber
+
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(0x00); // bAlternateSetting
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(app_usbd_class_iface_ep_count_get(p_cur_iface)); // bNumEndpoints
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(APP_USBD_HID_CLASS); // bInterfaceClass = HID
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(p_kbd->specific.inst.hid_inst.subclass_boot); // bInterfaceSubclass (Boot Interface)
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(p_kbd->specific.inst.hid_inst.protocol); // bInterfaceProtocol
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(0x00); // iInterface
+
+ /* HID DESCRIPTOR */
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(0x09); // bLength
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(APP_USBD_HID_DESCRIPTOR_HID); // bDescriptorType = HID
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(LSB_16(APP_USBD_HID_BCD_VER)); // bcdHID LSB
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(MSB_16(APP_USBD_HID_BCD_VER)); // bcdHID MSB
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(APP_USBD_HID_COUNTRY_NOT_SUPPORTED); // bCountryCode
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(hid_kbd_get_class_descriptors_count(p_inst)); // bNumDescriptors
+
+ static uint8_t class_desc_cnt = 0;
+ class_desc_cnt = hid_kbd_get_class_descriptors_count(p_inst);
+ static uint8_t j = 0;
+ static uint16_t class_desc_len = 0;
+
+ for (j = 0; j < class_desc_cnt; j++)
+ {
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(hid_kbd_get_class_descriptors_type(p_inst, j)); // bDescriptorType
+
+ class_desc_len = hid_kbd_get_class_descriptors_length(p_inst, j);
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(LSB_16(class_desc_len)); // wDescriptorLength LSB
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(MSB_16(class_desc_len)); // wDescriptorLength MSB
+ }
+
+ static uint8_t endpoints = 0;
+ endpoints = app_usbd_class_iface_ep_count_get(p_cur_iface);
+
+ for (j = 0; j < endpoints; j++)
+ {
+ /* ENDPOINT DESCRIPTOR */
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(0x07); // bLengths
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(APP_USBD_DESCRIPTOR_ENDPOINT); // bDescriptorType = Endpoint
+
+ static app_usbd_class_ep_conf_t const * p_cur_ep = NULL;
+ p_cur_ep = app_usbd_class_iface_ep_get(p_cur_iface, i);
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(app_usbd_class_ep_address_get(p_cur_ep)); // bEndpointAddress
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(APP_USBD_DESCRIPTOR_EP_ATTR_TYPE_INTERRUPT); // bmAttributes
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(LSB_16(NRF_DRV_USBD_EPSIZE)); // wMaxPacketSize LSB
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(MSB_16(NRF_DRV_USBD_EPSIZE)); // wMaxPacketSize MSB
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(0x01); // bInterval
+ }
+ }
+
+ APP_USBD_CLASS_DESCRIPTOR_END();
+}
+
+static bool hid_kbd_feed_subclass_descriptor(app_usbd_class_descriptor_ctx_t * p_ctx,
+ app_usbd_class_inst_t const * p_inst,
+ uint8_t * p_buff,
+ size_t max_size,
+ uint8_t index)
+{
+ APP_USBD_CLASS_DESCRIPTOR_BEGIN(p_ctx, p_buff, max_size);
+
+ /* PHYSICAL AND REPORT DESCRIPTORS */
+ static uint32_t cur_byte = 0;
+ static size_t sub_desc_size = 0;
+ sub_desc_size = hid_kbd_get_class_descriptors_length(p_inst, index);
+
+ for (cur_byte = 0; cur_byte <= sub_desc_size; cur_byte++)
+ {
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(hid_kbd_get_class_descriptors_data(p_inst, index, cur_byte));
+ }
+
+ APP_USBD_CLASS_DESCRIPTOR_END();
+}
+
+/** @} */
+
+const app_usbd_hid_methods_t app_usbd_hid_kbd_methods = {
+ .on_get_report = hid_kbd_on_get_report,
+ .on_set_report = hid_kbd_on_set_report,
+ .ep_transfer_in = hid_kbd_ep_transfer_in,
+ .ep_transfer_out = NULL,
+ .feed_subclass_descriptor = hid_kbd_feed_subclass_descriptor,
+};
+
+const app_usbd_class_methods_t app_usbd_hid_kbd_class_methods = {
+ .event_handler = hid_kbd_event_handler,
+ .feed_descriptors = hid_kbd_feed_descriptors,
+};
+
+#endif //NRF_MODULE_ENABLED(APP_USBD_HID_KBD)
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/usbd/class/hid/kbd/app_usbd_hid_kbd.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/usbd/class/hid/kbd/app_usbd_hid_kbd.h
new file mode 100644
index 0000000..2343829
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/usbd/class/hid/kbd/app_usbd_hid_kbd.h
@@ -0,0 +1,309 @@
+/**
+ * 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#ifndef APP_USBD_HID_KBD_H__
+#define APP_USBD_HID_KBD_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <stdint.h>
+#include <stdbool.h>
+
+#include "nrf_drv_usbd.h"
+#include "app_usbd_class_base.h"
+#include "app_usbd_hid_types.h"
+#include "app_usbd_hid.h"
+#include "app_usbd.h"
+#include "app_usbd_core.h"
+#include "app_usbd_descriptor.h"
+#include "app_usbd_hid_kbd_desc.h"
+#include "app_usbd_hid_kbd_internal.h"
+
+
+/**
+ * @defgroup app_usbd_hid_kbd USB HID keyboard
+ * @ingroup app_usbd_hid
+ *
+ * @brief @tagAPI52840 Module with types, definitions, and API used by the HID keyboard class.
+ * @{
+ */
+
+/**
+ * @brief HID keyboard codes.
+ */
+typedef enum {
+ APP_USBD_HID_KBD_A = 4, /**<KBD_A code*/
+ APP_USBD_HID_KBD_B = 5, /**<KBD_B code*/
+ APP_USBD_HID_KBD_C = 6, /**<KBD_C code*/
+ APP_USBD_HID_KBD_D = 7, /**<KBD_D code*/
+ APP_USBD_HID_KBD_E = 8, /**<KBD_E code*/
+ APP_USBD_HID_KBD_F = 9, /**<KBD_F code*/
+ APP_USBD_HID_KBD_G = 10, /**<KBD_G code*/
+ APP_USBD_HID_KBD_H = 11, /**<KBD_H code*/
+ APP_USBD_HID_KBD_I = 12, /**<KBD_I code*/
+ APP_USBD_HID_KBD_J = 13, /**<KBD_J code*/
+ APP_USBD_HID_KBD_K = 14, /**<KBD_K code*/
+ APP_USBD_HID_KBD_L = 15, /**<KBD_L code*/
+ APP_USBD_HID_KBD_M = 16, /**<KBD_M code*/
+ APP_USBD_HID_KBD_N = 17, /**<KBD_N code*/
+ APP_USBD_HID_KBD_O = 18, /**<KBD_O code*/
+ APP_USBD_HID_KBD_P = 19, /**<KBD_P code*/
+ APP_USBD_HID_KBD_Q = 20, /**<KBD_Q code*/
+ APP_USBD_HID_KBD_R = 21, /**<KBD_R code*/
+ APP_USBD_HID_KBD_S = 22, /**<KBD_S code*/
+ APP_USBD_HID_KBD_T = 23, /**<KBD_T code*/
+ APP_USBD_HID_KBD_U = 24, /**<KBD_U code*/
+ APP_USBD_HID_KBD_V = 25, /**<KBD_V code*/
+ APP_USBD_HID_KBD_W = 26, /**<KBD_W code*/
+ APP_USBD_HID_KBD_X = 27, /**<KBD_X code*/
+ APP_USBD_HID_KBD_Y = 28, /**<KBD_Y code*/
+ APP_USBD_HID_KBD_Z = 29, /**<KBD_Z code*/
+ APP_USBD_HID_KBD_1 = 30, /**<KBD_1 code*/
+ APP_USBD_HID_KBD_2 = 31, /**<KBD_2 code*/
+ APP_USBD_HID_KBD_3 = 32, /**<KBD_3 code*/
+ APP_USBD_HID_KBD_4 = 33, /**<KBD_4 code*/
+ APP_USBD_HID_KBD_5 = 34, /**<KBD_5 code*/
+ APP_USBD_HID_KBD_6 = 35, /**<KBD_6 code*/
+ APP_USBD_HID_KBD_7 = 36, /**<KBD_7 code*/
+ APP_USBD_HID_KBD_8 = 37, /**<KBD_8 code*/
+ APP_USBD_HID_KBD_9 = 38, /**<KBD_9 code*/
+ APP_USBD_HID_KBD_0 = 39, /**<KBD_0 code*/
+ APP_USBD_HID_KBD_ENTER = 40, /**<KBD_ENTER code*/
+ APP_USBD_HID_KBD_ESCAPE = 41, /**<KBD_ESCAPE code*/
+ APP_USBD_HID_KBD_BACKSPACE = 42, /**<KBD_BACKSPACE code*/
+ APP_USBD_HID_KBD_TAB = 43, /**<KBD_TAB code*/
+ APP_USBD_HID_KBD_SPACEBAR = 44, /**<KBD_SPACEBAR code*/
+ APP_USBD_HID_KBD_UNDERSCORE = 45, /**<KBD_UNDERSCORE code*/
+ APP_USBD_HID_KBD_PLUS = 46, /**<KBD_PLUS code*/
+ APP_USBD_HID_KBD_OPEN_BRACKET = 47, /**<KBD_OPEN_BRACKET code*/
+ APP_USBD_HID_KBD_CLOSE_BRACKET = 48, /**<KBD_CLOSE_BRACKET code*/
+ APP_USBD_HID_KBD_BACKSLASH = 49, /**<KBD_BACKSLASH code*/
+ APP_USBD_HID_KBD_ASH = 50, /**<KBD_ASH code*/
+ APP_USBD_HID_KBD_COLON = 51, /**<KBD_COLON code*/
+ APP_USBD_HID_KBD_QUOTE = 52, /**<KBD_QUOTE code*/
+ APP_USBD_HID_KBD_TILDE = 53, /**<KBD_TILDE code*/
+ APP_USBD_HID_KBD_COMMA = 54, /**<KBD_COMMA code*/
+ APP_USBD_HID_KBD_DOT = 55, /**<KBD_DOT code*/
+ APP_USBD_HID_KBD_SLASH = 56, /**<KBD_SLASH code*/
+ APP_USBD_HID_KBD_CAPS_LOCK = 57, /**<KBD_CAPS_LOCK code*/
+ APP_USBD_HID_KBD_F1 = 58, /**<KBD_F1 code*/
+ APP_USBD_HID_KBD_F2 = 59, /**<KBD_F2 code*/
+ APP_USBD_HID_KBD_F3 = 60, /**<KBD_F3 code*/
+ APP_USBD_HID_KBD_F4 = 61, /**<KBD_F4 code*/
+ APP_USBD_HID_KBD_F5 = 62, /**<KBD_F5 code*/
+ APP_USBD_HID_KBD_F6 = 63, /**<KBD_F6 code*/
+ APP_USBD_HID_KBD_F7 = 64, /**<KBD_F7 code*/
+ APP_USBD_HID_KBD_F8 = 65, /**<KBD_F8 code*/
+ APP_USBD_HID_KBD_F9 = 66, /**<KBD_F9 code*/
+ APP_USBD_HID_KBD_F10 = 67, /**<KBD_F10 code*/
+ APP_USBD_HID_KBD_F11 = 68, /**<KBD_F11 code*/
+ APP_USBD_HID_KBD_F12 = 69, /**<KBD_F12 code*/
+ APP_USBD_HID_KBD_PRINTSCREEN = 70, /**<KBD_PRINTSCREEN code*/
+ APP_USBD_HID_KBD_SCROLL_LOCK = 71, /**<KBD_SCROLL_LOCK code*/
+ APP_USBD_HID_KBD_PAUSE = 72, /**<KBD_PAUSE code*/
+ APP_USBD_HID_KBD_INSERT = 73, /**<KBD_INSERT code*/
+ APP_USBD_HID_KBD_HOME = 74, /**<KBD_HOME code*/
+ APP_USBD_HID_KBD_PAGEUP = 75, /**<KBD_PAGEUP code*/
+ APP_USBD_HID_KBD_DELETE = 76, /**<KBD_DELETE code*/
+ APP_USBD_HID_KBD_END = 77, /**<KBD_END code*/
+ APP_USBD_HID_KBD_PAGEDOWN = 78, /**<KBD_PAGEDOWN code*/
+ APP_USBD_HID_KBD_RIGHT = 79, /**<KBD_RIGHT code*/
+ APP_USBD_HID_KBD_LEFT = 80, /**<KBD_LEFT code*/
+ APP_USBD_HID_KBD_DOWN = 81, /**<KBD_DOWN code*/
+ APP_USBD_HID_KBD_UP = 82, /**<KBD_UP code*/
+ APP_USBD_HID_KBD_KEYPAD_NUM_LOCK = 83, /**<KBD_KEYPAD_NUM_LOCK code*/
+ APP_USBD_HID_KBD_KEYPAD_DIVIDE = 84, /**<KBD_KEYPAD_DIVIDE code*/
+ APP_USBD_HID_KBD_KEYPAD_AT = 85, /**<KBD_KEYPAD_AT code*/
+ APP_USBD_HID_KBD_KEYPAD_MULTIPLY = 85, /**<KBD_KEYPAD_MULTIPLY code*/
+ APP_USBD_HID_KBD_KEYPAD_MINUS = 86, /**<KBD_KEYPAD_MINUS code*/
+ APP_USBD_HID_KBD_KEYPAD_PLUS = 87, /**<KBD_KEYPAD_PLUS code*/
+ APP_USBD_HID_KBD_KEYPAD_ENTER = 88, /**<KBD_KEYPAD_ENTER code*/
+ APP_USBD_HID_KBD_KEYPAD_1 = 89, /**<KBD_KEYPAD_1 code*/
+ APP_USBD_HID_KBD_KEYPAD_2 = 90, /**<KBD_KEYPAD_2 code*/
+ APP_USBD_HID_KBD_KEYPAD_3 = 91, /**<KBD_KEYPAD_3 code*/
+ APP_USBD_HID_KBD_KEYPAD_4 = 92, /**<KBD_KEYPAD_4 code*/
+ APP_USBD_HID_KBD_KEYPAD_5 = 93, /**<KBD_KEYPAD_5 code*/
+ APP_USBD_HID_KBD_KEYPAD_6 = 94, /**<KBD_KEYPAD_6 code*/
+ APP_USBD_HID_KBD_KEYPAD_7 = 95, /**<KBD_KEYPAD_7 code*/
+ APP_USBD_HID_KBD_KEYPAD_8 = 96, /**<KBD_KEYPAD_8 code*/
+ APP_USBD_HID_KBD_KEYPAD_9 = 97, /**<KBD_KEYPAD_9 code*/
+ APP_USBD_HID_KBD_KEYPAD_0 = 98, /**<KBD_KEYPAD_0 code*/
+} app_usbd_hid_kbd_codes_t;
+
+/**
+ * @brief HID keyboard modifier
+ */
+typedef enum {
+ APP_USBD_HID_KBD_MODIFIER_NONE = 0x00, /**< MODIFIER_NONE bit*/
+ APP_USBD_HID_KBD_MODIFIER_LEFT_CTRL = 0x01, /**< MODIFIER_LEFT_CTRL bit*/
+ APP_USBD_HID_KBD_MODIFIER_LEFT_SHIFT = 0x02, /**< MODIFIER_LEFT_SHIFT bit*/
+ APP_USBD_HID_KBD_MODIFIER_LEFT_ALT = 0x04, /**< MODIFIER_LEFT_ALT bit*/
+ APP_USBD_HID_KBD_MODIFIER_LEFT_UI = 0x08, /**< MODIFIER_LEFT_UI bit*/
+ APP_USBD_HID_KBD_MODIFIER_RIGHT_CTRL = 0x10, /**< MODIFIER_RIGHT_CTRL bit*/
+ APP_USBD_HID_KBD_MODIFIER_RIGHT_SHIFT = 0x20, /**< MODIFIER_RIGHT_SHIFT bit*/
+ APP_USBD_HID_KBD_MODIFIER_RIGHT_ALT = 0x40, /**< MODIFIER_RIGHT_ALT bit*/
+ APP_USBD_HID_KBD_MODIFIER_RIGHT_UI = 0x80, /**< MODIFIER_RIGHT_UI bit*/
+} app_usbd_hid_kbd_modifier_t;
+
+/**
+ * @brief HID keyboard LEDs.
+ */
+typedef enum {
+ APP_USBD_HID_KBD_LED_NUM_LOCK = 0x01, /**< LED_NUM_LOCK id*/
+ APP_USBD_HID_KBD_LED_CAPS_LOCK = 0x02, /**< LED_CAPS_LOCK id*/
+ APP_USBD_HID_KBD_LED_SCROLL_LOCK = 0x04, /**< LED_SCROLL_LOCK id*/
+ APP_USBD_HID_KBD_LED_COMPOSE = 0x08, /**< LED_COMPOSE id*/
+ APP_USBD_HID_KBD_LED_KANA = 0x10, /**< LED_KANA id*/
+} app_usbd_hid_kbd_led_t;
+
+
+
+#ifdef DOXYGEN
+/**
+ * @brief HID keyboard class instance type
+ *
+ * @ref APP_USBD_CLASS_TYPEDEF
+ */
+typedef struct { } app_usbd_hid_kbd_t;
+#else
+/*lint -save -e10 -e26 -e123 -e505 */
+APP_USBD_CLASS_TYPEDEF(app_usbd_hid_kbd, \
+ APP_USBD_HID_KBD_CONFIG(0, NRF_DRV_USBD_EPIN1), \
+ APP_USBD_HID_KBD_INSTANCE_SPECIFIC_DEC, \
+ APP_USBD_HID_KBD_DATA_SPECIFIC_DEC \
+);
+/*lint -restore*/
+#endif
+
+/**
+ * @brief Global definition of app_usbd_hid_kbd_t class.
+ *
+ * @param instance_name Name of global instance.
+ * @param interface_number Unique interface index.
+ * @param endpoint Input endpoint (@ref nrf_drv_usbd_ep_t).
+ * @param user_ev_handler User event handler (optional parameter: NULL might be passed here).
+ * @param subclass_boot Subclass boot. (@ref app_usbd_hid_subclass_t)
+ *
+ * Example class definition:
+ * @code
+ APP_USBD_HID_KBD_GLOBAL_DEF(my_awesome_kbd, 0, NRF_DRV_USBD_EPIN1, NULL, APP_USBD_HID_SUBCLASS_BOOT);
+ * @endcode
+ */
+#define APP_USBD_HID_KBD_GLOBAL_DEF(instance_name, interface_number, endpoint, user_ev_handler, subclass_boot) \
+ APP_USBD_HID_GENERIC_SUBCLASS_REPORT_DESC(keyboard_desc, APP_USBD_HID_KBD_REPORT_DSC()); \
+ static const app_usbd_hid_subclass_desc_t * keyboard_descs[] = {&keyboard_desc}; \
+ APP_USBD_HID_KBD_GLOBAL_DEF_INTERNAL(instance_name, \
+ interface_number, \
+ endpoint, \
+ user_ev_handler, \
+ subclass_boot)
+
+/**
+ * @brief Helper function to get class instance from HID keyboard internals.
+ *
+ * @param[in] p_kbd Keyboard instance (declared by @ref APP_USBD_HID_KBD_GLOBAL_DEF).
+ *
+ * @return Base class instance.
+ */
+static inline app_usbd_class_inst_t const *
+app_usbd_hid_kbd_class_inst_get(app_usbd_hid_kbd_t const * p_kbd)
+{
+ return &p_kbd->base;
+}
+
+/**
+ * @brief Helper function to get HID keyboard from base class instance.
+ *
+ * @param[in] p_inst Base class instance.
+ *
+ * @return HID keyboard class handle.
+ */
+static inline app_usbd_hid_kbd_t const *
+app_usbd_hid_kbd_class_get(app_usbd_class_inst_t const * p_inst)
+{
+ return (app_usbd_hid_kbd_t const *)p_inst;
+}
+
+/**
+ * @brief Set HID keyboard modifier state.
+ *
+ * @param[in] p_kbd Keyboard instance (declared by @ref APP_USBD_HID_KBD_GLOBAL_DEF).
+ * @param[in] modifier Type of modifier.
+ * @param[in] state State, true active, false inactive.
+ *
+ * @return Standard error code.
+ */
+ret_code_t app_usbd_hid_kbd_modifier_state_set(app_usbd_hid_kbd_t const * p_kbd,
+ app_usbd_hid_kbd_modifier_t modifier,
+ bool state);
+
+
+/**
+ * @brief Press/release HID keyboard key.
+ *
+ * @param[in] p_kbd Keyboard instance (declared by @ref APP_USBD_HID_KBD_GLOBAL_DEF).
+ * @param[in] key Keyboard key code.
+ * @param[in] press True -> key press, false -> release.
+ *
+ * @return Standard error code.
+ */
+ret_code_t app_usbd_hid_kbd_key_control(app_usbd_hid_kbd_t const * p_kbd,
+ app_usbd_hid_kbd_codes_t key,
+ bool press);
+/**
+ * @brief HID Keyboard LEDs state get.
+ *
+ * @param[in] p_kbd Keyboard instance (declared by @ref APP_USBD_HID_KBD_GLOBAL_DEF).
+ * @param[in] led LED code.
+ *
+ * @retval true LED is set.
+ * @retval false LED is not set.
+ */
+bool app_usbd_hid_kbd_led_state_get(app_usbd_hid_kbd_t const * p_kbd,
+ app_usbd_hid_kbd_led_t led);
+
+/** @} */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* APP_USBD_HID_KBD_H__ */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/usbd/class/hid/kbd/app_usbd_hid_kbd_desc.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/usbd/class/hid/kbd/app_usbd_hid_kbd_desc.h
new file mode 100644
index 0000000..1083b42
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/usbd/class/hid/kbd/app_usbd_hid_kbd_desc.h
@@ -0,0 +1,128 @@
+/**
+ * Copyright (c) 2016 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#ifndef APP_USBD_HID_KBD_DESC_H__
+#define APP_USBD_HID_KBD_DESC_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+/**
+ * @defgroup app_usbd_hid_kbd_desc USB HID keyboard descriptors
+ * @ingroup app_usbd_hid_kbd
+ *
+ * @brief @tagAPI52840 Module with types, definitions, and API used by the HID keyboard class.
+ * @{
+ */
+
+/**
+ * @brief Initializer of interface descriptor for HID keyboard class.
+ *
+ * @param interface_number Interface number.
+ */
+#define APP_USBD_HID_KBD_INTERFACE_DSC(interface_number) \
+ APP_USBD_HID_INTERFACE_DSC(interface_number, \
+ 1, \
+ APP_USBD_HID_SUBCLASS_BOOT, \
+ APP_USBD_HID_PROTO_KEYBOARD)
+
+/**
+ * @brief Initializer of HID descriptor for HID keyboard class.
+ *
+ * @param ... Report descriptor item.
+ */
+#define APP_USBD_HID_KBD_HID_DSC(...) \
+ APP_USBD_HID_HID_DSC(__VA_ARGS__)
+/**
+ * @brief Initializer of endpoint descriptor for HID keyboard class.
+ *
+ * @param endpoint Endpoint number.
+ */
+#define APP_USBD_HID_KBD_EP_DSC(endpoint) \
+ APP_USBD_HID_EP_DSC(endpoint, 8, 1)
+
+
+/**
+ * @brief Example of USB HID keyboard report descriptor.
+ *
+ */
+#define APP_USBD_HID_KBD_REPORT_DSC() { \
+ 0x05, 0x01, /* USAGE_PAGE (Generic Desktop) */\
+ 0x09, 0x06, /* USAGE (Keyboard) */\
+ 0xa1, 0x01, /* COLLECTION (Application) */\
+ 0x05, 0x07, /* USAGE_PAGE (Keyboard) */\
+ 0x19, 0xe0, /* USAGE_MINIMUM (Keyboard LeftControl) */\
+ 0x29, 0xe7, /* USAGE_MAXIMUM (Keyboard Right GUI) */\
+ 0x15, 0x00, /* LOGICAL_MINIMUM (0) */\
+ 0x25, 0x01, /* LOGICAL_MAXIMUM (1) */\
+ 0x75, 0x01, /* REPORT_SIZE (1) */\
+ 0x95, 0x08, /* REPORT_COUNT (8) */\
+ 0x81, 0x02, /* INPUT (Data,Var,Abs) */\
+ 0x95, 0x01, /* REPORT_COUNT (1) */\
+ 0x75, 0x08, /* REPORT_SIZE (8) */\
+ 0x81, 0x03, /* INPUT (Cnst,Var,Abs) */\
+ 0x95, 0x05, /* REPORT_COUNT (5) */\
+ 0x75, 0x01, /* REPORT_SIZE (1) */\
+ 0x05, 0x08, /* USAGE_PAGE (LEDs) */\
+ 0x19, 0x01, /* USAGE_MINIMUM (Num Lock) */\
+ 0x29, 0x05, /* USAGE_MAXIMUM (Kana) */\
+ 0x91, 0x02, /* OUTPUT (Data,Var,Abs) */\
+ 0x95, 0x01, /* REPORT_COUNT (1) */\
+ 0x75, 0x03, /* REPORT_SIZE (3) */\
+ 0x91, 0x03, /* OUTPUT (Cnst,Var,Abs) */\
+ 0x95, 0x06, /* REPORT_COUNT (6) */\
+ 0x75, 0x08, /* REPORT_SIZE (8) */\
+ 0x15, 0x00, /* LOGICAL_MINIMUM (0) */\
+ 0x25, 0x65, /* LOGICAL_MAXIMUM (101) */\
+ 0x05, 0x07, /* USAGE_PAGE (Keyboard) */\
+ 0x19, 0x00, /* USAGE_MINIMUM (Reserved (no event indicated))*/\
+ 0x29, 0x65, /* USAGE_MAXIMUM (Keyboard Application) */\
+ 0x81, 0x00, /* INPUT (Data,Ary,Abs) */\
+ 0xc0 /* END_COLLECTION */\
+}
+
+/** @} */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* APP_USBD_HID_KBD_DESC_H__ */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/usbd/class/hid/kbd/app_usbd_hid_kbd_internal.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/usbd/class/hid/kbd/app_usbd_hid_kbd_internal.h
new file mode 100644
index 0000000..06ab405
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/usbd/class/hid/kbd/app_usbd_hid_kbd_internal.h
@@ -0,0 +1,174 @@
+/**
+ * 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#ifndef APP_USBD_HID_KBD_INTERNAL_H__
+#define APP_USBD_HID_KBD_INTERNAL_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+/**
+ * @defgroup app_usbd_hid_kbd_internal USB HID keyboard internals
+ * @ingroup app_usbd_hid_kbd
+ *
+ * @brief @tagAPI52840 Module with types, definitions, and API used by the HID keyboard class.
+ * @{
+ */
+
+/**
+ * @brief Forward declaration of HID keyboard class type.
+ *
+ */
+APP_USBD_CLASS_FORWARD(app_usbd_hid_kbd);
+
+
+/**
+ * @brief HID keyboard part of class instance data.
+ *
+ */
+typedef struct {
+ app_usbd_hid_inst_t hid_inst; //!< HID instance data.
+} app_usbd_hid_kbd_inst_t;
+
+/**
+ * @brief HID keyboard context
+ *
+ */
+typedef struct {
+ app_usbd_hid_ctx_t hid_ctx; //!< HID class context.
+
+ struct app_usbd_hid_kbd_ctx_internal_s {
+ uint8_t modifier; //!< Keyboard modifier state @ref app_usbd_hid_kbd_modifier_t.
+ uint8_t reserved; //!< Reserved value.
+ uint8_t key_table[6]; //!< Keyboard keys table @ref app_usbd_hid_kbd_codes_t.
+ } rep;
+
+ uint8_t report_buff[8]; //!< Raw report buffer.
+ uint8_t leds_state; //!< Output report LEDs state.
+ uint8_t set_report; //!< Set report flag.
+} app_usbd_hid_kbd_ctx_t;
+
+/**
+ * @brief HID keyboard configuration macro.
+ *
+ * Used by @ref APP_USBD_HID_KBD_GLOBAL_DEF.
+ *
+ *
+ */
+#define APP_USBD_HID_KBD_CONFIG(iface, ep) ((iface, ep))
+
+
+/**
+ * @brief Specific class constant data for HID keyboard class.
+ */
+#define APP_USBD_HID_KBD_INSTANCE_SPECIFIC_DEC app_usbd_hid_kbd_inst_t inst;
+
+/**
+ * @brief Specific class data for HID keyboard class.
+ */
+#define APP_USBD_HID_KBD_DATA_SPECIFIC_DEC app_usbd_hid_kbd_ctx_t ctx;
+
+
+/**
+ * @brief Configure internal part of HID keyboard instance.
+ *
+ * @param report_buff_in Input report buffers array.
+ * @param report_buff_out Output report buffer.
+ * @param user_ev_handler User event handler.
+ * @param subclass_boot Subclass boot. (@ref app_usbd_hid_subclass_t)
+ */
+#define APP_USBD_HID_KBD_INST_CONFIG(report_buff_in, \
+ report_buff_out, \
+ user_ev_handler, \
+ subclass_boot) \
+ .inst = { \
+ .hid_inst = APP_USBD_HID_INST_CONFIG(keyboard_descs, \
+ subclass_boot, \
+ APP_USBD_HID_PROTO_KEYBOARD, \
+ report_buff_in, \
+ report_buff_out, \
+ user_ev_handler, \
+ &app_usbd_hid_kbd_methods), \
+}
+
+
+/**
+ * @brief Public HID keyboard interface.
+ */
+extern const app_usbd_hid_methods_t app_usbd_hid_kbd_methods;
+
+/**
+ * @brief Public HID keyboard class interface.
+ */
+extern const app_usbd_class_methods_t app_usbd_hid_kbd_class_methods;
+
+/**
+ * @brief Global definition of @ref app_usbd_hid_kbd_t class.
+ *
+ * @ref APP_USBD_HID_KBD_GLOBAL_DEF
+ */
+#define APP_USBD_HID_KBD_GLOBAL_DEF_INTERNAL(instance_name, \
+ interface_number, \
+ endpoint, \
+ user_ev_handler, \
+ subclass_boot) \
+ static app_usbd_hid_report_buffer_t CONCAT_2(instance_name, _in)[1]; \
+ APP_USBD_HID_GENERIC_GLOBAL_OUT_REP_DEF(CONCAT_2(instance_name, _out), 1 + 1); \
+ APP_USBD_CLASS_INST_GLOBAL_DEF( \
+ instance_name, \
+ app_usbd_hid_kbd, \
+ &app_usbd_hid_kbd_class_methods, \
+ APP_USBD_HID_KBD_CONFIG(interface_number, endpoint), \
+ (APP_USBD_HID_KBD_INST_CONFIG(CONCAT_2(instance_name, _in), \
+ &CONCAT_2(instance_name, _out), \
+ user_ev_handler, \
+ subclass_boot)) \
+ )
+
+
+/** @} */
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* APP_USBD_HID_KBD_INTERNAL_H__ */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/usbd/class/hid/mouse/app_usbd_hid_mouse.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/usbd/class/hid/mouse/app_usbd_hid_mouse.c
new file mode 100644
index 0000000..7427c58
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/usbd/class/hid/mouse/app_usbd_hid_mouse.c
@@ -0,0 +1,620 @@
+/**
+ * Copyright (c) 2016 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#include "sdk_common.h"
+#if NRF_MODULE_ENABLED(APP_USBD_HID_MOUSE)
+
+#include <string.h>
+#include "app_usbd_hid_mouse.h"
+#include "app_util_platform.h"
+
+
+/**
+ * @defgroup app_usbd_hid_mouse_internal USBD HID Mouse internals
+ * @{
+ * @ingroup app_usbd_hid_mouse
+ * @internal
+ */
+
+/**
+ * @brief Auxiliary function to access HID mouse context data.
+ *
+ * @param[in] p_inst class instance data.
+ *
+ * @return HID mouse instance data context.
+ */
+static inline app_usbd_hid_mouse_ctx_t * hid_mouse_ctx_get(app_usbd_hid_mouse_t const * p_mouse)
+{
+ ASSERT(p_mouse != NULL);
+ ASSERT(p_mouse->specific.p_data != NULL);
+ return &p_mouse->specific.p_data->ctx;
+}
+
+
+/**
+ * @brief Auxiliary function to access HID mouse instance data.
+ *
+ * @param[in] p_inst class instance data.
+ *
+ * @return HID mouse instance.
+ */
+static inline app_usbd_hid_mouse_t const * hid_mouse_get(app_usbd_class_inst_t const * p_inst)
+{
+ ASSERT(p_inst != NULL);
+ return (app_usbd_hid_mouse_t const *)p_inst;
+}
+
+
+/**
+ * @brief Returns mouse report buffer handle.
+ *
+ * @param[in] p_kbd HID keyboard instance.
+ *
+ * @return HID report buffer.
+ */
+static inline
+app_usbd_hid_report_buffer_t const * hid_mouse_rep_buffer_get(app_usbd_hid_mouse_t const * p_mouse)
+{
+ ASSERT(p_mouse != NULL);
+ app_usbd_hid_inst_t const * p_hinst = &p_mouse->specific.inst.hid_inst;
+ app_usbd_hid_mouse_ctx_t * p_mouse_ctx = hid_mouse_ctx_get(p_mouse);
+ app_usbd_hid_report_buffer_t * p_rep_buff = app_usbd_hid_rep_buff_in_get(p_hinst);
+
+ p_rep_buff->p_buff = p_mouse_ctx->report_buff;
+ p_rep_buff->size = sizeof(p_mouse_ctx->report_buff);
+
+ /*Mouse has only one report input report buffer */
+ return app_usbd_hid_rep_buff_in_get(p_hinst);
+}
+
+
+/**@brief Auxiliary function to get report value from internal accumulated value.
+ *
+ * @param[in] acc Accumulated XY axis or scroll.
+ *
+ * @return Offset value that could be written directly to report buffer.
+ */
+static inline int8_t hid_mouse_axis_acc_get(int16_t acc)
+{
+ if (acc > INT8_MAX)
+ {
+ return INT8_MAX;
+ }
+
+ if (acc < INT8_MIN)
+ {
+ return INT8_MIN;
+ }
+
+ return acc;
+}
+
+
+/**@brief Auxiliary function to prepare report transfer buffer to next transfer.
+ *
+ * @param[in] p_mouse_ctx Mouse internal context.
+ *
+ * @retval true Next transfer is required.
+ * @retval false Next transfer is not required.
+ */
+static inline bool hid_mouse_transfer_next(app_usbd_hid_mouse_t const * p_mouse)
+{
+
+ app_usbd_hid_mouse_ctx_t * p_mouse_ctx = hid_mouse_ctx_get(p_mouse);
+ app_usbd_hid_report_buffer_t const * p_rep_buffer = hid_mouse_rep_buffer_get(p_mouse);
+
+ uint8_t * p_buff = p_rep_buffer->p_buff;
+
+ /*Save last buttons state*/
+ uint8_t last_button_state = p_buff[0];
+
+ /*Button state*/
+ p_buff[0] = p_mouse_ctx->button_state;
+
+ /*Axis X*/
+ int8_t val_x = hid_mouse_axis_acc_get(p_mouse_ctx->acc_x_axis);
+ p_mouse_ctx->acc_x_axis -= val_x;
+ p_buff[1] = val_x;
+
+ /*Axis Y*/
+ int8_t val_y = hid_mouse_axis_acc_get(p_mouse_ctx->acc_y_axis);
+ p_mouse_ctx->acc_y_axis -= val_y;
+ p_buff[2] = val_y;
+
+ /*Scroll*/
+ int8_t val_scroll = hid_mouse_axis_acc_get(p_mouse_ctx->acc_scroll);
+ p_mouse_ctx->acc_scroll -= val_scroll;
+ p_buff[3] = val_scroll;
+
+ if (val_x || val_y || val_scroll)
+ {
+ /*New transfer is required if any of mouse relative position is not zero*/
+ return true;
+ }
+
+ if (last_button_state != p_buff[0])
+ {
+ /*New transfer is required if button state has changed*/
+ return true;
+ }
+
+ return false;
+}
+
+
+/**
+ * @brief Triggers IN endpoint transfer.
+ *
+ * @param[in] p_mouse HID mouse instance.
+ *
+ * @return Standard error code.
+ */
+static inline ret_code_t hid_mouse_transfer_set(app_usbd_hid_mouse_t const * p_mouse)
+{
+ app_usbd_class_inst_t const * p_inst = (app_usbd_class_inst_t const *)p_mouse;
+ app_usbd_hid_mouse_ctx_t * p_mouse_ctx = hid_mouse_ctx_get(p_mouse);
+
+ nrf_drv_usbd_ep_t ep_addr = app_usbd_hid_epin_addr_get(p_inst);
+
+ app_usbd_hid_state_flag_clr(&p_mouse_ctx->hid_ctx, APP_USBD_HID_STATE_FLAG_TRANS_IN_PROGRESS);
+ if (!hid_mouse_transfer_next(p_mouse))
+ {
+ /* Transfer buffer hasn't changed since last transfer. No need to setup
+ * next transfer.
+ * */
+ return NRF_SUCCESS;
+ }
+
+ app_usbd_hid_report_buffer_t const * p_rep_buffer = hid_mouse_rep_buffer_get(p_mouse);
+
+ NRF_DRV_USBD_TRANSFER_IN(transfer, p_rep_buffer->p_buff, p_rep_buffer->size);
+
+ ret_code_t ret;
+ CRITICAL_REGION_ENTER();
+ ret = app_usbd_ep_transfer(ep_addr, &transfer);
+ if (ret == NRF_SUCCESS)
+ {
+ app_usbd_hid_state_flag_set(&p_mouse_ctx->hid_ctx,
+ APP_USBD_HID_STATE_FLAG_TRANS_IN_PROGRESS);
+ }
+ CRITICAL_REGION_EXIT();
+
+ return ret;
+}
+
+
+/**
+ * @brief Checks if adding would cause 16 bit signed integer overflow.
+ *
+ * @param[in] acc Signed 16 bit accumulator to test.
+ * @param[in] value Value to add to accumulator.
+ *
+ * @retval true Overflow detected.
+ * @retval false No overflow detected.
+ */
+static inline bool hid_mouse_acc_overflow_check(int16_t acc, int8_t val)
+{
+ if (((int32_t)acc + val) > INT16_MAX)
+ {
+ return true;
+ }
+
+ if (((int32_t)acc + val) < INT16_MIN)
+ {
+ return true;
+ }
+
+ return false;
+}
+
+
+ret_code_t app_usbd_hid_mouse_x_move(app_usbd_hid_mouse_t const * p_mouse, int8_t offset)
+{
+ app_usbd_hid_mouse_ctx_t * p_mouse_ctx = hid_mouse_ctx_get(p_mouse);
+
+ if (!app_usbd_hid_state_valid(&p_mouse_ctx->hid_ctx))
+ {
+ return NRF_ERROR_INVALID_STATE;
+ }
+
+ if (offset == 0)
+ {
+ /*No position change*/
+ return NRF_SUCCESS;
+ }
+
+ if (hid_mouse_acc_overflow_check(p_mouse_ctx->acc_y_axis, offset))
+ {
+ /*Overflow detected*/
+ return NRF_ERROR_BUSY;
+ }
+
+ app_usbd_hid_access_lock(&p_mouse_ctx->hid_ctx);
+ p_mouse_ctx->acc_x_axis += offset;
+ app_usbd_hid_access_unlock(&p_mouse_ctx->hid_ctx);
+
+ if (app_usbd_hid_trans_required(&p_mouse_ctx->hid_ctx))
+ {
+ /*New transfer need to be triggered*/
+ return hid_mouse_transfer_set(p_mouse);
+ }
+
+ return NRF_SUCCESS;
+}
+
+
+ret_code_t app_usbd_hid_mouse_y_move(app_usbd_hid_mouse_t const * p_mouse, int8_t offset)
+{
+ app_usbd_hid_mouse_ctx_t * p_mouse_ctx = hid_mouse_ctx_get(p_mouse);
+
+ if (!app_usbd_hid_state_valid(&p_mouse_ctx->hid_ctx))
+ {
+ return NRF_ERROR_INVALID_STATE;
+ }
+
+ if (offset == 0)
+ {
+ /*No position change*/
+ return NRF_SUCCESS;
+ }
+
+ if (hid_mouse_acc_overflow_check(p_mouse_ctx->acc_y_axis, offset))
+ {
+ /*Overflow detected*/
+ return NRF_ERROR_BUSY;
+ }
+
+ app_usbd_hid_access_lock(&p_mouse_ctx->hid_ctx);
+ p_mouse_ctx->acc_y_axis += offset;
+ app_usbd_hid_access_unlock(&p_mouse_ctx->hid_ctx);
+
+ if (app_usbd_hid_trans_required(&p_mouse_ctx->hid_ctx))
+ {
+ /*New transfer need to be triggered*/
+ return hid_mouse_transfer_set(p_mouse);
+ }
+
+ return NRF_SUCCESS;
+}
+
+
+ret_code_t app_usbd_hid_mouse_scroll_move(app_usbd_hid_mouse_t const * p_mouse, int8_t offset)
+{
+ app_usbd_hid_mouse_ctx_t * p_mouse_ctx = hid_mouse_ctx_get(p_mouse);
+
+ if (!app_usbd_hid_state_valid(&p_mouse_ctx->hid_ctx))
+ {
+ return NRF_ERROR_INVALID_STATE;
+ }
+
+ if (offset == 0)
+ {
+ /*No position change*/
+ return NRF_SUCCESS;
+ }
+
+ if (hid_mouse_acc_overflow_check(p_mouse_ctx->acc_scroll, offset))
+ {
+ /*Overflow detected*/
+ return NRF_ERROR_BUSY;
+ }
+
+ app_usbd_hid_access_lock(&p_mouse_ctx->hid_ctx);
+ p_mouse_ctx->acc_scroll += offset;
+ app_usbd_hid_access_unlock(&p_mouse_ctx->hid_ctx);
+
+ if (app_usbd_hid_trans_required(&p_mouse_ctx->hid_ctx))
+ {
+ /*New transfer need to be triggered*/
+ return hid_mouse_transfer_set(p_mouse);
+ }
+
+ return NRF_SUCCESS;
+}
+
+
+ret_code_t app_usbd_hid_mouse_button_state(app_usbd_hid_mouse_t const * p_mouse,
+ uint8_t button_id,
+ bool state)
+{
+ ASSERT(button_id < 8);
+ app_usbd_hid_mouse_ctx_t * p_mouse_ctx = hid_mouse_ctx_get(p_mouse);
+
+ if (button_id >= p_mouse->specific.inst.button_count)
+ {
+ return NRF_ERROR_INVALID_PARAM;
+ }
+
+ if (!app_usbd_hid_state_valid(&p_mouse_ctx->hid_ctx))
+ {
+ return NRF_ERROR_INVALID_STATE;
+ }
+
+ if (IS_SET(p_mouse_ctx->button_state, button_id) == (state ? 1 : 0))
+ {
+ return NRF_SUCCESS;
+ }
+
+ app_usbd_hid_access_lock(&p_mouse_ctx->hid_ctx);
+ if (state)
+ {
+ SET_BIT(p_mouse_ctx->button_state, button_id);
+ }
+ else
+ {
+ CLR_BIT(p_mouse_ctx->button_state, button_id);
+ }
+ app_usbd_hid_access_unlock(&p_mouse_ctx->hid_ctx);
+
+ if (app_usbd_hid_trans_required(&p_mouse_ctx->hid_ctx))
+ {
+ /*New transfer need to be triggered*/
+ return hid_mouse_transfer_set(p_mouse);
+ }
+
+ return NRF_SUCCESS;
+}
+
+
+/**
+ * @brief @ref app_usbd_hid_interface_t::on_get_report
+ */
+static ret_code_t hid_mouse_on_get_report(app_usbd_class_inst_t const * p_inst,
+ app_usbd_setup_evt_t const * p_setup_ev)
+{
+ if (p_setup_ev->setup.wValue.hb != APP_USBD_HID_REPORT_TYPE_INPUT)
+ {
+ return NRF_ERROR_NOT_SUPPORTED;
+ }
+
+ app_usbd_hid_mouse_t const * p_mouse = hid_mouse_get(p_inst);
+ app_usbd_hid_report_buffer_t const * p_rep_buffer = hid_mouse_rep_buffer_get(p_mouse);
+
+ return app_usbd_core_setup_rsp(&(p_setup_ev->setup), p_rep_buffer->p_buff, p_rep_buffer->size);
+}
+
+
+/**
+ * @brief @ref app_usbd_hid_interface_t::on_set_report
+ */
+static ret_code_t hid_mouse_on_set_report(app_usbd_class_inst_t const * p_inst,
+ app_usbd_setup_evt_t const * p_setup_ev)
+{
+ return NRF_ERROR_NOT_SUPPORTED;
+}
+
+
+/**
+ * @brief @ref app_usbd_hid_interface_t::ep_transfer_set
+ */
+static ret_code_t hid_mouse_ep_transfer_in(app_usbd_class_inst_t const * p_inst)
+{
+ return hid_mouse_transfer_set((app_usbd_hid_mouse_t const *)p_inst);
+}
+
+
+/**
+ * @brief @ref app_usbd_class_interface_t::event_handler
+ */
+static ret_code_t hid_mouse_event_handler(app_usbd_class_inst_t const * p_inst,
+ app_usbd_complex_evt_t const * p_event)
+{
+ ASSERT(p_inst != NULL);
+ ASSERT(p_event != NULL);
+
+ app_usbd_hid_mouse_t const * p_mouse = hid_mouse_get(p_inst);
+ app_usbd_hid_inst_t const * p_hinst = &p_mouse->specific.inst.hid_inst;
+
+ app_usbd_hid_mouse_ctx_t * p_mouse_ctx = hid_mouse_ctx_get(p_mouse);
+ app_usbd_hid_ctx_t * p_hid_ctx = &p_mouse_ctx->hid_ctx;
+
+
+ ret_code_t ret = NRF_SUCCESS;
+
+ switch (p_event->app_evt.type)
+ {
+ default:
+ ret = NRF_ERROR_NOT_SUPPORTED;
+ break;
+ }
+
+ if (ret != NRF_ERROR_NOT_SUPPORTED)
+ {
+ /* Event was processed by specific handler */
+ return ret;
+ }
+
+ /*Try handle event by generic HID event handler*/
+ return app_usbd_hid_event_handler(p_inst, p_hinst, p_hid_ctx, p_event);
+}
+
+
+static uint8_t hid_mouse_get_class_descriptors_count(app_usbd_class_inst_t const * p_inst)
+{
+ app_usbd_hid_mouse_t const * p_mouse = hid_mouse_get(p_inst);
+ app_usbd_hid_inst_t const * p_hinst = &p_mouse->specific.inst.hid_inst;
+
+ return p_hinst->subclass_desc_count;
+}
+
+
+static app_usbd_descriptor_t hid_mouse_get_class_descriptors_type(
+ app_usbd_class_inst_t const * p_inst,
+ uint8_t desc_num)
+{
+ app_usbd_hid_mouse_t const * p_mouse = hid_mouse_get(p_inst);
+ app_usbd_hid_inst_t const * p_hinst = &p_mouse->specific.inst.hid_inst;
+
+ return p_hinst->p_subclass_desc[desc_num]->type;
+}
+
+
+static size_t hid_mouse_get_class_descriptors_length(app_usbd_class_inst_t const * p_inst,
+ uint8_t desc_num)
+{
+ app_usbd_hid_mouse_t const * p_mouse = hid_mouse_get(p_inst);
+ app_usbd_hid_inst_t const * p_hinst = &p_mouse->specific.inst.hid_inst;
+
+ return p_hinst->p_subclass_desc[desc_num]->size;
+}
+
+
+static uint8_t hid_mouse_get_class_descriptors_data(app_usbd_class_inst_t const * p_inst,
+ uint8_t desc_num,
+ uint32_t cur_byte)
+{
+ app_usbd_hid_mouse_t const * p_mouse = hid_mouse_get(p_inst);
+ app_usbd_hid_inst_t const * p_hinst = &p_mouse->specific.inst.hid_inst;
+
+ return p_hinst->p_subclass_desc[desc_num]->p_data[cur_byte];
+}
+
+
+static bool hid_mouse_feed_descriptors(app_usbd_class_descriptor_ctx_t * p_ctx,
+ app_usbd_class_inst_t const * p_inst,
+ uint8_t * p_buff,
+ size_t max_size)
+{
+ static uint8_t ifaces = 0;
+
+ ifaces = app_usbd_class_iface_count_get(p_inst);
+ app_usbd_hid_mouse_t const * p_mouse = hid_mouse_get(p_inst);
+
+ APP_USBD_CLASS_DESCRIPTOR_BEGIN(p_ctx, p_buff, max_size);
+
+ static uint8_t i = 0;
+
+ for (i = 0; i < ifaces; i++)
+ {
+ /* INTERFACE DESCRIPTOR */
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(0x09); // bLength
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(APP_USBD_DESCRIPTOR_INTERFACE); // bDescriptorType = Interface
+
+ static app_usbd_class_iface_conf_t const * p_cur_iface = NULL;
+ p_cur_iface = app_usbd_class_iface_get(p_inst, i);
+
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(app_usbd_class_iface_number_get(p_cur_iface)); // bInterfaceNumber
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(0x00); // bAlternateSetting
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(app_usbd_class_iface_ep_count_get(p_cur_iface)); // bNumEndpoints
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(APP_USBD_HID_CLASS); // bInterfaceClass = HID
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(p_mouse->specific.inst.hid_inst.subclass_boot); // bInterfaceSubclass (Boot Interface)
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(p_mouse->specific.inst.hid_inst.protocol); // bInterfaceProtocol
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(0x00); // iInterface
+
+ /* HID DESCRIPTOR */
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(0x09); // bLength
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(APP_USBD_HID_DESCRIPTOR_HID); // bDescriptorType = HID
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(LSB_16(APP_USBD_HID_BCD_VER)); // bcdHID LSB
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(MSB_16(APP_USBD_HID_BCD_VER)); // bcdHID MSB
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(APP_USBD_HID_COUNTRY_NOT_SUPPORTED); // bCountryCode
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(hid_mouse_get_class_descriptors_count(p_inst)); // bNumDescriptors
+
+ static uint8_t class_desc_cnt = 0;
+ class_desc_cnt = hid_mouse_get_class_descriptors_count(p_inst);
+ static uint8_t j = 0;
+ static uint16_t class_desc_len = 0;
+
+ for (j = 0; j < class_desc_cnt; j++)
+ {
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(hid_mouse_get_class_descriptors_type(p_inst, j)); // bDescriptorType
+
+ class_desc_len = hid_mouse_get_class_descriptors_length(p_inst, j);
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(LSB_16(class_desc_len)); // wDescriptorLength LSB
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(MSB_16(class_desc_len)); // wDescriptorLength MSB
+ }
+
+ static uint8_t endpoints = 0;
+ endpoints = app_usbd_class_iface_ep_count_get(p_cur_iface);
+
+ for (j = 0; j < endpoints; j++)
+ {
+ /* ENDPOINT DESCRIPTOR */
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(0x07); // bLengths
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(APP_USBD_DESCRIPTOR_ENDPOINT); // bDescriptorType = Endpoint
+
+ static app_usbd_class_ep_conf_t const * p_cur_ep = NULL;
+ p_cur_ep = app_usbd_class_iface_ep_get(p_cur_iface, i);
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(app_usbd_class_ep_address_get(p_cur_ep)); // bEndpointAddress
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(APP_USBD_DESCRIPTOR_EP_ATTR_TYPE_INTERRUPT); // bmAttributes
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(LSB_16(NRF_DRV_USBD_EPSIZE)); // wMaxPacketSize LSB
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(MSB_16(NRF_DRV_USBD_EPSIZE)); // wMaxPacketSize MSB
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(0x01); // bInterval
+ }
+ }
+
+ APP_USBD_CLASS_DESCRIPTOR_END();
+}
+
+static bool hid_mouse_feed_subclass_descriptor(app_usbd_class_descriptor_ctx_t * p_ctx,
+ app_usbd_class_inst_t const * p_inst,
+ uint8_t * p_buff,
+ size_t max_size,
+ uint8_t index)
+{
+ APP_USBD_CLASS_DESCRIPTOR_BEGIN(p_ctx, p_buff, max_size);
+
+ /* PHYSICAL AND REPORT DESCRIPTORS */
+ static uint32_t cur_byte = 0;
+ static size_t sub_desc_size = 0;
+ sub_desc_size = hid_mouse_get_class_descriptors_length(p_inst, index);
+
+ for (cur_byte = 0; cur_byte <= sub_desc_size; cur_byte++)
+ {
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(hid_mouse_get_class_descriptors_data(p_inst, index, cur_byte));
+ }
+
+ APP_USBD_CLASS_DESCRIPTOR_END();
+}
+
+/** @} */
+
+const app_usbd_hid_methods_t app_usbd_hid_mouse_methods = {
+ .on_get_report = hid_mouse_on_get_report,
+ .on_set_report = hid_mouse_on_set_report,
+ .ep_transfer_in = hid_mouse_ep_transfer_in,
+ .ep_transfer_out = NULL,
+ .feed_subclass_descriptor = hid_mouse_feed_subclass_descriptor,
+};
+
+const app_usbd_class_methods_t app_usbd_hid_mouse_class_methods = {
+ .event_handler = hid_mouse_event_handler,
+ .feed_descriptors = hid_mouse_feed_descriptors,
+};
+
+#endif //NRF_MODULE_ENABLED(APP_USBD_HID_MOUSE)
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/usbd/class/hid/mouse/app_usbd_hid_mouse.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/usbd/class/hid/mouse/app_usbd_hid_mouse.h
new file mode 100644
index 0000000..2293f3c
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/usbd/class/hid/mouse/app_usbd_hid_mouse.h
@@ -0,0 +1,184 @@
+/**
+ * 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#ifndef APP_USBD_HID_MOUSE_H__
+#define APP_USBD_HID_MOUSE_H__
+
+#include <stdint.h>
+#include <stdbool.h>
+
+#include "nrf_drv_usbd.h"
+#include "app_usbd_class_base.h"
+#include "app_usbd_hid_types.h"
+#include "app_usbd_hid.h"
+#include "app_usbd.h"
+#include "app_usbd_core.h"
+#include "app_usbd_descriptor.h"
+#include "app_usbd_hid_mouse_desc.h"
+#include "app_usbd_hid_mouse_internal.h"
+
+/**
+ * @defgroup app_usbd_hid_mouse USB HID mouse
+ * @ingroup app_usbd_hid
+ *
+ * @brief @tagAPI52840 Module with types, definitions, and API used by the HID mouse class.
+ * @{
+ */
+
+#ifdef DOXYGEN
+/**
+ * @brief HID mouse class instance type
+ *
+ * @ref APP_USBD_CLASS_TYPEDEF
+ */
+typedef struct { } app_usbd_hid_mouse_t;
+#else
+/*lint -save -e10 -e26 -e123 -e505 */
+APP_USBD_CLASS_TYPEDEF(app_usbd_hid_mouse, \
+ APP_USBD_HID_MOUSE_CONFIG(0, NRF_DRV_USBD_EPIN1), \
+ APP_USBD_HID_MOUSE_INSTANCE_SPECIFIC_DEC, \
+ APP_USBD_HID_MOUSE_DATA_SPECIFIC_DEC \
+);
+/*lint -restore*/
+#endif
+
+/**
+ * @brief Global definition macro of app_usbd_hid_mouse_t class.
+ *
+ * @param instance_name Name of global instance.
+ * @param interface_number Unique interface number.
+ * @param endpoint Input endpoint (@ref nrf_drv_usbd_ep_t).
+ * @param bcnt Mouse button count (from 1 to 8).
+ * @param user_ev_handler User event handler (optional).
+ * @param subclass_boot Subclass boot. (@ref app_usbd_hid_subclass_t)
+ *
+ * @note This macro is just simplified version of @ref APP_USBD_HID_MOUSE_GLOBAL_DEF_INTERNAL.
+ *
+ * @code
+ APP_USBD_HID_MOUSE_GLOBAL_DEF(my_awesome_mouse, 0, NRF_DRV_USBD_EPIN1, 3, NULL);
+ * @endcode
+ */
+#define APP_USBD_HID_MOUSE_GLOBAL_DEF(instance_name, \
+ interface_number, \
+ endpoint, \
+ bcnt, \
+ user_ev_handler, \
+ subclass_boot) \
+ APP_USBD_HID_GENERIC_SUBCLASS_REPORT_DESC(mouse_desc, APP_USBD_HID_MOUSE_REPORT_DSC_BUTTON(bcnt)); \
+ static const app_usbd_hid_subclass_desc_t * mouse_descs[] = {&mouse_desc}; \
+ APP_USBD_HID_MOUSE_GLOBAL_DEF_INTERNAL(instance_name, \
+ interface_number, \
+ endpoint, \
+ bcnt, \
+ user_ev_handler, \
+ subclass_boot)
+
+
+/**
+ * @brief Helper function to get class instance from HID mouse internals.
+ *
+ * @param[in] p_mouse Mouse instance (declared by @ref APP_USBD_HID_MOUSE_GLOBAL_DEF).
+ *
+ * @return Base class instance.
+ */
+static inline app_usbd_class_inst_t const *
+app_usbd_hid_mouse_class_inst_get(app_usbd_hid_mouse_t const * p_mouse)
+{
+ return &p_mouse->base;
+}
+
+/**
+ * @brief Helper function to get HID mouse from base class instance.
+ *
+ * @param[in] p_inst Base class instance.
+ *
+ * @return HID mouse class handle.
+ */
+static inline app_usbd_hid_mouse_t const *
+app_usbd_hid_mouse_class_get(app_usbd_class_inst_t const * p_inst)
+{
+ return (app_usbd_hid_mouse_t const *)p_inst;
+}
+
+/**
+ * @brief Move mouse X axis.
+ *
+ * @param[in] p_mouse Mouse instance (declared by @ref APP_USBD_HID_MOUSE_GLOBAL_DEF).
+ * @param[in] offset Relative mouse position: allowed full int8_t range.
+ *
+ * @return Standard error code.
+ */
+ret_code_t app_usbd_hid_mouse_x_move(app_usbd_hid_mouse_t const * p_mouse, int8_t offset);
+
+/**
+ * @brief Move mouse Y axis.
+ *
+ * @param[in] p_mouse Mouse instance (declared by @ref APP_USBD_HID_MOUSE_GLOBAL_DEF).
+ * @param[in] offset Relative mouse position: allowed full int8_t range.
+ *
+ * @return Standard error code.
+ */
+ret_code_t app_usbd_hid_mouse_y_move(app_usbd_hid_mouse_t const * p_mouse, int8_t offset);
+
+/**
+ * @brief Move mouse scroll.
+ *
+ * @param[in] p_mouse Mouse instance (declared by @ref APP_USBD_HID_MOUSE_GLOBAL_DEF).
+ * @param[in] offset Relative mouse position: allowed full int8_t range.
+ *
+ * @return Standard error code.
+ */
+ret_code_t app_usbd_hid_mouse_scroll_move(app_usbd_hid_mouse_t const * p_mouse, int8_t offset);
+
+/**
+ * @brief Set mouse button state.
+ *
+ * @param[in] p_mouse Mouse instance (declared by @ref APP_USBD_HID_MOUSE_GLOBAL_DEF).
+ * @param[in] button_id Button number (0...7).
+ * @param[in] state Button state: true -> PRESSED, false -> RELEASED.
+ *
+ * @return Standard error code.
+ */
+ret_code_t app_usbd_hid_mouse_button_state(app_usbd_hid_mouse_t const * p_mouse,
+ uint8_t button_id,
+ bool state);
+
+/** @} */
+
+#endif /* APP_USBD_HID_MOUSE_H__ */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/usbd/class/hid/mouse/app_usbd_hid_mouse_desc.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/usbd/class/hid/mouse/app_usbd_hid_mouse_desc.h
new file mode 100644
index 0000000..e7517c2
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/usbd/class/hid/mouse/app_usbd_hid_mouse_desc.h
@@ -0,0 +1,117 @@
+/**
+ * Copyright (c) 2016 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#ifndef APP_USBD_HID_MOUSE_DESC_H__
+#define APP_USBD_HID_MOUSE_DESC_H__
+
+/**
+ * @defgroup app_usbd_hid_mouse_desc USB HID mouse descriptors
+ * @ingroup app_usbd_hid_mouse
+ *
+ * @brief @tagAPI52840 Module with types, definitions, and API used by the HID mouse class.
+ * @{
+ */
+
+/**
+ * @brief Initializer of interface descriptor for HID mouse class.
+ *
+ * @param interface_number Interface number.
+ */
+#define APP_USBD_HID_MOUSE_INTERFACE_DSC(interface_number) \
+ APP_USBD_HID_INTERFACE_DSC(interface_number, \
+ 1, \
+ APP_USBD_HID_SUBCLASS_BOOT, \
+ APP_USBD_HID_PROTO_MOUSE)
+
+/**
+ * @brief Initializer of HID descriptor for HID mouse class.
+ *
+ * @param ... Descriptor list.
+ */
+#define APP_USBD_HID_MOUSE_HID_DSC(...) \
+ APP_USBD_HID_HID_DSC(__VA_ARGS__)
+
+/**
+ * @brief Initializer of endpoint descriptor for HID mouse class.
+ *
+ * @param endpoint_number Endpoint number.
+ */
+#define APP_USBD_HID_MOUSE_EP_DSC(endpoint_number) \
+ APP_USBD_HID_EP_DSC(endpoint_number, 8, 1)
+
+
+
+/**
+ * @brief Example of USB HID mouse report descriptor for n button mouse.
+ *
+ * @param bcnt Button count. Allowed values from 1 to 8.
+ */
+#define APP_USBD_HID_MOUSE_REPORT_DSC_BUTTON(bcnt) { \
+ 0x05, 0x01, /* Usage Page (Generic Desktop), */ \
+ 0x09, 0x02, /* Usage (Mouse), */ \
+ 0xA1, 0x01, /* Collection (Application), */ \
+ 0x09, 0x01, /* Usage (Pointer), */ \
+ 0xA1, 0x00, /* Collection (Physical), */ \
+ 0x05, 0x09, /* Usage Page (Buttons), */ \
+ 0x19, 0x01, /* Usage Minimum (01), */ \
+ 0x29, bcnt, /* Usage Maximum (bcnt), */ \
+ 0x15, 0x00, /* Logical Minimum (0), */ \
+ 0x25, 0x01, /* Logical Maximum (1), */ \
+ 0x75, 0x01, /* Report Size (1), */ \
+ 0x95, bcnt, /* Report Count (bcnt), */ \
+ 0x81, 0x02, /* Input (Data, Variable, Absolute)*/ \
+ 0x75, (8-(bcnt)), /* Report Size (8-(bcnt)), */ \
+ 0x95, 0x01, /* Report Count (1), */ \
+ 0x81, 0x01, /* Input (Constant), */ \
+ 0x05, 0x01, /* Usage Page (Generic Desktop), */ \
+ 0x09, 0x30, /* Usage (X), */ \
+ 0x09, 0x31, /* Usage (Y), */ \
+ 0x09, 0x38, /* Usage (Scroll), */ \
+ 0x15, 0x81, /* Logical Minimum (-127), */ \
+ 0x25, 0x7F, /* Logical Maximum (127), */ \
+ 0x75, 0x08, /* Report Size (8), */ \
+ 0x95, 0x03, /* Report Count (3), */ \
+ 0x81, 0x06, /* Input (Data, Variable, Relative)*/ \
+ 0xC0, /* End Collection, */ \
+ 0xC0, /* End Collection */ \
+}
+
+ /** @} */
+
+#endif /* APP_USBD_HID_MOUSE_DESC_H__ */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/usbd/class/hid/mouse/app_usbd_hid_mouse_internal.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/usbd/class/hid/mouse/app_usbd_hid_mouse_internal.h
new file mode 100644
index 0000000..64ccc7f
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/usbd/class/hid/mouse/app_usbd_hid_mouse_internal.h
@@ -0,0 +1,173 @@
+/**
+ * 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#ifndef APP_USBD_HID_MOUSE_INTERNAL_H__
+#define APP_USBD_HID_MOUSE_INTERNAL_H__
+
+/**
+ * @defgroup app_usbd_hid_mouse_internals USB HID mouse internals
+ * @ingroup app_usbd_hid_mouse
+ *
+ * @brief @tagAPI52840 Module with types, definitions, and API used by the HID mouse class.
+ * @{
+ */
+
+/**
+ * @brief Forward declaration of HID mouse class type.
+ */
+APP_USBD_CLASS_FORWARD(app_usbd_hid_mouse);
+
+
+/**
+ * @brief HID mouse part of class instance data.
+ */
+typedef struct {
+ app_usbd_hid_inst_t hid_inst; //!< HID instance data.
+ const uint8_t button_count; //!< Number of buttons mouse specific.
+} app_usbd_hid_mouse_inst_t;
+
+/**
+ * @brief HID mouse context.
+ */
+typedef struct {
+ app_usbd_hid_ctx_t hid_ctx; //!< HID class context.
+
+ int16_t acc_x_axis; //!< Mouse specific. Accumulated x axis offset.
+ int16_t acc_y_axis; //!< Mouse specific. Accumulated y axis offset.
+ int16_t acc_scroll; //!< Mouse specific. Accumulated scroll offset.
+ uint8_t button_state; //!< Mouse specific. Actual button state. Bitfield of maximum 8 buttons states.
+ uint8_t report_buff[4];
+} app_usbd_hid_mouse_ctx_t;
+
+
+/**
+ * @brief HID mouse configuration macro.
+ *
+ * Used by @ref APP_USBD_HID_MOUSE_GLOBAL_DEF.
+ *
+ */
+#define APP_USBD_HID_MOUSE_CONFIG(iface, ep) ((iface, ep))
+
+
+/**
+ * @brief Specific class constant data for HID mouse class.
+ */
+#define APP_USBD_HID_MOUSE_INSTANCE_SPECIFIC_DEC app_usbd_hid_mouse_inst_t inst;
+
+/**
+ * @brief Specific class data for HID mouse class.
+ */
+#define APP_USBD_HID_MOUSE_DATA_SPECIFIC_DEC app_usbd_hid_mouse_ctx_t ctx;
+
+
+/**
+ * @brief HID mouse descriptors config macro
+ *
+ * @ref app_usbd_hid_mouse_inst_t
+ *
+ */
+#define APP_USBD_HID_MOUSE_DSC_CONFIG(interface_number, endpoint, rep_desc) { \
+ APP_USBD_HID_MOUSE_INTERFACE_DSC(interface_number) \
+ APP_USBD_HID_MOUSE_HID_DSC(rep_desc) \
+ APP_USBD_HID_MOUSE_EP_DSC(endpoint) \
+}
+
+/**
+ * @brief Configure internal part of HID mouse instance.
+ *
+ * @param report_buff_in Input report buffers array.
+ * @param report_buff_out Output report buffer.
+ * @param user_ev_handler User event handler.
+ * @param bcnt Mouse button count.
+ * @param subclass_boot Subclass boot. (@ref app_usbd_hid_subclass_t)
+ */
+#define APP_USBD_HID_MOUSE_INST_CONFIG(report_buff_in, \
+ report_buff_out, \
+ user_ev_handler, \
+ bcnt, \
+ subclass_boot) \
+ .inst = { \
+ .hid_inst = APP_USBD_HID_INST_CONFIG(mouse_descs, \
+ subclass_boot, \
+ APP_USBD_HID_PROTO_MOUSE, \
+ report_buff_in, \
+ report_buff_out, \
+ user_ev_handler, \
+ &app_usbd_hid_mouse_methods), \
+ .button_count = bcnt, \
+ }
+
+/**
+ * @brief Public HID mouse interface.
+ */
+extern const app_usbd_hid_methods_t app_usbd_hid_mouse_methods;
+
+/**
+ * @brief Public HID mouse class interface.
+ */
+extern const app_usbd_class_methods_t app_usbd_hid_mouse_class_methods;
+
+/**
+ * @brief Global definition of app_usbd_hid_mouse_t class.
+ *
+ * @ref APP_USBD_HID_MOUSE_GLOBAL_DEF
+ */
+#define APP_USBD_HID_MOUSE_GLOBAL_DEF_INTERNAL(instance_name, \
+ interface_number, \
+ endpoint, \
+ bcnt, \
+ user_ev_handler, \
+ subclass_boot) \
+ static app_usbd_hid_report_buffer_t CONCAT_2(instance_name, _in)[1]; \
+ APP_USBD_CLASS_INST_GLOBAL_DEF( \
+ instance_name, \
+ app_usbd_hid_mouse, \
+ &app_usbd_hid_mouse_class_methods, \
+ APP_USBD_HID_MOUSE_CONFIG(interface_number, endpoint), \
+ (APP_USBD_HID_MOUSE_INST_CONFIG(CONCAT_2(instance_name, _in), \
+ NULL, \
+ user_ev_handler, \
+ bcnt, \
+ subclass_boot)) \
+ )
+
+
+/** @} */
+
+#endif /* APP_USBD_HID_MOUSE_INTERNAL_H__ */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/usbd/class/msc/app_usbd_msc.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/usbd/class/msc/app_usbd_msc.c
new file mode 100644
index 0000000..a19de11
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/usbd/class/msc/app_usbd_msc.c
@@ -0,0 +1,2365 @@
+/**
+ * Copyright (c) 2016 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#include "sdk_common.h"
+#if NRF_MODULE_ENABLED(APP_USBD_MSC)
+
+#include <string.h>
+#include <ctype.h>
+#include "app_usbd.h"
+#include "app_usbd_msc.h"
+#include "app_usbd_string_desc.h"
+
+/**
+ * @defgroup app_usbd_msc_internal USBD MSC internals
+ * @{
+ * @ingroup app_usbd_msc
+ * @internal
+ */
+
+STATIC_ASSERT(sizeof(app_usbd_scsi_cmd_requestsense_t) == 6);
+STATIC_ASSERT(sizeof(app_usbd_scsi_cmd_requestsense_resp_t) == 18);
+STATIC_ASSERT(sizeof(app_usbd_scsi_cmd_inquiry_t) == 6);
+STATIC_ASSERT(sizeof(app_usbd_scsi_cmd_inquiry_resp_t) == 36);
+STATIC_ASSERT(sizeof(app_usbd_scsi_cmd_read6_t) == 6);
+STATIC_ASSERT(sizeof(app_usbd_scsi_cmd_write6_t) == 6);
+STATIC_ASSERT(sizeof(app_usbd_scsi_cmd_modesense6_t) == 6);
+STATIC_ASSERT(sizeof(app_usbd_scsi_cmd_modesense6_resp_t) == 4);
+STATIC_ASSERT(sizeof(app_usbd_scsi_cmd_readcapacity10_t) == 10);
+STATIC_ASSERT(sizeof(app_usbd_scsi_cmd_readcapacity10_resp_t) == 8);
+STATIC_ASSERT(sizeof(app_usbd_scsi_cmd_read10_t) == 10);
+STATIC_ASSERT(sizeof(app_usbd_scsi_cmd_write10_t) == 10);
+STATIC_ASSERT(sizeof(app_usbd_scsi_cmd_modesense10_t) == 10);
+STATIC_ASSERT(sizeof(app_usbd_scsi_cmd_modesense10_resp_t) == 8);
+
+STATIC_ASSERT(sizeof(app_usbd_msc_cbw_t) == 31);
+STATIC_ASSERT(sizeof(app_usbd_msc_csw_t) == 13);
+
+#define NRF_LOG_MODULE_NAME usbd_msc
+
+#if APP_USBD_MSC_CONFIG_LOG_ENABLED
+#define NRF_LOG_LEVEL APP_USBD_MSC_CONFIG_LOG_LEVEL
+#define NRF_LOG_INFO_COLOR APP_USBD_MSC_CONFIG_INFO_COLOR
+#define NRF_LOG_DEBUG_COLOR APP_USBD_MSC_CONFIG_DEBUG_COLOR
+#else // APP_USBD_MSC_CONFIG_LOG_ENABLED
+#define NRF_LOG_LEVEL 0
+#endif // APP_USBD_MSC_CONFIG_LOG_ENABLED
+#include "nrf_log.h"
+NRF_LOG_MODULE_REGISTER();
+
+#define APP_USBD_MSC_IFACE_IDX 0 /**< Mass storage class interface index */
+#define APP_USBD_MSC_EPIN_IDX 0 /**< Mass storage class endpoint IN index */
+#define APP_USBD_MSC_EPOUT_IDX 1 /**< Mass storage class endpoint OUT index */
+
+/**
+ * @brief Set request buffer busy flag
+ *
+ * @param[in] val Bitmask to set
+ * @param[in] id Buffer id
+ * */
+#define APP_USBD_MSC_REQ_BUSY_SET(val, id) SET_BIT(val, id)
+
+/**
+ * @brief Clear request buffer busy flag
+ *
+ * @param[in] val Bitmask to set
+ * @param[in] id Buffer id
+ * */
+#define APP_USBD_MSC_REQ_BUSY_CLR(val, id) CLR_BIT(val, id)
+
+#define APP_USBD_MSC_REQ_BUSY_FULL_MASK (0x03) /**< Request busy mask */
+
+static void msc_blockdev_ev_handler(nrf_block_dev_t const * p_blk_dev,
+ nrf_block_dev_event_t const * p_event);
+
+/**
+ * @brief Auxiliary function to access MSC instance data
+ *
+ * @param[in] p_inst Class instance data
+ *
+ * @return MSC instance data @ref app_usbd_msc_t
+ */
+static inline app_usbd_msc_t const * msc_get(app_usbd_class_inst_t const * p_inst)
+{
+ ASSERT(p_inst != NULL);
+ return (app_usbd_msc_t const *)p_inst;
+}
+
+
+/**
+ * @brief Auxiliary function to access MSC context data
+ *
+ * @param[in] p_msc MSC instance data
+ * @return MSC context data @ref app_usbd_msc_ctx_t
+ */
+static inline app_usbd_msc_ctx_t * msc_ctx_get(app_usbd_msc_t const * p_msc)
+{
+ ASSERT(p_msc != NULL);
+ ASSERT(p_msc->specific.p_data != NULL);
+ return &p_msc->specific.p_data->ctx;
+}
+
+
+/**
+ * @brief Auxiliary function to access MSC IN endpoint address
+ *
+ * @param[in] p_inst Class instance data
+ *
+ * @return IN endpoint address
+ */
+static inline nrf_drv_usbd_ep_t ep_in_addr_get(app_usbd_class_inst_t const * p_inst)
+{
+ app_usbd_class_iface_conf_t const * class_iface;
+
+ class_iface = app_usbd_class_iface_get(p_inst, APP_USBD_MSC_IFACE_IDX);
+
+ app_usbd_class_ep_conf_t const * ep_cfg;
+ ep_cfg = app_usbd_class_iface_ep_get(class_iface, APP_USBD_MSC_EPIN_IDX);
+
+ return app_usbd_class_ep_address_get(ep_cfg);
+}
+
+
+/**
+ * @brief Auxiliary function to access MSC OUT endpoint address
+ *
+ * @param[in] p_inst Class instance data
+ *
+ * @return OUT endpoint address
+ */
+static inline nrf_drv_usbd_ep_t ep_out_addr_get(app_usbd_class_inst_t const * p_inst)
+{
+ app_usbd_class_iface_conf_t const * class_iface;
+
+ class_iface = app_usbd_class_iface_get(p_inst, APP_USBD_MSC_IFACE_IDX);
+
+ app_usbd_class_ep_conf_t const * ep_cfg;
+ ep_cfg = app_usbd_class_iface_ep_get(class_iface, APP_USBD_MSC_EPOUT_IDX);
+
+ return app_usbd_class_ep_address_get(ep_cfg);
+}
+
+
+/**
+ * @brief Command Block Wrapper trigger
+ *
+ * @param[in] p_inst Generic class instance
+ * @param[in] state Next state transition
+ *
+ * @return Standard error code
+ * */
+static ret_code_t cbw_wait_start(app_usbd_class_inst_t const * p_inst)
+{
+ app_usbd_msc_t const * p_msc = msc_get(p_inst);
+ app_usbd_msc_ctx_t * p_msc_ctx = msc_ctx_get(p_msc);
+
+ nrf_drv_usbd_ep_t ep_addr_out = ep_out_addr_get(p_inst);
+
+ NRF_LOG_DEBUG("cbw_wait_start");
+ memset(&p_msc_ctx->cbw, 0, sizeof(app_usbd_msc_cbw_t));
+ NRF_DRV_USBD_TRANSFER_OUT(cbw, &p_msc_ctx->cbw, sizeof(app_usbd_msc_cbw_t));
+ ret_code_t ret = app_usbd_ep_transfer(ep_addr_out, &cbw);
+ if (ret == NRF_SUCCESS)
+ {
+ p_msc_ctx->state = APP_USBD_MSC_STATE_CBW;
+ }
+
+ return ret;
+}
+
+
+/**
+ * @brief Command Status Wrapper trigger
+ *
+ * @param[in] p_inst Generic class instance
+ * @param[in] state Next state transition
+ *
+ * @return Standard error code
+ * */
+static ret_code_t csw_wait_start(app_usbd_class_inst_t const * p_inst, uint8_t status)
+{
+ app_usbd_msc_t const * p_msc = msc_get(p_inst);
+ app_usbd_msc_ctx_t * p_msc_ctx = msc_ctx_get(p_msc);
+
+ nrf_drv_usbd_ep_t ep_addr_in = ep_in_addr_get(p_inst);
+
+ memset(&p_msc_ctx->csw, 0, sizeof(app_usbd_msc_csw_t));
+ memcpy(p_msc_ctx->csw.signature, APP_USBD_MSC_CSW_SIGNATURE, sizeof(p_msc_ctx->csw.signature));
+ memcpy(p_msc_ctx->csw.tag, p_msc_ctx->cbw.tag, sizeof(p_msc_ctx->csw.tag));
+ memcpy(p_msc_ctx->csw.residue, &p_msc_ctx->current.residue, sizeof(uint32_t));
+ p_msc_ctx->csw.status = status;
+
+ NRF_DRV_USBD_TRANSFER_IN(csw, &p_msc_ctx->csw, sizeof(app_usbd_msc_csw_t));
+ ret_code_t ret = app_usbd_ep_transfer(ep_addr_in, &csw);
+ if (ret == NRF_SUCCESS)
+ {
+ p_msc_ctx->state = APP_USBD_MSC_STATE_CSW;
+ }
+
+ return ret;
+}
+
+
+/**
+ * @brief IN transfer trigger
+ *
+ * @param[in] p_inst Generic class instance
+ * @param[in] p_buff IN transfer data buffer
+ * @param[in] size IN transfer size
+ * @param[in] state Next state transition
+ *
+ * @return Standard error code
+ * */
+static ret_code_t transfer_in_start(app_usbd_class_inst_t const * p_inst,
+ void const * p_buff,
+ size_t size,
+ app_usbd_msc_state_t state)
+{
+ app_usbd_msc_t const * p_msc = msc_get(p_inst);
+ app_usbd_msc_ctx_t * p_msc_ctx = msc_ctx_get(p_msc);
+
+ NRF_LOG_DEBUG("transfer_in_start: p_buff: %p, size: %u", (uint32_t)p_buff, size);
+
+ nrf_drv_usbd_ep_t ep_addr_in = ep_in_addr_get(p_inst);
+
+ NRF_DRV_USBD_TRANSFER_IN(resp, p_buff, size);
+ ret_code_t ret = app_usbd_ep_transfer(ep_addr_in, &resp);
+ if (ret == NRF_SUCCESS)
+ {
+ p_msc_ctx->state = state;
+ }
+ return ret;
+}
+
+
+/**
+ * @brief MSC reset request handler @ref APP_USBD_MSC_REQ_BULK_RESET
+ *
+ * @param[in] p_inst Generic class instance
+ *
+ * */
+static void bulk_ep_reset(app_usbd_class_inst_t const * p_inst)
+{
+ nrf_drv_usbd_ep_t ep_addr_in = ep_in_addr_get(p_inst);
+ nrf_drv_usbd_ep_t ep_addr_out = ep_out_addr_get(p_inst);
+
+ nrf_drv_usbd_ep_abort(ep_addr_in);
+ nrf_drv_usbd_ep_abort(ep_addr_out);
+}
+
+
+/**
+ * @brief OUT transfer trigger
+ *
+ * @param[in] p_inst Generic class instance
+ * @param[in] p_buff OUT transfer data buffer
+ * @param[in] size OUT transfer size
+ * @param[in] state Next state transition
+ *
+ * @return Standard error code
+ * */
+static ret_code_t transfer_out_start(app_usbd_class_inst_t const * p_inst,
+ void * p_buff,
+ size_t size,
+ app_usbd_msc_state_t state)
+{
+ app_usbd_msc_t const * p_msc = msc_get(p_inst);
+ app_usbd_msc_ctx_t * p_msc_ctx = msc_ctx_get(p_msc);
+
+ NRF_LOG_DEBUG("transfer_out_start: p_buff: %p, size: %u", (uint32_t)p_buff, size);
+ nrf_drv_usbd_ep_t ep_addr_out = ep_out_addr_get(p_inst);
+
+ NRF_DRV_USBD_TRANSFER_OUT(resp, p_buff, size);
+ ret_code_t ret = app_usbd_ep_transfer(ep_addr_out, &resp);
+ if (ret == NRF_SUCCESS)
+ {
+ p_msc_ctx->state = state;
+ }
+ return ret;
+}
+
+
+/**
+ * @brief Generic function to stall communication endpoints and mark error state
+ *
+ * Function used internally to stall all communication endpoints and mark current state.
+ *
+ * @param p_inst Generic class instance
+ * @param state State to set
+ */
+static void status_generic_error_stall(app_usbd_class_inst_t const * p_inst,
+ app_usbd_msc_state_t state)
+{
+ app_usbd_msc_t const * p_msc = msc_get(p_inst);
+ app_usbd_msc_ctx_t * p_msc_ctx = msc_ctx_get(p_msc);
+
+ nrf_drv_usbd_ep_t ep_in = ep_in_addr_get(p_inst);
+ nrf_drv_usbd_ep_t ep_out = ep_out_addr_get(p_inst);
+
+ nrf_drv_usbd_ep_stall(ep_in);
+ nrf_drv_usbd_ep_stall(ep_out);
+ nrf_drv_usbd_ep_abort(ep_in);
+ nrf_drv_usbd_ep_abort(ep_out);
+
+ p_msc_ctx->state = state;
+}
+
+
+/**
+ * @brief Start status stage of unsupported SCSI command
+ *
+ * @param[in,out] p_inst Generic class instance
+ *
+ * @return Standard error code
+ *
+ * @sa status_generic_error_stall
+ */
+static ret_code_t status_unsupported_start(app_usbd_class_inst_t const * p_inst)
+{
+ app_usbd_msc_t const * p_msc = msc_get(p_inst);
+ app_usbd_msc_ctx_t * p_msc_ctx = msc_ctx_get(p_msc);
+ bool data_stage = uint32_decode(p_msc_ctx->cbw.datlen) != 0;
+
+ if (!data_stage)
+ {
+ /* Try to transfer the response now */
+ ret_code_t ret;
+ ret = csw_wait_start(p_inst, APP_USBD_MSC_CSW_STATUS_FAIL);
+ if (ret == NRF_SUCCESS)
+ {
+ return ret;
+ }
+ }
+
+ /* Cannot transfer failed response in current command - stall the endpoints and postpone the answer */
+ status_generic_error_stall(p_inst, APP_USBD_MSC_STATE_UNSUPPORTED);
+ if (data_stage)
+ {
+ if (!(p_msc_ctx->cbw.flags & APP_USBD_MSC_CBW_DIRECTION_IN))
+ {
+ nrf_drv_usbd_transfer_out_drop(ep_out_addr_get(p_inst));
+ }
+ /* Unsupported command so we did not process any data - mark it in current residue value */
+ p_msc_ctx->current.residue = uint32_decode(p_msc_ctx->cbw.datlen);
+ }
+ return NRF_SUCCESS;
+}
+
+
+/**
+ * @brief Start status stage of CBW invalid
+ *
+ * @param[in,out] p_inst Generic class instance
+ *
+ * @sa status_generic_error_stall
+ */
+static void status_cbwinvalid_start(app_usbd_class_inst_t const * p_inst)
+{
+ status_generic_error_stall(p_inst, APP_USBD_MSC_STATE_CBW_INVALID);
+}
+
+
+/**
+ * @brief Start status stage of internal device error
+ *
+ * Kind of error that requires bulk reset but does not stall endpoint permanently - the correct
+ * answer is possible.
+ *
+ * @param[in] p_inst Generic class instance
+ *
+ * @sa status_generic_error_stall
+ */
+static void status_deverror_start(app_usbd_class_inst_t const * p_inst)
+{
+ status_generic_error_stall(p_inst, APP_USBD_MSC_STATE_DEVICE_ERROR);
+}
+
+
+/**
+ * @brief Internal SETUP standard IN request handler
+ *
+ * @param[in] p_inst Generic class instance
+ * @param[in] p_setup_ev Setup event
+ *
+ * @return Standard error code
+ * @retval NRF_SUCCESS if request handled correctly
+ * @retval NRF_ERROR_NOT_SUPPORTED if request is not supported
+ */
+static ret_code_t setup_req_std_in(app_usbd_class_inst_t const * p_inst,
+ app_usbd_setup_evt_t const * p_setup_ev)
+{
+ /* Only Get Descriptor standard IN request is supported by MSC class */
+ if ((app_usbd_setup_req_rec(p_setup_ev->setup.bmRequestType) == APP_USBD_SETUP_REQREC_INTERFACE)
+ &&
+ (p_setup_ev->setup.bmRequest == APP_USBD_SETUP_STDREQ_GET_DESCRIPTOR))
+ {
+ size_t dsc_len = 0;
+ size_t max_size;
+
+ uint8_t * p_trans_buff = app_usbd_core_setup_transfer_buff_get(&max_size);
+
+ /* Try to find descriptor in class internals*/
+ ret_code_t ret = app_usbd_class_descriptor_find(
+ p_inst,
+ p_setup_ev->setup.wValue.hb,
+ p_setup_ev->setup.wValue.lb,
+ p_trans_buff,
+ &dsc_len);
+
+ if (ret != NRF_ERROR_NOT_FOUND)
+ {
+ ASSERT(dsc_len < NRF_DRV_USBD_EPSIZE);
+ return app_usbd_core_setup_rsp(&(p_setup_ev->setup), p_trans_buff, dsc_len);
+ }
+ }
+ return NRF_ERROR_NOT_SUPPORTED;
+}
+
+
+/**
+ * @brief Internal SETUP standard OUT request handler
+ *
+ * @param[in] p_inst Generic class instance
+ * @param[in] p_setup_ev Setup event
+ *
+ * @return Standard error code
+ * @retval NRF_SUCCESS if request handled correctly
+ * @retval NRF_ERROR_NOT_SUPPORTED if request is not supported
+ * @retval NRF_ERROR_FORBIDDEN if endpoint stall cannot be cleared because of internal state
+ */
+static ret_code_t setup_req_std_out(app_usbd_class_inst_t const * p_inst,
+ app_usbd_setup_evt_t const * p_setup_ev)
+{
+ app_usbd_msc_t const * p_msc = msc_get(p_inst);
+ app_usbd_msc_ctx_t * p_msc_ctx = msc_ctx_get(p_msc);
+
+ app_usbd_setup_reqrec_t req_rec = app_usbd_setup_req_rec(p_setup_ev->setup.bmRequestType);
+
+ if ((req_rec == APP_USBD_SETUP_REQREC_ENDPOINT) &&
+ (p_setup_ev->setup.bmRequest == APP_USBD_SETUP_STDREQ_CLEAR_FEATURE) &&
+ (p_setup_ev->setup.wValue.w == APP_USBD_SETUP_STDFEATURE_ENDPOINT_HALT))
+ {
+ if (p_msc_ctx->state == APP_USBD_MSC_STATE_CBW_INVALID)
+ {
+ return NRF_ERROR_FORBIDDEN;
+ }
+ ret_code_t ret = NRF_SUCCESS;
+ /* Clearing endpoint here. It is done normally inside app_usbd, but we are overwritting this functionality */
+ nrf_drv_usbd_ep_t ep_addr = (nrf_drv_usbd_ep_t)(p_setup_ev->setup.wIndex.lb);
+ nrf_drv_usbd_ep_dtoggle_clear(ep_addr);
+ nrf_drv_usbd_ep_stall_clear(ep_addr);
+ if (NRF_USBD_EPIN_CHECK(ep_addr))
+ {
+ switch (p_msc_ctx->state)
+ {
+ case APP_USBD_MSC_STATE_UNSUPPORTED:
+ {
+ nrf_drv_usbd_ep_stall_clear(ep_out_addr_get(p_inst));
+ /*Unsupported command handle: status stage*/
+ ret = csw_wait_start(p_inst, APP_USBD_MSC_CSW_STATUS_FAIL);
+ if (ret != NRF_SUCCESS)
+ {
+ NRF_LOG_ERROR("Unexpected csw_wait_start on ep clear: %d", ret);
+ }
+ break;
+ }
+
+ case APP_USBD_MSC_STATE_DEVICE_ERROR:
+ {
+ nrf_drv_usbd_ep_stall_clear(ep_out_addr_get(p_inst));
+ /*Unsupported command handle: status stage*/
+ ret = csw_wait_start(p_inst, APP_USBD_MSC_CSW_STATUS_PE);
+ if (ret != NRF_SUCCESS)
+ {
+ NRF_LOG_ERROR("Unexpected csw_wait_start on ep clear: %d", ret);
+ }
+ break;
+ }
+
+ default:
+ break;
+ }
+ }
+ return ret;
+ }
+ return NRF_ERROR_NOT_SUPPORTED;
+}
+
+
+/**
+ * @brief Internal SETUP class IN request handler
+ *
+ * @param[in] p_inst Generic class instance
+ * @param[in] p_setup_ev Setup event
+ *
+ * @return Standard error code
+ * @retval NRF_SUCCESS if request handled correctly
+ * @retval NRF_ERROR_NOT_SUPPORTED if request is not supported
+ */
+static ret_code_t setup_req_class_in(app_usbd_class_inst_t const * p_inst,
+ app_usbd_setup_evt_t const * p_setup_ev)
+{
+ app_usbd_msc_t const * p_msc = msc_get(p_inst);
+
+ switch (p_setup_ev->setup.bmRequest)
+ {
+ case APP_USBD_MSC_REQ_GET_MAX_LUN:
+ {
+
+ if (p_setup_ev->setup.wValue.w != 0)
+ {
+ break;
+ }
+
+ if (p_setup_ev->setup.wLength.w != 1)
+ {
+ break;
+ }
+
+ size_t tx_size;
+ uint16_t * p_tx_buff = app_usbd_core_setup_transfer_buff_get(&tx_size);
+ ASSERT(p_msc->specific.inst.block_devs_count != 0);
+ p_tx_buff[0] = p_msc->specific.inst.block_devs_count - 1;
+
+ ret_code_t ret = cbw_wait_start(p_inst);
+ UNUSED_VARIABLE(ret);
+ return app_usbd_core_setup_rsp(&(p_setup_ev->setup), p_tx_buff, sizeof(uint8_t));
+ }
+
+ default:
+ break;
+
+ }
+
+ return NRF_ERROR_NOT_SUPPORTED;
+}
+
+
+/**
+ * @brief Internal SETUP class OUT request handler
+ *
+ * @param[in] p_inst Generic class instance
+ * @param[in] p_setup_ev Setup event
+ *
+ * @return Standard error code
+ * @retval NRF_SUCCESS if request handled correctly
+ * @retval NRF_ERROR_NOT_SUPPORTED if request is not supported
+ */
+static ret_code_t setup_req_class_out(app_usbd_class_inst_t const * p_inst,
+ app_usbd_setup_evt_t const * p_setup_ev)
+{
+ app_usbd_msc_t const * p_msc = msc_get(p_inst);
+ app_usbd_msc_ctx_t * p_msc_ctx = msc_ctx_get(p_msc);
+
+ switch (p_setup_ev->setup.bmRequest)
+ {
+ case APP_USBD_MSC_REQ_BULK_RESET:
+ {
+ if (p_setup_ev->setup.wValue.w != 0)
+ {
+ break;
+ }
+
+ if (p_setup_ev->setup.wLength.w != 0)
+ {
+ break;
+ }
+
+ /*
+ * Reset internal state to be ready for next CBW
+ */
+ NRF_LOG_DEBUG("bulk ep reset");
+ bulk_ep_reset(p_inst);
+
+ if (p_msc_ctx->state != APP_USBD_MSC_STATE_CBW)
+ {
+ ret_code_t ret = cbw_wait_start(p_inst);
+ UNUSED_VARIABLE(ret);
+ }
+
+ return NRF_SUCCESS;
+ }
+
+ default:
+ break;
+ }
+
+ return NRF_ERROR_NOT_SUPPORTED;
+}
+
+
+/**
+ * @brief Control endpoint handle
+ *
+ * @param[in] p_inst Generic class instance
+ * @param[in] p_setup_ev Setup event
+ *
+ * @return Standard error code
+ * @retval NRF_SUCCESS if request handled correctly
+ * @retval NRF_ERROR_NOT_SUPPORTED if request is not supported
+ */
+static ret_code_t setup_event_handler(app_usbd_class_inst_t const * p_inst,
+ app_usbd_setup_evt_t const * p_setup_ev)
+{
+ ASSERT(p_inst != NULL);
+ ASSERT(p_setup_ev != NULL);
+
+ if (app_usbd_setup_req_dir(p_setup_ev->setup.bmRequestType) == APP_USBD_SETUP_REQDIR_IN)
+ {
+ switch (app_usbd_setup_req_typ(p_setup_ev->setup.bmRequestType))
+ {
+ case APP_USBD_SETUP_REQTYPE_STD:
+ return setup_req_std_in(p_inst, p_setup_ev);
+
+ case APP_USBD_SETUP_REQTYPE_CLASS:
+ return setup_req_class_in(p_inst, p_setup_ev);
+
+ default:
+ break;
+ }
+ }
+ else /* APP_USBD_SETUP_REQDIR_OUT */
+ {
+ switch (app_usbd_setup_req_typ(p_setup_ev->setup.bmRequestType))
+ {
+ case APP_USBD_SETUP_REQTYPE_STD:
+ return setup_req_std_out(p_inst, p_setup_ev);
+
+ case APP_USBD_SETUP_REQTYPE_CLASS:
+ return setup_req_class_out(p_inst, p_setup_ev);
+
+ default:
+ break;
+ }
+ }
+
+ return NRF_ERROR_NOT_SUPPORTED;
+}
+
+
+/**
+ * @brief Handle read6/read10 command data stage
+ *
+ * @param[in] p_inst Generic class instance
+ *
+ * @return Standard error code
+ * @retval NRF_SUCCESS if request handled correctly
+ * @retval NRF_ERROR_NOT_SUPPORTED if request is not supported
+ */
+static ret_code_t state_data_in_handle(app_usbd_class_inst_t const * p_inst)
+{
+ app_usbd_msc_t const * p_msc = msc_get(p_inst);
+ app_usbd_msc_ctx_t * p_msc_ctx = msc_ctx_get(p_msc);
+
+ ret_code_t ret = NRF_SUCCESS;
+
+ p_msc_ctx->current.trans_in_progress = false;
+ APP_USBD_MSC_REQ_BUSY_CLR(p_msc_ctx->current.req_busy_mask, p_msc_ctx->current.trans_req_id);
+
+ if (p_msc_ctx->current.blk_datasize == 0 && p_msc_ctx->current.req_busy_mask == 0)
+ {
+ p_msc_ctx->current.blk_idx = p_msc_ctx->current.blk_size = 0;
+ ret = csw_wait_start(p_inst, p_msc_ctx->current.csw_status);
+ return ret;
+ }
+
+ ASSERT(p_msc_ctx->current.blk_size != 0);
+
+ if (p_msc_ctx->current.req_busy_mask == 0)
+ {
+ nrf_block_dev_t const * p_blkd =
+ p_msc->specific.inst.pp_block_devs[p_msc_ctx->current.lun];
+
+ /*Trigger new block read request*/
+ p_msc_ctx->current.workbuff_pos ^= p_msc->specific.inst.block_buff_size;
+ uint32_t req_pos = p_msc_ctx->current.workbuff_pos != 0 ? 1 : 0;
+ APP_USBD_MSC_REQ_BUSY_SET(p_msc_ctx->current.req_busy_mask, req_pos);
+
+ NRF_BLOCK_DEV_REQUEST(req,
+ p_msc_ctx->current.blk_idx,
+ p_msc_ctx->current.blk_count,
+ ((uint8_t *)p_msc->specific.inst.p_block_buff +
+ p_msc_ctx->current.workbuff_pos));
+
+ NRF_LOG_DEBUG("nrf_blk_dev_read_req 3: id: %u, count: %u, left: %u, ptr: %p",
+ req.blk_id,
+ req.blk_count,
+ p_msc_ctx->current.blk_datasize,
+ (uint32_t)req.p_buff);
+
+ ret = nrf_blk_dev_read_req(p_blkd, &req);
+ NRF_LOG_DEBUG("nrf_blk_dev_read_req 3: ret: %u", ret);
+ return ret;
+ }
+
+ uint32_t blk_size = p_msc_ctx->current.blk_size;
+ p_msc_ctx->current.trans_req_id ^= 1;
+
+ nrf_block_req_t * p_req = &p_msc_ctx->current.req;
+ if (p_req->p_buff == NULL)
+ {
+ p_msc_ctx->current.trans_req_id ^= 1;
+ return NRF_SUCCESS;
+ }
+
+ ret = transfer_in_start(p_inst,
+ p_req->p_buff,
+ p_req->blk_count * blk_size,
+ APP_USBD_MSC_STATE_DATA_IN);
+
+ if (ret == NRF_SUCCESS)
+ {
+ /*Clear processed block request.*/
+ memset(p_req, 0, sizeof(nrf_block_req_t));
+ p_msc_ctx->current.trans_in_progress = true;
+ }
+
+ return ret;
+}
+
+
+/**
+ * @brief Endpoint IN event handler
+ *
+ * @param[in] p_inst Generic class instance
+ * @param[in] p_setup_ev Setup event
+ *
+ * @return Standard error code
+ * @retval NRF_SUCCESS if request handled correctly
+ * @retval NRF_ERROR_NOT_SUPPORTED if request is not supported
+ */
+static ret_code_t endpoint_in_event_handler(app_usbd_class_inst_t const * p_inst,
+ app_usbd_complex_evt_t const * p_event)
+{
+ app_usbd_msc_t const * p_msc = msc_get(p_inst);
+ app_usbd_msc_ctx_t * p_msc_ctx = msc_ctx_get(p_msc);
+
+ NRF_LOG_DEBUG("state: %d, ep in event, status: %d",
+ p_msc_ctx->state,
+ p_event->drv_evt.data.eptransfer.status);
+
+ if (p_event->drv_evt.data.eptransfer.status != NRF_USBD_EP_OK)
+ {
+ return NRF_SUCCESS;
+ }
+
+ ret_code_t ret = NRF_SUCCESS;
+
+ switch (p_msc_ctx->state)
+ {
+ case APP_USBD_MSC_STATE_CMD_IN:
+ {
+ ret = csw_wait_start(p_inst, APP_USBD_MSC_CSW_STATUS_PASS);
+ break;
+ }
+
+ case APP_USBD_MSC_STATE_DATA_IN:
+ {
+ ret = state_data_in_handle(p_inst);
+ break;
+ }
+
+ case APP_USBD_MSC_STATE_CSW:
+ {
+ break;
+ }
+
+ case APP_USBD_MSC_STATE_DATA_OUT:
+ {
+ break;
+ }
+
+ case APP_USBD_MSC_STATE_UNSUPPORTED:
+ {
+ ret = NRF_ERROR_NOT_SUPPORTED;
+ break;
+ }
+
+ default:
+ {
+ ret = NRF_ERROR_INTERNAL;
+ break;
+ }
+ }
+
+ return ret;
+}
+
+
+/**
+ * @brief Helper function to calculate next block transfer block count
+ *
+ * @param[in] p_msc MSC instance
+ * @param[in] p_msc_ctx MSC context
+ *
+ * @return Blocks to transfer
+ * */
+static uint32_t next_transfer_blkcnt_calc(app_usbd_msc_t const * p_msc,
+ app_usbd_msc_ctx_t * p_msc_ctx)
+{
+ uint32_t blkcnt = p_msc->specific.inst.block_buff_size / p_msc_ctx->current.blk_size;
+
+ if (blkcnt > (p_msc_ctx->current.blk_datasize / p_msc_ctx->current.blk_size))
+ {
+ blkcnt = p_msc_ctx->current.blk_datasize / p_msc_ctx->current.blk_size;
+ }
+
+ return blkcnt;
+}
+
+
+/**
+ * @brief Helper function to calculate next transfer size
+ *
+ * @param[in] p_msc_ctx MSC context
+ *
+ * @return Blocks to transfer
+ * */
+static uint32_t next_transfer_size_calc(app_usbd_msc_ctx_t * p_msc_ctx)
+{
+ uint32_t blk_cnt = p_msc_ctx->current.blk_count;
+ uint32_t blk_size = p_msc_ctx->current.blk_size;
+
+ return p_msc_ctx->current.blk_datasize > blk_size * blk_cnt ?
+ blk_size * blk_cnt : p_msc_ctx->current.blk_datasize;
+}
+
+
+/**
+ * @brief SCSI Command: @ref APP_USBD_SCSI_CMD_TESTUNITREADY handle
+ *
+ * @param[in] p_inst Generic class instance
+ * @param[in] p_msc MSC instance
+ * @param[in] p_msc_ctx MSC context
+ * @return Standard error code
+ * */
+static ret_code_t cmd_testunitready(app_usbd_class_inst_t const * p_inst,
+ app_usbd_msc_t const * p_msc,
+ app_usbd_msc_ctx_t * p_msc_ctx)
+{
+ NRF_LOG_DEBUG("CMD: TESTUNITREADY");
+ if (uint32_decode(p_msc_ctx->cbw.datlen) != 0)
+ {
+ return status_unsupported_start(p_inst);
+ }
+
+ if (p_msc_ctx->cbw.cdb_length != APP_USBD_SCSI_CMD_TESTUNITREADY_LEN)
+ {
+ return status_unsupported_start(p_inst);
+ }
+
+ if (p_msc_ctx->cbw.lun >= p_msc->specific.inst.block_devs_count)
+ {
+ return status_unsupported_start(p_inst);
+ }
+
+ return csw_wait_start(p_inst, APP_USBD_MSC_CSW_STATUS_PASS);
+}
+
+
+/**
+ * @brief SCSI Command: @ref APP_USBD_SCSI_CMD_REQUESTSENSE handle
+ *
+ * @param[in] p_inst Generic class instance
+ * @param[in] p_msc MSC instance
+ * @param[in] p_msc_ctx MSC context
+ * @return Standard error code
+ * */
+static ret_code_t cmd_requestsense(app_usbd_class_inst_t const * p_inst,
+ app_usbd_msc_t const * p_msc,
+ app_usbd_msc_ctx_t * p_msc_ctx)
+{
+ NRF_LOG_DEBUG("CMD: REQUESTSENSE");
+ app_usbd_scsi_cmd_requestsense_t const * p_reqs = (const void *)p_msc_ctx->cbw.cdb;
+ UNUSED_VARIABLE(p_reqs);
+
+ if ((p_msc_ctx->cbw.cdb_length < sizeof(app_usbd_scsi_cmd_requestsense_t)))
+ {
+ return status_unsupported_start(p_inst);
+ }
+
+ if (p_msc_ctx->cbw.lun >= p_msc->specific.inst.block_devs_count)
+ {
+ return status_unsupported_start(p_inst);
+ }
+
+ if (uint32_decode(p_msc_ctx->cbw.datlen) > sizeof(app_usbd_scsi_cmd_requestsense_resp_t))
+ {
+ return status_unsupported_start(p_inst);
+ }
+
+ p_msc_ctx->resp_len = uint32_decode(p_msc_ctx->cbw.datlen);
+
+ if (p_msc_ctx->resp_len == 0)
+ {
+ return csw_wait_start(p_inst, APP_USBD_MSC_CSW_STATUS_PASS);
+ }
+
+ memset(&p_msc_ctx->scsi_resp, 0, sizeof(app_usbd_scsi_cmd_requestsense_resp_t));
+ p_msc_ctx->scsi_resp.requestsense.code = APP_USBD_SCSI_CMD_REQSENSE_CODE_VALID |
+ APP_USBD_SCSI_CMD_REQSENSE_CODE_CURRENT;
+
+ p_msc_ctx->scsi_resp.requestsense.len = sizeof(app_usbd_scsi_cmd_requestsense_resp_t) -
+ offsetof(app_usbd_scsi_cmd_requestsense_resp_t, len);
+
+ return transfer_in_start(p_inst,
+ &p_msc_ctx->scsi_resp,
+ p_msc_ctx->resp_len,
+ APP_USBD_MSC_STATE_CMD_IN);
+}
+
+
+/**
+ * @brief SCSI Command: @ref APP_USBD_SCSI_CMD_FORMAT_UNIT handle
+ *
+ * @param[in] p_inst Generic class instance
+ * @param[in] p_msc MSC instance
+ * @param[in] p_msc_ctx MSC context
+ * @return Standard error code
+ * */
+static ret_code_t cmd_formatunit(app_usbd_class_inst_t const * p_inst,
+ app_usbd_msc_t const * p_msc,
+ app_usbd_msc_ctx_t * p_msc_ctx)
+{
+ NRF_LOG_DEBUG("CMD: FORMAT_UNIT");
+ return status_unsupported_start(p_inst);
+}
+
+
+static ret_code_t cmd_read_start(app_usbd_class_inst_t const * p_inst,
+ app_usbd_msc_t const * p_msc,
+ app_usbd_msc_ctx_t * p_msc_ctx)
+{
+ nrf_block_dev_t const * p_blkd = p_msc->specific.inst.pp_block_devs[p_msc_ctx->cbw.lun];
+
+ p_msc_ctx->current.trans_in_progress = false;
+ p_msc_ctx->current.req_busy_mask = 0;
+ p_msc_ctx->current.workbuff_pos = 0;
+
+ APP_USBD_MSC_REQ_BUSY_SET(p_msc_ctx->current.req_busy_mask, 0);
+ NRF_BLOCK_DEV_REQUEST(req,
+ p_msc_ctx->current.blk_idx,
+ p_msc_ctx->current.blk_count,
+ ((uint8_t *)p_msc->specific.inst.p_block_buff +
+ p_msc_ctx->current.workbuff_pos));
+
+ NRF_LOG_DEBUG("cmd_read_start");
+ NRF_LOG_DEBUG("nrf_blk_dev_read_req 1: id: %u, count: %u, left: %u, ptr: %p",
+ req.blk_id,
+ req.blk_count,
+ p_msc_ctx->current.blk_datasize,
+ (uint32_t)req.p_buff);
+
+ ret_code_t ret = nrf_blk_dev_read_req(p_blkd, &req);
+ NRF_LOG_DEBUG("nrf_blk_dev_read_req 1: ret: %u", ret);
+
+ return ret;
+}
+
+
+/**
+ * @brief SCSI Command: @ref APP_USBD_SCSI_CMD_READ6 handle
+ *
+ * @param[in] p_inst Generic class instance
+ * @param[in] p_msc MSC instance
+ * @param[in] p_msc_ctx MSC context
+ * @return Standard error code
+ * */
+static ret_code_t cmd_read6(app_usbd_class_inst_t const * p_inst,
+ app_usbd_msc_t const * p_msc,
+ app_usbd_msc_ctx_t * p_msc_ctx)
+{
+ NRF_LOG_DEBUG("CMD: READ6");
+ app_usbd_scsi_cmd_read6_t const * p_read6 = (const void *)p_msc_ctx->cbw.cdb;
+ if (p_msc_ctx->cbw.cdb_length < sizeof(app_usbd_scsi_cmd_read6_t))
+ {
+ return status_unsupported_start(p_inst);
+ }
+
+ if (p_msc_ctx->cbw.lun >= p_msc->specific.inst.block_devs_count)
+ {
+ return status_unsupported_start(p_inst);
+ }
+
+ nrf_block_dev_t const * p_blkd = p_msc->specific.inst.pp_block_devs[p_msc_ctx->cbw.lun];
+
+ p_msc_ctx->current.lun = p_msc_ctx->cbw.lun;
+ p_msc_ctx->current.blk_idx = ((p_read6->mslba & 0x1F) << 16) |
+ uint16_big_decode(p_read6->lslba);
+ p_msc_ctx->current.blk_datasize = uint32_decode(p_msc_ctx->cbw.datlen);
+ p_msc_ctx->current.blk_size = nrf_blk_dev_geometry(p_blkd)->blk_size;
+ p_msc_ctx->current.blk_count = next_transfer_blkcnt_calc(p_msc, p_msc_ctx);
+
+ if (p_msc_ctx->current.blk_datasize > p_msc_ctx->current.blk_size * p_read6->xfrlen)
+ {
+ p_msc_ctx->current.residue = p_msc_ctx->current.blk_datasize -
+ p_msc_ctx->current.blk_size * p_read6->xfrlen;
+ }
+
+ return cmd_read_start(p_inst, p_msc, p_msc_ctx);
+}
+
+
+static ret_code_t cmd_write_start(app_usbd_class_inst_t const * p_inst,
+ app_usbd_msc_t const * p_msc,
+ app_usbd_msc_ctx_t * p_msc_ctx)
+{
+ NRF_LOG_DEBUG("cmd_write_start");
+ ret_code_t ret = transfer_out_start(p_inst,
+ ((uint8_t *)p_msc->specific.inst.p_block_buff +
+ p_msc_ctx->current.workbuff_pos),
+ next_transfer_size_calc(p_msc_ctx),
+ APP_USBD_MSC_STATE_DATA_OUT);
+
+ if (ret == NRF_SUCCESS)
+ {
+ p_msc_ctx->current.trans_req_id = 0;
+ APP_USBD_MSC_REQ_BUSY_SET(p_msc_ctx->current.req_busy_mask,
+ p_msc_ctx->current.trans_req_id);
+ p_msc_ctx->current.workbuff_pos ^= p_msc->specific.inst.block_buff_size;
+ p_msc_ctx->current.trans_in_progress = true;
+ }
+
+ return ret;
+}
+
+
+/**
+ * @brief SCSI Command: @ref APP_USBD_SCSI_CMD_WRITE6 handle
+ *
+ * @param[in] p_inst Generic class instance
+ * @param[in] p_msc MSC instance
+ * @param[in] p_msc_ctx MSC context
+ * @return Standard error code
+ * */
+static ret_code_t cmd_write6(app_usbd_class_inst_t const * p_inst,
+ app_usbd_msc_t const * p_msc,
+ app_usbd_msc_ctx_t * p_msc_ctx)
+{
+ NRF_LOG_DEBUG("CMD: WRITE6");
+ app_usbd_scsi_cmd_write6_t const * p_write6 = (const void *)p_msc_ctx->cbw.cdb;
+ if (p_msc_ctx->cbw.cdb_length < sizeof(app_usbd_scsi_cmd_write6_t))
+ {
+ return status_unsupported_start(p_inst);
+ }
+
+ if (p_msc_ctx->cbw.lun >= p_msc->specific.inst.block_devs_count)
+ {
+ return status_unsupported_start(p_inst);
+ }
+
+ nrf_block_dev_t const * p_blkd = p_msc->specific.inst.pp_block_devs[p_msc_ctx->cbw.lun];
+
+ p_msc_ctx->current.lun = p_msc_ctx->cbw.lun;
+ p_msc_ctx->current.blk_idx = (p_write6->mslba & 0x1F << 16) |
+ uint16_big_decode(p_write6->lslba);
+ p_msc_ctx->current.blk_datasize = uint32_decode(p_msc_ctx->cbw.datlen);
+ p_msc_ctx->current.blk_size = nrf_blk_dev_geometry(p_blkd)->blk_size;
+ p_msc_ctx->current.blk_count = next_transfer_blkcnt_calc(p_msc, p_msc_ctx);
+
+ if (p_msc_ctx->current.blk_datasize > p_msc_ctx->current.blk_size * p_write6->xfrlen)
+ {
+ p_msc_ctx->current.residue = p_msc_ctx->current.blk_datasize -
+ p_msc_ctx->current.blk_size * p_write6->xfrlen;
+ }
+
+ return cmd_write_start(p_inst, p_msc, p_msc_ctx);
+}
+
+
+/**
+ * @brief SCSI Command: @ref APP_USBD_SCSI_CMD_INQUIRY handle
+ *
+ * @param[in] p_inst Generic class instance
+ * @param[in] p_msc MSC instance
+ * @param[in] p_msc_ctx MSC context
+ * @return Standard error code
+ * */
+static ret_code_t cmd_inquiry(app_usbd_class_inst_t const * p_inst,
+ app_usbd_msc_t const * p_msc,
+ app_usbd_msc_ctx_t * p_msc_ctx)
+{
+ NRF_LOG_DEBUG("CMD: INQUIRY");
+ app_usbd_scsi_cmd_inquiry_t const * p_inq = (const void *)p_msc_ctx->cbw.cdb;
+ if (p_inq->pagecode != 0)
+ {
+ NRF_LOG_WARNING("unsupported pagecode");
+ return status_unsupported_start(p_inst);
+ }
+
+ if (p_msc_ctx->cbw.lun >= p_msc->specific.inst.block_devs_count)
+ {
+ NRF_LOG_WARNING("unsupported LUN");
+ return status_unsupported_start(p_inst);
+ }
+
+ if (uint32_decode(p_msc_ctx->cbw.datlen) > sizeof(app_usbd_scsi_cmd_inquiry_resp_t))
+ {
+ return status_unsupported_start(p_inst);
+ }
+
+ p_msc_ctx->resp_len = uint32_decode(p_msc_ctx->cbw.datlen);
+
+ if (p_msc_ctx->resp_len == 0)
+ {
+ return csw_wait_start(p_inst, APP_USBD_MSC_CSW_STATUS_PASS);
+ }
+
+
+ p_msc_ctx->scsi_resp.inquiry.qualtype = APP_USBD_MSC_SCSI_INQ_QUAL_CONNECTED |
+ APP_USBD_MSC_SCSI_INQ_TYPE_DIR_ACCESS;
+ p_msc_ctx->scsi_resp.inquiry.flags1 = APP_USBD_MSC_SCSI_INQ_FLAG1_RMB;
+ p_msc_ctx->scsi_resp.inquiry.version = APP_USBD_SCSI_INQ_VER_SPC4;
+ p_msc_ctx->scsi_resp.inquiry.flags2 = APP_USBD_MSC_SCSI_INQ_FLAG2_RSP_SPC2 |
+ APP_USBD_MSC_SCSI_INQ_FLAG2_HISUP;
+ p_msc_ctx->scsi_resp.inquiry.len = sizeof(app_usbd_scsi_cmd_inquiry_resp_t) -
+ offsetof(app_usbd_scsi_cmd_inquiry_resp_t, len);
+
+ nrf_block_dev_t const * p_blkd =
+ p_msc->specific.inst.pp_block_devs[p_msc_ctx->cbw.lun];
+ nrf_block_dev_info_strings_t * p_strings = NULL;
+ UNUSED_RETURN_VALUE(nrf_blk_dev_ioctl(p_blkd,
+ NRF_BLOCK_DEV_IOCTL_REQ_INFO_STRINGS,
+ &p_strings));
+
+ if (p_strings)
+ {
+ UNUSED_RETURN_VALUE(strncpy((char *)p_msc_ctx->scsi_resp.inquiry.vendorid,
+ p_strings->p_vendor,
+ sizeof(p_msc_ctx->scsi_resp.inquiry.vendorid)));
+
+ UNUSED_RETURN_VALUE(strncpy((char *)p_msc_ctx->scsi_resp.inquiry.productid,
+ p_strings->p_product,
+ sizeof(p_msc_ctx->scsi_resp.inquiry.productid)));
+
+ UNUSED_RETURN_VALUE(strncpy((char *)p_msc_ctx->scsi_resp.inquiry.revision,
+ p_strings->p_revision,
+ sizeof(p_msc_ctx->scsi_resp.inquiry.revision)));
+ }
+ else
+ {
+ memset(p_msc_ctx->scsi_resp.inquiry.vendorid,
+ 0,
+ sizeof(p_msc_ctx->scsi_resp.inquiry.vendorid));
+ memset(p_msc_ctx->scsi_resp.inquiry.productid,
+ 0,
+ sizeof(p_msc_ctx->scsi_resp.inquiry.productid));
+ memset(p_msc_ctx->scsi_resp.inquiry.revision,
+ 0,
+ sizeof(p_msc_ctx->scsi_resp.inquiry.revision));
+ }
+
+ return transfer_in_start(p_inst,
+ &p_msc_ctx->scsi_resp,
+ p_msc_ctx->resp_len,
+ APP_USBD_MSC_STATE_CMD_IN);
+}
+
+
+/**
+ * @brief SCSI Command: @ref APP_USBD_SCSI_CMD_MODESELECT6 handle
+ *
+ * @param[in] p_inst Generic class instance
+ * @param[in] p_msc MSC instance
+ * @param[in] p_msc_ctx MSC context
+ * @return Standard error code
+ * */
+static ret_code_t cmd_modeselect6(app_usbd_class_inst_t const * p_inst,
+ app_usbd_msc_t const * p_msc,
+ app_usbd_msc_ctx_t * p_msc_ctx)
+{
+ NRF_LOG_DEBUG("CMD: MODESELECT6");
+ return csw_wait_start(p_inst, APP_USBD_MSC_CSW_STATUS_PASS);
+}
+
+
+/**
+ * @brief SCSI Command: @ref APP_USBD_SCSI_CMD_MODESENSE6 handle
+ *
+ * @param[in] p_inst Generic class instance
+ * @param[in] p_msc MSC instance
+ * @param[in] p_msc_ctx MSC context
+ * @return Standard error code
+ * */
+static ret_code_t cmd_modesense6(app_usbd_class_inst_t const * p_inst,
+ app_usbd_msc_t const * p_msc,
+ app_usbd_msc_ctx_t * p_msc_ctx)
+{
+ NRF_LOG_DEBUG("CMD: MODESENSE6");
+ app_usbd_scsi_cmd_modesense6_t const * p_sense6 = (const void *)p_msc_ctx->cbw.cdb;
+ UNUSED_VARIABLE(p_sense6);
+ if (p_msc_ctx->cbw.cdb_length < sizeof(app_usbd_scsi_cmd_modesense6_t))
+ {
+ return status_unsupported_start(p_inst);
+ }
+
+ if (p_msc_ctx->cbw.lun >= p_msc->specific.inst.block_devs_count)
+ {
+ return status_unsupported_start(p_inst);
+ }
+
+ if (uint32_decode(p_msc_ctx->cbw.datlen) > sizeof(app_usbd_scsi_cmd_modesense6_resp_t))
+ {
+ return status_unsupported_start(p_inst);
+ }
+
+ p_msc_ctx->resp_len = uint32_decode(p_msc_ctx->cbw.datlen);
+
+ app_usbd_scsi_cmd_modesense6_resp_t * p_resp = &p_msc_ctx->scsi_resp.modesense6;
+ p_resp->mdlen = sizeof(app_usbd_scsi_cmd_modesense6_resp_t) - 1;
+ p_resp->type = 0;
+ p_resp->param = 0;
+ p_resp->bdlen = 0;
+
+ return transfer_in_start(p_inst,
+ &p_msc_ctx->scsi_resp,
+ p_msc_ctx->resp_len,
+ APP_USBD_MSC_STATE_CMD_IN);
+}
+
+
+/**
+ * @brief SCSI Command: @ref APP_USBD_SCSI_CMD_STARTSTOPUNIT handle
+ *
+ * @param[in] p_inst Generic class instance
+ * @param[in] p_msc MSC instance
+ * @param[in] p_msc_ctx MSC context
+ * @return Standard error code
+ * */
+static ret_code_t cmd_startstopunit(app_usbd_class_inst_t const * p_inst,
+ app_usbd_msc_t const * p_msc,
+ app_usbd_msc_ctx_t * p_msc_ctx)
+{
+ NRF_LOG_DEBUG("CMD: STARTSTOPUNIT");
+ return csw_wait_start(p_inst, APP_USBD_MSC_CSW_STATUS_PASS);
+}
+
+
+/**
+ * @brief SCSI Command: @ref APP_USBD_SCSI_CMD_SENDDIAGNOSTIC handle
+ *
+ * @param[in] p_inst Generic class instance
+ * @param[in] p_msc MSC instance
+ * @param[in] p_msc_ctx MSC context
+ * @return Standard error code
+ * */
+static ret_code_t cmd_senddiagnostic(app_usbd_class_inst_t const * p_inst,
+ app_usbd_msc_t const * p_msc,
+ app_usbd_msc_ctx_t * p_msc_ctx)
+{
+ NRF_LOG_DEBUG("CMD: SENDDIAGNOSTIC");
+ return csw_wait_start(p_inst, APP_USBD_MSC_CSW_STATUS_PASS);
+}
+
+
+/**
+ * @brief SCSI Command: @ref APP_USBD_SCSI_CMD_PREVENTMEDIAREMOVAL handle
+ *
+ * @param[in] p_inst Generic class instance
+ * @param[in] p_msc MSC instance
+ * @param[in] p_msc_ctx MSC context
+ * @return Standard error code
+ * */
+static ret_code_t cmd_preventremoval(app_usbd_class_inst_t const * p_inst,
+ app_usbd_msc_t const * p_msc,
+ app_usbd_msc_ctx_t * p_msc_ctx)
+{
+ NRF_LOG_DEBUG("CMD: PREVENTMEDIAREMOVAL");
+ return csw_wait_start(p_inst, APP_USBD_MSC_CSW_STATUS_PASS);
+}
+
+
+/**
+ * @brief SCSI Command: @ref APP_USBD_SCSI_CMD_READCAPACITY10 handle
+ *
+ * @param[in] p_inst Generic class instance
+ * @param[in] p_msc MSC instance
+ * @param[in] p_msc_ctx MSC context
+ * @return Standard error code
+ * */
+static ret_code_t cmd_readcapacity10(app_usbd_class_inst_t const * p_inst,
+ app_usbd_msc_t const * p_msc,
+ app_usbd_msc_ctx_t * p_msc_ctx)
+{
+ NRF_LOG_DEBUG("CMD: READCAPACITY10");
+
+ app_usbd_scsi_cmd_readcapacity10_t const * p_cap10 = (const void *)p_msc_ctx->cbw.cdb;
+ UNUSED_VARIABLE(p_cap10);
+ if (p_msc_ctx->cbw.cdb_length < sizeof(app_usbd_scsi_cmd_readcapacity10_t))
+ {
+ return status_unsupported_start(p_inst);
+ }
+
+ if (p_msc_ctx->cbw.lun >= p_msc->specific.inst.block_devs_count)
+ {
+ return status_unsupported_start(p_inst);
+ }
+
+ if (uint32_decode(p_msc_ctx->cbw.datlen) > sizeof(app_usbd_scsi_cmd_readcapacity10_resp_t))
+ {
+ return status_unsupported_start(p_inst);
+ }
+
+ p_msc_ctx->resp_len = uint32_decode(p_msc_ctx->cbw.datlen);
+
+ if (p_msc_ctx->resp_len == 0)
+ {
+ return csw_wait_start(p_inst, APP_USBD_MSC_CSW_STATUS_PASS);
+ }
+
+ nrf_block_dev_t const * p_blkd =
+ p_msc->specific.inst.pp_block_devs[p_msc_ctx->cbw.lun];
+ nrf_block_dev_geometry_t const * p_geometry = nrf_blk_dev_geometry(p_blkd);
+
+ (void)uint32_big_encode(p_geometry->blk_count - 1, p_msc_ctx->scsi_resp.readcapacity10.lba);
+ (void)uint32_big_encode(p_geometry->blk_size, p_msc_ctx->scsi_resp.readcapacity10.blklen);
+
+ return transfer_in_start(p_inst,
+ &p_msc_ctx->scsi_resp,
+ p_msc_ctx->resp_len,
+ APP_USBD_MSC_STATE_CMD_IN);
+}
+
+
+/**
+ * @brief SCSI Command: @ref APP_USBD_SCSI_CMD_READ10 handle
+ *
+ * @param[in] p_inst Generic class instance
+ * @param[in] p_msc MSC instance
+ * @param[in] p_msc_ctx MSC context
+ * @return Standard error code
+ * */
+static ret_code_t cmd_read10(app_usbd_class_inst_t const * p_inst,
+ app_usbd_msc_t const * p_msc,
+ app_usbd_msc_ctx_t * p_msc_ctx)
+{
+ NRF_LOG_DEBUG("CMD: READ10");
+ app_usbd_scsi_cmd_read10_t const * p_read10 = (const void *)p_msc_ctx->cbw.cdb;
+ if (p_msc_ctx->cbw.cdb_length < sizeof(app_usbd_scsi_cmd_read10_t))
+ {
+ return status_unsupported_start(p_inst);
+ }
+
+ if (p_msc_ctx->cbw.lun >= p_msc->specific.inst.block_devs_count)
+ {
+ return status_unsupported_start(p_inst);
+ }
+
+ if (uint32_decode(p_msc_ctx->cbw.datlen) == 0)
+ {
+ return csw_wait_start(p_inst, APP_USBD_MSC_CSW_STATUS_FAIL);
+ }
+
+ if ((p_msc_ctx->cbw.flags & APP_USBD_MSC_CBW_DIRECTION_IN) == 0)
+ {
+ return status_unsupported_start(p_inst);
+ }
+
+ nrf_block_dev_t const * p_blkd = p_msc->specific.inst.pp_block_devs[p_msc_ctx->cbw.lun];
+
+ p_msc_ctx->current.lun = p_msc_ctx->cbw.lun;
+ p_msc_ctx->current.blk_idx = uint32_big_decode(p_read10->lba);
+ p_msc_ctx->current.blk_datasize = uint32_decode(p_msc_ctx->cbw.datlen);
+ p_msc_ctx->current.blk_size = nrf_blk_dev_geometry(p_blkd)->blk_size;
+ p_msc_ctx->current.blk_count = next_transfer_blkcnt_calc(p_msc, p_msc_ctx);
+
+ uint16_t blocks = uint16_big_decode(p_read10->xfrlen);
+ p_msc_ctx->current.csw_status =
+ uint32_decode(p_msc_ctx->cbw.datlen) < p_msc_ctx->current.blk_size * blocks ?
+ APP_USBD_MSC_CSW_STATUS_FAIL : APP_USBD_MSC_CSW_STATUS_PASS;
+
+ if (p_msc_ctx->current.blk_datasize > p_msc_ctx->current.blk_size * blocks)
+ {
+ p_msc_ctx->current.residue = p_msc_ctx->current.blk_datasize -
+ p_msc_ctx->current.blk_size * blocks;
+ }
+
+ return cmd_read_start(p_inst, p_msc, p_msc_ctx);
+}
+
+
+/**
+ * @brief SCSI Command: @ref APP_USBD_SCSI_CMD_WRITE10 handle
+ *
+ * @param[in] p_inst Generic class instance
+ * @param[in] p_msc MSC instance
+ * @param[in] p_msc_ctx MSC context
+ * @return Standard error code
+ * */
+static ret_code_t cmd_write10(app_usbd_class_inst_t const * p_inst,
+ app_usbd_msc_t const * p_msc,
+ app_usbd_msc_ctx_t * p_msc_ctx)
+{
+ NRF_LOG_DEBUG("CMD: WRITE10");
+ app_usbd_scsi_cmd_write10_t const * p_write10 = (const void *)p_msc_ctx->cbw.cdb;
+ if (p_msc_ctx->cbw.cdb_length < sizeof(app_usbd_scsi_cmd_write10_t))
+ {
+ return status_unsupported_start(p_inst);
+ }
+
+ if (p_msc_ctx->cbw.lun >= p_msc->specific.inst.block_devs_count)
+ {
+ return status_unsupported_start(p_inst);
+ }
+
+ if (uint32_decode(p_msc_ctx->cbw.datlen) == 0)
+ {
+ return csw_wait_start(p_inst, APP_USBD_MSC_CSW_STATUS_FAIL);
+ }
+
+
+ if ((p_msc_ctx->cbw.flags & APP_USBD_MSC_CBW_DIRECTION_IN) != 0)
+ {
+ return status_unsupported_start(p_inst);
+ }
+
+ nrf_block_dev_t const * p_blkd = p_msc->specific.inst.pp_block_devs[p_msc_ctx->cbw.lun];
+
+ p_msc_ctx->current.lun = p_msc_ctx->cbw.lun;
+ p_msc_ctx->current.blk_idx = uint32_big_decode(p_write10->lba);
+ p_msc_ctx->current.blk_datasize = uint32_decode(p_msc_ctx->cbw.datlen);
+ p_msc_ctx->current.blk_size = nrf_blk_dev_geometry(p_blkd)->blk_size;
+ p_msc_ctx->current.blk_count = next_transfer_blkcnt_calc(p_msc, p_msc_ctx);
+
+ uint16_t blocks = uint16_big_decode(p_write10->xfrlen);
+ p_msc_ctx->current.csw_status =
+ uint32_decode(p_msc_ctx->cbw.datlen) < p_msc_ctx->current.blk_size * blocks ?
+ APP_USBD_MSC_CSW_STATUS_FAIL : APP_USBD_MSC_CSW_STATUS_PASS;
+
+ if (p_msc_ctx->current.blk_datasize > p_msc_ctx->current.blk_size * blocks)
+ {
+ p_msc_ctx->current.residue = p_msc_ctx->current.blk_datasize -
+ p_msc_ctx->current.blk_size * blocks;
+ }
+
+ return cmd_write_start(p_inst, p_msc, p_msc_ctx);
+}
+
+
+/**
+ * @brief SCSI Command: @ref APP_USBD_SCSI_CMD_MODESELECT10 handle
+ *
+ * @param[in] p_inst Generic class instance
+ * @param[in] p_msc MSC instance
+ * @param[in] p_msc_ctx MSC context
+ * @return Standard error code
+ * */
+static ret_code_t cmd_modeselect10(app_usbd_class_inst_t const * p_inst,
+ app_usbd_msc_t const * p_msc,
+ app_usbd_msc_ctx_t * p_msc_ctx)
+{
+ NRF_LOG_DEBUG("CMD: MODESELECT10");
+ return csw_wait_start(p_inst, APP_USBD_MSC_CSW_STATUS_PASS);
+}
+
+
+/**
+ * @brief SCSI Command: @ref APP_USBD_SCSI_CMD_MODESENSE10 handle
+ *
+ * @param[in] p_inst Generic class instance
+ * @param[in] p_msc MSC instance
+ * @param[in] p_msc_ctx MSC context
+ * @return Standard error code
+ * */
+static ret_code_t cmd_modesense10(app_usbd_class_inst_t const * p_inst,
+ app_usbd_msc_t const * p_msc,
+ app_usbd_msc_ctx_t * p_msc_ctx)
+{
+ NRF_LOG_DEBUG("CMD: MODESENSE10");
+ app_usbd_scsi_cmd_modesense10_t const * p_sense10 = (const void *)p_msc_ctx->cbw.cdb;
+ UNUSED_VARIABLE(p_sense10);
+ if (p_msc_ctx->cbw.cdb_length < sizeof(app_usbd_scsi_cmd_modesense10_t))
+ {
+ return status_unsupported_start(p_inst);
+ }
+
+ if (p_msc_ctx->cbw.lun >= p_msc->specific.inst.block_devs_count)
+ {
+ return status_unsupported_start(p_inst);
+ }
+
+ if (uint32_decode(p_msc_ctx->cbw.datlen) > sizeof(app_usbd_scsi_cmd_modesense6_resp_t))
+ {
+ return status_unsupported_start(p_inst);
+ }
+
+ p_msc_ctx->resp_len = uint32_decode(p_msc_ctx->cbw.datlen);
+
+ app_usbd_scsi_cmd_modesense10_resp_t * p_resp = &p_msc_ctx->scsi_resp.modesense10;
+
+ memset(p_resp, 0, sizeof(app_usbd_scsi_cmd_modesense10_resp_t));
+ uint16_t len = sizeof(app_usbd_scsi_cmd_modesense10_resp_t) - sizeof(p_resp->mdlen);
+ p_resp->mdlen[1] = len & 0xff;
+ p_resp->mdlen[0] = (len >> 8) & 0xff;
+
+ return transfer_in_start(p_inst,
+ &p_msc_ctx->scsi_resp,
+ p_msc_ctx->resp_len,
+ APP_USBD_MSC_STATE_CMD_IN);
+}
+
+
+/**
+ * @brief Get the size of the last OUT transfer
+ *
+ * @param p_inst Generic class instance
+ *
+ * @return Number of received bytes or 0 if none.
+ */
+static size_t get_last_out_size(app_usbd_class_inst_t const * p_inst)
+{
+ nrf_drv_usbd_ep_t ep = ep_out_addr_get(p_inst);
+ size_t size;
+ ret_code_t ret = nrf_drv_usbd_ep_status_get(ep, &size);
+
+ if (ret != NRF_SUCCESS)
+ {
+ size = 0;
+ }
+
+ return size;
+}
+
+
+/**
+ * @brief SCSI Command Block Wrapper handler
+ *
+ * @param[in] p_inst Generic class instance
+ * @return Standard error code
+ * */
+static ret_code_t state_cbw(app_usbd_class_inst_t const * p_inst)
+{
+ app_usbd_msc_t const * p_msc = msc_get(p_inst);
+ app_usbd_msc_ctx_t * p_msc_ctx = msc_ctx_get(p_msc);
+
+ memset(&p_msc_ctx->current, 0, sizeof(p_msc_ctx->current));
+
+ /*Verify the transfer size*/
+ if (get_last_out_size(p_inst) != sizeof(app_usbd_msc_cbw_t))
+ {
+ NRF_LOG_DEBUG("CMD: size error: %u", get_last_out_size(p_inst));
+ status_cbwinvalid_start(p_inst);
+ return NRF_SUCCESS;
+ }
+
+ /*Verify CBW signature*/
+ if (memcmp(p_msc_ctx->cbw.signature,
+ APP_USBD_MSC_CBW_SIGNATURE,
+ sizeof(p_msc_ctx->cbw.signature)) != 0)
+ {
+ NRF_LOG_DEBUG("CMD: header error: 0x%02x%02x%02x%02x",
+ p_msc_ctx->cbw.signature[0], p_msc_ctx->cbw.signature[1],
+ p_msc_ctx->cbw.signature[2], p_msc_ctx->cbw.signature[3]);
+
+ status_cbwinvalid_start(p_inst);
+ return NRF_SUCCESS;
+ }
+
+ ret_code_t ret = NRF_SUCCESS;
+
+ switch (p_msc_ctx->cbw.cdb[0])
+ {
+ case APP_USBD_SCSI_CMD_TESTUNITREADY:
+ ret = cmd_testunitready(p_inst, p_msc, p_msc_ctx);
+ break;
+
+ case APP_USBD_SCSI_CMD_REQUESTSENSE:
+ ret = cmd_requestsense(p_inst, p_msc, p_msc_ctx);
+ break;
+
+ case APP_USBD_SCSI_CMD_FORMAT_UNIT:
+ ret = cmd_formatunit(p_inst, p_msc, p_msc_ctx);
+ break;
+
+ case APP_USBD_SCSI_CMD_READ6:
+ ret = cmd_read6(p_inst, p_msc, p_msc_ctx);
+ break;
+
+ case APP_USBD_SCSI_CMD_WRITE6:
+ ret = cmd_write6(p_inst, p_msc, p_msc_ctx);
+ break;
+
+ case APP_USBD_SCSI_CMD_INQUIRY:
+ ret = cmd_inquiry(p_inst, p_msc, p_msc_ctx);
+ break;
+
+ case APP_USBD_SCSI_CMD_MODESELECT6:
+ ret = cmd_modeselect6(p_inst, p_msc, p_msc_ctx);
+ break;
+
+ case APP_USBD_SCSI_CMD_MODESENSE6:
+ ret = cmd_modesense6(p_inst, p_msc, p_msc_ctx);
+ break;
+
+ case APP_USBD_SCSI_CMD_STARTSTOPUNIT:
+ ret = cmd_startstopunit(p_inst, p_msc, p_msc_ctx);
+ break;
+
+ case APP_USBD_SCSI_CMD_SENDDIAGNOSTIC:
+ ret = cmd_senddiagnostic(p_inst, p_msc, p_msc_ctx);
+ break;
+
+ case APP_USBD_SCSI_CMD_PREVENTMEDIAREMOVAL:
+ ret = cmd_preventremoval(p_inst, p_msc, p_msc_ctx);
+ break;
+
+ case APP_USBD_SCSI_CMD_READCAPACITY10:
+ ret = cmd_readcapacity10(p_inst, p_msc, p_msc_ctx);
+ break;
+
+ case APP_USBD_SCSI_CMD_READ10:
+ ret = cmd_read10(p_inst, p_msc, p_msc_ctx);
+ break;
+
+ case APP_USBD_SCSI_CMD_WRITE10:
+ ret = cmd_write10(p_inst, p_msc, p_msc_ctx);
+ break;
+
+ case APP_USBD_SCSI_CMD_MODESELECT10:
+ ret = cmd_modeselect10(p_inst, p_msc, p_msc_ctx);
+ break;
+
+ case APP_USBD_SCSI_CMD_MODESENSE10:
+ ret = cmd_modesense10(p_inst, p_msc, p_msc_ctx);
+ break;
+
+ default:
+ NRF_LOG_DEBUG("CMD: UNSUPPORTED");
+ NRF_LOG_HEXDUMP_DEBUG(&(p_msc_ctx->cbw), sizeof(p_msc_ctx->cbw));
+ if (uint32_decode(p_msc_ctx->cbw.datlen) != 0)
+ {
+ ret = status_unsupported_start(p_inst);
+ }
+ else
+ {
+ ret = csw_wait_start(p_inst, APP_USBD_MSC_CSW_STATUS_FAIL);
+ }
+ break;
+ }
+
+ return ret;
+}
+
+
+/**
+ * @brief Handle write6/write10 command data stage
+ *
+ * @param[in] p_inst Generic class instance
+ *
+ * @return Standard error code
+ * @retval NRF_SUCCESS if request handled correctly
+ * @retval NRF_ERROR_NOT_SUPPORTED if request is not supported
+ */
+static ret_code_t state_data_out_handle(app_usbd_class_inst_t const * p_inst)
+{
+ app_usbd_msc_t const * p_msc = msc_get(p_inst);
+ app_usbd_msc_ctx_t * p_msc_ctx = msc_ctx_get(p_msc);
+
+ ret_code_t ret = NRF_SUCCESS;
+ uint32_t blk_size = p_msc_ctx->current.blk_size;
+
+ NRF_LOG_DEBUG("APP_USBD_MSC_STATE_DATA_OUT");
+
+ p_msc_ctx->current.trans_in_progress = false;
+ if ((p_msc_ctx->current.req_busy_mask != APP_USBD_MSC_REQ_BUSY_FULL_MASK) &&
+ (p_msc_ctx->current.blk_datasize > p_msc_ctx->current.blk_count * blk_size))
+ {
+ size_t size = p_msc_ctx->current.blk_datasize - p_msc_ctx->current.blk_count * blk_size;
+ if (size > p_msc_ctx->current.blk_count * blk_size)
+ {
+ size = p_msc_ctx->current.blk_count * blk_size;
+ }
+
+ if (size)
+ {
+ ret = transfer_out_start(p_inst,
+ ((uint8_t *)p_msc->specific.inst.p_block_buff +
+ p_msc_ctx->current.workbuff_pos),
+ size,
+ APP_USBD_MSC_STATE_DATA_OUT);
+ if (ret == NRF_SUCCESS)
+ {
+ p_msc_ctx->current.trans_req_id ^= 1;
+ APP_USBD_MSC_REQ_BUSY_SET(p_msc_ctx->current.req_busy_mask,
+ p_msc_ctx->current.trans_req_id);
+ p_msc_ctx->current.workbuff_pos ^= p_msc->specific.inst.block_buff_size;
+ p_msc_ctx->current.trans_in_progress = true;
+ }
+ }
+ }
+
+ if (!p_msc_ctx->current.block_req_in_progress)
+ {
+ nrf_block_dev_t const * p_blkd =
+ p_msc->specific.inst.pp_block_devs[p_msc_ctx->current.lun];
+
+ size_t pos = p_msc_ctx->current.workbuff_pos;
+ if (p_msc_ctx->current.req_busy_mask != APP_USBD_MSC_REQ_BUSY_FULL_MASK)
+ {
+ pos ^= p_msc->specific.inst.block_buff_size;
+ }
+
+ NRF_BLOCK_DEV_REQUEST(req,
+ p_msc_ctx->current.blk_idx,
+ p_msc_ctx->current.blk_count,
+ ((uint8_t *)p_msc->specific.inst.p_block_buff + pos));
+
+ NRF_LOG_DEBUG("nrf_blk_dev_write_req 1: id: %u, count: %u, left: %u, ptr: %p",
+ req.blk_id,
+ req.blk_count,
+ p_msc_ctx->current.blk_datasize,
+ (uint32_t)req.p_buff);
+
+ p_msc_ctx->current.block_req_in_progress = true;
+ ret = nrf_blk_dev_write_req(p_blkd, &req);
+ NRF_LOG_DEBUG("nrf_blk_dev_write_req 1: ret: %u", ret);
+ }
+
+ return ret;
+}
+
+
+/**
+ * @brief Endpoint OUT event handler
+ *
+ * @param[in] p_inst Generic class instance
+ * @param[in] p_setup_ev Setup event
+ *
+ * @return Standard error code
+ * @retval NRF_SUCCESS if request handled correctly
+ * @retval NRF_ERROR_NOT_SUPPORTED if request is not supported
+ */
+static ret_code_t endpoint_out_event_handler(app_usbd_class_inst_t const * p_inst,
+ app_usbd_complex_evt_t const * p_event)
+{
+ app_usbd_msc_t const * p_msc = msc_get(p_inst);
+ app_usbd_msc_ctx_t * p_msc_ctx = msc_ctx_get(p_msc);
+
+ NRF_LOG_DEBUG("state: %d, ep out event, status: %d",
+ p_msc_ctx->state,
+ p_event->drv_evt.data.eptransfer.status);
+
+ ret_code_t ret = NRF_SUCCESS;
+ if (p_event->drv_evt.data.eptransfer.status == NRF_USBD_EP_WAITING)
+ {
+ if (p_msc_ctx->state == APP_USBD_MSC_STATE_DATA_OUT)
+ {
+ NRF_LOG_DEBUG("NRF_USBD_EP_WAITING");
+ }
+ else if (p_msc_ctx->state == APP_USBD_MSC_STATE_CSW ||
+ p_msc_ctx->state == APP_USBD_MSC_STATE_IDLE)
+ {
+ ret = cbw_wait_start(p_inst);
+ }
+
+ return ret;
+ }
+ else if (p_event->drv_evt.data.eptransfer.status == NRF_USBD_EP_ABORTED)
+ {
+ p_msc_ctx->state = APP_USBD_MSC_STATE_IDLE;
+ return NRF_SUCCESS;
+ }
+ else if (p_event->drv_evt.data.eptransfer.status == NRF_USBD_EP_OVERLOAD)
+ {
+ NRF_LOG_ERROR("Data overload");
+
+ switch (p_msc_ctx->state)
+ {
+ case APP_USBD_MSC_STATE_DATA_OUT:
+ {
+ status_deverror_start(p_inst);
+ }
+
+ /* Default action is the same like CBW - stall totally until bulk reset */
+ case APP_USBD_MSC_STATE_CBW:
+ default:
+ {
+ status_cbwinvalid_start(p_inst);
+ }
+ }
+ return NRF_SUCCESS;
+ }
+ else /*NRF_USBD_EP_OK*/
+ {
+ switch (p_msc_ctx->state)
+ {
+ case APP_USBD_MSC_STATE_CBW:
+ {
+ ret = state_cbw(p_inst);
+ break;
+ }
+
+ case APP_USBD_MSC_STATE_CMD_OUT:
+ {
+ ret = csw_wait_start(p_inst, APP_USBD_MSC_CSW_STATUS_PASS);
+ break;
+ }
+
+ case APP_USBD_MSC_STATE_DATA_OUT:
+ {
+ CRITICAL_REGION_ENTER();
+ ret = state_data_out_handle(p_inst);
+ CRITICAL_REGION_EXIT();
+ break;
+ }
+
+ case APP_USBD_MSC_STATE_UNSUPPORTED:
+ {
+ ret = NRF_ERROR_NOT_SUPPORTED;
+ break;
+ }
+
+ case APP_USBD_MSC_STATE_CSW:
+ break;
+
+ default:
+ {
+ ASSERT(0);
+ ret = NRF_ERROR_NOT_SUPPORTED;
+ break;
+ }
+ }
+ }
+
+ NRF_LOG_DEBUG("Ep proc status: %d", ret);
+ return ret;
+}
+
+
+/**
+ * @brief @ref app_usbd_class_methods_t::event_handler
+ */
+static ret_code_t msc_event_handler(app_usbd_class_inst_t const * p_inst,
+ app_usbd_complex_evt_t const * p_event)
+{
+ ASSERT(p_inst != NULL);
+ ASSERT(p_event != NULL);
+
+ app_usbd_msc_t const * p_msc = msc_get(p_inst);
+ app_usbd_msc_ctx_t * p_msc_ctx = msc_ctx_get(p_msc);
+
+ UNUSED_VARIABLE(p_msc);
+ UNUSED_VARIABLE(p_msc_ctx);
+
+ ret_code_t ret = NRF_SUCCESS;
+
+ switch (p_event->app_evt.type)
+ {
+ case APP_USBD_EVT_DRV_SOF:
+ break;
+
+ case APP_USBD_EVT_DRV_RESET:
+ break;
+
+ case APP_USBD_EVT_DRV_SETUP:
+ ret = setup_event_handler(p_inst, (app_usbd_setup_evt_t const *)p_event);
+ break;
+
+ case APP_USBD_EVT_DRV_EPTRANSFER:
+ if (NRF_USBD_EPIN_CHECK(p_event->drv_evt.data.eptransfer.ep))
+ {
+ ret = endpoint_in_event_handler(p_inst, p_event);
+ }
+ else
+ {
+ ret = endpoint_out_event_handler(p_inst, p_event);
+ }
+
+ break;
+
+ case APP_USBD_EVT_DRV_SUSPEND:
+ {
+ /*Flush all block devices cache on suspend*/
+
+ for (size_t i = 0; i < p_msc->specific.inst.block_devs_count; ++i)
+ {
+ nrf_block_dev_t const * p_blkd = p_msc->specific.inst.pp_block_devs[i];
+ (void)nrf_blk_dev_ioctl(p_blkd, NRF_BLOCK_DEV_IOCTL_REQ_CACHE_FLUSH, NULL);
+ }
+
+ break;
+ }
+
+ case APP_USBD_EVT_DRV_RESUME:
+ break;
+
+ case APP_USBD_EVT_INST_APPEND:
+ {
+ /*Verify serial number string*/
+ uint16_t const * p_serial_str = app_usbd_string_desc_get(APP_USBD_STRING_ID_SERIAL, 0);
+ if (p_serial_str == NULL)
+ {
+ return NRF_ERROR_NOT_SUPPORTED;
+ }
+
+ size_t len = app_usbd_string_desc_length(p_serial_str) / sizeof(uint16_t);
+ if (len < APP_USBD_MSC_MINIMAL_SERIAL_STRING_SIZE)
+ {
+ return NRF_ERROR_NOT_SUPPORTED;
+ }
+
+ for (size_t i = 1; i < len; ++i)
+ {
+ if (isxdigit(p_serial_str[i]) == 0)
+ {
+ return NRF_ERROR_NOT_SUPPORTED;
+ }
+ }
+
+ break;
+ }
+
+ case APP_USBD_EVT_INST_REMOVE:
+ {
+ break;
+ }
+
+ case APP_USBD_EVT_STARTED:
+ {
+ /*Initialize all block devices*/
+ ASSERT(p_msc->specific.inst.block_devs_count <= 16);
+
+ for (size_t i = 0; i < p_msc->specific.inst.block_devs_count; ++i)
+ {
+ nrf_block_dev_t const * p_blk_dev = p_msc->specific.inst.pp_block_devs[i];
+ ret = nrf_blk_dev_init(p_blk_dev, msc_blockdev_ev_handler, p_msc);
+ if (ret != NRF_SUCCESS)
+ {
+ continue;
+ }
+
+ p_msc_ctx->blk_dev_init_mask |= 1u << i;
+ ASSERT(nrf_blk_dev_geometry(p_blk_dev)->blk_size <=
+ p_msc->specific.inst.block_buff_size);
+ }
+
+ break;
+ }
+
+ case APP_USBD_EVT_STOPPED:
+ {
+ /*Un-initialize all block devices*/
+ ASSERT(p_msc->specific.inst.block_devs_count <= 16);
+ size_t i;
+
+ for (i = 0; i < p_msc->specific.inst.block_devs_count; ++i)
+ {
+ nrf_block_dev_t const * p_blk_dev = p_msc->specific.inst.pp_block_devs[i];
+ ret = nrf_blk_dev_uninit(p_blk_dev);
+ if (ret != NRF_SUCCESS)
+ {
+ continue;
+ }
+
+ p_msc_ctx->blk_dev_init_mask &= ~(1u << i);
+ }
+
+ break;
+ }
+
+ default:
+ ret = NRF_ERROR_NOT_SUPPORTED;
+ break;
+ }
+
+ return ret;
+}
+
+
+/**
+ * @brief @ref app_usbd_class_methods_t::feed_descriptors
+ */
+
+static bool msc_feed_descriptors(app_usbd_class_descriptor_ctx_t * p_ctx,
+ app_usbd_class_inst_t const * p_inst,
+ uint8_t * p_buff,
+ size_t max_size)
+{
+ static uint8_t ifaces = 0;
+ ifaces = app_usbd_class_iface_count_get(p_inst);
+ app_usbd_msc_t const * p_msc = msc_get(p_inst);
+
+ APP_USBD_CLASS_DESCRIPTOR_BEGIN(p_ctx, p_buff, max_size);
+
+ static uint8_t i = 0;
+
+ for (i = 0; i < ifaces; i++)
+ {
+ /* INTERFACE DESCRIPTOR */
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(0x09); // bLength
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(APP_USBD_DESCRIPTOR_INTERFACE); // bDescriptorType = Interface
+
+ static app_usbd_class_iface_conf_t const * p_cur_iface = NULL;
+ p_cur_iface = app_usbd_class_iface_get(p_inst, i);
+
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(app_usbd_class_iface_number_get(p_cur_iface)); // bInterfaceNumber
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(0x00); // bAlternateSetting
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(app_usbd_class_iface_ep_count_get(p_cur_iface)); // bNumEndpoints
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(APP_USBD_MSC_CLASS); // bInterfaceClass = MSC
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(p_msc->specific.inst.subclass); // bInterfaceSubclass (Industry Standard Command Block)
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(p_msc->specific.inst.protocol); // bInterfaceProtocol
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(0x00); // iInterface
+
+
+ static uint8_t endpoints = 0;
+ endpoints = app_usbd_class_iface_ep_count_get(p_cur_iface);
+
+ static uint8_t j = 0;
+
+ for (j = 0; j < endpoints; j++)
+ {
+ // ENDPOINT DESCRIPTOR
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(0x07); // bLength
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(APP_USBD_DESCRIPTOR_ENDPOINT); // bDescriptorType = Endpoint
+
+ static app_usbd_class_ep_conf_t const * p_cur_ep = NULL;
+ p_cur_ep = app_usbd_class_iface_ep_get(p_cur_iface, j);
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(app_usbd_class_ep_address_get(p_cur_ep)); // bEndpointAddress
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(APP_USBD_DESCRIPTOR_EP_ATTR_TYPE_BULK); // bmAttributes
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(LSB_16(NRF_DRV_USBD_EPSIZE)); // wMaxPacketSize LSB
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(MSB_16(NRF_DRV_USBD_EPSIZE)); // wMaxPacketSize MSB
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(0x00); // bInterval
+ }
+
+ }
+
+ APP_USBD_CLASS_DESCRIPTOR_END();
+}
+
+const app_usbd_class_methods_t app_usbd_msc_class_methods = {
+ .event_handler = msc_event_handler,
+ .feed_descriptors = msc_feed_descriptors,
+};
+
+
+/**
+ * @brief Block device read done event handler.
+ *
+ * @ref NRF_BLOCK_DEV_EVT_BLK_READ_DONE
+ *
+ * @param p_blk_dev Block device handle
+ * @param p_event Block device event
+ *
+ * */
+static void msc_blockdev_read_done_handler(nrf_block_dev_t const * p_blk_dev,
+ nrf_block_dev_event_t const * p_event)
+{
+ ret_code_t ret;
+
+ app_usbd_class_inst_t const * p_inst = p_event->p_context;
+ app_usbd_msc_t const * p_msc = msc_get(p_inst);
+ app_usbd_msc_ctx_t * p_msc_ctx = msc_ctx_get(p_msc);
+
+ uint32_t blk_cnt = p_msc_ctx->current.blk_count;
+ uint32_t blk_size = p_msc_ctx->current.blk_size;
+
+ /*Save actual request*/
+ size_t req_pos = (p_msc_ctx->current.workbuff_pos != 0) ? 1 : 0;
+
+ p_msc_ctx->current.req = *p_event->p_blk_req;
+
+ p_msc_ctx->current.block_req_in_progress = false;
+
+ /*Decrement transfer counter*/
+ p_msc_ctx->current.blk_idx += blk_cnt;
+ if (p_msc_ctx->current.blk_datasize > blk_size * blk_cnt)
+ {
+ p_msc_ctx->current.blk_datasize -= blk_size * blk_cnt;
+ }
+ else
+ {
+ p_msc_ctx->current.blk_datasize = 0;
+ }
+
+ NRF_LOG_DEBUG("read_done_handler: p_buff: %p, size: %u data size: %u req_pos: %u",
+ (uint32_t)p_event->p_blk_req->p_buff,
+ p_event->p_blk_req->blk_count,
+ p_msc_ctx->current.blk_datasize,
+ req_pos);
+
+ /*Calculate next block request size*/
+ p_msc_ctx->current.blk_count = next_transfer_blkcnt_calc(p_msc, p_msc_ctx);
+
+ if (!p_msc_ctx->current.trans_in_progress)
+ {
+ /*Trigger new transfer.*/
+ p_msc_ctx->current.trans_req_id = req_pos;
+ nrf_block_req_t * p_req = &p_msc_ctx->current.req;
+
+ ret = transfer_in_start(p_inst,
+ p_req->p_buff,
+ p_req->blk_count * blk_size,
+ APP_USBD_MSC_STATE_DATA_IN);
+ if (ret != NRF_SUCCESS)
+ {
+ UNUSED_RETURN_VALUE(status_unsupported_start(p_inst));
+ }
+ else
+ {
+ /*Clear processed block request.*/
+ memset(p_req, 0, sizeof(nrf_block_req_t));
+ p_msc_ctx->current.trans_in_progress = true;
+ }
+
+ }
+
+ if (p_msc_ctx->current.req_busy_mask == APP_USBD_MSC_REQ_BUSY_FULL_MASK)
+ {
+ /* No need to perform next block read request. USB transfers need to catch-up
+ * block device readings */
+ return;
+ }
+
+ if (p_msc_ctx->current.blk_count == 0)
+ {
+ /*All data has been read. No need to trigger new block request.*/
+ return;
+ }
+
+ /*Trigger new block read request*/
+ p_msc_ctx->current.workbuff_pos ^= p_msc->specific.inst.block_buff_size;
+ req_pos = p_msc_ctx->current.workbuff_pos != 0 ? 1 : 0;
+
+ APP_USBD_MSC_REQ_BUSY_SET(p_msc_ctx->current.req_busy_mask, req_pos);
+
+ NRF_BLOCK_DEV_REQUEST(req,
+ p_msc_ctx->current.blk_idx,
+ p_msc_ctx->current.blk_count,
+ ((uint8_t *)p_msc->specific.inst.p_block_buff +
+ p_msc_ctx->current.workbuff_pos));
+
+
+ NRF_LOG_DEBUG("nrf_blk_dev_read_req 2: id: %u, count: %u, left: %u, ptr: %p",
+ req.blk_id,
+ req.blk_count,
+ p_msc_ctx->current.blk_datasize,
+ (uint32_t)req.p_buff);
+
+ ret = nrf_blk_dev_read_req(p_blk_dev, &req);
+ NRF_LOG_DEBUG("nrf_blk_dev_read_req 2: ret: %u", ret);
+
+ if (ret != NRF_SUCCESS)
+ {
+ UNUSED_RETURN_VALUE(status_unsupported_start(p_inst));
+ }
+}
+
+
+/**
+ * @brief Block device write done event handler.
+ *
+ * @ref NRF_BLOCK_DEV_EVT_BLK_WRITE_DONE
+ *
+ * @param p_blk_dev Block device handle
+ * @param p_event Block device event
+ *
+ * */
+static void msc_blockdev_write_done_handler(nrf_block_dev_t const * p_blk_dev,
+ nrf_block_dev_event_t const * p_event)
+{
+ app_usbd_class_inst_t const * p_inst = p_event->p_context;
+ app_usbd_msc_t const * p_msc = msc_get(p_inst);
+ app_usbd_msc_ctx_t * p_msc_ctx = msc_ctx_get(p_msc);
+
+ uint32_t blk_cnt = p_msc_ctx->current.blk_count;
+ uint32_t blk_size = p_msc_ctx->current.blk_size;
+
+ /*Save actual request*/
+ size_t req_pos = (p_event->p_blk_req->p_buff == p_msc->specific.inst.p_block_buff) ? 0 : 1;
+
+ p_msc_ctx->current.req = *p_event->p_blk_req;
+
+ APP_USBD_MSC_REQ_BUSY_CLR(p_msc_ctx->current.req_busy_mask, req_pos);
+ p_msc_ctx->current.block_req_in_progress = false;
+
+ p_msc_ctx->current.blk_idx += blk_cnt;
+
+ if (p_msc_ctx->current.blk_datasize > blk_size * blk_cnt)
+ {
+ p_msc_ctx->current.blk_datasize -= blk_size * blk_cnt;
+ }
+ else
+ {
+ p_msc_ctx->current.blk_datasize = 0;
+ }
+
+ NRF_LOG_DEBUG("write_done_handler: p_buff: %p, size: %u data size: %u req_pos: %u",
+ (uint32_t)p_event->p_blk_req->p_buff,
+ p_event->p_blk_req->blk_count,
+ p_msc_ctx->current.blk_datasize,
+ req_pos);
+
+ if (p_msc_ctx->current.blk_datasize == 0)
+ {
+ p_msc_ctx->current.blk_idx = p_msc_ctx->current.blk_size = 0;
+ UNUSED_RETURN_VALUE(csw_wait_start(p_inst, p_msc_ctx->current.csw_status));
+ return;
+ }
+
+ if (p_msc_ctx->current.blk_datasize <= p_msc_ctx->current.blk_count * blk_size)
+ {
+ size_t pos = p_msc_ctx->current.workbuff_pos;
+ if (p_msc_ctx->current.req_busy_mask != APP_USBD_MSC_REQ_BUSY_FULL_MASK)
+ {
+ pos ^= p_msc->specific.inst.block_buff_size;
+ }
+
+ NRF_BLOCK_DEV_REQUEST(req,
+ p_msc_ctx->current.blk_idx,
+ p_msc_ctx->current.blk_count,
+ ((uint8_t *)p_msc->specific.inst.p_block_buff + pos));
+
+ NRF_LOG_DEBUG("nrf_blk_dev_write_req 2: id: %u, count: %u, left: %u, ptr: %p",
+ req.blk_id,
+ req.blk_count,
+ p_msc_ctx->current.blk_datasize,
+ (uint32_t)req.p_buff);
+
+ p_msc_ctx->current.block_req_in_progress = true;
+ ret_code_t ret = nrf_blk_dev_write_req(p_blk_dev, &req);
+ NRF_LOG_DEBUG("nrf_blk_dev_write_req 2: ret: %u", ret);
+
+ if (ret != NRF_SUCCESS)
+ {
+ UNUSED_RETURN_VALUE(status_unsupported_start(p_inst));
+ }
+
+ return;
+ }
+
+ if (!p_msc_ctx->current.trans_in_progress &&
+ (p_msc_ctx->current.blk_datasize > p_msc_ctx->current.blk_count * blk_size))
+ {
+ size_t size = p_msc_ctx->current.blk_datasize - p_msc_ctx->current.blk_count * blk_size;
+ if (size > p_msc_ctx->current.blk_count * blk_size)
+ {
+ size = p_msc_ctx->current.blk_count * blk_size;
+ }
+
+ if (size > 0)
+ {
+ /*Trigger new transfer.*/
+ p_msc_ctx->current.blk_count = next_transfer_blkcnt_calc(p_msc, p_msc_ctx);
+ ret_code_t ret = transfer_out_start(p_inst,
+ ((uint8_t *)p_msc->specific.inst.p_block_buff +
+ p_msc_ctx->current.workbuff_pos),
+ size,
+ APP_USBD_MSC_STATE_DATA_OUT);
+ if (ret == NRF_SUCCESS)
+ {
+ p_msc_ctx->current.trans_req_id ^= 1;
+ APP_USBD_MSC_REQ_BUSY_SET(p_msc_ctx->current.req_busy_mask,
+ p_msc_ctx->current.trans_req_id);
+ p_msc_ctx->current.workbuff_pos ^= p_msc->specific.inst.block_buff_size;
+ p_msc_ctx->current.trans_in_progress = true;
+ }
+ else
+ {
+ UNUSED_RETURN_VALUE(status_unsupported_start(p_inst));
+ }
+ }
+ }
+}
+
+
+/**
+ * @brief Block device event handler.
+ *
+ * Mass storage block device event handler. Need to be pined to all block devices
+ * from initializer list.
+ *
+ * @param p_blk_dev Block device handle
+ * @param p_event Block device event
+ *
+ * */
+static void msc_blockdev_ev_handler(nrf_block_dev_t const * p_blk_dev,
+ nrf_block_dev_event_t const * p_event)
+{
+ switch (p_event->ev_type)
+ {
+ case NRF_BLOCK_DEV_EVT_INIT:
+ break;
+
+ case NRF_BLOCK_DEV_EVT_UNINIT:
+ break;
+
+ case NRF_BLOCK_DEV_EVT_BLK_READ_DONE:
+ CRITICAL_REGION_ENTER();
+ msc_blockdev_read_done_handler(p_blk_dev, p_event);
+ CRITICAL_REGION_EXIT();
+ break;
+
+ case NRF_BLOCK_DEV_EVT_BLK_WRITE_DONE:
+ CRITICAL_REGION_ENTER();
+ msc_blockdev_write_done_handler(p_blk_dev, p_event);
+ CRITICAL_REGION_EXIT();
+ break;
+
+ default:
+ break;
+ }
+}
+
+/** @} */
+
+bool app_usbd_msc_sync(app_usbd_msc_t const * p_msc)
+{
+ bool rc = true;
+ ret_code_t ret = NRF_SUCCESS;
+
+ for (size_t i = 0; i < p_msc->specific.inst.block_devs_count; ++i)
+ {
+ nrf_block_dev_t const * p_blkd = p_msc->specific.inst.pp_block_devs[i];
+ bool flush_in_progress = true;
+
+ ret = nrf_blk_dev_ioctl(p_blkd,
+ NRF_BLOCK_DEV_IOCTL_REQ_CACHE_FLUSH,
+ &flush_in_progress);
+
+ if ((ret != NRF_SUCCESS) || flush_in_progress)
+ {
+ rc = false;
+ }
+ }
+
+ return rc;
+}
+
+
+#endif //NRF_MODULE_ENABLED(APP_USBD_MSC)
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/usbd/class/msc/app_usbd_msc.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/usbd/class/msc/app_usbd_msc.h
new file mode 100644
index 0000000..b7fcb6a
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/usbd/class/msc/app_usbd_msc.h
@@ -0,0 +1,193 @@
+/**
+ * Copyright (c) 2016 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#ifndef APP_USBD_MSC_H__
+#define APP_USBD_MSC_H__
+
+#include <stdint.h>
+#include <stdbool.h>
+
+#include "nrf_drv_usbd.h"
+#include "nrf_block_dev.h"
+#include "app_usbd_class_base.h"
+#include "app_usbd.h"
+#include "app_usbd_core.h"
+#include "app_usbd_descriptor.h"
+
+#include "app_usbd_msc_types.h"
+#include "app_usbd_msc_desc.h"
+#include "app_usbd_msc_scsi.h"
+#include "app_usbd_msc_internal.h"
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @defgroup app_usbd_msc USB MSC class
+ * @ingroup app_usbd
+ *
+ * @brief @tagAPI52840 Module with types, definitions, and API used by the USB MSC class.
+ *
+ * @details References:
+ * - "Universal Serial Bus Mass Storage Class, Specification Overview,"
+ * Revision 1.2, USB Implementer's Forum, June 23, 2003.
+ * - "Universal Serial Bus Mass Storage Class, Bulk-Only Transport,"
+ * Revision 1.0, USB Implementer's Forum, September 31, 1999.
+ *
+ * @{
+ */
+
+#ifdef DOXYGEN
+/**
+ * @brief Mass storage class instance type
+ *
+ * @ref APP_USBD_CLASS_TYPEDEF
+ */
+typedef struct { } app_usbd_msc_t;
+#else
+/*lint -save -e10 -e26 -e123 -e505 */
+APP_USBD_CLASS_TYPEDEF(app_usbd_msc, \
+ APP_USBD_MSC_CONFIG(0, (NRF_DRV_USBD_EPIN1, NRF_DRV_USBD_EPOUT1)), \
+ APP_USBD_MSC_INSTANCE_SPECIFIC_DEC, \
+ APP_USBD_MSC_DATA_SPECIFIC_DEC \
+);
+#endif
+
+/*lint -restore*/
+
+
+/*lint -save -e407 */
+
+/**
+ * @brief Events passed to user event handler
+ *
+ * @note Example prototype of user event handler:
+ *
+ * void msc_user_ev_handler(app_usbd_class_inst_t const * p_inst,
+ * app_usbd_msc_user_event_t event);
+ */
+typedef enum app_usbd_msc_user_event_e {
+ APP_USBD_MSC_USER_EVT_NONE, /**< Dummy event to satisfy compilers. */
+} app_usbd_msc_user_event_t;
+
+/*lint -restore*/
+
+/**
+ * @brief Helper macro for defining MSC endpoints
+ *
+ * @param in_number Input endpoint number
+ * @param out_number Output endpoint number
+ * */
+#define APP_USBD_MSC_ENDPOINT_LIST(in_number, out_number) ( \
+ CONCAT_2(NRF_DRV_USBD_EPIN, in_number), \
+ CONCAT_2(NRF_DRV_USBD_EPOUT, out_number) \
+)
+
+/**
+ * @brief Global definition of app_usbd_msc_t class
+ *
+ * @param instance_name Name of global instance
+ * @param interface_number Unique interface number
+ * @param user_ev_handler User event handler (optional)
+ * @param endpoint_list Input endpoint list (@ref nrf_drv_usbd_ep_t)
+ * @param blockdev_list Block device list
+ * @param workbuffer_size Work buffer size (need to fit into all block devices from
+ * block device list)
+ *
+ * @note This macro is just simplified version of @ref APP_USBD_MSC_GLOBAL_DEF_INTERNAL
+ *
+ */
+#define APP_USBD_MSC_GLOBAL_DEF(instance_name, \
+ interface_number, \
+ user_ev_handler, \
+ endpoint_list, \
+ blockdev_list, \
+ workbuffer_size) \
+ APP_USBD_MSC_GLOBAL_DEF_INTERNAL(instance_name, \
+ interface_number, \
+ user_ev_handler, \
+ endpoint_list, \
+ blockdev_list, \
+ workbuffer_size)
+
+
+/**
+ * @@brief Helper function to get class instance from MSC
+ *
+ * @param[in] p_msc MSC instance (declared by @ref APP_USBD_MSC_GLOBAL_DEF)
+ *
+ * @return Base class instance
+ */
+static inline app_usbd_class_inst_t const *
+app_usbd_msc_class_inst_get(app_usbd_msc_t const * p_msc)
+{
+ return &p_msc->base;
+}
+
+/**
+ * @brief Helper function to get MSC from base class instance
+ *
+ * @param[in] p_inst Base class instance
+ *
+ * @return MSC class handle
+ */
+static inline app_usbd_msc_t const * app_usbd_msc_class_get(app_usbd_class_inst_t const * p_inst)
+{
+ return (app_usbd_msc_t const *)p_inst;
+}
+
+/**
+ * @brief Synchronization of all block devices pined to MSC
+ *
+ * @param[in] p_msc MSC instance (declared by @ref APP_USBD_MSC_GLOBAL_DEF)
+ *
+ * @retval true All block devices flushed data
+ * @retval false At least one block device has not flushed data
+ */
+bool app_usbd_msc_sync(app_usbd_msc_t const * p_msc);
+
+/** @} */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* APP_USBD_MSC_H__ */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/usbd/class/msc/app_usbd_msc_desc.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/usbd/class/msc/app_usbd_msc_desc.h
new file mode 100644
index 0000000..83c3916
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/usbd/class/msc/app_usbd_msc_desc.h
@@ -0,0 +1,104 @@
+/**
+ * Copyright (c) 2016 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#ifndef APP_USBD_MSC_DESC_H__
+#define APP_USBD_MSC_DESC_H__
+
+#include "app_usbd_descriptor.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @defgroup app_usbd_msc_desc USB MSC descriptors
+ * @ingroup app_usbd_msc
+ *
+ * @brief @tagAPI52840 Descriptors for the USB MSC class.
+ * @{
+ */
+
+/**
+ * @brief Initializer of interface descriptor for MSC class
+ *
+ * @param interface_number Interface number
+ * @param subclass Subclass, @ref app_usbd_msc_subclass_t
+ * @param protocol Protocol, @ref app_usbd_msc_protocol_t
+ * */
+#define APP_USBD_MSC_INTERFACE_DSC(interface_number, subclass, protocol) \
+ /*.bLength = */ sizeof(app_usbd_descriptor_iface_t), \
+ /*.bDescriptorType = */ APP_USBD_DESCRIPTOR_INTERFACE, \
+ /*.bInterfaceNumber = */ interface_number, \
+ /*.bAlternateSetting = */ 0x00, \
+ /*.bNumEndpoints = */ 2, \
+ /*.bInterfaceClass = */ APP_USBD_MSC_CLASS, \
+ /*.bInterfaceSubClass = */ subclass, \
+ /*.bInterfaceProtocol = */ protocol, \
+ /*.iInterface = 0, */ 0x00, \
+
+
+/**
+ * @brief Initializer of endpoint descriptors for MSC class
+ *
+ * @param endpoint_in IN endpoint
+ * @param endpoint_out OUT endpoint
+ * @param ep_size Endpoint size
+ * */
+#define APP_USBD_MSC_EP_DSC(endpoint_in, endpoint_out, ep_size) \
+ /*.bLength = */ sizeof(app_usbd_descriptor_ep_t), \
+ /*.bDescriptorType = */ APP_USBD_DESCRIPTOR_ENDPOINT, \
+ /*.bEndpointAddress = */ endpoint_in, \
+ /*.bmAttributes = */ APP_USBD_DESCRIPTOR_EP_ATTR_TYPE_BULK, \
+ /*.wMaxPacketSize = */ APP_USBD_U16_TO_RAW_DSC(ep_size), \
+ /*.bInterval = */ 0, \
+ /*.bLength = */ sizeof(app_usbd_descriptor_ep_t), \
+ /*.bDescriptorType = */ APP_USBD_DESCRIPTOR_ENDPOINT, \
+ /*.bEndpointAddress = */ endpoint_out, \
+ /*.bmAttributes = */ APP_USBD_DESCRIPTOR_EP_ATTR_TYPE_BULK, \
+ /*.wMaxPacketSize = */ APP_USBD_U16_TO_RAW_DSC(ep_size), \
+ /*.bInterval = */ 0, \
+
+
+/** @} */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* APP_USBD_MSC_DESC_H__ */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/usbd/class/msc/app_usbd_msc_internal.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/usbd/class/msc/app_usbd_msc_internal.h
new file mode 100644
index 0000000..c7036fa
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/usbd/class/msc/app_usbd_msc_internal.h
@@ -0,0 +1,259 @@
+/**
+ * Copyright (c) 2016 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#ifndef APP_USBD_MSC_INTERNAL_H__
+#define APP_USBD_MSC_INTERNAL_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @defgroup app_usbd_msc_internals USB MSC internals
+ * @ingroup app_usbd_msc
+ *
+ * @brief @tagAPI52840 Internals of the USB MSC class.
+ * @{
+ */
+
+/**
+ * @brief Minimal serial string descriptor length
+ * */
+#define APP_USBD_MSC_MINIMAL_SERIAL_STRING_SIZE (12 + 1)
+
+/**
+ * @brief Forward declaration of Mass Storage Class type
+ *
+ */
+APP_USBD_CLASS_FORWARD(app_usbd_msc);
+
+/*lint -save -e165*/
+/**
+ * @brief Forward declaration of @ref app_usbd_msc_user_event_e
+ *
+ */
+enum app_usbd_msc_user_event_e;
+
+/*lint -restore*/
+
+/**
+ * @brief User event handler
+ *
+ * @param[in] p_inst Class instance
+ * @param[in] event User event
+ *
+ * */
+typedef void (*app_usbd_msc_user_ev_handler_t)(app_usbd_class_inst_t const * p_inst,
+ enum app_usbd_msc_user_event_e event);
+
+/**
+ * @brief MSC part of class instance data
+ */
+typedef struct {
+ void * p_block_buff; //!< Block buffer
+ size_t block_buff_size; //!< Block buffer size (typically 512 bytes)
+
+ nrf_block_dev_t const ** pp_block_devs; //!< Block devices list
+ size_t block_devs_count; //!< Block device list size
+
+ app_usbd_msc_user_ev_handler_t user_ev_handler; //!< User event handler
+
+ app_usbd_msc_subclass_t subclass; //!< MSC subclass
+ app_usbd_msc_protocol_t protocol; //!< MSC protocol
+} app_usbd_msc_inst_t;
+
+/**
+ * @brief Internal module state
+ */
+typedef enum {
+ APP_USBD_MSC_STATE_DISABLED, /**< Internal module state DISABLED */
+ APP_USBD_MSC_STATE_IDLE, /**< Internal module state IDLE */
+ APP_USBD_MSC_STATE_CBW, /**< Internal module state CBW */
+ APP_USBD_MSC_STATE_CMD_IN, /**< Internal module state CMD_IN */
+ APP_USBD_MSC_STATE_CMD_OUT, /**< Internal module state CMD_OUT */
+ APP_USBD_MSC_STATE_DATA_IN, /**< Internal module state DATA_IN */
+ APP_USBD_MSC_STATE_DATA_OUT, /**< Internal module state DATA_OUT */
+ APP_USBD_MSC_STATE_DATA_OUT_WAIT, /**< Internal module state DATA_OUT_WAIT */
+ APP_USBD_MSC_STATE_CSW, /**< Internal module state CSW */
+ APP_USBD_MSC_STATE_UNSUPPORTED, /**< Internal module state UNSUPPORTED */
+ APP_USBD_MSC_STATE_CBW_INVALID, /**< Endpoint is stalled until
+ * the command @ref APP_USBD_MSC_REQ_BULK_RESET */
+ APP_USBD_MSC_STATE_DEVICE_ERROR, /**< Endpoint is stalled and it is required
+ * to send PE error when clearing */
+} app_usbd_msc_state_t;
+
+/**
+ * @brief MSC context
+ *
+ * */
+typedef struct {
+ app_usbd_msc_cbw_t cbw; //!< SCSI command block wrapper
+ app_usbd_msc_csw_t csw; //!< SCSI Command status wrapper
+
+ app_usbd_msc_state_t state; //!< Internal module state
+
+ struct {
+ uint8_t lun; //!< Current transfer blocks: logical unit
+ uint8_t csw_status; //!< Current CSW status
+ uint32_t blk_idx; //!< Current transfer: block index
+ uint32_t blk_datasize; //!< Current transfer: data size to transfer
+ uint32_t blk_size; //!< Current transfer: block size
+ uint32_t blk_count; //!< Current transfer: block count
+ uint32_t residue; //!< @ref app_usbd_msc_csw_t::residue
+
+ bool trans_in_progress; //!< Transfer in progress flag
+ bool block_req_in_progress; //!< Block request in progress flag
+ size_t workbuff_pos; //!< Current buffer offset (double buffering mode)
+ uint8_t req_busy_mask; //!< Request bust mask (double buffering mode)
+ uint8_t trans_req_id; //!< Current transfered request (double buffering mode)
+
+ nrf_block_req_t req; //!< Last processed block req (double buffering mode)
+ } current;
+
+ size_t resp_len; //!< Response length
+
+ /*SCSI response container*/
+ union {
+ app_usbd_scsi_cmd_inquiry_resp_t inquiry; //!< @ref APP_USBD_SCSI_CMD_INQUIRY response
+ app_usbd_scsi_cmd_requestsense_resp_t requestsense; //!< @ref APP_USBD_SCSI_CMD_REQUESTSENSE response
+ app_usbd_scsi_cmd_readcapacity10_resp_t readcapacity10; //!< @ref APP_USBD_SCSI_CMD_READCAPACITY10 response
+ app_usbd_scsi_cmd_modesense6_resp_t modesense6; //!< @ref APP_USBD_SCSI_CMD_MODESENSE6 response
+ app_usbd_scsi_cmd_modesense10_resp_t modesense10; //!< @ref APP_USBD_SCSI_CMD_MODESENSE10 response
+ } scsi_resp;
+
+ uint16_t blk_dev_init_mask; //!< Block devices init mask
+} app_usbd_msc_ctx_t;
+
+
+/**
+ * @brief MSC configuration macro
+ *
+ * Used by @ref APP_USBD_MSC_GLOBAL_DEF
+ *
+ * @param iface Interface number
+ * @param endpoints Endpoint list
+ * */
+#define APP_USBD_MSC_CONFIG(iface, endpoints) ((iface, BRACKET_EXTRACT(endpoints)))
+
+
+/**
+ * @brief Specific class constant data for MSC
+ *
+ * @ref app_usbd_msc_inst_t
+ */
+#define APP_USBD_MSC_INSTANCE_SPECIFIC_DEC app_usbd_msc_inst_t inst;
+
+/**
+ * @brief Configures MSC instance
+ *
+ * @param block_devs Block devices list
+ * @param block_buff Block buffer
+ * @param user_event_handler User event handler
+ */
+#define APP_USBD_MSC_INST_CONFIG(block_devs, block_buff, user_event_handler) \
+ .inst = { \
+ .pp_block_devs = block_devs, \
+ .block_devs_count = ARRAY_SIZE(block_devs), \
+ .p_block_buff = block_buff, \
+ .block_buff_size = sizeof(block_buff) / 2, \
+ .user_ev_handler = user_event_handler, \
+ .subclass = APP_USBD_MSC_SUBCLASS_TRANSPARENT, \
+ .protocol = APP_USBD_MSC_PROTOCOL_BULK, \
+ }
+
+/**
+ * @brief Specific class data for MSC
+ *
+ * @ref app_usbd_msc_ctx_t
+ * */
+#define APP_USBD_MSC_DATA_SPECIFIC_DEC app_usbd_msc_ctx_t ctx;
+
+
+/**
+ * @brief MSC descriptors config macro
+ *
+ * @param interface_number Interface number
+ * @param ... Extracted endpoint list
+ * */
+#define APP_USBD_MSC_DSC_CONFIG(interface_number, ...) { \
+ APP_USBD_MSC_INTERFACE_DSC(interface_number, \
+ APP_USBD_MSC_SUBCLASS_TRANSPARENT, \
+ APP_USBD_MSC_PROTOCOL_BULK) \
+ APP_USBD_MSC_EP_DSC(GET_VA_ARG_1(__VA_ARGS__), \
+ GET_VA_ARG_1(GET_ARGS_AFTER_1(__VA_ARGS__)), \
+ 64) \
+}
+
+/**
+ * @brief Public MSC class interface
+ *
+ * */
+extern const app_usbd_class_methods_t app_usbd_msc_class_methods;
+
+/**
+ * @brief Global definition of mass storage class instance
+ */
+#define APP_USBD_MSC_GLOBAL_DEF_INTERNAL(instance_name, \
+ interface_number, \
+ user_ev_handler, \
+ endpoint_list, \
+ blockdev_list, \
+ workbuffer_size) \
+ static const nrf_block_dev_t * CONCAT_2(instance_name, _blkdevs)[] = \
+ { BRACKET_EXTRACT(blockdev_list) }; \
+ static uint32_t CONCAT_2(instance_name, _block)[2 *(workbuffer_size) / sizeof(uint32_t)]; \
+ APP_USBD_CLASS_INST_GLOBAL_DEF( \
+ instance_name, \
+ app_usbd_msc, \
+ &app_usbd_msc_class_methods, \
+ APP_USBD_MSC_CONFIG(interface_number, endpoint_list), \
+ (APP_USBD_MSC_INST_CONFIG(CONCAT_2(instance_name, _blkdevs), \
+ CONCAT_2(instance_name, _block), \
+ user_ev_handler)) \
+ )
+
+
+/** @} */
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* APP_USBD_MSC_INTERNAL_H__ */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/usbd/class/msc/app_usbd_msc_scsi.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/usbd/class/msc/app_usbd_msc_scsi.h
new file mode 100644
index 0000000..8379a8c
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/usbd/class/msc/app_usbd_msc_scsi.h
@@ -0,0 +1,329 @@
+/**
+ * Copyright (c) 2016 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#ifndef APP_USBD_MSC_SCSI_H__
+#define APP_USBD_MSC_SCSI_H__
+
+#include "app_util.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @defgroup app_usbd_msc_scsi USB MSC SCSI data structures
+ * @ingroup app_usbd_msc
+ *
+ * @brief @tagAPI52840 USB MSC SCSI data structures.
+ *
+ * @details Reference specifications:
+ * - "Reduced Block Commands (Revision 10a)" American National Standard
+ * for Information Technology, August 18, 1999
+ * - "SCSI Primary Commands - 4 (SPC-4)," American National Standard
+ * for Information Technology, July 19, 2008
+ * - "SCSI Block Commands -2 (SBC-2)," American National Standard
+ * for Information Technology, November 13, 2004
+ * - NuttX source code - Real-time Operating System: http://nuttx.org/
+ * Gregory Nutt <gnutt@nuttx.org>
+ *
+ * @{
+ */
+
+/**
+ * @brief SCSI command set
+ *
+ * Mandatory (and some optional) commands required by SBC-2.
+ *
+ */
+typedef enum {
+ APP_USBD_SCSI_CMD_TESTUNITREADY = 0x00, /**< TESTUNITREADY */
+ APP_USBD_SCSI_CMD_REQUESTSENSE = 0x03, /**< REQUESTSENSE */
+ APP_USBD_SCSI_CMD_FORMAT_UNIT = 0x04, /**< FORMAT_UNIT */
+ APP_USBD_SCSI_CMD_READ6 = 0x08, /**< READ6 */
+ APP_USBD_SCSI_CMD_WRITE6 = 0x0a, /**< WRITE6 */
+ APP_USBD_SCSI_CMD_INQUIRY = 0x12, /**< INQUIRY */
+ APP_USBD_SCSI_CMD_MODESELECT6 = 0x15, /**< MODESELECT6 */
+ APP_USBD_SCSI_CMD_MODESENSE6 = 0x1a, /**< MODESENSE6 */
+ APP_USBD_SCSI_CMD_STARTSTOPUNIT = 0x1b, /**< STARTSTOPUNIT */
+ APP_USBD_SCSI_CMD_SENDDIAGNOSTIC = 0x1d, /**< SENDDIAGNOSTIC */
+ APP_USBD_SCSI_CMD_PREVENTMEDIAREMOVAL = 0x1e, /**< PREVENTMEDIAREMOVAL */
+ APP_USBD_SCSI_CMD_READCAPACITY10 = 0x25, /**< READCAPACITY10 */
+ APP_USBD_SCSI_CMD_READ10 = 0x28, /**< READ10 */
+ APP_USBD_SCSI_CMD_WRITE10 = 0x2a, /**< WRITE10 */
+ APP_USBD_SCSI_CMD_MODESELECT10 = 0x55, /**< MODESELECT10 */
+ APP_USBD_SCSI_CMD_MODESENSE10 = 0x5a, /**< MODESENSE10 */
+} app_usbd_scsi_cmd_t;
+
+
+#pragma pack(push, 1)
+
+/**
+ * @brief Payload of @ref APP_USBD_SCSI_CMD_REQUESTSENSE command
+ */
+typedef struct {
+ uint8_t opcode; //!< @ref APP_USBD_SCSI_CMD_REQUESTSENSE
+ uint8_t flags; //!< Flags
+ uint8_t reserved[2]; //!< Reserved
+ uint8_t alloclen; //!< Allocation length
+ uint8_t control; //!< Control
+} app_usbd_scsi_cmd_requestsense_t;
+
+#define APP_USBD_SCSI_CMD_REQSENSE_CODE_VALID 0x80 /**< @ref app_usbd_scsi_cmd_requestsense_resp_t::code */
+#define APP_USBD_SCSI_CMD_REQSENSE_CODE_CURRENT 0x70 /**< @ref app_usbd_scsi_cmd_requestsense_resp_t::code */
+#define APP_USBD_SCSI_CMD_REQSENSE_CODE_DEFERRED 0x71 /**< @ref app_usbd_scsi_cmd_requestsense_resp_t::code */
+#define APP_USBD_SCSI_CMD_REQSENSE_CODE_CURRENTDESC 0x72 /**< @ref app_usbd_scsi_cmd_requestsense_resp_t::code */
+#define APP_USBD_SCSI_CMD_REQSENSE_CODE_DEFERREDDESC 0x73 /**< @ref app_usbd_scsi_cmd_requestsense_resp_t::code */
+
+#define APP_USBD_SCSI_CMD_REQSENSE_FLAG_FILEMARK 0x80 /**< Bits 7 @ref app_usbd_scsi_cmd_requestsense_resp_t::flags */
+#define APP_USBD_SCSI_CMD_REQSENSE_FLAG_EOM 0x40 /**< Bits 6 @ref app_usbd_scsi_cmd_requestsense_resp_t::flags */
+#define APP_USBD_SCSI_CMD_REQSENSE_FLAG_ILI 0x20 /**< Bits 5 @ref app_usbd_scsi_cmd_requestsense_resp_t::flags */
+#define APP_USBD_SCSI_CMD_REQSENSE_FLAG_RESERVED 0x10 /**< Bits 4 @ref app_usbd_scsi_cmd_requestsense_resp_t::flags */
+
+#define APP_USBD_SCSI_CMD_REQSENSE_FLAG_NOSENSE 0x00 /**< Bits 3...0 @ref app_usbd_scsi_cmd_requestsense_resp_t::flags */
+#define APP_USBD_SCSI_CMD_REQSENSE_FLAG_RECOVEREDERROR 0x01 /**< Bits 3...0 @ref app_usbd_scsi_cmd_requestsense_resp_t::flags */
+#define APP_USBD_SCSI_CMD_REQSENSE_FLAG_NOTREADY 0x02 /**< Bits 3...0 @ref app_usbd_scsi_cmd_requestsense_resp_t::flags */
+#define APP_USBD_SCSI_CMD_REQSENSE_FLAG_MEDIUMERROR 0x03 /**< Bits 3...0 @ref app_usbd_scsi_cmd_requestsense_resp_t::flags */
+#define APP_USBD_SCSI_CMD_REQSENSE_FLAG_HARDWAREERROR 0x04 /**< Bits 3...0 @ref app_usbd_scsi_cmd_requestsense_resp_t::flags */
+#define APP_USBD_SCSI_CMD_REQSENSE_FLAG_ILLEGALREQUEST 0x05 /**< Bits 3...0 @ref app_usbd_scsi_cmd_requestsense_resp_t::flags */
+#define APP_USBD_SCSI_CMD_REQSENSE_FLAG_UNITATTENTION 0x06 /**< Bits 3...0 @ref app_usbd_scsi_cmd_requestsense_resp_t::flags */
+#define APP_USBD_SCSI_CMD_REQSENSE_FLAG_DATAPROTECT 0x07 /**< Bits 3...0 @ref app_usbd_scsi_cmd_requestsense_resp_t::flags */
+#define APP_USBD_SCSI_CMD_REQSENSE_FLAG_BLANKCHECK 0x08 /**< Bits 3...0 @ref app_usbd_scsi_cmd_requestsense_resp_t::flags */
+#define APP_USBD_SCSI_CMD_REQSENSE_FLAG_VENDORSPECIFIC 0x09 /**< Bits 3...0 @ref app_usbd_scsi_cmd_requestsense_resp_t::flags */
+#define APP_USBD_SCSI_CMD_REQSENSE_FLAG_ABORTEDCOMMAND 0x0b /**< Bits 3...0 @ref app_usbd_scsi_cmd_requestsense_resp_t::flags */
+
+
+#define APP_USBD_SCSI_CMD_TESTUNITREADY_LEN 6 /**< @ref APP_USBD_SCSI_CMD_TESTUNITREADY command length*/
+
+/**
+ * @brief Payload of @ref APP_USBD_SCSI_CMD_REQUESTSENSE response
+ */
+typedef struct {
+ uint8_t code; //!< Response code: APP_USBD_SCSI_CMD_REQSENSE_CODE_*
+ uint8_t obsolete; //!< Obsolete
+ uint8_t flags; //!< APP_USBD_SCSI_CMD_REQSENSE_FLAG_*
+ uint8_t info[4]; //!< Information
+ uint8_t len; //!< Additional length
+ uint8_t cmdinfo[4]; //!< Command-specific information
+ uint8_t code2; //!< Additional sense code
+ uint8_t qual2; //!< Additional sense code qualifier
+ uint8_t fru; //!< Field replacement unit code
+ uint8_t key[3]; //!< Sense key specific
+} app_usbd_scsi_cmd_requestsense_resp_t;
+
+/**
+ * @brief Payload of @ref APP_USBD_SCSI_CMD_INQUIRY command
+ */
+typedef struct {
+ uint8_t opcode; //!< @ref APP_USBD_SCSI_CMD_INQUIRY
+ uint8_t flags; //!< Command flags
+ uint8_t pagecode; //!< Page code
+ uint8_t alloclen[2]; //!< Allocation length
+ uint8_t control; //!< Control
+} app_usbd_scsi_cmd_inquiry_t;
+
+#define APP_USBD_MSC_SCSI_INQ_QUAL_CONNECTED 0x00 /**< Peripheral connected */
+#define APP_USBD_MSC_SCSI_INQ_QUAL_NOT_CONN 0x20 /**< Peripheral not connected */
+#define APP_USBD_MSC_SCSI_INQ_QUAL_NOT_SUPP 0x60 /**< Peripheral not supported */
+
+#define APP_USBD_MSC_SCSI_INQ_TYPE_DIR_ACCESS 0x00 /**< Direct Access (SBC) */
+#define APP_USBD_MSC_SCSI_INQ_TYPE_SEQ_ACCESS 0x01 /**< Sequential Access */
+#define APP_USBD_MSC_SCSI_INQ_TYPE_PRINTER 0x02 /**< Printer */
+#define APP_USBD_MSC_SCSI_INQ_TYPE_PROCESSOR 0x03 /**< Processor device */
+#define APP_USBD_MSC_SCSI_INQ_TYPE_WRITE_ONCE 0x04 /**< Write-once device */
+#define APP_USBD_MSC_SCSI_INQ_TYPE_CD_DVD 0x05 /**< CD/DVD device */
+#define APP_USBD_MSC_SCSI_INQ_TYPE_OPTICAL 0x07 /**< Optical Memory */
+#define APP_USBD_MSC_SCSI_INQ_TYPE_MC 0x08 /**< Medium Changer */
+#define APP_USBD_MSC_SCSI_INQ_TYPE_ARRAY 0x0c /**< Storage Array Controller */
+#define APP_USBD_MSC_SCSI_INQ_TYPE_ENCLOSURE 0x0d /**< Enclosure Services */
+#define APP_USBD_MSC_SCSI_INQ_TYPE_RBC 0x0e /**< Simplified Direct Access */
+#define APP_USBD_MSC_SCSI_INQ_TYPE_OCRW 0x0f /**< Optical card reader/writer */
+#define APP_USBD_MSC_SCSI_INQ_TYPE_BCC 0x10 /**< Bridge Controller Commands */
+#define APP_USBD_MSC_SCSI_INQ_TYPE_OSD 0x11 /**< Object-based Storage */
+#define APP_USBD_MSC_SCSI_INQ_TYPE_NONE 0x1f /**< No Peripheral */
+
+
+#define APP_USBD_MSC_SCSI_INQ_FLAG1_RMB 0x80 /**< Removable Medium */
+
+#define APP_USBD_SCSI_INQ_VER_NONE 0x00 /**< No standards conformance */
+#define APP_USBD_SCSI_INQ_VER_SPC 0x03 /**< SCSI Primary Commands (link to SBC) */
+#define APP_USBD_SCSI_INQ_VER_SPC2 0x04 /**< SCSI Primary Commands - 2 (link to SBC-2)*/
+#define APP_USBD_SCSI_INQ_VER_SPC3 0x05 /**< SCSI Primary Commands - 3 (link to SBC-2)*/
+#define APP_USBD_SCSI_INQ_VER_SPC4 0x06 /**< SCSI Primary Commands - 4 (link to SBC-3)*/
+
+#define APP_USBD_MSC_SCSI_INQ_FLAG2_NORMACA 0x20 /**< Normal ACA Supported */
+#define APP_USBD_MSC_SCSI_INQ_FLAG2_HISUP 0x10 /**< Hierarchal LUN addressing */
+#define APP_USBD_MSC_SCSI_INQ_FLAG2_RSP_SPC2 0x02 /**< SPC-2 / SPC-3 response format*/
+/**
+ * @brief Payload of @ref APP_USBD_SCSI_CMD_INQUIRY response
+ */
+typedef struct {
+ uint8_t qualtype; //!< Bits 5-7: Peripheral qualifier; Bits 0-4: Peripheral device type
+ uint8_t flags1; //!< Flags 1
+ uint8_t version; //!< Version
+ uint8_t flags2; //!< Flags 2
+ uint8_t len; //!< Additional length
+ uint8_t flags3; //!< Flags 3
+ uint8_t flags4; //!< Flags 4
+ uint8_t flags5; //!< Flags 5
+ uint8_t vendorid[8]; //!< T10 Vendor Identification
+ uint8_t productid[16]; //!< Product Identification
+ uint8_t revision[4]; //!< Product Revision Level
+} app_usbd_scsi_cmd_inquiry_resp_t;
+
+/**
+ * @brief Payload of @ref APP_USBD_SCSI_CMD_READ6 command
+ */
+typedef struct {
+ uint8_t opcode; //!< @ref APP_USBD_SCSI_CMD_READ6
+ uint8_t mslba; //!< Bits 5-7: reserved; Bits 0-6: MS Logical Block Address (LBA)
+ uint8_t lslba[2]; //!< LS Logical Block Address (LBA)
+ uint8_t xfrlen; //!< Transfer length (in contiguous logical blocks)
+ uint8_t control; //!< Control
+} app_usbd_scsi_cmd_read6_t;
+
+/**
+ * @brief Payload of @ref APP_USBD_SCSI_CMD_WRITE6 command
+ */
+typedef struct {
+ uint8_t opcode; //!< @ref APP_USBD_SCSI_CMD_WRITE6
+ uint8_t mslba; //!< Bits 5-7: reserved; Bits 0-6: MS Logical Block Address (LBA)
+ uint8_t lslba[2]; //!< LS Logical Block Address (LBA)
+ uint8_t xfrlen; //!< Transfer length (in contiguous logical blocks)
+ uint8_t control; //!< Control
+} app_usbd_scsi_cmd_write6_t;
+
+/**
+ * @brief Payload of @ref APP_USBD_SCSI_CMD_MODESENSE6 command
+ */
+typedef struct {
+ uint8_t opcode; //!<* @ref APP_USBD_SCSI_CMD_MODESENSE6
+ uint8_t flags; //!<* Flags
+ uint8_t pcpgcode; //!<* Bits 6-7: PC, bits 0-5: page code
+ uint8_t subpgcode; //!<* subpage code
+ uint8_t alloclen; //!<* Allocation length
+ uint8_t control; //!<* Control
+} app_usbd_scsi_cmd_modesense6_t;
+
+/**
+ * @brief Payload of @ref APP_USBD_SCSI_CMD_MODESENSE6 response
+ */
+typedef struct {
+ uint8_t mdlen; //!< Mode data length
+ uint8_t type; //!< Medium type
+ uint8_t param; //!< Device-specific parameter
+ uint8_t bdlen; //!< Block descriptor length
+} app_usbd_scsi_cmd_modesense6_resp_t;
+
+/**
+ * @brief Payload of @ref APP_USBD_SCSI_CMD_READCAPACITY10 command
+ */
+typedef struct {
+ uint8_t opcode; //!< @ref APP_USBD_SCSI_CMD_READCAPACITY10
+ uint8_t reserved1; //!< Reserved field
+ uint8_t lba[4]; //!< Logical block address (LBA)
+ uint8_t reserved2[2]; //!< Reserved field
+ uint8_t pmi; //!< Bits 1-7 Reserved; Bit 0: PMI
+ uint8_t control; //!< Control
+} app_usbd_scsi_cmd_readcapacity10_t;
+
+/**
+ * @brief Payload of @ref APP_USBD_SCSI_CMD_READCAPACITY10 response
+ */
+typedef struct {
+ uint8_t lba[4]; //!< Returned logical block address (LBA)
+ uint8_t blklen[4]; //!< Logical block length (in bytes)
+} app_usbd_scsi_cmd_readcapacity10_resp_t;
+
+/**
+ * @brief Payload of @ref APP_USBD_SCSI_CMD_READ10 command
+ */
+typedef struct {
+ uint8_t opcode; //!< @ref APP_USBD_SCSI_CMD_READ10
+ uint8_t flags; //!< Command flags
+ uint8_t lba[4]; //!< Logical Block Address (LBA)
+ uint8_t groupno; //!< Bits 5-7: reserved; Bits 0-6: group number
+ uint8_t xfrlen[2]; //!< Transfer length (in contiguous logical blocks)
+ uint8_t control; //!< Control
+} app_usbd_scsi_cmd_read10_t;
+
+/**
+ * @brief Payload of @ref APP_USBD_SCSI_CMD_WRITE10 command
+ */
+typedef struct {
+ uint8_t opcode; //!< @ref APP_USBD_SCSI_CMD_WRITE10
+ uint8_t flags; //!< Command flags
+ uint8_t lba[4]; //!< Logical Block Address (LBA)
+ uint8_t groupno; //!< Bits 5-7: reserved; Bits 0-6: group number
+ uint8_t xfrlen[2]; //!< Transfer length (in contiguous logical blocks)
+ uint8_t control; //!< Control
+} app_usbd_scsi_cmd_write10_t;
+
+/**
+ * @brief Payload of @ref APP_USBD_SCSI_CMD_MODESENSE10 command
+ */
+typedef struct {
+ uint8_t opcode; //!< @ref APP_USBD_SCSI_CMD_MODESENSE10
+ uint8_t flags; //!< Flags
+ uint8_t pcpgcode; //!< Bits 6-7: PC, bits 0-5: page code
+ uint8_t subpgcode; //!< Subpage code
+ uint8_t reserved[3]; //!< Reserved
+ uint8_t alloclen[2]; //!< Allocation length
+ uint8_t control; //!< Control
+} app_usbd_scsi_cmd_modesense10_t;
+
+/**
+ * @brief Payload of @ref APP_USBD_SCSI_CMD_MODESENSE10 response
+ */
+typedef struct {
+ uint8_t mdlen[2]; //!< Mode data length
+ uint8_t type; //!< Medium type
+ uint8_t param; //!< Device-specific parameter
+ uint8_t reserved[2]; //!< Reserved
+ uint8_t bdlen[2]; //!< Block descriptor length
+} app_usbd_scsi_cmd_modesense10_resp_t;
+
+#pragma pack(pop)
+
+/** @} */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* APP_USBD_MSC_SCSI_H__ */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/usbd/class/msc/app_usbd_msc_types.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/usbd/class/msc/app_usbd_msc_types.h
new file mode 100644
index 0000000..96a6431
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/usbd/class/msc/app_usbd_msc_types.h
@@ -0,0 +1,141 @@
+/**
+ * Copyright (c) 2016 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#ifndef APP_USBD_MSC_TYPES_H__
+#define APP_USBD_MSC_TYPES_H__
+
+#include "app_util.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @defgroup app_usbd_msc_types USB MSC types
+ * @ingroup app_usbd_msc
+ *
+ * @brief @tagAPI52840 Types used in the USB MSC class.
+ * @{
+ */
+
+/** @brief MSC class definition in interface descriptor
+ *
+ * @ref app_usbd_descriptor_iface_t::bInterfaceClass
+ * */
+#define APP_USBD_MSC_CLASS 0x08
+
+/**
+ * @brief MSC subclass possible value
+ */
+typedef enum {
+ APP_USBD_MSC_SUBCLASS_RBC = 0x01, /**< Reduced Block Commands */
+ APP_USBD_MSC_SUBCLASS_ATAPI = 0x02, /**< CD/DVD devices */
+ APP_USBD_MSC_SUBCLASS_QIC_157 = 0x03, /**< Tape devices */
+ APP_USBD_MSC_SUBCLASS_UFI = 0x04, /**< Floppy disk drives */
+ APP_USBD_MSC_SUBCLASS_SFF_8070I = 0x05, /**< Floppy disk drives */
+ APP_USBD_MSC_SUBCLASS_TRANSPARENT = 0x06, /**< Determined by INQUIRY */
+} app_usbd_msc_subclass_t;
+
+/**
+ * @brief MSC protocol possible value
+ *
+ * @note The USB Mass Storage Class Control/Bulk/Interrupt (CBI) Transport specification is approved
+ * for use only with full-speed floppy disk drives. CBI shall not be used in high-speed
+ * capable devices.
+ */
+typedef enum {
+ APP_USBD_MSC_PROTOCOL_CBI = 0x00, /**< Command/Bulk/Interrupt */
+ APP_USBD_MSC_PROTOCOL_CBI_ALT = 0x01, /**< W/o command completion */
+ APP_USBD_MSC_PROTOCOL_BULK = 0x50, /**< Bulk-only */
+} app_usbd_msc_protocol_t;
+
+/**
+ * @brief MSC USB requests @ref nrf_drv_usbd_setup_t::bmRequestType
+ *
+ * @note Requests are limited only to @ref APP_USBD_MSC_PROTOCOL_BULK protocol type.
+ */
+typedef enum {
+ APP_USBD_MSC_REQ_BULK_RESET = 0xFF, /**< Mass Storage Reset */
+ APP_USBD_MSC_REQ_GET_MAX_LUN = 0xFE, /**< Get Max LUN */
+} app_usbd_msc_req_t;
+
+#pragma pack(push, 1)
+
+#define APP_USBD_MSC_CBW_SIGNATURE "USBC" /**< CBW signature */
+#define APP_USBD_MSC_CBW_DIRECTION_IN (1u <<7) /**< CBW direction flag */
+
+/**
+ * @brief Command Block Wrapper (CBW)
+ */
+typedef struct {
+ uint8_t signature[4]; /**< "USBC" (hex: 0x43425355 little-endian) */
+ uint8_t tag[4]; /**< Unique command tag */
+ uint8_t datlen[4]; /**< Number of bytes that host expects to transfer */
+ uint8_t flags; /**< Bit 7: Direction=IN */
+ uint8_t lun; /**< Logical Unit Number, equals to @ref app_usbd_msc_inst_t :: block_devs_count*/
+ uint8_t cdb_length; /**< Length of cdb field */
+ uint8_t cdb[16]; /**< Command Data Block payload */
+} app_usbd_msc_cbw_t;
+
+#define APP_USBD_MSC_CSW_SIGNATURE "USBS" /**< CSW signature */
+
+#define APP_USBD_MSC_CSW_STATUS_PASS 0x00 /**< CSW status: Command Passed */
+#define APP_USBD_MSC_CSW_STATUS_FAIL 0x01 /**< CSW status: Command Failed */
+#define APP_USBD_MSC_CSW_STATUS_PE 0x02 /**< CSW status: Phase Error */
+
+/**
+ * @brief Command Status Wrapper (CSW)
+ */
+typedef struct {
+ uint8_t signature[4]; /**< "USBS" (hex: 0x53425355 little-endian) */
+ uint8_t tag[4]; /**< Unique command tag (@ref app_usbd_msc_cbw_t :: tag) */
+ uint8_t residue[4]; /**< Amount not transferred */
+ uint8_t status; /**< Status of transfer */
+} app_usbd_msc_csw_t;
+
+#pragma pack(pop)
+
+
+/** @} */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* APP_USBD_MSC_TYPES_H__ */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/usbd/class/nrf_dfu_trigger/app_usbd_nrf_dfu_trigger.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/usbd/class/nrf_dfu_trigger/app_usbd_nrf_dfu_trigger.c
new file mode 100644
index 0000000..3716ec0
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/usbd/class/nrf_dfu_trigger/app_usbd_nrf_dfu_trigger.c
@@ -0,0 +1,374 @@
+/**
+ * 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#include "sdk_common.h"
+#if NRF_MODULE_ENABLED(APP_USBD_NRF_DFU_TRIGGER)
+
+#include <string.h>
+#include <ctype.h>
+#include "app_usbd.h"
+#include "app_usbd_nrf_dfu_trigger.h"
+#include "app_usbd_string_desc.h"
+#include "nrf_gpio.h"
+
+/**
+ * @defgroup app_usbd_nrf_dfu_trigger_internal USBD Nordic DFU Trigger internals
+ * @{
+ * @ingroup app_usbd_nrf_dfu_trigger
+ * @internal
+ */
+
+#define NRF_LOG_MODULE_NAME usbd_nrf_dfu_trigger
+
+#if APP_USBD_NRF_DFU_TRIGGER_CONFIG_LOG_ENABLED
+#define NRF_LOG_LEVEL APP_USBD_NRF_DFU_TRIGGER_CONFIG_LOG_LEVEL
+#define NRF_LOG_INFO_COLOR APP_USBD_NRF_DFU_TRIGGER_CONFIG_INFO_COLOR
+#define NRF_LOG_DEBUG_COLOR APP_USBD_NRF_DFU_TRIGGER_CONFIG_DEBUG_COLOR
+#else //APP_USBD_NRF_DFU_TRIGGER_CONFIG_LOG_ENABLED
+#define NRF_LOG_LEVEL 0
+#endif //APP_USBD_NRF_DFU_TRIGGER_CONFIG_LOG_ENABLED
+#include "nrf_log.h"
+NRF_LOG_MODULE_REGISTER();
+
+/**
+ * @brief Auxiliary function to access DFU Trigger instance data
+ *
+ * @param[in] p_inst Class instance data
+ *
+ * @return DFU Trigger instance data @ref app_usbd_nrf_dfu_trigger_t
+ */
+static inline app_usbd_nrf_dfu_trigger_t const * nrf_dfu_trigger_get(app_usbd_class_inst_t const * p_inst)
+{
+ ASSERT(p_inst != NULL);
+ return (app_usbd_nrf_dfu_trigger_t const *)p_inst;
+}
+
+/**
+ * @brief Auxiliary function to access DFU Trigger context data
+ *
+ * @param[in] p_dfu DFU Trigger instance data
+ *
+ * @return DFU Trigger context data @ref app_usbd_nrf_dfu_trigger_ctx_t
+ */
+static inline app_usbd_nrf_dfu_trigger_ctx_t * nrf_dfu_trigger_ctx_get(
+ app_usbd_nrf_dfu_trigger_t const * p_dfu)
+{
+ ASSERT(p_dfu != NULL);
+ ASSERT(p_dfu->specific.p_data != NULL);
+ return &p_dfu->specific.p_data->ctx;
+}
+
+/**
+ * @brief Internal SETUP standard IN request handler
+ *
+ * @param[in] p_inst Generic class instance
+ * @param[in] p_setup_ev Setup event
+ *
+ * @return Standard error code
+ * @retval NRF_SUCCESS if request handled correctly
+ * @retval NRF_ERROR_NOT_SUPPORTED if request is not supported
+ */
+static ret_code_t setup_req_std_in(app_usbd_class_inst_t const * p_inst,
+ app_usbd_setup_evt_t const * p_setup_ev)
+{
+ /* Only Get Descriptor standard IN request is supported by DFU class */
+ if ((app_usbd_setup_req_rec(p_setup_ev->setup.bmRequestType) == APP_USBD_SETUP_REQREC_INTERFACE)
+ &&
+ (p_setup_ev->setup.bmRequest == APP_USBD_SETUP_STDREQ_GET_DESCRIPTOR))
+ {
+ size_t dsc_len = 0;
+ size_t max_size;
+
+ uint8_t * p_trans_buff = app_usbd_core_setup_transfer_buff_get(&max_size);
+ /* Try to find descriptor in class internals*/
+ ret_code_t ret = app_usbd_class_descriptor_find(p_inst,
+ p_setup_ev->setup.wValue.hb,
+ p_setup_ev->setup.wValue.lb,
+ p_trans_buff,
+ &dsc_len);
+ if (ret != NRF_ERROR_NOT_FOUND)
+ {
+ ASSERT(dsc_len < NRF_DRV_USBD_EPSIZE);
+ return app_usbd_core_setup_rsp(&(p_setup_ev->setup), p_trans_buff, dsc_len);
+ }
+ }
+ return NRF_ERROR_NOT_SUPPORTED;
+}
+
+/**
+ * @brief Internal SETUP standard OUT request handler
+ *
+ * @param[in] p_inst Generic class instance
+ * @param[in] p_setup_ev Setup event
+ *
+ * @return Standard error code
+ * @retval NRF_SUCCESS if request handled correctly
+ * @retval NRF_ERROR_NOT_SUPPORTED if request is not supported
+ * @retval NRF_ERROR_FORBIDDEN if endpoint stall cannot be cleared because of internal state
+ */
+static ret_code_t setup_req_std_out(app_usbd_class_inst_t const * p_inst,
+ app_usbd_setup_evt_t const * p_setup_ev)
+{
+
+ switch (p_setup_ev->setup.bmRequest)
+ {
+ default:
+ break;
+ }
+ return NRF_ERROR_NOT_SUPPORTED;
+}
+
+/**
+ * @brief User event handler.
+ *
+ * @param[in] p_inst Class instance.
+ * @param[in] event user Event type.
+ */
+static inline void user_event_handler(app_usbd_class_inst_t const * p_inst,
+ app_usbd_nrf_dfu_trigger_user_event_t event)
+{
+ app_usbd_nrf_dfu_trigger_t const * p_dfu = nrf_dfu_trigger_get(p_inst);
+ if (p_dfu->specific.inst.user_ev_handler != NULL)
+ {
+ p_dfu->specific.inst.user_ev_handler(p_inst, event);
+ }
+}
+
+/**
+ * @brief Internal SETUP class IN request handler
+ *
+ * @param[in] p_inst Generic class instance
+ * @param[in] p_setup_ev Setup event
+ *
+ * @return Standard error code
+ * @retval NRF_SUCCESS if request handled correctly
+ * @retval NRF_ERROR_NOT_SUPPORTED if request is not supported
+ */
+static ret_code_t setup_req_class_in(app_usbd_class_inst_t const * p_inst,
+ app_usbd_setup_evt_t const * p_setup_ev)
+{
+ app_usbd_nrf_dfu_trigger_t const * p_dfu = nrf_dfu_trigger_get(p_inst);
+
+ switch (p_setup_ev->setup.bmRequest)
+ {
+ case APP_USBD_NRF_DFU_TRIGGER_REQ_NORDIC_INFO:
+ if (p_setup_ev->setup.wLength.w != sizeof(app_usbd_nrf_dfu_trigger_nordic_info_t))
+ {
+ return NRF_ERROR_NOT_SUPPORTED;
+ }
+ return app_usbd_core_setup_rsp(&p_setup_ev->setup,
+ p_dfu->specific.inst.p_dfu_info,
+ sizeof(app_usbd_nrf_dfu_trigger_nordic_info_t));
+
+ case APP_USBD_NRF_DFU_TRIGGER_REQ_SEM_VER:
+ return app_usbd_core_setup_rsp(&p_setup_ev->setup,
+ p_dfu->specific.inst.p_sem_ver,
+ p_dfu->specific.inst.sem_ver_size);
+
+ default:
+ break;
+ }
+
+ return NRF_ERROR_NOT_SUPPORTED;
+}
+
+/**
+ * @brief Internal SETUP class OUT request handler
+ *
+ * @param[in] p_inst Generic class instance
+ * @param[in] p_setup_ev Setup event
+ *
+ * @return Standard error code
+ * @retval NRF_SUCCESS if request handled correctly
+ * @retval NRF_ERROR_NOT_SUPPORTED if request is not supported
+ */
+static ret_code_t setup_req_class_out(app_usbd_class_inst_t const * p_inst,
+ app_usbd_setup_evt_t const * p_setup_ev)
+{
+ app_usbd_nrf_dfu_trigger_t const * p_dfu = nrf_dfu_trigger_get(p_inst);
+ app_usbd_nrf_dfu_trigger_ctx_t * p_dfu_ctx = nrf_dfu_trigger_ctx_get(p_dfu);
+
+ switch (p_setup_ev->setup.bmRequest)
+ {
+ case APP_USBD_NRF_DFU_TRIGGER_REQ_DETACH:
+ {
+ NRF_LOG_DEBUG("Entering DFU Mode");
+ p_dfu_ctx->state = APP_USBD_NRF_DFU_TRIGGER_STATE_DETACH;
+ user_event_handler(p_inst, APP_USBD_NRF_DFU_TRIGGER_USER_EVT_DETACH);
+ return NRF_SUCCESS;
+ }
+ default:
+ break;
+ }
+
+ return NRF_ERROR_NOT_SUPPORTED;
+}
+
+/**
+ * @brief Control endpoint handle
+ *
+ * @param[in] p_inst Generic class instance
+ * @param[in] p_setup_ev Setup event
+ *
+ * @return Standard error code
+ * @retval NRF_SUCCESS if request handled correctly
+ * @retval NRF_ERROR_NOT_SUPPORTED if request is not supported
+ */
+static ret_code_t setup_event_handler(app_usbd_class_inst_t const * p_inst,
+ app_usbd_setup_evt_t const * p_setup_ev)
+{
+ ASSERT(p_inst != NULL);
+ ASSERT(p_setup_ev != NULL);
+
+ if (app_usbd_setup_req_dir(p_setup_ev->setup.bmRequestType) == APP_USBD_SETUP_REQDIR_IN)
+ {
+ switch (app_usbd_setup_req_typ(p_setup_ev->setup.bmRequestType))
+ {
+ case APP_USBD_SETUP_REQTYPE_STD:
+ return setup_req_std_in(p_inst, p_setup_ev);
+ case APP_USBD_SETUP_REQTYPE_CLASS:
+ return setup_req_class_in(p_inst, p_setup_ev);
+ default:
+ break;
+ }
+ }
+ else /* APP_USBD_SETUP_REQDIR_OUT */
+ {
+ switch (app_usbd_setup_req_typ(p_setup_ev->setup.bmRequestType))
+ {
+ case APP_USBD_SETUP_REQTYPE_STD:
+ return setup_req_std_out(p_inst, p_setup_ev);
+ case APP_USBD_SETUP_REQTYPE_CLASS:
+ return setup_req_class_out(p_inst, p_setup_ev);
+ default:
+ break;
+ }
+ }
+
+ return NRF_ERROR_NOT_SUPPORTED;
+}
+
+/**
+ * @brief @ref app_usbd_class_methods_t::event_handler
+ */
+static ret_code_t nrf_dfu_trigger_event_handler(app_usbd_class_inst_t const * p_inst,
+ app_usbd_complex_evt_t const * p_event)
+{
+ ASSERT(p_inst != NULL);
+ ASSERT(p_event != NULL);
+
+ ret_code_t ret = NRF_SUCCESS;
+ switch (p_event->app_evt.type)
+ {
+ case APP_USBD_EVT_DRV_SOF:
+ break;
+ case APP_USBD_EVT_DRV_RESET:
+ break;
+ case APP_USBD_EVT_DRV_SETUP:
+ ret = setup_event_handler(p_inst, (app_usbd_setup_evt_t const *) p_event);
+ break;
+ case APP_USBD_EVT_DRV_EPTRANSFER:
+ break;
+ case APP_USBD_EVT_DRV_SUSPEND:
+ break;
+ case APP_USBD_EVT_DRV_RESUME:
+ break;
+ case APP_USBD_EVT_INST_APPEND:
+ break;
+ case APP_USBD_EVT_INST_REMOVE:
+ break;
+ case APP_USBD_EVT_STARTED:
+ break;
+ case APP_USBD_EVT_STOPPED:
+ break;
+ default:
+ ret = NRF_ERROR_NOT_SUPPORTED;
+ break;
+ }
+
+ return ret;
+}
+
+/**
+ * @brief @ref app_usbd_class_methods_t::feed_descriptors
+ */
+static bool nrf_dfu_trigger_feed_descriptors(app_usbd_class_descriptor_ctx_t * p_ctx,
+ app_usbd_class_inst_t const * p_inst,
+ uint8_t * p_buff,
+ size_t max_size)
+{
+ static app_usbd_class_iface_conf_t const * p_cur_iface = NULL;
+ p_cur_iface = app_usbd_class_iface_get(p_inst, 0);
+ app_usbd_nrf_dfu_trigger_t const * p_dfu = nrf_dfu_trigger_get(p_inst);
+
+ APP_USBD_CLASS_DESCRIPTOR_BEGIN(p_ctx, p_buff, max_size)
+
+ /* INTERFACE DESCRIPTOR */
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(sizeof(app_usbd_descriptor_iface_t)); // bLength
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(APP_USBD_DESCRIPTOR_INTERFACE); // bDescriptorType
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(app_usbd_class_iface_number_get(p_cur_iface)); // bInterfaceNumber
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(0x00); // bAlternateSetting
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(0); // bNumEndpoints
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(APP_USBD_NRF_DFU_TRIGGER_CLASS); // bInterfaceClass
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(APP_USBD_NRF_DFU_TRIGGER_SUBCLASS); // bInterfaceSubClass
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(APP_USBD_NRF_DFU_TRIGGER_PROTOCOL_RUNTIME); // bInterfaceProtocol
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(0x00); // iInterface
+
+ /* FUNCTIONAL DESCRIPTOR */
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(sizeof(app_usbd_nrf_dfu_trigger_desc_func_t)); // bFunctionLength
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(APP_USBD_NRF_DFU_TRIGGER_CS_FUNCTIONAL); // bDescriptorType
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(APP_USBD_NRF_DFU_TRIGGER_BIT_CAN_DNLOAD |
+ APP_USBD_NRF_DFU_TRIGGER_BIT_WILL_DETACH); // bmAttribute
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(LSB_16(p_dfu->specific.inst.detach_timeout)); // wDetachTimeOut LSB
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(MSB_16(p_dfu->specific.inst.detach_timeout)); // wDetachTimeOut MSB
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(LSB_16(p_dfu->specific.inst.transfer_size)); // wTransferSize LSB
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(MSB_16(p_dfu->specific.inst.transfer_size)); // wTransferSize MSB
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(LSB_16(p_dfu->specific.inst.bcd_dfu)); // bcdDFUVersion LSB
+ APP_USBD_CLASS_DESCRIPTOR_WRITE(MSB_16(p_dfu->specific.inst.bcd_dfu)); // bcdDFUVersion MSB
+
+ APP_USBD_CLASS_DESCRIPTOR_END();
+}
+
+const app_usbd_class_methods_t app_usbd_nrf_dfu_trigger_class_methods = {
+ .event_handler = nrf_dfu_trigger_event_handler,
+ .feed_descriptors = nrf_dfu_trigger_feed_descriptors,
+};
+
+
+#endif //NRF_MODULE_ENABLED(APP_USBD_NRF_DFU_TRIGGER)
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/usbd/class/nrf_dfu_trigger/app_usbd_nrf_dfu_trigger.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/usbd/class/nrf_dfu_trigger/app_usbd_nrf_dfu_trigger.h
new file mode 100644
index 0000000..b15ea96
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/usbd/class/nrf_dfu_trigger/app_usbd_nrf_dfu_trigger.h
@@ -0,0 +1,166 @@
+/**
+ * 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#ifndef APP_USBD_NRF_DFU_TRIGGER_H__
+#define APP_USBD_NRF_DFU_TRIGGER_H__
+
+#include <stdint.h>
+#include <stdbool.h>
+
+#include "nrf_drv_usbd.h"
+#include "nrf_block_dev.h"
+#include "app_usbd_class_base.h"
+#include "app_usbd.h"
+#include "app_usbd_core.h"
+#include "app_usbd_descriptor.h"
+
+#include "app_usbd_nrf_dfu_trigger_types.h"
+#include "app_usbd_nrf_dfu_trigger_internal.h"
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @defgroup app_usbd_nrf_dfu_trigger USB Nordic DFU Trigger class
+ * @ingroup app_usbd
+ *
+ * @brief @tagAPI52840 Module with types, definitions,
+ * and API used by the USB Nordic DFU Trigger class.
+ *
+ * @{
+ */
+
+#ifdef DOXYGEN
+/**
+ * @brief Nordic DFU Trigger class instance type
+ *
+ * @ref APP_USBD_CLASS_TYPEDEF
+ */
+typedef struct { } app_usbd_nrf_dfu_trigger_t;
+#else
+/*lint -save -e10 -e26 -e123 -e505 */
+APP_USBD_CLASS_NO_EP_TYPEDEF(app_usbd_nrf_dfu_trigger, \
+ APP_USBD_NRF_DFU_TRIGGER_CONFIG(0), \
+ APP_USBD_NRF_DFU_TRIGGER_INSTANCE_SPECIFIC_DEC, \
+ APP_USBD_NRF_DFU_TRIGGER_DATA_SPECIFIC_DEC \
+);
+#endif
+
+/*lint -restore*/
+
+
+/*lint -save -e407 */
+
+/**
+ * @brief Events passed to user event handler
+ *
+ * @note Example prototype of user event handler:
+ *
+ * void dfu_user_ev_handler(app_usbd_class_inst_t const * p_inst,
+ * app_usbd_nrf_dfu_trigger_user_event_t event);
+ */
+typedef enum app_usbd_nrf_dfu_trigger_user_event_e {
+ APP_USBD_NRF_DFU_TRIGGER_USER_EVT_DETACH,
+} app_usbd_nrf_dfu_trigger_user_event_t;
+
+/*lint -restore*/
+
+/**
+ * @brief Global definition of app_usbd_nrf_dfu_trigger_t class
+ *
+ * @param instance_name Name of global instance
+ * @param interface_number Unique interface number
+ * @param p_nordic_dfu Pointer to @ref app_usbd_nrf_dfu_trigger_nordic_info_t structure
+ * @param sem_ver_str Semantic version string
+ * @param user_ev_handler User event handler (optional)
+ *
+ * @note This macro is just simplified version of @ref APP_USBD_NRF_DFU_TRIGGER_GLOBAL_DEF_INTERNAL
+ *
+ */
+/*lint -save -emacro(26 64 123 505 651, APP_USBD_NRF_DFU_TRIGGER_GLOBAL_DEF)*/
+#define APP_USBD_NRF_DFU_TRIGGER_GLOBAL_DEF(instance_name, \
+ interface_number, \
+ p_nordic_dfu, \
+ sem_ver_str, \
+ user_ev_handler) \
+ APP_USBD_NRF_DFU_TRIGGER_GLOBAL_DEF_INTERNAL(instance_name, \
+ interface_number, \
+ 0, \
+ 0, \
+ p_nordic_dfu, \
+ sem_ver_str, \
+ user_ev_handler)
+/*lint -restore*/
+
+/**
+ * @@brief Helper function to get class instance from Nordic DFU Trigger
+ *
+ * @param[in] p_dfu Nordic DFU Trigger instance
+ * (declared by @ref APP_USBD_NRF_DFU_TRIGGER_GLOBAL_DEF)
+ *
+ * @return Base class instance
+ */
+static inline app_usbd_class_inst_t const *
+app_usbd_nrf_dfu_trigger_class_inst_get(app_usbd_nrf_dfu_trigger_t const * p_dfu)
+{
+ return &p_dfu->base;
+}
+
+/**
+ * @brief Helper function to get DFU from base class instance
+ *
+ * @param[in] p_inst Base class instance
+ *
+ * @return DFU class handle
+ */
+static inline app_usbd_nrf_dfu_trigger_t const *
+app_usbd_nrf_dfu_trigger_class_get( app_usbd_class_inst_t const * p_inst)
+{
+ return (app_usbd_nrf_dfu_trigger_t const *)p_inst;
+}
+
+/** @} */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* APP_USBD_NRF_DFU_TRIGGER_H__ */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/usbd/class/nrf_dfu_trigger/app_usbd_nrf_dfu_trigger_internal.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/usbd/class/nrf_dfu_trigger/app_usbd_nrf_dfu_trigger_internal.h
new file mode 100644
index 0000000..9195e2a
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/usbd/class/nrf_dfu_trigger/app_usbd_nrf_dfu_trigger_internal.h
@@ -0,0 +1,203 @@
+/**
+ * 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#ifndef APP_USBD_NRF_DFU_TRIGGER_INTERNAL_H__
+#define APP_USBD_NRF_DFU_TRIGGER_INTERNAL_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @defgroup app_usbd_nrf_dfu_trigger_internals USB Nordic DFU Trigger internals
+ * @ingroup app_usbd_nrf_dfu_trigger
+ *
+ * @brief @tagAPI52840 Internals of the USB Nordic DFU Trigger class.
+ * @{
+ */
+
+/**
+ * @brief Forward declaration of Nordic DFU Trigger Class type
+ *
+ */
+APP_USBD_CLASS_FORWARD(app_usbd_nrf_dfu_trigger);
+
+/*lint -save -e165*/
+/**
+ * @brief Forward declaration of @ref app_usbd_nrf_dfu_trigger_user_event_e
+ *
+ */
+enum app_usbd_nrf_dfu_trigger_user_event_e;
+
+/*lint -restore*/
+
+/**
+ * @brief User event handler
+ *
+ * @param[in] p_inst Class instance
+ * @param[in] event User event
+ *
+ * */
+typedef void (*app_usbd_nrf_dfu_trigger_user_ev_handler_t)(
+ app_usbd_class_inst_t const * p_inst,
+ enum app_usbd_nrf_dfu_trigger_user_event_e event);
+
+/**
+ * @brief Nordic DFU Trigger part of class instance data
+ */
+typedef struct {
+ size_t const sem_ver_size; //!< Semantic string size
+ uint16_t const detach_timeout; //!< Detach timeout in ms - for compatibility with DFU spec.
+ uint16_t const transfer_size; //!< Transfer size - for compatibility with DFU spec.
+ uint16_t const bcd_dfu; //!< DFU spec version.
+ uint8_t const * p_sem_ver; //!< Pointer to semantic version string
+
+ app_usbd_nrf_dfu_trigger_nordic_info_t const * p_dfu_info; //!< Pointer to Nordic DFU Info
+
+ app_usbd_nrf_dfu_trigger_user_ev_handler_t user_ev_handler; //!< User event handler
+} app_usbd_nrf_dfu_trigger_inst_t;
+
+/**
+ * @brief Internal module state
+ *
+ * @note For future compatibility with DFU class.
+ */
+typedef enum {
+ APP_USBD_NRF_DFU_TRIGGER_STATE_IDLE, /**< Internal module state IDLE */
+ APP_USBD_NRF_DFU_TRIGGER_STATE_DETACH, /**< Internal module state DETACH */
+} app_usbd_nrf_dfu_trigger_state_t;
+
+/**
+ * @brief Nordic DFU Trigger context
+ *
+ * */
+typedef struct {
+ app_usbd_nrf_dfu_trigger_state_t state; //!< Internal module state
+} app_usbd_nrf_dfu_trigger_ctx_t;
+
+
+/**
+ * @brief Nordic DFU Trigger configuration macro
+ *
+ * Used by @ref APP_USBD_NRF_DFU_TRIGGER_GLOBAL_DEF
+ *
+ * @param iface Interface number
+ * */
+#define APP_USBD_NRF_DFU_TRIGGER_CONFIG(iface) (iface)
+
+
+/**
+ * @brief Specific class constant data for Nordic DFU Trigger
+ *
+ * @ref app_usbd_nrf_dfu_trigger_inst_t
+ */
+#define APP_USBD_NRF_DFU_TRIGGER_INSTANCE_SPECIFIC_DEC app_usbd_nrf_dfu_trigger_inst_t inst;
+
+
+/**
+ * @brief Configures Nordic DFU Trigger instance
+ *
+ * @param user_event_handler User event handler
+ * @param p_nordic_dfu Pointer to @ref app_usbd_nrf_dfu_trigger_nordic_info_t structure
+ * @param sem_ver_str Semantic version string
+ * @param timeout Detach timeout in ms - left for compatibility with USB DFU spec.
+ * @param size Transfer size in bytes - left for compatibility with USB DFU spec.
+ * @param bcd USB DFU specification version.
+ */
+#define APP_USBD_NRF_DFU_TRIGGER_INST_CONFIG(user_event_handler, \
+ p_nordic_dfu, \
+ sem_ver_str, \
+ timeout, \
+ size, \
+ bcd) \
+ .inst = { \
+ .user_ev_handler = user_event_handler, \
+ .p_dfu_info = p_nordic_dfu, \
+ .p_sem_ver = sem_ver_str, \
+ .sem_ver_size = sizeof(sem_ver_str), \
+ .transfer_size = size, \
+ .detach_timeout = timeout, \
+ .bcd_dfu = bcd, \
+ }
+
+/**
+ * @brief Specific class data for Nordic DFU Trigger
+ *
+ * @ref app_usbd_nrf_dfu_trigger_ctx_t
+ * */
+#define APP_USBD_NRF_DFU_TRIGGER_DATA_SPECIFIC_DEC app_usbd_nrf_dfu_trigger_ctx_t ctx;
+
+
+/**
+ * @brief Public Nordic DFU Trigger class interface
+ */
+extern const app_usbd_class_methods_t app_usbd_nrf_dfu_trigger_class_methods;
+
+/**
+ * @brief Global definition of Nordic DFU Trigger instance
+ */
+#define APP_USBD_NRF_DFU_TRIGGER_GLOBAL_DEF_INTERNAL(instance_name, \
+ interface_number, \
+ detach_timeout, \
+ transfer_size, \
+ p_nordic_dfu, \
+ sem_ver_str, \
+ user_ev_handler) \
+ APP_USBD_CLASS_INST_NO_EP_GLOBAL_DEF( \
+ instance_name, \
+ app_usbd_nrf_dfu_trigger, \
+ &app_usbd_nrf_dfu_trigger_class_methods, \
+ APP_USBD_NRF_DFU_TRIGGER_CONFIG((interface_number)), \
+ (APP_USBD_NRF_DFU_TRIGGER_INST_CONFIG(user_ev_handler, \
+ p_nordic_dfu, \
+ sem_ver_str, \
+ detach_timeout, \
+ transfer_size, \
+ 0x0110)) \
+ )
+
+
+/** @} */
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* APP_USBD_NRF_DFU_TRIGGER_INTERNAL_H__ */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/usbd/class/nrf_dfu_trigger/app_usbd_nrf_dfu_trigger_types.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/usbd/class/nrf_dfu_trigger/app_usbd_nrf_dfu_trigger_types.h
new file mode 100644
index 0000000..93f7fb9
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/usbd/class/nrf_dfu_trigger/app_usbd_nrf_dfu_trigger_types.h
@@ -0,0 +1,145 @@
+/**
+ * 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#ifndef APP_USBD_NRF_DFU_TRIGGER_TYPES_H__
+#define APP_USBD_NRF_DFU_TRIGGER_TYPES_H__
+
+#include "app_util.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @defgroup app_usbd_nrf_dfu_trigger_types USB Nordic DFU Trigger types
+ * @ingroup app_usbd_nrf_dfu_trigger
+ *
+ * @brief @tagAPI52840 Types used in the USB Nordic DFU Trigger class.
+ * @{
+ */
+
+/** @brief Nordic DFU Trigger class definition in interface descriptor
+ *
+ * @ref app_usbd_descriptor_iface_t::bInterfaceClass
+ * */
+#define APP_USBD_NRF_DFU_TRIGGER_CLASS 0xFF
+
+/**
+ * @brief Nordic DFU Trigger subclass possible value
+ */
+typedef enum {
+ APP_USBD_NRF_DFU_TRIGGER_SUBCLASS = 0x01, /**< Device Firmware Upgrade Code */
+} app_usbd_nrf_dfu_trigger_subclass_t;
+
+/**
+ * @brief Nordic DFU Trigger protocol possible value
+ *
+ * @note Only Run-time protocol is implemented, as DFU mode is covered by Nordic DFU.
+ */
+typedef enum {
+ APP_USBD_NRF_DFU_TRIGGER_PROTOCOL_RUNTIME = 0x01, /**< Run-time Protocol */
+} app_usbd_nrf_dfu_trigger_protocol_t;
+
+/**
+ * @brief Nordic DFU Trigger USB requests @ref nrf_drv_usbd_setup_t::bmRequestType
+ *
+ * @note Requests are limited only to @ref APP_USBD_NRF_DFU_TRIGGER_PROTOCOL_RUNTIME protocol type.
+ */
+typedef enum {
+ APP_USBD_NRF_DFU_TRIGGER_REQ_DETACH = 0x00, /**< Switch to DFU mode */
+ APP_USBD_NRF_DFU_TRIGGER_REQ_NORDIC_INFO = 0x07, /**< Request Nordic DFU information */
+ APP_USBD_NRF_DFU_TRIGGER_REQ_SEM_VER = 0x08, /**< Request semantic version information */
+} app_usbd_nrf_dfu_trigger_req_t;
+
+/**
+ * @brief Nordic DFU Trigger Functional Descriptor types.
+ */
+typedef enum {
+ APP_USBD_NRF_DFU_TRIGGER_CS_FUNCTIONAL = 0x21, /**< Functional descriptor type.*/
+} app_usbd_nrf_dfu_trigger_func_type_t;
+
+/**
+ * @brief Nordic DFU Trigger functional descriptor bmAttributes bit masks.
+ *
+ * @note For future compatibility with DFU class.
+ */
+typedef enum {
+ APP_USBD_NRF_DFU_TRIGGER_BIT_CAN_DNLOAD = 0x01, /**< bitCanDnload */
+ APP_USBD_NRF_DFU_TRIGGER_BIT_CAB_UPLOAD = 0x02, /**< bitCanUpload */
+ APP_USBD_NRF_DFU_TRIGGER_BIT_MANI_TOLERANT = 0x04, /**< bitManifestationTolerant */
+ APP_USBD_NRF_DFU_TRIGGER_BIT_WILL_DETACH = 0x08, /**< bitWillDetach */
+} app_usbd_nrf_dfu_trigger_bm_attributes_t;
+
+#pragma pack(push, 1)
+
+/**
+ * @brief Nordic DFU Trigger Functional Descriptor
+ */
+typedef struct {
+ uint8_t bFunctionLength; //!< Size of this descriptor in bytes.
+ uint8_t bDescriptorType; //!< Descriptor type.
+ uint8_t bmAttributes; //!< Attributes bits.
+ uint16_t wDetachTimeOut; //!< Device detach timeout - left for compatibility with USB DFU spec.
+ uint16_t wTransferSize; //!< Transfer size - left for compatibility with USB DFU spec.
+ uint16_t bcdDFUVersion; //!< DFU version.
+} app_usbd_nrf_dfu_trigger_desc_func_t;
+
+/**
+ * @brief Nordic custom DFU information.
+ */
+typedef struct {
+ uint32_t wAddress; //!< Firmware start address.
+ uint32_t wFirmwareSize; //!< Firmware size.
+ uint16_t wVersionMajor; //!< Firmware version major.
+ uint16_t wVersionMinor; //!< Firmware version minor.
+ uint32_t wFirmwareID; //!< Firmware ID.
+ uint32_t wFlashSize; //!< Flash size.
+ uint32_t wFlashPageSize; //!< Flash page size.
+} app_usbd_nrf_dfu_trigger_nordic_info_t;
+
+#pragma pack(pop)
+
+
+/** @} */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* APP_USBD_NRF_DFU_TRIGGER_TYPES_H__ */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/usbd/config/app_usbd_string_config.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/usbd/config/app_usbd_string_config.h
new file mode 100644
index 0000000..3c9da6b
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/usbd/config/app_usbd_string_config.h
@@ -0,0 +1,131 @@
+/**
+ * Copyright (c) 2016 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#ifndef APP_USBD_STRING_CONFIG_H
+#define APP_USBD_STRING_CONFIG_H
+
+/**
+ * @defgroup app_usbd_string_conf USBD string configuration
+ * @ingroup app_usbd_string_desc
+ *
+ * @brief @tagAPI52840 Configuration of the string module that can be easily affected by the final
+ * user.
+ * @{
+ */
+
+/**
+ * @brief Supported languages identifiers
+ *
+ * Comma separated list of supported languages.
+ */
+#define APP_USBD_STRINGS_LANGIDS \
+ ((uint16_t)APP_USBD_LANG_ENGLISH | (uint16_t)APP_USBD_SUBLANG_ENGLISH_US)
+
+/**
+ * @brief Manufacturer name string descriptor
+ *
+ * Comma separated list of manufacturer names for each defined language.
+ * Use @ref APP_USBD_STRING_DESC macro to create string descriptor.
+ *
+ * The order of manufacturer names has to be the same like in
+ * @ref APP_USBD_STRINGS_LANGIDS.
+ */
+#define APP_USBD_STRINGS_MANUFACTURER \
+ APP_USBD_STRING_DESC('N', 'o', 'r', 'd', 'i', 'c', ' ', 'S', 'e', 'm', 'i', 'c', 'o', 'n', 'd', 'u', 'c', 't', 'o', 'r')
+
+/**
+ * @brief Define whether @ref APP_USBD_STRINGS_MANUFACTURER is created by @ref APP_USBD_STRING_DESC
+ * or declared as global variable.
+ * */
+#define APP_USBD_STRINGS_MANUFACTURER_EXTERN 0
+
+/**
+ * @brief Product name string descriptor
+ *
+ * List of product names defined the same way like in @ref APP_USBD_STRINGS_MANUFACTURER
+ */
+#define APP_USBD_STRINGS_PRODUCT \
+ APP_USBD_STRING_DESC('n', 'R', 'F', '5', '2', ' ', 'U', 'S', 'B', ' ', 'D', 'e', 'm', 'o')
+
+
+/**
+ * @brief Define whether @ref APP_USBD_STRINGS_PRODUCT is created by @ref APP_USBD_STRING_DESC
+ * or declared as global variable.
+ * */
+#define APP_USBD_STRINGS_PRODUCT_EXTERN 0
+
+/**
+ * @brief Serial number string descriptor
+ *
+ * Create serial number string descriptor using @ref APP_USBD_STRING_DESC,
+ * or configure it to point to any internal variable pointer filled with descriptor.
+ *
+ * @note
+ * There is only one SERIAL number inside the library and it is Language independent.
+ */
+#define APP_USBD_STRING_SERIAL \
+ APP_USBD_STRING_DESC('0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0')
+
+/**
+ * @brief Define whether @ref APP_USBD_STRING_SERIAL is created by @ref APP_USBD_STRING_DESC
+ * or declared as global variable.
+ * */
+#define APP_USBD_STRING_SERIAL_EXTERN 0
+
+/**
+ * @brief User strings default values
+ *
+ * This value stores all application specific user strings with its default initialization.
+ * The setup is done by X-macros.
+ * Expected macro parameters:
+ * @code
+ * X(mnemonic, [=str_idx], ...)
+ * @endcode
+ * - @c mnemonic: Mnemonic of the string descriptor that would be added to
+ * @ref app_usbd_string_desc_idx_t enumerator.
+ * - @c str_idx : String index value, may be set or left empty.
+ * For example WinUSB driver requires descriptor to be present on 0xEE index.
+ * Then use X(USBD_STRING_WINUSB, =0xEE, (APP_USBD_STRING_DESC(...)))
+ * - @c ... : List of string descriptors for each defined language.
+ */
+#define APP_USBD_STRINGS_USER \
+ X(APP_USER_1, , APP_USBD_STRING_DESC('U', 's', 'e', 'r', ' ', '1'))
+
+/** @} */
+#endif /* APP_USBD_STRING_CONFIG_H */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/util/app_error.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/util/app_error.c
new file mode 100644
index 0000000..88b38e5
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/util/app_error.c
@@ -0,0 +1,125 @@
+/**
+ * Copyright (c) 2014 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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
+ *
+ * @defgroup app_error Common application error handler
+ * @{
+ * @ingroup app_common
+ *
+ * @brief Common application error handler.
+ */
+
+#include "nrf.h"
+#include <stdio.h>
+#include "app_error.h"
+#include "nordic_common.h"
+#include "sdk_errors.h"
+
+/**@brief Function for error handling, which is called when an error has occurred.
+ *
+ * @warning This handler is an example only and does not fit a final product. You need to analyze
+ * how your product is supposed to react in case of error.
+ *
+ * @param[in] error_code Error code supplied to the handler.
+ * @param[in] line_num Line number where the handler is called.
+ * @param[in] p_file_name Pointer to the file name.
+ */
+void app_error_handler_bare(ret_code_t error_code)
+{
+ error_info_t error_info =
+ {
+ .line_num = 0,
+ .p_file_name = NULL,
+ .err_code = error_code,
+ };
+
+ app_error_fault_handler(NRF_FAULT_ID_SDK_ERROR, 0, (uint32_t)(&error_info));
+
+ UNUSED_VARIABLE(error_info);
+}
+
+void app_error_save_and_stop(uint32_t id, uint32_t pc, uint32_t info)
+{
+ /* static error variables - in order to prevent removal by optimizers */
+ static volatile struct
+ {
+ uint32_t fault_id;
+ uint32_t pc;
+ uint32_t error_info;
+ assert_info_t * p_assert_info;
+ error_info_t * p_error_info;
+ ret_code_t err_code;
+ uint32_t line_num;
+ const uint8_t * p_file_name;
+ } m_error_data = {0};
+
+ // The following variable helps Keil keep the call stack visible, in addition, it can be set to
+ // 0 in the debugger to continue executing code after the error check.
+ volatile bool loop = true;
+ UNUSED_VARIABLE(loop);
+
+ m_error_data.fault_id = id;
+ m_error_data.pc = pc;
+ m_error_data.error_info = info;
+
+ switch (id)
+ {
+ case NRF_FAULT_ID_SDK_ASSERT:
+ m_error_data.p_assert_info = (assert_info_t *)info;
+ m_error_data.line_num = m_error_data.p_assert_info->line_num;
+ m_error_data.p_file_name = m_error_data.p_assert_info->p_file_name;
+ break;
+
+ case NRF_FAULT_ID_SDK_ERROR:
+ m_error_data.p_error_info = (error_info_t *)info;
+ m_error_data.err_code = m_error_data.p_error_info->err_code;
+ m_error_data.line_num = m_error_data.p_error_info->line_num;
+ m_error_data.p_file_name = m_error_data.p_error_info->p_file_name;
+ break;
+ }
+
+ UNUSED_VARIABLE(m_error_data);
+
+ // If printing is disrupted, remove the irq calls, or set the loop variable to 0 in the debugger.
+ __disable_irq();
+ while (loop);
+
+ __enable_irq();
+}
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/util/app_error.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/util/app_error.h
new file mode 100644
index 0000000..b831f7b
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/util/app_error.h
@@ -0,0 +1,192 @@
+/**
+ * Copyright (c) 2013 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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
+ *
+ * @defgroup app_error Common application error handler
+ * @{
+ * @ingroup app_common
+ *
+ * @brief Common application error handler and macros for utilizing a common error handler.
+ */
+
+#ifndef APP_ERROR_H__
+#define APP_ERROR_H__
+
+
+#include <stdint.h>
+#include <stdio.h>
+#include <stdbool.h>
+#include "nrf.h"
+#include "sdk_errors.h"
+#include "nordic_common.h"
+#include "app_error_weak.h"
+#ifdef ANT_STACK_SUPPORT_REQD
+#include "ant_error.h"
+#endif // ANT_STACK_SUPPORT_REQD
+
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define NRF_FAULT_ID_SDK_RANGE_START (0x00004000) /**< The start of the range of error IDs defined in the SDK. */
+
+/**@defgroup APP_ERROR_FAULT_IDS Fault ID types
+ * @{ */
+#define NRF_FAULT_ID_SDK_ERROR (NRF_FAULT_ID_SDK_RANGE_START + 1) /**< An error stemming from a call to @ref APP_ERROR_CHECK or @ref APP_ERROR_CHECK_BOOL. The info parameter is a pointer to an @ref error_info_t variable. */
+#define NRF_FAULT_ID_SDK_ASSERT (NRF_FAULT_ID_SDK_RANGE_START + 2) /**< An error stemming from a call to ASSERT (nrf_assert.h). The info parameter is a pointer to an @ref assert_info_t variable. */
+/**@} */
+
+/**@brief Structure containing info about an error of the type @ref NRF_FAULT_ID_SDK_ERROR.
+ */
+typedef struct
+{
+ uint32_t line_num; /**< The line number where the error occurred. */
+ uint8_t const * p_file_name; /**< The file in which the error occurred. */
+ uint32_t err_code; /**< The error code representing the error that occurred. */
+} error_info_t;
+
+/**@brief Structure containing info about an error of the type @ref NRF_FAULT_ID_SDK_ASSERT.
+ */
+typedef struct
+{
+ uint16_t line_num; /**< The line number where the error occurred. */
+ uint8_t const * p_file_name; /**< The file in which the error occurred. */
+} assert_info_t;
+
+/**@brief Defines required by app_error_handler assembler intructions.
+ */
+#define APP_ERROR_ERROR_INFO_OFFSET_LINE_NUM (offsetof(error_info_t, line_num))
+#define APP_ERROR_ERROR_INFO_OFFSET_P_FILE_NAME (offsetof(error_info_t, p_file_name))
+#define APP_ERROR_ERROR_INFO_OFFSET_ERR_CODE (offsetof(error_info_t, err_code))
+#define APP_ERROR_ERROR_INFO_SIZE (sizeof(error_info_t))
+#define APP_ERROR_ERROR_INFO_SIZE_ALIGNED_8BYTE \
+ ALIGN_NUM(APP_ERROR_ERROR_INFO_SIZE, sizeof(uint64_t))
+
+
+/**@brief Function for error handling, which is called when an error has occurred.
+ *
+ * @param[in] error_code Error code supplied to the handler.
+ * @param[in] line_num Line number where the handler is called.
+ * @param[in] p_file_name Pointer to the file name.
+ */
+void app_error_handler(uint32_t error_code, uint32_t line_num, const uint8_t * p_file_name);
+
+/**@brief Function for error handling, which is called when an error has occurred.
+ *
+ * @param[in] error_code Error code supplied to the handler.
+ */
+void app_error_handler_bare(ret_code_t error_code);
+
+/**@brief Function for saving the parameters and entering an eternal loop, for debug purposes.
+ *
+ * @param[in] id Fault identifier. See @ref NRF_FAULT_IDS.
+ * @param[in] pc The program counter of the instruction that triggered the fault, or 0 if
+ * unavailable.
+ * @param[in] info Optional additional information regarding the fault. Refer to each fault
+ * identifier for details.
+ */
+void app_error_save_and_stop(uint32_t id, uint32_t pc, uint32_t info);
+
+/**@brief Function for logging details of error and flushing logs.
+ *
+ * @param[in] id Fault identifier. See @ref NRF_FAULT_IDS.
+ * @param[in] pc The program counter of the instruction that triggered the fault, or 0 if
+ * unavailable.
+ * @param[in] info Optional additional information regarding the fault. Refer to each fault
+ * identifier for details.
+ */
+void app_error_log_handle(uint32_t id, uint32_t pc, uint32_t info);
+
+
+/**@brief Macro for calling error handler function.
+ *
+ * @param[in] ERR_CODE Error code supplied to the error handler.
+ */
+#ifdef DEBUG
+#define APP_ERROR_HANDLER(ERR_CODE) \
+ do \
+ { \
+ app_error_handler((ERR_CODE), __LINE__, (uint8_t*) __FILE__); \
+ } while (0)
+#else
+#define APP_ERROR_HANDLER(ERR_CODE) \
+ do \
+ { \
+ app_error_handler_bare((ERR_CODE)); \
+ } while (0)
+#endif
+/**@brief Macro for calling error handler function if supplied error code any other than NRF_SUCCESS.
+ *
+ * @param[in] ERR_CODE Error code supplied to the error handler.
+ */
+#define APP_ERROR_CHECK(ERR_CODE) \
+ do \
+ { \
+ const uint32_t LOCAL_ERR_CODE = (ERR_CODE); \
+ if (LOCAL_ERR_CODE != NRF_SUCCESS) \
+ { \
+ APP_ERROR_HANDLER(LOCAL_ERR_CODE); \
+ } \
+ } while (0)
+
+/**@brief Macro for calling error handler function if supplied boolean value is false.
+ *
+ * @param[in] BOOLEAN_VALUE Boolean value to be evaluated.
+ */
+#define APP_ERROR_CHECK_BOOL(BOOLEAN_VALUE) \
+ do \
+ { \
+ const uint32_t LOCAL_BOOLEAN_VALUE = (BOOLEAN_VALUE); \
+ if (!LOCAL_BOOLEAN_VALUE) \
+ { \
+ APP_ERROR_HANDLER(0); \
+ } \
+ } while (0)
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // APP_ERROR_H__
+
+/** @} */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/util/app_error_handler_gcc.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/util/app_error_handler_gcc.c
new file mode 100644
index 0000000..b2420ed
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/util/app_error_handler_gcc.c
@@ -0,0 +1,101 @@
+/**
+ * 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#include "sdk_common.h"
+#include "compiler_abstraction.h"
+#include "app_error.h"
+
+#if defined (__CORTEX_M) && (__CORTEX_M == 0x04)
+void app_error_handler(ret_code_t error_code, uint32_t line_num, const uint8_t * p_file_name) __attribute__(( naked ));
+
+void app_error_handler(ret_code_t error_code, uint32_t line_num, const uint8_t * p_file_name)
+{
+ __ASM volatile(
+
+ "push {lr} \n"
+
+ /* reserve space on stack for error_info_t struct - preserve 8byte stack aligment */
+ "sub sp, sp, %0 \n"
+
+ /* prepare error_info_t struct */
+ "str r0, [sp, %1] \n"
+ "str r1, [sp, %3] \n"
+ "str r2, [sp, %2] \n"
+
+ /* prepare arguments and call function: app_error_fault_handler */
+ "ldr r0, =%4 \n"
+ "mov r1, lr \n"
+ "mov r2, sp \n"
+ "bl %5 \n"
+
+ /* release stack */
+ "add sp, sp, %0 \n"
+
+ "pop {pc} \n"
+ ".ltorg \n"
+
+ : /* Outputs */
+ : /* Inputs */
+ "I" (APP_ERROR_ERROR_INFO_SIZE_ALIGNED_8BYTE),
+ "I" (APP_ERROR_ERROR_INFO_OFFSET_ERR_CODE),
+ "I" (APP_ERROR_ERROR_INFO_OFFSET_P_FILE_NAME),
+ "I" (APP_ERROR_ERROR_INFO_OFFSET_LINE_NUM),
+ "X" (NRF_FAULT_ID_SDK_ERROR),
+ "X" (app_error_fault_handler)
+ : /* Clobbers */
+ "r0", "r1", "r2"
+ );
+}
+#elif defined(__CORTEX_M) && (__CORTEX_M == 0x00)
+/* NRF51 implementation is currently not supporting PC readout */
+void app_error_handler(ret_code_t error_code, uint32_t line_num, const uint8_t * p_file_name)
+{
+ error_info_t error_info = {
+ .line_num = line_num,
+ .p_file_name = p_file_name,
+ .err_code = error_code,
+ };
+ app_error_fault_handler(NRF_FAULT_ID_SDK_ERROR, 0, (uint32_t)(&error_info));
+
+ UNUSED_VARIABLE(error_info);
+}
+#else
+#error Architecture not supported
+#endif
+
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/util/app_error_handler_iar.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/util/app_error_handler_iar.c
new file mode 100644
index 0000000..1a6dc54
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/util/app_error_handler_iar.c
@@ -0,0 +1,101 @@
+/**
+ * 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#include "sdk_common.h"
+#include "compiler_abstraction.h"
+#include "app_error.h"
+
+#if defined (__CORTEX_M) && (__CORTEX_M == 0x04)
+void app_error_handler(ret_code_t error_code, uint32_t line_num, const uint8_t * p_file_name)
+{
+ __ASM volatile(
+ "push {lr} \n"
+ /* reserve space on stack for error_info_t struct */
+ "sub sp, sp, %0 \n"
+
+ /* prepare error_info_t struct */
+ "str r0, [sp, %1] \n"
+ "str r1, [sp, %3] \n"
+ "str r2, [sp, %2] \n"
+
+ /* prepare arguments and call function: app_error_fault_handler */
+ "ldr.n r0, 1f \n"
+ "mov r1, LR \n"
+ "mov r2, sp \n"
+
+ /* call app_error_fault_handler */
+ "bl %c5 \n"
+
+ /* release stack */
+ "add sp, sp, %0 \n"
+ "pop {pc} \n"
+
+ "DATA \n"
+ "1: \n"
+ " DC32 %c4 \n"
+
+ : /* Outputs */
+ : /* Inputs */
+ "i" (APP_ERROR_ERROR_INFO_SIZE_ALIGNED_8BYTE),
+ "i" (APP_ERROR_ERROR_INFO_OFFSET_ERR_CODE),
+ "i" (APP_ERROR_ERROR_INFO_OFFSET_P_FILE_NAME),
+ "i" (APP_ERROR_ERROR_INFO_OFFSET_LINE_NUM),
+ "i" (NRF_FAULT_ID_SDK_ERROR),
+ "i" (app_error_fault_handler)
+ : /* CLobbers */
+ "r0", "r1", "r2"
+ );
+}
+#elif defined(__CORTEX_M) && (__CORTEX_M == 0x00)
+/* NRF51 implementation is currently not supporting PC readout */
+void app_error_handler(ret_code_t error_code, uint32_t line_num, const uint8_t * p_file_name)
+{
+ error_info_t error_info = {
+ .line_num = line_num,
+ .p_file_name = p_file_name,
+ .err_code = error_code,
+ };
+ app_error_fault_handler(NRF_FAULT_ID_SDK_ERROR, 0, (uint32_t)(&error_info));
+
+ UNUSED_VARIABLE(error_info);
+}
+#else
+#error Architecture not supported
+#endif
+
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/util/app_error_handler_keil.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/util/app_error_handler_keil.c
new file mode 100644
index 0000000..4ce648c
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/util/app_error_handler_keil.c
@@ -0,0 +1,89 @@
+/**
+ * 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#include "sdk_common.h"
+#include "compiler_abstraction.h"
+#include "app_error.h"
+
+#if defined (__CORTEX_M) && (__CORTEX_M == 0x04)
+__ASM void app_error_handler(ret_code_t error_code, uint32_t line_num, const uint8_t * p_file_name)
+{
+ PRESERVE8 {TRUE}
+ THUMB
+
+ push {lr}
+
+ /* reserve space on stack for error_info_t struct - preserve 8byte stack aligment */
+ sub sp, sp, #__cpp(APP_ERROR_ERROR_INFO_SIZE_ALIGNED_8BYTE)
+
+ /* prepare error_info_t struct */
+ str r0, [sp, #__cpp(APP_ERROR_ERROR_INFO_OFFSET_ERR_CODE)]
+ str r1, [sp, #__cpp(APP_ERROR_ERROR_INFO_OFFSET_LINE_NUM)]
+ str r2, [sp, #__cpp(APP_ERROR_ERROR_INFO_OFFSET_P_FILE_NAME)]
+
+ /* prepare arguments and call function: app_error_fault_handler */
+ mov r0, #__cpp(NRF_FAULT_ID_SDK_ERROR)
+ mov r1, lr
+ mov r2, sp
+
+ /* call function */
+ bl __cpp(app_error_fault_handler)
+
+ /* release stack */
+ add sp, sp, #__cpp(APP_ERROR_ERROR_INFO_SIZE_ALIGNED_8BYTE)
+
+ pop {pc}
+}
+#elif defined(__CORTEX_M) && (__CORTEX_M == 0x00)
+/* NRF51 implementation is currently not supporting PC readout */
+void app_error_handler(ret_code_t error_code, uint32_t line_num, const uint8_t * p_file_name)
+{
+ error_info_t error_info = {
+ .line_num = line_num,
+ .p_file_name = p_file_name,
+ .err_code = error_code,
+ };
+ app_error_fault_handler(NRF_FAULT_ID_SDK_ERROR, 0, (uint32_t)(&error_info));
+
+ UNUSED_VARIABLE(error_info);
+}
+#else
+#error Architecture not supported
+#endif
+
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/util/app_error_weak.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/util/app_error_weak.c
new file mode 100644
index 0000000..0e0130a
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/util/app_error_weak.c
@@ -0,0 +1,109 @@
+/**
+ * Copyright (c) 2016 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#include "app_error.h"
+
+#include "nrf_log.h"
+#include "nrf_log_ctrl.h"
+#include "nrf_strerror.h"
+
+#if defined(SOFTDEVICE_PRESENT) && SOFTDEVICE_PRESENT
+#include "nrf_sdm.h"
+#endif
+
+/*lint -save -e14 */
+/**
+ * Function is implemented as weak so that it can be overwritten by custom application error handler
+ * when needed.
+ */
+__WEAK void app_error_fault_handler(uint32_t id, uint32_t pc, uint32_t info)
+{
+ __disable_irq();
+ NRF_LOG_FINAL_FLUSH();
+
+#ifndef DEBUG
+ NRF_LOG_ERROR("Fatal error");
+#else
+ switch (id)
+ {
+#if defined(SOFTDEVICE_PRESENT) && SOFTDEVICE_PRESENT
+ case NRF_FAULT_ID_SD_ASSERT:
+ NRF_LOG_ERROR("SOFTDEVICE: ASSERTION FAILED");
+ break;
+ case NRF_FAULT_ID_APP_MEMACC:
+ NRF_LOG_ERROR("SOFTDEVICE: INVALID MEMORY ACCESS");
+ break;
+#endif
+ case NRF_FAULT_ID_SDK_ASSERT:
+ {
+ assert_info_t * p_info = (assert_info_t *)info;
+ NRF_LOG_ERROR("ASSERTION FAILED at %s:%u",
+ p_info->p_file_name,
+ p_info->line_num);
+ break;
+ }
+ case NRF_FAULT_ID_SDK_ERROR:
+ {
+ error_info_t * p_info = (error_info_t *)info;
+ NRF_LOG_ERROR("ERROR %u [%s] at %s:%u\r\nPC at: 0x%08x",
+ p_info->err_code,
+ nrf_strerror_get(p_info->err_code),
+ p_info->p_file_name,
+ p_info->line_num,
+ pc);
+ NRF_LOG_ERROR("End of error report");
+ break;
+ }
+ default:
+ NRF_LOG_ERROR("UNKNOWN FAULT at 0x%08X", pc);
+ break;
+ }
+#endif
+
+ NRF_BREAKPOINT_COND;
+ // On assert, the system can only recover with a reset.
+
+#ifndef DEBUG
+ NRF_LOG_WARNING("System reset");
+ NVIC_SystemReset();
+#else
+ app_error_save_and_stop(id, pc, info);
+#endif // DEBUG
+}
+/*lint -restore */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/util/app_error_weak.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/util/app_error_weak.h
new file mode 100644
index 0000000..fd1a502
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/util/app_error_weak.h
@@ -0,0 +1,87 @@
+/**
+ * Copyright (c) 2016 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#ifndef APP_ERROR_WEAK_H__
+#define APP_ERROR_WEAK_H__
+
+#include <stdint.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** @file
+ *
+ * @defgroup app_error Common application error handler
+ * @{
+ * @ingroup app_common
+ *
+ * @brief Common application error handler.
+ */
+
+/**@brief Callback function for errors, asserts, and faults.
+ *
+ * @details This function is called every time an error is raised in app_error, nrf_assert, or
+ * in the SoftDevice. Information about the error can be found in the @p info
+ * parameter.
+ *
+ * See also @ref nrf_fault_handler_t for more details.
+ *
+ * @note The function is implemented as weak so that it can be redefined by a custom error
+ * handler when needed.
+ *
+ * @param[in] id Fault identifier. See @ref NRF_FAULT_IDS.
+ * @param[in] pc The program counter of the instruction that triggered the fault, or 0 if
+ * unavailable.
+ * @param[in] info Optional additional information regarding the fault. The value of the @p id
+ * parameter dictates how to interpret this parameter. Refer to the documentation
+ * for each fault identifier (@ref NRF_FAULT_IDS and @ref APP_ERROR_FAULT_IDS) for
+ * details about interpreting @p info.
+ */
+void app_error_fault_handler(uint32_t id, uint32_t pc, uint32_t info);
+
+
+/** @} */
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // APP_ERROR_WEAK_H__
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/util/app_util.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/util/app_util.h
new file mode 100644
index 0000000..b5adb20
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/util/app_util.h
@@ -0,0 +1,1204 @@
+/**
+ * Copyright (c) 2012 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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
+ *
+ * @defgroup app_util Utility Functions and Definitions
+ * @{
+ * @ingroup app_common
+ *
+ * @brief Various types and definitions available to all applications.
+ */
+
+#ifndef APP_UTIL_H__
+#define APP_UTIL_H__
+
+#include <stdint.h>
+#include <stdbool.h>
+#include <stddef.h>
+#include "compiler_abstraction.h"
+#include "nordic_common.h"
+#include "nrf.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+/**
+ * @cond (NODOX)
+ */
+/*lint -save -e27 -e10 -e19 */
+#if defined (__LINT__)
+#define STACK_BASE 0x1F000 // Arbitrary value.
+#define STACK_TOP 0x20000 // Arbitrary value.
+
+#elif defined ( __CC_ARM )
+extern char STACK$$Base;
+extern char STACK$$Length;
+#define STACK_BASE &STACK$$Base
+#define STACK_TOP ((void*)((uint32_t)STACK_BASE + (uint32_t)&STACK$$Length))
+
+#elif defined ( __ICCARM__ )
+extern char CSTACK$$Base;
+extern char CSTACK$$Length;
+#define STACK_BASE &CSTACK$$Base
+#define STACK_TOP ((void*)((uint32_t)STACK_BASE + (uint32_t)&CSTACK$$Length))
+
+#elif defined ( __GNUC__ )
+extern uint32_t __StackTop;
+extern uint32_t __StackLimit;
+#define STACK_BASE &__StackLimit
+#define STACK_TOP &__StackTop
+#endif
+
+/* These macros are valid only when absolute placement is used for the application
+ * image. The macros are not compile time symbols. They cannot be used as a
+ * constant expression, for example, inside a static assert or linker script
+ * at-placement. */
+#if defined (__LINT__)
+#define CODE_START (0) // Arbitrary value.
+#define CODE_END (0x1000) // Arbitrary value.
+#define CODE_SIZE (0x1000) // Arbitrary value.
+
+#elif defined ( __CC_ARM )
+extern char Load$$LR$$LR_IROM1$$Base;
+extern char Load$$LR$$LR_IROM1$$Length;
+extern char Load$$LR$$LR_IROM1$$Limit;
+#define CODE_START ((uint32_t)&Load$$LR$$LR_IROM1$$Base)
+#define CODE_END ((uint32_t)&Load$$LR$$LR_IROM1$$Limit)
+#define CODE_SIZE ((uint32_t)&Load$$LR$$LR_IROM1$$Length)
+
+#elif defined ( __ICCARM__ )
+extern void * __vector_table;
+extern char RO_END$$Base;
+#define CODE_START ((uint32_t)&__vector_table)
+#define CODE_END ((uint32_t)&RO_END$$Base)
+#define CODE_SIZE (CODE_END - CODE_START)
+
+#elif defined(__SES_ARM)
+extern uint32_t * _vectors;
+extern uint32_t __FLASH_segment_used_end__;
+#define CODE_START ((uint32_t)&_vectors)
+#define CODE_END ((uint32_t)&__FLASH_segment_used_end__)
+#define CODE_SIZE (CODE_END - CODE_START)
+
+#elif defined ( __GNUC__ )
+extern uint32_t __isr_vector;
+extern uint32_t __etext;
+#define CODE_START ((uint32_t)&__isr_vector)
+#define CODE_END ((uint32_t)&__etext)
+#define CODE_SIZE (CODE_END - CODE_START)
+#endif
+/** @}
+ * @endcond
+ */
+/* lint -restore */
+
+enum
+{
+ UNIT_0_625_MS = 625, /**< Number of microseconds in 0.625 milliseconds. */
+ UNIT_1_25_MS = 1250, /**< Number of microseconds in 1.25 milliseconds. */
+ UNIT_10_MS = 10000 /**< Number of microseconds in 10 milliseconds. */
+};
+
+/**
+ * @brief Counts number of bits required for the given value
+ *
+ * The macro technically searches for the highest bit set.
+ * For value 0 it returns 0.
+ *
+ * @param val Value to be processed
+ *
+ * @return Number of bits required for the given value
+ */
+//lint -emacro(572,VBITS)
+#define VBITS(val) VBITS_32(val)
+
+/**
+ * @def VBITS_1
+ * @brief Internal macro used by @ref VBITS */
+/**
+ * @def VBITS_2
+ * @brief Internal macro used by @ref VBITS */
+/**
+ * @def VBITS_4
+ * @brief Internal macro used by @ref VBITS */
+/**
+ * @def VBITS_8
+ * @brief Internal macro used by @ref VBITS */
+/**
+ * @def VBITS_16
+ * @brief Internal macro used by @ref VBITS */
+/**
+ * @def VBITS_32
+ * @brief Internal macro used by @ref VBITS */
+#define VBITS_1( v) ((((v) & (0x0001U << 0)) != 0) ? 1U : 0U)
+#define VBITS_2( v) ((((v) & (0x0001U << 1)) != 0) ? VBITS_1 ((v) >> 1) + 1 : VBITS_1 (v))
+#define VBITS_4( v) ((((v) & (0x0003U << 2)) != 0) ? VBITS_2 ((v) >> 2) + 2 : VBITS_2 (v))
+#define VBITS_8( v) ((((v) & (0x000fU << 4)) != 0) ? VBITS_4 ((v) >> 4) + 4 : VBITS_4 (v))
+#define VBITS_16(v) ((((v) & (0x00ffU << 8)) != 0) ? VBITS_8 ((v) >> 8) + 8 : VBITS_8 (v))
+#define VBITS_32(v) ((((v) & (0xffffU << 16)) != 0) ? VBITS_16((v) >> 16) + 16 : VBITS_16(v))
+
+
+/*Segger embedded studio originally has offsetof macro which cannot be used in macros (like STATIC_ASSERT).
+ This redefinition is to allow using that. */
+#if defined(__SES_ARM) && defined(__GNUC__)
+#undef offsetof
+#define offsetof(TYPE, MEMBER) __builtin_offsetof (TYPE, MEMBER)
+#endif
+
+/**@brief Implementation specific macro for delayed macro expansion used in string concatenation
+*
+* @param[in] lhs Left hand side in concatenation
+* @param[in] rhs Right hand side in concatenation
+*/
+#define STRING_CONCATENATE_IMPL(lhs, rhs) lhs ## rhs
+
+
+/**@brief Macro used to concatenate string using delayed macro expansion
+*
+* @note This macro will delay concatenation until the expressions have been resolved
+*
+* @param[in] lhs Left hand side in concatenation
+* @param[in] rhs Right hand side in concatenation
+*/
+#define STRING_CONCATENATE(lhs, rhs) STRING_CONCATENATE_IMPL(lhs, rhs)
+
+
+#ifndef __LINT__
+
+#ifdef __GNUC__
+#define STATIC_ASSERT_SIMPLE(EXPR) _Static_assert(EXPR, "unspecified message")
+#define STATIC_ASSERT_MSG(EXPR, MSG) _Static_assert(EXPR, MSG)
+#endif
+
+#ifdef __CC_ARM
+#define STATIC_ASSERT_SIMPLE(EXPR) extern char (*_do_assert(void)) [sizeof(char[1 - 2*!(EXPR)])]
+#define STATIC_ASSERT_MSG(EXPR, MSG) extern char (*_do_assert(void)) [sizeof(char[1 - 2*!(EXPR)])]
+#endif
+
+#ifdef __ICCARM__
+#define STATIC_ASSERT_SIMPLE(EXPR) static_assert(EXPR, "unspecified message")
+#define STATIC_ASSERT_MSG(EXPR, MSG) static_assert(EXPR, MSG)
+#endif
+
+#else // __LINT__
+
+#define STATIC_ASSERT_SIMPLE(EXPR) extern char (*_ignore(void))
+#define STATIC_ASSERT_MSG(EXPR, MSG) extern char (*_ignore(void))
+
+#endif
+
+
+#define _SELECT_ASSERT_FUNC(x, EXPR, MSG, ASSERT_MACRO, ...) ASSERT_MACRO
+
+/**
+ * @brief Static (i.e. compile time) assert macro.
+ *
+ * @note The output of STATIC_ASSERT can be different across compilers.
+ *
+ * Usage:
+ * STATIC_ASSERT(expression);
+ * STATIC_ASSERT(expression, message);
+ *
+ * @hideinitializer
+ */
+//lint -save -esym(???, STATIC_ASSERT)
+#define STATIC_ASSERT(...) \
+ _SELECT_ASSERT_FUNC(x, ##__VA_ARGS__, \
+ STATIC_ASSERT_MSG(__VA_ARGS__), \
+ STATIC_ASSERT_SIMPLE(__VA_ARGS__))
+//lint -restore
+
+
+/**@brief Implementation details for NUM_VAR_ARGS */
+#define NUM_VA_ARGS_IMPL( \
+ _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, \
+ _11, _12, _13, _14, _15, _16, _17, _18, _19, _20, \
+ _21, _22, _23, _24, _25, _26, _27, _28, _29, _30, \
+ _31, _32, _33, _34, _35, _36, _37, _38, _39, _40, \
+ _41, _42, _43, _44, _45, _46, _47, _48, _49, _50, \
+ _51, _52, _53, _54, _55, _56, _57, _58, _59, _60, \
+ _61, _62, N, ...) N
+
+
+/**@brief Macro to get the number of arguments in a call variadic macro call
+ *
+ * param[in] ... List of arguments
+ *
+ * @retval Number of variadic arguments in the argument list
+ */
+#define NUM_VA_ARGS(...) NUM_VA_ARGS_IMPL(__VA_ARGS__, 63, 62, 61, \
+ 60, 59, 58, 57, 56, 55, 54, 53, 52, 51, \
+ 50, 49, 48, 47, 46, 45, 44, 43, 42, 41, \
+ 40, 39, 38, 37, 36, 35, 34, 33, 32, 31, \
+ 30, 29, 28, 27, 26, 25, 24, 23, 22, 21, \
+ 20, 19, 18, 17, 16, 15, 14, 13, 12, 11, \
+ 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0)
+
+/**@brief Implementation details for NUM_VAR_ARGS */
+#define NUM_VA_ARGS_LESS_1_IMPL( \
+ _ignored, \
+ _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, \
+ _11, _12, _13, _14, _15, _16, _17, _18, _19, _20, \
+ _21, _22, _23, _24, _25, _26, _27, _28, _29, _30, \
+ _31, _32, _33, _34, _35, _36, _37, _38, _39, _40, \
+ _41, _42, _43, _44, _45, _46, _47, _48, _49, _50, \
+ _51, _52, _53, _54, _55, _56, _57, _58, _59, _60, \
+ _61, _62, N, ...) N
+
+/**@brief Macro to get the number of arguments in a call variadic macro call.
+ * First argument is not counted.
+ *
+ * param[in] ... List of arguments
+ *
+ * @retval Number of variadic arguments in the argument list
+ */
+#define NUM_VA_ARGS_LESS_1(...) NUM_VA_ARGS_LESS_1_IMPL(__VA_ARGS__, 63, 62, 61, \
+ 60, 59, 58, 57, 56, 55, 54, 53, 52, 51, \
+ 50, 49, 48, 47, 46, 45, 44, 43, 42, 41, \
+ 40, 39, 38, 37, 36, 35, 34, 33, 32, 31, \
+ 30, 29, 28, 27, 26, 25, 24, 23, 22, 21, \
+ 20, 19, 18, 17, 16, 15, 14, 13, 12, 11, \
+ 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0, ~)
+
+
+/**@brief type for holding an encoded (i.e. little endian) 16 bit unsigned integer. */
+typedef uint8_t uint16_le_t[2];
+
+/**@brief Type for holding an encoded (i.e. little endian) 32 bit unsigned integer. */
+typedef uint8_t uint32_le_t[4];
+
+/**@brief Byte array type. */
+typedef struct
+{
+ uint16_t size; /**< Number of array entries. */
+ uint8_t * p_data; /**< Pointer to array entries. */
+} uint8_array_t;
+
+
+/**@brief Macro for performing rounded integer division (as opposed to truncating the result).
+ *
+ * @param[in] A Numerator.
+ * @param[in] B Denominator.
+ *
+ * @return Rounded (integer) result of dividing A by B.
+ */
+#define ROUNDED_DIV(A, B) (((A) + ((B) / 2)) / (B))
+
+
+/**@brief Macro for checking if an integer is a power of two.
+ *
+ * @param[in] A Number to be tested.
+ *
+ * @return true if value is power of two.
+ * @return false if value not power of two.
+ */
+#define IS_POWER_OF_TWO(A) ( ((A) != 0) && ((((A) - 1) & (A)) == 0) )
+
+
+/**@brief Macro for converting milliseconds to ticks.
+ *
+ * @param[in] TIME Number of milliseconds to convert.
+ * @param[in] RESOLUTION Unit to be converted to in [us/ticks].
+ */
+#define MSEC_TO_UNITS(TIME, RESOLUTION) (((TIME) * 1000) / (RESOLUTION))
+
+
+/**@brief Macro for performing integer division, making sure the result is rounded up.
+ *
+ * @details One typical use for this is to compute the number of objects with size B is needed to
+ * hold A number of bytes.
+ *
+ * @param[in] A Numerator.
+ * @param[in] B Denominator.
+ *
+ * @return Integer result of dividing A by B, rounded up.
+ */
+#define CEIL_DIV(A, B) \
+ (((A) + (B) - 1) / (B))
+
+
+/**@brief Macro for creating a buffer aligned to 4 bytes.
+ *
+ * @param[in] NAME Name of the buffor.
+ * @param[in] MIN_SIZE Size of this buffor (it will be rounded up to multiples of 4 bytes).
+ */
+#define WORD_ALIGNED_MEM_BUFF(NAME, MIN_SIZE) static uint32_t NAME[CEIL_DIV(MIN_SIZE, sizeof(uint32_t))]
+
+
+/**@brief Macro for calculating the number of words that are needed to hold a number of bytes.
+ *
+ * @details Adds 3 and divides by 4.
+ *
+ * @param[in] n_bytes The number of bytes.
+ *
+ * @return The number of words that @p n_bytes take up (rounded up).
+ */
+#define BYTES_TO_WORDS(n_bytes) (((n_bytes) + 3) >> 2)
+
+
+/**@brief The number of bytes in a word.
+ */
+#define BYTES_PER_WORD (4)
+
+
+/**@brief Macro for increasing a number to the nearest (larger) multiple of another number.
+ *
+ * @param[in] alignment The number to align to.
+ * @param[in] number The number to align (increase).
+ *
+ * @return The aligned (increased) @p number.
+ */
+#define ALIGN_NUM(alignment, number) (((number) - 1) + (alignment) - (((number) - 1) % (alignment)))
+
+/**@brief Macro for getting first of 2 parameters.
+ *
+ * @param[in] a1 First parameter.
+ * @param[in] a2 Second parameter.
+ */
+#define GET_ARG_1(a1, a2) a1
+
+/**@brief Macro for getting second of 2 parameters.
+ *
+ * @param[in] a1 First parameter.
+ * @param[in] a2 Second parameter.
+ */
+#define GET_ARG_2(a1, a2) a2
+
+
+/**@brief Container of macro (borrowed from Linux kernel).
+ *
+ * This macro returns parent structure address basing on child member address.
+ *
+ * @param ptr Address of child type.
+ * @param type Type of parent structure.
+ * @param member Name of child field in parent structure.
+ *
+ * @return Parent structure address.
+ * */
+#define CONTAINER_OF(ptr, type, member) \
+ (type *)((char *)ptr - offsetof(type, member))
+
+
+/**
+ * @brief Define Bit-field mask
+ *
+ * Macro that defined the mask with selected number of bits set, starting from
+ * provided bit number.
+ *
+ * @param[in] bcnt Number of bits in the bit-field
+ * @param[in] boff Lowest bit number
+ */
+#define BF_MASK(bcnt, boff) ( ((1U << (bcnt)) - 1U) << (boff) )
+
+/**
+ * @brief Get bit-field
+ *
+ * Macro that extracts selected bit-field from provided value
+ *
+ * @param[in] val Value from witch selected bit-field would be extracted
+ * @param[in] bcnt Number of bits in the bit-field
+ * @param[in] boff Lowest bit number
+ *
+ * @return Value of the selected bits
+ */
+#define BF_GET(val, bcnt, boff) ( ( (val) & BF_MASK((bcnt), (boff)) ) >> (boff) )
+
+/**
+ * @brief Create bit-field value
+ *
+ * Value is masked and shifted to match given bit-field
+ *
+ * @param[in] val Value to set on bit-field
+ * @param[in] bcnt Number of bits for bit-field
+ * @param[in] boff Offset of bit-field
+ *
+ * @return Value positioned of given bit-field.
+ */
+#define BF_VAL(val, bcnt, boff) ( (((uint32_t)(val)) << (boff)) & BF_MASK(bcnt, boff) )
+
+/**
+ * @name Configuration of complex bit-field
+ *
+ * @sa BF_CX
+ * @{
+ */
+/** @brief Position of bit count in complex bit-field value */
+#define BF_CX_BCNT_POS 0U
+/** @brief Mask of bit count in complex bit-field value */
+#define BF_CX_BCNT_MASK (0xffU << BF_CX_BCNT_POS)
+/** @brief Position of bit position in complex bit-field value */
+#define BF_CX_BOFF_POS 8U
+/** @brief Mask of bit position in complex bit-field value */
+#define BF_CX_BOFF_MASK (0xffU << BF_CX_BOFF_POS)
+/** @} */
+
+/**
+ * @brief Define complex bit-field
+ *
+ * Complex bit-field would contain its position and size in one number.
+ * @sa BF_CX_MASK
+ * @sa BF_CX_POS
+ * @sa BF_CX_GET
+ *
+ * @param[in] bcnt Number of bits in the bit-field
+ * @param[in] boff Lowest bit number
+ *
+ * @return The single number that describes the bit-field completely.
+ */
+#define BF_CX(bcnt, boff) ( ((((uint32_t)(bcnt)) << BF_CX_BCNT_POS) & BF_CX_BCNT_MASK) | ((((uint32_t)(boff)) << BF_CX_BOFF_POS) & BF_CX_BOFF_MASK) )
+
+/**
+ * @brief Get number of bits in bit-field
+ *
+ * @sa BF_CX
+ *
+ * @param bf_cx Complex bit-field
+ *
+ * @return Number of bits in given bit-field
+ */
+#define BF_CX_BCNT(bf_cx) ( ((bf_cx) & BF_CX_BCNT_MASK) >> BF_CX_BCNT_POS )
+
+/**
+ * @brief Get lowest bit number in the field
+ *
+ * @sa BF_CX
+ *
+ * @param[in] bf_cx Complex bit-field
+ *
+ * @return Lowest bit number in given bit-field
+ */
+#define BF_CX_BOFF(bf_cx) ( ((bf_cx) & BF_CX_BOFF_MASK) >> BF_CX_BOFF_POS )
+
+/**
+ * @brief Get bit mask of the selected field
+ *
+ * @sa BF_CX
+ *
+ * @param[in] bf_cx Complex bit-field
+ *
+ * @return Mask of given bit-field
+ */
+#define BF_CX_MASK(bf_cx) BF_MASK(BF_CX_BCNT(bf_cx), BF_CX_BOFF(bf_cx))
+
+/**
+ * @brief Get bit-field
+ *
+ * Macro that extracts selected bit-field from provided value.
+ * Bit-field is given as a complex value.
+ *
+ * @sa BF_CX
+ * @sa BF_GET
+ *
+ * @param[in] val Value from witch selected bit-field would be extracted
+ * @param[in] bf_cx Complex bit-field
+ *
+ * @return Value of the selected bits.
+ */
+#define BF_CX_GET(val, bf_cx) BF_GET(val, BF_CX_BCNT(bf_cx), BF_CX_BOFF(bf_cx))
+
+/**
+ * @brief Create bit-field value
+ *
+ * Value is masked and shifted to match given bit-field.
+ *
+ * @param[in] val Value to set on bit-field
+ * @param[in] bf_cx Complex bit-field
+ *
+ * @return Value positioned of given bit-field.
+ */
+#define BF_CX_VAL(val, bf_cx) BF_VAL(val, BF_CX_BCNT(bf_cx), BF_CX_BOFF(bf_cx))
+
+/**
+ * @brief Extracting data from the brackets
+ *
+ * This macro get rid of brackets around the argument.
+ * It can be used to pass multiple arguments in logical one argument to a macro.
+ * Call it with arguments inside brackets:
+ * @code
+ * #define ARGUMENTS (a, b, c)
+ * BRACKET_EXTRACT(ARGUMENTS)
+ * @endcode
+ * It would produce:
+ * @code
+ * a, b, c
+ * @endcode
+ *
+ * @param a Argument with anything inside brackets
+ * @return Anything that appears inside the brackets of the argument
+ *
+ * @note
+ * The argument of the macro have to be inside brackets.
+ * In other case the compilation would fail.
+ */
+#define BRACKET_EXTRACT(a) BRACKET_EXTRACT_(a)
+#define BRACKET_EXTRACT_(a) BRACKET_EXTRACT__ a
+#define BRACKET_EXTRACT__(...) __VA_ARGS__
+
+
+/**
+ * @brief Check if number of parameters is more than 1
+ *
+ * @param ... Arguments to count
+ *
+ * @return 0 If argument count is <= 1
+ * @return 1 If argument count is > 1
+ *
+ * @sa NUM_VA_ARGS
+ * @sa NUM_IS_MORE_THAN_1
+ */
+#define NUM_VA_ARGS_IS_MORE_THAN_1(...) NUM_IS_MORE_THAN_1(NUM_VA_ARGS(__VA_ARGS__))
+
+/**
+ * @brief Check if given numeric value is bigger than 1
+ *
+ * This macro accepts numeric value, that may be the result of argument expansion.
+ * This numeric value is then converted to 0 if it is lover than 1 or to 1 if
+ * its value is higher than 1.
+ * The generated result can be used to glue it into other macro mnemonic name.
+ *
+ * @param N Numeric value to check
+ *
+ * @return 0 If argument is <= 1
+ * @return 1 If argument is > 1
+ *
+ * @note Any existing definition of a form NUM_IS_MORE_THAN_1_PROBE_[N] can
+ * broke the result of this macro
+ */
+#define NUM_IS_MORE_THAN_1(N) NUM_IS_MORE_THAN_1_(N)
+#define NUM_IS_MORE_THAN_1_(N) NUM_IS_MORE_THAN_1_PROBE_(NUM_IS_MORE_THAN_1_PROBE_ ## N, 1)
+#define NUM_IS_MORE_THAN_1_PROBE_(...) GET_VA_ARG_1(GET_ARGS_AFTER_1(__VA_ARGS__))
+#define NUM_IS_MORE_THAN_1_PROBE_0 ~, 0
+#define NUM_IS_MORE_THAN_1_PROBE_1 ~, 0
+
+/**
+ * @brief Get the first argument
+ *
+ * @param ... Arguments to select
+ *
+ * @return First argument or empty if no arguments are provided
+ */
+#define GET_VA_ARG_1(...) GET_VA_ARG_1_(__VA_ARGS__, ) // Make sure that also for 1 argument it works
+#define GET_VA_ARG_1_(a1, ...) a1
+
+/**
+ * @brief Get all the arguments but the first one
+ *
+ * @param ... Arguments to select
+ *
+ * @return All arguments after the first one or empty if less than 2 arguments are provided
+ */
+#define GET_ARGS_AFTER_1(...) GET_ARGS_AFTER_1_(__VA_ARGS__, ) // Make sure that also for 1 argument it works
+#define GET_ARGS_AFTER_1_(a1, ...) __VA_ARGS__
+
+/**
+ * @brief Size of a field in declared structure
+ *
+ * Macro that returns the size of the structure field.
+ * @param struct_type Variable type to get the field size from
+ * @param field Field name to analyze. It can be even field inside field (field.somethingelse.and_another).
+ *
+ * @return Size of the field
+ */
+#define FIELD_SIZE(struct_type, field) sizeof(((struct struct_type*)NULL)->field)
+
+/**
+ * @brief Number of elements in field array in declared structure
+ *
+ * Macro that returns number of elementy in structure field.
+ * @param struct_type Variable type to get the field size from
+ * @param field Field name to analyze.
+ *
+ * @return Number of elements in field array
+ *
+ * @sa FIELD_SIZE
+ */
+#define FIELD_ARRAY_SIZE(struct_type, field) (FIELD_SIZE(struct_type, field) / FIELD_SIZE(struct_type, field[0]))
+
+/**
+ * @brief Mapping macro
+ *
+ * Macro that process all arguments using given macro
+ *
+ * @param ... Macro name to be used for argument processing followed by arguments to process.
+ * Macro should have following form: MACRO(argument)
+ *
+ * @return All arguments processed by given macro
+ */
+#define MACRO_MAP(...) MACRO_MAP_(__VA_ARGS__)
+#define MACRO_MAP_(...) MACRO_MAP_N(NUM_VA_ARGS_LESS_1(__VA_ARGS__), __VA_ARGS__) // To make sure it works also for 2 arguments in total
+
+/**
+ * @brief Mapping macro, recursive version
+ *
+ * Can be used in @ref MACRO_MAP macro
+ */
+#define MACRO_MAP_REC(...) MACRO_MAP_REC_(__VA_ARGS__)
+#define MACRO_MAP_REC_(...) MACRO_MAP_REC_N(NUM_VA_ARGS_LESS_1(__VA_ARGS__), __VA_ARGS__) // To make sure it works also for 2 arguments in total
+/**
+ * @brief Mapping N arguments macro
+ *
+ * Macro similar to @ref MACRO_MAP but maps exact number of arguments.
+ * If there is more arguments given, the rest would be ignored.
+ *
+ * @param N Number of arguments to map
+ * @param ... Macro name to be used for argument processing followed by arguments to process.
+ * Macro should have following form: MACRO(argument)
+ *
+ * @return Selected number of arguments processed by given macro
+ */
+#define MACRO_MAP_N(N, ...) MACRO_MAP_N_(N, __VA_ARGS__)
+#define MACRO_MAP_N_(N, ...) CONCAT_2(MACRO_MAP_, N)(__VA_ARGS__, )
+
+/**
+ * @brief Mapping N arguments macro, recursive version
+ *
+ * Can be used in @ref MACRO_MAP_N macro
+ */
+#define MACRO_MAP_REC_N(N, ...) MACRO_MAP_REC_N_(N, __VA_ARGS__)
+#define MACRO_MAP_REC_N_(N, ...) CONCAT_2(MACRO_MAP_REC_, N)(__VA_ARGS__, )
+
+#define MACRO_MAP_0( ...)
+#define MACRO_MAP_1( macro, a, ...) macro(a)
+#define MACRO_MAP_2( macro, a, ...) macro(a) MACRO_MAP_1 (macro, __VA_ARGS__, )
+#define MACRO_MAP_3( macro, a, ...) macro(a) MACRO_MAP_2 (macro, __VA_ARGS__, )
+#define MACRO_MAP_4( macro, a, ...) macro(a) MACRO_MAP_3 (macro, __VA_ARGS__, )
+#define MACRO_MAP_5( macro, a, ...) macro(a) MACRO_MAP_4 (macro, __VA_ARGS__, )
+#define MACRO_MAP_6( macro, a, ...) macro(a) MACRO_MAP_5 (macro, __VA_ARGS__, )
+#define MACRO_MAP_7( macro, a, ...) macro(a) MACRO_MAP_6 (macro, __VA_ARGS__, )
+#define MACRO_MAP_8( macro, a, ...) macro(a) MACRO_MAP_7 (macro, __VA_ARGS__, )
+#define MACRO_MAP_9( macro, a, ...) macro(a) MACRO_MAP_8 (macro, __VA_ARGS__, )
+#define MACRO_MAP_10(macro, a, ...) macro(a) MACRO_MAP_9 (macro, __VA_ARGS__, )
+#define MACRO_MAP_11(macro, a, ...) macro(a) MACRO_MAP_10(macro, __VA_ARGS__, )
+#define MACRO_MAP_12(macro, a, ...) macro(a) MACRO_MAP_11(macro, __VA_ARGS__, )
+#define MACRO_MAP_13(macro, a, ...) macro(a) MACRO_MAP_12(macro, __VA_ARGS__, )
+#define MACRO_MAP_14(macro, a, ...) macro(a) MACRO_MAP_13(macro, __VA_ARGS__, )
+#define MACRO_MAP_15(macro, a, ...) macro(a) MACRO_MAP_14(macro, __VA_ARGS__, )
+
+#define MACRO_MAP_REC_0( ...)
+#define MACRO_MAP_REC_1( macro, a, ...) macro(a)
+#define MACRO_MAP_REC_2( macro, a, ...) macro(a) MACRO_MAP_REC_1 (macro, __VA_ARGS__, )
+#define MACRO_MAP_REC_3( macro, a, ...) macro(a) MACRO_MAP_REC_2 (macro, __VA_ARGS__, )
+#define MACRO_MAP_REC_4( macro, a, ...) macro(a) MACRO_MAP_REC_3 (macro, __VA_ARGS__, )
+#define MACRO_MAP_REC_5( macro, a, ...) macro(a) MACRO_MAP_REC_4 (macro, __VA_ARGS__, )
+#define MACRO_MAP_REC_6( macro, a, ...) macro(a) MACRO_MAP_REC_5 (macro, __VA_ARGS__, )
+#define MACRO_MAP_REC_7( macro, a, ...) macro(a) MACRO_MAP_REC_6 (macro, __VA_ARGS__, )
+#define MACRO_MAP_REC_8( macro, a, ...) macro(a) MACRO_MAP_REC_7 (macro, __VA_ARGS__, )
+#define MACRO_MAP_REC_9( macro, a, ...) macro(a) MACRO_MAP_REC_8 (macro, __VA_ARGS__, )
+#define MACRO_MAP_REC_10(macro, a, ...) macro(a) MACRO_MAP_REC_9 (macro, __VA_ARGS__, )
+#define MACRO_MAP_REC_11(macro, a, ...) macro(a) MACRO_MAP_REC_10(macro, __VA_ARGS__, )
+#define MACRO_MAP_REC_12(macro, a, ...) macro(a) MACRO_MAP_REC_11(macro, __VA_ARGS__, )
+#define MACRO_MAP_REC_13(macro, a, ...) macro(a) MACRO_MAP_REC_12(macro, __VA_ARGS__, )
+#define MACRO_MAP_REC_14(macro, a, ...) macro(a) MACRO_MAP_REC_13(macro, __VA_ARGS__, )
+#define MACRO_MAP_REC_15(macro, a, ...) macro(a) MACRO_MAP_REC_14(macro, __VA_ARGS__, )
+
+/**
+ * @brief Mapping macro with current index
+ *
+ * Basically macro similar to @ref MACRO_MAP, but the processing function would get an argument
+ * and current argument index (beginning from 0).
+ *
+ * @param ... Macro name to be used for argument processing followed by arguments to process.
+ * Macro should have following form: MACRO(argument, index)
+ * @return All arguments processed by given macro
+ */
+#define MACRO_MAP_FOR(...) MACRO_MAP_FOR_(__VA_ARGS__)
+#define MACRO_MAP_FOR_N_LIST 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15
+#define MACRO_MAP_FOR_(...) MACRO_MAP_FOR_N(NUM_VA_ARGS_LESS_1(__VA_ARGS__), __VA_ARGS__)
+
+/**
+ * @brief Mapping N arguments macro with current index
+ *
+ * Macro is similar to @ref MACRO_MAP_FOR but maps exact number of arguments.
+ * If there is more arguments given, the rest would be ignored.
+ *
+ * @param N Number of arguments to map
+ * @param ... Macro name to be used for argument processing followed by arguments to process.
+ * Macro should have following form: MACRO(argument, index)
+ *
+ * @return Selected number of arguments processed by given macro
+ */
+#define MACRO_MAP_FOR_N(N, ...) MACRO_MAP_FOR_N_(N, __VA_ARGS__)
+#define MACRO_MAP_FOR_N_(N, ...) CONCAT_2(MACRO_MAP_FOR_, N)((MACRO_MAP_FOR_N_LIST), __VA_ARGS__, )
+
+#define MACRO_MAP_FOR_0( n_list, ...)
+#define MACRO_MAP_FOR_1( n_list, macro, a, ...) macro(a, GET_VA_ARG_1(BRACKET_EXTRACT(n_list)))
+#define MACRO_MAP_FOR_2( n_list, macro, a, ...) macro(a, GET_VA_ARG_1(BRACKET_EXTRACT(n_list))) MACRO_MAP_FOR_1 ((GET_ARGS_AFTER_1(BRACKET_EXTRACT(n_list))), macro, __VA_ARGS__, )
+#define MACRO_MAP_FOR_3( n_list, macro, a, ...) macro(a, GET_VA_ARG_1(BRACKET_EXTRACT(n_list))) MACRO_MAP_FOR_2 ((GET_ARGS_AFTER_1(BRACKET_EXTRACT(n_list))), macro, __VA_ARGS__, )
+#define MACRO_MAP_FOR_4( n_list, macro, a, ...) macro(a, GET_VA_ARG_1(BRACKET_EXTRACT(n_list))) MACRO_MAP_FOR_3 ((GET_ARGS_AFTER_1(BRACKET_EXTRACT(n_list))), macro, __VA_ARGS__, )
+#define MACRO_MAP_FOR_5( n_list, macro, a, ...) macro(a, GET_VA_ARG_1(BRACKET_EXTRACT(n_list))) MACRO_MAP_FOR_4 ((GET_ARGS_AFTER_1(BRACKET_EXTRACT(n_list))), macro, __VA_ARGS__, )
+#define MACRO_MAP_FOR_6( n_list, macro, a, ...) macro(a, GET_VA_ARG_1(BRACKET_EXTRACT(n_list))) MACRO_MAP_FOR_5 ((GET_ARGS_AFTER_1(BRACKET_EXTRACT(n_list))), macro, __VA_ARGS__, )
+#define MACRO_MAP_FOR_7( n_list, macro, a, ...) macro(a, GET_VA_ARG_1(BRACKET_EXTRACT(n_list))) MACRO_MAP_FOR_6 ((GET_ARGS_AFTER_1(BRACKET_EXTRACT(n_list))), macro, __VA_ARGS__, )
+#define MACRO_MAP_FOR_8( n_list, macro, a, ...) macro(a, GET_VA_ARG_1(BRACKET_EXTRACT(n_list))) MACRO_MAP_FOR_7 ((GET_ARGS_AFTER_1(BRACKET_EXTRACT(n_list))), macro, __VA_ARGS__, )
+#define MACRO_MAP_FOR_9( n_list, macro, a, ...) macro(a, GET_VA_ARG_1(BRACKET_EXTRACT(n_list))) MACRO_MAP_FOR_8 ((GET_ARGS_AFTER_1(BRACKET_EXTRACT(n_list))), macro, __VA_ARGS__, )
+#define MACRO_MAP_FOR_10(n_list, macro, a, ...) macro(a, GET_VA_ARG_1(BRACKET_EXTRACT(n_list))) MACRO_MAP_FOR_9 ((GET_ARGS_AFTER_1(BRACKET_EXTRACT(n_list))), macro, __VA_ARGS__, )
+#define MACRO_MAP_FOR_11(n_list, macro, a, ...) macro(a, GET_VA_ARG_1(BRACKET_EXTRACT(n_list))) MACRO_MAP_FOR_10((GET_ARGS_AFTER_1(BRACKET_EXTRACT(n_list))), macro, __VA_ARGS__, )
+#define MACRO_MAP_FOR_12(n_list, macro, a, ...) macro(a, GET_VA_ARG_1(BRACKET_EXTRACT(n_list))) MACRO_MAP_FOR_11((GET_ARGS_AFTER_1(BRACKET_EXTRACT(n_list))), macro, __VA_ARGS__, )
+#define MACRO_MAP_FOR_13(n_list, macro, a, ...) macro(a, GET_VA_ARG_1(BRACKET_EXTRACT(n_list))) MACRO_MAP_FOR_12((GET_ARGS_AFTER_1(BRACKET_EXTRACT(n_list))), macro, __VA_ARGS__, )
+#define MACRO_MAP_FOR_14(n_list, macro, a, ...) macro(a, GET_VA_ARG_1(BRACKET_EXTRACT(n_list))) MACRO_MAP_FOR_13((GET_ARGS_AFTER_1(BRACKET_EXTRACT(n_list))), macro, __VA_ARGS__, )
+#define MACRO_MAP_FOR_15(n_list, macro, a, ...) macro(a, GET_VA_ARG_1(BRACKET_EXTRACT(n_list))) MACRO_MAP_FOR_14((GET_ARGS_AFTER_1(BRACKET_EXTRACT(n_list))), macro, __VA_ARGS__, )
+
+
+/**
+ * @brief Mapping macro with current index and parameter
+ *
+ * Version of @ref MACRO_MAP_FOR that passes also the same parameter to all macros.
+ *
+ * @param param Parameter that would be passed to each macro call during mapping.
+ * @param ... Macro name to be used for argument processing followed by arguments to process.
+ * Macro should have following form: MACRO(argument, index, param)
+ *
+ * @return All arguments processed by given macro
+ */
+#define MACRO_MAP_FOR_PARAM(param, ...) MACRO_MAP_FOR_PARAM_(param, __VA_ARGS__)
+#define MACRO_MAP_FOR_PARAM_(param, ...) MACRO_MAP_FOR_PARAM_N(NUM_VA_ARGS_LESS_1(__VA_ARGS__), param, __VA_ARGS__)
+
+/**
+ * @brief Mapping N arguments macro with with current index and parameter
+ *
+ * @param N Number of arguments to map
+ * @param param Parameter that would be passed to each macro call during mapping.
+ * @param ... Macro name to be used for argument processing followed by arguments to process.
+ * Macro should have following form: MACRO(argument, index, param)
+ *
+ * @return All arguments processed by given macro
+ */
+#define MACRO_MAP_FOR_PARAM_N(N, param, ...) MACRO_MAP_FOR_PARAM_N_(N, param, __VA_ARGS__)
+#define MACRO_MAP_FOR_PARAM_N_(N, param, ...) CONCAT_2(MACRO_MAP_FOR_PARAM_, N)((MACRO_MAP_FOR_N_LIST), param, __VA_ARGS__, )
+
+
+#define MACRO_MAP_FOR_PARAM_0( n_list, param, ...)
+#define MACRO_MAP_FOR_PARAM_1( n_list, param, macro, a, ...) macro(a, GET_VA_ARG_1(BRACKET_EXTRACT(n_list)), param)
+#define MACRO_MAP_FOR_PARAM_2( n_list, param, macro, a, ...) macro(a, GET_VA_ARG_1(BRACKET_EXTRACT(n_list)), param) MACRO_MAP_FOR_PARAM_1 ((GET_ARGS_AFTER_1(BRACKET_EXTRACT(n_list))), param, macro, __VA_ARGS__, )
+#define MACRO_MAP_FOR_PARAM_3( n_list, param, macro, a, ...) macro(a, GET_VA_ARG_1(BRACKET_EXTRACT(n_list)), param) MACRO_MAP_FOR_PARAM_2 ((GET_ARGS_AFTER_1(BRACKET_EXTRACT(n_list))), param, macro, __VA_ARGS__, )
+#define MACRO_MAP_FOR_PARAM_4( n_list, param, macro, a, ...) macro(a, GET_VA_ARG_1(BRACKET_EXTRACT(n_list)), param) MACRO_MAP_FOR_PARAM_3 ((GET_ARGS_AFTER_1(BRACKET_EXTRACT(n_list))), param, macro, __VA_ARGS__, )
+#define MACRO_MAP_FOR_PARAM_5( n_list, param, macro, a, ...) macro(a, GET_VA_ARG_1(BRACKET_EXTRACT(n_list)), param) MACRO_MAP_FOR_PARAM_4 ((GET_ARGS_AFTER_1(BRACKET_EXTRACT(n_list))), param, macro, __VA_ARGS__, )
+#define MACRO_MAP_FOR_PARAM_6( n_list, param, macro, a, ...) macro(a, GET_VA_ARG_1(BRACKET_EXTRACT(n_list)), param) MACRO_MAP_FOR_PARAM_5 ((GET_ARGS_AFTER_1(BRACKET_EXTRACT(n_list))), param, macro, __VA_ARGS__, )
+#define MACRO_MAP_FOR_PARAM_7( n_list, param, macro, a, ...) macro(a, GET_VA_ARG_1(BRACKET_EXTRACT(n_list)), param) MACRO_MAP_FOR_PARAM_6 ((GET_ARGS_AFTER_1(BRACKET_EXTRACT(n_list))), param, macro, __VA_ARGS__, )
+#define MACRO_MAP_FOR_PARAM_8( n_list, param, macro, a, ...) macro(a, GET_VA_ARG_1(BRACKET_EXTRACT(n_list)), param) MACRO_MAP_FOR_PARAM_7 ((GET_ARGS_AFTER_1(BRACKET_EXTRACT(n_list))), param, macro, __VA_ARGS__, )
+#define MACRO_MAP_FOR_PARAM_9( n_list, param, macro, a, ...) macro(a, GET_VA_ARG_1(BRACKET_EXTRACT(n_list)), param) MACRO_MAP_FOR_PARAM_8 ((GET_ARGS_AFTER_1(BRACKET_EXTRACT(n_list))), param, macro, __VA_ARGS__, )
+#define MACRO_MAP_FOR_PARAM_10(n_list, param, macro, a, ...) macro(a, GET_VA_ARG_1(BRACKET_EXTRACT(n_list)), param) MACRO_MAP_FOR_PARAM_9 ((GET_ARGS_AFTER_1(BRACKET_EXTRACT(n_list))), param, macro, __VA_ARGS__, )
+#define MACRO_MAP_FOR_PARAM_11(n_list, param, macro, a, ...) macro(a, GET_VA_ARG_1(BRACKET_EXTRACT(n_list)), param) MACRO_MAP_FOR_PARAM_10((GET_ARGS_AFTER_1(BRACKET_EXTRACT(n_list))), param, macro, __VA_ARGS__, )
+#define MACRO_MAP_FOR_PARAM_12(n_list, param, macro, a, ...) macro(a, GET_VA_ARG_1(BRACKET_EXTRACT(n_list)), param) MACRO_MAP_FOR_PARAM_11((GET_ARGS_AFTER_1(BRACKET_EXTRACT(n_list))), param, macro, __VA_ARGS__, )
+#define MACRO_MAP_FOR_PARAM_13(n_list, param, macro, a, ...) macro(a, GET_VA_ARG_1(BRACKET_EXTRACT(n_list)), param) MACRO_MAP_FOR_PARAM_12((GET_ARGS_AFTER_1(BRACKET_EXTRACT(n_list))), param, macro, __VA_ARGS__, )
+#define MACRO_MAP_FOR_PARAM_14(n_list, param, macro, a, ...) macro(a, GET_VA_ARG_1(BRACKET_EXTRACT(n_list)), param) MACRO_MAP_FOR_PARAM_13((GET_ARGS_AFTER_1(BRACKET_EXTRACT(n_list))), param, macro, __VA_ARGS__, )
+#define MACRO_MAP_FOR_PARAM_15(n_list, param, macro, a, ...) macro(a, GET_VA_ARG_1(BRACKET_EXTRACT(n_list)), param) MACRO_MAP_FOR_PARAM_14((GET_ARGS_AFTER_1(BRACKET_EXTRACT(n_list))), param, macro, __VA_ARGS__, )
+
+
+/**
+ * @brief Repeating macro.
+ *
+ * @param count Count of repeats.
+ * @param macro Macro must have the following form: MACRO(arguments).
+ * @param ... Arguments passed to the macro.
+ *
+ * @return All arguments processed by the given macro.
+ */
+#define MACRO_REPEAT(count, macro, ...) MACRO_REPEAT_(count, macro, __VA_ARGS__)
+#define MACRO_REPEAT_(count, macro, ...) CONCAT_2(MACRO_REPEAT_, count)(macro, __VA_ARGS__)
+
+#define MACRO_REPEAT_0(macro, ...)
+#define MACRO_REPEAT_1(macro, ...) macro(__VA_ARGS__) MACRO_REPEAT_0(macro, __VA_ARGS__)
+#define MACRO_REPEAT_2(macro, ...) macro(__VA_ARGS__) MACRO_REPEAT_1(macro, __VA_ARGS__)
+#define MACRO_REPEAT_3(macro, ...) macro(__VA_ARGS__) MACRO_REPEAT_2(macro, __VA_ARGS__)
+#define MACRO_REPEAT_4(macro, ...) macro(__VA_ARGS__) MACRO_REPEAT_3(macro, __VA_ARGS__)
+#define MACRO_REPEAT_5(macro, ...) macro(__VA_ARGS__) MACRO_REPEAT_4(macro, __VA_ARGS__)
+#define MACRO_REPEAT_6(macro, ...) macro(__VA_ARGS__) MACRO_REPEAT_5(macro, __VA_ARGS__)
+#define MACRO_REPEAT_7(macro, ...) macro(__VA_ARGS__) MACRO_REPEAT_6(macro, __VA_ARGS__)
+#define MACRO_REPEAT_8(macro, ...) macro(__VA_ARGS__) MACRO_REPEAT_7(macro, __VA_ARGS__)
+#define MACRO_REPEAT_9(macro, ...) macro(__VA_ARGS__) MACRO_REPEAT_8(macro, __VA_ARGS__)
+#define MACRO_REPEAT_10(macro, ...) macro(__VA_ARGS__) MACRO_REPEAT_9(macro, __VA_ARGS__)
+#define MACRO_REPEAT_11(macro, ...) macro(__VA_ARGS__) MACRO_REPEAT_10(macro, __VA_ARGS__)
+#define MACRO_REPEAT_12(macro, ...) macro(__VA_ARGS__) MACRO_REPEAT_11(macro, __VA_ARGS__)
+#define MACRO_REPEAT_13(macro, ...) macro(__VA_ARGS__) MACRO_REPEAT_12(macro, __VA_ARGS__)
+#define MACRO_REPEAT_14(macro, ...) macro(__VA_ARGS__) MACRO_REPEAT_13(macro, __VA_ARGS__)
+#define MACRO_REPEAT_15(macro, ...) macro(__VA_ARGS__) MACRO_REPEAT_14(macro, __VA_ARGS__)
+
+
+/**
+ * @brief Repeating macro with current index.
+ *
+ * Macro similar to @ref MACRO_REPEAT but the processing function gets the arguments
+ * and the current argument index (beginning from 0).
+
+ * @param count Count of repeats.
+ * @param macro Macro must have the following form: MACRO(index, arguments).
+ * @param ... Arguments passed to the macro.
+ *
+ * @return All arguments processed by the given macro.
+ */
+#define MACRO_REPEAT_FOR(count, macro, ...) MACRO_REPEAT_FOR_(count, macro, __VA_ARGS__)
+#define MACRO_REPEAT_FOR_(count, macro, ...) CONCAT_2(MACRO_REPEAT_FOR_, count)((MACRO_MAP_FOR_N_LIST), macro, __VA_ARGS__)
+
+#define MACRO_REPEAT_FOR_0(n_list, macro, ...)
+#define MACRO_REPEAT_FOR_1(n_list, macro, ...) macro(GET_VA_ARG_1(BRACKET_EXTRACT(n_list)), __VA_ARGS__) MACRO_REPEAT_FOR_0((GET_ARGS_AFTER_1(BRACKET_EXTRACT(n_list))), macro, __VA_ARGS__)
+#define MACRO_REPEAT_FOR_2(n_list, macro, ...) macro(GET_VA_ARG_1(BRACKET_EXTRACT(n_list)), __VA_ARGS__) MACRO_REPEAT_FOR_1((GET_ARGS_AFTER_1(BRACKET_EXTRACT(n_list))), macro, __VA_ARGS__)
+#define MACRO_REPEAT_FOR_3(n_list, macro, ...) macro(GET_VA_ARG_1(BRACKET_EXTRACT(n_list)), __VA_ARGS__) MACRO_REPEAT_FOR_2((GET_ARGS_AFTER_1(BRACKET_EXTRACT(n_list))), macro, __VA_ARGS__)
+#define MACRO_REPEAT_FOR_4(n_list, macro, ...) macro(GET_VA_ARG_1(BRACKET_EXTRACT(n_list)), __VA_ARGS__) MACRO_REPEAT_FOR_3((GET_ARGS_AFTER_1(BRACKET_EXTRACT(n_list))), macro, __VA_ARGS__)
+#define MACRO_REPEAT_FOR_5(n_list, macro, ...) macro(GET_VA_ARG_1(BRACKET_EXTRACT(n_list)), __VA_ARGS__) MACRO_REPEAT_FOR_4((GET_ARGS_AFTER_1(BRACKET_EXTRACT(n_list))), macro, __VA_ARGS__)
+#define MACRO_REPEAT_FOR_6(n_list, macro, ...) macro(GET_VA_ARG_1(BRACKET_EXTRACT(n_list)), __VA_ARGS__) MACRO_REPEAT_FOR_5((GET_ARGS_AFTER_1(BRACKET_EXTRACT(n_list))), macro, __VA_ARGS__)
+#define MACRO_REPEAT_FOR_7(n_list, macro, ...) macro(GET_VA_ARG_1(BRACKET_EXTRACT(n_list)), __VA_ARGS__) MACRO_REPEAT_FOR_6((GET_ARGS_AFTER_1(BRACKET_EXTRACT(n_list))), macro, __VA_ARGS__)
+#define MACRO_REPEAT_FOR_8(n_list, macro, ...) macro(GET_VA_ARG_1(BRACKET_EXTRACT(n_list)), __VA_ARGS__) MACRO_REPEAT_FOR_7((GET_ARGS_AFTER_1(BRACKET_EXTRACT(n_list))), macro, __VA_ARGS__)
+#define MACRO_REPEAT_FOR_9(n_list, macro, ...) macro(GET_VA_ARG_1(BRACKET_EXTRACT(n_list)), __VA_ARGS__) MACRO_REPEAT_FOR_8((GET_ARGS_AFTER_1(BRACKET_EXTRACT(n_list))), macro, __VA_ARGS__)
+#define MACRO_REPEAT_FOR_10(n_list, macro, ...) macro(GET_VA_ARG_1(BRACKET_EXTRACT(n_list)), __VA_ARGS__) MACRO_REPEAT_FOR_9((GET_ARGS_AFTER_1(BRACKET_EXTRACT(n_list))), macro, __VA_ARGS__)
+#define MACRO_REPEAT_FOR_11(n_list, macro, ...) macro(GET_VA_ARG_1(BRACKET_EXTRACT(n_list)), __VA_ARGS__) MACRO_REPEAT_FOR_10((GET_ARGS_AFTER_1(BRACKET_EXTRACT(n_list))), macro, __VA_ARGS__)
+#define MACRO_REPEAT_FOR_12(n_list, macro, ...) macro(GET_VA_ARG_1(BRACKET_EXTRACT(n_list)), __VA_ARGS__) MACRO_REPEAT_FOR_11((GET_ARGS_AFTER_1(BRACKET_EXTRACT(n_list))), macro, __VA_ARGS__)
+#define MACRO_REPEAT_FOR_13(n_list, macro, ...) macro(GET_VA_ARG_1(BRACKET_EXTRACT(n_list)), __VA_ARGS__) MACRO_REPEAT_FOR_12((GET_ARGS_AFTER_1(BRACKET_EXTRACT(n_list))), macro, __VA_ARGS__)
+#define MACRO_REPEAT_FOR_14(n_list, macro, ...) macro(GET_VA_ARG_1(BRACKET_EXTRACT(n_list)), __VA_ARGS__) MACRO_REPEAT_FOR_13((GET_ARGS_AFTER_1(BRACKET_EXTRACT(n_list))), macro, __VA_ARGS__)
+#define MACRO_REPEAT_FOR_15(n_list, macro, ...) macro(GET_VA_ARG_1(BRACKET_EXTRACT(n_list)), __VA_ARGS__) MACRO_REPEAT_FOR_14((GET_ARGS_AFTER_1(BRACKET_EXTRACT(n_list))), macro, __VA_ARGS__)
+
+/**@brief Adding curly brace to the macro parameter.
+ *
+ * Useful in array of structures initialization.
+ *
+ * @param p Parameter to put into the curly brace. */
+#define PARAM_CBRACE(p) { p },
+
+
+/**@brief Function for changing the value unit.
+ *
+ * @param[in] value Value to be rescaled.
+ * @param[in] old_unit_reversal Reversal of the incoming unit.
+ * @param[in] new_unit_reversal Reversal of the desired unit.
+ *
+ * @return Number of bytes written.
+ */
+static __INLINE uint64_t value_rescale(uint32_t value, uint32_t old_unit_reversal, uint16_t new_unit_reversal)
+{
+ return (uint64_t)ROUNDED_DIV((uint64_t)value * new_unit_reversal, old_unit_reversal);
+}
+
+/**@brief Function for encoding a uint16 value.
+ *
+ * @param[in] value Value to be encoded.
+ * @param[out] p_encoded_data Buffer where the encoded data is to be written.
+ *
+ * @return Number of bytes written.
+ */
+static __INLINE uint8_t uint16_encode(uint16_t value, uint8_t * p_encoded_data)
+{
+ p_encoded_data[0] = (uint8_t) ((value & 0x00FF) >> 0);
+ p_encoded_data[1] = (uint8_t) ((value & 0xFF00) >> 8);
+ return sizeof(uint16_t);
+}
+
+/**@brief Function for encoding a three-byte value.
+ *
+ * @param[in] value Value to be encoded.
+ * @param[out] p_encoded_data Buffer where the encoded data is to be written.
+ *
+ * @return Number of bytes written.
+ */
+static __INLINE uint8_t uint24_encode(uint32_t value, uint8_t * p_encoded_data)
+{
+ p_encoded_data[0] = (uint8_t) ((value & 0x000000FF) >> 0);
+ p_encoded_data[1] = (uint8_t) ((value & 0x0000FF00) >> 8);
+ p_encoded_data[2] = (uint8_t) ((value & 0x00FF0000) >> 16);
+ return 3;
+}
+
+/**@brief Function for encoding a uint32 value.
+ *
+ * @param[in] value Value to be encoded.
+ * @param[out] p_encoded_data Buffer where the encoded data is to be written.
+ *
+ * @return Number of bytes written.
+ */
+static __INLINE uint8_t uint32_encode(uint32_t value, uint8_t * p_encoded_data)
+{
+ p_encoded_data[0] = (uint8_t) ((value & 0x000000FF) >> 0);
+ p_encoded_data[1] = (uint8_t) ((value & 0x0000FF00) >> 8);
+ p_encoded_data[2] = (uint8_t) ((value & 0x00FF0000) >> 16);
+ p_encoded_data[3] = (uint8_t) ((value & 0xFF000000) >> 24);
+ return sizeof(uint32_t);
+}
+
+/**@brief Function for encoding a uint40 value.
+ *
+ * @param[in] value Value to be encoded.
+ * @param[out] p_encoded_data Buffer where the encoded data is to be written.
+ *
+ * @return Number of bytes written.
+ */
+static __INLINE uint8_t uint40_encode(uint64_t value, uint8_t * p_encoded_data)
+{
+ p_encoded_data[0] = (uint8_t) ((value & 0x00000000FF) >> 0);
+ p_encoded_data[1] = (uint8_t) ((value & 0x000000FF00) >> 8);
+ p_encoded_data[2] = (uint8_t) ((value & 0x0000FF0000) >> 16);
+ p_encoded_data[3] = (uint8_t) ((value & 0x00FF000000) >> 24);
+ p_encoded_data[4] = (uint8_t) ((value & 0xFF00000000) >> 32);
+ return 5;
+}
+
+/**@brief Function for encoding a uint48 value.
+ *
+ * @param[in] value Value to be encoded.
+ * @param[out] p_encoded_data Buffer where the encoded data is to be written.
+ *
+ * @return Number of bytes written.
+ */
+static __INLINE uint8_t uint48_encode(uint64_t value, uint8_t * p_encoded_data)
+{
+ p_encoded_data[0] = (uint8_t) ((value & 0x0000000000FF) >> 0);
+ p_encoded_data[1] = (uint8_t) ((value & 0x00000000FF00) >> 8);
+ p_encoded_data[2] = (uint8_t) ((value & 0x000000FF0000) >> 16);
+ p_encoded_data[3] = (uint8_t) ((value & 0x0000FF000000) >> 24);
+ p_encoded_data[4] = (uint8_t) ((value & 0x00FF00000000) >> 32);
+ p_encoded_data[5] = (uint8_t) ((value & 0xFF0000000000) >> 40);
+ return 6;
+}
+
+/**@brief Function for decoding a uint16 value.
+ *
+ * @param[in] p_encoded_data Buffer where the encoded data is stored.
+ *
+ * @return Decoded value.
+ */
+static __INLINE uint16_t uint16_decode(const uint8_t * p_encoded_data)
+{
+ return ( (((uint16_t)((uint8_t *)p_encoded_data)[0])) |
+ (((uint16_t)((uint8_t *)p_encoded_data)[1]) << 8 ));
+}
+
+/**@brief Function for decoding a uint16 value in big-endian format.
+ *
+ * @param[in] p_encoded_data Buffer where the encoded data is stored.
+ *
+ * @return Decoded value.
+ */
+static __INLINE uint16_t uint16_big_decode(const uint8_t * p_encoded_data)
+{
+ return ( (((uint16_t)((uint8_t *)p_encoded_data)[0]) << 8 ) |
+ (((uint16_t)((uint8_t *)p_encoded_data)[1])) );
+}
+
+/**@brief Function for decoding a three-byte value.
+ *
+ * @param[in] p_encoded_data Buffer where the encoded data is stored.
+ *
+ * @return Decoded value (uint32_t).
+ */
+static __INLINE uint32_t uint24_decode(const uint8_t * p_encoded_data)
+{
+ return ( (((uint32_t)((uint8_t *)p_encoded_data)[0]) << 0) |
+ (((uint32_t)((uint8_t *)p_encoded_data)[1]) << 8) |
+ (((uint32_t)((uint8_t *)p_encoded_data)[2]) << 16));
+}
+
+/**@brief Function for decoding a uint32 value.
+ *
+ * @param[in] p_encoded_data Buffer where the encoded data is stored.
+ *
+ * @return Decoded value.
+ */
+static __INLINE uint32_t uint32_decode(const uint8_t * p_encoded_data)
+{
+ return ( (((uint32_t)((uint8_t *)p_encoded_data)[0]) << 0) |
+ (((uint32_t)((uint8_t *)p_encoded_data)[1]) << 8) |
+ (((uint32_t)((uint8_t *)p_encoded_data)[2]) << 16) |
+ (((uint32_t)((uint8_t *)p_encoded_data)[3]) << 24 ));
+}
+
+/**@brief Function for decoding a uint32 value in big-endian format.
+ *
+ * @param[in] p_encoded_data Buffer where the encoded data is stored.
+ *
+ * @return Decoded value.
+ */
+static __INLINE uint32_t uint32_big_decode(const uint8_t * p_encoded_data)
+{
+ return ( (((uint32_t)((uint8_t *)p_encoded_data)[0]) << 24) |
+ (((uint32_t)((uint8_t *)p_encoded_data)[1]) << 16) |
+ (((uint32_t)((uint8_t *)p_encoded_data)[2]) << 8) |
+ (((uint32_t)((uint8_t *)p_encoded_data)[3]) << 0) );
+}
+
+/**
+ * @brief Function for encoding an uint16 value in big-endian format.
+ *
+ * @param[in] value Value to be encoded.
+ * @param[out] p_encoded_data Buffer where the encoded data will be written.
+ *
+ * @return Number of bytes written.
+ */
+static __INLINE uint8_t uint16_big_encode(uint16_t value, uint8_t * p_encoded_data)
+{
+ p_encoded_data[0] = (uint8_t) (value >> 8);
+ p_encoded_data[1] = (uint8_t) (value & 0xFF);
+
+ return sizeof(uint16_t);
+}
+
+/*lint -esym(526, __rev) */
+/*lint -esym(628, __rev) */
+/**@brief Function for encoding a uint32 value in big-endian format.
+ *
+ * @param[in] value Value to be encoded.
+ * @param[out] p_encoded_data Buffer where the encoded data will be written.
+ *
+ * @return Number of bytes written.
+ */
+static __INLINE uint8_t uint32_big_encode(uint32_t value, uint8_t * p_encoded_data)
+{
+ *(uint32_t *)p_encoded_data = __REV(value);
+ return sizeof(uint32_t);
+}
+
+/**@brief Function for decoding a uint40 value.
+ *
+ * @param[in] p_encoded_data Buffer where the encoded data is stored.
+ *
+ * @return Decoded value. (uint64_t)
+ */
+static __INLINE uint64_t uint40_decode(const uint8_t * p_encoded_data)
+{
+ return ( (((uint64_t)((uint8_t *)p_encoded_data)[0]) << 0) |
+ (((uint64_t)((uint8_t *)p_encoded_data)[1]) << 8) |
+ (((uint64_t)((uint8_t *)p_encoded_data)[2]) << 16) |
+ (((uint64_t)((uint8_t *)p_encoded_data)[3]) << 24) |
+ (((uint64_t)((uint8_t *)p_encoded_data)[4]) << 32 ));
+}
+
+/**@brief Function for decoding a uint48 value.
+ *
+ * @param[in] p_encoded_data Buffer where the encoded data is stored.
+ *
+ * @return Decoded value. (uint64_t)
+ */
+static __INLINE uint64_t uint48_decode(const uint8_t * p_encoded_data)
+{
+ return ( (((uint64_t)((uint8_t *)p_encoded_data)[0]) << 0) |
+ (((uint64_t)((uint8_t *)p_encoded_data)[1]) << 8) |
+ (((uint64_t)((uint8_t *)p_encoded_data)[2]) << 16) |
+ (((uint64_t)((uint8_t *)p_encoded_data)[3]) << 24) |
+ (((uint64_t)((uint8_t *)p_encoded_data)[4]) << 32) |
+ (((uint64_t)((uint8_t *)p_encoded_data)[5]) << 40 ));
+}
+
+/** @brief Function for converting the input voltage (in milli volts) into percentage of 3.0 Volts.
+ *
+ * @details The calculation is based on a linearized version of the battery's discharge
+ * curve. 3.0V returns 100% battery level. The limit for power failure is 2.1V and
+ * is considered to be the lower boundary.
+ *
+ * The discharge curve for CR2032 is non-linear. In this model it is split into
+ * 4 linear sections:
+ * - Section 1: 3.0V - 2.9V = 100% - 42% (58% drop on 100 mV)
+ * - Section 2: 2.9V - 2.74V = 42% - 18% (24% drop on 160 mV)
+ * - Section 3: 2.74V - 2.44V = 18% - 6% (12% drop on 300 mV)
+ * - Section 4: 2.44V - 2.1V = 6% - 0% (6% drop on 340 mV)
+ *
+ * These numbers are by no means accurate. Temperature and
+ * load in the actual application is not accounted for!
+ *
+ * @param[in] mvolts The voltage in mV
+ *
+ * @return Battery level in percent.
+*/
+static __INLINE uint8_t battery_level_in_percent(const uint16_t mvolts)
+{
+ uint8_t battery_level;
+
+ if (mvolts >= 3000)
+ {
+ battery_level = 100;
+ }
+ else if (mvolts > 2900)
+ {
+ battery_level = 100 - ((3000 - mvolts) * 58) / 100;
+ }
+ else if (mvolts > 2740)
+ {
+ battery_level = 42 - ((2900 - mvolts) * 24) / 160;
+ }
+ else if (mvolts > 2440)
+ {
+ battery_level = 18 - ((2740 - mvolts) * 12) / 300;
+ }
+ else if (mvolts > 2100)
+ {
+ battery_level = 6 - ((2440 - mvolts) * 6) / 340;
+ }
+ else
+ {
+ battery_level = 0;
+ }
+
+ return battery_level;
+}
+
+/**@brief Function for checking if a pointer value is aligned to a 4 byte boundary.
+ *
+ * @param[in] p Pointer value to be checked.
+ *
+ * @return TRUE if pointer is aligned to a 4 byte boundary, FALSE otherwise.
+ */
+static __INLINE bool is_word_aligned(void const* p)
+{
+ return (((uintptr_t)p & 0x03) == 0);
+}
+
+/*lint -e{568, 685} */
+/**
+ * @brief Function for checking if provided address is located in stack space.
+ *
+ * @param[in] ptr Pointer to be checked.
+ *
+ * @return true if address is in stack space, false otherwise.
+ */
+static __INLINE bool is_address_from_stack(void * ptr)
+{
+ if (((uint32_t)ptr >= (uint32_t)STACK_BASE) &&
+ ((uint32_t)ptr < (uint32_t)STACK_TOP) )
+ {
+ return true;
+ }
+ else
+ {
+ return false;
+ }
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // APP_UTIL_H__
+
+/** @} */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/util/app_util_bds.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/util/app_util_bds.h
new file mode 100644
index 0000000..24ae12f
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/util/app_util_bds.h
@@ -0,0 +1,449 @@
+/**
+ * Copyright (c) 2012 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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
+ *
+ * @defgroup app_util Utility Functions and Definitions
+ * @{
+ * @ingroup app_common
+ *
+ * @brief Various types and definitions available to all applications.
+ */
+
+#ifndef APP_UTIL_BDS_H__
+#define APP_UTIL_BDS_H__
+
+#include <stdint.h>
+#include <string.h>
+#include <stdbool.h>
+#include "compiler_abstraction.h"
+#include "app_util.h"
+#include "ble_srv_common.h"
+#include "nordic_common.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef uint8_t nibble_t;
+typedef uint32_t uint24_t;
+typedef uint64_t uint40_t;
+
+/**@brief IEEE 11073-20601 Regulatory Certification Data List Structure */
+typedef struct
+{
+ uint8_t * p_list; /**< Pointer the byte array containing the encoded opaque structure based on IEEE 11073-20601 specification. */
+ uint8_t list_len; /**< Length of the byte array. */
+} regcertdatalist_t;
+
+/**@brief SFLOAT format (IEEE-11073 16-bit FLOAT, meaning 4 bits for exponent (base 10) and 12 bits mantissa) */
+typedef struct
+{
+ int8_t exponent; /**< Base 10 exponent, should be using only 4 bits */
+ int16_t mantissa; /**< Mantissa, should be using only 12 bits */
+} sfloat_t;
+
+/**@brief Date and Time structure. */
+typedef struct
+{
+ uint16_t year;
+ uint8_t month;
+ uint8_t day;
+ uint8_t hours;
+ uint8_t minutes;
+ uint8_t seconds;
+} ble_date_time_t;
+
+
+/**@brief Function for encoding a uint16 value.
+ *
+ * @param[in] p_value Value to be encoded.
+ * @param[out] p_encoded_data Buffer where the encoded data is to be written.
+ *
+ * @return Number of bytes written.
+ */
+static __INLINE uint8_t bds_uint16_encode(const uint16_t * p_value, uint8_t * p_encoded_data)
+{
+ p_encoded_data[0] = (uint8_t) ((*p_value & 0x00FF) >> 0);
+ p_encoded_data[1] = (uint8_t) ((*p_value & 0xFF00) >> 8);
+ return sizeof(uint16_t);
+}
+
+static __INLINE uint8_t bds_int16_encode(const int16_t * p_value, uint8_t * p_encoded_data)
+{
+ uint16_t tmp = *p_value;
+ return bds_uint16_encode(&tmp, p_encoded_data);
+}
+
+/**@brief Function for encoding a uint24 value.
+ *
+ * @param[in] p_value Value to be encoded.
+ * @param[out] p_encoded_data Buffer where the encoded data is to be written.
+ *
+ * @return Number of bytes written.
+ */
+static __INLINE uint8_t bds_uint24_encode(const uint32_t * p_value, uint8_t * p_encoded_data)
+{
+ p_encoded_data[0] = (uint8_t) ((*p_value & 0x000000FF) >> 0);
+ p_encoded_data[1] = (uint8_t) ((*p_value & 0x0000FF00) >> 8);
+ p_encoded_data[2] = (uint8_t) ((*p_value & 0x00FF0000) >> 16);
+ return (3);
+}
+
+
+/**@brief Function for encoding a uint32 value.
+ *
+ * @param[in] p_value Value to be encoded.
+ * @param[out] p_encoded_data Buffer where the encoded data is to be written.
+ *
+ * @return Number of bytes written.
+ */
+static __INLINE uint8_t bds_uint32_encode(const uint32_t * p_value, uint8_t * p_encoded_data)
+{
+ p_encoded_data[0] = (uint8_t) ((*p_value & 0x000000FF) >> 0);
+ p_encoded_data[1] = (uint8_t) ((*p_value & 0x0000FF00) >> 8);
+ p_encoded_data[2] = (uint8_t) ((*p_value & 0x00FF0000) >> 16);
+ p_encoded_data[3] = (uint8_t) ((*p_value & 0xFF000000) >> 24);
+ return sizeof(uint32_t);
+}
+
+
+/**@brief Function for encoding a uint40 value.
+ *
+ * @param[in] p_value Value to be encoded.
+ * @param[out] p_encoded_data Buffer where the encoded data is to be written.
+ *
+ * @return Number of bytes written.
+ */
+static __INLINE uint8_t bds_uint40_encode(const uint64_t * p_value, uint8_t * p_encoded_data)
+{
+ p_encoded_data[0] = (uint8_t) ((*p_value & 0x00000000000000FF) >> 0);
+ p_encoded_data[1] = (uint8_t) ((*p_value & 0x000000000000FF00) >> 8);
+ p_encoded_data[2] = (uint8_t) ((*p_value & 0x0000000000FF0000) >> 16);
+ p_encoded_data[3] = (uint8_t) ((*p_value & 0x00000000FF000000) >> 24);
+ p_encoded_data[4] = (uint8_t) ((*p_value & 0x000000FF00000000) >> 32);
+ return 5;
+}
+
+/**@brief Function for encoding a sfloat value.
+ *
+ * @param[in] p_value Value to be encoded.
+ * @param[out] p_encoded_data Buffer where the encoded data is to be written.
+ *
+ * @return Number of bytes written.
+ */
+static __INLINE uint8_t bds_sfloat_encode(const sfloat_t * p_value, uint8_t * p_encoded_data)
+{
+ uint16_t encoded_val;
+
+ encoded_val = ((p_value->exponent << 12) & 0xF000) |
+ ((p_value->mantissa << 0) & 0x0FFF);
+
+ return(bds_uint16_encode(&encoded_val, p_encoded_data));
+}
+
+
+/**@brief Function for encoding a uint8_array value.
+ *
+ * @param[in] p_value Value to be encoded.
+ * @param[out] p_encoded_data Buffer where the encoded data is to be written.
+ */
+static __INLINE uint8_t bds_uint8_array_encode(const uint8_array_t * p_value,
+ uint8_t * p_encoded_data)
+{
+ memcpy(p_encoded_data, p_value->p_data, p_value->size);
+ return p_value->size;
+}
+
+
+/**@brief Function for encoding a utf8_str value.
+ *
+ * @param[in] p_value Value to be encoded.
+ * @param[out] p_encoded_data Buffer where the encoded data is to be written.
+
+ */
+static __INLINE uint8_t bds_ble_srv_utf8_str_encode(const ble_srv_utf8_str_t * p_value,
+ uint8_t * p_encoded_data)
+{
+ memcpy(p_encoded_data, p_value->p_str, p_value->length);
+ return p_value->length;
+}
+
+/**@brief Function for encoding a regcertdatalist value.
+ *
+ * @param[in] p_value Value to be encoded.
+ * @param[out] p_encoded_data Buffer where the encoded data is to be written.
+
+ */
+static __INLINE uint8_t bds_regcertdatalist_encode(const regcertdatalist_t * p_value,
+ uint8_t * p_encoded_data)
+{
+ memcpy(p_encoded_data, p_value->p_list, p_value->list_len);
+ return p_value->list_len;
+}
+
+
+/**@brief Function for decoding a date_time value.
+ *
+ * @param[in] p_date_time pointer to the date_time structure to encode.
+ * @param[in] p_encoded_data pointer to the encoded data
+ * @return length of the encoded field.
+ */
+static __INLINE uint8_t bds_ble_date_time_encode(const ble_date_time_t * p_date_time,
+ uint8_t * p_encoded_data)
+{
+ uint8_t len = bds_uint16_encode(&p_date_time->year, &p_encoded_data[0]);
+
+ p_encoded_data[len++] = p_date_time->month;
+ p_encoded_data[len++] = p_date_time->day;
+ p_encoded_data[len++] = p_date_time->hours;
+ p_encoded_data[len++] = p_date_time->minutes;
+ p_encoded_data[len++] = p_date_time->seconds;
+
+ return len;
+}
+
+
+/**@brief Function for decoding a uint16 value.
+ *
+ * @param[in] len length of the field to be decoded.
+ * @param[in] p_encoded_data Buffer where the encoded data is stored.
+ * @param[in] p_decoded_val pointer to the decoded value
+ * @return length of the decoded field.
+ */
+static __INLINE uint8_t bds_uint16_decode(const uint8_t len,
+ const uint8_t * p_encoded_data,
+ uint16_t * p_decoded_val)
+{
+ UNUSED_VARIABLE(len);
+ *p_decoded_val = (((uint16_t)((uint8_t *)p_encoded_data)[0])) |
+ (((uint16_t)((uint8_t *)p_encoded_data)[1]) << 8 );
+ return (sizeof(uint16_t));
+}
+
+
+/**@brief Function for decoding a int16 value.
+ *
+ * @param[in] len length of the field to be decoded.
+ * @param[in] p_encoded_data Buffer where the encoded data is stored.
+ * @param[in] p_decoded_val pointer to the decoded value
+ * @return length of the decoded field.
+ */
+static __INLINE uint8_t bds_int16_decode(const uint8_t len,
+ const uint8_t * p_encoded_data,
+ int16_t * p_decoded_val)
+{
+ UNUSED_VARIABLE(len);
+ uint16_t tmp = 0;
+ uint8_t retval = bds_uint16_decode(len, p_encoded_data, &tmp);
+ *p_decoded_val = (int16_t)tmp;
+ return retval;
+}
+
+
+/**@brief Function for decoding a uint24 value.
+ *
+ * @param[in] len length of the field to be decoded.
+ * @param[in] p_encoded_data Buffer where the encoded data is stored.
+ * @param[in] p_decoded_val pointer to the decoded value
+ *
+ * @return length of the decoded field.
+ */
+static __INLINE uint8_t bds_uint24_decode(const uint8_t len,
+ const uint8_t * p_encoded_data,
+ uint32_t * p_decoded_val)
+{
+ UNUSED_VARIABLE(len);
+ *p_decoded_val = (((uint32_t)((uint8_t *)p_encoded_data)[0]) << 0) |
+ (((uint32_t)((uint8_t *)p_encoded_data)[1]) << 8) |
+ (((uint32_t)((uint8_t *)p_encoded_data)[2]) << 16);
+ return (3);
+}
+
+
+/**@brief Function for decoding a uint32 value.
+ *
+ * @param[in] len length of the field to be decoded.
+ * @param[in] p_encoded_data Buffer where the encoded data is stored.
+ * @param[in] p_decoded_val pointer to the decoded value
+ *
+ * @return length of the decoded field.
+ */
+static __INLINE uint8_t bds_uint32_decode(const uint8_t len,
+ const uint8_t * p_encoded_data,
+ uint32_t * p_decoded_val)
+{
+ UNUSED_VARIABLE(len);
+ *p_decoded_val = (((uint32_t)((uint8_t *)p_encoded_data)[0]) << 0) |
+ (((uint32_t)((uint8_t *)p_encoded_data)[1]) << 8) |
+ (((uint32_t)((uint8_t *)p_encoded_data)[2]) << 16) |
+ (((uint32_t)((uint8_t *)p_encoded_data)[3]) << 24 );
+ return (sizeof(uint32_t));
+}
+
+
+/**@brief Function for decoding a uint40 value.
+ *
+ * @param[in] len length of the field to be decoded.
+ * @param[in] p_encoded_data Buffer where the encoded data is stored.
+ * @param[in] p_decoded_val pointer to the decoded value
+ *
+ * @return length of the decoded field.
+ */
+static __INLINE uint8_t bds_uint40_decode(const uint8_t len,
+ const uint8_t * p_encoded_data,
+ uint64_t * p_decoded_val)
+{
+ UNUSED_VARIABLE(len);
+ *p_decoded_val = (((uint64_t)((uint8_t *)p_encoded_data)[0]) << 0) |
+ (((uint64_t)((uint8_t *)p_encoded_data)[1]) << 8) |
+ (((uint64_t)((uint8_t *)p_encoded_data)[2]) << 16) |
+ (((uint64_t)((uint8_t *)p_encoded_data)[3]) << 24 )|
+ (((uint64_t)((uint8_t *)p_encoded_data)[4]) << 32 );
+ return (40);
+}
+
+
+/**@brief Function for decoding a sfloat value.
+ *
+ * @param[in] len length of the field to be decoded.
+ * @param[in] p_encoded_data Buffer where the encoded data is stored.
+ * @param[in] p_decoded_val pointer to the decoded value
+ *
+ * @return length of the decoded field.
+
+ */
+static __INLINE uint8_t bds_sfloat_decode(const uint8_t len,
+ const uint8_t * p_encoded_data,
+ sfloat_t * p_decoded_val)
+{
+
+ p_decoded_val->exponent = 0;
+ bds_uint16_decode(len, p_encoded_data, (uint16_t*)&p_decoded_val->mantissa);
+ p_decoded_val->exponent = (uint8_t)((p_decoded_val->mantissa & 0xF000) >> 12);
+ p_decoded_val->mantissa &= 0x0FFF;
+ return len;
+}
+
+
+/**@brief Function for decoding a uint8_array value.
+ *
+ * @param[in] len length of the field to be decoded.
+ * @param[in] p_encoded_data Buffer where the encoded data is stored.
+ * @param[in] p_decoded_val pointer to the decoded value
+ *
+ * @return length of the decoded field.
+ */
+static __INLINE uint8_t bds_uint8_array_decode(const uint8_t len,
+ const uint8_t * p_encoded_data,
+ uint8_array_t * p_decoded_val)
+{
+ memcpy(p_decoded_val->p_data, p_encoded_data, len);
+ p_decoded_val->size = len;
+ return p_decoded_val->size;
+}
+
+
+/**@brief Function for decoding a utf8_str value.
+ *
+ * @param[in] len length of the field to be decoded.
+ * @param[in] p_encoded_data Buffer where the encoded data is stored.
+ * @param[in] p_decoded_val pointer to the decoded value
+ *
+ * @return length of the decoded field.
+ */
+static __INLINE uint8_t bds_ble_srv_utf8_str_decode(const uint8_t len,
+ const uint8_t * p_encoded_data,
+ ble_srv_utf8_str_t * p_decoded_val)
+{
+ p_decoded_val->p_str = (uint8_t*)p_encoded_data;
+ p_decoded_val->length = len;
+ return p_decoded_val->length;
+}
+
+
+/**@brief Function for decoding a regcertdatalist value.
+ *
+ * @param[in] len length of the field to be decoded.
+ * @param[in] p_encoded_data Buffer where the encoded data is stored.
+ * @param[in] p_decoded_val pointer to the decoded value
+ *
+ * @return length of the decoded field.
+ */
+static __INLINE uint8_t bds_regcertdatalist_decode(const uint8_t len,
+ const uint8_t * p_encoded_data,
+ regcertdatalist_t * p_decoded_val)
+{
+ memcpy(p_decoded_val->p_list, p_encoded_data, len);
+ p_decoded_val->list_len = len;
+ return p_decoded_val->list_len;
+}
+
+
+/**@brief Function for decoding a date_time value.
+ *
+ * @param[in] len length of the field to be decoded.
+ * @param[in] p_encoded_data Buffer where the encoded data is stored.
+ * @param[in] p_date_time pointer to the decoded value
+ *
+ * @return length of the decoded field.
+ */
+static __INLINE uint8_t bds_ble_date_time_decode(const uint8_t len,
+ const uint8_t * p_encoded_data,
+ ble_date_time_t * p_date_time)
+{
+ UNUSED_VARIABLE(len);
+ uint8_t pos = bds_uint16_decode(len, &p_encoded_data[0], &p_date_time->year);
+ p_date_time->month = p_encoded_data[pos++];
+ p_date_time->day = p_encoded_data[pos++];
+ p_date_time->hours = p_encoded_data[pos++];
+ p_date_time->minutes = p_encoded_data[pos++];
+ p_date_time->seconds = p_encoded_data[pos++];
+
+ return pos;
+}
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // APP_UTIL_BDS_H__
+
+/** @} */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/util/app_util_platform.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/util/app_util_platform.c
new file mode 100644
index 0000000..71690d0
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/util/app_util_platform.c
@@ -0,0 +1,127 @@
+/**
+ * Copyright (c) 2014 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#include "app_util_platform.h"
+
+#ifdef SOFTDEVICE_PRESENT
+/* Global nvic state instance, required by nrf_nvic.h */
+nrf_nvic_state_t nrf_nvic_state;
+#endif
+
+static uint32_t m_in_critical_region = 0;
+
+void app_util_disable_irq(void)
+{
+ __disable_irq();
+ m_in_critical_region++;
+}
+
+void app_util_enable_irq(void)
+{
+ m_in_critical_region--;
+ if (m_in_critical_region == 0)
+ {
+ __enable_irq();
+ }
+}
+
+void app_util_critical_region_enter(uint8_t *p_nested)
+{
+#if __CORTEX_M == (0x04U)
+ ASSERT(APP_LEVEL_PRIVILEGED == privilege_level_get())
+#endif
+
+#if defined(SOFTDEVICE_PRESENT)
+ /* return value can be safely ignored */
+ (void) sd_nvic_critical_region_enter(p_nested);
+#else
+ app_util_disable_irq();
+#endif
+}
+
+void app_util_critical_region_exit(uint8_t nested)
+{
+#if __CORTEX_M == (0x04U)
+ ASSERT(APP_LEVEL_PRIVILEGED == privilege_level_get())
+#endif
+
+#if defined(SOFTDEVICE_PRESENT)
+ /* return value can be safely ignored */
+ (void) sd_nvic_critical_region_exit(nested);
+#else
+ app_util_enable_irq();
+#endif
+}
+
+
+uint8_t privilege_level_get(void)
+{
+#if __CORTEX_M == (0x00U) || defined(_WIN32) || defined(__unix) || defined(__APPLE__)
+ /* the Cortex-M0 has no concept of privilege */
+ return APP_LEVEL_PRIVILEGED;
+#elif __CORTEX_M == (0x04U)
+ uint32_t isr_vector_num = __get_IPSR() & IPSR_ISR_Msk ;
+ if (0 == isr_vector_num)
+ {
+ /* Thread Mode, check nPRIV */
+ int32_t control = __get_CONTROL();
+ return control & CONTROL_nPRIV_Msk ? APP_LEVEL_UNPRIVILEGED : APP_LEVEL_PRIVILEGED;
+ }
+ else
+ {
+ /* Handler Mode, always privileged */
+ return APP_LEVEL_PRIVILEGED;
+ }
+#endif
+}
+
+
+uint8_t current_int_priority_get(void)
+{
+ uint32_t isr_vector_num = __get_IPSR() & IPSR_ISR_Msk ;
+ if (isr_vector_num > 0)
+ {
+ int32_t irq_type = ((int32_t)isr_vector_num - EXTERNAL_INT_VECTOR_OFFSET);
+ return (NVIC_GetPriority((IRQn_Type)irq_type) & 0xFF);
+ }
+ else
+ {
+ return APP_IRQ_PRIORITY_THREAD;
+ }
+}
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/util/app_util_platform.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/util/app_util_platform.h
new file mode 100644
index 0000000..ed478f3
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/util/app_util_platform.h
@@ -0,0 +1,279 @@
+/**
+ * Copyright (c) 2014 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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
+ *
+ * @defgroup app_util_platform Utility Functions and Definitions (Platform)
+ * @{
+ * @ingroup app_common
+ *
+ * @brief Various types and definitions available to all applications when using SoftDevice.
+ */
+
+#ifndef APP_UTIL_PLATFORM_H__
+#define APP_UTIL_PLATFORM_H__
+
+#include <stdint.h>
+#include "compiler_abstraction.h"
+#include "nrf.h"
+#ifdef SOFTDEVICE_PRESENT
+#include "nrf_soc.h"
+#include "nrf_nvic.h"
+#endif
+#include "nrf_assert.h"
+#include "app_error.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#if __CORTEX_M == (0x00U)
+#define _PRIO_SD_HIGH 0
+#define _PRIO_APP_HIGH 1
+#define _PRIO_APP_MID 1
+#define _PRIO_SD_LOW 2
+#define _PRIO_APP_LOW 3
+#define _PRIO_APP_LOWEST 3
+#define _PRIO_THREAD 4
+#elif __CORTEX_M == (0x04U)
+#define _PRIO_SD_HIGH 0
+#define _PRIO_SD_MID 1
+#define _PRIO_APP_HIGH 2
+#define _PRIO_APP_MID 3
+#define _PRIO_SD_LOW 4
+#define _PRIO_SD_LOWEST 5
+#define _PRIO_APP_LOW 6
+#define _PRIO_APP_LOWEST 7
+#define _PRIO_THREAD 15
+#else
+ #error "No platform defined"
+#endif
+
+
+//lint -save -e113 -e452
+/**@brief The interrupt priorities available to the application while the SoftDevice is active. */
+typedef enum
+{
+#ifndef SOFTDEVICE_PRESENT
+ APP_IRQ_PRIORITY_HIGHEST = _PRIO_SD_HIGH,
+#else
+ APP_IRQ_PRIORITY_HIGHEST = _PRIO_APP_HIGH,
+#endif
+ APP_IRQ_PRIORITY_HIGH = _PRIO_APP_HIGH,
+#ifndef SOFTDEVICE_PRESENT
+ APP_IRQ_PRIORITY_MID = _PRIO_SD_LOW,
+#else
+ APP_IRQ_PRIORITY_MID = _PRIO_APP_MID,
+#endif
+ APP_IRQ_PRIORITY_LOW = _PRIO_APP_LOW,
+ APP_IRQ_PRIORITY_LOWEST = _PRIO_APP_LOWEST,
+ APP_IRQ_PRIORITY_THREAD = _PRIO_THREAD /**< "Interrupt level" when running in Thread Mode. */
+} app_irq_priority_t;
+//lint -restore
+
+
+/*@brief The privilege levels available to applications in Thread Mode */
+typedef enum
+{
+ APP_LEVEL_UNPRIVILEGED,
+ APP_LEVEL_PRIVILEGED
+} app_level_t;
+
+/**@cond NO_DOXYGEN */
+#define EXTERNAL_INT_VECTOR_OFFSET 16
+/**@endcond */
+
+/**@brief Macro for setting a breakpoint.
+ */
+#if defined(__GNUC__)
+#define NRF_BREAKPOINT __asm__("BKPT 0");
+#else
+#define NRF_BREAKPOINT __BKPT(0)
+#endif
+
+/** @brief Macro for setting a breakpoint.
+ *
+ * If it is possible to detect debugger presence then it is set only in that case.
+ *
+ */
+#if __CORTEX_M == 0x04
+#define NRF_BREAKPOINT_COND do { \
+ /* C_DEBUGEN == 1 -> Debugger Connected */ \
+ if (CoreDebug->DHCSR & CoreDebug_DHCSR_C_DEBUGEN_Msk) \
+ { \
+ /* Generate breakpoint if debugger is connected */ \
+ NRF_BREAKPOINT; \
+ } \
+ }while (0)
+#else
+#define NRF_BREAKPOINT_COND NRF_BREAKPOINT
+#endif // __CORTEX_M == 0x04
+
+#if defined ( __CC_ARM )
+#define PACKED(TYPE) __packed TYPE
+#define PACKED_STRUCT PACKED(struct)
+#elif defined ( __GNUC__ )
+#define PACKED __attribute__((packed))
+#define PACKED_STRUCT struct PACKED
+#elif defined (__ICCARM__)
+#define PACKED_STRUCT __packed struct
+#endif
+
+#if defined ( __CC_ARM )
+#define PRAGMA_OPTIMIZATION_FORCE_START _Pragma ("push") \
+ _Pragma ("O3")
+#define PRAGMA_OPTIMIZATION_FORCE_END _Pragma ("pop")
+#elif defined ( __GNUC__ )
+#define PRAGMA_OPTIMIZATION_FORCE_START _Pragma("GCC push_options") \
+ _Pragma ("GCC optimize (\"Os\")")
+#define PRAGMA_OPTIMIZATION_FORCE_END _Pragma ("GCC pop_options")
+#elif defined (__ICCARM__)
+#define PRAGMA_OPTIMIZATION_FORCE_START _Pragma ("optimize=high z")
+#define PRAGMA_OPTIMIZATION_FORCE_END
+#endif
+
+
+void app_util_critical_region_enter (uint8_t *p_nested);
+void app_util_critical_region_exit (uint8_t nested);
+
+/**@brief Macro for entering a critical region.
+ *
+ * @note Due to implementation details, there must exist one and only one call to
+ * CRITICAL_REGION_EXIT() for each call to CRITICAL_REGION_ENTER(), and they must be located
+ * in the same scope.
+ */
+#ifdef SOFTDEVICE_PRESENT
+#define CRITICAL_REGION_ENTER() \
+ { \
+ uint8_t __CR_NESTED = 0; \
+ app_util_critical_region_enter(&__CR_NESTED);
+#else
+#define CRITICAL_REGION_ENTER() app_util_critical_region_enter(NULL)
+#endif
+
+/**@brief Macro for leaving a critical region.
+ *
+ * @note Due to implementation details, there must exist one and only one call to
+ * CRITICAL_REGION_EXIT() for each call to CRITICAL_REGION_ENTER(), and they must be located
+ * in the same scope.
+ */
+#ifdef SOFTDEVICE_PRESENT
+#define CRITICAL_REGION_EXIT() \
+ app_util_critical_region_exit(__CR_NESTED); \
+ }
+#else
+#define CRITICAL_REGION_EXIT() app_util_critical_region_exit(0)
+#endif
+
+/* Workaround for Keil 4 */
+#ifndef IPSR_ISR_Msk
+#define IPSR_ISR_Msk (0x1FFUL /*<< IPSR_ISR_Pos*/) /*!< IPSR: ISR Mask */
+#endif
+
+
+
+/**@brief Macro to enable anonymous unions from a certain point in the code.
+ */
+#if defined(__CC_ARM)
+ #define ANON_UNIONS_ENABLE _Pragma("push") \
+ _Pragma("anon_unions") \
+ struct semicolon_swallower
+#elif defined(__ICCARM__)
+ #define ANON_UNIONS_ENABLE _Pragma("language=extended") \
+ struct semicolon_swallower
+#else
+ #define ANON_UNIONS_ENABLE struct semicolon_swallower
+ // No action will be taken.
+ // For GCC anonymous unions are enabled by default.
+#endif
+
+/**@brief Macro to disable anonymous unions from a certain point in the code.
+ * @note Call only after first calling @ref ANON_UNIONS_ENABLE.
+ */
+#if defined(__CC_ARM)
+ #define ANON_UNIONS_DISABLE _Pragma("pop") \
+ struct semicolon_swallower
+#elif defined(__ICCARM__)
+ #define ANON_UNIONS_DISABLE struct semicolon_swallower
+ // for IAR leave anonymous unions enabled
+#else
+ #define ANON_UNIONS_DISABLE struct semicolon_swallower
+ // No action will be taken.
+ // For GCC anonymous unions are enabled by default.
+#endif
+
+/**@brief Macro for adding pragma directive only for GCC.
+ */
+#ifdef __GNUC__
+#define GCC_PRAGMA(v) _Pragma(v)
+#else
+#define GCC_PRAGMA(v)
+#endif
+
+/* Workaround for Keil 4 */
+#ifndef CONTROL_nPRIV_Msk
+#define CONTROL_nPRIV_Msk (1UL /*<< CONTROL_nPRIV_Pos*/) /*!< CONTROL: nPRIV Mask */
+#endif
+
+/**@brief Function for finding the current interrupt level.
+ *
+ * @return Current interrupt level.
+ * @retval APP_IRQ_PRIORITY_HIGH We are running in Application High interrupt level.
+ * @retval APP_IRQ_PRIORITY_LOW We are running in Application Low interrupt level.
+ * @retval APP_IRQ_PRIORITY_THREAD We are running in Thread Mode.
+ */
+uint8_t current_int_priority_get(void);
+
+
+/**@brief Function for finding out the current privilege level.
+ *
+ * @return Current privilege level.
+ * @retval APP_LEVEL_UNPRIVILEGED We are running in unprivileged level.
+ * @retval APP_LEVEL_PRIVILEGED We are running in privileged level.
+ */
+uint8_t privilege_level_get(void);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // APP_UTIL_PLATFORM_H__
+
+/** @} */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/util/nordic_common.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/util/nordic_common.h
new file mode 100644
index 0000000..1492acf
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/util/nordic_common.h
@@ -0,0 +1,215 @@
+/**
+ * Copyright (c) 2008 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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
+ * @brief Common defines and macros for firmware developed by Nordic Semiconductor.
+ */
+
+#ifndef NORDIC_COMMON_H__
+#define NORDIC_COMMON_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @brief Check if selected module is enabled
+ *
+ * This is save function for driver enable checking.
+ * Correct from Lint point of view (not using default of undefined value).
+ *
+ * Usage:
+ * @code
+ #if NRF_MODULE_ENABLED(UART)
+ ...
+ #endif
+ * @endcode
+ *
+ * @param module The module name.
+ *
+ * @retval 1 The macro <module>_ENABLE is defined and is non-zero.
+ * @retval 0 The macro <module>_ENABLE is not defined or it equals zero.
+ *
+ * @note
+ * This macro intentionally does not implement second expansion level.
+ * The name of the module to be checked has to be given directly as a parameter.
+ * And given parameter would be connected with @c _ENABLED postfix directly
+ * without evaluating its value.
+ */
+//lint -emacro(491,NRF_MODULE_ENABLED) // Suppers warning 491 "non-standard use of 'defined' preprocessor operator"
+#ifdef NRF_MODULE_ENABLE_ALL
+#warning "Do not use NRF_MODULE_ENABLE_ALL for real builds."
+#define NRF_MODULE_ENABLED(module) 1
+#else
+#define NRF_MODULE_ENABLED(module) \
+ ((defined(module ## _ENABLED) && (module ## _ENABLED)) ? 1 : 0)
+#endif
+/** The upper 8 bits of a 32 bit value */
+//lint -emacro(572,MSB_32) // Suppress warning 572 "Excessive shift value"
+#define MSB_32(a) (((a) & 0xFF000000) >> 24)
+/** The lower 8 bits (of a 32 bit value) */
+#define LSB_32(a) ((a) & 0x000000FF)
+
+/** The upper 8 bits of a 16 bit value */
+//lint -emacro(572,MSB_16) // Suppress warning 572 "Excessive shift value"
+#define MSB_16(a) (((a) & 0xFF00) >> 8)
+/** The lower 8 bits (of a 16 bit value) */
+#define LSB_16(a) ((a) & 0x00FF)
+
+/** Leaves the minimum of the two 32-bit arguments */
+/*lint -emacro(506, MIN) */ /* Suppress "Constant value Boolean */
+#define MIN(a, b) ((a) < (b) ? (a) : (b))
+/** Leaves the maximum of the two 32-bit arguments */
+/*lint -emacro(506, MAX) */ /* Suppress "Constant value Boolean */
+#define MAX(a, b) ((a) < (b) ? (b) : (a))
+
+/**@brief Concatenates two parameters.
+ *
+ * It realizes two level expansion to make it sure that all the parameters
+ * are actually expanded before gluing them together.
+ *
+ * @param p1 First parameter to concatenating
+ * @param p2 Second parameter to concatenating
+ *
+ * @return Two parameters glued together.
+ * They have to create correct C mnemonic in other case
+ * preprocessor error would be generated.
+ *
+ * @sa CONCAT_3
+ */
+#define CONCAT_2(p1, p2) CONCAT_2_(p1, p2)
+/** Auxiliary macro used by @ref CONCAT_2 */
+#define CONCAT_2_(p1, p2) p1##p2
+
+/**@brief Concatenates three parameters.
+ *
+ * It realizes two level expansion to make it sure that all the parameters
+ * are actually expanded before gluing them together.
+ *
+ * @param p1 First parameter to concatenating
+ * @param p2 Second parameter to concatenating
+ * @param p3 Third parameter to concatenating
+ *
+ * @return Three parameters glued together.
+ * They have to create correct C mnemonic in other case
+ * preprocessor error would be generated.
+ *
+ * @sa CONCAT_2
+ */
+#define CONCAT_3(p1, p2, p3) CONCAT_3_(p1, p2, p3)
+/** Auxiliary macro used by @ref CONCAT_3 */
+#define CONCAT_3_(p1, p2, p3) p1##p2##p3
+
+#define STRINGIFY_(val) #val
+/** Converts a macro argument into a character constant.
+ */
+#define STRINGIFY(val) STRINGIFY_(val)
+
+/** Counts number of elements inside the array
+ */
+#define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0]))
+
+/**@brief Set a bit in the uint32 word.
+ *
+ * @param[in] W Word whose bit is being set.
+ * @param[in] B Bit number in the word to be set.
+ */
+#define SET_BIT(W, B) ((W) |= (uint32_t)(1U << (B)))
+
+
+/**@brief Clears a bit in the uint32 word.
+ *
+ * @param[in] W Word whose bit is to be cleared.
+ * @param[in] B Bit number in the word to be cleared.
+ */
+#define CLR_BIT(W, B) ((W) &= (~(uint32_t)(1U << (B))))
+
+
+/**@brief Checks if a bit is set.
+ *
+ * @param[in] W Word whose bit is to be checked.
+ * @param[in] B Bit number in the word to be checked.
+ *
+ * @retval 1 if bit is set.
+ * @retval 0 if bit is not set.
+ */
+#define IS_SET(W, B) (((W) >> (B)) & 1)
+
+#define BIT_0 0x01 /**< The value of bit 0 */
+#define BIT_1 0x02 /**< The value of bit 1 */
+#define BIT_2 0x04 /**< The value of bit 2 */
+#define BIT_3 0x08 /**< The value of bit 3 */
+#define BIT_4 0x10 /**< The value of bit 4 */
+#define BIT_5 0x20 /**< The value of bit 5 */
+#define BIT_6 0x40 /**< The value of bit 6 */
+#define BIT_7 0x80 /**< The value of bit 7 */
+#define BIT_8 0x0100 /**< The value of bit 8 */
+#define BIT_9 0x0200 /**< The value of bit 9 */
+#define BIT_10 0x0400 /**< The value of bit 10 */
+#define BIT_11 0x0800 /**< The value of bit 11 */
+#define BIT_12 0x1000 /**< The value of bit 12 */
+#define BIT_13 0x2000 /**< The value of bit 13 */
+#define BIT_14 0x4000 /**< The value of bit 14 */
+#define BIT_15 0x8000 /**< The value of bit 15 */
+#define BIT_16 0x00010000 /**< The value of bit 16 */
+#define BIT_17 0x00020000 /**< The value of bit 17 */
+#define BIT_18 0x00040000 /**< The value of bit 18 */
+#define BIT_19 0x00080000 /**< The value of bit 19 */
+#define BIT_20 0x00100000 /**< The value of bit 20 */
+#define BIT_21 0x00200000 /**< The value of bit 21 */
+#define BIT_22 0x00400000 /**< The value of bit 22 */
+#define BIT_23 0x00800000 /**< The value of bit 23 */
+#define BIT_24 0x01000000 /**< The value of bit 24 */
+#define BIT_25 0x02000000 /**< The value of bit 25 */
+#define BIT_26 0x04000000 /**< The value of bit 26 */
+#define BIT_27 0x08000000 /**< The value of bit 27 */
+#define BIT_28 0x10000000 /**< The value of bit 28 */
+#define BIT_29 0x20000000 /**< The value of bit 29 */
+#define BIT_30 0x40000000 /**< The value of bit 30 */
+#define BIT_31 0x80000000 /**< The value of bit 31 */
+
+#define UNUSED_VARIABLE(X) ((void)(X))
+#define UNUSED_PARAMETER(X) UNUSED_VARIABLE(X)
+#define UNUSED_RETURN_VALUE(X) UNUSED_VARIABLE(X)
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // NORDIC_COMMON_H__
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/util/nrf_assert.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/util/nrf_assert.c
new file mode 100644
index 0000000..6678e22
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/util/nrf_assert.c
@@ -0,0 +1,54 @@
+/**
+ * Copyright (c) 2006 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#include "nrf_assert.h"
+#include "app_error.h"
+#include "nordic_common.h"
+
+__WEAK void assert_nrf_callback(uint16_t line_num, const uint8_t * file_name)
+{
+ assert_info_t assert_info =
+ {
+ .line_num = line_num,
+ .p_file_name = file_name,
+ };
+ app_error_fault_handler(NRF_FAULT_ID_SDK_ASSERT, 0, (uint32_t)(&assert_info));
+
+ UNUSED_VARIABLE(assert_info);
+}
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/util/nrf_assert.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/util/nrf_assert.h
new file mode 100644
index 0000000..f078910
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/util/nrf_assert.h
@@ -0,0 +1,122 @@
+/**
+ * Copyright (c) 2006 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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
+ * @brief Utilities for verifying program logic
+ */
+
+#ifndef NRF_ASSERT_H_
+#define NRF_ASSERT_H_
+
+#include <stdint.h>
+#include "nrf.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** @brief Function for handling assertions.
+ *
+ *
+ * @note
+ * This function is called when an assertion has triggered.
+ *
+ * @note
+ * This function is deprecated and will be removed in future releases.
+ * Use app_error_fault_handler instead.
+ *
+ *
+ * @post
+ * All hardware is put into an idle non-emitting state (in particular the radio is highly
+ * important to switch off since the radio might be in a state that makes it send
+ * packets continiously while a typical final infinit ASSERT loop is executing).
+ *
+ *
+ * @param line_num The line number where the assertion is called
+ * @param file_name Pointer to the file name
+ */
+//lint -save -esym(14, assert_nrf_callback)
+void assert_nrf_callback(uint16_t line_num, const uint8_t *file_name);
+//lint -restore
+
+#if (defined(DEBUG_NRF) || defined(DEBUG_NRF_USER))
+#define NRF_ASSERT_PRESENT 1
+#else
+#define NRF_ASSERT_PRESENT 0
+#endif
+
+//#if defined(DEBUG_NRF) || defined(DEBUG_NRF_USER)
+
+/*lint -emacro(506, ASSERT) */ /* Suppress "Constant value Boolean */
+/*lint -emacro(774, ASSERT) */ /* Suppress "Boolean within 'if' always evaluates to True" */ \
+
+/** @brief Function for checking intended for production code.
+ *
+ * Check passes if "expr" evaluates to true. */
+
+#ifdef _lint
+#define ASSERT(expr) \
+if (expr) \
+{ \
+} \
+else \
+{ \
+ while (1); \
+}
+#else //_lint
+#define ASSERT(expr) \
+if (NRF_ASSERT_PRESENT) \
+{ \
+ if (expr) \
+ { \
+ } \
+ else \
+ { \
+ assert_nrf_callback((uint16_t)__LINE__, (uint8_t *)__FILE__); \
+ } \
+}
+
+#endif
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* NRF_ASSERT_H_ */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/util/nrf_bitmask.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/util/nrf_bitmask.h
new file mode 100644
index 0000000..be2eac5
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/util/nrf_bitmask.h
@@ -0,0 +1,147 @@
+/**
+ * Copyright (c) 2006 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#ifndef NRF_BITMASK_H
+#define NRF_BITMASK_H
+
+#include "compiler_abstraction.h"
+#include <stdint.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define BITMASK_BYTE_GET(abs_bit) ((abs_bit)/8)
+#define BITMASK_RELBIT_GET(abs_bit) ((abs_bit) & 0x00000007)
+
+/**
+ * Function for checking if bit in the multi-byte bit mask is set.
+ *
+ * @param bit Bit index.
+ * @param p_mask A pointer to mask with bit fields.
+ *
+ * @return 0 if bit is not set, positive value otherwise.
+ */
+__STATIC_INLINE uint32_t nrf_bitmask_bit_is_set(uint32_t bit, void const * p_mask)
+{
+ uint8_t const * p_mask8 = (uint8_t const *)p_mask;
+ uint32_t byte_idx = BITMASK_BYTE_GET(bit);
+ bit = BITMASK_RELBIT_GET(bit);
+ return (1 << bit) & p_mask8[byte_idx];
+}
+
+/**
+ * Function for setting a bit in the multi-byte bit mask.
+ *
+ * @param bit Bit index.
+ * @param p_mask A pointer to mask with bit fields.
+ */
+__STATIC_INLINE void nrf_bitmask_bit_set(uint32_t bit, void * p_mask)
+{
+ uint8_t * p_mask8 = (uint8_t *)p_mask;
+ uint32_t byte_idx = BITMASK_BYTE_GET(bit);
+ bit = BITMASK_RELBIT_GET(bit);
+ p_mask8[byte_idx] |= (1 << bit);
+}
+
+/**
+ * Function for clearing a bit in the multi-byte bit mask.
+ *
+ * @param bit Bit index.
+ * @param p_mask A pointer to mask with bit fields.
+ */
+__STATIC_INLINE void nrf_bitmask_bit_clear(uint32_t bit, void * p_mask)
+{
+ uint8_t * p_mask8 = (uint8_t *)p_mask;
+ uint32_t byte_idx = BITMASK_BYTE_GET(bit);
+ bit = BITMASK_RELBIT_GET(bit);
+ p_mask8[byte_idx] &= ~(1 << bit);
+}
+
+/**
+ * Function for performing bitwise OR operation on two multi-byte bit masks.
+ *
+ * @param p_mask1 A pointer to the first bit mask.
+ * @param p_mask2 A pointer to the second bit mask.
+ * @param p_mask_out A pointer to the output bit mask.
+ * @param length Length of output mask in bytes.
+ */
+__STATIC_INLINE void nrf_bitmask_masks_or(void const * p_mask1,
+ void const * p_mask2,
+ void * p_out_mask,
+ uint32_t length)
+{
+ uint8_t const * p_mask8_1 = (uint8_t const *)p_mask1;
+ uint8_t const * p_mask8_2 = (uint8_t const *)p_mask2;
+ uint8_t * p_mask8_out = (uint8_t *)p_out_mask;
+ uint32_t i;
+ for (i = 0; i < length; i++)
+ {
+ p_mask8_out[i] = p_mask8_1[i] | p_mask8_2[i];
+ }
+}
+
+/**
+ * Function for performing bitwise AND operation on two multi-byte bit masks.
+ *
+ * @param p_mask1 A pointer to the first bit mask.
+ * @param p_mask2 A pointer to the second bit mask.
+ * @param p_mask_out A pointer to the output bit mask.
+ * @param length Length of output mask in bytes.
+ */
+__STATIC_INLINE void nrf_bitmask_masks_and(void const * p_mask1,
+ void const * p_mask2,
+ void * p_out_mask,
+ uint32_t length)
+{
+ uint8_t const * p_mask8_1 = (uint8_t const *)p_mask1;
+ uint8_t const * p_mask8_2 = (uint8_t const *)p_mask2;
+ uint8_t * p_mask8_out = (uint8_t *)p_out_mask;
+ uint32_t i;
+ for (i = 0; i < length; i++)
+ {
+ p_mask8_out[i] = p_mask8_1[i] & p_mask8_2[i];
+ }
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif //NRF_BITMASK_H
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/util/sdk_alloca.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/util/sdk_alloca.h
new file mode 100644
index 0000000..2266dd3
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/util/sdk_alloca.h
@@ -0,0 +1,85 @@
+/**
+ * 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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 sdk_alloca.h
+ *
+ * @brief Defines alloca() function.
+ *
+ * @details This file defines alloca() function. This can be done directly or by including system
+ * header files. Not all platforms support alloca(). In this case no error will be shown, but
+ * SDK_ALLOCA_DEFINED will be set to 0.
+ */
+
+#ifndef SDK_ALLOCA_H__
+#define SDK_ALLOCA_H__
+
+
+#if defined(__SDK_DOXYGEN__)
+ /** @brief Set to one it alloca() function is available on this platform and it is correctly defined
+ * by this header file.
+ */
+ #define SDK_ALLOCA_DEFINED 1
+#elif defined(__GNUC__)
+ #if defined(__SES_ARM)
+ // SES does not have definition of alloca(), but it have working GCC's __builtin_alloca().
+ #if !defined(alloca)
+ #define alloca(size) __builtin_alloca((size))
+ #endif
+ #else
+ // alloca() can be defined in <malloc.h> on some platforms, but if not then try standard <alloca.h> header file.
+ #include <malloc.h>
+ #if !defined(alloca)
+ #include <alloca.h>
+ #endif
+ #endif
+ #define SDK_ALLOCA_DEFINED 1
+#elif defined(__IAR_SYSTEMS_ICC__)
+ // IAR does not support alloca() function.
+ #define SDK_ALLOCA_DEFINED 0
+#else
+ // All other supported compilers have alloca() definition in <alloca.h> header file.
+ #include <alloca.h>
+ #define SDK_ALLOCA_DEFINED 1
+#endif
+
+
+/*lint -"d__builtin_alloca=(void*)" */
+
+
+#endif // NRF_ALLOCA_H__
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/util/sdk_common.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/util/sdk_common.h
new file mode 100644
index 0000000..6f65d03
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/util/sdk_common.h
@@ -0,0 +1,77 @@
+/**
+ * Copyright (c) 2013 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+/** @cond */
+/**@file
+ *
+ * @ingroup experimental_api
+ * @defgroup sdk_common SDK Common Header
+ * @brief All common headers needed for SDK examples will be included here so that application
+ * developer does not have to include headers on him/herself.
+ * @{
+ */
+
+#ifndef SDK_COMMON_H__
+#define SDK_COMMON_H__
+
+#include <stdint.h>
+#include <stdbool.h>
+#include <string.h>
+#include "sdk_config.h"
+#include "nordic_common.h"
+#include "compiler_abstraction.h"
+#include "sdk_os.h"
+#include "sdk_errors.h"
+#include "app_util.h"
+#include "sdk_macros.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+/** @} */
+/** @endcond */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // SDK_COMMON_H__
+
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/util/sdk_errors.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/util/sdk_errors.h
new file mode 100644
index 0000000..7b5dea5
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/util/sdk_errors.h
@@ -0,0 +1,167 @@
+/**
+ * Copyright (c) 2013 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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
+ *
+ * @defgroup sdk_error SDK Error codes
+ * @{
+ * @ingroup app_common
+ * @{
+ * @details Error codes are 32-bit unsigned integers with the most significant 16-bit reserved for
+ * identifying the module where the error occurred while the least least significant LSB
+ * are used to provide the cause or nature of error. Each module is assigned a 16-bit
+ * unsigned integer. Which it will use to identify all errors that occurred in it. 16-bit
+ * LSB range is with module id as the MSB in the 32-bit error code is reserved for the
+ * module. As an example, if 0x8800 identifies a certain SDK module, all values from
+ * 0x88000000 - 0x8800FFFF are reserved for this module.
+ * It should be noted that common error reasons have been assigned values to make it
+ * possible to decode error reason easily. As an example, lets module uninitialized has
+ * been assigned an error code 0x000A0. Then, if application encounters an error code
+ * 0xZZZZ00A0, it knows that it accessing a certain module without initializing it.
+ * Apart from this, each module is allowed to define error codes that are not covered by
+ * the common ones, however, these values are defined in a range that does not conflict
+ * with common error values. For module, specific error however, it is possible that the
+ * same error value is used by two different modules to indicated errors of very different
+ * nature. If error is already defined by the NRF common error codes, these are reused.
+ * A range is reserved for application as well, it can use this range for defining
+ * application specific errors.
+ *
+ * @note Success code, NRF_SUCCESS, does not include any module identifier.
+
+ */
+
+#ifndef SDK_ERRORS_H__
+#define SDK_ERRORS_H__
+
+#include <stdint.h>
+#include "nrf_error.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @defgroup sdk_err_base Base defined for SDK Modules
+ * @{
+ */
+#define NRF_ERROR_SDK_ERROR_BASE (NRF_ERROR_BASE_NUM + 0x8000) /**< Base value defined for SDK module identifiers. */
+#define NRF_ERROR_SDK_COMMON_ERROR_BASE (NRF_ERROR_BASE_NUM + 0x0080) /**< Base error value to be used for SDK error values. */
+/** @} */
+
+/**
+ * @defgroup sdk_module_codes Codes reserved as identification for module where the error occurred.
+ * @{
+ */
+#define NRF_ERROR_MEMORY_MANAGER_ERR_BASE (0x8100) /**< Base address for Memory Manager related errors. */
+#define NRF_ERROR_PERIPH_DRIVERS_ERR_BASE (0x8200) /**< Base address for Peripheral drivers related errors. */
+#define NRF_ERROR_GAZELLE_ERR_BASE (0x8300) /**< Base address for Gazelle related errors. */
+#define NRF_ERROR_BLE_IPSP_ERR_BASE (0x8400) /**< Base address for BLE IPSP related errors. */
+#define NRF_ERROR_CRYPTO_ERR_BASE (0x8500) /**< Base address for crypto related errors. */
+/** @} */
+
+
+/**
+ * @defgroup sdk_iot_errors Codes reserved as identification for IoT errors.
+ * @{
+ */
+#define NRF_ERROR_IOT_ERR_BASE_START (0xA000)
+#define NRF_ERROR_IOT_ERR_BASE_STOP (0xAFFF)
+/** @} */
+
+
+/**
+ * @defgroup sdk_common_errors Codes reserved as identification for common errors.
+ * @{
+ */
+#define NRF_ERROR_MODULE_NOT_INITIALIZED (NRF_ERROR_SDK_COMMON_ERROR_BASE + 0x0000) ///< Module not initialized
+#define NRF_ERROR_MUTEX_INIT_FAILED (NRF_ERROR_SDK_COMMON_ERROR_BASE + 0x0001) ///< Mutex initialization failed
+#define NRF_ERROR_MUTEX_LOCK_FAILED (NRF_ERROR_SDK_COMMON_ERROR_BASE + 0x0002) ///< Mutex lock failed
+#define NRF_ERROR_MUTEX_UNLOCK_FAILED (NRF_ERROR_SDK_COMMON_ERROR_BASE + 0x0003) ///< Mutex unlock failed
+#define NRF_ERROR_MUTEX_COND_INIT_FAILED (NRF_ERROR_SDK_COMMON_ERROR_BASE + 0x0004) ///< Mutex conditional initialization failed
+#define NRF_ERROR_MODULE_ALREADY_INITIALIZED (NRF_ERROR_SDK_COMMON_ERROR_BASE + 0x0005) ///< Module already initialized
+#define NRF_ERROR_STORAGE_FULL (NRF_ERROR_SDK_COMMON_ERROR_BASE + 0x0006) ///< Storage full
+#define NRF_ERROR_API_NOT_IMPLEMENTED (NRF_ERROR_SDK_COMMON_ERROR_BASE + 0x0010) ///< API not implemented
+#define NRF_ERROR_FEATURE_NOT_ENABLED (NRF_ERROR_SDK_COMMON_ERROR_BASE + 0x0011) ///< Feature not enabled
+#define NRF_ERROR_IO_PENDING (NRF_ERROR_SDK_COMMON_ERROR_BASE + 0x0012) ///< Input/Output pending
+/** @} */
+
+
+/**
+ * @defgroup drv_specific_errors Error / status codes specific to drivers.
+ * @{
+ */
+#define NRF_ERROR_DRV_TWI_ERR_OVERRUN (NRF_ERROR_PERIPH_DRIVERS_ERR_BASE + 0x0000)
+#define NRF_ERROR_DRV_TWI_ERR_ANACK (NRF_ERROR_PERIPH_DRIVERS_ERR_BASE + 0x0001)
+#define NRF_ERROR_DRV_TWI_ERR_DNACK (NRF_ERROR_PERIPH_DRIVERS_ERR_BASE + 0x0002)
+/** @} */
+
+
+/**
+ * @defgroup ble_ipsp_errors IPSP codes
+ * @brief Error and status codes specific to IPSP.
+ * @{
+ */
+#define NRF_ERROR_BLE_IPSP_RX_PKT_TRUNCATED (NRF_ERROR_BLE_IPSP_ERR_BASE + 0x0000)
+#define NRF_ERROR_BLE_IPSP_CHANNEL_ALREADY_EXISTS (NRF_ERROR_BLE_IPSP_ERR_BASE + 0x0001)
+#define NRF_ERROR_BLE_IPSP_LINK_DISCONNECTED (NRF_ERROR_BLE_IPSP_ERR_BASE + 0x0002)
+#define NRF_ERROR_BLE_IPSP_PEER_REJECTED (NRF_ERROR_BLE_IPSP_ERR_BASE + 0x0003)
+/* @} */
+
+
+/**
+ * @brief API Result.
+ *
+ * @details Indicates success or failure of an API procedure. In case of failure, a comprehensive
+ * error code indicating cause or reason for failure is provided.
+ *
+ * Though called an API result, it could used in Asynchronous notifications callback along
+ * with asynchronous callback as event result. This mechanism is employed when an event
+ * marks the end of procedure initiated using API. API result, in this case, will only be
+ * an indicative of whether the procedure has been requested successfully.
+ */
+typedef uint32_t ret_code_t;
+
+/** @} */
+/** @} */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // SDK_ERRORS_H__
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/util/sdk_macros.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/util/sdk_macros.h
new file mode 100644
index 0000000..c33c66e
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/util/sdk_macros.h
@@ -0,0 +1,215 @@
+/**
+ * Copyright (c) 2013 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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
+ *
+
+ * @defgroup sdk_common_macros SDK Common Header
+ * @ingroup app_common
+ * @brief Macros for parameter checking and similar tasks
+ * @{
+ */
+
+#ifndef SDK_MACROS_H__
+#define SDK_MACROS_H__
+
+#include "nrf_assert.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+/**@brief Macro for parameter checking.
+ *
+ * If @p _cond evaluates to true, does nothing. Otherwise,
+ * if @p _module ## _PARAM_CHECK_DISABLED is @e not set (default), prints an error message
+ * if @p _printfn is provided, and returns from the calling function context with code @p _err.
+ * If @p _module ## _PARAM_CHECK_DISABLED is set, behaves like the ASSERT macro.
+ *
+ * Parameter checking implemented using this macro can be optionally turned off for release code.
+ * Only disable runtime parameter checks if size if a major concern.
+ *
+ * @param _module The module name.
+ * @param _cond The condition to be evaluated.
+ * @param _err The error to be returned.
+ * @param _printfn A printf-compatible function used to log the error.
+ * Leave empty if no logging is needed.
+ *
+ * @hideinitializer
+ */
+/*lint -esym(666, NRF_PARAM_CHECK*) : Expression with side effects passed to macro */
+#define NRF_PARAM_CHECK(_module, _cond, _err, _printfn) \
+ do \
+ { \
+ if ((_cond)) \
+ { \
+ /* Do nothing. */ \
+ } \
+ else if (!(_module ## _PARAM_CHECK_DISABLED)) \
+ { \
+ _printfn("%s check failed in %s() with value 0x%x.", #_cond, __func__, _err); \
+ return (_err); \
+ } \
+ else \
+ { \
+ ASSERT((_cond)); \
+ } \
+ } while (0);
+
+
+/**@brief Macro for verifying statement to be true. It will cause the exterior function to return
+ * err_code if the statement is not true.
+ *
+ * @param[in] statement Statement to test.
+ * @param[in] err_code Error value to return if test was invalid.
+ *
+ * @retval nothing, but will cause the exterior function to return @p err_code if @p statement
+ * is false.
+ */
+#define VERIFY_TRUE(statement, err_code) \
+do \
+{ \
+ if (!(statement)) \
+ { \
+ return err_code; \
+ } \
+} while (0)
+
+
+/**@brief Macro for verifying statement to be true. It will cause the exterior function to return
+ * if the statement is not true.
+ *
+ * @param[in] statement Statement to test.
+ */
+#define VERIFY_TRUE_VOID(statement) VERIFY_TRUE((statement), )
+
+
+/**@brief Macro for verifying statement to be false. It will cause the exterior function to return
+ * err_code if the statement is not false.
+ *
+ * @param[in] statement Statement to test.
+ * @param[in] err_code Error value to return if test was invalid.
+ *
+ * @retval nothing, but will cause the exterior function to return @p err_code if @p statement
+ * is true.
+ */
+#define VERIFY_FALSE(statement, err_code) \
+do \
+{ \
+ if ((statement)) \
+ { \
+ return err_code; \
+ } \
+} while (0)
+
+
+/**@brief Macro for verifying statement to be false. It will cause the exterior function to return
+ * if the statement is not false.
+ *
+ * @param[in] statement Statement to test.
+ */
+#define VERIFY_FALSE_VOID(statement) VERIFY_FALSE((statement), )
+
+
+/**@brief Macro for verifying that a function returned NRF_SUCCESS. It will cause the exterior
+ * function to return error code of statement if it is not @ref NRF_SUCCESS.
+ *
+ * @param[in] statement Statement to check against NRF_SUCCESS.
+ */
+#define VERIFY_SUCCESS(statement) \
+do \
+{ \
+ uint32_t _err_code = (uint32_t) (statement); \
+ if (_err_code != NRF_SUCCESS) \
+ { \
+ return _err_code; \
+ } \
+} while(0)
+
+
+/**@brief Macro for verifying that a function returned NRF_SUCCESS. It will cause the exterior
+ * function to return if the err_code is not @ref NRF_SUCCESS.
+ *
+ * @param[in] err_code The error code to check.
+ */
+#define VERIFY_SUCCESS_VOID(err_code) VERIFY_TRUE_VOID((err_code) == NRF_SUCCESS)
+
+
+/**@brief Macro for verifying that the module is initialized. It will cause the exterior function to
+ * return @ref NRF_ERROR_INVALID_STATE if not.
+ *
+ * @note MODULE_INITIALIZED must be defined in each module using this macro. MODULE_INITIALIZED
+ * should be true if the module is initialized, false if not.
+ */
+#define VERIFY_MODULE_INITIALIZED() VERIFY_TRUE((MODULE_INITIALIZED), NRF_ERROR_INVALID_STATE)
+
+
+/**@brief Macro for verifying that the module is initialized. It will cause the exterior function to
+ * return if not.
+ *
+ * @note MODULE_INITIALIZED must be defined in each module using this macro. MODULE_INITIALIZED
+ * should be true if the module is initialized, false if not.
+ */
+#define VERIFY_MODULE_INITIALIZED_VOID() VERIFY_TRUE_VOID((MODULE_INITIALIZED))
+
+
+/**@brief Macro for verifying that the module is initialized. It will cause the exterior function to
+ * return if not.
+ *
+ * @param[in] param The variable to check if is NULL.
+ */
+#define VERIFY_PARAM_NOT_NULL(param) VERIFY_FALSE(((param) == NULL), NRF_ERROR_NULL)
+
+
+/**@brief Macro for verifying that the module is initialized. It will cause the exterior function to
+ * return if not.
+ *
+ * @param[in] param The variable to check if is NULL.
+ */
+#define VERIFY_PARAM_NOT_NULL_VOID(param) VERIFY_FALSE_VOID(((param) == NULL))
+
+/** @} */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // SDK_MACROS_H__
+
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/util/sdk_mapped_flags.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/util/sdk_mapped_flags.c
new file mode 100644
index 0000000..df5c09a
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/util/sdk_mapped_flags.c
@@ -0,0 +1,220 @@
+/**
+ * Copyright (c) 2015 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#include "sdk_mapped_flags.h"
+#include <stdint.h>
+#include <stdbool.h>
+#include <stddef.h>
+#include "compiler_abstraction.h"
+
+
+// Test whether the flag collection type is large enough to hold all the flags. If this fails,
+// reduce SDK_MAPPED_FLAGS_N_KEYS or increase the size of sdk_mapped_flags_t.
+STATIC_ASSERT((sizeof(sdk_mapped_flags_t) * SDK_MAPPED_FLAGS_N_KEYS_PER_BYTE) >= SDK_MAPPED_FLAGS_N_KEYS);
+
+
+/**@brief Function for setting the state of a flag to true.
+ *
+ * @note This function does not check whether the index is valid.
+ *
+ * @param[in] p_flags The collection of flags to modify.
+ * @param[in] index The index of the flag to modify.
+ */
+static __INLINE void sdk_mapped_flags_set_by_index(sdk_mapped_flags_t * p_flags, uint16_t index)
+{
+ *p_flags |= (1U << index);
+}
+
+
+/**@brief Function for setting the state of a flag to false.
+ *
+ * @note This function does not check whether the index is valid.
+ *
+ * @param[in] p_flags The collection of flags to modify.
+ * @param[in] index The index of the flag to modify.
+ */
+static __INLINE void sdk_mapped_flags_clear_by_index(sdk_mapped_flags_t * p_flags, uint16_t index)
+{
+ *p_flags &= ~(1U << index);
+}
+
+
+/**@brief Function for getting the state of a flag.
+ *
+ * @note This function does not check whether the index is valid.
+ *
+ * @param[in] p_flags The collection of flags to read.
+ * @param[in] index The index of the flag to get.
+ */
+static __INLINE bool sdk_mapped_flags_get_by_index(sdk_mapped_flags_t flags, uint16_t index)
+{
+ return ((flags & (1 << index)) != 0);
+}
+
+
+
+uint16_t sdk_mapped_flags_first_key_index_get(sdk_mapped_flags_t flags)
+{
+ for (uint16_t i = 0; i < SDK_MAPPED_FLAGS_N_KEYS; i++)
+ {
+ if (sdk_mapped_flags_get_by_index(flags, i))
+ {
+ return i;
+ }
+ }
+ return SDK_MAPPED_FLAGS_INVALID_INDEX;
+}
+
+
+void sdk_mapped_flags_update_by_key(uint16_t * p_keys,
+ sdk_mapped_flags_t * p_flags,
+ uint16_t key,
+ bool value)
+{
+ sdk_mapped_flags_bulk_update_by_key(p_keys, p_flags, 1, key, value);
+}
+
+
+void sdk_mapped_flags_bulk_update_by_key(uint16_t * p_keys,
+ sdk_mapped_flags_t * p_flags,
+ uint32_t n_flag_collections,
+ uint16_t key,
+ bool value)
+{
+ if ((p_keys != NULL) && (p_flags != NULL) && (n_flag_collections > 0))
+ {
+ for (uint32_t i = 0; i < SDK_MAPPED_FLAGS_N_KEYS; i++)
+ {
+ if (p_keys[i] == key)
+ {
+ for (uint32_t j = 0; j < n_flag_collections; j++)
+ {
+ if (value)
+ {
+ sdk_mapped_flags_set_by_index(&p_flags[j], i);
+ }
+ else
+ {
+ sdk_mapped_flags_clear_by_index(&p_flags[j], i);
+ }
+ }
+ return;
+ }
+ }
+ }
+}
+
+
+bool sdk_mapped_flags_get_by_key_w_idx(uint16_t * p_keys,
+ sdk_mapped_flags_t flags,
+ uint16_t key,
+ uint8_t * p_index)
+{
+ if (p_keys != NULL)
+ {
+ for (uint32_t i = 0; i < SDK_MAPPED_FLAGS_N_KEYS; i++)
+ {
+ if (p_keys[i] == key)
+ {
+ if (p_index != NULL)
+ {
+ *p_index = i;
+ }
+ return sdk_mapped_flags_get_by_index(flags, i);
+ }
+ }
+ }
+ if (p_index != NULL)
+ {
+ *p_index = SDK_MAPPED_FLAGS_N_KEYS;
+ }
+ return false;
+}
+
+
+bool sdk_mapped_flags_get_by_key(uint16_t * p_keys, sdk_mapped_flags_t flags, uint16_t key)
+{
+ if (p_keys != NULL)
+ {
+ for (uint32_t i = 0; i < SDK_MAPPED_FLAGS_N_KEYS; i++)
+ {
+ if (p_keys[i] == key)
+ {
+ return sdk_mapped_flags_get_by_index(flags, i);
+ }
+ }
+ }
+ return false;
+}
+
+
+sdk_mapped_flags_key_list_t sdk_mapped_flags_key_list_get(uint16_t * p_keys,
+ sdk_mapped_flags_t flags)
+{
+ sdk_mapped_flags_key_list_t key_list;
+ key_list.len = 0;
+
+ if (p_keys != NULL)
+ {
+ for (uint32_t i = 0; i < SDK_MAPPED_FLAGS_N_KEYS; i++)
+ {
+ if (sdk_mapped_flags_get_by_index(flags, i))
+ {
+ key_list.flag_keys[key_list.len++] = p_keys[i];
+ }
+ }
+ }
+
+ return key_list;
+}
+
+
+uint32_t sdk_mapped_flags_n_flags_set(sdk_mapped_flags_t flags)
+{
+ uint32_t n_flags_set = 0;
+
+ for (uint32_t i = 0; i < SDK_MAPPED_FLAGS_N_KEYS; i++)
+ {
+ if (sdk_mapped_flags_get_by_index(flags, i))
+ {
+ n_flags_set += 1;
+ }
+ }
+ return n_flags_set;
+}
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/util/sdk_mapped_flags.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/util/sdk_mapped_flags.h
new file mode 100644
index 0000000..2432c88
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/util/sdk_mapped_flags.h
@@ -0,0 +1,199 @@
+/**
+ * Copyright (c) 2015 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#ifndef SDK_MAPPED_FLAGS_H__
+#define SDK_MAPPED_FLAGS_H__
+
+#include <stdint.h>
+#include <stdbool.h>
+#include "app_util.h"
+#include "compiler_abstraction.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @file
+ * @defgroup sdk_mapped_flags Mapped flags
+ * @ingroup app_common
+ * @{
+ * @brief Module for writing and reading flags that are associated
+ * with keys.
+ *
+ * @details The flags are represented as bits in a bitmap called a <i>flag collection</i>. The keys
+ * are uint16_t. Each flag collection contains all flags of the same type, one flag for
+ * each key.
+ *
+ * The mapped flags module does not keep the flag states, nor the list of keys. These are
+ * provided in the API calls. A key's index in the key list determines which bit in the
+ * flag collection is associated with it. This module does not ever edit the key list, and
+ * does not edit flags except in function calls that take the flag collection as a pointer.
+ *
+ */
+
+#define SDK_MAPPED_FLAGS_N_KEYS 32 /**< The number of keys to keep flags for. This is also the number of flags in a flag collection. If changing this value, you might also need change the width of the sdk_mapped_flags_t type. */
+#define SDK_MAPPED_FLAGS_N_KEYS_PER_BYTE 8 /**< The number of flags that fit in one byte. */
+#define SDK_MAPPED_FLAGS_INVALID_INDEX 0xFFFF /**< A flag index guaranteed to be invalid. */
+
+typedef uint32_t sdk_mapped_flags_t; /**< The bitmap to hold flags. Each flag is one bit, and each bit represents the flag state associated with one key. */
+
+
+/**@brief Type used to present a subset of the registered keys.
+ */
+typedef struct
+{
+ uint32_t len; /**< The length of the list. */
+ uint16_t flag_keys[SDK_MAPPED_FLAGS_N_KEYS]; /**< The list of keys. */
+} sdk_mapped_flags_key_list_t;
+
+
+/**@brief Function for getting the first index at which the flag is true in the provided
+ * collection.
+ *
+ * @param[in] flags The flag collection to search for a flag set to true.
+ *
+ * @return The first index that has its flag set to true. If none were found, the
+ * function returns @ref SDK_MAPPED_FLAGS_INVALID_INDEX.
+ */
+uint16_t sdk_mapped_flags_first_key_index_get(sdk_mapped_flags_t flags);
+
+
+/**@brief Function for updating the state of a flag.
+ *
+ * @param[in] p_keys The list of associated keys (assumed to have a length of
+ * @ref SDK_MAPPED_FLAGS_N_KEYS).
+ * @param[out] p_flags The flag collection to modify.
+ * @param[in] key The key to modify the flag of.
+ * @param[in] value The state to set the flag to.
+ */
+void sdk_mapped_flags_update_by_key(uint16_t * p_keys,
+ sdk_mapped_flags_t * p_flags,
+ uint16_t key,
+ bool value);
+
+
+/**@brief Function for updating the state of the same flag in multiple flag collections.
+ *
+ * @details The key and value are the same for all flag collections in the p_flags array.
+ *
+ * @param[in] p_keys The list of associated keys (assumed to have a length of
+ * @ref SDK_MAPPED_FLAGS_N_KEYS).
+ * @param[out] p_flags The flag collections to modify.
+ * @param[out] n_flag_collections The number of flag collections in p_flags.
+ * @param[in] key The key to modify the flag of.
+ * @param[in] value The state to set the flag to.
+ */
+void sdk_mapped_flags_bulk_update_by_key(uint16_t * p_keys,
+ sdk_mapped_flags_t * p_flags,
+ uint32_t n_flag_collections,
+ uint16_t key,
+ bool value);
+
+
+/**@brief Function for getting the state of a specific flag.
+ *
+ * @param[in] p_keys The list of associated keys (assumed to have a length of
+ * @ref SDK_MAPPED_FLAGS_N_KEYS).
+ * @param[in] flags The flag collection to read from.
+ * @param[in] key The key to get the flag for.
+ *
+ * @return The state of the flag.
+ */
+bool sdk_mapped_flags_get_by_key(uint16_t * p_keys, sdk_mapped_flags_t flags, uint16_t key);
+
+
+/**@brief Function for getting the state of a specific flag.
+ *
+ * @param[in] p_keys The list of associated keys (assumed to have a length of
+ * @ref SDK_MAPPED_FLAGS_N_KEYS).
+ * @param[in] flags The flag collection from which to read.
+ * @param[in] key The key for which to get the flag.
+ * @param[out] p_index If not NULL, the index of the key.
+ *
+ * @return The state of the flag.
+ */
+bool sdk_mapped_flags_get_by_key_w_idx(uint16_t * p_keys,
+ sdk_mapped_flags_t flags,
+ uint16_t key,
+ uint8_t * p_index);
+
+
+/**@brief Function for getting a list of all keys that have a specific flag set to true.
+ *
+ * @param[in] p_keys The list of associated keys (assumed to have a length of
+ * @ref SDK_MAPPED_FLAGS_N_KEYS).
+ * @param[in] flags The flag collection to search.
+ *
+ * @return The list of keys.
+ */
+sdk_mapped_flags_key_list_t sdk_mapped_flags_key_list_get(uint16_t * p_keys,
+ sdk_mapped_flags_t flags);
+
+
+/**@brief Function for getting the number of keys that have a specific flag set to true.
+ *
+ * @param[in] flags The flag collection to search.
+ *
+ * @return The number of keys.
+ */
+uint32_t sdk_mapped_flags_n_flags_set(sdk_mapped_flags_t flags);
+
+
+/**@brief Function for querying whether any flags in the collection are set.
+ *
+ * @param[in] flags The flag collection to query.
+ *
+ * @retval true If one or more flags are set to true.
+ * @retval false Otherwise.
+ */
+static __INLINE bool sdk_mapped_flags_any_set(sdk_mapped_flags_t flags)
+{
+ return (flags != 0);
+}
+
+
+/** @} */
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* SDK_MAPPED_FLAGS_H__ */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/util/sdk_os.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/util/sdk_os.h
new file mode 100644
index 0000000..6aeb3d4
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/util/sdk_os.h
@@ -0,0 +1,76 @@
+/**
+ * Copyright (c) 2013 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+/** @cond */
+/**@file
+ *
+ * @defgroup sdk_os SDK OS Abstraction
+ * @ingroup experimental_api
+ * @details In order to made SDK modules independent of use of an embedded OS, and permit
+ * application with varied task architecture, SDK abstracts the OS specific
+ * elements here in order to make all other modules agnostic to the OS or task
+ * architecture.
+ * @{
+ */
+
+#ifndef SDK_OS_H__
+#define SDK_OS_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define SDK_MUTEX_DEFINE(X)
+#define SDK_MUTEX_INIT(X)
+#define SDK_MUTEX_LOCK(X)
+#define SDK_MUTEX_UNLOCK(X)
+
+/**
+ * @defgroup os_data_type Data types.
+ */
+
+/** @} */
+/** @endcond */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // SDK_OS_H__
+
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/util/sdk_resources.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/util/sdk_resources.h
new file mode 100644
index 0000000..eaef717
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/util/sdk_resources.h
@@ -0,0 +1,86 @@
+/**
+ * Copyright (c) 2015 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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
+ * @brief Definition file for resource usage by SoftDevice, ESB and Gazell.
+ */
+
+#ifndef SDK_RESOURCES_H__
+#define SDK_RESOURCES_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#if defined(SOFTDEVICE_PRESENT) || defined (BLE_STACK_SUPPORT_REQD) || defined (ANT_STACK_SUPPORT_REQD)
+ #include "nrf_sd_def.h"
+#else
+ #define SD_PPI_RESTRICTED 0uL /**< 1 if PPI peripheral is restricted, 0 otherwise. */
+ #define SD_PPI_CHANNELS_USED 0uL /**< PPI channels utilized by SotfDevice (not available to th spplication). */
+ #define SD_PPI_GROUPS_USED 0uL /**< PPI groups utilized by SotfDevice (not available to th spplication). */
+ #define SD_TIMERS_USED 0uL /**< Timers used by SoftDevice. */
+ #define SD_SWI_USED 0uL /**< Software interrupts used by SoftDevice. */
+#endif
+
+#ifdef GAZELL_PRESENT
+ #include "nrf_gzll_resources.h"
+#else
+ #define GZLL_PPI_CHANNELS_USED 0uL /**< PPI channels utilized by Gazell (not available to th spplication). */
+ #define GZLL_TIMERS_USED 0uL /**< Timers used by Gazell. */
+ #define GZLL_SWI_USED 0uL /**< Software interrupts used by Gazell */
+#endif
+
+#ifdef ESB_PRESENT
+ #include "nrf_esb_resources.h"
+#else
+ #define ESB_PPI_CHANNELS_USED 0uL /**< PPI channels utilized by ESB (not available to th spplication). */
+ #define ESB_TIMERS_USED 0uL /**< Timers used by ESB. */
+ #define ESB_SWI_USED 0uL /**< Software interrupts used by ESB */
+#endif
+
+#define NRF_PPI_CHANNELS_USED (SD_PPI_CHANNELS_USED | GZLL_PPI_CHANNELS_USED | ESB_PPI_CHANNELS_USED)
+#define NRF_PPI_GROUPS_USED (SD_PPI_GROUPS_USED)
+#define NRF_SWI_USED (SD_SWI_USED | GZLL_SWI_USED | ESB_SWI_USED)
+#define NRF_TIMERS_USED (SD_TIMERS_USED | GZLL_TIMERS_USED | ESB_TIMERS_USED)
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // SDK_RESOURCES_H__
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/ndef/conn_hand_parser/ac_rec_parser/nfc_ac_rec_parser.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/ndef/conn_hand_parser/ac_rec_parser/nfc_ac_rec_parser.c
new file mode 100644
index 0000000..58934c1
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/ndef/conn_hand_parser/ac_rec_parser/nfc_ac_rec_parser.c
@@ -0,0 +1,205 @@
+/**
+ * Copyright (c) 2016 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#include "sdk_common.h"
+#if NRF_MODULE_ENABLED(NFC_AC_REC_PARSER)
+#include "nfc_ac_rec_parser.h"
+#include "sdk_macros.h"
+
+/**
+ * @brief Function for parsing Data Reference field inside Alternative Carrier record payload.
+ *
+ * This function parses Data Reference field inside Alternative Carrier record payload and extracts
+ * its descriptor.
+ *
+ * @param[in,out] pp_buff Pointer to pointer to the remaining payload data.
+ * @param[in,out] p_len Pointer to the length of remaining payload data.
+ * @param[in,out] p_ref_field Pointer to the structure that will be used to hold
+ * parsed data.
+ *
+ * @retval NRF_SUCCESS If the function completed successfully.
+ * @retval NRF_ERROR_NULL If provided buffer for Data Reference in \p p_ref_field is
+ * null.
+ * @retval NRF_ERROR_NO_MEM If the buffer provided for Data Reference in \p p_ref_field
+ * does not have enough space to store it.
+ * @retval NRF_ERROR_INVALID_LENGTH If Data Reference length exceeds record payload.
+ */
+static ret_code_t ac_rec_reference_field_parse(uint8_t ** const pp_buff,
+ uint32_t * const p_len,
+ nfc_ac_rec_data_ref_t * const p_ref_field)
+{
+ if (p_ref_field->length < **pp_buff)
+ {
+ return NRF_ERROR_NO_MEM;
+ }
+ p_ref_field->length = **pp_buff;
+ *pp_buff += AC_REC_DATA_REF_LEN_SIZE;
+ (*p_len) -= AC_REC_DATA_REF_LEN_SIZE;
+
+ if (*p_len < p_ref_field->length)
+ {
+ return NRF_ERROR_INVALID_LENGTH;
+ }
+ VERIFY_PARAM_NOT_NULL(p_ref_field->p_data);
+ memcpy( p_ref_field->p_data,
+ *pp_buff,
+ p_ref_field->length );
+ *pp_buff += p_ref_field->length;
+ (*p_len) -= p_ref_field->length;
+
+ return NRF_SUCCESS;
+}
+
+/**
+ * @brief Function for parsing Alternative Carrier record payload.
+ *
+ * This function parses Alternative Carrier record payload and extracts its payload descriptor.
+ *
+ * @param[in] p_buff Pointer to the record payload.
+ * @param[in] p_len Pointer to the record payload length.
+ * @param[in,out] p_ac_rec_payload_data Pointer to the structure that will be used to hold
+ * parsed data.
+ *
+ * @retval NRF_SUCCESS If the function completed successfully.
+ * @retval NRF_ERROR_NULL If any provided arguments or any needed buffers stored in
+ * \p p_ac_rec_payload_data are nulls.
+ * @retval NRF_ERROR_NO_MEM If any from provided buffers does not have enough space
+ * to store its data.
+ * @retval NRF_ERROR_INVALID_LENGTH If any length field exceeds record payload.
+ * @retval NRF_ERROR_INVALID_PARAM If Carrier Power State field has incorrect value.
+ */
+static ret_code_t nfc_ac_payload_parse(uint8_t * p_buff,
+ uint32_t * const p_len,
+ nfc_ac_rec_payload_desc_t * const p_ac_rec_payload_data)
+{
+ if ( (p_buff == NULL) || (p_len == NULL) || (p_ac_rec_payload_data == NULL) )
+ {
+ return NRF_ERROR_NULL;
+ }
+
+ if (*p_len < AC_REC_CPS_BYTE_SIZE + AC_REC_DATA_REF_LEN_SIZE + AC_REC_AUX_DATA_REF_COUNT_SIZE)
+ {
+ return NRF_ERROR_INVALID_LENGTH;
+ }
+
+ // Copy CPS to ac record payload descriptor.
+ if (*p_buff & ~NFC_AC_CPS_MASK)
+ {
+ return NRF_ERROR_INVALID_PARAM;
+ }
+
+ p_ac_rec_payload_data->cps = (nfc_ac_rec_cps_t) *p_buff;
+ p_buff += AC_REC_CPS_BYTE_SIZE;
+ (*p_len) -= AC_REC_CPS_BYTE_SIZE;
+
+ // Copy Carrier Data Reference to ac record payload descriptor.
+ ret_code_t err_code = ac_rec_reference_field_parse(&p_buff,
+ p_len,
+ &p_ac_rec_payload_data->carrier_data_ref);
+ VERIFY_SUCCESS(err_code);
+
+ // Copy Auxiliary Data Reference to ac record payload descriptor.
+ if ( p_ac_rec_payload_data->aux_data_ref_count < *p_buff)
+ {
+ return NRF_ERROR_NO_MEM;
+ }
+ p_ac_rec_payload_data->aux_data_ref_count = *p_buff;
+ p_buff += AC_REC_AUX_DATA_REF_COUNT_SIZE;
+ (*p_len) -= AC_REC_AUX_DATA_REF_COUNT_SIZE;
+
+ if (p_ac_rec_payload_data->aux_data_ref_count != 0)
+ {
+ VERIFY_PARAM_NOT_NULL(p_ac_rec_payload_data->p_aux_data_ref);
+ }
+
+ for (uint8_t i = 0; i < p_ac_rec_payload_data->aux_data_ref_count; i++)
+ {
+ err_code = ac_rec_reference_field_parse(&p_buff,
+ p_len,
+ &(p_ac_rec_payload_data->p_aux_data_ref[i]));
+ VERIFY_SUCCESS(err_code);
+ }
+
+ // Check if all payload data were parsed.
+ if (*p_len != 0)
+ {
+ return NRF_ERROR_INVALID_LENGTH;
+ }
+
+ return NRF_SUCCESS;
+}
+
+ret_code_t nfc_ac_rec_parse(nfc_ndef_record_desc_t const * const p_rec_desc,
+ nfc_ac_rec_payload_desc_t * const p_ac_rec_payload_data)
+{
+ ret_code_t err_code;
+
+ if (p_rec_desc->tnf != TNF_WELL_KNOWN)
+ {
+ return NRF_ERROR_INVALID_DATA;
+ }
+
+ if (p_rec_desc->type_length != sizeof(nfc_ac_rec_type_field))
+ {
+ return NRF_ERROR_INVALID_DATA;
+ }
+
+ if (memcmp(p_rec_desc->p_type, nfc_ac_rec_type_field, sizeof(nfc_ac_rec_type_field)) != 0)
+ {
+ return NRF_ERROR_INVALID_DATA;
+ }
+
+ if (p_rec_desc->payload_constructor != (p_payload_constructor_t) nfc_ndef_bin_payload_memcopy)
+ {
+ return NRF_ERROR_NOT_SUPPORTED;
+ }
+
+ uint8_t const * p_payload =
+ ((nfc_ndef_bin_payload_desc_t *)(p_rec_desc->p_payload_descriptor))->p_payload;
+ uint32_t payload_length =
+ ((nfc_ndef_bin_payload_desc_t *)(p_rec_desc->p_payload_descriptor))->payload_length;
+
+ err_code = nfc_ac_payload_parse((uint8_t *) p_payload,
+ &payload_length,
+ p_ac_rec_payload_data);
+
+ return err_code;
+}
+
+#endif // NRF_MODULE_ENABLED(NFC_AC_REC_PARSER)
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/ndef/conn_hand_parser/ac_rec_parser/nfc_ac_rec_parser.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/ndef/conn_hand_parser/ac_rec_parser/nfc_ac_rec_parser.h
new file mode 100644
index 0000000..998084f
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/ndef/conn_hand_parser/ac_rec_parser/nfc_ac_rec_parser.h
@@ -0,0 +1,88 @@
+/**
+ * Copyright (c) 2016 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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
+ *
+ * @defgroup nfc_ac_rec_parser Alternative Carrier records parser
+ * @{
+ * @ingroup nfc_ble_pair_msg
+ * @brief Functions for parsing and decoding Alternative Carrier records.
+ */
+
+#ifndef __NFC_AC_REC_PARSER_H__
+#define __NFC_AC_REC_PARSER_H__
+
+#include "nfc_ndef_record.h"
+#include "nfc_ac_rec.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @brief Function for parsing general record description as Alternative Carrier record.
+ *
+ * This function checks if record description matches the Alternative Carrier record and extracts
+ * its payload structure. It is required for the record description to use binary payload
+ * descriptor.
+ *
+ * @param[in] p_rec_desc Pointer to the record descriptor.
+ * @param[in,out] p_ac_rec_payload_data Pointer to the structure that will be used to hold
+ * parsed data.
+ *
+ * @retval NRF_SUCCESS If the function completed successfully.
+ * @retval NRF_ERROR_INVALID_DATA If the NDEF record type or TNF is incorrect.
+ * @retval NRF_ERROR_NOT_SUPPORTED If the payload descriptor is not binary.
+ * @retval NRF_ERROR_NULL If any provided arguments or any needed buffers stored in
+ * \p p_ac_rec_payload_data are nulls.
+ * @retval NRF_ERROR_NO_MEM If any from provided buffers does not have enough space
+ * to store its data.
+ * @retval NRF_ERROR_INVALID_LENGTH If any length field exceeds record payload.
+ * @retval NRF_ERROR_INVALID_PARAM If Carrier Power State field has incorrect value.
+ */
+ret_code_t nfc_ac_rec_parse(nfc_ndef_record_desc_t const * const p_rec_desc,
+ nfc_ac_rec_payload_desc_t * const p_ac_rec_payload_data);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // __NFC_AC_REC_PARSER_H__
+
+/** @} */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/ndef/conn_hand_parser/ble_oob_advdata_parser/nfc_ble_oob_advdata_parser.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/ndef/conn_hand_parser/ble_oob_advdata_parser/nfc_ble_oob_advdata_parser.c
new file mode 100644
index 0000000..41ec302
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/ndef/conn_hand_parser/ble_oob_advdata_parser/nfc_ble_oob_advdata_parser.c
@@ -0,0 +1,524 @@
+/**
+ * Copyright (c) 2016 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#include "sdk_common.h"
+#if NRF_MODULE_ENABLED(NFC_BLE_OOB_ADVDATA_PARSER)
+#include "nfc_ble_oob_advdata_parser.h"
+#include "app_util.h"
+#include "nfc_ble_pair_common.h"
+
+#define NRF_LOG_MODULE_NAME ble_oob_ad_parser
+#include "nrf_log.h"
+NRF_LOG_MODULE_REGISTER();
+
+/* Workaround for using NRF_LOG_RAW_INFO() macro only when logging level is "DEBUG" */
+#if (NRF_LOG_LEVEL > 3)
+#define NRF_BLE_OOB_AD_PARSER_LOG_DEBUG(...) NRF_LOG_RAW_INFO(__VA_ARGS__)
+#else // (NRF_LOG_LEVEL > 3)
+#define NRF_BLE_OOB_AD_PARSER_LOG_DEBUG(...)
+#endif // (NRF_LOG_LEVEL > 3)
+
+#define EARLY_TERMINATOR 0 /* Value of AD Structure Length field indicating an early
+ termination of Advertising or Scan Response Data. */
+#define FIELD_LEN_INC_VAL 1 /* Incorrect Value of AD Structure Length field. */
+
+/** @brief Values used with @ref ad_type_counter_t. */
+typedef enum
+{
+ AD_TYPE_NOT_PRESENT = 0, /* Value indicating that AD type is not present. */
+ AD_TYPE_OCCUR_THRES = 1 /* Maximal occurrence number of any AD type within the buffer */
+} ad_type_counter_values_t;
+
+/**@brief Internal module structure indicating how many BLE AD fields of the same type are in the buffer. */
+typedef struct
+{
+ uint8_t name_type; /* Number of Short and Full Device Name AD Structures. */
+ uint8_t addr_type; /* Number of LE Bluetooth Device Address AD Structures. */
+ uint8_t appear_type; /* Number of Appearance AD Structures. */
+ uint8_t flags_type; /* Number of Flags AD Structures. */
+ uint8_t le_role_type; /* Number of LE Role AD Structures. */
+ uint8_t tk_type; /* Number of Security Manager TK AD Structures. */
+ uint8_t sec_mgr_oob_flags_type; /* Number of Security Manager OOB Flags AD Structures. */
+ uint8_t lesc_confirm_type; /* Number of LESC OOB Confirmation Value AD Structures. */
+ uint8_t lesc_random_type; /* Number of LESC OOB Random Value AD Structures. */
+} ad_type_counter_t;
+
+/**@brief Decodes and stores AD Data from Flags AD Structure. */
+__STATIC_INLINE ret_code_t flags_decode(uint8_t const * p_flags_data,
+ uint8_t len,
+ nfc_ble_oob_pairing_data_t * p_nfc_ble_pairing_data)
+{
+ if (len != AD_TYPE_FLAGS_DATA_SIZE)
+ {
+ return NRF_ERROR_INVALID_LENGTH;
+ }
+
+ p_nfc_ble_pairing_data->flags = *p_flags_data;
+
+ return NRF_SUCCESS;
+}
+
+void nfc_oob_data_printout(nfc_ble_oob_pairing_data_t const * const p_pairing_data)
+{
+ NRF_LOG_RAW_INFO("\r\n");
+ NRF_LOG_INFO("BLE Advertising data contents");
+ NRF_LOG_INFO("Device name: \"%s\"", NRF_LOG_PUSH((char *)p_pairing_data->device_name.p_name));
+ NRF_LOG_INFO("Device Address: ");
+
+ for (int i=0; i < BLE_GAP_ADDR_LEN; ++i)
+ {
+ NRF_LOG_RAW_INFO("%02X ", p_pairing_data->p_device_addr->addr[i]);
+ }
+ NRF_LOG_RAW_INFO("\r\n");
+
+ if (p_pairing_data->p_tk_value != NULL)
+ {
+ NRF_LOG_INFO("Device Temporary Key present.");
+ for (int i=0; i < BLE_GAP_SEC_KEY_LEN; ++i)
+ {
+ NRF_BLE_OOB_AD_PARSER_LOG_DEBUG("%02X ", p_pairing_data->p_tk_value->tk[i]);
+ }
+ NRF_BLE_OOB_AD_PARSER_LOG_DEBUG("\r\n");
+ }
+ else
+ {
+ NRF_LOG_INFO("Device Temporary Key not present.");
+ }
+
+ if (p_pairing_data->p_lesc_confirm_value != NULL && p_pairing_data->p_lesc_random_value)
+ {
+ NRF_LOG_INFO("LESC Confirmation Value present.");
+ for (int i=0; i < BLE_GAP_SEC_KEY_LEN; ++i)
+ {
+ NRF_BLE_OOB_AD_PARSER_LOG_DEBUG("%02X ", p_pairing_data->p_lesc_confirm_value[i]);
+ }
+ NRF_BLE_OOB_AD_PARSER_LOG_DEBUG("\r\n");
+
+ NRF_LOG_INFO("LESC Random Value present.");
+ for (int i=0; i < BLE_GAP_SEC_KEY_LEN; ++i)
+ {
+ NRF_BLE_OOB_AD_PARSER_LOG_DEBUG("%02X ", p_pairing_data->p_lesc_random_value[i]);
+ }
+ NRF_BLE_OOB_AD_PARSER_LOG_DEBUG("\r\n");
+ }
+ else
+ {
+ NRF_LOG_INFO("LESC data not present.");
+ }
+
+ NRF_LOG_RAW_INFO("\r\n");
+}
+
+/**@brief Decodes and stores AD Data that is common for Short and Full Device Name AD Structures. */
+static ret_code_t name_decode(uint8_t const * p_name_data,
+ uint8_t len,
+ nfc_ble_oob_pairing_data_t * p_nfc_ble_pairing_data)
+{
+ uint8_t * p_name = p_nfc_ble_pairing_data->device_name.p_name;
+ uint8_t * p_name_len = &p_nfc_ble_pairing_data->device_name.len;
+
+ VERIFY_PARAM_NOT_NULL(p_name);
+ if (*p_name_len < len)
+ {
+ return NRF_ERROR_NO_MEM;
+ }
+
+ memcpy(p_name, p_name_data, len);
+ *p_name_len = len;
+
+ return NRF_SUCCESS;
+}
+
+/**@brief Decodes and stores AD Data from Short Device Name AD Structure. */
+__STATIC_INLINE ret_code_t short_name_decode(uint8_t const * p_short_name_data,
+ uint8_t len,
+ nfc_ble_oob_pairing_data_t * p_nfc_ble_pairing_data)
+{
+ p_nfc_ble_pairing_data->device_name.name_type = BLE_ADVDATA_SHORT_NAME;
+
+ return name_decode(p_short_name_data, len, p_nfc_ble_pairing_data);
+}
+
+/**@brief Decodes and stores AD Data from Full Device Name AD Structure. */
+__STATIC_INLINE ret_code_t full_name_decode(uint8_t const * p_full_name_data,
+ uint8_t len,
+ nfc_ble_oob_pairing_data_t * p_nfc_ble_pairing_data)
+{
+ p_nfc_ble_pairing_data->device_name.name_type = BLE_ADVDATA_FULL_NAME;
+
+ return name_decode(p_full_name_data, len, p_nfc_ble_pairing_data);
+}
+
+/**@brief Decodes and stores AD Data from Security Manager TK AD Structure. */
+static ret_code_t tk_value_decode(uint8_t const * p_tk_value_data,
+ uint8_t len,
+ nfc_ble_oob_pairing_data_t * p_nfc_ble_pairing_data)
+{
+ if (len != AD_TYPE_TK_VALUE_DATA_SIZE)
+ {
+ return NRF_ERROR_INVALID_LENGTH;
+ }
+
+ ble_advdata_tk_value_t * p_tk_value = p_nfc_ble_pairing_data->p_tk_value;
+ VERIFY_PARAM_NOT_NULL(p_tk_value);
+
+ memcpy(p_tk_value->tk, p_tk_value_data, AD_TYPE_TK_VALUE_DATA_SIZE);
+
+ return NRF_SUCCESS;
+}
+
+/**@brief Decodes and stores AD Data from Security Manager TK AD Structure. */
+static ret_code_t lesc_confirm_value_decode(uint8_t const * p_lesc_confirm_value_data,
+ uint8_t len,
+ nfc_ble_oob_pairing_data_t * p_nfc_ble_pairing_data)
+{
+ if (len != AD_TYPE_CONFIRM_VALUE_DATA_SIZE)
+ {
+ return NRF_ERROR_INVALID_LENGTH;
+ }
+
+ uint8_t * p_lesc_confirm_data = p_nfc_ble_pairing_data->p_lesc_confirm_value;
+ VERIFY_PARAM_NOT_NULL(p_lesc_confirm_data);
+
+ memcpy(p_lesc_confirm_data, p_lesc_confirm_value_data, AD_TYPE_CONFIRM_VALUE_DATA_SIZE);
+
+ return NRF_SUCCESS;
+}
+
+/**@brief Decodes and stores AD Data from Security Manager TK AD Structure. */
+static ret_code_t lesc_random_value_decode(uint8_t const * p_lesc_random_value_data,
+ uint8_t len,
+ nfc_ble_oob_pairing_data_t * p_nfc_ble_pairing_data)
+{
+ if (len != AD_TYPE_RANDOM_VALUE_DATA_SIZE)
+ {
+ return NRF_ERROR_INVALID_LENGTH;
+ }
+
+ uint8_t * p_lesc_random_data = p_nfc_ble_pairing_data->p_lesc_random_value;
+ VERIFY_PARAM_NOT_NULL(p_lesc_random_data);
+
+ memcpy(p_lesc_random_data, p_lesc_random_value_data, AD_TYPE_RANDOM_VALUE_DATA_SIZE);
+
+ return NRF_SUCCESS;
+}
+
+/**@brief Decodes and stores AD Data from Security Manager OOB Flags AD Structure. */
+static ret_code_t sec_mgr_oob_flags_decode(uint8_t const * p_sec_mgr_oob_flags_data,
+ uint8_t len,
+ nfc_ble_oob_pairing_data_t * p_nfc_ble_pairing_data)
+{
+ if (len != AD_TYPE_OOB_FLAGS_DATA_SIZE)
+ {
+ return NRF_ERROR_INVALID_LENGTH;
+ }
+
+ VERIFY_PARAM_NOT_NULL(p_nfc_ble_pairing_data->p_sec_mgr_oob_flags);
+ *(p_nfc_ble_pairing_data->p_sec_mgr_oob_flags) = *(p_sec_mgr_oob_flags_data);
+
+ return NRF_SUCCESS;
+}
+
+/**@brief Decodes and stores AD Data from Appearance AD Structure. */
+static ret_code_t appearance_decode(uint8_t const * p_appearance_data,
+ uint8_t len,
+ nfc_ble_oob_pairing_data_t * p_nfc_ble_pairing_data)
+{
+ if (len != AD_TYPE_APPEARANCE_DATA_SIZE)
+ {
+ return NRF_ERROR_INVALID_LENGTH;
+ }
+
+ p_nfc_ble_pairing_data->appearance = uint16_decode(p_appearance_data);
+
+ return NRF_SUCCESS;
+}
+
+/**@brief Decodes and stores AD Data from LE Bluetooth Device Address AD Structure. */
+static ret_code_t ble_device_addr_decode(uint8_t const * p_dev_addr_data,
+ uint8_t len,
+ nfc_ble_oob_pairing_data_t * p_nfc_ble_pairing_data)
+{
+ if (len != AD_TYPE_BLE_DEVICE_ADDR_DATA_SIZE)
+ {
+ return NRF_ERROR_INVALID_LENGTH;
+ }
+
+ ble_gap_addr_t * p_device_addr = p_nfc_ble_pairing_data->p_device_addr;
+ VERIFY_PARAM_NOT_NULL(p_device_addr);
+
+ memcpy(p_device_addr->addr, p_dev_addr_data, BLE_GAP_ADDR_LEN);
+ p_device_addr->addr_type = *(p_dev_addr_data + BLE_GAP_ADDR_LEN);
+
+ return NRF_SUCCESS;
+}
+
+/**@brief Decodes and stores AD Data from LE Role AD Structure. */
+static ret_code_t le_role_decode(uint8_t const * p_le_role_data,
+ uint8_t len,
+ nfc_ble_oob_pairing_data_t * p_nfc_ble_pairing_data)
+{
+ if (len != AD_TYPE_LE_ROLE_DATA_SIZE)
+ {
+ return NRF_ERROR_INVALID_LENGTH;
+ }
+
+ uint8_t le_role = *p_le_role_data;
+ switch (le_role)
+ {
+ case NFC_BLE_ADVDATA_ROLE_ENCODED_ONLY_PERIPH:
+ p_nfc_ble_pairing_data->le_role = BLE_ADVDATA_ROLE_ONLY_PERIPH;
+ break;
+
+ case NFC_BLE_ADVDATA_ROLE_ENCODED_ONLY_CENTRAL:
+ p_nfc_ble_pairing_data->le_role = BLE_ADVDATA_ROLE_ONLY_CENTRAL;
+ break;
+
+ case NFC_BLE_ADVDATA_ROLE_ENCODED_BOTH_PERIPH_PREFERRED:
+ p_nfc_ble_pairing_data->le_role = BLE_ADVDATA_ROLE_BOTH_PERIPH_PREFERRED;
+ break;
+
+ case NFC_BLE_ADVDATA_ROLE_ENCODED_BOTH_CENTRAL_PREFERRED:
+ p_nfc_ble_pairing_data->le_role = BLE_ADVDATA_ROLE_BOTH_CENTRAL_PREFERRED;
+ break;
+
+ default:
+ return NRF_ERROR_INVALID_PARAM;
+ }
+
+ return NRF_SUCCESS;
+}
+
+/**@brief Validates if Length field of AD structure is correct. */
+__STATIC_INLINE ret_code_t field_length_validate(uint8_t field_length, uint8_t index, uint8_t len)
+{
+ if ( (field_length == FIELD_LEN_INC_VAL) || (index + field_length >= len) )
+ {
+ return NRF_ERROR_INVALID_LENGTH;
+ }
+ else
+ {
+ return NRF_SUCCESS;
+ }
+}
+
+/**@brief Validates which AD types were not present in parsed data and checks if any
+ * AD Type occured more than once.
+ */
+__STATIC_INLINE ret_code_t field_type_validate(nfc_ble_oob_pairing_data_t * p_nfc_ble_pairing_data,
+ ad_type_counter_t * ad_type_counter)
+{
+ /* Reset AD type fields which were not present in parsed buffer. */
+ if (ad_type_counter->name_type == AD_TYPE_NOT_PRESENT)
+ {
+ p_nfc_ble_pairing_data->device_name.p_name = NULL;
+ p_nfc_ble_pairing_data->device_name.len = 0;
+ p_nfc_ble_pairing_data->device_name.name_type = BLE_ADVDATA_NO_NAME;
+ }
+ if ( (ad_type_counter->addr_type == AD_TYPE_NOT_PRESENT) &&
+ (p_nfc_ble_pairing_data->p_device_addr != NULL) )
+ {
+ p_nfc_ble_pairing_data->p_device_addr = NULL;
+ }
+ if ( (ad_type_counter->tk_type == AD_TYPE_NOT_PRESENT) &&
+ (p_nfc_ble_pairing_data->p_tk_value != NULL) )
+ {
+ p_nfc_ble_pairing_data->p_tk_value = NULL;
+ }
+ if ( (ad_type_counter->lesc_confirm_type == AD_TYPE_NOT_PRESENT) &&
+ (p_nfc_ble_pairing_data->p_lesc_confirm_value != NULL) )
+ {
+ p_nfc_ble_pairing_data->p_lesc_confirm_value = NULL;
+ }
+ if ( (ad_type_counter->lesc_random_type == AD_TYPE_NOT_PRESENT) &&
+ (p_nfc_ble_pairing_data->p_lesc_random_value != NULL) )
+ {
+ p_nfc_ble_pairing_data->p_lesc_random_value = NULL;
+ }
+ if ( (ad_type_counter->sec_mgr_oob_flags_type == AD_TYPE_NOT_PRESENT) &&
+ (p_nfc_ble_pairing_data->p_sec_mgr_oob_flags != NULL) )
+ {
+ p_nfc_ble_pairing_data->p_sec_mgr_oob_flags = NULL;
+ }
+ if (ad_type_counter->appear_type == AD_TYPE_NOT_PRESENT)
+ {
+ p_nfc_ble_pairing_data->appearance = BLE_ADVDATA_APPEARANCE_NOT_PRESENT;
+ }
+ if (ad_type_counter->flags_type == AD_TYPE_NOT_PRESENT)
+ {
+ p_nfc_ble_pairing_data->flags = 0;
+ }
+ if (ad_type_counter->le_role_type == AD_TYPE_NOT_PRESENT)
+ {
+ p_nfc_ble_pairing_data->le_role = BLE_ADVDATA_ROLE_NOT_PRESENT;
+ }
+
+ /* Check if any AD Type was doubled. */
+ if ( (ad_type_counter->name_type > AD_TYPE_OCCUR_THRES) ||
+ (ad_type_counter->addr_type > AD_TYPE_OCCUR_THRES) ||
+ (ad_type_counter->tk_type > AD_TYPE_OCCUR_THRES) ||
+ (ad_type_counter->sec_mgr_oob_flags_type > AD_TYPE_OCCUR_THRES) ||
+ (ad_type_counter->appear_type > AD_TYPE_OCCUR_THRES) ||
+ (ad_type_counter->flags_type > AD_TYPE_OCCUR_THRES) ||
+ (ad_type_counter->le_role_type > AD_TYPE_OCCUR_THRES) ||
+ (ad_type_counter->lesc_confirm_type > AD_TYPE_OCCUR_THRES) ||
+ (ad_type_counter->lesc_random_type > AD_TYPE_OCCUR_THRES) )
+ {
+ return NRF_ERROR_NOT_SUPPORTED;
+ }
+
+ return NRF_SUCCESS;
+}
+
+ret_code_t nfc_ble_oob_advdata_parse(uint8_t const * p_advdata,
+ uint8_t len,
+ nfc_ble_oob_pairing_data_t * p_nfc_ble_pairing_data)
+{
+ ret_code_t err_code = NRF_SUCCESS;
+ uint8_t index = 0;
+
+ ad_type_counter_t ad_type_counter;
+ memset(&ad_type_counter, AD_TYPE_NOT_PRESENT, sizeof(ad_type_counter_t));
+
+ if ( (p_nfc_ble_pairing_data == NULL) || (p_advdata == NULL) )
+ {
+ return NRF_ERROR_NULL;
+ }
+
+ while (index < len)
+ {
+ uint8_t field_length = p_advdata[index];
+ if (field_length == EARLY_TERMINATOR)
+ {
+ return NRF_SUCCESS;
+ }
+ err_code = field_length_validate(field_length, index, len);
+ VERIFY_SUCCESS(err_code);
+
+ uint8_t field_type = p_advdata[index + AD_LENGTH_FIELD_SIZE];
+ uint8_t const * p_field_data = &p_advdata[index + AD_DATA_OFFSET];
+ uint8_t field_data_len = field_length - AD_TYPE_FIELD_SIZE;
+
+ switch (field_type)
+ {
+ case BLE_GAP_AD_TYPE_FLAGS:
+ ++ad_type_counter.flags_type;
+ err_code = flags_decode(p_field_data,
+ field_data_len,
+ p_nfc_ble_pairing_data);
+ break;
+
+ case BLE_GAP_AD_TYPE_SHORT_LOCAL_NAME:
+ ++ad_type_counter.name_type;
+ err_code = short_name_decode(p_field_data,
+ field_data_len,
+ p_nfc_ble_pairing_data);
+ break;
+
+ case BLE_GAP_AD_TYPE_COMPLETE_LOCAL_NAME:
+ ++ad_type_counter.name_type;
+ err_code = full_name_decode(p_field_data,
+ field_data_len,
+ p_nfc_ble_pairing_data);
+ break;
+
+ case BLE_GAP_AD_TYPE_SECURITY_MANAGER_TK_VALUE:
+ ++ad_type_counter.tk_type;
+ err_code = tk_value_decode(p_field_data,
+ field_data_len,
+ p_nfc_ble_pairing_data);
+ break;
+
+ case BLE_GAP_AD_TYPE_LESC_CONFIRMATION_VALUE:
+ ++ad_type_counter.lesc_confirm_type;
+ err_code = lesc_confirm_value_decode(p_field_data,
+ field_data_len,
+ p_nfc_ble_pairing_data);
+ break;
+
+ case BLE_GAP_AD_TYPE_LESC_RANDOM_VALUE:
+ ++ad_type_counter.lesc_random_type;
+ err_code = lesc_random_value_decode(p_field_data,
+ field_data_len,
+ p_nfc_ble_pairing_data);
+ break;
+
+ case BLE_GAP_AD_TYPE_SECURITY_MANAGER_OOB_FLAGS:
+ ++ad_type_counter.sec_mgr_oob_flags_type;
+ err_code = sec_mgr_oob_flags_decode(p_field_data,
+ field_data_len,
+ p_nfc_ble_pairing_data);
+ break;
+
+ case BLE_GAP_AD_TYPE_APPEARANCE:
+ ++ad_type_counter.appear_type;
+ err_code = appearance_decode(p_field_data,
+ field_data_len,
+ p_nfc_ble_pairing_data);
+ break;
+
+ case BLE_GAP_AD_TYPE_LE_BLUETOOTH_DEVICE_ADDRESS:
+ ++ad_type_counter.addr_type;
+ err_code = ble_device_addr_decode(p_field_data,
+ field_data_len,
+ p_nfc_ble_pairing_data);
+ break;
+
+ case BLE_GAP_AD_TYPE_LE_ROLE:
+ ++ad_type_counter.le_role_type;
+ err_code = le_role_decode(p_field_data,
+ field_data_len,
+ p_nfc_ble_pairing_data);
+ break;
+
+ default:
+ /* AD Structure Type field unknown for parser. */
+ return NRF_ERROR_NOT_SUPPORTED;
+ }
+
+ VERIFY_SUCCESS(err_code);
+
+ index += field_length + AD_LENGTH_FIELD_SIZE;
+ }
+
+ err_code = field_type_validate(p_nfc_ble_pairing_data, &ad_type_counter);
+ return err_code;
+}
+
+#endif // NRF_MODULE_ENABLED(NFC_BLE_OOB_ADVDATA_PARSER)
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/ndef/conn_hand_parser/ble_oob_advdata_parser/nfc_ble_oob_advdata_parser.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/ndef/conn_hand_parser/ble_oob_advdata_parser/nfc_ble_oob_advdata_parser.h
new file mode 100644
index 0000000..6168e98
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/ndef/conn_hand_parser/ble_oob_advdata_parser/nfc_ble_oob_advdata_parser.h
@@ -0,0 +1,137 @@
+/**
+ * Copyright (c) 2016 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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
+ *
+ * @defgroup nfc_ble_oob_advdata_parser Advertising and Scan Response Data Parser for NFC OOB pairing
+ * @{
+ * @ingroup nfc_ble_pair_msg
+ * @brief Functions for parsing and decoding data in the Advertising and Scan Response
+ * Data format for NFC OOB pairing.
+ */
+
+#ifndef NFC_BLE_OOB_ADVDATA_PARSER_H_
+#define NFC_BLE_OOB_ADVDATA_PARSER_H_
+
+#include "sdk_errors.h"
+#include "ble_advdata.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define BLE_ADVDATA_APPEARANCE_NOT_PRESENT 0 /**< Appearance AD structure not present. */
+
+/**@brief Bluetooth Low Energy GAP device name. */
+typedef struct
+{
+ ble_advdata_name_type_t name_type; /**< See @ref ble_advdata_name_type_t. */
+ uint8_t len; /**< Length of device name. */
+ uint8_t * p_name; /**< Pointer to the buffer with device name. */
+} ble_gap_dev_name_t;
+
+/**@brief BLE Advertising data that is relevant for OOB pairing. */
+typedef struct
+{
+ ble_gap_dev_name_t device_name; /**< See @ref ble_gap_dev_name_t. */
+ ble_gap_addr_t * p_device_addr; /**< See @ref ble_gap_addr_t. */
+ ble_advdata_tk_value_t * p_tk_value; /**< See @ref ble_advdata_tk_value_t. */
+ uint8_t * p_lesc_confirm_value; /**< LESC OOB confirmation data. */
+ uint8_t * p_lesc_random_value; /**< LESC OOB random data. */
+ ble_advdata_le_role_t le_role; /**< See @ref ble_advdata_le_role_t. */
+ uint16_t appearance; /**< Advertising data Appearance field. */
+ uint8_t flags; /**< Advertising data Flags field. */
+ uint8_t * p_sec_mgr_oob_flags; /**< Security Manager Out Of Band Flags data field. */
+} nfc_ble_oob_pairing_data_t;
+
+/**@brief Function for parsing BLE data encoded in AD Type format.
+ *
+ * @details This function parses BLE data encoded in Advertising Data Type format which
+ * can be generated with @ref ble_advdata_encode function. The result of the parsing is
+ * stored within @ref nfc_ble_oob_pairing_data_t structure.
+ *
+ * @note Currently, module can be used to parse BLE AD Type data, which contains
+ * AD Structures with following GAP AD Types: Flags, Shortened and Complete Device
+ * Name, Security Manager TK Value and OOB Flags, Appearance, LE Bluetooth Device
+ * Address and LE Role.
+ *
+ * @warning Before passing \p p_nfc_ble_pairing_data structure to this function,
+ * it is necessary to provide buffers for AD Structures Data, which are expected to be
+ * found within parsed buffer. This applies to following GAP AD Types with corresponding
+ * structures: Shortened and Complete Device Name - @ref ble_gap_dev_name_t,
+ * LE Bluetooth Device Address - @ref ble_gap_addr_t, Security Manager TK Value -
+ * @ref ble_advdata_tk_value_t and Security Manager OOB Flags - uint8_t.
+ *
+ * @param[in] p_advdata Pointer to the data to be parsed.
+ * @param[in] len Size of the data to be parsed.
+ * @param[out] p_nfc_ble_pairing_data Pointer to the structure that will be used
+ * to hold parsed data.
+ *
+ * @retval NRF_SUCCESS If the function completed successfully.
+ * @retval NRF_ERROR_NO_MEM If the provided buffer for device name is
+ * too small to hold parsed data.
+ * @retval NRF_ERROR_INVALID_LENGTH If any AD Structure Length field contains
+ * different value than expected.
+ * @retval NRF_ERROR_INVALID_PARAM If any AD Structure Data field contains
+ * invalid parameters.
+ * @retval NRF_ERROR_NULL If any function pointer parameter is NULL or
+ * any expected buffer in \p p_nfc_ble_pairing_data
+ * was not provided.
+ * @retval NRF_ERROR_NOT_SUPPORTED If any AD Structure Type field contains
+ * type which is not supported or any AD
+ * Structure Type occurs more than once.
+ */
+ret_code_t nfc_ble_oob_advdata_parse(uint8_t const * p_advdata,
+ uint8_t len,
+ nfc_ble_oob_pairing_data_t * p_nfc_ble_pairing_data);
+
+
+/**@brief Function for displaying values of basic BLE OOB Advertising data types.
+ *
+ * @param[in] p_pairing_data Structure containing parsed data.
+ */
+void nfc_oob_data_printout(nfc_ble_oob_pairing_data_t const * const p_pairing_data);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif //NFC_BLE_OOB_ADVDATA_PARSER_H__
+
+/** @} */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/ndef/conn_hand_parser/le_oob_rec_parser/nfc_le_oob_rec_parser.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/ndef/conn_hand_parser/le_oob_rec_parser/nfc_le_oob_rec_parser.c
new file mode 100644
index 0000000..98ea901
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/ndef/conn_hand_parser/le_oob_rec_parser/nfc_le_oob_rec_parser.c
@@ -0,0 +1,104 @@
+/**
+ * Copyright (c) 2016 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#include "sdk_common.h"
+#if NRF_MODULE_ENABLED(NFC_LE_OOB_REC_PARSER)
+#include "nfc_le_oob_rec_parser.h"
+#include "sdk_errors.h"
+
+/**
+ * @brief Function for parsing LE OOB record payload.
+ *
+ * This function parses LE OOB record payload and extracts BLE OOB Advertising data structure.
+ *
+ * @param[in] p_buff Pointer to the record payload.
+ * @param[in] p_len Pointer to the record payload length.
+ * @param[in,out] p_nfc_ble_oob_pairing_data Pointer to the structure that will be used to hold
+ * parsed data.
+ *
+ * @retval NRF_SUCCESS If the function completed successfully.
+ * @retval Other An error code that might have been returned by
+ * @ref nfc_ble_oob_advdata_parse function.
+ */
+static ret_code_t nfc_le_oob_payload_parse(uint8_t * p_buff,
+ uint32_t * const p_len,
+ nfc_ble_oob_pairing_data_t * const p_nfc_ble_oob_pairing_data)
+{
+ ret_code_t err_code = nfc_ble_oob_advdata_parse(p_buff,
+ *p_len,
+ p_nfc_ble_oob_pairing_data);
+ return err_code;
+}
+
+ret_code_t nfc_le_oob_rec_parse(nfc_ndef_record_desc_t const * const p_rec_desc,
+ nfc_ble_oob_pairing_data_t * const p_nfc_ble_oob_pairing_data)
+{
+ ret_code_t err_code;
+
+ if (p_rec_desc->tnf != TNF_MEDIA_TYPE)
+ {
+ return NRF_ERROR_INVALID_DATA;
+ }
+
+ if (p_rec_desc->type_length != sizeof(le_oob_rec_type_field))
+ {
+ return NRF_ERROR_INVALID_DATA;
+ }
+
+ if (memcmp(p_rec_desc->p_type, le_oob_rec_type_field, sizeof(le_oob_rec_type_field)) != 0)
+ {
+ return NRF_ERROR_INVALID_DATA;
+ }
+
+ if (p_rec_desc->payload_constructor != (p_payload_constructor_t) nfc_ndef_bin_payload_memcopy)
+ {
+ return NRF_ERROR_NOT_SUPPORTED;
+ }
+
+ uint8_t const * p_payload = ((nfc_ndef_bin_payload_desc_t*)(p_rec_desc->p_payload_descriptor))->p_payload;
+ uint32_t payload_lenght = ((nfc_ndef_bin_payload_desc_t*)(p_rec_desc->p_payload_descriptor))->payload_length;
+
+ err_code = nfc_le_oob_payload_parse((uint8_t *) p_payload,
+ &payload_lenght,
+ p_nfc_ble_oob_pairing_data);
+
+ return err_code;
+}
+
+#endif // NRF_MODULE_ENABLED(NFC_LE_OOB_REC_PARSER)
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/ndef/conn_hand_parser/le_oob_rec_parser/nfc_le_oob_rec_parser.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/ndef/conn_hand_parser/le_oob_rec_parser/nfc_le_oob_rec_parser.h
new file mode 100644
index 0000000..0df5657
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/ndef/conn_hand_parser/le_oob_rec_parser/nfc_le_oob_rec_parser.h
@@ -0,0 +1,85 @@
+/**
+ * Copyright (c) 2016 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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
+ *
+ * @defgroup nfc_le_oob_rec_parser LE OOB records parser
+ * @{
+ * @ingroup nfc_ble_pair_msg
+ * @brief Functions for parsing and decoding LE OOB records.
+ */
+
+#ifndef __NFC_LE_OOB_REC_PARSER_H__
+#define __NFC_LE_OOB_REC_PARSER_H__
+
+#include "nfc_ndef_record.h"
+#include "nfc_ble_oob_advdata_parser.h"
+#include "nfc_ble_pair_common.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @brief Function for parsing general record description as LE OOB record.
+ *
+ * This function checks if record description matches the LE OOB record pattern and extracts BLE
+ * OOB Advertising data structure. It is required for the record description to use binary payload
+ * descriptor.
+ *
+ * @param[in] p_rec_desc Pointer to the record descriptor.
+ * @param[in,out] p_nfc_ble_oob_pairing_data Pointer to the structure that will be used to hold
+ * parsed data.
+ *
+ * @retval NRF_SUCCESS If the function completed successfully.
+ * @retval NRF_ERROR_INVALID_DATA If the NDEF record type or TNF is incorrect.
+ * @retval NRF_ERROR_NOT_SUPPORTED If the payload descriptor is not binary.
+ * @retval Other An error code that might have been returned by
+ * @ref nfc_ble_oob_advdata_parse function.
+ */
+ret_code_t nfc_le_oob_rec_parse(nfc_ndef_record_desc_t const * const p_rec_desc,
+ nfc_ble_oob_pairing_data_t * const p_nfc_ble_oob_pairing_data);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // __NFC_LE_OOB_REC_PARSER_H__
+
+/** @} */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/ndef/connection_handover/ac_rec/nfc_ac_rec.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/ndef/connection_handover/ac_rec/nfc_ac_rec.c
new file mode 100644
index 0000000..c4cdabe
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/ndef/connection_handover/ac_rec/nfc_ac_rec.c
@@ -0,0 +1,164 @@
+/**
+ * Copyright (c) 2015 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#include "sdk_common.h"
+#if NRF_MODULE_ENABLED(NFC_AC_REC)
+
+#include "nfc_ac_rec.h"
+#include <string.h>
+#include "nrf_error.h"
+#include "nrf.h"
+
+#define AC_REC_CPS_BYTE_SIZE 1 ///< Size of the field with CPS data.
+#define AC_REC_DATA_REF_LEN_SIZE 1 ///< Size of the Data Reference Length field.
+#define AC_REC_AUX_DATA_REF_COUNT_SIZE 1 ///< Size of the Data Reference Length field.
+
+const uint8_t nfc_ac_rec_type_field[2] = {'a', 'c'}; ///< Alternative Carrier Record type.
+
+/**
+ * @brief Function for calculating the payload length of the NFC NDEF Alternative Carrier record.
+ */
+static uint32_t nfc_ac_rec_payload_size_get(nfc_ac_rec_payload_desc_t const * p_ac_rec_payload_desc)
+{
+ int32_t i = 0;
+ // Initialize with size of byte with CPS.
+ uint32_t payload_size = AC_REC_CPS_BYTE_SIZE;
+
+ // Add Carrier Data Reference size.
+ payload_size += p_ac_rec_payload_desc->carrier_data_ref.length + AC_REC_DATA_REF_LEN_SIZE;
+
+ // Add Auxiliary Data Reference Count size.
+ payload_size += AC_REC_AUX_DATA_REF_COUNT_SIZE;
+
+ for (i = 0; i < p_ac_rec_payload_desc->aux_data_ref_count; i++)
+ {
+ // Add Auxiliary Data Reference size.
+ payload_size += p_ac_rec_payload_desc->p_aux_data_ref[i].length + AC_REC_DATA_REF_LEN_SIZE;
+ }
+
+ return payload_size;
+}
+
+
+ret_code_t nfc_ac_rec_payload_constructor(nfc_ac_rec_payload_desc_t * p_nfc_rec_ac_payload_desc,
+ uint8_t * p_buff,
+ uint32_t * p_len)
+{
+ int32_t i = 0;
+ uint32_t payload_size = nfc_ac_rec_payload_size_get(p_nfc_rec_ac_payload_desc);
+
+ if (p_buff != NULL)
+ {
+ // Not enough space in the buffer, return an error.
+ if (payload_size > *p_len)
+ {
+ return NRF_ERROR_NO_MEM;
+ }
+
+ // Invalid CPS value.
+ if ( p_nfc_rec_ac_payload_desc->cps & ~NFC_AC_CPS_MASK )
+ {
+ return NRF_ERROR_INVALID_PARAM;
+ }
+
+ // Copy CPS.
+ *p_buff = p_nfc_rec_ac_payload_desc->cps;
+ p_buff += AC_REC_CPS_BYTE_SIZE;
+
+ // Copy Carrier Data Reference.
+ *p_buff = p_nfc_rec_ac_payload_desc->carrier_data_ref.length;
+ p_buff += AC_REC_DATA_REF_LEN_SIZE;
+
+ memcpy( p_buff,
+ p_nfc_rec_ac_payload_desc->carrier_data_ref.p_data,
+ p_nfc_rec_ac_payload_desc->carrier_data_ref.length );
+ p_buff += p_nfc_rec_ac_payload_desc->carrier_data_ref.length;
+
+ // Copy Auxiliary Data Reference.
+ *p_buff = p_nfc_rec_ac_payload_desc->aux_data_ref_count;
+ p_buff += AC_REC_AUX_DATA_REF_COUNT_SIZE;
+
+ for (i = 0; i < p_nfc_rec_ac_payload_desc->aux_data_ref_count; i++)
+ {
+ *p_buff = p_nfc_rec_ac_payload_desc->p_aux_data_ref[i].length;
+ p_buff += AC_REC_DATA_REF_LEN_SIZE;
+
+ memcpy( p_buff,
+ p_nfc_rec_ac_payload_desc->p_aux_data_ref[i].p_data,
+ p_nfc_rec_ac_payload_desc->p_aux_data_ref[i].length );
+ p_buff += p_nfc_rec_ac_payload_desc->p_aux_data_ref[i].length;
+ }
+ }
+
+ // Assign payload size to the return buffer.
+ *p_len = payload_size;
+
+ return NRF_SUCCESS;
+}
+
+
+void nfc_ac_rec_auxiliary_data_ref_clear(nfc_ndef_record_desc_t * p_ac_rec)
+{
+ nfc_ac_rec_payload_desc_t * p_ac_rec_payload =
+ (nfc_ac_rec_payload_desc_t*)p_ac_rec->p_payload_descriptor;
+
+ p_ac_rec_payload->aux_data_ref_count = 0;
+}
+
+
+ret_code_t nfc_ac_rec_auxiliary_data_ref_add(nfc_ndef_record_desc_t * p_ac_rec,
+ uint8_t * p_aux_data,
+ uint8_t aux_length)
+{
+ nfc_ac_rec_payload_desc_t * p_ac_rec_payload =
+ (nfc_ac_rec_payload_desc_t *)p_ac_rec->p_payload_descriptor;
+
+ if (p_ac_rec_payload->aux_data_ref_count >= p_ac_rec_payload->max_aux_data_ref)
+ {
+ return NRF_ERROR_NO_MEM;
+ }
+
+ p_ac_rec_payload->p_aux_data_ref[p_ac_rec_payload->aux_data_ref_count].p_data = p_aux_data;
+ p_ac_rec_payload->p_aux_data_ref[p_ac_rec_payload->aux_data_ref_count].length = aux_length;
+ p_ac_rec_payload->aux_data_ref_count++;
+
+ return NRF_SUCCESS;
+}
+
+#endif // NRF_MODULE_ENABLED(NFC_AC_REC)
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/ndef/connection_handover/ac_rec/nfc_ac_rec.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/ndef/connection_handover/ac_rec/nfc_ac_rec.h
new file mode 100644
index 0000000..d748d2a
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/ndef/connection_handover/ac_rec/nfc_ac_rec.h
@@ -0,0 +1,199 @@
+/**
+ * Copyright (c) 2015 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#ifndef NFC_AC_REC_H__
+#define NFC_AC_REC_H__
+
+/**@file
+ *
+ * @defgroup nfc_ac_rec ac (Alternative carrier) records
+ * @{
+ * @ingroup nfc_ble_pair_msg
+ *
+ * @brief Generation of NFC NDEF Alternative Carrier records for NDEF messages.
+ *
+ */
+
+#include <stdint.h>
+#include "nfc_ndef_record.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define AC_REC_CPS_BYTE_SIZE 1 ///< Size of the field with CPS data.
+#define AC_REC_DATA_REF_LEN_SIZE 1 ///< Size of the Data Reference Length field.
+#define AC_REC_AUX_DATA_REF_COUNT_SIZE 1 ///< Size of the Data Reference Length field.
+
+/**
+ * @brief Carrier Power State.
+ *
+ * Possible Carrier Power State field values in an Alternative Carrier record.
+ */
+typedef enum
+{
+ NFC_AC_CPS_INACTIVE = 0x00, ///< Alternative Carrier inactive.
+ NFC_AC_CPS_ACTIVE = 0x01, ///< Alternative Carrier active.
+ NFC_AC_CPS_ACTIVATING = 0x02, ///< Alternative Carrier activating.
+ NFC_AC_CPS_UNKNOWN = 0x03 ///< Alternative Carrier power status unknown.
+} nfc_ac_rec_cps_t;
+
+#define NFC_AC_CPS_MASK (NFC_AC_CPS_UNKNOWN) ///< Mask of Carrier Power State bits in a first ac record byte.
+
+/**
+ * @brief Carrier Data Reference and Auxiliary Data Reference descriptor.
+ */
+typedef struct
+{
+ uint8_t length; ///< Length of the data field.
+ uint8_t * p_data; ///< Pointer to the Data Reference characters. Not relevant if length is 0.
+} nfc_ac_rec_data_ref_t;
+
+/**
+ * @brief Alternative Carrier record payload descriptor.
+ */
+typedef struct
+{
+ nfc_ac_rec_cps_t cps; ///< Carrier Power State value.
+ nfc_ac_rec_data_ref_t carrier_data_ref; ///< Carrier Data Reference.
+ uint8_t const max_aux_data_ref; ///< Maximum number of Auxiliary Data Reference fields.
+ uint8_t aux_data_ref_count; ///< Number of Auxiliary Data Reference fields.
+ nfc_ac_rec_data_ref_t * p_aux_data_ref; ///< Pointer to the Auxiliary Data Reference fields.
+} nfc_ac_rec_payload_desc_t;
+
+
+/**
+ * @brief Constructor for an NFC NDEF Alternative Carrier record payload.
+ *
+ * This function encodes the payload of an Alternative Carrier record as specified in the Connection
+ * Handover standard. It implements an API compatible with @ref p_payload_constructor_t.
+ */
+ret_code_t nfc_ac_rec_payload_constructor(nfc_ac_rec_payload_desc_t * p_nfc_rec_ac_payload_desc,
+ uint8_t * p_buff,
+ uint32_t * p_len);
+
+/**
+ * @brief External reference to the type field of the Alternative Carrier record, defined in the
+ * file @c nfc_ac_rec.c. It is used in the @ref NFC_NDEF_AC_RECORD_DESC_DEF macro.
+ */
+extern const uint8_t nfc_ac_rec_type_field[2];
+
+/**
+ * @brief Size of the type field of the Alternative Carrier record, defined in the
+ * file @c nfc_ac_rec.c. It is used in the @ref NFC_NDEF_AC_RECORD_DESC_DEF macro.
+ */
+#define NFC_AC_REC_TYPE_LENGTH 2
+
+/**
+ *@brief Macro for creating and initializing an NFC NDEF record descriptor for an Alternative Carrier record.
+ *
+ * This macro creates and initializes an instance of type @ref nfc_ndef_record_desc_t and
+ * an instance of type @ref nfc_ac_rec_payload_desc_t, which together constitute an instance of an Alternative Carrier record.
+ *
+ * Use the macro @ref NFC_NDEF_AC_RECORD_DESC to access the NDEF Alternative Carrier record descriptor instance.
+ *
+ * @note The record descriptor is declared as automatic variable, which implies that
+ * the NDEF message encoding (see @ref nfc_ble_full_handover_select_msg_encode)
+ * must be done in the same variable scope.
+ *
+ * @param[in] NAME Name of the created record descriptor instance.
+ * @param[in] CPS Carrier Power State value.
+ * @param[in] CARR_DATA_REF_LEN Length of the Carrier Data Reference field.
+ * @param[in] P_CARR_DATA_REF Pointer to the Carrier Data Reference field.
+ * @param[in] MAX_AUX_DATA_REF Maximum number of Auxiliary Data Reference fields.
+ */
+#define NFC_NDEF_AC_RECORD_DESC_DEF(NAME, \
+ CPS, \
+ CARR_DATA_REF_LEN, \
+ P_CARR_DATA_REF, \
+ MAX_AUX_DATA_REF) \
+ nfc_ac_rec_data_ref_t NAME##_nfc_ac_rec_aux_data_ref_array[MAX_AUX_DATA_REF]; \
+ nfc_ac_rec_payload_desc_t NAME##_nfc_ac_rec_payload_desc = \
+ { \
+ .cps = CPS, \
+ .carrier_data_ref = {CARR_DATA_REF_LEN, P_CARR_DATA_REF}, \
+ .max_aux_data_ref = MAX_AUX_DATA_REF, \
+ .aux_data_ref_count = 0, \
+ .p_aux_data_ref = NAME##_nfc_ac_rec_aux_data_ref_array \
+ }; \
+ NFC_NDEF_GENERIC_RECORD_DESC_DEF(NAME, \
+ TNF_WELL_KNOWN, \
+ 0, \
+ 0, \
+ nfc_ac_rec_type_field, \
+ NFC_AC_REC_TYPE_LENGTH, \
+ nfc_ac_rec_payload_constructor, \
+ &(NAME##_nfc_ac_rec_payload_desc))
+
+/**
+ * @brief Macro for accessing the NFC NDEF Alternative Carrier record descriptor
+ * instance that was created with @ref NFC_NDEF_AC_RECORD_DESC_DEF.
+ */
+#define NFC_NDEF_AC_RECORD_DESC(NAME) NFC_NDEF_GENERIC_RECORD_DESC(NAME)
+
+/**
+ * @brief Function for clearing an Auxiliary Data Reference in an NFC NDEF Alternative Carrier record.
+ *
+ * This function clears the Auxiliary Data References from the Alternative Carrier record.
+ *
+ * @param[in, out] p_ac_rec Pointer to the Alternative Carrier record descriptor.
+ */
+void nfc_ac_rec_auxiliary_data_ref_clear(nfc_ndef_record_desc_t * p_ac_rec);
+
+/**
+ * @brief Function for adding an Auxiliary Data Reference to an NFC NDEF Alternative Carrier record.
+ *
+ * @param[in, out] p_ac_rec Pointer to an ac record.
+ * @param[in] p_aux_data Pointer to the Auxiliary Data Reference data buffer.
+ * @param[in] aux_length Length of the Auxiliary Data Reference data.
+ *
+ * @retval NRF_SUCCESS If the Auxiliary Data Reference was added successfully.
+ * @retval NRF_ERROR_NO_MEM If the record already contains the maximum number of Auxiliary Data References.
+ */
+ret_code_t nfc_ac_rec_auxiliary_data_ref_add(nfc_ndef_record_desc_t * p_ac_rec,
+ uint8_t * p_aux_data,
+ uint8_t aux_length);
+
+/** @} */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // NFC_AC_REC_H__
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/ndef/connection_handover/ble_oob_advdata/nfc_ble_oob_advdata.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/ndef/connection_handover/ble_oob_advdata/nfc_ble_oob_advdata.c
new file mode 100644
index 0000000..588c504
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/ndef/connection_handover/ble_oob_advdata/nfc_ble_oob_advdata.c
@@ -0,0 +1,402 @@
+/**
+ * Copyright (c) 2012 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#include "sdk_common.h"
+#if NRF_MODULE_ENABLED(NFC_BLE_OOB_ADVDATA)
+
+#include "nfc_ble_oob_advdata.h"
+#include "sdk_common.h"
+#include "nfc_ble_pair_msg.h"
+#include "nfc_ble_pair_common.h"
+
+
+/**
+ * @brief Macro for verifying basic parameters used for encoding single BLE AD Type.
+ *
+ * It verifies if provided buffer is NULL and if there is enough space for the encoded data.
+ * In case of NULL pointer buffer, necessary space for current AD Type is calculated.
+ *
+ * @param[in] P_ENCODED_DATA Buffer for the encoded data.
+ * @param[in] P_OFFSET Pointer to index of the first free cell in the buffer.
+ * @param[in] AD_TYPE_SIZE Size of the single AD Type.
+ * @param[in] MAX_SIZE Maximal size of the provided buffer.
+ */
+#define NFC_BLE_OOB_ADVDATA_INPUT_VERIFY( P_ENCODED_DATA, P_OFFSET, AD_TYPE_SIZE, MAX_SIZE) \
+ if ( (P_ENCODED_DATA) == NULL ) \
+ { \
+ *(P_OFFSET) += (AD_TYPE_SIZE); \
+ return NRF_SUCCESS; \
+ } \
+ if ( *(P_OFFSET) + (AD_TYPE_SIZE) > (MAX_SIZE) ) \
+ { \
+ return NRF_ERROR_DATA_SIZE; \
+ }
+
+/**@brief Function for encoding data of Security Manager OOB Flags AD Type.
+ *
+ * @param[in] oob_flags Security Manager OOB Flags AD Type payload.
+ * @param[out] p_encoded_data Pointer to the buffer where encoded data will be returned.
+ * @param[in,out] p_offset \c in: Offset of \p p_encoded_data buffer before this AD type encoding.
+ * \c out: Offset of \p p_encoded_data buffer after this AD type encoding.
+ * @param[in] max_size Size of \p p_encoded_data buffer.
+ *
+ * @retval NRF_SUCCESS If the operation was successful.
+ * @retval NRF_ERROR_DATA_SIZE If the provided buffer size is too small.
+ */
+static ret_code_t sec_mgr_oob_flags_encode(uint8_t oob_flags,
+ uint8_t * p_encoded_data,
+ uint16_t * p_offset,
+ uint16_t max_size)
+{
+ NFC_BLE_OOB_ADVDATA_INPUT_VERIFY(p_encoded_data, p_offset, AD_TYPE_OOB_FLAGS_SIZE, max_size);
+
+ // Encode flags.
+ p_encoded_data[*p_offset] = (uint8_t)(AD_TYPE_FIELD_SIZE + AD_TYPE_OOB_FLAGS_DATA_SIZE);
+ *p_offset += AD_LENGTH_FIELD_SIZE;
+ p_encoded_data[*p_offset] = BLE_GAP_AD_TYPE_SECURITY_MANAGER_OOB_FLAGS;
+ *p_offset += AD_TYPE_FIELD_SIZE;
+ p_encoded_data[*p_offset] = oob_flags;
+ *p_offset += AD_TYPE_OOB_FLAGS_DATA_SIZE;
+
+ return NRF_SUCCESS;
+}
+
+/**@brief Function for encoding data of Security Manager TK Value AD Type.
+ *
+ * @param[in] p_tk_value Security Manager TK Value AD Type payload.
+ * @param[out] p_encoded_data Pointer to the buffer where encoded data will be returned.
+ * @param[in,out] p_offset \c in: Offset of \p p_encoded_data buffer before this AD type encoding.
+ * \c out: Offset of \p p_encoded_data buffer after this AD type encoding.
+ * @param[in] max_size Size of \p p_encoded_data buffer.
+ *
+ * @retval NRF_SUCCESS If the operation was successful.
+ * @retval NRF_ERROR_DATA_SIZE If the provided buffer size is too small.
+ */
+static ret_code_t tk_value_encode(ble_advdata_tk_value_t * p_tk_value,
+ uint8_t * p_encoded_data,
+ uint16_t * p_offset,
+ uint16_t max_size)
+{
+ ret_code_t err_code;
+
+ NFC_BLE_OOB_ADVDATA_INPUT_VERIFY(p_encoded_data, p_offset, AD_TYPE_TK_VALUE_SIZE, max_size);
+
+ // Encode TK Value.
+ p_encoded_data[*p_offset] = (uint8_t)(AD_TYPE_FIELD_SIZE + AD_TYPE_TK_VALUE_DATA_SIZE);
+ *p_offset += AD_LENGTH_FIELD_SIZE;
+ p_encoded_data[*p_offset] = BLE_GAP_AD_TYPE_SECURITY_MANAGER_TK_VALUE;
+ *p_offset += AD_TYPE_FIELD_SIZE;
+
+ // Remember location of TK in the buffer if this feature was enabled.
+ err_code = nfc_tk_to_group_add(&p_encoded_data[*p_offset]);
+ VERIFY_SUCCESS(err_code);
+
+ nfc_tk_value_payload_encode(p_tk_value, &p_encoded_data[*p_offset]);
+ (*p_offset) += AD_TYPE_TK_VALUE_DATA_SIZE;
+
+ return NRF_SUCCESS;
+}
+
+/**@brief Function for encoding LESC OOB data in the CH NDEF message.
+ *
+ * @param[in] p_lesc_value Pointer to the LESC OOB values to be encoded.
+ * @param[out] p_encoded_data Pointer to the buffer where encoded data will be returned.
+ * @param[in,out] p_offset \c in: Offset of \p p_encoded_data buffer before this AD type encoding.
+ * \c out: Offset of \p p_encoded_data buffer after this AD type encoding.
+ * @param[in] max_size Size of \p p_encoded_data buffer.
+ *
+ * @retval NRF_SUCCESS If the operation was successful.
+ * @retval NRF_ERROR_DATA_SIZE If the provided buffer size is too small.
+ */
+static ret_code_t lesc_value_encode(ble_gap_lesc_oob_data_t * p_lesc_value,
+ uint8_t * p_encoded_data,
+ uint16_t * p_offset,
+ uint16_t max_size)
+{
+ ret_code_t err_code;
+
+ NFC_BLE_OOB_ADVDATA_INPUT_VERIFY(p_encoded_data, p_offset, AD_TYPE_LESC_SIZE, max_size);
+
+ // Encode LESC Confirm Value.
+ p_encoded_data[*p_offset] = (uint8_t)(AD_TYPE_FIELD_SIZE + AD_TYPE_CONFIRM_VALUE_DATA_SIZE);
+ *p_offset += AD_LENGTH_FIELD_SIZE;
+ p_encoded_data[*p_offset] = BLE_GAP_AD_TYPE_LESC_CONFIRMATION_VALUE;
+ *p_offset += AD_TYPE_FIELD_SIZE;
+
+ memcpy(&p_encoded_data[*p_offset], p_lesc_value->c, sizeof(p_lesc_value->c));
+
+ uint8_t *p_confirm = &p_encoded_data[*p_offset];
+
+ (*p_offset) += AD_TYPE_CONFIRM_VALUE_DATA_SIZE;
+
+ // Encode LESC Random Value.
+ p_encoded_data[*p_offset] = (uint8_t)(AD_TYPE_FIELD_SIZE + AD_TYPE_RANDOM_VALUE_DATA_SIZE);
+ *p_offset += AD_LENGTH_FIELD_SIZE;
+ p_encoded_data[*p_offset] = BLE_GAP_AD_TYPE_LESC_RANDOM_VALUE;
+ *p_offset += AD_TYPE_FIELD_SIZE;
+
+ memcpy(&p_encoded_data[*p_offset], p_lesc_value->r, sizeof(p_lesc_value->r));
+
+ uint8_t *p_random = &p_encoded_data[*p_offset];
+
+ (*p_offset) += AD_TYPE_RANDOM_VALUE_DATA_SIZE;
+
+ // Remember location of LESC OOB data in the buffer in case of key changes.
+ err_code = nfc_lesc_pos_set(p_confirm, p_random);
+
+ return err_code;
+}
+
+/**@brief Function for encoding data of LE Role AD Type.
+ *
+ * @param[in] le_role LE Role AD Type payload.
+ * @param[out] p_encoded_data Pointer to the buffer where encoded data will be returned.
+ * @param[in,out] p_offset \c in: Offset of \p p_encoded_data buffer before this AD type encoding.
+ * \c out: Offset of \p p_encoded_data buffer after this AD type encoding.
+ * @param[in] max_size Size of \p p_encoded_data buffer.
+ *
+ * @retval NRF_SUCCESS If the operation was successful.
+ * @retval NRF_ERROR_DATA_SIZE If the provided buffer size is too small.
+ * @retval NRF_ERROR_INVALID_PARAM If \p le_role parameter has invalid value.
+ */
+static ret_code_t le_role_encode(ble_advdata_le_role_t le_role,
+ uint8_t * p_encoded_data,
+ uint16_t * p_offset,
+ uint16_t max_size)
+{
+ NFC_BLE_OOB_ADVDATA_INPUT_VERIFY(p_encoded_data, p_offset, AD_TYPE_LE_ROLE_SIZE, max_size);
+
+ // Encode LE Role.
+ p_encoded_data[*p_offset] = (uint8_t)(AD_TYPE_FIELD_SIZE + AD_TYPE_LE_ROLE_DATA_SIZE);
+ *p_offset += AD_LENGTH_FIELD_SIZE;
+ p_encoded_data[*p_offset] = BLE_GAP_AD_TYPE_LE_ROLE;
+ *p_offset += AD_TYPE_FIELD_SIZE;
+ switch (le_role)
+ {
+ case BLE_ADVDATA_ROLE_ONLY_PERIPH:
+ p_encoded_data[*p_offset] = NFC_BLE_ADVDATA_ROLE_ENCODED_ONLY_PERIPH;
+ break;
+ case BLE_ADVDATA_ROLE_ONLY_CENTRAL:
+ p_encoded_data[*p_offset] = NFC_BLE_ADVDATA_ROLE_ENCODED_ONLY_CENTRAL;
+ break;
+ case BLE_ADVDATA_ROLE_BOTH_PERIPH_PREFERRED:
+ p_encoded_data[*p_offset] = NFC_BLE_ADVDATA_ROLE_ENCODED_BOTH_PERIPH_PREFERRED;
+ break;
+ case BLE_ADVDATA_ROLE_BOTH_CENTRAL_PREFERRED:
+ p_encoded_data[*p_offset] = NFC_BLE_ADVDATA_ROLE_ENCODED_BOTH_CENTRAL_PREFERRED;
+ break;
+ default:
+ return NRF_ERROR_INVALID_PARAM;
+ }
+ *p_offset += AD_TYPE_LE_ROLE_DATA_SIZE;
+
+ return NRF_SUCCESS;
+}
+
+/**@brief Function for calculating the size of Local Name AD Type.
+ *
+ * @param[in] p_advdata Pointer to the structure for specifying the content of encoded data.
+ * @param[out] p_len Size of the buffer that is necessary to encode Local Name AD Type.
+ *
+ * @retval NRF_SUCCESS If the operation was successful.
+ * @retval Other Other error codes might be returned depending on
+ * @ref sd_ble_gap_device_name_get function.
+ */
+__STATIC_INLINE ret_code_t nfc_ble_oob_name_size_calc(ble_advdata_t const * const p_advdata,
+ uint16_t * const p_len)
+{
+ ret_code_t err_code = NRF_SUCCESS;
+ uint16_t device_len;
+
+ if (p_advdata->name_type == BLE_ADVDATA_SHORT_NAME)
+ {
+ device_len = p_advdata->short_name_len;
+ }
+ else
+ {
+ err_code = sd_ble_gap_device_name_get(NULL, &device_len);
+ }
+
+ *p_len += AD_LENGTH_FIELD_SIZE + AD_TYPE_FIELD_SIZE + device_len;
+ return err_code;
+}
+
+/**@brief Function for calculating the size of AD Types which are encoded by @ref ble_advdata_encode function.
+ *
+ * @param[in] p_advdata Pointer to the structure for specifying the content of encoded data.
+ * @param[out] p_len Size of the buffer that is necessary to encode AD Types.
+ *
+ * @retval NRF_SUCCESS If the operation was successful.
+ * @retval Other Other error codes might be returned depending on
+ * @ref nfc_ble_oob_name_size_calc function.
+ */
+static ret_code_t nfc_ble_oob_adv_data_size_calc(ble_advdata_t const * const p_advdata,
+ uint16_t * const p_len)
+{
+ ret_code_t err_code = NRF_SUCCESS;
+
+ if (p_advdata->include_ble_device_addr)
+ {
+ *p_len += AD_TYPE_BLE_DEVICE_ADDR_SIZE;
+ }
+ if (p_advdata->include_appearance)
+ {
+ *p_len += AD_TYPE_APPEARANCE_SIZE;
+ }
+ if (p_advdata->flags != 0)
+ {
+ *p_len += AD_TYPE_FLAGS_SIZE;
+ }
+ if (p_advdata->name_type != BLE_ADVDATA_NO_NAME)
+ {
+ err_code = nfc_ble_oob_name_size_calc(p_advdata, p_len);
+ }
+ return err_code;
+}
+
+#if ADVANCED_ADVDATA_SUPPORT == 0
+/**@brief Function for verifying if BLE advertising data structure contains only supported AD Types
+ * by this encoding module.
+ *
+ * @param[in] advdata Structure with BLE advertising data.
+ *
+ * @retval NRF_SUCCESS If the verification was successful.
+ * @retval NRF_ERROR_INVALID_PARAM If there is any AD type which is not supported by this
+ * module.
+ */
+static ret_code_t nfc_ble_oob_adv_data_check(ble_advdata_t advdata)
+{
+ advdata.p_sec_mgr_oob_flags = NULL;
+ advdata.p_tk_value = NULL;
+ advdata.le_role = BLE_ADVDATA_ROLE_NOT_PRESENT;
+ advdata.include_ble_device_addr = false;
+ advdata.include_appearance = false;
+ advdata.flags = 0;
+ advdata.name_type = BLE_ADVDATA_NO_NAME;
+ advdata.short_name_len = 0;
+ advdata.p_lesc_data = NULL;
+
+ ble_advdata_t pattern_advdata;
+ memset(&pattern_advdata, 0, sizeof(ble_advdata_t));
+
+ if ( memcmp( &pattern_advdata, &advdata, sizeof(ble_advdata_t)) == 0 )
+ {
+ return NRF_SUCCESS;
+ }
+ else
+ {
+ return NRF_ERROR_INVALID_PARAM;
+ }
+}
+#endif //ADVANCED_ADVDATA_SUPPORT
+
+ret_code_t nfc_ble_oob_adv_data_encode(ble_advdata_t const * const p_advdata,
+ uint8_t * const p_encoded_data,
+ uint16_t * const p_len)
+{
+ ret_code_t err_code = NRF_SUCCESS;
+ uint16_t max_size = *p_len;
+ uint16_t offset = 0;
+
+#if ADVANCED_ADVDATA_SUPPORT
+ // In this mode, you cannot count the NDEF message length.
+ VERIFY_FALSE(p_encoded_data == NULL, NRF_ERROR_INVALID_PARAM);
+#else
+ // Verify ADV data structure.
+ err_code = nfc_ble_oob_adv_data_check(*p_advdata);
+ VERIFY_SUCCESS(err_code);
+#endif //ADVANCED_ADVDATA_SUPPORT
+
+ // Encode Security Manager OOB Flags.
+ if (p_advdata->p_sec_mgr_oob_flags != NULL)
+ {
+ err_code = sec_mgr_oob_flags_encode(*p_advdata->p_sec_mgr_oob_flags,
+ p_encoded_data,
+ &offset,
+ max_size);
+ VERIFY_SUCCESS(err_code);
+ }
+
+ // Encode LESC keys
+ if (p_advdata->p_lesc_data != NULL)
+ {
+ err_code = lesc_value_encode(p_advdata->p_lesc_data, p_encoded_data, &offset, max_size);
+ VERIFY_SUCCESS(err_code);
+ }
+
+ // Encode Security Manager TK value.
+ if (p_advdata->p_tk_value != NULL)
+ {
+ err_code = tk_value_encode(p_advdata->p_tk_value, p_encoded_data, &offset, max_size);
+ VERIFY_SUCCESS(err_code);
+ }
+
+ // Encode LE Role.
+ if (BLE_ADVDATA_ROLE_NOT_PRESENT != p_advdata->le_role)
+ {
+ err_code = le_role_encode(p_advdata->le_role, p_encoded_data, &offset, max_size);
+ VERIFY_SUCCESS(err_code);
+ }
+
+ // Encode remaining AD Types or precalculate necessary buffer space.
+ if (p_encoded_data != NULL)
+ {
+ uint16_t adv_data_size = max_size - offset;
+ err_code = ble_advdata_encode(p_advdata, p_encoded_data + offset, &adv_data_size);
+ *p_len = offset + adv_data_size;
+ }
+ else
+ {
+ err_code = nfc_ble_oob_adv_data_size_calc(p_advdata, &offset);
+ *p_len = offset;
+ }
+
+ return err_code;
+}
+
+void nfc_tk_value_payload_encode(ble_advdata_tk_value_t * p_tk_value,
+ uint8_t * p_tk_payload_data)
+{
+ for (uint8_t i = 0; i < AD_TYPE_TK_VALUE_DATA_SIZE; i++)
+ {
+ *(p_tk_payload_data++) = p_tk_value->tk[i];
+ }
+}
+
+#endif // NRF_MODULE_ENABLED(NFC_BLE_OOB_ADVDATA)
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/ndef/connection_handover/ble_oob_advdata/nfc_ble_oob_advdata.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/ndef/connection_handover/ble_oob_advdata/nfc_ble_oob_advdata.h
new file mode 100644
index 0000000..650b129
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/ndef/connection_handover/ble_oob_advdata/nfc_ble_oob_advdata.h
@@ -0,0 +1,94 @@
+/**
+ * Copyright (c) 2012 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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
+ *
+ * @defgroup nfc_ble_oob_advdata Advertising and Scan Response Data Encoder for NFC OOB pairing
+ * @{
+ * @ingroup nfc_ble_pair_msg
+ * @brief Function for encoding data in the Advertising and Scan Response Data format, which
+ * can be used to create payload of NFC message intended for initiating the Out-of-Band
+ * pairing.
+ */
+
+#ifndef NFC_BLE_OOB_ADVDATA_H__
+#define NFC_BLE_OOB_ADVDATA_H__
+
+#include <stdint.h>
+#include "ble_advdata.h"
+#include "app_util.h"
+#include "sdk_errors.h"
+
+
+/**@brief Function for encoding data in the Advertising and Scan Response data format, which
+ * is used for NFC OOB pairing.
+ *
+ *
+ * @details This function encodes data into the Advertising and Scan Response data format (AD structures).
+ * Encoding is based on the selections in the supplied structures. This function uses
+ * @ref ble_advdata_encode to encode regular data and adds additional AD Structures which are specific
+ * for NFC OOB pairing: Security Manager TK Value, LESC OOB values, OOB Flags, and LE Role.
+ *
+ * @param[in] p_advdata Pointer to the structure for specifying the content of encoded data.
+ * @param[out] p_encoded_data Pointer to the buffer where encoded data will be returned.
+ * @param[in,out] p_len \c in: Size of \p p_encoded_data buffer.
+ * \c out: Length of encoded data.
+ *
+ * @retval NRF_SUCCESS If the operation was successful.
+ * @retval NRF_ERROR_INVALID_PARAM If the operation failed because a wrong parameter was provided in \p p_advdata.
+ * @retval NRF_ERROR_DATA_SIZE If the operation failed because not all the requested data could fit into the
+ * provided buffer or some encoded AD structure is too long and its
+ * length cannot be encoded with one octet.
+ */
+ret_code_t nfc_ble_oob_adv_data_encode(ble_advdata_t const * const p_advdata,
+ uint8_t * const p_encoded_data,
+ uint16_t * const p_len);
+
+/**@brief Function for encoding payload field of Security Manager TK Value AD Type.
+ *
+ * @param[in] p_tk_value Security Manager TK Value AD Type payload.
+ * @param[out] p_tk_payload_data Pointer to the buffer where TK payload data will be stored.
+ *
+ */
+void nfc_tk_value_payload_encode(ble_advdata_tk_value_t * p_tk_value,
+ uint8_t * p_tk_payload_data);
+
+#endif // NFC_BLE_OOB_ADVDATA_H__
+
+/** @} */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/ndef/connection_handover/ble_pair_lib/nfc_ble_pair_lib.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/ndef/connection_handover/ble_pair_lib/nfc_ble_pair_lib.c
new file mode 100644
index 0000000..d356d61
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/ndef/connection_handover/ble_pair_lib/nfc_ble_pair_lib.c
@@ -0,0 +1,641 @@
+/**
+ * Copyright (c) 2016 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#include "sdk_common.h"
+#if NRF_MODULE_ENABLED(NFC_BLE_PAIR_LIB)
+
+#include "nfc_ble_pair_lib.h"
+#include "sdk_macros.h"
+#include "app_error.h"
+#include "nrf_drv_rng.h"
+#include "nfc_t2t_lib.h"
+#include "nfc_ble_pair_msg.h"
+#include "ecc.h"
+#include "nrf_sdh_ble.h"
+
+#define NRF_LOG_MODULE_NAME nfc_ble_pair
+#if NFC_BLE_PAIR_LIB_LOG_ENABLED
+#define NRF_LOG_LEVEL NFC_BLE_PAIR_LIB_LOG_LEVEL
+#define NRF_LOG_INFO_COLOR NFC_BLE_PAIR_LIB_INFO_COLOR
+#define NRF_LOG_DEBUG_COLOR NFC_BLE_PAIR_LIB_DEBUG_COLOR
+#else // NFC_BLE_PAIR_LIB_LOG_ENABLED
+#define NRF_LOG_LEVEL 0
+#endif // NFC_BLE_PAIR_LIB_LOG_ENABLED
+#include "nrf_log.h"
+NRF_LOG_MODULE_REGISTER();
+
+// Verify bonding and keys distribution settings.
+#if ((BLE_NFC_SEC_PARAM_BOND) && \
+ !(BLE_NFC_SEC_PARAM_KDIST_OWN_ENC) && \
+ !(BLE_NFC_SEC_PARAM_KDIST_OWN_ID) && \
+ !(BLE_NFC_SEC_PARAM_KDIST_PEER_ENC) && \
+ !(BLE_NFC_SEC_PARAM_KDIST_PEER_ID))
+ #error "At least one of the BLE_NFC_SEC_PARAM_KDIST flags must be set to 1 when bonding is enabled."
+#endif
+
+// Macro for verifying if the pairing mode argument is valid
+#define VERIFY_PAIRING_MODE(arg) \
+ if ((arg) >= NFC_PAIRING_MODE_CNT) \
+ { \
+ return NRF_ERROR_INVALID_PARAM; \
+ }
+
+#define BLE_GAP_LESC_P256_SK_LEN 32 /**< GAP LE Secure Connections Elliptic Curve Diffie-Hellman P-256 Secret Key Length. */
+#define TK_MAX_NUM 1 /**< Maximal number of TK locations in NDEF message buffer. */
+#define NDEF_MSG_BUFF_SIZE 256 /**< Size of buffer for the NDEF pairing message. */
+
+#define BLE_NFC_SEC_PARAM_KEYPRESS 0 /**< Keypress notifications not enabled. */
+#define BLE_NFC_SEC_PARAM_IO_CAPS BLE_GAP_IO_CAPS_NONE /**< No I/O capabilities. */
+
+typedef struct
+{
+ uint8_t sk[BLE_GAP_LESC_P256_SK_LEN]; /**< LE Secure Connections Elliptic Curve Diffie-Hellman P-256 Secret Key. */
+} ble_gap_lesc_p256_sk_t;
+
+static ble_advertising_t * m_p_advertising = NULL; /**< Pointer to the advertising module instance. */
+
+static uint8_t m_ndef_msg_buf[NDEF_MSG_BUFF_SIZE]; /**< NFC tag NDEF message buffer. */
+static ble_advdata_tk_value_t m_oob_auth_key; /**< Temporary Key buffer used in OOB legacy pairing mode. */
+static uint8_t * m_tk_group[TK_MAX_NUM]; /**< Locations of TK in NDEF message. */
+static nfc_pairing_mode_t m_pairing_mode; /**< Current pairing mode. */
+static ble_gap_lesc_oob_data_t m_ble_lesc_oob_data; /**< LESC OOB data used in LESC OOB pairing mode. */
+static ble_gap_sec_params_t m_sec_param; /**< Current Peer Manager secure parameters configuration. */
+
+static uint8_t m_connections = 0; /**< Number of active connections. */
+
+__ALIGN(4) static ble_gap_lesc_p256_pk_t m_lesc_pk; /**< LESC ECC Public Key. */
+__ALIGN(4) static ble_gap_lesc_p256_sk_t m_lesc_sk; /**< LESC ECC Secret Key. */
+__ALIGN(4) static ble_gap_lesc_dhkey_t m_lesc_dhkey; /**< LESC ECC DH Key. */
+__ALIGN(4) static ble_gap_lesc_p256_pk_t m_lesc_peer_pk; /**< LESC Peer ECC Public Key. */
+
+
+static void ble_evt_handler(ble_evt_t const * p_ble_evt, void * p_context);
+
+NRF_SDH_BLE_OBSERVER(m_ble_evt_observer, NFC_BLE_PAIR_LIB_BLE_OBSERVER_PRIO, ble_evt_handler, NULL);
+
+/**
+ * @brief Generates random values to a given buffer
+ *
+ * @param[out] p_buff Buffer for random values
+ * @param[in] size Number of bytes to generate
+ *
+ * @returns Number of generated bytes
+ */
+static uint8_t random_vector_generate(uint8_t * p_buff, uint8_t size)
+{
+ uint8_t available;
+ ret_code_t err_code = NRF_SUCCESS;
+
+ nrf_drv_rng_bytes_available(&available);
+
+ uint8_t length = (size < available) ? size : available;
+ err_code = nrf_drv_rng_rand(p_buff, length);
+ APP_ERROR_CHECK(err_code);
+ return length;
+}
+
+/**
+ * @brief Prints generated key to the log console
+ *
+ * @param[in] lenght TK value length
+ */
+static void random_vector_log(uint8_t length)
+{
+ NRF_LOG_INFO("TK Random Value:");
+ for (uint32_t i = 0; i < length; i++)
+ {
+ NRF_LOG_RAW_INFO(" %02X",(int)m_oob_auth_key.tk[i]);
+ }
+ NRF_LOG_RAW_INFO("\r\n");
+}
+
+/**
+ * @brief Function for handling NFC events.
+ *
+ * @details Starts advertising and generates new OOB keys on the NFC_T2T_EVENT_FIELD_ON event.
+ *
+ * @param[in] p_context Context for callback execution, not used in this callback implementation.
+ * @param[in] event Event generated by hal NFC lib.
+ * @param[in] p_data Received/transmitted data or NULL, not used in this callback implementation.
+ * @param[in] data_length Size of the received/transmitted packet, not used in this callback implementation.
+ */
+static void nfc_callback(void * p_context,
+ nfc_t2t_event_t event,
+ uint8_t const * p_data,
+ size_t data_length)
+{
+ UNUSED_PARAMETER(p_context);
+ UNUSED_PARAMETER(p_data);
+ UNUSED_PARAMETER(data_length);
+
+ ret_code_t err_code = NRF_SUCCESS;
+ nfc_pairing_mode_t pairing_mode;
+
+ switch (event)
+ {
+ case NFC_T2T_EVENT_FIELD_ON:
+ NRF_LOG_DEBUG("NFC_EVENT_FIELD_ON");
+
+ pairing_mode = nfc_ble_pair_mode_get();
+
+ if ((pairing_mode == NFC_PAIRING_MODE_OOB) ||
+ (pairing_mode == NFC_PAIRING_MODE_GENERIC_OOB))
+ {
+ // Generate Authentication OOB Key and update NDEF message content.
+ uint8_t length = random_vector_generate(m_oob_auth_key.tk, BLE_GAP_SEC_KEY_LEN);
+ random_vector_log(length);
+ err_code = nfc_tk_group_modifier_update(&m_oob_auth_key);
+ APP_ERROR_CHECK(err_code);
+ }
+
+ // Start advertising when NFC field is sensed and there is a place for another connection.
+ if (m_connections < NRF_SDH_BLE_PERIPHERAL_LINK_COUNT)
+ {
+ err_code = ble_advertising_start(m_p_advertising, BLE_ADV_MODE_FAST);
+ if (err_code != NRF_ERROR_INVALID_STATE)
+ {
+ APP_ERROR_CHECK(err_code);
+ }
+ }
+
+ break;
+
+ case NFC_T2T_EVENT_FIELD_OFF:
+ NRF_LOG_DEBUG("NFC_EVENT_FIELD_OFF");
+ break;
+
+ default:
+ break;
+ }
+}
+
+/**
+ * @brief Function for setting the Peer Manager secure mode used in device pairing.
+ *
+ * @param[in] mode NFC pairing mode, this is the value of @ref nfc_pairing_mode_t enum
+ *
+ * @retval NRF_SUCCESS If new secure mode has been set correctly.
+ * @retval NRF_ERROR_INVALID_PARAM If pairing mode is invalid.
+ * @retval Other Other error codes might be returned depending on used modules.
+ */
+static ret_code_t pm_secure_mode_set(nfc_pairing_mode_t mode)
+{
+ ret_code_t err_code = NRF_SUCCESS;
+
+ // Check if pairing mode is valid.
+ VERIFY_PAIRING_MODE(mode);
+
+ memset(&m_sec_param, 0x00, sizeof(m_sec_param));
+
+ // Pairing mode specific security parameters.
+ switch (mode)
+ {
+ case NFC_PAIRING_MODE_JUST_WORKS:
+ // Disable pairing with OOB data.
+ m_sec_param.mitm = 0;
+ m_sec_param.oob = 0;
+ m_sec_param.lesc = 0;
+ break;
+
+ case NFC_PAIRING_MODE_OOB:
+ // Enable legacy pairing with OOB data - TK value.
+ m_sec_param.mitm = 1;
+ m_sec_param.oob = 1;
+ m_sec_param.lesc = 0;
+ break;
+
+ case NFC_PAIRING_MODE_LESC_OOB:
+ case NFC_PAIRING_MODE_LESC_JUST_WORKS:
+ // Enable LESC pairing - OOB and MITM flags are cleared because it is the central device
+ // who decides if the connection will be authorized with LESC OOB data.
+ m_sec_param.mitm = 0;
+ m_sec_param.oob = 0;
+ m_sec_param.lesc = 1;
+ break;
+
+ case NFC_PAIRING_MODE_GENERIC_OOB:
+ // MITM, OOB and LESC flags are changing dynamically depending on central device pairing flags.
+ break;
+
+ default:
+ return NRF_ERROR_INVALID_PARAM;
+ }
+
+ // Common security parameters to be used for all security procedures.
+ m_sec_param.min_key_size = BLE_NFC_SEC_PARAM_MIN_KEY_SIZE;
+ m_sec_param.max_key_size = BLE_NFC_SEC_PARAM_MAX_KEY_SIZE;
+ m_sec_param.keypress = BLE_NFC_SEC_PARAM_KEYPRESS;
+ m_sec_param.io_caps = BLE_NFC_SEC_PARAM_IO_CAPS;
+ m_sec_param.bond = BLE_NFC_SEC_PARAM_BOND;
+
+#if (BLE_NFC_SEC_PARAM_BOND)
+ // If bonding is enabled, set key distribution flags.
+ m_sec_param.kdist_own.enc = BLE_NFC_SEC_PARAM_KDIST_OWN_ENC;
+ m_sec_param.kdist_own.id = BLE_NFC_SEC_PARAM_KDIST_OWN_ID;
+ m_sec_param.kdist_peer.enc = BLE_NFC_SEC_PARAM_KDIST_PEER_ENC;
+ m_sec_param.kdist_peer.id = BLE_NFC_SEC_PARAM_KDIST_PEER_ID;
+#else
+ // If bonding is not enabled, no keys can be distributed.
+ m_sec_param.kdist_own.enc = 0;
+ m_sec_param.kdist_own.id = 0;
+ m_sec_param.kdist_peer.enc = 0;
+ m_sec_param.kdist_peer.id = 0;
+#endif
+
+ // Update Peer Manager security parameter settings.
+ err_code = pm_sec_params_set(&m_sec_param);
+
+ return err_code;
+}
+
+
+ /**@brief Function for preparing the BLE pairing data for the NFC tag.
+ *
+ * @details This function does not stop and start the NFC tag data emulation.
+ *
+ * @param[in] mode Pairing mode for which the tag data will be prepared.
+ *
+ * @retval NRF_SUCCESS If new tag pairing data has been set correctly.
+ * @retval NRF_ERROR_INVALID_PARAM If pairing mode is invalid.
+ * @retval Other Other error codes might be returned depending on used modules.
+ */
+ret_code_t nfc_ble_pair_data_set(nfc_pairing_mode_t mode)
+{
+ ret_code_t err_code = NRF_SUCCESS;
+
+ // Check if pairing mode is valid
+ VERIFY_PAIRING_MODE(mode);
+
+ // Provide information about available buffer size to encoding function.
+ uint32_t ndef_msg_len = sizeof(m_ndef_msg_buf);
+
+ switch (mode)
+ {
+ case NFC_PAIRING_MODE_OOB:
+ // Encode NDEF message with Secure Simple Pairing OOB optional data - TK value.
+ err_code = nfc_ble_pair_msg_updatable_tk_encode(NFC_BLE_PAIR_MSG_BLUETOOTH_LE_SHORT,
+ &m_oob_auth_key,
+ NULL,
+ m_ndef_msg_buf,
+ &ndef_msg_len,
+ m_tk_group,
+ TK_MAX_NUM);
+ break;
+
+ case NFC_PAIRING_MODE_JUST_WORKS:
+ // Encode NDEF message with Secure Simple Pairing OOB data.
+ err_code = nfc_ble_pair_default_msg_encode(NFC_BLE_PAIR_MSG_BLUETOOTH_LE_SHORT,
+ NULL,
+ NULL,
+ m_ndef_msg_buf,
+ &ndef_msg_len);
+ break;
+
+ case NFC_PAIRING_MODE_LESC_OOB:
+ // Generate LESC OOB data
+ err_code = sd_ble_gap_lesc_oob_data_get(BLE_CONN_HANDLE_INVALID,
+ &m_lesc_pk,
+ &m_ble_lesc_oob_data);
+ VERIFY_SUCCESS(err_code);
+
+ // Encode NDEF message with BLE LESC OOB pairing data - LESC random and confirmation values.
+ err_code = nfc_ble_pair_default_msg_encode(NFC_BLE_PAIR_MSG_BLUETOOTH_LE_SHORT,
+ NULL,
+ &m_ble_lesc_oob_data,
+ m_ndef_msg_buf,
+ &ndef_msg_len);
+ break;
+
+ case NFC_PAIRING_MODE_LESC_JUST_WORKS:
+ err_code = nfc_ble_pair_default_msg_encode(NFC_BLE_PAIR_MSG_BLUETOOTH_LE_SHORT,
+ NULL,
+ NULL,
+ m_ndef_msg_buf,
+ &ndef_msg_len);
+ break;
+
+ case NFC_PAIRING_MODE_GENERIC_OOB:
+ // Generate LESC OOB data
+ err_code = sd_ble_gap_lesc_oob_data_get(BLE_CONN_HANDLE_INVALID,
+ &m_lesc_pk,
+ &m_ble_lesc_oob_data);
+ VERIFY_SUCCESS(err_code);
+
+ // Encode NDEF message with Secure Simple Pairing OOB data - TK value and LESC Random and Confirmation Keys.
+ err_code = nfc_ble_pair_msg_updatable_tk_encode(NFC_BLE_PAIR_MSG_BLUETOOTH_LE_SHORT,
+ &m_oob_auth_key,
+ &m_ble_lesc_oob_data,
+ m_ndef_msg_buf,
+ &ndef_msg_len,
+ m_tk_group,
+ TK_MAX_NUM);
+ break;
+
+ default:
+ return NRF_ERROR_INVALID_PARAM;
+ }
+
+ VERIFY_SUCCESS(err_code);
+
+ // Update NFC tag data
+ err_code = nfc_t2t_payload_set(m_ndef_msg_buf, ndef_msg_len);
+
+ return err_code;
+}
+
+ret_code_t nfc_ble_pair_init(ble_advertising_t * const p_advertising, nfc_pairing_mode_t mode)
+{
+ ret_code_t err_code = NRF_SUCCESS;
+
+ // Check if pairing mode is valid
+ VERIFY_PAIRING_MODE(mode);
+
+ // Check if pointer to the advertising module instance is not NULL
+ VERIFY_PARAM_NOT_NULL(p_advertising);
+
+ m_p_advertising = p_advertising;
+ m_pairing_mode = mode;
+
+ // Initialize RNG peripheral for authentication OOB data generation
+ err_code = nrf_drv_rng_init(NULL);
+ if (err_code != NRF_ERROR_INVALID_STATE)
+ {
+ VERIFY_SUCCESS(err_code);
+ }
+
+ // Initialize encryption module with random number generator use
+ ecc_init(true);
+
+ // Start NFC
+ err_code = nfc_t2t_setup(nfc_callback, NULL);
+ VERIFY_SUCCESS(err_code);
+
+ // Set Peer Manager pairing mode
+ err_code = pm_secure_mode_set(mode);
+ VERIFY_SUCCESS(err_code);
+
+ if ((mode == NFC_PAIRING_MODE_LESC_OOB) ||
+ (mode == NFC_PAIRING_MODE_LESC_JUST_WORKS) ||
+ (mode == NFC_PAIRING_MODE_GENERIC_OOB))
+ {
+ // Generate new LESC keys
+ err_code = ecc_p256_keypair_gen(m_lesc_sk.sk, m_lesc_pk.pk);
+ VERIFY_SUCCESS(err_code);
+
+ // Update Peer Manager with new LESC Public Key
+ err_code = pm_lesc_public_key_set(&m_lesc_pk);
+ VERIFY_SUCCESS(err_code);
+ }
+
+ // Set proper NFC data according to the pairing mode
+ err_code = nfc_ble_pair_data_set(mode);
+ VERIFY_SUCCESS(err_code);
+
+ // Turn on tag emulation
+ err_code = nfc_t2t_emulation_start();
+
+ return err_code;
+}
+
+ret_code_t nfc_ble_pair_mode_set(nfc_pairing_mode_t mode)
+{
+ ret_code_t err_code = NRF_SUCCESS;
+
+ // Check if pairing mode is valid
+ VERIFY_PAIRING_MODE(mode);
+
+ if (mode != m_pairing_mode)
+ {
+ m_pairing_mode = mode;
+
+ if ((mode == NFC_PAIRING_MODE_LESC_OOB) ||
+ (mode == NFC_PAIRING_MODE_LESC_JUST_WORKS) ||
+ (mode == NFC_PAIRING_MODE_GENERIC_OOB))
+ {
+ // Generate new LESC keys
+ err_code = ecc_p256_keypair_gen(m_lesc_sk.sk, m_lesc_pk.pk);
+ VERIFY_SUCCESS(err_code);
+
+ // Update Peer Manager with new LESC Public Key
+ err_code = pm_lesc_public_key_set(&m_lesc_pk);
+ VERIFY_SUCCESS(err_code);
+ }
+
+ // Update Peer Manager settings according to the new pairing mode
+ err_code = pm_secure_mode_set(mode);
+ VERIFY_SUCCESS(err_code);
+
+ // NFC tag emulation must be turned off during changes in payload
+ err_code = nfc_t2t_emulation_stop();
+ VERIFY_SUCCESS(err_code);
+
+ // Update NFC tag data
+ err_code = nfc_ble_pair_data_set(mode);
+ VERIFY_SUCCESS(err_code);
+
+ // Turn on tag emulation after changes
+ err_code = nfc_t2t_emulation_start();
+ VERIFY_SUCCESS(err_code);
+ }
+
+ return NRF_SUCCESS;
+}
+
+nfc_pairing_mode_t nfc_ble_pair_mode_get(void)
+{
+ return m_pairing_mode;
+}
+
+/**
+ * @brief Generates new key pair for LESC pairing.
+ *
+ * @details If device is in the @ref NFC_PAIRING_MODE_LESC_OOB mode or in
+ * the @ref NFC_PAIRING_MODE_GENERIC_OOB mode, NFC Connection Handover
+ * message is also updated with newly generated LESC OOB data.
+ *
+ * @retval NRF_SUCCESS If new tag pairing data has been set correctly.
+ * @retval Other Other error codes might be returned depending on used modules.
+ */
+static ret_code_t generate_lesc_keys(void)
+{
+ ret_code_t err_code = NRF_SUCCESS;
+
+ // Generate new LESC keys
+ err_code = ecc_p256_keypair_gen(m_lesc_sk.sk, m_lesc_pk.pk);
+ VERIFY_SUCCESS(err_code);
+
+ // Update Peer Manager with new LESC Public Key
+ err_code = pm_lesc_public_key_set(&m_lesc_pk);
+ VERIFY_SUCCESS(err_code);
+
+ if ((m_pairing_mode == NFC_PAIRING_MODE_LESC_OOB) ||
+ (m_pairing_mode == NFC_PAIRING_MODE_GENERIC_OOB))
+ {
+ // Generate LESC OOB data.
+ err_code = sd_ble_gap_lesc_oob_data_get(BLE_CONN_HANDLE_INVALID,
+ &m_lesc_pk,
+ &m_ble_lesc_oob_data);
+ VERIFY_SUCCESS(err_code);
+
+ // Update NDEF message with new LESC OOB data.
+ err_code = nfc_lesc_data_update(&m_ble_lesc_oob_data);
+ VERIFY_SUCCESS(err_code);
+ }
+
+ return NRF_SUCCESS;
+}
+
+/**
+ * @brief Function for handling BLE events.
+ *
+ * @param[in] p_ble_evt Event received from the BLE stack.
+ * @param[in] p_context Context.
+ */
+static void ble_evt_handler(ble_evt_t const * p_ble_evt, void * p_context)
+{
+ ret_code_t err_code = NRF_SUCCESS;
+
+ switch (p_ble_evt->header.evt_id)
+ {
+ // Upon authorization key request, reply with Temporary Key that was read from the NFC tag
+ case BLE_GAP_EVT_AUTH_KEY_REQUEST:
+ NRF_LOG_DEBUG("BLE_GAP_EVT_AUTH_KEY_REQUEST");
+
+ err_code = sd_ble_gap_auth_key_reply(p_ble_evt->evt.gap_evt.conn_handle,
+ BLE_GAP_AUTH_KEY_TYPE_OOB,
+ m_oob_auth_key.tk);
+ APP_ERROR_CHECK(err_code);
+ break;
+
+ // Upon LESC Diffie_Hellman key request, reply with key computed from device secret key and peer public key
+ case BLE_GAP_EVT_LESC_DHKEY_REQUEST:
+ NRF_LOG_DEBUG("BLE_GAP_EVT_LESC_DHKEY_REQUEST");
+
+ // If LESC OOB pairing is on, perform authentication with OOB data
+ if (p_ble_evt->evt.gap_evt.params.lesc_dhkey_request.oobd_req)
+ {
+ err_code = sd_ble_gap_lesc_oob_data_set(p_ble_evt->evt.gap_evt.conn_handle,
+ &m_ble_lesc_oob_data,
+ NULL);
+ APP_ERROR_CHECK(err_code);
+ }
+
+ // Buffer peer Public Key because ECC module arguments must be word aligned
+ memcpy(&m_lesc_peer_pk.pk[0],
+ &p_ble_evt->evt.gap_evt.params.lesc_dhkey_request.p_pk_peer->pk[0],
+ BLE_GAP_LESC_P256_PK_LEN);
+
+ // Compute D-H key
+ err_code = ecc_p256_shared_secret_compute(&m_lesc_sk.sk[0],
+ &m_lesc_peer_pk.pk[0],
+ &m_lesc_dhkey.key[0]);
+ APP_ERROR_CHECK(err_code);
+
+ // Reply with obtained result
+ err_code = sd_ble_gap_lesc_dhkey_reply(p_ble_evt->evt.gap_evt.conn_handle,
+ &m_lesc_dhkey);
+ APP_ERROR_CHECK(err_code);
+ break;
+
+ case BLE_GAP_EVT_CONNECTED:
+ m_connections++;
+ break;
+
+ case BLE_GAP_EVT_DISCONNECTED:
+ m_connections--;
+ // Intentional fallthrough.
+
+ case BLE_GAP_EVT_AUTH_STATUS:
+ // Generate new LESC key pair and OOB data
+ if ((m_pairing_mode == NFC_PAIRING_MODE_LESC_OOB) ||
+ (m_pairing_mode == NFC_PAIRING_MODE_LESC_JUST_WORKS) ||
+ (m_pairing_mode == NFC_PAIRING_MODE_GENERIC_OOB))
+ {
+ err_code = generate_lesc_keys();
+ APP_ERROR_CHECK(err_code);
+ }
+ break;
+
+ default:
+ break;
+ }
+}
+
+ret_code_t nfc_ble_pair_on_pm_params_req(pm_evt_t const * p_evt)
+{
+ ret_code_t err_code = NRF_SUCCESS;
+
+ NRF_LOG_DEBUG("PM_EVT_CONN_SEC_PARAMS_REQ");
+
+ // Dynamic security parameters changes are needed only
+ // by NFC_PAIRING_MODE_GENERIC_OOB pairing mode.
+ if (m_pairing_mode == NFC_PAIRING_MODE_GENERIC_OOB)
+ {
+ // Check if pointer to the Peer Manager event is not NULL.
+ VERIFY_PARAM_NOT_NULL(p_evt);
+
+ // Set up proper MITM, OOB and LESC flags depending on peer LESC flag
+ // to support either Legacy OOB or LESC OOB pairing mode.
+ if (p_evt->params.conn_sec_params_req.p_peer_params->lesc)
+ {
+ NRF_LOG_DEBUG("LESC OOB mode flags set.");
+
+ m_sec_param.mitm = 0;
+ m_sec_param.oob = 0;
+ m_sec_param.lesc = 1;
+ }
+ else
+ {
+ NRF_LOG_DEBUG("Legacy OOB mode flags set.");
+
+ m_sec_param.mitm = 1;
+ m_sec_param.oob = 1;
+ m_sec_param.lesc = 0;
+ }
+
+ // Reply with new security parameters to the Peer Manager.
+ err_code = pm_conn_sec_params_reply(p_evt->conn_handle,
+ &m_sec_param,
+ p_evt->params.conn_sec_params_req.p_context);
+ }
+
+ return err_code;
+}
+
+#endif // NRF_MODULE_ENABLED(NFC_BLE_PAIR_LIB)
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/ndef/connection_handover/ble_pair_lib/nfc_ble_pair_lib.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/ndef/connection_handover/ble_pair_lib/nfc_ble_pair_lib.h
new file mode 100644
index 0000000..4809cf2
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/ndef/connection_handover/ble_pair_lib/nfc_ble_pair_lib.h
@@ -0,0 +1,137 @@
+/**
+ * Copyright (c) 2016 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#ifndef NFC_BLE_PAIR_LIB_H__
+#define NFC_BLE_PAIR_LIB_H__
+
+#include <stdbool.h>
+#include "sdk_errors.h"
+#include "ble.h"
+#include "ble_advertising.h"
+#include "peer_manager.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**@file
+ *
+ * @addtogroup nfc_api
+ *
+ * @defgroup nfc_ble_pair_lib NFC BLE Pairing Library
+ * @ingroup nfc_api
+ * @brief @tagAPI52 High-level library for BLE Connection Handover pairing using NFC.
+ * @{
+ */
+
+/**
+ * @brief NFC pairing types.
+ */
+typedef enum
+{
+ NFC_PAIRING_MODE_JUST_WORKS, /**< Legacy Just Works pairing without a security key. */
+ NFC_PAIRING_MODE_OOB, /**< Legacy OOB pairing with a Temporary Key shared through NFC tag data. */
+ NFC_PAIRING_MODE_LESC_JUST_WORKS, /**< LESC pairing without authentication data. */
+ NFC_PAIRING_MODE_LESC_OOB, /**< LESC pairing with OOB authentication data. */
+ NFC_PAIRING_MODE_GENERIC_OOB, /**< OOB pairing with fallback from LESC to Legacy mode. */
+ NFC_PAIRING_MODE_CNT /**< Number of available pairing modes. */
+} nfc_pairing_mode_t;
+
+/**
+ * @brief Funtion for initializing NFC tag data and turning on tag emulation.
+ *
+ * @warning It is assumed that Peer Manager has already been initialized before calling this function.
+ * It is also assumed that BLE advertising has already been initialized and it is configured
+ * to run in the BLE_ADV_MODE_FAST mode.
+ *
+ * @param[in] mode Pairing mode, this is the value of the @ref nfc_pairing_mode_t enum.
+ * @param[in] p_advertising Pointer to the advertising module instance.
+ *
+ * @retval NRF_SUCCESS If NFC has been initialized properly.
+ * @retval NRF_ERROR_INVALID_PARAM If pairing mode is invalid.
+ * @retval NRF_ERROR_NULL If pointer to the advertising module instance is NULL.
+ * @retval Other Other error codes might be returned depending on used modules.
+ */
+ret_code_t nfc_ble_pair_init(ble_advertising_t * const p_advertising, nfc_pairing_mode_t mode);
+
+/**
+ * @brief Function for setting pairing data and BLE security mode.
+ *
+ * @param[in] mode New pairing mode, this is the value of the @ref nfc_pairing_mode_t enum.
+ *
+ * @retval NRF_SUCCESS If new pairing mode has been set correctly.
+ * @retval NRF_ERROR_INVALID_PARAM If pairing mode is invalid.
+ * @retval Other Other error codes might be returned depending on used modules.
+ */
+ret_code_t nfc_ble_pair_mode_set(nfc_pairing_mode_t mode);
+
+/**
+ * @brief Function for obtaining the current pairing mode.
+ *
+ * @return Current pairing mode.
+ */
+nfc_pairing_mode_t nfc_ble_pair_mode_get(void);
+
+/**
+ * @brief Function for replying to @ref PM_EVT_CONN_SEC_PARAMS_REQ.
+ *
+ * @details This function is used to allow dynamic changes in the Peer Manager
+ * security parameters depending on security parameters
+ * obtained from the peer. This is essential for dynamic switching
+ * between Legacy OOB and LESC OOB pairing modes when pairing
+ * library works in @ref NFC_PAIRING_MODE_GENERIC_OOB mode.
+ *
+ * @note This function invokes the @ref pm_conn_sec_params_reply function.
+ *
+ * @param[in] p_evt Pointer to the Peer Manager event struct with
+ * information about peer security parameters.
+ *
+ * @retval NRF_SUCCESS If proper reply has been sent or library does not need to reply.
+ * @retval NRF_ERROR_NULL If pointer to the Peer Manager event is NULL.
+ * @retval Other Other error codes might be returned by the @ref pm_conn_sec_params_reply function.
+ */
+ret_code_t nfc_ble_pair_on_pm_params_req(pm_evt_t const * p_evt);
+
+/** @} */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // NFC_BLE_PAIR_LIB_H__
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/ndef/connection_handover/ble_pair_msg/nfc_ble_pair_msg.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/ndef/connection_handover/ble_pair_msg/nfc_ble_pair_msg.c
new file mode 100644
index 0000000..88cb6a9
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/ndef/connection_handover/ble_pair_msg/nfc_ble_pair_msg.c
@@ -0,0 +1,411 @@
+/**
+ * Copyright (c) 2015 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#include "sdk_common.h"
+#if NRF_MODULE_ENABLED(NFC_BLE_PAIR_MSG)
+
+#include "nfc_ble_pair_msg.h"
+#include "nfc_hs_rec.h"
+#include "nfc_ac_rec.h"
+#include "nfc_le_oob_rec.h"
+#include "nfc_ep_oob_rec.h"
+#include "nfc_ndef_msg.h"
+#include "sdk_macros.h"
+
+/**
+ * @brief Descriptor of TK value locations in Connection Handover NDEF message.
+ */
+typedef struct
+{
+ uint8_t ** pp_tk_group; /**< Pointer to array of pointer with TK locations in CH NDEF message. */
+ uint8_t tk_num; /**< Number of valid TK locations. */
+ uint8_t tk_max_num; /**< Maximal number of possible TK locations. */
+} nfc_ble_tk_group_t;
+
+/**
+ * @brief Descriptor of LESC OOB data in Connection Handover NDEF message.
+ */
+typedef struct
+{
+ uint8_t * confirm; /**< Pointer to the LESC OOB confirmation value in the CH NDEF message. */
+ uint8_t * random; /**< Pointer to the LESC OOB random value in the CH NDEF message. */
+} nfc_ble_lesc_data_pos_t;
+
+static nfc_ble_lesc_data_pos_t m_lesc_pos = {NULL, NULL}; /**< Descriptor used to update LESC keys in the NDEF Message */
+static nfc_ble_tk_group_t m_tk_group; /**< Descriptor used to find TK locations in the NDEF Message which require update. */
+static bool m_tk_modifier_on = false; /**< Flag indicating that TK modifier feature is on. */
+
+/* Default value for Security Manager Out Of Band Flags field in BLE AD structure */
+/* which is used for EP OOB Record payload */
+static const uint8_t sec_mgr_oob_flags =
+ (AD_TYPE_SEC_MGR_OOB_FLAG_SET << AD_TYPE_SEC_MGR_OOB_FLAG_OOB_DATA_PRESENT_POS) |
+ (AD_TYPE_SEC_MGR_OOB_FLAG_SET << AD_TYPE_SEC_MGR_OOB_FLAG_OOB_LE_SUPPORTED_POS) |
+ (AD_TYPE_SEC_MGR_OOB_FLAG_CLEAR << AD_TYPE_SEC_MGR_OOB_FLAG_SIM_LE_AND_EP_POS) |
+ (AD_TYPE_SEC_MGR_OOB_ADDRESS_TYPE_RANDOM << AD_TYPE_SEC_MGR_OOB_FLAG_ADDRESS_TYPE_POS);
+
+/**@brief Function for configuring TK group modifier feature.
+ *
+ * @details This function configures the structure which is responsible for tracking TK locations.
+ * These locations can be afterwards easily accessed with @ref nfc_tk_group_modifier_update
+ * and modified.
+ *
+ * @param[in] pp_tk_group Pointer to array of TK locations that should be modified with
+ * @ref nfc_tk_group_modifier_update function.
+ * @param[in] max_group_size Maximal number of TK locations that can added to \p pp_tk_group.
+ */
+__STATIC_INLINE void nfc_tk_group_modifier_config(uint8_t ** pp_tk_group, uint8_t max_group_size)
+{
+ m_tk_group.pp_tk_group = pp_tk_group;
+ m_tk_group.tk_num = 0;
+ m_tk_group.tk_max_num = max_group_size;
+}
+
+/** @brief Function for creating an AD structure with common configuration for EP and LE OOB records.
+ *
+ * This function creates an AD structure and initializes its fields with default content. Only
+ * fields that are common for both EP and LE OOB records are filled.
+ *
+ * @param[in] p_tk_value Pointer to the authentication Temporary Key (TK). If NULL,
+ * TK field of the returned AD structure is empty.
+ * @param[out] p_adv_data Pointer to BLE AD structure with common configuration for EP
+ * and LE OOB records.
+ */
+static void common_adv_data_create(ble_advdata_tk_value_t * const p_tk_value,
+ ble_gap_lesc_oob_data_t * const p_lesc_data,
+ ble_advdata_t * const p_adv_data)
+{
+ memset((uint8_t *) p_adv_data, 0, sizeof(ble_advdata_t));
+
+ /* Set common configuration of AD structure for both Bluetooth EP and LE record */
+ p_adv_data->include_appearance = true;
+ p_adv_data->name_type = BLE_ADVDATA_FULL_NAME;
+ p_adv_data->p_tk_value = NULL;
+ if (p_tk_value != NULL)
+ {
+ p_adv_data->p_tk_value = p_tk_value;
+ }
+
+ p_adv_data->p_lesc_data = p_lesc_data;
+}
+
+/** @brief Function for creating an AD structure with default configuration for an LE OOB record.
+ *
+ * This function creates an AD structure and initializes its fields with default content for
+ * LE OOB record payload.
+ *
+ * @param[in] p_tk_value Pointer to the authentication Temporary Key (TK). If NULL,
+ * TK field of the returned AD structure is empty.
+ * @param[out] p_le_adv_data Pointer to BLE AD structure with default configuration
+ * for LE OOB record.
+ */
+static void le_oob_specific_adv_data_create(ble_advdata_tk_value_t * const p_tk_value,
+ ble_gap_lesc_oob_data_t * const p_lesc_data,
+ ble_advdata_t * const p_le_adv_data)
+{
+ /* Create default configuration which is common for both EP and LE OOB Records */
+ common_adv_data_create(p_tk_value, p_lesc_data, p_le_adv_data);
+
+ /* LE specific configuration */
+ p_le_adv_data->include_ble_device_addr = true;
+ p_le_adv_data->le_role = BLE_ADVDATA_ROLE_ONLY_PERIPH;
+ p_le_adv_data->flags = BLE_GAP_ADV_FLAG_BR_EDR_NOT_SUPPORTED;
+}
+
+/** @brief Function for creating an AD structure with default configuration for an EP OOB record.
+ *
+ * This function creates an AD structure and initializes its fields with default content for
+ * EP OOB record payload.
+ *
+ * @param[in] p_tk_value Pointer to the authentication Temporary Key (TK). If NULL,
+ * TK field of the returned AD structure is empty.
+ * @param[out] p_ep_adv_data Pointer to BLE AD structure with default configuration
+ * for EP OOB record.
+ */
+static void ep_oob_specific_adv_data_create(ble_advdata_tk_value_t * const p_tk_value,
+ ble_gap_lesc_oob_data_t * const p_lesc_data,
+ ble_advdata_t * const p_ep_adv_data)
+{
+ /* Create default configuration which is common for both EP and LE OOB Records */
+ common_adv_data_create(p_tk_value, p_lesc_data, p_ep_adv_data);
+
+ /* EP specific configuration */
+ p_ep_adv_data->p_sec_mgr_oob_flags = (uint8_t *) &sec_mgr_oob_flags;
+}
+
+ret_code_t nfc_ble_simplified_le_oob_msg_encode(ble_advdata_t const * const p_le_advdata,
+ uint8_t * p_buf,
+ uint32_t * p_len)
+{
+ ret_code_t err_code;
+
+ /* Create NFC NDEF message description, capacity - 1 record */
+ NFC_NDEF_MSG_DEF(nfc_le_oob_msg, 1);
+
+ /* Create NFC NDEF LE OOB Record description without record ID field */
+ NFC_NDEF_LE_OOB_RECORD_DESC_DEF(nfc_le_oob_rec, 0, p_le_advdata);
+
+ /* Add LE OOB Record as lone record to message */
+ err_code = nfc_ndef_msg_record_add(&NFC_NDEF_MSG(nfc_le_oob_msg),
+ &NFC_NDEF_LE_OOB_RECORD_DESC(nfc_le_oob_rec));
+ VERIFY_SUCCESS(err_code);
+ VERIFY_PARAM_NOT_NULL(p_le_advdata);
+
+ if (!m_tk_modifier_on)
+ {
+ nfc_tk_group_modifier_config(NULL, 0);
+ }
+
+ /* Encode whole message into buffer */
+ err_code = nfc_ndef_msg_encode(&NFC_NDEF_MSG(nfc_le_oob_msg),
+ p_buf,
+ p_len);
+
+ return err_code;
+}
+
+ret_code_t nfc_ble_simplified_ep_oob_msg_encode(ble_advdata_t const * const p_ep_advdata,
+ uint8_t * p_buf,
+ uint32_t * p_len)
+{
+ ret_code_t err_code;
+
+ /* Create NFC NDEF message description, capacity - 1 record */
+ NFC_NDEF_MSG_DEF(nfc_ep_oob_msg, 1);
+
+ /* Create NFC NDEF EP OOB Record description without record ID field */
+ NFC_NDEF_EP_OOB_RECORD_DESC_DEF(nfc_ep_oob_rec, 0, p_ep_advdata);
+
+ /* Add EP OOB Record as lone record to message */
+ err_code = nfc_ndef_msg_record_add(&NFC_NDEF_MSG(nfc_ep_oob_msg),
+ &NFC_NDEF_EP_OOB_RECORD_DESC(nfc_ep_oob_rec));
+ VERIFY_SUCCESS(err_code);
+ VERIFY_PARAM_NOT_NULL(p_ep_advdata);
+
+ if (!m_tk_modifier_on)
+ {
+ nfc_tk_group_modifier_config(NULL, 0);
+ }
+
+ /* Encode whole message into buffer */
+ err_code = nfc_ndef_msg_encode(&NFC_NDEF_MSG(nfc_ep_oob_msg),
+ p_buf,
+ p_len);
+
+ return err_code;
+}
+
+ret_code_t nfc_ble_full_handover_select_msg_encode(ble_advdata_t const * const p_le_advdata,
+ ble_advdata_t const * const p_ep_advdata,
+ uint8_t * p_buf,
+ uint32_t * p_len)
+{
+ ret_code_t err_code;
+
+ // Carrier reference buffers for ac records.
+ uint8_t carrier_le_reference = '0';
+ uint8_t carrier_ep_reference = '1';
+
+ // Create ac records for both message types.
+ NFC_NDEF_AC_RECORD_DESC_DEF(ac_rec_le, NFC_AC_CPS_ACTIVE, 1, &carrier_le_reference, 1);
+ NFC_NDEF_AC_RECORD_DESC_DEF(ac_rec_ep, NFC_AC_CPS_ACTIVE, 1, &carrier_ep_reference, 1);
+
+ // Create a Hs record and assign existing ac records to it.
+ NFC_NDEF_HS_RECORD_DESC_DEF(hs_rec, 1, 3, 2);
+ err_code = nfc_hs_rec_local_record_add(&NFC_NDEF_HS_RECORD_DESC(hs_rec),
+ &NFC_NDEF_AC_RECORD_DESC(ac_rec_le));
+ VERIFY_SUCCESS(err_code);
+ err_code = nfc_hs_rec_local_record_add(&NFC_NDEF_HS_RECORD_DESC(hs_rec),
+ &NFC_NDEF_AC_RECORD_DESC(ac_rec_ep));
+ VERIFY_SUCCESS(err_code);
+
+ // Create LE and EP records with different record IDs.
+ NFC_NDEF_LE_OOB_RECORD_DESC_DEF(nfc_le_oob_rec, carrier_le_reference, p_le_advdata);
+ NFC_NDEF_EP_OOB_RECORD_DESC_DEF(nfc_ep_oob_rec, carrier_ep_reference, p_ep_advdata);
+
+ // Create full NDEF Handover Select message for Connection Handover and assign Hs,
+ // LE and EP records to it.
+ NFC_NDEF_MSG_DEF(nfc_hs_full_msg, 3);
+ err_code = nfc_ndef_msg_record_add(&NFC_NDEF_MSG(nfc_hs_full_msg),
+ &NFC_NDEF_HS_RECORD_DESC(hs_rec));
+ VERIFY_SUCCESS(err_code);
+ err_code = nfc_ndef_msg_record_add(&NFC_NDEF_MSG(nfc_hs_full_msg),
+ &NFC_NDEF_LE_OOB_RECORD_DESC(nfc_le_oob_rec));
+ VERIFY_SUCCESS(err_code);
+ err_code = nfc_ndef_msg_record_add(&NFC_NDEF_MSG(nfc_hs_full_msg),
+ &NFC_NDEF_EP_OOB_RECORD_DESC(nfc_ep_oob_rec));
+ VERIFY_SUCCESS(err_code);
+
+ VERIFY_PARAM_NOT_NULL(p_le_advdata);
+ VERIFY_PARAM_NOT_NULL(p_ep_advdata);
+
+ if (!m_tk_modifier_on)
+ {
+ nfc_tk_group_modifier_config(NULL, 0);
+ }
+
+ /* Encode whole message into buffer */
+ err_code = nfc_ndef_msg_encode(&NFC_NDEF_MSG(nfc_hs_full_msg),
+ p_buf,
+ p_len);
+
+ return err_code;
+}
+
+ret_code_t nfc_ble_pair_default_msg_encode(nfc_ble_pair_type_t nfc_ble_pair_type,
+ ble_advdata_tk_value_t * const p_tk_value,
+ ble_gap_lesc_oob_data_t * const p_lesc_data,
+ uint8_t * p_buf,
+ uint32_t * p_len)
+{
+ ble_advdata_t le_adv_data;
+ ble_advdata_t ep_adv_data;
+ ret_code_t err_code = NRF_SUCCESS;
+
+ switch (nfc_ble_pair_type)
+ {
+
+ case NFC_BLE_PAIR_MSG_BLUETOOTH_LE_SHORT:
+ le_oob_specific_adv_data_create(p_tk_value, p_lesc_data, &le_adv_data);
+ err_code = nfc_ble_simplified_le_oob_msg_encode(&le_adv_data, p_buf, p_len);
+ break;
+
+ case NFC_BLE_PAIR_MSG_BLUETOOTH_EP_SHORT:
+ ep_oob_specific_adv_data_create(p_tk_value, NULL, &ep_adv_data);
+ err_code = nfc_ble_simplified_ep_oob_msg_encode(&ep_adv_data, p_buf, p_len);
+ break;
+
+ case NFC_BLE_PAIR_MSG_FULL:
+ le_oob_specific_adv_data_create(p_tk_value, p_lesc_data, &le_adv_data);
+ ep_oob_specific_adv_data_create(p_tk_value, NULL, &ep_adv_data);
+ err_code = nfc_ble_full_handover_select_msg_encode(&le_adv_data,
+ &ep_adv_data,
+ p_buf,
+ p_len);
+ break;
+
+ }
+
+ return err_code;
+}
+
+ret_code_t nfc_ble_pair_msg_updatable_tk_encode(nfc_ble_pair_type_t nfc_ble_pair_type,
+ ble_advdata_tk_value_t * const p_tk_value,
+ ble_gap_lesc_oob_data_t * const p_lesc_data,
+ uint8_t * p_buf,
+ uint32_t * p_len,
+ uint8_t ** pp_tk_group,
+ uint8_t max_group_size)
+{
+ ret_code_t err_code = NRF_SUCCESS;
+
+ m_tk_modifier_on = true;
+ nfc_tk_group_modifier_config(pp_tk_group, max_group_size);
+ err_code = nfc_ble_pair_default_msg_encode(nfc_ble_pair_type, p_tk_value,
+ p_lesc_data, p_buf, p_len);
+ m_tk_modifier_on = false;
+
+ return err_code;
+}
+
+ret_code_t nfc_tk_group_modifier_update(ble_advdata_tk_value_t * p_tk_value)
+{
+ VERIFY_PARAM_NOT_NULL(m_tk_group.pp_tk_group);
+ for (uint8_t tk_index = 0; tk_index < m_tk_group.tk_num; ++tk_index)
+ {
+ uint8_t * p_tk_payload_data = m_tk_group.pp_tk_group[tk_index];
+ nfc_tk_value_payload_encode(p_tk_value, p_tk_payload_data);
+ }
+ return NRF_SUCCESS;
+}
+
+ret_code_t nfc_tk_to_group_add(uint8_t * p_tk_location)
+{
+ // Feature was disabled.
+ if (m_tk_group.pp_tk_group == NULL)
+ {
+ return NRF_SUCCESS;
+ }
+
+ if (m_tk_group.tk_num < m_tk_group.tk_max_num)
+ {
+ m_tk_group.pp_tk_group[m_tk_group.tk_num++] = p_tk_location;
+ return NRF_SUCCESS;
+ }
+ else
+ {
+ return NRF_ERROR_NO_MEM;
+ }
+}
+
+ret_code_t nfc_lesc_pos_set(uint8_t * p_confirm, uint8_t * p_random)
+{
+ if ((p_confirm != NULL) && (p_random != NULL))
+ {
+ m_lesc_pos.confirm = p_confirm;
+ m_lesc_pos.random = p_random;
+
+ return NRF_SUCCESS;
+ }
+ else
+ {
+ return NRF_ERROR_NULL;
+ }
+}
+
+ret_code_t nfc_lesc_data_update(ble_gap_lesc_oob_data_t * p_ble_lesc_oob_data)
+{
+ if (p_ble_lesc_oob_data != NULL)
+ {
+ if ((m_lesc_pos.confirm != NULL) && (m_lesc_pos.random != NULL))
+ {
+ memcpy(m_lesc_pos.confirm, p_ble_lesc_oob_data->c, AD_TYPE_CONFIRM_VALUE_DATA_SIZE);
+ memcpy(m_lesc_pos.random, p_ble_lesc_oob_data->r, AD_TYPE_RANDOM_VALUE_DATA_SIZE);
+
+ return NRF_SUCCESS;
+ }
+
+ return NRF_ERROR_INVALID_STATE;
+ }
+ else
+ {
+ return NRF_ERROR_NULL;
+ }
+}
+
+#endif // NRF_MODULE_ENABLED(NFC_BLE_PAIR_MSG)
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/ndef/connection_handover/ble_pair_msg/nfc_ble_pair_msg.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/ndef/connection_handover/ble_pair_msg/nfc_ble_pair_msg.h
new file mode 100644
index 0000000..ab7ce18
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/ndef/connection_handover/ble_pair_msg/nfc_ble_pair_msg.h
@@ -0,0 +1,279 @@
+/**
+ * Copyright (c) 2015 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#ifndef NFC_BLE_PAIR_MSG_H__
+#define NFC_BLE_PAIR_MSG_H__
+
+/**@file
+ *
+ * @defgroup nfc_modules NDEF message modules
+ * @ingroup nfc_api
+ * @brief Implementation of NDEF messages.
+ *
+ * @defgroup nfc_ndef_messages Predefined NDEF messages
+ * @ingroup nfc_modules
+ * @brief Predefined NDEF messages for standard use.
+ *
+ * @defgroup nfc_ble_pair_msg BLE pairing messages
+ * @{
+ * @ingroup nfc_ndef_messages
+ *
+ * @brief Generation of NFC NDEF messages used for BLE pairing.
+ *
+ */
+
+#include <stdint.h>
+#include "ble_advdata.h"
+#include "sdk_errors.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @brief Types of BLE pairing message.
+ *
+ * Use one of these values to choose the type of NDEF BLE pairing message.
+ */
+typedef enum
+{
+ NFC_BLE_PAIR_MSG_BLUETOOTH_LE_SHORT, ///< Simplified LE OOB message.
+ NFC_BLE_PAIR_MSG_BLUETOOTH_EP_SHORT, ///< Simplified EP OOB message.
+ NFC_BLE_PAIR_MSG_FULL ///< BLE Handover Select Message.
+} nfc_ble_pair_type_t;
+
+/** @brief Function for encoding simplified LE OOB messages.
+ *
+ * This function encodes a simplified LE OOB message into a buffer. The payload of the LE OOB record
+ * inside the message can be configured via the advertising data structure.
+ *
+ * This function was implemented partially according to "Bluetooth Secure Simple Pairing Using NFC"
+ * (denotation "NFCForum-AD-BTSSP_1_1" published on 2014-01-09) chapters 3.1, 3.2, 4.3.2,
+ * and according to "Supplement to the Bluetooth Core Specification" (Version 5, adoption date:
+ * Dec 02 2014).
+ *
+ * @note To be able to encode the message, a SoftDevice must be enabled and configured.
+ *
+ * @param[in] p_le_advdata Pointer to the BLE advertising data structure for the LE OOB record.
+ * @param[out] p_buf Pointer to the buffer for the message.
+ * @param[in,out] p_len Size of the available memory for the message as input.
+ * Size of the generated message as output.
+ *
+ * @retval NRF_SUCCESS If the function completed successfully.
+ * @retval NRF_ERROR_xxx If an error occurred.
+ */
+ret_code_t nfc_ble_simplified_le_oob_msg_encode(ble_advdata_t const * const p_le_advdata,
+ uint8_t * p_buf,
+ uint32_t * p_len);
+
+/** @brief Function for encoding simplified EP OOB messages.
+ *
+ * This function encodes a simplified EP OOB message into a buffer. The payload of the EP OOB record
+ * inside the message can be configured via the advertising data structure.
+ *
+ * This function was implemented partially according to "Bluetooth Secure Simple Pairing Using NFC"
+ * (denotation "NFCForum-AD-BTSSP_1_1" published on 2014-01-09) chapters 3.1, 3.2, 4.3.1,
+ * and according to "Supplement to the Bluetooth Core Specification" (Version 5, adoption date:
+ * Dec 02 2014).
+ *
+ * @note To be able to encode the message, a SoftDevice must be enabled and configured.
+ *
+ * @param[in] p_ep_advdata Pointer to the BLE advertising data structure for the EP OOB record.
+ * @param[out] p_buf Pointer to the buffer for the message.
+ * @param[in,out] p_len Size of the available memory for the message as input.
+ * Size of the generated message as output.
+ *
+ * @retval NRF_SUCCESS If the function completed successfully.
+ * @retval NRF_ERROR_xxx If an error occurred.
+ */
+ret_code_t nfc_ble_simplified_ep_oob_msg_encode(ble_advdata_t const * const p_ep_advdata,
+ uint8_t * p_buf,
+ uint32_t * p_len);
+
+/** @brief Function for encoding BLE Handover Select Messages.
+ *
+ * This function encodes a BLE Handover Select Message into a buffer. The payload of the LE OOB record
+ * and the EP OOB record inside the message can be configured via the advertising data structures.
+ *
+ * This function was implemented partially according to "Bluetooth Secure Simple Pairing Using NFC"
+ * (denotation "NFCForum-AD-BTSSP_1_1" published on 2014-01-09) chapters 3.1, 3.2, 4.1.1
+ * and 4.1.2 (combined), and according to "Supplement to the Bluetooth Core Specification" (Version 5,
+ * adoption date: Dec 02 2014).
+ *
+ * @note To be able to encode the message, a SoftDevice must be enabled and configured.
+ *
+ * @param[in] p_le_advdata Pointer to the BLE advertising data structure for the LE OOB record.
+ * @param[in] p_ep_advdata Pointer to the BLE advertising data structure for the EP OOB record.
+ * @param[out] p_buf Pointer to the buffer for the message.
+ * @param[in,out] p_len Size of the available memory for the message as input.
+ * Size of the generated message as output.
+ *
+ * @retval NRF_SUCCESS If the function completed successfully.
+ * @retval NRF_ERROR_xxx If an error occurred.
+ */
+ret_code_t nfc_ble_full_handover_select_msg_encode(ble_advdata_t const * const p_le_advdata,
+ ble_advdata_t const * const p_ep_advdata,
+ uint8_t * p_buf,
+ uint32_t * p_len);
+
+/** @brief Function for encoding any type of BLE pairing messages with default BLE
+ * advertising data structures.
+ *
+ * This function encodes a BLE pairing message into a buffer. The message can be encoded as
+ * one of the three message types (using @ref nfc_ble_simplified_le_oob_msg_encode,
+ * @ref nfc_ble_simplified_ep_oob_msg_encode, or @ref nfc_ble_full_handover_select_msg_encode),
+ * according to the @p nfc_ble_pair_type parameter. LE and EP OOB records use the default
+ * advertising data structure configuration. Only one field ('Security Manager TK') in the BLE
+ * advertising data can be configured for both records by specifying the @p p_tk_value parameter.
+ *
+ * For LE OOB records, the default BLE advertising data structure configuration fills the required
+ * fields 'LE Bluetooth Device Address' and 'LE Role' and the optional fields 'Appearance',
+ * 'Local Name', and 'Flags'.
+ *
+ * For EP OOB records, the default BLE advertising data structure configuration fills the required
+ * field 'Security Manager Out Of Band Flags' and the optional fields 'Appearance',
+ * 'Local Name', and 'Flags'.
+ *
+ * @note To be able to encode the message, a SoftDevice must be enabled and configured.
+ *
+ * @param[in] nfc_ble_pair_type Type of BLE pairing message.
+ * @param[in] p_tk_value Pointer to the authentication Temporary Key (TK). If NULL,
+ * TK value field is not encoded in the NDEF message.
+ * @param[in] p_lesc_data Pointer to the LESC OOB data. If NULL, LESC OOB fields are
+ * not encoded in the NDEF message.
+ * @param[out] p_buf Pointer to the buffer for the message.
+ * @param[in,out] p_len Size of the available memory for the message as input.
+ * Size of the generated message as output.
+ *
+ * @retval NRF_SUCCESS If the function completed successfully.
+ * @retval NRF_ERROR_xxx If an error occurred.
+ */
+ret_code_t nfc_ble_pair_default_msg_encode(nfc_ble_pair_type_t nfc_ble_pair_type,
+ ble_advdata_tk_value_t * const p_tk_value,
+ ble_gap_lesc_oob_data_t * const p_lesc_data,
+ uint8_t * p_buf,
+ uint32_t * p_len);
+
+/** @brief Function for encoding any type of BLE pairing messages with default BLE
+ * advertising data structures and with TK modifier feature.
+ *
+ * This function is very similar to the @ref nfc_ble_pair_default_msg_encode function, but
+ * additionaly enables tracking of TK locations which were encoded in the Connection Handover
+ * NDEF message. After using this function, you can update the TK value in NDEF by calling
+ * @ref nfc_tk_group_modifier_update.
+ *
+ * @param[in] nfc_ble_pair_type Type of BLE pairing message.
+ * @param[in] p_tk_value Pointer to the authentication Temporary Key (TK). If NULL,
+ * TK value field is not encoded in the NDEF message.
+ * @param[in] p_lesc_data Pointer to the LESC OOB data. If NULL, LESC OOB values are
+ * not encoded in the NDEF message.
+ * @param[out] p_buf Pointer to the buffer for the message.
+ * @param[in,out] p_len Size of the available memory for the message as input.
+ * Size of the generated message as output.
+ * @param[in] pp_tk_group Pointer to array of TK locations that should be modified with
+ * @ref nfc_tk_group_modifier_update function.
+ * @param[in] max_group_size Maximal number of TK locations that can added to \p pp_tk_group.
+ *
+ * @retval NRF_SUCCESS If the function completed successfully.
+ * @retval NRF_ERROR_xxx If an error occurred.
+ */
+ret_code_t nfc_ble_pair_msg_updatable_tk_encode(nfc_ble_pair_type_t nfc_ble_pair_type,
+ ble_advdata_tk_value_t * const p_tk_value,
+ ble_gap_lesc_oob_data_t * const p_lesc_data,
+ uint8_t * p_buf,
+ uint32_t * p_len,
+ uint8_t ** pp_tk_group,
+ uint8_t max_group_size);
+
+/**@brief Function for updating the Connection Handover NDEF message with new TK value.
+ *
+ * @details This function updates NDEF message with new TK value. This update is applied to all of
+ * TK locations in the Connection Handover NDEF message. This function can only be used
+ * after calling @ref nfc_ble_pair_msg_updatable_tk_encode, which is used to encode
+ * Connection Handover NDEF message.
+ *
+ * @param[in] p_tk_value Pointer to the new TK value. The NDEF message will be updated with this
+ * value.
+ *
+ * @retval NRF_SUCCESS If the operation was successful.
+ * @retval NRF_ERROR_NULL If pointer to TK locations was NULL.
+ */
+ret_code_t nfc_tk_group_modifier_update(ble_advdata_tk_value_t * p_tk_value);
+
+/**@brief Function for adding new location of TK value to the location description structure.
+ *
+ * @param[in] p_tk_location New location of TK value in the Connection Handover NDEF message.
+ *
+ * @retval NRF_SUCCESS If the operation was successful or if buffer used for holding TK
+ * locations is NULL.
+ * @retval NRF_ERROR_NO_MEM If there is no place in the buffer for the new TK value location.
+ */
+ret_code_t nfc_tk_to_group_add(uint8_t * p_tk_location);
+
+/**@brief Function for updating the Connection Handover NDEF message with a new LESC OOB values.
+ *
+ * @details Updates LESC Confirmation and Random Values based on its locations set by the @ref nfc_lesc_pos_set function.
+ *
+ * @param[in] p_ble_lesc_oob_data Pointer to the new LESC OOB data. The NDEF message will be updated with this data.
+ *
+ * @retval NRF_SUCCESS If the operation was successful.
+ * @retval NRF_ERROR_NULL If pointer to the new LESC OOB data is NULL.
+ * @retval NRF_ERROR_INVALID_STATE If pointer to the LESC OOB data location in NDEF message is NULL.
+ */
+ret_code_t nfc_lesc_data_update(ble_gap_lesc_oob_data_t * p_ble_lesc_oob_data);
+
+/**@brief Function for storing pointers to the LESC OOB data inside NDEF message.
+ *
+ * @details It allows LESC OOB data update without regenerating entire CH NDEF message.
+ *
+ * @param[in] p_confirm Pointer to the LESC Confirmation Value position in the NDEF message.
+ * @param[in] p_random Pointer to the LESC Random Value position in the NDEF message.
+ *
+ * @retval NRF_SUCCESS If the operation was successful.
+ * @retval NRF_ERROR_NULL If either of pointers is set to NULL.
+ */
+ret_code_t nfc_lesc_pos_set(uint8_t * p_confirm, uint8_t * p_random);
+
+/** @} */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // NFC_BLE_PAIR_MSG_H__
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/ndef/connection_handover/common/nfc_ble_pair_common.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/ndef/connection_handover/common/nfc_ble_pair_common.c
new file mode 100644
index 0000000..31bf824
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/ndef/connection_handover/common/nfc_ble_pair_common.c
@@ -0,0 +1,53 @@
+/**
+ * Copyright (c) 2016 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#include "sdk_common.h"
+#if NRF_MODULE_ENABLED(NFC_CH_COMMON)
+#include "nfc_ble_pair_common.h"
+
+#include <stdint.h>
+
+/* Record Payload Type for Bluetooth Carrier Configuration LE record */
+const uint8_t le_oob_rec_type_field[] =
+{
+ 'a', 'p', 'p', 'l', 'i', 'c', 'a', 't', 'i', 'o', 'n', '/', 'v', 'n', 'd', '.',
+ 'b', 'l', 'u', 'e', 't', 'o', 'o', 't', 'h', '.', 'l', 'e', '.', 'o', 'o', 'b'
+};
+
+#endif // NRF_MODULE_ENABLED(NFC_CH_COMMON)
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/ndef/connection_handover/common/nfc_ble_pair_common.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/ndef/connection_handover/common/nfc_ble_pair_common.h
new file mode 100644
index 0000000..e9e26e7
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/ndef/connection_handover/common/nfc_ble_pair_common.h
@@ -0,0 +1,106 @@
+/**
+ * Copyright (c) 2016 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#ifndef NFC_BLE_PAIR_COMMON_H__
+#define NFC_BLE_PAIR_COMMON_H__
+
+#include <stdint.h>
+#include "ble_advdata.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ *
+ * @defgroup nfc_ble_pair_common Common data for Connection Handover and Connection Handover Parser modules
+ * @{
+ * @ingroup nfc_ble_pair_msg
+ */
+
+#define AD_TYPE_LE_ROLE_DATA_SIZE 1UL /**< Data size (in octets) of the LE Role AD type. */
+#define AD_TYPE_LE_ROLE_SIZE (AD_DATA_OFFSET + \
+ AD_TYPE_LE_ROLE_DATA_SIZE) /**< Size (in octets) of the LE Role AD type. */
+#define AD_TYPE_TK_VALUE_DATA_SIZE (sizeof(ble_advdata_tk_value_t)) /**< Data size (in octets) of the Security Manager TK value AD type. */
+#define AD_TYPE_TK_VALUE_SIZE (AD_DATA_OFFSET + \
+ AD_TYPE_TK_VALUE_DATA_SIZE) /**< Size (in octets) of the Security Manager TK value AD type. */
+#define AD_TYPE_OOB_FLAGS_DATA_SIZE 1UL /**< Data size (in octets) of the Security Manager OOB Flags AD type. */
+#define AD_TYPE_OOB_FLAGS_SIZE (AD_DATA_OFFSET + \
+ AD_TYPE_OOB_FLAGS_DATA_SIZE) /**< Size (in octets) of the Security Manager OOB Flags AD type. */
+
+#define AD_TYPE_CONFIRM_VALUE_DATA_SIZE 16UL /**< Data size (in octets) of the LESC Confirmation value. */
+#define AD_TYPE_CONFIRM_VALUE_SIZE (AD_DATA_OFFSET + \
+ AD_TYPE_CONFIRM_VALUE_DATA_SIZE) /**< Size (in octets) of the LESC Confirmation value AD type. */
+#define AD_TYPE_RANDOM_VALUE_DATA_SIZE 16UL /**< Data size (in octets) of the LESC Random value. */
+#define AD_TYPE_RANDOM_VALUE_SIZE (AD_DATA_OFFSET + \
+ AD_TYPE_RANDOM_VALUE_DATA_SIZE) /**< Size (in octets) of the LESC Random value AD type. */
+#define AD_TYPE_LESC_SIZE (AD_TYPE_RANDOM_VALUE_SIZE + \
+ AD_TYPE_CONFIRM_VALUE_SIZE) /**< Total size (in octets) of the LESC OOB AD data fields in NDEF message. */
+
+#define AD_TYPE_SEC_MGR_OOB_FLAG_SET 1U /**< Security Manager OOB Flag set. Flag selection is done using _POS defines */
+#define AD_TYPE_SEC_MGR_OOB_FLAG_CLEAR 0U /**< Security Manager OOB Flag clear. Flag selection is done using _POS defines */
+#define AD_TYPE_SEC_MGR_OOB_FLAG_OOB_DATA_PRESENT_POS 0UL /**< Security Manager OOB Data Present Flag position. */
+#define AD_TYPE_SEC_MGR_OOB_FLAG_OOB_LE_SUPPORTED_POS 1UL /**< Security Manager OOB Low Energy Supported Flag position. */
+#define AD_TYPE_SEC_MGR_OOB_FLAG_SIM_LE_AND_EP_POS 2UL /**< Security Manager OOB Simultaneous LE and BR/EDR to Same Device Capable Flag position. */
+#define AD_TYPE_SEC_MGR_OOB_ADDRESS_TYPE_PUBLIC 0UL /**< Security Manager OOB Public Address type. */
+#define AD_TYPE_SEC_MGR_OOB_ADDRESS_TYPE_RANDOM 1UL /**< Security Manager OOB Random Address type. */
+#define AD_TYPE_SEC_MGR_OOB_FLAG_ADDRESS_TYPE_POS 3UL /**< Security Manager OOB Address type Flag (0 = Public Address, 1 = Random Address) position. */
+
+/**@brief Payload field values of LE Role BLE GAP AD Type. Corresponds with @ref ble_advdata_le_role_t enum. */
+typedef enum
+{
+ NFC_BLE_ADVDATA_ROLE_ENCODED_ONLY_PERIPH = 0, /**< Only Peripheral Role supported. */
+ NFC_BLE_ADVDATA_ROLE_ENCODED_ONLY_CENTRAL, /**< Only Central Role supported. */
+ NFC_BLE_ADVDATA_ROLE_ENCODED_BOTH_PERIPH_PREFERRED, /**< Peripheral and Central Role supported. Peripheral Role preferred for connection establishment. */
+ NFC_BLE_ADVDATA_ROLE_ENCODED_BOTH_CENTRAL_PREFERRED /**< Peripheral and Central Role supported. Central Role preferred for connection establishment */
+} nfc_ble_advdata_le_role_encoded_t;
+
+/**
+ * @brief External reference to the type field of the Bluetooth LE Carrier Configuration NDEF record, defined
+ * in the file @c nfc_ble_pair_common.c
+ */
+extern const uint8_t le_oob_rec_type_field[32];
+
+/** @} */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // NFC_BLE_PAIR_COMMON_H__
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/ndef/connection_handover/ep_oob_rec/nfc_ep_oob_rec.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/ndef/connection_handover/ep_oob_rec/nfc_ep_oob_rec.c
new file mode 100644
index 0000000..12ab9f6
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/ndef/connection_handover/ep_oob_rec/nfc_ep_oob_rec.c
@@ -0,0 +1,188 @@
+/**
+ * Copyright (c) 2015 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#include "sdk_common.h"
+#if NRF_MODULE_ENABLED(NFC_EP_OOB_REC)
+
+#include "nfc_ep_oob_rec.h"
+#include "sdk_errors.h"
+#include "ble_gap.h"
+#include "app_util.h"
+
+/* NFC OOB EP definitions */
+#define NFC_EP_OOB_REC_GAP_ADDR_LEN BLE_GAP_ADDR_LEN
+#define NFC_EP_OOB_REC_OOB_DATA_LEN_SIZE 2UL
+#define NFC_EP_OOB_REC_PAYLOAD_PREFIX_LEN (NFC_EP_OOB_REC_GAP_ADDR_LEN + \
+ NFC_EP_OOB_REC_OOB_DATA_LEN_SIZE)
+
+/* Record Payload Type for Bluetooth Carrier Configuration EP record */
+const uint8_t ndef_ep_oob_record_type[] =
+{
+ 'a', 'p', 'p', 'l', 'i', 'c', 'a', 't', 'i', 'o', 'n', '/', 'v', 'n', 'd', '.',
+ 'b', 'l', 'u', 'e', 't', 'o', 'o', 't', 'h', '.', 'e', 'p', '.', 'o', 'o', 'b'
+};
+
+/**
+ * @brief Function for validating AD structure content for a Bluetooth Carrier Configuration EP record.
+ *
+ * This function validates AD structure content. LE Bluetooth Device Address and LE Role
+ * fields must not be included. Security Manager OOB Flags structure is required.
+ *
+ * @param[in] p_ble_advdata Pointer to the description of the payload.
+ *
+ * @retval NRF_SUCCESS If the validation was successful.
+ * @retval NRF_ERROR_INVALID_PARAM Otherwise.
+ */
+static ret_code_t nfc_ep_oob_adv_data_check(ble_advdata_t const * const p_ble_advdata)
+{
+ if ((true == p_ble_advdata->include_ble_device_addr) ||
+ (BLE_ADVDATA_ROLE_NOT_PRESENT != p_ble_advdata->le_role) ||
+ (NULL == p_ble_advdata->p_sec_mgr_oob_flags))
+ {
+ return NRF_ERROR_INVALID_PARAM;
+ }
+
+ /* If Flags field in AD structure is present, the BLE_GAP_ADV_FLAG_BR_EDR_NOT_SUPPORTED flag
+ must be set. */
+ if ((0 != p_ble_advdata->flags) &&
+ ((p_ble_advdata->flags & BLE_GAP_ADV_FLAG_BR_EDR_NOT_SUPPORTED) == 0))
+ {
+ return NRF_ERROR_INVALID_PARAM;
+ }
+ return NRF_SUCCESS;
+}
+
+/**
+ * @brief Function for encoding device address to Bluetooth Carrier Configuration EP record.
+ *
+ * This fuction is used to encode device address to Bluetooth Carrier Configuration EP record.
+ *
+ * @param[in] p_encoded_data Pointer to the buffer where encoded data will be returned.
+ * @param[in] max_len Available memory in the buffer.
+ *
+ * @retval NRF_SUCCESS If the encoding was successful.
+ * @retval NRF_ERROR_NO_MEM If available memory was not enough.
+ * @retval NRF_ERROR_xxx If any other error occured.
+ */
+static ret_code_t nfc_ep_oob_bluetooth_device_address_encode(uint8_t * const p_encoded_data,
+ uint16_t max_len)
+{
+ ret_code_t err_code = NRF_SUCCESS;
+ ble_gap_addr_t device_address;
+
+ memset(&device_address, 0x00, sizeof(device_address));
+
+ if (NFC_EP_OOB_REC_GAP_ADDR_LEN > max_len)
+ {
+ return NRF_ERROR_NO_MEM;
+ }
+
+ /* Get BLE address */
+ err_code = sd_ble_gap_addr_get(&device_address);
+ if (err_code != NRF_SUCCESS)
+ {
+ return err_code;
+ }
+
+ /* Encode Bluetooth EP device address */
+ memcpy(p_encoded_data, device_address.addr, NFC_EP_OOB_REC_GAP_ADDR_LEN);
+
+ return NRF_SUCCESS;
+}
+
+ret_code_t nfc_ep_oob_payload_constructor(ble_advdata_t * p_ble_advdata,
+ uint8_t * p_buff,
+ uint32_t * p_len)
+{
+ ret_code_t err_code = NRF_SUCCESS;
+ uint8_t * p_ad_data = NULL;
+ uint16_t payload_len, ad_data_len;
+
+ /* Check correctness of the configuration structure */
+ err_code = nfc_ep_oob_adv_data_check(p_ble_advdata);
+ if (NRF_SUCCESS != err_code)
+ {
+ return err_code;
+ }
+
+ if (p_buff != NULL)
+ {
+ /* Validate if there is enough memory for OOB payload length field and BLE device address */
+ if (NFC_EP_OOB_REC_PAYLOAD_PREFIX_LEN > *p_len)
+ {
+ return NRF_ERROR_NO_MEM;
+ }
+
+ /* Set proper memory offset in payload buffer for AD structure and count available memory.
+ * Bluetooth EP device address and OOB payload length field must be inserted before the AD payload */
+ p_ad_data = (uint8_t *) (p_buff + NFC_EP_OOB_REC_PAYLOAD_PREFIX_LEN);
+ ad_data_len = *p_len - NFC_EP_OOB_REC_PAYLOAD_PREFIX_LEN;
+ if ( *p_len - NFC_EP_OOB_REC_PAYLOAD_PREFIX_LEN > UINT16_MAX )
+ {
+ ad_data_len = UINT16_MAX;
+ }
+ }
+
+ /* Encode AD structures into NFC record payload */
+ err_code = nfc_ble_oob_adv_data_encode(p_ble_advdata, p_ad_data, &ad_data_len);
+ if (NRF_SUCCESS != err_code)
+ {
+ return err_code;
+ }
+
+ /* Now as the final payload length is known OOB payload length field, and Bluetooth device
+ * address can be encoded */
+ payload_len = ad_data_len + NFC_EP_OOB_REC_PAYLOAD_PREFIX_LEN;
+ if (p_buff != NULL)
+ {
+ p_buff += uint16_encode(payload_len, p_buff);
+ err_code = nfc_ep_oob_bluetooth_device_address_encode(p_buff, p_ad_data - p_buff);
+ if (NRF_SUCCESS != err_code)
+ {
+ return err_code;
+ }
+ }
+
+ /* Update total payload length */
+ *p_len = payload_len;
+
+ return err_code;
+}
+
+#endif // NRF_MODULE_ENABLED(NFC_EP_OOB_REC)
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/ndef/connection_handover/ep_oob_rec/nfc_ep_oob_rec.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/ndef/connection_handover/ep_oob_rec/nfc_ep_oob_rec.h
new file mode 100644
index 0000000..1b7be22
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/ndef/connection_handover/ep_oob_rec/nfc_ep_oob_rec.h
@@ -0,0 +1,135 @@
+/**
+ * Copyright (c) 2015 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#ifndef NFC_EP_OOB_REC_H__
+#define NFC_EP_OOB_REC_H__
+
+/**@file
+ *
+ * @defgroup nfc_ep_oob_rec EP OOB records
+ * @{
+ * @ingroup nfc_ble_pair_msg
+ *
+ * @brief Generation of NFC NDEF EP OOB records for NDEF messages.
+ *
+ */
+
+#include <stdint.h>
+#include "nfc_ndef_record.h"
+#include "nfc_ble_oob_advdata.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @brief Size of the type field of the Bluetooth Carrier Configuration EP record, defined in the
+ * file @c nfc_ep_oob_rec.c. It is used in the @ref NFC_NDEF_EP_OOB_RECORD_DESC_DEF macro.
+ */
+#define NFC_EP_OOB_REC_TYPE_LENGTH 32
+
+/**
+ * @brief External reference to the type field of the Bluetooth Carrier Configuration EP record, defined
+ * in the file @c nfc_ep_oob_rec.c. It is used in the @ref NFC_NDEF_EP_OOB_RECORD_DESC_DEF macro.
+ */
+extern const uint8_t ndef_ep_oob_record_type[NFC_EP_OOB_REC_TYPE_LENGTH];
+
+/**
+ * @brief Function for constructing the payload for a Bluetooth Carrier Configuration EP record.
+ *
+ * This function encodes the record payload according to the BLE AD structure. It implements
+ * an API compatible with @ref p_payload_constructor_t.
+ *
+ * @param[in] p_ble_advdata Pointer to the description of the payload.
+ * @param[out] p_buff Pointer to payload destination. If NULL, function will
+ * calculate the expected size of the record payload.
+ *
+ * @param[in,out] p_len Size of available memory to write as input. Size of generated
+ * payload as output.
+ *
+ * @retval NRF_SUCCESS If the record payload was encoded successfully.
+ * @retval NRF_ERROR_NO_MEM If available memory was not enough for record payload to be encoded.
+ * @retval Other If any other error occurred during record payload encoding.
+ */
+ret_code_t nfc_ep_oob_payload_constructor(ble_advdata_t * p_ble_advdata,
+ uint8_t * p_buff,
+ uint32_t * p_len);
+
+/** @brief Macro for generating a description of an NFC NDEF Bluetooth Carrier Configuration EP record.
+ *
+ * This macro declares and initializes an instance of an NFC NDEF record description
+ * for a Bluetooth Carrier Configuration EP record.
+ *
+ * @note The record descriptor is declared as automatic variable, which implies that
+ * the NDEF message encoding (see @ref nfc_ble_simplified_ep_oob_msg_encode)
+ * must be done in the same variable scope.
+ *
+ * @param[in] NAME Name for accessing record descriptor.
+ * @param[in] PAYLOAD_ID NDEF record header Payload ID field (Limited to one byte).
+ * If 0, no ID is present in the record description.
+ * @param[in] P_BLE_ADVDATA Pointer to the encoded BLE advertising data structure. This
+ * data is used to create the record payload.
+ */
+#define NFC_NDEF_EP_OOB_RECORD_DESC_DEF(NAME, \
+ PAYLOAD_ID, \
+ P_BLE_ADVDATA) \
+ uint8_t NAME##_ndef_ep_oob_record_id = (PAYLOAD_ID); \
+ uint8_t NAME##_ndef_ep_oob_record_id_length = ((PAYLOAD_ID) != 0) ? 1 : 0; \
+ NFC_NDEF_GENERIC_RECORD_DESC_DEF( NAME, \
+ TNF_MEDIA_TYPE, \
+ &NAME##_ndef_ep_oob_record_id, \
+ NAME##_ndef_ep_oob_record_id_length, \
+ (ndef_ep_oob_record_type), \
+ sizeof(ndef_ep_oob_record_type), \
+ nfc_ep_oob_payload_constructor, \
+ (P_BLE_ADVDATA)) \
+
+/**
+ * @brief Macro for accessing the NFC NDEF Bluetooth Carrier Configuration EP record descriptor
+ * instance that was created with @ref NFC_NDEF_EP_OOB_RECORD_DESC_DEF.
+ */
+#define NFC_NDEF_EP_OOB_RECORD_DESC(NAME) NFC_NDEF_GENERIC_RECORD_DESC(NAME)
+
+/** @} */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // NFC_EP_OOB_REC_H__
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/ndef/connection_handover/hs_rec/nfc_hs_rec.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/ndef/connection_handover/hs_rec/nfc_hs_rec.c
new file mode 100644
index 0000000..b453087
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/ndef/connection_handover/hs_rec/nfc_hs_rec.c
@@ -0,0 +1,107 @@
+/**
+ * Copyright (c) 2015 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#include "sdk_common.h"
+#if NRF_MODULE_ENABLED(NFC_HS_REC)
+
+#include "nfc_hs_rec.h"
+#include "nfc_ac_rec.h"
+#include "nrf_error.h"
+
+#define HS_REC_VERSION_SIZE 1
+
+const uint8_t nfc_hs_rec_type_field[] = {'H', 's'}; ///< Handover Select record type.
+
+
+ret_code_t nfc_hs_rec_payload_constructor(nfc_hs_rec_payload_desc_t * p_nfc_hs_rec_payload_desc,
+ uint8_t * p_buff,
+ uint32_t * p_len)
+{
+ ret_code_t err_code = NRF_SUCCESS;
+
+ if (p_buff != NULL)
+ {
+ // There must be at least 1 free byte in buffer for version byte.
+ if (*p_len < HS_REC_VERSION_SIZE)
+ {
+ return NRF_ERROR_NO_MEM;
+ }
+
+ // Major/minor version byte.
+ *p_buff = ( (p_nfc_hs_rec_payload_desc->major_version << 4) & 0xF0) |
+ ( p_nfc_hs_rec_payload_desc->minor_version & 0x0F);
+ p_buff += HS_REC_VERSION_SIZE;
+
+ // Decrement remaining buffer size.
+ *p_len -= HS_REC_VERSION_SIZE;
+ }
+
+ // Encode local records encapsulated in a message.
+ err_code = nfc_ndef_msg_encode(p_nfc_hs_rec_payload_desc->p_local_records, p_buff, p_len);
+ if (err_code!= NRF_SUCCESS)
+ {
+ return err_code;
+ }
+
+ // Add version byte to the total record size.
+ *p_len += HS_REC_VERSION_SIZE;
+
+ return NRF_SUCCESS;
+}
+
+
+void nfc_hs_rec_local_record_clear(nfc_ndef_record_desc_t * p_hs_rec)
+{
+ nfc_hs_rec_payload_desc_t* p_hs_payload =
+ (nfc_hs_rec_payload_desc_t*)p_hs_rec->p_payload_descriptor;
+
+ nfc_ndef_msg_clear(p_hs_payload->p_local_records);
+}
+
+
+ret_code_t nfc_hs_rec_local_record_add(nfc_ndef_record_desc_t * p_hs_rec,
+ nfc_ndef_record_desc_t * p_local_rec)
+{
+ nfc_hs_rec_payload_desc_t* p_hs_payload =
+ (nfc_hs_rec_payload_desc_t*)p_hs_rec->p_payload_descriptor;
+
+ return nfc_ndef_msg_record_add(p_hs_payload->p_local_records, p_local_rec);
+}
+
+#endif // NRF_MODULE_ENABLED(NFC_HS_REC)
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/ndef/connection_handover/hs_rec/nfc_hs_rec.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/ndef/connection_handover/hs_rec/nfc_hs_rec.h
new file mode 100644
index 0000000..0d0d88b
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/ndef/connection_handover/hs_rec/nfc_hs_rec.h
@@ -0,0 +1,165 @@
+/**
+ * Copyright (c) 2015 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#ifndef NFC_HS_REC_H__
+#define NFC_HS_REC_H__
+
+/**@file
+ *
+ * @defgroup nfc_hs_rec Hs (Handover Select) records
+ * @{
+ * @ingroup nfc_ble_pair_msg
+ *
+ * @brief Generation of NFC NDEF Handover Select records for NDEF messages.
+ *
+ */
+
+#include <stdint.h>
+#include "nfc_ndef_record.h"
+#include "nfc_ndef_msg.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @brief Handover Select record payload descriptor.
+ */
+typedef struct
+{
+ uint8_t major_version; ///< Major version number of the supported Connection Handover specification.
+ uint8_t minor_version; ///< Minor version number of the supported Connection Handover specification.
+ nfc_ndef_msg_desc_t * p_local_records; ///< Pointer to a message encapsulating local records.
+} nfc_hs_rec_payload_desc_t;
+
+
+/**
+ * @brief Constructor for an NFC NDEF Handover Select record payload.
+ *
+ * This function encodes the payload of a Handover Select record as specified in the Connection
+ * Handover standard. It implements an API compatible with @ref p_payload_constructor_t.
+ */
+
+ret_code_t nfc_hs_rec_payload_constructor(nfc_hs_rec_payload_desc_t * p_nfc_hs_rec_payload_desc,
+ uint8_t * p_buff,
+ uint32_t * p_len);
+
+/**
+ * @brief An external reference to the type field of the Handover Select record, defined in the
+ * file @c nfc_hs_rec.c. It is used in the @ref NFC_NDEF_HS_RECORD_DESC_DEF macro.
+ */
+extern const uint8_t nfc_hs_rec_type_field[];
+
+/**
+ * @brief Size of the type field of the Handover Select record, defined in the
+ * file @c nfc_hs_rec.c. It is used in the @ref NFC_NDEF_HS_RECORD_DESC_DEF macro.
+ */
+#define NFC_HS_REC_TYPE_LENGTH 2
+
+/**
+ * @brief Macro for creating and initializing an NFC NDEF record descriptor for a Handover Select record.
+ *
+ * This macro creates and initializes an instance of type @ref nfc_ndef_record_desc_t and
+ * an instance of type @ref nfc_hs_rec_payload_desc_t, which together constitute an instance of a Handover Select record.
+ *
+ * Use the macro @ref NFC_NDEF_HS_RECORD_DESC to access the NDEF Handover Select record descriptor instance.
+ *
+ * @note The record descriptor is declared as automatic variable, which implies that
+ * the NDEF message encoding (see @ref nfc_ble_full_handover_select_msg_encode)
+ * must be done in the same variable scope.
+ *
+ * @param[in] NAME Name of the created record descriptor instance.
+ * @param[in] MAJOR_VERSION Major version number of the supported Connection Handover specification.
+ * @param[in] MINOR_VERSION Minor version number of the supported Connection Handover specification.
+ * @param[in] MAX_RECORDS Maximum number of local records (ac records plus optional err record).
+ */
+#define NFC_NDEF_HS_RECORD_DESC_DEF(NAME, \
+ MAJOR_VERSION, \
+ MINOR_VERSION, \
+ MAX_RECORDS) \
+ NFC_NDEF_MSG_DEF(NAME, MAX_RECORDS); \
+ nfc_hs_rec_payload_desc_t NAME##_nfc_hs_rec_payload_desc = \
+ { \
+ .major_version = MAJOR_VERSION, \
+ .minor_version = MINOR_VERSION, \
+ .p_local_records = &NFC_NDEF_MSG(NAME) \
+ }; \
+ NFC_NDEF_GENERIC_RECORD_DESC_DEF(NAME, \
+ TNF_WELL_KNOWN, \
+ 0, \
+ 0, \
+ nfc_hs_rec_type_field, \
+ NFC_HS_REC_TYPE_LENGTH, \
+ nfc_hs_rec_payload_constructor, \
+ &(NAME##_nfc_hs_rec_payload_desc))
+
+/**
+ * @brief Macro for accessing the NFC NDEF Handover Select record descriptor
+ * instance that was created with @ref NFC_NDEF_HS_RECORD_DESC_DEF.
+ */
+#define NFC_NDEF_HS_RECORD_DESC(NAME) NFC_NDEF_GENERIC_RECORD_DESC(NAME)
+
+/**
+ * @brief Function for clearing local records in the NFC NDEF Handover Select record.
+ *
+ * This function clears local records from the Handover Select record.
+ *
+ * @param[in, out] p_hs_rec Pointer to the Handover Select record descriptor.
+ */
+void nfc_hs_rec_local_record_clear(nfc_ndef_record_desc_t * p_hs_rec);
+
+/**
+ * @brief Function for adding a local record to an NFC NDEF Handover Select record.
+ *
+ * @param[in, out] p_hs_rec Pointer to a Handover Select record.
+ * @param[in] p_local_rec Pointer to a local record to add.
+ *
+ * @retval NRF_SUCCESS If the local record was added successfully.
+ * @retval NRF_ERROR_NO_MEM If the Handover Select record already contains the maximum number of local records.
+ */
+ret_code_t nfc_hs_rec_local_record_add(nfc_ndef_record_desc_t * p_hs_rec,
+ nfc_ndef_record_desc_t * p_local_rec);
+
+/** @} */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // NFC_HS_REC_H__
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/ndef/connection_handover/le_oob_rec/nfc_le_oob_rec.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/ndef/connection_handover/le_oob_rec/nfc_le_oob_rec.c
new file mode 100644
index 0000000..95d939f
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/ndef/connection_handover/le_oob_rec/nfc_le_oob_rec.c
@@ -0,0 +1,106 @@
+/**
+ * Copyright (c) 2015 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#include "sdk_common.h"
+#if NRF_MODULE_ENABLED(NFC_LE_OOB_REC)
+
+#include "nfc_le_oob_rec.h"
+#include "sdk_errors.h"
+#include "ble_gap.h"
+#include "nfc_ble_pair_common.h"
+
+/**
+ * @brief Function for validating AD structure content for a Bluetooth Carrier Configuration LE record.
+ *
+ * This function validates AD structure content. LE Bluetooth Device Address and LE Role
+ * fields are required. Security Manager Out Of Band Flags structure must not be included.
+ *
+ * @param[in] p_ble_advdata Pointer to the description of the payload.
+ *
+ * @retval NRF_SUCCESS If the validation was successful.
+ * @retval NRF_ERROR_INVALID_PARAM Otherwise.
+ */
+static ret_code_t nfc_le_oob_adv_data_check(ble_advdata_t const * const p_ble_advdata)
+{
+ if ((false == p_ble_advdata->include_ble_device_addr) ||
+ (BLE_ADVDATA_ROLE_NOT_PRESENT == p_ble_advdata->le_role) ||
+ (NULL != p_ble_advdata->p_sec_mgr_oob_flags))
+ {
+ return NRF_ERROR_INVALID_PARAM;
+ }
+
+ /* If Flags field in AD structure is present, the BLE_GAP_ADV_FLAG_BR_EDR_NOT_SUPPORTED flag
+ must be set. */
+ if ((0 != p_ble_advdata->flags) &&
+ ((p_ble_advdata->flags & BLE_GAP_ADV_FLAG_BR_EDR_NOT_SUPPORTED) == 0))
+ {
+ return NRF_ERROR_INVALID_PARAM;
+ }
+
+ return NRF_SUCCESS;
+}
+
+ret_code_t nfc_le_oob_payload_constructor(ble_advdata_t * p_ble_advdata,
+ uint8_t * p_buff,
+ uint32_t * p_len)
+{
+ ret_code_t err_code = NRF_SUCCESS;
+
+ /* Check correctness of the configuration structure */
+ err_code = nfc_le_oob_adv_data_check(p_ble_advdata);
+ if (NRF_SUCCESS != err_code)
+ {
+ return err_code;
+ }
+
+ /* Encode AD structures into NFC record payload */
+ uint16_t buff_len = *p_len;
+ if (*p_len > UINT16_MAX)
+ {
+ buff_len = UINT16_MAX;
+ }
+ err_code = nfc_ble_oob_adv_data_encode(p_ble_advdata, p_buff, &buff_len);
+
+ /* Update total payload length */
+ *p_len = (uint32_t) buff_len;
+
+ return err_code;
+}
+
+#endif // NRF_MODULE_ENABLED(NFC_LE_OOB_REC)
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/ndef/connection_handover/le_oob_rec/nfc_le_oob_rec.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/ndef/connection_handover/le_oob_rec/nfc_le_oob_rec.h
new file mode 100644
index 0000000..6671671
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/ndef/connection_handover/le_oob_rec/nfc_le_oob_rec.h
@@ -0,0 +1,123 @@
+/**
+ * Copyright (c) 2015 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#ifndef NFC_LE_OOB_REC_H__
+#define NFC_LE_OOB_REC_H__
+
+/**@file
+ *
+ * @defgroup nfc_le_oob_rec LE OOB records
+ * @{
+ * @ingroup nfc_ble_pair_msg
+ *
+ * @brief Generation of NFC NDEF LE OOB records for NDEF messages.
+ *
+ */
+
+#include <stdint.h>
+#include "nfc_ndef_record.h"
+#include "nfc_ble_oob_advdata.h"
+#include "nfc_ble_pair_common.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @brief Function for constructing the payload for a Bluetooth Carrier Configuration LE record.
+ *
+ * This function encodes the record payload according to the BLE AD structure. It implements
+ * an API compatible with @ref p_payload_constructor_t
+ *
+ * @param[in] p_ble_advdata Pointer to the description of the payload.
+ * @param[out] p_buff Pointer to payload destination. If NULL, function will
+ * calculate the expected size of the record payload.
+ *
+ * @param[in,out] p_len Size of available memory to write as input. Size of generated
+ * payload as output.
+ *
+ * @retval NRF_SUCCESS If the record payload was encoded successfully.
+ * @retval Other If the record payload encoding failed.
+ */
+ret_code_t nfc_le_oob_payload_constructor(ble_advdata_t * p_ble_advdata,
+ uint8_t * p_buff,
+ uint32_t * p_len);
+
+/** @brief Macro for generating a description of an NFC NDEF Bluetooth Carrier Configuration LE Record.
+ *
+ * This macro declares and initializes an instance of an NFC NDEF record description
+ * for a Bluetooth Carrier Configuration LE record.
+ *
+ * @note The record descriptor is declared as automatic variable, which implies that
+ * the NDEF message encoding (see @ref nfc_ble_simplified_le_oob_msg_encode)
+ * must be done in the same variable scope.
+ *
+ * @param[in] NAME Name for accessing record descriptor.
+ * @param[in] PAYLOAD_ID NDEF record header Payload ID field (Limited to one byte).
+ * If 0, no ID is present in the record description.
+ * @param[in] P_BLE_ADVDATA Pointer to the encoded BLE advertising data structure. This
+ * data is used to create the record payload.
+ */
+#define NFC_NDEF_LE_OOB_RECORD_DESC_DEF(NAME, \
+ PAYLOAD_ID, \
+ P_BLE_ADVDATA) \
+ uint8_t NAME##_ndef_le_oob_record_id = (PAYLOAD_ID); \
+ uint8_t NAME##_ndef_le_oob_record_id_length = ((PAYLOAD_ID) != 0) ? 1 : 0; \
+ NFC_NDEF_GENERIC_RECORD_DESC_DEF( NAME, \
+ TNF_MEDIA_TYPE, \
+ &NAME##_ndef_le_oob_record_id, \
+ NAME##_ndef_le_oob_record_id_length, \
+ (le_oob_rec_type_field), \
+ sizeof(le_oob_rec_type_field), \
+ nfc_le_oob_payload_constructor, \
+ (P_BLE_ADVDATA)) \
+
+/**
+ * @brief Macro for accessing the NFC NDEF Bluetooth Carrier Configuration LE record descriptor
+ * instance that was created with @ref NFC_NDEF_LE_OOB_RECORD_DESC_DEF.
+ */
+#define NFC_NDEF_LE_OOB_RECORD_DESC(NAME) NFC_NDEF_GENERIC_RECORD_DESC(NAME)
+
+/** @} */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // NFC_LE_OOB_REC_H__
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/ndef/generic/message/nfc_ndef_msg.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/ndef/generic/message/nfc_ndef_msg.c
new file mode 100644
index 0000000..b1796af
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/ndef/generic/message/nfc_ndef_msg.c
@@ -0,0 +1,183 @@
+/**
+ * Copyright (c) 2015 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#include "sdk_common.h"
+#if NRF_MODULE_ENABLED(NFC_NDEF_MSG)
+
+#include "app_util.h"
+#include "nfc_ndef_msg.h"
+#include "nordic_common.h"
+#include "nrf.h"
+
+
+/**
+ * @brief Resolve the value of record location flags of the NFC NDEF record within an NFC NDEF message.
+ */
+__STATIC_INLINE nfc_ndef_record_location_t record_location_get(uint32_t index,
+ uint32_t record_count)
+{
+ nfc_ndef_record_location_t record_location;
+
+ if (index == 0)
+ {
+ if (record_count == 1)
+ {
+ record_location = NDEF_LONE_RECORD;
+ }
+ else
+ {
+ record_location = NDEF_FIRST_RECORD;
+ }
+ }
+ else if (record_count == index + 1)
+ {
+ record_location = NDEF_LAST_RECORD;
+ }
+ else
+ {
+ record_location = NDEF_MIDDLE_RECORD;
+ }
+
+ return record_location;
+}
+
+
+ret_code_t nfc_ndef_msg_encode(nfc_ndef_msg_desc_t const * p_ndef_msg_desc,
+ uint8_t * p_msg_buffer,
+ uint32_t * const p_msg_len)
+{
+ nfc_ndef_record_location_t record_location;
+ uint32_t temp_len;
+ uint32_t i;
+ uint32_t err_code;
+
+ uint32_t sum_of_len = 0;
+
+ if ((p_ndef_msg_desc == NULL) || p_msg_len == NULL)
+ {
+ return NRF_ERROR_NULL;
+ }
+
+ nfc_ndef_record_desc_t * * pp_record_rec_desc = p_ndef_msg_desc->pp_record;
+
+ if (p_ndef_msg_desc->pp_record == NULL)
+ {
+ return NRF_ERROR_NULL;
+ }
+
+#if NFC_NDEF_MSG_TAG_TYPE == TYPE_4_TAG
+ uint8_t * p_root_msg_buffer = p_msg_buffer;
+
+ if (p_msg_buffer != NULL)
+ {
+ if (*p_msg_len < NLEN_FIELD_SIZE)
+ {
+ return NRF_ERROR_NO_MEM;
+ }
+
+ p_msg_buffer += NLEN_FIELD_SIZE;
+ }
+ sum_of_len += NLEN_FIELD_SIZE;
+#endif
+
+ for (i = 0; i < p_ndef_msg_desc->record_count; i++)
+ {
+ record_location = record_location_get(i, p_ndef_msg_desc->record_count);
+
+ temp_len = *p_msg_len - sum_of_len;
+
+ err_code = nfc_ndef_record_encode(*pp_record_rec_desc,
+ record_location,
+ p_msg_buffer,
+ &temp_len);
+
+ if (err_code != NRF_SUCCESS)
+ {
+ return err_code;
+ }
+
+ sum_of_len += temp_len;
+ if (p_msg_buffer != NULL)
+ {
+ p_msg_buffer += temp_len;
+ }
+
+ /* next record */
+ pp_record_rec_desc++;
+ }
+
+#if NFC_NDEF_MSG_TAG_TYPE == TYPE_4_TAG
+ if (p_msg_buffer != NULL)
+ {
+ if (sum_of_len - NLEN_FIELD_SIZE > UINT16_MAX)
+ {
+ return NRF_ERROR_NOT_SUPPORTED;
+ }
+
+ UNUSED_RETURN_VALUE(uint16_big_encode(sum_of_len - NLEN_FIELD_SIZE, p_root_msg_buffer));
+ }
+#endif
+
+ *p_msg_len = sum_of_len;
+
+ return NRF_SUCCESS;
+}
+
+
+void nfc_ndef_msg_clear(nfc_ndef_msg_desc_t * p_msg)
+{
+ p_msg->record_count = 0;
+}
+
+
+ret_code_t nfc_ndef_msg_record_add(nfc_ndef_msg_desc_t * const p_msg,
+ nfc_ndef_record_desc_t * const p_record)
+{
+ if (p_msg->record_count >= p_msg->max_record_count)
+ {
+ return NRF_ERROR_NO_MEM;
+ }
+
+ p_msg->pp_record[p_msg->record_count] = p_record;
+ p_msg->record_count++;
+
+ return NRF_SUCCESS;
+}
+
+#endif // NRF_MODULE_ENABLED(NFC_NDEF_MSG)
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/ndef/generic/message/nfc_ndef_msg.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/ndef/generic/message/nfc_ndef_msg.h
new file mode 100644
index 0000000..9ca15f3
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/ndef/generic/message/nfc_ndef_msg.h
@@ -0,0 +1,197 @@
+/**
+ * Copyright (c) 2015 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#ifndef NFC_NDEF_MSG_H__
+#define NFC_NDEF_MSG_H__
+
+#include "nfc_ndef_record.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+/**@file
+ *
+ * @defgroup nfc_ndef_msg Custom NDEF messages
+ * @{
+ * @ingroup nfc_modules
+ *
+ * @brief Generation of NFC NDEF messages for the NFC tag.
+ *
+ */
+
+#define TYPE_4_TAG 4U ///< Type 4 Tag identifier.
+#define NLEN_FIELD_SIZE 2U ///< Size of NLEN field, used to encode NDEF message for Type 4 Tag.
+
+ /**
+ * @brief NDEF message descriptor.
+ */
+ typedef struct {
+ nfc_ndef_record_desc_t ** pp_record; ///< Pointer to an array of pointers to NDEF record descriptors.
+ uint32_t max_record_count; ///< Number of elements in the allocated pp_record array, which defines the maximum number of records within the NDEF message.
+ uint32_t record_count; ///< Number of records in the NDEF message.
+ } nfc_ndef_msg_desc_t;
+
+ /**
+ * @brief Function for encoding an NDEF message.
+ *
+ * This function encodes an NDEF message according to the provided message descriptor.
+ *
+ * @note The way of encoding an NDEF message may vary depending on tag's platform, which
+ * can be chosen with @ref NFC_NDEF_MSG_TAG_TYPE in @c sdk_config.h.
+ *
+ * @param[in] p_ndef_msg_desc Pointer to the message descriptor.
+ * @param[out] p_msg_buffer Pointer to the message destination. If NULL, function will
+ * calculate the expected size of the message.
+ * @param[in,out] p_msg_len Size of the available memory for the message as input. Size of
+ * the generated message as output.
+ *
+ * @return Return value from @ref nfc_ndef_record_encode.
+ */
+ret_code_t nfc_ndef_msg_encode(nfc_ndef_msg_desc_t const * p_ndef_msg_desc,
+ uint8_t * p_msg_buffer,
+ uint32_t * const p_msg_len);
+
+/**
+ * @brief Function for clearing an NDEF message.
+ *
+ * This function clears an NDEF message descriptor, thus empties the NDEF message.
+ *
+ * @param[in,out] p_msg Pointer to the message descriptor.
+ */
+void nfc_ndef_msg_clear( nfc_ndef_msg_desc_t * p_msg);
+
+/**
+ * @brief Function for adding a record to an NDEF message.
+ *
+ * @param[in] p_record Pointer to the record descriptor.
+ * @param[in,out] p_msg Pointer to the message descriptor.
+ *
+ * @retval NRF_SUCCESS If the record was added successfully.
+ * @retval NRF_ERROR_NO_MEM If the message already contains the maximum number of records and the operation is not allowed.
+ */
+ret_code_t nfc_ndef_msg_record_add(nfc_ndef_msg_desc_t * const p_msg,
+ nfc_ndef_record_desc_t * const p_record);
+
+
+/**@brief Macro for creating and initializing an NFC NDEF message descriptor.
+ *
+ * This macro creates and initializes an instance of type @ref nfc_ndef_msg_desc_t
+ * and an array of pointers to record descriptors (@ref nfc_ndef_record_desc_t) used
+ * by the message.
+ *
+ * Use the macro @ref NFC_NDEF_MSG to access the NDEF message descriptor instance.
+ *
+ * @note The message descriptor is declared as automatic variable, which implies that
+ * the NDEF message encoding must be done in the same variable scope.
+ *
+ * @param[in] NAME Name of the related instance.
+ * @param[in] MAX_RECORD_CNT Maximal count of records in the message.
+ */
+#define NFC_NDEF_MSG_DEF(NAME, MAX_RECORD_CNT) \
+ nfc_ndef_record_desc_t * NAME##_nfc_ndef_p_record_desc_array[MAX_RECORD_CNT]; \
+ nfc_ndef_msg_desc_t NAME##_nfc_ndef_msg_desc = \
+ { \
+ .pp_record = NAME##_nfc_ndef_p_record_desc_array, \
+ .max_record_count = MAX_RECORD_CNT, \
+ .record_count = 0 \
+ }
+
+/** @brief Macro for accessing the NFC NDEF message descriptor instance
+ * that you created with @ref NFC_NDEF_MSG_DEF.
+ */
+#define NFC_NDEF_MSG(NAME) (NAME##_nfc_ndef_msg_desc)
+
+/**
+ * @brief Macro for creating and initializing an NFC NDEF record descriptor with an encapsulated NDEF message.
+
+ * This macro creates and initializes a static instance of type
+ * @ref nfc_ndef_record_desc_t that contains an encapsulated NDEF message as
+ * payload. @ref nfc_ndef_msg_encode is used as payload constructor to encode
+ * the message. The encoded message is then used as payload for the record.
+ *
+ * Use the macro @ref NFC_NDEF_NESTED_NDEF_MSG_RECORD to access the NDEF record descriptor instance.
+ *
+ * @note The message descriptor is declared as automatic variable, which implies that
+ * the NDEF message encoding must be done in the same variable scope.
+ *
+ * @param[in] NAME Name of the created record descriptor instance.
+ * @param[in] TNF Type Name Format (TNF) value for the record.
+ * @param[in] P_ID Pointer to the ID string.
+ * @param[in] ID_LEN Length of the ID string.
+ * @param[in] P_TYPE Pointer to the type string.
+ * @param[in] TYPE_LEN Length of the type string.
+ * @param[in] P_NESTED_MESSAGE Pointer to the message descriptor to encapsulate
+ * as the record's payload.
+ */
+#define NFC_NDEF_NESTED_NDEF_MSG_RECORD_DEF( NAME, \
+ TNF, \
+ P_ID, \
+ ID_LEN, \
+ P_TYPE, \
+ TYPE_LEN, \
+ P_NESTED_MESSAGE ) \
+ nfc_ndef_record_desc_t NAME##_ndef_record_nested_desc = \
+ { \
+ .tnf = TNF, \
+ \
+ .id_length = ID_LEN, \
+ .p_id = P_ID, \
+ \
+ .type_length = TYPE_LEN, \
+ .p_type = P_TYPE, \
+ \
+ .payload_constructor = (p_payload_constructor_t)(nfc_ndef_msg_encode), \
+ .p_payload_descriptor = (void*) (P_NESTED_MESSAGE) \
+ }
+
+/** @brief Macro for accessing the NFC NDEF record descriptor instance
+ * that you created with @ref NFC_NDEF_NESTED_NDEF_MSG_RECORD_DEF.
+ */
+#define NFC_NDEF_NESTED_NDEF_MSG_RECORD(NAME) (NAME##_ndef_record_nested_desc)
+
+/**
+ * @}
+ */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/ndef/generic/record/nfc_ndef_record.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/ndef/generic/record/nfc_ndef_record.c
new file mode 100644
index 0000000..9397236
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/ndef/generic/record/nfc_ndef_record.c
@@ -0,0 +1,191 @@
+/**
+ * Copyright (c) 2015 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#include "sdk_config.h"
+#include "nordic_common.h"
+#if NRF_MODULE_ENABLED(NFC_NDEF_RECORD)
+
+#include <string.h>
+#include "nfc_ndef_record.h"
+#include "app_util.h"
+#include "nrf.h"
+
+
+/* Sum of sizes of fields: TNF-flags, Type Length, Payload Length in long NDEF record. */
+#define NDEF_RECORD_BASE_LONG_SIZE (2 + NDEF_RECORD_PAYLOAD_LEN_LONG_SIZE)
+
+__STATIC_INLINE uint32_t record_header_size_calc(nfc_ndef_record_desc_t const * p_ndef_record_desc)
+{
+ uint32_t len = NDEF_RECORD_BASE_LONG_SIZE;
+
+ len += p_ndef_record_desc->id_length + p_ndef_record_desc->type_length;
+
+ if (p_ndef_record_desc->id_length > 0)
+ {
+ len++;
+ }
+
+ return len;
+}
+
+
+ret_code_t nfc_ndef_record_encode(nfc_ndef_record_desc_t const * p_ndef_record_desc,
+ nfc_ndef_record_location_t record_location,
+ uint8_t * p_record_buffer,
+ uint32_t * p_record_len)
+{
+ uint8_t * p_flags; // use as pointer to TNF + flags field
+ uint8_t * p_payload_len = NULL; // use as pointer to payload length field
+ uint32_t record_payload_len;
+
+ if (p_ndef_record_desc == NULL)
+ {
+ return NRF_ERROR_NULL;
+ }
+
+ // count record length without payload
+ uint32_t record_header_len = record_header_size_calc(p_ndef_record_desc);
+ uint32_t err_code = NRF_SUCCESS;
+
+ if (p_record_buffer != NULL)
+ {
+ /* verify location range */
+ if ((record_location & (~NDEF_RECORD_LOCATION_MASK)) != 0x00)
+ {
+ return NRF_ERROR_INVALID_PARAM;
+ }
+
+ /* verify if there is enough available memory */
+ if (record_header_len > *p_record_len)
+ {
+ return NRF_ERROR_NO_MEM;
+ }
+
+ p_flags = p_record_buffer;
+ p_record_buffer++;
+
+ // set location bits and clear other bits in 1st byte.
+ *p_flags = record_location;
+
+ *p_flags |= p_ndef_record_desc->tnf;
+
+ /* TYPE LENGTH */
+ *(p_record_buffer++) = p_ndef_record_desc->type_length;
+
+ // use always long record and remember payload len field memory offset.
+ p_payload_len = p_record_buffer;
+ p_record_buffer += NDEF_RECORD_PAYLOAD_LEN_LONG_SIZE;
+
+ /* ID LENGTH - option */
+ if (p_ndef_record_desc->id_length > 0)
+ {
+ *(p_record_buffer++) = p_ndef_record_desc->id_length;
+
+ /* IL flag */
+ *p_flags |= NDEF_RECORD_IL_MASK;
+ }
+
+ /* TYPE */
+ memcpy(p_record_buffer, p_ndef_record_desc->p_type, p_ndef_record_desc->type_length);
+ p_record_buffer += p_ndef_record_desc->type_length;
+
+ /* ID */
+ if (p_ndef_record_desc->id_length > 0)
+ {
+ memcpy(p_record_buffer, p_ndef_record_desc->p_id, p_ndef_record_desc->id_length);
+ p_record_buffer += p_ndef_record_desc->id_length;
+ }
+
+ // count how much memory is left in record buffer for payload field.
+ record_payload_len = (*p_record_len - record_header_len);
+ }
+
+ /* PAYLOAD */
+ if (p_ndef_record_desc->payload_constructor != NULL)
+ {
+ err_code =
+ p_ndef_record_desc->payload_constructor(p_ndef_record_desc->p_payload_descriptor,
+ p_record_buffer,
+ &record_payload_len);
+
+ if (err_code != NRF_SUCCESS)
+ {
+ return err_code;
+ }
+ }
+ else
+ {
+ return NRF_ERROR_NULL;
+ }
+
+ if (p_record_buffer != NULL)
+ {
+ /* PAYLOAD LENGTH */
+ (void) uint32_big_encode(record_payload_len, p_payload_len);
+ }
+
+ *p_record_len = record_header_len + record_payload_len;
+
+ return NRF_SUCCESS;
+}
+
+
+ret_code_t nfc_ndef_bin_payload_memcopy(nfc_ndef_bin_payload_desc_t * p_payload_descriptor,
+ uint8_t * p_buffer,
+ uint32_t * p_len)
+{
+
+ if (p_buffer != NULL)
+ {
+ if ( *p_len < p_payload_descriptor->payload_length)
+ {
+ return NRF_ERROR_NO_MEM;
+ }
+
+ memcpy(p_buffer,
+ p_payload_descriptor->p_payload,
+ p_payload_descriptor->payload_length);
+ }
+
+ *p_len = p_payload_descriptor->payload_length;
+
+ return NRF_SUCCESS;
+}
+
+#endif // NRF_MODULE_ENABLED(NFC_NDEF_RECORD)
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/ndef/generic/record/nfc_ndef_record.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/ndef/generic/record/nfc_ndef_record.h
new file mode 100644
index 0000000..069258c
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/ndef/generic/record/nfc_ndef_record.h
@@ -0,0 +1,311 @@
+/**
+ * Copyright (c) 2015 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#ifndef NFC_NDEF_RECORD_H__
+#define NFC_NDEF_RECORD_H__
+
+#include <stdint.h>
+#include <string.h>
+#include "compiler_abstraction.h"
+#include "sdk_errors.h"
+#include "nrf.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**@file
+ *
+ * @defgroup nfc_ndef_record Custom NDEF records
+ * @{
+ * @ingroup nfc_ndef_msg
+ *
+ * @brief Generation of NFC NDEF records for NFC messages.
+ *
+ */
+
+
+#define NDEF_RECORD_IL_MASK 0x08 ///< Mask of the ID field presence bit in the flags byte of an NDEF record.
+#define NDEF_RECORD_TNF_MASK 0x07 ///< Mask of the TNF value field in the first byte of an NDEF record.
+#define NDEF_RECORD_SR_MASK 0x10 ///< Mask of the SR flag. If set, this flag indicates that the PAYLOAD_LENGTH field has a size of 1 byte. Otherwise, PAYLOAD_LENGTH has 4 bytes.
+#define NDEF_RECORD_PAYLOAD_LEN_LONG_SIZE 4 ///< Size of the Payload Length field in a long NDEF record.
+#define NDEF_RECORD_PAYLOAD_LEN_SHORT_SIZE 1 ///< Size of the Payload Length field in a short NDEF record.
+#define NDEF_RECORD_ID_LEN_SIZE 1 ///< Size of the ID Length field in an NDEF record.
+
+
+/**
+ * @brief Payload constructor type.
+
+ * A payload constructor is a function for constructing the payload of an NDEF
+ * record.
+ *
+ * @param[in] p_payload_descriptor Pointer to the input data for the constructor.
+ * @param[out] p_buffer Pointer to the payload destination. If NULL, function will
+ * calculate the expected size of the record payload.
+ *
+ * @param[in,out] p_len Size of the available memory to write as input. Size of the generated
+ * record payload as output. The implementation must check if the payload
+ * will fit in the provided buffer. This must be checked by the caller function.
+ *
+ * @retval NRF_SUCCESS If the function completed successfully.
+ * @retval NRF_ERROR_xxx If an error occurred.
+ */
+typedef ret_code_t (* p_payload_constructor_t)(void * p_payload_descriptor,
+ uint8_t * p_buffer,
+ uint32_t * p_len);
+
+
+/**
+ * @brief Type Name Format (TNF) Field Values.
+ *
+ * Values to specify the TNF of a record.
+ */
+typedef enum
+{
+ TNF_EMPTY = 0x00, ///< The value indicates that there is no type or payload associated with this record.
+ TNF_WELL_KNOWN = 0x01, ///< NFC Forum well-known type [NFC RTD].
+ TNF_MEDIA_TYPE = 0x02, ///< Media-type as defined in RFC 2046 [RFC 2046].
+ TNF_ABSOLUTE_URI = 0x03, ///< Absolute URI as defined in RFC 3986 [RFC 3986].
+ TNF_EXTERNAL_TYPE = 0x04, ///< NFC Forum external type [NFC RTD].
+ TNF_UNKNOWN_TYPE = 0x05, ///< The value indicates that there is no type associated with this record.
+ TNF_UNCHANGED = 0x06, ///< The value is used for the record chunks used in chunked payload.
+ TNF_RESERVED = 0x07, ///< The value is reserved for future use.
+} nfc_ndef_record_tnf_t;
+
+
+/**
+ * @brief NDEF record descriptor.
+ */
+typedef struct
+{
+ nfc_ndef_record_tnf_t tnf; ///< Value of the Type Name Format (TNF) field.
+
+ uint8_t id_length; ///< Length of the ID field. If 0, a record format without ID field is assumed.
+ uint8_t const * p_id; ///< Pointer to the ID field data. Not relevant if id_length is 0.
+
+ uint8_t type_length; ///< Length of the type field.
+ uint8_t const * p_type; ///< Pointer to the type field data. Not relevant if type_length is 0.
+
+ p_payload_constructor_t payload_constructor; ///< Pointer to the payload constructor function.
+ void * p_payload_descriptor; ///< Pointer to the data for the payload constructor function.
+
+} nfc_ndef_record_desc_t;
+
+/**
+ * @brief Record position within the NDEF message.
+ *
+ * Values to specify the location of a record within the NDEF message.
+ */
+typedef enum
+{
+ NDEF_FIRST_RECORD = 0x80, ///< First record.
+ NDEF_MIDDLE_RECORD = 0x00, ///< Middle record.
+ NDEF_LAST_RECORD = 0x40, ///< Last record.
+ NDEF_LONE_RECORD = 0xC0 ///< Only one record in the message.
+} nfc_ndef_record_location_t;
+
+#define NDEF_RECORD_LOCATION_MASK (NDEF_LONE_RECORD) ///< Mask of the Record Location bits in the NDEF record's flags byte.
+
+/**
+ * @brief Binary data descriptor containing the payload for the record.
+ */
+typedef struct
+{
+ uint8_t const * p_payload; ///< Pointer to the buffer with the data.
+ uint32_t payload_length; ///< Length of data in bytes.
+} nfc_ndef_bin_payload_desc_t;
+
+/**
+ * @brief Macro for creating and initializing an NFC NDEF record descriptor for a generic record.
+ *
+ * This macro creates and initializes an instance of type @ref nfc_ndef_record_desc_t.
+ *
+ * Use the macro @ref NFC_NDEF_GENERIC_RECORD_DESC to access the NDEF record descriptor instance.
+ *
+ * @note The record descriptor is declared as automatic variable, which implies that
+ * the NDEF record encoding must be done in the same variable scope.
+ *
+ * @param[in] NAME Name of the created descriptor instance.
+ * @param[in] TNF Type Name Format (TNF) value for the record.
+ * @param[in] P_ID Pointer to the ID string.
+ * @param[in] ID_LEN Length of the ID string.
+ * @param[in] P_TYPE Pointer to the type string.
+ * @param[in] TYPE_LEN Length of the type string.
+ * @param[in] P_PAYLOAD_CONSTRUCTOR Pointer to the payload constructor function.
+ * The constructor must be of type @ref p_payload_constructor_t.
+ * @param[in] P_PAYLOAD_DESCRIPTOR Pointer to the data for the payload constructor.
+ */
+#define NFC_NDEF_GENERIC_RECORD_DESC_DEF(NAME, \
+ TNF, \
+ P_ID, \
+ ID_LEN, \
+ P_TYPE, \
+ TYPE_LEN, \
+ P_PAYLOAD_CONSTRUCTOR, \
+ P_PAYLOAD_DESCRIPTOR) \
+ nfc_ndef_record_desc_t NAME##_ndef_generic_record_desc = \
+ { \
+ .tnf = TNF, \
+ \
+ .id_length = ID_LEN, \
+ .p_id = P_ID, \
+ \
+ .type_length = TYPE_LEN, \
+ .p_type = P_TYPE, \
+ \
+ .payload_constructor = (p_payload_constructor_t)P_PAYLOAD_CONSTRUCTOR, \
+ .p_payload_descriptor = (void *) P_PAYLOAD_DESCRIPTOR \
+ }
+
+
+/** @brief Macro for accessing the NFC NDEF record descriptor instance
+ * that you created with @ref NFC_NDEF_GENERIC_RECORD_DESC_DEF.
+ */
+#define NFC_NDEF_GENERIC_RECORD_DESC(NAME) (NAME##_ndef_generic_record_desc)
+
+/**
+ * @brief Macro for creating and initializing an NFC NDEF record descriptor for a record with
+ * binary payload.
+ *
+ * This macro creates and initializes a static instance of type @ref nfc_ndef_record_desc_t and a binary data descriptor containing the payload data.
+ *
+ * Use the macro @ref NFC_NDEF_RECORD_BIN_DATA to access the NDEF record descriptor instance.
+ *
+ * @note The record descriptor is declared as automatic variable, which implies that
+ * the NDEF record encoding must be done in the same variable scope.
+ *
+ * @param[in] NAME Name of the created descriptor instance.
+ * @param[in] TNF Type Name Format (TNF) value for the record.
+ * @param[in] P_ID Pointer to the ID string.
+ * @param[in] ID_LEN Length of the ID string.
+ * @param[in] P_TYPE Pointer to the type string.
+ * @param[in] TYPE_LEN Length of the type string.
+ * @param[in] P_PAYLOAD Pointer to the payload data that will be copied to the payload field.
+ * @param[in] PAYLOAD_LEN Length of the payload.
+ */
+#define NFC_NDEF_RECORD_BIN_DATA_DEF(NAME, \
+ TNF, \
+ P_ID, ID_LEN, \
+ P_TYPE, \
+ TYPE_LEN, \
+ P_PAYLOAD, \
+ PAYLOAD_LEN) \
+ nfc_ndef_bin_payload_desc_t NAME##_nfc_ndef_bin_payload_desc = \
+ { \
+ .p_payload = P_PAYLOAD, \
+ .payload_length = PAYLOAD_LEN \
+ }; \
+ \
+ nfc_ndef_record_desc_t NAME##_nfc_ndef_bin_record_desc = \
+ { \
+ .tnf = TNF, \
+ \
+ .id_length = ID_LEN, \
+ .p_id = P_ID, \
+ \
+ .type_length = TYPE_LEN, \
+ .p_type = P_TYPE, \
+ \
+ .payload_constructor = (p_payload_constructor_t) nfc_ndef_bin_payload_memcopy, \
+ .p_payload_descriptor = (void *) &NAME##_nfc_ndef_bin_payload_desc \
+ }
+
+
+/** @brief Macro for accessing the NFC NDEF record descriptor instance
+ * that you created with @ref NFC_NDEF_RECORD_BIN_DATA_DEF.
+ */
+#define NFC_NDEF_RECORD_BIN_DATA(NAME) (NAME##_nfc_ndef_bin_record_desc)
+
+/** @brief Macro for accessing the binary data descriptor that contains
+ * the payload of the record that you created with @ref NFC_NDEF_RECORD_BIN_DATA_DEF.
+ */
+#define NFC_NDEF_BIN_PAYLOAD_DESC(NAME) (NAME##_nfc_ndef_bin_payload_desc)
+
+/**
+ * @brief Function for encoding an NDEF record.
+ *
+ * This function encodes an NDEF record according to the provided record descriptor.
+ *
+ * @param[in] p_ndef_record_desc Pointer to the record descriptor.
+ * @param[in] record_location Location of the record within the NDEF message.
+ * @param[out] p_record_buffer Pointer to the record destination. If NULL, function will
+ * calculate the expected size of the record.
+ * @param[in,out] p_record_len Size of the available memory for the record as input. Size of the generated
+ * record as output.
+ *
+ * @retval NRF_SUCCESS If the record was encoded successfully.
+ * @retval NRF_ERROR_NO_MEM If the predicted record size is bigger than the provided buffer space.
+ * @retval NRF_ERROR_INVALID_PARAM If the location of the record is erroneous.
+ * @retval Other Other codes might be returned depending on the NDEF record payload constructor implementation.
+ */
+ret_code_t nfc_ndef_record_encode(nfc_ndef_record_desc_t const * p_ndef_record_desc,
+ nfc_ndef_record_location_t record_location,
+ uint8_t * p_record_buffer,
+ uint32_t * p_record_len);
+
+/**
+ * @brief Function for constructing the payload for an NFC NDEF record from binary data.
+ *
+ * This function copies data from a binary buffer to the payload field of the NFC NDEF record.
+ *
+ * @param[in] p_payload_descriptor Pointer to the descriptor of the binary data location and size.
+ *
+ * @param[out] p_buffer Pointer to the payload destination. If NULL, function will
+ * calculate the expected size of the record payload.
+ * @param[in,out] p_len Size of the available memory for the payload as input. Size of the copied payload
+ * as output.
+ *
+ * @retval NRF_SUCCESS If the function completed successfully.
+ * @retval NRF_ERROR_NO_MEM If the payload size is bigger than the provided buffer space.
+ */
+ret_code_t nfc_ndef_bin_payload_memcopy(nfc_ndef_bin_payload_desc_t * p_payload_descriptor,
+ uint8_t * p_buffer,
+ uint32_t * p_len);
+
+/**
+ * @}
+ */
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // NFC_NDEF_RECORD_H__
+
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/ndef/launchapp/nfc_launchapp_msg.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/ndef/launchapp/nfc_launchapp_msg.c
new file mode 100644
index 0000000..6ec240f
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/ndef/launchapp/nfc_launchapp_msg.c
@@ -0,0 +1,97 @@
+/**
+ * Copyright (c) 2015 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#include "sdk_common.h"
+#if NRF_MODULE_ENABLED(NFC_NDEF_LAUNCHAPP_MSG)
+
+#include <stdint.h>
+#include <string.h>
+#include "nfc_launchapp_rec.h"
+#include "nfc_launchapp_msg.h"
+#include "nrf_error.h"
+#include "sdk_macros.h"
+
+ret_code_t nfc_launchapp_msg_encode(uint8_t const * p_android_package_name,
+ uint8_t android_package_name_length,
+ uint8_t const * p_win_app_id,
+ uint8_t win_app_id_length,
+ uint8_t * p_buf,
+ uint32_t * p_len)
+{
+ ret_code_t err_code;
+
+ /* Create NFC NDEF message description, capacity - 2 records */
+ NFC_NDEF_MSG_DEF(nfc_launchapp_msg, 2);
+
+ /* Create NFC NDEF Windows Phone LaunchApp Record description */
+ NFC_NDEF_WINDOWS_LAUNCHAPP_RECORD_DESC_DEF(nfc_win_launchapp_rec,
+ p_win_app_id,
+ win_app_id_length);
+
+ /* Create NFC NDEF Android Application Record description */
+ NFC_NDEF_ANDROID_LAUNCHAPP_RECORD_DESC_DEF(nfc_and_launchapp_rec,
+ p_android_package_name,
+ android_package_name_length);
+
+ if (p_win_app_id != NULL)
+ {
+ /* Add Windows Phone LaunchApp Record as first record to message */
+ err_code = nfc_ndef_msg_record_add(&NFC_NDEF_MSG(nfc_launchapp_msg),
+ &NFC_NDEF_WINDOWS_LAUNCHAPP_RECORD_DESC(nfc_win_launchapp_rec));
+ VERIFY_SUCCESS(err_code);
+ }
+ if (p_android_package_name != NULL)
+ {
+ /* Add Android Application Record as second record to message */
+ err_code = nfc_ndef_msg_record_add(&NFC_NDEF_MSG(nfc_launchapp_msg),
+ &NFC_NDEF_ANDROID_LAUNCHAPP_RECORD_DESC(nfc_and_launchapp_rec));
+ VERIFY_SUCCESS(err_code);
+ }
+ VERIFY_FALSE(NFC_NDEF_MSG(nfc_launchapp_msg).record_count == 0,
+ NRF_ERROR_INVALID_PARAM);
+
+ /* Encode whole message into buffer */
+ err_code = nfc_ndef_msg_encode(&NFC_NDEF_MSG(nfc_launchapp_msg),
+ p_buf,
+ p_len);
+
+ return err_code;
+}
+
+#endif // NRF_MODULE_ENABLED(NFC_NDEF_LAUNCHAPP_MSG)
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/ndef/launchapp/nfc_launchapp_msg.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/ndef/launchapp/nfc_launchapp_msg.h
new file mode 100644
index 0000000..90cf9ed
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/ndef/launchapp/nfc_launchapp_msg.h
@@ -0,0 +1,100 @@
+/**
+ * Copyright (c) 2015 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#ifndef NFC_LAUNCHAPP_MSG_H__
+#define NFC_LAUNCHAPP_MSG_H__
+
+/** @file
+ *
+ * @defgroup nfc_launchapp_msg Launch app messages
+ * @{
+ * @ingroup nfc_ndef_messages
+ *
+ * @brief Generation of NFC NDEF messages that can be used to launch apps.
+ *
+ */
+
+#include <stdint.h>
+#include "nfc_ndef_msg.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+/** @brief Function for encoding an NFC NDEF launch app message.
+ *
+ * This function encodes an NFC NDEF message into a buffer.
+ *
+ * @param[in] p_android_package_name Pointer to the Android package name string.
+ * If NULL, the Android Application Record will be skipped.
+ * @param[in] android_package_name_length Length of the Android package name.
+ * @param[in] p_win_app_id Pointer to the Windows application ID string (GUID).
+ * If NULL, the Windows LaunchApp record will be skipped.
+ * @param[in] win_app_id_length Length of the Windows application ID.
+ * @param[out] p_buf Pointer to the buffer for the message.
+ * @param[in,out] p_len Size of the available memory for the message as input.
+ * Size of the generated message as output.
+ *
+ * @retval NRF_SUCCESS If the description was successfully created.
+ * @retval NRF_ERROR_INVALID_PARAM If both p_android_package_name and windows_application_id were
+ * invalid (equal to NULL).
+ * @retval NRF_ERROR_NO_MEM If the predicted message size is bigger than the provided
+ * buffer space.
+ * @retval Other Other codes might be returned depending on
+ * the function @ref nfc_ndef_msg_encode
+ */
+ret_code_t nfc_launchapp_msg_encode(uint8_t const * p_android_package_name,
+ uint8_t android_package_name_length,
+ uint8_t const * p_win_app_id,
+ uint8_t win_app_id_length,
+ uint8_t * p_buf,
+ uint32_t * p_len);
+
+/**
+ * @}
+ */
+
+#ifdef __cplusplus
+}
+#endif
+
+ #endif // NFC_LAUNCHAPP_MSG_H__
+
+
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/ndef/launchapp/nfc_launchapp_rec.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/ndef/launchapp/nfc_launchapp_rec.c
new file mode 100644
index 0000000..8e586b3
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/ndef/launchapp/nfc_launchapp_rec.c
@@ -0,0 +1,107 @@
+/**
+ * Copyright (c) 2015 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#include "sdk_common.h"
+#if NRF_MODULE_ENABLED(NFC_NDEF_LAUNCHAPP_REC)
+
+#include "nfc_launchapp_rec.h"
+#include <string.h>
+#include "nrf_error.h"
+#include "app_util.h"
+#include "nfc_ndef_record.h"
+
+/* Record Payload Type for NFC NDEF Android Application Record */
+const uint8_t ndef_android_launchapp_rec_type[] =
+{
+ 'a', 'n', 'd', 'r', 'o', 'i', 'd', '.', 'c','o', 'm', ':', 'p', 'k', 'g'
+};
+
+/* Record Payload Type for NFC NDEF Windows LaunchApp record */
+const uint8_t ndef_windows_launchapp_rec_type[] =
+{
+ 'w', 'i', 'n', 'd', 'o', 'w', 's', '.', 'c', 'o', 'm', '/', 'L', 'a', 'u',
+ 'n', 'c', 'h', 'A', 'p', 'p'
+};
+/* Platform type used in Record Payload of NFC NDEF Windows LaunchApp record */
+const uint8_t ndef_windows_launchapp_plat_type[] =
+{
+ 'W', 'i', 'n', 'd', 'o', 'w', 's', 'P', 'h', 'o', 'n', 'e'
+};
+
+#define WIN_LAUNCHAPP_EMPTY_PARAMETER 0x20 ///< The empty parameter value for the Windows LaunchApp Record.
+
+ret_code_t nfc_win_launchapp_payload_constructor(win_launchapp_payload_desc_t * p_input,
+ uint8_t * p_buff,
+ uint32_t * p_len)
+{
+
+ win_launchapp_payload_desc_t * launch_desc = (win_launchapp_payload_desc_t *) p_input;
+
+ uint32_t temp_len = (uint32_t)launch_desc->platform_length + launch_desc->app_id_length + 7;
+
+ if (p_buff != NULL)
+ {
+ if (temp_len > *p_len)
+ {
+ return NRF_ERROR_NO_MEM;
+ }
+
+ *p_buff++ = 0x00; // platform count: 1
+ *p_buff++ = 0x01; // -||-
+
+ *p_buff++ = launch_desc->platform_length;
+ memcpy(p_buff, launch_desc->platform, launch_desc->platform_length); // platform
+ p_buff += launch_desc->platform_length;
+
+
+ *p_buff++ = launch_desc->app_id_length;
+ memcpy(p_buff, launch_desc->app_id, launch_desc->app_id_length);
+ p_buff += launch_desc->app_id_length;
+
+ *p_buff++ = 0x00; // parameters length 1B
+ *p_buff++ = 0x01; // -||-
+ *p_buff++ = WIN_LAUNCHAPP_EMPTY_PARAMETER; // empty parameter
+ }
+
+ *p_len = temp_len;
+
+ return NRF_SUCCESS;
+}
+
+#endif // NRF_MODULE_ENABLED(NFC_NDEF_LAUNCHAPP_REC)
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/ndef/launchapp/nfc_launchapp_rec.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/ndef/launchapp/nfc_launchapp_rec.h
new file mode 100644
index 0000000..a923e69
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/ndef/launchapp/nfc_launchapp_rec.h
@@ -0,0 +1,205 @@
+/**
+ * Copyright (c) 2015 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#ifndef NFC_LAUNCHAPP_REC_H__
+#define NFC_LAUNCHAPP_REC_H__
+
+/**@file
+ *
+ * @defgroup nfc_launchapp_rec Launch app records
+ * @{
+ * @ingroup nfc_launchapp_msg
+ *
+ * @brief Generation of NFC NDEF record descriptions that launch apps.
+ *
+ */
+
+#include <stdint.h>
+#include "nfc_ndef_record.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @brief Size of the type field of the Android Application Record, defined in the file
+ * @c nfc_launchapp_rec.c. It is used in the @ref NFC_NDEF_ANDROID_LAUNCHAPP_RECORD_DESC macro.
+ */
+#define NFC_ANDROID_REC_TYPE_LENGTH 15
+
+/**
+ * @brief Size of the type field of the Windows LaunchApp Record, defined in the file
+ * @c nfc_launchapp_rec.c. It is used in the @ref NFC_NDEF_WINDOWS_LAUNCHAPP_RECORD_DESC_DEF macro.
+ */
+#define NFC_WINDOWS_REC_TYPE_LENGTH 21
+
+/**
+ * @brief Size of the platform type, which is used to encode payload field of the Windows LaunchApp
+ * Record, defined in the file @c nfc_launchapp_rec.c. It is used in the
+ * @ref NFC_NDEF_WINDOWS_LAUNCHAPP_RECORD_DESC_DEF macro.
+ */
+#define NFC_WINDOWS_PLAT_TYPE_LENGTH 12
+
+/**
+ * @brief Type of description of payload of Windows LaunchApp record.
+ */
+typedef struct
+{
+ const uint8_t * platform;
+ uint8_t platform_length;
+ const uint8_t * app_id;
+ uint8_t app_id_length;
+} win_launchapp_payload_desc_t;
+
+/**
+ * @brief External reference to the type field of the NFC NDEF Android Application Record, defined in the
+ * file @c nfc_launchapp_rec.c. It is used in the @ref NFC_NDEF_ANDROID_LAUNCHAPP_RECORD_DESC_DEF macro.
+ */
+extern const uint8_t ndef_android_launchapp_rec_type[NFC_ANDROID_REC_TYPE_LENGTH];
+
+/**
+ * @brief External reference to the type field of the NFC NDEF Windows LaunchApp record, defined in the
+ * file @c nfc_launchapp_rec.c. It is used in the @ref NFC_NDEF_WINDOWS_LAUNCHAPP_RECORD_DESC_DEF macro.
+ */
+extern const uint8_t ndef_windows_launchapp_rec_type[NFC_WINDOWS_REC_TYPE_LENGTH];
+
+/**
+ * @brief External reference to the platform type, which is used to encode payload field of the NFC NDEF
+ * Windows LaunchApp record. This constant is defined in the file @c nfc_launchapp_rec.c and is used in
+ * the macro @ref NFC_NDEF_WINDOWS_LAUNCHAPP_RECORD_DESC_DEF.
+ */
+extern const uint8_t ndef_windows_launchapp_plat_type[NFC_WINDOWS_PLAT_TYPE_LENGTH];
+
+/**
+ * @brief Function for constructing the payload for a Windows LaunchApp record.
+ *
+ * This function encodes the payload according to the LaunchApp record definition. It implements an API
+ * compatible with p_payload_constructor_t.
+ *
+ * @param[in] p_input Pointer to the description of the payload.
+ * @param[out] p_buff Pointer to payload destination. If NULL, function will
+ * calculate the expected size of the LaunchApp record payload.
+ *
+ * @param[in,out] p_len Size of available memory to write as input. Size of generated
+ * payload as output.
+ *
+ * @retval NRF_SUCCESS Always success.
+ */
+ret_code_t nfc_win_launchapp_payload_constructor(win_launchapp_payload_desc_t * p_input,
+ uint8_t * p_buff,
+ uint32_t * p_len);
+
+/** @brief Macro for generating a description of an NFC NDEF Android Application Record (AAR).
+ *
+ * This macro declares and initializes an instance of an NFC NDEF record description
+ * of an Android Application Record (AAR).
+ *
+ * @note The record descriptor is declared as automatic variable, which implies that
+ * the NDEF message encoding (see @ref nfc_launchapp_msg_encode) must be done
+ * in the same variable scope.
+ *
+ * @param[in] NAME Name for accessing record descriptor.
+ * @param[in] P_PACKAGE_NAME Pointer to the Android package name string.
+ * @param[in] PACKAGE_NAME_LENGTH Length of the Android package name.
+ */
+#define NFC_NDEF_ANDROID_LAUNCHAPP_RECORD_DESC_DEF(NAME, \
+ P_PACKAGE_NAME, \
+ PACKAGE_NAME_LENGTH) \
+ NFC_NDEF_RECORD_BIN_DATA_DEF(NAME, \
+ TNF_EXTERNAL_TYPE, \
+ NULL, \
+ 0, \
+ ndef_android_launchapp_rec_type, \
+ sizeof(ndef_android_launchapp_rec_type), \
+ (P_PACKAGE_NAME), \
+ (PACKAGE_NAME_LENGTH))
+
+/**
+ * @brief Macro for accessing the NFC NDEF Android Application Record descriptor
+ * instance that was created with @ref NFC_NDEF_ANDROID_LAUNCHAPP_RECORD_DESC_DEF.
+ */
+#define NFC_NDEF_ANDROID_LAUNCHAPP_RECORD_DESC(NAME) NFC_NDEF_RECORD_BIN_DATA(NAME)
+
+/** @brief Macro for generating a description of an NFC NDEF Windows LaunchApp record.
+ *
+ * This macro declares and initializes an instance of an NFC NDEF record description
+ * of a Windows LaunchApp record.
+ *
+ * @note The record descriptor is declared as automatic variable, which implies that
+ * the NDEF message encoding (see @ref nfc_launchapp_msg_encode) must be done
+ * in the same variable scope.
+ *
+ * @param[in] NAME Name for accessing record descriptor.
+ * @param[in] P_WIN_APP_ID Pointer to the Windows application ID string (GUID).
+ * @param[in] WIN_APP_ID_LENGTH Length of the Windows application ID.
+ *
+ * @return Pointer to the description of the record.
+ */
+#define NFC_NDEF_WINDOWS_LAUNCHAPP_RECORD_DESC_DEF(NAME, \
+ P_WIN_APP_ID, \
+ WIN_APP_ID_LENGTH) \
+ win_launchapp_payload_desc_t NAME##_ndef_win_launchapp_rec_payload_desc = \
+ { \
+ .platform = ndef_windows_launchapp_plat_type, \
+ .platform_length = sizeof(ndef_windows_launchapp_plat_type), \
+ .app_id = (P_WIN_APP_ID), \
+ .app_id_length = WIN_APP_ID_LENGTH \
+ }; \
+ NFC_NDEF_GENERIC_RECORD_DESC_DEF(NAME, \
+ TNF_ABSOLUTE_URI, \
+ NULL, \
+ 0, \
+ ndef_windows_launchapp_rec_type, \
+ sizeof(ndef_windows_launchapp_rec_type), \
+ nfc_win_launchapp_payload_constructor, \
+ &NAME##_ndef_win_launchapp_rec_payload_desc) \
+
+/**
+ * @brief Macro for accessing the NFC NDEF Windows LaunchApp Record descriptor
+ * instance that was created with @ref NFC_NDEF_WINDOWS_LAUNCHAPP_RECORD_DESC_DEF.
+ */
+#define NFC_NDEF_WINDOWS_LAUNCHAPP_RECORD_DESC(NAME) NFC_NDEF_GENERIC_RECORD_DESC(NAME)
+
+/** @} */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // NFC_LAUNCHAPP_REC
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/ndef/parser/message/nfc_ndef_msg_parser.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/ndef/parser/message/nfc_ndef_msg_parser.c
new file mode 100644
index 0000000..f4ee3e2
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/ndef/parser/message/nfc_ndef_msg_parser.c
@@ -0,0 +1,94 @@
+/**
+ * Copyright (c) 2016 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#include "sdk_common.h"
+#if NRF_MODULE_ENABLED(NFC_NDEF_MSG_PARSER)
+
+#include "nfc_ndef_msg_parser.h"
+#include "nrf_delay.h"
+
+#define NRF_LOG_MODULE_NAME nfc_ndef_msg_parser
+#if NFC_NDEF_MSG_PARSER_LOG_ENABLED
+#define NRF_LOG_LEVEL NFC_NDEF_MSG_PARSER_LOG_LEVEL
+#define NRF_LOG_INFO_COLOR NFC_NDEF_MSG_PARSER_INFO_COLOR
+#include "nrf_log.h"
+NRF_LOG_MODULE_REGISTER();
+#else // NFC_NDEF_MSG_PARSER_LOG_ENABLED
+#define NRF_LOG_LEVEL 0
+#include "nrf_log.h"
+#endif // NFC_NDEF_MSG_PARSER_LOG_ENABLED
+
+ret_code_t ndef_msg_parser(uint8_t * const p_result_buf,
+ uint32_t * const p_result_buf_len,
+ uint8_t * const p_nfc_data,
+ uint32_t * const p_nfc_data_len)
+{
+ ret_code_t ret_code;
+ nfc_ndef_parser_memo_desc_t parser_memory_helper;
+
+ ret_code = ndef_parser_memo_resolve(p_result_buf,
+ p_result_buf_len,
+ &parser_memory_helper);
+
+ if (ret_code != NRF_SUCCESS)
+ {
+ return ret_code;
+ }
+
+ ret_code = internal_ndef_msg_parser(&parser_memory_helper,
+ p_nfc_data,
+ p_nfc_data_len);
+
+ return ret_code;
+}
+
+
+void ndef_msg_printout(nfc_ndef_msg_desc_t * const p_msg_desc)
+{
+ uint32_t i;
+
+ NRF_LOG_INFO("NDEF message contains %d record(s)", p_msg_desc->record_count);
+
+ for (i = 0; i < p_msg_desc->record_count; i++)
+ {
+ ndef_record_printout(i, p_msg_desc->pp_record[i]);
+ }
+}
+
+#endif // NRF_MODULE_ENABLED(NFC_NDEF_MSG_PARSER)
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/ndef/parser/message/nfc_ndef_msg_parser.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/ndef/parser/message/nfc_ndef_msg_parser.h
new file mode 100644
index 0000000..dde1653
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/ndef/parser/message/nfc_ndef_msg_parser.h
@@ -0,0 +1,123 @@
+/**
+ * Copyright (c) 2016 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#ifndef NFC_NDEF_MSG_PARSER_H__
+#define NFC_NDEF_MSG_PARSER_H__
+
+/**@file
+ *
+ * @defgroup nfc_ndef_parser NDEF message parser
+ * @{
+ * @ingroup nfc_modules
+ *
+ * @brief Parser for NFC NDEF messages and records.
+ *
+ * @defgroup nfc_ndef_msg_parser Parser for NDEF messages
+ * @{
+ * @ingroup nfc_ndef_parser
+ *
+ * @brief Parser for NFC NDEF messages.
+ *
+ */
+
+#include <stdint.h>
+#include "nfc_ndef_msg_parser_local.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @brief Macro for calculating the memory size required for holding the
+ * description of a message that consists of a certain number of NDEF records.
+ *
+ * @param[in] max_count_of_records Maximum number of records to hold.
+ */
+#define NFC_NDEF_PARSER_REQIRED_MEMO_SIZE_CALC(max_count_of_records) \
+ ((uint32_t)(max_count_of_records) <= 1) ? \
+ (sizeof(parsed_ndef_msg_1_t) * (uint32_t)(max_count_of_records)) : \
+ (sizeof(parsed_ndef_msg_1_t) + ((NFC_PARSER_M_DELTA) *((uint32_t)(max_count_of_records) - 1)))
+
+/**
+ * @brief Function for parsing NFC NDEF messages.
+ *
+ * This function parses NDEF messages using NDEF binary record descriptors.
+ *
+ * @param[out] p_result_buf Pointer to the buffer that will be used to hold
+ * the NDEF message descriptor. After parsing is completed successfully, the first address
+ * in the buffer is filled by the NDEF message descriptor
+ * (@ref nfc_ndef_msg_desc_t), which provides a full description of
+ * the parsed NDEF message.
+ * @param[in,out] p_result_buf_len As input: size of the buffer specified by @p p_result_buf.
+ * As output: size of the reserved (used) part of the buffer specified by
+ * @p p_result_buf.
+ * @param[in] p_nfc_data Pointer to the data to be parsed.
+ * @param[in,out] p_nfc_data_len As input: size of the NFC data in the @p p_nfc_data buffer. As output: size of the parsed message.
+ *
+ * @retval NRF_SUCCESS If the function completed successfully.
+ * @retval NRF_ERROR_NO_MEM If the provided buffer is too small to hold a one-record message or
+ * the buffer is too small to hold the actual result of the parsing.
+ * @retval NRF_ERROR_INVALID_LENGTH If the expected message length is bigger than the amount of the provided input data.
+ * @retval NRF_ERROR_INVALID_DATA If the message is not a valid NDEF message.
+ */
+ret_code_t ndef_msg_parser(uint8_t * const p_result_buf,
+ uint32_t * const p_result_buf_len,
+ uint8_t * const p_nfc_data,
+ uint32_t * const p_nfc_data_len);
+
+/**
+ * @brief Function for printing the parsed contents of an NDEF message.
+ *
+ * @param[in] p_msg_desc Pointer to the descriptor of the message that should be printed.
+ */
+void ndef_msg_printout(nfc_ndef_msg_desc_t * const p_msg_desc);
+
+/**
+ * @}
+ * @}
+ */
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // NFC_NDEF_MSG_PARSER_H__
+
+
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/ndef/parser/message/nfc_ndef_msg_parser_local.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/ndef/parser/message/nfc_ndef_msg_parser_local.c
new file mode 100644
index 0000000..68c99e3
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/ndef/parser/message/nfc_ndef_msg_parser_local.c
@@ -0,0 +1,163 @@
+/**
+ * Copyright (c) 2016 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#include "sdk_common.h"
+#if NRF_MODULE_ENABLED(NFC_NDEF_MSG_PARSER)
+
+#include "nfc_ndef_msg_parser_local.h"
+
+ret_code_t internal_ndef_msg_parser(nfc_ndef_parser_memo_desc_t * const p_parser_memo_desc,
+ uint8_t const * p_nfc_data,
+ uint32_t * const p_nfc_data_len)
+{
+ nfc_ndef_record_location_t record_location;
+
+ ret_code_t ret_code;
+
+ uint32_t nfc_data_left = *p_nfc_data_len;
+ uint32_t temp_nfc_data_len = 0;
+
+ // want to modify -> use local copy
+ nfc_ndef_bin_payload_desc_t * p_bin_pay_desc = p_parser_memo_desc->p_bin_pay_desc;
+ nfc_ndef_record_desc_t * p_rec_desc = p_parser_memo_desc->p_rec_desc;
+
+
+ while (nfc_data_left > 0)
+ {
+ temp_nfc_data_len = nfc_data_left;
+
+ ret_code = ndef_record_parser(p_bin_pay_desc,
+ p_rec_desc,
+ &record_location,
+ p_nfc_data,
+ &temp_nfc_data_len);
+
+ if (ret_code != NRF_SUCCESS)
+ {
+ return ret_code;
+ }
+
+ // verify the records location flags
+ if (p_parser_memo_desc->p_msg_desc->record_count == 0)
+ {
+ if ((record_location != NDEF_FIRST_RECORD) && (record_location != NDEF_LONE_RECORD))
+ {
+ return NRF_ERROR_INVALID_DATA;
+ }
+ }
+ else
+ {
+ if ((record_location != NDEF_MIDDLE_RECORD) && (record_location != NDEF_LAST_RECORD))
+ {
+ return NRF_ERROR_INVALID_DATA;
+ }
+ }
+
+ ret_code = nfc_ndef_msg_record_add(p_parser_memo_desc->p_msg_desc, p_rec_desc);
+
+ if (ret_code != NRF_SUCCESS)
+ {
+ return ret_code;
+ }
+
+ nfc_data_left -= temp_nfc_data_len;
+
+ if ((record_location == NDEF_LAST_RECORD) || (record_location == NDEF_LONE_RECORD))
+ {
+ *p_nfc_data_len = *p_nfc_data_len - nfc_data_left;
+ return NRF_SUCCESS;
+ }
+ else
+ {
+ if (p_parser_memo_desc->p_msg_desc->record_count ==
+ p_parser_memo_desc->p_msg_desc->max_record_count)
+ {
+ return NRF_ERROR_NO_MEM;
+ }
+
+ p_nfc_data += temp_nfc_data_len;
+ p_bin_pay_desc++;
+ p_rec_desc++;
+ }
+ }
+
+ return NRF_ERROR_INVALID_DATA;
+
+}
+
+
+ret_code_t ndef_parser_memo_resolve(uint8_t * const p_result_buf,
+ uint32_t * const p_result_buf_len,
+ nfc_ndef_parser_memo_desc_t * const p_parser_memo_desc)
+{
+
+ uint32_t max_rec_num;
+ uint32_t memory_last;
+ uint8_t * p_end;
+ nfc_ndef_record_desc_t * * pp_record_desc_array;
+
+ if (*p_result_buf_len < sizeof(parsed_ndef_msg_1_t))
+ {
+ return NRF_ERROR_NO_MEM;
+ }
+
+ memory_last = (*p_result_buf_len) - sizeof(parsed_ndef_msg_1_t);
+ max_rec_num = (memory_last / (NFC_PARSER_M_DELTA)) + 1;
+
+ p_parser_memo_desc->p_msg_desc = (nfc_ndef_msg_desc_t *) p_result_buf;
+ pp_record_desc_array =
+ (nfc_ndef_record_desc_t * *) &p_parser_memo_desc->p_msg_desc[1];
+ p_parser_memo_desc->p_bin_pay_desc =
+ (nfc_ndef_bin_payload_desc_t *) &pp_record_desc_array[max_rec_num];
+ p_parser_memo_desc->p_rec_desc =
+ (nfc_ndef_record_desc_t *) &p_parser_memo_desc->p_bin_pay_desc[max_rec_num];
+
+ // initialize message description
+ p_parser_memo_desc->p_msg_desc->pp_record = pp_record_desc_array;
+ p_parser_memo_desc->p_msg_desc->max_record_count = max_rec_num;
+ p_parser_memo_desc->p_msg_desc->record_count = 0;
+
+ p_end = (uint8_t *) &p_parser_memo_desc->p_rec_desc[max_rec_num];
+
+ *p_result_buf_len = p_end - p_result_buf;
+
+ return NRF_SUCCESS;
+}
+
+#endif // NRF_MODULE_ENABLED(NFC_NDEF_MSG_PARSER)
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/ndef/parser/message/nfc_ndef_msg_parser_local.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/ndef/parser/message/nfc_ndef_msg_parser_local.h
new file mode 100644
index 0000000..745979c
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/ndef/parser/message/nfc_ndef_msg_parser_local.h
@@ -0,0 +1,166 @@
+/**
+ * Copyright (c) 2016 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#ifndef NFC_NDEF_MSG_PARSER_LOCAL_H__
+#define NFC_NDEF_MSG_PARSER_LOCAL_H__
+
+/**@file
+ *
+ * @defgroup nfc_ndef_msg_parser_local NDEF message parser (internal)
+ * @{
+ * @ingroup nfc_ndef_msg_parser
+ *
+ * @brief Internal part of the parser for NFC NDEF messages.
+ *
+ */
+
+#include <stdint.h>
+#include "nfc_ndef_msg.h"
+#include "nfc_ndef_record_parser.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @brief Type for holding descriptors that are used by the NDEF parser.
+ */
+typedef struct
+{
+ nfc_ndef_msg_desc_t * p_msg_desc; ///< Pointer to the message descriptor.
+ nfc_ndef_bin_payload_desc_t * p_bin_pay_desc; ///< Pointer to the array of binary payload descriptors.
+ nfc_ndef_record_desc_t * p_rec_desc; ///< Pointer to the array of record descriptors.
+} nfc_ndef_parser_memo_desc_t;
+
+/**
+ * @brief Memory allocated for a one-record message.
+ */
+typedef struct
+{
+ nfc_ndef_msg_desc_t msg_desc;
+ nfc_ndef_record_desc_t * p_record_desc_array[1];
+ nfc_ndef_bin_payload_desc_t bin_pay_desc[1];
+ nfc_ndef_record_desc_t rec_desc[1];
+} parsed_ndef_msg_1_t;
+
+/**
+ * @brief Memory allocated for a two-record message.
+ */
+typedef struct
+{
+ nfc_ndef_msg_desc_t msg_desc;
+ nfc_ndef_record_desc_t * p_record_desc_array[2];
+ nfc_ndef_bin_payload_desc_t bin_pay_desc[2];
+ nfc_ndef_record_desc_t rec_desc[2];
+} parsed_ndef_msg_2_t;
+
+/**
+ * @brief Amount of memory that is required per record in addition to the memory allocated for the message descriptor.
+ */
+#define NFC_PARSER_M_DELTA (sizeof(parsed_ndef_msg_2_t) - sizeof(parsed_ndef_msg_1_t))
+
+
+/**
+ * @brief Function for resolving data instances in the provided buffer according
+ * to requirements of the function @ref internal_ndef_msg_parser.
+ *
+ * This internal function distributes the provided memory between certain data instances that are required
+ * by @ref internal_ndef_msg_parser.
+ *
+ * This function should not be used directly.
+ *
+ * @param[in] p_result_buf Pointer to the buffer that will be used to allocate
+ * data instances.
+ * @param[in,out] p_result_buf_len As input: size of the buffer specified by @p p_result_buf.
+ * As output: size of the reserved (used) part of the buffer specified by
+ * @p p_result_buf.
+ * @param[out] p_parser_memo_desc Pointer to the structure for holding descriptors of the allocated data
+ * instances.
+ *
+ * @retval NRF_SUCCESS If the function completed successfully.
+ * @retval NRF_ERROR_NO_MEM If the provided buffer is too small to hold a one-record message.
+ */
+ret_code_t ndef_parser_memo_resolve(uint8_t * const p_result_buf,
+ uint32_t * const p_result_buf_len,
+ nfc_ndef_parser_memo_desc_t * const p_parser_memo_desc);
+
+
+/**
+ * @brief Function for parsing NFC NDEF messages.
+ *
+ * This internal function parses NDEF messages into certain data instances.
+ *
+ * This function should not be used directly.
+ *
+ * @param[in,out] p_parser_memo_desc Pointer to the structure that holds descriptors of the allocated data
+ * instances for the parser. This structure contains the following fields: @n
+ * .p_msg_desc Pointer to the message descriptor that will
+ * be filled with parsed data. @n
+ * .p_bin_pay_desc Pointer to the array of binary payload
+ * descriptors that will be filled with parsed
+ * data. @n
+ * .p_rec_desc Pointer to the array of record descriptors
+ * that will be filled with parsed data. @n
+ * The arrays specified by @p .p_bin_pay_desc and @p .p_rec_desc must not
+ * contain more elements than the message descriptor
+ * specified by \p .p_msg_desc can hold.
+ *
+ * @param[in] p_nfc_data Pointer to the data to be parsed.
+ * @param[in,out] p_nfc_data_len As input: size of the NFC data in the @p p_nfc_data buffer.
+ * As output: size of the parsed message.
+ *
+ * @retval NRF_SUCCESS If the function completed successfully.
+ * @retval NRF_ERROR_INVALID_LENGTH If the expected message length is bigger than the amount of provided input data.
+ * @retval NRF_ERROR_INVALID_DATA If the message is not a valid NDEF message.
+ * @retval NRF_ERROR_NO_MEM If the provided memory resources are too small to hold the parsing result.
+ */
+ret_code_t internal_ndef_msg_parser(nfc_ndef_parser_memo_desc_t * const p_parser_memo_desc,
+ uint8_t const * p_nfc_data,
+ uint32_t * const p_nfc_data_len);
+
+/**
+ * @}
+ */
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // NFC_NDEF_MSG_PARSER_LOCAL_H__
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/ndef/parser/record/nfc_ndef_record_parser.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/ndef/parser/record/nfc_ndef_record_parser.c
new file mode 100644
index 0000000..30376da
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/ndef/parser/record/nfc_ndef_record_parser.c
@@ -0,0 +1,219 @@
+/**
+ * Copyright (c) 2016 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#include "sdk_common.h"
+#if NRF_MODULE_ENABLED(NFC_NDEF_RECORD_PARSER)
+
+#include <stdint.h>
+#include <stdbool.h>
+#include "nfc_ndef_record_parser.h"
+#include "app_util.h"
+#include "nordic_common.h"
+#include "nrf_delay.h"
+
+#define NRF_LOG_MODULE_NAME nfc_ndef_parser
+#if NFC_NDEF_RECORD_PARSER_LOG_ENABLED
+#define NRF_LOG_LEVEL NFC_NDEF_RECORD_PARSER_LOG_LEVEL
+#define NRF_LOG_INFO_COLOR NFC_NDEF_RECORD_PARSER_INFO_COLOR
+#include "nrf_log.h"
+NRF_LOG_MODULE_REGISTER();
+#else // NFC_NDEF_RECORD_PARSER_LOG_ENABLED
+#define NRF_LOG_LEVEL 0
+#include "nrf_log.h"
+#endif // NFC_NDEF_RECORD_PARSER_LOG_ENABLED
+
+/* Sum of sizes of fields: TNF-flags, Type Length, Payload Length in short NDEF record. */
+#define NDEF_RECORD_BASE_LONG_SHORT (2 + NDEF_RECORD_PAYLOAD_LEN_SHORT_SIZE)
+
+
+ret_code_t ndef_record_parser(nfc_ndef_bin_payload_desc_t * p_bin_pay_desc,
+ nfc_ndef_record_desc_t * p_rec_desc,
+ nfc_ndef_record_location_t * p_record_location,
+ uint8_t const * p_nfc_data,
+ uint32_t * p_nfc_data_len)
+{
+ uint32_t expected_rec_size = NDEF_RECORD_BASE_LONG_SHORT;
+
+ if (expected_rec_size > *p_nfc_data_len)
+ {
+ return NRF_ERROR_INVALID_LENGTH;
+ }
+
+ p_rec_desc->tnf = (nfc_ndef_record_tnf_t) ((*p_nfc_data) & NDEF_RECORD_TNF_MASK);
+
+ /* An NDEF parser that receives an NDEF record with an unknown or unsupported TNF field value
+ SHOULD treat it as Unknown. See NFCForum-TS-NDEF_1.0 */
+ if (p_rec_desc->tnf == TNF_RESERVED)
+ {
+ p_rec_desc->tnf = TNF_UNKNOWN_TYPE;
+ }
+
+ *p_record_location = (nfc_ndef_record_location_t) ((*p_nfc_data) & NDEF_RECORD_LOCATION_MASK);
+
+ uint8_t flags = *(p_nfc_data++);
+
+ p_rec_desc->type_length = *(p_nfc_data++);
+
+ uint32_t payload_lenght;
+
+ if (flags & NDEF_RECORD_SR_MASK)
+ {
+ payload_lenght = *(p_nfc_data++);
+ }
+ else
+ {
+ expected_rec_size +=
+ NDEF_RECORD_PAYLOAD_LEN_LONG_SIZE - NDEF_RECORD_PAYLOAD_LEN_SHORT_SIZE;
+
+ if (expected_rec_size > *p_nfc_data_len)
+ {
+ return NRF_ERROR_INVALID_LENGTH;
+ }
+
+ payload_lenght = uint32_big_decode(p_nfc_data);
+ p_nfc_data += NDEF_RECORD_PAYLOAD_LEN_LONG_SIZE;
+ }
+
+ if (flags & NDEF_RECORD_IL_MASK)
+ {
+ expected_rec_size += NDEF_RECORD_ID_LEN_SIZE;
+
+ if (expected_rec_size > *p_nfc_data_len)
+ {
+ return NRF_ERROR_INVALID_LENGTH;
+ }
+
+ p_rec_desc->id_length = *(p_nfc_data++);
+ }
+ else
+ {
+ p_rec_desc->id_length = 0;
+ p_rec_desc->p_id = NULL;
+ }
+
+ expected_rec_size += p_rec_desc->type_length + p_rec_desc->id_length + payload_lenght;
+
+ if (expected_rec_size > *p_nfc_data_len)
+ {
+ return NRF_ERROR_INVALID_LENGTH;
+ }
+
+ if (p_rec_desc->type_length > 0)
+ {
+ p_rec_desc->p_type = p_nfc_data;
+
+ p_nfc_data += p_rec_desc->type_length;
+ }
+ else
+ {
+ p_rec_desc->p_type = NULL;
+ }
+
+ if (p_rec_desc->id_length > 0)
+ {
+ p_rec_desc->p_id = p_nfc_data;
+
+ p_nfc_data += p_rec_desc->id_length;
+ }
+
+ if (payload_lenght == 0)
+ {
+ p_bin_pay_desc->p_payload = NULL;
+ }
+ else
+ {
+ p_bin_pay_desc->p_payload = p_nfc_data;
+ }
+
+ p_bin_pay_desc->payload_length = payload_lenght;
+
+ p_rec_desc->p_payload_descriptor = p_bin_pay_desc;
+ p_rec_desc->payload_constructor = (p_payload_constructor_t) nfc_ndef_bin_payload_memcopy;
+
+ *p_nfc_data_len = expected_rec_size;
+
+ return NRF_SUCCESS;
+}
+
+char const * const tnf_strings[] =
+{
+ "Empty",
+ "NFC Forum well-known type",
+ "Media-type (RFC 2046)",
+ "Absolute URI (RFC 3986)",
+ "NFC Forum external type (NFC RTD)",
+ "Unknown",
+ "Unchanged",
+ "Reserved"
+};
+
+void ndef_record_printout(uint32_t num, nfc_ndef_record_desc_t * const p_rec_desc)
+{
+ NRF_LOG_INFO("NDEF record %d content:", num);
+ NRF_LOG_INFO("TNF: %s",(uint32_t)tnf_strings[p_rec_desc->tnf]);
+
+ if (p_rec_desc->p_id != NULL)
+ {
+ NRF_LOG_INFO("ID:");
+ NRF_LOG_HEXDUMP_INFO((uint8_t *)p_rec_desc->p_id, p_rec_desc->id_length);
+ }
+
+ if (p_rec_desc->p_type != NULL)
+ {
+ NRF_LOG_INFO("type:");
+ NRF_LOG_HEXDUMP_INFO((uint8_t *)p_rec_desc->p_type, p_rec_desc->type_length);
+ }
+
+ if (p_rec_desc->payload_constructor == (p_payload_constructor_t) nfc_ndef_bin_payload_memcopy)
+ {
+ nfc_ndef_bin_payload_desc_t * p_bin_pay_desc = p_rec_desc->p_payload_descriptor;
+
+ if (p_bin_pay_desc->p_payload != NULL)
+ {
+ NRF_LOG_INFO("Payload length: %d bytes", p_bin_pay_desc->payload_length);
+ NRF_LOG_HEXDUMP_DEBUG((uint8_t *)p_bin_pay_desc->p_payload, p_bin_pay_desc->payload_length);
+ }
+ else
+ {
+ NRF_LOG_INFO("No payload");
+ }
+ }
+}
+
+#endif // NRF_MODULE_ENABLED(NFC_NDEF_RECORD_PARSER)
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/ndef/parser/record/nfc_ndef_record_parser.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/ndef/parser/record/nfc_ndef_record_parser.h
new file mode 100644
index 0000000..c14a239
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/ndef/parser/record/nfc_ndef_record_parser.h
@@ -0,0 +1,100 @@
+/**
+ * Copyright (c) 2016 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#ifndef NFC_NDEF_RECORD_PARSER_H__
+#define NFC_NDEF_RECORD_PARSER_H__
+
+#include <stdint.h>
+#include "sdk_errors.h"
+#include "nfc_ndef_record.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**@file
+ *
+ * @defgroup nfc_ndef_record_parser Parser for NDEF records
+ * @{
+ * @ingroup nfc_ndef_parser
+ *
+ * @brief Parser for NFC NDEF records.
+ *
+ */
+
+
+/**
+ * @brief Function for parsing NDEF records.
+ *
+ * This parsing implementation uses the binary payload descriptor (@ref nfc_ndef_bin_payload_desc_t) to describe the payload for the record.
+ *
+ * @param[out] p_bin_pay_desc Pointer to the binary payload descriptor that will be filled and referenced by the record descriptor.
+ * @param[out] p_rec_desc Pointer to the record descriptor that will be filled with parsed data.
+ * @param[out] p_record_location Pointer to the record location.
+ * @param[in] p_nfc_data Pointer to the raw data to be parsed.
+ * @param[in,out] p_nfc_data_len As input: size of the NFC data in the @p p_nfc_data buffer. As output: size of the parsed record.
+ *
+ * @retval NRF_SUCCESS If the function completed successfully.
+ * @retval NRF_ERROR_INVALID_LENGTH If the expected record length is bigger than the provided input data amount.
+ */
+ret_code_t ndef_record_parser(nfc_ndef_bin_payload_desc_t * p_bin_pay_desc,
+ nfc_ndef_record_desc_t * p_rec_desc,
+ nfc_ndef_record_location_t * p_record_location,
+ uint8_t const * p_nfc_data,
+ uint32_t * p_nfc_data_len);
+
+/**
+ * @brief Function for printing the parsed contents of the NDEF record.
+ *
+ * @param[in] num Sequence number of the record within the NDEF message.
+ * @param[in] p_rec_desc Pointer to the descriptor of the record that should be printed.
+ *
+ */
+void ndef_record_printout(uint32_t num, nfc_ndef_record_desc_t * const p_rec_desc);
+
+/**
+ * @}
+ */
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // NFC_NDEF_RECORD_PARSER_H__
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/ndef/text/nfc_text_rec.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/ndef/text/nfc_text_rec.c
new file mode 100644
index 0000000..c420039
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/ndef/text/nfc_text_rec.c
@@ -0,0 +1,107 @@
+/**
+ * Copyright (c) 2015 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#include "sdk_common.h"
+#if NRF_MODULE_ENABLED(NFC_NDEF_TEXT_RECORD)
+
+#include <string.h>
+#include "nfc_text_rec.h"
+#include "nrf_error.h"
+
+#define TEXT_REC_STATUS_SIZE 1 ///< Size of the status.
+#define TEXT_REC_STATUS_UTF_POS 7 ///< Position of a character encoding type.
+#define TEXT_REC_RESERVED_POS 6 ///< Reserved position.
+
+const uint8_t nfc_text_rec_type_field[] = {'T'};
+
+
+/**
+ * @brief Function for calculating payload size.
+ */
+__STATIC_INLINE uint32_t nfc_text_rec_payload_size_get(nfc_text_rec_payload_desc_t * p_nfc_rec_text_payload_desc)
+{
+ return (TEXT_REC_STATUS_SIZE
+ + p_nfc_rec_text_payload_desc->lang_code_len
+ + p_nfc_rec_text_payload_desc->data_len);
+}
+
+ret_code_t nfc_text_rec_payload_constructor(nfc_text_rec_payload_desc_t * p_nfc_rec_text_payload_desc,
+ uint8_t * p_buff,
+ uint32_t * p_len)
+{
+ if ((p_nfc_rec_text_payload_desc->lang_code_len == 0)
+ || (p_nfc_rec_text_payload_desc->lang_code_len & (1 << TEXT_REC_RESERVED_POS))
+ || (p_nfc_rec_text_payload_desc->lang_code_len & (1 << TEXT_REC_STATUS_UTF_POS))
+ || (p_nfc_rec_text_payload_desc->p_lang_code == NULL)
+ || (p_nfc_rec_text_payload_desc->data_len == 0)
+ || (p_nfc_rec_text_payload_desc->p_data == NULL)
+ || (p_len == NULL))
+ {
+ return NRF_ERROR_INVALID_PARAM;
+ }
+
+ uint32_t payload_size = nfc_text_rec_payload_size_get(p_nfc_rec_text_payload_desc);
+
+ if (p_buff != NULL)
+ {
+ if (payload_size > *p_len)
+ {
+ return NRF_ERROR_NO_MEM;
+ }
+
+ *p_buff = (p_nfc_rec_text_payload_desc->lang_code_len
+ + (p_nfc_rec_text_payload_desc->utf << TEXT_REC_STATUS_UTF_POS));
+ p_buff += TEXT_REC_STATUS_SIZE;
+
+ memcpy(p_buff,
+ p_nfc_rec_text_payload_desc->p_lang_code,
+ p_nfc_rec_text_payload_desc->lang_code_len);
+ p_buff += p_nfc_rec_text_payload_desc->lang_code_len;
+
+ memcpy(p_buff,
+ p_nfc_rec_text_payload_desc->p_data,
+ p_nfc_rec_text_payload_desc->data_len);
+ }
+
+ *p_len = payload_size;
+
+ return NRF_SUCCESS;
+}
+
+#endif // NRF_MODULE_ENABLED(NFC_NDEF_TEXT_RECORD)
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/ndef/text/nfc_text_rec.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/ndef/text/nfc_text_rec.h
new file mode 100644
index 0000000..0e46f89
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/ndef/text/nfc_text_rec.h
@@ -0,0 +1,161 @@
+/**
+ * Copyright (c) 2015 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#ifndef NFC_TEXT_REC_H__
+#define NFC_TEXT_REC_H__
+
+/**@file
+ *
+ * @defgroup nfc_text_rec Text records
+ * @{
+ * @ingroup nfc_ndef_messages
+ *
+ * @brief Generation of NFC NDEF Text record descriptions.
+ *
+ */
+
+#include "nfc_ndef_record.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @brief Type of the Unicode Transformation Format.
+ *
+ * Values to specify the type of UTF for an NFC NDEF Text record.
+ */
+typedef enum
+{
+ UTF_8 = 0, ///< Unicode Transformation Format 8.
+ UTF_16 = 1, ///< Unicode Transformation Format 16.
+} nfc_text_rec_utf_type_t;
+
+/**
+ * @brief Text record payload descriptor.
+ */
+typedef struct
+{
+ nfc_text_rec_utf_type_t utf; ///< Type of the Unicode Transformation Format.
+
+ uint8_t const * p_lang_code; ///< Pointer to the IANA language code.
+ uint8_t lang_code_len; ///< Length of the IANA language code.
+
+ uint8_t const * p_data; ///< Pointer to the user text.
+ uint32_t data_len; ///< Length of the user text.
+} nfc_text_rec_payload_desc_t;
+
+/**
+ * @brief Constructor for an NFC NDEF Text record payload.
+ *
+ * @param[in] p_nfc_rec_text_payload_desc Pointer to the Text record description.
+ * @param[out] p_buff Pointer to the payload destination. If NULL, function will
+ * calculate the expected size of the Text record payload.
+ *
+ * @param[in,out] p_len Size of the available memory to write as input.
+ * Size of the generated record payload as output.
+ */
+ret_code_t nfc_text_rec_payload_constructor(nfc_text_rec_payload_desc_t * p_nfc_rec_text_payload_desc,
+ uint8_t * p_buff,
+ uint32_t * p_len);
+
+/**
+ * @brief External reference to the type field of the Text record, defined in the
+ * file @c nfc_text_rec.c. It is used in the @ref NFC_NDEF_TEXT_RECORD_DESC_DEF macro.
+ */
+extern const uint8_t nfc_text_rec_type_field[];
+
+/**
+ * @brief Size of the type field of the Text record, defined in the
+ * file @c nfc_text_rec.c. It is used in the @ref NFC_NDEF_TEXT_RECORD_DESC_DEF macro.
+ */
+#define NFC_TEXT_REC_TYPE_LENGTH 1
+
+/**
+ *@brief Macro for creating and initializing an NFC NDEF record descriptor for a Text record.
+ *
+ * This macro creates and initializes an instance of type @ref nfc_ndef_record_desc_t and
+ * an instance of type @ref nfc_text_rec_payload_desc_t, which together constitute
+ * an instance of a Text record.
+ *
+ * Use the macro @ref NFC_NDEF_TEXT_RECORD_DESC to access the NDEF Text record descriptor instance.
+ *
+ * @param[in] NAME Name of the created record descriptor instance.
+ * @param[in] UTF Unicode Transformation Format.
+ * @param[in] P_LANG_CODE Pointer to the IANA language code.
+ * @param[in] LANG_CODE_LEN Length of the IANA language code.
+ * @param[in] P_DATA Pointer to the user text.
+ * @param[in] DATA_LEN Length of the user text.
+ */
+#define NFC_NDEF_TEXT_RECORD_DESC_DEF(NAME, \
+ UTF, \
+ P_LANG_CODE, \
+ LANG_CODE_LEN, \
+ P_DATA, \
+ DATA_LEN) \
+ nfc_text_rec_payload_desc_t NAME##_nfc_text_rec_payload_desc = \
+ { \
+ .utf = UTF, \
+ .p_lang_code = P_LANG_CODE, \
+ .lang_code_len = LANG_CODE_LEN, \
+ .p_data = P_DATA, \
+ .data_len = DATA_LEN, \
+ }; \
+ NFC_NDEF_GENERIC_RECORD_DESC_DEF(NAME, \
+ TNF_WELL_KNOWN, \
+ 0, \
+ 0, \
+ nfc_text_rec_type_field, \
+ NFC_TEXT_REC_TYPE_LENGTH, \
+ nfc_text_rec_payload_constructor, \
+ &(NAME##_nfc_text_rec_payload_desc))
+
+/**
+ * @brief Macro for accessing the NFC NDEF Text record descriptor
+ * instance that was created with @ref NFC_NDEF_TEXT_RECORD_DESC_DEF.
+ */
+#define NFC_NDEF_TEXT_RECORD_DESC(NAME) NFC_NDEF_GENERIC_RECORD_DESC(NAME)
+
+/** @} */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // NFC_TEXT_REC_H__
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/ndef/uri/nfc_uri_msg.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/ndef/uri/nfc_uri_msg.c
new file mode 100644
index 0000000..205e585
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/ndef/uri/nfc_uri_msg.c
@@ -0,0 +1,72 @@
+/**
+ * Copyright (c) 2015 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#include "sdk_common.h"
+#if NRF_MODULE_ENABLED(NFC_NDEF_URI_MSG)
+
+#include <string.h>
+#include "nfc_uri_msg.h"
+#include "sdk_macros.h"
+
+ret_code_t nfc_uri_msg_encode( nfc_uri_id_t uri_id_code,
+ uint8_t const * const p_uri_data,
+ uint8_t uri_data_len,
+ uint8_t * p_buf,
+ uint32_t * p_len)
+{
+ ret_code_t err_code;
+
+ /* Create NFC NDEF message description with URI record */
+ NFC_NDEF_MSG_DEF(nfc_uri_msg, 1);
+ NFC_NDEF_URI_RECORD_DESC_DEF(nfc_uri_rec, uri_id_code, p_uri_data, uri_data_len);
+
+ err_code = nfc_ndef_msg_record_add(&NFC_NDEF_MSG(nfc_uri_msg),
+ &NFC_NDEF_URI_RECORD_DESC(nfc_uri_rec));
+ VERIFY_SUCCESS(err_code);
+ VERIFY_PARAM_NOT_NULL(p_uri_data);
+
+ /* Encode whole message into buffer */
+ err_code = nfc_ndef_msg_encode(&NFC_NDEF_MSG(nfc_uri_msg),
+ p_buf,
+ p_len);
+
+ return err_code;
+}
+
+#endif // NRF_MODULE_ENABLED(NFC_NDEF_URI_MSG)
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/ndef/uri/nfc_uri_msg.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/ndef/uri/nfc_uri_msg.h
new file mode 100644
index 0000000..fe95f4f
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/ndef/uri/nfc_uri_msg.h
@@ -0,0 +1,95 @@
+/**
+ * Copyright (c) 2015 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#ifndef NFC_URI_MSG_H__
+#define NFC_URI_MSG_H__
+
+/**@file
+ *
+ * @defgroup nfc_uri_msg URI messages
+ * @{
+ * @ingroup nfc_ndef_messages
+ *
+ * @brief Generation of NFC NDEF messages with a URI record.
+ *
+ */
+
+#include "nfc_ndef_msg.h"
+#include "nfc_uri_rec.h"
+#include "nrf_error.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** @brief Function for encoding an NFC NDEF URI message.
+ *
+ * This function encodes an NFC NDEF message into a buffer.
+ *
+ * @param[in] uri_id_code URI identifier code that defines the protocol field of the URI.
+ * @param[in] p_uri_data Pointer to the URI string.
+ * The string should not contain the protocol field if the protocol
+ * was specified in @p uri_id_code.
+ * @param[in] uri_data_len Length of the URI string.
+ * @param[out] p_buf Pointer to the buffer for the message.
+ * @param[in,out] p_len Size of the available memory for the message as input.
+ * Size of the generated message as output.
+ *
+ * @retval NRF_SUCCESS If the description was successfully created.
+ * @retval NRF_ERROR_NULL If the URI string was invalid (equal to NULL).
+ * @retval NRF_ERROR_NO_MEM If the predicted message size is bigger than the provided
+ * buffer space.
+ * @retval Other Other codes might be returned depending on
+ * the function @ref nfc_ndef_msg_encode.
+ */
+ret_code_t nfc_uri_msg_encode( nfc_uri_id_t uri_id_code,
+ uint8_t const * const p_uri_data,
+ uint8_t uri_data_len,
+ uint8_t * p_buf,
+ uint32_t * p_len);
+
+/**
+ * @}
+ */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // NFC_URI_MSG_H__
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/ndef/uri/nfc_uri_rec.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/ndef/uri/nfc_uri_rec.c
new file mode 100644
index 0000000..f4a60ab
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/ndef/uri/nfc_uri_rec.c
@@ -0,0 +1,87 @@
+/**
+ * Copyright (c) 2015 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#include "sdk_common.h"
+#if NRF_MODULE_ENABLED(NFC_NDEF_URI_REC)
+
+#include <string.h>
+#include "nfc_uri_rec.h"
+#include "nrf_error.h"
+
+const uint8_t ndef_uri_record_type = 'U'; ///< URI Record type.
+
+/**
+ * @brief Function for constructing the payload for a URI record.
+ *
+ * This function encodes the payload according to the URI record definition. It implements an API
+ * compatible with @ref p_payload_constructor_t.
+ *
+ * @param[in] p_input Pointer to the description of the payload.
+ * @param[out] p_buff Pointer to payload destination. If NULL, function will
+ * calculate the expected size of the URI record payload.
+ *
+ * @param[in,out] p_len Size of available memory to write as input. Size of generated
+ * payload as output.
+ *
+ * @retval NRF_SUCCESS If the payload was encoded successfully.
+ * @retval NRF_ERROR_NO_MEM If the predicted payload size is bigger than the provided buffer space.
+ */
+ret_code_t nfc_uri_payload_constructor( uri_payload_desc_t * p_input,
+ uint8_t * p_buff,
+ uint32_t * p_len)
+{
+ if (p_buff != NULL)
+ {
+ /* Verify if there is enough available memory */
+ if (p_input->uri_data_len >= *p_len)
+ {
+ return NRF_ERROR_NO_MEM;
+ }
+
+ /* Copy descriptor content into the buffer */
+ *(p_buff++) = p_input->uri_id_code;
+ memcpy(p_buff, p_input->p_uri_data, p_input->uri_data_len );
+ }
+
+ *p_len = p_input->uri_data_len + 1;
+
+ return NRF_SUCCESS;
+}
+
+#endif // NRF_MODULE_ENABLED(NFC_NDEF_URI_REC)
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/ndef/uri/nfc_uri_rec.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/ndef/uri/nfc_uri_rec.h
new file mode 100644
index 0000000..163b1c6
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/ndef/uri/nfc_uri_rec.h
@@ -0,0 +1,189 @@
+/**
+ * Copyright (c) 2015 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#ifndef NFC_URI_REC_H__
+#define NFC_URI_REC_H__
+
+/**@file
+ *
+ * @defgroup nfc_uri_rec URI records
+ * @{
+ * @ingroup nfc_uri_msg
+ *
+ * @brief Generation of NFC NDEF URI record descriptions.
+ *
+ */
+
+#include "nfc_ndef_record.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @enum nfc_uri_id_t
+ * @brief URI identifier codes according to "URI Record Type Definition"
+ * (denotation "NFCForum-TS-RTD_URI_1.0" published on 2006-07-24) chapter 3.2.2.
+ */
+typedef enum
+{
+ NFC_URI_NONE = 0x00, /**< No prepending is done. */
+ NFC_URI_HTTP_WWW = 0x01, /**< "http://www." */
+ NFC_URI_HTTPS_WWW = 0x02, /**< "https://www." */
+ NFC_URI_HTTP = 0x03, /**< "http:" */
+ NFC_URI_HTTPS = 0x04, /**< "https:" */
+ NFC_URI_TEL = 0x05, /**< "tel:" */
+ NFC_URI_MAILTO = 0x06, /**< "mailto:" */
+ NFC_URI_FTP_ANONYMOUS = 0x07, /**< "ftp://anonymous:anonymous@" */
+ NFC_URI_FTP_FTP = 0x08, /**< "ftp://ftp." */
+ NFC_URI_FTPS = 0x09, /**< "ftps://" */
+ NFC_URI_SFTP = 0x0A, /**< "sftp://" */
+ NFC_URI_SMB = 0x0B, /**< "smb://" */
+ NFC_URI_NFS = 0x0C, /**< "nfs://" */
+ NFC_URI_FTP = 0x0D, /**< "ftp://" */
+ NFC_URI_DAV = 0x0E, /**< "dav://" */
+ NFC_URI_NEWS = 0x0F, /**< "news:" */
+ NFC_URI_TELNET = 0x10, /**< "telnet://" */
+ NFC_URI_IMAP = 0x11, /**< "imap:" */
+ NFC_URI_RTSP = 0x12, /**< "rtsp://" */
+ NFC_URI_URN = 0x13, /**< "urn:" */
+ NFC_URI_POP = 0x14, /**< "pop:" */
+ NFC_URI_SIP = 0x15, /**< "sip:" */
+ NFC_URI_SIPS = 0x16, /**< "sips:" */
+ NFC_URI_TFTP = 0x17, /**< "tftp:" */
+ NFC_URI_BTSPP = 0x18, /**< "btspp://" */
+ NFC_URI_BTL2CAP = 0x19, /**< "btl2cap://" */
+ NFC_URI_BTGOEP = 0x1A, /**< "btgoep://" */
+ NFC_URI_TCPOBEX = 0x1B, /**< "tcpobex://" */
+ NFC_URI_IRDAOBEX = 0x1C, /**< "irdaobex://" */
+ NFC_URI_FILE = 0x1D, /**< "file://" */
+ NFC_URI_URN_EPC_ID = 0x1E, /**< "urn:epc:id:" */
+ NFC_URI_URN_EPC_TAG = 0x1F, /**< "urn:epc:tag:" */
+ NFC_URI_URN_EPC_PAT = 0x20, /**< "urn:epc:pat:" */
+ NFC_URI_URN_EPC_RAW = 0x21, /**< "urn:epc:raw:" */
+ NFC_URI_URN_EPC = 0x22, /**< "urn:epc:" */
+ NFC_URI_URN_NFC = 0x23, /**< "urn:nfc:" */
+ NFC_URI_RFU = 0xFF /**< No prepending is done. Reserved for future use. */
+} nfc_uri_id_t;
+
+
+/**
+ * @brief Type of description of the payload of a URI record.
+ */
+typedef struct
+{
+ nfc_uri_id_t uri_id_code; /**< URI identifier code. */
+ uint8_t const * p_uri_data; /**< Pointer to a URI string. */
+ uint8_t uri_data_len; /**< Length of the URI string. */
+} uri_payload_desc_t;
+
+/**
+ * @brief External reference to the type field of the URI record, defined in the
+ * file @c nfc_uri_rec.c. It is used in the @ref NFC_NDEF_URI_RECORD_DESC_DEF macro.
+ */
+extern const uint8_t ndef_uri_record_type;
+
+/**
+ * @brief Function for constructing the payload for a URI record.
+ *
+ * This function encodes the payload according to the URI record definition. It implements an API
+ * compatible with @ref p_payload_constructor_t.
+ *
+ * @param[in] p_input Pointer to the description of the payload.
+ * @param[out] p_buff Pointer to payload destination. If NULL, function will
+ * calculate the expected size of the URI record payload.
+ *
+ * @param[in,out] p_len Size of available memory to write as input. Size of generated
+ * payload as output.
+ *
+ * @retval NRF_SUCCESS If the payload was encoded successfully.
+ * @retval NRF_ERROR_NO_MEM If the predicted payload size is bigger than the provided buffer space.
+ */
+ret_code_t nfc_uri_payload_constructor( uri_payload_desc_t * p_input,
+ uint8_t * p_buff,
+ uint32_t * p_len);
+
+/** @brief Macro for generating a description of a URI record.
+ *
+ * This macro initializes an instance of an NFC NDEF record description of a URI record.
+ *
+ * @note The record descriptor is declared as automatic variable, which implies that
+ * the NDEF message encoding (see @ref nfc_uri_msg_encode) must be done
+ * in the same variable scope.
+ *
+ * @param[in] NAME Name for accessing record descriptor.
+ * @param[in] URI_ID_CODE URI identifier code that defines the protocol field of the URI.
+ * @param[in] P_URI_DATA Pointer to the URI string.
+ * The string should not contain the protocol field if the protocol
+ * was specified in @p uri_id_code.
+ * @param[in] URI_DATA_LEN Length of the URI string.
+ */
+#define NFC_NDEF_URI_RECORD_DESC_DEF(NAME, \
+ URI_ID_CODE, \
+ P_URI_DATA, \
+ URI_DATA_LEN) \
+ uri_payload_desc_t NAME##_ndef_uri_record_payload_desc = \
+ { \
+ .uri_id_code = (URI_ID_CODE), \
+ .p_uri_data = (P_URI_DATA), \
+ .uri_data_len = (URI_DATA_LEN) \
+ }; \
+ \
+ NFC_NDEF_GENERIC_RECORD_DESC_DEF( NAME, \
+ TNF_WELL_KNOWN, \
+ NULL, \
+ 0, \
+ &ndef_uri_record_type, \
+ sizeof(ndef_uri_record_type), \
+ nfc_uri_payload_constructor, \
+ &NAME##_ndef_uri_record_payload_desc) \
+
+/**
+ * @brief Macro for accessing the NFC NDEF URI record descriptor instance that
+ * was created with @ref NFC_NDEF_URI_RECORD_DESC_DEF.
+ */
+#define NFC_NDEF_URI_RECORD_DESC(NAME) NFC_NDEF_GENERIC_RECORD_DESC(NAME)
+
+/** @} */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // NFC_URI_REC_H__
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/t2t_lib/hal_t2t/hal_nfc_t2t.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/t2t_lib/hal_t2t/hal_nfc_t2t.c
new file mode 100644
index 0000000..25c79fb
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/t2t_lib/hal_t2t/hal_nfc_t2t.c
@@ -0,0 +1,1007 @@
+/**
+ * Copyright (c) 2015 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+
+#include "sdk_config.h"
+#if NFC_T2T_HAL_ENABLED
+
+#include "hal_nfc_t2t.h"
+#include <stdint.h>
+#include <stdbool.h>
+#include "nfc_t2t_lib.h"
+#include "nfc_fixes.h"
+#include "nrf.h"
+#include "app_util_platform.h"
+#include "nordic_common.h"
+#include "nrf_drv_clock.h"
+
+#define NRF_LOG_MODULE_NAME hal_nfc
+#if HAL_NFC_CONFIG_LOG_ENABLED
+#define NRF_LOG_LEVEL HAL_NFC_CONFIG_LOG_LEVEL
+#define NRF_LOG_INFO_COLOR HAL_NFC_CONFIG_INFO_COLOR
+#define NRF_LOG_DEBUG_COLOR HAL_NFC_CONFIG_DEBUG_COLOR
+#include "nrf_log.h"
+NRF_LOG_MODULE_REGISTER();
+#else // HAL_NFC_CONFIG_LOG_ENABLED
+#define NRF_LOG_LEVEL 0
+#include "nrf_log.h"
+#endif // HAL_NFC_CONFIG_LOG_ENABLED
+
+#if HAL_NFC_CONFIG_DEBUG_PIN_ENABLED
+ #include "nrf_gpio.h"
+
+ #define HAL_NFC_DEBUG_PIN_CONFIG(pin_num) nrf_gpio_cfg_output(pin_num)
+ #define HAL_NFC_DEBUG_PIN_CLEAR(pin_num) nrf_gpio_pin_clear(pin_num)
+ #define HAL_NFC_DEBUG_PIN_SET(pin_num) nrf_gpio_pin_set(pin_num)
+
+ #define HAL_NFC_DEBUG_PINS_INITIALIZE() \
+ do{ \
+ HAL_NFC_DEBUG_PIN_CONFIG(HAL_NFC_HCLOCK_OFF_DEBUG_PIN); \
+ HAL_NFC_DEBUG_PIN_CLEAR(HAL_NFC_HCLOCK_OFF_DEBUG_PIN); \
+ HAL_NFC_DEBUG_PIN_CONFIG(HAL_NFC_HCLOCK_ON_DEBUG_PIN); \
+ HAL_NFC_DEBUG_PIN_CLEAR(HAL_NFC_HCLOCK_ON_DEBUG_PIN); \
+ HAL_NFC_DEBUG_PIN_CONFIG(HAL_NFC_NFC_EVENT_DEBUG_PIN); \
+ HAL_NFC_DEBUG_PIN_CLEAR(HAL_NFC_NFC_EVENT_DEBUG_PIN); \
+ HAL_NFC_DEBUG_PIN_CONFIG(HAL_NFC_DETECT_EVENT_DEBUG_PIN); \
+ HAL_NFC_DEBUG_PIN_CLEAR(HAL_NFC_DETECT_EVENT_DEBUG_PIN); \
+ HAL_NFC_DEBUG_PIN_CONFIG(HAL_NFC_TIMER4_EVENT_DEBUG_PIN); \
+ HAL_NFC_DEBUG_PIN_CLEAR(HAL_NFC_TIMER4_EVENT_DEBUG_PIN); \
+ } while(0)
+#else
+ #define HAL_NFC_DEBUG_PIN_CLEAR(pin_num)
+ #define HAL_NFC_DEBUG_PIN_SET(pin_num)
+ #define HAL_NFC_DEBUG_PINS_INITIALIZE()
+#endif // HAL_NFC_CONFIG_DEBUG_PIN_ENABLED
+
+
+/* NFC library version history:
+ * #define NFC_LIB_VERSION 0x00 first experimental version intended for nRF52 IC rev. Engineering A (PCA10036, part of nRF52 Preview Development Kit)
+ * #define NFC_LIB_VERSION 0x01 experimental version intended for nRF52 IC rev. Engineering B (PCA10040, part of nRF52 Development Kit)
+ * #define NFC_LIB_VERSION 0x02 experimental version intended for fix IC-12826 and fix: not released HFCLK in SENSE mode
+ * #define NFC_LIB_VERSION 0x03 experimental version intended for support logging module
+ * #define NFC_LIB_VERSION 0x04 experimental version intended for nRF52840 IC rev. Engineering A (PCA10056, part of nRF52840 Preview Development Kit). Removed PCA10036 support.
+ */
+
+#define NFC_LIB_VERSION 0x03u /**< Internal: current NFC lib. version */
+
+#define T2T_INTERNAL_BYTES_NR 10u /**< Number of internal bytes defined by Type 2 Tag Operation Technical Specification */
+#define CASCADE_TAG_BYTE 0x88u /**< Constant defined by ISO/EIC 14443-3 */
+
+#define NFCID1_3RD_LAST_BYTE2_SHIFT 16u /**< Shift value for NFC ID byte 2 */
+#define NFCID1_3RD_LAST_BYTE1_SHIFT 8u /**< Shift value for NFC ID byte 1 */
+#define NFCID1_3RD_LAST_BYTE0_SHIFT 0u /**< Shift value for NFC ID byte 0 */
+#define NFCID1_2ND_LAST_BYTE2_SHIFT 16u /**< Shift value for NFC ID byte 2 */
+#define NFCID1_2ND_LAST_BYTE1_SHIFT 8u /**< Shift value for NFC ID byte 1 */
+#define NFCID1_2ND_LAST_BYTE0_SHIFT 0u /**< Shift value for NFC ID byte 0 */
+#define NFCID1_LAST_BYTE3_SHIFT 24u /**< Shift value for NFC ID byte 3 */
+#define NFCID1_LAST_BYTE2_SHIFT 16u /**< Shift value for NFC ID byte 2 */
+#define NFCID1_LAST_BYTE1_SHIFT 8u /**< Shift value for NFC ID byte 1 */
+#define NFCID1_LAST_BYTE0_SHIFT 0u /**< Shift value for NFC ID byte 0 */
+
+#define NFCID1_SINGLE_SIZE 4u /**< Length of single size NFCID1 */
+#define NFCID1_DOUBLE_SIZE 7u /**< Length of double size NFCID1 */
+#define NFCID1_TRIPLE_SIZE 10u /**< Length of triple size NFCID1 */
+#define NFCID1_DEFAULT_LENGHT NFCID1_DOUBLE_SIZE /**< Length of NFCID1 if user does not provide one */
+#define NFCID1_MAX_LENGHT NFCID1_TRIPLE_SIZE /**< Maximum length of NFCID1 */
+
+#define NFC_RX_BUFFER_SIZE 16u /**< NFC Rx data buffer size */
+#define T2T_READ_CMD 0x30u /**< Type 2 Tag Read command identifier */
+#define NFC_SLP_REQ_CMD 0x50u /**< NFC SLP_REQ command identifier */
+#define NFC_CRC_SIZE 2u /**< CRC size in bytes */
+
+#ifdef HAL_NFC_NRF52840_ENGINEERING_ABC_WORKAROUND
+ #define NRF_NFCT_ERRORSTATUS_ALL (NFCT_ERRORSTATUS_FRAMEDELAYTIMEOUT_Msk) /**< Mask for clearing all error flags in NFCT_ERRORSTATUS register */
+#else
+ #define NRF_NFCT_ERRORSTATUS_ALL (NFCT_ERRORSTATUS_NFCFIELDTOOWEAK_Msk | \
+ NFCT_ERRORSTATUS_NFCFIELDTOOSTRONG_Msk | \
+ NFCT_ERRORSTATUS_FRAMEDELAYTIMEOUT_Msk) /**< Mask for clearing all error flags in NFCT_ERRORSTATUS register */
+#endif // HAL_NFC_NRF52840_ENGINEERING_ABC_WORKAROUND
+
+#define NRF_NFCT_FRAMESTATUS_RX_MSK (NFCT_FRAMESTATUS_RX_OVERRUN_Msk | \
+ NFCT_FRAMESTATUS_RX_PARITYSTATUS_Msk | \
+ NFCT_FRAMESTATUS_RX_CRCERROR_Msk) /**< Mask for clearing all flags in NFCT_FRAMESTATUS_RX register */
+#define NFC_FIELD_ON_MASK NFCT_FIELDPRESENT_LOCKDETECT_Msk /**< Mask for checking FIELDPRESENT register for state: FIELD ON. */
+#define NFC_FIELD_OFF_MASK NFCT_FIELDPRESENT_FIELDPRESENT_Msk /**< Mask for checking FIELDPRESENT register for state: FIELD OFF. */
+
+#define NRF_NFCT_DEFAULTSTATESLEEP (*(uint32_t volatile *)(0x40005420)) /**< The default state of NFCT. */
+#define NRF_NFCT_DEFAULTSTATESLEEP_MSK 0x1UL /**< Mask for checking the default state of NFCT. */
+
+#ifdef HAL_NFC_NRF52840_ENGINEERING_ABC_WORKAROUND
+ #define NRF_NFCT_ACTIVATE_CONDS_THR 2 /**< Number of required conditions to activate NFCT. */
+ #define NRF_NFCT_ACTIVATE_DELAY 1000 /**< Minimal delay in us between NFC field detection and activation of NFCT. */
+#endif // HAL_NFC_NRF52840_ENGINEERING_ABC_WORKAROUND
+
+typedef enum
+{
+ NFC_FIELD_STATE_NONE, /**< Initial value indicating no NFCT Field events. */
+ NFC_FIELD_STATE_OFF, /**< NFCT FIELDLOST Event has been set. */
+ NFC_FIELD_STATE_ON, /**< NFCT FIELDDETECTED Event has been set. */
+ NFC_FIELD_STATE_UNKNOWN /**< Both NFCT Field Events have been set - ambiguous state. */
+}nfct_field_sense_state_t;
+
+/* Static function declarations */
+static inline void nrf_nfct_event_clear(volatile uint32_t * p_event);
+static inline void nrf_nfct_clock_event_handler(nrf_drv_clock_evt_type_t event);
+static inline void nrf_nfct_field_event_handler(volatile nfct_field_sense_state_t field_state);
+static void hal_nfc_nfcid1_default_bytes(void);
+static void hal_nfc_nfcid1_registers_setup(void);
+static void hal_nfc_internal_bytes_setup(void);
+
+/* Static data */
+static hal_nfc_callback_t m_nfc_lib_callback = (hal_nfc_callback_t) NULL; /**< Callback to nfc_lib layer */
+static void * m_nfc_lib_context; /**< Callback execution context */
+static volatile uint8_t m_nfc_rx_buffer[NFC_RX_BUFFER_SIZE] = {0}; /**< Buffer for NFC Rx data */
+static volatile bool m_slp_req_received = false; /**< Flag indicating that SLP_REQ Command was received */
+static volatile bool m_field_on = false; /**< Flag indicating that NFC Tag field is present */
+static nrf_drv_clock_handler_item_t m_clock_handler_item; /**< Clock event handler item structure */
+static uint8_t m_nfcid1_length = 0; /**< Length of NFCID1 provided by user or 0 if not initialized yet */
+static uint8_t m_nfcid1_data[NFCID1_MAX_LENGHT] = {0}; /**< Content of NFCID1 */
+
+#ifdef HAL_NFC_NRF52840_ENGINEERING_ABC_WORKAROUND
+static volatile bool m_nfc_fieldevents_filter_active = false; /**< Flag indicating that field events are ignored. */
+static volatile uint32_t m_nfc_activate_conditions = 0; /**< Number of activation conditions that are met. */
+#endif // HAL_NFC_NRF52840_ENGINEERING_ABC_WORKAROUND
+
+#ifndef HAL_NFC_ENGINEERING_BC_FTPAN_WORKAROUND
+static volatile uint32_t m_nfc_fieldpresent_mask = NFC_FIELD_OFF_MASK; /**< Mask used for NFC Field polling in NFCT_FIELDPRESENT register */
+#endif // HAL_NFC_ENGINEERING_BC_FTPAN_WORKAROUND
+
+#ifdef HAL_NFC_ENGINEERING_BC_FTPAN_WORKAROUND
+
+#define NRF_NFCT_POWER (*(uint32_t volatile *)(0x40005FFC))
+
+#define NFC_HAL_FIELDPRESENT_MASK (NFCT_FIELDPRESENT_LOCKDETECT_Msk | \
+ NFCT_FIELDPRESENT_FIELDPRESENT_Msk)
+
+#define NFC_HAL_FIELDPRESENT_IS_LOST ((NFCT_FIELDPRESENT_FIELDPRESENT_NoField << \
+ NFCT_FIELDPRESENT_FIELDPRESENT_Pos) | \
+ (NFCT_FIELDPRESENT_LOCKDETECT_NotLocked << \
+ NFCT_FIELDPRESENT_LOCKDETECT_Pos))
+
+#ifndef HAL_NFC_FIELD_TIMER_PERIOD
+ #define HAL_NFC_FIELD_TIMER_PERIOD 100 /* unit - us */
+#endif
+
+static inline void hal_nfc_re_setup(void);
+static void hal_nfc_field_check(void);
+
+#endif // HAL_NFC_ENGINEERING_BC_FTPAN_WORKAROUND
+
+#ifdef HAL_NFC_NRF52840_ENGINEERING_ABC_WORKAROUND
+static void hal_nfc_activate_check(void)
+{
+ static bool is_field_validation_pending = false;
+
+ if (is_field_validation_pending)
+ {
+ is_field_validation_pending = false;
+ m_nfc_fieldevents_filter_active = false;
+
+ // Check the field status with FIELDPRESENT and take action if field is lost.
+ nrf_nfct_field_event_handler(NFC_FIELD_STATE_UNKNOWN);
+ return;
+ }
+
+ m_nfc_activate_conditions++;
+ if (m_nfc_activate_conditions == NRF_NFCT_ACTIVATE_CONDS_THR)
+ {
+ m_nfc_activate_conditions = 0;
+
+ NRF_NFCT->TASKS_ACTIVATE = 1;
+ is_field_validation_pending = true;;
+
+ // Start the timer second time to validate if tag has locked to the field
+ NRF_TIMER4->TASKS_CLEAR = 1;
+ NRF_TIMER4->TASKS_START = 1;
+ }
+}
+#endif // HAL_NFC_NRF52840_ENGINEERING_ABC_WORKAROUND
+
+#if defined(HAL_NFC_ENGINEERING_BC_FTPAN_WORKAROUND) || defined(HAL_NFC_NRF52840_ENGINEERING_ABC_WORKAROUND)
+
+static void field_timer_with_callback_config(void)
+{
+ NRF_TIMER4->MODE = TIMER_MODE_MODE_Timer << TIMER_MODE_MODE_Pos;
+ NRF_TIMER4->BITMODE = TIMER_BITMODE_BITMODE_16Bit << TIMER_BITMODE_BITMODE_Pos;
+ NRF_TIMER4->PRESCALER = 4 << TIMER_PRESCALER_PRESCALER_Pos;
+#ifdef HAL_NFC_ENGINEERING_BC_FTPAN_WORKAROUND
+ NRF_TIMER4->CC[0] = HAL_NFC_FIELD_TIMER_PERIOD << TIMER_CC_CC_Pos;
+#else
+ NRF_TIMER4->CC[0] = NRF_NFCT_ACTIVATE_DELAY << TIMER_CC_CC_Pos;
+#endif
+ NRF_TIMER4->SHORTS = TIMER_SHORTS_COMPARE0_CLEAR_Enabled << TIMER_SHORTS_COMPARE0_CLEAR_Pos;
+ NRF_TIMER4->INTENSET = TIMER_INTENSET_COMPARE0_Set << TIMER_INTENSET_COMPARE0_Pos;
+
+ NVIC_ClearPendingIRQ(TIMER4_IRQn);
+ NVIC_SetPriority(TIMER4_IRQn, NFCT_CONFIG_IRQ_PRIORITY);
+ NVIC_EnableIRQ(TIMER4_IRQn);
+}
+
+void TIMER4_IRQHandler(void)
+{
+ HAL_NFC_DEBUG_PIN_SET(HAL_NFC_TIMER4_EVENT_DEBUG_PIN);
+#ifdef HAL_NFC_ENGINEERING_BC_FTPAN_WORKAROUND
+ hal_nfc_field_check();
+#else
+ NRF_TIMER4->TASKS_SHUTDOWN = 1;
+ hal_nfc_activate_check();
+#endif
+ NRF_TIMER4->EVENTS_COMPARE[0] = 0;
+ HAL_NFC_DEBUG_PIN_CLEAR(HAL_NFC_TIMER4_EVENT_DEBUG_PIN);
+}
+
+#endif // defined(HAL_NFC_ENGINEERING_BC_FTPAN_WORKAROUND) || defined(HAL_NFC_NRF52840_ENGINEERING_ABC_WORKAROUND)
+
+/**
+ * @brief Common part of setup used for NFCT initialization and reinitialization.
+ */
+#ifdef HAL_NFC_ENGINEERING_BC_FTPAN_WORKAROUND
+static void hal_nfc_common_hw_setup()
+#else
+static inline void hal_nfc_common_hw_setup()
+#endif // HAL_NFC_ENGINEERING_BC_FTPAN_WORKAROUND
+{
+#ifdef HAL_NFC_NRF52840_ENGINEERING_ABC_WORKAROUND
+ if (type_52840_sample_check())
+ {
+ /* Begin: Bugfix for FTPAN-98 */
+ *(volatile uint32_t *) 0x4000568C = 0x00038148;
+ /* End: Bugfix for FTPAN-98 */
+ /* Begin: Bugfix for FTPAN-144 */
+ *(volatile uint32_t *) 0x4000561c = 0x01;
+ *(volatile uint32_t *) 0x4000562c = 0x3F;
+ *(volatile uint32_t *) 0x4000563c = 0x0;
+ /* End: Bugfix for FTPAN-144 */
+ }
+#endif // HAL_NFC_NRF52840_ENGINEERING_ABC_WORKAROUND
+
+#ifdef HAL_NFC_ENGINEERING_BC_FTPAN_WORKAROUND
+ NRF_NFCT->INTENSET = (NFCT_INTENSET_FIELDDETECTED_Enabled << NFCT_INTENSET_FIELDDETECTED_Pos);
+#else
+ NRF_NFCT->INTENSET = (NFCT_INTENSET_FIELDDETECTED_Enabled << NFCT_INTENSET_FIELDDETECTED_Pos) |
+ (NFCT_INTENSET_FIELDLOST_Enabled << NFCT_INTENSET_FIELDLOST_Pos);
+#endif
+
+ NRF_NFCT->INTENSET = (NFCT_INTENSET_ERROR_Enabled << NFCT_INTENSET_ERROR_Pos) |
+ (NFCT_INTENSET_SELECTED_Enabled << NFCT_INTENSET_SELECTED_Pos);
+
+ // Use Window Grid frame delay mode.
+ NRF_NFCT->FRAMEDELAYMODE = (NFCT_FRAMEDELAYMODE_FRAMEDELAYMODE_WindowGrid <<
+ NFCT_FRAMEDELAYMODE_FRAMEDELAYMODE_Pos) &
+ NFCT_FRAMEDELAYMODE_FRAMEDELAYMODE_Msk;
+
+ hal_nfc_nfcid1_registers_setup();
+}
+
+/** @brief Setup NRF_NFCT->NFCID1 and NRF_NFCT->SENSRES registers based on m_nfcid1_data and m_nfcid1_length variables.
+ */
+static void hal_nfc_nfcid1_registers_setup(void)
+{
+ uint32_t sens_res_size; // Value that will be written to NRF_NFCT->SENSRES
+ uint8_t* p_nfcid_remaining_data; // Points to the first byte of m_nfcid1_data remaining to write to NRF_NFCT->NFCID1 registers
+
+ p_nfcid_remaining_data = m_nfcid1_data;
+
+ if (m_nfcid1_length == NFCID1_SINGLE_SIZE)
+ {
+ sens_res_size = NFCT_SENSRES_NFCIDSIZE_NFCID1Single;
+ }
+ else
+ {
+ if (m_nfcid1_length == NFCID1_DOUBLE_SIZE)
+ {
+ sens_res_size = NFCT_SENSRES_NFCIDSIZE_NFCID1Double;
+ }
+ else // then m_nfcid1_length == NFCID1_TRIPLE_SIZE
+ {
+ /* MSB of NFCID1_3RD_LAST register is not used - always 0 */
+ NRF_NFCT->NFCID1_3RD_LAST =
+ ((uint32_t) p_nfcid_remaining_data[0] << NFCID1_3RD_LAST_BYTE2_SHIFT) |
+ ((uint32_t) p_nfcid_remaining_data[1] << NFCID1_3RD_LAST_BYTE1_SHIFT) |
+ ((uint32_t) p_nfcid_remaining_data[2] << NFCID1_3RD_LAST_BYTE0_SHIFT);
+ p_nfcid_remaining_data += 3;
+ sens_res_size = NFCT_SENSRES_NFCIDSIZE_NFCID1Triple;
+ }
+ /* MSB of NFCID1_2ND_LAST register is not used - always 0 */
+ NRF_NFCT->NFCID1_2ND_LAST =
+ ((uint32_t) p_nfcid_remaining_data[0] << NFCID1_2ND_LAST_BYTE2_SHIFT) |
+ ((uint32_t) p_nfcid_remaining_data[1] << NFCID1_2ND_LAST_BYTE1_SHIFT) |
+ ((uint32_t) p_nfcid_remaining_data[2] << NFCID1_2ND_LAST_BYTE0_SHIFT);
+ p_nfcid_remaining_data += 3;
+ }
+
+ NRF_NFCT->NFCID1_LAST =
+ ((uint32_t) p_nfcid_remaining_data[0] << NFCID1_LAST_BYTE3_SHIFT) |
+ ((uint32_t) p_nfcid_remaining_data[1] << NFCID1_LAST_BYTE2_SHIFT) |
+ ((uint32_t) p_nfcid_remaining_data[2] << NFCID1_LAST_BYTE1_SHIFT) |
+ ((uint32_t) p_nfcid_remaining_data[3] << NFCID1_LAST_BYTE0_SHIFT);
+
+ /* Begin: Bugfix for FTPAN-25 (IC-9929) */
+ /* Workaround for wrong SENSRES values require using SDD00001, but here SDD00100 is used
+ because it's required to operate with Windows Phone */
+ NRF_NFCT->SENSRES =
+ (sens_res_size << NFCT_SENSRES_NFCIDSIZE_Pos) |
+ (NFCT_SENSRES_BITFRAMESDD_SDD00100 << NFCT_SENSRES_BITFRAMESDD_Pos);
+ /* End: Bugfix for FTPAN-25 (IC-9929)*/
+}
+
+/** @brief Call nfc_t2t_internal_set() with data generated based on m_nfcid1_data and m_nfcid1_length variables.
+ */
+static void hal_nfc_internal_bytes_setup(void)
+{
+ if (m_nfcid1_length == NFCID1_TRIPLE_SIZE)
+ {
+ (void) nfc_t2t_internal_set(m_nfcid1_data, T2T_INTERNAL_BYTES_NR);
+ }
+ else
+ {
+ uint8_t nfc_internal[T2T_INTERNAL_BYTES_NR];
+
+ if (m_nfcid1_length == NFCID1_DOUBLE_SIZE)
+ {
+ // CASCADE TAG send over the air, but not included in internal data
+ nfc_internal[0] = m_nfcid1_data[0]; // UID0 = Manufacturer ID
+ nfc_internal[1] = m_nfcid1_data[1]; // UID1
+ nfc_internal[2] = m_nfcid1_data[2]; // UID2
+ nfc_internal[3] = (uint8_t) CASCADE_TAG_BYTE ^ nfc_internal[0] ^
+ nfc_internal[1] ^ nfc_internal[2]; // BCC0 = XOR over the 4 previous bytes
+ nfc_internal[4] = m_nfcid1_data[3]; // UID3
+ nfc_internal[5] = m_nfcid1_data[4]; // UID4
+ nfc_internal[6] = m_nfcid1_data[5]; // UID5
+ nfc_internal[7] = m_nfcid1_data[6]; // UID6
+ nfc_internal[8] = nfc_internal[4] ^ nfc_internal[5] ^
+ nfc_internal[6] ^ nfc_internal[7]; // BCC1 = XOR over the 4 previous bytes
+ nfc_internal[9] = NFC_LIB_VERSION; // For internal use
+ }
+ else // then m_nfcid1_length == NFCID1_SINGLE_SIZE
+ {
+ nfc_internal[0] = m_nfcid1_data[0]; // UID0 = Manufacturer ID
+ nfc_internal[1] = m_nfcid1_data[1]; // UID1
+ nfc_internal[2] = m_nfcid1_data[2]; // UID2
+ nfc_internal[3] = m_nfcid1_data[3]; // UID3
+ nfc_internal[4] = nfc_internal[0] ^ nfc_internal[1] ^
+ nfc_internal[2] ^ nfc_internal[3]; // BCC0 = XOR over the 4 previous bytes
+ memset(&nfc_internal[5], 0xFF, 4); // 4-byte padding
+ nfc_internal[9] = NFC_LIB_VERSION; // For internal use
+ }
+
+ (void) nfc_t2t_internal_set(nfc_internal, T2T_INTERNAL_BYTES_NR);
+ }
+}
+
+ret_code_t hal_nfc_setup(hal_nfc_callback_t callback, void * p_context)
+{
+ m_nfc_lib_callback = callback;
+ m_nfc_lib_context = p_context;
+
+ if (m_nfcid1_length == 0)
+ {
+ m_nfcid1_length = NFCID1_DEFAULT_LENGHT;
+ hal_nfc_nfcid1_default_bytes();
+ }
+
+ hal_nfc_common_hw_setup();
+ hal_nfc_internal_bytes_setup();
+
+ /* Initialize SDK Clock module for handling high precission clock requests */
+ m_clock_handler_item.event_handler = nrf_nfct_clock_event_handler;
+ m_clock_handler_item.p_next = NULL;
+
+ ret_code_t err_code = nrf_drv_clock_init();
+
+#if defined(HAL_NFC_ENGINEERING_BC_FTPAN_WORKAROUND) || defined(HAL_NFC_NRF52840_ENGINEERING_ABC_WORKAROUND)
+ #if defined(HAL_NFC_NRF52840_ENGINEERING_ABC_WORKAROUND)
+ if (!type_52840_sample_check())
+ #endif // defined(HAL_NFC_NRF52840_ENGINEERING_ABC_WORKAROUND)
+ {
+ field_timer_with_callback_config();
+ }
+#endif // defined(HAL_NFC_ENGINEERING_BC_FTPAN_WORKAROUND) || defined(HAL_NFC_NRF52840_ENGINEERING_ABC_WORKAROUND)
+
+ NRF_LOG_INFO("Init");
+ HAL_NFC_DEBUG_PINS_INITIALIZE();
+
+ if ((err_code == NRF_SUCCESS) || (err_code == NRF_ERROR_MODULE_ALREADY_INITIALIZED))
+ {
+ return NRF_SUCCESS;
+ }
+ else
+ {
+ return NRF_ERROR_INTERNAL;
+ }
+}
+
+/**@brief Function for clearing an event flag in NRF_NFCT registers.
+ *
+ * @param[in] p_event Pointer to event register.
+ *
+ */
+static inline void nrf_nfct_event_clear(volatile uint32_t * p_event)
+{
+ *p_event = 0;
+
+ /* Perform read to ensure clearing is effective */
+ volatile uint32_t dummy = *p_event;
+ (void)dummy;
+}
+
+/**@brief Function for handling events from Clock Module.
+ *
+ * @param[in] event Clock event.
+ *
+ */
+static inline void nrf_nfct_clock_event_handler(nrf_drv_clock_evt_type_t event)
+{
+ switch(event)
+ {
+ case NRF_DRV_CLOCK_EVT_HFCLK_STARTED:
+ /* Activate NFCT only when HFXO is running */
+ HAL_NFC_DEBUG_PIN_SET(HAL_NFC_HCLOCK_ON_DEBUG_PIN); //DEBUG!
+
+#ifdef HAL_NFC_NRF52840_ENGINEERING_ABC_WORKAROUND
+ if (type_52840_final_check())
+ {
+ hal_nfc_activate_check();
+ }
+ else
+#endif // HAL_NFC_NRF52840_ENGINEERING_ABC_WORKAROUND
+ {
+ NRF_NFCT->TASKS_ACTIVATE = 1;
+ }
+
+ HAL_NFC_DEBUG_PIN_CLEAR(HAL_NFC_HCLOCK_ON_DEBUG_PIN); //DEBUG!
+ break;
+
+ default:
+ /* No implementation required */
+ break;
+ }
+}
+
+#ifdef HAL_NFC_ENGINEERING_BC_FTPAN_WORKAROUND
+static inline void nrf_nfct_field_lost_hfclk_handle(void)
+{
+ /* Begin: Bugfix for FTPAN-116 (IC-12886) */
+ // reset the NFC for release HFCLK
+ __DMB();
+ NRF_NFCT_POWER = 0;
+ __DMB();
+ NRF_NFCT_POWER = 1;
+ /* END: Bugfix for FTPAN-116 (IC-12886) */
+
+}
+#endif // HAL_NFC_ENGINEERING_BC_FTPAN_WORKAROUND
+
+#ifndef HAL_NFC_ENGINEERING_BC_FTPAN_WORKAROUND
+/**@brief Function for evaluating and handling NFC field events.
+ *
+ * @param[in] field_state Current field state.
+ *
+ */
+static inline void nrf_nfct_field_event_handler(volatile nfct_field_sense_state_t field_state)
+{
+#ifdef HAL_NFC_NRF52840_ENGINEERING_ABC_WORKAROUND
+ bool is_first_sample = type_52840_sample_check();
+
+ if((!is_first_sample) && (m_nfc_fieldevents_filter_active))
+ {
+ return;
+ }
+#endif // HAL_NFC_NRF52840_ENGINEERING_ABC_WORKAROUND
+
+ if (field_state == NFC_FIELD_STATE_UNKNOWN)
+ {
+ /* Probe NFC field */
+ uint32_t field_present = NRF_NFCT->FIELDPRESENT;
+
+ if (field_present & m_nfc_fieldpresent_mask)
+ {
+ field_state = NFC_FIELD_STATE_ON;
+ }
+ else
+ {
+ field_state = NFC_FIELD_STATE_OFF;
+ }
+ }
+
+ /* Field event service */
+ switch(field_state)
+ {
+ case NFC_FIELD_STATE_ON:
+ if (!m_field_on)
+ {
+ HAL_NFC_DEBUG_PIN_SET(HAL_NFC_HCLOCK_ON_DEBUG_PIN); //DEBUG!
+ nrf_drv_clock_hfclk_request(&m_clock_handler_item);
+
+#ifdef HAL_NFC_NRF52840_ENGINEERING_ABC_WORKAROUND
+ /* Begin: Bugfix for FTPAN-190 */
+ if (!is_first_sample)
+ {
+ m_nfc_activate_conditions = 0;
+ m_nfc_fieldevents_filter_active = true;
+
+ NRF_TIMER4->TASKS_CLEAR = 1;
+ NRF_TIMER4->TASKS_START = 1;
+ }
+ /* END: Bugfix for FTPAN-190 */
+#endif // HAL_NFC_NRF52840_ENGINEERING_ABC_WORKAROUND
+
+ HAL_NFC_DEBUG_PIN_CLEAR(HAL_NFC_HCLOCK_ON_DEBUG_PIN); //DEBUG!
+ }
+ m_field_on = true;
+ break;
+
+ case NFC_FIELD_STATE_OFF:
+ HAL_NFC_DEBUG_PIN_SET(HAL_NFC_HCLOCK_OFF_DEBUG_PIN); //DEBUG!
+
+#ifdef HAL_NFC_NRF52840_ENGINEERING_ABC_WORKAROUND
+ /* Begin: Bugfix for FTPAN-116 (IC-12886) */
+ if (is_first_sample)
+ {
+ *(volatile uint32_t *)0x40005010 = 1;
+ }
+ /* END: Bugfix for FTPAN-116 (IC-12886) */
+#endif // HAL_NFC_NRF52840_ENGINEERING_ABC_WORKAROUND
+
+ NRF_NFCT->TASKS_SENSE = 1;
+ nrf_drv_clock_hfclk_release();
+ m_field_on = false;
+
+ NRF_NFCT->INTENCLR =
+ (NFCT_INTENCLR_RXFRAMEEND_Clear << NFCT_INTENCLR_RXFRAMEEND_Pos) |
+ (NFCT_INTENCLR_RXERROR_Clear << NFCT_INTENCLR_RXERROR_Pos);
+
+ /* Change mask to FIELD_OFF state - trigger FIELD_ON even if HW has not locked to the field */
+ m_nfc_fieldpresent_mask = NFC_FIELD_OFF_MASK;
+
+ if ((m_nfc_lib_callback != NULL) )
+ {
+ m_nfc_lib_callback(m_nfc_lib_context, HAL_NFC_EVENT_FIELD_OFF, 0, 0);
+ }
+
+ HAL_NFC_DEBUG_PIN_CLEAR(HAL_NFC_HCLOCK_OFF_DEBUG_PIN); //DEBUG!
+ break;
+
+ default:
+ /* No implementation required */
+ break;
+ }
+}
+#endif // HAL_NFC_ENGINEERING_BC_FTPAN_WORKAROUND
+
+
+/** @brief Writes default values to m_nfcid1_data based on NRF_FICR->NFC registers.
+ */
+static void hal_nfc_nfcid1_default_bytes(void)
+{
+ uint32_t nfc_tag_header0 = NRF_FICR->NFC.TAGHEADER0;
+ uint32_t nfc_tag_header1 = NRF_FICR->NFC.TAGHEADER1;
+ uint32_t nfc_tag_header2 = NRF_FICR->NFC.TAGHEADER2;
+
+ m_nfcid1_data[0] = (uint8_t) LSB_32(nfc_tag_header0 >> 0);
+ m_nfcid1_data[1] = (uint8_t) LSB_32(nfc_tag_header0 >> 8);
+ m_nfcid1_data[2] = (uint8_t) LSB_32(nfc_tag_header0 >> 16);
+ m_nfcid1_data[3] = (uint8_t) LSB_32(nfc_tag_header1 >> 0);
+ m_nfcid1_data[4] = (uint8_t) LSB_32(nfc_tag_header1 >> 8);
+ m_nfcid1_data[5] = (uint8_t) LSB_32(nfc_tag_header1 >> 16);
+ m_nfcid1_data[6] = (uint8_t) LSB_32(nfc_tag_header1 >> 24);
+ m_nfcid1_data[7] = (uint8_t) LSB_32(nfc_tag_header2 >> 0);
+ m_nfcid1_data[8] = (uint8_t) LSB_32(nfc_tag_header2 >> 8);
+ m_nfcid1_data[9] = (uint8_t) LSB_32(nfc_tag_header2 >> 16);
+}
+
+
+/** @brief Resets NFCT peripheral to its default state before automatic collision resolution
+ * procedure.
+ */
+static inline void nrf_nfct_default_state_reset(void)
+{
+ if (NRF_NFCT_DEFAULTSTATESLEEP & NRF_NFCT_DEFAULTSTATESLEEP_MSK) // Default state is SLEEP_A
+ {
+ NRF_NFCT->TASKS_GOSLEEP = 1;
+ }
+ else // Default state is IDLE
+ {
+ NRF_NFCT->TASKS_GOIDLE = 1;
+ }
+
+ /* Disable RX here (will be enabled at SELECTED) */
+ NRF_NFCT->INTENCLR = NFCT_INTENCLR_RXFRAMEEND_Clear <<
+ NFCT_INTENCLR_RXFRAMEEND_Pos;
+}
+
+
+ret_code_t hal_nfc_parameter_set(hal_nfc_param_id_t id, void * p_data, size_t data_length)
+{
+ if (id == HAL_NFC_PARAM_ID_NFCID1)
+ {
+ if (data_length == 1)
+ {
+ uint8_t id_length = *((uint8_t *) p_data);
+ if (id_length == NFCID1_SINGLE_SIZE || id_length == NFCID1_DOUBLE_SIZE ||
+ id_length == NFCID1_TRIPLE_SIZE)
+ {
+ m_nfcid1_length = id_length;
+ hal_nfc_nfcid1_default_bytes();
+ }
+ else
+ {
+ return NRF_ERROR_INVALID_LENGTH;
+ }
+ }
+ else if (data_length == NFCID1_SINGLE_SIZE || data_length == NFCID1_DOUBLE_SIZE ||
+ data_length == NFCID1_TRIPLE_SIZE)
+ {
+ m_nfcid1_length = (uint8_t) data_length;
+ memcpy(m_nfcid1_data, p_data, data_length);
+ }
+ else
+ {
+ return NRF_ERROR_INVALID_LENGTH;
+ }
+ hal_nfc_nfcid1_registers_setup();
+ hal_nfc_internal_bytes_setup();
+ }
+
+ return NRF_SUCCESS;
+}
+
+ret_code_t hal_nfc_parameter_get(hal_nfc_param_id_t id, void * p_data, size_t * p_max_data_length)
+{
+ if (id == HAL_NFC_PARAM_ID_NFCID1)
+ {
+ if (m_nfcid1_length == 0)
+ {
+ m_nfcid1_length = NFCID1_DEFAULT_LENGHT;
+ hal_nfc_nfcid1_default_bytes();
+ }
+
+ if (*p_max_data_length < (size_t) m_nfcid1_length)
+ {
+ return NRF_ERROR_DATA_SIZE;
+ }
+
+ *p_max_data_length = (size_t) m_nfcid1_length;
+ memcpy(p_data, m_nfcid1_data, m_nfcid1_length);
+ }
+
+ return NRF_SUCCESS;
+}
+
+
+ret_code_t hal_nfc_start(void)
+{
+ NRF_NFCT->ERRORSTATUS = NRF_NFCT_ERRORSTATUS_ALL;
+ NRF_NFCT->TASKS_SENSE = 1;
+
+ NVIC_ClearPendingIRQ(NFCT_IRQn);
+ NVIC_SetPriority(NFCT_IRQn, NFCT_CONFIG_IRQ_PRIORITY);
+ NVIC_EnableIRQ(NFCT_IRQn);
+
+ NRF_LOG_INFO("Start");
+ return NRF_SUCCESS;
+}
+
+ret_code_t hal_nfc_send(const uint8_t * p_data, size_t data_length)
+{
+ if (data_length == 0)
+ {
+ return NRF_ERROR_DATA_SIZE;
+ }
+
+ /* Ignore previous TX END events, SW takes care only for data frames which tranmission is triggered in this function */
+ nrf_nfct_event_clear(&NRF_NFCT->EVENTS_TXFRAMEEND);
+
+ NRF_NFCT->PACKETPTR = (uint32_t) p_data;
+ NRF_NFCT->TXD.AMOUNT = (data_length << NFCT_TXD_AMOUNT_TXDATABYTES_Pos) &
+ NFCT_TXD_AMOUNT_TXDATABYTES_Msk;
+ NRF_NFCT->INTENSET = (NFCT_INTENSET_TXFRAMEEND_Enabled << NFCT_INTENSET_TXFRAMEEND_Pos);
+ NRF_NFCT->TASKS_STARTTX = 1;
+
+ NRF_LOG_INFO("Send");
+ return NRF_SUCCESS;
+}
+
+ret_code_t hal_nfc_stop(void)
+{
+ NRF_NFCT->TASKS_DISABLE = 1;
+
+ NRF_LOG_INFO("Stop");
+ return NRF_SUCCESS;
+}
+
+ret_code_t hal_nfc_done(void)
+{
+ m_nfc_lib_callback = (hal_nfc_callback_t) NULL;
+
+ return NRF_SUCCESS;
+}
+
+void NFCT_IRQHandler(void)
+{
+ nfct_field_sense_state_t current_field = NFC_FIELD_STATE_NONE;
+
+ HAL_NFC_DEBUG_PIN_SET(HAL_NFC_NFC_EVENT_DEBUG_PIN); //DEBUG!
+
+ if (NRF_NFCT->EVENTS_FIELDDETECTED && (NRF_NFCT->INTEN & NFCT_INTEN_FIELDDETECTED_Msk))
+ {
+ nrf_nfct_event_clear(&NRF_NFCT->EVENTS_FIELDDETECTED);
+ HAL_NFC_DEBUG_PIN_SET(HAL_NFC_DETECT_EVENT_DEBUG_PIN); //DEBUG!
+ current_field = NFC_FIELD_STATE_ON;
+ HAL_NFC_DEBUG_PIN_CLEAR(HAL_NFC_DETECT_EVENT_DEBUG_PIN); //DEBUG!
+
+ NRF_LOG_DEBUG("Field detected");
+ }
+
+#ifndef HAL_NFC_ENGINEERING_BC_FTPAN_WORKAROUND
+ if (NRF_NFCT->EVENTS_FIELDLOST && (NRF_NFCT->INTEN & NFCT_INTEN_FIELDLOST_Msk))
+ {
+ nrf_nfct_event_clear(&NRF_NFCT->EVENTS_FIELDLOST);
+ current_field =
+ (current_field == NFC_FIELD_STATE_NONE) ? NFC_FIELD_STATE_OFF : NFC_FIELD_STATE_UNKNOWN;
+
+ NRF_LOG_DEBUG("Field lost");
+ }
+#endif // HAL_NFC_ENGINEERING_BC_FTPAN_WORKAROUND
+
+ /* Perform actions if any FIELD event is active */
+ if (current_field != NFC_FIELD_STATE_NONE)
+ {
+ nrf_nfct_field_event_handler(current_field);
+ }
+
+ if (NRF_NFCT->EVENTS_RXFRAMEEND && (NRF_NFCT->INTEN & NFCT_INTEN_RXFRAMEEND_Msk))
+ {
+ /* Take into account only number of whole bytes */
+ uint32_t rx_status = 0;
+ uint32_t rx_data_size = ((NRF_NFCT->RXD.AMOUNT & NFCT_RXD_AMOUNT_RXDATABYTES_Msk) >>
+ NFCT_RXD_AMOUNT_RXDATABYTES_Pos) - NFC_CRC_SIZE;
+ nrf_nfct_event_clear(&NRF_NFCT->EVENTS_RXFRAMEEND);
+
+
+ if (NRF_NFCT->EVENTS_RXERROR && (NRF_NFCT->INTEN & NFCT_INTEN_RXERROR_Msk))
+ {
+ rx_status = (NRF_NFCT->FRAMESTATUS.RX & NRF_NFCT_FRAMESTATUS_RX_MSK);
+ nrf_nfct_event_clear(&NRF_NFCT->EVENTS_RXERROR);
+
+ NRF_LOG_DEBUG("Rx error (0x%x)", (unsigned int) rx_status);
+
+ /* Clear rx frame status */
+ NRF_NFCT->FRAMESTATUS.RX = NRF_NFCT_FRAMESTATUS_RX_MSK;
+ }
+
+ /* Go back to idle state if NFC-A frame with Transmission Errors occurs. */
+ if (rx_status)
+ {
+ nrf_nfct_default_state_reset();
+ }
+ else
+ {
+ /* Look for Tag 2 Type READ Command */
+ if (m_nfc_rx_buffer[0] == T2T_READ_CMD)
+ {
+ if (m_nfc_lib_callback != NULL)
+ {
+ /* This callback should trigger transmission of READ Response */
+ m_nfc_lib_callback(m_nfc_lib_context,
+ HAL_NFC_EVENT_DATA_RECEIVED,
+ (void*)m_nfc_rx_buffer,
+ rx_data_size);
+ }
+ }
+ else
+ {
+ /* Indicate that SLP_REQ was received - this will cause FRAMEDELAYTIMEOUT error */
+ if (m_nfc_rx_buffer[0] == NFC_SLP_REQ_CMD)
+ {
+ m_slp_req_received = true;
+ /* No need to parse incoming frames, wait for SELECTED */
+ NRF_NFCT->INTENCLR = NFCT_INTENCLR_RXFRAMEEND_Clear <<
+ NFCT_INTENCLR_RXFRAMEEND_Pos;
+ }
+ else
+ {
+ nrf_nfct_default_state_reset();
+ }
+ }
+ }
+
+ NRF_LOG_DEBUG("Rx fend");
+ }
+
+ if (NRF_NFCT->EVENTS_TXFRAMEEND && (NRF_NFCT->INTEN & NFCT_INTEN_TXFRAMEEND_Msk))
+ {
+ nrf_nfct_event_clear(&NRF_NFCT->EVENTS_TXFRAMEEND);
+
+ /* Disable TX END event to ignore frame transmission other than READ response */
+ NRF_NFCT->INTENCLR = (NFCT_INTENCLR_TXFRAMEEND_Clear << NFCT_INTENCLR_TXFRAMEEND_Pos);
+
+ /* Set up for reception */
+ NRF_NFCT->PACKETPTR = (uint32_t) m_nfc_rx_buffer;
+ NRF_NFCT->MAXLEN = NFC_RX_BUFFER_SIZE;
+ NRF_NFCT->TASKS_ENABLERXDATA = 1;
+
+ if (m_nfc_lib_callback != NULL)
+ {
+ m_nfc_lib_callback(m_nfc_lib_context, HAL_NFC_EVENT_DATA_TRANSMITTED, 0, 0);
+ }
+
+ NRF_LOG_DEBUG("Tx fend");
+ }
+
+ if (NRF_NFCT->EVENTS_SELECTED && (NRF_NFCT->INTEN & NFCT_INTEN_SELECTED_Msk))
+ {
+ nrf_nfct_event_clear(&NRF_NFCT->EVENTS_SELECTED);
+ /* Clear also RX END and RXERROR events because SW does not take care of commands which were received before selecting the tag */
+ nrf_nfct_event_clear(&NRF_NFCT->EVENTS_RXFRAMEEND);
+ nrf_nfct_event_clear(&NRF_NFCT->EVENTS_RXERROR);
+
+ /* Set up registers for EasyDMA and start receiving packets */
+ NRF_NFCT->PACKETPTR = (uint32_t) m_nfc_rx_buffer;
+ NRF_NFCT->MAXLEN = NFC_RX_BUFFER_SIZE;
+ NRF_NFCT->TASKS_ENABLERXDATA = 1;
+
+ NRF_NFCT->INTENSET = (NFCT_INTENSET_RXFRAMEEND_Enabled << NFCT_INTENSET_RXFRAMEEND_Pos) |
+ (NFCT_INTENSET_RXERROR_Enabled << NFCT_INTENSET_RXERROR_Pos);
+
+ /* At this point any previous error status can be ignored */
+ NRF_NFCT->FRAMESTATUS.RX = NRF_NFCT_FRAMESTATUS_RX_MSK;
+ NRF_NFCT->ERRORSTATUS = NRF_NFCT_ERRORSTATUS_ALL;
+
+#ifndef HAL_NFC_ENGINEERING_BC_FTPAN_WORKAROUND
+ /* Change mask to FIELD_ON state - trigger FIELD_ON only if HW has locked to the field */
+ m_nfc_fieldpresent_mask = NFC_FIELD_ON_MASK;
+#endif
+
+ if (m_nfc_lib_callback != NULL)
+ {
+ m_nfc_lib_callback(m_nfc_lib_context, HAL_NFC_EVENT_FIELD_ON, 0, 0);
+ }
+
+ NRF_LOG_DEBUG("Selected");
+ }
+
+ if (NRF_NFCT->EVENTS_ERROR && (NRF_NFCT->INTEN & NFCT_INTEN_ERROR_Msk))
+ {
+ uint32_t err_status = NRF_NFCT->ERRORSTATUS;
+ nrf_nfct_event_clear(&NRF_NFCT->EVENTS_ERROR);
+
+ /* Clear FRAMEDELAYTIMEOUT error (expected HW behaviour) when SLP_REQ command was received */
+ if ((err_status & NFCT_ERRORSTATUS_FRAMEDELAYTIMEOUT_Msk) && m_slp_req_received)
+ {
+ NRF_NFCT->ERRORSTATUS = NFCT_ERRORSTATUS_FRAMEDELAYTIMEOUT_Msk;
+ m_slp_req_received = false;
+
+ NRF_LOG_DEBUG("RX: SLP_REQ");
+ }
+ /* Report any other error */
+ err_status &= ~NFCT_ERRORSTATUS_FRAMEDELAYTIMEOUT_Msk;
+ if (err_status)
+ {
+ NRF_LOG_DEBUG("Error (0x%x)", (unsigned int) err_status);
+ }
+
+ /* Clear error status */
+ NRF_NFCT->ERRORSTATUS = NRF_NFCT_ERRORSTATUS_ALL;
+ }
+
+ HAL_NFC_DEBUG_PIN_CLEAR(HAL_NFC_NFC_EVENT_DEBUG_PIN); //DEBUG!
+}
+
+
+#ifdef HAL_NFC_ENGINEERING_BC_FTPAN_WORKAROUND
+
+#ifdef HAL_NFC_NRF52840_ENGINEERING_ABC_WORKAROUND
+ #error Wrong workaround combination
+#endif
+
+static uint32_t field_state_cnt = 0;
+/**
+ * @brief Function for evaluating and handling NFC fieldlost event.
+ */
+static void hal_nfc_field_check(void)
+{
+ uint32_t nfc_fieldpresen_masked;
+
+ nfc_fieldpresen_masked = NRF_NFCT->FIELDPRESENT & NFC_HAL_FIELDPRESENT_MASK;
+
+ if (nfc_fieldpresen_masked == NFC_HAL_FIELDPRESENT_IS_LOST)
+ {
+ ++field_state_cnt;
+ if (field_state_cnt > 7)
+ {
+ HAL_NFC_DEBUG_PIN_SET(HAL_NFC_HCLOCK_OFF_DEBUG_PIN); //DEBUG!
+
+ NRF_TIMER4->TASKS_SHUTDOWN = 1;
+
+ nrf_drv_clock_hfclk_release();
+
+ nrf_nfct_field_lost_hfclk_handle();
+
+ if ((m_nfc_lib_callback != NULL))
+ {
+ m_nfc_lib_callback(m_nfc_lib_context, HAL_NFC_EVENT_FIELD_OFF, 0, 0);
+ }
+ m_field_on = false;
+
+ /* Begin: Bugfix for FTPAN-116 (IC-12886) */
+ // resume the NFCT to initialized state
+ hal_nfc_re_setup();
+ /* End: Bugfix for FTPAN-116 (IC-12886) */
+
+ HAL_NFC_DEBUG_PIN_CLEAR(HAL_NFC_HCLOCK_OFF_DEBUG_PIN); //DEBUG!
+ }
+
+ return;
+ }
+
+ field_state_cnt = 0;
+}
+
+/**
+ * @brief Function for enablinge hight precision clock and start eveluating fieldlost event.
+ */
+static inline void nrf_nfct_field_event_handler(volatile nfct_field_sense_state_t field_state)
+{
+ if (!m_field_on)
+ {
+ HAL_NFC_DEBUG_PIN_SET(HAL_NFC_HCLOCK_ON_DEBUG_PIN); //DEBUG!
+ nrf_drv_clock_hfclk_request(&m_clock_handler_item);
+
+ NRF_TIMER4->TASKS_CLEAR = 1;
+ NRF_TIMER4->TASKS_START = 1;
+ field_state_cnt = 0;
+
+ HAL_NFC_DEBUG_PIN_CLEAR(HAL_NFC_HCLOCK_ON_DEBUG_PIN); //DEBUG!
+ }
+ m_field_on = true;
+}
+
+/**
+ * @brief Function for resume the NFCT to initialized state after software's reset.
+ */
+static inline void hal_nfc_re_setup(void)
+{
+ hal_nfc_common_hw_setup();
+
+ NRF_LOG_INFO("Reinitialize");
+}
+#endif // HAL_NFC_ENGINEERING_BC_FTPAN_WORKAROUND
+
+#endif // NFC_T2T_HAL_ENABLED
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/t2t_lib/hal_t2t/hal_nfc_t2t.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/t2t_lib/hal_t2t/hal_nfc_t2t.h
new file mode 100644
index 0000000..12b9d93
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/t2t_lib/hal_t2t/hal_nfc_t2t.h
@@ -0,0 +1,203 @@
+/**
+ * Copyright (c) 2015 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+
+#ifndef HAL_NFC_H__
+#define HAL_NFC_H__
+
+/** @file
+ * @defgroup nfc_t2t_hal NFC Type 2 Tag HAL
+ * @{
+ * @ingroup nfc_t2t
+ * @brief @tagAPI52 Hardware abstraction layer for the NFC Type 2 Tag library.
+ *
+ * @note Before the NFCT peripheral enters ACTIVATED state, the HFXO must be running.
+ * To fulfill this requirement and allow other software modules to also request the HFXO, the NFC Type 4 Tag HAL uses @ref nrf_drv_clock module.
+ *
+ */
+
+#include <stdint.h>
+#include <string.h>
+#include <sdk_errors.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** @brief Events passed to the upper-layer callback function. */
+typedef enum {
+ HAL_NFC_EVENT_FIELD_ON, ///< Field is detected.
+ HAL_NFC_EVENT_FIELD_OFF, ///< Field is lost.
+ HAL_NFC_EVENT_DATA_RECEIVED, ///< Data is received.
+ HAL_NFC_EVENT_DATA_TRANSMITTED ///< Data is Transmitted.
+} hal_nfc_event_t;
+
+
+/** @brief Parameter IDs for set/get function. */
+typedef enum {
+ HAL_NFC_PARAM_ID_TESTING, ///< Used for unit tests.
+ HAL_NFC_PARAM_ID_NFCID1, /**< NFCID1 value, data can be 4, 7, or 10 bytes long (single, double, or triple size).
+ To use default NFCID1 of specific length pass one byte containing requested length.
+ Default 7-byte NFCID1 will be used if this parameter was not set. This parameter can be
+ set before nfc_t2t_setup() to set initial NFCID1 and it can be changed later. */
+ HAL_NFC_PARAM_ID_UNKNOWN
+} hal_nfc_param_id_t;
+
+
+/** @brief Callback from HAL_NFC layer into the upper layer.
+ *
+ * If event == HAL_NFC_EVENT_DATA_RECEIVED:
+ * p_data points to the received packet. The memory belongs to the HAL_NFC layer and
+ * is guaranteed to be valid only until the callback returns.
+ *
+ * If event == HAL_NFC_EVENT_DATA_TRANSMITTED:
+ * p_data points to the transmitted packet. The memory belongs to the application.
+ *
+ * If event == \<Other event\>:
+ * p_data definition is event-specific (to be defined).
+ *
+ * @param[in] p_context Context for callback execution.
+ * @param[in] event The event that occurred.
+ * @param[in] p_data Received/transmitted data or NULL.
+ * @param[in] data_length Size of the received/transmitted packet.
+ */
+typedef void (* hal_nfc_callback_t)(void * p_context,
+ hal_nfc_event_t event,
+ const uint8_t * p_data,
+ size_t data_length);
+
+
+/** @brief Function for initializing the NFC layer.
+ *
+ * This function provides a pointer to a callback function and the callback context
+ * to the NFC layer.
+ *
+ * @param[in] callback Pointer to the callback function.
+ * @param[in] p_context Context of callback.
+ *
+ * @retval NRF_SUCCESS If the NFC layer was initialized successfully. If one
+ * of the arguments was invalid, an error code is returned.
+ */
+ret_code_t hal_nfc_setup(hal_nfc_callback_t callback, void * p_context);
+
+
+/** @brief Function for setting a HAL_NFC parameter.
+ *
+ * This function allows to set any parameter defined as available by HAL_NFC.
+ *
+ * @param[in] id ID of the parameter to set.
+ * @param[in] p_data Pointer to the buffer containing the data to set.
+ * @param[in] data_length Size of the buffer containing the data to set.
+ *
+ * @retval NRF_SUCCESS If the parameter was set successfully. If one of the arguments
+ * was invalid (for example, wrong data length), an error code
+ * is returned.
+ */
+ret_code_t hal_nfc_parameter_set(hal_nfc_param_id_t id, void * p_data, size_t data_length);
+
+
+/** @brief Function for querying a HAL_NFC parameter value.
+ *
+ * The queried value will be placed into the passed data buffer. If the buffer
+ * is too small, maxDataLength will contain the required buffer size.
+ *
+ * @param[in] id ID of the parameter to query.
+ * @param[in] p_data Pointer to a buffer receiving the queried data.
+ * @param[in, out] p_max_data_length Size of the buffer. It receives the required size if buffer is too small.
+ *
+ * @retval NRF_SUCCESS If the parameter was received successfully. If one of the arguments
+ * was invalid (for example, the buffer was too small), an error code
+ * is returned.
+ */
+ret_code_t hal_nfc_parameter_get(hal_nfc_param_id_t id, void * p_data, size_t * p_max_data_length);
+
+
+/** @brief Function for starting the NFC subsystem.
+ *
+ * After this function completes, NFC readers will be able to detect the chip.
+ *
+ * @retval NRF_SUCCESS If the NFC subsystem was started successfully. If the NFC
+ * subsystem could not be started, an error code is returned.
+ */
+ret_code_t hal_nfc_start(void);
+
+
+/** @brief Function for sending a packet to the connected NFC reader.
+ *
+ * The provided data buffer belongs to the caller and is guaranteed to be
+ * valid until the HAL_NFC_EVENT_DATA_TRANSMITTED event is received by the
+ * callback.
+ *
+ * @note Provided pointer must point to RAM region.
+ *
+ * @param[in] p_data Pointer to the memory area in RAM containing data packet to send.
+ * @param[in] data_length Size of the packet in bytes.
+ *
+ * @retval NRF_SUCCESS If the packet was sent. Otherwise, an error code is returned.
+ */
+ret_code_t hal_nfc_send(const uint8_t * p_data, size_t data_length);
+
+
+/** @brief Function for stopping the NFC subsystem.
+ *
+ * After this function returns, NFC readers will no longer be able to connect
+ * to the chip.
+ *
+ * @retval NRF_SUCCESS If the NFC subsystem was stopped. Otherwise, an error code
+ * is returned.
+ */
+ret_code_t hal_nfc_stop(void);
+
+
+/** @brief Function for releasing resources.
+ *
+ * After this call returns, the callback is considered invalid and no more
+ * events will be posted to it.
+ *
+ * @retval NRF_SUCCESS This function always succeeds.
+ */
+ret_code_t hal_nfc_done(void);
+
+#ifdef __cplusplus
+}
+#endif
+
+/** @} */
+#endif /* HAL_NFC_H__ */
+
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/t2t_lib/license.txt b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/t2t_lib/license.txt
new file mode 100644
index 0000000..c64e22b
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/t2t_lib/license.txt
@@ -0,0 +1,36 @@
+Copyright (c) 2015 - 2018, Telit Communications Cyprus Ltd
+
+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, except as embedded into a Nordic
+ Semiconductor ASA integrated circuit in a product or a software update for
+ such product, 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.
+
+4. This software, with or without modification, must only be used with a
+ Nordic Semiconductor ASA integrated circuit.
+
+5. Any software provided in binary form under this license must not be reverse
+ engineered, decompiled, modified and/or disassembled.
+
+THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/t2t_lib/nfc_fixes.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/t2t_lib/nfc_fixes.h
new file mode 100644
index 0000000..1ae29d0
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/t2t_lib/nfc_fixes.h
@@ -0,0 +1,133 @@
+/**
+ * Copyright (c) 2015 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+
+#ifndef NFC_FIXES_H__
+#define NFC_FIXES_H__
+
+#include <stdint.h>
+#include <stdbool.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** @file
+ * @defgroup nfc_fixes NFC fixes and workarounds
+ * @{
+ * @ingroup nfc_t2t
+ * @brief @tagAPI52 Fixes for hardware-related anomalies.
+ *
+ * If you are using PCA10040 (part of nRF52 Development Kit),
+ * you must define the macro HAL_NFC_ENGINEERING_BC_FTPAN_WORKAROUND in order to apply
+ * workarounds for the following anomalies:
+ * - 79. NFCT: A false EVENTS_FIELDDETECTED event occurs after the field is lost.
+ * - 116. NFCT does not release HFCLK when switching from ACTIVATED to SENSE mode.
+ *
+ * If you are using PCA10056 Engineering A (part of nRF52840 Development Kit),
+ * you must define the macro HAL_NFC_NRF52840_ENGINEERING_ABC_WORKAROUND in order to apply
+ * workarounds for the following anomalies:
+ * - 98. NFCT: The NFCT is not able to communicate with the peer.
+ * - 116. NFCT does not release HFCLK when switching from ACTIVATED to SENSE mode.
+ * - 144. NFCT: Not optimal NFC performance
+ *
+ * If you are using PCA10056 Engineering B or C (part of nRF52840 Development Kit),
+ * you must define the macro HAL_NFC_NRF52840_ENGINEERING_ABC_WORKAROUND in order to apply
+ * workarounds for the following anomalies:
+ * - 190. NFCT: Event FIELDDETECTED may be generated too early.
+ *
+ * The use of implemented workarounds for PCA10056 are determined at the runtime and depends
+ * on the chip variant.
+ *
+ * The current code contains a patch for anomaly 25 (NFCT: Reset value of
+ * SENSRES register is incorrect), so that it now works on Windows Phone.
+ */
+
+#ifdef BOARD_PCA10040 // assume nRF52832 chip in IC rev. Engineering B or Engineering C
+ #define HAL_NFC_ENGINEERING_BC_FTPAN_WORKAROUND
+#elif defined(BOARD_PCA10056) // assume nRF52840 chip in IC rev. Engineering A, B or C
+ #define HAL_NFC_NRF52840_ENGINEERING_ABC_WORKAROUND
+#endif
+
+
+/**
+ * @brief Internal auxiliary function to check if the program is running on NRF52840 chip
+ * @retval true It is NRF52480 chip
+ * @retval false It is other chip
+ */
+static inline bool type_52840_check(void)
+{
+ return ((((*(uint32_t *)0xF0000FE0) & 0xFF) == 0x08) &&
+ (((*(uint32_t *)0xF0000FE4) & 0x0F) == 0x0));
+}
+
+/**
+ * @brief Internal auxiliary function to check if the program is running on first sample of
+ * NRF52840 chip
+ * @retval true It is NRF52480 chip and it is first sample version
+ * @retval false It is other chip
+ */
+static inline bool type_52840_sample_check(void)
+{
+ return ( type_52840_check() &&
+ ( ((*(uint32_t *)0xF0000FE8) & 0xF0) == 0x00 ) &&
+ ( ((*(uint32_t *)0xF0000FEC) & 0xF0) == 0x00 ) );
+}
+
+/**
+ * @brief Internal auxiliary function to check if the program is running on final version of
+ * NRF52840 chip
+ * @retval true It is NRF52480 chip and it is final version
+ * @retval false It is other chip
+ */
+static inline bool type_52840_final_check(void)
+{
+ return ( type_52840_check() &&
+ ( ( ((*(uint32_t *)0xF0000FE8) & 0xF0) != 0x00 ) ||
+ ( ((*(uint32_t *)0xF0000FEC) & 0xF0) != 0x00 ) ));
+}
+
+/** @} */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* NFC_FIXES_H__ */
+
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/t2t_lib/nfc_t2t_lib.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/t2t_lib/nfc_t2t_lib.h
new file mode 100644
index 0000000..cfb88b7
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/t2t_lib/nfc_t2t_lib.h
@@ -0,0 +1,275 @@
+/**
+ * Copyright (c) 2015 - 2018, Telit Communications Cyprus Ltd
+ *
+ * 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+
+#ifndef NFC_T2T_LIB_H__
+#define NFC_T2T_LIB_H__
+
+/** @file
+ *
+ * @addtogroup nfc_api
+ *
+ * @defgroup nfc_t2t NFC Type 2 Tag
+ * @ingroup nfc_api
+ * @brief Implementation of NFC Type 2 Tag.
+ *
+ * @defgroup nfc_t2t_lib NFC tag 2 type emulation library
+ * @{
+ * @ingroup nfc_t2t
+ * @brief The T2T emulation library interface.
+ */
+
+#include <string.h>
+#include <sdk_errors.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define NFC_T2T_SIZEOF_INTERNAL_BYTES 10 ///< T2T internal byte size.
+#define NFC_T2T_MAX_PAYLOAD_SIZE 988 ///< Maximum NDEF message size.
+#define NFC_T2T_MAX_PAYLOAD_SIZE_RAW 1008 ///< No NDEF-TLV and no implicit lock bytes at the end.
+
+/** @brief Events passed to the callback function. */
+typedef enum
+{
+ NFC_T2T_EVENT_NONE,
+ ///< Not used.
+
+ NFC_T2T_EVENT_FIELD_ON,
+ ///< NFC tag has detected external NFC field and was selected by an NFC polling device.
+
+ NFC_T2T_EVENT_FIELD_OFF,
+ ///< External NFC field has been removed.
+
+ NFC_T2T_EVENT_DATA_READ,
+ ///< NFC polling device has read all tag data.
+ /**<
+ * Repeated reading in the same session i.e. before @ref NFC_T2T_EVENT_FIELD_OFF event,
+ * will not trigger another @ref NFC_T2T_EVENT_DATA_READ event.
+ */
+
+ NFC_T2T_EVENT_STOPPED
+ ///< Reference to the application NFC callback has been released using @ref nfc_t2t_done.
+} nfc_t2t_event_t;
+
+typedef enum
+{
+ NFC_T2T_PARAM_TESTING, ///< Used for unit tests.
+ NFC_T2T_PARAM_NFCID1, /**< NFCID1 value, data can be 4, 7, or 10 bytes long (single, double, or triple size).
+ To use default NFCID1 of specific length pass one byte containing requested length.
+ Default 7-byte NFCID1 will be used if this parameter was not set. This parameter can be
+ set before nfc_t2t_setup() to set initial NFCID1 and it can be changed later. */
+} nfc_t2t_param_id_t;
+
+/** @brief Callback to pass events from NFC T2T Library to application.
+ *
+ * @param[in] p_context Application context for callback execution.
+ * @param[in] event The event that occurred.
+ * @param[in] p_data Data to send to the application (event specific).
+ * @param[in] data_length Length of the data.
+ */
+typedef void (*nfc_t2t_callback_t)(void * p_context,
+ nfc_t2t_event_t event,
+ const uint8_t * p_data,
+ size_t data_length);
+
+/** @brief Function for registering the application callback for event signaling.
+ *
+ * The callback will be called by NFC T2T Library to notify the application of relevant
+ * events. It will be called from the HAL_NFC callback context.
+ *
+ * @param[in] callback Function pointer to the callback.
+ * @param[in] p_context Pointer to a memory area used by the callback for execution (optional).
+ *
+ * @retval NRF_SUCCESS If the application callback was registered successfully. If one
+ * of the arguments was invalid, an error code is returned.
+ */
+ret_code_t nfc_t2t_setup(nfc_t2t_callback_t callback, void * p_context);
+
+/** @brief Function for setting an NFC parameter.
+ *
+ * @note Not implemented. For future use.
+ *
+ * This function allows to set any parameter defined as available by HAL_NFC.
+ *
+ * @param[in] id ID of the parameter to set.
+ * @param[in] p_data Pointer to a buffer containing the data to set.
+ * @param[in] data_length Size of the buffer containing the data to set.
+ *
+ * @retval NRF_SUCCESS If the parameter was set successfully. If one of the arguments
+ * was invalid (for example, a wrong data length), an error code
+ * is returned.
+ */
+ret_code_t nfc_t2t_parameter_set(nfc_t2t_param_id_t id, void * p_data, size_t data_length);
+
+/** @brief Function for querying an NFC parameter value.
+ *
+ * @note Not implemented. For future use.
+ *
+ * The queried value will be placed into the passed data buffer. If the buffer
+ * is too small, p_max_data_length will contain the required buffer size. If the
+ * buffer is big enough, p_max_data_length will contain the actual size of the
+ * data.
+ *
+ * @param[in] id ID of the parameter to query.
+ * @param[in] p_data Pointer to a buffer receiving the queried data.
+ * @param[in, out] p_max_data_length Size of the buffer, receives actual size of queried data.
+ *
+ * @retval NRF_SUCCESS If the parameter was received successfully. If one of the arguments
+ * was invalid (for example, the buffer was too small), an error code
+ * is returned.
+ */
+ret_code_t nfc_t2t_parameter_get(nfc_t2t_param_id_t id, void * p_data, size_t * p_max_data_length);
+
+/** @brief Function for registering the payload to send on reception of a READ request.
+ *
+ * The payload is considered to only contain the NDEF message to deliver to a
+ * reader. The required NDEF TLV will be created implicitly by NFC T2T Library.
+ *
+ * The pointer to the payload must stay valid for the duration of the library
+ * execution, or until it is explicitly released.
+ *
+ * If the pointer is not NULL, but the length is zero, the paypload is
+ * considered to be an empty NDEF message.
+ *
+ * If a new payload is registered, the previously registered one is considered
+ * released.
+ *
+ * Passing a NULL pointer releases the current payload without registering a
+ * new one.
+ *
+ * If an invalid size is given (too big), the function returns with an error
+ * and the currently registered payload is left unchanged.
+ *
+ * @note Provided pointer must point to RAM region.
+ *
+ * @param[in] p_payload Pointer to the memory area in RAM containing the payload to send.
+ * @param[in] payload_length Size of the payload in bytes.
+ *
+ * @retval NRF_SUCCESS If the operation was successful. If one
+ * of the arguments was invalid, an error code is returned.
+ */
+ret_code_t nfc_t2t_payload_set(const uint8_t * p_payload, size_t payload_length);
+
+/** @brief Function for registering the raw payload to send on reception of a READ request.
+ *
+ * The payload will be delivered directly as-is to the reader, without
+ * implicitly adding an NDEF TLV container. This can be used if the
+ * application wants to define the TLVs itself, for example, to provide a different
+ * memory layout.
+ *
+ * The pointer to the payload must stay valid for the duration of the library
+ * execution, or until it is explicitly released.
+ *
+ * If a new payload is registered, the previously registered one is considered
+ * released.
+ *
+ * Passing a NULL pointer releases the current payload, without registering a
+ * new one.
+ *
+ * If an invalid size is given (too big), the function returns with an error
+ * and the currently registered payload is left unchanged.
+ *
+ * @note Provided pointer must points to RAM region.
+ *
+ * @param[in] p_payload Pointer to the memory area in RAM containing the payload to send.
+ * @param[in] payload_length Size of the payload in bytes.
+ *
+ * @retval NRF_SUCCESS If the operation was successful. If one
+ * of the arguments was invalid, an error code is returned.
+ */
+ret_code_t nfc_t2t_payload_raw_set(const uint8_t * p_payload, size_t payload_length);
+
+/** @brief Function for registering the sequence of internal bytes.
+ *
+ * This refers to the first 10 bytes of the tag memory. The library will set
+ * a sensible default for these bytes. The application can use this function
+ * to override the default.
+ *
+ * Passing a NULL pointer reverts back to the default sequence.
+ * The data will be copied by NFC T2T Library, so the memory does not have to remain valid
+ * after the function returns.
+ *
+ * @note When modifying the internal bytes, remember that they must be consistent
+ * with the NFC hardware register settings (see @ref nfc_t2t_format_internal).
+ *
+ * @param[in] p_data Pointer to the memory area containing the data.
+ * @param[in] data_length Size of the data in bytes.
+ *
+ * @retval NRF_SUCCESS If the operation was successful. If the data was not NULL and the
+ * data length was not 10, an error code is returned.
+ */
+ret_code_t nfc_t2t_internal_set(const uint8_t * p_data, size_t data_length);
+
+/** @brief Function for activating the NFC frontend.
+ *
+ * You must call this function so that events are posted to the application
+ * callback.
+ *
+ * @retval NRF_SUCCESS If the NFC frontend was activated successfully. If the lower layer
+ * could not be started, an error code is returned.
+ */
+ret_code_t nfc_t2t_emulation_start(void);
+
+/** @brief Function for deactivating the NFC frontend.
+ *
+ * After calling this function, no more events will be posted to the
+ * application callback.
+ *
+ * @retval NRF_SUCCESS If the NFC frontend was deactivated successfully. If the lower layer
+ * could not be stopped, an error code is returned.
+ */
+ret_code_t nfc_t2t_emulation_stop(void);
+
+/** @brief Function for releasing the reference to the application callback.
+ *
+ * After calling this function, the passed callback pointer is no longer
+ * considered valid.
+ *
+ * @retval NRF_SUCCESS This function always succeeds.
+ */
+ret_code_t nfc_t2t_done(void);
+
+#ifdef __cplusplus
+}
+#endif
+
+/** @} */
+#endif // NFC_T2T_LIB_H__
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/t2t_lib/nfc_t2t_lib_gcc.a b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/t2t_lib/nfc_t2t_lib_gcc.a
new file mode 100644
index 0000000..c1a7f5a
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/t2t_lib/nfc_t2t_lib_gcc.a
Binary files differ
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/t2t_lib/nfc_t2t_lib_gcc_no_fpu.a b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/t2t_lib/nfc_t2t_lib_gcc_no_fpu.a
new file mode 100644
index 0000000..f1c00e8
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/t2t_lib/nfc_t2t_lib_gcc_no_fpu.a
Binary files differ
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/t2t_lib/nfc_t2t_lib_iar.a b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/t2t_lib/nfc_t2t_lib_iar.a
new file mode 100644
index 0000000..47c8fa7
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/t2t_lib/nfc_t2t_lib_iar.a
Binary files differ
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/t2t_lib/nfc_t2t_lib_keil.lib b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/t2t_lib/nfc_t2t_lib_keil.lib
new file mode 100644
index 0000000..994a76b
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/t2t_lib/nfc_t2t_lib_keil.lib
Binary files differ
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/t2t_parser/nfc_t2t_parser.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/t2t_parser/nfc_t2t_parser.c
new file mode 100644
index 0000000..fd1477e
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/t2t_parser/nfc_t2t_parser.c
@@ -0,0 +1,679 @@
+/**
+ * Copyright (c) 2015 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#include "sdk_common.h"
+#if NRF_MODULE_ENABLED(NFC_T2T_PARSER)
+
+#include <string.h>
+#include <stdbool.h>
+#include "nrf_delay.h"
+#include "nfc_t2t_parser.h"
+
+#define NRF_LOG_MODULE_NAME nfc_t2t_parser
+#if NFC_T2T_PARSER_LOG_ENABLED
+#define NRF_LOG_LEVEL NFC_T2T_PARSER_LOG_LEVEL
+#define NRF_LOG_INFO_COLOR NFC_T2T_PARSER_INFO_COLOR
+#include "nrf_log.h"
+NRF_LOG_MODULE_REGISTER();
+#else // NFC_T2T_PARSER_LOG_ENABLED
+#define NRF_LOG_LEVEL 0
+#include "nrf_log.h"
+#endif // NFC_T2T_PARSER_LOG_ENABLED
+
+/// Gets least significant nibble (a 4-bit value) from a byte.
+#define LSN_GET(val) (val & 0x0F)
+
+/// Gets most significant nibble (a 4-bit value) from a byte.
+#define MSN_GET(val) ((val >> 4) & 0x0F)
+
+/**
+ * @brief Function for inserting the TLV block into a @ref type_2_tag_t structure.
+ *
+ * The content of a TLV block structure pointed by the p_tlv_block is copied into a TLV block
+ * array within the structure pointed by the p_type_2_tag.
+ *
+ * @param[in,out] p_type_2_tag Pointer to the structure that contains the TLV blocks array.
+ * @param[in] p_tlv_block Pointer to the TLV block to insert.
+ *
+ * @retval NRF_SUCCESS If the block was inserted successfully.
+ * @retval NRF_ERROR_NO_MEM If there is already maximum number of blocks stored in the array.
+ *
+ */
+static ret_code_t type_2_tag_tlv_block_insert(type_2_tag_t * p_type_2_tag,
+ tlv_block_t * p_tlv_block)
+{
+ if (p_type_2_tag->tlv_count == p_type_2_tag->max_tlv_blocks)
+ {
+ return NRF_ERROR_NO_MEM;
+ }
+
+ // Copy contents of the source block.
+ p_type_2_tag->p_tlv_block_array[p_type_2_tag->tlv_count] = *p_tlv_block;
+ p_type_2_tag->tlv_count++;
+
+ return NRF_SUCCESS;
+}
+
+
+/**
+ * @brief Function for checking if the TLV block length is correct.
+ *
+ * Some TLV block has predefined length:
+ * TLV_NULL and TLV_TERMINATOR always have a length of 1 byte.
+ * TLV_LOCK_CONTROL and TLV_MEMORY_CONTROL always have a length of 3 bytes.
+ *
+ * @param[in] p_block_to_check Pointer to the structure that contains the TLV block length.
+ *
+ * @retval TRUE If the length is correct.
+ * @retval FALSE Otherwise.
+ *
+ */
+static bool tlv_block_is_data_length_correct(tlv_block_t * p_block_to_check)
+{
+ switch (p_block_to_check->tag)
+ {
+ case TLV_NULL:
+ case TLV_TERMINATOR:
+ if (p_block_to_check->length != TLV_NULL_TERMINATOR_LEN)
+ {
+ return false;
+ }
+ break;
+
+ case TLV_LOCK_CONTROL:
+ case TLV_MEMORY_CONTROL:
+ if (p_block_to_check->length != TLV_LOCK_MEMORY_CTRL_LEN)
+ {
+ return false;
+ }
+ break;
+
+ case TLV_NDEF_MESSAGE:
+ case TLV_PROPRIETARY:
+ default:
+ // Any length will do.
+ break;
+ }
+
+ return true;
+}
+
+/**
+ * @brief Function for checking if the end of the tag data area was reached.
+ *
+ * @param[in] p_type_2_tag Pointer to the structure that contains the data area size.
+ * @param[in] offset Current byte offset.
+ *
+ * @retval TRUE If the offset indicates the end of the data area.
+ * @retval FALSE Otherwise.
+ *
+ */
+static bool type_2_tag_is_end_reached(type_2_tag_t * p_type_2_tag, uint16_t offset)
+{
+ return offset == (p_type_2_tag->cc.data_area_size + T2T_FIRST_DATA_BLOCK_OFFSET);
+}
+
+
+/**
+ * @brief Function for checking if version of Type 2 Tag specification read from a tag is supported.
+ *
+ * @param[in] p_type_2_tag Pointer to the structure that contains the tag version.
+ *
+ * @retval TRUE If the version is supported and tag data can be parsed.
+ * @retval FALSE Otherwise.
+ *
+ */
+static bool type_2_tag_is_version_supported(type_2_tag_t * p_type_2_tag)
+{
+ // Simple check atm, as only 1 major version has been issued so far, so no backward compatibility
+ // is needed, tags with newer version implemented shall be rejected according to the doc.
+ return p_type_2_tag->cc.major_version == T2T_SUPPORTED_MAJOR_VERSION;
+}
+
+
+/**
+ * @brief Function for checking if the field fits into the data area specified in
+ * the Capability Container.
+ *
+ * @param[in] p_type_2_tag Pointer to the structure that contains the data area size.
+ * @param[in] offset As Offset of the field to check.
+ * @param[in] field_length Length of the field to check.
+ *
+ * @retval TRUE If the field fits into the data area.
+ * @retval FALSE If the field exceeds the data area.
+ *
+ */
+static bool type_2_tag_is_field_within_data_range(type_2_tag_t * p_type_2_tag,
+ uint16_t offset,
+ uint16_t field_length)
+{
+ // Invalid argument, return false.
+ if (field_length == 0)
+ {
+ return false;
+ }
+ return ( (offset + field_length - 1) <
+ (p_type_2_tag->cc.data_area_size + T2T_FIRST_DATA_BLOCK_OFFSET) )
+ && ( offset >= T2T_FIRST_DATA_BLOCK_OFFSET );
+}
+
+
+/**
+ * @brief Function for reading the tag field of a TLV block from the p_raw_data buffer.
+ *
+ * This function reads the tag field containing a TLV block type and inserts its value into
+ * a structure pointed by the p_tlv_buf pointer.
+ *
+ * @param[in] p_type_2_tag Pointer to the structure that contains Type 2 Tag data parsed so far.
+ * @param[in] p_raw_data Pointer to the buffer with a raw data from the tag.
+ * @param[in,out] p_t_offset As input: offset of the tag field to read. As output: offset of
+ * the first byte after the tag field.
+ * @param[out] p_tlv_buf Pointer to a @ref tlv_block_t structure where the tag type will be
+ * inserted.
+ *
+ * @retval NRF_SUCCESS If the tag field at specified offset is correct.
+ * @retval NRF_ERROR_INVALID_DATA If the tag field at specified offset exceeds the data
+ * area specified in the Capability Container.
+ *
+ */
+static ret_code_t type_2_tag_type_extract(type_2_tag_t * p_type_2_tag,
+ uint8_t * p_raw_data,
+ uint16_t * p_t_offset,
+ tlv_block_t * p_tlv_buf)
+{
+ if (!type_2_tag_is_field_within_data_range(p_type_2_tag, *p_t_offset, TLV_T_LENGTH))
+ {
+ return NRF_ERROR_INVALID_DATA;
+ }
+
+ p_tlv_buf->tag = p_raw_data[*p_t_offset];
+ *p_t_offset += TLV_T_LENGTH;
+
+ return NRF_SUCCESS;
+}
+
+
+/**
+ * @brief Function for reading the length field of a TLV block from the p_raw_data buffer.
+ *
+ * This function reads the length field of a TLV block and inserts its value into a structure
+ * pointed by the p_tlv_buf pointer.
+ *
+ * @param[in] p_type_2_tag Pointer to the structure that contains Type 2 Tag data parsed so far.
+ * @param[in] p_raw_data Pointer to the buffer with a raw data from the tag.
+ * @param[in,out] p_l_offset As input: offset of the length field to read. As output: offset of
+ * the first byte after the length field.
+ * @param[out] p_tlv_buf Pointer to a @ref tlv_block_t structure where the length will be
+ * inserted.
+ *
+ * @retval NRF_SUCCESS If the length field at specified offset is correct.
+ * @retval NRF_ERROR_INVALID_DATA If the length field at specified offset exceeds the data
+ * area specified in the Capability Container or has
+ * incorrect format.
+ *
+ */
+static ret_code_t type_2_tag_length_extract(type_2_tag_t * p_type_2_tag,
+ uint8_t * p_raw_data,
+ uint16_t * p_l_offset,
+ tlv_block_t * p_tlv_buf)
+{
+ uint16_t length;
+
+ if (!type_2_tag_is_field_within_data_range(p_type_2_tag, *p_l_offset, TLV_L_SHORT_LENGTH))
+ {
+ return NRF_ERROR_INVALID_DATA;
+ }
+
+ length = p_raw_data[*p_l_offset];
+
+ if (length == TLV_L_FORMAT_FLAG)
+ {
+ // Check another two bytes.
+ if (!type_2_tag_is_field_within_data_range(p_type_2_tag, *p_l_offset, TLV_L_LONG_LENGTH))
+ {
+ return NRF_ERROR_INVALID_DATA;
+ }
+
+ length = uint16_big_decode(&p_raw_data[*p_l_offset + 1]);
+
+ // Long length value cannot be lower than 0xFF.
+ if (length < 0xFF)
+ {
+ return NRF_ERROR_INVALID_DATA;
+ }
+
+ p_tlv_buf->length = length;
+ *p_l_offset += TLV_L_LONG_LENGTH;
+
+ }
+ else
+ {
+ p_tlv_buf->length = length;
+ *p_l_offset += TLV_L_SHORT_LENGTH;
+ }
+
+ return NRF_SUCCESS;
+}
+
+
+/**
+ * @brief Function for reading a pointer to the value field of a TLV block from the p_raw_data buffer.
+ *
+ * This function reads a pointer to the value field of a TLV block and inserts it into
+ * a structure pointed by the p_tlv_buf pointer. If there is no value field present in the
+ * TLV block, NULL is inserted.
+ *
+ * @param[in] p_type_2_tag Pointer to the structure that contains Type 2 Tag data parsed so far.
+ * @param[in] p_raw_data Pointer to the buffer with a raw data from the tag.
+ * @param[in,out] p_v_offset As input: offset of the value field to read. As output: offset of
+ * the first byte after the value field.
+ * @param[in,out] p_tlv_buf Pointer to a @ref tlv_block_t structure where the value field
+ * pointer will be inserted.
+ *
+ * @retval NRF_SUCCESS If the value field at specified offset is correct.
+ * @retval NRF_ERROR_INVALID_DATA If the value field at specified offset exceeds the data
+ * area specified in the Capability Container.
+ *
+ */
+static ret_code_t type_2_tag_value_ptr_extract(type_2_tag_t * p_type_2_tag,
+ uint8_t * p_raw_data,
+ uint16_t * p_v_offset,
+ tlv_block_t * p_tlv_buf)
+{
+ if (p_tlv_buf->length == 0)
+ {
+ // Clear the value pointer, don't touch the offset.
+ p_tlv_buf->p_value = NULL;
+ }
+ else
+ {
+ if (!type_2_tag_is_field_within_data_range(p_type_2_tag, *p_v_offset, p_tlv_buf->length))
+ {
+ return NRF_ERROR_INVALID_DATA;
+ }
+
+ p_tlv_buf->p_value = p_raw_data + *p_v_offset;
+ *p_v_offset += p_tlv_buf->length;
+ }
+
+ return NRF_SUCCESS;
+}
+
+
+/**
+ * @brief Function for reading a single TLV block from the p_raw_data buffer.
+ *
+ * This function reads a single TLV block from the p_raw_data buffer and stores its contents in a
+ * structure pointed by the p_tlv_buf.
+ *
+ * @param[in] p_type_2_tag Pointer to the structure that contains Type 2 Tag data parsed so far.
+ * @param[in] p_raw_data Pointer to the buffer with a raw data from the tag.
+ * @param[in,out] p_tlv_offset As input: offset of the TLV block to read. As output: offset of the
+ * next TLV block, 0 if it was the last block.
+ * @param[out] p_tlv_buf Pointer to a @ref tlv_block_t structure that will be filled with
+ * the data read.
+ *
+ * @retval NRF_SUCCESS If the parsing operation of the block succeeded. Otherwise, an error
+ * code is returned.
+ *
+ */
+static ret_code_t type_2_tag_tlv_block_extract(type_2_tag_t * p_type_2_tag,
+ uint8_t * p_raw_data,
+ uint16_t * p_offset,
+ tlv_block_t * p_tlv_buf)
+{
+ ret_code_t err_code;
+ memset(p_tlv_buf, 0, sizeof(tlv_block_t));
+
+ // TLV Tag field.
+ err_code = type_2_tag_type_extract(p_type_2_tag, p_raw_data, p_offset, p_tlv_buf);
+ if (err_code != NRF_SUCCESS)
+ {
+ return err_code;
+ }
+
+ // Further processing depends on tag field value.
+ switch (p_tlv_buf->tag)
+ {
+ case TLV_NULL:
+ // Simply ignore NULL blocks, leave the incremented offset.
+ break;
+
+ case TLV_TERMINATOR:
+ // Write 0 to the offset variable, indicating that last TLV block was found.
+ *p_offset = 0;
+ break;
+
+ case TLV_LOCK_CONTROL:
+ case TLV_MEMORY_CONTROL:
+ case TLV_NDEF_MESSAGE:
+ case TLV_PROPRIETARY:
+ default:
+ // Unknown blocks should also be extracted.
+ err_code = type_2_tag_length_extract(p_type_2_tag, p_raw_data, p_offset, p_tlv_buf);
+ if (err_code != NRF_SUCCESS)
+ {
+ return err_code;
+ }
+
+ if (p_tlv_buf->length > 0)
+ {
+ err_code = type_2_tag_value_ptr_extract(p_type_2_tag, p_raw_data, p_offset, p_tlv_buf);
+ if (err_code != NRF_SUCCESS)
+ {
+ return err_code;
+ }
+ }
+
+ break;
+ }
+
+ return NRF_SUCCESS;
+}
+
+
+/**
+ * @brief Function for checking the checksum bytes of the UID stored in internal area.
+ *
+ * This function calculates the block check character (BCC) bytes based on the parsed serial number
+ * and compares them with bytes read from the Type 2 Tag.
+ *
+ * @param[in] p_sn Pointer to the @ref type_2_tag_serial_number_t structure to check.
+ *
+ * @retval TRUE If the calculated BCC matched the BCC from the tag.
+ * @retval FALSE Otherwise.
+ *
+ */
+static bool type_2_tag_is_bcc_correct(type_2_tag_serial_number_t * p_sn)
+{
+ uint8_t bcc1 = (uint8_t)T2T_UID_BCC_CASCADE_BYTE ^
+ (uint8_t)p_sn->manufacturer_id ^
+ (uint8_t)((p_sn->serial_number_part_1 >> 8) & 0xFF) ^
+ (uint8_t)(p_sn->serial_number_part_1 & 0xFF);
+
+ uint8_t bcc2 = (uint8_t)((p_sn->serial_number_part_2 >> 24) & 0xFF) ^
+ (uint8_t)((p_sn->serial_number_part_2 >> 16) & 0xFF) ^
+ (uint8_t)((p_sn->serial_number_part_2 >> 8) & 0xFF) ^
+ (uint8_t)( p_sn->serial_number_part_2 & 0xFF);
+
+ return (bcc1 == p_sn->check_byte_0) && (bcc2 == p_sn->check_byte_1);
+}
+
+
+/**
+ * @brief Function for parsing an internal area of a Type 2 Tag.
+ *
+ * This function reads data from an internal area in the raw data buffer and fills the
+ * @ref type_2_tag_serial_number_t structure within @ref type_2_tag_t.
+ *
+ * @param[in,out] p_type_2_tag Pointer to the structure that will be filled with parsed data.
+ * @param[in] p_raw_data Pointer to the buffer with raw data from the tag.
+ *
+ * @retval NRF_SUCCESS If the parsing operation of the internal area succeeded.
+ * Otherwise, an error code is returned.
+ *
+ */
+static ret_code_t type_2_tag_internal_parse(type_2_tag_t * p_type_2_tag, uint8_t * p_raw_data)
+{
+ p_type_2_tag->sn.manufacturer_id = p_raw_data[0];
+ p_type_2_tag->sn.serial_number_part_1 = uint16_big_decode(&p_raw_data[1]);
+ p_type_2_tag->sn.check_byte_0 = p_raw_data[3];
+ p_type_2_tag->sn.serial_number_part_2 = uint32_big_decode(&p_raw_data[4]);
+ p_type_2_tag->sn.check_byte_1 = p_raw_data[8];
+ p_type_2_tag->sn.internal = p_raw_data[9];
+
+ p_type_2_tag->lock_bytes = uint16_big_decode(&p_raw_data[10]);
+
+ if (!type_2_tag_is_bcc_correct(&p_type_2_tag->sn))
+ {
+ NRF_LOG_WARNING("Warning! BCC of the serial number is not correct!");
+ }
+
+ return NRF_SUCCESS;
+}
+
+
+/**
+ * @brief Function for parsing a Capabiliy Container area of a Type 2 Tag.
+ *
+ * This function reads data from a Capability Container area in the raw data buffer and fills the
+ * @ref type_2_tag_capability_container_t structure within @ref type_2_tag_t.
+ *
+ * @param[in,out] p_type_2_tag Pointer to the structure that will be filled with parsed data.
+ * @param[in] p_raw_data Pointer to the buffer with raw data from the tag.
+ *
+ * @retval NRF_SUCCESS If the parsing operation of the Capability Container succeeded.
+ * Otherwise, an error code is returned.
+ *
+ */
+static ret_code_t type_2_tag_cc_parse(type_2_tag_t * p_type_2_tag, uint8_t * p_raw_data)
+{
+ uint8_t * p_cc_block = p_raw_data + T2T_CC_BLOCK_OFFSET;
+
+ if (p_cc_block[0] != T2T_NFC_FORUM_DEFINED_DATA)
+ {
+ return NRF_ERROR_INVALID_DATA;
+ }
+
+ p_type_2_tag->cc.major_version = MSN_GET(p_cc_block[1]);
+ p_type_2_tag->cc.minor_version = LSN_GET(p_cc_block[1]);
+ p_type_2_tag->cc.data_area_size = p_cc_block[2] * 8;
+ p_type_2_tag->cc.read_access = MSN_GET(p_cc_block[3]);
+ p_type_2_tag->cc.write_access = LSN_GET(p_cc_block[3]);
+
+ return NRF_SUCCESS;
+}
+
+
+/**
+ * @brief Function for parsing a single TLV block.
+ *
+ * This function reads a single TLV block from the raw data buffer, from the position indicated by
+ * the p_tlv_offset, and adds it to the @ref type_2_tag_t structure.
+ *
+ * @param[in,out] p_type_2_tag Pointer to the structure that will be filled with parsed data.
+ * @param[in] p_raw_data Pointer to the buffer with raw data from the tag.
+ * @param[in,out] p_tlv_offset As input: offset of the TLV block to parse. As output: offset of the
+ * next TLV block, 0 if it was the last block.
+ *
+ * @retval NRF_SUCCESS If the parsing operation of the block succeeded. Otherwise, an error
+ * code is returned.
+ *
+ */
+static ret_code_t type_2_tag_tlv_parse(type_2_tag_t * p_type_2_tag,
+ uint8_t * p_raw_data,
+ uint16_t * p_tlv_offset)
+{
+ ret_code_t err_code;
+ tlv_block_t new_block;
+
+ // Get tag field.
+ err_code = type_2_tag_tlv_block_extract(p_type_2_tag, p_raw_data, p_tlv_offset, &new_block);
+ if (err_code != NRF_SUCCESS)
+ {
+ return err_code;
+ }
+
+ if (!tlv_block_is_data_length_correct(&new_block))
+ {
+ return NRF_ERROR_INVALID_DATA;
+ }
+
+ // Further action depends on tag type.
+ switch (new_block.tag)
+ {
+ case TLV_NULL:
+ case TLV_TERMINATOR:
+ // Ignore them.
+ break;
+
+ case TLV_LOCK_CONTROL:
+ case TLV_MEMORY_CONTROL:
+ case TLV_NDEF_MESSAGE:
+ case TLV_PROPRIETARY:
+ default:
+ // Unknown tag types are also added.
+ err_code = type_2_tag_tlv_block_insert(p_type_2_tag, &new_block);
+ if (err_code != NRF_SUCCESS)
+ {
+ NRF_LOG_WARNING("Warning! Not enough memory to insert all of the blocks!");
+ return err_code;
+ }
+ break;
+ }
+
+ return NRF_SUCCESS;
+}
+
+
+void type_2_tag_clear(type_2_tag_t * p_type_2_tag)
+{
+ p_type_2_tag->tlv_count = 0;
+ memset(&p_type_2_tag->cc, 0, sizeof(p_type_2_tag->cc));
+ memset(&p_type_2_tag->sn, 0, sizeof(p_type_2_tag->sn));
+}
+
+
+ret_code_t type_2_tag_parse(type_2_tag_t * p_type_2_tag, uint8_t * p_raw_data)
+{
+ ret_code_t err_code;
+
+ type_2_tag_clear(p_type_2_tag);
+
+ err_code = type_2_tag_internal_parse(p_type_2_tag, p_raw_data);
+ if (err_code != NRF_SUCCESS)
+ {
+ return err_code;
+ }
+
+ err_code = type_2_tag_cc_parse(p_type_2_tag, p_raw_data);
+ if (err_code != NRF_SUCCESS)
+ {
+ return err_code;
+ }
+
+ if (!type_2_tag_is_version_supported(p_type_2_tag))
+ {
+ return NRF_ERROR_NOT_SUPPORTED;
+ }
+
+ uint16_t offset = T2T_FIRST_DATA_BLOCK_OFFSET;
+
+ while (offset > 0)
+ {
+ // Check if end of tag is reached (no terminator block was present).
+ if (type_2_tag_is_end_reached(p_type_2_tag, offset))
+ {
+ NRF_LOG_DEBUG("No terminator block was found in the tag!");
+ break;
+ }
+
+ err_code = type_2_tag_tlv_parse(p_type_2_tag, p_raw_data, &offset);
+ if (err_code != NRF_SUCCESS)
+ {
+ return err_code;
+ }
+ }
+
+ return NRF_SUCCESS;
+}
+
+
+void type_2_tag_printout(type_2_tag_t * p_type_2_tag)
+{
+ uint32_t i;
+ NRF_LOG_INFO("Type 2 Tag contents:");
+ NRF_LOG_INFO("Number of TLV blocks: %d", p_type_2_tag->tlv_count);
+
+ NRF_LOG_DEBUG("Internal data:");
+ NRF_LOG_DEBUG(" Manufacturer ID: 0x%02x", p_type_2_tag->sn.manufacturer_id);
+ NRF_LOG_DEBUG(" Serial number part 1: 0x%04x", p_type_2_tag->sn.serial_number_part_1);
+ NRF_LOG_DEBUG(" Check byte 0: 0x%02x", p_type_2_tag->sn.check_byte_0);
+ NRF_LOG_DEBUG(" Serial number part 2: 0x%08lx", p_type_2_tag->sn.serial_number_part_2);
+ NRF_LOG_DEBUG(" Check byte 1: 0x%02x", p_type_2_tag->sn.check_byte_1);
+ NRF_LOG_DEBUG(" Internal byte: 0x%02x", p_type_2_tag->sn.internal);
+ NRF_LOG_DEBUG(" Lock bytes: 0x%04x", p_type_2_tag->lock_bytes);
+
+ NRF_LOG_DEBUG("Capability Container data:");
+ NRF_LOG_DEBUG(" Major version number: %d", p_type_2_tag->cc.major_version);
+ NRF_LOG_DEBUG(" Minor version number: %d", p_type_2_tag->cc.minor_version);
+ NRF_LOG_DEBUG(" Data area size: %d", p_type_2_tag->cc.data_area_size);
+ NRF_LOG_DEBUG(" Read access: 0x%02X", p_type_2_tag->cc.read_access);
+ NRF_LOG_DEBUG(" Write access: 0x%02X", p_type_2_tag->cc.write_access);
+
+ for (i = 0; i < p_type_2_tag->tlv_count; i++)
+ {
+ NRF_LOG_INFO("TLV block 0x%02X: ", p_type_2_tag->p_tlv_block_array[i].tag);
+ switch (p_type_2_tag->p_tlv_block_array[i].tag)
+ {
+ case TLV_LOCK_CONTROL:
+ NRF_LOG_INFO("Lock Control");
+ break;
+ case TLV_MEMORY_CONTROL:
+ NRF_LOG_INFO("Memory Control");
+ break;
+ case TLV_NDEF_MESSAGE:
+ NRF_LOG_INFO("NDEF Message");
+ break;
+ case TLV_PROPRIETARY:
+ NRF_LOG_INFO("Proprietary");
+ break;
+ case TLV_NULL:
+ NRF_LOG_INFO("Null\r\n");
+ break;
+ case TLV_TERMINATOR:
+ NRF_LOG_INFO("Terminator");
+ break;
+ default:
+ NRF_LOG_INFO("Unknown");
+ break;
+ }
+
+ NRF_LOG_INFO(" Data length: %d", p_type_2_tag->p_tlv_block_array[i].length);
+
+ if (p_type_2_tag->p_tlv_block_array[i].length > 0)
+ {
+ NRF_LOG_DEBUG(" Data:");
+ NRF_LOG_HEXDUMP_DEBUG(p_type_2_tag->p_tlv_block_array[i].p_value,
+ p_type_2_tag->p_tlv_block_array[i].length);
+ }
+ }
+}
+
+#endif // NRF_MODULE_ENABLED(NFC_T2T_PARSER)
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/t2t_parser/nfc_t2t_parser.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/t2t_parser/nfc_t2t_parser.h
new file mode 100644
index 0000000..23a8632
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/t2t_parser/nfc_t2t_parser.h
@@ -0,0 +1,195 @@
+/**
+ * Copyright (c) 2015 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#ifndef NFC_TYPE_2_TAG_PARSER_H__
+#define NFC_TYPE_2_TAG_PARSER_H__
+
+#include <stdint.h>
+#include "nfc_tlv_block.h"
+#include "sdk_errors.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @defgroup nfc_type_2_tag Type 2 Tag
+ * @{
+ * @ingroup nfc_type_2_tag_parser
+ *
+ * @brief Descriptor for a Type 2 Tag.
+ *
+ */
+
+/**
+ * @brief Descriptor for the internal bytes of a Type 2 Tag.
+ */
+typedef struct
+{
+ uint8_t manufacturer_id; ///< Manufacturer ID (the most significant byte of the UID/serial number).
+ uint16_t serial_number_part_1; ///< Bytes 5-4 of the tag UID.
+ uint8_t check_byte_0; ///< First block check character byte (XOR of the cascade tag byte, manufacturer ID byte, and the serial_number_part_1 bytes).
+ uint32_t serial_number_part_2; ///< Bytes 3-0 of the tag UID.
+ uint8_t check_byte_1; ///< Second block check character byte (XOR of the serial_number_part_2 bytes).
+ uint8_t internal; ///< Tag internal bytes.
+} type_2_tag_serial_number_t;
+
+/**
+ * @brief Descriptor for the Capability Container (CC) bytes of a Type 2 Tag.
+ */
+typedef struct
+{
+ uint8_t major_version; ///< Major version of the supported Type 2 Tag specification.
+ uint8_t minor_version; ///< Minor version of the supported Type 2 Tag specification.
+ uint16_t data_area_size; ///< Size of the data area in bytes.
+ uint8_t read_access; ///< Read access for the data area.
+ uint8_t write_access; ///< Write access for the data area.
+} type_2_tag_capability_container_t;
+
+/**
+ * @brief Type 2 Tag descriptor.
+ */
+typedef struct
+{
+ type_2_tag_serial_number_t sn; ///< Values within the serial number area of the tag.
+ uint16_t lock_bytes; ///< Value of the lock bytes.
+ type_2_tag_capability_container_t cc; ///< Values within the Capability Container area of the tag.
+
+ uint16_t const max_tlv_blocks; ///< Maximum number of TLV blocks that can be stored.
+ tlv_block_t * p_tlv_block_array; ///< Pointer to the array for TLV blocks.
+ uint16_t tlv_count; ///< Number of TLV blocks stored in the Type 2 Tag.
+
+} type_2_tag_t;
+
+/**
+ * @brief Macro for creating and initializing a Type 2 Tag descriptor.
+ *
+ * This macro creates and initializes a static instance of a @ref type_2_tag_t structure and
+ * an array of @ref tlv_block_t descriptors.
+ *
+ * Use the macro @ref NFC_TYPE_2_TAG_DESC to access the Type 2 Tag descriptor instance.
+ *
+ * @param[in] NAME Name of the created descriptor instance.
+ * @param[in] MAX_BLOCKS Maximum number of @ref tlv_block_t descriptors that can be stored in the array.
+ *
+ */
+#define NFC_TYPE_2_TAG_DESC_DEF(NAME, MAX_BLOCKS) \
+ static tlv_block_t NAME##_tlv_block_array[MAX_BLOCKS]; \
+ static type_2_tag_t NAME##_type_2_tag = \
+ { \
+ .max_tlv_blocks = MAX_BLOCKS, \
+ .p_tlv_block_array = NAME##_tlv_block_array, \
+ .tlv_count = 0 \
+ }
+
+/**
+ * @brief Macro for accessing the @ref type_2_tag_t instance that was created
+ * with @ref NFC_TYPE_2_TAG_DESC_DEF.
+ */
+#define NFC_TYPE_2_TAG_DESC(NAME) (NAME##_type_2_tag)
+
+
+#define T2T_NFC_FORUM_DEFINED_DATA 0xE1 ///< Value indicating that the Type 2 Tag contains NFC Forum defined data.
+#define T2T_UID_BCC_CASCADE_BYTE 0x88 ///< Value used for calculating the first BCC byte of a Type 2 Tag serial number.
+
+#define T2T_SUPPORTED_MAJOR_VERSION 1 ///< Supported major version of the Type 2 Tag specification.
+#define T2T_SUPPORTED_MINOR_VERSION 2 ///< Supported minor version of the Type 2 Tag specification.
+
+#define T2T_BLOCK_SIZE 4 ///< Type 2 Tag block size in bytes.
+
+#define T2T_CC_BLOCK_OFFSET 12 ///< Offset of the Capability Container area in the Type 2 Tag.
+#define T2T_FIRST_DATA_BLOCK_OFFSET 16 ///< Offset of the data area in the Type 2 Tag.
+
+/**
+ * @}
+ */
+
+
+/**
+ * @defgroup nfc_type_2_tag_parser NFC Type 2 Tag parser
+ * @{
+ * @ingroup nfc_t2t
+ *
+ * @brief Parser for Type 2 Tag data.
+ *
+ */
+
+/**
+ * @brief Function for clearing the @ref type_2_tag_t structure.
+ *
+ * @param[in,out] p_type_2_tag Pointer to the structure that should be cleared.
+ *
+ */
+void type_2_tag_clear(type_2_tag_t * p_type_2_tag);
+
+/**
+ * @brief Function for parsing raw data read from a Type 2 Tag.
+ *
+ * This function parses the header and the following TLV blocks of a Type 2 Tag. The data is read
+ * from a buffer and stored in a @ref type_2_tag_t structure.
+ *
+ * @param[out] p_type_2_tag Pointer to the structure that will be filled with parsed data.
+ * @param[in] p_raw_data Pointer to the buffer with raw data from the tag (should
+ * point at the first byte of the first block of the tag).
+ *
+ * @retval NRF_SUCCESS If the data was parsed successfully.
+ * @retval NRF_ERROR_NO_MEM If there is not enough memory to store all of the TLV blocks.
+ * @retval Other If an error occurred during the parsing operation.
+ *
+ */
+ret_code_t type_2_tag_parse(type_2_tag_t * p_type_2_tag, uint8_t * p_raw_data);
+
+/**
+ * @brief Function for printing parsed contents of the Type 2 Tag.
+ *
+ * @param[in] p_type_2_tag Pointer to the structure that should be printed.
+ *
+ */
+void type_2_tag_printout(type_2_tag_t * p_type_2_tag);
+
+/**
+ * @}
+ */
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* NFC_TYPE_2_TAG_PARSER_H__ */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/t2t_parser/nfc_tlv_block.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/t2t_parser/nfc_tlv_block.h
new file mode 100644
index 0000000..4c74f36
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/t2t_parser/nfc_tlv_block.h
@@ -0,0 +1,102 @@
+/**
+ * Copyright (c) 2015 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#ifndef NFC_TLV_BLOCK_H__
+#define NFC_TLV_BLOCK_H__
+
+#include <stdint.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**@file
+ *
+ * @defgroup nfc_type_2_tag_tlv_block Type 2 Tag TLV blocks
+ * @{
+ * @ingroup nfc_type_2_tag_parser
+ *
+ * @brief Descriptor for a Type 2 Tag TLV block.
+ *
+ */
+
+/**
+ * @brief Tag field values.
+ *
+ * Possible values for the tag field in a TLV block.
+ */
+typedef enum
+{
+ TLV_NULL = 0x00, ///< Might be used for padding of memory areas.
+ TLV_LOCK_CONTROL = 0x01, ///< Defines details of the lock bits.
+ TLV_MEMORY_CONTROL = 0x02, ///< Identifies reserved memory areas.
+ TLV_NDEF_MESSAGE = 0x03, ///< Contains an NDEF message.
+ TLV_PROPRIETARY = 0xFD, ///< Tag proprietary information.
+ TLV_TERMINATOR = 0xFE ///< Last TLV block in the data area.
+} tlv_block_types_t;
+
+/**
+ * @brief TLV block descriptor.
+ */
+typedef struct
+{
+ uint8_t tag; ///< Type of the TLV block.
+ uint16_t length; ///< Length of the value field.
+ uint8_t * p_value; ///< Pointer to the value field (NULL if no value field is present in the block).
+} tlv_block_t;
+
+#define TLV_T_LENGTH 1 ///< Length of a tag field.
+
+#define TLV_L_SHORT_LENGTH 1 ///< Length of a short length field.
+#define TLV_L_LONG_LENGTH 3 ///< Length of an extended length field.
+#define TLV_L_FORMAT_FLAG 0xFF ///< Value indicating the use of an extended length field.
+
+#define TLV_NULL_TERMINATOR_LEN 0 ///< Predefined length of the NULL and TERMINATOR TLV blocks.
+#define TLV_LOCK_MEMORY_CTRL_LEN 3 ///< Predefined length of the LOCK CONTROL and MEMORY CONTROL blocks.
+
+/**
+ * @}
+ */
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* NFC_TLV_BLOCK_H__ */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/t4t_lib/hal_t4t/hal_nfc_t4t.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/t4t_lib/hal_t4t/hal_nfc_t4t.c
new file mode 100644
index 0000000..8495060
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/t4t_lib/hal_t4t/hal_nfc_t4t.c
@@ -0,0 +1,1321 @@
+/**
+ * Copyright (c) 2016 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+
+#include "sdk_config.h"
+#if NFC_T4T_HAL_ENABLED
+
+#include "hal_nfc_t4t.h"
+#include <stdint.h>
+#include <stdbool.h>
+#include "nfc_t4t_lib.h"
+#include "nfc_fixes.h"
+#include "nrf.h"
+#include "app_util_platform.h"
+#include "nordic_common.h"
+#include "nrf_drv_clock.h"
+
+#define NRF_LOG_MODULE_NAME hal_nfc
+#if HAL_NFC_CONFIG_LOG_ENABLED
+#define NRF_LOG_LEVEL HAL_NFC_CONFIG_LOG_LEVEL
+#define NRF_LOG_INFO_COLOR HAL_NFC_CONFIG_INFO_COLOR
+#define NRF_LOG_DEBUG_COLOR HAL_NFC_CONFIG_DEBUG_COLOR
+#include "nrf_log.h"
+NRF_LOG_MODULE_REGISTER();
+#else // HAL_NFC_CONFIG_LOG_ENABLED
+#define NRF_LOG_LEVEL 0
+#include "nrf_log.h"
+#endif // HAL_NFC_CONFIG_LOG_ENABLED
+
+
+#if HAL_NFC_CONFIG_DEBUG_PIN_ENABLED
+ #include "nrf_gpio.h"
+
+ #define HAL_NFC_DEBUG_PIN_CONFIG(pin_num) nrf_gpio_cfg_output(pin_num)
+ #define HAL_NFC_DEBUG_PIN_CLEAR(pin_num) nrf_gpio_pin_clear(pin_num)
+ #define HAL_NFC_DEBUG_PIN_SET(pin_num) nrf_gpio_pin_set(pin_num)
+
+ #define HAL_NFC_DEBUG_PINS_INITIALIZE() \
+ do{ \
+ HAL_NFC_DEBUG_PIN_CONFIG(HAL_NFC_HCLOCK_OFF_DEBUG_PIN); \
+ HAL_NFC_DEBUG_PIN_CLEAR(HAL_NFC_HCLOCK_OFF_DEBUG_PIN); \
+ HAL_NFC_DEBUG_PIN_CONFIG(HAL_NFC_HCLOCK_ON_DEBUG_PIN); \
+ HAL_NFC_DEBUG_PIN_CLEAR(HAL_NFC_HCLOCK_ON_DEBUG_PIN); \
+ HAL_NFC_DEBUG_PIN_CONFIG(HAL_NFC_NFC_EVENT_DEBUG_PIN); \
+ HAL_NFC_DEBUG_PIN_CLEAR(HAL_NFC_NFC_EVENT_DEBUG_PIN); \
+ HAL_NFC_DEBUG_PIN_CONFIG(HAL_NFC_DETECT_EVENT_DEBUG_PIN); \
+ HAL_NFC_DEBUG_PIN_CLEAR(HAL_NFC_DETECT_EVENT_DEBUG_PIN); \
+ HAL_NFC_DEBUG_PIN_CONFIG(HAL_NFC_TIMER4_EVENT_DEBUG_PIN); \
+ HAL_NFC_DEBUG_PIN_CLEAR(HAL_NFC_TIMER4_EVENT_DEBUG_PIN); \
+ } while(0)
+#else
+ #define HAL_NFC_DEBUG_PIN_CLEAR(pin_num)
+ #define HAL_NFC_DEBUG_PIN_SET(pin_num)
+ #define HAL_NFC_DEBUG_PINS_INITIALIZE()
+#endif // HAL_NFC_DEBUG_PIN_ENABLE
+
+
+/* NFC library version history:
+ * #define NFC_LIB_VERSION 0x00 first experimental version intended for nRF52840 IC rev. Engineering A (PCA10056, part of nRF52840 Preview Development Kit)
+ */
+
+#define NFC_LIB_VERSION 0x00u /**< Internal: current NFC lib. version */
+
+#define CASCADE_TAG_BYTE 0x88u /**< Constant defined by ISO/EIC 14443-3 */
+#define NFCID1_3RD_LAST_BYTE2_SHIFT 16u /**< Shift value for NFC ID byte 2 */
+#define NFCID1_3RD_LAST_BYTE1_SHIFT 8u /**< Shift value for NFC ID byte 1 */
+#define NFCID1_3RD_LAST_BYTE0_SHIFT 0u /**< Shift value for NFC ID byte 0 */
+#define NFCID1_2ND_LAST_BYTE2_SHIFT 16u /**< Shift value for NFC ID byte 2 */
+#define NFCID1_2ND_LAST_BYTE1_SHIFT 8u /**< Shift value for NFC ID byte 1 */
+#define NFCID1_2ND_LAST_BYTE0_SHIFT 0u /**< Shift value for NFC ID byte 0 */
+#define NFCID1_LAST_BYTE3_SHIFT 24u /**< Shift value for NFC ID byte 3 */
+#define NFCID1_LAST_BYTE2_SHIFT 16u /**< Shift value for NFC ID byte 2 */
+#define NFCID1_LAST_BYTE1_SHIFT 8u /**< Shift value for NFC ID byte 1 */
+#define NFCID1_LAST_BYTE0_SHIFT 0u /**< Shift value for NFC ID byte 0 */
+#define NFCID1_SINGLE_SIZE 4u /**< Length of single size NFCID1 */
+#define NFCID1_DOUBLE_SIZE 7u /**< Length of double size NFCID1 */
+#define NFCID1_TRIPLE_SIZE 10u /**< Length of triple size NFCID1 */
+#define NFCID1_DEFAULT_LENGHT NFCID1_DOUBLE_SIZE /**< Length of NFCID1 if user does not provide one */
+#define NFCID1_MAX_LENGHT NFCID1_TRIPLE_SIZE /**< Maximum length of NFCID1 */
+#define NFC_RX_BUFFER_SIZE 256u /**< NFC Rx data buffer size */
+#define NFC_SLP_REQ_CMD 0x50u /**< NFC SLP_REQ command identifier */
+#define NFC_CRC_SIZE 2u /**< CRC size in bytes */
+#define NFC_T4T_SELRES_PROTOCOL 1u /**< Type 4A Tag PROTOCOL bit setup (b7:b6) for SEL_RES Response frame */
+#define NFC_T4T_SELRES_PROTOCOL_MSK 0x03u /**< PROTOCOL bits mask for SEL_RES Response frame */
+
+#ifdef BOARD_PCA10056
+ #define NFC_T4T_FWI_MAX 8u /**< Maximum FWI parameter value for 52840*/
+#else
+ #define NFC_T4T_FWI_MAX 4u /**< Maximum FWI parameter value */
+#endif // BOARD_PCA10056
+
+#define NFC_T4T_FWI_52840S_MAX 4u /**< Maximum FWI parameter value for first sample of 52840 */
+#define NFCT_FRAMEDELAYMAX_52840S (0xFFFFUL) /**< Bit mask of FRAMEDELAYMAX field for first sample of 52840 */
+#define NFC_T4T_FWI_DEFAULT 4u /**< Default FWI parameter value */
+#define NRF_T4T_FWI_LISTEN_MAX 8u /**< Maxiumum FWI parameter value in Listen Mode */
+#define NFC_T4T_RATS_CMD 0xE0u /**< RATS Command Byte */
+#define NFC_T4T_RATS_DID_MASK 0x0Fu /**< Mask of DID field inside RATS Parameter Byte. */
+#define NFC_T4T_RATS_DID_RFU 0x0Fu /**< Invalid value of DID - RFU. */
+#define NFC_T4T_S_DESELECT 0xC2u /**< S(DESELECT) Block identifier */
+#define NFC_T4T_S_WTX 0xF2u /**< S(WTX)Block identifier */
+#define NFC_T4T_S_BLOCK_MSK 0xF7u /**< S-Block Mask */
+#define NFC_T4T_I_BLOCK 0x02u /**< I-Block identifier */
+#define NFC_T4T_BLOCK_MSK 0xE6u /**< I/R- block mask (NAD not supported, expect this bit equal 0) */
+#define NFC_T4T_ISO_DEP_MSK 0x02u /**< ISO-DEP block mask */
+#define NFC_T4T_R_BLOCK 0xA2u /**< R- Block identifier (static bits) */
+#define NFC_T4T_WTX_NO_DID_SIZE 0x02 /**< WTX data buffer size without DID field. */
+#define NFC_T4T_WTX_DID_SIZE 0x03 /**< WTX data buffer size with DID field. */
+#define NFC_T4T_WTXM_MAX_VALUE 0x3B /**< WTXM max value, according to 'NFC Forum Digital Protocol Technical Specification 2.0, 16.2.2 */
+#define NFC_T4T_DID_BIT 0x08 /**< Indicates if DID present in ISO-DEP block. */
+#define NFC_T4T_DID_MASK 0x0F /**< DID field mask */
+#define NFCT_INTEN_MSK 0x1C5CFFu /**< Mask for all NFCT interrupts */
+
+
+#ifdef HAL_NFC_NRF52840_ENGINEERING_ABC_WORKAROUND
+ #define NRF_NFCT_ERRORSTATUS_ALL (NFCT_ERRORSTATUS_FRAMEDELAYTIMEOUT_Msk) /**< Mask for clearing all error flags in NFCT_ERRORSTATUS register */
+#else
+ #define NRF_NFCT_ERRORSTATUS_ALL (NFCT_ERRORSTATUS_NFCFIELDTOOWEAK_Msk | \
+ NFCT_ERRORSTATUS_NFCFIELDTOOSTRONG_Msk | \
+ NFCT_ERRORSTATUS_FRAMEDELAYTIMEOUT_Msk) /**< Mask for clearing all error flags in NFCT_ERRORSTATUS register */
+#endif // HAL_NFC_NRF52840_ENGINEERING_ABC_WORKAROUND
+
+#define NRF_NFCT_FRAMESTATUS_RX_MSK (NFCT_FRAMESTATUS_RX_OVERRUN_Msk | \
+ NFCT_FRAMESTATUS_RX_PARITYSTATUS_Msk | \
+ NFCT_FRAMESTATUS_RX_CRCERROR_Msk) /**< Mask for clearing all flags in NFCT_FRAMESTATUS_RX register */
+#define NFC_FIELD_ON_MASK NFCT_FIELDPRESENT_LOCKDETECT_Msk /**< Mask for checking FIELDPRESENT register for state: FIELD ON. */
+#define NFC_FIELD_OFF_MASK NFCT_FIELDPRESENT_FIELDPRESENT_Msk /**< Mask for checking FIELDPRESENT register for state: FIELD OFF. */
+
+#define NFC_T4T_FWI_TO_FWT(FWI) (256u * 16u * (1 << (FWI))) /**< Macro for calculating FWT (in number of NFC carrier periods) from FWI parameter. */
+#define NFC_T4T_WTXM_MAX(FWI) ( 1 << (NRF_T4T_FWI_LISTEN_MAX - (FWI))) /**< Macro for calculating WTXM based on 'NFC Forum Digital Protocol Specification Version 1.1, Requirement 15.2.2.9', and FRAMEDELAYMAX maximum register setting */
+
+/* Begin: Bugfix for FTPAN-xx (AUTOCOLRESCONFIG) */
+#define NRF_NFCT_AUTOCOLRESCONFIG (*(uint32_t volatile *)(0x4000559C))
+#define NRF_NFCT_AUTOCOLRESCONFIG_Pos 0
+/* End: Bugfix for FTPAN-xx */
+
+#define NRF_NFCT_DEFAULTSTATESLEEP (*(uint32_t volatile *)(0x40005420)) /**< The default state of NFCT. */
+#define NRF_NFCT_DEFAULTSTATESLEEP_MSK 0x1UL /**< Mask for checking the default state of NFCT. */
+
+#ifdef HAL_NFC_NRF52840_ENGINEERING_ABC_WORKAROUND
+ #define NRF_NFCT_ACTIVATE_CONDS_THR 2 /**< Number of required conditions to activate NFCT. */
+ #define NRF_NFCT_ACTIVATE_DELAY 1000 /**< Minimal delay in us between NFC field detection and activation of NFCT. */
+#endif // HAL_NFC_NRF52840_ENGINEERING_ABC_WORKAROUND
+
+typedef enum
+{
+ NFC_FIELD_STATE_NONE, /**< Initial value indicating no NFCT Field events. */
+ NFC_FIELD_STATE_OFF, /**< NFCT FIELDLOST Event has been set. */
+ NFC_FIELD_STATE_ON, /**< NFCT FIELDDETECTED Event has been set. */
+ NFC_FIELD_STATE_UNKNOWN /**< Both NFCT Field Events have been set - ambiguous state. */
+}nfct_field_sense_state_t;
+
+/* Static function declarations */
+static inline void nrf_nfct_event_clear(volatile uint32_t * p_event);
+static inline void nrf_nfct_clock_event_handler(nrf_drv_clock_evt_type_t event);
+static inline void nrf_nfct_field_event_handler(volatile nfct_field_sense_state_t field_state);
+static void hal_nfc_nfcid1_default_bytes(void);
+static void hal_nfc_nfcid1_registers_setup(void);
+
+/* Static data */
+static hal_nfc_callback_t m_nfc_lib_callback = (hal_nfc_callback_t) NULL; /**< Callback to nfc_lib layer */
+static void * m_nfc_lib_context; /**< Callback execution context */
+static volatile uint8_t m_nfc_rx_buffer[NFC_RX_BUFFER_SIZE] = {0}; /**< Buffer for NFC Rx data */
+static volatile bool m_slp_req_received = false; /**< Flag indicating that SLP_REQ Command was received */
+static volatile bool m_field_on = false; /**< Flag indicating that NFC Tag field is present */
+static nrf_drv_clock_handler_item_t m_clock_handler_item; /**< Clock event handler item structure */
+static volatile uint8_t m_fwi; /**< FWI parameter */
+static volatile uint8_t m_wtxm; /**< WTXM maximum value */
+static volatile uint8_t m_wtx_data[3]; /**< Tx buffer for an S(WTX) block */
+static volatile bool m_deselect = false; /**< Flag indicating reception of DESELECT command */
+static volatile bool m_swtx_sent = false; /**< Flag indicating that SWTX command has been sended. */
+static volatile bool m_pending_msg = false; /**< Flag signaling pending message during SWTX command execution. */
+static volatile const uint8_t * m_pending_msg_ptr = NULL; /**< Pointer to pending message buffer. */
+static volatile size_t m_pending_data_length = 0; /**< Length of pending message data. */
+static volatile bool m_t4t_tx_waiting = false; /**< Indicates if HAL is waiting for upper layer response to received command */
+static volatile uint8_t m_t4t_selres = NFC_T4T_SELRES_PROTOCOL; /**< Protocol bits setup in SEL_RES frame - can be modified using the library API */
+static volatile uint8_t m_did = 0; /**< DID field value. */
+static uint8_t m_nfcid1_length = 0; /**< Length of NFCID1 provided by user or 0 if not initialized yet */
+static uint8_t m_nfcid1_data[NFCID1_MAX_LENGHT] = {0}; /**< Content of NFCID1 */
+static volatile uint8_t m_t4t_active = false; /**< Indicates if NFC Tag is in 4A state (on reception of correct RATS command). */
+
+#ifdef HAL_NFC_NRF52840_ENGINEERING_ABC_WORKAROUND
+static volatile bool m_nfc_fieldevents_filter_active = false; /**< Flag indicating that field events are ignored. */
+static volatile uint32_t m_nfc_activate_conditions = 0; /**< Number of activation conditions that are met. */
+#endif // HAL_NFC_NRF52840_ENGINEERING_ABC_WORKAROUND
+
+#ifndef HAL_NFC_ENGINEERING_BC_FTPAN_WORKAROUND
+static volatile uint32_t m_nfc_fieldpresent_mask = NFC_FIELD_OFF_MASK; /**< Mask used for NFC Field polling in NFCT_FIELDPRESENT register */
+#endif // HAL_NFC_ENGINEERING_BC_FTPAN_WORKAROUND
+
+#ifdef HAL_NFC_ENGINEERING_BC_FTPAN_WORKAROUND
+
+static inline void hal_nfc_re_setup(void);
+static void hal_nfc_field_check(void);
+
+#define NRF_NFCT_POWER (*(uint32_t volatile *)(0x40005FFC))
+
+#define NFC_HAL_FIELDPRESENT_MASK (NFCT_FIELDPRESENT_LOCKDETECT_Msk | \
+ NFCT_FIELDPRESENT_FIELDPRESENT_Msk)
+
+#define NFC_HAL_FIELDPRESENT_IS_LOST ((NFCT_FIELDPRESENT_FIELDPRESENT_NoField << \
+ NFCT_FIELDPRESENT_FIELDPRESENT_Pos) | \
+ (NFCT_FIELDPRESENT_LOCKDETECT_NotLocked << \
+ NFCT_FIELDPRESENT_LOCKDETECT_Pos))
+
+#endif // HAL_NFC_ENGINEERING_BC_FTPAN_WORKAROUND
+
+#ifdef HAL_NFC_NRF52840_ENGINEERING_ABC_WORKAROUND
+static void hal_nfc_activate_check(void)
+{
+ static bool is_field_validation_pending = false;
+
+ if (is_field_validation_pending)
+ {
+ is_field_validation_pending = false;
+ m_nfc_fieldevents_filter_active = false;
+
+ // Check the field status with FIELDPRESENT and take action if field is lost.
+ nrf_nfct_field_event_handler(NFC_FIELD_STATE_UNKNOWN);
+ return;
+ }
+
+ m_nfc_activate_conditions++;
+ if (m_nfc_activate_conditions == NRF_NFCT_ACTIVATE_CONDS_THR)
+ {
+ m_nfc_activate_conditions = 0;
+
+ NRF_NFCT->TASKS_ACTIVATE = 1;
+ is_field_validation_pending = true;
+
+ // Start the timer second time to validate if tag has locked to the field
+ NRF_TIMER4->TASKS_CLEAR = 1;
+ NRF_TIMER4->TASKS_START = 1;
+ }
+}
+#endif // HAL_NFC_NRF52840_ENGINEERING_ABC_WORKAROUND
+
+#if defined(HAL_NFC_ENGINEERING_BC_FTPAN_WORKAROUND) || defined(HAL_NFC_NRF52840_ENGINEERING_ABC_WORKAROUND)
+
+static void field_timer_with_callback_config(void)
+{
+ NRF_TIMER4->MODE = TIMER_MODE_MODE_Timer << TIMER_MODE_MODE_Pos;
+ NRF_TIMER4->BITMODE = TIMER_BITMODE_BITMODE_16Bit << TIMER_BITMODE_BITMODE_Pos;
+ NRF_TIMER4->PRESCALER = 4 << TIMER_PRESCALER_PRESCALER_Pos;
+#ifdef HAL_NFC_ENGINEERING_BC_FTPAN_WORKAROUND
+ NRF_TIMER4->CC[0] = HAL_NFC_FIELD_TIMER_PERIOD << TIMER_CC_CC_Pos;
+#else
+ NRF_TIMER4->CC[0] = NRF_NFCT_ACTIVATE_DELAY << TIMER_CC_CC_Pos;
+#endif
+ NRF_TIMER4->SHORTS = TIMER_SHORTS_COMPARE0_CLEAR_Enabled << TIMER_SHORTS_COMPARE0_CLEAR_Pos;
+ NRF_TIMER4->INTENSET = TIMER_INTENSET_COMPARE0_Set << TIMER_INTENSET_COMPARE0_Pos;
+
+ NVIC_ClearPendingIRQ(TIMER4_IRQn);
+ NVIC_SetPriority(TIMER4_IRQn, NFCT_CONFIG_IRQ_PRIORITY);
+ NVIC_EnableIRQ(TIMER4_IRQn);
+}
+
+void TIMER4_IRQHandler(void)
+{
+ HAL_NFC_DEBUG_PIN_SET(HAL_NFC_TIMER4_EVENT_DEBUG_PIN);
+#ifdef HAL_NFC_ENGINEERING_BC_FTPAN_WORKAROUND
+ hal_nfc_field_check();
+#else
+ NRF_TIMER4->TASKS_SHUTDOWN = 1;
+ hal_nfc_activate_check();
+#endif
+ NRF_TIMER4->EVENTS_COMPARE[0] = 0;
+ HAL_NFC_DEBUG_PIN_CLEAR(HAL_NFC_TIMER4_EVENT_DEBUG_PIN);
+}
+
+#endif // defined(HAL_NFC_ENGINEERING_BC_FTPAN_WORKAROUND) || defined(HAL_NFC_NRF52840_ENGINEERING_ABC_WORKAROUND)
+
+/**
+ * @brief Common part of setup used for NFCT initialization and reinitialization.
+ */
+#ifdef HAL_NFC_ENGINEERING_BC_FTPAN_WORKAROUND
+static void hal_nfc_common_hw_setup()
+#else
+static inline void hal_nfc_common_hw_setup()
+#endif // HAL_NFC_ENGINEERING_BC_FTPAN_WORKAROUND
+{
+#ifdef HAL_NFC_NRF52840_ENGINEERING_ABC_WORKAROUND
+ if (type_52840_sample_check())
+ {
+ /* Begin: Bugfix for FTPAN-98 */
+ *(volatile uint32_t *) 0x4000568C = 0x00038148;
+ /* End: Bugfix for FTPAN-98 */
+ /* Begin: Bugfix for FTPAN-144 */
+ *(volatile uint32_t *) 0x4000561c = 0x01;
+ *(volatile uint32_t *) 0x4000562c = 0x3F;
+ *(volatile uint32_t *) 0x4000563c = 0x0;
+ /* End: Bugfix for FTPAN-144 */
+ }
+#endif // HAL_NFC_NRF52840_ENGINEERING_ABC_WORKAROUND
+
+/* Begin: Bugfix for FTPAN-17 */
+/* fixed by avoiding usage of FIELDLOST event */
+#ifdef HAL_NFC_ENGINEERING_BC_FTPAN_WORKAROUND
+ NRF_NFCT->INTENSET = (NFCT_INTENSET_FIELDDETECTED_Enabled << NFCT_INTENSET_FIELDDETECTED_Pos);
+#else
+ NRF_NFCT->INTENSET = (NFCT_INTENSET_FIELDDETECTED_Enabled << NFCT_INTENSET_FIELDDETECTED_Pos) |
+ (NFCT_INTENSET_FIELDLOST_Enabled << NFCT_INTENSET_FIELDLOST_Pos);
+#endif // HAL_NFC_ENGINEERING_BC_FTPAN_WORKAROUND
+/* End: Bugfix for FTPAN-17 */
+
+ NRF_NFCT->INTENSET = (NFCT_INTENSET_TXFRAMESTART_Enabled << NFCT_INTENSET_TXFRAMESTART_Pos);
+
+ NRF_NFCT->INTENSET = (NFCT_INTENSET_ERROR_Enabled << NFCT_INTENSET_ERROR_Pos) |
+ (NFCT_INTENSET_SELECTED_Enabled << NFCT_INTENSET_SELECTED_Pos);
+
+ hal_nfc_nfcid1_registers_setup();
+
+ /* Set FRAMEDELAYMAX to default setting */
+ uint8_t fwi = NFC_T4T_FWI_DEFAULT;
+
+ ret_code_t err_code = hal_nfc_parameter_set( HAL_NFC_PARAM_FWI, &fwi, sizeof(fwi));
+ ASSERT(err_code == NRF_SUCCESS);
+
+ /* Set PROTOCOL bits for Type 4A Tag */
+ NRF_NFCT->SELRES =
+ (m_t4t_selres << NFCT_SELRES_PROTOCOL_Pos) & NFCT_SELRES_PROTOCOL_Msk;
+
+ m_swtx_sent = false;
+ m_pending_msg = false;
+ m_pending_msg_ptr = NULL;
+ m_pending_data_length = 0;
+}
+
+/** @brief Setup NRF_NFCT->NFCID1 and NRF_NFCT->SENSRES registers based on m_nfcid1_data and m_nfcid1_length variables.
+ */
+static void hal_nfc_nfcid1_registers_setup(void)
+{
+ uint32_t sens_res_size; // Value that will be written to NRF_NFCT->SENSRES
+ uint8_t* p_nfcid_remaining_data; // Points to the first byte of m_nfcid1_data remaining to write to NRF_NFCT->NFCID1 registers
+
+ p_nfcid_remaining_data = m_nfcid1_data;
+
+ if (m_nfcid1_length == NFCID1_SINGLE_SIZE)
+ {
+ sens_res_size = NFCT_SENSRES_NFCIDSIZE_NFCID1Single;
+ }
+ else
+ {
+ if (m_nfcid1_length == NFCID1_DOUBLE_SIZE)
+ {
+ sens_res_size = NFCT_SENSRES_NFCIDSIZE_NFCID1Double;
+ }
+ else // then m_nfcid1_length == NFCID1_TRIPLE_SIZE
+ {
+ /* MSB of NFCID1_3RD_LAST register is not used - always 0 */
+ NRF_NFCT->NFCID1_3RD_LAST =
+ ((uint32_t) p_nfcid_remaining_data[0] << NFCID1_3RD_LAST_BYTE2_SHIFT) |
+ ((uint32_t) p_nfcid_remaining_data[1] << NFCID1_3RD_LAST_BYTE1_SHIFT) |
+ ((uint32_t) p_nfcid_remaining_data[2] << NFCID1_3RD_LAST_BYTE0_SHIFT);
+ p_nfcid_remaining_data += 3;
+ sens_res_size = NFCT_SENSRES_NFCIDSIZE_NFCID1Triple;
+ }
+ /* MSB of NFCID1_2ND_LAST register is not used - always 0 */
+ NRF_NFCT->NFCID1_2ND_LAST =
+ ((uint32_t) p_nfcid_remaining_data[0] << NFCID1_2ND_LAST_BYTE2_SHIFT) |
+ ((uint32_t) p_nfcid_remaining_data[1] << NFCID1_2ND_LAST_BYTE1_SHIFT) |
+ ((uint32_t) p_nfcid_remaining_data[2] << NFCID1_2ND_LAST_BYTE0_SHIFT);
+ p_nfcid_remaining_data += 3;
+ }
+
+ NRF_NFCT->NFCID1_LAST =
+ ((uint32_t) p_nfcid_remaining_data[0] << NFCID1_LAST_BYTE3_SHIFT) |
+ ((uint32_t) p_nfcid_remaining_data[1] << NFCID1_LAST_BYTE2_SHIFT) |
+ ((uint32_t) p_nfcid_remaining_data[2] << NFCID1_LAST_BYTE1_SHIFT) |
+ ((uint32_t) p_nfcid_remaining_data[3] << NFCID1_LAST_BYTE0_SHIFT);
+
+ /* Begin: Bugfix for FTPAN-25 (IC-9929) */
+ /* Workaround for wrong SENSRES values require using SDD00001, but here SDD00100 is used
+ because it's required to operate with Windows Phone */
+ NRF_NFCT->SENSRES =
+ (sens_res_size << NFCT_SENSRES_NFCIDSIZE_Pos) |
+ (NFCT_SENSRES_BITFRAMESDD_SDD00100 << NFCT_SENSRES_BITFRAMESDD_Pos);
+ /* End: Bugfix for FTPAN-25 (IC-9929)*/
+
+ m_t4t_active = false;
+ m_swtx_sent = false;
+ m_pending_msg = false;
+ m_pending_msg_ptr = NULL;
+ m_pending_data_length = 0;
+}
+
+
+ret_code_t hal_nfc_setup(hal_nfc_callback_t callback, void * p_context)
+{
+ m_nfc_lib_callback = callback;
+ m_nfc_lib_context = p_context;
+
+ if (m_nfcid1_length == 0)
+ {
+ m_nfcid1_length = NFCID1_DEFAULT_LENGHT;
+ hal_nfc_nfcid1_default_bytes();
+ }
+
+ hal_nfc_common_hw_setup();
+
+ /* Initialize SDK Clock module for handling high precission clock requests */
+ m_clock_handler_item.event_handler = nrf_nfct_clock_event_handler;
+ m_clock_handler_item.p_next = NULL;
+
+ ret_code_t err_code = nrf_drv_clock_init();
+
+#if defined(HAL_NFC_ENGINEERING_BC_FTPAN_WORKAROUND) || defined(HAL_NFC_NRF52840_ENGINEERING_ABC_WORKAROUND)
+ #if defined(HAL_NFC_NRF52840_ENGINEERING_ABC_WORKAROUND)
+ if (!type_52840_sample_check())
+ #endif // defined(HAL_NFC_NRF52840_ENGINEERING_ABC_WORKAROUND)
+ {
+ field_timer_with_callback_config();
+ }
+#endif // defined(HAL_NFC_ENGINEERING_BC_FTPAN_WORKAROUND) || defined(HAL_NFC_NRF52840_ENGINEERING_ABC_WORKAROUND)
+
+ NRF_LOG_INFO("Init");
+ HAL_NFC_DEBUG_PINS_INITIALIZE();
+
+ if ((err_code == NRF_SUCCESS) || (err_code == NRF_ERROR_MODULE_ALREADY_INITIALIZED))
+ {
+ return NRF_SUCCESS;
+ }
+ else
+ {
+ return NRF_ERROR_INTERNAL;
+ }
+}
+
+
+/**@brief Function for clearing an event flag in NRF_NFCT registers.
+ *
+ * @param[in] p_event Pointer to event register.
+ *
+ */
+static inline void nrf_nfct_event_clear(volatile uint32_t * p_event)
+{
+ *p_event = 0;
+
+ /* Perform read to ensure clearing is effective */
+ volatile uint32_t dummy = *p_event;
+ (void)dummy;
+}
+
+
+/**@brief Function for handling events from Clock Module.
+ *
+ * @param[in] event Clock event.
+ *
+ */
+static inline void nrf_nfct_clock_event_handler(nrf_drv_clock_evt_type_t event)
+{
+ switch (event)
+ {
+ case NRF_DRV_CLOCK_EVT_HFCLK_STARTED:
+ /* Activate NFCT only when HFXO is running */
+ HAL_NFC_DEBUG_PIN_SET(HAL_NFC_HCLOCK_ON_DEBUG_PIN); // DEBUG!
+
+#ifdef HAL_NFC_NRF52840_ENGINEERING_ABC_WORKAROUND
+ if (type_52840_final_check())
+ {
+ hal_nfc_activate_check();
+ }
+ else
+#endif // HAL_NFC_NRF52840_ENGINEERING_ABC_WORKAROUND
+ {
+ NRF_NFCT->TASKS_ACTIVATE = 1;
+ }
+
+ HAL_NFC_DEBUG_PIN_CLEAR(HAL_NFC_HCLOCK_ON_DEBUG_PIN); // DEBUG!
+ break;
+
+ default:
+ /* No implementation required */
+ break;
+ }
+}
+
+
+#ifdef HAL_NFC_ENGINEERING_BC_FTPAN_WORKAROUND
+static inline void nrf_nfct_field_lost_hfclk_handle(void)
+{
+ /* Begin: Bugfix for FTPAN-116 (IC-12886) */
+ // reset the NFC for release HFCLK
+ __DMB();
+ NRF_NFCT_POWER = 0;
+ __DMB();
+ NRF_NFCT_POWER = 1;
+ /* END: Bugfix for FTPAN-116 (IC-12886) */
+
+}
+#endif // HAL_NFC_ENGINEERING_BC_FTPAN_WORKAROUND
+
+#ifndef HAL_NFC_ENGINEERING_BC_FTPAN_WORKAROUND
+/**@brief Function for evaluating and handling NFC field events.
+ *
+ * @param[in] field_state Current field state.
+ *
+ */
+static inline void nrf_nfct_field_event_handler(volatile nfct_field_sense_state_t field_state)
+{
+#ifdef HAL_NFC_NRF52840_ENGINEERING_ABC_WORKAROUND
+ bool is_first_sample = type_52840_sample_check();
+
+ if((!is_first_sample) && (m_nfc_fieldevents_filter_active))
+ {
+ return;
+ }
+#endif // HAL_NFC_NRF52840_ENGINEERING_ABC_WORKAROUND
+
+ if (field_state == NFC_FIELD_STATE_UNKNOWN)
+ {
+ /* Probe NFC field */
+ uint32_t field_present = NRF_NFCT->FIELDPRESENT;
+
+ if (field_present & m_nfc_fieldpresent_mask)
+ {
+ field_state = NFC_FIELD_STATE_ON;
+ }
+ else
+ {
+ field_state = NFC_FIELD_STATE_OFF;
+ }
+ }
+
+ /* Field event service */
+ switch (field_state)
+ {
+ case NFC_FIELD_STATE_ON:
+ if (!m_field_on)
+ {
+ HAL_NFC_DEBUG_PIN_SET(HAL_NFC_HCLOCK_ON_DEBUG_PIN); // DEBUG!
+ nrf_drv_clock_hfclk_request(&m_clock_handler_item);
+
+#ifdef HAL_NFC_NRF52840_ENGINEERING_ABC_WORKAROUND
+ /* Begin: Bugfix for FTPAN-190 */
+ if (!is_first_sample)
+ {
+ m_nfc_activate_conditions = 0;
+ m_nfc_fieldevents_filter_active = true;
+
+ NRF_TIMER4->TASKS_CLEAR = 1;
+ NRF_TIMER4->TASKS_START = 1;
+ }
+ /* END: Bugfix for FTPAN-190 */
+#endif // HAL_NFC_NRF52840_ENGINEERING_ABC_WORKAROUND
+
+ HAL_NFC_DEBUG_PIN_CLEAR(HAL_NFC_HCLOCK_ON_DEBUG_PIN); // DEBUG!
+ }
+ m_field_on = true;
+ break;
+
+ case NFC_FIELD_STATE_OFF:
+ HAL_NFC_DEBUG_PIN_SET(HAL_NFC_HCLOCK_OFF_DEBUG_PIN); // DEBUG!
+
+#ifdef HAL_NFC_NRF52840_ENGINEERING_ABC_WORKAROUND
+ /* Begin: Bugfix for FTPAN-116 (IC-12886) */
+ if (is_first_sample)
+ {
+ *(volatile uint32_t *)0x40005010 = 1;
+ }
+ /* END: Bugfix for FTPAN-116 (IC-12886) */
+#endif // HAL_NFC_NRF52840_ENGINEERING_ABC_WORKAROUND
+
+ NRF_NFCT->TASKS_SENSE = 1;
+ nrf_drv_clock_hfclk_release();
+ m_field_on = false;
+
+ NRF_NFCT->INTENCLR =
+ (NFCT_INTENCLR_RXFRAMEEND_Clear << NFCT_INTENCLR_RXFRAMEEND_Pos) |
+ (NFCT_INTENCLR_RXERROR_Clear << NFCT_INTENCLR_RXERROR_Pos);
+
+ /* Change mask to FIELD_OFF state - trigger FIELD_ON even if HW has not locked to the field */
+ m_nfc_fieldpresent_mask = NFC_FIELD_OFF_MASK;
+
+ if ((m_nfc_lib_callback != NULL) )
+ {
+ m_nfc_lib_callback(m_nfc_lib_context, HAL_NFC_EVENT_FIELD_OFF, 0, 0);
+ }
+
+ /* Re-enable Auto Collision Resolution */
+ NRF_NFCT_AUTOCOLRESCONFIG = NRF_NFCT_AUTOCOLRESCONFIG &
+ ~(1u << NRF_NFCT_AUTOCOLRESCONFIG_Pos);
+ m_t4t_active = false;
+
+ /* Go back to default frame delay mode, bugfix for tag locking. */
+ NRF_NFCT->FRAMEDELAYMODE = NFCT_FRAMEDELAYMODE_FRAMEDELAYMODE_WindowGrid <<
+ NFCT_FRAMEDELAYMODE_FRAMEDELAYMODE_Pos;
+
+ HAL_NFC_DEBUG_PIN_CLEAR(HAL_NFC_HCLOCK_OFF_DEBUG_PIN); // DEBUG!
+ break;
+
+ default:
+ /* No implementation required */
+ break;
+ }
+}
+#endif // HAL_NFC_ENGINEERING_BC_FTPAN_WORKAROUND
+
+__STATIC_INLINE void hal_nfc_wtx_data_set(bool did_present)
+{
+ uint32_t wtx_data_size;
+
+ m_wtx_data[0] = NFC_T4T_S_WTX;
+ if (did_present)
+ {
+ m_wtx_data[0] |= NFC_T4T_DID_BIT;
+ m_wtx_data[1] = m_did;
+ m_wtx_data[2] = m_wtxm;
+ wtx_data_size = NFC_T4T_WTX_DID_SIZE;
+ }
+ else
+ {
+ m_wtx_data[1] = m_wtxm;
+ wtx_data_size = NFC_T4T_WTX_NO_DID_SIZE;
+ }
+
+ NRF_NFCT->PACKETPTR = (uint32_t) m_wtx_data;
+ NRF_NFCT->TXD.AMOUNT = (wtx_data_size << NFCT_TXD_AMOUNT_TXDATABYTES_Pos) &
+ NFCT_TXD_AMOUNT_TXDATABYTES_Msk;
+ NRF_NFCT->FRAMEDELAYMODE = NFCT_FRAMEDELAYMODE_FRAMEDELAYMODE_ExactVal <<
+ NFCT_FRAMEDELAYMODE_FRAMEDELAYMODE_Pos;
+ NRF_NFCT->TASKS_STARTTX = 1;
+ m_t4t_tx_waiting = true;
+}
+
+
+/** @brief Writes default values to m_nfcid1_data based on NRF_FICR->NFC registers.
+ */
+static void hal_nfc_nfcid1_default_bytes(void)
+{
+ uint32_t nfc_tag_header0 = NRF_FICR->NFC.TAGHEADER0;
+ uint32_t nfc_tag_header1 = NRF_FICR->NFC.TAGHEADER1;
+ uint32_t nfc_tag_header2 = NRF_FICR->NFC.TAGHEADER2;
+
+ m_nfcid1_data[0] = (uint8_t) LSB_32(nfc_tag_header0 >> 0);
+ m_nfcid1_data[1] = (uint8_t) LSB_32(nfc_tag_header0 >> 8);
+ m_nfcid1_data[2] = (uint8_t) LSB_32(nfc_tag_header0 >> 16);
+ m_nfcid1_data[3] = (uint8_t) LSB_32(nfc_tag_header1 >> 0);
+ m_nfcid1_data[4] = (uint8_t) LSB_32(nfc_tag_header1 >> 8);
+ m_nfcid1_data[5] = (uint8_t) LSB_32(nfc_tag_header1 >> 16);
+ m_nfcid1_data[6] = (uint8_t) LSB_32(nfc_tag_header1 >> 24);
+ m_nfcid1_data[7] = (uint8_t) LSB_32(nfc_tag_header2 >> 0);
+ m_nfcid1_data[8] = (uint8_t) LSB_32(nfc_tag_header2 >> 8);
+ m_nfcid1_data[9] = (uint8_t) LSB_32(nfc_tag_header2 >> 16);
+}
+
+
+/** @brief Resets NFCT peripheral to its default state before automatic collision resolution
+ * procedure.
+ */
+static inline void nrf_nfct_default_state_reset(void)
+{
+ if (NRF_NFCT_DEFAULTSTATESLEEP & NRF_NFCT_DEFAULTSTATESLEEP_MSK) // Default state is SLEEP_A
+ {
+ NRF_NFCT->TASKS_GOSLEEP = 1;
+ }
+ else // Default state is IDLE
+ {
+ NRF_NFCT->TASKS_GOIDLE = 1;
+ }
+
+ /* Disable RX here (will be enabled at SELECTED) */
+ NRF_NFCT->INTENCLR = NFCT_INTENCLR_RXFRAMEEND_Clear <<
+ NFCT_INTENCLR_RXFRAMEEND_Pos;
+}
+
+
+ret_code_t hal_nfc_parameter_set(hal_nfc_param_id_t id, void * p_data, size_t data_length)
+{
+ /* Parameter validation is done in upper-layer */
+
+ if (id == HAL_NFC_PARAM_FWI)
+ {
+ /* Update Frame Wait Time setting; possible settings are limited by NFCT hardware */
+ m_fwi = *((uint8_t *)p_data);
+
+ if (data_length != sizeof(uint8_t))
+ {
+ return NRF_ERROR_DATA_SIZE;
+ }
+ /* Frame Wait Time settings for first sample of 52840 */
+ if (type_52840_sample_check())
+ {
+ if (m_fwi > NFC_T4T_FWI_52840S_MAX)
+ {
+ return NRF_ERROR_INVALID_PARAM;
+ }
+ /* Set FRAMEDELAYTIME */
+ if (m_fwi == NFC_T4T_FWI_52840S_MAX)
+ {
+ NRF_NFCT->FRAMEDELAYMAX = NFCT_FRAMEDELAYMAX_52840S;
+ }
+ else
+ {
+ NRF_NFCT->FRAMEDELAYMAX = NFC_T4T_FWI_TO_FWT(m_fwi);
+ }
+ }
+ else
+ {
+ if (m_fwi > NFC_T4T_FWI_MAX)
+ {
+ return NRF_ERROR_INVALID_PARAM;
+ }
+
+ /* Set FRAMEDELAYTIME */
+ if (m_fwi == NFC_T4T_FWI_MAX)
+ {
+ NRF_NFCT->FRAMEDELAYMAX = NFCT_FRAMEDELAYMAX_FRAMEDELAYMAX_Msk;
+ }
+ else
+ {
+ NRF_NFCT->FRAMEDELAYMAX = NFC_T4T_FWI_TO_FWT(m_fwi);
+ }
+ }
+
+ if (NFC_T4T_WTXM_MAX(m_fwi) > NFC_T4T_WTXM_MAX_VALUE)
+ {
+ m_wtxm = NFC_T4T_WTXM_MAX_VALUE;
+ }
+ else
+ {
+ m_wtxm = NFC_T4T_WTXM_MAX(m_fwi);
+ }
+ }
+ else if (id == HAL_NFC_PARAM_SELRES)
+ {
+ /* Update SEL_RES 'Protocol' bits setting */
+ uint8_t sel_res = *((uint8_t *)p_data);
+
+ if (data_length != sizeof(uint8_t))
+ {
+ return NRF_ERROR_DATA_SIZE;
+ }
+ if (sel_res > NFC_T4T_SELRES_PROTOCOL_MSK)
+ {
+ return NRF_ERROR_INVALID_PARAM;
+ }
+
+ m_t4t_selres = sel_res;
+ NRF_NFCT->SELRES =
+ (m_t4t_selres << NFCT_SELRES_PROTOCOL_Pos) & NFCT_SELRES_PROTOCOL_Msk;
+ }
+ else if (id == HAL_NFC_PARAM_DID)
+ {
+ if (data_length > sizeof(uint8_t))
+ {
+ return NRF_ERROR_DATA_SIZE;
+ }
+
+ m_did = (data_length == sizeof(m_did)) ? *((uint8_t *)p_data) : 0;
+ }
+ else if (id == HAL_NFC_PARAM_NFCID1)
+ {
+ if (data_length == 1)
+ {
+ uint8_t id_length = *((uint8_t *) p_data);
+ if (id_length == NFCID1_SINGLE_SIZE || id_length == NFCID1_DOUBLE_SIZE ||
+ id_length == NFCID1_TRIPLE_SIZE)
+ {
+ m_nfcid1_length = id_length;
+ hal_nfc_nfcid1_default_bytes();
+ }
+ else
+ {
+ return NRF_ERROR_INVALID_LENGTH;
+ }
+ }
+ else if (data_length == NFCID1_SINGLE_SIZE || data_length == NFCID1_DOUBLE_SIZE ||
+ data_length == NFCID1_TRIPLE_SIZE)
+ {
+ m_nfcid1_length = (uint8_t) data_length;
+ memcpy(m_nfcid1_data, p_data, data_length);
+ }
+ else
+ {
+ return NRF_ERROR_INVALID_LENGTH;
+ }
+ hal_nfc_nfcid1_registers_setup();
+ }
+ else
+ {
+ /* No implementation needed */
+ }
+
+ return NRF_SUCCESS;
+}
+
+/* This function is used by nfc_lib for unit testing only */
+ret_code_t hal_nfc_parameter_get(hal_nfc_param_id_t id, void * p_data, size_t * p_max_data_length)
+{
+ if (*p_max_data_length < 1)
+ {
+ *p_max_data_length = 1;
+ return NRF_ERROR_DATA_SIZE;
+ }
+
+ if (id == HAL_NFC_PARAM_FWI)
+ {
+ *((uint8_t *) p_data) = m_fwi;
+ *p_max_data_length = sizeof(m_fwi);
+ }
+ else if (id == HAL_NFC_PARAM_SELRES)
+ {
+ /* Get SEL_RES 'Protocol' bits setting */
+ *((uint8_t *) p_data) = m_t4t_selres;
+ *p_max_data_length = sizeof(m_t4t_selres);
+ }
+ else if (id == HAL_NFC_PARAM_DID)
+ {
+ *((uint8_t *) p_data) = m_did;
+ *p_max_data_length = sizeof(m_did);
+ }
+ else if (id == HAL_NFC_PARAM_NFCID1)
+ {
+ if (m_nfcid1_length == 0)
+ {
+ m_nfcid1_length = NFCID1_DEFAULT_LENGHT;
+ hal_nfc_nfcid1_default_bytes();
+ }
+
+ if (*p_max_data_length < (size_t) m_nfcid1_length)
+ {
+ return NRF_ERROR_DATA_SIZE;
+ }
+
+ *p_max_data_length = (size_t) m_nfcid1_length;
+ memcpy(p_data, m_nfcid1_data, m_nfcid1_length);
+ }
+ else
+ {
+ /* No implementation needed */
+ }
+
+ return NRF_SUCCESS;
+}
+
+
+ret_code_t hal_nfc_start(void)
+{
+ NRF_NFCT->ERRORSTATUS = NRF_NFCT_ERRORSTATUS_ALL;
+ NRF_NFCT->TASKS_SENSE = 1;
+
+ NVIC_ClearPendingIRQ(NFCT_IRQn);
+ NVIC_SetPriority(NFCT_IRQn, NFCT_CONFIG_IRQ_PRIORITY);
+ NVIC_EnableIRQ(NFCT_IRQn);
+
+ NRF_LOG_INFO("Start");
+ return NRF_SUCCESS;
+}
+
+
+ret_code_t hal_nfc_send(const uint8_t * p_data, size_t data_length)
+{
+ if (data_length == 0)
+ {
+ return NRF_ERROR_DATA_SIZE;
+ }
+
+ if(m_swtx_sent)
+ {
+ m_pending_msg_ptr = p_data;
+ m_pending_data_length = data_length;
+ m_pending_msg = true;
+
+ NRF_LOG_DEBUG("Pending message.");
+ return NRF_SUCCESS;
+ }
+
+ m_t4t_tx_waiting = false;
+
+ /* Ignore previous TX END events, SW takes care only for data frames which tranmission is triggered in this function */
+ nrf_nfct_event_clear(&NRF_NFCT->EVENTS_TXFRAMEEND);
+
+ NRF_NFCT->INTENSET = (NFCT_INTENSET_TXFRAMEEND_Enabled << NFCT_INTENSET_TXFRAMEEND_Pos); //Moved to the end in T4T to avoid delaying TASKS_STARTX
+ NRF_NFCT->PACKETPTR = (uint32_t) p_data;
+ NRF_NFCT->TXD.AMOUNT = (data_length << NFCT_TXD_AMOUNT_TXDATABYTES_Pos) &
+ NFCT_TXD_AMOUNT_TXDATABYTES_Msk;
+ NRF_NFCT->FRAMEDELAYMODE = NFCT_FRAMEDELAYMODE_FRAMEDELAYMODE_WindowGrid <<
+ NFCT_FRAMEDELAYMODE_FRAMEDELAYMODE_Pos;
+ NRF_NFCT->TASKS_STARTTX = 1;
+
+ NRF_LOG_INFO("Send");
+ return NRF_SUCCESS;
+}
+
+
+ret_code_t hal_nfc_stop(void)
+{
+ NRF_NFCT->TASKS_DISABLE = 1;
+
+ NRF_LOG_INFO("Stop");
+ return NRF_SUCCESS;
+}
+
+
+ret_code_t hal_nfc_done(void)
+{
+ m_nfc_lib_callback = (hal_nfc_callback_t) NULL;
+
+ return NRF_SUCCESS;
+}
+
+
+void NFCT_IRQHandler(void)
+{
+ nfct_field_sense_state_t current_field = NFC_FIELD_STATE_NONE;
+
+ HAL_NFC_DEBUG_PIN_SET(HAL_NFC_NFC_EVENT_DEBUG_PIN); // DEBUG!
+
+ if (NRF_NFCT->EVENTS_FIELDDETECTED && (NRF_NFCT->INTEN & NFCT_INTEN_FIELDDETECTED_Msk))
+ {
+ nrf_nfct_event_clear(&NRF_NFCT->EVENTS_FIELDDETECTED);
+ HAL_NFC_DEBUG_PIN_SET(HAL_NFC_DETECT_EVENT_DEBUG_PIN); // DEBUG!
+ current_field = NFC_FIELD_STATE_ON;
+ HAL_NFC_DEBUG_PIN_CLEAR(HAL_NFC_DETECT_EVENT_DEBUG_PIN); // DEBUG!
+
+ NRF_LOG_DEBUG("Field detected");
+ }
+
+#ifndef HAL_NFC_ENGINEERING_BC_FTPAN_WORKAROUND
+ if (NRF_NFCT->EVENTS_FIELDLOST && (NRF_NFCT->INTEN & NFCT_INTEN_FIELDLOST_Msk))
+ {
+ nrf_nfct_event_clear(&NRF_NFCT->EVENTS_FIELDLOST);
+ current_field =
+ (current_field == NFC_FIELD_STATE_NONE) ? NFC_FIELD_STATE_OFF : NFC_FIELD_STATE_UNKNOWN;
+
+ NRF_LOG_DEBUG("Field lost");
+ }
+#endif // HAL_NFC_ENGINEERING_BC_FTPAN_WORKAROUND
+
+ /* Perform actions if any FIELD event is active */
+ if (current_field != NFC_FIELD_STATE_NONE)
+ {
+ nrf_nfct_field_event_handler(current_field);
+ }
+
+ if (NRF_NFCT->EVENTS_RXFRAMEEND && (NRF_NFCT->INTEN & NFCT_INTEN_RXFRAMEEND_Msk))
+ {
+ /* Take into account only number of whole bytes */
+ uint32_t rx_status = 0;
+ uint32_t rx_data_size = ((NRF_NFCT->RXD.AMOUNT & NFCT_RXD_AMOUNT_RXDATABYTES_Msk) >>
+ NFCT_RXD_AMOUNT_RXDATABYTES_Pos) - NFC_CRC_SIZE;
+ nrf_nfct_event_clear(&NRF_NFCT->EVENTS_RXFRAMEEND);
+
+ if (NRF_NFCT->EVENTS_RXERROR && (NRF_NFCT->INTEN & NFCT_INTEN_RXERROR_Msk))
+ {
+ rx_status = (NRF_NFCT->FRAMESTATUS.RX & NRF_NFCT_FRAMESTATUS_RX_MSK);
+ nrf_nfct_event_clear(&NRF_NFCT->EVENTS_RXERROR);
+
+ NRF_LOG_DEBUG("Rx error (0x%x)", (unsigned int) rx_status);
+
+ /* Clear rx frame status */
+ NRF_NFCT->FRAMESTATUS.RX = NRF_NFCT_FRAMESTATUS_RX_MSK;
+ }
+
+ /* Ignore all NFC-A data frames with Transmission Error */
+ if (rx_status)
+ {
+ /* Go back to idle state if currently in the ACTIVE_A state */
+ if (!m_t4t_active)
+ {
+ nrf_nfct_default_state_reset();
+ }
+ /* Stay in the CARD_EMULATOR_4A state */
+ else
+ {
+ /* Command with Transmission Error, so wait for next frame reception */
+ NRF_NFCT->TASKS_ENABLERXDATA = 1;
+ }
+ }
+ else
+ {
+ /* Look for NFC-A Commands */
+ if (!m_t4t_active)
+ {
+ // 'NFC Forum Digital Protocol Technical Specification 2.0, 14.6.1.13' */
+ if ((m_nfc_rx_buffer[0] == NFC_T4T_RATS_CMD) &&
+ ((m_nfc_rx_buffer[1] & NFC_T4T_RATS_DID_MASK) != NFC_T4T_RATS_DID_RFU))
+ {
+ /* Disable Auto Collision Resolution */
+ NRF_NFCT_AUTOCOLRESCONFIG = NRF_NFCT_AUTOCOLRESCONFIG |
+ (1u << NRF_NFCT_AUTOCOLRESCONFIG_Pos);
+ m_t4t_active = true;
+ NRF_LOG_DEBUG("RX: T4T Activate");
+ }
+ /* Indicate that SLP_REQ was received - this will cause FRAMEDELAYTIMEOUT error */
+ else if (m_nfc_rx_buffer[0] == NFC_SLP_REQ_CMD)
+ {
+ // disable RX here (will enable at SELECTED)
+ m_slp_req_received = true;
+ NRF_NFCT->INTENCLR = NFCT_INTENCLR_RXFRAMEEND_Clear << NFCT_INTENCLR_RXFRAMEEND_Pos;
+ }
+ else
+ {
+ nrf_nfct_default_state_reset();
+ }
+ }
+ /* Look for Tag 4 Type Commands */
+ else
+ {
+ bool did_present;
+ uint8_t did;
+
+ did_present = (m_nfc_rx_buffer[0] & NFC_T4T_DID_BIT) != 0;
+ did = m_did;
+
+ // React only to the ISO-DEP blocks that are directed to our tag.
+ if ((!did_present) && (did > 0)) // 'NFC Forum Digital Protocol Technical Specification 2.0, 16.1.2.12' */
+ {
+ /* Not our ISO-DEP block, so wait for next frame reception */
+ NRF_NFCT->TASKS_ENABLERXDATA = 1;
+ }
+ else if ((!did_present) || (did == (m_nfc_rx_buffer[1] & NFC_T4T_DID_MASK)))
+ {
+ if ((m_nfc_rx_buffer[0] & NFC_T4T_S_BLOCK_MSK) == NFC_T4T_S_DESELECT)
+ {
+ m_deselect = true;
+ NRF_LOG_DEBUG("RX: T4T Deselect");
+ }
+ else if (m_swtx_sent && ((m_nfc_rx_buffer[0] & NFC_T4T_S_BLOCK_MSK) == NFC_T4T_S_WTX))
+ {
+ m_swtx_sent = false;
+
+ NRF_LOG_DEBUG("RX: S(WTX) response");
+
+ if (m_pending_msg)
+ {
+ m_pending_msg = false;
+
+ nrf_nfct_event_clear(&NRF_NFCT->EVENTS_TXFRAMEEND);
+
+ NRF_NFCT->INTENSET = (NFCT_INTENSET_TXFRAMEEND_Enabled <<
+ NFCT_INTENSET_TXFRAMEEND_Pos);
+ NRF_NFCT->PACKETPTR = (uint32_t) m_pending_msg_ptr;
+ NRF_NFCT->TXD.AMOUNT = (m_pending_data_length <<
+ NFCT_TXD_AMOUNT_TXDATABYTES_Pos) &
+ NFCT_TXD_AMOUNT_TXDATABYTES_Msk;
+ NRF_NFCT->FRAMEDELAYMODE = NFCT_FRAMEDELAYMODE_FRAMEDELAYMODE_WindowGrid <<
+ NFCT_FRAMEDELAYMODE_FRAMEDELAYMODE_Pos;
+ NRF_NFCT->TASKS_STARTTX = 1;
+
+ m_t4t_tx_waiting = false;
+ NRF_LOG_DEBUG("Sending pending message!");
+ }
+ else
+ {
+ hal_nfc_wtx_data_set(did_present);
+ }
+ }
+ else if ((m_nfc_rx_buffer[0] & NFC_T4T_BLOCK_MSK) == NFC_T4T_I_BLOCK)
+ {
+ /* Set up default transmission of S(WTX) block. Tx will be executed only if FDT timer
+ * expires (FrameDelayMode-ExactVal) before hal_nfc_send is called */
+ hal_nfc_wtx_data_set(did_present);
+
+ NRF_NFCT->INTENSET = (NFCT_INTENSET_TXFRAMEEND_Enabled <<
+ NFCT_INTENSET_TXFRAMEEND_Pos);
+ }
+ else
+ {
+ /* Not a valid ISO-DEP block, so wait for next frame reception */
+ NRF_NFCT->TASKS_ENABLERXDATA = 1;
+ }
+ }
+ else
+ {
+ /* Not our ISO-DEP block, so wait for next frame reception */
+ NRF_NFCT->TASKS_ENABLERXDATA = 1;
+ }
+ }
+
+ if (m_nfc_lib_callback != NULL)
+ {
+ /* This callback should trigger transmission of READ Response */
+ m_nfc_lib_callback(m_nfc_lib_context,
+ HAL_NFC_EVENT_DATA_RECEIVED,
+ (void *)m_nfc_rx_buffer,
+ rx_data_size);
+ }
+ /* Clear TXFRAMESTART EVENT so it can be checked in hal_nfc_send */
+ nrf_nfct_event_clear(&NRF_NFCT->EVENTS_TXFRAMESTART);
+ }
+ NRF_LOG_DEBUG("Rx fend");
+ }
+
+ if (NRF_NFCT->EVENTS_TXFRAMEEND && (NRF_NFCT->INTEN & NFCT_INTEN_TXFRAMEEND_Msk))
+ {
+ nrf_nfct_event_clear(&NRF_NFCT->EVENTS_TXFRAMEEND);
+
+ /* Disable TX END event to ignore frame transmission other than READ response */
+ NRF_NFCT->INTENCLR = (NFCT_INTENCLR_TXFRAMEEND_Clear << NFCT_INTENCLR_TXFRAMEEND_Pos);
+
+ if (m_deselect)
+ {
+ /* Re-enable Auto Collision Resolution */
+ NRF_NFCT_AUTOCOLRESCONFIG = NRF_NFCT_AUTOCOLRESCONFIG &
+ ~(1u << NRF_NFCT_AUTOCOLRESCONFIG_Pos);
+ NRF_NFCT->TASKS_GOSLEEP = 1;
+ /* Disable RX here (will be enabled at SELECTED) */
+ NRF_NFCT->INTENCLR = NFCT_INTENCLR_RXFRAMEEND_Clear <<
+ NFCT_INTENCLR_RXFRAMEEND_Pos;
+ m_deselect = false;
+ m_t4t_active = false;
+ }
+ else
+ {
+ /* Set up for reception */
+ NRF_NFCT->PACKETPTR = (uint32_t) m_nfc_rx_buffer;
+ NRF_NFCT->MAXLEN = NFC_RX_BUFFER_SIZE;
+ NRF_NFCT->TASKS_ENABLERXDATA = 1;
+ NRF_NFCT->INTENSET =
+ (NFCT_INTENSET_RXFRAMEEND_Enabled << NFCT_INTENSET_RXFRAMEEND_Pos) |
+ (NFCT_INTENSET_RXERROR_Enabled << NFCT_INTENSET_RXERROR_Pos);
+ }
+
+ if (m_nfc_lib_callback != NULL)
+ {
+ m_nfc_lib_callback(m_nfc_lib_context, HAL_NFC_EVENT_DATA_TRANSMITTED, 0, 0);
+ }
+
+ NRF_LOG_DEBUG("Tx fend");
+ }
+
+ if (NRF_NFCT->EVENTS_SELECTED && (NRF_NFCT->INTEN & NFCT_INTEN_SELECTED_Msk))
+ {
+ nrf_nfct_event_clear(&NRF_NFCT->EVENTS_SELECTED);
+
+ /* Clear also RX END and RXERROR events because SW does not take care of commands which were received before selecting the tag */
+ nrf_nfct_event_clear(&NRF_NFCT->EVENTS_RXFRAMEEND);
+ nrf_nfct_event_clear(&NRF_NFCT->EVENTS_RXERROR);
+
+ /* Set up registers for EasyDMA and start receiving packets */
+ NRF_NFCT->PACKETPTR = (uint32_t) m_nfc_rx_buffer;
+ NRF_NFCT->MAXLEN = NFC_RX_BUFFER_SIZE;
+ NRF_NFCT->TASKS_ENABLERXDATA = 1;
+
+ NRF_NFCT->INTENSET = (NFCT_INTENSET_RXFRAMEEND_Enabled << NFCT_INTENSET_RXFRAMEEND_Pos) |
+ (NFCT_INTENSET_RXERROR_Enabled << NFCT_INTENSET_RXERROR_Pos);
+
+ /* At this point any previous error status can be ignored */
+ NRF_NFCT->FRAMESTATUS.RX = NRF_NFCT_FRAMESTATUS_RX_MSK;
+ NRF_NFCT->ERRORSTATUS = NRF_NFCT_ERRORSTATUS_ALL;
+
+#ifndef HAL_NFC_ENGINEERING_BC_FTPAN_WORKAROUND
+ /* Change mask to FIELD_ON state - trigger FIELD_ON only if HW has locked to the field */
+ m_nfc_fieldpresent_mask = NFC_FIELD_ON_MASK;
+#endif // HAL_NFC_ENGINEERING_BC_FTPAN_WORKAROUND
+
+ if (m_nfc_lib_callback != NULL)
+ {
+ m_nfc_lib_callback(m_nfc_lib_context, HAL_NFC_EVENT_FIELD_ON, 0, 0);
+ }
+
+ m_t4t_active = false;
+ m_swtx_sent = false;
+ m_pending_msg = false;
+ m_pending_msg_ptr = NULL;
+ m_pending_data_length = 0;
+
+ NRF_LOG_DEBUG("Selected");
+ }
+
+ if (NRF_NFCT->EVENTS_ERROR && (NRF_NFCT->INTEN & NFCT_INTEN_ERROR_Msk))
+ {
+ uint32_t err_status = NRF_NFCT->ERRORSTATUS;
+ nrf_nfct_event_clear(&NRF_NFCT->EVENTS_ERROR);
+
+ /* Clear FRAMEDELAYTIMEOUT error (expected HW behaviour) when SLP_REQ command was received */
+ if ((err_status & NFCT_ERRORSTATUS_FRAMEDELAYTIMEOUT_Msk) && m_slp_req_received)
+ {
+ NRF_NFCT->ERRORSTATUS = NFCT_ERRORSTATUS_FRAMEDELAYTIMEOUT_Msk;
+ m_slp_req_received = false;
+
+ NRF_LOG_DEBUG("RX: SLP_REQ");
+ }
+ /* Report any other error */
+ err_status &= ~NFCT_ERRORSTATUS_FRAMEDELAYTIMEOUT_Msk;
+
+ if (err_status)
+ {
+ NRF_LOG_DEBUG("Error (0x%x)", (unsigned int) err_status);
+ }
+
+ /* Clear error status */
+ NRF_NFCT->ERRORSTATUS = NRF_NFCT_ERRORSTATUS_ALL;
+ }
+
+ if (NRF_NFCT->EVENTS_TXFRAMESTART && (NRF_NFCT->INTEN & NFCT_INTEN_TXFRAMESTART_Msk))
+ {
+ nrf_nfct_event_clear(&NRF_NFCT->EVENTS_TXFRAMESTART);
+
+ if (m_t4t_tx_waiting)
+ {
+ m_t4t_tx_waiting = false;
+ m_swtx_sent = true;
+
+ NRF_LOG_DEBUG("Response timeout, sending WTX!");
+ }
+ }
+
+ HAL_NFC_DEBUG_PIN_CLEAR(HAL_NFC_NFC_EVENT_DEBUG_PIN); // DEBUG!
+}
+
+
+#ifdef HAL_NFC_ENGINEERING_BC_FTPAN_WORKAROUND
+
+#ifdef HAL_NFC_NRF52840_ENGINEERING_ABC_WORKAROUND
+ #error Wrong workaround combination
+#endif
+
+static uint32_t field_state_cnt = 0;
+/**
+ * @brief Function for evaluating and handling NFC fieldlost event.
+ */
+static void hal_nfc_field_check(void)
+{
+ uint32_t nfc_fieldpresen_masked;
+
+ nfc_fieldpresen_masked = NRF_NFCT->FIELDPRESENT & NFC_HAL_FIELDPRESENT_MASK;
+
+ if (nfc_fieldpresen_masked == NFC_HAL_FIELDPRESENT_IS_LOST)
+ {
+ ++field_state_cnt;
+ if (field_state_cnt > 7)
+ {
+ HAL_NFC_DEBUG_PIN_SET(HAL_NFC_HCLOCK_OFF_DEBUG_PIN); // DEBUG!
+
+ NRF_TIMER4->TASKS_SHUTDOWN = 1;
+
+ nrf_drv_clock_hfclk_release();
+
+ nrf_nfct_field_lost_hfclk_handle();
+
+ if ((m_nfc_lib_callback != NULL) )
+ {
+ m_nfc_lib_callback(m_nfc_lib_context, HAL_NFC_EVENT_FIELD_OFF, 0, 0);
+ }
+ m_field_on = false;
+
+ /* Begin: Bugfix for FTPAN-116 (IC-12886) */
+ // resume the NFCT to initialized state
+ hal_nfc_re_setup();
+ /* End: Bugfix for FTPAN-116 (IC-12886) */
+
+ HAL_NFC_DEBUG_PIN_CLEAR(HAL_NFC_HCLOCK_OFF_DEBUG_PIN); // DEBUG!
+ }
+
+ return;
+ }
+
+ field_state_cnt = 0;
+}
+
+
+/**
+ * @brief Function for enablinge hight precision clock and start eveluating fieldlost event.
+ */
+static inline void nrf_nfct_field_event_handler(volatile nfct_field_sense_state_t field_state)
+{
+ if (!m_field_on)
+ {
+ HAL_NFC_DEBUG_PIN_SET(HAL_NFC_HCLOCK_ON_DEBUG_PIN); // DEBUG!
+ nrf_drv_clock_hfclk_request(&m_clock_handler_item);
+
+ NRF_TIMER4->TASKS_CLEAR = 1;
+ NRF_TIMER4->TASKS_START = 1;
+ field_state_cnt = 0;
+
+ HAL_NFC_DEBUG_PIN_CLEAR(HAL_NFC_HCLOCK_ON_DEBUG_PIN); // DEBUG!
+ }
+ m_field_on = true;
+}
+
+
+/**
+ * @brief Function for resume the NFCT to initialized state after software's reset.
+ */
+static inline void hal_nfc_re_setup(void)
+{
+ hal_nfc_common_hw_setup();
+
+ NRF_LOG_INFO("Reinitialize");
+}
+#endif // HAL_NFC_ENGINEERING_BC_FTPAN_WORKAROUND
+
+#endif // NFC_T4T_HAL_ENABLED
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/t4t_lib/hal_t4t/hal_nfc_t4t.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/t4t_lib/hal_t4t/hal_nfc_t4t.h
new file mode 100644
index 0000000..4ffc9e1
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/t4t_lib/hal_t4t/hal_nfc_t4t.h
@@ -0,0 +1,203 @@
+/**
+ * Copyright (c) 2016 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+
+#ifndef HAL_NFC_H__
+#define HAL_NFC_H__
+
+/** @file
+ * @defgroup nfc_t4t_hal NFC Type 4 Tag HAL
+ * @{
+ * @ingroup nfc_t4t
+ * @brief @tagAPI52 Hardware abstraction layer for the NFC Type 4 Tag library.
+ *
+ * @note Before the NFCT peripheral enters ACTIVATED state, the HFXO must be running.
+ * To fulfill this requirement and allow other software modules to also request the HFXO, the NFC Type 4 Tag HAL uses @ref nrf_drv_clock module.
+ *
+ */
+
+#include <stdint.h>
+#include <string.h>
+#include <sdk_errors.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** @brief Events passed to the upper-layer callback function. */
+typedef enum {
+ HAL_NFC_EVENT_FIELD_ON, ///< Field is detected.
+ HAL_NFC_EVENT_FIELD_OFF, ///< Field is lost.
+ HAL_NFC_EVENT_DATA_RECEIVED, ///< Data is received.
+ HAL_NFC_EVENT_DATA_TRANSMITTED ///< Data is transmitted.
+} hal_nfc_event_t;
+
+
+/** @brief Parameter IDs for the set/get function. */
+typedef enum {
+ HAL_NFC_PARAM_ID_TESTING, ///< Used for unit tests.
+ HAL_NFC_PARAM_FWI, ///< Frame Wait Time parameter.
+ HAL_NFC_PARAM_SELRES, ///< Parameter for setting the 'Protocol' bits for SEL_RES packet.
+ HAL_NFC_PARAM_NFCID1, /**< NFCID1 value, data can be 4, 7, or 10 bytes long (simple, double, or triple size).
+ To use default NFCID1 of specific length pass one byte containing requested length.
+ Default 7-byte NFCID1 will be used if this parameter was not set before nfc_t4t_setup(). */
+ HAL_NFC_PARAM_DID, ///< Parameter for DID field management.
+ HAL_NFC_PARAM_ID_UNKNOWN
+} hal_nfc_param_id_t;
+
+
+/** @brief Callback from HAL_NFC layer into the upper layer.
+ *
+ * If event == HAL_NFC_EVENT_DATA_RECEIVED:
+ * p_data points to the received packet. The memory belongs to the HAL_NFC layer and
+ * is guaranteed to be valid only until the callback returns.
+ *
+ * If event == HAL_NFC_EVENT_DATA_TRANSMITTED:
+ * p_data points to the transmitted packet. The memory belongs to the application.
+ *
+ * If event == \<Other event\>:
+ * p_data definition is event-specific (to be defined).
+ *
+ * @param[in] p_context Context for callback execution.
+ * @param[in] event The event that occurred.
+ * @param[in] p_data Received/transmitted data or NULL.
+ * @param[in] data_length Size of the received/transmitted packet.
+ */
+typedef void (* hal_nfc_callback_t)(void * p_context,
+ hal_nfc_event_t event,
+ const uint8_t * p_data,
+ size_t data_length);
+
+
+/** @brief Function for initializing the NFC layer.
+ *
+ * This function provides a pointer to a callback function and the callback context
+ * to the NFC layer.
+ *
+ * @param[in] callback Pointer to the callback function.
+ * @param[in] p_context Context of callback.
+ *
+ * @retval NRF_SUCCESS If the NFC layer was initialized successfully. If one
+ * of the arguments was invalid, an error code is returned.
+ */
+ret_code_t hal_nfc_setup(hal_nfc_callback_t callback, void * p_context);
+
+
+/** @brief Function for setting a HAL_NFC parameter.
+ *
+ * This function allows to set any parameter defined as available by HAL_NFC.
+ *
+ * @param[in] id ID of the parameter to set.
+ * @param[in] p_data Pointer to the buffer containing the data to set.
+ * @param[in] data_length Size of the buffer containing the data to set.
+ *
+ * @retval NRF_SUCCESS If the parameter was set successfully. If one of the arguments
+ * was invalid (for example, wrong data length), an error code
+ * is returned.
+ */
+ret_code_t hal_nfc_parameter_set(hal_nfc_param_id_t id, void * p_data, size_t data_length);
+
+
+/** @brief Function for querying a HAL_NFC parameter value.
+ *
+ * The queried value will be placed into the passed data buffer. If the buffer
+ * is too small, p_max_data_length will contain the required buffer size.
+ *
+ * @param[in] id ID of the parameter to query.
+ * @param[in, out] p_data Pointer to a buffer receiving the queried data.
+ * @param[in, out] p_max_data_length Size of the buffer. It receives the required size if buffer is too small.
+ *
+ * @retval NRF_SUCCESS If the parameter was received successfully. If one of the arguments
+ * was invalid (for example, the buffer was too small), an error code
+ * is returned.
+ */
+ret_code_t hal_nfc_parameter_get(hal_nfc_param_id_t id, void * p_data, size_t * p_max_data_length);
+
+
+/** @brief Function for starting the NFC subsystem.
+ *
+ * After this function completes, NFC readers will be able to detect the chip.
+ *
+ * @retval NRF_SUCCESS If the NFC subsystem was started successfully. If the NFC
+ * subsystem could not be started, an error code is returned.
+ */
+ret_code_t hal_nfc_start(void);
+
+
+/** @brief Function for sending a packet to the connected NFC reader.
+ *
+ * The provided data buffer belongs to the caller and is guaranteed to be
+ * valid until the HAL_NFC_EVENT_DATA_TRANSMITTED event is received by the
+ * callback.
+ *
+ * @param[in] p_data The data packet to send.
+ * @param[in] data_length Size of the packet in bytes.
+ *
+ * @retval NRF_SUCCESS If the packet was sent. Otherwise, an error code is returned.
+ */
+ret_code_t hal_nfc_send(const uint8_t * p_data, size_t data_length);
+
+
+/** @brief Function for stopping the NFC subsystem.
+ *
+ * After this function returns, NFC readers will no longer be able to connect
+ * to the chip.
+ *
+ * @retval NRF_SUCCESS If the NFC subsystem was stopped. Otherwise, an error code
+ * is returned.
+ */
+ret_code_t hal_nfc_stop(void);
+
+
+/** @brief Function for releasing resources.
+ *
+ * After this call returns, the callback is considered invalid and no more
+ * events will be posted to it.
+ *
+ * @retval NRF_SUCCESS This function always succeeds.
+ */
+ret_code_t hal_nfc_done(void);
+
+#ifdef __cplusplus
+}
+#endif
+
+/** @} */
+#endif /* HAL_NFC_H__ */
+
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/t4t_lib/license.txt b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/t4t_lib/license.txt
new file mode 100644
index 0000000..1e65dd2
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/t4t_lib/license.txt
@@ -0,0 +1,36 @@
+Copyright (c) 2016 - 2018, Telit Communications Cyprus Ltd
+
+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, except as embedded into a Nordic
+ Semiconductor ASA integrated circuit in a product or a software update for
+ such product, 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.
+
+4. This software, with or without modification, must only be used with a
+ Nordic Semiconductor ASA integrated circuit.
+
+5. Any software provided in binary form under this license must not be reverse
+ engineered, decompiled, modified and/or disassembled.
+
+THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/t4t_lib/nfc_fixes.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/t4t_lib/nfc_fixes.h
new file mode 100644
index 0000000..e39e14f
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/t4t_lib/nfc_fixes.h
@@ -0,0 +1,132 @@
+/**
+ * Copyright (c) 2015 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+
+#ifndef NFC_FIXES_H__
+#define NFC_FIXES_H__
+
+#include <stdint.h>
+#include <stdbool.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** @file
+ * @defgroup nfc_fixes NFC fixes and workarounds
+ * @{
+ * @ingroup nfc_t4t
+ * @brief @tagAPI52 Fixes for hardware-related anomalies.
+ *
+ * If you are using PCA10040 (part of nRF52 Development Kit),
+ * you must define the macro HAL_NFC_ENGINEERING_BC_FTPAN_WORKAROUND in order to apply
+ * workarounds for the following anomalies:
+ * - 79. NFCT: A false EVENTS_FIELDDETECTED event occurs after the field is lost.
+ * - 116. NFCT does not release HFCLK when switching from ACTIVATED to SENSE mode.
+ *
+ * If you are using PCA10056 Engineering A (part of nRF52840 Development Kit),
+ * you must define the macro HAL_NFC_NRF52840_ENGINEERING_ABC_WORKAROUND in order to apply
+ * workarounds for the following anomalies:
+ * - 98. NFCT: The NFCT is not able to communicate with the peer.
+ * - 116. NFCT does not release HFCLK when switching from ACTIVATED to SENSE mode.
+ * - 144. NFCT: Not optimal NFC performance
+ *
+ * If you are using PCA10056 Engineering B or C (part of nRF52840 Development Kit),
+ * you must define the macro HAL_NFC_NRF52840_ENGINEERING_ABC_WORKAROUND in order to apply
+ * workarounds for the following anomalies:
+ * - 190. NFCT: Event FIELDDETECTED may be generated too early.
+ *
+ * The use of implemented workarounds for PCA10056 are determined at the runtime and depends
+ * on the chip variant.
+ *
+ * The current code contains a patch for anomaly 25 (NFCT: Reset value of
+ * SENSRES register is incorrect), so that it now works on Windows Phone.
+ */
+
+#ifdef BOARD_PCA10040 // assume nRF52832 chip in IC rev. Engineering B or Engineering C
+ #define HAL_NFC_ENGINEERING_BC_FTPAN_WORKAROUND
+#elif defined(BOARD_PCA10056) // assume nRF52840 chip in IC rev. Engineering A, B or C
+ #define HAL_NFC_NRF52840_ENGINEERING_ABC_WORKAROUND
+#endif
+
+/**
+ * @brief Internal auxiliary function to check if the program is running on NRF52840 chip
+ * @retval true It is NRF52480 chip
+ * @retval false It is other chip
+ */
+static inline bool type_52840_check(void)
+{
+ return ((((*(uint32_t *)0xF0000FE0) & 0xFF) == 0x08) &&
+ (((*(uint32_t *)0xF0000FE4) & 0x0F) == 0x0));
+}
+
+/**
+ * @brief Internal auxiliary function to check if the program is running on first sample of
+ * NRF52840 chip
+ * @retval true It is NRF52480 chip and it is first sample version
+ * @retval false It is other chip
+ */
+static inline bool type_52840_sample_check(void)
+{
+ return ( type_52840_check() &&
+ ( ((*(uint32_t *)0xF0000FE8) & 0xF0) == 0x00 ) &&
+ ( ((*(uint32_t *)0xF0000FEC) & 0xF0) == 0x00 ) );
+}
+
+/**
+ * @brief Internal auxiliary function to check if the program is running on final version of
+ * NRF52840 chip
+ * @retval true It is NRF52480 chip and it is final version
+ * @retval false It is other chip
+ */
+static inline bool type_52840_final_check(void)
+{
+ return ( type_52840_check() &&
+ ( ( ((*(uint32_t *)0xF0000FE8) & 0xF0) != 0x00 ) ||
+ ( ((*(uint32_t *)0xF0000FEC) & 0xF0) != 0x00 ) ));
+}
+
+/** @} */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* NFC_FIXES_H__ */
+
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/t4t_lib/nfc_t4t_lib.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/t4t_lib/nfc_t4t_lib.h
new file mode 100644
index 0000000..1ca3ca1
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/t4t_lib/nfc_t4t_lib.h
@@ -0,0 +1,323 @@
+/**
+ * Copyright (c) 2016 - 2018, Telit Communications Cyprus Ltd
+ *
+ * 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+
+#ifndef NFC_T4T_LIB_H__
+#define NFC_T4T_LIB_H__
+
+/** @file
+ *
+ * @addtogroup nfc_api
+ *
+ * @defgroup nfc_t4t NFC Type 4 Tag
+ * @ingroup nfc_api
+ * @brief Implementation of NFC Type 4 Tag.
+ *
+ * @defgroup nfc_t4t_lib NFC tag 4 type emulation library
+ * @{
+ * @ingroup nfc_t4t
+ * @brief The T4T emulation library interface
+ *
+ * This is the NFC Forum NDEF tag 4 type emulation library. It implements the ISO14443-4A protocol
+ * (ISO-DEP) and additionally can emulate a read-writable NDEF content. If the emulation of the NDEF
+ * content is not needed, the library works in a raw mode where all APDUs are delivered to the user,
+ * who is then responsible to generate a timely RPDU as a response.
+ *
+ * The sequence of initializing functions determines whether the NDEF emulation will run or whether
+ * the raw mode is used.
+ *
+ * - E.g. NDEF emulation
+ * * @ref nfc_t4t_setup
+ * * @ref nfc_t4t_ndef_rwpayload_set or @ref nfc_t4t_ndef_staticpayload_set
+ * * @ref nfc_t4t_emulation_start
+ * * ... running in NDEF emulation mode ...
+ * - E.g. RAW mode
+ * * @ref nfc_t4t_setup
+ * * @ref nfc_t4t_emulation_start
+ * * ... running in RAW emulation mode ...
+ */
+
+#include <stdint.h>
+#include <stdbool.h>
+#include <string.h>
+#include "sdk_errors.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define NFC_T4T_MAX_PAYLOAD_SIZE 0xFFF0U
+
+/**< @brief Emulation mode. */
+typedef enum
+{
+ NFC_T4T_EMUMODE_NDEF, ///< Emulated NDEF AID and EF-Files.
+ NFC_T4T_EMUMODE_PICC ///< Run just ISO-DEP, deliver I-Frames up.
+} nfc_t4t_emu_mode_t;
+
+
+/**< @brief Event identifiers used by the @ref nfc_t4t_callback_t */
+typedef enum
+{
+ NFC_T4T_EVENT_NONE,
+ ///< This ID is never used. Dummy value for completeness.
+
+ NFC_T4T_EVENT_FIELD_ON,
+ ///< External Reader polling detected.
+
+ NFC_T4T_EVENT_FIELD_OFF,
+ ///< External Reader polling ended.
+
+ NFC_T4T_EVENT_NDEF_READ,
+ ///< External Reader has read static NDEF-Data from Emulation.
+ /**<
+ * A Read operation happened on last byte of NDEF-Data.
+ */
+
+ NFC_T4T_EVENT_NDEF_UPDATED,
+ ///< External Reader has written to length information of NDEF-Data from Emulation.
+ /**<
+ * The usual behavior of a Reader-Writer that accesses NDEF information for update is to set
+ * the length to zero at the beginning of the update process. It then writes the content
+ * of NDEF-Data. When all content is written it will update the length information inside
+ * the NDEF file. This event will be generated every time an update to the length is happening.
+ * This length information is residing in the first 2 bytes of the NDEF-Content container and is called 'NLEN'.
+ * Since this callback is triggered on any access to these bytes the returned data_length
+ * information might not be consistent (e.g. in case of only a single byte write to the length).
+ *
+ * @param[out] data_length Current value of NDEF content length
+ * information i.e. 'NLEN' field.
+ */
+
+ NFC_T4T_EVENT_DATA_TRANSMITTED,
+ ///< In Raw mode it signals that the data from @ref nfc_t4t_response_pdu_send have been sent out.
+
+ NFC_T4T_EVENT_DATA_IND,
+ ///< In Raw mode delivers the APDU fragments
+ /**<
+ * All @ref NFC_T4T_EVENT_DATA_IND events that have the @ref NFC_T4T_DI_FLAG_MORE flag set
+ * belong to the same APDU. The first @ref NFC_T4T_EVENT_DATA_IND without @ref NFC_T4T_DI_FLAG_MORE
+ * flag signals the completeness of the APDU. The Application then has to reply with a call
+ * to @ref nfc_t4t_response_pdu_send. The library will handle internally the fragmentation of
+ * the response towards the Reader-Writer. The data of the response PDU must be kept
+ * valid until the next callback from the library happens (e.g. next @ref NFC_T4T_EVENT_DATA_IND
+ * or @ref NFC_T4T_EVENT_FIELD_OFF).
+ *
+ * @param[out] p_data Pointer to the fragment of APDU.
+ * @param[out] data_length Length of data.
+ * @param[out] flags @ref nfc_t4t_data_ind_flags_t.
+ */
+} nfc_t4t_event_t;
+
+/**< @brief Flags coming with nfc_t4t_callback_t at @ref NFC_T4T_EVENT_DATA_IND event.*/
+typedef enum
+{
+ NFC_T4T_DI_FLAG_NONE = 0x00, ///< Dummy value.
+ NFC_T4T_DI_FLAG_MORE = 0x01 ///< This signals that more data is expected to be received.
+} nfc_t4t_data_ind_flags_t;
+
+/**< @brief Parameter IDs that can be set/get with @ref nfc_t4t_parameter_set or
+ * @ref nfc_t4t_parameter_get.
+ */
+typedef enum
+{
+ NFC_T4T_PARAM_TESTING, ///< Internal usage only for Unit-Testing.
+ NFC_T4T_PARAM_FWI, ///< Frame Wait Time parameter
+ NFC_T4T_PARAM_SELRES, ///< Parameter for setting 'Protocol' bits for SEL_RES packet
+ NFC_T4T_PARAM_NFCID1, /**< NFCID1 value, data can be 4, 7, or 10 bytes long (single, double, or triple size).
+ To use default NFCID1 of specific length pass one byte containing requested length.
+ Default 7-byte NFCID1 will be used if this parameter was not set. This parameter can be
+ set before nfc_t2t_setup() to set initial NFCID1 and it can be changed later. */
+} nfc_t4t_param_id_t;
+
+/** @brief Callback to pass events from NFCLib to application.
+ *
+ * @param[out] p_context Application context for callback execution.
+ * @param[out] event The event that occurred. see @ref nfc_t4t_event_t.
+ * @param[out] p_data Data to send to the application (event specific).
+ * @param[out] data_length Length of the data. In case of @ref NFC_T4T_EVENT_NDEF_UPDATED, this parameter
+ * contains the value of the 'NLEN' field of the NDEF File;
+ * if the value is non-zero, it corresponds to the new size of the NDEF Message in the updated NDEF File.
+ * @param[out] flags Some events deliver flags. see @ref nfc_t4t_event_t for details.
+ */
+typedef void (*nfc_t4t_callback_t)(void * p_context,
+ nfc_t4t_event_t event,
+ const uint8_t * p_data,
+ size_t data_length,
+ uint32_t flags);
+
+/** @brief Register the application callback for event signaling.
+ *
+ * The callback will be called by NFCLib to notify the application of relevant events. It will be
+ * called from the HAL_NFC callback context. The library support 3 different Modes of Emulation:
+ * - Raw ISO-Dep exchanges. All PDUs are signaled through the callback.
+ * - Read-Only T4T NDEF-Tag. A static buffer is served. Only Field-Status callbacks.
+ * - Read-Write T4T NDEF-Tag. A mutable buffer is used. Only Field-Status callbacks.
+ *
+ * The default mode is Raw ISO-Dep mode. The two other NDEF T4T modes are activated through
+ * the corresponding @ref nfc_t4t_ndef_rwpayload_set/ @ref nfc_t4t_ndef_staticpayload_set functions.
+ * The mode is locked in with a call to @ref nfc_t4t_emulation_start.
+ *
+ * @param[in] callback Function pointer to the callback.
+ * @param[in] p_context Pointer to a memory area used by the callback for execution (optional).
+ *
+ * @retval NRF_SUCCESS Success.
+ * @retval NRF_ERROR_INVALID_STATE If emulation is in running state.
+ */
+ret_code_t nfc_t4t_setup(nfc_t4t_callback_t callback, void * p_context);
+
+/** @brief Set emulation buffer and content for a NDEF Tag emulation that is Read/Writable.
+ *
+ * The buffer needs to be kept accessible for the lifetime of the emulation.
+ * If an external Reader-Writer changes the NDEF content it is signaled through the app-callback.
+ *
+ * @param[in] p_emulation_buffer Buffer pointer
+ * @param[in] buffer_length Length of buffer (maximum writable NDEF size)
+ *
+ * @retval NRF_SUCCESS Success.
+ * @retval NRF_ERROR_DATA_SIZE Invalid argument (e.g. wrong data length).
+ * @retval NRF_ERROR_INVALID_PARAM Invalid argument (e.g. NULL pointer).
+ * @retval NRF_ERROR_INVALID_STATE If emulation is in running state.
+ */
+ret_code_t nfc_t4t_ndef_rwpayload_set(uint8_t * p_emulation_buffer, size_t buffer_length);
+
+/** @brief Set emulationBuffer and Content for a NDEF Tag emulation that is Read-Only.
+ *
+ * The buffer needs to be kept accessible for the lifetime of the emulation.
+ * Since no write access is done to the buffer, the content could reside in flash memory.
+ *
+ * @param[in] p_emulation_buffer Const buffer pointer
+ * @param[in] buffer_length Length of contained NDEF payload message
+ *
+ * @retval NRF_SUCCESS Success.
+ * @retval NRF_ERROR_DATA_SIZE Invalid argument (e.g. wrong data length).
+ * @retval NRF_ERROR_INVALID_PARAM Invalid argument (e.g. NULL pointer).
+ * @retval NRF_ERROR_INVALID_STATE Emulation is in running stated.
+ */
+ret_code_t nfc_t4t_ndef_staticpayload_set(const uint8_t * p_emulation_buffer, size_t buffer_length);
+
+/** @brief Send a raw response PDU after getting a Request PDU callback.
+ *
+ * When the library works in raw ISO-DEP mode it will signal request PDUs through the callback.
+ * The application then has to answer with a response PDU. It will use this function to send back
+ * the response PDU. This function can not be used in T4T NDEF (RW / STATIC) emulation modes.
+ *
+ * The lower ISODEP layer will handle the defragmentation of a long response PDU into smaller
+ * pieces that the PCD can understand.
+ *
+ * @param[in] p_pdu Const PDU pointer.
+ * @param[in] pdu_length Length of PDU.
+ *
+ * @retval NRF_SUCCESS Success.
+ * @retval NRF_ERROR_DATA_SIZE Invalid argument (e.g. wrong data length).
+ * @retval NRF_ERROR_INVALID_PARAM Invalid argument (e.g. NULL pointer).
+ * @retval NRF_ERROR_INVALID_STATE Emulation is in running state.
+ */
+ret_code_t nfc_t4t_response_pdu_send(const uint8_t * p_pdu, size_t pdu_length);
+
+/** @brief Set an NFC parameter.
+ *
+ * Allows to set any parameter defined as available by HAL_NFC.
+ *
+ * @param[in] id ID of the parameter to set.
+ * @param[in] p_data Pointer to a buffer containing the data to set.
+ * @param[in] data_length Size of the buffer containing the data to set.
+ *
+ * @retval NRF_SUCCESS Success.
+ * @retval NRF_ERROR_DATA_SIZE Invalid argument (e.g. wrong data length).
+ * @retval NRF_ERROR_INVALID_PARAM Invalid argument (e.g. NULL pointer).
+ */
+ret_code_t nfc_t4t_parameter_set(nfc_t4t_param_id_t id, void * p_data, size_t data_length);
+
+/** @brief Query an NFC parameter value.
+ *
+ * The queried value will be placed into the passed data buffer.
+ * If the buffer is too small, p_max_data_length will contain the required buffer size.
+ * If the buffer is big enough, p_max_data_length will contain the actual size of the data.
+ *
+ * @param[in] id ID of the parameter to query.
+ * @param[out] p_data Pointer to a buffer receiving the queried data.
+ * @param[out] p_max_data_length Size of the buffer, receives actual size of queried data.
+ *
+ * @retval NRF_SUCCESS Success.
+ * @retval NRF_ERROR_DATA_SIZE Invalid argument (e.g. wrong data length).
+ * @retval NRF_ERROR_INVALID_PARAM Invalid argument (e.g. NULL pointer).
+ */
+ret_code_t nfc_t4t_parameter_get(nfc_t4t_param_id_t id, void * p_data, size_t * p_max_data_length);
+
+/** @brief Activate the NFC frontend.
+ *
+ * Only after calling this function, events will be posted to the application callback.
+ *
+ * @retval NRF_SUCCESS Success.
+ * @retval NRF_ERROR_INVALID_STATE Already started.
+ */
+ret_code_t nfc_t4t_emulation_start(void);
+
+/**
+ * @brief Deactivate the NFC frontend.
+ *
+ * After calling this function, no more events will be posted to the application callback.
+ *
+ * @retval NRF_SUCCESS Success.
+ * @retval NRF_ERROR_INVALID_STATE Emulation was already stopped
+ */
+ret_code_t nfc_t4t_emulation_stop(void);
+
+/**
+ * @brief Release reference to application callback.
+ *
+ * After calling this function, the passed callback pointer is no longer considered valid.
+ * After calling this function, the passed p_ndef pointer is no longer considered valid.
+ *
+ * You need to restart with @ref nfc_t4t_setup to run a new Emulation.
+ *
+ * @retval NRF_SUCCESS Always succeeds.
+ */
+ret_code_t nfc_t4t_done(void);
+
+#ifdef __cplusplus
+}
+#endif
+
+/**
+ @}
+*/
+
+#endif // NFC_T4T_LIB_H__
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/t4t_lib/nfc_t4t_lib_gcc.a b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/t4t_lib/nfc_t4t_lib_gcc.a
new file mode 100644
index 0000000..606ca46
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/t4t_lib/nfc_t4t_lib_gcc.a
Binary files differ
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/t4t_lib/nfc_t4t_lib_gcc_no_fpu.a b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/t4t_lib/nfc_t4t_lib_gcc_no_fpu.a
new file mode 100644
index 0000000..68ec393
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/t4t_lib/nfc_t4t_lib_gcc_no_fpu.a
Binary files differ
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/t4t_lib/nfc_t4t_lib_iar.a b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/t4t_lib/nfc_t4t_lib_iar.a
new file mode 100644
index 0000000..cfc9aaf
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/t4t_lib/nfc_t4t_lib_iar.a
Binary files differ
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/t4t_lib/nfc_t4t_lib_keil.lib b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/t4t_lib/nfc_t4t_lib_keil.lib
new file mode 100644
index 0000000..e97272b
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/t4t_lib/nfc_t4t_lib_keil.lib
Binary files differ
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/t4t_parser/apdu/nfc_t4t_apdu.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/t4t_parser/apdu/nfc_t4t_apdu.c
new file mode 100644
index 0000000..71e5155
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/t4t_parser/apdu/nfc_t4t_apdu.c
@@ -0,0 +1,261 @@
+/**
+ * Copyright (c) 2016 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#include "sdk_config.h"
+#if NFC_T4T_APDU_ENABLED
+
+#include "nfc_t4t_apdu.h"
+#include "sdk_macros.h"
+#include "nordic_common.h"
+#include "app_util.h"
+
+#define NRF_LOG_MODULE_NAME nfc_t4t_apdu
+#if NFC_T4T_APDU_LOG_ENABLED
+#define NRF_LOG_LEVEL NFC_T4T_APDU_LOG_LEVEL
+#define NRF_LOG_INFO_COLOR NFC_T4T_APDU_LOG_COLOR
+#include "nrf_log.h"
+NRF_LOG_MODULE_REGISTER();
+#else // NFC_T4T_APDU_LOG_ENABLED
+#define NRF_LOG_LEVEL 0
+#include "nrf_log.h"
+#endif // NFC_T4T_APDU_LOG_ENABLED
+
+/**
+ * @brief Field sizes that can be present in CAPDU.
+ */
+#define CLASS_TYPE_SIZE 1U
+#define INSTRUCTION_TYPE_SIZE 1U
+#define PARAMETER_SIZE 2U
+#define LC_SHORT_FORMAT_SIZE 1U
+#define LC_LONG_FORMAT_SIZE 3U
+#define LE_SHORT_FORMAT_SIZE 1U
+#define LE_LONG_FORMAT_SIZE 2U
+
+/**
+ * @brief Values used to encode Lc field in CAPDU.
+ */
+#define LC_LONG_FORMAT_TOKEN 0x00
+#define LC_LONG_FORMAT_THR 0xFF
+
+/**
+ * @brief Values used to encode Le field in CAPDU.
+ */
+#define LE_FIELD_ABSENT 0U
+#define LE_LONG_FORMAT_THR 0x0100
+#define LE_ENCODED_VAL_256 0x00
+
+
+#define STATUS_SIZE 2U ///< Size of Status field contained in RAPDU.
+
+/**
+ * @brief Function for calculating size of CAPDU.
+ */
+__STATIC_INLINE uint16_t nfc_t4t_comm_apdu_size_calc(nfc_t4t_comm_apdu_t const * const p_cmd_apdu)
+{
+ uint16_t res = CLASS_TYPE_SIZE + INSTRUCTION_TYPE_SIZE + PARAMETER_SIZE;
+ if (p_cmd_apdu->data.p_buff != NULL)
+ {
+ if (p_cmd_apdu->data.len > LC_LONG_FORMAT_THR)
+ {
+ res += LC_LONG_FORMAT_SIZE;
+ }
+ else
+ {
+ res += LC_SHORT_FORMAT_SIZE;
+ }
+ }
+ res += p_cmd_apdu->data.len;
+ if (p_cmd_apdu->resp_len != LE_FIELD_ABSENT)
+ {
+ if (p_cmd_apdu->resp_len > LE_LONG_FORMAT_THR)
+ {
+ res += LE_LONG_FORMAT_SIZE;
+ }
+ else
+ {
+ res += LE_SHORT_FORMAT_SIZE;
+ }
+ }
+ return res;
+}
+
+
+/**
+ * @brief Function for validating arguments used by CAPDU encoding procedure.
+ */
+__STATIC_INLINE ret_code_t nfc_t4t_comm_apdu_args_validate(nfc_t4t_comm_apdu_t const * const p_cmd_apdu,
+ uint8_t * p_raw_data,
+ uint16_t * const p_len)
+{
+ if ((p_cmd_apdu == NULL) || (p_raw_data == NULL) || (p_len == NULL))
+ {
+ return NRF_ERROR_NULL;
+ }
+
+ if ((p_cmd_apdu->data.p_buff != NULL) && (p_cmd_apdu->data.len == 0))
+ {
+ return NRF_ERROR_INVALID_PARAM;
+ }
+
+ return NRF_SUCCESS;
+}
+
+
+ret_code_t nfc_t4t_comm_apdu_encode(nfc_t4t_comm_apdu_t const * const p_cmd_apdu,
+ uint8_t * p_raw_data,
+ uint16_t * const p_len)
+{
+ // Validate passed arguments.
+ ret_code_t err_code = nfc_t4t_comm_apdu_args_validate(p_cmd_apdu, p_raw_data, p_len);
+ VERIFY_SUCCESS(err_code);
+
+ // Check if there is enough memory in the provided buffer to store described CAPDU.
+ uint16_t comm_apdu_len = nfc_t4t_comm_apdu_size_calc(p_cmd_apdu);
+ if (comm_apdu_len > *p_len)
+ {
+ return NRF_ERROR_NO_MEM;
+ }
+ *p_len = comm_apdu_len;
+
+ // Start to encode described CAPDU in the buffer.
+ *p_raw_data++ = p_cmd_apdu->class_byte;
+ *p_raw_data++ = p_cmd_apdu->instruction;
+ *p_raw_data++ = MSB_16(p_cmd_apdu->parameter);
+ *p_raw_data++ = LSB_16(p_cmd_apdu->parameter);
+
+ // Check if optional data field should be included.
+ if (p_cmd_apdu->data.p_buff != NULL)
+ {
+ if (p_cmd_apdu->data.len > LC_LONG_FORMAT_THR) // Use long data length encoding.
+ {
+ *p_raw_data++ = LC_LONG_FORMAT_TOKEN;
+ *p_raw_data++ = MSB_16(p_cmd_apdu->data.len);
+ *p_raw_data++ = LSB_16(p_cmd_apdu->data.len);
+ }
+ else // Use short data length encoding.
+ {
+ *p_raw_data++ = LSB_16(p_cmd_apdu->data.len);
+ }
+ memcpy(p_raw_data, p_cmd_apdu->data.p_buff, p_cmd_apdu->data.len);
+ p_raw_data += p_cmd_apdu->data.len;
+ }
+
+ // Check if optional response length field present (Le) should be included.
+ if (p_cmd_apdu->resp_len != LE_FIELD_ABSENT)
+ {
+ if (p_cmd_apdu->resp_len > LE_LONG_FORMAT_THR) // Use long response length encoding.
+ {
+ *p_raw_data++ = MSB_16(p_cmd_apdu->resp_len);
+ *p_raw_data++ = LSB_16(p_cmd_apdu->resp_len);
+ }
+ else // Use short response length encoding.
+ {
+ if (p_cmd_apdu->resp_len == LE_LONG_FORMAT_THR)
+ {
+ *p_raw_data++ = LE_ENCODED_VAL_256;
+ }
+ else
+ {
+ *p_raw_data++ = LSB_16(p_cmd_apdu->resp_len);
+ }
+ }
+ }
+
+ return NRF_SUCCESS;
+}
+
+
+/**
+ * @brief Function for validating arguments used by RAPDU decoding procedure.
+ */
+__STATIC_INLINE ret_code_t nfc_t4t_resp_apdu_args_validate(nfc_t4t_resp_apdu_t const * const p_resp_apdu,
+ uint8_t const * const p_raw_data,
+ uint16_t len)
+{
+ if ((p_resp_apdu == NULL) || (p_raw_data == NULL))
+ {
+ return NRF_ERROR_NULL;
+ }
+
+ if (len < STATUS_SIZE)
+ {
+ return NRF_ERROR_INVALID_LENGTH;
+ }
+
+ return NRF_SUCCESS;
+}
+
+
+ret_code_t nfc_t4t_resp_apdu_decode(nfc_t4t_resp_apdu_t * const p_resp_apdu,
+ uint8_t const * const p_raw_data,
+ uint16_t len)
+{
+ // Validate passed arguments.
+ ret_code_t err_code = nfc_t4t_resp_apdu_args_validate(p_resp_apdu, p_raw_data, len);
+ VERIFY_SUCCESS(err_code);
+
+ nfc_t4t_resp_apdu_clear(p_resp_apdu);
+ if (len != STATUS_SIZE) // Optional data field is present in RAPDU.
+ {
+ p_resp_apdu->data.len = len - STATUS_SIZE;
+ p_resp_apdu->data.p_buff = (uint8_t *) p_raw_data;
+ }
+ p_resp_apdu->status = uint16_big_decode(p_raw_data + p_resp_apdu->data.len);
+
+ return NRF_SUCCESS;
+}
+
+
+void nfc_t4t_resp_apdu_printout(nfc_t4t_resp_apdu_t * p_resp_apdu)
+{
+ NRF_LOG_INFO("R-APDU status: %4X ", p_resp_apdu->status);
+ if (p_resp_apdu->data.p_buff != NULL)
+ {
+ NRF_LOG_INFO("R-APDU data: ");
+ NRF_LOG_HEXDUMP_INFO(p_resp_apdu->data.p_buff, p_resp_apdu->data.len);
+ }
+ else
+ {
+ NRF_LOG_INFO("R-APDU no data field present.");
+ }
+}
+
+
+#endif // NFC_T4T_APDU_ENABLED
+
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/t4t_parser/apdu/nfc_t4t_apdu.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/t4t_parser/apdu/nfc_t4t_apdu.h
new file mode 100644
index 0000000..0aa2f3d
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/t4t_parser/apdu/nfc_t4t_apdu.h
@@ -0,0 +1,221 @@
+/**
+ * Copyright (c) 2016 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#ifndef NFC_T4T_APDU_H__
+#define NFC_T4T_APDU_H__
+
+/**@file
+ *
+ * @defgroup nfc_t4t_apdu APDU reader/writer
+ * @{
+ * @ingroup nfc_t4t_parser
+ *
+ * @brief APDU reader/writer for Type 4 Tag communication.
+ *
+ */
+
+#include <stdint.h>
+#include <string.h>
+#include "sdk_errors.h"
+#include "nrf.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define CLASS_BYTE_NO_SECURE_MSG 0x00 ///< Class byte indicating no secure messaging, used in C-APDU.
+
+/**
+ * @name Parameters used when selecting instruction code in C-APDU.
+ * @{
+ */
+#define SELECT_BY_FILE_ID 0x000C ///< Select by file identifier, first or only occurence.
+#define SELECT_BY_NAME 0x0400 ///< Select by name, first or only occurence.
+/** @} */
+
+/**
+ * @name Status codes contained in R-APDU.
+ * @{
+ */
+#define RAPDU_STATUS_CMD_COMPLETED 0x9000 ///< Command completed successfully.
+#define RAPDU_STATUS_SEL_ITEM_NOT_FOUND 0x6A82 ///< Selected item has not been found.
+/** @} */
+
+/**
+ * @brief Possible instruction codes in C-APDU.
+ */
+typedef enum
+{
+ NFC_T4T_CAPDU_SELECT_INS = 0xA4, ///< Code used for selecting EF or NDEF application.
+ NFC_T4T_CAPDU_READ_INS = 0xB0, ///< Code used for selecting EF or NDEF application.
+ NFC_T4T_CAPDU_UPDATE_INS = 0xD6 ///< Code used for selecting EF or NDEF application.
+} nfc_t4t_comm_apdu_ins_type_t;
+
+/**
+ * @brief APDU data field descriptor.
+ */
+typedef struct
+{
+ uint16_t len; ///< Data field length.
+ uint8_t * p_buff; ///< Pointer to data field.
+} nfc_t4t_apdu_data_t;
+
+/**
+ * @brief Command Application Protocol Data Unit (C-APDU) descriptor.
+ */
+typedef struct
+{
+ uint8_t class_byte; ///< Class byte.
+ nfc_t4t_comm_apdu_ins_type_t instruction; ///< The chosen code of instruction.
+ uint16_t parameter; ///< Parameters associated with the instruction code.
+ nfc_t4t_apdu_data_t data; ///< Optional data fields (Lc + data bytes).
+ uint16_t resp_len; ///< Optional response length field (Le).
+} nfc_t4t_comm_apdu_t;
+
+/**
+ * @brief Response Application Protocol Data Unit (R-APDU) descriptor.
+ */
+typedef struct
+{
+ uint16_t status; ///< Mandatory status field.
+ nfc_t4t_apdu_data_t data; ///< Optional data field.
+} nfc_t4t_resp_apdu_t;
+
+/**
+ * @brief Macro for verifying R-APDU descriptor status.
+ *
+ * This macro verifies R-APDU descriptor status. It will cause the exterior
+ * function to return nrf_error translated from R-APDU status, if the status is
+ * not equal to @ref RAPDU_STATUS_CMD_COMPLETED.
+ *
+ * @param[in] P_RAPDU Pointer to R-APDU descriptor.
+ *
+ * @retval NRF_ERROR_NOT_FOUND If C-APDU select command could not find the selected item.
+ * @retval NRF_ERROR_INTERNAL Unknown R-APDU error.
+ */
+#define VERIFY_RAPDU_SUCCESS(P_RAPDU) \
+ if (P_RAPDU->status == RAPDU_STATUS_SEL_ITEM_NOT_FOUND) \
+ { \
+ return NRF_ERROR_NOT_FOUND; \
+ } \
+ if (P_RAPDU->status != RAPDU_STATUS_CMD_COMPLETED) \
+ { \
+ return NRF_ERROR_INTERNAL; \
+ }
+
+/**
+ * @brief Function for clearing C-APDU descriptor and restoring its default values.
+ *
+ * @param[in] p_cmd_apdu Pointer to C-APDU descriptor.
+ */
+__STATIC_INLINE void nfc_t4t_comm_apdu_clear(nfc_t4t_comm_apdu_t * const p_cmd_apdu);
+
+/**
+ * @brief Function for clearing R-APDU descriptor and restoring its default values.
+ *
+ * @param[in] p_resp_apdu Pointer to R-APDU descriptor.
+ */
+__STATIC_INLINE void nfc_t4t_resp_apdu_clear(nfc_t4t_resp_apdu_t * const p_resp_apdu);
+
+/**
+ * @brief Function for encoding C-APDU.
+ *
+ * This function encodes C-APDU according to the provided descriptor.
+ *
+ * @param[in] p_cmd_apdu Pointer to the C-APDU descriptor.
+ * @param[out] p_raw_data Pointer to the buffer with encoded C-APDU.
+ * @param[in,out] p_len Size of the available memory for the C-APDU as input.
+ * Size of the generated C-APDU as output.
+ *
+ * @retval NRF_SUCCESS If C-APDU was encoded successfully.
+ * @retval NRF_ERROR_NO_MEM If the predicted C-APDU size is bigger than the provided buffer space.
+ * @retval NRF_ERROR_INVALID_PARAM If C-APDU descriptor is invalid.
+ * @retval NRF_ERROR_NULL If any passed argument is NULL.
+ */
+ret_code_t nfc_t4t_comm_apdu_encode(nfc_t4t_comm_apdu_t const * const p_cmd_apdu,
+ uint8_t * p_raw_data,
+ uint16_t * const p_len);
+
+/**
+ * @brief Function for decoding R-APDU.
+ *
+ * This function decodes buffer with encoded R-APDU and stores results in the R-APDU descriptor.
+ *
+ * @param[out] p_resp_apdu Pointer to the R-APDU descriptor.
+ * @param[in] p_raw_data Pointer to the buffer with encoded R-APDU.
+ * @param[in] len Size of of the buffer with encoded R-APDU.
+ *
+ * @retval NRF_SUCCESS If R-APDU was encoded successfully.
+ * @retval NRF_ERROR_INVALID_LENGTH If the buffer is too small to hold a valid R-APDU.
+ * @retval NRF_ERROR_NULL If any passed argument is NULL.
+ */
+ret_code_t nfc_t4t_resp_apdu_decode(nfc_t4t_resp_apdu_t * const p_resp_apdu,
+ uint8_t const * const p_raw_data,
+ uint16_t len);
+
+/**
+ * @brief Function for printing a R-APDU descriptor.
+ *
+ * This function prints a R-APDU descriptor.
+ *
+ * @param[in] p_resp_apdu Pointer to the R-APDU descriptor.
+ */
+void nfc_t4t_resp_apdu_printout(nfc_t4t_resp_apdu_t * p_resp_apdu);
+
+#ifndef SUPPRESS_INLINE_IMPLEMENTATION
+
+__STATIC_INLINE void nfc_t4t_comm_apdu_clear(nfc_t4t_comm_apdu_t * const p_cmd_apdu)
+{
+ memset(p_cmd_apdu, 0, sizeof(nfc_t4t_comm_apdu_t));
+}
+
+__STATIC_INLINE void nfc_t4t_resp_apdu_clear(nfc_t4t_resp_apdu_t * const p_resp_apdu)
+{
+ memset(p_resp_apdu, 0, sizeof(nfc_t4t_resp_apdu_t));
+}
+
+#endif // SUPPRESS_INLINE_IMPLEMENTATION
+
+/** @} */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* NFC_T4T_APDU_H__ */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/t4t_parser/cc_file/nfc_t4t_cc_file.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/t4t_parser/cc_file/nfc_t4t_cc_file.c
new file mode 100644
index 0000000..197e0a0
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/t4t_parser/cc_file/nfc_t4t_cc_file.c
@@ -0,0 +1,266 @@
+/**
+ * Copyright (c) 2016 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#include "sdk_config.h"
+#if NFC_T4T_CC_FILE_PARSER_ENABLED
+
+#include <string.h>
+#include "nfc_t4t_cc_file.h"
+#include "sdk_macros.h"
+#include "nordic_common.h"
+#include "app_util.h"
+
+#define NRF_LOG_MODULE_NAME nfc_t4t_cc_file_parser
+#if NFC_T4T_CC_FILE_PARSER_LOG_ENABLED
+#define NRF_LOG_LEVEL NFC_T4T_CC_FILE_PARSER_LOG_LEVEL
+#define NRF_LOG_INFO_COLOR NFC_T4T_CC_FILE_PARSER_INFO_COLOR
+#include "nrf_log.h"
+NRF_LOG_MODULE_REGISTER();
+#else // NFC_T4T_CC_FILE_PARSER_LOG_ENABLED
+#define NRF_LOG_LEVEL 0
+#include "nrf_log.h"
+#endif // NFC_T4T_CC_FILE_PARSER_LOG_ENABLED
+
+/**
+ * @brief Valid value range for CCLEN field.
+ */
+#define CC_LEN_MIN_VALUE 0x000F
+#define CC_LEN_MAX_VALUE 0xFFFE
+
+/**
+ * @brief Valid major versions of Type 4 Tag specification.
+ */
+#define NFC_T4T_EXTENDED_MAJOR_VER 0x03 ///< Major version number allowing first TLV block to be Extended NDEF File Control TLV
+#define NFC_T4T_REGULAR_MAJOR_VER 0x02 ///< Major version number allowing first TLV block to be NDEF File Control TLV
+
+/**
+ * @brief Valid value range for MLe field.
+ */
+#define MLE_LEN_MIN_VALUE 0x000F
+#define MLE_LEN_MAX_VALUE 0xFFFF
+
+/**
+ * @brief Valid value range for MLc field.
+ */
+#define MLC_LEN_MIN_VALUE 0x0001
+#define MLC_LEN_MAX_VALUE 0xFFFF
+
+/**
+ * @brief Field sizes that are present in CC file.
+ */
+#define CC_LEN_FIELD_SIZE 2U
+#define MAP_VER_FIELD_SIZE 1U
+#define MLE_FIELD_SIZE 2U
+#define MLC_FIELD_SIZE 2U
+
+/// Gets least significant nibble (a 4-bit value) from a byte.
+#define LSN_GET(val) (val & 0x0F)
+
+/// Gets most significant nibble (a 4-bit value) from a byte.
+#define MSN_GET(val) ((val >> 4) & 0x0F)
+
+/**
+ * @brief Function for validating arguments used by CC file parsing procedure.
+ */
+__STATIC_INLINE ret_code_t nfc_t4t_cc_args_validate(nfc_t4t_capability_container_t * p_t4t_cc_file,
+ uint8_t * p_raw_data,
+ uint16_t len)
+{
+ if ( (p_t4t_cc_file == NULL)
+ || (p_t4t_cc_file->p_tlv_block_array == NULL)
+ || (p_raw_data == NULL) )
+ {
+ return NRF_ERROR_NULL;
+ }
+
+ if ( (len < CC_LEN_MIN_VALUE) || (len > CC_LEN_MAX_VALUE) )
+ {
+ return NRF_ERROR_INVALID_LENGTH;
+ }
+
+ if (p_t4t_cc_file->max_tlv_blocks == 0)
+ {
+ return NRF_ERROR_NO_MEM;
+ }
+
+ return NRF_SUCCESS;
+}
+
+
+/**
+ * @brief Function for validating CC file descriptor content.
+ */
+__STATIC_INLINE ret_code_t nfc_t4t_cc_file_validate(nfc_t4t_capability_container_t * p_t4t_cc_file)
+{
+ uint16_t type = p_t4t_cc_file->p_tlv_block_array[0].type;
+
+ if ( (p_t4t_cc_file->major_version == NFC_T4T_EXTENDED_MAJOR_VER
+ && type == EXTENDED_NDEF_FILE_CONTROL_TLV) ||
+ (p_t4t_cc_file->major_version == NFC_T4T_REGULAR_MAJOR_VER
+ && type == NDEF_FILE_CONTROL_TLV) )
+ {
+ return NRF_SUCCESS;
+ }
+
+ return NRF_ERROR_INVALID_DATA;
+}
+
+
+/**
+ * @brief Function for clearing all TLV blocks from CC file descriptor.
+ */
+__STATIC_INLINE void nfc_t4t_cc_file_clear(nfc_t4t_capability_container_t * p_t4t_cc_file)
+{
+ p_t4t_cc_file->tlv_count = 0;
+}
+
+
+/**
+ * @brief Function for adding a TLV block to the CC file descriptor.
+ */
+static ret_code_t nfc_t4t_tlv_block_insert(nfc_t4t_capability_container_t * p_t4t_cc_file,
+ nfc_t4t_tlv_block_t * p_tlv_block)
+{
+ if (p_t4t_cc_file->tlv_count == p_t4t_cc_file->max_tlv_blocks)
+ {
+ return NRF_ERROR_NO_MEM;
+ }
+
+ // Copy contents of the source block.
+ p_t4t_cc_file->p_tlv_block_array[p_t4t_cc_file->tlv_count] = *p_tlv_block;
+ p_t4t_cc_file->tlv_count++;
+
+ return NRF_SUCCESS;
+}
+
+
+ret_code_t nfc_t4t_cc_file_parse(nfc_t4t_capability_container_t * p_t4t_cc_file,
+ uint8_t * p_raw_data,
+ uint16_t len)
+{
+ ret_code_t err_code = nfc_t4t_cc_args_validate(p_t4t_cc_file, p_raw_data, len);
+ VERIFY_SUCCESS(err_code);
+
+ uint8_t * p_offset = p_raw_data;
+ nfc_t4t_cc_file_clear(p_t4t_cc_file);
+
+ p_t4t_cc_file->len = uint16_big_decode(p_offset);
+ p_offset += CC_LEN_FIELD_SIZE;
+
+ p_t4t_cc_file->major_version = MSN_GET(*p_offset);
+ p_t4t_cc_file->minor_version = LSN_GET(*p_offset);
+ p_offset += MAP_VER_FIELD_SIZE;
+
+ p_t4t_cc_file->max_rapdu_size = uint16_big_decode(p_offset);
+ p_offset += MLE_FIELD_SIZE;
+
+ p_t4t_cc_file->max_capdu_size = uint16_big_decode(p_offset);
+ p_offset += MLC_FIELD_SIZE;
+
+ nfc_t4t_tlv_block_t new_block;
+ len -= (p_offset - p_raw_data);
+ while (len > 0)
+ {
+ uint16_t tlv_len = len;
+ err_code = nfc_t4t_file_control_tlv_parse(&new_block, p_offset, &tlv_len);
+ VERIFY_SUCCESS(err_code);
+ p_offset += tlv_len;
+ len -= tlv_len;
+
+ err_code = nfc_t4t_tlv_block_insert(p_t4t_cc_file, &new_block);
+ VERIFY_SUCCESS(err_code);
+ }
+
+ return nfc_t4t_cc_file_validate(p_t4t_cc_file);
+}
+
+
+nfc_t4t_tlv_block_t * nfc_t4t_file_content_get(nfc_t4t_capability_container_t * p_t4t_cc_file,
+ uint16_t file_id)
+{
+ nfc_t4t_tlv_block_t * p_tlv_array = p_t4t_cc_file->p_tlv_block_array;
+ for (uint8_t i = 0; i < p_t4t_cc_file->tlv_count; i++)
+ {
+ nfc_t4t_file_control_val_t * p_tlv_value = &p_tlv_array[i].value;
+ if (p_tlv_value->file_id == file_id)
+ {
+ return (p_tlv_array + i);
+ }
+ }
+ return NULL;
+}
+
+
+ret_code_t nfc_t4t_file_content_set(nfc_t4t_capability_container_t * p_t4t_cc_file,
+ nfc_t4t_file_t file,
+ uint16_t file_id)
+{
+ nfc_t4t_tlv_block_t * p_tlv_block;
+
+ p_tlv_block = nfc_t4t_file_content_get(p_t4t_cc_file, file_id);
+ if (p_tlv_block != NULL)
+ {
+ p_tlv_block->value.file = file;
+ return NRF_SUCCESS;
+ }
+ return NRF_ERROR_NOT_FOUND;
+}
+
+
+void nfc_t4t_cc_file_printout(nfc_t4t_capability_container_t * p_t4t_cc_file)
+{
+ NRF_LOG_INFO("Capability Container File content: ")
+ NRF_LOG_INFO("CCLEN: %d ", p_t4t_cc_file->len);
+ NRF_LOG_INFO("Mapping Version: %d.%d ",
+ p_t4t_cc_file->major_version,
+ p_t4t_cc_file->minor_version);
+ NRF_LOG_INFO("MLe: %d ", p_t4t_cc_file->max_rapdu_size)
+ NRF_LOG_INFO("MLc: %d ", p_t4t_cc_file->max_capdu_size)
+
+ NRF_LOG_INFO("Capability Container File contains %d File Control TLV block(s).",
+ p_t4t_cc_file->tlv_count);
+ for (uint8_t i = 0; i < p_t4t_cc_file->tlv_count; i++)
+ {
+ nfc_t4t_file_control_tlv_printout(i, &p_t4t_cc_file->p_tlv_block_array[i]);
+ }
+}
+
+
+#endif // NFC_T4T_CC_FILE_PARSER_ENABLED
+
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/t4t_parser/cc_file/nfc_t4t_cc_file.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/t4t_parser/cc_file/nfc_t4t_cc_file.h
new file mode 100644
index 0000000..dc41c2c
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/t4t_parser/cc_file/nfc_t4t_cc_file.h
@@ -0,0 +1,177 @@
+/**
+ * Copyright (c) 2016 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#ifndef NFC_T4T_CC_FILE_H__
+#define NFC_T4T_CC_FILE_H__
+
+/**@file
+ *
+ * @defgroup nfc_t4t_cc_file CC file parser
+ * @{
+ * @ingroup nfc_t4t_parser
+ *
+ * @brief Capability Container file parser for Type 4 Tag.
+ *
+ */
+
+#include <stdint.h>
+#include "sdk_errors.h"
+#include "nfc_t4t_tlv_block.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @brief Descriptor for the Capability Container (CC) file of Type 4 Tag.
+ */
+typedef struct
+{
+ nfc_t4t_tlv_block_t * p_tlv_block_array; ///< Pointer to the array for TLV blocks.
+ uint16_t tlv_count; ///< Number of TLV blocks stored in the Type 4 Tag.
+ uint16_t const max_tlv_blocks; ///< Maximum number of TLV blocks.
+ uint16_t len; ///< Size (bytes) of a Capability Container including this field.
+ uint16_t max_rapdu_size; ///< MLe field - maximum R-APDU data size (bytes).
+ uint16_t max_capdu_size; ///< MLc field - maximum C-APDU data size (bytes).
+ uint8_t major_version; ///< Major version of the supported Type 4 Tag specification.
+ uint8_t minor_version; ///< Minor version of the supported Type 4 Tag specification.
+} nfc_t4t_capability_container_t;
+
+/**
+ * @brief Macro for creating and initializing a Type 4 Tag Capability Container descriptor.
+ *
+ * This macro creates and initializes a static instance of a @ref nfc_t4t_capability_container_t
+ * structure and an array of @ref nfc_t4t_tlv_block_t descriptors.
+ *
+ * Use the macro @ref NFC_T4T_CC_DESC to access the Type 4 Tag descriptor instance.
+ *
+ * @param[in] NAME Name of the created descriptor instance.
+ * @param[in] MAX_BLOCKS Maximum number of @ref nfc_t4t_tlv_block_t descriptors that can be
+ * stored in the array.
+ *
+ */
+#define NFC_T4T_CC_DESC_DEF(NAME, MAX_BLOCKS) \
+ static nfc_t4t_tlv_block_t NAME##_tlv_block_array[MAX_BLOCKS]; \
+ static nfc_t4t_capability_container_t NAME##_type_4_tag = \
+ { \
+ .max_tlv_blocks = MAX_BLOCKS, \
+ .p_tlv_block_array = NAME##_tlv_block_array, \
+ .tlv_count = 0 \
+ }
+
+/**
+ * @brief Macro for accessing the @ref nfc_t4t_capability_container_t instance that was created
+ * with @ref NFC_T4T_CC_DESC_DEF.
+ *
+ * @param[in] NAME Name of the created descriptor instance.
+ */
+#define NFC_T4T_CC_DESC(NAME) (NAME##_type_4_tag)
+
+/**
+ * @brief Function for parsing raw data of a CC file, read from a Type 4 Tag.
+ *
+ * This function parses raw data of a Capability Container file and stores the results in its
+ * descriptor.
+ *
+ * @param[in,out] p_t4t_cc_file Pointer to the CC file descriptor that will be filled with
+ * parsed data.
+ * @param[in] p_raw_data Pointer to the buffer with raw data.
+ * @param[in] len Buffer length.
+ *
+ * @retval NRF_SUCCESS If operation was successful.
+ * @retval NRF_ERROR_NULL If any of the provided pointer arguments is NULL.
+ * @retval NRF_ERROR_INVALID_LENGTH If provided buffer exceeds a valid CC file length range.
+ * @retval NRF_ERROR_INVALID_DATA If mapping version of Type 4 Tag specification is not a
+ * compatible CC file structure.
+ * @retval Other Other error codes might be returned depending on
+ * @ref nfc_t4t_file_control_tlv_parse function.
+ */
+ret_code_t nfc_t4t_cc_file_parse(nfc_t4t_capability_container_t * p_t4t_cc_file,
+ uint8_t * p_raw_data,
+ uint16_t len);
+
+/**
+ * @brief Function for finding File Control TLV block within the CC file descriptor.
+ *
+ * This function finds File Control TLV block that matches
+ * the specified file ID within the CC file descriptor.
+ *
+ * @param[in] p_t4t_cc_file Pointer to the CC file descriptor.
+ * @param[in] file_id File identifier.
+ *
+ * @retval TLV Pointer to the File Control TLV.
+ * @retval NULL If TLV with the specified File ID was not found.
+ */
+nfc_t4t_tlv_block_t * nfc_t4t_file_content_get(nfc_t4t_capability_container_t * p_t4t_cc_file,
+ uint16_t file_id);
+
+/**
+ * @brief Function for binding a file with its File Control TLV block.
+ *
+ * This function binds file content with its File Control TLV block, in which
+ * maximal file size and access conditions are stored.
+ *
+ * @param[in,out] p_t4t_cc_file Pointer to the CC file descriptor.
+ * @param[in] file File descriptor.
+ * @param[in] file_id File identifier.
+ *
+ * @retval NRF_SUCCESS If operation was successful.
+ * @retval NRF_ERROR_NOT_FOUND If the provided file ID does not match any ID stored in TLV blocks
+ * of the CC file.
+ */
+ret_code_t nfc_t4t_file_content_set(nfc_t4t_capability_container_t * p_t4t_cc_file,
+ nfc_t4t_file_t file,
+ uint16_t file_id);
+
+/**
+ * @brief Function for printing the CC file descriptor.
+ *
+ * This function prints the CC file descriptor.
+ *
+ * @param[in] p_t4t_cc_file Pointer to the CC file.
+ */
+void nfc_t4t_cc_file_printout(nfc_t4t_capability_container_t * p_t4t_cc_file);
+
+/** @} */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* NFC_T4T_CC_FILE_H__ */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/t4t_parser/hl_detection_procedure/nfc_t4t_hl_detection_procedures.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/t4t_parser/hl_detection_procedure/nfc_t4t_hl_detection_procedures.c
new file mode 100644
index 0000000..f27625f
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/t4t_parser/hl_detection_procedure/nfc_t4t_hl_detection_procedures.c
@@ -0,0 +1,401 @@
+/**
+ * Copyright (c) 2016 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#include "sdk_config.h"
+#if NFC_T4T_HL_DETECTION_PROCEDURES_ENABLED
+
+#include "nfc_t4t_hl_detection_procedures.h"
+#include "nfc_t4t_apdu.h"
+#include "adafruit_pn532.h"
+#include "sdk_macros.h"
+#include "nordic_common.h"
+
+#define NRF_LOG_MODULE_NAME nfc_t4t_hl_detection_procedures
+#if NFC_T4T_HL_DETECTION_PROCEDURES_LOG_ENABLED
+#define NRF_LOG_LEVEL NFC_T4T_HL_DETECTION_PROCEDURES_LOG_LEVEL
+#define NRF_LOG_INFO_COLOR NFC_T4T_HL_DETECTION_PROCEDURES_INFO_COLOR
+#include "nrf_log.h"
+NRF_LOG_MODULE_REGISTER();
+#else // NFC_T4T_HL_DETECTION_PROCEDURES_LOG_ENABLED
+#define NRF_LOG_LEVEL 0
+#include "nrf_log.h"
+#endif // NFC_T4T_HL_DETECTION_PROCEDURES_LOG_ENABLED
+
+#define CC_FILE_ID 0xE103 ///< File Identifier of Capability Container.
+#define FILE_ID_SIZE 2 ///< Size of File Identifier field in CC file.
+#define MIN_MAX_RAPDU_SIZE 0x0F ///< Minimal value of maximal RAPDU data field size.
+#define NDEF_FILE_NLEN_FIELD_SIZE 2 ///< Size of NLEN field in NDEF file.
+#define NDEF_APP_PROC_RESP_LEN 256 ///< Maximal size of RAPDU data in the NDEF Tag Application Select Procedure.
+
+// Adafruit library limitations.
+#define MAX_ADAFRUIT_RAPDU_SIZE 242 ///< Maximal value of RAPDU data field size
+#define MAX_ADAFRUIT_CAPDU_SIZE 240 ///< Maximal value of CAPDU data field size
+
+static uint8_t m_file_id[FILE_ID_SIZE]; ///< Buffer for selected EF ID storage.
+static const uint8_t m_nfc_t4t_select_ndef_app_data[] = {0xD2, 0x76, 0x00, 0x00, 0x85, 0x01, 0x01}; ///< NDEF Tag Application name.
+static const uint8_t m_nlen_update_value[] = {0x00, 0x00}; ///< NLEN value used in NDEF Update Procedure.
+
+/**
+ * @brief Function for performing APDU exchanges with Adafruit library.
+ */
+static ret_code_t nfc_t4t_apdu_exchange(nfc_t4t_comm_apdu_t * const p_capdu,
+ nfc_t4t_resp_apdu_t * const p_rapdu,
+ uint8_t * const p_apdu_buff,
+ uint8_t resp_len)
+{
+ if (resp_len > APDU_BUFF_SIZE)
+ {
+ return NRF_ERROR_NO_MEM;
+ }
+
+ uint16_t apdu_buff_len = APDU_BUFF_SIZE;
+ ret_code_t err_code = nfc_t4t_comm_apdu_encode(p_capdu,
+ p_apdu_buff,
+ &apdu_buff_len);
+ VERIFY_SUCCESS(err_code);
+
+ err_code = adafruit_pn532_in_data_exchange(p_apdu_buff, apdu_buff_len, p_apdu_buff, &resp_len);
+ VERIFY_SUCCESS(err_code);
+
+ err_code = nfc_t4t_resp_apdu_decode(p_rapdu, p_apdu_buff, resp_len);
+ VERIFY_SUCCESS(err_code);
+
+ nfc_t4t_resp_apdu_printout(p_rapdu);
+ VERIFY_RAPDU_SUCCESS(p_rapdu);
+
+ return err_code;
+}
+
+/**
+ * @brief Function for performing APDU exchanges with Adafruit library with default response length.
+ */
+static ret_code_t nfc_t4t_apdu_default_exchange(nfc_t4t_comm_apdu_t * const p_capdu,
+ nfc_t4t_resp_apdu_t * const p_rapdu,
+ uint8_t * const p_apdu_buff)
+{
+ if (p_capdu->resp_len + sizeof(p_rapdu->status) > UINT8_MAX)
+ {
+ return NRF_ERROR_NOT_SUPPORTED;
+ }
+
+ uint8_t resp_len = (uint8_t) (p_capdu->resp_len + sizeof(p_rapdu->status));
+ ret_code_t err_code = nfc_t4t_apdu_exchange(p_capdu, p_rapdu, p_apdu_buff, resp_len);
+
+ return err_code;
+}
+
+
+/**
+ * @brief Function for saving part of EF (contained in RAPDU) in storage buffer.
+ */
+static ret_code_t nfc_t4t_file_chunk_save(nfc_t4t_resp_apdu_t const * const p_rapdu,
+ uint8_t * const p_storage_buff,
+ uint16_t storage_buff_len,
+ uint16_t * const p_file_offset)
+{
+ if (p_rapdu->data.p_buff == NULL)
+ {
+ return NRF_ERROR_NULL;
+ }
+ if ((*p_file_offset) + p_rapdu->data.len > storage_buff_len)
+ {
+ return NRF_ERROR_NO_MEM;
+ }
+
+ memcpy(p_storage_buff + (*p_file_offset), p_rapdu->data.p_buff, p_rapdu->data.len);
+ *p_file_offset += p_rapdu->data.len;
+
+ return NRF_SUCCESS;
+}
+
+
+/**
+ * @brief Function for updating the remaining length of the read file.
+ */
+static ret_code_t nfc_t4t_file_len_update(nfc_t4t_resp_apdu_t const * const p_rapdu,
+ uint16_t * const p_len)
+{
+ if (*p_len < p_rapdu->data.len)
+ {
+ return NRF_ERROR_INVALID_DATA;
+ }
+ *p_len -= p_rapdu->data.len;
+
+ return NRF_SUCCESS;
+}
+
+
+ret_code_t nfc_t4t_ndef_tag_app_select(void)
+{
+ ret_code_t err_code;
+ nfc_t4t_comm_apdu_t capdu;
+ nfc_t4t_resp_apdu_t rapdu;
+ uint8_t apdu_buff[APDU_BUFF_SIZE];
+
+ NRF_LOG_INFO("NDEF Tag Application Select Procedure ");
+
+ nfc_t4t_comm_apdu_clear(&capdu);
+ capdu.instruction = NFC_T4T_CAPDU_SELECT_INS;
+ capdu.parameter = SELECT_BY_NAME;
+ capdu.data.p_buff = (uint8_t *) m_nfc_t4t_select_ndef_app_data;
+ capdu.data.len = sizeof(m_nfc_t4t_select_ndef_app_data);
+ capdu.resp_len = NDEF_APP_PROC_RESP_LEN;
+
+ err_code = nfc_t4t_apdu_exchange(&capdu, &rapdu, apdu_buff, sizeof(rapdu.status));
+ NRF_LOG_RAW_INFO("\r\n");
+ return err_code;
+}
+
+
+ret_code_t nfc_t4t_file_select(uint16_t file_id)
+{
+ ret_code_t err_code;
+ nfc_t4t_comm_apdu_t capdu;
+ nfc_t4t_resp_apdu_t rapdu;
+ uint8_t apdu_buff[APDU_BUFF_SIZE];
+
+ if (file_id != CC_FILE_ID)
+ {
+ NRF_LOG_INFO("File (ID = %4X) Select Procedure ", file_id);
+ }
+ UNUSED_RETURN_VALUE(uint16_big_encode(file_id, m_file_id));
+
+ nfc_t4t_comm_apdu_clear(&capdu);
+ capdu.instruction = NFC_T4T_CAPDU_SELECT_INS;
+ capdu.parameter = SELECT_BY_FILE_ID;
+ capdu.data.p_buff = m_file_id;
+ capdu.data.len = sizeof(m_file_id);
+
+ err_code = nfc_t4t_apdu_default_exchange(&capdu, &rapdu, apdu_buff);
+ NRF_LOG_RAW_INFO("\r\n");
+ return err_code;
+}
+
+
+ret_code_t nfc_t4t_cc_select(void)
+{
+ NRF_LOG_INFO("Capability Container Select Procedure ");
+
+ return nfc_t4t_file_select(CC_FILE_ID);
+}
+
+
+ret_code_t nfc_t4t_cc_read(nfc_t4t_capability_container_t * const p_cc_file)
+{
+ ret_code_t err_code;
+ nfc_t4t_comm_apdu_t capdu;
+ nfc_t4t_resp_apdu_t rapdu;
+ uint16_t clen;
+ uint16_t file_offset = 0;
+ uint8_t storage_buff[CC_STORAGE_BUFF_SIZE];
+ uint8_t apdu_buff[APDU_BUFF_SIZE];
+
+ NRF_LOG_INFO("Capability Container Read Procedure ");
+
+ nfc_t4t_comm_apdu_clear(&capdu);
+ capdu.instruction = NFC_T4T_CAPDU_READ_INS;
+ capdu.parameter = file_offset;
+ capdu.resp_len = MIN_MAX_RAPDU_SIZE;
+
+ err_code = nfc_t4t_apdu_default_exchange(&capdu, &rapdu, apdu_buff);
+ VERIFY_SUCCESS(err_code);
+
+ err_code = nfc_t4t_file_chunk_save(&rapdu, storage_buff, CC_STORAGE_BUFF_SIZE, &file_offset);
+ VERIFY_SUCCESS(err_code);
+
+ clen = uint16_big_decode(storage_buff);
+ err_code = nfc_t4t_file_len_update(&rapdu, &clen);
+ VERIFY_SUCCESS(err_code);
+
+ while (clen > 0)
+ {
+ capdu.parameter = file_offset;
+ capdu.resp_len = MIN(MIN_MAX_RAPDU_SIZE, MIN(clen, MAX_ADAFRUIT_RAPDU_SIZE));
+
+ err_code = nfc_t4t_apdu_default_exchange(&capdu, &rapdu, apdu_buff);
+ VERIFY_SUCCESS(err_code);
+
+ err_code = nfc_t4t_file_chunk_save(&rapdu, storage_buff, CC_STORAGE_BUFF_SIZE, &file_offset);
+ VERIFY_SUCCESS(err_code);
+
+ err_code = nfc_t4t_file_len_update(&rapdu, &clen);
+ VERIFY_SUCCESS(err_code);
+ }
+
+ err_code = nfc_t4t_cc_file_parse(p_cc_file, storage_buff, file_offset);
+
+ NRF_LOG_RAW_INFO("\r\n");
+ return err_code;
+}
+
+
+ret_code_t nfc_t4t_ndef_read(nfc_t4t_capability_container_t * const p_cc_file,
+ uint8_t * p_ndef_file_buff,
+ uint8_t ndef_file_buff_len)
+{
+ ret_code_t err_code;
+ nfc_t4t_comm_apdu_t capdu;
+ nfc_t4t_resp_apdu_t rapdu;
+ uint16_t len;
+ uint16_t file_offset = 0;
+ uint8_t apdu_buff[APDU_BUFF_SIZE];
+
+ NRF_LOG_INFO("NDEF Read Procedure ");
+
+ // Read the NLEN (NDEF length) field of NDEF file.
+ nfc_t4t_comm_apdu_clear(&capdu);
+ capdu.instruction = NFC_T4T_CAPDU_READ_INS;
+ capdu.parameter = file_offset;
+ capdu.resp_len = NDEF_FILE_NLEN_FIELD_SIZE;
+
+ err_code = nfc_t4t_apdu_default_exchange(&capdu, &rapdu, apdu_buff);
+ VERIFY_SUCCESS(err_code);
+
+ err_code = nfc_t4t_file_chunk_save(&rapdu, p_ndef_file_buff, ndef_file_buff_len, &file_offset);
+ VERIFY_SUCCESS(err_code);
+
+ len = uint16_big_decode(p_ndef_file_buff) + NDEF_FILE_NLEN_FIELD_SIZE;
+ err_code = nfc_t4t_file_len_update(&rapdu, &len);
+ VERIFY_SUCCESS(err_code);
+
+ // Read the NDEF message.
+ while (len > 0)
+ {
+ capdu.parameter = file_offset;
+ capdu.resp_len = MIN(len, MIN(p_cc_file->max_rapdu_size, MAX_ADAFRUIT_RAPDU_SIZE));
+
+ err_code = nfc_t4t_apdu_default_exchange(&capdu, &rapdu, apdu_buff);
+ VERIFY_SUCCESS(err_code);
+
+ err_code = nfc_t4t_file_chunk_save(&rapdu, p_ndef_file_buff, ndef_file_buff_len, &file_offset);
+ VERIFY_SUCCESS(err_code);
+
+ err_code = nfc_t4t_file_len_update(&rapdu, &len);
+ VERIFY_SUCCESS(err_code);
+ }
+
+ // Bind NDEF File Control TLV with NDEF file.
+ nfc_t4t_file_t file =
+ {
+ .p_content = p_ndef_file_buff,
+ .len = file_offset
+ };
+ uint16_t file_id = uint16_big_decode(m_file_id);
+ err_code = nfc_t4t_file_content_set(p_cc_file, file, file_id);
+
+ NRF_LOG_RAW_INFO("\r\n");
+ return err_code;
+}
+
+
+ret_code_t nfc_t4t_ndef_update(nfc_t4t_capability_container_t * const p_cc_file,
+ uint8_t * p_ndef_file_buff,
+ uint8_t ndef_file_buff_len)
+{
+ ret_code_t err_code;
+ nfc_t4t_comm_apdu_t capdu;
+ nfc_t4t_resp_apdu_t rapdu;
+ uint16_t len;
+ uint16_t file_offset = 0;
+ uint16_t file_id = uint16_big_decode(m_file_id);
+ uint8_t apdu_buff[APDU_BUFF_SIZE];
+ nfc_t4t_tlv_block_t * p_tlv_block;
+
+ NRF_LOG_INFO("NDEF Update Procedure ");
+
+ if (ndef_file_buff_len < NDEF_FILE_NLEN_FIELD_SIZE)
+ {
+ return NRF_ERROR_INVALID_DATA;
+ }
+
+ // Check if selected NDEF file is registered in CC file descriptor.
+ p_tlv_block = nfc_t4t_file_content_get(p_cc_file, file_id);
+ if (p_tlv_block == NULL)
+ {
+ return NRF_ERROR_NULL;
+ }
+
+ // Check NDEF file capacity before writing anything to it.
+ len = uint16_big_decode(p_ndef_file_buff);
+ if ((len + NDEF_FILE_NLEN_FIELD_SIZE != ndef_file_buff_len) ||
+ (ndef_file_buff_len > p_tlv_block->value.max_file_size))
+ {
+ return NRF_ERROR_INVALID_LENGTH;
+ }
+
+ // Write the value 0000h in the NLEN field.
+ nfc_t4t_comm_apdu_clear(&capdu);
+ capdu.instruction = NFC_T4T_CAPDU_UPDATE_INS;
+ capdu.parameter = file_offset;
+ capdu.data.p_buff = (uint8_t *) m_nlen_update_value;
+ capdu.data.len = NDEF_FILE_NLEN_FIELD_SIZE;
+
+ err_code = nfc_t4t_apdu_default_exchange(&capdu, &rapdu, apdu_buff);
+ VERIFY_SUCCESS(err_code);
+ file_offset += NDEF_FILE_NLEN_FIELD_SIZE;
+
+ // Write the NDEF message in the NDEF message field.
+ while (len > 0)
+ {
+ capdu.parameter = file_offset;
+ capdu.data.p_buff = p_ndef_file_buff + file_offset;
+ capdu.data.len = MIN(len, MIN(p_cc_file->max_capdu_size, MAX_ADAFRUIT_CAPDU_SIZE));
+
+ err_code = nfc_t4t_apdu_default_exchange(&capdu, &rapdu, apdu_buff);
+ VERIFY_SUCCESS(err_code);
+
+ file_offset += capdu.data.len;
+ len -= capdu.data.len;
+ }
+
+ // Write the length of the NDEF message in the NLEN field.
+ capdu.parameter = 0;
+ capdu.data.p_buff = p_ndef_file_buff;
+ capdu.data.len = NDEF_FILE_NLEN_FIELD_SIZE;
+
+ err_code = nfc_t4t_apdu_default_exchange(&capdu, &rapdu, apdu_buff);
+ VERIFY_SUCCESS(err_code);
+
+ NRF_LOG_RAW_INFO("\r\n");
+ return NRF_SUCCESS;
+}
+
+
+#endif // NFC_T4T_HL_DETECTION_PROCEDURES_ENABLED
+
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/t4t_parser/hl_detection_procedure/nfc_t4t_hl_detection_procedures.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/t4t_parser/hl_detection_procedure/nfc_t4t_hl_detection_procedures.h
new file mode 100644
index 0000000..7ebc56e
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/t4t_parser/hl_detection_procedure/nfc_t4t_hl_detection_procedures.h
@@ -0,0 +1,184 @@
+/**
+ * Copyright (c) 2016 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#ifndef NFC_T4T_HL_DETECTION_PROCEDURES_H__
+#define NFC_T4T_HL_DETECTION_PROCEDURES_H__
+
+/**@file
+ *
+ * @defgroup nfc_t4t_parser NFC Type 4 Tag parser
+ * @ingroup nfc_t4t
+ * @brief Parser for Type 4 Tag data.
+ *
+ * @defgroup nfc_t4t_hl_detection_procedures High-level NDEF Detection Procedure
+ * @{
+ * @ingroup nfc_t4t_parser
+ *
+ * @brief High-level NDEF Detection Procedure for Type 4 Tag communication.
+ *
+ */
+
+#include <stdint.h>
+#include "sdk_errors.h"
+#include "nfc_t4t_cc_file.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @brief Function for performing NDEF Tag Application Select Procedure.
+ *
+ * This function performs NDEF Tag Application Select Procedure according to "Type 4 Tag Operation"
+ * (Version 3.0 published on 2014-07-30) chapter 5.5.2.
+ *
+ * @retval NRF_SUCCESS If NDEF Tag Application was successfully selected.
+ * @retval NRF_ERROR_NOT_FOUND If NDEF Tag Application was not found.
+ * @retval NRF_ERROR_NO_MEM If the APDU buffer is too small.
+ * @retval Other Other error codes may be returned depending on function
+ * @ref adafruit_pn532_in_data_exchange and on @ref nfc_t4t_apdu
+ * module functions.
+ */
+ret_code_t nfc_t4t_ndef_tag_app_select(void);
+
+/**
+ * @brief Function for performing Capability Container Select Procedure.
+ *
+ * This function performs Capability Container Select Procedure according to "Type 4 Tag Operation"
+ * (Version 3.0 published on 2014-07-30) chapter 5.5.3.
+ *
+ * @retval NRF_SUCCESS If the Capability Container file was successfully selected.
+ * @retval NRF_ERROR_NOT_FOUND If the Capability Container file was not found.
+ * @retval NRF_ERROR_NO_MEM If the APDU buffer is too small.
+ * @retval Other Other error codes might be returned depending on function
+ * @ref adafruit_pn532_in_data_exchange and on @ref nfc_t4t_apdu
+ * module functions.
+ */
+ret_code_t nfc_t4t_cc_select(void);
+
+/**
+ * @brief Function for performing Capability Container Read Procedure.
+ *
+ * This function performs Capability Container Read Procedure according to "Type 4 Tag Operation"
+ * (Version 3.0 published on 2014-07-30) chapter 5.5.4.
+ *
+ * @param[out] p_cc_file Pointer to the Capability Container descriptor.
+ *
+ * @retval NRF_SUCCESS If Capability Container file was successfully read.
+ * @retval NRF_ERROR_NO_MEM If APDU buffer or CC file storage buffer is too small.
+ * @retval NRF_ERROR_NOT_SUPPORTED If the requested response length in C-APDU is too big.
+ * @retval NRF_ERROR_NULL If R-APDU did not return any data bytes.
+ * @retval NRF_ERROR_INVALID_DATA If CCLEN field is not coherent with R-APDU data length.
+ * @retval Other Other error codes may be returned depending on functions
+ * @ref adafruit_pn532_in_data_exchange, @ref nfc_t4t_cc_file_parse,
+ * and on @ref nfc_t4t_apdu module functions.
+ */
+ret_code_t nfc_t4t_cc_read(nfc_t4t_capability_container_t * const p_cc_file);
+
+/**
+ * @brief Function for performing NDEF Select Procedure.
+ *
+ * This function performs NDEF Select Procedure according to "Type 4 Tag Operation"
+ * (Version 3.0 published on 2014-07-30) chapter 5.5.5.
+ *
+ * @param[in] file_id File Identifier to choose the correct file.
+ *
+ * @retval NRF_SUCCESS If NDEF file was successfully selected.
+ * @retval NRF_ERROR_NOT_FOUND If NDEF file was not found.
+ * @retval NRF_ERROR_NO_MEM If APDU buffer is too small.
+ * @retval Other Other error codes may be returned depending on function
+ * @ref adafruit_pn532_in_data_exchange and on @ref nfc_t4t_apdu
+ * module functions.
+ */
+ret_code_t nfc_t4t_file_select(uint16_t file_id);
+
+/**
+ * @brief Function for performing NDEF Read Procedure.
+ *
+ * This function performs NDEF Read Procedure according to "Type 4 Tag Operation"
+ * (Version 3.0 published on 2014-07-30) chapter 5.5.6.
+ *
+ * @param[in,out] p_cc_file Pointer to the Capability Container descriptor.
+ * @param[out] p_ndef_file_buff Pointer to the buffer where the NDEF file will be stored.
+ * @param[in] ndef_file_buff_len Length of the provided NDEF file buffer.
+ *
+ * @retval NRF_SUCCESS If NDEF file was successfully read.
+ * @retval NRF_ERROR_NO_MEM If APDU buffer or NDEF file buffer is too small.
+ * @retval NRF_ERROR_NOT_SUPPORTED If requested response length in C-APDU is too big.
+ * @retval NRF_ERROR_NULL If R-APDU did not return any data bytes.
+ * @retval NRF_ERROR_INVALID_DATA If NLEN field is not coherent with R-APDU data length.
+ * @retval Other Other error codes may be returned depending on function
+ * @ref adafruit_pn532_in_data_exchange, @ref nfc_t4t_file_content_set,
+ * and on @ref nfc_t4t_apdu module functions.
+ */
+ret_code_t nfc_t4t_ndef_read(nfc_t4t_capability_container_t * const p_cc_file,
+ uint8_t * p_ndef_file_buff,
+ uint8_t ndef_file_buff_len);
+
+/**
+ * @brief Function for performing NDEF Update Procedure.
+ *
+ * This function performs NDEF Update Procedure according to "Type 4 Tag Operation"
+ * (Version 3.0 published on 2014-07-30) chapter 5.5.7.
+ *
+ * @param[in] p_cc_file Pointer to the Capability Container descriptor.
+ * @param[in] p_ndef_file_buff Pointer to the buffer with NDEF file.
+ * @param[in] ndef_file_buff_len Length of the provided NDEF file.
+ *
+ * @retval NRF_SUCCESS If NDEF file was successfully updated.
+ * @retval NRF_ERROR_NO_MEM If APDU buffer or NDEF file buffer is too small.
+ * @retval NRF_ERROR_NOT_SUPPORTED If the requested response length in C-APDU is too big.
+ * @retval NRF_ERROR_INVALID_DATA If NDEF file buffer is smaller than NLEN field size.
+ * @retval NRF_ERROR_INVALID_LENGTH If NLEN value is not coherent with NDEF file buffer length
+ * or if buffer length is bigger than maximal file size.
+ * @retval Other Other error codes may be returned depending on function
+ * @ref adafruit_pn532_in_data_exchange, @ref nfc_t4t_file_content_get,
+ * and on @ref nfc_t4t_apdu module functions.
+ */
+ret_code_t nfc_t4t_ndef_update(nfc_t4t_capability_container_t * const p_cc_file,
+ uint8_t * p_ndef_file_buff,
+ uint8_t ndef_file_buff_len);
+
+/** @} */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* NFC_T4T_HL_DETECTION_PROCEDURES_H__ */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/t4t_parser/tlv/nfc_t4t_tlv_block.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/t4t_parser/tlv/nfc_t4t_tlv_block.c
new file mode 100644
index 0000000..028018b
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/t4t_parser/tlv/nfc_t4t_tlv_block.c
@@ -0,0 +1,327 @@
+/**
+ * Copyright (c) 2016 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#include "sdk_config.h"
+#if NFC_T4T_TLV_BLOCK_PARSER_ENABLED
+
+#include <string.h>
+#include "nfc_t4t_tlv_block.h"
+#include "app_util.h"
+#include "sdk_macros.h"
+#include "nordic_common.h"
+
+#define NRF_LOG_MODULE_NAME nfc_t4t_tlv_block_parser
+#if NFC_T4T_TLV_BLOCK_PARSER_LOG_ENABLED
+#define NRF_LOG_LEVEL NFC_T4T_TLV_BLOCK_PARSER_LOG_LEVEL
+#define NRF_LOG_INFO_COLOR NFC_T4T_TLV_BLOCK_PARSER_INFO_COLOR
+#include "nrf_log.h"
+NRF_LOG_MODULE_REGISTER();
+#else // NFC_T4T_TLV_BLOCK_PARSER_LOG_ENABLED
+#define NRF_LOG_LEVEL 0
+#include "nrf_log.h"
+#endif // NFC_T4T_TLV_BLOCK_PARSER_LOG_ENABLED
+
+#define TLV_TYPE_FIELD_LEN 1U ///< Length of a type field.
+
+/**
+ * @brief TLV length field related defines.
+ */
+#define TLV_LEN_SHORT_FIELD_LEN 1U ///< Length of a short length field.
+#define TLV_LEN_LONG_FIELD_LEN 3U ///< Length of an extended length field.
+#define TLV_LEN_LONG_FORMAT_TOKEN 0xFF ///< Value indicating the use of an extended length field.
+#define TLV_LEN_LONG_FORMAT_TOKEN_SIZE 1U ///< Size of long format token.
+#define TLV_LEN_LONG_FORMAT_MIN_VALUE 0xFF ///< The minimal value of length field that can be used in long format.
+
+/**
+ * @brief Possible sizes of TLV block.
+ */
+#define TLV_MIN_TL_FIELD_LEN (TLV_TYPE_FIELD_LEN + TLV_LEN_SHORT_FIELD_LEN)
+#define TLV_MIN_LONG_FORMAT_TL_FIELD_LEN (TLV_TYPE_FIELD_LEN + TLV_LEN_LONG_FIELD_LEN)
+#define TLV_MIN_VALUE_FIELD_SIZE 6U
+
+/**
+ * @brief Field sizes that are present in TLV block.
+ */
+#define FILE_CONTROL_FILE_ID_FIELD_SIZE 2U
+#define FILE_CONTROL_READ_ACCESS_FIELD_SIZE 1U
+#define FILE_CONTROL_WRITE_ACCESS_FIELD_SIZE 1U
+#define FILE_CONTROL_COMMON_FIELDS_SIZE (FILE_CONTROL_FILE_ID_FIELD_SIZE \
+ + FILE_CONTROL_READ_ACCESS_FIELD_SIZE \
+ + FILE_CONTROL_WRITE_ACCESS_FIELD_SIZE)
+
+/**
+ * @brief Invalid values for File Identifier field.
+ */
+#define FILE_ID_INVALID_VALUE_0 0x0000
+#define FILE_ID_INVALID_VALUE_1 0xE102
+#define FILE_ID_INVALID_VALUE_2 0xE103
+#define FILE_ID_INVALID_VALUE_3 0x3F00
+#define FILE_ID_INVALID_VALUE_4 0x3FFF
+#define FILE_ID_INVALID_VALUE_5 0xFFFF
+
+/**
+ * @brief NDEF file related defines.
+ */
+#define NDEF_FILE_MAX_SIZE_FIELD_SIZE 2U
+#define NDEF_FILE_MAX_SIZE_MIN_VAL 0x0005
+#define NDEF_FILE_MAX_SIZE_MAX_VAL 0xFFFE
+#define NDEF_FILE_CONTROL_TLV_LEN (FILE_CONTROL_COMMON_FIELDS_SIZE \
+ + NDEF_FILE_MAX_SIZE_FIELD_SIZE)
+
+/**
+ * @brief Proprietary file related defines.
+ */
+#define PROPRIETARY_FILE_MAX_SIZE_FIELD_SIZE 2U
+#define PROPRIETARY_FILE_MAX_SIZE_MIN_VAL 0x0003
+#define PROPRIETARY_FILE_MAX_SIZE_MAX_VAL 0xFFFE
+#define PROPRIETARY_FILE_CONTROL_TLV_LEN (FILE_CONTROL_COMMON_FIELDS_SIZE \
+ + PROPRIETARY_FILE_MAX_SIZE_FIELD_SIZE)
+
+/**
+ * @brief Extended NDEF file related defines.
+ */
+#define EXTENDED_NDEF_FILE_MAX_SIZE_FIELD_SIZE 4U
+#define EXTENDED_NDEF_FILE_MAX_SIZE_MIN_VAL 0x0000FFFF
+#define EXTENDED_NDEF_FILE_MAX_SIZE_MAX_VAL 0xFFFFFFFE
+#define EXTENDED_NDEF_FILE_CONTROL_TLV_LEN (FILE_CONTROL_COMMON_FIELDS_SIZE \
+ + EXTENDED_NDEF_FILE_MAX_SIZE_FIELD_SIZE)
+
+/**
+ * @brief Validates maximum file size field range. This field is present in every File Control TLV.
+ */
+#define NFC_T4T_FILE_CONTROL_MAX_SIZE_FIELD_RANGE_VERIFY(VALUE, MIN, MAX) \
+ if ( ( (VALUE) < (MIN) ) || ( (VALUE) > (MAX) ) ) \
+ { \
+ return NRF_ERROR_INVALID_DATA; \
+ }
+
+
+/**
+ * @brief Function for validating all possible types of File Control TLV.
+ */
+__STATIC_INLINE ret_code_t nfc_t4t_file_control_tl_validate(nfc_t4t_tlv_block_t * p_file_control_tlv)
+{
+ switch (p_file_control_tlv->type)
+ {
+ case NDEF_FILE_CONTROL_TLV:
+ VERIFY_TRUE(p_file_control_tlv->length == NDEF_FILE_CONTROL_TLV_LEN,
+ NRF_ERROR_INVALID_DATA);
+ return NRF_SUCCESS;
+
+ case PROPRIETARY_FILE_CONTROL_TLV:
+ VERIFY_TRUE(p_file_control_tlv->length == PROPRIETARY_FILE_CONTROL_TLV_LEN,
+ NRF_ERROR_INVALID_DATA);
+ return NRF_SUCCESS;
+
+ case EXTENDED_NDEF_FILE_CONTROL_TLV:
+ VERIFY_TRUE(p_file_control_tlv->length == EXTENDED_NDEF_FILE_CONTROL_TLV_LEN,
+ NRF_ERROR_INVALID_DATA);
+ return NRF_SUCCESS;
+
+ default:
+ return NRF_ERROR_INVALID_DATA;
+ }
+}
+
+
+/**
+ * @brief Function for parsing value field of File Control TLV.
+ */
+static ret_code_t nfc_t4t_file_control_value_parse(nfc_t4t_tlv_block_t * p_file_control_tlv,
+ uint8_t * p_value_buff)
+{
+ nfc_t4t_file_control_val_t * p_control_tlv_val;
+
+ // Handle File Identifier field.
+ p_control_tlv_val = &p_file_control_tlv->value;
+ p_control_tlv_val->file_id = uint16_big_decode(p_value_buff);
+ p_value_buff += FILE_CONTROL_FILE_ID_FIELD_SIZE;
+
+ switch (p_control_tlv_val->file_id)
+ {
+ case FILE_ID_INVALID_VALUE_0:
+ case FILE_ID_INVALID_VALUE_1:
+ case FILE_ID_INVALID_VALUE_2:
+ case FILE_ID_INVALID_VALUE_3:
+ case FILE_ID_INVALID_VALUE_4:
+ case FILE_ID_INVALID_VALUE_5:
+ return NRF_ERROR_INVALID_DATA;
+
+ default:
+ break;
+ }
+
+ // Handle Max file size field.
+ switch (p_file_control_tlv->type)
+ {
+ case NDEF_FILE_CONTROL_TLV:
+ p_control_tlv_val->max_file_size = uint16_big_decode(p_value_buff);
+ p_value_buff += NDEF_FILE_MAX_SIZE_FIELD_SIZE;
+ NFC_T4T_FILE_CONTROL_MAX_SIZE_FIELD_RANGE_VERIFY(p_control_tlv_val->max_file_size,
+ NDEF_FILE_MAX_SIZE_MIN_VAL,
+ NDEF_FILE_MAX_SIZE_MAX_VAL);
+ break;
+
+ case PROPRIETARY_FILE_CONTROL_TLV:
+ p_control_tlv_val->max_file_size = uint16_big_decode(p_value_buff);
+ p_value_buff += PROPRIETARY_FILE_MAX_SIZE_FIELD_SIZE;
+ NFC_T4T_FILE_CONTROL_MAX_SIZE_FIELD_RANGE_VERIFY(p_control_tlv_val->max_file_size,
+ PROPRIETARY_FILE_MAX_SIZE_MIN_VAL,
+ PROPRIETARY_FILE_MAX_SIZE_MAX_VAL);
+ break;
+
+ case EXTENDED_NDEF_FILE_CONTROL_TLV:
+ p_control_tlv_val->max_file_size = uint32_big_decode(p_value_buff);
+ p_value_buff += EXTENDED_NDEF_FILE_MAX_SIZE_FIELD_SIZE;
+ NFC_T4T_FILE_CONTROL_MAX_SIZE_FIELD_RANGE_VERIFY(p_control_tlv_val->max_file_size,
+ EXTENDED_NDEF_FILE_MAX_SIZE_MIN_VAL,
+ EXTENDED_NDEF_FILE_MAX_SIZE_MAX_VAL);
+ break;
+ }
+
+ // Handle read access condition field.
+ p_control_tlv_val->read_access = *p_value_buff;
+ p_value_buff += FILE_CONTROL_READ_ACCESS_FIELD_SIZE;
+
+ // Handle write access condition field.
+ p_control_tlv_val->write_access = *p_value_buff;
+
+ return NRF_SUCCESS;
+}
+
+
+ret_code_t nfc_t4t_file_control_tlv_parse(nfc_t4t_tlv_block_t * p_file_control_tlv,
+ uint8_t * p_raw_data,
+ uint16_t * p_len)
+{
+ ret_code_t err_code;
+ uint8_t * p_offset = p_raw_data;
+
+ if (*p_len < TLV_MIN_TL_FIELD_LEN)
+ {
+ return NRF_ERROR_INVALID_LENGTH;
+ }
+ memset(p_file_control_tlv, 0, sizeof(nfc_t4t_tlv_block_t));
+
+ // Handle type field of TLV block.
+ p_file_control_tlv->type = *p_offset;
+ p_offset += TLV_TYPE_FIELD_LEN;
+
+ // Handle length field of TLV block.
+ if (*p_offset == TLV_LEN_LONG_FORMAT_TOKEN)
+ {
+ if (*p_len < TLV_MIN_LONG_FORMAT_TL_FIELD_LEN)
+ {
+ return NRF_ERROR_INVALID_LENGTH;
+ }
+
+ p_file_control_tlv->length = uint16_big_decode(p_offset + TLV_LEN_LONG_FORMAT_TOKEN_SIZE);
+ p_offset += TLV_LEN_LONG_FIELD_LEN;
+
+ if (p_file_control_tlv->length < TLV_LEN_LONG_FORMAT_MIN_VALUE)
+ {
+ return NRF_ERROR_INVALID_DATA;
+ }
+ }
+ else
+ {
+ p_file_control_tlv->length = *p_offset;
+ p_offset += TLV_LEN_SHORT_FIELD_LEN;
+ }
+
+ // Calculate the total TLV block size.
+ uint16_t tlv_block_len = (p_offset - p_raw_data) + p_file_control_tlv->length;
+ if (*p_len < tlv_block_len)
+ {
+ return NRF_ERROR_INVALID_LENGTH;
+ }
+ *p_len = tlv_block_len;
+
+ // Validate if type and length fields contain values supported by Type 4 Tag.
+ err_code = nfc_t4t_file_control_tl_validate(p_file_control_tlv);
+ VERIFY_SUCCESS(err_code);
+
+ // Handle value field of TLV block.
+ err_code = nfc_t4t_file_control_value_parse(p_file_control_tlv, p_offset);
+ return err_code;
+}
+
+
+void nfc_t4t_file_control_tlv_printout(uint8_t num, nfc_t4t_tlv_block_t * p_t4t_tlv_block)
+{
+ NRF_LOG_INFO("%d file Control TLV", num);
+ switch (p_t4t_tlv_block->type)
+ {
+ case NDEF_FILE_CONTROL_TLV:
+ NRF_LOG_INFO("Type: NDEF File Control (0x%02x)", p_t4t_tlv_block->type);
+ break;
+
+ case PROPRIETARY_FILE_CONTROL_TLV:
+ NRF_LOG_INFO("Type: Proprietary File Control (0x%02x)", p_t4t_tlv_block->type);
+ break;
+
+ case EXTENDED_NDEF_FILE_CONTROL_TLV:
+ NRF_LOG_INFO("Type: Extended NDEF File Control (0x%02x)", p_t4t_tlv_block->type);
+ break;
+
+ default:
+ NRF_LOG_INFO("Type: Unknown (0x%02x)", p_t4t_tlv_block->type);
+ }
+ NRF_LOG_INFO("Length (in bytes): %d", p_t4t_tlv_block->length);
+
+ nfc_t4t_file_control_val_t * p_tlv_val = &p_t4t_tlv_block->value;
+ NRF_LOG_INFO("File Identifier: 0x%04X ", p_tlv_val->file_id);
+ NRF_LOG_INFO("Maximum file size: %d ", p_tlv_val->max_file_size);
+ NRF_LOG_INFO("Read access condition: 0x%02X ", p_tlv_val->read_access);
+ NRF_LOG_INFO("Write access condition: 0x%02x ", p_tlv_val->write_access);
+
+ if (p_tlv_val->file.p_content != NULL)
+ {
+ NRF_LOG_INFO("NDEF file content present. Length: %d ", p_tlv_val->file.len);
+ NRF_LOG_HEXDUMP_INFO(p_tlv_val->file.p_content, p_tlv_val->file.len);
+ }
+ else
+ {
+ NRF_LOG_INFO("NDEF file content is not present ");
+ }
+}
+
+
+#endif // NFC_T4T_TLV_BLOCK_PARSER_ENABLED
+
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/t4t_parser/tlv/nfc_t4t_tlv_block.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/t4t_parser/tlv/nfc_t4t_tlv_block.h
new file mode 100644
index 0000000..f67396b
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/nfc/t4t_parser/tlv/nfc_t4t_tlv_block.h
@@ -0,0 +1,147 @@
+/**
+ * Copyright (c) 2016 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#ifndef NFC_T4T_TLV_BLOCK_H__
+#define NFC_T4T_TLV_BLOCK_H__
+
+/**@file
+ *
+ * @defgroup nfc_t4t_tlv_block File Control TLV block parser for Type 4 Tag.
+ * @{
+ * @ingroup nfc_t4t_cc_file
+ *
+ * @brief File Control TLV block parser for Type 4 Tag (T4T).
+ *
+ */
+
+#include <stdint.h>
+#include "sdk_errors.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define CONTROL_FILE_READ_ACCESS_GRANTED 0x00 ///< Read access granted without any security.
+
+/**
+ * @name Possible values of file write access condition field.
+ * @{
+ */
+#define CONTROL_FILE_WRITE_ACCESS_GRANTED 0x00 ///< Write access granted without any security.
+#define CONTROL_FILE_WRITE_ACCESS_DISABLED 0xFF ///< No write access granted without any security (read-only).
+/** @} */
+
+/**
+ * @brief Possible types of File Control TLV for Type 4 Tag.
+ */
+typedef enum
+{
+ NDEF_FILE_CONTROL_TLV = 0x04, ///< Control information concerning the EF file with short NDEF message.
+ PROPRIETARY_FILE_CONTROL_TLV = 0x05, ///< Control information concerning the Proprietary file with proprietary data.
+ EXTENDED_NDEF_FILE_CONTROL_TLV = 0x06 ///< Control information concerning the EF file with long NDEF message.
+} nfc_t4t_tlv_block_types_t;
+
+/**
+ * @brief File content descriptor.
+ */
+typedef struct
+{
+ uint8_t * p_content; ///< Pointer to the file content.
+ uint16_t len; ///< Length of file content.
+} nfc_t4t_file_t;
+
+/**
+ * @brief Extended NDEF/NDEF/Proprietary File Control Value descriptor.
+ */
+typedef struct
+{
+ nfc_t4t_file_t file; ///< Pointer to the described file content.
+ uint32_t max_file_size; ///< Maximum size (in bytes) of the file.
+ uint16_t file_id; ///< File identifier.
+ uint8_t read_access; ///< File read access condition.
+ uint8_t write_access; ///< File write access condition.
+} nfc_t4t_file_control_val_t;
+
+/**
+ * @brief File Control TLV block descriptor.
+ */
+typedef struct
+{
+ nfc_t4t_file_control_val_t value; ///< Value field descriptor.
+ uint16_t length; ///< Length of the value field.
+ uint8_t type; ///< Type of the TLV block.
+} nfc_t4t_tlv_block_t;
+
+/**
+ * @brief Function for parsing raw data of File Control TLV, read from a Type 4 Tag.
+ *
+ * This function parses raw data of File Control TLV and stores the results in its
+ * descriptor.
+ *
+ * @param[in,out] p_file_control_tlv Pointer to the File Control TLV that will be filled with
+ * parsed data.
+ * @param[in] p_raw_data Pointer to the buffer with raw TLV data.
+ * @param[in,out] p_len In: Buffer length with TLV blocks.
+ * Out: Total length of first identified TLV within the buffer.
+ *
+ * @retval NRF_SUCCESS If operation was successful.
+ * @retval NRF_ERROR_INVALID_LENGTH If provided buffer length is too small for TLV block.
+ * @retval NRF_ERROR_INVALID_DATA If any TLV block field contains invalid data.
+ */
+ret_code_t nfc_t4t_file_control_tlv_parse(nfc_t4t_tlv_block_t * p_file_control_tlv,
+ uint8_t * p_raw_data,
+ uint16_t * p_len);
+
+/**
+ * @brief Function for printing TLV block descriptor.
+ *
+ * This function prints TLV block descriptor.
+ *
+ * @param[in] num TLV block number.
+ * @param[in] p_t4t_tlv_block Pointer to the TLV block descriptor.
+ */
+void nfc_t4t_file_control_tlv_printout(uint8_t num, nfc_t4t_tlv_block_t * p_t4t_tlv_block);
+
+/** @} */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* NFC_T4T_TLV_BLOCK_H__ */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/proprietary_rf/esb/nrf_esb.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/proprietary_rf/esb/nrf_esb.c
new file mode 100644
index 0000000..5624d19
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/proprietary_rf/esb/nrf_esb.c
@@ -0,0 +1,1603 @@
+/**
+ * Copyright (c) 2016 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+
+#include "nrf_error.h"
+#include "nrf_esb.h"
+#include "nrf_esb_error_codes.h"
+#include "nrf_gpio.h"
+#include <string.h>
+#include <stddef.h>
+#include "sdk_common.h"
+#include "sdk_macros.h"
+#include "app_util.h"
+#include "nrf_log.h"
+#include "nrf_delay.h"
+
+#define BIT_MASK_UINT_8(x) (0xFF >> (8 - (x)))
+#define NRF_ESB_PIPE_COUNT 8
+
+// Constant parameters
+#define RX_WAIT_FOR_ACK_TIMEOUT_US_2MBPS (48) /**< 2 Mb RX wait for acknowledgment time-out value. Smallest reliable value - 43. */
+#define RX_WAIT_FOR_ACK_TIMEOUT_US_1MBPS (64) /**< 1 Mb RX wait for acknowledgment time-out value. Smallest reliable value - 59. */
+#define RX_WAIT_FOR_ACK_TIMEOUT_US_250KBPS (250) /**< 250 Kb RX wait for acknowledgment time-out value. */
+#define RX_WAIT_FOR_ACK_TIMEOUT_US_1MBPS_BLE (73) /**< 1 Mb RX wait for acknowledgment time-out (combined with BLE). Smallest reliable value - 68.*/
+
+// Interrupt flags
+#define NRF_ESB_INT_TX_SUCCESS_MSK 0x01 /**< Interrupt mask value for TX success. */
+#define NRF_ESB_INT_TX_FAILED_MSK 0x02 /**< Interrupt mask value for TX failure. */
+#define NRF_ESB_INT_RX_DATA_RECEIVED_MSK 0x04 /**< Interrupt mask value for RX_DR. */
+
+#define NRF_ESB_PID_RESET_VALUE 0xFF /**< Invalid PID value which is guaranteed to not collide with any valid PID value. */
+#define NRF_ESB_PID_MAX 3 /**< Maximum value for PID. */
+#define NRF_ESB_CRC_RESET_VALUE 0xFFFF /**< CRC reset value. */
+
+// Internal Enhanced ShockBurst module state.
+typedef enum {
+ NRF_ESB_STATE_IDLE, /**< Module idle. */
+ NRF_ESB_STATE_PTX_TX, /**< Module transmitting without acknowledgment. */
+ NRF_ESB_STATE_PTX_TX_ACK, /**< Module transmitting with acknowledgment. */
+ NRF_ESB_STATE_PTX_RX_ACK, /**< Module transmitting with acknowledgment and reception of payload with the acknowledgment response. */
+ NRF_ESB_STATE_PRX, /**< Module receiving packets without acknowledgment. */
+ NRF_ESB_STATE_PRX_SEND_ACK, /**< Module transmitting acknowledgment in RX mode. */
+} nrf_esb_mainstate_t;
+
+
+#define DISABLE_RF_IRQ() NVIC_DisableIRQ(RADIO_IRQn)
+#define ENABLE_RF_IRQ() NVIC_EnableIRQ(RADIO_IRQn)
+
+#define _RADIO_SHORTS_COMMON ( RADIO_SHORTS_READY_START_Msk | RADIO_SHORTS_END_DISABLE_Msk | \
+ RADIO_SHORTS_ADDRESS_RSSISTART_Msk | RADIO_SHORTS_DISABLED_RSSISTOP_Msk )
+
+#define VERIFY_PAYLOAD_LENGTH(p) \
+do \
+{ \
+ if (p->length == 0 || \
+ p->length > NRF_ESB_MAX_PAYLOAD_LENGTH || \
+ (m_config_local.protocol == NRF_ESB_PROTOCOL_ESB && \
+ p->length > m_config_local.payload_length)) \
+ { \
+ return NRF_ERROR_INVALID_LENGTH; \
+ } \
+}while (0)
+
+
+/* @brief Structure holding pipe info PID and CRC and acknowledgment payload. */
+typedef struct
+{
+ uint16_t crc; /**< CRC value of the last received packet (Used to detect retransmits). */
+ uint8_t pid; /**< Packet ID of the last received packet (Used to detect retransmits). */
+ bool ack_payload; /**< Flag indicating the state of the transmission of acknowledgment payloads. */
+} pipe_info_t;
+
+
+/* @brief First-in, first-out queue of payloads to be transmitted. */
+typedef struct
+{
+ nrf_esb_payload_t * p_payload[NRF_ESB_TX_FIFO_SIZE]; /**< Pointer to the actual queue. */
+ uint32_t entry_point; /**< Current start of queue. */
+ uint32_t exit_point; /**< Current end of queue. */
+ uint32_t count; /**< Current number of elements in the queue. */
+} nrf_esb_payload_tx_fifo_t;
+
+
+/* @brief First-in, first-out queue of received payloads. */
+typedef struct
+{
+ nrf_esb_payload_t * p_payload[NRF_ESB_RX_FIFO_SIZE]; /**< Pointer to the actual queue. */
+ uint32_t entry_point; /**< Current start of queue. */
+ uint32_t exit_point; /**< Current end of queue. */
+ uint32_t count; /**< Current number of elements in the queue. */
+} nrf_esb_payload_rx_fifo_t;
+
+
+/**@brief Enhanced ShockBurst address.
+ *
+ * Enhanced ShockBurst addresses consist of a base address and a prefix
+ * that is unique for each pipe. See @ref esb_addressing in the ESB user
+ * guide for more information.
+*/
+typedef struct
+{
+ uint8_t base_addr_p0[4]; /**< Base address for pipe 0 encoded in big endian. */
+ uint8_t base_addr_p1[4]; /**< Base address for pipe 1-7 encoded in big endian. */
+ uint8_t pipe_prefixes[8]; /**< Address prefix for pipe 0 to 7. */
+ uint8_t num_pipes; /**< Number of pipes available. */
+ uint8_t addr_length; /**< Length of the address including the prefix. */
+ uint8_t rx_pipes_enabled; /**< Bitfield for enabled pipes. */
+ uint8_t rf_channel; /**< Channel to use (must be between 0 and 100). */
+} nrf_esb_address_t;
+
+
+// Module state
+static bool m_esb_initialized = false;
+static nrf_esb_mainstate_t m_nrf_esb_mainstate = NRF_ESB_STATE_IDLE;
+static nrf_esb_payload_t * mp_current_payload;
+
+static nrf_esb_event_handler_t m_event_handler;
+
+// Address parameters
+__ALIGN(4) static nrf_esb_address_t m_esb_addr = NRF_ESB_ADDR_DEFAULT;
+
+// RF parameters
+static nrf_esb_config_t m_config_local;
+
+// TX FIFO
+static nrf_esb_payload_t m_tx_fifo_payload[NRF_ESB_TX_FIFO_SIZE];
+static nrf_esb_payload_tx_fifo_t m_tx_fifo;
+
+// RX FIFO
+static nrf_esb_payload_t m_rx_fifo_payload[NRF_ESB_RX_FIFO_SIZE];
+static nrf_esb_payload_rx_fifo_t m_rx_fifo;
+
+// Payload buffers
+static uint8_t m_tx_payload_buffer[NRF_ESB_MAX_PAYLOAD_LENGTH + 2];
+static uint8_t m_rx_payload_buffer[NRF_ESB_MAX_PAYLOAD_LENGTH + 2];
+
+// Run time variables
+static volatile uint32_t m_interrupt_flags = 0;
+static uint8_t m_pids[NRF_ESB_PIPE_COUNT];
+static pipe_info_t m_rx_pipe_info[NRF_ESB_PIPE_COUNT];
+static volatile uint32_t m_retransmits_remaining;
+static volatile uint32_t m_last_tx_attempts;
+static volatile uint32_t m_wait_for_ack_timeout_us;
+
+// nRF52 address workaround enable
+#ifdef NRF52
+static bool m_address_hang_fix_enable = true;
+#endif
+static uint32_t m_radio_shorts_common = _RADIO_SHORTS_COMMON;
+
+// These function pointers are changed dynamically, depending on protocol configuration and state.
+static void (*on_radio_disabled)(void) = 0;
+static void (*on_radio_end)(void) = 0;
+static void (*update_rf_payload_format)(uint32_t payload_length) = 0;
+
+
+// The following functions are assigned to the function pointers above.
+static void on_radio_disabled_tx_noack(void);
+static void on_radio_disabled_tx(void);
+static void on_radio_disabled_tx_wait_for_ack(void);
+static void on_radio_disabled_rx(void);
+static void on_radio_disabled_rx_ack(void);
+
+
+#define NRF_ESB_ADDR_UPDATE_MASK_BASE0 (1 << 0) /*< Mask value to signal updating BASE0 radio address. */
+#define NRF_ESB_ADDR_UPDATE_MASK_BASE1 (1 << 1) /*< Mask value to signal updating BASE1 radio address. */
+#define NRF_ESB_ADDR_UPDATE_MASK_PREFIX (1 << 2) /*< Mask value to signal updating radio prefixes. */
+
+
+// Function to do bytewise bit-swap on an unsigned 32-bit value
+static uint32_t bytewise_bit_swap(uint8_t const * p_inp)
+{
+ uint32_t inp = (*(uint32_t*)p_inp);
+#if __CORTEX_M == (0x04U)
+ return __REV((uint32_t)__RBIT(inp)); //lint -esym(628, __rev) -esym(526, __rev) -esym(628, __rbit) -esym(526, __rbit) */
+#else
+ inp = (inp & 0xF0F0F0F0) >> 4 | (inp & 0x0F0F0F0F) << 4;
+ inp = (inp & 0xCCCCCCCC) >> 2 | (inp & 0x33333333) << 2;
+ inp = (inp & 0xAAAAAAAA) >> 1 | (inp & 0x55555555) << 1;
+ return inp;
+#endif
+}
+
+
+// Internal function to convert base addresses from nRF24L type addressing to nRF51 type addressing
+static uint32_t addr_conv(uint8_t const* p_addr)
+{
+ return __REV(bytewise_bit_swap(p_addr)); //lint -esym(628, __rev) -esym(526, __rev) */
+}
+
+
+static ret_code_t apply_address_workarounds()
+{
+#ifdef NRF52
+ // Set up radio parameters.
+ NRF_RADIO->MODECNF0 = (NRF_RADIO->MODECNF0 & ~RADIO_MODECNF0_RU_Msk) | RADIO_MODECNF0_RU_Default << RADIO_MODECNF0_RU_Pos;
+
+ // Workaround for nRF52832 Rev 1 Errata 102 and nRF52832 Rev 1 Errata 106. This will reduce sensitivity by 3dB.
+ *((volatile uint32_t *)0x40001774) = (*((volatile uint32_t *)0x40001774) & 0xFFFFFFFE) | 0x01000000;
+#endif
+ return NRF_SUCCESS;
+}
+
+
+static void update_rf_payload_format_esb_dpl(uint32_t payload_length)
+{
+#if (NRF_ESB_MAX_PAYLOAD_LENGTH <= 32)
+ // Using 6 bits for length
+ NRF_RADIO->PCNF0 = (0 << RADIO_PCNF0_S0LEN_Pos) |
+ (6 << RADIO_PCNF0_LFLEN_Pos) |
+ (3 << RADIO_PCNF0_S1LEN_Pos) ;
+#else
+ // Using 8 bits for length
+ NRF_RADIO->PCNF0 = (0 << RADIO_PCNF0_S0LEN_Pos) |
+ (8 << RADIO_PCNF0_LFLEN_Pos) |
+ (3 << RADIO_PCNF0_S1LEN_Pos) ;
+#endif
+ NRF_RADIO->PCNF1 = (RADIO_PCNF1_WHITEEN_Disabled << RADIO_PCNF1_WHITEEN_Pos) |
+ (RADIO_PCNF1_ENDIAN_Big << RADIO_PCNF1_ENDIAN_Pos) |
+ ((m_esb_addr.addr_length - 1) << RADIO_PCNF1_BALEN_Pos) |
+ (0 << RADIO_PCNF1_STATLEN_Pos) |
+ (NRF_ESB_MAX_PAYLOAD_LENGTH << RADIO_PCNF1_MAXLEN_Pos);
+}
+
+
+static void update_rf_payload_format_esb(uint32_t payload_length)
+{
+ NRF_RADIO->PCNF0 = (1 << RADIO_PCNF0_S0LEN_Pos) |
+ (0 << RADIO_PCNF0_LFLEN_Pos) |
+ (1 << RADIO_PCNF0_S1LEN_Pos);
+
+ NRF_RADIO->PCNF1 = (RADIO_PCNF1_WHITEEN_Disabled << RADIO_PCNF1_WHITEEN_Pos) |
+ (RADIO_PCNF1_ENDIAN_Big << RADIO_PCNF1_ENDIAN_Pos) |
+ ((m_esb_addr.addr_length - 1) << RADIO_PCNF1_BALEN_Pos) |
+ (payload_length << RADIO_PCNF1_STATLEN_Pos) |
+ (payload_length << RADIO_PCNF1_MAXLEN_Pos);
+}
+
+
+static void update_radio_addresses(uint8_t update_mask)
+{
+ if ((update_mask & NRF_ESB_ADDR_UPDATE_MASK_BASE0) != 0)
+ {
+ NRF_RADIO->BASE0 = addr_conv(m_esb_addr.base_addr_p0);
+ }
+
+ if ((update_mask & NRF_ESB_ADDR_UPDATE_MASK_BASE1) != 0)
+ {
+ NRF_RADIO->BASE1 = addr_conv(m_esb_addr.base_addr_p1);
+ }
+
+ if ((update_mask & NRF_ESB_ADDR_UPDATE_MASK_PREFIX) != 0)
+ {
+ NRF_RADIO->PREFIX0 = bytewise_bit_swap(&m_esb_addr.pipe_prefixes[0]);
+ NRF_RADIO->PREFIX1 = bytewise_bit_swap(&m_esb_addr.pipe_prefixes[4]);
+ }
+}
+
+
+static void update_radio_tx_power()
+{
+ NRF_RADIO->TXPOWER = m_config_local.tx_output_power << RADIO_TXPOWER_TXPOWER_Pos;
+}
+
+
+static bool update_radio_bitrate()
+{
+ NRF_RADIO->MODE = m_config_local.bitrate << RADIO_MODE_MODE_Pos;
+
+ switch (m_config_local.bitrate)
+ {
+ case NRF_ESB_BITRATE_2MBPS:
+#ifdef NRF52
+ case NRF_ESB_BITRATE_2MBPS_BLE:
+#endif
+ m_wait_for_ack_timeout_us = RX_WAIT_FOR_ACK_TIMEOUT_US_2MBPS;
+ break;
+
+ case NRF_ESB_BITRATE_1MBPS:
+ m_wait_for_ack_timeout_us = RX_WAIT_FOR_ACK_TIMEOUT_US_1MBPS;
+ break;
+
+#ifdef NRF51
+ case NRF_ESB_BITRATE_250KBPS:
+ m_wait_for_ack_timeout_us = RX_WAIT_FOR_ACK_TIMEOUT_US_250KBPS;
+ break;
+#endif
+
+ case NRF_ESB_BITRATE_1MBPS_BLE:
+ m_wait_for_ack_timeout_us = RX_WAIT_FOR_ACK_TIMEOUT_US_1MBPS_BLE;
+ break;
+
+ default:
+ // Should not be reached
+ return false;
+ }
+ return true;
+}
+
+
+static bool update_radio_protocol()
+{
+ switch (m_config_local.protocol)
+ {
+ case NRF_ESB_PROTOCOL_ESB_DPL:
+ update_rf_payload_format = update_rf_payload_format_esb_dpl;
+ break;
+
+ case NRF_ESB_PROTOCOL_ESB:
+ update_rf_payload_format = update_rf_payload_format_esb;
+ break;
+
+ default:
+ // Should not be reached
+ return false;
+ }
+ return true;
+}
+
+
+static bool update_radio_crc()
+{
+ switch(m_config_local.crc)
+ {
+ case NRF_ESB_CRC_16BIT:
+ NRF_RADIO->CRCINIT = 0xFFFFUL; // Initial value
+ NRF_RADIO->CRCPOLY = 0x11021UL; // CRC poly: x^16+x^12^x^5+1
+ break;
+
+ case NRF_ESB_CRC_8BIT:
+ NRF_RADIO->CRCINIT = 0xFFUL; // Initial value
+ NRF_RADIO->CRCPOLY = 0x107UL; // CRC poly: x^8+x^2^x^1+1
+ break;
+
+ case NRF_ESB_CRC_OFF:
+ break;
+
+ default:
+ return false;
+ }
+ NRF_RADIO->CRCCNF = m_config_local.crc << RADIO_CRCCNF_LEN_Pos;
+ return true;
+}
+
+
+static bool update_radio_parameters()
+{
+ bool params_valid = true;
+ update_radio_tx_power();
+ params_valid &= update_radio_bitrate();
+ params_valid &= update_radio_protocol();
+ params_valid &= update_radio_crc();
+ update_rf_payload_format(m_config_local.payload_length);
+ params_valid &= (m_config_local.retransmit_delay >= NRF_ESB_RETRANSMIT_DELAY_MIN);
+ return params_valid;
+}
+
+
+static void reset_fifos()
+{
+ m_tx_fifo.entry_point = 0;
+ m_tx_fifo.exit_point = 0;
+ m_tx_fifo.count = 0;
+
+ m_rx_fifo.entry_point = 0;
+ m_rx_fifo.exit_point = 0;
+ m_rx_fifo.count = 0;
+}
+
+
+static void initialize_fifos()
+{
+ reset_fifos();
+
+ for (int i = 0; i < NRF_ESB_TX_FIFO_SIZE; i++)
+ {
+ m_tx_fifo.p_payload[i] = &m_tx_fifo_payload[i];
+ }
+
+ for (int i = 0; i < NRF_ESB_RX_FIFO_SIZE; i++)
+ {
+ m_rx_fifo.p_payload[i] = &m_rx_fifo_payload[i];
+ }
+}
+
+
+static void tx_fifo_remove_last()
+{
+ if (m_tx_fifo.count > 0)
+ {
+ DISABLE_RF_IRQ();
+
+ m_tx_fifo.count--;
+ if (++m_tx_fifo.exit_point >= NRF_ESB_TX_FIFO_SIZE)
+ {
+ m_tx_fifo.exit_point = 0;
+ }
+
+ ENABLE_RF_IRQ();
+ }
+}
+
+/** @brief Function to push the content of the rx_buffer to the RX FIFO.
+ *
+ * The module will point the register NRF_RADIO->PACKETPTR to a buffer for receiving packets.
+ * After receiving a packet the module will call this function to copy the received data to
+ * the RX FIFO.
+ *
+ * @param pipe Pipe number to set for the packet.
+ * @param pid Packet ID.
+ *
+ * @retval true Operation successful.
+ * @retval false Operation failed.
+ */
+static bool rx_fifo_push_rfbuf(uint8_t pipe, uint8_t pid)
+{
+ if (m_rx_fifo.count < NRF_ESB_RX_FIFO_SIZE)
+ {
+ if (m_config_local.protocol == NRF_ESB_PROTOCOL_ESB_DPL)
+ {
+ if (m_rx_payload_buffer[0] > NRF_ESB_MAX_PAYLOAD_LENGTH)
+ {
+ return false;
+ }
+
+ m_rx_fifo.p_payload[m_rx_fifo.entry_point]->length = m_rx_payload_buffer[0];
+ }
+ else if (m_config_local.mode == NRF_ESB_MODE_PTX)
+ {
+ // Received packet is an acknowledgment
+ m_rx_fifo.p_payload[m_rx_fifo.entry_point]->length = 0;
+ }
+ else
+ {
+ m_rx_fifo.p_payload[m_rx_fifo.entry_point]->length = m_config_local.payload_length;
+ }
+
+ memcpy(m_rx_fifo.p_payload[m_rx_fifo.entry_point]->data, &m_rx_payload_buffer[2],
+ m_rx_fifo.p_payload[m_rx_fifo.entry_point]->length);
+
+ m_rx_fifo.p_payload[m_rx_fifo.entry_point]->pipe = pipe;
+ m_rx_fifo.p_payload[m_rx_fifo.entry_point]->rssi = NRF_RADIO->RSSISAMPLE;
+ m_rx_fifo.p_payload[m_rx_fifo.entry_point]->pid = pid;
+ m_rx_fifo.p_payload[m_rx_fifo.entry_point]->noack = !(m_rx_payload_buffer[1] & 0x01);
+ if (++m_rx_fifo.entry_point >= NRF_ESB_RX_FIFO_SIZE)
+ {
+ m_rx_fifo.entry_point = 0;
+ }
+ m_rx_fifo.count++;
+
+ return true;
+ }
+
+ return false;
+}
+
+
+static void sys_timer_init()
+{
+ // Configure the system timer with a 1 MHz base frequency
+ NRF_ESB_SYS_TIMER->PRESCALER = 4;
+ NRF_ESB_SYS_TIMER->BITMODE = TIMER_BITMODE_BITMODE_16Bit;
+ NRF_ESB_SYS_TIMER->SHORTS = TIMER_SHORTS_COMPARE1_CLEAR_Msk | TIMER_SHORTS_COMPARE1_STOP_Msk;
+}
+
+
+static void ppi_init()
+{
+ NRF_PPI->CH[NRF_ESB_PPI_TIMER_START].EEP = (uint32_t)&NRF_RADIO->EVENTS_READY;
+ NRF_PPI->CH[NRF_ESB_PPI_TIMER_START].TEP = (uint32_t)&NRF_ESB_SYS_TIMER->TASKS_START;
+
+ NRF_PPI->CH[NRF_ESB_PPI_TIMER_STOP].EEP = (uint32_t)&NRF_RADIO->EVENTS_ADDRESS;
+ NRF_PPI->CH[NRF_ESB_PPI_TIMER_STOP].TEP = (uint32_t)&NRF_ESB_SYS_TIMER->TASKS_STOP;
+
+ NRF_PPI->CH[NRF_ESB_PPI_RX_TIMEOUT].EEP = (uint32_t)&NRF_ESB_SYS_TIMER->EVENTS_COMPARE[0];
+ NRF_PPI->CH[NRF_ESB_PPI_RX_TIMEOUT].TEP = (uint32_t)&NRF_RADIO->TASKS_DISABLE;
+
+ NRF_PPI->CH[NRF_ESB_PPI_TX_START].EEP = (uint32_t)&NRF_ESB_SYS_TIMER->EVENTS_COMPARE[1];
+ NRF_PPI->CH[NRF_ESB_PPI_TX_START].TEP = (uint32_t)&NRF_RADIO->TASKS_TXEN;
+}
+
+
+static void start_tx_transaction()
+{
+ bool ack;
+
+ m_last_tx_attempts = 1;
+ // Prepare the payload
+ mp_current_payload = m_tx_fifo.p_payload[m_tx_fifo.exit_point];
+
+
+ switch (m_config_local.protocol)
+ {
+ case NRF_ESB_PROTOCOL_ESB:
+ update_rf_payload_format(mp_current_payload->length);
+ m_tx_payload_buffer[0] = mp_current_payload->pid;
+ m_tx_payload_buffer[1] = 0;
+ memcpy(&m_tx_payload_buffer[2], mp_current_payload->data, mp_current_payload->length);
+
+ NRF_RADIO->SHORTS = m_radio_shorts_common | RADIO_SHORTS_DISABLED_RXEN_Msk;
+ NRF_RADIO->INTENSET = RADIO_INTENSET_DISABLED_Msk | RADIO_INTENSET_READY_Msk;
+
+ // Configure the retransmit counter
+ m_retransmits_remaining = m_config_local.retransmit_count;
+ on_radio_disabled = on_radio_disabled_tx;
+ m_nrf_esb_mainstate = NRF_ESB_STATE_PTX_TX_ACK;
+ break;
+
+ case NRF_ESB_PROTOCOL_ESB_DPL:
+ ack = !mp_current_payload->noack || !m_config_local.selective_auto_ack;
+ m_tx_payload_buffer[0] = mp_current_payload->length;
+ m_tx_payload_buffer[1] = mp_current_payload->pid << 1;
+ m_tx_payload_buffer[1] |= mp_current_payload->noack ? 0x00 : 0x01;
+ memcpy(&m_tx_payload_buffer[2], mp_current_payload->data, mp_current_payload->length);
+
+ // Handling ack if noack is set to false or if selective auto ack is turned off
+ if (ack)
+ {
+ NRF_RADIO->SHORTS = m_radio_shorts_common | RADIO_SHORTS_DISABLED_RXEN_Msk;
+ NRF_RADIO->INTENSET = RADIO_INTENSET_DISABLED_Msk | RADIO_INTENSET_READY_Msk;
+
+ // Configure the retransmit counter
+ m_retransmits_remaining = m_config_local.retransmit_count;
+ on_radio_disabled = on_radio_disabled_tx;
+ m_nrf_esb_mainstate = NRF_ESB_STATE_PTX_TX_ACK;
+ }
+ else
+ {
+ NRF_RADIO->SHORTS = m_radio_shorts_common;
+ NRF_RADIO->INTENSET = RADIO_INTENSET_DISABLED_Msk;
+ on_radio_disabled = on_radio_disabled_tx_noack;
+ m_nrf_esb_mainstate = NRF_ESB_STATE_PTX_TX;
+ }
+ break;
+
+ default:
+ // Should not be reached
+ break;
+ }
+
+ NRF_RADIO->TXADDRESS = mp_current_payload->pipe;
+ NRF_RADIO->RXADDRESSES = 1 << mp_current_payload->pipe;
+
+ NRF_RADIO->FREQUENCY = m_esb_addr.rf_channel;
+ NRF_RADIO->PACKETPTR = (uint32_t)m_tx_payload_buffer;
+
+ NVIC_ClearPendingIRQ(RADIO_IRQn);
+ NVIC_EnableIRQ(RADIO_IRQn);
+
+ NRF_RADIO->EVENTS_ADDRESS = 0;
+ NRF_RADIO->EVENTS_PAYLOAD = 0;
+ NRF_RADIO->EVENTS_DISABLED = 0;
+
+ DEBUG_PIN_SET(DEBUGPIN4);
+ NRF_RADIO->TASKS_TXEN = 1;
+}
+
+
+static void on_radio_disabled_tx_noack()
+{
+ m_interrupt_flags |= NRF_ESB_INT_TX_SUCCESS_MSK;
+ tx_fifo_remove_last();
+
+ if (m_tx_fifo.count == 0)
+ {
+ m_nrf_esb_mainstate = NRF_ESB_STATE_IDLE;
+ NVIC_SetPendingIRQ(ESB_EVT_IRQ);
+ }
+ else
+ {
+ NVIC_SetPendingIRQ(ESB_EVT_IRQ);
+ start_tx_transaction();
+ }
+}
+
+
+static void on_radio_disabled_tx()
+{
+ // Remove the DISABLED -> RXEN shortcut, to make sure the radio stays
+ // disabled after the RX window
+ NRF_RADIO->SHORTS = m_radio_shorts_common;
+
+ // Make sure the timer is started the next time the radio is ready,
+ // and that it will disable the radio automatically if no packet is
+ // received by the time defined in m_wait_for_ack_timeout_us
+ NRF_ESB_SYS_TIMER->CC[0] = m_wait_for_ack_timeout_us;
+ NRF_ESB_SYS_TIMER->CC[1] = m_config_local.retransmit_delay - 130;
+ NRF_ESB_SYS_TIMER->TASKS_CLEAR = 1;
+ NRF_ESB_SYS_TIMER->EVENTS_COMPARE[0] = 0;
+ NRF_ESB_SYS_TIMER->EVENTS_COMPARE[1] = 0;
+
+ NRF_PPI->CHENSET = (1 << NRF_ESB_PPI_TIMER_START) |
+ (1 << NRF_ESB_PPI_RX_TIMEOUT) |
+ (1 << NRF_ESB_PPI_TIMER_STOP);
+ NRF_PPI->CHENCLR = (1 << NRF_ESB_PPI_TX_START);
+ NRF_RADIO->EVENTS_END = 0;
+
+ if (m_config_local.protocol == NRF_ESB_PROTOCOL_ESB)
+ {
+ update_rf_payload_format(0);
+ }
+
+ NRF_RADIO->PACKETPTR = (uint32_t)m_rx_payload_buffer;
+ on_radio_disabled = on_radio_disabled_tx_wait_for_ack;
+ m_nrf_esb_mainstate = NRF_ESB_STATE_PTX_RX_ACK;
+}
+
+
+static void on_radio_disabled_tx_wait_for_ack()
+{
+ // This marks the completion of a TX_RX sequence (TX with ACK)
+
+ // Make sure the timer will not deactivate the radio if a packet is received
+ NRF_PPI->CHENCLR = (1 << NRF_ESB_PPI_TIMER_START) |
+ (1 << NRF_ESB_PPI_RX_TIMEOUT) |
+ (1 << NRF_ESB_PPI_TIMER_STOP);
+
+ // If the radio has received a packet and the CRC status is OK
+ if (NRF_RADIO->EVENTS_END && NRF_RADIO->CRCSTATUS != 0)
+ {
+ NRF_ESB_SYS_TIMER->TASKS_STOP = 1;
+ NRF_PPI->CHENCLR = (1 << NRF_ESB_PPI_TX_START);
+ m_interrupt_flags |= NRF_ESB_INT_TX_SUCCESS_MSK;
+ m_last_tx_attempts = m_config_local.retransmit_count - m_retransmits_remaining + 1;
+
+ tx_fifo_remove_last();
+
+ if (m_config_local.protocol != NRF_ESB_PROTOCOL_ESB && m_rx_payload_buffer[0] > 0)
+ {
+ if (rx_fifo_push_rfbuf((uint8_t)NRF_RADIO->TXADDRESS, m_rx_payload_buffer[1] >> 1))
+ {
+ m_interrupt_flags |= NRF_ESB_INT_RX_DATA_RECEIVED_MSK;
+ }
+ }
+
+ if ((m_tx_fifo.count == 0) || (m_config_local.tx_mode == NRF_ESB_TXMODE_MANUAL))
+ {
+ m_nrf_esb_mainstate = NRF_ESB_STATE_IDLE;
+ NVIC_SetPendingIRQ(ESB_EVT_IRQ);
+ }
+ else
+ {
+ NVIC_SetPendingIRQ(ESB_EVT_IRQ);
+ start_tx_transaction();
+ }
+ }
+ else
+ {
+ if (m_retransmits_remaining-- == 0)
+ {
+ NRF_ESB_SYS_TIMER->TASKS_STOP = 1;
+ NRF_PPI->CHENCLR = (1 << NRF_ESB_PPI_TX_START);
+ // All retransmits are expended, and the TX operation is suspended
+ m_last_tx_attempts = m_config_local.retransmit_count + 1;
+ m_interrupt_flags |= NRF_ESB_INT_TX_FAILED_MSK;
+
+ m_nrf_esb_mainstate = NRF_ESB_STATE_IDLE;
+ NVIC_SetPendingIRQ(ESB_EVT_IRQ);
+ }
+ else
+ {
+ // There are still more retransmits left, TX mode should be
+ // entered again as soon as the system timer reaches CC[1].
+ NRF_RADIO->SHORTS = m_radio_shorts_common | RADIO_SHORTS_DISABLED_RXEN_Msk;
+ update_rf_payload_format(mp_current_payload->length);
+ NRF_RADIO->PACKETPTR = (uint32_t)m_tx_payload_buffer;
+ on_radio_disabled = on_radio_disabled_tx;
+ m_nrf_esb_mainstate = NRF_ESB_STATE_PTX_TX_ACK;
+ NRF_ESB_SYS_TIMER->TASKS_START = 1;
+ NRF_PPI->CHENSET = (1 << NRF_ESB_PPI_TX_START);
+ if (NRF_ESB_SYS_TIMER->EVENTS_COMPARE[1])
+ {
+ NRF_RADIO->TASKS_TXEN = 1;
+ }
+ }
+ }
+}
+
+static void clear_events_restart_rx(void)
+{
+ NRF_RADIO->SHORTS = m_radio_shorts_common;
+ update_rf_payload_format(m_config_local.payload_length);
+ NRF_RADIO->PACKETPTR = (uint32_t)m_rx_payload_buffer;
+ NRF_RADIO->EVENTS_DISABLED = 0;
+ NRF_RADIO->TASKS_DISABLE = 1;
+
+ while (NRF_RADIO->EVENTS_DISABLED == 0);
+
+ NRF_RADIO->EVENTS_DISABLED = 0;
+ NRF_RADIO->SHORTS = m_radio_shorts_common | RADIO_SHORTS_DISABLED_TXEN_Msk;
+
+ NRF_RADIO->TASKS_RXEN = 1;
+}
+
+static void on_radio_disabled_rx(void)
+{
+ bool ack = false;
+ bool retransmit_payload = false;
+ bool send_rx_event = true;
+ pipe_info_t * p_pipe_info;
+
+ if (NRF_RADIO->CRCSTATUS == 0)
+ {
+ clear_events_restart_rx();
+ return;
+ }
+
+ if (m_rx_fifo.count >= NRF_ESB_RX_FIFO_SIZE)
+ {
+ clear_events_restart_rx();
+ return;
+ }
+
+ p_pipe_info = &m_rx_pipe_info[NRF_RADIO->RXMATCH];
+ if (NRF_RADIO->RXCRC == p_pipe_info->crc &&
+ (m_rx_payload_buffer[1] >> 1) == p_pipe_info->pid
+ )
+ {
+ retransmit_payload = true;
+ send_rx_event = false;
+ }
+
+ p_pipe_info->pid = m_rx_payload_buffer[1] >> 1;
+ p_pipe_info->crc = NRF_RADIO->RXCRC;
+
+ if ((m_config_local.selective_auto_ack == false) || ((m_rx_payload_buffer[1] & 0x01) == 1))
+ {
+ ack = true;
+ }
+
+ if (ack)
+ {
+ NRF_RADIO->SHORTS = m_radio_shorts_common | RADIO_SHORTS_DISABLED_RXEN_Msk;
+
+ switch (m_config_local.protocol)
+ {
+ case NRF_ESB_PROTOCOL_ESB_DPL:
+ {
+ if (m_tx_fifo.count > 0 &&
+ (m_tx_fifo.p_payload[m_tx_fifo.exit_point]->pipe == NRF_RADIO->RXMATCH)
+ )
+ {
+ // Pipe stays in ACK with payload until TX FIFO is empty
+ // Do not report TX success on first ack payload or retransmit
+ if (p_pipe_info->ack_payload == true && !retransmit_payload)
+ {
+ if (++m_tx_fifo.exit_point >= NRF_ESB_TX_FIFO_SIZE)
+ {
+ m_tx_fifo.exit_point = 0;
+ }
+
+ m_tx_fifo.count--;
+
+ // ACK payloads also require TX_DS
+ // (page 40 of the 'nRF24LE1_Product_Specification_rev1_6.pdf').
+ m_interrupt_flags |= NRF_ESB_INT_TX_SUCCESS_MSK;
+ }
+
+ p_pipe_info->ack_payload = true;
+
+ mp_current_payload = m_tx_fifo.p_payload[m_tx_fifo.exit_point];
+
+ update_rf_payload_format(mp_current_payload->length);
+ m_tx_payload_buffer[0] = mp_current_payload->length;
+ memcpy(&m_tx_payload_buffer[2],
+ mp_current_payload->data,
+ mp_current_payload->length);
+ }
+ else
+ {
+ p_pipe_info->ack_payload = false;
+ update_rf_payload_format(0);
+ m_tx_payload_buffer[0] = 0;
+ }
+
+ m_tx_payload_buffer[1] = m_rx_payload_buffer[1];
+ }
+ break;
+
+ case NRF_ESB_PROTOCOL_ESB:
+ {
+ update_rf_payload_format(0);
+ m_tx_payload_buffer[0] = m_rx_payload_buffer[0];
+ m_tx_payload_buffer[1] = 0;
+ }
+ break;
+ }
+
+ m_nrf_esb_mainstate = NRF_ESB_STATE_PRX_SEND_ACK;
+ NRF_RADIO->TXADDRESS = NRF_RADIO->RXMATCH;
+ NRF_RADIO->PACKETPTR = (uint32_t)m_tx_payload_buffer;
+ on_radio_disabled = on_radio_disabled_rx_ack;
+ }
+ else
+ {
+ clear_events_restart_rx();
+ }
+
+ if (send_rx_event)
+ {
+ // Push the new packet to the RX buffer and trigger a received event if the operation was
+ // successful.
+ if (rx_fifo_push_rfbuf(NRF_RADIO->RXMATCH, p_pipe_info->pid))
+ {
+ m_interrupt_flags |= NRF_ESB_INT_RX_DATA_RECEIVED_MSK;
+ NVIC_SetPendingIRQ(ESB_EVT_IRQ);
+ }
+ }
+}
+
+
+static void on_radio_disabled_rx_ack(void)
+{
+ NRF_RADIO->SHORTS = m_radio_shorts_common | RADIO_SHORTS_DISABLED_TXEN_Msk;
+ update_rf_payload_format(m_config_local.payload_length);
+
+ NRF_RADIO->PACKETPTR = (uint32_t)m_rx_payload_buffer;
+ on_radio_disabled = on_radio_disabled_rx;
+
+ m_nrf_esb_mainstate = NRF_ESB_STATE_PRX;
+}
+
+
+/**@brief Function for clearing pending interrupts.
+ *
+ * @param[in,out] p_interrupts Pointer to the value that holds the current interrupts.
+ *
+ * @retval NRF_SUCCESS If the interrupts were cleared successfully.
+ * @retval NRF_ERROR_NULL If the required parameter was NULL.
+ * @retval NRF_INVALID_STATE If the module is not initialized.
+ */
+static uint32_t nrf_esb_get_clear_interrupts(uint32_t * p_interrupts)
+{
+ VERIFY_TRUE(m_esb_initialized, NRF_ERROR_INVALID_STATE);
+ VERIFY_PARAM_NOT_NULL(p_interrupts);
+
+ DISABLE_RF_IRQ();
+
+ *p_interrupts = m_interrupt_flags;
+ m_interrupt_flags = 0;
+
+ ENABLE_RF_IRQ();
+
+ return NRF_SUCCESS;
+}
+
+
+void RADIO_IRQHandler()
+{
+ if (NRF_RADIO->EVENTS_READY && (NRF_RADIO->INTENSET & RADIO_INTENSET_READY_Msk))
+ {
+ NRF_RADIO->EVENTS_READY = 0;
+ DEBUG_PIN_SET(DEBUGPIN1);
+ }
+
+ if (NRF_RADIO->EVENTS_END && (NRF_RADIO->INTENSET & RADIO_INTENSET_END_Msk))
+ {
+ NRF_RADIO->EVENTS_END = 0;
+ DEBUG_PIN_SET(DEBUGPIN2);
+
+ // Call the correct on_radio_end function, depending on the current protocol state
+ if (on_radio_end)
+ {
+ on_radio_end();
+ }
+ }
+
+ if (NRF_RADIO->EVENTS_DISABLED && (NRF_RADIO->INTENSET & RADIO_INTENSET_DISABLED_Msk))
+ {
+ NRF_RADIO->EVENTS_DISABLED = 0;
+ DEBUG_PIN_SET(DEBUGPIN3);
+
+ // Call the correct on_radio_disable function, depending on the current protocol state
+ if (on_radio_disabled)
+ {
+ on_radio_disabled();
+ }
+ }
+
+ DEBUG_PIN_CLR(DEBUGPIN1);
+ DEBUG_PIN_CLR(DEBUGPIN2);
+ DEBUG_PIN_CLR(DEBUGPIN3);
+ DEBUG_PIN_CLR(DEBUGPIN4);
+}
+
+
+uint32_t nrf_esb_init(nrf_esb_config_t const * p_config)
+{
+ uint32_t err_code;
+
+ VERIFY_PARAM_NOT_NULL(p_config);
+
+ if (m_esb_initialized)
+ {
+ err_code = nrf_esb_disable();
+ if (err_code != NRF_SUCCESS)
+ {
+ return err_code;
+ }
+ }
+
+ m_event_handler = p_config->event_handler;
+
+ memcpy(&m_config_local, p_config, sizeof(nrf_esb_config_t));
+
+ m_interrupt_flags = 0;
+
+ memset(m_rx_pipe_info, 0, sizeof(m_rx_pipe_info));
+ memset(m_pids, 0, sizeof(m_pids));
+
+ VERIFY_TRUE(update_radio_parameters(), NRF_ERROR_INVALID_PARAM);
+
+ // Configure radio address registers according to ESB default values
+ NRF_RADIO->BASE0 = 0xE7E7E7E7;
+ NRF_RADIO->BASE1 = 0x43434343;
+ NRF_RADIO->PREFIX0 = 0x23C343E7;
+ NRF_RADIO->PREFIX1 = 0x13E363A3;
+
+ initialize_fifos();
+
+ sys_timer_init();
+
+ ppi_init();
+
+ NVIC_SetPriority(RADIO_IRQn, m_config_local.radio_irq_priority & ESB_IRQ_PRIORITY_MSK);
+ NVIC_SetPriority(ESB_EVT_IRQ, m_config_local.event_irq_priority & ESB_IRQ_PRIORITY_MSK);
+ NVIC_EnableIRQ(ESB_EVT_IRQ);
+
+#ifdef NRF52
+ if(m_address_hang_fix_enable)
+ {
+ // Setup a timeout timer to start on an ADDRESS match, and stop on a BCMATCH event.
+ // If the BCMATCH event never occurs the CC[0] event will fire, and the timer interrupt will disable the radio to recover.
+ m_radio_shorts_common |= RADIO_SHORTS_ADDRESS_BCSTART_Msk;
+ NRF_RADIO->BCC = 2;
+ NRF_ESB_BUGFIX_TIMER->BITMODE = TIMER_BITMODE_BITMODE_32Bit << TIMER_BITMODE_BITMODE_Pos;
+ NRF_ESB_BUGFIX_TIMER->PRESCALER = 4;
+ NRF_ESB_BUGFIX_TIMER->CC[0] = 5;
+ NRF_ESB_BUGFIX_TIMER->SHORTS = TIMER_SHORTS_COMPARE0_STOP_Msk | TIMER_SHORTS_COMPARE0_CLEAR_Msk;
+ NRF_ESB_BUGFIX_TIMER->MODE = TIMER_MODE_MODE_Timer << TIMER_MODE_MODE_Pos;
+ NRF_ESB_BUGFIX_TIMER->INTENSET = TIMER_INTENSET_COMPARE0_Msk;
+ NRF_ESB_BUGFIX_TIMER->TASKS_CLEAR = 1;
+ NVIC_SetPriority(NRF_ESB_BUGFIX_TIMER_IRQn, 5);
+ NVIC_EnableIRQ(NRF_ESB_BUGFIX_TIMER_IRQn);
+
+ NRF_PPI->CH[NRF_ESB_PPI_BUGFIX1].EEP = (uint32_t)&NRF_RADIO->EVENTS_ADDRESS;
+ NRF_PPI->CH[NRF_ESB_PPI_BUGFIX1].TEP = (uint32_t)&NRF_ESB_BUGFIX_TIMER->TASKS_START;
+
+ NRF_PPI->CH[NRF_ESB_PPI_BUGFIX2].EEP = (uint32_t)&NRF_RADIO->EVENTS_BCMATCH;
+ NRF_PPI->CH[NRF_ESB_PPI_BUGFIX2].TEP = (uint32_t)&NRF_ESB_BUGFIX_TIMER->TASKS_STOP;
+
+ NRF_PPI->CH[NRF_ESB_PPI_BUGFIX3].EEP = (uint32_t)&NRF_RADIO->EVENTS_BCMATCH;
+ NRF_PPI->CH[NRF_ESB_PPI_BUGFIX3].TEP = (uint32_t)&NRF_ESB_BUGFIX_TIMER->TASKS_CLEAR;
+
+ NRF_PPI->CHENSET = (1 << NRF_ESB_PPI_BUGFIX1) | (1 << NRF_ESB_PPI_BUGFIX2) | (1 << NRF_ESB_PPI_BUGFIX3);
+ }
+#endif
+
+ m_nrf_esb_mainstate = NRF_ESB_STATE_IDLE;
+ m_esb_initialized = true;
+
+ return NRF_SUCCESS;
+}
+
+
+uint32_t nrf_esb_suspend(void)
+{
+ VERIFY_TRUE(m_nrf_esb_mainstate == NRF_ESB_STATE_IDLE, NRF_ERROR_BUSY);
+
+ // Clear PPI
+ NRF_PPI->CHENCLR = (1 << NRF_ESB_PPI_TIMER_START) |
+ (1 << NRF_ESB_PPI_TIMER_STOP) |
+ (1 << NRF_ESB_PPI_RX_TIMEOUT) |
+ (1 << NRF_ESB_PPI_TX_START);
+
+ m_nrf_esb_mainstate = NRF_ESB_STATE_IDLE;
+
+ return NRF_SUCCESS;
+}
+
+
+uint32_t nrf_esb_disable(void)
+{
+ // Clear PPI
+ NRF_PPI->CHENCLR = (1 << NRF_ESB_PPI_TIMER_START) |
+ (1 << NRF_ESB_PPI_TIMER_STOP) |
+ (1 << NRF_ESB_PPI_RX_TIMEOUT) |
+ (1 << NRF_ESB_PPI_TX_START);
+
+ m_nrf_esb_mainstate = NRF_ESB_STATE_IDLE;
+
+ reset_fifos();
+
+ memset(m_rx_pipe_info, 0, sizeof(m_rx_pipe_info));
+ memset(m_pids, 0, sizeof(m_pids));
+
+ // Disable the radio
+ NVIC_DisableIRQ(ESB_EVT_IRQ);
+ NRF_RADIO->SHORTS = RADIO_SHORTS_READY_START_Enabled << RADIO_SHORTS_READY_START_Pos |
+ RADIO_SHORTS_END_DISABLE_Enabled << RADIO_SHORTS_END_DISABLE_Pos;
+
+ return NRF_SUCCESS;
+}
+
+
+bool nrf_esb_is_idle(void)
+{
+ return m_nrf_esb_mainstate == NRF_ESB_STATE_IDLE;
+}
+
+
+void ESB_EVT_IRQHandler(void)
+{
+ ret_code_t err_code;
+ uint32_t interrupts;
+ nrf_esb_evt_t event;
+
+ event.tx_attempts = m_last_tx_attempts;
+
+ err_code = nrf_esb_get_clear_interrupts(&interrupts);
+ if (err_code == NRF_SUCCESS && m_event_handler != 0)
+ {
+ if (interrupts & NRF_ESB_INT_TX_SUCCESS_MSK)
+ {
+ event.evt_id = NRF_ESB_EVENT_TX_SUCCESS;
+ m_event_handler(&event);
+ }
+ if (interrupts & NRF_ESB_INT_TX_FAILED_MSK)
+ {
+ event.evt_id = NRF_ESB_EVENT_TX_FAILED;
+ m_event_handler(&event);
+ }
+ if (interrupts & NRF_ESB_INT_RX_DATA_RECEIVED_MSK)
+ {
+ event.evt_id = NRF_ESB_EVENT_RX_RECEIVED;
+ m_event_handler(&event);
+ }
+ }
+}
+
+uint32_t nrf_esb_write_payload(nrf_esb_payload_t const * p_payload)
+{
+ VERIFY_TRUE(m_esb_initialized, NRF_ERROR_INVALID_STATE);
+ VERIFY_PARAM_NOT_NULL(p_payload);
+ VERIFY_PAYLOAD_LENGTH(p_payload);
+ VERIFY_FALSE(m_tx_fifo.count >= NRF_ESB_TX_FIFO_SIZE, NRF_ERROR_NO_MEM);
+ VERIFY_TRUE(p_payload->pipe < NRF_ESB_PIPE_COUNT, NRF_ERROR_INVALID_PARAM);
+
+ DISABLE_RF_IRQ();
+
+ memcpy(m_tx_fifo.p_payload[m_tx_fifo.entry_point], p_payload, sizeof(nrf_esb_payload_t));
+
+ m_pids[p_payload->pipe] = (m_pids[p_payload->pipe] + 1) % (NRF_ESB_PID_MAX + 1);
+ m_tx_fifo.p_payload[m_tx_fifo.entry_point]->pid = m_pids[p_payload->pipe];
+
+ if (++m_tx_fifo.entry_point >= NRF_ESB_TX_FIFO_SIZE)
+ {
+ m_tx_fifo.entry_point = 0;
+ }
+
+ m_tx_fifo.count++;
+
+ ENABLE_RF_IRQ();
+
+
+ if (m_config_local.mode == NRF_ESB_MODE_PTX &&
+ m_config_local.tx_mode == NRF_ESB_TXMODE_AUTO &&
+ m_nrf_esb_mainstate == NRF_ESB_STATE_IDLE)
+ {
+ start_tx_transaction();
+ }
+
+ return NRF_SUCCESS;
+}
+
+
+uint32_t nrf_esb_read_rx_payload(nrf_esb_payload_t * p_payload)
+{
+ VERIFY_TRUE(m_esb_initialized, NRF_ERROR_INVALID_STATE);
+ VERIFY_PARAM_NOT_NULL(p_payload);
+
+ if (m_rx_fifo.count == 0)
+ {
+ return NRF_ERROR_NOT_FOUND;
+ }
+
+ DISABLE_RF_IRQ();
+
+ p_payload->length = m_rx_fifo.p_payload[m_rx_fifo.exit_point]->length;
+ p_payload->pipe = m_rx_fifo.p_payload[m_rx_fifo.exit_point]->pipe;
+ p_payload->rssi = m_rx_fifo.p_payload[m_rx_fifo.exit_point]->rssi;
+ p_payload->pid = m_rx_fifo.p_payload[m_rx_fifo.exit_point]->pid;
+ p_payload->noack = m_rx_fifo.p_payload[m_rx_fifo.exit_point]->noack;
+ memcpy(p_payload->data, m_rx_fifo.p_payload[m_rx_fifo.exit_point]->data, p_payload->length);
+
+ if (++m_rx_fifo.exit_point >= NRF_ESB_RX_FIFO_SIZE)
+ {
+ m_rx_fifo.exit_point = 0;
+ }
+
+ m_rx_fifo.count--;
+
+ ENABLE_RF_IRQ();
+
+ return NRF_SUCCESS;
+}
+
+
+uint32_t nrf_esb_start_tx(void)
+{
+ VERIFY_TRUE(m_nrf_esb_mainstate == NRF_ESB_STATE_IDLE, NRF_ERROR_BUSY);
+
+ if (m_tx_fifo.count == 0)
+ {
+ return NRF_ERROR_BUFFER_EMPTY;
+ }
+
+ start_tx_transaction();
+
+ return NRF_SUCCESS;
+}
+
+
+uint32_t nrf_esb_start_rx(void)
+{
+ VERIFY_TRUE(m_nrf_esb_mainstate == NRF_ESB_STATE_IDLE, NRF_ERROR_BUSY);
+
+ NRF_RADIO->INTENCLR = 0xFFFFFFFF;
+ NRF_RADIO->EVENTS_DISABLED = 0;
+ on_radio_disabled = on_radio_disabled_rx;
+
+ NRF_RADIO->SHORTS = m_radio_shorts_common | RADIO_SHORTS_DISABLED_TXEN_Msk;
+ NRF_RADIO->INTENSET = RADIO_INTENSET_DISABLED_Msk;
+ m_nrf_esb_mainstate = NRF_ESB_STATE_PRX;
+
+ NRF_RADIO->RXADDRESSES = m_esb_addr.rx_pipes_enabled;
+ NRF_RADIO->FREQUENCY = m_esb_addr.rf_channel;
+ NRF_RADIO->PACKETPTR = (uint32_t)m_rx_payload_buffer;
+
+ NVIC_ClearPendingIRQ(RADIO_IRQn);
+ NVIC_EnableIRQ(RADIO_IRQn);
+
+ NRF_RADIO->EVENTS_ADDRESS = 0;
+ NRF_RADIO->EVENTS_PAYLOAD = 0;
+ NRF_RADIO->EVENTS_DISABLED = 0;
+
+ NRF_RADIO->TASKS_RXEN = 1;
+
+ return NRF_SUCCESS;
+}
+
+
+uint32_t nrf_esb_stop_rx(void)
+{
+ if (m_nrf_esb_mainstate == NRF_ESB_STATE_PRX)
+ {
+ NRF_RADIO->SHORTS = 0;
+ NRF_RADIO->INTENCLR = 0xFFFFFFFF;
+ on_radio_disabled = NULL;
+ NRF_RADIO->EVENTS_DISABLED = 0;
+ NRF_RADIO->TASKS_DISABLE = 1;
+ while (NRF_RADIO->EVENTS_DISABLED == 0);
+ m_nrf_esb_mainstate = NRF_ESB_STATE_IDLE;
+
+ return NRF_SUCCESS;
+ }
+
+ return NRF_ESB_ERROR_NOT_IN_RX_MODE;
+}
+
+
+uint32_t nrf_esb_flush_tx(void)
+{
+ VERIFY_TRUE(m_esb_initialized, NRF_ERROR_INVALID_STATE);
+
+ DISABLE_RF_IRQ();
+
+ m_tx_fifo.count = 0;
+ m_tx_fifo.entry_point = 0;
+ m_tx_fifo.exit_point = 0;
+
+ ENABLE_RF_IRQ();
+
+ return NRF_SUCCESS;
+}
+
+
+uint32_t nrf_esb_pop_tx(void)
+{
+ VERIFY_TRUE(m_esb_initialized, NRF_ERROR_INVALID_STATE);
+ VERIFY_TRUE(m_tx_fifo.count > 0, NRF_ERROR_BUFFER_EMPTY);
+
+ DISABLE_RF_IRQ();
+
+ if (++m_tx_fifo.entry_point >= NRF_ESB_TX_FIFO_SIZE)
+ {
+ m_tx_fifo.entry_point = 0;
+ }
+ m_tx_fifo.count--;
+
+ ENABLE_RF_IRQ();
+
+ return NRF_SUCCESS;
+}
+
+
+uint32_t nrf_esb_flush_rx(void)
+{
+ VERIFY_TRUE(m_esb_initialized, NRF_ERROR_INVALID_STATE);
+
+ DISABLE_RF_IRQ();
+
+ m_rx_fifo.count = 0;
+ m_rx_fifo.entry_point = 0;
+ m_rx_fifo.exit_point = 0;
+
+ memset(m_rx_pipe_info, 0, sizeof(m_rx_pipe_info));
+
+ ENABLE_RF_IRQ();
+
+ return NRF_SUCCESS;
+}
+
+
+uint32_t nrf_esb_set_address_length(uint8_t length)
+{
+ VERIFY_TRUE(m_nrf_esb_mainstate == NRF_ESB_STATE_IDLE, NRF_ERROR_BUSY);
+ VERIFY_TRUE(length > 2 && length < 6, NRF_ERROR_INVALID_PARAM);
+
+ /*
+ Workaround for nRF52832 Rev 1 Errata 107
+ Check if pipe 0 or pipe 1-7 has a 'zero address'.
+ Avoid using access addresses in the following pattern (where X is don't care):
+ ADDRLEN=5
+ BASE0 = 0x0000XXXX, PREFIX0 = 0xXXXXXX00
+ BASE1 = 0x0000XXXX, PREFIX0 = 0xXXXX00XX
+ BASE1 = 0x0000XXXX, PREFIX0 = 0xXX00XXXX
+ BASE1 = 0x0000XXXX, PREFIX0 = 0x00XXXXXX
+ BASE1 = 0x0000XXXX, PREFIX1 = 0xXXXXXX00
+ BASE1 = 0x0000XXXX, PREFIX1 = 0xXXXX00XX
+ BASE1 = 0x0000XXXX, PREFIX1 = 0xXX00XXXX
+ BASE1 = 0x0000XXXX, PREFIX1 = 0x00XXXXXX
+
+ ADDRLEN=4
+ BASE0 = 0x00XXXXXX, PREFIX0 = 0xXXXXXX00
+ BASE1 = 0x00XXXXXX, PREFIX0 = 0xXXXX00XX
+ BASE1 = 0x00XXXXXX, PREFIX0 = 0xXX00XXXX
+ BASE1 = 0x00XXXXXX, PREFIX0 = 0x00XXXXXX
+ BASE1 = 0x00XXXXXX, PREFIX1 = 0xXXXXXX00
+ BASE1 = 0x00XXXXXX, PREFIX1 = 0xXXXX00XX
+ BASE1 = 0x00XXXXXX, PREFIX1 = 0xXX00XXXX
+ BASE1 = 0x00XXXXXX, PREFIX1 = 0x00XXXXXX
+ */
+ uint32_t base_address_mask = length == 5 ? 0xFFFF0000 : 0xFF000000;
+ if((NRF_RADIO->BASE0 & base_address_mask) == 0 && (NRF_RADIO->PREFIX0 & 0x000000FF) == 0)
+ {
+ return NRF_ERROR_INVALID_PARAM;
+ }
+ if((NRF_RADIO->BASE1 & base_address_mask) == 0 && ((NRF_RADIO->PREFIX0 & 0x0000FF00) == 0 ||(NRF_RADIO->PREFIX0 & 0x00FF0000) == 0 || (NRF_RADIO->PREFIX0 & 0xFF000000) == 0 ||
+ (NRF_RADIO->PREFIX1 & 0xFF000000) == 0 || (NRF_RADIO->PREFIX1 & 0x00FF0000) == 0 ||(NRF_RADIO->PREFIX1 & 0x0000FF00) == 0 || (NRF_RADIO->PREFIX1 & 0x000000FF) == 0))
+ {
+ return NRF_ERROR_INVALID_PARAM;
+ }
+
+ m_esb_addr.addr_length = length;
+
+ update_rf_payload_format(m_config_local.payload_length);
+
+ return NRF_SUCCESS;
+}
+
+
+uint32_t nrf_esb_set_base_address_0(uint8_t const * p_addr)
+{
+ VERIFY_TRUE(m_nrf_esb_mainstate == NRF_ESB_STATE_IDLE, NRF_ERROR_BUSY);
+ VERIFY_PARAM_NOT_NULL(p_addr);
+
+ /*
+ Workaround for nRF52832 Rev 1 Errata 107
+ Check if pipe 0 or pipe 1-7 has a 'zero address'.
+ Avoid using access addresses in the following pattern (where X is don't care):
+ ADDRLEN=5
+ BASE0 = 0x0000XXXX, PREFIX0 = 0xXXXXXX00
+ BASE1 = 0x0000XXXX, PREFIX0 = 0xXXXX00XX
+ BASE1 = 0x0000XXXX, PREFIX0 = 0xXX00XXXX
+ BASE1 = 0x0000XXXX, PREFIX0 = 0x00XXXXXX
+ BASE1 = 0x0000XXXX, PREFIX1 = 0xXXXXXX00
+ BASE1 = 0x0000XXXX, PREFIX1 = 0xXXXX00XX
+ BASE1 = 0x0000XXXX, PREFIX1 = 0xXX00XXXX
+ BASE1 = 0x0000XXXX, PREFIX1 = 0x00XXXXXX
+
+ ADDRLEN=4
+ BASE0 = 0x00XXXXXX, PREFIX0 = 0xXXXXXX00
+ BASE1 = 0x00XXXXXX, PREFIX0 = 0xXXXX00XX
+ BASE1 = 0x00XXXXXX, PREFIX0 = 0xXX00XXXX
+ BASE1 = 0x00XXXXXX, PREFIX0 = 0x00XXXXXX
+ BASE1 = 0x00XXXXXX, PREFIX1 = 0xXXXXXX00
+ BASE1 = 0x00XXXXXX, PREFIX1 = 0xXXXX00XX
+ BASE1 = 0x00XXXXXX, PREFIX1 = 0xXX00XXXX
+ BASE1 = 0x00XXXXXX, PREFIX1 = 0x00XXXXXX
+ */
+ uint32_t base_address_mask = m_esb_addr.addr_length == 5 ? 0xFFFF0000 : 0xFF000000;
+ if((addr_conv(p_addr) & base_address_mask) == 0 && (NRF_RADIO->PREFIX0 & 0x000000FF) == 0)
+ {
+ return NRF_ERROR_INVALID_PARAM;
+ }
+
+ memcpy(m_esb_addr.base_addr_p0, p_addr, 4);
+
+ update_radio_addresses(NRF_ESB_ADDR_UPDATE_MASK_BASE0);
+
+ return apply_address_workarounds();
+}
+
+
+uint32_t nrf_esb_set_base_address_1(uint8_t const * p_addr)
+{
+ VERIFY_TRUE(m_nrf_esb_mainstate == NRF_ESB_STATE_IDLE, NRF_ERROR_BUSY);
+ VERIFY_PARAM_NOT_NULL(p_addr);
+
+ /*
+ Workaround for nRF52832 Rev 1 Errata 107
+ Check if pipe 0 or pipe 1-7 has a 'zero address'.
+ Avoid using access addresses in the following pattern (where X is don't care):
+ ADDRLEN=5
+ BASE0 = 0x0000XXXX, PREFIX0 = 0xXXXXXX00
+ BASE1 = 0x0000XXXX, PREFIX0 = 0xXXXX00XX
+ BASE1 = 0x0000XXXX, PREFIX0 = 0xXX00XXXX
+ BASE1 = 0x0000XXXX, PREFIX0 = 0x00XXXXXX
+ BASE1 = 0x0000XXXX, PREFIX1 = 0xXXXXXX00
+ BASE1 = 0x0000XXXX, PREFIX1 = 0xXXXX00XX
+ BASE1 = 0x0000XXXX, PREFIX1 = 0xXX00XXXX
+ BASE1 = 0x0000XXXX, PREFIX1 = 0x00XXXXXX
+
+ ADDRLEN=4
+ BASE0 = 0x00XXXXXX, PREFIX0 = 0xXXXXXX00
+ BASE1 = 0x00XXXXXX, PREFIX0 = 0xXXXX00XX
+ BASE1 = 0x00XXXXXX, PREFIX0 = 0xXX00XXXX
+ BASE1 = 0x00XXXXXX, PREFIX0 = 0x00XXXXXX
+ BASE1 = 0x00XXXXXX, PREFIX1 = 0xXXXXXX00
+ BASE1 = 0x00XXXXXX, PREFIX1 = 0xXXXX00XX
+ BASE1 = 0x00XXXXXX, PREFIX1 = 0xXX00XXXX
+ BASE1 = 0x00XXXXXX, PREFIX1 = 0x00XXXXXX
+ */
+ uint32_t base_address_mask = m_esb_addr.addr_length == 5 ? 0xFFFF0000 : 0xFF000000;
+ if((addr_conv(p_addr) & base_address_mask) == 0 && ((NRF_RADIO->PREFIX0 & 0x0000FF00) == 0 ||(NRF_RADIO->PREFIX0 & 0x00FF0000) == 0 || (NRF_RADIO->PREFIX0 & 0xFF000000) == 0 ||
+ (NRF_RADIO->PREFIX1 & 0xFF000000) == 0 || (NRF_RADIO->PREFIX1 & 0x00FF0000) == 0 ||(NRF_RADIO->PREFIX1 & 0x0000FF00) == 0 || (NRF_RADIO->PREFIX1 & 0x000000FF) == 0))
+ {
+ return NRF_ERROR_INVALID_PARAM;
+ }
+
+ memcpy(m_esb_addr.base_addr_p1, p_addr, 4);
+
+ update_radio_addresses(NRF_ESB_ADDR_UPDATE_MASK_BASE1);
+
+ return apply_address_workarounds();
+}
+
+
+uint32_t nrf_esb_set_prefixes(uint8_t const * p_prefixes, uint8_t num_pipes)
+{
+ VERIFY_TRUE(m_nrf_esb_mainstate == NRF_ESB_STATE_IDLE, NRF_ERROR_BUSY);
+ VERIFY_PARAM_NOT_NULL(p_prefixes);
+ VERIFY_TRUE(num_pipes < 9, NRF_ERROR_INVALID_PARAM);
+
+ /*
+ Workaround for nRF52832 Rev 1 Errata 107
+ Check if pipe 0 or pipe 1-7 has a 'zero address'.
+ Avoid using access addresses in the following pattern (where X is don't care):
+ ADDRLEN=5
+ BASE0 = 0x0000XXXX, PREFIX0 = 0xXXXXXX00
+ BASE1 = 0x0000XXXX, PREFIX0 = 0xXXXX00XX
+ BASE1 = 0x0000XXXX, PREFIX0 = 0xXX00XXXX
+ BASE1 = 0x0000XXXX, PREFIX0 = 0x00XXXXXX
+ BASE1 = 0x0000XXXX, PREFIX1 = 0xXXXXXX00
+ BASE1 = 0x0000XXXX, PREFIX1 = 0xXXXX00XX
+ BASE1 = 0x0000XXXX, PREFIX1 = 0xXX00XXXX
+ BASE1 = 0x0000XXXX, PREFIX1 = 0x00XXXXXX
+
+ ADDRLEN=4
+ BASE0 = 0x00XXXXXX, PREFIX0 = 0xXXXXXX00
+ BASE1 = 0x00XXXXXX, PREFIX0 = 0xXXXX00XX
+ BASE1 = 0x00XXXXXX, PREFIX0 = 0xXX00XXXX
+ BASE1 = 0x00XXXXXX, PREFIX0 = 0x00XXXXXX
+ BASE1 = 0x00XXXXXX, PREFIX1 = 0xXXXXXX00
+ BASE1 = 0x00XXXXXX, PREFIX1 = 0xXXXX00XX
+ BASE1 = 0x00XXXXXX, PREFIX1 = 0xXX00XXXX
+ BASE1 = 0x00XXXXXX, PREFIX1 = 0x00XXXXXX
+ */
+ uint32_t base_address_mask = m_esb_addr.addr_length == 5 ? 0xFFFF0000 : 0xFF000000;
+ if(num_pipes >= 1 && (NRF_RADIO->BASE0 & base_address_mask) == 0 && p_prefixes[0] == 0)
+ {
+ return NRF_ERROR_INVALID_PARAM;
+ }
+
+ if((NRF_RADIO->BASE1 & base_address_mask) == 0)
+ {
+ for (uint8_t i = 1; i < num_pipes; i++)
+ {
+ if (p_prefixes[i] == 0)
+ {
+ return NRF_ERROR_INVALID_PARAM;
+ }
+ }
+ }
+
+ memcpy(m_esb_addr.pipe_prefixes, p_prefixes, num_pipes);
+ m_esb_addr.num_pipes = num_pipes;
+ m_esb_addr.rx_pipes_enabled = BIT_MASK_UINT_8(num_pipes);
+
+ update_radio_addresses(NRF_ESB_ADDR_UPDATE_MASK_PREFIX);
+
+ return apply_address_workarounds();
+}
+
+
+uint32_t nrf_esb_update_prefix(uint8_t pipe, uint8_t prefix)
+{
+ VERIFY_TRUE(m_nrf_esb_mainstate == NRF_ESB_STATE_IDLE, NRF_ERROR_BUSY);
+ VERIFY_TRUE(pipe < 8, NRF_ERROR_INVALID_PARAM);
+
+ /*
+ Workaround for nRF52832 Rev 1 Errata 107
+ Check if pipe 0 or pipe 1-7 has a 'zero address'.
+ Avoid using access addresses in the following pattern (where X is don't care):
+ ADDRLEN=5
+ BASE0 = 0x0000XXXX, PREFIX0 = 0xXXXXXX00
+ BASE1 = 0x0000XXXX, PREFIX0 = 0xXXXX00XX
+ BASE1 = 0x0000XXXX, PREFIX0 = 0xXX00XXXX
+ BASE1 = 0x0000XXXX, PREFIX0 = 0x00XXXXXX
+ BASE1 = 0x0000XXXX, PREFIX1 = 0xXXXXXX00
+ BASE1 = 0x0000XXXX, PREFIX1 = 0xXXXX00XX
+ BASE1 = 0x0000XXXX, PREFIX1 = 0xXX00XXXX
+ BASE1 = 0x0000XXXX, PREFIX1 = 0x00XXXXXX
+
+ ADDRLEN=4
+ BASE0 = 0x00XXXXXX, PREFIX0 = 0xXXXXXX00
+ BASE1 = 0x00XXXXXX, PREFIX0 = 0xXXXX00XX
+ BASE1 = 0x00XXXXXX, PREFIX0 = 0xXX00XXXX
+ BASE1 = 0x00XXXXXX, PREFIX0 = 0x00XXXXXX
+ BASE1 = 0x00XXXXXX, PREFIX1 = 0xXXXXXX00
+ BASE1 = 0x00XXXXXX, PREFIX1 = 0xXXXX00XX
+ BASE1 = 0x00XXXXXX, PREFIX1 = 0xXX00XXXX
+ BASE1 = 0x00XXXXXX, PREFIX1 = 0x00XXXXXX
+ */
+ uint32_t base_address_mask = m_esb_addr.addr_length == 5 ? 0xFFFF0000 : 0xFF000000;
+ if (pipe == 0)
+ {
+ if((NRF_RADIO->BASE0 & base_address_mask) == 0 && prefix == 0)
+ {
+ return NRF_ERROR_INVALID_PARAM;
+ }
+ }
+ else{
+ if((NRF_RADIO->BASE1 & base_address_mask) == 0 && prefix == 0)
+ {
+ return NRF_ERROR_INVALID_PARAM;
+ }
+ }
+
+ m_esb_addr.pipe_prefixes[pipe] = prefix;
+
+ update_radio_addresses(NRF_ESB_ADDR_UPDATE_MASK_PREFIX);
+
+ return apply_address_workarounds();
+}
+
+
+uint32_t nrf_esb_enable_pipes(uint8_t enable_mask)
+{
+ VERIFY_TRUE(m_nrf_esb_mainstate == NRF_ESB_STATE_IDLE, NRF_ERROR_BUSY);
+
+ m_esb_addr.rx_pipes_enabled = enable_mask;
+
+ return apply_address_workarounds();
+}
+
+
+uint32_t nrf_esb_set_rf_channel(uint32_t channel)
+{
+ VERIFY_TRUE(m_nrf_esb_mainstate == NRF_ESB_STATE_IDLE, NRF_ERROR_BUSY);
+ VERIFY_TRUE(channel <= 100, NRF_ERROR_INVALID_PARAM);
+
+ m_esb_addr.rf_channel = channel;
+
+ return NRF_SUCCESS;
+}
+
+
+uint32_t nrf_esb_get_rf_channel(uint32_t * p_channel)
+{
+ VERIFY_PARAM_NOT_NULL(p_channel);
+
+ *p_channel = m_esb_addr.rf_channel;
+
+ return NRF_SUCCESS;
+}
+
+
+uint32_t nrf_esb_set_tx_power(nrf_esb_tx_power_t tx_output_power)
+{
+ VERIFY_TRUE(m_nrf_esb_mainstate == NRF_ESB_STATE_IDLE, NRF_ERROR_BUSY);
+
+ if ( m_config_local.tx_output_power != tx_output_power )
+ {
+ m_config_local.tx_output_power = tx_output_power;
+ update_radio_tx_power();
+ }
+
+ return NRF_SUCCESS;
+}
+
+
+uint32_t nrf_esb_set_retransmit_delay(uint16_t delay)
+{
+ VERIFY_TRUE(m_nrf_esb_mainstate == NRF_ESB_STATE_IDLE, NRF_ERROR_BUSY);
+ VERIFY_TRUE(delay >= NRF_ESB_RETRANSMIT_DELAY_MIN, NRF_ERROR_INVALID_PARAM);
+
+ m_config_local.retransmit_delay = delay;
+ return NRF_SUCCESS;
+}
+
+
+uint32_t nrf_esb_set_retransmit_count(uint16_t count)
+{
+ VERIFY_TRUE(m_nrf_esb_mainstate == NRF_ESB_STATE_IDLE, NRF_ERROR_BUSY);
+
+ m_config_local.retransmit_count = count;
+ return NRF_SUCCESS;
+}
+
+
+uint32_t nrf_esb_set_bitrate(nrf_esb_bitrate_t bitrate)
+{
+ VERIFY_TRUE(m_nrf_esb_mainstate == NRF_ESB_STATE_IDLE, NRF_ERROR_BUSY);
+
+ m_config_local.bitrate = bitrate;
+ return update_radio_bitrate() ? NRF_SUCCESS : NRF_ERROR_INVALID_PARAM;
+}
+
+
+uint32_t nrf_esb_reuse_pid(uint8_t pipe)
+{
+ VERIFY_TRUE(m_nrf_esb_mainstate == NRF_ESB_STATE_IDLE, NRF_ERROR_BUSY);
+ VERIFY_TRUE(pipe < 8, NRF_ERROR_INVALID_PARAM);
+
+ m_pids[pipe] = (m_pids[pipe] + NRF_ESB_PID_MAX) % (NRF_ESB_PID_MAX + 1);
+ return NRF_SUCCESS;
+}
+
+
+// Handler for
+#ifdef NRF52
+void NRF_ESB_BUGFIX_TIMER_IRQHandler(void)
+{
+ if(NRF_ESB_BUGFIX_TIMER->EVENTS_COMPARE[0])
+ {
+ NRF_ESB_BUGFIX_TIMER->EVENTS_COMPARE[0] = 0;
+
+ // If the timeout timer fires and we are in the PTX receive ACK state, disable the radio
+ if(m_nrf_esb_mainstate == NRF_ESB_STATE_PTX_RX_ACK)
+ {
+ NRF_RADIO->TASKS_DISABLE = 1;
+ }
+ }
+}
+#endif
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/proprietary_rf/esb/nrf_esb.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/proprietary_rf/esb/nrf_esb.h
new file mode 100644
index 0000000..0c80efb
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/proprietary_rf/esb/nrf_esb.h
@@ -0,0 +1,609 @@
+/**
+ * Copyright (c) 2016 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#ifndef __NRF_ESB_H
+#define __NRF_ESB_H
+
+#include <stdbool.h>
+#include <stdint.h>
+#include "nrf.h"
+#include "app_util.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** @defgroup nrf_esb Enhanced ShockBurst
+ * @{
+ * @ingroup proprietary_api
+ *
+ * @brief Enhanced ShockBurst (ESB) is a basic protocol that supports two-way data
+ * packet communication including packet buffering, packet acknowledgment,
+ * and automatic retransmission of lost packets.
+ */
+
+/** @name Debug pins
+ * @{
+ * @brief If NRF_ESB_DEBUG is defined, these GPIO pins can be used for debug timing.
+ */
+
+#define DEBUGPIN1 12 //!< If NRF_ESB_DEBUG is defined, this GPIO pin is set with every radio interrupt.
+#define DEBUGPIN2 13 //!< If NRF_ESB_DEBUG is defined, this GPIO pin is set with every NRF_RADIO->EVENTS_END.
+#define DEBUGPIN3 14 //!< If NRF_ESB_DEBUG is defined, this GPIO pin is set with every NRF_RADIO->EVENTS_DISABLED.
+#define DEBUGPIN4 15 //!< If NRF_ESB_DEBUG is defined, this GPIO pin is set when the radio is set to start transmission.
+
+
+#ifdef NRF_ESB_DEBUG
+#define DEBUG_PIN_SET(a) (NRF_GPIO->OUTSET = (1 << (a))) //!< Used internally to set debug pins.
+#define DEBUG_PIN_CLR(a) (NRF_GPIO->OUTCLR = (1 << (a))) //!< Used internally to clear debug pins.
+#else
+#define DEBUG_PIN_SET(a) //!< Used internally to set debug pins.
+#define DEBUG_PIN_CLR(a) //!< Used internally to clear debug pins.
+#endif
+
+ /** @} */
+
+#define NRF_ESB_RETRANSMIT_DELAY_MIN 135
+
+// Hardcoded parameters - change if necessary
+#ifndef NRF_ESB_MAX_PAYLOAD_LENGTH
+#define NRF_ESB_MAX_PAYLOAD_LENGTH 32 //!< The maximum size of the payload. Valid values are 1 to 252.
+#endif
+
+#define NRF_ESB_TX_FIFO_SIZE 8 //!< The size of the transmission first-in, first-out buffer.
+#define NRF_ESB_RX_FIFO_SIZE 8 //!< The size of the reception first-in, first-out buffer.
+
+// 252 is the largest possible payload size according to the nRF5 architecture.
+STATIC_ASSERT(NRF_ESB_MAX_PAYLOAD_LENGTH <= 252);
+
+#define NRF_ESB_SYS_TIMER NRF_TIMER2 //!< The timer that is used by the module.
+#define NRF_ESB_SYS_TIMER_IRQ_Handler TIMER2_IRQHandler //!< The handler that is used by @ref NRF_ESB_SYS_TIMER.
+
+#define NRF_ESB_PPI_TIMER_START 10 //!< The PPI channel used for starting the timer.
+#define NRF_ESB_PPI_TIMER_STOP 11 //!< The PPI channel used for stopping the timer.
+#define NRF_ESB_PPI_RX_TIMEOUT 12 //!< The PPI channel used for RX time-out.
+#define NRF_ESB_PPI_TX_START 13 //!< The PPI channel used for starting TX.
+
+/**@cond NO_DOXYGEN */
+
+// nRF52 address fix timer and PPI defines
+#ifdef NRF52
+#define NRF_ESB_PPI_BUGFIX1 9
+#define NRF_ESB_PPI_BUGFIX2 8
+#define NRF_ESB_PPI_BUGFIX3 7
+
+#define NRF_ESB_BUGFIX_TIMER NRF_TIMER3
+#define NRF_ESB_BUGFIX_TIMER_IRQn TIMER3_IRQn
+#define NRF_ESB_BUGFIX_TIMER_IRQHandler TIMER3_IRQHandler
+#endif
+
+/** @endcond */
+
+// Interrupt flags
+#define NRF_ESB_INT_TX_SUCCESS_MSK 0x01 //!< The flag used to indicate a success since the last event.
+#define NRF_ESB_INT_TX_FAILED_MSK 0x02 //!< The flag used to indicate a failure since the last event.
+#define NRF_ESB_INT_RX_DR_MSK 0x04 //!< The flag used to indicate that a packet was received since the last event.
+
+#define NRF_ESB_PID_RESET_VALUE 0xFF //!< Invalid PID value that is guaranteed to not collide with any valid PID value.
+#define NRF_ESB_PID_MAX 3 //!< The maximum value for PID.
+#define NRF_ESB_CRC_RESET_VALUE 0xFFFF //!< The CRC reset value.
+
+#define ESB_EVT_IRQ SWI0_IRQn //!< The ESB event IRQ number when running on an nRF5 device.
+#define ESB_EVT_IRQHandler SWI0_IRQHandler //!< The handler for @ref ESB_EVT_IRQ when running on an nRF5 device.
+
+#if defined(NRF52)
+#define ESB_IRQ_PRIORITY_MSK 0x07 //!< The mask used to enforce a valid IRQ priority.
+#else
+#define ESB_IRQ_PRIORITY_MSK 0x03 //!< The mask used to enforce a valid IRQ priority.
+#endif
+
+/** @brief Default address configuration for ESB.
+ * @details Roughly equal to the nRF24Lxx default (except for the number of pipes, because more pipes are supported). */
+#define NRF_ESB_ADDR_DEFAULT \
+{ \
+ .base_addr_p0 = { 0xE7, 0xE7, 0xE7, 0xE7 }, \
+ .base_addr_p1 = { 0xC2, 0xC2, 0xC2, 0xC2 }, \
+ .pipe_prefixes = { 0xE7, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7, 0xC8 }, \
+ .addr_length = 5, \
+ .num_pipes = 8, \
+ .rf_channel = 2, \
+ .rx_pipes_enabled = 0xFF \
+}
+
+
+/** @brief Default radio parameters.
+ * @details Roughly equal to the nRF24Lxx default parameters (except for CRC, which is set to 16 bit, and protocol, which is set to DPL). */
+#define NRF_ESB_DEFAULT_CONFIG {.protocol = NRF_ESB_PROTOCOL_ESB_DPL, \
+ .mode = NRF_ESB_MODE_PTX, \
+ .event_handler = 0, \
+ .bitrate = NRF_ESB_BITRATE_2MBPS, \
+ .crc = NRF_ESB_CRC_16BIT, \
+ .tx_output_power = NRF_ESB_TX_POWER_0DBM, \
+ .retransmit_delay = 250, \
+ .retransmit_count = 3, \
+ .tx_mode = NRF_ESB_TXMODE_AUTO, \
+ .radio_irq_priority = 1, \
+ .event_irq_priority = 2, \
+ .payload_length = 32, \
+ .selective_auto_ack = false \
+}
+
+
+/** @brief Default legacy radio parameters. Identical to the nRF24Lxx defaults. */
+#define NRF_ESB_LEGACY_CONFIG {.protocol = NRF_ESB_PROTOCOL_ESB, \
+ .mode = NRF_ESB_MODE_PTX, \
+ .event_handler = 0, \
+ .bitrate = NRF_ESB_BITRATE_2MBPS, \
+ .crc = NRF_ESB_CRC_8BIT, \
+ .tx_output_power = NRF_ESB_TX_POWER_0DBM, \
+ .retransmit_delay = 600, \
+ .retransmit_count = 3, \
+ .tx_mode = NRF_ESB_TXMODE_AUTO, \
+ .radio_irq_priority = 1, \
+ .event_irq_priority = 2, \
+ .payload_length = 32, \
+ .selective_auto_ack = false \
+}
+
+
+/** @brief Macro to create an initializer for a TX data packet.
+ *
+ * @details This macro generates an initializer. Using the initializer is more efficient
+ * than setting the individual parameters dynamically.
+ *
+ * @param[in] _pipe The pipe to use for the data packet.
+ * @param[in] ... Comma separated list of character data to put in the TX buffer.
+ * Supported values consist of 1 to 63 characters.
+ *
+ * @return Initializer that sets up the pipe, length, and byte array for content of the TX data.
+ */
+#define NRF_ESB_CREATE_PAYLOAD(_pipe, ...) \
+ {.pipe = _pipe, .length = NUM_VA_ARGS(__VA_ARGS__), .data = {__VA_ARGS__}}; \
+ STATIC_ASSERT(NUM_VA_ARGS(__VA_ARGS__) > 0 && NUM_VA_ARGS(__VA_ARGS__) <= 63)
+
+
+/**@brief Enhanced ShockBurst protocols. */
+typedef enum {
+ NRF_ESB_PROTOCOL_ESB, /**< Enhanced ShockBurst with fixed payload length. */
+ NRF_ESB_PROTOCOL_ESB_DPL /**< Enhanced ShockBurst with dynamic payload length. */
+} nrf_esb_protocol_t;
+
+
+/**@brief Enhanced ShockBurst modes. */
+typedef enum {
+ NRF_ESB_MODE_PTX, /**< Primary transmitter mode. */
+ NRF_ESB_MODE_PRX /**< Primary receiver mode. */
+} nrf_esb_mode_t;
+
+
+/**@brief Enhanced ShockBurst bitrate modes. */
+typedef enum {
+ NRF_ESB_BITRATE_2MBPS = RADIO_MODE_MODE_Nrf_2Mbit, /**< 2 Mb radio mode. */
+ NRF_ESB_BITRATE_1MBPS = RADIO_MODE_MODE_Nrf_1Mbit, /**< 1 Mb radio mode. */
+ NRF_ESB_BITRATE_250KBPS = RADIO_MODE_MODE_Nrf_250Kbit, /**< 250 Kb radio mode. */
+ NRF_ESB_BITRATE_1MBPS_BLE = RADIO_MODE_MODE_Ble_1Mbit, /**< 1 Mb radio mode using @e Bluetooth low energy radio parameters. */
+#if defined(NRF52)
+ NRF_ESB_BITRATE_2MBPS_BLE = 4 /**< 2 Mb radio mode using @e Bluetooth low energy radio parameters. */
+#endif
+} nrf_esb_bitrate_t;
+
+
+/**@brief Enhanced ShockBurst CRC modes. */
+typedef enum {
+ NRF_ESB_CRC_16BIT = RADIO_CRCCNF_LEN_Two, /**< Use two-byte CRC. */
+ NRF_ESB_CRC_8BIT = RADIO_CRCCNF_LEN_One, /**< Use one-byte CRC. */
+ NRF_ESB_CRC_OFF = RADIO_CRCCNF_LEN_Disabled /**< Disable CRC. */
+} nrf_esb_crc_t;
+
+
+/**@brief Enhanced ShockBurst radio transmission power modes. */
+typedef enum {
+ NRF_ESB_TX_POWER_4DBM = RADIO_TXPOWER_TXPOWER_Pos4dBm, /**< 4 dBm radio transmit power. */
+#if defined(NRF52)
+ NRF_ESB_TX_POWER_3DBM = RADIO_TXPOWER_TXPOWER_Pos3dBm, /**< 3 dBm radio transmit power. */
+#endif
+ NRF_ESB_TX_POWER_0DBM = RADIO_TXPOWER_TXPOWER_0dBm, /**< 0 dBm radio transmit power. */
+ NRF_ESB_TX_POWER_NEG4DBM = RADIO_TXPOWER_TXPOWER_Neg4dBm, /**< -4 dBm radio transmit power. */
+ NRF_ESB_TX_POWER_NEG8DBM = RADIO_TXPOWER_TXPOWER_Neg8dBm, /**< -8 dBm radio transmit power. */
+ NRF_ESB_TX_POWER_NEG12DBM = RADIO_TXPOWER_TXPOWER_Neg12dBm, /**< -12 dBm radio transmit power. */
+ NRF_ESB_TX_POWER_NEG16DBM = RADIO_TXPOWER_TXPOWER_Neg16dBm, /**< -16 dBm radio transmit power. */
+ NRF_ESB_TX_POWER_NEG20DBM = RADIO_TXPOWER_TXPOWER_Neg20dBm, /**< -20 dBm radio transmit power. */
+ NRF_ESB_TX_POWER_NEG30DBM = RADIO_TXPOWER_TXPOWER_Neg30dBm /**< -30 dBm radio transmit power. */
+} nrf_esb_tx_power_t;
+
+
+/**@brief Enhanced ShockBurst transmission modes. */
+typedef enum {
+ NRF_ESB_TXMODE_AUTO, /**< Automatic TX mode: When the TX FIFO contains packets and the radio is idle, packets are sent automatically. */
+ NRF_ESB_TXMODE_MANUAL, /**< Manual TX mode: Packets are not sent until @ref nrf_esb_start_tx is called. This mode can be used to ensure consistent packet timing. */
+ NRF_ESB_TXMODE_MANUAL_START /**< Manual start TX mode: Packets are not sent until @ref nrf_esb_start_tx is called. Then, transmission continues automatically until the TX FIFO is empty. */
+} nrf_esb_tx_mode_t;
+
+
+/**@brief Enhanced ShockBurst event IDs used to indicate the type of the event. */
+typedef enum
+{
+ NRF_ESB_EVENT_TX_SUCCESS, /**< Event triggered on TX success. */
+ NRF_ESB_EVENT_TX_FAILED, /**< Event triggered on TX failure. */
+ NRF_ESB_EVENT_RX_RECEIVED /**< Event triggered on RX received. */
+} nrf_esb_evt_id_t;
+
+
+/**@brief Enhanced ShockBurst payload.
+ *
+ * @details The payload is used both for transmissions and for acknowledging a
+ * received packet with a payload.
+*/
+typedef struct
+{
+ uint8_t length; //!< Length of the packet (maximum value is @ref NRF_ESB_MAX_PAYLOAD_LENGTH).
+ uint8_t pipe; //!< Pipe used for this payload.
+ int8_t rssi; //!< RSSI for the received packet.
+ uint8_t noack; //!< Flag indicating that this packet will not be acknowledgement.
+ uint8_t pid; //!< PID assigned during communication.
+ uint8_t data[NRF_ESB_MAX_PAYLOAD_LENGTH]; //!< The payload data.
+} nrf_esb_payload_t;
+
+
+/**@brief Enhanced ShockBurst event. */
+typedef struct
+{
+ nrf_esb_evt_id_t evt_id; //!< Enhanced ShockBurst event ID.
+ uint32_t tx_attempts; //!< Number of TX retransmission attempts.
+} nrf_esb_evt_t;
+
+
+/**@brief Definition of the event handler for the module. */
+typedef void (* nrf_esb_event_handler_t)(nrf_esb_evt_t const * p_event);
+
+
+/**@brief Main configuration structure for the module. */
+typedef struct
+{
+ nrf_esb_protocol_t protocol; //!< Enhanced ShockBurst protocol.
+ nrf_esb_mode_t mode; //!< Enhanced ShockBurst mode.
+ nrf_esb_event_handler_t event_handler; //!< Enhanced ShockBurst event handler.
+
+ // General RF parameters
+ nrf_esb_bitrate_t bitrate; //!< Enhanced ShockBurst bitrate mode.
+ nrf_esb_crc_t crc; //!< Enhanced ShockBurst CRC mode.
+
+ nrf_esb_tx_power_t tx_output_power; //!< Enhanced ShockBurst radio transmission power mode.
+
+ uint16_t retransmit_delay; //!< The delay between each retransmission of unacknowledged packets.
+ uint16_t retransmit_count; //!< The number of retransmission attempts before transmission fail.
+
+ // Control settings
+ nrf_esb_tx_mode_t tx_mode; //!< Enhanced ShockBurst transmission mode.
+
+ uint8_t radio_irq_priority; //!< nRF radio interrupt priority.
+ uint8_t event_irq_priority; //!< ESB event interrupt priority.
+ uint8_t payload_length; //!< Length of the payload (maximum length depends on the platforms that are used on each side).
+
+ bool selective_auto_ack; //!< Enable or disable selective auto acknowledgement.
+} nrf_esb_config_t;
+
+
+/**@brief Function for initializing the Enhanced ShockBurst module.
+ *
+ * @param p_config Parameters for initializing the module.
+ *
+ * @retval NRF_SUCCESS If initialization was successful.
+ * @retval NRF_ERROR_NULL If the @p p_config argument was NULL.
+ * @retval NRF_ERROR_BUSY If the function failed because the radio is busy.
+ */
+uint32_t nrf_esb_init(nrf_esb_config_t const * p_config);
+
+
+/**@brief Function for suspending the Enhanced ShockBurst module.
+ *
+ * Calling this function stops ongoing communications without changing the queues.
+ *
+ * @retval NRF_SUCCESS If Enhanced ShockBurst was suspended.
+ * @retval NRF_ERROR_BUSY If the function failed because the radio is busy.
+ */
+uint32_t nrf_esb_suspend(void);
+
+
+/**@brief Function for disabling the Enhanced ShockBurst module.
+ *
+ * Calling this function disables the Enhanced ShockBurst module immediately.
+ * Doing so might stop ongoing communications.
+ *
+ * @note All queues are flushed by this function.
+ *
+ * @retval NRF_SUCCESS If Enhanced ShockBurst was disabled.
+ */
+uint32_t nrf_esb_disable(void);
+
+
+/**@brief Function for checking if the Enhanced ShockBurst module is idle.
+ *
+ * @retval true If the module is idle.
+ * @retval false If the module is busy.
+ */
+bool nrf_esb_is_idle(void);
+
+
+/**@brief Function for writing a payload for transmission or acknowledgement.
+ *
+ * This function writes a payload that is added to the queue. When the module is in PTX mode, the
+ * payload is queued for a regular transmission. When the module is in PRX mode, the payload
+ * is queued for when a packet is received that requires an acknowledgement with payload.
+ *
+ * @param[in] p_payload Pointer to the structure that contains information and state of the payload.
+ *
+ * @retval NRF_SUCCESS If the payload was successfully queued for writing.
+ * @retval NRF_ERROR_NULL If the required parameter was NULL.
+ * @retval NRF_INVALID_STATE If the module is not initialized.
+ * @retval NRF_ERROR_NOT_SUPPORTED If @p p_payload->noack was false, but selective acknowledgement is not enabled.
+ * @retval NRF_ERROR_NO_MEM If the TX FIFO is full.
+ * @retval NRF_ERROR_INVALID_LENGTH If the payload length was invalid (zero or larger than the allowed maximum).
+ */
+uint32_t nrf_esb_write_payload(nrf_esb_payload_t const * p_payload);
+
+
+/**@brief Function for reading an RX payload.
+ *
+ * @param[in,out] p_payload Pointer to the structure that contains information and state of the payload.
+ *
+ * @retval NRF_SUCCESS If the data was read successfully.
+ * @retval NRF_ERROR_NULL If the required parameter was NULL.
+ * @retval NRF_INVALID_STATE If the module is not initialized.
+ */
+uint32_t nrf_esb_read_rx_payload(nrf_esb_payload_t * p_payload);
+
+
+/**@brief Function for starting transmission.
+ *
+ * @retval NRF_SUCCESS If the TX started successfully.
+ * @retval NRF_ERROR_BUFFER_EMPTY If the TX did not start because the FIFO buffer is empty.
+ * @retval NRF_ERROR_BUSY If the function failed because the radio is busy.
+ */
+uint32_t nrf_esb_start_tx(void);
+
+
+/**@brief Function for starting to transmit data from the FIFO buffer.
+ *
+ * @retval NRF_SUCCESS If the transmission was started successfully.
+ * @retval NRF_ERROR_BUSY If the function failed because the radio is busy.
+ */
+uint32_t nrf_esb_start_rx(void);
+
+
+/** @brief Function for stopping data reception.
+ *
+ * @retval NRF_SUCCESS If data reception was stopped successfully.
+ * @retval NRF_ESB_ERROR_NOT_IN_RX_MODE If the function failed because the module is not in RX mode.
+ */
+uint32_t nrf_esb_stop_rx(void);
+
+
+/**@brief Function for removing remaining items from the TX buffer.
+ *
+ * This function clears the TX FIFO buffer.
+ *
+ * @retval NRF_SUCCESS If pending items in the TX buffer were successfully cleared.
+ * @retval NRF_INVALID_STATE If the module is not initialized.
+ */
+uint32_t nrf_esb_flush_tx(void);
+
+
+/**@brief Function for removing the first item from the TX buffer.
+ *
+ * @retval NRF_SUCCESS If the operation completed successfully.
+ * @retval NRF_INVALID_STATE If the module is not initialized.
+ * @retval NRF_ERROR_BUFFER_EMPTY If there are no items in the queue to remove.
+ */
+uint32_t nrf_esb_pop_tx(void);
+
+
+/**@brief Function for removing remaining items from the RX buffer.
+ *
+ * @retval NRF_SUCCESS If the pending items in the RX buffer were successfully cleared.
+ * @retval NRF_INVALID_STATE If the module is not initialized.
+ */
+uint32_t nrf_esb_flush_rx(void);
+
+
+/**@brief Function for setting the length of the address.
+ *
+ * @param[in] length Length of the ESB address (in bytes).
+ *
+ * @retval NRF_SUCCESS If the address length was set successfully.
+ * @retval NRF_ERROR_INVALID_PARAM If the address length was invalid.
+ * @retval NRF_ERROR_BUSY If the function failed because the radio is busy.
+ */
+uint32_t nrf_esb_set_address_length(uint8_t length);
+
+
+/**@brief Function for setting the base address for pipe 0.
+ *
+ * @param[in] p_addr Pointer to the address data.
+ *
+ * @retval NRF_SUCCESS If the base address was set successfully.
+ * @retval NRF_ERROR_BUSY If the function failed because the radio is busy.
+ * @retval NRF_ERROR_INVALID_PARAM If the function failed because the address given was too close to a zero address.
+ * @retval NRF_ERROR_NULL If the required parameter was NULL.
+ */
+uint32_t nrf_esb_set_base_address_0(uint8_t const * p_addr);
+
+
+/**@brief Function for setting the base address for pipe 1 to pipe 7.
+ *
+ * @param[in] p_addr Pointer to the address data.
+ *
+ * @retval NRF_SUCCESS If the base address was set successfully.
+ * @retval NRF_ERROR_BUSY If the function failed because the radio is busy.
+ * @retval NRF_ERROR_INVALID_PARAM If the function failed because the address given was too close to a zero address.
+ * @retval NRF_ERROR_NULL If the required parameter was NULL.
+ */
+uint32_t nrf_esb_set_base_address_1(uint8_t const * p_addr);
+
+
+/**@brief Function for setting the number of pipes and the pipe prefix addresses.
+ *
+ * This function configures the number of available pipes, enables the pipes,
+ * and sets their prefix addresses.
+ *
+ * @param[in] p_prefixes Pointer to a char array that contains the prefix for each pipe.
+ * @param[in] num_pipes Number of pipes.
+ *
+ * @retval NRF_SUCCESS If the prefix addresses were set successfully.
+ * @retval NRF_ERROR_BUSY If the function failed because the radio is busy.
+ * @retval NRF_ERROR_NULL If a required parameter was NULL.
+ * @retval NRF_ERROR_INVALID_PARAM If an invalid number of pipes was given or if the address given was too close to a zero address.
+ */
+uint32_t nrf_esb_set_prefixes(uint8_t const * p_prefixes, uint8_t num_pipes);
+
+
+/**@brief Function for enabling pipes.
+ *
+ * The @p enable_mask parameter must contain the same number of pipes as has been configured
+ * with @ref nrf_esb_set_prefixes.
+ *
+ * @param enable_mask Bitfield mask to enable or disable pipes. Setting a bit to
+ * 0 disables the pipe. Setting a bit to 1 enables the pipe.
+ *
+ * @retval NRF_SUCCESS If the pipes were enabled and disabled successfully.
+ * @retval NRF_ERROR_BUSY If the function failed because the radio is busy.
+ * @retval NRF_ERROR_INVALID_PARAM If the function failed because the address given was too close to a zero address.
+ */
+uint32_t nrf_esb_enable_pipes(uint8_t enable_mask);
+
+
+/**@brief Function for updating the prefix for a pipe.
+ *
+ * @param pipe Pipe for which to set the prefix.
+ * @param prefix Prefix to set for the pipe.
+ *
+ * @retval NRF_SUCCESS If the operation completed successfully.
+ * @retval NRF_ERROR_BUSY If the function failed because the radio is busy.
+ * @retval NRF_ERROR_INVALID_PARAM If the given pipe number was invalid or if the address given was too close to a zero address.
+ */
+uint32_t nrf_esb_update_prefix(uint8_t pipe, uint8_t prefix);
+
+
+/** @brief Function for setting the channel to use for the radio.
+ *
+ * The module must be in an idle state to call this function. As a PTX, the
+ * application must wait for an idle state and as a PRX, the application must stop RX
+ * before changing the channel. After changing the channel, operation can be resumed.
+ *
+ * @param[in] channel Channel to use for radio.
+ *
+ * @retval NRF_SUCCESS If the operation completed successfully.
+ * @retval NRF_INVALID_STATE If the module is not initialized.
+ * @retval NRF_ERROR_BUSY If the module was not in idle state.
+ * @retval NRF_ERROR_INVALID_PARAM If the channel is invalid (larger than 100).
+ */
+uint32_t nrf_esb_set_rf_channel(uint32_t channel);
+
+
+/**@brief Function for getting the current radio channel.
+ *
+ * @param[in, out] p_channel Pointer to the channel data.
+ *
+ * @retval NRF_SUCCESS If the operation completed successfully.
+ * @retval NRF_ERROR_NULL If the required parameter was NULL.
+ */
+uint32_t nrf_esb_get_rf_channel(uint32_t * p_channel);
+
+
+/**@brief Function for setting the radio output power.
+ *
+ * @param[in] tx_output_power Output power.
+ *
+ * @retval NRF_SUCCESS If the operation completed successfully.
+ * @retval NRF_ERROR_BUSY If the function failed because the radio is busy.
+ */
+uint32_t nrf_esb_set_tx_power(nrf_esb_tx_power_t tx_output_power);
+
+
+/**@brief Function for setting the packet retransmit delay.
+ *
+ * @param[in] delay Delay between retransmissions.
+ *
+ * @retval NRF_SUCCESS If the operation completed successfully.
+ * @retval NRF_ERROR_BUSY If the function failed because the radio is busy.
+ */
+uint32_t nrf_esb_set_retransmit_delay(uint16_t delay);
+
+
+/**@brief Function for setting the number of retransmission attempts.
+ *
+ * @param[in] count Number of retransmissions.
+ *
+ * @retval NRF_SUCCESS If the operation completed successfully.
+ * @retval NRF_ERROR_BUSY If the function failed because the radio is busy.
+ */
+uint32_t nrf_esb_set_retransmit_count(uint16_t count);
+
+
+/**@brief Function for setting the radio bitrate.
+ *
+ * @param[in] bitrate Radio bitrate.
+ *
+ * @retval NRF_SUCCESS If the operation completed successfully.
+ * @retval NRF_ERROR_BUSY If the function failed because the radio is busy.
+ */
+uint32_t nrf_esb_set_bitrate(nrf_esb_bitrate_t bitrate);
+
+
+/**@brief Function for reusing a packet ID for a specific pipe.
+ *
+ * The ESB protocol uses a 2-bit sequence number (packet ID) to identify
+ * retransmitted packets. By default, the packet ID is incremented for every
+ * uploaded packet. Use this function to prevent this and send two different
+ * packets with the same packet ID.
+ *
+ * @param[in] pipe Pipe.
+ *
+ * @retval NRF_SUCCESS If the operation completed successfully.
+ * @retval NRF_ERROR_BUSY If the function failed because the radio is busy.
+ */
+uint32_t nrf_esb_reuse_pid(uint8_t pipe);
+
+/** @} */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // NRF_ESB
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/proprietary_rf/esb/nrf_esb_error_codes.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/proprietary_rf/esb/nrf_esb_error_codes.h
new file mode 100644
index 0000000..88b24ff
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/proprietary_rf/esb/nrf_esb_error_codes.h
@@ -0,0 +1,56 @@
+/**
+ * Copyright (c) 2016 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#ifndef __NRF_ESB_ERROR_CODES_H__
+#define __NRF_ESB_ERROR_CODES_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define NRF_ERROR_BUFFER_EMPTY (0x0100)
+
+#define NRF_ESB_ERROR_NOT_IN_RX_MODE (0x0101)
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/proprietary_rf/esb/nrf_esb_resources.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/proprietary_rf/esb/nrf_esb_resources.h
new file mode 100644
index 0000000..3e1af51
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/proprietary_rf/esb/nrf_esb_resources.h
@@ -0,0 +1,72 @@
+/**
+ * Copyright (c) 2016 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#ifndef NRF_ESB_RESOURCES_H__
+#define NRF_ESB_RESOURCES_H__
+
+#include <stdint.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @defgroup nrf_esb_resources ESB resources
+ * @{
+ * @ingroup nrf_esb
+ */
+
+#ifndef ESB_ALTERNATIVE_RESOURCES
+ #define ESB_PPI_CHANNELS_USED 0x00000007uL /**< PPI channels used by ESB (not available to the application). */
+ #define ESB_TIMERS_USED 0x00000004uL /**< Timers used by ESB. */
+ #define ESB_SWI_USED 0x00000001uL /**< Software interrupts used by ESB. */
+#else
+ #define ESB_PPI_CHANNELS_USED 0x00000700uL /**< PPI channels used by ESB (not available to the application). */
+ #define ESB_TIMERS_USED 0x00000001uL /**< Timers used by ESB. */
+ #define ESB_SWI_USED 0x00000002uL /**< Software interrupts used by ESB. */
+#endif
+
+/** @} */
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* NRF_ESB_RESOURCES_H__ */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/proprietary_rf/gzll/arm/gzll_nrf51_arm.lib b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/proprietary_rf/gzll/arm/gzll_nrf51_arm.lib
new file mode 100644
index 0000000..e0e9915
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/proprietary_rf/gzll/arm/gzll_nrf51_arm.lib
Binary files differ
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/proprietary_rf/gzll/arm/gzll_nrf51_sd_resources_arm.lib b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/proprietary_rf/gzll/arm/gzll_nrf51_sd_resources_arm.lib
new file mode 100644
index 0000000..aedb24e
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/proprietary_rf/gzll/arm/gzll_nrf51_sd_resources_arm.lib
Binary files differ
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/proprietary_rf/gzll/arm/gzll_nrf52840_arm.lib b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/proprietary_rf/gzll/arm/gzll_nrf52840_arm.lib
new file mode 100644
index 0000000..63503ab
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/proprietary_rf/gzll/arm/gzll_nrf52840_arm.lib
Binary files differ
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/proprietary_rf/gzll/arm/gzll_nrf52840_sd_resources_arm.lib b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/proprietary_rf/gzll/arm/gzll_nrf52840_sd_resources_arm.lib
new file mode 100644
index 0000000..25cb7d3
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/proprietary_rf/gzll/arm/gzll_nrf52840_sd_resources_arm.lib
Binary files differ
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/proprietary_rf/gzll/arm/gzll_nrf52_arm.lib b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/proprietary_rf/gzll/arm/gzll_nrf52_arm.lib
new file mode 100644
index 0000000..afd9a9b
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/proprietary_rf/gzll/arm/gzll_nrf52_arm.lib
Binary files differ
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/proprietary_rf/gzll/arm/gzll_nrf52_sd_resources_arm.lib b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/proprietary_rf/gzll/arm/gzll_nrf52_sd_resources_arm.lib
new file mode 100644
index 0000000..12596fc
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/proprietary_rf/gzll/arm/gzll_nrf52_sd_resources_arm.lib
Binary files differ
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/proprietary_rf/gzll/arm/license.txt b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/proprietary_rf/gzll/arm/license.txt
new file mode 100644
index 0000000..957d928
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/proprietary_rf/gzll/arm/license.txt
@@ -0,0 +1,37 @@
+Copyright (c) 2010 - 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, except as embedded into a Nordic
+ Semiconductor ASA integrated circuit in a product or a software update for
+ such product, 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.
+
+4. This software, with or without modification, must only be used with a
+ Nordic Semiconductor ASA integrated circuit.
+
+5. Any software provided in binary form under this license must not be reverse
+ engineered, decompiled, modified and/or disassembled.
+
+THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/proprietary_rf/gzll/config/nrf_gzp_config.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/proprietary_rf/gzll/config/nrf_gzp_config.h
new file mode 100644
index 0000000..801cc3f
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/proprietary_rf/gzll/config/nrf_gzp_config.h
@@ -0,0 +1,168 @@
+/**
+ * Copyright (c) 2008 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#ifndef __GZP_CONFIG_H
+#define __GZP_CONFIG_H
+
+#include "nrf.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+/**
+ * Definition of "secret key" used during "Host ID exchange".
+ */
+
+#define GZP_SECRET_KEY {1, 23, 45, 57, 26, 68, 12, 64, 13, 73, 13, 62, 26, 45, 12, 77}
+
+//-----------------------------------------------------------------------------
+
+/**
+ Definition of the first static selected pairing channel. Should be located in
+ the lower Nth of the channel range, where N is the size if the channel subset
+ selected by the application.
+*/
+#define GZP_CHANNEL_LOW 2
+
+/**
+ Definition of the second static selected pairing channel. Should be located in
+ the upper Nth of the channel range, where N is the size if the channel subset
+ selected by the application.
+*/
+#define GZP_CHANNEL_HIGH 79
+
+/**
+ Definition of the static "global" pairing address.
+*/
+#define GZP_ADDRESS 4, 6, 8, 10
+
+/**
+ Reduced TX power for use during close proximity pairing.
+ */
+#define GZP_POWER NRF_GZLL_TX_POWER_N16_DBM
+
+/**
+ Definition of pairing request timeout.
+*/
+#define GZP_REQ_TX_TIMEOUT 200
+
+/**
+ Definition of the maximimum number of "backoff" packets (step 0) to be transmitted.
+*/
+#define GZP_MAX_BACKOFF_PACKETS 100
+
+/**
+ Definition of the period a device shall wait before attempting to send the packet for
+ fetching the pairing response (step 1).
+*/
+#define GZP_TX_ACK_WAIT_TIMEOUT (GZP_CLOSE_PROXIMITY_BACKOFF_RX_TIMEOUT + 50)
+
+/**
+ Definition of the period a device in close proximity shall back off on the pairing
+ address after a backoff packet has been received.
+*/
+#define GZP_CLOSE_PROXIMITY_BACKOFF_RX_TIMEOUT ((GZP_REQ_TX_TIMEOUT / 2) + 50)
+
+/**
+ Definition of the period a device NOT in close proximity shall back off on the pairing
+ address after a backoff packet has been received.
+*/
+#define GZP_NOT_PROXIMITY_BACKOFF_RX_TIMEOUT (GZP_CLOSE_PROXIMITY_BACKOFF_RX_TIMEOUT + GZP_STEP1_RX_TIMEOUT)
+
+/**
+ Definition of the time the host waits for a device to complete
+ transmission of the pairing request step 1 packet.
+*/
+#define GZP_STEP1_RX_TIMEOUT (((GZP_REQ_TX_TIMEOUT / 2) + GZP_TX_ACK_WAIT_TIMEOUT) + 50)
+
+/**
+ Definition of the lowest boundary for the channel range to be used.
+*/
+#define GZP_CHANNEL_MIN 2
+
+/**
+ Definition of the upper boundary for the channel range to be used.
+*/
+#define GZP_CHANNEL_MAX 80
+
+/**
+ Definition of the minimum channel spacing for the channel subset generated
+ during pairing.
+*/
+#define GZP_CHANNEL_SPACING_MIN 5
+
+/**
+ Non volatile memory (Flash or OTP) storage address. A device will
+ require GZP_DEVICE_PARAMS_STORAGE_SIZE bytes of memory, and
+ Host 11 bytes. When using flash memory, storage address should
+ be a multiple of chip page size.
+*/
+#define GZP_PARAMS_STORAGE_ADR 0x00001000
+
+/**
+ Number of bytes available for parameter storage in Device.
+ It is equal to flash page size on nRF5x chips.
+*/
+#if defined (NRF51)
+ #define GZP_DEVICE_PARAMS_STORAGE_SIZE 1024
+#elif defined (NRF52_SERIES)
+ #define GZP_DEVICE_PARAMS_STORAGE_SIZE 4096
+#else
+ #error Chip type is undefined!
+#endif
+
+/**
+ Maximum Device TX payload length [bytes].
+ */
+#define GZP_MAX_FW_PAYLOAD_LENGTH 17
+
+/**
+ Maximum Host ACK payload length [bytes].
+ */
+#define GZP_MAX_ACK_PAYLOAD_LENGTH 10
+
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/proprietary_rf/gzll/gcc/gzll_nrf51_gcc.a b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/proprietary_rf/gzll/gcc/gzll_nrf51_gcc.a
new file mode 100644
index 0000000..8c9fe0a
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/proprietary_rf/gzll/gcc/gzll_nrf51_gcc.a
Binary files differ
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/proprietary_rf/gzll/gcc/gzll_nrf51_sd_resources_gcc.a b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/proprietary_rf/gzll/gcc/gzll_nrf51_sd_resources_gcc.a
new file mode 100644
index 0000000..4896b0c
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/proprietary_rf/gzll/gcc/gzll_nrf51_sd_resources_gcc.a
Binary files differ
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/proprietary_rf/gzll/gcc/gzll_nrf52840_gcc.a b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/proprietary_rf/gzll/gcc/gzll_nrf52840_gcc.a
new file mode 100644
index 0000000..911ae7d
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/proprietary_rf/gzll/gcc/gzll_nrf52840_gcc.a
Binary files differ
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/proprietary_rf/gzll/gcc/gzll_nrf52840_sd_resources_gcc.a b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/proprietary_rf/gzll/gcc/gzll_nrf52840_sd_resources_gcc.a
new file mode 100644
index 0000000..46284ef
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/proprietary_rf/gzll/gcc/gzll_nrf52840_sd_resources_gcc.a
Binary files differ
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/proprietary_rf/gzll/gcc/gzll_nrf52_gcc.a b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/proprietary_rf/gzll/gcc/gzll_nrf52_gcc.a
new file mode 100644
index 0000000..d463ca4
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/proprietary_rf/gzll/gcc/gzll_nrf52_gcc.a
Binary files differ
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/proprietary_rf/gzll/gcc/gzll_nrf52_sd_resources_gcc.a b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/proprietary_rf/gzll/gcc/gzll_nrf52_sd_resources_gcc.a
new file mode 100644
index 0000000..052634c
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/proprietary_rf/gzll/gcc/gzll_nrf52_sd_resources_gcc.a
Binary files differ
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/proprietary_rf/gzll/gcc/license.txt b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/proprietary_rf/gzll/gcc/license.txt
new file mode 100644
index 0000000..957d928
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/proprietary_rf/gzll/gcc/license.txt
@@ -0,0 +1,37 @@
+Copyright (c) 2010 - 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, except as embedded into a Nordic
+ Semiconductor ASA integrated circuit in a product or a software update for
+ such product, 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.
+
+4. This software, with or without modification, must only be used with a
+ Nordic Semiconductor ASA integrated circuit.
+
+5. Any software provided in binary form under this license must not be reverse
+ engineered, decompiled, modified and/or disassembled.
+
+THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/proprietary_rf/gzll/iar/gzll_nrf51_iar.a b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/proprietary_rf/gzll/iar/gzll_nrf51_iar.a
new file mode 100644
index 0000000..bf4ad39
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/proprietary_rf/gzll/iar/gzll_nrf51_iar.a
Binary files differ
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/proprietary_rf/gzll/iar/gzll_nrf51_sd_resources_iar.a b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/proprietary_rf/gzll/iar/gzll_nrf51_sd_resources_iar.a
new file mode 100644
index 0000000..23fcdd1
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/proprietary_rf/gzll/iar/gzll_nrf51_sd_resources_iar.a
Binary files differ
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/proprietary_rf/gzll/iar/gzll_nrf52840_iar.a b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/proprietary_rf/gzll/iar/gzll_nrf52840_iar.a
new file mode 100644
index 0000000..755dbfd
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/proprietary_rf/gzll/iar/gzll_nrf52840_iar.a
Binary files differ
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/proprietary_rf/gzll/iar/gzll_nrf52840_sd_resources_iar.a b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/proprietary_rf/gzll/iar/gzll_nrf52840_sd_resources_iar.a
new file mode 100644
index 0000000..b7971e6
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/proprietary_rf/gzll/iar/gzll_nrf52840_sd_resources_iar.a
Binary files differ
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/proprietary_rf/gzll/iar/gzll_nrf52_iar.a b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/proprietary_rf/gzll/iar/gzll_nrf52_iar.a
new file mode 100644
index 0000000..36e7653
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/proprietary_rf/gzll/iar/gzll_nrf52_iar.a
Binary files differ
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/proprietary_rf/gzll/iar/gzll_nrf52_sd_resources_iar.a b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/proprietary_rf/gzll/iar/gzll_nrf52_sd_resources_iar.a
new file mode 100644
index 0000000..d09ca0f
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/proprietary_rf/gzll/iar/gzll_nrf52_sd_resources_iar.a
Binary files differ
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/proprietary_rf/gzll/iar/license.txt b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/proprietary_rf/gzll/iar/license.txt
new file mode 100644
index 0000000..957d928
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/proprietary_rf/gzll/iar/license.txt
@@ -0,0 +1,37 @@
+Copyright (c) 2010 - 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, except as embedded into a Nordic
+ Semiconductor ASA integrated circuit in a product or a software update for
+ such product, 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.
+
+4. This software, with or without modification, must only be used with a
+ Nordic Semiconductor ASA integrated circuit.
+
+5. Any software provided in binary form under this license must not be reverse
+ engineered, decompiled, modified and/or disassembled.
+
+THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/proprietary_rf/gzll/nrf_gzll.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/proprietary_rf/gzll/nrf_gzll.h
new file mode 100644
index 0000000..79a9ee8
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/proprietary_rf/gzll/nrf_gzll.h
@@ -0,0 +1,937 @@
+/**
+ * Copyright (c) 2012 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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
+ * @brief Gazell Link Layer API.
+ */
+
+#ifndef NRF_GZLL_H__
+#define NRF_GZLL_H__
+
+#include <stdbool.h>
+#include "nrf.h"
+#include "nrf_gzll_constants.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+/**
+* @defgroup gzll_02_api Gazell Link Layer
+* @{
+* @ingroup modules_01_gzll
+* @brief Gazell Link Layer Application Programming Interface (API).
+*/
+
+/**
+ * @enum nrf_gzll_mode_t
+ * @brief Enumerator used for selecting Gazell mode.
+ */
+typedef enum
+{
+ NRF_GZLL_MODE_DEVICE, ///< Device mode
+ NRF_GZLL_MODE_HOST, ///< Host mode
+ NRF_GZLL_MODE_SUSPEND, ///< Suspend mode ("disabled with timer running")
+} nrf_gzll_mode_t;
+
+/**
+ * @enum nrf_gzll_device_channel_selection_policy_t
+ * @brief Enumerator used for selecting Gazell Device channel
+ * selection policy.
+ */
+typedef enum
+{
+ NRF_GZLL_DEVICE_CHANNEL_SELECTION_POLICY_USE_SUCCESSFUL, ///< Start on previous successful channel
+ NRF_GZLL_DEVICE_CHANNEL_SELECTION_POLICY_USE_CURRENT, ///< Start on channel currently monitored by Host
+} nrf_gzll_device_channel_selection_policy_t;
+
+/**
+ * @enum nrf_gzll_tx_power_t
+ * @brief Enumerator used for selecting the transmit (TX) power.
+ */
+typedef enum
+{
+ NRF_GZLL_TX_POWER_4_DBM, ///< 4 dBm transmit power.
+ NRF_GZLL_TX_POWER_0_DBM, ///< 0 dBm transmit power.
+ NRF_GZLL_TX_POWER_N4_DBM, ///< -4 dBm transmit power.
+ NRF_GZLL_TX_POWER_N8_DBM, ///< -8 dBm transmit power.
+ NRF_GZLL_TX_POWER_N12_DBM, ///< -12 dBm transmit power.
+ NRF_GZLL_TX_POWER_N16_DBM, ///< -16 dBm transmit power.
+ NRF_GZLL_TX_POWER_N20_DBM ///< -20 dBm transmit power.
+} nrf_gzll_tx_power_t;
+
+/**
+ * @enum nrf_gzll_datarate_t
+ * @brief Enumerator used for selecting the radio datarate.
+ */
+typedef enum
+{
+#ifdef NRF51
+ NRF_GZLL_DATARATE_250KBIT = 0, ///< 250 Kbps datarate, available only for the nRF51.
+#endif
+ NRF_GZLL_DATARATE_1MBIT = 1, ///< 1 Mbps datarate.
+ NRF_GZLL_DATARATE_2MBIT = 2 ///< 2 Mbps datarate.
+} nrf_gzll_datarate_t;
+
+/**
+ * @enum nrf_gzll_xosc_ctl_t
+ * @brief Enumerator used for specifying whether switching the
+ * external 16 MHz oscillator on/off shall be handled automatically
+ * inside Gazell or manually by the application.
+ */
+typedef enum
+{
+ NRF_GZLL_XOSC_CTL_AUTO, ///< Switch XOSC on/off automatically
+ NRF_GZLL_XOSC_CTL_MANUAL ///< Switch XOSC on/off manually
+} nrf_gzll_xosc_ctl_t;
+
+/**
+ * @enum nrf_gzll_error_code_t
+ * @brief Enumerator used for error codes for Gazell API functions
+ */
+typedef enum
+{
+ NRF_GZLL_ERROR_CODE_NO_ERROR = 0, ///< No error has been detected.
+ NRF_GZLL_ERROR_CODE_FAILED_TO_INITIALIZE = 1, ///< The function NRF_GZLL_init failed.
+ NRF_GZLL_ERROR_CODE_ATTEMPTED_TO_CONFIGURE_WHEN_ENABLED = 2, ///< A call to a configuration 'set' function was made while Gazell was enabled.
+ NRF_GZLL_ERROR_CODE_POINTER_IS_NULL = 3, ///< A null pointer was given as an input to a function.
+ NRF_GZLL_ERROR_CODE_INVALID_PIPE = 4, ///< An invalid pipe number was given as an input to a function.
+ NRF_GZLL_ERROR_CODE_INVALID_MODE = 5, ///< An invalid value for the nrf_gzll_mode_t enumerator was given as input to a function.
+ NRF_GZLL_ERROR_CODE_INVALID_PAYLOAD_LENGTH = 6, ///< An invalid payload length was given as an input to a function.
+ NRF_GZLL_ERROR_CODE_INVALID_CHANNEL_TABLE_SIZE = 7, ///< An invalid channel table size was given as an input to a function.
+ NRF_GZLL_ERROR_CODE_INSUFFICIENT_PACKETS_AVAILABLE = 8, ///< There are insufficient packets in the Gazell memory pool to successfully execute the operation.
+ NRF_GZLL_ERROR_CODE_ATTEMPTED_TO_ADD_TO_FULL_FIFO = 9, ///< There is insufficient space in the TX FIFO for the data packet.
+ NRF_GZLL_ERROR_CODE_NO_SPACE_IN_RX_FIFO_FOR_ACK = 10, ///< There is insufficient space in the RX FIFO for the ACK.
+ NRF_GZLL_ERROR_CODE_ATTEMPTED_TO_FETCH_FROM_EMPTY_FIFO = 11, ///< Attempted to fetch a packet from an empty FIFO. Use the functions nrf_gzll_get_tx_fifo_packet_count() or nrf_gzll_get_rx_fifo_packet_count()
+ NRF_GZLL_ERROR_CODE_ATTEMPTED_TO_FLUSH_WHEN_ENABLED = 12, ///< Attempted to fetch a packet from an empty FIFO. Use the functions nrf_gzll_get_tx_fifo_packet_count() or nrf_gzll_get_rx_fifo_packet_count()
+ NRF_GZLL_ERROR_CODE_INVALID_PARAMETER = 14, ///< Attempted to set a variable which was not valid.
+ NRF_GZLL_ERROR_CODE_INTERNAL_ASSERT_OCCURRED = 15, ///< An internal assert occurred.
+ NRF_GZLL_ERROR_CODE_CALLBACK_NOT_IMPLEMENTED = 16, ///< A callback was called but not implemented by the application.
+ NRF_GZLL_ERROR_CODE_INVALID_ADDRESS = 17, ///< Invalid pipe 0 address detected, see Anomaly 107 at nRF52832 errata document.
+ NRF_GZLL_ERROR_CODE_NUMBER_OF_ERROR_CODES = 18, ///< Number of possible error codes.
+} nrf_gzll_error_code_t;
+
+/**
+ * @struct nrf_gzll_device_tx_info_t;
+ * @brief Data structure containing information about the last packet
+ * transmission.
+ */
+typedef struct
+{
+ bool payload_received_in_ack; ///< A payload was received in the ACK.
+ uint16_t num_tx_attempts; ///< Number of attempts used on previous Device packet transmission.
+ uint16_t num_channel_switches; ///< Number of channel switches needed during previous packet transmission.
+ int8_t rssi; ///< Received signal strength indicator in dBm. @sa nrf_gzll_enable_rssi().
+ uint8_t rf_channel; ///< Channel on which packet has been transmitted.
+} nrf_gzll_device_tx_info_t;
+
+
+/**
+ * @struct nrf_gzll_host_rx_info_t;
+ * @brief Data structure containing information about the last packet
+ * received.
+ */
+typedef struct
+{
+ bool packet_removed_from_tx_fifo; ///< A payload was received in the ACK.
+ int8_t rssi; ///< Received signal strength indicator in dBm. @sa nrf_gzll_enable_rssi().
+ uint8_t rf_channel; ///< Channel on which packet has been received.
+} nrf_gzll_host_rx_info_t;
+
+
+typedef struct
+{
+ uint32_t packets_num; ///< Number of succesfully transmitted packets
+ uint32_t timeouts_num; ///< Total timeouts number
+ uint32_t channel_timeouts[NRF_GZLL_CONST_MAX_CHANNEL_TABLE_SIZE]; ///< Transmission timeouts per channel
+ uint32_t channel_packets[NRF_GZLL_CONST_MAX_CHANNEL_TABLE_SIZE]; ///< Succesfully transmitted packets per channel
+} nrf_gzll_tx_statistics_t;
+
+
+/**< Transmission timeout callback function definition */
+typedef void (*nrf_gzll_tx_timeout_callback)(uint32_t pipe, uint8_t rf_channel);
+
+
+/**< Transmission CRC failure callback function definition */
+typedef void (*nrf_gzll_crc_failure_callback)(uint32_t pipe, uint8_t rf_channel);
+
+
+#if defined(NRF52_SERIES) || defined(__SDK_DOXYGEN__)
+/**
+ * @brief Data structure holding external front
+ * end control configuration.
+ */
+typedef struct
+{
+ bool pa_enabled; ///< Flag indicating if PA control is enabled.
+ bool pa_active_high; ///< Flag indicating if PA is active in high input state.
+ uint8_t pa_gpio_pin; ///< Number of output pin used for PA control.
+ uint8_t pa_gpiote_channel; ///< Number of GPIOTE channel used for PA control.
+ bool lna_enabled; ///< Flag indicating if LNA control is enabled.
+ bool lna_active_high; ///< Flag indicating if LNA is active in high input state.
+ uint8_t lna_gpio_pin; ///< Number of output pin used for LNA control.
+ uint8_t lna_gpiote_channel; ///< Number of GPIOTE channel used for LNA control.
+ NRF_TIMER_Type * timer; ///< Pointer to the TIMER instance.
+ uint8_t ppi_channels[NRF_GZLL_PA_LNA_PPI_CHANNELS_NUM]; ///< PPI channels used to control front end.
+ uint8_t ramp_up_time; ///< Determines how early should the PA/LNA be turned one before RADIO activity. Should be less than @ref NRF_GZLL_PA_LNA_MAX_RAMP_UP_TIME.
+} nrf_gzll_pa_lna_cfg_t;
+#endif
+
+/******************************************************************************/
+/** @name General API functions
+ * @{ */
+/******************************************************************************/
+
+/**
+ * @brief Initialize Gazell.
+ *
+ * @param mode The mode to initialize Gazell in.
+ *
+ * @retval true if Gazell initialized.
+ * @retval false if Gazell failed to initialize.
+ */
+bool nrf_gzll_init(nrf_gzll_mode_t mode);
+
+/**
+ * @brief Enable Gazell.
+ *
+ * When enabled the behaviour described for the current Gazell Link Layer mode
+ * will apply.
+ *
+ * @retval false if nrf_gzll_init has not previously been called or invalid address
+ * has been set - see Anomaly 107 at nRF52832 errata document.
+ */
+bool nrf_gzll_enable(void);
+
+/**
+ * @brief Disable Gazell.
+ *
+ * When calling this function the Gazell Link Layer will begin disabling,
+ * and will be fully disabled when Gazell calls nrf_gzll_disabled().
+ * If there are any pending notifications, or if any new notifications are
+ * being added to the internal notification queue while Gazell is disabling,
+ * these will be sent to the application before Gazell is fully disabled.
+ *
+ * After Gazell has been fully disabled, no more notifications will be sent to
+ * the application.
+ */
+void nrf_gzll_disable(void);
+
+/** Check whether Gazell is enabled or disabled.
+ *
+ * @retval true If Gazell is enabled.
+ * @retval false If Gazell is disabled.
+ */
+bool nrf_gzll_is_enabled(void);
+
+/** @} */
+
+/******************************************************************************/
+/** @name Device mode callback functions
+ * @{ */
+/******************************************************************************/
+
+/**
+ * @brief ACK received callback (Device mode only).
+ *
+ * This callback is made when the Device receives an ACK (acknowledgement)
+ * packet.
+ * @sa nrf_gzll_ack_payload_received.
+ *
+ * @param pipe is the pipe on which an ACK packet was received.
+ * @param tx_info struct used to indicate whether a payload was received in the
+ * ack, as well as the number of TX attempts and channel switches required.
+ */
+void nrf_gzll_device_tx_success(uint32_t pipe, nrf_gzll_device_tx_info_t tx_info);
+
+/**
+ * @brief Transmission failed callback (Device mode only).
+ *
+ * This callback is made when a packet does not receive an ACK after
+ * nrf_gzll_max_retries is reached. The packet is deleted by Gazell.
+ *
+ * @param pipe is the pipe on which the transmission failed.
+ * @param tx_info struct used to indicate whether a payload was received
+ * in the ack, as well as RSSI and the number of TX attempts and
+ * channel switches required.
+ */
+void nrf_gzll_device_tx_failed(uint32_t pipe, nrf_gzll_device_tx_info_t tx_info);
+
+/** @} */
+
+/******************************************************************************/
+/** @name Host mode callback functions
+ * @{ */
+/******************************************************************************/
+
+/**
+ * @brief Data packet received callback (Host mode only).
+ *
+ * This callback is made when a Host receives a data packet from a Device.
+ *
+ * @param pipe is the pipe on which the data packet was received.
+ * @param rx_info struct used to indicate whether a payload was removed from the
+ * pipe's TX FIFO, as well as RSSI.
+ */
+void nrf_gzll_host_rx_data_ready(uint32_t pipe, nrf_gzll_host_rx_info_t rx_info);
+
+/** @} */
+
+/******************************************************************************/
+/** @name Callback functions for both Device and Host mode
+ * @{ */
+/******************************************************************************/
+
+/**
+ * @brief Disabled callback.
+ *
+ * This is called after Gazell enters the disabled state.
+ * There is no further CPU use by Gazell, the radio is disabled and the timer is
+ * powered down.
+ */
+void nrf_gzll_disabled(void);
+
+/**
+ * @brief Mode changed callbackl.
+ *
+ * This function is called after the Gazell mode has been changed.
+ * This function can only be called when Gazell is enabled.
+ */
+void nrf_gzll_mode_changed(void);
+
+/** @} */
+
+/******************************************************************************/
+/** @name Packet transmission and receiving functions
+ * @{ */
+/******************************************************************************/
+
+/**
+ * @brief Add a packet to the tail of the TX FIFO.
+ *
+ * In Device mode, the packet will be added.
+ * In Host mode, the payload will be piggybacked onto an ACK.
+ *
+ * @param pipe Pipe to which to add the payload. This value must be < NRF_GZLL_CONST_PIPE_COUNT.
+ * @param p_payload Pointer to the payload.
+ * @param length Number of bytes of the payload to transmit
+ * (0 to NRF_GZLL_CONST_MAX_PAYLOAD_LENGTH).
+ *
+ * @retval true if the packet was successfully added to the TX FIFO.
+ * @retval false if unsuccessful, check nrf_gzll_error_code_t for more information.
+ */
+bool nrf_gzll_add_packet_to_tx_fifo(uint32_t pipe, uint8_t * p_payload, uint32_t length);
+
+/**
+ * @brief Fetch a packet from the head of the RX FIFO.
+ *
+ * @param pipe Pipe from which to fetch the payload. This value must be < NRF_GZLL_CONST_PIPE_COUNT.
+ * @param p_payload Pointer to copy the payload to.
+ * @param p_length Length must be at least as large as the the number of bytes
+ * in the received payload length.
+ *
+ * @retval true If the fetch was successful.
+ * @retval false If unsuccessful, check nrf_gzll_error_code_t for more information.
+ */
+bool nrf_gzll_fetch_packet_from_rx_fifo(uint32_t pipe, uint8_t * p_payload, uint32_t * p_length);
+
+/**
+ * @brief Get the number of packets in the TX FIFO on a specific pipe.
+ *
+ * @param pipe The pipe for which to check. This value must be < NRF_GZLL_CONST_PIPE_COUNT.
+ *
+ * @retval >=0 The number of packets in the TX FIFO for the pipe.
+ * @retval -1 If the pipe number is invalid.
+ */
+int32_t nrf_gzll_get_tx_fifo_packet_count(uint32_t pipe);
+
+/**
+ * @brief Get the number of packets in the RX FIFO on a specific pipe.
+ *
+ * @param pipe The pipe for which to check. This value must be < NRF_GZLL_CONST_PIPE_COUNT.
+ * @retval >=0 The number of packets in the RX FIFO for the pipe.
+ * @retval -1 If the pipe number is invalid.
+ */
+int32_t nrf_gzll_get_rx_fifo_packet_count(uint32_t pipe);
+
+/**
+ * @brief Get the total number of packets residing in all TX and RX FIFOs.
+ *
+ * Can be used to check against NRF_GZLL_CONST_MAX_TOTAL_PACKETS to
+ * determine if there is free space in the memory pool for more packets.
+ *
+ * @return The number of packets residing in all TX and RX FIFOs.
+ */
+uint32_t nrf_gzll_get_total_allocated_packet_count(void);
+
+/**
+ * @brief Check if adding a packet to a pipe's TX FIFO should be successful.
+ *
+ * Checks if there is another space in the pipe's TX and RX FIFOs
+ * as well as enough overall space in the packet pool.
+ *
+ * @param pipe The pip for which to check. This value must be < NRF_GZLL_CONST_PIPE_COUNT.
+ *
+ * @retval true If there is another space.
+ * @retval false If there is not enough space, or the pipe is invalid.
+ */
+bool nrf_gzll_ok_to_add_packet_to_tx_fifo(uint32_t pipe);
+
+/**
+ * @brief Flush the RX FIFO for a specific pipe.
+ *
+ * Delete all the packets and free the memory of the TX FIFO for a
+ * specific pipe.
+ *
+ * Note that it is not allowed to flush a TX FIFO when
+ * Gazell is enabled.
+ *
+ * @param pipe is the pipe for which to flush. This value must be < NRF_GZLL_CONST_PIPE_COUNT.
+ * @retval true if the pipe was flushed.
+ * @retval false if the pipe was not flushed.
+ */
+bool nrf_gzll_flush_tx_fifo(uint32_t pipe);
+
+/**
+ * @brief Flush the RX FIFO for a specific pipe.
+ *
+ * Delete all the packets and free the memory of the RX FIFO for a
+ * specific pipe.
+ *
+ * @param pipe is the pipe for which to flush. This value must be < NRF_GZLL_CONST_PIPE_COUNT.
+ * @retval true if the pipe was flushed.
+ * @retval false if the pipe was not flushed.
+ */
+bool nrf_gzll_flush_rx_fifo(uint32_t pipe);
+
+/**
+ * @brief Function for enabling transmission statistics.
+ *
+ * @param p_statistics Pointer to the statistics structure.
+ *
+ * @return True if channel statistics has been enabled, false otherwise.
+ */
+bool nrf_gzll_tx_statistics_enable(nrf_gzll_tx_statistics_t * p_statistics);
+
+/**
+ * @brief Function for disabling transmission statistics.
+ */
+void nrf_gzll_tx_statistics_disable(void);
+
+/**
+ * @brief Function for obtaining number of transmission timeouts for specific channel.
+ *
+ * @param[in] channel_index Channel index in channel table.
+ * @param[out] p_timeouts Pointer for the result.
+ *
+ * @return True in case of success, false otherwise.
+ */
+bool nrf_gzll_get_channel_timeouts(uint8_t channel_index, uint32_t *p_timeouts);
+
+/**
+ * @brief Function for clearing transmission statistic structure.
+ */
+void nrf_gzll_reset_tx_statistics(void);
+
+/** @} */
+
+/******************************************************************************/
+/** @name Configuration functions
+ *
+ * Configuration 'set' functions may only be called while Gazell is disabled. The
+ * new parameter comes into effect when Gazell is enabled again.
+ *
+ * Configuration 'get' functions may be called at any time.
+ *
+ * @{ */
+/******************************************************************************/
+
+/**
+ * @brief Function for registering callback to be called on the transmission timeout.
+ */
+void nrf_gzll_tx_timeout_callback_register(nrf_gzll_tx_timeout_callback callback);
+
+
+/**
+ * @brief Function for registering callback to be called on the packet CRC failure.
+ */
+void nrf_gzll_crc_failure_callback_register(nrf_gzll_crc_failure_callback callback);
+
+
+/**
+ * @brief Set the mode.
+ *
+ * @param mode The mode to be used.
+ * See nrf_gzll_mode_t for a list of valid modes.
+ *
+ * It is allowed to change mode when Gazell is enabled. If the mode is
+ * being changed while Gazell is enabled, the mode will not change right away.
+ * In this case the callback function nrf_gzll_mode_changed() will be called
+ * after the mdoe has changed.
+ *
+ * @retval true If the parameter was set.
+ */
+bool nrf_gzll_set_mode(nrf_gzll_mode_t mode);
+
+/**
+ * @brief Get function counterpart to nrf_gzll_set_mode().
+ *
+ * @return The current mode.
+ */
+nrf_gzll_mode_t nrf_gzll_get_mode(void);
+
+/**
+ * @brief Set the base address for pipe 0.
+ *
+ * The full on-air address for each pipe is composed of a multi-byte base address
+ * prepended to a prefix byte.
+ *
+ * For packets to be received correctly, the most significant byte of
+ * the base address should not be an alternating sequence of 0s and 1s i.e.
+ * it should not be 0x55 or 0xAA.
+ *
+ * @param base_address The 4 byte base address. All bytes are used.
+ *
+ * @note Due to the nRF52 Anomaly 107, pipe 0 address should not have
+ * both prefix and two LSB of base address set to 0.
+ *
+ * @retval true If the parameter was set.
+ * @return false If Gazell was enabled.
+ */
+bool nrf_gzll_set_base_address_0(uint32_t base_address);
+
+/**
+ * @brief Get function counterpart to nrf_gzll_set_base_address_0().
+ *
+ * @return Base address 0.
+ */
+uint32_t nrf_gzll_get_base_address_0(void);
+
+/**
+ * @brief Set the base address for pipes 1-7.
+ *
+ * Pipes 1 through 7 share base_address_1. @sa nrf_gzll_set_base_address_0.
+ *
+ * @param base_address The 4 byte base address.
+ *
+ * @retval true If the parameter was set.
+ * @retval false If Gazell was enabled.
+ */
+bool nrf_gzll_set_base_address_1(uint32_t base_address);
+
+/**
+ * @brief Get function counterpart to nrf_gzll_set_base_address_1().
+ *
+ * @return Base address 1.
+ */
+uint32_t nrf_gzll_get_base_address_1(void);
+
+/**
+ * @brief Set the address prefix byte for a specific pipe.
+ *
+ * Each pipe should have its own unique prefix byte.
+ *
+ * @param pipe The pipe that the address should apply to.
+ * This value must be < NRF_GZLL_CONST_PIPE_COUNT.
+ * @param address_prefix_byte The address prefix byte.
+ *
+ * @note Due to the Anomaly 107, pipe 0 address should not have
+ * both prefix and two LSB of base address set to 0.
+ *
+ * @retval true If the parameter was set.
+ * @retval false If Gazell was enabled, or if the pipe was invalid.
+ */
+bool nrf_gzll_set_address_prefix_byte(uint32_t pipe, uint8_t address_prefix_byte);
+
+/**
+ * @brief Get function counterpart to nrf_gzll_set_address_prefix_byte().
+ *
+ * @param pipe The pipe for which to get the address.
+ * This value must be < NRF_GZLL_CONST_PIPE_COUNT.
+ * @param p_out_address_prefix_byte The pointer in which to return the
+ * address prefix byte.
+ *
+ * @retval true If the parameter was returned.
+ * @retval false If Gazell was enabled, the pipe was invalid or
+ * out_address was a NULL pointer.
+ */
+bool nrf_gzll_get_address_prefix_byte(uint32_t pipe, uint8_t * p_out_address_prefix_byte);
+
+/**
+ * @brief Set which pipes shall listen for packets in Host mode.
+ *
+ * This value is a bitmap, and each bit corresponds to a given pipe number.
+ * Bit 0 set to "1" enables pipes 0, bit 1 set to "1" enables pipe 1
+ * and so forth.
+ * The maximum number of pipes is defined by NRF_GZLL_CONST_PIPE_COUNT.
+ *
+ * @param pipes A bitmap specifying which pipes to monitor.
+ *
+ * @retval true If the parameter was set.
+ * @retval false If Gazell was enabled.
+ */
+bool nrf_gzll_set_rx_pipes_enabled(uint32_t pipes);
+
+/**
+ * @brief Get function counterpart to nrf_gzll_set_rx_pipes_enabled().
+ *
+ * @return Bitmap holding the current enabled pipes.
+ */
+uint32_t nrf_gzll_get_rx_pipes_enabled(void);
+
+/**
+ * @brief Set the timeslot period.
+ *
+ * The length in microseconds of a Gazell link layer timeslot.
+ *
+ * The minimum value of the timeslot period is dependent of the
+ * radio data rate (@sa nrf_gzll_set_datarate()).
+ *
+ * - For NRF_GZLL_DATARATE_2MBIT the timeslot period must be >= 600 us.
+ * - For NRF_GZLL_DATARATE_1MBIT the timeslot period must be >= 900 us.
+ * - For NRF_GZLL_DATARATE_250KBIT the timeslot period must be >= 2700 us.
+ *
+ * @param period_us The timeslot period in microseconds.
+ *
+ * @retval true If the parameter was set.
+ * @retval false If Gazell was enabled.
+ */
+bool nrf_gzll_set_timeslot_period(uint32_t period_us);
+
+/**
+ * @brief Get function counterpart to nrf_gzll_get_timeslot_period().
+ *
+ * @return The current timeslot period.
+ */
+uint32_t nrf_gzll_get_timeslot_period(void);
+
+/**
+ * @brief Set the Device channel selection policy
+ *
+ * The policy determines the initial channel when starting a new packet.
+ * transmission.
+ *
+ * @param policy The channel selection policy.
+ *
+ * @arg NRF_GZLL_DEVICE_CHANNEL_SELECTION_POLICY_USE_SUCCESSFUL specifies
+ * that a new packet transmission always shall use the previous
+ * successful channel from the channel table. If Gazell is "in sync", Gazell
+ * will wait until this channel is being monitored by the Host before starting
+ * the transmission.
+ *
+ * @arg NRF_GZLL_DEVICE_CHANNEL_SELECTION_POLICY_USE_CURRENT specifies that
+ * Gazell shall transmit on the channel that is currently being monitored by the
+ * Host. This parameter is only used when Gazell is "in sync". When "out of" sync,
+ * Gazell will always start using the "previous successful" channel.
+ *
+ * @retval true If the parameter was set.
+ * @retval false If Gazell was enabled or the policy was invalid.
+ */
+bool nrf_gzll_set_device_channel_selection_policy(nrf_gzll_device_channel_selection_policy_t policy);
+
+/**
+ * @brief Get function counterpart to nrf_gzll_set_device_channel_selection_policy().
+ *
+ * @return the Device channel selection policy.
+ */
+nrf_gzll_device_channel_selection_policy_t nrf_gzll_get_device_channel_selection_policy(void);
+
+/**
+ * @brief Set the number of timeslots that Gazell shall
+ * reside on a single channel before switching to another channel.
+ *
+ * This parameter applies in Host mode and for a Device that is
+ * in the "in sync" state.
+ *
+ * Since the Device and Host can not be in perfect synchronization, a
+ * transmission should overlap to adjacent timeslots on the Host.
+ * Therefore this value should be at least 2.
+ *
+ * @sa nrf_gzll_set_timeslots_per_channel_when_device_out_of_sync
+ *
+ * @param timeslots The number of timeslots to reside on
+ * each channel before channel switch.
+ *
+ * @retval true If the parameter was set.
+ * @retval false If Gazell was enabled.
+ */
+bool nrf_gzll_set_timeslots_per_channel(uint32_t timeslots);
+
+/**
+ * @brief Get function counterpart to nrf_gzll_set_timeslots_per_channel().
+ *
+ * @return The current number of timeslots.
+ */
+uint32_t nrf_gzll_get_timeslots_per_channel(void);
+
+/**
+ * @brief Set the number of timeslots that a Gazell shall
+ * reside on a single channel before switching to another channel when
+ * in the "out of sync" state.
+ *
+ * This value should be set so that the Device transmits on one channel
+ * while the Host goes through a full channel rotation, i.e.,
+ * channel_table_size*timeslots_per_channel.
+ * This ensures that the channels on the Device and Host will coincide
+ * at some point.
+ * Further increasing the value has been observed to provide better performance
+ * in the presence of interferers.
+ *
+ * @param timeslots The number of timeslots to reside on
+ * each channel before channel switch.
+ *
+ * @retval true If the parameter was set.
+ * @retval false If Gazell was enabled.
+ */
+bool nrf_gzll_set_timeslots_per_channel_when_device_out_of_sync(uint32_t timeslots);
+
+/**
+ * @brief Get function counterpart to
+ * nrf_gzll_set_timeslots_per_channel_when_device_out_of_sync().
+ *
+ * @return The current number of timeslots.
+ */
+uint32_t nrf_gzll_get_timeslots_per_channel_when_device_out_of_sync(void);
+
+/**
+ * @brief Set the number of timeslots after a successful
+ * reception of a Device or Host packet that the Gazell Link Layer shall assume
+ * that the link is synchronized. A value of 0 implies that the
+ * link is always out of sync.
+ *
+ * @param lifetime The sync lifetime in number of timeslots.
+ *
+ * @retval true If the sync lifetime was set.
+ * @retval false If Gazell was enabled.
+ */
+bool nrf_gzll_set_sync_lifetime(uint32_t lifetime);
+
+/**
+ * @brief Get function counterpart to nrf_gzll_set_sync_lifetime().
+ *
+ * @return The sync lifetime measured in number of timeslots.
+ */
+uint32_t nrf_gzll_get_sync_lifetime(void);
+
+/**
+ * @brief Set the maximum number of TX attempts
+ * that can be used for a single packet.
+ *
+ * After the maximum number of attempts have been spent without
+ * receiving any ACK from the Host, the transmission will be terminated
+ * and the nrf_gzll_device_tx_failed() callback will be called. A zero
+ * value of the function parameter implies the infinite number of TX attempts.
+ *
+ * @param max_tx_attempts The maximum number of TX attempts.
+ */
+void nrf_gzll_set_max_tx_attempts(uint16_t max_tx_attempts);
+
+/**
+ * @brief Get function counterpart to nrf_gzll_set_max_tx_attempts().
+ *
+ * @return The current max Device TX attempts.
+ */
+uint16_t nrf_gzll_get_max_tx_attempts(void);
+
+/**
+ * @brief Set the table of Radio Frequency (RF) channels.
+ *
+ * The valid channels are in the range 0 <= channel <= 125, where the
+ * actual centre frequency is (2400 + channel) MHz.
+ * The maximum channel table size is defined by
+ * NRF_GZLL_CONST_MAX_CHANNEL_TABLE_SIZE.
+ *
+ * @param p_channel_table Pointer to the channel table.
+ * @param size The size of the channel table.
+ *
+ * @retval true If the channel table was set.
+ * @retval false If Gazell was enabled, or the channel_table pointer was NULL,
+ * or the size was invalid.
+ */
+bool nrf_gzll_set_channel_table(uint8_t * p_channel_table, uint32_t size);
+
+/**
+ * @brief Get the table of Radio Frequency (RF) channels.
+ *
+ * @param p_channel_table Pointer to copy the channel table to.
+ * @param p_size Pointer to copy the size of the channel table to.
+ * The value already at size must be at least the size
+ * of the channel table.
+ *
+ * @retval true If the channel table was copied to channel_table.
+ * @retval false If the channel_table pointer was NULL,
+ * or the size was not large enough.
+ */
+bool nrf_gzll_get_channel_table(uint8_t * p_channel_table, uint32_t * p_size);
+
+/**
+ * @brief Get the current channel table size.
+ *
+ * @return The current channel table size.
+ */
+uint32_t nrf_gzll_get_channel_table_size(void);
+
+/**
+ * @brief Set the radio TX power.
+ *
+ * @param tx_power TX power.
+ *
+ * @retval true If the parameter was set.
+ * @retval false If the TX power was invalid.
+*/
+bool nrf_gzll_set_tx_power(nrf_gzll_tx_power_t tx_power);
+
+/**
+ * @brief Get function counterpart to nrf_gzll_set_tx_power().
+ *
+ * @return The current TX power.
+ */
+nrf_gzll_tx_power_t nrf_gzll_get_tx_power(void);
+
+/**
+ * @brief Set the radio datarate.
+ *
+ * @param data_rate Datarate.
+ *
+ * @retval true If the parameter was set.
+ * @retval false If Gazell was enabled or the datarate was invalid.
+ */
+bool nrf_gzll_set_datarate(nrf_gzll_datarate_t data_rate);
+
+/**
+ * @brief Get function counterpart to nrf_gzll_set_datarate().
+ *
+ * @return The current datarate.
+ */
+nrf_gzll_datarate_t nrf_gzll_get_datarate(void);
+
+/**
+ * @brief Set whether start/stop of external oscillator (XOSC) shall be handled
+ * automatically inside Gazell or manually by the application.
+ *
+ * When controlling the XOSC manually from the application it is
+ * required that the XOSC is started before Gazell is enabled.
+ *
+ * When start/stop of the XOSC is handled automatically by Gazell,
+ * the XOSC will only be running when needed, that is when the radio
+ * is being used or when Gazell needs to maintain synchronization.
+ *
+ * It is required that the XOSC is started in order for the radio to be
+ * able to send or receive any packets.
+ *
+ * @param xosc_ctl setting for XOSC control.
+ *
+ * @retval true if the parameter was set.
+ * @retval false if Gazell was enabled or the xosc_ctl value was invalid.
+ */
+bool nrf_gzll_set_xosc_ctl(nrf_gzll_xosc_ctl_t xosc_ctl);
+
+/**
+ * Get function counterpart for nrf_gzll_set_xosc_ctl();
+ *
+ * @return The XOSC control setting.
+ */
+nrf_gzll_xosc_ctl_t nrf_gzll_get_xosc_ctl(void);
+
+/**
+ * @brief Set Gazell to disable automatically after a certain number of timeslot ticks.
+ *
+ * @param num_ticks Number of timeslot ticks.
+ *
+ */
+void nrf_gzll_set_auto_disable(uint32_t num_ticks);
+
+#if defined(NRF52_SERIES) || defined(__SDK_DOXYGEN__)
+/**
+ * @brief Set up external front end control.
+ *
+ * @param p_pa_lna_cfg Pointer to the configuration struct.
+ */
+bool nrf_gzll_set_pa_lna_cfg(nrf_gzll_pa_lna_cfg_t const * p_pa_lna_cfg);
+#endif
+
+/**
+ * @brief Get the number of timeslot ticks that have occurred since
+ * nrf_gzll_init() was called.
+ *
+ * @return Number of timeslot ticks.
+ *
+ */
+uint32_t nrf_gzll_get_tick_count(void);
+
+/**
+ * @brief Clear the internal timeslot tick count variable that is read
+ * by nrf_gzll_get_tick_count().
+ *
+ */
+void nrf_gzll_clear_tick_count(void);
+
+/** @} */
+
+/******************************************************************************/
+/** @name Error handling functions
+ * @{ */
+/******************************************************************************/
+
+/**
+ * @brief Gets the Gazell error code.
+ *
+ * @return The current error code.
+ */
+nrf_gzll_error_code_t nrf_gzll_get_error_code(void);
+
+
+/**
+ * @brief Reset the Gazell error code.
+ *
+ * The error code is reset to NRF_GZLL_ERROR_CODE_NO_ERRROR.
+ */
+void nrf_gzll_reset_error_code(void);
+
+/** @} */
+
+/** @} */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/proprietary_rf/gzll/nrf_gzll_constants.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/proprietary_rf/gzll/nrf_gzll_constants.h
new file mode 100644
index 0000000..80df7c1
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/proprietary_rf/gzll/nrf_gzll_constants.h
@@ -0,0 +1,188 @@
+/**
+ * Copyright (c) 2011 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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
+ * @brief Gazell Link Layer constants and default values.
+ *
+ * NOTE! Changing values here has no effect. They are only provided as a reference.
+ */
+
+#ifndef NRF_GZLL_CONSTANTS_H__
+#define NRF_GZLL_CONSTANTS_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+/**
+ * @addtogroup gzll_02_api
+ * @{
+ */
+
+
+/*****************************************************************************/
+/** @name Hardware resources used by Gazell */
+/*****************************************************************************/
+#define NRF_GZLL_HIGH_IRQ_PRIORITY 0 ///< Interrupt priority the Gazell timer and the radio
+#define NRF_GZLL_LOW_IRQ_PRIORITY 1 ///< Interrupt priority for Gazell callback functions.
+
+#ifndef USE_SD_HW_RESOURCES
+
+#define NRF_GZLL_SWI_IRQn SWI0_IRQn ///< Software interrupt # used for callback functions.
+#define NRF_GZLL_SWI_IRQ_HANDLER SWI0_IRQHandler ///< Software interrupt handler used for callback functions.
+#define NRF_GZLL_TIMER NRF_TIMER2 ///< Timer to be used as flywheel timer.
+#define NRF_GZLL_TIMER_IRQn TIMER2_IRQn ///< Interrupt # for the timer.
+#define NRF_GZLL_TIMER_IRQ_HANDLER TIMER2_IRQHandler ///< Interrupt handler for the timer.
+
+// In addition, Gazell uses the radio peripheral and radio interrupts.
+
+/*
+ * PPI configuration
+ */
+#define NRF_GZLL_PPI_EEP0 (NRF_PPI->CH0_EEP) ///< Gazell PPI event endpoint 0
+#define NRF_GZLL_PPI_TEP0 (NRF_PPI->CH0_TEP) ///< Gazell PPI task endpoint 0
+#define NRF_GZLL_PPI_EEP1 (NRF_PPI->CH1_EEP) ///< Gazell PPI event endpoint 1
+#define NRF_GZLL_PPI_TEP1 (NRF_PPI->CH1_TEP) ///< Gazell PPI task endpoint 1
+#define NRF_GZLL_PPI_EEP2 (NRF_PPI->CH2_EEP) ///< Gazell PPI event endpoint 2
+#define NRF_GZLL_PPI_TEP2 (NRF_PPI->CH2_TEP) ///< Gazell PPI task endpoint 2
+
+#define NRF_GZLL_PPI_CHEN_MSK_0_AND_1 (0x03) ///< Channel enable/disable mask for PPI endpoint 0 and 1.
+#define NRF_GZLL_PPI_CHEN_MSK_2 (0x04) ///< Channel enable/disable mask for PPI endpoint 2.
+
+#else
+
+#define NRF_GZLL_SWI_IRQn SWI1_IRQn ///< Software interrupt # used for callback functions.
+#define NRF_GZLL_SWI_IRQ_HANDLER SWI1_IRQHandler ///< Software interrupt handler used for callback functions.
+#define NRF_GZLL_TIMER NRF_TIMER0 ///< Timer to be used as flywheel timer.
+#define NRF_GZLL_TIMER_PERPOWER_Msk POWER_PERPOWER_TIMER0_Msk ///< PERPOWER mask for the timer.
+#define NRF_GZLL_TIMER_IRQn TIMER0_IRQn ///< Interrupt # for the timer.
+#define NRF_GZLL_TIMER_IRQ_HANDLER TIMER0_IRQHandler ///< Interrupt handler for the timer.
+
+// In addition, Gazell uses the radio peripheral and radio interrupts.
+
+/*
+ * PPI configuration
+ */
+#define NRF_GZLL_PPI_EEP0 (NRF_PPI->CH8_EEP) ///< Gazell PPI event endpoint 0
+#define NRF_GZLL_PPI_TEP0 (NRF_PPI->CH8_TEP) ///< Gazell PPI task endpoint 0
+#define NRF_GZLL_PPI_EEP1 (NRF_PPI->CH9_EEP) ///< Gazell PPI event endpoint 1
+#define NRF_GZLL_PPI_TEP1 (NRF_PPI->CH9_TEP) ///< Gazell PPI task endpoint 1
+#define NRF_GZLL_PPI_EEP2 (NRF_PPI->CH10_EEP) ///< Gazell PPI event endpoint 2
+#define NRF_GZLL_PPI_TEP2 (NRF_PPI->CH10_TEP) ///< Gazell PPI task endpoint 2
+
+#define NRF_GZLL_PPI_CHEN_MSK_0_AND_1 (0x300) ///< Channel enable/disable mask for PPI endpoint 0 and 1.
+#define NRF_GZLL_PPI_CHEN_MSK_2 (0x400) ///< Channel enable/disable mask for PPI endpoint 2.
+
+#endif
+/** @} */
+
+/*****************************************************************************/
+/** @name Constant pipe and FIFO configuration */
+/*****************************************************************************/
+#define NRF_GZLL_CONST_PIPE_COUNT 8 ///< Number of TX pipes (at least one for each Device-Host pairs).
+#define NRF_GZLL_CONST_FIFO_LENGTH 3 ///< Maximum number of packets allowed in a TX or RX FIFO.
+#define NRF_GZLL_CONST_MAX_TOTAL_PACKETS 6 ///< Maximum number of packets available for reservation at any one time.
+#define NRF_GZLL_CONST_MAX_PAYLOAD_LENGTH 32 ///< Maximum allowed payload length in bytes.
+#define NRF_GZLL_CONST_CALLBACK_QUEUE_LENGTH 10 ///< Maximum number of notifications allowed in the callback queue.
+/** @} */
+
+/*****************************************************************************/
+/** @name Default radio configuration */
+/*****************************************************************************/
+#define NRF_GZLL_DEFAULT_TX_POWER NRF_GZLL_TX_POWER_0_DBM ///< Default TX power.
+#define NRF_GZLL_DEFAULT_DATARATE NRF_GZLL_DATARATE_2MBIT ///< Default data rate.
+
+#define NRF_GZLL_DEFAULT_CHANNEL_TABLE {4, 25, 42, 63, 77} ///< Default channel table.
+#define NRF_GZLL_DEFAULT_CHANNEL_TABLE_SIZE 5 ///< Default channel table size.
+#define NRF_GZLL_CONST_MAX_CHANNEL_TABLE_SIZE 16 ///< Maximum channel table size allowed by Gazell.
+/** @} */
+
+/*****************************************************************************/
+/** @name Default Address configuration */
+/*****************************************************************************/
+
+/*
+Corresponds to Legacy nRFgo SDK Gazell config:
+#define GZLL_DEFAULT_ADDRESS_PIPE0 {0x01, 0x04, 0x07, 0x0A, 0x0D}
+#define GZLL_DEFAULT_ADDRESS_PIPE1 {0x02, 0x05, 0x08, 0x0B, 0x0E}
+#define GZLL_DEFAULT_ADDRESS_PIPE2 3
+#define GZLL_DEFAULT_ADDRESS_PIPE3 4
+#define GZLL_DEFAULT_ADDRESS_PIPE4 5
+#define GZLL_DEFAULT_ADDRESS_PIPE5 6
+*/
+
+#define NRF_GZLL_DEFAULT_FULL_ADDRESS_PIPE0 {0x01, 0x04, 0x07, 0x0A, 0x0D} ///< Corresponding legacy Gazell pipe 0 address.
+#define NRF_GZLL_DEFAULT_BASE_ADDRESS_0 0x0D0A0704 ///< Default base address 0.
+#define NRF_GZLL_DEFAULT_BASE_ADDRESS_1 0x0E0B0805 ///< Default base address 1.
+#define NRF_GZLL_DEFAULT_PREFIX_BYTE_0 1 ///< Default prefix address pipe 0.
+#define NRF_GZLL_DEFAULT_PREFIX_BYTE_1 2 ///< Default prefix address pipe 1.
+#define NRF_GZLL_DEFAULT_PREFIX_BYTE_2 3 ///< Default prefix address pipe 2.
+#define NRF_GZLL_DEFAULT_PREFIX_BYTE_3 4 ///< Default prefix address pipe 3.
+#define NRF_GZLL_DEFAULT_PREFIX_BYTE_4 5 ///< Default prefix address pipe 4.
+#define NRF_GZLL_DEFAULT_PREFIX_BYTE_5 6 ///< Default prefix address pipe 5.
+#define NRF_GZLL_DEFAULT_PREFIX_BYTE_6 7 ///< Default prefix address pipe 6.
+#define NRF_GZLL_DEFAULT_PREFIX_BYTE_7 8 ///< Default prefix address pipe 7.
+#define NRF_GZLL_DEFAULT_BASE_ADDRESS_LENGTH NRF_GZLL_BASE_ADDRESS_LENGTH_4B ///< Default on-air base address length.
+#define NRF_GZLL_DEFAULT_RX_PIPES_ENABLED 0x000000FF ///< Enabled Rx pipes. See nrf_gzll_set_rx_pipes_enabled().
+/** @} */
+
+/*****************************************************************************/
+/** @name Default timeslot and synchronization configuration */
+/*****************************************************************************/
+#define NRF_GZLL_DEFAULT_TIMESLOT_PERIOD 600 ///< Default timeslot period.
+#define NRF_GZLL_DEFAULT_TIMESLOTS_PER_CHANNEL 2 ///< Timeslots use by the Host and by the Device when communication is in sync.
+#define NRF_GZLL_DEFAULT_DEVICE_CHANNEL_SELECTION_POLICY NRF_GZLL_DEVICE_CHANNEL_SELECTION_POLICY_USE_SUCCESSFUL ///< Default channel Gazell Device channel selection policy
+#define NRF_GZLL_DEFAULT_MAX_TX_ATTEMPTS 0 ///< Default maximum TX attempts for each packet. A value of zero implies the infinite number of TX attempts.
+#define NRF_GZLL_DEFAULT_XOSC_CTL NRF_GZLL_XOSC_CTL_AUTO ///< Deafult setting for controlling the XOSC
+#define NRF_GZLL_DEFAULT_TIMESLOTS_PER_CHANNEL_WHEN_DEVICE_OUT_OF_SYNC 15 ///< Timeslots use by the Device before communication is in sync.
+#define NRF_GZLL_DEFAULT_SYNC_LIFETIME (3 * NRF_GZLL_DEFAULT_CHANNEL_TABLE_SIZE * NRF_GZLL_DEFAULT_TIMESLOTS_PER_CHANNEL) ///< Number of timeslots to keep the timer running so that communication remains synchronized.
+/** @} */
+
+#define NRF_GZLL_PA_LNA_MAX_RAMP_UP_TIME 129 ///< Max external front end ramp up time [us].
+#define NRF_GZLL_PA_LNA_PPI_CHANNELS_NUM 4 ///< Number of PPI channels used for front end control.
+
+/** @} */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/proprietary_rf/gzll/nrf_gzll_error.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/proprietary_rf/gzll/nrf_gzll_error.h
new file mode 100644
index 0000000..6806a1b
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/proprietary_rf/gzll/nrf_gzll_error.h
@@ -0,0 +1,72 @@
+/**
+ * Copyright (c) 2016 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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
+ * @brief Gazell error API.
+ */
+
+#ifndef NRF_GZLL_ERROR_H__
+#define NRF_GZLL_ERROR_H__
+
+#include "sdk_errors.h"
+#include "nrf_gzll.h"
+#include "app_error.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define GAZELLE_ERROR_CODE_CHECK(GZLL_RESULT) \
+ do \
+ { \
+ if ((GZLL_RESULT) == false) \
+ { \
+ nrf_gzll_error_code_t gzll_error_code = nrf_gzll_get_error_code(); \
+ ret_code_t error_code = gzll_error_code + NRF_ERROR_GAZELLE_ERR_BASE; \
+ APP_ERROR_HANDLER(error_code); \
+ } \
+ } while (0)
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/proprietary_rf/gzll/nrf_gzll_resources.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/proprietary_rf/gzll/nrf_gzll_resources.h
new file mode 100644
index 0000000..f419b6a
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/proprietary_rf/gzll/nrf_gzll_resources.h
@@ -0,0 +1,66 @@
+/**
+ * Copyright (c) 2015 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#ifndef NRF_GZLL_RESOURCES_H__
+#define NRF_GZLL_RESOURCES_H__
+
+#include <stdint.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifndef GAZELL_ALTERNATIVE_RESOURCES
+ #define GZLL_PPI_CHANNELS_USED 0x00000007uL /**< PPI channels utilized by Gazell (not available to th spplication). */
+ #define GZLL_TIMERS_USED 0x00000004uL /**< Timers used by Gazell. */
+ #define GZLL_SWI_USED 0x00000001uL /**< Software interrupts used by Gazell */
+#else
+ #define GZLL_PPI_CHANNELS_USED 0x00000700uL /**< PPI channels utilized by Gazell (not available to th spplication). */
+ #define GZLL_TIMERS_USED 0x00000001uL /**< Timers used by Gazell. */
+ #define GZLL_SWI_USED 0x00000002uL /**< Software interrupts used by Gazell */
+#endif
+
+
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* NRF_GZLL_RESOURCES_H__ */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/proprietary_rf/gzll/nrf_gzp.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/proprietary_rf/gzll/nrf_gzp.c
new file mode 100644
index 0000000..07e0488
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/proprietary_rf/gzll/nrf_gzp.c
@@ -0,0 +1,363 @@
+/**
+ * Copyright (c) 2009 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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
+ * @brief Implementation of Gazell Pairing Library (gzp), Common functions.
+ * @defgroup gzp_source_common Gazell Pairing common functions implementation
+ * @{
+ * @ingroup gzp_04_source
+ */
+
+
+#include "nrf_gzp.h"
+#include "nrf_gzll.h"
+#include "nrf_ecb.h"
+#include <string.h>
+
+
+#define SOURCE_FILE NRF_SOURCE_FILE_GZP ///< File identifer for asserts.
+
+
+/******************************************************************************/
+/** @name Global variables
+ * @{ */
+/******************************************************************************/
+
+/**
+ * Constant holding base address part of the pairing address.
+ */
+static const uint8_t pairing_base_address[4] = { GZP_ADDRESS };
+
+/**
+ * Constant holding prefix byte of the pairing address.
+ */
+static const uint8_t pairing_address_prefix_byte = 0;
+
+/**
+ * Constant holding pre-defined "validation ID".
+ */
+static const uint8_t gzp_validation_id[GZP_VALIDATION_ID_LENGTH] = GZP_VALIDATION_ID;
+
+/**
+ * Constant holding pre-defined "secret key".
+ */
+static const uint8_t gzp_secret_key[16] = GZP_SECRET_KEY;
+
+/**
+ * Variable used for AES key selection
+ */
+static gzp_key_select_t gzp_key_select;
+
+
+/** @} */
+
+
+/******************************************************************************/
+/** @name Misc. external variables.
+ * @{ */
+/******************************************************************************/
+static uint8_t gzp_session_token[GZP_SESSION_TOKEN_LENGTH];
+static uint8_t gzp_dyn_key[GZP_DYN_KEY_LENGTH];
+
+/** @} */
+
+/******************************************************************************/
+/** @name Implementation common internal GZP functions
+ * @{ */
+/******************************************************************************/
+bool gzp_update_radio_params(const uint8_t* system_address)
+{
+ uint8_t i;
+ uint8_t channels[NRF_GZLL_CONST_MAX_CHANNEL_TABLE_SIZE];
+ uint32_t channel_table_size;
+ uint32_t pairing_base_address_32, system_address_32;
+ bool update_ok = true;
+ bool gzll_enabled_state;
+
+ gzll_enabled_state = nrf_gzll_is_enabled();
+
+ // Configure "global" pairing address
+ pairing_base_address_32 = (pairing_base_address[0]) +
+ ((uint32_t)pairing_base_address[1] << 8) +
+ ((uint32_t)pairing_base_address[2] << 16) +
+ ((uint32_t)pairing_base_address[3] << 24) ;
+ if (system_address != NULL)
+ {
+ system_address_32 = (system_address[0]) +
+ ((uint32_t)system_address[1] << 8) +
+ ((uint32_t)system_address[2] << 16) +
+ ((uint32_t)system_address[3] << 24) ;
+ }
+ else
+ {
+ return false;
+ }
+
+ nrf_gzp_disable_gzll();
+ update_ok = update_ok && nrf_gzll_set_base_address_0(pairing_base_address_32);
+ update_ok = update_ok && nrf_gzll_set_address_prefix_byte(GZP_PAIRING_PIPE, pairing_address_prefix_byte);
+ update_ok = update_ok && nrf_gzll_set_base_address_1(system_address_32);
+
+ // Configure address for pipe 1 - 5. Address byte set to equal pipe number.
+ for (i = 1; i < NRF_GZLL_CONST_PIPE_COUNT; i++)
+ {
+ update_ok = update_ok && nrf_gzll_set_address_prefix_byte(i,i);
+ }
+
+ channel_table_size = nrf_gzll_get_channel_table_size();
+ gzp_generate_channels(&channels[0], system_address, channel_table_size);
+
+ // Write generated channel subset to Gazell Link Layer
+ update_ok = update_ok && nrf_gzll_set_channel_table(&channels[0], channel_table_size);
+ if (gzll_enabled_state)
+ {
+ update_ok = update_ok && nrf_gzll_enable();
+ }
+ return update_ok;
+}
+
+void gzp_generate_channels(uint8_t* ch_dst, const uint8_t* system_address, uint8_t channel_tab_size)
+{
+ uint8_t binsize, spacing, i;
+
+ binsize = (GZP_CHANNEL_MAX - GZP_CHANNEL_MIN) / channel_tab_size;
+
+ ch_dst[0] = GZP_CHANNEL_LOW;
+ ch_dst[channel_tab_size - 1] = GZP_CHANNEL_HIGH;
+
+ if (system_address != NULL)
+ {
+ for (i = 1; i < (channel_tab_size - 1); i++)
+ {
+ ch_dst[i] = (binsize * i) + (system_address[i % 4] % binsize);
+ }
+ }
+
+ // If channels are too close, shift them to better positions
+ for (i = 1; i < channel_tab_size; i++)
+ {
+ spacing = (ch_dst[i] - ch_dst[i - 1]);
+ if (spacing < GZP_CHANNEL_SPACING_MIN)
+ {
+ ch_dst[i] += (GZP_CHANNEL_SPACING_MIN - spacing);
+ }
+ }
+}
+
+__INLINE void nrf_gzp_disable_gzll(void)
+{
+ if (nrf_gzll_is_enabled())
+ {
+ nrf_gzll_disable();
+ __WFI();
+ while (nrf_gzll_is_enabled())
+ {
+ }
+ }
+}
+
+#ifndef GZP_CRYPT_DISABLE
+
+void gzp_xor_cipher(uint8_t* dst, const uint8_t* src, const uint8_t* pad, uint8_t length)
+{
+ uint8_t i;
+
+ for (i = 0; i < length; i++)
+ {
+ *dst = *src ^ *pad;
+ dst++;
+ src++;
+ pad++;
+ }
+}
+
+bool gzp_validate_id(const uint8_t* id)
+{
+ return (memcmp(id, (void*)gzp_validation_id, GZP_VALIDATION_ID_LENGTH) == 0);
+}
+
+void gzp_add_validation_id(uint8_t* dst)
+{
+ memcpy(dst, (void const*)gzp_validation_id, GZP_VALIDATION_ID_LENGTH);
+}
+
+void gzp_crypt_set_session_token(const uint8_t * token)
+{
+ memcpy(gzp_session_token, (void const*)token, GZP_SESSION_TOKEN_LENGTH);
+}
+
+void gzp_crypt_set_dyn_key(const uint8_t* key)
+{
+ memcpy(gzp_dyn_key, (void const*)key, GZP_DYN_KEY_LENGTH);
+}
+
+void gzp_crypt_get_session_token(uint8_t * dst_token)
+{
+ memcpy(dst_token, (void const*)gzp_session_token, GZP_SESSION_TOKEN_LENGTH);
+}
+
+void gzp_crypt_get_dyn_key(uint8_t* dst_key)
+{
+ memcpy(dst_key, (void const*)gzp_dyn_key, GZP_DYN_KEY_LENGTH);
+}
+
+void gzp_crypt_select_key(gzp_key_select_t key_select)
+{
+ gzp_key_select = key_select;
+}
+
+void gzp_crypt(uint8_t* dst, const uint8_t* src, uint8_t length)
+{
+ uint8_t i;
+ uint8_t key[16];
+ uint8_t iv[16];
+
+ // Build AES key based on "gzp_key_select"
+
+ switch (gzp_key_select)
+ {
+ case GZP_ID_EXCHANGE:
+ memcpy(key, (void const*)gzp_secret_key, 16);
+ break;
+ case GZP_KEY_EXCHANGE:
+ memcpy(key, (void const*)gzp_secret_key, 16);
+ gzp_get_host_id(key);
+ break;
+ case GZP_DATA_EXCHANGE:
+ memcpy(key, (void const*)gzp_secret_key, 16);
+ memcpy(key, (void const*)gzp_dyn_key, GZP_DYN_KEY_LENGTH);
+ break;
+ default:
+ return;
+ }
+
+ // Build init vector from "gzp_session_token"
+ for (i = 0; i < 16; i++)
+ {
+ if (i < GZP_SESSION_TOKEN_LENGTH)
+ {
+ iv[i] = gzp_session_token[i];
+ }
+ else
+ {
+ iv[i] = 0;
+ }
+ }
+
+ // Set up hal_aes using new key and init vector
+ (void)nrf_ecb_init();
+ nrf_ecb_set_key(key);
+ //hal_aes_setup(false, ECB, key, NULL); // Note, here we skip the IV as we use ECB mode
+
+ // Encrypt IV using ECB mode
+ (void)nrf_ecb_crypt(iv, iv);
+
+ // Encrypt data by XOR'ing with AES output
+ gzp_xor_cipher(dst, src, iv, length);
+
+}
+
+void gzp_random_numbers_generate(uint8_t * dst, uint8_t n)
+{
+ uint8_t i;
+
+ NRF_RNG->EVENTS_VALRDY=0;
+ NRF_RNG->TASKS_START = 1;
+ for (i = 0; i < n; i++)
+ {
+ while (NRF_RNG->EVENTS_VALRDY==0)
+ {}
+ dst[i] = (uint8_t)NRF_RNG->VALUE;
+ NRF_RNG->EVENTS_VALRDY=0;
+ }
+ NRF_RNG->TASKS_STOP = 1;
+}
+
+
+/******************************************************************************/
+/** @name Implementation of nRF51 specific GZP functions
+ * @{ */
+/******************************************************************************/
+
+/**
+* @brief Function for setting the Primask variable. Only necessary if ARMCC
+* compiler skips __set_PRIMASK at high optimization levels.
+*
+* @param primask The primask value. 1 to disable interrupts, 0 otherwise.
+*/
+static void nrf_gzp_set_primask(uint32_t primask)
+{
+ #if defined(__CC_ARM)
+ //lint -save -e10 -e618 -e438 -e550 -e526 -e628 -e526
+ volatile register uint32_t __regPriMask __ASM("primask");
+ __regPriMask = (primask);
+ #else
+ __set_PRIMASK(primask);
+ #endif
+ //lint -restore
+}
+
+void nrf_gzp_flush_rx_fifo(uint32_t pipe)
+{
+ static uint8_t dummy_packet[NRF_GZLL_CONST_MAX_PAYLOAD_LENGTH];
+ uint32_t length;
+
+ nrf_gzp_set_primask(1);
+ while (nrf_gzll_get_rx_fifo_packet_count(pipe) >0)
+ {
+ length = NRF_GZLL_CONST_MAX_PAYLOAD_LENGTH;
+ (void)nrf_gzll_fetch_packet_from_rx_fifo(pipe,dummy_packet,&length);
+ }
+ nrf_gzp_set_primask(0);
+}
+/** @} */
+
+
+
+/******************************************************************************/
+/** @name Implementation of debug functions
+ * @{ */
+/******************************************************************************/
+
+
+/** @} */
+
+/** @} */
+#endif
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/proprietary_rf/gzll/nrf_gzp.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/proprietary_rf/gzll/nrf_gzp.h
new file mode 100644
index 0000000..336151f
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/proprietary_rf/gzll/nrf_gzp.h
@@ -0,0 +1,665 @@
+/**
+ * Copyright (c) 2012 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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
+ * @brief Gazell Pairing API
+ */
+
+#ifndef __GZP_H
+#define __GZP_H
+
+#include "nrf.h"
+#include "nrf_gzp_config.h"
+#include <stdbool.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+/**
+* @defgroup gzp_02_api Gazell Pairing
+* @{
+* @ingroup modules_02_gzp
+* @brief Gazell Pairing Application Programming Interface (API).
+*/
+
+
+/******************************************************************************/
+/** @name Pairing configuration defines
+ * @{ */
+/******************************************************************************/
+
+
+#define GZP_PAIRING_PIPE 0 ///< Pipe reserved for initial pairing communication.
+#define GZP_DATA_PIPE 1 ///< Pipe reserved for GZP encrypted data communication (one pipe only).
+#define GZP_TX_RX_TRANS_DELAY 10 ///< Time to wait between request and fetch packets in RX_PERIODS (2 timeslot periods)
+#define GZP_SYSTEM_ADDRESS_WIDTH 4 ///< Must equal Gazell base address length.
+
+
+#define GZP_VALIDATION_ID {0x32, 0x53, 0x66} ///< Validation ID. Required to be shared by Host and Device. Not a secret.
+#define GZP_VALIDATION_ID_LENGTH 3 ///< Validation ID length in bytes.
+#define GZP_HOST_ID_LENGTH 5 ///< Host ID length in bytes.
+#define GZP_SESSION_TOKEN_LENGTH GZP_HOST_ID_LENGTH ///< Session token length in bytes.
+#define GZP_DYN_KEY_LENGTH (16 - GZP_VALIDATION_ID_LENGTH) ///< Dynamic key length in bytes.
+
+#define GZP_HOST_RX_POWER_THRESHOLD -64 ///< RSSI threshold for when signal strength in RX packet power is high enough.
+
+/** @} */
+
+
+/******************************************************************************/
+/** @name Device -> Host packet definitions
+ * @{ */
+/******************************************************************************/
+
+#define GZP_CMD_HOST_ADDRESS_REQ_PAYLOAD_LENGTH 1 ///< "Host address request" packet, payload length
+
+#define GZP_CMD_HOST_ADDRESS_FETCH_PAYLOAD_LENGTH 1 ///< "Host address fetch" packet, payload length
+
+#define GZP_CMD_HOST_ID_REQ_SESSION_TOKEN 1 ///< "Host ID request" packet, session token position
+#define GZP_CMD_HOST_ID_REQ_PAYLOAD_LENGTH (GZP_CMD_HOST_ID_REQ_SESSION_TOKEN + GZP_SESSION_TOKEN_LENGTH) ///< "Host ID request" payload length
+
+#if (GZP_CMD_HOST_ID_REQ_PAYLOAD_LENGTH > 17)
+#error GZP_SESSION_TOKEN_LENGTH too long.
+#endif
+
+
+#define GZP_CMD_HOST_ID_FETCH_VALIDATION_ID 1 ///< "Host ID fetch" packet
+#define GZP_CMD_HOST_ID_FETCH_PAYLOAD_LENGTH (GZP_CMD_HOST_ID_FETCH_VALIDATION_ID + GZP_VALIDATION_ID_LENGTH) ///< "Host ID fetch" payload length
+
+#if (GZP_CMD_HOST_ID_FETCH_PAYLOAD_LENGTH > 17)
+#error GZP_VALIDATION_ID_LENGTH set too long.
+#endif
+
+#define GZP_CMD_KEY_UPDATE_PREPARE_PAYLOAD_LENGTH 1 ///< "Key update prepare" payload length
+
+#define GZP_CMD_KEY_UPDATE_VALIDATION_ID 1 ///< "Key update" packet, validation ID position
+#define GZP_CMD_KEY_UPDATE_NEW_KEY (GZP_CMD_KEY_UPDATE_VALIDATION_ID + GZP_VALIDATION_ID_LENGTH) ///< "Key update" packet, new key position
+#define GZP_CMD_KEY_UPDATE_PAYLOAD_LENGTH (GZP_CMD_KEY_UPDATE_NEW_KEY + GZP_DYN_KEY_LENGTH) ///< "Key update" packet, payload length
+
+#if (GZP_CMD_KEY_UPDATE_PAYLOAD_LENGTH > 17)
+#error Sum (GZP_VALIDATION_ID_LENGTH + GZP_DYN_KEY_LENGTH) too high.
+#endif
+
+
+#define GZP_CMD_ENCRYPTED_USER_DATA_VALIDATION_ID 1 ///< "Encrypted user data" packet, validation ID position
+#define GZP_CMD_ENCRYPTED_USER_DATA_PAYLOAD ((GZP_CMD_ENCRYPTED_USER_DATA_VALIDATION_ID + GZP_VALIDATION_ID_LENGTH)) ///< "Encrypted user data" packet, user data position
+#define GZP_ENCRYPTED_USER_DATA_PACKET_OVERHEAD ( GZP_CMD_ENCRYPTED_USER_DATA_VALIDATION_ID + GZP_VALIDATION_ID_LENGTH) ///< "Encrypted user data" packet, packet overhead length
+#define GZP_ENCRYPTED_USER_DATA_MAX_LENGTH (17 - GZP_ENCRYPTED_USER_DATA_PACKET_OVERHEAD) ///< "Encrypted user data" packet, max payload length
+
+#if (GZP_MAX_FW_PAYLOAD_LENGTH < 17)
+ #error GZP_MAX_FW_PAYLOAD_LENGTH must be greater or equal to 17.
+#endif
+
+#define GZP_CMD_FETCH_RESP_PAYLOAD_LENGTH 1 ///< General "fetch response" packet, payload_length
+
+/** @} */
+
+
+/******************************************************************************/
+/** @name Host -> Device packet definitions
+ * @{ */
+/******************************************************************************/
+
+
+#define GZP_CMD_HOST_ADDRESS_RESP_ADDRESS 1 ///< "Host address fetch" response packet, address position
+#define GZP_CMD_HOST_ADDRESS_RESP_PAYLOAD_LENGTH (GZP_CMD_HOST_ADDRESS_RESP_ADDRESS + GZP_SYSTEM_ADDRESS_WIDTH) ///< ///< "Host address fetch" response packet, payload length
+
+#if (GZP_MAX_ACK_PAYLOAD_LENGTH < GZP_CMD_HOST_ADDRESS_RESP_PAYLOAD_LENGTH)
+ #error GZP_MAX_ACK_PAYLOAD_LENGTH must be greater or equal to GZP_CMD_HOST_ADDRESS_RESP_PAYLOAD_LENGTH.
+#endif
+
+
+#define GZP_CMD_HOST_ID_FETCH_RESP_VALIDATION_ID 1 ///< "Host ID fetch" response packet, validation ID position
+#define GZP_CMD_HOST_ID_FETCH_RESP_STATUS (GZP_CMD_HOST_ID_FETCH_RESP_VALIDATION_ID + GZP_VALIDATION_ID_LENGTH) ///< "Host ID fetch" response packet, status position
+#define GZP_CMD_HOST_ID_FETCH_RESP_HOST_ID (GZP_CMD_HOST_ID_FETCH_RESP_STATUS + 1) ///< "Host ID fetch" response packet, Host ID position
+#define GZP_CMD_HOST_ID_FETCH_RESP_PAYLOAD_LENGTH (GZP_CMD_HOST_ID_FETCH_RESP_HOST_ID + GZP_HOST_ID_LENGTH) ///< "Host ID fetch" response packet, payload length
+
+#if (GZP_MAX_ACK_PAYLOAD_LENGTH < GZP_CMD_HOST_ID_FETCH_RESP_PAYLOAD_LENGTH)
+ #error GZP_MAX_ACK_PAYLOAD_LENGTH must be greater or equal to GZP_CMD_HOST_ID_FETCH_RESP_PAYLOAD_LENGTH.
+#endif
+
+
+#define GZP_CMD_KEY_UPDATE_PREPARE_RESP_SESSION_TOKEN 1 ///< "Key update prepare" response packet, session token position
+#define GZP_CMD_KEY_UPDATE_PREPARE_RESP_PAYLOAD_LENGTH (GZP_CMD_KEY_UPDATE_PREPARE_RESP_SESSION_TOKEN + GZP_SESSION_TOKEN_LENGTH) ///< "Key update prepare" response packet, payload length position
+
+#if (GZP_MAX_ACK_PAYLOAD_LENGTH < GZP_CMD_KEY_UPDATE_PREPARE_RESP_PAYLOAD_LENGTH)
+ #error GZP_MAX_ACK_PAYLOAD_LENGTH must be greater or equal to GZP_CMD_KEY_UPDATE_PREPARE_RESP_PAYLOAD_LENGTH.
+#endif
+
+
+#define GZP_CMD_ENCRYPTED_USER_DATA_RESP_SESSION_TOKEN 1 ///< "Encrypted user data" response packet, session token position
+#define GZP_CMD_ENCRYPTED_USER_DATA_RESP_VALIDATION_ID (GZP_CMD_ENCRYPTED_USER_DATA_RESP_SESSION_TOKEN + GZP_SESSION_TOKEN_LENGTH) ///< "Encrypted user data" response packet, validation ID position
+#define GZP_CMD_ENCRYPTED_USER_DATA_RESP_PAYLOAD_LENGTH (GZP_CMD_ENCRYPTED_USER_DATA_RESP_VALIDATION_ID + GZP_VALIDATION_ID_LENGTH) ///< "Encrypted user data" response packet, payload length position
+
+#if (GZP_MAX_ACK_PAYLOAD_LENGTH < GZP_CMD_ENCRYPTED_USER_DATA_RESP_PAYLOAD_LENGTH)
+ #error GZP_MAX_ACK_PAYLOAD_LENGTH must be greater or equal to GZP_CMD_ENCRYPTED_USER_DATA_RESP_PAYLOAD_LENGTH.
+#endif
+
+#if (GZP_VALIDATION_ID_LENGTH > GZP_HOST_ID_LENGTH)
+ #error GZP_HOST_ID_LENGTH should be greater or equal to GZP_VALIDATION_ID_LENGTH.
+#endif
+
+#if (GZP_SESSION_TOKEN_LENGTH != GZP_HOST_ID_LENGTH)
+ #error GZP_SESSION_TOKEN_LENGTH must equal GZP_HOST_ID_LENGTH.
+#endif
+
+#ifdef GZLL_CRYPT_ENABLE
+ #error Gazell encryption can not be enabled when using the Gazell pairing library. \
+ GZLL_CRYPT_ENABLE must be undefined.
+#endif
+
+/** @} */
+
+
+/******************************************************************************/
+/** @name Typedefs
+ * @{ */
+/******************************************************************************/
+
+
+/**
+ * @enum gzp_key_select_t
+ * @brief Enumerator used for selecting the key to be used for encryption.
+ */
+typedef enum
+{
+ GZP_ID_EXCHANGE, ///< "Secret key" only
+ GZP_KEY_EXCHANGE, ///< "Secret key" and "Host ID"
+ GZP_DATA_EXCHANGE ///< "Dynamic key" and "Host ID"
+} gzp_key_select_t;
+
+
+/**
+ * @enum gzp_cmd_t
+ * @brief Enumerator used in the first payload byte of each packet to
+ * indicate the packet type.
+ */
+typedef enum
+{
+ GZP_CMD_HOST_ADDRESS_REQ = 0, ///< Host address request
+ GZP_CMD_HOST_ADDRESS_FETCH, ///< Host address fetch
+ GZP_CMD_HOST_ID_REQ, ///< Host ID request
+ GZP_CMD_HOST_ID_FETCH, ///< Host ID fetch request
+ GZP_CMD_KEY_UPDATE_PREPARE, ///< Key update prepare
+ GZP_CMD_KEY_UPDATE, ///< Key update
+ GZP_CMD_ENCRYPTED_USER_DATA, ///< Encrypted user data
+ GZP_CMD_FETCH_RESP, ///< Fetch response
+ GZP_CMD_HOST_ADDRESS_RESP, ///< Host address response
+ GZP_CMD_HOST_ID_FETCH_RESP, ///< Host ID fetch response
+ GZP_CMD_KEY_UPDATE_PREPARE_RESP, ///< Key update prepare
+ GZP_CMD_ENCRYPTED_USER_DATA_RESP, ///< Encrypted user data response
+} gzp_cmd_t;
+
+
+/**
+ * @enum gzp_id_req_res_t
+ * @brief Enumerator used to identify the state of the current
+ * Host ID request.
+ */
+typedef enum
+{
+ GZP_ID_RESP_PENDING, ///< ID response pending
+ GZP_ID_RESP_GRANTED, ///< ID response granted
+ GZP_ID_RESP_REJECTED, ///< ID response rejected
+ GZP_ID_RESP_FAILED, ///< ID response failed
+ GZP_ID_RESP_NO_REQUEST ///< Default value. No ID request has yet been received.
+} gzp_id_req_res_t;
+
+
+/** @} */
+
+
+/******************************************************************************/
+/** @name Misc. function prototypes
+ * @{ */
+/******************************************************************************/
+
+/**
+ * Set the session token.
+ *
+ * @param token Pointer to the session token to set.
+ */
+void gzp_crypt_set_session_token(const uint8_t *token);
+
+
+/**
+ * Get the session token.
+ *
+ * @param dst_token Pointer to write the session token.
+ */
+void gzp_crypt_get_session_token(uint8_t *dst_token);
+
+
+/**
+ * Set the dynamic key.
+ *
+ * @param dyn_key Pointer to the dynamic key to set.
+ */
+void gzp_crypt_set_dyn_key(const uint8_t* dyn_key);
+
+
+/**
+ * Get the dynamic key.
+ *
+ * @param dst_key Pointer to write the dynamic key too.
+ */
+void gzp_crypt_get_dyn_key(uint8_t *dst_key);
+
+
+/**
+ * Set the Host ID.
+ *
+ * @param src Pointer to the Host ID to set.
+ */
+static void gzp_set_host_id(const uint8_t* src);
+
+
+/**
+ * Get the Host ID.
+ *
+ * @param dst Pointer to write the Host ID to.
+ */
+void gzp_get_host_id(uint8_t *dst);
+
+
+/**
+ * Selecting what key-set that should be used when encrypting data
+ * using gzp_crypt().
+ *
+ * @param key_select Key-set to use.
+ */
+void gzp_crypt_select_key(gzp_key_select_t key_select);
+
+
+/**
+ * Encypt / decrypt data.
+ *
+ * The current "session token" will be used as initialization vector (IV).
+ * The AES key to be used is selected by gzp_crypt_select_key().
+ * AES is a symmetric encryption scheme, this function can be used
+ * to perform both encryption and decryption.
+ *
+ * @param dst Destination to write encrypted data to. Should be 16 bytes long.
+ * @param src Source data to encrypt.
+ * @param length Length in bytes of src.
+ */
+void gzp_crypt(uint8_t* dst, const uint8_t* src, uint8_t length);
+
+
+/**
+ * Compare the *src_id with a pre-defined validation ID.
+ *
+ * @param src_id Pointer to the source validation ID to compare to.
+ *
+ * @retval true If *src_id equals the pre-defined ID.
+ * @retval false If *src_id does not equal the pre-defined ID.
+ */
+bool gzp_validate_id(const uint8_t *src_id);
+
+
+/**
+ * Add the pre-defined validation ID to dst_id.
+ * GZP_VALIDATION_ID_LENGTH bytes will be added.
+ *
+ * @param dst_id Pointer to add the GZP validation ID to.
+ */
+void gzp_add_validation_id(uint8_t *dst_id);
+
+
+/**
+ * Generate random bytes.
+ *
+ * @param dst Destination to write the random bytes to.
+ * @param n Number of bytes to generate.
+ */
+void gzp_random_numbers_generate(uint8_t *dst, uint8_t n);
+
+
+/**
+ * Update the channel table and the system address.
+ *
+ * The channel table is updated to pseudo-random set generated using the
+ * system address. The channel table still includes GZP_CHANNEL_MAX and
+ * GZP_CHANNEL_MIN.
+ * The system address is applied to base address 1 and therefore applies
+ * to pipes 1-7.
+ *
+ * @param system_address Pointer to the system_address to set.
+ *
+ * @retval true If theradio parameters were updated successfully.
+ * @retval false If there was an error updated the radio parameters.
+ */
+bool gzp_update_radio_params(const uint8_t *system_address);
+
+
+/**
+ * Generate a set of channels from a 4 byte address.
+ *
+ * @param ch_dst Destination to write the channel set to. The channel set
+ * includes GZP_CHANNEL_MAX and GZP_CHANNEL_MIN.
+ * @param address Four byte address to generate the channel set from.
+ * @param channel_set_size Size of the channel set to generate.
+ */
+void gzp_generate_channels(uint8_t *ch_dst, const uint8_t * address, uint8_t channel_set_size);
+
+
+/**
+ * Perform an XOR on two byte strings.
+ *
+ * @param dst Destination to write the result to. Should be of size length.
+ * @param src
+ * @param pad
+ * @param length Number of bytes to perform the XOR operation on.
+ */
+void gzp_xor_cipher(uint8_t* dst, const uint8_t* src, const uint8_t* pad, uint8_t length);
+
+
+/******************************************************************************/
+/** @name Common Device and Host functions
+ * @{ */
+/******************************************************************************/
+
+
+/**
+ * Initialization function. This function initializes the Gazell Pairing Library.
+
+ * This function must be called before any of the other Gazell Pairing Library functions are
+ * used and must be called @b after gzll_init() is called.
+ *
+ */
+void gzp_init(void);
+
+/**
+ * Function for erasing all pairing data.
+ */
+void gzp_erase_pairing_data(void);
+
+/**
+ * Disable Gazell and sleep while waiting for nrf_gzll_disabled callback.
+ */
+void nrf_gzp_disable_gzll(void);
+
+/**
+ Function for cancelling an ongoing (pending) "Host ID request".
+
+ After calling this function the "Host ID request" status will go to
+ "ID request Idle".
+*/
+void gzp_id_req_cancel(void);
+
+/**
+ * Flush the GZLL RX FIFO for a specific pipe while GZLL is disabled.
+ *
+ * @param pipe Pipe.
+ */
+void nrf_gzp_flush_rx_fifo(uint32_t pipe);
+
+/**
+@name Device functions
+*/
+
+/**
+ * Check whether current GZP packet transaction has completed.
+ *
+ * @retval true
+ * @retval false
+ */
+bool nrf_gzp_tx_complete(void);
+
+/**
+ * Check whether previous GZP packet transaction was successful.
+ *
+ * @retval true
+ * @retval false
+ */
+bool nrf_gzp_tx_success(void);
+
+/**
+ * Reset tx_complete status.
+ */
+void nrf_gzp_reset_tx_complete(void);
+
+/**
+ * Reset tx_success status.
+ */
+void nrf_gzp_reset_tx_success(void);
+
+/**
+* Function to check whether a Device has existing pairing data, implying that it is
+* paired to a Host.
+*
+* @retval -2 The pairing database is empty.
+* @retval -1 The device has a system address but no Host ID.
+* @retval >=0 The device has a system address and HostID at this index value in the database.
+*/
+int8_t gzp_get_pairing_status(void);
+
+/**
+ Function for sending a "system address" request to a Host.
+
+ When calling this function the Device will attempt acquiring the "system address" from
+ any Host within close proximity.
+
+ If a host is located within close proximity and pairing is enabled in the Host,
+ a "system address" will be sent in return to the Device.
+
+ The new "system address" will apply immediately in the Device, and the new "system address"
+ will be stored in non volatile (NV) memory.
+
+ Note. Using OTP devices limits the number of times a new "system address" can
+ be stored in NV memory.
+
+ @return
+
+ @retval true if new "system address" was received from a Host.
+ @retval false if no "system address" was received from a Host.
+*/
+bool gzp_address_req_send(void);
+
+/**
+ Function for sending a "Host ID request" to a Host.
+
+ The "Host ID" is needed to be able to send encrypted data using
+ gzp_crypt_data_send().
+
+ The request will be sent using the "system address" previously received using
+ gzp_address_req_send().
+
+ It is not required that the Host is within close proximity in order to acquire the
+ "Host ID".
+
+ The new "Host ID" will apply immediately for the Device, and the new "Host ID"
+ will be stored in non volatile (NV) memory.
+
+ Note. Using OTP devices limits the number of times a new "Host ID" can
+ be stored in NV memory.
+
+ @return
+
+ @retval GZP_ID_RESP_PENDING if a "Host ID request" has been sent to the Host, but the Host application has
+ not yet decided whether to Grant or Reject the "ID request".
+ @retval GZP_ID_RESP_GRANTED if the "Host ID" has been received from the Host. The received "Host ID" will be stored
+ in non volatile memory.
+ @retval GZP_ID_RESP_REJECTED if the Host application has rejected the "Host ID request".
+ @retval GZP_ID_RESP_FAILED if failing to send a request or receive a response from the Host.
+*/
+gzp_id_req_res_t gzp_id_req_send(void);
+
+/**
+ Function for sending encrypted user data to the Host.
+
+ Before any data can be sent the Device must acquire both the Host's
+ "system address" by using gzp_address_req_send() and the "Host ID" by using
+ gzp_id_req_send().
+
+ @param *src is a pointer to the data packet to be sent.
+ @param length is the length of the data packet to be sent.
+
+
+ @return
+ @retval true if the data was successfully transmitted and decrypted by the Host.
+ @retval false if data transmission failed or Host failed to decryption data correctly.
+*/
+bool gzp_crypt_data_send(const uint8_t *src, uint8_t length);
+
+
+/**
+@name Host functions
+*/
+
+/**
+ Function for enabling/disabling pairing in a host. When pairing is enabled the host will
+ be monitoring for "system address" and "Host ID" requests from Devices.
+
+ A "system address request" received from a Device will always be granted.
+ When a "host ID request" has been received, the Host application have to grant,
+ reject or cancel this by using one of the following functions:
+
+ - gzp_id_req_grant()
+ - gzp_id_req_reject()
+ - gzp_id_req_cancel()
+
+ @param enable
+ @arg true enables pairing.
+ @arg false disables pairing.
+*/
+void gzp_pairing_enable(bool enable);
+
+/**
+ * Execute the Gazell Pairing Library Host operation.
+ *
+ * This function must be called regularly by the Host application.
+ */
+void gzp_host_execute(void);
+
+/**
+ * Address exchanged check.
+ *
+ * @retval true If a "system address" was delivered to a requesting Device during the
+ * previous call to gzp_host_execute();
+ * @retval false Otherwise.
+*/
+bool gzp_address_exchanged(void);
+
+/**
+ Function for checking if a "Host ID request" has been received from a Device.
+
+ If a request has been received, the Pairing library will enter "ID request pending"
+ state.
+
+ The application is responsible for responding to this request by calling
+ one of the following functions:
+
+ - gzp_id_req_grant()
+ - gzp_id_req_reject()
+ - gzp_id_req_cancel()
+
+ @retval true if a "Host ID request" has been received (internal state is "ID request pending")
+ @retval false if no "Host ID request" has been received (internal state is "ID request idle")
+*/
+bool gzp_id_req_received(void);
+
+/**
+ Function for rejecting the previously received "Host ID request". This function should be called
+ only when a "Host ID request" has been received (internal state is "ID request pending").
+
+ The internal state of the Pairing library will remain "ID request pending" until the a "reject" message
+ has been successfully transmitted to the requesting Device. After this the internal state will
+ change to "ID request idle".
+*/
+void gzp_id_req_reject(void);
+
+/**
+ * Function for granting the previously received "Host ID request". This function should be called
+ only when a "Host ID request" has been received (internal state is "ID request pending").
+
+ The internal state of the Pairing library will remain "ID request pending" until the "Host ID" has
+ been successfully transmitted to the requesting Device. After this the internal state will
+ change to "ID request idle".
+*/
+void gzp_id_req_grant(void);
+
+
+/**
+ * Check if user data has been received.
+ *
+ * @retval true If encrypted user data has been received.
+ * @retval false Otherwise.
+*/
+bool gzp_crypt_user_data_received(void);
+
+/**
+ Function for reading encrypted user data.
+
+ Note that the read user data will be automatically decrypted. Only data
+ that was decrypted correctly will be presented.
+
+ @param dst* is a pointer to where the received data will be written.
+ @param length* is a pointer for returning the number of bytes received. Only 1 byte will
+ be writtem to length*.
+
+ @return
+ @retval true if data has been received and is written to dst*
+ @retval false if no data has been received.
+*/
+bool gzp_crypt_user_data_read(uint8_t* dst, uint8_t* length);
+
+
+/**
+ Function emulating behavior of gzll_rx_start() in legeacy nRF24xx Gaell
+ linbrary.
+
+ This functions sets Gazell in Host mode and starts reception (enable).
+*/
+void gzll_rx_start(void);
+
+
+/** @} */
+/** @} */
+/** @} */
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/proprietary_rf/gzll/nrf_gzp_device.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/proprietary_rf/gzll/nrf_gzp_device.c
new file mode 100644
index 0000000..7ee4037
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/proprietary_rf/gzll/nrf_gzp_device.c
@@ -0,0 +1,1146 @@
+/**
+ * Copyright (c) 2009 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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
+ * @brief Implementation of Gazell Pairing Library (gzp), Device functions.
+ * @defgroup gzp_source_device Gazell Pairing Device implementation.
+ * @{
+ * @ingroup gzp_04_source
+ */
+
+
+#include <stdint.h>
+#include <stdbool.h>
+#include <string.h>
+
+#include "nrf_gzll.h"
+#include "nrf_gzp.h"
+#include "nrf_delay.h"
+#include "nrf_nvmc.h"
+
+#define SOURCE_FILE NRF_SOURCE_FILE_GZP_DEVICE ///< File identifer for asserts.
+
+/******************************************************************************/
+/** @name Misc. defines
+ * @{ */
+/******************************************************************************/
+
+#define GZP_PARAMS_DB_ELEMENT_SYSTEM_ADDRESS 0 ///< System address position.
+#define GZP_PARAMS_DB_ELEMENT_HOST_ID (GZP_PARAMS_DB_ELEMENT_SYSTEM_ADDRESS + GZP_SYSTEM_ADDRESS_WIDTH) ///< Host ID position
+#define GZP_PARAMS_DB_ELEMENT_SIZE (GZP_SYSTEM_ADDRESS_WIDTH + GZP_HOST_ID_LENGTH)///< Total size
+#define GZP_PARAMS_DB_MAX_ENTRIES 14 ///< Maximum allowed entries in the database.
+
+/** @} */
+
+/******************************************************************************/
+/** @name Derived parameters
+ * @{ */
+/******************************************************************************/
+
+//lint -esym(40, GZP_PARAMS_STORAGE_ADR) "Undeclare identifier"
+#define GZP_PARAMS_DB_ADR GZP_PARAMS_STORAGE_ADR ///<
+#define GZP_PARAMS_DB_SIZE (GZP_PARAMS_DB_MAX_ENTRIES * GZP_PARAMS_DB_ELEMENT_SIZE) ///<
+
+#define GZP_INDEX_DB_ADR (GZP_PARAMS_STORAGE_ADR + GZP_PARAMS_DB_SIZE) ///<
+#define GZP_INDEX_DB_SIZE (GZP_DEVICE_PARAMS_STORAGE_SIZE - GZP_PARAMS_DB_SIZE) ///<
+
+#if (GZP_DEVICE_PARAMS_STORAGE_SIZE < GZP_PARAMS_DB_SIZE)
+ #error GZP_DEVICE_PARAMS_STORAGE_SIZE must be greater or equal to GZP_PAIRING_PARAMS_DB_SIZE
+#elif (GZP_DEVICE_PARAMS_STORAGE_SIZE == GZP_PARAMS_DB_SIZE )
+ #warning GZP_DEVICE_PARAMS_STORAGE_SIZE to low to be able store any pairing parameters NV memory
+#endif
+/** @} */
+
+
+/******************************************************************************/
+/** @name Typedefs
+ * @{ */
+/******************************************************************************/
+
+
+/**
+ * Possible return values for the function gzp_tx_rx_transaction()
+ */
+typedef enum
+{
+ GZP_TX_RX_SUCCESS, ///< ACK received. Transaction successful.
+ GZP_TX_RX_FAILED_TO_SEND, ///<
+ GZP_TX_RX_NO_RESPONSE ///<
+} gzp_tx_rx_trans_result_t;
+/** @} */
+
+
+/******************************************************************************/
+/** @name Internal variables
+ * @{ */
+/******************************************************************************/
+
+static uint8_t gzp_system_address[GZP_SYSTEM_ADDRESS_WIDTH]; ///<
+static uint8_t gzp_host_id[GZP_HOST_ID_LENGTH]; ///<
+static uint8_t dyn_key[GZP_DYN_KEY_LENGTH];
+static bool gzp_id_req_pending = false;
+
+/** @} */
+
+
+/******************************************************************************/
+/** @name Internal (static) function prototypes
+ * @{ */
+/******************************************************************************/
+
+/**
+ * Function for sending an encrypted packet.
+ *
+ * The function waits for the transmission to complete.
+ *
+ * @param tx_packet Pointer to the packet to be sent.
+ * @param length Length of the packet to be sent.
+ * @param pipe Pipe on which the packet should be sent.
+ *
+ * @retval true If the transmission succeeded.
+ * @retval false If the transmission failed (timed out).
+ */
+static bool gzp_tx_packet(const uint8_t* tx_packet, uint8_t length, uint8_t pipe);
+
+/**
+ * Function sending the packet *tx_packet and a subsequent packet fetching the response
+ * to *tx_packet.
+ *
+ * @param tx_packet is a pointer to the packet to be sent.
+ * @param tx_length is the length of the packet to be sent.
+ * @param rx_dst is a pointer to where the received response packet should be stored.
+ * @param rx_length is a pointer to where the length of the received packet should be stored.
+ * @param pipe is the pipe on which the packet should be sent.
+ *
+ * @return result of the transaction.
+ */
+ static gzp_tx_rx_trans_result_t gzp_tx_rx_transaction(const uint8_t *tx_packet, uint8_t tx_length, uint8_t *rx_dst, uint32_t *rx_length, uint8_t pipe);
+
+/**
+ * Function for sending an encrypted packet. The function detects whether the correct
+ * key was used, and attempts to send a "key update" to the host if the wrong key was being
+ * used.
+
+ * @param tx_packet is a pointer to the packet to be sent.
+ * @param length is the length of the packet to be sent.
+
+ * @retval true if transmission succeeded and packet was decrypted correctly by host.
+ * @retval false if transmission failed or packet was not decrypted correctly by host.
+ */
+static bool gzp_crypt_tx_transaction(const uint8_t *tx_packet, uint8_t length);
+
+/**
+ * Function updateing the "dynamic key" and sending a "key update" to the host.
+ *
+ * @retval true if key update succeeded.
+ * @retval false if if key update failed.
+ */
+static bool gzp_key_update(void);
+
+/**
+ * Function for adding an element to "parameters data base" in non volatile (NV) memory. An element is
+ * GZP_PARAMS_ELEMENT_SYSTEM_ADDRESS bytes long, holding the "system address" and "host ID".
+ *
+ * The "parameters data base" can store up to GZP_DEVICE_PAIRING_PARAMS_DB_MAX_ENTRIES
+ * elements.
+ *
+ * @param src_element is a pointer to the element.
+ * @param index is a number between 0 and (GZP_PARAMS_DB_MAX_ENTRIES - 1)
+ * selecting the location in which the element will be stored.
+ */
+static void gzp_params_db_add(const uint8_t *src_element, uint8_t index);
+
+/**
+ * Function for reading an element from "parameters data base" in non volatile (NV) memory. An element is
+ * GZP_PARAMS_ELEMENT_SYSTEM_ADDRESS bytes long, holding the "system address" and "host ID".
+ *
+ * @param dst_element is a pointer where the read element should be stored.
+ * @param index is a number between 0 and (GZP_PARAMS_DB_MAX_ENTRIES - 1).
+ * selecting the location that should be read.
+ */
+static void gzp_params_db_read(uint8_t* dst_element, uint8_t index);
+
+/**
+ * Function for writing an index to the "index data base" in non volatile (NV) memory.
+ *
+ * @param index is the index to be written to the data base.
+ */
+static void gzp_index_db_add(uint8_t index);
+
+/**
+ * Function for reading the index previously written to the "index data base" in NV memory.
+ *
+ * @return
+ */
+static uint8_t gzp_index_db_read(void);
+
+/**
+ * Check "index data base" is full.
+ *
+ * @retval true
+ * @retval false
+ */
+static bool gzp_index_db_full(void);
+
+/**
+ * Function returning @b true if the "index data base" is empty.
+ *
+ * @retval true
+ * @retval false
+ */
+static bool gzp_index_db_empty(void);
+
+/**
+ * Function returning @b true if array contains only 1s (0xff).
+ *
+ * @param *src is a pointer to the array to be evaluated.
+ * @param length is the length of the array to be evaluated.
+ *
+ * @retval true
+ * @retval false
+ */
+static bool gzp_array_is_set(const uint8_t* src, uint8_t length);
+
+/**
+ * Function for storing the current "system address" and "host ID" in NV memory.
+ *
+ * @param store_all selects whether only "system address" or both "system address" and
+ * "host ID" should be stored.
+ * @arg true selects that both should be stored.
+ * @arg false selects that only "system address" should be stored.
+ *
+ * @retval true
+ * @retval false
+ */
+static bool gzp_params_store(bool store_all);
+
+/**
+ * Restore the "system address" and "host ID" from NV memory.
+ * @retval true
+ * @retval false
+ */
+static bool gzp_params_restore(void);
+
+/**
+ * Delay function. Will add a delay equal to GZLL_RX_PERIOD * rx_periods [us].
+ *
+ * @param rx_periods
+ */
+void gzp_delay_rx_periods(uint32_t rx_periods);
+
+/**
+ * Delay function. Will add a delay equal to GZLL_RX_PERIOD * rx_periods [us] using the
+ * gazell timer and not a delay loop.
+ *
+ * @param rx_periods
+ */
+void gzp_tick_sleep_rx_periods(uint32_t rx_periods);
+
+/*
+ * Print debug string. By default does nothing.
+ *
+ * If GZP_DEBUG is defined then the print string function is required to
+ * be implemented.
+ */
+void print_string(char* p_expr);
+
+/** @} */
+
+/******************************************************************************/
+/** @name Internal (static) variables
+ * @{ */
+/******************************************************************************/
+
+static nrf_gzll_device_tx_info_t latest_tx_info; ///< Information about the last TX attempt, e.g. RSSI of ACK.
+
+static volatile bool tx_complete; ///< Flag to indicate whether a GZLL TX attempt has completed.
+static bool tx_success; ///< Flag to indicate whether a GZLL TX attempt was successful.
+
+// Define Macro to make array initialization nicer
+#define REP4(X) X X X X
+
+#if defined(__ICCARM__)
+ #if GZP_PARAMS_DB_ADR == 0x1000
+ static const uint32_t database[GZP_DEVICE_PARAMS_STORAGE_SIZE/4] @ "gzp_dev_data"
+ #elif GZP_PARAMS_DB_ADR == 0x15000
+ static const uint32_t database[GZP_DEVICE_PARAMS_STORAGE_SIZE/4] @ "gzp_dev_data_sd"
+ #else
+ #error
+ #endif
+#else
+static const uint32_t database[GZP_DEVICE_PARAMS_STORAGE_SIZE / 4] __attribute__((at(GZP_PARAMS_DB_ADR)))
+#endif
+= {
+ #define STATIC_INIT_VALUE 0xFFFFFFFF
+ #define STATIC_INIT_COUNT (GZP_DEVICE_PARAMS_STORAGE_SIZE / 4)
+ #define INIT_1 STATIC_INIT_VALUE,
+ #define INIT_4 REP4(INIT_1)
+ #define INIT_16 REP4(INIT_4)
+ #define INIT_64 REP4(INIT_16)
+ #define INIT_256 REP4(INIT_64)
+ #define INIT_1024 REP4(INIT_256)
+
+ #if (STATIC_INIT_COUNT == 256)
+ INIT_256
+ #elif (STATIC_INIT_COUNT == 1024)
+ INIT_1024
+ #else
+ #error Gazell Pairing Library database not initialized properly!
+ #endif
+}; ///< Database for storing keys.
+
+
+/** @} */
+
+
+/******************************************************************************/
+// Implementation: Device-specific API functions
+/******************************************************************************/
+
+
+void gzp_init()
+{
+ gzp_id_req_pending = false;
+
+#ifndef GZP_NV_STORAGE_DISABLE
+ (void)gzp_params_restore();
+#endif
+
+ // Update radio parameters from gzp_system_address
+ (void)gzp_update_radio_params(gzp_system_address);
+}
+
+
+void gzp_erase_pairing_data(void)
+{
+ // Erase database flash page so that it can be later written to.
+ nrf_nvmc_page_erase((uint32_t)database);
+}
+
+bool gzp_address_req_send()
+{
+ //lint -save -e514 Unusual use of a Boolean expression (gzll_update_ok &= ...)
+ uint8_t i;
+ bool retval = false;
+ bool success;
+ uint8_t address_req[GZP_CMD_HOST_ADDRESS_REQ_PAYLOAD_LENGTH];
+ uint8_t rx_payload[NRF_GZLL_CONST_MAX_PAYLOAD_LENGTH];
+ uint32_t rx_payload_length = NRF_GZLL_CONST_MAX_PAYLOAD_LENGTH;
+ nrf_gzll_tx_power_t temp_power;
+ uint32_t temp_max_tx_attempts;
+ bool gzll_update_ok = true;
+
+
+ // Store parameters that are temporarily changed
+ temp_max_tx_attempts = nrf_gzll_get_max_tx_attempts();
+ temp_power = nrf_gzll_get_tx_power();
+
+ // Modify parameters
+ nrf_gzp_disable_gzll();
+ nrf_gzll_set_max_tx_attempts(GZP_REQ_TX_TIMEOUT);
+ gzll_update_ok &= nrf_gzll_set_tx_power(GZP_POWER);
+
+ // Flush RX FIFO
+ gzll_update_ok &= nrf_gzll_flush_rx_fifo(GZP_PAIRING_PIPE);
+ gzll_update_ok &= nrf_gzll_enable();
+ // Build "request" packet
+ address_req[0] = (uint8_t)GZP_CMD_HOST_ADDRESS_REQ;
+
+ // Send a number of packets in order to broadcast that devices not within
+ // close proximity must back off.
+ for (i = 0; i < GZP_MAX_BACKOFF_PACKETS; i++)
+ {
+ success = gzp_tx_packet(address_req, GZP_CMD_HOST_ADDRESS_REQ_PAYLOAD_LENGTH, GZP_PAIRING_PIPE);
+ if (success)
+ {
+ nrf_gzp_flush_rx_fifo(GZP_PAIRING_PIPE);
+ }
+ else
+ {
+ break;
+ }
+ }
+
+ gzp_delay_rx_periods(GZP_TX_ACK_WAIT_TIMEOUT);
+ // Send message for fetching pairing response from host.
+ address_req[0] = (uint8_t)GZP_CMD_HOST_ADDRESS_FETCH;
+
+ success = gzp_tx_packet(address_req, GZP_CMD_HOST_ADDRESS_REQ_PAYLOAD_LENGTH, GZP_PAIRING_PIPE);
+ if (success && latest_tx_info.payload_received_in_ack)
+ {
+ // If pairing response received
+ if (nrf_gzll_get_rx_fifo_packet_count(GZP_PAIRING_PIPE) > 0)
+ {
+ rx_payload_length = NRF_GZLL_CONST_MAX_PAYLOAD_LENGTH; //dummy placeholder
+ if (nrf_gzll_fetch_packet_from_rx_fifo(GZP_PAIRING_PIPE, rx_payload, &rx_payload_length))
+ {
+ if (rx_payload[0] == (uint8_t)GZP_CMD_HOST_ADDRESS_RESP)
+ {
+ memcpy(gzp_system_address, &rx_payload[GZP_CMD_HOST_ADDRESS_RESP_ADDRESS], GZP_SYSTEM_ADDRESS_WIDTH);
+ gzll_update_ok &= gzp_update_radio_params(&rx_payload[GZP_CMD_HOST_ADDRESS_RESP_ADDRESS]);
+ #ifndef GZP_NV_STORAGE_DISABLE
+ (void)gzp_params_store(false); // "False" indicates that only "system address" part of DB element will be stored
+ #endif
+ retval = true;
+ }
+ }
+ }
+ }
+ else
+ {
+ gzp_delay_rx_periods(GZP_NOT_PROXIMITY_BACKOFF_RX_TIMEOUT - GZP_TX_ACK_WAIT_TIMEOUT);
+ }
+ gzp_delay_rx_periods(GZP_STEP1_RX_TIMEOUT);
+
+ // Clean-up and restore parameters temporarily modified
+ nrf_gzp_disable_gzll();
+ gzll_update_ok &= nrf_gzll_flush_rx_fifo(GZP_PAIRING_PIPE);
+ gzll_update_ok &= nrf_gzll_flush_tx_fifo(GZP_PAIRING_PIPE);
+ nrf_gzll_set_max_tx_attempts(temp_max_tx_attempts);
+ gzll_update_ok &= nrf_gzll_set_tx_power(temp_power);
+ gzll_update_ok &= nrf_gzll_enable();
+
+ if (!gzll_update_ok)
+ {
+ /*
+ The update of the Gazell parameters failed. Use nrf_gzll_get_error_code()
+ to investigate the cause.
+ */
+ }
+
+ return retval;
+ //lint -restore
+}
+
+#ifndef GZP_CRYPT_DISABLE
+
+gzp_id_req_res_t gzp_id_req_send()
+{
+ uint8_t tx_packet[GZP_CMD_HOST_ID_REQ_PAYLOAD_LENGTH];
+ uint8_t rx_packet[GZP_MAX_ACK_PAYLOAD_LENGTH];
+ gzp_tx_rx_trans_result_t trans_result;
+
+ // If no ID request is pending, send new "ID request"
+ if (!gzp_id_req_pending)
+ {
+ // Build "Host ID request packet"
+ tx_packet[0] = (uint8_t)GZP_CMD_HOST_ID_REQ;
+
+ // Generate new session token
+ gzp_random_numbers_generate(&tx_packet[GZP_CMD_HOST_ID_REQ_SESSION_TOKEN], GZP_SESSION_TOKEN_LENGTH);
+
+ // Send "Host ID request"
+ if (gzp_tx_packet(tx_packet, GZP_CMD_HOST_ID_REQ_PAYLOAD_LENGTH, GZP_DATA_PIPE))
+ {
+ // Update session token if "Host ID request" was successfully transmitted
+ gzp_crypt_set_session_token(&tx_packet[GZP_CMD_HOST_ID_REQ_SESSION_TOKEN]);
+ gzp_id_req_pending = true;
+
+ return GZP_ID_RESP_PENDING;
+ }
+ }
+ else // If "ID request is pending" send "fetch ID" packet
+ {
+ // Build "host ID fetch" packet
+ tx_packet[0] = (uint8_t)GZP_CMD_HOST_ID_FETCH;
+ gzp_add_validation_id(&tx_packet[GZP_CMD_HOST_ID_FETCH_VALIDATION_ID]);
+
+ // Encrypt "host ID fetch" packet
+ gzp_crypt_select_key(GZP_ID_EXCHANGE);
+ gzp_crypt(&tx_packet[1], &tx_packet[1], GZP_CMD_HOST_ID_FETCH_PAYLOAD_LENGTH - 1);
+
+ trans_result = gzp_tx_rx_transaction(tx_packet, GZP_CMD_HOST_ID_FETCH_PAYLOAD_LENGTH, rx_packet, NULL, GZP_DATA_PIPE);
+ // If packet was successfully sent AND a response packet was received
+ if (trans_result == GZP_TX_RX_SUCCESS)
+ {
+ // Validate response packet
+ if (rx_packet[0] == (uint8_t)GZP_CMD_HOST_ID_FETCH_RESP)
+ {
+ gzp_crypt(&rx_packet[1], &rx_packet[1], GZP_CMD_HOST_ID_FETCH_RESP_PAYLOAD_LENGTH - 1);
+ if (gzp_validate_id(&rx_packet[GZP_CMD_HOST_ID_FETCH_RESP_VALIDATION_ID]))
+ {
+ switch (rx_packet[GZP_CMD_HOST_ID_FETCH_RESP_STATUS])
+ {
+ case GZP_ID_RESP_PENDING:
+ break;
+ case GZP_ID_RESP_REJECTED:
+ gzp_id_req_pending = false;
+ break;
+ case GZP_ID_RESP_GRANTED:
+ gzp_set_host_id(&rx_packet[GZP_CMD_HOST_ID_FETCH_RESP_HOST_ID]);
+ gzp_random_numbers_generate(dyn_key, GZP_DYN_KEY_LENGTH);
+ gzp_crypt_set_dyn_key(dyn_key);
+ #ifndef GZP_NV_STORAGE_DISABLE
+ (void)gzp_params_store(true);
+ #endif
+ gzp_id_req_pending = false;
+ break;
+ default:
+ break;
+ }
+
+ return (gzp_id_req_res_t)rx_packet[GZP_CMD_HOST_ID_FETCH_RESP_STATUS];
+ }
+ else
+ {
+ gzp_id_req_pending = false;
+ return GZP_ID_RESP_REJECTED;
+ }
+ }
+ }
+ }
+
+ gzp_id_req_pending = false;
+ return GZP_ID_RESP_FAILED;
+}
+
+void gzp_id_req_cancel()
+{
+ gzp_id_req_pending = false;
+}
+
+bool gzp_crypt_data_send(const uint8_t *src, uint8_t length)
+{
+ if (length <= GZP_ENCRYPTED_USER_DATA_MAX_LENGTH)
+ {
+ if (gzp_crypt_tx_transaction(src, length))
+ {
+ return true;
+ }
+ else
+ {
+ //print_string("GZP_CRYPT_TX failed\r\n");
+ // Attempt key update if user data transmission failed
+ // during normal operation (!gzp_id_req_pending)
+ if (!gzp_id_req_pending)
+ {
+ //print_string("KEY UPDATE\r\n");
+ if (gzp_key_update())
+ {
+ return gzp_crypt_tx_transaction(src, length);
+ }
+ }
+ return false;
+ }
+ }
+ else
+ {
+ return false;
+ }
+}
+
+#endif
+/** @} */
+
+
+/******************************************************************************/
+// Implementation: Internal (static) functions
+/******************************************************************************/
+
+static bool gzp_tx_packet(const uint8_t* tx_packet, uint8_t length, uint8_t pipe)
+{
+ tx_complete = false;
+ tx_success = false;
+
+ if (nrf_gzll_add_packet_to_tx_fifo(pipe,(uint8_t *)tx_packet, length))
+ {
+ while (tx_complete == false)
+ {
+ __WFI();
+ }
+ return tx_success;
+ }
+ else
+ {
+ return false;
+ }
+}
+
+static gzp_tx_rx_trans_result_t gzp_tx_rx_transaction(const uint8_t *tx_packet, uint8_t tx_length, uint8_t *rx_dst, uint32_t *rx_length, uint8_t pipe)
+{
+
+ gzp_tx_rx_trans_result_t retval;
+ uint8_t fetch_packet[GZP_CMD_FETCH_RESP_PAYLOAD_LENGTH];
+ bool tx_packet_success;
+ bool fetch_success;
+ uint32_t local_rx_length = GZP_MAX_ACK_PAYLOAD_LENGTH;
+ uint32_t temp_lifetime;
+
+ nrf_gzp_flush_rx_fifo(pipe);
+
+ retval = GZP_TX_RX_FAILED_TO_SEND;
+
+ (void)nrf_gzll_disable();
+ while (nrf_gzll_is_enabled())
+ {}
+ temp_lifetime = nrf_gzll_get_sync_lifetime();
+ (void)nrf_gzll_set_sync_lifetime(GZP_TX_RX_TRANS_DELAY * 3); // 3 = RXPERIOD * 2 + margin
+ (void)nrf_gzll_enable();
+
+ tx_packet_success = gzp_tx_packet(tx_packet, tx_length, pipe);
+
+ if (tx_packet_success)
+ {
+ retval = GZP_TX_RX_NO_RESPONSE;
+
+ nrf_gzp_flush_rx_fifo(pipe);
+
+ fetch_packet[0] = (uint8_t)GZP_CMD_FETCH_RESP;
+
+ gzp_tick_sleep_rx_periods(GZP_TX_RX_TRANS_DELAY);
+
+ tx_packet_success = gzp_tx_packet(fetch_packet, GZP_CMD_FETCH_RESP_PAYLOAD_LENGTH, pipe);
+
+ if (tx_packet_success)
+ {
+ if (nrf_gzll_get_rx_fifo_packet_count(pipe))
+ {
+ local_rx_length = NRF_GZLL_CONST_MAX_PAYLOAD_LENGTH;
+ fetch_success = nrf_gzll_fetch_packet_from_rx_fifo(pipe, rx_dst, &local_rx_length);
+ }
+ else
+ {
+ fetch_success = false;
+ }
+
+ if (fetch_success)
+ {
+ retval = GZP_TX_RX_SUCCESS;
+ }
+ else
+ {
+ //print_string("GZP_TX_FETCH_FAILED\r\n");
+ }
+ }
+ else
+ {
+ //print_string("GZP_TX_FETCH_NO_ACK\r\n");
+ }
+ }
+
+ (void)nrf_gzll_disable();
+ while (nrf_gzll_is_enabled())
+ {}
+ (void)nrf_gzll_set_sync_lifetime(temp_lifetime);
+ (void)nrf_gzll_enable();
+
+ return retval;
+}
+
+#ifndef GZP_CRYPT_DISABLE
+
+static bool gzp_crypt_tx_transaction(const uint8_t *src, uint8_t length)
+{
+ uint8_t tx_packet[GZP_MAX_FW_PAYLOAD_LENGTH];
+ uint8_t rx_packet[GZP_MAX_ACK_PAYLOAD_LENGTH];
+ uint8_t tx_packet_length;
+
+ gzp_tx_rx_trans_result_t result;
+
+ tx_packet_length = length + (uint8_t)GZP_ENCRYPTED_USER_DATA_PACKET_OVERHEAD;
+
+ // Assemble tx packet
+ tx_packet[0] = (uint8_t)GZP_CMD_ENCRYPTED_USER_DATA;
+ gzp_add_validation_id(&tx_packet[GZP_CMD_ENCRYPTED_USER_DATA_VALIDATION_ID]);
+ memcpy(&tx_packet[GZP_CMD_ENCRYPTED_USER_DATA_PAYLOAD], (uint8_t*)src, length);
+
+ // Encrypt tx packet
+ if (gzp_id_req_pending)
+ {
+ gzp_crypt_select_key(GZP_ID_EXCHANGE);
+ }
+ else
+ {
+ gzp_crypt_select_key(GZP_DATA_EXCHANGE);
+ }
+ gzp_crypt(&tx_packet[1], &tx_packet[1], tx_packet_length - 1);
+
+ // If packet was successfully sent AND a response packet was received
+ result = gzp_tx_rx_transaction(tx_packet, tx_packet_length, rx_packet, NULL, GZP_DATA_PIPE);
+ if (result == GZP_TX_RX_SUCCESS)
+ {
+ if (rx_packet[0] == (uint8_t)GZP_CMD_ENCRYPTED_USER_DATA_RESP)
+ {
+ gzp_crypt(&rx_packet[GZP_CMD_ENCRYPTED_USER_DATA_RESP_VALIDATION_ID], &rx_packet[GZP_CMD_ENCRYPTED_USER_DATA_RESP_VALIDATION_ID], GZP_VALIDATION_ID_LENGTH);
+
+ // Validate response in order to know whether packet was correctly decrypted by host
+ if (gzp_validate_id(&rx_packet[GZP_CMD_ENCRYPTED_USER_DATA_RESP_VALIDATION_ID]))
+ {
+ // Update session token if normal operation (!gzp_id_req_pending)
+ if (!gzp_id_req_pending)
+ {
+ gzp_crypt_set_session_token(&rx_packet[GZP_CMD_ENCRYPTED_USER_DATA_RESP_SESSION_TOKEN]);
+ }
+ return true;
+ }
+ else
+ {
+ //print_string("GZP_CRYPT_TX_TRANS: Validation ID bad\r\n");
+ return false;
+ }
+ }
+ else
+ {
+ //print_string("GZP_CRYPT_TX_TRANS: Bad CMD. \r\n");
+ return false;
+ }
+ }
+ else
+ {
+ //print_string("GZP_CRYPT_TX_TRANS: gzp_tx_rx_trans not SUCCESS\r\n");
+ return false;
+ }
+}
+
+static bool gzp_key_update(void)
+{
+ uint8_t tx_packet[GZP_CMD_KEY_UPDATE_PAYLOAD_LENGTH], rx_packet[GZP_MAX_ACK_PAYLOAD_LENGTH];
+
+ // Send "prepare packet" to get session token to be used for key update
+ tx_packet[0] = (uint8_t)GZP_CMD_KEY_UPDATE_PREPARE;
+
+ // If packet was successfully sent AND a response packet was received
+ if (gzp_tx_rx_transaction(tx_packet, GZP_CMD_KEY_UPDATE_PREPARE_PAYLOAD_LENGTH, rx_packet, NULL, GZP_DATA_PIPE) == GZP_TX_RX_SUCCESS)
+ {
+ if (rx_packet[0] == (uint8_t)GZP_CMD_KEY_UPDATE_PREPARE_RESP)
+ {
+ gzp_crypt_set_session_token(&rx_packet[GZP_CMD_KEY_UPDATE_PREPARE_RESP_SESSION_TOKEN]);
+
+ // Build "key update" packet
+ tx_packet[0] = (uint8_t)GZP_CMD_KEY_UPDATE;
+ gzp_add_validation_id(&tx_packet[GZP_CMD_KEY_UPDATE_VALIDATION_ID]);
+ gzp_random_numbers_generate(&tx_packet[GZP_CMD_KEY_UPDATE_NEW_KEY], GZP_DYN_KEY_LENGTH);
+ gzp_crypt_set_dyn_key(&tx_packet[GZP_CMD_KEY_UPDATE_NEW_KEY]);
+
+ // Encrypt "key update packet"
+ gzp_crypt_select_key(GZP_KEY_EXCHANGE);
+ gzp_crypt(&tx_packet[1], &tx_packet[1], GZP_CMD_KEY_UPDATE_PAYLOAD_LENGTH - 1);
+
+ // Send "key update" packet
+ if (gzp_tx_packet(tx_packet, GZP_CMD_KEY_UPDATE_PAYLOAD_LENGTH, GZP_DATA_PIPE))
+ {
+ return true;
+ }
+ }
+ }
+
+ return false;
+}
+
+#endif
+
+void gzp_set_host_id(const uint8_t * id)
+{
+ memcpy(gzp_host_id, id, GZP_HOST_ID_LENGTH);
+}
+
+void gzp_get_host_id(uint8_t * dst_id)
+{
+ memcpy(dst_id, gzp_host_id, GZP_HOST_ID_LENGTH);
+}
+
+static void gzp_params_db_add(const uint8_t* src_element, uint8_t index)
+{
+ nrf_nvmc_write_bytes((GZP_PARAMS_DB_ADR + (index * GZP_PARAMS_DB_ELEMENT_SIZE)), src_element, (uint32_t)GZP_PARAMS_DB_ELEMENT_SIZE);
+}
+
+
+static void gzp_params_db_read(uint8_t* dst_element, uint8_t index)
+{
+ memcpy(dst_element,(uint8_t*)(GZP_PARAMS_DB_ADR + (index * GZP_PARAMS_DB_ELEMENT_SIZE)), GZP_PARAMS_DB_ELEMENT_SIZE);
+}
+
+
+static void gzp_index_db_add(uint8_t val)
+{
+ int16_t i;
+ uint8_t temp_val;
+ uint32_t addr;
+
+ // Search for unwritten loacation in index DB
+ for (i = 0; i < GZP_INDEX_DB_SIZE; i++)
+ {
+ temp_val = *(uint8_t*)(GZP_INDEX_DB_ADR + i);
+
+ // Lower nibble
+ if (i != (GZP_INDEX_DB_SIZE - 1))
+ {
+ if ((temp_val & 0x0f) == 0x0f)
+ {
+ temp_val = (temp_val & 0xf0) | val;
+ break;
+ }
+ // Upper nibble
+ else if ((temp_val & 0xf0) == 0xf0)
+ {
+ temp_val = (temp_val & 0x0f) | (val << 4);
+ break;
+ }
+ }
+ else
+ {
+ temp_val = (GZP_PARAMS_DB_MAX_ENTRIES << 4) | val;
+ break;
+ }
+ }
+
+ // Write index DB
+ addr = (GZP_INDEX_DB_ADR + i);
+ nrf_nvmc_write_byte(addr, temp_val);
+}
+
+static uint8_t gzp_index_db_read()
+{
+ uint8_t retval;
+ int16_t i;
+
+ // Search for previously written location
+ for (i = (GZP_INDEX_DB_SIZE - 1); i >= 0; i--)
+ {
+ retval = *(uint8_t*)(GZP_INDEX_DB_ADR + i);
+
+ if (retval != 0xff)
+ {
+ break;
+ }
+ }
+
+ if (retval == 0xff)
+ {
+ retval = GZP_PARAMS_DB_MAX_ENTRIES; // index db empty
+ }
+ else if ((retval & 0xf0) != 0xf0)
+ {
+ retval >>= 4;
+ }
+ else
+ {
+ retval &= 0x0f;
+ }
+
+ return retval;
+}
+
+int8_t gzp_get_pairing_status(void)
+{
+ uint8_t db_byte;
+ int8_t db_index;
+ int16_t i;
+ uint8_t temp_element[GZP_PARAMS_DB_ELEMENT_SIZE];
+ uint8_t default_host_id[GZP_HOST_ID_LENGTH];
+
+ db_index = -2;
+
+ // Populate default Host ID with F's.
+ for (i=0; i< GZP_HOST_ID_LENGTH; i++)
+ {
+ default_host_id[i] = 0xFF;
+ }
+
+ // Search for previously written location
+ for (i = (GZP_INDEX_DB_SIZE - 1); i >= 0; i--)
+ {
+ db_byte = *(uint8_t*)(GZP_INDEX_DB_ADR + i);
+
+ // Check if idx has been written to
+ if (db_byte != 0xff)
+ {
+ // Convert 4-bit nibble to index
+ if ((db_byte & 0xf0) != 0xf0)
+ {
+ db_byte = (db_byte >> 4) & 0x0f;
+ }
+ else
+ {
+ db_byte = db_byte & 0x0f;
+ }
+
+ // Retrieve database entry
+ gzp_params_db_read(temp_element, db_byte);
+
+ // Check if database entry is all F's
+ if ( memcmp(&temp_element[GZP_PARAMS_DB_ELEMENT_HOST_ID], default_host_id, GZP_HOST_ID_LENGTH) != 0)
+ {
+
+ db_index = db_byte;
+ }
+ else
+ {
+ db_index = -1;
+ }
+ break;
+ }
+ }
+
+ return db_index;
+}
+
+
+static bool gzp_index_db_full()
+{
+#if (GZP_INDEX_DB_SIZE != 0)
+ return ((*(uint8_t*)(GZP_INDEX_DB_ADR + (GZP_INDEX_DB_SIZE - 1)) != 0xff));
+#else
+ return true;
+#endif
+}
+
+//lint -save -e506 Constant value boolean
+static bool gzp_index_db_empty()
+{
+#if (GZP_INDEX_DB_SIZE != 0)
+ return ((GZP_INDEX_DB_SIZE == 0) || ((*(uint8_t*)(GZP_INDEX_DB_ADR)) == 0xff));
+#else
+ return true;
+#endif
+}
+//lint -restore
+
+static bool gzp_array_is_set(const uint8_t* src, uint8_t length)
+{
+ uint8_t i;
+
+ for (i = 0; i < length; i++)
+ {
+ if (*(src++) != 0xff)
+ {
+ return false;
+ }
+ }
+ return true;
+}
+
+static bool gzp_params_store(bool store_all)
+{
+ uint8_t i;
+ bool write_index_db = false;
+ bool write_param_db = false;
+ uint8_t new_db_index = 0;
+ uint8_t temp_element[GZP_PARAMS_DB_ELEMENT_SIZE];
+
+ // Search param DB to see if current setup exists
+ if (store_all)
+ {
+ // Search for: Current system address and host ID exists
+ for (i = 0; i < GZP_PARAMS_DB_MAX_ENTRIES; i++)
+ {
+ gzp_params_db_read(temp_element, i);
+
+ if (((memcmp(&temp_element[GZP_PARAMS_DB_ELEMENT_SYSTEM_ADDRESS], gzp_system_address, GZP_SYSTEM_ADDRESS_WIDTH)) == 0) && ((memcmp(&temp_element[GZP_PARAMS_DB_ELEMENT_HOST_ID], gzp_host_id, GZP_HOST_ID_LENGTH)) == 0))
+ {
+ write_index_db = true;
+ new_db_index = i;
+ break; // System address + host_id allready exists in database
+ }
+ }
+
+ // Search for: Current system address and cleared host ID
+ if (!write_index_db)
+ {
+ for (i = 0; i < GZP_PARAMS_DB_MAX_ENTRIES; i++)
+ {
+ gzp_params_db_read(temp_element, i);
+
+ if (((memcmp(&temp_element[GZP_PARAMS_DB_ELEMENT_SYSTEM_ADDRESS], gzp_system_address, GZP_SYSTEM_ADDRESS_WIDTH)) == 0) && \
+ (gzp_array_is_set(&temp_element[GZP_PARAMS_DB_ELEMENT_HOST_ID], GZP_HOST_ID_LENGTH)))
+ {
+ memcpy(&temp_element[GZP_PARAMS_DB_ELEMENT_HOST_ID], gzp_host_id, GZP_HOST_ID_LENGTH);
+ new_db_index = i;
+ write_index_db = true;
+ write_param_db = true;
+ break;
+ }
+ }
+ }
+
+ // Search for: Cleared system address and cleared host ID
+ if (!write_index_db)
+ {
+ for (i = 0; i < GZP_PARAMS_DB_MAX_ENTRIES; i++)
+ {
+ gzp_params_db_read(temp_element, i);
+
+ if (gzp_array_is_set(temp_element, GZP_PARAMS_DB_ELEMENT_SIZE))
+ {
+ memcpy(&temp_element[GZP_PARAMS_DB_ELEMENT_SYSTEM_ADDRESS], gzp_system_address, GZP_SYSTEM_ADDRESS_WIDTH);
+ memcpy(&temp_element[GZP_PARAMS_DB_ELEMENT_HOST_ID], gzp_host_id, GZP_HOST_ID_LENGTH);
+ new_db_index = i;
+ write_index_db = true;
+ write_param_db = true;
+ break;
+ }
+ }
+ }
+ }
+ else
+ {
+ // Search for: System address + any host ID
+ for (i = 0; i < GZP_PARAMS_DB_MAX_ENTRIES; i++)
+ {
+ gzp_params_db_read(temp_element, i);
+
+ if ((memcmp(&temp_element[GZP_PARAMS_DB_ELEMENT_SYSTEM_ADDRESS], gzp_system_address, GZP_SYSTEM_ADDRESS_WIDTH)) == 0)
+ {
+ //memcpy(&temp_element[GZP_PARAMS_DB_ELEMENT_HOST_ID], gzp_host_id, GZP_HOST_ID_LENGTH);
+ write_index_db = true;
+ new_db_index = i;
+ break;
+ }
+ }
+
+ // Search for: System address cleared
+ if (!write_index_db)
+ {
+ for (i = 0; i < GZP_PARAMS_DB_MAX_ENTRIES; i++)
+ {
+ gzp_params_db_read(temp_element, i);
+
+ if (gzp_array_is_set(&temp_element[GZP_PARAMS_DB_ELEMENT_SYSTEM_ADDRESS], GZP_SYSTEM_ADDRESS_WIDTH))
+ {
+ memcpy(&temp_element[GZP_PARAMS_DB_ELEMENT_SYSTEM_ADDRESS], gzp_system_address, GZP_SYSTEM_ADDRESS_WIDTH);
+ write_index_db = true;
+ write_param_db = true;
+ new_db_index = i;
+ break;
+ }
+ }
+ }
+ }
+
+ if (write_param_db)
+ {
+ gzp_params_db_add(temp_element, new_db_index);
+ }
+
+ if (write_index_db)
+ {
+ if (!gzp_index_db_full() && (new_db_index != gzp_index_db_read()) && (new_db_index != GZP_PARAMS_DB_MAX_ENTRIES))
+ {
+ gzp_index_db_add(new_db_index);
+ return true;
+ }
+ }
+
+ return false;
+}
+
+static bool gzp_params_restore(void)
+{
+ uint8_t i;
+ uint8_t temp_element[GZP_PARAMS_DB_ELEMENT_SIZE];
+
+ if (!gzp_index_db_full() && !gzp_index_db_empty())
+ {
+ i = gzp_index_db_read();
+
+ if (i < GZP_PARAMS_DB_MAX_ENTRIES)
+ {
+ gzp_params_db_read(temp_element, i);
+ memcpy(gzp_system_address, &temp_element[GZP_PARAMS_DB_ELEMENT_SYSTEM_ADDRESS], GZP_SYSTEM_ADDRESS_WIDTH);
+ gzp_set_host_id(&temp_element[GZP_PARAMS_DB_ELEMENT_HOST_ID]);
+ return true;
+ }
+ }
+
+ return false;
+}
+
+void gzp_delay_rx_periods(uint32_t rx_periods)
+{
+ nrf_delay_us(rx_periods * 2 * nrf_gzll_get_timeslot_period());
+}
+
+void gzp_tick_sleep_rx_periods(uint32_t rx_periods)
+{
+ nrf_gzll_clear_tick_count();
+
+ while (nrf_gzll_get_tick_count() < 2 * rx_periods)
+ {
+ __WFI();
+ }
+}
+
+
+void nrf_gzll_device_tx_success(uint32_t pipe, nrf_gzll_device_tx_info_t tx_info)
+{
+ latest_tx_info = tx_info;
+
+ tx_complete = true;
+ tx_success = true;
+}
+
+void nrf_gzll_device_tx_failed(uint32_t pipe, nrf_gzll_device_tx_info_t tx_info)
+{
+ latest_tx_info = tx_info;
+
+ tx_complete = true;
+ tx_success = false;
+}
+
+bool nrf_gzp_tx_complete(void)
+{
+ return tx_complete;
+}
+
+bool nrf_gzp_tx_success(void)
+{
+ return tx_success;
+}
+
+void nrf_gzp_reset_tx_complete()
+{
+ tx_complete = false;
+}
+
+void nrf_gzp_reset_tx_success()
+{
+ tx_success = false;
+}
+
+void nrf_gzll_disabled(void)
+{
+}
+
+void nrf_gzll_host_rx_data_ready(uint32_t pipe, nrf_gzll_host_rx_info_t rx_info)
+{
+}
+
+/** @} */
+/** @} */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/proprietary_rf/gzll/nrf_gzp_host.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/proprietary_rf/gzll/nrf_gzp_host.c
new file mode 100644
index 0000000..6e331a9
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/proprietary_rf/gzll/nrf_gzp_host.c
@@ -0,0 +1,821 @@
+/**
+ * Copyright (c) 2009 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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
+ * @brief Implementation of Gazell Pairing Library (gzp), Host functions.
+ * @defgroup gzp_source_host Gazell Pairing Host implementation
+ * @{
+ * @ingroup gzp_04_source
+ */
+
+
+#include "nrf_gzp.h"
+#include "nrf_gzll.h"
+#include <string.h>
+#include <stdint.h>
+#include <stdbool.h>
+#include "nrf_assert.h"
+#include "nrf_ecb.h"
+#include "nrf_nvmc.h"
+
+
+//lint -esym(40, GZP_PARAMS_STORAGE_ADR) "Undeclared identifier"
+#define GZP_PARAMS_DB_ADR GZP_PARAMS_STORAGE_ADR // Address of the GZP parameters flash page.
+
+
+/******************************************************************************/
+/** @name Typedefs
+ * @{ */
+/******************************************************************************/
+
+/**
+ * Definition of internal states.
+ */
+typedef enum
+{
+ GZP_ID_REQ_IDLE, ///< No Host ID request received from Device.
+ GZP_ID_REQ_PENDING, ///< Host ID request received and waiting on application to grant/reject.
+ GZP_ID_REQ_PENDING_AND_GRANTED, ///< Host ID request received and granted by application.
+ GZP_ID_REQ_PENDING_AND_REJECTED, ///< Host ID request received and rejected by application.
+} gzp_id_req_stat_t;
+
+/** @} */
+
+
+/******************************************************************************/
+/** @name Internal (static) function prototypes
+ * @{ */
+/******************************************************************************/
+
+
+/**
+ * Function for incrementing internal session counter.
+ */
+static void gzp_session_counter_inc(void);
+
+
+/**
+ * Function for reading value of internal session counter.
+ * @param dst Current session counter.
+ */
+static void gzp_get_session_counter(uint8_t* dst);
+
+
+/**
+ * Function processing received "system address request" from Device.
+ *
+ * @param gzp_req Pointer to RX payload containing system address request.
+ */
+static void gzp_process_address_req(uint8_t* gzp_req);
+
+
+/**
+ * Function to process Host ID request from device.
+ *
+ * The Host shall retrieve the Host ID from NVM, or shall generate if
+ * it does not yet exist.
+ *
+ * @param rx_payload Pointer to rx_payload contaning Host ID request.
+ */
+static void gzp_process_id_req(uint8_t* rx_payload);
+
+/**
+ * Function to process Host ID fetch request from Device.
+ *
+ * The Device fetches the Host ID after the Host has generated/retrieved
+ * the Host ID.
+ *
+ * @param rx_payload Pointer to rx_payload contaning Host ID fetch request.
+ */
+static void gzp_process_id_fetch(uint8_t* rx_payload);
+
+
+/**
+ * Function to process Key Update Prepare packet.
+ *
+ * Device requests the Session Token to be used for the Key Update request.
+ */
+static void gzp_process_key_update_prepare(void);
+
+
+/**
+ * Function to process Key Update packet.
+ *
+ * Device requests a Key Update and sends a new Dynamic Key. The Dynamic Key is
+ * updated on the Host.
+ *
+ * @param rx_payload Pointer to rx_payload containing Key Update request.
+ */
+static void gzp_process_key_update(uint8_t* rx_payload);
+
+
+/**
+ * Function to process received Encrypted User packet.
+ *
+ * @param rx_payload Pointer to rx_payload containing the encrypted user data.
+ * @param length Length of encrypted user data.
+ */
+static void gzp_process_encrypted_user_data(uint8_t* rx_payload, uint8_t length);
+
+
+/**
+ * Function to preload the payload for the next ACK.
+ *
+ * @param src Pointer to source payload.
+ * @param length Length of source payload.
+ * @param pipe Pipe for the ACK payload.
+ */
+static void gzp_preload_ack(uint8_t* src, uint8_t length, uint8_t pipe);
+
+
+/**
+ * Function for reading the Chip ID from non-volatile memory.
+ *
+ * The chip ID is used for the system address.
+ *
+ * If the Chip ID is not yet created a random Chip ID is created and
+ * written to non-volatile memory. Note that the term chip ID is used as
+ * the factory programmed chip sequence number was used for the system
+ * address in nRF24LU ICs.
+ *
+ * @param dst Address to copy Host ID to.
+ * @param[in] n Number of bytes in the Host ID.
+ */
+void gzp_host_chip_id_read(uint8_t *dst, uint8_t n);
+
+
+/**
+ * Function to set the Host ID.
+ *
+ * Writes the Host ID to non-volatile memory.
+ * @param src Address of the Host ID to copy from.
+ */
+static void gzp_set_host_id(const uint8_t* src);
+
+
+/**
+ * Function to request disabling of Gazell and wait for it to be disabled.
+ *
+ * Emulates legacy gzll_goto_idle().
+ */
+static void gzll_goto_idle(void);
+
+
+/**
+ * Flush all TX FIFOs.
+ *
+ * Emulates legacy gzll_tx_fifo_flush().
+ */
+static void gzll_tx_fifo_flush(void);
+
+
+/**
+ * Flush all RX FIFOs.
+ *
+ * Emulates legacy gzll_rx_fifo_flush().
+ */
+static void gzll_rx_fifo_flush(void);
+
+
+/**
+ * Set a timeout for the reception of packets on the Gazell Host.
+ *
+ * Emulates legacy Gazell function: gzll_set_param(GZLL_PARAM_RX_TIMEOUT, x).
+ *
+ * @param timeout Timeout in number of legacy "RX periods"
+ * (1 RX period = 2 timeslot periods).
+ */
+static void gzll_set_rx_timeout(uint32_t timeout);
+
+/** @} */
+
+
+/******************************************************************************/
+/** @name Internal (static) variabls
+ * @{ */
+/******************************************************************************/
+
+static gzp_id_req_stat_t gzp_id_req_stat; ///< Current state of Host ID request.
+static bool gzp_pairing_enabled_f; ///< True if Host is paired with a device.
+static bool gzp_address_exchanged_f; ///< True if Host has exchanged a system address with a device and thus pairing has begun.
+
+static uint8_t gzp_session_counter[GZP_SESSION_TOKEN_LENGTH]; ///< Session counter used for key generation and update.
+
+static bool gzp_encrypted_user_data[GZP_ENCRYPTED_USER_DATA_MAX_LENGTH]; ///< Placeholder for encrypted data from Device.
+static uint8_t gzp_encrypted_user_data_length; ///< Length of gzp_encrypted_user_data. Zero implies no data received.
+
+static nrf_gzll_host_rx_info_t prev_gzp_rx_info = {0, 0}; ///< RSSI and status of ACK payload transmission of previous Gazell packet.
+
+// Define Macro to make array initialization nicer
+#define REP4(X) X X X X
+
+#if defined(__ICCARM__)
+ #if GZP_PARAMS_DB_ADR == 0x1000
+ static const uint32_t database[GZP_DEVICE_PARAMS_STORAGE_SIZE/4] @ "gzp_dev_data"
+ #elif GZP_PARAMS_DB_ADR == 0x15000
+ static const uint32_t database[GZP_DEVICE_PARAMS_STORAGE_SIZE/4] @ "gzp_dev_data_sd"
+ #else
+ #error
+ #endif
+#else
+static const uint32_t database[GZP_DEVICE_PARAMS_STORAGE_SIZE / 4] __attribute__((at(GZP_PARAMS_DB_ADR)))
+#endif
+= {
+ #define STATIC_INIT_VALUE 0xFFFFFFFF
+ #define STATIC_INIT_COUNT (GZP_DEVICE_PARAMS_STORAGE_SIZE / 4)
+ #define INIT_1 STATIC_INIT_VALUE,
+ #define INIT_4 REP4(INIT_1)
+ #define INIT_16 REP4(INIT_4)
+ #define INIT_64 REP4(INIT_16)
+ #define INIT_256 REP4(INIT_64)
+ #define INIT_1024 REP4(INIT_256)
+
+ #if (STATIC_INIT_COUNT == 256)
+ INIT_256
+ #elif (STATIC_INIT_COUNT == 1024)
+ INIT_1024
+ #else
+ #error Gazell Pairing Library database not initialized properly!
+ #endif
+}; ///< Database for storing keys.
+
+/** @} */
+
+
+/******************************************************************************/
+// Implementation: Host-specific API functions
+/******************************************************************************/
+
+void gzp_init()
+{
+ uint8_t system_address[GZP_SYSTEM_ADDRESS_WIDTH];
+
+ // Read "chip id", of which 4 bytes (GZP_SYSTEM_ADDRESS_WIDTH)
+ // are used as system address
+ gzp_host_chip_id_read(system_address, GZP_SYSTEM_ADDRESS_WIDTH);
+
+ // Set up radio parameters (addresses and channel subset) from system_address
+ (void)gzp_update_radio_params(system_address);
+
+ // Only "data pipe" enabled by default
+
+ (void)nrf_gzll_set_rx_pipes_enabled(nrf_gzll_get_rx_pipes_enabled() | (1 << GZP_DATA_PIPE));
+
+ gzp_pairing_enabled_f = false;
+ gzp_address_exchanged_f = false;
+ gzp_id_req_stat = GZP_ID_REQ_IDLE;
+ gzp_encrypted_user_data_length = 0;
+
+ // Infinite RX timeout
+ gzll_set_rx_timeout(0);
+}
+
+void gzp_pairing_enable(bool enable)
+{
+ if (gzp_pairing_enabled_f != enable)
+ {
+ gzll_goto_idle();
+
+ if (enable)
+ {
+ (void)nrf_gzll_set_rx_pipes_enabled(nrf_gzll_get_rx_pipes_enabled() | (1 << GZP_PAIRING_PIPE));
+ }
+ else
+ {
+ (void)nrf_gzll_set_rx_pipes_enabled(nrf_gzll_get_rx_pipes_enabled() & ~(1 << GZP_PAIRING_PIPE));
+
+ gzp_id_req_stat = GZP_ID_REQ_IDLE;
+ }
+
+ gzp_pairing_enabled_f = enable;
+
+ gzll_rx_start();
+ }
+}
+
+void gzp_host_execute()
+{
+ bool gzp_packet_received = false;
+ uint32_t payload_length = NRF_GZLL_CONST_MAX_PAYLOAD_LENGTH;
+ uint8_t rx_payload[NRF_GZLL_CONST_MAX_PAYLOAD_LENGTH];
+
+ gzp_address_exchanged_f = false;
+
+ if (nrf_gzll_get_rx_fifo_packet_count(GZP_PAIRING_PIPE) > 0)
+ {
+ gzp_packet_received = nrf_gzll_fetch_packet_from_rx_fifo(GZP_PAIRING_PIPE, rx_payload, &payload_length);
+ }
+
+ if (!gzp_packet_received && (gzp_encrypted_user_data_length == 0))
+ {
+ if (nrf_gzll_get_rx_fifo_packet_count(GZP_DATA_PIPE) > 0)
+ {
+ gzp_packet_received = nrf_gzll_fetch_packet_from_rx_fifo(GZP_DATA_PIPE, rx_payload, &payload_length);
+ }
+ }
+
+ if (gzp_packet_received)
+ {
+ //lint -save -esym(644,rx_payload) //may not have been initialized
+ switch (rx_payload[0])
+ {
+ case GZP_CMD_HOST_ADDRESS_REQ:
+ gzp_process_address_req(rx_payload);
+ break;
+
+ #ifndef GZP_CRYPT_DISABLE
+
+ case GZP_CMD_HOST_ID_REQ:
+ gzp_process_id_req(rx_payload);
+ break;
+ case GZP_CMD_HOST_ID_FETCH:
+ gzp_process_id_fetch(rx_payload);
+ break;
+ case GZP_CMD_KEY_UPDATE_PREPARE:
+ gzp_process_key_update_prepare();
+ break;
+ case GZP_CMD_KEY_UPDATE:
+ gzp_process_key_update(rx_payload);
+ break;
+ case GZP_CMD_ENCRYPTED_USER_DATA:
+ gzp_process_encrypted_user_data(rx_payload, payload_length);
+ break;
+
+ #endif
+
+ case GZP_CMD_FETCH_RESP:
+ default:
+ break;
+ }
+ }
+
+ // Restart reception if "not proximity backoff" period has elapsed
+ if (!nrf_gzll_is_enabled())
+ {
+ gzll_set_rx_timeout(0);
+
+ if (gzp_pairing_enabled_f)
+ {
+ (void)nrf_gzll_set_rx_pipes_enabled(nrf_gzll_get_rx_pipes_enabled() | (1 << GZP_PAIRING_PIPE));
+ }
+
+ gzll_rx_start();
+ }
+
+ #ifndef GZP_CRYPT_DISABLE
+ gzp_session_counter_inc();
+ #endif
+}
+
+void gzll_rx_start(void)
+{
+ if (nrf_gzll_get_mode() != NRF_GZLL_MODE_HOST)
+ {
+ gzll_goto_idle();
+ (void)nrf_gzll_set_mode(NRF_GZLL_MODE_HOST);
+ }
+
+ if (!nrf_gzll_is_enabled())
+ {
+ (void)nrf_gzll_enable();
+ }
+}
+
+bool gzp_id_req_received()
+{
+ return (gzp_id_req_stat != GZP_ID_REQ_IDLE);
+}
+
+void gzp_id_req_reject()
+{
+ if (gzp_id_req_received())
+ {
+ gzp_id_req_stat = GZP_ID_REQ_PENDING_AND_REJECTED;
+ }
+}
+
+void gzp_id_req_grant()
+{
+ if (gzp_id_req_received())
+ {
+ gzp_id_req_stat = GZP_ID_REQ_PENDING_AND_GRANTED;
+ }
+}
+
+void gzp_id_req_cancel()
+{
+ if (gzp_id_req_received())
+ {
+ gzp_id_req_stat = GZP_ID_REQ_IDLE;
+ }
+}
+
+//-----------------------------------------------------------------------------
+// Implementation: Static functions
+//-----------------------------------------------------------------------------
+
+static void gzp_process_address_req(uint8_t* gzp_req)
+{
+ uint8_t temp_rx_pipes;
+ uint8_t pairing_resp[GZP_CMD_HOST_ADDRESS_RESP_PAYLOAD_LENGTH];
+ uint32_t rx_payload_length = NRF_GZLL_CONST_MAX_PAYLOAD_LENGTH;
+
+ gzp_address_exchanged_f = false;
+
+ gzll_goto_idle();
+ ASSERT(nrf_gzll_get_error_code() == NRF_GZLL_ERROR_CODE_NO_ERROR);
+
+ temp_rx_pipes = nrf_gzll_get_rx_pipes_enabled();
+ ASSERT(nrf_gzll_get_error_code() == NRF_GZLL_ERROR_CODE_NO_ERROR);
+
+ // If requesting Device within close proximity
+ if (prev_gzp_rx_info.rssi >= GZP_HOST_RX_POWER_THRESHOLD)
+ {
+ (void)nrf_gzll_set_rx_pipes_enabled(0);
+ ASSERT(nrf_gzll_get_error_code() == NRF_GZLL_ERROR_CODE_NO_ERROR);
+
+ gzll_set_rx_timeout(GZP_CLOSE_PROXIMITY_BACKOFF_RX_TIMEOUT);
+ ASSERT(nrf_gzll_get_error_code() == NRF_GZLL_ERROR_CODE_NO_ERROR);
+
+ gzll_rx_fifo_flush();
+ ASSERT(nrf_gzll_get_error_code() == NRF_GZLL_ERROR_CODE_NO_ERROR);
+
+ // Start "proximity" back off period
+ gzll_rx_start();
+ ASSERT(nrf_gzll_get_error_code() == NRF_GZLL_ERROR_CODE_NO_ERROR);
+
+ while (nrf_gzll_is_enabled())
+ {}
+
+ // Build pairing response packet
+ pairing_resp[0] = (uint8_t)GZP_CMD_HOST_ADDRESS_RESP;
+ gzp_host_chip_id_read(&pairing_resp[GZP_CMD_HOST_ADDRESS_RESP_ADDRESS], GZP_SYSTEM_ADDRESS_WIDTH);
+
+ (void)nrf_gzll_add_packet_to_tx_fifo(0, &pairing_resp[0], GZP_CMD_HOST_ADDRESS_RESP_PAYLOAD_LENGTH);
+ ASSERT(nrf_gzll_get_error_code() == NRF_GZLL_ERROR_CODE_NO_ERROR);
+ gzll_set_rx_timeout(GZP_STEP1_RX_TIMEOUT);
+
+ // Enable only pairing pipe when waiting for pairing request step 1
+ (void)nrf_gzll_set_rx_pipes_enabled((1 << GZP_PAIRING_PIPE));
+
+ gzll_rx_start();
+
+ while (nrf_gzll_is_enabled())
+ {
+ if (nrf_gzll_get_rx_fifo_packet_count(GZP_PAIRING_PIPE))
+ {
+ (void)nrf_gzll_fetch_packet_from_rx_fifo(GZP_PAIRING_PIPE, &gzp_req[0], &rx_payload_length);
+
+ // Validate step 1 of pairing request
+ if (gzp_req[0] == (uint8_t)GZP_CMD_HOST_ADDRESS_FETCH)
+ {
+ gzp_address_exchanged_f = true;
+ }
+ }
+ }
+
+ gzll_tx_fifo_flush();
+ gzll_rx_fifo_flush();
+
+ gzll_set_rx_timeout(0);
+
+ (void)nrf_gzll_set_rx_pipes_enabled(temp_rx_pipes);
+
+ // Return to normal operation
+ gzll_rx_start();
+ }
+ else
+ {
+ (void)nrf_gzll_set_rx_pipes_enabled(temp_rx_pipes & ~(1 << GZP_PAIRING_PIPE));
+
+ gzll_set_rx_timeout(GZP_NOT_PROXIMITY_BACKOFF_RX_TIMEOUT);
+
+ // Start "not proximity" backoff period
+ gzll_rx_start();
+ }
+}
+
+static void gzp_preload_ack(uint8_t* src, uint8_t length, uint8_t pipe)
+{
+ gzll_goto_idle();
+
+ gzll_tx_fifo_flush();
+
+ (void)nrf_gzll_add_packet_to_tx_fifo(pipe, src, length);
+
+ gzll_rx_start();
+}
+
+static void gzll_set_rx_timeout(uint32_t timeout)
+{
+ timeout *= 2; // * 2 as gzll_set_rx_timeout() takes RX_PERIODS as input, which equals 2 timeslots.
+ nrf_gzll_set_auto_disable(timeout);
+}
+
+bool gzp_address_exchanged()
+{
+ return gzp_address_exchanged_f;
+}
+
+#ifndef GZP_CRYPT_DISABLE
+
+bool gzp_crypt_user_data_received()
+{
+ return (gzp_encrypted_user_data_length > 0);
+}
+
+bool gzp_crypt_user_data_read(uint8_t* dst, uint8_t* length)
+{
+ if (gzp_encrypted_user_data_length > 0)
+ {
+ memcpy(dst, (void*)gzp_encrypted_user_data, gzp_encrypted_user_data_length);
+
+ if (length != NULL)
+ {
+ *length = gzp_encrypted_user_data_length;
+ }
+ gzp_encrypted_user_data_length = 0;
+
+ return true;
+ }
+ else
+ {
+ return false;
+ }
+}
+
+static void gzp_session_counter_inc()
+{
+ uint8_t i;
+
+ for (i = 0; i < GZP_SESSION_TOKEN_LENGTH; i++)
+ {
+ gzp_session_counter[i]++;
+ if (gzp_session_counter[i] != 0)
+ {
+ break;
+ }
+ }
+}
+
+static void gzp_get_session_counter(uint8_t* dst)
+{
+ memcpy(dst, (void*)gzp_session_counter, GZP_SESSION_TOKEN_LENGTH);
+}
+
+static void gzp_set_host_id(const uint8_t* src)
+{
+ if (*((uint8_t*)database) == 0xff)
+ {
+ nrf_nvmc_write_bytes(GZP_PARAMS_STORAGE_ADR + 1, src, GZP_HOST_ID_LENGTH);
+ nrf_nvmc_write_byte(GZP_PARAMS_STORAGE_ADR, 0x00);
+ }
+}
+
+void gzp_get_host_id(uint8_t *dst)
+{
+ memcpy(dst, (uint8_t*)GZP_PARAMS_STORAGE_ADR + 1, GZP_HOST_ID_LENGTH);
+}
+
+static void gzp_process_id_req(uint8_t* rx_payload)
+{
+ int i;
+ uint8_t temp_host_id[GZP_HOST_ID_LENGTH];
+
+ if (gzp_pairing_enabled_f)
+ {
+ if (!gzp_id_req_received())
+ {
+ gzp_crypt_set_session_token(&rx_payload[GZP_CMD_HOST_ID_REQ_SESSION_TOKEN]);
+ gzp_id_req_stat = GZP_ID_REQ_PENDING;
+ }
+
+ gzp_get_host_id(temp_host_id);
+
+ // Added:
+ for (i = 0; i < GZP_HOST_ID_LENGTH; i++)
+ {
+ if (temp_host_id[i] != 0xFF)
+ {
+ break;
+ }
+ }
+
+ if (i == GZP_HOST_ID_LENGTH) // If host not generated yet
+ {
+ gzp_get_session_counter(temp_host_id);
+
+#if (GZP_HOST_ID_LENGTH > GZP_SESSION_TOKEN_LENGTH)
+ gzp_xor_cipher(temp_host_id, temp_host_id, &rx_payload[GZP_CMD_HOST_ID_REQ_SESSION_TOKEN], GZP_SESSION_TOKEN_LENGTH);
+#else //(GZP_HOST_ID_LENGTH > GZP_SESSION_TOKEN_LENGTH)
+ gzp_xor_cipher(temp_host_id, temp_host_id, &rx_payload[GZP_CMD_HOST_ID_REQ_SESSION_TOKEN], GZP_HOST_ID_LENGTH);
+#endif //(GZP_HOST_ID_LENGTH > GZP_SESSION_TOKEN_LENGTH)
+
+ gzp_set_host_id(temp_host_id);
+ }
+ }
+}
+
+static void gzp_process_id_fetch(uint8_t* rx_payload)
+{
+ uint8_t tx_payload[GZP_CMD_HOST_ID_FETCH_RESP_PAYLOAD_LENGTH];
+
+ if (gzp_id_req_received())
+ {
+ gzp_crypt_select_key(GZP_ID_EXCHANGE);
+ gzp_crypt(&rx_payload[1], &rx_payload[1], GZP_CMD_HOST_ID_FETCH_PAYLOAD_LENGTH - 1);
+ if (gzp_validate_id(&rx_payload[GZP_CMD_HOST_ID_FETCH_VALIDATION_ID]))
+ {
+ switch (gzp_id_req_stat)
+ {
+ case GZP_ID_REQ_PENDING_AND_GRANTED:
+ tx_payload[GZP_CMD_HOST_ID_FETCH_RESP_STATUS] = (uint8_t)GZP_ID_RESP_GRANTED;
+ gzp_get_host_id(&tx_payload[GZP_CMD_HOST_ID_FETCH_RESP_HOST_ID]);
+ gzp_id_req_stat = GZP_ID_REQ_IDLE;
+ break;
+ case GZP_ID_REQ_PENDING_AND_REJECTED:
+ tx_payload[GZP_CMD_HOST_ID_FETCH_RESP_STATUS] = (uint8_t)GZP_ID_RESP_REJECTED;
+ gzp_id_req_stat = GZP_ID_REQ_IDLE;
+ break;
+ case GZP_ID_REQ_PENDING:
+ default:
+ tx_payload[GZP_CMD_HOST_ID_FETCH_RESP_STATUS] = (uint8_t)GZP_ID_RESP_PENDING;
+ break;
+ }
+
+ tx_payload[0] = (uint8_t)GZP_CMD_HOST_ID_FETCH_RESP;
+ gzp_add_validation_id(&tx_payload[GZP_CMD_HOST_ID_FETCH_RESP_VALIDATION_ID]);
+ gzp_crypt(&tx_payload[1], &tx_payload[1], GZP_CMD_HOST_ID_FETCH_RESP_PAYLOAD_LENGTH - 1);
+
+ ASSERT(nrf_gzll_get_error_code() == NRF_GZLL_ERROR_CODE_NO_ERROR);
+ gzp_preload_ack(tx_payload, GZP_CMD_HOST_ID_FETCH_RESP_PAYLOAD_LENGTH, GZP_DATA_PIPE);
+ ASSERT(nrf_gzll_get_error_code() == NRF_GZLL_ERROR_CODE_NO_ERROR);
+ }
+ }
+}
+
+static void gzp_process_key_update_prepare()
+{
+ uint8_t tx_payload[GZP_CMD_KEY_UPDATE_PREPARE_RESP_PAYLOAD_LENGTH];
+
+ tx_payload[0] = (uint8_t)GZP_CMD_KEY_UPDATE_PREPARE_RESP;
+
+ gzp_get_session_counter(&tx_payload[GZP_CMD_KEY_UPDATE_PREPARE_RESP_SESSION_TOKEN]);
+
+ // Update session token if no ID request is pending
+ if (!gzp_id_req_received())
+ {
+ gzp_crypt_set_session_token(&tx_payload[GZP_CMD_KEY_UPDATE_PREPARE_RESP_SESSION_TOKEN]);
+ }
+
+ gzp_preload_ack(tx_payload, GZP_CMD_KEY_UPDATE_PREPARE_RESP_PAYLOAD_LENGTH, GZP_DATA_PIPE);
+ ASSERT(nrf_gzll_get_error_code() == NRF_GZLL_ERROR_CODE_NO_ERROR);
+}
+
+static void gzp_process_key_update(uint8_t* rx_payload)
+{
+ gzp_crypt_select_key(GZP_KEY_EXCHANGE);
+ gzp_crypt(&rx_payload[1], &rx_payload[1], GZP_CMD_KEY_UPDATE_PAYLOAD_LENGTH - 1);
+ if (gzp_validate_id(&rx_payload[GZP_CMD_KEY_UPDATE_VALIDATION_ID]))
+ {
+ gzp_crypt_set_dyn_key(&rx_payload[GZP_CMD_KEY_UPDATE_NEW_KEY]);
+ }
+}
+
+static void gzp_process_encrypted_user_data(uint8_t* rx_payload, uint8_t length)
+{
+ uint8_t tx_payload[GZP_CMD_ENCRYPTED_USER_DATA_RESP_PAYLOAD_LENGTH];
+
+ if (gzp_id_req_received())
+ {
+ gzp_crypt_select_key(GZP_ID_EXCHANGE);
+ }
+ else
+ {
+ gzp_crypt_select_key(GZP_DATA_EXCHANGE);
+ }
+
+ gzp_crypt(&rx_payload[1], &rx_payload[1], length - 1);
+ if (gzp_validate_id(&rx_payload[GZP_CMD_ENCRYPTED_USER_DATA_VALIDATION_ID]))
+ {
+ gzp_encrypted_user_data_length = length - GZP_ENCRYPTED_USER_DATA_PACKET_OVERHEAD;
+ memcpy((void*)gzp_encrypted_user_data, &rx_payload[GZP_CMD_ENCRYPTED_USER_DATA_PAYLOAD], gzp_encrypted_user_data_length);
+ }
+
+ // Build response packet
+ tx_payload[0] = (uint8_t)GZP_CMD_ENCRYPTED_USER_DATA_RESP;
+ gzp_add_validation_id(&tx_payload[GZP_CMD_ENCRYPTED_USER_DATA_RESP_VALIDATION_ID]);
+ gzp_crypt(&tx_payload[GZP_CMD_ENCRYPTED_USER_DATA_RESP_VALIDATION_ID], &tx_payload[GZP_CMD_ENCRYPTED_USER_DATA_RESP_VALIDATION_ID], GZP_VALIDATION_ID_LENGTH);
+ gzp_get_session_counter(&tx_payload[GZP_CMD_ENCRYPTED_USER_DATA_RESP_SESSION_TOKEN]);
+
+ // Update "session token" only if no ID request is pending
+ if (!gzp_id_req_received())
+ {
+ gzp_crypt_set_session_token(&tx_payload[GZP_CMD_ENCRYPTED_USER_DATA_RESP_SESSION_TOKEN]);
+ }
+
+ ASSERT(nrf_gzll_get_error_code() == NRF_GZLL_ERROR_CODE_NO_ERROR);
+ gzp_preload_ack(tx_payload, GZP_CMD_ENCRYPTED_USER_DATA_RESP_PAYLOAD_LENGTH, GZP_DATA_PIPE);
+ ASSERT(nrf_gzll_get_error_code() == NRF_GZLL_ERROR_CODE_NO_ERROR);
+}
+
+//-----------------------------------------------------------------------------
+// Function added during LE1 -> nRF51 port
+//-----------------------------------------------------------------------------
+
+static void gzll_goto_idle()
+{
+ nrf_gzll_disable();
+ while (nrf_gzll_is_enabled())
+ {}
+}
+
+static void gzll_tx_fifo_flush(void)
+{
+ int i;
+
+ for (i = 0; i < NRF_GZLL_CONST_PIPE_COUNT; i++)
+ {
+ (void)nrf_gzll_flush_tx_fifo(i);
+ }
+}
+
+static void gzll_rx_fifo_flush(void)
+{
+ int i;
+
+ for (i = 0; i < NRF_GZLL_CONST_PIPE_COUNT; i++)
+ {
+ (void)nrf_gzll_flush_rx_fifo(i);
+ }
+}
+
+
+/******************************************************************************/
+// Implementation: Gazell callback functions
+/******************************************************************************/
+
+void nrf_gzll_device_tx_failed(uint32_t pipe, nrf_gzll_device_tx_info_t tx_info)
+{
+}
+
+
+void nrf_gzll_device_tx_success(uint32_t pipe, nrf_gzll_device_tx_info_t tx_info)
+{
+}
+
+
+void nrf_gzll_disabled(void)
+{
+}
+
+
+void nrf_gzll_host_rx_data_ready(uint32_t pipe, nrf_gzll_host_rx_info_t rx_info)
+{
+ if (pipe == GZP_PAIRING_PIPE)
+ {
+ prev_gzp_rx_info = rx_info;
+ }
+}
+
+/** @} */
+/** @} */
+
+#endif
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/proprietary_rf/gzll/nrf_gzp_host_nrf5x.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/proprietary_rf/gzll/nrf_gzp_host_nrf5x.c
new file mode 100644
index 0000000..b78c34c
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/proprietary_rf/gzll/nrf_gzp_host_nrf5x.c
@@ -0,0 +1,74 @@
+/**
+ * Copyright (c) 2009 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#include "nrf_gzp.h"
+#include "nrf_nvmc.h"
+
+/**
+ * @file
+ * @brief Implementation of Gazell Pairing Library (gzp), nRF5x specific Host functions.
+ * @defgroup gzp_source_host_nrf5x Gazell Pairing Host nRF5x specific implementation
+ * @{
+ * @ingroup gzp_04_source
+ */
+
+
+void gzp_host_chip_id_read(uint8_t *dst, uint8_t n)
+{
+ uint8_t i;
+ uint8_t random_number;
+
+ if ( *((uint8_t*)(GZP_PARAMS_STORAGE_ADR + GZP_HOST_ID_LENGTH + 1)) == 0xff)
+ {
+ nrf_nvmc_write_byte((GZP_PARAMS_STORAGE_ADR + GZP_HOST_ID_LENGTH + 1) , 0x00);
+
+ for (i = 0; i < n; i++)
+ {
+ gzp_random_numbers_generate(&random_number, 1);
+ nrf_nvmc_write_byte((GZP_PARAMS_STORAGE_ADR + GZP_HOST_ID_LENGTH + 2 + i) , random_number);
+ }
+ }
+
+ for (i = 0; i < n; i++)
+ {
+ *(dst++) = *((uint8_t*)(GZP_PARAMS_STORAGE_ADR + GZP_HOST_ID_LENGTH + 2 + i));
+ }
+}
+
+/** @} */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/sdk_validation.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/sdk_validation.h
new file mode 100644
index 0000000..738b56e
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/sdk_validation.h
@@ -0,0 +1,305 @@
+/**
+ * Copyright (c) 2016 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#ifndef SDK_VALIDATION_H
+#define SDK_VALIDATION_H
+
+#include "nrf_peripherals.h"
+#include "sdk_config.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+// Validate peripheral availibility
+
+#if ((defined(SAADC_ENABLED)) && (SAADC_ENABLED > 0) && (!defined(SAADC_PRESENT)))
+#error "SAADC not present in selected MCU."
+#endif
+
+#if ((defined(ADC_ENABLED)) && (ADC_ENABLED > 0) && (!defined(ADC_PRESENT)))
+#error "SAADC not present in selected MCU."
+#endif
+
+#if ((defined(I2S_ENABLED)) && (I2S_ENABLED > 0) && (!defined(I2S_PRESENT)))
+#error "I2S not present in selected MCU."
+#endif
+
+#if ((defined(COMP_ENABLED)) && (COMP_ENABLED > 0) && (!defined(COMP_PRESENT)))
+#error "COMP not present in selected MCU."
+#endif
+
+#if ((defined(LPCOMP_ENABLED)) && (LPCOMP_ENABLED > 0) && (!defined(LPCOMP_PRESENT)))
+#error "LPCOMP not present in selected MCU."
+#endif
+
+#if ((defined(SPIS0_ENABLED)) && (SPIS0_ENABLED > 0) && (!defined(SPIS_PRESENT)))
+#error "SPIS0 instance not present in selected MCU."
+#endif
+
+#if ((defined(EGU_ENABLED)) && (EGU_ENABLED > 0) && (!defined(EGU_PRESENT)))
+#error "EGU instance not present in selected MCU."
+#endif
+
+#if ((defined(NFC_HAL_ENABLED)) && (NFC_HAL_ENABLED > 0) && (!defined(NFCT_PRESENT)))
+#error "NFC TAG not present in selected MCU."
+#endif
+
+// Validate count of instances
+
+#if ((defined(RTC2_ENABLED)) && (RTC2_ENABLED > 0) && (RTC_COUNT < 2))
+#error "RTC2 not present in selected MCU."
+#endif
+
+#if ((defined(TWIS0_ENABLED) || defined(TWIS1_ENABLED)) &&\
+ ((TWIS0_ENABLED + TWIS1_ENABLED) > 0) &&\
+ (!defined(TWIS_PRESENT)))
+#error "TWIS not present in selected MCU."
+#endif
+
+#if ((defined(SPIS2_ENABLED)) && (SPIS2_ENABLED > 0) && (SPIS_COUNT < 2))
+#error "SPI2/SPIS2 instance not present in selected MCU."
+#endif
+
+#if ((defined(TIMER3_ENABLED) || defined(TIMER4_ENABLED)) &&\
+ ((TIMER3_ENABLED + TIMER4_ENABLED ) > 0) &&\
+ (TIMER_COUNT < 5))
+#error "TIMER3 and TIMER4 not present in selected MCU."
+#endif
+
+// Validate peripheral sharing feature
+#if !NRFX_CHECK(NRFX_PRS_ENABLED)
+
+#if ((defined(TWIM0_ENABLED) && defined(TWIS0_ENABLED)) &&\
+ ((TWIM0_ENABLED + TWIS0_ENABLED) > 1))
+#error "Peripherals overlap. TWIM0, TWIS0 - only one of these can be enabled."
+#endif
+
+#if ((defined(TWIM0_ENABLED) && defined(SPIM0_ENABLED)) &&\
+ ((TWIM0_ENABLED + SPIM0_ENABLED) > 1))
+#error "Peripherals overlap. TWIM0, SPIM0 - only one of these can be enabled."
+#endif
+
+#if ((defined(TWIM0_ENABLED) && defined(SPIS0_ENABLED)) &&\
+ ((TWIM0_ENABLED + SPIS0_ENABLED) > 1))
+#error "Peripherals overlap. TWIM0, SPIS0 - only one of these can be enabled."
+#endif
+
+#if ((defined(TWIM0_ENABLED) && defined(SPI0_ENABLED)) &&\
+ ((TWIM0_ENABLED + SPI0_ENABLED) > 1))
+#error "Peripherals overlap. TWIM0, SPI0 - only one of these can be enabled."
+#endif
+
+#if ((defined(TWIM0_ENABLED) && defined(TWI0_ENABLED)) &&\
+ ((TWIM0_ENABLED + TWI0_ENABLED) > 1))
+#error "Peripherals overlap. TWIM0, TWI0 - only one of these can be enabled."
+#endif
+
+#if ((defined(TWIS0_ENABLED) && defined(SPIM0_ENABLED)) &&\
+ ((TWIS0_ENABLED + SPIM0_ENABLED) > 1))
+#error "Peripherals overlap. TWIS0, SPIM0 - only one of these can be enabled."
+#endif
+
+#if ((defined(TWIS0_ENABLED) && defined(SPIS0_ENABLED)) &&\
+ ((TWIS0_ENABLED + SPIS0_ENABLED) > 1))
+#error "Peripherals overlap. TWIS0, SPIS0 - only one of these can be enabled."
+#endif
+
+#if ((defined(TWIS0_ENABLED) && defined(SPI0_ENABLED)) &&\
+ ((TWIS0_ENABLED + SPI0_ENABLED) > 1))
+#error "Peripherals overlap. TWIS0, SPI0 - only one of these can be enabled."
+#endif
+
+#if ((defined(TWIS0_ENABLED) && defined(TWI0_ENABLED)) &&\
+ ((TWIS0_ENABLED + TWI0_ENABLED) > 1))
+#error "Peripherals overlap. TWIS0, TWI0 - only one of these can be enabled."
+#endif
+
+#if ((defined(SPIM0_ENABLED) && defined(SPIS0_ENABLED)) &&\
+ ((SPIM0_ENABLED + SPIS0_ENABLED) > 1))
+#error "Peripherals overlap. SPIM0, SPIS0 - only one of these can be enabled."
+#endif
+
+#if ((defined(SPIM0_ENABLED) && defined(SPI0_ENABLED)) &&\
+ ((SPIM0_ENABLED + SPI0_ENABLED) > 1))
+#error "Peripherals overlap. SPIM0, SPI0 - only one of these can be enabled."
+#endif
+
+#if ((defined(SPIM0_ENABLED) && defined(TWI0_ENABLED)) &&\
+ ((SPIM0_ENABLED + TWI0_ENABLED) > 1))
+#error "Peripherals overlap. SPIM0, TWI0 - only one of these can be enabled."
+#endif
+
+#if ((defined(SPIS0_ENABLED) && defined(SPI0_ENABLED)) &&\
+ ((SPIS0_ENABLED + SPI0_ENABLED) > 1))
+#error "Peripherals overlap. SPIS0, SPI0 - only one of these can be enabled."
+#endif
+
+#if ((defined(SPIS0_ENABLED) && defined(TWI0_ENABLED)) &&\
+ ((SPIS0_ENABLED + TWI0_ENABLED) > 1))
+#error "Peripherals overlap. SPIS0, TWI0 - only one of these can be enabled."
+#endif
+
+#if ((defined(SPI0_ENABLED) && defined(TWI0_ENABLED)) &&\
+ ((SPI0_ENABLED + TWI0_ENABLED) > 1))
+#error "Peripherals overlap. SPI0, TWI0 - only one of these can be enabled."
+#endif
+
+#if ((defined(TWIM1_ENABLED) && defined(TWIS1_ENABLED)) &&\
+ ((TWIM1_ENABLED + TWIS1_ENABLED) > 1))
+#error "Peripherals overlap. TWIM1, TWIS1 - only one of these can be enabled."
+#endif
+
+#if ((defined(TWIM1_ENABLED) && defined(SPIM1_ENABLED)) &&\
+ ((TWIM1_ENABLED + SPIM1_ENABLED) > 1))
+#error "Peripherals overlap. TWIM1, SPIM1 - only one of these can be enabled."
+#endif
+
+#if ((defined(TWIM1_ENABLED) && defined(SPIS1_ENABLED)) &&\
+ ((TWIM1_ENABLED + SPIS1_ENABLED) > 1))
+#error "Peripherals overlap. TWIM1, SPIS1 - only one of these can be enabled."
+#endif
+
+#if ((defined(TWIM1_ENABLED) && defined(SPI1_ENABLED)) &&\
+ ((TWIM1_ENABLED + SPI1_ENABLED) > 1))
+#error "Peripherals overlap. TWIM1, SPI1 - only one of these can be enabled."
+#endif
+
+#if ((defined(TWIM1_ENABLED) && defined(TWI1_ENABLED)) &&\
+ ((TWIM1_ENABLED + TWI1_ENABLED) > 1))
+#error "Peripherals overlap. TWIM1, TWI1 - only one of these can be enabled."
+#endif
+
+#if ((defined(TWIS1_ENABLED) && defined(SPIM1_ENABLED)) &&\
+ ((TWIS1_ENABLED + SPIM1_ENABLED) > 1))
+#error "Peripherals overlap. TWIS1, SPIM1 - only one of these can be enabled."
+#endif
+
+#if ((defined(TWIS1_ENABLED) && defined(SPIS1_ENABLED)) &&\
+ ((TWIS1_ENABLED + SPIS1_ENABLED) > 1))
+#error "Peripherals overlap. TWIS1, SPIS1 - only one of these can be enabled."
+#endif
+
+#if ((defined(TWIS1_ENABLED) && defined(SPI1_ENABLED)) &&\
+ ((TWIS1_ENABLED + SPI1_ENABLED) > 1))
+#error "Peripherals overlap. TWIS1, SPI1 - only one of these can be enabled."
+#endif
+
+#if ((defined(TWIS1_ENABLED) && defined(TWI1_ENABLED)) &&\
+ ((TWIS1_ENABLED + TWI1_ENABLED) > 1))
+#error "Peripherals overlap. TWIS1, TWI1 - only one of these can be enabled."
+#endif
+
+#if ((defined(SPIM1_ENABLED) && defined(SPIS1_ENABLED)) &&\
+ ((SPIM1_ENABLED + SPIS1_ENABLED) > 1))
+#error "Peripherals overlap. SPIM1, SPIS1 - only one of these can be enabled."
+#endif
+
+#if ((defined(SPIM1_ENABLED) && defined(SPI1_ENABLED)) &&\
+ ((SPIM1_ENABLED + SPI1_ENABLED) > 1))
+#error "Peripherals overlap. SPIM1, SPI1 - only one of these can be enabled."
+#endif
+
+#if ((defined(SPIM1_ENABLED) && defined(TWI1_ENABLED)) &&\
+ ((SPIM1_ENABLED + TWI1_ENABLED) > 1))
+#error "Peripherals overlap. SPIM1, TWI1 - only one of these can be enabled."
+#endif
+
+#if ((defined(SPIS1_ENABLED) && defined(SPI1_ENABLED)) &&\
+ ((SPIS1_ENABLED + SPI1_ENABLED) > 1))
+#error "Peripherals overlap. SPIS1, SPI1 - only one of these can be enabled."
+#endif
+
+#if ((defined(SPIS1_ENABLED) && defined(TWI1_ENABLED)) &&\
+ ((SPIS1_ENABLED + TWI1_ENABLED) > 1))
+#error "Peripherals overlap. SPIS1, TWI1 - only one of these can be enabled."
+#endif
+
+#if ((defined(SPI1_ENABLED) && defined(TWI1_ENABLED)) &&\
+ ((SPI1_ENABLED + TWI1_ENABLED) > 1))
+#error "Peripherals overlap. SPI1, TWI1 - only one of these can be enabled."
+#endif
+
+#if ((defined(SPI2_ENABLED) && defined(SPIS2_ENABLED)) &&\
+ ((SPI2_ENABLED + SPIS2_ENABLED) > 1))
+#error "Peripherals overlap. SPI2, SPIS2 - only one of these can be enabled."
+#endif
+
+#if ((defined(SPIM2_ENABLED) && defined(SPIS2_ENABLED)) &&\
+ ((SPI2_ENABLED + SPIS2_ENABLED) > 1))
+#error "Peripherals overlap. SPIM2, SPIS2 - only one of these can be enabled."
+#endif
+
+#if ((defined(SPIM2_ENABLED) && defined(SPI2_ENABLED)) &&\
+ ((SPI2_ENABLED + SPIS2_ENABLED) > 1))
+#error "Peripherals overlap. SPIM2, SPI2 - only one of these can be enabled."
+#endif
+
+#endif // !NRFX_CHECK(NRFX_PRS_ENABLED)
+
+#ifdef NFCT_PRESENT
+
+#if ((defined(NFC_HAL_ENABLED) && defined(CLOCK_ENABLED)) &&\
+ ((NFC_HAL_ENABLED) && (!CLOCK_ENABLED)))
+#error "NFC_HAL requires CLOCK to work. NFC_HAL can not be enabled without CLOCK."
+#endif
+
+#if ((defined(NFC_HAL_ENABLED) && defined(TIMER4_ENABLED)) &&\
+ ((NFC_HAL_ENABLED + TIMER4_ENABLED) > 1))
+#error "TIMER4 is used by NFC_HAL. NFC_HAL, TIMER4 - only one of these can be enabled."
+#endif
+
+#endif
+// Complex driver validation
+#ifdef LPCOMP_PRESENT
+
+#if ((defined(COMP_ENABLED) && defined(LPCOMP_ENABLED)) && \
+ (!NRFX_CHECK(NRFX_PRS_ENABLED)) && \
+ ((COMP_ENABLED + LPCOMP_ENABLED) > 1))
+#error "Peripherals overlap. COMP, LPCOMP - only one of these can be enabled."
+#endif
+
+#endif
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // SDK_VALIDATION_H
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/application/codecs/ant/middleware/app_mw_ant.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/application/codecs/ant/middleware/app_mw_ant.c
new file mode 100644
index 0000000..016fa67
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/application/codecs/ant/middleware/app_mw_ant.c
@@ -0,0 +1,1868 @@
+/**
+ * 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+
+#include <stdint.h>
+#include "ant_interface.h"
+#include "ble_serialization.h"
+#include "ant_app.h"
+#include "ser_sd_transport.h"
+#include "app_error.h"
+
+static void * mp_out_params[3];
+
+static void tx_buf_alloc(uint8_t * * p_data, uint32_t * p_len)
+{
+ uint32_t err_code;
+ uint16_t len16;
+
+ do
+ {
+ err_code = ser_sd_transport_tx_alloc(p_data, &len16);
+ }
+ while (err_code != NRF_SUCCESS);
+
+ *p_data[0] = SER_PKT_TYPE_ANT_CMD;
+ *p_len = (uint32_t)len16 - 1;
+}
+
+/**@brief Command response callback function for @ref sd_ant_enable ANT command.
+ *
+ * Callback for decoding the output parameters and the command response return code.
+ *
+ * @param[in] p_buffer Pointer to begin of command response buffer.
+ * @param[in] length Length of data in bytes.
+ *
+ * @return Decoded command response return code.
+ */
+static uint32_t enable_rsp_dec(const uint8_t * p_buffer, uint16_t length)
+{
+ uint32_t result_code;
+
+ const uint32_t err_code = ant_enable_rsp_dec(p_buffer,
+ length,
+ &result_code);
+
+ //@note: Should never fail.
+
+ APP_ERROR_CHECK(err_code);
+
+ return result_code;
+}
+
+uint32_t sd_ant_enable(ANT_ENABLE * const p_ant_enable)
+{
+ uint8_t * p_buffer;
+ uint32_t buffer_length;
+
+ tx_buf_alloc(&p_buffer, &buffer_length);
+
+ const uint32_t err_code = ant_enable_req_enc(p_ant_enable,
+ &(p_buffer[1]),
+ &buffer_length);
+ APP_ERROR_CHECK(err_code);
+
+ //@note: Increment buffer length as internally managed packet type field must be included.
+ return ser_sd_transport_cmd_write(p_buffer,
+ (++buffer_length),
+ enable_rsp_dec);
+
+}
+
+/**@brief Command response callback function for @ref sd_ant_channel_assign ANT command.
+ *
+ * Callback for decoding the output parameters and the command response return code.
+ *
+ * @param[in] p_buffer Pointer to begin of command response buffer.
+ * @param[in] length Length of data in bytes.
+ *
+ * @return Decoded command response return code.
+ */
+static uint32_t channel_assign_rsp_dec(const uint8_t * p_buffer, uint16_t length)
+{
+ uint32_t result_code;
+
+ const uint32_t err_code = ant_channel_assign_rsp_dec(p_buffer,
+ length,
+ &result_code);
+ //@note: Should never fail.
+
+ APP_ERROR_CHECK(err_code);
+
+ return result_code;
+}
+
+uint32_t sd_ant_channel_assign(uint8_t channel, uint8_t channel_type, uint8_t network, uint8_t ext_assign)
+{
+ uint8_t * p_buffer;
+ uint32_t buffer_length;
+
+ tx_buf_alloc(&p_buffer, &buffer_length);
+
+ const uint32_t err_code = ant_channel_assign_req_enc(channel,
+ channel_type,
+ network,
+ ext_assign,
+ &(p_buffer[1]),
+ &buffer_length);
+ APP_ERROR_CHECK(err_code);
+
+ //@note: Increment buffer length as internally managed packet type field must be included.
+ return ser_sd_transport_cmd_write(p_buffer,
+ (++buffer_length),
+ channel_assign_rsp_dec);
+
+}
+
+/**@brief Command response callback function for @ref sd_ant_channel_open_with_offset ANT command.
+ *
+ * Callback for decoding the output parameters and the command response return code.
+ *
+ * @param[in] p_buffer Pointer to begin of command response buffer.
+ * @param[in] length Length of data in bytes.
+ *
+ * @return Decoded command response return code.
+ */
+static uint32_t channel_open_with_offset_rsp_dec(const uint8_t * p_buffer, uint16_t length)
+{
+ uint32_t result_code;
+
+ const uint32_t err_code = ant_channel_open_with_offset_rsp_dec(p_buffer,
+ length,
+ &result_code);
+ //@note: Should never fail.
+
+ APP_ERROR_CHECK(err_code);
+
+ return result_code;
+}
+
+uint32_t sd_ant_channel_open_with_offset(uint8_t channel, uint16_t usOffset)
+{
+ uint8_t * p_buffer;
+ uint32_t buffer_length;
+
+ tx_buf_alloc(&p_buffer, &buffer_length);
+
+ const uint32_t err_code = ant_channel_open_with_offset_req_enc(channel,
+ usOffset,
+ &(p_buffer[1]),
+ &buffer_length);
+ APP_ERROR_CHECK(err_code);
+
+ //@note: Increment buffer length as internally managed packet type field must be included.
+ return ser_sd_transport_cmd_write(p_buffer,
+ (++buffer_length),
+ channel_open_with_offset_rsp_dec);
+
+}
+
+/**@brief Command response callback function for @ref sd_ant_channel_id_set ANT command.
+ *
+ * Callback for decoding the output parameters and the command response return code.
+ *
+ * @param[in] p_buffer Pointer to begin of command response buffer.
+ * @param[in] length Length of data in bytes.
+ *
+ * @return Decoded command response return code.
+ */
+static uint32_t channel_id_set_rsp_dec(const uint8_t * p_buffer, uint16_t length)
+{
+ uint32_t result_code;
+
+ const uint32_t err_code = ant_channel_id_set_rsp_dec(p_buffer,
+ length,
+ &result_code);
+ //@note: Should never fail.
+
+ APP_ERROR_CHECK(err_code);
+
+ return result_code;
+}
+
+uint32_t sd_ant_channel_id_set (uint8_t channel, uint16_t device_number, uint8_t device_type, uint8_t transmit_type)
+{
+ uint8_t * p_buffer;
+ uint32_t buffer_length;
+
+ tx_buf_alloc(&p_buffer, &buffer_length);
+
+ const uint32_t err_code = ant_channel_id_set_req_enc(channel,
+ device_number,
+ device_type,
+ transmit_type,
+ &(p_buffer[1]),
+ &buffer_length);
+ APP_ERROR_CHECK(err_code);
+
+ //@note: Increment buffer length as internally managed packet type field must be included.
+ return ser_sd_transport_cmd_write(p_buffer,
+ (++buffer_length),
+ channel_id_set_rsp_dec);
+
+}
+
+/**@brief Command response callback function for @ref sd_ant_channel_period_set ANT command.
+ *
+ * Callback for decoding the output parameters and the command response return code.
+ *
+ * @param[in] p_buffer Pointer to begin of command response buffer.
+ * @param[in] length Length of data in bytes.
+ *
+ * @return Decoded command response return code.
+ */
+static uint32_t channel_period_set_rsp_dec(const uint8_t * p_buffer, uint16_t length)
+{
+ uint32_t result_code;
+
+ const uint32_t err_code = ant_channel_period_set_rsp_dec(p_buffer,
+ length,
+ &result_code);
+ //@note: Should never fail.
+
+ APP_ERROR_CHECK(err_code);
+
+ return result_code;
+}
+
+uint32_t sd_ant_channel_period_set(uint8_t channel, uint16_t period)
+{
+ uint8_t * p_buffer;
+ uint32_t buffer_length;
+
+ tx_buf_alloc(&p_buffer, &buffer_length);
+
+ const uint32_t err_code = ant_channel_period_set_req_enc(channel,
+ period,
+ &(p_buffer[1]),
+ &buffer_length);
+
+ APP_ERROR_CHECK(err_code);
+
+ //@note: Increment buffer length as internally managed packet type field must be included.
+ return ser_sd_transport_cmd_write(p_buffer,
+ (++buffer_length),
+ channel_period_set_rsp_dec);
+}
+
+/**@brief Command response callback function for @ref sd_ant_channel_radio_freq_set ANT command.
+ *
+ * Callback for decoding the output parameters and the command response return code.
+ *
+ * @param[in] p_buffer Pointer to begin of command response buffer.
+ * @param[in] length Length of data in bytes.
+ *
+ * @return Decoded command response return code.
+ */
+static uint32_t channel_radio_freq_set_rsp_dec(const uint8_t * p_buffer, uint16_t length)
+{
+ uint32_t result_code;
+
+ const uint32_t err_code = ant_channel_radio_freq_set_rsp_dec(p_buffer,
+ length,
+ &result_code);
+ //@note: Should never fail.
+
+ APP_ERROR_CHECK(err_code);
+
+ return result_code;
+}
+
+uint32_t sd_ant_channel_radio_freq_set (uint8_t channel, uint8_t freq)
+{
+ uint8_t * p_buffer;
+ uint32_t buffer_length;
+
+ tx_buf_alloc(&p_buffer, &buffer_length);
+
+ const uint32_t err_code = ant_channel_radio_freq_set_req_enc(channel,
+ freq,
+ &(p_buffer[1]),
+ &buffer_length);
+
+ APP_ERROR_CHECK(err_code);
+
+ //@note: Increment buffer length as internally managed packet type field must be included.
+ return ser_sd_transport_cmd_write(p_buffer,
+ (++buffer_length),
+ channel_radio_freq_set_rsp_dec);
+}
+
+/**@brief Command response callback function for @ref sd_ant_broadcast_message_tx ANT command.
+ *
+ * Callback for decoding the output parameters and the command response return code.
+ *
+ * @param[in] p_buffer Pointer to begin of command response buffer.
+ * @param[in] length Length of data in bytes.
+ *
+ * @return Decoded command response return code.
+ */
+static uint32_t broadcast_message_tx_rsp_dec(const uint8_t * p_buffer, uint16_t length)
+{
+ uint32_t result_code;
+
+ const uint32_t err_code = ant_broadcast_message_tx_rsp_dec(p_buffer,
+ length,
+ &result_code);
+ //@note: Should never fail.
+
+ APP_ERROR_CHECK(err_code);
+
+ return result_code;
+}
+
+uint32_t sd_ant_broadcast_message_tx(uint8_t channel, uint8_t size, uint8_t * p_mesg)
+{
+ uint8_t * p_buffer;
+ uint32_t buffer_length;
+
+ tx_buf_alloc(&p_buffer, &buffer_length);
+
+ const uint32_t err_code = ant_broadcast_message_tx_req_enc(channel,
+ size,
+ p_mesg,
+ &(p_buffer[1]),
+ &buffer_length);
+
+ APP_ERROR_CHECK(err_code);
+
+ //@note: Increment buffer length as internally managed packet type field must be included.
+ return ser_sd_transport_cmd_write(p_buffer,
+ (++buffer_length),
+ broadcast_message_tx_rsp_dec);
+}
+
+/**@brief Command response callback function for @ref sd_ant_acknowledge_message_tx ANT command.
+ *
+ * Callback for decoding the output parameters and the command response return code.
+ *
+ * @param[in] p_buffer Pointer to begin of command response buffer.
+ * @param[in] length Length of data in bytes.
+ *
+ * @return Decoded command response return code.
+ */
+static uint32_t acknowledge_message_tx_rsp_dec(const uint8_t * p_buffer, uint16_t length)
+{
+ uint32_t result_code;
+
+ const uint32_t err_code = ant_acknowledge_message_tx_rsp_dec(p_buffer,
+ length,
+ &result_code);
+
+ //@note: Should never fail.
+
+ APP_ERROR_CHECK(err_code);
+
+ return result_code;
+}
+
+uint32_t sd_ant_acknowledge_message_tx(uint8_t channel, uint8_t size, uint8_t * p_mesg)
+{
+ uint8_t * p_buffer;
+ uint32_t buffer_length;
+
+ tx_buf_alloc(&p_buffer, &buffer_length);
+
+ const uint32_t err_code = ant_acknowledge_message_tx_req_enc(channel,
+ size,
+ p_mesg,
+ &(p_buffer[1]),
+ &buffer_length);
+
+ APP_ERROR_CHECK(err_code);
+
+ //@note: Increment buffer length as internally managed packet type field must be included.
+ return ser_sd_transport_cmd_write(p_buffer,
+ (++buffer_length),
+ acknowledge_message_tx_rsp_dec);
+}
+
+/**@brief Command response callback function for @ref sd_ant_channel_unassign ANT command.
+ *
+ * Callback for decoding the output parameters and the command response return code.
+ *
+ * @param[in] p_buffer Pointer to begin of command response buffer.
+ * @param[in] length Length of data in bytes.
+ *
+ * @return Decoded command response return code.
+ */
+static uint32_t channel_unassign_rsp_dec(const uint8_t * p_buffer, uint16_t length)
+{
+ uint32_t result_code;
+
+ const uint32_t err_code = ant_channel_unassign_rsp_dec(p_buffer,
+ length,
+ &result_code);
+
+ //@note: Should never fail.
+
+ APP_ERROR_CHECK(err_code);
+
+ return result_code;
+}
+
+uint32_t sd_ant_channel_unassign(uint8_t channel)
+{
+ uint8_t * p_buffer;
+ uint32_t buffer_length;
+
+ tx_buf_alloc(&p_buffer, &buffer_length);
+
+ const uint32_t err_code = ant_channel_unassign_req_enc(channel,
+ &(p_buffer[1]),
+ &buffer_length);
+
+ APP_ERROR_CHECK(err_code);
+
+ //@note: Increment buffer length as internally managed packet type field must be included.
+ return ser_sd_transport_cmd_write(p_buffer,
+ (++buffer_length),
+ channel_unassign_rsp_dec);
+}
+
+/**@brief Command response callback function for @ref sd_ant_channel_close ANT command.
+ *
+ * Callback for decoding the output parameters and the command response return code.
+ *
+ * @param[in] p_buffer Pointer to begin of command response buffer.
+ * @param[in] length Length of data in bytes.
+ *
+ * @return Decoded command response return code.
+ */
+static uint32_t channel_close_rsp_dec(const uint8_t * p_buffer, uint16_t length)
+{
+ uint32_t result_code;
+
+ const uint32_t err_code = ant_channel_close_rsp_dec(p_buffer,
+ length,
+ &result_code);
+
+ //@note: Should never fail.
+
+ APP_ERROR_CHECK(err_code);
+
+ return result_code;
+}
+
+uint32_t sd_ant_channel_close(uint8_t channel)
+{
+ uint8_t * p_buffer;
+ uint32_t buffer_length;
+
+ tx_buf_alloc(&p_buffer, &buffer_length);
+
+ const uint32_t err_code = ant_channel_close_req_enc(channel,
+ &(p_buffer[1]),
+ &buffer_length);
+
+ APP_ERROR_CHECK(err_code);
+
+ //@note: Increment buffer length as internally managed packet type field must be included.
+ return ser_sd_transport_cmd_write(p_buffer,
+ (++buffer_length),
+ channel_close_rsp_dec);
+}
+
+/**@brief Command response callback function for @ref sd_ant_network_address_set ANT command.
+ *
+ * Callback for decoding the output parameters and the command response return code.
+ *
+ * @param[in] p_buffer Pointer to begin of command response buffer.
+ * @param[in] length Length of data in bytes.
+ *
+ * @return Decoded command response return code.
+ */
+static uint32_t network_address_set_rsp_dec(const uint8_t * p_buffer, uint16_t length)
+{
+ uint32_t result_code;
+
+ const uint32_t err_code = ant_network_address_set_rsp_dec(p_buffer,
+ length,
+ &result_code);
+
+ //@note: Should never fail
+
+ APP_ERROR_CHECK(err_code);
+
+ return result_code;
+}
+
+uint32_t sd_ant_network_address_set(uint8_t network, const uint8_t * p_network_key)
+{
+ uint8_t * p_buffer;
+ uint32_t buffer_length;
+
+ tx_buf_alloc(&p_buffer, &buffer_length);
+
+ const uint32_t err_code = ant_network_address_set_req_enc(network,
+ p_network_key,
+ &(p_buffer[1]),
+ &buffer_length);
+
+ APP_ERROR_CHECK(err_code);
+
+ //@note: Increment buffer length as internally managed packet type field must be included.
+ return ser_sd_transport_cmd_write(p_buffer,
+ (++buffer_length),
+ network_address_set_rsp_dec);
+}
+
+/**@brief Command response callback function for @ref sd_ant_channel_radio_tx_power_set ANT command.
+ *
+ * Callback for decoding the output parameters and the command response return code.
+ *
+ * @param[in] p_buffer Pointer to begin of command response buffer.
+ * @param[in] length Length of data in bytes.
+ *
+ * @return Decoded command response return code.
+ */
+static uint32_t channel_radio_tx_power_set_rsp_dec(const uint8_t * p_buffer, uint16_t length)
+{
+ uint32_t result_code;
+
+ const uint32_t err_code = ant_channel_radio_tx_power_set_rsp_dec(p_buffer,
+ length,
+ &result_code);
+
+ //@note: Should never fail
+
+ APP_ERROR_CHECK(err_code);
+
+ return result_code;
+}
+
+uint32_t sd_ant_channel_radio_tx_power_set(uint8_t channel, uint8_t tx_power, uint8_t custom_tx_power)
+{
+ uint8_t * p_buffer;
+ uint32_t buffer_length;
+
+ tx_buf_alloc(&p_buffer, &buffer_length);
+
+ const uint32_t err_code = ant_channel_radio_tx_power_set_req_enc(channel,
+ tx_power,
+ custom_tx_power,
+ &(p_buffer[1]),
+ &buffer_length);
+
+ APP_ERROR_CHECK(err_code);
+
+ //@note: Increment buffer length as internally managed packet type field must be included.
+ return ser_sd_transport_cmd_write(p_buffer,
+ (++buffer_length),
+ channel_radio_tx_power_set_rsp_dec);
+}
+
+/**@brief Command response callback function for @ref sd_ant_channel_rx_search_timeout_set ANT command.
+ *
+ * Callback for decoding the output parameters and the command response return code.
+ *
+ * @param[in] p_buffer Pointer to begin of command response buffer.
+ * @param[in] length Length of data in bytes.
+ *
+ * @return Decoded command response return code.
+ */
+static uint32_t channel_rx_search_timeout_set_rsp_dec(const uint8_t * p_buffer, uint16_t length)
+{
+ uint32_t result_code;
+
+ const uint32_t err_code = ant_channel_rx_search_timeout_set_rsp_dec(p_buffer,
+ length,
+ &result_code);
+
+ //@note: Should never fail
+
+ APP_ERROR_CHECK(err_code);
+
+ return result_code;
+}
+
+uint32_t sd_ant_channel_rx_search_timeout_set(uint8_t channel, uint8_t timeout)
+{
+ uint8_t * p_buffer;
+ uint32_t buffer_length;
+
+ tx_buf_alloc(&p_buffer, &buffer_length);
+
+ const uint32_t err_code = ant_channel_rx_search_timeout_set_req_enc(channel,
+ timeout,
+ &(p_buffer[1]),
+ &buffer_length);
+
+ APP_ERROR_CHECK(err_code);
+
+ //@note: Increment buffer length as internally managed packet type field must be included.
+ return ser_sd_transport_cmd_write(p_buffer,
+ (++buffer_length),
+ channel_rx_search_timeout_set_rsp_dec);
+}
+
+/**@brief Command response callback function for @ref sd_ant_channel_low_priority_rx_search_timeout_set ANT command.
+ *
+ * Callback for decoding the output parameters and the command response return code.
+ *
+ * @param[in] p_buffer Pointer to begin of command response buffer.
+ * @param[in] length Length of data in bytes.
+ *
+ * @return Decoded command response return code.
+ */
+static uint32_t channel_low_priority_rx_search_timeout_set_rsp_dec(const uint8_t * p_buffer, uint16_t length)
+{
+ uint32_t result_code;
+
+ const uint32_t err_code = ant_channel_low_priority_rx_search_timeout_set_rsp_dec(p_buffer,
+ length,
+ &result_code);
+
+ //@note: Should never fail
+
+ APP_ERROR_CHECK(err_code);
+
+ return result_code;
+}
+
+uint32_t sd_ant_channel_low_priority_rx_search_timeout_set(uint8_t channel, uint8_t timeout)
+{
+ uint8_t * p_buffer;
+ uint32_t buffer_length;
+
+ tx_buf_alloc(&p_buffer, &buffer_length);
+
+ const uint32_t err_code = ant_channel_low_priority_rx_search_timeout_set_req_enc(channel,
+ timeout,
+ &(p_buffer[1]),
+ &buffer_length);
+
+ APP_ERROR_CHECK(err_code);
+
+ //@note: Increment buffer length as internally managed packet type field must be included.
+ return ser_sd_transport_cmd_write(p_buffer,
+ (++buffer_length),
+ channel_low_priority_rx_search_timeout_set_rsp_dec);
+}
+
+/**@brief Command response callback function for @ref sd_ant_prox_search_set ANT command.
+ *
+ * Callback for decoding the output parameters and the command response return code.
+ *
+ * @param[in] p_buffer Pointer to begin of command response buffer.
+ * @param[in] length Length of data in bytes.
+ *
+ * @return Decoded command response return code.
+ */
+static uint32_t prox_search_set_rsp_dec(const uint8_t * p_buffer, uint16_t length)
+{
+ uint32_t result_code;
+
+ const uint32_t err_code = ant_prox_search_set_rsp_dec(p_buffer,
+ length,
+ &result_code);
+
+ //@note: Should never fail
+
+ APP_ERROR_CHECK(err_code);
+
+ return result_code;
+}
+
+uint32_t sd_ant_prox_search_set(uint8_t channel, uint8_t prox_threshold, uint8_t custom_prox_threshold)
+{
+ uint8_t * p_buffer;
+ uint32_t buffer_length;
+
+ tx_buf_alloc(&p_buffer, &buffer_length);
+
+ const uint32_t err_code = ant_prox_search_set_req_enc(channel,
+ prox_threshold,
+ custom_prox_threshold,
+ &(p_buffer[1]),
+ &buffer_length);
+
+ APP_ERROR_CHECK(err_code);
+
+ //@note: Increment buffer length as internally managed packet type field must be included.
+ return ser_sd_transport_cmd_write(p_buffer,
+ (++buffer_length),
+ prox_search_set_rsp_dec);
+}
+
+/**@brief Command response callback function for @ref sd_ant_search_waveform_set ANT command.
+ *
+ * Callback for decoding the output parameters and the command response return code.
+ *
+ * @param[in] p_buffer Pointer to begin of command response buffer.
+ * @param[in] length Length of data in bytes.
+ *
+ * @return Decoded command response return code.
+ */
+static uint32_t search_waveform_set_rsp_dec(const uint8_t * p_buffer, uint16_t length)
+{
+ uint32_t result_code;
+
+ const uint32_t err_code = ant_search_waveform_set_rsp_dec(p_buffer,
+ length,
+ &result_code);
+
+ //@note: Should never fail
+
+ APP_ERROR_CHECK(err_code);
+
+ return result_code;
+}
+
+uint32_t sd_ant_search_waveform_set(uint8_t channel, uint16_t waveform)
+{
+ uint8_t * p_buffer;
+ uint32_t buffer_length;
+
+ tx_buf_alloc(&p_buffer, &buffer_length);
+
+ const uint32_t err_code = ant_search_waveform_set_req_enc(channel,
+ waveform,
+ &(p_buffer[1]),
+ &buffer_length);
+
+ APP_ERROR_CHECK(err_code);
+
+ //@note: Increment buffer length as internally managed packet type field must be included.
+ return ser_sd_transport_cmd_write(p_buffer,
+ (++buffer_length),
+ search_waveform_set_rsp_dec);
+}
+
+/**@brief Command response callback function for @ref sd_ant_channel_id_get ANT command.
+ *
+ * Callback for decoding the output parameters and the command response return code.
+ *
+ * @param[in] p_buffer Pointer to begin of command response buffer.
+ * @param[in] length Length of data in bytes.
+ *
+ * @return Decoded command response return code.
+ */
+static uint32_t channel_id_get_rsp_dec(const uint8_t * p_buffer, uint16_t length)
+{
+ uint32_t result_code;
+
+ const uint32_t err_code = ant_channel_id_get_rsp_dec(p_buffer,
+ length,
+ mp_out_params[0],
+ mp_out_params[1],
+ mp_out_params[2],
+ &result_code);
+
+ //@note: Should never fail
+
+ APP_ERROR_CHECK(err_code);
+
+ return result_code;
+}
+
+uint32_t sd_ant_channel_id_get(uint8_t channel, uint16_t * p_device_number, uint8_t * p_device_type, uint8_t * p_transmit_type)
+{
+ uint8_t * p_buffer;
+ uint32_t buffer_length;
+
+ tx_buf_alloc(&p_buffer, &buffer_length);
+ mp_out_params[0] = p_device_number;
+ mp_out_params[1] = p_device_type;
+ mp_out_params[2] = p_transmit_type;
+
+ const uint32_t err_code = ant_channel_id_get_req_enc(channel,
+ &(p_buffer[1]),
+ &buffer_length);
+
+ APP_ERROR_CHECK(err_code);
+
+ //@note: Increment buffer length as internally managed packet type field must be included.
+ return ser_sd_transport_cmd_write(p_buffer,
+ (++buffer_length),
+ channel_id_get_rsp_dec);
+}
+
+/**@brief Command response callback function for @ref sd_ant_channel_radio_freq_get ANT command.
+ *
+ * Callback for decoding the output parameters and the command response return code.
+ *
+ * @param[in] p_buffer Pointer to begin of command response buffer.
+ * @param[in] length Length of data in bytes.
+ *
+ * @return Decoded command response return code.
+ */
+static uint32_t channel_radio_freq_get_rsp_dec(const uint8_t * p_buffer, uint16_t length)
+{
+ uint32_t result_code;
+
+ const uint32_t err_code = ant_channel_radio_freq_get_rsp_dec(p_buffer,
+ length,
+ mp_out_params[0],
+ &result_code);
+
+ //@note: Should never fail
+
+ APP_ERROR_CHECK(err_code);
+
+ return result_code;
+}
+
+uint32_t sd_ant_channel_radio_freq_get(uint8_t channel, uint8_t * p_r_freq)
+{
+ uint8_t * p_buffer;
+ uint32_t buffer_length;
+
+ tx_buf_alloc(&p_buffer, &buffer_length);
+ mp_out_params[0] = p_r_freq;
+
+ const uint32_t err_code = ant_channel_radio_freq_get_req_enc(channel,
+ &(p_buffer[1]),
+ &buffer_length);
+
+ APP_ERROR_CHECK(err_code);
+
+ //@note: Increment buffer length as internally managed packet type field must be included.
+ return ser_sd_transport_cmd_write(p_buffer,
+ (++buffer_length),
+ channel_radio_freq_get_rsp_dec);
+}
+
+/**@brief Command response callback function for @ref sd_ant_channel_period_get ANT command.
+ *
+ * Callback for decoding the output parameters and the command response return code.
+ *
+ * @param[in] p_buffer Pointer to begin of command response buffer.
+ * @param[in] length Length of data in bytes.
+ *
+ * @return Decoded command response return code.
+ */
+static uint32_t channel_period_get_rsp_dec(const uint8_t * p_buffer, uint16_t length)
+{
+ uint32_t result_code;
+
+ const uint32_t err_code = ant_channel_period_get_rsp_dec(p_buffer,
+ length,
+ mp_out_params[0],
+ &result_code);
+
+ //@note: Should never fail
+
+ APP_ERROR_CHECK(err_code);
+
+ return result_code;
+}
+
+uint32_t sd_ant_channel_period_get(uint8_t channel, uint16_t * p_period)
+{
+ uint8_t * p_buffer;
+ uint32_t buffer_length;
+
+ tx_buf_alloc(&p_buffer, &buffer_length);
+ mp_out_params[0] = p_period;
+
+ const uint32_t err_code = ant_channel_period_get_req_enc(channel,
+ &(p_buffer[1]),
+ &buffer_length);
+
+ APP_ERROR_CHECK(err_code);
+
+ //@note: Increment buffer length as internally managed packet type field must be included.
+ return ser_sd_transport_cmd_write(p_buffer,
+ (++buffer_length),
+ channel_period_get_rsp_dec);
+}
+
+/**@brief Command response callback function for @ref sd_ant_search_channel_priority_set ANT command.
+ *
+ * Callback for decoding the output parameters and the command response return code.
+ *
+ * @param[in] p_buffer Pointer to begin of command response buffer.
+ * @param[in] length Length of data in bytes.
+ *
+ * @return Decoded command response return code.
+ */
+static uint32_t search_channel_priority_set_rsp_dec(const uint8_t * p_buffer, uint16_t length)
+{
+ uint32_t result_code;
+
+ const uint32_t err_code = ant_search_channel_priority_set_rsp_dec(p_buffer,
+ length,
+ &result_code);
+
+ //@note: Should never fail
+
+ APP_ERROR_CHECK(err_code);
+
+ return result_code;
+}
+
+uint32_t sd_ant_search_channel_priority_set(uint8_t channel, uint8_t search_priority)
+{
+ uint8_t * p_buffer;
+ uint32_t buffer_length;
+
+ tx_buf_alloc(&p_buffer, &buffer_length);
+
+ const uint32_t err_code = ant_search_channel_priority_set_req_enc(channel,
+ search_priority,
+ &(p_buffer[1]),
+ &buffer_length);
+
+ APP_ERROR_CHECK(err_code);
+
+ //@note: Increment buffer length as internally managed packet type field must be included.
+ return ser_sd_transport_cmd_write(p_buffer,
+ (++buffer_length),
+ search_channel_priority_set_rsp_dec);
+}
+
+/**@brief Command response callback function for @ref sd_ant_active_search_sharing_cycles_set ANT command.
+ *
+ * Callback for decoding the output parameters and the command response return code.
+ *
+ * @param[in] p_buffer Pointer to begin of command response buffer.
+ * @param[in] length Length of data in bytes.
+ *
+ * @return Decoded command response return code.
+ */
+static uint32_t active_search_sharing_cycles_set_rsp_dec(const uint8_t * p_buffer, uint16_t length)
+{
+ uint32_t result_code;
+
+ const uint32_t err_code = ant_active_search_sharing_cycles_set_rsp_dec(p_buffer,
+ length,
+ &result_code);
+
+ //@note: Should never fail
+
+ APP_ERROR_CHECK(err_code);
+
+ return result_code;
+}
+
+uint32_t sd_ant_active_search_sharing_cycles_set(uint8_t channel, uint8_t cycles)
+{
+ uint8_t * p_buffer;
+ uint32_t buffer_length;
+
+ tx_buf_alloc(&p_buffer, &buffer_length);
+
+ const uint32_t err_code = ant_active_search_sharing_cycles_set_req_enc(channel,
+ cycles,
+ &(p_buffer[1]),
+ &buffer_length);
+
+ APP_ERROR_CHECK(err_code);
+
+ //@note: Increment buffer length as internally managed packet type field must be included.
+ return ser_sd_transport_cmd_write(p_buffer,
+ (++buffer_length),
+ active_search_sharing_cycles_set_rsp_dec);
+}
+
+/**@brief Command response callback function for @ref sd_ant_lib_config_set ANT command.
+ *
+ * Callback for decoding the output parameters and the command response return code.
+ *
+ * @param[in] p_buffer Pointer to begin of command response buffer.
+ * @param[in] length Length of data in bytes.
+ *
+ * @return Decoded command response return code.
+ */
+static uint32_t lib_config_set_rsp_dec(const uint8_t * p_buffer, uint16_t length)
+{
+ uint32_t result_code;
+
+ const uint32_t err_code = ant_lib_config_set_rsp_dec(p_buffer,
+ length,
+ &result_code);
+
+ //@note: Should never fail
+
+ APP_ERROR_CHECK(err_code);
+
+ return result_code;
+}
+
+uint32_t sd_ant_lib_config_set(uint8_t ant_lib_config)
+{
+ uint8_t * p_buffer;
+ uint32_t buffer_length;
+
+ tx_buf_alloc(&p_buffer, &buffer_length);
+
+ const uint32_t err_code = ant_lib_config_set_req_enc(ant_lib_config,
+ &(p_buffer[1]),
+ &buffer_length);
+
+ APP_ERROR_CHECK(err_code);
+
+ //@note: Increment buffer length as internally managed packet type field must be included.
+ return ser_sd_transport_cmd_write(p_buffer,
+ (++buffer_length),
+ lib_config_set_rsp_dec);
+}
+
+/**@brief Command response callback function for @ref sd_ant_active_search_sharing_channels_get ANT command.
+ *
+ * Callback for decoding the output parameters and the command response return code.
+ *
+ * @param[in] p_buffer Pointer to begin of command response buffer.
+ * @param[in] length Length of data in bytes.
+ *
+ * @return Decoded command response return code.
+ */
+static uint32_t active_search_sharing_cycles_get_rsp_dec(const uint8_t * p_buffer, uint16_t length)
+{
+ uint32_t result_code;
+
+ const uint32_t err_code = ant_active_search_sharing_cycles_get_rsp_dec(p_buffer,
+ length,
+ mp_out_params[0],
+ &result_code);
+
+ //@note: Should never fail
+
+ APP_ERROR_CHECK(err_code);
+
+ return result_code;
+}
+
+uint32_t sd_ant_active_search_sharing_cycles_get(uint8_t channel, uint8_t * p_cycles)
+{
+ uint8_t * p_buffer;
+ uint32_t buffer_length;
+
+ tx_buf_alloc(&p_buffer, &buffer_length);
+ mp_out_params[0] = p_cycles;
+
+ const uint32_t err_code = ant_active_search_sharing_cycles_get_req_enc(channel,
+ &(p_buffer[1]),
+ &buffer_length);
+
+ APP_ERROR_CHECK(err_code);
+
+ //@note: Increment buffer length as internally managed packet type field must be included.
+ return ser_sd_transport_cmd_write(p_buffer,
+ (++buffer_length),
+ active_search_sharing_cycles_get_rsp_dec);
+}
+
+/**@brief Command response callback function for @ref sd_ant_lib_config_get ANT command.
+ *
+ * Callback for decoding the output parameters and the command response return code.
+ *
+ * @param[in] p_buffer Pointer to begin of command response buffer.
+ * @param[in] length Length of data in bytes.
+ *
+ * @return Decoded command response return code.
+ */
+static uint32_t lib_config_get_rsp_dec(const uint8_t * p_buffer, uint16_t length)
+{
+ uint32_t result_code;
+
+ const uint32_t err_code = ant_lib_config_get_rsp_dec(p_buffer,
+ length,
+ mp_out_params[0],
+ &result_code);
+
+ //@note: Should never fail
+
+ APP_ERROR_CHECK(err_code);
+
+ return result_code;
+}
+
+uint32_t sd_ant_lib_config_get(uint8_t * p_ant_lib_config)
+{
+ uint8_t * p_buffer;
+ uint32_t buffer_length;
+
+ tx_buf_alloc(&p_buffer, &buffer_length);
+ mp_out_params[0] = p_ant_lib_config;
+
+ const uint32_t err_code = ant_lib_config_get_req_enc(&(p_buffer[1]),
+ &buffer_length);
+
+ APP_ERROR_CHECK(err_code);
+
+ //@note: Increment buffer length as internally managed packet type field must be included.
+ return ser_sd_transport_cmd_write(p_buffer,
+ (++buffer_length),
+ lib_config_get_rsp_dec);
+}
+
+/**@brief Command response callback function for @ref sd_ant_lib_config_clear ANT command.
+ *
+ * Callback for decoding the output parameters and the command response return code.
+ *
+ * @param[in] p_buffer Pointer to begin of command response buffer.
+ * @param[in] length Length of data in bytes.
+ *
+ * @return Decoded command response return code.
+ */
+static uint32_t lib_config_clear_rsp_dec(const uint8_t * p_buffer, uint16_t length)
+{
+ uint32_t result_code;
+
+ const uint32_t err_code = ant_lib_config_clear_rsp_dec(p_buffer,
+ length,
+ &result_code);
+
+ //@note: Should never fail
+
+ APP_ERROR_CHECK(err_code);
+
+ return result_code;
+}
+
+uint32_t sd_ant_lib_config_clear(uint8_t ant_lib_config)
+{
+ uint8_t * p_buffer;
+ uint32_t buffer_length;
+
+ tx_buf_alloc(&p_buffer, &buffer_length);
+
+ const uint32_t err_code = ant_lib_config_clear_req_enc(ant_lib_config,
+ &(p_buffer[1]),
+ &buffer_length);
+
+ APP_ERROR_CHECK(err_code);
+
+ //@note: Increment buffer length as internally managed packet type field must be included.
+ return ser_sd_transport_cmd_write(p_buffer,
+ (++buffer_length),
+ lib_config_clear_rsp_dec);
+}
+
+/**@brief Command response callback function for @ref sd_ant_stack_reset ANT command.
+ *
+ * Callback for decoding the output parameters and the command response return code.
+ *
+ * @param[in] p_buffer Pointer to begin of command response buffer.
+ * @param[in] length Length of data in bytes.
+ *
+ * @return Decoded command response return code.
+ */
+static uint32_t stack_reset_rsp_dec(const uint8_t * p_buffer, uint16_t length)
+{
+ uint32_t result_code;
+
+ const uint32_t err_code = ant_stack_reset_rsp_dec(p_buffer,
+ length,
+ &result_code);
+
+ //@note: Should never fail
+
+ APP_ERROR_CHECK(err_code);
+
+ return result_code;
+}
+
+uint32_t sd_ant_stack_reset()
+{
+ uint8_t * p_buffer;
+ uint32_t buffer_length;
+
+ tx_buf_alloc(&p_buffer, &buffer_length);
+
+ const uint32_t err_code = ant_stack_reset_req_enc(&(p_buffer[1]),
+ &buffer_length);
+
+ APP_ERROR_CHECK(err_code);
+
+ //@note: Increment buffer length as internally managed packet type field must be included.
+ return ser_sd_transport_cmd_write(p_buffer,
+ (++buffer_length),
+ stack_reset_rsp_dec);
+}
+
+/**@brief Command response callback function for @ref sd_ant_rx_scan_mode_start ANT command.
+ *
+ * Callback for decoding the output parameters and the command response return code.
+ *
+ * @param[in] p_buffer Pointer to begin of command response buffer.
+ * @param[in] length Length of data in bytes.
+ *
+ * @return Decoded command response return code.
+ */
+static uint32_t rx_scan_mode_start_rsp_dec(const uint8_t * p_buffer, uint16_t length)
+{
+ uint32_t result_code;
+
+ const uint32_t err_code = ant_rx_scan_mode_start_rsp_dec(p_buffer,
+ length,
+ &result_code);
+
+ //@note: Should never fail
+
+ APP_ERROR_CHECK(err_code);
+
+ return result_code;
+}
+
+uint32_t sd_ant_rx_scan_mode_start(uint8_t sync_channel_packets_only)
+{
+ uint8_t * p_buffer;
+ uint32_t buffer_length;
+
+ tx_buf_alloc(&p_buffer, &buffer_length);
+
+ const uint32_t err_code = ant_rx_scan_mode_start_req_enc(sync_channel_packets_only,
+ &(p_buffer[1]),
+ &buffer_length);
+
+ APP_ERROR_CHECK(err_code);
+
+ //@note: Increment buffer length as internally managed packet type field must be included.
+ return ser_sd_transport_cmd_write(p_buffer,
+ (++buffer_length),
+ rx_scan_mode_start_rsp_dec);
+}
+
+/**@brief Command response callback function for @ref sd_ant_id_list_add ANT command.
+ *
+ * Callback for decoding the output parameters and the command response return code.
+ *
+ * @param[in] p_buffer Pointer to begin of command response buffer.
+ * @param[in] length Length of data in bytes.
+ *
+ * @return Decoded command response return code.
+ */
+static uint32_t id_list_add_rsp_dec(const uint8_t * p_buffer, uint16_t length)
+{
+ uint32_t result_code;
+
+ const uint32_t err_code = ant_id_list_add_rsp_dec(p_buffer,
+ length,
+ &result_code);
+
+ //@note: Should never fail
+
+ APP_ERROR_CHECK(err_code);
+
+ return result_code;
+}
+
+uint32_t sd_ant_id_list_add(uint8_t channel, uint8_t * p_dev_id, uint8_t list_index)
+{
+ uint8_t * p_buffer;
+ uint32_t buffer_length;
+
+ tx_buf_alloc(&p_buffer, &buffer_length);
+
+ const uint32_t err_code = ant_id_list_add_req_enc(channel,
+ p_dev_id,
+ list_index,
+ &(p_buffer[1]),
+ &buffer_length);
+
+ APP_ERROR_CHECK(err_code);
+
+ //@note: Increment buffer length as internally managed packet type field must be included.
+ return ser_sd_transport_cmd_write(p_buffer,
+ (++buffer_length),
+ id_list_add_rsp_dec);
+}
+
+/**@brief Command response callback function for @ref sd_ant_id_list_config ANT command.
+ *
+ * Callback for decoding the output parameters and the command response return code.
+ *
+ * @param[in] p_buffer Pointer to begin of command response buffer.
+ * @param[in] length Length of data in bytes.
+ *
+ * @return Decoded command response return code.
+ */
+static uint32_t id_list_config_rsp_dec(const uint8_t * p_buffer, uint16_t length)
+{
+ uint32_t result_code;
+
+ const uint32_t err_code = ant_id_list_config_rsp_dec(p_buffer,
+ length,
+ &result_code);
+
+ //@note: Should never fail
+
+ APP_ERROR_CHECK(err_code);
+
+ return result_code;
+}
+
+uint32_t sd_ant_id_list_config(uint8_t channel, uint8_t id_list_size, uint8_t inc_exc_flag)
+{
+ uint8_t * p_buffer;
+ uint32_t buffer_length;
+
+ tx_buf_alloc(&p_buffer, &buffer_length);
+
+ const uint32_t err_code = ant_id_list_config_req_enc(channel,
+ id_list_size,
+ inc_exc_flag,
+ &(p_buffer[1]),
+ &buffer_length);
+
+ APP_ERROR_CHECK(err_code);
+
+ //@note: Increment buffer length as internally managed packet type field must be included.
+ return ser_sd_transport_cmd_write(p_buffer,
+ (++buffer_length),
+ id_list_config_rsp_dec);
+}
+
+/**@brief Command response callback function for @ref sd_ant_channel_status_get ANT command.
+ *
+ * Callback for decoding the output parameters and the command response return code.
+ *
+ * @param[in] p_buffer Pointer to begin of command response buffer.
+ * @param[in] length Length of data in bytes.
+ *
+ * @return Decoded command response return code.
+ */
+static uint32_t channel_status_get_rsp_dec(const uint8_t * p_buffer, uint16_t length)
+{
+ uint32_t result_code;
+
+ const uint32_t err_code = ant_channel_status_get_rsp_dec(p_buffer,
+ length,
+ mp_out_params[0],
+ &result_code);
+
+ //@note: Should never fail
+
+ APP_ERROR_CHECK(err_code);
+
+ return result_code;
+}
+
+uint32_t sd_ant_channel_status_get(uint8_t channel, uint8_t * p_status)
+{
+ uint8_t * p_buffer;
+ uint32_t buffer_length;
+
+ tx_buf_alloc(&p_buffer, &buffer_length);
+ mp_out_params[0] = p_status;
+
+ const uint32_t err_code = ant_channel_status_get_req_enc(channel,
+ &(p_buffer[1]),
+ &buffer_length);
+
+ APP_ERROR_CHECK(err_code);
+
+ //@note: Increment buffer length as internally managed packet type field must be included.
+ return ser_sd_transport_cmd_write(p_buffer,
+ (++buffer_length),
+ channel_status_get_rsp_dec);
+}
+
+/**@brief Command response callback function for @ref sd_ant_cw_test_mode_init ANT command.
+ *
+ * Callback for decoding the output parameters and the command response return code.
+ *
+ * @param[in] p_buffer Pointer to begin of command response buffer.
+ * @param[in] length Length of data in bytes.
+ *
+ * @return Decoded command response return code.
+ */
+static uint32_t cw_test_mode_init_rsp_dec(const uint8_t * p_buffer, uint16_t length)
+{
+ uint32_t result_code;
+
+ const uint32_t err_code = ant_cw_test_mode_init_rsp_dec(p_buffer,
+ length,
+ &result_code);
+
+ //@note: Should never fail
+
+ APP_ERROR_CHECK(err_code);
+
+ return result_code;
+}
+
+uint32_t sd_ant_cw_test_mode_init()
+{
+ uint8_t * p_buffer;
+ uint32_t buffer_length;
+
+ tx_buf_alloc(&p_buffer, &buffer_length);
+
+ const uint32_t err_code = ant_cw_test_mode_init_req_enc(&(p_buffer[1]),
+ &buffer_length);
+
+ APP_ERROR_CHECK(err_code);
+
+ //@note: Increment buffer length as internally managed packet type field must be included.
+ return ser_sd_transport_cmd_write(p_buffer,
+ (++buffer_length),
+ cw_test_mode_init_rsp_dec);
+}
+
+/**@brief Command response callback function for @ref sd_ant_cw_test_mode ANT command.
+ *
+ * Callback for decoding the output parameters and the command response return code.
+ *
+ * @param[in] p_buffer Pointer to begin of command response buffer.
+ * @param[in] length Length of data in bytes.
+ *
+ * @return Decoded command response return code.
+ */
+static uint32_t cw_test_mode_rsp_dec(const uint8_t * p_buffer, uint16_t length)
+{
+ uint32_t result_code;
+
+ const uint32_t err_code = ant_cw_test_mode_rsp_dec(p_buffer,
+ length,
+ &result_code);
+
+ //@note: Should never fail
+
+ APP_ERROR_CHECK(err_code);
+
+ return result_code;
+}
+
+uint32_t sd_ant_cw_test_mode(uint8_t radio_freq, uint8_t tx_power, uint8_t custom_tx_power, uint8_t mode)
+{
+ uint8_t * p_buffer;
+ uint32_t buffer_length;
+
+ tx_buf_alloc(&p_buffer, &buffer_length);
+
+ const uint32_t err_code = ant_cw_test_mode_req_enc(radio_freq,
+ tx_power,
+ custom_tx_power,
+ mode,
+ &(p_buffer[1]),
+ &buffer_length);
+
+ APP_ERROR_CHECK(err_code);
+
+ //@note: Increment buffer length as internally managed packet type field must be included.
+ return ser_sd_transport_cmd_write(p_buffer,
+ (++buffer_length),
+ cw_test_mode_rsp_dec);
+}
+
+/**@brief Command response callback function for @ref sd_ant_version_get ANT command.
+ *
+ * Callback for decoding the output parameters and the command response return code.
+ *
+ * @param[in] p_buffer Pointer to begin of command response buffer.
+ * @param[in] length Length of data in bytes.
+ *
+ * @return Decoded command response return code.
+ */
+static uint32_t version_get_rsp_dec(const uint8_t * p_buffer, uint16_t length)
+{
+ uint32_t result_code;
+
+ const uint32_t err_code = ant_version_get_rsp_dec(p_buffer,
+ length,
+ &mp_out_params[0],
+ &result_code);
+
+ //@note: Should never fail
+
+ APP_ERROR_CHECK(err_code);
+
+ return result_code;
+}
+
+uint32_t sd_ant_version_get(uint8_t * p_version)
+{
+ uint8_t * p_buffer;
+ uint32_t buffer_length;
+
+ tx_buf_alloc(&p_buffer, &buffer_length);
+ mp_out_params[0] = p_version;
+
+ const uint32_t err_code = ant_version_get_req_enc(&(p_buffer[1]),
+ &buffer_length);
+
+ APP_ERROR_CHECK(err_code);
+
+ //@note: Increment buffer length as internally managed packet type field must be included.
+ return ser_sd_transport_cmd_write(p_buffer,
+ (++buffer_length),
+ version_get_rsp_dec);
+}
+
+/**@brief Command response callback function for @ref sd_ant_capabilities_get ANT command.
+ *
+ * Callback for decoding the output parameters and the command response return code.
+ *
+ * @param[in] p_buffer Pointer to begin of command response buffer.
+ * @param[in] length Length of data in bytes.
+ *
+ * @return Decoded command response return code.
+ */
+static uint32_t capabilities_get_rsp_dec(const uint8_t * p_buffer, uint16_t length)
+{
+ uint32_t result_code;
+
+ const uint32_t err_code = ant_capabilities_get_rsp_dec(p_buffer,
+ length,
+ &mp_out_params[0],
+ &result_code);
+
+ //@note: Should never fail
+
+ APP_ERROR_CHECK(err_code);
+
+ return result_code;
+}
+
+uint32_t sd_ant_capabilities_get(uint8_t * p_capabilities)
+{
+ uint8_t * p_buffer;
+ uint32_t buffer_length;
+
+ tx_buf_alloc(&p_buffer, &buffer_length);
+ mp_out_params[0] = p_capabilities;
+
+ const uint32_t err_code = ant_capabilities_get_req_enc(&(p_buffer[1]),
+ &buffer_length);
+
+ APP_ERROR_CHECK(err_code);
+
+ //@note: Increment buffer length as internally managed packet type field must be included.
+ return ser_sd_transport_cmd_write(p_buffer,
+ (++buffer_length),
+ capabilities_get_rsp_dec);
+}
+
+/**@brief Command response callback function for @ref sd_ant_crypto_channel_enable ANT command.
+ *
+ * Callback for decoding the output parameters and the command response return code.
+ *
+ * @param[in] p_buffer Pointer to begin of command response buffer.
+ * @param[in] length Length of data in bytes.
+ *
+ * @return Decoded command response return code.
+ */
+static uint32_t crypto_channel_enable_rsp_dec(const uint8_t * p_buffer, uint16_t length)
+{
+ uint32_t result_code;
+
+ const uint32_t err_code = ant_crypto_channel_enable_rsp_dec(p_buffer,
+ length,
+ &result_code);
+ //@note: Should never fail.
+
+ APP_ERROR_CHECK(err_code);
+
+ return result_code;
+}
+
+uint32_t sd_ant_crypto_channel_enable(uint8_t channel, uint8_t enable, uint8_t key_num, uint8_t decimation_rate)
+{
+ uint8_t * p_buffer;
+ uint32_t buffer_length;
+
+ tx_buf_alloc(&p_buffer, &buffer_length);
+
+ const uint32_t err_code = ant_crypto_channel_enable_req_enc(channel,
+ enable,
+ key_num,
+ decimation_rate,
+ &(p_buffer[1]),
+ &buffer_length);
+
+ APP_ERROR_CHECK(err_code);
+
+ //@note: Increment buffer length as internally managed packet type field must be included.
+ return ser_sd_transport_cmd_write(p_buffer,
+ (++buffer_length),
+ crypto_channel_enable_rsp_dec);
+}
+
+/**@brief Command response callback function for @ref sd_ant_adv_burst_config_set ANT command.
+ *
+ * Callback for decoding the output parameters and the command response return code.
+ *
+ * @param[in] p_buffer Pointer to begin of command response buffer.
+ * @param[in] length Length of data in bytes.
+ *
+ * @return Decoded command response return code.
+ */
+static uint32_t adv_burst_config_set_rsp_dec(const uint8_t * p_buffer, uint16_t length)
+{
+ uint32_t result_code;
+
+ const uint32_t err_code = ant_adv_burst_config_set_rsp_dec(p_buffer,
+ length,
+ &result_code);
+ //@note: Should never fail.
+ APP_ERROR_CHECK(err_code);
+
+ return result_code;
+}
+
+uint32_t sd_ant_adv_burst_config_set(uint8_t * p_config, uint8_t size)
+{
+ uint8_t * p_buffer;
+ uint32_t buffer_length;
+
+ tx_buf_alloc(&p_buffer, &buffer_length);
+
+ const uint32_t err_code = ant_adv_burst_config_set_req_enc(p_config,
+ size,
+ &(p_buffer[1]),
+ &buffer_length);
+
+ APP_ERROR_CHECK(err_code);
+
+ //@note: Increment buffer length as internally managed packet type field must be included.
+ return ser_sd_transport_cmd_write(p_buffer,
+ (++buffer_length),
+ adv_burst_config_set_rsp_dec);
+}
+
+/**@brief Command response callback function for @ref sd_ant_crypto_key_set ANT command.
+ *
+ * Callback for decoding the output parameters and the command response return code.
+ *
+ * @param[in] p_buffer Pointer to begin of command response buffer.
+ * @param[in] length Length of data in bytes.
+ *
+ * @return Decoded command response return code.
+ */
+static uint32_t crypto_key_set_rsp_dec(const uint8_t * p_buffer, uint16_t length)
+{
+ uint32_t result_code;
+
+ const uint32_t err_code = ant_crypto_key_set_rsp_dec(p_buffer,
+ length,
+ &result_code);
+ //@note: Should never fail.
+ APP_ERROR_CHECK(err_code);
+
+ return result_code;
+}
+
+uint32_t sd_ant_crypto_key_set(uint8_t key_num, uint8_t * p_key)
+{
+ uint8_t * p_buffer;
+ uint32_t buffer_length;
+
+ tx_buf_alloc(&p_buffer, &buffer_length);
+
+ const uint32_t err_code = ant_crypto_key_set_req_enc(key_num,
+ p_key,
+ &(p_buffer[1]),
+ &buffer_length);
+
+ APP_ERROR_CHECK(err_code);
+
+ //@note: Increment buffer length as internally managed packet type field must be included.
+ return ser_sd_transport_cmd_write(p_buffer,
+ (++buffer_length),
+ crypto_key_set_rsp_dec);
+}
+
+/**@brief Command response callback function for @ref sd_ant_crypto_info_set ANT command.
+ *
+ * Callback for decoding the output parameters and the command response return code.
+ *
+ * @param[in] p_buffer Pointer to begin of command response buffer.
+ * @param[in] length Length of data in bytes.
+ *
+ * @return Decoded command response return code.
+ */
+static uint32_t crypto_info_set_rsp_dec(const uint8_t * p_buffer, uint16_t length)
+{
+ uint32_t result_code;
+
+ const uint32_t err_code = ant_crypto_info_set_rsp_dec(p_buffer,
+ length,
+ &result_code);
+ //@note: Should never fail.
+ APP_ERROR_CHECK(err_code);
+
+ return result_code;
+}
+
+uint32_t sd_ant_crypto_info_set(uint8_t type, uint8_t * p_info)
+{
+ uint8_t * p_buffer;
+ uint32_t buffer_length;
+
+ tx_buf_alloc(&p_buffer, &buffer_length);
+
+ const uint32_t err_code = ant_crypto_info_set_req_enc(type,
+ p_info,
+ &(p_buffer[1]),
+ &buffer_length);
+
+ APP_ERROR_CHECK(err_code);
+
+ //@note: Increment buffer length as internally managed packet type field must be included.
+ return ser_sd_transport_cmd_write(p_buffer,
+ (++buffer_length),
+ crypto_info_set_rsp_dec);
+}
+
+/**@brief Command response callback function for @ref sd_ant_crypto_info_get ANT command.
+ *
+ * Callback for decoding the output parameters and the command response return code.
+ *
+ * @param[in] p_buffer Pointer to begin of command response buffer.
+ * @param[in] length Length of data in bytes.
+ *
+ * @return Decoded command response return code.
+ */
+static uint32_t crypto_info_get_rsp_dec(const uint8_t * p_buffer, uint16_t length)
+{
+ uint32_t result_code;
+
+ const uint32_t err_code = ant_crypto_info_get_rsp_dec(p_buffer,
+ length,
+ mp_out_params[0],
+ &result_code);
+ //@note: Should never fail.
+ APP_ERROR_CHECK(err_code);
+
+ return result_code;
+}
+
+uint32_t sd_ant_crypto_info_get(uint8_t type, uint8_t * p_info)
+{
+ uint8_t * p_buffer;
+ uint32_t buffer_length;
+
+ tx_buf_alloc(&p_buffer, &buffer_length);
+ mp_out_params[0] = p_info;
+
+ const uint32_t err_code = ant_crypto_info_get_req_enc(type,
+ &(p_buffer[1]),
+ &buffer_length);
+
+ APP_ERROR_CHECK(err_code);
+
+ //@note: Increment buffer length as internally managed packet type field must be included.
+ return ser_sd_transport_cmd_write(p_buffer,
+ (++buffer_length),
+ crypto_info_get_rsp_dec);
+}
+
+/**@brief Command response callback function for @ref sd_ant_coex_config_set ANT command.
+ *
+ * Callback for decoding the output parameters and the command response return code.
+ *
+ * @param[in] p_buffer Pointer to begin of command response buffer.
+ * @param[in] length Length of data in bytes.
+ *
+ * @return Decoded command response return code.
+ */
+static uint32_t coex_config_set_rsp_dec(const uint8_t * p_buffer, uint16_t length)
+{
+ uint32_t result_code;
+
+ const uint32_t err_code = ant_coex_config_set_rsp_dec(p_buffer,
+ length,
+ &result_code);
+ //@note: Should never fail.
+ APP_ERROR_CHECK(err_code);
+
+ return result_code;
+}
+
+uint32_t sd_ant_coex_config_set(uint8_t channel, ANT_BUFFER_PTR * p_coex_config, ANT_BUFFER_PTR * p_adv_coex_config)
+{
+ uint8_t * p_buffer;
+ uint32_t buffer_length;
+
+ tx_buf_alloc(&p_buffer, &buffer_length);
+
+ const uint32_t err_code = ant_coex_config_set_req_enc(channel,
+ p_coex_config,
+ p_adv_coex_config,
+ &(p_buffer[1]),
+ &buffer_length);
+
+ APP_ERROR_CHECK(err_code);
+
+ //@note: Increment buffer length as internally managed packet type field must be included.
+ return ser_sd_transport_cmd_write(p_buffer,
+ (++buffer_length),
+ coex_config_set_rsp_dec);
+}
+
+/**@brief Command response callback function for @ref sd_ant_coex_config_get ANT command.
+ *
+ * Callback for decoding the output parameters and the command response return code.
+ *
+ * @param[in] p_buffer Pointer to begin of command response buffer.
+ * @param[in] length Length of data in bytes.
+ *
+ * @return Decoded command response return code.
+ */
+static uint32_t coex_config_get_rsp_dec(const uint8_t * p_buffer, uint16_t length)
+{
+ uint32_t result_code;
+
+ const uint32_t err_code = ant_coex_config_get_rsp_dec(p_buffer,
+ length,
+ mp_out_params[0],
+ mp_out_params[1],
+ &result_code);
+
+ //@note: Should never fail
+
+ APP_ERROR_CHECK(err_code);
+
+ return result_code;
+}
+
+uint32_t sd_ant_coex_config_get(uint8_t channel, ANT_BUFFER_PTR * p_coex_config, ANT_BUFFER_PTR * p_adv_coex_config)
+{
+ uint8_t * p_buffer;
+ uint32_t buffer_length;
+
+ tx_buf_alloc(&p_buffer, &buffer_length);
+ mp_out_params[0] = p_coex_config;
+ mp_out_params[1] = p_adv_coex_config;
+
+ const uint32_t err_code = ant_coex_config_get_req_enc(channel,
+ &(p_buffer[1]),
+ &buffer_length);
+
+ APP_ERROR_CHECK(err_code);
+
+ //@note: Increment buffer length as internally managed packet type field must be included.
+ return ser_sd_transport_cmd_write(p_buffer,
+ (++buffer_length),
+ coex_config_get_rsp_dec);
+}
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/application/codecs/ant/serializers/ant_acknowledge_message_tx.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/application/codecs/ant/serializers/ant_acknowledge_message_tx.c
new file mode 100644
index 0000000..ee4e763
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/application/codecs/ant/serializers/ant_acknowledge_message_tx.c
@@ -0,0 +1,90 @@
+/**
+ * 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+
+#include <stdlib.h>
+#include <string.h>
+#include "ant_app.h"
+#include "ble_serialization.h"
+#include "ant_struct_serialization.h"
+#include "cond_field_serialization.h"
+#include "app_util.h"
+
+uint32_t ant_acknowledge_message_tx_req_enc(uint8_t channel,
+ uint8_t size,
+ uint8_t const * const p_mesg,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len)
+{
+ SER_ASSERT_NOT_NULL(p_buf);
+ SER_ASSERT_NOT_NULL(p_buf_len);
+
+ uint8_t svc_number = SVC_ANT_TX_ACKNOWLEDGED_MESSAGE;
+ uint32_t err_code = NRF_SUCCESS;
+ uint32_t buf_len = *p_buf_len;
+ uint32_t index = 0;
+
+ err_code = uint8_t_enc(&svc_number, p_buf, buf_len, &index);
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code);
+
+ err_code = uint8_t_enc(&channel, p_buf, buf_len, &index);
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code);
+
+ err_code = uint8_t_enc(&size, p_buf, buf_len, &index);
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code);
+
+ err_code = uint8_vector_enc(p_mesg, size, p_buf, buf_len, &index);
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code);
+
+ SER_ASSERT_LENGTH_LEQ(index, *p_buf_len);
+
+ *p_buf_len = index;
+
+ return err_code;
+}
+
+
+uint32_t ant_acknowledge_message_tx_rsp_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ uint32_t * const p_result_code)
+{
+ // Use the ble cmd rsp dec function because it is adequte to decode
+ // the command response as it is the same for both ant and ble.
+ return ser_ble_cmd_rsp_dec(p_buf, packet_len, SVC_ANT_TX_ACKNOWLEDGED_MESSAGE, p_result_code);
+}
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/application/codecs/ant/serializers/ant_active_search_sharing_cycles_get.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/application/codecs/ant/serializers/ant_active_search_sharing_cycles_get.c
new file mode 100644
index 0000000..f0312f3
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/application/codecs/ant/serializers/ant_active_search_sharing_cycles_get.c
@@ -0,0 +1,96 @@
+/**
+ * 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+
+#include <stdlib.h>
+#include <string.h>
+#include "ant_app.h"
+#include "ble_serialization.h"
+#include "ant_struct_serialization.h"
+#include "cond_field_serialization.h"
+#include "app_util.h"
+
+uint32_t ant_active_search_sharing_cycles_get_req_enc(uint8_t channel,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len)
+{
+ uint32_t index = 0;
+ uint32_t err_code = NRF_SUCCESS;
+
+
+ SER_ASSERT_NOT_NULL(p_buf);
+ SER_ASSERT_NOT_NULL(p_buf_len);
+
+ p_buf[index++] = SVC_ANT_ACTIVE_SEARCH_SHARING_CYCLES_GET;
+ p_buf[index++] = channel;
+
+ SER_ASSERT_LENGTH_LEQ(index, *p_buf_len);
+
+ *p_buf_len = index;
+
+ return err_code;
+}
+
+uint32_t ant_active_search_sharing_cycles_get_rsp_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ void * const p_cycles,
+ uint32_t * const p_result_code)
+{
+ SER_ASSERT_NOT_NULL(p_buf);
+ SER_ASSERT_NOT_NULL(p_result_code);
+
+ uint32_t index = 0;
+ uint32_t err_code = ser_ble_cmd_rsp_result_code_dec(p_buf, &index, packet_len,
+ SVC_ANT_ACTIVE_SEARCH_SHARING_CYCLES_GET, p_result_code);
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code);
+
+ if (*p_result_code != NRF_SUCCESS)
+ {
+ SER_ASSERT_LENGTH_EQ(index, packet_len);
+
+ return NRF_SUCCESS;
+ }
+
+ err_code = uint8_t_dec(p_buf, packet_len, &index, p_cycles);
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code);
+
+ SER_ASSERT_LENGTH_EQ(index, packet_len);
+
+ return NRF_SUCCESS;
+}
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/application/codecs/ant/serializers/ant_active_search_sharing_cycles_set.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/application/codecs/ant/serializers/ant_active_search_sharing_cycles_set.c
new file mode 100644
index 0000000..a0e27d8
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/application/codecs/ant/serializers/ant_active_search_sharing_cycles_set.c
@@ -0,0 +1,78 @@
+/**
+ * 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+
+#include <stdlib.h>
+#include <string.h>
+#include "ant_app.h"
+#include "ble_serialization.h"
+#include "ant_struct_serialization.h"
+#include "cond_field_serialization.h"
+#include "app_util.h"
+
+uint32_t ant_active_search_sharing_cycles_set_req_enc(uint8_t channel,
+ uint8_t cycles,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len)
+{
+ uint32_t index = 0;
+ uint32_t err_code = NRF_SUCCESS;
+
+ SER_ASSERT_NOT_NULL(p_buf);
+ SER_ASSERT_NOT_NULL(p_buf_len);
+
+ p_buf[index++] = SVC_ANT_ACTIVE_SEARCH_SHARING_CYCLES_SET;
+ p_buf[index++] = channel;
+ p_buf[index++] = cycles;
+
+ SER_ASSERT_LENGTH_LEQ(index, *p_buf_len);
+
+ *p_buf_len = index;
+
+ return err_code;
+}
+
+uint32_t ant_active_search_sharing_cycles_set_rsp_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ uint32_t * const p_result_code)
+{
+ // Use the ble cmd rsp dec function because it is adequte to decode
+ // the command response as it is the same for both ant and ble.
+ return ser_ble_cmd_rsp_dec(p_buf, packet_len, SVC_ANT_ACTIVE_SEARCH_SHARING_CYCLES_SET, p_result_code);
+}
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/application/codecs/ant/serializers/ant_adv_burst_config_set.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/application/codecs/ant/serializers/ant_adv_burst_config_set.c
new file mode 100644
index 0000000..74020ee
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/application/codecs/ant/serializers/ant_adv_burst_config_set.c
@@ -0,0 +1,86 @@
+/**
+ * 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+
+#include <stdlib.h>
+#include <string.h>
+#include "ant_app.h"
+#include "ble_serialization.h"
+#include "ant_struct_serialization.h"
+#include "cond_field_serialization.h"
+#include "app_util.h"
+
+uint32_t ant_adv_burst_config_set_req_enc(uint8_t const * const p_config,
+ uint8_t size,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len)
+{
+ SER_ASSERT_NOT_NULL(p_buf);
+ SER_ASSERT_NOT_NULL(p_buf_len);
+
+ uint8_t svc_number = SVC_ANT_ADV_BURST_CONFIG_SET;
+ uint32_t err_code = NRF_SUCCESS;
+ uint32_t buf_len = *p_buf_len;
+ uint32_t index = 0;
+
+ err_code = uint8_t_enc(&svc_number, p_buf, buf_len, &index);
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code);
+
+ err_code = uint8_t_enc(&size, p_buf, buf_len, &index);
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code);
+
+ err_code = uint8_vector_enc(p_config, size, p_buf, buf_len, &index);
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code);
+
+ SER_ASSERT_LENGTH_LEQ(index, *p_buf_len);
+
+ *p_buf_len = index;
+
+ return err_code;
+}
+
+
+uint32_t ant_adv_burst_config_set_rsp_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ uint32_t * const p_result_code)
+{
+ // Use the ble cmd rsp dec function because it is adequte to decode
+ // the command response as it is the same for both ant and ble.
+ return ser_ble_cmd_rsp_dec(p_buf, packet_len, SVC_ANT_ADV_BURST_CONFIG_SET, p_result_code);
+}
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/application/codecs/ant/serializers/ant_app.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/application/codecs/ant/serializers/ant_app.h
new file mode 100644
index 0000000..c3c7fd2
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/application/codecs/ant/serializers/ant_app.h
@@ -0,0 +1,1652 @@
+/**
+ * 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#ifndef ANT_APP_H__
+#define ANT_APP_H__
+
+/**
+ * @addtogroup ser_app_s212_codecs Application codecs for S212
+ * @ingroup ser_codecs_app
+ */
+
+/**@file
+ *
+ * @defgroup ant_app Application command request encoders and command response decoders
+ * @{
+ * @ingroup ser_app_s212_codecs
+ *
+ * @brief Application command request encoders and command response decoders.
+ */
+//#include "ble.h"
+#include "ant_interface.h"
+
+/**@brief Encodes @ref sd_ant_enable command request.
+ *
+ * @sa @ref ant_enable_rsp_dec for command response decoder.
+ *
+ * @param[in] p_ant_enable_params Pointer to an @ref ANT_ENABLE structure.
+ * @param[in] p_buf Pointer to buffer where encoded data command will be
+ * returned.
+ * @param[in,out] p_buf_len \c in: Size of \p p_buf buffer.
+ * \c out: Length of encoded command packet.
+ *
+ * @retval NRF_SUCCESS Encoding success.
+ * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length.
+ */
+uint32_t ant_enable_req_enc(ANT_ENABLE * p_ant_enable_params,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len);
+
+/**@brief Decodes response to @ref sd_ant_enable command.
+ *
+ * @sa @ref ant_enable_req_enc for command request encoder.
+ *
+ * @param[in] p_buf Pointer to beginning of command response packet.
+ * @param[in] packet_len Length (in bytes) of response packet.
+ * @param[out] p_result_code Command result code.
+ *
+ * @retval NRF_SUCCESS Success.
+ * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length.
+ * @retval NRF_ERROR_DATA_SIZE Decoding failure. Length of \p p_event is too small to
+ * hold decoded event.
+ */
+uint32_t ant_enable_rsp_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ uint32_t * const p_result_code);
+
+/**@brief Encodes @ref sd_ant_channel_assign command request.
+ *
+ * @sa @ref ant_channel_assign_rsp_dec for command response decoder.
+ *
+ * @param[in] channel Channel is an unsigned char (1 octet) denoting the channel
+ * to assign.
+ * @param[in] channel_type Channel Type is an unsigned char (1 octet) denoting the
+ * channel type. See Assign Channel Parameters/Assign Channel
+ * Types in ant_parameters.h.
+ * @param[in] network Network is an unsigned char (1 octet) denoting the network
+ * key to associate with the channel.
+ * @param[in] ext_assign Ext Assign is a bit field (1 octet) for an extended
+ * assign. See Ext. Assign Channel Parameters in
+ * ant_parameters.h.
+ * @param[in] p_buf Pointer to buffer where encoded data command will be
+ * returned.
+ * @param[in,out] p_buf_len \c in: Size of \p p_buf buffer.
+ * \c out: Length of encoded command packet.
+ *
+ * @retval NRF_SUCCESS Encoding success.
+ * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length.
+ */
+uint32_t ant_channel_assign_req_enc(uint8_t channel,
+ uint8_t channel_type,
+ uint8_t network,
+ uint8_t ext_assign,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len);
+
+/**@brief Decodes response to @ref sd_ant_channel_assign command.
+ *
+ * @sa @ref ant_channel_assign_req_enc for command request encoder.
+ *
+ * @param[in] p_buf Pointer to beginning of command response packet.
+ * @param[in] packet_len Length (in bytes) of response packet.
+ * @param[out] p_result_code Command result code.
+ *
+ * @retval NRF_SUCCESS Success.
+ * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length.
+ * @retval NRF_ERROR_DATA_SIZE Decoding failure. Length of \p p_event is too small to
+ * hold decoded event.
+ */
+uint32_t ant_channel_assign_rsp_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ uint32_t * const p_result_code);
+
+/**@brief Encodes @ref sd_ant_channel_open command request.
+ *
+ * @sa @ref ant_channel_open_with_offset_rsp_dec for command response decoder.
+ *
+ * @param[in] channel Channel is an unsigned char (1 octet) denoting the channel to
+ * open.
+ * @param[in] usOffset Denote the offset from which to start the channel.
+ *
+ * @param[in] p_buf Pointer to buffer where encoded data command will be returned.
+ * @param[in,out] p_buf_len \c in: Size of \p p_buf buffer.
+ * \c out: Length of encoded command packet.
+ *
+ * @retval NRF_SUCCESS Encoding success.
+ * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length.
+ */
+uint32_t ant_channel_open_with_offset_req_enc(uint8_t channel,
+ uint16_t usOffset,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len);
+
+/**@brief Decodes response to @ref sd_ant_channel_open command.
+ *
+ * @sa @ref ant_channel_open_with_offset_req_enc for command request encoder.
+ *
+ * @param[in] p_buf Pointer to beginning of command response packet.
+ * @param[in] packet_len Length (in bytes) of response packet.
+ * @param[out] p_result_code Command result code.
+ *
+ * @retval NRF_SUCCESS Success.
+ * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length.
+ * @retval NRF_ERROR_DATA_SIZE Decoding failure. Length of \p p_event is too small to
+ * hold decoded event.
+ */
+uint32_t ant_channel_open_with_offset_rsp_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ uint32_t * const p_result_code);
+
+/**@brief Encodes @ref sd_ant_channel_id_set command request.
+ *
+ * @sa @ref ant_channel_id_set_rsp_dec for command response decoder.
+ *
+ * @param[in] channel Channel is an unsigned char (1 octet) denoting the channel
+ * number to set.
+ * @param[in] device_number Device Number is an unsigned short (2 octets) denoting the
+ * device number.
+ * @param[in] device_type Device Type is an unsigned char (1 octet) denoting the device
+ * type.
+ * @param[in] transmit_type Transmit Type is an unsigned char (1 octet) denoting the
+ * transmission type.
+ * @param[in] p_buf Pointer to buffer where encoded data command will be returned.
+ * @param[in,out] p_buf_len \c in: Size of \p p_buf buffer.
+ * \c out: Length of encoded command packet.
+ *
+ * @retval NRF_SUCCESS Encoding success.
+ * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length.
+ */
+uint32_t ant_channel_id_set_req_enc(uint8_t channel,
+ uint16_t device_number,
+ uint8_t device_type,
+ uint8_t transmit_type,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len);
+
+/**@brief Decodes response to @ref sd_ant_channel_id_set command.
+ *
+ * @sa @ref ant_channel_id_set_req_enc for command request encoder.
+ *
+ * @param[in] p_buf Pointer to beginning of command response packet.
+ * @param[in] packet_len Length (in bytes) of response packet.
+ * @param[out] p_result_code Command result code.
+ *
+ * @retval NRF_SUCCESS Success.
+ * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length.
+ * @retval NRF_ERROR_DATA_SIZE Decoding failure. Length of \p p_event is too small to
+ * hold decoded event.
+ */
+uint32_t ant_channel_id_set_rsp_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ uint32_t * const p_result_code);
+
+/**@brief Encodes @ref sd_ant_channel_period_set command request.
+ *
+ * @sa @ref ant_channel_period_set_rsp_dec for command response decoder.
+ *
+ * @param[in] channel Channel is an unsigned char (1 octet) denoting the channel
+ * number to set the period to.
+ * @param[in] period Period is an unsigned short (2 octets) denoting the period in
+ * 32 kHz counts (usPeriod/32768 s).
+ * @param[in] p_buf Pointer to buffer where encoded data command will be returned.
+ * @param[in,out] p_buf_len \c in: Size of \p p_buf buffer.
+ * \c out: Length of encoded command packet.
+ *
+ * @retval NRF_SUCCESS Encoding success.
+ * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length.
+ */
+uint32_t ant_channel_period_set_req_enc(uint8_t channel,
+ uint16_t period,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len);
+
+/**@brief Decodes response to @ref sd_ant_channel_period_set command.
+ *
+ * @sa @ref ant_channel_period_set_req_enc for command request encoder.
+ *
+ * @param[in] p_buf Pointer to beginning of command response packet.
+ * @param[in] packet_len Length (in bytes) of response packet.
+ * @param[out] p_result_code Command result code.
+ *
+ * @retval NRF_SUCCESS Success.
+ * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length.
+ * @retval NRF_ERROR_DATA_SIZE Decoding failure. Length of \p p_event is too small to
+ * hold decoded event.
+ */
+uint32_t ant_channel_period_set_rsp_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ uint32_t * const p_result_code);
+
+/**@brief Encodes @ref sd_ant_channel_radio_freq_set command request.
+ *
+ * @sa @ref ant_channel_radio_freq_set_rsp_dec for command response decoder.
+ *
+ * @param[in] channel Channel is an unsigned char (1 octet) denoting the channel
+ * number to set to.
+ * @param[in] freq Freq is an unsigned char (1 octet) denoting the radio
+ * frequency offset from 2400 MHz (eg. 2466 MHz, ucFreq = 66).
+ * @param[in] p_buf Pointer to buffer where encoded data command will be returned.
+ * @param[in,out] p_buf_len \c in: Size of \p p_buf buffer.
+ * \c out: Length of encoded command packet.
+ *
+ * @retval NRF_SUCCESS Encoding success.
+ * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length.
+ */
+uint32_t ant_channel_radio_freq_set_req_enc(uint8_t channel,
+ uint8_t freq,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len);
+
+/**@brief Decodes response to @ref sd_ant_channel_radio_freq_set command.
+ *
+ * @sa @ref ant_channel_radio_freq_set_req_enc for command request encoder.
+ *
+ * @param[in] p_buf Pointer to beginning of command response packet.
+ * @param[in] packet_len Length (in bytes) of response packet.
+ * @param[out] p_result_code Command result code.
+ *
+ * @retval NRF_SUCCESS Success.
+ * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length.
+ * @retval NRF_ERROR_DATA_SIZE Decoding failure. Length of \p p_event is too small to
+ * hold decoded event.
+ */
+uint32_t ant_channel_radio_freq_set_rsp_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ uint32_t * const p_result_code);
+
+/**@brief Encodes @ref sd_ant_broadcast_message_tx command request.
+ *
+ * @sa @ref ant_broadcast_message_tx_rsp_dec for command response decoder.
+ *
+ * @param[in] channel Channel is an unsigned char (1 octet) denoting the channel to
+ * send the data on.
+ * @param[in] size Size is an unsigned char (1 octet) denoting the size of the
+ * message, ucSize must be 8.
+ * @param[in] p_mesg Mesg is the buffer where the message is located (array must be
+ * 8 octets).
+ * @param[in] p_buf Pointer to buffer where encoded data command will be returned.
+ * @param[in,out] p_buf_len \c in: Size of \p p_buf buffer.
+ * \c out: Length of encoded command packet.
+ *
+ * @retval NRF_SUCCESS Encoding success.
+ * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length.
+ */
+uint32_t ant_broadcast_message_tx_req_enc(uint8_t channel,
+ uint8_t size,
+ uint8_t const * const p_mesg,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len);
+
+/**@brief Decodes response to @ref sd_ant_broadcast_message_tx command.
+ *
+ * @sa @ref ant_broadcast_message_tx_req_enc for command request encoder.
+ *
+ * @param[in] p_buf Pointer to beginning of command response packet.
+ * @param[in] packet_len Length (in bytes) of response packet.
+ * @param[out] p_result_code Command result code.
+ *
+ * @retval NRF_SUCCESS Success.
+ * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length.
+ * @retval NRF_ERROR_DATA_SIZE Decoding failure. Length of \p p_event is too small to
+ * hold decoded event.
+ */
+uint32_t ant_broadcast_message_tx_rsp_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ uint32_t * const p_result_code);
+
+
+/**@brief Encodes @ref sd_ant_acknowledge_message_tx command request.
+ *
+ * @sa @ref ant_acknowledge_message_tx_rsp_dec for command response decoder.
+ *
+ * @param[in] channel Channel is an unsigned char (1 octet) denoting the channel to
+ * send the data on.
+ * @param[in] size Size is an unsigned char (1 octet) denoting the size of the
+ * message, ucSize must be 8.
+ * @param[in] p_mesg Mesg is the buffer where the message is located (array must be
+ * 8 octets).
+ * @param[in] p_buf Pointer to buffer where encoded data command will be returned.
+ * @param[in,out] p_buf_len \c in: Size of \p p_buf buffer.
+ * \c out: Length of encoded command packet.
+ *
+ * @retval NRF_SUCCESS Encoding success.
+ * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length.
+ */
+uint32_t ant_acknowledge_message_tx_req_enc(uint8_t channel,
+ uint8_t size,
+ uint8_t const * const p_mesg,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len);
+
+/**@brief Decodes response to @ref sd_ant_acknowledge_message_tx command.
+ *
+ * @sa @ref ant_acknowledge_message_tx_req_enc for command request encoder.
+ *
+ * @param[in] p_buf Pointer to beginning of command response packet.
+ * @param[in] packet_len Length (in bytes) of response packet.
+ * @param[out] p_result_code Command result code.
+ *
+ * @retval NRF_SUCCESS Success.
+ * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length.
+ * @retval NRF_ERROR_DATA_SIZE Decoding failure. Length of \p p_event is too small to
+ * hold decoded event.
+ */
+uint32_t ant_acknowledge_message_tx_rsp_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ uint32_t * const p_result_code);
+
+/**@brief Encodes @ref sd_ant_channel_unassign command request.
+ *
+ * @sa @ref ant_channel_unassign_rsp_dec for command response decoder.
+ *
+ * @param[in] channel Channel is an unsigned char (1 octet) denoting the channel
+ * to unassign.
+ * @param[in] p_buf Pointer to buffer where encoded data command will be
+ * returned.
+ * @param[in,out] p_buf_len \c in: Size of \p p_buf buffer.
+ * \c out: Length of encoded command packet.
+ *
+ * @retval NRF_SUCCESS Encoding success.
+ * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length.
+ */
+uint32_t ant_channel_unassign_req_enc(uint8_t channel,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len);
+
+/**@brief Decodes response to @ref sd_ant_channel_unassign command.
+ *
+ * @sa @ref ant_channel_unassign_req_enc for command request encoder.
+ *
+ * @param[in] p_buf Pointer to beginning of command response packet.
+ * @param[in] packet_len Length (in bytes) of response packet.
+ * @param[out] p_result_code Command result code.
+ *
+ * @retval NRF_SUCCESS Success.
+ * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length.
+ * @retval NRF_ERROR_DATA_SIZE Decoding failure. Length of \p p_event is too small to
+ * hold decoded event.
+ */
+uint32_t ant_channel_unassign_rsp_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ uint32_t * const p_result_code);
+
+/**@brief Encodes @ref sd_ant_channel_close command request.
+ *
+ * @sa @ref ant_channel_close_rsp_dec for command response decoder.
+ *
+ * @param[in] channel Channel is an unsigned char (1 octet) denoting the channel
+ * to close.
+ * @param[in] p_buf Pointer to buffer where encoded data command will be returned.
+ * @param[in,out] p_buf_len \c in: Size of \p p_buf buffer.
+ * \c out: Length of encoded command packet.
+ *
+ * @retval NRF_SUCCESS Encoding success.
+ * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length.
+ */
+uint32_t ant_channel_close_req_enc(uint8_t channel,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len);
+
+/**@brief Decodes response to @ref sd_ant_channel_close command.
+ *
+ * @sa @ref ant_channel_close_req_enc for command request encoder.
+ *
+ * @param[in] p_buf Pointer to beginning of command response packet.
+ * @param[in] packet_len Length (in bytes) of response packet.
+ * @param[out] p_result_code Command result code.
+ *
+ * @retval NRF_SUCCESS Success.
+ * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length.
+ * @retval NRF_ERROR_DATA_SIZE Decoding failure. Length of \p p_event is too small to
+ * hold decoded event.
+ */
+uint32_t ant_channel_close_rsp_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ uint32_t * const p_result_code);
+
+/**@brief Encodes @ref sd_ant_network_address_set command request.
+ *
+ * @sa @ref ant_network_address_set_rsp_dec for command response decoder.
+ *
+ * @param[in] network Network is an unsigned char (1 octet) denoting the network
+ * number to assign the network address to.
+ * @param[in] p_network_key Network key is the pointer to location of the Network Key (8
+ * octets in length).
+ * @param[in] p_buf Pointer to buffer where encoded data command will be returned.
+ * @param[in,out] p_buf_len \c in: Size of \p p_buf buffer.
+ * \c out: Length of encoded command packet.
+ *
+ * @retval NRF_SUCCESS Encoding success.
+ * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length.
+ */
+uint32_t ant_network_address_set_req_enc(uint8_t network,
+ uint8_t const * const p_network_key,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len);
+
+/**@brief Decodes response to @ref sd_ant_network_address_set command.
+ *
+ * @sa @ref ant_network_address_set_req_enc for command request encoder.
+ *
+ * @param[in] p_buf Pointer to beginning of command response packet.
+ * @param[in] packet_len Length (in bytes) of response packet.
+ * @param[out] p_result_code Command result code.
+ *
+ * @retval NRF_SUCCESS Success.
+ * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length.
+ * @retval NRF_ERROR_DATA_SIZE Decoding failure. Length of \p p_event is too small to
+ * hold decoded event.
+ */
+uint32_t ant_network_address_set_rsp_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ uint32_t * const p_result_code);
+
+/**@brief Encodes @ref sd_ant_channel_radio_tx_power_set command request.
+ *
+ * @sa @ref ant_channel_radio_tx_power_set_rsp_dec for command response decoder.
+ *
+ * @param[in] channel Channel is an unsigned char (1 octet) denoting the channel
+ * number to assign the radio TX power.
+ * @param[in] tx_power TX Power is an unsigned char (1 octet) denoting the ANT
+ * transmit power index. See Radio TX Power Definitions in
+ * ant_parameters.h.
+ * @param[in] custom_tx_power Custom TX Power is an unsigned char (1 octet) denoting the
+ * custom nRF transmit power as defined in nrf51_bitfields.h.
+ * Only applicable if tx_power is set to custom TX power
+ * selection.
+ * @param[in] p_buf Pointer to buffer where encoded data command will be returned.
+ * @param[in,out] p_buf_len \c in: Size of \p p_buf buffer.
+ * \c out: Length of encoded command packet.
+ *
+ * @retval NRF_SUCCESS Encoding success.
+ * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length.
+ */
+uint32_t ant_channel_radio_tx_power_set_req_enc(uint8_t channel,
+ uint8_t tx_power,
+ uint8_t custom_tx_power,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len);
+
+/**@brief Decodes response to @ref sd_ant_channel_radio_tx_power_set command.
+ *
+ * @sa @ref ant_channel_radio_tx_power_set_req_enc for command request encoder.
+ *
+ * @param[in] p_buf Pointer to beginning of command response packet.
+ * @param[in] packet_len Length (in bytes) of response packet.
+ * @param[out] p_result_code Command result code.
+ *
+ * @retval NRF_SUCCESS Success.
+ * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length.
+ * @retval NRF_ERROR_DATA_SIZE Decoding failure. Length of \p p_event is too small to
+ * hold decoded event.
+ */
+uint32_t ant_channel_radio_tx_power_set_rsp_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ uint32_t * const p_result_code);
+
+/**@brief Encodes @ref sd_ant_channel_rx_search_timeout_set command request.
+ *
+ * @sa @ref ant_channel_rx_search_timeout_set_rsp_dec for command response decoder.
+ *
+ * @param[in] channel Channel is an unsigned char (1 octet) denoting the channel
+ * number to set.
+ * @param[in] timeout Timeout is an unsigned char (1 octet) denoting the time-out
+ * value.
+ * When applied to an assigned slave channel, ucTimeout is in 2.5
+ * second increments. Default = 10 (25 s) at channel assignment.
+ * When applied to an assigned master channel, ucTimeout is in
+ * 250 ms increments. Default = 0 (disabled) at channel assignment
+ * @param[in] p_buf Pointer to buffer where encoded data command will be returned.
+ * @param[in,out] p_buf_len \c in: Size of \p p_buf buffer.
+ * \c out: Length of encoded command packet.
+ *
+ * @retval NRF_SUCCESS Encoding success.
+ * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length.
+ */
+uint32_t ant_channel_rx_search_timeout_set_req_enc(uint8_t channel,
+ uint8_t timeout,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len);
+
+/**@brief Decodes response to @ref sd_ant_channel_rx_search_timeout_set command.
+ *
+ * @sa @ref ant_channel_rx_search_timeout_set_req_enc for command request encoder.
+ *
+ * @param[in] p_buf Pointer to beginning of command response packet.
+ * @param[in] packet_len Length (in bytes) of response packet.
+ * @param[out] p_result_code Command result code.
+ *
+ * @retval NRF_SUCCESS Success.
+ * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length.
+ * @retval NRF_ERROR_DATA_SIZE Decoding failure. Length of \p p_event is too small to
+ * hold decoded event.
+ */
+uint32_t ant_channel_rx_search_timeout_set_rsp_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ uint32_t * const p_result_code);
+
+/**@brief Encodes @ref sd_ant_channel_low_priority_rx_search_timeout_set command request.
+ *
+ * @sa @ref ant_channel_low_priority_rx_search_timeout_set_rsp_dec for command response decoder.
+ *
+ * @param[in] channel Channel is an unsigned char (1 octet) denoting the channel
+ * number to set.
+ * @param[in] timeout Timeout is an unsigned char (1 octet) denoting the time-out
+ * value in 2.5 seconds increments. Default = 2 (5s).
+ * @param[in] p_buf Pointer to buffer where encoded data command will be returned.
+ * @param[in,out] p_buf_len \c in: Size of \p p_buf buffer.
+ * \c out: Length of encoded command packet.
+ *
+ * @retval NRF_SUCCESS Encoding success.
+ * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length.
+ */
+uint32_t ant_channel_low_priority_rx_search_timeout_set_req_enc(uint8_t channel,
+ uint8_t timeout,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len);
+
+/**@brief Decodes response to @ref sd_ant_channel_low_priority_rx_search_timeout_set command.
+ *
+ * @sa @ref ant_channel_low_priority_rx_search_timeout_set_req_enc for command request encoder.
+ *
+ * @param[in] p_buf Pointer to beginning of command response packet.
+ * @param[in] packet_len Length (in bytes) of response packet.
+ * @param[out] p_result_code Command result code.
+ *
+ * @retval NRF_SUCCESS Success.
+ * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length.
+ * @retval NRF_ERROR_DATA_SIZE Decoding failure. Length of \p p_event is too small to
+ * hold decoded event.
+ */
+uint32_t ant_channel_low_priority_rx_search_timeout_set_rsp_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ uint32_t * const p_result_code);
+
+/**@brief Encodes @ref sd_ant_prox_search_set command request.
+ *
+ * @sa @ref ant_prox_search_set_rsp_dec for command response decoder.
+ *
+ * @param[in] channel Channel is an unsigned char (1 octet) denoting the channel
+ * number.
+ * @param[in] prox_threshold Prox threshold is an unsigned char (1 octet) denoting the
+ * minimum RSSI threshold required for acquisition during a
+ * search. See Radio Proximity Search Threshold in
+ * ant_parameters.h.
+ * @param[in] custom_prox_threshold Custom prox threshold is an unsigned char (1 octet) denoting
+ * the custom minimum RSSI threshold for acquisition during a
+ * search. Only applicable if ucProxThreshold is set to custom
+ * proximity selection.
+ * @param[in] p_buf Pointer to buffer where encoded data command will be returned.
+ * @param[in,out] p_buf_len \c in: Size of \p p_buf buffer.
+ * \c out: Length of encoded command packet.
+ *
+ * @retval NRF_SUCCESS Encoding success.
+ * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length.
+ */
+uint32_t ant_prox_search_set_req_enc(uint8_t channel,
+ uint8_t prox_threshold,
+ uint8_t custom_prox_threshold,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len);
+
+/**@brief Decodes response to @ref sd_ant_prox_search_set command.
+ *
+ * @sa @ref ant_prox_search_set_req_enc for command request encoder.
+ *
+ * @param[in] p_buf Pointer to beginning of command response packet.
+ * @param[in] packet_len Length (in bytes) of response packet.
+ * @param[out] p_result_code Command result code.
+ *
+ * @retval NRF_SUCCESS Success.
+ * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length.
+ * @retval NRF_ERROR_DATA_SIZE Decoding failure. Length of \p p_event is too small to
+ * hold decoded event.
+ */
+uint32_t ant_prox_search_set_rsp_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ uint32_t * const p_result_code);
+
+/**@brief Encodes @ref sd_ant_search_waveform_set command request.
+ *
+ * @sa @ref ant_search_waveform_set_rsp_dec for command response decoder.
+ *
+ * @param[in] channel Channel is an unsigned char (1 octet) denoting the channel
+ * number.
+ * @param[in] waveform Waveform is an unsigned short (2 octets) denoting the channel
+ * waveform period (usWaveform/32768 s). Default = 316.
+ * @param[in] p_buf Pointer to buffer where encoded data command will be returned.
+ * @param[in,out] p_buf_len \c in: Size of \p p_buf buffer.
+ * \c out: Length of encoded command packet.
+ *
+ * @retval NRF_SUCCESS Encoding success.
+ * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length.
+ */
+uint32_t ant_search_waveform_set_req_enc(uint8_t channel,
+ uint16_t waveform,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len);
+
+/**@brief Decodes response to @ref sd_ant_search_waveform_set command.
+ *
+ * @sa @ref ant_search_waveform_set_req_enc for command request encoder.
+ *
+ * @param[in] p_buf Pointer to beginning of command response packet.
+ * @param[in] packet_len Length (in bytes) of response packet.
+ * @param[out] p_result_code Command result code.
+ *
+ * @retval NRF_SUCCESS Success.
+ * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length.
+ * @retval NRF_ERROR_DATA_SIZE Decoding failure. Length of \p p_event is too small to
+ * hold decoded event.
+ */
+uint32_t ant_search_waveform_set_rsp_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ uint32_t * const p_result_code);
+
+/**@brief Encodes @ref sd_ant_channel_id_get command request.
+ *
+ * @sa @ref ant_channel_id_get_rsp_dec for command response decoder.
+ *
+ * @param[in] channel Channel is an unsigned char (1 octet) denoting the channel
+ * number.
+ * @param[in] p_buf Pointer to buffer where encoded data command will be returned.
+ * @param[in,out] p_buf_len \c in: Size of \p p_buf buffer.
+ * \c out: Length of encoded command packet.
+ *
+ * @retval NRF_SUCCESS Encoding success.
+ * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length.
+ */
+uint32_t ant_channel_id_get_req_enc(uint8_t channel,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len);
+
+/**@brief Decodes response to @ref sd_ant_channel_id_get command.
+ *
+ * @sa @ref ant_channel_id_get_req_enc for command request encoder.
+ *
+ * @param[in] p_buf Pointer to beginning of command response packet.
+ * @param[in] packet_len Length (in bytes) of response packet.
+ * @param[in] p_device_number Pointer to device number.
+ * @param[in] p_device_type Pointer to device type.
+ * @param[in] p_transmit_type Pointer to transmit type.
+ * @param[out] p_result_code Command result code.
+ *
+ * @retval NRF_SUCCESS Success.
+ * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length.
+ * @retval NRF_ERROR_DATA_SIZE Decoding failure. Length of \p p_event is too small to
+ * hold decoded event.
+ */
+uint32_t ant_channel_id_get_rsp_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ void * const p_device_number,
+ void * const p_device_type,
+ void * const p_transmit_type,
+ uint32_t * const p_result_code);
+
+/**@brief Encodes @ref sd_ant_channel_radio_freq_get command request.
+ *
+ * @sa @ref ant_channel_radio_freq_get_rsp_dec for command response decoder.
+ *
+ * @param[in] channel Channel is an unsigned char (1 octet) denoting the channel
+ * number.
+ * @param[in] p_buf Pointer to buffer where encoded data command will be returned.
+ * @param[in,out] p_buf_len \c in: Size of \p p_buf buffer.
+ * \c out: Length of encoded command packet.
+ *
+ * @retval NRF_SUCCESS Encoding success.
+ * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length.
+ */
+uint32_t ant_channel_radio_freq_get_req_enc(uint8_t channel,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len);
+
+/**@brief Decodes response to @ref sd_ant_channel_radio_freq_get command.
+ *
+ * @sa @ref ant_channel_radio_freq_get_req_enc for command request encoder.
+ *
+ * @param[in] p_buf Pointer to beginning of command response packet.
+ * @param[in] packet_len Length (in bytes) of response packet.
+ * @param[in] p_r_freq Pointer to radio frequency.
+ * @param[out] p_result_code Command result code.
+ *
+ * @retval NRF_SUCCESS Success.
+ * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length.
+ * @retval NRF_ERROR_DATA_SIZE Decoding failure. Length of \p p_event is too small to
+ * hold decoded event.
+ */
+uint32_t ant_channel_radio_freq_get_rsp_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ void * const p_r_freq,
+ uint32_t * const p_result_code);
+
+/**@brief Encodes @ref sd_ant_channel_period_get command request.
+ *
+ * @sa @ref ant_channel_period_get_rsp_dec for command response decoder.
+ *
+ * @param[in] channel Channel is an unsigned char (1 octet) denoting the channel
+ * number.
+ * @param[in] p_buf Pointer to buffer where encoded data command will be returned.
+ * @param[in,out] p_buf_len \c in: Size of \p p_buf buffer.
+ * \c out: Length of encoded command packet.
+ *
+ * @retval NRF_SUCCESS Encoding success.
+ * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length.
+ */
+uint32_t ant_channel_period_get_req_enc(uint8_t channel,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len);
+
+/**@brief Decodes response to @ref sd_ant_channel_period_get command.
+ *
+ * @sa @ref ant_channel_period_get_req_enc for command request encoder.
+ *
+ * @param[in] p_buf Pointer to beginning of command response packet.
+ * @param[in] packet_len Length (in bytes) of response packet.
+ * @param[in] p_period Pointer to period
+ * @param[out] p_result_code Command result code.
+ *
+ * @retval NRF_SUCCESS Success.
+ * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length.
+ * @retval NRF_ERROR_DATA_SIZE Decoding failure. Length of \p p_event is too small to
+ * hold decoded event.
+ */
+uint32_t ant_channel_period_get_rsp_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ void * p_period,
+ uint32_t * const p_result_code);
+
+/**@brief Encodes @ref sd_ant_search_channel_priority_set command request.
+ *
+ * @sa @ref ant_search_channel_priority_set_rsp_dec for command response decoder.
+ *
+ * @param[in] channel Channel is an unsigned char (1 octet) denoting the channel
+ * number.
+ * @param[in] search_priority Search Priority is an unsigned char (1 octet) denoting the
+ * search priority value. 0 to 7 (Default = 0).
+ * @param[in] p_buf Pointer to buffer where encoded data command will be returned.
+ * @param[in,out] p_buf_len \c in: Size of \p p_buf buffer.
+ * \c out: Length of encoded command packet.
+ *
+ * @retval NRF_SUCCESS Encoding success.
+ * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length.
+ */
+uint32_t ant_search_channel_priority_set_req_enc(uint8_t channel,
+ uint8_t search_priority,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len);
+
+/**@brief Decodes response to @ref sd_ant_search_channel_priority_set command.
+ *
+ * @sa @ref ant_search_channel_priority_set_req_enc for command request encoder.
+ *
+ * @param[in] p_buf Pointer to beginning of command response packet.
+ * @param[in] packet_len Length (in bytes) of response packet.
+ * @param[out] p_result_code Command result code.
+ *
+ * @retval NRF_SUCCESS Success.
+ * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length.
+ * @retval NRF_ERROR_DATA_SIZE Decoding failure. Length of \p p_event is too small to
+ * hold decoded event.
+ */
+uint32_t ant_search_channel_priority_set_rsp_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ uint32_t * const p_result_code);
+
+
+/**@brief Encodes @ref sd_ant_active_search_sharing_cycles_set command request.
+ *
+ * @sa @ref ant_active_search_sharing_cycles_set_rsp_dec for command response decoder.
+ *
+ * @param[in] channel Channel is an unsigned char (1 octet) denoting the channel
+ * number.
+ * @param[in] cycles Cycles is an unsigned char (1 octet) denoting the number of
+ * cycles to set.
+ * @param[in] p_buf Pointer to buffer where encoded data command will be returned.
+ * @param[in,out] p_buf_len \c in: Size of \p p_buf buffer.
+ * \c out: Length of encoded command packet.
+ *
+ * @retval NRF_SUCCESS Encoding success.
+ * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length.
+ */
+uint32_t ant_active_search_sharing_cycles_set_req_enc(uint8_t channel,
+ uint8_t cycles,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len);
+
+/**@brief Decodes response to @ref sd_ant_active_search_sharing_cycles_set command.
+ *
+ * @sa @ref ant_active_search_sharing_cycles_set_req_enc for command request encoder.
+ *
+ * @param[in] p_buf Pointer to beginning of command response packet.
+ * @param[in] packet_len Length (in bytes) of response packet.
+ * @param[out] p_result_code Command result code.
+ *
+ * @retval NRF_SUCCESS Success.
+ * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length.
+ * @retval NRF_ERROR_DATA_SIZE Decoding failure. Length of \p p_event is too small to
+ * hold decoded event.
+ */
+uint32_t ant_active_search_sharing_cycles_set_rsp_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ uint32_t * const p_result_code);
+
+/**@brief Encodes @ref sd_ant_lib_config_set command request.
+ *
+ * @sa @ref ant_lib_config_set_rsp_dec for command response decoder.
+ *
+ * @param[in] ant_lib_config ANT Lib Config an unsigned char (1 octet) denoting the ANT lib
+ * config bit flags. See ANT Library Config in ant_parameters.h.
+ * @param[in] p_buf Pointer to buffer where encoded data command will be returned.
+ * @param[in,out] p_buf_len \c in: Size of \p p_buf buffer.
+ * \c out: Length of encoded command packet.
+ *
+ * @retval NRF_SUCCESS Encoding success.
+ * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length.
+ */
+uint32_t ant_lib_config_set_req_enc(uint8_t ant_lib_config,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len);
+
+/**@brief Decodes response to @ref sd_ant_lib_config_set command.
+ *
+ * @sa @ref ant_lib_config_set_req_enc for command request encoder.
+ *
+ * @param[in] p_buf Pointer to beginning of command response packet.
+ * @param[in] packet_len Length (in bytes) of response packet.
+ * @param[out] p_result_code Command result code.
+ *
+ * @retval NRF_SUCCESS Success.
+ * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length.
+ * @retval NRF_ERROR_DATA_SIZE Decoding failure. Length of \p p_event is too small to
+ * hold decoded event.
+ */
+uint32_t ant_lib_config_set_rsp_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ uint32_t * const p_result_code);
+
+/**@brief Encodes @ref sd_ant_active_search_sharing_cycles_get command request.
+ *
+ * @sa @ref ant_active_search_sharing_cycles_get_rsp_dec for command response decoder.
+ *
+ * @param[in] channel Channel is an unsigned char (1 octet) denoting the channel
+ * number.
+ * @param[in] p_buf Pointer to buffer where encoded data command will be returned.
+ * @param[in,out] p_buf_len \c in: Size of \p p_buf buffer.
+ * \c out: Length of encoded command packet.
+ *
+ * @retval NRF_SUCCESS Encoding success.
+ * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length.
+ */
+uint32_t ant_active_search_sharing_cycles_get_req_enc(uint8_t channel,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len);
+
+/**@brief Decodes response to @ref sd_ant_active_search_sharing_cycles_get command.
+ *
+ * @sa @ref ant_active_search_sharing_cycles_get_req_enc for command request encoder.
+ *
+ * @param[in] p_buf Pointer to beginning of command response packet.
+ * @param[in] packet_len Length (in bytes) of response packet.
+ * @param[in] p_cycles Pointer to cycles.
+ * @param[out] p_result_code Command result code.
+ *
+ * @retval NRF_SUCCESS Success.
+ * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length.
+ * @retval NRF_ERROR_DATA_SIZE Decoding failure. Length of \p p_event is too small to
+ * hold decoded event.
+ */
+uint32_t ant_active_search_sharing_cycles_get_rsp_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ void * const p_cycles,
+ uint32_t * const p_result_code);
+
+/**@brief Encodes @ref sd_ant_lib_config_get command request.
+ *
+ * @sa @ref ant_lib_config_get_rsp_dec for command response decoder.
+ *
+ * @param[in] p_buf Pointer to buffer where encoded data command will be returned.
+ * @param[in,out] p_buf_len \c in: Size of \p p_buf buffer.
+ * \c out: Length of encoded command packet.
+ *
+ * @retval NRF_SUCCESS Encoding success.
+ * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length.
+ */
+uint32_t ant_lib_config_get_req_enc(uint8_t * const p_buf,
+ uint32_t * const p_buf_len);
+
+/**@brief Decodes response to @ref sd_ant_lib_config_get command.
+ *
+ * @sa @ref ant_lib_config_get_req_enc for command request encoder.
+ *
+ * @param[in] p_buf Pointer to beginning of command response packet.
+ * @param[in] packet_len Length (in bytes) of response packet.
+ * @param[in] p_ant_lib_config Pointer to the ANT library configuration.
+ * @param[out] p_result_code Command result code.
+ *
+ * @retval NRF_SUCCESS Success.
+ * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length.
+ * @retval NRF_ERROR_DATA_SIZE Decoding failure. Length of \p p_event is too small to
+ * hold decoded event.
+ */
+uint32_t ant_lib_config_get_rsp_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ void * const p_ant_lib_config,
+ uint32_t * const p_result_code);
+
+/**@brief Encodes @ref sd_ant_lib_config_clear command request.
+ *
+ * @sa @ref ant_lib_config_clear_rsp_dec for command response decoder.
+ *
+ * @param[in] ant_lib_config ANT lib config is an unsigned char (1 octet) denoting the
+ * ANT lib config bit(s) to clear. See ANT Library Config in
+ * ant_parameters.h.
+ * @param[in] p_buf Pointer to buffer where encoded data command will be returned.
+ * @param[in,out] p_buf_len \c in: Size of \p p_buf buffer.
+ * \c out: Length of encoded command packet.
+ *
+ * @retval NRF_SUCCESS Encoding success.
+ * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length.
+ */
+uint32_t ant_lib_config_clear_req_enc(uint8_t ant_lib_config,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len);
+
+/**@brief Decodes response to @ref sd_ant_lib_config_clear command.
+ *
+ * @sa @ref ant_lib_config_clear_req_enc for command request encoder.
+ *
+ * @param[in] p_buf Pointer to beginning of command response packet.
+ * @param[in] packet_len Length (in bytes) of response packet.
+ * @param[out] p_result_code Command result code.
+ *
+ * @retval NRF_SUCCESS Success.
+ * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length.
+ * @retval NRF_ERROR_DATA_SIZE Decoding failure. Length of \p p_event is too small to
+ * hold decoded event.
+ */
+uint32_t ant_lib_config_clear_rsp_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ uint32_t * const p_result_code);
+
+/**@brief Encodes @ref sd_ant_stack_reset command request.
+ *
+ * @sa @ref ant_stack_reset_rsp_dec for command response decoder.
+ *
+ * @param[in] p_buf Pointer to buffer where encoded data command will be returned.
+ * @param[in,out] p_buf_len \c in: Size of \p p_buf buffer.
+ * \c out: Length of encoded command packet.
+ *
+ * @retval NRF_SUCCESS Encoding success.
+ * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length.
+ */
+uint32_t ant_stack_reset_req_enc(uint8_t * const p_buf,
+ uint32_t * const p_buf_len);
+
+/**@brief Decodes response to @ref sd_ant_stack_reset command.
+ *
+ * @sa @ref ant_stack_reset_req_enc for command request encoder.
+ *
+ * @param[in] p_buf Pointer to beginning of command response packet.
+ * @param[in] packet_len Length (in bytes) of response packet.
+ * @param[out] p_result_code Command result code.
+ *
+ * @retval NRF_SUCCESS Success.
+ * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length.
+ * @retval NRF_ERROR_DATA_SIZE Decoding failure. Length of \p p_event is too small to
+ * hold decoded event.
+ */
+uint32_t ant_stack_reset_rsp_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ uint32_t * const p_result_code);
+
+/**@brief Encodes @ref sd_ant_rx_scan_mode_start command request.
+ *
+ * @sa @ref ant_rx_scan_mode_start_rsp_dec for command response decoder.
+ *
+ * @param[in] sync_channel_packets_only Sync channel packets only is an unsigned char (1 octet)
+ * denoting synchronous channel only scanning mode.
+ * 0 = disable, 1 = enable.
+ * @param[in] p_buf Pointer to buffer where encoded data command will be
+ * returned.
+ * @param[in,out] p_buf_len \c in: Size of \p p_buf buffer.
+ * \c out: Length of encoded command packet.
+ *
+ * @retval NRF_SUCCESS Encoding success.
+ * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length.
+ */
+uint32_t ant_rx_scan_mode_start_req_enc(uint8_t sync_channel_packets_only,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len);
+
+/**@brief Decodes response to @ref sd_ant_rx_scan_mode_start command.
+ *
+ * @sa @ref ant_rx_scan_mode_start_req_enc for command request encoder.
+ *
+ * @param[in] p_buf Pointer to beginning of command response packet.
+ * @param[in] packet_len Length (in bytes) of response packet.
+ * @param[out] p_result_code Command result code.
+ *
+ * @retval NRF_SUCCESS Success.
+ * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length.
+ * @retval NRF_ERROR_DATA_SIZE Decoding failure. Length of \p p_event is too small to
+ * hold decoded event.
+ */
+uint32_t ant_rx_scan_mode_start_rsp_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ uint32_t * const p_result_code);
+
+/**@brief Encodes @ref sd_ant_id_list_add command request.
+ *
+ * @sa @ref ant_id_list_add_rsp_dec for command response decoder.
+ *
+ * @param[in] channel Channel is an unsigned char (1 octet) denoting the channel
+ * number to add the list entry to.
+ * @param[in] p_dev_id Dev ID is the pointer to the buffer (4 octets) containing
+ * device ID information with the following format:
+ * Byte0 = DeviceNumber_LSB
+ * Byte1 = DeviceNumber_MSB
+ * Byte2 = DeviceType
+ * Byte3 = TransType
+ * @param[in] list_index List index is an unsigned char (1 octet) denoting the index
+ * where the specified channel ID is to be placed in the list (0-3).
+ * @param[in] p_buf Pointer to buffer where encoded data command will be returned.
+ * @param[in,out] p_buf_len \c in: Size of \p p_buf buffer.
+ * \c out: Length of encoded command packet.
+ *
+ * @retval NRF_SUCCESS Encoding success.
+ * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length.
+ */
+uint32_t ant_id_list_add_req_enc(uint8_t channel,
+ uint8_t const * const p_dev_id,
+ uint8_t list_index,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len);
+
+/**@brief Decodes response to @ref sd_ant_id_list_add command.
+ *
+ * @sa @ref ant_id_list_add_req_enc for command request encoder.
+ *
+ * @param[in] p_buf Pointer to beginning of command response packet.
+ * @param[in] packet_len Length (in bytes) of response packet.
+ * @param[out] p_result_code Command result code.
+ *
+ * @retval NRF_SUCCESS Success.
+ * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length.
+ * @retval NRF_ERROR_DATA_SIZE Decoding failure. Length of \p p_event is too small to
+ * hold decoded event.
+ */
+uint32_t ant_id_list_add_rsp_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ uint32_t * const p_result_code);
+
+/**@brief Encodes @ref sd_ant_id_list_config command request.
+ *
+ * @sa @ref ant_id_list_config_rsp_dec for command response decoder.
+ *
+ * @param[in] channel Channel is an unsigned char (1 octet) denoting the
+ * channel number of the device ID list.
+ * @param[in] id_list_size ID list size is an unsigned char (1 octet) denoting the size of
+ * the inclusion or exclusion list (0-4).
+ * @param[in] inc_exc_flag Inc exc flag is an unsigned char (1 octet) denoting the type of
+ * list as Include(0) or Exclude(1).
+ * @param[in] channel
+ * @param[in] p_buf Pointer to buffer where encoded data command will be returned.
+ * @param[in,out] p_buf_len \c in: Size of \p p_buf buffer.
+ * \c out: Length of encoded command packet.
+ *
+ * @retval NRF_SUCCESS Encoding success.
+ * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length.
+ */
+uint32_t ant_id_list_config_req_enc(uint8_t channel,
+ uint8_t id_list_size,
+ uint8_t inc_exc_flag,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len);
+
+/**@brief Decodes response to @ref sd_ant_id_list_config command.
+ *
+ * @sa @ref ant_id_list_config_req_enc for command request encoder.
+ *
+ * @param[in] p_buf Pointer to beginning of command response packet.
+ * @param[in] packet_len Length (in bytes) of response packet.
+ * @param[out] p_result_code Command result code.
+ *
+ * @retval NRF_SUCCESS Success.
+ * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length.
+ * @retval NRF_ERROR_DATA_SIZE Decoding failure. Length of \p p_event is too small to
+ * hold decoded event.
+ */
+uint32_t ant_id_list_config_rsp_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ uint32_t * const p_result_code);
+
+/**@brief Encodes @ref sd_ant_channel_status_get command request.
+ *
+ * @sa @ref ant_channel_status_get_rsp_dec for command response decoder.
+ *
+ * @param[in] channel Channel is an unsigned char (1 octet) denoting the channel
+ * number.
+ * @param[in] p_buf Pointer to buffer where encoded data command will be returned.
+ * @param[in,out] p_buf_len \c in: Size of \p p_buf buffer.
+ * \c out: Length of encoded command packet.
+ *
+ * @retval NRF_SUCCESS Encoding success.
+ * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length.
+ */
+uint32_t ant_channel_status_get_req_enc(uint8_t channel,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len);
+
+/**@brief Decodes response to @ref sd_ant_channel_status_get command.
+ *
+ * @sa @ref ant_channel_status_get_req_enc for command request encoder.
+ *
+ * @param[in] p_buf Pointer to beginning of command response packet.
+ * @param[in] packet_len Length (in bytes) of response packet.
+ * @param[in] p_status Pointer to status
+ * @param[out] p_result_code Command result code.
+ *
+ * @retval NRF_SUCCESS Success.
+ * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length.
+ * @retval NRF_ERROR_DATA_SIZE Decoding failure. Length of \p p_event is too small to
+ * hold decoded event.
+ */
+uint32_t ant_channel_status_get_rsp_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ void * const p_status,
+ uint32_t * const p_result_code);
+
+/**@brief Encodes @ref sd_ant_cw_test_mode_init command request.
+ *
+ * @sa @ref ant_cw_test_mode_init_rsp_dec for command response decoder.
+ *
+ * @param[in] p_buf Pointer to buffer where encoded data command will be returned.
+ * @param[in,out] p_buf_len \c in: Size of \p p_buf buffer.
+ * \c out: Length of encoded command packet.
+ *
+ * @retval NRF_SUCCESS Encoding success.
+ * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length.
+ */
+uint32_t ant_cw_test_mode_init_req_enc(uint8_t * const p_buf,
+ uint32_t * const p_buf_len);
+
+/**@brief Decodes response to @ref sd_ant_cw_test_mode_init command.
+ *
+ * @sa @ref ant_cw_test_mode_init_req_enc for command request encoder.
+ *
+ * @param[in] p_buf Pointer to beginning of command response packet.
+ * @param[in] packet_len Length (in bytes) of response packet.
+ * @param[out] p_result_code Command result code.
+ *
+ * @retval NRF_SUCCESS Success.
+ * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length.
+ * @retval NRF_ERROR_DATA_SIZE Decoding failure. Length of \p p_event is too small to
+ * hold decoded event.
+ */
+uint32_t ant_cw_test_mode_init_rsp_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ uint32_t * const p_result_code);
+
+/**@brief Encodes @ref sd_ant_cw_test_mode command request.
+ *
+ * @sa @ref ant_cw_test_mode_rsp_dec for command response decoder.
+ *
+ * @param[in] radio_freq Radio freq is an unsigned char (1 octet) denoting the radio
+ * frequency offset from 2400 MHz for continuous wave mode.
+ * (eg. 2466 MHz, ucRadioFreq = 66).
+ * @param[in] tx_power TX Power is an unsigned char (1 octet) denoting the ANT transmit
+ * power index for continuous wave mode. See Radio TX Power
+ * Definitions in ant_parameters.h
+ * @param[in] custom_tx_power Custom TX power is an unsigned char (1 octet) denoting the
+ * custom nRF transmit power as defined in nrf51_bitfields.h. Only
+ * applicable if ucTxPower is set to custom TX power selection.
+ * @param[in] mode Mode is an unsigned char (1 octet) denoting test mode type where
+ * 0 = cw tx carrier transmission, 1 = cw tx modulated transmission.
+ * @param[in] p_buf Pointer to buffer where encoded data command will be returned.
+ * @param[in,out] p_buf_len \c in: Size of \p p_buf buffer.
+ * \c out: Length of encoded command packet.
+ *
+ * @retval NRF_SUCCESS Encoding success.
+ * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length.
+ */
+uint32_t ant_cw_test_mode_req_enc(uint8_t radio_freq,
+ uint8_t tx_power,
+ uint8_t custom_tx_power,
+ uint8_t mode,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len);
+
+/**@brief Decodes response to @ref sd_ant_cw_test_mode command.
+ *
+ * @sa @ref ant_cw_test_mode_req_enc for command request encoder.
+ *
+ * @param[in] p_buf Pointer to beginning of command response packet.
+ * @param[in] packet_len Length (in bytes) of response packet.
+ * @param[out] p_result_code Command result code.
+ *
+ * @retval NRF_SUCCESS Success.
+ * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length.
+ * @retval NRF_ERROR_DATA_SIZE Decoding failure. Length of \p p_event is too small to
+ * hold decoded event.
+ */
+uint32_t ant_cw_test_mode_rsp_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ uint32_t * const p_result_code);
+
+/**@brief Encodes @ref sd_ant_version_get command request.
+ *
+ * @sa @ref ant_version_get_rsp_dec for command response decoder.
+ *
+ * @param[in] p_buf Pointer to buffer where encoded data command will be returned.
+ * @param[in,out] p_buf_len \c in: Size of \p p_buf buffer.
+ * \c out: Length of encoded command packet.
+ *
+ * @retval NRF_SUCCESS Encoding success.
+ * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length.
+ */
+uint32_t ant_version_get_req_enc(uint8_t * const p_buf,
+ uint32_t * const p_buf_len);
+
+/**@brief Decodes response to @ref sd_ant_version_get command.
+ *
+ * @sa @ref ant_version_get_req_enc for command request encoder.
+ *
+ * @param[in] p_buf Pointer to beginning of command response packet.
+ * @param[in] packet_len Length (in bytes) of response packet.
+ * @param[in] p_version Pointer to version string buffer.
+ * @param[out] p_result_code Command result code.
+ *
+ * @retval NRF_SUCCESS Success.
+ * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length.
+ * @retval NRF_ERROR_DATA_SIZE Decoding failure. Length of \p p_event is too small to
+ * hold decoded event.
+ */
+uint32_t ant_version_get_rsp_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ void * * const p_version,
+ uint32_t * const p_result_code);
+
+/**@brief Encodes @ref sd_ant_capabilities_get command request.
+ *
+ * @sa @ref ant_capabilities_get_rsp_dec for command response decoder.
+ *
+ * @param[in] p_buf Pointer to buffer where encoded data command will be returned.
+ * @param[in,out] p_buf_len \c in: Size of \p p_buf buffer.
+ * \c out: Length of encoded command packet.
+ *
+ * @retval NRF_SUCCESS Encoding success.
+ * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length.
+ */
+uint32_t ant_capabilities_get_req_enc(uint8_t * const p_buf,
+ uint32_t * const p_buf_len);
+
+/**@brief Decodes response to @ref sd_ant_capabilities_get command.
+ *
+ * @sa @ref ant_capabilities_get_req_enc for command request encoder.
+ *
+ * @param[in] p_buf Pointer to beginning of command response packet.
+ * @param[in] packet_len Length (in bytes) of response packet.
+ * @param[in] pp_capabilities Pointer to pointer to capabilities buffer.
+ * @param[out] p_result_code Command result code.
+ *
+ * @retval NRF_SUCCESS Success.
+ * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length.
+ * @retval NRF_ERROR_DATA_SIZE Decoding failure. Length of \p p_event is too small to
+ * hold decoded event.
+ */
+uint32_t ant_capabilities_get_rsp_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ void * * const pp_capabilities,
+ uint32_t * const p_result_code);
+
+/**@brief Encodes @ref sd_ant_crypto_channel_enable command request.
+ *
+ * @sa @ref ant_crypto_channel_enable_rsp_dec for command response decoder.
+ *
+ * @param[in] channel Channel is an unsigned char (1 octet) denoting the channel in
+ * which encryption mode is set.
+ * @param[in] enable Enable is an unsigned char (1 octet) denoting the encryption
+ * mode. See Encrypted Channel Defines in ant_parameters.h.
+ * @param[in] key_num Key num is an unsigned char (1 octet) denoting the key index of
+ * the 128-bit key to be used for encryption. The key index range
+ * is bound by the number of encrypted channels configured by
+ * sd_ant_enable(). If sd_ant_enable() is not used then by default
+ * key num is 0. Range is [0 to (num encrypted channels - 1)], if
+ * 1 or more encrypted channels are configured.
+ * @param[in] decimation_rate Decimation rate is an unsigned char (1 octet) denoting the
+ * decimate rate to apply for encrypted slave channel. Must be > 0.
+ * @param[in] p_buf Pointer to buffer where encoded data command will be returned.
+ * @param[in,out] p_buf_len \c in: Size of \p p_buf buffer.
+ * \c out: Length of encoded command packet.
+ *
+ * @retval NRF_SUCCESS Encoding success.
+ * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length.
+ */
+uint32_t ant_crypto_channel_enable_req_enc(uint8_t channel,
+ uint8_t enable,
+ uint8_t key_num,
+ uint8_t decimation_rate,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len);
+
+/**@brief Decodes response to @ref sd_ant_crypto_channel_enable command.
+ *
+ * @sa @ref ant_crypto_channel_enable_req_enc for command request encoder.
+ *
+ * @param[in] p_buf Pointer to beginning of command response packet.
+ * @param[in] packet_len Length (in bytes) of response packet.
+ * @param[out] p_result_code Command result code.
+ *
+ * @retval NRF_SUCCESS Success.
+ * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length.
+ * @retval NRF_ERROR_DATA_SIZE Decoding failure. Length of \p p_event is too small to
+ * hold decoded event.
+ */
+uint32_t ant_crypto_channel_enable_rsp_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ uint32_t * const p_result_code);
+
+/**@brief Encodes @ref sd_ant_adv_burst_config_set command request.
+ *
+ * @sa @ref ant_adv_burst_config_set_rsp_dec for command response decoder.
+ *
+ * @param[in] p_config Config is a buffer containing the advanced burst
+ * configuration to be set.
+ * @param[in] size Size is an unsigned char (1 octet) denoting the size of the
+ * configuration parameter buffer.
+ * @param[in] p_buf Pointer to buffer where encoded data command will be returned.
+ * @param[in,out] p_buf_len \c in: Size of \p p_buf buffer.
+ * \c out: Length of encoded command packet.
+ *
+ * @retval NRF_SUCCESS Encoding success.
+ * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length.
+ */
+uint32_t ant_adv_burst_config_set_req_enc(uint8_t const * const p_config,
+ uint8_t size,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len);
+
+/**@brief Decodes response to @ref sd_ant_adv_burst_config_set command.
+ *
+ * @sa @ref ant_adv_burst_config_set_req_enc for command request encoder.
+ *
+ * @param[in] p_buf Pointer to beginning of command response packet.
+ * @param[in] packet_len Length (in bytes) of response packet.
+ * @param[out] p_result_code Command result code.
+ *
+ * @retval NRF_SUCCESS Success.
+ * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length.
+ * @retval NRF_ERROR_DATA_SIZE Decoding failure. Length of \p p_event is too small to
+ * hold decoded event.
+ */
+uint32_t ant_adv_burst_config_set_rsp_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ uint32_t * const p_result_code);
+
+/**@brief Encodes @ref sd_ant_crypto_key_set command request.
+ *
+ * @sa @ref ant_crypto_key_set_rsp_dec for command response decoder.
+ *
+ * @param[in] key_num Key num is an unsigned char (1 octet) denoting the key index for
+ * assignment.
+ * @param[in] p_key Buffer (16 octets) containing the 128-bit AES key to be
+ * assigned to the key index.
+ *
+ * @param[in] p_buf Pointer to buffer where encoded data command will be returned.
+ * @param[in,out] p_buf_len \c in: Size of \p p_buf buffer.
+ * \c out: Length of encoded command packet.
+ *
+ * @retval NRF_SUCCESS Encoding success.
+ * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length.
+ */
+uint32_t ant_crypto_key_set_req_enc(uint8_t key_num,
+ uint8_t const * const p_key,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len);
+
+/**@brief Decodes response to @ref sd_ant_crypto_key_set command.
+ *
+ * @sa @ref ant_crypto_key_set_req_enc for command request encoder.
+ *
+ * @param[in] p_buf Pointer to beginning of command response packet.
+ * @param[in] packet_len Length (in bytes) of response packet.
+ * @param[out] p_result_code Command result code.
+ *
+ * @retval NRF_SUCCESS Success.
+ * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length.
+ * @retval NRF_ERROR_DATA_SIZE Decoding failure. Length of \p p_event is too small to
+ * hold decoded event.
+ */
+uint32_t ant_crypto_key_set_rsp_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ uint32_t * const p_result_code);
+
+/**@brief Encodes @ref sd_ant_crypto_info_set command request.
+ *
+ * @sa @ref ant_crypto_info_set_rsp_dec for command response decoder.
+ *
+ * @param[in] type Type is an unsigned char (1 octet) denoting the type of
+ * information being set.
+ * @param[in] p_info Pointer to a buffer buffer containing the information being set.
+ *
+ * @param[in] p_buf Pointer to buffer where encoded data command will be returned.
+ * @param[in,out] p_buf_len \c in: Size of \p p_buf buffer.
+ * \c out: Length of encoded command packet.
+ *
+ * @retval NRF_SUCCESS Encoding success.
+ * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length.
+ */
+uint32_t ant_crypto_info_set_req_enc(uint8_t type,
+ uint8_t const * const p_info,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len);
+
+/**@brief Decodes response to @ref sd_ant_crypto_info_set command.
+ *
+ * @sa @ref ant_crypto_info_set_req_enc for command request encoder.
+ *
+ * @param[in] p_buf Pointer to beginning of command response packet.
+ * @param[in] packet_len Length (in bytes) of response packet.
+ * @param[out] p_result_code Command result code.
+ *
+ * @retval NRF_SUCCESS Success.
+ * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length.
+ * @retval NRF_ERROR_DATA_SIZE Decoding failure. Length of \p p_event is too small to
+ * hold decoded event.
+ */
+uint32_t ant_crypto_info_set_rsp_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ uint32_t * const p_result_code);
+
+/**@brief Encodes @ref sd_ant_crypto_info_get command request.
+ *
+ * @sa @ref ant_crypto_info_get_rsp_dec for command response decoder.
+ *
+ * @param[in] type Type is an unsigned char (1 octet) denoting the type of
+ * information being set.
+ * @param[in] p_buf Pointer to buffer where encoded data command will be returned.
+ * @param[in,out] p_buf_len \c in: Size of \p p_buf buffer.
+ * \c out: Length of encoded command packet.
+ *
+ * @retval NRF_SUCCESS Encoding success.
+ * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length.
+ */
+uint32_t ant_crypto_info_get_req_enc(uint8_t type,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len);
+
+/**@brief Decodes response to @ref sd_ant_crypto_info_get command.
+ *
+ * @sa @ref ant_crypto_info_get_req_enc for command request encoder.
+ *
+ * @param[in] p_buf Pointer to beginning of command response packet.
+ * @param[in] packet_len Length (in bytes) of response packet.
+ * @param[in] p_info Pointer to the info buffer.
+ * @param[out] p_result_code Command result code.
+ *
+ * @retval NRF_SUCCESS Success.
+ * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length.
+ * @retval NRF_ERROR_DATA_SIZE Decoding failure. Length of \p p_event is too small to
+ * hold decoded event.
+ */
+uint32_t ant_crypto_info_get_rsp_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ void * const p_info,
+ uint32_t * const p_result_code);
+
+/**@brief Encodes @ref sd_ant_coex_config_set command request.
+ *
+ * @sa @ref ant_coex_config_set_rsp_dec for command response decoder.
+ *
+ * @param[in] channel Channel is an unsigned char (1 octet) denoting the channel for
+ * which the coexistence configuration is to be set
+ * @param[in] p_config Pointer to a buffer containing the configuration to be set.
+ * @param[in] p_adv_coex_config Pointer to a buffer containing the advanced coexistence configuration
+ * to be set.
+ *
+ * @param[in] p_buf Pointer to buffer where encoded data command will be returned.
+ * @param[in,out] p_buf_len \c in: Size of \p p_buf buffer.
+ * \c out: Length of encoded command packet.
+ *
+ * @retval NRF_SUCCESS Encoding success.
+ * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length.
+ */
+uint32_t ant_coex_config_set_req_enc(uint8_t channel,
+ ANT_BUFFER_PTR const * const p_config,
+ ANT_BUFFER_PTR const * const p_adv_coex_config,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len);
+
+/**@brief Decodes response to @ref sd_ant_coex_config_set command.
+ *
+ * @sa @ref ant_coex_config_set_req_enc for command request encoder.
+ *
+ * @param[in] p_buf Pointer to beginning of command response packet.
+ * @param[in] packet_len Length (in bytes) of response packet.
+ * @param[out] p_result_code Command result code.
+ *
+ * @retval NRF_SUCCESS Success.
+ * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length.
+ * @retval NRF_ERROR_DATA_SIZE Decoding failure. Length of \p p_event is too small to
+ * hold decoded event.
+ */
+uint32_t ant_coex_config_set_rsp_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ uint32_t * const p_result_code);
+
+/**@brief Encodes @ref sd_ant_coex_config_get command request.
+ *
+ * @sa @ref ant_coex_config_get_rsp_dec for command response decoder.
+ *
+ * @param[in] channel Channel is an unsigned char (1 octet) denoting the channel to
+ * query.
+ * @param[in] p_buf Pointer to buffer where encoded data command will be returned.
+ * @param[in,out] p_buf_len \c in: Size of \p p_buf buffer.
+ * \c out: Length of encoded command packet.
+ *
+ * @retval NRF_SUCCESS Encoding success.
+ * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length.
+ */
+uint32_t ant_coex_config_get_req_enc(uint8_t channel,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len);
+
+/**@brief Decodes response to @ref sd_ant_coex_config_get command.
+ *
+ * @sa @ref ant_coex_config_get_req_enc for command request encoder.
+ *
+ * @param[in] p_buf Pointer to beginning of command response packet.
+ * @param[in] packet_len Length (in bytes) of response packet.
+ * @param[in] p_coex_config Pointer to the coexistence configuration buffer.
+ * @param[in] p_adv_coex_config Pointer to the advanced coexistence configuration buffer.
+ * @param[out] p_result_code Command result code.
+ *
+ * @retval NRF_SUCCESS Success.
+ * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length.
+ * @retval NRF_ERROR_DATA_SIZE Decoding failure. Length of \p p_event is too small to
+ * hold decoded event.
+ */
+uint32_t ant_coex_config_get_rsp_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ void * const p_coex_config,
+ void * const p_adv_coex_config,
+ uint32_t * const p_result_code);
+/** @} */
+#endif
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/application/codecs/ant/serializers/ant_broadcast_message_tx.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/application/codecs/ant/serializers/ant_broadcast_message_tx.c
new file mode 100644
index 0000000..86548e0
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/application/codecs/ant/serializers/ant_broadcast_message_tx.c
@@ -0,0 +1,90 @@
+/**
+ * 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+
+#include <stdlib.h>
+#include <string.h>
+#include "ant_app.h"
+#include "ble_serialization.h"
+#include "ant_struct_serialization.h"
+#include "cond_field_serialization.h"
+#include "app_util.h"
+
+uint32_t ant_broadcast_message_tx_req_enc(uint8_t channel,
+ uint8_t size,
+ uint8_t const * const p_mesg,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len)
+{
+ SER_ASSERT_NOT_NULL(p_buf);
+ SER_ASSERT_NOT_NULL(p_buf_len);
+
+ uint8_t svc_number = SVC_ANT_TX_BROADCAST_MESSAGE;
+ uint32_t err_code = NRF_SUCCESS;
+ uint32_t buf_len = *p_buf_len;
+ uint32_t index = 0;
+
+ err_code = uint8_t_enc(&svc_number, p_buf, buf_len, &index);
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code);
+
+ err_code = uint8_t_enc(&channel, p_buf, buf_len, &index);
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code);
+
+ err_code = uint8_t_enc(&size, p_buf, buf_len, &index);
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code);
+
+ err_code = uint8_vector_enc(p_mesg, size, p_buf, buf_len, &index);
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code);
+
+ SER_ASSERT_LENGTH_LEQ(index, *p_buf_len);
+
+ *p_buf_len = index;
+
+ return err_code;
+}
+
+
+uint32_t ant_broadcast_message_tx_rsp_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ uint32_t * const p_result_code)
+{
+ // Use the ble cmd rsp dec function because it is adequte to decode
+ // the command response as it is the same for both ant and ble.
+ return ser_ble_cmd_rsp_dec(p_buf, packet_len, SVC_ANT_TX_BROADCAST_MESSAGE, p_result_code);
+}
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/application/codecs/ant/serializers/ant_capabilities_get.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/application/codecs/ant/serializers/ant_capabilities_get.c
new file mode 100644
index 0000000..9d47722
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/application/codecs/ant/serializers/ant_capabilities_get.c
@@ -0,0 +1,93 @@
+/**
+ * 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+
+#include <stdlib.h>
+#include <string.h>
+#include "ant_app.h"
+#include "ble_serialization.h"
+#include "ant_struct_serialization.h"
+#include "cond_field_serialization.h"
+#include "app_util.h"
+
+uint32_t ant_capabilities_get_req_enc(uint8_t * const p_buf,
+ uint32_t * const p_buf_len)
+{
+ uint32_t index = 0;
+ uint32_t err_code = NRF_SUCCESS;
+
+ SER_ASSERT_NOT_NULL(p_buf);
+ SER_ASSERT_NOT_NULL(p_buf_len);
+
+ p_buf[index++] = SVC_ANT_CAPABILITIES;
+
+ SER_ASSERT_LENGTH_LEQ(index, *p_buf_len);
+
+ *p_buf_len = index;
+
+ return err_code;
+}
+
+uint32_t ant_capabilities_get_rsp_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ void * * const pp_capabilities,
+ uint32_t * const p_result_code)
+{
+ SER_ASSERT_NOT_NULL(p_buf);
+ SER_ASSERT_NOT_NULL(p_result_code);
+
+ uint32_t index = 0;
+ uint32_t err_code = ser_ble_cmd_rsp_result_code_dec(p_buf, &index, packet_len,
+ SVC_ANT_CAPABILITIES, p_result_code);
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code);
+
+ if (*p_result_code != NRF_SUCCESS)
+ {
+ SER_ASSERT_LENGTH_EQ(index, packet_len);
+
+ return NRF_SUCCESS;
+ }
+
+ err_code = uint8_vector_dec(p_buf, packet_len, &index, (uint8_t *)*pp_capabilities, MESG_CAPABILITIES_SIZE);
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code);
+
+ SER_ASSERT_LENGTH_EQ(index, packet_len);
+
+ return NRF_SUCCESS;
+}
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/application/codecs/ant/serializers/ant_channel_assign.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/application/codecs/ant/serializers/ant_channel_assign.c
new file mode 100644
index 0000000..ca4a44a
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/application/codecs/ant/serializers/ant_channel_assign.c
@@ -0,0 +1,83 @@
+/**
+ * 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+
+#include <stdlib.h>
+#include <string.h>
+#include "ant_app.h"
+#include "ble_serialization.h"
+#include "ant_struct_serialization.h"
+#include "cond_field_serialization.h"
+#include "app_util.h"
+
+uint32_t ant_channel_assign_req_enc(uint8_t channel,
+ uint8_t channel_type,
+ uint8_t network,
+ uint8_t ext_assign,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len)
+{
+ uint32_t index = 0;
+ uint32_t err_code = NRF_SUCCESS;
+
+ SER_ASSERT_NOT_NULL(p_buf);
+ SER_ASSERT_NOT_NULL(p_buf_len);
+
+ p_buf[index++] = SVC_ANT_CHANNEL_ASSIGN;
+ p_buf[index++] = channel;
+ p_buf[index++] = channel_type;
+ p_buf[index++] = network;
+ p_buf[index++] = ext_assign;
+
+ SER_ASSERT_LENGTH_LEQ(index, *p_buf_len);
+
+ *p_buf_len = index;
+
+ return err_code;
+}
+
+
+uint32_t ant_channel_assign_rsp_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ uint32_t * const p_result_code)
+{
+ // Use the ble cmd rsp dec function because it is adequte to decode
+ // the command response as it is the same for both ant and ble.
+ return ser_ble_cmd_rsp_dec(p_buf, packet_len, SVC_ANT_CHANNEL_ASSIGN, p_result_code);
+}
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/application/codecs/ant/serializers/ant_channel_close.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/application/codecs/ant/serializers/ant_channel_close.c
new file mode 100644
index 0000000..bd3995d
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/application/codecs/ant/serializers/ant_channel_close.c
@@ -0,0 +1,76 @@
+/**
+ * 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+
+#include <stdlib.h>
+#include <string.h>
+#include "ant_app.h"
+#include "ble_serialization.h"
+#include "ant_struct_serialization.h"
+#include "cond_field_serialization.h"
+#include "app_util.h"
+
+uint32_t ant_channel_close_req_enc(uint8_t channel,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len)
+{
+ uint32_t index = 0;
+ uint32_t err_code = NRF_SUCCESS;
+
+ SER_ASSERT_NOT_NULL(p_buf);
+ SER_ASSERT_NOT_NULL(p_buf_len);
+
+ p_buf[index++] = SVC_ANT_CHANNEL_CLOSE;
+ p_buf[index++] = channel;
+
+ SER_ASSERT_LENGTH_LEQ(index, *p_buf_len);
+
+ *p_buf_len = index;
+
+ return err_code;
+}
+
+uint32_t ant_channel_close_rsp_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ uint32_t * const p_result_code)
+{
+ // Use the ble cmd rsp dec function because it is adequte to decode
+ // the command response as it is the same for both ant and ble.
+ return ser_ble_cmd_rsp_dec(p_buf, packet_len, SVC_ANT_CHANNEL_CLOSE, p_result_code);
+}
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/application/codecs/ant/serializers/ant_channel_id_get.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/application/codecs/ant/serializers/ant_channel_id_get.c
new file mode 100644
index 0000000..a4b11cd
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/application/codecs/ant/serializers/ant_channel_id_get.c
@@ -0,0 +1,103 @@
+/**
+ * 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+
+#include <stdlib.h>
+#include <string.h>
+#include "ant_app.h"
+#include "ble_serialization.h"
+#include "ant_struct_serialization.h"
+#include "cond_field_serialization.h"
+#include "app_util.h"
+
+uint32_t ant_channel_id_get_req_enc(uint8_t channel,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len)
+{
+ uint32_t index = 0;
+ uint32_t err_code = NRF_SUCCESS;
+
+ SER_ASSERT_NOT_NULL(p_buf);
+ SER_ASSERT_NOT_NULL(p_buf_len);
+
+ p_buf[index++] = SVC_ANT_CHANNEL_ID_GET;
+ p_buf[index++] = channel;
+
+ SER_ASSERT_LENGTH_LEQ(index, *p_buf_len);
+
+ *p_buf_len = index;
+
+ return err_code;
+}
+
+uint32_t ant_channel_id_get_rsp_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ void * const p_device_number,
+ void * const p_device_type,
+ void * const p_transmit_type,
+ uint32_t * const p_result_code)
+{
+ SER_ASSERT_NOT_NULL(p_buf);
+ SER_ASSERT_NOT_NULL(p_result_code);
+
+ uint32_t index = 0;
+ uint32_t err_code = ser_ble_cmd_rsp_result_code_dec(p_buf, &index, packet_len,
+ SVC_ANT_CHANNEL_ID_GET, p_result_code);
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code);
+
+ if (*p_result_code != NRF_SUCCESS)
+ {
+ SER_ASSERT_LENGTH_EQ(index, packet_len);
+
+ return NRF_SUCCESS;
+ }
+
+ err_code = uint16_t_dec(p_buf, packet_len, &index, p_device_number);
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code);
+
+ err_code = uint8_t_dec(p_buf, packet_len, &index, p_device_type);
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code);
+
+ err_code = uint8_t_dec(p_buf, packet_len, &index, p_transmit_type);
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code);
+
+ SER_ASSERT_LENGTH_EQ(index, packet_len);
+
+ return NRF_SUCCESS;
+}
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/application/codecs/ant/serializers/ant_channel_id_set.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/application/codecs/ant/serializers/ant_channel_id_set.c
new file mode 100644
index 0000000..09563b3
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/application/codecs/ant/serializers/ant_channel_id_set.c
@@ -0,0 +1,83 @@
+/**
+ * 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+
+#include <stdlib.h>
+#include <string.h>
+#include "ant_app.h"
+#include "ble_serialization.h"
+#include "ant_struct_serialization.h"
+#include "cond_field_serialization.h"
+#include "app_util.h"
+
+uint32_t ant_channel_id_set_req_enc(uint8_t channel,
+ uint16_t device_number,
+ uint8_t device_type,
+ uint8_t transmit_type,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len)
+{
+ uint32_t index = 0;
+ uint32_t err_code = NRF_SUCCESS;
+
+ SER_ASSERT_NOT_NULL(p_buf);
+ SER_ASSERT_NOT_NULL(p_buf_len);
+
+ p_buf[index++] = SVC_ANT_CHANNEL_ID_SET;
+ p_buf[index++] = channel;
+ index += uint16_encode(device_number, &p_buf[index]);
+ p_buf[index++] = device_type;
+ p_buf[index++] = transmit_type;
+
+ SER_ASSERT_LENGTH_LEQ(index, *p_buf_len);
+
+ *p_buf_len = index;
+
+ return err_code;
+}
+
+
+uint32_t ant_channel_id_set_rsp_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ uint32_t * const p_result_code)
+{
+ // Use the ble cmd rsp dec function because it is adequte to decode
+ // the command response as it is the same for both ant and ble.
+ return ser_ble_cmd_rsp_dec(p_buf, packet_len, SVC_ANT_CHANNEL_ID_SET, p_result_code);
+}
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/application/codecs/ant/serializers/ant_channel_low_priority_rx_search_timeout_set.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/application/codecs/ant/serializers/ant_channel_low_priority_rx_search_timeout_set.c
new file mode 100644
index 0000000..135f470
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/application/codecs/ant/serializers/ant_channel_low_priority_rx_search_timeout_set.c
@@ -0,0 +1,79 @@
+/**
+ * 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+
+#include <stdlib.h>
+#include <string.h>
+#include "ant_app.h"
+#include "ble_serialization.h"
+#include "ant_struct_serialization.h"
+#include "cond_field_serialization.h"
+#include "app_util.h"
+
+uint32_t ant_channel_low_priority_rx_search_timeout_set_req_enc(uint8_t channel,
+ uint8_t timeout,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len)
+{
+ uint32_t index = 0;
+ uint32_t err_code = NRF_SUCCESS;
+
+ SER_ASSERT_NOT_NULL(p_buf);
+ SER_ASSERT_NOT_NULL(p_buf_len);
+
+ p_buf[index++] = SVC_ANT_CHANNEL_LOW_PRIO_RX_SEARCH_TIMEOUT_SET;
+ p_buf[index++] = channel;
+ p_buf[index++] = timeout;
+
+ SER_ASSERT_LENGTH_LEQ(index, *p_buf_len);
+
+ *p_buf_len = index;
+
+ return err_code;
+}
+
+
+uint32_t ant_channel_low_priority_rx_search_timeout_set_rsp_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ uint32_t * const p_result_code)
+{
+ // Use the ble cmd rsp dec function because it is adequte to decode
+ // the command response as it is the same for both ant and ble.
+ return ser_ble_cmd_rsp_dec(p_buf, packet_len, SVC_ANT_CHANNEL_LOW_PRIO_RX_SEARCH_TIMEOUT_SET, p_result_code);
+}
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/application/codecs/ant/serializers/ant_channel_open_with_offset.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/application/codecs/ant/serializers/ant_channel_open_with_offset.c
new file mode 100644
index 0000000..c4e30ef
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/application/codecs/ant/serializers/ant_channel_open_with_offset.c
@@ -0,0 +1,79 @@
+/**
+ * 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+
+#include <stdlib.h>
+#include <string.h>
+#include "ant_app.h"
+#include "ble_serialization.h"
+#include "ant_struct_serialization.h"
+#include "cond_field_serialization.h"
+#include "app_util.h"
+
+uint32_t ant_channel_open_with_offset_req_enc(uint8_t channel,
+ uint16_t usOffset,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len)
+{
+ uint32_t index = 0;
+ uint32_t err_code = NRF_SUCCESS;
+
+ SER_ASSERT_NOT_NULL(p_buf);
+ SER_ASSERT_NOT_NULL(p_buf_len);
+
+ p_buf[index++] = SVC_ANT_CHANNEL_OPEN;
+ p_buf[index++] = channel;
+ index += uint16_encode(usOffset, &p_buf[index]);
+
+ SER_ASSERT_LENGTH_LEQ(index, *p_buf_len);
+
+ *p_buf_len = index;
+
+ return err_code;
+}
+
+
+uint32_t ant_channel_open_with_offset_rsp_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ uint32_t * const p_result_code)
+{
+ // Use the ble cmd rsp dec function because it is adequte to decode
+ // the command response as it is the same for both ant and ble.
+ return ser_ble_cmd_rsp_dec(p_buf, packet_len, SVC_ANT_CHANNEL_OPEN, p_result_code);
+}
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/application/codecs/ant/serializers/ant_channel_period_get.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/application/codecs/ant/serializers/ant_channel_period_get.c
new file mode 100644
index 0000000..09576fe
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/application/codecs/ant/serializers/ant_channel_period_get.c
@@ -0,0 +1,94 @@
+/**
+ * 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#include <stdlib.h>
+#include <string.h>
+#include "ant_app.h"
+#include "ble_serialization.h"
+#include "ant_struct_serialization.h"
+#include "cond_field_serialization.h"
+#include "app_util.h"
+
+uint32_t ant_channel_period_get_req_enc(uint8_t channel,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len)
+{
+ uint32_t index = 0;
+ uint32_t err_code = NRF_SUCCESS;
+
+ SER_ASSERT_NOT_NULL(p_buf);
+ SER_ASSERT_NOT_NULL(p_buf_len);
+
+ p_buf[index++] = SVC_ANT_CHANNEL_PERIOD_GET;
+ p_buf[index++] = channel;
+
+ SER_ASSERT_LENGTH_LEQ(index, *p_buf_len);
+
+ *p_buf_len = index;
+
+ return err_code;
+}
+
+uint32_t ant_channel_period_get_rsp_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ void * p_period,
+ uint32_t * const p_result_code)
+{
+ SER_ASSERT_NOT_NULL(p_buf);
+ SER_ASSERT_NOT_NULL(p_result_code);
+
+ uint32_t index = 0;
+ uint32_t err_code = ser_ble_cmd_rsp_result_code_dec(p_buf, &index, packet_len,
+ SVC_ANT_CHANNEL_PERIOD_GET, p_result_code);
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code);
+
+ if (*p_result_code != NRF_SUCCESS)
+ {
+ SER_ASSERT_LENGTH_EQ(index, packet_len);
+
+ return NRF_SUCCESS;
+ }
+
+ err_code = uint16_t_dec(p_buf, packet_len, &index, p_period);
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code);
+
+ SER_ASSERT_LENGTH_EQ(index, packet_len);
+
+ return NRF_SUCCESS;
+}
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/application/codecs/ant/serializers/ant_channel_period_set.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/application/codecs/ant/serializers/ant_channel_period_set.c
new file mode 100644
index 0000000..292f8f9
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/application/codecs/ant/serializers/ant_channel_period_set.c
@@ -0,0 +1,78 @@
+/**
+ * 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+
+#include <stdlib.h>
+#include <string.h>
+#include "ant_app.h"
+#include "ble_serialization.h"
+#include "ant_struct_serialization.h"
+#include "cond_field_serialization.h"
+#include "app_util.h"
+
+uint32_t ant_channel_period_set_req_enc(uint8_t channel,
+ uint16_t period,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len)
+{
+ uint32_t index = 0;
+ uint32_t err_code = NRF_SUCCESS;
+
+ SER_ASSERT_NOT_NULL(p_buf);
+ SER_ASSERT_NOT_NULL(p_buf_len);
+
+ p_buf[index++] = SVC_ANT_CHANNEL_PERIOD_SET;
+ p_buf[index++] = channel;
+ index += uint16_encode(period, &p_buf[index]);
+
+ SER_ASSERT_LENGTH_LEQ(index, *p_buf_len);
+
+ *p_buf_len = index;
+
+ return err_code;
+}
+
+uint32_t ant_channel_period_set_rsp_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ uint32_t * const p_result_code)
+{
+ // Use the ble cmd rsp dec function because it is adequte to decode
+ // the command response as it is the same for both ant and ble.
+ return ser_ble_cmd_rsp_dec(p_buf, packet_len, SVC_ANT_CHANNEL_PERIOD_SET, p_result_code);
+}
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/application/codecs/ant/serializers/ant_channel_radio_freq_get.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/application/codecs/ant/serializers/ant_channel_radio_freq_get.c
new file mode 100644
index 0000000..6651862
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/application/codecs/ant/serializers/ant_channel_radio_freq_get.c
@@ -0,0 +1,95 @@
+/**
+ * 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+
+#include <stdlib.h>
+#include <string.h>
+#include "ant_app.h"
+#include "ble_serialization.h"
+#include "ant_struct_serialization.h"
+#include "cond_field_serialization.h"
+#include "app_util.h"
+
+uint32_t ant_channel_radio_freq_get_req_enc(uint8_t channel,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len)
+{
+ uint32_t index = 0;
+ uint32_t err_code = NRF_SUCCESS;
+
+ SER_ASSERT_NOT_NULL(p_buf);
+ SER_ASSERT_NOT_NULL(p_buf_len);
+
+ p_buf[index++] = SVC_ANT_CHANNEL_RADIO_FREQ_GET;
+ p_buf[index++] = channel;
+
+ SER_ASSERT_LENGTH_LEQ(index, *p_buf_len);
+
+ *p_buf_len = index;
+
+ return err_code;
+}
+
+uint32_t ant_channel_radio_freq_get_rsp_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ void * const p_r_freq,
+ uint32_t * const p_result_code)
+{
+ SER_ASSERT_NOT_NULL(p_buf);
+ SER_ASSERT_NOT_NULL(p_result_code);
+
+ uint32_t index = 0;
+ uint32_t err_code = ser_ble_cmd_rsp_result_code_dec(p_buf, &index, packet_len,
+ SVC_ANT_CHANNEL_RADIO_FREQ_GET, p_result_code);
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code);
+
+ if (*p_result_code != NRF_SUCCESS)
+ {
+ SER_ASSERT_LENGTH_EQ(index, packet_len);
+
+ return NRF_SUCCESS;
+ }
+
+ err_code = uint8_t_dec(p_buf, packet_len, &index, p_r_freq);
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code);
+
+ SER_ASSERT_LENGTH_EQ(index, packet_len);
+
+ return NRF_SUCCESS;
+}
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/application/codecs/ant/serializers/ant_channel_radio_freq_set.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/application/codecs/ant/serializers/ant_channel_radio_freq_set.c
new file mode 100644
index 0000000..5638e97
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/application/codecs/ant/serializers/ant_channel_radio_freq_set.c
@@ -0,0 +1,78 @@
+/**
+ * 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+
+#include <stdlib.h>
+#include <string.h>
+#include "ant_app.h"
+#include "ble_serialization.h"
+#include "ant_struct_serialization.h"
+#include "cond_field_serialization.h"
+#include "app_util.h"
+
+uint32_t ant_channel_radio_freq_set_req_enc(uint8_t channel,
+ uint8_t freq,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len)
+{
+ uint32_t index = 0;
+ uint32_t err_code = NRF_SUCCESS;
+
+ SER_ASSERT_NOT_NULL(p_buf);
+ SER_ASSERT_NOT_NULL(p_buf_len);
+
+ p_buf[index++] = SVC_ANT_CHANNEL_RADIO_FREQ_SET;
+ p_buf[index++] = channel;
+ p_buf[index++] = freq;
+
+ SER_ASSERT_LENGTH_LEQ(index, *p_buf_len);
+
+ *p_buf_len = index;
+
+ return err_code;
+}
+
+uint32_t ant_channel_radio_freq_set_rsp_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ uint32_t * const p_result_code)
+{
+ // Use the ble cmd rsp dec function because it is adequte to decode
+ // the command response as it is the same for both ant and ble.
+ return ser_ble_cmd_rsp_dec(p_buf, packet_len, SVC_ANT_CHANNEL_RADIO_FREQ_SET, p_result_code);
+}
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/application/codecs/ant/serializers/ant_channel_radio_tx_power_set.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/application/codecs/ant/serializers/ant_channel_radio_tx_power_set.c
new file mode 100644
index 0000000..c7ea273
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/application/codecs/ant/serializers/ant_channel_radio_tx_power_set.c
@@ -0,0 +1,81 @@
+/**
+ * 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+
+#include <stdlib.h>
+#include <string.h>
+#include "ant_app.h"
+#include "ble_serialization.h"
+#include "ant_struct_serialization.h"
+#include "cond_field_serialization.h"
+#include "app_util.h"
+
+uint32_t ant_channel_radio_tx_power_set_req_enc(uint8_t channel,
+ uint8_t tx_power,
+ uint8_t custom_tx_power,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len)
+{
+ uint32_t index = 0;
+ uint32_t err_code = NRF_SUCCESS;
+
+ SER_ASSERT_NOT_NULL(p_buf);
+ SER_ASSERT_NOT_NULL(p_buf_len);
+
+ p_buf[index++] = SVC_ANT_CHANNEL_RADIO_TX_POWER_SET;
+ p_buf[index++] = channel;
+ p_buf[index++] = tx_power;
+ p_buf[index++] = custom_tx_power;
+
+ SER_ASSERT_LENGTH_LEQ(index, *p_buf_len);
+
+ *p_buf_len = index;
+
+ return err_code;
+}
+
+
+uint32_t ant_channel_radio_tx_power_set_rsp_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ uint32_t * const p_result_code)
+{
+ // Use the ble cmd rsp dec function because it is adequte to decode
+ // the command response as it is the same for both ant and ble.
+ return ser_ble_cmd_rsp_dec(p_buf, packet_len, SVC_ANT_CHANNEL_RADIO_TX_POWER_SET, p_result_code);
+}
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/application/codecs/ant/serializers/ant_channel_rx_search_timeout_set.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/application/codecs/ant/serializers/ant_channel_rx_search_timeout_set.c
new file mode 100644
index 0000000..1ac542d
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/application/codecs/ant/serializers/ant_channel_rx_search_timeout_set.c
@@ -0,0 +1,79 @@
+/**
+ * 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+
+#include <stdlib.h>
+#include <string.h>
+#include "ant_app.h"
+#include "ble_serialization.h"
+#include "ant_struct_serialization.h"
+#include "cond_field_serialization.h"
+#include "app_util.h"
+
+uint32_t ant_channel_rx_search_timeout_set_req_enc(uint8_t channel,
+ uint8_t timeout,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len)
+{
+ uint32_t index = 0;
+ uint32_t err_code = NRF_SUCCESS;
+
+ SER_ASSERT_NOT_NULL(p_buf);
+ SER_ASSERT_NOT_NULL(p_buf_len);
+
+ p_buf[index++] = SVC_ANT_CHANNEL_SEARCH_TIMEOUT_SET;
+ p_buf[index++] = channel;
+ p_buf[index++] = timeout;
+
+ SER_ASSERT_LENGTH_LEQ(index, *p_buf_len);
+
+ *p_buf_len = index;
+
+ return err_code;
+}
+
+
+uint32_t ant_channel_rx_search_timeout_set_rsp_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ uint32_t * const p_result_code)
+{
+ // Use the ble cmd rsp dec function because it is adequte to decode
+ // the command response as it is the same for both ant and ble.
+ return ser_ble_cmd_rsp_dec(p_buf, packet_len, SVC_ANT_CHANNEL_SEARCH_TIMEOUT_SET, p_result_code);
+}
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/application/codecs/ant/serializers/ant_channel_status_get.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/application/codecs/ant/serializers/ant_channel_status_get.c
new file mode 100644
index 0000000..2ed53eb
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/application/codecs/ant/serializers/ant_channel_status_get.c
@@ -0,0 +1,95 @@
+/**
+ * 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+
+#include <stdlib.h>
+#include <string.h>
+#include "ant_app.h"
+#include "ble_serialization.h"
+#include "ant_struct_serialization.h"
+#include "cond_field_serialization.h"
+#include "app_util.h"
+
+uint32_t ant_channel_status_get_req_enc(uint8_t channel,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len)
+{
+ uint32_t index = 0;
+ uint32_t err_code = NRF_SUCCESS;
+
+ SER_ASSERT_NOT_NULL(p_buf);
+ SER_ASSERT_NOT_NULL(p_buf_len);
+
+ p_buf[index++] = SVC_ANT_CHANNEL_STATUS_GET;
+ p_buf[index++] = channel;
+
+ SER_ASSERT_LENGTH_LEQ(index, *p_buf_len);
+
+ *p_buf_len = index;
+
+ return err_code;
+}
+
+uint32_t ant_channel_status_get_rsp_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ void * const p_status,
+ uint32_t * const p_result_code)
+{
+ SER_ASSERT_NOT_NULL(p_buf);
+ SER_ASSERT_NOT_NULL(p_result_code);
+
+ uint32_t index = 0;
+ uint32_t err_code = ser_ble_cmd_rsp_result_code_dec(p_buf, &index, packet_len,
+ SVC_ANT_CHANNEL_STATUS_GET, p_result_code);
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code);
+
+ if (*p_result_code != NRF_SUCCESS)
+ {
+ SER_ASSERT_LENGTH_EQ(index, packet_len);
+
+ return NRF_SUCCESS;
+ }
+
+ err_code = uint8_t_dec(p_buf, packet_len, &index, p_status);
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code);
+
+ SER_ASSERT_LENGTH_EQ(index, packet_len);
+
+ return NRF_SUCCESS;
+}
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/application/codecs/ant/serializers/ant_channel_unassign.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/application/codecs/ant/serializers/ant_channel_unassign.c
new file mode 100644
index 0000000..1c82fe9
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/application/codecs/ant/serializers/ant_channel_unassign.c
@@ -0,0 +1,76 @@
+/**
+ * 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+
+#include <stdlib.h>
+#include <string.h>
+#include "ant_app.h"
+#include "ble_serialization.h"
+#include "ant_struct_serialization.h"
+#include "cond_field_serialization.h"
+#include "app_util.h"
+
+uint32_t ant_channel_unassign_req_enc(uint8_t channel,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len)
+{
+ uint32_t index = 0;
+ uint32_t err_code = NRF_SUCCESS;
+
+ SER_ASSERT_NOT_NULL(p_buf);
+ SER_ASSERT_NOT_NULL(p_buf_len);
+
+ p_buf[index++] = SVC_ANT_CHANNEL_UNASSIGN;
+ p_buf[index++] = channel;
+
+ SER_ASSERT_LENGTH_LEQ(index, *p_buf_len);
+
+ *p_buf_len = index;
+
+ return err_code;
+}
+
+uint32_t ant_channel_unassign_rsp_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ uint32_t * const p_result_code)
+{
+ // Use the ble cmd rsp dec function because it is adequte to decode
+ // the command response as it is the same for both ant and ble.
+ return ser_ble_cmd_rsp_dec(p_buf, packet_len, SVC_ANT_CHANNEL_UNASSIGN, p_result_code);
+}
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/application/codecs/ant/serializers/ant_coex_config_get.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/application/codecs/ant/serializers/ant_coex_config_get.c
new file mode 100644
index 0000000..a38f497
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/application/codecs/ant/serializers/ant_coex_config_get.c
@@ -0,0 +1,130 @@
+/**
+ * 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+
+#include <stdlib.h>
+#include <string.h>
+#include "ant_app.h"
+#include "ble_serialization.h"
+#include "ant_struct_serialization.h"
+#include "cond_field_serialization.h"
+#include "app_util.h"
+#include "ant_interface.h"
+
+uint32_t ant_coex_config_get_req_enc(uint8_t channel,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len)
+{
+ SER_ASSERT_NOT_NULL(p_buf);
+ SER_ASSERT_NOT_NULL(p_buf_len);
+
+ uint8_t svc_number = SVC_ANT_COEX_CONFIG_GET;
+ uint32_t err_code = NRF_SUCCESS;
+ uint32_t buf_len = *p_buf_len;
+ uint32_t index = 0;
+
+ err_code = uint8_t_enc(&svc_number, p_buf, buf_len, &index);
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code);
+
+ err_code = uint8_t_enc(&channel, p_buf, buf_len, &index);
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code);
+
+ SER_ASSERT_LENGTH_LEQ(index, *p_buf_len);
+
+ *p_buf_len = index;
+
+ return err_code;
+}
+
+uint32_t ant_coex_config_get_rsp_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ void * const p_coex_config,
+ void * const p_adv_coex_config,
+ uint32_t * const p_result_code)
+{
+ SER_ASSERT_NOT_NULL(p_buf);
+ SER_ASSERT_NOT_NULL(p_result_code);
+
+ uint32_t index = 0;
+ uint32_t err_code = ser_ble_cmd_rsp_result_code_dec(p_buf, &index, packet_len,
+ SVC_ANT_COEX_CONFIG_GET, p_result_code);
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code);
+
+ if (*p_result_code != NRF_SUCCESS)
+ {
+ SER_ASSERT_LENGTH_EQ(index, packet_len);
+
+ return NRF_SUCCESS;
+ }
+
+ uint8_t coex_config_size;
+ uint8_t coex_config_buffer[(MESG_BUFFER_SIZE / 2) - 1];
+
+ uint8_t adv_coex_config_size;
+ uint8_t adv_coex_config_buffer[(MESG_BUFFER_SIZE / 2) - 1];
+
+ err_code = uint8_t_dec(p_buf, packet_len, &index, &coex_config_size);
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code);
+
+ err_code = uint8_vector_dec(p_buf, packet_len, &index, coex_config_buffer, coex_config_size);
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code);
+
+ err_code = uint8_t_dec(p_buf, packet_len, &index, &(adv_coex_config_size));
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code);
+
+ err_code = uint8_vector_dec(p_buf, packet_len, &index, adv_coex_config_buffer, adv_coex_config_size);
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code);
+
+
+ if (p_coex_config)
+ {
+ ((ANT_BUFFER_PTR *)p_coex_config)->ucBufferSize = coex_config_size;
+ memcpy(((ANT_BUFFER_PTR *)p_coex_config)->pucBuffer, coex_config_buffer,((ANT_BUFFER_PTR *)p_coex_config)->ucBufferSize);
+ }
+
+ if (p_adv_coex_config)
+ {
+ ((ANT_BUFFER_PTR *)p_adv_coex_config)->ucBufferSize = coex_config_size;
+ memcpy(((ANT_BUFFER_PTR *)p_adv_coex_config)->pucBuffer, coex_config_buffer,((ANT_BUFFER_PTR *)p_adv_coex_config)->ucBufferSize);
+ }
+
+ SER_ASSERT_LENGTH_LEQ(index, packet_len);
+
+ return NRF_SUCCESS;
+}
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/application/codecs/ant/serializers/ant_coex_config_set.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/application/codecs/ant/serializers/ant_coex_config_set.c
new file mode 100644
index 0000000..4465abc
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/application/codecs/ant/serializers/ant_coex_config_set.c
@@ -0,0 +1,109 @@
+/**
+ * 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+
+#include <stdlib.h>
+#include <string.h>
+#include "ant_app.h"
+#include "ble_serialization.h"
+#include "ant_struct_serialization.h"
+#include "cond_field_serialization.h"
+#include "app_util.h"
+
+uint32_t ant_coex_config_set_req_enc(uint8_t channel,
+ ANT_BUFFER_PTR const * const p_coex_config,
+ ANT_BUFFER_PTR const * const p_adv_coex_config,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len)
+{
+ SER_ASSERT_NOT_NULL(p_buf);
+ SER_ASSERT_NOT_NULL(p_buf_len);
+
+ uint8_t svc_number = SVC_ANT_COEX_CONFIG_SET;
+ uint32_t err_code = NRF_SUCCESS;
+ uint32_t buf_len = *p_buf_len;
+ uint32_t index = 0;
+
+ err_code = uint8_t_enc(&svc_number, p_buf, buf_len, &index);
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code);
+
+ err_code = uint8_t_enc(&channel, p_buf, buf_len, &index);
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code);
+
+ // Encode coex config buffer size
+ uint8_t coex_config_buffer_size = p_coex_config -> ucBufferSize;
+ err_code = uint8_t_enc(&coex_config_buffer_size, p_buf, buf_len, &index);
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code);
+
+ // Encode coex config buffer
+ err_code = uint8_vector_enc(p_coex_config -> pucBuffer,
+ coex_config_buffer_size,
+ p_buf,
+ buf_len,
+ &index);
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code);
+
+ // Encode advanced coex config buffer size
+ uint8_t adv_coex_config_buffer_size = p_adv_coex_config -> ucBufferSize;
+ err_code = uint8_t_enc(&adv_coex_config_buffer_size, p_buf, buf_len, &index);
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code);
+
+ // Encode advanced coex config buffer
+ err_code = uint8_vector_enc(p_adv_coex_config -> pucBuffer,
+ adv_coex_config_buffer_size,
+ p_buf,
+ buf_len,
+ &index);
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code);
+
+ SER_ASSERT_LENGTH_LEQ(index, *p_buf_len);
+
+ *p_buf_len = index;
+
+ return err_code;
+}
+
+uint32_t ant_coex_config_set_rsp_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ uint32_t * const p_result_code)
+{
+ // Use the ble cmd rsp dec function because it is adequte to decode
+ // the command response as it is the same for both ant and ble.
+ return ser_ble_cmd_rsp_dec(p_buf, packet_len, SVC_ANT_COEX_CONFIG_SET, p_result_code);
+}
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/application/codecs/ant/serializers/ant_crypto_channel_enable.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/application/codecs/ant/serializers/ant_crypto_channel_enable.c
new file mode 100644
index 0000000..9071c89
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/application/codecs/ant/serializers/ant_crypto_channel_enable.c
@@ -0,0 +1,82 @@
+/**
+ * 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+
+#include <stdlib.h>
+#include <string.h>
+#include "ant_app.h"
+#include "ble_serialization.h"
+#include "ant_struct_serialization.h"
+#include "cond_field_serialization.h"
+#include "app_util.h"
+
+uint32_t ant_crypto_channel_enable_req_enc(uint8_t channel,
+ uint8_t enable,
+ uint8_t key_num,
+ uint8_t decimation_rate,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len)
+{
+ uint32_t index = 0;
+ uint32_t err_code = NRF_SUCCESS;
+
+ SER_ASSERT_NOT_NULL(p_buf);
+ SER_ASSERT_NOT_NULL(p_buf_len);
+
+ p_buf[index++] = SVC_ANT_CRYPTO_CHANNEL_ENABLE;
+ p_buf[index++] = channel;
+ p_buf[index++] = enable;
+ p_buf[index++] = key_num;
+ p_buf[index++] = decimation_rate;
+
+ SER_ASSERT_LENGTH_LEQ(index, *p_buf_len);
+
+ *p_buf_len = index;
+
+ return err_code;
+}
+
+uint32_t ant_crypto_channel_enable_rsp_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ uint32_t * const p_result_code)
+{
+ // Use the ble cmd rsp dec function because it is adequte to decode
+ // the command response as it is the same for both ant and ble.
+ return ser_ble_cmd_rsp_dec(p_buf, packet_len, SVC_ANT_CRYPTO_CHANNEL_ENABLE, p_result_code);
+}
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/application/codecs/ant/serializers/ant_crypto_info_get.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/application/codecs/ant/serializers/ant_crypto_info_get.c
new file mode 100644
index 0000000..6a2b5a4
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/application/codecs/ant/serializers/ant_crypto_info_get.c
@@ -0,0 +1,123 @@
+/**
+ * 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+
+#include <stdlib.h>
+#include <string.h>
+#include "ant_app.h"
+#include "ble_serialization.h"
+#include "ant_struct_serialization.h"
+#include "cond_field_serialization.h"
+#include "app_util.h"
+
+uint32_t ant_crypto_info_get_req_enc(uint8_t type,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len)
+{
+ SER_ASSERT_NOT_NULL(p_buf);
+ SER_ASSERT_NOT_NULL(p_buf_len);
+
+ uint8_t svc_number = SVC_ANT_CRYPTO_INFO_GET;
+ uint32_t err_code = NRF_SUCCESS;
+ uint32_t buf_len = *p_buf_len;
+ uint32_t index = 0;
+
+ err_code = uint8_t_enc(&svc_number, p_buf, buf_len, &index);
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code);
+
+ err_code = uint8_t_enc(&type, p_buf, buf_len, &index);
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code);
+
+ SER_ASSERT_LENGTH_LEQ(index, buf_len);
+
+ *p_buf_len = index;
+
+ return err_code;
+}
+
+uint32_t ant_crypto_info_get_rsp_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ void * const p_info,
+ uint32_t * const p_result_code)
+{
+ SER_ASSERT_NOT_NULL(p_buf);
+ SER_ASSERT_NOT_NULL(p_result_code);
+
+ uint32_t index = 0;
+ uint32_t err_code = ser_ble_cmd_rsp_result_code_dec(p_buf, &index, packet_len,
+ SVC_ANT_CRYPTO_INFO_GET, p_result_code);
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code);
+
+ if (*p_result_code != NRF_SUCCESS)
+ {
+ SER_ASSERT_LENGTH_EQ(index, packet_len);
+
+ return NRF_SUCCESS;
+ }
+
+ uint8_t type;
+ uint8_t crypto_info_size;
+
+ err_code = uint8_t_dec(p_buf, packet_len, &index, &type);
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code);
+
+ switch (type)
+ {
+ case ENCRYPTION_INFO_GET_SUPPORTED_MODE:
+ crypto_info_size = MESG_CONFIG_ENCRYPT_REQ_CAPABILITIES_SIZE - MESG_CHANNEL_NUM_SIZE;
+ break;
+ case ENCRYPTION_INFO_GET_CRYPTO_ID:
+ crypto_info_size = MESG_CONFIG_ENCRYPT_REQ_CONFIG_ID_SIZE - MESG_CHANNEL_NUM_SIZE;
+ break;
+ case ENCRYPTION_INFO_GET_CUSTOM_USER_DATA:
+ crypto_info_size = (MESG_CONFIG_ENCRYPT_REQ_CONFIG_USER_DATA_SIZE -
+ MESG_CHANNEL_NUM_SIZE);
+ break;
+ default:
+ crypto_info_size = 0;
+ break;
+ }
+
+ err_code = uint8_vector_dec(p_buf, packet_len, &index, (uint8_t *)p_info, crypto_info_size);
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code);
+
+ SER_ASSERT_LENGTH_LEQ(index, packet_len);
+
+ return NRF_SUCCESS;
+}
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/application/codecs/ant/serializers/ant_crypto_info_set.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/application/codecs/ant/serializers/ant_crypto_info_set.c
new file mode 100644
index 0000000..b56987a
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/application/codecs/ant/serializers/ant_crypto_info_set.c
@@ -0,0 +1,90 @@
+/**
+ * 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+
+#include <stdlib.h>
+#include <string.h>
+#include "ant_app.h"
+#include "ble_serialization.h"
+#include "ant_struct_serialization.h"
+#include "cond_field_serialization.h"
+#include "app_util.h"
+
+uint32_t ant_crypto_info_set_req_enc(uint8_t type,
+ uint8_t const * const p_config,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len)
+{
+ SER_ASSERT_NOT_NULL(p_buf);
+ SER_ASSERT_NOT_NULL(p_buf_len);
+
+ uint8_t svc_number = SVC_ANT_CRYPTO_INFO_SET;
+ uint32_t err_code = NRF_SUCCESS;
+ uint32_t buf_len = *p_buf_len;
+ uint32_t index = 0;
+
+ err_code = uint8_t_enc(&svc_number, p_buf, buf_len, &index);
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code);
+
+ err_code = uint8_t_enc(&type, p_buf, buf_len, &index);
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code);
+
+ uint8_t crypto_info_size = (MESG_CONFIG_ENCRYPT_REQ_CONFIG_USER_DATA_SIZE -
+ MESG_CHANNEL_NUM_SIZE) +
+ (MESG_CONFIG_ENCRYPT_REQ_CONFIG_ID_SIZE -
+ MESG_CHANNEL_NUM_SIZE);
+
+ err_code = uint8_vector_enc(p_config, crypto_info_size, p_buf, buf_len, &index);
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code);
+
+ SER_ASSERT_LENGTH_LEQ(index, *p_buf_len);
+
+ *p_buf_len = index;
+
+ return err_code;
+}
+
+uint32_t ant_crypto_info_set_rsp_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ uint32_t * const p_result_code)
+{
+ // Use the ble cmd rsp dec function because it is adequte to decode
+ // the command response as it is the same for both ant and ble.
+ return ser_ble_cmd_rsp_dec(p_buf, packet_len, SVC_ANT_CRYPTO_INFO_SET, p_result_code);
+}
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/application/codecs/ant/serializers/ant_crypto_key_set.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/application/codecs/ant/serializers/ant_crypto_key_set.c
new file mode 100644
index 0000000..4c1b05c
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/application/codecs/ant/serializers/ant_crypto_key_set.c
@@ -0,0 +1,85 @@
+/**
+ * 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+
+#include <stdlib.h>
+#include <string.h>
+#include "ant_app.h"
+#include "ble_serialization.h"
+#include "ant_struct_serialization.h"
+#include "cond_field_serialization.h"
+#include "app_util.h"
+
+uint32_t ant_crypto_key_set_req_enc(uint8_t key_num,
+ uint8_t const * const p_key,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len)
+{
+ SER_ASSERT_NOT_NULL(p_buf);
+ SER_ASSERT_NOT_NULL(p_buf_len);
+
+ uint8_t svc_number = SVC_ANT_CRYPTO_KEY_SET;
+ uint32_t err_code = NRF_SUCCESS;
+ uint32_t buf_len = *p_buf_len;
+ uint32_t index = 0;
+
+ err_code = uint8_t_enc(&svc_number, p_buf, buf_len, &index);
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code);
+
+ err_code = uint8_t_enc(&key_num, p_buf, buf_len, &index);
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code);
+
+ err_code = uint8_vector_enc(p_key, SIZE_OF_ENCRYPTED_KEY, p_buf, buf_len, &index);
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code);
+
+ SER_ASSERT_LENGTH_LEQ(index, *p_buf_len);
+
+ *p_buf_len = index;
+
+ return err_code;
+}
+
+uint32_t ant_crypto_key_set_rsp_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ uint32_t * const p_result_code)
+{
+ // Use the ble cmd rsp dec function because it is adequte to decode
+ // the command response as it is the same for both ant and ble.
+ return ser_ble_cmd_rsp_dec(p_buf, packet_len, SVC_ANT_CRYPTO_KEY_SET, p_result_code);
+}
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/application/codecs/ant/serializers/ant_cw_test_mode.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/application/codecs/ant/serializers/ant_cw_test_mode.c
new file mode 100644
index 0000000..c149907
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/application/codecs/ant/serializers/ant_cw_test_mode.c
@@ -0,0 +1,82 @@
+/**
+ * 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+
+#include <stdlib.h>
+#include <string.h>
+#include "ant_app.h"
+#include "ble_serialization.h"
+#include "ant_struct_serialization.h"
+#include "cond_field_serialization.h"
+#include "app_util.h"
+
+uint32_t ant_cw_test_mode_req_enc(uint8_t radio_freq,
+ uint8_t tx_power,
+ uint8_t custom_tx_power,
+ uint8_t mode,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len)
+{
+ uint32_t index = 0;
+ uint32_t err_code = NRF_SUCCESS;
+
+ SER_ASSERT_NOT_NULL(p_buf);
+ SER_ASSERT_NOT_NULL(p_buf_len);
+
+ p_buf[index++] = SVC_ANT_CW_TEST_MODE;
+ p_buf[index++] = radio_freq;
+ p_buf[index++] = tx_power;
+ p_buf[index++] = custom_tx_power;
+ p_buf[index++] = mode;
+
+ SER_ASSERT_LENGTH_LEQ(index, *p_buf_len);
+
+ *p_buf_len = index;
+
+ return err_code;
+}
+
+uint32_t ant_cw_test_mode_rsp_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ uint32_t * const p_result_code)
+{
+ // Use the ble cmd rsp dec function because it is adequte to decode
+ // the command response as it is the same for both ant and ble.
+ return ser_ble_cmd_rsp_dec(p_buf, packet_len, SVC_ANT_CW_TEST_MODE, p_result_code);
+}
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/application/codecs/ant/serializers/ant_cw_test_mode_init.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/application/codecs/ant/serializers/ant_cw_test_mode_init.c
new file mode 100644
index 0000000..706fd3b
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/application/codecs/ant/serializers/ant_cw_test_mode_init.c
@@ -0,0 +1,74 @@
+/**
+ * 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+
+#include <stdlib.h>
+#include <string.h>
+#include "ant_app.h"
+#include "ble_serialization.h"
+#include "ant_struct_serialization.h"
+#include "cond_field_serialization.h"
+#include "app_util.h"
+
+uint32_t ant_cw_test_mode_init_req_enc(uint8_t * const p_buf,
+ uint32_t * const p_buf_len)
+{
+ uint32_t index = 0;
+ uint32_t err_code = NRF_SUCCESS;
+
+ SER_ASSERT_NOT_NULL(p_buf);
+ SER_ASSERT_NOT_NULL(p_buf_len);
+
+ p_buf[index++] = SVC_ANT_INIT_CW_TEST_MODE;
+
+ SER_ASSERT_LENGTH_LEQ(index, *p_buf_len);
+
+ *p_buf_len = index;
+
+ return err_code;
+}
+
+uint32_t ant_cw_test_mode_init_rsp_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ uint32_t * const p_result_code)
+{
+ // Use the ble cmd rsp dec function because it is adequte to decode
+ // the command response as it is the same for both ant and ble.
+ return ser_ble_cmd_rsp_dec(p_buf, packet_len, SVC_ANT_INIT_CW_TEST_MODE, p_result_code);
+}
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/application/codecs/ant/serializers/ant_enable.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/application/codecs/ant/serializers/ant_enable.c
new file mode 100644
index 0000000..e8b9f20
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/application/codecs/ant/serializers/ant_enable.c
@@ -0,0 +1,79 @@
+/**
+ * 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+
+#include <stdlib.h>
+#include <string.h>
+#include "ant_app.h"
+#include "ble_serialization.h"
+#include "ant_struct_serialization.h"
+#include "cond_field_serialization.h"
+#include "app_util.h"
+
+uint32_t ant_enable_req_enc(ANT_ENABLE * const p_channel_enable,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len)
+{
+ uint32_t index = 0;
+ uint32_t err_code = NRF_SUCCESS;
+
+ SER_ASSERT_NOT_NULL(p_buf);
+ SER_ASSERT_NOT_NULL(p_buf_len);
+
+ p_buf[index++] = SVC_ANT_ENABLE;
+
+ err_code = cond_field_enc(p_channel_enable, p_buf, *p_buf_len, &index, ANT_ENABLE_enc);
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code);
+
+ SER_ASSERT_LENGTH_LEQ(index, *p_buf_len);
+
+ *p_buf_len = index;
+
+ return err_code;
+}
+
+
+uint32_t ant_enable_rsp_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ uint32_t * const p_result_code)
+{
+ // Use the ble cmd rsp dec function because it is adequte to decode
+ // the command response as it is the same for both ant and ble.
+ return ser_ble_cmd_rsp_dec(p_buf, packet_len, SVC_ANT_ENABLE, p_result_code);
+}
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/application/codecs/ant/serializers/ant_event.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/application/codecs/ant/serializers/ant_event.c
new file mode 100644
index 0000000..afad594
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/application/codecs/ant/serializers/ant_event.c
@@ -0,0 +1,74 @@
+/**
+ * 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+
+//#include "ble_app.h"
+//#include "ble_evt_app.h"
+//#include "ble_gap_evt_app.h"
+//#include "ble_gattc_evt_app.h"
+//#include "ble_gatts_evt_app.h"
+//#include "ble_l2cap_evt_app.h"
+#include "ble_serialization.h"
+#include "app_util.h"
+#include "nrf_sdh_ant.h"
+#include "ant_struct_serialization.h"
+#include "ant_parameters.h"
+
+uint32_t ant_event_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ ant_evt_t * const p_event,
+ uint32_t * const p_event_len)
+{
+ uint32_t index = SER_ANT_EVT_ID_POS;
+ uint32_t err_code = NRF_SUCCESS;
+
+ SER_ASSERT_NOT_NULL(p_buf);
+ SER_ASSERT_NOT_NULL(p_event_len);
+ SER_ASSERT_LENGTH_LEQ(SER_EVT_HEADER_SIZE, packet_len);
+ SER_ASSERT_NOT_NULL(p_event);
+
+ err_code = ant_evt_t_dec(p_buf, packet_len, &index, p_event);
+
+ SER_ASSERT_LENGTH_EQ(index, packet_len);
+ *p_event_len = index;
+
+ SER_ASSERT_LENGTH_LEQ(p_event->channel, MAX_ANT_CHANNELS);
+
+ return err_code;
+}
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/application/codecs/ant/serializers/ant_event.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/application/codecs/ant/serializers/ant_event.h
new file mode 100644
index 0000000..da62571
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/application/codecs/ant/serializers/ant_event.h
@@ -0,0 +1,81 @@
+/**
+ * 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+
+#ifndef __ANT_EVENT_H__
+#define __ANT_EVENT_H__
+
+#include "ble_serialization.h"
+#include "app_util.h"
+#include "nrf_sdh_ant.h"
+
+/**
+ * @addtogroup ser_app_s212_codecs
+ * @{
+ */
+
+
+/**@brief Event decoding dispatcher.
+ *
+ * The event decoding dispatcher will route the event packet to the correct decoder, which in turn
+ * decodes the contents of the event and updates the \p p_event struct.
+ *
+ * If \p p_event is null, the required length of \p p_event is returned in \p p_event_len.
+ *
+ * @param[in] p_buf Pointer to the beginning of the event packet.
+ * @param[in] packet_len Length (in bytes) of the event packet.
+ * @param[in,out] p_event Pointer to the \ref ant_evt_t buffer where the decoded event will be
+ * stored. If NULL, the required length will be returned in \p p_event_len.
+ * @param[in,out] p_event_len \c in: Size (in bytes) of \p p_event buffer.
+ * \c out: Length of the decoded contents of \p p_event.
+ *
+ * @retval NRF_SUCCESS Decoding success.
+ * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length.
+ * @retval NRF_ERROR_DATA_SIZE Decoding failure. Length of \p p_event is too small to
+ * hold the decoded event.
+ * @retval NRF_ERROR_NOT_FOUND Decoding failure. No event decoder is available.
+ */
+uint32_t ant_event_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ ant_evt_t * const p_event,
+ uint32_t * const p_event_len);
+/** @} */
+
+#endif
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/application/codecs/ant/serializers/ant_id_list_add.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/application/codecs/ant/serializers/ant_id_list_add.c
new file mode 100644
index 0000000..ef318e0
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/application/codecs/ant/serializers/ant_id_list_add.c
@@ -0,0 +1,91 @@
+/**
+ * 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+
+#include <stdlib.h>
+#include <string.h>
+#include "ant_app.h"
+#include "ble_serialization.h"
+#include "ant_struct_serialization.h"
+#include "cond_field_serialization.h"
+#include "app_util.h"
+#include "ant_parameters.h"
+
+uint32_t ant_id_list_add_req_enc(uint8_t channel,
+ uint8_t const * const p_dev_id,
+ uint8_t list_index,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len)
+{
+ SER_ASSERT_NOT_NULL(p_buf);
+ SER_ASSERT_NOT_NULL(p_buf_len);
+
+ uint8_t svc_number = SVC_ANT_ID_LIST_ADD;
+ uint32_t err_code = NRF_SUCCESS;
+ uint32_t buf_len = *p_buf_len;
+ uint32_t index = 0;
+
+ err_code = uint8_t_enc(&svc_number, p_buf, buf_len, &index);
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code);
+
+ err_code = uint8_t_enc(&channel, p_buf, buf_len, &index);
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code);
+
+ err_code = uint8_vector_enc(p_dev_id, ANT_ID_SIZE, p_buf, buf_len, &index);
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code);
+
+ err_code = uint8_t_enc(&list_index, p_buf, buf_len, &index);
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code);
+
+ SER_ASSERT_LENGTH_LEQ(index, *p_buf_len);
+
+ *p_buf_len = index;
+
+ return err_code;
+}
+
+
+uint32_t ant_id_list_add_rsp_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ uint32_t * const p_result_code)
+{
+ // Use the ble cmd rsp dec function because it is adequte to decode
+ // the command response as it is the same for both ant and ble.
+ return ser_ble_cmd_rsp_dec(p_buf, packet_len, SVC_ANT_ID_LIST_ADD, p_result_code);
+}
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/application/codecs/ant/serializers/ant_id_list_config.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/application/codecs/ant/serializers/ant_id_list_config.c
new file mode 100644
index 0000000..305dec8
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/application/codecs/ant/serializers/ant_id_list_config.c
@@ -0,0 +1,81 @@
+/**
+ * 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+
+#include <stdlib.h>
+#include <string.h>
+#include "ant_app.h"
+#include "ble_serialization.h"
+#include "ant_struct_serialization.h"
+#include "cond_field_serialization.h"
+#include "app_util.h"
+
+uint32_t ant_id_list_config_req_enc(uint8_t channel,
+ uint8_t id_list_size,
+ uint8_t inc_exc_flag,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len)
+{
+ uint32_t index = 0;
+ uint32_t err_code = NRF_SUCCESS;
+
+ SER_ASSERT_NOT_NULL(p_buf);
+ SER_ASSERT_NOT_NULL(p_buf_len);
+
+ p_buf[index++] = SVC_ANT_ID_LIST_CONFIG;
+ p_buf[index++] = channel;
+ p_buf[index++] = id_list_size;
+ p_buf[index++] = inc_exc_flag;
+
+ SER_ASSERT_LENGTH_LEQ(index, *p_buf_len);
+
+ *p_buf_len = index;
+
+ return err_code;
+}
+
+
+uint32_t ant_id_list_config_rsp_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ uint32_t * const p_result_code)
+{
+ // Use the ble cmd rsp dec function because it is adequte to decode
+ // the command response as it is the same for both ant and ble.
+ return ser_ble_cmd_rsp_dec(p_buf, packet_len, SVC_ANT_ID_LIST_CONFIG, p_result_code);
+}
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/application/codecs/ant/serializers/ant_lib_config_clear.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/application/codecs/ant/serializers/ant_lib_config_clear.c
new file mode 100644
index 0000000..0a703b2
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/application/codecs/ant/serializers/ant_lib_config_clear.c
@@ -0,0 +1,76 @@
+/**
+ * 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+
+#include <stdlib.h>
+#include <string.h>
+#include "ant_app.h"
+#include "ble_serialization.h"
+#include "ant_struct_serialization.h"
+#include "cond_field_serialization.h"
+#include "app_util.h"
+
+uint32_t ant_lib_config_clear_req_enc(uint8_t ant_lib_config,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len)
+{
+ uint32_t index = 0;
+ uint32_t err_code = NRF_SUCCESS;
+
+ SER_ASSERT_NOT_NULL(p_buf);
+ SER_ASSERT_NOT_NULL(p_buf_len);
+
+ p_buf[index++] = SVC_ANT_LIB_CONFIG_CLEAR;
+ p_buf[index++] = ant_lib_config;
+
+ SER_ASSERT_LENGTH_LEQ(index, *p_buf_len);
+
+ *p_buf_len = index;
+
+ return err_code;
+}
+
+uint32_t ant_lib_config_clear_rsp_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ uint32_t * const p_result_code)
+{
+ // Use the ble cmd rsp dec function because it is adequte to decode
+ // the command response as it is the same for both ant and ble.
+ return ser_ble_cmd_rsp_dec(p_buf, packet_len, SVC_ANT_LIB_CONFIG_CLEAR, p_result_code);
+}
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/application/codecs/ant/serializers/ant_lib_config_get.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/application/codecs/ant/serializers/ant_lib_config_get.c
new file mode 100644
index 0000000..93f8819
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/application/codecs/ant/serializers/ant_lib_config_get.c
@@ -0,0 +1,93 @@
+/**
+ * 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+
+#include <stdlib.h>
+#include <string.h>
+#include "ant_app.h"
+#include "ble_serialization.h"
+#include "ant_struct_serialization.h"
+#include "cond_field_serialization.h"
+#include "app_util.h"
+
+uint32_t ant_lib_config_get_req_enc(uint8_t * const p_buf,
+ uint32_t * const p_buf_len)
+{
+ uint32_t index = 0;
+ uint32_t err_code = NRF_SUCCESS;
+
+ SER_ASSERT_NOT_NULL(p_buf);
+ SER_ASSERT_NOT_NULL(p_buf_len);
+
+ p_buf[index++] = SVC_ANT_LIB_CONFIG_GET;
+
+ SER_ASSERT_LENGTH_LEQ(index, *p_buf_len);
+
+ *p_buf_len = index;
+
+ return err_code;
+}
+
+uint32_t ant_lib_config_get_rsp_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ void * const p_ant_lib_config,
+ uint32_t * const p_result_code)
+{
+ SER_ASSERT_NOT_NULL(p_buf);
+ SER_ASSERT_NOT_NULL(p_result_code);
+
+ uint32_t index = 0;
+ uint32_t err_code = ser_ble_cmd_rsp_result_code_dec(p_buf, &index, packet_len,
+ SVC_ANT_LIB_CONFIG_GET, p_result_code);
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code);
+
+ if (*p_result_code != NRF_SUCCESS)
+ {
+ SER_ASSERT_LENGTH_EQ(index, packet_len);
+
+ return NRF_SUCCESS;
+ }
+
+ err_code = uint8_t_dec(p_buf, packet_len, &index, p_ant_lib_config);
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code);
+
+ SER_ASSERT_LENGTH_EQ(index, packet_len);
+
+ return NRF_SUCCESS;
+}
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/application/codecs/ant/serializers/ant_lib_config_set.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/application/codecs/ant/serializers/ant_lib_config_set.c
new file mode 100644
index 0000000..3f00546
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/application/codecs/ant/serializers/ant_lib_config_set.c
@@ -0,0 +1,76 @@
+/**
+ * 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+
+#include <stdlib.h>
+#include <string.h>
+#include "ant_app.h"
+#include "ble_serialization.h"
+#include "ant_struct_serialization.h"
+#include "cond_field_serialization.h"
+#include "app_util.h"
+
+uint32_t ant_lib_config_set_req_enc(uint8_t ant_lib_config,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len)
+{
+ uint32_t index = 0;
+ uint32_t err_code = NRF_SUCCESS;
+
+ SER_ASSERT_NOT_NULL(p_buf);
+ SER_ASSERT_NOT_NULL(p_buf_len);
+
+ p_buf[index++] = SVC_ANT_LIB_CONFIG_SET;
+ p_buf[index++] = ant_lib_config;
+
+ SER_ASSERT_LENGTH_LEQ(index, *p_buf_len);
+
+ *p_buf_len = index;
+
+ return err_code;
+}
+
+uint32_t ant_lib_config_set_rsp_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ uint32_t * const p_result_code)
+{
+ // Use the ble cmd rsp dec function because it is adequte to decode
+ // the command response as it is the same for both ant and ble.
+ return ser_ble_cmd_rsp_dec(p_buf, packet_len, SVC_ANT_LIB_CONFIG_SET, p_result_code);
+}
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/application/codecs/ant/serializers/ant_network_address_set.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/application/codecs/ant/serializers/ant_network_address_set.c
new file mode 100644
index 0000000..fade1d4
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/application/codecs/ant/serializers/ant_network_address_set.c
@@ -0,0 +1,85 @@
+/**
+ * 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+
+#include <stdlib.h>
+#include <string.h>
+#include "ant_app.h"
+#include "ble_serialization.h"
+#include "ant_struct_serialization.h"
+#include "cond_field_serialization.h"
+#include "app_util.h"
+
+uint32_t ant_network_address_set_req_enc(uint8_t network,
+ uint8_t const * const p_network_key,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len)
+{
+ SER_ASSERT_NOT_NULL(p_buf);
+ SER_ASSERT_NOT_NULL(p_buf_len);
+
+ uint8_t svc_number = SVC_ANT_NETWORK_KEY_SET;
+ uint32_t err_code = NRF_SUCCESS;
+ uint32_t buf_len = *p_buf_len;
+ uint32_t index = 0;
+
+ err_code = uint8_t_enc(&svc_number, p_buf, buf_len, &index);
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code);
+
+ err_code = uint8_t_enc(&network, p_buf, buf_len, &index);
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code);
+
+ err_code = uint8_vector_enc(p_network_key, MESG_NETWORK_KEY_SIZE - MESG_CHANNEL_NUM_SIZE, p_buf, buf_len, &index);
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code);
+
+ SER_ASSERT_LENGTH_LEQ(index, *p_buf_len);
+
+ *p_buf_len = index;
+
+ return err_code;
+}
+
+uint32_t ant_network_address_set_rsp_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ uint32_t * const p_result_code)
+{
+ // Use the ble cmd rsp dec function because it is adequte to decode
+ // the command response as it is the same for both ant and ble.
+ return ser_ble_cmd_rsp_dec(p_buf, packet_len, SVC_ANT_NETWORK_KEY_SET, p_result_code);
+}
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/application/codecs/ant/serializers/ant_prox_search_set.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/application/codecs/ant/serializers/ant_prox_search_set.c
new file mode 100644
index 0000000..45b5415
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/application/codecs/ant/serializers/ant_prox_search_set.c
@@ -0,0 +1,81 @@
+/**
+ * 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+
+#include <stdlib.h>
+#include <string.h>
+#include "ant_app.h"
+#include "ble_serialization.h"
+#include "ant_struct_serialization.h"
+#include "cond_field_serialization.h"
+#include "app_util.h"
+
+uint32_t ant_prox_search_set_req_enc(uint8_t channel,
+ uint8_t prox_threshold,
+ uint8_t custom_prox_threshold,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len)
+{
+ uint32_t index = 0;
+ uint32_t err_code = NRF_SUCCESS;
+
+ SER_ASSERT_NOT_NULL(p_buf);
+ SER_ASSERT_NOT_NULL(p_buf_len);
+
+ p_buf[index++] = SVC_ANT_PROX_SEARCH_SET;
+ p_buf[index++] = channel;
+ p_buf[index++] = prox_threshold;
+ p_buf[index++] = custom_prox_threshold;
+
+ SER_ASSERT_LENGTH_LEQ(index, *p_buf_len);
+
+ *p_buf_len = index;
+
+ return err_code;
+}
+
+
+uint32_t ant_prox_search_set_rsp_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ uint32_t * const p_result_code)
+{
+ // Use the ble cmd rsp dec function because it is adequte to decode
+ // the command response as it is the same for both ant and ble.
+ return ser_ble_cmd_rsp_dec(p_buf, packet_len, SVC_ANT_PROX_SEARCH_SET, p_result_code);
+}
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/application/codecs/ant/serializers/ant_rx_scan_mode_start.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/application/codecs/ant/serializers/ant_rx_scan_mode_start.c
new file mode 100644
index 0000000..6cdefe7
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/application/codecs/ant/serializers/ant_rx_scan_mode_start.c
@@ -0,0 +1,76 @@
+/**
+ * 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+
+#include <stdlib.h>
+#include <string.h>
+#include "ant_app.h"
+#include "ble_serialization.h"
+#include "ant_struct_serialization.h"
+#include "cond_field_serialization.h"
+#include "app_util.h"
+
+uint32_t ant_rx_scan_mode_start_req_enc(uint8_t sync_scan_channel_packets_only,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len)
+{
+ uint32_t index = 0;
+ uint32_t err_code = NRF_SUCCESS;
+
+ SER_ASSERT_NOT_NULL(p_buf);
+ SER_ASSERT_NOT_NULL(p_buf_len);
+
+ p_buf[index++] = SVC_ANT_RX_SCAN_MODE_START;
+ p_buf[index++] = sync_scan_channel_packets_only;
+
+ SER_ASSERT_LENGTH_LEQ(index, *p_buf_len);
+
+ *p_buf_len = index;
+
+ return err_code;
+}
+
+uint32_t ant_rx_scan_mode_start_rsp_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ uint32_t * const p_result_code)
+{
+ // Use the ble cmd rsp dec function because it is adequte to decode
+ // the command response as it is the same for both ant and ble.
+ return ser_ble_cmd_rsp_dec(p_buf, packet_len, SVC_ANT_RX_SCAN_MODE_START, p_result_code);
+}
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/application/codecs/ant/serializers/ant_search_channel_priority_set.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/application/codecs/ant/serializers/ant_search_channel_priority_set.c
new file mode 100644
index 0000000..0ad7a55
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/application/codecs/ant/serializers/ant_search_channel_priority_set.c
@@ -0,0 +1,78 @@
+/**
+ * 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+
+#include <stdlib.h>
+#include <string.h>
+#include "ant_app.h"
+#include "ble_serialization.h"
+#include "ant_struct_serialization.h"
+#include "cond_field_serialization.h"
+#include "app_util.h"
+
+uint32_t ant_search_channel_priority_set_req_enc(uint8_t channel,
+ uint8_t search_priority,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len)
+{
+ uint32_t index = 0;
+ uint32_t err_code = NRF_SUCCESS;
+
+ SER_ASSERT_NOT_NULL(p_buf);
+ SER_ASSERT_NOT_NULL(p_buf_len);
+
+ p_buf[index++] = SVC_ANT_SEARCH_CHANNEL_PRIORITY_SET;
+ p_buf[index++] = channel;
+ p_buf[index++] = search_priority;
+
+ SER_ASSERT_LENGTH_LEQ(index, *p_buf_len);
+
+ *p_buf_len = index;
+
+ return err_code;
+}
+
+uint32_t ant_search_channel_priority_set_rsp_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ uint32_t * const p_result_code)
+{
+ // Use the ble cmd rsp dec function because it is adequte to decode
+ // the command response as it is the same for both ant and ble.
+ return ser_ble_cmd_rsp_dec(p_buf, packet_len, SVC_ANT_SEARCH_CHANNEL_PRIORITY_SET, p_result_code);
+}
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/application/codecs/ant/serializers/ant_search_waveform_set.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/application/codecs/ant/serializers/ant_search_waveform_set.c
new file mode 100644
index 0000000..6204445
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/application/codecs/ant/serializers/ant_search_waveform_set.c
@@ -0,0 +1,79 @@
+/**
+ * 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+
+#include <stdlib.h>
+#include <string.h>
+#include "ant_app.h"
+#include "ble_serialization.h"
+#include "ant_struct_serialization.h"
+#include "cond_field_serialization.h"
+#include "app_util.h"
+
+uint32_t ant_search_waveform_set_req_enc(uint8_t channel,
+ uint16_t waveform,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len)
+{
+ uint32_t index = 0;
+ uint32_t err_code = NRF_SUCCESS;
+
+ SER_ASSERT_NOT_NULL(p_buf);
+ SER_ASSERT_NOT_NULL(p_buf_len);
+
+ p_buf[index++] = SVC_ANT_SEARCH_WAVEFORM_SET;
+ p_buf[index++] = channel;
+ index += uint16_encode(waveform, &p_buf[index]);
+
+ SER_ASSERT_LENGTH_LEQ(index, *p_buf_len);
+
+ *p_buf_len = index;
+
+ return err_code;
+}
+
+
+uint32_t ant_search_waveform_set_rsp_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ uint32_t * const p_result_code)
+{
+ // Use the ble cmd rsp dec function because it is adequte to decode
+ // the command response as it is the same for both ant and ble.
+ return ser_ble_cmd_rsp_dec(p_buf, packet_len, SVC_ANT_SEARCH_WAVEFORM_SET, p_result_code);
+}
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/application/codecs/ant/serializers/ant_stack_reset.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/application/codecs/ant/serializers/ant_stack_reset.c
new file mode 100644
index 0000000..15fb65d
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/application/codecs/ant/serializers/ant_stack_reset.c
@@ -0,0 +1,74 @@
+/**
+ * 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+
+#include <stdlib.h>
+#include <string.h>
+#include "ant_app.h"
+#include "ble_serialization.h"
+#include "ant_struct_serialization.h"
+#include "cond_field_serialization.h"
+#include "app_util.h"
+
+uint32_t ant_stack_reset_req_enc(uint8_t * const p_buf,
+ uint32_t * const p_buf_len)
+{
+ uint32_t index = 0;
+ uint32_t err_code = NRF_SUCCESS;
+
+ SER_ASSERT_NOT_NULL(p_buf);
+ SER_ASSERT_NOT_NULL(p_buf_len);
+
+ p_buf[index++] = SVC_ANT_STACK_INIT;
+
+ SER_ASSERT_LENGTH_LEQ(index, *p_buf_len);
+
+ *p_buf_len = index;
+
+ return err_code;
+}
+
+uint32_t ant_stack_reset_rsp_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ uint32_t * const p_result_code)
+{
+ // Use the ble cmd rsp dec function because it is adequte to decode
+ // the command response as it is the same for both ant and ble.
+ return ser_ble_cmd_rsp_dec(p_buf, packet_len, SVC_ANT_STACK_INIT, p_result_code);
+}
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/application/codecs/ant/serializers/ant_version_get.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/application/codecs/ant/serializers/ant_version_get.c
new file mode 100644
index 0000000..f0159de
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/application/codecs/ant/serializers/ant_version_get.c
@@ -0,0 +1,93 @@
+/**
+ * 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+
+#include <stdlib.h>
+#include <string.h>
+#include "ant_app.h"
+#include "ble_serialization.h"
+#include "ant_struct_serialization.h"
+#include "cond_field_serialization.h"
+#include "app_util.h"
+
+uint32_t ant_version_get_req_enc(uint8_t * const p_buf,
+ uint32_t * const p_buf_len)
+{
+ uint32_t index = 0;
+ uint32_t err_code = NRF_SUCCESS;
+
+ SER_ASSERT_NOT_NULL(p_buf);
+ SER_ASSERT_NOT_NULL(p_buf_len);
+
+ p_buf[index++] = SVC_ANT_VERSION;
+
+ SER_ASSERT_LENGTH_LEQ(index, *p_buf_len);
+
+ *p_buf_len = index;
+
+ return err_code;
+}
+
+uint32_t ant_version_get_rsp_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ void * * const p_version,
+ uint32_t * const p_result_code)
+{
+ SER_ASSERT_NOT_NULL(p_buf);
+ SER_ASSERT_NOT_NULL(p_result_code);
+
+ uint32_t index = 0;
+ uint32_t err_code = ser_ble_cmd_rsp_result_code_dec(p_buf, &index, packet_len,
+ SVC_ANT_VERSION, p_result_code);
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code);
+
+ if (*p_result_code != NRF_SUCCESS)
+ {
+ SER_ASSERT_LENGTH_EQ(index, packet_len);
+
+ return NRF_SUCCESS;
+ }
+
+ err_code = uint8_vector_dec(p_buf, packet_len, &index, (uint8_t *)*p_version, MESG_BUFFER_SIZE);
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code);
+
+ SER_ASSERT_LENGTH_EQ(index, packet_len);
+
+ return NRF_SUCCESS;
+}
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/application/codecs/ble/middleware/app_mw_ble.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/application/codecs/ble/middleware/app_mw_ble.c
new file mode 100644
index 0000000..5aa5571
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/application/codecs/ble/middleware/app_mw_ble.c
@@ -0,0 +1,621 @@
+/**
+ * Copyright (c) 2014 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#include "ble.h"
+#include "ble_serialization.h"
+#include <stdint.h>
+#include "ble_app.h"
+#include "ser_sd_transport.h"
+#include "app_error.h"
+#include "app_ble_user_mem.h"
+
+extern ser_ble_user_mem_t m_app_user_mem_table[];
+
+/**@brief Structure containing @ref sd_ble_uuid_encode output parameters. */
+typedef struct
+{
+ uint8_t * p_uuid_le_len; /**< @ref sd_ble_uuid_encode appearance p_uuid_le_len output parameter. */
+ uint8_t * p_uuid_le; /**< @ref sd_ble_uuid_encode appearance p_uuid_le output parameter. */
+} ble_uuid_encode_out_params_t;
+
+/**@brief Structure containing @ref sd_ble_user_mem_reply output parameters. */
+typedef struct
+{
+ uint16_t conn_handle; /**< @ref sd_ble_user_mem_reply conn_handle. */
+ uint8_t context_allocated; /**< @ref sd_ble_user_mem_reply user memory context allocated flag. */
+} ble_user_mem_reply_out_params_t;
+
+/**@brief Union containing BLE command output parameters. */
+typedef union
+{
+ ble_uuid_encode_out_params_t ble_uuid_encode_out_params; /**< @ref sd_ble_uuid_encode output parameters. */
+ ble_user_mem_reply_out_params_t ble_user_mem_reply_out_params; /**< @ref sd_ble_user_mem_reply output parameters. */
+} ble_command_output_params_t;
+
+static ble_command_output_params_t m_output_params; /**< BLE command output parameters. */
+
+static void * mp_out_params[3];
+static uint32_t m_uint32_param;
+
+static void tx_buf_alloc(uint8_t * * p_data, uint32_t * p_len)
+{
+ uint32_t err_code;
+ uint16_t len16;
+
+ do
+ {
+ err_code = ser_sd_transport_tx_alloc(p_data, &len16);
+ }
+ while (err_code != NRF_SUCCESS);
+
+ *p_data[0] = SER_PKT_TYPE_CMD;
+ *p_len = (uint32_t)len16 - 1;
+}
+
+/**@brief Command response callback function for @ref sd_ble_uuid_encode BLE command.
+ *
+ * Callback for decoding the output parameters and the command response return code.
+ *
+ * @param[in] p_buffer Pointer to begin of command response buffer.
+ * @param[in] length Length of data in bytes.
+ *
+ * @return Decoded command response return code.
+ */
+static uint32_t uuid_encode_rsp_dec(const uint8_t * p_buffer, uint16_t length)
+{
+ uint32_t result_code;
+
+ const uint32_t err_code =
+ ble_uuid_encode_rsp_dec(p_buffer,
+ length,
+ m_output_params.ble_uuid_encode_out_params.p_uuid_le_len,
+ m_output_params.ble_uuid_encode_out_params.p_uuid_le,
+ &result_code);
+
+ //@note: Should never fail.
+ APP_ERROR_CHECK(err_code);
+ return result_code;
+}
+
+#ifndef _sd_ble_uuid_encode
+#define _sd_ble_uuid_encode sd_ble_uuid_encode
+#endif
+uint32_t _sd_ble_uuid_encode(ble_uuid_t const * const p_uuid,
+ uint8_t * const p_uuid_le_len,
+ uint8_t * const p_uuid_le)
+{
+ uint8_t * p_buffer;
+ uint32_t buffer_length;
+
+ tx_buf_alloc(&p_buffer, &buffer_length);
+
+ m_output_params.ble_uuid_encode_out_params.p_uuid_le_len = p_uuid_le_len;
+ m_output_params.ble_uuid_encode_out_params.p_uuid_le = p_uuid_le;
+
+ uint32_t err_code = ble_uuid_encode_req_enc(p_uuid,
+ p_uuid_le_len,
+ p_uuid_le,
+ &(p_buffer[1]),
+ &buffer_length);
+ //@note: Should never fail.
+ APP_ERROR_CHECK(err_code);
+
+ //@note: Increment buffer length as internally managed packet type field must be included.
+ return ser_sd_transport_cmd_write(p_buffer,
+ (++buffer_length),
+ uuid_encode_rsp_dec);
+
+}
+
+#if defined(NRF_SD_BLE_API_VERSION) && NRF_SD_BLE_API_VERSION < 4
+/**@brief Command response callback function for @ref sd_ble_tx_packet_count_get BLE command.
+ *
+ * Callback for decoding the output parameters and the command response return code.
+ *
+ * @param[in] p_buffer Pointer to begin of command response buffer.
+ * @param[in] length Length of data in bytes.
+ *
+ * @return Decoded command response return code.
+ */
+static uint32_t tx_packet_count_get_rsp_dec(const uint8_t * p_buffer, uint16_t length)
+{
+ uint32_t result_code;
+
+ const uint32_t err_code = ble_tx_packet_count_get_rsp_dec(p_buffer,
+ length,
+ (uint8_t * *)&mp_out_params[0],
+ &result_code);
+
+ //@note: Should never fail.
+ APP_ERROR_CHECK(err_code);
+
+ return result_code;
+}
+
+#ifndef _sd_ble_tx_packet_count_get
+#define _sd_ble_tx_packet_count_get sd_ble_tx_packet_count_get
+#endif
+uint32_t _sd_ble_tx_packet_count_get(uint16_t conn_handle, uint8_t * p_count)
+{
+ uint8_t * p_buffer;
+ uint32_t buffer_length;
+
+ tx_buf_alloc(&p_buffer, &buffer_length);
+ mp_out_params[0] = p_count;
+
+ const uint32_t err_code = ble_tx_packet_count_get_req_enc(conn_handle,
+ p_count,
+ &(p_buffer[1]),
+ &buffer_length);
+ APP_ERROR_CHECK(err_code);
+
+ //@note: Increment buffer length as internally managed packet type field must be included.
+ return ser_sd_transport_cmd_write(p_buffer,
+ (++buffer_length),
+ tx_packet_count_get_rsp_dec);
+
+}
+#endif
+/**@brief Command response callback function for @ref sd_ble_uuid_vs_add BLE command.
+ *
+ * Callback for decoding the output parameters and the command response return code.
+ *
+ * @param[in] p_buffer Pointer to begin of command response buffer.
+ * @param[in] length Length of data in bytes.
+ *
+ * @return Decoded command response return code.
+ */
+static uint32_t uuid_vs_add_rsp_dec(const uint8_t * p_buffer, uint16_t length)
+{
+ uint32_t result_code;
+
+ const uint32_t err_code = ble_uuid_vs_add_rsp_dec(p_buffer,
+ length,
+ (uint8_t * *)&mp_out_params[0],
+ &result_code);
+
+ //@note: Should never fail.
+ APP_ERROR_CHECK(err_code);
+
+ return result_code;
+}
+
+#ifndef _sd_ble_uuid_vs_add
+#define _sd_ble_uuid_vs_add sd_ble_uuid_vs_add
+#endif
+uint32_t _sd_ble_uuid_vs_add(ble_uuid128_t const * const p_vs_uuid, uint8_t * const p_uuid_type)
+{
+ uint8_t * p_buffer;
+ uint32_t buffer_length;
+
+ tx_buf_alloc(&p_buffer, &buffer_length);
+ mp_out_params[0] = p_uuid_type;
+
+ const uint32_t err_code = ble_uuid_vs_add_req_enc(p_vs_uuid, p_uuid_type,
+ &(p_buffer[1]),
+ &buffer_length);
+ APP_ERROR_CHECK(err_code);
+
+ //@note: Increment buffer length as internally managed packet type field must be included.
+ return ser_sd_transport_cmd_write(p_buffer,
+ (++buffer_length),
+ uuid_vs_add_rsp_dec);
+}
+
+/**@brief Command response callback function for @ref sd_ble_uuid_decode BLE command.
+ *
+ * Callback for decoding the output parameters and the command response return code.
+ *
+ * @param[in] p_buffer Pointer to begin of command response buffer.
+ * @param[in] length Length of data in bytes.
+ *
+ * @return Decoded command response return code.
+ */
+static uint32_t uuid_decode_rsp_dec(const uint8_t * p_buffer, uint16_t length)
+{
+ uint32_t result_code;
+
+ const uint32_t err_code = ble_uuid_decode_rsp_dec(p_buffer,
+ length,
+ (ble_uuid_t * *)&mp_out_params[0],
+ &result_code);
+
+ //@note: Should never fail.
+ APP_ERROR_CHECK(err_code);
+
+ return result_code;
+}
+
+#ifndef _sd_ble_uuid_decode
+#define _sd_ble_uuid_decode sd_ble_uuid_decode
+#endif
+uint32_t _sd_ble_uuid_decode(uint8_t uuid_le_len,
+ uint8_t const * const p_uuid_le,
+ ble_uuid_t * const p_uuid)
+{
+ uint8_t * p_buffer;
+ uint32_t buffer_length;
+
+ tx_buf_alloc(&p_buffer, &buffer_length);
+ mp_out_params[0] = p_uuid;
+
+ const uint32_t err_code = ble_uuid_decode_req_enc(uuid_le_len, p_uuid_le, p_uuid,
+ &(p_buffer[1]),
+ &buffer_length);
+ APP_ERROR_CHECK(err_code);
+
+ //@note: Increment buffer length as internally managed packet type field must be included.
+ return ser_sd_transport_cmd_write(p_buffer,
+ (++buffer_length),
+ uuid_decode_rsp_dec);
+}
+
+/**@brief Command response callback function for @ref sd_ble_version_get BLE command.
+ *
+ * Callback for decoding the output parameters and the command response return code.
+ *
+ * @param[in] p_buffer Pointer to begin of command response buffer.
+ * @param[in] length Length of data in bytes.
+ *
+ * @return Decoded command response return code.
+ */
+static uint32_t version_get_rsp_dec(const uint8_t * p_buffer, uint16_t length)
+{
+ uint32_t result_code;
+
+ const uint32_t err_code = ble_version_get_rsp_dec(p_buffer,
+ length,
+ (ble_version_t *)mp_out_params[0],
+ &result_code);
+
+ //@note: Should never fail.
+ APP_ERROR_CHECK(err_code);
+
+ return result_code;
+}
+
+#ifndef _sd_ble_version_get
+#define _sd_ble_version_get sd_ble_version_get
+#endif
+uint32_t _sd_ble_version_get(ble_version_t * p_version)
+{
+ uint8_t * p_buffer;
+ uint32_t buffer_length;
+
+ tx_buf_alloc(&p_buffer, &buffer_length);
+ mp_out_params[0] = p_version;
+
+ const uint32_t err_code = ble_version_get_req_enc(p_version,
+ &(p_buffer[1]),
+ &buffer_length);
+ APP_ERROR_CHECK(err_code);
+
+ //@note: Increment buffer length as internally managed packet type field must be included.
+ return ser_sd_transport_cmd_write(p_buffer,
+ (++buffer_length),
+ version_get_rsp_dec);
+
+}
+
+/**@brief Command response callback function for @ref sd_ble_opt_get BLE command.
+ *
+ * Callback for decoding the output parameters and the command response return code.
+ *
+ * @param[in] p_buffer Pointer to begin of command response buffer.
+ * @param[in] length Length of data in bytes.
+ *
+ * @return Decoded command response return code.
+ */
+static uint32_t opt_get_rsp_dec(const uint8_t * p_buffer, uint16_t length)
+{
+ uint32_t result_code;
+ uint32_t uint32_param;
+ uint32_t err_code = ble_opt_get_rsp_dec(p_buffer,
+ length,
+ &uint32_param,
+ (ble_opt_t *)mp_out_params[0],
+ &result_code);
+
+ APP_ERROR_CHECK(err_code);
+ if ((result_code == NRF_SUCCESS) && (m_uint32_param != uint32_param)) // decoded id should be the same as encoded one
+ {
+ err_code = NRF_ERROR_INVALID_PARAM;
+ }
+ APP_ERROR_CHECK(err_code);
+
+ return result_code;
+}
+
+#ifndef _sd_ble_opt_get
+#define _sd_ble_opt_get sd_ble_opt_get
+#endif
+uint32_t _sd_ble_opt_get(uint32_t opt_id, ble_opt_t *p_opt)
+{
+ uint8_t * p_buffer;
+ uint32_t buffer_length;
+
+ tx_buf_alloc(&p_buffer, &buffer_length);
+ mp_out_params[0] = p_opt;
+ m_uint32_param = opt_id;
+
+ const uint32_t err_code = ble_opt_get_req_enc(opt_id,
+ p_opt,
+ &(p_buffer[1]),
+ &buffer_length);
+ APP_ERROR_CHECK(err_code);
+
+ //@note: Increment buffer length as internally managed packet type field must be included.
+ return ser_sd_transport_cmd_write(p_buffer,
+ (++buffer_length),
+ opt_get_rsp_dec);
+
+}
+
+/**@brief Command response callback function for @ref sd_ble_opt_set BLE command.
+ *
+ * Callback for decoding the output parameters and the command response return code.
+ *
+ * @param[in] p_buffer Pointer to begin of command response buffer.
+ * @param[in] length Length of data in bytes.
+ *
+ * @return Decoded command response return code.
+ */
+static uint32_t opt_set_rsp_dec(const uint8_t * p_buffer, uint16_t length)
+{
+ uint32_t result_code;
+
+ const uint32_t err_code = ble_opt_set_rsp_dec(p_buffer,
+ length,
+ &result_code);
+
+ APP_ERROR_CHECK(err_code);
+
+ return result_code;
+}
+
+#ifndef _sd_ble_opt_set
+#define _sd_ble_opt_set sd_ble_opt_set
+#endif
+uint32_t _sd_ble_opt_set(uint32_t opt_id, ble_opt_t const *p_opt)
+{
+ uint8_t * p_buffer;
+ uint32_t buffer_length;
+
+ tx_buf_alloc(&p_buffer, &buffer_length);
+
+ const uint32_t err_code = ble_opt_set_req_enc(opt_id,
+ p_opt,
+ &(p_buffer[1]),
+ &buffer_length);
+ APP_ERROR_CHECK(err_code);
+
+ //@note: Increment buffer length as internally managed packet type field must be included.
+ return ser_sd_transport_cmd_write(p_buffer,
+ (++buffer_length),
+ opt_set_rsp_dec);
+
+}
+
+/**@brief Command response callback function for @ref sd_ble_enable BLE command.
+ *
+ * Callback for decoding the output parameters and the command response return code.
+ *
+ * @param[in] p_buffer Pointer to begin of command response buffer.
+ * @param[in] length Length of data in bytes.
+ *
+ * @return Decoded command response return code.
+ */
+static uint32_t enable_rsp_dec(const uint8_t * p_buffer, uint16_t length)
+{
+ uint32_t result_code;
+
+ const uint32_t err_code = ble_enable_rsp_dec(p_buffer,
+ length,
+ &result_code);
+
+ //@note: Should never fail.
+ APP_ERROR_CHECK(err_code);
+
+ return result_code;
+}
+
+#ifndef _sd_ble_enable
+#define _sd_ble_enable sd_ble_enable
+#endif
+#if defined(NRF_SD_BLE_API_VERSION) && NRF_SD_BLE_API_VERSION < 4
+uint32_t _sd_ble_enable(ble_enable_params_t * p_params, uint32_t * p_app_ram_base)
+{
+ uint8_t * p_buffer;
+ uint32_t buffer_length;
+
+ //Ignore ram_base parameter
+ (void)p_app_ram_base;
+
+ tx_buf_alloc(&p_buffer, &buffer_length);
+ mp_out_params[0] = p_params;
+
+ const uint32_t err_code = ble_enable_req_enc(p_params,
+ &(p_buffer[1]),
+ &buffer_length);
+ APP_ERROR_CHECK(err_code);
+
+ //@note: Increment buffer length as internally managed packet type field must be included.
+ return ser_sd_transport_cmd_write(p_buffer,
+ (++buffer_length),
+ enable_rsp_dec);
+
+}
+#else
+uint32_t _sd_ble_enable(uint32_t * p_app_ram_base)
+{
+ uint8_t * p_buffer;
+ uint32_t buffer_length;
+
+ //Ignore ram_base parameter
+ (void)p_app_ram_base;
+
+ tx_buf_alloc(&p_buffer, &buffer_length);
+
+ const uint32_t err_code = ble_enable_req_enc(&(p_buffer[1]),
+ &buffer_length);
+ APP_ERROR_CHECK(err_code);
+
+ //@note: Increment buffer length as internally managed packet type field must be included.
+ return ser_sd_transport_cmd_write(p_buffer,
+ (++buffer_length),
+ enable_rsp_dec);
+
+}
+#endif
+/**@brief Command response callback function for @ref sd_ble_user_mem_reply BLE command.
+ *
+ * Callback for decoding the output parameters and the command response return code.
+ *
+ * @param[in] p_buffer Pointer to begin of command response buffer.
+ * @param[in] length Length of data in bytes.
+ *
+ * @return Decoded command response return code.
+ */
+static uint32_t user_mem_reply_rsp_dec(const uint8_t * p_buffer, uint16_t length)
+{
+ uint32_t result_code;
+
+ uint32_t err_code = ble_user_mem_reply_rsp_dec(p_buffer,
+ length,
+ &result_code);
+ APP_ERROR_CHECK(err_code);
+
+ if ((result_code != NRF_SUCCESS) &&
+ (m_output_params.ble_user_mem_reply_out_params.context_allocated))
+ {
+ err_code = app_ble_user_mem_context_destroy(
+ m_output_params.ble_user_mem_reply_out_params.conn_handle);
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code);
+ }
+
+ return result_code;
+}
+
+#ifndef _sd_ble_user_mem_reply
+#define _sd_ble_user_mem_reply sd_ble_user_mem_reply
+#endif
+uint32_t _sd_ble_user_mem_reply(uint16_t conn_handle, ble_user_mem_block_t const *p_block)
+{
+ uint8_t * p_buffer;
+ uint32_t buffer_length, user_mem_table_index;
+ uint32_t err_code = NRF_SUCCESS;
+
+ tx_buf_alloc(&p_buffer, &buffer_length);
+
+ // Prepare User Memory Block context for later synchronization when SoftDevice updates
+ // the data in the memory block
+ if (p_block != NULL)
+ {
+ err_code = app_ble_user_mem_context_create(conn_handle, &user_mem_table_index);
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code);
+ m_app_user_mem_table[user_mem_table_index].mem_block.len = p_block->len;
+ m_app_user_mem_table[user_mem_table_index].mem_block.p_mem = p_block->p_mem;
+ // Save connection handle and context allocation flag for case if context destroy was needed
+ m_output_params.ble_user_mem_reply_out_params.conn_handle = conn_handle;
+ m_output_params.ble_user_mem_reply_out_params.context_allocated = 1;
+ }
+ else
+ {
+ m_output_params.ble_user_mem_reply_out_params.context_allocated = 0;
+ }
+
+ err_code = ble_user_mem_reply_req_enc(conn_handle,
+ p_block,
+ &(p_buffer[1]),
+ &buffer_length);
+ APP_ERROR_CHECK(err_code);
+
+ //@note: Increment buffer length as internally managed packet type field must be included.
+ return ser_sd_transport_cmd_write(p_buffer,
+ (++buffer_length),
+ user_mem_reply_rsp_dec);
+}
+#if NRF_SD_BLE_API_VERSION >= 4
+/**@brief Command response callback function for @ref sd_ble_cfg_set BLE command.
+ *
+ * Callback for decoding the output parameters and the command response return code.
+ *
+ * @param[in] p_buffer Pointer to begin of command response buffer.
+ * @param[in] length Length of data in bytes.
+ *
+ * @return Decoded command response return code.
+ */
+static uint32_t cfg_set_rsp_dec(const uint8_t * p_buffer, uint16_t length)
+{
+ uint32_t result_code;
+
+ const uint32_t err_code = ble_cfg_set_rsp_dec(p_buffer,
+ length,
+ &result_code);
+
+ //@note: Should never fail.
+ APP_ERROR_CHECK(err_code);
+
+ return result_code;
+}
+
+#ifndef _sd_ble_cfg_set
+#define _sd_ble_cfg_set sd_ble_cfg_set
+#endif
+uint32_t _sd_ble_cfg_set(uint32_t cfg_id, ble_cfg_t const * p_cfg, uint32_t app_ram_base)
+{
+ uint8_t * p_buffer;
+ uint32_t buffer_length;
+
+ //Ignore ram_base parameter
+ (void)app_ram_base;
+
+ tx_buf_alloc(&p_buffer, &buffer_length);
+
+ const uint32_t err_code = ble_cfg_set_req_enc(cfg_id, p_cfg,
+ &(p_buffer[1]),
+ &buffer_length);
+ APP_ERROR_CHECK(err_code);
+
+ //@note: Increment buffer length as internally managed packet type field must be included.
+ return ser_sd_transport_cmd_write(p_buffer,
+ (++buffer_length),
+ cfg_set_rsp_dec);
+}
+#endif
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/application/codecs/ble/middleware/app_mw_ble_gap.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/application/codecs/ble/middleware/app_mw_ble_gap.c
new file mode 100644
index 0000000..55cc2fa
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/application/codecs/ble/middleware/app_mw_ble_gap.c
@@ -0,0 +1,2025 @@
+/**
+ * Copyright (c) 2014 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#include "ble_gap.h"
+#include <stdint.h>
+#include <string.h>
+#include "ble_serialization.h"
+#include "ser_sd_transport.h"
+#include "ble_gap_app.h"
+#include "app_error.h"
+#include "app_ble_gap_sec_keys.h"
+#include "ser_config.h"
+
+extern ser_ble_gap_app_keyset_t m_app_keys_table[SER_MAX_CONNECTIONS];
+
+/**@brief Structure containing @ref sd_ble_gap_device_name_get output parameters. */
+typedef struct
+{
+ uint8_t * p_dev_name; /**< @ref sd_ble_gap_device_name_get p_dev_name output parameter. */
+ uint16_t * p_len; /**< @ref sd_ble_gap_device_name_get p_len output parameter. */
+} gap_device_name_get_output_params_t;
+
+/**@brief Structure containing @ref sd_ble_gap_appearance_get output parameters. */
+typedef struct
+{
+ uint16_t * p_appearance; /**< @ref sd_ble_gap_appearance_get p_appearance output parameter. */
+} gap_appearance_get_output_params_t;
+
+/**@brief Structure containing @ref sd_ble_gap_ppcp_get output parameters. */
+typedef struct
+{
+ ble_gap_conn_params_t * p_conn_params; /**< @ref sd_ble_gap_ppcp_get p_conn_params output parameter. */
+} gap_ppcp_get_out_params_t;
+
+/**@brief Structure containing @ref sd_ble_gap_sec_params_reply output parameters. */
+typedef struct
+{
+ ble_gap_sec_keyset_t const * p_sec_keyset; /**< @ref sd_ble_gap_sec_params_reply p_sec_keyset output parameter. */
+ uint16_t conn_handle; /**< @ref sd_ble_gap_sec_params_reply p_conn_handle output parameter. */
+} gap_sec_params_reply_out_params_t;
+
+/**@brief Union containing BLE command output parameters. */
+typedef union
+{
+ gap_device_name_get_output_params_t gap_device_name_get_out_params; /**< @ref sd_ble_gap_device_name_get output parameters. */
+ gap_appearance_get_output_params_t gap_appearance_get_out_params; /**< @ref sd_ble_gap_appearance_get output parameters. */
+ gap_ppcp_get_out_params_t gap_ppcp_get_out_params; /**< @ref sd_ble_gap_ppcp_get output parameters. */
+ gap_sec_params_reply_out_params_t gap_sec_params_reply_out_params;/**< @ref sd_ble_sec_params_reply output parameters. */
+} gap_command_output_params_t;
+
+static gap_command_output_params_t m_output_params; /**< BLE command output parameters. */
+
+static void * mp_out_params[3];
+
+static void tx_buf_alloc(uint8_t * * p_data, uint16_t * p_len)
+{
+ uint32_t err_code;
+
+ do
+ {
+ err_code = ser_sd_transport_tx_alloc(p_data, p_len);
+ }
+ while (err_code != NRF_SUCCESS);
+ *p_data[0] = SER_PKT_TYPE_CMD;
+ *p_len -= 1;
+}
+
+/**@brief Command response callback function for @ref sd_ble_gap_adv_start BLE command.
+ *
+ * Callback for decoding the command response return code.
+ *
+ * @param[in] p_buffer Pointer to begin of command response buffer.
+ * @param[in] length Length of data in bytes.
+ *
+ * @return Decoded command response return code.
+ */
+static uint32_t gap_adv_start_rsp_dec(const uint8_t * p_buffer, uint16_t length)
+{
+ uint32_t result_code;
+
+ const uint32_t err_code = ble_gap_adv_start_rsp_dec(p_buffer, length, &result_code);
+
+ APP_ERROR_CHECK(err_code);
+
+ return result_code;
+}
+
+#ifndef _sd_ble_gap_adv_start
+#define _sd_ble_gap_adv_start sd_ble_gap_adv_start
+#endif
+uint32_t _sd_ble_gap_adv_start(
+#if NRF_SD_BLE_API_VERSION > 5
+ uint8_t adv_handle
+#else
+ ble_gap_adv_params_t const * const p_adv_params
+#endif
+#if NRF_SD_BLE_API_VERSION >= 4
+ ,uint8_t conn_cfg_tag
+#endif
+)
+{
+ uint8_t * p_buffer;
+ uint32_t buffer_length = 0;
+
+ tx_buf_alloc(&p_buffer, (uint16_t *)&buffer_length);
+
+ const uint32_t err_code = ble_gap_adv_start_req_enc(
+#if NRF_SD_BLE_API_VERSION > 5
+ adv_handle,
+#else
+ p_adv_params,
+#endif
+#if NRF_SD_BLE_API_VERSION >= 4
+ conn_cfg_tag,
+#endif
+ &(p_buffer[1]),
+ &buffer_length);
+ APP_ERROR_CHECK(err_code);
+
+ //@note: Increment buffer length as internally managed packet type field must be included.
+ return ser_sd_transport_cmd_write(p_buffer,
+ (++buffer_length),
+ gap_adv_start_rsp_dec);
+}
+
+/**@brief Command response callback function for @ref ble_gap_device_name_get_req_enc BLE command.
+ *
+ * Callback for decoding the output parameters and the command response return code.
+ *
+ * @param[in] p_buffer Pointer to begin of command response buffer.
+ * @param[in] length Length of data in bytes.
+ *
+ * @return Decoded command response return code.
+ */
+static uint32_t gap_device_name_get_rsp_dec(const uint8_t * p_buffer, uint16_t length)
+{
+ uint32_t result_code;
+
+ const uint32_t err_code =
+ ble_gap_device_name_get_rsp_dec(p_buffer,
+ length,
+ m_output_params.gap_device_name_get_out_params.p_dev_name,
+ m_output_params.gap_device_name_get_out_params.p_len,
+ &result_code);
+
+ APP_ERROR_CHECK(err_code);
+
+ return result_code;
+}
+
+#ifndef _sd_ble_gap_device_name_get
+#define _sd_ble_gap_device_name_get sd_ble_gap_device_name_get
+#endif
+uint32_t _sd_ble_gap_device_name_get(uint8_t * const p_dev_name, uint16_t * const p_len)
+{
+ uint8_t * p_buffer;
+ uint32_t buffer_length = 0;
+
+ tx_buf_alloc(&p_buffer, (uint16_t *)&buffer_length);
+ m_output_params.gap_device_name_get_out_params.p_dev_name = p_dev_name;
+ m_output_params.gap_device_name_get_out_params.p_len = p_len;
+
+ const uint32_t err_code = ble_gap_device_name_get_req_enc(p_dev_name,
+ p_len,
+ &(p_buffer[1]),
+ &buffer_length);
+ //@note: Should never fail.
+ APP_ERROR_CHECK(err_code);
+
+ //@note: Increment buffer length as internally managed packet type field must be included.
+ return ser_sd_transport_cmd_write(p_buffer,
+ (++buffer_length),
+ gap_device_name_get_rsp_dec);
+}
+
+
+/**@brief Command response callback function for @ref sd_ble_gap_appearance_get BLE command.
+ *
+ * Callback for decoding the output parameters and the command response return code.
+ *
+ * @param[in] p_buffer Pointer to begin of command response buffer.
+ * @param[in] length Length of data in bytes.
+ *
+ * @return Decoded command response return code.
+ */
+static uint32_t gap_appearance_get_rsp_dec(const uint8_t * p_buffer, uint16_t length)
+{
+ uint32_t result_code;
+
+ const uint32_t err_code =
+ ble_gap_appearance_get_rsp_dec(p_buffer,
+ length,
+ m_output_params.gap_appearance_get_out_params.p_appearance,
+ &result_code);
+
+ //@note: Should never fail.
+ APP_ERROR_CHECK(err_code);
+
+ return result_code;
+}
+
+#ifndef _sd_ble_gap_appearance_get
+#define _sd_ble_gap_appearance_get sd_ble_gap_appearance_get
+#endif
+uint32_t _sd_ble_gap_appearance_get(uint16_t * const p_appearance)
+{
+ uint8_t * p_buffer;
+ uint32_t buffer_length = 0;
+
+ tx_buf_alloc(&p_buffer, (uint16_t *)&buffer_length);
+ m_output_params.gap_appearance_get_out_params.p_appearance = p_appearance;
+
+ const uint32_t err_code = ble_gap_appearance_get_req_enc(p_appearance,
+ &(p_buffer[1]),
+ &buffer_length);
+ //@note: Should never fail.
+ APP_ERROR_CHECK(err_code);
+
+ //@note: Increment buffer length as internally managed packet type field must be included.
+ return ser_sd_transport_cmd_write(p_buffer,
+ (++buffer_length),
+ gap_appearance_get_rsp_dec);
+}
+
+
+/**@brief Command response callback function for @ref sd_ble_gap_device_name_set BLE command.
+ *
+ * Callback for decoding the command response return code.
+ *
+ * @param[in] p_buffer Pointer to begin of command response buffer.
+ * @param[in] length Length of data in bytes.
+ *
+ * @return Decoded command response return code.
+ */
+static uint32_t gap_device_name_set_rsp_dec(const uint8_t * p_buffer, uint16_t length)
+{
+ uint32_t result_code;
+
+ const uint32_t err_code = ble_gap_device_name_set_rsp_dec(p_buffer, length, &result_code);
+
+ APP_ERROR_CHECK(err_code);
+
+ return result_code;
+}
+
+#ifndef _sd_ble_gap_device_name_set
+#define _sd_ble_gap_device_name_set sd_ble_gap_device_name_set
+#endif
+uint32_t _sd_ble_gap_device_name_set(ble_gap_conn_sec_mode_t const * const p_write_perm,
+ uint8_t const * const p_dev_name,
+ uint16_t len)
+{
+ uint8_t * p_buffer;
+ uint32_t buffer_length = 0;
+
+ tx_buf_alloc(&p_buffer, (uint16_t *)&buffer_length);
+ const uint32_t err_code = ble_gap_device_name_set_req_enc(p_write_perm,
+ p_dev_name,
+ len,
+ &(p_buffer[1]),
+ &buffer_length);
+ //@note: Should never fail.
+ APP_ERROR_CHECK(err_code);
+
+ //@note: Increment buffer length as internally managed packet type field must be included.
+ return ser_sd_transport_cmd_write(p_buffer,
+ (++buffer_length),
+ gap_device_name_set_rsp_dec);
+}
+
+
+/**@brief Command response callback function for @ref sd_ble_gap_appearance_set BLE command.
+ *
+ * Callback for decoding the command response return code.
+ *
+ * @param[in] p_buffer Pointer to begin of command response buffer.
+ * @param[in] length Length of data in bytes.
+ *
+ * @return Decoded command response return code.
+ */
+static uint32_t gap_appearance_set_rsp_dec(const uint8_t * p_buffer, uint16_t length)
+{
+ uint32_t result_code;
+
+ const uint32_t err_code = ble_gap_appearance_set_rsp_dec(p_buffer, length, &result_code);
+
+ APP_ERROR_CHECK(err_code);
+
+ return result_code;
+}
+
+#ifndef _sd_ble_gap_appearance_set
+#define _sd_ble_gap_appearance_set sd_ble_gap_appearance_set
+#endif
+uint32_t _sd_ble_gap_appearance_set(uint16_t appearance)
+{
+ uint8_t * p_buffer;
+ uint32_t buffer_length = 0;
+
+ tx_buf_alloc(&p_buffer, (uint16_t *)&buffer_length);
+ const uint32_t err_code = ble_gap_appearance_set_req_enc(appearance,
+ &(p_buffer[1]),
+ &buffer_length);
+ //@note: Should never fail.
+ APP_ERROR_CHECK(err_code);
+
+ //@note: Increment buffer length as internally managed packet type field must be included.
+ return ser_sd_transport_cmd_write(p_buffer,
+ (++buffer_length),
+ gap_appearance_set_rsp_dec);
+}
+
+
+/**@brief Command response callback function for @ref sd_ble_gap_ppcp_set BLE command.
+ *
+ * Callback for decoding the command response return code.
+ *
+ * @param[in] p_buffer Pointer to begin of command response buffer.
+ * @param[in] length Length of data in bytes.
+ *
+ * @return Decoded command response return code.
+ */
+static uint32_t gap_ppcp_set_rsp_dec(const uint8_t * p_buffer, uint16_t length)
+{
+ uint32_t result_code;
+
+ const uint32_t err_code = ble_gap_ppcp_set_rsp_dec(p_buffer, length, &result_code);
+
+ APP_ERROR_CHECK(err_code);
+
+
+ return result_code;
+}
+
+#ifndef _sd_ble_gap_ppcp_set
+#define _sd_ble_gap_ppcp_set sd_ble_gap_ppcp_set
+#endif
+uint32_t _sd_ble_gap_ppcp_set(ble_gap_conn_params_t const * const p_conn_params)
+{
+ uint8_t * p_buffer;
+ uint32_t buffer_length = 0;
+
+ tx_buf_alloc(&p_buffer, (uint16_t *)&buffer_length);
+ const uint32_t err_code = ble_gap_ppcp_set_req_enc(p_conn_params,
+ &(p_buffer[1]),
+ &buffer_length);
+ //@note: Should never fail.
+ APP_ERROR_CHECK(err_code);
+
+ //@note: Increment buffer length as internally managed packet type field must be included.
+ return ser_sd_transport_cmd_write(p_buffer,
+ (++buffer_length),
+ gap_ppcp_set_rsp_dec);
+}
+
+
+/**@brief Command response callback function for @ref sd_ble_gap_adv_data_set BLE command.
+ *
+ * Callback for decoding the command response return code.
+ *
+ * @param[in] p_buffer Pointer to begin of command response buffer.
+ * @param[in] length Length of data in bytes.
+ *
+ * @return Decoded command response return code.
+ */
+#if NRF_SD_BLE_API_VERSION <= 5
+static uint32_t gap_adv_data_set_rsp_dec(const uint8_t * p_buffer, uint16_t length)
+{
+ uint32_t result_code;
+
+ const uint32_t err_code = ble_gap_adv_data_set_rsp_dec(p_buffer, length, &result_code);
+
+ APP_ERROR_CHECK(err_code);
+
+ return result_code;
+}
+#ifndef _sd_ble_gap_adv_data_set
+#define _sd_ble_gap_adv_data_set sd_ble_gap_adv_data_set
+#endif
+uint32_t _sd_ble_gap_adv_data_set(uint8_t const * const p_data,
+ uint8_t dlen,
+ uint8_t const * const p_sr_data,
+ uint8_t srdlen)
+{
+ uint8_t * p_buffer;
+ uint32_t buffer_length = 0;
+
+ tx_buf_alloc(&p_buffer, (uint16_t *)&buffer_length);
+ const uint32_t err_code = ble_gap_adv_data_set_req_enc(p_data,
+ dlen,
+ p_sr_data,
+ srdlen,
+ &(p_buffer[1]),
+ &buffer_length);
+ APP_ERROR_CHECK(err_code);
+
+ //@note: Increment buffer length as internally managed packet type field must be included.
+ return ser_sd_transport_cmd_write(p_buffer,
+ (++buffer_length),
+ gap_adv_data_set_rsp_dec);
+}
+#endif
+
+/**@brief Command response callback function for @ref sd_ble_gap_conn_param_update BLE command.
+ *
+ * Callback for decoding the command response return code.
+ *
+ * @param[in] p_buffer Pointer to begin of command response buffer.
+ * @param[in] length Length of data in bytes.
+ *
+ * @return Decoded command response return code.
+ */
+static uint32_t gap_conn_param_update_rsp_dec(const uint8_t * p_buffer, uint16_t length)
+{
+ uint32_t result_code;
+
+ const uint32_t err_code = ble_gap_conn_param_update_rsp_dec(p_buffer, length, &result_code);
+
+ APP_ERROR_CHECK(err_code);
+
+ return result_code;
+}
+
+#ifndef _sd_ble_gap_conn_param_update
+#define _sd_ble_gap_conn_param_update sd_ble_gap_conn_param_update
+#endif
+uint32_t _sd_ble_gap_conn_param_update(uint16_t conn_handle,
+ ble_gap_conn_params_t const * const p_conn_params)
+{
+ uint8_t * p_buffer;
+ uint32_t buffer_length = 0;
+
+ tx_buf_alloc(&p_buffer, (uint16_t *)&buffer_length);
+ const uint32_t err_code = ble_gap_conn_param_update_req_enc(conn_handle,
+ p_conn_params,
+ &(p_buffer[1]),
+ &buffer_length);
+ APP_ERROR_CHECK(err_code);
+
+ //@note: Increment buffer length as internally managed packet type field must be included.
+ return ser_sd_transport_cmd_write(p_buffer,
+ (++buffer_length),
+ gap_conn_param_update_rsp_dec);
+}
+
+
+/**@brief Command response callback function for @ref sd_ble_gap_disconnect BLE command.
+ *
+ * Callback for decoding the command response return code.
+ *
+ * @param[in] p_buffer Pointer to begin of command response buffer.
+ * @param[in] length Length of data in bytes.
+ *
+ * @return Decoded command response return code.
+ */
+static uint32_t gap_disconnect_rsp_dec(const uint8_t * p_buffer, uint16_t length)
+{
+ uint32_t result_code;
+
+ const uint32_t err_code = ble_gap_disconnect_rsp_dec(p_buffer, length, &result_code);
+
+ APP_ERROR_CHECK(err_code);
+
+ return result_code;
+}
+
+#ifndef _sd_ble_gap_disconnect
+#define _sd_ble_gap_disconnect sd_ble_gap_disconnect
+#endif
+uint32_t _sd_ble_gap_disconnect(uint16_t conn_handle, uint8_t hci_status_code)
+{
+ uint8_t * p_buffer;
+ uint32_t buffer_length = 0;
+
+ tx_buf_alloc(&p_buffer, (uint16_t *)&buffer_length);
+ const uint32_t err_code = ble_gap_disconnect_req_enc(conn_handle,
+ hci_status_code,
+ &(p_buffer[1]),
+ &buffer_length);
+ //@note: Should never fail.
+ APP_ERROR_CHECK(err_code);
+
+ //@note: Increment buffer length as internally managed packet type field must be included.
+ return ser_sd_transport_cmd_write(p_buffer,
+ (++buffer_length),
+ gap_disconnect_rsp_dec);
+}
+
+
+/**@brief Command response callback function for @ref sd_ble_gap_sec_info_reply BLE command.
+ *
+ * Callback for decoding the command response return code.
+ *
+ * @param[in] p_buffer Pointer to begin of command response buffer.
+ * @param[in] length Length of data in bytes.
+ *
+ * @return Decoded command response return code.
+ */
+static uint32_t gap_sec_info_reply_rsp_dec(const uint8_t * p_buffer, uint16_t length)
+{
+ uint32_t result_code;
+
+ const uint32_t err_code = ble_gap_sec_info_reply_rsp_dec(p_buffer, length, &result_code);
+
+ APP_ERROR_CHECK(err_code);
+
+ return result_code;
+}
+
+#ifndef _sd_ble_gap_sec_info_reply
+#define _sd_ble_gap_sec_info_reply sd_ble_gap_sec_info_reply
+#endif
+uint32_t _sd_ble_gap_sec_info_reply(uint16_t conn_handle,
+ ble_gap_enc_info_t const * p_enc_info,
+ ble_gap_irk_t const * p_id_info,
+ ble_gap_sign_info_t const * p_sign_info)
+{
+ uint8_t * p_buffer;
+ uint32_t buffer_length = 0;
+
+ tx_buf_alloc(&p_buffer, (uint16_t *)&buffer_length);
+ const uint32_t err_code = ble_gap_sec_info_reply_req_enc(conn_handle,
+ p_enc_info,
+ p_id_info,
+ p_sign_info,
+ &(p_buffer[1]),
+ &buffer_length);
+ APP_ERROR_CHECK(err_code);
+
+ //@note: Increment buffer length as internally managed packet type field must be included.
+ return ser_sd_transport_cmd_write(p_buffer,
+ (++buffer_length),
+ gap_sec_info_reply_rsp_dec);
+}
+
+
+/**@brief Command response callback function for @ref sd_ble_gap_sec_params_reply BLE command.
+ *
+ * Callback for decoding the command response return code.
+ *
+ * @param[in] p_buffer Pointer to begin of command response buffer.
+ * @param[in] length Length of data in bytes.
+ *
+ * @return Decoded command response return code.
+ */
+static uint32_t gap_sec_params_reply_rsp_dec(const uint8_t * p_buffer, uint16_t length)
+{
+ uint32_t result_code = 0;
+
+ uint32_t err_code = ble_gap_sec_params_reply_rsp_dec(p_buffer, length,
+ m_output_params.gap_sec_params_reply_out_params.p_sec_keyset, &result_code);
+ APP_ERROR_CHECK(err_code);
+
+ // If soft device returned error free security context
+ if (result_code)
+ {
+ err_code = app_ble_gap_sec_context_destroy(m_output_params.gap_sec_params_reply_out_params.conn_handle);
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code);
+ }
+
+ return result_code;
+}
+
+#ifndef _sd_ble_gap_sec_params_reply
+#define _sd_ble_gap_sec_params_reply sd_ble_gap_sec_params_reply
+#endif
+uint32_t _sd_ble_gap_sec_params_reply(uint16_t conn_handle,
+ uint8_t sec_status,
+ ble_gap_sec_params_t const * p_sec_params,
+ ble_gap_sec_keyset_t const * p_sec_keyset)
+{
+ uint8_t * p_buffer;
+ uint32_t buffer_length = 0;
+ uint32_t sec_tab_index = 0;
+ uint32_t err_code = NRF_SUCCESS;
+
+ tx_buf_alloc(&p_buffer, (uint16_t *)&buffer_length);
+ m_output_params.gap_sec_params_reply_out_params.p_sec_keyset = p_sec_keyset;
+ m_output_params.gap_sec_params_reply_out_params.conn_handle = conn_handle;
+
+ // First allocate security context for serialization
+ if (p_sec_keyset)
+ {
+ err_code = app_ble_gap_sec_context_create(conn_handle, &sec_tab_index);
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code);
+ memcpy(&(m_app_keys_table[sec_tab_index].keyset), p_sec_keyset, sizeof(ble_gap_sec_keyset_t));
+ }
+
+ err_code = ble_gap_sec_params_reply_req_enc(conn_handle,
+ sec_status,
+ p_sec_params,
+ p_sec_keyset,
+ &(p_buffer[1]),
+ &buffer_length);
+ APP_ERROR_CHECK(err_code);
+
+ //@note: Increment buffer length as internally managed packet type field must be included.
+ return ser_sd_transport_cmd_write(p_buffer,
+ (++buffer_length),
+ gap_sec_params_reply_rsp_dec);
+}
+
+
+/**@brief Command response callback function for @ref sd_ble_gap_ppcp_get BLE command.
+ *
+ * Callback for decoding the output parameters and the command response return code.
+ *
+ * @param[in] p_buffer Pointer to begin of command response buffer.
+ * @param[in] length Length of data in bytes.
+ *
+ * @return Decoded command response return code.
+ */
+static uint32_t gap_ppcp_get_reply_rsp_dec(const uint8_t * p_buffer, uint16_t length)
+{
+ uint32_t result_code = 0;
+
+ const uint32_t err_code = ble_gap_ppcp_get_rsp_dec(
+ p_buffer,
+ length,
+ m_output_params.gap_ppcp_get_out_params.
+ p_conn_params,
+ &result_code);
+
+ //@note: Should never fail.
+ APP_ERROR_CHECK(err_code);
+
+ return result_code;
+}
+
+#ifndef _sd_ble_gap_ppcp_get
+#define _sd_ble_gap_ppcp_get sd_ble_gap_ppcp_get
+#endif
+uint32_t _sd_ble_gap_ppcp_get(ble_gap_conn_params_t * const p_conn_params)
+{
+ uint8_t * p_buffer;
+ uint32_t buffer_length = 0;
+
+ tx_buf_alloc(&p_buffer, (uint16_t *)&buffer_length);
+ m_output_params.gap_ppcp_get_out_params.p_conn_params = p_conn_params;
+
+ const uint32_t err_code = ble_gap_ppcp_get_req_enc(p_conn_params,
+ &(p_buffer[1]),
+ &buffer_length);
+ //@note: Should never fail.
+ APP_ERROR_CHECK(err_code);
+
+ //@note: Increment buffer length as internally managed packet type field must be included.
+ return ser_sd_transport_cmd_write(p_buffer,
+ (++buffer_length),
+ gap_ppcp_get_reply_rsp_dec);
+}
+
+
+/**@brief Command response callback function for @ref sd_ble_gap_adv_stop BLE command.
+ *
+ * Callback for decoding the output parameters and the command response return code.
+ *
+ * @param[in] p_buffer Pointer to begin of command response buffer.
+ * @param[in] length Length of data in bytes.
+ *
+ * @return Decoded command response return code.
+ */
+static uint32_t gap_adv_stop_rsp_dec(const uint8_t * p_buffer, uint16_t length)
+{
+ uint32_t result_code = 0;
+
+ const uint32_t err_code = ble_gap_adv_stop_rsp_dec(p_buffer,
+ length,
+ &result_code);
+
+ //@note: Should never fail.
+ APP_ERROR_CHECK(err_code);
+
+ return result_code;
+}
+
+#ifndef _sd_ble_gap_adv_stop
+#define _sd_ble_gap_adv_stop sd_ble_gap_adv_stop
+#endif
+uint32_t _sd_ble_gap_adv_stop(
+#if NRF_SD_BLE_API_VERSION > 5
+ uint8_t adv_handle
+#else
+ void
+#endif
+ )
+{
+ uint8_t * p_buffer;
+ uint32_t buffer_length = 0;
+
+ tx_buf_alloc(&p_buffer, (uint16_t *)&buffer_length);
+ const uint32_t err_code = ble_gap_adv_stop_req_enc(
+#if NRF_SD_BLE_API_VERSION > 5
+ adv_handle,
+#endif
+ &(p_buffer[1]),
+ &buffer_length);
+ //@note: Should never fail.
+ APP_ERROR_CHECK(err_code);
+
+ //@note: Increment buffer length as internally managed packet type field must be included.
+ return ser_sd_transport_cmd_write(p_buffer,
+ (++buffer_length),
+ gap_adv_stop_rsp_dec);
+}
+
+/**@brief Command response callback function for @ref sd_ble_gap_auth_key_reply BLE command.
+ *
+ * Callback for decoding the output parameters and the command response return code.
+ *
+ * @param[in] p_buffer Pointer to begin of command response buffer.
+ * @param[in] length Length of data in bytes.
+ *
+ * @return Decoded command response return code.
+ */
+static uint32_t gap_auth_key_reply_rsp_dec(const uint8_t * p_buffer, uint16_t length)
+{
+ uint32_t result_code = 0;
+
+ const uint32_t err_code = ble_gap_auth_key_reply_rsp_dec(p_buffer,
+ length,
+ &result_code);
+
+ //@note: Should never fail.
+ APP_ERROR_CHECK(err_code);
+
+
+
+ return result_code;
+}
+
+
+#ifndef _sd_ble_gap_auth_key_reply
+#define _sd_ble_gap_auth_key_reply sd_ble_gap_auth_key_reply
+#endif
+uint32_t _sd_ble_gap_auth_key_reply(uint16_t conn_handle,
+ uint8_t key_type,
+ uint8_t const * const key)
+{
+ uint8_t * p_buffer;
+ uint32_t buffer_length = 0;
+
+ tx_buf_alloc(&p_buffer, (uint16_t *)&buffer_length);
+ const uint32_t err_code = ble_gap_auth_key_reply_req_enc(conn_handle, key_type, key,
+ &(p_buffer[1]), &buffer_length);
+ //@note: Should never fail.
+ APP_ERROR_CHECK(err_code);
+
+ //@note: Increment buffer length as internally managed packet type field must be included.
+ return ser_sd_transport_cmd_write(p_buffer,
+ (++buffer_length),
+ gap_auth_key_reply_rsp_dec);
+}
+
+/**@brief Command response callback function for @ref sd_ble_gap_authenticate BLE command.
+ *
+ * Callback for decoding the output parameters and the command response return code.
+ *
+ * @param[in] p_buffer Pointer to begin of command response buffer.
+ * @param[in] length Length of data in bytes.
+ *
+ * @return Decoded command response return code.
+ */
+static uint32_t gap_authenticate_rsp_dec(const uint8_t * p_buffer, uint16_t length)
+{
+ uint32_t result_code = 0;
+
+ const uint32_t err_code = ble_gap_authenticate_rsp_dec(p_buffer,
+ length,
+ &result_code);
+
+ //@note: Should never fail.
+ APP_ERROR_CHECK(err_code);
+
+
+
+ return result_code;
+}
+
+#ifndef _sd_ble_gap_authenticate
+#define _sd_ble_gap_authenticate sd_ble_gap_authenticate
+#endif
+uint32_t _sd_ble_gap_authenticate(uint16_t conn_handle,
+ ble_gap_sec_params_t const * const p_sec_params)
+{
+ uint8_t * p_buffer;
+ uint32_t buffer_length = 0;
+
+ tx_buf_alloc(&p_buffer, (uint16_t *)&buffer_length);
+ const uint32_t err_code = ble_gap_authenticate_req_enc(conn_handle, p_sec_params,
+ &(p_buffer[1]), &buffer_length);
+ //@note: Should never fail.
+ APP_ERROR_CHECK(err_code);
+
+ //@note: Increment buffer length as internally managed packet type field must be included.
+ return ser_sd_transport_cmd_write(p_buffer,
+ (++buffer_length),
+ gap_authenticate_rsp_dec);
+}
+
+/**@brief Command response callback function for @ref sd_ble_gap_conn_sec_get BLE command.
+ *
+ * Callback for decoding the output parameters and the command response return code.
+ *
+ * @param[in] p_buffer Pointer to begin of command response buffer.
+ * @param[in] length Length of data in bytes.
+ *
+ * @return Decoded command response return code.
+ */
+static uint32_t gap_conn_sec_get_rsp_dec(const uint8_t * p_buffer, uint16_t length)
+{
+ uint32_t result_code = 0;
+
+ const uint32_t err_code = ble_gap_conn_sec_get_rsp_dec(
+ p_buffer,
+ length,
+ (ble_gap_conn_sec_t * *)&mp_out_params[0
+ ],
+ &result_code);
+
+ //@note: Should never fail.
+ APP_ERROR_CHECK(err_code);
+
+
+
+ return result_code;
+}
+
+#ifndef _sd_ble_gap_conn_sec_get
+#define _sd_ble_gap_conn_sec_get sd_ble_gap_conn_sec_get
+#endif
+uint32_t _sd_ble_gap_conn_sec_get(uint16_t conn_handle, ble_gap_conn_sec_t * const p_conn_sec)
+{
+ uint8_t * p_buffer;
+ uint32_t buffer_length = 0;
+
+ tx_buf_alloc(&p_buffer, (uint16_t *)&buffer_length);
+ mp_out_params[0] = p_conn_sec;
+
+ const uint32_t err_code = ble_gap_conn_sec_get_req_enc(conn_handle, p_conn_sec,
+ &(p_buffer[1]), &buffer_length);
+ //@note: Should never fail.
+ APP_ERROR_CHECK(err_code);
+
+ //@note: Increment buffer length as internally managed packet type field must be included.
+ return ser_sd_transport_cmd_write(p_buffer,
+ (++buffer_length),
+ gap_conn_sec_get_rsp_dec);
+}
+
+/**@brief Command response callback function for @ref sd_ble_gap_rssi_start BLE command.
+ *
+ * Callback for decoding the output parameters and the command response return code.
+ *
+ * @param[in] p_buffer Pointer to begin of command response buffer.
+ * @param[in] length Length of data in bytes.
+ *
+ * @return Decoded command response return code.
+ */
+static uint32_t gap_rssi_start_rsp_dec(const uint8_t * p_buffer, uint16_t length)
+{
+ uint32_t result_code = 0;
+
+ const uint32_t err_code = ble_gap_rssi_start_rsp_dec(p_buffer,
+ length,
+ &result_code);
+
+ //@note: Should never fail.
+ APP_ERROR_CHECK(err_code);
+
+
+
+ return result_code;
+}
+
+#ifndef _sd_ble_gap_rssi_start
+#define _sd_ble_gap_rssi_start sd_ble_gap_rssi_start
+#endif
+uint32_t _sd_ble_gap_rssi_start(uint16_t conn_handle, uint8_t threshold_dbm, uint8_t skip_count)
+{
+ uint8_t * p_buffer;
+ uint32_t buffer_length = 0;
+
+ tx_buf_alloc(&p_buffer, (uint16_t *)&buffer_length);
+ const uint32_t err_code = ble_gap_rssi_start_req_enc(conn_handle,
+ threshold_dbm,
+ skip_count,
+ &(p_buffer[1]), &buffer_length);
+ //@note: Should never fail.
+ APP_ERROR_CHECK(err_code);
+
+ //@note: Increment buffer length as internally managed packet type field must be included.
+ return ser_sd_transport_cmd_write(p_buffer,
+ (++buffer_length),
+ gap_rssi_start_rsp_dec);
+}
+
+/**@brief Command response callback function for @ref sd_ble_gap_rssi_stop BLE command.
+ *
+ * Callback for decoding the output parameters and the command response return code.
+ *
+ * @param[in] p_buffer Pointer to begin of command response buffer.
+ * @param[in] length Length of data in bytes.
+ *
+ * @return Decoded command response return code.
+ */
+static uint32_t gap_rssi_stop_rsp_dec(const uint8_t * p_buffer, uint16_t length)
+{
+ uint32_t result_code = 0;
+
+ const uint32_t err_code = ble_gap_rssi_stop_rsp_dec(p_buffer,
+ length,
+ &result_code);
+
+ //@note: Should never fail.
+ APP_ERROR_CHECK(err_code);
+
+
+
+ return result_code;
+}
+
+#ifndef _sd_ble_gap_rssi_stop
+#define _sd_ble_gap_rssi_stop sd_ble_gap_rssi_stop
+#endif
+uint32_t _sd_ble_gap_rssi_stop(uint16_t conn_handle)
+{
+ uint8_t * p_buffer;
+ uint32_t buffer_length = 0;
+
+ tx_buf_alloc(&p_buffer, (uint16_t *)&buffer_length);
+ const uint32_t err_code = ble_gap_rssi_stop_req_enc(conn_handle,
+ &(p_buffer[1]), &buffer_length);
+ //@note: Should never fail.
+ APP_ERROR_CHECK(err_code);
+
+ //@note: Increment buffer length as internally managed packet type field must be included.
+ return ser_sd_transport_cmd_write(p_buffer,
+ (++buffer_length),
+ gap_rssi_stop_rsp_dec);
+}
+
+/**@brief Command response callback function for @ref sd_ble_gap_tx_power_set BLE command.
+ *
+ * Callback for decoding the output parameters and the command response return code.
+ *
+ * @param[in] p_buffer Pointer to begin of command response buffer.
+ * @param[in] length Length of data in bytes.
+ *
+ * @return Decoded command response return code.
+ */
+static uint32_t gap_tx_power_set_rsp_dec(const uint8_t * p_buffer, uint16_t length)
+{
+ uint32_t result_code = 0;
+
+ const uint32_t err_code = ble_gap_tx_power_set_rsp_dec(p_buffer,
+ length,
+ &result_code);
+
+ //@note: Should never fail.
+ APP_ERROR_CHECK(err_code);
+
+
+
+ return result_code;
+}
+
+#ifndef _sd_ble_gap_tx_power_set
+#define _sd_ble_gap_tx_power_set sd_ble_gap_tx_power_set
+#endif
+uint32_t _sd_ble_gap_tx_power_set(
+#if NRF_SD_BLE_API_VERSION > 5
+ uint8_t role, uint16_t handle,
+#endif
+ int8_t tx_power)
+{
+ uint8_t * p_buffer;
+ uint32_t buffer_length = 0;
+
+ tx_buf_alloc(&p_buffer, (uint16_t *)&buffer_length);
+#if NRF_SD_BLE_API_VERSION > 5
+ const uint32_t err_code = ble_gap_tx_power_set_req_enc(role, handle, tx_power,
+ &(p_buffer[1]), &buffer_length);
+#else
+ const uint32_t err_code = ble_gap_tx_power_set_req_enc(tx_power,
+ &(p_buffer[1]), &buffer_length);
+#endif
+ //@note: Should never fail.
+ APP_ERROR_CHECK(err_code);
+
+ //@note: Increment buffer length as internally managed packet type field must be included.
+ return ser_sd_transport_cmd_write(p_buffer,
+ (++buffer_length),
+ gap_tx_power_set_rsp_dec);
+}
+
+#ifndef S112
+/**@brief Command response callback function for @ref sd_ble_gap_scan_stop BLE command.
+ *
+ * Callback for decoding the output parameters and the command response return code.
+ *
+ * @param[in] p_buffer Pointer to begin of command response buffer.
+ * @param[in] length Length of data in bytes.
+ *
+ * @return Decoded command response return code.
+ */
+static uint32_t gap_scan_stop_rsp_dec(const uint8_t * p_buffer, uint16_t length)
+{
+ uint32_t result_code = 0;
+
+ const uint32_t err_code = ble_gap_scan_stop_rsp_dec(p_buffer,
+ length,
+ &result_code);
+
+ //@note: Should never fail.
+ APP_ERROR_CHECK(err_code);
+
+
+
+ return result_code;
+}
+
+#ifndef _sd_ble_gap_scan_stop
+#define _sd_ble_gap_scan_stop sd_ble_gap_scan_stop
+#endif
+uint32_t _sd_ble_gap_scan_stop(void)
+{
+ uint8_t * p_buffer;
+ uint32_t buffer_length = 0;
+
+ tx_buf_alloc(&p_buffer, (uint16_t *)&buffer_length);
+ const uint32_t err_code = ble_gap_scan_stop_req_enc(&(p_buffer[1]),
+ &buffer_length);
+ //@note: Should never fail.
+ APP_ERROR_CHECK(err_code);
+
+ //@note: Increment buffer length as internally managed packet type field must be included.
+ return ser_sd_transport_cmd_write(p_buffer,
+ (++buffer_length),
+ gap_scan_stop_rsp_dec);
+}
+
+/**@brief Command response callback function for @ref sd_ble_gap_connect BLE command.
+ *
+ * Callback for decoding the output parameters and the command response return code.
+ *
+ * @param[in] p_buffer Pointer to begin of command response buffer.
+ * @param[in] length Length of data in bytes.
+ *
+ * @return Decoded command response return code.
+ */
+static uint32_t gap_connect_rsp_dec(const uint8_t * p_buffer, uint16_t length)
+{
+ uint32_t result_code = 0;
+
+ const uint32_t err_code = ble_gap_connect_rsp_dec(p_buffer,
+ length,
+ &result_code);
+
+ //@note: Should never fail.
+ APP_ERROR_CHECK(err_code);
+
+
+
+ return result_code;
+}
+
+#ifndef _sd_ble_gap_connect
+#define _sd_ble_gap_connect sd_ble_gap_connect
+#endif
+uint32_t _sd_ble_gap_connect(ble_gap_addr_t const * const p_addr,
+ ble_gap_scan_params_t const * const p_scan_params,
+ ble_gap_conn_params_t const * const p_conn_params
+#if NRF_SD_BLE_API_VERSION >= 4
+ ,uint8_t conn_cfg_tag
+#endif
+ )
+{
+ uint8_t * p_buffer;
+ uint32_t buffer_length = 0;
+
+ tx_buf_alloc(&p_buffer, (uint16_t *)&buffer_length);
+ const uint32_t err_code = ble_gap_connect_req_enc(p_addr,
+ p_scan_params,
+ p_conn_params,
+#if NRF_SD_BLE_API_VERSION >= 4
+ conn_cfg_tag,
+#endif
+ &(p_buffer[1]),
+ &buffer_length);
+ //@note: Should never fail.
+ APP_ERROR_CHECK(err_code);
+
+ //@note: Increment buffer length as internally managed packet type field must be included.
+ return ser_sd_transport_cmd_write(p_buffer,
+ (++buffer_length),
+ gap_connect_rsp_dec);
+}
+
+/**@brief Command response callback function for @ref sd_ble_gap_connect_cancel BLE command.
+ *
+ * Callback for decoding the output parameters and the command response return code.
+ *
+ * @param[in] p_buffer Pointer to begin of command response buffer.
+ * @param[in] length Length of data in bytes.
+ *
+ * @return Decoded command response return code.
+ */
+static uint32_t gap_connect_cancel_rsp_dec(const uint8_t * p_buffer, uint16_t length)
+{
+ uint32_t result_code = 0;
+
+ const uint32_t err_code = ble_gap_connect_cancel_rsp_dec(p_buffer,
+ length,
+ &result_code);
+
+ //@note: Should never fail.
+ APP_ERROR_CHECK(err_code);
+
+
+
+ return result_code;
+}
+
+#ifndef _sd_ble_gap_connect_cancel
+#define _sd_ble_gap_connect_cancel sd_ble_gap_connect_cancel
+#endif
+uint32_t _sd_ble_gap_connect_cancel(void)
+{
+ uint8_t * p_buffer;
+ uint32_t buffer_length = 0;
+
+ tx_buf_alloc(&p_buffer, (uint16_t *)&buffer_length);
+ const uint32_t err_code = ble_gap_connect_cancel_req_enc(&(p_buffer[1]),
+ &buffer_length);
+ //@note: Should never fail.
+ APP_ERROR_CHECK(err_code);
+
+ //@note: Increment buffer length as internally managed packet type field must be included.
+ return ser_sd_transport_cmd_write(p_buffer,
+ (++buffer_length),
+ gap_connect_cancel_rsp_dec);
+}
+
+/**@brief Command response callback function for @ref sd_ble_gap_scan_start BLE command.
+ *
+ * Callback for decoding the output parameters and the command response return code.
+ *
+ * @param[in] p_buffer Pointer to begin of command response buffer.
+ * @param[in] length Length of data in bytes.
+ *
+ * @return Decoded command response return code.
+ */
+static uint32_t gap_scan_start_rsp_dec(const uint8_t * p_buffer, uint16_t length)
+{
+ uint32_t result_code = 0;
+
+ const uint32_t err_code = ble_gap_scan_start_rsp_dec(p_buffer,
+ length,
+ &result_code);
+
+ //@note: Should never fail.
+ APP_ERROR_CHECK(err_code);
+
+ return result_code;
+}
+
+#ifndef _sd_ble_gap_scan_start
+#define _sd_ble_gap_scan_start sd_ble_gap_scan_start
+#endif
+uint32_t _sd_ble_gap_scan_start(ble_gap_scan_params_t const * const p_scan_params
+#if defined(NRF_SD_BLE_API_VERSION) && NRF_SD_BLE_API_VERSION > 5
+ ,ble_data_t const * p_adv_report_buffer
+#endif
+ )
+{
+ uint8_t * p_buffer;
+ uint32_t buffer_length = 0;
+ uint32_t err_code;
+
+ tx_buf_alloc(&p_buffer, (uint16_t *)&buffer_length);
+#if defined(NRF_SD_BLE_API_VERSION) && NRF_SD_BLE_API_VERSION > 5
+ if (p_adv_report_buffer)
+ {
+ err_code = app_ble_gap_scan_data_set(p_adv_report_buffer);
+ APP_ERROR_CHECK(err_code);
+ }
+#endif
+ err_code = ble_gap_scan_start_req_enc(p_scan_params,
+#if defined(NRF_SD_BLE_API_VERSION) && NRF_SD_BLE_API_VERSION > 5
+ p_adv_report_buffer,
+#endif
+ &(p_buffer[1]),
+ &buffer_length);
+ //@note: Should never fail.
+ APP_ERROR_CHECK(err_code);
+
+ //@note: Increment buffer length as internally managed packet type field must be included.
+ return ser_sd_transport_cmd_write(p_buffer,
+ (++buffer_length),
+ gap_scan_start_rsp_dec);
+}
+
+/**@brief Command response callback function for @ref sd_ble_gap_encrypt BLE command.
+ *
+ * Callback for decoding the output parameters and the command response return code.
+ *
+ * @param[in] p_buffer Pointer to begin of command response buffer.
+ * @param[in] length Length of data in bytes.
+ *
+ * @return Decoded command response return code.
+ */
+static uint32_t gap_encrypt_rsp_dec(const uint8_t * p_buffer, uint16_t length)
+{
+ uint32_t result_code = 0;
+
+ const uint32_t err_code = ble_gap_encrypt_rsp_dec(p_buffer,
+ length,
+ &result_code);
+
+ //@note: Should never fail.
+ APP_ERROR_CHECK(err_code);
+
+ return result_code;
+}
+
+#ifndef _sd_ble_gap_encrypt
+#define _sd_ble_gap_encrypt sd_ble_gap_encrypt
+#endif
+uint32_t _sd_ble_gap_encrypt( uint16_t conn_handle,
+ ble_gap_master_id_t const * p_master_id,
+ ble_gap_enc_info_t const * p_enc_info)
+{
+ uint8_t * p_buffer;
+ uint32_t buffer_length = 0;
+
+ tx_buf_alloc(&p_buffer, (uint16_t *)&buffer_length);
+ const uint32_t err_code = ble_gap_encrypt_req_enc( conn_handle, p_master_id, p_enc_info, &(p_buffer[1]), &buffer_length );
+ //@note: Should never fail.
+ APP_ERROR_CHECK(err_code);
+
+ //@note: Increment buffer length as internally managed packet type field must be included.
+ return ser_sd_transport_cmd_write(p_buffer,
+ (++buffer_length),
+ gap_encrypt_rsp_dec);
+}
+#endif //!S112
+
+/**@brief Command response callback function for @ref sd_ble_gap_rssi_get BLE command.
+ *
+ * Callback for decoding the output parameters and the command response return code.
+ *
+ * @param[in] p_buffer Pointer to begin of command response buffer.
+ * @param[in] length Length of data in bytes.
+ *
+ * @return Decoded command response return code.
+ */
+static uint32_t gap_rssi_get_rsp_dec(const uint8_t * p_buffer, uint16_t length)
+{
+ uint32_t result_code = 0;
+
+ const uint32_t err_code = ble_gap_rssi_get_rsp_dec(p_buffer,
+ length,
+ (int8_t *) mp_out_params[0],
+#if NRF_SD_BLE_API_VERSION > 5
+ (uint8_t *) mp_out_params[1],
+#endif
+ &result_code);
+
+ //@note: Should never fail.
+ APP_ERROR_CHECK(err_code);
+
+ return result_code;
+}
+
+#ifndef _sd_ble_gap_rssi_get
+#define _sd_ble_gap_rssi_get sd_ble_gap_rssi_get
+#endif
+uint32_t _sd_ble_gap_rssi_get(uint16_t conn_handle,
+ int8_t * p_rssi
+#if NRF_SD_BLE_API_VERSION > 5
+ ,uint8_t * p_ch_index
+#endif
+)
+{
+ uint8_t * p_buffer;
+ uint32_t buffer_length = 0;
+
+ tx_buf_alloc(&p_buffer, (uint16_t *)&buffer_length);
+ mp_out_params[0] = p_rssi;
+
+#if NRF_SD_BLE_API_VERSION > 5
+ mp_out_params[1] = p_ch_index;
+ const uint32_t err_code = ble_gap_rssi_get_req_enc(conn_handle, p_rssi, p_ch_index, &(p_buffer[1]), &buffer_length);
+#else
+ const uint32_t err_code = ble_gap_rssi_get_req_enc(conn_handle, p_rssi, &(p_buffer[1]), &buffer_length);
+#endif
+ //@note: Should never fail.
+ APP_ERROR_CHECK(err_code);
+
+ //@note: Increment buffer length as internally managed packet type field must be included.
+ return ser_sd_transport_cmd_write(p_buffer,
+ (++buffer_length),
+ gap_rssi_get_rsp_dec);
+}
+
+/**@brief Command response callback function for @ref sd_ble_gap_keypress_notify BLE command.
+ *
+ * Callback for decoding the output parameters and the command response return code.
+ *
+ * @param[in] p_buffer Pointer to begin of command response buffer.
+ * @param[in] length Length of data in bytes.
+ *
+ * @return Decoded command response return code.
+ */
+static uint32_t gap_keypress_notify_rsp_dec(const uint8_t * p_buffer, uint16_t length)
+{
+ uint32_t result_code = 0;
+
+ const uint32_t err_code = ble_gap_keypress_notify_rsp_dec(p_buffer,
+ length,
+ &result_code);
+
+ //@note: Should never fail.
+ APP_ERROR_CHECK(err_code);
+
+ return result_code;
+}
+
+#ifndef _sd_ble_gap_keypress_notify
+#define _sd_ble_gap_keypress_notify sd_ble_gap_keypress_notify
+#endif
+uint32_t _sd_ble_gap_keypress_notify( uint16_t conn_handle, uint8_t kp_not)
+{
+ uint8_t * p_buffer;
+ uint32_t buffer_length = 0;
+
+ tx_buf_alloc(&p_buffer, (uint16_t *)&buffer_length);
+ const uint32_t err_code = ble_gap_keypress_notify_req_enc( conn_handle, kp_not, &p_buffer[1], &buffer_length );
+ //@note: Should never fail.
+ APP_ERROR_CHECK(err_code);
+
+ //@note: Increment buffer length as internally managed packet type field must be included.
+ return ser_sd_transport_cmd_write(p_buffer,
+ (++buffer_length),
+ gap_keypress_notify_rsp_dec);
+}
+
+/**@brief Command response callback function for @ref sd_ble_gap_lesc_dhkey_reply BLE command.
+ *
+ * Callback for decoding the output parameters and the command response return code.
+ *
+ * @param[in] p_buffer Pointer to begin of command response buffer.
+ * @param[in] length Length of data in bytes.
+ *
+ * @return Decoded command response return code.
+ */
+static uint32_t gap_lesc_dhkey_reply_rsp_dec(const uint8_t * p_buffer, uint16_t length)
+{
+ uint32_t result_code = 0;
+
+ const uint32_t err_code = ble_gap_lesc_dhkey_reply_rsp_dec(p_buffer,
+ length,
+ &result_code);
+
+ //@note: Should never fail.
+ APP_ERROR_CHECK(err_code);
+
+ return result_code;
+}
+
+#ifndef _sd_ble_gap_lesc_dhkey_reply
+#define _sd_ble_gap_lesc_dhkey_reply sd_ble_gap_lesc_dhkey_reply
+#endif
+uint32_t _sd_ble_gap_lesc_dhkey_reply( uint16_t conn_handle, ble_gap_lesc_dhkey_t const *p_dhkey)
+{
+ uint8_t * p_buffer;
+ uint32_t buffer_length = 0;
+
+ tx_buf_alloc(&p_buffer, (uint16_t *)&buffer_length);
+ const uint32_t err_code = ble_gap_lesc_dhkey_reply_req_enc( conn_handle, p_dhkey, &(p_buffer[1]), &buffer_length );
+ //@note: Should never fail.
+ APP_ERROR_CHECK(err_code);
+
+ //@note: Increment buffer length as internally managed packet type field must be included.
+ return ser_sd_transport_cmd_write(p_buffer,
+ (++buffer_length),
+ gap_lesc_dhkey_reply_rsp_dec);
+}
+
+/**@brief Command response callback function for @ref sd_ble_gap_lesc_oob_data_set BLE command.
+ *
+ * Callback for decoding the output parameters and the command response return code.
+ *
+ * @param[in] p_buffer Pointer to begin of command response buffer.
+ * @param[in] length Length of data in bytes.
+ *
+ * @return Decoded command response return code.
+ */
+static uint32_t gap_lesc_oob_data_set_rsp_dec(const uint8_t * p_buffer, uint16_t length)
+{
+ uint32_t result_code = 0;
+
+ const uint32_t err_code = ble_gap_lesc_oob_data_set_rsp_dec(p_buffer,
+ length,
+ &result_code);
+
+ //@note: Should never fail.
+ APP_ERROR_CHECK(err_code);
+
+ return result_code;
+}
+
+#ifndef _sd_ble_gap_lesc_oob_data_set
+#define _sd_ble_gap_lesc_oob_data_set sd_ble_gap_lesc_oob_data_set
+#endif
+uint32_t _sd_ble_gap_lesc_oob_data_set(uint16_t conn_handle,
+ ble_gap_lesc_oob_data_t const *p_oobd_own,
+ ble_gap_lesc_oob_data_t const *p_oobd_peer)
+{
+ uint8_t * p_buffer;
+ uint32_t buffer_length = 0;
+
+ tx_buf_alloc(&p_buffer, (uint16_t *)&buffer_length);
+ const uint32_t err_code = ble_gap_lesc_oob_data_set_req_enc(conn_handle, p_oobd_own, p_oobd_peer,
+ &(p_buffer[1]), &buffer_length );
+ //@note: Should never fail.
+ APP_ERROR_CHECK(err_code);
+
+ //@note: Increment buffer length as internally managed packet type field must be included.
+ return ser_sd_transport_cmd_write(p_buffer,
+ (++buffer_length),
+ gap_lesc_oob_data_set_rsp_dec);
+}
+
+/**@brief Command response callback function for @ref sd_ble_gap_lesc_oob_data_get BLE command.
+ *
+ * Callback for decoding the output parameters and the command response return code.
+ *
+ * @param[in] p_buffer Pointer to begin of command response buffer.
+ * @param[in] length Length of data in bytes.
+ *
+ * @return Decoded command response return code.
+ */
+static uint32_t gap_lesc_oob_data_get_rsp_dec(const uint8_t * p_buffer, uint16_t length)
+{
+ uint32_t result_code = 0;
+
+ const uint32_t err_code = ble_gap_lesc_oob_data_get_rsp_dec(p_buffer,
+ length,
+ (ble_gap_lesc_oob_data_t **) &mp_out_params[0],
+ &result_code);
+
+ //@note: Should never fail.
+ APP_ERROR_CHECK(err_code);
+
+ return result_code;
+}
+
+#ifndef _sd_ble_gap_lesc_oob_data_get
+#define _sd_ble_gap_lesc_oob_data_get sd_ble_gap_lesc_oob_data_get
+#endif
+uint32_t _sd_ble_gap_lesc_oob_data_get(uint16_t conn_handle,
+ ble_gap_lesc_p256_pk_t const *p_pk_own,
+ ble_gap_lesc_oob_data_t *p_oobd_own)
+{
+ uint8_t * p_buffer;
+ uint32_t buffer_length = 0;
+
+ tx_buf_alloc(&p_buffer, (uint16_t *)&buffer_length);
+ mp_out_params[0] = p_oobd_own;
+ const uint32_t err_code = ble_gap_lesc_oob_data_get_req_enc(conn_handle, p_pk_own, p_oobd_own,
+ &(p_buffer[1]), &buffer_length );
+ //@note: Should never fail.
+ APP_ERROR_CHECK(err_code);
+
+ //@note: Increment buffer length as internally managed packet type field must be included.
+ return ser_sd_transport_cmd_write(p_buffer,
+ (++buffer_length),
+ gap_lesc_oob_data_get_rsp_dec);
+}
+
+/**@brief Command response callback function for @ref sd_ble_gap_addr_get BLE command.
+ *
+ * Callback for decoding the output parameters and the command response return code.
+ *
+ * @param[in] p_buffer Pointer to begin of command response buffer.
+ * @param[in] length Length of data in bytes.
+ *
+ * @return Decoded command response return code.
+ */
+static uint32_t gap_addr_get_rsp_dec(const uint8_t * p_buffer, uint16_t length)
+{
+ uint32_t result_code = 0;
+
+ const uint32_t err_code = ble_gap_addr_get_rsp_dec(p_buffer,
+ length,
+ (ble_gap_addr_t *)mp_out_params[0],
+ &result_code);
+
+ //@note: Should never fail.
+ APP_ERROR_CHECK(err_code);
+ return result_code;
+}
+
+#ifndef _sd_ble_gap_addr_get
+#define _sd_ble_gap_addr_get sd_ble_gap_addr_get
+#endif
+uint32_t _sd_ble_gap_addr_get(ble_gap_addr_t * const p_addr)
+{
+ uint8_t * p_buffer;
+ uint32_t buffer_length = 0;
+
+ tx_buf_alloc(&p_buffer, (uint16_t *)&buffer_length);
+ mp_out_params[0] = p_addr;
+
+ const uint32_t err_code = ble_gap_addr_get_req_enc(p_addr,
+ &(p_buffer[1]),
+ &buffer_length);
+ //@note: Should never fail.
+ APP_ERROR_CHECK(err_code);
+
+ //@note: Increment buffer length as internally managed packet type field must be included.
+ return ser_sd_transport_cmd_write(p_buffer,
+ (++buffer_length),
+ gap_addr_get_rsp_dec);
+}
+
+/**@brief Command response callback function for @ref sd_ble_gap_addr_set BLE command.
+ *
+ * Callback for decoding the output parameters and the command response return code.
+ *
+ * @param[in] p_buffer Pointer to begin of command response buffer.
+ * @param[in] length Length of data in bytes.
+ *
+ * @return Decoded command response return code.
+ */
+static uint32_t gap_addr_set_rsp_dec(const uint8_t * p_buffer, uint16_t length)
+{
+ uint32_t result_code = 0;
+
+ const uint32_t err_code = ble_gap_addr_set_rsp_dec(p_buffer,
+ length,
+ &result_code);
+
+ //@note: Should never fail.
+ APP_ERROR_CHECK(err_code);
+ return result_code;
+}
+
+#ifndef _sd_ble_gap_addr_set
+#define _sd_ble_gap_addr_set sd_ble_gap_addr_set
+#endif
+uint32_t _sd_ble_gap_addr_set(ble_gap_addr_t const * const p_addr)
+{
+ uint8_t * p_buffer;
+ uint32_t buffer_length = 0;
+
+ tx_buf_alloc(&p_buffer, (uint16_t *)&buffer_length);
+ const uint32_t err_code = ble_gap_addr_set_req_enc(p_addr,
+ &(p_buffer[1]),
+ &buffer_length);
+ //@note: Should never fail.
+ APP_ERROR_CHECK(err_code);
+
+ //@note: Increment buffer length as internally managed packet type field must be included.
+ return ser_sd_transport_cmd_write(p_buffer,
+ (++buffer_length),
+ gap_addr_set_rsp_dec);
+}
+
+/**@brief Command response callback function for @ref sd_ble_gap_privacy_set BLE command.
+ *
+ * Callback for decoding the output parameters and the command response return code.
+ *
+ * @param[in] p_buffer Pointer to begin of command response buffer.
+ * @param[in] length Length of data in bytes.
+ *
+ * @return Decoded command response return code.
+ */
+static uint32_t gap_privacy_set_rsp_dec(const uint8_t * p_buffer, uint16_t length)
+{
+ uint32_t result_code = 0;
+
+ const uint32_t err_code = ble_gap_privacy_set_rsp_dec(p_buffer,
+ length,
+ &result_code);
+
+ //@note: Should never fail.
+ APP_ERROR_CHECK(err_code);
+ return result_code;
+}
+
+#ifndef _sd_ble_gap_privacy_set
+#define _sd_ble_gap_privacy_set sd_ble_gap_privacy_set
+#endif
+uint32_t _sd_ble_gap_privacy_set(ble_gap_privacy_params_t const *p_privacy_params)
+{
+ uint8_t * p_buffer;
+ uint32_t buffer_length = 0;
+
+ tx_buf_alloc(&p_buffer, (uint16_t *)&buffer_length);
+
+ const uint32_t err_code = ble_gap_privacy_set_req_enc(p_privacy_params,
+ &(p_buffer[1]), &buffer_length);
+ //@note: Should never fail.
+ APP_ERROR_CHECK(err_code);
+
+ //@note: Increment buffer length as internally managed packet type field must be included.
+ return ser_sd_transport_cmd_write(p_buffer,
+ (++buffer_length),
+ gap_privacy_set_rsp_dec);
+}
+
+/**@brief Command response callback function for @ref sd_ble_gap_privacy_get BLE command.
+ *
+ * Callback for decoding the output parameters and the command response return code.
+ *
+ * @param[in] p_buffer Pointer to begin of command response buffer.
+ * @param[in] length Length of data in bytes.
+ *
+ * @return Decoded command response return code.
+ */
+static uint32_t gap_privacy_get_rsp_dec(const uint8_t * p_buffer, uint16_t length)
+{
+ uint32_t result_code = 0;
+
+ const uint32_t err_code = ble_gap_privacy_get_rsp_dec(p_buffer,
+ length,
+ (ble_gap_privacy_params_t *)mp_out_params[0],
+ &result_code);
+
+ //@note: Should never fail.
+ APP_ERROR_CHECK(err_code);
+ return result_code;
+}
+
+#ifndef _sd_ble_gap_privacy_get
+#define _sd_ble_gap_privacy_get sd_ble_gap_privacy_get
+#endif
+uint32_t _sd_ble_gap_privacy_get(ble_gap_privacy_params_t *p_privacy_params)
+{
+ uint8_t * p_buffer;
+ uint32_t buffer_length = 0;
+
+ tx_buf_alloc(&p_buffer, (uint16_t *)&buffer_length);
+ mp_out_params[0] = p_privacy_params;
+
+ const uint32_t err_code = ble_gap_privacy_get_req_enc(p_privacy_params,
+ &(p_buffer[1]), &buffer_length);
+ //@note: Should never fail.
+ APP_ERROR_CHECK(err_code);
+
+ //@note: Increment buffer length as internally managed packet type field must be included.
+ return ser_sd_transport_cmd_write(p_buffer,
+ (++buffer_length),
+ gap_privacy_get_rsp_dec);
+}
+
+/**@brief Command response callback function for @ref sd_ble_gap_whitelist_set BLE command.
+ *
+ * Callback for decoding the output parameters and the command response return code.
+ *
+ * @param[in] p_buffer Pointer to begin of command response buffer.
+ * @param[in] length Length of data in bytes.
+ *
+ * @return Decoded command response return code.
+ */
+static uint32_t gap_whitelist_set_rsp_dec(const uint8_t * p_buffer, uint16_t length)
+{
+ uint32_t result_code = 0;
+
+ const uint32_t err_code = ble_gap_whitelist_set_rsp_dec(p_buffer,
+ length,
+ &result_code);
+
+ //@note: Should never fail.
+ APP_ERROR_CHECK(err_code);
+ return result_code;
+}
+
+#ifndef _sd_ble_gap_whitelist_set
+#define _sd_ble_gap_whitelist_set sd_ble_gap_whitelist_set
+#endif
+uint32_t _sd_ble_gap_whitelist_set(ble_gap_addr_t const * const * pp_wl_addrs, uint8_t len)
+{
+ uint8_t * p_buffer;
+ uint32_t buffer_length = 0;
+
+ tx_buf_alloc(&p_buffer, (uint16_t *)&buffer_length);
+
+ const uint32_t err_code = ble_gap_whitelist_set_req_enc(pp_wl_addrs, len,
+ &(p_buffer[1]), &buffer_length);
+ //@note: Should never fail.
+ APP_ERROR_CHECK(err_code);
+
+ //@note: Increment buffer length as internally managed packet type field must be included.
+ return ser_sd_transport_cmd_write(p_buffer,
+ (++buffer_length),
+ gap_whitelist_set_rsp_dec);
+}
+
+/**@brief Command response callback function for @ref sd_ble_gap_device_identities_set BLE command.
+ *
+ * Callback for decoding the output parameters and the command response return code.
+ *
+ * @param[in] p_buffer Pointer to begin of command response buffer.
+ * @param[in] length Length of data in bytes.
+ *
+ * @return Decoded command response return code.
+ */
+static uint32_t gap_device_identities_set_rsp_dec(const uint8_t * p_buffer, uint16_t length)
+{
+ uint32_t result_code = 0;
+
+ const uint32_t err_code = ble_gap_device_identities_set_rsp_dec(p_buffer,
+ length,
+ &result_code);
+
+ //@note: Should never fail.
+ APP_ERROR_CHECK(err_code);
+ return result_code;
+}
+
+#ifndef _sd_ble_gap_device_identities_set
+#define _sd_ble_gap_device_identities_set sd_ble_gap_device_identities_set
+#endif
+uint32_t _sd_ble_gap_device_identities_set(ble_gap_id_key_t const * const * pp_id_keys, ble_gap_irk_t const * const * pp_local_irks, uint8_t len)
+{
+ uint8_t * p_buffer;
+ uint32_t buffer_length = 0;
+
+ tx_buf_alloc(&p_buffer, (uint16_t *)&buffer_length);
+
+ const uint32_t err_code = ble_gap_device_identities_set_req_enc(pp_id_keys,
+ pp_local_irks,
+ len,
+ &(p_buffer[1]), &buffer_length);
+ //@note: Should never fail.
+ APP_ERROR_CHECK(err_code);
+
+ //@note: Increment buffer length as internally managed packet type field must be included.
+ return ser_sd_transport_cmd_write(p_buffer,
+ (++buffer_length),
+ gap_device_identities_set_rsp_dec);
+}
+
+#if NRF_SD_BLE_API_VERSION >= 4 && !defined(S112)
+/**@brief Command response callback function for @ref sd_ble_gap_data_length_update BLE command.
+ *
+ * Callback for decoding the output parameters and the command response return code.
+ *
+ * @param[in] p_buffer Pointer to begin of command response buffer.
+ * @param[in] length Length of data in bytes.
+ *
+ * @return Decoded command response return code.
+ */
+static uint32_t gap_data_length_update_rsp_dec(const uint8_t * p_buffer, uint16_t length)
+{
+ uint32_t result_code = 0;
+
+ const uint32_t err_code = ble_gap_data_length_update_rsp_dec(p_buffer,
+ length,
+ (ble_gap_data_length_limitation_t *)mp_out_params[0],
+ &result_code);
+
+ //@note: Should never fail.
+ APP_ERROR_CHECK(err_code);
+ return result_code;
+}
+
+#ifndef _sd_ble_gap_data_length_update
+#define _sd_ble_gap_data_length_update sd_ble_gap_data_length_update
+#endif
+uint32_t _sd_ble_gap_data_length_update(uint16_t conn_handle,
+ ble_gap_data_length_params_t const *p_dl_params,
+ ble_gap_data_length_limitation_t *p_dl_limitation)
+{
+ uint8_t * p_buffer;
+ uint32_t buffer_length = 0;
+ tx_buf_alloc(&p_buffer, (uint16_t *)&buffer_length);
+ mp_out_params[0] = p_dl_limitation;
+
+ const uint32_t err_code = ble_gap_data_length_update_req_enc(conn_handle, p_dl_params,p_dl_limitation,
+ &(p_buffer[1]), &buffer_length);
+ //@note: Should never fail.
+ APP_ERROR_CHECK(err_code);
+
+ //@note: Increment buffer length as internally managed packet type field must be included.
+ return ser_sd_transport_cmd_write(p_buffer,
+ (++buffer_length),
+ gap_data_length_update_rsp_dec);
+}
+
+#endif // NRF_SD_BLE_API_VERSION >= 4 && !defined(S112)
+
+#if NRF_SD_BLE_API_VERSION >= 5
+/**@brief Command response callback function for @ref sd_ble_gap_phy_update BLE command.
+ *
+ * Callback for decoding the output parameters and the command response return code.
+ *
+ * @param[in] p_buffer Pointer to begin of command response buffer.
+ * @param[in] length Length of data in bytes.
+ *
+ * @return Decoded command response return code.
+ */
+static uint32_t gap_phy_update_rsp_dec(const uint8_t * p_buffer, uint16_t length)
+{
+ uint32_t result_code = 0;
+
+ const uint32_t err_code = ble_gap_phy_update_rsp_dec(p_buffer,
+ length,
+ &result_code);
+
+ //@note: Should never fail.
+ APP_ERROR_CHECK(err_code);
+
+
+
+ return result_code;
+}
+
+#ifndef _sd_ble_gap_phy_update
+#define _sd_ble_gap_phy_update sd_ble_gap_phy_update
+#endif
+uint32_t _sd_ble_gap_phy_update(uint16_t conn_handle,
+ ble_gap_phys_t const * const p_gap_phys)
+{
+ uint8_t * p_buffer;
+ uint32_t buffer_length = 0;
+
+ tx_buf_alloc(&p_buffer, (uint16_t *)&buffer_length);
+ const uint32_t err_code = ble_gap_phy_update_req_enc(conn_handle, p_gap_phys,
+ &(p_buffer[1]), &buffer_length);
+ //@note: Should never fail.
+ APP_ERROR_CHECK(err_code);
+
+ //@note: Increment buffer length as internally managed packet type field must be included.
+ return ser_sd_transport_cmd_write(p_buffer,
+ (++buffer_length),
+ gap_phy_update_rsp_dec);
+}
+#endif
+
+#if NRF_SD_BLE_API_VERSION >= 6
+/**@brief Command response callback function for @ref sd_ble_gap_adv_set_configure BLE command.
+ *
+ * Callback for decoding the output parameters and the command response return code.
+ *
+ * @param[in] p_buffer Pointer to begin of command response buffer.
+ * @param[in] length Length of data in bytes.
+ *
+ * @return Decoded command response return code.
+ */
+static uint32_t gap_adv_set_configure_rsp_dec(const uint8_t * p_buffer, uint16_t length)
+{
+ uint32_t result_code = 0;
+
+ uint32_t err_code = ble_gap_adv_set_configure_rsp_dec(p_buffer,
+ length,
+ (uint8_t *)mp_out_params[0],
+ &result_code);
+
+ //@note: Should never fail.
+ APP_ERROR_CHECK(err_code);
+
+ err_code = app_ble_gap_adv_set_register(*(uint8_t *)mp_out_params[0],
+ (uint8_t *)mp_out_params[1],
+ (uint8_t *)mp_out_params[2]);
+ APP_ERROR_CHECK(err_code);
+
+ return result_code;
+}
+
+#ifndef _sd_ble_gap_adv_set_configure
+#define _sd_ble_gap_adv_set_configure sd_ble_gap_adv_set_configure
+#endif
+uint32_t _sd_ble_gap_adv_set_configure(uint8_t *p_adv_handle,
+ ble_gap_adv_data_t const *p_adv_data,
+ ble_gap_adv_params_t const *p_adv_params)
+{
+ uint8_t * p_buffer;
+ uint32_t buffer_length = 0;
+
+
+
+ tx_buf_alloc(&p_buffer, (uint16_t *)&buffer_length);
+
+ mp_out_params[0] = p_adv_handle;
+ mp_out_params[1] = p_adv_data ? p_adv_data->adv_data.p_data : NULL;
+ mp_out_params[2] = p_adv_data ? p_adv_data->scan_rsp_data.p_data : NULL;
+ const uint32_t err_code = ble_gap_adv_set_configure_req_enc(p_adv_handle, p_adv_data, p_adv_params,
+ &(p_buffer[1]), &buffer_length);
+ //@note: Should never fail.
+ APP_ERROR_CHECK(err_code);
+
+ //@note: Increment buffer length as internally managed packet type field must be included.
+ return ser_sd_transport_cmd_write(p_buffer,
+ (++buffer_length),
+ gap_adv_set_configure_rsp_dec);
+}
+
+#ifndef S112
+/**@brief Command response callback function for @ref sd_ble_gap_qos_channel_survey_start BLE command.
+ *
+ * Callback for decoding the output parameters and the command response return code.
+ *
+ * @param[in] p_buffer Pointer to begin of command response buffer.
+ * @param[in] length Length of data in bytes.
+ *
+ * @return Decoded command response return code.
+ */
+static uint32_t gap_qos_channel_survey_start_rsp_dec(const uint8_t * p_buffer, uint16_t length)
+{
+ uint32_t result_code = 0;
+
+ uint32_t err_code = ble_gap_qos_channel_survey_start_rsp_dec(p_buffer,
+ length,
+ &result_code);
+ //@note: Should never fail.
+ APP_ERROR_CHECK(err_code);
+
+ return result_code;
+}
+
+#ifndef _sd_ble_gap_qos_channel_survey_start
+#define _sd_ble_gap_qos_channel_survey_start sd_ble_gap_qos_channel_survey_start
+#endif
+uint32_t _sd_ble_gap_qos_channel_survey_start(uint32_t interval_us)
+{
+ uint8_t * p_buffer;
+ uint32_t buffer_length = 0;
+
+ tx_buf_alloc(&p_buffer, (uint16_t *)&buffer_length);
+
+ const uint32_t err_code = ble_gap_qos_channel_survey_start_req_enc(interval_us,
+ &(p_buffer[1]), &buffer_length);
+ //@note: Should never fail.
+ APP_ERROR_CHECK(err_code);
+
+ //@note: Increment buffer length as internally managed packet type field must be included.
+ return ser_sd_transport_cmd_write(p_buffer,
+ (++buffer_length),
+ gap_qos_channel_survey_start_rsp_dec);
+}
+
+/**@brief Command response callback function for @ref sd_ble_gap_qos_channel_survey_stop BLE command.
+ *
+ * Callback for decoding the output parameters and the command response return code.
+ *
+ * @param[in] p_buffer Pointer to begin of command response buffer.
+ * @param[in] length Length of data in bytes.
+ *
+ * @return Decoded command response return code.
+ */
+static uint32_t gap_qos_channel_survey_stop_rsp_dec(const uint8_t * p_buffer, uint16_t length)
+{
+ uint32_t result_code = 0;
+
+ uint32_t err_code = ble_gap_qos_channel_survey_stop_rsp_dec(p_buffer,
+ length,
+ &result_code);
+ //@note: Should never fail.
+ APP_ERROR_CHECK(err_code);
+
+ return result_code;
+}
+
+#ifndef _sd_ble_gap_qos_channel_survey_stop
+#define _sd_ble_gap_qos_channel_survey_stop sd_ble_gap_qos_channel_survey_stop
+#endif
+uint32_t _sd_ble_gap_qos_channel_survey_stop(void)
+{
+ uint8_t * p_buffer;
+ uint32_t buffer_length = 0;
+
+ tx_buf_alloc(&p_buffer, (uint16_t *)&buffer_length);
+
+ const uint32_t err_code = ble_gap_qos_channel_survey_stop_req_enc(&(p_buffer[1]), &buffer_length);
+ //@note: Should never fail.
+ APP_ERROR_CHECK(err_code);
+
+ //@note: Increment buffer length as internally managed packet type field must be included.
+ return ser_sd_transport_cmd_write(p_buffer,
+ (++buffer_length),
+ gap_qos_channel_survey_stop_rsp_dec);
+}
+#endif //!S112
+#endif
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/application/codecs/ble/middleware/app_mw_ble_gattc.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/application/codecs/ble/middleware/app_mw_ble_gattc.c
new file mode 100644
index 0000000..7edf6ee
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/application/codecs/ble/middleware/app_mw_ble_gattc.c
@@ -0,0 +1,566 @@
+/**
+ * Copyright (c) 2014 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#include <stdint.h>
+#include "ble_gattc.h"
+#include "ble_gattc_app.h"
+#include "ble_serialization.h"
+#include "ser_sd_transport.h"
+#include "app_error.h"
+
+static void tx_buf_alloc(uint8_t * * p_data, uint16_t * p_len)
+{
+ uint32_t err_code;
+
+ do
+ {
+ err_code = ser_sd_transport_tx_alloc(p_data, p_len);
+ }
+ while (err_code != NRF_SUCCESS);
+ *p_data[0] = SER_PKT_TYPE_CMD;
+ *p_len -= 1;
+}
+/**@brief Command response callback function for @ref sd_ble_gattc_primary_services_discover BLE command.
+ *
+ * Callback for decoding the command response return code.
+ *
+ * @param[in] p_buffer Pointer to begin of command response buffer.
+ * @param[in] length Length of data in bytes.
+ *
+ * @return Decoded command response return code.
+ */
+static uint32_t gattc_primary_services_discover_rsp_dec(const uint8_t * p_buffer, uint16_t length)
+{
+ uint32_t result_code;
+
+ const uint32_t err_code = ble_gattc_primary_services_discover_rsp_dec(p_buffer,
+ length,
+ &result_code);
+
+ APP_ERROR_CHECK(err_code);
+
+
+
+ return result_code;
+}
+
+#ifndef _sd_ble_gattc_primary_services_discover
+#define _sd_ble_gattc_primary_services_discover sd_ble_gattc_primary_services_discover
+#endif
+uint32_t _sd_ble_gattc_primary_services_discover(uint16_t conn_handle,
+ uint16_t start_handle,
+ ble_uuid_t const * const p_srvc_uuid)
+{
+ uint8_t * p_buffer;
+ uint32_t buffer_length = 0;
+
+ tx_buf_alloc(&p_buffer, (uint16_t *)&buffer_length);
+
+ const uint32_t err_code = ble_gattc_primary_services_discover_req_enc(conn_handle,
+ start_handle,
+ p_srvc_uuid,
+ &(p_buffer[1]),
+ &buffer_length);
+ APP_ERROR_CHECK(err_code);
+
+ //@note: Increment buffer length as internally managed packet type field must be included.
+ return ser_sd_transport_cmd_write(p_buffer,
+ (++buffer_length),
+ gattc_primary_services_discover_rsp_dec);
+}
+
+/**@brief Command response callback function for @ref sd_ble_gattc_relationships_discover BLE command.
+ *
+ * Callback for decoding the command response return code.
+ *
+ * @param[in] p_buffer Pointer to begin of command response buffer.
+ * @param[in] length Length of data in bytes.
+ *
+ * @return Decoded command response return code.
+ */
+static uint32_t gattc_relationships_discover_rsp_dec(const uint8_t * p_buffer, uint16_t length)
+{
+ uint32_t result_code;
+
+ const uint32_t err_code = ble_gattc_relationships_discover_rsp_dec(p_buffer,
+ length,
+ &result_code);
+
+ APP_ERROR_CHECK(err_code);
+
+
+
+ return result_code;
+}
+
+#ifndef _sd_ble_gattc_relationships_discover
+#define _sd_ble_gattc_relationships_discover sd_ble_gattc_relationships_discover
+#endif
+uint32_t _sd_ble_gattc_relationships_discover(uint16_t conn_handle,
+ ble_gattc_handle_range_t const * const p_handle_range)
+{
+ uint8_t * p_buffer;
+ uint32_t buffer_length = 0;
+
+ tx_buf_alloc(&p_buffer, (uint16_t *)&buffer_length);
+
+ const uint32_t err_code = ble_gattc_relationships_discover_req_enc(conn_handle,
+ p_handle_range,
+ &(p_buffer[1]),
+ &buffer_length);
+ APP_ERROR_CHECK(err_code);
+
+ //@note: Increment buffer length as internally managed packet type field must be included.
+ return ser_sd_transport_cmd_write(p_buffer,
+ (++buffer_length),
+ gattc_relationships_discover_rsp_dec);
+}
+
+/**@brief Command response callback function for @ref sd_ble_gattc_characteristics_discover BLE command.
+ *
+ * Callback for decoding the command response return code.
+ *
+ * @param[in] p_buffer Pointer to begin of command response buffer.
+ * @param[in] length Length of data in bytes.
+ *
+ * @return Decoded command response return code.
+ */
+static uint32_t gattc_characteristics_discover_rsp_dec(const uint8_t * p_buffer, uint16_t length)
+{
+ uint32_t result_code;
+
+ const uint32_t err_code = ble_gattc_characteristics_discover_rsp_dec(p_buffer,
+ length,
+ &result_code);
+
+ APP_ERROR_CHECK(err_code);
+
+
+
+ return result_code;
+}
+
+#ifndef _sd_ble_gattc_characteristics_discover
+#define _sd_ble_gattc_characteristics_discover sd_ble_gattc_characteristics_discover
+#endif
+uint32_t _sd_ble_gattc_characteristics_discover(
+ uint16_t conn_handle,
+ ble_gattc_handle_range_t const * const
+ p_handle_range)
+{
+ uint8_t * p_buffer;
+ uint32_t buffer_length = 0;
+
+ tx_buf_alloc(&p_buffer, (uint16_t *)&buffer_length);
+
+ const uint32_t err_code = ble_gattc_characteristics_discover_req_enc(conn_handle,
+ p_handle_range,
+ &(p_buffer[1]),
+ &buffer_length);
+ APP_ERROR_CHECK(err_code);
+
+ //@note: Increment buffer length as internally managed packet type field must be included.
+ return ser_sd_transport_cmd_write(p_buffer,
+ (++buffer_length),
+ gattc_characteristics_discover_rsp_dec);
+}
+
+/**@brief Command response callback function for @ref sd_ble_gattc_descriptors_discover BLE command.
+ *
+ * Callback for decoding the command response return code.
+ *
+ * @param[in] p_buffer Pointer to begin of command response buffer.
+ * @param[in] length Length of data in bytes.
+ *
+ * @return Decoded command response return code.
+ */
+static uint32_t gattc_descriptors_discover_rsp_dec(const uint8_t * p_buffer, uint16_t length)
+{
+ uint32_t result_code;
+
+ const uint32_t err_code = ble_gattc_descriptors_discover_rsp_dec(p_buffer, length, &result_code);
+
+ APP_ERROR_CHECK(err_code);
+
+
+
+ return result_code;
+}
+
+#ifndef _sd_ble_gattc_descriptors_discover
+#define _sd_ble_gattc_descriptors_discover sd_ble_gattc_descriptors_discover
+#endif
+uint32_t _sd_ble_gattc_descriptors_discover(uint16_t conn_handle,
+ ble_gattc_handle_range_t const * const p_handle_range)
+{
+ uint8_t * p_buffer;
+ uint32_t buffer_length = 0;
+
+ tx_buf_alloc(&p_buffer, (uint16_t *)&buffer_length);
+
+ const uint32_t err_code = ble_gattc_descriptors_discover_req_enc(conn_handle,
+ p_handle_range,
+ &(p_buffer[1]),
+ &buffer_length);
+ APP_ERROR_CHECK(err_code);
+
+ //@note: Increment buffer length as internally managed packet type field must be included.
+ return ser_sd_transport_cmd_write(p_buffer,
+ (++buffer_length),
+ gattc_descriptors_discover_rsp_dec);
+}
+
+/**@brief Command response callback function for @ref sd_ble_gattc_char_value_by_uuid_read BLE command.
+ *
+ * Callback for decoding the command response return code.
+ *
+ * @param[in] p_buffer Pointer to begin of command response buffer.
+ * @param[in] length Length of data in bytes.
+ *
+ * @return Decoded command response return code.
+ */
+static uint32_t gattc_char_value_by_uuid_read_rsp_dec(const uint8_t * p_buffer, uint16_t length)
+{
+ uint32_t result_code;
+
+ const uint32_t err_code = ble_gattc_char_value_by_uuid_read_rsp_dec(p_buffer,
+ length,
+ &result_code);
+
+ APP_ERROR_CHECK(err_code);
+
+
+
+ return result_code;
+}
+
+#ifndef _sd_ble_gattc_char_value_by_uuid_read
+#define _sd_ble_gattc_char_value_by_uuid_read sd_ble_gattc_char_value_by_uuid_read
+#endif
+uint32_t _sd_ble_gattc_char_value_by_uuid_read(uint16_t conn_handle,
+ ble_uuid_t const * const p_uuid,
+ ble_gattc_handle_range_t const * const p_handle_range)
+{
+ uint8_t * p_buffer;
+ uint32_t buffer_length = 0;
+
+ tx_buf_alloc(&p_buffer, (uint16_t *)&buffer_length);
+
+ const uint32_t err_code = ble_gattc_char_value_by_uuid_read_req_enc(conn_handle,
+ p_uuid,
+ p_handle_range,
+ &(p_buffer[1]),
+ &buffer_length);
+ APP_ERROR_CHECK(err_code);
+
+ //@note: Increment buffer length as internally managed packet type field must be included.
+ return ser_sd_transport_cmd_write(p_buffer,
+ (++buffer_length),
+ gattc_char_value_by_uuid_read_rsp_dec);
+}
+
+/**@brief Command response callback function for @ref sd_ble_gattc_read BLE command.
+ *
+ * Callback for decoding the command response return code.
+ *
+ * @param[in] p_buffer Pointer to begin of command response buffer.
+ * @param[in] length Length of data in bytes.
+ *
+ * @return Decoded command response return code.
+ */
+static uint32_t gattc_read_rsp_dec(const uint8_t * p_buffer, uint16_t length)
+{
+ uint32_t result_code;
+
+ const uint32_t err_code = ble_gattc_read_rsp_dec(p_buffer, length, &result_code);
+
+ APP_ERROR_CHECK(err_code);
+
+
+
+ return result_code;
+}
+
+#ifndef _sd_ble_gattc_read
+#define _sd_ble_gattc_read sd_ble_gattc_read
+#endif
+uint32_t _sd_ble_gattc_read(uint16_t conn_handle,
+ uint16_t handle,
+ uint16_t offset)
+{
+ uint8_t * p_buffer;
+ uint32_t buffer_length = 0;
+
+ tx_buf_alloc(&p_buffer, (uint16_t *)&buffer_length);
+
+ const uint32_t err_code = ble_gattc_read_req_enc(conn_handle,
+ handle,
+ offset,
+ &(p_buffer[1]),
+ &buffer_length);
+ APP_ERROR_CHECK(err_code);
+
+ //@note: Increment buffer length as internally managed packet type field must be included.
+ return ser_sd_transport_cmd_write(p_buffer,
+ (++buffer_length),
+ gattc_read_rsp_dec);
+}
+
+/**@brief Command response callback function for @ref sd_ble_gattc_char_values_read BLE command.
+ *
+ * Callback for decoding the command response return code.
+ *
+ * @param[in] p_buffer Pointer to begin of command response buffer.
+ * @param[in] length Length of data in bytes.
+ *
+ * @return Decoded command response return code.
+ */
+static uint32_t gattc_char_values_read_rsp_dec(const uint8_t * p_buffer, uint16_t length)
+{
+ uint32_t result_code;
+
+ const uint32_t err_code = ble_gattc_char_values_read_rsp_dec(p_buffer, length, &result_code);
+
+ APP_ERROR_CHECK(err_code);
+
+
+
+ return result_code;
+}
+
+#ifndef _sd_ble_gattc_char_values_read
+#define _sd_ble_gattc_char_values_read sd_ble_gattc_char_values_read
+#endif
+uint32_t _sd_ble_gattc_char_values_read(uint16_t conn_handle,
+ uint16_t const * const p_handles,
+ uint16_t handle_count)
+{
+ uint8_t * p_buffer;
+ uint32_t buffer_length = 0;
+
+ tx_buf_alloc(&p_buffer, (uint16_t *)&buffer_length);
+
+ const uint32_t err_code = ble_gattc_char_values_read_req_enc(conn_handle,
+ p_handles,
+ handle_count,
+ &(p_buffer[1]),
+ &buffer_length);
+ APP_ERROR_CHECK(err_code);
+
+ //@note: Increment buffer length as internally managed packet type field must be included.
+ return ser_sd_transport_cmd_write(p_buffer,
+ (++buffer_length),
+ gattc_char_values_read_rsp_dec);
+}
+
+/**@brief Command response callback function for @ref sd_ble_gattc_write BLE command.
+ *
+ * Callback for decoding the command response return code.
+ *
+ * @param[in] p_buffer Pointer to begin of command response buffer.
+ * @param[in] length Length of data in bytes.
+ *
+ * @return Decoded command response return code.
+ */
+static uint32_t gattc_write_rsp_dec(const uint8_t * p_buffer, uint16_t length)
+{
+ uint32_t result_code;
+
+ const uint32_t err_code = ble_gattc_write_rsp_dec(p_buffer, length, &result_code);
+
+ APP_ERROR_CHECK(err_code);
+
+
+
+ return result_code;
+}
+
+#ifndef _sd_ble_gattc_write
+#define _sd_ble_gattc_write sd_ble_gattc_write
+#endif
+uint32_t _sd_ble_gattc_write(uint16_t conn_handle,
+ ble_gattc_write_params_t const * const p_write_params)
+{
+ uint8_t * p_buffer;
+ uint32_t buffer_length = 0;
+
+ tx_buf_alloc(&p_buffer, (uint16_t *)&buffer_length);
+
+ const uint32_t err_code = ble_gattc_write_req_enc(conn_handle,
+ p_write_params,
+ &(p_buffer[1]),
+ &buffer_length);
+ APP_ERROR_CHECK(err_code);
+
+ //@note: Increment buffer length as internally managed packet type field must be included.
+ return ser_sd_transport_cmd_write(p_buffer,
+ (++buffer_length),
+ gattc_write_rsp_dec);
+}
+
+/**@brief Command response callback function for @ref sd_ble_gattc_hv_confirm BLE command.
+ *
+ * Callback for decoding the command response return code.
+ *
+ * @param[in] p_buffer Pointer to begin of command response buffer.
+ * @param[in] length Length of data in bytes.
+ *
+ * @return Decoded command response return code.
+ */
+static uint32_t gattc_hv_confirm_rsp_dec(const uint8_t * p_buffer, uint16_t length)
+{
+ uint32_t result_code;
+
+ const uint32_t err_code = ble_gattc_hv_confirm_rsp_dec(p_buffer, length, &result_code);
+
+ APP_ERROR_CHECK(err_code);
+
+
+
+ return result_code;
+}
+
+#ifndef _sd_ble_gattc_hv_confirm
+#define _sd_ble_gattc_hv_confirm sd_ble_gattc_hv_confirm
+#endif
+uint32_t _sd_ble_gattc_hv_confirm(uint16_t conn_handle,
+ uint16_t handle)
+{
+ uint8_t * p_buffer;
+ uint32_t buffer_length = 0;
+
+ tx_buf_alloc(&p_buffer, (uint16_t *)&buffer_length);
+
+ const uint32_t err_code = ble_gattc_hv_confirm_req_enc(conn_handle,
+ handle,
+ &(p_buffer[1]),
+ &buffer_length);
+ APP_ERROR_CHECK(err_code);
+
+ //@note: Increment buffer length as internally managed packet type field must be included.
+ return ser_sd_transport_cmd_write(p_buffer,
+ (++buffer_length),
+ gattc_hv_confirm_rsp_dec);
+}
+
+
+/**@brief Command response callback function for @ref sd_ble_gattc_info_discover BLE command.
+ *
+ * Callback for decoding the command response return code.
+ *
+ * @param[in] p_buffer Pointer to begin of command response buffer.
+ * @param[in] length Length of data in bytes.
+ *
+ * @return Decoded command response return code.
+ */
+static uint32_t gattc_attr_info_discover_rsp_dec(const uint8_t * p_buffer, uint16_t length)
+{
+ uint32_t result_code;
+
+ const uint32_t err_code = ble_gattc_attr_info_discover_rsp_dec(p_buffer, length, &result_code);
+
+ APP_ERROR_CHECK(err_code);
+
+ return result_code;
+}
+
+#ifndef _sd_ble_gattc_attr_info_discover
+#define _sd_ble_gattc_attr_info_discover sd_ble_gattc_attr_info_discover
+#endif
+uint32_t _sd_ble_gattc_attr_info_discover(uint16_t conn_handle,
+ ble_gattc_handle_range_t const * const p_handle_range)
+{
+ uint8_t * p_buffer;
+ uint32_t buffer_length = 0;
+
+ tx_buf_alloc(&p_buffer, (uint16_t *)&buffer_length);
+
+ const uint32_t err_code = ble_gattc_attr_info_discover_req_enc(conn_handle,
+ p_handle_range,
+ &(p_buffer[1]),
+ &buffer_length);
+ APP_ERROR_CHECK(err_code);
+
+ //@note: Increment buffer length as internally managed packet type field must be included.
+ return ser_sd_transport_cmd_write(p_buffer,
+ (++buffer_length),
+ gattc_attr_info_discover_rsp_dec);
+}
+
+/**@brief Command response callback function for @ref sd_ble_gattc_write BLE command.
+ *
+ * Callback for decoding the command response return code.
+ *
+ * @param[in] p_buffer Pointer to begin of command response buffer.
+ * @param[in] length Length of data in bytes.
+ *
+ * @return Decoded command response return code.
+ */
+static uint32_t gattc_exchange_mtu_request_rsp_dec(const uint8_t * p_buffer, uint16_t length)
+{
+ uint32_t result_code;
+
+ const uint32_t err_code = ble_gattc_exchange_mtu_request_rsp_dec(p_buffer, length, &result_code);
+
+ APP_ERROR_CHECK(err_code);
+ return result_code;
+}
+
+#ifndef _sd_ble_gattc_exchange_mtu_request
+#define _sd_ble_gattc_exchange_mtu_request sd_ble_gattc_exchange_mtu_request
+#endif
+uint32_t _sd_ble_gattc_exchange_mtu_request(uint16_t conn_handle,
+ uint16_t client_rx_mtu)
+{
+ uint8_t * p_buffer;
+ uint32_t buffer_length = 0;
+
+ tx_buf_alloc(&p_buffer, (uint16_t *)&buffer_length);
+
+ const uint32_t err_code = ble_gattc_exchange_mtu_request_req_enc(conn_handle,
+ client_rx_mtu,
+ &(p_buffer[1]),
+ &buffer_length);
+ APP_ERROR_CHECK(err_code);
+
+ //@note: Increment buffer length as internally managed packet type field must be included.
+ return ser_sd_transport_cmd_write(p_buffer,
+ (++buffer_length),
+ gattc_exchange_mtu_request_rsp_dec);
+}
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/application/codecs/ble/middleware/app_mw_ble_gatts.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/application/codecs/ble/middleware/app_mw_ble_gatts.c
new file mode 100644
index 0000000..e4b3002
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/application/codecs/ble/middleware/app_mw_ble_gatts.c
@@ -0,0 +1,773 @@
+/**
+ * Copyright (c) 2013 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#include "ble_gatts.h"
+#include <stdint.h>
+#include "ble_serialization.h"
+#include "ser_sd_transport.h"
+#include "ble_gatts_app.h"
+#include "app_error.h"
+
+
+//Pointer for sd calls output params
+static void * mp_out_params[3];
+
+static void tx_buf_alloc(uint8_t * * p_data, uint16_t * p_len)
+{
+ uint32_t err_code;
+
+ do
+ {
+ err_code = ser_sd_transport_tx_alloc(p_data, p_len);
+ }
+ while (err_code != NRF_SUCCESS);
+ *p_data[0] = SER_PKT_TYPE_CMD;
+ *p_len -= 1;
+}
+
+/**@brief Command response callback function for @ref sd_ble_gatts_sys_attr_set BLE command.
+ *
+ * Callback for decoding the command response return code.
+ *
+ * @param[in] p_buffer Pointer to begin of command response buffer.
+ * @param[in] length Length of data in bytes.
+ *
+ * @return Decoded command response return code.
+ */
+static uint32_t gatts_sys_attr_set_rsp_dec(const uint8_t * p_buffer, uint16_t length)
+{
+ uint32_t result_code;
+
+ const uint32_t err_code = ble_gatts_sys_attr_set_rsp_dec(p_buffer, length, &result_code);
+
+ APP_ERROR_CHECK(err_code);
+
+
+
+ return result_code;
+}
+
+#ifndef _sd_ble_gatts_sys_attr_set
+#define _sd_ble_gatts_sys_attr_set sd_ble_gatts_sys_attr_set
+#endif
+uint32_t _sd_ble_gatts_sys_attr_set(uint16_t conn_handle,
+ uint8_t const * const p_sys_attr_data,
+ uint16_t len,
+ uint32_t flags)
+{
+ uint8_t * p_buffer;
+ uint32_t buffer_length = 0;
+
+ tx_buf_alloc(&p_buffer, (uint16_t *)&buffer_length);
+ const uint32_t err_code = ble_gatts_sys_attr_set_req_enc(conn_handle,
+ p_sys_attr_data,
+ len,
+ flags,
+ &(p_buffer[1]),
+ &buffer_length);
+ APP_ERROR_CHECK(err_code);
+
+ //@note: Increment buffer length as internally managed packet type field must be included.
+ return ser_sd_transport_cmd_write(p_buffer,
+ (++buffer_length),
+ gatts_sys_attr_set_rsp_dec);
+}
+
+
+/**@brief Command response callback function for @ref sd_ble_gatts_hvx BLE command.
+ *
+ * Callback for decoding the command response return code.
+ *
+ * @param[in] p_buffer Pointer to begin of command response buffer.
+ * @param[in] length Length of data in bytes.
+ *
+ * @return Decoded command response return code.
+ */
+static uint32_t gatts_hvx_rsp_dec(const uint8_t * p_buffer, uint16_t length)
+{
+ uint32_t result_code;
+
+ const uint32_t err_code = ble_gatts_hvx_rsp_dec(p_buffer, length, &result_code,
+ (uint16_t * *)&mp_out_params[0]);
+
+ APP_ERROR_CHECK(err_code);
+
+ return result_code;
+}
+
+#ifndef _sd_ble_gatts_hvx
+#define _sd_ble_gatts_hvx sd_ble_gatts_hvx
+#endif
+uint32_t _sd_ble_gatts_hvx(uint16_t conn_handle, ble_gatts_hvx_params_t const * const p_hvx_params)
+{
+ uint8_t * p_buffer;
+ uint32_t buffer_length = 0;
+
+ tx_buf_alloc(&p_buffer, (uint16_t *)&buffer_length);
+ mp_out_params[0] = (p_hvx_params) ? p_hvx_params->p_len : NULL;
+
+ const uint32_t err_code = ble_gatts_hvx_req_enc(conn_handle,
+ p_hvx_params,
+ &(p_buffer[1]),
+ &buffer_length);
+ APP_ERROR_CHECK(err_code);
+
+ //@note: Increment buffer length as internally managed packet type field must be included.
+ return ser_sd_transport_cmd_write(p_buffer,
+ (++buffer_length),
+ gatts_hvx_rsp_dec);
+}
+
+
+/**@brief Command response callback function for @ref sd_ble_gatts_service_add BLE command.
+ *
+ * Callback for decoding the output parameters and the command response return code.
+ *
+ * @param[in] p_buffer Pointer to begin of command response buffer.
+ * @param[in] length Length of data in bytes.
+ *
+ * @return Decoded command response return code.
+ */
+static uint32_t gatts_service_add_rsp_dec(const uint8_t * p_buffer, uint16_t length)
+{
+ uint32_t result_code;
+
+ const uint32_t err_code =
+ ble_gatts_service_add_rsp_dec(p_buffer,
+ length,
+ (uint16_t *)mp_out_params[0],
+ &result_code);
+
+ APP_ERROR_CHECK(err_code);
+
+
+
+ return result_code;
+}
+
+#ifndef _sd_ble_gatts_service_add
+#define _sd_ble_gatts_service_add sd_ble_gatts_service_add
+#endif
+uint32_t _sd_ble_gatts_service_add(uint8_t type,
+ ble_uuid_t const * const p_uuid,
+ uint16_t * const p_handle)
+{
+ uint8_t * p_buffer;
+ uint32_t buffer_length = 0;
+
+ tx_buf_alloc(&p_buffer, (uint16_t *)&buffer_length);
+ mp_out_params[0] = p_handle;
+
+ const uint32_t err_code = ble_gatts_service_add_req_enc(type,
+ p_uuid,
+ p_handle,
+ &(p_buffer[1]),
+ &buffer_length);
+ APP_ERROR_CHECK(err_code);
+
+ //@note: Increment buffer length as internally managed packet type field must be included.
+ return ser_sd_transport_cmd_write(p_buffer,
+ (++buffer_length),
+ gatts_service_add_rsp_dec);
+}
+
+/**@brief Command response callback function for @ref sd_ble_gatts_service_add BLE command.
+ *
+ * Callback for decoding the output parameters and the command response return code.
+ *
+ * @param[in] p_buffer Pointer to begin of command response buffer.
+ * @param[in] length Length of data in bytes.
+ *
+ * @return Decoded command response return code.
+ */
+static uint32_t gatts_service_changed_rsp_dec(const uint8_t * p_buffer, uint16_t length)
+{
+ uint32_t result_code = NRF_SUCCESS;
+
+ const uint32_t err_code = ble_gatts_service_changed_rsp_dec(p_buffer,
+ length,
+ &result_code);
+
+ APP_ERROR_CHECK(err_code);
+
+
+
+ return result_code;
+}
+
+#ifndef _sd_ble_gatts_service_changed
+#define _sd_ble_gatts_service_changed sd_ble_gatts_service_changed
+#endif
+uint32_t _sd_ble_gatts_service_changed(uint16_t conn_handle,
+ uint16_t start_handle,
+ uint16_t end_handle)
+{
+ uint8_t * p_buffer;
+ uint32_t buffer_length = 0;
+
+ tx_buf_alloc(&p_buffer, (uint16_t *)&buffer_length);
+ const uint32_t err_code = ble_gatts_service_changed_req_enc(conn_handle,
+ start_handle,
+ end_handle,
+ &(p_buffer[1]),
+ &buffer_length);
+
+ APP_ERROR_CHECK(err_code);
+
+ //@note: Increment buffer length as internally managed packet type field must be included.
+ return ser_sd_transport_cmd_write(p_buffer,
+ (++buffer_length),
+ gatts_service_changed_rsp_dec);
+}
+
+/**@brief Command response callback function for @ref sd_ble_gatts_include_add BLE command.
+ *
+ * Callback for decoding the output parameters and the command response return code.
+ *
+ * @param[in] p_buffer Pointer to begin of command response buffer.
+ * @param[in] length Length of data in bytes.
+ *
+ * @return Decoded command response return code.
+ */
+static uint32_t gatts_include_add_rsp_dec(const uint8_t * p_buffer, uint16_t length)
+{
+ uint32_t result_code = NRF_SUCCESS;
+
+ const uint32_t err_code =
+ ble_gatts_include_add_rsp_dec(p_buffer,
+ length,
+ (uint16_t *) mp_out_params[0],
+ &result_code);
+
+ APP_ERROR_CHECK(err_code);
+
+
+
+ return result_code;
+}
+
+#ifndef _sd_ble_gatts_include_add
+#define _sd_ble_gatts_include_add sd_ble_gatts_include_add
+#endif
+uint32_t _sd_ble_gatts_include_add(uint16_t service_handle,
+ uint16_t inc_serv_handle,
+ uint16_t * const p_include_handle)
+{
+ uint8_t * p_buffer;
+ uint32_t buffer_length = 0;
+
+ tx_buf_alloc(&p_buffer, (uint16_t *)&buffer_length);
+ mp_out_params[0] = p_include_handle;
+
+ const uint32_t err_code = ble_gatts_include_add_req_enc(service_handle,
+ inc_serv_handle,
+ p_include_handle,
+ &(p_buffer[1]),
+ &buffer_length);
+
+ APP_ERROR_CHECK(err_code);
+
+ //@note: Increment buffer length as internally managed packet type field must be included.
+ return ser_sd_transport_cmd_write(p_buffer,
+ (++buffer_length),
+ gatts_include_add_rsp_dec);
+}
+
+/**@brief Command response callback function for @ref sd_ble_gatts_characteristic_add BLE command.
+ *
+ * Callback for decoding the output parameters and the command response return code.
+ *
+ * @param[in] p_buffer Pointer to begin of command response buffer.
+ * @param[in] length Length of data in bytes.
+ *
+ * @return Decoded command response return code.
+ */
+static uint32_t gatts_characteristic_add_rsp_dec(const uint8_t * p_buffer, uint16_t length)
+{
+ uint32_t result_code;
+
+ const uint32_t err_code = ble_gatts_characteristic_add_rsp_dec(
+ p_buffer,
+ length,
+ (uint16_t * *)&mp_out_params[0],
+ &result_code);
+
+ APP_ERROR_CHECK(err_code);
+
+ return result_code;
+}
+
+#ifndef _sd_ble_gatts_characteristic_add
+#define _sd_ble_gatts_characteristic_add sd_ble_gatts_characteristic_add
+#endif
+uint32_t _sd_ble_gatts_characteristic_add(uint16_t service_handle,
+ ble_gatts_char_md_t const * const p_char_md,
+ ble_gatts_attr_t const * const p_attr_char_value,
+ ble_gatts_char_handles_t * const p_handles)
+{
+ uint8_t * p_buffer;
+ uint32_t buffer_length = 0;
+
+ tx_buf_alloc(&p_buffer, (uint16_t *)&buffer_length);
+ mp_out_params[0] = p_handles;
+
+ const uint32_t err_code = ble_gatts_characteristic_add_req_enc(service_handle,
+ p_char_md,
+ p_attr_char_value,
+ p_handles,
+ &(p_buffer[1]),
+ &buffer_length);
+ APP_ERROR_CHECK(err_code);
+
+ //@note: Increment buffer length as internally managed packet type field must be included.
+ return ser_sd_transport_cmd_write(p_buffer,
+ (++buffer_length),
+ gatts_characteristic_add_rsp_dec);
+}
+
+/**@brief Command response callback function for @ref sd_ble_gatts_descriptor_add BLE command.
+ *
+ * Callback for decoding the output parameters and the command response return code.
+ *
+ * @param[in] p_buffer Pointer to begin of command response buffer.
+ * @param[in] length Length of data in bytes.
+ *
+ * @return Decoded command response return code.
+ */
+static uint32_t gatts_descriptor_add_rsp_dec(const uint8_t * p_buffer, uint16_t length)
+{
+ uint32_t result_code = NRF_SUCCESS;
+
+ const uint32_t err_code =
+ ble_gatts_descriptor_add_rsp_dec(p_buffer,
+ length,
+ (uint16_t *) mp_out_params[0],
+ &result_code);
+
+ APP_ERROR_CHECK(err_code);
+
+
+
+ return result_code;
+}
+
+#ifndef _sd_ble_gatts_descriptor_add
+#define _sd_ble_gatts_descriptor_add sd_ble_gatts_descriptor_add
+#endif
+uint32_t _sd_ble_gatts_descriptor_add(uint16_t char_handle,
+ ble_gatts_attr_t const * const p_attr,
+ uint16_t * const p_handle)
+{
+ uint8_t * p_buffer;
+ uint32_t buffer_length = 0;
+
+ tx_buf_alloc(&p_buffer, (uint16_t *)&buffer_length);
+ mp_out_params[0] = p_handle;
+
+ const uint32_t err_code = ble_gatts_descriptor_add_req_enc(char_handle,
+ p_attr,
+ p_handle,
+ &(p_buffer[1]),
+ &buffer_length);
+
+ APP_ERROR_CHECK(err_code);
+
+ //@note: Increment buffer length as internally managed packet type field must be included.
+ return ser_sd_transport_cmd_write(p_buffer,
+ (++buffer_length),
+ gatts_descriptor_add_rsp_dec);
+}
+
+/**@brief Command response callback function for @ref sd_ble_gatts_rw_authorize_reply BLE command.
+ *
+ * Callback for decoding the output parameters and the command response return code.
+ *
+ * @param[in] p_buffer Pointer to begin of command response buffer.
+ * @param[in] length Length of data in bytes.
+ *
+ * @return Decoded command response return code.
+ */
+static uint32_t gatts_rw_authorize_reply_rsp_dec(const uint8_t * p_buffer, uint16_t length)
+{
+ uint32_t result_code = NRF_SUCCESS;
+
+ const uint32_t err_code = ble_gatts_rw_authorize_reply_rsp_dec(p_buffer,
+ length,
+ &result_code);
+
+ APP_ERROR_CHECK(err_code);
+
+
+
+ return result_code;
+}
+
+#ifndef _sd_ble_gatts_rw_authorize_reply
+#define _sd_ble_gatts_rw_authorize_reply sd_ble_gatts_rw_authorize_reply
+#endif
+uint32_t _sd_ble_gatts_rw_authorize_reply(
+ uint16_t conn_handle,
+ ble_gatts_rw_authorize_reply_params_t const * const
+ p_rw_authorize_reply_params)
+{
+
+ uint8_t * p_buffer;
+ uint32_t buffer_length = 0;
+
+ tx_buf_alloc(&p_buffer, (uint16_t *)&buffer_length);
+
+ const uint32_t err_code = ble_gatts_rw_authorize_reply_req_enc(conn_handle,
+ p_rw_authorize_reply_params,
+ &(p_buffer[1]),
+ &buffer_length);
+
+ APP_ERROR_CHECK(err_code);
+
+ //@note: Increment buffer length as internally managed packet type field must be included.
+ return ser_sd_transport_cmd_write(p_buffer,
+ (++buffer_length),
+ gatts_rw_authorize_reply_rsp_dec);
+}
+
+/**@brief Command response callback function for @ref sd_ble_gatts_value_get BLE command.
+ *
+ * Callback for decoding the output parameters and the command response return code.
+ *
+ * @param[in] p_buffer Pointer to begin of command response buffer.
+ * @param[in] length Length of data in bytes.
+ *
+ * @return Decoded command response return code.
+ */
+static uint32_t gatts_value_get_rsp_dec(const uint8_t * p_buffer, uint16_t length)
+{
+ uint32_t result_code;
+
+ const uint32_t err_code = ble_gatts_value_get_rsp_dec(p_buffer,
+ length,
+ (ble_gatts_value_t *)mp_out_params[0],
+ &result_code);
+
+ APP_ERROR_CHECK(err_code);
+
+
+
+ return result_code;
+}
+
+#ifndef _sd_ble_gatts_value_get
+#define _sd_ble_gatts_value_get sd_ble_gatts_value_get
+#endif
+uint32_t _sd_ble_gatts_value_get(uint16_t conn_handle,
+ uint16_t handle,
+ ble_gatts_value_t * p_value)
+{
+ uint8_t * p_buffer;
+ uint32_t buffer_length = 0;
+
+ tx_buf_alloc(&p_buffer, (uint16_t *)&buffer_length);
+ mp_out_params[0] = p_value;
+
+ const uint32_t err_code = ble_gatts_value_get_req_enc(conn_handle,
+ handle,
+ p_value,
+ &(p_buffer[1]),
+ &buffer_length);
+
+ APP_ERROR_CHECK(err_code);
+
+ //@note: Increment buffer length as internally managed packet type field must be included.
+ return ser_sd_transport_cmd_write(p_buffer,
+ (++buffer_length),
+ gatts_value_get_rsp_dec);
+}
+
+/**@brief Command response callback function for @ref sd_ble_gatts_value_set BLE command.
+ *
+ * Callback for decoding the output parameters and the command response return code.
+ *
+ * @param[in] p_buffer Pointer to begin of command response buffer.
+ * @param[in] length Length of data in bytes.
+ *
+ * @return Decoded command response return code.
+ */
+static uint32_t gatts_value_set_rsp_dec(const uint8_t * p_buffer, uint16_t length)
+{
+ uint32_t result_code;
+
+ const uint32_t err_code = ble_gatts_value_set_rsp_dec(
+ p_buffer,
+ length,
+ (ble_gatts_value_t *)mp_out_params[0],
+ &result_code);
+
+ APP_ERROR_CHECK(err_code);
+
+ return result_code;
+}
+
+#ifndef _sd_ble_gatts_value_set
+#define _sd_ble_gatts_value_set sd_ble_gatts_value_set
+#endif
+uint32_t _sd_ble_gatts_value_set(uint16_t conn_handle,
+ uint16_t handle,
+ ble_gatts_value_t * p_value)
+{
+ uint8_t * p_buffer;
+ uint32_t buffer_length = 0;
+
+ tx_buf_alloc(&p_buffer, (uint16_t *)&buffer_length);
+ mp_out_params[0] = p_value;
+
+ const uint32_t err_code = ble_gatts_value_set_req_enc(conn_handle,
+ handle,
+ p_value,
+ &(p_buffer[1]),
+ &buffer_length);
+ //@note: Should never fail.
+ APP_ERROR_CHECK(err_code);
+
+ //@note: Increment buffer length as internally managed packet type field must be included.
+ return ser_sd_transport_cmd_write(p_buffer,
+ (++buffer_length),
+ gatts_value_set_rsp_dec);
+}
+
+
+/**@brief Command response callback function for @ref sd_ble_gatts_sys_attr_get BLE command.
+ *
+ * Callback for decoding the output parameters and the command response return code.
+ *
+ * @param[in] p_buffer Pointer to begin of command response buffer.
+ * @param[in] length Length of data in bytes.
+ *
+ * @return Decoded command response return code.
+ */
+static uint32_t gatts_sys_attr_get_rsp_dec(const uint8_t * p_buffer, uint16_t length)
+{
+ uint32_t result_code;
+
+ const uint32_t err_code = ble_gatts_sys_attr_get_rsp_dec(
+ p_buffer,
+ length,
+ (uint8_t * *) &mp_out_params[0],
+ (uint16_t * *) &mp_out_params[1],
+ &result_code);
+
+ APP_ERROR_CHECK(err_code);
+
+ return result_code;
+}
+
+#ifndef _sd_ble_gatts_sys_attr_get
+#define _sd_ble_gatts_sys_attr_get sd_ble_gatts_sys_attr_get
+#endif
+uint32_t _sd_ble_gatts_sys_attr_get(uint16_t conn_handle,
+ uint8_t * const p_sys_attr_data,
+ uint16_t * const p_len,
+ uint32_t flags)
+{
+ uint8_t * p_buffer;
+ uint32_t buffer_length = 0;
+
+ tx_buf_alloc(&p_buffer, (uint16_t *)&buffer_length);
+ mp_out_params[0] = p_sys_attr_data;
+ mp_out_params[1] = p_len;
+
+ const uint32_t err_code = ble_gatts_sys_attr_get_req_enc(conn_handle,
+ p_sys_attr_data,
+ p_len,
+ flags,
+ &(p_buffer[1]),
+ &buffer_length);
+ //@note: Should never fail.
+ APP_ERROR_CHECK(err_code);
+
+ //@note: Increment buffer length as internally managed packet type field must be included.
+ return ser_sd_transport_cmd_write(p_buffer,
+ (++buffer_length),
+ gatts_sys_attr_get_rsp_dec);
+}
+
+/**@brief Command response callback function for @ref sd_ble_gatts_attr_get BLE command.
+ *
+ * Callback for decoding the output parameters and the command response return code.
+ *
+ * @param[in] p_buffer Pointer to begin of command response buffer.
+ * @param[in] length Length of data in bytes.
+ *
+ * @return Decoded command response return code.
+ */
+static uint32_t gatts_attr_get_rsp_dec(const uint8_t * p_buffer, uint16_t length)
+{
+ uint32_t result_code;
+
+ const uint32_t err_code = ble_gatts_attr_get_rsp_dec(
+ p_buffer,
+ length,
+ (ble_uuid_t **)&mp_out_params[0],
+ (ble_gatts_attr_md_t **)&mp_out_params[1],
+ &result_code);
+
+ APP_ERROR_CHECK(err_code);
+
+ return result_code;
+}
+
+#ifndef _sd_ble_gatts_attr_get
+#define _sd_ble_gatts_attr_get sd_ble_gatts_attr_get
+#endif
+uint32_t _sd_ble_gatts_attr_get(uint16_t handle,
+ ble_uuid_t * p_uuid,
+ ble_gatts_attr_md_t * p_md)
+{
+ uint8_t * p_buffer;
+ uint32_t buffer_length = 0;
+
+ tx_buf_alloc(&p_buffer, (uint16_t *)&buffer_length);
+ mp_out_params[0] = p_uuid;
+ mp_out_params[1] = p_md;
+
+ const uint32_t err_code = ble_gatts_attr_get_req_enc(handle,
+ p_uuid,
+ p_md,
+ &(p_buffer[1]),
+ &buffer_length);
+ //@note: Should never fail.
+ APP_ERROR_CHECK(err_code);
+
+ //@note: Increment buffer length as internally managed packet type field must be included.
+ return ser_sd_transport_cmd_write(p_buffer,
+ (++buffer_length),
+ gatts_attr_get_rsp_dec);
+}
+
+/**@brief Command response callback function for @ref sd_ble_gatts_initial_user_handle_get BLE command.
+ *
+ * Callback for decoding the output parameters and the command response return code.
+ *
+ * @param[in] p_buffer Pointer to begin of command response buffer.
+ * @param[in] length Length of data in bytes.
+ *
+ * @return Decoded command response return code.
+ */
+static uint32_t gatts_initial_user_handle_get_rsp_dec(const uint8_t * p_buffer, uint16_t length)
+{
+ uint32_t result_code;
+
+ const uint32_t err_code = ble_gatts_initial_user_handle_get_rsp_dec(
+ p_buffer,
+ length,
+ (uint16_t **)&mp_out_params[0],
+ &result_code);
+
+ APP_ERROR_CHECK(err_code);
+
+ return result_code;
+}
+
+#ifndef _sd_ble_gatts_initial_user_handle_get
+#define _sd_ble_gatts_initial_user_handle_get sd_ble_gatts_initial_user_handle_get
+#endif
+uint32_t _sd_ble_gatts_initial_user_handle_get(uint16_t * p_handle)
+{
+ uint8_t * p_buffer;
+ uint32_t buffer_length = 0;
+
+ tx_buf_alloc(&p_buffer, (uint16_t *)&buffer_length);
+ mp_out_params[0] = p_handle;
+
+ const uint32_t err_code = ble_gatts_initial_user_handle_get_req_enc(p_handle,
+ &(p_buffer[1]),
+ &buffer_length);
+ //@note: Should never fail.
+ APP_ERROR_CHECK(err_code);
+
+ //@note: Increment buffer length as internally managed packet type field must be included.
+ return ser_sd_transport_cmd_write(p_buffer,
+ (++buffer_length),
+ gatts_initial_user_handle_get_rsp_dec);
+}
+
+/**@brief Command response callback function for @ref sd_ble_gatts_exchange_mtu_reply BLE command.
+ *
+ * Callback for decoding the output parameters and the command response return code.
+ *
+ * @param[in] p_buffer Pointer to begin of command response buffer.
+ * @param[in] length Length of data in bytes.
+ *
+ * @return Decoded command response return code.
+ */
+static uint32_t gatts_exchange_mtu_reply_rsp_dec(const uint8_t * p_buffer, uint16_t length)
+{
+ uint32_t result_code;
+
+ const uint32_t err_code = ble_gatts_exchange_mtu_reply_rsp_dec(
+ p_buffer,
+ length,
+ &result_code);
+
+ APP_ERROR_CHECK(err_code);
+
+ return result_code;
+}
+
+#ifndef _sd_ble_gatts_exchange_mtu_reply
+#define _sd_ble_gatts_exchange_mtu_reply sd_ble_gatts_exchange_mtu_reply
+#endif
+uint32_t _sd_ble_gatts_exchange_mtu_reply(uint16_t conn_handle, uint16_t server_rx_mtu)
+{
+
+
+ uint8_t * p_buffer;
+ uint32_t buffer_length = 0;
+
+ tx_buf_alloc(&p_buffer, (uint16_t *)&buffer_length);
+
+ const uint32_t err_code = ble_gatts_exchange_mtu_reply_req_enc(conn_handle,
+ server_rx_mtu,
+ &(p_buffer[1]),
+ &buffer_length);
+
+ APP_ERROR_CHECK(err_code);
+
+ //@note: Increment buffer length as internally managed packet type field must be included.
+ return ser_sd_transport_cmd_write(p_buffer,
+ (++buffer_length),
+ gatts_exchange_mtu_reply_rsp_dec);
+}
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/application/codecs/ble/middleware/app_mw_ble_l2cap.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/application/codecs/ble/middleware/app_mw_ble_l2cap.c
new file mode 100644
index 0000000..41aa555
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/application/codecs/ble/middleware/app_mw_ble_l2cap.c
@@ -0,0 +1,453 @@
+/**
+ * Copyright (c) 2014 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#include "ble_gap.h"
+#include <stdint.h>
+#include "ble_serialization.h"
+#include "ser_sd_transport.h"
+#include "ble_l2cap_app.h"
+#include "app_error.h"
+
+#if defined(NRF_SD_BLE_API_VERSION) && ((NRF_SD_BLE_API_VERSION < 4) || (NRF_SD_BLE_API_VERSION >=5))
+static void tx_buf_alloc(uint8_t * * p_data, uint16_t * p_len)
+{
+ uint32_t err_code;
+
+ do
+ {
+ err_code = ser_sd_transport_tx_alloc(p_data, p_len);
+ }
+ while (err_code != NRF_SUCCESS);
+ *p_data[0] = SER_PKT_TYPE_CMD;
+ *p_len -= 1;
+}
+
+#endif
+#if defined(NRF_SD_BLE_API_VERSION) && NRF_SD_BLE_API_VERSION < 4
+/**@brief Command response callback function for @ref ble_l2cap_cid_register_req_enc BLE command.
+ *
+ * Callback for decoding the output parameters and the command response return code.
+ *
+ * @param[in] p_buffer Pointer to begin of command response buffer.
+ * @param[in] length Length of data in bytes.
+ *
+ * @return Decoded command response return code.
+ */
+static uint32_t l2cap_cid_register_rsp_dec(const uint8_t * p_buffer, uint16_t length)
+{
+ uint32_t result_code;
+
+ const uint32_t err_code =
+ ble_l2cap_cid_register_rsp_dec(p_buffer,
+ length,
+ &result_code);
+
+ APP_ERROR_CHECK(err_code);
+
+ return result_code;
+}
+
+#ifndef _sd_ble_l2cap_cid_register
+#define _sd_ble_l2cap_cid_register sd_ble_l2cap_cid_register
+#endif
+uint32_t _sd_ble_l2cap_cid_register(uint16_t cid)
+{
+
+ uint8_t * p_buffer;
+ uint32_t buffer_length = 0;
+
+ tx_buf_alloc(&p_buffer, (uint16_t *)&buffer_length);
+ const uint32_t err_code = ble_l2cap_cid_register_req_enc(cid,
+ &(p_buffer[1]),
+ &buffer_length);
+ //@note: Should never fail.
+ APP_ERROR_CHECK(err_code);
+
+ //@note: Increment buffer length as internally managed packet type field must be included.
+ return ser_sd_transport_cmd_write(p_buffer,
+ (++buffer_length),
+ l2cap_cid_register_rsp_dec);
+}
+
+/**@brief Command response callback function for @ref ble_l2cap_cid_unregister_req_enc BLE command.
+ *
+ * Callback for decoding the output parameters and the command response return code.
+ *
+ * @param[in] p_buffer Pointer to begin of command response buffer.
+ * @param[in] length Length of data in bytes.
+ *
+ * @return Decoded command response return code.
+ */
+static uint32_t l2cap_cid_unregister_rsp_dec(const uint8_t * p_buffer, uint16_t length)
+{
+ uint32_t result_code;
+
+ const uint32_t err_code =
+ ble_l2cap_cid_unregister_rsp_dec(p_buffer,
+ length,
+ &result_code);
+
+ APP_ERROR_CHECK(err_code);
+
+
+
+ return result_code;
+}
+
+#ifndef _sd_ble_l2cap_cid_unregister
+#define _sd_ble_l2cap_cid_unregister sd_ble_l2cap_cid_unregister
+#endif
+uint32_t _sd_ble_l2cap_cid_unregister(uint16_t cid)
+{
+ uint8_t * p_buffer;
+ uint32_t buffer_length = 0;
+
+ tx_buf_alloc(&p_buffer, (uint16_t *)&buffer_length);
+ const uint32_t err_code = ble_l2cap_cid_unregister_req_enc(cid,
+ &(p_buffer[1]),
+ &buffer_length);
+ //@note: Should never fail.
+ APP_ERROR_CHECK(err_code);
+
+ //@note: Increment buffer length as internally managed packet type field must be included.
+ return ser_sd_transport_cmd_write(p_buffer,
+ (++buffer_length),
+ l2cap_cid_unregister_rsp_dec);
+}
+
+/**@brief Command response callback function for @ref ble_l2cap_tx_req_enc BLE command.
+ *
+ * Callback for decoding the output parameters and the command response return code.
+ *
+ * @param[in] p_buffer Pointer to begin of command response buffer.
+ * @param[in] length Length of data in bytes.
+ *
+ * @return Decoded command response return code.
+ */
+static uint32_t l2cap_tx_rsp_dec(const uint8_t * p_buffer, uint16_t length)
+{
+ uint32_t result_code;
+
+ const uint32_t err_code =
+ ble_l2cap_tx_rsp_dec(p_buffer,
+ length,
+ &result_code);
+
+ APP_ERROR_CHECK(err_code);
+
+
+
+ return result_code;
+}
+
+#ifndef _sd_ble_l2cap_tx
+#define _sd_ble_l2cap_tx sd_ble_l2cap_tx
+#endif
+uint32_t _sd_ble_l2cap_tx(uint16_t conn_handle,
+ ble_l2cap_header_t const * const p_header,
+ uint8_t const * const p_data)
+{
+
+ uint8_t * p_buffer;
+ uint32_t buffer_length = 0;
+
+ tx_buf_alloc(&p_buffer, (uint16_t *)&buffer_length);
+ const uint32_t err_code = ble_l2cap_tx_req_enc(conn_handle, p_header, p_data,
+ &(p_buffer[1]),
+ &buffer_length);
+ //@note: Should never fail.
+ APP_ERROR_CHECK(err_code);
+
+ //@note: Increment buffer length as internally managed packet type field must be included.
+ return ser_sd_transport_cmd_write(p_buffer,
+ (++buffer_length),
+ l2cap_tx_rsp_dec);
+}
+
+#endif
+
+#if NRF_SD_BLE_API_VERSION >= 5
+static void * mp_out_params[1];
+/**@brief Command response callback function for @ref ble_l2cap_ch_setup_req_enc BLE command.
+ *
+ * Callback for decoding the output parameters and the command response return code.
+ *
+ * @param[in] p_buffer Pointer to begin of command response buffer.
+ * @param[in] length Length of data in bytes.
+ *
+ * @return Decoded command response return code.
+ */
+static uint32_t l2cap_ch_setup_rsp_dec(const uint8_t * p_buffer, uint16_t length)
+{
+ uint32_t result_code;
+
+ const uint32_t err_code =
+ ble_l2cap_ch_setup_rsp_dec(p_buffer,
+ length,
+ (uint16_t *)mp_out_params[0],
+ &result_code);
+
+ APP_ERROR_CHECK(err_code);
+
+
+
+ return result_code;
+}
+
+#ifndef _sd_ble_l2cap_ch_setup
+#define _sd_ble_l2cap_ch_setup sd_ble_l2cap_ch_setup
+#endif
+uint32_t _sd_ble_l2cap_ch_setup(uint16_t conn_handle,
+ uint16_t * p_local_cid,
+ ble_l2cap_ch_setup_params_t const *p_params)
+{
+
+ uint8_t * p_buffer;
+ uint32_t buffer_length = 0;
+
+ tx_buf_alloc(&p_buffer, (uint16_t *)&buffer_length);
+ mp_out_params[0] = p_local_cid;
+ const uint32_t err_code = ble_l2cap_ch_setup_req_enc(conn_handle, p_local_cid, p_params,
+ &(p_buffer[1]),
+ &buffer_length);
+ //@note: Should never fail.
+ APP_ERROR_CHECK(err_code);
+
+ //@note: Increment buffer length as internally managed packet type field must be included.
+ return ser_sd_transport_cmd_write(p_buffer,
+ (++buffer_length),
+ l2cap_ch_setup_rsp_dec);
+}
+
+/**@brief Command response callback function for @ref ble_l2cap_ch_release_req_enc BLE command.
+ *
+ * Callback for decoding the output parameters and the command response return code.
+ *
+ * @param[in] p_buffer Pointer to begin of command response buffer.
+ * @param[in] length Length of data in bytes.
+ *
+ * @return Decoded command response return code.
+ */
+static uint32_t l2cap_ch_release_rsp_dec(const uint8_t * p_buffer, uint16_t length)
+{
+ uint32_t result_code;
+
+ const uint32_t err_code =
+ ble_l2cap_ch_release_rsp_dec(p_buffer,
+ length,
+ &result_code);
+
+ APP_ERROR_CHECK(err_code);
+
+
+
+ return result_code;
+}
+
+#ifndef _sd_ble_l2cap_ch_release
+#define _sd_ble_l2cap_ch_release sd_ble_l2cap_ch_release
+#endif
+uint32_t _sd_ble_l2cap_ch_release(uint16_t conn_handle,
+ uint16_t local_cid)
+{
+
+ uint8_t * p_buffer;
+ uint32_t buffer_length = 0;
+
+ tx_buf_alloc(&p_buffer, (uint16_t *)&buffer_length);
+ const uint32_t err_code = ble_l2cap_ch_release_req_enc(conn_handle, local_cid,
+ &(p_buffer[1]),
+ &buffer_length);
+ //@note: Should never fail.
+ APP_ERROR_CHECK(err_code);
+
+ //@note: Increment buffer length as internally managed packet type field must be included.
+ return ser_sd_transport_cmd_write(p_buffer,
+ (++buffer_length),
+ l2cap_ch_release_rsp_dec);
+}
+
+
+/**@brief Command response callback function for @ref ble_l2cap_ch_rx_req_enc BLE command.
+ *
+ * Callback for decoding the output parameters and the command response return code.
+ *
+ * @param[in] p_buffer Pointer to begin of command response buffer.
+ * @param[in] length Length of data in bytes.
+ *
+ * @return Decoded command response return code.
+ */
+static uint32_t l2cap_ch_rx_rsp_dec(const uint8_t * p_buffer, uint16_t length)
+{
+ uint32_t result_code;
+
+ const uint32_t err_code =
+ ble_l2cap_ch_rx_rsp_dec(p_buffer,
+ length,
+ &result_code);
+
+ APP_ERROR_CHECK(err_code);
+
+
+
+ return result_code;
+}
+
+#ifndef _sd_ble_l2cap_ch_rx
+#define _sd_ble_l2cap_ch_rx sd_ble_l2cap_ch_rx
+#endif
+uint32_t _sd_ble_l2cap_ch_rx(uint16_t conn_handle, uint16_t local_cid, ble_data_t const *p_sdu_buf)
+{
+
+ uint8_t * p_buffer;
+ uint32_t buffer_length = 0;
+
+ tx_buf_alloc(&p_buffer, (uint16_t *)&buffer_length);
+ const uint32_t err_code = ble_l2cap_ch_rx_req_enc(conn_handle, local_cid, p_sdu_buf,
+ &(p_buffer[1]),
+ &buffer_length);
+ //@note: Should never fail.
+ APP_ERROR_CHECK(err_code);
+
+ //@note: Increment buffer length as internally managed packet type field must be included.
+ return ser_sd_transport_cmd_write(p_buffer,
+ (++buffer_length),
+ l2cap_ch_rx_rsp_dec);
+}
+
+
+/**@brief Command response callback function for @ref ble_l2cap_ch_tx_req_enc BLE command.
+ *
+ * Callback for decoding the output parameters and the command response return code.
+ *
+ * @param[in] p_buffer Pointer to begin of command response buffer.
+ * @param[in] length Length of data in bytes.
+ *
+ * @return Decoded command response return code.
+ */
+static uint32_t l2cap_ch_tx_rsp_dec(const uint8_t * p_buffer, uint16_t length)
+{
+ uint32_t result_code;
+
+ const uint32_t err_code =
+ ble_l2cap_ch_tx_rsp_dec(p_buffer,
+ length,
+ &result_code);
+
+ APP_ERROR_CHECK(err_code);
+
+
+
+ return result_code;
+}
+
+#ifndef _sd_ble_l2cap_ch_tx
+#define _sd_ble_l2cap_ch_tx sd_ble_l2cap_ch_tx
+#endif
+uint32_t _sd_ble_l2cap_ch_tx(uint16_t conn_handle, uint16_t local_cid, ble_data_t const *p_sdu_buf)
+{
+
+ uint8_t * p_buffer;
+ uint32_t buffer_length = 0;
+
+ tx_buf_alloc(&p_buffer, (uint16_t *)&buffer_length);
+ const uint32_t err_code = ble_l2cap_ch_tx_req_enc(conn_handle, local_cid, p_sdu_buf,
+ &(p_buffer[1]),
+ &buffer_length);
+ //@note: Should never fail.
+ APP_ERROR_CHECK(err_code);
+
+ //@note: Increment buffer length as internally managed packet type field must be included.
+ return ser_sd_transport_cmd_write(p_buffer,
+ (++buffer_length),
+ l2cap_ch_tx_rsp_dec);
+}
+
+/**@brief Command response callback function for @ref ble_l2cap_ch_flow_control_req_enc BLE command.
+ *
+ * Callback for decoding the output parameters and the command response return code.
+ *
+ * @param[in] p_buffer Pointer to begin of command response buffer.
+ * @param[in] length Length of data in bytes.
+ *
+ * @return Decoded command response return code.
+ */
+static uint32_t l2cap_ch_flow_control_rsp_dec(const uint8_t * p_buffer, uint16_t length)
+{
+ uint32_t result_code;
+
+ const uint32_t err_code =
+ ble_l2cap_ch_flow_control_rsp_dec(p_buffer,
+ length,
+ (uint16_t *)mp_out_params[0],
+ &result_code);
+
+ APP_ERROR_CHECK(err_code);
+
+
+
+ return result_code;
+}
+
+#ifndef _sd_ble_l2cap_ch_flow_control
+#define _sd_ble_l2cap_ch_flow_control sd_ble_l2cap_ch_flow_control
+#endif
+uint32_t _sd_ble_l2cap_ch_flow_control(uint16_t conn_handle,
+ uint16_t local_cid,
+ uint16_t credits,
+ uint16_t *p_credits)
+{
+
+ uint8_t * p_buffer;
+ uint32_t buffer_length = 0;
+
+ tx_buf_alloc(&p_buffer, (uint16_t *)&buffer_length);
+ mp_out_params[0] = p_credits;
+ const uint32_t err_code = ble_l2cap_ch_flow_control_req_enc(conn_handle, local_cid, credits, p_credits,
+ &(p_buffer[1]),
+ &buffer_length);
+ //@note: Should never fail.
+ APP_ERROR_CHECK(err_code);
+
+ //@note: Increment buffer length as internally managed packet type field must be included.
+ return ser_sd_transport_cmd_write(p_buffer,
+ (++buffer_length),
+ l2cap_ch_flow_control_rsp_dec);
+}
+#endif
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/application/codecs/ble/middleware/app_mw_nrf_soc.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/application/codecs/ble/middleware/app_mw_nrf_soc.c
new file mode 100644
index 0000000..0b0158e
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/application/codecs/ble/middleware/app_mw_nrf_soc.c
@@ -0,0 +1,171 @@
+/**
+ * Copyright (c) 2014 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#include "nrf_soc.h"
+#include <stdint.h>
+#include <string.h>
+#include "ser_sd_transport.h"
+#include "nrf_soc_app.h"
+#include "nrf_error_soc.h"
+#include "app_error.h"
+#include "ble_serialization.h"
+
+#include "ser_app_power_system_off.h"
+
+static void * mp_out_param;
+
+static void tx_buf_alloc(uint8_t * * p_data, uint16_t * p_len)
+{
+ uint32_t err_code;
+
+ do
+ {
+ err_code = ser_sd_transport_tx_alloc(p_data, p_len);
+ }
+ while (err_code != NRF_SUCCESS);
+ *p_data[0] = SER_PKT_TYPE_CMD;
+ *p_len -= 1;
+}
+
+
+uint32_t sd_power_system_off(void)
+{
+ uint8_t * p_buffer;
+ uint32_t buffer_length = 0;
+
+ tx_buf_alloc(&p_buffer, (uint16_t *)&buffer_length);
+ const uint32_t err_code = power_system_off_req_enc(&(p_buffer[1]), &buffer_length);
+ APP_ERROR_CHECK(err_code);
+
+ ser_app_power_system_off_set();
+
+ //@note: Increment buffer length as internally managed packet type field must be included.
+ return ser_sd_transport_cmd_write(p_buffer,
+ (++buffer_length),
+ NULL);
+}
+
+
+/**@brief Command response callback function for @ref sd_temp_get BLE command.
+ *
+ * Callback for decoding the output parameters and the command response return code.
+ *
+ * @param[in] p_buffer Pointer to begin of command response buffer.
+ * @param[in] length Length of data in bytes.
+ *
+ * @return Decoded command response return code.
+ */
+
+static uint32_t mw_temp_get_rsp_dec(const uint8_t * p_buffer, uint16_t length)
+{
+ uint32_t result_code;
+
+ const uint32_t err_code = temp_get_rsp_dec(p_buffer,
+ length,
+ &result_code,
+ (int32_t * *) &mp_out_param);
+
+ APP_ERROR_CHECK(err_code);
+
+ return result_code;
+}
+
+uint32_t sd_temp_get(int32_t * p_temp)
+{
+
+ uint8_t * p_buffer;
+ uint32_t buffer_length = 0;
+
+ tx_buf_alloc(&p_buffer, (uint16_t *)&buffer_length);
+ mp_out_param = p_temp;
+
+ const uint32_t err_code = temp_get_req_enc(p_temp,
+ &(p_buffer[1]),
+ &buffer_length);
+ APP_ERROR_CHECK(err_code);
+
+ //@note: Increment buffer length as internally managed packet type field must be included.
+ return ser_sd_transport_cmd_write(p_buffer,
+ (++buffer_length),
+ mw_temp_get_rsp_dec);
+}
+
+/**@brief Command response callback function for @ref sd_ecb_block_encrypt BLE command.
+ *
+ * Callback for decoding the output parameters and the command response return code.
+ *
+ * @param[in] p_buffer Pointer to begin of command response buffer.
+ * @param[in] length Length of data in bytes.
+ *
+ * @return Decoded command response return code.
+ */
+
+static uint32_t mw_ecb_block_encrypt_rsp_dec(const uint8_t * p_buffer, uint16_t length)
+{
+ uint32_t result_code;
+
+ const uint32_t err_code = ecb_block_encrypt_rsp_dec(p_buffer,
+ length,
+ (nrf_ecb_hal_data_t * *)&mp_out_param,
+ &result_code);
+
+ APP_ERROR_CHECK(err_code);
+
+ return result_code;
+}
+
+uint32_t sd_ecb_block_encrypt(nrf_ecb_hal_data_t * p_ecb_data)
+{
+
+ uint8_t * p_buffer;
+ uint32_t buffer_length = 0;
+
+ tx_buf_alloc(&p_buffer, (uint16_t *)&buffer_length);
+ mp_out_param = p_ecb_data;
+
+ const uint32_t err_code = ecb_block_encrypt_req_enc(p_ecb_data,
+ &(p_buffer[1]),
+ &buffer_length);
+ APP_ERROR_CHECK(err_code);
+
+ //@note: Increment buffer length as internally managed packet type field must be included.
+ return ser_sd_transport_cmd_write(p_buffer,
+ (++buffer_length),
+ mw_ecb_block_encrypt_rsp_dec);
+}
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/application/codecs/ble/serializers/app_ble_gap_sec_keys.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/application/codecs/ble/serializers/app_ble_gap_sec_keys.c
new file mode 100644
index 0000000..108231d
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/application/codecs/ble/serializers/app_ble_gap_sec_keys.c
@@ -0,0 +1,182 @@
+/**
+ * Copyright (c) 2014 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#include "app_ble_gap_sec_keys.h"
+#include "ser_config.h"
+#include "nrf_error.h"
+#include "nordic_common.h"
+#include <stddef.h>
+#include <stdbool.h>
+#include <string.h>
+
+#if NRF_SD_BLE_API_VERSION >= 6
+typedef struct {
+ bool active;
+ uint8_t adv_handle;
+ uint8_t * p_adv_data;
+ uint8_t * p_scan_rsp_data;
+} adv_set_t;
+
+static adv_set_t m_adv_sets[4]; //todo configurable number of adv sets.
+
+static ble_data_t m_scan_data = {0};
+#endif
+ser_ble_gap_app_keyset_t m_app_keys_table[SER_MAX_CONNECTIONS];
+
+uint32_t app_ble_gap_sec_context_create(uint16_t conn_handle, uint32_t *p_index)
+{
+ uint32_t err_code = NRF_ERROR_NO_MEM;
+ uint32_t i;
+
+ for (i=0; i<SER_MAX_CONNECTIONS; i++ )
+ {
+ if ( ! m_app_keys_table[i].conn_active )
+ {
+ m_app_keys_table[i].conn_active = 1;
+ m_app_keys_table[i].conn_handle = conn_handle;
+ *p_index = i;
+ err_code = NRF_SUCCESS;
+ break;
+ }
+ }
+
+ return err_code;
+}
+
+uint32_t app_ble_gap_sec_context_destroy(uint16_t conn_handle)
+{
+ uint32_t err_code = NRF_ERROR_NOT_FOUND;
+ uint32_t i;
+
+ for (i=0; i<SER_MAX_CONNECTIONS; i++ )
+ {
+ if ( m_app_keys_table[i].conn_handle == conn_handle )
+ {
+ m_app_keys_table[i].conn_active = 0;
+ err_code = NRF_SUCCESS;
+ break;
+ }
+ }
+
+ return err_code;
+}
+
+uint32_t app_ble_gap_sec_context_find(uint16_t conn_handle, uint32_t *p_index)
+{
+ uint32_t err_code = NRF_ERROR_NOT_FOUND;
+ uint32_t i;
+
+ for (i=0; i<SER_MAX_CONNECTIONS; i++ )
+ {
+ if ( (m_app_keys_table[i].conn_handle == conn_handle) && (m_app_keys_table[i].conn_active == 1) )
+ {
+ *p_index = i;
+ err_code = NRF_SUCCESS;
+ break;
+ }
+ }
+
+ return err_code;
+}
+#if NRF_SD_BLE_API_VERSION >= 6
+uint32_t app_ble_gap_scan_data_set(ble_data_t const * p_data)
+{
+ if (m_scan_data.p_data)
+ {
+ return NRF_ERROR_BUSY;
+ }
+ else
+ {
+ memcpy(&m_scan_data, p_data, sizeof(ble_data_t));
+ return NRF_SUCCESS;
+ }
+}
+
+
+uint32_t app_ble_gap_scan_data_fetch_clear(ble_data_t * p_data)
+{
+ memcpy(p_data, &m_scan_data, sizeof(ble_data_t));
+ if (m_scan_data.p_data)
+ {
+ m_scan_data.p_data = NULL;
+ return NRF_SUCCESS;
+ }
+ else
+ {
+ return NRF_ERROR_NOT_FOUND;
+ }
+}
+
+uint32_t app_ble_gap_adv_set_register(uint8_t adv_handle, uint8_t * p_adv_data, uint8_t * p_scan_rsp_data)
+{
+ uint32_t err_code = NRF_ERROR_NO_MEM;
+ uint32_t i;
+ for (i = 0; i < ARRAY_SIZE(m_adv_sets); i++)
+ {
+ if (m_adv_sets[i].active == false)
+ {
+ m_adv_sets[i].active = true;
+ m_adv_sets[i].adv_handle = adv_handle;
+ m_adv_sets[i].p_adv_data = p_adv_data;
+ m_adv_sets[i].p_scan_rsp_data = p_scan_rsp_data;
+ err_code = NRF_SUCCESS;
+ break;
+ }
+ }
+ return err_code;
+}
+
+uint32_t app_ble_gap_adv_set_unregister(uint8_t adv_handle, uint8_t * * pp_adv_data, uint8_t **pp_scan_rsp_data)
+{
+ uint32_t err_code = NRF_ERROR_NOT_FOUND;
+ uint32_t i;
+ for (i = 0; i < ARRAY_SIZE(m_adv_sets); i++)
+ {
+ if ((m_adv_sets[i].active == true) && (m_adv_sets[i].adv_handle == adv_handle))
+ {
+ m_adv_sets[i].active = false;
+ *pp_adv_data = m_adv_sets[i].p_adv_data;
+ *pp_scan_rsp_data = m_adv_sets[i].p_scan_rsp_data;
+ err_code = NRF_SUCCESS;
+ break;
+ }
+ }
+ return err_code;
+}
+#endif
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/application/codecs/ble/serializers/app_ble_gap_sec_keys.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/application/codecs/ble/serializers/app_ble_gap_sec_keys.h
new file mode 100644
index 0000000..314a5f5
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/application/codecs/ble/serializers/app_ble_gap_sec_keys.h
@@ -0,0 +1,151 @@
+/**
+ * Copyright (c) 2014 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#ifndef _APP_BLE_GAP_SEC_KEYS_H
+#define _APP_BLE_GAP_SEC_KEYS_H
+
+ /**@file
+ *
+ * @defgroup app_ble_gap_sec_keys GAP Functions for managing memory for security keys in the application device.
+ * @{
+ * @ingroup ser_app_s130_codecs
+ *
+ * @brief GAP Application auxiliary functions for synchronizing the GAP security keys with the ones stored in the connectivity device.
+ */
+
+#include "ble_gap.h"
+#include "ble_types.h"
+
+#include <stdint.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**@brief GAP connection - keyset mapping structure.
+ *
+ * @note This structure is used to map keysets to connection instances and store them in a static table.
+ */
+typedef struct
+{
+ uint16_t conn_handle; /**< Connection handle.*/
+ uint8_t conn_active; /**< Indication that keys for this connection are used by the SoftDevice. 0: keys used; 1: keys not used. */
+ ble_gap_sec_keyset_t keyset; /**< Keyset structure, see @ref ble_gap_sec_keyset_t.*/
+} ser_ble_gap_app_keyset_t;
+
+/**@brief Allocates the instance in m_app_keys_table[] for storage of encryption keys.
+ *
+ * @param[in] conn_handle conn_handle
+ * @param[out] p_index Pointer to the index of the allocated instance.
+ *
+ * @retval NRF_SUCCESS Context allocated.
+ * @retval NRF_ERROR_NO_MEM No free instance available.
+ */
+uint32_t app_ble_gap_sec_context_create(uint16_t conn_handle, uint32_t *p_index);
+
+/**@brief Release the instance identified by a connection handle.
+ *
+ * @param[in] conn_handle conn_handle
+ *
+ * @retval NRF_SUCCESS Context released.
+ * @retval NRF_ERROR_NOT_FOUND Instance with conn_handle not found.
+ */
+uint32_t app_ble_gap_sec_context_destroy(uint16_t conn_handle);
+
+/**@brief Finds index of instance identified by a connection handle in m_app_keys_table[].
+ *
+ * @param[in] conn_handle conn_handle
+ *
+ * @param[out] p_index Pointer to the index of the entry in the context table corresponding to the given conn_handle.
+ *
+ * @retval NRF_SUCCESS Context found.
+ * @retval NRF_ERROR_NOT_FOUND Instance with conn_handle not found.
+ */
+uint32_t app_ble_gap_sec_context_find(uint16_t conn_handle, uint32_t *p_index);
+/** @} */
+
+#if NRF_SD_BLE_API_VERSION >= 6
+/**
+ * @brief Stores buffer for adv report data.
+ *
+ * @param p_data Pointer to the buffer.
+ *
+ * @return NRF_SUCCESS or error in case pointer is already set.
+ */
+uint32_t app_ble_gap_scan_data_set(ble_data_t const * p_data);
+
+/**
+ * @brief Returns pointer to the buffer for storing report data. Returns error if not paired with
+ * @ref app_ble_gap_scan_data_set call.
+ *
+ * @param[out] p_data Stored data.
+ * @return NRF_SUCCESS or error in case pointer is already cleared.
+ */
+uint32_t app_ble_gap_scan_data_fetch_clear(ble_data_t * p_data);
+
+/**
+ * @brief Function for registering data pointers related with given adv_handle.
+ *
+ * @param adv_handle Handle.
+ * @param p_adv_data Adv_data buffer.
+ * @param p_scan_rsp_data Scan_rsp_data buffer.
+ *
+ * @return NRF_SUCCESS or error.
+ *
+ */
+uint32_t app_ble_gap_adv_set_register(uint8_t adv_handle, uint8_t * p_adv_data, uint8_t * p_scan_rsp_data);
+
+
+/**
+ * @brief Function for unregistering given .
+ *
+ * @param[in] adv_handle Handle.
+ * @param[out] pp_adv_data Pointer to adv_data buffer associated with given adv_handle.
+ * @param[out] pp_scan_rsp_data Pointer to adv_data buffer associated with given adv_handle.
+ *
+ * @return NRF_SUCCESS or error.
+ *
+ */
+uint32_t app_ble_gap_adv_set_unregister(uint8_t adv_handle, uint8_t * * pp_adv_data, uint8_t **pp_scan_rsp_data);
+#endif
+#ifdef __cplusplus
+}
+#endif
+
+#endif //_APP_BLE_GAP_SEC_KEYS_H
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/application/codecs/ble/serializers/app_ble_user_mem.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/application/codecs/ble/serializers/app_ble_user_mem.c
new file mode 100644
index 0000000..dcb1371
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/application/codecs/ble/serializers/app_ble_user_mem.c
@@ -0,0 +1,101 @@
+/**
+ * Copyright (c) 2014 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#include "app_ble_user_mem.h"
+#include "ser_config.h"
+#include "nrf_error.h"
+#include <stddef.h>
+
+ser_ble_user_mem_t m_app_user_mem_table[SER_MAX_CONNECTIONS];
+
+uint32_t app_ble_user_mem_context_create(uint16_t conn_handle, uint32_t *p_index)
+{
+ uint32_t err_code = NRF_ERROR_NO_MEM;
+ uint32_t i;
+
+ for (i=0; i<SER_MAX_CONNECTIONS; i++ )
+ {
+ if ( ! m_app_user_mem_table[i].conn_active )
+ {
+ m_app_user_mem_table[i].conn_active = 1;
+ m_app_user_mem_table[i].conn_handle = conn_handle;
+ *p_index = i;
+ err_code = NRF_SUCCESS;
+ break;
+ }
+ }
+
+ return err_code;
+}
+
+uint32_t app_ble_user_mem_context_destroy(uint16_t conn_handle)
+{
+ uint32_t err_code = NRF_ERROR_NOT_FOUND;
+ uint32_t i;
+
+ for (i=0; i<SER_MAX_CONNECTIONS; i++ )
+ {
+ if ( m_app_user_mem_table[i].conn_handle == conn_handle )
+ {
+ m_app_user_mem_table[i].conn_active = 0;
+ err_code = NRF_SUCCESS;
+ break;
+ }
+ }
+
+ return err_code;
+}
+
+uint32_t app_ble_user_mem_context_find(uint16_t conn_handle, uint32_t *p_index)
+{
+ uint32_t err_code = NRF_ERROR_NOT_FOUND;
+ uint32_t i;
+
+ for (i=0; i<SER_MAX_CONNECTIONS; i++ )
+ {
+ if ( (m_app_user_mem_table[i].conn_handle == conn_handle) && (m_app_user_mem_table[i].conn_active == 1) )
+ {
+ *p_index = i;
+ err_code = NRF_SUCCESS;
+ break;
+ }
+ }
+
+ return err_code;
+}
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/application/codecs/ble/serializers/app_ble_user_mem.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/application/codecs/ble/serializers/app_ble_user_mem.h
new file mode 100644
index 0000000..ac95b01
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/application/codecs/ble/serializers/app_ble_user_mem.h
@@ -0,0 +1,109 @@
+/**
+ * Copyright (c) 2014 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#ifndef _APP_BLE_USER_MEM_H
+#define _APP_BLE_USER_MEM_H
+
+
+ /**@file
+ *
+ * @defgroup app_ble_user_mem Functions for managing memory for user memory request in the application device.
+ * @{
+ * @ingroup ser_app_s130_codecs
+ *
+ * @brief Application auxiliary functions for synchronizing user memory with the one stored in the connectivity device.
+ */
+
+#include "ble.h"
+#include "ser_config.h"
+#include <stdint.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**@brief Connection - user memory mapping structure.
+ *
+ * @note This structure is used to map user memory to connection instances and store it in a static table.
+ */
+//lint -esym(452,ser_ble_user_mem_t)
+typedef struct
+{
+ uint16_t conn_handle; /**< Connection handle. */
+ uint8_t conn_active; /**< Indication that user memory for this connection is used by the SoftDevice. 0: memory used; 1: memory not used. */
+ ble_user_mem_block_t mem_block; /**< User memory block structure, see @ref ble_user_mem_block_t. */
+} ser_ble_user_mem_t;
+
+/**@brief Allocates instance in m_user_mem_table[] for storage.
+ *
+ * @param[in] conn_handle conn_handle
+ * @param[out] p_index Pointer to the index of the allocated instance.
+ *
+ * @retval NRF_SUCCESS Context allocated.
+ * @retval NRF_ERROR_NO_MEM No free instance available.
+ */
+uint32_t app_ble_user_mem_context_create(uint16_t conn_handle, uint32_t *p_index);
+
+/**@brief Release instance identified by a connection handle.
+ *
+ * @param[in] conn_handle conn_handle
+ *
+ * @retval NRF_SUCCESS Context released.
+ * @retval NRF_ERROR_NOT_FOUND Instance with conn_handle not found.
+ */
+uint32_t app_ble_user_mem_context_destroy(uint16_t conn_handle);
+
+/**@brief Finds index of the instance identified by a connection handle in m_user_mem_table[].
+ *
+ * @param[in] conn_handle conn_handle
+ *
+ * @param[out] p_index Pointer to the index of the entry in the context table corresponding to the given conn_handle.
+ *
+ * @retval NRF_SUCCESS Context found.
+ * @retval NRF_ERROR_NOT_FOUND Instance with conn_handle not found.
+ */
+uint32_t app_ble_user_mem_context_find(uint16_t conn_handle, uint32_t *p_index);
+/** @} */
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif //_APP_BLE_USER_MEM_H
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/application/codecs/ble/serializers/ble_app.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/application/codecs/ble/serializers/ble_app.c
new file mode 100644
index 0000000..fcc71ab
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/application/codecs/ble/serializers/ble_app.c
@@ -0,0 +1,513 @@
+/**
+ * Copyright (c) 2014 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#include <stdlib.h>
+#include <string.h>
+#include "ble_app.h"
+#include "ble_serialization.h"
+#include "ble_struct_serialization.h"
+#include "ble_gap_struct_serialization.h"
+#include "ble_gatt_struct_serialization.h"
+#include "ble_gattc_struct_serialization.h"
+#include "ble_gatts_struct_serialization.h"
+#include "ble_l2cap_struct_serialization.h"
+#include "cond_field_serialization.h"
+#include "app_util.h"
+
+#if defined(NRF_SD_BLE_API_VERSION) && NRF_SD_BLE_API_VERSION < 4
+uint32_t ble_enable_req_enc(ble_enable_params_t * p_ble_enable_params,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len)
+{
+ SER_REQ_ENC_BEGIN(SD_BLE_ENABLE);
+ SER_PUSH_COND(p_ble_enable_params, ble_enable_params_t_enc);
+ SER_REQ_ENC_END;
+}
+#else
+uint32_t ble_enable_req_enc(uint8_t * const p_buf,
+ uint32_t * const p_buf_len)
+{
+ SER_REQ_ENC_BEGIN(SD_BLE_ENABLE);
+ SER_REQ_ENC_END;
+}
+#endif
+
+uint32_t ble_enable_rsp_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ uint32_t * const p_result_code)
+{
+ SER_RSP_DEC_RESULT_ONLY(SD_BLE_ENABLE);
+}
+
+uint32_t ble_opt_get_req_enc(uint32_t opt_id,
+ ble_opt_t const * const p_opt,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len)
+{
+ SER_REQ_ENC_BEGIN(SD_BLE_OPT_GET);
+
+ SER_PUSH_uint32(&opt_id);
+ SER_PUSH_COND(p_opt, NULL);
+
+ SER_REQ_ENC_END;
+}
+
+uint32_t ble_opt_get_rsp_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ uint32_t * const p_opt_id,
+ ble_opt_t * const p_opt,
+ uint32_t * const p_result_code)
+{
+ SER_RSP_DEC_BEGIN(SD_BLE_OPT_GET);
+
+ SER_PULL_uint32(p_opt_id);
+
+ field_decoder_handler_t fp_decoder = NULL;
+ void * p_struct = NULL;
+
+ switch (*p_opt_id)
+ {
+#if defined(NRF_SD_BLE_API_VERSION) && NRF_SD_BLE_API_VERSION < 4
+ case BLE_COMMON_OPT_CONN_BW:
+ fp_decoder = ble_common_opt_conn_bw_t_dec;
+ p_struct = &(p_opt->common_opt.conn_bw);
+ break;
+#endif
+ case BLE_COMMON_OPT_PA_LNA:
+ fp_decoder = ble_common_opt_pa_lna_t_dec;
+ p_struct = &(p_opt->common_opt.pa_lna);
+ break;
+ case BLE_COMMON_OPT_CONN_EVT_EXT:
+ fp_decoder = ble_common_opt_conn_evt_ext_t_dec;
+ p_struct = &(p_opt->common_opt.conn_evt_ext);
+ break;
+ case BLE_GAP_OPT_CH_MAP:
+ fp_decoder = ble_gap_opt_ch_map_t_dec;
+ p_struct =&(p_opt->gap_opt.ch_map);
+ break;
+ case BLE_GAP_OPT_LOCAL_CONN_LATENCY:
+ fp_decoder = ble_gap_opt_local_conn_latency_t_dec;
+ p_struct = &(p_opt->gap_opt.local_conn_latency);
+ break;
+ case BLE_GAP_OPT_PASSKEY:
+ fp_decoder = ble_gap_opt_passkey_t_dec;
+ p_struct = &(p_opt->gap_opt.passkey);
+ break;
+ case BLE_GAP_OPT_AUTH_PAYLOAD_TIMEOUT:
+ fp_decoder = ble_gap_opt_auth_payload_timeout_t_dec;
+ p_struct = &(p_opt->gap_opt.auth_payload_timeout);
+ break;
+#if defined(NRF_SD_BLE_API_VERSION) && NRF_SD_BLE_API_VERSION < 4
+ case BLE_GAP_OPT_EXT_LEN:
+ fp_decoder = ble_gap_opt_ext_len_t_dec;
+ p_struct = &(p_opt->gap_opt.ext_len);
+ break;
+#endif
+#if defined(NRF_SD_BLE_API_VERSION) && NRF_SD_BLE_API_VERSION < 6
+ case BLE_GAP_OPT_SCAN_REQ_REPORT:
+ fp_decoder = ble_gap_opt_scan_req_report_t_dec;
+ p_struct = &(p_opt->gap_opt.scan_req_report);
+ break;
+#endif
+#if defined(NRF_SD_BLE_API_VERSION) && NRF_SD_BLE_API_VERSION < 4
+ case BLE_GAP_OPT_COMPAT_MODE:
+ fp_decoder = ble_gap_opt_compat_mode_t_dec;
+ p_struct = &(p_opt->gap_opt.compat_mode);
+ break;
+#else
+#ifndef S112
+ case BLE_GAP_OPT_COMPAT_MODE_1:
+ fp_decoder = ble_gap_opt_compat_mode_1_t_dec;
+ p_struct = &(p_opt->gap_opt.compat_mode_1);
+ break;
+#endif
+#endif
+#if defined(NRF_SD_BLE_API_VERSION) && NRF_SD_BLE_API_VERSION == 4
+ case BLE_GAP_OPT_COMPAT_MODE_2:
+ fp_decoder = ble_gap_opt_compat_mode_2_t_dec;
+ p_struct = &(p_opt->gap_opt.compat_mode_2);
+ break;
+#endif
+ default:
+ SER_ASSERT(NRF_ERROR_INVALID_PARAM, NRF_ERROR_INVALID_PARAM);
+ break;
+ }
+
+ SER_PULL_FIELD(p_struct, fp_decoder);
+
+ SER_RSP_DEC_END;
+}
+
+
+
+uint32_t ble_opt_set_req_enc(uint32_t const opt_id,
+ ble_opt_t const * const p_opt,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len)
+{
+ SER_REQ_ENC_BEGIN(SD_BLE_OPT_SET);
+
+ SER_PUSH_uint32(&opt_id);
+
+ field_encoder_handler_t fp_encoder = NULL;
+ void const * p_struct = NULL;
+
+ SER_PUSH_COND(p_opt, NULL);
+ if (p_opt)
+ {
+ switch (opt_id)
+ {
+#if defined(NRF_SD_BLE_API_VERSION) && NRF_SD_BLE_API_VERSION < 4
+ case BLE_COMMON_OPT_CONN_BW:
+ fp_encoder = ble_common_opt_conn_bw_t_enc;
+ p_struct = &(p_opt->common_opt.conn_bw);
+ break;
+#endif
+ case BLE_COMMON_OPT_PA_LNA:
+ fp_encoder = ble_common_opt_pa_lna_t_enc;
+ p_struct = &(p_opt->common_opt.pa_lna);
+ break;
+ case BLE_COMMON_OPT_CONN_EVT_EXT:
+ fp_encoder = ble_common_opt_conn_evt_ext_t_enc;
+ p_struct = &(p_opt->common_opt.conn_evt_ext);
+ break;
+ case BLE_GAP_OPT_CH_MAP:
+ fp_encoder = ble_gap_opt_ch_map_t_enc;
+ p_struct = &(p_opt->gap_opt.ch_map);
+ break;
+ case BLE_GAP_OPT_LOCAL_CONN_LATENCY:
+ fp_encoder = ble_gap_opt_local_conn_latency_t_enc;
+ p_struct = &(p_opt->gap_opt.local_conn_latency);
+ break;
+ case BLE_GAP_OPT_PASSKEY:
+ fp_encoder = ble_gap_opt_passkey_t_enc;
+ p_struct = &(p_opt->gap_opt.passkey);
+ break;
+ case BLE_GAP_OPT_AUTH_PAYLOAD_TIMEOUT:
+ fp_encoder = ble_gap_opt_auth_payload_timeout_t_enc;
+ p_struct = &(p_opt->gap_opt.auth_payload_timeout);
+ break;
+#if defined(NRF_SD_BLE_API_VERSION) && NRF_SD_BLE_API_VERSION < 4
+ case BLE_GAP_OPT_EXT_LEN:
+ fp_encoder = ble_gap_opt_ext_len_t_enc;
+ p_struct = &(p_opt->gap_opt.ext_len);
+ break;
+#endif
+#if defined(NRF_SD_BLE_API_VERSION) && NRF_SD_BLE_API_VERSION < 6
+ case BLE_GAP_OPT_SCAN_REQ_REPORT:
+ fp_encoder = ble_gap_opt_scan_req_report_t_enc;
+ p_struct = &(p_opt->gap_opt.scan_req_report);
+ break;
+#endif
+#if defined(NRF_SD_BLE_API_VERSION) && NRF_SD_BLE_API_VERSION < 4
+ case BLE_GAP_OPT_COMPAT_MODE:
+ fp_encoder = ble_gap_opt_compat_mode_t_enc;
+ p_struct = &(p_opt->gap_opt.compat_mode);
+ break;
+#else
+#ifndef S112
+ case BLE_GAP_OPT_COMPAT_MODE_1:
+ fp_encoder = ble_gap_opt_compat_mode_1_t_enc;
+ p_struct = &(p_opt->gap_opt.compat_mode_1);
+ break;
+#endif
+ case BLE_GAP_OPT_SLAVE_LATENCY_DISABLE:
+ fp_encoder = ble_gap_opt_slave_latency_disable_t_enc;
+ p_struct = &(p_opt->gap_opt.slave_latency_disable);
+ break;
+#endif
+#if defined(NRF_SD_BLE_API_VERSION) && NRF_SD_BLE_API_VERSION == 4
+ case BLE_GAP_OPT_COMPAT_MODE_2:
+ fp_encoder = ble_gap_opt_compat_mode_2_t_enc;
+ p_struct = &(p_opt->gap_opt.compat_mode_2);
+ break;
+#endif
+ default:
+ SER_ASSERT(NRF_ERROR_INVALID_PARAM,NRF_ERROR_INVALID_PARAM);
+ break;
+ }
+
+ SER_PUSH_FIELD(p_struct, fp_encoder);
+ }
+
+ SER_REQ_ENC_END;
+}
+
+
+uint32_t ble_opt_set_rsp_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ uint32_t * const p_result_code)
+{
+ SER_RSP_DEC_RESULT_ONLY(SD_BLE_OPT_SET);
+}
+
+#if defined(NRF_SD_BLE_API_VERSION) && NRF_SD_BLE_API_VERSION < 4
+uint32_t ble_tx_packet_count_get_req_enc(uint16_t conn_handle,
+ uint8_t const * const p_count,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len)
+{
+ SER_REQ_ENC_BEGIN(SD_BLE_TX_PACKET_COUNT_GET);
+
+ SER_PUSH_uint16(&conn_handle);
+ SER_PUSH_COND(p_count, NULL);
+
+ SER_REQ_ENC_END;
+}
+
+
+uint32_t ble_tx_packet_count_get_rsp_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ uint8_t * * const pp_count,
+ uint32_t * const p_result_code)
+{
+ SER_RSP_DEC_BEGIN(SD_BLE_TX_PACKET_COUNT_GET);
+ SER_PULL_COND(pp_count, uint8_t_dec);
+ SER_RSP_DEC_END;
+}
+#endif
+
+uint32_t ble_user_mem_reply_req_enc(uint16_t conn_handle,
+ ble_user_mem_block_t const * p_block,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len)
+{
+ SER_REQ_ENC_BEGIN(SD_BLE_USER_MEM_REPLY);
+
+ SER_PUSH_uint16(&conn_handle);
+ SER_PUSH_COND(p_block, ble_user_mem_block_t_enc);
+
+ SER_REQ_ENC_END;
+}
+
+uint32_t ble_user_mem_reply_rsp_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ uint32_t * const p_result_code)
+{
+ SER_RSP_DEC_RESULT_ONLY(SD_BLE_USER_MEM_REPLY);
+}
+
+
+
+uint32_t ble_uuid_decode_req_enc(uint8_t uuid_le_len,
+ uint8_t const * const p_uuid_le,
+ ble_uuid_t * const p_uuid,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len)
+{
+ SER_REQ_ENC_BEGIN(SD_BLE_UUID_DECODE);
+
+ SER_PUSH_len8data(p_uuid_le, uuid_le_len);
+ SER_PUSH_COND(p_uuid, NULL);
+
+ SER_REQ_ENC_END;
+}
+
+
+uint32_t ble_uuid_decode_rsp_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ ble_uuid_t * * const pp_uuid,
+ uint32_t * const p_result_code)
+{
+ SER_RSP_DEC_BEGIN(SD_BLE_UUID_DECODE);
+ SER_PULL_COND(pp_uuid, ble_uuid_t_dec);
+ SER_RSP_DEC_END;
+}
+
+
+uint32_t ble_uuid_encode_req_enc(ble_uuid_t const * const p_uuid,
+ uint8_t const * const p_uuid_le_len,
+ uint8_t const * const p_uuid_le,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len)
+{
+ SER_REQ_ENC_BEGIN(SD_BLE_UUID_ENCODE);
+
+ SER_PUSH_COND(p_uuid, ble_uuid_t_enc);
+ SER_PUSH_COND(p_uuid_le_len, NULL);
+ SER_PUSH_COND(p_uuid_le, NULL);
+
+ SER_REQ_ENC_END;
+}
+
+
+uint32_t ble_uuid_encode_rsp_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ uint8_t * const p_uuid_le_len,
+ uint8_t * const p_uuid_le,
+ uint32_t * const p_result_code)
+{
+ SER_RSP_DEC_BEGIN(SD_BLE_UUID_ENCODE);
+
+ uint8_t uuid_le_len;
+ SER_PULL_uint8(&uuid_le_len);
+ if (p_uuid_le_len)
+ {
+ *p_uuid_le_len = uuid_le_len;
+ if (p_uuid_le)
+ {
+ SER_PULL_uint8array(p_uuid_le, uuid_le_len);
+ }
+ }
+
+ SER_RSP_DEC_END;
+}
+
+uint32_t ble_uuid_vs_add_req_enc(ble_uuid128_t const * const p_vs_uuid,
+ uint8_t * const p_uuid_type,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len)
+{
+ SER_REQ_ENC_BEGIN(SD_BLE_UUID_VS_ADD);
+
+ SER_PUSH_COND(p_vs_uuid, ble_uuid128_t_enc);
+ SER_PUSH_COND(p_uuid_type, NULL);
+
+ SER_REQ_ENC_END;
+}
+
+
+uint32_t ble_uuid_vs_add_rsp_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ uint8_t * * const pp_uuid_type,
+ uint32_t * const p_result_code)
+{
+ SER_RSP_DEC_BEGIN(SD_BLE_UUID_VS_ADD);
+
+ SER_ASSERT_NOT_NULL(pp_uuid_type);
+ SER_PULL_COND(pp_uuid_type, uint8_t_dec);
+
+ SER_RSP_DEC_END;
+}
+
+uint32_t ble_version_get_req_enc(ble_version_t const * const p_version,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len)
+{
+ SER_REQ_ENC_BEGIN(SD_BLE_VERSION_GET);
+ SER_PUSH_COND(p_version, NULL);
+ SER_REQ_ENC_END;
+}
+
+uint32_t ble_version_get_rsp_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ ble_version_t * p_version,
+ uint32_t * const p_result_code)
+{
+ SER_RSP_DEC_BEGIN(SD_BLE_VERSION_GET);
+ SER_PULL_FIELD(p_version, ble_version_t_dec);
+ SER_RSP_DEC_END;
+}
+#if NRF_SD_BLE_API_VERSION >= 4
+uint32_t ble_cfg_set_req_enc(uint32_t cfg_id,
+ ble_cfg_t const * p_cfg,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len)
+{
+ SER_REQ_ENC_BEGIN(SD_BLE_CFG_SET);
+ SER_PUSH_uint32(&cfg_id);
+ field_encoder_handler_t fp_encoder = NULL;
+ void const * p_struct = NULL;
+
+ SER_PUSH_COND(p_cfg, NULL);
+ if (p_cfg)
+ {
+
+ switch (cfg_id)
+ {
+ case BLE_CONN_CFG_GAP:
+ fp_encoder = ble_gap_conn_cfg_t_enc;
+ p_struct = &(p_cfg->conn_cfg.params.gap_conn_cfg);
+ break;
+ case BLE_CONN_CFG_GATTC:
+ fp_encoder = ble_gattc_conn_cfg_t_enc;
+ p_struct = &(p_cfg->conn_cfg.params.gattc_conn_cfg);
+ break;
+ case BLE_CONN_CFG_GATTS:
+ fp_encoder = ble_gatts_conn_cfg_t_enc;
+ p_struct = &(p_cfg->conn_cfg.params.gatts_conn_cfg);
+ break;
+ case BLE_CONN_CFG_GATT:
+ fp_encoder = ble_gatt_conn_cfg_t_enc;
+ p_struct = &(p_cfg->conn_cfg.params.gatt_conn_cfg);
+ break;
+#if defined(NRF_SD_BLE_API_VERSION) && NRF_SD_BLE_API_VERSION >= 5 && !defined(S112)
+ case BLE_CONN_CFG_L2CAP:
+ fp_encoder = ble_l2cap_conn_cfg_t_enc;
+ p_struct = &(p_cfg->conn_cfg.params.l2cap_conn_cfg);
+ break;
+#endif
+ case BLE_COMMON_CFG_VS_UUID:
+ fp_encoder = ble_common_cfg_vs_uuid_t_enc;
+ p_struct = &(p_cfg->common_cfg.vs_uuid_cfg);
+ break;
+ case BLE_GAP_CFG_ROLE_COUNT:
+ fp_encoder = ble_gap_cfg_role_count_t_enc;
+ p_struct = &(p_cfg->gap_cfg.role_count_cfg);
+ break;
+ case BLE_GAP_CFG_DEVICE_NAME:
+ fp_encoder = ble_gap_cfg_device_name_t_enc;
+ p_struct = &(p_cfg->gap_cfg.device_name_cfg);
+ break;
+ case BLE_GATTS_CFG_SERVICE_CHANGED:
+ fp_encoder = ble_gatts_cfg_service_changed_t_enc;
+ p_struct = &(p_cfg->gatts_cfg.service_changed);
+ break;
+ case BLE_GATTS_CFG_ATTR_TAB_SIZE:
+ fp_encoder = ble_gatts_cfg_attr_tab_size_t_enc;
+ p_struct = &(p_cfg->gatts_cfg.attr_tab_size);
+ break;
+ }
+ if (cfg_id >= BLE_CONN_CFG_BASE && cfg_id <= BLE_CONN_CFG_GATT)
+ {
+ SER_PUSH_uint8(&p_cfg->conn_cfg.conn_cfg_tag);
+ }
+ SER_PUSH_FIELD(p_struct, fp_encoder);
+ }
+ SER_REQ_ENC_END;
+}
+
+
+uint32_t ble_cfg_set_rsp_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ uint32_t * const p_result_code)
+{
+ SER_RSP_DEC_RESULT_ONLY(SD_BLE_CFG_SET);
+}
+#endif //NRF_SD_BLE_API_VERSION >= 4
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/application/codecs/ble/serializers/ble_app.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/application/codecs/ble/serializers/ble_app.h
new file mode 100644
index 0000000..a68cf0d
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/application/codecs/ble/serializers/ble_app.h
@@ -0,0 +1,523 @@
+/**
+ * Copyright (c) 2013 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#ifndef BLE_APP_H__
+#define BLE_APP_H__
+
+/**
+ * @addtogroup ser_codecs Serialization codecs
+ * @ingroup ble_sdk_lib_serialization
+ */
+
+/**
+ * @addtogroup ser_app_s130_codecs Application codecs for S132 and S140
+ * @ingroup ser_codecs_app
+ */
+
+/**@file
+ *
+ * @defgroup ble_app Application command request encoders and command response decoders
+ * @{
+ * @ingroup ser_app_s130_codecs
+ *
+ * @brief Application command request encoders and command response decoders.
+ */
+#include "ble.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+#if defined(NRF_SD_BLE_API_VERSION) && NRF_SD_BLE_API_VERSION < 4
+/**
+ * @brief Encodes @ref sd_ble_tx_packet_count_get command request.
+ *
+ * @sa @ref ble_tx_packet_count_get_rsp_dec for command response decoder.
+ *
+ * @param[in] conn_handle Connection handle.
+ * @param[in] p_count Pointer to count value to be filled.
+ * @param[in] p_buf Pointer to buffer where encoded data command will be returned.
+ * @param[in,out] p_buf_len \c in: Size of \p p_buf buffer.
+ * \c out: Length of the encoded command packet.
+ *
+ * @note \p p_count will not be updated by the command
+ * request encoder. Updated values are set by @ref ble_tx_packet_count_get_rsp_dec.
+ *
+ * @retval NRF_SUCCESS Encoding success.
+ * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length.
+ */
+uint32_t ble_tx_packet_count_get_req_enc(uint16_t conn_handle,
+ uint8_t const * const p_count,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len);
+
+/**
+ * @brief Decodes a response to @ref sd_ble_tx_packet_count_get command.
+ *
+ * @sa @ref ble_tx_packet_count_get_req_enc for command request encoder.
+ *
+ * @param[in] p_buf Pointer to the beginning of a command response packet.
+ * @param[in] packet_len Length (in bytes) of the response packet.
+ * @param[out] pp_count Pointer to the pointer to count value.
+ * @param[out] p_result_code Command result code.
+ *
+ * @retval NRF_SUCCESS Decoding success.
+ * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length.
+ * @retval NRF_ERROR_INVALID_DATA Decoding failure. Decoded operation code does not match
+ * expected operation code.
+ */
+uint32_t ble_tx_packet_count_get_rsp_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ uint8_t * * const pp_count,
+ uint32_t * const p_result_code);
+#endif
+/**@brief Encodes the @ref sd_ble_uuid_encode command request.
+ *
+ * @sa @ref ble_uuid_encode_rsp_dec for command response decoder.
+ *
+ * @param[in] p_uuid Pointer to a @ref ble_uuid_t structure that will be encoded into bytes.
+ * @param[in] p_uuid_le_len Size of \p p_uuid_le, if \p p_uuid_le is not NULL
+ * @param[in] p_uuid_le Pointer to a buffer where the little endian raw UUID bytes(2 or 16)
+ * will be stored. Can be NULL to calculate the required size.
+ * @param[in] p_buf Pointer to a buffer where the encoded data command will be returned.
+ * @param[in,out] p_buf_len \c in: Size of \p p_buf buffer.
+ * \c out: Length of the encoded command packet.
+ *
+ * @note \p p_uuid_le_len and \p p_uuid_le will not be updated by the command
+ * request encoder. Updated values are set by @ref ble_uuid_encode_rsp_dec.
+ *
+ * @retval NRF_SUCCESS Encoding success.
+ * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length.
+ */
+uint32_t ble_uuid_encode_req_enc(ble_uuid_t const * const p_uuid,
+ uint8_t const * const p_uuid_le_len,
+ uint8_t const * const p_uuid_le,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len);
+
+/**@brief Decodes a response to the @ref sd_ble_uuid_encode command.
+ *
+ * @sa @ref ble_uuid_encode_req_enc for command request encoder.
+ *
+ * @param[in] p_buf Pointer to the beginning of a command response packet.
+ * @param[in] packet_len Length (in bytes) of a response packet.
+ * @param[in,out] p_uuid_le_len \c in: Size (in bytes) of \p p_uuid_le buffer.
+ * \c out: Length of decoded contents of \p p_uuid_le.
+ * @param[out] p_uuid_le Pointer to a buffer where the encoded UUID will be stored.
+ * @param[out] p_result_code Command result code.
+ *
+ * @retval NRF_SUCCESS Decoding success.
+ * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length.
+ * @retval NRF_ERROR_DATA_SIZE Length of \p p_uuid_le is too small to hold the decoded
+ * value from response.
+ * @retval NRF_ERROR_INVALID_DATA Decoding failure. Decoded operation code does not match the expected
+ * operation code.
+ */
+uint32_t ble_uuid_encode_rsp_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ uint8_t * const p_uuid_le_len,
+ uint8_t * const p_uuid_le,
+ uint32_t * const p_result_code);
+
+/**@brief Encodes @ref sd_ble_uuid_decode command request.
+ *
+ * @sa @ref ble_uuid_decode_rsp_dec for command response decoder.
+ *
+ * @param[in] uuid_le_len Size of \p p_uuid_le if \p p_uuid_le is not NULL.
+ * @param[in] p_uuid_le Pointer to a buffer where the little endian raw UUID bytes(2 or 16)
+ * are stored.
+ * @param[out] p_uuid Pointer to a @ref ble_uuid_t structure were the raw UUID will be decoded.
+ * @param[in] p_buf Pointer to the buffer where encoded data command will be returned.
+ * @param[in,out] p_buf_len \c in: Size of \p p_buf buffer.
+ * \c out: Length of the encoded command packet.
+ *
+ * @note \p p_uuid will not be updated by the command request encoder.
+ * Updated values are set by @ref ble_uuid_decode_rsp_dec.
+ *
+ * @retval NRF_SUCCESS Encoding success.
+ * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length.
+ */
+uint32_t ble_uuid_decode_req_enc(uint8_t uuid_le_len,
+ uint8_t const * const p_uuid_le,
+ ble_uuid_t * const p_uuid,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len);
+
+/**@brief Decodes a response to the @ref sd_ble_uuid_decode command.
+ *
+ * @sa @ref ble_uuid_decode_req_enc for command request encoder.
+ *
+ * @param[in] p_buf Pointer to the beginning of command response packet.
+ * @param[in] packet_len Length (in bytes) of the response packet.
+ * @param[out] p_uuid Pointer to a buffer where the decoded UUID will be stored.
+ * @param[out] p_result_code Command result code.
+ *
+ * @retval NRF_SUCCESS Decoding success.
+ * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length.
+ * @retval NRF_ERROR_INVALID_DATA Decoding failure. Decoded operation code does not match the expected
+ * operation code.
+ */
+uint32_t ble_uuid_decode_rsp_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ ble_uuid_t * * const p_uuid,
+ uint32_t * const p_result_code);
+
+/**@brief Encodes the @ref sd_ble_uuid_vs_add command request.
+ *
+ * @sa @ref ble_uuid_vs_add_rsp_dec for command response decoder.
+ *
+ * @param[in] p_vs_uuid Pointer to a @ref ble_uuid128_t structure.
+ * @param[in] p_uuid_type Pointer to uint8_t where UUID type will be returned.
+ * @param[in] p_buf Pointer to buffer where the encoded data command will be returned.
+ * @param[in,out] p_buf_len \c in: Size of \p p_buf buffer.
+ * \c out: Length of encoded command packet.
+ *
+ * @note \p p_uuid_type will not be updated by the command request encoder.
+ * Updated values are set by @ref ble_uuid_vs_add_rsp_dec.
+ *
+ * @retval NRF_SUCCESS Encoding success.
+ * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length.
+ */
+uint32_t ble_uuid_vs_add_req_enc(ble_uuid128_t const * const p_vs_uuid,
+ uint8_t * const p_uuid_type,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len);
+
+/**@brief Decodes response to the @ref sd_ble_uuid_vs_add command.
+ *
+ * @sa @ref ble_uuid_vs_add_req_enc for command request encoder.
+ *
+ * @param[in] p_buf Pointer to the beginning of command response packet.
+ * @param[in] packet_len Length (in bytes) of a response packet.
+ * @param[out] pp_uuid_type Pointer to a pointer to uint8_t where the decoded UUID type will be stored.
+ * @param[out] p_result_code Command result code.
+ *
+ * @retval NRF_SUCCESS Decoding success.
+ * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length.
+ * @retval NRF_ERROR_INVALID_DATA Decoding failure. Decoded operation code does not match expected
+ * operation code.
+ */
+uint32_t ble_uuid_vs_add_rsp_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ uint8_t * * const pp_uuid_type,
+ uint32_t * const p_result_code);
+
+/**@brief Encodes the @ref sd_ble_version_get command request.
+ *
+ * @sa @ref ble_version_get_rsp_dec for command response decoder.
+ *
+ * @param[in] p_version Pointer to a @ref ble_version_t structure to be filled by the response.
+ * @param[in] p_buf Pointer to a buffer where the encoded data command will be returned.
+ * @param[in,out] p_buf_len \c in: Size of \p p_buf buffer.
+ * \c out: Length of encoded command packet.
+ *
+ * @retval NRF_SUCCESS Encoding success.
+ * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length.
+ */
+uint32_t ble_version_get_req_enc(ble_version_t const * const p_version,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len);
+
+/**@brief Decodes response to the @ref sd_ble_version_get command.
+ *
+ * @sa @ref ble_version_get_req_enc for command request encoder.
+ *
+ * @param[in] p_buf Pointer to the beginning of a command response packet.
+ * @param[in] packet_len Length (in bytes) of the response packet.
+ * @param[out] p_version Pointer to a @ref ble_version_t where the decoded version will be stored.
+ * @param[out] p_result_code Command result code.
+ *
+ * @retval NRF_SUCCESS Version information stored successfully.
+ * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length.
+ * @retval NRF_ERROR_DATA_SIZE Decoding failure. Length of \p p_event is too small to
+ * hold the decoded event.
+ */
+uint32_t ble_version_get_rsp_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ ble_version_t * p_version,
+ uint32_t * const p_result_code);
+
+
+/**@brief Encodes the @ref sd_ble_opt_set command request.
+ *
+ * @sa @ref ble_opt_set_rsp_dec for command response decoder.
+ *
+ * @param[in] opt_id Identifies type of parameter in ble_opt_t union.
+ * @param[in] p_opt Pointer to the ble_opt_t union.
+ * @param[in] p_buf Pointer to a buffer where the encoded data command will be returned.
+ * @param[in,out] p_buf_len \c in: Size of \p p_buf buffer.
+ * \c out: Length of the encoded command packet.
+ *
+ * @retval NRF_SUCCESS Encoding success.
+ * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length.
+ * @retval NRF_ERROR_INVALID_PARAM Invalid opt id.
+ */
+uint32_t ble_opt_set_req_enc(uint32_t const opt_id,
+ ble_opt_t const * const p_opt,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len);
+
+/**@brief Decodes response to the @ref sd_ble_opt_set command.
+ *
+ * @sa @ref ble_opt_set_req_enc for command request encoder.
+ *
+ * @param[in] p_buf Pointer to the beginning of a command response packet.
+ * @param[in] packet_len Length (in bytes) of the response packet.
+ * @param[out] p_result_code Command result code.
+ *
+ * @retval NRF_SUCCESS Version information stored successfully.
+ * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length.
+ */
+uint32_t ble_opt_set_rsp_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ uint32_t * const p_result_code);
+
+#if defined(NRF_SD_BLE_API_VERSION) && NRF_SD_BLE_API_VERSION < 4
+/**@brief Encodes the @ref sd_ble_enable command request.
+ *
+ * @sa @ref ble_enable_rsp_dec for command response decoder.
+ *
+ * @param[in] p_ble_enable_params Pointer to the @ref ble_enable_params_t structure.
+ * @param[in] p_buf Pointer to the buffer where encoded data command will be returned.
+ * @param[in,out] p_buf_len \c in: Size of \p p_buf buffer.
+ * \c out: Length of the encoded command packet.
+ *
+ * @retval NRF_SUCCESS Encoding success.
+ * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length.
+ */
+uint32_t ble_enable_req_enc(ble_enable_params_t * p_ble_enable_params,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len);
+#else
+/**@brief Encodes the @ref sd_ble_enable command request.
+ *
+ * @sa @ref ble_enable_rsp_dec for command response decoder.
+ *
+ * @param[in] p_buf Pointer to the buffer where encoded data command will be returned.
+ * @param[in,out] p_buf_len \c in: Size of \p p_buf buffer.
+ * \c out: Length of the encoded command packet.
+ *
+ * @retval NRF_SUCCESS Encoding success.
+ * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length.
+ */
+uint32_t ble_enable_req_enc(uint8_t * const p_buf,
+ uint32_t * const p_buf_len);
+
+#endif
+
+/**@brief Decodes response to the @ref sd_ble_enable command.
+ *
+ * @sa @ref ble_enable_req_enc for command request encoder.
+ *
+ * @param[in] p_buf Pointer to the beginning of a command response packet.
+ * @param[in] packet_len Length (in bytes) of the response packet.
+ * @param[out] p_result_code Command result code.
+ *
+ * @retval NRF_SUCCESS Success.
+ * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length.
+ * @retval NRF_ERROR_DATA_SIZE Decoding failure. Length of \p p_event is too small to
+ * hold the decoded event.
+ */
+uint32_t ble_enable_rsp_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ uint32_t * const p_result_code);
+/**@brief Encodes the @ref sd_ble_opt_get command request.
+ *
+ * @sa @ref ble_opt_get_rsp_dec for command response decoder.
+ *
+ * @param[in] opt_id Identifies the type of parameter in the ble_opt_t union.
+ * @param[in] p_opt Pointer to the @ref ble_opt_t union to be filled by the response.
+ * @param[in] p_buf Pointer to the buffer where the encoded data command will be returned.
+ * @param[in,out] p_buf_len \c in: Size of \p p_buf buffer.
+ * \c out: Length of the encoded command packet.
+ *
+ * @retval NRF_SUCCESS Encoding success.
+ * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length.
+ * @retval NRF_ERROR_INVALID_PARAM Invalid opt id.
+ */
+uint32_t ble_opt_get_req_enc(uint32_t opt_id,
+ ble_opt_t const * const p_opt,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len);
+
+/**@brief Decodes response to the @ref sd_ble_opt_get command.
+ *
+ * @sa @ref ble_opt_get_req_enc for command request encoder.
+ *
+ * @param[in] p_buf Pointer to the beginning of a command response packet.
+ * @param[in] packet_len Length (in bytes) of the response packet.
+ * @param[out] p_opt_id Pointer to the decoded opt_id.
+ * @param[out] p_opt Pointer to the decoded @ref ble_opt_t union.
+ * @param[out] p_result_code Command result code.
+ *
+ * @retval NRF_SUCCESS Opt stored successfully.
+ * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length.
+ * @retval NRF_ERROR_DATA_SIZE Decoding failure. Length of \p p_event is too small to
+ * hold the decoded event.
+ * @retval NRF_ERROR_INVALID_PARAM Invalid opt id.
+ */
+
+uint32_t ble_opt_get_rsp_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ uint32_t * const p_opt_id,
+ ble_opt_t * const p_opt,
+ uint32_t * const p_result_code);
+
+/**@brief Encodes the @ref sd_ble_user_mem_reply command request.
+ *
+ * @sa @ref ble_user_mem_reply_rsp_dec for command response decoder.
+ *
+ * @param[in] conn_handle Connection handle.
+ * @param[in] p_block Pointer to the @ref ble_user_mem_block_t structure.
+ * @param[in] p_buf Pointer to the buffer where the encoded data command will be returned.
+ * @param[in,out] p_buf_len \c in: Size of \p p_buf buffer.
+ * \c out: Length of the encoded command packet.
+ *
+ * @retval NRF_SUCCESS Encoding success.
+ * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length.
+ * @retval NRF_ERROR_INVALID_PARAM Invalid opt id.
+ */
+uint32_t ble_user_mem_reply_req_enc(uint16_t conn_handle,
+ ble_user_mem_block_t const * p_block,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len);
+
+/**@brief Decodes response to the @ref sd_ble_user_mem_reply command.
+ *
+ * @sa @ref ble_user_mem_reply_req_enc for command request encoder.
+ *
+ * @param[in] p_buf Pointer to the beginning of a command response packet.
+ * @param[in] packet_len Length (in bytes) of the response packet.
+ * @param[out] p_result_code Command result code.
+ *
+ * @retval NRF_SUCCESS Opt stored successfully.
+ * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length.
+ * @retval NRF_ERROR_DATA_SIZE Decoding failure. Length of \p p_event is too small to
+ * hold the decoded event.
+ * @retval NRF_ERROR_INVALID_PARAM Invalid opt id.
+ */
+uint32_t ble_user_mem_reply_rsp_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ uint32_t * const p_result_code);
+#if NRF_SD_BLE_API_VERSION >= 4
+/**@brief Encodes the @ref sd_ble_cfg_set command request.
+ *
+ * @sa @ref ble_cfg_set_rsp_dec for command response decoder.
+ *
+ * @param[in] cfg_id Configuratio id.
+ * @param[in] p_cfg Pointer to the configuration.
+ * @param[in] p_buf Pointer to the buffer where the encoded data command will be returned.
+ * @param[in,out] p_buf_len \c in: Size of \p p_buf buffer.
+ * \c out: Length of the encoded command packet.
+ *
+ * @retval NRF_SUCCESS Encoding success.
+ * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length.
+ * @retval NRF_ERROR_INVALID_PARAM Invalid opt id.
+ */
+uint32_t ble_cfg_set_req_enc(uint32_t cfg_id,
+ ble_cfg_t const * p_cfg,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len);
+
+/**@brief Decodes response to the @ref sd_ble_cfg_set command.
+ *
+ * @sa @ref ble_cfg_set_req_enc for command request encoder.
+ *
+ * @param[in] p_buf Pointer to the beginning of a command response packet.
+ * @param[in] packet_len Length (in bytes) of the response packet.
+ * @param[out] p_result_code Command result code.
+ *
+ * @retval NRF_SUCCESS Opt stored successfully.
+ * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length.
+ * @retval NRF_ERROR_DATA_SIZE Decoding failure. Length of \p p_event is too small to
+ * hold the decoded event.
+ * @retval NRF_ERROR_INVALID_PARAM Invalid opt id.
+ */
+uint32_t ble_cfg_set_rsp_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ uint32_t * const p_result_code);
+#endif //NRF_SD_BLE_API_VERSION >= 4
+
+/**@brief Event decoding dispatcher.
+ *
+ * The event decoding dispatcher will route the event packet to the correct decoder, which in turn
+ * decodes the contents of the event and updates the \p p_event struct.
+ *
+ * If \p p_event is null, the required length of \p p_event is returned in \p p_event_len.
+ *
+ * @param[in] p_buf Pointer to the beginning of the event packet.
+ * @param[in] packet_len Length (in bytes) of the event packet.
+ * @param[in,out] p_event Pointer to the \ref ble_evt_t buffer where the decoded event will be
+ * stored. If NULL, the required length will be returned in \p p_event_len.
+ * @param[in,out] p_event_len \c in: Size (in bytes) of \p p_event buffer.
+ * \c out: Length of the decoded contents of \p p_event.
+ *
+ * @retval NRF_SUCCESS Decoding success.
+ * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length.
+ * @retval NRF_ERROR_DATA_SIZE Decoding failure. Length of \p p_event is too small to
+ * hold the decoded event.
+ * @retval NRF_ERROR_NOT_FOUND Decoding failure. No event decoder is available.
+ */
+uint32_t ble_event_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ ble_evt_t * const p_event,
+ uint32_t * const p_event_len);
+
+/** @} */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/application/codecs/ble/serializers/ble_event.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/application/codecs/ble/serializers/ble_event.c
new file mode 100644
index 0000000..e32a905
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/application/codecs/ble/serializers/ble_event.c
@@ -0,0 +1,316 @@
+/**
+ * Copyright (c) 2014 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#include "ble_serialization.h"
+#include "ble_app.h"
+#include "ble_evt_app.h"
+#include "ble_gap_evt_app.h"
+#include "ble_gattc_evt_app.h"
+#include "ble_gatts_evt_app.h"
+#include "ble_l2cap_evt_app.h"
+#include "app_util.h"
+
+uint32_t ble_event_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ ble_evt_t * const p_event,
+ uint32_t * const p_event_len)
+{
+ uint32_t err_code;
+ SER_ASSERT_NOT_NULL(p_buf);
+ SER_ASSERT_NOT_NULL(p_event_len);
+ SER_ASSERT_LENGTH_LEQ(SER_EVT_HEADER_SIZE, packet_len);
+ SER_ASSERT_NOT_NULL(p_event);
+ SER_ASSERT_LENGTH_LEQ(sizeof (ble_evt_hdr_t), *p_event_len);
+ *p_event_len -= sizeof (ble_evt_hdr_t);
+
+ const uint16_t event_id = uint16_decode(&p_buf[SER_EVT_ID_POS]);
+ const uint8_t * p_sub_buffer = &p_buf[SER_EVT_HEADER_SIZE];
+ const uint32_t sub_packet_len = packet_len - SER_EVT_HEADER_SIZE;
+
+ uint32_t (*fp_event_decoder)(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ ble_evt_t * const p_event,
+ uint32_t * const p_event_len) = NULL;
+
+ switch (event_id)
+ {
+#if defined(NRF_SD_BLE_API_VERSION) && NRF_SD_BLE_API_VERSION < 4
+ case BLE_EVT_TX_COMPLETE:
+ fp_event_decoder = ble_evt_tx_complete_dec;
+ break;
+ case BLE_EVT_DATA_LENGTH_CHANGED:
+ fp_event_decoder = ble_evt_data_length_changed_dec;
+ break;
+#endif
+ case BLE_EVT_USER_MEM_REQUEST:
+ fp_event_decoder = ble_evt_user_mem_request_dec;
+ break;
+
+ case BLE_EVT_USER_MEM_RELEASE:
+ fp_event_decoder = ble_evt_user_mem_release_dec;
+ break;
+
+
+ case BLE_GAP_EVT_PASSKEY_DISPLAY:
+ fp_event_decoder = ble_gap_evt_passkey_display_dec;
+ break;
+
+ case BLE_GAP_EVT_AUTH_KEY_REQUEST:
+ fp_event_decoder = ble_gap_evt_auth_key_request_dec;
+ break;
+
+ case BLE_GAP_EVT_CONN_PARAM_UPDATE:
+ fp_event_decoder = ble_gap_evt_conn_param_update_dec;
+ break;
+
+#ifndef S112
+ case BLE_GAP_EVT_CONN_PARAM_UPDATE_REQUEST:
+ fp_event_decoder = ble_gap_evt_conn_param_update_request_dec;
+ break;
+#endif
+ case BLE_GAP_EVT_CONN_SEC_UPDATE:
+ fp_event_decoder = ble_gap_evt_conn_sec_update_dec;
+ break;
+
+ case BLE_GAP_EVT_CONNECTED:
+ fp_event_decoder = ble_gap_evt_connected_dec;
+ break;
+
+ case BLE_GAP_EVT_DISCONNECTED:
+ fp_event_decoder = ble_gap_evt_disconnected_dec;
+ break;
+
+ case BLE_GAP_EVT_TIMEOUT:
+ fp_event_decoder = ble_gap_evt_timeout_dec;
+ break;
+
+ case BLE_GAP_EVT_RSSI_CHANGED:
+ fp_event_decoder = ble_gap_evt_rssi_changed_dec;
+ break;
+
+ case BLE_GAP_EVT_SEC_INFO_REQUEST:
+ fp_event_decoder = ble_gap_evt_sec_info_request_dec;
+ break;
+
+ case BLE_GAP_EVT_SEC_PARAMS_REQUEST:
+ fp_event_decoder = ble_gap_evt_sec_params_request_dec;
+ break;
+
+ case BLE_GAP_EVT_AUTH_STATUS:
+ fp_event_decoder = ble_gap_evt_auth_status_dec;
+ break;
+
+ case BLE_GAP_EVT_SEC_REQUEST:
+ fp_event_decoder = ble_gap_evt_sec_request_dec;
+ break;
+
+ case BLE_GAP_EVT_KEY_PRESSED:
+ fp_event_decoder = ble_gap_evt_key_pressed_dec;
+ break;
+
+ case BLE_GAP_EVT_LESC_DHKEY_REQUEST:
+ fp_event_decoder = ble_gap_evt_lesc_dhkey_request_dec;
+ break;
+#if NRF_SD_BLE_API_VERSION >= 5
+ case BLE_GAP_EVT_PHY_UPDATE:
+ fp_event_decoder = ble_gap_evt_phy_update_dec;
+ break;
+ case BLE_GAP_EVT_PHY_UPDATE_REQUEST:
+ fp_event_decoder = ble_gap_evt_phy_update_request_dec;
+ break;
+#endif
+#if NRF_SD_BLE_API_VERSION >= 4 && !defined(S112)
+ case BLE_GAP_EVT_DATA_LENGTH_UPDATE_REQUEST:
+ fp_event_decoder = ble_gap_evt_data_length_update_request_dec;
+ break;
+ case BLE_GAP_EVT_DATA_LENGTH_UPDATE:
+ fp_event_decoder = ble_gap_evt_data_length_update_dec;
+ break;
+#endif
+ case BLE_GATTC_EVT_CHAR_DISC_RSP:
+ fp_event_decoder = ble_gattc_evt_char_disc_rsp_dec;
+ break;
+
+ case BLE_GATTC_EVT_CHAR_VAL_BY_UUID_READ_RSP:
+ fp_event_decoder = ble_gattc_evt_char_val_by_uuid_read_rsp_dec;
+ break;
+
+ case BLE_GATTC_EVT_DESC_DISC_RSP:
+ fp_event_decoder = ble_gattc_evt_desc_disc_rsp_dec;
+ break;
+
+ case BLE_GATTC_EVT_PRIM_SRVC_DISC_RSP:
+ fp_event_decoder = ble_gattc_evt_prim_srvc_disc_rsp_dec;
+ break;
+
+ case BLE_GATTC_EVT_READ_RSP:
+ fp_event_decoder = ble_gattc_evt_read_rsp_dec;
+ break;
+
+ case BLE_GATTC_EVT_HVX:
+ fp_event_decoder = ble_gattc_evt_hvx_dec;
+ break;
+
+ case BLE_GATTC_EVT_TIMEOUT:
+ fp_event_decoder = ble_gattc_evt_timeout_dec;
+ break;
+
+ case BLE_GATTC_EVT_WRITE_RSP:
+ fp_event_decoder = ble_gattc_evt_write_rsp_dec;
+ break;
+
+ case BLE_GATTC_EVT_CHAR_VALS_READ_RSP:
+ fp_event_decoder = ble_gattc_evt_char_vals_read_rsp_dec;
+ break;
+
+ case BLE_GATTC_EVT_REL_DISC_RSP:
+ fp_event_decoder = ble_gattc_evt_rel_disc_rsp_dec;
+ break;
+
+ case BLE_GATTC_EVT_ATTR_INFO_DISC_RSP:
+ fp_event_decoder = ble_gattc_evt_attr_info_disc_rsp_dec;
+ break;
+
+ case BLE_GATTC_EVT_EXCHANGE_MTU_RSP:
+ fp_event_decoder = ble_gattc_evt_exchange_mtu_rsp_dec;
+ break;
+#if NRF_SD_BLE_API_VERSION >= 4
+ case BLE_GATTC_EVT_WRITE_CMD_TX_COMPLETE:
+ fp_event_decoder = ble_gattc_evt_write_cmd_tx_complete_dec;
+ break;
+#endif
+ case BLE_GATTS_EVT_WRITE:
+ fp_event_decoder = ble_gatts_evt_write_dec;
+ break;
+
+ case BLE_GATTS_EVT_TIMEOUT:
+ fp_event_decoder = ble_gatts_evt_timeout_dec;
+ break;
+
+ case BLE_GATTS_EVT_SC_CONFIRM:
+ fp_event_decoder = ble_gatts_evt_sc_confirm_dec;
+ break;
+
+ case BLE_GATTS_EVT_HVC:
+ fp_event_decoder = ble_gatts_evt_hvc_dec;
+ break;
+
+ case BLE_GATTS_EVT_SYS_ATTR_MISSING:
+ fp_event_decoder = ble_gatts_evt_sys_attr_missing_dec;
+ break;
+
+ case BLE_GATTS_EVT_RW_AUTHORIZE_REQUEST:
+ fp_event_decoder = ble_gatts_evt_rw_authorize_request_dec;
+ break;
+
+ case BLE_GATTS_EVT_EXCHANGE_MTU_REQUEST:
+ fp_event_decoder = ble_gatts_evt_exchange_mtu_request_dec;
+ break;
+#if NRF_SD_BLE_API_VERSION >= 4
+ case BLE_GATTS_EVT_HVN_TX_COMPLETE:
+ fp_event_decoder = ble_gatts_evt_hvn_tx_complete_dec;
+ break;
+#endif
+#if defined(NRF_SD_BLE_API_VERSION) && NRF_SD_BLE_API_VERSION < 4
+ case BLE_L2CAP_EVT_RX:
+ fp_event_decoder = ble_l2cap_evt_rx_dec;
+ break;
+#endif
+
+#if defined(NRF_SD_BLE_API_VERSION) && NRF_SD_BLE_API_VERSION >= 5 && !defined(S112)
+ case BLE_L2CAP_EVT_CH_SETUP_REQUEST:
+ fp_event_decoder = ble_l2cap_evt_ch_setup_request_dec;
+ break;
+
+ case BLE_L2CAP_EVT_CH_SETUP_REFUSED:
+ fp_event_decoder = ble_l2cap_evt_ch_setup_refused_dec;
+ break;
+
+ case BLE_L2CAP_EVT_CH_SETUP:
+ fp_event_decoder = ble_l2cap_evt_ch_setup_dec;
+ break;
+
+ case BLE_L2CAP_EVT_CH_RELEASED:
+ fp_event_decoder = ble_l2cap_evt_ch_released_dec;
+ break;
+
+ case BLE_L2CAP_EVT_CH_SDU_BUF_RELEASED:
+ fp_event_decoder = ble_l2cap_evt_ch_sdu_buf_released_dec;
+ break;
+
+ case BLE_L2CAP_EVT_CH_CREDIT:
+ fp_event_decoder = ble_l2cap_evt_ch_credit_dec;
+ break;
+
+ case BLE_L2CAP_EVT_CH_RX:
+ fp_event_decoder = ble_l2cap_evt_ch_rx_dec;
+ break;
+
+ case BLE_L2CAP_EVT_CH_TX:
+ fp_event_decoder = ble_l2cap_evt_ch_tx_dec;
+ break;
+
+#endif
+#ifndef S112
+ case BLE_GAP_EVT_ADV_REPORT:
+ fp_event_decoder = ble_gap_evt_adv_report_dec;
+ break;
+#endif
+ case BLE_GAP_EVT_SCAN_REQ_REPORT:
+ fp_event_decoder = ble_gap_evt_scan_req_report_dec;
+ break;
+ default:
+ break;
+ }
+
+ if (fp_event_decoder)
+ {
+ err_code = fp_event_decoder(p_sub_buffer, sub_packet_len, p_event, p_event_len);
+ }
+ else
+ {
+ err_code = NRF_ERROR_NOT_FOUND;
+ }
+
+ *p_event_len += offsetof(ble_evt_t, evt);
+ p_event->header.evt_id = (err_code == NRF_SUCCESS) ? event_id : 0;
+ p_event->header.evt_len = (err_code == NRF_SUCCESS) ? (uint16_t)*p_event_len : 0;
+
+ return err_code;
+}
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/application/codecs/ble/serializers/ble_evt_app.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/application/codecs/ble/serializers/ble_evt_app.c
new file mode 100644
index 0000000..a5964c6
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/application/codecs/ble/serializers/ble_evt_app.c
@@ -0,0 +1,129 @@
+/**
+ * Copyright (c) 2015 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#include "ble_serialization.h"
+#include "ble_struct_serialization.h"
+#include "cond_field_serialization.h"
+#include "app_util.h"
+#include "ble_evt_app.h"
+#include "app_ble_user_mem.h"
+
+
+// Helper definitions for common event type names to be compliant with
+// event serialization macros.
+#define ble_common_evt_tx_complete_t ble_evt_tx_complete_t
+#define ble_common_evt_user_mem_request_t ble_evt_user_mem_request_t
+#define ble_common_evt_user_mem_release_t ble_evt_user_mem_release_t
+#define ble_common_evt_data_length_changed_t ble_evt_data_length_changed_t
+
+
+extern ser_ble_user_mem_t m_app_user_mem_table[];
+
+uint32_t ble_evt_user_mem_release_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ ble_evt_t * const p_event,
+ uint32_t * const p_event_len)
+{
+ SER_EVT_DEC_BEGIN(BLE_EVT_USER_MEM_RELEASE, common, user_mem_release);
+
+ SER_PULL_uint16(&p_event->evt.common_evt.conn_handle);
+ SER_PULL_uint8(&p_event->evt.common_evt.params.user_mem_release.type);
+ SER_PULL_uint16(&p_event->evt.common_evt.params.user_mem_release.mem_block.len);
+
+ //Set the memory pointer to not-null value.
+ p_event->evt.common_evt.params.user_mem_release.mem_block.p_mem = (uint8_t *)~0;
+ SER_PULL_COND(&p_event->evt.common_evt.params.user_mem_release.mem_block.p_mem, NULL);
+ if (p_event->evt.common_evt.params.user_mem_release.mem_block.p_mem)
+ {
+ // Using connection handle find which mem block to release in Application Processor
+ uint32_t user_mem_table_index;
+ err_code = app_ble_user_mem_context_find(p_event->evt.common_evt.conn_handle, &user_mem_table_index);
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code);
+ p_event->evt.common_evt.params.user_mem_release.mem_block.p_mem =
+ m_app_user_mem_table[user_mem_table_index].mem_block.p_mem;
+ }
+
+ // Now user memory context can be released
+ err_code = app_ble_user_mem_context_destroy(p_event->evt.common_evt.conn_handle);
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code);
+
+ SER_EVT_DEC_END;
+}
+
+uint32_t ble_evt_user_mem_request_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ ble_evt_t * const p_event,
+ uint32_t * const p_event_len)
+{
+ SER_EVT_DEC_BEGIN(BLE_EVT_USER_MEM_REQUEST, common, user_mem_request);
+
+ SER_PULL_uint16(&p_event->evt.common_evt.conn_handle);
+ SER_PULL_uint8(&p_event->evt.common_evt.params.user_mem_request.type);
+
+ SER_EVT_DEC_END;
+}
+
+#if defined(NRF_SD_BLE_API_VERSION) && NRF_SD_BLE_API_VERSION < 4
+uint32_t ble_evt_tx_complete_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ ble_evt_t * const p_event,
+ uint32_t * const p_event_len)
+{
+ SER_EVT_DEC_BEGIN(BLE_EVT_TX_COMPLETE, common, tx_complete);
+
+ SER_PULL_uint16(&p_event->evt.common_evt.conn_handle);
+ SER_PULL_uint8(&p_event->evt.common_evt.params.tx_complete.count);
+
+ SER_EVT_DEC_END;
+}
+
+
+uint32_t ble_evt_data_length_changed_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ ble_evt_t * const p_event,
+ uint32_t * const p_event_len)
+{
+ SER_EVT_DEC_BEGIN(BLE_EVT_DATA_LENGTH_CHANGED, common, data_length_changed);
+
+ SER_PULL_uint16(&p_event->evt.common_evt.conn_handle);
+ SER_PULL_FIELD(&p_event->evt.common_evt.params.data_length_changed, ble_evt_data_length_changed_t_dec);
+
+ SER_EVT_DEC_END;
+}
+#endif
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/application/codecs/ble/serializers/ble_evt_app.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/application/codecs/ble/serializers/ble_evt_app.h
new file mode 100644
index 0000000..67b6135
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/application/codecs/ble/serializers/ble_evt_app.h
@@ -0,0 +1,157 @@
+/**
+ * Copyright (c) 2014 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#ifndef BLE_EVT_APP_H__
+#define BLE_EVT_APP_H__
+
+/**@file
+ *
+ * @defgroup ble_evt_app Application event decoders
+ * @{
+ * @ingroup ser_app_s130_codecs
+ *
+ * @brief Application event decoders.
+ */
+#include "ble.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#if defined(NRF_SD_BLE_API_VERSION) && NRF_SD_BLE_API_VERSION < 4
+/**
+ * @brief Decodes the ble_evt_tx_complete event.
+ *
+ * If \p p_event is null, the required length of \p p_event is returned in \p p_event_len.
+ *
+ * @param[in] p_buf Pointer to the beginning of the event packet.
+ * @param[in] packet_len Length (in bytes) of the event packet.
+ * @param[in,out] p_event Pointer to the \ref ble_evt_t buffer where the decoded event will be
+ * stored. If NULL, the required length will be returned in \p p_event_len.
+ * @param[in,out] p_event_len \c in: Size (in bytes) of the \p p_event buffer.
+ * \c out: Length of the decoded contents of \p p_event.
+ *
+ * @retval NRF_SUCCESS Decoding success.
+ * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length.
+ * @retval NRF_ERROR_DATA_SIZE Decoding failure. Length of \p p_event is too small to
+ * hold the decoded event.
+ */
+uint32_t ble_evt_tx_complete_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ ble_evt_t * const p_event,
+ uint32_t * const p_event_len);
+#endif
+/**
+ * @brief Decodes the ble_evt_user_mem_request event.
+ *
+ * If \p p_event is null, the required length of \p p_event is returned in \p p_event_len.
+ *
+ * @param[in] p_buf Pointer to the beginning of the event packet.
+ * @param[in] packet_len Length (in bytes) of the event packet.
+ * @param[in,out] p_event Pointer to the \ref ble_evt_t buffer where the decoded event will be
+ * stored. If NULL, the required length will be returned in \p p_event_len.
+ * @param[in,out] p_event_len \c in: Size (in bytes) of the \p p_event buffer.
+ * \c out: Length of the decoded contents of \p p_event.
+ *
+ * @retval NRF_SUCCESS Decoding success.
+ * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length.
+ * @retval NRF_ERROR_DATA_SIZE Decoding failure. Length of \p p_event is too small to
+ * hold the decoded event.
+ */
+uint32_t ble_evt_user_mem_request_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ ble_evt_t * const p_event,
+ uint32_t * const p_event_len);
+
+/**
+ * @brief Decodes the ble_evt_user_mem_release event.
+ *
+ * If \p p_event is null, the required length of \p p_event is returned in \p p_event_len.
+ *
+ * @param[in] p_buf Pointer to the beginning of the event packet.
+ * @param[in] packet_len Length (in bytes) of the event packet.
+ * @param[in,out] p_event Pointer to the \ref ble_evt_t buffer where the decoded event will be
+ * stored. If NULL, the required length will be returned in \p p_event_len.
+ * @param[in,out] p_event_len \c in: Size (in bytes) of the \p p_event buffer.
+ * \c out: Length of the decoded contents of \p p_event.
+ *
+ * @retval NRF_SUCCESS Decoding success.
+ * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length.
+ * @retval NRF_ERROR_DATA_SIZE Decoding failure. Length of \p p_event is too small to
+ * hold the decoded event.
+ */
+uint32_t ble_evt_user_mem_release_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ ble_evt_t * const p_event,
+ uint32_t * const p_event_len);
+#if defined(NRF_SD_BLE_API_VERSION) && NRF_SD_BLE_API_VERSION < 4
+/**
+ * @brief Decodes the ble_evt_data_length_changed event.
+ *
+ * If \p p_event is null, the required length of \p p_event is returned in \p p_event_len.
+ *
+ * @param[in] p_buf Pointer to the beginning of the event packet.
+ * @param[in] packet_len Length (in bytes) of the event packet.
+ * @param[in,out] p_event Pointer to the \ref ble_evt_t buffer where the decoded event will be
+ * stored. If NULL, the required length will be returned in \p p_event_len.
+ * @param[in,out] p_event_len \c in: Size (in bytes) of the \p p_event buffer.
+ * \c out: Length of the decoded contents of \p p_event.
+ *
+ * @retval NRF_SUCCESS Decoding success.
+ * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length.
+ * @retval NRF_ERROR_DATA_SIZE Decoding failure. Length of \p p_event is too small to
+ * hold the decoded event.
+ */
+uint32_t ble_evt_data_length_changed_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ ble_evt_t * const p_event,
+ uint32_t * const p_event_len);
+#endif
+
+/** @} */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/application/codecs/ble/serializers/ble_gap_app.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/application/codecs/ble/serializers/ble_gap_app.c
new file mode 100644
index 0000000..ca227e0
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/application/codecs/ble/serializers/ble_gap_app.c
@@ -0,0 +1,1019 @@
+/**
+ * Copyright (c) 2013 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#include "ble_gap_app.h"
+#include <stdlib.h>
+#include <string.h>
+#include "ble_serialization.h"
+#include "ble_gap_struct_serialization.h"
+#include "ble_struct_serialization.h"
+#include "cond_field_serialization.h"
+#include "app_util.h"
+
+#if defined(NRF_SD_BLE_API_VERSION) && NRF_SD_BLE_API_VERSION < 6
+uint32_t ble_gap_adv_data_set_req_enc(uint8_t const * const p_data,
+ uint8_t dlen,
+ uint8_t const * const p_sr_data,
+ uint8_t srdlen,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len)
+{
+ SER_REQ_ENC_BEGIN(SD_BLE_GAP_ADV_DATA_SET);
+
+ SER_PUSH_len8data(p_data, dlen);
+ SER_PUSH_len8data(p_sr_data, srdlen);
+
+ SER_REQ_ENC_END;
+}
+
+
+uint32_t ble_gap_adv_data_set_rsp_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ uint32_t * const p_result_code)
+{
+ SER_RSP_DEC_RESULT_ONLY(SD_BLE_GAP_ADV_DATA_SET);
+}
+#endif
+
+uint32_t ble_gap_adv_start_req_enc(
+#if NRF_SD_BLE_API_VERSION > 5
+ uint8_t adv_handle,
+#else
+ ble_gap_adv_params_t const * const p_adv_params,
+#endif
+#if NRF_SD_BLE_API_VERSION >= 4
+ uint8_t conn_cfg_tag,
+#endif
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len)
+{
+ SER_REQ_ENC_BEGIN(SD_BLE_GAP_ADV_START);
+
+#if NRF_SD_BLE_API_VERSION > 5
+ SER_PUSH_uint8(&adv_handle);
+#else
+ SER_PUSH_COND(p_adv_params, ble_gap_adv_params_t_enc);
+#endif
+
+#if NRF_SD_BLE_API_VERSION >= 4
+ SER_PUSH_uint8(&conn_cfg_tag);
+#endif
+ SER_REQ_ENC_END;
+}
+
+
+uint32_t ble_gap_adv_start_rsp_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ uint32_t * const p_result_code)
+{
+ SER_RSP_DEC_RESULT_ONLY(SD_BLE_GAP_ADV_START);
+}
+
+
+uint32_t ble_gap_adv_stop_req_enc(
+#if NRF_SD_BLE_API_VERSION > 5
+ uint8_t adv_handle,
+#endif
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len)
+{
+ SER_REQ_ENC_BEGIN(SD_BLE_GAP_ADV_STOP);
+#if NRF_SD_BLE_API_VERSION > 5
+ SER_PUSH_uint8(&adv_handle);
+#endif
+ SER_REQ_ENC_END;
+}
+
+uint32_t ble_gap_adv_stop_rsp_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ uint32_t * const p_result_code)
+{
+ SER_RSP_DEC_RESULT_ONLY(SD_BLE_GAP_ADV_STOP);
+}
+
+
+
+uint32_t ble_gap_appearance_get_req_enc(uint16_t const * const p_appearance,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len)
+{
+ SER_REQ_ENC_BEGIN(SD_BLE_GAP_APPEARANCE_GET);
+ SER_PUSH_COND(p_appearance, NULL);
+ SER_REQ_ENC_END;
+}
+
+
+uint32_t ble_gap_appearance_get_rsp_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ uint16_t * const p_appearance,
+ uint32_t * const p_result_code)
+{
+ SER_RSP_DEC_BEGIN(SD_BLE_GAP_APPEARANCE_GET);
+ SER_PULL_COND(&p_appearance, uint16_t_dec);
+ SER_RSP_DEC_END;
+}
+
+
+uint32_t ble_gap_appearance_set_req_enc(uint16_t appearance,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len)
+{
+ SER_REQ_ENC_BEGIN(SD_BLE_GAP_APPEARANCE_SET);
+ SER_PUSH_uint16(&appearance);
+ SER_REQ_ENC_END;
+}
+
+
+uint32_t ble_gap_appearance_set_rsp_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ uint32_t * const p_result_code)
+{
+ SER_RSP_DEC_RESULT_ONLY(SD_BLE_GAP_APPEARANCE_SET);
+}
+
+
+uint32_t ble_gap_auth_key_reply_req_enc(uint16_t conn_handle,
+ uint8_t key_type,
+ uint8_t const * const p_key,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len)
+{
+ SER_REQ_ENC_BEGIN(SD_BLE_GAP_AUTH_KEY_REPLY);
+
+ uint8_t key_len;
+ switch (key_type)
+ {
+ case BLE_GAP_AUTH_KEY_TYPE_NONE:
+ key_len = 0;
+ break;
+
+ case BLE_GAP_AUTH_KEY_TYPE_PASSKEY:
+ key_len = 6;
+ break;
+
+ case BLE_GAP_AUTH_KEY_TYPE_OOB:
+ key_len = 16;
+ break;
+
+ default:
+ return NRF_ERROR_INVALID_PARAM;
+ }
+
+ SER_PUSH_uint16(&conn_handle);
+ SER_PUSH_uint8(&key_type);
+ SER_PUSH_buf(p_key, key_len);
+
+ SER_REQ_ENC_END;
+}
+
+
+uint32_t ble_gap_auth_key_reply_rsp_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ uint32_t * const p_result_code)
+{
+ SER_RSP_DEC_RESULT_ONLY(SD_BLE_GAP_AUTH_KEY_REPLY);
+}
+
+
+
+uint32_t ble_gap_authenticate_req_enc(uint16_t conn_handle,
+ ble_gap_sec_params_t const * const p_sec_params,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len)
+{
+ SER_REQ_ENC_BEGIN(SD_BLE_GAP_AUTHENTICATE);
+
+ SER_PUSH_uint16(&conn_handle);
+ SER_PUSH_COND(p_sec_params, ble_gap_sec_params_t_enc);
+
+ SER_REQ_ENC_END;
+}
+
+
+uint32_t ble_gap_authenticate_rsp_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ uint32_t * const p_result_code)
+{
+ SER_RSP_DEC_RESULT_ONLY(SD_BLE_GAP_AUTHENTICATE);
+}
+
+
+uint32_t ble_gap_conn_param_update_req_enc(uint16_t conn_handle,
+ ble_gap_conn_params_t const * const p_conn_params,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len)
+{
+ SER_REQ_ENC_BEGIN(SD_BLE_GAP_CONN_PARAM_UPDATE);
+
+ SER_PUSH_uint16(&conn_handle);
+ SER_PUSH_COND(p_conn_params, ble_gap_conn_params_t_enc);
+
+ SER_REQ_ENC_END;
+}
+
+
+uint32_t ble_gap_conn_param_update_rsp_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ uint32_t * const p_result_code)
+{
+ SER_RSP_DEC_RESULT_ONLY(SD_BLE_GAP_CONN_PARAM_UPDATE);
+}
+
+
+uint32_t ble_gap_conn_sec_get_req_enc(uint16_t conn_handle,
+ ble_gap_conn_sec_t const * const p_conn_sec,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len)
+{
+ SER_REQ_ENC_BEGIN(SD_BLE_GAP_CONN_SEC_GET);
+
+ SER_PUSH_uint16(&conn_handle);
+ SER_PUSH_COND(p_conn_sec, NULL);
+
+ SER_REQ_ENC_END;
+}
+
+
+uint32_t ble_gap_conn_sec_get_rsp_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ ble_gap_conn_sec_t * * const pp_conn_sec,
+ uint32_t * const p_result_code)
+{
+ SER_RSP_DEC_BEGIN(SD_BLE_GAP_CONN_SEC_GET);
+ SER_PULL_COND(pp_conn_sec, ble_gap_conn_sec_t_dec);
+ SER_RSP_DEC_END;
+}
+
+#ifndef S112
+uint32_t ble_gap_connect_req_enc(ble_gap_addr_t const * const p_peer_addr,
+ ble_gap_scan_params_t const * const p_scan_params,
+ ble_gap_conn_params_t const * const p_conn_params,
+#if NRF_SD_BLE_API_VERSION >= 4
+ uint8_t conn_cfg_tag,
+#endif
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len)
+{
+ SER_REQ_ENC_BEGIN(SD_BLE_GAP_CONNECT);
+
+ SER_PUSH_COND(p_peer_addr, ble_gap_addr_t_enc);
+ SER_PUSH_COND(p_scan_params, ble_gap_scan_params_t_enc);
+ SER_PUSH_COND(p_conn_params, ble_gap_conn_params_t_enc);
+#if NRF_SD_BLE_API_VERSION >= 4
+ SER_PUSH_uint8(&conn_cfg_tag);
+#endif
+
+ SER_REQ_ENC_END;
+}
+
+uint32_t ble_gap_connect_rsp_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ uint32_t * const p_result_code)
+{
+ SER_RSP_DEC_RESULT_ONLY(SD_BLE_GAP_CONNECT);
+}
+
+
+uint32_t ble_gap_connect_cancel_req_enc(uint8_t * const p_buf,
+ uint32_t * const p_buf_len)
+{
+ SER_REQ_ENC_BEGIN(SD_BLE_GAP_CONNECT_CANCEL);
+ SER_REQ_ENC_END;
+}
+
+uint32_t ble_gap_connect_cancel_rsp_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ uint32_t * const p_result_code)
+{
+ SER_RSP_DEC_RESULT_ONLY(SD_BLE_GAP_CONNECT_CANCEL);
+}
+#endif
+
+uint32_t ble_gap_device_name_get_req_enc(uint8_t const * const p_dev_name,
+ uint16_t const * const p_len,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len)
+{
+ SER_REQ_ENC_BEGIN(SD_BLE_GAP_DEVICE_NAME_GET);
+
+ SER_PUSH_COND(p_len, uint16_t_enc);
+ SER_PUSH_COND(p_dev_name, NULL);
+
+ SER_REQ_ENC_END;
+}
+
+uint32_t ble_gap_device_name_get_rsp_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ uint8_t * const p_dev_name,
+ uint16_t * const p_dev_name_len,
+ uint32_t * const p_result_code)
+{
+ SER_RSP_DEC_BEGIN(SD_BLE_GAP_DEVICE_NAME_GET);
+
+ SER_PULL_COND(&p_dev_name_len, uint16_t_dec);
+ if (p_dev_name_len)
+ {
+ SER_PULL_uint8array(p_dev_name, *p_dev_name_len);
+ }
+
+ SER_RSP_DEC_END;
+}
+
+
+uint32_t ble_gap_device_name_set_req_enc(ble_gap_conn_sec_mode_t const * const p_write_perm,
+ uint8_t const * const p_dev_name,
+ uint16_t len,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len)
+{
+ SER_REQ_ENC_BEGIN(SD_BLE_GAP_DEVICE_NAME_SET);
+
+ SER_ERROR_CHECK(len <= BLE_GAP_DEVNAME_MAX_LEN, NRF_ERROR_INVALID_PARAM);
+
+ SER_PUSH_COND(p_write_perm, ble_gap_conn_sec_mode_t_enc);
+ SER_PUSH_len16data(p_dev_name, len);
+
+ SER_REQ_ENC_END;
+}
+
+
+uint32_t ble_gap_device_name_set_rsp_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ uint32_t * const p_result_code)
+{
+ SER_RSP_DEC_RESULT_ONLY(SD_BLE_GAP_DEVICE_NAME_SET);
+}
+
+
+uint32_t ble_gap_disconnect_req_enc(uint16_t conn_handle,
+ uint8_t hci_status_code,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len)
+{
+ SER_REQ_ENC_BEGIN(SD_BLE_GAP_DISCONNECT);
+
+ SER_PUSH_uint16(&conn_handle);
+ SER_PUSH_uint8(&hci_status_code);
+
+ SER_REQ_ENC_END;
+}
+
+
+uint32_t ble_gap_disconnect_rsp_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ uint32_t * const p_result_code)
+{
+ SER_RSP_DEC_RESULT_ONLY(SD_BLE_GAP_DISCONNECT);
+}
+
+#ifndef S112
+uint32_t ble_gap_encrypt_req_enc(uint16_t conn_handle,
+ ble_gap_master_id_t const * const p_master_id,
+ ble_gap_enc_info_t const * const p_enc_info,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len)
+{
+ SER_REQ_ENC_BEGIN(SD_BLE_GAP_ENCRYPT);
+
+ SER_PUSH_uint16(&conn_handle);
+ SER_PUSH_COND(p_master_id, ble_gap_master_id_t_enc);
+ SER_PUSH_COND(p_enc_info, ble_gap_enc_info_t_enc);
+
+ SER_REQ_ENC_END;
+}
+
+
+uint32_t ble_gap_encrypt_rsp_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ uint32_t * const p_result_code)
+{
+ SER_RSP_DEC_RESULT_ONLY(SD_BLE_GAP_ENCRYPT);
+}
+#endif
+
+uint32_t ble_gap_keypress_notify_req_enc(uint16_t conn_handle,
+ uint8_t kp_not,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len)
+{
+ SER_REQ_ENC_BEGIN(SD_BLE_GAP_KEYPRESS_NOTIFY);
+
+ SER_PUSH_uint16(&conn_handle);
+ SER_PUSH_uint8(&kp_not);
+
+ SER_REQ_ENC_END;
+}
+
+uint32_t ble_gap_keypress_notify_rsp_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ uint32_t * const p_result_code)
+{
+ SER_RSP_DEC_RESULT_ONLY(SD_BLE_GAP_KEYPRESS_NOTIFY);
+}
+
+
+uint32_t ble_gap_lesc_dhkey_reply_req_enc(uint16_t conn_handle,
+ ble_gap_lesc_dhkey_t const *p_dhkey,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len)
+{
+ SER_REQ_ENC_BEGIN(SD_BLE_GAP_LESC_DHKEY_REPLY);
+
+ SER_PUSH_uint16(&conn_handle);
+ SER_PUSH_COND(p_dhkey, ble_gap_lesc_dhkey_t_enc);
+
+ SER_REQ_ENC_END;
+}
+
+uint32_t ble_gap_lesc_dhkey_reply_rsp_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ uint32_t * const p_result_code)
+{
+ SER_RSP_DEC_RESULT_ONLY(SD_BLE_GAP_LESC_DHKEY_REPLY);
+}
+
+
+uint32_t ble_gap_lesc_oob_data_get_req_enc(uint16_t conn_handle,
+ ble_gap_lesc_p256_pk_t const *p_pk_own,
+ ble_gap_lesc_oob_data_t *p_oobd_own,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len)
+{
+ SER_REQ_ENC_BEGIN(SD_BLE_GAP_LESC_OOB_DATA_GET);
+
+ SER_PUSH_uint16(&conn_handle);
+ SER_PUSH_COND(p_pk_own, ble_gap_lesc_p256_pk_t_enc);
+ SER_PUSH_COND(p_oobd_own, NULL);
+
+ SER_REQ_ENC_END;
+}
+
+uint32_t ble_gap_lesc_oob_data_get_rsp_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ ble_gap_lesc_oob_data_t * *pp_oobd_own,
+ uint32_t * const p_result_code)
+{
+ SER_RSP_DEC_BEGIN(SD_BLE_GAP_LESC_OOB_DATA_GET);
+ SER_PULL_COND(pp_oobd_own, ble_gap_lesc_oob_data_t_dec);
+ SER_RSP_DEC_END;
+}
+
+
+uint32_t ble_gap_lesc_oob_data_set_req_enc(uint16_t conn_handle,
+ ble_gap_lesc_oob_data_t const *p_oobd_own,
+ ble_gap_lesc_oob_data_t const *p_oobd_peer,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len)
+{
+ SER_REQ_ENC_BEGIN(SD_BLE_GAP_LESC_OOB_DATA_SET);
+
+ SER_PUSH_uint16(&conn_handle);
+ SER_PUSH_COND(p_oobd_own, ble_gap_lesc_oob_data_t_enc);
+ SER_PUSH_COND(p_oobd_peer, ble_gap_lesc_oob_data_t_enc);
+
+ SER_REQ_ENC_END;
+}
+
+uint32_t ble_gap_lesc_oob_data_set_rsp_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ uint32_t * const p_result_code)
+{
+ SER_RSP_DEC_RESULT_ONLY(SD_BLE_GAP_LESC_OOB_DATA_SET);
+}
+
+
+uint32_t ble_gap_ppcp_get_req_enc(ble_gap_conn_params_t const * const p_conn_params,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len)
+{
+ SER_REQ_ENC_BEGIN(SD_BLE_GAP_PPCP_GET);
+ SER_PUSH_COND(p_conn_params, NULL);
+ SER_REQ_ENC_END;
+}
+
+uint32_t ble_gap_ppcp_get_rsp_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ ble_gap_conn_params_t * const p_conn_params,
+ uint32_t * const p_result_code)
+{
+ SER_RSP_DEC_BEGIN(SD_BLE_GAP_PPCP_GET);
+ SER_PULL_COND(&p_conn_params, ble_gap_conn_params_t_dec);
+ SER_RSP_DEC_END;
+}
+
+
+uint32_t ble_gap_ppcp_set_req_enc(ble_gap_conn_params_t const * const p_conn_params,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len)
+{
+ SER_REQ_ENC_BEGIN(SD_BLE_GAP_PPCP_SET);
+ SER_PUSH_COND(p_conn_params, ble_gap_conn_params_t_enc);
+ SER_REQ_ENC_END;
+}
+
+
+uint32_t ble_gap_ppcp_set_rsp_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ uint32_t * const p_result_code)
+{
+ SER_RSP_DEC_RESULT_ONLY(SD_BLE_GAP_PPCP_SET);
+}
+
+uint32_t ble_gap_rssi_get_req_enc(uint16_t conn_handle,
+ int8_t const * const p_rssi,
+#if NRF_SD_BLE_API_VERSION > 5
+ uint8_t const * const p_ch_index,
+#endif
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len)
+{
+ SER_REQ_ENC_BEGIN(SD_BLE_GAP_RSSI_GET);
+
+ SER_PUSH_uint16(&conn_handle);
+ SER_PUSH_COND(p_rssi, NULL);
+#if NRF_SD_BLE_API_VERSION > 5
+ SER_PUSH_COND(p_ch_index, NULL);
+#endif
+ SER_REQ_ENC_END;
+}
+
+
+uint32_t ble_gap_rssi_get_rsp_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ int8_t * const p_rssi,
+#if NRF_SD_BLE_API_VERSION > 5
+ uint8_t * const p_ch_index,
+#endif
+ uint32_t * const p_result_code)
+{
+ SER_RSP_DEC_BEGIN(SD_BLE_GAP_RSSI_GET);
+ SER_PULL_COND(&p_rssi, uint8_t_dec);
+#if NRF_SD_BLE_API_VERSION > 5
+ SER_PULL_COND(&p_ch_index, uint8_t_dec);
+#endif
+ SER_RSP_DEC_END;
+}
+
+
+uint32_t ble_gap_rssi_start_req_enc(uint16_t conn_handle,
+ uint8_t threshold_dbm,
+ uint8_t skip_count,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len)
+{
+ SER_REQ_ENC_BEGIN(SD_BLE_GAP_RSSI_START);
+
+ SER_PUSH_uint16(&conn_handle);
+ SER_PUSH_uint8(&threshold_dbm);
+ SER_PUSH_uint8(&skip_count);
+
+ SER_REQ_ENC_END;
+}
+
+uint32_t ble_gap_rssi_start_rsp_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ uint32_t * const p_result_code)
+{
+ SER_RSP_DEC_RESULT_ONLY(SD_BLE_GAP_RSSI_START);
+}
+
+
+uint32_t ble_gap_rssi_stop_req_enc(uint16_t conn_handle,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len)
+{
+ SER_REQ_ENC_BEGIN(SD_BLE_GAP_RSSI_STOP);
+ SER_PUSH_uint16(&conn_handle);
+ SER_REQ_ENC_END;
+}
+
+uint32_t ble_gap_rssi_stop_rsp_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ uint32_t * const p_result_code)
+{
+ SER_RSP_DEC_RESULT_ONLY(SD_BLE_GAP_RSSI_STOP);
+}
+
+#ifndef S112
+uint32_t ble_gap_scan_start_req_enc(ble_gap_scan_params_t const * p_scan_params,
+#if defined(NRF_SD_BLE_API_VERSION) && NRF_SD_BLE_API_VERSION > 5
+ ble_data_t const * p_adv_report_buffer,
+#endif
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len)
+{
+ SER_REQ_ENC_BEGIN(SD_BLE_GAP_SCAN_START);
+ SER_PUSH_COND(p_scan_params, ble_gap_scan_params_t_enc);
+#if defined(NRF_SD_BLE_API_VERSION) && NRF_SD_BLE_API_VERSION > 5
+ SER_PUSH_COND(p_adv_report_buffer, ble_data_t_enc);
+#endif
+ SER_REQ_ENC_END;
+}
+uint32_t ble_gap_scan_start_rsp_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ uint32_t * const p_result_code)
+{
+ SER_RSP_DEC_RESULT_ONLY(SD_BLE_GAP_SCAN_START);
+}
+
+
+uint32_t ble_gap_scan_stop_req_enc(uint8_t * const p_buf,
+ uint32_t * const p_buf_len)
+{
+ SER_REQ_ENC_BEGIN(SD_BLE_GAP_SCAN_STOP);
+ SER_REQ_ENC_END;
+}
+
+uint32_t ble_gap_scan_stop_rsp_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ uint32_t * const p_result_code)
+{
+ SER_RSP_DEC_RESULT_ONLY(SD_BLE_GAP_SCAN_STOP);
+}
+#endif
+
+uint32_t ble_gap_sec_info_reply_req_enc(uint16_t conn_handle,
+ ble_gap_enc_info_t const * p_enc_info,
+ ble_gap_irk_t const * p_id_info,
+ ble_gap_sign_info_t const * p_sign_info,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len)
+{
+ SER_REQ_ENC_BEGIN(SD_BLE_GAP_SEC_INFO_REPLY);
+
+ SER_PUSH_uint16(&conn_handle);
+ SER_PUSH_COND(p_enc_info, ble_gap_enc_info_t_enc);
+ SER_PUSH_COND(p_id_info, ble_gap_irk_t_enc);
+ SER_PUSH_COND(p_sign_info, ble_gap_sign_info_t_enc);
+
+ SER_REQ_ENC_END;
+}
+
+
+uint32_t ble_gap_sec_info_reply_rsp_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ uint32_t * const p_result_code)
+{
+ SER_RSP_DEC_RESULT_ONLY(SD_BLE_GAP_SEC_INFO_REPLY);
+}
+
+
+uint32_t ble_gap_sec_params_reply_req_enc(uint16_t conn_handle,
+ uint8_t sec_status,
+ ble_gap_sec_params_t const * const p_sec_params,
+ ble_gap_sec_keyset_t const * const p_sec_keyset,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len)
+{
+ SER_REQ_ENC_BEGIN(SD_BLE_GAP_SEC_PARAMS_REPLY);
+
+ SER_PUSH_uint16(&conn_handle);
+ SER_PUSH_uint8(&sec_status);
+ SER_PUSH_COND(p_sec_params, ble_gap_sec_params_t_enc);
+ SER_PUSH_COND(p_sec_keyset, ble_gap_sec_keyset_t_enc);
+
+ SER_REQ_ENC_END;
+}
+
+uint32_t ble_gap_sec_params_reply_rsp_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ ble_gap_sec_keyset_t const * const p_sec_keyset,
+ uint32_t * const p_result_code)
+{
+ SER_RSP_DEC_BEGIN(SD_BLE_GAP_SEC_PARAMS_REPLY);
+ SER_PULL_COND(&p_sec_keyset, ble_gap_sec_keyset_t_dec);
+ SER_RSP_DEC_END;
+}
+
+
+uint32_t ble_gap_tx_power_set_req_enc(
+#if NRF_SD_BLE_API_VERSION > 5
+ uint8_t role, uint16_t handle,
+#endif
+ int8_t tx_power,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len)
+{
+ SER_REQ_ENC_BEGIN(SD_BLE_GAP_TX_POWER_SET);
+#if NRF_SD_BLE_API_VERSION > 5
+ SER_PUSH_uint8(&role);
+ SER_PUSH_uint16(&handle);
+#endif
+ SER_PUSH_int8(&tx_power);
+ SER_REQ_ENC_END;
+}
+
+uint32_t ble_gap_tx_power_set_rsp_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ uint32_t * const p_result_code)
+{
+ SER_RSP_DEC_RESULT_ONLY(SD_BLE_GAP_TX_POWER_SET);
+}
+
+uint32_t ble_gap_addr_get_req_enc(ble_gap_addr_t const * const p_address,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len)
+{
+ SER_REQ_ENC_BEGIN(SD_BLE_GAP_ADDR_GET);
+ SER_PUSH_COND(p_address, NULL);
+ SER_REQ_ENC_END;
+}
+
+uint32_t ble_gap_addr_get_rsp_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ ble_gap_addr_t * const p_address,
+ uint32_t * const p_result_code)
+{
+ SER_RSP_DEC_BEGIN(SD_BLE_GAP_ADDR_GET);
+ SER_PULL_FIELD(p_address, ble_gap_addr_t_dec);
+ SER_RSP_DEC_END;
+}
+
+uint32_t ble_gap_addr_set_req_enc(ble_gap_addr_t const * const p_addr,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len)
+{
+ SER_REQ_ENC_BEGIN(SD_BLE_GAP_ADDR_SET);
+ SER_PUSH_COND(p_addr, ble_gap_addr_t_enc);
+ SER_REQ_ENC_END;
+}
+
+uint32_t ble_gap_addr_set_rsp_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ uint32_t * const p_result_code)
+{
+ SER_RSP_DEC_RESULT_ONLY(SD_BLE_GAP_ADDR_SET);
+}
+
+uint32_t ble_gap_privacy_set_req_enc(ble_gap_privacy_params_t const * p_privacy_params,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len)
+{
+ SER_REQ_ENC_BEGIN(SD_BLE_GAP_PRIVACY_SET);
+ SER_PUSH_COND(p_privacy_params, ble_gap_privacy_params_t_enc);
+ SER_REQ_ENC_END;
+}
+
+uint32_t ble_gap_privacy_set_rsp_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ uint32_t * const p_result_code)
+{
+ SER_RSP_DEC_RESULT_ONLY(SD_BLE_GAP_PRIVACY_SET);
+}
+
+
+uint32_t ble_gap_privacy_get_req_enc(ble_gap_privacy_params_t const * const p_privacy_params,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len)
+{
+ SER_REQ_ENC_BEGIN(SD_BLE_GAP_PRIVACY_GET);
+ SER_PUSH_COND(p_privacy_params, ble_gap_privacy_params_t_enc);
+ SER_REQ_ENC_END;
+}
+
+uint32_t ble_gap_privacy_get_rsp_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ ble_gap_privacy_params_t const * const p_privacy_params,
+ uint32_t * const p_result_code)
+{
+ SER_RSP_DEC_BEGIN(SD_BLE_GAP_PRIVACY_GET);
+ SER_PULL_COND((void **)&p_privacy_params, ble_gap_privacy_params_t_dec);
+ SER_RSP_DEC_END;
+}
+
+uint32_t ble_gap_whitelist_set_req_enc(ble_gap_addr_t const * const * const pp_wl_addrs,
+ uint8_t const len,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len)
+{
+ SER_REQ_ENC_BEGIN(SD_BLE_GAP_WHITELIST_SET);
+
+ uint8_t presence;
+ SER_PUSH_uint8(&len);
+
+ if (pp_wl_addrs)
+ {
+ presence = SER_FIELD_PRESENT;
+ SER_PUSH_uint8(&presence);
+
+ for (uint32_t i = 0; i < len; ++i)
+ {
+ SER_PUSH_COND(pp_wl_addrs[i], ble_gap_addr_t_enc);
+ }
+ }
+ else
+ {
+ presence = SER_FIELD_NOT_PRESENT;
+ SER_PUSH_uint8(&presence);
+ }
+
+ SER_REQ_ENC_END;
+}
+
+uint32_t ble_gap_whitelist_set_rsp_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ uint32_t * const p_result_code)
+{
+ SER_RSP_DEC_RESULT_ONLY(SD_BLE_GAP_WHITELIST_SET);
+}
+
+uint32_t ble_gap_device_identities_set_req_enc(ble_gap_id_key_t const * const * const pp_id_keys,
+ ble_gap_irk_t const * const * const pp_local_irks,
+ uint8_t const len,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len)
+{
+ SER_REQ_ENC_BEGIN(SD_BLE_GAP_DEVICE_IDENTITIES_SET);
+ uint8_t presence;
+ SER_PUSH_uint8(&len);
+
+ if (pp_id_keys)
+ {
+ presence = SER_FIELD_PRESENT;
+ SER_PUSH_uint8(&presence);
+
+ for (uint32_t i = 0; i < len; ++i)
+ {
+ SER_PUSH_COND(pp_id_keys[i], ble_gap_id_key_t_enc);
+ }
+ }
+ else
+ {
+ presence = SER_FIELD_NOT_PRESENT;
+ SER_PUSH_uint8(&presence);
+ }
+
+ if (pp_local_irks)
+ {
+ presence = SER_FIELD_PRESENT;
+ SER_PUSH_uint8(&presence);
+
+ for (uint32_t i = 0; i < len; ++i)
+ {
+ SER_PUSH_COND(pp_local_irks[i], ble_gap_irk_t_enc);
+ }
+ }
+ else
+ {
+ presence = SER_FIELD_NOT_PRESENT;
+ SER_PUSH_uint8(&presence);
+ }
+
+ SER_REQ_ENC_END;
+}
+
+uint32_t ble_gap_device_identities_set_rsp_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ uint32_t * const p_result_code)
+{
+ SER_RSP_DEC_RESULT_ONLY(SD_BLE_GAP_DEVICE_IDENTITIES_SET);
+}
+#if NRF_SD_BLE_API_VERSION >= 4 && !defined(S112)
+uint32_t ble_gap_data_length_update_req_enc(uint16_t conn_handle,
+ ble_gap_data_length_params_t const * p_dl_params,
+ ble_gap_data_length_limitation_t * p_dl_limitation,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len)
+{
+ SER_REQ_ENC_BEGIN(SD_BLE_GAP_DATA_LENGTH_UPDATE);
+
+ SER_PUSH_uint16(&conn_handle);
+ SER_PUSH_COND(p_dl_params, ble_gap_data_length_params_t_enc);
+ SER_PUSH_COND(p_dl_limitation, NULL);
+
+ SER_REQ_ENC_END;
+}
+
+
+uint32_t ble_gap_data_length_update_rsp_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ ble_gap_data_length_limitation_t * p_dl_limitation,
+ uint32_t * const p_result_code)
+{
+ SER_RSP_DEC_BEGIN(SD_BLE_GAP_DATA_LENGTH_UPDATE);
+ SER_PULL_COND((void **)&p_dl_limitation, ble_gap_data_length_limitation_t_dec);
+ SER_RSP_DEC_END;
+}
+#endif
+#if NRF_SD_BLE_API_VERSION >= 5
+uint32_t ble_gap_phy_update_req_enc(uint16_t conn_handle,
+ ble_gap_phys_t const * p_gap_phys,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len)
+{
+ SER_REQ_ENC_BEGIN(SD_BLE_GAP_PHY_UPDATE);
+
+ SER_PUSH_uint16(&conn_handle);
+ SER_PUSH_COND(p_gap_phys, ble_gap_phys_t_enc);
+
+ SER_REQ_ENC_END;
+}
+
+
+uint32_t ble_gap_phy_update_rsp_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ uint32_t * const p_result_code)
+{
+ SER_RSP_DEC_RESULT_ONLY(SD_BLE_GAP_PHY_UPDATE);
+}
+#endif
+
+#if NRF_SD_BLE_API_VERSION > 5
+uint32_t ble_gap_adv_set_configure_req_enc(uint8_t * p_adv_handle,
+ ble_gap_adv_data_t const * p_adv_data,
+ ble_gap_adv_params_t const *p_adv_params,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len)
+{
+ SER_REQ_ENC_BEGIN(SD_BLE_GAP_ADV_SET_CONFIGURE);
+
+ SER_PUSH_COND(p_adv_handle, uint8_t_enc);
+ SER_PUSH_COND(p_adv_data, ble_gap_adv_data_t_enc);
+ SER_PUSH_COND(p_adv_params, ble_gap_adv_params_t_enc);
+
+ SER_REQ_ENC_END;
+}
+
+
+uint32_t ble_gap_adv_set_configure_rsp_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ uint8_t * p_adv_handle,
+ uint32_t * const p_result_code)
+{
+ SER_RSP_DEC_BEGIN(SD_BLE_GAP_ADV_SET_CONFIGURE);
+ SER_PULL_COND((void **)&p_adv_handle, uint8_t_dec);
+ SER_RSP_DEC_END;
+}
+
+#ifndef S112
+uint32_t ble_gap_qos_channel_survey_start_req_enc(uint32_t interval_us,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len)
+{
+ SER_REQ_ENC_BEGIN(SD_BLE_GAP_QOS_CHANNEL_SURVEY_START);
+
+ SER_PUSH_uint32(&interval_us);
+
+ SER_REQ_ENC_END;
+}
+
+
+uint32_t ble_gap_qos_channel_survey_start_rsp_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ uint32_t * const p_result_code)
+{
+ SER_RSP_DEC_RESULT_ONLY(SD_BLE_GAP_QOS_CHANNEL_SURVEY_START);
+}
+
+uint32_t ble_gap_qos_channel_survey_stop_req_enc(uint8_t * const p_buf,
+ uint32_t * const p_buf_len)
+{
+ SER_REQ_ENC_BEGIN(SD_BLE_GAP_QOS_CHANNEL_SURVEY_STOP);
+ SER_REQ_ENC_END;
+}
+
+
+uint32_t ble_gap_qos_channel_survey_stop_rsp_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ uint32_t * const p_result_code)
+{
+ SER_RSP_DEC_RESULT_ONLY(SD_BLE_GAP_QOS_CHANNEL_SURVEY_STOP);
+}
+#endif //!S112
+#endif
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/application/codecs/ble/serializers/ble_gap_app.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/application/codecs/ble/serializers/ble_gap_app.h
new file mode 100644
index 0000000..715a8df
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/application/codecs/ble/serializers/ble_gap_app.h
@@ -0,0 +1,1667 @@
+/**
+ * Copyright (c) 2013 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#ifndef BLE_GAP_APP_H__
+#define BLE_GAP_APP_H__
+
+/**@file
+ *
+ * @defgroup ble_gap_app GAP Application command request encoders and command response decoders
+ * @{
+ * @ingroup ser_app_s130_codecs
+ *
+ * @brief GAP Application command request encoders and command response decoders.
+ */
+#include "ble.h"
+#include "ble_gap.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#if defined(NRF_SD_BLE_API_VERSION) && (NRF_SD_BLE_API_VERSION <= 5)
+/**
+ * @brief Encodes @ref sd_ble_gap_adv_data_set command request.
+ *
+ * @sa @ref ble_gap_adv_data_set_rsp_dec for command response decoder.
+ *
+ * @param[in] p_data Raw data to be placed in advertisement packet. If NULL, no changes
+ * are made to the current advertisement packet data.
+ * @param[in] dlen Data length for p_data. Max size: @ref BLE_GAP_ADV_SR_MAX_LEN_DEFAULT octets.
+ * Should be 0 if p_data is NULL, can be 0 if p_data is not NULL.
+ * @param[in] p_sr_data Raw data to be placed in scan response packet. If NULL,
+ * no changes are made to the current scan response packet data.
+ * @param[in] srdlen Data length for p_sr_data. Max size: @ref BLE_GAP_ADV_SR_MAX_LEN_DEFAULT octets.
+ * Should be 0 if p_sr_data is NULL, can be 0 if p_data is not NULL.
+ * @param[in] p_buf Pointer to buffer where encoded data command will be returned.
+ * @param[in,out] p_buf_len \c in: Size of \p p_buf buffer.
+ * \c out: Length of encoded command packet.
+ *
+ * @retval NRF_SUCCESS Encoding success.
+ * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length.
+ */
+uint32_t ble_gap_adv_data_set_req_enc(uint8_t const * const p_data,
+ uint8_t dlen,
+ uint8_t const * const p_sr_data,
+ uint8_t srdlen,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len);
+
+/**
+ * @brief Decodes response to @ref sd_ble_gap_adv_data_set command.
+ *
+ * @sa @ref ble_gap_adv_data_set_req_enc for command request encoder.
+ *
+ * @param[in] p_buf Pointer to beginning of command response packet.
+ * @param[in] packet_len Length (in bytes) of response packet.
+ * @param[out] p_result_code Command result code.
+ *
+ * @retval NRF_SUCCESS Decoding success.
+ * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length.
+ * @retval NRF_ERROR_INVALID_DATA Decoding failure. Decoded operation code does not match
+ * expected operation code.
+ */
+uint32_t ble_gap_adv_data_set_rsp_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ uint32_t * const p_result_code);
+#endif
+
+/**
+ * @brief Encodes @ref sd_ble_gap_adv_start command request.
+ *
+ * @sa @ref ble_gap_adv_start_rsp_dec for command response decoder.
+ *
+ * @param[in] p_adv_params Pointer to advertising parameters structure.
+ * @param[in] p_buf Pointer to buffer where encoded data command will be returned.
+ * @param[in,out] p_buf_len \c in: Size of \p p_buf buffer.
+ * \c out: Length of encoded command packet.
+ *
+ * @retval NRF_SUCCESS Encoding success.
+ * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length.
+ */
+uint32_t ble_gap_adv_start_req_enc(
+#if NRF_SD_BLE_API_VERSION > 5
+ uint8_t adv_handle,
+#else
+ ble_gap_adv_params_t const * const p_adv_params,
+#endif
+#if NRF_SD_BLE_API_VERSION >= 4
+ uint8_t conn_cfg_tag,
+#endif
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len);
+
+/**
+ * @brief Decodes response to @ref sd_ble_gap_adv_start command.
+ *
+ * @sa @ref ble_gap_adv_start_req_enc for command request encoder.
+ *
+ * @param[in] p_buf Pointer to beginning of command response packet.
+ * @param[in] packet_len Length (in bytes) of response packet.
+ * @param[out] p_result_code Command result code.
+ *
+ * @retval NRF_SUCCESS Decoding success.
+ * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length.
+ * @retval NRF_ERROR_INVALID_DATA Decoding failure. Decoded operation code does not match
+ * expected operation code.
+ */
+uint32_t ble_gap_adv_start_rsp_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ uint32_t * const p_result_code);
+
+/**
+ * @brief Encodes @ref sd_ble_gap_tx_power_set command request.
+ *
+ * @sa @ref ble_gap_tx_power_set_rsp_dec for command response decoder.
+ *
+ * @param[in] tx_power Radio transmit power in dBm (accepted values are -40, -30, -20, -16, -12, -8, -4, 0, and 4 dBm).
+ * @param[in] p_buf Pointer to buffer where encoded data command will be returned.
+ * @param[in,out] p_buf_len \c in: Size of \p p_buf buffer.
+ * \c out: Length of encoded command packet.
+ *
+ * @retval NRF_SUCCESS Encoding success.
+ * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length.
+ */
+uint32_t ble_gap_tx_power_set_req_enc(
+#if NRF_SD_BLE_API_VERSION > 5
+ uint8_t role, uint16_t handle,
+#endif
+ int8_t tx_power,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len);
+
+/**
+ * @brief Decodes response to @ref sd_ble_gap_tx_power_set command.
+ *
+ * @sa @ref ble_gap_tx_power_set_req_enc for command request encoder.
+ *
+ * @param[in] p_buf Pointer to beginning of command response packet.
+ * @param[in] packet_len Length (in bytes) of response packet.
+ * @param[out] p_result_code Command result code.
+ *
+ * @retval NRF_SUCCESS Decoding success.
+ * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length.
+ * @retval NRF_ERROR_INVALID_DATA Decoding failure. Decoded operation code does not match
+ * expected operation code.
+ */
+uint32_t ble_gap_tx_power_set_rsp_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ uint32_t * const p_result_code);
+
+/**
+ * @brief Encodes @ref sd_ble_gap_appearance_get command request.
+ *
+ * @sa @ref ble_gap_appearance_get_rsp_dec for command response decoder.
+ *
+ * @param[in] p_appearance Appearance (16 bit), see @ref BLE_APPEARANCES.
+ * @param[in] p_buf Pointer to buffer where encoded data command will be returned.
+ * @param[in,out] p_buf_len \c in: Size of \p p_buf buffer.
+ * \c out: Length of encoded command packet.
+ *
+ * @note \p p_appearance will not be updated by the command
+ * request encoder. Updated values are set by @ref ble_gap_appearance_get_rsp_dec.
+ *
+ * @retval NRF_SUCCESS Encoding success.
+ * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length.
+ */
+uint32_t ble_gap_appearance_get_req_enc(uint16_t const * const p_appearance,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len);
+
+/**
+ * @brief Decodes response to @ref sd_ble_gap_appearance_get command.
+ *
+ * @sa @ref ble_gap_appearance_get_req_enc for command request encoder.
+ *
+ * @param[in] p_buf Pointer to beginning of command response packet.
+ * @param[in] packet_len Length (in bytes) of response packet.
+ * @param[out] p_appearance Appearance (16 bit), see @ref BLE_APPEARANCES.
+ * @param[out] p_result_code Command result code.
+ *
+ * @retval NRF_SUCCESS Decoding success.
+ * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length.
+ * @retval NRF_ERROR_INVALID_DATA Decoding failure. Decoded operation code does not match
+ * expected operation code.
+ */
+uint32_t ble_gap_appearance_get_rsp_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ uint16_t * const p_appearance,
+ uint32_t * const p_result_code);
+
+/**
+ * @brief Encodes @ref sd_ble_gap_appearance_set command request.
+ *
+ * @sa @ref ble_gap_appearance_set_rsp_dec for command response decoder.
+ *
+ * @param[in] appearance Appearance (16 bit), see @ref BLE_APPEARANCES.
+ * @param[in] p_buf Pointer to buffer where encoded data command will be returned.
+ * @param[in,out] p_buf_len \c in: Size of \p p_buf buffer.
+ * \c out: Length of encoded command packet.
+ *
+ * @retval NRF_SUCCESS Encoding success.
+ * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length.
+ */
+uint32_t ble_gap_appearance_set_req_enc(uint16_t appearance,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len);
+
+/**
+ * @brief Decodes response to @ref sd_ble_gap_appearance_set command.
+ *
+ * @sa @ref ble_gap_appearance_set_req_enc for command request encoder.
+ *
+ * @param[in] p_buf Pointer to beginning of command response packet.
+ * @param[in] packet_len Length (in bytes) of response packet.
+ * @param[out] p_result_code Command result code.
+ *
+ * @retval NRF_SUCCESS Decoding success.
+ * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length.
+ * @retval NRF_ERROR_INVALID_DATA Decoding failure. Decoded operation code does not match
+ * expected operation code.
+ */
+uint32_t ble_gap_appearance_set_rsp_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ uint32_t * const p_result_code);
+
+/**
+ * @brief Encodes @ref sd_ble_gap_device_name_get command request.
+ *
+ * @sa @ref ble_gap_device_name_get_rsp_dec for command response decoder.
+ *
+ * @param[in] p_dev_name Pointer to an empty buffer where the UTF-8 <b>non NULL-terminated</b>
+ * string will be placed. Set to NULL to obtain the complete device
+ * name length.
+ * @param[in] p_dev_name_len Length of the buffer pointed by p_dev_name.
+ * @param[in] p_buf Pointer to buffer where encoded data command will be returned.
+ * @param[in,out] p_buf_len \c in: Size of \p p_buf buffer.
+ * \c out: Length of encoded command packet.
+ *
+ * @note \p p_dev_name and \p p_len will not be updated by the command
+ * request encoder. Updated values are set by @ref ble_gap_device_name_get_rsp_dec.
+ *
+ * @retval NRF_SUCCESS Encoding success.
+ * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length.
+ */
+uint32_t ble_gap_device_name_get_req_enc(uint8_t const * const p_dev_name,
+ uint16_t const * const p_dev_name_len,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len);
+
+/**
+ * @brief Decodes response to @ref sd_ble_gap_device_name_get command.
+ *
+ * @sa @ref ble_gap_device_name_get_req_enc for command request encoder.
+ *
+ * @param[in] p_buf Pointer to beginning of command response packet.
+ * @param[in] packet_len Length (in bytes) of response packet.
+ * @param[out] p_dev_name Pointer to an empty buffer where the UTF-8
+ * <b>non NULL-terminated</b> string will be placed.
+ * @param[in,out] p_dev_name_len Length of the buffer pointed by p_dev_name, complete device name
+ * length on output.
+ * @param[out] p_result_code Command result code.
+ *
+ * @retval NRF_SUCCESS Decoding success.
+ * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length.
+ * @retval NRF_ERROR_INVALID_DATA Decoding failure. Decoded operation code does not match
+ * expected operation code.
+ */
+uint32_t ble_gap_device_name_get_rsp_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ uint8_t * const p_dev_name,
+ uint16_t * const p_dev_name_len,
+ uint32_t * const p_result_code);
+
+/**
+ * @brief Encodes @ref sd_ble_gap_device_name_set command request.
+ *
+ * @sa @ref ble_gap_device_name_set_rsp_dec for command response decoder.
+ *
+ * @param[in] p_write_perm Write permissions for the Device Name characteristic, see
+ * @ref ble_gap_conn_sec_mode_t.
+ * @param[in] p_dev_name Pointer to a UTF-8 encoded, <b>non NULL-terminated</b> string.
+ * @param[in] len Length of the UTF-8, <b>non NULL-terminated</b> string pointed
+ * to by p_dev_name in octets (must be smaller or equal
+ * than @ref BLE_GAP_DEVNAME_MAX_LEN).
+ * @param[in] p_buf Pointer to buffer where encoded data command will be returned.
+ * @param[in,out] p_buf_len \c in: Size of \p p_buf buffer.
+ * \c out: Length of encoded command packet.
+ *
+ * @retval NRF_SUCCESS Encoding success.
+ * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length.
+ */
+uint32_t ble_gap_device_name_set_req_enc(ble_gap_conn_sec_mode_t const * const p_write_perm,
+ uint8_t const * const p_dev_name,
+ uint16_t len,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len);
+
+/**
+ * @brief Decodes response to @ref sd_ble_gap_device_name_set command.
+ *
+ * @sa @ref ble_gap_device_name_set_req_enc for command request encoder.
+ *
+ * @param[in] p_buf Pointer to beginning of command response packet.
+ * @param[in] packet_len Length (in bytes) of response packet.
+ * @param[out] p_result_code Command result code.
+ *
+ * @retval NRF_SUCCESS Decoding success.
+ * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length.
+ * @retval NRF_ERROR_INVALID_DATA Decoding failure. Decoded operation code does not match
+ * expected operation code.
+ */
+uint32_t ble_gap_device_name_set_rsp_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ uint32_t * const p_result_code);
+
+/**
+ * @brief Encodes @ref sd_ble_gap_ppcp_set command request.
+ *
+ * @sa @ref ble_gap_ppcp_set_rsp_dec for command response decoder.
+ *
+ * @param[in] p_conn_params Pointer to a @ref ble_gap_conn_params_t structure with the
+ * desired parameters.
+ * @param[in] p_buf Pointer to buffer where encoded data command will be returned.
+ * @param[in,out] p_buf_len \c in: Size of \p p_buf buffer.
+ * \c out: Length of encoded command packet.
+ *
+ * @retval NRF_SUCCESS Encoding success.
+ * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length.
+ */
+uint32_t ble_gap_ppcp_set_req_enc(ble_gap_conn_params_t const * const p_conn_params,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len);
+
+/**
+ * @brief Decodes response to @ref sd_ble_gap_ppcp_set command.
+ *
+ * @sa @ref ble_gap_ppcp_set_req_enc for command request encoder.
+ *
+ * @param[in] p_buf Pointer to beginning of command response packet.
+ * @param[in] packet_len Length (in bytes) of response packet.
+ * @param[out] p_result_code Command result code.
+ *
+ * @retval NRF_SUCCESS Decoding success.
+ * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length.
+ * @retval NRF_ERROR_INVALID_DATA Decoding failure. Decoded operation code does not match
+ * expected operation code.
+ */
+uint32_t ble_gap_ppcp_set_rsp_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ uint32_t * const p_result_code);
+
+/**@brief Encodes @ref sd_ble_gap_conn_param_update command request.
+ *
+ * @sa @ref ble_gap_conn_param_update_rsp_dec for command response decoder.
+ *
+ * @param[in] conn_handle Connection handle of the connection.
+ * @param[in] p_conn_params Pointer to desired connection parameters.
+ * @param[in] p_buf Pointer to buffer where encoded data command will be returned.
+ * @param[in, out] p_buf_len \c in: size of \p p_buf buffer.
+ * \c out: Length of encoded command packet.
+ *
+ * @retval NRF_SUCCESS Encoding success.
+ * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length.
+ */
+uint32_t ble_gap_conn_param_update_req_enc(uint16_t conn_handle,
+ ble_gap_conn_params_t const * const p_conn_params,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len);
+
+/**@brief Decodes response to @ref sd_ble_gap_conn_param_update command.
+ *
+ * @sa @ref ble_gap_conn_param_update_req_enc for command request encoder.
+ *
+ * @param[in] p_buf Pointer to beginning of command response packet.
+ * @param[in] packet_len Length (in bytes) of response packet.
+ * @param[out] p_result_code Command response result code.
+ *
+ * @retval NRF_SUCCESS Decoding success.
+ * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_DATA_SIZE Decoding failure. Incorrect buffer length.
+ * @retval NRF_ERROR_INVALID_DATA Decoding failure. Decoded operation code does not match expected
+ * operation code.
+ */
+uint32_t ble_gap_conn_param_update_rsp_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ uint32_t * const p_result_code);
+
+/**@brief Encodes @ref sd_ble_gap_disconnect command request.
+ *
+ * @sa @ref ble_gap_disconnect_rsp_dec for command response decoder.
+ *
+ * @param[in] conn_handle Connection handle of the connection.
+ * @param[in] hci_status_code HCI status code, see @ref BLE_HCI_STATUS_CODES.
+ * @param[in] p_buf Pointer to buffer where encoded data command will be returned.
+ * @param[in, out] p_buf_len \c in: size of \p p_buf buffer.
+ * \c out: Length of encoded command packet.
+ *
+ * @retval NRF_SUCCESS Encoding success.
+ * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length.
+ */
+uint32_t ble_gap_disconnect_req_enc(uint16_t conn_handle,
+ uint8_t hci_status_code,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len);
+
+/**@brief Decodes response to @ref sd_ble_gap_disconnect command.
+ *
+ * @sa @ref ble_gap_disconnect_req_enc for command request encoder.
+ *
+ * @param[in] p_buf Pointer to beginning of command response packet.
+ * @param[in] packet_len Length (in bytes) of response packet.
+ * @param[out] p_result_code Command response result code.
+ *
+ * @retval NRF_SUCCESS Decoding success.
+ * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_DATA_SIZE Decoding failure. Incorrect buffer length.
+ * @retval NRF_ERROR_INVALID_DATA Decoding failure. Decoded operation code does not match expected
+ * operation code.
+ */
+uint32_t ble_gap_disconnect_rsp_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ uint32_t * const p_result_code);
+
+
+/**@brief Encodes @ref sd_ble_gap_rssi_stop command request.
+ *
+ * @sa @ref ble_gap_rssi_stop_rsp_dec for command response decoder.
+ *
+ * @param[in] conn_handle Connection handle of the connection.
+ * @param[in] p_buf Pointer to buffer where encoded data command will be returned.
+ * @param[in, out] p_buf_len \c in: size of \p p_buf buffer.
+ * \c out: Length of encoded command packet.
+ *
+ * @retval NRF_SUCCESS Encoding success.
+ * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length.
+ */
+uint32_t ble_gap_rssi_stop_req_enc(uint16_t conn_handle,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len);
+
+/**@brief Decodes response to @ref sd_ble_gap_rssi_stop command.
+ *
+ * @sa @ref ble_gap_rssi_stop_rsp_dec for command response decoder.
+ *
+ * @param[in] p_buf Pointer to beginning of command response packet.
+ * @param[in] packet_len Length (in bytes) of response packet.
+ * @param[out] p_result_code Command response result code.
+ *
+ * @retval NRF_SUCCESS Decoding success.
+ * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_DATA_SIZE Decoding failure. Incorrect buffer length.
+ * @retval NRF_ERROR_INVALID_DATA Decoding failure. Decoded operation code does not match expected
+ * operation code.
+ */
+uint32_t ble_gap_rssi_stop_rsp_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ uint32_t * const p_result_code);
+
+
+
+
+/**@brief Encodes @ref sd_ble_gap_ppcp_get command request.
+ *
+ * @sa @ref ble_gap_ppcp_get_rsp_dec for command response decoder.
+ *
+ * @param[in] p_conn_params Pointer to a @ref ble_gap_conn_params_t structure where the
+ * parameters will be stored.
+ * @param[in] p_buf Pointer to buffer where encoded data command will be returned.
+ * @param[in, out] p_buf_len \c in: size of \p p_buf buffer.
+ * \c out: Length of encoded command packet.
+ *
+ * @note \p p_conn_params will not be updated by the command request encoder. Updated values are
+ * set by @ref ble_gap_ppcp_get_rsp_dec.
+ *
+ * @retval NRF_SUCCESS Encoding success.
+ * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length.
+ */
+uint32_t ble_gap_ppcp_get_req_enc(ble_gap_conn_params_t const * const p_conn_params,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len);
+
+/**@brief Decodes response to @ref sd_ble_gap_ppcp_get command.
+ *
+ * @sa @ref ble_gap_ppcp_get_req_enc for command request encoder.
+ *
+ * @param[in] p_buf Pointer to beginning of command response packet.
+ * @param[in] packet_len Length (in bytes) of response packet.
+ * @param[out] p_conn_params Pointer to a @ref ble_gap_conn_params_t structure where the parameters
+ * will be stored.
+ * @param[out] p_result_code Command response result code.
+ *
+ * @retval NRF_SUCCESS Decoding success.
+ * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_DATA_SIZE Decoding failure. Incorrect buffer length.
+ * @retval NRF_ERROR_INVALID_DATA Decoding failure. Decoded operation code does not match expected
+ * operation code.
+ */
+uint32_t ble_gap_ppcp_get_rsp_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ ble_gap_conn_params_t * const p_conn_params,
+ uint32_t * const p_result_code);
+
+/**@brief Encodes @ref sd_ble_gap_auth_key_reply command request.
+ *
+ * @sa @ref ble_gap_auth_key_reply_rsp_dec for command response decoder.
+ *
+ * @param[in] conn_handle Connection handle of the connection.
+ * @param[in] key_type Key type which defines length of key data as defined for
+ * @ref sd_ble_gap_auth_key_reply .
+ * @param[in] p_key Pointer to a buffer which contains key
+ * @param[in] p_buf Pointer to buffer where encoded data command will be returned.
+ * @param[in, out] p_buf_len \c in: size of \p p_buf buffer.
+ * \c out: Length of encoded command packet.
+ *
+ * @retval NRF_SUCCESS Encoding success.
+ * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length.
+ * @retval NRF_ERROR_INVALID_PARAM Encoding failure. Incorrect param provided (key_type).
+ */
+uint32_t ble_gap_auth_key_reply_req_enc(uint16_t conn_handle,
+ uint8_t key_type,
+ uint8_t const * const p_key,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len);
+
+/**@brief Decodes response to @ref sd_ble_gap_auth_key_reply command.
+ *
+ * @sa @ref ble_gap_auth_key_reply_req_enc for command request encoder.
+ *
+ * @param[in] p_buf Pointer to beginning of command response packet.
+ * @param[in] packet_len Length (in bytes) of response packet.
+ * @param[out] p_result_code Command response result code.
+ *
+ * @retval NRF_SUCCESS Decoding success.
+ * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_DATA_SIZE Decoding failure. Incorrect buffer length.
+ * @retval NRF_ERROR_INVALID_DATA Decoding failure. Decoded operation code does not match expected
+ * operation code.
+ */
+uint32_t ble_gap_auth_key_reply_rsp_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ uint32_t * const p_result_code);
+
+/**@brief Encodes @ref sd_ble_gap_sec_info_reply command request.
+ *
+ * @sa @ref ble_gap_sec_info_reply_rsp_dec for command response decoder.
+ *
+ * @param[in] conn_handle Connection handle of the connection.
+ * @param[in] p_enc_info Pointer to a @ref ble_gap_enc_info_t encryption information
+ * structure.
+ * @param[in] p_id_info Pointer to a @ref ble_gap_irk_t id information
+ * structure.
+ * @param[in] p_sign_info Pointer to a @ref ble_gap_sign_info_t signing information
+ * structure.
+ * @param[in] p_buf Pointer to buffer where encoded data command will be returned.
+ * @param[in, out] p_buf_len \c in: size of \p p_buf buffer.
+ * \c out: Length of encoded command packet.
+ *
+ * @retval NRF_SUCCESS Encoding success.
+ * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length.
+ */
+uint32_t ble_gap_sec_info_reply_req_enc(uint16_t conn_handle,
+ ble_gap_enc_info_t const * p_enc_info,
+ ble_gap_irk_t const * p_id_info,
+ ble_gap_sign_info_t const * p_sign_info,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len);
+
+/**@brief Decodes response to @ref sd_ble_gap_sec_info_reply command.
+ *
+ * @sa @ref ble_gap_sec_info_reply_req_enc for command request encoder.
+ *
+ * @param[in] p_buf Pointer to beginning of command response packet.
+ * @param[in] packet_len Length (in bytes) of response packet.
+ * @param[out] p_result_code Command response result code.
+ *
+ * @retval NRF_SUCCESS Decoding success.
+ * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_DATA_SIZE Decoding failure. Incorrect buffer length.
+ * @retval NRF_ERROR_INVALID_DATA Decoding failure. Decoded operation code does not match expected
+ * operation code.
+ */
+uint32_t ble_gap_sec_info_reply_rsp_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ uint32_t * const p_result_code);
+
+/**@brief Encodes @ref sd_ble_gap_sec_params_reply command request.
+ *
+ * @sa @ref ble_gap_sec_params_reply_rsp_dec for command response decoder.
+ *
+ * @param[in] conn_handle Connection handle of the connection.
+ * @param[in] sec_status Security status, see @ref BLE_GAP_SEC_STATUS.
+ * @param[in] p_sec_params Pointer to @ref ble_gap_sec_params_t security parameters
+ * structure.
+ * @param[in] p_sec_keyset Pointer to @ref ble_gap_sec_keyset_t security keys
+ * structure.
+ * @param[in] p_buf Pointer to buffer where encoded data command will be returned.
+ * @param[in, out] p_buf_len \c in: size of \p p_buf buffer.
+ * \c out: Length of encoded command packet.
+ *
+ * @retval NRF_SUCCESS Encoding success.
+ * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length.
+ */
+uint32_t ble_gap_sec_params_reply_req_enc(uint16_t conn_handle,
+ uint8_t sec_status,
+ ble_gap_sec_params_t const * const p_sec_params,
+ ble_gap_sec_keyset_t const * const p_sec_keyset,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len);
+
+/**@brief Decodes response to @ref sd_ble_gap_sec_params_reply command.
+ *
+ * @sa @ref ble_gap_sec_params_reply_req_enc for command request encoder.
+ *
+ * @param[in] p_buf Pointer to beginning of command response packet.
+ * @param[in] packet_len Length (in bytes) of response packet.
+ * @param[in] p_sec_keyset Pointer to @ref ble_gap_sec_keyset_t security keys
+ * @param[out] p_result_code Command response result code.
+ *
+ * @retval NRF_SUCCESS Decoding success.
+ * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_DATA_SIZE Decoding failure. Incorrect buffer length.
+ * @retval NRF_ERROR_INVALID_DATA Decoding failure. Decoded operation code does not match expected
+ * operation code.
+ */
+uint32_t ble_gap_sec_params_reply_rsp_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ ble_gap_sec_keyset_t const * const p_sec_keyset,
+ uint32_t * const p_result_code);
+
+/**@brief Encodes @ref sd_ble_gap_authenticate command request.
+ *
+ * @sa @ref ble_gap_authenticate_rsp_dec for command response decoder.
+ *
+ * @param[in] conn_handle Connection handle of the connection.
+ * @param[in] p_sec_params Pointer to a @ref ble_gap_sec_params_t security parameters
+ * structure.
+ * @param[in] p_buf Pointer to buffer where encoded data command will be returned.
+ * @param[in, out] p_buf_len \c in: size of \p p_buf buffer.
+ * \c out: Length of encoded command packet.
+ *
+ * @retval NRF_SUCCESS Encoding success.
+ * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length.
+ */
+uint32_t ble_gap_authenticate_req_enc(uint16_t conn_handle,
+ ble_gap_sec_params_t const * const p_sec_params,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len);
+
+/**@brief Decodes response to @ref sd_ble_gap_authenticate command.
+ *
+ * @sa @ref ble_gap_authenticate_req_enc for command request encoder.
+ *
+ * @param[in] p_buf Pointer to beginning of command response packet.
+ * @param[in] packet_len Length (in bytes) of response packet.
+ * @param[out] p_result_code Command response result code.
+ *
+ * @retval NRF_SUCCESS Decoding success.
+ * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_DATA_SIZE Decoding failure. Incorrect buffer length.
+ * @retval NRF_ERROR_INVALID_DATA Decoding failure. Decoded operation code does not match expected
+ * operation code.
+ */
+uint32_t ble_gap_authenticate_rsp_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ uint32_t * const p_result_code);
+
+/**@brief Encodes @ref sd_ble_gap_adv_stop command request.
+ *
+ * @sa @ref ble_gap_adv_stop_rsp_dec for command response decoder.
+ *
+ * @param[in] p_buf Pointer to buffer where encoded data command will be returned.
+ * @param[in, out] p_buf_len \c in: size of \p p_buf buffer.
+ * \c out: Length of encoded command packet.
+ *
+ * @retval NRF_SUCCESS Encoding success.
+ * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length.
+ */
+uint32_t ble_gap_adv_stop_req_enc(
+#if NRF_SD_BLE_API_VERSION > 5
+ uint8_t adv_handle,
+#endif
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len);
+
+/**@brief Decodes response to @ref sd_ble_gap_adv_stop command.
+ *
+ * @sa @ref ble_gap_adv_stop_req_enc for command request encoder.
+ *
+ * @param[in] p_buf Pointer to beginning of command response packet.
+ * @param[in] packet_len Length (in bytes) of response packet.
+ * @param[out] p_result_code Command response result code.
+ *
+ * @retval NRF_SUCCESS Decoding success.
+ * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_DATA_SIZE Decoding failure. Incorrect buffer length.
+ * @retval NRF_ERROR_INVALID_DATA Decoding failure. Decoded operation code does not match expected
+ * operation code.
+ */
+uint32_t ble_gap_adv_stop_rsp_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ uint32_t * const p_result_code);
+
+/**@brief Encodes @ref sd_ble_gap_conn_sec_get command request.
+ *
+ * @sa @ref ble_gap_conn_sec_get_rsp_dec for command response decoder.
+ *
+ * @param[in] conn_handle Connection handle of the connection.
+ * @param[in] p_conn_sec Pointer to \ref ble_gap_conn_sec_t which will be filled in
+ * response.
+ * @param[in] p_buf Pointer to buffer where encoded data command will be returned.
+ * @param[in, out] p_buf_len \c in: size of \p p_buf buffer.
+ * \c out: Length of encoded command packet.
+ *
+ * @retval NRF_SUCCESS Encoding success.
+ * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length.
+ */
+uint32_t ble_gap_conn_sec_get_req_enc(uint16_t conn_handle,
+ ble_gap_conn_sec_t const * const p_conn_sec,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len);
+
+/**@brief Decodes response to @ref sd_ble_gap_conn_sec_get command.
+ *
+ * @sa @ref ble_gap_conn_sec_get_req_enc for command request encoder.
+ *
+ * @param[in] p_buf Pointer to beginning of command response packet.
+ * @param[in] packet_len Length (in bytes) of response packet.
+ * @param[out] pp_conn_sec Pointer to pointer to \ref ble_gap_conn_sec_t which will be filled by
+ * the decoded data (if present).
+ * @param[out] p_result_code Command response result code.
+ *
+ * @retval NRF_SUCCESS Decoding success.
+ * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_DATA_SIZE Decoding failure. Incorrect buffer length.
+ * @retval NRF_ERROR_INVALID_DATA Decoding failure. Decoded operation code does not match expected
+ * operation code.
+ */
+uint32_t ble_gap_conn_sec_get_rsp_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ ble_gap_conn_sec_t * * const pp_conn_sec,
+ uint32_t * const p_result_code);
+
+/**@brief Encodes @ref sd_ble_gap_rssi_start command request.
+ *
+ * @sa @ref ble_gap_rssi_start_rsp_dec for command response decoder.
+ *
+ * @param[in] conn_handle Connection handle of the connection.
+ * @param[in] threshold_dbm Threshold in dBm.
+ * @param[in] skip_count Sample skip count.
+ * @param[in] p_buf Pointer to buffer where encoded data command will be returned.
+ * @param[in, out] p_buf_len \c in: size of \p p_buf buffer.
+ * \c out: Length of encoded command packet.
+ *
+ * @retval NRF_SUCCESS Encoding success.
+ * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length.
+ */
+uint32_t ble_gap_rssi_start_req_enc(uint16_t conn_handle,
+ uint8_t threshold_dbm,
+ uint8_t skip_count,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len);
+
+/**@brief Decodes response to @ref sd_ble_gap_rssi_start command.
+ *
+ * @sa @ref ble_gap_rssi_start_req_enc for command request encoder.
+ *
+ * @param[in] p_buf Pointer to beginning of command response packet.
+ * @param[in] packet_len Length (in bytes) of response packet.
+ * @param[out] p_result_code Command response result code.
+ *
+ * @retval NRF_SUCCESS Decoding success.
+ * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_DATA_SIZE Decoding failure. Incorrect buffer length.
+ * @retval NRF_ERROR_INVALID_DATA Decoding failure. Decoded operation code does not match expected
+ * operation code.
+ */
+uint32_t ble_gap_rssi_start_rsp_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ uint32_t * const p_result_code);
+#ifndef S112
+/**@brief Encodes @ref sd_ble_gap_scan_stop command request.
+ *
+ * @sa @ref ble_gap_scan_stop_rsp_dec for command response decoder.
+ *
+ * @param[in] p_buf Pointer to buffer where encoded data command will be returned.
+ * @param[in, out] p_buf_len \c in: size of \p p_buf buffer.
+ * \c out: Length of encoded command packet.
+ *
+ * @retval NRF_SUCCESS Encoding success.
+ * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length.
+ */
+uint32_t ble_gap_scan_stop_req_enc(uint8_t * const p_buf, uint32_t * const p_buf_len);
+
+/**@brief Decodes response to @ref sd_ble_gap_scan_stop command.
+ *
+ * @sa @ref ble_gap_scan_stop_req_enc for command request encoder.
+ *
+ * @param[in] p_buf Pointer to beginning of command response packet.
+ * @param[in] packet_len Length (in bytes) of response packet.
+ * @param[out] p_result_code Command response result code.
+ *
+ * @retval NRF_SUCCESS Decoding success.
+ * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_DATA_SIZE Decoding failure. Incorrect buffer length.
+ * @retval NRF_ERROR_INVALID_DATA Decoding failure. Decoded operation code does not match expected
+ * operation code.
+ */
+uint32_t ble_gap_scan_stop_rsp_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ uint32_t * const p_result_code);
+
+/**@brief Encodes @ref sd_ble_gap_scan_start command request.
+ *
+ * @sa @ref ble_gap_scan_start_rsp_dec for command response decoder.
+ *
+ * @param[in] p_scan_params Pointer to scan params structure.
+ * @param[in] p_buf Pointer to buffer where encoded data command will be returned.
+ * @param[in, out] p_buf_len \c in: size of \p p_buf buffer.
+ * \c out: Length of encoded command packet.
+ *
+ * @retval NRF_SUCCESS Encoding success.
+ * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length.
+ */
+uint32_t ble_gap_scan_start_req_enc(ble_gap_scan_params_t const * p_scan_params,
+#if defined(NRF_SD_BLE_API_VERSION) && NRF_SD_BLE_API_VERSION > 5
+ ble_data_t const * p_adv_report_buffer,
+#endif
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len);
+
+/**@brief Decodes response to @ref sd_ble_gap_scan_start command.
+ *
+ * @sa @ref ble_gap_scan_start_req_enc for command request encoder.
+ *
+ * @param[in] p_buf Pointer to beginning of command response packet.
+ * @param[in] packet_len Length (in bytes) of response packet.
+ * @param[out] p_result_code Command response result code.
+ *
+ * @retval NRF_SUCCESS Decoding success.
+ * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_DATA_SIZE Decoding failure. Incorrect buffer length.
+ * @retval NRF_ERROR_INVALID_DATA Decoding failure. Decoded operation code does not match expected
+ * operation code.
+ */
+uint32_t ble_gap_scan_start_rsp_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ uint32_t * const p_result_code);
+
+/**@brief Encodes @ref sd_ble_gap_connect command request.
+ *
+ * @sa @ref ble_gap_connect_rsp_dec for command response decoder.
+ *
+ * @param[in] p_peer_addr Pointer to peer address.
+ * @param[in] p_scan_params Pointer to scan params structure.
+ * @param[in] p_conn_params Pointer to desired connection parameters.
+ * @param[in] p_buf Pointer to buffer where encoded data command will be returned.
+ * @param[in, out] p_buf_len \c in: size of \p p_buf buffer.
+ * \c out: Length of encoded command packet.
+ *
+ * @retval NRF_SUCCESS Encoding success.
+ * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length.
+ */
+uint32_t ble_gap_connect_req_enc(ble_gap_addr_t const * const p_peer_addr,
+ ble_gap_scan_params_t const * const p_scan_params,
+ ble_gap_conn_params_t const * const p_conn_params,
+#if NRF_SD_BLE_API_VERSION >= 4
+ uint8_t conn_cfg_tag,
+#endif
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len);
+
+/**@brief Decodes response to @ref sd_ble_gap_connect command.
+ *
+ * @sa @ref ble_gap_connect_req_enc for command request encoder.
+ *
+ * @param[in] p_buf Pointer to beginning of command response packet.
+ * @param[in] packet_len Length (in bytes) of response packet.
+ * @param[out] p_result_code Command response result code.
+ *
+ * @retval NRF_SUCCESS Decoding success.
+ * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_DATA_SIZE Decoding failure. Incorrect buffer length.
+ * @retval NRF_ERROR_INVALID_DATA Decoding failure. Decoded operation code does not match expected
+ * operation code.
+ */
+uint32_t ble_gap_connect_rsp_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ uint32_t * const p_result_code);
+
+/**@brief Encodes @ref sd_ble_gap_connect_cancel command request.
+ *
+ * @sa @ref ble_gap_connect_cancel_rsp_dec for command response decoder.
+ *
+ * @param[in] p_buf Pointer to buffer where encoded data command will be returned.
+ * @param[in, out] p_buf_len \c in: size of \p p_buf buffer.
+ * \c out: Length of encoded command packet.
+ *
+ * @retval NRF_SUCCESS Encoding success.
+ * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length.
+ */
+uint32_t ble_gap_connect_cancel_req_enc(uint8_t * const p_buf,
+ uint32_t * const p_buf_len);
+
+/**@brief Decodes response to @ref sd_ble_gap_connect_cancel command.
+ *
+ * @sa @ref ble_gap_connect_cancel_req_enc for command request encoder.
+ *
+ * @param[in] p_buf Pointer to beginning of command response packet.
+ * @param[in] packet_len Length (in bytes) of response packet.
+ * @param[out] p_result_code Command response result code.
+ *
+ * @retval NRF_SUCCESS Decoding success.
+ * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_DATA_SIZE Decoding failure. Incorrect buffer length.
+ * @retval NRF_ERROR_INVALID_DATA Decoding failure. Decoded operation code does not match expected
+ * operation code.
+ */
+uint32_t ble_gap_connect_cancel_rsp_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ uint32_t * const p_result_code);
+
+
+/**@brief Encodes @ref sd_ble_gap_encrypt command request.
+ *
+ * @sa @ref ble_gap_encrypt_rsp_dec for command response decoder.
+ *
+ * @param[in] conn_handle Connection handle.
+ * @param[in] p_master_id Pointer to a master identification structure.
+ * @param[in] p_enc_info Pointer to desired connection parameters.
+ * @param[in] p_buf Pointer to a ble_gap_enc_info_t encryption information structure.
+ * @param[in, out] p_buf_len \c in: size of \p p_buf buffer.
+ * \c out: Length of encoded command packet.
+ *
+ * @retval NRF_SUCCESS Encoding success.
+ * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length.
+ */
+
+uint32_t ble_gap_encrypt_req_enc(uint16_t conn_handle,
+ ble_gap_master_id_t const * const p_master_id,
+ ble_gap_enc_info_t const * const p_enc_info,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len);
+
+
+/**@brief Decodes response to @ref sd_ble_gap_encrypt command.
+ *
+ * @sa @ref ble_gap_encrypt_req_enc for command request encoder.
+ *
+ * @param[in] p_buf Pointer to beginning of command response packet.
+ * @param[in] packet_len Length (in bytes) of response packet.
+ * @param[out] p_result_code Command response result code.
+ *
+ * @retval NRF_SUCCESS Decoding success.
+ * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_DATA_SIZE Decoding failure. Incorrect buffer length.
+ * @retval NRF_ERROR_INVALID_DATA Decoding failure. Decoded operation code does not match expected
+ * operation code.
+ */
+uint32_t ble_gap_encrypt_rsp_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ uint32_t * const p_result_code);
+#endif //!S112
+
+/**@brief Encodes @ref sd_ble_gap_rssi_get command request.
+ *
+ * @sa @ref ble_gap_rssi_get_rsp_dec for command response decoder.
+ *
+ * @param[in] conn_handle Connection handle.
+ * @param[in] p_rssi Pointer to the RSSI value.
+ * @param[in] p_buf Pointer to buffer where encoded data command will be returned.
+ * @param[in, out] p_buf_len \c in: size of \p p_buf buffer.
+ * \c out: Length of encoded command packet.
+ *
+ * @retval NRF_SUCCESS Encoding success.
+ * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length.
+ */
+uint32_t ble_gap_rssi_get_req_enc(uint16_t conn_handle,
+ int8_t const * const p_rssi,
+#if NRF_SD_BLE_API_VERSION > 5
+ uint8_t const * const p_ch_index,
+#endif
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len);
+
+/**@brief Decodes response to @ref sd_ble_gap_rssi_get command.
+ *
+ * @sa @ref ble_gap_rssi_get_req_enc for command request encoder.
+ *
+ * @param[in] p_buf Pointer to beginning of command response packet.
+ * @param[in] packet_len Length (in bytes) of response packet.
+ * @param[out] p_rssi Pointer to RSSI value.
+ * @param[out] p_result_code Command response result code.
+ *
+ * @retval NRF_SUCCESS Decoding success.
+ * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_DATA_SIZE Decoding failure. Incorrect buffer length.
+ * @retval NRF_ERROR_INVALID_DATA Decoding failure. Decoded operation code does not match expected
+ * operation code.
+ */
+uint32_t ble_gap_rssi_get_rsp_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ int8_t * const p_rssi,
+#if NRF_SD_BLE_API_VERSION > 5
+ uint8_t * const p_ch_index,
+#endif
+ uint32_t * const p_result_code);
+
+/**@brief Encodes @ref sd_ble_gap_keypress_notify command request.
+ *
+ * @sa @ref ble_gap_keypress_notify_rsp_dec for command response decoder.
+ *
+ * @param[in] conn_handle Connection handle.
+ * @param[in] kp_not See @ref sd_ble_gap_keypress_notify.
+ * @param[in] p_buf Pointer to buffer where encoded data command will be returned.
+ * @param[in, out] p_buf_len \c in: size of \p p_buf buffer.
+ * \c out: Length of encoded command packet.
+ *
+ * @retval NRF_SUCCESS Encoding success.
+ * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length.
+ */
+uint32_t ble_gap_keypress_notify_req_enc(uint16_t conn_handle,
+ uint8_t kp_not,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len);
+
+/**@brief Decodes response to @ref sd_ble_gap_keypress_notify command.
+ *
+ * @sa @ref ble_gap_keypress_notify_req_enc for command request encoder.
+ *
+ * @param[in] p_buf Pointer to beginning of command response packet.
+ * @param[in] packet_len Length (in bytes) of response packet.
+ * @param[out] p_result_code Command response result code.
+ *
+ * @retval NRF_SUCCESS Decoding success.
+ * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_DATA_SIZE Decoding failure. Incorrect buffer length.
+ * @retval NRF_ERROR_INVALID_DATA Decoding failure. Decoded operation code does not match expected
+ * operation code.
+ */
+uint32_t ble_gap_keypress_notify_rsp_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ uint32_t * const p_result_code);
+
+/**@brief Encodes @ref sd_ble_gap_lesc_dhkey_reply command request.
+ *
+ * @sa @ref ble_gap_lesc_dhkey_reply_rsp_dec for command response decoder.
+ *
+ * @param[in] conn_handle Connection handle.
+ * @param[in] p_dhkey See @ref sd_ble_gap_lesc_dhkey_reply.
+ * @param[in] p_buf Pointer to buffer where encoded data command will be returned.
+ * @param[in, out] p_buf_len \c in: size of \p p_buf buffer.
+ * \c out: Length of encoded command packet.
+ *
+ * @retval NRF_SUCCESS Encoding success.
+ * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length.
+ */
+uint32_t ble_gap_lesc_dhkey_reply_req_enc(uint16_t conn_handle,
+ ble_gap_lesc_dhkey_t const *p_dhkey,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len);
+
+/**@brief Decodes response to @ref sd_ble_gap_lesc_dhkey_reply command.
+ *
+ * @sa @ref ble_gap_lesc_dhkey_reply_req_enc for command request encoder.
+ *
+ * @param[in] p_buf Pointer to beginning of command response packet.
+ * @param[in] packet_len Length (in bytes) of response packet.
+ * @param[out] p_result_code Command response result code.
+ *
+ * @retval NRF_SUCCESS Decoding success.
+ * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_DATA_SIZE Decoding failure. Incorrect buffer length.
+ * @retval NRF_ERROR_INVALID_DATA Decoding failure. Decoded operation code does not match expected
+ * operation code.
+ */
+uint32_t ble_gap_lesc_dhkey_reply_rsp_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ uint32_t * const p_result_code);
+
+/**@brief Encodes @ref sd_ble_gap_lesc_oob_data_set command request.
+ *
+ * @sa @ref ble_gap_lesc_oob_data_set_rsp_dec for command response decoder.
+ *
+ * @param[in] conn_handle Connection handle.
+ * @param[in] p_oobd_own See @ref sd_ble_gap_lesc_oob_data_set.
+ * @param[in] p_oobd_peer See @ref sd_ble_gap_lesc_oob_data_set.
+ * @param[in] p_buf Pointer to buffer where encoded data command will be returned.
+ * @param[in, out] p_buf_len \c in: size of \p p_buf buffer.
+ * \c out: Length of encoded command packet.
+ *
+ * @retval NRF_SUCCESS Encoding success.
+ * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length.
+ */
+uint32_t ble_gap_lesc_oob_data_set_req_enc(uint16_t conn_handle,
+ ble_gap_lesc_oob_data_t const *p_oobd_own,
+ ble_gap_lesc_oob_data_t const *p_oobd_peer,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len);
+
+/**@brief Decodes response to @ref sd_ble_gap_lesc_oob_data_set command.
+ *
+ * @sa @ref ble_gap_lesc_oob_data_set_req_enc for command request encoder.
+ *
+ * @param[in] p_buf Pointer to beginning of command response packet.
+ * @param[in] packet_len Length (in bytes) of response packet.
+ * @param[out] p_result_code Command response result code.
+ *
+ * @retval NRF_SUCCESS Decoding success.
+ * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_DATA_SIZE Decoding failure. Incorrect buffer length.
+ * @retval NRF_ERROR_INVALID_DATA Decoding failure. Decoded operation code does not match expected
+ * operation code.
+ */
+uint32_t ble_gap_lesc_oob_data_set_rsp_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ uint32_t * const p_result_code);
+
+/**@brief Encodes @ref sd_ble_gap_lesc_oob_data_get command request.
+ *
+ * @sa @ref ble_gap_lesc_oob_data_get_rsp_dec for command response decoder.
+ *
+ * @param[in] conn_handle Connection handle.
+ * @param[in] p_pk_own See @ref sd_ble_gap_lesc_oob_data_get.
+ * @param[in] p_oobd_own See @ref sd_ble_gap_lesc_oob_data_get.
+ * @param[in] p_buf Pointer to buffer where encoded data command will be returned.
+ * @param[in, out] p_buf_len \c in: size of \p p_buf buffer.
+ * \c out: Length of encoded command packet.
+ *
+ * @retval NRF_SUCCESS Encoding success.
+ * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length.
+ */
+uint32_t ble_gap_lesc_oob_data_get_req_enc(uint16_t conn_handle,
+ ble_gap_lesc_p256_pk_t const *p_pk_own,
+ ble_gap_lesc_oob_data_t *p_oobd_own,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len);
+
+/**@brief Decodes response to @ref sd_ble_gap_lesc_oob_data_get command.
+ *
+ * @sa @ref ble_gap_lesc_oob_data_get_req_enc for command request encoder.
+ *
+ * @param[in] p_buf Pointer to beginning of command response packet.
+ * @param[in] packet_len Length (in bytes) of response packet.
+ * @param[out] pp_oobd_own Pointer to pointer to location where OOB data is decoded.
+ * @param[out] p_result_code Command response result code.
+ *
+ * @retval NRF_SUCCESS Decoding success.
+ * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_DATA_SIZE Decoding failure. Incorrect buffer length.
+ * @retval NRF_ERROR_INVALID_DATA Decoding failure. Decoded operation code does not match expected
+ * operation code.
+ */
+uint32_t ble_gap_lesc_oob_data_get_rsp_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ ble_gap_lesc_oob_data_t * *pp_oobd_own,
+ uint32_t * const p_result_code);
+
+/**
+ * @brief Encodes @ref sd_ble_gap_addr_get command request.
+ *
+ * @sa @ref ble_gap_addr_get_rsp_dec for command response decoder.
+ *
+ * @param[in] p_address Pointer to address.
+ * @param[in] p_buf Pointer to buffer where encoded data command will be returned.
+ * @param[in,out] p_buf_len \c in: Size of \p p_buf buffer.
+ * \c out: Length of encoded command packet.
+ *
+ * @note \p p_address will not be updated by the command
+ * request encoder. Updated values are set by @ref ble_gap_addr_get_rsp_dec.
+ *
+ * @retval NRF_SUCCESS Encoding success.
+ * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length.
+ */
+uint32_t ble_gap_addr_get_req_enc(ble_gap_addr_t const * const p_address,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len);
+
+/**
+ * @brief Decodes response to @ref sd_ble_gap_addr_get command.
+ *
+ * @sa @ref ble_gap_addr_get_req_enc for command request encoder.
+ *
+ * @param[in] p_buf Pointer to beginning of command response packet.
+ * @param[in] packet_len Length (in bytes) of response packet.
+ * @param[out] p_address Pointer to address.
+ * @param[out] p_result_code Command result code.
+ *
+ * @retval NRF_SUCCESS Decoding success.
+ * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length.
+ * @retval NRF_ERROR_INVALID_DATA Decoding failure. Decoded operation code does not match
+ * expected operation code.
+ */
+uint32_t ble_gap_addr_get_rsp_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ ble_gap_addr_t * const p_address,
+ uint32_t * const p_result_code);
+
+/**
+ * @brief Encodes @ref sd_ble_gap_addr_set command request.
+ *
+ * @sa @ref ble_gap_addr_set_rsp_dec for command response decoder.
+ *
+ * @param[in] p_addr Pointer to address structure.
+ * @param[in,out] p_buf Pointer to buffer where encoded data command will be returned.
+ * @param[in,out] p_buf_len \c in: size of \p p_buf buffer.
+ * \c out: Length of encoded command packet.
+ *
+ * @retval NRF_SUCCESS Encoding success.
+ * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length.
+ */
+uint32_t ble_gap_addr_set_req_enc(ble_gap_addr_t const * const p_addr,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len);
+
+/**
+ * @brief Decodes response to @ref sd_ble_gap_addr_set command.
+ *
+ * @sa @ref ble_gap_addr_set_req_enc for command request encoder.
+ *
+ * @param[in] p_buf Pointer to beginning of command response packet.
+ * @param[in] packet_len Length (in bytes) of response packet.
+ * @param[out] p_result_code Command result code.
+ *
+ * @retval NRF_SUCCESS Decoding success.
+ * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length.
+ * @retval NRF_ERROR_INVALID_DATA Decoding failure. Decoded operation code does not match
+ * expected operation code.
+ */
+uint32_t ble_gap_addr_set_rsp_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ uint32_t * const p_result_code);
+
+/**
+ * @brief Encodes @ref sd_ble_gap_privacy_set command request.
+ *
+ * @sa @ref ble_gap_privacy_set_rsp_dec for command response decoder.
+ *
+ * @param[in] p_privacy_params Pointer to privacy settings structure.
+ * @param[in,out] p_buf Pointer to buffer where encoded data command will be returned.
+ * @param[in,out] p_buf_len \c in: size of \p p_buf buffer.
+ * \c out: Length of encoded command packet.
+ *
+ * @retval NRF_SUCCESS Encoding success.
+ * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length.
+ */
+uint32_t ble_gap_privacy_set_req_enc(ble_gap_privacy_params_t const * p_privacy_params,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len);
+
+/**
+ * @brief Decodes response to @ref sd_ble_gap_privacy_set command.
+ *
+ * @sa @ref ble_gap_privacy_set_req_enc for command request encoder.
+ *
+ * @param[in] p_buf Pointer to beginning of command response packet.
+ * @param[in] packet_len Length (in bytes) of response packet.
+ * @param[out] p_result_code Command result code.
+ *
+ * @retval NRF_SUCCESS Decoding success.
+ * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length.
+ * @retval NRF_ERROR_INVALID_DATA Decoding failure. Decoded operation code does not match
+ * expected operation code.
+ */
+uint32_t ble_gap_privacy_set_rsp_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ uint32_t * const p_result_code);
+
+/**
+ * @brief Encodes @ref sd_ble_gap_privacy_get command request.
+ *
+ * @sa @ref ble_gap_privacy_get_rsp_dec for command response decoder.
+ *
+ * @param[in] p_privacy_params Pointer to privacy settings structure.
+ * @param[in,out] p_buf Pointer to buffer where encoded data command will be returned.
+ * @param[in,out] p_buf_len \c in: size of \p p_buf buffer.
+ * \c out: Length of encoded command packet.
+ *
+ * @retval NRF_SUCCESS Encoding success.
+ * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length.
+ */
+uint32_t ble_gap_privacy_get_req_enc(ble_gap_privacy_params_t const * const p_privacy_params,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len);
+
+/**
+ * @brief Decodes response to @ref sd_ble_gap_privacy_get command.
+ *
+ * @sa @ref ble_gap_privacy_get_req_enc for command request encoder.
+ *
+ * @param[in] p_buf Pointer to beginning of command response packet.
+ * @param[in] packet_len Length (in bytes) of response packet.
+ * @param[out] p_privacy_params Pointer to privacy settings structure.
+ * @param[out] p_result_code Command result code.
+ *
+ * @retval NRF_SUCCESS Decoding success.
+ * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length.
+ * @retval NRF_ERROR_INVALID_DATA Decoding failure. Decoded operation code does not match
+ * expected operation code.
+ */
+uint32_t ble_gap_privacy_get_rsp_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ ble_gap_privacy_params_t const * const p_privacy_params,
+ uint32_t * const p_result_code);
+
+/**
+ * @brief Encodes @ref sd_ble_gap_whitelist_set command request.
+ *
+ * @sa @ref ble_gap_whitelist_set_rsp_dec for command response decoder.
+ *
+ * @param[in] pp_wl_addrs Pointer to a whitelist of peer addresses.
+ * @param[out] len Pointer to a length of the whitelist.
+ * @param[in,out] p_buf Pointer to buffer where encoded data command will be returned.
+ * @param[in,out] p_buf_len \c in: size of \p p_buf buffer.
+ * \c out: Length of encoded command packet.
+ *
+ * @retval NRF_SUCCESS Encoding success.
+ * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length.
+ */
+uint32_t ble_gap_whitelist_set_req_enc(ble_gap_addr_t const * const * const pp_wl_addrs,
+ uint8_t const len,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len);
+
+/**
+ * @brief Decodes response to @ref sd_ble_gap_whitelist_set command.
+ *
+ * @sa @ref ble_gap_whitelist_set_req_enc for command request encoder.
+ *
+ * @param[in] p_buf Pointer to beginning of command response packet.
+ * @param[in] packet_len Length (in bytes) of response packet.
+ * @param[out] p_result_code Command result code.
+ *
+ * @retval NRF_SUCCESS Decoding success.
+ * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length.
+ * @retval NRF_ERROR_INVALID_DATA Decoding failure. Decoded operation code does not match
+ * expected operation code.
+ */
+uint32_t ble_gap_whitelist_set_rsp_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ uint32_t * const p_result_code);
+
+/**
+ * @brief Encodes @ref sd_ble_gap_device_identities_set command request.
+ *
+ * @sa @ref ble_gap_device_identities_set_rsp_dec for command response decoder.
+ *
+ * @param[in] pp_id_keys Pointer to an array of peer identity addresses and peer IRKs.
+ * @param[in] pp_local_irks Pointer to an array of local IRKs.
+ * @param[out] len Pointer to a length of the device identity list.
+ * @param[in,out] p_buf Pointer to buffer where encoded data command will be returned.
+ * @param[in,out] p_buf_len \c in: size of \p p_buf buffer.
+ * \c out: Length of encoded command packet.
+ *
+ * @retval NRF_SUCCESS Encoding success.
+ * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length.
+ */
+uint32_t ble_gap_device_identities_set_req_enc(ble_gap_id_key_t const * const * const pp_id_keys,
+ ble_gap_irk_t const * const * const pp_local_irks,
+ uint8_t const len,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len);
+/**
+ * @brief Decodes response to @ref sd_ble_gap_device_identities_set command.
+ *
+ * @sa @ref ble_gap_device_identities_set_req_enc for command request encoder.
+ *
+ * @param[in] p_buf Pointer to beginning of command response packet.
+ * @param[in] packet_len Length (in bytes) of response packet.
+ * @param[out] p_result_code Command result code.
+ *
+ * @retval NRF_SUCCESS Decoding success.
+ * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length.
+ * @retval NRF_ERROR_INVALID_DATA Decoding failure. Decoded operation code does not match
+ * expected operation code.
+ */
+uint32_t ble_gap_device_identities_set_rsp_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ uint32_t * const p_result_code);
+
+#if NRF_SD_BLE_API_VERSION >= 4 && !defined(S112)
+/**
+ * @brief Encodes @ref sd_ble_gap_data_length_update command request.
+ *
+ * @sa @ref ble_gap_data_length_update_rsp_dec for command response decoder.
+ *
+ * @param[in] conn_handle Connection handle.
+ * @param[in] p_dl_params Pointer to a data length params structure.
+ * @param[out] p_dl_limitation Pointer to a data length limitation structure.
+ * @param[in,out] p_buf Pointer to buffer where encoded data command will be returned.
+ * @param[in,out] p_buf_len \c in: size of \p p_buf buffer.
+ * \c out: Length of encoded command packet.
+ *
+ * @retval NRF_SUCCESS Encoding success.
+ * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length.
+ */
+uint32_t ble_gap_data_length_update_req_enc(uint16_t conn_handle,
+ ble_gap_data_length_params_t const * p_dl_params,
+ ble_gap_data_length_limitation_t * p_dl_limitation,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len);
+/**
+ * @brief Decodes response to @ref sd_ble_gap_data_length_update command.
+ *
+ * @sa @ref ble_gap_data_length_update_req_enc for command request encoder.
+ *
+ * @param[in] p_buf Pointer to beginning of command response packet.
+ * @param[in] packet_len Length (in bytes) of response packet.
+ * @param[out] p_dl_limitation Pointer to a data length limitation structure.
+ * @param[out] p_result_code Command result code.
+ *
+ * @retval NRF_SUCCESS Decoding success.
+ * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length.
+ * @retval NRF_ERROR_INVALID_DATA Decoding failure. Decoded operation code does not match
+ * expected operation code.
+ */
+uint32_t ble_gap_data_length_update_rsp_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ ble_gap_data_length_limitation_t * p_dl_limitation,
+ uint32_t * const p_result_code);
+#endif
+
+#if NRF_SD_BLE_API_VERSION >= 5
+/**@brief Encodes @ref sd_ble_gap_phy_update command request.
+ *
+ * @sa @ref ble_gap_phy_update_rsp_dec for command response decoder.
+ *
+ * @param[in] conn_handle Connection handle of the connection.
+ * @param[in] p_gap_phys Pointer to a @ref ble_gap_phys_t
+ * structure.
+ * @param[in] p_buf Pointer to buffer where encoded data command will be returned.
+ * @param[in, out] p_buf_len \c in: size of \p p_buf buffer.
+ * \c out: Length of encoded command packet.
+ *
+ * @retval NRF_SUCCESS Encoding success.
+ * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length.
+ */
+uint32_t ble_gap_phy_update_req_enc(uint16_t conn_handle,
+ ble_gap_phys_t const * p_gap_phys,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len);
+
+/**@brief Decodes response to @ref sd_ble_gap_phy_update command.
+ *
+ * @sa @ref ble_gap_phy_update_req_enc for command request encoder.
+ *
+ * @param[in] p_buf Pointer to beginning of command response packet.
+ * @param[in] packet_len Length (in bytes) of response packet.
+ * @param[out] p_result_code Command response result code.
+ *
+ * @retval NRF_SUCCESS Decoding success.
+ * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_DATA_SIZE Decoding failure. Incorrect buffer length.
+ * @retval NRF_ERROR_INVALID_DATA Decoding failure. Decoded operation code does not match expected
+ * operation code.
+ */
+uint32_t ble_gap_phy_update_rsp_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ uint32_t * const p_result_code);
+#endif
+
+#if NRF_SD_BLE_API_VERSION >= 6
+/**@brief Encodes @ref sd_ble_gap_adv_set_configure command request.
+ *
+ * @sa @ref ble_gap_adv_set_configure_rsp_dec for command response decoder.
+ *
+ * @param[in] p_adv_handle Advertising handle.
+ * @param[in] p_adv_data Pointer to a @ref ble_gap_adv_data_t structure.
+ * @param[in] p_adv_params Pointer to a @ref ble_gap_adv_params_t structure.
+ * @param[in] p_buf Pointer to buffer where encoded data command will be returned.
+ * @param[in, out] p_buf_len \c in: size of \p p_buf buffer.
+ * \c out: Length of encoded command packet.
+ *
+ * @retval NRF_SUCCESS Encoding success.
+ * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length.
+ */
+uint32_t ble_gap_adv_set_configure_req_enc(uint8_t * p_adv_handle,
+ ble_gap_adv_data_t const * p_adv_data,
+ ble_gap_adv_params_t const *p_adv_params,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len);
+
+
+/**@brief Decodes response to @ref sd_ble_gap_adv_set_configure command.
+ *
+ * @sa @ref ble_gap_adv_set_configure_req_enc for command request encoder.
+ *
+ * @param[in] p_buf Pointer to beginning of command response packet.
+ * @param[in] packet_len Length (in bytes) of response packet.
+ * @param[out] p_adv_handle Advertising handle.
+ * @param[out] p_result_code Command response result code.
+ *
+ * @retval NRF_SUCCESS Decoding success.
+ * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_DATA_SIZE Decoding failure. Incorrect buffer length.
+ * @retval NRF_ERROR_INVALID_DATA Decoding failure. Decoded operation code does not match expected
+ * operation code.
+ */
+uint32_t ble_gap_adv_set_configure_rsp_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ uint8_t * p_adv_handle,
+ uint32_t * const p_result_code);
+
+/**@brief Encodes @ref sd_ble_gap_qos_channel_survey_start command request.
+ *
+ * @sa @ref ble_gap_qos_channel_survey_start_rsp_dec for command response decoder.
+ *
+ * @param[in] interval_us Interval.
+ * @param[in] p_buf Pointer to buffer where encoded data command will be returned.
+ * @param[in, out] p_buf_len \c in: size of \p p_buf buffer.
+ * \c out: Length of encoded command packet.
+ *
+ * @retval NRF_SUCCESS Encoding success.
+ * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length.
+ */
+uint32_t ble_gap_qos_channel_survey_start_req_enc(uint32_t interval_us,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len);
+
+
+/**@brief Decodes response to @ref sd_ble_gap_qos_channel_survey_start command.
+ *
+ * @sa @ref ble_gap_qos_channel_survey_start_req_enc for command request encoder.
+ *
+ * @param[in] p_buf Pointer to beginning of command response packet.
+ * @param[in] packet_len Length (in bytes) of response packet.
+ * @param[out] p_result_code Command response result code.
+ *
+ * @retval NRF_SUCCESS Decoding success.
+ * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_DATA_SIZE Decoding failure. Incorrect buffer length.
+ * @retval NRF_ERROR_INVALID_DATA Decoding failure. Decoded operation code does not match expected
+ * operation code.
+ */
+uint32_t ble_gap_qos_channel_survey_start_rsp_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ uint32_t * const p_result_code);
+
+/**@brief Encodes @ref sd_ble_gap_qos_channel_survey_stop command request.
+ *
+ * @sa @ref ble_gap_qos_channel_survey_stop_rsp_dec for command response decoder.
+ *
+ * @param[in] p_buf Pointer to buffer where encoded data command will be returned.
+ * @param[in, out] p_buf_len \c in: size of \p p_buf buffer.
+ * \c out: Length of encoded command packet.
+ *
+ * @retval NRF_SUCCESS Encoding success.
+ * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length.
+ */
+uint32_t ble_gap_qos_channel_survey_stop_req_enc(uint8_t * const p_buf,
+ uint32_t * const p_buf_len);
+
+
+/**@brief Decodes response to @ref sd_ble_gap_qos_channel_survey_stop command.
+ *
+ * @sa @ref ble_gap_qos_channel_survey_stop_req_enc for command request encoder.
+ *
+ * @param[in] p_buf Pointer to beginning of command response packet.
+ * @param[in] packet_len Length (in bytes) of response packet.
+ * @param[out] p_result_code Command response result code.
+ *
+ * @retval NRF_SUCCESS Decoding success.
+ * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_DATA_SIZE Decoding failure. Incorrect buffer length.
+ * @retval NRF_ERROR_INVALID_DATA Decoding failure. Decoded operation code does not match expected
+ * operation code.
+ */
+uint32_t ble_gap_qos_channel_survey_stop_rsp_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ uint32_t * const p_result_code);
+#endif
+/** @} */
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/application/codecs/ble/serializers/ble_gap_evt_app.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/application/codecs/ble/serializers/ble_gap_evt_app.c
new file mode 100644
index 0000000..150a891
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/application/codecs/ble/serializers/ble_gap_evt_app.c
@@ -0,0 +1,415 @@
+/**
+ * Copyright (c) 2014 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#include "ble_gap_evt_app.h"
+#include "ble_serialization.h"
+#include "app_util.h"
+#include "app_ble_gap_sec_keys.h"
+#include "ble_gap_struct_serialization.h"
+#include "cond_field_serialization.h"
+#include <string.h>
+
+extern ser_ble_gap_app_keyset_t m_app_keys_table[];
+
+#ifndef S112
+uint32_t ble_gap_evt_adv_report_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ ble_evt_t * const p_event,
+ uint32_t * const p_event_len)
+{
+ SER_EVT_DEC_BEGIN(BLE_GAP_EVT_ADV_REPORT, gap, adv_report);
+
+ SER_PULL_uint16(&p_event->evt.gap_evt.conn_handle);
+
+#if defined(NRF_SD_BLE_API_VERSION) && NRF_SD_BLE_API_VERSION >= 6
+ //get buffer stored during scan start.
+ err_code = app_ble_gap_scan_data_fetch_clear(&p_event->evt.gap_evt.params.adv_report.data);
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code);
+#endif
+ SER_PULL_FIELD(&p_event->evt.gap_evt.params.adv_report, ble_gap_evt_adv_report_t_dec);
+
+ SER_EVT_DEC_END;
+}
+#endif //!S112
+
+uint32_t ble_gap_evt_auth_key_request_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ ble_evt_t * const p_event,
+ uint32_t * const p_event_len)
+{
+ SER_EVT_DEC_BEGIN(BLE_GAP_EVT_AUTH_KEY_REQUEST, gap, auth_key_request);
+
+ SER_PULL_uint16(&p_event->evt.gap_evt.conn_handle);
+ SER_PULL_uint8(&p_event->evt.gap_evt.params.auth_key_request.key_type);
+
+ SER_EVT_DEC_END;
+}
+
+
+extern ser_ble_gap_app_keyset_t m_app_keys_table[];
+
+uint32_t ble_gap_evt_auth_status_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ ble_evt_t * const p_event,
+ uint32_t * const p_event_len)
+{
+ SER_EVT_DEC_BEGIN(BLE_GAP_EVT_AUTH_STATUS, gap, auth_status);
+
+ SER_PULL_uint16(&p_event->evt.gap_evt.conn_handle);
+ SER_PULL_FIELD(&p_event->evt.gap_evt.params.auth_status, ble_gap_evt_auth_status_t_dec);
+
+ // keyset is an extension of standard event data - used to synchronize keys at application
+ uint32_t conn_index;
+ err_code = app_ble_gap_sec_context_find(p_event->evt.gap_evt.conn_handle, &conn_index);
+ if (err_code == NRF_SUCCESS)
+ {
+ SER_PULL_FIELD(&(m_app_keys_table[conn_index].keyset), ble_gap_sec_keyset_t_dec);
+
+ err_code = app_ble_gap_sec_context_destroy(p_event->evt.gap_evt.conn_handle);
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code);
+ }
+
+ SER_EVT_DEC_END;
+}
+
+
+uint32_t ble_gap_evt_conn_param_update_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ ble_evt_t * const p_event,
+ uint32_t * const p_event_len)
+{
+ SER_EVT_DEC_BEGIN(BLE_GAP_EVT_CONN_PARAM_UPDATE, gap, conn_param_update);
+
+ SER_PULL_uint16(&p_event->evt.gap_evt.conn_handle);
+ SER_PULL_FIELD(&p_event->evt.gap_evt.params.conn_param_update, ble_gap_evt_conn_param_update_t_dec);
+
+ SER_EVT_DEC_END;
+}
+
+
+#ifndef S112
+uint32_t ble_gap_evt_conn_param_update_request_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ ble_evt_t * const p_event,
+ uint32_t * const p_event_len)
+{
+ SER_EVT_DEC_BEGIN(BLE_GAP_EVT_CONN_PARAM_UPDATE_REQUEST, gap, conn_param_update_request);
+
+ SER_PULL_uint16(&p_event->evt.gap_evt.conn_handle);
+ SER_PULL_FIELD(&p_event->evt.gap_evt.params.conn_param_update_request,
+ ble_gap_evt_conn_param_update_request_t_dec);
+
+ SER_EVT_DEC_END;
+}
+#endif
+
+uint32_t ble_gap_evt_conn_sec_update_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ ble_evt_t * const p_event,
+ uint32_t * const p_event_len)
+{
+ SER_EVT_DEC_BEGIN(BLE_GAP_EVT_CONN_SEC_UPDATE, gap, conn_sec_update);
+
+ SER_PULL_uint16(&p_event->evt.gap_evt.conn_handle);
+ SER_PULL_FIELD(&p_event->evt.gap_evt.params.conn_sec_update, ble_gap_evt_conn_sec_update_t_dec);
+
+ SER_EVT_DEC_END;
+}
+
+uint32_t ble_gap_evt_connected_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ ble_evt_t * const p_event,
+ uint32_t * const p_event_len)
+{
+ SER_EVT_DEC_BEGIN(BLE_GAP_EVT_CONNECTED, gap, connected);
+
+ SER_PULL_uint16(&p_event->evt.gap_evt.conn_handle);
+ SER_PULL_FIELD(&p_event->evt.gap_evt.params.connected, ble_gap_evt_connected_t_dec);
+#if defined(NRF_SD_BLE_API_VERSION) && NRF_SD_BLE_API_VERSION > 5
+ if (BLE_GAP_ROLE_PERIPH == p_event->evt.gap_evt.params.connected.role)
+ {
+ err_code = app_ble_gap_adv_set_unregister(p_event->evt.gap_evt.params.connected.adv_handle,
+ &p_event->evt.gap_evt.params.connected.adv_data.adv_data.p_data,
+ &p_event->evt.gap_evt.params.connected.adv_data.scan_rsp_data.p_data);
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code);
+ }
+#endif
+ SER_EVT_DEC_END;
+}
+
+
+uint32_t ble_gap_evt_disconnected_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ ble_evt_t * const p_event,
+ uint32_t * const p_event_len)
+{
+ SER_EVT_DEC_BEGIN(BLE_GAP_EVT_DISCONNECTED, gap, disconnected);
+
+ SER_PULL_uint16(&p_event->evt.gap_evt.conn_handle);
+ SER_PULL_FIELD(&p_event->evt.gap_evt.params.disconnected, ble_gap_evt_disconnected_t_dec);
+
+ SER_EVT_DEC_END;
+}
+
+uint32_t ble_gap_evt_key_pressed_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ ble_evt_t * const p_event,
+ uint32_t * const p_event_len)
+{
+ SER_EVT_DEC_BEGIN(BLE_GAP_EVT_KEY_PRESSED, gap, key_pressed);
+
+ SER_PULL_uint16(&p_event->evt.gap_evt.conn_handle);
+ SER_PULL_uint8(&p_event->evt.gap_evt.params.key_pressed.kp_not);
+
+ SER_EVT_DEC_END;
+}
+
+
+uint32_t ble_gap_evt_lesc_dhkey_request_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ ble_evt_t * const p_event,
+ uint32_t * const p_event_len)
+{
+ SER_EVT_DEC_BEGIN(BLE_GAP_EVT_LESC_DHKEY_REQUEST, gap, lesc_dhkey_request);
+
+ uint8_t ser_data;
+ SER_PULL_uint16(&p_event->evt.gap_evt.conn_handle);
+
+ // keyset is an extension of standard event data - used to synchronize keys at application
+ uint32_t conn_index;
+ err_code = app_ble_gap_sec_context_find(p_event->evt.gap_evt.conn_handle, &conn_index);
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code);
+ p_event->evt.gap_evt.params.lesc_dhkey_request.p_pk_peer = m_app_keys_table[conn_index].keyset.keys_peer.p_pk;
+ SER_PULL_COND(&p_event->evt.gap_evt.params.lesc_dhkey_request.p_pk_peer, ble_gap_lesc_p256_pk_t_dec);
+
+ SER_PULL_uint8(&ser_data);
+ p_event->evt.gap_evt.params.lesc_dhkey_request.oobd_req = ser_data & 0x01;
+
+ SER_EVT_DEC_END;
+}
+
+
+#define PASSKEY_LEN sizeof (p_event->evt.gap_evt.params.passkey_display.passkey)
+
+
+uint32_t ble_gap_evt_passkey_display_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ ble_evt_t * const p_event,
+ uint32_t * const p_event_len)
+{
+ SER_EVT_DEC_BEGIN(BLE_GAP_EVT_PASSKEY_DISPLAY, gap, passkey_display);
+
+ uint8_t ser_data;
+ SER_PULL_uint16(&p_event->evt.gap_evt.conn_handle);
+ SER_PULL_uint8array(p_event->evt.gap_evt.params.passkey_display.passkey, BLE_GAP_PASSKEY_LEN);
+ SER_PULL_uint8(&ser_data);
+ p_event->evt.gap_evt.params.passkey_display.match_request = (ser_data & 0x01);
+
+ SER_EVT_DEC_END;
+}
+
+
+
+uint32_t ble_gap_evt_rssi_changed_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ ble_evt_t * const p_event,
+ uint32_t * const p_event_len)
+{
+ SER_EVT_DEC_BEGIN(BLE_GAP_EVT_RSSI_CHANGED, gap, rssi_changed);
+
+ SER_PULL_uint16(&p_event->evt.gap_evt.conn_handle);
+ SER_PULL_int8(&p_event->evt.gap_evt.params.rssi_changed.rssi);
+#if defined(NRF_SD_BLE_API_VERSION) && NRF_SD_BLE_API_VERSION > 5
+ SER_PULL_uint8(&p_event->evt.gap_evt.params.rssi_changed.ch_index);
+#endif
+ SER_EVT_DEC_END;
+}
+
+
+uint32_t ble_gap_evt_scan_req_report_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ ble_evt_t * const p_event,
+ uint32_t * const p_event_len)
+{
+ SER_EVT_DEC_BEGIN(BLE_GAP_EVT_SCAN_REQ_REPORT, gap, scan_req_report);
+
+ SER_PULL_uint16(&p_event->evt.gap_evt.conn_handle);
+#if defined(NRF_SD_BLE_API_VERSION) && NRF_SD_BLE_API_VERSION > 5
+ SER_PULL_uint8(&p_event->evt.gap_evt.params.scan_req_report.adv_handle);
+#endif
+ SER_PULL_FIELD(&p_event->evt.gap_evt.params.scan_req_report.peer_addr, ble_gap_addr_t_dec);
+ SER_PULL_int8(&p_event->evt.gap_evt.params.scan_req_report.rssi);
+
+ SER_EVT_DEC_END;
+}
+
+uint32_t ble_gap_evt_sec_info_request_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ ble_evt_t * const p_event,
+ uint32_t * const p_event_len)
+{
+ SER_EVT_DEC_BEGIN(BLE_GAP_EVT_SEC_INFO_REQUEST, gap, sec_info_request);
+
+ SER_PULL_uint16(&p_event->evt.gap_evt.conn_handle);
+ SER_PULL_FIELD(&p_event->evt.gap_evt.params.sec_info_request, ble_gap_evt_sec_info_request_t_dec);
+
+ SER_EVT_DEC_END;
+}
+
+uint32_t ble_gap_evt_sec_params_request_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ ble_evt_t * const p_event,
+ uint32_t * const p_event_len)
+{
+ SER_EVT_DEC_BEGIN(BLE_GAP_EVT_SEC_PARAMS_REQUEST, gap, sec_params_request);
+
+ SER_PULL_uint16(&p_event->evt.gap_evt.conn_handle);
+ SER_PULL_FIELD(&p_event->evt.gap_evt.params.sec_params_request, ble_gap_evt_sec_params_request_t_dec);
+
+ SER_EVT_DEC_END;
+}
+
+uint32_t ble_gap_evt_sec_request_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ ble_evt_t * const p_event,
+ uint32_t * const p_event_len)
+{
+ SER_EVT_DEC_BEGIN(BLE_GAP_EVT_SEC_REQUEST, gap, sec_request);
+
+ SER_PULL_uint16(&p_event->evt.gap_evt.conn_handle);
+ SER_PULL_FIELD(&p_event->evt.gap_evt.params.sec_request, ble_gap_evt_sec_request_t_dec);
+
+ SER_EVT_DEC_END;
+}
+
+uint32_t ble_gap_evt_timeout_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ ble_evt_t * const p_event,
+ uint32_t * const p_event_len)
+{
+ SER_EVT_DEC_BEGIN(BLE_GAP_EVT_TIMEOUT, gap, timeout);
+
+ SER_PULL_uint16(&p_event->evt.gap_evt.conn_handle);
+ SER_PULL_uint8(&p_event->evt.gap_evt.params.timeout.src);
+#if defined(NRF_SD_BLE_API_VERSION) && (NRF_SD_BLE_API_VERSION > 5) && !defined(S112)
+ if (p_event->evt.gap_evt.params.timeout.src == BLE_GAP_TIMEOUT_SRC_SCAN)
+ {
+ SER_PULL_uint16(&p_event->evt.gap_evt.params.timeout.params.adv_report_buffer.len);
+ err_code = app_ble_gap_scan_data_fetch_clear(&p_event->evt.gap_evt.params.timeout.params.adv_report_buffer);
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code);
+ }
+#endif
+ SER_EVT_DEC_END;
+}
+
+#if NRF_SD_BLE_API_VERSION >= 5
+uint32_t ble_gap_evt_phy_update_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ ble_evt_t * const p_event,
+ uint32_t * const p_event_len)
+{
+ SER_EVT_DEC_BEGIN(BLE_GAP_EVT_PHY_UPDATE, gap, phy_update);
+
+ SER_PULL_uint16(&p_event->evt.gap_evt.conn_handle);
+ SER_PULL_uint8(&p_event->evt.gap_evt.params.phy_update.status);
+ SER_PULL_uint8(&p_event->evt.gap_evt.params.phy_update.tx_phy);
+ SER_PULL_uint8(&p_event->evt.gap_evt.params.phy_update.rx_phy);
+
+ SER_EVT_DEC_END;
+}
+
+uint32_t ble_gap_evt_phy_update_request_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ ble_evt_t * const p_event,
+ uint32_t * const p_event_len)
+{
+ SER_EVT_DEC_BEGIN(BLE_GAP_EVT_PHY_UPDATE_REQUEST, gap, phy_update);
+
+ SER_PULL_uint16(&p_event->evt.gap_evt.conn_handle);
+ SER_PULL_FIELD(&p_event->evt.gap_evt.params.phy_update_request, ble_gap_phys_t_dec);
+
+ SER_EVT_DEC_END;
+}
+#endif
+#if NRF_SD_BLE_API_VERSION >= 4 && !defined(S112)
+uint32_t ble_gap_evt_data_length_update_request_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ ble_evt_t * const p_event,
+ uint32_t * const p_event_len)
+{
+ SER_EVT_DEC_BEGIN(BLE_GAP_EVT_DATA_LENGTH_UPDATE_REQUEST, gap, timeout);
+
+ SER_PULL_uint16(&p_event->evt.gap_evt.conn_handle);
+ SER_PULL_FIELD(&p_event->evt.gap_evt.params.data_length_update_request.peer_params, ble_gap_data_length_params_t_dec);
+
+ SER_EVT_DEC_END;
+}
+uint32_t ble_gap_evt_data_length_update_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ ble_evt_t * const p_event,
+ uint32_t * const p_event_len)
+{
+ SER_EVT_DEC_BEGIN(BLE_GAP_EVT_DATA_LENGTH_UPDATE, gap, timeout);
+
+ SER_PULL_uint16(&p_event->evt.gap_evt.conn_handle);
+ SER_PULL_FIELD(&p_event->evt.gap_evt.params.data_length_update.effective_params, ble_gap_data_length_params_t_dec);
+
+ SER_EVT_DEC_END;
+}
+#endif //NRF_SD_BLE_API_VERSION >= 4 @@ !defined(S112)
+#if NRF_SD_BLE_API_VERSION > 5
+uint32_t ble_gap_evt_adv_set_terminated_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ ble_evt_t * const p_event,
+ uint32_t * const p_event_len)
+{
+ SER_EVT_DEC_BEGIN(BLE_GAP_EVT_ADV_SET_TERMINATED, gap, adv_set_terminated);
+
+ SER_PULL_uint16(&p_event->evt.gap_evt.conn_handle);
+ SER_PULL_FIELD(&p_event->evt.gap_evt.params.adv_set_terminated, ble_gap_evt_adv_set_terminated_t_dec);
+
+ err_code = app_ble_gap_adv_set_unregister(
+ p_event->evt.gap_evt.params.adv_set_terminated.adv_handle,
+ &p_event->evt.gap_evt.params.adv_set_terminated.adv_data.adv_data.p_data,
+ &p_event->evt.gap_evt.params.adv_set_terminated.adv_data.scan_rsp_data.p_data);
+ SER_ERROR_CHECK(err_code == NRF_SUCCESS, err_code);
+
+ SER_EVT_DEC_END;
+}
+#endif
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/application/codecs/ble/serializers/ble_gap_evt_app.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/application/codecs/ble/serializers/ble_gap_evt_app.h
new file mode 100644
index 0000000..b36e70b
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/application/codecs/ble/serializers/ble_gap_evt_app.h
@@ -0,0 +1,546 @@
+/**
+ * Copyright (c) 2014 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#ifndef BLE_GAP_EVT_APP_H__
+#define BLE_GAP_EVT_APP_H__
+
+/**@file
+ *
+ * @defgroup ble_gap_evt_app GAP Application event decoders
+ * @{
+ * @ingroup ser_app_s130_codecs
+ *
+ * @brief GAP Application event decoders.
+ */
+#include "ble.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @brief Decodes ble_gap_evt_auth_key_request event.
+ *
+ * If \p p_event is null, the required length of \p p_event is returned in \p p_event_len.
+ *
+ * @param[in] p_buf Pointer to the beginning of an event packet.
+ * @param[in] packet_len Length (in bytes) of the event packet.
+ * @param[in,out] p_event Pointer to a \ref ble_evt_t buffer where the decoded event will be
+ * stored. If NULL, required length will be returned in \p p_event_len.
+ * @param[in,out] p_event_len \c in: Size (in bytes) of \p p_event buffer.
+ * \c out: Length of decoded contents of \p p_event.
+ *
+ * @retval NRF_SUCCESS Decoding success.
+ * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length.
+ * @retval NRF_ERROR_DATA_SIZE Decoding failure. Length of \p p_event is too small to
+ * hold decoded event.
+ */
+uint32_t ble_gap_evt_auth_key_request_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ ble_evt_t * const p_event,
+ uint32_t * const p_event_len);
+
+/**
+ * @brief Decodes ble_gap_evt_auth_status event.
+ *
+ * If \p p_event is null, the required length of \p p_event is returned in \p p_event_len.
+ *
+ * @param[in] p_buf Pointer to the beginning of an event packet.
+ * @param[in] packet_len Length (in bytes) of the event packet.
+ * @param[in,out] p_event Pointer to a \ref ble_evt_t buffer where the decoded event will be
+ * stored. If NULL, required length will be returned in \p p_event_len.
+ * @param[in,out] p_event_len \c in: Size (in bytes) of \p p_event buffer.
+ * \c out: Length of decoded contents of \p p_event.
+ *
+ * @retval NRF_SUCCESS Decoding success.
+ * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length.
+ * @retval NRF_ERROR_DATA_SIZE Decoding failure. Length of \p p_event is too small to
+ * hold decoded event.
+ */
+uint32_t ble_gap_evt_auth_status_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ ble_evt_t * const p_event,
+ uint32_t * const p_event_len);
+
+/**
+ * @brief Decodes ble_gap_evt_conn_param_update event.
+ *
+ * If \p p_event is null, the required length of \p p_event is returned in \p p_event_len.
+ *
+ * @param[in] p_buf Pointer to the beginning of an event packet.
+ * @param[in] packet_len Length (in bytes) of the event packet.
+ * @param[in,out] p_event Pointer to a \ref ble_evt_t buffer where the decoded event will be
+ * stored. If NULL, required length will be returned in \p p_event_len.
+ * @param[in,out] p_event_len \c in: Size (in bytes) of \p p_event buffer.
+ * \c out: Length of decoded contents of \p p_event.
+ *
+ * @retval NRF_SUCCESS Decoding success.
+ * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length.
+ * @retval NRF_ERROR_DATA_SIZE Decoding failure. Length of \p p_event is too small to
+ * hold decoded event.
+ */
+uint32_t ble_gap_evt_conn_param_update_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ ble_evt_t * const p_event,
+ uint32_t * const p_event_len);
+
+/**
+ * @brief Decodes ble_gap_evt_conn_sec_update event.
+ *
+ * If \p p_event is null, the required length of \p p_event is returned in \p p_event_len.
+ *
+ * @param[in] p_buf Pointer to the beginning of an event packet.
+ * @param[in] packet_len Length (in bytes) of the event packet.
+ * @param[in,out] p_event Pointer to a \ref ble_evt_t buffer where the decoded event will be
+ * stored. If NULL, required length will be returned in \p p_event_len.
+ * @param[in,out] p_event_len \c in: Size (in bytes) of \p p_event buffer.
+ * \c out: Length of decoded contents of \p p_event.
+ *
+ * @retval NRF_SUCCESS Decoding success.
+ * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length.
+ * @retval NRF_ERROR_DATA_SIZE Decoding failure. Length of \p p_event is too small to
+ * hold decoded event.
+ */
+uint32_t ble_gap_evt_conn_sec_update_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ ble_evt_t * const p_event,
+ uint32_t * const p_event_len);
+
+/**
+ * @brief Decodes ble_gap_evt_connected event.
+ *
+ * If \p p_event is null, the required length of \p p_event is returned in \p p_event_len.
+ *
+ * @param[in] p_buf Pointer to the beginning of an event packet.
+ * @param[in] packet_len Length (in bytes) of the event packet.
+ * @param[in,out] p_event Pointer to a \ref ble_evt_t buffer where the decoded event will be
+ * stored. If NULL, required length will be returned in \p p_event_len.
+ * @param[in,out] p_event_len \c in: Size (in bytes) of \p p_event buffer.
+ * \c out: Length of decoded contents of \p p_event.
+ *
+ * @retval NRF_SUCCESS Decoding success.
+ * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length.
+ * @retval NRF_ERROR_DATA_SIZE Decoding failure. Length of \p p_event is too small to
+ * hold decoded event.
+ */
+uint32_t ble_gap_evt_connected_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ ble_evt_t * const p_event,
+ uint32_t * const p_event_len);
+
+/**
+ * @brief Decodes ble_gap_evt_disconnected event.
+ *
+ * If \p p_event is null, the required length of \p p_event is returned in \p p_event_len.
+ *
+ * @param[in] p_buf Pointer to the beginning of an event packet.
+ * @param[in] packet_len Length (in bytes) of the event packet.
+ * @param[in,out] p_event Pointer to a \ref ble_evt_t buffer where the decoded event will be
+ * stored. If NULL, required length will be returned in \p p_event_len.
+ * @param[in,out] p_event_len \c in: Size (in bytes) of \p p_event buffer.
+ * \c out: Length of decoded contents of \p p_event.
+ *
+ * @retval NRF_SUCCESS Decoding success.
+ * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length.
+ * @retval NRF_ERROR_DATA_SIZE Decoding failure. Length of \p p_event is too small to
+ * hold decoded event.
+ */
+uint32_t ble_gap_evt_disconnected_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ ble_evt_t * const p_event,
+ uint32_t * const p_event_len);
+
+/**
+ * @brief Decodes ble_gap_evt_passkey_display event.
+ *
+ * If \p p_event is null, the required length of \p p_event is returned in \p p_event_len.
+ *
+ * @param[in] p_buf Pointer to the beginning of an event packet.
+ * @param[in] packet_len Length (in bytes) of the event packet.
+ * @param[in,out] p_event Pointer to a \ref ble_evt_t buffer where the decoded event will be
+ * stored. If NULL, required length will be returned in \p p_event_len.
+ * @param[in,out] p_event_len \c in: Size (in bytes) of \p p_event buffer.
+ * \c out: Length of decoded contents of \p p_event.
+ *
+ * @retval NRF_SUCCESS Decoding success.
+ * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length.
+ * @retval NRF_ERROR_DATA_SIZE Decoding failure. Length of \p p_event is too small to
+ * hold decoded event.
+ */
+uint32_t ble_gap_evt_passkey_display_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ ble_evt_t * const p_event,
+ uint32_t * const p_event_len);
+
+/**
+ * @brief Decodes ble_gap_evt_rssi_changed event.
+ *
+ * If \p p_event is null, the required length of \p p_event is returned in \p p_event_len.
+ *
+ * @param[in] p_buf Pointer to the beginning of an event packet.
+ * @param[in] packet_len Length (in bytes) of the event packet.
+ * @param[in,out] p_event Pointer to a \ref ble_evt_t buffer where the decoded event will be
+ * stored. If NULL, required length will be returned in \p p_event_len.
+ * @param[in,out] p_event_len \c in: Size (in bytes) of \p p_event buffer.
+ * \c out: Length of decoded contents of \p p_event.
+ *
+ * @retval NRF_SUCCESS Decoding success.
+ * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length.
+ * @retval NRF_ERROR_DATA_SIZE Decoding failure. Length of \p p_event is too small to
+ * hold decoded event.
+ */
+uint32_t ble_gap_evt_rssi_changed_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ ble_evt_t * const p_event,
+ uint32_t * const p_event_len);
+
+/**
+ * @brief Decodes ble_gap_evt_sec_info_request event.
+ *
+ * If \p p_event is null, the required length of \p p_event is returned in \p p_event_len.
+ *
+ * @param[in] p_buf Pointer to the beginning of an event packet.
+ * @param[in] packet_len Length (in bytes) of the event packet.
+ * @param[in,out] p_event Pointer to a \ref ble_evt_t buffer where the decoded event will be
+ * stored. If NULL, required length will be returned in \p p_event_len.
+ * @param[in,out] p_event_len \c in: Size (in bytes) of \p p_event buffer.
+ * \c out: Length of decoded contents of \p p_event.
+ *
+ * @retval NRF_SUCCESS Decoding success.
+ * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length.
+ * @retval NRF_ERROR_DATA_SIZE Decoding failure. Length of \p p_event is too small to
+ * hold decoded event.
+ */
+uint32_t ble_gap_evt_sec_info_request_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ ble_evt_t * const p_event,
+ uint32_t * const p_event_len);
+
+/**
+ * @brief Decodes ble_gap_evt_sec_params_request event.
+ *
+ * If \p p_event is null, the required length of \p p_event is returned in \p p_event_len.
+ *
+ * @param[in] p_buf Pointer to the beginning of an event packet.
+ * @param[in] packet_len Length (in bytes) of the event packet.
+ * @param[in,out] p_event Pointer to a \ref ble_evt_t buffer where the decoded event will be
+ * stored. If NULL, required length will be returned in \p p_event_len.
+ * @param[in,out] p_event_len \c in: Size (in bytes) of \p p_event buffer.
+ * \c out: Length of decoded contents of \p p_event.
+ *
+ * @retval NRF_SUCCESS Decoding success.
+ * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length.
+ * @retval NRF_ERROR_DATA_SIZE Decoding failure. Length of \p p_event is too small to
+ * hold decoded event.
+ */
+uint32_t ble_gap_evt_sec_params_request_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ ble_evt_t * const p_event,
+ uint32_t * const p_event_len);
+
+/**
+ * @brief Decodes ble_gap_evt_timeout event.
+ *
+ * If \p p_event is null, the required length of \p p_event is returned in \p p_event_len.
+ *
+ * @param[in] p_buf Pointer to the beginning of an event packet.
+ * @param[in] packet_len Length (in bytes) of the event packet.
+ * @param[in,out] p_event Pointer to a \ref ble_evt_t buffer where the decoded event will be
+ * stored. If NULL, required length will be returned in \p p_event_len.
+ * @param[in,out] p_event_len \c in: Size (in bytes) of \p p_event buffer.
+ * \c out: Length of decoded contents of \p p_event.
+ *
+ * @retval NRF_SUCCESS Decoding success.
+ * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length.
+ * @retval NRF_ERROR_DATA_SIZE Decoding failure. Length of \p p_event is too small to
+ * hold decoded event.
+ */
+uint32_t ble_gap_evt_timeout_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ ble_evt_t * const p_event,
+ uint32_t * const p_event_len);
+
+/**
+ * @brief Decodes ble_gap_evt_sec_request event.
+ *
+ * If \p p_event is null, the required length of \p p_event is returned in \p p_event_len.
+ *
+ * @param[in] p_buf Pointer to the beginning of an event packet.
+ * @param[in] packet_len Length (in bytes) of the event packet.
+ * @param[in,out] p_event Pointer to a \ref ble_evt_t buffer where the decoded event will be
+ * stored. If NULL, required length will be returned in \p p_event_len.
+ * @param[in,out] p_event_len \c in: Size (in bytes) of \p p_event buffer.
+ * \c out: Length of decoded contents of \p p_event.
+ *
+ * @retval NRF_SUCCESS Decoding success.
+ * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length.
+ * @retval NRF_ERROR_DATA_SIZE Decoding failure. Length of \p p_event is too small to
+ * hold decoded event.
+ */
+uint32_t ble_gap_evt_sec_request_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ ble_evt_t * const p_event,
+ uint32_t * const p_event_len);
+
+/**
+ * @brief Decodes ble_gap_evt_conn_param_update_request event.
+ *
+ * If \p p_event is null, the required length of \p p_event is returned in \p p_event_len.
+ *
+ * @param[in] p_buf Pointer to the beginning of an event packet.
+ * @param[in] packet_len Length (in bytes) of the event packet.
+ * @param[in,out] p_event Pointer to a \ref ble_evt_t buffer where the decoded event will be
+ * stored. If NULL, required length will be returned in \p p_event_len.
+ * @param[in,out] p_event_len \c in: Size (in bytes) of \p p_event buffer.
+ * \c out: Length of decoded contents of \p p_event.
+ *
+ * @retval NRF_SUCCESS Decoding success.
+ * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length.
+ * @retval NRF_ERROR_DATA_SIZE Decoding failure. Length of \p p_event is too small to
+ * hold decoded event.
+ */
+uint32_t ble_gap_evt_conn_param_update_request_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ ble_evt_t * const p_event,
+ uint32_t * const p_event_len);
+/**
+ * @brief Decodes ble_gap_evt_adv_report event.
+ *
+ * If \p p_event is null, the required length of \p p_event is returned in \p p_event_len.
+ *
+ * @param[in] p_buf Pointer to the beginning of an event packet.
+ * @param[in] packet_len Length (in bytes) of the event packet.
+ * @param[in,out] p_event Pointer to a \ref ble_evt_t buffer where the decoded event will be
+ * stored. If NULL, required length will be returned in \p p_event_len.
+ * @param[in,out] p_event_len \c in: Size (in bytes) of \p p_event buffer.
+ * \c out: Length of decoded contents of \p p_event.
+ *
+ * @retval NRF_SUCCESS Decoding success.
+ * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length.
+ * @retval NRF_ERROR_DATA_SIZE Decoding failure. Length of \p p_event is too small to
+ * hold decoded event.
+ */
+uint32_t ble_gap_evt_adv_report_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ ble_evt_t * const p_event,
+ uint32_t * const p_event_len);
+
+/**
+ * @brief Decodes ble_gap_evt_scan_req_report event.
+ *
+ * If \p p_event is null, the required length of \p p_event is returned in \p p_event_len.
+ *
+ * @param[in] p_buf Pointer to the beginning of an event packet.
+ * @param[in] packet_len Length (in bytes) of the event packet.
+ * @param[in,out] p_event Pointer to a \ref ble_evt_t buffer where the decoded event will be
+ * stored. If NULL, required length will be returned in \p p_event_len.
+ * @param[in,out] p_event_len \c in: Size (in bytes) of \p p_event buffer.
+ * \c out: Length of decoded contents of \p p_event.
+ *
+ * @retval NRF_SUCCESS Decoding success.
+ * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length.
+ * @retval NRF_ERROR_DATA_SIZE Decoding failure. Length of \p p_event is too small to
+ * hold decoded event.
+ */
+uint32_t ble_gap_evt_scan_req_report_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ ble_evt_t * const p_event,
+ uint32_t * const p_event_len);
+
+/**
+ * @brief Decodes ble_gap_evt_key_pressed event.
+ *
+ * If \p p_event is null, the required length of \p p_event is returned in \p p_event_len.
+ *
+ * @param[in] p_buf Pointer to the beginning of an event packet.
+ * @param[in] packet_len Length (in bytes) of the event packet.
+ * @param[in,out] p_event Pointer to a \ref ble_evt_t buffer where the decoded event will be
+ * stored. If NULL, required length will be returned in \p p_event_len.
+ * @param[in,out] p_event_len \c in: Size (in bytes) of \p p_event buffer.
+ * \c out: Length of decoded contents of \p p_event.
+ *
+ * @retval NRF_SUCCESS Decoding success.
+ * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length.
+ * @retval NRF_ERROR_DATA_SIZE Decoding failure. Length of \p p_event is too small to
+ * hold decoded event.
+ */
+uint32_t ble_gap_evt_key_pressed_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ ble_evt_t * const p_event,
+ uint32_t * const p_event_len);
+/**
+ * @brief Decodes ble_gap_evt_lesc_dhkey_request event.
+ *
+ * If \p p_event is null, the required length of \p p_event is returned in \p p_event_len.
+ *
+ * @param[in] p_buf Pointer to the beginning of an event packet.
+ * @param[in] packet_len Length (in bytes) of the event packet.
+ * @param[in,out] p_event Pointer to a \ref ble_evt_t buffer where the decoded event will be
+ * stored. If NULL, required length will be returned in \p p_event_len.
+ * @param[in,out] p_event_len \c in: Size (in bytes) of \p p_event buffer.
+ * \c out: Length of decoded contents of \p p_event.
+ *
+ * @retval NRF_SUCCESS Decoding success.
+ * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length.
+ * @retval NRF_ERROR_DATA_SIZE Decoding failure. Length of \p p_event is too small to
+ * hold decoded event.
+ */
+uint32_t ble_gap_evt_lesc_dhkey_request_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ ble_evt_t * const p_event,
+ uint32_t * const p_event_len);
+
+#if NRF_SD_BLE_API_VERSION >= 5
+/**
+ * @brief Decodes ble_gap_evt_phy_update event.
+ *
+ * If \p p_event is null, the required length of \p p_event is returned in \p p_event_len.
+ *
+ * @param[in] p_buf Pointer to the beginning of an event packet.
+ * @param[in] packet_len Length (in bytes) of the event packet.
+ * @param[in,out] p_event Pointer to a \ref ble_evt_t buffer where the decoded event will be
+ * stored. If NULL, required length will be returned in \p p_event_len.
+ * @param[in,out] p_event_len \c in: Size (in bytes) of \p p_event buffer.
+ * \c out: Length of decoded contents of \p p_event.
+ *
+ * @retval NRF_SUCCESS Decoding success.
+ * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length.
+ * @retval NRF_ERROR_DATA_SIZE Decoding failure. Length of \p p_event is too small to
+ * hold decoded event.
+ */
+uint32_t ble_gap_evt_phy_update_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ ble_evt_t * const p_event,
+ uint32_t * const p_event_len);
+
+/**
+ * @brief Decodes ble_gap_evt_phy_update_request event.
+ *
+ * If \p p_event is null, the required length of \p p_event is returned in \p p_event_len.
+ *
+ * @param[in] p_buf Pointer to the beginning of an event packet.
+ * @param[in] packet_len Length (in bytes) of the event packet.
+ * @param[in,out] p_event Pointer to a \ref ble_evt_t buffer where the decoded event will be
+ * stored. If NULL, required length will be returned in \p p_event_len.
+ * @param[in,out] p_event_len \c in: Size (in bytes) of \p p_event buffer.
+ * \c out: Length of decoded contents of \p p_event.
+ *
+ * @retval NRF_SUCCESS Decoding success.
+ * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length.
+ * @retval NRF_ERROR_DATA_SIZE Decoding failure. Length of \p p_event is too small to
+ * hold decoded event.
+ */
+uint32_t ble_gap_evt_phy_update_request_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ ble_evt_t * const p_event,
+ uint32_t * const p_event_len);
+#endif
+
+#if NRF_SD_BLE_API_VERSION >= 4
+/**
+ * @brief Decodes ble_gap_evt_data_length_update_request event.
+ *
+ * If \p p_event is null, the required length of \p p_event is returned in \p p_event_len.
+ *
+ * @param[in] p_buf Pointer to the beginning of an event packet.
+ * @param[in] packet_len Length (in bytes) of the event packet.
+ * @param[in,out] p_event Pointer to a \ref ble_evt_t buffer where the decoded event will be
+ * stored. If NULL, required length will be returned in \p p_event_len.
+ * @param[in,out] p_event_len \c in: Size (in bytes) of \p p_event buffer.
+ * \c out: Length of decoded contents of \p p_event.
+ *
+ * @retval NRF_SUCCESS Decoding success.
+ * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length.
+ * @retval NRF_ERROR_DATA_SIZE Decoding failure. Length of \p p_event is too small to
+ * hold decoded event.
+ */
+uint32_t ble_gap_evt_data_length_update_request_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ ble_evt_t * const p_event,
+ uint32_t * const p_event_len);
+/**
+ * @brief Decodes ble_gap_evt_data_length_update event.
+ *
+ * If \p p_event is null, the required length of \p p_event is returned in \p p_event_len.
+ *
+ * @param[in] p_buf Pointer to the beginning of an event packet.
+ * @param[in] packet_len Length (in bytes) of the event packet.
+ * @param[in,out] p_event Pointer to a \ref ble_evt_t buffer where the decoded event will be
+ * stored. If NULL, required length will be returned in \p p_event_len.
+ * @param[in,out] p_event_len \c in: Size (in bytes) of \p p_event buffer.
+ * \c out: Length of decoded contents of \p p_event.
+ *
+ * @retval NRF_SUCCESS Decoding success.
+ * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length.
+ * @retval NRF_ERROR_DATA_SIZE Decoding failure. Length of \p p_event is too small to
+ * hold decoded event.
+ */
+uint32_t ble_gap_evt_data_length_update_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ ble_evt_t * const p_event,
+ uint32_t * const p_event_len);
+#endif
+/** @} */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/application/codecs/ble/serializers/ble_gattc_app.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/application/codecs/ble/serializers/ble_gattc_app.c
new file mode 100644
index 0000000..dc0057c
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/application/codecs/ble/serializers/ble_gattc_app.c
@@ -0,0 +1,286 @@
+/**
+ * Copyright (c) 2013 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#include "ble_gattc_app.h"
+#include <string.h>
+#include "ble_serialization.h"
+#include "ble_gattc_struct_serialization.h"
+#include "cond_field_serialization.h"
+#include "app_util.h"
+#include "ble_struct_serialization.h"
+#include "ble_types.h"
+
+uint32_t ble_gattc_attr_info_discover_req_enc(uint16_t conn_handle,
+ ble_gattc_handle_range_t const * const p_handle_range,
+ uint8_t * const p_buf,
+ uint32_t * p_buf_len)
+{
+ SER_REQ_ENC_BEGIN(SD_BLE_GATTC_ATTR_INFO_DISCOVER);
+
+ SER_PUSH_uint16(&conn_handle);
+ SER_PUSH_COND(p_handle_range, ble_gattc_handle_range_t_enc);
+
+ SER_REQ_ENC_END;
+}
+
+
+uint32_t ble_gattc_attr_info_discover_rsp_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ uint32_t * const p_result_code)
+{
+ SER_RSP_DEC_RESULT_ONLY(SD_BLE_GATTC_ATTR_INFO_DISCOVER);
+}
+
+uint32_t ble_gattc_char_value_by_uuid_read_req_enc(uint16_t conn_handle,
+ ble_uuid_t const * const p_uuid,
+ ble_gattc_handle_range_t const * const p_handle_range,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len)
+{
+ SER_REQ_ENC_BEGIN(SD_BLE_GATTC_CHAR_VALUE_BY_UUID_READ);
+
+ SER_PUSH_uint16(&conn_handle);
+ SER_PUSH_COND(p_uuid, ble_uuid_t_enc);
+ SER_PUSH_COND(p_handle_range, ble_gattc_handle_range_t_enc);
+
+ SER_REQ_ENC_END;
+}
+
+uint32_t ble_gattc_char_value_by_uuid_read_rsp_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ uint32_t * const p_result_code)
+{
+ SER_RSP_DEC_RESULT_ONLY(SD_BLE_GATTC_CHAR_VALUE_BY_UUID_READ);
+}
+
+uint32_t ble_gattc_char_values_read_req_enc(uint16_t conn_handle,
+ uint16_t const * const p_handles,
+ uint16_t handle_count,
+ uint8_t * const p_buf,
+ uint32_t * p_buf_len)
+{
+ SER_REQ_ENC_BEGIN(SD_BLE_GATTC_CHAR_VALUES_READ);
+
+ SER_PUSH_uint16(&conn_handle);
+ SER_PUSH_len16data16(p_handles, handle_count);
+
+ SER_REQ_ENC_END;
+}
+
+
+uint32_t ble_gattc_char_values_read_rsp_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ uint32_t * const p_result_code)
+{
+ SER_RSP_DEC_RESULT_ONLY(SD_BLE_GATTC_CHAR_VALUES_READ);
+}
+
+uint32_t ble_gattc_characteristics_discover_req_enc(
+ uint16_t conn_handle,
+ ble_gattc_handle_range_t const * const p_handle_range,
+ uint8_t * const p_buf,
+ uint32_t * p_buf_len)
+{
+ SER_REQ_ENC_BEGIN(SD_BLE_GATTC_CHARACTERISTICS_DISCOVER);
+
+ SER_PUSH_uint16(&conn_handle);
+ SER_PUSH_COND(p_handle_range, ble_gattc_handle_range_t_enc);
+
+ SER_REQ_ENC_END;
+}
+
+
+uint32_t ble_gattc_characteristics_discover_rsp_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ uint32_t * const p_result_code)
+{
+ SER_RSP_DEC_RESULT_ONLY(SD_BLE_GATTC_CHARACTERISTICS_DISCOVER);
+}
+
+uint32_t ble_gattc_descriptors_discover_req_enc(
+ uint16_t conn_handle,
+ ble_gattc_handle_range_t const * const p_handle_range,
+ uint8_t * const p_buf,
+ uint32_t * p_buf_len)
+{
+ SER_REQ_ENC_BEGIN(SD_BLE_GATTC_DESCRIPTORS_DISCOVER);
+
+ SER_PUSH_uint16(&conn_handle);
+ SER_PUSH_COND(p_handle_range, ble_gattc_handle_range_t_enc);
+
+ SER_REQ_ENC_END;
+}
+
+
+uint32_t ble_gattc_descriptors_discover_rsp_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ uint32_t * const p_result_code)
+{
+ SER_RSP_DEC_RESULT_ONLY(SD_BLE_GATTC_DESCRIPTORS_DISCOVER);
+}
+
+uint32_t ble_gattc_hv_confirm_req_enc(uint16_t conn_handle,
+ uint16_t handle,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len)
+{
+ SER_REQ_ENC_BEGIN(SD_BLE_GATTC_HV_CONFIRM);
+
+ SER_PUSH_uint16(&conn_handle);
+ SER_PUSH_uint16(&handle);
+
+ SER_REQ_ENC_END;
+}
+
+uint32_t ble_gattc_hv_confirm_rsp_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ uint32_t * const p_result_code)
+{
+ SER_RSP_DEC_RESULT_ONLY(SD_BLE_GATTC_HV_CONFIRM);
+}
+
+uint32_t ble_gattc_primary_services_discover_req_enc(uint16_t conn_handle,
+ uint16_t start_handle,
+ ble_uuid_t const * const p_srvc_uuid,
+ uint8_t * const p_buf,
+ uint32_t * p_buf_len)
+{
+ SER_REQ_ENC_BEGIN(SD_BLE_GATTC_PRIMARY_SERVICES_DISCOVER);
+
+ SER_PUSH_uint16(&conn_handle);
+ SER_PUSH_uint16(&start_handle);
+ SER_PUSH_COND(p_srvc_uuid, ble_uuid_t_enc);
+
+ SER_REQ_ENC_END;
+}
+
+
+uint32_t ble_gattc_primary_services_discover_rsp_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ uint32_t * const p_result_code)
+{
+ SER_RSP_DEC_RESULT_ONLY(SD_BLE_GATTC_PRIMARY_SERVICES_DISCOVER);
+}
+
+uint32_t ble_gattc_read_req_enc(uint16_t conn_handle,
+ uint16_t handle,
+ uint16_t offset,
+ uint8_t * const p_buf,
+ uint32_t * p_buf_len)
+{
+ SER_REQ_ENC_BEGIN(SD_BLE_GATTC_READ);
+
+ SER_PUSH_uint16(&conn_handle);
+ SER_PUSH_uint16(&handle);
+ SER_PUSH_uint16(&offset);
+
+ SER_REQ_ENC_END;
+}
+
+
+uint32_t ble_gattc_read_rsp_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ uint32_t * const p_result_code)
+{
+ SER_RSP_DEC_RESULT_ONLY(SD_BLE_GATTC_READ);
+}
+
+uint32_t ble_gattc_relationships_discover_req_enc(
+ uint16_t conn_handle,
+ ble_gattc_handle_range_t const * const p_handle_range,
+ uint8_t * const p_buf,
+ uint32_t * p_buf_len)
+{
+ SER_REQ_ENC_BEGIN(SD_BLE_GATTC_RELATIONSHIPS_DISCOVER);
+
+ SER_PUSH_uint16(&conn_handle);
+ SER_PUSH_COND(p_handle_range, ble_gattc_handle_range_t_enc);
+
+ SER_REQ_ENC_END;
+}
+
+
+uint32_t ble_gattc_relationships_discover_rsp_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ uint32_t * const p_result_code)
+{
+ SER_RSP_DEC_RESULT_ONLY(SD_BLE_GATTC_RELATIONSHIPS_DISCOVER);
+}
+
+uint32_t ble_gattc_write_req_enc(uint16_t conn_handle,
+ ble_gattc_write_params_t const * const p_write_params,
+ uint8_t * const p_buf,
+ uint32_t * p_buf_len)
+{
+ SER_REQ_ENC_BEGIN(SD_BLE_GATTC_WRITE);
+
+ SER_PUSH_uint16(&conn_handle);
+ SER_PUSH_COND(p_write_params, ble_gattc_write_params_t_enc);
+
+ SER_REQ_ENC_END;
+}
+
+
+uint32_t ble_gattc_write_rsp_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ uint32_t * const p_result_code)
+{
+ SER_RSP_DEC_RESULT_ONLY(SD_BLE_GATTC_WRITE);
+}
+
+uint32_t ble_gattc_exchange_mtu_request_req_enc(uint16_t conn_handle,
+ uint16_t client_rx_mtu,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len)
+{
+ SER_REQ_ENC_BEGIN(SD_BLE_GATTC_EXCHANGE_MTU_REQUEST);
+
+ SER_PUSH_uint16(&conn_handle);
+ SER_PUSH_uint16(&client_rx_mtu);
+
+ SER_REQ_ENC_END;
+}
+
+
+uint32_t ble_gattc_exchange_mtu_request_rsp_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ uint32_t * const p_result_code)
+{
+ SER_RSP_DEC_RESULT_ONLY(SD_BLE_GATTC_EXCHANGE_MTU_REQUEST);
+}
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/application/codecs/ble/serializers/ble_gattc_app.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/application/codecs/ble/serializers/ble_gattc_app.h
new file mode 100644
index 0000000..ddb237e
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/application/codecs/ble/serializers/ble_gattc_app.h
@@ -0,0 +1,491 @@
+/**
+ * Copyright (c) 2013 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#ifndef BLE_GATTC_APP_H__
+#define BLE_GATTC_APP_H__
+
+/**@file
+ *
+ * @defgroup ble_gattc_app GATTC Application command request encoders and command response decoders
+ * @{
+ * @ingroup ser_app_s130_codecs
+ *
+ * @brief GATTC Application command request encoders and command response decoders.
+ */
+#include "ble_gattc.h"
+#include "ble.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**@brief Encodes @ref sd_ble_gattc_primary_services_discover command request.
+ *
+ * @sa @ref ble_gattc_primary_services_discover_rsp_dec for command response decoder.
+ *
+ * @param[in] conn_handle Connection handle of the connection.
+ * @param[in] start_handle Handle to start searching from.
+ * @param[in] p_srvc_uuid Pointer to a @ref ble_uuid_t which indicates the service UUID to
+ * be found. If it is NULL, all primary services will be returned.
+ * @param[in] p_buf Pointer to buffer where encoded data command will be returned.
+ * @param[in, out] p_buf_len \c in: size of \p p_buf buffer.
+ * \c out: Length of encoded command packet.
+ *
+ * @retval NRF_SUCCESS Encoding success.
+ * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length.
+ */
+uint32_t ble_gattc_primary_services_discover_req_enc(uint16_t conn_handle,
+ uint16_t start_handle,
+ ble_uuid_t const * const p_srvc_uuid,
+ uint8_t * const p_buf,
+ uint32_t * p_buf_len);
+
+/**@brief Decodes response to @ref sd_ble_gattc_primary_services_discover command.
+ *
+ * @sa @ref ble_gattc_primary_services_discover_req_enc for command request encoder.
+ *
+ * @param[in] p_buf Pointer to beginning of command response packet.
+ * @param[in] packet_len Length (in bytes) of response packet.
+ * @param[out] p_result_code Command response result code.
+ *
+ * @retval NRF_SUCCESS Decoding success.
+ * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_DATA_SIZE Decoding failure. Incorrect buffer length.
+ * @retval NRF_ERROR_INVALID_DATA Decoding failure. Decoded operation code does not match expected
+ * operation code.
+ */
+uint32_t ble_gattc_primary_services_discover_rsp_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ uint32_t * const p_result_code);
+
+/**@brief Encodes @ref sd_ble_gattc_descriptors_discover command request.
+ *
+ * @sa @ref ble_gattc_descriptors_discover_rsp_dec for command response decoder.
+ *
+ * @param[in] conn_handle Connection handle of the connection.
+ * @param[in] p_handle_range A pointer to the range of handles of the Service to perform
+ * this procedure on.
+ * @param[in] p_buf Pointer to buffer where encoded data command will be returned.
+ * @param[in, out] p_buf_len \c in: size of \p p_buf buffer.
+ * \c out: Length of encoded command packet.
+ *
+ * @retval NRF_SUCCESS Encoding success.
+ * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length.
+ */
+uint32_t ble_gattc_descriptors_discover_req_enc(
+ uint16_t conn_handle,
+ ble_gattc_handle_range_t const * const p_handle_range,
+ uint8_t * const p_buf,
+ uint32_t * p_buf_len);
+
+
+/**@brief Decodes response to @ref sd_ble_gattc_descriptors_discover command.
+ *
+ * @sa @ref ble_gattc_primary_services_discover_rsp_dec for command request encoder.
+ *
+ * @param[in] p_buf Pointer to beginning of command response packet.
+ * @param[in] packet_len Length (in bytes) of response packet.
+ * @param[out] p_result_code Command response result code.
+ *
+ * @retval NRF_SUCCESS Decoding success.
+ * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_DATA_SIZE Decoding failure. Incorrect buffer length.
+ * @retval NRF_ERROR_INVALID_DATA Decoding failure. Decoded operation code does not match expected
+ * operation code.
+ */
+uint32_t ble_gattc_descriptors_discover_rsp_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ uint32_t * const p_result_code);
+
+/**@brief Encodes @ref sd_ble_gattc_relationships_discover command request.
+ *
+ * @sa @ref ble_gattc_relationships_discover_rsp_dec for command response decoder.
+ *
+ * @param[in] conn_handle Connection handle of the connection.
+ * @param[in] p_handle_range A pointer to the range of handles of the Service to perform
+ * this procedure on.
+ * @param[in] p_buf Pointer to buffer where encoded data command will be returned.
+ * @param[in, out] p_buf_len \c in: size of \p p_buf buffer.
+ * \c out: Length of encoded command packet.
+ *
+ * @retval NRF_SUCCESS Encoding success.
+ * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length.
+ */
+uint32_t ble_gattc_relationships_discover_req_enc(
+ uint16_t conn_handle,
+ ble_gattc_handle_range_t const * const p_handle_range,
+ uint8_t * const p_buf,
+ uint32_t * p_buf_len);
+
+/**@brief Decodes response to @ref sd_ble_gattc_relationships_discover command.
+ *
+ * @sa @ref ble_gattc_relationships_discover_req_enc for command request encoder.
+ *
+ * @param[in] p_buf Pointer to beginning of command response packet.
+ * @param[in] packet_len Length (in bytes) of response packet.
+ * @param[out] p_result_code Command response result code.
+ *
+ * @retval NRF_SUCCESS Decoding success.
+ * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_DATA_SIZE Decoding failure. Incorrect buffer length.
+ * @retval NRF_ERROR_INVALID_DATA Decoding failure. Decoded operation code does not match expected
+ * operation code.
+ */
+uint32_t ble_gattc_relationships_discover_rsp_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ uint32_t * const p_result_code);
+
+/**@brief Encodes @ref sd_ble_gattc_characteristics_discover command request.
+ *
+ * @sa @ref ble_gattc_characteristics_discover_rsp_dec for command response decoder.
+ *
+ * @param[in] conn_handle Connection handle of the connection.
+ * @param[in] p_handle_range A pointer to the range of handles of the Service to perform
+ * this procedure on.
+ * @param[in] p_buf Pointer to buffer where encoded data command will be returned.
+ * @param[in, out] p_buf_len \c in: size of \p p_buf buffer.
+ * \c out: Length of encoded command packet.
+ *
+ * @retval NRF_SUCCESS Encoding success.
+ * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length.
+ */
+uint32_t ble_gattc_characteristics_discover_req_enc
+ (uint16_t conn_handle,
+ ble_gattc_handle_range_t const * const p_handle_range,
+ uint8_t * const p_buf,
+ uint32_t * p_buf_len);
+
+/**@brief Decodes response to @ref sd_ble_gattc_characteristics_discover command.
+ *
+ * @sa @ref ble_gattc_primary_services_discover_rsp_dec for command request encoder.
+ *
+ * @param[in] p_buf Pointer to beginning of command response packet.
+ * @param[in] packet_len Length (in bytes) of response packet.
+ * @param[out] p_result_code Command response result code.
+ *
+ * @retval NRF_SUCCESS Decoding success.
+ * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_DATA_SIZE Decoding failure. Incorrect buffer length.
+ * @retval NRF_ERROR_INVALID_DATA Decoding failure. Decoded operation code does not match expected
+ * operation code.
+ */
+uint32_t ble_gattc_characteristics_discover_rsp_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ uint32_t * const p_result_code);
+
+/**@brief Encodes @ref sd_ble_gattc_read command request.
+ *
+ * @sa @ref ble_gattc_read_rsp_dec for command response decoder.
+ *
+ * @param[in] conn_handle Connection handle of the connection.
+ * @param[in] handle The handle of the attribute to be read.
+ * @param[in] offset Offset into the attribute value to be read.
+ * @param[in] p_buf Pointer to buffer where encoded data command will be returned.
+ * @param[in, out] p_buf_len \c in: size of \p p_buf buffer.
+ * \c out: Length of encoded command packet.
+ *
+ * @retval NRF_SUCCESS Encoding success.
+ * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length.
+ */
+uint32_t ble_gattc_read_req_enc(uint16_t conn_handle,
+ uint16_t handle,
+ uint16_t offset,
+ uint8_t * const p_buf,
+ uint32_t * p_buf_len);
+
+/**@brief Decodes response to @ref sd_ble_gattc_read command.
+ *
+ * @sa @ref ble_gattc_read_req_enc for command request encoder.
+ *
+ * @param[in] p_buf Pointer to beginning of command response packet.
+ * @param[in] packet_len Length (in bytes) of response packet.
+ * @param[out] p_result_code Command response result code.
+ *
+ * @retval NRF_SUCCESS Decoding success.
+ * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_DATA_SIZE Decoding failure. Incorrect buffer length.
+ * @retval NRF_ERROR_INVALID_DATA Decoding failure. Decoded operation code does not match expected
+ * operation code.
+ */
+uint32_t ble_gattc_read_rsp_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ uint32_t * const p_result_code);
+
+/**@brief Encodes @ref sd_ble_gattc_char_values_read command request.
+ *
+ * @sa @ref ble_gattc_char_values_read_rsp_dec for command response decoder.
+ *
+ * @param[in] conn_handle Connection handle of the connection.
+ * @param[in] p_handles A pointer to the handle(s) of the attribute(s) to be read.
+ * @param[in] handle_count The number of handles in p_handles.
+ * @param[in] p_buf Pointer to buffer where encoded data command will be returned.
+ * @param[in, out] p_buf_len \c in: size of \p p_buf buffer.
+ * \c out: Length of encoded command packet.
+ *
+ * @retval NRF_SUCCESS Encoding success.
+ * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length.
+ */
+uint32_t ble_gattc_char_values_read_req_enc(uint16_t conn_handle,
+ uint16_t const * const p_handles,
+ uint16_t handle_count,
+ uint8_t * const p_buf,
+ uint32_t * p_buf_len);
+
+/**@brief Decodes response to @ref sd_ble_gattc_char_values_read command.
+ *
+ * @sa @ref ble_gattc_char_values_read_req_enc for command request encoder.
+ *
+ * @param[in] p_buf Pointer to beginning of command response packet.
+ * @param[in] packet_len Length (in bytes) of response packet.
+ * @param[out] p_result_code Command response result code.
+ *
+ * @retval NRF_SUCCESS Decoding success.
+ * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_DATA_SIZE Decoding failure. Incorrect buffer length.
+ * @retval NRF_ERROR_INVALID_DATA Decoding failure. Decoded operation code does not match expected
+ * operation code.
+ */
+uint32_t ble_gattc_char_values_read_rsp_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ uint32_t * const p_result_code);
+
+/**@brief Encodes @ref sd_ble_gattc_write command request.
+ *
+ * @sa @ref ble_gattc_write_rsp_dec for command response decoder.
+ *
+ * @param[in] conn_handle Connection handle of the connection.
+ * @param[in] p_write_params Pointer to \ref sd_ble_gattc_write params.
+ * @param[in] p_buf Pointer to buffer where encoded data command will be returned.
+ * @param[in, out] p_buf_len \c in: size of \p p_buf buffer.
+ * \c out: Length of encoded command packet.
+ *
+ * @retval NRF_SUCCESS Encoding success.
+ * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length.
+ */
+uint32_t ble_gattc_write_req_enc(uint16_t conn_handle,
+ ble_gattc_write_params_t const * const p_write_params,
+ uint8_t * const p_buf,
+ uint32_t * p_buf_len);
+
+/**@brief Decodes response to @ref sd_ble_gattc_write command.
+ *
+ * @sa @ref ble_gattc_write_req_enc for command request encoder.
+ *
+ * @param[in] p_buf Pointer to beginning of command response packet.
+ * @param[in] packet_len Length (in bytes) of response packet.
+ * @param[out] p_result_code Command response result code.
+ *
+ * @retval NRF_SUCCESS Decoding success.
+ * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_DATA_SIZE Decoding failure. Incorrect buffer length.
+ * @retval NRF_ERROR_INVALID_DATA Decoding failure. Decoded operation code does not match expected
+ * operation code.
+ */
+uint32_t ble_gattc_write_rsp_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ uint32_t * const p_result_code);
+
+/**@brief Encodes @ref sd_ble_gattc_hv_confirm command request.
+ *
+ * @sa @ref ble_gattc_hv_confirm_rsp_dec for command response decoder.
+ *
+ * @param[in] conn_handle Connection handle of the connection.
+ * @param[in] handle Handle of the attribute in the indication.
+ * @param[in] p_buf Pointer to buffer where encoded data command will be returned.
+ * @param[in, out] p_buf_len \c in: size of \p p_buf buffer.
+ * \c out: Length of encoded command packet.
+ *
+ * @retval NRF_SUCCESS Encoding success.
+ * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length.
+ */
+uint32_t ble_gattc_hv_confirm_req_enc(uint16_t conn_handle,
+ uint16_t handle,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len);
+
+/**@brief Decodes response to @ref sd_ble_gattc_hv_confirm command.
+ *
+ * @sa @ref ble_gattc_hv_confirm_req_enc for command request encoder.
+ *
+ * @param[in] p_buf Pointer to beginning of command response packet.
+ * @param[in] packet_len Length (in bytes) of response packet.
+ * @param[out] p_result_code Pointer to command response result code.
+ *
+ * @retval NRF_SUCCESS Decoding success.
+ * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_DATA_SIZE Decoding failure. Incorrect buffer length.
+ * @retval NRF_ERROR_INVALID_DATA Decoding failure. Decoded operation code does not match expected
+ * operation code.
+ */
+uint32_t ble_gattc_hv_confirm_rsp_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ uint32_t * const p_result_code);
+
+/**@brief Encodes @ref sd_ble_gattc_char_value_by_uuid_read command request.
+ *
+ * @sa @ref ble_gattc_char_value_by_uuid_read_rsp_dec for command response decoder.
+ *
+ * @param[in] conn_handle Connection handle of the connection.
+ * @param[in] p_uuid Pointer to a characteristic value UUID to read.
+ * @param[in] p_handle_range Pointer to the range of handles to perform this procedure on.
+ * @param[in] p_buf Pointer to buffer where encoded data command will be returned.
+ * @param[in, out] p_buf_len \c in: size of \p p_buf buffer.
+ * \c out: Length of encoded command packet.
+ *
+ * @retval NRF_SUCCESS Encoding success.
+ * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length.
+ */
+uint32_t ble_gattc_char_value_by_uuid_read_req_enc
+ (uint16_t conn_handle,
+ ble_uuid_t const * const p_uuid,
+ ble_gattc_handle_range_t const * const p_handle_range,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len);
+
+/**@brief Decodes response to @ref sd_ble_gattc_char_value_by_uuid_read command.
+ *
+ * @sa @ref ble_gattc_char_value_by_uuid_read_req_enc for command request encoder.
+ *
+ * @param[in] p_buf Pointer to beginning of command response packet.
+ * @param[in] packet_len Length (in bytes) of response packet.
+ * @param[out] p_result_code Pointer to command response result code.
+ *
+ * @retval NRF_SUCCESS Decoding success.
+ * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_DATA_SIZE Decoding failure. Incorrect buffer length.
+ * @retval NRF_ERROR_INVALID_DATA Decoding failure. Decoded operation code does not match expected
+ * operation code.
+ */
+uint32_t ble_gattc_char_value_by_uuid_read_rsp_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ uint32_t * const p_result_code);
+
+/**@brief Encodes @ref sd_ble_gattc_attr_info_discover command request.
+ *
+ * @sa @ref ble_gattc_attr_info_discover_rsp_dec for command response decoder.
+ *
+ * @param[in] conn_handle Connection handle of the connection.
+ * @param[in] p_handle_range Pointer to the range of handles
+ * @param[in] p_buf Pointer to buffer where encoded data command will be returned.
+ * @param[in, out] p_buf_len \c in: size of \p p_buf buffer.
+ * \c out: Length of encoded command packet.
+ *
+ * @retval NRF_SUCCESS Encoding success.
+ * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length.
+ */
+uint32_t ble_gattc_attr_info_discover_req_enc(uint16_t conn_handle,
+ ble_gattc_handle_range_t const * const p_handle_range,
+ uint8_t * const p_buf,
+ uint32_t * p_buf_len);
+
+/**@brief Decodes response to @ref sd_ble_gattc_attr_info_discover command.
+ *
+ * @sa @ref ble_gattc_attr_info_discover_req_enc for command request encoder.
+ *
+ * @param[in] p_buf Pointer to beginning of command response packet.
+ * @param[in] packet_len Length (in bytes) of response packet.
+ * @param[out] p_result_code Pointer to command response result code.
+ *
+ * @retval NRF_SUCCESS Decoding success.
+ * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_DATA_SIZE Decoding failure. Incorrect buffer length.
+ * @retval NRF_ERROR_INVALID_DATA Decoding failure. Decoded operation code does not match expected
+ * operation code.
+ */
+uint32_t ble_gattc_attr_info_discover_rsp_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ uint32_t * const p_result_code);
+
+/**@brief Encodes @ref sd_ble_gattc_exchange_mtu_request command request.
+ *
+ * @sa @ref ble_gattc_exchange_mtu_request_rsp_dec for command response decoder.
+ *
+ * @param[in] conn_handle Connection handle of the connection.
+ * @param[in] client_rx_mtu Client MTU Size.
+ * @param[in] p_buf Pointer to buffer where encoded data command will be returned.
+ * @param[in, out] p_buf_len \c in: size of \p p_buf buffer.
+ * \c out: Length of encoded command packet.
+ *
+ * @retval NRF_SUCCESS Encoding success.
+ * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length.
+ */
+uint32_t ble_gattc_exchange_mtu_request_req_enc(uint16_t conn_handle,
+ uint16_t client_rx_mtu,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len);
+
+/**@brief Decodes response to @ref sd_ble_gattc_exchange_mtu_request command.
+ *
+ * @sa @ref ble_gattc_exchange_mtu_request_req_enc for command request encoder.
+ *
+ * @param[in] p_buf Pointer to beginning of command response packet.
+ * @param[in] packet_len Length (in bytes) of response packet.
+ * @param[out] p_result_code Pointer to command response result code.
+ *
+ * @retval NRF_SUCCESS Decoding success.
+ * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_DATA_SIZE Decoding failure. Incorrect buffer length.
+ * @retval NRF_ERROR_INVALID_DATA Decoding failure. Decoded operation code does not match expected
+ * operation code.
+ */
+uint32_t ble_gattc_exchange_mtu_request_rsp_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ uint32_t * const p_result_code);
+
+
+/** @} */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
+
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/application/codecs/ble/serializers/ble_gattc_evt_app.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/application/codecs/ble/serializers/ble_gattc_evt_app.c
new file mode 100644
index 0000000..c049ed4
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/application/codecs/ble/serializers/ble_gattc_evt_app.c
@@ -0,0 +1,262 @@
+/**
+ * Copyright (c) 2013 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#include "ble_gattc_evt_app.h"
+#include <string.h>
+#include "ble_serialization.h"
+#include "ble_gattc_struct_serialization.h"
+#include "app_util.h"
+
+uint32_t ble_gattc_evt_attr_info_disc_rsp_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ ble_evt_t * const p_event,
+ uint32_t * const p_event_len)
+{
+ SER_EVT_DEC_BEGIN(BLE_GATTC_EVT_ATTR_INFO_DISC_RSP, gattc, attr_info_disc_rsp);
+
+ SER_PULL_uint16(&p_event->evt.gattc_evt.conn_handle);
+ SER_PULL_uint16(&p_event->evt.gattc_evt.gatt_status);
+ SER_PULL_uint16(&p_event->evt.gattc_evt.error_handle);
+ SER_PULL_FIELD_EXTENDED(&p_event->evt.gattc_evt.params.attr_info_disc_rsp,
+ ble_gattc_evt_attr_info_disc_rsp_t_dec);
+
+ SER_EVT_DEC_END;
+}
+
+uint32_t ble_gattc_evt_char_disc_rsp_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ ble_evt_t * const p_event,
+ uint32_t * const p_event_len)
+{
+ SER_EVT_DEC_BEGIN(BLE_GATTC_EVT_CHAR_DISC_RSP, gattc, char_disc_rsp);
+
+ SER_PULL_uint16(&p_event->evt.gattc_evt.conn_handle);
+ SER_PULL_uint16(&p_event->evt.gattc_evt.gatt_status);
+ SER_PULL_uint16(&p_event->evt.gattc_evt.error_handle);
+ SER_PULL_FIELD_EXTENDED(&p_event->evt.gattc_evt.params.char_disc_rsp,
+ ble_gattc_evt_char_disc_rsp_t_dec);
+
+ SER_EVT_DEC_END;
+}
+
+
+
+uint32_t ble_gattc_evt_char_val_by_uuid_read_rsp_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ ble_evt_t * const p_event,
+ uint32_t * const p_event_len)
+{
+ SER_EVT_DEC_BEGIN(BLE_GATTC_EVT_CHAR_VAL_BY_UUID_READ_RSP, gattc, char_val_by_uuid_read_rsp);
+
+ SER_PULL_uint16(&p_event->evt.gattc_evt.conn_handle);
+ SER_PULL_uint16(&p_event->evt.gattc_evt.gatt_status);
+ SER_PULL_uint16(&p_event->evt.gattc_evt.error_handle);
+ SER_PULL_FIELD_EXTENDED(&p_event->evt.gattc_evt.params.char_val_by_uuid_read_rsp,
+ ble_gattc_evt_char_val_by_uuid_read_rsp_t_dec);
+
+ SER_EVT_DEC_END;
+}
+
+
+uint32_t ble_gattc_evt_char_vals_read_rsp_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ ble_evt_t * const p_event,
+ uint32_t * const p_event_len)
+{
+ SER_EVT_DEC_BEGIN(BLE_GATTC_EVT_CHAR_VALS_READ_RSP, gattc, char_vals_read_rsp);
+
+ SER_PULL_uint16(&p_event->evt.gattc_evt.conn_handle);
+ SER_PULL_uint16(&p_event->evt.gattc_evt.gatt_status);
+ SER_PULL_uint16(&p_event->evt.gattc_evt.error_handle);
+ SER_PULL_FIELD_EXTENDED(&p_event->evt.gattc_evt.params.char_vals_read_rsp,
+ ble_gattc_evt_char_vals_read_rsp_t_dec);
+
+ SER_EVT_DEC_END;
+}
+
+
+uint32_t ble_gattc_evt_desc_disc_rsp_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ ble_evt_t * const p_event,
+ uint32_t * const p_event_len)
+{
+ SER_EVT_DEC_BEGIN(BLE_GATTC_EVT_DESC_DISC_RSP, gattc, desc_disc_rsp);
+
+ SER_PULL_uint16(&p_event->evt.gattc_evt.conn_handle);
+ SER_PULL_uint16(&p_event->evt.gattc_evt.gatt_status);
+ SER_PULL_uint16(&p_event->evt.gattc_evt.error_handle);
+ SER_PULL_FIELD_EXTENDED(&p_event->evt.gattc_evt.params.desc_disc_rsp,
+ ble_gattc_evt_desc_disc_rsp_t_dec);
+
+ SER_EVT_DEC_END;
+}
+
+uint32_t ble_gattc_evt_hvx_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ ble_evt_t * const p_event,
+ uint32_t * const p_event_len)
+{
+ SER_EVT_DEC_BEGIN(BLE_GATTC_EVT_HVX, gattc, hvx);
+
+ SER_PULL_uint16(&p_event->evt.gattc_evt.conn_handle);
+ SER_PULL_uint16(&p_event->evt.gattc_evt.gatt_status);
+ SER_PULL_uint16(&p_event->evt.gattc_evt.error_handle);
+ SER_PULL_FIELD_EXTENDED(&p_event->evt.gattc_evt.params.hvx,
+ ble_gattc_evt_hvx_t_dec);
+
+ SER_EVT_DEC_END;
+}
+
+
+uint32_t ble_gattc_evt_prim_srvc_disc_rsp_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ ble_evt_t * const p_event,
+ uint32_t * const p_event_len)
+{
+ SER_EVT_DEC_BEGIN(BLE_GATTC_EVT_PRIM_SRVC_DISC_RSP, gattc, prim_srvc_disc_rsp);
+
+ SER_PULL_uint16(&p_event->evt.gattc_evt.conn_handle);
+ SER_PULL_uint16(&p_event->evt.gattc_evt.gatt_status);
+ SER_PULL_uint16(&p_event->evt.gattc_evt.error_handle);
+ SER_PULL_FIELD_EXTENDED(&p_event->evt.gattc_evt.params.prim_srvc_disc_rsp,
+ ble_gattc_evt_prim_srvc_disc_rsp_t_dec);
+
+ SER_EVT_DEC_END;
+}
+
+uint32_t ble_gattc_evt_read_rsp_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ ble_evt_t * const p_event,
+ uint32_t * const p_event_len)
+{
+ SER_EVT_DEC_BEGIN(BLE_GATTC_EVT_READ_RSP, gattc, read_rsp);
+
+ SER_PULL_uint16(&p_event->evt.gattc_evt.conn_handle);
+ SER_PULL_uint16(&p_event->evt.gattc_evt.gatt_status);
+ SER_PULL_uint16(&p_event->evt.gattc_evt.error_handle);
+ SER_PULL_FIELD_EXTENDED(&p_event->evt.gattc_evt.params.read_rsp,
+ ble_gattc_evt_read_rsp_t_dec);
+
+ SER_EVT_DEC_END;
+}
+
+
+#define BLE_GATTC_EVT_REL_DISC_RSP_COUNT_POSITION 6
+
+
+uint32_t ble_gattc_evt_rel_disc_rsp_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ ble_evt_t * const p_event,
+ uint32_t * const p_event_len)
+{
+ SER_EVT_DEC_BEGIN(BLE_GATTC_EVT_READ_RSP, gattc, rel_disc_rsp);
+
+ SER_PULL_uint16(&p_event->evt.gattc_evt.conn_handle);
+ SER_PULL_uint16(&p_event->evt.gattc_evt.gatt_status);
+ SER_PULL_uint16(&p_event->evt.gattc_evt.error_handle);
+ SER_PULL_FIELD_EXTENDED(&p_event->evt.gattc_evt.params.rel_disc_rsp,
+ ble_gattc_evt_rel_disc_rsp_t_dec);
+
+ SER_EVT_DEC_END;
+}
+
+
+uint32_t ble_gattc_evt_timeout_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ ble_evt_t * const p_event,
+ uint32_t * const p_event_len)
+{
+ SER_EVT_DEC_BEGIN(BLE_GATTC_EVT_TIMEOUT, gattc, timeout);
+
+ SER_PULL_uint16(&p_event->evt.gattc_evt.conn_handle);
+ SER_PULL_uint16(&p_event->evt.gattc_evt.gatt_status);
+ SER_PULL_uint16(&p_event->evt.gattc_evt.error_handle);
+ SER_PULL_FIELD(&p_event->evt.gattc_evt.params.timeout,
+ ble_gattc_evt_timeout_t_dec);
+
+ SER_EVT_DEC_END;
+}
+
+uint32_t ble_gattc_evt_write_rsp_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ ble_evt_t * const p_event,
+ uint32_t * const p_event_len)
+{
+ SER_EVT_DEC_BEGIN(BLE_GATTC_EVT_WRITE_RSP, gattc, write_rsp);
+
+ SER_PULL_uint16(&p_event->evt.gattc_evt.conn_handle);
+ SER_PULL_uint16(&p_event->evt.gattc_evt.gatt_status);
+ SER_PULL_uint16(&p_event->evt.gattc_evt.error_handle);
+ SER_PULL_FIELD_EXTENDED(&p_event->evt.gattc_evt.params.write_rsp,
+ ble_gattc_evt_write_rsp_t_dec);
+
+ SER_EVT_DEC_END;
+}
+
+uint32_t ble_gattc_evt_exchange_mtu_rsp_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ ble_evt_t * const p_event,
+ uint32_t * const p_event_len)
+{
+ SER_EVT_DEC_BEGIN(BLE_GATTC_EVT_EXCHANGE_MTU_RSP, gattc, exchange_mtu_rsp);
+
+ SER_PULL_uint16(&p_event->evt.gattc_evt.conn_handle);
+ SER_PULL_uint16(&p_event->evt.gattc_evt.gatt_status);
+ SER_PULL_uint16(&p_event->evt.gattc_evt.error_handle);
+ SER_PULL_FIELD(&p_event->evt.gattc_evt.params.exchange_mtu_rsp,
+ ble_gattc_evt_exchange_mtu_rsp_t_dec);
+
+ SER_EVT_DEC_END;
+}
+
+#if NRF_SD_BLE_API_VERSION >= 4
+uint32_t ble_gattc_evt_write_cmd_tx_complete_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ ble_evt_t * const p_event,
+ uint32_t * const p_event_len)
+{
+ SER_EVT_DEC_BEGIN(BLE_GATTC_EVT_WRITE_CMD_TX_COMPLETE, gattc, write_cmd_tx_complete);
+ SER_PULL_uint16(&p_event->evt.gattc_evt.conn_handle);
+ SER_PULL_uint16(&p_event->evt.gattc_evt.gatt_status);
+ SER_PULL_uint16(&p_event->evt.gattc_evt.error_handle);
+ SER_PULL_uint8(&p_event->evt.gattc_evt.params.write_cmd_tx_complete.count);
+
+ SER_EVT_DEC_END;
+}
+#endif
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/application/codecs/ble/serializers/ble_gattc_evt_app.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/application/codecs/ble/serializers/ble_gattc_evt_app.h
new file mode 100644
index 0000000..73a0c78
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/application/codecs/ble/serializers/ble_gattc_evt_app.h
@@ -0,0 +1,364 @@
+/**
+ * Copyright (c) 2014 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#ifndef BLE_GATTC_EVT_APP_H__
+#define BLE_GATTC_EVT_APP_H__
+
+/**@file
+ *
+ * @defgroup ble_gattc_evt_app GATTC Application event decoders
+ * @{
+ * @ingroup ser_app_s130_codecs
+ *
+ * @brief GATTC Application event decoders.
+ */
+#include "ble.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @brief Decodes ble_gattc_evt_char_disc_rsp event.
+ *
+ * If \p p_event is null, the required length of \p p_event is returned in \p p_event_len.
+ *
+ * @param[in] p_buf Pointer to the beginning of an event packet.
+ * @param[in] packet_len Length (in bytes) of the event packet.
+ * @param[in,out] p_event Pointer to a \ref ble_evt_t buffer where the decoded event will be
+ * stored. If NULL, required length will be returned in \p p_event_len.
+ * @param[in,out] p_event_len \c in: Size (in bytes) of \p p_event buffer.
+ * \c out: Length of decoded contents of \p p_event.
+ *
+ * @retval NRF_SUCCESS Decoding success.
+ * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length.
+ * @retval NRF_ERROR_DATA_SIZE Decoding failure. Length of \p p_event is too small to
+ * hold decoded event.
+ */
+uint32_t ble_gattc_evt_char_disc_rsp_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ ble_evt_t * const p_event,
+ uint32_t * const p_event_len);
+
+/**
+ * @brief Decodes ble_gattc_evt_char_val_by_uuid_read_rsp event.
+ *
+ * If \p p_event is null, the required length of \p p_event is returned in \p p_event_len.
+ *
+ * @param[in] p_buf Pointer to the beginning of an event packet.
+ * @param[in] packet_len Length (in bytes) of the event packet.
+ * @param[in,out] p_event Pointer to a \ref ble_evt_t buffer where the decoded event will be
+ * stored. If NULL, required length will be returned in \p p_event_len.
+ * @param[in,out] p_event_len \c in: Size (in bytes) of \p p_event buffer.
+ * \c out: Length of decoded contents of \p p_event.
+ *
+ * @retval NRF_SUCCESS Decoding success.
+ * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length.
+ * @retval NRF_ERROR_DATA_SIZE Decoding failure. Length of \p p_event is too small to
+ * hold decoded event.
+ */
+uint32_t ble_gattc_evt_char_val_by_uuid_read_rsp_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ ble_evt_t * const p_event,
+ uint32_t * const p_event_len);
+
+/**
+ * @brief Decodes ble_gattc_evt_char_vals_read_rsp event.
+ *
+ * If \p p_event is null, the required length of \p p_event is returned in \p p_event_len.
+ *
+ * @param[in] p_buf Pointer to the beginning of an event packet.
+ * @param[in] packet_len Length (in bytes) of the event packet.
+ * @param[in,out] p_event Pointer to a \ref ble_evt_t buffer where the decoded event will be
+ * stored. If NULL, required length will be returned in \p p_event_len.
+ * @param[in,out] p_event_len \c in: Size (in bytes) of \p p_event buffer.
+ * \c out: Length of decoded contents of \p p_event.
+ *
+ * @retval NRF_SUCCESS Decoding success.
+ * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length.
+ * @retval NRF_ERROR_DATA_SIZE Decoding failure. Length of \p p_event is too small to
+ * hold decoded event.
+ */
+uint32_t ble_gattc_evt_char_vals_read_rsp_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ ble_evt_t * const p_event,
+ uint32_t * const p_event_len);
+
+/**
+ * @brief Decodes ble_gattc_evt_desc_disc_rsp event.
+ *
+ * If \p p_event is null, the required length of \p p_event is returned in \p p_event_len.
+ *
+ * @param[in] p_buf Pointer to the beginning of an event packet.
+ * @param[in] packet_len Length (in bytes) of the event packet.
+ * @param[in,out] p_event Pointer to a \ref ble_evt_t buffer where the decoded event will be
+ * stored. If NULL, required length will be returned in \p p_event_len.
+ * @param[in,out] p_event_len \c in: Size (in bytes) of \p p_event buffer.
+ * \c out: Length of decoded contents of \p p_event.
+ *
+ * @retval NRF_SUCCESS Decoding success.
+ * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length.
+ * @retval NRF_ERROR_DATA_SIZE Decoding failure. Length of \p p_event is too small to
+ * hold decoded event.
+ */
+uint32_t ble_gattc_evt_desc_disc_rsp_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ ble_evt_t * const p_event,
+ uint32_t * const p_event_len);
+
+/**
+ * @brief Decodes ble_gattc_evt_hvx event.
+ *
+ * If \p p_event is null, the required length of \p p_event is returned in \p p_event_len.
+ *
+ * @param[in] p_buf Pointer to the beginning of an event packet.
+ * @param[in] packet_len Length (in bytes) of the event packet.
+ * @param[in,out] p_event Pointer to a \ref ble_evt_t buffer where the decoded event will be
+ * stored. If NULL, required length will be returned in \p p_event_len.
+ * @param[in,out] p_event_len \c in: Size (in bytes) of \p p_event buffer.
+ * \c out: Length of decoded contents of \p p_event.
+ *
+ * @retval NRF_SUCCESS Decoding success.
+ * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length.
+ * @retval NRF_ERROR_DATA_SIZE Decoding failure. Length of \p p_event is too small to
+ * hold decoded event.
+ */
+uint32_t ble_gattc_evt_hvx_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ ble_evt_t * const p_event,
+ uint32_t * const p_event_len);
+
+/**
+ * @brief Decodes ble_gattc_evt_prim_srvc_disc_rsp event.
+ *
+ * If \p p_event is null, the required length of \p p_event is returned in \p p_event_len.
+ *
+ * @param[in] p_buf Pointer to the beginning of an event packet.
+ * @param[in] packet_len Length (in bytes) of the event packet.
+ * @param[in,out] p_event Pointer to a \ref ble_evt_t buffer where the decoded event will be
+ * stored. If NULL, required length will be returned in \p p_event_len.
+ * @param[in,out] p_event_len \c in: Size (in bytes) of \p p_event buffer.
+ * \c out: Length of decoded contents of \p p_event.
+ *
+ * @retval NRF_SUCCESS Decoding success.
+ * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length.
+ * @retval NRF_ERROR_DATA_SIZE Decoding failure. Length of \p p_event is too small to
+ * hold decoded event.
+ */
+uint32_t ble_gattc_evt_prim_srvc_disc_rsp_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ ble_evt_t * const p_event,
+ uint32_t * const p_event_len);
+
+/**
+ * @brief Decodes ble_gattc_evt_read_rsp event.
+ *
+ * If \p p_event is null, the required length of \p p_event is returned in \p p_event_len.
+ *
+ * @param[in] p_buf Pointer to the beginning of an event packet.
+ * @param[in] packet_len Length (in bytes) of the event packet.
+ * @param[in,out] p_event Pointer to a \ref ble_evt_t buffer where the decoded event will be
+ * stored. If NULL, required length will be returned in \p p_event_len.
+ * @param[in,out] p_event_len \c in: Size (in bytes) of \p p_event buffer.
+ * \c out: Length of decoded contents of \p p_event.
+ *
+ * @retval NRF_SUCCESS Decoding success.
+ * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length.
+ * @retval NRF_ERROR_DATA_SIZE Decoding failure. Length of \p p_event is too small to
+ * hold decoded event.
+ */
+uint32_t ble_gattc_evt_read_rsp_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ ble_evt_t * const p_event,
+ uint32_t * const p_event_len);
+
+/**
+ * @brief Decodes ble_gattc_evt_rel_disc_rsp_dec event.
+ *
+ * If \p p_event is null, the required length of \p p_event is returned in \p p_event_len.
+ *
+ * @param[in] p_buf Pointer to the beginning of an event packet.
+ * @param[in] packet_len Length (in bytes) of the event packet.
+ * @param[in,out] p_event Pointer to a \ref ble_evt_t buffer where the decoded event will be
+ * stored. If NULL, required length will be returned in \p p_event_len.
+ * @param[in,out] p_event_len \c in: Size (in bytes) of \p p_event buffer.
+ * \c out: Length of decoded contents of \p p_event.
+ *
+ * @retval NRF_SUCCESS Decoding success.
+ * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length.
+ * @retval NRF_ERROR_DATA_SIZE Decoding failure. Length of \p p_event is too small to
+ * hold decoded event.
+ */
+uint32_t ble_gattc_evt_rel_disc_rsp_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ ble_evt_t * const p_event,
+ uint32_t * const p_event_len);
+
+/**
+ * @brief Decodes ble_gattc_evt_timeout event.
+ *
+ * If \p p_event is null, the required length of \p p_event is returned in \p p_event_len.
+ *
+ * @param[in] p_buf Pointer to the beginning of an event packet.
+ * @param[in] packet_len Length (in bytes) of the event packet.
+ * @param[in,out] p_event Pointer to a \ref ble_evt_t buffer where the decoded event will be
+ * stored. If NULL, required length will be returned in \p p_event_len.
+ * @param[in,out] p_event_len \c in: Size (in bytes) of \p p_event buffer.
+ * \c out: Length of decoded contents of \p p_event.
+ *
+ * @retval NRF_SUCCESS Decoding success.
+ * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length.
+ * @retval NRF_ERROR_DATA_SIZE Decoding failure. Length of \p p_event is too small to
+ * hold decoded event.
+ */
+uint32_t ble_gattc_evt_timeout_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ ble_evt_t * const p_event,
+ uint32_t * const p_event_len);
+
+/**
+ * @brief Decodes ble_gattc_evt_write_rsp event.
+ *
+ * If \p p_event is null, the required length of \p p_event is returned in \p p_event_len.
+ *
+ * @param[in] p_buf Pointer to the beginning of an event packet.
+ * @param[in] packet_len Length (in bytes) of the event packet.
+ * @param[in,out] p_event Pointer to a \ref ble_evt_t buffer where the decoded event will be
+ * stored. If NULL, required length will be returned in \p p_event_len.
+ * @param[in,out] p_event_len \c in: Size (in bytes) of \p p_event buffer.
+ * \c out: Length of decoded contents of \p p_event.
+ *
+ * @retval NRF_SUCCESS Decoding success.
+ * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length.
+ * @retval NRF_ERROR_DATA_SIZE Decoding failure. Length of \p p_event is too small to
+ * hold decoded event.
+ */
+uint32_t ble_gattc_evt_write_rsp_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ ble_evt_t * const p_event,
+ uint32_t * const p_event_len);
+
+/**
+ * @brief Decodes ble_gattc_evt_attr_info_disc_rsp event.
+ *
+ * If \p p_event is null, the required length of \p p_event is returned in \p p_event_len.
+ *
+ * @param[in] p_buf Pointer to the beginning of an event packet.
+ * @param[in] packet_len Length (in bytes) of the event packet.
+ * @param[in,out] p_event Pointer to a \ref ble_evt_t buffer where the decoded event will be
+ * stored. If NULL, required length will be returned in \p p_event_len.
+ * @param[in,out] p_event_len \c in: Size (in bytes) of \p p_event buffer.
+ * \c out: Length of decoded contents of \p p_event.
+ *
+ * @retval NRF_SUCCESS Decoding success.
+ * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length.
+ * @retval NRF_ERROR_DATA_SIZE Decoding failure. Length of \p p_event is too small to
+ * hold decoded event.
+ */
+uint32_t ble_gattc_evt_attr_info_disc_rsp_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ ble_evt_t * const p_event,
+ uint32_t * const p_event_len);
+
+/**
+ * @brief Decodes ble_gattc_evt_exchange_mtu_rsp event.
+ *
+ * If \p p_event is null, the required length of \p p_event is returned in \p p_event_len.
+ *
+ * @param[in] p_buf Pointer to the beginning of an event packet.
+ * @param[in] packet_len Length (in bytes) of the event packet.
+ * @param[in,out] p_event Pointer to a \ref ble_evt_t buffer where the decoded event will be
+ * stored. If NULL, required length will be returned in \p p_event_len.
+ * @param[in,out] p_event_len \c in: Size (in bytes) of \p p_event buffer.
+ * \c out: Length of decoded contents of \p p_event.
+ *
+ * @retval NRF_SUCCESS Decoding success.
+ * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length.
+ * @retval NRF_ERROR_DATA_SIZE Decoding failure. Length of \p p_event is too small to
+ * hold decoded event.
+ */
+uint32_t ble_gattc_evt_exchange_mtu_rsp_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ ble_evt_t * const p_event,
+ uint32_t * const p_event_len);
+
+#if NRF_SD_BLE_API_VERSION >= 4
+
+/**
+ * @brief Decodes ble_gattc_evt_write_cmd_tx_complete event.
+ *
+ * If \p p_event is null, the required length of \p p_event is returned in \p p_event_len.
+ *
+ * @param[in] p_buf Pointer to the beginning of an event packet.
+ * @param[in] packet_len Length (in bytes) of the event packet.
+ * @param[in,out] p_event Pointer to a \ref ble_evt_t buffer where the decoded event will be
+ * stored. If NULL, required length will be returned in \p p_event_len.
+ * @param[in,out] p_event_len \c in: Size (in bytes) of \p p_event buffer.
+ * \c out: Length of decoded contents of \p p_event.
+ *
+ * @retval NRF_SUCCESS Decoding success.
+ * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length.
+ * @retval NRF_ERROR_DATA_SIZE Decoding failure. Length of \p p_event is too small to
+ * hold decoded event.
+ */
+uint32_t ble_gattc_evt_write_cmd_tx_complete_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ ble_evt_t * const p_event,
+ uint32_t * const p_event_len);
+#endif
+/** @} */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/application/codecs/ble/serializers/ble_gatts_app.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/application/codecs/ble/serializers/ble_gatts_app.c
new file mode 100644
index 0000000..eb7c76c
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/application/codecs/ble/serializers/ble_gatts_app.c
@@ -0,0 +1,439 @@
+/**
+ * Copyright (c) 2013 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#include "ble_gatts_app.h"
+#include <stdlib.h>
+#include <string.h>
+#include "ble_serialization.h"
+#include "ble_gatts_struct_serialization.h"
+#include "ble_struct_serialization.h"
+#include "cond_field_serialization.h"
+#include "app_util.h"
+
+
+uint32_t ble_gatts_attr_get_req_enc(uint16_t handle,
+ ble_uuid_t * p_uuid,
+ ble_gatts_attr_md_t * p_md,
+ uint8_t * const p_buf,
+ uint32_t * p_buf_len)
+{
+ SER_REQ_ENC_BEGIN(SD_BLE_GATTS_ATTR_GET);
+
+ SER_PUSH_uint16(&handle);
+ SER_PUSH_COND(p_uuid, NULL);
+ SER_PUSH_COND(p_md, NULL);
+
+ SER_REQ_ENC_END;
+}
+
+
+uint32_t ble_gatts_attr_get_rsp_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ ble_uuid_t ** pp_uuid,
+ ble_gatts_attr_md_t ** pp_md,
+ uint32_t * const p_result_code)
+{
+ SER_RSP_DEC_BEGIN(SD_BLE_GATTS_ATTR_GET);
+ SER_PULL_COND(pp_uuid, ble_uuid_t_dec);
+ SER_PULL_COND(pp_md, ble_gatts_attr_md_t_dec);
+ SER_RSP_DEC_END;
+}
+
+
+uint32_t ble_gatts_characteristic_add_req_enc(
+ uint16_t service_handle,
+ ble_gatts_char_md_t const * const p_char_md,
+ ble_gatts_attr_t const * const p_attr_char_value,
+ ble_gatts_char_handles_t const * const p_handles,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len)
+{
+ SER_REQ_ENC_BEGIN(SD_BLE_GATTS_CHARACTERISTIC_ADD);
+
+ SER_PUSH_uint16(&service_handle);
+ SER_PUSH_COND(p_char_md, ble_gatts_char_md_t_enc);
+ SER_PUSH_COND(p_attr_char_value, ble_gatts_attr_t_enc);
+ SER_PUSH_COND(p_handles, NULL);
+
+ SER_REQ_ENC_END;
+}
+
+
+uint32_t ble_gatts_characteristic_add_rsp_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ uint16_t * * const pp_handles,
+ uint32_t * const p_result_code)
+{
+ SER_RSP_DEC_BEGIN(SD_BLE_GATTS_CHARACTERISTIC_ADD);
+
+ SER_PULL_COND(pp_handles, ble_gatts_char_handles_t_dec);
+
+ SER_RSP_DEC_END;
+}
+
+
+
+uint32_t ble_gatts_descriptor_add_req_enc(uint16_t char_handle,
+ ble_gatts_attr_t const * const p_attr,
+ uint16_t * const p_handle,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len)
+{
+ SER_REQ_ENC_BEGIN(SD_BLE_GATTS_DESCRIPTOR_ADD);
+
+ SER_PUSH_uint16(&char_handle);
+ SER_PUSH_COND(p_attr, ble_gatts_attr_t_enc);
+ SER_PUSH_COND(p_handle, NULL);
+
+ SER_REQ_ENC_END;
+}
+
+uint32_t ble_gatts_descriptor_add_rsp_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ uint16_t * const p_handle,
+ uint32_t * const p_result_code)
+{
+ SER_RSP_DEC_BEGIN(SD_BLE_GATTS_DESCRIPTOR_ADD);
+
+ SER_PULL_COND(&p_handle, uint16_t_dec);
+
+ SER_RSP_DEC_END;
+}
+
+
+uint32_t ble_gatts_hvx_req_enc(uint16_t conn_handle,
+ ble_gatts_hvx_params_t const * const p_hvx_params,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len)
+{
+ SER_REQ_ENC_BEGIN(SD_BLE_GATTS_HVX);
+
+ SER_PUSH_uint16(&conn_handle);
+ SER_PUSH_COND(p_hvx_params, ble_gatts_hvx_params_t_enc);
+
+ SER_REQ_ENC_END;
+}
+
+
+uint32_t ble_gatts_hvx_rsp_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ uint32_t * const p_result_code,
+ uint16_t * * const pp_bytes_written)
+{
+ SER_RSP_DEC_BEGIN(SD_BLE_GATTS_HVX);
+
+ SER_PULL_COND(pp_bytes_written, uint16_t_dec);
+
+ SER_RSP_DEC_END;
+}
+
+
+uint32_t ble_gatts_include_add_req_enc(uint16_t service_handle,
+ uint16_t inc_srvc_handle,
+ uint16_t * const p_include_handle,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len)
+{
+ SER_REQ_ENC_BEGIN(SD_BLE_GATTS_INCLUDE_ADD);
+
+ SER_PUSH_uint16(&service_handle);
+ SER_PUSH_uint16(&inc_srvc_handle);
+ SER_PUSH_COND(p_include_handle, NULL);
+
+ SER_REQ_ENC_END;
+}
+
+
+uint32_t ble_gatts_include_add_rsp_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ uint16_t * const p_include_handle,
+ uint32_t * const p_result_code)
+{
+ SER_RSP_DEC_BEGIN(SD_BLE_GATTS_INCLUDE_ADD);
+
+ SER_PULL_COND(&p_include_handle, uint16_t_dec);
+
+ SER_RSP_DEC_END;
+}
+
+
+uint32_t ble_gatts_initial_user_handle_get_req_enc(uint16_t * p_handle,
+ uint8_t * const p_buf,
+ uint32_t * p_buf_len)
+{
+ SER_REQ_ENC_BEGIN(SD_BLE_GATTS_INITIAL_USER_HANDLE_GET);
+
+ SER_PUSH_COND(p_handle, NULL);
+
+ SER_REQ_ENC_END;
+}
+
+
+uint32_t ble_gatts_initial_user_handle_get_rsp_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ uint16_t ** pp_handle,
+ uint32_t * const p_result_code)
+{
+ SER_RSP_DEC_BEGIN(SD_BLE_GATTS_INITIAL_USER_HANDLE_GET);
+
+ SER_PULL_COND(pp_handle, uint16_t_dec);
+
+ SER_RSP_DEC_END;
+}
+
+
+uint32_t ble_gatts_rw_authorize_reply_req_enc(uint16_t conn_handle,
+ ble_gatts_rw_authorize_reply_params_t const * const p_reply_params,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len)
+{
+ SER_REQ_ENC_BEGIN(SD_BLE_GATTS_RW_AUTHORIZE_REPLY);
+
+ SER_PUSH_uint16(&conn_handle);
+ SER_PUSH_COND(p_reply_params, ble_gatts_rw_authorize_reply_params_t_enc);
+
+ SER_REQ_ENC_END;
+}
+
+
+uint32_t ble_gatts_rw_authorize_reply_rsp_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ uint32_t * const p_result_code)
+{
+ SER_RSP_DEC_RESULT_ONLY(SD_BLE_GATTS_RW_AUTHORIZE_REPLY);
+}
+
+
+uint32_t ble_gatts_service_add_req_enc(uint8_t type,
+ ble_uuid_t const * const p_uuid,
+ uint16_t const * const p_conn_handle,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len)
+{
+ SER_REQ_ENC_BEGIN(SD_BLE_GATTS_SERVICE_ADD);
+
+ SER_PUSH_uint8(&type);
+ SER_PUSH_COND(p_uuid, ble_uuid_t_enc);
+ SER_PUSH_COND(p_conn_handle, NULL);
+
+ SER_REQ_ENC_END;
+}
+
+uint32_t ble_gatts_service_add_rsp_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ uint16_t * const p_conn_handle,
+ uint32_t * const p_result_code)
+{
+ SER_RSP_DEC_BEGIN(SD_BLE_GATTS_SERVICE_ADD);
+
+ SER_PULL_COND(&p_conn_handle, uint16_t_dec);
+
+ SER_RSP_DEC_END;
+}
+
+
+uint32_t ble_gatts_service_changed_req_enc(uint16_t conn_handle,
+ uint16_t start_handle,
+ uint16_t end_handle,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len)
+{
+ SER_REQ_ENC_BEGIN(SD_BLE_GATTS_SERVICE_CHANGED);
+
+ SER_PUSH_uint16(&conn_handle);
+ SER_PUSH_uint16(&start_handle);
+ SER_PUSH_uint16(&end_handle);
+
+ SER_REQ_ENC_END;
+}
+
+
+uint32_t ble_gatts_service_changed_rsp_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ uint32_t * const p_result_code)
+{
+ SER_RSP_DEC_RESULT_ONLY(SD_BLE_GATTS_SERVICE_CHANGED);
+}
+
+
+uint32_t ble_gatts_sys_attr_get_req_enc(uint16_t conn_handle,
+ uint8_t const * const p_sys_attr_data,
+ uint16_t const * const p_sys_attr_data_len,
+ uint32_t flags,
+ uint8_t * const p_buf,
+ uint32_t * p_buf_len)
+{
+ SER_REQ_ENC_BEGIN(SD_BLE_GATTS_SYS_ATTR_GET);
+
+ SER_PUSH_uint16(&conn_handle);
+ SER_PUSH_COND(p_sys_attr_data_len, uint16_t_enc);
+ SER_PUSH_COND(p_sys_attr_data, NULL);
+ SER_PUSH_uint32(&flags);
+
+ SER_REQ_ENC_END;
+}
+
+
+uint32_t ble_gatts_sys_attr_get_rsp_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ uint8_t * * const pp_sys_attr_data,
+ uint16_t * * const pp_sys_attr_data_len,
+ uint32_t * const p_result_code)
+{
+ SER_RSP_DEC_BEGIN(SD_BLE_GATTS_SYS_ATTR_GET);
+
+ SER_PULL_COND(pp_sys_attr_data_len, uint16_t_dec);
+ if (*pp_sys_attr_data_len)
+ {
+ SER_PULL_buf(pp_sys_attr_data, **pp_sys_attr_data_len, **pp_sys_attr_data_len);
+ }
+
+ SER_RSP_DEC_END;
+}
+
+
+uint32_t ble_gatts_sys_attr_set_req_enc(uint16_t conn_handle,
+ uint8_t const * const p_sys_attr_data,
+ uint16_t sys_attr_data_len,
+ uint32_t flags,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len)
+{
+ SER_REQ_ENC_BEGIN(SD_BLE_GATTS_SYS_ATTR_SET);
+
+ SER_PUSH_uint16(&conn_handle);
+ SER_PUSH_len16data(p_sys_attr_data, sys_attr_data_len);
+ SER_PUSH_uint32(&flags);
+
+ SER_REQ_ENC_END;
+}
+
+
+uint32_t ble_gatts_sys_attr_set_rsp_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ uint32_t * const p_result_code)
+{
+ return ser_ble_cmd_rsp_dec(p_buf, packet_len, SD_BLE_GATTS_SYS_ATTR_SET, p_result_code);
+}
+
+
+uint32_t ble_gatts_value_get_req_enc(uint16_t conn_handle,
+ uint16_t handle,
+ ble_gatts_value_t const * const p_value,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len)
+{
+ SER_REQ_ENC_BEGIN(SD_BLE_GATTS_VALUE_GET);
+
+ SER_PUSH_uint16(&conn_handle);
+ SER_PUSH_uint16(&handle);
+
+ //Special case: skip the data.
+ SER_PUSH_COND(p_value, NULL);
+ if (p_value)
+ {
+ SER_PUSH_uint16(&p_value->offset);
+ SER_PUSH_uint16(&p_value->len);
+ SER_PUSH_COND(p_value->p_value, NULL);
+ }
+
+ SER_REQ_ENC_END;
+}
+
+uint32_t ble_gatts_value_get_rsp_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ ble_gatts_value_t * const p_value,
+ uint32_t * const p_result_code)
+{
+ SER_RSP_DEC_BEGIN(SD_BLE_GATTS_VALUE_GET);
+
+ SER_PULL_COND(&p_value, ble_gatts_value_t_dec);
+
+ SER_RSP_DEC_END;
+}
+
+
+uint32_t ble_gatts_value_set_req_enc(uint16_t conn_handle,
+ uint16_t handle,
+ ble_gatts_value_t * p_value,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len)
+{
+ SER_REQ_ENC_BEGIN(SD_BLE_GATTS_VALUE_SET);
+
+ SER_PUSH_uint16(&conn_handle);
+ SER_PUSH_uint16(&handle);
+ SER_PUSH_COND(p_value, ble_gatts_value_t_enc);
+
+ SER_REQ_ENC_END;
+}
+
+
+uint32_t ble_gatts_value_set_rsp_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ ble_gatts_value_t * const p_value,
+ uint32_t * const p_result_code)
+{
+ SER_RSP_DEC_BEGIN(SD_BLE_GATTS_VALUE_SET);
+
+ SER_PULL_COND(&p_value, ble_gatts_value_t_dec);
+
+ SER_RSP_DEC_END;
+}
+
+uint32_t ble_gatts_exchange_mtu_reply_req_enc(uint16_t conn_handle,
+ uint16_t server_rx_mtu,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len)
+{
+ SER_REQ_ENC_BEGIN(SD_BLE_GATTS_EXCHANGE_MTU_REPLY);
+
+ SER_PUSH_uint16(&conn_handle);
+ SER_PUSH_uint16(&server_rx_mtu);
+
+ SER_REQ_ENC_END;
+}
+
+
+uint32_t ble_gatts_exchange_mtu_reply_rsp_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ uint32_t * const p_result_code)
+{
+ SER_RSP_DEC_RESULT_ONLY(SD_BLE_GATTS_EXCHANGE_MTU_REPLY);
+}
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/application/codecs/ble/serializers/ble_gatts_app.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/application/codecs/ble/serializers/ble_gatts_app.h
new file mode 100644
index 0000000..3dcf5d5
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/application/codecs/ble/serializers/ble_gatts_app.h
@@ -0,0 +1,677 @@
+/**
+ * Copyright (c) 2013 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#ifndef BLE_GATTS_APP_H__
+#define BLE_GATTS_APP_H__
+
+/**@file
+ *
+ * @defgroup ble_gatts_app GATTS Application command request encoders and command response decoders
+ * @{
+ * @ingroup ser_app_s130_codecs
+ *
+ * @brief GATTS Application command request encoders and command response decoders.
+ */
+#include "ble_gatts.h"
+#include "ble.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**@brief Encodes @ref sd_ble_gatts_value_get command request.
+ *
+ * @sa @ref ble_gatts_value_get_rsp_dec for command response decoder.
+ *
+ * @param[in] conn_handle Connection handle.
+ * @param[in] handle Attribute handle.
+ * @param[in] p_value Pointer to attribute value information.
+ * @param[in] p_buf Pointer to buffer where encoded data command will be returned.
+ * @param[in,out] p_buf_len \c in: Size of \p p_buf buffer.
+ * \c out: Length of encoded command packet.
+ *
+ * @note \p p_data_len and \p p_data will not be updated by the command
+ * request encoder. Updated values are set by @ref ble_gatts_value_get_rsp_dec.
+ *
+ * @retval NRF_SUCCESS Encoding success.
+ * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length.
+ */
+uint32_t ble_gatts_value_get_req_enc(uint16_t conn_handle,
+ uint16_t handle,
+ ble_gatts_value_t const * const p_value,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len);
+
+/**@brief Decodes response to @ref sd_ble_gatts_value_get command.
+ *
+ * @sa @ref ble_gatts_value_get_req_enc for command request encoder.
+ *
+ * @param[in] p_buf Pointer to beginning of command response packet.
+ * @param[in] packet_len Length (in bytes) of response packet.
+ * @param[out] p_value Pointer to structure where the attribute value will be stored.
+ * @param[out] p_result_code Command result code.
+ *
+ * @retval NRF_SUCCESS Decoding success.
+ * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length.
+ * @retval NRF_ERROR_DATA_SIZE Length of \p p_value is too small to hold decoded
+ * value from response.
+ */
+uint32_t ble_gatts_value_get_rsp_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ ble_gatts_value_t * const p_value,
+ uint32_t * const p_result_code);
+
+/**@brief Encodes @ref sd_ble_gatts_hvx command request.
+ *
+ * @sa @ref ble_gatts_hvx_rsp_dec for command response decoder.
+ *
+ * @param[in] conn_handle Connection handle.
+ * @param[in] p_hvx_params Pointer to an HVx parameters structure to be encoded.
+ * @param[in] p_buf Pointer to buffer where encoded data command will be returned.
+ * @param[in,out] p_buf_len \c in: Size of \p p_buf buffer.
+ * \c out: Length of encoded command packet.
+ *
+ * @note \p p_hvx_params will not be updated by the command
+ * request encoder. Updated values are set by @ref ble_gatts_hvx_rsp_dec.
+ *
+ * @retval NRF_SUCCESS Encoding success.
+ * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length.
+ */
+uint32_t ble_gatts_hvx_req_enc(uint16_t conn_handle,
+ ble_gatts_hvx_params_t const * const p_hvx_params,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len);
+
+/**@brief Decodes response to @ref sd_ble_gatts_hvx command.
+ *
+ * @sa @ref ble_gatts_hvx_req_enc for command request encoder.
+ *
+ * @param[in] p_buf Pointer to beginning of command response packet.
+ * @param[in] packet_len Length (in bytes) of response packet.
+ * @param[out] p_result_code Command result code.
+ * @param[out] pp_bytes_written Pointer to pointer to location where number of bytes is written.
+ *
+ * @retval NRF_SUCCESS Decoding success.
+ * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length.
+ * @retval NRF_ERROR_INVALID_DATA Decoding failure. Decoded operation code does not match
+ * expected operation code.
+ */
+uint32_t ble_gatts_hvx_rsp_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ uint32_t * const p_result_code,
+ uint16_t * * const pp_bytes_written);
+
+/**@brief Encodes @ref sd_ble_gatts_characteristic_add command request.
+ *
+ * @sa @ref ble_gatts_characteristic_add_rsp_dec for command response decoder.
+ *
+ * @param[in] service_handle Handle of the service where the characteristic is to be placed.
+ * If @ref BLE_GATT_HANDLE_INVALID is used, it will be placed
+ * sequentially.
+ * @param[in] p_char_md Pointer to a @ref ble_gatts_char_md_t structure, characteristic
+ * metadata.
+ * @param[in] p_attr_char_value Pointer to a @ref ble_gatts_attr_t structure, corresponding to
+ * the characteristic value.
+ * @param[in] p_handles Pointer to a @ref ble_gatts_char_handles_t structure, where the
+ * assigned handles will be stored.
+ * @param[in] p_buf Pointer to buffer where encoded data command will be returned.
+ * @param[in,out] p_buf_len \c in: Size of \p p_buf buffer.
+ * \c out: Length of encoded command packet.
+ *
+ * @note \p p_handles will not be updated by the command
+ * request encoder. Updated values are set by @ref ble_gatts_characteristic_add_rsp_dec.
+ *
+ * @retval NRF_SUCCESS Encoding success.
+ * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length.
+ */
+uint32_t ble_gatts_characteristic_add_req_enc
+ (uint16_t service_handle,
+ ble_gatts_char_md_t const * const p_char_md,
+ ble_gatts_attr_t const * const p_attr_char_value,
+ ble_gatts_char_handles_t const * const p_handles,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len);
+
+/**@brief Decodes response to @ref sd_ble_gatts_characteristic_add command.
+ *
+ * @sa @ref ble_gatts_characteristic_add_req_enc for command request encoder.
+ *
+ * @param[in] p_buf Pointer to beginning of command response packet.
+ * @param[in] packet_len Length (in bytes) of response packet.
+ * @param[out] pp_handles Pointer to pointer to location where handles should be decoded.
+ * @param[out] p_result_code Pointer to command result code decode location.
+ *
+ * @retval NRF_SUCCESS Decoding success.
+ * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length.
+ * @retval NRF_ERROR_INVALID_DATA Decoding failure. Decoded operation code does not match
+ * expected operation code.
+ */
+uint32_t ble_gatts_characteristic_add_rsp_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ uint16_t * * const pp_handles,
+ uint32_t * const p_result_code);
+
+
+/**@brief Encodes @ref sd_ble_gatts_service_add command request.
+ *
+ * @sa @ref ble_gatts_service_add_rsp_dec for command response decoder.
+ *
+ * @param[in] type Toggles between primary and secondary services,
+ * see @ref BLE_GATTS_SRVC_TYPES.
+ * @param[in] p_uuid Pointer to service UUID.
+ * @param[in] p_conn_handle Pointer to a 16-bit word where the assigned handle will be stored.
+ * @param[in] p_buf Pointer to buffer where encoded data command will be returned.
+ * @param[in,out] p_buf_len \c in: Size of \p p_buf buffer.
+ * \c out: Length of encoded command packet.
+ *
+ * @note \p p_conn_handle will not be updated by the command
+ * request encoder. Updated values are set by @ref ble_gatts_service_add_rsp_dec.
+ *
+ * @retval NRF_SUCCESS Encoding success.
+ * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length.
+ */
+uint32_t ble_gatts_service_add_req_enc(uint8_t type,
+ ble_uuid_t const * const p_uuid,
+ uint16_t const * const p_conn_handle,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len);
+
+/**@brief Decodes response to @ref sd_ble_gatts_service_add command.
+ *
+ * @sa @ref ble_gatts_service_add_req_enc for command request encoder.
+ *
+ * @param[in] p_buf Pointer to beginning of command response packet.
+ * @param[in] packet_len Length (in bytes) of response packet.
+ * @param[out] p_conn_handle Connection handle.
+ * @param[out] p_result_code Command result code.
+ *
+ * @retval NRF_SUCCESS Decoding success.
+ * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length.
+ * @retval NRF_ERROR_INVALID_DATA Decoding failure. Decoded operation code does not match
+ * expected operation code.
+ */
+uint32_t ble_gatts_service_add_rsp_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ uint16_t * const p_conn_handle,
+ uint32_t * const p_result_code);
+
+/**@brief Encodes @ref sd_ble_gatts_sys_attr_set command request.
+ *
+ * @sa @ref ble_gatts_sys_attr_set_rsp_dec for command response decoder.
+ *
+ * @param[in] conn_handle Connection handle.
+ * @param[in] p_sys_attr_data Pointer to a buffer (at least \p sys_attr_data_len bytes long)
+ * containing the attribute value to write.
+ * @param[in] sys_attr_data_len Length (in bytes) of \p p_sys_attr_data.
+ * @param[in] flags Optional additional flags.
+ * @param[in] p_buf Pointer to buffer where encoded data command will be returned.
+ * @param[in,out] p_buf_len \c in: Size of \p p_buf buffer.
+ * \c out: Length of encoded command packet.
+ *
+ * @retval NRF_SUCCESS Encoding success.
+ * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length.
+ */
+uint32_t ble_gatts_sys_attr_set_req_enc(uint16_t conn_handle,
+ uint8_t const * const p_sys_attr_data,
+ uint16_t sys_attr_data_len,
+ uint32_t flags,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len);
+
+/**@brief Decodes response to @ref sd_ble_gatts_sys_attr_set command.
+ *
+ * @sa @ref ble_gatts_sys_attr_set_req_enc for command request encoder.
+ *
+ * @param[in] p_buf Pointer to beginning of command response packet.
+ * @param[in] packet_len Length (in bytes) of response packet.
+ * @param[out] p_result_code Command result code.
+ *
+ * @retval NRF_SUCCESS Decoding success.
+ * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length.
+ * @retval NRF_ERROR_INVALID_DATA Decoding failure. Decoded operation code does not match
+ * expected operation code.
+ */
+uint32_t ble_gatts_sys_attr_set_rsp_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ uint32_t * const p_result_code);
+
+/**@brief Encodes @ref sd_ble_gatts_value_set command request.
+ *
+ * @sa @ref ble_gatts_value_set_rsp_dec for command response decoder.
+ *
+ * @param[in] conn_handle Connection handle.
+ * @param[in] handle Attribute handle.
+ * @param[in] p_value Pointer to attribute value information.
+ * @param[in] p_buf Pointer to buffer where encoded data command will be returned.
+ * @param[in,out] p_buf_len \c in: Size of \p p_buf buffer.
+ * \c out: Length of encoded command packet.
+ *
+ * @retval NRF_SUCCESS Encoding success.
+ * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length.
+ */
+uint32_t ble_gatts_value_set_req_enc(uint16_t conn_handle,
+ uint16_t handle,
+ ble_gatts_value_t * p_value,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len);
+
+/**@brief Decodes response to @ref sd_ble_gatts_value_set command.
+ *
+ * @sa @ref ble_gatts_value_set_req_enc for command request encoder.
+ *
+ * @param[in] p_buf Pointer to beginning of command response packet.
+ * @param[in] packet_len Length (in bytes) of response packet.
+ * @param[out] p_value Pointer to attribute value information.
+ * @param[out] p_result_code Command result code.
+ *
+ * @retval NRF_SUCCESS Decoding success.
+ * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length.
+ * @retval NRF_ERROR_INVALID_DATA Decoding failure. Decoded operation code does not match
+ * expected operation code.
+ */
+uint32_t ble_gatts_value_set_rsp_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ ble_gatts_value_t * const p_value,
+ uint32_t * const p_result_code);
+
+/**@brief Encodes @ref sd_ble_gatts_sys_attr_get command request.
+ *
+ * @sa @ref ble_gatts_sys_attr_get_rsp_dec for command response decoder.
+ *
+ * @param[in] conn_handle Connection handle of the connection.
+ * @param[in] p_sys_attr_data Pointer to buffer where updated information about system
+ * attributes will be stored. Can be NULL to calculate required
+ * size.
+ * @param[in] p_sys_attr_data_len Size of p_sys_attr_data buffer if \p p_sys_attr_data is
+ * not NULL.
+ * @param[in] flags Additional optional flags.
+ * @param[in,out] p_buf Pointer to buffer where encoded data command will
+ * be returned.
+ * @param[in,out] p_buf_len \c in: size of \p p_buf buffer.
+ * \c out: Length of encoded command packet.
+ *
+ * @note \p p_sys_attr_data and \p p_sys_attr_data_len will not be updated by the command
+ * request encoder. Updated values are set by @ref ble_gatts_sys_attr_get_rsp_dec.
+ *
+ * @retval NRF_SUCCESS Encoding success.
+ * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length.
+ */
+uint32_t ble_gatts_sys_attr_get_req_enc(uint16_t conn_handle,
+ uint8_t const * const p_sys_attr_data,
+ uint16_t const * const p_sys_attr_data_len,
+ uint32_t flags,
+ uint8_t * const p_buf,
+ uint32_t * p_buf_len);
+
+/**@brief Decodes response to @ref sd_ble_gatts_sys_attr_get command.
+ *
+ * @sa @ref ble_gatts_sys_attr_get_req_enc for command request encoder.
+ *
+ * @param[in] p_buf Pointer to beginning of command response packet.
+ * @param[in] packet_len Length (in bytes) of response packet.
+ * @param[out] pp_sys_attr_data Pointer to a buffer where updated information about system
+ * attributes will be stored.
+ * @param[in,out] pp_sys_attr_data_len \c in: Size (in bytes) of \p p_sys_attr_data buffer.
+ * \c out: Length of decoded contents of \p p_sys_attr_data.
+ * @param[out] p_result_code Command result code.
+ *
+ * @retval NRF_SUCCESS Decoding success.
+ * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length.
+ * @retval NRF_ERROR_DATA_SIZE Length of \p p_sys_attr_data is too small to hold decoded
+ * value from response.
+ * @retval NRF_ERROR_INVALID_DATA Decoding failure. Decoded operation code does not match
+ * expected operation code.
+ */
+uint32_t ble_gatts_sys_attr_get_rsp_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ uint8_t * * const pp_sys_attr_data,
+ uint16_t * * const pp_sys_attr_data_len,
+ uint32_t * const p_result_code);
+
+/**@brief Encodes @ref sd_ble_gatts_descriptor_add command request.
+ *
+ * @sa @ref ble_gatts_descriptor_add_rsp_dec for command response decoder.
+ *
+ * @param[in] char_handle Handle of the characteristic where the description is to be placed.
+ * If @ref BLE_GATT_HANDLE_INVALID is used, it will be placed
+ * sequentially.
+ * @param[in] p_attr Pointer to a @ref ble_gatts_attr_t structure, characteristic
+ * metadata.
+ * @param[in] p_handle Pointer to a @ref ble_gatts_char_handles_t structure, where the
+ * assigned handles will be stored.
+ * @param[in] p_buf Pointer to buffer where encoded data command will be returned.
+ * @param[in,out] p_buf_len \c in: Size of \p p_buf buffer.
+ * \c out: Length of encoded command packet.
+ *
+ * @retval NRF_SUCCESS Encoding success.
+ * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length.
+ */
+uint32_t ble_gatts_descriptor_add_req_enc(uint16_t char_handle,
+ ble_gatts_attr_t const * const p_attr,
+ uint16_t * const p_handle,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len);
+
+/**@brief Decodes response to @ref sd_ble_gatts_descriptor_add command.
+ *
+ * @sa @ref ble_gatts_descriptor_add_req_enc for command request encoder.
+ *
+ * @param[in] p_buf Pointer to beginning of command response packet.
+ * @param[in] packet_len Length (in bytes) of response packet.
+ * @param[out] p_handle Pointer to bufer where descriptor handle will be
+ returned.
+ * @param[out] p_result_code Pointer to command result code decode location.
+ *
+ * @retval NRF_SUCCESS Decoding success.
+ * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length.
+ * @retval NRF_ERROR_INVALID_DATA Decoding failure. Decoded operation code does not match
+ * expected operation code.
+ */
+uint32_t ble_gatts_descriptor_add_rsp_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ uint16_t * const p_handle,
+ uint32_t * const p_result_code);
+
+/**@brief Encodes @ref sd_ble_gatts_include_add command request.
+ *
+ * @sa @ref ble_gatts_include_add_rsp_dec for command response decoder.
+ *
+ * @param[in] service_handle Handle of the service where the included service is to be placed.
+ * @param[in] inc_srvc_handle Handle of the included service
+ * @param[in] p_include_handle Pointer to Pointer to a 16-bit word where the assigned handle will be stored.
+ * @param[in] p_buf Pointer to buffer where encoded data command will be returned.
+ * @param[in,out] p_buf_len \c in: Size of \p p_buf buffer.
+ * \c out: Length of encoded command packet.
+ *
+ * @retval NRF_SUCCESS Encoding success.
+ * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length.
+ */
+uint32_t ble_gatts_include_add_req_enc(uint16_t service_handle,
+ uint16_t inc_srvc_handle,
+ uint16_t * const p_include_handle,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len);
+
+/**@brief Decodes response to @ref sd_ble_gatts_include_add command.
+ *
+ * @sa @ref ble_gatts_include_add_req_enc for command request encoder.
+ *
+ * @param[in] p_buf Pointer to beginning of command response packet.
+ * @param[in] packet_len Length (in bytes) of response packet.
+ * @param[out] p_include_handle Pointer to a 16-bit word where the assigned handle will be stored.
+ * @param[out] p_result_code Pointer to command result code decode location.
+ *
+ * @retval NRF_SUCCESS Decoding success.
+ * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length.
+ * @retval NRF_ERROR_INVALID_DATA Decoding failure. Decoded operation code does not match
+ * expected operation code.
+ */
+uint32_t ble_gatts_include_add_rsp_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ uint16_t * const p_include_handle,
+ uint32_t * const p_result_code);
+
+
+/**@brief Encodes @ref sd_ble_gatts_rw_authorize_reply command request.
+ *
+ * @sa @ref ble_gatts_rw_authorize_reply_rsp_dec for command response decoder.
+ *
+ * @param[in] conn_handle Connection handle.
+ * @param[in] p_reply_params Pointer to \ref ble_gatts_rw_authorize_reply_params_t
+ * @param[in] p_buf Pointer to buffer where encoded data command will be returned.
+ * @param[in,out] p_buf_len \c in: Size of \p p_buf buffer.
+ * \c out: Length of encoded command packet.
+ *
+ * @retval NRF_SUCCESS Encoding success.
+ * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length.
+ * @retval NRF_ERROR_INVALID_PARAM Encoding failure. Invalid param provided in p_reply_params.
+ */
+uint32_t ble_gatts_rw_authorize_reply_req_enc(
+ uint16_t conn_handle,
+ ble_gatts_rw_authorize_reply_params_t const * const
+ p_reply_params,
+ uint8_t * const
+ p_buf,
+ uint32_t * const
+ p_buf_len);
+
+/**@brief Decodes response to @ref sd_ble_gatts_rw_authorize_reply command.
+ *
+ * @sa @ref ble_gatts_rw_authorize_reply_req_enc for command request encoder.
+ *
+ * @param[in] p_buf Pointer to beginning of command response packet.
+ * @param[in] packet_len Length (in bytes) of response packet.
+ * @param[out] p_result_code Command result code.
+ *
+ * @retval NRF_SUCCESS Decoding success.
+ * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length.
+ * @retval NRF_ERROR_INVALID_DATA Decoding failure. Decoded operation code does not match
+ * expected operation code.
+ */
+uint32_t ble_gatts_rw_authorize_reply_rsp_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ uint32_t * const p_result_code);
+
+/**@brief Encodes @ref sd_ble_gatts_service_changed command request.
+ *
+ * @sa @ref ble_gatts_service_changed_rsp_dec for command response decoder.
+ *
+ * @param[in] conn_handle Connection handle.
+ * @param[in] start_handle Start of affected attribute handle range.
+ * @param[in] end_handle End of affected attribute handle range.
+ * @param[in] p_buf Pointer to buffer where encoded data command will be returned.
+ * @param[in,out] p_buf_len \c in: Size of \p p_buf buffer.
+ * \c out: Length of encoded command packet.
+ *
+ * @retval NRF_SUCCESS Encoding success.
+ * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length.
+ * @retval NRF_ERROR_INVALID_PARAM Encoding failure. Invalid param provided in p_reply_params.
+ */
+uint32_t ble_gatts_service_changed_req_enc(uint16_t conn_handle,
+ uint16_t start_handle,
+ uint16_t end_handle,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len);
+
+/**@brief Decodes response to @ref sd_ble_gatts_service_changed command.
+ *
+ * @sa @ref ble_gatts_service_changed_req_enc for command request encoder.
+ *
+ * @param[in] p_buf Pointer to beginning of command response packet.
+ * @param[in] packet_len Length (in bytes) of response packet.
+ * @param[out] p_result_code Command result code.
+ *
+ * @retval NRF_SUCCESS Decoding success.
+ * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length.
+ * @retval NRF_ERROR_INVALID_DATA Decoding failure. Decoded operation code does not match
+ * expected operation code.
+ */
+uint32_t ble_gatts_service_changed_rsp_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ uint32_t * const p_result_code);
+
+/**@brief Encodes @ref sd_ble_gatts_attr_get command request.
+ *
+ * @sa @ref ble_gatts_attr_get_rsp_dec for command response decoder.
+ *
+ * @param[in] handle See @ref sd_ble_gatts_attr_get.
+ * @param[in] p_uuid See @ref sd_ble_gatts_attr_get.
+ * @param[out] p_md See @ref sd_ble_gatts_attr_get.
+ * @param[in,out] p_buf Pointer to buffer where encoded data command will be returned.
+ * @param[in,out] p_buf_len \c in: size of \p p_buf buffer.
+ * \c out: Length of encoded command packet.
+ *
+ * @retval NRF_SUCCESS Encoding success.
+ * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length.
+ */
+uint32_t ble_gatts_attr_get_req_enc(uint16_t handle,
+ ble_uuid_t * p_uuid,
+ ble_gatts_attr_md_t * p_md,
+ uint8_t * const p_buf,
+ uint32_t * p_buf_len);
+
+/**@brief Decodes response to @ref sd_ble_gatts_attr_get command.
+ *
+ * @sa @ref ble_gatts_attr_get_req_enc for command request encoder.
+ *
+ * @param[in] p_buf Pointer to beginning of command response packet.
+ * @param[in] packet_len Length (in bytes) of response packet.
+ * @param[out] pp_uuid Pointer to address where to put output data.
+ * @param[out] pp_md Pointer to address where to put output data.
+ * @param[out] p_result_code Command result code.
+ *
+ * @retval NRF_SUCCESS Decoding success.
+ * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length.
+ * @retval NRF_ERROR_INVALID_DATA Decoding failure. Decoded operation code does not match
+ * expected operation code.
+ */
+uint32_t ble_gatts_attr_get_rsp_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ ble_uuid_t ** pp_uuid,
+ ble_gatts_attr_md_t ** pp_md,
+ uint32_t * const p_result_code);
+
+/**@brief Encodes @ref sd_ble_gatts_initial_user_handle_get command request.
+ *
+ * @sa @ref ble_gatts_initial_user_handle_get_rsp_dec for command response decoder.
+ *
+ * @param[out] p_handle See @ref sd_ble_gatts_initial_user_handle_get.
+ * @param[in,out] p_buf Pointer to buffer where encoded data command will be returned.
+ * @param[in,out] p_buf_len \c in: size of \p p_buf buffer.
+ * \c out: Length of encoded command packet.
+ *
+ * @retval NRF_SUCCESS Encoding success.
+ * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length.
+ */
+uint32_t ble_gatts_initial_user_handle_get_req_enc(uint16_t * p_handle,
+ uint8_t * const p_buf,
+ uint32_t * p_buf_len);
+
+/**@brief Decodes response to @ref sd_ble_gatts_initial_user_handle_get command.
+ *
+ * @sa @ref ble_gatts_initial_user_handle_get_req_enc for command request encoder.
+ *
+ * @param[in] p_buf Pointer to beginning of command response packet.
+ * @param[in] packet_len Length (in bytes) of response packet.
+ * @param[out] pp_handle Pointer to address where to put output data.
+ * @param[out] p_result_code Command result code.
+ *
+ * @retval NRF_SUCCESS Decoding success.
+ * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length.
+ * @retval NRF_ERROR_INVALID_DATA Decoding failure. Decoded operation code does not match
+ * expected operation code.
+ */
+uint32_t ble_gatts_initial_user_handle_get_rsp_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ uint16_t ** pp_handle,
+ uint32_t * const p_result_code);
+
+/**@brief Encodes @ref sd_ble_gatts_exchange_mtu_reply command request.
+ *
+ * @sa @ref ble_gatts_exchange_mtu_reply_rsp_dec for command response decoder.
+ *
+ * @param[in] conn_handle Connection handle.
+ * @param[in] server_rx_mtu Server MTU Size.
+ * @param[in] p_buf Pointer to buffer where encoded data command will be returned.
+ * @param[in,out] p_buf_len \c in: Size of \p p_buf buffer.
+ * \c out: Length of encoded command packet.
+ *
+ * @retval NRF_SUCCESS Encoding success.
+ * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length.
+ * @retval NRF_ERROR_INVALID_PARAM Encoding failure. Invalid param provided in p_reply_params.
+ */
+uint32_t ble_gatts_exchange_mtu_reply_req_enc(uint16_t conn_handle,
+ uint16_t server_rx_mtu,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len);
+
+/**@brief Decodes response to @ref sd_ble_gatts_exchange_mtu_reply command.
+ *
+ * @sa @ref ble_gatts_exchange_mtu_reply_req_enc for command request encoder.
+ *
+ * @param[in] p_buf Pointer to beginning of command response packet.
+ * @param[in] packet_len Length (in bytes) of response packet.
+ * @param[out] p_result_code Command result code.
+ *
+ * @retval NRF_SUCCESS Decoding success.
+ * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length.
+ * @retval NRF_ERROR_INVALID_DATA Decoding failure. Decoded operation code does not match
+ * expected operation code.
+ */
+uint32_t ble_gatts_exchange_mtu_reply_rsp_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ uint32_t * const p_result_code);
+
+/** @} */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif //BLE_GATTS_APP_H__
+
+
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/application/codecs/ble/serializers/ble_gatts_evt_app.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/application/codecs/ble/serializers/ble_gatts_evt_app.c
new file mode 100644
index 0000000..bbe71e8
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/application/codecs/ble/serializers/ble_gatts_evt_app.c
@@ -0,0 +1,190 @@
+/**
+ * Copyright (c) 2013 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#include "ble_gatts_evt_app.h"
+#include "ble_serialization.h"
+#include "ble_gatts_struct_serialization.h"
+#include "app_ble_user_mem.h"
+#include "app_util.h"
+
+extern ser_ble_user_mem_t m_app_user_mem_table[];
+
+uint32_t ble_gatts_evt_hvc_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ ble_evt_t * const p_event,
+ uint32_t * const p_event_len)
+{
+ SER_EVT_DEC_BEGIN(BLE_GATTS_EVT_HVC, gatts, hvc);
+
+ SER_PULL_uint16(&p_event->evt.gatts_evt.conn_handle);
+ SER_PULL_FIELD(&p_event->evt.gatts_evt.params.hvc,
+ ble_gatts_evt_hvc_t_dec);
+
+ SER_EVT_DEC_END;
+}
+
+uint32_t ble_gatts_evt_rw_authorize_request_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ ble_evt_t * const p_event,
+ uint32_t * const p_event_len)
+{
+ SER_EVT_DEC_BEGIN(BLE_GATTS_EVT_HVC, gatts, rw_authorize_request);
+
+ SER_PULL_uint16(&p_event->evt.gatts_evt.conn_handle);
+ SER_PULL_FIELD_EXTENDED(&p_event->evt.gatts_evt.params.authorize_request, ble_gatts_evt_rw_authorize_request_t_dec);
+
+ //Correct event length / memory sync.
+ if (p_event->evt.gatts_evt.params.authorize_request.type == BLE_GATTS_AUTHORIZE_TYPE_READ)
+ {
+ evt_struct_len = offsetof(ble_evt_t, evt.gatts_evt.params.authorize_request.request.read)
+ - offsetof(ble_evt_t, evt)
+ + sizeof(ble_gatts_evt_read_t);
+ }
+ else if ((p_event->evt.gatts_evt.params.authorize_request.type == BLE_GATTS_AUTHORIZE_TYPE_WRITE) &&
+ ( (p_event->evt.gatts_evt.params.authorize_request.request.write.op == BLE_GATTS_OP_EXEC_WRITE_REQ_NOW) ||
+ (p_event->evt.gatts_evt.params.authorize_request.request.write.op == BLE_GATTS_OP_PREP_WRITE_REQ)))
+ {
+ uint32_t conn_index;
+ if (app_ble_user_mem_context_find(p_event->evt.gatts_evt.conn_handle, &conn_index) != NRF_ERROR_NOT_FOUND)
+ {
+ SER_PULL_len16data(&m_app_user_mem_table[conn_index].mem_block.p_mem, &m_app_user_mem_table[conn_index].mem_block.len);
+ }
+ }
+
+ SER_EVT_DEC_END;
+}
+
+
+uint32_t ble_gatts_evt_sc_confirm_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ ble_evt_t * const p_event,
+ uint32_t * const p_event_len)
+{
+ SER_EVT_DEC_BEGIN_NO_STRUCT(BLE_GATTS_EVT_SC_CONFIRM, gatts);
+ SER_PULL_uint16(&p_event->evt.gatts_evt.conn_handle);
+ SER_EVT_DEC_END;
+}
+
+
+uint32_t ble_gatts_evt_sys_attr_missing_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ ble_evt_t * const p_event,
+ uint32_t * const p_event_len)
+{
+ SER_EVT_DEC_BEGIN(BLE_GATTS_EVT_SYS_ATTR_MISSING, gatts, sys_attr_missing);
+
+ SER_PULL_uint16(&p_event->evt.gatts_evt.conn_handle);
+ SER_PULL_FIELD(&p_event->evt.gatts_evt.params.sys_attr_missing,
+ ble_gatts_evt_sys_attr_missing_t_dec);
+
+ SER_EVT_DEC_END;
+}
+
+
+uint32_t ble_gatts_evt_timeout_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ ble_evt_t * const p_event,
+ uint32_t * const p_event_len)
+{
+ SER_EVT_DEC_BEGIN(BLE_GATTS_EVT_TIMEOUT, gatts, timeout);
+
+ SER_PULL_uint16(&p_event->evt.gatts_evt.conn_handle);
+ SER_PULL_FIELD(&p_event->evt.gatts_evt.params.timeout,
+ ble_gatts_evt_timeout_t_dec);
+
+ SER_EVT_DEC_END;
+}
+
+
+
+
+uint32_t ble_gatts_evt_write_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ ble_evt_t * const p_event,
+ uint32_t * const p_event_len)
+{
+ SER_EVT_DEC_BEGIN(BLE_GATTS_EVT_WRITE, gatts, write);
+
+ SER_PULL_uint16(&p_event->evt.gatts_evt.conn_handle);
+ SER_PULL_FIELD_EXTENDED(&p_event->evt.gatts_evt.params.write, ble_gatts_evt_write_t_dec);
+
+ if (p_event != NULL)
+ {
+ if (p_event->evt.gatts_evt.params.write.op == BLE_GATTS_OP_EXEC_WRITE_REQ_NOW)
+ {
+ uint32_t conn_index;
+ if (app_ble_user_mem_context_find(p_event->evt.gatts_evt.conn_handle, &conn_index) != NRF_ERROR_NOT_FOUND)
+ {
+ SER_PULL_len16data(&m_app_user_mem_table[conn_index].mem_block.p_mem, &m_app_user_mem_table[conn_index].mem_block.len);
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code);
+ }
+ }
+ }
+
+ SER_EVT_DEC_END;
+}
+
+
+uint32_t ble_gatts_evt_exchange_mtu_request_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ ble_evt_t * const p_event,
+ uint32_t * const p_event_len)
+{
+ SER_EVT_DEC_BEGIN(BLE_GATTS_EVT_EXCHANGE_MTU_REQUEST, gatts, exchange_mtu_request);
+
+ SER_PULL_uint16(&p_event->evt.gatts_evt.conn_handle);
+ SER_PULL_FIELD(&p_event->evt.gatts_evt.params.exchange_mtu_request, ble_gatts_evt_exchange_mtu_request_t_dec);
+
+ SER_EVT_DEC_END;
+}
+
+#if NRF_SD_BLE_API_VERSION >= 4
+uint32_t ble_gatts_evt_hvn_tx_complete_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ ble_evt_t * const p_event,
+ uint32_t * const p_event_len)
+{
+ SER_EVT_DEC_BEGIN(BLE_GATTS_EVT_HVN_TX_COMPLETE, gatts, hvn_tx_complete);
+
+ SER_PULL_uint16(&p_event->evt.gatts_evt.conn_handle);
+ SER_PULL_uint8(&p_event->evt.gatts_evt.params.hvn_tx_complete.count);
+
+ SER_EVT_DEC_END;
+}
+#endif
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/application/codecs/ble/serializers/ble_gatts_evt_app.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/application/codecs/ble/serializers/ble_gatts_evt_app.h
new file mode 100644
index 0000000..d294b81
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/application/codecs/ble/serializers/ble_gatts_evt_app.h
@@ -0,0 +1,249 @@
+/**
+ * Copyright (c) 2014 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#ifndef BLE_GATTS_EVT_APP_H__
+#define BLE_GATTS_EVT_APP_H__
+
+/**@file
+ *
+ * @defgroup ble_gatts_evt_app GATTS Application event decoders
+ * @{
+ * @ingroup ser_app_s130_codecs
+ *
+ * @brief GATTS Application event decoders.
+ */
+#include "ble.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @brief Decodes ble_gatts_evt_hvc event.
+ *
+ * If \p p_event is null, the required length of \p p_event is returned in \p p_event_len.
+ *
+ * @param[in] p_buf Pointer to the beginning of an event packet.
+ * @param[in] packet_len Length (in bytes) of the event packet.
+ * @param[in,out] p_event Pointer to a \ref ble_evt_t buffer where the decoded event will be
+ * stored. If NULL, required length will be returned in \p p_event_len.
+ * @param[in,out] p_event_len \c in: Size (in bytes) of \p p_event buffer.
+ * \c out: Length of decoded contents of \p p_event.
+ *
+ * @retval NRF_SUCCESS Decoding success.
+ * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length.
+ * @retval NRF_ERROR_DATA_SIZE Decoding failure. Length of \p p_event is too small to
+ * hold decoded event.
+ */
+uint32_t ble_gatts_evt_hvc_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ ble_evt_t * const p_event,
+ uint32_t * const p_event_len);
+
+/**
+ * @brief Decodes ble_gatts_evt_rw_authorize_request event.
+ *
+ * If \p p_event is null, the required length of \p p_event is returned in \p p_event_len.
+ *
+ * @param[in] p_buf Pointer to the beginning of an event packet.
+ * @param[in] packet_len Length (in bytes) of the event packet.
+ * @param[in,out] p_event Pointer to a \ref ble_evt_t buffer where the decoded event will be
+ * stored. If NULL, required length will be returned in \p p_event_len.
+ * @param[in,out] p_event_len \c in: Size (in bytes) of \p p_event buffer.
+ * \c out: Length of decoded contents of \p p_event.
+ *
+ * @retval NRF_SUCCESS Decoding success.
+ * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length.
+ * @retval NRF_ERROR_DATA_SIZE Decoding failure. Length of \p p_event is too small to
+ * hold decoded event.
+ */
+uint32_t ble_gatts_evt_rw_authorize_request_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ ble_evt_t * const p_event,
+ uint32_t * const p_event_len);
+
+/**
+ * @brief Decodes ble_gatts_evt_sc_confirm event.
+ *
+ * If \p p_event is null, the required length of \p p_event is returned in \p p_event_len.
+ *
+ * @param[in] p_buf Pointer to the beginning of an event packet.
+ * @param[in] packet_len Length (in bytes) of the event packet.
+ * @param[in,out] p_event Pointer to a \ref ble_evt_t buffer where the decoded event will be
+ * stored. If NULL, required length will be returned in \p p_event_len.
+ * @param[in,out] p_event_len \c in: Size (in bytes) of \p p_event buffer.
+ * \c out: Length of decoded contents of \p p_event.
+ *
+ * @retval NRF_SUCCESS Decoding success.
+ * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length.
+ * @retval NRF_ERROR_DATA_SIZE Decoding failure. Length of \p p_event is too small to
+ * hold decoded event.
+ */
+uint32_t ble_gatts_evt_sc_confirm_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ ble_evt_t * const p_event,
+ uint32_t * const p_event_len);
+
+/**
+ * @brief Decodes ble_gatts_evt_sys_attr_missing event.
+ *
+ * If \p p_event is null, the required length of \p p_event is returned in \p p_event_len.
+ *
+ * @param[in] p_buf Pointer to the beginning of an event packet.
+ * @param[in] packet_len Length (in bytes) of the event packet.
+ * @param[in,out] p_event Pointer to a \ref ble_evt_t buffer where the decoded event will be
+ * stored. If NULL, required length will be returned in \p p_event_len.
+ * @param[in,out] p_event_len \c in: Size (in bytes) of \p p_event buffer.
+ * \c out: Length of decoded contents of \p p_event.
+ *
+ * @retval NRF_SUCCESS Decoding success.
+ * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length.
+ * @retval NRF_ERROR_DATA_SIZE Decoding failure. Length of \p p_event is too small to
+ * hold decoded event.
+ */
+uint32_t ble_gatts_evt_sys_attr_missing_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ ble_evt_t * const p_event,
+ uint32_t * const p_event_len);
+
+/**
+ * @brief Decodes ble_gatts_evt_timeout event.
+ *
+ * If \p p_event is null, the required length of \p p_event is returned in \p p_event_len.
+ *
+ * @param[in] p_buf Pointer to the beginning of an event packet.
+ * @param[in] packet_len Length (in bytes) of the event packet.
+ * @param[in,out] p_event Pointer to a \ref ble_evt_t buffer where the decoded event will be
+ * stored. If NULL, required length will be returned in \p p_event_len.
+ * @param[in,out] p_event_len \c in: Size (in bytes) of \p p_event buffer.
+ * \c out: Length of decoded contents of \p p_event.
+ *
+ * @retval NRF_SUCCESS Decoding success.
+ * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length.
+ * @retval NRF_ERROR_DATA_SIZE Decoding failure. Length of \p p_event is too small to
+ * hold decoded event.
+ */
+uint32_t ble_gatts_evt_timeout_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ ble_evt_t * const p_event,
+ uint32_t * const p_event_len);
+
+/**
+ * @brief Decodes ble_gatts_evt_write event.
+ *
+ * If \p p_event is null, the required length of \p p_event is returned in \p p_event_len.
+ *
+ * @param[in] p_buf Pointer to the beginning of an event packet.
+ * @param[in] packet_len Length (in bytes) of the event packet.
+ * @param[in,out] p_event Pointer to a \ref ble_evt_t buffer where the decoded event will be
+ * stored. If NULL, required length will be returned in \p p_event_len.
+ * @param[in,out] p_event_len \c in: Size (in bytes) of \p p_event buffer.
+ * \c out: Length of decoded contents of \p p_event.
+ *
+ * @retval NRF_SUCCESS Decoding success.
+ * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length.
+ * @retval NRF_ERROR_DATA_SIZE Decoding failure. Length of \p p_event is too small to
+ * hold decoded event.
+ */
+uint32_t ble_gatts_evt_write_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ ble_evt_t * const p_event,
+ uint32_t * const p_event_len);
+
+/**
+ * @brief Decodes ble_gatts_evt_exchange_mtu_request event.
+ *
+ * If \p p_event is null, the required length of \p p_event is returned in \p p_event_len.
+ *
+ * @param[in] p_buf Pointer to the beginning of an event packet.
+ * @param[in] packet_len Length (in bytes) of the event packet.
+ * @param[in,out] p_event Pointer to a \ref ble_evt_t buffer where the decoded event will be
+ * stored. If NULL, required length will be returned in \p p_event_len.
+ * @param[in,out] p_event_len \c in: Size (in bytes) of \p p_event buffer.
+ * \c out: Length of decoded contents of \p p_event.
+ *
+ * @retval NRF_SUCCESS Decoding success.
+ * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length.
+ * @retval NRF_ERROR_DATA_SIZE Decoding failure. Length of \p p_event is too small to
+ * hold decoded event.
+ */
+uint32_t ble_gatts_evt_exchange_mtu_request_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ ble_evt_t * const p_event,
+ uint32_t * const p_event_len);
+
+#if NRF_SD_BLE_API_VERSION >= 4
+
+/**
+ * @brief Decodes ble_gatts_evt_hvn_tx_complete event.
+ *
+ * If \p p_event is null, the required length of \p p_event is returned in \p p_event_len.
+ *
+ * @param[in] p_buf Pointer to the beginning of an event packet.
+ * @param[in] packet_len Length (in bytes) of the event packet.
+ * @param[in,out] p_event Pointer to a \ref ble_evt_t buffer where the decoded event will be
+ * stored. If NULL, required length will be returned in \p p_event_len.
+ * @param[in,out] p_event_len \c in: Size (in bytes) of \p p_event buffer.
+ * \c out: Length of decoded contents of \p p_event.
+ *
+ * @retval NRF_SUCCESS Decoding success.
+ * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length.
+ * @retval NRF_ERROR_DATA_SIZE Decoding failure. Length of \p p_event is too small to
+ * hold decoded event.
+ */
+uint32_t ble_gatts_evt_hvn_tx_complete_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ ble_evt_t * const p_event,
+ uint32_t * const p_event_len);
+#endif
+/** @} */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/application/codecs/ble/serializers/ble_l2cap_app.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/application/codecs/ble/serializers/ble_l2cap_app.c
new file mode 100644
index 0000000..8378c80
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/application/codecs/ble/serializers/ble_l2cap_app.c
@@ -0,0 +1,279 @@
+/**
+ * Copyright (c) 2014 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#include <string.h>
+#include "ble_l2cap_app.h"
+#include "ble_serialization.h"
+#include "ble_struct_serialization.h"
+#include "ble_l2cap_struct_serialization.h"
+#include "ble_gap.h"
+#include "app_util.h"
+#include "cond_field_serialization.h"
+
+#if defined(NRF_SD_BLE_API_VERSION) && NRF_SD_BLE_API_VERSION < 4
+uint32_t ble_l2cap_cid_register_req_enc(uint16_t cid,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len)
+{
+ uint32_t index = 0;
+ uint32_t err_code = NRF_SUCCESS;
+
+ SER_ASSERT_NOT_NULL(p_buf);
+ SER_ASSERT_NOT_NULL(p_buf_len);
+
+ SER_ASSERT_LENGTH_LEQ(index + 3, *p_buf_len);
+
+ p_buf[index++] = SD_BLE_L2CAP_CID_REGISTER;
+ err_code = uint16_t_enc(&cid, p_buf, *p_buf_len, &index);
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code);
+
+ *p_buf_len = index;
+
+ return err_code;
+}
+
+uint32_t ble_l2cap_cid_register_rsp_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ uint32_t * const p_result_code)
+{
+ return ser_ble_cmd_rsp_dec(p_buf, packet_len, SD_BLE_L2CAP_CID_REGISTER, p_result_code);
+}
+
+uint32_t ble_l2cap_cid_unregister_req_enc(uint16_t cid,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len)
+{
+ uint32_t index = 0;
+ uint32_t err_code = NRF_SUCCESS;
+
+ SER_ASSERT_NOT_NULL(p_buf);
+ SER_ASSERT_NOT_NULL(p_buf_len);
+
+ SER_ASSERT_LENGTH_LEQ(index + 3, *p_buf_len);
+
+ p_buf[index++] = SD_BLE_L2CAP_CID_UNREGISTER;
+ err_code = uint16_t_enc(&cid, p_buf, *p_buf_len, &index);
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code);
+
+ *p_buf_len = index;
+
+ return err_code;
+}
+
+uint32_t ble_l2cap_cid_unregister_rsp_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ uint32_t * const p_result_code)
+{
+ return ser_ble_cmd_rsp_dec(p_buf, packet_len, SD_BLE_L2CAP_CID_UNREGISTER, p_result_code);
+}
+
+
+uint32_t ble_l2cap_tx_req_enc(uint16_t conn_handle,
+ ble_l2cap_header_t const * const p_l2cap_header,
+ uint8_t const * const p_data,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len)
+{
+ uint32_t index = 0;
+ uint32_t err_code = NRF_SUCCESS;
+
+ SER_ASSERT_NOT_NULL(p_buf);
+ SER_ASSERT_NOT_NULL(p_buf_len);
+
+ SER_ASSERT_LENGTH_LEQ(1, *p_buf_len);
+ p_buf[index++] = SD_BLE_L2CAP_TX;
+
+ err_code = uint16_t_enc(&conn_handle, p_buf, *p_buf_len, &index);
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code);
+
+ err_code = cond_field_enc(p_l2cap_header, p_buf, *p_buf_len, &index, ble_l2cap_header_t_enc);
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code);
+
+ if (p_l2cap_header != NULL)
+ {
+ err_code = buf_enc(p_data, p_l2cap_header->len, p_buf, *p_buf_len, &index);
+ }
+ else
+ {
+ err_code = buf_enc(NULL, 0, p_buf, *p_buf_len, &index);
+ }
+
+ *p_buf_len = index;
+
+ return err_code;
+}
+
+uint32_t ble_l2cap_tx_rsp_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ uint32_t * const p_result_code)
+{
+ return ser_ble_cmd_rsp_dec(p_buf, packet_len, SD_BLE_L2CAP_TX, p_result_code);
+}
+#endif
+
+#if NRF_SD_BLE_API_VERSION >= 5
+uint32_t ble_l2cap_ch_setup_req_enc(uint16_t conn_handle,
+ uint16_t * p_local_cid,
+ ble_l2cap_ch_setup_params_t const *p_params,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len)
+{
+ SER_REQ_ENC_BEGIN(SD_BLE_L2CAP_CH_SETUP);
+
+ SER_PUSH_uint16(&conn_handle);
+ SER_PUSH_COND(p_local_cid, uint16_t_enc);
+ SER_PUSH_COND(p_params, ble_l2cap_ch_setup_params_t_enc);
+
+ SER_REQ_ENC_END;
+}
+
+uint32_t ble_l2cap_ch_setup_rsp_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ uint16_t * p_local_cid,
+ uint32_t * const p_result_code)
+{
+ SER_RSP_DEC_BEGIN(SD_BLE_L2CAP_CH_SETUP);
+ SER_PULL_COND((void **)&p_local_cid, uint16_t_dec);
+ SER_RSP_DEC_END;
+}
+
+uint32_t ble_l2cap_ch_release_req_enc(uint16_t conn_handle,
+ uint16_t local_cid,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len)
+{
+ SER_REQ_ENC_BEGIN(SD_BLE_L2CAP_CH_RELEASE);
+
+ SER_PUSH_uint16(&conn_handle);
+ SER_PUSH_uint16(&local_cid);
+
+ SER_REQ_ENC_END;
+}
+
+uint32_t ble_l2cap_ch_release_rsp_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ uint32_t * const p_result_code)
+{
+ SER_RSP_DEC_RESULT_ONLY(SD_BLE_L2CAP_CH_RELEASE);
+}
+
+uint32_t ble_l2cap_ch_rx_req_enc(uint16_t conn_handle,
+ uint16_t local_cid,
+ ble_data_t const *p_sdu_buf,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len)
+{
+ SER_REQ_ENC_BEGIN(SD_BLE_L2CAP_CH_RX);
+
+ SER_PUSH_uint16(&conn_handle);
+ SER_PUSH_uint16(&local_cid);
+
+ SER_PUSH_COND(p_sdu_buf, NULL);
+ if (p_sdu_buf)
+ {
+ SER_PUSH_uint16(&p_sdu_buf->len);
+ SER_PUSH_uint32(&p_sdu_buf->p_data);
+ }
+
+ SER_REQ_ENC_END;
+}
+
+uint32_t ble_l2cap_ch_rx_rsp_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ uint32_t * const p_result_code)
+{
+ SER_RSP_DEC_RESULT_ONLY(SD_BLE_L2CAP_CH_RX);
+}
+
+uint32_t ble_l2cap_ch_tx_req_enc(uint16_t conn_handle,
+ uint16_t local_cid,
+ ble_data_t const *p_sdu_buf,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len)
+{
+ SER_REQ_ENC_BEGIN(SD_BLE_L2CAP_CH_TX);
+
+ SER_PUSH_uint16(&conn_handle);
+ SER_PUSH_uint16(&local_cid);
+
+ SER_PUSH_COND(p_sdu_buf, NULL);
+ if (p_sdu_buf)
+ {
+ SER_PUSH_uint32(&p_sdu_buf->p_data);
+ SER_PUSH_uint16(&p_sdu_buf->len);
+ SER_PUSH_buf(p_sdu_buf->p_data, p_sdu_buf->len);
+ }
+
+ SER_REQ_ENC_END;
+}
+
+uint32_t ble_l2cap_ch_tx_rsp_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ uint32_t * const p_result_code)
+{
+ SER_RSP_DEC_RESULT_ONLY(SD_BLE_L2CAP_CH_TX);
+}
+
+uint32_t ble_l2cap_ch_flow_control_req_enc(uint16_t conn_handle,
+ uint16_t local_cid,
+ uint16_t credits,
+ uint16_t *p_credits,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len)
+{
+ SER_REQ_ENC_BEGIN(SD_BLE_L2CAP_CH_FLOW_CONTROL);
+
+ SER_PUSH_uint16(&conn_handle);
+ SER_PUSH_uint16(&local_cid);
+ SER_PUSH_uint16(&credits);
+ SER_PUSH_COND(p_credits, NULL);
+
+ SER_REQ_ENC_END;
+}
+
+uint32_t ble_l2cap_ch_flow_control_rsp_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ uint16_t * p_credits,
+ uint32_t * const p_result_code)
+{
+ SER_RSP_DEC_BEGIN(SD_BLE_L2CAP_CH_FLOW_CONTROL);
+ SER_PULL_COND((void **)&p_credits, uint16_t_dec);
+ SER_RSP_DEC_END;
+}
+#endif //NRF_SD_BLE_API_VERSION >= 5
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/application/codecs/ble/serializers/ble_l2cap_app.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/application/codecs/ble/serializers/ble_l2cap_app.h
new file mode 100644
index 0000000..68d8f68
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/application/codecs/ble/serializers/ble_l2cap_app.h
@@ -0,0 +1,242 @@
+/**
+ * Copyright (c) 2014 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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
+ *
+ * @defgroup ble_l2cap_app L2CAP Application command request encoders and command response decoders
+ * @{
+ * @ingroup ser_app_s130_codecs
+ *
+ * @brief L2CAP Application command request encoders and command response decoders.
+ */
+
+#ifndef BLE_L2CAP_APP_H__
+#define BLE_L2CAP_APP_H__
+
+#include "ble.h"
+#include "ble_types.h"
+#include "ble_ranges.h"
+#include "ble_err.h"
+#include "ble_l2cap.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+#if defined(NRF_SD_BLE_API_VERSION) && NRF_SD_BLE_API_VERSION < 4
+/**@brief Register a CID with L2CAP.
+ *
+ * @details This registers a higher protocol layer with the L2CAP multiplexer, and is required prior to all operations on the CID.
+ *
+ * @param[in] cid L2CAP CID.
+ * @param[in] p_buf Pointer to beginning of command response packet.
+ * @param[in,out] p_buf_len \c in: Size of \p p_buf buffer.
+ * \c out: Length of encoded command packet.
+ *
+ * @retval NRF_SUCCESS Encoding success.
+ * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length.
+ */
+uint32_t ble_l2cap_cid_register_req_enc(uint16_t cid,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len);
+
+/**
+ * @brief Decodes response to @ref sd_ble_l2cap_cid_register command.
+ *
+ * @sa @ref ble_l2cap_cid_register_req_enc for command request encoder.
+ *
+ * @param[in] p_buf Pointer to beginning of command response packet.
+ * @param[in] packet_len Length (in bytes) of response packet.
+ * @param[out] p_result_code Command result code.
+ *
+ * @retval NRF_SUCCESS Decoding success.
+ * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length.
+ * @retval NRF_ERROR_INVALID_DATA Decoding failure. Decoded operation code does not match
+ * expected operation code.
+ */
+uint32_t ble_l2cap_cid_register_rsp_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ uint32_t * const p_result_code);
+
+/**@brief Unregister a CID with L2CAP.
+ *
+ * @details This unregisters a previously registered higher protocol layer with the L2CAP multiplexer.
+ *
+ * @param[in] cid L2CAP CID.
+ * @param[in] p_buf Pointer to beginning of command response packet.
+ * @param[in,out] p_buf_len \c in: Size of \p p_buf buffer.
+ * \c out: Length of encoded command packet.
+ *
+ * @retval NRF_SUCCESS Encoding success.
+ * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length.
+ */
+uint32_t ble_l2cap_cid_unregister_req_enc(uint16_t cid,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len);
+
+/**
+ * @brief Decodes response to @ref sd_ble_l2cap_cid_unregister command.
+ *
+ * @sa @ref ble_l2cap_cid_unregister_req_enc for command request encoder.
+ *
+ * @param[in] p_buf Pointer to beginning of command response packet.
+ * @param[in] packet_len Length (in bytes) of response packet.
+ * @param[out] p_result_code Command result code.
+ *
+ * @retval NRF_SUCCESS Decoding success.
+ * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length.
+ * @retval NRF_ERROR_INVALID_DATA Decoding failure. Decoded operation code does not match
+ * expected operation code.
+ */
+uint32_t ble_l2cap_cid_unregister_rsp_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ uint32_t * const p_result_code);
+
+/**@brief Transmit an L2CAP packet.
+ *
+ * @note It is important to note that a call to this function will <b>consume an application buffer</b>, and will therefore
+ * generate a @ref BLE_EVT_TX_COMPLETE event when the packet has been transmitted.
+ * See the documentation of @ref sd_ble_tx_packet_count_get for more details.
+ *
+ * @param[in] conn_handle Connection handle.
+ * @param[in] p_l2cap_header Pointer to a packet header containing length and CID.
+ * @param[in] p_data Pointer to the data to be transmitted.
+ * @param[in] p_buf Pointer to beginning of command response packet.
+ * @param[in,out] p_buf_len\ c in: Size of \p p_buf buffer.
+ * \c out: Length of encoded command packet.
+ *
+ * @retval NRF_SUCCESS Successfully queued an L2CAP packet for transmission.
+ * @retval NRF_ERROR_INVALID_ADDR Invalid pointer supplied.
+ * @retval NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied, CIDs must be registered beforehand with @ref sd_ble_l2cap_cid_register.
+ * @retval NRF_ERROR_NOT_FOUND CID not found.
+ * @retval NRF_ERROR_NO_MEM Not enough memory to complete operation.
+ * @retval NRF_ERROR_DATA_SIZE Invalid data size(s) supplied, see @ref BLE_L2CAP_MTU_DEF.
+ */
+uint32_t ble_l2cap_tx_req_enc(uint16_t conn_handle,
+ ble_l2cap_header_t const * const p_l2cap_header,
+ uint8_t const * const p_data,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len);
+
+/**
+ * @brief Decodes response to @ref sd_ble_l2cap_tx command.
+ *
+ * @sa @ref ble_l2cap_tx_req_enc for command request encoder.
+ *
+ * @param[in] p_buf Pointer to beginning of command response packet.
+ * @param[in] packet_len Length (in bytes) of response packet.
+ * @param[out] p_result_code Command result code.
+ *
+ * @retval NRF_SUCCESS Decoding success.
+ * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length.
+ * @retval NRF_ERROR_INVALID_DATA Decoding failure. Decoded operation code does not match
+ * expected operation code.
+ */
+uint32_t ble_l2cap_tx_rsp_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ uint32_t * const p_result_code);
+#endif
+
+#if NRF_SD_BLE_API_VERSION >= 5
+uint32_t ble_l2cap_ch_setup_req_enc(uint16_t conn_handle,
+ uint16_t * p_local_cid,
+ ble_l2cap_ch_setup_params_t const *p_params,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len);
+
+uint32_t ble_l2cap_ch_setup_rsp_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ uint16_t * p_local_cid,
+ uint32_t * const p_result_code);
+
+uint32_t ble_l2cap_ch_release_req_enc(uint16_t conn_handle,
+ uint16_t local_cid,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len);
+
+uint32_t ble_l2cap_ch_release_rsp_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ uint32_t * const p_result_code);
+
+uint32_t ble_l2cap_ch_rx_req_enc(uint16_t conn_handle,
+ uint16_t local_cid,
+ ble_data_t const *p_sdu_buf,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len);
+
+uint32_t ble_l2cap_ch_rx_rsp_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ uint32_t * const p_result_code);
+
+uint32_t ble_l2cap_ch_tx_req_enc(uint16_t conn_handle,
+ uint16_t local_cid,
+ ble_data_t const *p_sdu_buf,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len);
+
+uint32_t ble_l2cap_ch_tx_rsp_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ uint32_t * const p_result_code);
+
+uint32_t ble_l2cap_ch_flow_control_req_enc(uint16_t conn_handle,
+ uint16_t local_cid,
+ uint16_t credits,
+ uint16_t *p_credits,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len);
+
+uint32_t ble_l2cap_ch_flow_control_rsp_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ uint16_t * p_credits,
+ uint32_t * const p_result_code);
+#endif //NRF_SD_BLE_API_VERSION >= 5
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif //BLE_L2CAP_APP_H__
+
+/**
+ @}
+ */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/application/codecs/ble/serializers/ble_l2cap_evt_app.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/application/codecs/ble/serializers/ble_l2cap_evt_app.c
new file mode 100644
index 0000000..392d860
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/application/codecs/ble/serializers/ble_l2cap_evt_app.c
@@ -0,0 +1,183 @@
+/**
+ * Copyright (c) 2014 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#include "ble_serialization.h"
+#include "ble_struct_serialization.h"
+#include "ble_l2cap_struct_serialization.h"
+#include "app_util.h"
+#include "ble_l2cap_evt_app.h"
+
+#if defined(NRF_SD_BLE_API_VERSION) && NRF_SD_BLE_API_VERSION < 4
+uint32_t ble_l2cap_evt_rx_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ ble_evt_t * const p_event,
+ uint32_t * const p_event_len)
+{
+ SER_EVT_DEC_BEGIN(BLE_L2CAP_EVT_RX, l2cap, rx);
+
+ SER_PULL_uint16(&p_event->evt.l2cap_evt.conn_handle);
+ SER_PULL_FIELD_EXTENDED(&p_event->evt.l2cap_evt.params.rx, ble_l2cap_evt_rx_t_dec);
+
+ SER_EVT_DEC_END;
+}
+#endif
+
+#if defined(NRF_SD_BLE_API_VERSION) && NRF_SD_BLE_API_VERSION >= 5
+
+uint32_t ble_l2cap_evt_ch_setup_request_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ ble_evt_t * const p_event,
+ uint32_t * const p_event_len)
+{
+ SER_EVT_DEC_BEGIN(BLE_L2CAP_EVT_CH_SETUP_REQUEST, l2cap, ch_setup_request);
+
+ SER_PULL_uint16(&p_event->evt.l2cap_evt.conn_handle);
+ SER_PULL_uint16(&p_event->evt.l2cap_evt.local_cid);
+ SER_PULL_uint16(&p_event->evt.l2cap_evt.params.ch_setup_request.le_psm);
+ SER_PULL_FIELD(&p_event->evt.l2cap_evt.params.ch_setup_request.tx_params, ble_l2cap_ch_tx_params_t_dec);
+
+ SER_EVT_DEC_END;
+}
+
+uint32_t ble_l2cap_evt_ch_setup_refused_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ ble_evt_t * const p_event,
+ uint32_t * const p_event_len)
+{
+ SER_EVT_DEC_BEGIN(BLE_L2CAP_EVT_CH_SETUP_REFUSED, l2cap, ch_setup_refused);
+
+ SER_PULL_uint16(&p_event->evt.l2cap_evt.conn_handle);
+ SER_PULL_uint16(&p_event->evt.l2cap_evt.local_cid);
+ SER_PULL_uint8(&p_event->evt.l2cap_evt.params.ch_setup_refused.source);
+ SER_PULL_uint16(&p_event->evt.l2cap_evt.params.ch_setup_refused.status);
+
+ SER_EVT_DEC_END;
+}
+
+uint32_t ble_l2cap_evt_ch_setup_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ ble_evt_t * const p_event,
+ uint32_t * const p_event_len)
+{
+ SER_EVT_DEC_BEGIN(BLE_L2CAP_EVT_CH_SETUP, l2cap, ch_setup);
+
+ SER_PULL_uint16(&p_event->evt.l2cap_evt.conn_handle);
+ SER_PULL_uint16(&p_event->evt.l2cap_evt.local_cid);
+ SER_PULL_FIELD(&p_event->evt.l2cap_evt.params.ch_setup.tx_params, ble_l2cap_ch_tx_params_t_dec);
+
+ SER_EVT_DEC_END;
+}
+
+uint32_t ble_l2cap_evt_ch_released_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ ble_evt_t * const p_event,
+ uint32_t * const p_event_len)
+{
+ SER_EVT_DEC_BEGIN_NO_STRUCT(BLE_L2CAP_EVT_CH_RELEASED, l2cap);
+
+ SER_PULL_uint16(&p_event->evt.l2cap_evt.conn_handle);
+ SER_PULL_uint16(&p_event->evt.l2cap_evt.local_cid);
+
+ SER_EVT_DEC_END;
+}
+
+uint32_t ble_l2cap_evt_ch_sdu_buf_released_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ ble_evt_t * const p_event,
+ uint32_t * const p_event_len)
+{
+ SER_EVT_DEC_BEGIN(BLE_L2CAP_EVT_CH_SDU_BUF_RELEASED, l2cap, ch_sdu_buf_released);
+
+ SER_PULL_uint16(&p_event->evt.l2cap_evt.conn_handle);
+ SER_PULL_uint16(&p_event->evt.l2cap_evt.local_cid);
+ SER_PULL_uint16(&p_event->evt.l2cap_evt.params.ch_sdu_buf_released.sdu_buf.len);
+ SER_PULL_uint32(&p_event->evt.l2cap_evt.params.ch_sdu_buf_released.sdu_buf.p_data);
+
+ SER_EVT_DEC_END;
+}
+
+uint32_t ble_l2cap_evt_ch_credit_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ ble_evt_t * const p_event,
+ uint32_t * const p_event_len)
+{
+ SER_EVT_DEC_BEGIN(BLE_L2CAP_EVT_CH_CREDIT, l2cap, ch_credit);
+
+ SER_PULL_uint16(&p_event->evt.l2cap_evt.conn_handle);
+ SER_PULL_uint16(&p_event->evt.l2cap_evt.local_cid);
+ SER_PULL_uint16(&p_event->evt.l2cap_evt.params.credit.credits);
+
+ SER_EVT_DEC_END;
+}
+
+uint32_t ble_l2cap_evt_ch_rx_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ ble_evt_t * const p_event,
+ uint32_t * const p_event_len)
+{
+ SER_EVT_DEC_BEGIN(BLE_L2CAP_EVT_CH_RX, l2cap, ch_rx);
+
+ SER_PULL_uint16(&p_event->evt.l2cap_evt.conn_handle);
+ SER_PULL_uint16(&p_event->evt.l2cap_evt.local_cid);
+ SER_PULL_uint16(&p_event->evt.l2cap_evt.params.rx.sdu_len);
+ SER_PULL_uint16(&p_event->evt.l2cap_evt.params.rx.sdu_buf.len);
+
+ SER_PULL_uint32(&p_event->evt.l2cap_evt.params.rx.sdu_buf.p_data);
+ SER_PULL_buf(&p_event->evt.l2cap_evt.params.rx.sdu_buf.p_data, p_event->evt.l2cap_evt.params.rx.sdu_buf.len, p_event->evt.l2cap_evt.params.rx.sdu_buf.len);
+
+ SER_EVT_DEC_END;
+}
+
+
+uint32_t ble_l2cap_evt_ch_tx_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ ble_evt_t * const p_event,
+ uint32_t * const p_event_len)
+{
+ SER_EVT_DEC_BEGIN(BLE_L2CAP_EVT_CH_TX, l2cap, ch_tx);
+
+ SER_PULL_uint16(&p_event->evt.l2cap_evt.conn_handle);
+ SER_PULL_uint16(&p_event->evt.l2cap_evt.local_cid);
+ SER_PULL_uint16(&p_event->evt.l2cap_evt.params.tx.sdu_buf.len);
+ SER_PULL_uint32(&p_event->evt.l2cap_evt.params.tx.sdu_buf.p_data);
+
+ SER_EVT_DEC_END;
+}
+
+#endif
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/application/codecs/ble/serializers/ble_l2cap_evt_app.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/application/codecs/ble/serializers/ble_l2cap_evt_app.h
new file mode 100644
index 0000000..e2d7958
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/application/codecs/ble/serializers/ble_l2cap_evt_app.h
@@ -0,0 +1,126 @@
+/**
+ * Copyright (c) 2014 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#ifndef BLE_L2CAP_EVT_APP_H__
+#define BLE_L2CAP_EVT_APP_H__
+
+/**@file
+ *
+ * @defgroup ble_l2cap_evt_app L2CAP Application event decoders
+ * @{
+ * @ingroup ser_app_s130_codecs
+ *
+ * @brief L2CAP Application event decoders.
+ */
+#include "ble.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @brief Decodes ble_l2cap_evt_rx event.
+ *
+ * If \p p_event is null, the required length of \p p_event is returned in \p p_event_len.
+ *
+ * @param[in] p_buf Pointer to the beginning of an event packet.
+ * @param[in] packet_len Length (in bytes) of the event packet.
+ * @param[in,out] p_event Pointer to a \ref ble_evt_t buffer where the decoded event will be
+ * stored. If NULL, required length will be returned in \p p_event_len.
+ * @param[in,out] p_event_len \c in: Size (in bytes) of \p p_event buffer.
+ * \c out: Length of decoded contents of \p p_event.
+ *
+ * @retval NRF_SUCCESS Decoding success.
+ * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length.
+ * @retval NRF_ERROR_DATA_SIZE Decoding failure. Length of \p p_event is too small to
+ * hold decoded event.
+ */
+uint32_t ble_l2cap_evt_rx_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ ble_evt_t * const p_event,
+ uint32_t * const p_event_len);
+
+uint32_t ble_l2cap_evt_ch_setup_request_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ ble_evt_t * const p_event,
+ uint32_t * const p_event_len);
+
+uint32_t ble_l2cap_evt_ch_setup_refused_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ ble_evt_t * const p_event,
+ uint32_t * const p_event_len);
+
+uint32_t ble_l2cap_evt_ch_setup_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ ble_evt_t * const p_event,
+ uint32_t * const p_event_len);
+
+uint32_t ble_l2cap_evt_ch_released_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ ble_evt_t * const p_event,
+ uint32_t * const p_event_len);
+
+uint32_t ble_l2cap_evt_ch_sdu_buf_released_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ ble_evt_t * const p_event,
+ uint32_t * const p_event_len);
+
+uint32_t ble_l2cap_evt_ch_credit_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ ble_evt_t * const p_event,
+ uint32_t * const p_event_len);
+
+uint32_t ble_l2cap_evt_ch_rx_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ ble_evt_t * const p_event,
+ uint32_t * const p_event_len);
+
+
+uint32_t ble_l2cap_evt_ch_tx_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ ble_evt_t * const p_event,
+ uint32_t * const p_event_len);
+/** @} */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/application/codecs/ble/serializers/nrf_soc_app.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/application/codecs/ble/serializers/nrf_soc_app.c
new file mode 100644
index 0000000..dab842b
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/application/codecs/ble/serializers/nrf_soc_app.c
@@ -0,0 +1,95 @@
+/**
+ * Copyright (c) 2013 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#include "nrf_soc_app.h"
+#include "nrf_soc.h"
+#include <stdlib.h>
+#include <string.h>
+#include "ble_serialization.h"
+#include "cond_field_serialization.h"
+#include "nrf_soc_struct_serialization.h"
+#include "app_util.h"
+
+
+uint32_t ecb_block_encrypt_req_enc(nrf_ecb_hal_data_t * p_ecb_data,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len)
+{
+ SER_REQ_ENC_BEGIN(SD_ECB_BLOCK_ENCRYPT);
+ SER_PUSH_COND(p_ecb_data, nrf_ecb_hal_data_t_in_enc);
+ SER_REQ_ENC_END;
+}
+
+
+uint32_t ecb_block_encrypt_rsp_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ nrf_ecb_hal_data_t * * const pp_ecb_data,
+ uint32_t * const p_result_code)
+{
+ SER_RSP_DEC_BEGIN(SD_ECB_BLOCK_ENCRYPT);
+ SER_PULL_COND(pp_ecb_data, nrf_ecb_hal_data_t_out_dec);
+ SER_RSP_DEC_END;
+}
+
+
+uint32_t power_system_off_req_enc(uint8_t * const p_buf, uint32_t * const p_buf_len)
+{
+ SER_REQ_ENC_BEGIN(SD_POWER_SYSTEM_OFF);
+ SER_REQ_ENC_END;
+}
+
+
+uint32_t temp_get_req_enc(int32_t const * const p_temp,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len)
+{
+ SER_REQ_ENC_BEGIN(SD_TEMP_GET);
+ SER_PUSH_COND(p_temp, NULL);
+ SER_REQ_ENC_END;
+}
+
+uint32_t temp_get_rsp_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ uint32_t * const p_result_code,
+ int32_t * * const pp_temp)
+{
+ SER_RSP_DEC_BEGIN(SD_TEMP_GET);
+ SER_PULL_COND(pp_temp, uint32_t_dec);
+ SER_RSP_DEC_END;
+}
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/application/codecs/ble/serializers/nrf_soc_app.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/application/codecs/ble/serializers/nrf_soc_app.h
new file mode 100644
index 0000000..ed1cb84
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/application/codecs/ble/serializers/nrf_soc_app.h
@@ -0,0 +1,147 @@
+/**
+ * Copyright (c) 2013 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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
+ *
+ * @defgroup soc_app SOC Application command request encoders and command response decoders
+ * @{
+ * @ingroup ser_app_s130_codecs
+ *
+ * @brief SOC Application command request encoders and command response decoders.
+ */
+
+#ifndef NRF_SOC_APP_H__
+#define NRF_SOC_APP_H__
+
+#include <stdint.h>
+#include "nrf_soc.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+/**@brief Encodes @ref sd_power_system_off command request.
+ *
+ *
+ * @param[in] p_buf Pointer to buffer where encoded data command will be returned.
+ * @param[in,out] p_buf_len \c in: size of p_buf buffer. \c out: Length of encoded command packet.
+ *
+ * @retval NRF_SUCCESS Encoding success.
+ * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length.
+ */
+uint32_t power_system_off_req_enc(uint8_t * const p_buf, uint32_t * const p_buf_len);
+
+
+/**@brief Encodes @ref sd_temp_get command request.
+ *
+ * @sa @ref temp_get_rsp_dec for command response decoder.
+ *
+ * @param[in] p_temp Pointer to result of temperature measurement.
+ * @param[in] p_buf Pointer to buffer where encoded data command will be returned.
+ * @param[in,out] p_buf_len \c in: size of p_buf buffer. \c out: Length of encoded command packet.
+ *
+ * @retval NRF_SUCCESS Encoding success.
+ * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length.
+ */
+uint32_t temp_get_req_enc(int32_t const * const p_temp,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len);
+
+/**@brief Decodes response to @ref sd_temp_get command.
+ *
+ * @sa @ref temp_get_req_enc for command request encoder.
+ *
+ * @param[in] p_buf Pointer to beginning of command response packet.
+ * @param[in] packet_len Length (in bytes) of response packet.
+ * @param[out] p_result_code Command result code.
+ * @param[out] pp_temp Pointer to result of temperature measurement.
+ *
+ * @retval NRF_SUCCESS Version information stored successfully.
+ * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length.
+ * @retval NRF_ERROR_DATA_SIZE Decoding failure. Length of \p p_event is too small to
+ * hold decoded event.
+ */
+uint32_t temp_get_rsp_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ uint32_t * const p_result_code,
+ int32_t * * const pp_temp);
+
+/**@brief Encodes @ref sd_ecb_block_encrypt command request.
+ *
+ * @sa @ref ecb_block_encrypt_rsp_dec for command response decoder.
+ *
+ * @param[in] p_ecb_data Pointer to ECB data.
+ * @param[in] p_buf Pointer to buffer where encoded data command will be returned.
+ * @param[in,out] p_buf_len \c in: size of p_buf buffer. \c out: Length of encoded command packet.
+ *
+ * @retval NRF_SUCCESS Encoding success.
+ * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length.
+ */
+uint32_t ecb_block_encrypt_req_enc(nrf_ecb_hal_data_t * p_ecb_data,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len);
+
+/**@brief Decodes response to @ref sd_ecb_block_encrypt command.
+ *
+ * @sa @ref ecb_block_encrypt_req_enc for command request encoder.
+ *
+ * @param[in] p_buf Pointer to beginning of command response packet.
+ * @param[in] packet_len Length (in bytes) of response packet.
+ * @param[out] p_ecb_data Pointer to ECB data.
+ * @param[out] p_result_code Command result code.
+ *
+ * @retval NRF_SUCCESS Version information stored successfully.
+ * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length.
+ * @retval NRF_ERROR_DATA_SIZE Decoding failure. Length of \p p_event is too small to
+ * hold decoded event.
+ */
+uint32_t ecb_block_encrypt_rsp_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ nrf_ecb_hal_data_t * * const p_ecb_data,
+ uint32_t * const p_result_code);
+/** @} */
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // NRF_SOC_APP_H__
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/application/codecs/common/ble_dtm_app.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/application/codecs/common/ble_dtm_app.c
new file mode 100644
index 0000000..fe86167
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/application/codecs/common/ble_dtm_app.c
@@ -0,0 +1,100 @@
+/**
+ * Copyright (c) 2014 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#include <stdint.h>
+#include "app_error.h"
+#include "ble_dtm_app.h"
+#include "ble_serialization.h"
+#include "nrf_error.h"
+#include "ser_config.h"
+#include "ser_hal_transport.h"
+#include "ser_sd_transport.h"
+
+
+static uint32_t dtm_init_rsp_dec(const uint8_t * p_buffer, uint16_t length)
+{
+ uint32_t result_code;
+
+ const uint32_t err_code = ble_dtm_init_rsp_dec(p_buffer, length, &result_code);
+ APP_ERROR_CHECK(err_code);
+
+ return result_code;
+}
+
+
+uint32_t ble_dtm_init(app_uart_stream_comm_params_t * p_uart_comm_params)
+{
+ if (p_uart_comm_params == NULL)
+ {
+ return NRF_ERROR_NULL;
+ }
+
+ uint32_t err_code = NRF_SUCCESS;
+ uint32_t index = 0;
+
+ uint8_t * p_tx_buf = NULL;
+ uint32_t tx_buf_len = 0;
+
+ err_code = ser_hal_transport_tx_pkt_alloc(&p_tx_buf, (uint16_t *)&tx_buf_len);
+ if (err_code != NRF_SUCCESS)
+ {
+ return err_code;
+ }
+
+ p_tx_buf[index++] = SER_PKT_TYPE_DTM_CMD;
+ tx_buf_len -= SER_PKT_TYPE_SIZE;
+
+ err_code = ble_dtm_init_req_enc(p_uart_comm_params, &(p_tx_buf[SER_PKT_TYPE_SIZE]), &tx_buf_len);
+ if (err_code == NRF_SUCCESS)
+ {
+ tx_buf_len += SER_PKT_TYPE_SIZE;
+
+ err_code = ser_sd_transport_cmd_write(p_tx_buf, tx_buf_len, dtm_init_rsp_dec);
+ if (err_code != NRF_SUCCESS)
+ {
+ err_code = NRF_ERROR_INTERNAL;
+ }
+ }
+ else
+ {
+ err_code = NRF_ERROR_INTERNAL;
+ }
+
+ return err_code;
+}
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/application/codecs/common/ble_dtm_app.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/application/codecs/common/ble_dtm_app.h
new file mode 100644
index 0000000..3d008a3
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/application/codecs/common/ble_dtm_app.h
@@ -0,0 +1,126 @@
+/**
+ * Copyright (c) 2014 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#ifndef BLE_DTM_APP_H__
+#define BLE_DTM_APP_H__
+
+/**
+ * @addtogroup ser_codecs Serialization codecs
+ * @ingroup ble_sdk_lib_serialization
+ * @brief Application and Connectivity codecs.
+ */
+
+/**
+ * @addtogroup ser_codecs_app Application codecs
+ * @ingroup ser_codecs
+ */
+
+/**
+ * @addtogroup ser_app_common_codecs Application common codecs
+ * @ingroup ser_codecs_app
+ */
+
+/**@file
+ *
+ * @defgroup ble_dtm_app DTM Application command request encoders and command response decoders
+ * @{
+ * @ingroup ser_app_common_codecs
+ *
+ * @brief DTM Application command request encoders and command response decoders.
+ */
+
+#include "dtm_uart_params.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**@brief Encodes the @ref ble_dtm_init command request.
+ *
+ * @sa @ref encoding_data for packet format,
+ * @ref ble_dtm_init_rsp_dec for command response decoder.
+ *
+ * @param[in] p_uart_comm_params Pointer to the UART configuration parameters.
+ * @param[in] p_buf Pointer to the buffer where encoded data command will be returned.
+ * @param[in,out] p_buf_len \c in: Size of \p p_buf buffer.
+ * \c out: Length of the encoded command packet.
+ *
+ * @retval NRF_SUCCESS Encoding success.
+ * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length.
+ */
+uint32_t ble_dtm_init_req_enc(app_uart_stream_comm_params_t const * const p_uart_comm_params,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len);
+
+
+/**@brief Decodes the response @ref ble_dtm_init command.
+ *
+ * @sa @ref encoding_data for packet format,
+ * @ref ble_dtm_init_req_enc for command request encoder.
+ *
+ * @param[in] p_buf Pointer to the beginning of a command response packet.
+ * @param[in] packet_len Length (in bytes) of the response packet.
+ * @param[out] p_result_code Command result code.
+ *
+ * @retval NRF_SUCCESS Decoding success.
+ * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length.
+ */
+uint32_t ble_dtm_init_rsp_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ uint32_t * const p_result_code);
+
+
+/**@brief Function to initializing the DTM mode.
+ *
+ * @param[in] p_uart_comm_params Pointer to the DTM UART configuration parameters.
+ *
+ * @retval NRF_SUCCESS Encoding success.
+ * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied.
+ */
+uint32_t ble_dtm_init(app_uart_stream_comm_params_t * p_uart_comm_params);
+
+/** @} */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // BLE_DTM_APP_H__
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/application/codecs/common/ble_dtm_init.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/application/codecs/common/ble_dtm_init.c
new file mode 100644
index 0000000..16e3c47
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/application/codecs/common/ble_dtm_init.c
@@ -0,0 +1,83 @@
+/**
+ * Copyright (c) 2014 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#include "ble_dtm_app.h"
+#include "ble_serialization.h"
+#include "nrf_error.h"
+
+uint32_t ble_dtm_init_req_enc(app_uart_stream_comm_params_t const * const p_uart_comm_params, uint8_t * const p_buf, uint32_t * const p_buf_len)
+{
+ SER_ASSERT_NOT_NULL(p_buf);
+ SER_ASSERT_NOT_NULL(p_buf_len);
+ SER_ASSERT_NOT_NULL(p_uart_comm_params);
+
+ uint32_t index = 0;
+ uint32_t buf_len = *p_buf_len;
+ uint32_t err_code;
+
+ err_code = uint8_t_enc(&p_uart_comm_params->tx_pin_no, p_buf, buf_len, &index);
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code);
+
+ err_code = uint8_t_enc(&p_uart_comm_params->rx_pin_no, p_buf, buf_len, &index);
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code);
+
+ err_code = uint8_t_enc(&p_uart_comm_params->baud_rate, p_buf, buf_len, &index);
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code);
+
+ *p_buf_len = index;
+
+ return err_code;
+}
+
+
+uint32_t ble_dtm_init_rsp_dec(uint8_t const * const p_buf, uint32_t packet_len, uint32_t * const p_result_code)
+{
+ SER_ASSERT_NOT_NULL(p_buf);
+ SER_ASSERT_NOT_NULL(p_result_code);
+
+ uint32_t err_code;
+ uint32_t index = 0;
+
+ err_code = uint32_t_dec(p_buf, packet_len, &index, p_result_code);
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code);
+
+ SER_ASSERT(packet_len == index, NRF_ERROR_INVALID_LENGTH);
+
+ return err_code;
+}
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/application/codecs/common/conn_systemreset.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/application/codecs/common/conn_systemreset.c
new file mode 100644
index 0000000..b98e6d5
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/application/codecs/common/conn_systemreset.c
@@ -0,0 +1,69 @@
+/**
+ * Copyright (c) 2014 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#include <stdint.h>
+#include "ble_serialization.h"
+#include "ser_hal_transport.h"
+#include "ser_sd_transport.h"
+
+
+uint32_t conn_systemreset(void)
+{
+ uint32_t err_code = NRF_SUCCESS;
+ uint8_t * p_tx_buf = NULL;
+ uint32_t tx_buf_len = 0;
+
+ err_code = ser_hal_transport_tx_pkt_alloc(&p_tx_buf, (uint16_t *)&tx_buf_len);
+ if (err_code != NRF_SUCCESS)
+ {
+ return err_code;
+ }
+
+ SER_ASSERT_LENGTH_LEQ(SER_PKT_TYPE_SIZE, tx_buf_len);
+ p_tx_buf[SER_PKT_TYPE_POS] = SER_PKT_TYPE_RESET_CMD;
+ tx_buf_len = SER_PKT_TYPE_SIZE;
+
+ err_code = ser_sd_transport_cmd_write(p_tx_buf, tx_buf_len, NULL);
+ if (err_code != NRF_SUCCESS)
+ {
+ err_code = NRF_ERROR_INTERNAL;
+ }
+
+ return err_code;
+}
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/application/codecs/common/conn_systemreset.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/application/codecs/common/conn_systemreset.h
new file mode 100644
index 0000000..00ea5f5
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/application/codecs/common/conn_systemreset.h
@@ -0,0 +1,79 @@
+/**
+ * Copyright (c) 2014 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#ifndef CONN_SYSTEMRESET_H__
+#define CONN_SYSTEMRESET_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @addtogroup ser_codecs Serialization codecs
+ * @ingroup ble_sdk_lib_serialization
+ */
+
+/**
+ * @addtogroup ser_app_common_codecs Application common codecs
+ * @ingroup ser_codecs_app
+ */
+
+/**@file
+ *
+ * @defgroup conn_systemreset Connectivity chip reset command request encoder
+ * @{
+ * @ingroup ser_app_common_codecs
+ *
+ * @brief Connectivity chip reset command request encoder.
+ */
+
+/**@brief Function for performing the connectivity chip reset.
+ *
+ * @retval NRF_SUCCESS Encoding success.
+ * @retval NRF_ERROR_INTERNAL Encoding failure. Transport error.
+ */
+uint32_t conn_systemreset(void);
+
+/** @} */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // CONN_SYSTEMRESET_H__
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/application/hal/ser_app_hal.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/application/hal/ser_app_hal.h
new file mode 100644
index 0000000..3c87057
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/application/hal/ser_app_hal.h
@@ -0,0 +1,116 @@
+/**
+ * Copyright (c) 2014 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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
+ *
+ * @defgroup ser_app_hal Serialization Application Hardware Abstraction Layer (HAL)
+ * @{
+ * @ingroup ble_sdk_lib_serialization
+ *
+ * @brief Functions that set up hardware on Application Board and perform the reset of the Connectivity Board.
+ */
+
+#ifndef SER_APP_HAL_H_
+#define SER_APP_HAL_H_
+
+#include <stdint.h>
+#include <stdbool.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+typedef void (*ser_app_hal_flash_op_done_handler_t)(bool success);
+/**@brief Function for initializing hardware modules.
+ *
+ * @details Function can initialize hardware modules on the Application Chip. It is optional to
+ * implement. It is called once the Connectivity Chip is initialized.
+ *
+ * @param handler Flash operation event handler.
+ *
+ * @return @ref NRF_SUCCESS HAL initialized successfully.
+ * @return @ref nrf_error "NRF_ERROR_..." HAL initialization failed.
+ *
+ */
+uint32_t ser_app_hal_hw_init(ser_app_hal_flash_op_done_handler_t handler);
+
+/**@brief Function for waiting for a given amount of time.
+ *
+ * @param[in] ms Number of milliseconds to wait.
+ *
+ */
+void ser_app_hal_delay(uint32_t ms);
+
+/**@brief Function for clearing the Connectivity Chip reset pin.
+ *
+ */
+void ser_app_hal_nrf_reset_pin_clear(void);
+
+/**@brief Function for setting the Connectivity Chip reset pin.
+ *
+ */
+void ser_app_hal_nrf_reset_pin_set(void);
+
+
+/**@brief Function for setting the SoftDevice event interrupt priority that serves the events incoming
+ * from the Connectivity Chip.
+ *
+ * @note Serialization solution on the application side mimics a SoC solution where events are handled in
+ * the interrupt context in two ways: either directly in the interrupt context or with a message being posted to
+ * the scheduler. However, it is possible that the Application Chip does not use a dedicated interrupt
+ * for connectivity events. In that case, this function can be left empty and
+ * \ref ser_app_hal_nrf_evt_pending will directly call an interrupt handler function.
+ */
+void ser_app_hal_nrf_evt_irq_priority_set(void);
+
+/**@brief Function for setting a pending interrupt for serving events incoming from the Connectivity Chip.
+ *
+ * @note The interrupt used for event from the Connectivity Chip mimics behavior of SoC and it is not
+ * intended to be triggered by any hardware event. This function should be the only source of
+ * interrupt triggering.
+ */
+void ser_app_hal_nrf_evt_pending(void);
+
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* SER_APP_HAL_H_ */
+/** @} */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/application/hal/ser_app_hal_nrf5x.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/application/hal/ser_app_hal_nrf5x.c
new file mode 100644
index 0000000..7304a12
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/application/hal/ser_app_hal_nrf5x.c
@@ -0,0 +1,163 @@
+/**
+ * Copyright (c) 2014 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#include "app_util_platform.h"
+#include "ser_app_hal.h"
+#include "nrf.h"
+#include "nrf_gpio.h"
+#include "nrf_soc.h"
+#include "nrf_delay.h"
+#include "nrf_nvmc.h"
+#include "boards.h"
+#include "ser_phy.h"
+#include "ser_phy_config_app.h"
+#include "nrf_drv_clock.h"
+
+#define SOFTDEVICE_EVT_IRQ SD_EVT_IRQn /**< SoftDevice Event IRQ number. Used for both protocol events and SoC events. */
+#define FLASH_WRITE_MAX_LENGTH ((uint16_t)NRF_FICR->CODEPAGESIZE)
+#define BLE_FLASH_PAGE_SIZE ((uint16_t)NRF_FICR->CODEPAGESIZE) /**< Size of one flash page. */
+
+static ser_app_hal_flash_op_done_handler_t m_flash_op_handler;
+uint32_t ser_app_hal_hw_init(ser_app_hal_flash_op_done_handler_t handler)
+{
+ nrf_gpio_cfg_output(CONN_CHIP_RESET_PIN_NO);
+
+ if (NRF_SUCCESS != nrf_drv_clock_init())
+ {
+ return NRF_ERROR_INTERNAL;
+ }
+
+ nrf_drv_clock_lfclk_request(NULL);
+ nrf_drv_clock_hfclk_request(NULL);
+
+ while (false == nrf_drv_clock_hfclk_is_running());
+ while (false == nrf_drv_clock_lfclk_is_running());
+
+ m_flash_op_handler = handler;
+
+ return NRF_SUCCESS;
+}
+
+void ser_app_hal_delay(uint32_t ms)
+{
+ nrf_delay_ms(ms);
+}
+
+void ser_app_hal_nrf_reset_pin_clear()
+{
+ nrf_gpio_pin_clear(CONN_CHIP_RESET_PIN_NO);
+}
+
+void ser_app_hal_nrf_reset_pin_set()
+{
+ nrf_gpio_pin_set(CONN_CHIP_RESET_PIN_NO);
+}
+
+void ser_app_hal_nrf_evt_irq_priority_set()
+{
+ NVIC_SetPriority(SOFTDEVICE_EVT_IRQ, APP_IRQ_PRIORITY_LOWEST);
+}
+
+void ser_app_hal_nrf_evt_pending()
+{
+ NVIC_SetPendingIRQ(SOFTDEVICE_EVT_IRQ);
+}
+
+uint32_t sd_ppi_channel_enable_get(uint32_t * p_channel_enable)
+{
+ *p_channel_enable = NRF_PPI->CHEN;
+ return NRF_SUCCESS;
+}
+
+uint32_t sd_ppi_channel_enable_set(uint32_t channel_enable_set_msk)
+{
+ NRF_PPI->CHEN = channel_enable_set_msk;
+ return NRF_SUCCESS;
+}
+
+uint32_t sd_ppi_channel_assign(uint8_t channel_num,
+ const volatile void * evt_endpoint,
+ const volatile void * task_endpoint)
+{
+ NRF_PPI->CH[channel_num].TEP = (uint32_t)task_endpoint;
+ NRF_PPI->CH[channel_num].EEP = (uint32_t)evt_endpoint;
+ return NRF_SUCCESS;
+}
+/**
+ * @brief Check if given address is in device FLASH range.
+ *
+ * @param[in] ptr Address to check.
+ * @retval true Given address is located in FLASH.
+ * @retval false Given address is not located in FLASH.
+ */
+__STATIC_INLINE bool addr_is_in_FLASH(void const * const ptr)
+{
+ return ((((uintptr_t)ptr) & 0xFF000000u) == 0x00000000u);
+}
+
+uint32_t sd_flash_page_erase(uint32_t page_number)
+{
+ uint32_t * p_page = (uint32_t *)(BLE_FLASH_PAGE_SIZE * page_number);
+
+ if (!addr_is_in_FLASH(p_page))
+ {
+ return NRF_ERROR_INVALID_ADDR;
+ }
+
+ nrf_nvmc_page_erase((uint32_t) p_page);
+ m_flash_op_handler(true);
+ return NRF_SUCCESS;
+}
+
+uint32_t sd_flash_write(uint32_t * const p_dst, uint32_t const * const p_src, uint32_t size)
+{
+ if (size > FLASH_WRITE_MAX_LENGTH)
+ {
+ return NRF_ERROR_INVALID_LENGTH;
+ }
+
+ if (!addr_is_in_FLASH(p_dst))
+ {
+ return NRF_ERROR_INVALID_ADDR;
+ }
+
+ nrf_nvmc_write_words((uint32_t) p_dst, p_src, size);
+ m_flash_op_handler(true);
+ return NRF_SUCCESS;
+}
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/application/hal/ser_app_power_system_off.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/application/hal/ser_app_power_system_off.c
new file mode 100644
index 0000000..056636f
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/application/hal/ser_app_power_system_off.c
@@ -0,0 +1,62 @@
+/**
+ * Copyright (c) 2014 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#include "nrf.h"
+#include "ser_app_power_system_off.h"
+
+static bool m_power_system_off = false;
+
+
+void ser_app_power_system_off_set(void)
+{
+ m_power_system_off = true;
+}
+
+bool ser_app_power_system_off_get(void)
+{
+ return m_power_system_off;
+}
+
+void ser_app_power_system_off_enter(void)
+{
+ NRF_POWER->SYSTEMOFF = POWER_SYSTEMOFF_SYSTEMOFF_Enter;
+
+ /*Only for debugging purpose, will not be reached without connected debugger*/
+ while (1);
+}
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/application/hal/ser_app_power_system_off.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/application/hal/ser_app_power_system_off.h
new file mode 100644
index 0000000..914a59e
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/application/hal/ser_app_power_system_off.h
@@ -0,0 +1,60 @@
+/**
+ * Copyright (c) 2014 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#ifndef APP_POWER_SYSTEM_OFF_H
+#define APP_POWER_SYSTEM_OFF_H
+
+#include <stdbool.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void ser_app_power_system_off_set(void);
+
+bool ser_app_power_system_off_get(void);
+
+void ser_app_power_system_off_enter(void);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/application/transport/ser_sd_transport.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/application/transport/ser_sd_transport.c
new file mode 100644
index 0000000..8f0118a
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/application/transport/ser_sd_transport.c
@@ -0,0 +1,325 @@
+/**
+ * Copyright (c) 2014 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#include <stdbool.h>
+#include <stdint.h>
+#include <stddef.h>
+#include "ser_sd_transport.h"
+#include "ser_hal_transport.h"
+#include "nrf_error.h"
+#include "app_error.h"
+#include "ble_serialization.h"
+#include "ser_dbg_sd_str.h"
+#include "ser_app_power_system_off.h"
+#include "app_util.h"
+#define NRF_LOG_MODULE_NAME ser_xfer
+#include "nrf_log.h"
+NRF_LOG_MODULE_REGISTER();
+
+#ifdef BLE_STACK_SUPPORT_REQD
+/** SoftDevice event handler. */
+static ser_sd_transport_evt_handler_t m_ble_evt_handler = NULL;
+#endif // BLE_STACK_SUPPORT_REQD
+
+#ifdef ANT_STACK_SUPPORT_REQD
+/** SoftDevice event handler for ANT events. */
+static ser_sd_transport_evt_handler_t m_ant_evt_handler = NULL;
+#endif // ANT_STACK_SUPPORT_REQD
+
+/** 'One time' handler called in task context while waiting for response to scheduled command. */
+static ser_sd_transport_rsp_wait_handler_t m_ot_rsp_wait_handler = NULL;
+
+/** Handler called in task context while waiting for response to scheduled command. */
+static ser_sd_transport_rsp_wait_handler_t m_os_rsp_wait_handler = NULL;
+
+/** Handler called in serial peripheral interrupt context when response is received. */
+static ser_sd_transport_rsp_set_handler_t m_os_rsp_set_handler = NULL;
+
+/** Handler called when hal_transport notifies that packet reception has started. */
+static ser_sd_transport_rx_notification_handler_t m_rx_notify_handler = NULL;
+
+/** User decoder handler for expected response packet. */
+static ser_sd_transport_rsp_handler_t m_rsp_dec_handler = NULL;
+
+/** Flag indicated whether module is waiting for response packet. */
+static volatile bool m_rsp_wait = false;
+
+/** SoftDevice call return value decoded by user decoder handler. */
+static uint32_t m_return_value;
+
+/**@brief Function for handling the rx packets comming from hal_transport.
+ *
+ * @details
+ * This function is called in serial peripheral interrupt context. Response packets are handled in
+ * this context. Events are passed to the application and it is up to application in which context
+ * they are handled.
+ *
+ * @param[in] p_data Pointer to received data.
+ * @param[in] length Size of data.
+ */
+static void ser_sd_transport_rx_packet_handler(uint8_t * p_data, uint16_t length)
+{
+ if (p_data && (length >= SER_PKT_TYPE_SIZE))
+ {
+ const uint8_t packet_type = p_data[SER_PKT_TYPE_POS];
+ p_data += SER_PKT_TYPE_SIZE;
+ length -= SER_PKT_TYPE_SIZE;
+
+ switch (packet_type)
+ {
+ case SER_PKT_TYPE_RESP:
+ case SER_PKT_TYPE_DTM_RESP:
+#ifdef ANT_STACK_SUPPORT_REQD
+ case SER_PKT_TYPE_ANT_RESP:
+#endif // ANT_STACK_SUPPORT_REQD
+ if (m_rsp_wait)
+ {
+ m_return_value = m_rsp_dec_handler(p_data, length);
+ (void)ser_sd_transport_rx_free(p_data);
+
+ /* Reset response flag - cmd_write function is pending on it.*/
+ m_rsp_wait = false;
+
+ /* If os handler is set, signal os that response has arrived.*/
+ if (m_os_rsp_set_handler)
+ {
+ m_os_rsp_set_handler();
+ }
+ }
+ else
+ {
+ /* Unexpected packet. */
+ (void)ser_sd_transport_rx_free(p_data);
+ APP_ERROR_HANDLER(packet_type);
+ }
+ break;
+
+#ifdef BLE_STACK_SUPPORT_REQD
+ case SER_PKT_TYPE_EVT:
+ /* It is ensured during opening that handler is not NULL. No check needed. */
+ NRF_LOG_DEBUG("[EVT]: %s ", (uint32_t)ser_dbg_sd_evt_str_get(uint16_decode(&p_data[SER_EVT_ID_POS]))); // p_data points to EVT_ID
+ m_ble_evt_handler(p_data, length);
+ break;
+#endif // BLE_STACK_SUPPORT_REQD
+
+#ifdef ANT_STACK_SUPPORT_REQD
+ case SER_PKT_TYPE_ANT_EVT:
+ /* It is ensured during opening that handler is not NULL. No check needed. */
+ NRF_LOG_DEBUG("[ANT_EVT_ID]: %s ", (uint32_t)ser_dbg_sd_evt_str_get(uint16_decode(&p_data[SER_EVT_ID_POS]))); // p_data points to EVT_ID
+ m_ant_evt_handler(p_data, length);
+ break;
+#endif // ANT_STACK_SUPPORT_REQD
+
+ default:
+ (void)ser_sd_transport_rx_free(p_data);
+ APP_ERROR_HANDLER(packet_type);
+ break;
+ }
+ }
+}
+
+/**@brief Function for handling the event from hal_transport.
+ *
+ * @param[in] event Event from hal_transport.
+ */
+static void ser_sd_transport_hal_handler(ser_hal_transport_evt_t event)
+{
+ switch (event.evt_type)
+ {
+ case SER_HAL_TRANSP_EVT_RX_PKT_RECEIVED:
+ ser_sd_transport_rx_packet_handler(event.evt_params.rx_pkt_received.p_buffer,
+ event.evt_params.rx_pkt_received.num_of_bytes);
+ break;
+ case SER_HAL_TRANSP_EVT_RX_PKT_RECEIVING:
+ if (m_rx_notify_handler)
+ {
+ m_rx_notify_handler();
+ }
+ break;
+ case SER_HAL_TRANSP_EVT_TX_PKT_SENT:
+ if (ser_app_power_system_off_get() == true)
+ {
+ ser_app_power_system_off_enter();
+ }
+ break;
+ case SER_HAL_TRANSP_EVT_PHY_ERROR:
+
+ if (m_rsp_wait)
+ {
+ m_return_value = NRF_ERROR_INTERNAL;
+
+ /* Reset response flag - cmd_write function is pending on it.*/
+ m_rsp_wait = false;
+
+ /* If os handler is set, signal os that response has arrived.*/
+ if (m_os_rsp_set_handler)
+ {
+ m_os_rsp_set_handler();
+ }
+ }
+ break;
+ default:
+ break;
+ }
+}
+
+uint32_t ser_sd_transport_open(ser_sd_transport_evt_handler_t ble_evt_handler,
+ ser_sd_transport_evt_handler_t ant_evt_handler,
+ ser_sd_transport_rsp_wait_handler_t os_rsp_wait_handler,
+ ser_sd_transport_rsp_set_handler_t os_rsp_set_handler,
+ ser_sd_transport_rx_notification_handler_t rx_not_handler)
+{
+ m_os_rsp_wait_handler = os_rsp_wait_handler;
+ m_os_rsp_set_handler = os_rsp_set_handler;
+ m_rx_notify_handler = rx_not_handler;
+ m_ot_rsp_wait_handler = NULL;
+
+#ifdef ANT_STACK_SUPPORT_REQD
+ m_ant_evt_handler = ant_evt_handler;
+
+ if (m_ant_evt_handler == NULL)
+ {
+ return NRF_ERROR_INVALID_PARAM;
+ }
+#else
+ UNUSED_PARAMETER(ant_evt_handler);
+#endif // ANT_STACK_SUPPORT_REQD
+
+#ifdef BLE_STACK_SUPPORT_REQD
+ m_ble_evt_handler = ble_evt_handler;
+
+ if (m_ble_evt_handler == NULL)
+ {
+ return NRF_ERROR_INVALID_PARAM;
+ }
+#else
+ UNUSED_PARAMETER(ble_evt_handler);
+#endif // BLE_STACK_SUPPORT_REQD
+
+ return ser_hal_transport_open(ser_sd_transport_hal_handler);
+}
+
+uint32_t ser_sd_transport_close(void)
+{
+#ifdef ANT_STACK_SUPPORT_REQD
+ m_ant_evt_handler = NULL;
+#endif // ANT_STACK_SUPPORT_REQD
+
+#ifdef BLE_STACK_SUPPORT_REQD
+ m_ble_evt_handler = NULL;
+#endif // BLE_STACK_SUPPORT_REQD
+
+ m_os_rsp_wait_handler = NULL;
+ m_os_rsp_set_handler = NULL;
+ m_ot_rsp_wait_handler = NULL;
+
+ ser_hal_transport_close();
+
+ return NRF_SUCCESS;
+}
+
+uint32_t ser_sd_transport_ot_rsp_wait_handler_set(ser_sd_transport_rsp_wait_handler_t handler)
+{
+ m_ot_rsp_wait_handler = handler;
+
+ return NRF_SUCCESS;
+}
+
+bool ser_sd_transport_is_busy(void)
+{
+ return m_rsp_wait;
+}
+
+uint32_t ser_sd_transport_tx_alloc(uint8_t * * pp_data, uint16_t * p_len)
+{
+ uint32_t err_code;
+
+ if (m_rsp_wait)
+ {
+ err_code = NRF_ERROR_BUSY;
+ }
+ else
+ {
+ err_code = ser_hal_transport_tx_pkt_alloc(pp_data, p_len);
+ }
+ return err_code;
+}
+
+uint32_t ser_sd_transport_tx_free(uint8_t * p_data)
+{
+ return ser_hal_transport_tx_pkt_free(p_data);
+}
+
+uint32_t ser_sd_transport_rx_free(uint8_t * p_data)
+{
+ p_data -= SER_PKT_TYPE_SIZE;
+ return ser_hal_transport_rx_pkt_free(p_data);
+}
+
+uint32_t ser_sd_transport_cmd_write(const uint8_t * p_buffer,
+ uint16_t length,
+ ser_sd_transport_rsp_handler_t cmd_rsp_decode_callback)
+{
+ uint32_t err_code = NRF_SUCCESS;
+
+ m_rsp_wait = true;
+ m_rsp_dec_handler = cmd_rsp_decode_callback;
+ err_code = ser_hal_transport_tx_pkt_send(p_buffer, length);
+ APP_ERROR_CHECK(err_code);
+
+ /* Execute callback for response decoding only if one was provided.*/
+ if ((err_code == NRF_SUCCESS) && cmd_rsp_decode_callback)
+ {
+ if (m_ot_rsp_wait_handler)
+ {
+ m_ot_rsp_wait_handler();
+ m_ot_rsp_wait_handler = NULL;
+ }
+
+ m_os_rsp_wait_handler();
+ err_code = m_return_value;
+ }
+ else
+ {
+ m_rsp_wait = false;
+ }
+
+ NRF_LOG_DEBUG("[SD_CALL]:%s, err_code= 0x%X", (uint32_t)ser_dbg_sd_call_str_get(p_buffer[1]), err_code);
+ return err_code;
+}
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/application/transport/ser_sd_transport.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/application/transport/ser_sd_transport.h
new file mode 100644
index 0000000..77dadf2
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/application/transport/ser_sd_transport.h
@@ -0,0 +1,193 @@
+/**
+ * Copyright (c) 2014 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+/**
+ * @addtogroup ser_app Application side code
+ * @ingroup ble_sdk_lib_serialization
+ * @brief SoftDevice handler and transport on the application side.
+ */
+
+/** @file
+ *
+ * @defgroup ser_sd_transport Serialization SoftDevice Transport
+ * @{
+ * @ingroup ser_app
+ *
+ * @brief Serialization SoftDevice Transport on application side.
+ *
+ * @details This file contains declarations of functions and definitions of data structures and
+ * identifiers (typedef enum) used as API of the serialization of SoftDevice. This layer
+ * ensures atomic nature of SoftDevice calls (command and waiting for response). Packet
+ * type field of incoming packets is handled in this layer - responses are handled by
+ * ser_sd_transport (using response decoder handler provided for each SoftDevice call), but
+ * events are forwarded to the user so it is up to the user to free the RX buffer.
+ *
+ */
+#ifndef SER_SD_TRANSPORT_H_
+#define SER_SD_TRANSPORT_H_
+
+#include <stdint.h>
+#include <stdbool.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef void (*ser_sd_transport_evt_handler_t)(uint8_t * p_buffer, uint16_t length);
+typedef void (*ser_sd_transport_rsp_wait_handler_t)(void);
+typedef void (*ser_sd_transport_rsp_set_handler_t)(void);
+typedef void (*ser_sd_transport_rx_notification_handler_t)(void);
+
+typedef uint32_t (*ser_sd_transport_rsp_handler_t)(const uint8_t * p_buffer, uint16_t length);
+
+/**@brief Function for opening the module.
+ *
+ * @note 'Wait for response' and 'Response set' callbacks can be set in RTOS environment.
+ * It enables rescheduling while waiting for the Connectivity Chip response. In a nonOS environment,
+ * usually 'Wait for response' will only be used for handling incoming events or forcing the
+ * application to low power mode.
+ *
+ * @param[in] ble_evt_handler Handler to be called when ble event packet is received.
+ * @param[in] ant_evt_handler Handler to be called when ant event packet is received.
+ * @param[in] os_rsp_wait_handler Handler to be called after the request is send. It should
+ * implement a 'Wait for signal' functionality in an OS environment.
+ * @param[in] os_rsp_set_handler Handler to be called after response reception. It should
+ * implement a 'Signal Set' functionality in an OS environment.
+ * @param[in] rx_not_handler Handler to be called after the transport layer notifies that
+ * an incoming RX packet is detected.
+ *
+ * @retval NRF_SUCCESS Operation success.
+ * @retval NRF_ERROR_NULL Operation failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_PARAM Operation failure. Parameter propagated from ser_hal_transport
+ * opening or timer creation.
+ * @retval NRF_ERROR_INVALID_STATE Operation failure. Parameter propagated from ser_hal_transport
+ * opening or timer creation.
+ * @retval NRF_ERROR_INTERNAL Operation failure. Parameter propagated from ser_hal_transport
+ * opening or timer creation.
+ * @retval NRF_ERROR_NO_MEM Operation failure. Parameter propagated from timer creation.
+ */
+uint32_t ser_sd_transport_open(ser_sd_transport_evt_handler_t ble_evt_handler,
+ ser_sd_transport_evt_handler_t ant_evt_handler,
+ ser_sd_transport_rsp_wait_handler_t os_rsp_wait_handler,
+ ser_sd_transport_rsp_set_handler_t os_rsp_set_handler,
+ ser_sd_transport_rx_notification_handler_t rx_not_handler);
+
+
+/**@brief Function setting a 'One Time' handler to be called between sending the next request packet and
+ * receiving the response packet.
+ * @note It is intended to be used in a nonOS environment to implement concurrency.
+ * @note It is a 'One Time' handler meaning that it is valid only for the next SoftDevice call processing.
+ *
+ *
+ * @param[in] wait_handler Handler to be called after the request packet is sent.
+ *
+ * @retval NRF_SUCCESS Operation success.
+ */
+uint32_t ser_sd_transport_ot_rsp_wait_handler_set(ser_sd_transport_rsp_wait_handler_t wait_handler);
+
+
+/**@brief Function for closing the module.
+ *
+ * @retval NRF_SUCCESS Operation success.
+ */
+uint32_t ser_sd_transport_close(void);
+
+/**@brief Function for allocating a TX packet to be used for request command.
+ *
+ * @param[out] pp_data Pointer to the data pointer to be set to point to allocated buffer.
+ * @param[out] p_len Pointer to allocated buffer length.
+ *
+ * @retval NRF_SUCCESS Operation success.
+ */
+uint32_t ser_sd_transport_tx_alloc(uint8_t * * pp_data, uint16_t * p_len);
+
+
+/**@brief Function for freeing a TX packet.
+ *
+ * @note Function should be called once the command is processed.
+ *
+ * @param[out] p_data Pointer to the allocated TX buffer.
+ *
+ * @retval NRF_SUCCESS Operation success.
+ */
+uint32_t ser_sd_transport_tx_free(uint8_t * p_data);
+
+
+/**@brief Function for freeing an RX event packet.
+ *
+ * @note Function should be called once the SoftDevice event buffer is processed.
+ *
+ * @param[out] p_data Pointer to the allocated RX buffer.
+ *
+ * @retval NRF_SUCCESS Operation success.
+ */
+uint32_t ser_sd_transport_rx_free(uint8_t * p_data);
+
+
+/**@brief Function for checking if module is busy waiting for response from connectivity side.
+ *
+ * @retval true Module busy. Cannot accept the next command.
+ * @retval false Module not busy. Can accept next the command.
+ */
+bool ser_sd_transport_is_busy(void);
+
+/**@brief Function for handling a SoftDevice command.
+ *
+ * @note Function blocks task context until response is received and processed.
+ * @note Non-blocking functionality can be achieved using OS handlers or a 'One Time' handler
+ * @warning Function should not be called from interrupt context, which would block switching to
+ * serial port interrupt.
+ *
+ * @param[in] p_buffer Pointer to command.
+ * @param[in] length Pointer to allocated buffer length.
+ * @param[in] cmd_resp_decode_callback Pointer to a function for decoding the response packet.
+ *
+ * @retval NRF_SUCCESS Operation success.
+ */
+uint32_t ser_sd_transport_cmd_write(const uint8_t * p_buffer,
+ uint16_t length,
+ ser_sd_transport_rsp_handler_t cmd_resp_decode_callback);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* SER_SD_TRANSPORT_H_ */
+/** @} */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/application/transport/ser_softdevice_handler.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/application/transport/ser_softdevice_handler.c
new file mode 100644
index 0000000..57db847
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/application/transport/ser_softdevice_handler.c
@@ -0,0 +1,311 @@
+/**
+ * Copyright (c) 2014 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#include <stdlib.h>
+#include <string.h>
+#include "nrf_queue.h"
+#include "app_scheduler.h"
+#include "nrf_sdh.h"
+#include "nrf_sdm.h"
+#include "ser_sd_transport.h"
+#include "ser_app_hal.h"
+#include "ser_config.h"
+#include "nrf_soc.h"
+#include "ble_serialization.h"
+#if defined(BLE_STACK_SUPPORT_REQD)
+#include "ble_app.h"
+#include "nrf_sdh_ble.h"
+#endif
+#if defined(ANT_STACK_SUPPORT_REQD)
+#include "ant_event.h"
+#endif
+
+#define SD_BLE_EVT_MAILBOX_QUEUE_SIZE 5 /**< Size of mailbox queue. */
+
+/** @brief Structure used to pass packet details through mailbox.
+ */
+#if defined(BLE_STACK_SUPPORT_REQD)
+typedef struct
+{
+ //lint -save -e666
+ uint32_t evt_data[CEIL_DIV(NRF_SDH_BLE_EVT_BUF_SIZE, sizeof (uint32_t))]; /**< Buffer for decoded event */
+ //lint -restore
+} ser_sd_handler_evt_data_t;
+#endif
+
+#if defined(ANT_STACK_SUPPORT_REQD)
+typedef struct
+{
+ uint32_t evt_data[CEIL_DIV(sizeof(ant_evt_t), sizeof (uint32_t))]; /**< Buffer for decoded event */
+} ser_ant_sd_handler_evt_data_t;
+#endif
+
+/** @brief
+ * Mailbox used for communication between event handler (called from serial stream
+ * interrupt context) and event processing function (called from scheduler or interrupt context).
+ */
+#if defined(BLE_STACK_SUPPORT_REQD)
+NRF_QUEUE_DEF(ser_sd_handler_evt_data_t,
+ m_sd_ble_evt_mailbox,
+ SD_BLE_EVT_MAILBOX_QUEUE_SIZE,
+ NRF_QUEUE_MODE_NO_OVERFLOW);
+#endif
+
+#if defined(ANT_STACK_SUPPORT_REQD)
+NRF_QUEUE_DEF(ser_ant_sd_handler_evt_data_t,
+ m_sd_ant_evt_mailbox,
+ SD_BLE_EVT_MAILBOX_QUEUE_SIZE,
+ NRF_QUEUE_MODE_NO_OVERFLOW);
+#endif
+
+NRF_QUEUE_DEF(uint32_t,
+ m_sd_soc_evt_mailbox,
+ SD_BLE_EVT_MAILBOX_QUEUE_SIZE,
+ NRF_QUEUE_MODE_NO_OVERFLOW);
+
+/**
+ * @brief Function to be replaced by user implementation if needed.
+ *
+ * Weak function - user can add different implementation of this function if application needs it.
+ */
+__WEAK void os_rsp_set_handler(void)
+{
+
+}
+
+static void connectivity_reset_low(void)
+{
+ //Signal a reset to the connectivity chip by setting the reset pin low.
+ ser_app_hal_nrf_reset_pin_clear();
+ ser_app_hal_delay(CONN_CHIP_RESET_TIME);
+
+}
+
+static void connectivity_reset_high(void)
+{
+
+ //Set the reset level to high again.
+ ser_app_hal_nrf_reset_pin_set();
+
+ //Wait for connectivity chip to be ready.
+ ser_app_hal_delay(CONN_CHIP_WAKEUP_TIME);
+}
+
+#if defined(BLE_STACK_SUPPORT_REQD)
+static void ser_softdevice_ble_evt_handler(uint8_t * p_data, uint16_t length)
+{
+ ser_sd_handler_evt_data_t item;
+ uint32_t err_code;
+ uint32_t len32 = sizeof (item.evt_data);
+
+ err_code = ble_event_dec(p_data, length, (ble_evt_t *)item.evt_data, &len32);
+ APP_ERROR_CHECK(err_code);
+
+ err_code = ser_sd_transport_rx_free(p_data);
+ APP_ERROR_CHECK(err_code);
+
+ err_code = nrf_queue_push(&m_sd_ble_evt_mailbox, &item);
+ APP_ERROR_CHECK(err_code);
+
+ ser_app_hal_nrf_evt_pending();
+}
+#endif
+
+#if defined(ANT_STACK_SUPPORT_REQD)
+static void ser_softdevice_ant_evt_handler(uint8_t * p_data, uint16_t length)
+{
+ ser_ant_sd_handler_evt_data_t item;
+ uint32_t err_code;
+ uint32_t len32 = sizeof (item.evt_data);
+
+ err_code = ant_event_dec(p_data, length, (ant_evt_t *)item.evt_data, &len32);
+ APP_ERROR_CHECK(err_code);
+
+ err_code = ser_sd_transport_rx_free(p_data);
+ APP_ERROR_CHECK(err_code);
+
+ err_code = nrf_queue_push(&m_sd_ant_evt_mailbox, &item);
+ APP_ERROR_CHECK(err_code);
+
+ ser_app_hal_nrf_evt_pending();
+}
+#endif
+
+void ser_softdevice_flash_operation_success_evt(bool success)
+{
+ uint32_t evt_type = success ? NRF_EVT_FLASH_OPERATION_SUCCESS :
+ NRF_EVT_FLASH_OPERATION_ERROR;
+
+ uint32_t err_code = nrf_queue_push(&m_sd_soc_evt_mailbox, &evt_type);
+ APP_ERROR_CHECK(err_code);
+
+ ser_app_hal_nrf_evt_pending();
+}
+
+/**
+ * @brief Function called while waiting for connectivity chip response. It handles incoming events.
+ */
+static void ser_sd_rsp_wait(void)
+{
+ do
+ {
+ (void)sd_app_evt_wait();
+
+ //intern_softdevice_events_execute();
+ }
+ while (ser_sd_transport_is_busy());
+}
+
+uint32_t sd_evt_get(uint32_t * p_evt_id)
+{
+ return nrf_queue_pop(&m_sd_soc_evt_mailbox, p_evt_id);
+}
+
+#if defined(BLE_STACK_SUPPORT_REQD)
+uint32_t sd_ble_evt_get(uint8_t * p_data, uint16_t * p_len)
+{
+ uint32_t err_code = nrf_queue_pop(&m_sd_ble_evt_mailbox, p_data);
+
+ if (err_code == NRF_SUCCESS) //if anything in the mailbox
+ {
+ if (((ble_evt_t *)p_data)->header.evt_len > *p_len)
+ {
+ err_code = NRF_ERROR_DATA_SIZE;
+ }
+ else
+ {
+ *p_len = ((ble_evt_t *)p_data)->header.evt_len;
+ }
+ }
+ else
+ {
+ err_code = NRF_ERROR_NOT_FOUND;
+ }
+
+ return err_code;
+}
+#endif
+
+#if defined(ANT_STACK_SUPPORT_REQD)
+uint32_t sd_ant_event_get(uint8_t* p_channel, uint8_t* p_event, uint8_t* p_ant_mesg)
+{
+ SER_ASSERT_NOT_NULL(p_channel);
+ SER_ASSERT_NOT_NULL(p_event);
+ SER_ASSERT_NOT_NULL(p_ant_mesg);
+
+ uint32_t err_code;
+
+ ser_ant_sd_handler_evt_data_t item;
+
+ err_code = nrf_queue_pop(&m_sd_ant_evt_mailbox, &item);
+
+ if (err_code == NRF_SUCCESS)
+ {
+ *p_event = ((ant_evt_t *)item.evt_data) -> event;
+ *p_channel = ((ant_evt_t *)item.evt_data) -> channel;
+ memcpy(p_ant_mesg, ((ant_evt_t *)item.evt_data)->message.aucMessage, MESG_BUFFER_SIZE);
+ } else {
+ err_code = NRF_ERROR_NOT_FOUND;
+ }
+
+ return err_code;
+}
+#endif
+
+#if defined(BLE_STACK_SUPPORT_REQD)
+uint32_t sd_ble_evt_mailbox_length_get(uint32_t * p_mailbox_length)
+{
+ *p_mailbox_length = nrf_queue_utilization_get(&m_sd_ble_evt_mailbox);
+ return NRF_SUCCESS;
+}
+#endif
+
+#if (defined(S332) || defined(S212))
+uint32_t sd_softdevice_enable(nrf_clock_lf_cfg_t const * p_clock_lf_cfg,
+ nrf_fault_handler_t fault_handler,
+ const char* p_license_key)
+#else
+uint32_t sd_softdevice_enable(nrf_clock_lf_cfg_t const * p_clock_lf_cfg,
+ nrf_fault_handler_t assertion_handler)
+#endif
+{
+ uint32_t err_code;
+
+ err_code = ser_app_hal_hw_init(ser_softdevice_flash_operation_success_evt);
+
+ if (err_code == NRF_SUCCESS)
+ {
+ connectivity_reset_low();
+
+ nrf_queue_reset(&m_sd_soc_evt_mailbox);
+ ser_sd_transport_evt_handler_t ble_evt_handler = NULL;
+ ser_sd_transport_evt_handler_t ant_evt_handler = NULL;
+
+#ifdef BLE_STACK_SUPPORT_REQD
+ ble_evt_handler = ser_softdevice_ble_evt_handler;
+ nrf_queue_reset(&m_sd_ble_evt_mailbox);
+#endif // BLE_STACK_SUPPORT_REQD
+
+#ifdef ANT_STACK_SUPPORT_REQD
+ ant_evt_handler = ser_softdevice_ant_evt_handler;
+ nrf_queue_reset(&m_sd_ant_evt_mailbox);
+#endif // ANT_STACK_SUPPORT_REQD
+ err_code = ser_sd_transport_open(ble_evt_handler,
+ ant_evt_handler,
+ ser_sd_rsp_wait,
+ os_rsp_set_handler,
+ NULL);
+
+ if (err_code == NRF_SUCCESS)
+ {
+ connectivity_reset_high();
+ }
+
+ ser_app_hal_nrf_evt_irq_priority_set();
+ }
+
+ return err_code;
+}
+
+
+uint32_t sd_softdevice_disable(void)
+{
+ return ser_sd_transport_close();
+}
+
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/application/transport/ser_softdevice_handler.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/application/transport/ser_softdevice_handler.h
new file mode 100644
index 0000000..a07bf51
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/application/transport/ser_softdevice_handler.h
@@ -0,0 +1,80 @@
+/**
+ * Copyright (c) 2014 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+/**
+ * @addtogroup ser_app Application side code
+ * @ingroup ble_sdk_lib_serialization
+ */
+
+/** @file
+ *
+ * @defgroup ser_softdevice_handler Serialization SoftDevice Handler
+ * @{
+ * @ingroup ser_app
+ *
+ * @brief Serialization SoftDevice Handler on application side.
+ *
+ */
+#ifndef SER_SOFTDEVICE_HANDLER_H_
+#define SER_SOFTDEVICE_HANDLER_H_
+
+#include <stdint.h>
+#include <stdbool.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+/**@brief Function for checking if there are any more events in the internal mailbox.
+ *
+ * @param[in] p_mailbox_length Pointer to mailbox length.
+ *
+ * @retval ::NRF_SUCCESS Length succesfully obtained.
+ * @retval ::NRF_ERROR_NULL Null pointer provided.
+ */
+uint32_t sd_ble_evt_mailbox_length_get(uint32_t * p_mailbox_length);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* SER_SOFTDEVICE_HANDLER_H_ */
+/** @} */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/common/ble_serialization.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/common/ble_serialization.c
new file mode 100644
index 0000000..de2b51f
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/common/ble_serialization.c
@@ -0,0 +1,549 @@
+/**
+ * Copyright (c) 2013 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#include "ble_serialization.h"
+#include "nrf_error.h"
+#include "app_util.h"
+#include <stddef.h>
+#include <string.h>
+
+uint32_t ser_ble_cmd_rsp_status_code_enc(uint8_t op_code,
+ uint32_t command_status,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len)
+{
+ SER_ASSERT_NOT_NULL(p_buf);
+ SER_ASSERT_NOT_NULL(p_buf_len);
+ uint32_t index = 0;
+
+ SER_ASSERT_LENGTH_LEQ(SER_CMD_RSP_HEADER_SIZE, *p_buf_len);
+
+ //Encode Op Code.
+ p_buf[index++] = op_code;
+
+ //Encode Status.
+ index += uint32_encode(command_status, &(p_buf[index]));
+ *p_buf_len = index;
+
+ return NRF_SUCCESS;
+}
+
+
+uint32_t ser_ble_cmd_rsp_result_code_dec(uint8_t const * const p_buf,
+ uint32_t * const p_pos,
+ uint32_t packet_len,
+ uint8_t op_code,
+ uint32_t * const p_result_code)
+{
+ SER_ASSERT_NOT_NULL(p_buf);
+ SER_ASSERT_NOT_NULL(p_pos);
+ SER_ASSERT_NOT_NULL(p_result_code);
+
+ if (packet_len < SER_CMD_RSP_HEADER_SIZE)
+ {
+ return NRF_ERROR_DATA_SIZE;
+ }
+
+ if (p_buf[(*p_pos)] != op_code)
+ {
+ return NRF_ERROR_INVALID_DATA;
+ }
+
+ *p_result_code = uint32_decode(&(p_buf[(*p_pos) + SER_CMD_RSP_STATUS_CODE_POS]));
+ *p_pos += SER_CMD_RSP_HEADER_SIZE;
+
+ return NRF_SUCCESS;
+}
+
+
+uint32_t ser_ble_cmd_rsp_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ uint8_t op_code,
+ uint32_t * const p_result_code)
+{
+ uint32_t index = 0;
+ uint32_t result_code = ser_ble_cmd_rsp_result_code_dec(p_buf, &index, packet_len, op_code,
+ p_result_code);
+
+ if (result_code != NRF_SUCCESS)
+ {
+ return result_code;
+ }
+
+ if (index != packet_len)
+ {
+ return NRF_ERROR_DATA_SIZE;
+ }
+
+ return NRF_SUCCESS;
+}
+
+uint32_t uint32_t_enc(void const * const p_field,
+ uint8_t * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index)
+{
+ SER_ASSERT_NOT_NULL(p_buf);
+ SER_ASSERT_NOT_NULL(p_field);
+ SER_ASSERT_NOT_NULL(p_index);
+
+ uint32_t * p_uint32 = (uint32_t *)p_field;
+
+ SER_ASSERT_LENGTH_LEQ(4, buf_len - *p_index);
+
+ *p_index += uint32_encode(*p_uint32, &p_buf[*p_index]);
+
+ return NRF_SUCCESS;
+}
+
+uint32_t uint32_t_dec(uint8_t const * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index,
+ void * p_field)
+{
+ SER_ASSERT_NOT_NULL(p_buf);
+ SER_ASSERT_NOT_NULL(p_index);
+ SER_ASSERT_NOT_NULL(p_field);
+
+ uint32_t * p_uint32 = (uint32_t *)p_field;
+
+ SER_ASSERT_LENGTH_LEQ(4, ((int32_t)buf_len - *p_index));
+
+ *p_uint32 = uint32_decode(&p_buf[*p_index]);
+ *p_index += 4;
+
+ return NRF_SUCCESS;
+}
+
+uint32_t uint16_t_enc(const void * const p_field,
+ uint8_t * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index)
+{
+ uint16_t * p_u16 = (uint16_t *)p_field;
+
+ SER_ASSERT_LENGTH_LEQ(2, buf_len - *p_index);
+
+ *p_index += uint16_encode(*p_u16, &p_buf[*p_index]);
+
+ return NRF_SUCCESS;
+}
+
+uint32_t uint16_t_dec(uint8_t const * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index,
+ void * p_field)
+{
+ uint16_t * p_u16 = (uint16_t *)p_field;
+
+ SER_ASSERT_LENGTH_LEQ(2, ((int32_t)buf_len - *p_index));
+
+ *p_u16 = uint16_decode(&p_buf[*p_index]);
+ *p_index += 2;
+
+ return NRF_SUCCESS;
+}
+
+void uint16_dec(uint8_t const * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const index,
+ uint16_t * const value)
+{
+ SER_ASSERT_VOID_RETURN(*index + 2 <= buf_len);
+ *value = uint16_decode(&p_buf[*index]);
+ *index += 2;
+}
+
+uint32_t uint8_t_enc(const void * const p_field,
+ uint8_t * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index)
+{
+ SER_ASSERT_LENGTH_LEQ(1, buf_len - *p_index);
+
+ uint8_t * p_u8 = (uint8_t *)p_field;
+ p_buf[*p_index] = *p_u8;
+ *p_index += 1;
+
+ return NRF_SUCCESS;
+}
+
+uint32_t uint8_t_dec(uint8_t const * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index,
+ void * p_field)
+{
+ uint8_t * p_u8 = (uint8_t *)p_field;
+
+ SER_ASSERT_LENGTH_LEQ(1, ((int32_t)buf_len - *p_index));
+ *p_u8 = p_buf[*p_index];
+ *p_index += 1;
+
+ return NRF_SUCCESS;
+}
+
+void uint8_dec(uint8_t const * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const index,
+ uint8_t * const value)
+{
+ SER_ASSERT_VOID_RETURN(*index + 1 <= buf_len);
+ *value = p_buf[*index];
+ *index += 1;
+}
+
+
+void int8_dec(uint8_t const * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const index,
+ int8_t * const value)
+{
+ SER_ASSERT_VOID_RETURN(*index + 1 <= buf_len);
+ *value = p_buf[*index];
+ *index += 1;
+}
+
+uint32_t len8data_enc(uint8_t const * const p_data,
+ uint8_t const dlen,
+ uint8_t * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index)
+{
+ uint32_t err_code = NRF_SUCCESS;
+
+ err_code = uint8_t_enc(&dlen, p_buf, buf_len, p_index);
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code);
+
+ err_code = buf_enc(p_data, dlen, p_buf, buf_len, p_index);
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code);
+
+ return err_code;
+}
+
+uint32_t len8data_dec(uint8_t const * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index,
+ uint8_t * * const pp_data,
+ uint8_t * const p_len)
+{
+ uint32_t err_code = NRF_SUCCESS;
+ uint16_t out_buf_len = *p_len;
+
+ err_code = uint8_t_dec(p_buf, buf_len, p_index, p_len);
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code);
+
+ err_code = buf_dec(p_buf, buf_len, p_index, pp_data, out_buf_len, *p_len);
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code);
+
+ return err_code;
+}
+
+uint32_t len16data_enc(uint8_t const * const p_data,
+ uint16_t const dlen,
+ uint8_t * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index)
+{
+ uint32_t err_code = NRF_SUCCESS;
+
+ err_code = uint16_t_enc(&dlen, p_buf, buf_len, p_index);
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code);
+
+ err_code = buf_enc(p_data, dlen, p_buf, buf_len, p_index);
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code);
+
+ return err_code;
+}
+
+uint32_t len16data_dec(uint8_t const * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index,
+ uint8_t * * const pp_data,
+ uint16_t * const p_dlen)
+{
+ uint32_t err_code = NRF_SUCCESS;
+ uint16_t out_buf_len = *p_dlen;
+
+ err_code = uint16_t_dec(p_buf, buf_len, p_index, p_dlen);
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code);
+
+ err_code = buf_dec(p_buf, buf_len, p_index, pp_data, out_buf_len, *p_dlen);
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code);
+
+ return err_code;
+}
+
+uint32_t count16_cond_data16_enc(uint16_t const * const p_data,
+ uint16_t const count,
+ uint8_t * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index)
+{
+ uint32_t i = 0;
+
+ SER_ASSERT_LENGTH_LEQ(3, ((int32_t)buf_len - *p_index));
+ *p_index += uint16_encode(count, &p_buf[*p_index]);
+
+ if (p_data)
+ {
+ SER_ASSERT_LENGTH_LEQ((int32_t)(2 * count + 1), ((int32_t)buf_len - (int32_t) * p_index));
+ p_buf[*p_index] = SER_FIELD_PRESENT;
+ *p_index += 1;
+
+ //memcpy may fail in case of Endianness difference between application and connectivity processor
+ for (i = 0; i < count; i++)
+ {
+ *p_index += uint16_encode(p_data[i], &p_buf[*p_index]);
+ }
+ }
+ else
+ {
+ SER_ASSERT_LENGTH_LEQ((1), ((int32_t)buf_len - *p_index));
+ p_buf[*p_index] = SER_FIELD_NOT_PRESENT;
+ *p_index += 1;
+ }
+
+ return NRF_SUCCESS;
+}
+
+uint32_t count16_cond_data16_dec(uint8_t const * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index,
+ uint16_t * * const pp_data,
+ uint16_t * const p_count)
+
+{
+ uint16_t count = 0;
+ uint8_t is_present = 0;
+ uint16_t i;
+
+ SER_ASSERT_NOT_NULL(p_count);
+ SER_ASSERT_NOT_NULL(pp_data);
+ SER_ASSERT_NOT_NULL(*pp_data);
+
+ SER_ASSERT_LENGTH_LEQ(3, ((int32_t)buf_len - (*p_index)));
+
+ uint16_dec(p_buf, buf_len, p_index, &count);
+
+ if (count > *p_count)
+ {
+ return NRF_ERROR_DATA_SIZE;
+ }
+
+ SER_ASSERT_LENGTH_LEQ(count, *p_count);
+
+ uint8_dec(p_buf, buf_len, p_index, &is_present);
+
+ if (!is_present)
+ {
+ *p_count = count;
+ *pp_data = NULL;
+ return NRF_SUCCESS;
+ }
+ else
+ {
+ for (i = 0; i < count; i++ )
+ {
+ uint16_dec(p_buf, buf_len, p_index, &((&(**pp_data))[i]) );
+ }
+ *p_count = i;
+ }
+ return NRF_SUCCESS;
+}
+
+
+
+uint32_t cond_len16_cond_data_dec(uint8_t const * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index,
+ uint8_t * * const pp_data,
+ uint16_t * * const pp_len)
+{
+ SER_ASSERT_NOT_NULL(pp_len);
+ SER_ASSERT_NOT_NULL(*pp_len);
+ SER_ASSERT_NOT_NULL(pp_data);
+ SER_ASSERT_NOT_NULL(*pp_data);
+
+ SER_ASSERT_LENGTH_LEQ(2, ((int32_t)buf_len - (*p_index)));
+ uint8_t is_present = 0;
+
+ uint8_dec(p_buf, buf_len, p_index, &is_present);
+
+ if (!is_present)
+ {
+ *pp_len = NULL; //if length field is not present
+ (*p_index)++; //then data can not be present
+ *pp_data = NULL;
+ return NRF_SUCCESS;
+ }
+ else
+ {
+ return len16data_dec(p_buf, buf_len, p_index, pp_data, *pp_len);
+ }
+}
+
+uint32_t op_status_enc(uint8_t op_code,
+ uint32_t return_code,
+ uint8_t * const p_buff,
+ uint32_t * const p_buff_len,
+ uint32_t * const p_index)
+{
+ SER_ASSERT_NOT_NULL(p_buff);
+ SER_ASSERT_NOT_NULL(p_buff_len);
+ SER_ASSERT_NOT_NULL(p_index);
+ SER_ASSERT_LENGTH_LEQ(SER_CMD_RSP_HEADER_SIZE, *p_buff_len - *p_index);
+
+ //Encode Op Code.
+ p_buff[(*p_index)++] = op_code;
+ //Encode Status.
+ *p_index += uint32_encode(return_code, &(p_buff[*p_index]));
+ //update size of used buffer
+ *p_buff_len = *p_index;
+
+ return NRF_SUCCESS;
+}
+
+uint32_t op_status_cond_uint16_enc(uint8_t op_code,
+ uint32_t return_code,
+ uint16_t value,
+ uint8_t * const p_buff,
+ uint32_t * const p_buff_len,
+ uint32_t * const p_index)
+{
+ uint32_t status_code;
+ uint32_t init_buff_len = *p_buff_len;
+
+ status_code = op_status_enc(op_code, return_code, p_buff, p_buff_len, p_index);
+ SER_ASSERT(status_code == NRF_SUCCESS, status_code);
+
+ if (return_code == NRF_SUCCESS) //Add 16bit value when return_code is a success
+ {
+ *p_buff_len = init_buff_len; //restore original value - it has been modified by op_status_enc
+ status_code = uint16_t_enc(&value, p_buff, *p_buff_len, p_index);
+ *p_buff_len = *p_index;
+ SER_ASSERT(status_code == NRF_SUCCESS, status_code);
+ }
+
+ return status_code;
+}
+
+uint32_t buf_enc(uint8_t const * const p_data,
+ uint16_t const dlen,
+ uint8_t * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index)
+{
+ uint32_t err_code = NRF_SUCCESS;
+ uint8_t is_present = (p_data == NULL) ? SER_FIELD_NOT_PRESENT : SER_FIELD_PRESENT;
+
+ err_code = uint8_t_enc(&is_present, p_buf, buf_len, p_index);
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code);
+
+ if (p_data)
+ {
+ SER_ASSERT_LENGTH_LEQ(dlen, ((int32_t)buf_len - *p_index));
+ memcpy(&p_buf[*p_index], p_data, dlen);
+ *p_index += dlen;
+ }
+
+ return err_code;
+}
+
+uint32_t buf_dec(uint8_t const * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index,
+ uint8_t * * const pp_data,
+ uint16_t data_len,
+ uint16_t dlen)
+{
+ uint8_t is_present = 0;
+
+ SER_ASSERT_LENGTH_LEQ(1, ((int32_t)buf_len - *p_index));
+ uint8_dec(p_buf, buf_len, p_index, &is_present);
+
+ if (is_present == SER_FIELD_PRESENT)
+ {
+ SER_ASSERT_NOT_NULL(pp_data);
+ SER_ASSERT_NOT_NULL(*pp_data);
+ SER_ASSERT_LENGTH_LEQ(dlen, data_len);
+ SER_ASSERT_LENGTH_LEQ(dlen, ((int32_t)buf_len - *p_index));
+ memcpy(*pp_data, &p_buf[*p_index], dlen);
+ *p_index += dlen;
+ }
+ else
+ {
+ if (pp_data)
+ {
+ *pp_data = NULL;
+ }
+ }
+ return NRF_SUCCESS;
+}
+
+uint32_t uint8_vector_enc(uint8_t const * const p_data,
+ uint16_t const dlen,
+ uint8_t * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index)
+{
+
+ SER_ASSERT_NOT_NULL(p_data);
+ SER_ASSERT_NOT_NULL(p_buf);
+ SER_ASSERT_NOT_NULL(p_index);
+ SER_ASSERT_LENGTH_LEQ(dlen, ((int32_t)buf_len - *p_index));
+ memcpy(&p_buf[*p_index], p_data, dlen);
+ *p_index += dlen;
+
+ return NRF_SUCCESS;
+}
+
+uint32_t uint8_vector_dec(uint8_t const * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index,
+ uint8_t * const p_data,
+ uint16_t dlen)
+{
+ SER_ASSERT_NOT_NULL(p_data);
+ SER_ASSERT_LENGTH_LEQ(dlen, ((int32_t)buf_len - *p_index));
+ memcpy(p_data, &p_buf[*p_index], dlen);
+ *p_index += dlen;
+
+ return NRF_SUCCESS;
+}
+
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/common/ble_serialization.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/common/ble_serialization.h
new file mode 100644
index 0000000..d66c95a
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/common/ble_serialization.h
@@ -0,0 +1,1097 @@
+/**
+ * Copyright (c) 2013 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#ifndef BLE_SERIALIZATION_H__
+#define BLE_SERIALIZATION_H__
+
+#include "nordic_common.h"
+#include "nrf_error.h"
+#include <stdint.h>
+#include <stddef.h>
+#include "cond_field_serialization.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**@brief Types of serialization packets. */
+typedef enum
+{
+ SER_PKT_TYPE_CMD = 0, /**< Command packet type. */
+ SER_PKT_TYPE_RESP, /**< Command Response packet type. */
+ SER_PKT_TYPE_EVT, /**< Event packet type. */
+ SER_PKT_TYPE_DTM_CMD, /**< DTM Command packet type. */
+ SER_PKT_TYPE_DTM_RESP, /**< DTM Response packet type. */
+ SER_PKT_TYPE_RESET_CMD, /**< System Reset Command packet type. */
+#if defined(ANT_STACK_SUPPORT_REQD)
+ SER_PKT_TYPE_ANT_CMD, /**< ANT Command packet type. */
+ SER_PKT_TYPE_ANT_RESP, /**< ANT Response packet type. */
+ SER_PKT_TYPE_ANT_EVT, /**< ANT Event packet type. */
+#endif
+ SER_PKT_TYPE_MAX /**< Upper bound. */
+} ser_pkt_type_t;
+
+#define LOW16(a) ((uint16_t)((a & 0x0000FFFF) >> 0))
+#define HIGH16(a) ((uint16_t)((a & 0xFFFF0000) >> 16))
+
+//lint -esym(516,__INTADDR__) Symbol '__INTADDR__()' has arg. type conflict
+//lint -esym(628,__INTADDR__) no argument information provided for function '__INTADDR__()'
+
+/** Size in bytes of the Error Code field in a Command Response packet. */
+#define SER_ERR_CODE_SIZE 4
+/** Size in bytes of the Packet Type field (@ref ser_pkt_type_t). */
+#define SER_PKT_TYPE_SIZE 1
+/** Size in bytes of the Operation Code field. */
+#define SER_OP_CODE_SIZE 1
+
+/** Position of the Packet Type field in a serialized packet buffer. */
+#define SER_PKT_TYPE_POS 0
+/** Position of the Operation Code field in a serialized packet buffer. */
+#define SER_PKT_OP_CODE_POS (SER_PKT_TYPE_SIZE)
+/** Position of the Data in a serialized packet buffer. */
+#define SER_PKT_DATA_POS (SER_PKT_TYPE_SIZE + SER_OP_CODE_SIZE)
+
+/** Position of the Operation Code field in a command buffer. */
+#define SER_CMD_OP_CODE_POS 0
+/** Position of the Data in a command buffer.*/
+#define SER_CMD_DATA_POS (SER_OP_CODE_SIZE)
+/** Size of the Command header. */
+#define SER_CMD_HEADER_SIZE (SER_OP_CODE_SIZE)
+/** Size of the Command Response header. */
+#define SER_CMD_RSP_HEADER_SIZE (SER_OP_CODE_SIZE + SER_ERR_CODE_SIZE)
+/** Position of the Command Response code. */
+#define SER_CMD_RSP_STATUS_CODE_POS (SER_OP_CODE_SIZE)
+
+/** Size of event ID field. */
+#define SER_EVT_ID_SIZE 2
+/** Position of event ID field. */
+#define SER_EVT_ID_POS 0
+/** Size of event header. */
+#define SER_EVT_HEADER_SIZE (SER_EVT_ID_SIZE)
+/** Size of event connection handler. */
+#define SER_EVT_CONN_HANDLE_SIZE 2
+
+#if defined(ANT_STACK_SUPPORT_REQD)
+/** Size of event ID field. */
+#define SER_ANT_EVT_ID_SIZE 2
+/** Position of event ID field. */
+#define SER_ANT_EVT_ID_POS 0
+/** Size of event header. */
+#define SER_ANT_EVT_HEADER_SIZE (SER_ANT_EVT_ID_SIZE)
+#endif
+
+/** Position of the Op Code in the DTM command buffer.*/
+#define SER_DTM_CMD_OP_CODE_POS 0
+/** Position of the data in the DTM command buffer.*/
+#define SER_DTM_CMD_DATA_POS 1
+
+/** Position of the Op Code in the DTM command response buffer.*/
+#define SER_DTM_RESP_OP_CODE_POS 1
+/** Position of the status field in the DTM command response buffer.*/
+#define SER_DTM_RESP_STATUS_POS 2
+
+/** Value to indicate that an optional field is encoded in the serialized packet, e.g. white list.*/
+#define SER_FIELD_PRESENT 0x01
+/** Value to indicate that an optional field is not encoded in the serialized packet. */
+#define SER_FIELD_NOT_PRESENT 0x00
+
+
+/** Enable SER_ASSERT<*> asserts */
+#define SER_ASSERTS_ENABLED 1
+
+/** Returns with error code if expr is not true. It is used for checking error which should be
+ * checked even when SER_ASSERTS_ENABLED is not set. */
+#define SER_ERROR_CHECK(expr, error_code) do { if (!(expr)) return (error_code); } while (0)
+
+
+#ifdef SER_ASSERTS_ENABLED
+/** Returns with error code if expr is not true. */
+#define SER_ASSERT(expr, error_code) SER_ERROR_CHECK(expr, error_code)
+/** Returns if expression is not true. */
+#define SER_ASSERT_VOID_RETURN(expr) do { if (!(expr)) return; } while (0)
+/** Returns with \ref NRF_ERROR_INVALID_LENGTH if len is not less or equal to maxlen. */
+#define SER_ASSERT_LENGTH_LEQ(len, maxlen) \
+ SER_ASSERT((len) <= (maxlen), NRF_ERROR_INVALID_LENGTH)
+/** Returns with \ref NRF_ERROR_INVALID_LENGTH if actual_len is not equal to expected_len. */
+#define SER_ASSERT_LENGTH_EQ(actual_len, expected_len) \
+ SER_ASSERT((actual_len) == (expected_len), NRF_ERROR_INVALID_LENGTH)
+/** Returns with \ref NRF_ERROR_NULL if pointer is null. */
+#define SER_ASSERT_NOT_NULL(ptr) SER_ASSERT((ptr) != NULL, NRF_ERROR_NULL)
+#else
+#define SER_ASSERT(expr, error_code)
+#define SER_ASSERT_VOID_RETURN(expr)
+#define SER_ASSERT_LENGTH_LEQ(len, maxlen) UNUSED_VARIABLE(maxlen)
+#define SER_ASSERT_LENGTH_EQ(actual_len, expected_len)
+#define SER_ASSERT_NOT_NULL(ptr)
+#endif
+
+#if defined(BLE_GATT_MTU_SIZE_DEFAULT) && !defined(GATT_MTU_SIZE_DEFAULT)
+#define GATT_MTU_SIZE_DEFAULT BLE_GATT_MTU_SIZE_DEFAULT
+#endif
+
+/** See Bluetooth 4.0 spec: 3.4.4.7. */
+#define BLE_GATTC_HANDLE_COUNT_LEN_MAX ((GATT_MTU_SIZE_DEFAULT - 1) / 2)
+
+/** Subtract 1 from X if X is greater than 0. */
+#define SUB1(X) (((X)>0) ? ((X)-1) : (X))
+
+static inline void static_force_impl_castable_p_void(void const * const p) {}
+/** Force the argument to be a double pointer. */
+#define STATIC_FORCE_PP(PP) static_force_impl_castable_p_void(*(PP))
+
+/** Field decoder for special structures containing variable length data. */
+typedef uint32_t (*field_ext_decoder_handler_t)(uint8_t const * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index,
+ uint32_t * const p_ext_length,
+ void * p_field);
+
+
+/** Push uint8_t field into the output packet. */
+#define SER_PUSH_uint8(P_VAR) do { \
+ err_code = uint8_t_enc((P_VAR), p_buf, buf_len, p_index); \
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code); \
+ } while (0)
+
+/** Push uint16_t field into the output packet. */
+#define SER_PUSH_uint16(P_VAR) do { \
+ err_code = uint16_t_enc((P_VAR), p_buf, buf_len, p_index); \
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code); \
+ } while (0)
+
+/** Push uint32_t field into the output packet. */
+#define SER_PUSH_uint32(P_VAR) do { \
+ err_code = uint32_t_enc((P_VAR), p_buf, buf_len, p_index); \
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code); \
+ } while (0)
+
+/** Push int8_t field into the output packet. */
+#define SER_PUSH_int8(P_VAR) SER_PUSH_uint8(P_VAR)
+
+/** Push uint16_t field into the output packet. */
+#define SER_PUSH_int16(P_VAR) SER_PUSH_uint16(P_VAR)
+
+/** Push uint32_t field into the output packet. */
+#define SER_PUSH_int32(P_VAR) SER_PUSH_uint32(P_VAR)
+
+/** Push a constant length array of bytes into the output packet. */
+#define SER_PUSH_uint8array(P_DATA, LEN) do { \
+ err_code = uint8_vector_enc((P_DATA), (LEN), p_buf, buf_len, p_index); \
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code); \
+ } while (0)
+
+/** Push a variable length (8-bit) array of bytes into the output packet. */
+#define SER_PUSH_len8data(P_DATA, LEN) do { \
+ err_code = len8data_enc((P_DATA), (LEN), p_buf, buf_len, p_index); \
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code); \
+ } while (0)
+
+/** Push a variable length (16-bit) array of bytes into the output packet. */
+#define SER_PUSH_len16data(P_DATA, LEN) do { \
+ err_code = len16data_enc((P_DATA), (LEN), p_buf, buf_len, p_index); \
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code); \
+ } while (0)
+
+/** Push a variable length (16-bit) array of 16-bit words into the output packet. */
+#define SER_PUSH_len16data16(P_DATA, LEN) do { \
+ err_code = count16_cond_data16_enc((P_DATA), (LEN), p_buf, buf_len, p_index); \
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code); \
+ } while (0)
+
+/** Push a buffer into the output packet. */
+#define SER_PUSH_buf(P_DATA, LEN) do { \
+ err_code = buf_enc((P_DATA), (LEN), p_buf, buf_len, p_index); \
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code); \
+ } while (0)
+
+/** Push a structure into the output packet. */
+#define SER_PUSH_FIELD(P_VAR, P_ENCODER) do { \
+ err_code = field_enc((P_VAR), p_buf, buf_len, p_index, (P_ENCODER)); \
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code); \
+ } while (0)
+
+/** Push an array of structures into the output packet. */
+#define SER_PUSH_FIELD_ARRAY(P_ARRAY, P_ENCODER, COUNT) do { \
+ for (uint32_t _idx = 0; _idx < (COUNT); ++_idx) \
+ { \
+ SER_PUSH_FIELD(&((P_ARRAY)[_idx]),P_ENCODER);\
+ } \
+ } while (0)
+
+/** Conditionally push a field if the specified pointer is not null. */
+#define SER_PUSH_COND(P_VAR, P_ENCODER) do { \
+ err_code = cond_field_enc((P_VAR), p_buf, buf_len, p_index, (P_ENCODER)); \
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code); \
+ } while (0)
+
+
+/** Pull a uint8_t field from the input packet. */
+#define SER_PULL_uint8(P_VAR) do { \
+ err_code = uint8_t_dec(p_buf, packet_len, p_index, (P_VAR)); \
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code); \
+ } while (0)
+
+/** Pull a uint16_t field from the input packet. */
+#define SER_PULL_uint16(P_VAR) do { \
+ err_code = uint16_t_dec(p_buf, packet_len, p_index, (P_VAR)); \
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code); \
+ } while (0)
+
+/** Pull a uint32_t field from the input packet. */
+#define SER_PULL_uint32(P_VAR) do { \
+ err_code = uint32_t_dec(p_buf, packet_len, p_index, (P_VAR)); \
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code); \
+ } while (0)
+
+/** Pull an int8_t field from the input packet. */
+#define SER_PULL_int8(P_VAR) SER_PULL_uint8(P_VAR)
+
+/** Pull an int16_t field from the input packet. */
+#define SER_PULL_int16(P_VAR) SER_PULL_uint16(P_VAR)
+
+/** Pull an int32_t field from the input packet. */
+#define SER_PULL_int32(P_VAR) SER_PULL_uint32(P_VAR)
+
+/** Pull a constant length byte array from the input packet. */
+#define SER_PULL_uint8array(P_DATA, LEN) do { \
+ err_code = uint8_vector_dec(p_buf, packet_len, p_index, (P_DATA), (LEN)); \
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code); \
+ } while (0)
+
+/** Pull a variable length (8-bit) byte array from the input packet. */
+#define SER_PULL_len8data(PP_DATA, LEN) do { \
+ STATIC_FORCE_PP(PP_DATA); \
+ err_code = len8data_dec(p_buf, packet_len, p_index, (PP_DATA), (LEN)); \
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code); \
+ } while (0)
+
+/** Pull a variable length (16-bit) byte array from the input packet. */
+#define SER_PULL_len16data(PP_DATA, P_LEN) do { \
+ STATIC_FORCE_PP(PP_DATA); \
+ err_code = len16data_dec(p_buf, packet_len, p_index, (PP_DATA), (P_LEN)); \
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code); \
+ } while (0)
+
+/** Pull a variable length (16-bit) word (16-bit) array from the input packet. */
+#define SER_PULL_len16data16(PP_DATA, P_LEN) do { \
+ STATIC_FORCE_PP(PP_DATA); \
+ err_code = count16_cond_data16_dec(p_buf, packet_len, p_index, (PP_DATA), (P_LEN)); \
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code); \
+ } while (0)
+
+/** Pull a buffer from the input packet. */
+#define SER_PULL_buf(PP_DATA, OUT_BUF_LEN, LEN) do { \
+ STATIC_FORCE_PP(PP_DATA); \
+ err_code = buf_dec(p_buf, packet_len, p_index, (PP_DATA), (OUT_BUF_LEN), (LEN)); \
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code); \
+ } while (0)
+
+/** Pull a structure from the input packet. */
+#define SER_PULL_FIELD(P_VAR, P_DECODER) do { \
+ err_code = field_dec(p_buf, packet_len, p_index, (P_VAR), (P_DECODER)); \
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code); \
+ } while (0)
+
+/** Pull an array of structures from the input packet. */
+#define SER_PULL_FIELD_ARRAY(P_ARRAY, P_DECODER, COUNT) do { \
+ for (uint32_t _idx = 0; _idx < (COUNT); ++_idx) \
+ { \
+ SER_PULL_FIELD(&((P_ARRAY)[_idx]),P_DECODER); \
+ } \
+ } while (0)
+
+/** Conditionally pull a structure from the input packet. */
+#define SER_PULL_COND(PP_VAR, P_DECODER) do { \
+ STATIC_FORCE_PP(PP_VAR); \
+ err_code = cond_field_dec(p_buf, packet_len, p_index, (void * *)(PP_VAR), (P_DECODER)); \
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code); \
+ } while (0)
+
+
+/** Start the encoding of a structure and prepare local variables for the usage of SER_PUSH_ macros. */
+#define SER_STRUCT_ENC_BEGIN(STRUCT_TYPE) \
+ SER_ASSERT_NOT_NULL(p_buf); \
+ SER_ASSERT_NOT_NULL(p_index); \
+ SER_ASSERT_NOT_NULL(p_void_struct); \
+ STRUCT_TYPE * p_struct = (STRUCT_TYPE *) p_void_struct; \
+ uint32_t err_code = NRF_SUCCESS
+
+/** End the encoding of a structure. */
+#define SER_STRUCT_ENC_END return err_code
+
+/** Start the decoding of a structure and prepare local variables for the usage of SER_PULL_ macros. */
+#define SER_STRUCT_DEC_BEGIN(STRUCT_TYPE) \
+ SER_ASSERT_NOT_NULL(p_buf); \
+ SER_ASSERT_NOT_NULL(p_index); \
+ SER_ASSERT_NOT_NULL(p_void_struct); \
+ STRUCT_TYPE * p_struct = (STRUCT_TYPE *) p_void_struct; \
+ uint32_t err_code = NRF_SUCCESS; \
+ uint32_t packet_len = buf_len
+
+/** End the encoding of a structure. */
+#define SER_STRUCT_DEC_END return err_code
+
+
+/** Start the encoding of command request and prepare local variables for the usage of SER_PUSH_ macros. */
+#define SER_REQ_ENC_BEGIN(OPCODE) \
+ SER_ASSERT_NOT_NULL(p_buf); \
+ SER_ASSERT_NOT_NULL(p_buf_len); \
+ \
+ uint32_t index = 0; \
+ uint32_t * const p_index = &index; \
+ uint32_t err_code = NRF_SUCCESS; \
+ uint32_t buf_len = *p_buf_len; \
+ \
+ uint8_t opcode = (OPCODE); \
+ SER_PUSH_uint8(&opcode)
+
+/** End the encoding of command request. */
+#define SER_REQ_ENC_END \
+ *p_buf_len = index; \
+ return NRF_SUCCESS \
+
+/** Start the decoding of command response that does not contain any data except the result code. */
+#define SER_RSP_DEC_RESULT_ONLY(OPCODE) \
+ return ser_ble_cmd_rsp_dec(p_buf, packet_len, (OPCODE), p_result_code)
+
+/** Start the decoding of command response and prepare local variables for the usage of SER_PULL_ macros. */
+#define SER_RSP_DEC_BEGIN(OPCODE) \
+ SER_ASSERT_NOT_NULL(p_buf); \
+ SER_ASSERT_NOT_NULL(p_result_code); \
+ uint32_t err_code = NRF_SUCCESS; \
+ uint32_t index = 0; \
+ uint32_t * const p_index = &index; \
+ /* Decode the result code and exit if decoding has failed or \
+ the decoded result is not NRF_SUCCESS. */ \
+ err_code = ser_ble_cmd_rsp_result_code_dec(p_buf, &index, packet_len, (OPCODE), p_result_code); \
+ \
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code); \
+ if (*p_result_code != NRF_SUCCESS) \
+ { \
+ SER_ASSERT_LENGTH_EQ(index, packet_len); \
+ return NRF_SUCCESS; \
+ }
+
+/** End the decoding of command response. */
+#define SER_RSP_DEC_END \
+ /* Require all data to be pulled. */ \
+ SER_ASSERT_LENGTH_EQ(index, packet_len); \
+ return err_code
+
+
+/** Start the decoding of command request and prepare local variables for the usage of SER_PULL_ macros. */
+#define SER_REQ_DEC_BEGIN(OPCODE) \
+ SER_ASSERT_NOT_NULL(p_buf); \
+ SER_ASSERT(packet_len>0, NRF_ERROR_INVALID_PARAM); \
+ uint32_t index = 0; \
+ uint32_t * const p_index = &index; \
+ uint32_t err_code = NRF_SUCCESS; \
+ SER_ASSERT(p_buf[index] == (OPCODE), NRF_ERROR_INVALID_PARAM); \
+ (void)err_code; \
+ (void)p_index; \
+ ++index
+
+/** End the decoding of command request. */
+#define SER_REQ_DEC_END \
+ SER_ASSERT_LENGTH_EQ(index, packet_len); \
+ return NRF_SUCCESS
+
+/** Start the encoding of command response and prepare local variables for the usage of SER_PUSH_ macros. */
+#define SER_RSP_ENC_BEGIN(OPCODE) \
+ SER_ASSERT_NOT_NULL(p_buf); \
+ SER_ASSERT_NOT_NULL(p_buf_len); \
+ uint32_t index = 0; \
+ uint32_t * const p_index = &index; \
+ uint32_t err_code = NRF_SUCCESS; \
+ uint32_t buf_len = *p_buf_len; \
+ /* Push the opcode + result and exit if result \
+ is not NRF_SUCCESS. */ \
+ uint8_t opcode = (OPCODE); \
+ SER_PUSH_uint8(&opcode); \
+ SER_PUSH_uint32(&return_code); \
+ \
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code); \
+ if (return_code != NRF_SUCCESS) \
+ { \
+ SER_RSP_ENC_END; \
+ }
+
+/** Start the encoding of command response that contains the result code only. */
+#define SER_RSP_ENC_RESULT_ONLY(OPCODE) \
+ return ser_ble_cmd_rsp_status_code_enc((OPCODE), return_code, p_buf, p_buf_len)
+
+/** End the encoding of command response. */
+#define SER_RSP_ENC_END \
+ *p_buf_len = index; \
+ return NRF_SUCCESS
+
+
+/** Start the encoding of an event and prepare local variables for the usage of SER_PUSH_ macros. */
+#define SER_EVT_ENC_BEGIN(EVT_HEADER) \
+ SER_ASSERT_NOT_NULL(p_event); \
+ SER_ASSERT_NOT_NULL(p_buf); \
+ SER_ASSERT_NOT_NULL(p_buf_len); \
+ SER_ASSERT(p_event->header.evt_id == (EVT_HEADER), NRF_ERROR_INVALID_PARAM); \
+ uint32_t index = 0; \
+ uint32_t * p_index = &index; \
+ uint32_t buf_len = *p_buf_len; \
+ uint32_t err_code = NRF_SUCCESS; \
+ uint16_t evt_header = (EVT_HEADER); \
+ /* Push event header. */ \
+ SER_PUSH_uint16(&evt_header)
+
+/** End the encoding of an event. */
+#define SER_EVT_ENC_END \
+ *p_buf_len = index; \
+ return err_code
+
+
+/** Start the decoding of an event that has an event-specific data structure
+ and prepare local variables for the usage of SER_PULL_ macros. */
+#define SER_EVT_DEC_BEGIN(EVT_CODE, EVT_GROUP, EVT_NAME) \
+ uint32_t err_code = NRF_SUCCESS; \
+ uint32_t index = 0; \
+ uint32_t * p_index = &index; \
+ SER_ASSERT_NOT_NULL(p_buf); \
+ SER_ASSERT_NOT_NULL(p_event_len); \
+ /* Calculate the base event structure length */ \
+ /* and make sure that there is enough free space */ \
+ /* in the output buffer. */ \
+ uint32_t evt_struct_len = \
+ offsetof(ble_evt_t, evt.EVT_GROUP##_evt.params) \
+ - offsetof(ble_evt_t, evt) \
+ + sizeof(ble_##EVT_GROUP##_evt_##EVT_NAME##_t); \
+ SER_ASSERT_LENGTH_LEQ(evt_struct_len, *p_event_len); \
+ *p_event_len -= evt_struct_len; \
+ /* Some structures contains variable length arrays */ \
+ /* and the overall size may be greater. */ \
+ uint32_t evt_extended_len = 0; \
+ (void) evt_extended_len; \
+ p_event->header.evt_id = EVT_CODE
+
+/** Start the decoding of an event that has no event-specific data structure.
+ and prepare local variables for the usage of SER_PULL_ macros. */
+#define SER_EVT_DEC_BEGIN_NO_STRUCT(EVT_CODE, EVT_GROUP) \
+ uint32_t err_code = NRF_SUCCESS; \
+ uint32_t index = 0; \
+ uint32_t * p_index = &index; \
+ SER_ASSERT_NOT_NULL(p_buf); \
+ SER_ASSERT_NOT_NULL(p_event_len); \
+ /* Calculate the base event structure length */ \
+ /* and make sure that there is enough free space */ \
+ /* in the output buffer. */ \
+ uint32_t evt_struct_len = \
+ offsetof(ble_evt_t, evt.EVT_GROUP##_evt.params) \
+ - offsetof(ble_evt_t, evt) ; \
+ SER_ASSERT_LENGTH_LEQ(evt_struct_len, *p_event_len); \
+ *p_event_len -= evt_struct_len; \
+ /* Some structures contain variable length arrays */ \
+ /* and the overall size may be greater. */ \
+ uint32_t evt_extended_len = 0; \
+ (void) evt_extended_len; \
+ p_event->header.evt_id = EVT_CODE
+
+/** End the decoding of an event. */
+#define SER_EVT_DEC_END \
+ SER_ASSERT_LENGTH_EQ(index, packet_len); \
+ /*p_event_len = index; */ \
+ /*p_event->header.evt_len = index; */ \
+ *p_event_len = evt_struct_len + evt_extended_len; \
+ return NRF_SUCCESS
+
+/** Push an event-specific special field that contains variable length fields and get the extended data size. */
+#define SER_PULL_FIELD_EXTENDED(P_VAR, P_DECODER) \
+ do \
+ { \
+ uint32_t field_ext_len = *p_event_len; \
+ err_code = field_ext_dec(p_buf, packet_len, p_index, &field_ext_len, (P_VAR), (P_DECODER)); \
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code); \
+ *p_event_len -= field_ext_len; \
+ evt_extended_len += field_ext_len; \
+ } while (0) \
+
+
+/** Generic command response status code encoder. */
+uint32_t ser_ble_cmd_rsp_status_code_enc(uint8_t op_code,
+ uint32_t command_status,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len);
+
+/** Generic command response result code decoder. */
+uint32_t ser_ble_cmd_rsp_result_code_dec(uint8_t const * const p_buf,
+ uint32_t * const p_pos,
+ uint32_t packet_len,
+ uint8_t op_code,
+ uint32_t * const p_result_code);
+
+/** Generic command response decoder. */
+uint32_t ser_ble_cmd_rsp_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ uint8_t op_code,
+ uint32_t * const p_result_code);
+
+
+
+/**@brief Function for safe field encoding field.
+ *
+ * @param[in] p_field Pointer to the input struct. Must not be a null.
+ * @param[in] p_buf Pointer to the beginning of the output buffer.
+ * @param[in] buf_len Size of the buffer.
+ * @param[in,out] p_index \c in: Index to start of uint8 value in buffer.
+ * \c out: Index in the buffer to the first byte after the encoded data.
+ * @param[in] fp_field_encoder Pointer to the function that implements fields encoding.
+ *
+ * @return NRF_SUCCESS Field encoded successfully.
+ * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length.
+ * @retval NRF_ERROR_NULL p_field or fp_field_encoder is NULL.
+ */
+static inline uint32_t field_enc(void const * const p_field,
+ uint8_t * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index,
+ field_encoder_handler_t fp_field_encoder)
+{
+ SER_ASSERT_NOT_NULL(fp_field_encoder);
+ SER_ASSERT_NOT_NULL(p_field);
+
+ return fp_field_encoder(p_field, p_buf, buf_len, p_index);
+}
+
+/**@brief Function for safe field decoding.
+ *
+ * Function checks if conditional field is present in the input buffer and if it is set, it calls
+ * the provided parser function that attempts to parse the buffer content to the known field.
+ *
+ * @param[in] p_buf Pointer to the beginning of the input buffer.
+ * @param[in] buf_len Size of the buffer.
+ * @param[in,out] p_index \c in: Index to the start of uint8 value in buffer.
+ * \c out: Index in the buffer to the first byte after the decoded data.
+ * @param[in] p_field Pointer to the output location.
+ * @param[in] fp_field_decoder Pointer to the function that implements field decoding.
+ *
+ * @return NRF_SUCCESS Field decoded successfully.
+ * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length.
+ * @retval NRF_ERROR_NULL p_field or fp_field_decoder is NULL.
+ */
+static inline uint32_t field_dec(uint8_t const * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index,
+ void * const p_field,
+ field_decoder_handler_t fp_field_decoder)
+{
+ SER_ASSERT_NOT_NULL(fp_field_decoder);
+ SER_ASSERT_NOT_NULL(p_field);
+
+ return fp_field_decoder(p_buf, buf_len, p_index, p_field);
+}
+
+/**@brief Function for safe decoding of an event-specific field that contains extended data.
+ *
+ * Some event structures contain a variable length array (extended data),
+ * that may be written next to the event structure.
+ *
+ * @param[in] p_buf Pointer to the beginning of the input buffer.
+ * @param[in] buf_len Size of the buffer.
+ * @param[in,out] p_index \c in: Index to the start of uint8 value in the buffer.
+ * \c out: Index in the buffer to the first byte after the decoded data.
+ * @param[in,out] p_ext_length \c in: Maximum size of extended data.
+ * \c out: Extended data length in bytes.
+ * @param[in] p_field Pointer to output location.
+ * @param[in] fp_field_decoder Pointer to the function that implements field decoding.
+ *
+ * @return NRF_SUCCESS Field decoded successfully.
+ * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length.
+ * @retval NRF_ERROR_NULL p_field or fp_field_decoder is NULL.
+ */
+static inline uint32_t field_ext_dec(uint8_t const * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index,
+ uint32_t * const p_ext_length,
+ void * const p_field,
+ field_ext_decoder_handler_t fp_field_decoder)
+{
+ SER_ASSERT_NOT_NULL(fp_field_decoder);
+ SER_ASSERT_NOT_NULL(p_field);
+
+ return fp_field_decoder(p_buf, buf_len, p_index, p_ext_length, p_field);
+}
+
+/**@brief Function for safe encoding an uint16 value.
+ *
+ * Safe decoding of a uint16 value. Range checks will be done if @ref SER_ASSERTS_ENABLED is set.
+ *
+ * @param[in] p_field A uint16 value to be encoded.
+ * @param[out] p_buf Buffer containing the value.
+ * @param[in] buf_len Size of the buffer.
+ * @param[in,out] p_index \c in: Index to the start of the uint16 value in the buffer.
+ * \c out: Index in the buffer to the first byte after the decoded value.
+ *
+ * @return NRF_SUCCESS Fields decoded successfully.
+ * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length.
+ */
+uint32_t uint16_t_enc(const void * const p_field,
+ uint8_t * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index);
+
+/**@brief Function for safe decoding of a uint16 value.
+ *
+ * Safe decoding of a uint16 value. Range checks will be done if @ref SER_ASSERTS_ENABLED is set.
+ *
+ * @param[in] p_buf Buffer containing the value.
+ * @param[in] buf_len Size of the buffer.
+ * @param[in,out] p_index \c in: Index to the start of the uint16 value in the buffer.
+ * \c out: Index in the buffer to the first byte after the decoded value.
+ * @param[out] p_field Pointer to the location where the uint16 value will be decoded.
+ */
+uint32_t uint16_t_dec(uint8_t const * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index,
+ void * p_field);
+
+/**@brief Function for safe decoding of a uint16 value.
+ *
+ * Safe decoding of a uint16 value. Range checks will be done if @ref SER_ASSERTS_ENABLED is set.
+ *
+ * @param[in] p_buf Buffer containing the value.
+ * @param[in] buf_len Size of the buffer.
+ * @param[in,out] index \c in: Index to the start of the uint16 value in buffer.
+ * \c out: Index in the buffer to the first byte after the decoded value.
+ * @param[out] value Decoded uint16 value.
+ */
+void uint16_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ uint32_t * const index,
+ uint16_t * const value);
+
+/**@brief Function for safe encoding of a uint18 value.
+ *
+ * Safe decoding of a uint8 value. Range checks will be done if @ref SER_ASSERTS_ENABLED is set.
+ *
+ * @param[in] p_buf Buffer containing the value.
+ * @param[in] buf_len Size of the buffer.
+ * @param[in,out] p_index \c in: Index to the start of the uint8 value in the buffer.
+ * \c out: Index in the buffer to the first byte after the decoded value.
+ * @param[out] p_field Pointer to uint8 value to be encoded.
+ *
+ * @return NRF_SUCCESS Fields decoded successfully.
+ * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length.
+ */
+uint32_t uint8_t_enc(const void * const p_field,
+ uint8_t * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index);
+
+/**@brief Function for safe decoding of a uint8 value.
+ *
+ * Safe decoding of a uint8 value. Range checks will be done if @ref SER_ASSERTS_ENABLED is set.
+ *
+ * @param[in] p_buf Buffer containing the value.
+ * @param[in] buf_len Size of the buffer.
+ * @param[in,out] p_index \c in: Index to the start of the uint8 value in buffer.
+ * \c out: Index in the buffer to the first byte after the decoded value.
+ * @param[out] p_field Pointer to the location for decoded uint8 value.
+ *
+ * @return NRF_SUCCESS Fields decoded successfully.
+ * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length.
+ */
+uint32_t uint8_t_dec(uint8_t const * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index,
+ void * p_field);
+
+/**@brief Function for safe decoding of a uint8 value.
+ *
+ * Safe decoding of a uint8 value. Range checks will be done if @ref SER_ASSERTS_ENABLED is set.
+ *
+ * @param[in] p_buf Buffer containing the value.
+ * @param[in] buf_len Size of the buffer.
+ * @param[in,out] index \c in: Index to the start of the uint8 value in the buffer.
+ * \c out: Index in the buffer to the first byte after the decoded value.
+ * @param[out] value Decoded uint8 value.
+ */
+void uint8_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ uint32_t * const index,
+ uint8_t * const value);
+
+/**@brief Function for safe decoding of a uint18 value.
+ *
+ * Safe decoding of a uint8 value. Range checks will be done if @ref SER_ASSERTS_ENABLED is set.
+ *
+ * @param[in] p_buf Buffer containing the value.
+ * @param[in] buf_len Size of the buffer.
+ * @param[in,out] index \c in: Index to the start of the uint8 value in the buffer.
+ * \c out: Index in the buffer to the first byte after the decoded value.
+ * @param[out] value Decoded uint8 value.
+ */
+void int8_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ uint32_t * const index,
+ int8_t * const value);
+
+/**@brief Function for safe encoding of a variable length field encoded as length(8bit) + data.
+ *
+ * Safe encoding of a variable length field. Range checks will be done if @ref SER_ASSERTS_ENABLED is set.
+ *
+ * @param[out] p_data Pointer to data to encode.
+ * @param[in] dlen Length of data to encode (0-255).
+ * @param[out] p_buf Buffer containing the value.
+ * @param[in] buf_len Size of the buffer.
+ * @param[in,out] p_index \c in: Index to the start of the uint8 value in the buffer.
+ * \c out: Index in the buffer to the first byte after the decoded value.
+ *
+ * @return NRF_SUCCESS Fields decoded successfully.
+ * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length.
+ */
+uint32_t len8data_enc(uint8_t const * const p_data,
+ uint8_t const dlen,
+ uint8_t * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index);
+
+/**@brief Function for safe decoding of a variable length field encoded as length(8bit) + data.
+ *
+ * Safe decoding of a variable length field. Range checks will be done if @ref SER_ASSERTS_ENABLED is set.
+ *
+ * @param[in] p_buf Buffer containing the value.
+ * @param[in] buf_len Size of the buffer.
+ * @param[in,out] p_index \c in: Index to the start of the uint8 value in the buffer.
+ * \c out: Index in the buffer to the first byte after the decoded value.
+ * @param[out] pp_data Pointer to decoded data (p_data is set to NULL in
+ * case data is not present in the buffer).
+ * @param[out] p_len Decoded length (0-255).
+ *
+ * @return NRF_SUCCESS Fields decoded successfully.
+ * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length.
+ */
+uint32_t len8data_dec(uint8_t const * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index,
+ uint8_t * * const pp_data,
+ uint8_t * const p_len);
+
+/**@brief Function for safe encoding of a variable length field encoded as length(16 bit) + data.
+ *
+ * Safe encoding of a variable length field. Range checks will be done if @ref SER_ASSERTS_ENABLED is set.
+ * It is possible that provided p_data is NULL. In that case, length is encoded and it is followed by
+ * SER_FIELD_NOT_PRESENT flag. Otherwise, the SER_FIELD_PRESENT flag precedes the data.
+ *
+ * @param[in] p_data Data to encode.
+ * @param[in] dlen Input data length (16 bit).
+ * @param[in] p_buf Pointer to the beginning of the output buffer.
+ * @param[in] buf_len Size of the buffer.
+ * @param[in,out] p_index \c in: Index to the start of the uint8 value in the buffer.
+ * \c out: Index in the buffer to the first byte after the encoded data.
+ *
+ * @return NRF_SUCCESS Fields decoded successfully.
+ * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length.
+ */
+uint32_t len16data_enc(uint8_t const * const p_data,
+ uint16_t const dlen,
+ uint8_t * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index);
+
+/**@brief Function for safe decoding of a variable length field encoded as length(16 bit) + data.
+ *
+ * Safe decoding of a variable length field. Range checks will be done if @ref SER_ASSERTS_ENABLED is set.
+ * Encoded data consists of a length field, a presence flag, and conditional data (present only if the presence flag
+ * is set). The p_data pointer cannot be NULL if the presence flag is set.
+ *
+ * @param[in] p_buf Pointer to the beginning of the input buffer.
+ * @param[in] buf_len Size of the buffer.
+ * @param[in,out] p_index \c in: Index to the start of the uint8 value in the buffer.
+ * \c out: Index in the buffer to the first byte after the decoded data.
+ * @param[in] pp_data Pointer to decoded data.
+ * @param[in] p_dlen Data length (16 bit).
+ *
+ * @return NRF_SUCCESS Fields decoded successfully.
+ * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length.
+ */
+uint32_t len16data_dec(uint8_t const * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index,
+ uint8_t * * const pp_data,
+ uint16_t * const p_dlen);
+
+
+/**@brief Function for safe encoding of a uint16 table with a given element count.
+ *
+ * Safe encoding of a variable length field. Range checks will be done if @ref SER_ASSERTS_ENABLED is set.
+ * It is possible that the provided p_data is NULL. In that case, length is encoded and it is followed by a
+ * SER_FIELD_NOT_PRESENT flag. Otherwise, the SER_FIELD_PRESENT flag precedes the data.
+ *
+ * @param[in] p_data Data table to encode.
+ * @param[in] count Table element count.
+ * @param[in] p_buf Pointer to the beginning of the output buffer.
+ * @param[in] buf_len Size of the buffer.
+ * @param[in,out] p_index \c in: Index to the start of the uint8 value in the buffer.
+ * \c out: Index in the buffer to the first byte after the encoded data.
+ *
+ * @return NRF_SUCCESS Fields decoded successfully.
+ * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length.
+ */
+
+uint32_t count16_cond_data16_enc(uint16_t const * const p_data,
+ uint16_t const count,
+ uint8_t * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index);
+
+/**@brief Function for safe decoding of a uint16 table with a given element count.
+ *
+ * Safe encoding of a variable length field. Range checks will be done if @ref SER_ASSERTS_ENABLED is set.
+ * It is possible that the provided p_data is NULL. In that case, length is encoded and it is followed by a
+ * SER_FIELD_NOT_PRESENT flag. Otherwise, the SER_FIELD_PRESENT flag precedes the data.
+ *
+ * @param[in] p_buf Pointer to the beginning of the output buffer.
+ * @param[in] buf_len Size of the buffer.
+ * @param[in,out] p_index \c in: Index to the start of the uint8 value in the buffer.
+ * \c out: Index in the buffer to the first byte after the encoded data.
+ * @param[in] pp_data Pointer to the table to encode.
+ * @param[in,out] p_count Pointer to table element count - initialised with max count.
+ *
+ * @return NRF_SUCCESS Fields decoded successfully.
+ * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length.
+ * @retval NRF_ERROR_DATA_SIZE Decoding failure. Initial count is smaller than actual.
+ */
+
+uint32_t count16_cond_data16_dec(uint8_t const * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index,
+ uint16_t * * const pp_data,
+ uint16_t * const p_count);
+
+
+/**@brief Function for safe decoding of a variable length field encoded as length(16 bit) + data.
+ *
+ * Safe decoding of a variable length field. Range checks will be done if @ref SER_ASSERTS_ENABLED is set.
+ * Encoded data consists of a presence flag, an optional length field, a second presence flag, and optional data.
+ *
+ *
+ * @param[in] p_buf Pointer to the beginning of the input buffer.
+ * @param[in] buf_len Size of the buffer.
+ * @param[in,out] p_index \c in: Index to the start of the uint8 value in the buffer.
+ * \c out: Index in the buffer to the first byte after the decoded data.
+ * @param[out] pp_data Pointer to decoded data.
+ * @param[out] pp_len Data length (16 bit).
+ *
+ * @return NRF_SUCCESS Fields decoded successfully.
+ * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length.
+ */
+
+uint32_t cond_len16_cond_data_dec(uint8_t const * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index,
+ uint8_t * * const pp_data,
+ uint16_t * * const pp_len);
+
+/**@brief Command response encoder - replacement of ser_ble_cmd_rsp_status_code_enc
+ * with layout aligned to the rest of encoder functions.
+ *
+ * @param[in] op_code Operation code - see BLE_GAP_SVCS.
+ * @param[in] return_code nRF error code.
+ * @param[in] p_buff Pointer to the start of pointer to decoded data.
+ * @param[in,out] p_buff_len \c in: Size of the buffer.
+ * \c out: Used bytes in the buffer.
+ * @param[in,out] p_buff_len \c in: Initial offset in the buffer.
+ * \c out: Final offset in the buffer.
+ *
+ * @return NRF_SUCCESS Fields decoded successfully.
+ * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length.
+ * @retval NRF_ERROR_NULL Invalid pointer.
+ */
+uint32_t op_status_enc(uint8_t op_code,
+ uint32_t return_code,
+ uint8_t * const p_buff,
+ uint32_t * const p_buff_len,
+ uint32_t * const p_index);
+
+/**@brief Command response encoder with a conditional 16-bit field.
+ *
+ * @param[in] op_code Operation code - see BLE_GAP_SVCS.
+ * @param[in] return_code nRF error code.
+ * @param[in] value Optional 16-bit field encoded for return code == NRF_SUCCESS.
+ * @param[in] p_buff Pointer to the start of pointer to decoded data.
+ * @param[in,out] p_buff_len \c in: Size of the buffer.
+ * \c out: Used bytes in the buffer.
+ * @param[in,out] p_buff_len \c in: Initial offset in the buffer.
+ * \c out: Final offset in the buffer.
+ *
+ * @return NRF_SUCCESS Fields decoded successfully.
+ * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length.
+ * @retval NRF_ERROR_NULL Invalid pointer.
+ */
+
+uint32_t op_status_cond_uint16_enc(uint8_t op_code,
+ uint32_t return_code,
+ uint16_t value,
+ uint8_t * const p_buff,
+ uint32_t * const p_buff_len,
+ uint32_t * const p_index);
+
+/**@brief Function for safe encoding of a buffer of known size.
+ *
+ * Safe encoding of a buffer. Encoder assumes that the size is known to the decoder and it is not
+ * encoded here. Range checks will be done if @ref SER_ASSERTS_ENABLED is set.
+ *
+ * @param[in] p_data Data to encode.
+ * @param[in] dlen Input data length (16 bit).
+ * @param[in] p_buf Pointer to the beginning of the output buffer.
+ * @param[in] buf_len Size of the buffer.
+ * @param[in,out] p_index \c in: Index to the start of the uint8 value in the buffer.
+ * \c out: Index in the buffer to the first byte after the encoded data.
+ *
+ * @return NRF_SUCCESS Fields decoded successfully.
+ * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length.
+ */
+uint32_t buf_enc(uint8_t const * const p_data,
+ uint16_t const dlen,
+ uint8_t * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index);
+
+/**@brief Function for safe decoding of a buffer of known size.
+ *
+ * Safe decoding of a buffer of known size. Range checks will be done if @ref SER_ASSERTS_ENABLED is set.
+ * Encoded data consists of a presence flag and conditional data (present only if the presence flag
+ * is set). The p_data pointer cannot be NULL only if the presence flag is set. Length is provided
+ * as input to the function.
+ *
+ * @param[in] p_buf Pointer to the beginning of the input buffer.
+ * @param[in] buf_len Size of the buffer.
+ * @param[in,out] p_index \c in: Index to the start of the uint8 value in the buffer.
+ * \c out: Index in the buffer to the first byte after the decoded data.
+ * @param[in] pp_data Pointer to decoded data.
+ * @param[in] data_len Length of the buffer for decoded data (16 bit).
+ * @param[in] dlen Length of the data to decode (16 bit).
+ *
+ * @return NRF_SUCCESS Fields decoded successfully.
+ * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length.
+ */
+uint32_t buf_dec(uint8_t const * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index,
+ uint8_t * * const pp_data,
+ uint16_t data_len,
+ uint16_t dlen);
+
+/**@brief Function for safe encoding of a uint32 value.
+ *
+ * Safe decoding of a uint32 value. Range checks will be done if @ref SER_ASSERTS_ENABLED is set.
+ *
+ * @param[in] p_field A uint32 value to be encoded.
+ * @param[out] p_buf Buffer containing the value.
+ * @param[in] buf_len Size of the buffer.
+ * @param[in,out] p_index \c in: Index to the start of the uint32 value in the buffer.
+ * \c out: Index in the buffer to the first byte after the decoded value.
+ *
+ * @return NRF_SUCCESS Fields decoded successfully.
+ * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length.
+ */
+uint32_t uint32_t_enc(void const * const p_field,
+ uint8_t * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index);
+
+/**@brief Function for safe decoding of a uint32 value.
+ *
+ * Safe decoding of a uint32 value. Range checks will be done if @ref SER_ASSERTS_ENABLED is set.
+ *
+ * @param[in] p_buf Buffer containing the value.
+ * @param[in] buf_len Size of the buffer.
+ * @param[in,out] p_index \c in: Index to the start of the uint32 value in the buffer.
+ * \c out: Index in the buffer to the first byte after the decoded value.
+ * @param[out] value Decoded uint32 value.
+ */
+uint32_t uint32_t_dec(uint8_t const * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index,
+ void * p_field);
+
+/**@brief Function for safe encoding of a uint8 vector.
+ *
+ * Range checks will be done if @ref SER_ASSERTS_ENABLED is set.
+ * *
+ * @param[in] p_data Data to encode.
+ * @param[in] dlen Input data length (16 bit).
+ * @param[in] p_buf Pointer to the beginning of the output buffer.
+ * @param[in] buf_len Size of the buffer.
+ * @param[in,out] p_index \c in: Index to the start of the uint8 value in the buffer.
+ * \c out: Index in the buffer to the first byte after the encoded data.
+ *
+ * @return NRF_SUCCESS Fields decoded successfully.
+ * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length.
+ */
+uint32_t uint8_vector_enc(uint8_t const * const p_data,
+ uint16_t const dlen,
+ uint8_t * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index);
+
+/**@brief Function for safe decoding a uint8 vector.
+ *
+ * Safe decoding of a buffer of known size. Range checks will be done if @ref SER_ASSERTS_ENABLED is set.
+ * Vector length is provided as input to the function.
+ *
+ * @param[in] p_buf Pointer to the beginning of the input buffer.
+ * @param[in] buf_len Size of the buffer.
+ * @param[in,out] p_index \c in: Index to the start of the uint8 value in the buffer.
+ * \c out: Index in the buffer to the first byte after the decoded data.
+ * @param[in] p_data Pointer to decoded data.
+ * @param[in] dlen Length of data to decode (16 bit).
+ *
+ * @return NRF_SUCCESS Fields decoded successfully.
+ * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length.
+ */
+uint32_t uint8_vector_dec(uint8_t const * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index,
+ uint8_t * const p_data,
+ uint16_t dlen);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
+
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/common/cond_field_serialization.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/common/cond_field_serialization.c
new file mode 100644
index 0000000..049dc27
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/common/cond_field_serialization.c
@@ -0,0 +1,101 @@
+/**
+ * Copyright (c) 2014 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#include "nrf_error.h"
+#include "cond_field_serialization.h"
+#include "ble_serialization.h"
+#include <stddef.h>
+
+uint32_t cond_field_enc(void const * const p_field,
+ uint8_t * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index,
+ field_encoder_handler_t fp_field_encoder)
+{
+ uint32_t err_code = NRF_SUCCESS;
+
+ SER_ASSERT_LENGTH_LEQ(*p_index + 1, buf_len);
+ p_buf[*p_index] = (p_field == NULL) ? SER_FIELD_NOT_PRESENT : SER_FIELD_PRESENT;
+ *p_index += 1;
+
+ if (p_field && (fp_field_encoder != NULL))
+ {
+ err_code = fp_field_encoder(p_field, p_buf, buf_len, p_index);
+ }
+
+ return err_code;
+}
+
+
+uint32_t cond_field_dec(uint8_t const * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index,
+ void * * const pp_field,
+ field_decoder_handler_t fp_field_decoder)
+{
+ uint32_t err_code = NRF_SUCCESS;
+ uint8_t is_present;
+
+ SER_ASSERT_LENGTH_LEQ(1, buf_len - *p_index);
+ uint8_dec(p_buf, buf_len, p_index, &is_present);
+
+ if (is_present == SER_FIELD_PRESENT)
+ {
+ SER_ASSERT_NOT_NULL(pp_field);
+ SER_ASSERT_NOT_NULL(*pp_field);
+
+ if (fp_field_decoder != NULL)
+ {
+ err_code = fp_field_decoder(p_buf, buf_len, p_index, *pp_field);
+ }
+ }
+ else if (is_present == SER_FIELD_NOT_PRESENT)
+ {
+ if (pp_field != NULL)
+ {
+ *pp_field = NULL;
+ }
+ }
+ else
+ {
+ err_code = NRF_ERROR_INVALID_DATA;
+ }
+
+ return err_code;
+}
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/common/cond_field_serialization.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/common/cond_field_serialization.h
new file mode 100644
index 0000000..b3103b1
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/common/cond_field_serialization.h
@@ -0,0 +1,105 @@
+/**
+ * Copyright (c) 2014 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#ifndef COND_FIELD_SERIALIZATION_H__
+#define COND_FIELD_SERIALIZATION_H__
+
+#include <stdint.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef uint32_t (*field_encoder_handler_t)(void const * const p_field,
+ uint8_t * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index);
+
+typedef uint32_t (*field_decoder_handler_t)(uint8_t const * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index,
+ void * p_field);
+
+/**@brief Function for safe encoding of a conditional field.
+ *
+ * Function sets a presence flag and checks if conditional field is provided. If the field is not NULL,
+ * it calls the provided parser function which attempts to encode the field content to the buffer stream.
+ *
+ * @param[in] p_field Pointer to the input struct.
+ * @param[in] p_buf Pointer to the beginning of the output buffer.
+ * @param[in] buf_len Size of the buffer.
+ * @param[in,out] p_index \c in: Index to the start of the uint8 value in the buffer.
+ * \c out: Index in the buffer to the first byte after the encoded data.
+ * @param[in] fp_field_encoder Pointer to the function which implements fields encoding.
+ *
+ * @return NRF_SUCCESS Fields encoded successfully.
+ * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length.
+ */
+uint32_t cond_field_enc(void const * const p_field,
+ uint8_t * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index,
+ field_encoder_handler_t fp_field_encoder);
+
+/**@brief Function for safe decoding of a conditional field.
+ *
+ * Function checks if conditional field is present in the input buffer. If it is set, it calls
+ * the provided parser function which attempts to parse the buffer content to the known field.
+ *
+ * @param[in] p_buf Pointer to the beginning of the input buffer.
+ * @param[in] buf_len Size of the buffer.
+ * @param[in,out] p_index \c in: Index to the start of the uint8 value in the buffer.
+ * \c out: Index in the buffer to the first byte after the decoded data.
+ * @param[in] pp_field Pointer to output location.
+ * @param[in] fp_field_decoder Pointer to the function which implements field decoding.
+ *
+ * @return NRF_SUCCESS Fields decoded successfully.
+ * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length.
+ */
+uint32_t cond_field_dec(uint8_t const * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index,
+ void * * const pp_field,
+ field_decoder_handler_t fp_field_decoder);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // COND_FIELD_SERIALIZATION_H__
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/common/ser_config.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/common/ser_config.h
new file mode 100644
index 0000000..a432d2e
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/common/ser_config.h
@@ -0,0 +1,121 @@
+/**
+ * Copyright (c) 2014 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#ifndef SER_CONFIG_H__
+#define SER_CONFIG_H__
+
+#include <stdint.h>
+
+#include "nrf.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/***********************************************************************************************//**
+ * General parameters configuration.
+ **************************************************************************************************/
+
+/** Value used as error code on SoftDevice stack dump. Can be used to identify stack location on
+ * stack unwind.*/
+#define SER_SD_ERROR_CODE (0xDEADBEEFUL)
+
+/** Value used as error code indicating warning - unusual situation but not critical so system
+ * should NOT be reset. */
+#define SER_WARNING_CODE (0xBADDCAFEUL)
+
+/***********************************************************************************************//**
+ * HAL Transport layer configuration.
+ **************************************************************************************************/
+
+/** Max packets size in serialization HAL Transport layer (packets before adding PHY header i.e.
+ * packet length). */
+#define SER_HAL_TRANSPORT_APP_TO_CONN_MAX_PKT_SIZE (512UL)
+#define SER_HAL_TRANSPORT_CONN_TO_APP_MAX_PKT_SIZE (512UL)
+
+#define SER_HAL_TRANSPORT_MAX_PKT_SIZE ((SER_HAL_TRANSPORT_APP_TO_CONN_MAX_PKT_SIZE) >= \
+ (SER_HAL_TRANSPORT_CONN_TO_APP_MAX_PKT_SIZE) \
+ ? \
+ (SER_HAL_TRANSPORT_APP_TO_CONN_MAX_PKT_SIZE) : \
+ (SER_HAL_TRANSPORT_CONN_TO_APP_MAX_PKT_SIZE))
+#ifdef SER_CONNECTIVITY
+ #define SER_HAL_TRANSPORT_TX_MAX_PKT_SIZE SER_HAL_TRANSPORT_CONN_TO_APP_MAX_PKT_SIZE
+ #define SER_HAL_TRANSPORT_RX_MAX_PKT_SIZE SER_HAL_TRANSPORT_APP_TO_CONN_MAX_PKT_SIZE
+
+#else /* APPLICATION SIDE */
+ #define SER_HAL_TRANSPORT_TX_MAX_PKT_SIZE SER_HAL_TRANSPORT_APP_TO_CONN_MAX_PKT_SIZE
+ #define SER_HAL_TRANSPORT_RX_MAX_PKT_SIZE SER_HAL_TRANSPORT_CONN_TO_APP_MAX_PKT_SIZE
+#endif /* SER_CONNECTIVITY */
+
+
+/***********************************************************************************************//**
+ * SER_PHY layer configuration.
+ **************************************************************************************************/
+
+#define SER_PHY_HEADER_SIZE 2
+
+#define SER_PHY_HCI_SLIP_TX_BUF_SIZE 30
+
+#define SER_PHY_SPI_FREQUENCY NRF_DRV_SPI_FREQ_1M
+
+/** Max transfer unit for SPI MASTER and SPI SLAVE. */
+#define SER_PHY_SPI_MTU_SIZE 255
+
+/** UART transmission parameters */
+#define SER_PHY_UART_FLOW_CTRL NRF_UART_HWFC_ENABLED
+#define SER_PHY_UART_PARITY NRF_UART_PARITY_INCLUDED
+#define SER_PHY_UART_BAUDRATE_VAL 1000000
+
+#define SER_PHY_UART_BAUDRATE CONCAT_2(NRF_UART_BAUDRATE_,SER_PHY_UART_BAUDRATE_VAL)
+
+/** Configuration timeouts of connectivity MCU. */
+#define CONN_CHIP_RESET_TIME 50 /**< Time to keep the reset line to the connectivity chip low (in milliseconds). */
+#define CONN_CHIP_WAKEUP_TIME 500 /**< Time for the connectivity chip to reset and become ready to receive serialized commands (in milliseconds). */
+
+#define SER_MAX_CONNECTIONS 8
+
+#ifndef SER_MAX_ADV_DATA
+#define SER_MAX_ADV_DATA 256
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* SER_CONFIG_H__ */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/common/ser_dbg_sd_str.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/common/ser_dbg_sd_str.c
new file mode 100644
index 0000000..5d4bc89
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/common/ser_dbg_sd_str.c
@@ -0,0 +1,320 @@
+/**
+ * Copyright (c) 2016 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#include "ser_dbg_sd_str.h"
+#include "nrf_soc.h"
+#include "nrf_log.h"
+#include <string.h>
+#include "sdk_common.h"
+
+#ifdef BLE_STACK_SUPPORT_REQD
+#include "ble_ranges.h"
+#endif
+
+#ifdef ANT_STACK_SUPPORT_REQD
+#include "ant_interface.h"
+#include "ant_parameters.h"
+#endif
+
+#if NRF_MODULE_ENABLED(NRF_LOG) && defined(BLE_STACK_SUPPORT_REQD)
+static const char * sd_events[] = {
+ "BLE_EVT_TX_COMPLETE", /*0x01*/
+ "BLE_EVT_USER_MEM_REQUEST", /*0x02*/
+ "BLE_EVT_USER_MEM_RELEASE", /*0x03*/
+ "BLE_EVT_DATA_LENGTH_CHANGED", /*0x04*/
+ "SD_EVT_UNKNOWN", /*0x05*/
+ "SD_EVT_UNKNOWN", /*0x06*/
+ "SD_EVT_UNKNOWN", /*0x07*/
+ "SD_EVT_UNKNOWN", /*0x08*/
+ "SD_EVT_UNKNOWN", /*0x09*/
+ "SD_EVT_UNKNOWN", /*0x0a*/
+ "SD_EVT_UNKNOWN", /*0x0b*/
+ "SD_EVT_UNKNOWN", /*0x0c*/
+ "SD_EVT_UNKNOWN", /*0x0d*/
+ "SD_EVT_UNKNOWN", /*0x0e*/
+ "SD_EVT_UNKNOWN", /*0x0f*/
+ "BLE_GAP_EVT_CONNECTED", /*0x10*/
+ "BLE_GAP_EVT_DISCONNECTED", /*0x11*/
+ "BLE_GAP_EVT_CONN_PARAM_UPDATE", /*0x12*/
+ "BLE_GAP_EVT_SEC_PARAMS_REQUEST", /*0x13*/
+ "BLE_GAP_EVT_SEC_INFO_REQUEST", /*0x14*/
+ "BLE_GAP_EVT_PASSKEY_DISPLAY", /*0x15*/
+ "BLE_GAP_EVT_KEY_PRESxSED", /*0x16*/
+ "BLE_GAP_EVT_AUTH_KEY_REQUEST", /*0x17*/
+ "BLE_GAP_EVT_LESC_DHKEY_REQUEST", /*0x18*/
+ "BLE_GAP_EVT_AUTH_STATUS", /*0x19*/
+ "BLE_GAP_EVT_CONN_SEC_UPDATE", /*0x1a*/
+ "BLE_GAP_EVT_TIMEOUT", /*0x1b*/
+ "BLE_GAP_EVT_RSSI_CHANGED", /*0x1c*/
+ "BLE_GAP_EVT_ADV_REPORT", /*0x1d*/
+ "BLE_GAP_EVT_SEC_REQUEST", /*0x1e*/
+ "BLE_GAP_EVT_CONN_PARAM_UPDATE_REQUEST", /*0x1f*/
+ "BLE_GAP_EVT_SCAN_REQ_REPORT", /*0x20*/
+ "SD_EVT_UNKNOWN", /*0x21*/
+ "SD_EVT_UNKNOWN", /*0x22*/
+ "SD_EVT_UNKNOWN", /*0x23*/
+ "SD_EVT_UNKNOWN", /*0x24*/
+ "SD_EVT_UNKNOWN", /*0x25*/
+ "SD_EVT_UNKNOWN", /*0x26*/
+ "SD_EVT_UNKNOWN", /*0x27*/
+ "SD_EVT_UNKNOWN", /*0x28*/
+ "SD_EVT_UNKNOWN", /*0x29*/
+ "SD_EVT_UNKNOWN", /*0x2a*/
+ "SD_EVT_UNKNOWN", /*0x2b*/
+ "SD_EVT_UNKNOWN", /*0x2c*/
+ "SD_EVT_UNKNOWN", /*0x2d*/
+ "SD_EVT_UNKNOWN", /*0x2e*/
+ "SD_EVT_UNKNOWN", /*0x2f*/
+ "BLE_GATTC_EVT_PRIM_SRVC_DISC_RSP", /*0x30*/
+ "BLE_GATTC_EVT_REL_DISC_RSP", /*0x31*/
+ "BLE_GATTC_EVT_CHAR_DISC_RSP", /*0x32*/
+ "BLE_GATTC_EVT_DESC_DISC_RSP", /*0x33*/
+ "BLE_GATTC_EVT_ATTR_INFO_DISC_RSP", /*0x34*/
+ "BLE_GATTC_EVT_CHAR_VAL_BY_UUID_READ_RSP", /*0x35*/
+ "BLE_GATTC_EVT_READ_RSP", /*0x36*/
+ "BLE_GATTC_EVT_CHAR_VALS_READ_RSP", /*0x37*/
+ "BLE_GATTC_EVT_WRITE_RSP", /*0x38*/
+ "BLE_GATTC_EVT_HVX", /*0x39*/
+ "BLE_GATTC_EVT_EXCHANGE_MTU_RSP", /*0x3a*/
+ "BLE_GATTC_EVT_TIMEOUT", /*0x3b*/
+ "SD_EVT_UNKNOWN", /*0x3c*/
+ "SD_EVT_UNKNOWN", /*0x3d*/
+ "SD_EVT_UNKNOWN", /*0x3e*/
+ "SD_EVT_UNKNOWN", /*0x3f*/
+ "SD_EVT_UNKNOWN", /*0x40*/
+ "SD_EVT_UNKNOWN", /*0x41*/
+ "SD_EVT_UNKNOWN", /*0x42*/
+ "SD_EVT_UNKNOWN", /*0x43*/
+ "SD_EVT_UNKNOWN", /*0x44*/
+ "SD_EVT_UNKNOWN", /*0x45*/
+ "SD_EVT_UNKNOWN", /*0x46*/
+ "SD_EVT_UNKNOWN", /*0x47*/
+ "SD_EVT_UNKNOWN", /*0x48*/
+ "SD_EVT_UNKNOWN", /*0x49*/
+ "SD_EVT_UNKNOWN", /*0x4a*/
+ "SD_EVT_UNKNOWN", /*0x4b*/
+ "SD_EVT_UNKNOWN", /*0x4c*/
+ "SD_EVT_UNKNOWN", /*0x4d*/
+ "SD_EVT_UNKNOWN", /*0x4e*/
+ "SD_EVT_UNKNOWN", /*0x4f*/
+ "BLE_GATTS_EVT_WRITE", /*0x50*/
+ "BLE_GATTS_EVT_RW_AUTHORIZE_REQUEST", /*0x51*/
+ "BLE_GATTS_EVT_SYS_ATTR_MISSING", /*0x52*/
+ "BLE_GATTS_EVT_HVC", /*0x53*/
+ "BLE_GATTS_EVT_SC_CONFIRM", /*0x54*/
+ "BLE_GATTS_EVT_EXCHANGE_MTU_REQUEST", /*0x55*/
+ "BLE_GATTS_EVT_TIMEOUT", /*0x56*/
+};
+
+static const char * sd_functions[] = {
+ /* 0x60 offset */
+ "SD_BLE_ENABLE", /*0x60*/
+ "SD_BLE_EVT_GET", /*0x61*/
+ "SD_BLE_UUID_VS_ADD", /*0x62*/
+ "SD_BLE_UUID_DECODE", /*0x63*/
+ "SD_BLE_UUID_ENCODE", /*0x64*/
+ "SD_BLE_VERSION_GET", /*0x65*/
+ "SD_BLE_USER_MEM_REPLY", /*0x66*/
+ "SD_BLE_OPT_SET", /*0x67*/
+ "SD_BLE_OPT_GET", /*0x68*/
+ "SD_BLE_CFG_SET", /*0x69*/
+ "SD_UNKNOWN", /*0x6A*/
+ "SD_UNKNOWN", /*0x6B*/
+ "SD_BLE_GAP_ADDR_SET" , /*0x6C*/
+ "SD_BLE_GAP_ADDR_GET" , /*0x6D*/
+ "SD_BLE_GAP_WHITELIST_SET" , /*0x6E*/
+ "SD_BLE_GAP_DEVICE_IDENTITIES_SET" , /*0x6F*/
+ "SD_BLE_GAP_PRIVACY_SET" , /*0x70*/
+ "SD_BLE_GAP_PRIVACY_GET" , /*0x71*/
+ "SD_BLE_GAP_ADV_SET_CONFIGURE" , /*0x72*/
+ "SD_BLE_GAP_ADV_START" , /*0x73*/
+ "SD_BLE_GAP_ADV_STOP" , /*0x74*/
+ "SD_BLE_GAP_CONN_PARAM_UPDATE" , /*0x75*/
+ "SD_BLE_GAP_DISCONNECT" , /*0x76*/
+ "SD_BLE_GAP_TX_POWER_SET" , /*0x77*/
+ "SD_BLE_GAP_APPEARANCE_SET" , /*0x78*/
+ "SD_BLE_GAP_APPEARANCE_GET" , /*0x79*/
+ "SD_BLE_GAP_PPCP_SET" , /*0x7a*/
+ "SD_BLE_GAP_PPCP_GET" , /*0x7b*/
+ "SD_BLE_GAP_DEVICE_NAME_SET" , /*0x7c*/
+ "SD_BLE_GAP_DEVICE_NAME_GET" , /*0x7d*/
+ "SD_BLE_GAP_AUTHENTICATE" , /*0x7e*/
+ "SD_BLE_GAP_SEC_PARAMS_REPLY" , /*0x7f*/
+ "SD_BLE_GAP_AUTH_KEY_REPLY" , /*0x80*/
+ "SD_BLE_GAP_LESC_DHKEY_REPLY" , /*0x81*/
+ "SD_BLE_GAP_KEYPRESS_NOTIFY" , /*0x82*/
+ "SD_BLE_GAP_LESC_OOB_DATA_GET" , /*0x83*/
+ "SD_BLE_GAP_LESC_OOB_DATA_SET" , /*0x84*/
+ "SD_BLE_GAP_ENCRYPT" , /*0x85*/
+ "SD_BLE_GAP_SEC_INFO_REPLY" , /*0x86*/
+ "SD_BLE_GAP_CONN_SEC_GET" , /*0x87*/
+ "SD_BLE_GAP_RSSI_START" , /*0x88*/
+ "SD_BLE_GAP_RSSI_STOP" , /*0x89*/
+ "SD_BLE_GAP_SCAN_START" , /*0x8a*/
+ "SD_BLE_GAP_SCAN_STOP" , /*0x8b*/
+ "SD_BLE_GAP_CONNECT" , /*0x8c*/
+ "SD_BLE_GAP_CONNECT_CANCEL " , /*0x8d*/
+ "SD_BLE_GAP_RSSI_GET" , /*0x8e*/
+ "SD_BLE_GAP_PHY_UPDATE" , /*0x8f*/
+ "SD_BLE_GAP_DATA_LENGTH_UPDATE" , /*0x90*/
+ "SD_BLE_GAP_QOS_CHANNEL_SURVEY_START", /*0x91*/
+ "SD_BLE_GAP_QOS_CHANNEL_SURVEY_STOP" , /*0x92*/
+ "SD_UNKNOWN", /*0x93*/
+ "SD_UNKNOWN", /*0x94*/
+ "SD_UNKNOWN", /*0x95*/
+ "SD_UNKNOWN", /*0x96*/
+ "SD_UNKNOWN", /*0x97*/
+ "SD_UNKNOWN", /*0x98*/
+ "SD_UNKNOWN", /*0x99*/
+ "SD_UNKNOWN", /*0x9A*/
+ "SD_BLE_GATTC_PRIMARY_SERVICES_DISCOVER", /*0x9B*/
+ "SD_BLE_GATTC_RELATIONSHIPS_DISCOVER", /*0x9C*/
+ "SD_BLE_GATTC_CHARACTERISTICS_DISCOVER", /*0x9D*/
+ "SD_BLE_GATTC_DESCRIPTORS_DISCOVER", /*0x9E*/
+ "SD_BLE_GATTC_ATTR_INFO_DISCOVER", /*0x9F*/
+ "SD_BLE_GATTC_CHAR_VALUE_BY_UUID_READ", /*0xA0*/
+ "SD_BLE_GATTC_READ", /*0xA1*/
+ "SD_BLE_GATTC_CHAR_VALUES_READ", /*0xA2*/
+ "SD_BLE_GATTC_WRITE", /*0xA3*/
+ "SD_BLE_GATTC_HV_CONFIRM", /*0xA4*/
+ "SD_BLE_GATTC_EXCHANGE_MTU_REQUEST", /*0xA5*/
+ "SD_UNKNOWN", /*0xA6*/
+ "SD_UNKNOWN", /*0xA7*/
+ "SD_BLE_GATTS_SERVICE_ADD", /*0xA8*/
+ "SD_BLE_GATTS_INCLUDE_ADD", /*0xA9*/
+ "SD_BLE_GATTS_CHARACTERISTIC_ADD", /*0xAA*/
+ "SD_BLE_GATTS_DESCRIPTOR_ADD", /*0xAB*/
+ "SD_BLE_GATTS_VALUE_SET", /*0xAC*/
+ "SD_BLE_GATTS_VALUE_GET", /*0xAD*/
+ "SD_BLE_GATTS_HVX", /*0xAE*/
+ "SD_BLE_GATTS_SERVICE_CHANGED", /*0xAF*/
+ "SD_BLE_GATTS_RW_AUTHORIZE_REPLY", /*0xB0*/
+ "SD_BLE_GATTS_SYS_ATTR_SET", /*0xB1*/
+ "SD_BLE_GATTS_SYS_ATTR_GET", /*0xB2*/
+ "SD_BLE_GATTS_INITIAL_USER_HANDLE_GET", /*0xB3*/
+ "SD_BLE_GATTS_ATTR_GET", /*0xB4*/
+ "SD_BLE_GATTS_EXCHANGE_MTU_REPLY", /*0xB5*/
+};
+#endif // NRF_MODULE_ENABLED(NRF_LOG) && defined(BLE_STACK_SUPPORT_REQD)
+
+#ifdef ANT_STACK_SUPPORT_REQD
+const char * string[] =
+{
+ "ANT SVC",
+ "ANT_EVT",
+};
+#endif // ANT_STACK_SUPPORT_REQD
+
+const char * ser_dbg_sd_call_str_get(uint8_t opcode)
+{
+#if NRF_MODULE_ENABLED(NRF_LOG)
+ const char * p_str = "SD_CALL_UNKNOWN";
+#ifdef BLE_STACK_SUPPORT_REQD
+ if (opcode >= BLE_SVC_BASE && opcode <= BLE_GATTS_SVC_LAST)
+ {
+ uint32_t idx = opcode-BLE_SVC_BASE;
+ if (idx < ARRAY_SIZE(sd_functions) )
+ {
+ p_str = sd_functions[idx];
+ }
+ }
+#endif // BLE_STACK_SUPPORT_REQD
+
+#ifdef ANT_STACK_SUPPORT_REQD
+ // Check if opcode is within the range of the ANT Stack API SVC numbers
+#ifdef BLE_STACK_SUPPORT_REQD
+ else if (opcode >= STK_SVC_BASE_2)
+#else
+ if (opcode >= STK_SVC_BASE_2)
+#endif // BLE_STACK_SUPPORT_REQD
+ {
+ p_str = string[0];
+ }
+#endif // ANT_STACK_SUPPORT_REQD
+ else
+ {
+ switch (opcode)
+ {
+ case SD_ECB_BLOCK_ENCRYPT:
+ p_str = "SD_ECB_BLOCK_ENCRYPT";
+ break;
+ case SD_TEMP_GET:
+ p_str = "SD_TEMP_GET";
+ break;
+ default:
+ break;
+ }
+ }
+ return p_str;
+#else
+ return NULL;
+#endif
+}
+
+const char * ser_dbg_sd_evt_str_get(uint16_t opcode)
+{
+#if NRF_MODULE_ENABLED(NRF_LOG)
+ const char * p_str = "SD_EVT_UNKNOWN";
+#ifdef BLE_STACK_SUPPORT_REQD
+ if (opcode >= BLE_EVT_BASE && opcode <= BLE_GATTS_EVT_LAST)
+ {
+ uint32_t idx = opcode - BLE_EVT_BASE;
+ if (idx < ARRAY_SIZE(sd_events))
+ {
+ p_str = sd_events[idx];
+ }
+ }
+#endif // BLE_STACK_SUPPORT_REQD
+
+#ifdef ANT_STACK_SUPPORT_REQD
+ // Check if opcode is within the range of the ANT Stack API SVC numbers
+#ifdef BLE_STACK_SUPPORT_REQD
+ else if (opcode <= EVENT_BLOCKED)
+#else
+ if (opcode <= EVENT_BLOCKED)
+#endif // BLE_STACK_SUPPORT_REQD
+ {
+ p_str = string[1];
+ }
+#endif
+ return p_str;
+#else
+ return NULL;
+#endif // NRF_MODULE_ENABLED(NRF_LOG)
+}
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/common/ser_dbg_sd_str.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/common/ser_dbg_sd_str.h
new file mode 100644
index 0000000..3e386e7
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/common/ser_dbg_sd_str.h
@@ -0,0 +1,45 @@
+/**
+ * Copyright (c) 2016 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#ifndef SER_DBG_SD_STR_H
+#define SER_DBG_SD_STR_H
+#include <stdint.h>
+const char * ser_dbg_sd_call_str_get(uint8_t opcode);
+const char * ser_dbg_sd_evt_str_get(uint16_t opcode);
+#endif //SER_DBG_SD_STR_H
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/common/struct_ser/ant/ant_struct_serialization.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/common/struct_ser/ant/ant_struct_serialization.c
new file mode 100644
index 0000000..c0129b3
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/common/struct_ser/ant/ant_struct_serialization.c
@@ -0,0 +1,159 @@
+/**
+ * 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+
+#include "ant_interface.h"
+#include "ant_struct_serialization.h"
+#include "nrf_sdh_ant.h"
+#include "ble_serialization.h"
+#include "app_util.h"
+#include "cond_field_serialization.h"
+#include <string.h>
+
+
+uint32_t ANT_ENABLE_enc(void const * const p_void_enable_params,
+ uint8_t * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index)
+{
+ SER_ASSERT_NOT_NULL(p_buf);
+ SER_ASSERT_NOT_NULL(p_index);
+ SER_ASSERT_NOT_NULL(p_void_enable_params);
+
+ ANT_ENABLE * p_enable_params = (ANT_ENABLE *)p_void_enable_params;
+ uint32_t err_code = NRF_SUCCESS;
+
+ err_code = uint8_t_enc(&p_enable_params->ucTotalNumberOfChannels, p_buf, buf_len, p_index);
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code);
+
+ err_code = uint8_t_enc(&p_enable_params->ucNumberOfEncryptedChannels, p_buf, buf_len, p_index);
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code);
+
+ err_code = uint16_t_enc(&p_enable_params->usNumberOfEvents, p_buf, buf_len, p_index);
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code);
+
+ err_code = uint32_t_enc(&p_enable_params->pucMemoryBlockStartLocation, p_buf, buf_len, p_index);
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code);
+
+ err_code = uint16_t_enc(&p_enable_params->usMemoryBlockByteSize, p_buf, buf_len, p_index);
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code);
+
+ return err_code;
+}
+
+
+uint32_t ANT_ENABLE_dec(uint8_t const * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index,
+ void * const p_void_enable_params)
+
+{
+ SER_ASSERT_NOT_NULL(p_buf);
+ SER_ASSERT_NOT_NULL(p_index);
+ SER_ASSERT_NOT_NULL(p_void_enable_params);
+
+ ANT_ENABLE * p_enable_params = (ANT_ENABLE *)p_void_enable_params;
+ uint32_t err_code = NRF_SUCCESS;
+
+ err_code = uint8_t_dec(p_buf, buf_len, p_index, &p_enable_params->ucTotalNumberOfChannels);
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code);
+
+ err_code = uint8_t_dec(p_buf, buf_len, p_index, &p_enable_params->ucNumberOfEncryptedChannels);
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code);
+
+ err_code = uint16_t_dec(p_buf, buf_len, p_index, &p_enable_params->usNumberOfEvents);
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code);
+
+ err_code = uint32_t_dec(p_buf, buf_len, p_index, &p_enable_params->pucMemoryBlockStartLocation);
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code);
+
+ err_code = uint16_t_dec(p_buf, buf_len, p_index, &p_enable_params->usMemoryBlockByteSize);
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code);
+
+ return err_code;
+}
+
+uint32_t ant_evt_t_enc(void const * const p_void_ant_evt,
+ uint8_t * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index)
+{
+ SER_ASSERT_NOT_NULL(p_buf);
+ SER_ASSERT_NOT_NULL(p_index);
+ SER_ASSERT_NOT_NULL(p_void_ant_evt);
+
+ ant_evt_t * p_ant_evt = (ant_evt_t *)p_void_ant_evt;
+ uint32_t err_code = NRF_SUCCESS;
+
+ memcpy(&p_buf[*p_index], p_ant_evt->message.aucMessage, MESG_BUFFER_SIZE); // Size + sizeof(size) & sizeof(msg id)
+ *p_index += MESG_BUFFER_SIZE;
+
+ err_code = uint8_t_enc(&p_ant_evt->event, p_buf, buf_len, p_index);
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code);
+
+ err_code = uint8_t_enc(&p_ant_evt->channel, p_buf, buf_len, p_index);
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code);
+
+ return(err_code);
+}
+
+uint32_t ant_evt_t_dec(uint8_t const * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index,
+ void * const p_void_ant_evt)
+
+{
+ SER_ASSERT_NOT_NULL(p_buf);
+ SER_ASSERT_NOT_NULL(p_index);
+ SER_ASSERT_NOT_NULL(p_void_ant_evt);
+
+ ant_evt_t * p_ant_evt = (ant_evt_t *)p_void_ant_evt;
+ uint32_t err_code = NRF_SUCCESS;
+
+ memcpy(p_ant_evt->message.aucMessage, &p_buf[*p_index], MESG_BUFFER_SIZE); // Size + sizeof(size) & sizeof(msg id)
+ *p_index += MESG_BUFFER_SIZE;
+
+ err_code = uint8_t_dec(p_buf, buf_len, p_index, &p_ant_evt->event);
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code);
+
+ err_code = uint8_t_dec(p_buf, buf_len, p_index, &p_ant_evt->channel);
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code);
+
+ return err_code;
+}
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/common/struct_ser/ant/ant_struct_serialization.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/common/struct_ser/ant/ant_struct_serialization.h
new file mode 100644
index 0000000..8f405fa
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/common/struct_ser/ant/ant_struct_serialization.h
@@ -0,0 +1,110 @@
+/**
+ * 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+
+#ifndef _ANT_STRUCT_SERIALIZATION_
+#define _ANT_STRUCT_SERIALIZATION_
+
+/**@brief Function for safe encoding of an ANT_ENABLE struct.
+ *
+ * Safe decoding of an ANT_ENABLE struct. Range checks will be done if @ref SER_ASSERTS_ENABLED is set.
+ *
+ * @param[in] p_void_enable_params An ANT_ENABLE struct to be encoded.
+ * @param[out] p_buf Buffer containing the struct.
+ * @param[in] buf_len Size of the buffer.
+ * @param[in,out] p_index \c in: Index to the start of the ANT_ENABLE struct in the buffer.
+ * \c out: Index in the buffer to the first byte after the decoded struct.
+ *
+ * @return NRF_SUCCESS Fields decoded successfully.
+ * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length.
+ */
+uint32_t ANT_ENABLE_enc( void const * const p_void_enable_params,
+ uint8_t * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index);
+
+/**@brief Function for safe decoding of an ANT_ENABLE struct.
+ *
+ * Safe decoding of a ANT_ENABLE struct. Range checks will be done if @ref SER_ASSERTS_ENABLED is set.
+ *
+ * @param[in] p_buf Buffer containing the struct.
+ * @param[in] buf_len Size of the buffer.
+ * @param[in,out] p_index \c in: Index to the start of the ANT_ENABLE struct in the buffer.
+ * \c out: Index in the buffer to the first byte after the decoded struct.
+ * @param[out] p_void_enable_params Decoded ANT_ENABLE struct.
+ */
+uint32_t ANT_ENABLE_dec( uint8_t const * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index,
+ void * const p_void_enable_params);
+
+/**@brief Function for safe encoding of an ant_evt_t struct.
+ *
+ * Safe decoding of an ant_evt_t struct. Range checks will be done if @ref SER_ASSERTS_ENABLED is set.
+ *
+ * @param[in] p_void_ant_evt An ant_evt_t struct to be encoded.
+ * @param[out] p_buf Buffer containing the struct.
+ * @param[in] buf_len Size of the buffer.
+ * @param[in,out] p_index \c in: Index to the start of the ant_evt_t struct in the buffer.
+ * \c out: Index in the buffer to the first byte after the decoded struct.
+ *
+ * @return NRF_SUCCESS Fields decoded successfully.
+ * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length.
+ */
+uint32_t ant_evt_t_enc( void const * const p_void_ant_evt,
+ uint8_t * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index);
+
+/**@brief Function for safe decoding of an ant_evt_t struct.
+ *
+ * Safe decoding of a ant_evt_t struct. Range checks will be done if @ref SER_ASSERTS_ENABLED is set.
+ *
+ * @param[in] p_buf Buffer containing the struct.
+ * @param[in] buf_len Size of the buffer.
+ * @param[in,out] p_index \c in: Index to the start of the ant_evt_t struct in the buffer.
+ * \c out: Index in the buffer to the first byte after the decoded struct.
+ * @param[out] p_void_ant_evt Decoded ant_evt_t struct.
+ */
+uint32_t ant_evt_t_dec( uint8_t const * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index,
+ void * const p_void_ant_evt);
+
+#endif
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/common/struct_ser/ble/ble_gap_struct_serialization.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/common/struct_ser/ble/ble_gap_struct_serialization.c
new file mode 100644
index 0000000..9071ad7
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/common/struct_ser/ble/ble_gap_struct_serialization.c
@@ -0,0 +1,1749 @@
+/**
+ * Copyright (c) 2014 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#include "ble_gap_struct_serialization.h"
+#include "ble_struct_serialization.h"
+#include "ble_serialization.h"
+#include "cond_field_serialization.h"
+#include "app_util.h"
+#include "string.h"
+#include "ble_gatts.h"
+
+#ifndef S112
+uint32_t ble_gap_evt_adv_report_t_enc(void const * const p_void_struct,
+ uint8_t * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index)
+{
+ SER_STRUCT_ENC_BEGIN(ble_gap_evt_adv_report_t);
+#if NRF_SD_BLE_API_VERSION > 5
+ SER_PUSH_FIELD(&p_struct->type, ble_gap_adv_report_type_t_enc);
+ SER_PUSH_FIELD(&p_struct->peer_addr, ble_gap_addr_t_enc);
+ SER_PUSH_FIELD(&p_struct->direct_addr, ble_gap_addr_t_enc);
+ SER_PUSH_uint8(&p_struct->primary_phy);
+ SER_PUSH_uint8(&p_struct->secondary_phy);
+ SER_PUSH_int8(&p_struct->tx_power);
+ SER_PUSH_int8(&p_struct->rssi);
+ SER_PUSH_uint8(&p_struct->ch_index);
+ SER_PUSH_uint8(&p_struct->set_id);
+ uint16_t temp = p_struct->data_id;
+ SER_PUSH_uint16(&temp);
+ SER_PUSH_FIELD(&p_struct->data, ble_data_t_enc);
+ SER_PUSH_FIELD(&p_struct->aux_pointer, ble_gap_aux_pointer_t_enc);
+#else
+ uint8_t ser_data = (p_struct->scan_rsp & 0x01)
+ | ((p_struct->type & 0x03) << 1);
+ uint8_t data_len = (p_struct->dlen & 0x1F);
+ SER_PUSH_FIELD(&p_struct->peer_addr, ble_gap_addr_t_enc);
+ SER_PUSH_FIELD(&p_struct->direct_addr, ble_gap_addr_t_enc);
+ SER_PUSH_int8(&p_struct->rssi);
+ SER_PUSH_uint8(&ser_data);
+ SER_PUSH_len8data(p_struct->data, data_len);
+#endif
+ SER_STRUCT_ENC_END;
+}
+
+uint32_t ble_gap_evt_adv_report_t_dec(uint8_t const * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index,
+ void * const p_void_struct)
+{
+ SER_STRUCT_DEC_BEGIN(ble_gap_evt_adv_report_t);
+
+#if NRF_SD_BLE_API_VERSION > 5
+ SER_PULL_FIELD(&p_struct->type, ble_gap_adv_report_type_t_dec);
+ SER_PULL_FIELD(&p_struct->peer_addr, ble_gap_addr_t_dec);
+ SER_PULL_FIELD(&p_struct->direct_addr, ble_gap_addr_t_dec);
+ SER_PULL_uint8(&p_struct->primary_phy);
+ SER_PULL_uint8(&p_struct->secondary_phy);
+ SER_PULL_int8(&p_struct->tx_power);
+ SER_PULL_int8(&p_struct->rssi);
+ SER_PULL_uint8(&p_struct->ch_index);
+ SER_PULL_uint8(&p_struct->set_id);
+ uint16_t temp;
+ SER_PULL_uint16(&temp);
+ p_struct->data_id = temp & 0x0FFF;
+ SER_PULL_FIELD(&p_struct->data, ble_data_t_dec);
+ SER_PULL_FIELD(&p_struct->aux_pointer, ble_gap_aux_pointer_t_dec);
+#else
+ uint8_t ser_data;
+ uint8_t data_len = BLE_GAP_ADV_MAX_SIZE;
+ uint8_t * p_field_data = p_struct->data;
+ SER_PULL_FIELD(&p_struct->peer_addr, ble_gap_addr_t_dec);
+ SER_PULL_FIELD(&p_struct->direct_addr, ble_gap_addr_t_dec);
+ SER_PULL_int8(&p_struct->rssi);
+ SER_PULL_uint8(&ser_data);
+ SER_PULL_len8data(&p_field_data, &data_len);
+
+ p_struct->scan_rsp = ser_data & 0x01;
+ p_struct->type = (ser_data >> 1) & 0x03;
+ p_struct->dlen = data_len;
+#endif
+ SER_STRUCT_DEC_END;
+}
+#endif
+
+uint32_t ble_gap_irk_t_enc(void const * const p_void_struct,
+ uint8_t * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index)
+{
+ SER_STRUCT_ENC_BEGIN(ble_gap_irk_t);
+ SER_PUSH_uint8array(p_struct->irk, BLE_GAP_SEC_KEY_LEN);
+ SER_STRUCT_ENC_END;
+}
+
+uint32_t ble_gap_irk_t_dec(uint8_t const * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index,
+ void * const p_void_struct)
+{
+ SER_STRUCT_DEC_BEGIN(ble_gap_irk_t);
+ SER_PULL_uint8array(p_struct->irk, BLE_GAP_SEC_KEY_LEN);
+ SER_STRUCT_DEC_END;
+}
+
+uint32_t ble_gap_addr_t_enc(void const * const p_void_struct,
+ uint8_t * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index)
+{
+ SER_STRUCT_ENC_BEGIN(ble_gap_addr_t);
+
+ uint8_t ser_data = (p_struct->addr_id_peer & 0x01)
+ | ((p_struct->addr_type & 0x7F) << 1);
+ SER_PUSH_uint8(&ser_data);
+ SER_PUSH_uint8array(p_struct->addr, BLE_GAP_ADDR_LEN);
+
+ SER_STRUCT_ENC_END;
+}
+
+uint32_t ble_gap_addr_t_dec(uint8_t const * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index,
+ void * const p_void_struct)
+{
+ SER_STRUCT_DEC_BEGIN(ble_gap_addr_t);
+
+ uint8_t ser_data;
+ SER_PULL_uint8(&ser_data);
+ SER_PULL_uint8array(p_struct->addr, BLE_GAP_ADDR_LEN);
+
+ p_struct->addr_id_peer = ser_data & 0x01;
+ p_struct->addr_type = (ser_data >> 1) & 0x7F;
+
+ SER_STRUCT_DEC_END;
+}
+
+uint32_t ble_gap_sec_levels_t_enc(void const * const p_void_struct,
+ uint8_t * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index)
+{
+ SER_STRUCT_ENC_BEGIN(ble_gap_sec_levels_t);
+
+ uint8_t sec_levels_serialized = (p_struct->lv1 << 0) | (p_struct->lv2 << 1)
+ | (p_struct->lv3 << 2) | (p_struct->lv4 << 3);
+ SER_PUSH_uint8(&sec_levels_serialized);
+
+ SER_STRUCT_ENC_END;
+}
+
+uint32_t ble_gap_sec_levels_t_dec(uint8_t const * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index,
+ void * const p_void_struct)
+{
+ SER_STRUCT_DEC_BEGIN(ble_gap_sec_levels_t);
+
+ uint32_t sec_levels_serialized;
+ SER_PULL_uint8(&sec_levels_serialized);
+
+ p_struct->lv1 = sec_levels_serialized & 0x01;
+ p_struct->lv2 = (sec_levels_serialized >> 1) & 0x01;
+ p_struct->lv3 = (sec_levels_serialized >> 2) & 0x01;
+ p_struct->lv4 = (sec_levels_serialized >> 3) & 0x01;
+
+ SER_STRUCT_DEC_END;
+}
+
+uint32_t ble_gap_sec_keys_t_enc(void const * const p_void_struct,
+ uint8_t * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index)
+{
+ SER_STRUCT_ENC_BEGIN(ble_gap_sec_keys_t);
+
+ SER_PUSH_COND(p_struct->p_enc_key, ble_gap_enc_key_t_enc);
+ SER_PUSH_COND(p_struct->p_id_key, ble_gap_id_key_t_enc);
+ SER_PUSH_COND(p_struct->p_sign_key, ble_gap_sign_info_t_enc);
+ SER_PUSH_COND(p_struct->p_pk, ble_gap_lesc_p256_pk_t_enc);
+
+ SER_STRUCT_ENC_END;
+}
+
+uint32_t ble_gap_sec_keys_t_dec(uint8_t const * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index,
+ void * const p_void_struct)
+{
+ SER_STRUCT_DEC_BEGIN(ble_gap_sec_keys_t);
+
+ SER_PULL_COND(&(p_struct->p_enc_key), ble_gap_enc_key_t_dec);
+ SER_PULL_COND(&(p_struct->p_id_key), ble_gap_id_key_t_dec);
+ SER_PULL_COND(&(p_struct->p_sign_key), ble_gap_sign_info_t_dec);
+ SER_PULL_COND(&(p_struct->p_pk), ble_gap_lesc_p256_pk_t_dec);
+
+ SER_STRUCT_DEC_END;
+}
+
+uint32_t ble_gap_enc_info_t_enc(void const * const p_void_struct,
+ uint8_t * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index)
+{
+ SER_STRUCT_ENC_BEGIN(ble_gap_enc_info_t);
+
+ SER_PUSH_uint8array(p_struct->ltk, BLE_GAP_SEC_KEY_LEN);
+ uint8_t ser_data = (p_struct->lesc & 0x01)
+ | ((p_struct->auth & 0x01) << 1)
+ | ((p_struct->ltk_len & 0x3F) << 2);
+ SER_PUSH_uint8(&ser_data);
+
+ SER_STRUCT_ENC_END;
+}
+
+uint32_t ble_gap_enc_info_t_dec(uint8_t const * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index,
+ void * const p_void_struct)
+{
+ SER_STRUCT_DEC_BEGIN(ble_gap_enc_info_t);
+
+ uint8_t ser_data;
+ SER_PULL_uint8array(p_struct->ltk, BLE_GAP_SEC_KEY_LEN);
+ SER_PULL_uint8(&ser_data);
+ p_struct->lesc = ser_data & 0x01;
+ p_struct->auth = (ser_data >> 1) & 0x01;
+ p_struct->ltk_len = (ser_data >> 2) & 0x3F;
+
+ SER_STRUCT_DEC_END;
+}
+
+uint32_t ble_gap_sign_info_t_enc(void const * const p_void_struct,
+ uint8_t * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index)
+{
+ SER_STRUCT_ENC_BEGIN(ble_gap_sign_info_t);
+ SER_PUSH_uint8array(p_struct->csrk, BLE_GAP_SEC_KEY_LEN);
+ SER_STRUCT_ENC_END;
+}
+
+uint32_t ble_gap_sign_info_t_dec(uint8_t const * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index,
+ void * const p_void_struct)
+{
+ SER_STRUCT_DEC_BEGIN(ble_gap_sign_info_t);
+ SER_PULL_uint8array(p_struct->csrk, BLE_GAP_SEC_KEY_LEN);
+ SER_STRUCT_ENC_END;
+}
+
+uint32_t ble_gap_evt_auth_status_t_enc(void const * const p_void_struct,
+ uint8_t * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index)
+{
+ SER_STRUCT_ENC_BEGIN(ble_gap_evt_auth_status_t);
+ uint8_t ser_data = (p_struct->error_src) | ((p_struct->bonded) << 2);
+#if NRF_SD_BLE_API_VERSION >= 5
+ ser_data |= ((p_struct->lesc) << 3);
+#endif
+ SER_PUSH_uint8(&(p_struct->auth_status));
+ SER_PUSH_uint8(&ser_data);
+
+ SER_PUSH_FIELD(&(p_struct->sm1_levels), ble_gap_sec_levels_t_enc);
+ SER_PUSH_FIELD(&(p_struct->sm2_levels), ble_gap_sec_levels_t_enc);
+ SER_PUSH_FIELD(&(p_struct->kdist_own), ble_gap_sec_kdist_t_enc);
+ SER_PUSH_FIELD(&(p_struct->kdist_peer), ble_gap_sec_kdist_t_enc);
+
+ SER_STRUCT_ENC_END;
+}
+
+uint32_t ble_gap_evt_auth_status_t_dec(uint8_t const * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index,
+ void * const p_void_struct)
+{
+ SER_STRUCT_DEC_BEGIN(ble_gap_evt_auth_status_t);
+
+ uint8_t ser_data;
+ SER_PULL_uint8(&(p_struct->auth_status));
+ SER_PULL_uint8(&ser_data);
+ p_struct->error_src = ser_data & 0x03;
+ p_struct->bonded = (ser_data >> 2) & 0x01;
+#if NRF_SD_BLE_API_VERSION >= 5
+ p_struct->lesc = (ser_data >> 3) & 0x01;
+#endif
+
+ SER_PULL_FIELD(&(p_struct->sm1_levels), ble_gap_sec_levels_t_dec);
+ SER_PULL_FIELD(&(p_struct->sm2_levels), ble_gap_sec_levels_t_dec);
+ SER_PULL_FIELD(&(p_struct->kdist_own), ble_gap_sec_kdist_t_dec);
+ SER_PULL_FIELD(&(p_struct->kdist_peer), ble_gap_sec_kdist_t_dec);
+
+ SER_STRUCT_DEC_END;
+}
+
+
+uint32_t ble_gap_conn_sec_mode_t_enc(void const * const p_void_struct,
+ uint8_t * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index)
+{
+ SER_STRUCT_ENC_BEGIN(ble_gap_conn_sec_mode_t);
+
+ uint8_t ser_data = (p_struct->sm & 0x0F)
+ | ((p_struct->lv & 0x0F) << 4);
+ SER_PUSH_uint8(&ser_data);
+
+ SER_STRUCT_ENC_END;
+}
+
+uint32_t ble_gap_conn_sec_mode_t_dec(uint8_t const * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index,
+ void * const p_void_struct)
+{
+ SER_STRUCT_DEC_BEGIN(ble_gap_conn_sec_mode_t);
+
+ uint8_t ser_data;
+ SER_PULL_uint8(&ser_data);
+ p_struct->sm = ser_data & 0x0F;
+ p_struct->lv = (ser_data >> 4) & 0x0F;
+
+ SER_STRUCT_DEC_END;
+}
+
+uint32_t ble_gap_evt_conn_sec_update_t_enc(void const * const p_void_struct,
+ uint8_t * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index)
+{
+ SER_STRUCT_ENC_BEGIN(ble_gap_evt_conn_sec_update_t);
+ SER_PUSH_FIELD(&(p_struct->conn_sec), ble_gap_conn_sec_t_enc);
+ SER_STRUCT_ENC_END;
+}
+
+uint32_t ble_gap_evt_conn_sec_update_t_dec(uint8_t const * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index,
+ void * const p_void_struct)
+{
+ SER_STRUCT_DEC_BEGIN(ble_gap_evt_conn_sec_update_t);
+ SER_PULL_FIELD(&(p_struct->conn_sec), ble_gap_conn_sec_t_dec);
+ SER_STRUCT_DEC_END;
+}
+
+uint32_t ble_gap_conn_sec_t_enc(void const * const p_void_struct,
+ uint8_t * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index)
+{
+ SER_STRUCT_ENC_BEGIN(ble_gap_conn_sec_t);
+
+ SER_PUSH_FIELD(&p_struct->sec_mode, ble_gap_conn_sec_mode_t_enc);
+ SER_PUSH_uint8(&p_struct->encr_key_size);
+
+ SER_STRUCT_ENC_END;
+}
+
+uint32_t ble_gap_conn_sec_t_dec(uint8_t const * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index,
+ void * const p_void_struct)
+{
+ SER_STRUCT_DEC_BEGIN(ble_gap_conn_sec_t);
+
+ SER_PULL_FIELD(&p_struct->sec_mode, ble_gap_conn_sec_mode_t_dec);
+ SER_PULL_uint8(&p_struct->encr_key_size);
+
+ SER_STRUCT_DEC_END;
+}
+
+uint32_t ble_gap_evt_sec_info_request_t_enc(void const * const p_void_struct,
+ uint8_t * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index)
+{
+ SER_STRUCT_ENC_BEGIN(ble_gap_evt_sec_info_request_t);
+
+ uint8_t ser_data = (p_struct->enc_info & 0x01)
+ | ((p_struct->id_info & 0x01) << 1)
+ | ((p_struct->sign_info& 0x01) << 2);
+ SER_PUSH_FIELD(&p_struct->peer_addr, ble_gap_addr_t_enc);
+ SER_PUSH_FIELD(&p_struct->master_id, ble_gap_master_id_t_enc);
+ SER_PUSH_uint8(&ser_data);
+
+ SER_STRUCT_ENC_END;
+}
+
+uint32_t ble_gap_evt_sec_info_request_t_dec(uint8_t const * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index,
+ void * const p_void_struct)
+{
+ SER_STRUCT_DEC_BEGIN(ble_gap_evt_sec_info_request_t);
+
+ uint8_t ser_data;
+ SER_PULL_FIELD(&p_struct->peer_addr, ble_gap_addr_t_dec);
+ SER_PULL_FIELD(&p_struct->master_id, ble_gap_master_id_t_dec);
+ SER_PULL_uint8(&ser_data);
+ p_struct->enc_info = ser_data & 0x01;
+ p_struct->id_info = (ser_data >> 1) & 0x01;
+ p_struct->sign_info = (ser_data >> 2) & 0x01;
+
+ SER_STRUCT_DEC_END;
+}
+
+uint32_t ble_gap_evt_connected_t_enc(void const * const p_void_struct,
+ uint8_t * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index)
+{
+ SER_STRUCT_ENC_BEGIN(ble_gap_evt_connected_t);
+
+ SER_PUSH_FIELD(&p_struct->peer_addr, ble_gap_addr_t_enc);
+ SER_PUSH_uint8(&p_struct->role);
+ SER_PUSH_FIELD(&p_struct->conn_params, ble_gap_conn_params_t_enc);
+#if defined(NRF_SD_BLE_API_VERSION) && NRF_SD_BLE_API_VERSION > 5
+ SER_PUSH_uint8(&p_struct->adv_handle);
+ SER_PUSH_uint16(&p_struct->adv_data.adv_data.len);
+ SER_PUSH_uint16(&p_struct->adv_data.scan_rsp_data.len);
+#endif
+
+ SER_STRUCT_ENC_END;
+}
+
+uint32_t ble_gap_evt_connected_t_dec(uint8_t const * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index,
+ void * const p_void_struct)
+{
+ SER_STRUCT_DEC_BEGIN(ble_gap_evt_connected_t);
+
+ SER_PULL_FIELD(&p_struct->peer_addr, ble_gap_addr_t_dec);
+ SER_PULL_uint8(&p_struct->role);
+ SER_PULL_FIELD(&p_struct->conn_params, ble_gap_conn_params_t_dec);
+#if defined(NRF_SD_BLE_API_VERSION) && NRF_SD_BLE_API_VERSION > 5
+ SER_PULL_uint8(&p_struct->adv_handle);
+ SER_PULL_uint16(&p_struct->adv_data.adv_data.len);
+ SER_PULL_uint16(&p_struct->adv_data.scan_rsp_data.len);
+#endif
+
+ SER_STRUCT_DEC_END;
+}
+
+uint32_t ble_gap_sec_params_t_enc(void const * const p_void_struct,
+ uint8_t * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index)
+{
+ SER_STRUCT_ENC_BEGIN(ble_gap_sec_params_t);
+
+ uint8_t ser_data = (p_struct->bond & 0x01)
+ | ((p_struct->mitm & 0x01) << 1)
+ | ((p_struct->lesc & 0x01) << 2)
+ | ((p_struct->keypress & 0x01) << 3)
+ | ((p_struct->io_caps & 0x07) << 4)
+ | ((p_struct->oob & 0x01) << 7);
+ SER_PUSH_uint8(&ser_data);
+ SER_PUSH_uint8(&p_struct->min_key_size);
+ SER_PUSH_uint8(&p_struct->max_key_size);
+ SER_PUSH_FIELD(&p_struct->kdist_own, ble_gap_sec_kdist_t_enc);
+ SER_PUSH_FIELD(&p_struct->kdist_peer, ble_gap_sec_kdist_t_enc);
+
+ SER_STRUCT_ENC_END;
+}
+
+uint32_t ble_gap_sec_params_t_dec(uint8_t const * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index,
+ void * const p_void_struct)
+{
+ SER_STRUCT_DEC_BEGIN(ble_gap_sec_params_t);
+
+ uint8_t ser_data;
+ SER_PULL_uint8(&ser_data);
+ SER_PULL_uint8(&p_struct->min_key_size);
+ SER_PULL_uint8(&p_struct->max_key_size);
+ SER_PULL_FIELD(&p_struct->kdist_own, ble_gap_sec_kdist_t_dec);
+ SER_PULL_FIELD(&p_struct->kdist_peer, ble_gap_sec_kdist_t_dec);
+ p_struct->bond = ser_data & 0x01;
+ p_struct->mitm = (ser_data >> 1) & 0x01;
+ p_struct->lesc = (ser_data >> 2) & 0x01;
+ p_struct->keypress = (ser_data >> 3) & 0x01;
+ p_struct->io_caps = (ser_data >> 4) & 0x07;
+ p_struct->oob = (ser_data >> 7) & 0x01;
+
+ SER_STRUCT_DEC_END;
+}
+
+uint32_t ble_gap_evt_sec_params_request_t_enc(void const * const p_void_struct,
+ uint8_t * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index)
+{
+ SER_STRUCT_ENC_BEGIN(ble_gap_evt_sec_params_request_t);
+ SER_PUSH_FIELD(&(p_struct->peer_params), ble_gap_sec_params_t_enc);
+ SER_STRUCT_ENC_END;
+}
+
+ uint32_t ble_gap_evt_sec_params_request_t_dec(uint8_t const * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index,
+ void * const p_void_struct)
+{
+ SER_STRUCT_DEC_BEGIN(ble_gap_evt_sec_params_request_t);
+ SER_PULL_FIELD(&(p_struct->peer_params), ble_gap_sec_params_t_dec);
+ SER_STRUCT_DEC_END;
+}
+
+uint32_t ble_gap_evt_conn_param_update_t_enc(void const * const p_void_struct,
+ uint8_t * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index)
+{
+ SER_STRUCT_ENC_BEGIN(ble_gap_evt_conn_param_update_t);
+ SER_PUSH_FIELD(&(p_struct->conn_params), ble_gap_conn_params_t_enc);
+ SER_STRUCT_ENC_END;
+}
+
+uint32_t ble_gap_evt_conn_param_update_t_dec(uint8_t const * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index,
+ void * const p_void_struct)
+{
+ SER_STRUCT_DEC_BEGIN(ble_gap_evt_conn_param_update_t);
+ SER_PULL_FIELD(&(p_struct->conn_params), ble_gap_conn_params_t_dec);
+ SER_STRUCT_DEC_END;
+}
+
+#ifndef S112
+uint32_t ble_gap_evt_conn_param_update_request_t_enc(void const * const p_void_struct,
+ uint8_t * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index)
+{
+ SER_STRUCT_ENC_BEGIN(ble_gap_evt_conn_param_update_request_t);
+ SER_PUSH_FIELD(&(p_struct->conn_params), ble_gap_conn_params_t_enc);
+ SER_STRUCT_ENC_END;
+}
+
+uint32_t ble_gap_evt_conn_param_update_request_t_dec(uint8_t const * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index,
+ void * const p_void_struct)
+{
+ SER_STRUCT_DEC_BEGIN(ble_gap_evt_conn_param_update_request_t);
+ SER_PULL_FIELD(&(p_struct->conn_params), ble_gap_conn_params_t_dec);
+ SER_STRUCT_DEC_END;
+}
+#endif //!S112
+
+uint32_t ble_gap_conn_params_t_enc(void const * const p_void_struct,
+ uint8_t * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index)
+{
+ SER_STRUCT_ENC_BEGIN(ble_gap_conn_params_t);
+
+ SER_PUSH_uint16(&p_struct->min_conn_interval);
+ SER_PUSH_uint16(&p_struct->max_conn_interval);
+ SER_PUSH_uint16(&p_struct->slave_latency);
+ SER_PUSH_uint16(&p_struct->conn_sup_timeout);
+
+ SER_STRUCT_ENC_END;
+}
+
+uint32_t ble_gap_conn_params_t_dec(uint8_t const * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index,
+ void * const p_void_struct)
+{
+ SER_STRUCT_DEC_BEGIN(ble_gap_conn_params_t);
+
+ SER_PULL_uint16(&p_struct->min_conn_interval);
+ SER_PULL_uint16(&p_struct->max_conn_interval);
+ SER_PULL_uint16(&p_struct->slave_latency);
+ SER_PULL_uint16(&p_struct->conn_sup_timeout);
+
+ SER_STRUCT_DEC_END;
+}
+
+uint32_t ble_gap_evt_disconnected_t_enc(void const * const p_void_struct,
+ uint8_t * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index)
+{
+ SER_STRUCT_ENC_BEGIN(ble_gap_evt_disconnected_t);
+ SER_PUSH_uint8(&p_struct->reason);
+ SER_STRUCT_ENC_END;
+}
+
+uint32_t ble_gap_evt_disconnected_t_dec(uint8_t const * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index,
+ void * const p_void_struct)
+{
+ SER_STRUCT_DEC_BEGIN(ble_gap_evt_disconnected_t);
+ SER_PULL_uint8(&p_struct->reason);
+ SER_STRUCT_DEC_END;
+}
+
+uint32_t ble_gap_master_id_t_enc(void const * const p_void_struct,
+ uint8_t * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index)
+{
+ SER_STRUCT_ENC_BEGIN(ble_gap_master_id_t);
+ SER_PUSH_uint16(&p_struct->ediv);
+ SER_PUSH_uint8array(p_struct->rand, BLE_GAP_SEC_RAND_LEN);
+ SER_STRUCT_ENC_END;
+}
+
+uint32_t ble_gap_master_id_t_dec(uint8_t const * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index,
+ void * const p_void_struct)
+{
+ SER_STRUCT_DEC_BEGIN(ble_gap_master_id_t);
+ SER_PULL_uint16(&p_struct->ediv);
+ SER_PULL_uint8array(p_struct->rand, BLE_GAP_SEC_RAND_LEN);
+ SER_STRUCT_DEC_END;
+}
+
+#ifndef S112
+uint32_t ble_gap_scan_params_t_enc(void const * const p_void_struct,
+ uint8_t * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index)
+{
+ SER_STRUCT_ENC_BEGIN(ble_gap_scan_params_t);
+ uint8_t ser_data;
+#if defined(NRF_SD_BLE_API_VERSION) && NRF_SD_BLE_API_VERSION < 6
+ ser_data = (p_struct->active & 0x01)
+ | ((p_struct->use_whitelist & 0x01) << 1)
+ | ((p_struct->adv_dir_report & 0x01) << 2);
+ SER_PUSH_uint8(&ser_data);
+#else
+ ser_data =
+ ((p_struct->extended & 0x01) << 0) |
+ ((p_struct->report_incomplete_evts & 0x01) << 1) |
+ ((p_struct->active & 0x01) << 2) |
+ ((p_struct->filter_policy & 0x03) << 3);
+ SER_PUSH_uint8(&ser_data);
+ SER_PUSH_uint8(&p_struct->scan_phys);
+ SER_PUSH_buf(p_struct->channel_mask, 5);
+#endif
+ SER_PUSH_uint16(&p_struct->interval);
+ SER_PUSH_uint16(&p_struct->window);
+ SER_PUSH_uint16(&p_struct->timeout);
+
+ SER_STRUCT_ENC_END;
+}
+uint32_t ble_gap_scan_params_t_dec(uint8_t const * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index,
+ void * const p_void_struct)
+{
+ SER_STRUCT_DEC_BEGIN(ble_gap_scan_params_t);
+
+ uint8_t ser_data;
+#if defined(NRF_SD_BLE_API_VERSION) && NRF_SD_BLE_API_VERSION < 6
+ SER_PULL_uint8(&ser_data);
+ p_struct->active = ser_data & 0x01;
+ p_struct->use_whitelist = (ser_data >> 1) & 0x01;
+ p_struct->adv_dir_report = (ser_data >> 2) & 0x01;
+#else
+ SER_PULL_uint8(&ser_data);
+ p_struct->extended = ser_data & 0x01;
+ p_struct->report_incomplete_evts = (ser_data >> 1) & 0x01;
+ p_struct->active = (ser_data >> 2) & 0x01;
+ p_struct->filter_policy = (ser_data >> 3) & 0x03;
+
+ SER_PULL_uint8(&p_struct->scan_phys);
+ uint8_t * p_channel_mask = (uint8_t *)p_struct->channel_mask;
+ SER_PULL_buf(&p_channel_mask, 5, 5);
+#endif
+ SER_PULL_uint16(&p_struct->interval);
+ SER_PULL_uint16(&p_struct->window);
+ SER_PULL_uint16(&p_struct->timeout);
+
+ SER_STRUCT_DEC_END;
+}
+#endif //!S112
+
+uint32_t ble_gap_enc_key_t_enc(void const * const p_void_struct,
+ uint8_t * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index)
+{
+ SER_STRUCT_ENC_BEGIN(ble_gap_enc_key_t);
+
+ SER_PUSH_FIELD(&p_struct->enc_info, ble_gap_enc_info_t_enc);
+ SER_PUSH_FIELD(&p_struct->master_id, ble_gap_master_id_t_enc);
+
+ SER_STRUCT_ENC_END;
+}
+
+uint32_t ble_gap_enc_key_t_dec(uint8_t const * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index,
+ void * const p_void_struct)
+{
+ SER_STRUCT_DEC_BEGIN(ble_gap_enc_key_t);
+
+ SER_PULL_FIELD(&p_struct->enc_info, ble_gap_enc_info_t_dec);
+ SER_PULL_FIELD(&p_struct->master_id, ble_gap_master_id_t_dec);
+
+ SER_STRUCT_DEC_END;
+}
+
+uint32_t ble_gap_id_key_t_enc(void const * const p_void_struct,
+ uint8_t * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index)
+{
+ SER_STRUCT_ENC_BEGIN(ble_gap_id_key_t);
+
+ SER_PUSH_FIELD(&p_struct->id_info, ble_gap_irk_t_enc);
+ SER_PUSH_FIELD(&p_struct->id_addr_info, ble_gap_addr_t_enc);
+
+ SER_STRUCT_ENC_END;
+}
+
+uint32_t ble_gap_id_key_t_dec(uint8_t const * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index,
+ void * const p_void_struct)
+{
+ SER_STRUCT_DEC_BEGIN(ble_gap_id_key_t);
+
+ SER_PULL_FIELD(&p_struct->id_info, ble_gap_irk_t_dec);
+ SER_PULL_FIELD(&p_struct->id_addr_info, ble_gap_addr_t_dec);
+
+ SER_STRUCT_DEC_END;
+}
+
+uint32_t ble_gap_sec_keyset_t_enc(void const * const p_void_struct,
+ uint8_t * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index)
+{
+ SER_STRUCT_ENC_BEGIN(ble_gap_sec_keyset_t);
+
+ SER_PUSH_FIELD(&p_struct->keys_own, ble_gap_sec_keys_t_enc);
+ SER_PUSH_FIELD(&p_struct->keys_peer, ble_gap_sec_keys_t_enc);
+
+ SER_STRUCT_ENC_END;
+}
+
+uint32_t ble_gap_sec_keyset_t_dec(uint8_t const * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index,
+ void * const p_void_struct)
+{
+ SER_STRUCT_DEC_BEGIN(ble_gap_sec_keyset_t);
+
+ SER_PULL_FIELD(&p_struct->keys_own, ble_gap_sec_keys_t_dec);
+ SER_PULL_FIELD(&p_struct->keys_peer, ble_gap_sec_keys_t_dec);
+
+ SER_STRUCT_DEC_END;
+}
+
+uint32_t ble_gap_evt_sec_request_t_enc(void const * const p_void_struct,
+ uint8_t * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index)
+{
+ SER_STRUCT_ENC_BEGIN(ble_gap_evt_sec_request_t);
+
+ uint8_t ser_data = (p_struct->bond & 0x01)
+ | ((p_struct->mitm & 0x01) << 1)
+ | ((p_struct->lesc & 0x01) << 2)
+ | ((p_struct->keypress & 0x01) << 3);
+ SER_PUSH_uint8(&ser_data);
+
+ SER_STRUCT_ENC_END;
+}
+
+uint32_t ble_gap_evt_sec_request_t_dec(uint8_t const * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index,
+ void * const p_void_struct)
+{
+ SER_STRUCT_DEC_BEGIN(ble_gap_evt_sec_request_t);
+
+ uint8_t ser_data;
+ SER_PULL_uint8(&ser_data);
+ p_struct->bond = ser_data & 0x01;
+ p_struct->mitm = (ser_data >> 1) & 0x01;
+ p_struct->lesc = (ser_data >> 2) & 0x01;
+ p_struct->keypress = (ser_data >> 3) & 0x01;
+
+ SER_STRUCT_DEC_END;
+}
+
+uint32_t ble_gap_sec_kdist_t_enc(void const * const p_void_struct,
+ uint8_t * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index)
+{
+ SER_STRUCT_ENC_BEGIN(ble_gap_sec_kdist_t);
+
+ uint8_t ser_data = (p_struct->enc & 0x01)
+ | (p_struct->id & 0x01) << 1
+ | (p_struct->sign & 0x01) << 2
+ | (p_struct->link & 0x01) << 3;
+ SER_PUSH_uint8(&ser_data);
+
+ SER_STRUCT_ENC_END;
+}
+
+uint32_t ble_gap_sec_kdist_t_dec(uint8_t const * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index,
+ void * const p_void_struct)
+{
+ SER_STRUCT_DEC_BEGIN(ble_gap_sec_kdist_t);
+
+ uint8_t ser_data;
+ SER_PULL_uint8(&ser_data);
+ p_struct->enc = ser_data & 0x01;
+ p_struct->id = (ser_data >> 1) & 0x01;
+ p_struct->sign = (ser_data >> 2) & 0x01;
+ p_struct->link = (ser_data >> 3) & 0x01;
+
+ SER_STRUCT_DEC_END;
+}
+
+uint32_t ble_gap_opt_ch_map_t_enc(void const * const p_void_struct,
+ uint8_t * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index)
+{
+ SER_STRUCT_ENC_BEGIN(ble_gap_opt_ch_map_t);
+
+ SER_PUSH_uint16(&p_struct->conn_handle);
+ SER_PUSH_uint8array(p_struct->ch_map, 5);
+
+ SER_STRUCT_ENC_END;
+}
+
+uint32_t ble_gap_opt_ch_map_t_dec(uint8_t const * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index,
+ void * const p_void_struct)
+{
+ SER_STRUCT_DEC_BEGIN(ble_gap_opt_ch_map_t);
+
+ SER_PULL_uint16(&p_struct->conn_handle);
+ SER_PULL_uint8array(p_struct->ch_map, 5);
+
+ SER_STRUCT_DEC_END;
+}
+
+uint32_t ble_gap_opt_local_conn_latency_t_enc(void const * const p_void_struct,
+ uint8_t * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index)
+{
+ SER_STRUCT_ENC_BEGIN(ble_gap_opt_local_conn_latency_t);
+
+ SER_PUSH_uint16(&p_struct->conn_handle);
+ SER_PUSH_uint16(&p_struct->requested_latency);
+ SER_PUSH_COND(p_struct->p_actual_latency, uint16_t_enc);
+
+ SER_STRUCT_ENC_END;
+}
+
+uint32_t ble_gap_opt_local_conn_latency_t_dec(uint8_t const * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index,
+ void * const p_void_struct)
+{
+ SER_STRUCT_DEC_BEGIN(ble_gap_opt_local_conn_latency_t);
+
+ SER_PULL_uint16(&p_struct->conn_handle);
+ SER_PULL_uint16(&p_struct->requested_latency);
+ SER_PULL_COND(&p_struct->p_actual_latency, uint16_t_dec);
+
+ SER_STRUCT_DEC_END;
+}
+
+uint32_t ble_gap_opt_passkey_t_enc(void const * const p_void_struct,
+ uint8_t * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index)
+{
+ SER_STRUCT_ENC_BEGIN(ble_gap_opt_passkey_t);
+ SER_PUSH_buf(p_struct->p_passkey, BLE_GAP_PASSKEY_LEN);
+ SER_STRUCT_ENC_END;
+}
+
+uint32_t ble_gap_opt_passkey_t_dec(uint8_t const * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index,
+ void * const p_void_struct)
+{
+ SER_STRUCT_DEC_BEGIN(ble_gap_opt_passkey_t);
+ SER_PULL_buf((uint8_t**)&p_struct->p_passkey, BLE_GAP_PASSKEY_LEN, BLE_GAP_PASSKEY_LEN);
+ SER_STRUCT_DEC_END;
+}
+#if defined(NRF_SD_BLE_API_VERSION) && NRF_SD_BLE_API_VERSION < 6
+uint32_t ble_gap_opt_scan_req_report_t_enc(void const * const p_void_struct,
+ uint8_t * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index)
+{
+ SER_STRUCT_ENC_BEGIN(ble_gap_opt_scan_req_report_t);
+
+ uint8_t ser_data = p_struct->enable & 0x01;
+ SER_PUSH_uint8(&ser_data);
+
+ SER_STRUCT_ENC_END;
+}
+
+uint32_t ble_gap_opt_scan_req_report_t_dec(uint8_t const * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index,
+ void * const p_void_struct)
+{
+ SER_STRUCT_DEC_BEGIN(ble_gap_opt_scan_req_report_t);
+
+ uint8_t ser_data;
+ SER_PULL_uint8(&ser_data);
+ p_struct->enable = ser_data & 0x01;
+
+ SER_STRUCT_DEC_END;
+}
+#endif
+
+#if defined(NRF_SD_BLE_API_VERSION) && NRF_SD_BLE_API_VERSION < 4
+uint32_t ble_gap_opt_compat_mode_t_enc(void const * const p_void_struct,
+ uint8_t * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index)
+{
+ SER_STRUCT_ENC_BEGIN(ble_gap_opt_compat_mode_t);
+
+ uint8_t ser_data = p_struct->mode_1_enable & 0x01;
+ SER_PUSH_uint8(&ser_data);
+
+ SER_STRUCT_ENC_END;
+}
+
+uint32_t ble_gap_opt_compat_mode_t_dec(uint8_t const * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index,
+ void * const p_void_struct)
+{
+ SER_STRUCT_DEC_BEGIN(ble_gap_opt_compat_mode_t);
+
+ uint8_t ser_data;
+ SER_PULL_uint8(&ser_data);
+ p_struct->mode_1_enable = ser_data & 0x01;
+
+ SER_STRUCT_DEC_END;
+}
+#endif
+
+#if defined(NRF_SD_BLE_API_VERSION) && NRF_SD_BLE_API_VERSION < 6
+uint32_t ble_gap_adv_ch_mask_t_enc(void const * const p_void_struct,
+ uint8_t * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index)
+{
+ SER_STRUCT_ENC_BEGIN(ble_gap_adv_ch_mask_t);
+
+ uint8_t ser_data = (p_struct->ch_37_off & 0x01)
+ | ((p_struct->ch_38_off & 0x01) << 1)
+ | ((p_struct->ch_39_off & 0x01) << 2);
+ SER_PUSH_uint8(&ser_data);
+
+ SER_STRUCT_ENC_END;
+}
+
+uint32_t ble_gap_adv_ch_mask_t_dec(uint8_t const * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index,
+ void * const p_void_struct)
+{
+ SER_STRUCT_DEC_BEGIN(ble_gap_adv_ch_mask_t);
+
+ uint8_t ser_data;
+ SER_PULL_uint8(&ser_data);
+ p_struct->ch_37_off = ser_data & 0x01;
+ p_struct->ch_38_off = (ser_data >> 1) & 0x01;
+ p_struct->ch_39_off = (ser_data >> 2) & 0x01;
+
+ SER_STRUCT_DEC_END;
+}
+#endif
+
+#if defined(NRF_SD_BLE_API_VERSION) && NRF_SD_BLE_API_VERSION < 4
+uint32_t ble_gap_enable_params_t_enc(void const * const p_void_struct,
+ uint8_t * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index)
+{
+ SER_STRUCT_ENC_BEGIN(ble_gap_enable_params_t);
+
+ SER_PUSH_uint8(&p_struct->periph_conn_count);
+ SER_PUSH_uint8(&p_struct->central_conn_count);
+ SER_PUSH_uint8(&p_struct->central_sec_count);
+ SER_PUSH_COND(p_struct->p_device_name, ble_gap_device_name_t_enc);
+
+ SER_STRUCT_ENC_END;
+}
+
+uint32_t ble_gap_enable_params_t_dec(uint8_t const * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index,
+ void * const p_void_struct)
+{
+ SER_STRUCT_DEC_BEGIN(ble_gap_enable_params_t);
+
+ SER_PULL_uint8(&p_struct->periph_conn_count);
+ SER_PULL_uint8(&p_struct->central_conn_count);
+ SER_PULL_uint8(&p_struct->central_sec_count);
+ SER_PULL_COND(&p_struct->p_device_name, ble_gap_device_name_t_dec);
+
+ SER_STRUCT_DEC_END;
+}
+#endif
+
+uint32_t ble_gap_lesc_p256_pk_t_enc(void const * const p_void_struct,
+ uint8_t * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index)
+{
+ SER_STRUCT_ENC_BEGIN(ble_gap_lesc_p256_pk_t);
+ SER_PUSH_uint8array(p_struct->pk, BLE_GAP_LESC_P256_PK_LEN);
+ SER_STRUCT_ENC_END;
+}
+
+uint32_t ble_gap_lesc_p256_pk_t_dec(uint8_t const * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index,
+ void * const p_void_struct)
+{
+ SER_STRUCT_DEC_BEGIN(ble_gap_lesc_p256_pk_t);
+ SER_PULL_uint8array(p_struct->pk, BLE_GAP_LESC_P256_PK_LEN);
+ SER_STRUCT_DEC_END;
+}
+
+uint32_t ble_gap_lesc_dhkey_t_enc(void const * const p_void_struct,
+ uint8_t * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index)
+{
+ SER_STRUCT_ENC_BEGIN(ble_gap_lesc_dhkey_t);
+ SER_PUSH_uint8array(p_struct->key, BLE_GAP_LESC_DHKEY_LEN);
+ SER_STRUCT_ENC_END;
+}
+
+uint32_t ble_gap_lesc_dhkey_t_dec(uint8_t const * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index,
+ void * const p_void_struct)
+{
+ SER_STRUCT_DEC_BEGIN(ble_gap_lesc_dhkey_t);
+ SER_PULL_uint8array(p_struct->key, BLE_GAP_LESC_DHKEY_LEN);
+ SER_STRUCT_DEC_END;
+}
+
+uint32_t ble_gap_lesc_oob_data_t_enc(void const * const p_void_struct,
+ uint8_t * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index)
+{
+ SER_STRUCT_ENC_BEGIN(ble_gap_lesc_oob_data_t);
+
+ SER_PUSH_FIELD(&p_struct->addr, ble_gap_addr_t_enc);
+ SER_PUSH_uint8array(p_struct->r, BLE_GAP_SEC_KEY_LEN);
+ SER_PUSH_uint8array(p_struct->c, BLE_GAP_SEC_KEY_LEN);
+
+ SER_STRUCT_ENC_END;
+}
+
+uint32_t ble_gap_lesc_oob_data_t_dec(uint8_t const * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index,
+ void * const p_void_struct)
+{
+ SER_STRUCT_DEC_BEGIN(ble_gap_lesc_oob_data_t);
+
+ SER_PULL_FIELD(&p_struct->addr, ble_gap_addr_t_dec);
+ SER_PULL_uint8array(p_struct->r, BLE_GAP_SEC_KEY_LEN);
+ SER_PULL_uint8array(p_struct->c, BLE_GAP_SEC_KEY_LEN);
+
+ SER_STRUCT_DEC_END;
+}
+
+uint32_t ble_gap_adv_params_t_enc(void const * const p_void_struct,
+ uint8_t * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index)
+{
+ SER_STRUCT_ENC_BEGIN(ble_gap_adv_params_t);
+#if defined(NRF_SD_BLE_API_VERSION) && NRF_SD_BLE_API_VERSION < 6
+ SER_PUSH_uint8(&p_struct->type);
+ SER_PUSH_COND(p_struct->p_peer_addr, ble_gap_addr_t_enc);
+ SER_PUSH_uint8(&p_struct->fp);
+ SER_PUSH_uint16(&p_struct->interval);
+ SER_PUSH_uint16(&p_struct->timeout);
+ SER_PUSH_FIELD(&p_struct->channel_mask, ble_gap_adv_ch_mask_t_enc);
+#else
+ SER_PUSH_FIELD(&p_struct->properties, ble_gap_adv_properties_t_enc);
+ SER_PUSH_COND(p_struct->p_peer_addr, ble_gap_addr_t_enc);
+ SER_PUSH_uint32(&p_struct->interval);
+ SER_PUSH_uint16(&p_struct->duration);
+ SER_PUSH_uint8(&p_struct->max_adv_evts);
+ SER_PUSH_buf(p_struct->channel_mask, 5);
+ SER_PUSH_uint8(&p_struct->filter_policy);
+ SER_PUSH_uint8(&p_struct->primary_phy);
+ SER_PUSH_uint8(&p_struct->secondary_phy);
+ uint8_t temp = p_struct->set_id | (p_struct->scan_req_notification << 4);
+ SER_PUSH_uint8(&temp);
+
+#endif
+ SER_STRUCT_ENC_END;
+}
+
+uint32_t ble_gap_adv_params_t_dec(uint8_t const * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index,
+ void * const p_void_struct)
+{
+ SER_STRUCT_DEC_BEGIN(ble_gap_adv_params_t);
+
+#if defined(NRF_SD_BLE_API_VERSION) && NRF_SD_BLE_API_VERSION < 6
+ SER_PULL_uint8(&p_struct->type);
+ SER_PULL_COND(&p_struct->p_peer_addr, ble_gap_addr_t_dec);
+ SER_PULL_uint8(&p_struct->fp);
+ SER_PULL_uint16(&p_struct->interval);
+ SER_PULL_uint16(&p_struct->timeout);
+ SER_PULL_FIELD(&p_struct->channel_mask, ble_gap_adv_ch_mask_t_dec);
+#else
+ SER_PULL_FIELD(&p_struct->properties, ble_gap_adv_properties_t_dec);
+ SER_PULL_COND(&p_struct->p_peer_addr, ble_gap_addr_t_dec);
+ SER_PULL_uint32(&p_struct->interval);
+ SER_PULL_uint16(&p_struct->duration);
+ SER_PULL_uint8(&p_struct->max_adv_evts);
+ uint8_t * p_channel_mask = p_struct->channel_mask;
+ SER_PULL_buf((uint8_t **)&p_channel_mask, 5, 5);
+ SER_PULL_uint8(&p_struct->filter_policy);
+ SER_PULL_uint8(&p_struct->primary_phy);
+ SER_PULL_uint8(&p_struct->secondary_phy);
+
+ uint8_t temp;
+ SER_PULL_uint8(&temp);
+ p_struct->set_id = temp & 0x0F;
+ p_struct->scan_req_notification = (temp & 0x10) ? 1 : 0;
+
+#endif
+
+ SER_STRUCT_DEC_END;
+}
+#if defined(NRF_SD_BLE_API_VERSION) && NRF_SD_BLE_API_VERSION < 4
+uint32_t ble_gap_opt_ext_len_t_enc(void const * const p_void_struct,
+ uint8_t * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index)
+{
+ SER_STRUCT_ENC_BEGIN(ble_gap_opt_ext_len_t);
+ SER_PUSH_uint8(&p_struct->rxtx_max_pdu_payload_size);
+ SER_STRUCT_ENC_END;
+}
+
+uint32_t ble_gap_opt_ext_len_t_dec(uint8_t const * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index,
+ void * const p_void_struct)
+{
+ SER_STRUCT_DEC_BEGIN(ble_gap_opt_ext_len_t);
+ SER_PULL_uint8(&p_struct->rxtx_max_pdu_payload_size);
+ SER_STRUCT_DEC_END;
+}
+#endif
+uint32_t ble_gap_opt_auth_payload_timeout_t_enc(void const * const p_void_struct,
+ uint8_t * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index)
+{
+ SER_STRUCT_ENC_BEGIN(ble_gap_opt_auth_payload_timeout_t);
+
+ SER_PUSH_uint16(&p_struct->conn_handle);
+ SER_PUSH_uint16(&p_struct->auth_payload_timeout);
+
+ SER_STRUCT_ENC_END;
+}
+
+uint32_t ble_gap_opt_auth_payload_timeout_t_dec(uint8_t const * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index,
+ void * const p_void_struct)
+{
+ SER_STRUCT_DEC_BEGIN(ble_gap_opt_auth_payload_timeout_t);
+
+ SER_PULL_uint16(&p_struct->conn_handle);
+ SER_PULL_uint16(&p_struct->auth_payload_timeout);
+
+ SER_STRUCT_DEC_END;
+}
+
+#if defined(NRF_SD_BLE_API_VERSION) && NRF_SD_BLE_API_VERSION < 4
+uint32_t ble_gap_device_name_t_enc
+#else
+uint32_t ble_gap_cfg_device_name_t_enc
+#endif
+ (void const * const p_void_struct,
+ uint8_t * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index)
+
+{
+#if defined(NRF_SD_BLE_API_VERSION) && NRF_SD_BLE_API_VERSION < 4
+ SER_STRUCT_ENC_BEGIN(ble_gap_device_name_t);
+#else
+ SER_STRUCT_ENC_BEGIN(ble_gap_cfg_device_name_t);
+#endif
+ /* serializer does not support attributes on stack */
+ if (p_struct->vloc != BLE_GATTS_VLOC_STACK)
+ {
+ err_code = NRF_ERROR_INVALID_PARAM;
+ }
+
+ SER_PUSH_FIELD(&p_struct->write_perm, ble_gap_conn_sec_mode_t_enc);
+
+ uint8_t ser_data = p_struct->vloc & 0x03;
+ SER_PUSH_uint8(&ser_data);
+ SER_PUSH_uint16(&p_struct->current_len);
+ SER_PUSH_uint16(&p_struct->max_len);
+ SER_PUSH_buf(p_struct->p_value, p_struct->current_len);
+
+ SER_STRUCT_ENC_END;
+}
+
+#if defined(NRF_SD_BLE_API_VERSION) && NRF_SD_BLE_API_VERSION < 4
+uint32_t ble_gap_device_name_t_dec
+#else
+uint32_t ble_gap_cfg_device_name_t_dec
+#endif
+ (uint8_t const * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index,
+ void * const p_void_struct)
+{
+#if defined(NRF_SD_BLE_API_VERSION) && NRF_SD_BLE_API_VERSION < 4
+ SER_STRUCT_DEC_BEGIN(ble_gap_device_name_t);
+#else
+ SER_STRUCT_DEC_BEGIN(ble_gap_cfg_device_name_t);
+#endif
+
+ uint16_t value_max_len = p_struct->max_len;
+ uint8_t ser_data;
+ SER_PULL_FIELD(&p_struct->write_perm, ble_gap_conn_sec_mode_t_dec);
+ SER_PULL_uint8(&ser_data);
+ p_struct->vloc = ser_data & 0x03;
+ SER_PULL_uint16(&p_struct->current_len);
+ SER_PULL_uint16(&p_struct->max_len);
+ SER_PULL_buf(&p_struct->p_value,value_max_len, p_struct->current_len);
+
+ SER_STRUCT_DEC_END;
+}
+
+
+
+uint32_t ble_gap_privacy_params_t_enc(void const * const p_void_struct,
+ uint8_t * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index)
+{
+ SER_STRUCT_ENC_BEGIN(ble_gap_privacy_params_t);
+
+ SER_PUSH_uint8(&p_struct->privacy_mode);
+ SER_PUSH_uint8(&p_struct->private_addr_type);
+ SER_PUSH_uint16(&p_struct->private_addr_cycle_s);
+ SER_PUSH_COND(p_struct->p_device_irk, ble_gap_irk_t_enc);
+
+ SER_STRUCT_ENC_END;
+}
+
+uint32_t ble_gap_privacy_params_t_dec(uint8_t const * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index,
+ void * const p_void_struct)
+{
+ SER_STRUCT_DEC_BEGIN(ble_gap_privacy_params_t);
+
+ SER_PULL_uint8(&p_struct->privacy_mode);
+ SER_PULL_uint8(&p_struct->private_addr_type);
+ SER_PULL_uint16(&p_struct->private_addr_cycle_s);
+ SER_PULL_COND(&p_struct->p_device_irk, ble_gap_irk_t_dec);
+
+ SER_STRUCT_DEC_END;
+}
+
+
+
+
+#if NRF_SD_BLE_API_VERSION >= 4
+#ifndef S112
+uint32_t ble_gap_opt_compat_mode_1_t_enc(void const * const p_void_struct,
+ uint8_t * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index)
+{
+ SER_STRUCT_ENC_BEGIN(ble_gap_opt_compat_mode_1_t);
+
+ uint8_t enable = p_struct->enable;
+ SER_PUSH_uint8(&enable);
+
+ SER_STRUCT_ENC_END;
+}
+
+uint32_t ble_gap_opt_compat_mode_1_t_dec(uint8_t const * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index,
+ void * const p_void_struct)
+{
+ SER_STRUCT_DEC_BEGIN(ble_gap_opt_compat_mode_1_t);
+
+ uint8_t enable;
+ SER_PULL_uint8(&enable);
+ p_struct->enable = enable;
+
+ SER_STRUCT_DEC_END;
+}
+#endif //!S112
+
+uint32_t ble_gap_opt_slave_latency_disable_t_enc(void const * const p_void_struct,
+ uint8_t * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index)
+{
+ SER_STRUCT_ENC_BEGIN(ble_gap_opt_slave_latency_disable_t);
+
+ SER_PUSH_uint16(&p_struct->conn_handle);
+ uint8_t disable = p_struct->disable;
+ SER_PUSH_uint8(&disable);
+
+ SER_STRUCT_ENC_END;
+}
+
+uint32_t ble_gap_opt_slave_latency_disable_t_dec(uint8_t const * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index,
+ void * const p_void_struct)
+{
+ SER_STRUCT_DEC_BEGIN(ble_gap_opt_slave_latency_disable_t);
+
+ SER_PULL_uint16(&p_struct->conn_handle);
+ uint8_t disable;
+ SER_PULL_uint8(&disable);
+ p_struct->disable = disable;
+
+ SER_STRUCT_DEC_END;
+}
+
+uint32_t ble_gap_conn_cfg_t_enc(void const * const p_void_struct,
+ uint8_t * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index)
+{
+ SER_STRUCT_ENC_BEGIN(ble_gap_conn_cfg_t);
+
+ SER_PUSH_uint8(&p_struct->conn_count);
+ SER_PUSH_uint16(&p_struct->event_length);
+
+ SER_STRUCT_ENC_END;
+}
+
+uint32_t ble_gap_conn_cfg_t_dec(uint8_t const * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index,
+ void * const p_void_struct)
+{
+ SER_STRUCT_DEC_BEGIN(ble_gap_conn_cfg_t);
+
+ SER_PULL_uint8(&p_struct->conn_count);
+ SER_PULL_uint16(&p_struct->event_length);
+
+ SER_STRUCT_DEC_END;
+}
+
+uint32_t ble_gap_cfg_role_count_t_enc(void const * const p_void_struct,
+ uint8_t * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index)
+{
+ SER_STRUCT_ENC_BEGIN(ble_gap_cfg_role_count_t);
+
+ SER_PUSH_uint8(&p_struct->periph_role_count);
+#ifndef S112
+ SER_PUSH_uint8(&p_struct->central_role_count);
+ SER_PUSH_uint8(&p_struct->central_sec_count);
+#endif //!S112
+#if NRF_SD_BLE_API_VERSION > 5
+ SER_PUSH_uint8(&p_struct->adv_set_count);
+#ifndef S112
+ uint32_t temp = p_struct->qos_channel_survey_role_available;
+ SER_PUSH_uint8(&temp);
+#endif //!S112
+#endif
+ SER_STRUCT_ENC_END;
+}
+
+uint32_t ble_gap_cfg_role_count_t_dec(uint8_t const * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index,
+ void * const p_void_struct)
+{
+ SER_STRUCT_DEC_BEGIN(ble_gap_cfg_role_count_t);
+
+ SER_PULL_uint8(&p_struct->periph_role_count);
+#ifndef S112
+ SER_PULL_uint8(&p_struct->central_role_count);
+ SER_PULL_uint8(&p_struct->central_sec_count);
+#endif //!S112
+#if NRF_SD_BLE_API_VERSION > 5
+ SER_PULL_uint8(&p_struct->adv_set_count);
+#ifndef S112
+ uint8_t temp;
+ SER_PULL_uint8(&temp);
+ p_struct->qos_channel_survey_role_available = temp;
+#endif //!S112
+#endif
+ SER_STRUCT_DEC_END;
+}
+
+#ifndef S112
+uint32_t ble_gap_data_length_params_t_enc(void const * const p_void_struct,
+ uint8_t * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index)
+{
+ SER_STRUCT_ENC_BEGIN(ble_gap_data_length_params_t);
+
+ SER_PUSH_uint16(&p_struct->max_tx_octets);
+ SER_PUSH_uint16(&p_struct->max_rx_octets);
+ SER_PUSH_uint16(&p_struct->max_tx_time_us);
+ SER_PUSH_uint16(&p_struct->max_rx_time_us);
+
+ SER_STRUCT_ENC_END;
+}
+
+uint32_t ble_gap_data_length_params_t_dec(uint8_t const * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index,
+ void * const p_void_struct)
+{
+ SER_STRUCT_DEC_BEGIN(ble_gap_data_length_params_t);
+
+ SER_PULL_uint16(&p_struct->max_tx_octets);
+ SER_PULL_uint16(&p_struct->max_rx_octets);
+ SER_PULL_uint16(&p_struct->max_tx_time_us);
+ SER_PULL_uint16(&p_struct->max_rx_time_us);
+
+ SER_STRUCT_DEC_END;
+}
+
+uint32_t ble_gap_data_length_limitation_t_enc(void const * const p_void_struct,
+ uint8_t * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index)
+{
+ SER_STRUCT_ENC_BEGIN(ble_gap_data_length_limitation_t);
+
+ SER_PUSH_uint16(&p_struct->tx_payload_limited_octets);
+ SER_PUSH_uint16(&p_struct->rx_payload_limited_octets);
+ SER_PUSH_uint16(&p_struct->tx_rx_time_limited_us);
+
+ SER_STRUCT_ENC_END;
+}
+
+uint32_t ble_gap_data_length_limitation_t_dec(uint8_t const * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index,
+ void * const p_void_struct)
+{
+ SER_STRUCT_DEC_BEGIN(ble_gap_data_length_limitation_t);
+
+ SER_PULL_uint16(&p_struct->tx_payload_limited_octets);
+ SER_PULL_uint16(&p_struct->rx_payload_limited_octets);
+ SER_PULL_uint16(&p_struct->tx_rx_time_limited_us);
+
+ SER_STRUCT_DEC_END;
+}
+#endif //!S112
+#endif
+
+#if NRF_SD_BLE_API_VERSION == 4
+
+uint32_t ble_gap_opt_compat_mode_2_t_enc(void const * const p_void_struct,
+ uint8_t * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index)
+{
+ SER_STRUCT_ENC_BEGIN(ble_gap_opt_compat_mode_2_t);
+
+ uint8_t enable = p_struct->enable;
+ SER_PUSH_uint8(&enable);
+
+ SER_STRUCT_ENC_END;
+}
+
+uint32_t ble_gap_opt_compat_mode_2_t_dec(uint8_t const * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index,
+ void * const p_void_struct)
+{
+ SER_STRUCT_DEC_BEGIN(ble_gap_opt_compat_mode_2_t);
+
+ uint8_t enable;
+ SER_PULL_uint8(&enable);
+ p_struct->enable = enable;
+
+ SER_STRUCT_DEC_END;
+}
+
+#endif
+
+#if NRF_SD_BLE_API_VERSION >= 5
+uint32_t ble_gap_phys_t_enc(void const * const p_void_struct,
+ uint8_t * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index)
+{
+ SER_STRUCT_ENC_BEGIN(ble_gap_phys_t);
+
+ SER_PUSH_uint8(&p_struct->tx_phys);
+ SER_PUSH_uint8(&p_struct->rx_phys);
+
+ SER_STRUCT_ENC_END;
+}
+
+uint32_t ble_gap_phys_t_dec(uint8_t const * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index,
+ void * const p_void_struct)
+{
+ SER_STRUCT_DEC_BEGIN(ble_gap_phys_t);
+
+ SER_PULL_uint8(&p_struct->tx_phys);
+ SER_PULL_uint8(&p_struct->rx_phys);
+
+ SER_STRUCT_DEC_END;
+}
+#endif
+
+#if NRF_SD_BLE_API_VERSION > 5
+uint32_t ble_gap_adv_properties_t_enc(void const * const p_void_struct,
+ uint8_t * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index)
+{
+ SER_STRUCT_ENC_BEGIN(ble_gap_adv_properties_t);
+
+ SER_PUSH_uint8(&p_struct->type);
+ uint8_t temp = p_struct->anonymous | (p_struct->include_tx_power << 1);
+ SER_PUSH_uint8(&temp);
+
+ SER_STRUCT_ENC_END;
+}
+
+uint32_t ble_gap_adv_properties_t_dec(uint8_t const * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index,
+ void * const p_void_struct)
+{
+ SER_STRUCT_DEC_BEGIN(ble_gap_adv_properties_t);
+
+ SER_PULL_uint8(&p_struct->type);
+ uint8_t temp;
+ SER_PULL_uint8(&temp);
+ p_struct->anonymous = temp & 0x01;
+ p_struct->include_tx_power = (temp & 0x02) ? 1 : 0;
+
+ SER_STRUCT_DEC_END;
+}
+
+#ifndef S112
+uint32_t ble_gap_adv_report_type_t_enc(void const * const p_void_struct,
+ uint8_t * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index)
+{
+ SER_STRUCT_ENC_BEGIN(ble_gap_adv_report_type_t);
+
+ uint16_t temp =
+ (p_struct->connectable << 0) |
+ (p_struct->scannable << 1) |
+ (p_struct->directed << 2) |
+ (p_struct->scan_response << 3) |
+ (p_struct->extended_pdu << 4) |
+ (p_struct->status << 5) |
+ (p_struct->reserved << 7);
+ SER_PUSH_uint16(&temp);
+
+ SER_STRUCT_ENC_END;
+}
+
+uint32_t ble_gap_adv_report_type_t_dec(uint8_t const * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index,
+ void * const p_void_struct)
+{
+ SER_STRUCT_DEC_BEGIN(ble_gap_adv_report_type_t);
+
+ uint16_t temp;
+ SER_PULL_uint16(&temp);
+ p_struct->connectable = (temp >> 0) & 0x01;
+ p_struct->scannable = (temp >> 1) & 0x01;
+ p_struct->directed = (temp >> 2) & 0x01;
+ p_struct->scan_response = (temp >> 3) & 0x01;
+ p_struct->extended_pdu = (temp >> 4) & 0x01;
+ p_struct->status = (temp >> 5) & 0x03;
+ p_struct->reserved = (temp >> 7) & 0x1FF;
+
+ SER_STRUCT_DEC_END;
+}
+
+uint32_t ble_gap_aux_pointer_t_enc(void const * const p_void_struct,
+ uint8_t * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index)
+{
+ SER_STRUCT_ENC_BEGIN(ble_gap_aux_pointer_t);
+
+ SER_PUSH_uint16(&p_struct->aux_offset);
+ SER_PUSH_uint8(&p_struct->aux_phy);
+
+ SER_STRUCT_ENC_END;
+}
+
+uint32_t ble_gap_aux_pointer_t_dec(uint8_t const * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index,
+ void * const p_void_struct)
+{
+ SER_STRUCT_DEC_BEGIN(ble_gap_aux_pointer_t);
+
+ SER_PULL_uint16(&p_struct->aux_offset);
+ SER_PULL_uint8(&p_struct->aux_phy);
+
+ SER_STRUCT_DEC_END;
+}
+#endif //!S112
+
+uint32_t ble_gap_adv_data_t_enc(void const * const p_void_struct,
+ uint8_t * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index)
+{
+ SER_STRUCT_ENC_BEGIN(ble_gap_adv_data_t);
+
+ SER_PUSH_FIELD(&p_struct->adv_data, ble_data_t_enc);
+ SER_PUSH_FIELD(&p_struct->scan_rsp_data, ble_data_t_enc);
+
+ SER_STRUCT_ENC_END;
+}
+
+uint32_t ble_gap_adv_data_t_dec(uint8_t const * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index,
+ void * const p_void_struct)
+{
+ SER_STRUCT_DEC_BEGIN(ble_gap_adv_data_t);
+
+ SER_PULL_FIELD(&p_struct->adv_data, ble_data_t_dec);
+ SER_PULL_FIELD(&p_struct->scan_rsp_data, ble_data_t_dec);
+
+ SER_STRUCT_DEC_END;
+}
+
+uint32_t ble_gap_evt_adv_set_terminated_t_enc(void const * const p_void_struct,
+ uint8_t * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index)
+{
+ SER_STRUCT_ENC_BEGIN(ble_gap_evt_adv_set_terminated_t);
+
+ SER_PUSH_uint8(&p_struct->reason);
+ SER_PUSH_uint8(&p_struct->adv_handle);
+ SER_PUSH_uint8(&p_struct->num_completed_adv_events);
+ SER_PUSH_uint16(&p_struct->adv_data.adv_data.len);
+ SER_PUSH_COND(&p_struct->adv_data.adv_data.p_data, NULL);
+ SER_PUSH_uint16(&p_struct->adv_data.scan_rsp_data.len);
+ SER_PUSH_COND(&p_struct->adv_data.scan_rsp_data.p_data, NULL);
+
+ SER_STRUCT_ENC_END;
+}
+
+uint32_t ble_gap_evt_adv_set_terminated_t_dec(uint8_t const * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index,
+ void * const p_void_struct)
+{
+ SER_STRUCT_DEC_BEGIN(ble_gap_evt_adv_set_terminated_t);
+
+ SER_PULL_uint8(&p_struct->reason);
+ SER_PULL_uint8(&p_struct->adv_handle);
+ SER_PULL_uint8(&p_struct->num_completed_adv_events);
+ SER_PULL_uint16(&p_struct->adv_data.adv_data.len);
+ SER_PULL_COND(&p_struct->adv_data.adv_data.p_data, NULL);
+ SER_PULL_uint16(&p_struct->adv_data.scan_rsp_data.len);
+ SER_PULL_COND(&p_struct->adv_data.scan_rsp_data.p_data, NULL);
+
+ SER_STRUCT_DEC_END;
+}
+#endif
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/common/struct_ser/ble/ble_gap_struct_serialization.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/common/struct_ser/ble/ble_gap_struct_serialization.h
new file mode 100644
index 0000000..918d6f5
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/common/struct_ser/ble/ble_gap_struct_serialization.h
@@ -0,0 +1,612 @@
+/**
+ * Copyright (c) 2014 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#ifndef BLE_GAP_STRUCT_SERIALIZATION_H__
+#define BLE_GAP_STRUCT_SERIALIZATION_H__
+
+#include "ble_gap.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+uint32_t ble_gap_evt_adv_report_t_enc(void const * const p_void_struct,
+ uint8_t * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index);
+
+uint32_t ble_gap_evt_adv_report_t_dec(uint8_t const * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index,
+ void * const p_void_struct);
+
+uint32_t ble_gap_irk_t_enc(void const * const p_void_struct,
+ uint8_t * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index);
+
+uint32_t ble_gap_irk_t_dec(uint8_t const * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index,
+ void * const p_void_struct);
+
+uint32_t ble_gap_addr_t_enc(void const * const p_void_struct,
+ uint8_t * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index);
+
+uint32_t ble_gap_addr_t_dec(uint8_t const * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index,
+ void * const p_void_struct);
+
+uint32_t ble_gap_sec_levels_t_enc(void const * const p_void_struct,
+ uint8_t * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index);
+
+uint32_t ble_gap_sec_levels_t_dec(uint8_t const * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index,
+ void * const p_void_struct);
+
+uint32_t ble_gap_sec_keys_t_enc(void const * const p_void_struct,
+ uint8_t * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index);
+
+uint32_t ble_gap_sec_keys_t_dec(uint8_t const * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index,
+ void * const p_void_struct);
+
+uint32_t ble_gap_enc_info_t_enc(void const * const p_void_struct,
+ uint8_t * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index);
+
+uint32_t ble_gap_enc_info_t_dec(uint8_t const * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index,
+ void * const p_void_struct);
+
+uint32_t ble_gap_sign_info_t_enc(void const * const p_void_struct,
+ uint8_t * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index);
+
+uint32_t ble_gap_sign_info_t_dec(uint8_t const * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index,
+ void * const p_void_struct);
+
+uint32_t ble_gap_evt_auth_status_t_enc(void const * const p_void_struct,
+ uint8_t * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index);
+
+uint32_t ble_gap_evt_auth_status_t_dec(uint8_t const * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index,
+ void * const p_void_struct);
+
+uint32_t ble_gap_conn_sec_mode_t_enc(void const * const p_void_struct,
+ uint8_t * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index);
+
+uint32_t ble_gap_conn_sec_mode_t_dec(uint8_t const * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index,
+ void * const p_void_struct);
+
+uint32_t ble_gap_conn_sec_t_enc(void const * const p_void_struct,
+ uint8_t * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index);
+
+uint32_t ble_gap_conn_sec_t_dec(uint8_t const * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index,
+ void * const p_void_struct);
+
+uint32_t ble_gap_evt_conn_sec_update_t_enc(void const * const p_void_struct,
+ uint8_t * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index);
+
+uint32_t ble_gap_evt_conn_sec_update_t_dec(uint8_t const * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index,
+ void * const p_void_struct);
+
+uint32_t ble_gap_evt_sec_info_request_t_enc(void const * const p_void_struct,
+ uint8_t * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index);
+
+uint32_t ble_gap_evt_sec_info_request_t_dec(uint8_t const * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index,
+ void * const p_void_struct);
+
+uint32_t ble_gap_evt_connected_t_enc(void const * const p_void_struct,
+ uint8_t * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index);
+
+uint32_t ble_gap_evt_connected_t_dec(uint8_t const * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index,
+ void * const p_void_struct);
+
+uint32_t ble_gap_sec_params_t_enc(void const * const p_void_struct,
+ uint8_t * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index);
+
+uint32_t ble_gap_sec_params_t_dec(uint8_t const * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index,
+ void * const p_void_struct);
+
+uint32_t ble_gap_evt_sec_params_request_t_enc(void const * const p_void_struct,
+ uint8_t * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index);
+
+uint32_t ble_gap_evt_sec_params_request_t_dec(uint8_t const * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index,
+ void * const p_void_struct);
+
+uint32_t ble_gap_conn_params_t_enc(void const * const p_void_struct,
+ uint8_t * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index);
+
+uint32_t ble_gap_conn_params_t_dec(uint8_t const * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index,
+ void * const p_void_struct);
+
+uint32_t ble_gap_evt_conn_param_update_t_enc(void const * const p_void_struct,
+ uint8_t * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index);
+
+uint32_t ble_gap_evt_conn_param_update_t_dec(uint8_t const * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index,
+ void * const p_void_struct);
+
+uint32_t ble_gap_evt_conn_param_update_request_t_enc(void const * const p_void_struct,
+ uint8_t * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index);
+
+uint32_t ble_gap_evt_conn_param_update_request_t_dec(uint8_t const * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index,
+ void * const p_void_struct);
+
+uint32_t ble_gap_evt_disconnected_t_enc(void const * const p_void_struct,
+ uint8_t * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index);
+
+uint32_t ble_gap_evt_disconnected_t_dec(uint8_t const * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index,
+ void * const p_void_struct);
+
+uint32_t ble_gap_scan_params_t_enc(void const * const p_void_struct,
+ uint8_t * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index);
+
+uint32_t ble_gap_scan_params_t_dec(uint8_t const * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index,
+ void * const p_data);
+
+uint32_t ble_gap_master_id_t_enc(void const * const p_void_struct,
+ uint8_t * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index);
+
+uint32_t ble_gap_master_id_t_dec(uint8_t const * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index,
+ void * const p_void_struct);
+
+uint32_t ble_gap_enc_key_t_enc(void const * const p_void_struct,
+ uint8_t * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index);
+
+uint32_t ble_gap_enc_key_t_dec(uint8_t const * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index,
+ void * const p_void_struct);
+
+uint32_t ble_gap_id_key_t_enc(void const * const p_void_struct,
+ uint8_t * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index);
+
+uint32_t ble_gap_id_key_t_dec(uint8_t const * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index,
+ void * const p_void_struct);
+
+uint32_t ble_gap_sec_keyset_t_enc(void const * const p_void_struct,
+ uint8_t * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index);
+
+uint32_t ble_gap_sec_keyset_t_dec(uint8_t const * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index,
+ void * const p_void_struct);
+
+uint32_t ble_gap_evt_sec_request_t_enc(void const * const p_void_struct,
+ uint8_t * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index);
+
+uint32_t ble_gap_evt_sec_request_t_dec(uint8_t const * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index,
+ void * const p_void_struct);
+
+uint32_t ble_gap_sec_kdist_t_enc(void const * const p_void_struct,
+ uint8_t * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index);
+
+uint32_t ble_gap_sec_kdist_t_dec(uint8_t const * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index,
+ void * const p_void_struct);
+
+uint32_t ble_gap_opt_ch_map_t_enc(void const * const p_void_struct,
+ uint8_t * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index);
+
+uint32_t ble_gap_opt_ch_map_t_dec(uint8_t const * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index,
+ void * const p_void_struct);
+
+uint32_t ble_gap_opt_local_conn_latency_t_enc(void const * const p_void_struct,
+ uint8_t * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index);
+
+uint32_t ble_gap_opt_local_conn_latency_t_dec(uint8_t const * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index,
+ void * const p_void_struct);
+
+uint32_t ble_gap_opt_passkey_t_enc(void const * const p_void_struct,
+ uint8_t * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index);
+
+uint32_t ble_gap_opt_passkey_t_dec(uint8_t const * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index,
+ void * const p_void_struct);
+
+uint32_t ble_gap_opt_scan_req_report_t_enc(void const * const p_void_struct,
+ uint8_t * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index);
+
+uint32_t ble_gap_opt_scan_req_report_t_dec(uint8_t const * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index,
+ void * const p_void_struct);
+#if defined(NRF_SD_BLE_API_VERSION) && NRF_SD_BLE_API_VERSION < 4
+uint32_t ble_gap_opt_compat_mode_t_enc(void const * const p_void_struct,
+ uint8_t * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index);
+
+uint32_t ble_gap_opt_compat_mode_t_dec(uint8_t const * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index,
+ void * const p_void_struct);
+#endif
+uint32_t ble_gap_adv_ch_mask_t_enc(void const * const p_void_struct,
+ uint8_t * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index);
+
+uint32_t ble_gap_adv_ch_mask_t_dec(uint8_t const * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index,
+ void * const p_void_struct);
+
+uint32_t ble_gap_enable_params_t_enc(void const * const p_void_struct,
+ uint8_t * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index);
+
+uint32_t ble_gap_enable_params_t_dec(uint8_t const * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index,
+ void * const p_void_struct);
+
+uint32_t ble_gap_lesc_p256_pk_t_enc(void const * const p_void_struct,
+ uint8_t * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index);
+
+uint32_t ble_gap_lesc_p256_pk_t_dec(uint8_t const * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index,
+ void * const p_void_struct);
+
+uint32_t ble_gap_lesc_dhkey_t_enc(void const * const p_void_struct,
+ uint8_t * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index);
+
+uint32_t ble_gap_lesc_dhkey_t_dec(uint8_t const * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index,
+ void * const p_void_struct);
+
+uint32_t ble_gap_lesc_oob_data_t_enc(void const * const p_void_struct,
+ uint8_t * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index);
+
+uint32_t ble_gap_lesc_oob_data_t_dec(uint8_t const * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index,
+ void * const p_void_struct);
+
+uint32_t ble_gap_adv_params_t_enc(void const * const p_void_struct,
+ uint8_t * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index);
+
+uint32_t ble_gap_adv_params_t_dec(uint8_t const * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index,
+ void * const p_void_struct);
+
+#if defined(NRF_SD_BLE_API_VERSION) && NRF_SD_BLE_API_VERSION < 4
+uint32_t ble_gap_opt_ext_len_t_enc(void const * const p_void_struct,
+ uint8_t * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index);
+
+uint32_t ble_gap_opt_ext_len_t_dec(uint8_t const * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index,
+ void * const p_void_struct);
+#endif
+
+uint32_t ble_gap_opt_auth_payload_timeout_t_enc(void const * const p_void_struct,
+ uint8_t * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index);
+
+uint32_t ble_gap_opt_auth_payload_timeout_t_dec(uint8_t const * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index,
+ void * const p_void_struct);
+
+#if defined(NRF_SD_BLE_API_VERSION) && NRF_SD_BLE_API_VERSION < 4
+uint32_t ble_gap_device_name_t_enc(void const * const p_void_struct,
+ uint8_t * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index);
+
+uint32_t ble_gap_device_name_t_dec(uint8_t const * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index,
+ void * const p_void_struct);
+#else
+uint32_t ble_gap_cfg_device_name_t_enc(void const * const p_void_struct,
+ uint8_t * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index);
+
+uint32_t ble_gap_cfg_device_name_t_dec(uint8_t const * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index,
+ void * const p_void_struct);
+#endif
+
+uint32_t ble_gap_privacy_params_t_enc(void const * const p_void_struct,
+ uint8_t * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index);
+
+uint32_t ble_gap_privacy_params_t_dec(uint8_t const * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index,
+ void * const p_void_struct);
+
+#if NRF_SD_BLE_API_VERSION >= 4
+uint32_t ble_gap_opt_compat_mode_1_t_enc(void const * const p_void_struct,
+ uint8_t * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index);
+
+uint32_t ble_gap_opt_compat_mode_1_t_dec(uint8_t const * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index,
+ void * const p_void_struct);
+
+uint32_t ble_gap_opt_compat_mode_2_t_enc(void const * const p_void_struct,
+ uint8_t * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index);
+
+uint32_t ble_gap_opt_compat_mode_2_t_dec(uint8_t const * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index,
+ void * const p_void_struct);
+uint32_t ble_gap_opt_slave_latency_disable_t_enc(void const * const p_void_struct,
+ uint8_t * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index);
+
+uint32_t ble_gap_opt_slave_latency_disable_t_dec(uint8_t const * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index,
+ void * const p_void_struct);
+
+uint32_t ble_gap_conn_cfg_t_enc(void const * const p_void_struct,
+ uint8_t * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index);
+
+uint32_t ble_gap_conn_cfg_t_dec(uint8_t const * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index,
+ void * const p_void_struct);
+
+uint32_t ble_gap_cfg_role_count_t_enc(void const * const p_void_struct,
+ uint8_t * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index);
+
+uint32_t ble_gap_cfg_role_count_t_dec(uint8_t const * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index,
+ void * const p_void_struct);
+
+uint32_t ble_gap_data_length_params_t_enc(void const * const p_void_struct,
+ uint8_t * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index);
+
+uint32_t ble_gap_data_length_params_t_dec(uint8_t const * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index,
+ void * const p_void_struct);
+
+uint32_t ble_gap_data_length_limitation_t_enc(void const * const p_void_struct,
+ uint8_t * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index);
+
+uint32_t ble_gap_data_length_limitation_t_dec(uint8_t const * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index,
+ void * const p_void_struct);
+#endif
+
+#if NRF_SD_BLE_API_VERSION >= 5
+uint32_t ble_gap_phys_t_enc(void const * const p_void_struct,
+ uint8_t * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index);
+
+uint32_t ble_gap_phys_t_dec(uint8_t const * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index,
+ void * const p_void_struct);
+#endif
+
+#if NRF_SD_BLE_API_VERSION > 5
+uint32_t ble_gap_adv_properties_t_enc(void const * const p_void_struct,
+ uint8_t * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index);
+
+uint32_t ble_gap_adv_properties_t_dec(uint8_t const * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index,
+ void * const p_void_struct);
+
+uint32_t ble_gap_adv_report_type_t_enc(void const * const p_void_struct,
+ uint8_t * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index);
+
+uint32_t ble_gap_adv_report_type_t_dec(uint8_t const * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index,
+ void * const p_void_struct);
+
+uint32_t ble_gap_aux_pointer_t_enc(void const * const p_void_struct,
+ uint8_t * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index);
+
+uint32_t ble_gap_aux_pointer_t_dec(uint8_t const * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index,
+ void * const p_void_struct);
+
+uint32_t ble_gap_adv_data_t_enc(void const * const p_void_struct,
+ uint8_t * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index);
+
+uint32_t ble_gap_adv_data_t_dec(uint8_t const * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index,
+ void * const p_void_struct);
+
+uint32_t ble_gap_evt_adv_set_terminated_t_enc(void const * const p_void_struct,
+ uint8_t * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index);
+
+uint32_t ble_gap_evt_adv_set_terminated_t_dec(uint8_t const * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index,
+ void * const p_void_struct);
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // BLE_GAP_STRUCT_SERIALIZATION_H__
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/common/struct_ser/ble/ble_gatt_struct_serialization.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/common/struct_ser/ble/ble_gatt_struct_serialization.c
new file mode 100644
index 0000000..f308ea8
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/common/struct_ser/ble/ble_gatt_struct_serialization.c
@@ -0,0 +1,158 @@
+/**
+ * Copyright (c) 2016 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#include "ble_serialization.h"
+#include "ble_struct_serialization.h"
+#include "ble_gatt_struct_serialization.h"
+#include "cond_field_serialization.h"
+#include "app_util.h"
+#include "ble_gatt.h"
+#include <string.h>
+
+uint32_t ble_gatt_char_props_t_enc(void const * const p_void_struct,
+ uint8_t * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index)
+{
+ SER_STRUCT_ENC_BEGIN(ble_gatt_char_props_t);
+
+ uint8_t ser_data = (p_struct->broadcast & 0x01)
+ | ((p_struct->read & 0x01) << 1)
+ | ((p_struct->write_wo_resp & 0x01) << 2)
+ | ((p_struct->write & 0x01) << 3)
+ | ((p_struct->notify & 0x01) << 4)
+ | ((p_struct->indicate & 0x01) << 5)
+ | ((p_struct->auth_signed_wr & 0x01) << 6);
+ SER_PUSH_uint8(&ser_data);
+
+ SER_STRUCT_ENC_END;
+}
+
+uint32_t ble_gatt_char_props_t_dec(uint8_t const * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index,
+ void * const p_void_struct)
+{
+ SER_STRUCT_DEC_BEGIN(ble_gatt_char_props_t);
+
+ uint8_t ser_data;
+ SER_PULL_uint8(&ser_data);
+ p_struct->broadcast = ser_data & 0x01;
+ p_struct->read = (ser_data >> 1) & 0x01;
+ p_struct->write_wo_resp = (ser_data >> 2) & 0x01;
+ p_struct->write = (ser_data >> 3) & 0x01;
+ p_struct->notify = (ser_data >> 4) & 0x01;
+ p_struct->indicate = (ser_data >> 5) & 0x01;
+ p_struct->auth_signed_wr = (ser_data >> 6) & 0x01;
+
+ SER_STRUCT_DEC_END;
+}
+
+uint32_t ble_gatt_char_ext_props_t_enc(void const * const p_void_struct,
+ uint8_t * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index)
+{
+ SER_STRUCT_ENC_BEGIN(ble_gatt_char_ext_props_t);
+
+ uint8_t ser_data = (p_struct->reliable_wr & 0x01)
+ | ((p_struct->wr_aux & 0x01) << 1);
+ SER_PUSH_uint8(&ser_data);
+
+ SER_STRUCT_ENC_END;
+}
+
+uint32_t ble_gatt_char_ext_props_t_dec(uint8_t const * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index,
+ void * const p_void_struct)
+{
+ SER_STRUCT_DEC_BEGIN(ble_gatt_char_ext_props_t);
+
+ uint8_t ser_data;
+ SER_PULL_uint8(&ser_data);
+ p_struct->reliable_wr = ser_data & 0x01;
+ p_struct->wr_aux = (ser_data >> 1) & 0x01;
+
+ SER_STRUCT_DEC_END;
+}
+
+#if defined(NRF_SD_BLE_API_VERSION) && NRF_SD_BLE_API_VERSION < 4
+uint32_t ble_gatt_enable_params_t_enc(void const * const p_void_struct,
+ uint8_t * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index)
+{
+ SER_STRUCT_ENC_BEGIN(ble_gatt_enable_params_t);
+ SER_PUSH_uint16(&p_struct->att_mtu);
+ SER_STRUCT_ENC_END;
+}
+
+
+uint32_t ble_gatt_enable_params_t_dec(uint8_t const * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index,
+ void * const p_void_struct)
+{
+ SER_STRUCT_DEC_BEGIN(ble_gatt_enable_params_t);
+ SER_PULL_uint16(&p_struct->att_mtu);
+ SER_STRUCT_DEC_END;
+}
+#else
+uint32_t ble_gatt_conn_cfg_t_enc(void const * const p_void_struct,
+ uint8_t * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index)
+{
+ SER_STRUCT_ENC_BEGIN(ble_gatt_conn_cfg_t);
+ SER_PUSH_uint16(&p_struct->att_mtu);
+ SER_STRUCT_ENC_END;
+}
+
+
+uint32_t ble_gatt_conn_cfg_t_dec(uint8_t const * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index,
+ void * const p_void_struct)
+{
+ SER_STRUCT_DEC_BEGIN(ble_gatt_conn_cfg_t);
+ SER_PULL_uint16(&p_struct->att_mtu);
+ SER_STRUCT_DEC_END;
+}
+#endif
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/common/struct_ser/ble/ble_gatt_struct_serialization.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/common/struct_ser/ble/ble_gatt_struct_serialization.h
new file mode 100644
index 0000000..d61eaa7
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/common/struct_ser/ble/ble_gatt_struct_serialization.h
@@ -0,0 +1,94 @@
+/**
+ * Copyright (c) 2016 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#ifndef BLE_GATT_STRUCT_SERIALIZATION_H
+#define BLE_GATT_STRUCT_SERIALIZATION_H
+
+#include "ble_gatt.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+uint32_t ble_gatt_char_props_t_enc(void const * const p_void_struct,
+ uint8_t * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index);
+
+uint32_t ble_gatt_char_props_t_dec(uint8_t const * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index,
+ void * const p_void_struct);
+
+uint32_t ble_gatt_char_ext_props_t_enc(void const * const p_void_struct,
+ uint8_t * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index);
+
+uint32_t ble_gatt_char_ext_props_t_dec(uint8_t const * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index,
+ void * const p_void_struct);
+
+#if defined(NRF_SD_BLE_API_VERSION) && NRF_SD_BLE_API_VERSION < 4
+uint32_t ble_gatt_enable_params_t_enc(void const * const p_void_struct,
+ uint8_t * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index);
+
+uint32_t ble_gatt_enable_params_t_dec(uint8_t const * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index,
+ void * const p_void_struct);
+#else
+uint32_t ble_gatt_conn_cfg_t_enc(void const * const p_void_struct,
+ uint8_t * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index);
+
+uint32_t ble_gatt_conn_cfg_t_dec(uint8_t const * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index,
+ void * const p_void_struct);
+#endif
+#ifdef __cplusplus
+}
+#endif
+
+#endif /*BLE_GATT_STRUCT_SERIALIZATION_H*/
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/common/struct_ser/ble/ble_gattc_struct_serialization.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/common/struct_ser/ble/ble_gattc_struct_serialization.c
new file mode 100644
index 0000000..b1b9db6
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/common/struct_ser/ble/ble_gattc_struct_serialization.c
@@ -0,0 +1,715 @@
+/**
+ * Copyright (c) 2014 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#include "ble_gatt_struct_serialization.h"
+#include "ble_gattc_struct_serialization.h"
+#include "ble_struct_serialization.h"
+#include "ble_serialization.h"
+#include "app_util.h"
+#include "ble_gattc.h"
+#include "cond_field_serialization.h"
+#include <string.h>
+
+uint32_t ble_gattc_evt_char_val_by_uuid_read_rsp_t_enc(void const * const p_void_struct,
+ uint8_t * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index)
+{
+ SER_STRUCT_ENC_BEGIN(ble_gattc_evt_char_val_by_uuid_read_rsp_t);
+
+ SER_PUSH_uint16(&p_struct->count);
+ SER_PUSH_uint16(&p_struct->value_len);
+
+ // Copy the whole packed list.
+ uint16_t list_length = (p_struct->value_len + sizeof(uint16_t)) * p_struct->count;
+ SER_PUSH_uint8array(p_struct->handle_value, list_length);
+
+ SER_STRUCT_ENC_END;
+}
+
+uint32_t ble_gattc_evt_char_val_by_uuid_read_rsp_t_dec(uint8_t const * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index,
+ uint32_t * const p_ext_len,
+ void * const p_void_struct)
+{
+ SER_STRUCT_DEC_BEGIN(ble_gattc_evt_char_val_by_uuid_read_rsp_t);
+
+ SER_PULL_uint16(&p_struct->count);
+ SER_PULL_uint16(&p_struct->value_len);
+
+ uint16_t list_length = (p_struct->value_len + sizeof(uint16_t)) * p_struct->count;
+ SER_ASSERT_LENGTH_LEQ(list_length, *p_ext_len);
+ SER_PULL_uint8array(p_struct->handle_value, list_length);
+ *p_ext_len = list_length;
+
+ SER_STRUCT_DEC_END;
+}
+
+uint32_t ble_gattc_evt_char_vals_read_rsp_t_enc(void const * const p_void_struct,
+ uint8_t * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index)
+{
+ SER_STRUCT_ENC_BEGIN(ble_gattc_evt_char_vals_read_rsp_t);
+
+ SER_PUSH_uint16(&p_struct->len);
+ SER_PUSH_uint8array(p_struct->values, p_struct->len);
+
+ SER_STRUCT_ENC_END;
+}
+
+uint32_t ble_gattc_evt_char_vals_read_rsp_t_dec(uint8_t const * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index,
+ uint32_t * const p_ext_len,
+ void * const p_void_struct)
+{
+ SER_STRUCT_DEC_BEGIN(ble_gattc_evt_char_vals_read_rsp_t);
+
+ SER_PULL_uint16(&p_struct->len);
+
+ SER_ASSERT_LENGTH_LEQ(p_struct->len, *p_ext_len);
+ SER_PULL_uint8array(p_struct->values, p_struct->len);
+ *p_ext_len = p_struct->len;
+
+ SER_STRUCT_DEC_END;
+}
+
+uint32_t ble_gattc_handle_range_t_enc(void const * const p_void_struct,
+ uint8_t * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index)
+{
+ SER_STRUCT_ENC_BEGIN(ble_gattc_handle_range_t);
+
+ SER_PUSH_uint16(&p_struct->start_handle);
+ SER_PUSH_uint16(&p_struct->end_handle);
+
+ SER_STRUCT_ENC_END;
+}
+
+uint32_t ble_gattc_handle_range_t_dec(uint8_t const * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index,
+ void * const p_void_struct)
+{
+ SER_STRUCT_DEC_BEGIN(ble_gattc_handle_range_t);
+
+ SER_PULL_uint16(&p_struct->start_handle);
+ SER_PULL_uint16(&p_struct->end_handle);
+
+ SER_STRUCT_DEC_END;
+}
+
+
+uint32_t ble_gattc_service_t_enc(void const * const p_void_struct,
+ uint8_t * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index)
+{
+ SER_STRUCT_ENC_BEGIN(ble_gattc_service_t);
+
+ SER_PUSH_FIELD(&p_struct->uuid, ble_uuid_t_enc);
+ SER_PUSH_FIELD(&p_struct->handle_range, ble_gattc_handle_range_t_enc);
+
+ SER_STRUCT_ENC_END;
+}
+
+uint32_t ble_gattc_service_t_dec(uint8_t const * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index,
+ void * const p_void_struct)
+{
+ SER_STRUCT_DEC_BEGIN(ble_gattc_service_t);
+
+ SER_PULL_FIELD(&p_struct->uuid, ble_uuid_t_dec);
+ SER_PULL_FIELD(&p_struct->handle_range, ble_gattc_handle_range_t_dec);
+
+ SER_STRUCT_DEC_END;
+}
+
+uint32_t ble_gattc_include_t_enc(void const * const p_void_struct,
+ uint8_t * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index)
+{
+ SER_STRUCT_ENC_BEGIN(ble_gattc_include_t);
+
+ SER_PUSH_uint16(&p_struct->handle);
+ SER_PUSH_FIELD(&p_struct->included_srvc, ble_gattc_service_t_enc);
+
+ SER_STRUCT_ENC_END;
+}
+
+uint32_t ble_gattc_include_t_dec(uint8_t const * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index,
+ void * const p_void_struct)
+{
+ SER_STRUCT_DEC_BEGIN(ble_gattc_include_t);
+
+ SER_PULL_uint16(&p_struct->handle);
+ SER_PULL_FIELD(&p_struct->included_srvc, ble_gattc_service_t_dec);
+
+ SER_STRUCT_DEC_END;
+}
+
+uint32_t ble_gattc_evt_rel_disc_rsp_t_enc(void const * const p_void_struct,
+ uint8_t * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index)
+{
+ SER_STRUCT_ENC_BEGIN(ble_gattc_evt_rel_disc_rsp_t);
+
+ SER_PUSH_uint16(&p_struct->count);
+
+ ble_gattc_include_t * p_include = &(p_struct->includes[0]);
+ uint32_t i;
+
+ for (i = 0; i < p_struct->count; i++)
+ {
+ SER_PUSH_FIELD(p_include, ble_gattc_include_t_enc);
+ ++p_include;
+ }
+
+ SER_STRUCT_ENC_END;
+}
+
+
+
+uint32_t ble_gattc_evt_rel_disc_rsp_t_dec(uint8_t const * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index,
+ uint32_t * const p_ext_len,
+ void * const p_void_struct)
+{
+ SER_STRUCT_DEC_BEGIN(ble_gattc_evt_rel_disc_rsp_t);
+
+ SER_PULL_uint16(&p_struct->count);
+
+ uint32_t data_len = (SUB1(p_struct->count) * sizeof(ble_gattc_include_t));
+ SER_ASSERT_LENGTH_LEQ(data_len, *p_ext_len);
+
+ ble_gattc_include_t * p_include = &(p_struct->includes[0]);
+ uint32_t i;
+
+ for (i = 0; i < p_struct->count; i++)
+ {
+ SER_PULL_FIELD(p_include, ble_gattc_include_t_dec);
+ ++p_include;
+ }
+
+ *p_ext_len = data_len;
+ SER_STRUCT_DEC_END;
+}
+
+uint32_t ble_gattc_write_params_t_enc(void const * const p_void_struct,
+ uint8_t * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index)
+{
+ SER_STRUCT_ENC_BEGIN(ble_gattc_write_params_t);
+
+ SER_PUSH_uint8(&p_struct->write_op);
+ SER_PUSH_uint8(&p_struct->flags);
+ SER_PUSH_uint16(&p_struct->handle);
+ SER_PUSH_uint16(&p_struct->offset);
+ SER_PUSH_len16data(p_struct->p_value, p_struct->len);
+
+ SER_STRUCT_ENC_END;
+}
+
+uint32_t ble_gattc_write_params_t_dec(uint8_t const * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index,
+ void * const p_void_struct)
+{
+ SER_STRUCT_DEC_BEGIN(ble_gattc_write_params_t);
+
+ SER_PULL_uint8(&p_struct->write_op);
+ SER_PULL_uint8(&p_struct->flags);
+ SER_PULL_uint16(&p_struct->handle);
+ SER_PULL_uint16(&p_struct->offset);
+ SER_PULL_len16data((uint8_t **) &p_struct->p_value, &p_struct->len);
+
+ SER_STRUCT_DEC_END;
+}
+
+uint32_t ble_gattc_attr_info16_t_enc(void const * const p_void_struct,
+ uint8_t * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index)
+{
+ SER_STRUCT_ENC_BEGIN(ble_gattc_attr_info16_t);
+
+ SER_PUSH_uint16(&p_struct->handle);
+ SER_PUSH_FIELD(&(p_struct->uuid), ble_uuid_t_enc);
+
+ SER_STRUCT_ENC_END;
+}
+
+uint32_t ble_gattc_attr_info16_t_dec(uint8_t const * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index,
+ void * const p_void_struct)
+{
+ SER_STRUCT_DEC_BEGIN(ble_gattc_attr_info16_t);
+
+ SER_PULL_uint16(&p_struct->handle);
+ SER_PULL_FIELD(&(p_struct->uuid), ble_uuid_t_dec);
+
+ SER_STRUCT_DEC_END;
+}
+
+uint32_t ble_gattc_attr_info128_t_enc(void const * const p_void_struct,
+ uint8_t * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index)
+{
+ SER_STRUCT_ENC_BEGIN(ble_gattc_attr_info128_t);
+
+ SER_PUSH_uint16(&p_struct->handle);
+ SER_PUSH_FIELD(&(p_struct->uuid), ble_uuid128_t_enc);
+
+ SER_STRUCT_ENC_END;
+}
+
+uint32_t ble_gattc_attr_info128_t_dec(uint8_t const * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index,
+ void * const p_void_struct)
+{
+ SER_STRUCT_DEC_BEGIN(ble_gattc_attr_info128_t);
+
+ SER_PULL_uint16(&p_struct->handle);
+ SER_PULL_FIELD(&(p_struct->uuid), ble_uuid128_t_dec);
+
+ SER_STRUCT_DEC_END;
+}
+
+uint32_t ble_gattc_evt_attr_info_disc_rsp_t_enc(void const * const p_void_struct,
+ uint8_t * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index)
+{
+ SER_STRUCT_ENC_BEGIN(ble_gattc_evt_attr_info_disc_rsp_t);
+
+ SER_PUSH_uint16(&p_struct->count);
+ SER_PUSH_uint8(&p_struct->format);
+
+ field_encoder_handler_t fp_encoder = (p_struct->format == BLE_GATTC_ATTR_INFO_FORMAT_16BIT) ?
+ ble_gattc_attr_info16_t_enc : ble_gattc_attr_info128_t_enc;
+
+ uint32_t i;
+ for (i = 0; i < p_struct->count; ++i)
+ {
+ void * uuid_struct;
+ uuid_struct = (p_struct->format == BLE_GATTC_ATTR_INFO_FORMAT_16BIT) ?
+ (void *)&(p_struct->info.attr_info16[i]) : (void *)&(p_struct->info.attr_info128[i]);
+ SER_PUSH_FIELD(uuid_struct, fp_encoder);
+ }
+
+ SER_STRUCT_ENC_END;
+}
+
+uint32_t ble_gattc_evt_attr_info_disc_rsp_t_dec(uint8_t const * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index,
+ uint32_t * const p_ext_len,
+ void * const p_void_struct)
+{
+ SER_STRUCT_DEC_BEGIN(ble_gattc_evt_attr_info_disc_rsp_t);
+
+ SER_PULL_uint16(&p_struct->count);
+ SER_PULL_uint8(&p_struct->format);
+
+ uint32_t i;
+ uint32_t data_len;
+ field_decoder_handler_t fp_decoder;
+ if (p_struct->format == BLE_GATTC_ATTR_INFO_FORMAT_16BIT)
+ {
+ fp_decoder = ble_gattc_attr_info16_t_dec;
+ data_len = (SUB1(p_struct->count) * sizeof(ble_gattc_attr_info16_t));
+ }
+ else
+ {
+ fp_decoder = ble_gattc_attr_info128_t_dec;
+ data_len = (SUB1(p_struct->count) * sizeof(ble_gattc_attr_info128_t));
+ }
+ SER_ASSERT_LENGTH_LEQ(data_len, *p_ext_len);
+
+ for (i = 0; i < p_struct->count; i++)
+ {
+ void * uuid_struct;
+ uuid_struct = (p_struct->format == BLE_GATTC_ATTR_INFO_FORMAT_16BIT) ?
+ (void *)&(p_struct->info.attr_info16[i]) : (void *)&(p_struct->info.attr_info128[i]);
+ SER_PULL_FIELD(uuid_struct, fp_decoder);
+ }
+
+ *p_ext_len = data_len;
+ SER_STRUCT_DEC_END;
+}
+
+uint32_t ble_gattc_char_t_enc(void const * const p_void_struct,
+ uint8_t * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index)
+{
+ SER_STRUCT_ENC_BEGIN(ble_gattc_char_t);
+
+ uint8_t ser_data;
+ SER_PUSH_FIELD(&p_struct->uuid, ble_uuid_t_enc);
+ SER_PUSH_FIELD(&p_struct->char_props, ble_gatt_char_props_t_enc);
+ ser_data = p_struct->char_ext_props & 0x01;
+ SER_PUSH_uint8(&ser_data);
+ SER_PUSH_uint16(&p_struct->handle_decl);
+ SER_PUSH_uint16(&p_struct->handle_value);
+
+ SER_STRUCT_ENC_END;
+}
+
+uint32_t ble_gattc_char_t_dec(uint8_t const * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index,
+ void * const p_void_struct)
+{
+ SER_STRUCT_DEC_BEGIN(ble_gattc_char_t);
+
+ uint8_t ser_data;
+ SER_PULL_FIELD(&p_struct->uuid, ble_uuid_t_dec);
+ SER_PULL_FIELD(&p_struct->char_props, ble_gatt_char_props_t_dec);
+ SER_PULL_uint8(&ser_data);
+ p_struct->char_ext_props = ser_data & 0x01;
+ SER_PULL_uint16(&p_struct->handle_decl);
+ SER_PULL_uint16(&p_struct->handle_value);
+
+ SER_STRUCT_DEC_END;
+}
+
+uint32_t ble_gattc_evt_char_disc_rsp_t_enc(void const * const p_void_struct,
+ uint8_t * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index)
+{
+ SER_STRUCT_ENC_BEGIN(ble_gattc_evt_char_disc_rsp_t);
+
+ SER_PUSH_uint16(&p_struct->count);
+ SER_PUSH_FIELD_ARRAY(p_struct->chars, ble_gattc_char_t_enc, p_struct->count);
+
+ SER_STRUCT_ENC_END;
+}
+
+uint32_t ble_gattc_evt_char_disc_rsp_t_dec(uint8_t const * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index,
+ uint32_t * const p_ext_len,
+ void * const p_void_struct)
+{
+ SER_STRUCT_DEC_BEGIN(ble_gattc_evt_char_disc_rsp_t);
+
+ SER_PULL_uint16(&p_struct->count);
+ uint32_t data_len = (SUB1(p_struct->count) * sizeof(ble_gattc_char_t));
+ SER_ASSERT_LENGTH_LEQ(data_len, *p_ext_len);
+
+ SER_PULL_FIELD_ARRAY(p_struct->chars, ble_gattc_char_t_dec, p_struct->count);
+
+ *p_ext_len = data_len;
+ SER_STRUCT_DEC_END;
+}
+
+uint32_t ble_gattc_desc_t_enc(void const * const p_void_struct,
+ uint8_t * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index)
+{
+ SER_STRUCT_ENC_BEGIN(ble_gattc_desc_t);
+
+ SER_PUSH_uint16(&p_struct->handle);
+ SER_PUSH_FIELD(&p_struct->uuid, ble_uuid_t_enc);
+
+ SER_STRUCT_ENC_END;
+}
+
+uint32_t ble_gattc_desc_t_dec(uint8_t const * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index,
+ void * const p_void_struct)
+{
+ SER_STRUCT_DEC_BEGIN(ble_gattc_desc_t);
+
+ SER_PULL_uint16(&p_struct->handle);
+ SER_PULL_FIELD(&p_struct->uuid, ble_uuid_t_dec);
+
+ SER_STRUCT_DEC_END;
+}
+
+uint32_t ble_gattc_evt_desc_disc_rsp_t_enc(void const * const p_void_struct,
+ uint8_t * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index)
+{
+ SER_STRUCT_ENC_BEGIN(ble_gattc_evt_desc_disc_rsp_t);
+
+ SER_PUSH_uint16(&p_struct->count);
+ SER_PUSH_FIELD_ARRAY(p_struct->descs, ble_gattc_desc_t_enc, p_struct->count);
+
+ SER_STRUCT_ENC_END;
+}
+
+uint32_t ble_gattc_evt_desc_disc_rsp_t_dec(uint8_t const * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index,
+ uint32_t * const p_ext_len,
+ void * const p_void_struct)
+{
+ SER_STRUCT_DEC_BEGIN(ble_gattc_evt_desc_disc_rsp_t);
+
+ SER_PULL_uint16(&p_struct->count);
+ uint32_t data_len = (SUB1(p_struct->count) * sizeof(ble_gattc_desc_t));
+ SER_ASSERT_LENGTH_LEQ(data_len, *p_ext_len);
+
+ SER_PULL_FIELD_ARRAY(p_struct->descs, ble_gattc_desc_t_dec, p_struct->count);
+
+ *p_ext_len = data_len;
+ SER_STRUCT_DEC_END;
+}
+
+uint32_t ble_gattc_evt_hvx_t_enc(void const * const p_void_struct,
+ uint8_t * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index)
+{
+ SER_STRUCT_ENC_BEGIN(ble_gattc_evt_hvx_t);
+
+ SER_PUSH_uint16(&p_struct->handle);
+ SER_PUSH_uint8(&p_struct->type);
+ SER_PUSH_uint16(&p_struct->len);
+ SER_PUSH_uint8array(p_struct->data, p_struct->len);
+
+ SER_STRUCT_ENC_END;
+}
+
+uint32_t ble_gattc_evt_hvx_t_dec(uint8_t const * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index,
+ uint32_t * const p_ext_len,
+ void * const p_void_struct)
+{
+ SER_STRUCT_DEC_BEGIN(ble_gattc_evt_hvx_t);
+
+ SER_PULL_uint16(&p_struct->handle);
+ SER_PULL_uint8(&p_struct->type);
+ SER_PULL_uint16(&p_struct->len);
+
+ uint32_t data_len = (SUB1(p_struct->len));
+ SER_ASSERT_LENGTH_LEQ(data_len, *p_ext_len);
+
+ SER_PULL_uint8array(p_struct->data, p_struct->len);
+
+ *p_ext_len = data_len;
+ SER_STRUCT_DEC_END;
+}
+
+uint32_t ble_gattc_evt_prim_srvc_disc_rsp_t_enc(void const * const p_void_struct,
+ uint8_t * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index)
+{
+ SER_STRUCT_ENC_BEGIN(ble_gattc_evt_prim_srvc_disc_rsp_t);
+
+ SER_PUSH_uint16(&p_struct->count);
+ SER_PUSH_FIELD_ARRAY(p_struct->services, ble_gattc_service_t_enc, p_struct->count);
+
+ SER_STRUCT_ENC_END;
+}
+
+uint32_t ble_gattc_evt_prim_srvc_disc_rsp_t_dec(uint8_t const * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index,
+ uint32_t * const p_ext_len,
+ void * const p_void_struct)
+{
+ SER_STRUCT_DEC_BEGIN(ble_gattc_evt_prim_srvc_disc_rsp_t);
+
+ SER_PULL_uint16(&p_struct->count);
+ uint32_t data_len = (SUB1(p_struct->count) * sizeof(ble_gattc_service_t));
+ SER_ASSERT_LENGTH_LEQ(data_len, *p_ext_len);
+
+ SER_PULL_FIELD_ARRAY(p_struct->services, ble_gattc_service_t_dec, p_struct->count);
+
+ *p_ext_len = data_len;
+ SER_STRUCT_DEC_END;
+}
+
+uint32_t ble_gattc_evt_read_rsp_t_enc(void const * const p_void_struct,
+ uint8_t * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index)
+{
+ SER_STRUCT_ENC_BEGIN(ble_gattc_evt_read_rsp_t);
+
+ SER_PUSH_uint16(&p_struct->handle);
+ SER_PUSH_uint16(&p_struct->offset);
+ SER_PUSH_uint16(&p_struct->len);
+ SER_PUSH_uint8array(p_struct->data, p_struct->len);
+
+ SER_STRUCT_ENC_END;
+}
+
+uint32_t ble_gattc_evt_read_rsp_t_dec(uint8_t const * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index,
+ uint32_t * const p_ext_len,
+ void * const p_void_struct)
+{
+ SER_STRUCT_DEC_BEGIN(ble_gattc_evt_read_rsp_t);
+
+ SER_PULL_uint16(&p_struct->handle);
+ SER_PULL_uint16(&p_struct->offset);
+ SER_PULL_uint16(&p_struct->len);
+
+ uint32_t data_len = (SUB1(p_struct->len));
+ SER_ASSERT_LENGTH_LEQ(data_len, *p_ext_len);
+
+ SER_PULL_uint8array(p_struct->data, p_struct->len);
+
+ *p_ext_len = data_len;
+ SER_STRUCT_DEC_END;
+}
+
+uint32_t ble_gattc_evt_timeout_t_enc(void const * const p_void_struct,
+ uint8_t * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index)
+{
+ SER_STRUCT_ENC_BEGIN(ble_gattc_evt_timeout_t);
+ SER_PUSH_uint8(&p_struct->src);
+ SER_STRUCT_ENC_END;
+}
+
+uint32_t ble_gattc_evt_timeout_t_dec(uint8_t const * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index,
+ void * const p_void_struct)
+{
+ SER_STRUCT_DEC_BEGIN(ble_gattc_evt_timeout_t);
+ SER_PULL_uint8(&p_struct->src);
+ SER_STRUCT_DEC_END;
+}
+
+uint32_t ble_gattc_evt_write_rsp_t_enc(void const * const p_void_struct,
+ uint8_t * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index)
+{
+ SER_STRUCT_ENC_BEGIN(ble_gattc_evt_write_rsp_t);
+
+ SER_PUSH_uint16(&p_struct->handle);
+ SER_PUSH_uint8(&p_struct->write_op);
+ SER_PUSH_uint16(&p_struct->offset);
+ SER_PUSH_uint16(&p_struct->len);
+ SER_PUSH_uint8array(p_struct->data, p_struct->len);
+
+ SER_STRUCT_ENC_END;
+}
+
+uint32_t ble_gattc_evt_write_rsp_t_dec(uint8_t const * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index,
+ uint32_t * const p_ext_len,
+ void * const p_void_struct)
+{
+ SER_STRUCT_DEC_BEGIN(ble_gattc_evt_write_rsp_t);
+
+ SER_PULL_uint16(&p_struct->handle);
+ SER_PULL_uint8(&p_struct->write_op);
+ SER_PULL_uint16(&p_struct->offset);
+ SER_PULL_uint16(&p_struct->len);
+
+ uint32_t data_len = (SUB1(p_struct->len));
+ SER_ASSERT_LENGTH_LEQ(data_len, *p_ext_len);
+
+ SER_PULL_uint8array(p_struct->data, p_struct->len);
+
+ *p_ext_len = data_len;
+ SER_STRUCT_DEC_END;
+}
+
+uint32_t ble_gattc_evt_exchange_mtu_rsp_t_enc(void const * const p_void_struct,
+ uint8_t * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index)
+{
+ SER_STRUCT_ENC_BEGIN(ble_gattc_evt_exchange_mtu_rsp_t);
+ SER_PUSH_uint16(&p_struct->server_rx_mtu);
+ SER_STRUCT_ENC_END;
+}
+
+uint32_t ble_gattc_evt_exchange_mtu_rsp_t_dec(uint8_t const * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index,
+ void * const p_void_struct)
+{
+ SER_STRUCT_DEC_BEGIN(ble_gattc_evt_exchange_mtu_rsp_t);
+ SER_PULL_uint16(&p_struct->server_rx_mtu);
+ SER_STRUCT_DEC_END;
+}
+
+#if NRF_SD_BLE_API_VERSION >= 4
+uint32_t ble_gattc_conn_cfg_t_enc(void const * const p_void_struct,
+ uint8_t * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index)
+{
+ SER_STRUCT_ENC_BEGIN(ble_gattc_conn_cfg_t);
+ SER_PUSH_uint8(&p_struct->write_cmd_tx_queue_size);
+ SER_STRUCT_ENC_END;
+}
+
+uint32_t ble_gattc_conn_cfg_t_dec(uint8_t const * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index,
+ void * const p_void_struct)
+{
+ SER_STRUCT_DEC_BEGIN(ble_gattc_conn_cfg_t);
+ SER_PULL_uint8(&p_struct->write_cmd_tx_queue_size);
+ SER_STRUCT_DEC_END;
+}
+#endif
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/common/struct_ser/ble/ble_gattc_struct_serialization.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/common/struct_ser/ble/ble_gattc_struct_serialization.h
new file mode 100644
index 0000000..f17e58f
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/common/struct_ser/ble/ble_gattc_struct_serialization.h
@@ -0,0 +1,293 @@
+/**
+ * Copyright (c) 2014 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#ifndef BLE_GATTC_STRUCT_SERIALIZATION_H
+#define BLE_GATTC_STRUCT_SERIALIZATION_H
+
+#include "ble_gattc.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+uint32_t ble_gattc_evt_char_val_by_uuid_read_rsp_t_enc(void const * const p_void_struct,
+ uint8_t * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index);
+
+uint32_t ble_gattc_evt_char_val_by_uuid_read_rsp_t_dec(uint8_t const * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index,
+ uint32_t * const p_ext_len,
+ void * const p_void_struct);
+
+uint32_t ble_gattc_evt_char_vals_read_rsp_t_enc(void const * const p_void_struct,
+ uint8_t * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index);
+
+uint32_t ble_gattc_evt_char_vals_read_rsp_t_dec(uint8_t const * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index,
+ uint32_t * const p_ext_len,
+ void * const p_void_struct);
+
+uint32_t ble_gattc_handle_range_t_enc(void const * const p_void_struct,
+ uint8_t * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index);
+
+uint32_t ble_gattc_handle_range_t_dec(uint8_t const * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index,
+ void * const p_void_struct);
+
+uint32_t ble_gattc_service_t_enc(void const * const p_void_struct,
+ uint8_t * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index);
+
+uint32_t ble_gattc_service_t_dec(uint8_t const * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index,
+ void * const p_void_struct);
+
+uint32_t ble_gattc_include_t_enc(void const * const p_void_struct,
+ uint8_t * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index);
+
+uint32_t ble_gattc_include_t_dec(uint8_t const * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index,
+ void * const p_void_struct);
+
+uint32_t ble_gattc_evt_rel_disc_rsp_t_enc(void const * const p_void_struct,
+ uint8_t * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index);
+
+uint32_t ble_gattc_evt_rel_disc_rsp_t_dec(uint8_t const * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index,
+ uint32_t * const p_ext_len,
+ void * const p_void_struct);
+
+uint32_t ble_gattc_write_params_t_enc(void const * const p_void_struct,
+ uint8_t * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index);
+
+uint32_t ble_gattc_write_params_t_dec(uint8_t const * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index,
+ void * const p_void_struct);
+
+uint32_t ble_gattc_attr_info16_t_enc(void const * const p_void_struct,
+ uint8_t * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index);
+
+uint32_t ble_gattc_attr_info16_t_dec(uint8_t const * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index,
+ void * const p_void_struct);
+
+uint32_t ble_gattc_attr_info128_t_enc(void const * const p_void_struct,
+ uint8_t * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index);
+
+uint32_t ble_gattc_attr_info128_t_dec(uint8_t const * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index,
+ void * const p_void_struct);
+
+uint32_t ble_gattc_evt_attr_info_disc_rsp_t_enc(void const * const p_void_struct,
+ uint8_t * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index);
+
+uint32_t ble_gattc_evt_attr_info_disc_rsp_t_dec(uint8_t const * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index,
+ uint32_t * const p_ext_len,
+ void * const p_void_struct);
+
+uint32_t ble_gatt_char_props_t_enc(void const * const p_void_struct,
+ uint8_t * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index);
+
+uint32_t ble_gatt_char_props_t_dec(uint8_t const * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index,
+ void * const p_void_struct);
+
+uint32_t ble_gatt_char_ext_props_t_enc(void const * const p_void_struct,
+ uint8_t * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index);
+
+uint32_t ble_gatt_char_ext_props_t_dec(uint8_t const * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index,
+ void * const p_void_struct);
+
+uint32_t ble_gattc_char_t_enc(void const * const p_void_struct,
+ uint8_t * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index);
+
+uint32_t ble_gattc_char_t_dec(uint8_t const * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index,
+ void * const p_void_struct);
+
+uint32_t ble_gattc_evt_char_disc_rsp_t_enc(void const * const p_void_struct,
+ uint8_t * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index);
+
+uint32_t ble_gattc_evt_char_disc_rsp_t_dec(uint8_t const * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index,
+ uint32_t * const p_ext_len,
+ void * const p_void_struct);
+
+uint32_t ble_gattc_desc_t_enc(void const * const p_void_struct,
+ uint8_t * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index);
+
+uint32_t ble_gattc_desc_t_dec(uint8_t const * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index,
+ void * const p_void_struct);
+
+uint32_t ble_gattc_evt_desc_disc_rsp_t_enc(void const * const p_void_struct,
+ uint8_t * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index);
+
+uint32_t ble_gattc_evt_desc_disc_rsp_t_dec(uint8_t const * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index,
+ uint32_t * const p_ext_len,
+ void * const p_void_struct);
+
+uint32_t ble_gattc_evt_hvx_t_enc(void const * const p_void_struct,
+ uint8_t * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index);
+
+uint32_t ble_gattc_evt_hvx_t_dec(uint8_t const * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index,
+ uint32_t * const p_ext_len,
+ void * const p_void_struct);
+
+uint32_t ble_gattc_evt_prim_srvc_disc_rsp_t_enc(void const * const p_void_struct,
+ uint8_t * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index);
+
+uint32_t ble_gattc_evt_prim_srvc_disc_rsp_t_dec(uint8_t const * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index,
+ uint32_t * const p_ext_len,
+ void * const p_void_struct);
+
+uint32_t ble_gattc_evt_read_rsp_t_enc(void const * const p_void_struct,
+ uint8_t * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index);
+
+uint32_t ble_gattc_evt_read_rsp_t_dec(uint8_t const * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index,
+ uint32_t * const p_ext_len,
+ void * const p_void_struct);
+
+uint32_t ble_gattc_evt_timeout_t_enc(void const * const p_void_struct,
+ uint8_t * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index);
+
+uint32_t ble_gattc_evt_timeout_t_dec(uint8_t const * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index,
+ void * const p_void_struct);
+
+uint32_t ble_gattc_evt_write_rsp_t_enc(void const * const p_void_struct,
+ uint8_t * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index);
+
+uint32_t ble_gattc_evt_write_rsp_t_dec(uint8_t const * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index,
+ uint32_t * const p_ext_len,
+ void * const p_void_struct);
+
+uint32_t ble_gattc_evt_exchange_mtu_rsp_t_enc(void const * const p_void_struct,
+ uint8_t * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index);
+
+uint32_t ble_gattc_evt_exchange_mtu_rsp_t_dec(uint8_t const * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index,
+ void * const p_void_struct);
+#if NRF_SD_BLE_API_VERSION >= 4
+uint32_t ble_gattc_conn_cfg_t_enc(void const * const p_void_struct,
+ uint8_t * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index);
+
+uint32_t ble_gattc_conn_cfg_t_dec(uint8_t const * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index,
+ void * const p_void_struct);
+#endif
+#ifdef __cplusplus
+}
+#endif
+
+#endif /*BLE_GATTC_STRUCT_SERIALIZATION_H*/
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/common/struct_ser/ble/ble_gatts_struct_serialization.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/common/struct_ser/ble/ble_gatts_struct_serialization.c
new file mode 100644
index 0000000..476a11d
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/common/struct_ser/ble/ble_gatts_struct_serialization.c
@@ -0,0 +1,689 @@
+/**
+ * Copyright (c) 2014 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#include "ble_gatt_struct_serialization.h"
+#include "ble_gatts_struct_serialization.h"
+#include "ble_gap_struct_serialization.h"
+#include "ble_struct_serialization.h"
+#include "ble_serialization.h"
+#include "app_util.h"
+#include "ble_gatts.h"
+#include "cond_field_serialization.h"
+#include <string.h>
+
+uint32_t ble_gatts_char_pf_t_enc(void const * const p_void_struct,
+ uint8_t * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index)
+{
+ SER_STRUCT_ENC_BEGIN(ble_gatts_char_pf_t);
+
+ SER_PUSH_uint8(&p_struct->format);
+ SER_PUSH_int8(&p_struct->exponent);
+ SER_PUSH_uint16(&p_struct->unit);
+ SER_PUSH_uint8(&p_struct->name_space);
+ SER_PUSH_uint16(&p_struct->desc);
+
+ SER_STRUCT_ENC_END;
+}
+
+uint32_t ble_gatts_char_pf_t_dec(uint8_t const * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index,
+ void * const p_void_struct)
+{
+ SER_STRUCT_DEC_BEGIN(ble_gatts_char_pf_t);
+
+ SER_PULL_uint8(&p_struct->format);
+ SER_PULL_int8(&p_struct->exponent);
+ SER_PULL_uint16(&p_struct->unit);
+ SER_PULL_uint8(&p_struct->name_space);
+ SER_PULL_uint16(&p_struct->desc);
+
+ SER_STRUCT_DEC_END;
+}
+
+uint32_t ble_gatts_attr_md_t_enc(void const * const p_void_struct,
+ uint8_t * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index)
+{
+ SER_STRUCT_ENC_BEGIN(ble_gatts_attr_md_t);
+
+ SER_PUSH_FIELD(&p_struct->read_perm, ble_gap_conn_sec_mode_t_enc);
+ SER_PUSH_FIELD(&p_struct->write_perm, ble_gap_conn_sec_mode_t_enc);
+ uint8_t ser_data = (p_struct->vlen & 0x01)
+ | ((p_struct->vloc & 0x03) << 1)
+ | ((p_struct->rd_auth & 0x01) << 3)
+ | ((p_struct->wr_auth & 0x01) << 4);
+ SER_PUSH_uint8(&ser_data);
+
+ // Serializer does not support attributes on stack.
+ if (p_struct->vloc != BLE_GATTS_VLOC_STACK)
+ {
+ err_code = NRF_ERROR_INVALID_PARAM;
+ }
+
+ SER_STRUCT_ENC_END;
+}
+
+uint32_t ble_gatts_attr_md_t_dec(uint8_t const * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index,
+ void * const p_void_struct)
+{
+ SER_STRUCT_DEC_BEGIN(ble_gatts_attr_md_t);
+
+ uint8_t ser_data;
+ SER_PULL_FIELD(&p_struct->read_perm, ble_gap_conn_sec_mode_t_dec);
+ SER_PULL_FIELD(&p_struct->write_perm, ble_gap_conn_sec_mode_t_dec);
+ SER_PULL_uint8(&ser_data);
+
+ p_struct->vlen = ser_data & 0x01;
+ p_struct->vloc = (ser_data >> 1) & 0x03;
+ p_struct->rd_auth = (ser_data >> 3) & 0x01;
+ p_struct->wr_auth = (ser_data >> 4) & 0x01;
+
+ SER_STRUCT_DEC_END;
+}
+
+uint32_t ble_gatts_char_md_t_enc(void const * const p_void_struct,
+ uint8_t * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index)
+{
+ SER_STRUCT_ENC_BEGIN(ble_gatts_char_md_t);
+
+ SER_PUSH_FIELD(&p_struct->char_props, ble_gatt_char_props_t_enc);
+ SER_PUSH_FIELD(&p_struct->char_ext_props, ble_gatt_char_ext_props_t_enc);
+ SER_PUSH_uint16(&p_struct->char_user_desc_max_size);
+ SER_ERROR_CHECK(p_struct->char_user_desc_size <= BLE_GATTS_VAR_ATTR_LEN_MAX,
+ NRF_ERROR_INVALID_PARAM);
+ SER_PUSH_len16data(p_struct->p_char_user_desc, p_struct->char_user_desc_size);
+ SER_PUSH_COND(p_struct->p_char_pf, ble_gatts_char_pf_t_enc);
+ SER_PUSH_COND(p_struct->p_user_desc_md, ble_gatts_attr_md_t_enc);
+ SER_PUSH_COND(p_struct->p_cccd_md, ble_gatts_attr_md_t_enc);
+ SER_PUSH_COND(p_struct->p_sccd_md, ble_gatts_attr_md_t_enc);
+
+ SER_STRUCT_ENC_END;
+}
+
+uint32_t ble_gatts_char_md_t_dec(uint8_t const * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index,
+ void * const p_void_struct)
+{
+ SER_STRUCT_DEC_BEGIN(ble_gatts_char_md_t);
+
+ SER_PULL_FIELD(&p_struct->char_props, ble_gatt_char_props_t_dec);
+ SER_PULL_FIELD(&p_struct->char_ext_props, ble_gatt_char_ext_props_t_dec);
+ SER_PULL_uint16(&p_struct->char_user_desc_max_size);
+#if defined(NRF_SD_BLE_API_VERSION) && NRF_SD_BLE_API_VERSION < 4
+ SER_PULL_len16data(&p_struct->p_char_user_desc, &p_struct->char_user_desc_size);
+#else
+ SER_PULL_len16data((uint8_t * * )&p_struct->p_char_user_desc, &p_struct->char_user_desc_size);
+#endif
+ SER_PULL_COND(&p_struct->p_char_pf, ble_gatts_char_pf_t_dec);
+ SER_PULL_COND(&p_struct->p_user_desc_md, ble_gatts_attr_md_t_dec);
+ SER_PULL_COND(&p_struct->p_cccd_md, ble_gatts_attr_md_t_dec);
+ SER_PULL_COND(&p_struct->p_sccd_md, ble_gatts_attr_md_t_dec);
+
+ SER_STRUCT_ENC_END;
+}
+
+uint32_t ble_gatts_attr_t_enc(void const * const p_void_struct,
+ uint8_t * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index)
+{
+ SER_STRUCT_ENC_BEGIN(ble_gatts_attr_t);
+
+ SER_PUSH_COND(p_struct->p_uuid, ble_uuid_t_enc);
+ SER_PUSH_COND(p_struct->p_attr_md, ble_gatts_attr_md_t_enc);
+ SER_PUSH_uint16(&p_struct->init_offs);
+ SER_PUSH_uint16(&p_struct->max_len);
+ SER_ERROR_CHECK(p_struct->init_len <= BLE_GATTS_VAR_ATTR_LEN_MAX, NRF_ERROR_INVALID_PARAM);
+ SER_PUSH_len16data(p_struct->p_value, p_struct->init_len);
+
+ SER_STRUCT_ENC_END;
+}
+
+uint32_t ble_gatts_attr_t_dec(uint8_t const * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index,
+ void * const p_void_struct)
+{
+ SER_STRUCT_DEC_BEGIN(ble_gatts_attr_t);
+
+ SER_PULL_COND(&p_struct->p_uuid, ble_uuid_t_dec);
+ SER_PULL_COND(&p_struct->p_attr_md, ble_gatts_attr_md_t_dec);
+ SER_PULL_uint16(&p_struct->init_offs);
+ SER_PULL_uint16(&p_struct->max_len);
+ SER_PULL_len16data(&p_struct->p_value, &p_struct->init_len);
+
+ SER_STRUCT_DEC_END;
+}
+
+uint32_t ble_gatts_char_handles_t_enc(void const * const p_void_struct,
+ uint8_t * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index)
+{
+ SER_STRUCT_ENC_BEGIN(ble_gatts_char_handles_t);
+
+ SER_PUSH_uint16(&p_struct->value_handle);
+ SER_PUSH_uint16(&p_struct->user_desc_handle);
+ SER_PUSH_uint16(&p_struct->cccd_handle);
+ SER_PUSH_uint16(&p_struct->sccd_handle);
+
+ SER_STRUCT_ENC_END;
+}
+
+uint32_t ble_gatts_char_handles_t_dec(uint8_t const * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index,
+ void * const p_void_struct)
+{
+ SER_STRUCT_DEC_BEGIN(ble_gatts_char_handles_t);
+
+ SER_PULL_uint16(&p_struct->value_handle);
+ SER_PULL_uint16(&p_struct->user_desc_handle);
+ SER_PULL_uint16(&p_struct->cccd_handle);
+ SER_PULL_uint16(&p_struct->sccd_handle);
+
+ SER_STRUCT_DEC_END;
+}
+
+uint32_t ble_gatts_hvx_params_t_enc(void const * const p_void_struct,
+ uint8_t * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index)
+{
+ SER_STRUCT_ENC_BEGIN(ble_gatts_hvx_params_t);
+
+ SER_PUSH_uint16(&p_struct->handle);
+ SER_PUSH_uint8(&p_struct->type);
+ SER_PUSH_uint16(&p_struct->offset);
+ SER_PUSH_COND(p_struct->p_len, uint16_t_enc);
+ if (p_struct->p_len)
+ {
+ SER_PUSH_buf(p_struct->p_data, *p_struct->p_len);
+ }
+
+ SER_STRUCT_ENC_END;
+}
+
+uint32_t ble_gatts_hvx_params_t_dec(uint8_t const * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index,
+ void * const p_void_struct)
+{
+ SER_STRUCT_DEC_BEGIN(ble_gatts_hvx_params_t);
+
+ SER_PULL_uint16(&p_struct->handle);
+ SER_PULL_uint8(&p_struct->type);
+ SER_PULL_uint16(&p_struct->offset);
+ SER_PULL_COND(&p_struct->p_len, uint16_t_dec);
+ if (p_struct->p_len)
+ {
+#if defined(NRF_SD_BLE_API_VERSION) && NRF_SD_BLE_API_VERSION < 4
+ SER_PULL_buf(&p_struct->p_data, *p_struct->p_len, *p_struct->p_len);
+#else
+ SER_PULL_buf((uint8_t**)&p_struct->p_data, *p_struct->p_len, *p_struct->p_len);
+#endif
+ }
+
+ SER_STRUCT_DEC_END;
+}
+
+uint32_t ble_gatts_evt_write_t_enc(void const * const p_void_struct,
+ uint8_t * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index)
+{
+ SER_STRUCT_ENC_BEGIN(ble_gatts_evt_write_t);
+
+ SER_PUSH_uint16(&p_struct->handle);
+ SER_PUSH_FIELD(&p_struct->uuid, ble_uuid_t_enc);
+ SER_PUSH_uint8(&p_struct->op);
+ SER_PUSH_uint8(&p_struct->auth_required);
+ SER_PUSH_uint16(&p_struct->offset);
+ SER_PUSH_uint16(&p_struct->len);
+ SER_PUSH_uint8array(p_struct->data, p_struct->len);
+
+ SER_STRUCT_ENC_END;
+}
+
+uint32_t ble_gatts_evt_write_t_dec(uint8_t const * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index,
+ uint32_t * const p_ext_len,
+ void * const p_void_struct)
+{
+ SER_STRUCT_DEC_BEGIN(ble_gatts_evt_write_t);
+
+ SER_PULL_uint16(&p_struct->handle);
+ SER_PULL_FIELD(&p_struct->uuid, ble_uuid_t_dec);
+ SER_PULL_uint8(&p_struct->op);
+ SER_PULL_uint8(&p_struct->auth_required);
+ SER_PULL_uint16(&p_struct->offset);
+ SER_PULL_uint16(&p_struct->len);
+
+ // Data field is defined as 1-element array, so the first element
+ // is always allocated in the structure.
+ SER_ASSERT_LENGTH_LEQ(p_struct->len, *p_ext_len + 1);
+ SER_PULL_uint8array(p_struct->data, p_struct->len);
+ *p_ext_len = (p_struct->len > 1) ? p_struct->len - 1 : 0;
+
+ SER_STRUCT_ENC_END;
+}
+
+uint32_t ble_gatts_evt_read_t_enc(void const * const p_void_struct,
+ uint8_t * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index)
+{
+ SER_STRUCT_ENC_BEGIN(ble_gatts_evt_read_t);
+
+ SER_PUSH_uint16(&p_struct->handle);
+ SER_PUSH_FIELD(&p_struct->uuid, ble_uuid_t_enc);
+ SER_PUSH_uint16(&p_struct->offset);
+
+ SER_STRUCT_ENC_END;
+}
+
+uint32_t ble_gatts_evt_read_t_dec(uint8_t const * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index,
+ void * const p_void_struct)
+{
+ SER_STRUCT_DEC_BEGIN(ble_gatts_evt_read_t);
+
+ SER_PULL_uint16(&p_struct->handle);
+ SER_PULL_FIELD(&p_struct->uuid, ble_uuid_t_dec);
+ SER_PULL_uint16(&p_struct->offset);
+
+ SER_STRUCT_DEC_END;
+}
+
+uint32_t ble_gatts_evt_rw_authorize_request_t_enc(void const * const p_void_struct,
+ uint8_t * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index)
+{
+ SER_STRUCT_ENC_BEGIN(ble_gatts_evt_rw_authorize_request_t);
+
+ SER_PUSH_uint8(&p_struct->type);
+
+ switch (p_struct->type)
+ {
+ case BLE_GATTS_AUTHORIZE_TYPE_READ:
+ SER_PUSH_FIELD(&p_struct->request.read, ble_gatts_evt_read_t_enc);
+ break;
+
+ case BLE_GATTS_AUTHORIZE_TYPE_WRITE:
+ SER_PUSH_FIELD(&p_struct->request.write, ble_gatts_evt_write_t_enc);
+ break;
+
+ default:
+ case BLE_GATTS_AUTHORIZE_TYPE_INVALID:
+ err_code = NRF_ERROR_INVALID_PARAM;
+ break;
+ }
+
+ SER_STRUCT_ENC_END;
+}
+
+uint32_t ble_gatts_evt_rw_authorize_request_t_dec(uint8_t const * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index,
+ uint32_t * const p_ext_len,
+ void * const p_void_struct)
+{
+ SER_STRUCT_DEC_BEGIN(ble_gatts_evt_rw_authorize_request_t);
+
+ SER_PULL_uint8(&p_struct->type);
+
+ switch (p_struct->type)
+ {
+ case BLE_GATTS_AUTHORIZE_TYPE_READ:
+ SER_PULL_FIELD(&p_struct->request.read, ble_gatts_evt_read_t_dec);
+ break;
+
+ case BLE_GATTS_AUTHORIZE_TYPE_WRITE:
+ err_code = ble_gatts_evt_write_t_dec(p_buf,
+ buf_len,
+ p_index,
+ p_ext_len,
+ &p_struct->request.write);
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code);
+ break;
+
+ default:
+ case BLE_GATTS_AUTHORIZE_TYPE_INVALID:
+ return NRF_ERROR_INVALID_DATA;
+ }
+
+ SER_STRUCT_ENC_END;
+}
+
+uint32_t ble_gatts_authorize_params_t_enc(void const * const p_void_struct,
+ uint8_t * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index)
+{
+ SER_STRUCT_ENC_BEGIN(ble_gatts_authorize_params_t);
+
+ uint8_t ser_data = p_struct->update & 0x01;
+ SER_PUSH_uint16(&p_struct->gatt_status);
+ SER_PUSH_uint8(&ser_data);
+ SER_PUSH_uint16(&p_struct->offset);
+ SER_PUSH_len16data(p_struct->p_data, p_struct->len);
+
+ SER_STRUCT_ENC_END;
+}
+
+uint32_t ble_gatts_authorize_params_t_dec(uint8_t const * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index,
+ void * const p_void_struct)
+{
+ SER_STRUCT_DEC_BEGIN(ble_gatts_authorize_params_t);
+
+ uint8_t ser_data;
+ SER_PULL_uint16(&p_struct->gatt_status);
+ SER_PULL_uint8(&ser_data);
+ SER_PULL_uint16(&p_struct->offset);
+ SER_PULL_len16data((uint8_t **) &p_struct->p_data, &p_struct->len);
+
+ p_struct->update = ser_data & 0x01;
+
+ SER_STRUCT_DEC_END;
+}
+
+uint32_t ble_gatts_rw_authorize_reply_params_t_enc(void const * const p_void_struct,
+ uint8_t * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index)
+{
+ SER_STRUCT_ENC_BEGIN(ble_gatts_rw_authorize_reply_params_t);
+
+ SER_PUSH_uint8(&p_struct->type);
+ if (p_struct->type == BLE_GATTS_AUTHORIZE_TYPE_READ)
+ {
+ SER_PUSH_FIELD(&p_struct->params.read, ble_gatts_authorize_params_t_enc);
+ }
+ else if (p_struct->type == BLE_GATTS_AUTHORIZE_TYPE_WRITE)
+ {
+ SER_PUSH_FIELD(&p_struct->params.write, ble_gatts_authorize_params_t_enc);
+ }
+ else
+ {
+ return NRF_ERROR_INVALID_PARAM;
+ }
+
+ SER_STRUCT_ENC_END;
+}
+
+uint32_t ble_gatts_rw_authorize_reply_params_t_dec(uint8_t const * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index,
+ void * const p_void_struct)
+{
+ SER_STRUCT_DEC_BEGIN(ble_gatts_rw_authorize_reply_params_t);
+
+ SER_PULL_uint8(&p_struct->type);
+ if (p_struct->type == BLE_GATTS_AUTHORIZE_TYPE_READ)
+ {
+ SER_PULL_FIELD(&p_struct->params.read, ble_gatts_authorize_params_t_dec);
+ }
+ else if (p_struct->type == BLE_GATTS_AUTHORIZE_TYPE_WRITE)
+ {
+ SER_PULL_FIELD(&p_struct->params.write, ble_gatts_authorize_params_t_dec);
+ }
+ else
+ {
+ return NRF_ERROR_INVALID_PARAM;
+ }
+
+ SER_STRUCT_DEC_END;
+}
+#if defined(NRF_SD_BLE_API_VERSION) && NRF_SD_BLE_API_VERSION < 4
+uint32_t ble_gatts_enable_params_t_enc(void const * const p_void_struct,
+ uint8_t * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index)
+{
+ SER_STRUCT_ENC_BEGIN(ble_gatts_enable_params_t);
+
+ uint8_t ser_data = p_struct->service_changed & 0x01;
+ SER_PUSH_uint8(&ser_data);
+ SER_PUSH_uint32(&p_struct->attr_tab_size);
+
+ SER_STRUCT_ENC_END;
+}
+
+uint32_t ble_gatts_enable_params_t_dec(uint8_t const * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index,
+ void * const p_void_struct)
+{
+ SER_STRUCT_DEC_BEGIN(ble_gatts_enable_params_t);
+
+ uint8_t ser_data;
+ SER_PULL_uint8(&ser_data);
+ SER_PULL_uint32(&p_struct->attr_tab_size);
+
+ p_struct->service_changed = ser_data & 0x01;
+
+ SER_STRUCT_DEC_END;
+}
+#endif
+
+uint32_t ble_gatts_value_t_enc(void const * const p_void_struct,
+ uint8_t * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index)
+{
+ SER_STRUCT_ENC_BEGIN(ble_gatts_value_t);
+
+ SER_PUSH_uint16(&p_struct->offset);
+ SER_PUSH_len16data(p_struct->p_value, p_struct->len);
+
+ SER_STRUCT_ENC_END;
+}
+
+uint32_t ble_gatts_value_t_dec(uint8_t const * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index,
+ void * const p_void_struct)
+{
+ SER_STRUCT_DEC_BEGIN(ble_gatts_value_t);
+
+ SER_PULL_uint16(&p_struct->offset);
+ SER_PULL_len16data(&p_struct->p_value, &p_struct->len);
+
+ SER_STRUCT_DEC_END;
+}
+
+uint32_t ble_gatts_evt_exchange_mtu_request_t_enc(void const * const p_void_struct,
+ uint8_t * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index)
+{
+ SER_STRUCT_ENC_BEGIN(ble_gatts_evt_exchange_mtu_request_t);
+ SER_PUSH_uint16(&p_struct->client_rx_mtu);
+ SER_STRUCT_ENC_END;
+}
+
+uint32_t ble_gatts_evt_exchange_mtu_request_t_dec(uint8_t const * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index,
+ void * const p_void_struct)
+{
+ SER_STRUCT_DEC_BEGIN(ble_gatts_evt_exchange_mtu_request_t);
+ SER_PULL_uint16(&p_struct->client_rx_mtu);
+ SER_STRUCT_DEC_END;
+}
+
+uint32_t ble_gatts_evt_hvc_t_enc(void const * const p_void_struct,
+ uint8_t * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index)
+{
+ SER_STRUCT_ENC_BEGIN(ble_gatts_evt_hvc_t);
+ SER_PUSH_uint16(&p_struct->handle);
+ SER_STRUCT_ENC_END;
+}
+
+uint32_t ble_gatts_evt_hvc_t_dec(uint8_t const * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index,
+ void * const p_void_struct)
+{
+ SER_STRUCT_DEC_BEGIN(ble_gatts_evt_hvc_t);
+ SER_PULL_uint16(&p_struct->handle);
+ SER_STRUCT_DEC_END;
+}
+
+uint32_t ble_gatts_evt_sys_attr_missing_t_enc(void const * const p_void_struct,
+ uint8_t * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index)
+{
+ SER_STRUCT_ENC_BEGIN(ble_gatts_evt_sys_attr_missing_t);
+ SER_PUSH_uint8(&p_struct->hint);
+ SER_STRUCT_ENC_END;
+}
+
+uint32_t ble_gatts_evt_sys_attr_missing_t_dec(uint8_t const * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index,
+ void * const p_void_struct)
+{
+ SER_STRUCT_DEC_BEGIN(ble_gatts_evt_sys_attr_missing_t);
+ SER_PULL_uint8(&p_struct->hint);
+ SER_STRUCT_DEC_END;
+}
+
+uint32_t ble_gatts_evt_timeout_t_enc(void const * const p_void_struct,
+ uint8_t * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index)
+{
+ SER_STRUCT_ENC_BEGIN(ble_gatts_evt_timeout_t);
+ SER_PUSH_uint8(&p_struct->src);
+ SER_STRUCT_ENC_END;
+}
+
+uint32_t ble_gatts_evt_timeout_t_dec(uint8_t const * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index,
+ void * const p_void_struct)
+{
+ SER_STRUCT_DEC_BEGIN(ble_gatts_evt_timeout_t);
+ SER_PULL_uint8(&p_struct->src);
+ SER_STRUCT_DEC_END;
+}
+
+#if NRF_SD_BLE_API_VERSION >= 4
+uint32_t ble_gatts_conn_cfg_t_enc(void const * const p_void_struct,
+ uint8_t * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index)
+{
+ SER_STRUCT_ENC_BEGIN(ble_gatts_conn_cfg_t);
+ SER_PUSH_uint8(&p_struct->hvn_tx_queue_size);
+ SER_STRUCT_ENC_END;
+}
+
+uint32_t ble_gatts_conn_cfg_t_dec(uint8_t const * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index,
+ void * const p_void_struct)
+{
+ SER_STRUCT_DEC_BEGIN(ble_gatts_conn_cfg_t);
+ SER_PULL_uint8(&p_struct->hvn_tx_queue_size);
+ SER_STRUCT_DEC_END;
+}
+
+uint32_t ble_gatts_cfg_service_changed_t_enc(void const * const p_void_struct,
+ uint8_t * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index)
+{
+ SER_STRUCT_ENC_BEGIN(ble_gatts_cfg_service_changed_t);
+ uint8_t service_changed = p_struct->service_changed;
+ SER_PUSH_uint8(&service_changed);
+ SER_STRUCT_ENC_END;
+}
+
+uint32_t ble_gatts_cfg_service_changed_t_dec(uint8_t const * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index,
+ void * const p_void_struct)
+{
+ SER_STRUCT_DEC_BEGIN(ble_gatts_cfg_service_changed_t);
+ uint8_t service_changed;
+ SER_PULL_uint8(&service_changed);
+ p_struct->service_changed = service_changed;
+ SER_STRUCT_DEC_END;
+}
+uint32_t ble_gatts_cfg_attr_tab_size_t_enc(void const * const p_void_struct,
+ uint8_t * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index)
+{
+ SER_STRUCT_ENC_BEGIN(ble_gatts_cfg_attr_tab_size_t);
+ SER_PUSH_uint32(&p_struct->attr_tab_size);
+ SER_STRUCT_ENC_END;
+}
+
+uint32_t ble_gatts_cfg_attr_tab_size_t_dec(uint8_t const * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index,
+ void * const p_void_struct)
+{
+ SER_STRUCT_DEC_BEGIN(ble_gatts_cfg_attr_tab_size_t);
+ SER_PULL_uint32(&p_struct->attr_tab_size);
+ SER_STRUCT_DEC_END;
+}
+
+
+#endif
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/common/struct_ser/ble/ble_gatts_struct_serialization.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/common/struct_ser/ble/ble_gatts_struct_serialization.h
new file mode 100644
index 0000000..4a93913
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/common/struct_ser/ble/ble_gatts_struct_serialization.h
@@ -0,0 +1,259 @@
+/**
+ * Copyright (c) 2014 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#ifndef BLE_GATTS_STRUCT_SERIALIZATION_H
+#define BLE_GATTS_STRUCT_SERIALIZATION_H
+
+#include "ble_gatts.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+uint32_t ble_gatts_char_pf_t_enc(void const * const p_void_struct,
+ uint8_t * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index);
+
+uint32_t ble_gatts_char_pf_t_dec(uint8_t const * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index,
+ void * const p_void_struct);
+
+uint32_t ble_gatts_attr_md_t_enc(void const * const p_void_struct,
+ uint8_t * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index);
+
+uint32_t ble_gatts_attr_md_t_dec(uint8_t const * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index,
+ void * const p_void_struct);
+
+uint32_t ble_gatts_char_md_t_enc(void const * const p_void_struct,
+ uint8_t * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index);
+
+uint32_t ble_gatts_char_md_t_dec(uint8_t const * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index,
+ void * const p_void_struct);
+
+uint32_t ble_gatts_attr_t_enc(void const * const p_void_struct,
+ uint8_t * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index);
+
+uint32_t ble_gatts_attr_t_dec(uint8_t const * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index,
+ void * const p_void_struct);
+
+uint32_t ble_gatts_char_handles_t_enc(void const * const p_void_struct,
+ uint8_t * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index);
+
+uint32_t ble_gatts_char_handles_t_dec(uint8_t const * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index,
+ void * const p_void_struct);
+
+uint32_t ble_gatts_evt_write_t_enc(void const * const p_void_struct,
+ uint8_t * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index);
+
+uint32_t ble_gatts_evt_write_t_dec(uint8_t const * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index,
+ uint32_t * const p_ext_len,
+ void * const p_void_struct);
+
+uint32_t ble_gatts_hvx_params_t_enc(void const * const p_void_struct,
+ uint8_t * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index);
+
+uint32_t ble_gatts_hvx_params_t_dec(uint8_t const * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index,
+ void * const p_void_struct);
+
+uint32_t ble_gatts_evt_read_t_enc(void const * const p_void_struct,
+ uint8_t * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index);
+
+uint32_t ble_gatts_evt_read_t_dec(uint8_t const * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index,
+ void * const p_void_struct);
+
+uint32_t ble_gatts_evt_rw_authorize_request_t_enc(void const * const p_void_struct,
+ uint8_t * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index);
+
+uint32_t ble_gatts_evt_rw_authorize_request_t_dec(uint8_t const * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index,
+ uint32_t * const p_ext_len,
+ void * const p_void_struct);
+
+uint32_t ble_gatts_authorize_params_t_enc(void const * const p_void_struct,
+ uint8_t * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index);
+
+uint32_t ble_gatts_authorize_params_t_dec(uint8_t const * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index,
+ void * const p_void_struct);
+
+uint32_t ble_gatts_rw_authorize_reply_params_t_enc(void const * const p_void_struct,
+ uint8_t * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index);
+
+uint32_t ble_gatts_rw_authorize_reply_params_t_dec(uint8_t const * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index,
+ void * const p_void_struct);
+
+#if defined(NRF_SD_BLE_API_VERSION) && NRF_SD_BLE_API_VERSION < 4
+uint32_t ble_gatts_enable_params_t_enc(void const * const p_void_struct,
+ uint8_t * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index);
+
+uint32_t ble_gatts_enable_params_t_dec(uint8_t const * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index,
+ void * const p_void_struct);
+#endif
+
+uint32_t ble_gatts_value_t_enc(void const * const p_void_struct,
+ uint8_t * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index);
+
+uint32_t ble_gatts_value_t_dec(uint8_t const * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index,
+ void * const p_void_struct);
+
+uint32_t ble_gatts_evt_exchange_mtu_request_t_enc(void const * const p_void_struct,
+ uint8_t * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index);
+
+uint32_t ble_gatts_evt_exchange_mtu_request_t_dec(uint8_t const * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index,
+ void * const p_void_struct);
+
+uint32_t ble_gatts_evt_hvc_t_enc(void const * const p_void_struct,
+ uint8_t * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index);
+
+uint32_t ble_gatts_evt_hvc_t_dec(uint8_t const * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index,
+ void * const p_void_struct);
+
+uint32_t ble_gatts_evt_sys_attr_missing_t_enc(void const * const p_void_struct,
+ uint8_t * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index);
+
+uint32_t ble_gatts_evt_sys_attr_missing_t_dec(uint8_t const * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index,
+ void * const p_void_struct);
+
+uint32_t ble_gatts_evt_timeout_t_enc(void const * const p_void_struct,
+ uint8_t * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index);
+
+uint32_t ble_gatts_evt_timeout_t_dec(uint8_t const * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index,
+ void * const p_void_struct);
+
+#if NRF_SD_BLE_API_VERSION >= 4
+uint32_t ble_gatts_conn_cfg_t_enc(void const * const p_void_struct,
+ uint8_t * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index);
+
+uint32_t ble_gatts_conn_cfg_t_dec(uint8_t const * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index,
+ void * const p_void_struct);
+
+uint32_t ble_gatts_cfg_service_changed_t_enc(void const * const p_void_struct,
+ uint8_t * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index);
+
+uint32_t ble_gatts_cfg_service_changed_t_dec(uint8_t const * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index,
+ void * const p_void_struct);
+
+uint32_t ble_gatts_cfg_attr_tab_size_t_enc(void const * const p_void_struct,
+ uint8_t * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index);
+
+uint32_t ble_gatts_cfg_attr_tab_size_t_dec(uint8_t const * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index,
+ void * const p_void_struct);
+
+#endif
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* BLE_GATTS_STRUCT_SERIALIZATION_H */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/common/struct_ser/ble/ble_l2cap_struct_serialization.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/common/struct_ser/ble/ble_l2cap_struct_serialization.c
new file mode 100644
index 0000000..cc48f80
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/common/struct_ser/ble/ble_l2cap_struct_serialization.c
@@ -0,0 +1,227 @@
+/**
+ * Copyright (c) 2014 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#include "ble_l2cap_struct_serialization.h"
+#include "ble_struct_serialization.h"
+#include "ble_serialization.h"
+#include "app_util.h"
+#include "cond_field_serialization.h"
+#include <string.h>
+
+#if defined(NRF_SD_BLE_API_VERSION) && NRF_SD_BLE_API_VERSION < 4
+uint32_t ble_l2cap_header_t_enc(void const * const p_void_struct,
+ uint8_t * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index)
+{
+ SER_STRUCT_ENC_BEGIN(ble_l2cap_header_t);
+
+ SER_PUSH_uint16(&p_struct->len);
+ SER_PUSH_uint16(&p_struct->cid);
+
+ SER_STRUCT_ENC_END;
+}
+
+uint32_t ble_l2cap_header_t_dec(uint8_t const * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index,
+ void * const p_void_struct)
+{
+ SER_STRUCT_DEC_BEGIN(ble_l2cap_header_t);
+
+ SER_PULL_uint16(&p_struct->len);
+ SER_PULL_uint16(&p_struct->cid);
+
+ SER_STRUCT_DEC_END;
+}
+
+uint32_t ble_l2cap_evt_rx_t_enc(void const * const p_void_struct,
+ uint8_t * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index)
+{
+ SER_STRUCT_ENC_BEGIN(ble_l2cap_evt_rx_t);
+
+ SER_PUSH_FIELD(&p_struct->header, ble_l2cap_header_t_enc);
+ SER_PUSH_uint8array(p_struct->data, p_struct->header.len);
+
+ SER_STRUCT_ENC_END;
+}
+
+uint32_t ble_l2cap_evt_rx_t_dec(uint8_t const * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index,
+ uint32_t * const p_ext_len,
+ void * const p_void_struct)
+{
+ SER_STRUCT_DEC_BEGIN(ble_l2cap_evt_rx_t);
+
+ SER_PULL_FIELD(&p_struct->header, ble_l2cap_header_t_dec);
+
+ uint32_t data_len = (SUB1(p_struct->header.len));
+ SER_ASSERT_LENGTH_LEQ(data_len, *p_ext_len);
+
+ SER_PULL_uint8array(p_struct->data, p_struct->header.len);
+
+ *p_ext_len = data_len;
+ SER_STRUCT_DEC_END;
+}
+#endif
+
+#if NRF_SD_BLE_API_VERSION >= 5
+uint32_t ble_l2cap_conn_cfg_t_enc(void const * const p_void_struct,
+ uint8_t * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index)
+{
+ SER_STRUCT_ENC_BEGIN(ble_l2cap_conn_cfg_t);
+
+ SER_PUSH_uint16(&p_struct->rx_mps);
+ SER_PUSH_uint16(&p_struct->tx_mps);
+ SER_PUSH_uint8(&p_struct->rx_queue_size);
+ SER_PUSH_uint8(&p_struct->tx_queue_size);
+ SER_PUSH_uint8(&p_struct->ch_count);
+
+ SER_STRUCT_ENC_END;
+}
+
+uint32_t ble_l2cap_conn_cfg_t_dec(uint8_t const * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index,
+ void * const p_void_struct)
+{
+ SER_STRUCT_DEC_BEGIN(ble_l2cap_conn_cfg_t);
+
+ SER_PULL_uint16(&p_struct->rx_mps);
+ SER_PULL_uint16(&p_struct->tx_mps);
+ SER_PULL_uint8(&p_struct->rx_queue_size);
+ SER_PULL_uint8(&p_struct->tx_queue_size);
+ SER_PULL_uint8(&p_struct->ch_count);
+
+ SER_STRUCT_DEC_END;
+}
+
+uint32_t ble_l2cap_ch_rx_params_t_enc(void const * const p_void_struct,
+ uint8_t * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index)
+{
+ SER_STRUCT_ENC_BEGIN(ble_l2cap_ch_rx_params_t);
+
+ SER_PUSH_uint16(&p_struct->rx_mtu);
+ SER_PUSH_uint16(&p_struct->rx_mps);
+ SER_PUSH_uint16(&p_struct->sdu_buf.len);
+ SER_PUSH_uint32(&p_struct->sdu_buf.p_data);
+
+ SER_STRUCT_ENC_END;
+}
+
+uint32_t ble_l2cap_ch_rx_params_t_dec(uint8_t const * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index,
+ void * const p_void_struct)
+{
+ SER_STRUCT_DEC_BEGIN(ble_l2cap_ch_rx_params_t);
+
+ SER_PULL_uint16(&p_struct->rx_mtu);
+ SER_PULL_uint16(&p_struct->rx_mps);
+ SER_PULL_uint16(&p_struct->sdu_buf.len);
+ SER_PULL_uint32(&p_struct->sdu_buf.p_data);
+
+ SER_STRUCT_DEC_END;
+}
+
+uint32_t ble_l2cap_ch_setup_params_t_enc(void const * const p_void_struct,
+ uint8_t * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index)
+{
+ SER_STRUCT_ENC_BEGIN(ble_l2cap_ch_setup_params_t);
+
+ SER_PUSH_FIELD(&p_struct->rx_params, ble_l2cap_ch_rx_params_t_enc);
+ SER_PUSH_uint16(&p_struct->le_psm);
+ SER_PUSH_uint16(&p_struct->status);
+
+ SER_STRUCT_ENC_END;
+}
+
+uint32_t ble_l2cap_ch_setup_params_t_dec(uint8_t const * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index,
+ void * const p_void_struct)
+{
+ SER_STRUCT_DEC_BEGIN(ble_l2cap_ch_setup_params_t);
+
+ SER_PULL_FIELD(&p_struct->rx_params, ble_l2cap_ch_rx_params_t_dec);
+ SER_PULL_uint16(&p_struct->le_psm);
+ SER_PULL_uint16(&p_struct->status);
+
+ SER_STRUCT_DEC_END;
+}
+
+uint32_t ble_l2cap_ch_tx_params_t_enc(void const * const p_void_struct,
+ uint8_t * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index)
+{
+ SER_STRUCT_ENC_BEGIN(ble_l2cap_ch_tx_params_t);
+
+ SER_PUSH_uint16(&p_struct->tx_mtu);
+ SER_PUSH_uint16(&p_struct->peer_mps);
+ SER_PUSH_uint16(&p_struct->tx_mps);
+ SER_PUSH_uint16(&p_struct->credits);
+
+ SER_STRUCT_ENC_END;
+}
+
+uint32_t ble_l2cap_ch_tx_params_t_dec(uint8_t const * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index,
+ void * const p_void_struct)
+{
+ SER_STRUCT_DEC_BEGIN(ble_l2cap_ch_tx_params_t);
+
+ SER_PULL_uint16(&p_struct->tx_mtu);
+ SER_PULL_uint16(&p_struct->peer_mps);
+ SER_PULL_uint16(&p_struct->tx_mps);
+ SER_PULL_uint16(&p_struct->credits);
+
+ SER_STRUCT_DEC_END;
+}
+#endif //NRF_SD_BLE_API_VERSION >= 5
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/common/struct_ser/ble/ble_l2cap_struct_serialization.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/common/struct_ser/ble/ble_l2cap_struct_serialization.h
new file mode 100644
index 0000000..a8c7bc1
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/common/struct_ser/ble/ble_l2cap_struct_serialization.h
@@ -0,0 +1,119 @@
+/**
+ * Copyright (c) 2014 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#ifndef BLE_L2CAP_STRUCT_SERIALIZATION_H
+#define BLE_L2CAP_STRUCT_SERIALIZATION_H
+
+#ifndef S112
+#include "ble_l2cap.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#if defined(NRF_SD_BLE_API_VERSION) && NRF_SD_BLE_API_VERSION < 4
+uint32_t ble_l2cap_header_t_enc(void const * const p_void_struct,
+ uint8_t * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index);
+
+uint32_t ble_l2cap_header_t_dec(uint8_t const * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index,
+ void * const p_void_struct);
+
+uint32_t ble_l2cap_evt_rx_t_enc(void const * const p_void_struct,
+ uint8_t * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index);
+
+uint32_t ble_l2cap_evt_rx_t_dec(uint8_t const * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index,
+ uint32_t * const p_ext_len,
+ void * const p_void_struct);
+#endif
+
+#if NRF_SD_BLE_API_VERSION >= 5
+uint32_t ble_l2cap_conn_cfg_t_enc(void const * const p_void_struct,
+ uint8_t * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index);
+
+uint32_t ble_l2cap_conn_cfg_t_dec(uint8_t const * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index,
+ void * const p_void_struct);
+
+uint32_t ble_l2cap_ch_rx_params_t_enc(void const * const p_void_struct,
+ uint8_t * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index);
+
+uint32_t ble_l2cap_ch_rx_params_t_dec(uint8_t const * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index,
+ void * const p_void_struct);
+
+uint32_t ble_l2cap_ch_setup_params_t_enc(void const * const p_void_struct,
+ uint8_t * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index);
+
+uint32_t ble_l2cap_ch_setup_params_t_dec(uint8_t const * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index,
+ void * const p_void_struct);
+
+uint32_t ble_l2cap_ch_tx_params_t_enc(void const * const p_void_struct,
+ uint8_t * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index);
+
+uint32_t ble_l2cap_ch_tx_params_t_dec(uint8_t const * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index,
+ void * const p_void_struct);
+#endif
+#endif
+#ifdef __cplusplus
+}
+#endif
+
+#endif /*BLE_L2CAP_STRUCT_SERIALIZATION_H*/
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/common/struct_ser/ble/ble_struct_serialization.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/common/struct_ser/ble/ble_struct_serialization.c
new file mode 100644
index 0000000..5687801
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/common/struct_ser/ble/ble_struct_serialization.c
@@ -0,0 +1,500 @@
+/**
+ * Copyright (c) 2014 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#include "ble_struct_serialization.h"
+#include "ble_gap_struct_serialization.h"
+#include "ble_gatt_struct_serialization.h"
+#include "ble_gatts_struct_serialization.h"
+#include "ble_serialization.h"
+#include "app_util.h"
+#include "ble_types.h"
+#include "ble.h"
+#include "cond_field_serialization.h"
+#ifdef SER_CONNECTIVITY
+#include "conn_ble_gap_sec_keys.h"
+#endif
+#include <string.h>
+
+
+uint32_t ble_uuid_t_enc(void const * const p_void_struct,
+ uint8_t * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index)
+{
+ SER_STRUCT_ENC_BEGIN(ble_uuid_t);
+
+ SER_PUSH_uint16(&p_struct->uuid);
+ SER_PUSH_uint8(&p_struct->type);
+
+ SER_STRUCT_ENC_END;
+}
+
+uint32_t ble_uuid_t_dec(uint8_t const * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index,
+ void * const p_void_struct)
+{
+ SER_STRUCT_DEC_BEGIN(ble_uuid_t);
+
+ SER_PULL_uint16(&p_struct->uuid);
+ SER_PULL_uint8(&p_struct->type);
+
+ SER_STRUCT_DEC_END;
+}
+
+uint32_t ble_uuid128_t_enc(void const * const p_void_struct,
+ uint8_t * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index)
+{
+ SER_STRUCT_ENC_BEGIN(ble_uuid128_t);
+ SER_PUSH_uint8array(p_struct->uuid128, sizeof (p_struct->uuid128));
+ SER_STRUCT_ENC_END;
+}
+
+uint32_t ble_uuid128_t_dec(uint8_t const * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index,
+ void * const p_void_struct)
+{
+ SER_STRUCT_DEC_BEGIN(ble_uuid128_t);
+ SER_PULL_uint8array(p_struct->uuid128, sizeof (p_struct->uuid128));
+ SER_STRUCT_DEC_END;
+}
+
+#if defined(NRF_SD_BLE_API_VERSION) && NRF_SD_BLE_API_VERSION < 4
+uint32_t ble_enable_params_t_enc(void const * const p_void_struct,
+ uint8_t * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index)
+{
+ SER_STRUCT_ENC_BEGIN(ble_enable_params_t);
+
+ SER_PUSH_FIELD(&p_struct->common_enable_params, ble_common_enable_params_t_enc);
+ SER_PUSH_FIELD(&p_struct->gap_enable_params, ble_gap_enable_params_t_enc);
+ SER_PUSH_FIELD(&p_struct->gatt_enable_params, ble_gatt_enable_params_t_enc);
+ SER_PUSH_FIELD(&p_struct->gatts_enable_params, ble_gatts_enable_params_t_enc);
+
+ SER_STRUCT_ENC_END;
+}
+
+uint32_t ble_enable_params_t_dec(uint8_t const * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index,
+ void * const p_void_struct)
+{
+ SER_STRUCT_DEC_BEGIN(ble_enable_params_t);
+
+ SER_PULL_FIELD(&p_struct->common_enable_params, ble_common_enable_params_t_dec);
+ SER_PULL_FIELD(&p_struct->gap_enable_params, ble_gap_enable_params_t_dec);
+ SER_PULL_FIELD(&p_struct->gatt_enable_params, ble_gatt_enable_params_t_dec);
+ SER_PULL_FIELD(&p_struct->gatts_enable_params, ble_gatts_enable_params_t_dec);
+
+ SER_STRUCT_DEC_END;
+}
+
+uint32_t ble_conn_bw_t_enc(void const * const p_void_struct,
+ uint8_t * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index)
+{
+ SER_STRUCT_ENC_BEGIN(ble_conn_bw_t);
+
+ SER_PUSH_uint8(&p_struct->conn_bw_rx);
+ SER_PUSH_uint8(&p_struct->conn_bw_tx);
+
+ SER_STRUCT_ENC_END;
+}
+
+uint32_t ble_conn_bw_t_dec(uint8_t const * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index,
+ void * const p_void_struct)
+{
+ SER_STRUCT_DEC_BEGIN(ble_conn_bw_t);
+
+ SER_PULL_uint8(&p_struct->conn_bw_rx);
+ SER_PULL_uint8(&p_struct->conn_bw_tx);
+
+ SER_STRUCT_DEC_END;
+}
+
+uint32_t ble_common_opt_conn_bw_t_enc(void const * const p_void_struct,
+ uint8_t * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index)
+{
+ SER_STRUCT_ENC_BEGIN(ble_common_opt_conn_bw_t);
+
+ SER_PUSH_uint8(&p_struct->role);
+ SER_PUSH_FIELD(&p_struct->conn_bw, ble_conn_bw_t_enc);
+
+ SER_STRUCT_ENC_END;
+}
+
+uint32_t ble_common_opt_conn_bw_t_dec(uint8_t const * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index,
+ void * const p_void_struct)
+{
+ SER_STRUCT_DEC_BEGIN(ble_common_opt_conn_bw_t);
+
+ SER_PULL_uint8(&p_struct->role);
+ SER_PULL_FIELD(&p_struct->conn_bw, ble_conn_bw_t_dec);
+
+ SER_STRUCT_DEC_END;
+}
+
+uint32_t ble_conn_bw_count_t_enc(void const * const p_void_struct,
+ uint8_t * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index)
+{
+ SER_STRUCT_ENC_BEGIN(ble_conn_bw_count_t);
+
+ SER_PUSH_uint8(&p_struct->high_count);
+ SER_PUSH_uint8(&p_struct->mid_count);
+ SER_PUSH_uint8(&p_struct->low_count);
+
+ SER_STRUCT_DEC_END;
+}
+
+uint32_t ble_conn_bw_count_t_dec(uint8_t const * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index,
+ void * const p_void_struct)
+{
+ SER_STRUCT_DEC_BEGIN(ble_conn_bw_count_t);
+
+ SER_PULL_uint8(&p_struct->high_count);
+ SER_PULL_uint8(&p_struct->mid_count);
+ SER_PULL_uint8(&p_struct->low_count);
+
+ SER_STRUCT_DEC_END;
+}
+
+uint32_t ble_conn_bw_counts_t_enc(void const * const p_void_struct,
+ uint8_t * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index)
+{
+ SER_STRUCT_ENC_BEGIN(ble_conn_bw_counts_t);
+
+ SER_PUSH_FIELD(&p_struct->tx_counts, ble_conn_bw_count_t_enc);
+ SER_PUSH_FIELD(&p_struct->rx_counts, ble_conn_bw_count_t_enc);
+
+ SER_STRUCT_DEC_END;
+}
+
+uint32_t ble_conn_bw_counts_t_dec(uint8_t const * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index,
+ void * const p_void_struct)
+{
+ SER_STRUCT_DEC_BEGIN(ble_conn_bw_counts_t);
+
+ SER_PULL_FIELD(&p_struct->tx_counts, ble_conn_bw_count_t_dec);
+ SER_PULL_FIELD(&p_struct->rx_counts, ble_conn_bw_count_t_dec);
+
+ SER_STRUCT_DEC_END;
+}
+
+uint32_t ble_common_enable_params_t_enc(void const * const p_void_struct,
+ uint8_t * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index)
+{
+ SER_STRUCT_ENC_BEGIN(ble_common_enable_params_t);
+
+ SER_PUSH_uint16(&p_struct->vs_uuid_count);
+ SER_PUSH_COND(p_struct->p_conn_bw_counts, ble_conn_bw_counts_t_enc);
+
+ SER_STRUCT_ENC_END;
+}
+
+uint32_t ble_common_enable_params_t_dec(uint8_t const * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index,
+ void * const p_void_struct)
+{
+ SER_STRUCT_DEC_BEGIN(ble_common_enable_params_t);
+
+ SER_PULL_uint16(&p_struct->vs_uuid_count);
+ SER_PULL_COND(&p_struct->p_conn_bw_counts, ble_conn_bw_counts_t_dec);
+
+ SER_STRUCT_DEC_END;
+}
+#endif
+uint32_t ble_common_opt_pa_lna_t_enc(void const * const p_void_struct,
+ uint8_t * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index)
+{
+ SER_STRUCT_ENC_BEGIN(ble_common_opt_pa_lna_t);
+
+ SER_PUSH_FIELD(&p_struct->pa_cfg, ble_pa_lna_cfg_t_enc);
+ SER_PUSH_FIELD(&p_struct->lna_cfg, ble_pa_lna_cfg_t_enc);
+ SER_PUSH_uint8(&p_struct->ppi_ch_id_set);
+ SER_PUSH_uint8(&p_struct->ppi_ch_id_clr);
+ SER_PUSH_uint8(&p_struct->gpiote_ch_id);
+
+ SER_STRUCT_ENC_END;
+}
+
+uint32_t ble_common_opt_pa_lna_t_dec(uint8_t const * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index,
+ void * const p_void_struct)
+{
+ SER_STRUCT_DEC_BEGIN(ble_common_opt_pa_lna_t);
+
+ SER_PULL_FIELD(&p_struct->pa_cfg, ble_pa_lna_cfg_t_dec);
+ SER_PULL_FIELD(&p_struct->lna_cfg, ble_pa_lna_cfg_t_dec);
+ SER_PULL_uint8(&p_struct->ppi_ch_id_set);
+ SER_PULL_uint8(&p_struct->ppi_ch_id_clr);
+ SER_PULL_uint8(&p_struct->gpiote_ch_id);
+
+ SER_STRUCT_DEC_END;
+}
+
+
+uint32_t ble_pa_lna_cfg_t_enc(void const * const p_void_struct,
+ uint8_t * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index)
+{
+ SER_STRUCT_ENC_BEGIN(ble_pa_lna_cfg_t);
+
+ uint8_t ser_data = (p_struct->enable & 0x01)
+ | ((p_struct->active_high & 0x01) << 1)
+ | ((p_struct->gpio_pin & 0x3F) << 2);
+ SER_PUSH_uint8(&ser_data);
+
+ SER_STRUCT_ENC_END;
+}
+
+uint32_t ble_pa_lna_cfg_t_dec(uint8_t const * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index,
+ void * const p_void_struct)
+{
+ SER_STRUCT_DEC_BEGIN(ble_pa_lna_cfg_t);
+
+ uint8_t ser_data;
+ SER_PULL_uint8(&ser_data);
+ p_struct->enable = ser_data & 0x01;
+ p_struct->active_high = (ser_data >> 1) & 0x01;
+ p_struct->gpio_pin = (ser_data >> 2) & 0x3F;
+
+ SER_STRUCT_DEC_END;
+}
+
+
+uint32_t ble_user_mem_block_t_enc(void const * const p_void_struct,
+ uint8_t * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index)
+{
+ SER_STRUCT_ENC_BEGIN(ble_user_mem_block_t);
+
+ SER_PUSH_uint16(&p_struct->len);
+ SER_PUSH_COND(p_struct->p_mem, NULL);
+
+ SER_STRUCT_ENC_END;
+}
+
+uint32_t ble_user_mem_block_t_dec(uint8_t const * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index,
+ void * const p_void_struct)
+{
+ SER_STRUCT_DEC_BEGIN(ble_user_mem_block_t);
+
+ SER_PULL_uint16(&p_struct->len);
+ SER_PULL_COND(&p_struct->p_mem, NULL);
+
+ SER_STRUCT_DEC_END;
+}
+
+uint32_t ble_version_t_enc(void const * const p_void_struct,
+ uint8_t * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index)
+{
+ SER_STRUCT_ENC_BEGIN(ble_version_t);
+
+ SER_PUSH_uint8(&p_struct->version_number);
+ SER_PUSH_uint16(&p_struct->company_id);
+ SER_PUSH_uint16(&p_struct->subversion_number);
+
+ SER_STRUCT_ENC_END;
+}
+
+uint32_t ble_version_t_dec(uint8_t const * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index,
+ void * const p_void_struct)
+{
+ SER_STRUCT_DEC_BEGIN(ble_version_t);
+
+ SER_PULL_uint8(&p_struct->version_number);
+ SER_PULL_uint16(&p_struct->company_id);
+ SER_PULL_uint16(&p_struct->subversion_number);
+
+ SER_STRUCT_DEC_END;
+}
+#if defined(NRF_SD_BLE_API_VERSION) && NRF_SD_BLE_API_VERSION < 4
+uint32_t ble_evt_data_length_changed_t_enc(void const * const p_void_struct,
+ uint8_t * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index)
+{
+ SER_STRUCT_ENC_BEGIN(ble_evt_data_length_changed_t);
+
+ SER_PUSH_uint16(&p_struct->max_tx_octets);
+ SER_PUSH_uint16(&p_struct->max_tx_time);
+ SER_PUSH_uint16(&p_struct->max_rx_octets);
+ SER_PUSH_uint16(&p_struct->max_rx_time);
+
+ SER_STRUCT_ENC_END;
+}
+
+uint32_t ble_evt_data_length_changed_t_dec(uint8_t const * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index,
+ void * const p_void_struct)
+{
+ SER_STRUCT_DEC_BEGIN(ble_evt_data_length_changed_t);
+
+ SER_PULL_uint16(&p_struct->max_tx_octets);
+ SER_PULL_uint16(&p_struct->max_tx_time);
+ SER_PULL_uint16(&p_struct->max_rx_octets);
+ SER_PULL_uint16(&p_struct->max_rx_time);
+
+ SER_STRUCT_DEC_END;
+}
+#endif
+uint32_t ble_common_opt_conn_evt_ext_t_enc(void const * const p_void_struct,
+ uint8_t * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index)
+{
+ SER_STRUCT_ENC_BEGIN(ble_common_opt_conn_evt_ext_t);
+
+ uint8_t ser_data = p_struct->enable & 0x01;
+ SER_PUSH_uint8(&ser_data);
+
+ SER_STRUCT_ENC_END;
+}
+
+uint32_t ble_common_opt_conn_evt_ext_t_dec(uint8_t const * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index,
+ void * const p_void_struct)
+{
+ SER_STRUCT_DEC_BEGIN(ble_common_opt_conn_evt_ext_t);
+
+ uint8_t ser_data;
+ SER_PULL_uint8(&ser_data);
+ p_struct->enable = ser_data & 0x01;
+
+ SER_STRUCT_DEC_END;
+}
+#if NRF_SD_BLE_API_VERSION >= 4
+uint32_t ble_common_cfg_vs_uuid_t_enc(void const * const p_void_struct,
+ uint8_t * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index)
+{
+ SER_STRUCT_ENC_BEGIN(ble_common_cfg_vs_uuid_t);
+
+ SER_PUSH_uint8(&p_struct->vs_uuid_count);
+
+ SER_STRUCT_ENC_END;
+}
+
+uint32_t ble_common_cfg_vs_uuid_t_dec(uint8_t const * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index,
+ void * const p_void_struct)
+{
+ SER_STRUCT_DEC_BEGIN(ble_common_cfg_vs_uuid_t);
+
+ SER_PULL_uint8(&p_struct->vs_uuid_count);
+
+ SER_STRUCT_DEC_END;
+}
+
+#endif
+
+#if defined(NRF_SD_BLE_API_VERSION) && NRF_SD_BLE_API_VERSION > 4
+uint32_t ble_data_t_enc(void const * const p_void_struct,
+ uint8_t * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index)
+{
+ SER_STRUCT_ENC_BEGIN(ble_data_t);
+
+ uint32_t buf_id = (uint32_t)p_struct->p_data;
+ SER_PUSH_uint32(&buf_id);
+ SER_PUSH_len16data(p_struct->p_data, p_struct->len);
+
+ SER_STRUCT_ENC_END;
+}
+
+uint32_t ble_data_t_dec(uint8_t const * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index,
+ void * const p_void_struct)
+{
+ SER_STRUCT_DEC_BEGIN(ble_data_t);
+
+ uint32_t buf_id;
+ SER_PULL_uint32(&buf_id);
+#if defined(SER_CONNECTIVITY) && NRF_SD_BLE_API_VERSION > 5
+ if (buf_id && (p_struct->p_data == NULL))
+ {
+ p_struct->p_data = conn_ble_gap_ble_data_buf_alloc(buf_id);
+ }
+#endif
+ SER_PULL_len16data(&p_struct->p_data, &p_struct->len);
+
+ SER_STRUCT_DEC_END;
+}
+#endif
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/common/struct_ser/ble/ble_struct_serialization.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/common/struct_ser/ble/ble_struct_serialization.h
new file mode 100644
index 0000000..66c05a9
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/common/struct_ser/ble/ble_struct_serialization.h
@@ -0,0 +1,217 @@
+/**
+ * Copyright (c) 2014 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#ifndef BLE_STRUCT_SERIALIZATION_H__
+#define BLE_STRUCT_SERIALIZATION_H__
+
+#include "ble_types.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+uint32_t ble_uuid_t_enc(void const * const p_void_struct,
+ uint8_t * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index);
+
+uint32_t ble_uuid_t_dec(uint8_t const * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index,
+ void * const p_void_struct);
+
+uint32_t ble_uuid128_t_enc(const void * const p_void_struct,
+ uint8_t * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index);
+
+uint32_t ble_uuid128_t_dec(uint8_t const * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index,
+ void * const p_void_struct);
+
+uint32_t ble_enable_params_t_enc(void const * const p_void_struct,
+ uint8_t * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index);
+
+uint32_t ble_enable_params_t_dec(uint8_t const * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index,
+ void * const p_void_struct);
+
+uint32_t ble_conn_bw_t_enc(void const * const p_void_struct,
+ uint8_t * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index);
+
+uint32_t ble_conn_bw_t_dec(uint8_t const * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index,
+ void * const p_void_struct);
+
+uint32_t ble_common_opt_conn_bw_t_enc(void const * const p_void_struct,
+ uint8_t * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index);
+
+uint32_t ble_common_opt_conn_bw_t_dec(uint8_t const * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index,
+ void * const p_void_struct);
+
+uint32_t ble_conn_bw_count_t_enc(void const * const p_void_struct,
+ uint8_t * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index);
+
+uint32_t ble_conn_bw_count_t_dec(uint8_t const * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index,
+ void * const p_void_struct);
+
+uint32_t ble_conn_bw_counts_t_enc(void const * const p_void_struct,
+ uint8_t * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index);
+
+uint32_t ble_conn_bw_counts_t_dec(uint8_t const * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index,
+ void * const p_void_struct);
+
+uint32_t ble_common_enable_params_t_enc(void const * const p_void_struct,
+ uint8_t * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index);
+
+uint32_t ble_common_enable_params_t_dec(uint8_t const * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index,
+ void * const p_void_struct);
+
+uint32_t ble_common_opt_pa_lna_t_enc(void const * const p_void_struct,
+ uint8_t * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index);
+
+uint32_t ble_common_opt_pa_lna_t_dec(uint8_t const * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index,
+ void * const p_void_struct);
+
+uint32_t ble_pa_lna_cfg_t_enc(void const * const p_void_struct,
+ uint8_t * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index);
+
+uint32_t ble_pa_lna_cfg_t_dec(uint8_t const * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index,
+ void * const p_void_struct);
+
+uint32_t ble_user_mem_block_t_enc(void const * const p_void_struct,
+ uint8_t * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index);
+
+uint32_t ble_user_mem_block_t_dec(uint8_t const * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index,
+ void * const p_void_struct);
+
+uint32_t ble_version_t_enc(void const * const p_void_struct,
+ uint8_t * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index);
+
+uint32_t ble_version_t_dec(uint8_t const * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index,
+ void * const p_void_struct);
+
+uint32_t ble_evt_data_length_changed_t_enc(void const * const p_void_struct,
+ uint8_t * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index);
+
+uint32_t ble_evt_data_length_changed_t_dec(uint8_t const * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index,
+ void * const p_void_struct);
+
+uint32_t ble_common_opt_conn_evt_ext_t_enc(void const * const p_void_struct,
+ uint8_t * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index);
+
+uint32_t ble_common_opt_conn_evt_ext_t_dec(uint8_t const * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index,
+ void * const p_void_struct);
+#if NRF_SD_BLE_API_VERSION >= 4
+uint32_t ble_common_cfg_vs_uuid_t_enc(void const * const p_void_struct,
+ uint8_t * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index);
+
+uint32_t ble_common_cfg_vs_uuid_t_dec(uint8_t const * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index,
+ void * const p_void_struct);
+
+#endif
+
+#if defined(NRF_SD_BLE_API_VERSION) && NRF_SD_BLE_API_VERSION > 4
+uint32_t ble_data_t_enc(void const * const p_void_struct,
+ uint8_t * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index);
+
+uint32_t ble_data_t_dec(uint8_t const * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index,
+ void * const p_void_struct);
+#endif
+#ifdef __cplusplus
+}
+#endif
+
+#endif // BLE_STRUCT_SERIALIZATION_H__
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/common/struct_ser/ble/nrf_soc_struct_serialization.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/common/struct_ser/ble/nrf_soc_struct_serialization.c
new file mode 100644
index 0000000..47a0aac
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/common/struct_ser/ble/nrf_soc_struct_serialization.c
@@ -0,0 +1,90 @@
+/**
+ * Copyright (c) 2014 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#include "nrf_soc_struct_serialization.h"
+#include "ble_serialization.h"
+#include "cond_field_serialization.h"
+#include "app_util.h"
+#include "string.h"
+
+uint32_t nrf_ecb_hal_data_t_in_enc(void const * const p_void_struct,
+ uint8_t * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index)
+{
+ SER_STRUCT_ENC_BEGIN(nrf_ecb_hal_data_t);
+
+ SER_PUSH_uint8array(p_struct->key, SOC_ECB_KEY_LENGTH);
+ SER_PUSH_uint8array(p_struct->cleartext, SOC_ECB_CLEARTEXT_LENGTH);
+
+ SER_STRUCT_DEC_END;
+}
+
+uint32_t nrf_ecb_hal_data_t_in_dec(uint8_t const * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index,
+ void * const p_void_struct)
+{
+ SER_STRUCT_DEC_BEGIN(nrf_ecb_hal_data_t);
+
+ SER_PULL_uint8array(p_struct->key, SOC_ECB_KEY_LENGTH);
+ SER_PULL_uint8array(p_struct->cleartext, SOC_ECB_CLEARTEXT_LENGTH);
+
+ SER_STRUCT_DEC_END;
+}
+
+uint32_t nrf_ecb_hal_data_t_out_enc(void const * const p_void_struct,
+ uint8_t * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index)
+{
+ SER_STRUCT_ENC_BEGIN(nrf_ecb_hal_data_t);
+ SER_PUSH_uint8array(p_struct->ciphertext, SOC_ECB_CIPHERTEXT_LENGTH);
+ SER_STRUCT_DEC_END;
+}
+
+uint32_t nrf_ecb_hal_data_t_out_dec(uint8_t const * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index,
+ void * const p_void_struct)
+{
+ SER_STRUCT_DEC_BEGIN(nrf_ecb_hal_data_t);
+ SER_PULL_uint8array(p_struct->ciphertext, SOC_ECB_CIPHERTEXT_LENGTH);
+ SER_STRUCT_DEC_END;
+}
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/common/struct_ser/ble/nrf_soc_struct_serialization.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/common/struct_ser/ble/nrf_soc_struct_serialization.h
new file mode 100644
index 0000000..b6923e9
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/common/struct_ser/ble/nrf_soc_struct_serialization.h
@@ -0,0 +1,73 @@
+/**
+ * Copyright (c) 2014 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#ifndef NRF_SOC_STRUCT_SERIALIZATION_H__
+#define NRF_SOC_STRUCT_SERIALIZATION_H__
+
+#include "nrf_soc.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+uint32_t nrf_ecb_hal_data_t_in_enc(void const * const p_void_struct,
+ uint8_t * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index);
+
+uint32_t nrf_ecb_hal_data_t_in_dec(uint8_t const * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index,
+ void * const p_void_struct);
+
+uint32_t nrf_ecb_hal_data_t_out_enc(void const * const p_void_struct,
+ uint8_t * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index);
+
+uint32_t nrf_ecb_hal_data_t_out_dec(uint8_t const * const p_buf,
+ uint32_t buf_len,
+ uint32_t * const p_index,
+ void * const p_void_struct);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // NRF_SOC_STRUCT_SERIALIZATION_H__
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/common/transport/dtm_uart_params.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/common/transport/dtm_uart_params.h
new file mode 100644
index 0000000..1c79923
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/common/transport/dtm_uart_params.h
@@ -0,0 +1,93 @@
+/**
+ * Copyright (c) 2013 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#ifndef DTM_UART_PARAMS_H__
+#define DTM_UART_PARAMS_H__
+
+#include <stdbool.h>
+#include <stdint.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** @ingroup ble_dtm_app
+ */
+
+
+/**@brief Enumeration of supported baud rates. */
+typedef enum
+{
+ UART_BAUD_RATE_1200, /**< Baud rate 1200. */
+ UART_BAUD_RATE_2400, /**< Baud rate 2400. */
+ UART_BAUD_RATE_4800, /**< Baud rate 4800. */
+ UART_BAUD_RATE_9600, /**< Baud rate 9600. */
+ UART_BAUD_RATE_14400, /**< Baud rate 14400. */
+ UART_BAUD_RATE_19200, /**< Baud rate 19200. */
+ UART_BAUD_RATE_28800, /**< Baud rate 28800. */
+ UART_BAUD_RATE_38400, /**< Baud rate 38400. */
+ UART_BAUD_RATE_57600, /**< Baud rate 57600. */
+ UART_BAUD_RATE_76800, /**< Baud rate 76800. */
+ UART_BAUD_RATE_115200, /**< Baud rate 115200. */
+ UART_BAUD_RATE_230400, /**< Baud rate 230400. */
+ UART_BAUD_RATE_250000, /**< Baud rate 250000. */
+ UART_BAUD_RATE_460800, /**< Baud rate 460800. */
+ UART_BAUD_RATE_921600, /**< Baud rate 921600. */
+ UART_BAUD_RATE_1000000, /**< Baud rate 1000000. */
+ UART_BAUD_RATE_MAX /**< Enumeration upper bound. */
+} app_uart_stream_baud_rate_t;
+
+/**@brief UART communication structure holding configuration settings for the peripheral.
+ */
+typedef struct
+{
+ uint8_t rx_pin_no; /**< RX pin number. */
+ uint8_t tx_pin_no; /**< TX pin number. */
+ uint8_t rts_pin_no; /**< RTS pin number, only used if flow control is enabled. */
+ uint8_t cts_pin_no; /**< CTS pin number, only used if flow control is enabled. */
+ bool use_parity; /**< Even parity if TRUE, no parity if FALSE. */
+ app_uart_stream_baud_rate_t baud_rate; /**< Baud rate configuration. */
+} app_uart_stream_comm_params_t;
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // DTM_UART_PARAMS_H__
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/common/transport/ser_hal_transport.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/common/transport/ser_hal_transport.c
new file mode 100644
index 0000000..0a8bc16
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/common/transport/ser_hal_transport.c
@@ -0,0 +1,503 @@
+/**
+ * Copyright (c) 2014 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#include <stdbool.h>
+#include <string.h>
+#include "app_error.h"
+#include "sdk_config.h"
+#include "ser_config.h"
+#include "ser_phy.h"
+#include "ser_hal_transport.h"
+
+#define NRF_LOG_MODULE_NAME ser_hal_transport
+#if SER_HAL_TRANSPORT_CONFIG_LOG_ENABLED
+ #define NRF_LOG_LEVEL SER_HAL_TRANSPORT_CONFIG_LOG_LEVEL
+ #define NRF_LOG_INFO_COLOR SER_HAL_TRANSPORT_CONFIG_INFO_COLOR
+ #define NRF_LOG_DEBUG_COLOR SER_HAL_TRANSPORT_CONFIG_DEBUG_COLOR
+#else //SER_HAL_TRANSPORT_CONFIG_LOG_ENABLED
+ #define NRF_LOG_LEVEL 0
+#endif //SER_HAL_TRANSPORT_CONFIG_LOG_ENABLED
+#include "nrf_log.h"
+NRF_LOG_MODULE_REGISTER();
+
+/**
+ * @brief States of the RX state machine.
+ */
+typedef enum
+{
+ HAL_TRANSP_RX_STATE_CLOSED = 0,
+ HAL_TRANSP_RX_STATE_IDLE,
+ HAL_TRANSP_RX_STATE_RECEIVING,
+ HAL_TRANSP_RX_STATE_DROPPING,
+ HAL_TRANSP_RX_STATE_RECEIVED,
+ HAL_TRANSP_RX_STATE_RECEIVED_PENDING_BUF_REQ,
+ HAL_TRANSP_RX_STATE_RECEIVED_DROPPING,
+ HAL_TRANSP_RX_STATE_MAX
+}ser_hal_transp_rx_states_t;
+
+/**
+ * @brief States of the TX state machine.
+ */
+typedef enum
+{
+ HAL_TRANSP_TX_STATE_CLOSED = 0,
+ HAL_TRANSP_TX_STATE_IDLE,
+ HAL_TRANSP_TX_STATE_TX_ALLOCATED,
+ HAL_TRANSP_TX_STATE_TRANSMITTING,
+ HAL_TRANSP_TX_STATE_TRANSMITTED,
+ HAL_TRANSP_TX_STATE_MAX
+}ser_hal_transp_tx_states_t;
+
+/**
+ * @brief RX state.
+ */
+static ser_hal_transp_rx_states_t m_rx_state = HAL_TRANSP_RX_STATE_CLOSED;
+/**
+ * @brief TX state.
+ */
+static ser_hal_transp_tx_states_t m_tx_state = HAL_TRANSP_TX_STATE_CLOSED;
+
+/**
+ * @brief Transmission buffer.
+ */
+static uint8_t m_tx_buffer[SER_HAL_TRANSPORT_TX_MAX_PKT_SIZE];
+/**
+ * @brief Reception buffer.
+ */
+static uint8_t m_rx_buffer[SER_HAL_TRANSPORT_RX_MAX_PKT_SIZE];
+
+/**
+ * @brief Callback function handler for Serialization HAL Transport layer events.
+ */
+static ser_hal_transport_events_handler_t m_events_handler = NULL;
+
+
+/**
+ * @brief A callback function to be used to handle a PHY module events. This function is called in
+ * an interrupt context.
+ */
+static void phy_events_handler(ser_phy_evt_t phy_event)
+{
+ uint32_t err_code = 0;
+ ser_hal_transport_evt_t hal_transp_event;
+
+ memset(&hal_transp_event, 0, sizeof (ser_hal_transport_evt_t));
+ hal_transp_event.evt_type = SER_HAL_TRANSP_EVT_TYPE_MAX;
+
+ NRF_LOG_INFO("phy evt:%d", phy_event.evt_type);
+ switch (phy_event.evt_type)
+ {
+ case SER_PHY_EVT_TX_PKT_SENT:
+ {
+ if (HAL_TRANSP_TX_STATE_TRANSMITTING == m_tx_state)
+ {
+ m_tx_state = HAL_TRANSP_TX_STATE_TRANSMITTED;
+ NRF_LOG_INFO("tx free");
+ err_code = ser_hal_transport_tx_pkt_free(m_tx_buffer);
+ APP_ERROR_CHECK(err_code);
+ /* An event to an upper layer that a packet has been transmitted. */
+ hal_transp_event.evt_type = SER_HAL_TRANSP_EVT_TX_PKT_SENT;
+ m_events_handler(hal_transp_event);
+ }
+ else
+ {
+ /* Lower layer should not generate this event in current state. */
+ APP_ERROR_CHECK_BOOL(false);
+ }
+ break;
+ }
+
+ case SER_PHY_EVT_RX_BUF_REQUEST:
+ {
+ /* An event to an upper layer that a packet is being scheduled to receive or to drop. */
+ hal_transp_event.evt_type = SER_HAL_TRANSP_EVT_RX_PKT_RECEIVING;
+
+ /* Receive or drop a packet. */
+ if (phy_event.evt_params.rx_buf_request.num_of_bytes <= sizeof (m_rx_buffer))
+ {
+ if (HAL_TRANSP_RX_STATE_IDLE == m_rx_state)
+ {
+ m_events_handler(hal_transp_event);
+ err_code = ser_phy_rx_buf_set(m_rx_buffer);
+ APP_ERROR_CHECK(err_code);
+ m_rx_state = HAL_TRANSP_RX_STATE_RECEIVING;
+ }
+ else if (HAL_TRANSP_RX_STATE_RECEIVED == m_rx_state)
+ {
+ /* It is OK to get know higher layer at this point that we are going to receive
+ * a new packet even though we will start receiving when rx buffer is freed. */
+ m_events_handler(hal_transp_event);
+ m_rx_state = HAL_TRANSP_RX_STATE_RECEIVED_PENDING_BUF_REQ;
+ }
+ else
+ {
+ /* Lower layer should not generate this event in current state. */
+ APP_ERROR_CHECK_BOOL(false);
+ }
+ }
+ else
+ {
+ /* There is not enough memory but packet has to be received to dummy location. */
+ if (HAL_TRANSP_RX_STATE_IDLE == m_rx_state)
+ {
+ m_events_handler(hal_transp_event);
+ err_code = ser_phy_rx_buf_set(NULL);
+ APP_ERROR_CHECK(err_code);
+ m_rx_state = HAL_TRANSP_RX_STATE_DROPPING;
+ }
+ else if (HAL_TRANSP_RX_STATE_RECEIVED == m_rx_state)
+ {
+ m_events_handler(hal_transp_event);
+ err_code = ser_phy_rx_buf_set(NULL);
+ APP_ERROR_CHECK(err_code);
+ m_rx_state = HAL_TRANSP_RX_STATE_RECEIVED_DROPPING;
+ }
+ else
+ {
+ /* Lower layer should not generate this event in current state. */
+ APP_ERROR_CHECK_BOOL(false);
+ }
+ }
+ break;
+ }
+
+ case SER_PHY_EVT_RX_PKT_RECEIVED:
+ {
+ if (HAL_TRANSP_RX_STATE_RECEIVING == m_rx_state)
+ {
+ m_rx_state = HAL_TRANSP_RX_STATE_RECEIVED;
+ /* Generate the event to an upper layer. */
+ hal_transp_event.evt_type =
+ SER_HAL_TRANSP_EVT_RX_PKT_RECEIVED;
+ hal_transp_event.evt_params.rx_pkt_received.p_buffer =
+ phy_event.evt_params.rx_pkt_received.p_buffer;
+ hal_transp_event.evt_params.rx_pkt_received.num_of_bytes =
+ phy_event.evt_params.rx_pkt_received.num_of_bytes;
+ m_events_handler(hal_transp_event);
+ }
+ else
+ {
+ /* Lower layer should not generate this event in current state. */
+ APP_ERROR_CHECK_BOOL(false);
+ }
+ break;
+ }
+
+ case SER_PHY_EVT_RX_PKT_DROPPED:
+ {
+ if (HAL_TRANSP_RX_STATE_DROPPING == m_rx_state)
+ {
+ /* Generate the event to an upper layer. */
+ hal_transp_event.evt_type = SER_HAL_TRANSP_EVT_RX_PKT_DROPPED;
+ m_events_handler(hal_transp_event);
+ m_rx_state = HAL_TRANSP_RX_STATE_IDLE;
+ }
+ else if (HAL_TRANSP_RX_STATE_RECEIVED_DROPPING == m_rx_state)
+ {
+ /* Generate the event to an upper layer. */
+ hal_transp_event.evt_type = SER_HAL_TRANSP_EVT_RX_PKT_DROPPED;
+ m_events_handler(hal_transp_event);
+ m_rx_state = HAL_TRANSP_RX_STATE_RECEIVED;
+ }
+ else
+ {
+ /* Lower layer should not generate this event in current state. */
+ APP_ERROR_CHECK_BOOL(false);
+ }
+ break;
+ }
+
+ case SER_PHY_EVT_RX_OVERFLOW_ERROR:
+ {
+ /* Generate the event to an upper layer. */
+ hal_transp_event.evt_type = SER_HAL_TRANSP_EVT_PHY_ERROR;
+ hal_transp_event.evt_params.phy_error.error_type =
+ SER_HAL_TRANSP_PHY_ERROR_RX_OVERFLOW;
+ m_events_handler(hal_transp_event);
+ break;
+ }
+
+ case SER_PHY_EVT_TX_OVERREAD_ERROR:
+ {
+ /* Generate the event to an upper layer. */
+ hal_transp_event.evt_type = SER_HAL_TRANSP_EVT_PHY_ERROR;
+ hal_transp_event.evt_params.phy_error.error_type =
+ SER_HAL_TRANSP_PHY_ERROR_TX_OVERREAD;
+ m_events_handler(hal_transp_event);
+ break;
+ }
+
+ case SER_PHY_EVT_HW_ERROR:
+ {
+ /* Generate the event to an upper layer. */
+ hal_transp_event.evt_type = SER_HAL_TRANSP_EVT_PHY_ERROR;
+ hal_transp_event.evt_params.phy_error.error_type =
+ SER_HAL_TRANSP_PHY_ERROR_HW_ERROR;
+ hal_transp_event.evt_params.phy_error.hw_error_code =
+ phy_event.evt_params.hw_error.error_code;
+ if (HAL_TRANSP_TX_STATE_TRANSMITTING == m_tx_state)
+ {
+ m_tx_state = HAL_TRANSP_TX_STATE_TRANSMITTED;
+ err_code = ser_hal_transport_tx_pkt_free(phy_event.evt_params.hw_error.p_buffer);
+ APP_ERROR_CHECK(err_code);
+ /* An event to an upper layer that a packet has been transmitted. */
+ }
+ else if (HAL_TRANSP_RX_STATE_RECEIVING == m_rx_state)
+ {
+ m_rx_state = HAL_TRANSP_RX_STATE_RECEIVED;
+ err_code = ser_hal_transport_rx_pkt_free(phy_event.evt_params.hw_error.p_buffer);
+ APP_ERROR_CHECK(err_code);
+ }
+ m_events_handler(hal_transp_event);
+
+ break;
+ }
+
+ default:
+ {
+ APP_ERROR_CHECK_BOOL(false);
+ break;
+ }
+ }
+}
+
+uint32_t ser_hal_transport_open(ser_hal_transport_events_handler_t events_handler)
+{
+ uint32_t err_code = NRF_SUCCESS;
+
+ if ((HAL_TRANSP_RX_STATE_CLOSED != m_rx_state) || (HAL_TRANSP_TX_STATE_CLOSED != m_tx_state))
+ {
+ err_code = NRF_ERROR_INVALID_STATE;
+ }
+ else if (NULL == events_handler)
+ {
+ err_code = NRF_ERROR_NULL;
+ }
+ else
+ {
+ /* We have to change states before calling lower layer because ser_phy_open() function is
+ * going to enable interrupts. On success an event from PHY layer can be emitted immediately
+ * after return from ser_phy_open(). */
+ m_rx_state = HAL_TRANSP_RX_STATE_IDLE;
+ m_tx_state = HAL_TRANSP_TX_STATE_IDLE;
+
+ m_events_handler = events_handler;
+
+ /* Initialize a PHY module. */
+ err_code = ser_phy_open(phy_events_handler);
+
+ if (NRF_SUCCESS != err_code)
+ {
+ m_rx_state = HAL_TRANSP_RX_STATE_CLOSED;
+ m_tx_state = HAL_TRANSP_TX_STATE_CLOSED;
+ m_events_handler = NULL;
+
+ if (NRF_ERROR_INVALID_PARAM != err_code)
+ {
+ err_code = NRF_ERROR_INTERNAL;
+ }
+ }
+ }
+
+ return err_code;
+}
+
+
+void ser_hal_transport_close(void)
+{
+ /* Reset generic handler for all events, reset internal states and close PHY module. */
+ ser_phy_interrupts_disable();
+ m_rx_state = HAL_TRANSP_RX_STATE_CLOSED;
+ m_tx_state = HAL_TRANSP_TX_STATE_CLOSED;
+
+ m_events_handler = NULL;
+
+ ser_phy_close();
+}
+
+
+uint32_t ser_hal_transport_rx_pkt_free(uint8_t * p_buffer)
+{
+
+ NRF_LOG_INFO("rx pkt free:%d", p_buffer);
+ uint32_t err_code = NRF_SUCCESS;
+
+ ser_phy_interrupts_disable();
+
+ if (NULL == p_buffer)
+ {
+ err_code = NRF_ERROR_NULL;
+ }
+ else if (p_buffer != m_rx_buffer)
+ {
+ err_code = NRF_ERROR_INVALID_ADDR;
+ }
+ else if (HAL_TRANSP_RX_STATE_RECEIVED == m_rx_state)
+ {
+ m_rx_state = HAL_TRANSP_RX_STATE_IDLE;
+ }
+ else if (HAL_TRANSP_RX_STATE_RECEIVED_DROPPING == m_rx_state)
+ {
+ m_rx_state = HAL_TRANSP_RX_STATE_DROPPING;
+ }
+ else if (HAL_TRANSP_RX_STATE_RECEIVED_PENDING_BUF_REQ == m_rx_state)
+ {
+ err_code = ser_phy_rx_buf_set(m_rx_buffer);
+
+ if (NRF_SUCCESS == err_code)
+ {
+ m_rx_state = HAL_TRANSP_RX_STATE_RECEIVING;
+ }
+ else
+ {
+ err_code = NRF_ERROR_INTERNAL;
+ }
+ }
+ else
+ {
+ /* Upper layer should not call this function in current state. */
+ err_code = NRF_ERROR_INVALID_STATE;
+ }
+ ser_phy_interrupts_enable();
+
+ return err_code;
+}
+
+
+uint32_t ser_hal_transport_tx_pkt_alloc(uint8_t * * pp_memory, uint16_t * p_num_of_bytes)
+{
+ uint32_t err_code = NRF_SUCCESS;
+
+ if ((NULL == pp_memory) || (NULL == p_num_of_bytes))
+ {
+ err_code = NRF_ERROR_NULL;
+ }
+ else if (HAL_TRANSP_TX_STATE_CLOSED == m_tx_state)
+ {
+ err_code = NRF_ERROR_INVALID_STATE;
+ }
+ else if (HAL_TRANSP_TX_STATE_IDLE == m_tx_state)
+ {
+ m_tx_state = HAL_TRANSP_TX_STATE_TX_ALLOCATED;
+ *pp_memory = &m_tx_buffer[0];
+ *p_num_of_bytes = (uint16_t)sizeof (m_tx_buffer);
+ }
+ else
+ {
+ err_code = NRF_ERROR_NO_MEM;
+ }
+
+ return err_code;
+}
+
+
+uint32_t ser_hal_transport_tx_pkt_send(const uint8_t * p_buffer, uint16_t num_of_bytes)
+{
+ uint32_t err_code = NRF_SUCCESS;
+
+ /* The buffer provided to this function must be allocated through ser_hal_transport_tx_alloc()
+ * function - this assures correct state and that correct memory buffer is used. */
+ if (NULL == p_buffer)
+ {
+ err_code = NRF_ERROR_NULL;
+ }
+ else if (0 == num_of_bytes)
+ {
+ err_code = NRF_ERROR_INVALID_PARAM;
+ }
+ else if (p_buffer != m_tx_buffer)
+ {
+ err_code = NRF_ERROR_INVALID_ADDR;
+ }
+ else if (num_of_bytes > sizeof (m_tx_buffer))
+ {
+ err_code = NRF_ERROR_DATA_SIZE;
+ }
+ else if (HAL_TRANSP_TX_STATE_TX_ALLOCATED == m_tx_state)
+ {
+ ser_phy_interrupts_disable();
+ err_code = ser_phy_tx_pkt_send(p_buffer, num_of_bytes);
+
+ if (NRF_SUCCESS == err_code)
+ {
+ m_tx_state = HAL_TRANSP_TX_STATE_TRANSMITTING;
+ }
+ else
+ {
+ if (NRF_ERROR_BUSY != err_code)
+ {
+ err_code = NRF_ERROR_INTERNAL;
+ }
+ }
+ ser_phy_interrupts_enable();
+ }
+ else
+ {
+ err_code = NRF_ERROR_INVALID_STATE;
+ }
+
+ return err_code;
+}
+
+
+uint32_t ser_hal_transport_tx_pkt_free(uint8_t * p_buffer)
+{
+ uint32_t err_code = NRF_SUCCESS;
+
+ if (NULL == p_buffer)
+ {
+ err_code = NRF_ERROR_NULL;
+ }
+ else if (p_buffer != m_tx_buffer)
+ {
+ err_code = NRF_ERROR_INVALID_ADDR;
+ }
+ else if ((HAL_TRANSP_TX_STATE_TX_ALLOCATED == m_tx_state) ||
+ (HAL_TRANSP_TX_STATE_TRANSMITTED == m_tx_state))
+ {
+ /* Release TX buffer for use. */
+ m_tx_state = HAL_TRANSP_TX_STATE_IDLE;
+ }
+ else
+ {
+ err_code = NRF_ERROR_INVALID_STATE;
+ }
+
+ return err_code;
+}
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/common/transport/ser_hal_transport.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/common/transport/ser_hal_transport.h
new file mode 100644
index 0000000..e0b78be
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/common/transport/ser_hal_transport.h
@@ -0,0 +1,266 @@
+/**
+ * Copyright (c) 2014 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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
+ *
+ * @defgroup ser_hal_transport Serialization HAL Transport
+ * @{
+ * @ingroup ble_sdk_lib_serialization
+ *
+ * @brief HAL Transport layer for serialization.
+ *
+ * @details The @ref ser_hal_transport declares functions and typedefs used as API of the HAL
+ * transport layer for serialization. This layer is fully hardware-independent.
+ * Currently, the HAL transport layer is responsible for controlling the PHY layer and
+ * memory management. In the future, more features might be added to it, such as CRC
+ * or retransmission.
+ *
+ * \n \n
+ * \image html ser_hal_transport_rx_state_machine.svg "RX state machine"
+ * \n \n
+ * \image html ser_hal_transport_tx_state_machine.svg "TX state machine"
+ * \n
+ */
+
+#ifndef SER_HAL_TRANSPORT_H__
+#define SER_HAL_TRANSPORT_H__
+
+#include <stdint.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+/**@brief Serialization HAL Transport layer event types. */
+typedef enum
+{
+ SER_HAL_TRANSP_EVT_TX_PKT_SENT = 0, /**< An event indicating that TX packet has been
+ transmitted. */
+ SER_HAL_TRANSP_EVT_RX_PKT_RECEIVING, /**< An event indicating that RX packet is being
+ scheduled to receive or to drop. */
+ SER_HAL_TRANSP_EVT_RX_PKT_RECEIVED, /**< An event indicating that RX packet is ready for
+ read. */
+ SER_HAL_TRANSP_EVT_RX_PKT_DROPPED, /**< An event indicating that RX packet was dropped
+ because it was longer than available buffer. */
+ SER_HAL_TRANSP_EVT_PHY_ERROR, /**< An event indicating error on PHY layer. */
+ SER_HAL_TRANSP_EVT_TYPE_MAX /**< Enumeration upper bound. */
+} ser_hal_transport_evt_type_t;
+
+
+/**@brief Serialization PHY layer error types. */
+typedef enum
+{
+ SER_HAL_TRANSP_PHY_ERROR_RX_OVERFLOW = 0, /**< An error indicating that more information has
+ been transmitted than the PHY module could handle. */
+ SER_HAL_TRANSP_PHY_ERROR_TX_OVERREAD, /**< An error indicating that the PHY module was forced to
+ transmit more information than possessed. */
+ SER_HAL_TRANSP_PHY_ERROR_HW_ERROR, /**< An error indicating a hardware error in the PHY
+ module. */
+ SER_HAL_TRANSP_PHY_ERROR_TYPE_MAX /**< Enumeration upper bound. */
+} ser_hal_transport_phy_error_type_t;
+
+
+/**@brief Struct containing parameters of event of type
+ * @ref SER_HAL_TRANSP_EVT_RX_PKT_RECEIVED.
+ */
+typedef struct
+{
+ uint8_t * p_buffer; /**< Pointer to a buffer containing a packet to read. */
+ uint16_t num_of_bytes; /**< Length of a received packet in octets. */
+} ser_hal_transport_evt_rx_pkt_received_params_t;
+
+
+/**@brief Struct containing parameters of event of type @ref SER_HAL_TRANSP_EVT_PHY_ERROR. */
+typedef struct
+{
+ ser_hal_transport_phy_error_type_t error_type; /**< Type of the PHY error. */
+ uint32_t hw_error_code; /**< Hardware error code - specific for a microcontroller. Parameter
+ is valid only for the PHY error of type
+ @ref SER_HAL_TRANSP_PHY_ERROR_HW_ERROR. */
+} ser_hal_transport_evt_phy_error_params_t;
+
+
+/**@brief Struct containing events from the Serialization HAL Transport layer.
+ *
+ * @note Some events do not have parameters, then the whole information is contained in the evt_type.
+ */
+typedef struct
+{
+ ser_hal_transport_evt_type_t evt_type; /**< Type of event. */
+ union /**< Union alternative identified by evt_type in the enclosing struct. */
+ {
+ ser_hal_transport_evt_rx_pkt_received_params_t rx_pkt_received; /**< Parameters of event of type @ref SER_HAL_TRANSP_EVT_RX_PKT_RECEIVED. */
+ ser_hal_transport_evt_phy_error_params_t phy_error; /**< Parameters of event of type @ref SER_HAL_TRANSP_EVT_PHY_ERROR. */
+ } evt_params;
+} ser_hal_transport_evt_t;
+
+
+/**@brief Generic callback function type to be used by all Serialization HAL Transport layer
+ * events.
+ *
+ * @param[in] event Serialization HAL Transport layer event.
+ */
+typedef void (*ser_hal_transport_events_handler_t)(ser_hal_transport_evt_t event);
+
+
+/**@brief Function for opening and initializing the Serialization HAL Transport layer.
+ *
+ * @note The function opens the transport channel, initializes a PHY layer, and registers the callback
+ * function to be used by all Serialization HAL Transport layer events.
+ *
+ * @warning If the function has been already called, the function @ref ser_hal_transport_close has
+ * to be called before ser_hal_transport_open can be called again.
+ *
+ * @param[in] events_handler Generic callback function to be used by all Serialization HAL
+ * Transport layer events.
+ *
+ * @retval NRF_SUCCESS Operation success.
+ * @retval NRF_ERROR_NULL Operation failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_PARAM Operation failure. Hardware initialization parameters taken from
+ * the configuration file are wrong.
+ * @retval NRF_ERROR_INVALID_STATE Operation failure. The function has been already called. To call
+ * it again the function @ref ser_hal_transport_close has to be
+ * called first.
+ * @retval NRF_ERROR_INTERNAL Operation failure. Internal error ocurred.
+ */
+uint32_t ser_hal_transport_open(ser_hal_transport_events_handler_t events_handler);
+
+
+/**@brief Function for closing a transport channel.
+ *
+ * @note The function disables the hardware, resets internal module states, and unregisters the events
+ * callback function. Can be called multiple times, also for a channel that is not opened.
+ */
+void ser_hal_transport_close(void);
+
+
+/**@brief Function for freeing memory allocated for an RX packet.
+ *
+ * @note The function should be called as a response to an event of type
+ * @ref SER_HAL_TRANSP_EVT_RX_PKT_RECEIVED when the received data has beed processed. The function
+ * frees the RX memory pointed by p_buffer. The memory, immediately or at a later time, is
+ * reused by the underlying transport layer.
+ *
+ * @param[in] p_buffer A pointer to the beginning of the buffer that has been processed (has to be
+ * the same address as provided in the event of type
+ * @ref SER_HAL_TRANSP_EVT_RX_PKT_RECEIVED).
+ *
+ * @retval NRF_SUCCESS Operation success.
+ * @retval NRF_ERROR_NULL Operation failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_ADDR Operation failure. Not a valid pointer (provided address is not
+ * the starting address of a buffer managed by HAL Transport layer).
+ * @retval NRF_ERROR_INVALID_STATE Operation failure. The function should be called as a response
+ * to an event of type @ref SER_HAL_TRANSP_EVT_RX_PKT_RECEIVED.
+ * @retval NRF_ERROR_INTERNAL Operation failure. Internal error ocurred.
+ */
+uint32_t ser_hal_transport_rx_pkt_free(uint8_t * p_buffer);
+
+
+/**@brief Function for allocating memory for a TX packet.
+ *
+ * @param[out] pp_memory A pointer to pointer to which an address of the beginning of the
+ * allocated buffer is written.
+ * @param[out] p_num_of_bytes A pointer to a variable to which size in octets of the allocated
+ * buffer is written.
+ *
+ * @retval NRF_SUCCESS Operation success. Memory was allocated.
+ * @retval NRF_ERROR_NULL Operation failure. NULL pointer supplied.
+ * @retval NRF_ERROR_NO_MEM Operation failure. No memory available.
+ * @retval NRF_ERROR_INVALID_STATE Operation failure. The function was called before calling
+ * @ref ser_hal_transport_open function.
+ */
+uint32_t ser_hal_transport_tx_pkt_alloc(uint8_t ** pp_memory, uint16_t * p_num_of_bytes);
+
+/**@brief Function for transmitting a packet.
+ *
+ * @note The function adds a packet pointed by the p_buffer parameter to a transmission queue. A buffer
+ * provided to this function must be allocated by the @ref ser_hal_transport_tx_pkt_alloc function.
+ *
+ * @warning Completion of this method does not guarantee that actual peripheral transmission will be completed.
+ *
+ * @param[in] p_buffer Pointer to the buffer to transmit.
+ * @param[in] num_of_bytes Number of octets to transmit. Must be more than 0.
+ *
+ * @retval NRF_SUCCESS Operation success. Packet was added to the transmission queue.
+ * @retval NRF_ERROR_NULL Operation failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_PARAM Operation failure. num_of_bytes is equal to 0.
+ * @retval NRF_ERROR_INVALID_ADDR Operation failure. Not a valid pointer (provided address is not
+ * the starting address of a buffer managed by HAL Transport layer).
+ * @retval NRF_ERROR_DATA_SIZE Operation failure. Packet size exceeds limit.
+ * @retval NRF_ERROR_BUSY Operation failure. Transmission queue is full so packet was not
+ * added to the transmission queue.
+ * @retval NRF_ERROR_INVALID_STATE Operation failure. Transmittion channel was not opened by
+ * @ref ser_hal_transport_open function or provided buffer was not
+ * allocated by @ref ser_hal_transport_tx_pkt_alloc function.
+ * @retval NRF_ERROR_INTERNAL Operation failure. Internal error ocurred.
+ */
+uint32_t ser_hal_transport_tx_pkt_send(const uint8_t * p_buffer, uint16_t num_of_bytes);
+
+
+/**@brief Function for freeing memory allocated for a TX packet.
+ *
+ * @note The function frees the TX memory pointed by p_buffer. Freeing a TX buffer is possible only if
+ * the buffer was allocated by @ref ser_hal_transport_tx_pkt_alloc function and transmittion
+ * is not in progress. When transmittion has finished, this function is automatically called by
+ * the Serialization HAL Transport layer, so the only case when this function should be used
+ * from outside is when a TX buffer was allocated but a transmittion has not been started
+ * (@ref ser_hal_transport_tx_pkt_send function has not been called).
+ *
+ * @param[in] p_buffer Pointer to the beginning of a buffer that has been allocated by
+ * @ref ser_hal_transport_tx_pkt_alloc function.
+ *
+ * @retval NRF_SUCCESS Operation success. Memory was freed.
+ * @retval NRF_ERROR_NULL Operation failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_ADDR Operation failure. Not a valid pointer (provided address is not
+ * the starting address of a buffer managed by HAL Transport layer).
+ * @retval NRF_ERROR_INVALID_STATE Operation failure. Freeing a TX buffer is possible only if the
+ * buffer was allocated by @ref ser_hal_transport_tx_pkt_alloc
+ * function and transmittion is not in progress.
+ */
+uint32_t ser_hal_transport_tx_pkt_free(uint8_t * p_buffer);
+
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* SER_HAL_TRANSPORT_H__ */
+/** @} */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/common/transport/ser_phy/config/ser_config_5W_app.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/common/transport/ser_phy/config/ser_config_5W_app.h
new file mode 100644
index 0000000..c9081e1
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/common/transport/ser_phy/config/ser_config_5W_app.h
@@ -0,0 +1,52 @@
+/**
+ * Copyright (c) 2014 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#ifndef SER_CONFIG_5W_APP_H__
+#define SER_CONFIG_5W_APP_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // SER_CONFIG_5W_APP_H__
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/common/transport/ser_phy/config/ser_phy_config_app.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/common/transport/ser_phy/config/ser_phy_config_app.h
new file mode 100644
index 0000000..04f9f74
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/common/transport/ser_phy/config/ser_phy_config_app.h
@@ -0,0 +1,106 @@
+/**
+ * Copyright (c) 2014 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#ifndef SER_PHY_CONFIG_APP_H__
+#define SER_PHY_CONFIG_APP_H__
+
+#include "boards.h"
+#include "ser_config.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#if defined(SPI_MASTER_0_ENABLE)
+#define SER_PHY_SPI_MASTER SPI_MASTER_0
+#endif
+#if defined(SPI_MASTER_1_ENABLE)
+#define SER_PHY_SPI_MASTER SPI_MASTER_1
+#endif
+#if defined(SPI_MASTER_2_ENABLE)
+#define SER_PHY_SPI_MASTER SPI_MASTER_2
+#endif
+
+#if (defined(SPI0_ENABLED) && (SPI0_ENABLED == 1)) || defined(SPI_MASTER_0_ENABLE)
+
+#define SER_PHY_SPI_MASTER_INSTANCE NRF_DRV_SPI_INSTANCE(0)
+#define SER_PHY_SPI_MASTER_PIN_SCK SER_APP_SPIM0_SCK_PIN
+#define SER_PHY_SPI_MASTER_PIN_MISO SER_APP_SPIM0_MISO_PIN
+#define SER_PHY_SPI_MASTER_PIN_MOSI SER_APP_SPIM0_MOSI_PIN
+#define SER_PHY_SPI_MASTER_PIN_SLAVE_SELECT SER_APP_SPIM0_SS_PIN
+#define SER_PHY_SPI_MASTER_PIN_SLAVE_REQUEST SER_APP_SPIM0_REQ_PIN
+#define SER_PHY_SPI_MASTER_PIN_SLAVE_READY SER_APP_SPIM0_RDY_PIN
+
+#elif (defined(SPI1_ENABLED) && (SPI1_ENABLED == 1)) || defined(SPI_MASTER_1_ENABLE)
+
+#define SER_PHY_SPI_MASTER_INSTANCE NRF_DRV_SPI_INSTANCE(1)
+#define SER_PHY_SPI_MASTER_PIN_SCK SER_APP_SPIM1_SCK_PIN
+#define SER_PHY_SPI_MASTER_PIN_MISO SER_APP_SPIM1_MISO_PIN
+#define SER_PHY_SPI_MASTER_PIN_MOSI SER_APP_SPIM1_MOSI_PIN
+#define SER_PHY_SPI_MASTER_PIN_SLAVE_SELECT SER_APP_SPIM1_SS_PIN
+#define SER_PHY_SPI_MASTER_PIN_SLAVE_REQUEST SER_APP_SPIM1_REQ_PIN
+#define SER_PHY_SPI_MASTER_PIN_SLAVE_READY SER_APP_SPIM1_RDY_PIN
+
+#elif (defined(SPI2_ENABLED) && (SPI2_ENABLED == 1)) || defined(SPI_MASTER_2_ENABLE)
+
+#define SER_PHY_SPI_MASTER_INSTANCE NRF_DRV_SPI_INSTANCE(2)
+#define SER_PHY_SPI_MASTER_PIN_SCK SER_APP_SPIM2_SCK_PIN
+#define SER_PHY_SPI_MASTER_PIN_MISO SER_APP_SPIM2_MISO_PIN
+#define SER_PHY_SPI_MASTER_PIN_MOSI SER_APP_SPIM2_MOSI_PIN
+#define SER_PHY_SPI_MASTER_PIN_SLAVE_SELECT SER_APP_SPIM2_SS_PIN
+#define SER_PHY_SPI_MASTER_PIN_SLAVE_REQUEST SER_APP_SPIM2_REQ_PIN
+#define SER_PHY_SPI_MASTER_PIN_SLAVE_READY SER_APP_SPIM2_RDY_PIN
+
+#endif
+
+#define CONN_CHIP_RESET_PIN_NO SER_CONN_CHIP_RESET_PIN /**< Pin used for reseting the connectivity. */
+
+/* UART configuration */
+#define UART_IRQ_PRIORITY APP_IRQ_PRIORITY_MID
+#define SER_PHY_UART_RX SER_APP_RX_PIN
+#define SER_PHY_UART_TX SER_APP_TX_PIN
+#define SER_PHY_UART_CTS SER_APP_CTS_PIN
+#define SER_PHY_UART_RTS SER_APP_RTS_PIN
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // SER_PHY_CONFIG_APP_H__
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/common/transport/ser_phy/config/ser_phy_config_conn.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/common/transport/ser_phy/config/ser_phy_config_conn.h
new file mode 100644
index 0000000..baff210
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/common/transport/ser_phy/config/ser_phy_config_conn.h
@@ -0,0 +1,82 @@
+/**
+ * Copyright (c) 2014 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#ifndef SER_PHY_CONFIG_CONN_H__
+#define SER_PHY_CONFIG_CONN_H__
+
+#include "boards.h"
+#include "ser_config.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/***********************************************************************************************//**
+ * SER_PHY layer configuration.
+ **************************************************************************************************/
+#define SER_PHY_SPI_PPI_RDY_CH 0
+#define SER_PHY_SPI_GPIOTE_RDY_CH 0
+
+#ifdef NRF_SPIS0
+#define SER_PHY_SPI_SLAVE_INSTANCE 0
+#else
+#define SER_PHY_SPI_SLAVE_INSTANCE 1
+#endif
+
+#define SER_PHY_SPI_SLAVE_REQ_PIN SER_CON_SPIS_REQ_PIN
+#define SER_PHY_SPI_SLAVE_RDY_PIN SER_CON_SPIS_RDY_PIN
+#define SER_PHY_SPI_SLAVE_SCK_PIN SER_CON_SPIS_SCK_PIN
+#define SER_PHY_SPI_SLAVE_MISO_PIN SER_CON_SPIS_MISO_PIN
+#define SER_PHY_SPI_SLAVE_MOSI_PIN SER_CON_SPIS_MOSI_PIN
+#define SER_PHY_SPI_SLAVE_SS_PIN SER_CON_SPIS_CSN_PIN
+
+/* UART configuration */
+#define UART_IRQ_PRIORITY APP_IRQ_PRIORITY_LOWEST
+
+#define SER_PHY_UART_RX SER_CON_RX_PIN
+#define SER_PHY_UART_TX SER_CON_TX_PIN
+#define SER_PHY_UART_CTS SER_CON_CTS_PIN
+#define SER_PHY_UART_RTS SER_CON_RTS_PIN
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // SER_PHY_CONFIG_CONN_H__
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/common/transport/ser_phy/config/ser_phy_debug_app.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/common/transport/ser_phy/config/ser_phy_debug_app.h
new file mode 100644
index 0000000..d60f15c
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/common/transport/ser_phy/config/ser_phy_debug_app.h
@@ -0,0 +1,198 @@
+/**
+ * Copyright (c) 2014 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#ifndef SER_PHY_DEBUG_APP_H__
+#define SER_PHY_DEBUG_APP_H__
+
+#ifndef SER_PHY_DEBUG_APP_ENABLE
+
+#define DEBUG_EVT_SPI_MASTER_RAW_REQUEST(data)
+#define DEBUG_EVT_SPI_MASTER_RAW_READY(data)
+#define DEBUG_EVT_SPI_MASTER_RAW_XFER_DONE(data)
+#define DEBUG_EVT_SPI_MASTER_RAW_API_CALL(data)
+#define DEBUG_EVT_SPI_MASTER_RAW_READY_EDGE(data)
+#define DEBUG_EVT_SPI_MASTER_RAW_REQUEST_EDGE(data)
+#define DEBUG_EVT_SPI_MASTER_PHY_TX_PKT_SENT(data)
+#define DEBUG_EVT_SPI_MASTER_PHY_RX_PKT_DROPPED(data)
+#define DEBUG_EVT_SPI_MASTER_PHY_RX_PKT_RECEIVED(data)
+#define DEBUG_EVT_SPI_MASTER_PHY_BUF_REQUEST(data)
+
+#define DEBUG_EVT_SPI_MASTER_RAW_XFER_GUARDED(data)
+#define DEBUG_EVT_SPI_MASTER_RAW_XFER_PASSED(data)
+#define DEBUG_EVT_SPI_MASTER_RAW_XFER_ABORTED(data)
+#define DEBUG_EVT_SPI_MASTER_RAW_XFER_RESTARTED(data)
+
+#else
+#include <stdint.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+//Low level hardware events
+typedef enum
+{
+ SPI_MASTER_RAW_READY,
+ SPI_MASTER_RAW_REQUEST,
+ SPI_MASTER_RAW_XFER_DONE,
+ SPI_MASTER_RAW_API_CALL,
+ SPI_MASTER_RAW_READY_EDGE,
+ SPI_MASTER_RAW_REQUEST_EDGE,
+ SPI_MASTER_RAW_XFER_STARTED,
+ SPI_MASTER_RAW_XFER_GUARDED,
+ SPI_MASTER_RAW_XFER_PASSED,
+ SPI_MASTER_RAW_XFER_ABORTED,
+ SPI_MASTER_RAW_XFER_RESTARTED,
+ SPI_MASTER_PHY_TX_PKT_SENT,
+ SPI_MASTER_PHY_BUF_REQUEST,
+ SPI_MASTER_PHY_RX_PKT_RECEIVED,
+ SPI_MASTER_PHY_RX_PKT_DROPPED,
+ SPI_MASTER_EVT_MAX
+} spi_master_raw_evt_type_t;
+
+
+//Low level hardware event definition
+typedef struct
+{
+ spi_master_raw_evt_type_t evt;
+ uint32_t data;
+} spi_master_raw_evt_t;
+
+typedef void (*spi_master_raw_callback_t)(spi_master_raw_evt_t event);
+
+void debug_init(spi_master_raw_callback_t spi_master_raw_evt_callback);
+
+void debug_evt(spi_master_raw_evt_type_t evt, uint32_t data);
+
+
+#define DEBUG_EVT(evt, data) \
+do { \
+ debug_evt(evt, data); \
+} while (0);
+
+
+#define DEBUG_EVT_SPI_MASTER_RAW_REQUEST(data) \
+do { \
+ DEBUG_EVT(SPI_MASTER_RAW_REQUEST, data); \
+} while (0);
+
+
+#define DEBUG_EVT_SPI_MASTER_RAW_READY(data) \
+do { \
+ DEBUG_EVT(SPI_MASTER_RAW_READY, data); \
+} while (0);
+
+
+#define DEBUG_EVT_SPI_MASTER_RAW_XFER_DONE(data) \
+do { \
+ DEBUG_EVT(SPI_MASTER_RAW_XFER_DONE, data); \
+} while (0);
+
+
+#define DEBUG_EVT_SPI_MASTER_RAW_API_CALL(data) \
+do { \
+ DEBUG_EVT(SPI_MASTER_RAW_API_CALL, data); \
+} while (0);
+
+
+#define DEBUG_EVT_SPI_MASTER_RAW_READY_EDGE(data) \
+do { \
+ DEBUG_EVT(SPI_MASTER_RAW_READY_EDGE, data); \
+} while (0);
+
+
+#define DEBUG_EVT_SPI_MASTER_RAW_REQUEST_EDGE(data) \
+do { \
+ DEBUG_EVT(SPI_MASTER_RAW_REQUEST_EDGE, data); \
+} while (0);
+
+
+#define DEBUG_EVT_SPI_MASTER_PHY_TX_PKT_SENT(data) \
+do { \
+ DEBUG_EVT(SPI_MASTER_PHY_TX_PKT_SENT, data); \
+} while (0);
+
+
+#define DEBUG_EVT_SPI_MASTER_PHY_RX_PKT_DROPPED(data) \
+do { \
+ DEBUG_EVT(SPI_MASTER_PHY_RX_PKT_DROPPED, data); \
+} while (0);
+
+
+#define DEBUG_EVT_SPI_MASTER_PHY_RX_PKT_RECEIVED(data) \
+do { \
+ DEBUG_EVT(SPI_MASTER_PHY_RX_PKT_RECEIVED, data); \
+} while (0);
+
+
+#define DEBUG_EVT_SPI_MASTER_PHY_BUF_REQUEST(data) \
+do { \
+ DEBUG_EVT(SPI_MASTER_PHY_BUF_REQUEST, data); \
+} while (0);
+
+#define DEBUG_EVT_SPI_MASTER_RAW_XFER_GUARDED(data) \
+do { \
+ DEBUG_EVT(SPI_MASTER_RAW_XFER_GUARDED, data); \
+} while (0);
+
+#define DEBUG_EVT_SPI_MASTER_RAW_XFER_PASSED(data) \
+do { \
+ DEBUG_EVT(SPI_MASTER_RAW_XFER_PASSED, data); \
+} while (0);
+
+#define DEBUG_EVT_SPI_MASTER_RAW_XFER_ABORTED(data) \
+do { \
+ DEBUG_EVT(SPI_MASTER_RAW_XFER_ABORTED, data); \
+} while (0);
+
+#define DEBUG_EVT_SPI_MASTER_RAW_XFER_RESTARTED(data) \
+do { \
+ DEBUG_EVT(SPI_MASTER_RAW_XFER_RESTARTED, data); \
+} while (0);
+
+
+
+#endif
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif //SER_PHY_DEBUG_APP_H__
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/common/transport/ser_phy/config/ser_phy_debug_conn.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/common/transport/ser_phy/config/ser_phy_debug_conn.h
new file mode 100644
index 0000000..f79b2d0
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/common/transport/ser_phy/config/ser_phy_debug_conn.h
@@ -0,0 +1,166 @@
+/**
+ * Copyright (c) 2014 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#ifndef SER_PHY_DEBUG_CONN_H__
+#define SER_PHY_DEBUG_CONN_H__
+
+#ifndef SER_PHY_DEBUG_CONN_ENABLE
+
+#define DEBUG_EVT_SPI_SLAVE_RAW_RX_XFER_DONE(data);
+
+#define DEBUG_EVT_SPI_SLAVE_RAW_TX_XFER_DONE(data);
+
+#define DEBUG_EVT_SPI_SLAVE_RAW_BUFFERS_SET(data);
+
+#define DEBUG_EVT_SPI_SLAVE_RAW_REQ_SET(data);
+
+#define DEBUG_EVT_SPI_SLAVE_RAW_REQ_CLEARED(data);
+
+#define DEBUG_EVT_SPI_SLAVE_PHY_BUF_REQUEST(data);
+
+#define DEBUG_EVT_SPI_SLAVE_PHY_PKT_RECEIVED(data);
+
+#define DEBUG_EVT_SPI_SLAVE_PHY_PKT_DROPPED(data);
+
+#define DEBUG_EVT_SPI_SLAVE_PHY_PKT_SENT(data);
+
+#else
+
+#include <stdint.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+// low level hardware event types
+typedef enum
+{
+ SPI_SLAVE_RAW_BUFFERS_SET,
+ SPI_SLAVE_RAW_RX_XFER_DONE,
+ SPI_SLAVE_RAW_TX_XFER_DONE,
+ SPI_SLAVE_RAW_REQ_SET,
+ SPI_SLAVE_RAW_REQ_CLEARED,
+ SPI_SLAVE_PHY_BUF_REQUEST,
+ SPI_SLAVE_PHY_PKT_SENT,
+ SPI_SLAVE_PHY_PKT_RECEIVED,
+ SPI_SLAVE_PHY_PKT_DROPPED,
+ SPI_SLAVE_RAW_EVT_TYPE_MAX
+} spi_slave_raw_evt_type_t;
+
+// low level hardware event definition
+typedef struct
+{
+ spi_slave_raw_evt_type_t evt_type;
+ uint32_t data;
+} spi_slave_raw_evt_t;
+
+typedef void (*spi_slave_raw_callback_t)(spi_slave_raw_evt_t event);
+
+void debug_init(spi_slave_raw_callback_t spi_slave_raw_evt_callback);
+
+void debug_evt(spi_slave_raw_evt_type_t evt_type, uint32_t data);
+
+#define DEBUG_EVT(evt, data) \
+do { \
+ debug_evt(evt, data); \
+} while (0);
+
+
+#define DEBUG_EVT_SPI_SLAVE_RAW_RX_XFER_DONE(data) \
+do { \
+ DEBUG_EVT(SPI_SLAVE_RAW_RX_XFER_DONE, data); \
+} while (0);
+
+
+#define DEBUG_EVT_SPI_SLAVE_RAW_TX_XFER_DONE(data) \
+do { \
+ DEBUG_EVT(SPI_SLAVE_RAW_TX_XFER_DONE, data); \
+} while (0);
+
+
+#define DEBUG_EVT_SPI_SLAVE_RAW_BUFFERS_SET(data) \
+do { \
+ DEBUG_EVT(SPI_SLAVE_RAW_BUFFERS_SET, data); \
+} while (0);
+
+
+#define DEBUG_EVT_SPI_SLAVE_RAW_REQ_SET(data) \
+do { \
+ DEBUG_EVT(SPI_SLAVE_RAW_REQ_SET, data); \
+} while (0);
+
+
+#define DEBUG_EVT_SPI_SLAVE_RAW_REQ_CLEARED(data) \
+do { \
+ DEBUG_EVT(SPI_SLAVE_RAW_REQ_CLEARED, data); \
+} while (0);
+
+
+#define DEBUG_EVT_SPI_SLAVE_PHY_BUF_REQUEST(data) \
+do { \
+ DEBUG_EVT(SPI_SLAVE_PHY_BUF_REQUEST, data); \
+} while (0);
+
+
+#define DEBUG_EVT_SPI_SLAVE_PHY_PKT_RECEIVED(data) \
+do { \
+ DEBUG_EVT(SPI_SLAVE_PHY_PKT_RECEIVED, data); \
+} while (0);
+
+
+#define DEBUG_EVT_SPI_SLAVE_PHY_PKT_DROPPED(data) \
+do { \
+ DEBUG_EVT(SPI_SLAVE_PHY_PKT_DROPPED, data); \
+} while (0);
+
+
+#define DEBUG_EVT_SPI_SLAVE_PHY_PKT_SENT(data) \
+do { \
+ DEBUG_EVT(SPI_SLAVE_PHY_PKT_SENT, data); \
+} while (0);
+
+
+#endif
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif //SER_PHY_DEBUG_CONN_H__
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/common/transport/ser_phy/ser_phy.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/common/transport/ser_phy/ser_phy.c
new file mode 100644
index 0000000..57220fe
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/common/transport/ser_phy/ser_phy.c
@@ -0,0 +1,88 @@
+/**
+ * Copyright (c) 2014 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#include "ser_phy.h"
+#include "app_error.h"
+
+
+__weak uint32_t ser_phy_open(ser_phy_events_handler_t events_handler)
+{
+ /* A function stub. Function should be implemented according to ser_phy.h API. */
+ APP_ERROR_CHECK_BOOL(false);
+
+ return NRF_SUCCESS;
+}
+
+__weak uint32_t ser_phy_tx_pkt_send(const uint8_t * p_buffer, uint16_t num_of_bytes)
+{
+ /* A function stub. Function should be implemented according to ser_phy.h API. */
+ APP_ERROR_CHECK_BOOL(false);
+
+ return NRF_SUCCESS;
+}
+
+__weak uint32_t ser_phy_rx_buf_set(uint8_t * p_buffer)
+{
+ /* A function stub. Function should be implemented according to ser_phy.h API. */
+ APP_ERROR_CHECK_BOOL(false);
+
+ return NRF_SUCCESS;
+}
+
+__weak void ser_phy_close(void)
+{
+ /* A function stub. Function should be implemented according to ser_phy.h API. */
+ APP_ERROR_CHECK_BOOL(false);
+}
+
+
+__weak void ser_phy_interrupts_enable(void)
+{
+ /* A function stub. Function should be implemented according to ser_phy.h API. */
+ APP_ERROR_CHECK_BOOL(false);
+}
+
+
+__weak void ser_phy_interrupts_disable(void)
+{
+ /* A function stub. Function should be implemented according to ser_phy.h API. */
+ APP_ERROR_CHECK_BOOL(false);
+}
+
+
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/common/transport/ser_phy/ser_phy.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/common/transport/ser_phy/ser_phy.h
new file mode 100644
index 0000000..d40c06e
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/common/transport/ser_phy/ser_phy.h
@@ -0,0 +1,308 @@
+/**
+ * Copyright (c) 2014 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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
+ *
+ * @defgroup ser_phy Serialization PHY
+ * @{
+ * @ingroup ble_sdk_lib_serialization
+ *
+ * @brief PHY layer for serialization.
+ *
+ * @details The @ref ser_phy library declares functions and definitions of data structures and
+ * identifiers (typedef enum) that are used as API of the serialization PHY layer.
+ *
+ * \par Rationale
+ * Each specific PHY layer (SPI, I2C, UART, low power UART etc.) should provide the same API. This
+ * allows the layer above (the HAL Transport layer), which is responsible for controlling the PHY
+ * layer, memory management, CRC, retransmission etc., to be hardware independent.
+ *
+ *
+ * \par Interlayer communication and control
+ * The PHY layer is controlled by the HAL transport layer by calling functions declared in
+ * the @ref ser_phy library.
+ *
+ * @par
+ * The PHY layer communicates events to the HAL transport layer by calling a callback function.
+ * A handler to this function is passed in the @ref ser_phy_open function. This callback function
+ * should be called with a parameter of type @ref ser_phy_evt_t, filled accordingly to an event to be
+ * passed. Types of supported events are defined in @ref ser_phy_evt_type_t.
+ *
+ * @par
+ * For example, to pass an event indicating that an RX packet has been successfully received, first a
+ * struct of type @ref ser_phy_evt_t must be filled:
+ * @code
+ * ser_phy_evt_t phy_evt;
+ * phy_evt.evt_type = SER_PHY_EVT_RX_PKT_RECEIVED;
+ * phy_evt.evt_params.rx_pkt_received.p_buffer = (pointer to the RX buffer);
+ * phy_evt.evt_params.rx_pkt_received.num_of_bytes = (number of received bytes);
+ * @endcode
+ * Then, the callback function must be called:
+ * @code
+ * events_handler(phy_evt);
+ * @endcode
+ * All functions declared in the @ref ser_phy file (ser_phy.h) must be implemented. Some events specified in
+ * @ref ser_phy_evt_type_t are optional to implement.
+ *
+ * \par Transmitting a packet
+ * Each PHY layer is responsible for adding the PHY header to a packet to be sent. This header
+ * consists of a 16-bit field that carries the packet length (the uint16_encode function defined in
+ * app_util.h should be used to ensure endianness independence). A pointer to a packet to be sent
+ * and length of the packet are parameters of the @ref ser_phy_tx_pkt_send function. When a packet
+ * has been transmitted, an event of type @ref SER_PHY_EVT_TX_PKT_SENT should be emitted.
+ *
+ * \image html ser_phy_transport_tx.svg "TX - interlayer communication"
+ *
+ * \par Receiving a packet
+ * The PHY layer should be able to store only the PHY header (16-bit field carrying the packet
+ * length). After the PHY header has been received, the transmission is stopped and the PHY
+ * layer must send a request to the HAL transport layer for memory to store the packet - an event
+ * of type @ref SER_PHY_EVT_RX_BUF_REQUEST with event parameters defined in
+ * @ref ser_phy_evt_rx_buf_request_params_t (the uint16_decode function defined in app_util.h should
+ * be used for header decoding to ensure endianness independence). The transmission should be
+ * resumed when the @ref ser_phy_rx_buf_set function has been called.
+ *
+ * @par
+ * When the @ref ser_phy_rx_buf_set function parameter equals NULL, there is not
+ * enough memory to store the packet. However, the packet will be received to a dummy location to
+ * ensure continuous communication. After receiving has finished, an event of type
+ * @ref SER_PHY_EVT_RX_PKT_DROPPED is generated.
+ *
+ * \image html ser_phy_transport_rx_dropped.svg "RX dropping - interlayer communication"
+ *
+ * @par
+ * When the @ref ser_phy_rx_buf_set function parameter is different than NULL, the packet is
+ * received to a buffer pointed to by it. After receiving has finished, an event of type
+ * @ref SER_PHY_EVT_RX_PKT_RECEIVED is generated with event parameters defined in
+ * @ref ser_phy_evt_rx_pkt_received_params_t.
+ *
+ * \image html ser_phy_transport_rx_received.svg "RX - interlayer communication"
+ *
+ * \par PHY layer errors
+ * PHY layer errors can be signaled by an event of type @ref SER_PHY_EVT_RX_OVERFLOW_ERROR or
+ * @ref SER_PHY_EVT_TX_OVERREAD_ERROR or @ref SER_PHY_EVT_HW_ERROR with event parameters defined in
+ * @ref ser_phy_evt_hw_error_params_t.
+ *
+ * @par Available PHY layers
+ * The following PHY layers are available:
+ * - @ref ser_phy_spi_page
+ * - @ref ser_phy_spi_5W_page
+ * - @ref ser_phy_uart_page
+ * - @ref ser_phy_uart_hci_page
+ * <!-- - @ref ser_phy_usb_hci_page -->
+ *
+ */
+
+#ifndef SER_PHY_H__
+#define SER_PHY_H__
+
+#include <stdint.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**@brief Serialization PHY module event types. */
+typedef enum
+{
+ SER_PHY_EVT_TX_PKT_SENT = 0, /**< Obligatory to implement. An event indicating that a TX packet
+ * has been transmitted. */
+ SER_PHY_EVT_RX_BUF_REQUEST, /**< Obligatory to implement. An event indicating that the PHY layer
+ * needs a buffer for an RX packet. The PHY flow should be blocked
+ * until the @ref ser_phy_rx_buf_set function is called. */
+ SER_PHY_EVT_RX_PKT_RECEIVED, /**< Obligatory to implement. An event indicating that an RX packet
+ * has been successfully received. */
+ SER_PHY_EVT_RX_PKT_DROPPED, /**< Obligatory to implement. An event indicating that the RX packet
+ * receiving has been finished but the packet was discarded because
+ * it was longer than available the buffer. */
+
+ SER_PHY_EVT_RX_OVERFLOW_ERROR, /**< Optional to implement. An event indicating that more
+ * information has been transmitted than the PHY module could
+ * handle. */
+ SER_PHY_EVT_TX_OVERREAD_ERROR, /**< Optional to implement. An event indicating that the PHY module
+ * was forced to transmit more information than possessed. */
+ SER_PHY_EVT_HW_ERROR, /**< Optional to implement. An event indicating a hardware error
+ * in the PHY module. */
+ SER_PHY_EVT_TYPE_MAX /**< Enumeration upper bound. */
+} ser_phy_evt_type_t;
+
+
+/**@brief A struct containing parameters of event of type @ref SER_PHY_EVT_RX_BUF_REQUEST. */
+typedef struct
+{
+ uint16_t num_of_bytes; /**< Length of a buffer in octets that the layer above the PHY module should
+ * deliver, so that the PHY module can receive a packet. */
+} ser_phy_evt_rx_buf_request_params_t;
+
+
+/**@brief A struct containing parameters of event of type @ref SER_PHY_EVT_RX_PKT_RECEIVED. */
+typedef struct
+{
+ uint8_t * p_buffer; /**< Pointer to a buffer containing the received packet. */
+ uint16_t num_of_bytes; /**< Length of the received packet in octets. */
+} ser_phy_evt_rx_pkt_received_params_t;
+
+
+/**@brief A struct containing parameters of event of type @ref SER_PHY_EVT_HW_ERROR. */
+typedef struct
+{
+ uint32_t error_code; /**< Hardware error code - specific for a microcontroller. */
+ uint8_t * p_buffer; /**< Pointer to the buffer that was processed when error occured. */
+} ser_phy_evt_hw_error_params_t;
+
+
+/**@brief A struct containing events from a Serialization PHY module.
+ *
+ * @note Some events do not have parameters, then whole information is contained in the evt_type.
+ */
+typedef struct
+{
+ ser_phy_evt_type_t evt_type; /**< Type of event. */
+
+ union /**< Union alternative identified by evt_type in enclosing struct. */
+ {
+ /** Parameters of event of type @ref SER_PHY_EVT_RX_BUF_REQUEST. */
+ ser_phy_evt_rx_buf_request_params_t rx_buf_request;
+ /** Parameters of event of type @ref SER_PHY_EVT_RX_PKT_RECEIVED. */
+ ser_phy_evt_rx_pkt_received_params_t rx_pkt_received;
+ /** Parameters of the event of type @ref SER_PHY_EVT_HW_ERROR. */
+ ser_phy_evt_hw_error_params_t hw_error;
+ } evt_params;
+} ser_phy_evt_t;
+
+
+/**@brief A type of generic callback function handler to be used by all PHY module events.
+ *
+ * @param[in] event Serialization PHY module event.
+ */
+typedef void (*ser_phy_events_handler_t)(ser_phy_evt_t event);
+
+
+/**@brief Function for opening and initializing the PHY module.
+ *
+ * @note The function initializes hardware and internal module states, and registers callback
+ * function to be used by all PHY module events.
+ *
+ * @warning If the function has been already called, the function @ref ser_phy_close has to be
+ * called before ser_phy_open can be called again.
+ *
+ * @param[in] events_handler Generic callback function handler to be used by all PHY module
+ * events.
+ *
+ * @retval NRF_SUCCESS Operation success.
+ * @retval NRF_ERROR_INVALID_STATE Operation failure. The function has been already called.
+ * To call it again, the function @ref ser_phy_close has to be
+ * called first.
+ * @retval NRF_ERROR_NULL Operation failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_PARAM Operation failure. Hardware initialization parameters are not
+ * supported.
+ */
+uint32_t ser_phy_open(ser_phy_events_handler_t events_handler);
+
+
+/**@brief Function for transmitting a packet.
+ *
+ * @note The function adds a packet pointed by p_buffer parameter to a transmission queue and
+ * schedules generation of an event of type @ref SER_PHY_EVT_TX_PKT_SENT upon transmission
+ * completion.
+ *
+ * @param[in] p_buffer Pointer to a buffer to transmit.
+ * @param[in] num_of_bytes Number of octets to transmit. Must be more than 0.
+ *
+ * @retval NRF_SUCCESS Operation success. Packet was added to the transmission queue
+ * and event will be send upon transmission completion.
+ * @retval NRF_ERROR_NULL Operation failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_PARAM Operation failure. The num_of_bytes parameter equal to 0.
+ * @retval NRF_ERROR_BUSY Operation failure. Transmitting of a packet in progress.
+ */
+uint32_t ser_phy_tx_pkt_send(const uint8_t * p_buffer, uint16_t num_of_bytes);
+
+
+/**@brief Function for setting an RX buffer and enabling reception of data (the PHY flow).
+ *
+ * @note The function has to be called as a response to an event of type
+ * @ref SER_PHY_EVT_RX_BUF_REQUEST. The function sets an RX buffer and enables reception of
+ * data (enables the PHY flow).
+ * Size of a buffer pointed by the p_buffer parameter should be at least equal to the
+ * num_of_bytes parameter passed within the event (@ref ser_phy_evt_rx_buf_request_params_t),
+ * or p_buffer should be equal to NULL if there is not enough memory.
+ * When p_buffer is different from NULL and num_of_bytes octets have been received, an event of
+ * type @ref SER_PHY_EVT_RX_PKT_RECEIVED is generated
+ * (@ref ser_phy_evt_rx_pkt_received_params_t).
+ * When p_buffer is equal to NULL, data is received to dummy location to ensure continuous
+ * communication. Then, if num_of_bytes octets have been received, an event of type
+ * @ref SER_PHY_EVT_RX_PKT_DROPPED is generated.
+ *
+ * @param[in] p_buffer Pointer to an RX buffer in which to receive.
+ *
+ * @retval NRF_SUCCESS Operation success.
+ * @retval NRF_ERROR_INVALID_STATE Operation failure. A buffer was set without request.
+ */
+uint32_t ser_phy_rx_buf_set(uint8_t * p_buffer);
+
+
+/**@brief Function for closing the PHY module.
+ *
+ * @note The function disables hardware, resets internal module states, and unregisters the events
+ * callback function.
+ */
+void ser_phy_close(void);
+
+
+/**@brief Function for enabling the PHY module interrupts.
+ *
+ * @note The function enables all interrupts that are used by the PHY module (and only those).
+ */
+void ser_phy_interrupts_enable(void);
+
+
+/**@brief Function for disabling the PHY module interrupts.
+ *
+ * @note The function disables all interrupts that are used by the PHY module (and only those).
+ */
+void ser_phy_interrupts_disable(void);
+
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* SER_PHY_H__ */
+/** @} */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/common/transport/ser_phy/ser_phy_hci.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/common/transport/ser_phy/ser_phy_hci.c
new file mode 100644
index 0000000..4e1f85a
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/common/transport/ser_phy/ser_phy_hci.c
@@ -0,0 +1,1704 @@
+/**
+ * Copyright (c) 2014 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#include <stddef.h>
+#include <string.h>
+
+#include "app_error.h"
+#include "app_util.h"
+#include "app_util_platform.h"
+#include "app_timer.h"
+#include "nrf_queue.h"
+#include "ser_phy.h"
+#include "ser_phy_hci.h"
+#include "crc16.h"
+#include "nrf_soc.h"
+#include "ser_config.h"
+#include "ser_phy_debug_comm.h"
+#define NRF_LOG_MODULE_NAME sphy_hci
+#include "nrf_log.h"
+NRF_LOG_MODULE_REGISTER();
+// hide globals for release version, expose for debug version
+#if defined(SER_PHY_HCI_DEBUG_ENABLE)
+#define _static
+#else
+#define _static static
+#endif
+
+#define PKT_HDR_SIZE 4 /**< Packet header size in number of bytes. */
+#define PKT_CRC_SIZE 2 /**< Packet CRC size in number of bytes. */
+#define MAX_PACKET_SIZE_IN_BITS (11uL * \
+ (SER_HAL_TRANSPORT_MAX_PKT_SIZE + PKT_HDR_SIZE + PKT_CRC_SIZE))
+#define BAUD_TIME_us (1000000uL / SER_PHY_UART_BAUDRATE_VAL)
+
+#define TX_EVT_QUEUE_SIZE 16
+#define RX_EVT_QUEUE_SIZE 16
+#define PKT_TYPE_VENDOR_SPECIFIC 14 /**< Packet type vendor specific. */
+#define PKT_TYPE_ACK 0 /**< Packet type acknowledgement. */
+#define PKT_TYPE_LINK_CONTROL 15 /**< Packet type link control. */
+#define PKT_TYPE_RESET 5 /**< Packet type reset. */
+#define DATA_INTEGRITY_MASK (1 << 6) /**< Mask for data integrity bit in the packet header. */
+#define RELIABLE_PKT_MASK (1 << 7) /**< Mask for reliable packet bit in the packet header. */
+#define INITIAL_ACK_NUMBER_EXPECTED 0 /**< Initial acknowledge number expected. */
+#define INITIAL_SEQ_NUMBER INITIAL_ACK_NUMBER_EXPECTED /**< Initial acknowledge number transmitted. */
+#define INVALID_PKT_TYPE 0xFFFFFFFFu /**< Internal invalid packet type value. */
+#define MAX_TRANSMISSION_TIME_ms (MAX_PACKET_SIZE_IN_BITS * BAUD_TIME_us / 1000uL) /**< Max transmission time of a single application packet over UART in units of mseconds. */
+#define RETRANSMISSION_TIMEOUT_IN_ms (50uL * MAX_TRANSMISSION_TIME_ms) /**< Retransmission timeout for application packet in units of mseconds. */
+
+#ifdef HCI_LINK_CONTROL
+#define HCI_PKT_SYNC 0x7E01u /**< Link Control Packet: type SYNC */
+#define HCI_PKT_SYNC_RSP 0x7D02u /**< Link Control Packet: type SYNC RESPONSE */
+#define HCI_PKT_CONFIG 0xFC03u /**< Link Control Packet: type CONFIG */
+#define HCI_PKT_CONFIG_RSP 0x7B04u /**< Link Control Packet: type CONFIG RESPONSE */
+#define HCI_CONFIG_FIELD 0x11u /**< Configuration field of CONFIG and CONFIG_RSP packet */
+#define HCI_PKT_SYNC_SIZE 6u /**< Size of SYNC and SYNC_RSP packet */
+#define HCI_PKT_CONFIG_SIZE 7u /**< Size of CONFIG and CONFIG_RSP packet */
+#define HCI_LINK_CONTROL_PKT_INVALID 0xFFFFu /**< Size of CONFIG and CONFIG_RSP packet */
+#define HCI_LINK_CONTROL_TIMEOUT 1u /**< Default link control timeout. */
+#endif /* HCI_LINK_CONTROL */
+
+
+#define RETRANSMISSION_TIMEOUT_IN_TICKS (APP_TIMER_TICKS(RETRANSMISSION_TIMEOUT_IN_ms)) /**< Retransmission timeout for application packet in units of timer ticks. */
+#define MAX_RETRY_COUNT 5 /**< Max retransmission retry count for application packets. */
+
+#if (defined(HCI_TIMER0))
+#define HCI_TIMER NRF_TIMER0
+#define HCI_TIMER_IRQn TIMER0_IRQn
+#define HCI_TIMER_IRQHandler TIMER0_IRQHandler
+#elif (defined(HCI_TIMER1))
+#define HCI_TIMER NRF_TIMER1
+#define HCI_TIMER_IRQn TIMER1_IRQn
+#define HCI_TIMER_IRQHandler TIMER1_IRQHandler
+#elif (defined(HCI_TIMER2))
+#define HCI_TIMER NRF_TIMER2
+#define HCI_TIMER_IRQn TIMER2_IRQn
+#define HCI_TIMER_IRQHandler TIMER2_IRQHandler
+#else
+#define HCI_APP_TIMER
+#endif
+
+
+/**@brief States of the hci event driven state machine. */
+typedef enum
+{
+ HCI_TX_STATE_DISABLE,
+ HCI_TX_STATE_SEND,
+ HCI_TX_STATE_WAIT_FOR_FIRST_TX_END,
+ HCI_TX_STATE_WAIT_FOR_ACK_OR_TX_END,
+ HCI_TX_STATE_WAIT_FOR_ACK,
+ HCI_TX_STATE_WAIT_FOR_TX_END
+} hci_tx_fsm_state_t;
+
+typedef enum
+{
+ HCI_RX_STATE_DISABLE,
+ HCI_RX_STATE_RECEIVE,
+ HCI_RX_STATE_WAIT_FOR_MEM,
+ HCI_RX_STATE_WAIT_FOR_SLIP_ACK_END,
+ HCI_RX_STATE_WAIT_FOR_SLIP_NACK_END,
+} hci_rx_fsm_state_t;
+
+typedef enum
+{
+ HCI_EVT_TIMEOUT,
+} hci_timer_evt_type_t;
+
+typedef enum
+{
+ HCI_SER_PHY_TX_REQUEST,
+ HCI_SER_PHY_RX_BUF_GRANTED,
+ HCI_SER_PHY_EVT_GEN_ENABLE,
+ HCI_SER_PHY_EVT_GEN_DISABLE
+} ser_phy_int_evt_type_t;
+
+typedef enum
+{
+ HCI_SER_PHY_EVT,
+ HCI_SLIP_EVT,
+ HCI_TIMER_EVT,
+} hci_evt_source_t;
+
+#ifdef HCI_LINK_CONTROL
+typedef enum
+{
+ HCI_MODE_DISABLE,
+ HCI_MODE_UNINITIALIZED,
+ HCI_MODE_INITIALIZED,
+ HCI_MODE_ACTIVE,
+} hci_mode_t;
+#endif /*HCI_LINK_CONTROL */
+
+typedef struct
+{
+ hci_timer_evt_type_t evt_type; /**< Type of an event. */
+} hci_timer_evt_t;
+
+typedef struct
+{
+ ser_phy_int_evt_type_t evt_type; /**< Type of an event. */
+} ser_phy_int_evt_t;
+
+typedef struct
+{
+ hci_evt_source_t evt_source; /**< source of an event. */
+ union
+ {
+ ser_phy_int_evt_t ser_phy_evt; /**< ser_phy event. */
+ ser_phy_hci_slip_evt_t ser_phy_slip_evt; /**< ser_phy_hci event. */
+ hci_timer_evt_t timer_evt; /**< timer event. */
+ } evt;
+} hci_evt_t;
+
+_static uint8_t m_tx_packet_header[PKT_HDR_SIZE];
+_static uint8_t m_tx_packet_crc[PKT_CRC_SIZE];
+_static uint8_t m_tx_ack_packet[PKT_HDR_SIZE];
+#ifdef HCI_LINK_CONTROL
+_static uint8_t m_tx_link_control_header[PKT_HDR_SIZE];
+_static uint8_t m_tx_link_control_payload[HCI_PKT_CONFIG_SIZE - PKT_HDR_SIZE];
+#endif /* HCI_LINK_CONTROL */
+
+_static uint32_t m_packet_ack_number; // Sequence number counter of the packet expected to be received
+_static uint32_t m_packet_seq_number; // Sequence number counter of the transmitted packet for which acknowledgement packet is waited for
+
+
+_static uint32_t m_tx_retry_count;
+
+
+// _static uint32_t m_tx_retx_counter = 0;
+// _static uint32_t m_rx_drop_counter = 0;
+
+NRF_QUEUE_DEF(hci_evt_t,
+ m_tx_evt_queue,
+ TX_EVT_QUEUE_SIZE,
+ NRF_QUEUE_MODE_NO_OVERFLOW);
+
+NRF_QUEUE_DEF(hci_evt_t,
+ m_rx_evt_queue,
+ RX_EVT_QUEUE_SIZE,
+ NRF_QUEUE_MODE_NO_OVERFLOW);
+
+_static hci_tx_fsm_state_t m_hci_tx_fsm_state = HCI_TX_STATE_DISABLE;
+_static hci_rx_fsm_state_t m_hci_rx_fsm_state = HCI_RX_STATE_DISABLE;
+
+#ifdef HCI_LINK_CONTROL
+_static hci_mode_t m_hci_mode = HCI_MODE_DISABLE;
+_static uint16_t m_hci_link_control_next_pkt = HCI_PKT_SYNC;
+_static bool m_hci_other_side_active = false;
+#endif /* HCI_LINK_CONTROL */
+
+#ifdef HCI_APP_TIMER
+APP_TIMER_DEF(m_app_timer_id);
+#endif
+
+_static bool m_tx_fsm_idle_flag = true;
+_static bool m_rx_fsm_idle_flag = true;
+
+_static bool m_buffer_reqested_flag = false;
+
+_static uint8_t * m_p_rx_buffer = NULL;
+_static uint16_t m_rx_packet_length;
+_static uint8_t * m_p_rx_packet;
+_static uint8_t * m_p_tx_payload = NULL;
+_static uint16_t m_tx_payload_length;
+
+_static ser_phy_events_handler_t m_ser_phy_callback = NULL;
+
+static void hci_tx_event_handler(hci_evt_t * p_event);
+static void hci_rx_event_handler(hci_evt_t * p_event);
+#ifdef HCI_LINK_CONTROL
+static void hci_link_control_event_handler(hci_evt_t * p_event);
+#endif /* HCI_LINK_CONTROL */
+
+_static bool m_hci_timer_enabled_flag = true;
+_static bool m_hci_timout_pending_flag = false;
+_static bool m_hci_global_enable_flag = true;
+
+#define ser_phy_hci_assert(cond) APP_ERROR_CHECK_BOOL(cond)
+
+static void hci_signal_timeout_event(void)
+{
+ hci_evt_t event;
+
+ event.evt_source = HCI_TIMER_EVT;
+ event.evt.timer_evt.evt_type = HCI_EVT_TIMEOUT;
+ DEBUG_EVT_TIMEOUT(0);
+
+#ifndef HCI_LINK_CONTROL
+ hci_tx_event_handler(&event);
+#else
+ hci_link_control_event_handler(&event);
+ if ((m_hci_mode == HCI_MODE_ACTIVE) && m_hci_other_side_active)
+ {
+ hci_tx_event_handler(&event);
+ }
+#endif /* HCI_LINK_CONTROL */
+}
+
+
+#ifndef HCI_APP_TIMER
+
+void HCI_TIMER_IRQHandler(void)
+{
+
+ if ((HCI_TIMER->EVENTS_COMPARE[1] == 1) && (HCI_TIMER->INTENSET & TIMER_INTENSET_COMPARE1_Msk))
+ {
+ HCI_TIMER->EVENTS_COMPARE[1] = 0;
+ HCI_TIMER->TASKS_CLEAR = 1;
+
+ if (m_hci_timer_enabled_flag)
+ {
+ hci_signal_timeout_event();
+ }
+ else
+ {
+ m_hci_timout_pending_flag = true;
+ }
+ }
+}
+
+
+static void hci_timeout_setup(uint32_t count)
+{
+
+ uint32_t time_msec;
+
+ if (count)
+ {
+ HCI_TIMER->INTENCLR = TIMER_INTENCLR_COMPARE1_Msk;
+ time_msec = count * RETRANSMISSION_TIMEOUT_IN_ms;
+ HCI_TIMER->CC[1] = time_msec * 31;
+ HCI_TIMER->CC[1] += time_msec / 4;
+ HCI_TIMER->TASKS_CLEAR = 1; // < Clear TIMER
+ HCI_TIMER->EVENTS_COMPARE[1] = 0;
+ HCI_TIMER->TASKS_START = 1; // < Start TIMER
+ HCI_TIMER->INTENSET = TIMER_INTENSET_COMPARE1_Msk;
+ }
+ else
+ {
+ HCI_TIMER->INTENCLR = TIMER_INTENCLR_COMPARE1_Msk;
+ HCI_TIMER->TASKS_STOP = 1; // < Start TIMER
+ }
+}
+
+
+#else
+
+_static bool m_hci_timer_setup_flag = false;
+_static uint32_t m_hci_timer_counter = 0;
+_static uint32_t m_hci_timer_setup;
+
+static void hci_timeout_setup(uint32_t count)
+{
+ m_hci_timer_setup = count;
+ m_hci_timer_setup_flag = true;
+}
+
+
+static void hci_timeout_handler(void * p_context)
+{
+
+ if (m_hci_timer_setup_flag)
+ {
+ m_hci_timer_setup_flag = false;
+ m_hci_timer_counter = m_hci_timer_setup; /* for 1 it will be always more than 1 tick - jitter is up to 1 tick */
+ }
+ else if ( m_hci_timer_counter )
+ {
+ m_hci_timer_counter--;
+
+ if (m_hci_timer_counter == 0)
+ {
+ if (m_hci_timer_enabled_flag)
+ {
+ hci_signal_timeout_event();
+ }
+ else
+ {
+ m_hci_timout_pending_flag = true;
+ }
+ }
+ }
+ return;
+}
+
+
+#endif
+
+
+/**@brief Function for validating a received packet.
+ *
+ * @param[in] p_buffer Pointer to the packet data.
+ * @param[in] length Length of packet data in bytes.
+ *
+ * @return true if received packet is valid, false in other case.
+ */
+static bool is_rx_pkt_valid(const uint8_t * p_buffer, uint32_t length)
+{
+ // Executed packet filtering algorithm order:
+ // - verify packet overall length
+ // - verify data integrity bit set
+ // - verify reliable packet bit set
+ // - verify supported packet type
+ // - verify header checksum
+ // - verify payload length field
+ // - verify CRC
+ if (length <= PKT_HDR_SIZE)
+ {
+ return false;
+ }
+
+ if (!(p_buffer[0] & DATA_INTEGRITY_MASK))
+ {
+ return false;
+ }
+
+ if (!(p_buffer[0] & RELIABLE_PKT_MASK))
+ {
+ return false;
+ }
+
+ if ((p_buffer[1] & 0x0Fu) != PKT_TYPE_VENDOR_SPECIFIC)
+ {
+ return false;
+ }
+
+ const uint32_t expected_checksum =
+ ((p_buffer[0] + p_buffer[1] + p_buffer[2] + p_buffer[3])) & 0xFFu;
+
+ if (expected_checksum != 0)
+ {
+ return false;
+ }
+
+ const uint16_t crc_calculated = crc16_compute(p_buffer, (length - PKT_CRC_SIZE), NULL);
+ const uint16_t crc_received = uint16_decode(&p_buffer[length - PKT_CRC_SIZE]);
+
+ if (crc_calculated != crc_received)
+ {
+ return false;
+ }
+
+ return true;
+}
+
+
+/**@brief Function for getting the sequence number of the next reliable packet expected.
+ *
+ * @return sequence number of the next reliable packet expected.
+ */
+static __INLINE uint8_t packet_ack_get(void)
+{
+ return (uint8_t) m_packet_ack_number;
+}
+
+
+/**@brief Function for getting the sequence number of a reliable TX packet for which peer protocol
+ * entity acknowledgment is pending.
+ *
+ * @return sequence number of a reliable TX packet for which peer protocol entity acknowledgement
+ * is pending.
+ */
+static __INLINE uint8_t packet_seq_get(void)
+{
+ return m_packet_seq_number;
+}
+
+
+static __INLINE uint8_t packet_seq_nmbr_extract(const uint8_t * p_buffer)
+{
+ return (p_buffer[0] & 0x07u);
+}
+
+
+/**@brief Function for constructing 1st byte of the packet header of the packet to be transmitted.
+ *
+ * @return 1st byte of the packet header of the packet to be transmitted
+ */
+static __INLINE uint8_t tx_packet_byte_zero_construct(void)
+{
+ const uint32_t value = DATA_INTEGRITY_MASK | RELIABLE_PKT_MASK |
+ (packet_ack_get() << 3u) | packet_seq_get();
+
+ return (uint8_t) value;
+}
+
+
+/**@brief Function for calculating a packet header checksum.
+ *
+ * @param[in] p_hdr Pointer to the packet header.
+ *
+ * @return Calculated checksum.
+ */
+static __INLINE uint8_t header_checksum_calculate(const uint8_t * p_hdr)
+{
+ // @note: no pointer validation check needed as already checked by calling function.
+ uint32_t checksum;
+
+ checksum = p_hdr[0];
+ checksum += p_hdr[1];
+ checksum += p_hdr[2];
+ checksum &= 0xFFu;
+ checksum = (~checksum + 1u);
+
+ return (uint8_t)checksum;
+}
+
+
+/**@brief Function for getting the expected ACK number.
+ *
+ * @return expected ACK number.
+ */
+static __INLINE uint8_t expected_ack_number_get(void)
+{
+ uint8_t seq_nmbr = packet_seq_get();
+
+ ++seq_nmbr;
+ seq_nmbr &= 0x07u;
+
+ return seq_nmbr;
+}
+
+
+/**@brief Function for getting the expected ACK number.
+ *
+ * @return next expected ACK number.
+ */
+
+static __INLINE uint8_t next_expected_ack_number_get(void)
+{
+ uint8_t seq_nmbr = expected_ack_number_get();
+
+ ++seq_nmbr;
+ seq_nmbr &= 0x07u;
+
+ return seq_nmbr;
+}
+
+
+/**@brief Function for processing a received acknowledgement packet.
+ *
+ * Verifies does the received acknowledgement packet has the expected acknowledgement number and
+ * that the header checksum is correct.
+ *
+ * @param[in] p_buffer Pointer to the packet data.
+ *
+ * @return true if valid acknowledgement packet received.
+ */
+
+static bool rx_ack_pkt_valid(const uint8_t * p_buffer)
+{
+ // @note: no pointer validation check needed as allready checked by calling function.
+
+ // Verify header checksum.
+ const uint32_t expected_checksum =
+ ((p_buffer[0] + p_buffer[1] + p_buffer[2] + p_buffer[3])) & 0xFFu;
+
+ if (expected_checksum != 0)
+ {
+ return false;
+ }
+
+ const uint8_t ack_number = (p_buffer[0] >> 3u) & 0x07u;
+
+ // Verify expected acknowledgment number.
+ return ( (ack_number == expected_ack_number_get()) ||
+ (ack_number == next_expected_ack_number_get()) );
+}
+
+
+/**@brief Function for decoding a packet type field.
+ *
+ * @param[in] p_buffer Pointer to the packet data.
+ * @param[in] length Length of packet data in bytes.
+ *
+ * @return Packet type field or INVALID_PKT_TYPE in case of decode error.
+ */
+
+static uint32_t packet_type_decode(const uint8_t * p_buffer, uint32_t length)
+{
+ // @note: no pointer validation check needed as allready checked by calling function.
+ uint32_t return_value;
+
+ if (length >= PKT_HDR_SIZE)
+ {
+ return_value = (p_buffer[1] & 0x0Fu);
+ }
+ else
+ {
+ return_value = INVALID_PKT_TYPE;
+ }
+
+ return return_value;
+}
+
+#ifdef HCI_LINK_CONTROL
+/**@brief Function for decoding a link control packet.
+ *
+ * @param[in] p_buffer Pointer to the packet data.
+ * @param[in] length Length of packet data in bytes.
+ *
+ * @return Link Control Packet Type if decoding successful, HCI_LINK_CONTROL_PKT_INVALID otherwise.
+ */
+static uint16_t link_control_packet_decode(const uint8_t * p_buffer, uint32_t length)
+{
+ // @note: no pointer validation check needed as allready checked by calling function.
+ uint16_t packet_type = HCI_LINK_CONTROL_PKT_INVALID;
+
+ // Executed link control packet filtering algorithm order:
+ // - verify packet overall length
+ // - verify data integrity bit cleared
+ // - verify reliable packet bit cleared
+ // - verify header checksum
+ // - verify payload: length and value
+
+ if (length < HCI_PKT_SYNC_SIZE)
+ {
+ packet_type = HCI_LINK_CONTROL_PKT_INVALID;
+ }
+
+ packet_type = p_buffer[PKT_HDR_SIZE] | (p_buffer[PKT_HDR_SIZE + 1] << 8u);
+
+ if ((p_buffer[0] & DATA_INTEGRITY_MASK) || (p_buffer[0] & RELIABLE_PKT_MASK))
+ {
+ packet_type = HCI_LINK_CONTROL_PKT_INVALID;
+ }
+
+ const uint32_t expected_checksum =
+ ((p_buffer[0] + p_buffer[1] + p_buffer[2] + p_buffer[3])) & 0xFFu;
+
+ if (expected_checksum != 0)
+ {
+ packet_type = HCI_LINK_CONTROL_PKT_INVALID;
+ }
+
+ // This is a CONFIG or CONFIG_RSP packet
+ if ((packet_type == HCI_PKT_CONFIG) || (packet_type == HCI_PKT_CONFIG_RSP))
+ {
+ if (length != HCI_PKT_CONFIG_SIZE)
+ {
+ packet_type = HCI_LINK_CONTROL_PKT_INVALID;
+ }
+ // Verify configuration field (0x11):
+ // - Sliding Window Size == 1,
+ // - OOF Flow Control == 0,
+ // - Data Integrity Check Type == 1,
+ // - Version Number == 0
+ if (p_buffer[HCI_PKT_CONFIG_SIZE - 1] != HCI_CONFIG_FIELD)
+ {
+ packet_type = HCI_LINK_CONTROL_PKT_INVALID;
+ }
+ }
+ // This is a SYNC or SYNC_RSP packet
+ else if ((packet_type == HCI_PKT_SYNC) || (packet_type == HCI_PKT_SYNC_RSP))
+ {
+ if (length != HCI_PKT_SYNC_SIZE)
+ {
+ packet_type = HCI_LINK_CONTROL_PKT_INVALID;
+ }
+ }
+ else
+ {
+ packet_type = HCI_LINK_CONTROL_PKT_INVALID;
+ }
+
+ return packet_type;
+}
+#endif /* HCI_LINK_CONTROL */
+
+/**@brief Function for writing an acknowledgment packet for transmission.
+ */
+
+static void ack_transmit(void)
+{
+ uint32_t err_code;
+ // TX ACK packet format:
+ // - Unreliable Packet type
+ // - Payload Length set to 0
+ // - Sequence Number set to 0
+ // - Header checksum calculated
+ // - Acknowledge Number set correctly
+ m_tx_ack_packet[0] = (packet_ack_get() << 3u);
+ m_tx_ack_packet[1] = 0;
+ m_tx_ack_packet[2] = 0;
+ m_tx_ack_packet[3] = header_checksum_calculate(m_tx_ack_packet);
+
+ ser_phy_hci_pkt_params_t pkt_header;
+
+ pkt_header.p_buffer = m_tx_ack_packet;
+ pkt_header.num_of_bytes = PKT_HDR_SIZE;
+ DEBUG_EVT_SLIP_ACK_TX(0);
+ err_code = ser_phy_hci_slip_tx_pkt_send(&pkt_header, NULL, NULL);
+ ser_phy_hci_assert(err_code == NRF_SUCCESS);
+
+ return;
+}
+
+
+static void ser_phy_event_callback(ser_phy_evt_t event)
+{
+ if (m_ser_phy_callback)
+ {
+ m_ser_phy_callback(event);
+ }
+
+ return;
+}
+
+
+static void memory_request_callback(uint16_t size)
+{
+ ser_phy_evt_t event;
+
+ DEBUG_EVT_HCI_PHY_EVT_BUF_REQUEST(0);
+
+ event.evt_type = SER_PHY_EVT_RX_BUF_REQUEST;
+ event.evt_params.rx_buf_request.num_of_bytes = size;
+ ser_phy_event_callback(event);
+}
+
+
+static void packet_received_callback(uint8_t * pBuffer, uint16_t size)
+{
+ ser_phy_evt_t event;
+
+ DEBUG_EVT_HCI_PHY_EVT_RX_PKT_RECEIVED(0);
+
+ event.evt_type = SER_PHY_EVT_RX_PKT_RECEIVED;
+ event.evt_params.rx_pkt_received.num_of_bytes = size;
+ event.evt_params.rx_pkt_received.p_buffer = pBuffer;
+ ser_phy_event_callback(event);
+}
+
+
+static void packet_dropped_callback(void)
+{
+ ser_phy_evt_t event;
+
+ DEBUG_EVT_HCI_PHY_EVT_RX_PKT_DROPPED(0);
+
+ event.evt_type = SER_PHY_EVT_RX_PKT_DROPPED;
+ ser_phy_event_callback(event);
+}
+
+
+static void packet_transmitted_callback(void)
+{
+ ser_phy_evt_t event;
+
+ DEBUG_EVT_HCI_PHY_EVT_TX_PKT_SENT(0);
+
+ event.evt_type = SER_PHY_EVT_TX_PKT_SENT;
+ ser_phy_event_callback(event);
+}
+
+
+static void error_callback(void)
+{
+ ser_phy_evt_t event;
+
+ DEBUG_EVT_HCI_PHY_EVT_TX_ERROR(0);
+
+ event.evt_type = SER_PHY_EVT_HW_ERROR;
+ event.evt_params.hw_error.p_buffer = m_p_tx_payload;
+ ser_phy_event_callback(event);
+}
+
+
+static void hci_slip_event_handler(ser_phy_hci_slip_evt_t * p_event)
+{
+ hci_evt_t event;
+ uint32_t packet_type;
+ uint32_t err_code;
+
+ if ( p_event->evt_type == SER_PHY_HCI_SLIP_EVT_PKT_SENT )
+ {
+ NRF_LOG_DEBUG("EVT_PKT_SENT");
+
+ DEBUG_EVT_SLIP_PACKET_TXED(0);
+ event.evt_source = HCI_SLIP_EVT;
+ event.evt.ser_phy_slip_evt.evt_type = p_event->evt_type;
+#ifndef HCI_LINK_CONTROL
+ hci_tx_event_handler(&event);
+#else
+ if ((m_hci_mode == HCI_MODE_ACTIVE) && m_hci_other_side_active)
+ {
+ hci_tx_event_handler(&event);
+ }
+#endif /*HCI_LINK_CONTROL*/
+ }
+ else if ( p_event->evt_type == SER_PHY_HCI_SLIP_EVT_ACK_SENT )
+ {
+ NRF_LOG_DEBUG("EVT_ACK_SENT");
+
+ DEBUG_EVT_SLIP_ACK_TXED(0);
+ event.evt_source = HCI_SLIP_EVT;
+ event.evt.ser_phy_slip_evt.evt_type = p_event->evt_type;
+#ifndef HCI_LINK_CONTROL
+ hci_rx_event_handler(&event);
+#else
+ if ((m_hci_mode == HCI_MODE_ACTIVE) && m_hci_other_side_active)
+ {
+ hci_rx_event_handler(&event);
+ }
+#endif /* HCI_LINK_CONTROL */
+ }
+
+ else if ( p_event->evt_type == SER_PHY_HCI_SLIP_EVT_PKT_RECEIVED )
+ {
+ event.evt_source = HCI_SLIP_EVT;
+ event.evt.ser_phy_slip_evt.evt_type = p_event->evt_type;
+ event.evt.ser_phy_slip_evt.evt_params.received_pkt.p_buffer =
+ p_event->evt_params.received_pkt.p_buffer;
+ event.evt.ser_phy_slip_evt.evt_params.received_pkt.num_of_bytes =
+ p_event->evt_params.received_pkt.num_of_bytes;
+ ser_phy_hci_assert(event.evt.ser_phy_slip_evt.evt_params.received_pkt.p_buffer != NULL);
+ ser_phy_hci_assert(event.evt.ser_phy_slip_evt.evt_params.received_pkt.num_of_bytes != 0);
+ packet_type = packet_type_decode(
+ event.evt.ser_phy_slip_evt.evt_params.received_pkt.p_buffer,
+ event.evt.ser_phy_slip_evt.evt_params.received_pkt.num_of_bytes);
+
+ NRF_LOG_DEBUG("EVT_PKT_RECEIVED 0x%X/%u", packet_type,
+ p_event->evt_params.received_pkt.num_of_bytes);
+
+ if (packet_type == PKT_TYPE_RESET)
+ {
+ NVIC_SystemReset();
+ }
+ else if (packet_type == PKT_TYPE_ACK )
+ {
+ DEBUG_EVT_SLIP_ACK_RXED(0);
+#ifndef HCI_LINK_CONTROL
+ hci_tx_event_handler(&event);
+#else
+ if ((m_hci_mode == HCI_MODE_ACTIVE) && m_hci_other_side_active)
+ {
+ hci_tx_event_handler(&event);
+ }
+ else
+ {
+ err_code = ser_phy_hci_slip_rx_buf_free(
+ event.evt.ser_phy_slip_evt.evt_params.received_pkt.p_buffer);
+ }
+#endif /* HCI_LINK_CONTROL */
+ }
+ else if ( packet_type == PKT_TYPE_VENDOR_SPECIFIC )
+ {
+ if (is_rx_pkt_valid(event.evt.ser_phy_slip_evt.evt_params.received_pkt.p_buffer,
+ event.evt.ser_phy_slip_evt.evt_params.received_pkt.num_of_bytes))
+ {
+ DEBUG_EVT_SLIP_PACKET_RXED(0);
+#ifndef HCI_LINK_CONTROL
+ hci_rx_event_handler(&event);
+#else
+ if ((m_hci_mode == HCI_MODE_ACTIVE) && m_hci_other_side_active)
+ {
+ hci_rx_event_handler(&event);
+ }
+ else
+ {
+ err_code = ser_phy_hci_slip_rx_buf_free(
+ event.evt.ser_phy_slip_evt.evt_params.received_pkt.p_buffer);
+ }
+#endif /* HCI_LINK_CONTROL */
+ }
+ else
+ {
+ err_code = ser_phy_hci_slip_rx_buf_free(
+ event.evt.ser_phy_slip_evt.evt_params.received_pkt.p_buffer);
+ ser_phy_hci_assert(err_code == NRF_SUCCESS);
+ /* throw assert when in debug mode*/
+ DEBUG_EVT_SLIP_ERR_RXED(0);
+ }
+ }
+#ifdef HCI_LINK_CONTROL
+ else if (packet_type == PKT_TYPE_LINK_CONTROL)
+ {
+ hci_link_control_event_handler(&event);
+ }
+#endif /* HCI_LINK_CONTROL */
+ else
+ {
+ err_code = ser_phy_hci_slip_rx_buf_free(
+ event.evt.ser_phy_slip_evt.evt_params.received_pkt.p_buffer);
+ ser_phy_hci_assert(err_code == NRF_SUCCESS);
+ /* throw assert when in debug mode*/
+ DEBUG_EVT_SLIP_ERR_RXED(0);
+ }
+ }
+ else
+ {
+ NRF_LOG_DEBUG("EVT_HW_ERROR");
+ }
+}
+
+
+static void hci_pkt_send(void)
+{
+ uint32_t err_code;
+
+ m_tx_packet_header[0] = tx_packet_byte_zero_construct();
+ uint16_t type_and_length_fields = ((m_tx_payload_length << 4u) | PKT_TYPE_VENDOR_SPECIFIC);
+ (void)uint16_encode(type_and_length_fields, &(m_tx_packet_header[1]));
+ m_tx_packet_header[3] = header_checksum_calculate(m_tx_packet_header);
+ uint16_t crc = crc16_compute(m_tx_packet_header, PKT_HDR_SIZE, NULL);
+ crc = crc16_compute(m_p_tx_payload, m_tx_payload_length, &crc);
+ (void)uint16_encode(crc, m_tx_packet_crc);
+
+ ser_phy_hci_pkt_params_t pkt_header;
+ ser_phy_hci_pkt_params_t pkt_payload;
+ ser_phy_hci_pkt_params_t pkt_crc;
+
+ pkt_header.p_buffer = m_tx_packet_header;
+ pkt_header.num_of_bytes = PKT_HDR_SIZE;
+ pkt_payload.p_buffer = m_p_tx_payload;
+ pkt_payload.num_of_bytes = m_tx_payload_length;
+ pkt_crc.p_buffer = m_tx_packet_crc;
+ pkt_crc.num_of_bytes = PKT_CRC_SIZE;
+ DEBUG_EVT_SLIP_PACKET_TX(0);
+ err_code = ser_phy_hci_slip_tx_pkt_send(&pkt_header, &pkt_payload, &pkt_crc);
+ ser_phy_hci_assert(err_code == NRF_SUCCESS);
+
+ return;
+}
+
+#ifdef HCI_LINK_CONTROL
+static void hci_link_control_pkt_send(void)
+{
+ uint32_t err_code;
+ uint16_t link_control_payload_len = 0;
+
+ m_tx_link_control_header[0] = 0x00u; // SEQ, ACK, DI and RP are set to 0 for link control
+ if (m_hci_link_control_next_pkt == HCI_PKT_SYNC)
+ {
+ link_control_payload_len = HCI_PKT_SYNC_SIZE - PKT_HDR_SIZE;
+ (void)uint16_encode(HCI_PKT_SYNC, m_tx_link_control_payload);
+ }
+ else if (m_hci_link_control_next_pkt == HCI_PKT_SYNC_RSP)
+ {
+ link_control_payload_len = HCI_PKT_SYNC_SIZE - PKT_HDR_SIZE;
+ (void)uint16_encode(HCI_PKT_SYNC_RSP, m_tx_link_control_payload);
+ }
+ else if (m_hci_link_control_next_pkt == HCI_PKT_CONFIG)
+ {
+ link_control_payload_len = HCI_PKT_CONFIG_SIZE - PKT_HDR_SIZE;
+ (void)uint16_encode(HCI_PKT_CONFIG, m_tx_link_control_payload);
+ m_tx_link_control_payload[2] = HCI_CONFIG_FIELD;
+ }
+ else if (m_hci_link_control_next_pkt == HCI_PKT_CONFIG_RSP)
+ {
+ link_control_payload_len = HCI_PKT_CONFIG_SIZE - PKT_HDR_SIZE;
+ (void)uint16_encode(HCI_PKT_CONFIG_RSP, m_tx_link_control_payload);
+ m_tx_link_control_payload[2] = HCI_CONFIG_FIELD;
+ }
+ uint16_t type_and_length_fields = ((link_control_payload_len << 4u) | PKT_TYPE_LINK_CONTROL);
+ (void)uint16_encode(type_and_length_fields, &(m_tx_link_control_header[1]));
+ m_tx_link_control_header[3] = header_checksum_calculate(m_tx_link_control_header);
+
+ ser_phy_hci_pkt_params_t pkt_header;
+ ser_phy_hci_pkt_params_t pkt_payload;
+ ser_phy_hci_pkt_params_t pkt_crc;
+
+ pkt_header.p_buffer = m_tx_link_control_header;
+ pkt_header.num_of_bytes = PKT_HDR_SIZE;
+ pkt_payload.p_buffer = m_tx_link_control_payload;
+ pkt_payload.num_of_bytes = link_control_payload_len;
+ pkt_crc.p_buffer = NULL;
+ pkt_crc.num_of_bytes = 0;
+ DEBUG_EVT_SLIP_PACKET_TX(0);
+ err_code = ser_phy_hci_slip_tx_pkt_send(&pkt_header, &pkt_payload, &pkt_crc);
+ ser_phy_hci_assert(err_code == NRF_SUCCESS);
+
+ return;
+}
+#endif /* HCI_LINK_CONTROL */
+
+static void hci_pkt_sent_upcall(void)
+{
+ m_packet_seq_number++; // incoming ACK is valid, increment SEQ
+ m_packet_seq_number &= 0x07u;
+ m_p_tx_payload = NULL;
+ packet_transmitted_callback();
+
+ return;
+}
+
+
+static void hci_release_ack_buffer(hci_evt_t * p_event)
+{
+ uint32_t err_code;
+
+ err_code = ser_phy_hci_slip_rx_buf_free(
+ p_event->evt.ser_phy_slip_evt.evt_params.received_pkt.p_buffer);
+ ser_phy_hci_assert(err_code == NRF_SUCCESS);
+
+ return;
+}
+
+
+static void hci_process_orphaned_ack(hci_evt_t * p_event)
+{
+ hci_release_ack_buffer(p_event);
+ return;
+}
+
+/* main tx fsm */
+static void hci_tx_fsm_event_process(hci_evt_t * p_event)
+{
+
+ switch (m_hci_tx_fsm_state)
+ {
+ case HCI_TX_STATE_SEND:
+
+ if ((p_event->evt_source == HCI_SER_PHY_EVT) &&
+ (p_event->evt.ser_phy_evt.evt_type == HCI_SER_PHY_TX_REQUEST))
+ {
+ hci_pkt_send();
+ hci_timeout_setup(0);
+ m_tx_retry_count = MAX_RETRY_COUNT;
+ m_hci_tx_fsm_state = HCI_TX_STATE_WAIT_FOR_FIRST_TX_END;
+ }
+ else if ((p_event->evt_source == HCI_SLIP_EVT) &&
+ (p_event->evt.ser_phy_slip_evt.evt_type == SER_PHY_HCI_SLIP_EVT_PKT_RECEIVED))
+ {
+ hci_process_orphaned_ack(p_event);
+ }
+
+ break;
+
+ case HCI_TX_STATE_WAIT_FOR_FIRST_TX_END:
+
+ if ((p_event->evt_source == HCI_SLIP_EVT) &&
+ (p_event->evt.ser_phy_slip_evt.evt_type == SER_PHY_HCI_SLIP_EVT_PKT_SENT))
+ {
+ hci_timeout_setup(1);
+ m_hci_tx_fsm_state = HCI_TX_STATE_WAIT_FOR_ACK;
+ }
+ else if ((p_event->evt_source == HCI_SLIP_EVT) &&
+ (p_event->evt.ser_phy_slip_evt.evt_type == SER_PHY_HCI_SLIP_EVT_PKT_RECEIVED))
+ {
+ hci_process_orphaned_ack(p_event);
+ }
+ break;
+
+ case HCI_TX_STATE_WAIT_FOR_ACK_OR_TX_END:
+
+ if ((p_event->evt_source == HCI_SLIP_EVT) &&
+ (p_event->evt.ser_phy_slip_evt.evt_type == SER_PHY_HCI_SLIP_EVT_PKT_SENT))
+ {
+ hci_timeout_setup(1);
+ m_hci_tx_fsm_state = HCI_TX_STATE_WAIT_FOR_ACK;
+ }
+ else if ((p_event->evt_source == HCI_SLIP_EVT) &&
+ (p_event->evt.ser_phy_slip_evt.evt_type == SER_PHY_HCI_SLIP_EVT_PKT_RECEIVED))
+ {
+ if (rx_ack_pkt_valid(p_event->evt.ser_phy_slip_evt.evt_params.received_pkt.p_buffer))
+ {
+ hci_timeout_setup(0);
+ m_hci_tx_fsm_state = HCI_TX_STATE_WAIT_FOR_TX_END;
+ }
+ hci_release_ack_buffer(p_event);
+ }
+ break;
+
+ case HCI_TX_STATE_WAIT_FOR_ACK:
+
+ if ((p_event->evt_source == HCI_SLIP_EVT) &&
+ (p_event->evt.ser_phy_slip_evt.evt_type == SER_PHY_HCI_SLIP_EVT_PKT_RECEIVED))
+ {
+ if (rx_ack_pkt_valid(p_event->evt.ser_phy_slip_evt.evt_params.received_pkt.p_buffer))
+ {
+ hci_timeout_setup(0);
+ hci_pkt_sent_upcall();
+ m_hci_tx_fsm_state = HCI_TX_STATE_SEND;
+ }
+ hci_release_ack_buffer(p_event);
+ }
+ else if (p_event->evt_source == HCI_TIMER_EVT)
+ {
+ m_tx_retry_count--;
+ // m_tx_retx_counter++; // global retransmissions counter
+ if (m_tx_retry_count)
+ {
+ hci_pkt_send();
+ DEBUG_HCI_RETX(0);
+ m_hci_tx_fsm_state = HCI_TX_STATE_WAIT_FOR_ACK_OR_TX_END;
+ }
+ else
+ {
+ error_callback();
+ m_hci_tx_fsm_state = HCI_TX_STATE_SEND;
+ }
+ }
+ break;
+
+ case HCI_TX_STATE_WAIT_FOR_TX_END:
+
+ if ((p_event->evt_source == HCI_SLIP_EVT) &&
+ (p_event->evt.ser_phy_slip_evt.evt_type == SER_PHY_HCI_SLIP_EVT_PKT_SENT))
+ {
+ hci_pkt_sent_upcall();
+ m_hci_tx_fsm_state = HCI_TX_STATE_SEND;
+ }
+ else if ((p_event->evt_source == HCI_SLIP_EVT) &&
+ (p_event->evt.ser_phy_slip_evt.evt_type == SER_PHY_HCI_SLIP_EVT_PKT_RECEIVED))
+ {
+ hci_process_orphaned_ack(p_event);
+ }
+
+ break;
+
+#ifdef HCI_LINK_CONTROL
+ case HCI_TX_STATE_DISABLE:
+ /* This case should not happen if HCI is in ACTIVE mode */
+ if (m_hci_mode == HCI_MODE_ACTIVE)
+ {
+ ser_phy_hci_assert(false);
+ }
+ break;
+#endif /* HCI_LINK_CONTROL */
+
+ default:
+ ser_phy_hci_assert(false);
+ break;
+ }
+}
+
+
+static void hci_mem_request(hci_evt_t * p_event)
+{
+ m_buffer_reqested_flag = true;
+ m_p_rx_packet = p_event->evt.ser_phy_slip_evt.evt_params.received_pkt.p_buffer;
+ m_rx_packet_length = p_event->evt.ser_phy_slip_evt.evt_params.received_pkt.num_of_bytes;
+ ser_phy_hci_assert(m_rx_packet_length > PKT_HDR_SIZE + PKT_CRC_SIZE);
+ memory_request_callback(m_rx_packet_length - PKT_HDR_SIZE - PKT_CRC_SIZE);
+ return;
+}
+
+
+static void hci_inc_ack()
+{
+ m_packet_ack_number++;
+ m_packet_ack_number &= 0x07u;
+}
+
+
+static void hci_rx_fsm_event_process(hci_evt_t * p_event)
+{
+ switch (m_hci_rx_fsm_state)
+ {
+ case HCI_RX_STATE_RECEIVE:
+
+ if ((p_event->evt_source == HCI_SLIP_EVT) &&
+ (p_event->evt.ser_phy_slip_evt.evt_type == SER_PHY_HCI_SLIP_EVT_PKT_RECEIVED))
+ {
+ /* type and crc and check sum are validated by slip handler */
+ uint8_t rx_seq_number = packet_seq_nmbr_extract(
+ p_event->evt.ser_phy_slip_evt.evt_params.received_pkt.p_buffer);
+
+ if (packet_ack_get() == rx_seq_number)
+ {
+ hci_mem_request(p_event);
+ m_hci_rx_fsm_state = HCI_RX_STATE_WAIT_FOR_MEM;
+ }
+ else
+ {
+ // m_rx_drop_counter++;
+ m_hci_rx_fsm_state = HCI_RX_STATE_WAIT_FOR_SLIP_NACK_END;
+ (void) ser_phy_hci_slip_rx_buf_free(m_p_rx_packet); // and drop a packet
+ ack_transmit(); // send NACK with valid ACK
+ }
+ }
+ break;
+
+ case HCI_RX_STATE_WAIT_FOR_MEM:
+
+ if ((p_event->evt_source == HCI_SER_PHY_EVT) &&
+ (p_event->evt.ser_phy_evt.evt_type == HCI_SER_PHY_RX_BUF_GRANTED))
+ {
+ if (m_p_rx_buffer)
+ {
+ memcpy(m_p_rx_buffer,
+ m_p_rx_packet + PKT_HDR_SIZE,
+ m_rx_packet_length - PKT_HDR_SIZE - PKT_CRC_SIZE);
+ (void) ser_phy_hci_slip_rx_buf_free(m_p_rx_packet);
+ }
+ m_hci_rx_fsm_state = HCI_RX_STATE_WAIT_FOR_SLIP_ACK_END;
+ hci_inc_ack(); // SEQ was valid for good packet, we will send incremented SEQ as ACK
+ ack_transmit();
+ }
+
+ break;
+
+ case HCI_RX_STATE_WAIT_FOR_SLIP_ACK_END:
+
+ if ((p_event->evt_source == HCI_SLIP_EVT) &&
+ (p_event->evt.ser_phy_slip_evt.evt_type == SER_PHY_HCI_SLIP_EVT_ACK_SENT))
+ {
+
+ if (m_p_rx_buffer)
+ {
+ packet_received_callback(m_p_rx_buffer,
+ m_rx_packet_length - PKT_HDR_SIZE - PKT_CRC_SIZE);
+ }
+ else
+ {
+ packet_dropped_callback();
+ }
+ m_hci_rx_fsm_state = HCI_RX_STATE_RECEIVE;
+ }
+ else if ((p_event->evt_source == HCI_SLIP_EVT) &&
+ (p_event->evt.ser_phy_slip_evt.evt_type == SER_PHY_HCI_SLIP_EVT_PKT_RECEIVED))
+ {
+ (void) ser_phy_hci_slip_rx_buf_free(p_event->evt.ser_phy_slip_evt.evt_params.received_pkt.p_buffer);
+ }
+ break;
+
+ case HCI_RX_STATE_WAIT_FOR_SLIP_NACK_END:
+ if ((p_event->evt_source == HCI_SLIP_EVT) &&
+ (p_event->evt.ser_phy_slip_evt.evt_type == SER_PHY_HCI_SLIP_EVT_ACK_SENT))
+ {
+ m_hci_rx_fsm_state = HCI_RX_STATE_RECEIVE;
+ }
+ else
+ {
+ (void) ser_phy_hci_slip_rx_buf_free(p_event->evt.ser_phy_slip_evt.evt_params.received_pkt.p_buffer);
+ }
+ break;
+
+
+#ifdef HCI_LINK_CONTROL
+ case HCI_RX_STATE_DISABLE:
+ if (m_hci_mode == HCI_MODE_ACTIVE)
+ {
+ ser_phy_hci_assert(false);
+ }
+ break;
+#endif /* HCI_LINK_CONTROL */
+
+ default:
+ ser_phy_hci_assert(false);
+ break;
+ }
+}
+
+
+/* this function might be entered only via hci_tx_event_handler */
+static void hci_tx_fsm(void)
+{
+ hci_evt_t event;
+ uint32_t err_code = NRF_SUCCESS;
+
+ while (err_code == NRF_SUCCESS)
+ {
+
+ CRITICAL_REGION_ENTER();
+ err_code = nrf_queue_pop(&m_tx_evt_queue, &event);
+
+ if (err_code != NRF_SUCCESS)
+ {
+ m_tx_fsm_idle_flag = true;
+ }
+ CRITICAL_REGION_EXIT();
+
+ if (err_code == NRF_SUCCESS)
+ {
+ hci_tx_fsm_event_process(&event); /* this is the only entry to the TX_FSM */
+ }
+ }
+ return;
+}
+
+
+/* this function might be entered only via hci_rx_event_handler */
+static void hci_rx_fsm(void)
+{
+ hci_evt_t event;
+ uint32_t err_code = NRF_SUCCESS;
+
+ while (err_code == NRF_SUCCESS)
+ {
+ CRITICAL_REGION_ENTER();
+ err_code = nrf_queue_pop(&m_rx_evt_queue, &event);
+
+ if (err_code != NRF_SUCCESS)
+ {
+ m_rx_fsm_idle_flag = true;
+ }
+ CRITICAL_REGION_EXIT();
+
+ if (err_code == NRF_SUCCESS)
+ {
+ hci_rx_fsm_event_process(&event); /* this is the only entry to the RX_FSM */
+ }
+ }
+ return;
+}
+
+
+/* something might have been queued by API with disabled 'PHY-interrupts' */
+static void hci_tx_reschedule()
+{
+ bool tx_exec_flag = false;
+ uint32_t tx_queue_length;
+
+ CRITICAL_REGION_ENTER();
+ tx_queue_length = nrf_queue_utilization_get(&m_tx_evt_queue);
+
+#ifndef HCI_LINK_CONTROL
+ if (m_tx_fsm_idle_flag && m_hci_global_enable_flag && tx_queue_length)
+#else
+ if (m_tx_fsm_idle_flag && m_hci_global_enable_flag && tx_queue_length && (m_hci_mode == HCI_MODE_ACTIVE))
+#endif /* HCI_LINK_CONTROL */
+ {
+ tx_exec_flag = true; // FSM should be activated
+ m_tx_fsm_idle_flag = false; // FSM will be busy from now on till the queue is exhausted
+ }
+ CRITICAL_REGION_EXIT();
+
+ if (tx_exec_flag)
+ {
+ hci_tx_fsm();
+ }
+ return;
+}
+
+
+/* entry to TX state machine, might be called asynchronously from different contexts */
+/* Puts event into the TX event queue and execute if FSM was idle */
+static void hci_tx_event_handler(hci_evt_t * p_event)
+{
+ bool tx_exec_flag = false;
+ uint32_t err_code;
+
+ CRITICAL_REGION_ENTER();
+ err_code = nrf_queue_push(&m_tx_evt_queue, p_event);
+ ser_phy_hci_assert(err_code == NRF_SUCCESS);
+
+ // CRITICAL_REGION_ENTER();
+ /* only one process can acquire tx_exec_flag */
+ if (m_tx_fsm_idle_flag && m_hci_global_enable_flag)
+ {
+ tx_exec_flag = true; // FSM should be activated
+ m_tx_fsm_idle_flag = false; // FSM will be busy from now on till the queue is exhausted
+ }
+ CRITICAL_REGION_EXIT();
+
+ if (tx_exec_flag)
+ {
+ hci_tx_fsm();
+ }
+ return;
+}
+
+
+/* Something might have been queued by API with disabled 'PHY-interrupts' */
+static void hci_rx_reschedule()
+{
+ bool rx_exec_flag = false;
+ uint32_t rx_queue_length;
+
+ CRITICAL_REGION_ENTER();
+ rx_queue_length = nrf_queue_utilization_get(&m_rx_evt_queue);
+
+#ifndef HCI_LINK_CONTROL
+ if (m_rx_fsm_idle_flag && m_hci_global_enable_flag && rx_queue_length)
+#else
+ if (m_rx_fsm_idle_flag && m_hci_global_enable_flag && rx_queue_length && (m_hci_mode == HCI_MODE_ACTIVE))
+#endif /* HCI_LINK_CONTROL */
+ {
+ rx_exec_flag = true; // FSM should be activated
+ m_rx_fsm_idle_flag = false; // FSM will be busy from now on till the queue is exhausted
+ }
+ CRITICAL_REGION_EXIT();
+
+ if (rx_exec_flag)
+ {
+ hci_rx_fsm();
+ }
+
+}
+
+
+/* Entry to RX state machine, might be called asynchronously from different contexts */
+/* Puts event into the RX event queue and execute if FSM was idle */
+static void hci_rx_event_handler(hci_evt_t * p_event)
+{
+ bool rx_exec_flag = false;
+ uint32_t err_code;
+
+ CRITICAL_REGION_ENTER();
+ err_code = nrf_queue_push(&m_rx_evt_queue, p_event);
+ ser_phy_hci_assert(err_code == NRF_SUCCESS);
+
+ /* only one process can acquire rx_exec_flag */
+ // CRITICAL_REGION_ENTER();
+ if (m_rx_fsm_idle_flag && m_hci_global_enable_flag)
+ {
+ rx_exec_flag = true; // FSM should be activated
+ m_rx_fsm_idle_flag = false; // FSM will be busy from now on till the queue is exhausted
+ }
+ CRITICAL_REGION_EXIT();
+
+ if (rx_exec_flag)
+ {
+ hci_rx_fsm();
+ }
+
+ return;
+}
+
+#ifdef HCI_LINK_CONTROL
+/* Link control event handler - used only for Link Control packets */
+/* This handler will be called only in 2 cases:
+ - when SER_PHY_HCI_SLIP_EVT_PKT_RECEIVED event is received
+ - when HCI_TIMER_EVT event is reveived */
+static void hci_link_control_event_handler(hci_evt_t * p_event)
+{
+ uint16_t pkt_type = HCI_LINK_CONTROL_PKT_INVALID;
+
+ switch (p_event->evt_source)
+ {
+ case HCI_SLIP_EVT:
+ pkt_type = link_control_packet_decode(
+ p_event->evt.ser_phy_slip_evt.evt_params.received_pkt.p_buffer,
+ p_event->evt.ser_phy_slip_evt.evt_params.received_pkt.num_of_bytes);
+ /* Perform HCI mode transition if needed */
+ CRITICAL_REGION_ENTER();
+ switch (pkt_type)
+ {
+ case HCI_PKT_SYNC:
+ m_hci_link_control_next_pkt = HCI_PKT_SYNC_RSP;
+ /* Restart HCI communication if it was in ACTIVE mode */
+ if (m_hci_mode == HCI_MODE_ACTIVE)
+ {
+ m_hci_mode = HCI_MODE_UNINITIALIZED;
+ m_packet_ack_number = INITIAL_ACK_NUMBER_EXPECTED;
+ m_packet_seq_number = INITIAL_SEQ_NUMBER;
+ m_hci_tx_fsm_state = HCI_TX_STATE_DISABLE;
+ m_hci_rx_fsm_state = HCI_RX_STATE_DISABLE;
+ m_hci_other_side_active = false;
+ }
+ hci_link_control_pkt_send();
+ hci_timeout_setup(HCI_LINK_CONTROL_TIMEOUT); // Need to trigger transmitting SYNC messages
+ break;
+ case HCI_PKT_SYNC_RSP:
+ if (m_hci_mode == HCI_MODE_UNINITIALIZED)
+ {
+ m_hci_mode = HCI_MODE_INITIALIZED;
+ m_hci_link_control_next_pkt = HCI_PKT_CONFIG;
+ }
+ break;
+ case HCI_PKT_CONFIG:
+ if (m_hci_mode != HCI_MODE_UNINITIALIZED)
+ {
+ m_hci_link_control_next_pkt = HCI_PKT_CONFIG_RSP;
+ hci_link_control_pkt_send();
+ m_hci_other_side_active = true;
+ }
+ break;
+ case HCI_PKT_CONFIG_RSP:
+ if (m_hci_mode == HCI_MODE_INITIALIZED)
+ {
+ m_hci_mode = HCI_MODE_ACTIVE;
+ m_hci_tx_fsm_state = HCI_TX_STATE_SEND;
+ m_hci_rx_fsm_state = HCI_RX_STATE_RECEIVE;
+ }
+ break;
+ }
+ CRITICAL_REGION_EXIT();
+ (void) ser_phy_hci_slip_rx_buf_free(
+ p_event->evt.ser_phy_slip_evt.evt_params.received_pkt.p_buffer);
+ /* Kick the state machine so it can start process BLE packets */
+ if ((m_hci_mode == HCI_MODE_ACTIVE) && m_hci_other_side_active)
+ {
+ hci_tx_reschedule();
+ hci_rx_reschedule();
+ }
+ break;
+
+ case HCI_TIMER_EVT:
+ /* Send one of the Link Control packets if in Unintialized or Initialized state */
+ CRITICAL_REGION_ENTER();
+ switch (m_hci_mode)
+ {
+ case HCI_MODE_UNINITIALIZED:
+ //send packet
+ m_hci_link_control_next_pkt = HCI_PKT_SYNC;
+ hci_link_control_pkt_send();
+ hci_timeout_setup(HCI_LINK_CONTROL_TIMEOUT);
+ break;
+ case HCI_MODE_INITIALIZED:
+ m_hci_link_control_next_pkt = HCI_PKT_CONFIG;
+ hci_link_control_pkt_send();
+ hci_timeout_setup(HCI_LINK_CONTROL_TIMEOUT);
+ break;
+ case HCI_MODE_ACTIVE:
+ case HCI_MODE_DISABLE:
+ default:
+ // No implementation needed
+ break;
+ }
+ CRITICAL_REGION_EXIT();
+ break;
+ case HCI_SER_PHY_EVT:
+ default:
+ // No implementation needed
+ break;
+ }
+}
+#endif /* HCI_LINK_CONTROL */
+
+/* ser_phy API function */
+void ser_phy_interrupts_enable(void)
+{
+ bool pending_timer_callback_flag = false;
+
+ CRITICAL_REGION_ENTER();
+ m_hci_timer_enabled_flag = true;
+
+ if (m_hci_timout_pending_flag)
+ {
+ m_hci_timout_pending_flag = false;
+ pending_timer_callback_flag = true;
+ }
+ CRITICAL_REGION_EXIT();
+ // this is a workaround - scheduled SER_PHY EVENTS
+ m_hci_global_enable_flag = true;
+ hci_tx_reschedule();
+ hci_rx_reschedule();
+
+ if (pending_timer_callback_flag)
+ {
+ hci_signal_timeout_event();
+ }
+
+ return;
+}
+
+
+/* ser_phy API function */
+void ser_phy_interrupts_disable(void)
+{
+ CRITICAL_REGION_ENTER();
+ m_hci_timer_enabled_flag = false;
+ // transport calls PHY API with ser_phy_interrupts_disabled
+ m_hci_global_enable_flag = false;
+ CRITICAL_REGION_EXIT();
+}
+
+
+/* ser_phy API function */
+uint32_t ser_phy_rx_buf_set(uint8_t * p_buffer)
+{
+ uint32_t status = NRF_SUCCESS;
+ hci_evt_t event;
+
+ if (m_buffer_reqested_flag)
+ {
+ m_buffer_reqested_flag = false;
+ m_p_rx_buffer = p_buffer;
+ event.evt_source = HCI_SER_PHY_EVT;
+ event.evt.ser_phy_evt.evt_type = HCI_SER_PHY_RX_BUF_GRANTED;
+ hci_rx_event_handler(&event);
+ }
+ else
+ {
+ status = NRF_ERROR_BUSY;
+ }
+ return status;
+}
+
+
+/* ser_phy API function */
+uint32_t ser_phy_tx_pkt_send(const uint8_t * p_buffer, uint16_t num_of_bytes)
+{
+ uint32_t status = NRF_SUCCESS;
+ hci_evt_t event;
+
+ if ( p_buffer == NULL || num_of_bytes == 0)
+ {
+ return NRF_ERROR_NULL;
+ }
+
+ if ( m_p_tx_payload == NULL)
+ {
+ m_tx_payload_length = num_of_bytes;
+ m_p_tx_payload = (uint8_t *)p_buffer;
+ DEBUG_EVT_TX_REQ(0);
+ event.evt_source = HCI_SER_PHY_EVT;
+ event.evt.ser_phy_evt.evt_type = HCI_SER_PHY_TX_REQUEST;
+ hci_tx_event_handler(&event);
+ }
+ else
+ {
+ status = NRF_ERROR_BUSY;
+ }
+
+ return status;
+}
+
+
+static uint32_t hci_timer_init(void)
+{
+ uint32_t err_code = NRF_SUCCESS;
+
+#ifdef HCI_APP_TIMER
+
+ err_code = app_timer_create(&m_app_timer_id, APP_TIMER_MODE_REPEATED, hci_timeout_handler);
+
+ if (err_code != NRF_SUCCESS)
+ {
+ return NRF_ERROR_INTERNAL;
+ }
+
+ err_code = app_timer_start(m_app_timer_id, RETRANSMISSION_TIMEOUT_IN_TICKS, NULL);
+
+ if (err_code != NRF_SUCCESS)
+ {
+ return NRF_ERROR_INTERNAL;
+ }
+
+#else
+
+ // Configure TIMER for compare[1] event
+ HCI_TIMER->PRESCALER = 9;
+ HCI_TIMER->MODE = TIMER_MODE_MODE_Timer;
+ HCI_TIMER->BITMODE = TIMER_BITMODE_BITMODE_16Bit;
+
+ // Clear TIMER
+ HCI_TIMER->TASKS_CLEAR = 1;
+
+ // Enable interrupt
+ HCI_TIMER->INTENCLR = 0xFFFFFFFF;
+ HCI_TIMER->INTENSET = TIMER_INTENSET_COMPARE1_Enabled << TIMER_INTENSET_COMPARE1_Pos;
+
+ NVIC_ClearPendingIRQ(HCI_TIMER_IRQn);
+ NVIC_SetPriority(HCI_TIMER_IRQn, APP_IRQ_PRIORITY_HIGH);
+ NVIC_EnableIRQ(HCI_TIMER_IRQn);
+
+#endif
+
+ return err_code;
+
+}
+
+
+/* ser_phy API function */
+uint32_t ser_phy_open(ser_phy_events_handler_t events_handler)
+{
+ uint32_t err_code;
+
+ if ((m_hci_tx_fsm_state != HCI_TX_STATE_DISABLE) || (m_hci_rx_fsm_state != HCI_RX_STATE_DISABLE))
+ {
+ return NRF_ERROR_INVALID_STATE;
+ }
+
+ if (events_handler == NULL)
+ {
+ return NRF_ERROR_NULL;
+ }
+
+ err_code = hci_timer_init();
+
+ if (err_code != NRF_SUCCESS)
+ {
+ return NRF_ERROR_INTERNAL;
+ }
+
+ nrf_queue_reset(&m_tx_evt_queue);
+ nrf_queue_reset(&m_rx_evt_queue);
+
+ err_code = ser_phy_hci_slip_open(hci_slip_event_handler);
+
+ if (err_code != NRF_SUCCESS)
+ {
+ return err_code;
+ }
+
+ if (err_code == NRF_SUCCESS)
+ {
+ m_packet_ack_number = INITIAL_ACK_NUMBER_EXPECTED;
+ m_packet_seq_number = INITIAL_SEQ_NUMBER;
+ m_ser_phy_callback = events_handler;
+
+#ifndef HCI_LINK_CONTROL
+ m_hci_tx_fsm_state = HCI_TX_STATE_SEND;
+ m_hci_rx_fsm_state = HCI_RX_STATE_RECEIVE;
+#else
+ hci_timeout_setup(HCI_LINK_CONTROL_TIMEOUT);// Trigger sending SYNC messages
+ m_hci_mode = HCI_MODE_UNINITIALIZED;
+ m_hci_other_side_active = false;
+#endif /*HCI_LINK_CONTROL*/
+ }
+ return err_code;
+}
+
+static uint32_t hci_timer_close(void)
+{
+ uint32_t err_code = NRF_SUCCESS;
+
+#ifdef HCI_APP_TIMER
+ err_code = app_timer_stop(m_app_timer_id);
+
+ if (err_code != NRF_SUCCESS)
+ {
+ return NRF_ERROR_INTERNAL;
+ }
+#endif
+
+ return err_code;
+}
+
+/* ser_phy API function */
+void ser_phy_close(void)
+{
+ m_ser_phy_callback = NULL;
+ ser_phy_hci_slip_close();
+ m_hci_tx_fsm_state = HCI_TX_STATE_DISABLE;
+ m_hci_rx_fsm_state = HCI_RX_STATE_DISABLE;
+
+#ifdef HCI_LINK_CONTROL
+ m_hci_mode = HCI_MODE_DISABLE;
+#endif /* HCI_LINK_CONTROL */
+
+ uint32_t err_code = hci_timer_close();
+ ser_phy_hci_assert(err_code == NRF_SUCCESS);
+}
+
+
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/common/transport/ser_phy/ser_phy_hci.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/common/transport/ser_phy/ser_phy_hci.h
new file mode 100644
index 0000000..c2993fd
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/common/transport/ser_phy/ser_phy_hci.h
@@ -0,0 +1,183 @@
+/**
+ * Copyright (c) 2014 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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
+ *
+ * @defgroup ser_phy_hci HCI Serialization PHY
+ * @{
+ * @ingroup ble_sdk_lib_serialization
+ *
+ * @brief HCI PHY layer for serialization.
+ *
+ * @details This file contains declarations of functions and definitions of data structures and
+ * identifiers (typedef enum) used as API of the serialization HCI PHY layer.
+ *
+ *
+ */
+
+#ifndef SER_PHY_HCI_H__
+#define SER_PHY_HCI_H__
+
+#include <stdint.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**@brief Serialization PHY HCI module events types. */
+typedef enum
+{
+ SER_PHY_HCI_SLIP_EVT_PKT_SENT = 0, /**< An event indicating that packet has been transmitted. */
+ SER_PHY_HCI_SLIP_EVT_ACK_SENT, /**< An event indicating that ack packet has been transmitted. */
+ SER_PHY_HCI_SLIP_EVT_PKT_RECEIVED, /**< An event indicating that packet has been received. */
+ SER_PHY_HCI_SLIP_EVT_HW_ERROR, /**< An event indicating a hardware error in PHY HCI module. */
+ SER_PHY_HCI_SLIP_EVT_TYPE_MAX /**< Enumeration upper bound. */
+} ser_phy_hci_slip_evt_type_t;
+
+/**@brief Struct representing a PHY HCI packet. */
+typedef struct
+{
+ uint8_t * p_buffer; /**< Pointer to a buffer containing a packet. */
+ uint16_t num_of_bytes; /**< Length of a packet in octets. */
+} ser_phy_hci_pkt_params_t;
+
+
+/**@brief Struct containing parameters of event of type @ref SER_PHY_HCI_SLIP_EVT_HW_ERROR. */
+typedef struct
+{
+ uint32_t error_code; /**< Hardware error code - specific for a microcontroller. */
+} ser_phy_hci_evt_hw_error_params_t;
+
+
+/**@brief Struct containing events from the Serialization PHY module.
+ *
+ * @note Some events do not have parameters, then the whole information is contained in the evt_type.
+ */
+typedef struct
+{
+ ser_phy_hci_slip_evt_type_t evt_type; /**< Type of an event. */
+ union /**< Union alternative identified by evt_type in the enclosing struct. */
+ {
+ /** Parameters of event of type @ref SER_PHY_HCI_SLIP_EVT_PKT_RECEIVED. */
+ ser_phy_hci_pkt_params_t received_pkt;
+ /** Parameters of event of type @ref SER_PHY_HCI_SLIP_EVT_HW_ERROR. */
+ ser_phy_hci_evt_hw_error_params_t hw_error;
+ } evt_params;
+} ser_phy_hci_slip_evt_t;
+
+
+/**@brief Type of generic callback function handler to be used by all PHY HCI events.
+ *
+ * @param[in] event Serialization PHY HCI module event.
+ */
+typedef void (*ser_phy_hci_slip_event_handler_t)(ser_phy_hci_slip_evt_t *p_event);
+
+/**@brief Function for opening and initializing a HCI SLIP PHY module.
+ *
+ * @note The function initializes hardware and internal module states and registers callback
+ * function to be used by all PHY HCI module events.
+ *
+ * @warning If the function has been already called, the function @ref ser_phy_hci_slip_close has to be
+ * called before ser_phy_hci_slip_open can be called again.
+ *
+ * @param[in] events_handler Generic callback function handler to be used by all PHY HCI module
+ * events.
+ *
+ * @retval NRF_SUCCESS Operation success.
+ * @retval NRF_ERROR_INVALID_STATE Operation failure. The function has been already called.
+ * To call it again, the function @ref ser_phy_hci_slip_close has to
+ * be called first.
+ * @retval NRF_ERROR_NULL Operation failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_PARAM Operation failure. Hardware initialization parameters are not
+ * supported.
+ */
+uint32_t ser_phy_hci_slip_open(ser_phy_hci_slip_event_handler_t events_handler);
+
+
+/**@brief A function for transmitting a HCI SLIP packet.
+ *
+ * @note The function adds a packet pointed by p_buffer parameter to a transmission queue and
+ * schedules generation of an event of type @ref SER_PHY_HCI_SLIP_EVT_PKT_SENT upon transmission
+ * completion.
+ *
+ * @param[in] p_header Pointer to ser_phy_hci_pkt_params_t structure representing packet header.
+ * @param[in] p_payload Pointer to ser_phy_hci_pkt_params_t structure representing packet payload.
+ * @param[in] p_crc Pointer to ser_phy_hci_pkt_params_t structure representing packet crc.
+ *
+ * @retval NRF_SUCCESS Operation success. Packet was added to the transmission queue
+ * and event will be sent upon transmission completion.
+ * @retval NRF_ERROR_NULL Operation failure. NULL pointer supplied in p_header parameter.
+ * NULL pointer is allowed for p_payload and p_crc parameters.
+ * @retval NRF_ERROR_INVALID_PARAM Operation failure. Number of bytes to be sent equals 0.
+ * @retval NRF_ERROR_BUSY Operation failure. Transmitting of a packet in progress.
+ */
+uint32_t ser_phy_hci_slip_tx_pkt_send(const ser_phy_hci_pkt_params_t * p_header,
+ const ser_phy_hci_pkt_params_t * p_payload,
+ const ser_phy_hci_pkt_params_t * p_crc);
+
+
+/**@brief A function for freeing an RX buffer.
+ *
+ * @note The function has to be called as a response to event @ref SER_PHY_HCI_SLIP_EVT_PKT_RECEIVED
+ * when an RX packet has been processed. The function frees the RX buffer and therefore enables
+ * reception of next incoming data.
+
+ * @param[in] p_buffer Pointer to an RX buffer which must be freed.
+ *
+ * @retval NRF_SUCCESS Operation success.
+ * @retval NRF_ERROR_NULL Operation failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_STATE Operation failure. A buffer was already free.
+ */
+uint32_t ser_phy_hci_slip_rx_buf_free(uint8_t * p_buffer);
+
+
+/**@brief A function for closing a PHY HCI module.
+ *
+ * @note The function disables hardware, resets internal module states, and unregisters the events
+ * callback function.
+ */
+void ser_phy_hci_slip_close(void);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* SER_PHY_HCI_H__ */
+/** @} */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/common/transport/ser_phy/ser_phy_hci_slip.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/common/transport/ser_phy/ser_phy_hci_slip.c
new file mode 100644
index 0000000..4139bae
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/common/transport/ser_phy/ser_phy_hci_slip.c
@@ -0,0 +1,689 @@
+/**
+ * Copyright (c) 2014 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+
+#include <string.h>
+#include "ser_phy_hci.h"
+#include "ser_config.h"
+#ifdef SER_CONNECTIVITY
+#include "ser_phy_config_conn.h"
+#else
+#include "ser_phy_config_app.h"
+#endif
+#include "nrf_drv_uart.h"
+#include "app_error.h"
+#include "app_util_platform.h"
+
+#define APP_SLIP_END 0xC0 /**< SLIP code for identifying the beginning and end of a packet frame.. */
+#define APP_SLIP_ESC 0xDB /**< SLIP escape code. This code is used to specify that the following character is specially encoded. */
+#define APP_SLIP_ESC_END 0xDC /**< SLIP special code. When this code follows 0xDB, this character is interpreted as payload data 0xC0.. */
+#define APP_SLIP_ESC_ESC 0xDD /**< SLIP special code. When this code follows 0xDB, this character is interpreted as payload data 0xDB. */
+
+#define HDR_SIZE 4
+#define CRC_SIZE 2
+#define PKT_SIZE (SER_HAL_TRANSPORT_MAX_PKT_SIZE + HDR_SIZE + CRC_SIZE)
+
+static const nrf_drv_uart_t m_uart = NRF_DRV_UART_INSTANCE(0);
+static const nrf_drv_uart_config_t m_uart_config = {
+ .pseltxd = SER_PHY_UART_TX,
+ .pselrxd = SER_PHY_UART_RX,
+ .pselrts = SER_PHY_UART_RTS,
+ .pselcts = SER_PHY_UART_CTS,
+ .p_context = NULL,
+ .interrupt_priority = UART_IRQ_PRIORITY,
+#if defined(UARTE_PRESENT) && defined(UART_PRESENT)
+ .use_easy_dma = true,
+#endif
+ // These values are common for application and connectivity, they are
+ // defined in "ser_config.h".
+ .hwfc = SER_PHY_UART_FLOW_CTRL,
+ .parity = SER_PHY_UART_PARITY,
+ .baudrate = (nrf_uart_baudrate_t)SER_PHY_UART_BAUDRATE
+};
+
+typedef struct {
+ ser_phy_hci_pkt_params_t header;
+ ser_phy_hci_pkt_params_t payload;
+ ser_phy_hci_pkt_params_t crc;
+} ser_phy_hci_slip_pkt_t;
+static ser_phy_hci_slip_pkt_t m_tx_curr_packet;
+static ser_phy_hci_slip_pkt_t m_tx_next_packet;
+
+static ser_phy_hci_slip_evt_t m_ser_phy_hci_slip_event;
+static ser_phy_hci_slip_event_handler_t m_ser_phy_hci_slip_event_handler; /**< Event handler for upper layer */
+
+static uint8_t m_tx_buf0[SER_PHY_HCI_SLIP_TX_BUF_SIZE];
+static uint8_t m_tx_buf1[SER_PHY_HCI_SLIP_TX_BUF_SIZE];
+static uint8_t * mp_tx_buf;
+static uint8_t m_tx_bytes;
+static enum {
+ PHASE_BEGIN,
+ PHASE_HEADER,
+ PHASE_PAYLOAD,
+ PHASE_CRC,
+ PHASE_ACK_END,
+ // The following three elements have to have consecutive values,
+ // 'tx_buf_fill()' relies on this.
+ PHASE_PACKET_END,
+ PHASE_PRE_IDLE = PHASE_PACKET_END + 1,
+ PHASE_IDLE = PHASE_PRE_IDLE + 1
+} volatile m_tx_phase;
+static bool volatile m_tx_in_progress;
+static bool volatile m_tx_pending;
+
+#define NO_EVENT SER_PHY_HCI_SLIP_EVT_TYPE_MAX
+static ser_phy_hci_slip_evt_type_t m_tx_evt_type;
+static ser_phy_hci_slip_evt_type_t m_tx_pending_evt_type;
+
+static uint8_t m_small_buffer[HDR_SIZE];
+static uint8_t m_big_buffer[PKT_SIZE];
+
+static uint8_t * mp_small_buffer = NULL;
+static uint8_t * mp_big_buffer = NULL;
+static uint8_t * mp_buffer = NULL;
+
+static uint8_t m_rx_buf[1];
+static bool m_rx_escape;
+
+
+// The function returns false to signal that no more bytes can be passed to be
+// sent (put into the TX buffer) until UART transmission is done.
+static bool tx_buf_put(uint8_t data_byte)
+{
+ ASSERT(m_tx_bytes < SER_PHY_HCI_SLIP_TX_BUF_SIZE);
+
+ mp_tx_buf[m_tx_bytes] = data_byte;
+ ++m_tx_bytes;
+
+ bool flush = false;
+ ser_phy_hci_slip_evt_type_t slip_evt_type = NO_EVENT;
+ if (m_tx_phase == PHASE_ACK_END)
+ {
+ // Send buffer, then signal that an acknowledge packet has been sent.
+ flush = true;
+ slip_evt_type = SER_PHY_HCI_SLIP_EVT_ACK_SENT;
+ }
+ else if (m_tx_phase == PHASE_PACKET_END)
+ {
+ // Send buffer, then signal that a packet with payload has been sent.
+ flush = true;
+ slip_evt_type = SER_PHY_HCI_SLIP_EVT_PKT_SENT;
+ }
+ else if (m_tx_bytes >= SER_PHY_HCI_SLIP_TX_BUF_SIZE)
+ {
+ // Send buffer (because it is filled up), but don't signal anything,
+ // since the packet sending is not complete yet.
+ flush = true;
+ }
+
+ if (flush)
+ {
+ // If some TX transfer is being done at the moment, a new one cannot be
+ // started, it must be scheduled to be performed later.
+ if (m_tx_in_progress)
+ {
+ m_tx_pending_evt_type = slip_evt_type;
+ m_tx_pending = true;
+ // No more buffers available, can't continue filling.
+ return false;
+ }
+
+ m_tx_in_progress = true;
+ m_tx_evt_type = slip_evt_type;
+ APP_ERROR_CHECK(nrf_drv_uart_tx(&m_uart, mp_tx_buf, m_tx_bytes));
+
+ // Switch to the second buffer.
+ mp_tx_buf = (mp_tx_buf == m_tx_buf0) ? m_tx_buf1 : m_tx_buf0;
+ m_tx_bytes = 0;
+ }
+
+ return true;
+}
+
+static void tx_buf_fill(void)
+{
+ static ser_phy_hci_pkt_params_t * mp_tx_data = NULL;
+ static uint32_t m_tx_index;
+ bool can_continue = true;
+
+ do {
+ static uint8_t tx_escaped_data = 0;
+
+ if (tx_escaped_data != 0)
+ {
+ can_continue = tx_buf_put(tx_escaped_data);
+ tx_escaped_data = 0;
+ }
+ else switch (m_tx_phase)
+ {
+ case PHASE_BEGIN:
+ can_continue = tx_buf_put(APP_SLIP_END);
+ mp_tx_data = &m_tx_curr_packet.header;
+ m_tx_index = 0;
+ m_tx_phase = PHASE_HEADER;
+ tx_escaped_data = 0;
+ break;
+
+ case PHASE_ACK_END:
+ case PHASE_PACKET_END:
+ can_continue = tx_buf_put(APP_SLIP_END);
+
+ // [this is needed for the '++m_tx_phase;' below]
+ m_tx_phase = PHASE_PACKET_END;
+ // no break, intentional fall-through
+
+ case PHASE_PRE_IDLE:
+ // In PHASE_PRE_IDLE the sending process is almost finished, only
+ // the NRF_DRV_UART_EVT_TX_DONE event is needed before it can switch
+ // to PHASE_IDLE. But during this waiting a new packet may appear
+ // (i.e. 'ser_phy_hci_slip_tx_pkt_send()' may be called), hence
+ // the following pointer must be checked before switching the phase,
+ // just like right after writing whole packet to buffer (i.e. in
+ // PHASE_PACKET_END). Therefore, the following code is common for
+ // these two cases.
+ if (m_tx_next_packet.header.p_buffer != NULL)
+ {
+ m_tx_curr_packet = m_tx_next_packet;
+ m_tx_next_packet.header.p_buffer = NULL;
+
+ m_tx_phase = PHASE_BEGIN;
+ break;
+ }
+ // Go to the next phase:
+ // PHASE_PACKET_END -> PHASE_PRE_IDLE
+ // PHASE_PRE_IDLE -> PHASE_IDLE
+ ++m_tx_phase;
+ return;
+
+ default:
+ ASSERT(mp_tx_data->p_buffer != NULL);
+ uint8_t data = mp_tx_data->p_buffer[m_tx_index];
+ ++m_tx_index;
+
+ if (data == APP_SLIP_END)
+ {
+ data = APP_SLIP_ESC;
+ tx_escaped_data = APP_SLIP_ESC_END;
+ }
+ else if (data == APP_SLIP_ESC)
+ {
+ tx_escaped_data = APP_SLIP_ESC_ESC;
+ }
+ can_continue = tx_buf_put(data);
+
+ if (m_tx_index >= mp_tx_data->num_of_bytes)
+ {
+ mp_tx_data->p_buffer = NULL;
+
+ if (m_tx_phase == PHASE_HEADER)
+ {
+ if (m_tx_curr_packet.payload.p_buffer == NULL)
+ {
+ // No payload -> ACK packet.
+ m_tx_phase = PHASE_ACK_END;
+ }
+ else
+ {
+ mp_tx_data = &m_tx_curr_packet.payload;
+ m_tx_index = 0;
+ m_tx_phase = PHASE_PAYLOAD;
+ }
+ }
+ else if (m_tx_phase == PHASE_PAYLOAD)
+ {
+ if (m_tx_curr_packet.crc.p_buffer == NULL)
+ {
+ // Packet without CRC.
+ m_tx_phase = PHASE_PACKET_END;
+ }
+ else
+ {
+ mp_tx_data = &m_tx_curr_packet.crc;
+ m_tx_index = 0;
+ m_tx_phase = PHASE_CRC;
+ }
+ }
+ else
+ {
+ ASSERT(m_tx_phase == PHASE_CRC);
+ m_tx_phase = PHASE_PACKET_END;
+ }
+ }
+ break;
+ }
+ } while (can_continue);
+}
+
+uint32_t ser_phy_hci_slip_tx_pkt_send(const ser_phy_hci_pkt_params_t * p_header,
+ const ser_phy_hci_pkt_params_t * p_payload,
+ const ser_phy_hci_pkt_params_t * p_crc)
+{
+ if (p_header == NULL)
+ {
+ return NRF_ERROR_NULL;
+ }
+
+ CRITICAL_REGION_ENTER();
+
+ // If some packet is already transmitted, schedule this new one to be sent
+ // as next. A critical region is needed here to ensure that the transmission
+ // won't finish before the following assignments are done.
+ if (m_tx_phase != PHASE_IDLE)
+ {
+ m_tx_next_packet.header = *p_header;
+
+ if (p_payload == NULL)
+ {
+ m_tx_next_packet.payload.p_buffer = NULL;
+ }
+ else
+ {
+ m_tx_next_packet.payload = *p_payload;
+ }
+
+ if (p_crc == NULL)
+ {
+ m_tx_next_packet.crc.p_buffer = NULL;
+ }
+ else
+ {
+ m_tx_next_packet.crc = *p_crc;
+ }
+ }
+ else
+ {
+ m_tx_curr_packet.header = *p_header;
+
+ if (p_payload == NULL)
+ {
+ m_tx_curr_packet.payload.p_buffer = NULL;
+ }
+ else
+ {
+ m_tx_curr_packet.payload = *p_payload;
+ }
+
+ if (p_crc == NULL)
+ {
+ m_tx_curr_packet.crc.p_buffer = NULL;
+ }
+ else
+ {
+ m_tx_curr_packet.crc = *p_crc;
+ }
+
+ m_tx_phase = PHASE_BEGIN;
+ tx_buf_fill();
+ }
+
+ CRITICAL_REGION_EXIT();
+
+ return NRF_SUCCESS;
+}
+
+/* Function returns false when last byte in packet is detected.*/
+static bool slip_decode(uint8_t * p_received_byte)
+{
+ switch (*p_received_byte)
+ {
+ case APP_SLIP_END:
+ return false;
+
+ case APP_SLIP_ESC:
+ m_rx_escape = true;
+ break;
+
+ case APP_SLIP_ESC_END:
+
+ if (m_rx_escape == true)
+ {
+ m_rx_escape = false;
+ *p_received_byte = APP_SLIP_END;
+ }
+ break;
+
+ case APP_SLIP_ESC_ESC:
+
+ if (m_rx_escape == true)
+ {
+ m_rx_escape = false;
+ *p_received_byte = APP_SLIP_ESC;
+ }
+ break;
+
+ /* Normal character - decoding not needed*/
+ default:
+ break;
+ }
+
+ return true;
+}
+
+
+static void ser_phi_hci_rx_byte(uint8_t rx_byte)
+{
+ static bool rx_sync = false;
+ uint8_t received_byte = rx_byte;
+ static bool big_buff_in_use = false;
+ static uint32_t m_rx_index;
+ /* Test received byte for SLIP packet start: 0xC0*/
+ if (!rx_sync)
+ {
+ if (received_byte == APP_SLIP_END)
+ {
+ m_rx_index = 0;
+ rx_sync = true;
+ }
+ return;
+ }
+
+ /* Additional check needed in case rx_sync flag was set by end of previous packet*/
+ if ((m_rx_index) == 0 && (received_byte == APP_SLIP_END))
+ {
+ return;
+ }
+
+ /* Check if small (ACK) buffer is available*/
+ if ((mp_small_buffer != NULL) && (big_buff_in_use == false))
+ {
+ if (m_rx_index == 0)
+ {
+ mp_buffer = mp_small_buffer;
+ }
+
+ /* Check if switch between small and big buffer is needed*/
+ if (m_rx_index == sizeof (m_small_buffer) && received_byte != APP_SLIP_END)
+ {
+ /* Check if big (PKT) buffer is available*/
+ if (mp_big_buffer != NULL)
+ {
+ /* Switch to big buffer*/
+ memcpy(m_big_buffer, m_small_buffer, sizeof (m_small_buffer));
+ mp_buffer = m_big_buffer;
+ }
+ else
+ {
+ /* Small buffer is too small and big buffer not available - cannot continue reception*/
+ rx_sync = false;
+ return;
+ }
+ }
+
+ /* Check if big buffer is full */
+ if ((m_rx_index >= PKT_SIZE) && (received_byte != APP_SLIP_END))
+ {
+ /* Do not notify upper layer - the packet is too big and cannot be handled by slip */
+ rx_sync = false;
+ return;
+ }
+
+ /* Decode byte. Will return false when it is 0xC0 - end of packet*/
+ if (slip_decode(&received_byte))
+ {
+ /* Write Rx byte only if it is not escape char */
+ if (!m_rx_escape)
+ {
+ mp_buffer[m_rx_index++] = received_byte;
+ }
+ }
+ else
+ {
+ /* Reset pointers to signalise buffers are locked waiting for upper layer */
+ if (mp_buffer == mp_small_buffer)
+ {
+ mp_small_buffer = NULL;
+ }
+ else
+ {
+ mp_big_buffer = NULL;
+ }
+ /* Report packet reception end*/
+ m_ser_phy_hci_slip_event.evt_type =
+ SER_PHY_HCI_SLIP_EVT_PKT_RECEIVED;
+ m_ser_phy_hci_slip_event.evt_params.received_pkt.p_buffer = mp_buffer;
+ m_ser_phy_hci_slip_event.evt_params.received_pkt.num_of_bytes = m_rx_index;
+ m_ser_phy_hci_slip_event_handler(&m_ser_phy_hci_slip_event);
+
+ rx_sync = false;
+ }
+ }
+ else if (mp_big_buffer != NULL)
+ {
+ big_buff_in_use = true;
+ mp_buffer = mp_big_buffer;
+
+ /* Check if big buffer is full */
+ if ((m_rx_index >= PKT_SIZE) && (received_byte != APP_SLIP_END))
+ {
+ /* Do not notify upper layer - the packet is too big and cannot be handled by slip */
+ rx_sync = false;
+ return;
+ }
+
+ /* Decode byte*/
+ if (slip_decode(&received_byte))
+ {
+ /* Write Rx byte only if it is not escape char */
+ if (!m_rx_escape)
+ {
+ mp_buffer[m_rx_index++] = received_byte;
+ }
+ }
+ else
+ {
+ // Mark the big buffer as locked (it should be freed by the upper
+ // layer).
+ mp_big_buffer = NULL;
+ big_buff_in_use = false;
+
+ /* Report packet reception end*/
+ m_ser_phy_hci_slip_event.evt_type =
+ SER_PHY_HCI_SLIP_EVT_PKT_RECEIVED;
+ m_ser_phy_hci_slip_event.evt_params.received_pkt.p_buffer = mp_buffer;
+ m_ser_phy_hci_slip_event.evt_params.received_pkt.num_of_bytes = m_rx_index;
+ m_ser_phy_hci_slip_event_handler(&m_ser_phy_hci_slip_event);
+
+ rx_sync = false;
+ }
+ }
+ else
+ {
+ /* Both buffers are not available - cannot continue reception*/
+ rx_sync = false;
+ return;
+ }
+}
+
+
+uint32_t ser_phy_hci_slip_rx_buf_free(uint8_t * p_buffer)
+{
+ uint32_t err_code = NRF_SUCCESS;
+
+ if (p_buffer == NULL)
+ {
+ return NRF_ERROR_NULL;
+ }
+ else if (p_buffer == m_small_buffer)
+ {
+ /* Free small buffer*/
+ if (mp_small_buffer == NULL)
+ {
+ mp_small_buffer = m_small_buffer;
+ }
+ else
+ {
+ err_code = NRF_ERROR_INVALID_STATE;
+ }
+ }
+ else if (p_buffer == m_big_buffer)
+ {
+ /* Free big buffer*/
+ if (mp_big_buffer == NULL)
+ {
+ mp_big_buffer = m_big_buffer;
+ }
+ else
+ {
+ err_code = NRF_ERROR_INVALID_STATE;
+ }
+ }
+
+ return err_code;
+}
+
+
+static void uart_event_handler(nrf_drv_uart_event_t * p_event,
+ void * p_context)
+{
+ (void)p_context;
+
+ switch (p_event->type)
+ {
+ case NRF_DRV_UART_EVT_ERROR:
+ // Process the error only if this is a parity or overrun error.
+ // Break and framing errors will always occur before the other
+ // side becomes active.
+ if (p_event->data.error.error_mask &
+ (NRF_UART_ERROR_PARITY_MASK | NRF_UART_ERROR_OVERRUN_MASK))
+ {
+ // Pass error source to upper layer
+ m_ser_phy_hci_slip_event.evt_type =
+ SER_PHY_HCI_SLIP_EVT_HW_ERROR;
+ m_ser_phy_hci_slip_event.evt_params.hw_error.error_code =
+ p_event->data.error.error_mask;
+ m_ser_phy_hci_slip_event_handler(&m_ser_phy_hci_slip_event);
+ }
+ APP_ERROR_CHECK(nrf_drv_uart_rx(&m_uart, m_rx_buf, 1));
+ break;
+
+ case NRF_DRV_UART_EVT_TX_DONE:
+ // If there is a pending transfer (the second buffer is ready to
+ // be sent), start it immediately.
+ if (m_tx_pending)
+ {
+ APP_ERROR_CHECK(nrf_drv_uart_tx(&m_uart, mp_tx_buf, m_tx_bytes));
+
+ // Switch to the buffer that has just been sent completely
+ // and now can be filled again.
+ mp_tx_buf = (mp_tx_buf == m_tx_buf0) ? m_tx_buf1 : m_tx_buf0;
+ m_tx_bytes = 0;
+
+ m_ser_phy_hci_slip_event.evt_type = m_tx_evt_type;
+ m_tx_evt_type = m_tx_pending_evt_type;
+
+ m_tx_pending = false;
+ }
+ else
+ {
+ m_tx_in_progress = false;
+ m_ser_phy_hci_slip_event.evt_type = m_tx_evt_type;
+ }
+ // If needed, notify the upper layer that the packet transfer is
+ // complete (note that this notification may result in another
+ // packet send request, so everything must be cleaned up above).
+ if (m_ser_phy_hci_slip_event.evt_type != NO_EVENT)
+ {
+ m_ser_phy_hci_slip_event_handler(&m_ser_phy_hci_slip_event);
+ }
+ // And if the sending process is not yet finished, look what is
+ // to be done next.
+ if (m_tx_phase != PHASE_IDLE)
+ {
+ tx_buf_fill();
+ }
+ break;
+
+ case NRF_DRV_UART_EVT_RX_DONE:
+ {
+ uint8_t rx_byte = m_rx_buf[0];
+ APP_ERROR_CHECK(nrf_drv_uart_rx(&m_uart, m_rx_buf, 1));
+ ser_phi_hci_rx_byte(rx_byte);
+ }
+ break;
+
+ default:
+ APP_ERROR_CHECK(NRF_ERROR_INTERNAL);
+ }
+}
+
+
+uint32_t ser_phy_hci_slip_open(ser_phy_hci_slip_event_handler_t events_handler)
+{
+ uint32_t err_code;
+
+ if (events_handler == NULL)
+ {
+ return NRF_ERROR_NULL;
+ }
+
+ // Check if function was not called before.
+ if (m_ser_phy_hci_slip_event_handler != NULL)
+ {
+ return NRF_ERROR_INVALID_STATE;
+ }
+
+ m_ser_phy_hci_slip_event_handler = events_handler;
+
+ err_code = nrf_drv_uart_init(&m_uart, &m_uart_config, uart_event_handler);
+ if (err_code != NRF_SUCCESS)
+ {
+ return NRF_ERROR_INVALID_PARAM;
+ }
+
+ mp_tx_buf = m_tx_buf0;
+ m_tx_bytes = 0;
+ m_tx_phase = PHASE_IDLE;
+ m_tx_in_progress = false;
+ m_tx_pending = false;
+
+ m_rx_escape = false;
+ mp_small_buffer = m_small_buffer;
+ mp_big_buffer = m_big_buffer;
+
+ APP_ERROR_CHECK(nrf_drv_uart_rx(&m_uart, m_rx_buf, 1));
+
+ return NRF_SUCCESS;
+}
+
+
+void ser_phy_hci_slip_close(void)
+{
+ nrf_drv_uart_uninit(&m_uart);
+ m_ser_phy_hci_slip_event_handler = NULL;
+}
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/common/transport/ser_phy/ser_phy_hci_slip_cdc.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/common/transport/ser_phy/ser_phy_hci_slip_cdc.c
new file mode 100644
index 0000000..99efac0
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/common/transport/ser_phy/ser_phy_hci_slip_cdc.c
@@ -0,0 +1,720 @@
+/**
+ * Copyright (c) 2014 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+
+#include <string.h>
+#include "ser_phy_hci.h"
+#include "ser_config.h"
+#ifdef SER_CONNECTIVITY
+#include "ser_phy_config_conn.h"
+#else
+#include "ser_phy_config_app.h"
+#endif
+#include "app_usbd_cdc_acm.h"
+#include "nrf_drv_clock.h"
+#include "app_error.h"
+#include "app_util_platform.h"
+
+#define NRF_LOG_MODULE_NAME sphy_cdc
+#include "nrf_log.h"
+NRF_LOG_MODULE_REGISTER();
+
+#define APP_SLIP_END 0xC0 /**< SLIP code for identifying the beginning and end of a packet frame.. */
+#define APP_SLIP_ESC 0xDB /**< SLIP escape code. This code is used to specify that the following character is specially encoded. */
+#define APP_SLIP_ESC_END 0xDC /**< SLIP special code. When this code follows 0xDB, this character is interpreted as payload data 0xC0.. */
+#define APP_SLIP_ESC_ESC 0xDD /**< SLIP special code. When this code follows 0xDB, this character is interpreted as payload data 0xDB. */
+
+#define HDR_SIZE 4
+#define CRC_SIZE 2
+#define PKT_SIZE (SER_HAL_TRANSPORT_MAX_PKT_SIZE + HDR_SIZE + CRC_SIZE)
+
+static void cdc_acm_user_ev_handler(app_usbd_class_inst_t const * p_inst,
+ app_usbd_cdc_acm_user_event_t event);
+
+#define CDC_ACM_COMM_INTERFACE 0
+#define CDC_ACM_COMM_EPIN NRF_DRV_USBD_EPIN2
+
+#define CDC_ACM_DATA_INTERFACE 1
+#define CDC_ACM_DATA_EPIN NRF_DRV_USBD_EPIN1
+#define CDC_ACM_DATA_EPOUT NRF_DRV_USBD_EPOUT1
+
+APP_USBD_CDC_ACM_GLOBAL_DEF(m_app_cdc_acm,
+ cdc_acm_user_ev_handler,
+ CDC_ACM_COMM_INTERFACE,
+ CDC_ACM_DATA_INTERFACE,
+ CDC_ACM_COMM_EPIN,
+ CDC_ACM_DATA_EPIN,
+ CDC_ACM_DATA_EPOUT,
+ APP_USBD_CDC_COMM_PROTOCOL_NONE
+);
+
+static bool volatile m_port_open;
+
+typedef struct {
+ ser_phy_hci_pkt_params_t header;
+ ser_phy_hci_pkt_params_t payload;
+ ser_phy_hci_pkt_params_t crc;
+} ser_phy_hci_slip_pkt_t;
+static ser_phy_hci_slip_pkt_t m_tx_curr_packet;
+static ser_phy_hci_slip_pkt_t m_tx_next_packet;
+
+static ser_phy_hci_slip_evt_t m_ser_phy_hci_slip_event;
+static ser_phy_hci_slip_event_handler_t m_ser_phy_hci_slip_event_handler; /**< Event handler for upper layer */
+
+static uint8_t m_tx_buf0[NRF_DRV_USBD_EPSIZE];
+static uint8_t m_tx_buf1[NRF_DRV_USBD_EPSIZE];
+static uint8_t * mp_tx_buf;
+static uint8_t m_tx_bytes;
+
+static enum {
+ PHASE_BEGIN,
+ PHASE_HEADER,
+ PHASE_PAYLOAD,
+ PHASE_CRC,
+ PHASE_ACK_END,
+ // The following three elements have to have consecutive values,
+ // 'tx_buf_fill()' relies on this.
+ PHASE_PACKET_END,
+ PHASE_PRE_IDLE = PHASE_PACKET_END + 1,
+ PHASE_IDLE = PHASE_PRE_IDLE + 1
+} volatile m_tx_phase;
+
+static bool volatile m_tx_in_progress;
+static bool volatile m_tx_pending;
+
+#define NO_EVENT SER_PHY_HCI_SLIP_EVT_TYPE_MAX
+static ser_phy_hci_slip_evt_type_t m_tx_evt_type;
+static ser_phy_hci_slip_evt_type_t m_tx_pending_evt_type;
+
+static ser_phy_hci_pkt_params_t * mp_tx_data = NULL;
+static uint32_t m_tx_index;
+
+static uint8_t m_small_buffer[HDR_SIZE];
+static uint8_t m_big_buffer[PKT_SIZE];
+
+static uint8_t * mp_small_buffer = NULL;
+static uint8_t * mp_big_buffer = NULL;
+static uint8_t * mp_buffer = NULL;
+static uint32_t m_rx_index;
+
+static uint8_t m_rx_byte;
+static bool m_rx_escape;
+
+
+// The function returns false to signal that no more bytes can be passed to be
+// sent (put into the TX buffer) until UART transmission is done.
+static bool tx_buf_put(uint8_t data_byte)
+{
+ ASSERT(m_tx_bytes < SER_PHY_HCI_SLIP_TX_BUF_SIZE);
+ mp_tx_buf[m_tx_bytes] = data_byte;
+ ++m_tx_bytes;
+
+ bool flush = false;
+ ser_phy_hci_slip_evt_type_t slip_evt_type = NO_EVENT;
+ if (m_tx_phase == PHASE_ACK_END)
+ {
+ // Send buffer, then signal that an acknowledge packet has been sent.
+ flush = true;
+ slip_evt_type = SER_PHY_HCI_SLIP_EVT_ACK_SENT;
+ }
+ else if (m_tx_phase == PHASE_PACKET_END)
+ {
+ // Send buffer, then signal that a packet with payload has been sent.
+ flush = true;
+ slip_evt_type = SER_PHY_HCI_SLIP_EVT_PKT_SENT;
+ }
+ else if (m_tx_bytes >= SER_PHY_HCI_SLIP_TX_BUF_SIZE)
+ {
+ // Send buffer (because it is filled up), but don't signal anything,
+ // since the packet sending is not complete yet.
+ flush = true;
+ }
+
+ if (flush)
+ {
+ // If some TX transfer is being done at the moment, a new one cannot be
+ // started, it must be scheduled to be performed later.
+ if (m_tx_in_progress)
+ {
+ m_tx_pending_evt_type = slip_evt_type;
+ m_tx_pending = true;
+ // No more buffers available, can't continue filling.
+ return false;
+ }
+
+ if (m_port_open)
+ {
+ m_tx_in_progress = true;
+ m_tx_evt_type = slip_evt_type;
+ APP_ERROR_CHECK(app_usbd_cdc_acm_write(&m_app_cdc_acm,
+ mp_tx_buf, m_tx_bytes));
+ }
+
+ // Switch to the second buffer.
+ mp_tx_buf = (mp_tx_buf == m_tx_buf0) ? m_tx_buf1 : m_tx_buf0;
+ m_tx_bytes = 0;
+ }
+
+ return true;
+}
+
+static void tx_buf_fill(void)
+{
+ bool can_continue = true;
+ do {
+ static uint8_t tx_escaped_data = 0;
+
+ if (tx_escaped_data != 0)
+ {
+ can_continue = tx_buf_put(tx_escaped_data);
+ tx_escaped_data = 0;
+ }
+ else switch (m_tx_phase)
+ {
+ case PHASE_BEGIN:
+ can_continue = tx_buf_put(APP_SLIP_END);
+ mp_tx_data = &m_tx_curr_packet.header;
+ m_tx_index = 0;
+ m_tx_phase = PHASE_HEADER;
+ tx_escaped_data = 0;
+ break;
+
+ case PHASE_ACK_END:
+ case PHASE_PACKET_END:
+ can_continue = tx_buf_put(APP_SLIP_END);
+
+ // [this is needed for the '++m_tx_phase;' below]
+ m_tx_phase = PHASE_PACKET_END;
+ // no break, intentional fall-through
+
+ case PHASE_PRE_IDLE:
+ // In PHASE_PRE_IDLE the sending process is almost finished, only
+ // the NRF_DRV_UART_EVT_TX_DONE event is needed before it can switch
+ // to PHASE_IDLE. But during this waiting a new packet may appear
+ // (i.e. 'ser_phy_hci_slip_tx_pkt_send()' may be called), hence
+ // the following pointer must be checked before switching the phase,
+ // just like right after writing whole packet to buffer (i.e. in
+ // PHASE_PACKET_END). Therefore, the following code is common for
+ // these two cases.
+ if (m_tx_next_packet.header.p_buffer != NULL)
+ {
+ m_tx_curr_packet = m_tx_next_packet;
+ m_tx_next_packet.header.p_buffer = NULL;
+
+ m_tx_phase = PHASE_BEGIN;
+ break;
+ }
+ // Go to the next phase:
+ // PHASE_PACKET_END -> PHASE_PRE_IDLE
+ // PHASE_PRE_IDLE -> PHASE_IDLE
+ ++m_tx_phase;
+ return;
+
+ default:
+ ASSERT(mp_tx_data->p_buffer != NULL);
+ uint8_t data = mp_tx_data->p_buffer[m_tx_index];
+ ++m_tx_index;
+
+ if (data == APP_SLIP_END)
+ {
+ data = APP_SLIP_ESC;
+ tx_escaped_data = APP_SLIP_ESC_END;
+ }
+ else if (data == APP_SLIP_ESC)
+ {
+ tx_escaped_data = APP_SLIP_ESC_ESC;
+ }
+ can_continue = tx_buf_put(data);
+
+ if (m_tx_index >= mp_tx_data->num_of_bytes)
+ {
+ mp_tx_data->p_buffer = NULL;
+
+ if (m_tx_phase == PHASE_HEADER)
+ {
+ if (m_tx_curr_packet.payload.p_buffer == NULL)
+ {
+ // No payload -> ACK packet.
+ m_tx_phase = PHASE_ACK_END;
+ }
+ else
+ {
+ mp_tx_data = &m_tx_curr_packet.payload;
+ m_tx_index = 0;
+ m_tx_phase = PHASE_PAYLOAD;
+ }
+ }
+ else if (m_tx_phase == PHASE_PAYLOAD)
+ {
+ if (m_tx_curr_packet.crc.p_buffer == NULL)
+ {
+ // Packet without CRC.
+ m_tx_phase = PHASE_PACKET_END;
+ }
+ else
+ {
+ mp_tx_data = &m_tx_curr_packet.crc;
+ m_tx_index = 0;
+ m_tx_phase = PHASE_CRC;
+ }
+ }
+ else
+ {
+ ASSERT(m_tx_phase == PHASE_CRC);
+ m_tx_phase = PHASE_PACKET_END;
+ }
+ }
+ break;
+ }
+ } while (can_continue);
+}
+
+uint32_t ser_phy_hci_slip_tx_pkt_send(const ser_phy_hci_pkt_params_t * p_header,
+ const ser_phy_hci_pkt_params_t * p_payload,
+ const ser_phy_hci_pkt_params_t * p_crc)
+{
+ if (p_header == NULL)
+ {
+ return NRF_ERROR_NULL;
+ }
+
+ if (!m_port_open)
+ {
+ return NRF_SUCCESS;
+ }
+
+ CRITICAL_REGION_ENTER();
+
+ // If some packet is already transmitted, schedule this new one to be sent
+ // as next. A critical region is needed here to ensure that the transmission
+ // won't finish before the following assignments are done.
+ if (m_tx_phase != PHASE_IDLE)
+ {
+ m_tx_next_packet.header = *p_header;
+
+ if (p_payload == NULL)
+ {
+ m_tx_next_packet.payload.p_buffer = NULL;
+ }
+ else
+ {
+ m_tx_next_packet.payload = *p_payload;
+ }
+
+ if (p_crc == NULL)
+ {
+ m_tx_next_packet.crc.p_buffer = NULL;
+ }
+ else
+ {
+ m_tx_next_packet.crc = *p_crc;
+ }
+ }
+ else
+ {
+ m_tx_curr_packet.header = *p_header;
+
+ if (p_payload == NULL)
+ {
+ m_tx_curr_packet.payload.p_buffer = NULL;
+ }
+ else
+ {
+ m_tx_curr_packet.payload = *p_payload;
+ }
+
+ if (p_crc == NULL)
+ {
+ m_tx_curr_packet.crc.p_buffer = NULL;
+ }
+ else
+ {
+ m_tx_curr_packet.crc = *p_crc;
+ }
+
+ m_tx_phase = PHASE_BEGIN;
+ tx_buf_fill();
+ }
+
+ CRITICAL_REGION_EXIT();
+
+ return NRF_SUCCESS;
+}
+
+/* Function returns false when last byte in packet is detected.*/
+static bool slip_decode(uint8_t * p_received_byte)
+{
+ switch (*p_received_byte)
+ {
+ case APP_SLIP_END:
+ return false;
+
+ case APP_SLIP_ESC:
+ m_rx_escape = true;
+ break;
+
+ case APP_SLIP_ESC_END:
+
+ if (m_rx_escape == true)
+ {
+ m_rx_escape = false;
+ *p_received_byte = APP_SLIP_END;
+ }
+ break;
+
+ case APP_SLIP_ESC_ESC:
+
+ if (m_rx_escape == true)
+ {
+ m_rx_escape = false;
+ *p_received_byte = APP_SLIP_ESC;
+ }
+ break;
+
+ /* Normal character - decoding not needed*/
+ default:
+ break;
+ }
+
+ return true;
+}
+
+
+static void ser_phi_hci_rx_byte(uint8_t rx_byte)
+{
+ static bool rx_sync = false;
+ uint8_t received_byte = rx_byte;
+ static bool big_buff_in_use = false;
+
+ /* Test received byte for SLIP packet start: 0xC0*/
+ if (!rx_sync)
+ {
+ if (received_byte == APP_SLIP_END)
+ {
+ m_rx_index = 0;
+ rx_sync = true;
+ }
+ return;
+ }
+
+ /* Additional check needed in case rx_sync flag was set by end of previous packet*/
+ if ((m_rx_index) == 0 && (received_byte == APP_SLIP_END))
+ {
+ return;
+ }
+
+ /* Check if small (ACK) buffer is available*/
+ if ((mp_small_buffer != NULL) && (big_buff_in_use == false))
+ {
+ if (m_rx_index == 0)
+ {
+ mp_buffer = mp_small_buffer;
+ }
+
+ /* Check if switch between small and big buffer is needed*/
+ if (m_rx_index == sizeof (m_small_buffer) /*NEW!!!*/ && received_byte != APP_SLIP_END)
+ {
+ /* Check if big (PKT) buffer is available*/
+ if (mp_big_buffer != NULL)
+ {
+ /* Switch to big buffer*/
+ memcpy(m_big_buffer, m_small_buffer, sizeof (m_small_buffer));
+ mp_buffer = m_big_buffer;
+ }
+ else
+ {
+ /* Small buffer is too small and big buffer not available - cannot continue reception*/
+ rx_sync = false;
+ return;
+ }
+ }
+
+ /* Check if big buffer is full */
+ if ((m_rx_index >= PKT_SIZE) && (received_byte != APP_SLIP_END))
+ {
+ /* Do not notify upper layer - the packet is too big and cannot be handled by slip */
+ rx_sync = false;
+ return;
+ }
+
+ /* Decode byte. Will return false when it is 0xC0 - end of packet*/
+ if (slip_decode(&received_byte))
+ {
+ /* Write Rx byte only if it is not escape char */
+ if (!m_rx_escape)
+ {
+ mp_buffer[m_rx_index++] = received_byte;
+ }
+ }
+ else
+ {
+ /* Reset pointers to signalise buffers are locked waiting for upper layer */
+ if (mp_buffer == mp_small_buffer)
+ {
+ mp_small_buffer = NULL;
+ }
+ else
+ {
+ mp_big_buffer = NULL;
+ }
+ /* Report packet reception end*/
+ m_ser_phy_hci_slip_event.evt_type =
+ SER_PHY_HCI_SLIP_EVT_PKT_RECEIVED;
+ m_ser_phy_hci_slip_event.evt_params.received_pkt.p_buffer = mp_buffer;
+ m_ser_phy_hci_slip_event.evt_params.received_pkt.num_of_bytes = m_rx_index;
+ m_ser_phy_hci_slip_event_handler(&m_ser_phy_hci_slip_event);
+
+ rx_sync = false;
+ }
+ }
+ else if (mp_big_buffer != NULL)
+ {
+ big_buff_in_use = true;
+ mp_buffer = mp_big_buffer;
+
+ /* Check if big buffer is full */
+ if ((m_rx_index >= PKT_SIZE) && (received_byte != APP_SLIP_END))
+ {
+ /* Do not notify upper layer - the packet is too big and cannot be handled by slip */
+ rx_sync = false;
+ return;
+ }
+
+ /* Decode byte*/
+ if (slip_decode(&received_byte))
+ {
+ /* Write Rx byte only if it is not escape char */
+ if (!m_rx_escape)
+ {
+ mp_buffer[m_rx_index++] = received_byte;
+ }
+ }
+ else
+ {
+ // Mark the big buffer as locked (it should be freed by the upper
+ // layer).
+ mp_big_buffer = NULL;
+ big_buff_in_use = false;
+
+ /* Report packet reception end*/
+ m_ser_phy_hci_slip_event.evt_type =
+ SER_PHY_HCI_SLIP_EVT_PKT_RECEIVED;
+ m_ser_phy_hci_slip_event.evt_params.received_pkt.p_buffer = mp_buffer;
+ m_ser_phy_hci_slip_event.evt_params.received_pkt.num_of_bytes = m_rx_index;
+ m_ser_phy_hci_slip_event_handler(&m_ser_phy_hci_slip_event);
+
+ rx_sync = false;
+ }
+ }
+ else
+ {
+ /* Both buffers are not available - cannot continue reception*/
+ rx_sync = false;
+ return;
+ }
+}
+
+
+uint32_t ser_phy_hci_slip_rx_buf_free(uint8_t * p_buffer)
+{
+ uint32_t err_code = NRF_SUCCESS;
+
+ if (p_buffer == NULL)
+ {
+ return NRF_ERROR_NULL;
+ }
+ else if (p_buffer == m_small_buffer)
+ {
+ /* Free small buffer*/
+ if (mp_small_buffer == NULL)
+ {
+ mp_small_buffer = m_small_buffer;
+ }
+ else
+ {
+ err_code = NRF_ERROR_INVALID_STATE;
+ }
+ }
+ else if (p_buffer == m_big_buffer)
+ {
+ /* Free big buffer*/
+ if (mp_big_buffer == NULL)
+ {
+ mp_big_buffer = m_big_buffer;
+ }
+ else
+ {
+ err_code = NRF_ERROR_INVALID_STATE;
+ }
+ }
+
+ return err_code;
+}
+
+
+static void cdc_acm_user_ev_handler(app_usbd_class_inst_t const * p_inst,
+ app_usbd_cdc_acm_user_event_t event)
+{
+ app_usbd_cdc_acm_t const * p_cdc_acm = app_usbd_cdc_acm_class_get(p_inst);
+
+ switch (event)
+ {
+ case APP_USBD_CDC_ACM_USER_EVT_PORT_OPEN:
+ NRF_LOG_DEBUG("EVT_PORT_OPEN");
+ if (!m_port_open)
+ {
+ ret_code_t ret_code;
+
+ m_port_open = true;
+
+ do {
+ ret_code = app_usbd_cdc_acm_read(p_cdc_acm, &m_rx_byte, 1);
+ if (ret_code == NRF_SUCCESS)
+ {
+ ser_phi_hci_rx_byte(m_rx_byte);
+ }
+ else if (ret_code != NRF_ERROR_IO_PENDING)
+ {
+ APP_ERROR_CHECK(ret_code);
+ }
+ } while (ret_code == NRF_SUCCESS);
+ }
+ break;
+
+ case APP_USBD_CDC_ACM_USER_EVT_PORT_CLOSE:
+ NRF_LOG_DEBUG("EVT_PORT_CLOSE");
+ m_port_open = false;
+ break;
+
+ case APP_USBD_CDC_ACM_USER_EVT_TX_DONE:
+ // If there is a pending transfer (the second buffer is ready to
+ // be sent), start it immediately.
+ if (m_tx_pending)
+ {
+ APP_ERROR_CHECK(app_usbd_cdc_acm_write(p_cdc_acm,
+ mp_tx_buf, m_tx_bytes));
+
+ // Switch to the buffer that has just been sent completely
+ // and now can be filled again.
+ mp_tx_buf = (mp_tx_buf == m_tx_buf0) ? m_tx_buf1 : m_tx_buf0;
+ m_tx_bytes = 0;
+
+ m_ser_phy_hci_slip_event.evt_type = m_tx_evt_type;
+ m_tx_evt_type = m_tx_pending_evt_type;
+
+ m_tx_pending = false;
+ }
+ else
+ {
+ m_tx_in_progress = false;
+ m_ser_phy_hci_slip_event.evt_type = m_tx_evt_type;
+ }
+ // If needed, notify the upper layer that the packet transfer is
+ // complete (note that this notification may result in another
+ // packet send request, so everything must be cleaned up above).
+ if (m_ser_phy_hci_slip_event.evt_type != NO_EVENT)
+ {
+ m_ser_phy_hci_slip_event_handler(&m_ser_phy_hci_slip_event);
+ }
+ // And if the sending process is not yet finished, look what is
+ // to be done next.
+ if (m_tx_phase != PHASE_IDLE)
+ {
+ tx_buf_fill();
+ }
+ break;
+
+ case APP_USBD_CDC_ACM_USER_EVT_RX_DONE:
+ {
+ ret_code_t ret_code;
+ do
+ {
+ ser_phi_hci_rx_byte(m_rx_byte);
+
+ ret_code = app_usbd_cdc_acm_read(p_cdc_acm, &m_rx_byte, 1);
+ } while (ret_code == NRF_SUCCESS);
+ }
+ break;
+
+ default:
+ break;
+ }
+}
+
+uint32_t ser_phy_hci_slip_open(ser_phy_hci_slip_event_handler_t events_handler)
+{
+ if (events_handler == NULL)
+ {
+ return NRF_ERROR_NULL;
+ }
+
+ // Check if function was not called before.
+ if (m_ser_phy_hci_slip_event_handler != NULL)
+ {
+ return NRF_ERROR_INVALID_STATE;
+ }
+
+ ret_code_t ret = app_usbd_class_append(
+ app_usbd_cdc_acm_class_inst_get(&m_app_cdc_acm));
+ if (ret != NRF_SUCCESS)
+ {
+ return ret;
+ }
+
+
+ m_ser_phy_hci_slip_event_handler = events_handler;
+
+ mp_tx_buf = m_tx_buf0;
+ m_tx_bytes = 0;
+ m_tx_phase = PHASE_IDLE;
+ m_tx_in_progress = false;
+ m_tx_pending = false;
+
+ m_rx_escape = false;
+ mp_small_buffer = m_small_buffer;
+ mp_big_buffer = m_big_buffer;
+
+ return NRF_SUCCESS;
+}
+
+
+void ser_phy_hci_slip_close(void)
+{
+ m_ser_phy_hci_slip_event_handler = NULL;
+}
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/common/transport/ser_phy/ser_phy_nohci.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/common/transport/ser_phy/ser_phy_nohci.c
new file mode 100644
index 0000000..4580086
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/common/transport/ser_phy/ser_phy_nohci.c
@@ -0,0 +1,382 @@
+/**
+ * Copyright (c) 2014 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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
+ *
+ * @defgroup ser_phy_spi_phy_driver_slave ser_phy_nrf51_spi_slave.c
+ * @{
+ * @ingroup ser_phy_spi_phy_driver_slave
+ *
+ * @brief SPI_RAW PHY slave driver.
+ */
+
+#include <stddef.h>
+#include <string.h>
+
+#include "app_error.h"
+#include "app_util.h"
+#include "app_util_platform.h"
+#include "app_timer.h"
+#include "ser_phy.h"
+#include "ser_phy_hci.h"
+#include "crc16.h"
+#include "nrf_soc.h"
+
+#include "ser_phy_debug_comm.h"
+
+static bool m_flag_nohci_init = false;
+static bool m_flag_expect_ack;
+static bool m_flag_buffer_reqested = false;
+
+static uint16_t m_rx_packet_length;
+static uint8_t * m_p_rx_packet;
+
+static uint16_t m_rx_pending_packet_length;
+static uint8_t * m_p_rx_pending_packet;
+
+static uint16_t m_rx_allocated_packet_length;
+static uint8_t * m_p_rx_allocated_packet;
+
+static uint8_t * m_p_tx_packet = NULL;
+static uint16_t m_tx_packet_length;
+
+static ser_phy_events_handler_t m_ser_phy_callback = NULL;
+
+#define PKT_HDR_SIZE 4 /**< Packet header size in number of bytes. */
+#define PKT_CRC_SIZE 2 /**< Packet CRC size in number of bytes. */
+
+static void ser_phy_nohci_assert(bool cond)
+{
+ APP_ERROR_CHECK_BOOL(cond);
+}
+
+
+static void ser_phy_event_callback(ser_phy_evt_t event)
+{
+ if (m_ser_phy_callback)
+ {
+ m_ser_phy_callback(event);
+ }
+}
+
+
+static void memory_request_callback(uint16_t size)
+{
+ ser_phy_evt_t event;
+
+ DEBUG_EVT_HCI_PHY_EVT_BUF_REQUEST(0);
+
+ event.evt_type = SER_PHY_EVT_RX_BUF_REQUEST;
+ event.evt_params.rx_buf_request.num_of_bytes = size;
+ ser_phy_event_callback(event);
+}
+
+
+static void packet_received_callback(uint8_t * pBuffer, uint16_t size)
+{
+ ser_phy_evt_t event;
+
+ DEBUG_EVT_HCI_PHY_EVT_RX_PKT_RECEIVED(0);
+
+ event.evt_type = SER_PHY_EVT_RX_PKT_RECEIVED;
+ event.evt_params.rx_pkt_received.num_of_bytes = size;
+ event.evt_params.rx_pkt_received.p_buffer = pBuffer;
+ ser_phy_event_callback(event);
+}
+
+
+static void packet_dropped_callback(void)
+{
+ ser_phy_evt_t event;
+
+ DEBUG_EVT_HCI_PHY_EVT_RX_PKT_DROPPED(0);
+
+ event.evt_type = SER_PHY_EVT_RX_PKT_DROPPED;
+ ser_phy_event_callback(event);
+}
+
+
+static void packet_transmitted_callback(void)
+{
+ ser_phy_evt_t event;
+
+ DEBUG_EVT_HCI_PHY_EVT_TX_PKT_SENT(0);
+
+ event.evt_type = SER_PHY_EVT_TX_PKT_SENT;
+ ser_phy_event_callback(event);
+}
+
+
+static void hci_slip_event_handler(ser_phy_hci_slip_evt_t * p_event)
+{
+ if ( p_event->evt_type == SER_PHY_HCI_SLIP_EVT_PKT_SENT )
+ {
+ DEBUG_EVT_SLIP_PACKET_TXED(0);
+
+ if (!m_flag_expect_ack)
+ {
+ m_p_tx_packet = NULL;
+ packet_transmitted_callback();
+ }
+ else
+ {
+ ser_phy_nohci_assert(false); // packet was send as a ACK packet, callback should be with ACK_SENT
+ }
+
+ }
+ else if ( p_event->evt_type == SER_PHY_HCI_SLIP_EVT_ACK_SENT )
+ {
+ DEBUG_EVT_SLIP_ACK_TXED(0);
+
+ if (m_flag_expect_ack)
+ {
+ m_p_tx_packet = NULL;
+ packet_transmitted_callback();
+ }
+ else
+ {
+ ser_phy_nohci_assert(false); // packet was send as a normal packet, callback should be with PKT_SENT
+ }
+
+ }
+ else if ( p_event->evt_type == SER_PHY_HCI_SLIP_EVT_PKT_RECEIVED )
+ {
+ CRITICAL_REGION_ENTER();
+
+ if (m_p_rx_packet == NULL)
+ {
+ m_p_rx_packet = p_event->evt_params.received_pkt.p_buffer;
+ m_rx_packet_length = p_event->evt_params.received_pkt.num_of_bytes;
+ m_p_rx_allocated_packet = m_p_rx_packet;
+ m_rx_allocated_packet_length = m_rx_packet_length;
+ m_flag_buffer_reqested = true;
+ memory_request_callback(m_rx_allocated_packet_length);
+ }
+ else if (m_p_rx_pending_packet == NULL)
+ {
+ m_p_rx_pending_packet = p_event->evt_params.received_pkt.p_buffer;
+ m_rx_pending_packet_length = p_event->evt_params.received_pkt.num_of_bytes;
+ }
+ else
+ {
+ // both buffers are not released; this is fault
+ ser_phy_nohci_assert(false);
+ }
+ CRITICAL_REGION_EXIT();
+ }
+ else
+ {
+ // no other callbacks are expected
+ ser_phy_nohci_assert(false);
+ }
+}
+
+
+/* ser_phy API function */
+void ser_phy_interrupts_enable(void)
+{
+
+ NVIC_EnableIRQ(UART0_IRQn);
+ return;
+}
+
+
+/* ser_phy API function */
+void ser_phy_interrupts_disable(void)
+{
+ NVIC_DisableIRQ(UART0_IRQn);
+ return;
+}
+
+
+/* ser_phy API function */
+uint32_t ser_phy_rx_buf_set(uint8_t * p_buffer)
+{
+ uint32_t status = NRF_SUCCESS;
+
+ if (m_flag_buffer_reqested)
+ {
+ m_flag_buffer_reqested = false;
+
+ if (p_buffer)
+ {
+ memcpy(p_buffer, m_p_rx_allocated_packet, m_rx_allocated_packet_length);
+ packet_received_callback(p_buffer, m_rx_allocated_packet_length);
+ }
+ else
+ {
+ packet_dropped_callback();
+ }
+
+ CRITICAL_REGION_ENTER();
+
+ if (m_p_rx_allocated_packet == m_p_rx_packet && (m_p_rx_pending_packet == NULL))
+ {
+ // packet is copied and there is no pending packet
+ (void) ser_phy_hci_slip_rx_buf_free(m_p_rx_packet);
+ m_p_rx_packet = NULL;
+ m_p_rx_allocated_packet = NULL;
+ }
+ else if (m_p_rx_allocated_packet == m_p_rx_packet && (m_p_rx_pending_packet != NULL))
+ {
+ // there is a pending packet - request memory for it
+ m_p_rx_allocated_packet = m_p_rx_pending_packet;
+ m_rx_allocated_packet_length = m_rx_pending_packet_length;
+ m_flag_buffer_reqested = true;
+ }
+ else if (m_p_rx_allocated_packet == m_p_rx_pending_packet )
+ {
+ // the pending packet was serviced - release both
+ m_p_rx_allocated_packet = NULL;
+ (void) ser_phy_hci_slip_rx_buf_free(m_p_rx_packet);
+ m_p_rx_packet = NULL;
+ (void) ser_phy_hci_slip_rx_buf_free(m_p_rx_pending_packet);
+ m_p_rx_pending_packet = NULL;
+ }
+ else
+ {
+ // no other calls are expected
+ ser_phy_nohci_assert(false);
+ }
+ CRITICAL_REGION_EXIT();
+
+ // request memory for a pending
+ if (m_p_rx_allocated_packet)
+ {
+ memory_request_callback(m_rx_allocated_packet_length);
+ }
+ }
+ else
+ {
+ status = NRF_ERROR_BUSY;
+ }
+ return status;
+}
+
+
+/* ser_phy API function */
+uint32_t ser_phy_tx_pkt_send(const uint8_t * p_buffer, uint16_t num_of_bytes)
+{
+ uint32_t status = NRF_SUCCESS;
+ uint32_t err_code;
+
+ if ( p_buffer == NULL || num_of_bytes == 0)
+ {
+ return NRF_ERROR_NULL;
+ }
+
+ if ( m_p_tx_packet == NULL)
+ {
+ m_tx_packet_length = num_of_bytes;
+ m_p_tx_packet = (uint8_t *)p_buffer;
+
+ if (m_tx_packet_length <= PKT_HDR_SIZE + PKT_CRC_SIZE)
+ {
+ ser_phy_hci_pkt_params_t pkt; // all packets smaller than 6 goes as ACK
+
+ m_flag_expect_ack = true;
+ pkt.p_buffer = (uint8_t *)m_p_tx_packet;
+ pkt.num_of_bytes = m_tx_packet_length;
+ DEBUG_EVT_SLIP_ACK_TX(0);
+ err_code = ser_phy_hci_slip_tx_pkt_send(&pkt, NULL, NULL); // this will look like ACK for slip
+ ser_phy_nohci_assert(err_code == NRF_SUCCESS);
+ }
+ else
+ {
+ ser_phy_hci_pkt_params_t header; // this is fake header - just first 4 bytes
+ ser_phy_hci_pkt_params_t crc; // this is fake header - just last 2 bytes
+ ser_phy_hci_pkt_params_t payload; // this is fake payload - all except for header and crc
+
+ m_flag_expect_ack = false;
+ header.p_buffer = (uint8_t *)m_p_tx_packet;
+ header.num_of_bytes = PKT_HDR_SIZE;
+ crc.p_buffer = (uint8_t *)m_p_tx_packet + m_tx_packet_length - PKT_CRC_SIZE;
+ crc.num_of_bytes = PKT_CRC_SIZE;
+ payload.p_buffer = (uint8_t *)m_p_tx_packet + PKT_HDR_SIZE;
+ payload.num_of_bytes = m_tx_packet_length - PKT_HDR_SIZE - PKT_CRC_SIZE;
+ DEBUG_EVT_SLIP_PACKET_TX(0);
+ err_code = ser_phy_hci_slip_tx_pkt_send(&header, &payload, &crc); // this will look like normal packet for slip
+ ser_phy_nohci_assert(err_code == NRF_SUCCESS);
+ }
+ }
+ else
+ {
+ status = NRF_ERROR_BUSY;
+ }
+
+ return status;
+}
+
+
+/* ser_phy API function */
+uint32_t ser_phy_open(ser_phy_events_handler_t events_handler)
+{
+ uint32_t err_code;
+
+ if (m_flag_nohci_init)
+ {
+ return NRF_ERROR_INVALID_STATE;
+ }
+
+ if (events_handler == NULL)
+ {
+ return NRF_ERROR_NULL;
+ }
+ err_code = ser_phy_hci_slip_open(hci_slip_event_handler);
+
+ if (err_code != NRF_SUCCESS)
+ {
+ return err_code;
+ }
+
+ m_ser_phy_callback = events_handler;
+ m_flag_nohci_init = true;
+ return NRF_SUCCESS;
+}
+
+
+/* ser_phy API function */
+void ser_phy_close(void)
+{
+ m_ser_phy_callback = NULL;
+ ser_phy_hci_slip_close();
+ m_flag_nohci_init = false;
+}
+
+
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/common/transport/ser_phy/ser_phy_spi_5W_master.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/common/transport/ser_phy/ser_phy_spi_5W_master.c
new file mode 100644
index 0000000..ade86e5
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/common/transport/ser_phy/ser_phy_spi_5W_master.c
@@ -0,0 +1,823 @@
+/**
+ * Copyright (c) 2014 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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
+ *
+ * @defgroup ser_phy_spi_5W_phy_driver_master ser_phy_nrf51_spi_5W_master.c
+ * @{
+ * @ingroup ser_phy_spi_5W_phy_driver_master
+ *
+ * @brief SPI_5W_RAW PHY master driver.
+ */
+
+#include <stdio.h>
+#include "app_util.h"
+#include "app_util_platform.h"
+#include "boards.h"
+#include "nrf_error.h"
+#include "nrf_gpio.h"
+#include "nrf_drv_gpiote.h"
+#include "ser_config.h"
+#include "ser_config_5W_app.h"
+#include "ser_phy.h"
+#include "ser_phy_config_app.h"
+#include "spi_5W_master.h"
+#include "ser_phy_debug_app.h"
+#include "app_error.h"
+#define notUSE_PendSV
+
+#ifdef USE_PendSV
+#define SW_IRQn PendSV_IRQn
+#define SW_IRQ_Handler() PendSV_Handler()
+#define SET_Pend_SW_IRQ() SCB->ICSR = SCB->ICSR | SCB_ICSR_PENDSVSET_Msk //NVIC_SetPendingIRQ(PendSV_IRQn) - PendSV_IRQn is a negative - does not work with CMSIS
+#else
+#define SW_IRQn SWI3_IRQn
+#define SW_IRQ_Handler() SWI3_IRQHandler()
+#define SET_Pend_SW_IRQ() NVIC_SetPendingIRQ(SWI3_IRQn)
+#endif
+
+#define SER_PHY_SPI_5W_MTU_SIZE SER_PHY_SPI_MTU_SIZE
+
+typedef enum
+{
+ SER_PHY_STATE_IDLE = 0,
+ SER_PHY_STATE_TX_HEADER,
+ SER_PHY_STATE_TX_WAIT_FOR_RDY,
+ SER_PHY_STATE_TX_PAYLOAD,
+ SER_PHY_STATE_RX_WAIT_FOR_RDY,
+ SER_PHY_STATE_TX_ZERO_HEADER,
+ SER_PHY_STATE_RX_HEADER,
+ SER_PHY_STATE_MEMORY_REQUEST,
+ SER_PHY_STATE_RX_PAYLOAD,
+ SER_PHY_STATE_DISABLED
+} ser_phy_spi_master_state_t;
+
+typedef enum
+{
+ SER_PHY_EVT_GPIO_RDY = 0,
+ SER_PHY_EVT_GPIO_REQ,
+ SER_PHY_EVT_SPI_TRANSFER_DONE,
+ SER_PHY_EVT_TX_API_CALL,
+ SER_PHY_EVT_RX_API_CALL
+} ser_phy_event_source_t;
+
+#define _static static
+
+_static uint8_t * mp_tx_buffer = NULL;
+_static uint16_t m_tx_buf_len = 0;
+
+_static uint8_t * mp_rx_buffer = NULL;
+_static uint16_t m_rx_buf_len = 0;
+_static uint8_t m_recv_buffer[SER_PHY_SPI_5W_MTU_SIZE];
+_static uint8_t m_len_buffer[SER_PHY_HEADER_SIZE + 1] = { 0 }; //len is asymmetric for 5W, there is a 1 byte guard when receiving
+
+_static uint16_t m_tx_packet_length = 0;
+_static uint16_t m_accumulated_tx_packet_length = 0;
+_static uint16_t m_current_tx_packet_length = 0;
+
+_static uint16_t m_rx_packet_length = 0;
+_static uint16_t m_accumulated_rx_packet_length = 0;
+_static uint16_t m_current_rx_packet_length = 0;
+
+_static volatile bool m_pend_req_flag = 0;
+_static volatile bool m_pend_rdy_flag = 0;
+_static volatile bool m_pend_xfer_flag = 0;
+_static volatile bool m_pend_rx_api_flag = 0;
+_static volatile bool m_pend_tx_api_flag = 0;
+
+_static volatile bool m_slave_ready_flag = false;
+_static volatile bool m_slave_request_flag = false;
+
+
+_static ser_phy_events_handler_t m_callback_events_handler = NULL;
+_static ser_phy_spi_master_state_t m_spi_master_state = SER_PHY_STATE_DISABLED;
+
+static void ser_phy_switch_state(ser_phy_event_source_t evt_src);
+
+static void spi_master_raw_assert(bool cond)
+{
+ APP_ERROR_CHECK_BOOL(cond);
+}
+
+void SW_IRQ_Handler()
+{
+ if (m_pend_req_flag)
+ {
+ m_pend_req_flag = false;
+ DEBUG_EVT_SPI_MASTER_RAW_REQUEST(0);
+ ser_phy_switch_state(SER_PHY_EVT_GPIO_REQ);
+ }
+
+ if (m_pend_rdy_flag)
+ {
+ m_pend_rdy_flag = false;
+ DEBUG_EVT_SPI_MASTER_RAW_READY(0);
+ ser_phy_switch_state(SER_PHY_EVT_GPIO_RDY);
+ }
+
+ if (m_pend_xfer_flag)
+ {
+ m_pend_xfer_flag = false;
+ DEBUG_EVT_SPI_MASTER_RAW_XFER_DONE(0);
+ ser_phy_switch_state(SER_PHY_EVT_SPI_TRANSFER_DONE);
+ }
+
+ if (m_pend_rx_api_flag)
+ {
+ m_pend_rx_api_flag = false;
+ DEBUG_EVT_SPI_MASTER_RAW_API_CALL(0);
+ ser_phy_switch_state(SER_PHY_EVT_RX_API_CALL);
+ }
+
+ if (m_pend_tx_api_flag)
+ {
+ m_pend_tx_api_flag = false;
+ DEBUG_EVT_SPI_MASTER_RAW_API_CALL(0);
+ ser_phy_switch_state(SER_PHY_EVT_TX_API_CALL);
+ }
+
+}
+
+#ifndef _SPI_5W_
+static void ser_phy_spi_master_ready(nrf_drv_gpiote_pin_t pin,
+ nrf_gpiote_polarity_t action)
+{
+ if (nrf_gpio_pin_read(pin) == 0)
+ {
+ m_slave_ready_flag = true;
+ m_pend_rdy_flag = true;
+ }
+ else
+ {
+ m_slave_ready_flag = false;
+ }
+
+ DEBUG_EVT_SPI_MASTER_RAW_READY_EDGE((uint32_t) !m_slave_ready_flag);
+ SET_Pend_SW_IRQ();
+}
+#endif
+
+static void ser_phy_spi_master_request(nrf_drv_gpiote_pin_t pin,
+ nrf_gpiote_polarity_t action)
+{
+ if (nrf_gpio_pin_read(pin) == 0)
+ {
+ m_slave_request_flag = true;
+ m_pend_req_flag = true;
+ }
+ else
+ {
+ m_slave_request_flag = false;
+ }
+
+ DEBUG_EVT_SPI_MASTER_RAW_REQUEST_EDGE((uint32_t) !m_slave_request_flag);
+ SET_Pend_SW_IRQ();
+}
+
+/* Send event SER_PHY_EVT_TX_PKT_SENT */
+static __INLINE void callback_packet_sent()
+{
+ ser_phy_evt_t event;
+
+ event.evt_type = SER_PHY_EVT_TX_PKT_SENT;
+ m_callback_events_handler(event);
+}
+
+/* Send event SER_PHY_EVT_RX_PKT_DROPPED */
+static __INLINE void callback_packet_dropped()
+{
+ ser_phy_evt_t event;
+
+ event.evt_type = SER_PHY_EVT_RX_PKT_DROPPED;
+ m_callback_events_handler(event);
+}
+
+/* Send event SER_PHY_EVT_RX_PKT_RECEIVED */
+static __INLINE void callback_packet_received()
+{
+ ser_phy_evt_t event;
+
+ event.evt_type = SER_PHY_EVT_RX_PKT_RECEIVED;
+ event.evt_params.rx_pkt_received.p_buffer = mp_rx_buffer;
+ event.evt_params.rx_pkt_received.num_of_bytes = m_rx_buf_len;
+ m_callback_events_handler(event);
+}
+
+/* Send event SER_PHY_EVT_RX_BUF_REQUEST */
+static __INLINE void callback_mem_request()
+{
+ ser_phy_evt_t event;
+
+ event.evt_type = SER_PHY_EVT_RX_BUF_REQUEST;
+ event.evt_params.rx_buf_request.num_of_bytes = m_rx_buf_len;
+ m_callback_events_handler(event);
+}
+
+static __INLINE void copy_buff(uint8_t * const p_dest, uint8_t const * const p_src, uint16_t len)
+{
+ uint16_t index;
+
+ for (index = 0; index < len; index++)
+ {
+ p_dest[index] = p_src[index];
+ }
+ return;
+}
+
+static __INLINE void buffer_release(uint8_t * * const pp_buffer, uint16_t * const p_buf_len)
+{
+ *pp_buffer = NULL;
+ *p_buf_len = 0;
+}
+
+static uint16_t compute_current_packet_length(const uint16_t packet_length,
+ const uint16_t accumulated_packet_length)
+{
+ uint16_t current_packet_length = packet_length - accumulated_packet_length;
+
+ if (current_packet_length > SER_PHY_SPI_5W_MTU_SIZE)
+ {
+ current_packet_length = SER_PHY_SPI_5W_MTU_SIZE;
+ }
+
+ return current_packet_length;
+}
+
+static __INLINE uint32_t header_send(const uint16_t length)
+{
+ uint16_t buf_len_size = uint16_encode(length, m_len_buffer);
+
+ return spi_master_send_recv(SER_PHY_SPI_MASTER, m_len_buffer, buf_len_size, NULL, 0);
+}
+
+static __INLINE uint32_t frame_send()
+{
+ uint32_t err_code;
+
+ m_current_tx_packet_length = compute_current_packet_length(m_tx_packet_length,
+ m_accumulated_tx_packet_length);
+ err_code =
+ spi_master_send_recv(SER_PHY_SPI_MASTER,
+ &mp_tx_buffer[m_accumulated_tx_packet_length],
+ m_current_tx_packet_length,
+ NULL,
+ 0);
+ m_accumulated_tx_packet_length += m_current_tx_packet_length;
+ return err_code;
+}
+
+static __INLINE uint32_t header_get()
+{
+ return spi_master_send_recv(SER_PHY_SPI_MASTER, NULL, 0, m_len_buffer, SER_PHY_HEADER_SIZE + 1); //add 0 byte guard when receiving
+}
+
+static __INLINE uint32_t frame_get()
+{
+ uint32_t err_code;
+
+ m_current_rx_packet_length = compute_current_packet_length(m_rx_packet_length,
+ m_accumulated_rx_packet_length);
+
+ if (m_current_rx_packet_length < SER_PHY_SPI_5W_MTU_SIZE)
+ {
+ m_current_rx_packet_length++; //take into account guard byte when receiving
+ }
+ err_code = spi_master_send_recv(SER_PHY_SPI_MASTER,
+ NULL,
+ 0,
+ m_recv_buffer,
+ m_current_rx_packet_length);
+ return err_code;
+}
+
+/**
+ * \brief Master driver main state machine
+ * Executed only in the context of PendSV_Handler()
+ * For UML graph, please refer to SDK documentation
+*/
+
+static void ser_phy_switch_state(ser_phy_event_source_t evt_src)
+{
+ uint32_t err_code = NRF_SUCCESS;
+ static bool m_waitForReadyFlag = false; //local scheduling flag to defer RDY events
+
+ switch (m_spi_master_state)
+ {
+
+ case SER_PHY_STATE_IDLE:
+
+ if (evt_src == SER_PHY_EVT_GPIO_REQ)
+ {
+ m_waitForReadyFlag = false;
+
+ if (m_slave_ready_flag)
+ {
+ m_spi_master_state = SER_PHY_STATE_TX_ZERO_HEADER;
+ err_code = header_send(0);
+ }
+ else
+ {
+ m_spi_master_state = SER_PHY_STATE_RX_WAIT_FOR_RDY;
+ }
+ }
+ else if (evt_src == SER_PHY_EVT_TX_API_CALL)
+ {
+ spi_master_raw_assert(mp_tx_buffer != NULL); //api event with tx_buffer == NULL has no sense
+ m_waitForReadyFlag = false;
+
+ if (m_slave_ready_flag)
+ {
+ m_spi_master_state = SER_PHY_STATE_TX_HEADER;
+ err_code = header_send(m_tx_buf_len);
+ }
+ else
+ {
+ m_spi_master_state = SER_PHY_STATE_TX_WAIT_FOR_RDY;
+ }
+ }
+ break;
+
+ case SER_PHY_STATE_TX_WAIT_FOR_RDY:
+
+ if (evt_src == SER_PHY_EVT_GPIO_RDY)
+ {
+ m_spi_master_state = SER_PHY_STATE_TX_HEADER;
+ err_code = header_send(m_tx_buf_len);
+ }
+ break;
+
+ case SER_PHY_STATE_RX_WAIT_FOR_RDY:
+
+ if (evt_src == SER_PHY_EVT_GPIO_RDY)
+ {
+ m_spi_master_state = SER_PHY_STATE_TX_ZERO_HEADER;
+ err_code = header_send(0);
+
+ }
+ break;
+
+ case SER_PHY_STATE_TX_HEADER:
+
+ if (evt_src == SER_PHY_EVT_SPI_TRANSFER_DONE)
+ {
+ m_tx_packet_length = m_tx_buf_len;
+ m_accumulated_tx_packet_length = 0;
+
+ if (m_slave_ready_flag)
+ {
+ m_spi_master_state = SER_PHY_STATE_TX_PAYLOAD;
+ err_code = frame_send();
+
+ }
+ else
+ {
+ m_waitForReadyFlag = true;
+ }
+ }
+ else if ((evt_src == SER_PHY_EVT_GPIO_RDY) && m_waitForReadyFlag)
+ {
+ m_waitForReadyFlag = false;
+ m_spi_master_state = SER_PHY_STATE_TX_PAYLOAD;
+ err_code = frame_send();
+ }
+
+ break;
+
+ case SER_PHY_STATE_TX_PAYLOAD:
+
+ if (evt_src == SER_PHY_EVT_SPI_TRANSFER_DONE)
+ {
+ if (m_accumulated_tx_packet_length < m_tx_packet_length)
+ {
+ if (m_slave_ready_flag)
+ {
+ err_code = frame_send();
+ }
+ else
+ {
+ m_waitForReadyFlag = true;
+ }
+ }
+ else
+ {
+ spi_master_raw_assert(m_accumulated_tx_packet_length == m_tx_packet_length);
+ //Release TX buffer
+ buffer_release(&mp_tx_buffer, &m_tx_buf_len);
+ callback_packet_sent();
+
+ if ( m_slave_request_flag)
+ {
+ if (m_slave_ready_flag)
+ {
+ m_spi_master_state = SER_PHY_STATE_TX_ZERO_HEADER;
+ err_code = header_send(0);
+ }
+ else
+ {
+ m_spi_master_state = SER_PHY_STATE_RX_WAIT_FOR_RDY;
+ }
+ }
+ else
+ {
+ m_spi_master_state = SER_PHY_STATE_IDLE; //m_Tx_buffer is NULL - have to wait for API event
+ }
+ }
+ }
+ else if ((evt_src == SER_PHY_EVT_GPIO_RDY) && m_waitForReadyFlag )
+ {
+ m_waitForReadyFlag = false;
+ err_code = frame_send();
+ }
+
+ break;
+
+ case SER_PHY_STATE_TX_ZERO_HEADER:
+
+ if (evt_src == SER_PHY_EVT_SPI_TRANSFER_DONE)
+ {
+ if (m_slave_ready_flag)
+ {
+ m_spi_master_state = SER_PHY_STATE_RX_HEADER;
+ err_code = header_get();
+ }
+ else
+ {
+ m_waitForReadyFlag = true;
+ }
+ }
+ else if ( (evt_src == SER_PHY_EVT_GPIO_RDY) && m_waitForReadyFlag)
+ {
+ m_waitForReadyFlag = false;
+ m_spi_master_state = SER_PHY_STATE_RX_HEADER;
+ err_code = header_get();
+ }
+ break;
+
+ case SER_PHY_STATE_RX_HEADER:
+
+ if (evt_src == SER_PHY_EVT_SPI_TRANSFER_DONE)
+ {
+ m_spi_master_state = SER_PHY_STATE_MEMORY_REQUEST;
+ m_rx_buf_len = uint16_decode(&(m_len_buffer[1])); //skip guard when receiving
+ m_rx_packet_length = m_rx_buf_len;
+ callback_mem_request();
+ }
+ break;
+
+ case SER_PHY_STATE_MEMORY_REQUEST:
+
+ if (evt_src == SER_PHY_EVT_RX_API_CALL)
+ {
+ m_accumulated_rx_packet_length = 0;
+
+ if (m_slave_ready_flag)
+ {
+ m_spi_master_state = SER_PHY_STATE_RX_PAYLOAD;
+ err_code = frame_get();
+ }
+ else
+ {
+ m_waitForReadyFlag = true;
+ }
+ }
+ else if ((evt_src == SER_PHY_EVT_GPIO_RDY) && m_waitForReadyFlag)
+ {
+ m_waitForReadyFlag = false;
+ m_spi_master_state = SER_PHY_STATE_RX_PAYLOAD;
+ err_code = frame_get();
+ }
+ break;
+
+ case SER_PHY_STATE_RX_PAYLOAD:
+
+ if (evt_src == SER_PHY_EVT_SPI_TRANSFER_DONE)
+ {
+ if (mp_rx_buffer)
+ {
+ copy_buff(&(mp_rx_buffer[m_accumulated_rx_packet_length]),
+ &(m_recv_buffer[1]),
+ m_current_rx_packet_length - 1); //skip guard byte when receiving
+ }
+ m_accumulated_rx_packet_length += (m_current_rx_packet_length - 1);
+
+ if (m_accumulated_rx_packet_length < m_rx_packet_length)
+ {
+ if (m_slave_ready_flag)
+ {
+ err_code = frame_get();
+ }
+ else
+ {
+ m_waitForReadyFlag = true;
+ }
+ }
+ else
+ {
+ spi_master_raw_assert(m_accumulated_rx_packet_length == m_rx_packet_length);
+
+ if (mp_rx_buffer == NULL)
+ {
+ callback_packet_dropped();
+ }
+ else
+ {
+ callback_packet_received();
+ }
+ //Release RX buffer
+ buffer_release(&mp_rx_buffer, &m_rx_buf_len);
+
+ if ((mp_tx_buffer != NULL)) //mp_tx_buffer !=NULL, this means that API_EVT was scheduled
+ {
+ if (m_slave_ready_flag )
+ {
+ err_code = header_send(m_tx_buf_len);
+ m_spi_master_state = SER_PHY_STATE_TX_HEADER;
+ }
+ else
+ {
+ m_spi_master_state = SER_PHY_STATE_TX_WAIT_FOR_RDY;
+ }
+ }
+ else if (m_slave_request_flag)
+ {
+ if (m_slave_ready_flag)
+ {
+ m_spi_master_state = SER_PHY_STATE_TX_ZERO_HEADER;
+ err_code = header_send(0);
+ }
+ else
+ {
+ m_spi_master_state = SER_PHY_STATE_RX_WAIT_FOR_RDY;
+ }
+ }
+ else
+ {
+ m_spi_master_state = SER_PHY_STATE_IDLE;
+ }
+ }
+ }
+ else if ( evt_src == SER_PHY_EVT_GPIO_RDY && m_waitForReadyFlag)
+ {
+ m_waitForReadyFlag = false;
+ err_code = frame_get();
+ }
+
+
+ break;
+
+ default:
+ break;
+ }
+
+
+ if (err_code != NRF_SUCCESS)
+ {
+ (void)err_code;
+ }
+}
+
+/* SPI master event handler */
+static void ser_phy_spi_master_event_handler(spi_master_evt_t spi_master_evt)
+{
+ switch (spi_master_evt.type)
+ {
+ case SPI_MASTER_EVT_TRANSFER_COMPLETED:
+
+ /* Switch state */
+ m_pend_xfer_flag = true;
+ SET_Pend_SW_IRQ();
+
+ break;
+
+ default:
+ break;
+ }
+}
+
+static void ser_phy_init_pendSV(void)
+{
+ NVIC_SetPriority(SW_IRQn, APP_IRQ_PRIORITY_MID);
+ NVIC_EnableIRQ(SW_IRQn);
+}
+
+static void ser_phy_init_gpiote(void)
+{
+ if (!nrf_drv_gpiote_is_init())
+ {
+ (void)nrf_drv_gpiote_init();
+ }
+ NVIC_SetPriority(GPIOTE_IRQn, APP_IRQ_PRIORITY_HIGH);
+
+ nrf_drv_gpiote_in_config_t config = GPIOTE_CONFIG_IN_SENSE_TOGGLE(true);
+ /* Enable pullup to ensure high state while connectivity device is reset */
+ config.pull = NRF_GPIO_PIN_PULLUP;
+ (void)nrf_drv_gpiote_in_init(SER_PHY_SPI_MASTER_PIN_SLAVE_REQUEST, &config,
+ ser_phy_spi_master_request);
+ nrf_drv_gpiote_in_event_enable(SER_PHY_SPI_MASTER_PIN_SLAVE_REQUEST,true);
+ m_slave_request_flag = !(nrf_gpio_pin_read(SER_PHY_SPI_MASTER_PIN_SLAVE_REQUEST));
+
+#ifdef _SPI_5W_
+ m_slave_ready_flag = true;
+#else
+ (void)nrf_drv_gpiote_in_init(SER_PHY_SPI_MASTER_PIN_SLAVE_READY, &config,
+ ser_phy_spi_master_ready);
+ nrf_drv_gpiote_in_event_enable(SER_PHY_SPI_MASTER_PIN_SLAVE_READY,true);
+ m_slave_ready_flag = !(nrf_gpio_pin_read(SER_PHY_SPI_MASTER_PIN_SLAVE_READY));
+#endif
+
+ NVIC_ClearPendingIRQ(SW_IRQn);
+}
+
+static void ser_phy_deinit_gpiote(void)
+{
+ nrf_drv_gpiote_in_uninit(SER_PHY_SPI_MASTER_PIN_SLAVE_REQUEST);
+#ifndef _SPI_5W_
+ nrf_drv_gpiote_in_uninit(SER_PHY_SPI_MASTER_PIN_SLAVE_READY);
+#endif
+}
+
+/* ser_phy API function */
+uint32_t ser_phy_tx_pkt_send(const uint8_t * p_buffer, uint16_t num_of_bytes)
+{
+ if (p_buffer == NULL)
+ {
+ return NRF_ERROR_NULL;
+ }
+
+ if (num_of_bytes == 0)
+ {
+ return NRF_ERROR_INVALID_PARAM;
+ }
+
+ if (mp_tx_buffer != NULL)
+ {
+ return NRF_ERROR_BUSY;
+ }
+
+ //ser_phy_interrupts_disable();
+ CRITICAL_REGION_ENTER();
+ mp_tx_buffer = (uint8_t *)p_buffer;
+ m_tx_buf_len = num_of_bytes;
+ m_pend_tx_api_flag = true;
+ SET_Pend_SW_IRQ();
+ //ser_phy_interrupts_enable();
+ CRITICAL_REGION_EXIT();
+
+ return NRF_SUCCESS;
+}
+
+/* ser_phy API function */
+uint32_t ser_phy_rx_buf_set(uint8_t * p_buffer)
+{
+ if (m_spi_master_state != SER_PHY_STATE_MEMORY_REQUEST)
+ {
+ return NRF_ERROR_INVALID_STATE;
+ }
+
+ //ser_phy_interrupts_disable();
+ CRITICAL_REGION_ENTER();
+ mp_rx_buffer = p_buffer;
+ m_pend_rx_api_flag = true;
+ SET_Pend_SW_IRQ();
+ //ser_phy_interrupts_enable();
+ CRITICAL_REGION_EXIT();
+
+ return NRF_SUCCESS;
+}
+
+/* ser_phy API function */
+uint32_t ser_phy_open(ser_phy_events_handler_t events_handler)
+{
+
+ if (m_spi_master_state != SER_PHY_STATE_DISABLED)
+ {
+ return NRF_ERROR_INVALID_STATE;
+ }
+
+ if (events_handler == NULL)
+ {
+ return NRF_ERROR_NULL;
+ }
+
+ uint32_t err_code = NRF_SUCCESS;
+ m_spi_master_state = SER_PHY_STATE_IDLE;
+ m_callback_events_handler = events_handler;
+ ser_phy_init_gpiote();
+
+ /* Configure SPI Master driver */
+ spi_master_config_t spi_master_config;
+ spi_master_config.SPI_Freq = SPI_FREQUENCY_FREQUENCY_M1;
+ spi_master_config.SPI_Pin_SCK = SER_PHY_SPI_MASTER_PIN_SCK;
+ spi_master_config.SPI_Pin_MISO = SER_PHY_SPI_MASTER_PIN_MISO;
+ spi_master_config.SPI_Pin_MOSI = SER_PHY_SPI_MASTER_PIN_MOSI;
+ spi_master_config.SPI_Pin_SS = SER_PHY_SPI_MASTER_PIN_SLAVE_SELECT;
+ spi_master_config.SPI_ORDER = SPI_CONFIG_ORDER_LsbFirst;
+ spi_master_config.SPI_CPOL = SPI_CONFIG_CPOL_ActiveHigh;
+ spi_master_config.SPI_CPHA = SPI_CONFIG_CPHA_Leading;
+
+ err_code = spi_master_open(SER_PHY_SPI_MASTER, &spi_master_config);
+
+ if (err_code != NRF_SUCCESS)
+ {
+ return err_code;
+ }
+#ifdef _SPI_5W_
+ spi_5W_master_evt_handler_reg(SER_PHY_SPI_MASTER, ser_phy_spi_master_event_handler);
+#else
+ spi_master_evt_handler_reg(SER_PHY_SPI_MASTER, ser_phy_spi_master_event_handler);
+#endif
+ ser_phy_init_pendSV();
+
+ return err_code;
+}
+
+/* ser_phy API function */
+void ser_phy_close(void)
+{
+ m_spi_master_state = SER_PHY_STATE_DISABLED;
+
+ m_callback_events_handler = NULL;
+
+ buffer_release(&mp_tx_buffer, &m_tx_buf_len);
+ buffer_release(&mp_rx_buffer, &m_rx_buf_len);
+ m_tx_packet_length = 0;
+ m_accumulated_tx_packet_length = 0;
+ m_current_tx_packet_length = 0;
+ m_rx_packet_length = 0;
+ m_accumulated_rx_packet_length = 0;
+ m_current_rx_packet_length = 0;
+ ser_phy_deinit_gpiote();
+ spi_master_close(SER_PHY_SPI_MASTER);
+}
+
+/* ser_phy API function */
+void ser_phy_interrupts_enable(void)
+{
+ NVIC_EnableIRQ(SW_IRQn);
+}
+
+/* ser_phy API function */
+void ser_phy_interrupts_disable(void)
+{
+ NVIC_DisableIRQ(SW_IRQn);
+}
+
+
+#ifdef SER_PHY_DEBUG_APP_ENABLE
+
+static spi_master_raw_callback_t m_spi_master_raw_evt_callback;
+
+void debug_evt(spi_master_raw_evt_type_t evt, uint32_t data)
+{
+ if (m_spi_master_raw_evt_callback)
+ {
+ spi_master_raw_evt_t e;
+ e.evt = evt;
+ e.data = data;
+ m_spi_master_raw_evt_callback(e);
+ }
+}
+
+void debug_init(spi_master_raw_callback_t spi_master_raw_evt_callback)
+{
+ m_spi_master_raw_evt_callback = spi_master_raw_evt_callback;
+}
+
+#endif
+/** @} */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/common/transport/ser_phy/ser_phy_spi_5W_slave.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/common/transport/ser_phy/ser_phy_spi_5W_slave.c
new file mode 100644
index 0000000..88588b4
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/common/transport/ser_phy/ser_phy_spi_5W_slave.c
@@ -0,0 +1,644 @@
+/**
+ * Copyright (c) 2014 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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
+ *
+ * @defgroup ser_phy_spi_5W_phy_driver_slave ser_phy_nrf51_spi_5W_slave.c
+ * @{
+ * @ingroup ser_phy_spi_5W_phy_driver_slave
+ *
+ * @brief SPI_5W_RAW PHY slave driver.
+ */
+
+
+#include <stddef.h>
+#include <string.h>
+
+
+#include "boards.h"
+#include "nrf_drv_spis.h"
+#include "ser_phy.h"
+#include "ser_config.h"
+#include "nrf_gpio.h"
+#include "nrf_gpiote.h"
+#include "nrf_soc.h"
+#include "app_error.h"
+#include "app_util.h"
+#include "ser_phy_config_conn.h"
+#include "ser_phy_debug_conn.h"
+#include "app_error.h"
+
+#define _static static
+
+#define SER_PHY_SPI_5W_MTU_SIZE SER_PHY_SPI_MTU_SIZE
+
+#define SER_PHY_SPI_DEF_CHARACTER 0xFF //SPI default character. Character clocked out in case of an ignored transaction
+#define SER_PHY_SPI_ORC_CHARACTER 0xFF //SPI over-read character. Character clocked out after an over-read of the transmit buffer
+
+static nrf_drv_spis_t m_spis = NRF_DRV_SPIS_INSTANCE(SER_PHY_SPI_SLAVE_INSTANCE);
+
+#define _SPI_5W_
+
+//SPI raw peripheral device configuration data
+typedef struct
+{
+ int32_t pin_req; //SPI /REQ pin. -1 for not using
+ int32_t pin_rdy; //SPI /RDY pin. -1 for not using
+ int32_t ppi_rdy_ch; //SPI /RDY ppi ready channel
+ int32_t gpiote_rdy_ch; //SPI /RDY pin ready channel
+} spi_slave_raw_trasp_cfg_t;
+
+/**@brief States of the SPI transaction state machine. */
+typedef enum
+{
+ SPI_RAW_STATE_UNKNOWN,
+ SPI_RAW_STATE_SETUP_HEADER,
+ SPI_RAW_STATE_RX_HEADER,
+ SPI_RAW_STATE_MEM_REQUESTED,
+ SPI_RAW_STATE_RX_PAYLOAD,
+ SPI_RAW_STATE_TX_HEADER,
+ SPI_RAW_STATE_TX_PAYLOAD,
+} trans_state_t;
+
+_static spi_slave_raw_trasp_cfg_t m_spi_slave_raw_config;
+
+_static uint16_t m_accumulated_rx_packet_length;
+_static uint16_t m_rx_packet_length;
+_static uint16_t m_current_rx_frame_length;
+
+_static uint16_t m_accumulated_tx_packet_length;
+_static uint16_t m_tx_packet_length;
+_static uint16_t m_current_tx_frame_length;
+
+_static uint8_t m_header_rx_buffer[SER_PHY_HEADER_SIZE + 1]; // + 1 for '0' guard in SPI_5W
+_static uint8_t m_header_tx_buffer[SER_PHY_HEADER_SIZE + 1]; // + 1 for '0' guard in SPI_5W
+
+_static uint8_t m_tx_frame_buffer[SER_PHY_SPI_5W_MTU_SIZE];
+_static uint8_t m_rx_frame_buffer[SER_PHY_SPI_5W_MTU_SIZE];
+_static uint8_t m_zero_buff[SER_PHY_SPI_5W_MTU_SIZE] = { 0 }; //ROM'able declaration - all guard bytes
+
+_static uint8_t * volatile m_p_rx_buffer = NULL;
+_static const uint8_t * volatile m_p_tx_buffer = NULL;
+
+_static bool m_trash_payload_flag;
+_static bool m_buffer_reqested_flag;
+
+_static trans_state_t m_trans_state = SPI_RAW_STATE_UNKNOWN;
+_static ser_phy_events_handler_t m_ser_phy_callback = NULL;
+
+static void spi_slave_raw_assert(bool cond)
+{
+ APP_ERROR_CHECK_BOOL(cond);
+}
+
+static void callback_ser_phy_event(ser_phy_evt_t event)
+{
+ if (m_ser_phy_callback)
+ {
+ m_ser_phy_callback(event);
+ }
+ return;
+}
+
+static void callback_memory_request(uint16_t size)
+{
+ ser_phy_evt_t event;
+
+ event.evt_type = SER_PHY_EVT_RX_BUF_REQUEST;
+ event.evt_params.rx_buf_request.num_of_bytes = size;
+ callback_ser_phy_event(event);
+ return;
+
+}
+
+static void callback_packet_received(uint8_t * pBuffer, uint16_t size)
+{
+ ser_phy_evt_t event;
+
+ event.evt_type = SER_PHY_EVT_RX_PKT_RECEIVED;
+ event.evt_params.rx_pkt_received.num_of_bytes = size;
+ event.evt_params.rx_pkt_received.p_buffer = pBuffer;
+ callback_ser_phy_event(event);
+ return;
+}
+
+static void callback_packet_dropped()
+{
+ ser_phy_evt_t event;
+
+ event.evt_type = SER_PHY_EVT_RX_PKT_DROPPED;
+ callback_ser_phy_event(event);
+ return;
+}
+
+static void callback_packet_transmitted(void)
+{
+ ser_phy_evt_t event;
+
+ event.evt_type = SER_PHY_EVT_TX_PKT_SENT;
+ callback_ser_phy_event(event);
+ return;
+}
+
+static void copy_buff(uint8_t * const p_dest, uint8_t const * const p_src, uint16_t len)
+{
+ uint16_t index;
+
+ for (index = 0; index < len; index++)
+ {
+ p_dest[index] = p_src[index];
+ }
+ return;
+}
+
+/* Function computes current packet length */
+static uint16_t compute_current_frame_length(const uint16_t packet_length,
+ const uint16_t accumulated_packet_length)
+{
+ uint16_t current_packet_length = packet_length - accumulated_packet_length;
+
+ if (current_packet_length > SER_PHY_SPI_5W_MTU_SIZE)
+ {
+ current_packet_length = SER_PHY_SPI_5W_MTU_SIZE;
+ }
+
+ return current_packet_length;
+}
+
+static uint32_t header_get()
+{
+ uint32_t err_code;
+
+ err_code = nrf_drv_spis_buffers_set(&m_spis,
+ (uint8_t *) m_zero_buff,
+ SER_PHY_HEADER_SIZE,
+ m_header_rx_buffer,
+ SER_PHY_HEADER_SIZE);
+ return err_code;
+}
+
+static uint32_t frame_get()
+{
+ uint32_t err_code;
+
+ m_current_rx_frame_length = compute_current_frame_length(m_rx_packet_length,
+ m_accumulated_rx_packet_length);
+
+ if (!m_trash_payload_flag)
+ {
+ err_code =
+ nrf_drv_spis_buffers_set(&m_spis,
+ (uint8_t *) m_zero_buff,
+ m_current_rx_frame_length,
+ &(m_p_rx_buffer[m_accumulated_rx_packet_length]),
+ m_current_rx_frame_length);
+ }
+ else
+ {
+ err_code = nrf_drv_spis_buffers_set(&m_spis,
+ (uint8_t *) m_zero_buff,
+ m_current_rx_frame_length,
+ m_rx_frame_buffer,
+ m_current_rx_frame_length);
+ }
+ return err_code;
+}
+
+static uint32_t header_send(uint16_t len)
+{
+ uint32_t err_code;
+
+ m_header_tx_buffer[0] = (uint8_t) 0; //this is guard byte
+ (void)uint16_encode(len, &(m_header_tx_buffer[1]));
+ err_code = nrf_drv_spis_buffers_set(&m_spis,
+ m_header_tx_buffer,
+ SER_PHY_HEADER_SIZE + 1,
+ m_header_rx_buffer,
+ SER_PHY_HEADER_SIZE + 1);
+ return err_code;
+}
+
+static uint32_t frame_send()
+{
+ uint32_t err_code;
+
+ m_current_tx_frame_length = compute_current_frame_length(m_tx_packet_length,
+ m_accumulated_tx_packet_length);
+
+ if (m_current_tx_frame_length == SER_PHY_SPI_5W_MTU_SIZE)
+ {
+ m_current_tx_frame_length -= 1; //extra space for guard byte must be taken into account for MTU
+ }
+ m_tx_frame_buffer[0] = 0; //guard byte
+ copy_buff(&(m_tx_frame_buffer[1]),
+ &(m_p_tx_buffer[m_accumulated_tx_packet_length]),
+ m_current_tx_frame_length);
+ err_code = nrf_drv_spis_buffers_set(&m_spis,
+ m_tx_frame_buffer,
+ m_current_tx_frame_length + 1,
+ m_rx_frame_buffer,
+ m_current_tx_frame_length + 1);
+
+ return err_code;
+}
+
+static void set_ready_line(void)
+{
+#ifndef _SPI_5W_
+ //toggle - this should go high - but toggle is unsafe
+ uint32_t rdy_task = nrf_drv_gpiote_out_task_addr_get(m_spi_slave_raw_config.gpiote_rdy_ch);
+ *(uint32_t *)rdy_task = 1;
+#endif
+ return;
+}
+
+static void set_request_line(void)
+{
+ //active low logic - set is 0
+ nrf_gpio_pin_clear(m_spi_slave_raw_config.pin_req);
+ DEBUG_EVT_SPI_SLAVE_RAW_REQ_SET(0);
+ return;
+}
+
+static void clear_request_line(void)
+{
+ //active low logic - clear is 1
+ nrf_gpio_pin_set(m_spi_slave_raw_config.pin_req);
+ DEBUG_EVT_SPI_SLAVE_RAW_REQ_CLEARED(0);
+ return;
+}
+
+/**
+ * \brief Slave driver main state machine
+ * For UML graph, please refer to SDK documentation
+*/
+static void spi_slave_event_handle(nrf_drv_spis_event_t event)
+{
+ static uint32_t err_code = NRF_SUCCESS;
+ static uint16_t packetLength;
+
+ switch (m_trans_state)
+ {
+ case SPI_RAW_STATE_SETUP_HEADER:
+ m_trans_state = SPI_RAW_STATE_RX_HEADER;
+ err_code = header_get();
+ break;
+
+ case SPI_RAW_STATE_RX_HEADER:
+
+ if (event.evt_type == NRF_DRV_SPIS_BUFFERS_SET_DONE)
+ {
+ DEBUG_EVT_SPI_SLAVE_RAW_BUFFERS_SET(0);
+ set_ready_line();
+ }
+
+ if (event.evt_type == NRF_DRV_SPIS_XFER_DONE)
+ {
+ DEBUG_EVT_SPI_SLAVE_RAW_RX_XFER_DONE(event.rx_amount);
+ spi_slave_raw_assert(event.rx_amount == SER_PHY_HEADER_SIZE);
+ packetLength = uint16_decode(m_header_rx_buffer);
+
+ if (packetLength != 0 )
+ {
+ m_trans_state = SPI_RAW_STATE_MEM_REQUESTED;
+ m_buffer_reqested_flag = true;
+ m_rx_packet_length = packetLength;
+ callback_memory_request(packetLength);
+ }
+ else
+ {
+ if (m_p_tx_buffer)
+ {
+ clear_request_line();
+ m_trans_state = SPI_RAW_STATE_TX_HEADER;
+ err_code = header_send(m_tx_packet_length);
+ }
+ else
+ {
+ //there is nothing to send - zero response facilitates pooling - but perhaps, it should be assert
+ err_code = header_send(0);
+ }
+ }
+ }
+
+ break;
+
+ case SPI_RAW_STATE_MEM_REQUESTED:
+
+ if (event.evt_type == NRF_DRV_SPIS_EVT_TYPE_MAX) //This is API dummy event
+ {
+ m_buffer_reqested_flag = false;
+ m_trans_state = SPI_RAW_STATE_RX_PAYLOAD;
+ m_accumulated_rx_packet_length = 0;
+ err_code = frame_get();
+ }
+ break;
+
+
+ case SPI_RAW_STATE_RX_PAYLOAD:
+
+ if (event.evt_type == NRF_DRV_SPIS_BUFFERS_SET_DONE)
+ {
+ DEBUG_EVT_SPI_SLAVE_RAW_BUFFERS_SET(0);
+ set_ready_line();
+ }
+
+ if (event.evt_type == NRF_DRV_SPIS_XFER_DONE)
+ {
+ DEBUG_EVT_SPI_SLAVE_RAW_RX_XFER_DONE(event.rx_amount);
+ spi_slave_raw_assert(event.rx_amount == m_current_rx_frame_length);
+ m_accumulated_rx_packet_length += m_current_rx_frame_length;
+
+ if (m_accumulated_rx_packet_length < m_rx_packet_length )
+ {
+ err_code = frame_get();
+ }
+ else
+ {
+ spi_slave_raw_assert(m_accumulated_rx_packet_length == m_rx_packet_length);
+ m_trans_state = SPI_RAW_STATE_RX_HEADER;
+ err_code = header_get();
+
+ if (!m_trash_payload_flag)
+ {
+ callback_packet_received(m_p_rx_buffer, m_accumulated_rx_packet_length);
+ }
+ else
+ {
+ callback_packet_dropped();
+ }
+ }
+ }
+ break;
+
+ case SPI_RAW_STATE_TX_HEADER:
+
+ if (event.evt_type == NRF_DRV_SPIS_BUFFERS_SET_DONE)
+ {
+ DEBUG_EVT_SPI_SLAVE_RAW_BUFFERS_SET(0);
+ set_ready_line();
+ }
+
+ if (event.evt_type == NRF_DRV_SPIS_XFER_DONE)
+ {
+ DEBUG_EVT_SPI_SLAVE_RAW_TX_XFER_DONE(event.tx_amount);
+ spi_slave_raw_assert(event.tx_amount == SER_PHY_HEADER_SIZE + 1);
+ m_trans_state = SPI_RAW_STATE_TX_PAYLOAD;
+ m_accumulated_tx_packet_length = 0;
+ err_code = frame_send();
+ }
+
+ break;
+
+ case SPI_RAW_STATE_TX_PAYLOAD:
+
+ if (event.evt_type == NRF_DRV_SPIS_BUFFERS_SET_DONE)
+ {
+ DEBUG_EVT_SPI_SLAVE_RAW_BUFFERS_SET(0);
+ set_ready_line();
+ }
+
+ if (event.evt_type == NRF_DRV_SPIS_XFER_DONE)
+ {
+ DEBUG_EVT_SPI_SLAVE_RAW_TX_XFER_DONE(event.tx_amount);
+ spi_slave_raw_assert(event.tx_amount == m_current_tx_frame_length + 1);
+ m_accumulated_tx_packet_length += m_current_tx_frame_length;
+
+ if ( m_accumulated_tx_packet_length < m_tx_packet_length )
+ {
+ err_code = frame_send();
+ }
+ else
+ {
+ spi_slave_raw_assert(m_accumulated_tx_packet_length == m_tx_packet_length);
+ //clear pointer before callback
+ m_p_tx_buffer = NULL;
+ callback_packet_transmitted();
+ //spi slave TX transfer is possible only when RX is ready, so return to waiting for a header
+ m_trans_state = SPI_RAW_STATE_RX_HEADER;
+ err_code = header_get();
+ }
+ }
+ break;
+
+ default:
+ err_code = NRF_ERROR_INVALID_STATE;
+ break;
+ }
+ APP_ERROR_CHECK(err_code);
+}
+
+#ifndef _SPI_5W_
+static void spi_slave_gpiote_init(void)
+{
+ if (!nrf_drv_gpiote_is_init())
+ {
+ (void)nrf_drv_gpiote_init();
+ }
+ nrf_drv_gpiote_out_config_t config = GPIOTE_CONFIG_OUT_TASK_TOGGLE(true);
+ (void)nrf_drv_gpiote_out_init(m_spi_slave_raw_config.gpiote_rdy_ch, &config);
+ return;
+}
+
+static void spi_slave_ppi_init(void)
+{
+ uint32_t rdy_task = nrf_drv_gpiote_out_task_addr_get(m_spi_slave_raw_config.gpiote_rdy_ch);
+ //Configure PPI channel to clear /RDY line
+ NRF_PPI->CH[m_spi_slave_raw_config.ppi_rdy_ch].EEP = (uint32_t)(&NRF_SPIS1->EVENTS_END);
+ NRF_PPI->CH[m_spi_slave_raw_config.ppi_rdy_ch].TEP = rdy_task;
+
+ //this works only for channels 0..15 - but soft device is using 8-15 anyway
+ NRF_PPI->CHEN |= (1 << m_spi_slave_raw_config.ppi_rdy_ch);
+ return;
+}
+#endif
+
+static void spi_slave_gpio_init(void)
+{
+ nrf_gpio_pin_set(m_spi_slave_raw_config.pin_req);
+ nrf_gpio_cfg_output(m_spi_slave_raw_config.pin_req);
+#ifndef _SPI_5W_
+ nrf_gpio_pin_set(m_spi_slave_raw_config.pin_rdy);
+ nrf_gpio_cfg_output(m_spi_slave_raw_config.pin_rdy);
+#endif
+ return;
+}
+
+/* ser_phy API function */
+void ser_phy_interrupts_enable(void)
+{
+ NVIC_EnableIRQ(nrfx_get_irq_number(m_spis.p_reg));
+}
+
+/* ser_phy API function */
+void ser_phy_interrupts_disable(void)
+{
+ NVIC_DisableIRQ(nrfx_get_irq_number(m_spis.p_reg));
+}
+
+/* ser_phy API function */
+uint32_t ser_phy_rx_buf_set(uint8_t * p_buffer)
+{
+ uint32_t status = NRF_SUCCESS;
+ nrf_drv_spis_event_t event;
+
+ ser_phy_interrupts_disable();
+
+ if (m_buffer_reqested_flag && (m_trans_state == SPI_RAW_STATE_MEM_REQUESTED))
+ {
+ m_p_rx_buffer = p_buffer;
+
+ if (m_p_rx_buffer)
+ {
+ m_trash_payload_flag = false;
+ }
+ else
+ {
+ m_trash_payload_flag = true;
+ }
+
+ event.evt_type = NRF_DRV_SPIS_EVT_TYPE_MAX; //force transition with dummy event
+ event.rx_amount = 0;
+ event.tx_amount = 0;
+ spi_slave_event_handle(event);
+ }
+ else
+ {
+ status = NRF_ERROR_BUSY;
+ }
+ ser_phy_interrupts_enable();
+
+ return status;
+}
+
+/* ser_phy API function */
+uint32_t ser_phy_tx_pkt_send(const uint8_t * p_buffer, uint16_t num_of_bytes)
+{
+ uint32_t status = NRF_SUCCESS;
+
+ if ( p_buffer == NULL || num_of_bytes == 0)
+ {
+ return NRF_ERROR_NULL;
+ }
+
+ ser_phy_interrupts_disable();
+
+ if ( m_p_tx_buffer == NULL)
+ {
+ m_tx_packet_length = num_of_bytes;
+ m_p_tx_buffer = p_buffer;
+ set_request_line();
+ }
+ else
+ {
+ status = NRF_ERROR_BUSY;
+ }
+ ser_phy_interrupts_enable();
+
+ return status;
+}
+
+/* ser_phy API function */
+uint32_t ser_phy_open(ser_phy_events_handler_t events_handler)
+{
+ uint32_t err_code;
+ nrf_drv_spis_config_t spi_slave_config;
+ nrf_drv_spis_event_t event;
+
+ if (m_trans_state != SPI_RAW_STATE_UNKNOWN)
+ {
+ return NRF_ERROR_INVALID_STATE;
+ }
+
+ if (events_handler == NULL)
+ {
+ return NRF_ERROR_NULL;
+ }
+
+ //one ppi channel and one gpiote channel are used to drive RDY line
+ m_spi_slave_raw_config.pin_req = SER_PHY_SPI_SLAVE_REQ_PIN;
+ m_spi_slave_raw_config.pin_rdy = SER_PHY_SPI_SLAVE_RDY_PIN;
+ m_spi_slave_raw_config.ppi_rdy_ch = SER_PHY_SPI_PPI_RDY_CH;
+ m_spi_slave_raw_config.gpiote_rdy_ch = SER_PHY_SPI_GPIOTE_RDY_CH;
+
+ spi_slave_gpio_init();
+#ifndef _SPI_5W_
+ spi_slave_gpiote_init();
+ spi_slave_ppi_init();
+#endif
+
+ spi_slave_config.miso_pin = SER_CON_SPIS_MISO_PIN;
+ spi_slave_config.mosi_pin = SER_CON_SPIS_MOSI_PIN;
+ spi_slave_config.sck_pin = SER_CON_SPIS_SCK_PIN;
+ spi_slave_config.csn_pin = SER_CON_SPIS_CSN_PIN;
+ spi_slave_config.mode = NRF_DRV_SPIS_MODE_0;
+ spi_slave_config.bit_order = NRF_DRV_SPIS_BIT_ORDER_LSB_FIRST;
+ spi_slave_config.def = SER_PHY_SPI_DEF_CHARACTER;
+ spi_slave_config.orc = SER_PHY_SPI_ORC_CHARACTER;
+ spi_slave_config.csn_pullup = NRF_GPIO_PIN_PULLUP;
+ spi_slave_config.irq_priority = APP_IRQ_PRIORITY_LOWEST;
+
+ //keep /CS high when init
+ nrf_gpio_cfg_input(spi_slave_config.csn_pin, NRF_GPIO_PIN_PULLUP);
+
+ err_code = nrf_drv_spis_init(&m_spis, &spi_slave_config, spi_slave_event_handle);
+ APP_ERROR_CHECK(err_code);
+
+ if (err_code == NRF_SUCCESS)
+ {
+ m_ser_phy_callback = events_handler;
+
+ m_trans_state = SPI_RAW_STATE_SETUP_HEADER;
+ event.evt_type = NRF_DRV_SPIS_EVT_TYPE_MAX; //force transition for dummy event
+ event.rx_amount = 0;
+ event.tx_amount = 0;
+ spi_slave_event_handle(event);
+
+ }
+
+ return err_code;
+}
+
+/* ser_phy API function */
+void ser_phy_close(void)
+{
+ nrf_drv_spis_uninit(&m_spis);
+ m_ser_phy_callback = NULL;
+ m_trans_state = SPI_RAW_STATE_UNKNOWN;
+}
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/common/transport/ser_phy/ser_phy_spi_master.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/common/transport/ser_phy/ser_phy_spi_master.c
new file mode 100644
index 0000000..6065446
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/common/transport/ser_phy/ser_phy_spi_master.c
@@ -0,0 +1,804 @@
+/**
+ * Copyright (c) 2014 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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
+ *
+ * @defgroup ser_phy_spi_phy_driver_master ser_phy_nrf51_spi_master.c
+ * @{
+ * @ingroup ser_phy_spi_phy_driver_master
+ *
+ * @brief SPI_RAW PHY master driver.
+ */
+
+#include <stdio.h>
+#include "nrf_drv_gpiote.h"
+#include "nrf_drv_spi.h"
+#include "ser_phy.h"
+#include "ser_config.h"
+#include "app_util.h"
+#include "app_util_platform.h"
+#include "app_error.h"
+#include "nrf_error.h"
+#include "nrf_gpio.h"
+#include "nrf_gpiote.h"
+#include "boards.h"
+#include "app_error.h"
+#include "ser_phy_config_app.h"
+#include "ser_phy_debug_app.h"
+
+#define notUSE_PendSV
+
+#ifdef USE_PendSV
+
+#define SW_IRQn PendSV_IRQn
+#define SW_IRQ_Handler() PendSV_Handler()
+#define SET_Pend_SW_IRQ() SCB->ICSR = SCB->ICSR | SCB_ICSR_PENDSVSET_Msk //NVIC_SetPendingIRQ(PendSV_IRQn) - PendSV_IRQn is a negative - does not work with CMSIS
+
+#else
+
+#define SW_IRQn SWI3_IRQn
+#define SW_IRQ_Handler() SWI3_IRQHandler()
+#define SET_Pend_SW_IRQ() NVIC_SetPendingIRQ(SWI3_IRQn)
+#endif /* USE_PendSV */
+
+typedef enum
+{
+ SER_PHY_STATE_IDLE = 0,
+ SER_PHY_STATE_TX_HEADER,
+ SER_PHY_STATE_TX_WAIT_FOR_RDY,
+ SER_PHY_STATE_TX_PAYLOAD,
+ SER_PHY_STATE_RX_WAIT_FOR_RDY,
+ SER_PHY_STATE_TX_ZERO_HEADER,
+ SER_PHY_STATE_RX_HEADER,
+ SER_PHY_STATE_MEMORY_REQUEST,
+ SER_PHY_STATE_RX_PAYLOAD,
+ SER_PHY_STATE_DISABLED
+} ser_phy_spi_master_state_t;
+
+typedef enum
+{
+ SER_PHY_EVT_GPIO_RDY = 0,
+ SER_PHY_EVT_GPIO_REQ,
+ SER_PHY_EVT_SPI_TRANSFER_DONE,
+ SER_PHY_EVT_TX_API_CALL,
+ SER_PHY_EVT_RX_API_CALL
+} ser_phy_event_source_t;
+
+#define _static static
+
+_static uint8_t * mp_tx_buffer = NULL;
+_static uint16_t m_tx_buf_len = 0;
+
+_static uint8_t * mp_rx_buffer = NULL;
+_static uint16_t m_rx_buf_len = 0;
+_static uint8_t m_frame_buffer[SER_PHY_SPI_MTU_SIZE];
+_static uint8_t m_header_buffer[SER_PHY_HEADER_SIZE] = { 0 };
+
+_static uint16_t m_tx_packet_length = 0;
+_static uint16_t m_accumulated_tx_packet_length = 0;
+_static uint16_t m_current_tx_packet_length = 0;
+
+_static uint16_t m_rx_packet_length = 0;
+_static uint16_t m_accumulated_rx_packet_length = 0;
+_static uint16_t m_current_rx_packet_length = 0;
+
+_static volatile bool m_pend_req_flag = 0;
+_static volatile bool m_pend_rdy_flag = 0;
+_static volatile bool m_pend_xfer_flag = 0;
+_static volatile bool m_pend_rx_api_flag = 0;
+_static volatile bool m_pend_tx_api_flag = 0;
+
+_static volatile bool m_slave_ready_flag = false;
+_static volatile bool m_slave_request_flag = false;
+
+_static ser_phy_events_handler_t m_callback_events_handler = NULL;
+_static ser_phy_spi_master_state_t m_spi_master_state = SER_PHY_STATE_DISABLED;
+
+_static const nrf_drv_spi_t m_spi_master = SER_PHY_SPI_MASTER_INSTANCE;
+
+static void ser_phy_switch_state(ser_phy_event_source_t evt_src);
+
+static void spi_master_raw_assert(bool cond)
+{
+ APP_ERROR_CHECK_BOOL(cond);
+}
+
+void SW_IRQ_Handler()
+{
+ if (m_pend_req_flag)
+ {
+ m_pend_req_flag = false;
+ DEBUG_EVT_SPI_MASTER_RAW_REQUEST(0);
+ ser_phy_switch_state(SER_PHY_EVT_GPIO_REQ);
+ }
+
+ if (m_pend_rdy_flag)
+ {
+ m_pend_rdy_flag = false;
+ DEBUG_EVT_SPI_MASTER_RAW_READY(0);
+ ser_phy_switch_state(SER_PHY_EVT_GPIO_RDY);
+ }
+
+ if (m_pend_xfer_flag)
+ {
+ m_pend_xfer_flag = false;
+ DEBUG_EVT_SPI_MASTER_RAW_XFER_DONE(0);
+ ser_phy_switch_state(SER_PHY_EVT_SPI_TRANSFER_DONE);
+ }
+
+ if (m_pend_rx_api_flag)
+ {
+ m_pend_rx_api_flag = false;
+ DEBUG_EVT_SPI_MASTER_RAW_API_CALL(0);
+ ser_phy_switch_state(SER_PHY_EVT_RX_API_CALL);
+ }
+
+ if (m_pend_tx_api_flag)
+ {
+ m_pend_tx_api_flag = false;
+ DEBUG_EVT_SPI_MASTER_RAW_API_CALL(0);
+ ser_phy_switch_state(SER_PHY_EVT_TX_API_CALL);
+ }
+}
+
+static void ser_phy_spi_master_ready(nrf_drv_gpiote_pin_t pin,
+ nrf_gpiote_polarity_t action)
+{
+ if (nrf_gpio_pin_read(pin) == 0)
+ {
+ m_slave_ready_flag = true;
+ m_pend_rdy_flag = true;
+ }
+ else
+ {
+ m_slave_ready_flag = false;
+ }
+
+ DEBUG_EVT_SPI_MASTER_RAW_READY_EDGE((uint32_t) !m_slave_ready_flag);
+ SET_Pend_SW_IRQ();
+}
+
+static void ser_phy_spi_master_request(nrf_drv_gpiote_pin_t pin,
+ nrf_gpiote_polarity_t action)
+{
+ if (nrf_gpio_pin_read(pin) == 0)
+ {
+ m_slave_request_flag = true;
+ m_pend_req_flag = true;
+ }
+ else
+ {
+ m_slave_request_flag = false;
+ }
+
+ DEBUG_EVT_SPI_MASTER_RAW_REQUEST_EDGE((uint32_t) !m_slave_request_flag);
+ SET_Pend_SW_IRQ();
+}
+
+/* Send event SER_PHY_EVT_TX_PKT_SENT */
+static __INLINE void callback_packet_sent()
+{
+ ser_phy_evt_t event;
+
+ DEBUG_EVT_SPI_MASTER_PHY_TX_PKT_SENT(0);
+
+ event.evt_type = SER_PHY_EVT_TX_PKT_SENT;
+ m_callback_events_handler(event);
+}
+
+/* Send event SER_PHY_EVT_RX_PKT_DROPPED */
+static __INLINE void callback_packet_dropped()
+{
+ ser_phy_evt_t event;
+
+ DEBUG_EVT_SPI_MASTER_PHY_RX_PKT_DROPPED(0);
+
+ event.evt_type = SER_PHY_EVT_RX_PKT_DROPPED;
+ m_callback_events_handler(event);
+}
+
+/* Send event SER_PHY_EVT_RX_PKT_RECEIVED */
+static __INLINE void callback_packet_received()
+{
+ ser_phy_evt_t event;
+
+ DEBUG_EVT_SPI_MASTER_PHY_RX_PKT_RECEIVED(0);
+
+ event.evt_type = SER_PHY_EVT_RX_PKT_RECEIVED;
+ event.evt_params.rx_pkt_received.p_buffer = mp_rx_buffer;
+ event.evt_params.rx_pkt_received.num_of_bytes = m_rx_buf_len;
+ m_callback_events_handler(event);
+}
+
+/* Send event SER_PHY_EVT_RX_BUF_REQUEST */
+static __INLINE void callback_mem_request()
+{
+ ser_phy_evt_t event;
+
+ DEBUG_EVT_SPI_MASTER_PHY_BUF_REQUEST(0);
+
+ event.evt_type = SER_PHY_EVT_RX_BUF_REQUEST;
+ event.evt_params.rx_buf_request.num_of_bytes = m_rx_buf_len;
+ m_callback_events_handler(event);
+}
+
+/* Release buffer */
+static __INLINE void buffer_release(uint8_t * * const pp_buffer,
+ uint16_t * const p_buf_len)
+{
+ *pp_buffer = NULL;
+ *p_buf_len = 0;
+}
+
+/* Function computes current packet length */
+static uint16_t compute_current_packet_length(const uint16_t packet_length,
+ const uint16_t accumulated_packet_length)
+{
+ uint16_t current_packet_length = packet_length - accumulated_packet_length;
+
+ if (current_packet_length > SER_PHY_SPI_MTU_SIZE)
+ {
+ current_packet_length = SER_PHY_SPI_MTU_SIZE;
+ }
+
+ return current_packet_length;
+}
+
+static __INLINE uint32_t header_send(const uint16_t length)
+{
+ uint8_t buf_len_size = uint16_encode(length, m_header_buffer);
+
+ return nrf_drv_spi_transfer(&m_spi_master, m_header_buffer, buf_len_size, NULL, 0);
+}
+
+
+static __INLINE uint32_t frame_send()
+{
+ uint32_t err_code;
+
+ m_current_tx_packet_length = compute_current_packet_length(m_tx_packet_length,
+ m_accumulated_tx_packet_length);
+ err_code =
+ nrf_drv_spi_transfer(&m_spi_master,
+ &mp_tx_buffer[m_accumulated_tx_packet_length],
+ m_current_tx_packet_length,
+ NULL,
+ 0);
+ m_accumulated_tx_packet_length += m_current_tx_packet_length;
+ return err_code;
+}
+
+static __INLINE uint32_t header_get()
+{
+ return nrf_drv_spi_transfer(&m_spi_master, NULL, 0, m_header_buffer, SER_PHY_HEADER_SIZE);
+}
+
+static __INLINE uint32_t frame_get()
+{
+ uint32_t err_code;
+
+ m_current_rx_packet_length = compute_current_packet_length(m_rx_packet_length,
+ m_accumulated_rx_packet_length);
+
+ if (mp_rx_buffer)
+ {
+ err_code = nrf_drv_spi_transfer(&m_spi_master,
+ NULL,
+ 0,
+ &(mp_rx_buffer[m_accumulated_rx_packet_length]),
+ m_current_rx_packet_length);
+ }
+ else
+ {
+ err_code = nrf_drv_spi_transfer(&m_spi_master,
+ NULL,
+ 0,
+ m_frame_buffer,
+ m_current_rx_packet_length);
+ }
+ return err_code;
+}
+
+
+/**
+ * \brief Master driver main state machine
+ * Executed only in the context of PendSV_Handler()
+ * For UML graph, please refer to SDK documentation
+*/
+static void ser_phy_switch_state(ser_phy_event_source_t evt_src)
+{
+ uint32_t err_code = NRF_SUCCESS;
+ static bool m_wait_for_ready_flag = false; //local scheduling flag to defer RDY events
+
+ switch (m_spi_master_state)
+ {
+
+ case SER_PHY_STATE_IDLE:
+
+ if (evt_src == SER_PHY_EVT_GPIO_REQ)
+ {
+ m_wait_for_ready_flag = false;
+
+ if (m_slave_ready_flag)
+ {
+ m_spi_master_state = SER_PHY_STATE_TX_ZERO_HEADER;
+ err_code = header_send(0);
+ }
+ else
+ {
+ m_spi_master_state = SER_PHY_STATE_RX_WAIT_FOR_RDY;
+ }
+ }
+ else if (evt_src == SER_PHY_EVT_TX_API_CALL)
+ {
+ spi_master_raw_assert(mp_tx_buffer != NULL); //api event with tx_buffer == NULL has no sense
+ m_wait_for_ready_flag = false;
+
+ if (m_slave_ready_flag)
+ {
+ m_spi_master_state = SER_PHY_STATE_TX_HEADER;
+ err_code = header_send(m_tx_buf_len);
+ }
+ else
+ {
+ m_spi_master_state = SER_PHY_STATE_TX_WAIT_FOR_RDY;
+ }
+ }
+ break;
+
+ case SER_PHY_STATE_TX_WAIT_FOR_RDY:
+
+ if (evt_src == SER_PHY_EVT_GPIO_RDY)
+ {
+ m_spi_master_state = SER_PHY_STATE_TX_HEADER;
+ err_code = header_send(m_tx_buf_len);
+ }
+ break;
+
+ case SER_PHY_STATE_RX_WAIT_FOR_RDY:
+
+ if (evt_src == SER_PHY_EVT_GPIO_RDY)
+ {
+ m_spi_master_state = SER_PHY_STATE_TX_ZERO_HEADER;
+ err_code = header_send(0);
+
+ }
+ break;
+
+ case SER_PHY_STATE_TX_HEADER:
+
+ if (evt_src == SER_PHY_EVT_SPI_TRANSFER_DONE)
+ {
+ m_tx_packet_length = m_tx_buf_len;
+ m_accumulated_tx_packet_length = 0;
+
+ if (m_slave_ready_flag)
+ {
+ m_spi_master_state = SER_PHY_STATE_TX_PAYLOAD;
+ err_code = frame_send();
+
+ }
+ else
+ {
+ m_wait_for_ready_flag = true;
+ }
+ }
+ else if ((evt_src == SER_PHY_EVT_GPIO_RDY) && m_wait_for_ready_flag)
+ {
+ m_wait_for_ready_flag = false;
+ m_spi_master_state = SER_PHY_STATE_TX_PAYLOAD;
+ err_code = frame_send();
+ }
+
+ break;
+
+ case SER_PHY_STATE_TX_PAYLOAD:
+
+ if (evt_src == SER_PHY_EVT_SPI_TRANSFER_DONE)
+ {
+ if (m_accumulated_tx_packet_length < m_tx_packet_length)
+ {
+ if (m_slave_ready_flag)
+ {
+ err_code = frame_send();
+ }
+ else
+ {
+ m_wait_for_ready_flag = true;
+ }
+ }
+ else
+ {
+ spi_master_raw_assert(m_accumulated_tx_packet_length == m_tx_packet_length);
+ buffer_release(&mp_tx_buffer, &m_tx_buf_len);
+ callback_packet_sent();
+ if ( m_slave_request_flag)
+ {
+ if (m_slave_ready_flag)
+ {
+ m_spi_master_state = SER_PHY_STATE_TX_ZERO_HEADER;
+ err_code = header_send(0);
+ }
+ else
+ {
+ m_spi_master_state = SER_PHY_STATE_RX_WAIT_FOR_RDY;
+ }
+ }
+ else
+ {
+ m_spi_master_state = SER_PHY_STATE_IDLE; //m_Tx_buffer is NULL - have to wait for API event
+ }
+ }
+ }
+ else if ((evt_src == SER_PHY_EVT_GPIO_RDY) && m_wait_for_ready_flag )
+ {
+ m_wait_for_ready_flag = false;
+ err_code = frame_send();
+ }
+
+ break;
+
+ case SER_PHY_STATE_TX_ZERO_HEADER:
+
+ if (evt_src == SER_PHY_EVT_SPI_TRANSFER_DONE)
+ {
+ if (m_slave_ready_flag)
+ {
+ m_spi_master_state = SER_PHY_STATE_RX_HEADER;
+ err_code = header_get();
+ }
+ else
+ {
+ m_wait_for_ready_flag = true;
+ }
+ }
+ else if ( (evt_src == SER_PHY_EVT_GPIO_RDY) && m_wait_for_ready_flag)
+ {
+ m_wait_for_ready_flag = false;
+ m_spi_master_state = SER_PHY_STATE_RX_HEADER;
+ err_code = header_get();
+ }
+ break;
+
+ case SER_PHY_STATE_RX_HEADER:
+
+ if (evt_src == SER_PHY_EVT_SPI_TRANSFER_DONE)
+ {
+ m_spi_master_state = SER_PHY_STATE_MEMORY_REQUEST;
+ m_rx_buf_len = uint16_decode(m_header_buffer);
+ m_rx_packet_length = m_rx_buf_len;
+ callback_mem_request();
+
+ }
+ break;
+
+ case SER_PHY_STATE_MEMORY_REQUEST:
+
+ if (evt_src == SER_PHY_EVT_RX_API_CALL)
+ {
+ m_accumulated_rx_packet_length = 0;
+
+ if (m_slave_ready_flag)
+ {
+ m_spi_master_state = SER_PHY_STATE_RX_PAYLOAD;
+ err_code = frame_get();
+ }
+ else
+ {
+ m_wait_for_ready_flag = true;
+ }
+ }
+ else if ((evt_src == SER_PHY_EVT_GPIO_RDY) && m_wait_for_ready_flag)
+ {
+ m_wait_for_ready_flag = false;
+ m_spi_master_state = SER_PHY_STATE_RX_PAYLOAD;
+ err_code = frame_get();
+ }
+ break;
+
+ case SER_PHY_STATE_RX_PAYLOAD:
+
+ if (evt_src == SER_PHY_EVT_SPI_TRANSFER_DONE)
+ {
+ m_accumulated_rx_packet_length += m_current_rx_packet_length;
+
+ if (m_accumulated_rx_packet_length < m_rx_packet_length)
+ {
+ if (m_slave_ready_flag)
+ {
+ err_code = frame_get();
+ }
+ else
+ {
+ m_wait_for_ready_flag = true;
+ }
+ }
+ else
+ {
+ spi_master_raw_assert(m_accumulated_rx_packet_length == m_rx_packet_length);
+
+ if (mp_rx_buffer == NULL)
+ {
+ callback_packet_dropped();
+ }
+ else
+ {
+ callback_packet_received();
+ }
+ buffer_release(&mp_rx_buffer, &m_rx_buf_len);
+ if (mp_tx_buffer != NULL) //mp_tx_buffer !=NULL, this means that API_EVT was scheduled
+ {
+ if (m_slave_ready_flag )
+ {
+ err_code = header_send(m_tx_buf_len);
+ m_spi_master_state = SER_PHY_STATE_TX_HEADER;
+ }
+ else
+ {
+ m_spi_master_state = SER_PHY_STATE_TX_WAIT_FOR_RDY;
+ }
+ }
+ else if (m_slave_request_flag)
+ {
+ if (m_slave_ready_flag)
+ {
+ m_spi_master_state = SER_PHY_STATE_TX_ZERO_HEADER;
+ err_code = header_send(0);
+ }
+ else
+ {
+ m_spi_master_state = SER_PHY_STATE_RX_WAIT_FOR_RDY;
+ }
+ }
+ else
+ {
+ m_spi_master_state = SER_PHY_STATE_IDLE;
+
+ }
+ }
+
+ }
+ else if ( evt_src == SER_PHY_EVT_GPIO_RDY && m_wait_for_ready_flag)
+ {
+ m_wait_for_ready_flag = false;
+ err_code = frame_get();
+ }
+ break;
+
+ default:
+ break;
+ }
+
+ if (err_code != NRF_SUCCESS)
+ {
+ (void)err_code;
+ }
+}
+
+static void ser_phy_spi_master_event_handler(nrf_drv_spi_evt_t const * p_event,
+ void * p_context)
+{
+ switch (p_event->type)
+ {
+ case NRF_DRV_SPI_EVENT_DONE:
+
+ /* Switch state */
+ m_pend_xfer_flag = true;
+ SET_Pend_SW_IRQ();
+
+ break;
+
+ default:
+ break;
+ }
+}
+
+static void ser_phy_init_PendSV(void)
+{
+ NVIC_SetPriority(SW_IRQn, APP_IRQ_PRIORITY_MID);
+ NVIC_EnableIRQ(SW_IRQn);
+}
+
+static ret_code_t ser_phy_init_gpiote(void)
+{
+ if (!nrf_drv_gpiote_is_init())
+ {
+ (void)nrf_drv_gpiote_init();
+ }
+ NVIC_SetPriority(GPIOTE_IRQn, APP_IRQ_PRIORITY_HIGH);
+
+ nrf_drv_gpiote_in_config_t config = GPIOTE_CONFIG_IN_SENSE_TOGGLE(true);
+ /* Enable pullup to ensure high state while connectivity device is reset */
+ config.pull = NRF_GPIO_PIN_PULLUP;
+ ret_code_t err_code = nrf_drv_gpiote_in_init(SER_PHY_SPI_MASTER_PIN_SLAVE_REQUEST,
+ &config, ser_phy_spi_master_request);
+ if (err_code != NRF_SUCCESS)
+ {
+ return err_code;
+ }
+ nrf_drv_gpiote_in_event_enable(SER_PHY_SPI_MASTER_PIN_SLAVE_REQUEST,true);
+
+ err_code = nrf_drv_gpiote_in_init(SER_PHY_SPI_MASTER_PIN_SLAVE_READY,
+ &config, ser_phy_spi_master_ready);
+ if (err_code != NRF_SUCCESS)
+ {
+ return err_code;
+ }
+ nrf_drv_gpiote_in_event_enable(SER_PHY_SPI_MASTER_PIN_SLAVE_READY,true);
+
+ m_slave_request_flag = !(nrf_gpio_pin_read(SER_PHY_SPI_MASTER_PIN_SLAVE_REQUEST));
+ m_slave_ready_flag = !(nrf_gpio_pin_read(SER_PHY_SPI_MASTER_PIN_SLAVE_READY));
+
+ NVIC_ClearPendingIRQ(SW_IRQn);
+
+ return NRF_SUCCESS;
+}
+
+static void ser_phy_deinit_gpiote(void)
+{
+ nrf_drv_gpiote_in_uninit(SER_PHY_SPI_MASTER_PIN_SLAVE_REQUEST);
+ nrf_drv_gpiote_in_uninit(SER_PHY_SPI_MASTER_PIN_SLAVE_READY);
+}
+
+/* ser_phy API function */
+uint32_t ser_phy_tx_pkt_send(const uint8_t * p_buffer, uint16_t num_of_bytes)
+{
+ if (p_buffer == NULL)
+ {
+ return NRF_ERROR_NULL;
+ }
+
+ if (num_of_bytes == 0)
+ {
+ return NRF_ERROR_INVALID_PARAM;
+ }
+
+ if (mp_tx_buffer != NULL)
+ {
+ return NRF_ERROR_BUSY;
+ }
+
+ //ser_phy_interrupts_disable();
+ CRITICAL_REGION_ENTER();
+ mp_tx_buffer = (uint8_t *)p_buffer;
+ m_tx_buf_len = num_of_bytes;
+ m_pend_tx_api_flag = true;
+ SET_Pend_SW_IRQ();
+ //ser_phy_interrupts_enable();
+ CRITICAL_REGION_EXIT();
+
+ return NRF_SUCCESS;
+}
+/* ser_phy API function */
+uint32_t ser_phy_rx_buf_set(uint8_t * p_buffer)
+{
+ if (m_spi_master_state != SER_PHY_STATE_MEMORY_REQUEST)
+ {
+ return NRF_ERROR_INVALID_STATE;
+ }
+
+ //ser_phy_interrupts_disable();
+ CRITICAL_REGION_ENTER();
+ mp_rx_buffer = p_buffer;
+ m_pend_rx_api_flag = true;
+ SET_Pend_SW_IRQ();
+ //ser_phy_interrupts_enable();
+ CRITICAL_REGION_EXIT();
+
+ return NRF_SUCCESS;
+}
+
+/* ser_phy API function */
+uint32_t ser_phy_open(ser_phy_events_handler_t events_handler)
+{
+ if (m_spi_master_state != SER_PHY_STATE_DISABLED)
+ {
+ return NRF_ERROR_INVALID_STATE;
+ }
+
+ if (events_handler == NULL)
+ {
+ return NRF_ERROR_NULL;
+ }
+
+ uint32_t err_code = NRF_SUCCESS;
+
+ m_spi_master_state = SER_PHY_STATE_IDLE;
+ m_callback_events_handler = events_handler;
+ nrf_drv_spi_config_t spi_master_config = {
+ .sck_pin = SER_PHY_SPI_MASTER_PIN_SCK,
+ .mosi_pin = SER_PHY_SPI_MASTER_PIN_MOSI,
+ .miso_pin = SER_PHY_SPI_MASTER_PIN_MISO,
+ .ss_pin = SER_PHY_SPI_MASTER_PIN_SLAVE_SELECT,
+ .irq_priority = APP_IRQ_PRIORITY_MID,
+ .orc = 0,
+ .frequency = SER_PHY_SPI_FREQUENCY,
+ .mode = NRF_DRV_SPI_MODE_0,
+ .bit_order = NRF_DRV_SPI_BIT_ORDER_LSB_FIRST,
+ };
+ err_code = nrf_drv_spi_init(&m_spi_master,
+ &spi_master_config,
+ ser_phy_spi_master_event_handler,
+ NULL);
+ if (err_code != NRF_SUCCESS)
+ {
+ return err_code;
+ }
+
+ err_code = ser_phy_init_gpiote();
+ ser_phy_init_PendSV();
+ return err_code;
+}
+
+/* ser_phy API function */
+void ser_phy_close(void)
+{
+ m_spi_master_state = SER_PHY_STATE_DISABLED;
+
+ m_callback_events_handler = NULL;
+
+ buffer_release(&mp_tx_buffer, &m_tx_buf_len);
+ buffer_release(&mp_rx_buffer, &m_rx_buf_len);
+
+ m_tx_packet_length = 0;
+ m_accumulated_tx_packet_length = 0;
+ m_current_tx_packet_length = 0;
+
+ m_rx_packet_length = 0;
+ m_accumulated_rx_packet_length = 0;
+ m_current_rx_packet_length = 0;
+
+ ser_phy_deinit_gpiote();
+ nrf_drv_spi_uninit(&m_spi_master);
+}
+
+/* ser_phy API function */
+/* only PendSV may interact with ser_phy layer, other interrupts are internal */
+void ser_phy_interrupts_enable(void)
+{
+ NVIC_EnableIRQ(SW_IRQn);
+}
+
+/* ser_phy API function */
+void ser_phy_interrupts_disable(void)
+{
+ NVIC_DisableIRQ(SW_IRQn);
+}
+
+/** @} */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/common/transport/ser_phy/ser_phy_spi_slave.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/common/transport/ser_phy/ser_phy_spi_slave.c
new file mode 100644
index 0000000..cde0250
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/common/transport/ser_phy/ser_phy_spi_slave.c
@@ -0,0 +1,613 @@
+/**
+ * Copyright (c) 2014 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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
+ *
+ * @defgroup ser_phy_spi_phy_driver_slave ser_phy_nrf51_spi_slave.c
+ * @{
+ * @ingroup ser_phy_spi_phy_driver_slave
+ *
+ * @brief SPI_RAW PHY slave driver.
+ */
+
+#include <stddef.h>
+#include <string.h>
+
+#include "app_error.h"
+#include "app_util.h"
+#include "boards.h"
+#include "nrf_gpio.h"
+#include "nrf_drv_gpiote.h"
+#include "nrf_soc.h"
+#include "nrf_drv_spis.h"
+#include "ser_config.h"
+#include "ser_phy.h"
+#include "ser_phy_config_conn.h"
+#include "ser_phy_debug_conn.h"
+
+#define SER_PHY_SPI_DEF_CHARACTER 0xFF //SPI default character. Character clocked out in case of an ignored transaction
+#define SER_PHY_SPI_ORC_CHARACTER 0xFF //SPI over-read character. Character clocked out after an over-read of the transmit buffer
+
+static nrf_drv_spis_t m_spis = NRF_DRV_SPIS_INSTANCE(SER_PHY_SPI_SLAVE_INSTANCE);
+
+#ifdef NRF_SPIS0
+#define SPI_SLAVE_REG NRF_SPIS0
+#else
+#define SPI_SLAVE_REG NRF_SPIS1
+#endif
+
+//SPI raw peripheral device configuration data
+typedef struct
+{
+ int32_t pin_req; //SPI /REQ pin. -1 for not using
+ int32_t pin_rdy; //SPI /RDY pin. -1 for not using
+ int32_t ppi_rdy_ch; //SPI /RDY ppi ready channel
+ int32_t gpiote_rdy_ch; //SPI /RDY pin ready channel
+} spi_slave_raw_trasp_cfg_t;
+
+/**@brief States of the SPI transaction state machine. */
+typedef enum
+{
+ SPI_RAW_STATE_UNKNOWN,
+ SPI_RAW_STATE_SETUP_HEADER,
+ SPI_RAW_STATE_RX_HEADER,
+ SPI_RAW_STATE_MEM_REQUESTED,
+ SPI_RAW_STATE_RX_PAYLOAD,
+ SPI_RAW_STATE_TX_HEADER,
+ SPI_RAW_STATE_TX_PAYLOAD,
+} trans_state_t;
+
+#define _static static
+
+static spi_slave_raw_trasp_cfg_t m_spi_slave_raw_config;
+
+_static uint16_t m_accumulated_rx_packet_length;
+_static uint16_t m_rx_packet_length;
+_static uint16_t m_current_rx_frame_length;
+
+_static uint16_t m_accumulated_tx_packet_length;
+_static uint16_t m_tx_packet_length;
+_static uint16_t m_current_tx_frame_length;
+
+_static uint8_t m_header_rx_buffer[SER_PHY_HEADER_SIZE];
+_static uint8_t m_header_tx_buffer[SER_PHY_HEADER_SIZE];
+
+_static uint8_t m_frame_buffer[SER_PHY_SPI_MTU_SIZE]; //trash storage
+_static uint8_t m_zero_buffer[SER_PHY_SPI_MTU_SIZE] = { 0 }; //ROM'able declaration
+
+_static uint8_t * volatile m_p_rx_buffer = NULL;
+_static const uint8_t * volatile m_p_tx_buffer = NULL;
+
+_static bool m_trash_payload_flag;
+_static bool m_buffer_reqested_flag;
+
+_static trans_state_t m_trans_state = SPI_RAW_STATE_UNKNOWN;
+_static ser_phy_events_handler_t m_ser_phy_callback = NULL;
+
+static void spi_slave_raw_assert(bool cond)
+{
+ APP_ERROR_CHECK_BOOL(cond);
+}
+
+static void callback_ser_phy_event(ser_phy_evt_t event)
+{
+ if (m_ser_phy_callback)
+ {
+ m_ser_phy_callback(event);
+ }
+}
+
+static void callback_memory_request(uint16_t size)
+{
+ ser_phy_evt_t event;
+
+ DEBUG_EVT_SPI_SLAVE_PHY_BUF_REQUEST(0);
+
+ event.evt_type = SER_PHY_EVT_RX_BUF_REQUEST;
+ event.evt_params.rx_buf_request.num_of_bytes = size;
+ callback_ser_phy_event(event);
+}
+
+static void callback_packet_received(uint8_t * pBuffer, uint16_t size)
+{
+ ser_phy_evt_t event;
+
+ DEBUG_EVT_SPI_SLAVE_PHY_PKT_RECEIVED(0);
+
+ event.evt_type = SER_PHY_EVT_RX_PKT_RECEIVED;
+ event.evt_params.rx_pkt_received.num_of_bytes = size;
+ event.evt_params.rx_pkt_received.p_buffer = pBuffer;
+ callback_ser_phy_event(event);
+}
+
+static void callback_packet_dropped()
+{
+ ser_phy_evt_t event;
+
+ DEBUG_EVT_SPI_SLAVE_PHY_PKT_DROPPED(0);
+
+ event.evt_type = SER_PHY_EVT_RX_PKT_DROPPED;
+ callback_ser_phy_event(event);
+}
+
+static void callback_packet_transmitted(void)
+{
+ ser_phy_evt_t event;
+
+ DEBUG_EVT_SPI_SLAVE_PHY_PKT_SENT(0);
+
+ event.evt_type = SER_PHY_EVT_TX_PKT_SENT;
+ callback_ser_phy_event(event);
+}
+
+/* Function computes current packet length */
+static uint16_t compute_current_frame_length(const uint16_t packet_length,
+ const uint16_t accumulated_packet_length)
+{
+ uint16_t current_packet_length = packet_length - accumulated_packet_length;
+
+ if (current_packet_length > SER_PHY_SPI_MTU_SIZE)
+ {
+ current_packet_length = SER_PHY_SPI_MTU_SIZE;
+ }
+
+ return current_packet_length;
+}
+
+static uint32_t header_get()
+{
+ uint32_t err_code;
+
+ err_code = nrf_drv_spis_buffers_set(&m_spis,
+ (uint8_t *) m_zero_buffer,
+ SER_PHY_HEADER_SIZE,
+ m_header_rx_buffer,
+ SER_PHY_HEADER_SIZE);
+ return err_code;
+}
+
+static uint32_t frame_get()
+{
+ uint32_t err_code;
+
+ m_current_rx_frame_length = compute_current_frame_length(m_rx_packet_length,
+ m_accumulated_rx_packet_length);
+
+ if (!m_trash_payload_flag)
+ {
+ err_code =
+ nrf_drv_spis_buffers_set(&m_spis,
+ (uint8_t *) m_zero_buffer,
+ m_current_rx_frame_length,
+ &(m_p_rx_buffer[m_accumulated_rx_packet_length]),
+ m_current_rx_frame_length);
+ }
+ else
+ {
+ err_code = nrf_drv_spis_buffers_set(&m_spis,
+ (uint8_t *) m_zero_buffer,
+ m_current_rx_frame_length,
+ m_frame_buffer,
+ m_current_rx_frame_length);
+ }
+ return err_code;
+}
+
+static uint32_t header_send(uint16_t len)
+{
+ uint32_t err_code;
+
+ (void) uint16_encode(len, m_header_tx_buffer);
+ err_code =
+ nrf_drv_spis_buffers_set(&m_spis,
+ m_header_tx_buffer,
+ sizeof (m_header_tx_buffer),
+ m_header_rx_buffer,
+ sizeof (m_header_tx_buffer));
+ return err_code;
+}
+
+static uint32_t frame_send()
+{
+ uint32_t err_code;
+
+ m_current_tx_frame_length = compute_current_frame_length(m_tx_packet_length,
+ m_accumulated_tx_packet_length);
+ err_code =
+ nrf_drv_spis_buffers_set(&m_spis,
+ (uint8_t *) &(m_p_tx_buffer[m_accumulated_tx_packet_length]),
+ m_current_tx_frame_length,
+ m_frame_buffer,
+ m_current_tx_frame_length);
+ return err_code;
+}
+
+static void set_ready_line(void)
+{
+ //toggle - this should go high - but toggle is unsafe
+ uint32_t rdy_task = nrf_drv_gpiote_out_task_addr_get(m_spi_slave_raw_config.pin_rdy);
+ *(uint32_t *)rdy_task = 1;
+ return;
+}
+
+static void set_request_line(void)
+{
+ //active low logic - set is 0
+ nrf_gpio_pin_clear(m_spi_slave_raw_config.pin_req);
+ DEBUG_EVT_SPI_SLAVE_RAW_REQ_SET(0);
+}
+
+static void clear_request_line(void)
+{
+ //active low logic - clear is 1
+ nrf_gpio_pin_set(m_spi_slave_raw_config.pin_req);
+ DEBUG_EVT_SPI_SLAVE_RAW_REQ_SET(0);
+}
+
+/**
+ * \brief Slave driver main state machine
+ * For UML graph, please refer to SDK documentation
+*/
+static void spi_slave_event_handle(nrf_drv_spis_event_t event)
+{
+ uint32_t err_code = NRF_SUCCESS;
+ static uint16_t packetLength;
+
+ switch (m_trans_state)
+ {
+ case SPI_RAW_STATE_SETUP_HEADER:
+ m_trans_state = SPI_RAW_STATE_RX_HEADER;
+ err_code = header_get();
+ break;
+
+ case SPI_RAW_STATE_RX_HEADER:
+
+ if (event.evt_type == NRF_DRV_SPIS_BUFFERS_SET_DONE)
+ {
+ DEBUG_EVT_SPI_SLAVE_RAW_BUFFERS_SET(0);
+ set_ready_line();
+ }
+
+ if (event.evt_type == NRF_DRV_SPIS_XFER_DONE)
+ {
+ DEBUG_EVT_SPI_SLAVE_RAW_RX_XFER_DONE(event.rx_amount);
+ spi_slave_raw_assert(event.rx_amount == SER_PHY_HEADER_SIZE);
+ packetLength = uint16_decode(m_header_rx_buffer);
+
+ if (packetLength != 0 )
+ {
+ m_trans_state = SPI_RAW_STATE_MEM_REQUESTED;
+ m_buffer_reqested_flag = true;
+ m_rx_packet_length = packetLength;
+ callback_memory_request(packetLength);
+ }
+ else
+ {
+ if (m_p_tx_buffer)
+ {
+ clear_request_line();
+ m_trans_state = SPI_RAW_STATE_TX_HEADER;
+ err_code = header_send(m_tx_packet_length);
+ }
+ else
+ {
+ //there is nothing to send - zero response facilitates pooling - but perhaps, it should be assert
+ err_code = header_send(0);
+ }
+ }
+ }
+
+ break;
+
+ case SPI_RAW_STATE_MEM_REQUESTED:
+
+ if (event.evt_type == NRF_DRV_SPIS_EVT_TYPE_MAX) //This is API dummy event
+ {
+ m_buffer_reqested_flag = false;
+ m_trans_state = SPI_RAW_STATE_RX_PAYLOAD;
+ m_accumulated_rx_packet_length = 0;
+ err_code = frame_get();
+ }
+ break;
+
+ case SPI_RAW_STATE_RX_PAYLOAD:
+
+ if (event.evt_type == NRF_DRV_SPIS_BUFFERS_SET_DONE)
+ {
+ DEBUG_EVT_SPI_SLAVE_RAW_BUFFERS_SET(0);
+ set_ready_line();
+ }
+
+ if (event.evt_type == NRF_DRV_SPIS_XFER_DONE)
+ {
+ DEBUG_EVT_SPI_SLAVE_RAW_RX_XFER_DONE(event.rx_amount);
+ spi_slave_raw_assert(event.rx_amount == m_current_rx_frame_length);
+ m_accumulated_rx_packet_length += m_current_rx_frame_length;
+
+ if (m_accumulated_rx_packet_length < m_rx_packet_length )
+ {
+ err_code = frame_get();
+ }
+ else
+ {
+ spi_slave_raw_assert(m_accumulated_rx_packet_length == m_rx_packet_length);
+ m_trans_state = SPI_RAW_STATE_RX_HEADER;
+ err_code = header_get();
+
+ if (!m_trash_payload_flag)
+ {
+ callback_packet_received(m_p_rx_buffer, m_accumulated_rx_packet_length);
+ }
+ else
+ {
+ callback_packet_dropped();
+ }
+ }
+ }
+ break;
+
+ case SPI_RAW_STATE_TX_HEADER:
+
+ if (event.evt_type == NRF_DRV_SPIS_BUFFERS_SET_DONE)
+ {
+ DEBUG_EVT_SPI_SLAVE_RAW_BUFFERS_SET(0);
+ set_ready_line();
+ }
+
+ if (event.evt_type == NRF_DRV_SPIS_XFER_DONE)
+ {
+ DEBUG_EVT_SPI_SLAVE_RAW_TX_XFER_DONE(event.tx_amount);
+ spi_slave_raw_assert(event.tx_amount == SER_PHY_HEADER_SIZE);
+ m_trans_state = SPI_RAW_STATE_TX_PAYLOAD;
+ m_accumulated_tx_packet_length = 0;
+ err_code = frame_send();
+ }
+
+ break;
+
+ case SPI_RAW_STATE_TX_PAYLOAD:
+
+ if (event.evt_type == NRF_DRV_SPIS_BUFFERS_SET_DONE)
+ {
+ DEBUG_EVT_SPI_SLAVE_RAW_BUFFERS_SET(0);
+ set_ready_line();
+ }
+
+ if (event.evt_type == NRF_DRV_SPIS_XFER_DONE)
+ {
+ DEBUG_EVT_SPI_SLAVE_RAW_TX_XFER_DONE(event.tx_amount);
+ spi_slave_raw_assert(event.tx_amount == m_current_tx_frame_length);
+ m_accumulated_tx_packet_length += m_current_tx_frame_length;
+
+ if ( m_accumulated_tx_packet_length < m_tx_packet_length )
+ {
+ err_code = frame_send();
+ }
+ else
+ {
+ spi_slave_raw_assert(m_accumulated_tx_packet_length == m_tx_packet_length);
+ //clear pointer before callback
+ m_p_tx_buffer = NULL;
+ callback_packet_transmitted();
+ //spi slave TX transfer is possible only when RX is ready, so return to waiting for a header
+ m_trans_state = SPI_RAW_STATE_RX_HEADER;
+ err_code = header_get();
+ }
+ }
+ break;
+
+ default:
+ err_code = NRF_ERROR_INVALID_STATE;
+ break;
+ }
+ APP_ERROR_CHECK(err_code);
+}
+
+static void spi_slave_gpiote_init(void)
+{
+ if (!nrf_drv_gpiote_is_init())
+ {
+ (void)nrf_drv_gpiote_init();
+ }
+ nrf_drv_gpiote_out_config_t config = GPIOTE_CONFIG_OUT_TASK_TOGGLE(true);
+ (void) nrf_drv_gpiote_out_init(m_spi_slave_raw_config.pin_rdy, &config);
+ (void) nrf_drv_gpiote_out_task_enable(m_spi_slave_raw_config.pin_rdy);
+ return;
+}
+
+static void spi_slave_ppi_init(void)
+{
+ uint32_t rdy_task = nrf_drv_gpiote_out_task_addr_get(m_spi_slave_raw_config.pin_rdy);
+ //Configure PPI channel to clear /RDY line
+ NRF_PPI->CH[m_spi_slave_raw_config.ppi_rdy_ch].EEP = (uint32_t)(&SPI_SLAVE_REG->EVENTS_END);
+ NRF_PPI->CH[m_spi_slave_raw_config.ppi_rdy_ch].TEP = rdy_task;
+
+ //this works only for channels 0..15 - but soft device is using 8-15 anyway
+ NRF_PPI->CHEN |= (1 << m_spi_slave_raw_config.ppi_rdy_ch);
+ return;
+}
+
+static void spi_slave_gpio_init(void)
+{
+ nrf_gpio_pin_set(m_spi_slave_raw_config.pin_req);
+ nrf_gpio_cfg_output(m_spi_slave_raw_config.pin_req);
+ nrf_gpio_pin_set(m_spi_slave_raw_config.pin_rdy);
+ nrf_gpio_cfg_output(m_spi_slave_raw_config.pin_rdy);
+}
+
+/* ser_phy API function */
+void ser_phy_interrupts_enable(void)
+{
+ (void)sd_nvic_EnableIRQ(nrfx_get_irq_number(m_spis.p_reg));
+}
+
+/* ser_phy API function */
+void ser_phy_interrupts_disable(void)
+{
+ (void)sd_nvic_DisableIRQ(nrfx_get_irq_number(m_spis.p_reg));
+}
+
+/* ser_phy API function */
+uint32_t ser_phy_rx_buf_set(uint8_t * p_buffer)
+{
+ uint32_t status = NRF_SUCCESS;
+ nrf_drv_spis_event_t event;
+
+ ser_phy_interrupts_disable();
+
+ if (m_buffer_reqested_flag && (m_trans_state == SPI_RAW_STATE_MEM_REQUESTED))
+ {
+ m_p_rx_buffer = p_buffer;
+
+ if (m_p_rx_buffer)
+ {
+ m_trash_payload_flag = false;
+ }
+ else
+ {
+ m_trash_payload_flag = true;
+ }
+ event.evt_type = NRF_DRV_SPIS_EVT_TYPE_MAX; //force transition with dummy event
+ event.rx_amount = 0;
+ event.tx_amount = 0;
+ spi_slave_event_handle(event);
+ }
+ else
+ {
+ status = NRF_ERROR_BUSY;
+ }
+ ser_phy_interrupts_enable();
+
+ return status;
+}
+
+/* ser_phy API function */
+uint32_t ser_phy_tx_pkt_send(const uint8_t * p_buffer, uint16_t num_of_bytes)
+{
+ uint32_t status = NRF_SUCCESS;
+
+ if ( p_buffer == NULL || num_of_bytes == 0)
+ {
+ return NRF_ERROR_NULL;
+ }
+
+ ser_phy_interrupts_disable();
+
+ if ( m_p_tx_buffer == NULL)
+ {
+ m_tx_packet_length = num_of_bytes;
+ m_p_tx_buffer = p_buffer;
+ set_request_line();
+ }
+ else
+ {
+ status = NRF_ERROR_BUSY;
+ }
+ ser_phy_interrupts_enable();
+
+ return status;
+}
+
+/* ser_phy API function */
+uint32_t ser_phy_open(ser_phy_events_handler_t events_handler)
+{
+ uint32_t err_code;
+ nrf_drv_spis_config_t spi_slave_config;
+ nrf_drv_spis_event_t event;
+
+ if (m_trans_state != SPI_RAW_STATE_UNKNOWN)
+ {
+ return NRF_ERROR_INVALID_STATE;
+ }
+
+ if (events_handler == NULL)
+ {
+ return NRF_ERROR_NULL;
+ }
+
+ //one ppi channel and one gpiote channel are used to drive RDY line
+ m_spi_slave_raw_config.pin_req = SER_PHY_SPI_SLAVE_REQ_PIN;
+ m_spi_slave_raw_config.pin_rdy = SER_PHY_SPI_SLAVE_RDY_PIN;
+ m_spi_slave_raw_config.ppi_rdy_ch = SER_PHY_SPI_PPI_RDY_CH;
+ m_spi_slave_raw_config.gpiote_rdy_ch = SER_PHY_SPI_GPIOTE_RDY_CH;
+
+ spi_slave_gpio_init();
+ spi_slave_gpiote_init();
+ spi_slave_ppi_init();
+
+ spi_slave_config.miso_pin = SER_PHY_SPI_SLAVE_MISO_PIN;
+ spi_slave_config.mosi_pin = SER_PHY_SPI_SLAVE_MOSI_PIN;
+ spi_slave_config.sck_pin = SER_PHY_SPI_SLAVE_SCK_PIN;
+ spi_slave_config.csn_pin = SER_PHY_SPI_SLAVE_SS_PIN;
+ spi_slave_config.mode = NRF_DRV_SPIS_MODE_0;
+ spi_slave_config.bit_order = NRF_DRV_SPIS_BIT_ORDER_LSB_FIRST;
+ spi_slave_config.def = SER_PHY_SPI_DEF_CHARACTER;
+ spi_slave_config.orc = SER_PHY_SPI_ORC_CHARACTER;
+ spi_slave_config.irq_priority = APP_IRQ_PRIORITY_LOWEST;
+ spi_slave_config.miso_drive = NRF_DRV_SPIS_DEFAULT_MISO_DRIVE;
+ //use /CS pullup because state of the line might be undefined when master redefines PIO lines
+ spi_slave_config.csn_pullup = NRF_GPIO_PIN_PULLUP;
+
+ //keep /CS high when init
+ nrf_gpio_cfg_input(spi_slave_config.csn_pin, NRF_GPIO_PIN_PULLUP);
+
+ err_code = nrf_drv_spis_init(&m_spis, &spi_slave_config, spi_slave_event_handle);
+ APP_ERROR_CHECK(err_code);
+
+ if (err_code == NRF_SUCCESS)
+ {
+ m_ser_phy_callback = events_handler;
+
+ m_trans_state = SPI_RAW_STATE_SETUP_HEADER;
+ event.evt_type = NRF_DRV_SPIS_EVT_TYPE_MAX; //force transition for dummy event
+ event.rx_amount = 0;
+ event.tx_amount = 0;
+ spi_slave_event_handle(event);
+
+ }
+ return err_code;
+}
+
+/* ser_phy API function */
+void ser_phy_close(void)
+{
+ nrf_drv_spis_uninit(&m_spis);
+ m_ser_phy_callback = NULL;
+ m_trans_state = SPI_RAW_STATE_UNKNOWN;
+}
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/common/transport/ser_phy/ser_phy_uart.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/common/transport/ser_phy/ser_phy_uart.c
new file mode 100644
index 0000000..d690ac7
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/common/transport/ser_phy/ser_phy_uart.c
@@ -0,0 +1,357 @@
+/**
+ * Copyright (c) 2014 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#include "ser_phy.h"
+#include "ser_config.h"
+#ifdef SER_CONNECTIVITY
+ #include "ser_phy_config_conn.h"
+#else
+ #include "ser_phy_config_app.h"
+#endif
+#include "nrf_drv_uart.h"
+#include "app_error.h"
+#include "app_util.h"
+#include "app_util_platform.h"
+
+#define UART_TRANSFER_MAX 255
+
+#if defined(UARTE_PRESENT) && !defined(UART_PRESENT)
+#define SER_UART_IRQ UARTE0_IRQn
+#else
+#define SER_UART_IRQ UART0_IRQn
+#endif
+
+static const nrf_drv_uart_t m_uart = NRF_DRV_UART_INSTANCE(0);
+static const nrf_drv_uart_config_t m_uart_config = {
+ .pseltxd = SER_PHY_UART_TX,
+ .pselrxd = SER_PHY_UART_RX,
+ .pselrts = SER_PHY_UART_RTS,
+ .pselcts = SER_PHY_UART_CTS,
+ .p_context = NULL,
+ .interrupt_priority = UART_IRQ_PRIORITY,
+#if defined(UARTE_PRESENT) && defined(UART_PRESENT)
+ .use_easy_dma = true,
+#endif
+ // These values are common for application and connectivity, they are
+ // defined in "ser_config.h".
+ .hwfc = SER_PHY_UART_FLOW_CTRL,
+ .parity = SER_PHY_UART_PARITY,
+ .baudrate = (nrf_uart_baudrate_t)SER_PHY_UART_BAUDRATE
+};
+
+static bool volatile m_tx_in_progress;
+static uint8_t m_tx_header_buf[SER_PHY_HEADER_SIZE];
+static uint16_t m_bytes_to_transmit;
+static uint8_t const * mp_tx_buffer;
+
+static uint8_t m_rx_header_buf[SER_PHY_HEADER_SIZE];
+static uint16_t m_bytes_to_receive;
+static uint8_t m_rx_drop_buf[1];
+
+static ser_phy_events_handler_t m_ser_phy_event_handler;
+static ser_phy_evt_t m_ser_phy_rx_event;
+
+
+static void packet_sent_callback(void)
+{
+ static ser_phy_evt_t const event = {
+ .evt_type = SER_PHY_EVT_TX_PKT_SENT,
+ };
+ m_ser_phy_event_handler(event);
+}
+
+static void buffer_request_callback(uint16_t num_of_bytes)
+{
+ m_ser_phy_rx_event.evt_type = SER_PHY_EVT_RX_BUF_REQUEST;
+ m_ser_phy_rx_event.evt_params.rx_buf_request.num_of_bytes = num_of_bytes;
+ m_ser_phy_event_handler(m_ser_phy_rx_event);
+}
+
+static void packet_received_callback(void)
+{
+ m_ser_phy_event_handler(m_ser_phy_rx_event);
+}
+
+static void packet_dropped_callback(void)
+{
+ static ser_phy_evt_t const event = {
+ .evt_type = SER_PHY_EVT_RX_PKT_DROPPED,
+ };
+ m_ser_phy_event_handler(event);
+}
+
+static void hardware_error_callback(uint32_t hw_error)
+{
+ ser_phy_evt_t event = {
+ .evt_type = SER_PHY_EVT_HW_ERROR,
+ .evt_params.hw_error.error_code = hw_error,
+ };
+ m_ser_phy_event_handler(event);
+}
+
+static void packet_rx_start(void)
+{
+ APP_ERROR_CHECK(nrf_drv_uart_rx(&m_uart, m_rx_header_buf,
+ SER_PHY_HEADER_SIZE));
+}
+
+static void packet_byte_drop(void)
+{
+ APP_ERROR_CHECK(nrf_drv_uart_rx(&m_uart, m_rx_drop_buf, 1));
+}
+
+static void uart_event_handler(nrf_drv_uart_event_t * p_event,
+ void * p_context)
+{
+ (void)p_context;
+
+ switch (p_event->type)
+ {
+ case NRF_DRV_UART_EVT_ERROR:
+ // Process the error only if this is a parity or overrun error.
+ // Break and framing errors will always occur before the other
+ // side becomes active.
+ if (p_event->data.error.error_mask &
+ (NRF_UART_ERROR_PARITY_MASK | NRF_UART_ERROR_OVERRUN_MASK))
+ {
+ // Pass error source to upper layer.
+ hardware_error_callback(p_event->data.error.error_mask);
+ }
+
+ packet_rx_start();
+ break;
+
+ case NRF_DRV_UART_EVT_TX_DONE:
+ if (p_event->data.rxtx.p_data == m_tx_header_buf)
+ {
+#if (SER_HAL_TRANSPORT_TX_MAX_PKT_SIZE > UART_TRANSFER_MAX)
+ if (m_bytes_to_transmit > UART_TRANSFER_MAX)
+ {
+ APP_ERROR_CHECK(nrf_drv_uart_tx(&m_uart, mp_tx_buffer,
+ UART_TRANSFER_MAX));
+ }
+ else
+#endif // (SER_HAL_TRANSPORT_TX_MAX_PKT_SIZE > UART_TRANSFER_MAX)
+ {
+ APP_ERROR_CHECK(nrf_drv_uart_tx(&m_uart, mp_tx_buffer,
+ m_bytes_to_transmit));
+ }
+ }
+ else
+ {
+#if (SER_HAL_TRANSPORT_TX_MAX_PKT_SIZE > UART_TRANSFER_MAX)
+ ASSERT(p_event->data.rxtx.bytes <= m_bytes_to_transmit);
+ m_bytes_to_transmit -= p_event->data.rxtx.bytes;
+ if (m_bytes_to_transmit != 0)
+ {
+ APP_ERROR_CHECK(nrf_drv_uart_tx(&m_uart,
+ p_event->data.rxtx.p_data + p_event->data.rxtx.bytes,
+ m_bytes_to_transmit < UART_TRANSFER_MAX ?
+ m_bytes_to_transmit : UART_TRANSFER_MAX));
+ }
+ else
+#endif // (SER_HAL_TRANSPORT_TX_MAX_PKT_SIZE > UART_TRANSFER_MAX)
+ {
+ m_tx_in_progress = false;
+ packet_sent_callback();
+ }
+ }
+ break;
+
+ case NRF_DRV_UART_EVT_RX_DONE:
+ if (p_event->data.rxtx.p_data == m_rx_header_buf)
+ {
+ m_bytes_to_receive = uint16_decode(m_rx_header_buf);
+ buffer_request_callback(m_bytes_to_receive);
+ }
+ else if (p_event->data.rxtx.p_data == m_rx_drop_buf)
+ {
+ --m_bytes_to_receive;
+ if (m_bytes_to_receive != 0)
+ {
+ packet_byte_drop();
+ }
+ else
+ {
+ packet_dropped_callback();
+
+ packet_rx_start();
+ }
+ }
+ else
+ {
+#if (SER_HAL_TRANSPORT_RX_MAX_PKT_SIZE > UART_TRANSFER_MAX)
+ ASSERT(p_event->data.rxtx.bytes <= m_bytes_to_receive);
+ m_bytes_to_receive -= p_event->data.rxtx.bytes;
+ if (m_bytes_to_receive != 0)
+ {
+ APP_ERROR_CHECK(nrf_drv_uart_rx(&m_uart,
+ p_event->data.rxtx.p_data + p_event->data.rxtx.bytes,
+ m_bytes_to_receive < UART_TRANSFER_MAX ?
+ m_bytes_to_receive : UART_TRANSFER_MAX));
+ }
+ else
+#endif // (SER_HAL_TRANSPORT_RX_MAX_PKT_SIZE > UART_TRANSFER_MAX)
+ {
+ packet_received_callback();
+
+ packet_rx_start();
+ }
+ }
+ break;
+
+ default:
+ APP_ERROR_CHECK(NRF_ERROR_INTERNAL);
+ }
+}
+
+/** API FUNCTIONS */
+
+uint32_t ser_phy_open(ser_phy_events_handler_t events_handler)
+{
+ uint32_t err_code;
+
+ if (events_handler == NULL)
+ {
+ return NRF_ERROR_NULL;
+ }
+
+ // Check if function was not called before.
+ if (m_ser_phy_event_handler != NULL)
+ {
+ return NRF_ERROR_INVALID_STATE;
+ }
+
+ err_code = nrf_drv_uart_init(&m_uart, &m_uart_config, uart_event_handler);
+ if (err_code != NRF_SUCCESS)
+ {
+ return NRF_ERROR_INVALID_PARAM;
+ }
+
+ m_ser_phy_event_handler = events_handler;
+
+ packet_rx_start();
+
+ return err_code;
+}
+
+uint32_t ser_phy_tx_pkt_send(const uint8_t * p_buffer, uint16_t num_of_bytes)
+{
+ if (p_buffer == NULL)
+ {
+ return NRF_ERROR_NULL;
+ }
+ else if (num_of_bytes == 0)
+ {
+ return NRF_ERROR_INVALID_PARAM;
+ }
+
+ bool busy;
+
+ CRITICAL_REGION_ENTER();
+ busy = m_tx_in_progress;
+ m_tx_in_progress = true;
+ CRITICAL_REGION_EXIT();
+
+ if (busy)
+ {
+ return NRF_ERROR_BUSY;
+ }
+
+ (void)uint16_encode(num_of_bytes, m_tx_header_buf);
+ mp_tx_buffer = p_buffer;
+ m_bytes_to_transmit = num_of_bytes;
+ APP_ERROR_CHECK(nrf_drv_uart_tx(&m_uart, m_tx_header_buf,
+ SER_PHY_HEADER_SIZE));
+
+ return NRF_SUCCESS;
+}
+
+
+uint32_t ser_phy_rx_buf_set(uint8_t * p_buffer)
+{
+
+ if (m_ser_phy_rx_event.evt_type != SER_PHY_EVT_RX_BUF_REQUEST)
+ {
+ return NRF_ERROR_INVALID_STATE;
+ }
+
+ m_ser_phy_rx_event.evt_type = SER_PHY_EVT_RX_PKT_RECEIVED;
+ m_ser_phy_rx_event.evt_params.rx_pkt_received.p_buffer = p_buffer;
+ m_ser_phy_rx_event.evt_params.rx_pkt_received.num_of_bytes =
+ m_bytes_to_receive;
+
+ // If there is not enough memory to receive the packet (no buffer was
+ // provided), drop its data byte by byte (using an internal 1-byte buffer).
+ if (p_buffer == NULL)
+ {
+ packet_byte_drop();
+ }
+#if (SER_HAL_TRANSPORT_RX_MAX_PKT_SIZE > UART_TRANSFER_MAX)
+ else if (m_bytes_to_receive > UART_TRANSFER_MAX)
+ {
+ APP_ERROR_CHECK(nrf_drv_uart_rx(&m_uart, p_buffer, UART_TRANSFER_MAX));
+ }
+#endif // (SER_HAL_TRANSPORT_RX_MAX_PKT_SIZE > UART_TRANSFER_MAX)
+ else
+ {
+ APP_ERROR_CHECK(nrf_drv_uart_rx(&m_uart, p_buffer, m_bytes_to_receive));
+ }
+
+ return NRF_SUCCESS;
+}
+
+
+void ser_phy_close(void)
+{
+ nrf_drv_uart_uninit(&m_uart);
+ m_ser_phy_event_handler = NULL;
+}
+
+
+void ser_phy_interrupts_enable(void)
+{
+ NVIC_EnableIRQ(SER_UART_IRQ);
+}
+
+
+void ser_phy_interrupts_disable(void)
+{
+ NVIC_DisableIRQ(SER_UART_IRQ);
+}
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/common/transport/ser_phy_debug_comm.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/common/transport/ser_phy_debug_comm.h
new file mode 100644
index 0000000..4ec0697
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/common/transport/ser_phy_debug_comm.h
@@ -0,0 +1,203 @@
+/**
+ * Copyright (c) 2014 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#ifndef SER_PHY_DEBUG_COMM_H__
+#define SER_PHY_DEBUG_COMM_H__
+
+#ifndef SER_PHY_HCI_DEBUG_ENABLE
+
+// empty definitions here
+#define DEBUG_EVT_HCI_PHY_EVT_TX_PKT_SENT(data)
+#define DEBUG_EVT_HCI_PHY_EVT_BUF_REQUEST(data)
+#define DEBUG_EVT_HCI_PHY_EVT_RX_PKT_RECEIVED(data)
+#define DEBUG_EVT_HCI_PHY_EVT_RX_PKT_DROPPED(data)
+#define DEBUG_EVT_HCI_PHY_EVT_TX_ERROR(data)
+#define DEBUG_EVT_SLIP_PACKET_TX(data)
+#define DEBUG_EVT_SLIP_ACK_TX(data)
+#define DEBUG_EVT_SLIP_PACKET_TXED(data)
+#define DEBUG_EVT_SLIP_ACK_TXED(data)
+#define DEBUG_EVT_SLIP_PACKET_RXED(data)
+#define DEBUG_EVT_SLIP_ACK_RXED(data)
+#define DEBUG_EVT_SLIP_ERR_RXED(data)
+#define DEBUG_EVT_TIMEOUT(data)
+#define DEBUG_HCI_RETX(data)
+#define DEBUG_EVT_MAIN_BUSY(data)
+#define DEBUG_EVT_TX_REQ(data)
+
+#else
+#include <stdint.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+//Low level hardware events
+typedef enum
+{
+ HCI_PHY_EVT_TX_PKT_SENT,
+ HCI_PHY_EVT_BUF_REQUEST,
+ HCI_PHY_EVT_RX_PKT_RECEIVED,
+ HCI_PHY_EVT_RX_PKT_DROPPED,
+ HCI_PHY_EVT_TX_ERROR,
+ HCI_SLIP_EVT_PACKET_TX,
+ HCI_SLIP_EVT_ACK_TX,
+ HCI_SLIP_EVT_PACKET_TXED,
+ HCI_SLIP_EVT_ACK_TXED,
+ HCI_SLIP_EVT_PACKET_RXED,
+ HCI_SLIP_EVT_ACK_RXED,
+ HCI_SLIP_EVT_ERR_RXED,
+ HCI_TIMER_EVT_TIMEOUT,
+ HCI_RETX,
+ HCI_MAIN_BUSY,
+ HCI_TX_REQ,
+ HCI_PHY_EVT_MAX
+} hci_dbg_evt_type_t;
+
+
+//Low level hardware event definition
+typedef struct
+{
+ hci_dbg_evt_type_t evt;
+ uint32_t data;
+} hci_dbg_evt_t;
+
+typedef void (*hci_dbg_event_handler_t)(hci_dbg_evt_t event);
+
+void debug_init(hci_dbg_event_handler_t evt_callback);
+
+void debug_evt(hci_dbg_evt_type_t evt, uint32_t data);
+
+
+#define DEBUG_EVT(event_type, data) \
+do { \
+ debug_evt(event_type, data); \
+} while (0);
+
+
+#define DEBUG_EVT_HCI_PHY_EVT_TX_PKT_SENT(data) \
+do { \
+ DEBUG_EVT(HCI_PHY_EVT_TX_PKT_SENT, data); \
+} while (0);
+
+
+#define DEBUG_EVT_HCI_PHY_EVT_BUF_REQUEST(data) \
+do { \
+ DEBUG_EVT(HCI_PHY_EVT_BUF_REQUEST, data); \
+} while (0);
+
+
+#define DEBUG_EVT_HCI_PHY_EVT_RX_PKT_RECEIVED(data) \
+do { \
+ DEBUG_EVT(HCI_PHY_EVT_RX_PKT_RECEIVED, data); \
+} while (0);
+
+
+#define DEBUG_EVT_HCI_PHY_EVT_RX_PKT_DROPPED(data) \
+do { \
+ DEBUG_EVT(HCI_PHY_EVT_RX_PKT_DROPPED, data); \
+} while (0);
+
+#define DEBUG_EVT_HCI_PHY_EVT_TX_ERROR(data) \
+do { \
+ DEBUG_EVT(HCI_PHY_EVT_TX_ERROR, data); \
+} while (0);
+
+#define DEBUG_EVT_SLIP_PACKET_TX(data) \
+do { \
+ DEBUG_EVT(HCI_SLIP_EVT_PACKET_TX, data); \
+} while (0);
+
+#define DEBUG_EVT_SLIP_ACK_TX(data) \
+do { \
+ DEBUG_EVT(HCI_SLIP_EVT_ACK_TX, data); \
+} while (0);
+
+#define DEBUG_EVT_SLIP_PACKET_TXED(data) \
+do { \
+ DEBUG_EVT(HCI_SLIP_EVT_PACKET_TXED, data); \
+} while (0);
+
+#define DEBUG_EVT_SLIP_ACK_TXED(data) \
+do { \
+ DEBUG_EVT(HCI_SLIP_EVT_ACK_TXED, data); \
+} while (0);
+
+#define DEBUG_EVT_SLIP_PACKET_RXED(data) \
+do { \
+ DEBUG_EVT(HCI_SLIP_EVT_PACKET_RXED, data); \
+} while (0);
+
+#define DEBUG_EVT_SLIP_ACK_RXED(data) \
+do { \
+ DEBUG_EVT(HCI_SLIP_EVT_ACK_RXED, data); \
+} while (0);
+
+#define DEBUG_EVT_SLIP_ERR_RXED(data) \
+do { \
+ DEBUG_EVT(HCI_SLIP_EVT_ERR_RXED, data); \
+} while (0);
+
+#define DEBUG_EVT_TIMEOUT(data) \
+do { \
+ DEBUG_EVT(HCI_TIMER_EVT_TIMEOUT, data); \
+} while (0);
+
+#define DEBUG_HCI_RETX(data) \
+do { \
+ DEBUG_EVT(HCI_RETX, data); \
+} while (0);
+
+#define DEBUG_EVT_MAIN_BUSY(data) \
+do { \
+ DEBUG_EVT(HCI_MAIN_BUSY, data); \
+} while (0);
+
+#define DEBUG_EVT_TX_REQ(data) \
+do { \
+ DEBUG_EVT(HCI_TX_REQ, data); \
+} while (0);
+
+#endif // SER_PHY_HCI_DEBUG_ENABLE
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // SER_PHY_DEBUG_COMM_H__
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/connectivity/codecs/ant/middleware/conn_mw_ant.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/connectivity/codecs/ant/middleware/conn_mw_ant.c
new file mode 100644
index 0000000..95b9b24
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/connectivity/codecs/ant/middleware/conn_mw_ant.c
@@ -0,0 +1,1196 @@
+/**
+ * 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#include <string.h>
+#include "ant_conn.h"
+#include "conn_mw_ant.h"
+#include "ble_serialization.h"
+#include "nrf_log_ctrl.h"
+#include "sdk_config.h"
+
+#define ANT_BUFFER_SIZE_FOR_SD ANT_ENABLE_GET_REQUIRED_SPACE(ANT_SER_CONFIG_TOTAL_CHANNELS_ALLOCATED, \
+ ANT_SER_CONFIG_ENCRYPTED_CHANNELS, \
+ ANT_SER_CONFIG_BURST_QUEUE_SIZE, \
+ ANT_SER_CONFIG_EVENT_QUEUE_SIZE)
+#define ANT_ADV_BURST_CFG_SIZE_MAX (11u)
+#define ANT_CRYPTO_INFO_SIZE (((MESG_CONFIG_ENCRYPT_REQ_CONFIG_USER_DATA_SIZE) - \
+ (MESG_CHANNEL_NUM_SIZE)) + \
+ ((MESG_CONFIG_ENCRYPT_REQ_CONFIG_ID_SIZE) - \
+ (MESG_CHANNEL_NUM_SIZE)))
+#define ANT_CRYPTO_INFO_MAX_SIZE (MESG_CONFIG_ENCRYPT_REQ_CONFIG_USER_DATA_SIZE - \
+ MESG_CHANNEL_NUM_SIZE)
+
+#ifdef ANT_STACK_SUPPORT_REQD
+static union
+{
+ uint8_t u8[ANT_BUFFER_SIZE_FOR_SD];
+ uint32_t u32[1]; // force allign to uint32_t
+}ant_stack_buffer; /*!< Memory buffer provided in order to support channel configuration */
+#endif
+
+uint32_t conn_mw_ant_enable(uint8_t const * const p_rx_buf,
+ uint32_t rx_buf_len,
+ uint8_t * const p_tx_buf,
+ uint32_t * const p_tx_buf_len)
+{
+ SER_ASSERT_NOT_NULL(p_rx_buf);
+ SER_ASSERT_NOT_NULL(p_tx_buf);
+ SER_ASSERT_NOT_NULL(p_tx_buf_len);
+
+
+ ANT_ENABLE params;
+ ANT_ENABLE * p_params = &params;
+
+ uint32_t err_code = NRF_SUCCESS;
+ uint32_t sd_err_code = 0;
+
+ err_code = ant_enable_req_dec(p_rx_buf, rx_buf_len, &p_params);
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code);
+
+ SER_ASSERT(p_params -> ucTotalNumberOfChannels == ANT_SER_CONFIG_TOTAL_CHANNELS_ALLOCATED, err_code);
+ SER_ASSERT(p_params -> ucNumberOfEncryptedChannels == ANT_SER_CONFIG_ENCRYPTED_CHANNELS, err_code);
+ SER_ASSERT(p_params -> usNumberOfEvents == ANT_SER_CONFIG_EVENT_QUEUE_SIZE, err_code);
+ SER_ASSERT(p_params -> usMemoryBlockByteSize == ANT_BUFFER_SIZE_FOR_SD, err_code);
+
+ ANT_ENABLE m_ant_enable_cfg =
+ {
+ .ucTotalNumberOfChannels = p_params -> ucTotalNumberOfChannels,
+ .ucNumberOfEncryptedChannels = p_params -> ucNumberOfEncryptedChannels,
+ .usNumberOfEvents = p_params -> usNumberOfEvents,
+ .pucMemoryBlockStartLocation = ant_stack_buffer.u8,
+ .usMemoryBlockByteSize = p_params -> usMemoryBlockByteSize
+ };
+
+ sd_err_code = sd_ant_enable(&m_ant_enable_cfg);
+
+ err_code = ant_enable_rsp_enc(sd_err_code, p_tx_buf, p_tx_buf_len);
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code);
+
+ return err_code;
+}
+
+uint32_t conn_ant_channel_assign(uint8_t const * const p_rx_buf,
+ uint32_t rx_buf_len,
+ uint8_t * const p_tx_buf,
+ uint32_t * const p_tx_buf_len)
+{
+ SER_ASSERT_NOT_NULL(p_rx_buf);
+ SER_ASSERT_NOT_NULL(p_tx_buf);
+ SER_ASSERT_NOT_NULL(p_tx_buf_len);
+
+ uint8_t channel;
+ uint8_t type;
+ uint8_t network;
+ uint8_t ext_assign;
+
+ uint32_t err_code = NRF_SUCCESS;
+ uint32_t sd_err_code = 0;
+
+ err_code =ant_channel_assign_req_dec(p_rx_buf, rx_buf_len, &channel, &type, &network, &ext_assign);
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code);
+
+ //disabled till codec is adopted.
+ sd_err_code = sd_ant_channel_assign(channel, type, network, ext_assign);
+
+
+ err_code = ant_channel_assign_rsp_enc(sd_err_code, p_tx_buf, p_tx_buf_len);
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code);
+
+ return err_code;
+
+}
+
+uint32_t conn_ant_channel_open_with_offset(uint8_t const * const p_rx_buf,
+ uint32_t rx_buf_len,
+ uint8_t * const p_tx_buf,
+ uint32_t * const p_tx_buf_len)
+{
+ SER_ASSERT_NOT_NULL(p_rx_buf);
+ SER_ASSERT_NOT_NULL(p_tx_buf);
+ SER_ASSERT_NOT_NULL(p_tx_buf_len);
+
+ uint8_t channel;
+ uint16_t usOffset;
+
+ uint32_t err_code = NRF_SUCCESS;
+ uint32_t sd_err_code = 0;
+
+ err_code = ant_channel_open_with_offset_req_dec(p_rx_buf, rx_buf_len, &channel, &usOffset);
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code);
+
+ sd_err_code = sd_ant_channel_open_with_offset(channel, usOffset);
+
+ err_code = ant_channel_open_with_offset_rsp_enc(sd_err_code, p_tx_buf, p_tx_buf_len);
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code);
+
+ return err_code;
+}
+
+
+uint32_t conn_ant_channel_id_set(uint8_t const * const p_rx_buf,
+ uint32_t rx_buf_len,
+ uint8_t * const p_tx_buf,
+ uint32_t * const p_tx_buf_len)
+{
+ SER_ASSERT_NOT_NULL(p_rx_buf);
+ SER_ASSERT_NOT_NULL(p_tx_buf);
+ SER_ASSERT_NOT_NULL(p_tx_buf_len);
+
+ uint8_t channel;
+ uint16_t device_number;
+ uint8_t device_type;
+ uint8_t transmission_type;
+
+ uint32_t err_code = NRF_SUCCESS;
+ uint32_t sd_err_code = 0;
+
+ err_code =ant_channel_id_set_req_dec(p_rx_buf, rx_buf_len, &channel, &device_number, &device_type, &transmission_type);
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code);
+
+ //disabled till codec is adopted.
+ sd_err_code = sd_ant_channel_id_set(channel, device_number, device_type, transmission_type);
+
+ err_code = ant_channel_id_set_rsp_enc(sd_err_code, p_tx_buf, p_tx_buf_len);
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code);
+
+ return err_code;
+}
+
+uint32_t conn_ant_channel_period_set(uint8_t const * const p_rx_buf,
+ uint32_t rx_buf_len,
+ uint8_t * const p_tx_buf,
+ uint32_t * const p_tx_buf_len)
+{
+ SER_ASSERT_NOT_NULL(p_rx_buf);
+ SER_ASSERT_NOT_NULL(p_tx_buf);
+ SER_ASSERT_NOT_NULL(p_tx_buf_len);
+
+ uint8_t channel;
+ uint16_t period;
+
+ uint32_t err_code = NRF_SUCCESS;
+ uint32_t sd_err_code = 0;
+
+ err_code = ant_channel_period_set_req_dec(p_rx_buf, rx_buf_len, &channel, &period);
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code);
+
+ sd_err_code = sd_ant_channel_period_set(channel, period);
+
+ err_code = ant_channel_period_set_rsp_enc(sd_err_code, p_tx_buf, p_tx_buf_len);
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code);
+
+ return err_code;
+}
+
+uint32_t conn_ant_channel_radio_freq_set(uint8_t const * const p_rx_buf,
+ uint32_t rx_buf_len,
+ uint8_t * const p_tx_buf,
+ uint32_t * const p_tx_buf_len)
+{
+ SER_ASSERT_NOT_NULL(p_rx_buf);
+ SER_ASSERT_NOT_NULL(p_tx_buf);
+ SER_ASSERT_NOT_NULL(p_tx_buf_len);
+
+ uint8_t channel;
+ uint8_t freq;
+
+ uint32_t err_code = NRF_SUCCESS;
+ uint32_t sd_err_code = 0;
+
+ err_code = ant_channel_radio_freq_set_req_dec(p_rx_buf, rx_buf_len, &channel, &freq);
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code);
+
+ sd_err_code = sd_ant_channel_radio_freq_set(channel, freq);
+
+ err_code = ant_channel_radio_freq_set_rsp_enc(sd_err_code, p_tx_buf, p_tx_buf_len);
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code);
+
+ return err_code;
+}
+
+uint32_t conn_ant_broadcast_message_tx(uint8_t const * const p_rx_buf,
+ uint32_t rx_buf_len,
+ uint8_t * const p_tx_buf,
+ uint32_t * const p_tx_buf_len)
+{
+ SER_ASSERT_NOT_NULL(p_rx_buf);
+ SER_ASSERT_NOT_NULL(p_tx_buf);
+ SER_ASSERT_NOT_NULL(p_tx_buf_len);
+
+ uint8_t channel;
+ uint8_t size;
+ uint8_t mesg[ANT_STANDARD_DATA_PAYLOAD_SIZE];
+ uint8_t * p_mesg = mesg;
+
+ uint32_t err_code = NRF_SUCCESS;
+ uint32_t sd_err_code = 0;
+
+ err_code = ant_broadcast_message_tx_req_dec(p_rx_buf, rx_buf_len, &channel, &size, &p_mesg);
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code);
+
+ sd_err_code = sd_ant_broadcast_message_tx(channel, size, p_mesg);
+
+ err_code = ant_broadcast_message_tx_rsp_enc(sd_err_code, p_tx_buf, p_tx_buf_len);
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code);
+
+ return err_code;
+}
+
+uint32_t conn_ant_acknowledge_message_tx(uint8_t const * const p_rx_buf,
+ uint32_t rx_buf_len,
+ uint8_t * const p_tx_buf,
+ uint32_t * const p_tx_buf_len)
+{
+ SER_ASSERT_NOT_NULL(p_rx_buf);
+ SER_ASSERT_NOT_NULL(p_tx_buf);
+ SER_ASSERT_NOT_NULL(p_tx_buf_len);
+
+ uint8_t channel;
+ uint8_t size;
+ uint8_t mesg[ANT_STANDARD_DATA_PAYLOAD_SIZE];
+ uint8_t * p_mesg = mesg;
+
+ uint32_t err_code = NRF_SUCCESS;
+ uint32_t sd_err_code = 0;
+
+ err_code = ant_acknowledge_message_tx_req_dec(p_rx_buf, rx_buf_len, &channel, &size, &p_mesg);
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code);
+
+ sd_err_code = sd_ant_acknowledge_message_tx(channel, size, p_mesg);
+
+ err_code = ant_acknowledge_message_tx_rsp_enc(sd_err_code, p_tx_buf, p_tx_buf_len);
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code);
+
+ return err_code;
+}
+
+uint32_t conn_ant_channel_unassign(uint8_t const * const p_rx_buf,
+ uint32_t rx_buf_len,
+ uint8_t * const p_tx_buf,
+ uint32_t * const p_tx_buf_len)
+{
+ SER_ASSERT_NOT_NULL(p_rx_buf);
+ SER_ASSERT_NOT_NULL(p_tx_buf);
+ SER_ASSERT_NOT_NULL(p_tx_buf_len);
+
+ uint8_t channel;
+
+ uint32_t err_code = NRF_SUCCESS;
+ uint32_t sd_err_code = 0;
+
+ err_code = ant_channel_unassign_req_dec(p_rx_buf, rx_buf_len, &channel);
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code);
+
+ sd_err_code = sd_ant_channel_unassign(channel);
+
+ err_code = ant_channel_unassign_rsp_enc(sd_err_code, p_tx_buf, p_tx_buf_len);
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code);
+
+ return err_code;
+}
+
+uint32_t conn_ant_channel_close(uint8_t const * const p_rx_buf,
+ uint32_t rx_buf_len,
+ uint8_t * const p_tx_buf,
+ uint32_t * const p_tx_buf_len)
+{
+ SER_ASSERT_NOT_NULL(p_rx_buf);
+ SER_ASSERT_NOT_NULL(p_tx_buf);
+ SER_ASSERT_NOT_NULL(p_tx_buf_len);
+
+ uint8_t channel;
+
+ uint32_t err_code = NRF_SUCCESS;
+ uint32_t sd_err_code = 0;
+
+ err_code = ant_channel_close_req_dec(p_rx_buf, rx_buf_len, &channel);
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code);
+
+ sd_err_code = sd_ant_channel_close(channel);
+
+ err_code = ant_channel_close_rsp_enc(sd_err_code, p_tx_buf, p_tx_buf_len);
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code);
+
+ return err_code;
+}
+
+uint32_t conn_ant_network_address_set(uint8_t const * const p_rx_buf,
+ uint32_t rx_buf_len,
+ uint8_t * const p_tx_buf,
+ uint32_t * const p_tx_buf_len)
+{
+ SER_ASSERT_NOT_NULL(p_rx_buf);
+ SER_ASSERT_NOT_NULL(p_tx_buf);
+ SER_ASSERT_NOT_NULL(p_tx_buf_len);
+
+ uint8_t network;
+ uint8_t network_address[MESG_NETWORK_KEY_SIZE - MESG_CHANNEL_NUM_SIZE];
+ uint8_t * p_network_address = network_address;
+
+ uint32_t err_code = NRF_SUCCESS;
+ uint32_t sd_err_code = 0;
+
+ err_code = ant_network_address_set_req_dec(p_rx_buf, rx_buf_len, &network, &p_network_address);
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code);
+
+ sd_err_code = sd_ant_network_address_set(network, p_network_address);
+
+ err_code = ant_network_address_set_rsp_enc(sd_err_code, p_tx_buf, p_tx_buf_len);
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code);
+
+ return err_code;
+}
+
+uint32_t conn_ant_channel_radio_tx_power_set(uint8_t const * const p_rx_buf,
+ uint32_t rx_buf_len,
+ uint8_t * const p_tx_buf,
+ uint32_t * const p_tx_buf_len)
+{
+ SER_ASSERT_NOT_NULL(p_rx_buf);
+ SER_ASSERT_NOT_NULL(p_tx_buf);
+ SER_ASSERT_NOT_NULL(p_tx_buf_len);
+
+ uint8_t channel;
+ uint8_t tx_power;
+ uint8_t custom_tx_power;
+
+ uint32_t err_code = NRF_SUCCESS;
+ uint32_t sd_err_code = 0;
+
+ err_code = ant_channel_radio_tx_power_set_req_dec(p_rx_buf, rx_buf_len, &channel, &tx_power, &custom_tx_power);
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code);
+
+ sd_err_code = sd_ant_channel_radio_tx_power_set(channel, tx_power, custom_tx_power);
+
+ err_code = ant_channel_radio_tx_power_set_rsp_enc(sd_err_code, p_tx_buf, p_tx_buf_len);
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code);
+
+ return err_code;
+}
+
+uint32_t conn_ant_channel_rx_search_timeout_set(uint8_t const * const p_rx_buf,
+ uint32_t rx_buf_len,
+ uint8_t * const p_tx_buf,
+ uint32_t * const p_tx_buf_len)
+{
+ SER_ASSERT_NOT_NULL(p_rx_buf);
+ SER_ASSERT_NOT_NULL(p_tx_buf);
+ SER_ASSERT_NOT_NULL(p_tx_buf_len);
+
+ uint8_t channel;
+ uint8_t timeout;
+
+ uint32_t err_code = NRF_SUCCESS;
+ uint32_t sd_err_code = 0;
+
+ err_code = ant_channel_rx_search_timeout_set_req_dec(p_rx_buf, rx_buf_len, &channel, &timeout);
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code);
+
+ sd_err_code = sd_ant_channel_rx_search_timeout_set(channel, timeout);
+
+ err_code = ant_channel_rx_search_timeout_set_rsp_enc(sd_err_code, p_tx_buf, p_tx_buf_len);
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code);
+
+ return err_code;
+}
+
+uint32_t conn_ant_channel_low_priority_rx_search_timeout_set(uint8_t const * const p_rx_buf,
+ uint32_t rx_buf_len,
+ uint8_t * const p_tx_buf,
+ uint32_t * const p_tx_buf_len)
+{
+ SER_ASSERT_NOT_NULL(p_rx_buf);
+ SER_ASSERT_NOT_NULL(p_tx_buf);
+ SER_ASSERT_NOT_NULL(p_tx_buf_len);
+
+ uint8_t channel;
+ uint8_t timeout;
+
+ uint32_t err_code = NRF_SUCCESS;
+ uint32_t sd_err_code = 0;
+
+ err_code = ant_channel_low_priority_rx_search_timeout_set_req_dec(p_rx_buf, rx_buf_len, &channel, &timeout);
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code);
+
+ sd_err_code = sd_ant_channel_low_priority_rx_search_timeout_set(channel, timeout);
+
+ err_code = ant_channel_low_priority_rx_search_timeout_set_rsp_enc(sd_err_code, p_tx_buf, p_tx_buf_len);
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code);
+
+ return err_code;
+}
+
+uint32_t conn_ant_prox_search_set(uint8_t const * const p_rx_buf,
+ uint32_t rx_buf_len,
+ uint8_t * const p_tx_buf,
+ uint32_t * const p_tx_buf_len)
+{
+ SER_ASSERT_NOT_NULL(p_rx_buf);
+ SER_ASSERT_NOT_NULL(p_tx_buf);
+ SER_ASSERT_NOT_NULL(p_tx_buf_len);
+
+ uint8_t channel;
+ uint8_t prox_threshold;
+ uint8_t custom_prox_threshold;
+
+ uint32_t err_code = NRF_SUCCESS;
+ uint32_t sd_err_code = 0;
+
+ err_code = ant_prox_search_set_req_dec(p_rx_buf, rx_buf_len, &channel, &prox_threshold, &custom_prox_threshold);
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code);
+
+ sd_err_code = sd_ant_prox_search_set(channel, prox_threshold, custom_prox_threshold);
+
+ err_code = ant_prox_search_set_rsp_enc(sd_err_code, p_tx_buf, p_tx_buf_len);
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code);
+
+ return err_code;
+}
+
+uint32_t conn_ant_search_waveform_set(uint8_t const * const p_rx_buf,
+ uint32_t rx_buf_len,
+ uint8_t * const p_tx_buf,
+ uint32_t * const p_tx_buf_len)
+{
+ SER_ASSERT_NOT_NULL(p_rx_buf);
+ SER_ASSERT_NOT_NULL(p_tx_buf);
+ SER_ASSERT_NOT_NULL(p_tx_buf_len);
+
+ uint8_t channel;
+ uint16_t waveform;
+
+ uint32_t err_code = NRF_SUCCESS;
+ uint32_t sd_err_code = 0;
+
+ err_code = ant_search_waveform_set_req_dec(p_rx_buf, rx_buf_len, &channel, &waveform);
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code);
+
+ sd_err_code = sd_ant_search_waveform_set(channel, waveform);
+
+ err_code = ant_search_waveform_set_rsp_enc(sd_err_code, p_tx_buf, p_tx_buf_len);
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code);
+
+ return err_code;
+}
+
+uint32_t conn_ant_channel_id_get(uint8_t const * const p_rx_buf,
+ uint32_t rx_buf_len,
+ uint8_t * const p_tx_buf,
+ uint32_t * const p_tx_buf_len)
+{
+ SER_ASSERT_NOT_NULL(p_rx_buf);
+ SER_ASSERT_NOT_NULL(p_tx_buf);
+ SER_ASSERT_NOT_NULL(p_tx_buf_len);
+
+ uint16_t device_number;
+ uint8_t device_type;
+ uint8_t transmit_type;
+ uint8_t channel;
+ uint16_t * p_device_number = &device_number;
+ uint8_t * p_device_type = &device_type;
+ uint8_t * p_transmit_type = &transmit_type;
+
+ uint32_t err_code = NRF_SUCCESS;
+ uint32_t sd_err_code = 0;
+
+ err_code = ant_channel_id_get_req_dec(p_rx_buf, rx_buf_len, &channel);
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code);
+
+ sd_err_code = sd_ant_channel_id_get(channel, p_device_number, p_device_type, p_transmit_type);
+
+ err_code = ant_channel_id_get_rsp_enc(sd_err_code, p_tx_buf, p_tx_buf_len, p_device_number, p_device_type, p_transmit_type);
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code);
+
+ return err_code;
+}
+
+uint32_t conn_ant_channel_radio_freq_get(uint8_t const * const p_rx_buf,
+ uint32_t rx_buf_len,
+ uint8_t * const p_tx_buf,
+ uint32_t * const p_tx_buf_len)
+{
+ SER_ASSERT_NOT_NULL(p_rx_buf);
+ SER_ASSERT_NOT_NULL(p_tx_buf);
+ SER_ASSERT_NOT_NULL(p_tx_buf_len);
+
+ uint8_t r_freq;
+ uint8_t channel;
+ uint8_t * p_r_freq = &r_freq;
+
+ uint32_t err_code = NRF_SUCCESS;
+ uint32_t sd_err_code = 0;
+
+ err_code = ant_channel_radio_freq_get_req_dec(p_rx_buf, rx_buf_len, &channel);
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code);
+
+ sd_err_code = sd_ant_channel_radio_freq_get(channel, p_r_freq);
+
+ err_code = ant_channel_radio_freq_get_rsp_enc(sd_err_code, p_tx_buf, p_tx_buf_len, p_r_freq);
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code);
+
+ return err_code;
+}
+
+uint32_t conn_ant_channel_period_get(uint8_t const * const p_rx_buf,
+ uint32_t rx_buf_len,
+ uint8_t * const p_tx_buf,
+ uint32_t * const p_tx_buf_len)
+{
+ SER_ASSERT_NOT_NULL(p_rx_buf);
+ SER_ASSERT_NOT_NULL(p_tx_buf);
+ SER_ASSERT_NOT_NULL(p_tx_buf_len);
+
+ uint16_t period;
+ uint8_t channel;
+ uint16_t * p_period = &period;
+
+ uint32_t err_code = NRF_SUCCESS;
+ uint32_t sd_err_code = 0;
+
+ err_code = ant_channel_period_get_req_dec(p_rx_buf, rx_buf_len, &channel);
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code);
+
+ sd_err_code = sd_ant_channel_period_get(channel, p_period);
+
+ err_code = ant_channel_period_get_rsp_enc(sd_err_code, p_tx_buf, p_tx_buf_len, p_period);
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code);
+
+ return err_code;
+}
+
+uint32_t conn_ant_search_channel_priority_set(uint8_t const * const p_rx_buf,
+ uint32_t rx_buf_len,
+ uint8_t * const p_tx_buf,
+ uint32_t * const p_tx_buf_len)
+{
+ SER_ASSERT_NOT_NULL(p_rx_buf);
+ SER_ASSERT_NOT_NULL(p_tx_buf);
+ SER_ASSERT_NOT_NULL(p_tx_buf_len);
+
+ uint8_t channel;
+ uint8_t search_priority;
+
+ uint32_t err_code = NRF_SUCCESS;
+ uint32_t sd_err_code = 0;
+
+ err_code = ant_search_channel_priority_set_req_dec(p_rx_buf, rx_buf_len, &channel, &search_priority);
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code);
+
+ sd_err_code = sd_ant_search_channel_priority_set(channel, search_priority);
+
+ err_code = ant_search_channel_priority_set_rsp_enc(sd_err_code, p_tx_buf, p_tx_buf_len);
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code);
+
+ return err_code;
+}
+
+uint32_t conn_ant_active_search_sharing_cycles_set(uint8_t const * const p_rx_buf,
+ uint32_t rx_buf_len,
+ uint8_t * const p_tx_buf,
+ uint32_t * const p_tx_buf_len)
+{
+ SER_ASSERT_NOT_NULL(p_rx_buf);
+ SER_ASSERT_NOT_NULL(p_tx_buf);
+ SER_ASSERT_NOT_NULL(p_tx_buf_len);
+
+ uint8_t channel;
+ uint8_t cycles;
+
+ uint32_t err_code = NRF_SUCCESS;
+ uint32_t sd_err_code = 0;
+
+ err_code = ant_active_search_sharing_cycles_set_req_dec(p_rx_buf, rx_buf_len, &channel, &cycles);
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code);
+
+ sd_err_code = sd_ant_active_search_sharing_cycles_set(channel, cycles);
+
+ err_code = ant_active_search_sharing_cycles_set_rsp_enc(sd_err_code, p_tx_buf, p_tx_buf_len);
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code);
+
+ return err_code;
+}
+
+uint32_t conn_ant_lib_config_set(uint8_t const * const p_rx_buf,
+ uint32_t rx_buf_len,
+ uint8_t * const p_tx_buf,
+ uint32_t * const p_tx_buf_len)
+{
+ SER_ASSERT_NOT_NULL(p_rx_buf);
+ SER_ASSERT_NOT_NULL(p_tx_buf);
+ SER_ASSERT_NOT_NULL(p_tx_buf_len);
+
+ uint8_t ant_lib_config;
+
+ uint32_t err_code = NRF_SUCCESS;
+ uint32_t sd_err_code = 0;
+
+ err_code = ant_lib_config_set_req_dec(p_rx_buf, rx_buf_len, &ant_lib_config);
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code);
+
+ sd_err_code = sd_ant_lib_config_set(ant_lib_config);
+
+ err_code = ant_lib_config_set_rsp_enc(sd_err_code, p_tx_buf, p_tx_buf_len);
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code);
+
+ return err_code;
+}
+
+uint32_t conn_ant_active_search_sharing_cycles_get(uint8_t const * const p_rx_buf,
+ uint32_t rx_buf_len,
+ uint8_t * const p_tx_buf,
+ uint32_t * const p_tx_buf_len)
+{
+ SER_ASSERT_NOT_NULL(p_rx_buf);
+ SER_ASSERT_NOT_NULL(p_tx_buf);
+ SER_ASSERT_NOT_NULL(p_tx_buf_len);
+
+ uint8_t cycles;
+ uint8_t channel;
+ uint8_t * p_cycles = &cycles;
+
+ uint32_t err_code = NRF_SUCCESS;
+ uint32_t sd_err_code = 0;
+
+ err_code = ant_active_search_sharing_cycles_get_req_dec(p_rx_buf, rx_buf_len, &channel);
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code);
+
+ sd_err_code = sd_ant_active_search_sharing_cycles_get(channel, p_cycles);
+
+ err_code = ant_active_search_sharing_cycles_get_rsp_enc(sd_err_code, p_tx_buf, p_tx_buf_len, p_cycles);
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code);
+
+ return err_code;
+}
+
+uint32_t conn_ant_lib_config_get(uint8_t const * const p_rx_buf,
+ uint32_t rx_buf_len,
+ uint8_t * const p_tx_buf,
+ uint32_t * const p_tx_buf_len)
+{
+ SER_ASSERT_NOT_NULL(p_rx_buf);
+ SER_ASSERT_NOT_NULL(p_tx_buf);
+ SER_ASSERT_NOT_NULL(p_tx_buf_len);
+
+ uint8_t ant_lib_config;
+ uint8_t * p_ant_lib_config = &ant_lib_config;
+
+ uint32_t err_code = NRF_SUCCESS;
+ uint32_t sd_err_code = 0;
+
+ sd_err_code = sd_ant_lib_config_get(p_ant_lib_config);
+
+ err_code = ant_lib_config_get_rsp_enc(sd_err_code, p_tx_buf, p_tx_buf_len, p_ant_lib_config);
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code);
+
+ return err_code;
+}
+
+uint32_t conn_ant_lib_config_clear(uint8_t const * const p_rx_buf,
+ uint32_t rx_buf_len,
+ uint8_t * const p_tx_buf,
+ uint32_t * const p_tx_buf_len)
+{
+ SER_ASSERT_NOT_NULL(p_rx_buf);
+ SER_ASSERT_NOT_NULL(p_tx_buf);
+ SER_ASSERT_NOT_NULL(p_tx_buf_len);
+
+ uint8_t ant_lib_config;
+
+ uint32_t err_code = NRF_SUCCESS;
+ uint32_t sd_err_code = 0;
+
+ err_code = ant_lib_config_clear_req_dec(p_rx_buf, rx_buf_len, &ant_lib_config);
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code);
+
+ sd_err_code = sd_ant_lib_config_clear(ant_lib_config);
+
+ err_code = ant_lib_config_clear_rsp_enc(sd_err_code, p_tx_buf, p_tx_buf_len);
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code);
+
+ return err_code;
+}
+
+uint32_t conn_ant_stack_reset(uint8_t const * const p_rx_buf,
+ uint32_t rx_buf_len,
+ uint8_t * const p_tx_buf,
+ uint32_t * const p_tx_buf_len)
+{
+ SER_ASSERT_NOT_NULL(p_rx_buf);
+ SER_ASSERT_NOT_NULL(p_tx_buf);
+ SER_ASSERT_NOT_NULL(p_tx_buf_len);
+
+ uint32_t err_code = NRF_SUCCESS;
+ uint32_t sd_err_code = 0;
+
+ sd_err_code = sd_ant_stack_reset();
+
+ err_code = ant_stack_reset_rsp_enc(sd_err_code, p_tx_buf, p_tx_buf_len);
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code);
+
+ return err_code;
+}
+
+uint32_t conn_ant_rx_scan_mode_start(uint8_t const * const p_rx_buf,
+ uint32_t rx_buf_len,
+ uint8_t * const p_tx_buf,
+ uint32_t * const p_tx_buf_len)
+{
+ SER_ASSERT_NOT_NULL(p_rx_buf);
+ SER_ASSERT_NOT_NULL(p_tx_buf);
+ SER_ASSERT_NOT_NULL(p_tx_buf_len);
+
+ uint8_t sync_channel_packets_only;
+
+ uint32_t err_code = NRF_SUCCESS;
+ uint32_t sd_err_code = 0;
+
+ err_code = ant_rx_scan_mode_start_req_dec(p_rx_buf, rx_buf_len, &sync_channel_packets_only);
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code);
+
+ sd_err_code = sd_ant_rx_scan_mode_start(sync_channel_packets_only);
+
+ err_code = ant_rx_scan_mode_start_rsp_enc(sd_err_code, p_tx_buf, p_tx_buf_len);
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code);
+
+ return err_code;
+}
+
+uint32_t conn_ant_id_list_add(uint8_t const * const p_rx_buf,
+ uint32_t rx_buf_len,
+ uint8_t * const p_tx_buf,
+ uint32_t * const p_tx_buf_len)
+{
+ SER_ASSERT_NOT_NULL(p_rx_buf);
+ SER_ASSERT_NOT_NULL(p_tx_buf);
+ SER_ASSERT_NOT_NULL(p_tx_buf_len);
+
+ uint8_t channel;
+ uint8_t dev_id[ANT_ID_SIZE];
+ uint8_t * p_dev_id = dev_id;
+ uint8_t list_index;
+
+ uint32_t err_code = NRF_SUCCESS;
+ uint32_t sd_err_code = 0;
+
+ err_code = ant_id_list_add_req_dec(p_rx_buf, rx_buf_len, &channel, &p_dev_id, &list_index);
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code);
+
+ sd_err_code = sd_ant_id_list_add(channel, p_dev_id, list_index);
+
+ err_code = ant_id_list_add_rsp_enc(sd_err_code, p_tx_buf, p_tx_buf_len);
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code);
+
+ return err_code;
+}
+
+uint32_t conn_ant_id_list_config(uint8_t const * const p_rx_buf,
+ uint32_t rx_buf_len,
+ uint8_t * const p_tx_buf,
+ uint32_t * const p_tx_buf_len)
+{
+ SER_ASSERT_NOT_NULL(p_rx_buf);
+ SER_ASSERT_NOT_NULL(p_tx_buf);
+ SER_ASSERT_NOT_NULL(p_tx_buf_len);
+
+ uint8_t channel;
+ uint8_t id_list_size;
+ uint8_t inc_exc_flag;
+
+ uint32_t err_code = NRF_SUCCESS;
+ uint32_t sd_err_code = 0;
+
+ err_code = ant_id_list_config_req_dec(p_rx_buf, rx_buf_len, &channel, &id_list_size, &inc_exc_flag);
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code);
+
+ sd_err_code = sd_ant_id_list_config(channel, id_list_size, inc_exc_flag);
+
+ err_code = ant_id_list_config_rsp_enc(sd_err_code, p_tx_buf, p_tx_buf_len);
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code);
+
+ return err_code;
+}
+
+uint32_t conn_ant_channel_status_get(uint8_t const * const p_rx_buf,
+ uint32_t rx_buf_len,
+ uint8_t * const p_tx_buf,
+ uint32_t * const p_tx_buf_len)
+{
+ SER_ASSERT_NOT_NULL(p_rx_buf);
+ SER_ASSERT_NOT_NULL(p_tx_buf);
+ SER_ASSERT_NOT_NULL(p_tx_buf_len);
+
+ uint8_t status;
+ uint8_t channel;
+ uint8_t * p_status = &status;
+
+ uint32_t err_code = NRF_SUCCESS;
+ uint32_t sd_err_code = 0;
+
+ err_code = ant_channel_status_get_req_dec(p_rx_buf, rx_buf_len, &channel);
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code);
+
+ sd_err_code = sd_ant_channel_status_get(channel, p_status);
+
+ err_code = ant_channel_status_get_rsp_enc(sd_err_code, p_tx_buf, p_tx_buf_len, p_status);
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code);
+
+ return err_code;
+}
+
+uint32_t conn_ant_cw_test_mode_init(uint8_t const * const p_rx_buf,
+ uint32_t rx_buf_len,
+ uint8_t * const p_tx_buf,
+ uint32_t * const p_tx_buf_len)
+{
+ SER_ASSERT_NOT_NULL(p_rx_buf);
+ SER_ASSERT_NOT_NULL(p_tx_buf);
+ SER_ASSERT_NOT_NULL(p_tx_buf_len);
+
+ uint32_t err_code = NRF_SUCCESS;
+ uint32_t sd_err_code = 0;
+
+ sd_err_code = sd_ant_cw_test_mode_init();
+
+ err_code = ant_cw_test_mode_init_rsp_enc(sd_err_code, p_tx_buf, p_tx_buf_len);
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code);
+
+ return err_code;
+}
+
+uint32_t conn_ant_cw_test_mode(uint8_t const * const p_rx_buf,
+ uint32_t rx_buf_len,
+ uint8_t * const p_tx_buf,
+ uint32_t * const p_tx_buf_len)
+{
+ SER_ASSERT_NOT_NULL(p_rx_buf);
+ SER_ASSERT_NOT_NULL(p_tx_buf);
+ SER_ASSERT_NOT_NULL(p_tx_buf_len);
+
+ uint8_t radio_freq;
+ uint8_t tx_power;
+ uint8_t custom_tx_power;
+ uint8_t mode;
+
+ uint32_t err_code = NRF_SUCCESS;
+ uint32_t sd_err_code = 0;
+
+ err_code = ant_cw_test_mode_req_dec(p_rx_buf, rx_buf_len, &radio_freq, &tx_power, &custom_tx_power, &mode);
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code);
+
+ sd_err_code = sd_ant_cw_test_mode(radio_freq, tx_power, custom_tx_power, mode);
+
+ err_code = ant_cw_test_mode_rsp_enc(sd_err_code, p_tx_buf, p_tx_buf_len);
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code);
+
+ return err_code;
+}
+
+uint32_t conn_ant_version_get(uint8_t const * const p_rx_buf,
+ uint32_t rx_buf_len,
+ uint8_t * const p_tx_buf,
+ uint32_t * const p_tx_buf_len)
+{
+ SER_ASSERT_NOT_NULL(p_rx_buf);
+ SER_ASSERT_NOT_NULL(p_tx_buf);
+ SER_ASSERT_NOT_NULL(p_tx_buf_len);
+
+ uint8_t version[MESG_BUFFER_SIZE];
+ memset(version, 0, sizeof(version));
+
+ uint32_t err_code = NRF_SUCCESS;
+ uint32_t sd_err_code = 0;
+
+ sd_err_code = sd_ant_version_get(version);
+
+ err_code = ant_version_get_rsp_enc(sd_err_code, p_tx_buf, p_tx_buf_len, version);
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code);
+
+ return err_code;
+}
+
+uint32_t conn_ant_capabilities_get(uint8_t const * const p_rx_buf,
+ uint32_t rx_buf_len,
+ uint8_t * const p_tx_buf,
+ uint32_t * const p_tx_buf_len)
+{
+ SER_ASSERT_NOT_NULL(p_rx_buf);
+ SER_ASSERT_NOT_NULL(p_tx_buf);
+ SER_ASSERT_NOT_NULL(p_tx_buf_len);
+
+ uint8_t capabilities[MESG_CAPABILITIES_SIZE];
+ memset(capabilities, 0, sizeof(capabilities));
+
+ uint32_t err_code = NRF_SUCCESS;
+ uint32_t sd_err_code = 0;
+
+ sd_err_code = sd_ant_capabilities_get(capabilities);
+
+ err_code = ant_capabilities_get_rsp_enc(sd_err_code, p_tx_buf, p_tx_buf_len, capabilities);
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code);
+
+ return err_code;
+}
+
+uint32_t conn_ant_crypto_channel_enable(uint8_t const * const p_rx_buf,
+ uint32_t rx_buf_len,
+ uint8_t * const p_tx_buf,
+ uint32_t * const p_tx_buf_len)
+{
+ SER_ASSERT_NOT_NULL(p_rx_buf);
+ SER_ASSERT_NOT_NULL(p_tx_buf);
+ SER_ASSERT_NOT_NULL(p_tx_buf_len);
+
+ uint8_t channel;
+ uint8_t enable;
+ uint8_t key_num;
+ uint8_t decimation_rate;
+
+ uint32_t err_code = NRF_SUCCESS;
+ uint32_t sd_err_code = 0;
+
+ err_code = ant_crypto_channel_enable_req_dec(p_rx_buf, rx_buf_len, &channel, &enable, &key_num, &decimation_rate);
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code);
+
+ sd_err_code = sd_ant_crypto_channel_enable(channel, enable, key_num, decimation_rate);
+
+ err_code = ant_crypto_channel_enable_rsp_enc(sd_err_code, p_tx_buf, p_tx_buf_len);
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code);
+
+ return err_code;
+}
+
+uint32_t conn_ant_adv_burst_config_set(uint8_t const * const p_rx_buf,
+ uint32_t rx_buf_len,
+ uint8_t * const p_tx_buf,
+ uint32_t * const p_tx_buf_len)
+{
+ SER_ASSERT_NOT_NULL(p_rx_buf);
+ SER_ASSERT_NOT_NULL(p_tx_buf);
+ SER_ASSERT_NOT_NULL(p_tx_buf_len);
+
+ uint8_t size;
+ uint8_t config[ANT_ADV_BURST_CFG_SIZE_MAX];
+
+ uint32_t err_code = NRF_SUCCESS;
+ uint32_t sd_err_code = 0;
+
+ err_code = ant_adv_burst_config_set_req_dec(p_rx_buf, rx_buf_len, config, &size);
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code);
+
+ sd_err_code = sd_ant_adv_burst_config_set(config, size);
+
+ err_code = ant_adv_burst_config_set_rsp_enc(sd_err_code, p_tx_buf, p_tx_buf_len);
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code);
+
+ return err_code;
+}
+
+uint32_t conn_ant_crypto_key_set(uint8_t const * const p_rx_buf,
+ uint32_t rx_buf_len,
+ uint8_t * const p_tx_buf,
+ uint32_t * const p_tx_buf_len)
+{
+ SER_ASSERT_NOT_NULL(p_rx_buf);
+ SER_ASSERT_NOT_NULL(p_tx_buf);
+ SER_ASSERT_NOT_NULL(p_tx_buf_len);
+
+ uint8_t key_num;
+ uint8_t key[SIZE_OF_ENCRYPTED_KEY];
+ uint8_t * p_key = key;
+
+ uint32_t err_code = NRF_SUCCESS;
+ uint32_t sd_err_code = 0;
+
+ err_code = ant_crypto_key_set_req_dec(p_rx_buf, rx_buf_len, &key_num, &p_key);
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code);
+
+ sd_err_code = sd_ant_crypto_key_set(key_num, p_key);
+
+ err_code = ant_crypto_key_set_rsp_enc(sd_err_code, p_tx_buf, p_tx_buf_len);
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code);
+
+ return err_code;
+}
+
+uint32_t conn_ant_crypto_info_set(uint8_t const * const p_rx_buf,
+ uint32_t rx_buf_len,
+ uint8_t * const p_tx_buf,
+ uint32_t * const p_tx_buf_len)
+{
+ SER_ASSERT_NOT_NULL(p_rx_buf);
+ SER_ASSERT_NOT_NULL(p_tx_buf);
+ SER_ASSERT_NOT_NULL(p_tx_buf_len);
+
+ uint8_t type;
+ uint8_t info[ANT_CRYPTO_INFO_SIZE];
+ uint8_t * p_info = info;
+
+ uint32_t err_code = NRF_SUCCESS;
+ uint32_t sd_err_code = 0;
+
+ err_code = ant_crypto_info_set_req_dec(p_rx_buf, rx_buf_len, &type, &p_info);
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code);
+
+ sd_err_code = sd_ant_crypto_info_set(type, p_info);
+
+ err_code = ant_crypto_info_set_rsp_enc(sd_err_code, p_tx_buf, p_tx_buf_len);
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code);
+
+ return err_code;
+}
+
+uint32_t conn_ant_crypto_info_get(uint8_t const * const p_rx_buf,
+ uint32_t rx_buf_len,
+ uint8_t * const p_tx_buf,
+ uint32_t * const p_tx_buf_len)
+{
+ SER_ASSERT_NOT_NULL(p_rx_buf);
+ SER_ASSERT_NOT_NULL(p_tx_buf);
+ SER_ASSERT_NOT_NULL(p_tx_buf_len);
+
+ uint8_t type;
+ uint8_t info[ANT_CRYPTO_INFO_MAX_SIZE];
+ memset(info, 0, sizeof(info));
+
+ uint32_t err_code = NRF_SUCCESS;
+ uint32_t sd_err_code = 0;
+
+ err_code = ant_crypto_info_get_req_dec(p_rx_buf, rx_buf_len, &type);
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code);
+
+ sd_err_code = sd_ant_crypto_info_get(type, info);
+
+ err_code = ant_crypto_info_get_rsp_enc(sd_err_code, p_tx_buf, p_tx_buf_len, type, info);
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code);
+
+ return err_code;
+}
+
+uint32_t conn_ant_coex_config_set(uint8_t const * const p_rx_buf,
+ uint32_t rx_buf_len,
+ uint8_t * const p_tx_buf,
+ uint32_t * const p_tx_buf_len)
+{
+ SER_ASSERT_NOT_NULL(p_rx_buf);
+ SER_ASSERT_NOT_NULL(p_tx_buf);
+ SER_ASSERT_NOT_NULL(p_tx_buf_len);
+
+ uint8_t channel;
+ uint8_t coex_config_buffer[(MESG_BUFFER_SIZE / 2) - 1];
+ uint8_t adv_coex_config_buffer[(MESG_BUFFER_SIZE / 2) - 1];
+
+ ANT_BUFFER_PTR coex_config =
+ {
+ .ucBufferSize = 0,
+ .pucBuffer = coex_config_buffer
+ };
+
+ ANT_BUFFER_PTR adv_coex_config =
+ {
+ .ucBufferSize = 0,
+ .pucBuffer = adv_coex_config_buffer
+ };
+
+ uint32_t err_code = NRF_SUCCESS;
+ uint32_t sd_err_code = 0;
+
+ err_code = ant_coex_config_set_req_dec(p_rx_buf, rx_buf_len, &channel, &coex_config, &adv_coex_config);
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code);
+
+ if (coex_config.ucBufferSize == 0 && adv_coex_config.ucBufferSize == 0)
+ {
+ sd_err_code = sd_ant_coex_config_set(channel, NULL, NULL);
+ }
+ else if (coex_config.ucBufferSize == 0)
+ {
+ sd_err_code = sd_ant_coex_config_set(channel, NULL, &adv_coex_config);
+ }
+ else if (adv_coex_config.ucBufferSize == 0)
+ {
+ sd_err_code = sd_ant_coex_config_set(channel, &coex_config, NULL);
+ }
+ else
+ {
+ sd_err_code = sd_ant_coex_config_set(channel, &coex_config, &adv_coex_config);
+ }
+
+ err_code = ant_coex_config_set_rsp_enc(sd_err_code, p_tx_buf, p_tx_buf_len);
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code);
+
+ return err_code;
+}
+
+uint32_t conn_ant_coex_config_get(uint8_t const * const p_rx_buf,
+ uint32_t rx_buf_len,
+ uint8_t * const p_tx_buf,
+ uint32_t * const p_tx_buf_len)
+{
+ SER_ASSERT_NOT_NULL(p_rx_buf);
+ SER_ASSERT_NOT_NULL(p_tx_buf);
+ SER_ASSERT_NOT_NULL(p_tx_buf_len);
+
+ uint8_t channel;
+ uint8_t coex_config_buffer[(MESG_BUFFER_SIZE / 2) - 1];
+ uint8_t adv_coex_config_buffer[(MESG_BUFFER_SIZE / 2) - 1];
+
+ ANT_BUFFER_PTR coex_config =
+ {
+ .ucBufferSize = sizeof(coex_config_buffer),
+ .pucBuffer = coex_config_buffer
+ };
+
+ ANT_BUFFER_PTR adv_coex_config =
+ {
+ .ucBufferSize = sizeof(adv_coex_config_buffer),
+ .pucBuffer = adv_coex_config_buffer
+ };
+
+ uint32_t err_code = NRF_SUCCESS;
+ uint32_t sd_err_code = 0;
+
+ err_code = ant_coex_config_get_req_dec(p_rx_buf, rx_buf_len, &channel);
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code);
+
+ sd_err_code = sd_ant_coex_config_get(channel, &coex_config, &adv_coex_config);
+
+ err_code = ant_coex_config_get_rsp_enc(sd_err_code, p_tx_buf, p_tx_buf_len, &coex_config, &adv_coex_config);
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code);
+
+ return err_code;
+}
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/connectivity/codecs/ant/middleware/conn_mw_ant.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/connectivity/codecs/ant/middleware/conn_mw_ant.h
new file mode 100644
index 0000000..93e9130
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/connectivity/codecs/ant/middleware/conn_mw_ant.h
@@ -0,0 +1,793 @@
+/**
+ * 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#ifndef _CONN_MW_ANT_H
+#define _CONN_MW_ANT_H
+
+#include <stdint.h>
+
+/**
+ * @addtogroup sercon_mw_ant Connectivity middleware codecs for S212 (connectivity side)
+ * @{
+ * @ingroup ser_codecs_mw
+ */
+
+
+/**@brief Handles @ref sd_ant_enable command and prepares response.
+ *
+ * @param[in] p_rx_buf Pointer to input buffer.
+ * @param[in] rx_buf_len Size of @p p_rx_buf.
+ * @param[out] p_tx_buf Pointer to output buffer.
+ * @param[in,out] p_tx_buf_len \c in: Size of \p p_tx_buf buffer.
+ * \c out: Length of valid data in \p p_tx_buf.
+ *
+ * @retval NRF_SUCCESS Handler success.
+ * @retval NRF_ERROR_NULL Handler failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Handler failure. Incorrect buffer length.
+ * @retval NRF_ERROR_INVALID_PARAM Handler failure. Invalid operation type.
+ */
+uint32_t conn_mw_ant_enable(uint8_t const * const p_rx_buf,
+ uint32_t rx_buf_len,
+ uint8_t * const p_tx_buf,
+ uint32_t * const p_tx_buf_len);
+
+/**@brief Handles @ref sd_ant_channel_assign command and prepares response.
+ *
+ * @param[in] p_rx_buf Pointer to input buffer.
+ * @param[in] rx_buf_len Size of @p p_rx_buf.
+ * @param[out] p_tx_buf Pointer to output buffer.
+ * @param[in,out] p_tx_buf_len \c in: Size of \p p_tx_buf buffer.
+ * \c out: Length of valid data in \p p_tx_buf.
+ *
+ * @retval NRF_SUCCESS Handler success.
+ * @retval NRF_ERROR_NULL Handler failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Handler failure. Incorrect buffer length.
+ * @retval NRF_ERROR_INVALID_PARAM Handler failure. Invalid operation type.
+ */
+uint32_t conn_ant_channel_assign(uint8_t const * const p_rx_buf,
+ uint32_t rx_buf_len,
+ uint8_t * const p_tx_buf,
+ uint32_t * const p_tx_buf_len);
+
+/**@brief Handles @ref sd_ant_channel_open command and prepares response.
+ *
+ * @param[in] p_rx_buf Pointer to input buffer.
+ * @param[in] rx_buf_len Size of @p p_rx_buf.
+ * @param[out] p_tx_buf Pointer to output buffer.
+ * @param[in,out] p_tx_buf_len \c in: Size of \p p_tx_buf buffer.
+ * \c out: Length of valid data in \p p_tx_buf.
+ *
+ * @retval NRF_SUCCESS Handler success.
+ * @retval NRF_ERROR_NULL Handler failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Handler failure. Incorrect buffer length.
+ * @retval NRF_ERROR_INVALID_PARAM Handler failure. Invalid operation type.
+ */
+uint32_t conn_ant_channel_open_with_offset(uint8_t const * const p_rx_buf,
+ uint32_t rx_buf_len,
+ uint8_t * const p_tx_buf,
+ uint32_t * const p_tx_buf_len);
+
+/**@brief Handles @ref sd_ant_channel_id_set command and prepares response.
+ *
+ * @param[in] p_rx_buf Pointer to input buffer.
+ * @param[in] rx_buf_len Size of @p p_rx_buf.
+ * @param[out] p_tx_buf Pointer to output buffer.
+ * @param[in,out] p_tx_buf_len \c in: Size of \p p_tx_buf buffer.
+ * \c out: Length of valid data in \p p_tx_buf.
+ *
+ * @retval NRF_SUCCESS Handler success.
+ * @retval NRF_ERROR_NULL Handler failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Handler failure. Incorrect buffer length.
+ * @retval NRF_ERROR_INVALID_PARAM Handler failure. Invalid operation type.
+ */
+uint32_t conn_ant_channel_id_set(uint8_t const * const p_rx_buf,
+ uint32_t rx_buf_len,
+ uint8_t * const p_tx_buf,
+ uint32_t * const p_tx_buf_len);
+
+/**@brief Handles @ref sd_ant_channel_period_set command and prepares response.
+ *
+ * @param[in] p_rx_buf Pointer to input buffer.
+ * @param[in] rx_buf_len Size of @p p_rx_buf.
+ * @param[out] p_tx_buf Pointer to output buffer.
+ * @param[in,out] p_tx_buf_len \c in: Size of \p p_tx_buf buffer.
+ * \c out: Length of valid data in \p p_tx_buf.
+ *
+ * @retval NRF_SUCCESS Handler success.
+ * @retval NRF_ERROR_NULL Handler failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Handler failure. Incorrect buffer length.
+ * @retval NRF_ERROR_INVALID_PARAM Handler failure. Invalid operation type.
+ */
+uint32_t conn_ant_channel_period_set(uint8_t const * const p_rx_buf,
+ uint32_t rx_buf_len,
+ uint8_t * const p_tx_buf,
+ uint32_t * const p_tx_buf_len);
+
+/**@brief Handles @ref sd_ant_channel_radio_freq_set command and prepares response.
+ *
+ * @param[in] p_rx_buf Pointer to input buffer.
+ * @param[in] rx_buf_len Size of @p p_rx_buf.
+ * @param[out] p_tx_buf Pointer to output buffer.
+ * @param[in,out] p_tx_buf_len \c in: Size of \p p_tx_buf buffer.
+ * \c out: Length of valid data in \p p_tx_buf.
+ *
+ * @retval NRF_SUCCESS Handler success.
+ * @retval NRF_ERROR_NULL Handler failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Handler failure. Incorrect buffer length.
+ * @retval NRF_ERROR_INVALID_PARAM Handler failure. Invalid operation type.
+ */
+uint32_t conn_ant_channel_radio_freq_set(uint8_t const * const p_rx_buf,
+ uint32_t rx_buf_len,
+ uint8_t * const p_tx_buf,
+ uint32_t * const p_tx_buf_len);
+
+/**@brief Handles @ref sd_ant_broadcast_message_tx command and prepares response.
+ *
+ * @param[in] p_rx_buf Pointer to input buffer.
+ * @param[in] rx_buf_len Size of @p p_rx_buf.
+ * @param[out] p_tx_buf Pointer to output buffer.
+ * @param[in,out] p_tx_buf_len \c in: Size of \p p_tx_buf buffer.
+ * \c out: Length of valid data in \p p_tx_buf.
+ *
+ * @retval NRF_SUCCESS Handler success.
+ * @retval NRF_ERROR_NULL Handler failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Handler failure. Incorrect buffer length.
+ * @retval NRF_ERROR_INVALID_PARAM Handler failure. Invalid operation type.
+ */
+uint32_t conn_ant_broadcast_message_tx(uint8_t const * const p_rx_buf,
+ uint32_t rx_buf_len,
+ uint8_t * const p_tx_buf,
+ uint32_t * const p_tx_buf_len);
+
+/**@brief Handles @ref sd_ant_acknowledge_message_tx command and prepares response.
+ *
+ * @param[in] p_rx_buf Pointer to input buffer.
+ * @param[in] rx_buf_len Size of @p p_rx_buf.
+ * @param[out] p_tx_buf Pointer to output buffer.
+ * @param[in,out] p_tx_buf_len \c in: Size of \p p_tx_buf buffer.
+ * \c out: Length of valid data in \p p_tx_buf.
+ *
+ * @retval NRF_SUCCESS Handler success.
+ * @retval NRF_ERROR_NULL Handler failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Handler failure. Incorrect buffer length.
+ * @retval NRF_ERROR_INVALID_PARAM Handler failure. Invalid operation type.
+ */
+uint32_t conn_ant_acknowledge_message_tx(uint8_t const * const p_rx_buf,
+ uint32_t rx_buf_len,
+ uint8_t * const p_tx_buf,
+ uint32_t * const p_tx_buf_len);
+
+/**@brief Handles @ref sd_ant_channel_unassign command and prepares response.
+ *
+ * @param[in] p_rx_buf Pointer to input buffer.
+ * @param[in] rx_buf_len Size of @p p_rx_buf.
+ * @param[out] p_tx_buf Pointer to output buffer.
+ * @param[in,out] p_tx_buf_len \c in: Size of \p p_tx_buf buffer.
+ * \c out: Length of valid data in \p p_tx_buf.
+ *
+ * @retval NRF_SUCCESS Handler success.
+ * @retval NRF_ERROR_NULL Handler failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Handler failure. Incorrect buffer length.
+ * @retval NRF_ERROR_INVALID_PARAM Handler failure. Invalid operation type.
+ */
+uint32_t conn_ant_channel_unassign(uint8_t const * const p_rx_buf,
+ uint32_t rx_buf_len,
+ uint8_t * const p_tx_buf,
+ uint32_t * const p_tx_buf_len);
+
+/**@brief Handles @ref sd_ant_channel_close command and prepares response.
+ *
+ * @param[in] p_rx_buf Pointer to input buffer.
+ * @param[in] rx_buf_len Size of @p p_rx_buf.
+ * @param[out] p_tx_buf Pointer to output buffer.
+ * @param[in,out] p_tx_buf_len \c in: Size of \p p_tx_buf buffer.
+ * \c out: Length of valid data in \p p_tx_buf.
+ *
+ * @retval NRF_SUCCESS Handler success.
+ * @retval NRF_ERROR_NULL Handler failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Handler failure. Incorrect buffer length.
+ * @retval NRF_ERROR_INVALID_PARAM Handler failure. Invalid operation type.
+ */
+uint32_t conn_ant_channel_close(uint8_t const * const p_rx_buf,
+ uint32_t rx_buf_len,
+ uint8_t * const p_tx_buf,
+ uint32_t * const p_tx_buf_len);
+
+/**@brief Handles @ref sd_ant_network_address_set command and prepares response.
+ *
+ * @param[in] p_rx_buf Pointer to input buffer.
+ * @param[in] rx_buf_len Size of @p p_rx_buf.
+ * @param[out] p_tx_buf Pointer to output buffer.
+ * @param[in,out] p_tx_buf_len \c in: Size of \p p_tx_buf buffer.
+ * \c out: Length of valid data in \p p_tx_buf.
+ *
+ * @retval NRF_SUCCESS Handler success.
+ * @retval NRF_ERROR_NULL Handler failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Handler failure. Incorrect buffer length.
+ * @retval NRF_ERROR_INVALID_PARAM Handler failure. Invalid operation type.
+ */
+uint32_t conn_ant_network_address_set(uint8_t const * const p_rx_buf,
+ uint32_t rx_buf_len,
+ uint8_t * const p_tx_buf,
+ uint32_t * const p_tx_buf_len);
+
+/**@brief Handles @ref sd_ant_channel_radio_tx_power_set command and prepares response.
+ *
+ * @param[in] p_rx_buf Pointer to input buffer.
+ * @param[in] rx_buf_len Size of @p p_rx_buf.
+ * @param[out] p_tx_buf Pointer to output buffer.
+ * @param[in,out] p_tx_buf_len \c in: Size of \p p_tx_buf buffer.
+ * \c out: Length of valid data in \p p_tx_buf.
+ *
+ * @retval NRF_SUCCESS Handler success.
+ * @retval NRF_ERROR_NULL Handler failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Handler failure. Incorrect buffer length.
+ * @retval NRF_ERROR_INVALID_PARAM Handler failure. Invalid operation type.
+ */
+uint32_t conn_ant_channel_radio_tx_power_set(uint8_t const * const p_rx_buf,
+ uint32_t rx_buf_len,
+ uint8_t * const p_tx_buf,
+ uint32_t * const p_tx_buf_len);
+
+/**@brief Handles @ref sd_ant_channel_rx_search_timeout_set command and prepares response.
+ *
+ * @param[in] p_rx_buf Pointer to input buffer.
+ * @param[in] rx_buf_len Size of @p p_rx_buf.
+ * @param[out] p_tx_buf Pointer to output buffer.
+ * @param[in,out] p_tx_buf_len \c in: Size of \p p_tx_buf buffer.
+ * \c out: Length of valid data in \p p_tx_buf.
+ *
+ * @retval NRF_SUCCESS Handler success.
+ * @retval NRF_ERROR_NULL Handler failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Handler failure. Incorrect buffer length.
+ * @retval NRF_ERROR_INVALID_PARAM Handler failure. Invalid operation type.
+ */
+uint32_t conn_ant_channel_rx_search_timeout_set(uint8_t const * const p_rx_buf,
+ uint32_t rx_buf_len,
+ uint8_t * const p_tx_buf,
+ uint32_t * const p_tx_buf_len);
+
+/**@brief Handles @ref sd_ant_channel_low_priority_rx_search_timeout_set command and prepares response.
+ *
+ * @param[in] p_rx_buf Pointer to input buffer.
+ * @param[in] rx_buf_len Size of @p p_rx_buf.
+ * @param[out] p_tx_buf Pointer to output buffer.
+ * @param[in,out] p_tx_buf_len \c in: Size of \p p_tx_buf buffer.
+ * \c out: Length of valid data in \p p_tx_buf.
+ *
+ * @retval NRF_SUCCESS Handler success.
+ * @retval NRF_ERROR_NULL Handler failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Handler failure. Incorrect buffer length.
+ * @retval NRF_ERROR_INVALID_PARAM Handler failure. Invalid operation type.
+ */
+uint32_t conn_ant_channel_low_priority_rx_search_timeout_set(uint8_t const * const p_rx_buf,
+ uint32_t rx_buf_len,
+ uint8_t * const p_tx_buf,
+ uint32_t * const p_tx_buf_len);
+
+/**@brief Handles @ref sd_ant_prox_search_set command and prepares response.
+ *
+ * @param[in] p_rx_buf Pointer to input buffer.
+ * @param[in] rx_buf_len Size of @p p_rx_buf.
+ * @param[out] p_tx_buf Pointer to output buffer.
+ * @param[in,out] p_tx_buf_len \c in: Size of \p p_tx_buf buffer.
+ * \c out: Length of valid data in \p p_tx_buf.
+ *
+ * @retval NRF_SUCCESS Handler success.
+ * @retval NRF_ERROR_NULL Handler failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Handler failure. Incorrect buffer length.
+ * @retval NRF_ERROR_INVALID_PARAM Handler failure. Invalid operation type.
+ */
+uint32_t conn_ant_prox_search_set(uint8_t const * const p_rx_buf,
+ uint32_t rx_buf_len,
+ uint8_t * const p_tx_buf,
+ uint32_t * const p_tx_buf_len);
+
+/**@brief Handles @ref sd_ant_search_waveform_set command and prepares response.
+ *
+ * @param[in] p_rx_buf Pointer to input buffer.
+ * @param[in] rx_buf_len Size of @p p_rx_buf.
+ * @param[out] p_tx_buf Pointer to output buffer.
+ * @param[in,out] p_tx_buf_len \c in: Size of \p p_tx_buf buffer.
+ * \c out: Length of valid data in \p p_tx_buf.
+ *
+ * @retval NRF_SUCCESS Handler success.
+ * @retval NRF_ERROR_NULL Handler failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Handler failure. Incorrect buffer length.
+ * @retval NRF_ERROR_INVALID_PARAM Handler failure. Invalid operation type.
+ */
+uint32_t conn_ant_search_waveform_set(uint8_t const * const p_rx_buf,
+ uint32_t rx_buf_len,
+ uint8_t * const p_tx_buf,
+ uint32_t * const p_tx_buf_len);
+
+/**@brief Handles @ref sd_ant_channel_id_get command and prepares response.
+ *
+ * @param[in] p_rx_buf Pointer to input buffer.
+ * @param[in] rx_buf_len Size of @p p_rx_buf.
+ * @param[out] p_tx_buf Pointer to output buffer.
+ * @param[in,out] p_tx_buf_len \c in: Size of \p p_tx_buf buffer.
+ * \c out: Length of valid data in \p p_tx_buf.
+ *
+ * @retval NRF_SUCCESS Handler success.
+ * @retval NRF_ERROR_NULL Handler failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Handler failure. Incorrect buffer length.
+ * @retval NRF_ERROR_INVALID_PARAM Handler failure. Invalid operation type.
+ */
+uint32_t conn_ant_channel_id_get(uint8_t const * const p_rx_buf,
+ uint32_t rx_buf_len,
+ uint8_t * const p_tx_buf,
+ uint32_t * const p_tx_buf_len);
+
+/**@brief Handles @ref sd_ant_channel_radio_freq_get command and prepares response.
+ *
+ * @param[in] p_rx_buf Pointer to input buffer.
+ * @param[in] rx_buf_len Size of @p p_rx_buf.
+ * @param[out] p_tx_buf Pointer to output buffer.
+ * @param[in,out] p_tx_buf_len \c in: Size of \p p_tx_buf buffer.
+ * \c out: Length of valid data in \p p_tx_buf.
+ *
+ * @retval NRF_SUCCESS Handler success.
+ * @retval NRF_ERROR_NULL Handler failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Handler failure. Incorrect buffer length.
+ * @retval NRF_ERROR_INVALID_PARAM Handler failure. Invalid operation type.
+ */
+uint32_t conn_ant_channel_radio_freq_get(uint8_t const * const p_rx_buf,
+ uint32_t rx_buf_len,
+ uint8_t * const p_tx_buf,
+ uint32_t * const p_tx_buf_len);
+
+/**@brief Handles @ref sd_ant_channel_period_get command and prepares response.
+ *
+ * @param[in] p_rx_buf Pointer to input buffer.
+ * @param[in] rx_buf_len Size of @p p_rx_buf.
+ * @param[out] p_tx_buf Pointer to output buffer.
+ * @param[in,out] p_tx_buf_len \c in: Size of \p p_tx_buf buffer.
+ * \c out: Length of valid data in \p p_tx_buf.
+ *
+ * @retval NRF_SUCCESS Handler success.
+ * @retval NRF_ERROR_NULL Handler failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Handler failure. Incorrect buffer length.
+ * @retval NRF_ERROR_INVALID_PARAM Handler failure. Invalid operation type.
+ */
+uint32_t conn_ant_channel_period_get(uint8_t const * const p_rx_buf,
+ uint32_t rx_buf_len,
+ uint8_t * const p_tx_buf,
+ uint32_t * const p_tx_buf_len);
+
+/**@brief Handles @ref sd_ant_search_channel_priority_set command and prepares response.
+ *
+ * @param[in] p_rx_buf Pointer to input buffer.
+ * @param[in] rx_buf_len Size of @p p_rx_buf.
+ * @param[out] p_tx_buf Pointer to output buffer.
+ * @param[in,out] p_tx_buf_len \c in: Size of \p p_tx_buf buffer.
+ * \c out: Length of valid data in \p p_tx_buf.
+ *
+ * @retval NRF_SUCCESS Handler success.
+ * @retval NRF_ERROR_NULL Handler failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Handler failure. Incorrect buffer length.
+ * @retval NRF_ERROR_INVALID_PARAM Handler failure. Invalid operation type.
+ */
+uint32_t conn_ant_search_channel_priority_set(uint8_t const * const p_rx_buf,
+ uint32_t rx_buf_len,
+ uint8_t * const p_tx_buf,
+ uint32_t * const p_tx_buf_len);
+
+/**@brief Handles @ref sd_ant_active_search_sharing_cycles_set command and prepares response.
+ *
+ * @param[in] p_rx_buf Pointer to input buffer.
+ * @param[in] rx_buf_len Size of @p p_rx_buf.
+ * @param[out] p_tx_buf Pointer to output buffer.
+ * @param[in,out] p_tx_buf_len \c in: Size of \p p_tx_buf buffer.
+ * \c out: Length of valid data in \p p_tx_buf.
+ *
+ * @retval NRF_SUCCESS Handler success.
+ * @retval NRF_ERROR_NULL Handler failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Handler failure. Incorrect buffer length.
+ * @retval NRF_ERROR_INVALID_PARAM Handler failure. Invalid operation type.
+ */
+uint32_t conn_ant_active_search_sharing_cycles_set(uint8_t const * const p_rx_buf,
+ uint32_t rx_buf_len,
+ uint8_t * const p_tx_buf,
+ uint32_t * const p_tx_buf_len);
+
+/**@brief Handles @ref sd_ant_lib_config_set command and prepares response.
+ *
+ * @param[in] p_rx_buf Pointer to input buffer.
+ * @param[in] rx_buf_len Size of @p p_rx_buf.
+ * @param[out] p_tx_buf Pointer to output buffer.
+ * @param[in,out] p_tx_buf_len \c in: Size of \p p_tx_buf buffer.
+ * \c out: Length of valid data in \p p_tx_buf.
+ *
+ * @retval NRF_SUCCESS Handler success.
+ * @retval NRF_ERROR_NULL Handler failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Handler failure. Incorrect buffer length.
+ * @retval NRF_ERROR_INVALID_PARAM Handler failure. Invalid operation type.
+ */
+uint32_t conn_ant_lib_config_set(uint8_t const * const p_rx_buf,
+ uint32_t rx_buf_len,
+ uint8_t * const p_tx_buf,
+ uint32_t * const p_tx_buf_len);
+
+/**@brief Handles @ref sd_ant_active_search_sharing_cycles_get command and prepares response.
+ *
+ * @param[in] p_rx_buf Pointer to input buffer.
+ * @param[in] rx_buf_len Size of @p p_rx_buf.
+ * @param[out] p_tx_buf Pointer to output buffer.
+ * @param[in,out] p_tx_buf_len \c in: Size of \p p_tx_buf buffer.
+ * \c out: Length of valid data in \p p_tx_buf.
+ *
+ * @retval NRF_SUCCESS Handler success.
+ * @retval NRF_ERROR_NULL Handler failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Handler failure. Incorrect buffer length.
+ * @retval NRF_ERROR_INVALID_PARAM Handler failure. Invalid operation type.
+ */
+uint32_t conn_ant_active_search_sharing_cycles_get(uint8_t const * const p_rx_buf,
+ uint32_t rx_buf_len,
+ uint8_t * const p_tx_buf,
+ uint32_t * const p_tx_buf_len);
+
+/**@brief Handles @ref sd_ant_lib_config_get command and prepares response.
+ *
+ * @param[in] p_rx_buf Pointer to input buffer.
+ * @param[in] rx_buf_len Size of @p p_rx_buf.
+ * @param[out] p_tx_buf Pointer to output buffer.
+ * @param[in,out] p_tx_buf_len \c in: Size of \p p_tx_buf buffer.
+ * \c out: Length of valid data in \p p_tx_buf.
+ *
+ * @retval NRF_SUCCESS Handler success.
+ * @retval NRF_ERROR_NULL Handler failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Handler failure. Incorrect buffer length.
+ * @retval NRF_ERROR_INVALID_PARAM Handler failure. Invalid operation type.
+ */
+uint32_t conn_ant_lib_config_get(uint8_t const * const p_rx_buf,
+ uint32_t rx_buf_len,
+ uint8_t * const p_tx_buf,
+ uint32_t * const p_tx_buf_len);
+
+/**@brief Handles @ref sd_ant_lib_config_clear command and prepares response.
+ *
+ * @param[in] p_rx_buf Pointer to input buffer.
+ * @param[in] rx_buf_len Size of @p p_rx_buf.
+ * @param[out] p_tx_buf Pointer to output buffer.
+ * @param[in,out] p_tx_buf_len \c in: Size of \p p_tx_buf buffer.
+ * \c out: Length of valid data in \p p_tx_buf.
+ *
+ * @retval NRF_SUCCESS Handler success.
+ * @retval NRF_ERROR_NULL Handler failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Handler failure. Incorrect buffer length.
+ * @retval NRF_ERROR_INVALID_PARAM Handler failure. Invalid operation type.
+ */
+uint32_t conn_ant_lib_config_clear(uint8_t const * const p_rx_buf,
+ uint32_t rx_buf_len,
+ uint8_t * const p_tx_buf,
+ uint32_t * const p_tx_buf_len);
+
+/**@brief Handles @ref sd_ant_stack_reset command and prepares response.
+ *
+ * @param[in] p_rx_buf Pointer to input buffer.
+ * @param[in] rx_buf_len Size of @p p_rx_buf.
+ * @param[out] p_tx_buf Pointer to output buffer.
+ * @param[in,out] p_tx_buf_len \c in: Size of \p p_tx_buf buffer.
+ * \c out: Length of valid data in \p p_tx_buf.
+ *
+ * @retval NRF_SUCCESS Handler success.
+ * @retval NRF_ERROR_NULL Handler failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Handler failure. Incorrect buffer length.
+ * @retval NRF_ERROR_INVALID_PARAM Handler failure. Invalid operation type.
+ */
+uint32_t conn_ant_stack_reset(uint8_t const * const p_rx_buf,
+ uint32_t rx_buf_len,
+ uint8_t * const p_tx_buf,
+ uint32_t * const p_tx_buf_len);
+
+/**@brief Handles @ref sd_ant_rx_scan_mode_start command and prepares response.
+ *
+ * @param[in] p_rx_buf Pointer to input buffer.
+ * @param[in] rx_buf_len Size of @p p_rx_buf.
+ * @param[out] p_tx_buf Pointer to output buffer.
+ * @param[in,out] p_tx_buf_len \c in: Size of \p p_tx_buf buffer.
+ * \c out: Length of valid data in \p p_tx_buf.
+ *
+ * @retval NRF_SUCCESS Handler success.
+ * @retval NRF_ERROR_NULL Handler failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Handler failure. Incorrect buffer length.
+ * @retval NRF_ERROR_INVALID_PARAM Handler failure. Invalid operation type.
+ */
+uint32_t conn_ant_rx_scan_mode_start(uint8_t const * const p_rx_buf,
+ uint32_t rx_buf_len,
+ uint8_t * const p_tx_buf,
+ uint32_t * const p_tx_buf_len);
+
+/**@brief Handles @ref sd_ant_id_list_add command and prepares response.
+ *
+ * @param[in] p_rx_buf Pointer to input buffer.
+ * @param[in] rx_buf_len Size of @p p_rx_buf.
+ * @param[out] p_tx_buf Pointer to output buffer.
+ * @param[in,out] p_tx_buf_len \c in: Size of \p p_tx_buf buffer.
+ * \c out: Length of valid data in \p p_tx_buf.
+ *
+ * @retval NRF_SUCCESS Handler success.
+ * @retval NRF_ERROR_NULL Handler failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Handler failure. Incorrect buffer length.
+ * @retval NRF_ERROR_INVALID_PARAM Handler failure. Invalid operation type.
+ */
+uint32_t conn_ant_id_list_add(uint8_t const * const p_rx_buf,
+ uint32_t rx_buf_len,
+ uint8_t * const p_tx_buf,
+ uint32_t * const p_tx_buf_len);
+
+/**@brief Handles @ref sd_ant_id_list_config command and prepares response.
+ *
+ * @param[in] p_rx_buf Pointer to input buffer.
+ * @param[in] rx_buf_len Size of @p p_rx_buf.
+ * @param[out] p_tx_buf Pointer to output buffer.
+ * @param[in,out] p_tx_buf_len \c in: Size of \p p_tx_buf buffer.
+ * \c out: Length of valid data in \p p_tx_buf.
+ *
+ * @retval NRF_SUCCESS Handler success.
+ * @retval NRF_ERROR_NULL Handler failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Handler failure. Incorrect buffer length.
+ * @retval NRF_ERROR_INVALID_PARAM Handler failure. Invalid operation type.
+ */
+uint32_t conn_ant_id_list_config(uint8_t const * const p_rx_buf,
+ uint32_t rx_buf_len,
+ uint8_t * const p_tx_buf,
+ uint32_t * const p_tx_buf_len);
+
+/**@brief Handles @ref sd_ant_channel_status_get command and prepares response.
+ *
+ * @param[in] p_rx_buf Pointer to input buffer.
+ * @param[in] rx_buf_len Size of @p p_rx_buf.
+ * @param[out] p_tx_buf Pointer to output buffer.
+ * @param[in,out] p_tx_buf_len \c in: Size of \p p_tx_buf buffer.
+ * \c out: Length of valid data in \p p_tx_buf.
+ *
+ * @retval NRF_SUCCESS Handler success.
+ * @retval NRF_ERROR_NULL Handler failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Handler failure. Incorrect buffer length.
+ * @retval NRF_ERROR_INVALID_PARAM Handler failure. Invalid operation type.
+ */
+uint32_t conn_ant_channel_status_get(uint8_t const * const p_rx_buf,
+ uint32_t rx_buf_len,
+ uint8_t * const p_tx_buf,
+ uint32_t * const p_tx_buf_len);
+
+/**@brief Handles @ref sd_ant_cw_test_mode_init command and prepares response.
+ *
+ * @param[in] p_rx_buf Pointer to input buffer.
+ * @param[in] rx_buf_len Size of @p p_rx_buf.
+ * @param[out] p_tx_buf Pointer to output buffer.
+ * @param[in,out] p_tx_buf_len \c in: Size of \p p_tx_buf buffer.
+ * \c out: Length of valid data in \p p_tx_buf.
+ *
+ * @retval NRF_SUCCESS Handler success.
+ * @retval NRF_ERROR_NULL Handler failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Handler failure. Incorrect buffer length.
+ * @retval NRF_ERROR_INVALID_PARAM Handler failure. Invalid operation type.
+ */
+uint32_t conn_ant_cw_test_mode_init(uint8_t const * const p_rx_buf,
+ uint32_t rx_buf_len,
+ uint8_t * const p_tx_buf,
+ uint32_t * const p_tx_buf_len);
+
+/**@brief Handles @ref sd_ant_cw_test_mode command and prepares response.
+ *
+ * @param[in] p_rx_buf Pointer to input buffer.
+ * @param[in] rx_buf_len Size of @p p_rx_buf.
+ * @param[out] p_tx_buf Pointer to output buffer.
+ * @param[in,out] p_tx_buf_len \c in: Size of \p p_tx_buf buffer.
+ * \c out: Length of valid data in \p p_tx_buf.
+ *
+ * @retval NRF_SUCCESS Handler success.
+ * @retval NRF_ERROR_NULL Handler failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Handler failure. Incorrect buffer length.
+ * @retval NRF_ERROR_INVALID_PARAM Handler failure. Invalid operation type.
+ */
+uint32_t conn_ant_cw_test_mode(uint8_t const * const p_rx_buf,
+ uint32_t rx_buf_len,
+ uint8_t * const p_tx_buf,
+ uint32_t * const p_tx_buf_len);
+
+/**@brief Handles @ref sd_ant_version_get command and prepares response.
+ *
+ * @param[in] p_rx_buf Pointer to input buffer.
+ * @param[in] rx_buf_len Size of @p p_rx_buf.
+ * @param[out] p_tx_buf Pointer to output buffer.
+ * @param[in,out] p_tx_buf_len \c in: Size of \p p_tx_buf buffer.
+ * \c out: Length of valid data in \p p_tx_buf.
+ *
+ * @retval NRF_SUCCESS Handler success.
+ * @retval NRF_ERROR_NULL Handler failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Handler failure. Incorrect buffer length.
+ * @retval NRF_ERROR_INVALID_PARAM Handler failure. Invalid operation type.
+ */
+uint32_t conn_ant_version_get(uint8_t const * const p_rx_buf,
+ uint32_t rx_buf_len,
+ uint8_t * const p_tx_buf,
+ uint32_t * const p_tx_buf_len);
+
+/**@brief Handles @ref sd_ant_capabilities_get command and prepares response.
+ *
+ * @param[in] p_rx_buf Pointer to input buffer.
+ * @param[in] rx_buf_len Size of @p p_rx_buf.
+ * @param[out] p_tx_buf Pointer to output buffer.
+ * @param[in,out] p_tx_buf_len \c in: Size of \p p_tx_buf buffer.
+ * \c out: Length of valid data in \p p_tx_buf.
+ *
+ * @retval NRF_SUCCESS Handler success.
+ * @retval NRF_ERROR_NULL Handler failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Handler failure. Incorrect buffer length.
+ * @retval NRF_ERROR_INVALID_PARAM Handler failure. Invalid operation type.
+ */
+uint32_t conn_ant_capabilities_get(uint8_t const * const p_rx_buf,
+ uint32_t rx_buf_len,
+ uint8_t * const p_tx_buf,
+ uint32_t * const p_tx_buf_len);
+
+/**@brief Handles @ref sd_ant_crypto_channel_enable command and prepares response.
+ *
+ * @param[in] p_rx_buf Pointer to input buffer.
+ * @param[in] rx_buf_len Size of @p p_rx_buf.
+ * @param[out] p_tx_buf Pointer to output buffer.
+ * @param[in,out] p_tx_buf_len \c in: Size of \p p_tx_buf buffer.
+ * \c out: Length of valid data in \p p_tx_buf.
+ *
+ * @retval NRF_SUCCESS Handler success.
+ * @retval NRF_ERROR_NULL Handler failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Handler failure. Incorrect buffer length.
+ * @retval NRF_ERROR_INVALID_PARAM Handler failure. Invalid operation type.
+ */
+uint32_t conn_ant_crypto_channel_enable(uint8_t const * const p_rx_buf,
+ uint32_t rx_buf_len,
+ uint8_t * const p_tx_buf,
+ uint32_t * const p_tx_buf_len);
+
+/**@brief Handles @ref sd_ant_adv_burst_config_set command and prepares response.
+ *
+ * @param[in] p_rx_buf Pointer to input buffer.
+ * @param[in] rx_buf_len Size of @p p_rx_buf.
+ * @param[out] p_tx_buf Pointer to output buffer.
+ * @param[in,out] p_tx_buf_len \c in: Size of \p p_tx_buf buffer.
+ * \c out: Length of valid data in \p p_tx_buf.
+ *
+ * @retval NRF_SUCCESS Handler success.
+ * @retval NRF_ERROR_NULL Handler failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Handler failure. Incorrect buffer length.
+ * @retval NRF_ERROR_INVALID_PARAM Handler failure. Invalid operation type.
+ */
+uint32_t conn_ant_adv_burst_config_set(uint8_t const * const p_rx_buf,
+ uint32_t rx_buf_len,
+ uint8_t * const p_tx_buf,
+ uint32_t * const p_tx_buf_len);
+
+/**@brief Handles @ref sd_ant_crypto_key_set command and prepares response.
+ *
+ * @param[in] p_rx_buf Pointer to input buffer.
+ * @param[in] rx_buf_len Size of @p p_rx_buf.
+ * @param[out] p_tx_buf Pointer to output buffer.
+ * @param[in,out] p_tx_buf_len \c in: Size of \p p_tx_buf buffer.
+ * \c out: Length of valid data in \p p_tx_buf.
+ *
+ * @retval NRF_SUCCESS Handler success.
+ * @retval NRF_ERROR_NULL Handler failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Handler failure. Incorrect buffer length.
+ * @retval NRF_ERROR_INVALID_PARAM Handler failure. Invalid operation type.
+ */
+uint32_t conn_ant_crypto_key_set(uint8_t const * const p_rx_buf,
+ uint32_t rx_buf_len,
+ uint8_t * const p_tx_buf,
+ uint32_t * const p_tx_buf_len);
+
+/**@brief Handles @ref sd_ant_crypto_info_set command and prepares response.
+ *
+ * @param[in] p_rx_buf Pointer to input buffer.
+ * @param[in] rx_buf_len Size of @p p_rx_buf.
+ * @param[out] p_tx_buf Pointer to output buffer.
+ * @param[in,out] p_tx_buf_len \c in: Size of \p p_tx_buf buffer.
+ * \c out: Length of valid data in \p p_tx_buf.
+ *
+ * @retval NRF_SUCCESS Handler success.
+ * @retval NRF_ERROR_NULL Handler failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Handler failure. Incorrect buffer length.
+ * @retval NRF_ERROR_INVALID_PARAM Handler failure. Invalid operation type.
+ */
+uint32_t conn_ant_crypto_info_set(uint8_t const * const p_rx_buf,
+ uint32_t rx_buf_len,
+ uint8_t * const p_tx_buf,
+ uint32_t * const p_tx_buf_len);
+
+/**@brief Handles @ref sd_ant_crypto_info_get command and prepares response.
+ *
+ * @param[in] p_rx_buf Pointer to input buffer.
+ * @param[in] rx_buf_len Size of @p p_rx_buf.
+ * @param[out] p_tx_buf Pointer to output buffer.
+ * @param[in,out] p_tx_buf_len \c in: Size of \p p_tx_buf buffer.
+ * \c out: Length of valid data in \p p_tx_buf.
+ *
+ * @retval NRF_SUCCESS Handler success.
+ * @retval NRF_ERROR_NULL Handler failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Handler failure. Incorrect buffer length.
+ * @retval NRF_ERROR_INVALID_PARAM Handler failure. Invalid operation type.
+ */
+uint32_t conn_ant_crypto_info_get(uint8_t const * const p_rx_buf,
+ uint32_t rx_buf_len,
+ uint8_t * const p_tx_buf,
+ uint32_t * const p_tx_buf_len);
+
+/**@brief Handles @ref sd_ant_coex_config_set command and prepares response.
+ *
+ * @param[in] p_rx_buf Pointer to input buffer.
+ * @param[in] rx_buf_len Size of @p p_rx_buf.
+ * @param[out] p_tx_buf Pointer to output buffer.
+ * @param[in,out] p_tx_buf_len \c in: Size of \p p_tx_buf buffer.
+ * \c out: Length of valid data in \p p_tx_buf.
+ *
+ * @retval NRF_SUCCESS Handler success.
+ * @retval NRF_ERROR_NULL Handler failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Handler failure. Incorrect buffer length.
+ * @retval NRF_ERROR_INVALID_PARAM Handler failure. Invalid operation type.
+ */
+uint32_t conn_ant_coex_config_set(uint8_t const * const p_rx_buf,
+ uint32_t rx_buf_len,
+ uint8_t * const p_tx_buf,
+ uint32_t * const p_tx_buf_len);
+
+/**@brief Handles @ref sd_ant_coex_config_get command and prepares response.
+ *
+ * @param[in] p_rx_buf Pointer to input buffer.
+ * @param[in] rx_buf_len Size of @p p_rx_buf.
+ * @param[out] p_tx_buf Pointer to output buffer.
+ * @param[in,out] p_tx_buf_len \c in: Size of \p p_tx_buf buffer.
+ * \c out: Length of valid data in \p p_tx_buf.
+ *
+ * @retval NRF_SUCCESS Handler success.
+ * @retval NRF_ERROR_NULL Handler failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Handler failure. Incorrect buffer length.
+ * @retval NRF_ERROR_INVALID_PARAM Handler failure. Invalid operation type.
+ */
+uint32_t conn_ant_coex_config_get(uint8_t const * const p_rx_buf,
+ uint32_t rx_buf_len,
+ uint8_t * const p_tx_buf,
+ uint32_t * const p_tx_buf_len);
+
+
+/** @} */
+
+#endif //_CONN_MW_ANT_H
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/connectivity/codecs/ant/serializers/ant_acknowledge_message_tx.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/connectivity/codecs/ant/serializers/ant_acknowledge_message_tx.c
new file mode 100644
index 0000000..3e1fb20
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/connectivity/codecs/ant/serializers/ant_acknowledge_message_tx.c
@@ -0,0 +1,84 @@
+/**
+ * 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+
+#include <string.h>
+#include "ant_conn.h"
+#include "ble_serialization.h"
+#include "cond_field_serialization.h"
+#include "ant_struct_serialization.h"
+#include "app_util.h"
+
+uint32_t ant_acknowledge_message_tx_req_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ uint8_t * const p_channel,
+ uint8_t * const p_size,
+ uint8_t * * const pp_mesg)
+{
+ uint32_t index = SER_CMD_DATA_POS;
+ uint32_t err_code;
+
+ SER_ASSERT_NOT_NULL(p_buf);
+ SER_ASSERT_NOT_NULL(p_channel);
+ SER_ASSERT_NOT_NULL(p_size);
+ SER_ASSERT_NOT_NULL(*pp_mesg);
+
+ err_code = uint8_t_dec(p_buf, packet_len, &index, p_channel);
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code);
+
+ err_code = uint8_t_dec(p_buf, packet_len, &index, p_size);
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code);
+
+ err_code = uint8_vector_dec(p_buf, packet_len, &index, *pp_mesg, *p_size);
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code);
+
+ SER_ASSERT_LENGTH_EQ(index, packet_len);
+
+ return err_code;
+}
+
+
+uint32_t ant_acknowledge_message_tx_rsp_enc(uint32_t return_code,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len)
+{
+ uint32_t index = 0;
+
+ return op_status_enc(SVC_ANT_TX_ACKNOWLEDGED_MESSAGE, return_code, p_buf, p_buf_len, &index);
+}
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/connectivity/codecs/ant/serializers/ant_active_search_sharing_cycles_get.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/connectivity/codecs/ant/serializers/ant_active_search_sharing_cycles_get.c
new file mode 100644
index 0000000..baea0f9
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/connectivity/codecs/ant/serializers/ant_active_search_sharing_cycles_get.c
@@ -0,0 +1,89 @@
+/**
+ * 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+
+#include <string.h>
+#include "ant_conn.h"
+#include "ble_serialization.h"
+#include "cond_field_serialization.h"
+#include "ant_struct_serialization.h"
+#include "app_util.h"
+
+uint32_t ant_active_search_sharing_cycles_get_req_dec(uint8_t const * const p_buf,
+ uint16_t packet_len,
+ uint8_t * const p_channel)
+{
+ uint32_t index = SER_CMD_DATA_POS;
+ uint32_t err_code;
+
+ SER_ASSERT_NOT_NULL(p_buf);
+ SER_ASSERT_NOT_NULL(p_channel);
+
+ err_code = uint8_t_dec(p_buf, packet_len, &index, p_channel);
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code);
+
+ SER_ASSERT_LENGTH_EQ(index, packet_len);
+
+ return err_code;
+}
+
+uint32_t ant_active_search_sharing_cycles_get_rsp_enc(uint32_t return_code,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len,
+ uint8_t const * const p_cycles)
+{
+ SER_ASSERT_NOT_NULL(p_buf);
+ SER_ASSERT_NOT_NULL(p_buf_len);
+
+ uint32_t total_len = *p_buf_len;
+
+ uint32_t err_code = ser_ble_cmd_rsp_status_code_enc(SVC_ANT_ACTIVE_SEARCH_SHARING_CYCLES_GET, return_code,
+ p_buf, p_buf_len);
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code);
+
+ if (return_code != NRF_SUCCESS)
+ {
+ return NRF_SUCCESS;
+ }
+
+ err_code = uint8_t_enc(p_cycles, p_buf, total_len, p_buf_len);
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code);
+
+ return NRF_SUCCESS;
+}
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/connectivity/codecs/ant/serializers/ant_active_search_sharing_cycles_set.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/connectivity/codecs/ant/serializers/ant_active_search_sharing_cycles_set.c
new file mode 100644
index 0000000..230c93e
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/connectivity/codecs/ant/serializers/ant_active_search_sharing_cycles_set.c
@@ -0,0 +1,78 @@
+/**
+ * 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+
+#include <string.h>
+#include "ant_conn.h"
+#include "ble_serialization.h"
+#include "cond_field_serialization.h"
+#include "ant_struct_serialization.h"
+#include "app_util.h"
+
+uint32_t ant_active_search_sharing_cycles_set_req_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ uint8_t * const p_channel,
+ uint8_t * const p_cycles)
+{
+ uint32_t index = SER_CMD_DATA_POS;
+ uint32_t err_code;
+
+ SER_ASSERT_NOT_NULL(p_buf);
+ SER_ASSERT_NOT_NULL(p_channel);
+ SER_ASSERT_NOT_NULL(p_cycles);
+
+ err_code = uint8_t_dec(p_buf, packet_len, &index, p_channel);
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code);
+
+ err_code = uint8_t_dec(p_buf, packet_len, &index, p_cycles);
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code);
+
+ SER_ASSERT_LENGTH_EQ(index, packet_len);
+
+ return err_code;
+}
+
+uint32_t ant_active_search_sharing_cycles_set_rsp_enc(uint32_t return_code,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len)
+{
+ uint32_t index = 0;
+
+ return op_status_enc(SVC_ANT_ACTIVE_SEARCH_SHARING_CYCLES_SET, return_code, p_buf, p_buf_len, &index);
+}
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/connectivity/codecs/ant/serializers/ant_adv_burst_config_set.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/connectivity/codecs/ant/serializers/ant_adv_burst_config_set.c
new file mode 100644
index 0000000..70d9362
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/connectivity/codecs/ant/serializers/ant_adv_burst_config_set.c
@@ -0,0 +1,79 @@
+/**
+ * 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+
+#include <string.h>
+#include "ant_conn.h"
+#include "ble_serialization.h"
+#include "cond_field_serialization.h"
+#include "ant_struct_serialization.h"
+#include "app_util.h"
+
+uint32_t ant_adv_burst_config_set_req_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ uint8_t * const p_config,
+ uint8_t * const p_size)
+{
+ uint32_t index = SER_CMD_DATA_POS;
+ uint32_t err_code;
+
+ SER_ASSERT_NOT_NULL(p_buf);
+ SER_ASSERT_NOT_NULL(p_size);
+ SER_ASSERT_NOT_NULL(p_config);
+
+ err_code = uint8_t_dec(p_buf, packet_len, &index, p_size);
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code);
+
+ err_code = uint8_vector_dec(p_buf, packet_len, &index, p_config, *p_size);
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code);
+
+ SER_ASSERT_LENGTH_EQ(index, packet_len);
+
+ return err_code;
+}
+
+
+uint32_t ant_adv_burst_config_set_rsp_enc(uint32_t return_code,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len)
+{
+ uint32_t index = 0;
+
+ return op_status_enc(SVC_ANT_ADV_BURST_CONFIG_SET, return_code, p_buf, p_buf_len, &index);
+}
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/connectivity/codecs/ant/serializers/ant_broadcast_message_tx.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/connectivity/codecs/ant/serializers/ant_broadcast_message_tx.c
new file mode 100644
index 0000000..63bf6da
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/connectivity/codecs/ant/serializers/ant_broadcast_message_tx.c
@@ -0,0 +1,84 @@
+/**
+ * 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+
+#include <string.h>
+#include "ant_conn.h"
+#include "ble_serialization.h"
+#include "cond_field_serialization.h"
+#include "ant_struct_serialization.h"
+#include "app_util.h"
+
+uint32_t ant_broadcast_message_tx_req_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ uint8_t * const p_channel,
+ uint8_t * const p_size,
+ uint8_t * * const pp_mesg)
+{
+ uint32_t index = SER_CMD_DATA_POS;
+ uint32_t err_code;
+
+ SER_ASSERT_NOT_NULL(p_buf);
+ SER_ASSERT_NOT_NULL(p_channel);
+ SER_ASSERT_NOT_NULL(p_size);
+ SER_ASSERT_NOT_NULL(*pp_mesg);
+
+ err_code = uint8_t_dec(p_buf, packet_len, &index, p_channel);
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code);
+
+ err_code = uint8_t_dec(p_buf, packet_len, &index, p_size);
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code);
+
+ err_code = uint8_vector_dec(p_buf, packet_len, &index, *pp_mesg, *p_size);
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code);
+
+ SER_ASSERT_LENGTH_EQ(index, packet_len);
+
+ return err_code;
+}
+
+
+uint32_t ant_broadcast_message_tx_rsp_enc(uint32_t return_code,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len)
+{
+ uint32_t index = 0;
+
+ return op_status_enc(SVC_ANT_TX_BROADCAST_MESSAGE, return_code, p_buf, p_buf_len, &index);
+}
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/connectivity/codecs/ant/serializers/ant_capabilities_get.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/connectivity/codecs/ant/serializers/ant_capabilities_get.c
new file mode 100644
index 0000000..113a13e
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/connectivity/codecs/ant/serializers/ant_capabilities_get.c
@@ -0,0 +1,71 @@
+/**
+ * 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+
+#include <string.h>
+#include "ant_conn.h"
+#include "ble_serialization.h"
+#include "cond_field_serialization.h"
+#include "ant_struct_serialization.h"
+#include "app_util.h"
+
+uint32_t ant_capabilities_get_rsp_enc(uint32_t return_code,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len,
+ uint8_t const * const p_capabilities)
+{
+ SER_ASSERT_NOT_NULL(p_buf);
+ SER_ASSERT_NOT_NULL(p_buf_len);
+
+ uint32_t total_len = *p_buf_len;
+
+ uint32_t err_code = ser_ble_cmd_rsp_status_code_enc(SVC_ANT_CAPABILITIES, return_code,
+ p_buf, p_buf_len);
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code);
+
+ if (return_code != NRF_SUCCESS)
+ {
+ return NRF_SUCCESS;
+ }
+
+ err_code = uint8_vector_enc(p_capabilities, MESG_CAPABILITIES_SIZE, p_buf, total_len, p_buf_len);
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code);
+
+ return NRF_SUCCESS;
+}
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/connectivity/codecs/ant/serializers/ant_channel_assign.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/connectivity/codecs/ant/serializers/ant_channel_assign.c
new file mode 100644
index 0000000..4121d2b
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/connectivity/codecs/ant/serializers/ant_channel_assign.c
@@ -0,0 +1,89 @@
+/**
+ * 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+
+#include <string.h>
+#include "ant_conn.h"
+#include "ble_serialization.h"
+#include "cond_field_serialization.h"
+#include "ant_struct_serialization.h"
+#include "app_util.h"
+
+uint32_t ant_channel_assign_req_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ uint8_t * const p_channel,
+ uint8_t * const p_type,
+ uint8_t * const p_network,
+ uint8_t * const p_ext_assign)
+{
+ uint32_t index = SER_CMD_DATA_POS;
+ uint32_t err_code;
+
+ SER_ASSERT_NOT_NULL(p_buf);
+ SER_ASSERT_NOT_NULL(p_channel);
+ SER_ASSERT_NOT_NULL(p_type);
+ SER_ASSERT_NOT_NULL(p_network);
+ SER_ASSERT_NOT_NULL(p_ext_assign);
+
+ err_code = uint8_t_dec(p_buf, packet_len, &index, p_channel);
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code);
+
+ err_code = uint8_t_dec(p_buf, packet_len, &index, p_type);
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code);
+
+ err_code = uint8_t_dec(p_buf, packet_len, &index, p_network);
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code);
+
+ err_code = uint8_t_dec(p_buf, packet_len, &index, p_ext_assign);
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code);
+
+ SER_ASSERT_LENGTH_EQ(index, packet_len);
+
+ return err_code;
+}
+
+
+uint32_t ant_channel_assign_rsp_enc(uint32_t return_code,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len)
+{
+ uint32_t index = 0;
+
+ return op_status_enc(SVC_ANT_CHANNEL_ASSIGN, return_code, p_buf, p_buf_len, &index);
+}
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/connectivity/codecs/ant/serializers/ant_channel_close.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/connectivity/codecs/ant/serializers/ant_channel_close.c
new file mode 100644
index 0000000..3ef78d0
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/connectivity/codecs/ant/serializers/ant_channel_close.c
@@ -0,0 +1,73 @@
+/**
+ * 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+
+#include <string.h>
+#include "ant_conn.h"
+#include "ble_serialization.h"
+#include "cond_field_serialization.h"
+#include "ant_struct_serialization.h"
+#include "app_util.h"
+
+uint32_t ant_channel_close_req_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ uint8_t * const p_channel)
+{
+ uint32_t index = SER_CMD_DATA_POS;
+ uint32_t err_code;
+
+ SER_ASSERT_NOT_NULL(p_buf);
+ SER_ASSERT_NOT_NULL(p_channel);
+
+ err_code = uint8_t_dec(p_buf, packet_len, &index, p_channel);
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code);
+
+ SER_ASSERT_LENGTH_EQ(index, packet_len);
+
+ return err_code;
+}
+
+uint32_t ant_channel_close_rsp_enc(uint32_t return_code,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len)
+{
+ uint32_t index = 0;
+
+ return op_status_enc(SVC_ANT_CHANNEL_CLOSE, return_code, p_buf, p_buf_len, &index);
+}
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/connectivity/codecs/ant/serializers/ant_channel_id_get.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/connectivity/codecs/ant/serializers/ant_channel_id_get.c
new file mode 100644
index 0000000..5bc0fba
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/connectivity/codecs/ant/serializers/ant_channel_id_get.c
@@ -0,0 +1,97 @@
+/**
+ * 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+
+#include <string.h>
+#include "ant_conn.h"
+#include "ble_serialization.h"
+#include "cond_field_serialization.h"
+#include "ant_struct_serialization.h"
+#include "app_util.h"
+
+uint32_t ant_channel_id_get_req_dec(uint8_t const * const p_buf,
+ uint16_t packet_len,
+ uint8_t * const p_channel)
+{
+ uint32_t index = SER_CMD_DATA_POS;
+ uint32_t err_code;
+
+ SER_ASSERT_NOT_NULL(p_buf);
+ SER_ASSERT_NOT_NULL(p_channel);
+
+ err_code = uint8_t_dec(p_buf, packet_len, &index, p_channel);
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code);
+
+ SER_ASSERT_LENGTH_EQ(index, packet_len);
+
+ return err_code;
+}
+
+uint32_t ant_channel_id_get_rsp_enc(uint32_t return_code,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len,
+ uint16_t const * const p_device_number,
+ uint8_t const * const p_device_type,
+ uint8_t const * const p_transmit_type)
+{
+ SER_ASSERT_NOT_NULL(p_buf);
+ SER_ASSERT_NOT_NULL(p_buf_len);
+
+ uint32_t total_len = *p_buf_len;
+
+ uint32_t err_code = ser_ble_cmd_rsp_status_code_enc(SVC_ANT_CHANNEL_ID_GET, return_code,
+ p_buf, p_buf_len);
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code);
+
+ if (return_code != NRF_SUCCESS)
+ {
+ return NRF_SUCCESS;
+ }
+
+ err_code = uint16_t_enc(p_device_number, p_buf, total_len, p_buf_len);
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code);
+
+ err_code = uint8_t_enc(p_device_type, p_buf, total_len, p_buf_len);
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code);
+
+ err_code = uint8_t_enc(p_transmit_type, p_buf, total_len, p_buf_len);
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code);
+
+ return NRF_SUCCESS;
+}
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/connectivity/codecs/ant/serializers/ant_channel_id_set.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/connectivity/codecs/ant/serializers/ant_channel_id_set.c
new file mode 100644
index 0000000..ec50390
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/connectivity/codecs/ant/serializers/ant_channel_id_set.c
@@ -0,0 +1,89 @@
+/**
+ * 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+
+#include <string.h>
+#include "ant_conn.h"
+#include "ble_serialization.h"
+#include "cond_field_serialization.h"
+#include "ant_struct_serialization.h"
+#include "app_util.h"
+
+uint32_t ant_channel_id_set_req_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ uint8_t * const p_channel,
+ uint16_t * const p_device_number,
+ uint8_t * const p_device_type,
+ uint8_t * const p_transmission_type)
+{
+ uint32_t index = SER_CMD_DATA_POS;
+ uint32_t err_code;
+
+ SER_ASSERT_NOT_NULL(p_buf);
+ SER_ASSERT_NOT_NULL(p_channel);
+ SER_ASSERT_NOT_NULL(p_device_number);
+ SER_ASSERT_NOT_NULL(p_device_type);
+ SER_ASSERT_NOT_NULL(p_transmission_type);
+
+ err_code = uint8_t_dec(p_buf, packet_len, &index, p_channel);
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code);
+
+ err_code = uint16_t_dec(p_buf, packet_len, &index, p_device_number);
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code);
+
+ err_code = uint8_t_dec(p_buf, packet_len, &index, p_device_type);
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code);
+
+ err_code = uint8_t_dec(p_buf, packet_len, &index, p_transmission_type);
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code);
+
+ SER_ASSERT_LENGTH_EQ(index, packet_len);
+
+ return err_code;
+}
+
+
+uint32_t ant_channel_id_set_rsp_enc(uint32_t return_code,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len)
+{
+ uint32_t index = 0;
+
+ return op_status_enc(SVC_ANT_CHANNEL_ID_SET, return_code, p_buf, p_buf_len, &index);
+}
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/connectivity/codecs/ant/serializers/ant_channel_low_priority_rx_search_timout_set.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/connectivity/codecs/ant/serializers/ant_channel_low_priority_rx_search_timout_set.c
new file mode 100644
index 0000000..ff17048
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/connectivity/codecs/ant/serializers/ant_channel_low_priority_rx_search_timout_set.c
@@ -0,0 +1,78 @@
+/**
+ * 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+
+#include <string.h>
+#include "ant_conn.h"
+#include "ble_serialization.h"
+#include "cond_field_serialization.h"
+#include "ant_struct_serialization.h"
+#include "app_util.h"
+
+uint32_t ant_channel_low_priority_rx_search_timeout_set_req_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ uint8_t * const p_channel,
+ uint8_t * const p_timeout)
+{
+ uint32_t index = SER_CMD_DATA_POS;
+ uint32_t err_code;
+
+ SER_ASSERT_NOT_NULL(p_buf);
+ SER_ASSERT_NOT_NULL(p_channel);
+ SER_ASSERT_NOT_NULL(p_timeout);
+
+ err_code = uint8_t_dec(p_buf, packet_len, &index, p_channel);
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code);
+
+ err_code = uint8_t_dec(p_buf, packet_len, &index, p_timeout);
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code);
+
+ SER_ASSERT_LENGTH_EQ(index, packet_len);
+
+ return err_code;
+}
+
+uint32_t ant_channel_low_priority_rx_search_timeout_set_rsp_enc(uint32_t return_code,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len)
+{
+ uint32_t index = 0;
+
+ return op_status_enc(SVC_ANT_CHANNEL_LOW_PRIO_RX_SEARCH_TIMEOUT_SET, return_code, p_buf, p_buf_len, &index);
+}
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/connectivity/codecs/ant/serializers/ant_channel_open_with_offset.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/connectivity/codecs/ant/serializers/ant_channel_open_with_offset.c
new file mode 100644
index 0000000..784143f
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/connectivity/codecs/ant/serializers/ant_channel_open_with_offset.c
@@ -0,0 +1,78 @@
+/**
+ * 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+
+#include <string.h>
+#include "ant_conn.h"
+#include "ble_serialization.h"
+#include "cond_field_serialization.h"
+#include "ant_struct_serialization.h"
+#include "app_util.h"
+
+uint32_t ant_channel_open_with_offset_req_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ uint8_t * const p_channel,
+ uint16_t * const p_usOffset)
+{
+ uint32_t index = SER_CMD_DATA_POS;
+ uint32_t err_code;
+
+ SER_ASSERT_NOT_NULL(p_buf);
+ SER_ASSERT_NOT_NULL(p_channel);
+
+ err_code = uint8_t_dec(p_buf, packet_len, &index, p_channel);
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code);
+
+ err_code = uint16_t_dec(p_buf, packet_len, &index, p_usOffset);
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code);
+
+ SER_ASSERT_LENGTH_EQ(index, packet_len);
+
+ return err_code;
+}
+
+
+uint32_t ant_channel_open_with_offset_rsp_enc(uint32_t return_code,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len)
+{
+ uint32_t index = 0;
+
+ return op_status_enc(SVC_ANT_CHANNEL_OPEN, return_code, p_buf, p_buf_len, &index);
+}
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/connectivity/codecs/ant/serializers/ant_channel_period_get.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/connectivity/codecs/ant/serializers/ant_channel_period_get.c
new file mode 100644
index 0000000..f62da42
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/connectivity/codecs/ant/serializers/ant_channel_period_get.c
@@ -0,0 +1,89 @@
+/**
+ * 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+
+#include <string.h>
+#include "ant_conn.h"
+#include "ble_serialization.h"
+#include "cond_field_serialization.h"
+#include "ant_struct_serialization.h"
+#include "app_util.h"
+
+uint32_t ant_channel_period_get_req_dec(uint8_t const * const p_buf,
+ uint16_t packet_len,
+ uint8_t * const p_channel)
+{
+ uint32_t index = SER_CMD_DATA_POS;
+ uint32_t err_code;
+
+ SER_ASSERT_NOT_NULL(p_buf);
+ SER_ASSERT_NOT_NULL(p_channel);
+
+ err_code = uint8_t_dec(p_buf, packet_len, &index, p_channel);
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code);
+
+ SER_ASSERT_LENGTH_EQ(index, packet_len);
+
+ return err_code;
+}
+
+uint32_t ant_channel_period_get_rsp_enc(uint32_t return_code,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len,
+ uint16_t const * const p_period)
+{
+ SER_ASSERT_NOT_NULL(p_buf);
+ SER_ASSERT_NOT_NULL(p_buf_len);
+
+ uint32_t total_len = *p_buf_len;
+
+ uint32_t err_code = ser_ble_cmd_rsp_status_code_enc(SVC_ANT_CHANNEL_PERIOD_GET, return_code,
+ p_buf, p_buf_len);
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code);
+
+ if (return_code != NRF_SUCCESS)
+ {
+ return NRF_SUCCESS;
+ }
+
+ err_code = uint16_t_enc(p_period, p_buf, total_len, p_buf_len);
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code);
+
+ return NRF_SUCCESS;
+}
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/connectivity/codecs/ant/serializers/ant_channel_period_set.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/connectivity/codecs/ant/serializers/ant_channel_period_set.c
new file mode 100644
index 0000000..719cac5
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/connectivity/codecs/ant/serializers/ant_channel_period_set.c
@@ -0,0 +1,78 @@
+/**
+ * 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+
+#include <string.h>
+#include "ant_conn.h"
+#include "ble_serialization.h"
+#include "cond_field_serialization.h"
+#include "ant_struct_serialization.h"
+#include "app_util.h"
+
+uint32_t ant_channel_period_set_req_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ uint8_t * const p_channel,
+ uint16_t * const p_period)
+{
+ uint32_t index = SER_CMD_DATA_POS;
+ uint32_t err_code;
+
+ SER_ASSERT_NOT_NULL(p_buf);
+ SER_ASSERT_NOT_NULL(p_channel);
+ SER_ASSERT_NOT_NULL(p_period);
+
+ err_code = uint8_t_dec(p_buf, packet_len, &index, p_channel);
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code);
+
+ err_code = uint16_t_dec(p_buf, packet_len, &index, p_period);
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code);
+
+ SER_ASSERT_LENGTH_EQ(index, packet_len);
+
+ return err_code;
+}
+
+uint32_t ant_channel_period_set_rsp_enc(uint32_t return_code,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len)
+{
+ uint32_t index = 0;
+
+ return op_status_enc(SVC_ANT_CHANNEL_PERIOD_SET, return_code, p_buf, p_buf_len, &index);
+}
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/connectivity/codecs/ant/serializers/ant_channel_radio_freq_get.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/connectivity/codecs/ant/serializers/ant_channel_radio_freq_get.c
new file mode 100644
index 0000000..fde80af
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/connectivity/codecs/ant/serializers/ant_channel_radio_freq_get.c
@@ -0,0 +1,89 @@
+/**
+ * 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+
+#include <string.h>
+#include "ant_conn.h"
+#include "ble_serialization.h"
+#include "cond_field_serialization.h"
+#include "ant_struct_serialization.h"
+#include "app_util.h"
+
+uint32_t ant_channel_radio_freq_get_req_dec(uint8_t const * const p_buf,
+ uint16_t packet_len,
+ uint8_t * const p_channel)
+{
+ uint32_t index = SER_CMD_DATA_POS;
+ uint32_t err_code;
+
+ SER_ASSERT_NOT_NULL(p_buf);
+ SER_ASSERT_NOT_NULL(p_channel);
+
+ err_code = uint8_t_dec(p_buf, packet_len, &index, p_channel);
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code);
+
+ SER_ASSERT_LENGTH_EQ(index, packet_len);
+
+ return err_code;
+}
+
+uint32_t ant_channel_radio_freq_get_rsp_enc(uint32_t return_code,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len,
+ uint8_t const * const p_r_freq)
+{
+ SER_ASSERT_NOT_NULL(p_buf);
+ SER_ASSERT_NOT_NULL(p_buf_len);
+
+ uint32_t total_len = *p_buf_len;
+
+ uint32_t err_code = ser_ble_cmd_rsp_status_code_enc(SVC_ANT_CHANNEL_RADIO_FREQ_GET, return_code,
+ p_buf, p_buf_len);
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code);
+
+ if (return_code != NRF_SUCCESS)
+ {
+ return NRF_SUCCESS;
+ }
+
+ err_code = uint8_t_enc(p_r_freq, p_buf, total_len, p_buf_len);
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code);
+
+ return NRF_SUCCESS;
+}
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/connectivity/codecs/ant/serializers/ant_channel_radio_freq_set.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/connectivity/codecs/ant/serializers/ant_channel_radio_freq_set.c
new file mode 100644
index 0000000..35248e9
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/connectivity/codecs/ant/serializers/ant_channel_radio_freq_set.c
@@ -0,0 +1,78 @@
+/**
+ * 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+
+#include <string.h>
+#include "ant_conn.h"
+#include "ble_serialization.h"
+#include "cond_field_serialization.h"
+#include "ant_struct_serialization.h"
+#include "app_util.h"
+
+uint32_t ant_channel_radio_freq_set_req_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ uint8_t * const p_channel,
+ uint8_t * const p_freq)
+{
+ uint32_t index = SER_CMD_DATA_POS;
+ uint32_t err_code;
+
+ SER_ASSERT_NOT_NULL(p_buf);
+ SER_ASSERT_NOT_NULL(p_channel);
+ SER_ASSERT_NOT_NULL(p_freq);
+
+ err_code = uint8_t_dec(p_buf, packet_len, &index, p_channel);
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code);
+
+ err_code = uint8_t_dec(p_buf, packet_len, &index, p_freq);
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code);
+
+ SER_ASSERT_LENGTH_EQ(index, packet_len);
+
+ return err_code;
+}
+
+uint32_t ant_channel_radio_freq_set_rsp_enc(uint32_t return_code,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len)
+{
+ uint32_t index = 0;
+
+ return op_status_enc(SVC_ANT_CHANNEL_RADIO_FREQ_SET, return_code, p_buf, p_buf_len, &index);
+}
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/connectivity/codecs/ant/serializers/ant_channel_radio_tx_power_set.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/connectivity/codecs/ant/serializers/ant_channel_radio_tx_power_set.c
new file mode 100644
index 0000000..9bbcc32
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/connectivity/codecs/ant/serializers/ant_channel_radio_tx_power_set.c
@@ -0,0 +1,83 @@
+/**
+ * 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+
+#include <string.h>
+#include "ant_conn.h"
+#include "ble_serialization.h"
+#include "cond_field_serialization.h"
+#include "ant_struct_serialization.h"
+#include "app_util.h"
+
+uint32_t ant_channel_radio_tx_power_set_req_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ uint8_t * const p_channel,
+ uint8_t * const p_tx_power,
+ uint8_t * const p_custom_tx_power)
+{
+ uint32_t index = SER_CMD_DATA_POS;
+ uint32_t err_code;
+
+ SER_ASSERT_NOT_NULL(p_buf);
+ SER_ASSERT_NOT_NULL(p_channel);
+ SER_ASSERT_NOT_NULL(p_tx_power);
+ SER_ASSERT_NOT_NULL(p_custom_tx_power);
+
+ err_code = uint8_t_dec(p_buf, packet_len, &index, p_channel);
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code);
+
+ err_code = uint8_t_dec(p_buf, packet_len, &index, p_tx_power);
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code);
+
+ err_code = uint8_t_dec(p_buf, packet_len, &index, p_custom_tx_power);
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code);
+
+ SER_ASSERT_LENGTH_EQ(index, packet_len);
+
+ return err_code;
+}
+
+uint32_t ant_channel_radio_tx_power_set_rsp_enc(uint32_t return_code,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len)
+{
+ uint32_t index = 0;
+
+ return op_status_enc(SVC_ANT_CHANNEL_RADIO_TX_POWER_SET, return_code, p_buf, p_buf_len, &index);
+}
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/connectivity/codecs/ant/serializers/ant_channel_rx_search_timeout_set.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/connectivity/codecs/ant/serializers/ant_channel_rx_search_timeout_set.c
new file mode 100644
index 0000000..f7de11b
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/connectivity/codecs/ant/serializers/ant_channel_rx_search_timeout_set.c
@@ -0,0 +1,78 @@
+/**
+ * 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+
+#include <string.h>
+#include "ant_conn.h"
+#include "ble_serialization.h"
+#include "cond_field_serialization.h"
+#include "ant_struct_serialization.h"
+#include "app_util.h"
+
+uint32_t ant_channel_rx_search_timeout_set_req_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ uint8_t * const p_channel,
+ uint8_t * const p_timeout)
+{
+ uint32_t index = SER_CMD_DATA_POS;
+ uint32_t err_code;
+
+ SER_ASSERT_NOT_NULL(p_buf);
+ SER_ASSERT_NOT_NULL(p_channel);
+ SER_ASSERT_NOT_NULL(p_timeout);
+
+ err_code = uint8_t_dec(p_buf, packet_len, &index, p_channel);
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code);
+
+ err_code = uint8_t_dec(p_buf, packet_len, &index, p_timeout);
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code);
+
+ SER_ASSERT_LENGTH_EQ(index, packet_len);
+
+ return err_code;
+}
+
+uint32_t ant_channel_rx_search_timeout_set_rsp_enc(uint32_t return_code,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len)
+{
+ uint32_t index = 0;
+
+ return op_status_enc(SVC_ANT_CHANNEL_SEARCH_TIMEOUT_SET, return_code, p_buf, p_buf_len, &index);
+}
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/connectivity/codecs/ant/serializers/ant_channel_status_get.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/connectivity/codecs/ant/serializers/ant_channel_status_get.c
new file mode 100644
index 0000000..3f77fd4
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/connectivity/codecs/ant/serializers/ant_channel_status_get.c
@@ -0,0 +1,89 @@
+/**
+ * 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+
+#include <string.h>
+#include "ant_conn.h"
+#include "ble_serialization.h"
+#include "cond_field_serialization.h"
+#include "ant_struct_serialization.h"
+#include "app_util.h"
+
+uint32_t ant_channel_status_get_req_dec(uint8_t const * const p_buf,
+ uint16_t packet_len,
+ uint8_t * const p_channel)
+{
+ uint32_t index = SER_CMD_DATA_POS;
+ uint32_t err_code;
+
+ SER_ASSERT_NOT_NULL(p_buf);
+ SER_ASSERT_NOT_NULL(p_channel);
+
+ err_code = uint8_t_dec(p_buf, packet_len, &index, p_channel);
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code);
+
+ SER_ASSERT_LENGTH_EQ(index, packet_len);
+
+ return err_code;
+}
+
+uint32_t ant_channel_status_get_rsp_enc(uint32_t return_code,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len,
+ uint8_t const * const p_status)
+{
+ SER_ASSERT_NOT_NULL(p_buf);
+ SER_ASSERT_NOT_NULL(p_buf_len);
+
+ uint32_t total_len = *p_buf_len;
+
+ uint32_t err_code = ser_ble_cmd_rsp_status_code_enc(SVC_ANT_CHANNEL_STATUS_GET, return_code,
+ p_buf, p_buf_len);
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code);
+
+ if (return_code != NRF_SUCCESS)
+ {
+ return NRF_SUCCESS;
+ }
+
+ err_code = uint8_t_enc(p_status, p_buf, total_len, p_buf_len);
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code);
+
+ return NRF_SUCCESS;
+}
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/connectivity/codecs/ant/serializers/ant_channel_unassign.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/connectivity/codecs/ant/serializers/ant_channel_unassign.c
new file mode 100644
index 0000000..9c37cb9
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/connectivity/codecs/ant/serializers/ant_channel_unassign.c
@@ -0,0 +1,73 @@
+/**
+ * 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+
+#include <string.h>
+#include "ant_conn.h"
+#include "ble_serialization.h"
+#include "cond_field_serialization.h"
+#include "ant_struct_serialization.h"
+#include "app_util.h"
+
+uint32_t ant_channel_unassign_req_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ uint8_t * const p_channel)
+{
+ uint32_t index = SER_CMD_DATA_POS;
+ uint32_t err_code;
+
+ SER_ASSERT_NOT_NULL(p_buf);
+ SER_ASSERT_NOT_NULL(p_channel);
+
+ err_code = uint8_t_dec(p_buf, packet_len, &index, p_channel);
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code);
+
+ SER_ASSERT_LENGTH_EQ(index, packet_len);
+
+ return err_code;
+}
+
+uint32_t ant_channel_unassign_rsp_enc(uint32_t return_code,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len)
+{
+ uint32_t index = 0;
+
+ return op_status_enc(SVC_ANT_CHANNEL_UNASSIGN, return_code, p_buf, p_buf_len, &index);
+}
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/connectivity/codecs/ant/serializers/ant_coex_config_get.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/connectivity/codecs/ant/serializers/ant_coex_config_get.c
new file mode 100644
index 0000000..e15fbb2
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/connectivity/codecs/ant/serializers/ant_coex_config_get.c
@@ -0,0 +1,107 @@
+/**
+ * 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+
+#include <string.h>
+#include "ant_conn.h"
+#include "ble_serialization.h"
+#include "cond_field_serialization.h"
+#include "ant_struct_serialization.h"
+#include "app_util.h"
+
+uint32_t ant_coex_config_get_req_dec(uint8_t const * const p_buf,
+ uint16_t packet_len,
+ uint8_t * const p_channel)
+{
+ uint32_t index = SER_CMD_DATA_POS;
+ uint32_t err_code;
+
+ SER_ASSERT_NOT_NULL(p_buf);
+ SER_ASSERT_NOT_NULL(p_channel);
+
+ err_code = uint8_t_dec(p_buf, packet_len, &index, p_channel);
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code);
+
+ SER_ASSERT_LENGTH_EQ(index, packet_len);
+
+ return err_code;
+}
+
+uint32_t ant_coex_config_get_rsp_enc(uint32_t return_code,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len,
+ ANT_BUFFER_PTR * const p_coex_config,
+ ANT_BUFFER_PTR * const p_adv_coex_config)
+{
+ SER_ASSERT_NOT_NULL(p_buf);
+ SER_ASSERT_NOT_NULL(p_buf_len);
+
+ uint32_t total_len = *p_buf_len;
+
+ uint32_t err_code = ser_ble_cmd_rsp_status_code_enc(SVC_ANT_COEX_CONFIG_GET, return_code,
+ p_buf, p_buf_len);
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code);
+
+ if (return_code != NRF_SUCCESS)
+ {
+ return NRF_SUCCESS;
+ }
+
+ err_code = uint8_t_enc(&(p_coex_config->ucBufferSize), p_buf, total_len, p_buf_len);
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code);
+
+ err_code = uint8_vector_enc(p_coex_config->pucBuffer,
+ p_coex_config->ucBufferSize,
+ p_buf,
+ total_len,
+ p_buf_len);
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code);
+
+ err_code = uint8_t_enc(&(p_adv_coex_config->ucBufferSize), p_buf, total_len, p_buf_len);
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code);
+
+ err_code = uint8_vector_enc(p_adv_coex_config->pucBuffer,
+ p_adv_coex_config->ucBufferSize,
+ p_buf,
+ total_len,
+ p_buf_len);
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code);
+
+ return NRF_SUCCESS;
+}
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/connectivity/codecs/ant/serializers/ant_coex_config_set.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/connectivity/codecs/ant/serializers/ant_coex_config_set.c
new file mode 100644
index 0000000..730cb1e
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/connectivity/codecs/ant/serializers/ant_coex_config_set.c
@@ -0,0 +1,101 @@
+/**
+ * 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+
+#include <string.h>
+#include "ant_conn.h"
+#include "ble_serialization.h"
+#include "cond_field_serialization.h"
+#include "ant_struct_serialization.h"
+#include "app_util.h"
+
+uint32_t ant_coex_config_set_req_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ uint8_t * const p_channel,
+ ANT_BUFFER_PTR * const p_coex_config,
+ ANT_BUFFER_PTR * const p_adv_coex_config)
+{
+ uint32_t index = SER_CMD_DATA_POS;
+ uint32_t err_code;
+
+ SER_ASSERT_NOT_NULL(p_buf);
+ SER_ASSERT_NOT_NULL(p_channel);
+ SER_ASSERT_NOT_NULL(p_coex_config);
+ SER_ASSERT_NOT_NULL(p_adv_coex_config);
+
+ err_code = uint8_t_dec(p_buf, packet_len, &index, p_channel);
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code);
+
+ // Decode coex config buffer size
+ err_code = uint8_t_dec(p_buf, packet_len, &index, &(p_coex_config->ucBufferSize));
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code);
+
+ // Decode coex config buffer
+ err_code = uint8_vector_dec(p_buf,
+ packet_len,
+ &index,
+ p_coex_config->pucBuffer,
+ p_coex_config->ucBufferSize);
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code);
+
+ // Decode advanced coex config buffer size
+ err_code = uint8_t_dec(p_buf, packet_len, &index, &(p_adv_coex_config->ucBufferSize));
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code);
+
+ // Decode advanced coex config buffer
+ err_code = uint8_vector_dec(p_buf,
+ packet_len,
+ &index,
+ p_adv_coex_config->pucBuffer,
+ p_adv_coex_config->ucBufferSize);
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code);
+
+ SER_ASSERT_LENGTH_EQ(index, packet_len);
+
+ return err_code;
+}
+
+uint32_t ant_coex_config_set_rsp_enc(uint32_t return_code,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len)
+{
+ uint32_t index = 0;
+
+ return op_status_enc(SVC_ANT_COEX_CONFIG_SET, return_code, p_buf, p_buf_len, &index);
+}
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/connectivity/codecs/ant/serializers/ant_conn.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/connectivity/codecs/ant/serializers/ant_conn.h
new file mode 100644
index 0000000..0f70413
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/connectivity/codecs/ant/serializers/ant_conn.h
@@ -0,0 +1,1591 @@
+/**
+ * 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#ifndef ANT_CONN_H__
+#define ANT_CONN_H__
+
+
+/**
+ * @addtogroup ser_conn_s212_codecs Connectivity codecs for S212
+ * @ingroup ser_codecs_conn
+ */
+
+/**@file
+ *
+ * @defgroup ant_conn Connectivity command request decoders and command response encoders
+ * @{
+ * @ingroup ser_conn_s212_codecs
+ *
+ * @brief Connectivity command request decoders and command response encoders.
+ */
+#include "ant_interface.h"
+
+/**@brief Decodes @ref sd_ant_enable command request.
+ *
+ * @sa @ref ant_enable_rsp_enc for response encoding.
+ *
+ * @param[in] p_buf Pointer to beginning of command request packet.
+ * @param[in] packet_len Length (in bytes) of response packet.
+ * @param[out] pp_ant_enable_params Pointer to pointer to @ref ANT_ENABLE.
+ * \c It will be set to NULL if p_ant_enable_params is not
+ * present in the packet.
+ *
+ * @retval NRF_SUCCESS Decoding success.
+ * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length.
+ */
+uint32_t ant_enable_req_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ ANT_ENABLE * * const pp_ant_enable_params);
+
+/**@brief Encodes @ref sd_ant_enable command response.
+ *
+ * @sa @ref ant_enable_req_dec for request decoding.
+ *
+ * @param[in] return_code Return code indicating if command was successful or not.
+ * @param[out] p_buf Pointer to buffer where encoded data command response will be
+ * returned.
+ * @param[in,out] p_buf_len \c in: Size of \p p_buf buffer.
+ * \c out: Length of encoded command response packet.
+ *
+ * @retval NRF_SUCCESS Encoding success.
+ * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length.
+ */
+uint32_t ant_enable_rsp_enc(uint32_t return_code,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len);
+
+/**@brief Decodes @ref sd_ant_channel_assign command request.
+ *
+ * @sa @ref ant_channel_assign_rsp_enc for response encoding.
+ *
+ * @param[in] p_buf Pointer to beginning of command request packet.
+ * @param[in] packet_len Length (in bytes) of response packet.
+ *
+ * @param[out] p_channel Pointer to an unsigned char (1 octet) where the channel to be
+ * assigned will be set.
+ * @param[out] p_type Pointer to an unsigned char (1 octet) where the channel type
+ * to be assigned will be set.
+ * @param[out] p_network Pointer to an unsigned char (1 octet) where the network key to
+ * associate with the channel will be set.
+ * @param[out] p_ext_assign Pointer to a bit field (1 octet) where an extended assign will
+ * be set.
+ *
+ * @retval NRF_SUCCESS Decoding success.
+ * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length.
+ */
+uint32_t ant_channel_assign_req_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ uint8_t * const p_channel,
+ uint8_t * const p_type,
+ uint8_t * const p_network,
+ uint8_t * const p_ext_assign);
+
+/**@brief Encodes @ref sd_ant_channel_assign command response.
+ *
+ * @sa @ref ant_channel_assign_req_dec for request decoding.
+ *
+ * @param[in] return_code Return code indicating if command was successful or not.
+ * @param[out] p_buf Pointer to buffer where encoded data command response will be
+ * returned.
+ * @param[in,out] p_buf_len \c in: Size of \p p_buf buffer.
+ * \c out: Length of encoded command response packet.
+ *
+ * @retval NRF_SUCCESS Encoding success.
+ * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length.
+ */
+uint32_t ant_channel_assign_rsp_enc(uint32_t return_code,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len);
+
+/**@brief Decodes @ref sd_ant_channel_open command request.
+ *
+ * @sa @ref ant_channel_open_with_offset_rsp_enc for response encoding.
+ *
+ * @param[in] p_buf Pointer to beginning of command request packet.
+ * @param[in] packet_len Length (in bytes) of response packet.
+ *
+ * @param[out] p_channel Pointer to an unsigned char (1 octet) where the channel to be
+ * opened will be set.
+ * @param[out] p_usOffset Pointer to a channel start time offset value.
+ *
+ * @retval NRF_SUCCESS Decoding success.
+ * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length.
+ */
+uint32_t ant_channel_open_with_offset_req_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ uint8_t * const p_channel,
+ uint16_t * const p_usOffset);
+
+/**@brief Encodes @ref sd_ant_channel_open command response.
+ *
+ * @sa @ref ant_channel_open_with_offset_req_dec for request decoding.
+ *
+ * @param[in] return_code Return code indicating if command was successful or not.
+ * @param[out] p_buf Pointer to buffer where encoded data command response will be
+ * returned.
+ * @param[in,out] p_buf_len \c in: Size of \p p_buf buffer.
+ * \c out: Length of encoded command response packet.
+ *
+ * @retval NRF_SUCCESS Encoding success.
+ * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length.
+ */
+uint32_t ant_channel_open_with_offset_rsp_enc(uint32_t return_code,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len);
+
+/**@brief Decodes @ref sd_ant_channel_id_set command request.
+ *
+ * @sa @ref ant_channel_id_set_rsp_enc for response encoding.
+ *
+ * @param[in] p_buf Pointer to beginning of command request packet.
+ * @param[in] packet_len Length (in bytes) of response packet.
+ *
+ * @param[out] p_channel Pointer to an unsigned char (1 octet) where the channel number
+ * will be set.
+ * @param[out] p_device_number Pointer to an unsigned short (2 octets) where the device
+ * number will be set.
+ * @param[out] p_device_type Pointer to an an unsigned char (1 octet) where the device type
+ * will be set.
+ * @param[out] p_transmission_type Pointer to an unsigned char (1 octet) where the transmission
+ * type will be set.
+ *
+ * @retval NRF_SUCCESS Decoding success.
+ * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length.
+ */
+uint32_t ant_channel_id_set_req_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ uint8_t * const p_channel,
+ uint16_t * const p_device_number,
+ uint8_t * const p_device_type,
+ uint8_t * const p_transmission_type);
+
+/**@brief Encodes @ref sd_ant_channel_id_set command response.
+ *
+ * @sa @ref ant_channel_id_set_req_dec for request decoding.
+ *
+ * @param[in] return_code Return code indicating if command was successful or not.
+ * @param[out] p_buf Pointer to buffer where encoded data command response will be
+ * returned.
+ * @param[in,out] p_buf_len \c in: Size of \p p_buf buffer.
+ * \c out: Length of encoded command response packet.
+ *
+ * @retval NRF_SUCCESS Encoding success.
+ * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length.
+ */
+uint32_t ant_channel_id_set_rsp_enc(uint32_t return_code,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len);
+
+/**@brief Decodes @ref sd_ant_channel_period_set command request.
+ *
+ * @sa @ref ant_channel_period_set_rsp_enc for response encoding.
+ *
+ * @param[in] p_buf Pointer to beginning of command request packet.
+ * @param[in] packet_len Length (in bytes) of response packet.
+ *
+ * @param[out] p_channel Pointer to an unsigned char (1 octet) where the channel number
+ * associated with the period will be set.
+ * @param[out] p_period Pointer to an unsigned short (2 octets) where the period will
+ * be set. Value is in 32 kHz counts (usPeriod/32768 s).
+ *
+ * @retval NRF_SUCCESS Decoding success.
+ * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length.
+ */
+uint32_t ant_channel_period_set_req_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ uint8_t * const p_channel,
+ uint16_t * const p_period);
+
+/**@brief Encodes @ref sd_ant_channel_period_set command response.
+ *
+ * @sa @ref ant_channel_period_set_req_dec for request decoding.
+ *
+ * @param[in] return_code Return code indicating if command was successful or not.
+ * @param[out] p_buf Pointer to buffer where encoded data command response will be
+ * returned.
+ * @param[in,out] p_buf_len \c in: Size of \p p_buf buffer.
+ * \c out: Length of encoded command response packet.
+ *
+ * @retval NRF_SUCCESS Encoding success.
+ * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length.
+ */
+uint32_t ant_channel_period_set_rsp_enc(uint32_t return_code,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len);
+
+/**@brief Decodes @ref sd_ant_channel_radio_freq_set command request.
+ *
+ * @sa @ref ant_channel_radio_freq_set_rsp_enc for response encoding.
+ *
+ * @param[in] p_buf Pointer to beginning of command request packet.
+ * @param[in] packet_len Length (in bytes) of response packet.
+ *
+ * @param[out] p_channel Pointer to an unsigned char (1 octet) where the channel number
+ * associated with the radio frequency will be set.
+ * @param[out] p_freq Pointer to an unsigned char (1 octet) where the radio
+ * frequency will be set. Value is offset from 2400 MHz
+ * (eg. 2466 MHz, ucFreq = 66).
+ *
+ * @retval NRF_SUCCESS Decoding success.
+ * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length.
+ */
+uint32_t ant_channel_radio_freq_set_req_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ uint8_t * const p_channel,
+ uint8_t * const p_freq);
+
+/**@brief Encodes @ref sd_ant_channel_radio_freq_set command response.
+ *
+ * @sa @ref ant_channel_radio_freq_set_req_dec for request decoding.
+ *
+ * @param[in] return_code Return code indicating if command was successful or not.
+ * @param[out] p_buf Pointer to buffer where encoded data command response will be
+ * returned.
+ * @param[in,out] p_buf_len \c in: Size of \p p_buf buffer.
+ * \c out: Length of encoded command response packet.
+ *
+ * @retval NRF_SUCCESS Encoding success.
+ * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length.
+ */
+uint32_t ant_channel_radio_freq_set_rsp_enc(uint32_t return_code,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len);
+
+/**@brief Decodes @ref sd_ant_broadcast_message_tx command request.
+ *
+ * @sa @ref ant_broadcast_message_tx_rsp_enc for response encoding.
+ *
+ * @param[in] p_buf Pointer to beginning of command request packet.
+ * @param[in] packet_len Length (in bytes) of response packet.
+ *
+ * @param[out] p_channel Pointer to an unsigned char (1 octet) where the channel to
+ * send the data on will be set.
+ * @param[out] p_size Pointer to an unsigned char (1 octet) where the size of the
+ * message will be set.
+ * @param[out] pp_mesg Pointer to pointer to the buffer where the broadcast message
+ * will be set (array must be 8 octets).
+ *
+ * @retval NRF_SUCCESS Decoding success.
+ * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length.
+ */
+uint32_t ant_broadcast_message_tx_req_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ uint8_t * const p_channel,
+ uint8_t * const p_size,
+ uint8_t * * const pp_mesg);
+
+/**@brief Encodes @ref sd_ant_broadcast_message_tx command response.
+ *
+ * @sa @ref ant_broadcast_message_tx_req_dec for request decoding.
+ *
+ * @param[in] return_code Return code indicating if command was successful or not.
+ * @param[out] p_buf Pointer to buffer where encoded data command response will be
+ * returned.
+ * @param[in,out] p_buf_len \c in: Size of \p p_buf buffer.
+ * \c out: Length of encoded command response packet.
+ *
+ * @retval NRF_SUCCESS Encoding success.
+ * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length.
+ */
+uint32_t ant_broadcast_message_tx_rsp_enc(uint32_t return_code,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len);
+
+/**@brief Decodes @ref sd_ant_acknowledge_message_tx command request.
+ *
+ * @sa @ref ant_acknowledge_message_tx_rsp_enc for response encoding.
+ *
+ * @param[in] p_buf Pointer to beginning of command request packet.
+ * @param[in] packet_len Length (in bytes) of response packet.
+ *
+ * @param[out] p_channel Pointer to an unsigned char (1 octet) where the channel to
+ * send the data on will be set.
+ * @param[out] p_size Pointer to an unsigned char (1 octet) where the size of the
+ * message will be set.
+ * @param[out] pp_mesg Pointer to pointer to the buffer where the acknowledge message
+ * will be set (array must be 8 octets).
+ *
+ * @retval NRF_SUCCESS Decoding success.
+ * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length.
+ */
+uint32_t ant_acknowledge_message_tx_req_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ uint8_t * const p_channel,
+ uint8_t * const p_size,
+ uint8_t * * const pp_mesg);
+
+/**@brief Encodes @ref sd_ant_acknowledge_message_tx command response.
+ *
+ * @sa @ref ant_acknowledge_message_tx_req_dec for request decoding.
+ *
+ * @param[in] return_code Return code indicating if command was successful or not.
+ * @param[out] p_buf Pointer to buffer where encoded data command response will be
+ * returned.
+ * @param[in,out] p_buf_len \c in: Size of \p p_buf buffer.
+ * \c out: Length of encoded command response packet.
+ *
+ * @retval NRF_SUCCESS Encoding success.
+ * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length.
+ */
+uint32_t ant_acknowledge_message_tx_rsp_enc(uint32_t return_code,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len);
+
+/**@brief Decodes @ref sd_ant_channel_unassign command request.
+ *
+ * @sa @ref ant_channel_unassign_rsp_enc for response encoding.
+ *
+ * @param[in] p_buf Pointer to beginning of command request packet.
+ * @param[in] packet_len Length (in bytes) of response packet.
+ *
+ * @param[out] p_channel Pointer to an unsigned char (1 octet) where the channel to be
+ * unassigned will be set.
+ *
+ * @retval NRF_SUCCESS Decoding success.
+ * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length.
+ */
+uint32_t ant_channel_unassign_req_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ uint8_t * const p_channel);
+
+/**@brief Encodes @ref sd_ant_channel_unassign command response.
+ *
+ * @sa @ref ant_channel_unassign_req_dec for request decoding.
+ *
+ * @param[in] return_code Return code indicating if command was successful or not.
+ * @param[out] p_buf Pointer to buffer where encoded data command response will be
+ * returned.
+ * @param[in,out] p_buf_len \c in: Size of \p p_buf buffer.
+ * \c out: Length of encoded command response packet.
+ *
+ * @retval NRF_SUCCESS Encoding success.
+ * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length.
+ */
+uint32_t ant_channel_unassign_rsp_enc(uint32_t return_code,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len);
+
+/**@brief Decodes @ref sd_ant_channel_close command request.
+ *
+ * @sa @ref ant_channel_close_rsp_enc for response encoding.
+ *
+ * @param[in] p_buf Pointer to beginning of command request packet.
+ * @param[in] packet_len Length (in bytes) of response packet.
+ *
+ * @param[out] p_channel Pointer to an unsigned char (1 octet) where the channel to be
+ * closed will be set.
+ *
+ * @retval NRF_SUCCESS Decoding success.
+ * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length.
+ */
+uint32_t ant_channel_close_req_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ uint8_t * const p_channel);
+
+/**@brief Encodes @ref sd_ant_channel_close command response.
+ *
+ * @sa @ref ant_channel_close_req_dec for request decoding.
+ *
+ * @param[in] return_code Return code indicating if command was successful or not.
+ * @param[out] p_buf Pointer to buffer where encoded data command response will be
+ * returned.
+ * @param[in,out] p_buf_len \c in: Size of \p p_buf buffer.
+ * \c out: Length of encoded command response packet.
+ *
+ * @retval NRF_SUCCESS Encoding success.
+ * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length.
+ */
+uint32_t ant_channel_close_rsp_enc(uint32_t return_code,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len);
+
+/**@brief Decodes @ref sd_ant_network_address_set command request.
+ *
+ * @sa @ref ant_network_address_set_rsp_enc for response encoding.
+ *
+ * @param[in] p_buf Pointer to beginning of command request packet.
+ * @param[in] packet_len Length (in bytes) of response packet.
+ *
+ * @param[out] p_network Pointer to an unsigned char (1 octet) where the network number
+ * to assign the network address to will be set.
+ * @param[out] pp_network_key Pointer to a pointer to where the network key (8 octets in
+ * length) will be set.
+ *
+ * @retval NRF_SUCCESS Decoding success.
+ * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length.
+ */
+uint32_t ant_network_address_set_req_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ uint8_t * const p_network,
+ uint8_t * * const pp_network_key);
+
+/**@brief Encodes @ref sd_ant_network_address_set command response.
+ *
+ * @sa @ref ant_network_address_set_req_dec for request decoding.
+ *
+ * @param[in] return_code Return code indicating if command was successful or not.
+ * @param[out] p_buf Pointer to buffer where encoded data command response will be
+ * returned.
+ * @param[in,out] p_buf_len \c in: Size of \p p_buf buffer.
+ * \c out: Length of encoded command response packet.
+ *
+ * @retval NRF_SUCCESS Encoding success.
+ * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length.
+ */
+uint32_t ant_network_address_set_rsp_enc(uint32_t return_code,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len);
+
+/**@brief Decodes @ref sd_ant_channel_radio_tx_power_set command request.
+ *
+ * @sa @ref ant_channel_radio_tx_power_set_rsp_enc for response encoding.
+ *
+ * @param[in] p_buf Pointer to beginning of command request packet.
+ * @param[in] packet_len Length (in bytes) of response packet.
+ *
+ * @param[out] p_channel Pointer to an unsigned char (1 octet) where the channel number
+ * to assign the radio TX power will be set.
+ * @param[out] p_tx_power Pointer to an unsigned char (1 octet) where the ANT transmit
+ * power index will be set. See Radio TX Power Definitions in
+ * ant_parameters.h.
+ * @param[out] p_custom_tx_power Pointer to an unsigned char (1 octet) where the custom nRF
+ * transmit power as defined in nrf51_bitfields.h will be set.
+ * Only applicable if tx_power is set to custom TX power
+ * selection.
+ *
+ * @retval NRF_SUCCESS Decoding success.
+ * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length.
+ */
+uint32_t ant_channel_radio_tx_power_set_req_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ uint8_t * const p_channel,
+ uint8_t * const p_tx_power,
+ uint8_t * const p_custom_tx_power);
+
+/**@brief Encodes @ref sd_ant_channel_radio_tx_power_set command response.
+ *
+ * @sa @ref ant_channel_radio_tx_power_set_req_dec for request decoding.
+ *
+ * @param[in] return_code Return code indicating if command was successful or not.
+ * @param[out] p_buf Pointer to buffer where encoded data command response will be
+ * returned.
+ * @param[in,out] p_buf_len \c in: Size of \p p_buf buffer.
+ * \c out: Length of encoded command response packet.
+ *
+ * @retval NRF_SUCCESS Encoding success.
+ * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length.
+ */
+uint32_t ant_channel_radio_tx_power_set_rsp_enc(uint32_t return_code,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len);
+
+/**@brief Decodes @ref sd_ant_channel_rx_search_timeout_set command request.
+ *
+ * @sa @ref ant_channel_rx_search_timeout_set_rsp_enc for response encoding.
+ *
+ * @param[in] p_buf Pointer to beginning of command request packet.
+ * @param[in] packet_len Length (in bytes) of response packet.
+ *
+ * @param[out] p_channel Pointer to an unsigned char (1 octet) where the channel number
+ * will be set.
+ * @param[out] p_timeout Pointer to an unsigned char (1 octet) where the time-out value
+ * will be set.
+ *
+ * @retval NRF_SUCCESS Decoding success.
+ * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length.
+ */
+uint32_t ant_channel_rx_search_timeout_set_req_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ uint8_t * const p_channel,
+ uint8_t * const p_timeout);
+
+/**@brief Encodes @ref sd_ant_channel_rx_search_timeout_set command response.
+ *
+ * @sa @ref ant_channel_rx_search_timeout_set_req_dec for request decoding.
+ *
+ * @param[in] return_code Return code indicating if command was successful or not.
+ * @param[out] p_buf Pointer to buffer where encoded data command response will be
+ * returned.
+ * @param[in,out] p_buf_len \c in: Size of \p p_buf buffer.
+ * \c out: Length of encoded command response packet.
+ *
+ * @retval NRF_SUCCESS Encoding success.
+ * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length.
+ */
+uint32_t ant_channel_rx_search_timeout_set_rsp_enc(uint32_t return_code,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len);
+
+/**@brief Decodes @ref sd_ant_channel_low_priority_rx_search_timeout_set command request.
+ *
+ * @sa @ref ant_channel_low_priority_rx_search_timeout_set_rsp_enc for response encoding.
+ *
+ * @param[in] p_buf Pointer to beginning of command request packet.
+ * @param[in] packet_len Length (in bytes) of response packet.
+ *
+ * @param[out] p_channel Pointer to an unsigned char (1 octet) where the channel number
+ * will be set.
+ * @param[out] p_timeout Pointer to an unsigned char (1 octet) where the time-out value
+ * will be set.
+ *
+ * @retval NRF_SUCCESS Decoding success.
+ * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length.
+ */
+uint32_t ant_channel_low_priority_rx_search_timeout_set_req_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ uint8_t * const p_channel,
+ uint8_t * const p_timeout);
+
+/**@brief Encodes @ref sd_ant_channel_low_priority_rx_search_timeout_set command response.
+ *
+ * @sa @ref ant_channel_low_priority_rx_search_timeout_set_req_dec for request decoding.
+ *
+ * @param[in] return_code Return code indicating if command was successful or not.
+ * @param[out] p_buf Pointer to buffer where encoded data command response will be
+ * returned.
+ * @param[in,out] p_buf_len \c in: Size of \p p_buf buffer.
+ * \c out: Length of encoded command response packet.
+ *
+ * @retval NRF_SUCCESS Encoding success.
+ * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length.
+ */
+uint32_t ant_channel_low_priority_rx_search_timeout_set_rsp_enc(uint32_t return_code,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len);
+
+/**@brief Decodes @ref sd_ant_prox_search_set command request.
+ *
+ * @sa @ref ant_prox_search_set_rsp_enc for response encoding.
+ *
+ * @param[in] p_buf Pointer to beginning of command request packet.
+ * @param[in] packet_len Length (in bytes) of response packet.
+ *
+ * @param[out] p_channel Pointer to an unsigned char (1 octet) where the channel
+ * number will be set.
+ * @param[out] p_prox_threshold Pointer to an unsigned char (1 octet) where the minimum
+ * RSSI threshold required for acquisition during a search
+ * will be set. See Radio Proximity Search Threshold in
+ * ant_parameters.h.
+ * @param[out] p_custom_prox_threshold Pointer to an unsigned char (1 octet) where the custom
+ * minimum RSSI threshold for acquisition during a search
+ * will be set. Only applicable if prox_threshold is set to
+ * custom proximity selection.
+ *
+ * @retval NRF_SUCCESS Decoding success.
+ * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length.
+ */
+uint32_t ant_prox_search_set_req_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ uint8_t * const p_channel,
+ uint8_t * const p_prox_threshold,
+ uint8_t * const p_custom_prox_threshold);
+
+/**@brief Encodes @ref sd_ant_prox_search_set command response.
+ *
+ * @sa @ref ant_prox_search_set_req_dec for request decoding.
+ *
+ * @param[in] return_code Return code indicating if command was successful or not.
+ * @param[out] p_buf Pointer to buffer where encoded data command response will be
+ * returned.
+ * @param[in,out] p_buf_len \c in: Size of \p p_buf buffer.
+ * \c out: Length of encoded command response packet.
+ *
+ * @retval NRF_SUCCESS Encoding success.
+ * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length.
+ */
+uint32_t ant_prox_search_set_rsp_enc(uint32_t return_code,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len);
+
+/**@brief Decodes @ref sd_ant_search_waveform_set command request.
+ *
+ * @sa @ref ant_search_waveform_set_rsp_enc for response encoding.
+ *
+ * @param[in] p_buf Pointer to beginning of command request packet.
+ * @param[in] packet_len Length (in bytes) of response packet.
+ *
+ * @param[out] p_channel Pointer to an unsigned char (1 octet) where the channel
+ * number will be set.
+ * @param[out] p_waveform Pointer to an unsigned short (2 octets) where the channel
+ * waveform period (usWaveform/32768 s) will be set.
+ * Default = 316.
+ *
+ * @retval NRF_SUCCESS Decoding success.
+ * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length.
+ */
+uint32_t ant_search_waveform_set_req_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ uint8_t * const p_channel,
+ uint16_t * const p_waveform);
+
+/**@brief Encodes @ref sd_ant_search_waveform_set command response.
+ *
+ * @sa @ref ant_search_waveform_set_req_dec for request decoding.
+ *
+ * @param[in] return_code Return code indicating if command was successful or not.
+ * @param[out] p_buf Pointer to buffer where encoded data command response will be
+ * returned.
+ * @param[in,out] p_buf_len \c in: Size of \p p_buf buffer.
+ * \c out: Length of encoded command response packet.
+ *
+ * @retval NRF_SUCCESS Encoding success.
+ * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length.
+ */
+uint32_t ant_search_waveform_set_rsp_enc(uint32_t return_code,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len);
+
+/**@brief Decodes @ref sd_ant_channel_id_get command request.
+ *
+ * @sa @ref ant_channel_id_get_rsp_enc for response encoding.
+ *
+ * @param[in] p_buf Pointer to beginning of command request packet.
+ * @param[in] packet_len Length (in bytes) of response packet.
+ *
+ * @param[out] p_channel Pointer to an unsigned char (1 octet) where the channel
+ * number will be set.
+ *
+ * @retval NRF_SUCCESS Decoding success.
+ * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length.
+ */
+uint32_t ant_channel_id_get_req_dec(uint8_t const * const p_buf,
+ uint16_t packet_len,
+ uint8_t * const p_channel);
+
+/**@brief Encodes @ref sd_ant_channel_id_get command response.
+ *
+ * @sa @ref ant_channel_id_get_req_dec for request decoding.
+ *
+ * @param[in] return_code Return code indicating if command was successful or not.
+ * @param[out] p_buf Pointer to buffer where encoded data command response will be
+ * returned.
+ * @param[in,out] p_buf_len \c in: Size of \p p_buf buffer.
+ * \c out: Length of encoded command response packet.
+ * @param[in] p_device_number Pointer to device number
+ * @param[in] p_device_type Pointer to device type
+ * @param[in] p_transmit_type Pointer to transmit type
+ *
+ * @retval NRF_SUCCESS Encoding success.
+ * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length.
+ */
+uint32_t ant_channel_id_get_rsp_enc(uint32_t return_code,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len,
+ uint16_t const * const p_device_number,
+ uint8_t const * const p_device_type,
+ uint8_t const * const p_transmit_type);
+
+/**@brief Decodes @ref sd_ant_channel_radio_freq_get command request.
+ *
+ * @sa @ref ant_channel_radio_freq_get_rsp_enc for response encoding.
+ *
+ * @param[in] p_buf Pointer to beginning of command request packet.
+ * @param[in] packet_len Length (in bytes) of response packet.
+ *
+ * @param[out] p_channel Pointer to an unsigned char (1 octet) where the channel number
+ * will be set.
+ *
+ * @retval NRF_SUCCESS Decoding success.
+ * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length.
+ */
+uint32_t ant_channel_radio_freq_get_req_dec(uint8_t const * const p_buf,
+ uint16_t packet_len,
+ uint8_t * const p_channel);
+
+/**@brief Encodes @ref sd_ant_channel_radio_freq_get command response.
+ *
+ * @sa @ref ant_channel_radio_freq_get_req_dec for request decoding.
+ *
+ * @param[in] return_code Return code indicating if command was successful or not.
+ * @param[out] p_buf Pointer to buffer where encoded data command response will be
+ * returned.
+ * @param[in,out] p_buf_len \c in: Size of \p p_buf buffer.
+ * \c out: Length of encoded command response packet.
+ * @param[in] p_r_freq Pointer to radio frequency
+ *
+ * @retval NRF_SUCCESS Encoding success.
+ * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length.
+ */
+uint32_t ant_channel_radio_freq_get_rsp_enc(uint32_t return_code,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len,
+ uint8_t const * const p_r_freq);
+
+/**@brief Decodes @ref sd_ant_channel_period_get command request.
+ *
+ * @sa @ref ant_channel_period_get_rsp_enc for response encoding.
+ *
+ * @param[in] p_buf Pointer to beginning of command request packet.
+ * @param[in] packet_len Length (in bytes) of response packet.
+ *
+ * @param[out] p_channel Pointer to an unsigned char (1 octet) where the channel number
+ * will be set.
+ *
+ * @retval NRF_SUCCESS Decoding success.
+ * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length.
+ */
+uint32_t ant_channel_period_get_req_dec(uint8_t const * const p_buf,
+ uint16_t packet_len,
+ uint8_t * const p_channel);
+
+/**@brief Encodes @ref sd_ant_channel_period_get command response.
+ *
+ * @sa @ref ant_channel_period_get_req_dec for request decoding.
+ *
+ * @param[in] return_code Return code indicating if command was successful or not.
+ * @param[out] p_buf Pointer to buffer where encoded data command response will be
+ * returned.
+ * @param[in,out] p_buf_len \c in: Size of \p p_buf buffer.
+ * \c out: Length of encoded command response packet.
+ * @param[in] p_period Pointer to period
+ *
+ * @retval NRF_SUCCESS Encoding success.
+ * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length.
+ */
+uint32_t ant_channel_period_get_rsp_enc(uint32_t return_code,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len,
+ uint16_t const * const p_period);
+
+/**@brief Decodes @ref sd_ant_search_channel_priority_set command request.
+ *
+ * @sa @ref ant_search_channel_priority_set_rsp_enc for response encoding.
+ *
+ * @param[in] p_buf Pointer to beginning of command request packet.
+ * @param[in] packet_len Length (in bytes) of response packet.
+ *
+ * @param[out] p_channel Pointer to an unsigned char (1 octet) where the channel number
+ * will be set.
+ * @param[out] p_search_priority Pointer to an unsigned char (1 octet) where the search
+ * priority value will be set. 0 to 7 (Default = 0).
+ *
+ * @retval NRF_SUCCESS Decoding success.
+ * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length.
+ */
+uint32_t ant_search_channel_priority_set_req_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ uint8_t * const p_channel,
+ uint8_t * const p_search_priority);
+
+/**@brief Encodes @ref sd_ant_search_channel_priority_set command response.
+ *
+ * @sa @ref ant_search_channel_priority_set_req_dec for request decoding.
+ *
+ * @param[in] return_code Return code indicating if command was successful or not.
+ * @param[out] p_buf Pointer to buffer where encoded data command response will be
+ * returned.
+ * @param[in,out] p_buf_len \c in: Size of \p p_buf buffer.
+ * \c out: Length of encoded command response packet.
+ *
+ * @retval NRF_SUCCESS Encoding success.
+ * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length.
+ */
+uint32_t ant_search_channel_priority_set_rsp_enc(uint32_t return_code,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len);
+
+/**@brief Decodes @ref sd_ant_active_search_sharing_cycles_set command request.
+ *
+ * @sa @ref ant_active_search_sharing_cycles_set_rsp_enc for response encoding.
+ *
+ * @param[in] p_buf Pointer to beginning of command request packet.
+ * @param[in] packet_len Length (in bytes) of response packet.
+ *
+ * @param[out] p_channel Pointer to an unsigned char (1 octet) where the channel number
+ * will be set.
+ * @param[out] p_cycles Pointer to an unsigned char (1 octet) where the numbe of
+ * cycles will be set.
+ *
+ * @retval NRF_SUCCESS Decoding success.
+ * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length.
+ */
+uint32_t ant_active_search_sharing_cycles_set_req_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ uint8_t * const p_channel,
+ uint8_t * const p_cycles);
+
+/**@brief Encodes @ref sd_ant_active_search_sharing_cycles_set command response.
+ *
+ * @sa @ref ant_active_search_sharing_cycles_set_req_dec for request decoding.
+ *
+ * @param[in] return_code Return code indicating if command was successful or not.
+ * @param[out] p_buf Pointer to buffer where encoded data command response will be
+ * returned.
+ * @param[in,out] p_buf_len \c in: Size of \p p_buf buffer.
+ * \c out: Length of encoded command response packet.
+ *
+ * @retval NRF_SUCCESS Encoding success.
+ * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length.
+ */
+uint32_t ant_active_search_sharing_cycles_set_rsp_enc(uint32_t return_code,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len);
+
+/**@brief Decodes @ref sd_ant_lib_config_set command request.
+ *
+ * @sa @ref ant_lib_config_set_rsp_enc for response encoding.
+ *
+ * @param[in] p_buf Pointer to beginning of command request packet.
+ * @param[in] packet_len Length (in bytes) of response packet.
+ *
+ * @param[out] p_ant_lib_config Pointer to an unsigned char (1 octet) where the ANT lib
+ * config bit flags will be set. See ANT Library Config in
+ * ant_parameters.h.
+ *
+ * @retval NRF_SUCCESS Decoding success.
+ * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length.
+ */
+uint32_t ant_lib_config_set_req_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ uint8_t * const p_ant_lib_config);
+
+/**@brief Encodes @ref sd_ant_lib_config_set command response.
+ *
+ * @sa @ref ant_lib_config_set_req_dec for request decoding.
+ *
+ * @param[in] return_code Return code indicating if command was successful or not.
+ * @param[out] p_buf Pointer to buffer where encoded data command response will be
+ * returned.
+ * @param[in,out] p_buf_len \c in: Size of \p p_buf buffer.
+ * \c out: Length of encoded command response packet.
+ *
+ * @retval NRF_SUCCESS Encoding success.
+ * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length.
+ */
+uint32_t ant_lib_config_set_rsp_enc(uint32_t return_code,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len);
+
+/**@brief Decodes @ref sd_ant_active_search_sharing_cycles_get command request.
+ *
+ * @sa @ref ant_active_search_sharing_cycles_get_rsp_enc for response encoding.
+ *
+ * @param[in] p_buf Pointer to beginning of command request packet.
+ * @param[in] packet_len Length (in bytes) of response packet.
+ *
+ * @param[out] p_channel Pointer to an unsigned char (1 octet) where the channel number
+ * will be set.
+ *
+ * @retval NRF_SUCCESS Decoding success.
+ * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length.
+ */
+uint32_t ant_active_search_sharing_cycles_get_req_dec(uint8_t const * const p_buf,
+ uint16_t packet_len,
+ uint8_t * const p_channel);
+
+/**@brief Encodes @ref sd_ant_active_search_sharing_cycles_get command response.
+ *
+ * @sa @ref ant_active_search_sharing_cycles_get_req_dec for request decoding.
+ *
+ * @param[in] return_code Return code indicating if command was successful or not.
+ * @param[out] p_buf Pointer to buffer where encoded data command response will be
+ * returned.
+ * @param[in,out] p_buf_len \c in: Size of \p p_buf buffer.
+ * \c out: Length of encoded command response packet.
+ * @param[in] p_cycles Pointer to cycles.
+ *
+ * @retval NRF_SUCCESS Encoding success.
+ * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length.
+ */
+uint32_t ant_active_search_sharing_cycles_get_rsp_enc(uint32_t return_code,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len,
+ uint8_t const * const p_cycles);
+
+/**@brief Encodes @ref sd_ant_lib_config_get command response.
+ *
+ * @param[in] return_code Return code indicating if command was successful or not.
+ * @param[out] p_buf Pointer to buffer where encoded data command response will be
+ * returned.
+ * @param[in,out] p_buf_len \c in: Size of \p p_buf buffer.
+ * \c out: Length of encoded command response packet.
+ * @param[in] p_ant_lib_config Pointer to ANT library configuration.
+ *
+ * @retval NRF_SUCCESS Encoding success.
+ * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length.
+ */
+uint32_t ant_lib_config_get_rsp_enc(uint32_t return_code,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len,
+ uint8_t const * const p_ant_lib_config);
+
+/**@brief Decodes @ref sd_ant_lib_config_clear command request.
+ *
+ * @sa @ref ant_lib_config_clear_rsp_enc for response encoding.
+ *
+ * @param[in] p_buf Pointer to beginning of command request packet.
+ * @param[in] packet_len Length (in bytes) of response packet.
+ *
+ * @param[out] p_ant_lib_config Pointer to an unsigned char (1 octet) where the ANT lib config
+ * bit(s) to clear will be set. See ANT Library Config in
+ * ant_parameters.h.
+ *
+ * @retval NRF_SUCCESS Decoding success.
+ * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length.
+ */
+uint32_t ant_lib_config_clear_req_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ uint8_t * const p_ant_lib_config);
+
+/**@brief Encodes @ref sd_ant_lib_config_clear command response.
+ *
+ * @sa @ref ant_lib_config_clear_req_dec for request decoding.
+ *
+ * @param[in] return_code Return code indicating if command was successful or not.
+ * @param[out] p_buf Pointer to buffer where encoded data command response will be
+ * returned.
+ * @param[in,out] p_buf_len \c in: Size of \p p_buf buffer.
+ * \c out: Length of encoded command response packet.
+ *
+ * @retval NRF_SUCCESS Encoding success.
+ * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length.
+ */
+uint32_t ant_lib_config_clear_rsp_enc(uint32_t return_code,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len);
+
+/**@brief Encodes @ref sd_ant_stack_reset command response.
+ *
+ * @param[in] return_code Return code indicating if command was successful or not.
+ * @param[out] p_buf Pointer to buffer where encoded data command response will be
+ * returned.
+ * @param[in,out] p_buf_len \c in: Size of \p p_buf buffer.
+ * \c out: Length of encoded command response packet.
+ *
+ * @retval NRF_SUCCESS Encoding success.
+ * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length.
+ */
+uint32_t ant_stack_reset_rsp_enc(uint32_t return_code,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len);
+
+/**@brief Decodes @ref sd_ant_rx_scan_mode_start command request.
+ *
+ * @sa @ref ant_rx_scan_mode_start_rsp_enc for response encoding.
+ *
+ * @param[in] p_buf Pointer to beginning of command request packet.
+ * @param[in] packet_len Length (in bytes) of response packet.
+ *
+ * @param[out] p_sync_channel_packets_only Pointer to an unsigned char (1 octet) where the
+ * synchronous channel only scanning mode will be set.
+ * 0 = disable, 1 = enable.
+ *
+ * @retval NRF_SUCCESS Decoding success.
+ * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length.
+ */
+uint32_t ant_rx_scan_mode_start_req_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ uint8_t * const p_sync_channel_packets_only);
+
+/**@brief Encodes @ref sd_ant_rx_scan_mode_start command response.
+ *
+ * @sa @ref ant_rx_scan_mode_start_req_dec for request decoding.
+ *
+ * @param[in] return_code Return code indicating if command was successful or not.
+ * @param[out] p_buf Pointer to buffer where encoded data command response will be
+ * returned.
+ * @param[in,out] p_buf_len \c in: Size of \p p_buf buffer.
+ * \c out: Length of encoded command response packet.
+ *
+ * @retval NRF_SUCCESS Encoding success.
+ * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length.
+ */
+uint32_t ant_rx_scan_mode_start_rsp_enc(uint32_t return_code,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len);
+
+/**@brief Decodes @ref sd_ant_id_list_add command request.
+ *
+ * @sa @ref ant_id_list_add_rsp_enc for response encoding.
+ *
+ * @param[in] p_buf Pointer to beginning of command request packet.
+ * @param[in] packet_len Length (in bytes) of response packet.
+ *
+ * @param[out] p_channel Pointer to an unsigned char (1 octet) where the channel
+ * number to add the list entry to will be set.
+ * @param[out] pp_dev_id Pointer to pointer to where the Dev ID will be stored.
+ * @param[out] p_list_index Pointer to an unsigned char (1 octet) where the list
+ * index (0-3), will be set.
+ *
+ * @retval NRF_SUCCESS Decoding success.
+ * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length.
+ */
+uint32_t ant_id_list_add_req_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ uint8_t * const p_channel,
+ uint8_t * * const pp_dev_id,
+ uint8_t * const p_list_index);
+
+/**@brief Encodes @ref sd_ant_id_list_add command response.
+ *
+ * @sa @ref ant_id_list_add_req_dec for request decoding.
+ *
+ * @param[in] return_code Return code indicating if command was successful or not.
+ * @param[out] p_buf Pointer to buffer where encoded data command response will be
+ * returned.
+ * @param[in,out] p_buf_len \c in: Size of \p p_buf buffer.
+ * \c out: Length of encoded command response packet.
+ *
+ * @retval NRF_SUCCESS Encoding success.
+ * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length.
+ */
+uint32_t ant_id_list_add_rsp_enc(uint32_t return_code,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len);
+
+/**@brief Decodes @ref sd_ant_id_list_config command request.
+ *
+ * @sa @ref ant_id_list_config_rsp_enc for response encoding.
+ *
+ * @param[in] p_buf Pointer to beginning of command request packet.
+ * @param[in] packet_len Length (in bytes) of response packet.
+ *
+ * @param[out] p_channel Pointer to an unsigned char (1 octet) wher the channel number
+ * of the device ID list will be stored.
+ * @param[out] p_id_list_size Pointer to an unsigned char (1 octet) where the size of the
+ * inclusion or exclusion list (0-4) will be stored.
+ * @param[out] p_inc_exc_flag Pointer to an unsigned char (1 octet) where the type of list
+ * will be stored.
+ *
+ * @retval NRF_SUCCESS Decoding success.
+ * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length.
+ */
+uint32_t ant_id_list_config_req_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ uint8_t * const p_channel,
+ uint8_t * const p_id_list_size,
+ uint8_t * const p_inc_exc_flag);
+
+/**@brief Encodes @ref sd_ant_id_list_add command response.
+ *
+ * @sa @ref ant_id_list_config_req_dec for request decoding.
+ *
+ * @param[in] return_code Return code indicating if command was successful or not.
+ * @param[out] p_buf Pointer to buffer where encoded data command response will be
+ * returned.
+ * @param[in,out] p_buf_len \c in: Size of \p p_buf buffer.
+ * \c out: Length of encoded command response packet.
+ *
+ * @retval NRF_SUCCESS Encoding success.
+ * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length.
+ */
+uint32_t ant_id_list_config_rsp_enc(uint32_t return_code,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len);
+
+/**@brief Decodes @ref sd_ant_channel_status_get command request.
+ *
+ * @sa @ref ant_channel_status_get_rsp_enc for response encoding.
+ *
+ * @param[in] p_buf Pointer to beginning of command request packet.
+ * @param[in] packet_len Length (in bytes) of response packet.
+ *
+ * @param[out] p_channel Pointer to an unsigned char (1 octet) where the channel number
+ * will be set.
+ *
+ * @retval NRF_SUCCESS Decoding success.
+ * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length.
+ */
+uint32_t ant_channel_status_get_req_dec(uint8_t const * const p_buf,
+ uint16_t packet_len,
+ uint8_t * const p_channel);
+
+/**@brief Encodes @ref sd_ant_channel_status_get command response.
+ *
+ * @sa @ref ant_channel_status_get_req_dec for request decoding.
+ *
+ * @param[in] return_code Return code indicating if command was successful or not.
+ * @param[out] p_buf Pointer to buffer where encoded data command response will be
+ * returned.
+ * @param[in,out] p_buf_len \c in: Size of \p p_buf buffer.
+ * \c out: Length of encoded command response packet.
+ * @param[in] p_status Pointer to status
+ *
+ * @retval NRF_SUCCESS Encoding success.
+ * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length.
+ */
+uint32_t ant_channel_status_get_rsp_enc(uint32_t return_code,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len,
+ uint8_t const * const p_status);
+
+/**@brief Encodes @ref sd_ant_cw_test_mode_init command response.
+ *
+ * @param[in] return_code Return code indicating if command was successful or not.
+ * @param[out] p_buf Pointer to buffer where encoded data command response will be
+ * returned.
+ * @param[in,out] p_buf_len \c in: Size of \p p_buf buffer.
+ * \c out: Length of encoded command response packet.
+ *
+ * @retval NRF_SUCCESS Encoding success.
+ * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length.
+ */
+uint32_t ant_cw_test_mode_init_rsp_enc(uint32_t return_code,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len);
+
+/**@brief Decodes @ref sd_ant_cw_test_mode command request.
+ *
+ * @sa @ref ant_cw_test_mode_rsp_enc for response encoding.
+ *
+ * @param[in] p_buf Pointer to beginning of command request packet.
+ * @param[in] packet_len Length (in bytes) of response packet.
+ *
+ * @param[out] p_radio_freq Pointer to an unsigned char (1 octet) where the radio
+ * frequency offset from 2400 MHz for continuous wave mode will be
+ * set. (eg. 2466 MHz, ucRadioFreq = 66).
+ * @param[out] p_tx_power Pointer to an unsigned char (1 octet) where the ANT transmit
+ * power index for continuous wave mode will be set. See Radio
+ * TX Power Definitions in ant_parameters.h
+ * @param[out] p_custom_tx_power Pointer to an unsigned char (1 octet) where the custom nRF
+ * transmit power as defined in nrf51_bitfields.h will be set. Only
+ * applicable if ucTxPower is set to custom TX power selection.
+ * @param[out] p_mode Pointer to an unsigned char (1 octet) where the test mode type
+ * will be set.
+ * @param[in] p_buf Pointer to buffer where encoded data command will be returned.
+ *
+ * @retval NRF_SUCCESS Decoding success.
+ * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length.
+ */
+uint32_t ant_cw_test_mode_req_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ uint8_t * const p_radio_freq,
+ uint8_t * const p_tx_power,
+ uint8_t * const p_custom_tx_power,
+ uint8_t * const p_mode);
+
+/**@brief Encodes @ref sd_ant_cw_test_mode command response.
+ *
+ * @sa @ref ant_cw_test_mode_req_dec for request decoding.
+ *
+ * @param[in] return_code Return code indicating if command was successful or not.
+ * @param[out] p_buf Pointer to buffer where encoded data command response will be
+ * returned.
+ * @param[in,out] p_buf_len \c in: Size of \p p_buf buffer.
+ * \c out: Length of encoded command response packet.
+ *
+ * @retval NRF_SUCCESS Encoding success.
+ * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length.
+ */
+uint32_t ant_cw_test_mode_rsp_enc(uint32_t return_code,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len);
+
+/**@brief Encodes @ref sd_ant_version_get command response.
+ *
+ * @param[in] return_code Return code indicating if command was successful or not.
+ * @param[out] p_buf Pointer to buffer where encoded data command response will be
+ * returned.
+ * @param[in,out] p_buf_len \c in: Size of \p p_buf buffer.
+ * \c out: Length of encoded command response packet.
+ * @param[in] p_version Pointer to version.
+ *
+ * @retval NRF_SUCCESS Encoding success.
+ * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length.
+ */
+uint32_t ant_version_get_rsp_enc(uint32_t return_code,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len,
+ uint8_t const * const p_version);
+
+/**@brief Encodes @ref sd_ant_capabilities_get command response.
+ *
+ * @param[in] return_code Return code indicating if command was successful or not.
+ * @param[out] p_buf Pointer to buffer where encoded data command response will be
+ * returned.
+ * @param[in,out] p_buf_len \c in: Size of \p p_buf buffer.
+ * \c out: Length of encoded command response packet.
+ * @param[in] p_capabilities Pointer to ant capabilities buffer.
+ *
+ * @retval NRF_SUCCESS Encoding success.
+ * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length.
+ */
+uint32_t ant_capabilities_get_rsp_enc(uint32_t return_code,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len,
+ uint8_t const * const p_capabilities);
+
+/**@brief Decodes @ref sd_ant_crypto_channel_enable command request.
+ *
+ * @sa @ref ant_crypto_channel_enable_rsp_enc for response encoding.
+ *
+ * @param[in] p_buf Pointer to beginning of command request packet.
+ * @param[in] packet_len Length (in bytes) of response packet.
+ *
+ * @param[out] p_channel Pointer to an unsigned char (1 octet) where the channel in which
+ * encryption mode is set will be copied to.
+ * @param[out] p_enable Pointer to an unsigned char (1 octet) where the encryption
+ * mode will be set.
+ * @param[out] p_key_num Pointer to an unsigned char (1 octet) where the key index of the
+ * 128-bit key to be used for encryption will be set.
+ * @param[out] p_decimation_rate Pointer to an unsigned char (1 octet) where the decimate rate to
+ * apply for encrypted slave channel will be set. Must be > 0.
+ *
+ * @retval NRF_SUCCESS Decoding success.
+ * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length.
+ */
+uint32_t ant_crypto_channel_enable_req_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ uint8_t * const p_channel,
+ uint8_t * const p_enable,
+ uint8_t * const p_key_num,
+ uint8_t * const p_decimation_rate);
+
+/**@brief Encodes @ref sd_ant_crypto_channel_enable command response.
+ *
+ * @sa @ref ant_crypto_channel_enable_req_dec for request decoding.
+ *
+ * @param[in] return_code Return code indicating if command was successful or not.
+ * @param[out] p_buf Pointer to buffer where encoded data command response will be
+ * returned.
+ * @param[in,out] p_buf_len \c in: Size of \p p_buf buffer.
+ * \c out: Length of encoded command response packet.
+ *
+ * @retval NRF_SUCCESS Encoding success.
+ * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length.
+ */
+uint32_t ant_crypto_channel_enable_rsp_enc(uint32_t return_code,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len);
+
+/**@brief Decodes @ref sd_ant_adv_burst_config_set command request.
+ *
+ * @sa @ref ant_adv_burst_config_set_rsp_enc for response encoding.
+ *
+ * @param[in] p_buf Pointer to beginning of command request packet.
+ * @param[in] packet_len Length (in bytes) of response packet.
+ *
+ * @param[out] p_config Pointer to the buffer where advanced burst
+ * configuration will be set.
+ * @param[out] p_size Pointer to an unsigned char (1 octet) where the size of the
+ * configuration parameter buffer will be set.
+ * @retval NRF_SUCCESS Decoding success.
+ * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length.
+ */
+uint32_t ant_adv_burst_config_set_req_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ uint8_t * const p_config,
+ uint8_t * const p_size);
+
+/**@brief Encodes @ref sd_ant_adv_burst_config_set command response.
+ *
+ * @sa @ref ant_adv_burst_config_set_req_dec for request decoding.
+ *
+ * @param[in] return_code Return code indicating if command was successful or not.
+ * @param[out] p_buf Pointer to buffer where encoded data command response will be
+ * returned.
+ * @param[in,out] p_buf_len \c in: Size of \p p_buf buffer.
+ * \c out: Length of encoded command response packet.
+ *
+ * @retval NRF_SUCCESS Encoding success.
+ * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length.
+ */
+uint32_t ant_adv_burst_config_set_rsp_enc(uint32_t return_code,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len);
+
+/**@brief Decodes @ref sd_ant_crypto_key_set command request.
+ *
+ * @sa @ref ant_crypto_key_set_rsp_enc for response encoding.
+ *
+ * @param[in] p_buf Pointer to beginning of command request packet.
+ * @param[in] packet_len Length (in bytes) of response packet.
+ *
+ * @param[out] p_key_num Pointer to an unsigned char (1 octet) where the key index for
+ * assignment will be set.
+ * @param[out] pp_key Pointer to pointer to buffer (16 octets) where the 128-bit
+ * AES key to be assigned to the key index will be set.
+ *
+ * @retval NRF_SUCCESS Decoding success.
+ * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length.
+ */
+uint32_t ant_crypto_key_set_req_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ uint8_t * const p_key_num,
+ uint8_t * * const pp_key);
+
+/**@brief Encodes @ref sd_ant_crypto_key_set command response.
+ *
+ * @sa @ref ant_crypto_key_set_req_dec for request decoding.
+ *
+ * @param[in] return_code Return code indicating if command was successful or not.
+ * @param[out] p_buf Pointer to buffer where encoded data command response will be
+ * returned.
+ * @param[in,out] p_buf_len \c in: Size of \p p_buf buffer.
+ * \c out: Length of encoded command response packet.
+ *
+ * @retval NRF_SUCCESS Encoding success.
+ * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length.
+ */
+uint32_t ant_crypto_key_set_rsp_enc(uint32_t return_code,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len);
+
+/**@brief Decodes @ref sd_ant_crypto_info_set command request.
+ *
+ * @sa @ref ant_crypto_info_set_rsp_enc for response encoding.
+ *
+ * @param[in] p_buf Pointer to beginning of command request packet.
+ * @param[in] packet_len Length (in bytes) of response packet.
+ *
+ * @param[out] p_type Pointer to an unsigned char (1 octet) where the type of
+ * information being set will be copied.
+ * @param[out] pp_info Pointer to pointer to buffer where information being set will be
+ * copied.
+ *
+ * @retval NRF_SUCCESS Decoding success.
+ * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length.
+ */
+uint32_t ant_crypto_info_set_req_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ uint8_t * const p_type,
+ uint8_t * * const pp_info);
+
+/**@brief Encodes @ref sd_ant_crypto_info_set command response.
+ *
+ * @sa @ref ant_crypto_info_set_req_dec for request decoding.
+ *
+ * @param[in] return_code Return code indicating if command was successful or not.
+ * @param[out] p_buf Pointer to buffer where encoded data command response will be
+ * returned.
+ * @param[in,out] p_buf_len \c in: Size of \p p_buf buffer.
+ * \c out: Length of encoded command response packet.
+ *
+ * @retval NRF_SUCCESS Encoding success.
+ * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length.
+ */
+uint32_t ant_crypto_info_set_rsp_enc(uint32_t return_code,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len);
+
+/**@brief Decodes @ref sd_ant_crypto_info_get command request.
+ *
+ * @sa @ref ant_crypto_info_get_rsp_enc for response encoding.
+ *
+ * @param[in] p_buf Pointer to beginning of command request packet.
+ * @param[in] packet_len Length (in bytes) of response packet.
+ *
+ * @param[out] p_type Pointer to an unsigned char (1 octet) where the type of
+ * information being set will be copied.
+ *
+ * @retval NRF_SUCCESS Decoding success.
+ * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length.
+ */
+uint32_t ant_crypto_info_get_req_dec(uint8_t const * const p_buf,
+ uint16_t packet_len,
+ uint8_t * const p_type);
+
+/**@brief Encodes @ref sd_ant_crypto_info_get command response.
+ *
+ * @sa @ref ant_crypto_info_get_req_dec for request decoding.
+ *
+ * @param[in] return_code Return code indicating if command was successful or not.
+ * @param[out] p_buf Pointer to buffer where encoded data command response will be
+ * returned.
+ * @param[in,out] p_buf_len \c in: Size of \p p_buf buffer.
+ * \c out: Length of encoded command response packet.
+ * @param[in] type The type of information being set.
+ * @param[in] p_info Pointer to info buffer.
+ *
+ * @retval NRF_SUCCESS Encoding success.
+ * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length.
+ */
+uint32_t ant_crypto_info_get_rsp_enc(uint32_t return_code,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len,
+ uint8_t type,
+ uint8_t const * const p_info);
+
+/**@brief Decodes @ref sd_ant_coex_config_set command request.
+ *
+ * @sa @ref ant_coex_config_set_rsp_enc for response encoding.
+ *
+ * @param[in] p_buf Pointer to beginning of command request packet.
+ * @param[in] packet_len Length (in bytes) of response packet.
+ *
+ * @param[in] p_channel Pointer to an unsigned char (1 octet) where the channel for
+ * which the coexistence configuration is to be set will be copied.
+ * @param[in] p_coex_config Pointer to a buffer where the coexistence configuration to be set will
+ * be copied.
+ * @param[in] p_adv_coex_config Pointer to a buffer where the advanced coexistence configuration to be set will
+ * be copied.
+ *
+ * @retval NRF_SUCCESS Decoding success.
+ * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length.
+ */
+uint32_t ant_coex_config_set_req_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ uint8_t * const p_channel,
+ ANT_BUFFER_PTR * const p_coex_config,
+ ANT_BUFFER_PTR * const p_adv_coex_config);
+
+/**@brief Encodes @ref sd_ant_coex_config_set command response.
+ *
+ * @sa @ref ant_coex_config_set_req_dec for request decoding.
+ *
+ * @param[in] return_code Return code indicating if command was successful or not.
+ * @param[out] p_buf Pointer to buffer where encoded data command response will be
+ * returned.
+ * @param[in,out] p_buf_len \c in: Size of \p p_buf buffer.
+ * \c out: Length of encoded command response packet.
+ *
+ * @retval NRF_SUCCESS Encoding success.
+ * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length.
+ */
+uint32_t ant_coex_config_set_rsp_enc(uint32_t return_code,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len);
+
+/**@brief Decodes @ref sd_ant_coex_config_get command request.
+ *
+ * @sa @ref ant_channel_id_get_rsp_enc for response encoding.
+ *
+ * @param[in] p_buf Pointer to beginning of command request packet.
+ * @param[in] packet_len Length (in bytes) of response packet.
+ *
+ * @param[out] p_channel Pointer to an unsigned char (1 octet) where the channel
+ * number will be set.
+ *
+ * @retval NRF_SUCCESS Decoding success.
+ * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length.
+ */
+uint32_t ant_coex_config_get_req_dec(uint8_t const * const p_buf,
+ uint16_t packet_len,
+ uint8_t * const p_channel);
+
+/**@brief Encodes @ref sd_ant_coex_config_get command response.
+ *
+ * @sa @ref ant_channel_id_get_req_dec for request decoding.
+ *
+ * @param[in] return_code Return code indicating if command was successful or not.
+ * @param[out] p_buf Pointer to buffer where encoded data command response will be
+ * returned.
+ * @param[in,out] p_buf_len \c in: Size of \p p_buf buffer.
+ * \c out: Length of encoded command response packet.
+ * @param[in] p_coex_config Pointer to the coexistence configuration.
+ * @param[in] p_adv_coex_config Pointer to the advanced coexistence configuration.
+ *
+ * @retval NRF_SUCCESS Encoding success.
+ * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length.
+ */
+uint32_t ant_coex_config_get_rsp_enc(uint32_t return_code,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len,
+ ANT_BUFFER_PTR * const p_coex_config,
+ ANT_BUFFER_PTR * const p_adv_coex_config);
+/** @} */
+
+#endif
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/connectivity/codecs/ant/serializers/ant_crypto_channel_enable.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/connectivity/codecs/ant/serializers/ant_crypto_channel_enable.c
new file mode 100644
index 0000000..66db3cb
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/connectivity/codecs/ant/serializers/ant_crypto_channel_enable.c
@@ -0,0 +1,88 @@
+/**
+ * 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+
+#include <string.h>
+#include "ant_conn.h"
+#include "ble_serialization.h"
+#include "cond_field_serialization.h"
+#include "ant_struct_serialization.h"
+#include "app_util.h"
+
+uint32_t ant_crypto_channel_enable_req_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ uint8_t * const p_channel,
+ uint8_t * const p_enable,
+ uint8_t * const p_key_num,
+ uint8_t * const p_decimation_rate)
+{
+ uint32_t index = SER_CMD_DATA_POS;
+ uint32_t err_code;
+
+ SER_ASSERT_NOT_NULL(p_buf);
+ SER_ASSERT_NOT_NULL(p_channel);
+ SER_ASSERT_NOT_NULL(p_enable);
+ SER_ASSERT_NOT_NULL(p_key_num);
+ SER_ASSERT_NOT_NULL(p_decimation_rate);
+
+ err_code = uint8_t_dec(p_buf, packet_len, &index, p_channel);
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code);
+
+ err_code = uint8_t_dec(p_buf, packet_len, &index, p_enable);
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code);
+
+ err_code = uint8_t_dec(p_buf, packet_len, &index, p_key_num);
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code);
+
+ err_code = uint8_t_dec(p_buf, packet_len, &index, p_decimation_rate);
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code);
+
+ SER_ASSERT_LENGTH_EQ(index, packet_len);
+
+ return err_code;
+}
+
+uint32_t ant_crypto_channel_enable_rsp_enc(uint32_t return_code,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len)
+{
+ uint32_t index = 0;
+
+ return op_status_enc(SVC_ANT_CRYPTO_CHANNEL_ENABLE, return_code, p_buf, p_buf_len, &index);
+}
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/connectivity/codecs/ant/serializers/ant_crypto_info_get.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/connectivity/codecs/ant/serializers/ant_crypto_info_get.c
new file mode 100644
index 0000000..495aee0
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/connectivity/codecs/ant/serializers/ant_crypto_info_get.c
@@ -0,0 +1,96 @@
+/**
+ * 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+
+#include <string.h>
+#include "ant_conn.h"
+#include "ble_serialization.h"
+#include "cond_field_serialization.h"
+#include "ant_struct_serialization.h"
+#include "app_util.h"
+
+uint32_t ant_crypto_info_get_req_dec(uint8_t const * const p_buf,
+ uint16_t packet_len,
+ uint8_t * const p_type)
+{
+ uint32_t index = SER_CMD_DATA_POS;
+ uint32_t err_code;
+
+ SER_ASSERT_NOT_NULL(p_buf);
+ SER_ASSERT_NOT_NULL(p_type);
+
+ err_code = uint8_t_dec(p_buf, packet_len, &index, p_type);
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code);
+
+ SER_ASSERT_LENGTH_EQ(index, packet_len);
+
+ return err_code;
+}
+
+uint32_t ant_crypto_info_get_rsp_enc(uint32_t return_code,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len,
+ uint8_t type,
+ uint8_t const * const p_info)
+{
+ SER_ASSERT_NOT_NULL(p_buf);
+ SER_ASSERT_NOT_NULL(p_buf_len);
+
+ uint32_t total_len = *p_buf_len;
+
+ uint32_t err_code = ser_ble_cmd_rsp_status_code_enc(SVC_ANT_CRYPTO_INFO_GET, return_code,
+ p_buf, p_buf_len);
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code);
+
+ if (return_code != NRF_SUCCESS)
+ {
+ return NRF_SUCCESS;
+ }
+
+ err_code = uint8_t_enc(&type, p_buf, total_len, p_buf_len);
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code);
+
+ uint8_t crypto_info_size = (MESG_CONFIG_ENCRYPT_REQ_CONFIG_USER_DATA_SIZE -
+ MESG_CHANNEL_NUM_SIZE);
+
+ err_code = uint8_vector_enc(p_info, crypto_info_size, p_buf, total_len, p_buf_len);
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code);
+
+ return NRF_SUCCESS;
+}
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/connectivity/codecs/ant/serializers/ant_crypto_info_set.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/connectivity/codecs/ant/serializers/ant_crypto_info_set.c
new file mode 100644
index 0000000..d429119
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/connectivity/codecs/ant/serializers/ant_crypto_info_set.c
@@ -0,0 +1,84 @@
+/**
+ * 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+
+#include <string.h>
+#include "ant_conn.h"
+#include "ble_serialization.h"
+#include "cond_field_serialization.h"
+#include "ant_struct_serialization.h"
+#include "app_util.h"
+
+uint32_t ant_crypto_info_set_req_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ uint8_t * const p_type,
+ uint8_t * * const pp_info)
+{
+ uint32_t index = SER_CMD_DATA_POS;
+ uint32_t err_code;
+
+ SER_ASSERT_NOT_NULL(p_buf);
+ SER_ASSERT_NOT_NULL(p_type);
+ SER_ASSERT_NOT_NULL(*pp_info);
+
+ err_code = uint8_t_dec(p_buf, packet_len, &index, p_type);
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code);
+
+ uint8_t crypto_info_size = (MESG_CONFIG_ENCRYPT_REQ_CONFIG_USER_DATA_SIZE -
+ MESG_CHANNEL_NUM_SIZE) +
+ (MESG_CONFIG_ENCRYPT_REQ_CONFIG_ID_SIZE -
+ MESG_CHANNEL_NUM_SIZE);
+
+ err_code = uint8_vector_dec(p_buf, packet_len, &index, *pp_info, crypto_info_size);
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code);
+
+ SER_ASSERT_LENGTH_EQ(index, packet_len);
+
+ return err_code;
+}
+
+
+uint32_t ant_crypto_info_set_rsp_enc(uint32_t return_code,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len)
+{
+ uint32_t index = 0;
+
+ return op_status_enc(SVC_ANT_CRYPTO_INFO_SET, return_code, p_buf, p_buf_len, &index);
+}
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/connectivity/codecs/ant/serializers/ant_crypto_key_set.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/connectivity/codecs/ant/serializers/ant_crypto_key_set.c
new file mode 100644
index 0000000..e5d0980
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/connectivity/codecs/ant/serializers/ant_crypto_key_set.c
@@ -0,0 +1,79 @@
+/**
+ * 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+
+#include <string.h>
+#include "ant_conn.h"
+#include "ble_serialization.h"
+#include "cond_field_serialization.h"
+#include "ant_struct_serialization.h"
+#include "app_util.h"
+
+uint32_t ant_crypto_key_set_req_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ uint8_t * const p_key_num,
+ uint8_t * * const pp_key)
+{
+ uint32_t index = SER_CMD_DATA_POS;
+ uint32_t err_code;
+
+ SER_ASSERT_NOT_NULL(p_buf);
+ SER_ASSERT_NOT_NULL(p_key_num);
+ SER_ASSERT_NOT_NULL(*pp_key);
+
+ err_code = uint8_t_dec(p_buf, packet_len, &index, p_key_num);
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code);
+
+ err_code = uint8_vector_dec(p_buf, packet_len, &index, *pp_key, SIZE_OF_ENCRYPTED_KEY);
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code);
+
+ SER_ASSERT_LENGTH_EQ(index, packet_len);
+
+ return err_code;
+}
+
+
+uint32_t ant_crypto_key_set_rsp_enc(uint32_t return_code,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len)
+{
+ uint32_t index = 0;
+
+ return op_status_enc(SVC_ANT_CRYPTO_KEY_SET, return_code, p_buf, p_buf_len, &index);
+}
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/connectivity/codecs/ant/serializers/ant_cw_test_mode.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/connectivity/codecs/ant/serializers/ant_cw_test_mode.c
new file mode 100644
index 0000000..0830ebe
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/connectivity/codecs/ant/serializers/ant_cw_test_mode.c
@@ -0,0 +1,88 @@
+/**
+ * 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+
+#include <string.h>
+#include "ant_conn.h"
+#include "ble_serialization.h"
+#include "cond_field_serialization.h"
+#include "ant_struct_serialization.h"
+#include "app_util.h"
+
+uint32_t ant_cw_test_mode_req_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ uint8_t * const p_radio_freq,
+ uint8_t * const p_tx_power,
+ uint8_t * const p_custom_tx_power,
+ uint8_t * const p_mode)
+{
+ uint32_t index = SER_CMD_DATA_POS;
+ uint32_t err_code;
+
+ SER_ASSERT_NOT_NULL(p_buf);
+ SER_ASSERT_NOT_NULL(p_radio_freq);
+ SER_ASSERT_NOT_NULL(p_tx_power);
+ SER_ASSERT_NOT_NULL(p_custom_tx_power);
+ SER_ASSERT_NOT_NULL(p_mode);
+
+ err_code = uint8_t_dec(p_buf, packet_len, &index, p_radio_freq);
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code);
+
+ err_code = uint8_t_dec(p_buf, packet_len, &index, p_tx_power);
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code);
+
+ err_code = uint8_t_dec(p_buf, packet_len, &index, p_custom_tx_power);
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code);
+
+ err_code = uint8_t_dec(p_buf, packet_len, &index, p_mode);
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code);
+
+ SER_ASSERT_LENGTH_EQ(index, packet_len);
+
+ return err_code;
+}
+
+uint32_t ant_cw_test_mode_rsp_enc(uint32_t return_code,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len)
+{
+ uint32_t index = 0;
+
+ return op_status_enc(SVC_ANT_CW_TEST_MODE, return_code, p_buf, p_buf_len, &index);
+}
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/connectivity/codecs/ant/serializers/ant_cw_test_mode_init.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/connectivity/codecs/ant/serializers/ant_cw_test_mode_init.c
new file mode 100644
index 0000000..baf8699
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/connectivity/codecs/ant/serializers/ant_cw_test_mode_init.c
@@ -0,0 +1,55 @@
+/**
+ * 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+
+#include <string.h>
+#include "ant_conn.h"
+#include "ble_serialization.h"
+#include "cond_field_serialization.h"
+#include "ant_struct_serialization.h"
+#include "app_util.h"
+
+uint32_t ant_cw_test_mode_init_rsp_enc(uint32_t return_code,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len)
+{
+ uint32_t index = 0;
+
+ return op_status_enc(SVC_ANT_INIT_CW_TEST_MODE, return_code, p_buf, p_buf_len, &index);
+}
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/connectivity/codecs/ant/serializers/ant_enable.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/connectivity/codecs/ant/serializers/ant_enable.c
new file mode 100644
index 0000000..9f38a38
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/connectivity/codecs/ant/serializers/ant_enable.c
@@ -0,0 +1,75 @@
+/**
+ * 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+
+#include <string.h>
+#include "ant_conn.h"
+#include "ble_serialization.h"
+#include "cond_field_serialization.h"
+#include "ant_struct_serialization.h"
+#include "app_util.h"
+
+uint32_t ant_enable_req_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ ANT_ENABLE * * const pp_ant_enable_params)
+{
+ uint32_t index = SER_CMD_DATA_POS;
+ uint32_t err_code;
+
+ SER_ASSERT_NOT_NULL(p_buf);
+ SER_ASSERT_NOT_NULL(pp_ant_enable_params);
+ SER_ASSERT_NOT_NULL(*pp_ant_enable_params);
+
+ err_code = cond_field_dec(p_buf, packet_len, &index, (void * *)pp_ant_enable_params, ANT_ENABLE_dec);
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code);
+
+ SER_ASSERT_LENGTH_EQ(index, packet_len);
+
+ return err_code;
+}
+
+
+uint32_t ant_enable_rsp_enc(uint32_t return_code,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len)
+{
+ uint32_t index = 0;
+
+ return op_status_enc(SVC_ANT_ENABLE, return_code, p_buf, p_buf_len, &index);
+}
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/connectivity/codecs/ant/serializers/ant_event.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/connectivity/codecs/ant/serializers/ant_event.c
new file mode 100644
index 0000000..192784b
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/connectivity/codecs/ant/serializers/ant_event.c
@@ -0,0 +1,114 @@
+/**
+ * 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+
+#include "ant_parameters.h"
+#include "nrf_sdh_ant.h"
+#include "ant_struct_serialization.h"
+#include "ble_serialization.h"
+#include "ant_event_rx.h"
+#include "app_util.h"
+#include "cond_field_serialization.h"
+
+
+uint32_t ant_event_enc(ant_evt_t const * const p_event,
+ uint32_t event_len,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len)
+{
+ uint32_t ret_val = NRF_SUCCESS;
+ SER_ASSERT_NOT_NULL(p_buf);
+ SER_ASSERT_NOT_NULL(p_buf_len);
+ SER_ASSERT_NOT_NULL(p_event);
+
+ switch (p_event->event)
+ {
+ case NO_EVENT:
+ case EVENT_RX_SEARCH_TIMEOUT:
+ case EVENT_RX_FAIL:
+ case EVENT_TRANSFER_RX_FAILED:
+ case EVENT_TRANSFER_TX_COMPLETED:
+ case EVENT_TRANSFER_TX_FAILED:
+ case EVENT_CHANNEL_CLOSED:
+ case EVENT_RX_FAIL_GO_TO_SEARCH:
+ case EVENT_CHANNEL_COLLISION:
+ case EVENT_TRANSFER_TX_START:
+ case EVENT_TRANSFER_NEXT_DATA_BLOCK:
+ case CHANNEL_IN_WRONG_STATE:
+ case CHANNEL_NOT_OPENED:
+ case CHANNEL_ID_NOT_SET:
+ case CLOSE_ALL_CHANNELS:
+ case TRANSFER_IN_PROGRESS:
+ case TRANSFER_SEQUENCE_NUMBER_ERROR:
+ case TRANSFER_IN_ERROR:
+ case TRANSFER_BUSY:
+ case MESSAGE_SIZE_EXCEEDS_LIMIT:
+ case INVALID_MESSAGE:
+ case INVALID_NETWORK_NUMBER:
+ case INVALID_LIST_ID:
+ case INVALID_SCAN_TX_CHANNEL:
+ case INVALID_PARAMETER_PROVIDED:
+ case EVENT_QUE_OVERFLOW:
+ case EVENT_ENCRYPT_NEGOTIATION_SUCCESS:
+ case EVENT_ENCRYPT_NEGOTIATION_FAIL:
+ case EVENT_RFACTIVE_NOTIFICATION:
+ case EVENT_CONNECTION_START:
+ case EVENT_CONNECTION_SUCCESS:
+ case EVENT_CONNECTION_FAIL:
+ case EVENT_CONNECTION_TIMEOUT:
+ case EVENT_CONNECTION_UPDATE:
+ case NO_RESPONSE_MESSAGE:
+ case EVENT_RX:
+ case EVENT_BLOCKED:
+ case EVENT_TX:
+ {
+ uint32_t index = 0;
+ // TO DO - SER_ASSERT_LENGTH_LEQ(index + SER_EVT_HEADER_SIZE + 2 + 1, *p_buf_len);
+ uint32_t err_code = ant_evt_t_enc(p_event, p_buf, *p_buf_len, &index);
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code);
+ *p_buf_len = index;
+ break;
+ }
+ default:
+ ret_val = NRF_ERROR_NOT_SUPPORTED;
+ break;
+ }
+
+ return ret_val;
+}
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/connectivity/codecs/ant/serializers/ant_event.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/connectivity/codecs/ant/serializers/ant_event.h
new file mode 100644
index 0000000..5b6ce1c
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/connectivity/codecs/ant/serializers/ant_event.h
@@ -0,0 +1,74 @@
+/**
+ * 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#ifndef __ANT_EVENT_H__
+#define __ANT_EVENT_H__
+#include "ant_parameters.h"
+#include "app_util.h"
+#include "nrf_sdh_ant.h"
+
+/**
+ * @addtogroup ser_conn_s212_codecs
+ * @{
+ * @ingroup ser_codecs_conn
+ */
+
+/**@brief Event encoding dispatcher.
+ *
+ * The event encoding dispatcher will route the event packet to the correct encoder which in turn
+ * encodes the contents of the event and updates the \p p_buf buffer.
+ *
+ * @param[in] p_event Pointer to the \ref ant_evt_t buffer that shall be encoded.
+ * @param[in] event_len Size (in bytes) of \p p_event buffer.
+ * @param[out] p_buf Pointer to the beginning of a buffer for encoded event packet.
+ * @param[in,out] p_buf_len \c in: Size (in bytes) of \p p_buf buffer.
+ * \c out: Length of encoded contents in \p p_buf.
+ *
+ * @retval NRF_SUCCESS Encoding success.
+ * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length.
+ * @retval NRF_ERROR_NOT_SUPPORTED Event encoder is not implemented.
+ */
+uint32_t ant_event_enc(ant_evt_t const * const p_event,
+ uint32_t event_len,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len);
+
+/** @} */
+#endif
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/connectivity/codecs/ant/serializers/ant_event_rx.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/connectivity/codecs/ant/serializers/ant_event_rx.c
new file mode 100644
index 0000000..b8dfed0
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/connectivity/codecs/ant/serializers/ant_event_rx.c
@@ -0,0 +1,70 @@
+/**
+ * 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+
+#include <string.h>
+#include "ant_event_rx.h"
+#include "ble_serialization.h"
+#include "app_util.h"
+
+uint32_t ant_event_rx_enc(ant_evt_t const * const p_event,
+ uint32_t event_len,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len)
+{
+ ANT_MESSAGE * p_message;
+ uint32_t index = 0;
+
+
+ SER_ASSERT_NOT_NULL(p_event);
+ SER_ASSERT_NOT_NULL(p_buf);
+ SER_ASSERT_NOT_NULL(p_buf_len);
+
+ SER_ASSERT_LENGTH_LEQ(index + SER_EVT_HEADER_SIZE + 2 + 1, *p_buf_len);
+ p_message = (ANT_MESSAGE *)&p_event->message;
+
+ index += uint16_encode(EVENT_RX, &(p_buf[index])); // Mesg ID
+ p_buf[index++] = p_message->ANT_MESSAGE_ucSize; // Mesg Size
+ memcpy(&(p_buf[index]), p_message->ANT_MESSAGE_aucPayload,p_message->ANT_MESSAGE_ucSize); // Payload
+ index += p_message->ANT_MESSAGE_ucSize;
+
+ *p_buf_len = index;
+
+ return NRF_SUCCESS;
+}
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/connectivity/codecs/ant/serializers/ant_event_rx.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/connectivity/codecs/ant/serializers/ant_event_rx.h
new file mode 100644
index 0000000..72c346e
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/connectivity/codecs/ant/serializers/ant_event_rx.h
@@ -0,0 +1,72 @@
+/**
+ * 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#ifndef __ANT_EVENT_RX_H__
+#define __ANT_EVENT_RX_H__
+
+#include <string.h>
+#include "ant_parameters.h"
+#include "nrf_sdh_ant.h"
+
+/**
+ * @addtogroup ser_conn_s212_codecs
+ * @{
+ * @ingroup ser_codecs_conn
+ */
+
+/**
+ * @brief Encodes ant_event_rx event.
+ *
+ * @param[in] p_event Pointer to the \ref ant_evt_t buffer that shall be encoded.
+ * @param[in] event_len Size (in bytes) of \p p_event buffer.
+ * @param[out] p_buf Pointer to the beginning of a buffer for encoded event packet.
+ * @param[in,out] p_buf_len \c in: Size (in bytes) of \p p_buf buffer.
+ * \c out: Length of encoded contents in \p p_buf.
+ *
+ * @retval NRF_SUCCESS Encoding success.
+ * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length.
+ */
+uint32_t ant_event_rx_enc(ant_evt_t const * const p_event,
+ uint32_t event_len,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len);
+
+/** @} */
+#endif
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/connectivity/codecs/ant/serializers/ant_id_list_add.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/connectivity/codecs/ant/serializers/ant_id_list_add.c
new file mode 100644
index 0000000..49314c6
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/connectivity/codecs/ant/serializers/ant_id_list_add.c
@@ -0,0 +1,84 @@
+/**
+ * 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+
+#include <string.h>
+#include "ant_conn.h"
+#include "ble_serialization.h"
+#include "cond_field_serialization.h"
+#include "ant_struct_serialization.h"
+#include "app_util.h"
+
+uint32_t ant_id_list_add_req_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ uint8_t * const p_channel,
+ uint8_t * * const pp_dev_id,
+ uint8_t * const p_list_index)
+{
+ uint32_t index = SER_CMD_DATA_POS;
+ uint32_t err_code;
+
+ SER_ASSERT_NOT_NULL(p_buf);
+ SER_ASSERT_NOT_NULL(p_channel);
+ SER_ASSERT_NOT_NULL(*pp_dev_id);
+ SER_ASSERT_NOT_NULL(p_list_index);
+
+ err_code = uint8_t_dec(p_buf, packet_len, &index, p_channel);
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code);
+
+ err_code = uint8_vector_dec(p_buf, packet_len, &index, *pp_dev_id, ANT_ID_SIZE);
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code);
+
+ err_code = uint8_t_dec(p_buf, packet_len, &index, p_list_index);
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code);
+
+ SER_ASSERT_LENGTH_EQ(index, packet_len);
+
+ return err_code;
+}
+
+
+uint32_t ant_id_list_add_rsp_enc(uint32_t return_code,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len)
+{
+ uint32_t index = 0;
+
+ return op_status_enc(SVC_ANT_ID_LIST_ADD, return_code, p_buf, p_buf_len, &index);
+}
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/connectivity/codecs/ant/serializers/ant_id_list_config.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/connectivity/codecs/ant/serializers/ant_id_list_config.c
new file mode 100644
index 0000000..d7f69ab
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/connectivity/codecs/ant/serializers/ant_id_list_config.c
@@ -0,0 +1,84 @@
+/**
+ * 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+
+#include <string.h>
+#include "ant_conn.h"
+#include "ble_serialization.h"
+#include "cond_field_serialization.h"
+#include "ant_struct_serialization.h"
+#include "app_util.h"
+
+uint32_t ant_id_list_config_req_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ uint8_t * const p_channel,
+ uint8_t * const p_id_list_size,
+ uint8_t * const p_inc_exc_flag)
+{
+ uint32_t index = SER_CMD_DATA_POS;
+ uint32_t err_code;
+
+ SER_ASSERT_NOT_NULL(p_buf);
+ SER_ASSERT_NOT_NULL(p_channel);
+ SER_ASSERT_NOT_NULL(p_id_list_size);
+ SER_ASSERT_NOT_NULL(p_inc_exc_flag);
+
+ err_code = uint8_t_dec(p_buf, packet_len, &index, p_channel);
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code);
+
+ err_code = uint8_t_dec(p_buf, packet_len, &index, p_id_list_size);
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code);
+
+ err_code = uint8_t_dec(p_buf, packet_len, &index, p_inc_exc_flag);
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code);
+
+ SER_ASSERT_LENGTH_EQ(index, packet_len);
+
+ return err_code;
+}
+
+
+uint32_t ant_id_list_config_rsp_enc(uint32_t return_code,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len)
+{
+ uint32_t index = 0;
+
+ return op_status_enc(SVC_ANT_ID_LIST_CONFIG, return_code, p_buf, p_buf_len, &index);
+}
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/connectivity/codecs/ant/serializers/ant_lib_config_clear.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/connectivity/codecs/ant/serializers/ant_lib_config_clear.c
new file mode 100644
index 0000000..387828d
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/connectivity/codecs/ant/serializers/ant_lib_config_clear.c
@@ -0,0 +1,73 @@
+/**
+ * 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+
+#include <string.h>
+#include "ant_conn.h"
+#include "ble_serialization.h"
+#include "cond_field_serialization.h"
+#include "ant_struct_serialization.h"
+#include "app_util.h"
+
+uint32_t ant_lib_config_clear_req_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ uint8_t * const p_ant_lib_config)
+{
+ uint32_t index = SER_CMD_DATA_POS;
+ uint32_t err_code;
+
+ SER_ASSERT_NOT_NULL(p_buf);
+ SER_ASSERT_NOT_NULL(p_ant_lib_config);
+
+ err_code = uint8_t_dec(p_buf, packet_len, &index, p_ant_lib_config);
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code);
+
+ SER_ASSERT_LENGTH_EQ(index, packet_len);
+
+ return err_code;
+}
+
+uint32_t ant_lib_config_clear_rsp_enc(uint32_t return_code,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len)
+{
+ uint32_t index = 0;
+
+ return op_status_enc(SVC_ANT_LIB_CONFIG_CLEAR, return_code, p_buf, p_buf_len, &index);
+}
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/connectivity/codecs/ant/serializers/ant_lib_config_get.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/connectivity/codecs/ant/serializers/ant_lib_config_get.c
new file mode 100644
index 0000000..cdb0980
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/connectivity/codecs/ant/serializers/ant_lib_config_get.c
@@ -0,0 +1,71 @@
+/**
+ * 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+
+#include <string.h>
+#include "ant_conn.h"
+#include "ble_serialization.h"
+#include "cond_field_serialization.h"
+#include "ant_struct_serialization.h"
+#include "app_util.h"
+
+uint32_t ant_lib_config_get_rsp_enc(uint32_t return_code,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len,
+ uint8_t const * const p_ant_lib_config)
+{
+ SER_ASSERT_NOT_NULL(p_buf);
+ SER_ASSERT_NOT_NULL(p_buf_len);
+
+ uint32_t total_len = *p_buf_len;
+
+ uint32_t err_code = ser_ble_cmd_rsp_status_code_enc(SVC_ANT_LIB_CONFIG_GET, return_code,
+ p_buf, p_buf_len);
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code);
+
+ if (return_code != NRF_SUCCESS)
+ {
+ return NRF_SUCCESS;
+ }
+
+ err_code = uint8_t_enc(p_ant_lib_config, p_buf, total_len, p_buf_len);
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code);
+
+ return NRF_SUCCESS;
+}
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/connectivity/codecs/ant/serializers/ant_lib_config_set.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/connectivity/codecs/ant/serializers/ant_lib_config_set.c
new file mode 100644
index 0000000..01748a0
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/connectivity/codecs/ant/serializers/ant_lib_config_set.c
@@ -0,0 +1,73 @@
+/**
+ * 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+
+#include <string.h>
+#include "ant_conn.h"
+#include "ble_serialization.h"
+#include "cond_field_serialization.h"
+#include "ant_struct_serialization.h"
+#include "app_util.h"
+
+uint32_t ant_lib_config_set_req_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ uint8_t * const p_ant_lib_config)
+{
+ uint32_t index = SER_CMD_DATA_POS;
+ uint32_t err_code;
+
+ SER_ASSERT_NOT_NULL(p_buf);
+ SER_ASSERT_NOT_NULL(p_ant_lib_config);
+
+ err_code = uint8_t_dec(p_buf, packet_len, &index, p_ant_lib_config);
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code);
+
+ SER_ASSERT_LENGTH_EQ(index, packet_len);
+
+ return err_code;
+}
+
+uint32_t ant_lib_config_set_rsp_enc(uint32_t return_code,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len)
+{
+ uint32_t index = 0;
+
+ return op_status_enc(SVC_ANT_LIB_CONFIG_SET, return_code, p_buf, p_buf_len, &index);
+}
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/connectivity/codecs/ant/serializers/ant_network_address_set.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/connectivity/codecs/ant/serializers/ant_network_address_set.c
new file mode 100644
index 0000000..a81a556
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/connectivity/codecs/ant/serializers/ant_network_address_set.c
@@ -0,0 +1,79 @@
+/**
+ * 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+
+#include <string.h>
+#include "ant_conn.h"
+#include "ble_serialization.h"
+#include "cond_field_serialization.h"
+#include "ant_struct_serialization.h"
+#include "app_util.h"
+
+uint32_t ant_network_address_set_req_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ uint8_t * const p_network,
+ uint8_t * * const pp_network_key)
+{
+ uint32_t index = SER_CMD_DATA_POS;
+ uint32_t err_code;
+
+ SER_ASSERT_NOT_NULL(p_buf);
+ SER_ASSERT_NOT_NULL(p_network);
+ SER_ASSERT_NOT_NULL(*pp_network_key);
+
+ err_code = uint8_t_dec(p_buf, packet_len, &index, p_network);
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code);
+
+ err_code = uint8_vector_dec(p_buf, packet_len, &index, *pp_network_key, MESG_NETWORK_KEY_SIZE - MESG_CHANNEL_NUM_SIZE);
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code);
+
+ SER_ASSERT_LENGTH_EQ(index, packet_len);
+
+ return err_code;
+}
+
+
+uint32_t ant_network_address_set_rsp_enc(uint32_t return_code,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len)
+{
+ uint32_t index = 0;
+
+ return op_status_enc(SVC_ANT_NETWORK_KEY_SET, return_code, p_buf, p_buf_len, &index);
+}
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/connectivity/codecs/ant/serializers/ant_prox_search_set.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/connectivity/codecs/ant/serializers/ant_prox_search_set.c
new file mode 100644
index 0000000..5275843
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/connectivity/codecs/ant/serializers/ant_prox_search_set.c
@@ -0,0 +1,83 @@
+/**
+ * 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+
+#include <string.h>
+#include "ant_conn.h"
+#include "ble_serialization.h"
+#include "cond_field_serialization.h"
+#include "ant_struct_serialization.h"
+#include "app_util.h"
+
+uint32_t ant_prox_search_set_req_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ uint8_t * const p_channel,
+ uint8_t * const p_prox_threshold,
+ uint8_t * const p_custom_prox_threshold)
+{
+ uint32_t index = SER_CMD_DATA_POS;
+ uint32_t err_code;
+
+ SER_ASSERT_NOT_NULL(p_buf);
+ SER_ASSERT_NOT_NULL(p_channel);
+ SER_ASSERT_NOT_NULL(p_prox_threshold);
+ SER_ASSERT_NOT_NULL(p_custom_prox_threshold);
+
+ err_code = uint8_t_dec(p_buf, packet_len, &index, p_channel);
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code);
+
+ err_code = uint8_t_dec(p_buf, packet_len, &index, p_prox_threshold);
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code);
+
+ err_code = uint8_t_dec(p_buf, packet_len, &index, p_custom_prox_threshold);
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code);
+
+ SER_ASSERT_LENGTH_EQ(index, packet_len);
+
+ return err_code;
+}
+
+uint32_t ant_prox_search_set_rsp_enc(uint32_t return_code,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len)
+{
+ uint32_t index = 0;
+
+ return op_status_enc(SVC_ANT_PROX_SEARCH_SET, return_code, p_buf, p_buf_len, &index);
+}
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/connectivity/codecs/ant/serializers/ant_rx_scan_mode_start.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/connectivity/codecs/ant/serializers/ant_rx_scan_mode_start.c
new file mode 100644
index 0000000..fde428c
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/connectivity/codecs/ant/serializers/ant_rx_scan_mode_start.c
@@ -0,0 +1,73 @@
+/**
+ * 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+
+#include <string.h>
+#include "ant_conn.h"
+#include "ble_serialization.h"
+#include "cond_field_serialization.h"
+#include "ant_struct_serialization.h"
+#include "app_util.h"
+
+uint32_t ant_rx_scan_mode_start_req_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ uint8_t * const p_sync_channel_packets_only)
+{
+ uint32_t index = SER_CMD_DATA_POS;
+ uint32_t err_code;
+
+ SER_ASSERT_NOT_NULL(p_buf);
+ SER_ASSERT_NOT_NULL(p_sync_channel_packets_only);
+
+ err_code = uint8_t_dec(p_buf, packet_len, &index, p_sync_channel_packets_only);
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code);
+
+ SER_ASSERT_LENGTH_EQ(index, packet_len);
+
+ return err_code;
+}
+
+uint32_t ant_rx_scan_mode_start_rsp_enc(uint32_t return_code,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len)
+{
+ uint32_t index = 0;
+
+ return op_status_enc(SVC_ANT_RX_SCAN_MODE_START, return_code, p_buf, p_buf_len, &index);
+}
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/connectivity/codecs/ant/serializers/ant_search_channel_priority_set.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/connectivity/codecs/ant/serializers/ant_search_channel_priority_set.c
new file mode 100644
index 0000000..9cf0ad7
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/connectivity/codecs/ant/serializers/ant_search_channel_priority_set.c
@@ -0,0 +1,78 @@
+/**
+ * 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+
+#include <string.h>
+#include "ant_conn.h"
+#include "ble_serialization.h"
+#include "cond_field_serialization.h"
+#include "ant_struct_serialization.h"
+#include "app_util.h"
+
+uint32_t ant_search_channel_priority_set_req_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ uint8_t * const p_channel,
+ uint8_t * const p_search_priority)
+{
+ uint32_t index = SER_CMD_DATA_POS;
+ uint32_t err_code;
+
+ SER_ASSERT_NOT_NULL(p_buf);
+ SER_ASSERT_NOT_NULL(p_channel);
+ SER_ASSERT_NOT_NULL(p_search_priority);
+
+ err_code = uint8_t_dec(p_buf, packet_len, &index, p_channel);
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code);
+
+ err_code = uint8_t_dec(p_buf, packet_len, &index, p_search_priority);
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code);
+
+ SER_ASSERT_LENGTH_EQ(index, packet_len);
+
+ return err_code;
+}
+
+uint32_t ant_search_channel_priority_set_rsp_enc(uint32_t return_code,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len)
+{
+ uint32_t index = 0;
+
+ return op_status_enc(SVC_ANT_SEARCH_CHANNEL_PRIORITY_SET, return_code, p_buf, p_buf_len, &index);
+}
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/connectivity/codecs/ant/serializers/ant_search_waveform_set.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/connectivity/codecs/ant/serializers/ant_search_waveform_set.c
new file mode 100644
index 0000000..b15df8a
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/connectivity/codecs/ant/serializers/ant_search_waveform_set.c
@@ -0,0 +1,78 @@
+/**
+ * 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+
+#include <string.h>
+#include "ant_conn.h"
+#include "ble_serialization.h"
+#include "cond_field_serialization.h"
+#include "ant_struct_serialization.h"
+#include "app_util.h"
+
+uint32_t ant_search_waveform_set_req_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ uint8_t * const p_channel,
+ uint16_t * const p_waveform)
+{
+ uint32_t index = SER_CMD_DATA_POS;
+ uint32_t err_code;
+
+ SER_ASSERT_NOT_NULL(p_buf);
+ SER_ASSERT_NOT_NULL(p_channel);
+ SER_ASSERT_NOT_NULL(p_waveform);
+
+ err_code = uint8_t_dec(p_buf, packet_len, &index, p_channel);
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code);
+
+ err_code = uint16_t_dec(p_buf, packet_len, &index, p_waveform);
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code);
+
+ SER_ASSERT_LENGTH_EQ(index, packet_len);
+
+ return err_code;
+}
+
+uint32_t ant_search_waveform_set_rsp_enc(uint32_t return_code,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len)
+{
+ uint32_t index = 0;
+
+ return op_status_enc(SVC_ANT_SEARCH_WAVEFORM_SET, return_code, p_buf, p_buf_len, &index);
+}
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/connectivity/codecs/ant/serializers/ant_stack_reset.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/connectivity/codecs/ant/serializers/ant_stack_reset.c
new file mode 100644
index 0000000..aaed2dd
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/connectivity/codecs/ant/serializers/ant_stack_reset.c
@@ -0,0 +1,55 @@
+/**
+ * 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+
+#include <string.h>
+#include "ant_conn.h"
+#include "ble_serialization.h"
+#include "cond_field_serialization.h"
+#include "ant_struct_serialization.h"
+#include "app_util.h"
+
+uint32_t ant_stack_reset_rsp_enc(uint32_t return_code,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len)
+{
+ uint32_t index = 0;
+
+ return op_status_enc(SVC_ANT_STACK_INIT, return_code, p_buf, p_buf_len, &index);
+}
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/connectivity/codecs/ant/serializers/ant_version_get.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/connectivity/codecs/ant/serializers/ant_version_get.c
new file mode 100644
index 0000000..3caabcb
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/connectivity/codecs/ant/serializers/ant_version_get.c
@@ -0,0 +1,71 @@
+/**
+ * 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+
+#include <string.h>
+#include "ant_conn.h"
+#include "ble_serialization.h"
+#include "cond_field_serialization.h"
+#include "ant_struct_serialization.h"
+#include "app_util.h"
+
+uint32_t ant_version_get_rsp_enc(uint32_t return_code,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len,
+ uint8_t const * const p_version)
+{
+ SER_ASSERT_NOT_NULL(p_buf);
+ SER_ASSERT_NOT_NULL(p_buf_len);
+
+ uint32_t total_len = *p_buf_len;
+
+ uint32_t err_code = ser_ble_cmd_rsp_status_code_enc(SVC_ANT_VERSION, return_code,
+ p_buf, p_buf_len);
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code);
+
+ if (return_code != NRF_SUCCESS)
+ {
+ return NRF_SUCCESS;
+ }
+
+ err_code = uint8_vector_enc(p_version, MESG_BUFFER_SIZE, p_buf, total_len, p_buf_len);
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code);
+
+ return NRF_SUCCESS;
+}
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/connectivity/codecs/ble/middleware/conn_mw.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/connectivity/codecs/ble/middleware/conn_mw.h
new file mode 100644
index 0000000..974925a
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/connectivity/codecs/ble/middleware/conn_mw.h
@@ -0,0 +1,83 @@
+/**
+ * Copyright (c) 2014 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#ifndef _CONN_MW_H
+#define _CONN_MW_H
+
+/**
+ * @addtogroup sercon_mw_s132 Connectivity middleware codecs for S132 and S140 (connectivity side)
+ * @{
+ * @ingroup ser_codecs_mw
+ */
+
+#include <stdint.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**@brief Connectivity Middleware dispatcher function
+ *
+ * @details It handles decoding of the opcode from the RX buffer and based on the opcode, it searches
+ * for registered handler. Handler is called once it is found.
+ *
+ * @param[in] p_rx_buf Pointer to input buffer.
+ * @param[in] rx_buf_len Size of @p p_rx_buf.
+ * @param[out] p_tx_buf Pointer to output buffer.
+ * @param[in,out] p_tx_buf_len \c in: size of \p p_tx_buf buffer.
+ * \c out: Length of valid data in \p p_tx_buf.
+ *
+ * @retval NRF_SUCCESS Handler success.
+ * @retval NRF_ERROR_NULL Handler failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Handler failure. Incorrect buffer length.
+ * @retval NRF_ERROR_INVALID_PARAM Handler failure. Invalid operation type.
+ * @retval NRF_ERROR_NOT_SUPPORTED Handler failure. Opcode not supported.
+ */
+uint32_t conn_mw_handler (uint8_t const * const p_rx_buf,
+ uint32_t rx_buf_len,
+ uint8_t * const p_tx_buf,
+ uint32_t * const p_tx_buf_len);
+
+#ifdef __cplusplus
+}
+#endif
+
+/** @} */
+
+#endif //_CONN_MW_H
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/connectivity/codecs/ble/middleware/conn_mw_ble.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/connectivity/codecs/ble/middleware/conn_mw_ble.c
new file mode 100644
index 0000000..4893059
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/connectivity/codecs/ble/middleware/conn_mw_ble.c
@@ -0,0 +1,416 @@
+/**
+ * Copyright (c) 2014 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#include "ble_conn.h"
+#include "conn_mw_ble.h"
+#include "ble_serialization.h"
+#include "conn_ble_user_mem.h"
+#if defined(NRF_SD_BLE_API_VERSION) && NRF_SD_BLE_API_VERSION >= 5
+#include "nrf_sdh_ble.h"
+#endif
+#include <string.h>
+extern sercon_ble_user_mem_t m_conn_user_mem_table[];
+
+#if defined(NRF_SD_BLE_API_VERSION) && NRF_SD_BLE_API_VERSION < 4
+uint32_t conn_mw_ble_tx_packet_count_get(uint8_t const * const p_rx_buf,
+ uint32_t rx_buf_len,
+ uint8_t * const p_tx_buf,
+ uint32_t * const p_tx_buf_len)
+{
+ SER_ASSERT_NOT_NULL(p_rx_buf);
+ SER_ASSERT_NOT_NULL(p_tx_buf);
+ SER_ASSERT_NOT_NULL(p_tx_buf_len);
+
+ uint8_t count;
+ uint16_t conn_handle;
+ uint8_t * p_count = &count;
+
+ uint32_t err_code = NRF_SUCCESS;
+ uint32_t sd_err_code;
+
+ err_code = ble_tx_packet_count_get_req_dec(p_rx_buf, rx_buf_len, &conn_handle, &p_count);
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code);
+
+ sd_err_code = sd_ble_tx_packet_count_get(conn_handle, p_count);
+
+ err_code = ble_tx_packet_count_get_rsp_enc(sd_err_code, p_tx_buf, p_tx_buf_len, p_count);
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code);
+
+ return err_code;
+}
+#endif
+uint32_t conn_mw_ble_uuid_vs_add(uint8_t const * const p_rx_buf,
+ uint32_t rx_buf_len,
+ uint8_t * const p_tx_buf,
+ uint32_t * const p_tx_buf_len)
+{
+ SER_ASSERT_NOT_NULL(p_rx_buf);
+ SER_ASSERT_NOT_NULL(p_tx_buf);
+ SER_ASSERT_NOT_NULL(p_tx_buf_len);
+
+ ble_uuid128_t uuid;
+ ble_uuid128_t * p_uuid = &uuid;
+ uint8_t uuid_type;
+ uint8_t * p_uuid_type = &uuid_type;
+
+ uint32_t err_code = NRF_SUCCESS;
+ uint32_t sd_err_code;
+
+ err_code = ble_uuid_vs_add_req_dec(p_rx_buf, rx_buf_len, &p_uuid, &p_uuid_type);
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code);
+
+ sd_err_code = sd_ble_uuid_vs_add(p_uuid, p_uuid_type);
+
+ err_code = ble_uuid_vs_add_rsp_enc(sd_err_code, p_tx_buf, p_tx_buf_len, p_uuid_type);
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code);
+ return err_code;
+}
+
+uint32_t conn_mw_ble_uuid_decode(uint8_t const * const p_rx_buf,
+ uint32_t rx_buf_len,
+ uint8_t * const p_tx_buf,
+ uint32_t * const p_tx_buf_len)
+{
+ SER_ASSERT_NOT_NULL(p_rx_buf);
+ SER_ASSERT_NOT_NULL(p_tx_buf);
+ SER_ASSERT_NOT_NULL(p_tx_buf_len);
+
+ uint8_t raw_uuid[16];
+ uint8_t uuid_len = sizeof (raw_uuid);
+ uint8_t * p_raw_uuid = raw_uuid;
+ ble_uuid_t uuid;
+ ble_uuid_t * p_uuid = &uuid;
+ uint32_t err_code = NRF_SUCCESS;
+ uint32_t sd_err_code;
+
+ err_code = ble_uuid_decode_req_dec(p_rx_buf, rx_buf_len, &uuid_len, &p_raw_uuid, &p_uuid);
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code);
+
+ sd_err_code = sd_ble_uuid_decode(uuid_len, p_raw_uuid, p_uuid);
+
+ err_code = ble_uuid_decode_rsp_enc(sd_err_code, p_tx_buf, p_tx_buf_len, p_uuid);
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code);
+
+ return err_code;
+}
+
+uint32_t conn_mw_ble_uuid_encode(uint8_t const * const p_rx_buf,
+ uint32_t rx_buf_len,
+ uint8_t * const p_tx_buf,
+ uint32_t * const p_tx_buf_len)
+{
+ SER_ASSERT_NOT_NULL(p_rx_buf);
+ SER_ASSERT_NOT_NULL(p_tx_buf);
+ SER_ASSERT_NOT_NULL(p_tx_buf_len);
+
+ uint8_t raw_uuid[16];
+ uint8_t uuid_len = sizeof (raw_uuid);
+ uint8_t * p_uuid_len = &uuid_len;
+ uint8_t * p_raw_uuid = raw_uuid;
+ ble_uuid_t uuid;
+ ble_uuid_t * p_uuid = &uuid;
+ uint32_t err_code = NRF_SUCCESS;
+ uint32_t sd_err_code;
+
+ memset(&uuid, 0, sizeof(uuid));
+ err_code = ble_uuid_encode_req_dec(p_rx_buf, rx_buf_len, &p_uuid, &p_uuid_len, &p_raw_uuid);
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code);
+
+ sd_err_code = sd_ble_uuid_encode(p_uuid, p_uuid_len, p_raw_uuid);
+
+ err_code = ble_uuid_encode_rsp_enc(sd_err_code, p_tx_buf, p_tx_buf_len, uuid_len, p_raw_uuid);
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code);
+
+ return err_code;
+}
+
+uint32_t conn_mw_ble_version_get(uint8_t const * const p_rx_buf,
+ uint32_t rx_buf_len,
+ uint8_t * const p_tx_buf,
+ uint32_t * const p_tx_buf_len)
+{
+ SER_ASSERT_NOT_NULL(p_rx_buf);
+ SER_ASSERT_NOT_NULL(p_tx_buf);
+ SER_ASSERT_NOT_NULL(p_tx_buf_len);
+
+ ble_version_t version;
+ ble_version_t * p_version = &version;
+
+ uint32_t err_code = NRF_SUCCESS;
+ uint32_t sd_err_code;
+
+ err_code = ble_version_get_req_dec(p_rx_buf, rx_buf_len, &p_version);
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code);
+
+ sd_err_code = sd_ble_version_get(p_version);
+
+ err_code = ble_version_get_rsp_enc(sd_err_code, p_tx_buf, p_tx_buf_len, p_version);
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code);
+
+ return err_code;
+}
+uint32_t conn_mw_ble_opt_get(uint8_t const * const p_rx_buf,
+ uint32_t rx_buf_len,
+ uint8_t * const p_tx_buf,
+ uint32_t * const p_tx_buf_len)
+{
+ SER_ASSERT_NOT_NULL(p_rx_buf);
+ SER_ASSERT_NOT_NULL(p_tx_buf);
+ SER_ASSERT_NOT_NULL(p_tx_buf_len);
+
+ uint32_t opt_id;
+ ble_opt_t opt;
+ ble_opt_t *p_opt = &opt;
+
+ uint32_t err_code = NRF_SUCCESS;
+ uint32_t sd_err_code;
+
+ err_code = ble_opt_get_req_dec(p_rx_buf, rx_buf_len, &opt_id, &p_opt);
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code);
+
+ uint16_t act_latency;
+ uint8_t passkey[BLE_GAP_PASSKEY_LEN];
+ /* Initialaize appropriate pointers inside opt union based on opt_id */
+ switch (opt_id)
+ {
+ case BLE_GAP_OPT_LOCAL_CONN_LATENCY:
+ opt.gap_opt.local_conn_latency.p_actual_latency = &act_latency;
+ break;
+ case BLE_GAP_OPT_PASSKEY:
+ opt.gap_opt.passkey.p_passkey = passkey;
+ break;
+ }
+ sd_err_code = sd_ble_opt_get(opt_id, p_opt);
+
+ err_code = ble_opt_get_rsp_enc(sd_err_code, p_tx_buf, p_tx_buf_len, opt_id, p_opt);
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code);
+
+ return err_code;
+}
+
+uint32_t conn_mw_ble_opt_set(uint8_t const * const p_rx_buf,
+ uint32_t rx_buf_len,
+ uint8_t * const p_tx_buf,
+ uint32_t * const p_tx_buf_len)
+{
+ SER_ASSERT_NOT_NULL(p_rx_buf);
+ SER_ASSERT_NOT_NULL(p_tx_buf);
+ SER_ASSERT_NOT_NULL(p_tx_buf_len);
+
+ uint32_t opt_id = 0xFFFFFFFF;
+ uint16_t act_latency;
+ uint8_t passkey[BLE_GAP_PASSKEY_LEN];
+ uint32_t err_code = NRF_SUCCESS;
+
+ /* Pre-decode type of ble_opt_t union */
+ err_code = ble_opt_id_pre_dec(p_rx_buf, rx_buf_len, &opt_id);
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code);
+
+ ble_opt_t opt;
+ ble_opt_t *p_opt = &opt;
+ /* Initialaize appropriate pointers inside opt union based on opt_id */
+ switch (opt_id)
+ {
+ case BLE_GAP_OPT_LOCAL_CONN_LATENCY:
+ opt.gap_opt.local_conn_latency.p_actual_latency = &act_latency;
+ break;
+ case BLE_GAP_OPT_PASSKEY:
+ opt.gap_opt.passkey.p_passkey = passkey;
+ break;
+ }
+
+ uint32_t sd_err_code;
+
+ err_code = ble_opt_set_req_dec(p_rx_buf, rx_buf_len, &opt_id, &p_opt);
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code);
+
+ sd_err_code = sd_ble_opt_set(opt_id, p_opt);
+
+ err_code = ble_opt_set_rsp_enc(sd_err_code, p_tx_buf, p_tx_buf_len);
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code);
+
+ return err_code;
+}
+
+
+uint32_t conn_mw_ble_enable(uint8_t const * const p_rx_buf,
+ uint32_t rx_buf_len,
+ uint8_t * const p_tx_buf,
+ uint32_t * const p_tx_buf_len)
+{
+ SER_ASSERT_NOT_NULL(p_rx_buf);
+ SER_ASSERT_NOT_NULL(p_tx_buf);
+ SER_ASSERT_NOT_NULL(p_tx_buf_len);
+
+ uint32_t app_ram_base;
+
+/*lint --e{10} --e{19} --e{27} --e{40} --e{529} -save suppress Error 27: Illegal character */
+#if defined(_WIN32) || defined(__unix) || defined(__APPLE__)
+ uint32_t ram_start = 0;
+#elif defined ( __CC_ARM )
+ extern uint32_t Image$$RW_IRAM1$$Base;
+ volatile uint32_t ram_start = (uint32_t) &Image$$RW_IRAM1$$Base;
+#elif defined ( __ICCARM__ )
+ extern uint32_t __ICFEDIT_region_RAM_start__;
+ volatile uint32_t ram_start = (uint32_t) &__ICFEDIT_region_RAM_start__;
+#elif defined ( __GNUC__ )
+ extern uint32_t __data_start__;
+ volatile uint32_t ram_start = (uint32_t) &__data_start__;
+#endif
+ app_ram_base = ram_start;
+ uint32_t err_code = NRF_SUCCESS;
+ uint32_t sd_err_code;
+#if defined(NRF_SD_BLE_API_VERSION) && NRF_SD_BLE_API_VERSION < 4
+ ble_enable_params_t params;
+ ble_enable_params_t * p_params = &params;
+ ble_conn_bw_counts_t conn_bw_counts;
+ params.common_enable_params.p_conn_bw_counts = &conn_bw_counts;
+
+ uint8_t gap_device_name_value[BLE_GAP_DEVNAME_MAX_LEN];
+ ble_gap_device_name_t device_name;
+ device_name.max_len = BLE_GAP_DEVNAME_MAX_LEN;
+ device_name.p_value = gap_device_name_value;
+ params.gap_enable_params.p_device_name = &device_name;
+
+ err_code = ble_enable_req_dec(p_rx_buf, rx_buf_len, &p_params);
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code);
+
+ sd_err_code = sd_ble_enable(p_params, &app_ram_base);
+#else
+ err_code = ble_enable_req_dec(p_rx_buf, rx_buf_len);
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code);
+#if defined(NRF_SD_BLE_API_VERSION) && NRF_SD_BLE_API_VERSION <= 4
+ //Enable BLE SDH to enable events from BLE.
+ sd_err_code = sd_ble_enable(&app_ram_base);
+#else
+ //Enable BLE SDH to enable events from BLE.
+ sd_err_code = nrf_sdh_ble_enable(&app_ram_base);
+#endif
+#endif
+
+ err_code = ble_enable_rsp_enc(sd_err_code, p_tx_buf, p_tx_buf_len);
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code);
+
+ return err_code;
+}
+
+uint32_t conn_mw_ble_user_mem_reply(uint8_t const * const p_rx_buf,
+ uint32_t rx_buf_len,
+ uint8_t * const p_tx_buf,
+ uint32_t * const p_tx_buf_len)
+{
+ SER_ASSERT_NOT_NULL(p_rx_buf);
+ SER_ASSERT_NOT_NULL(p_tx_buf);
+ SER_ASSERT_NOT_NULL(p_tx_buf_len);
+
+ ble_user_mem_block_t mem_block;
+ ble_user_mem_block_t * p_mem_block = &mem_block;
+ uint32_t err_code = NRF_SUCCESS;
+ uint32_t user_mem_tab_index;
+ uint16_t conn_handle;
+ /* Allocate user memory context for SoftDevice */
+
+ uint32_t sd_err_code;
+
+ err_code = ble_user_mem_reply_req_dec(p_rx_buf, rx_buf_len, &conn_handle, &p_mem_block);
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code);
+
+ if (p_mem_block != NULL)
+ {
+ //Use the context if p_mem_block was not null
+ err_code = conn_ble_user_mem_context_create(&user_mem_tab_index);
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code);
+ m_conn_user_mem_table[user_mem_tab_index].conn_handle = conn_handle;
+ m_conn_user_mem_table[user_mem_tab_index].mem_block.len = p_mem_block->len;
+ p_mem_block = &(m_conn_user_mem_table[user_mem_tab_index].mem_block);
+ }
+
+ sd_err_code = sd_ble_user_mem_reply(conn_handle, p_mem_block);
+
+ err_code = ble_user_mem_reply_rsp_enc(sd_err_code, p_tx_buf, p_tx_buf_len);
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code);
+
+ return err_code;
+}
+#if NRF_SD_BLE_API_VERSION >= 4
+uint32_t conn_mw_ble_cfg_set(uint8_t const * const p_rx_buf,
+ uint32_t rx_buf_len,
+ uint8_t * const p_tx_buf,
+ uint32_t * const p_tx_buf_len)
+{
+ SER_ASSERT_NOT_NULL(p_rx_buf);
+ SER_ASSERT_NOT_NULL(p_tx_buf);
+ SER_ASSERT_NOT_NULL(p_tx_buf_len);
+
+ uint32_t app_ram_base;
+
+/*lint --e{10} --e{19} --e{27} --e{40} --e{529} -save suppress Error 27: Illegal character */
+#if defined(_WIN32) || defined(__unix) || defined(__APPLE__)
+ uint32_t ram_start = 0;
+#elif defined ( __CC_ARM )
+ extern uint32_t Image$$RW_IRAM1$$Base;
+ volatile uint32_t ram_start = (uint32_t) &Image$$RW_IRAM1$$Base;
+#elif defined ( __ICCARM__ )
+ extern uint32_t __ICFEDIT_region_RAM_start__;
+ volatile uint32_t ram_start = (uint32_t) &__ICFEDIT_region_RAM_start__;
+#elif defined ( __GNUC__ )
+ extern uint32_t __data_start__;
+ volatile uint32_t ram_start = (uint32_t) &__data_start__;
+#endif
+ app_ram_base = ram_start;
+ uint32_t err_code = NRF_SUCCESS;
+ uint32_t sd_err_code;
+ uint32_t cfg_id;
+ ble_cfg_t cfg;
+ uint8_t gap_device_name_value[BLE_GAP_DEVNAME_MAX_LEN];
+ cfg.gap_cfg.device_name_cfg.p_value = gap_device_name_value;
+ cfg.gap_cfg.device_name_cfg.max_len = BLE_GAP_DEVNAME_MAX_LEN;
+ ble_cfg_t * p_cfg = &cfg;
+
+ err_code = ble_cfg_set_req_dec(p_rx_buf, rx_buf_len, &cfg_id, &p_cfg);
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code);
+
+ sd_err_code = sd_ble_cfg_set(cfg_id,p_cfg, app_ram_base);
+
+ err_code = ble_cfg_set_rsp_enc(sd_err_code, p_tx_buf, p_tx_buf_len);
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code);
+
+ return err_code;
+}
+#endif
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/connectivity/codecs/ble/middleware/conn_mw_ble.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/connectivity/codecs/ble/middleware/conn_mw_ble.h
new file mode 100644
index 0000000..9d67e7e
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/connectivity/codecs/ble/middleware/conn_mw_ble.h
@@ -0,0 +1,242 @@
+/**
+ * Copyright (c) 2014 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#ifndef _CONN_MW_BLE_H
+#define _CONN_MW_BLE_H
+
+#include <stdint.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @addtogroup sercon_mw_s132_ble Middleware command handlers
+ * @{
+ * @ingroup sercon_mw_s132
+ */
+
+/**@brief Handles sd_ble_tx_packet_count_get command and prepares response.
+ *
+ * @param[in] p_rx_buf Pointer to input buffer.
+ * @param[in] rx_buf_len Size of @p p_rx_buf.
+ * @param[out] p_tx_buf Pointer to output buffer.
+ * @param[in,out] p_tx_buf_len \c in: Size of \p p_tx_buf buffer.
+ * \c out: Length of valid data in \p p_tx_buf.
+ *
+ * @retval NRF_SUCCESS Handler success.
+ * @retval NRF_ERROR_NULL Handler failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Handler failure. Incorrect buffer length.
+ * @retval NRF_ERROR_INVALID_PARAM Handler failure. Invalid operation type.
+ */
+uint32_t conn_mw_ble_tx_packet_count_get(uint8_t const * const p_rx_buf,
+ uint32_t rx_buf_len,
+ uint8_t * const p_tx_buf,
+ uint32_t * const p_tx_buf_len);
+
+/**@brief Handles @ref sd_ble_uuid_vs_add command and prepares response.
+ *
+ * @param[in] p_rx_buf Pointer to input buffer.
+ * @param[in] rx_buf_len Size of @p p_rx_buf.
+ * @param[out] p_tx_buf Pointer to output buffer.
+ * @param[in,out] p_tx_buf_len \c in: Size of \p p_tx_buf buffer.
+ * \c out: Length of valid data in \p p_tx_buf.
+ *
+ * @retval NRF_SUCCESS Handler success.
+ * @retval NRF_ERROR_NULL Handler failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Handler failure. Incorrect buffer length.
+ * @retval NRF_ERROR_INVALID_PARAM Handler failure. Invalid operation type.
+ */
+uint32_t conn_mw_ble_uuid_vs_add(uint8_t const * const p_rx_buf,
+ uint32_t rx_buf_len,
+ uint8_t * const p_tx_buf,
+ uint32_t * const p_tx_buf_len);
+
+/**@brief Handles @ref sd_ble_uuid_decode command and prepares response.
+ *
+ * @param[in] p_rx_buf Pointer to input buffer.
+ * @param[in] rx_buf_len Size of @p p_rx_buf.
+ * @param[out] p_tx_buf Pointer to output buffer.
+ * @param[in,out] p_tx_buf_len \c in: Size of \p p_tx_buf buffer.
+ * \c out: Length of valid data in \p p_tx_buf.
+ *
+ * @retval NRF_SUCCESS Handler success.
+ * @retval NRF_ERROR_NULL Handler failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Handler failure. Incorrect buffer length.
+ * @retval NRF_ERROR_INVALID_PARAM Handler failure. Invalid operation type.
+ */
+uint32_t conn_mw_ble_uuid_decode(uint8_t const * const p_rx_buf,
+ uint32_t rx_buf_len,
+ uint8_t * const p_tx_buf,
+ uint32_t * const p_tx_buf_len);
+
+/**@brief Handles @ref sd_ble_uuid_encode command and prepares response.
+ *
+ * @param[in] p_rx_buf Pointer to input buffer.
+ * @param[in] rx_buf_len Size of @p p_rx_buf.
+ * @param[out] p_tx_buf Pointer to output buffer.
+ * @param[in,out] p_tx_buf_len \c in: Size of \p p_tx_buf buffer.
+ * \c out: Length of valid data in \p p_tx_buf.
+ *
+ * @retval NRF_SUCCESS Handler success.
+ * @retval NRF_ERROR_NULL Handler failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Handler failure. Incorrect buffer length.
+ * @retval NRF_ERROR_INVALID_PARAM Handler failure. Invalid operation type.
+ */
+uint32_t conn_mw_ble_uuid_encode(uint8_t const * const p_rx_buf,
+ uint32_t rx_buf_len,
+ uint8_t * const p_tx_buf,
+ uint32_t * const p_tx_buf_len);
+
+/**@brief Handles @ref sd_ble_version_get command and prepares response.
+ *
+ * @param[in] p_rx_buf Pointer to input buffer.
+ * @param[in] rx_buf_len Size of @p p_rx_buf.
+ * @param[out] p_tx_buf Pointer to output buffer.
+ * @param[in,out] p_tx_buf_len \c in: Size of \p p_tx_buf buffer.
+ * \c out: Length of valid data in \p p_tx_buf.
+ *
+ * @retval NRF_SUCCESS Handler success.
+ * @retval NRF_ERROR_NULL Handler failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Handler failure. Incorrect buffer length.
+ * @retval NRF_ERROR_INVALID_PARAM Handler failure. Invalid operation type.
+ */
+uint32_t conn_mw_ble_version_get(uint8_t const * const p_rx_buf,
+ uint32_t rx_buf_len,
+ uint8_t * const p_tx_buf,
+ uint32_t * const p_tx_buf_len);
+
+/**@brief Handles @ref sd_ble_opt_get command and prepares response.
+ *
+ * @param[in] p_rx_buf Pointer to input buffer.
+ * @param[in] rx_buf_len Size of @p p_rx_buf.
+ * @param[out] p_tx_buf Pointer to output buffer.
+ * @param[in,out] p_tx_buf_len \c in: Size of \p p_tx_buf buffer.
+ * \c out: Length of valid data in \p p_tx_buf.
+ *
+ * @retval NRF_SUCCESS Handler success.
+ * @retval NRF_ERROR_NULL Handler failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Handler failure. Incorrect buffer length.
+ * @retval NRF_ERROR_INVALID_PARAM Handler failure. Invalid operation type.
+ */
+uint32_t conn_mw_ble_opt_get(uint8_t const * const p_rx_buf,
+ uint32_t rx_buf_len,
+ uint8_t * const p_tx_buf,
+ uint32_t * const p_tx_buf_len);
+
+/**@brief Handles @ref sd_ble_opt_set command and prepares response.
+ *
+ * @param[in] p_rx_buf Pointer to input buffer.
+ * @param[in] rx_buf_len Size of @p p_rx_buf.
+ * @param[out] p_tx_buf Pointer to output buffer.
+ * @param[in,out] p_tx_buf_len \c in: Size of \p p_tx_buf buffer.
+ * \c out: Length of valid data in \p p_tx_buf.
+ *
+ * @retval NRF_SUCCESS Handler success.
+ * @retval NRF_ERROR_NULL Handler failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Handler failure. Incorrect buffer length.
+ * @retval NRF_ERROR_INVALID_PARAM Handler failure. Invalid operation type.
+ */
+uint32_t conn_mw_ble_opt_set(uint8_t const * const p_rx_buf,
+ uint32_t rx_buf_len,
+ uint8_t * const p_tx_buf,
+ uint32_t * const p_tx_buf_len);
+
+/**@brief Handles @ref sd_ble_enable command and prepares response.
+ *
+ * @param[in] p_rx_buf Pointer to input buffer.
+ * @param[in] rx_buf_len Size of @p p_rx_buf.
+ * @param[out] p_tx_buf Pointer to output buffer.
+ * @param[in,out] p_tx_buf_len \c in: Size of \p p_tx_buf buffer.
+ * \c out: Length of valid data in \p p_tx_buf.
+ *
+ * @retval NRF_SUCCESS Handler success.
+ * @retval NRF_ERROR_NULL Handler failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Handler failure. Incorrect buffer length.
+ * @retval NRF_ERROR_INVALID_PARAM Handler failure. Invalid operation type.
+ */
+uint32_t conn_mw_ble_enable(uint8_t const * const p_rx_buf,
+ uint32_t rx_buf_len,
+ uint8_t * const p_tx_buf,
+ uint32_t * const p_tx_buf_len);
+
+/**@brief Handles @ref sd_ble_user_mem_reply command and prepares response.
+ *
+ * @param[in] p_rx_buf Pointer to input buffer.
+ * @param[in] rx_buf_len Size of @p p_rx_buf.
+ * @param[out] p_tx_buf Pointer to output buffer.
+ * @param[in,out] p_tx_buf_len \c in: Size of \p p_tx_buf buffer.
+ * \c out: Length of valid data in \p p_tx_buf.
+ *
+ * @retval NRF_SUCCESS Handler success.
+ * @retval NRF_ERROR_NULL Handler failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Handler failure. Incorrect buffer length.
+ * @retval NRF_ERROR_INVALID_PARAM Handler failure. Invalid operation type.
+ */
+uint32_t conn_mw_ble_user_mem_reply(uint8_t const * const p_rx_buf,
+ uint32_t rx_buf_len,
+ uint8_t * const p_tx_buf,
+ uint32_t * const p_tx_buf_len);
+#if NRF_SD_BLE_API_VERSION >= 4
+/**@brief Handles @ref sd_ble_cfg_set command and prepares response.
+ *
+ * @param[in] p_rx_buf Pointer to input buffer.
+ * @param[in] rx_buf_len Size of @p p_rx_buf.
+ * @param[out] p_tx_buf Pointer to output buffer.
+ * @param[in,out] p_tx_buf_len \c in: Size of \p p_tx_buf buffer.
+ * \c out: Length of valid data in \p p_tx_buf.
+ *
+ * @retval NRF_SUCCESS Handler success.
+ * @retval NRF_ERROR_NULL Handler failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Handler failure. Incorrect buffer length.
+ * @retval NRF_ERROR_INVALID_PARAM Handler failure. Invalid operation type.
+ */
+uint32_t conn_mw_ble_cfg_set(uint8_t const * const p_rx_buf,
+ uint32_t rx_buf_len,
+ uint8_t * const p_tx_buf,
+ uint32_t * const p_tx_buf_len);
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+/** @} */
+
+#endif //_CONN_MW_BLE_H
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/connectivity/codecs/ble/middleware/conn_mw_ble_gap.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/connectivity/codecs/ble/middleware/conn_mw_ble_gap.c
new file mode 100644
index 0000000..6142d44
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/connectivity/codecs/ble/middleware/conn_mw_ble_gap.c
@@ -0,0 +1,1290 @@
+/**
+ * Copyright (c) 2014 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#include "ble_gap_conn.h"
+#include "ser_config.h"
+#include "conn_mw_ble_gap.h"
+#include "ble_serialization.h"
+#include "conn_ble_gap_sec_keys.h"
+#include <stddef.h>
+
+extern ser_ble_gap_conn_keyset_t m_conn_keys_table[SER_MAX_CONNECTIONS];
+#if NRF_SD_BLE_API_VERSION > 5 && !defined(S112)
+static uint8_t * mp_scan_data;
+#endif
+
+/* Id used to identify buffer allocated for scan reports. */
+#define SCAN_BUFFER_ID 1
+#ifndef S112
+
+uint32_t conn_mw_ble_gap_connect(uint8_t const * const p_rx_buf,
+ uint32_t rx_buf_len,
+ uint8_t * const p_tx_buf,
+ uint32_t * const p_tx_buf_len)
+{
+ SER_ASSERT_NOT_NULL(p_rx_buf);
+ SER_ASSERT_NOT_NULL(p_tx_buf);
+ SER_ASSERT_NOT_NULL(p_tx_buf_len);
+
+ ble_gap_addr_t addr;
+ ble_gap_addr_t * p_addr = &addr;
+
+ ble_gap_scan_params_t scan_params;
+ ble_gap_scan_params_t * p_scan_params = &scan_params;
+
+ ble_gap_conn_params_t conn_params;
+ ble_gap_conn_params_t * p_conn_params = &conn_params;
+
+ uint32_t err_code = NRF_SUCCESS;
+ uint32_t sd_err_code;
+
+#if NRF_SD_BLE_API_VERSION >= 4
+ uint8_t conn_cfg_tag;
+ err_code = ble_gap_connect_req_dec(p_rx_buf, rx_buf_len, &p_addr,
+ &p_scan_params, &p_conn_params, &conn_cfg_tag);
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code);
+
+ sd_err_code = sd_ble_gap_connect(p_addr, p_scan_params, p_conn_params, conn_cfg_tag);
+#else
+ err_code = ble_gap_connect_req_dec(p_rx_buf, rx_buf_len, &p_addr,
+ &p_scan_params, &p_conn_params);
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code);
+
+ sd_err_code = sd_ble_gap_connect(p_addr, p_scan_params, p_conn_params);
+#endif
+
+ err_code = ble_gap_connect_rsp_enc(sd_err_code, p_tx_buf, p_tx_buf_len);
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code);
+
+ return err_code;
+}
+
+uint32_t conn_mw_ble_gap_connect_cancel(uint8_t const * const p_rx_buf,
+ uint32_t rx_buf_len,
+ uint8_t * const p_tx_buf,
+ uint32_t * const p_tx_buf_len)
+{
+ SER_ASSERT_NOT_NULL(p_rx_buf);
+ SER_ASSERT_NOT_NULL(p_tx_buf);
+ SER_ASSERT_NOT_NULL(p_tx_buf_len);
+
+ uint32_t err_code = NRF_SUCCESS;
+ uint32_t sd_err_code;
+
+ sd_err_code = sd_ble_gap_connect_cancel();
+
+ err_code = ble_gap_connect_cancel_rsp_enc(sd_err_code, p_tx_buf, p_tx_buf_len);
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code);
+
+ return err_code;
+}
+
+uint32_t conn_mw_ble_gap_scan_start(uint8_t const * const p_rx_buf,
+ uint32_t rx_buf_len,
+ uint8_t * const p_tx_buf,
+ uint32_t * const p_tx_buf_len)
+{
+ SER_ASSERT_NOT_NULL(p_rx_buf);
+ SER_ASSERT_NOT_NULL(p_tx_buf);
+ SER_ASSERT_NOT_NULL(p_tx_buf_len);
+ uint32_t err_code = NRF_SUCCESS;
+ uint32_t sd_err_code;
+ ble_gap_scan_params_t scan_params;
+ ble_gap_scan_params_t * p_scan_params = &scan_params;
+#if defined(NRF_SD_BLE_API_VERSION) && NRF_SD_BLE_API_VERSION > 5
+ ble_data_t adv_report_buffer;
+ ble_data_t * p_adv_report_buffer = &adv_report_buffer;
+ mp_scan_data = conn_ble_gap_ble_data_buf_alloc(SCAN_BUFFER_ID);
+ adv_report_buffer.p_data = mp_scan_data;
+ adv_report_buffer.len = SER_MAX_ADV_DATA;
+ err_code = ble_gap_scan_start_req_dec(p_rx_buf, rx_buf_len, &p_scan_params, &p_adv_report_buffer);
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code);
+
+ sd_err_code = sd_ble_gap_scan_start(p_scan_params, p_adv_report_buffer);
+#else
+ err_code = ble_gap_scan_start_req_dec(p_rx_buf, rx_buf_len, &p_scan_params);
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code);
+
+ sd_err_code = sd_ble_gap_scan_start(p_scan_params);
+#endif
+ err_code = ble_gap_scan_start_rsp_enc(sd_err_code, p_tx_buf, p_tx_buf_len);
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code);
+
+ return err_code;
+}
+
+
+uint32_t conn_mw_ble_gap_scan_stop(uint8_t const * const p_rx_buf,
+ uint32_t rx_buf_len,
+ uint8_t * const p_tx_buf,
+ uint32_t * const p_tx_buf_len)
+{
+ SER_ASSERT_NOT_NULL(p_rx_buf);
+ SER_ASSERT_NOT_NULL(p_tx_buf);
+ SER_ASSERT_NOT_NULL(p_tx_buf_len);
+
+ uint32_t err_code = NRF_SUCCESS;
+ uint32_t sd_err_code;
+
+#if defined(NRF_SD_BLE_API_VERSION) && NRF_SD_BLE_API_VERSION > 5
+ conn_ble_gap_ble_data_buf_free(mp_scan_data);
+#endif
+
+ sd_err_code = sd_ble_gap_scan_stop();
+
+ err_code = ble_gap_scan_stop_rsp_enc(sd_err_code, p_tx_buf, p_tx_buf_len);
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code);
+
+ return err_code;
+}
+
+uint32_t conn_mw_ble_gap_encrypt(uint8_t const * const p_rx_buf,
+ uint32_t rx_buf_len,
+ uint8_t * const p_tx_buf,
+ uint32_t * const p_tx_buf_len)
+{
+ SER_ASSERT_NOT_NULL(p_rx_buf);
+ SER_ASSERT_NOT_NULL(p_tx_buf);
+ SER_ASSERT_NOT_NULL(p_tx_buf_len);
+
+ uint32_t err_code = NRF_SUCCESS;
+ uint32_t sd_err_code;
+
+ uint16_t conn_handle;
+
+ ble_gap_master_id_t master_id;
+ ble_gap_master_id_t *p_master_id = &master_id;
+
+ ble_gap_enc_info_t enc_info;
+ ble_gap_enc_info_t *p_enc_info = &enc_info;
+
+ err_code = ble_gap_encrypt_req_dec(p_rx_buf, rx_buf_len, &conn_handle, &p_master_id, &p_enc_info);
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code);
+
+ sd_err_code = sd_ble_gap_encrypt(conn_handle, p_master_id, p_enc_info);
+
+ err_code = ble_gap_encrypt_rsp_enc(sd_err_code, p_tx_buf, p_tx_buf_len);
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code);
+
+ return err_code;
+}
+#endif //!S112
+
+#if defined(NRF_SD_BLE_API_VERSION) && NRF_SD_BLE_API_VERSION < 6
+uint32_t conn_mw_ble_gap_adv_data_set(uint8_t const * const p_rx_buf,
+ uint32_t rx_buf_len,
+ uint8_t * const p_tx_buf,
+ uint32_t * const p_tx_buf_len)
+{
+ SER_ASSERT_NOT_NULL(p_rx_buf);
+ SER_ASSERT_NOT_NULL(p_tx_buf);
+ SER_ASSERT_NOT_NULL(p_tx_buf_len);
+
+ uint8_t data[BLE_GAP_ADV_MAX_SIZE];
+ uint8_t * p_data = data;
+ uint8_t dlen = sizeof (data);
+
+ uint8_t sr_data[BLE_GAP_ADV_MAX_SIZE];
+ uint8_t * p_sr_data = sr_data;
+ uint8_t srdlen = sizeof (sr_data);
+
+ uint32_t err_code = NRF_SUCCESS;
+ uint32_t sd_err_code;
+
+ err_code = ble_gap_adv_data_set_req_dec(p_rx_buf,
+ rx_buf_len,
+ &p_data,
+ &dlen,
+ &p_sr_data,
+ &srdlen);
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code);
+
+ sd_err_code = sd_ble_gap_adv_data_set(p_data, dlen, p_sr_data, srdlen);
+
+ err_code = ble_gap_adv_data_set_rsp_enc(sd_err_code, p_tx_buf, p_tx_buf_len);
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code);
+
+ return err_code;
+}
+#endif
+
+uint32_t conn_mw_ble_gap_adv_start(uint8_t const * const p_rx_buf,
+ uint32_t rx_buf_len,
+ uint8_t * const p_tx_buf,
+ uint32_t * const p_tx_buf_len)
+{
+ SER_ASSERT_NOT_NULL(p_rx_buf);
+ SER_ASSERT_NOT_NULL(p_tx_buf);
+ SER_ASSERT_NOT_NULL(p_tx_buf_len);
+
+ uint32_t err_code = NRF_SUCCESS;
+ uint32_t sd_err_code;
+
+#if NRF_SD_BLE_API_VERSION > 5
+ uint8_t conn_cfg_tag;
+ uint8_t adv_handle;
+
+ err_code = ble_gap_adv_start_req_dec(p_rx_buf, rx_buf_len, &adv_handle, &conn_cfg_tag);
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code);
+
+ sd_err_code = sd_ble_gap_adv_start(adv_handle, conn_cfg_tag);
+#else
+ ble_gap_addr_t peer_addr;
+ ble_gap_adv_params_t adv_params;
+ ble_gap_adv_params_t * p_adv_params;
+
+ adv_params.p_peer_addr = &peer_addr;
+ p_adv_params = &adv_params;
+#if NRF_SD_BLE_API_VERSION >= 4
+ uint8_t conn_cfg_tag;
+ err_code = ble_gap_adv_start_req_dec(p_rx_buf, rx_buf_len, &p_adv_params, &conn_cfg_tag);
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code);
+
+ sd_err_code = sd_ble_gap_adv_start(p_adv_params, conn_cfg_tag);
+#else
+ err_code = ble_gap_adv_start_req_dec(p_rx_buf, rx_buf_len, &p_adv_params);
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code);
+
+ sd_err_code = sd_ble_gap_adv_start(p_adv_params);
+#endif
+#endif
+ err_code = ble_gap_adv_start_rsp_enc(sd_err_code, p_tx_buf, p_tx_buf_len);
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code);
+
+ return err_code;
+}
+
+uint32_t conn_mw_ble_gap_adv_stop(uint8_t const * const p_rx_buf,
+ uint32_t rx_buf_len,
+ uint8_t * const p_tx_buf,
+ uint32_t * const p_tx_buf_len)
+{
+ SER_ASSERT_NOT_NULL(p_rx_buf);
+ SER_ASSERT_NOT_NULL(p_tx_buf);
+ SER_ASSERT_NOT_NULL(p_tx_buf_len);
+
+ uint32_t err_code = NRF_SUCCESS;
+ uint32_t sd_err_code;
+#if NRF_SD_BLE_API_VERSION > 5
+ uint8_t adv_handle;
+ err_code = ble_gap_adv_stop_req_dec(p_rx_buf, rx_buf_len, &adv_handle);
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code);
+
+ sd_err_code = sd_ble_gap_adv_stop(adv_handle);
+#else
+ sd_err_code = sd_ble_gap_adv_stop();
+#endif
+
+ err_code = ble_gap_adv_stop_rsp_enc(sd_err_code, p_tx_buf, p_tx_buf_len);
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code);
+
+ return err_code;
+}
+
+uint32_t conn_mw_ble_gap_conn_param_update(uint8_t const * const p_rx_buf,
+ uint32_t rx_buf_len,
+ uint8_t * const p_tx_buf,
+ uint32_t * const p_tx_buf_len)
+{
+ SER_ASSERT_NOT_NULL(p_rx_buf);
+ SER_ASSERT_NOT_NULL(p_tx_buf);
+ SER_ASSERT_NOT_NULL(p_tx_buf_len);
+
+ uint16_t conn_handle;
+ ble_gap_conn_params_t conn_params;
+ ble_gap_conn_params_t * p_conn_params = &conn_params;
+
+ uint32_t err_code = NRF_SUCCESS;
+ uint32_t sd_err_code;
+
+ err_code = ble_gap_conn_param_update_req_dec(p_rx_buf, rx_buf_len, &conn_handle, &p_conn_params);
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code);
+
+ sd_err_code = sd_ble_gap_conn_param_update(conn_handle, p_conn_params);
+
+ err_code = ble_gap_conn_param_update_rsp_enc(sd_err_code, p_tx_buf, p_tx_buf_len);
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code);
+
+ return err_code;
+}
+
+uint32_t conn_mw_ble_gap_disconnect(uint8_t const * const p_rx_buf,
+ uint32_t rx_buf_len,
+ uint8_t * const p_tx_buf,
+ uint32_t * const p_tx_buf_len)
+{
+ SER_ASSERT_NOT_NULL(p_rx_buf);
+ SER_ASSERT_NOT_NULL(p_tx_buf);
+ SER_ASSERT_NOT_NULL(p_tx_buf_len);
+
+ uint16_t conn_handle;
+ uint8_t hci_status_code;
+
+ uint32_t err_code = NRF_SUCCESS;
+ uint32_t sd_err_code;
+
+ err_code = ble_gap_disconnect_req_dec(p_rx_buf, rx_buf_len, &conn_handle, &hci_status_code);
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code);
+
+ sd_err_code = sd_ble_gap_disconnect(conn_handle, hci_status_code);
+
+ err_code = ble_gap_disconnect_rsp_enc(sd_err_code, p_tx_buf, p_tx_buf_len);
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code);
+
+ return err_code;
+}
+
+uint32_t conn_mw_ble_gap_tx_power_set(uint8_t const * const p_rx_buf,
+ uint32_t rx_buf_len,
+ uint8_t * const p_tx_buf,
+ uint32_t * const p_tx_buf_len)
+{
+ SER_ASSERT_NOT_NULL(p_rx_buf);
+ SER_ASSERT_NOT_NULL(p_tx_buf);
+ SER_ASSERT_NOT_NULL(p_tx_buf_len);
+
+ int8_t tx_power;
+
+ uint32_t err_code = NRF_SUCCESS;
+ uint32_t sd_err_code;
+#if NRF_SD_BLE_API_VERSION > 5
+ uint8_t role;
+ uint16_t handle;
+
+ err_code = ble_gap_tx_power_set_req_dec(p_rx_buf, rx_buf_len, &role, &handle, &tx_power);
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code);
+
+ sd_err_code = sd_ble_gap_tx_power_set(role, handle, tx_power);
+#else
+ err_code = ble_gap_tx_power_set_req_dec(p_rx_buf, rx_buf_len, &tx_power);
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code);
+
+ sd_err_code = sd_ble_gap_tx_power_set(tx_power);
+#endif
+ err_code = ble_gap_tx_power_set_rsp_enc(sd_err_code, p_tx_buf, p_tx_buf_len);
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code);
+
+ return err_code;
+}
+
+uint32_t conn_mw_ble_gap_appearance_set(uint8_t const * const p_rx_buf,
+ uint32_t rx_buf_len,
+ uint8_t * const p_tx_buf,
+ uint32_t * const p_tx_buf_len)
+{
+ SER_ASSERT_NOT_NULL(p_rx_buf);
+ SER_ASSERT_NOT_NULL(p_tx_buf);
+ SER_ASSERT_NOT_NULL(p_tx_buf_len);
+
+ uint16_t appearance;
+
+ uint32_t err_code = NRF_SUCCESS;
+ uint32_t sd_err_code;
+
+ err_code = ble_gap_appearance_set_req_dec(p_rx_buf, rx_buf_len, &appearance);
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code);
+
+ sd_err_code = sd_ble_gap_appearance_set(appearance);
+
+ err_code = ble_gap_appearance_set_rsp_enc(sd_err_code, p_tx_buf, p_tx_buf_len);
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code);
+
+ return err_code;
+}
+
+uint32_t conn_mw_ble_gap_appearance_get(uint8_t const * const p_rx_buf,
+ uint32_t rx_buf_len,
+ uint8_t * const p_tx_buf,
+ uint32_t * const p_tx_buf_len)
+{
+ SER_ASSERT_NOT_NULL(p_rx_buf);
+ SER_ASSERT_NOT_NULL(p_tx_buf);
+ SER_ASSERT_NOT_NULL(p_tx_buf_len);
+
+ uint16_t appearance;
+ uint16_t * p_appearance = &appearance;
+
+ uint32_t err_code = NRF_SUCCESS;
+ uint32_t sd_err_code;
+
+ err_code = ble_gap_appearance_get_req_dec(p_rx_buf, rx_buf_len, &p_appearance);
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code);
+
+ sd_err_code = sd_ble_gap_appearance_get(p_appearance);
+
+ err_code = ble_gap_appearance_get_rsp_enc(sd_err_code, p_tx_buf, p_tx_buf_len, p_appearance);
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code);
+
+ return err_code;
+}
+
+
+uint32_t conn_mw_ble_gap_ppcp_set(uint8_t const * const p_rx_buf,
+ uint32_t rx_buf_len,
+ uint8_t * const p_tx_buf,
+ uint32_t * const p_tx_buf_len)
+{
+ SER_ASSERT_NOT_NULL(p_rx_buf);
+ SER_ASSERT_NOT_NULL(p_tx_buf);
+ SER_ASSERT_NOT_NULL(p_tx_buf_len);
+
+ ble_gap_conn_params_t conn_params;
+ ble_gap_conn_params_t * p_conn_params = &conn_params;
+
+ uint32_t err_code = NRF_SUCCESS;
+ uint32_t sd_err_code;
+
+ err_code = ble_gap_ppcp_set_req_dec(p_rx_buf, rx_buf_len, &p_conn_params);
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code);
+
+ sd_err_code = sd_ble_gap_ppcp_set(p_conn_params);
+
+ err_code = ble_gap_ppcp_set_rsp_enc(sd_err_code, p_tx_buf, p_tx_buf_len);
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code);
+
+ return err_code;
+}
+
+uint32_t conn_mw_ble_gap_ppcp_get(uint8_t const * const p_rx_buf,
+ uint32_t rx_buf_len,
+ uint8_t * const p_tx_buf,
+ uint32_t * const p_tx_buf_len)
+{
+ SER_ASSERT_NOT_NULL(p_rx_buf);
+ SER_ASSERT_NOT_NULL(p_tx_buf);
+ SER_ASSERT_NOT_NULL(p_tx_buf_len);
+
+ ble_gap_conn_params_t conn_params;
+ ble_gap_conn_params_t * p_conn_params = &conn_params;
+
+ uint32_t err_code = NRF_SUCCESS;
+ uint32_t sd_err_code;
+
+ err_code = ble_gap_ppcp_get_req_dec(p_rx_buf, rx_buf_len, &p_conn_params);
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code);
+
+ sd_err_code = sd_ble_gap_ppcp_get(p_conn_params);
+
+ err_code = ble_gap_ppcp_get_rsp_enc(sd_err_code, p_tx_buf, p_tx_buf_len, p_conn_params);
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code);
+
+ return err_code;
+}
+
+uint32_t conn_mw_ble_gap_device_name_get(uint8_t const * const p_rx_buf,
+ uint32_t rx_buf_len,
+ uint8_t * const p_tx_buf,
+ uint32_t * const p_tx_buf_len)
+{
+ SER_ASSERT_NOT_NULL(p_rx_buf);
+ SER_ASSERT_NOT_NULL(p_tx_buf);
+ SER_ASSERT_NOT_NULL(p_tx_buf_len);
+
+ uint32_t err_code = NRF_SUCCESS;
+ uint32_t sd_err_code;
+
+ uint8_t dev_name[BLE_GAP_DEVNAME_MAX_LEN];
+ uint8_t * p_dev_name = dev_name;
+
+ uint16_t len;
+ uint16_t * p_len = &len;
+
+ err_code = ble_gap_device_name_get_req_dec(p_rx_buf, rx_buf_len, &p_dev_name, &p_len);
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code);
+
+ sd_err_code = sd_ble_gap_device_name_get(p_dev_name, p_len);
+
+ err_code = ble_gap_device_name_get_rsp_enc(sd_err_code, p_dev_name, p_len, p_tx_buf, p_tx_buf_len);
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code);
+
+ return err_code;
+}
+
+uint32_t conn_mw_ble_gap_device_name_set(uint8_t const * const p_rx_buf,
+ uint32_t rx_buf_len,
+ uint8_t * const p_tx_buf,
+ uint32_t * const p_tx_buf_len)
+{
+ SER_ASSERT_NOT_NULL(p_rx_buf);
+ SER_ASSERT_NOT_NULL(p_tx_buf);
+ SER_ASSERT_NOT_NULL(p_tx_buf_len);
+
+ uint32_t err_code = NRF_SUCCESS;
+ uint32_t sd_err_code;
+
+ ble_gap_conn_sec_mode_t write_perm;
+ ble_gap_conn_sec_mode_t * p_write_perm = &write_perm;
+
+ uint8_t dev_name[BLE_GAP_DEVNAME_MAX_LEN];
+ uint8_t * p_dev_name = dev_name;
+
+ uint16_t len = BLE_GAP_DEVNAME_MAX_LEN;
+
+ err_code = ble_gap_device_name_set_req_dec(p_rx_buf,
+ rx_buf_len,
+ &p_write_perm,
+ &p_dev_name,
+ &len);
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code);
+
+ sd_err_code = sd_ble_gap_device_name_set(p_write_perm, p_dev_name, len);
+
+ err_code = ble_gap_device_name_set_rsp_enc(sd_err_code, p_tx_buf, p_tx_buf_len);
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code);
+
+ return err_code;
+}
+
+uint32_t conn_mw_ble_gap_authenticate(uint8_t const * const p_rx_buf,
+ uint32_t rx_buf_len,
+ uint8_t * const p_tx_buf,
+ uint32_t * const p_tx_buf_len)
+{
+ SER_ASSERT_NOT_NULL(p_rx_buf);
+ SER_ASSERT_NOT_NULL(p_tx_buf);
+ SER_ASSERT_NOT_NULL(p_tx_buf_len);
+
+ uint32_t err_code = NRF_SUCCESS;
+ uint32_t sd_err_code;
+
+ uint16_t conn_handle;
+
+ ble_gap_sec_params_t sec_params;
+ ble_gap_sec_params_t * p_sec_params = &sec_params;
+
+ err_code = ble_gap_authenticate_req_dec(p_rx_buf, rx_buf_len, &conn_handle, &p_sec_params);
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code);
+
+ sd_err_code = sd_ble_gap_authenticate(conn_handle, p_sec_params);
+
+ err_code = ble_gap_authenticate_rsp_enc(sd_err_code, p_tx_buf, p_tx_buf_len);
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code);
+
+ return err_code;
+}
+
+uint32_t conn_mw_ble_gap_sec_params_reply(uint8_t const * const p_rx_buf,
+ uint32_t rx_buf_len,
+ uint8_t * const p_tx_buf,
+ uint32_t * const p_tx_buf_len)
+{
+ SER_ASSERT_NOT_NULL(p_rx_buf);
+ SER_ASSERT_NOT_NULL(p_tx_buf);
+ SER_ASSERT_NOT_NULL(p_tx_buf_len);
+
+ uint32_t err_code = NRF_SUCCESS;
+ uint32_t sd_err_code;
+ uint32_t sec_tab_index = 0;
+
+ uint16_t * p_conn_handle;
+ uint8_t sec_status;
+
+ ble_gap_sec_params_t sec_params;
+ ble_gap_sec_params_t * p_sec_params = &sec_params;
+
+ // Allocate global security context for soft device
+ err_code = conn_ble_gap_sec_context_create(&sec_tab_index);
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code);
+ p_conn_handle = &(m_conn_keys_table[sec_tab_index].conn_handle);
+
+ // Set up global structure for command decoder
+ ble_gap_sec_keyset_t * p_sec_keyset = &(m_conn_keys_table[sec_tab_index].keyset);
+
+ p_sec_keyset->keys_own.p_enc_key = &(m_conn_keys_table[sec_tab_index].enc_key_own);
+ p_sec_keyset->keys_own.p_id_key = &(m_conn_keys_table[sec_tab_index].id_key_own);
+ p_sec_keyset->keys_own.p_sign_key = &(m_conn_keys_table[sec_tab_index].sign_key_own);
+ p_sec_keyset->keys_own.p_pk = &(m_conn_keys_table[sec_tab_index].pk_own);
+ p_sec_keyset->keys_peer.p_enc_key = &(m_conn_keys_table[sec_tab_index].enc_key_peer);
+ p_sec_keyset->keys_peer.p_id_key = &(m_conn_keys_table[sec_tab_index].id_key_peer);
+ p_sec_keyset->keys_peer.p_sign_key = &(m_conn_keys_table[sec_tab_index].sign_key_peer);
+ p_sec_keyset->keys_peer.p_pk = &(m_conn_keys_table[sec_tab_index].pk_peer);
+
+ err_code = ble_gap_sec_params_reply_req_dec(p_rx_buf,
+ rx_buf_len,
+ p_conn_handle,
+ &sec_status,
+ &p_sec_params,
+ &p_sec_keyset);
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code);
+
+ if (p_sec_keyset == NULL)
+ {
+ //If no keyset was sent destroy the context.
+ err_code = conn_ble_gap_sec_context_destroy(*p_conn_handle);
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code);
+ }
+ sd_err_code = sd_ble_gap_sec_params_reply(*p_conn_handle, sec_status, p_sec_params, p_sec_keyset);
+
+ err_code = ble_gap_sec_params_reply_rsp_enc(sd_err_code, p_tx_buf, p_tx_buf_len, p_sec_keyset);
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code);
+
+ return err_code;
+}
+
+uint32_t conn_mw_ble_gap_auth_key_reply(uint8_t const * const p_rx_buf,
+ uint32_t rx_buf_len,
+ uint8_t * const p_tx_buf,
+ uint32_t * const p_tx_buf_len)
+{
+ SER_ASSERT_NOT_NULL(p_rx_buf);
+ SER_ASSERT_NOT_NULL(p_tx_buf);
+ SER_ASSERT_NOT_NULL(p_tx_buf_len);
+
+ uint32_t err_code = NRF_SUCCESS;
+ uint32_t sd_err_code;
+
+ uint16_t conn_handle;
+ uint8_t key_type;
+
+ uint8_t key[BLE_GAP_SEC_KEY_LEN];
+ uint8_t * p_key = key;
+
+ err_code = ble_gap_auth_key_reply_req_dec(p_rx_buf, rx_buf_len, &conn_handle, &key_type, &p_key);
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code);
+
+ sd_err_code = sd_ble_gap_auth_key_reply(conn_handle, key_type, p_key);
+
+ err_code = ble_gap_auth_key_reply_rsp_enc(sd_err_code, p_tx_buf, p_tx_buf_len);
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code);
+
+ return err_code;
+}
+
+uint32_t conn_mw_ble_gap_sec_info_reply(uint8_t const * const p_rx_buf,
+ uint32_t rx_buf_len,
+ uint8_t * const p_tx_buf,
+ uint32_t * const p_tx_buf_len)
+{
+ SER_ASSERT_NOT_NULL(p_rx_buf);
+ SER_ASSERT_NOT_NULL(p_tx_buf);
+ SER_ASSERT_NOT_NULL(p_tx_buf_len);
+
+ uint32_t err_code = NRF_SUCCESS;
+ uint32_t sd_err_code;
+
+ uint16_t conn_handle;
+
+ ble_gap_enc_info_t enc_info;
+ ble_gap_enc_info_t * p_enc_info = &enc_info;
+
+ ble_gap_irk_t id_info;
+ ble_gap_irk_t * p_id_info = &id_info;
+
+ ble_gap_sign_info_t sign_info;
+ ble_gap_sign_info_t * p_sign_info = &sign_info;
+
+ err_code = ble_gap_sec_info_reply_req_dec(p_rx_buf,
+ rx_buf_len,
+ &conn_handle,
+ &p_enc_info,
+ &p_id_info,
+ &p_sign_info);
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code);
+
+ sd_err_code = sd_ble_gap_sec_info_reply(conn_handle, p_enc_info, p_id_info, p_sign_info);
+
+ err_code = ble_gap_sec_info_reply_rsp_enc(sd_err_code, p_tx_buf, p_tx_buf_len);
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code);
+
+ return err_code;
+}
+
+uint32_t conn_mw_ble_gap_conn_sec_get(uint8_t const * const p_rx_buf,
+ uint32_t rx_buf_len,
+ uint8_t * const p_tx_buf,
+ uint32_t * const p_tx_buf_len)
+{
+ SER_ASSERT_NOT_NULL(p_rx_buf);
+ SER_ASSERT_NOT_NULL(p_tx_buf);
+ SER_ASSERT_NOT_NULL(p_tx_buf_len);
+
+ uint32_t err_code = NRF_SUCCESS;
+ uint32_t sd_err_code;
+
+ uint16_t conn_handle;
+
+ ble_gap_conn_sec_t conn_sec;
+ ble_gap_conn_sec_t * p_conn_sec = &conn_sec;
+
+ err_code = ble_gap_conn_sec_get_req_dec(p_rx_buf, rx_buf_len, &conn_handle, &p_conn_sec);
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code);
+
+ sd_err_code = sd_ble_gap_conn_sec_get(conn_handle, p_conn_sec);
+
+ err_code = ble_gap_conn_sec_get_rsp_enc(sd_err_code, p_conn_sec, p_tx_buf, p_tx_buf_len);
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code);
+
+ return err_code;
+}
+
+uint32_t conn_mw_ble_gap_rssi_start(uint8_t const * const p_rx_buf,
+ uint32_t rx_buf_len,
+ uint8_t * const p_tx_buf,
+ uint32_t * const p_tx_buf_len)
+{
+ SER_ASSERT_NOT_NULL(p_rx_buf);
+ SER_ASSERT_NOT_NULL(p_tx_buf);
+ SER_ASSERT_NOT_NULL(p_tx_buf_len);
+
+ uint32_t err_code = NRF_SUCCESS;
+ uint32_t sd_err_code;
+
+ uint16_t conn_handle;
+ uint8_t threshold_dbm;
+ uint8_t skip_count;
+
+ err_code = ble_gap_rssi_start_req_dec(p_rx_buf, rx_buf_len, &conn_handle, &threshold_dbm, &skip_count);
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code);
+
+ sd_err_code = sd_ble_gap_rssi_start(conn_handle, threshold_dbm, skip_count);
+
+ err_code = ble_gap_rssi_start_rsp_enc(sd_err_code, p_tx_buf, p_tx_buf_len);
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code);
+
+ return err_code;
+}
+
+uint32_t conn_mw_ble_gap_rssi_stop(uint8_t const * const p_rx_buf,
+ uint32_t rx_buf_len,
+ uint8_t * const p_tx_buf,
+ uint32_t * const p_tx_buf_len)
+{
+ SER_ASSERT_NOT_NULL(p_rx_buf);
+ SER_ASSERT_NOT_NULL(p_tx_buf);
+ SER_ASSERT_NOT_NULL(p_tx_buf_len);
+
+ uint32_t err_code = NRF_SUCCESS;
+ uint32_t sd_err_code;
+
+ uint16_t conn_handle;
+
+ err_code = ble_gap_rssi_stop_req_dec(p_rx_buf, rx_buf_len, &conn_handle);
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code);
+
+ sd_err_code = sd_ble_gap_rssi_stop(conn_handle);
+
+ err_code = ble_gap_rssi_stop_rsp_enc(sd_err_code, p_tx_buf, p_tx_buf_len);
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code);
+
+ return err_code;
+}
+
+uint32_t conn_mw_ble_gap_rssi_get(uint8_t const * const p_rx_buf,
+ uint32_t rx_buf_len,
+ uint8_t * const p_tx_buf,
+ uint32_t * const p_tx_buf_len)
+{
+ SER_ASSERT_NOT_NULL(p_rx_buf);
+ SER_ASSERT_NOT_NULL(p_tx_buf);
+ SER_ASSERT_NOT_NULL(p_tx_buf_len);
+
+ uint32_t err_code = NRF_SUCCESS;
+ uint32_t sd_err_code;
+ uint16_t conn_handle;
+ int8_t rssi;
+ int8_t * p_rssi = &rssi;
+
+#if NRF_SD_BLE_API_VERSION > 5
+ uint8_t ch_index;
+ uint8_t * p_ch_index = &ch_index;
+
+ err_code = ble_gap_rssi_get_req_dec(p_rx_buf, rx_buf_len, &conn_handle, &p_rssi, &p_ch_index);
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code);
+
+ sd_err_code = sd_ble_gap_rssi_get(conn_handle, p_rssi, p_ch_index);
+
+ err_code = ble_gap_rssi_get_rsp_enc(sd_err_code, p_tx_buf, p_tx_buf_len, p_rssi, p_ch_index);
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code);
+#else
+ err_code = ble_gap_rssi_get_req_dec(p_rx_buf, rx_buf_len, &conn_handle, &p_rssi);
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code);
+
+ sd_err_code = sd_ble_gap_rssi_get(conn_handle, p_rssi);
+
+ err_code = ble_gap_rssi_get_rsp_enc(sd_err_code, p_tx_buf, p_tx_buf_len, p_rssi);
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code);
+#endif
+ return err_code;
+}
+
+uint32_t conn_mw_ble_gap_keypress_notify(uint8_t const * const p_rx_buf,
+ uint32_t rx_buf_len,
+ uint8_t * const p_tx_buf,
+ uint32_t * const p_tx_buf_len)
+{
+ SER_ASSERT_NOT_NULL(p_rx_buf);
+ SER_ASSERT_NOT_NULL(p_tx_buf);
+ SER_ASSERT_NOT_NULL(p_tx_buf_len);
+
+ uint32_t err_code = NRF_SUCCESS;
+ uint32_t sd_err_code;
+
+ uint16_t conn_handle;
+ uint8_t kp_not;
+
+ err_code = ble_gap_keypress_notify_req_dec(p_rx_buf, rx_buf_len, &conn_handle, &kp_not);
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code);
+
+ sd_err_code = sd_ble_gap_keypress_notify(conn_handle, kp_not);
+
+ err_code = ble_gap_keypress_notify_rsp_enc(sd_err_code, p_tx_buf, p_tx_buf_len);
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code);
+
+ return err_code;
+}
+
+uint32_t conn_mw_ble_gap_lesc_dhkey_reply(uint8_t const * const p_rx_buf,
+ uint32_t rx_buf_len,
+ uint8_t * const p_tx_buf,
+ uint32_t * const p_tx_buf_len)
+{
+ SER_ASSERT_NOT_NULL(p_rx_buf);
+ SER_ASSERT_NOT_NULL(p_tx_buf);
+ SER_ASSERT_NOT_NULL(p_tx_buf_len);
+
+ uint32_t err_code = NRF_SUCCESS;
+ uint32_t sd_err_code;
+
+ uint16_t conn_handle;
+ ble_gap_lesc_dhkey_t dhkey;
+ ble_gap_lesc_dhkey_t * p_dhkey = &dhkey;
+
+ err_code = ble_gap_lesc_dhkey_reply_req_dec(p_rx_buf, rx_buf_len, &conn_handle, &p_dhkey);
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code);
+
+ sd_err_code = sd_ble_gap_lesc_dhkey_reply(conn_handle, p_dhkey);
+
+ err_code = ble_gap_lesc_dhkey_reply_rsp_enc(sd_err_code, p_tx_buf, p_tx_buf_len);
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code);
+
+ return err_code;
+}
+
+uint32_t conn_mw_ble_gap_lesc_oob_data_set(uint8_t const * const p_rx_buf,
+ uint32_t rx_buf_len,
+ uint8_t * const p_tx_buf,
+ uint32_t * const p_tx_buf_len)
+{
+ SER_ASSERT_NOT_NULL(p_rx_buf);
+ SER_ASSERT_NOT_NULL(p_tx_buf);
+ SER_ASSERT_NOT_NULL(p_tx_buf_len);
+
+ uint32_t err_code = NRF_SUCCESS;
+ uint32_t sd_err_code;
+
+ uint16_t conn_handle;
+ ble_gap_lesc_oob_data_t own;
+ ble_gap_lesc_oob_data_t peer;
+ ble_gap_lesc_oob_data_t * p_own = &own;
+ ble_gap_lesc_oob_data_t * p_peer = &peer;
+
+ err_code = ble_gap_lesc_oob_data_set_req_dec(p_rx_buf, rx_buf_len, &conn_handle, &p_own, &p_peer);
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code);
+
+ sd_err_code = sd_ble_gap_lesc_oob_data_set(conn_handle, p_own, p_peer);
+
+ err_code = ble_gap_lesc_oob_data_set_rsp_enc(sd_err_code, p_tx_buf, p_tx_buf_len);
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code);
+
+ return err_code;
+}
+
+uint32_t conn_mw_ble_gap_lesc_oob_data_get(uint8_t const * const p_rx_buf,
+ uint32_t rx_buf_len,
+ uint8_t * const p_tx_buf,
+ uint32_t * const p_tx_buf_len)
+{
+ SER_ASSERT_NOT_NULL(p_rx_buf);
+ SER_ASSERT_NOT_NULL(p_tx_buf);
+ SER_ASSERT_NOT_NULL(p_tx_buf_len);
+
+ uint32_t err_code = NRF_SUCCESS;
+ uint32_t sd_err_code;
+
+ uint16_t conn_handle;
+ ble_gap_lesc_oob_data_t own;
+ ble_gap_lesc_oob_data_t * p_own = &own;
+ ble_gap_lesc_p256_pk_t pk;
+ ble_gap_lesc_p256_pk_t * p_pk = &pk;
+
+ err_code = ble_gap_lesc_oob_data_get_req_dec(p_rx_buf, rx_buf_len, &conn_handle, &p_pk, &p_own);
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code);
+ sd_err_code = sd_ble_gap_lesc_oob_data_get(conn_handle, p_pk, p_own);
+
+ err_code = ble_gap_lesc_oob_data_get_rsp_enc(sd_err_code, p_own, p_tx_buf, p_tx_buf_len);
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code);
+
+ return err_code;
+}
+
+uint32_t conn_mw_ble_gap_addr_set(uint8_t const * const p_rx_buf,
+ uint32_t rx_buf_len,
+ uint8_t * const p_tx_buf,
+ uint32_t * const p_tx_buf_len)
+{
+ SER_ASSERT_NOT_NULL(p_rx_buf);
+ SER_ASSERT_NOT_NULL(p_tx_buf);
+ SER_ASSERT_NOT_NULL(p_tx_buf_len);
+
+ ble_gap_addr_t addr;
+ ble_gap_addr_t * p_addr = &addr;
+
+ uint32_t err_code = NRF_SUCCESS;
+ uint32_t sd_err_code;
+
+ err_code = ble_gap_addr_set_req_dec(p_rx_buf, rx_buf_len, &p_addr);
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code);
+
+ sd_err_code = sd_ble_gap_addr_set(p_addr);
+
+ err_code = ble_gap_addr_set_rsp_enc(sd_err_code, p_tx_buf, p_tx_buf_len);
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code);
+
+ return err_code;
+}
+uint32_t conn_mw_ble_gap_addr_get(uint8_t const * const p_rx_buf,
+ uint32_t rx_buf_len,
+ uint8_t * const p_tx_buf,
+ uint32_t * const p_tx_buf_len)
+{
+ SER_ASSERT_NOT_NULL(p_rx_buf);
+ SER_ASSERT_NOT_NULL(p_tx_buf);
+ SER_ASSERT_NOT_NULL(p_tx_buf_len);
+
+ ble_gap_addr_t addr;
+ ble_gap_addr_t * p_addr = &addr;
+
+ uint32_t err_code = NRF_SUCCESS;
+ uint32_t sd_err_code;
+
+ err_code = ble_gap_addr_get_req_dec(p_rx_buf, rx_buf_len, &p_addr);
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code);
+
+ sd_err_code = sd_ble_gap_addr_get(p_addr);
+
+ err_code = ble_gap_addr_get_rsp_enc(sd_err_code, p_tx_buf, p_tx_buf_len, p_addr);
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code);
+
+ return err_code;
+}
+
+uint32_t conn_mw_ble_gap_privacy_set(uint8_t const * const p_rx_buf,
+ uint32_t rx_buf_len,
+ uint8_t * const p_tx_buf,
+ uint32_t * const p_tx_buf_len)
+{
+ SER_ASSERT_NOT_NULL(p_rx_buf);
+ SER_ASSERT_NOT_NULL(p_tx_buf);
+ SER_ASSERT_NOT_NULL(p_tx_buf_len);
+
+ uint32_t err_code = NRF_SUCCESS;
+ uint32_t sd_err_code;
+
+ ble_gap_privacy_params_t privacy_params;
+ ble_gap_privacy_params_t * p_privacy_params = &privacy_params;
+
+ ble_gap_irk_t irk;
+ privacy_params.p_device_irk = &irk;
+
+ err_code = ble_gap_privacy_set_req_dec(p_rx_buf, rx_buf_len, &p_privacy_params);
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code);
+
+ sd_err_code = sd_ble_gap_privacy_set(p_privacy_params);
+
+ err_code = ble_gap_privacy_set_rsp_enc(sd_err_code, p_tx_buf, p_tx_buf_len);
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code);
+
+ return err_code;
+}
+
+
+uint32_t conn_mw_ble_gap_privacy_get(uint8_t const * const p_rx_buf,
+ uint32_t rx_buf_len,
+ uint8_t * const p_tx_buf,
+ uint32_t * const p_tx_buf_len)
+{
+ SER_ASSERT_NOT_NULL(p_rx_buf);
+ SER_ASSERT_NOT_NULL(p_tx_buf);
+ SER_ASSERT_NOT_NULL(p_tx_buf_len);
+
+ uint32_t err_code = NRF_SUCCESS;
+ uint32_t sd_err_code;
+
+ ble_gap_privacy_params_t privacy_params;
+ ble_gap_privacy_params_t * p_privacy_params = &privacy_params;
+
+ ble_gap_irk_t irk;
+ privacy_params.p_device_irk = &irk;
+
+ err_code = ble_gap_privacy_get_req_dec(p_rx_buf, rx_buf_len, &p_privacy_params);
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code);
+
+ sd_err_code = sd_ble_gap_privacy_get(p_privacy_params);
+
+ err_code = ble_gap_privacy_get_rsp_enc(sd_err_code, p_tx_buf, p_tx_buf_len, p_privacy_params);
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code);
+
+ return err_code;
+}
+
+uint32_t conn_mw_ble_gap_whitelist_set(uint8_t const * const p_rx_buf,
+ uint32_t rx_buf_len,
+ uint8_t * const p_tx_buf,
+ uint32_t * const p_tx_buf_len)
+{
+ SER_ASSERT_NOT_NULL(p_rx_buf);
+ SER_ASSERT_NOT_NULL(p_tx_buf);
+ SER_ASSERT_NOT_NULL(p_tx_buf_len);
+
+ uint32_t err_code = NRF_SUCCESS;
+ uint32_t sd_err_code;
+
+ uint8_t length;
+ ble_gap_addr_t wl_addr_array[BLE_GAP_WHITELIST_ADDR_MAX_COUNT];
+ ble_gap_addr_t * p_wl_addrs_array[BLE_GAP_WHITELIST_ADDR_MAX_COUNT];
+
+ for (uint8_t i = 0; i < BLE_GAP_WHITELIST_ADDR_MAX_COUNT; ++i)
+ {
+ p_wl_addrs_array[i] = &wl_addr_array[i];
+ }
+
+ ble_gap_addr_t * * pp_wl_addrs = p_wl_addrs_array;
+
+ err_code = ble_gap_whitelist_set_req_dec(p_rx_buf, rx_buf_len, &pp_wl_addrs, &length);
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code);
+ sd_err_code = sd_ble_gap_whitelist_set((ble_gap_addr_t const * *)pp_wl_addrs, length);
+
+ err_code = ble_gap_whitelist_set_rsp_enc(sd_err_code, p_tx_buf, p_tx_buf_len);
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code);
+
+ return err_code;
+}
+
+uint32_t conn_mw_ble_gap_device_identities_set(uint8_t const * const p_rx_buf,
+ uint32_t rx_buf_len,
+ uint8_t * const p_tx_buf,
+ uint32_t * const p_tx_buf_len)
+{
+ SER_ASSERT_NOT_NULL(p_rx_buf);
+ SER_ASSERT_NOT_NULL(p_tx_buf);
+ SER_ASSERT_NOT_NULL(p_tx_buf_len);
+
+ uint32_t err_code = NRF_SUCCESS;
+ uint32_t sd_err_code;
+
+ uint8_t length;
+ ble_gap_id_key_t id_key_array[BLE_GAP_DEVICE_IDENTITIES_MAX_COUNT];
+ ble_gap_id_key_t * p_id_key_array[BLE_GAP_DEVICE_IDENTITIES_MAX_COUNT];
+ ble_gap_irk_t irk_array[BLE_GAP_DEVICE_IDENTITIES_MAX_COUNT];
+ ble_gap_irk_t * p_irk_array[BLE_GAP_DEVICE_IDENTITIES_MAX_COUNT];
+
+ for (uint8_t i = 0; i < BLE_GAP_DEVICE_IDENTITIES_MAX_COUNT; ++i)
+ {
+ p_id_key_array[i] = &id_key_array[i];
+ p_irk_array[i] = &irk_array[i];
+ }
+
+ ble_gap_id_key_t * * pp_id_keys = p_id_key_array;
+ ble_gap_irk_t * * pp_local_irks = p_irk_array;
+
+ err_code = ble_gap_device_identities_set_req_dec(p_rx_buf, rx_buf_len,
+ &pp_id_keys,
+ &pp_local_irks,
+ &length);
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code);
+
+ sd_err_code = sd_ble_gap_device_identities_set((ble_gap_id_key_t const * *) pp_id_keys,
+ (ble_gap_irk_t const * *) pp_local_irks,
+ length);
+
+ err_code = ble_gap_device_identities_set_rsp_enc(sd_err_code, p_tx_buf, p_tx_buf_len);
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code);
+
+ return err_code;
+}
+
+#if NRF_SD_BLE_API_VERSION >= 5
+uint32_t conn_mw_ble_gap_phy_update(uint8_t const * const p_rx_buf,
+ uint32_t rx_buf_len,
+ uint8_t * const p_tx_buf,
+ uint32_t * const p_tx_buf_len)
+{
+ SER_ASSERT_NOT_NULL(p_rx_buf);
+ SER_ASSERT_NOT_NULL(p_tx_buf);
+ SER_ASSERT_NOT_NULL(p_tx_buf_len);
+
+ uint32_t err_code = NRF_SUCCESS;
+ uint32_t sd_err_code;
+
+ uint16_t conn_handle;
+
+ ble_gap_phys_t gap_phys;
+ ble_gap_phys_t * p_gap_phys = &gap_phys;
+
+ err_code = ble_gap_phy_update_req_dec(p_rx_buf, rx_buf_len, &conn_handle, &p_gap_phys);
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code);
+
+ sd_err_code = sd_ble_gap_phy_update(conn_handle, p_gap_phys);
+
+ err_code = ble_gap_phy_update_rsp_enc(sd_err_code, p_tx_buf, p_tx_buf_len);
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code);
+
+ return err_code;
+}
+#endif
+
+#if NRF_SD_BLE_API_VERSION >= 4 && !defined(S112)
+uint32_t conn_mw_ble_gap_data_length_update(uint8_t const * const p_rx_buf,
+ uint32_t rx_buf_len,
+ uint8_t * const p_tx_buf,
+ uint32_t * const p_tx_buf_len)
+{
+ SER_ASSERT_NOT_NULL(p_rx_buf);
+ SER_ASSERT_NOT_NULL(p_tx_buf);
+ SER_ASSERT_NOT_NULL(p_tx_buf_len);
+
+ uint32_t err_code = NRF_SUCCESS;
+ uint32_t sd_err_code;
+
+ uint16_t conn_handle;
+ ble_gap_data_length_params_t dl_params;
+ ble_gap_data_length_params_t * p_dl_params = &dl_params;
+ ble_gap_data_length_limitation_t dl_limitation;
+ ble_gap_data_length_limitation_t * p_dl_limitation = &dl_limitation;
+
+ err_code = ble_gap_data_length_update_req_dec(p_rx_buf, rx_buf_len, &conn_handle, &p_dl_params, &p_dl_limitation);
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code);
+
+ sd_err_code = sd_ble_gap_data_length_update(conn_handle, p_dl_params,p_dl_limitation );
+
+ err_code = ble_gap_data_length_update_rsp_enc(sd_err_code, p_tx_buf, p_tx_buf_len, p_dl_limitation);
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code);
+
+ return err_code;
+}
+#endif //NRF_SD_BLE_API_VERSION >= 4 && !defined(S112)
+
+#if NRF_SD_BLE_API_VERSION > 5
+uint32_t conn_mw_ble_gap_adv_set_configure(uint8_t const * const p_rx_buf,
+ uint32_t rx_buf_len,
+ uint8_t * const p_tx_buf,
+ uint32_t * const p_tx_buf_len)
+{
+ SER_ASSERT_NOT_NULL(p_rx_buf);
+ SER_ASSERT_NOT_NULL(p_tx_buf);
+ SER_ASSERT_NOT_NULL(p_tx_buf_len);
+
+ uint32_t err_code = NRF_SUCCESS;
+ uint32_t sd_err_code;
+
+ uint8_t adv_handle;
+ uint8_t * p_adv_handle = &adv_handle;
+ ble_gap_adv_data_t adv_data;
+ ble_gap_adv_data_t * p_adv_data = &adv_data;
+ adv_data.adv_data.len = SER_MAX_ADV_DATA;
+ adv_data.adv_data.p_data = NULL;
+ adv_data.scan_rsp_data.len = SER_MAX_ADV_DATA;
+ adv_data.scan_rsp_data.p_data = NULL;
+ ble_gap_addr_t addr;
+ ble_gap_adv_params_t adv_params;
+ adv_params.p_peer_addr = &addr;
+ ble_gap_adv_params_t * p_adv_params = &adv_params;
+
+
+ err_code = ble_gap_adv_set_configure_req_dec(p_rx_buf, rx_buf_len, &p_adv_handle, &p_adv_data, &p_adv_params);
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code);
+
+ sd_err_code = sd_ble_gap_adv_set_configure(p_adv_handle, p_adv_data, p_adv_params);
+
+ err_code = ble_gap_adv_set_configure_rsp_enc(sd_err_code, p_tx_buf, p_tx_buf_len, p_adv_handle);
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code);
+
+ return err_code;
+}
+
+#ifndef S112
+uint32_t conn_mw_ble_gap_qos_channel_survey_start(uint8_t const * const p_rx_buf,
+ uint32_t rx_buf_len,
+ uint8_t * const p_tx_buf,
+ uint32_t * const p_tx_buf_len)
+{
+ SER_ASSERT_NOT_NULL(p_rx_buf);
+ SER_ASSERT_NOT_NULL(p_tx_buf);
+ SER_ASSERT_NOT_NULL(p_tx_buf_len);
+
+ uint32_t err_code = NRF_SUCCESS;
+ uint32_t sd_err_code;
+
+ uint32_t interval_us;
+
+ err_code = ble_gap_qos_channel_survey_start_req_dec(p_rx_buf, rx_buf_len, &interval_us);
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code);
+
+ sd_err_code = sd_ble_gap_qos_channel_survey_start(interval_us);
+
+ err_code = ble_gap_qos_channel_survey_start_rsp_enc(sd_err_code, p_tx_buf, p_tx_buf_len);
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code);
+
+ return err_code;
+}
+
+uint32_t conn_mw_ble_gap_qos_channel_survey_stop(uint8_t const * const p_rx_buf,
+ uint32_t rx_buf_len,
+ uint8_t * const p_tx_buf,
+ uint32_t * const p_tx_buf_len)
+{
+ SER_ASSERT_NOT_NULL(p_rx_buf);
+ SER_ASSERT_NOT_NULL(p_tx_buf);
+ SER_ASSERT_NOT_NULL(p_tx_buf_len);
+
+ uint32_t err_code = NRF_SUCCESS;
+ uint32_t sd_err_code;
+
+ err_code = ble_gap_qos_channel_survey_stop_req_dec(p_rx_buf, rx_buf_len);
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code);
+
+ sd_err_code = sd_ble_gap_qos_channel_survey_stop();
+
+ err_code = ble_gap_qos_channel_survey_stop_rsp_enc(sd_err_code, p_tx_buf, p_tx_buf_len);
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code);
+
+ return err_code;
+}
+#endif //!S112
+#endif
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/connectivity/codecs/ble/middleware/conn_mw_ble_gap.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/connectivity/codecs/ble/middleware/conn_mw_ble_gap.h
new file mode 100644
index 0000000..0dcb602
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/connectivity/codecs/ble/middleware/conn_mw_ble_gap.h
@@ -0,0 +1,820 @@
+/**
+ * Copyright (c) 2014 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#ifndef _CONN_MW_BLE_GAP_H
+#define _CONN_MW_BLE_GAP_H
+
+#include <stdint.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @addtogroup sercon_mw_s132_ble_gap GAP Middleware command handlers
+ * @{
+ * @ingroup sercon_mw_s132
+ */
+
+#if defined(NRF_SD_BLE_API_VERSION) && (NRF_SD_BLE_API_VERSION <= 5)
+/**@brief Handles @ref sd_ble_gap_adv_data_set command and prepares response.
+ *
+ * @param[in] p_rx_buf Pointer to input buffer.
+ * @param[in] rx_buf_len Size of @p p_rx_buf.
+ * @param[out] p_tx_buf Pointer to output buffer.
+ * @param[in,out] p_tx_buf_len \c in: Size of \p p_tx_buf buffer.
+ * \c out: Length of valid data in \p p_tx_buf.
+ *
+ * @retval NRF_SUCCESS Handler success.
+ * @retval NRF_ERROR_NULL Handler failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Handler failure. Incorrect buffer length.
+ * @retval NRF_ERROR_INVALID_PARAM Handler failure. Invalid operation type.
+ */
+uint32_t conn_mw_ble_gap_adv_data_set(uint8_t const * const p_rx_buf,
+ uint32_t rx_buf_len,
+ uint8_t * const p_tx_buf,
+ uint32_t * const p_tx_buf_len);
+#endif
+
+/**@brief Handles @ref sd_ble_gap_adv_start command and prepares response.
+ *
+ * @param[in] p_rx_buf Pointer to input buffer.
+ * @param[in] rx_buf_len Size of @p p_rx_buf.
+ * @param[out] p_tx_buf Pointer to output buffer.
+ * @param[in,out] p_tx_buf_len \c in: Size of \p p_tx_buf buffer.
+ * \c out: Length of valid data in \p p_tx_buf.
+ *
+ * @retval NRF_SUCCESS Handler success.
+ * @retval NRF_ERROR_NULL Handler failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Handler failure. Incorrect buffer length.
+ * @retval NRF_ERROR_INVALID_PARAM Handler failure. Invalid operation type.
+ */
+uint32_t conn_mw_ble_gap_adv_start(uint8_t const * const p_rx_buf,
+ uint32_t rx_buf_len,
+ uint8_t * const p_tx_buf,
+ uint32_t * const p_tx_buf_len);
+
+/**@brief Handles @ref sd_ble_gap_adv_stop command and prepares response.
+ *
+ * @param[in] p_rx_buf Pointer to input buffer.
+ * @param[in] rx_buf_len Size of @p p_rx_buf.
+ * @param[out] p_tx_buf Pointer to output buffer.
+ * @param[in,out] p_tx_buf_len \c in: Size of \p p_tx_buf buffer.
+ * \c out: Length of valid data in \p p_tx_buf.
+ *
+ * @retval NRF_SUCCESS Handler success.
+ * @retval NRF_ERROR_NULL Handler failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Handler failure. Incorrect buffer length.
+ * @retval NRF_ERROR_INVALID_PARAM Handler failure. Invalid operation type.
+ */
+uint32_t conn_mw_ble_gap_adv_stop(uint8_t const * const p_rx_buf,
+ uint32_t rx_buf_len,
+ uint8_t * const p_tx_buf,
+ uint32_t * const p_tx_buf_len);
+
+/**@brief Handles @ref sd_ble_gap_conn_param_update command and prepares response.
+ *
+ * @param[in] p_rx_buf Pointer to input buffer.
+ * @param[in] rx_buf_len Size of @p p_rx_buf.
+ * @param[out] p_tx_buf Pointer to output buffer.
+ * @param[in,out] p_tx_buf_len \c in: Size of \p p_tx_buf buffer.
+ * \c out: Length of valid data in \p p_tx_buf.
+ *
+ * @retval NRF_SUCCESS Handler success.
+ * @retval NRF_ERROR_NULL Handler failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Handler failure. Incorrect buffer length.
+ * @retval NRF_ERROR_INVALID_PARAM Handler failure. Invalid operation type.
+ */
+uint32_t conn_mw_ble_gap_conn_param_update(uint8_t const * const p_rx_buf,
+ uint32_t rx_buf_len,
+ uint8_t * const p_tx_buf,
+ uint32_t * const p_tx_buf_len);
+
+/**@brief Handles @ref sd_ble_gap_disconnect command and prepares response.
+ *
+ * @param[in] p_rx_buf Pointer to input buffer.
+ * @param[in] rx_buf_len Size of @p p_rx_buf.
+ * @param[out] p_tx_buf Pointer to output buffer.
+ * @param[in,out] p_tx_buf_len \c in: Size of \p p_tx_buf buffer.
+ * \c out: Length of valid data in \p p_tx_buf.
+ *
+ * @retval NRF_SUCCESS Handler success.
+ * @retval NRF_ERROR_NULL Handler failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Handler failure. Incorrect buffer length.
+ * @retval NRF_ERROR_INVALID_PARAM Handler failure. Invalid operation type.
+ */
+uint32_t conn_mw_ble_gap_disconnect(uint8_t const * const p_rx_buf,
+ uint32_t rx_buf_len,
+ uint8_t * const p_tx_buf,
+ uint32_t * const p_tx_buf_len);
+
+/**@brief Handles @ref sd_ble_gap_tx_power_set command and prepares response.
+ *
+ * @param[in] p_rx_buf Pointer to input buffer.
+ * @param[in] rx_buf_len Size of @p p_rx_buf.
+ * @param[out] p_tx_buf Pointer to output buffer.
+ * @param[in,out] p_tx_buf_len \c in: Size of \p p_tx_buf buffer.
+ * \c out: Length of valid data in \p p_tx_buf.
+ *
+ * @retval NRF_SUCCESS Handler success.
+ * @retval NRF_ERROR_NULL Handler failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Handler failure. Incorrect buffer length.
+ * @retval NRF_ERROR_INVALID_PARAM Handler failure. Invalid operation type.
+ */
+uint32_t conn_mw_ble_gap_tx_power_set(uint8_t const * const p_rx_buf,
+ uint32_t rx_buf_len,
+ uint8_t * const p_tx_buf,
+ uint32_t * const p_tx_buf_len);
+
+/**@brief Handles @ref sd_ble_gap_appearance_set command and prepares response.
+ *
+ * @param[in] p_rx_buf Pointer to input buffer.
+ * @param[in] rx_buf_len Size of @p p_rx_buf.
+ * @param[out] p_tx_buf Pointer to output buffer.
+ * @param[in,out] p_tx_buf_len \c in: Size of \p p_tx_buf buffer.
+ * \c out: Length of valid data in \p p_tx_buf.
+ *
+ * @retval NRF_SUCCESS Handler success.
+ * @retval NRF_ERROR_NULL Handler failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Handler failure. Incorrect buffer length.
+ * @retval NRF_ERROR_INVALID_PARAM Handler failure. Invalid operation type.
+ */
+uint32_t conn_mw_ble_gap_appearance_set(uint8_t const * const p_rx_buf,
+ uint32_t rx_buf_len,
+ uint8_t * const p_tx_buf,
+ uint32_t * const p_tx_buf_len);
+
+/**@brief Handles @ref sd_ble_gap_appearance_get command and prepares response.
+ *
+ * @param[in] p_rx_buf Pointer to input buffer.
+ * @param[in] rx_buf_len Size of @p p_rx_buf.
+ * @param[out] p_tx_buf Pointer to output buffer.
+ * @param[in,out] p_tx_buf_len \c in: Size of \p p_tx_buf buffer.
+ * \c out: Length of valid data in \p p_tx_buf.
+ *
+ * @retval NRF_SUCCESS Handler success.
+ * @retval NRF_ERROR_NULL Handler failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Handler failure. Incorrect buffer length.
+ * @retval NRF_ERROR_INVALID_PARAM Handler failure. Invalid operation type.
+ */
+uint32_t conn_mw_ble_gap_appearance_get(uint8_t const * const p_rx_buf,
+ uint32_t rx_buf_len,
+ uint8_t * const p_tx_buf,
+ uint32_t * const p_tx_buf_len);
+
+/**@brief Handles @ref sd_ble_gap_ppcp_set command and prepares response.
+ *
+ * @param[in] p_rx_buf Pointer to input buffer.
+ * @param[in] rx_buf_len Size of @p p_rx_buf.
+ * @param[out] p_tx_buf Pointer to output buffer.
+ * @param[in,out] p_tx_buf_len \c in: Size of \p p_tx_buf buffer.
+ * \c out: Length of valid data in \p p_tx_buf.
+ *
+ * @retval NRF_SUCCESS Handler success.
+ * @retval NRF_ERROR_NULL Handler failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Handler failure. Incorrect buffer length.
+ * @retval NRF_ERROR_INVALID_PARAM Handler failure. Invalid operation type.
+ */
+uint32_t conn_mw_ble_gap_ppcp_set(uint8_t const * const p_rx_buf,
+ uint32_t rx_buf_len,
+ uint8_t * const p_tx_buf,
+ uint32_t * const p_tx_buf_len);
+
+/**@brief Handles @ref sd_ble_gap_ppcp_get command and prepares response.
+ *
+ * @param[in] p_rx_buf Pointer to input buffer.
+ * @param[in] rx_buf_len Size of @p p_rx_buf.
+ * @param[out] p_tx_buf Pointer to output buffer.
+ * @param[in,out] p_tx_buf_len \c in: Size of \p p_tx_buf buffer.
+ * \c out: Length of valid data in \p p_tx_buf.
+ *
+ * @retval NRF_SUCCESS Handler success.
+ * @retval NRF_ERROR_NULL Handler failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Handler failure. Incorrect buffer length.
+ * @retval NRF_ERROR_INVALID_PARAM Handler failure. Invalid operation type.
+ */
+uint32_t conn_mw_ble_gap_ppcp_get(uint8_t const * const p_rx_buf,
+ uint32_t rx_buf_len,
+ uint8_t * const p_tx_buf,
+ uint32_t * const p_tx_buf_len);
+
+/**@brief Handles @ref sd_ble_gap_device_name_get command and prepares response.
+ *
+ * @param[in] p_rx_buf Pointer to input buffer.
+ * @param[in] rx_buf_len Size of @p p_rx_buf.
+ * @param[out] p_tx_buf Pointer to output buffer.
+ * @param[in,out] p_tx_buf_len \c in: Size of \p p_tx_buf buffer.
+ * \c out: Length of valid data in \p p_tx_buf.
+ *
+ * @retval NRF_SUCCESS Handler success.
+ * @retval NRF_ERROR_NULL Handler failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Handler failure. Incorrect buffer length.
+ * @retval NRF_ERROR_INVALID_PARAM Handler failure. Invalid operation type.
+ */
+uint32_t conn_mw_ble_gap_device_name_get(uint8_t const * const p_rx_buf,
+ uint32_t rx_buf_len,
+ uint8_t * const p_tx_buf,
+ uint32_t * const p_tx_buf_len);
+
+/**@brief Handles @ref sd_ble_gap_device_name_set command and prepares response.
+ *
+ * @param[in] p_rx_buf Pointer to input buffer.
+ * @param[in] rx_buf_len Size of @p p_rx_buf.
+ * @param[out] p_tx_buf Pointer to output buffer.
+ * @param[in,out] p_tx_buf_len \c in: Size of \p p_tx_buf buffer.
+ * \c out: Length of valid data in \p p_tx_buf.
+ *
+ * @retval NRF_SUCCESS Handler success.
+ * @retval NRF_ERROR_NULL Handler failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Handler failure. Incorrect buffer length.
+ * @retval NRF_ERROR_INVALID_PARAM Handler failure. Invalid operation type.
+ */
+uint32_t conn_mw_ble_gap_device_name_set(uint8_t const * const p_rx_buf,
+ uint32_t rx_buf_len,
+ uint8_t * const p_tx_buf,
+ uint32_t * const p_tx_buf_len);
+
+/**@brief Handles @ref sd_ble_gap_authenticate command and prepares response.
+ *
+ * @param[in] p_rx_buf Pointer to input buffer.
+ * @param[in] rx_buf_len Size of @p p_rx_buf.
+ * @param[out] p_tx_buf Pointer to output buffer.
+ * @param[in,out] p_tx_buf_len \c in: Size of \p p_tx_buf buffer.
+ * \c out: Length of valid data in \p p_tx_buf.
+ *
+ * @retval NRF_SUCCESS Handler success.
+ * @retval NRF_ERROR_NULL Handler failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Handler failure. Incorrect buffer length.
+ * @retval NRF_ERROR_INVALID_PARAM Handler failure. Invalid operation type.
+ */
+uint32_t conn_mw_ble_gap_authenticate(uint8_t const * const p_rx_buf,
+ uint32_t rx_buf_len,
+ uint8_t * const p_tx_buf,
+ uint32_t * const p_tx_buf_len);
+
+/**@brief Handles @ref sd_ble_gap_sec_params_reply command and prepares response.
+ *
+ * @param[in] p_rx_buf Pointer to input buffer.
+ * @param[in] rx_buf_len Size of @p p_rx_buf.
+ * @param[out] p_tx_buf Pointer to output buffer.
+ * @param[in,out] p_tx_buf_len \c in: Size of \p p_tx_buf buffer.
+ * \c out: Length of valid data in \p p_tx_buf.
+ *
+ * @retval NRF_SUCCESS Handler success.
+ * @retval NRF_ERROR_NULL Handler failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Handler failure. Incorrect buffer length.
+ * @retval NRF_ERROR_INVALID_PARAM Handler failure. Invalid operation type.
+ */
+uint32_t conn_mw_ble_gap_sec_params_reply(uint8_t const * const p_rx_buf,
+ uint32_t rx_buf_len,
+ uint8_t * const p_tx_buf,
+ uint32_t * const p_tx_buf_len);
+
+/**@brief Handles @ref sd_ble_gap_auth_key_reply command and prepares response.
+ *
+ * @param[in] p_rx_buf Pointer to input buffer.
+ * @param[in] rx_buf_len Size of @p p_rx_buf.
+ * @param[out] p_tx_buf Pointer to output buffer.
+ * @param[in,out] p_tx_buf_len \c in: Size of \p p_tx_buf buffer.
+ * \c out: Length of valid data in \p p_tx_buf.
+ *
+ * @retval NRF_SUCCESS Handler success.
+ * @retval NRF_ERROR_NULL Handler failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Handler failure. Incorrect buffer length.
+ * @retval NRF_ERROR_INVALID_PARAM Handler failure. Invalid operation type.
+ */
+uint32_t conn_mw_ble_gap_auth_key_reply(uint8_t const * const p_rx_buf,
+ uint32_t rx_buf_len,
+ uint8_t * const p_tx_buf,
+ uint32_t * const p_tx_buf_len);
+
+/**@brief Handles @ref sd_ble_gap_sec_info_reply command and prepares response.
+ *
+ * @param[in] p_rx_buf Pointer to input buffer.
+ * @param[in] rx_buf_len Size of @p p_rx_buf.
+ * @param[out] p_tx_buf Pointer to output buffer.
+ * @param[in,out] p_tx_buf_len \c in: Size of \p p_tx_buf buffer.
+ * \c out: Length of valid data in \p p_tx_buf.
+ *
+ * @retval NRF_SUCCESS Handler success.
+ * @retval NRF_ERROR_NULL Handler failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Handler failure. Incorrect buffer length.
+ * @retval NRF_ERROR_INVALID_PARAM Handler failure. Invalid operation type.
+ */
+uint32_t conn_mw_ble_gap_sec_info_reply(uint8_t const * const p_rx_buf,
+ uint32_t rx_buf_len,
+ uint8_t * const p_tx_buf,
+ uint32_t * const p_tx_buf_len);
+
+/**@brief Handles @ref sd_ble_gap_conn_sec_get command and prepares response.
+ *
+ * @param[in] p_rx_buf Pointer to input buffer.
+ * @param[in] rx_buf_len Size of @p p_rx_buf.
+ * @param[out] p_tx_buf Pointer to output buffer.
+ * @param[in,out] p_tx_buf_len \c in: Size of \p p_tx_buf buffer.
+ * \c out: Length of valid data in \p p_tx_buf.
+ *
+ * @retval NRF_SUCCESS Handler success.
+ * @retval NRF_ERROR_NULL Handler failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Handler failure. Incorrect buffer length.
+ * @retval NRF_ERROR_INVALID_PARAM Handler failure. Invalid operation type.
+ */
+uint32_t conn_mw_ble_gap_conn_sec_get(uint8_t const * const p_rx_buf,
+ uint32_t rx_buf_len,
+ uint8_t * const p_tx_buf,
+ uint32_t * const p_tx_buf_len);
+
+/**@brief Handles @ref sd_ble_gap_rssi_start command and prepares response.
+ *
+ * @param[in] p_rx_buf Pointer to input buffer.
+ * @param[in] rx_buf_len Size of @p p_rx_buf.
+ * @param[out] p_tx_buf Pointer to output buffer.
+ * @param[in,out] p_tx_buf_len \c in: Size of \p p_tx_buf buffer.
+ * \c out: Length of valid data in \p p_tx_buf.
+ *
+ * @retval NRF_SUCCESS Handler success.
+ * @retval NRF_ERROR_NULL Handler failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Handler failure. Incorrect buffer length.
+ * @retval NRF_ERROR_INVALID_PARAM Handler failure. Invalid operation type.
+ */
+uint32_t conn_mw_ble_gap_rssi_start(uint8_t const * const p_rx_buf,
+ uint32_t rx_buf_len,
+ uint8_t * const p_tx_buf,
+ uint32_t * const p_tx_buf_len);
+
+/**@brief Handles @ref sd_ble_gap_rssi_stop command and prepares response.
+ *
+ * @param[in] p_rx_buf Pointer to input buffer.
+ * @param[in] rx_buf_len Size of @p p_rx_buf.
+ * @param[out] p_tx_buf Pointer to output buffer.
+ * @param[in,out] p_tx_buf_len \c in: Size of \p p_tx_buf buffer.
+ * \c out: Length of valid data in \p p_tx_buf.
+ *
+ * @retval NRF_SUCCESS Handler success.
+ * @retval NRF_ERROR_NULL Handler failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Handler failure. Incorrect buffer length.
+ * @retval NRF_ERROR_INVALID_PARAM Handler failure. Invalid operation type.
+ */
+uint32_t conn_mw_ble_gap_rssi_stop(uint8_t const * const p_rx_buf,
+ uint32_t rx_buf_len,
+ uint8_t * const p_tx_buf,
+ uint32_t * const p_tx_buf_len);
+
+/**@brief Handles @ref sd_ble_gap_rssi_get command and prepares response.
+ *
+ * @param[in] p_rx_buf Pointer to input buffer.
+ * @param[in] rx_buf_len Size of @p p_rx_buf.
+ * @param[out] p_tx_buf Pointer to output buffer.
+ * @param[in,out] p_tx_buf_len \c in: Size of \p p_tx_buf buffer.
+ * \c out: Length of valid data in \p p_tx_buf.
+ *
+ * @retval NRF_SUCCESS Handler success.
+ * @retval NRF_ERROR_NULL Handler failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Handler failure. Incorrect buffer length.
+ * @retval NRF_ERROR_INVALID_PARAM Handler failure. Invalid operation type.
+ */
+uint32_t conn_mw_ble_gap_rssi_get(uint8_t const * const p_rx_buf,
+ uint32_t rx_buf_len,
+ uint8_t * const p_tx_buf,
+ uint32_t * const p_tx_buf_len);
+
+/**@brief Handles @ref sd_ble_gap_connect command and prepares response.
+ *
+ * @param[in] p_rx_buf Pointer to input buffer.
+ * @param[in] rx_buf_len Size of @p p_rx_buf.
+ * @param[out] p_tx_buf Pointer to output buffer.
+ * @param[in,out] p_tx_buf_len \c in: Size of \p p_tx_buf buffer.
+ * \c out: Length of valid data in \p p_tx_buf.
+ *
+ * @retval NRF_SUCCESS Handler success.
+ * @retval NRF_ERROR_NULL Handler failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Handler failure. Incorrect buffer length.
+ * @retval NRF_ERROR_INVALID_PARAM Handler failure. Invalid operation type.
+ */
+uint32_t conn_mw_ble_gap_connect(uint8_t const * const p_rx_buf,
+ uint32_t rx_buf_len,
+ uint8_t * const p_tx_buf,
+ uint32_t * const p_tx_buf_len);
+
+/**@brief Handles @ref sd_ble_gap_connect_cancel command and prepares response.
+ *
+ * @param[in] p_rx_buf Pointer to input buffer.
+ * @param[in] rx_buf_len Size of @p p_rx_buf.
+ * @param[out] p_tx_buf Pointer to output buffer.
+ * @param[in,out] p_tx_buf_len \c in: Size of \p p_tx_buf buffer.
+ * \c out: Length of valid data in \p p_tx_buf.
+ *
+ * @retval NRF_SUCCESS Handler success.
+ * @retval NRF_ERROR_NULL Handler failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Handler failure. Incorrect buffer length.
+ * @retval NRF_ERROR_INVALID_PARAM Handler failure. Invalid operation type.
+ */
+uint32_t conn_mw_ble_gap_connect_cancel(uint8_t const * const p_rx_buf,
+ uint32_t rx_buf_len,
+ uint8_t * const p_tx_buf,
+ uint32_t * const p_tx_buf_len);
+
+/**@brief Handles @ref sd_ble_gap_scan_start command and prepares response.
+ *
+ * @param[in] p_rx_buf Pointer to input buffer.
+ * @param[in] rx_buf_len Size of @p p_rx_buf.
+ * @param[out] p_tx_buf Pointer to output buffer.
+ * @param[in,out] p_tx_buf_len \c in: Size of \p p_tx_buf buffer.
+ * \c out: Length of valid data in \p p_tx_buf.
+ *
+ * @retval NRF_SUCCESS Handler success.
+ * @retval NRF_ERROR_NULL Handler failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Handler failure. Incorrect buffer length.
+ * @retval NRF_ERROR_INVALID_PARAM Handler failure. Invalid operation type.
+ */
+uint32_t conn_mw_ble_gap_scan_start(uint8_t const * const p_rx_buf,
+ uint32_t rx_buf_len,
+ uint8_t * const p_tx_buf,
+ uint32_t * const p_tx_buf_len);
+
+/**@brief Handles @ref sd_ble_gap_scan_stop command and prepares response.
+ *
+ * @param[in] p_rx_buf Pointer to input buffer.
+ * @param[in] rx_buf_len Size of @p p_rx_buf.
+ * @param[out] p_tx_buf Pointer to output buffer.
+ * @param[in,out] p_tx_buf_len \c in: Size of \p p_tx_buf buffer.
+ * \c out: Length of valid data in \p p_tx_buf.
+ *
+ * @retval NRF_SUCCESS Handler success.
+ * @retval NRF_ERROR_NULL Handler failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Handler failure. Incorrect buffer length.
+ * @retval NRF_ERROR_INVALID_PARAM Handler failure. Invalid operation type.
+ */
+uint32_t conn_mw_ble_gap_scan_stop(uint8_t const * const p_rx_buf,
+ uint32_t rx_buf_len,
+ uint8_t * const p_tx_buf,
+ uint32_t * const p_tx_buf_len);
+
+/**@brief Handles @ref sd_ble_gap_encrypt command and prepares response.
+ *
+ * @param[in] p_rx_buf Pointer to input buffer.
+ * @param[in] rx_buf_len Size of @p p_rx_buf.
+ * @param[out] p_tx_buf Pointer to output buffer.
+ * @param[in,out] p_tx_buf_len \c in: Size of \p p_tx_buf buffer.
+ * \c out: Length of valid data in \p p_tx_buf.
+ *
+ * @retval NRF_SUCCESS Handler success.
+ * @retval NRF_ERROR_NULL Handler failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Handler failure. Incorrect buffer length.
+ * @retval NRF_ERROR_INVALID_PARAM Handler failure. Invalid operation type.
+ */
+
+uint32_t conn_mw_ble_gap_encrypt(uint8_t const * const p_rx_buf,
+ uint32_t rx_buf_len,
+ uint8_t * const p_tx_buf,
+ uint32_t * const p_tx_buf_len);
+
+/**@brief Handles @ref sd_ble_gap_keypress_notify command and prepares response.
+ *
+ * @param[in] p_rx_buf Pointer to input buffer.
+ * @param[in] rx_buf_len Size of @p p_rx_buf.
+ * @param[out] p_tx_buf Pointer to output buffer.
+ * @param[in,out] p_tx_buf_len \c in: Size of \p p_tx_buf buffer.
+ * \c out: Length of valid data in \p p_tx_buf.
+ *
+ * @retval NRF_SUCCESS Handler success.
+ * @retval NRF_ERROR_NULL Handler failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Handler failure. Incorrect buffer length.
+ * @retval NRF_ERROR_INVALID_PARAM Handler failure. Invalid operation type.
+ */
+
+uint32_t conn_mw_ble_gap_keypress_notify(uint8_t const * const p_rx_buf,
+ uint32_t rx_buf_len,
+ uint8_t * const p_tx_buf,
+ uint32_t * const p_tx_buf_len);
+
+/**@brief Handles @ref sd_ble_gap_lesc_dhkey_reply command and prepares response.
+ *
+ * @param[in] p_rx_buf Pointer to input buffer.
+ * @param[in] rx_buf_len Size of @p p_rx_buf.
+ * @param[out] p_tx_buf Pointer to output buffer.
+ * @param[in,out] p_tx_buf_len \c in: Size of \p p_tx_buf buffer.
+ * \c out: Length of valid data in \p p_tx_buf.
+ *
+ * @retval NRF_SUCCESS Handler success.
+ * @retval NRF_ERROR_NULL Handler failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Handler failure. Incorrect buffer length.
+ * @retval NRF_ERROR_INVALID_PARAM Handler failure. Invalid operation type.
+ */
+
+uint32_t conn_mw_ble_gap_lesc_dhkey_reply(uint8_t const * const p_rx_buf,
+ uint32_t rx_buf_len,
+ uint8_t * const p_tx_buf,
+ uint32_t * const p_tx_buf_len);
+
+/**@brief Handles @ref sd_ble_gap_lesc_oob_data_set command and prepares response.
+ *
+ * @param[in] p_rx_buf Pointer to input buffer.
+ * @param[in] rx_buf_len Size of @p p_rx_buf.
+ * @param[out] p_tx_buf Pointer to output buffer.
+ * @param[in,out] p_tx_buf_len \c in: Size of \p p_tx_buf buffer.
+ * \c out: Length of valid data in \p p_tx_buf.
+ *
+ * @retval NRF_SUCCESS Handler success.
+ * @retval NRF_ERROR_NULL Handler failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Handler failure. Incorrect buffer length.
+ * @retval NRF_ERROR_INVALID_PARAM Handler failure. Invalid operation type.
+ */
+
+uint32_t conn_mw_ble_gap_lesc_oob_data_set(uint8_t const * const p_rx_buf,
+ uint32_t rx_buf_len,
+ uint8_t * const p_tx_buf,
+ uint32_t * const p_tx_buf_len);
+
+/**@brief Handles @ref sd_ble_gap_lesc_oob_data_get command and prepares response.
+ *
+ * @param[in] p_rx_buf Pointer to input buffer.
+ * @param[in] rx_buf_len Size of @p p_rx_buf.
+ * @param[out] p_tx_buf Pointer to output buffer.
+ * @param[in,out] p_tx_buf_len \c in: Size of \p p_tx_buf buffer.
+ * \c out: Length of valid data in \p p_tx_buf.
+ *
+ * @retval NRF_SUCCESS Handler success.
+ * @retval NRF_ERROR_NULL Handler failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Handler failure. Incorrect buffer length.
+ * @retval NRF_ERROR_INVALID_PARAM Handler failure. Invalid operation type.
+ */
+
+uint32_t conn_mw_ble_gap_lesc_oob_data_get(uint8_t const * const p_rx_buf,
+ uint32_t rx_buf_len,
+ uint8_t * const p_tx_buf,
+ uint32_t * const p_tx_buf_len);
+
+/**@brief Allocates instance in m_conn_keys_table[] for storage of encryption keys.
+ *
+ * @param[in] conn_handle Connection handle.
+ * @param[out] p_index Pointer to the index of allocated instance.
+ *
+ * @retval NRF_SUCCESS Success.
+ * @retval NRF_ERROR_NO_MEM No free instance available.
+ */
+uint32_t conn_mw_ble_gap_sec_context_create(uint16_t conn_handle, uint32_t *p_index);
+
+/**@brief Releases the instance identified by a connection handle.
+ *
+ * @param[in] conn_handle Connection handle.
+
+ * @retval NRF_SUCCESS Success.
+ * @retval NRF_ERROR_NOT_FOUND Instance with the @p conn_handle not found.
+ */
+uint32_t conn_mw_ble_gap_sec_context_destroy(uint16_t conn_handle);
+
+/**@brief Finds index of instance identified by a connection handle in m_conn_keys_table[].
+ *
+ * @param[in] conn_handle Connection handle.
+ * @param[out] p_index Pointer to the index of the context instance.
+ *
+ * @retval NRF_SUCCESS Success.
+ * @retval NRF_ERROR_NOT_FOUND Instance with the @p conn_handle not found.
+ */
+uint32_t conn_mw_ble_gap_sec_context_find(uint16_t conn_handle, uint32_t *p_index);
+
+/**@brief Handles @ref sd_ble_gap_addr_set command request and prepares response.
+ *
+ * @param[in] p_rx_buf Pointer to input buffer.
+ * @param[in] rx_buf_len Size of @p p_rx_buf.
+ * @param[out] p_tx_buf Pointer to output buffer.
+ * @param[in,out] p_tx_buf_len \c in: Size of \p p_tx_buf buffer.
+ * \c out: Length of valid data in \p p_tx_buf.
+ *
+ * @retval NRF_SUCCESS Handler success.
+ * @retval NRF_ERROR_NULL Handler failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Handler failure. Incorrect buffer length.
+ * @retval NRF_ERROR_INVALID_PARAM Handler failure. Invalid operation type.
+ */
+uint32_t conn_mw_ble_gap_addr_set(uint8_t const * const p_rx_buf,
+ uint32_t rx_buf_len,
+ uint8_t * const p_tx_buf,
+ uint32_t * const p_tx_buf_len);
+
+/**@brief Handles @ref sd_ble_gap_addr_get command request and prepares response.
+ *
+ * @param[in] p_rx_buf Pointer to input buffer.
+ * @param[in] rx_buf_len Size of @p p_rx_buf.
+ * @param[out] p_tx_buf Pointer to output buffer.
+ * @param[in,out] p_tx_buf_len \c in: Size of \p p_tx_buf buffer.
+ * \c out: Length of valid data in \p p_tx_buf.
+ *
+ * @retval NRF_SUCCESS Handler success.
+ * @retval NRF_ERROR_NULL Handler failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Handler failure. Incorrect buffer length.
+ * @retval NRF_ERROR_INVALID_PARAM Handler failure. Invalid operation type.
+ */
+uint32_t conn_mw_ble_gap_addr_get(uint8_t const * const p_rx_buf,
+ uint32_t rx_buf_len,
+ uint8_t * const p_tx_buf,
+ uint32_t * const p_tx_buf_len);
+
+/**@brief Handles @ref sd_ble_gap_privacy_set command request and prepares response.
+ *
+ * @param[in] p_rx_buf Pointer to input buffer.
+ * @param[in] rx_buf_len Size of @p p_rx_buf.
+ * @param[out] p_tx_buf Pointer to output buffer.
+ * @param[in,out] p_tx_buf_len \c in: Size of \p p_tx_buf buffer.
+ * \c out: Length of valid data in \p p_tx_buf.
+ *
+ * @retval NRF_SUCCESS Handler success.
+ * @retval NRF_ERROR_NULL Handler failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Handler failure. Incorrect buffer length.
+ * @retval NRF_ERROR_INVALID_PARAM Handler failure. Invalid operation type.
+ */
+uint32_t conn_mw_ble_gap_privacy_set(uint8_t const * const p_rx_buf,
+ uint32_t rx_buf_len,
+ uint8_t * const p_tx_buf,
+ uint32_t * const p_tx_buf_len);
+
+/**@brief Handles @ref sd_ble_gap_privacy_get command request and prepares response.
+ *
+ * @param[in] p_rx_buf Pointer to input buffer.
+ * @param[in] rx_buf_len Size of @p p_rx_buf.
+ * @param[out] p_tx_buf Pointer to output buffer.
+ * @param[in,out] p_tx_buf_len \c in: Size of \p p_tx_buf buffer.
+ * \c out: Length of valid data in \p p_tx_buf.
+ *
+ * @retval NRF_SUCCESS Handler success.
+ * @retval NRF_ERROR_NULL Handler failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Handler failure. Incorrect buffer length.
+ * @retval NRF_ERROR_INVALID_PARAM Handler failure. Invalid operation type.
+ */
+uint32_t conn_mw_ble_gap_privacy_get(uint8_t const * const p_rx_buf,
+ uint32_t rx_buf_len,
+ uint8_t * const p_tx_buf,
+ uint32_t * const p_tx_buf_len);
+
+/**@brief Handles @ref sd_ble_gap_whitelist_set command request and prepares response.
+ *
+ * @param[in] p_rx_buf Pointer to input buffer.
+ * @param[in] rx_buf_len Size of @p p_rx_buf.
+ * @param[out] p_tx_buf Pointer to output buffer.
+ * @param[in,out] p_tx_buf_len \c in: Size of \p p_tx_buf buffer.
+ * \c out: Length of valid data in \p p_tx_buf.
+ *
+ * @retval NRF_SUCCESS Handler success.
+ * @retval NRF_ERROR_NULL Handler failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Handler failure. Incorrect buffer length.
+ * @retval NRF_ERROR_INVALID_PARAM Handler failure. Invalid operation type.
+ */
+uint32_t conn_mw_ble_gap_whitelist_set(uint8_t const * const p_rx_buf,
+ uint32_t rx_buf_len,
+ uint8_t * const p_tx_buf,
+ uint32_t * const p_tx_buf_len);
+
+/**@brief Handles @ref sd_ble_gap_device_identities_set command request and prepares response.
+ *
+ * @param[in] p_rx_buf Pointer to input buffer.
+ * @param[in] rx_buf_len Size of @p p_rx_buf.
+ * @param[out] p_tx_buf Pointer to output buffer.
+ * @param[in,out] p_tx_buf_len \c in: Size of \p p_tx_buf buffer.
+ * \c out: Length of valid data in \p p_tx_buf.
+ *
+ * @retval NRF_SUCCESS Handler success.
+ * @retval NRF_ERROR_NULL Handler failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Handler failure. Incorrect buffer length.
+ * @retval NRF_ERROR_INVALID_PARAM Handler failure. Invalid operation type.
+ */
+uint32_t conn_mw_ble_gap_device_identities_set(uint8_t const * const p_rx_buf,
+ uint32_t rx_buf_len,
+ uint8_t * const p_tx_buf,
+ uint32_t * const p_tx_buf_len);
+
+/**@brief Handles @ref sd_ble_gap_phy_update command request and prepares response.
+ *
+ * @param[in] p_rx_buf Pointer to input buffer.
+ * @param[in] rx_buf_len Size of @p p_rx_buf.
+ * @param[out] p_tx_buf Pointer to output buffer.
+ * @param[in,out] p_tx_buf_len \c in: Size of \p p_tx_buf buffer.
+ * \c out: Length of valid data in \p p_tx_buf.
+ *
+ * @retval NRF_SUCCESS Handler success.
+ * @retval NRF_ERROR_NULL Handler failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Handler failure. Incorrect buffer length.
+ * @retval NRF_ERROR_INVALID_PARAM Handler failure. Invalid operation type.
+ */
+
+#if NRF_SD_BLE_API_VERSION >= 5
+uint32_t conn_mw_ble_gap_phy_update(uint8_t const * const p_rx_buf,
+ uint32_t rx_buf_len,
+ uint8_t * const p_tx_buf,
+ uint32_t * const p_tx_buf_len);
+#endif
+#ifdef __cplusplus
+}
+#endif
+
+#if NRF_SD_BLE_API_VERSION >= 4
+/**@brief Handles @ref sd_ble_gap_data_length_update command request and prepares response.
+ *
+ * @param[in] p_rx_buf Pointer to input buffer.
+ * @param[in] rx_buf_len Size of @p p_rx_buf.
+ * @param[out] p_tx_buf Pointer to output buffer.
+ * @param[in,out] p_tx_buf_len \c in: Size of \p p_tx_buf buffer.
+ * \c out: Length of valid data in \p p_tx_buf.
+ *
+ * @retval NRF_SUCCESS Handler success.
+ * @retval NRF_ERROR_NULL Handler failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Handler failure. Incorrect buffer length.
+ * @retval NRF_ERROR_INVALID_PARAM Handler failure. Invalid operation type.
+ */
+uint32_t conn_mw_ble_gap_data_length_update(uint8_t const * const p_rx_buf,
+ uint32_t rx_buf_len,
+ uint8_t * const p_tx_buf,
+ uint32_t * const p_tx_buf_len);
+
+/**@brief Handles @ref sd_ble_gap_adv_set_configure command request and prepares response.
+ *
+ * @param[in] p_rx_buf Pointer to input buffer.
+ * @param[in] rx_buf_len Size of @p p_rx_buf.
+ * @param[out] p_tx_buf Pointer to output buffer.
+ * @param[in,out] p_tx_buf_len \c in: Size of \p p_tx_buf buffer.
+ * \c out: Length of valid data in \p p_tx_buf.
+ *
+ * @retval NRF_SUCCESS Handler success.
+ * @retval NRF_ERROR_NULL Handler failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Handler failure. Incorrect buffer length.
+ * @retval NRF_ERROR_INVALID_PARAM Handler failure. Invalid operation type.
+ */
+uint32_t conn_mw_ble_gap_adv_set_configure(uint8_t const * const p_rx_buf,
+ uint32_t rx_buf_len,
+ uint8_t * const p_tx_buf,
+ uint32_t * const p_tx_buf_len);
+
+/**@brief Handles @ref sd_ble_gap_qos_channel_survey_start command request and prepares response.
+ *
+ * @param[in] p_rx_buf Pointer to input buffer.
+ * @param[in] rx_buf_len Size of @p p_rx_buf.
+ * @param[out] p_tx_buf Pointer to output buffer.
+ * @param[in,out] p_tx_buf_len \c in: Size of \p p_tx_buf buffer.
+ * \c out: Length of valid data in \p p_tx_buf.
+ *
+ * @retval NRF_SUCCESS Handler success.
+ * @retval NRF_ERROR_NULL Handler failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Handler failure. Incorrect buffer length.
+ * @retval NRF_ERROR_INVALID_PARAM Handler failure. Invalid operation type.
+ */
+uint32_t conn_mw_ble_gap_qos_channel_survey_start(uint8_t const * const p_rx_buf,
+ uint32_t rx_buf_len,
+ uint8_t * const p_tx_buf,
+ uint32_t * const p_tx_buf_len);
+
+/**@brief Handles @ref sd_ble_gap_qos_channel_survey_stop command request and prepares response.
+ *
+ * @param[in] p_rx_buf Pointer to input buffer.
+ * @param[in] rx_buf_len Size of @p p_rx_buf.
+ * @param[out] p_tx_buf Pointer to output buffer.
+ * @param[in,out] p_tx_buf_len \c in: Size of \p p_tx_buf buffer.
+ * \c out: Length of valid data in \p p_tx_buf.
+ *
+ * @retval NRF_SUCCESS Handler success.
+ * @retval NRF_ERROR_NULL Handler failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Handler failure. Incorrect buffer length.
+ * @retval NRF_ERROR_INVALID_PARAM Handler failure. Invalid operation type.
+ */
+uint32_t conn_mw_ble_gap_qos_channel_survey_stop(uint8_t const * const p_rx_buf,
+ uint32_t rx_buf_len,
+ uint8_t * const p_tx_buf,
+ uint32_t * const p_tx_buf_len);
+#endif
+#endif //_CONN_MW_BLE_GAP_H
+
+/** @} */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/connectivity/codecs/ble/middleware/conn_mw_ble_gattc.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/connectivity/codecs/ble/middleware/conn_mw_ble_gattc.c
new file mode 100644
index 0000000..904c67f
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/connectivity/codecs/ble/middleware/conn_mw_ble_gattc.c
@@ -0,0 +1,389 @@
+/**
+ * Copyright (c) 2014 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#include "ble_gattc_conn.h"
+#include "conn_mw_ble_gattc.h"
+#include "ble_serialization.h"
+
+#if defined(BLE_GATT_MTU_SIZE_DEFAULT) && !defined(GATT_MTU_SIZE_DEFAULT)
+#define GATT_MTU_SIZE_DEFAULT BLE_GATT_MTU_SIZE_DEFAULT
+#endif
+
+#if defined(BLE_GATT_ATT_MTU_DEFAULT) && !defined(GATT_MTU_SIZE_DEFAULT)
+#define GATT_MTU_SIZE_DEFAULT BLE_GATT_ATT_MTU_DEFAULT
+#endif
+
+#define BLE_GATTC_WRITE_P_VALUE_LEN_MAX (247 - 3)
+
+/** See Bluetooth 4.0 spec: 3.4.4.7. */
+#define BLE_GATTC_HANDLE_COUNT_LEN_MAX ((GATT_MTU_SIZE_DEFAULT - 1) / 2)
+
+uint32_t conn_mw_ble_gattc_primary_services_discover(uint8_t const * const p_rx_buf,
+ uint32_t rx_buf_len,
+ uint8_t * const p_tx_buf,
+ uint32_t * const p_tx_buf_len)
+{
+ SER_ASSERT_NOT_NULL(p_rx_buf);
+ SER_ASSERT_NOT_NULL(p_tx_buf);
+ SER_ASSERT_NOT_NULL(p_tx_buf_len);
+
+ uint16_t conn_handle;
+ uint16_t start_handle;
+ ble_uuid_t srvc_uuid;
+ ble_uuid_t * p_srvc_uuid = &srvc_uuid;
+
+ uint32_t err_code = NRF_SUCCESS;
+ uint32_t sd_err_code;
+
+ err_code = ble_gattc_primary_services_discover_req_dec(p_rx_buf,
+ rx_buf_len,
+ &conn_handle,
+ &start_handle,
+ &p_srvc_uuid);
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code);
+
+ sd_err_code = sd_ble_gattc_primary_services_discover(conn_handle, start_handle, p_srvc_uuid);
+
+ err_code = ble_gattc_primary_services_discover_rsp_enc(sd_err_code, p_tx_buf, p_tx_buf_len);
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code);
+
+ return err_code;
+}
+
+uint32_t conn_mw_ble_gattc_relationships_discover(uint8_t const * const p_rx_buf,
+ uint32_t rx_buf_len,
+ uint8_t * const p_tx_buf,
+ uint32_t * const p_tx_buf_len)
+{
+ SER_ASSERT_NOT_NULL(p_rx_buf);
+ SER_ASSERT_NOT_NULL(p_tx_buf);
+ SER_ASSERT_NOT_NULL(p_tx_buf_len);
+
+ uint16_t conn_handle;
+ ble_gattc_handle_range_t handle_range;
+ ble_gattc_handle_range_t * p_handle_range = &handle_range;
+
+ uint32_t err_code = NRF_SUCCESS;
+ uint32_t sd_err_code;
+
+ err_code = ble_gattc_relationships_discover_req_dec(p_rx_buf, rx_buf_len,
+ &conn_handle, &p_handle_range);
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code);
+
+ sd_err_code = sd_ble_gattc_relationships_discover(conn_handle, p_handle_range);
+
+ err_code = ble_gattc_relationships_discover_rsp_enc(sd_err_code, p_tx_buf, p_tx_buf_len);
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code);
+
+ return err_code;
+}
+
+uint32_t conn_mw_ble_gattc_characteristics_discover(uint8_t const * const p_rx_buf,
+ uint32_t rx_buf_len,
+ uint8_t * const p_tx_buf,
+ uint32_t * const p_tx_buf_len)
+{
+ SER_ASSERT_NOT_NULL(p_rx_buf);
+ SER_ASSERT_NOT_NULL(p_tx_buf);
+ SER_ASSERT_NOT_NULL(p_tx_buf_len);
+
+ uint16_t conn_handle;
+ ble_gattc_handle_range_t handle_range;
+ ble_gattc_handle_range_t * p_handle_range = &handle_range;
+
+ uint32_t err_code = NRF_SUCCESS;
+ uint32_t sd_err_code;
+
+ err_code = ble_gattc_characteristics_discover_req_dec(p_rx_buf, rx_buf_len,
+ &conn_handle, &p_handle_range);
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code);
+
+ sd_err_code = sd_ble_gattc_characteristics_discover(conn_handle, p_handle_range);
+
+ err_code = ble_gattc_characteristics_discover_rsp_enc(sd_err_code, p_tx_buf, p_tx_buf_len);
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code);
+
+ return err_code;
+}
+
+uint32_t conn_mw_ble_gattc_descriptors_discover(uint8_t const * const p_rx_buf,
+ uint32_t rx_buf_len,
+ uint8_t * const p_tx_buf,
+ uint32_t * const p_tx_buf_len)
+{
+ SER_ASSERT_NOT_NULL(p_rx_buf);
+ SER_ASSERT_NOT_NULL(p_tx_buf);
+ SER_ASSERT_NOT_NULL(p_tx_buf_len);
+
+ uint16_t conn_handle;
+ ble_gattc_handle_range_t handle_range;
+ ble_gattc_handle_range_t * p_handle_range = &handle_range;
+
+ uint32_t err_code = NRF_SUCCESS;
+ uint32_t sd_err_code;
+
+ err_code = ble_gattc_descriptors_discover_req_dec(p_rx_buf, rx_buf_len,
+ &conn_handle, &p_handle_range);
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code);
+
+ sd_err_code = sd_ble_gattc_descriptors_discover(conn_handle, p_handle_range);
+
+ err_code = ble_gattc_descriptors_discover_rsp_enc(sd_err_code, p_tx_buf, p_tx_buf_len);
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code);
+
+ return err_code;
+}
+
+uint32_t conn_mw_ble_gattc_char_value_by_uuid_read(uint8_t const * const p_rx_buf,
+ uint32_t rx_buf_len,
+ uint8_t * const p_tx_buf,
+ uint32_t * const p_tx_buf_len)
+{
+ SER_ASSERT_NOT_NULL(p_rx_buf);
+ SER_ASSERT_NOT_NULL(p_tx_buf);
+ SER_ASSERT_NOT_NULL(p_tx_buf_len);
+
+ uint16_t conn_handle;
+
+ ble_uuid_t uuid = {0};
+ ble_uuid_t * p_uuid = &uuid;
+
+ ble_gattc_handle_range_t handle_range;
+ ble_gattc_handle_range_t * p_handle_range = &handle_range;
+
+ uint32_t err_code = NRF_SUCCESS;
+ uint32_t sd_err_code;
+
+ err_code = ble_gattc_char_value_by_uuid_read_req_dec(p_rx_buf, rx_buf_len,
+ &conn_handle, &p_uuid, &p_handle_range);
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code);
+
+ sd_err_code = sd_ble_gattc_char_value_by_uuid_read(conn_handle, p_uuid, p_handle_range);
+
+ err_code = ble_gattc_char_value_by_uuid_read_rsp_enc(sd_err_code, p_tx_buf, p_tx_buf_len);
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code);
+
+ return err_code;
+}
+
+uint32_t conn_mw_ble_gattc_read(uint8_t const * const p_rx_buf,
+ uint32_t rx_buf_len,
+ uint8_t * const p_tx_buf,
+ uint32_t * const p_tx_buf_len)
+{
+ SER_ASSERT_NOT_NULL(p_rx_buf);
+ SER_ASSERT_NOT_NULL(p_tx_buf);
+ SER_ASSERT_NOT_NULL(p_tx_buf_len);
+
+ uint16_t conn_handle;
+ uint16_t * p_conn_handle = &conn_handle;
+
+ uint16_t handle;
+ uint16_t * p_handle = &handle;
+
+ uint16_t offset;
+ uint16_t * p_offset = &offset;
+
+ uint32_t err_code = NRF_SUCCESS;
+ uint32_t sd_err_code;
+
+ err_code = ble_gattc_read_req_dec(p_rx_buf, rx_buf_len, p_conn_handle, p_handle, p_offset);
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code);
+
+ sd_err_code = sd_ble_gattc_read(conn_handle, handle, offset);
+
+ err_code = ble_gattc_read_rsp_enc(sd_err_code, p_tx_buf, p_tx_buf_len);
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code);
+
+ return err_code;
+}
+
+uint32_t conn_mw_ble_gattc_char_values_read(uint8_t const * const p_rx_buf,
+ uint32_t rx_buf_len,
+ uint8_t * const p_tx_buf,
+ uint32_t * const p_tx_buf_len)
+{
+ SER_ASSERT_NOT_NULL(p_rx_buf);
+ SER_ASSERT_NOT_NULL(p_tx_buf);
+ SER_ASSERT_NOT_NULL(p_tx_buf_len);
+
+ uint16_t conn_handle;
+ uint16_t * p_conn_handle = &conn_handle;
+
+ uint16_t handles[BLE_GATTC_HANDLE_COUNT_LEN_MAX];
+ uint16_t * p_handles = handles;
+
+ uint16_t handle_count = BLE_GATTC_HANDLE_COUNT_LEN_MAX;
+ uint16_t * p_handle_count = &handle_count;
+
+ uint32_t err_code = NRF_SUCCESS;
+ uint32_t sd_err_code;
+
+ err_code = ble_gattc_char_values_read_req_dec(p_rx_buf,
+ rx_buf_len,
+ p_conn_handle,
+ &p_handles,
+ p_handle_count);
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code);
+
+ sd_err_code = sd_ble_gattc_char_values_read(conn_handle, p_handles, handle_count);
+
+ err_code = ble_gattc_char_values_read_rsp_enc(sd_err_code, p_tx_buf, p_tx_buf_len);
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code);
+
+ return err_code;
+}
+
+uint32_t conn_mw_ble_gattc_write(uint8_t const * const p_rx_buf,
+ uint32_t rx_buf_len,
+ uint8_t * const p_tx_buf,
+ uint32_t * const p_tx_buf_len)
+{
+ SER_ASSERT_NOT_NULL(p_rx_buf);
+ SER_ASSERT_NOT_NULL(p_tx_buf);
+ SER_ASSERT_NOT_NULL(p_tx_buf_len);
+
+ uint16_t conn_handle;
+ uint16_t * p_conn_handle = &conn_handle;
+
+ uint8_t value[BLE_GATTC_WRITE_P_VALUE_LEN_MAX];
+
+ ble_gattc_write_params_t write_params = {0};
+ ble_gattc_write_params_t * p_write_params = &write_params;
+
+ p_write_params->len = BLE_GATTC_WRITE_P_VALUE_LEN_MAX;
+ p_write_params->p_value = value;
+
+ uint32_t err_code = NRF_SUCCESS;
+ uint32_t sd_err_code;
+
+ err_code = ble_gattc_write_req_dec(p_rx_buf, rx_buf_len, p_conn_handle, &p_write_params);
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code);
+
+ sd_err_code = sd_ble_gattc_write(conn_handle, p_write_params);
+
+ err_code = ble_gattc_write_rsp_enc(sd_err_code, p_tx_buf, p_tx_buf_len);
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code);
+
+ return err_code;
+}
+
+uint32_t conn_mw_ble_gattc_hv_confirm(uint8_t const * const p_rx_buf,
+ uint32_t rx_buf_len,
+ uint8_t * const p_tx_buf,
+ uint32_t * const p_tx_buf_len)
+{
+ SER_ASSERT_NOT_NULL(p_rx_buf);
+ SER_ASSERT_NOT_NULL(p_tx_buf);
+ SER_ASSERT_NOT_NULL(p_tx_buf_len);
+
+ uint32_t err_code = NRF_SUCCESS;
+ uint32_t sd_err_code;
+
+ uint16_t conn_handle;
+ uint16_t * p_conn_handle = &conn_handle;
+
+ uint16_t handle;
+ uint16_t * p_handle = &handle;
+
+ err_code = ble_gattc_hv_confirm_req_dec(p_rx_buf, rx_buf_len, p_conn_handle, p_handle);
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code);
+
+ sd_err_code = sd_ble_gattc_hv_confirm(conn_handle, handle);
+
+ err_code = ble_gattc_hv_confirm_rsp_enc(sd_err_code, p_tx_buf, p_tx_buf_len);
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code);
+
+ return err_code;
+}
+
+uint32_t conn_mw_ble_gattc_attr_info_discover(uint8_t const * const p_rx_buf,
+ uint32_t rx_buf_len,
+ uint8_t * const p_tx_buf,
+ uint32_t * const p_tx_buf_len)
+{
+ SER_ASSERT_NOT_NULL(p_rx_buf);
+ SER_ASSERT_NOT_NULL(p_tx_buf);
+ SER_ASSERT_NOT_NULL(p_tx_buf_len);
+
+ uint16_t conn_handle;
+ uint16_t * p_conn_handle = &conn_handle;
+
+ ble_gattc_handle_range_t range = {0};
+ ble_gattc_handle_range_t * p_range = &range;
+
+ uint32_t err_code = NRF_SUCCESS;
+ uint32_t sd_err_code;
+
+ err_code = ble_gattc_attr_info_discover_req_dec(p_rx_buf, rx_buf_len, p_conn_handle, &p_range);
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code);
+
+ sd_err_code = sd_ble_gattc_attr_info_discover(conn_handle, p_range);
+
+ err_code = ble_gattc_attr_info_discover_rsp_enc(sd_err_code, p_tx_buf, p_tx_buf_len);
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code);
+
+ return err_code;
+}
+
+uint32_t conn_mw_ble_gattc_exchange_mtu_request(uint8_t const * const p_rx_buf,
+ uint32_t rx_buf_len,
+ uint8_t * const p_tx_buf,
+ uint32_t * const p_tx_buf_len)
+{
+ SER_ASSERT_NOT_NULL(p_rx_buf);
+ SER_ASSERT_NOT_NULL(p_tx_buf);
+ SER_ASSERT_NOT_NULL(p_tx_buf_len);
+
+ uint16_t conn_handle;
+ uint16_t client_rx_mtu;
+
+ uint32_t err_code = NRF_SUCCESS;
+ uint32_t sd_err_code;
+
+ err_code = ble_gattc_exchange_mtu_request_req_dec(p_rx_buf, rx_buf_len, &conn_handle, &client_rx_mtu);
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code);
+
+ sd_err_code = sd_ble_gattc_exchange_mtu_request(conn_handle, client_rx_mtu);
+
+ err_code = ble_gattc_exchange_mtu_request_rsp_enc(sd_err_code, p_tx_buf, p_tx_buf_len);
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code);
+
+ return err_code;
+}
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/connectivity/codecs/ble/middleware/conn_mw_ble_gattc.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/connectivity/codecs/ble/middleware/conn_mw_ble_gattc.h
new file mode 100644
index 0000000..61b6248
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/connectivity/codecs/ble/middleware/conn_mw_ble_gattc.h
@@ -0,0 +1,259 @@
+/**
+ * Copyright (c) 2014 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#ifndef _CONN_MW_BLE_GATTC_H
+ #define _CONN_MW_BLE_GATTC_H
+
+#include <stdint.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @addtogroup sercon_mw_s132_ble_gattc GATTC Middleware command handlers
+ * @{
+ * @ingroup sercon_mw_s132
+ */
+
+/**@brief Handles @ref sd_ble_gattc_primary_services_discover command and prepares response.
+ *
+ * @param[in] p_rx_buf Pointer to input buffer.
+ * @param[in] rx_buf_len Size of @p p_rx_buf.
+ * @param[out] p_tx_buf Pointer to output buffer.
+ * @param[in,out] p_tx_buf_len \c in: Size of \p p_tx_buf buffer.
+ * \c out: Length of valid data in \p p_tx_buf.
+ *
+ * @retval NRF_SUCCESS Handler success.
+ * @retval NRF_ERROR_NULL Handler failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Handler failure. Incorrect buffer length.
+ * @retval NRF_ERROR_INVALID_PARAM Handler failure. Invalid operation type.
+ */
+uint32_t conn_mw_ble_gattc_primary_services_discover (uint8_t const * const p_rx_buf,
+ uint32_t rx_buf_len,
+ uint8_t * const p_tx_buf,
+ uint32_t * const p_tx_buf_len);
+
+/**@brief Handles @ref sd_ble_gattc_relationships_discover command and prepares response.
+ *
+ * @param[in] p_rx_buf Pointer to input buffer.
+ * @param[in] rx_buf_len Size of @p p_rx_buf.
+ * @param[out] p_tx_buf Pointer to output buffer.
+ * @param[in,out] p_tx_buf_len \c in: Size of \p p_tx_buf buffer.
+ * \c out: Length of valid data in \p p_tx_buf.
+ *
+ * @retval NRF_SUCCESS Handler success.
+ * @retval NRF_ERROR_NULL Handler failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Handler failure. Incorrect buffer length.
+ * @retval NRF_ERROR_INVALID_PARAM Handler failure. Invalid operation type.
+ */
+uint32_t conn_mw_ble_gattc_relationships_discover(uint8_t const * const p_rx_buf,
+ uint32_t rx_buf_len,
+ uint8_t * const p_tx_buf,
+ uint32_t * const p_tx_buf_len);
+
+/**@brief Handles @ref sd_ble_gattc_characteristics_discover command and prepares response.
+ *
+ * @param[in] p_rx_buf Pointer to input buffer.
+ * @param[in] rx_buf_len Size of @p p_rx_buf.
+ * @param[out] p_tx_buf Pointer to output buffer.
+ * @param[in,out] p_tx_buf_len \c in: Size of \p p_tx_buf buffer.
+ * \c out: Length of valid data in \p p_tx_buf.
+ *
+ * @retval NRF_SUCCESS Handler success.
+ * @retval NRF_ERROR_NULL Handler failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Handler failure. Incorrect buffer length.
+ * @retval NRF_ERROR_INVALID_PARAM Handler failure. Invalid operation type.
+ */
+uint32_t conn_mw_ble_gattc_characteristics_discover(uint8_t const * const p_rx_buf,
+ uint32_t rx_buf_len,
+ uint8_t * const p_tx_buf,
+ uint32_t * const p_tx_buf_len);
+
+/**@brief Handles @ref sd_ble_gattc_descriptors_discover command and prepares response.
+ *
+ * @param[in] p_rx_buf Pointer to input buffer.
+ * @param[in] rx_buf_len Size of @p p_rx_buf.
+ * @param[out] p_tx_buf Pointer to output buffer.
+ * @param[in,out] p_tx_buf_len \c in: Size of \p p_tx_buf buffer.
+ * \c out: Length of valid data in \p p_tx_buf.
+ *
+ * @retval NRF_SUCCESS Handler success.
+ * @retval NRF_ERROR_NULL Handler failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Handler failure. Incorrect buffer length.
+ * @retval NRF_ERROR_INVALID_PARAM Handler failure. Invalid operation type.
+ */
+uint32_t conn_mw_ble_gattc_descriptors_discover(uint8_t const * const p_rx_buf,
+ uint32_t rx_buf_len,
+ uint8_t * const p_tx_buf,
+ uint32_t * const p_tx_buf_len);
+
+/**@brief Handles @ref sd_ble_gattc_char_value_by_uuid_read command and prepares response.
+ *
+ * @param[in] p_rx_buf Pointer to input buffer.
+ * @param[in] rx_buf_len Size of @p p_rx_buf.
+ * @param[out] p_tx_buf Pointer to output buffer.
+ * @param[in,out] p_tx_buf_len \c in: Size of \p p_tx_buf buffer.
+ * \c out: Length of valid data in \p p_tx_buf.
+ *
+ * @retval NRF_SUCCESS Handler success.
+ * @retval NRF_ERROR_NULL Handler failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Handler failure. Incorrect buffer length.
+ * @retval NRF_ERROR_INVALID_PARAM Handler failure. Invalid operation type.
+ */
+uint32_t conn_mw_ble_gattc_char_value_by_uuid_read(uint8_t const * const p_rx_buf,
+ uint32_t rx_buf_len,
+ uint8_t * const p_tx_buf,
+ uint32_t * const p_tx_buf_len);
+
+/**@brief Handles @ref sd_ble_gattc_read command and prepares response.
+ *
+ * @param[in] rx_buf Pointer to input buffer.
+ * @param[in] rx_buf_len Size of @p p_rx_buf.
+ * @param[out] tx_buf Pointer to output buffer.
+ * @param[in,out] p_tx_buf_len \c in: Size of \p p_tx_buf buffer.
+ * \c out: Length of valid data in \p p_tx_buf.
+ *
+ * @retval NRF_SUCCESS Handler success.
+ * @retval NRF_ERROR_NULL Handler failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Handler failure. Incorrect buffer length.
+ * @retval NRF_ERROR_INVALID_PARAM Handler failure. Invalid operation type.
+ */
+uint32_t conn_mw_ble_gattc_read (uint8_t const *const rx_buf,
+ uint32_t rx_buf_len,
+ uint8_t *const tx_buf,
+ uint32_t *const p_tx_buf_len);
+
+/**@brief Handles @ref sd_ble_gattc_char_values_read command and prepares response.
+ *
+ * @param[in] rx_buf Pointer to input buffer.
+ * @param[in] rx_buf_len Size of @p p_rx_buf.
+ * @param[out] tx_buf Pointer to output buffer.
+ * @param[in,out] p_tx_buf_len \c in: Size of \p p_tx_buf buffer.
+ * \c out: Length of valid data in \p p_tx_buf.
+ *
+ * @retval NRF_SUCCESS Handler success.
+ * @retval NRF_ERROR_NULL Handler failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Handler failure. Incorrect buffer length.
+ * @retval NRF_ERROR_INVALID_PARAM Handler failure. Invalid operation type.
+ */
+uint32_t conn_mw_ble_gattc_char_values_read (uint8_t const *const rx_buf,
+ uint32_t rx_buf_len,
+ uint8_t *const tx_buf,
+ uint32_t *const p_tx_buf_len);
+
+/**@brief Handles @ref sd_ble_gattc_write command and prepares response.
+ *
+ * @param[in] rx_buf Pointer to input buffer.
+ * @param[in] rx_buf_len Size of @p p_rx_buf.
+ * @param[out] tx_buf Pointer to output buffer.
+ * @param[in,out] p_tx_buf_len \c in: Size of \p p_tx_buf buffer.
+ * \c out: Length of valid data in \p p_tx_buf.
+ *
+ * @retval NRF_SUCCESS Handler success.
+ * @retval NRF_ERROR_NULL Handler failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Handler failure. Incorrect buffer length.
+ * @retval NRF_ERROR_INVALID_PARAM Handler failure. Invalid operation type.
+ */
+uint32_t conn_mw_ble_gattc_write (uint8_t const *const rx_buf,
+ uint32_t rx_buf_len,
+ uint8_t *const tx_buf,
+ uint32_t *const p_tx_buf_len);
+
+/**@brief Handles @ref sd_ble_gattc_hv_confirm command and prepares response.
+ *
+ * @param[in] rx_buf Pointer to input buffer.
+ * @param[in] rx_buf_len Size of @p p_rx_buf.
+ * @param[out] tx_buf Pointer to output buffer.
+ * @param[in,out] p_tx_buf_len \c in: Size of \p p_tx_buf buffer.
+ * \c out: Length of valid data in \p p_tx_buf.
+ *
+ * @retval NRF_SUCCESS Handler success.
+ * @retval NRF_ERROR_NULL Handler failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Handler failure. Incorrect buffer length.
+ * @retval NRF_ERROR_INVALID_PARAM Handler failure. Invalid operation type.
+ */
+uint32_t conn_mw_ble_gattc_hv_confirm (uint8_t const *const rx_buf,
+ uint32_t rx_buf_len,
+ uint8_t *const tx_buf,
+ uint32_t *const p_tx_buf_len);
+
+/**@brief Handles @ref sd_ble_gattc_attr_info_discover command and prepares response.
+ *
+ * @param[in] p_rx_buf Pointer to input buffer.
+ * @param[in] rx_buf_len Size of @p p_rx_buf.
+ * @param[out] p_tx_buf Pointer to output buffer.
+ * @param[in,out] p_tx_buf_len \c in: Size of \p p_tx_buf buffer.
+ * \c out: Length of valid data in \p p_tx_buf.
+ *
+ * @retval NRF_SUCCESS Handler success.
+ * @retval NRF_ERROR_NULL Handler failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Handler failure. Incorrect buffer length.
+ * @retval NRF_ERROR_INVALID_PARAM Handler failure. Invalid operation type.
+ */
+uint32_t conn_mw_ble_gattc_attr_info_discover(uint8_t const * const p_rx_buf,
+ uint32_t rx_buf_len,
+ uint8_t * const p_tx_buf,
+ uint32_t * const p_tx_buf_len);
+
+/**@brief Handles @ref sd_ble_gattc_exchange_mtu_request command and prepares response.
+ *
+ * @param[in] p_rx_buf Pointer to input buffer.
+ * @param[in] rx_buf_len Size of @p p_rx_buf.
+ * @param[out] p_tx_buf Pointer to output buffer.
+ * @param[in,out] p_tx_buf_len \c in: Size of \p p_tx_buf buffer.
+ * \c out: Length of valid data in \p p_tx_buf.
+ *
+ * @retval NRF_SUCCESS Handler success.
+ * @retval NRF_ERROR_NULL Handler failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Handler failure. Incorrect buffer length.
+ * @retval NRF_ERROR_INVALID_PARAM Handler failure. Invalid operation type.
+ */
+uint32_t conn_mw_ble_gattc_exchange_mtu_request(uint8_t const * const p_rx_buf,
+ uint32_t rx_buf_len,
+ uint8_t * const p_tx_buf,
+ uint32_t * const p_tx_buf_len);
+
+/** @} */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif //_CONN_MW_BLE_GATTC_H
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/connectivity/codecs/ble/middleware/conn_mw_ble_gatts.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/connectivity/codecs/ble/middleware/conn_mw_ble_gatts.c
new file mode 100644
index 0000000..d55626f
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/connectivity/codecs/ble/middleware/conn_mw_ble_gatts.c
@@ -0,0 +1,517 @@
+/**
+ * Copyright (c) 2014 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#include "ble_gatts_conn.h"
+#include "conn_mw_ble_gatts.h"
+#include "ble_serialization.h"
+
+uint32_t conn_mw_ble_gatts_service_add(uint8_t const * const p_rx_buf,
+ uint32_t rx_buf_len,
+ uint8_t * const p_tx_buf,
+ uint32_t * const p_tx_buf_len)
+{
+ SER_ASSERT_NOT_NULL(p_rx_buf);
+ SER_ASSERT_NOT_NULL(p_tx_buf);
+ SER_ASSERT_NOT_NULL(p_tx_buf_len);
+
+ uint8_t type;
+ ble_uuid_t uuid = {0};
+ ble_uuid_t * p_uuid = &uuid;
+ uint16_t handle;
+ uint16_t * p_handle = &handle;
+
+ uint32_t err_code = NRF_SUCCESS;
+ uint32_t sd_err_code;
+
+ err_code = ble_gatts_service_add_req_dec(p_rx_buf, rx_buf_len, &type, &p_uuid, &p_handle);
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code);
+
+ sd_err_code = sd_ble_gatts_service_add(type, p_uuid, p_handle);
+
+ err_code = ble_gatts_service_add_rsp_enc(sd_err_code, p_tx_buf, p_tx_buf_len, p_handle);
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code);
+
+ return err_code;
+}
+
+uint32_t conn_mw_ble_gatts_characteristic_add(uint8_t const * const p_rx_buf,
+ uint32_t rx_buf_len,
+ uint8_t * const p_tx_buf,
+ uint32_t * const p_tx_buf_len)
+{
+ SER_ASSERT_NOT_NULL(p_rx_buf);
+ SER_ASSERT_NOT_NULL(p_tx_buf);
+ SER_ASSERT_NOT_NULL(p_tx_buf_len);
+
+ uint16_t service_handle;
+
+ //Preparing char_md
+ ble_gatts_char_md_t char_md;
+
+ uint8_t char_user_desc[BLE_GATTS_VAR_ATTR_LEN_MAX];
+ ble_gatts_char_pf_t char_pf;
+ ble_gatts_attr_md_t user_desc_md;
+ ble_gatts_attr_md_t cccd_md;
+ ble_gatts_attr_md_t sccd_md;
+
+ char_md.char_user_desc_size = sizeof (char_user_desc);
+ char_md.p_char_user_desc = char_user_desc;
+ char_md.p_char_pf = &char_pf;
+ char_md.p_user_desc_md = &user_desc_md;
+ char_md.p_cccd_md = &cccd_md;
+ char_md.p_sccd_md = &sccd_md;
+
+ ble_gatts_char_md_t * p_char_md = &char_md;
+
+ //Preparing attr_char_value
+ ble_gatts_attr_t attr_char_value;
+ ble_uuid_t uuid;
+ ble_gatts_attr_md_t attr_md;
+ uint8_t value[BLE_GATTS_VAR_ATTR_LEN_MAX];
+
+ attr_char_value.p_uuid = &uuid;
+ attr_char_value.p_attr_md = &attr_md;
+ attr_char_value.init_len = sizeof (value);
+ attr_char_value.p_value = value;
+
+ ble_gatts_attr_t * p_attr_char_value = &attr_char_value;
+
+ //Preparing handles
+ ble_gatts_char_handles_t handles;
+ ble_gatts_char_handles_t * p_handles = &handles;
+
+ uint32_t err_code = NRF_SUCCESS;
+ uint32_t sd_err_code;
+
+ err_code = ble_gatts_characteristic_add_req_dec(p_rx_buf, rx_buf_len, &service_handle,
+ &p_char_md, &p_attr_char_value, &p_handles);
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code);
+
+ sd_err_code = sd_ble_gatts_characteristic_add(service_handle, p_char_md,
+ p_attr_char_value, p_handles);
+
+ err_code = ble_gatts_characteristic_add_rsp_enc(sd_err_code, p_tx_buf, p_tx_buf_len,
+ p_handles);
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code);
+
+ return err_code;
+
+}
+
+uint32_t conn_mw_ble_gatts_include_add(uint8_t const * const p_rx_buf,
+ uint32_t rx_buf_len,
+ uint8_t * const p_tx_buf,
+ uint32_t * const p_tx_buf_len)
+{
+ SER_ASSERT_NOT_NULL(p_rx_buf);
+ SER_ASSERT_NOT_NULL(p_tx_buf);
+ SER_ASSERT_NOT_NULL(p_tx_buf_len);
+
+ uint16_t service_handle;
+ uint16_t inc_srvc_handle;
+ uint16_t handle;
+ uint16_t * p_handle = &handle;
+
+ uint32_t err_code = NRF_SUCCESS;
+ uint32_t sd_err_code;
+
+ err_code = ble_gatts_include_add_req_dec(p_rx_buf, rx_buf_len, &service_handle,
+ &inc_srvc_handle, &p_handle);
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code);
+
+ sd_err_code = sd_ble_gatts_include_add(service_handle, inc_srvc_handle, p_handle);
+
+ err_code = ble_gatts_include_add_rsp_enc(sd_err_code, p_tx_buf, p_tx_buf_len, p_handle);
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code);
+
+ return err_code;
+}
+
+uint32_t conn_mw_ble_gatts_descriptor_add(uint8_t const * const p_rx_buf,
+ uint32_t rx_buf_len,
+ uint8_t * const p_tx_buf,
+ uint32_t * const p_tx_buf_len)
+{
+
+ SER_ASSERT_NOT_NULL(p_rx_buf);
+ SER_ASSERT_NOT_NULL(p_tx_buf);
+ SER_ASSERT_NOT_NULL(p_tx_buf_len);
+
+ uint16_t char_handle;
+ uint8_t attr_value[BLE_GATTS_VAR_ATTR_LEN_MAX];
+ ble_uuid_t char_uuid;
+ ble_gatts_attr_md_t metadata;
+ ble_gatts_attr_t attr;
+ ble_gatts_attr_t * p_attr = &attr;
+
+ attr.p_uuid = &char_uuid;
+ attr.p_attr_md = &metadata;
+ attr.p_value = attr_value;
+ attr.init_len = sizeof (attr_value);
+
+ uint16_t handle;
+ uint16_t * p_handle = &handle;
+
+ uint32_t err_code = NRF_SUCCESS;
+ uint32_t sd_err_code;
+
+ err_code = ble_gatts_descriptor_add_req_dec(p_rx_buf, rx_buf_len, &char_handle, &p_attr,
+ &p_handle);
+
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code);
+
+ sd_err_code = sd_ble_gatts_descriptor_add(char_handle, p_attr, p_handle);
+
+ err_code = ble_gatts_descriptor_add_rsp_enc(sd_err_code, p_tx_buf, p_tx_buf_len, p_handle);
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code);
+
+ return err_code;
+}
+
+uint32_t conn_mw_ble_gatts_value_set(uint8_t const * const p_rx_buf,
+ uint32_t rx_buf_len,
+ uint8_t * const p_tx_buf,
+ uint32_t * const p_tx_buf_len)
+{
+ SER_ASSERT_NOT_NULL(p_rx_buf);
+ SER_ASSERT_NOT_NULL(p_tx_buf);
+ SER_ASSERT_NOT_NULL(p_tx_buf_len);
+
+ uint16_t conn_handle;
+ uint16_t handle;
+ uint8_t attr_val_table[BLE_GATTS_VAR_ATTR_LEN_MAX];
+ ble_gatts_value_t attr_val =
+ {
+ .len = sizeof (attr_val_table),
+ .offset = 0,
+ .p_value = attr_val_table
+ };
+ ble_gatts_value_t * p_attr_val = &attr_val;
+
+ uint32_t err_code = NRF_SUCCESS;
+ uint32_t sd_err_code;
+
+ err_code = ble_gatts_value_set_req_dec(p_rx_buf, rx_buf_len, &conn_handle, &handle, &p_attr_val);
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code);
+
+ sd_err_code = sd_ble_gatts_value_set(conn_handle, handle, p_attr_val);
+
+ err_code = ble_gatts_value_set_rsp_enc(sd_err_code, p_tx_buf, p_tx_buf_len, p_attr_val);
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code);
+
+ return err_code;
+}
+
+uint32_t conn_mw_ble_gatts_value_get(uint8_t const * const p_rx_buf,
+ uint32_t rx_buf_len,
+ uint8_t * const p_tx_buf,
+ uint32_t * const p_tx_buf_len)
+{
+ SER_ASSERT_NOT_NULL(p_rx_buf);
+ SER_ASSERT_NOT_NULL(p_tx_buf);
+ SER_ASSERT_NOT_NULL(p_tx_buf_len);
+
+ uint16_t conn_handle;
+ uint16_t handle;
+ uint8_t val[BLE_GATTS_VAR_ATTR_LEN_MAX];
+ ble_gatts_value_t attr_value;
+ ble_gatts_value_t * p_attr_value = &attr_value;
+
+ attr_value.p_value = val;
+
+ uint32_t err_code = NRF_SUCCESS;
+ uint32_t sd_err_code;
+
+ err_code = ble_gatts_value_get_req_dec(p_rx_buf, rx_buf_len, &conn_handle, &handle, &p_attr_value);
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code);
+ sd_err_code = sd_ble_gatts_value_get(conn_handle, handle, p_attr_value);
+
+ err_code = ble_gatts_value_get_rsp_enc(sd_err_code, p_tx_buf, p_tx_buf_len, p_attr_value);
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code);
+
+ return err_code;
+}
+
+uint32_t conn_mw_ble_gatts_hvx(uint8_t const * const p_rx_buf,
+ uint32_t rx_buf_len,
+ uint8_t * const p_tx_buf,
+ uint32_t * const p_tx_buf_len)
+{
+ SER_ASSERT_NOT_NULL(p_rx_buf);
+ SER_ASSERT_NOT_NULL(p_tx_buf);
+ SER_ASSERT_NOT_NULL(p_tx_buf_len);
+
+ uint16_t conn_handle;
+ uint8_t data[BLE_GATTS_VAR_ATTR_LEN_MAX];
+ uint8_t * p_data = data;
+ uint16_t len = sizeof data;
+ uint16_t * p_len = &len;
+
+ ble_gatts_hvx_params_t hvx_params;
+ ble_gatts_hvx_params_t * p_hvx_params = &hvx_params;
+
+ hvx_params.p_len = p_len;
+ hvx_params.p_data = p_data;
+
+ uint32_t err_code = NRF_SUCCESS;
+ uint32_t sd_err_code;
+
+ err_code = ble_gatts_hvx_req_dec(p_rx_buf, rx_buf_len, &conn_handle, &p_hvx_params);
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code);
+ sd_err_code = sd_ble_gatts_hvx(conn_handle, p_hvx_params);
+
+ p_len = (p_hvx_params) ? p_hvx_params->p_len : NULL;
+ err_code = ble_gatts_hvx_rsp_enc(sd_err_code, p_tx_buf, p_tx_buf_len, p_len);
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code);
+
+ return err_code;
+}
+
+uint32_t conn_mw_ble_gatts_service_changed(uint8_t const * const p_rx_buf,
+ uint32_t rx_buf_len,
+ uint8_t * const p_tx_buf,
+ uint32_t * const p_tx_buf_len)
+{
+ SER_ASSERT_NOT_NULL(p_rx_buf);
+ SER_ASSERT_NOT_NULL(p_tx_buf);
+ SER_ASSERT_NOT_NULL(p_tx_buf_len);
+
+ uint16_t conn_handle;
+ uint16_t start_handle;
+ uint16_t end_handle;
+
+ uint32_t err_code = NRF_SUCCESS;
+ uint32_t sd_err_code;
+
+ err_code = ble_gatts_service_changed_req_dec(p_rx_buf, rx_buf_len, &conn_handle, &start_handle,
+ &end_handle);
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code);
+
+ sd_err_code = sd_ble_gatts_service_changed(conn_handle, start_handle, end_handle);
+
+ err_code = ble_gatts_service_changed_rsp_enc(sd_err_code, p_tx_buf, p_tx_buf_len);
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code);
+
+ return err_code;
+}
+
+uint32_t conn_mw_ble_gatts_rw_authorize_reply(uint8_t const * const p_rx_buf,
+ uint32_t rx_buf_len,
+ uint8_t * const p_tx_buf,
+ uint32_t * const p_tx_buf_len)
+{
+ SER_ASSERT_NOT_NULL(p_rx_buf);
+ SER_ASSERT_NOT_NULL(p_tx_buf);
+ SER_ASSERT_NOT_NULL(p_tx_buf_len);
+
+ uint16_t conn_handle;
+
+ uint8_t data[BLE_GATTS_VAR_ATTR_LEN_MAX];
+ ble_gatts_rw_authorize_reply_params_t auth_params;
+ ble_gatts_rw_authorize_reply_params_t * p_auth_params = &auth_params;
+
+ auth_params.params.read.p_data = data;
+ auth_params.params.read.len = sizeof (data);
+
+ uint32_t err_code = NRF_SUCCESS;
+ uint32_t sd_err_code;
+
+ err_code = ble_gatts_rw_authorize_reply_req_dec(p_rx_buf, rx_buf_len, &conn_handle,
+ &p_auth_params);
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code);
+
+ sd_err_code = sd_ble_gatts_rw_authorize_reply(conn_handle, p_auth_params);
+
+ err_code = ble_gatts_rw_authorize_reply_rsp_enc(sd_err_code, p_tx_buf, p_tx_buf_len);
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code);
+
+ return err_code;
+}
+
+uint32_t conn_mw_ble_gatts_sys_attr_set(uint8_t const * const p_rx_buf,
+ uint32_t rx_buf_len,
+ uint8_t * const p_tx_buf,
+ uint32_t * const p_tx_buf_len)
+{
+ SER_ASSERT_NOT_NULL(p_rx_buf);
+ SER_ASSERT_NOT_NULL(p_tx_buf);
+ SER_ASSERT_NOT_NULL(p_tx_buf_len);
+
+ uint16_t conn_handle;
+
+ uint8_t sys_attr[BLE_GATTS_VAR_ATTR_LEN_MAX];
+
+ uint8_t * p_sys_attr = sys_attr;
+ uint16_t sys_attr_len = sizeof (sys_attr);
+
+ uint32_t flags;
+
+ uint32_t err_code = NRF_SUCCESS;
+ uint32_t sd_err_code;
+
+ err_code = ble_gatts_sys_attr_set_req_dec(p_rx_buf, rx_buf_len, &conn_handle, &p_sys_attr,
+ &sys_attr_len, &flags);
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code);
+
+ sd_err_code = sd_ble_gatts_sys_attr_set(conn_handle, p_sys_attr, sys_attr_len, flags);
+
+ err_code = ble_gatts_sys_attr_set_rsp_enc(sd_err_code, p_tx_buf, p_tx_buf_len);
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code);
+
+ return err_code;
+}
+
+uint32_t conn_mw_ble_gatts_sys_attr_get(uint8_t const * const p_rx_buf,
+ uint32_t rx_buf_len,
+ uint8_t * const p_tx_buf,
+ uint32_t * const p_tx_buf_len)
+{
+ SER_ASSERT_NOT_NULL(p_rx_buf);
+ SER_ASSERT_NOT_NULL(p_tx_buf);
+ SER_ASSERT_NOT_NULL(p_tx_buf_len);
+
+ uint16_t conn_handle;
+
+ uint8_t sys_attr[BLE_GATTS_VAR_ATTR_LEN_MAX];
+
+ uint8_t * p_sys_attr = sys_attr;
+ uint16_t sys_attr_len = sizeof (sys_attr);
+ uint16_t * p_sys_attr_len = &sys_attr_len;
+
+ uint32_t flags;
+
+ uint32_t err_code = NRF_SUCCESS;
+ uint32_t sd_err_code;
+
+ err_code = ble_gatts_sys_attr_get_req_dec(p_rx_buf, rx_buf_len, &conn_handle, &p_sys_attr,
+ &p_sys_attr_len, &flags);
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code);
+
+ sd_err_code = sd_ble_gatts_sys_attr_get(conn_handle, p_sys_attr, p_sys_attr_len, flags);
+
+ err_code = ble_gatts_sys_attr_get_rsp_enc(sd_err_code, p_tx_buf, p_tx_buf_len, p_sys_attr,
+ p_sys_attr_len);
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code);
+
+ return err_code;
+}
+
+uint32_t conn_mw_ble_gatts_attr_get(uint8_t const * const p_rx_buf,
+ uint32_t rx_buf_len,
+ uint8_t * const p_tx_buf,
+ uint32_t * const p_tx_buf_len)
+{
+ SER_ASSERT_NOT_NULL(p_rx_buf);
+ SER_ASSERT_NOT_NULL(p_tx_buf);
+ SER_ASSERT_NOT_NULL(p_tx_buf_len);
+
+ uint16_t handle;
+
+ ble_gatts_attr_md_t md;
+ ble_gatts_attr_md_t * p_md = &md;
+ ble_uuid_t uuid;
+ ble_uuid_t * p_uuid = &uuid;
+
+ uint32_t err_code = NRF_SUCCESS;
+ uint32_t sd_err_code;
+
+ err_code = ble_gatts_attr_get_req_dec(p_rx_buf, rx_buf_len, &handle, &p_uuid, &p_md);
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code);
+
+ sd_err_code = sd_ble_gatts_attr_get(handle, p_uuid, p_md);
+
+ err_code = ble_gatts_attr_get_rsp_enc(sd_err_code, p_tx_buf, p_tx_buf_len, p_uuid, p_md);
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code);
+
+ return err_code;
+}
+
+uint32_t conn_mw_ble_gatts_initial_user_handle_get(uint8_t const * const p_rx_buf,
+ uint32_t rx_buf_len,
+ uint8_t * const p_tx_buf,
+ uint32_t * const p_tx_buf_len)
+{
+ SER_ASSERT_NOT_NULL(p_rx_buf);
+ SER_ASSERT_NOT_NULL(p_tx_buf);
+ SER_ASSERT_NOT_NULL(p_tx_buf_len);
+
+ uint16_t handle;
+ uint16_t * p_handle = &handle;
+
+ uint32_t err_code = NRF_SUCCESS;
+ uint32_t sd_err_code;
+
+ err_code = ble_gatts_initial_user_handle_get_req_dec(p_rx_buf, rx_buf_len, &p_handle);
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code);
+
+ sd_err_code = sd_ble_gatts_initial_user_handle_get(p_handle);
+
+ err_code = ble_gatts_initial_user_handle_get_rsp_enc(sd_err_code, p_tx_buf, p_tx_buf_len, p_handle);
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code);
+
+ return err_code;
+}
+
+uint32_t conn_mw_ble_gatts_exchange_mtu_reply(uint8_t const * const p_rx_buf,
+ uint32_t rx_buf_len,
+ uint8_t * const p_tx_buf,
+ uint32_t * const p_tx_buf_len)
+{
+ SER_ASSERT_NOT_NULL(p_rx_buf);
+ SER_ASSERT_NOT_NULL(p_tx_buf);
+ SER_ASSERT_NOT_NULL(p_tx_buf_len);
+
+ uint16_t conn_handle;
+ uint16_t * p_conn_handle = &conn_handle;
+ uint16_t server_rx_mtu;
+ uint16_t * p_server_rx_mtu = &server_rx_mtu;
+
+ uint32_t err_code = NRF_SUCCESS;
+ uint32_t sd_err_code;
+
+ err_code = ble_gatts_exchange_mtu_reply_req_dec(p_rx_buf, rx_buf_len, p_conn_handle, p_server_rx_mtu);
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code);
+
+ sd_err_code = sd_ble_gatts_exchange_mtu_reply(conn_handle, server_rx_mtu);
+
+ err_code = ble_gatts_exchange_mtu_reply_rsp_enc(sd_err_code, p_tx_buf, p_tx_buf_len);
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code);
+
+ return err_code;
+}
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/connectivity/codecs/ble/middleware/conn_mw_ble_gatts.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/connectivity/codecs/ble/middleware/conn_mw_ble_gatts.h
new file mode 100644
index 0000000..d10609c
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/connectivity/codecs/ble/middleware/conn_mw_ble_gatts.h
@@ -0,0 +1,314 @@
+/**
+ * Copyright (c) 2014 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#ifndef _CONN_MW_BLE_GATTS_H
+#define _CONN_MW_BLE_GATTS_H
+
+#include <stdint.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @addtogroup sercon_mw_s132_ble_gatts GATTS Middleware command handlers
+ * @{
+ * @ingroup sercon_mw_s132
+ */
+
+/**@brief Handles @ref sd_ble_gatts_service_add command and prepares response.
+ *
+ * @param[in] p_rx_buf Pointer to input buffer.
+ * @param[in] rx_buf_len Size of @p p_rx_buf.
+ * @param[out] p_tx_buf Pointer to output buffer.
+ * @param[in,out] p_tx_buf_len \c in: Size of \p p_tx_buf buffer.
+ * \c out: Length of valid data in \p p_tx_buf.
+ *
+ * @retval NRF_SUCCESS Handler success.
+ * @retval NRF_ERROR_NULL Handler failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Handler failure. Incorrect buffer length.
+ * @retval NRF_ERROR_INVALID_PARAM Handler failure. Invalid operation type.
+ */
+uint32_t conn_mw_ble_gatts_service_add (uint8_t const * const p_rx_buf,
+ uint32_t rx_buf_len,
+ uint8_t * const p_tx_buf,
+ uint32_t * const p_tx_buf_len);
+
+/**@brief Handles @ref sd_ble_gatts_characteristic_add command and prepares response.
+ *
+ * @param[in] p_rx_buf Pointer to input buffer.
+ * @param[in] rx_buf_len Size of @p p_rx_buf.
+ * @param[out] p_tx_buf Pointer to output buffer.
+ * @param[in,out] p_tx_buf_len \c in: Size of \p p_tx_buf buffer.
+ * \c out: Length of valid data in \p p_tx_buf.
+ *
+ * @retval NRF_SUCCESS Handler success.
+ * @retval NRF_ERROR_NULL Handler failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Handler failure. Incorrect buffer length.
+ * @retval NRF_ERROR_INVALID_PARAM Handler failure. Invalid operation type.
+ */
+uint32_t conn_mw_ble_gatts_characteristic_add(uint8_t const * const p_rx_buf,
+ uint32_t rx_buf_len,
+ uint8_t * const p_tx_buf,
+ uint32_t * const p_tx_buf_len);
+
+/**@brief Handles @ref conn_mw_ble_gatts_include_add command and prepares response.
+ *
+ * @param[in] p_rx_buf Pointer to input buffer.
+ * @param[in] rx_buf_len Size of @p p_rx_buf.
+ * @param[out] p_tx_buf Pointer to output buffer.
+ * @param[in,out] p_tx_buf_len \c in: Size of \p p_tx_buf buffer.
+ * \c out: Length of valid data in \p p_tx_buf.
+ *
+ * @retval NRF_SUCCESS Handler success.
+ * @retval NRF_ERROR_NULL Handler failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Handler failure. Incorrect buffer length.
+ * @retval NRF_ERROR_INVALID_PARAM Handler failure. Invalid operation type.
+ */
+uint32_t conn_mw_ble_gatts_include_add (uint8_t const * const p_rx_buf,
+ uint32_t rx_buf_len,
+ uint8_t * const p_tx_buf,
+ uint32_t * const p_tx_buf_len);
+
+/**@brief Handles @ref conn_mw_ble_gatts_descriptor_add command and prepares response.
+ *
+ * @param[in] p_rx_buf Pointer to input buffer.
+ * @param[in] rx_buf_len Size of @p p_rx_buf.
+ * @param[out] p_tx_buf Pointer to output buffer.
+ * @param[in,out] p_tx_buf_len \c in: Size of \p p_tx_buf buffer.
+ * \c out: Length of valid data in \p p_tx_buf.
+ *
+ * @retval NRF_SUCCESS Handler success.
+ * @retval NRF_ERROR_NULL Handler failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Handler failure. Incorrect buffer length.
+ * @retval NRF_ERROR_INVALID_PARAM Handler failure. Invalid operation type.
+ */
+uint32_t conn_mw_ble_gatts_descriptor_add(uint8_t const * const p_rx_buf,
+ uint32_t rx_buf_len,
+ uint8_t * const p_tx_buf,
+ uint32_t * const p_tx_buf_len);
+
+/**@brief Handles @ref conn_mw_ble_gatts_value_set command and prepares response.
+ *
+ * @param[in] p_rx_buf Pointer to input buffer.
+ * @param[in] rx_buf_len Size of @p p_rx_buf.
+ * @param[out] p_tx_buf Pointer to output buffer.
+ * @param[in,out] p_tx_buf_len \c in: Size of \p p_tx_buf buffer.
+ * \c out: Length of valid data in \p p_tx_buf.
+ *
+ * @retval NRF_SUCCESS Handler success.
+ * @retval NRF_ERROR_NULL Handler failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Handler failure. Incorrect buffer length.
+ * @retval NRF_ERROR_INVALID_PARAM Handler failure. Invalid operation type.
+ */
+uint32_t conn_mw_ble_gatts_value_set(uint8_t const * const p_rx_buf,
+ uint32_t rx_buf_len,
+ uint8_t * const p_tx_buf,
+ uint32_t * const p_tx_buf_len);
+
+/**@brief Handles @ref conn_mw_ble_gatts_value_get command and prepares response.
+ *
+ * @param[in] p_rx_buf Pointer to input buffer.
+ * @param[in] rx_buf_len Size of @p p_rx_buf.
+ * @param[out] p_tx_buf Pointer to output buffer.
+ * @param[in,out] p_tx_buf_len \c in: Size of \p p_tx_buf buffer.
+ * \c out: Length of valid data in \p p_tx_buf.
+ *
+ * @retval NRF_SUCCESS Handler success.
+ * @retval NRF_ERROR_NULL Handler failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Handler failure. Incorrect buffer length.
+ * @retval NRF_ERROR_INVALID_PARAM Handler failure. Invalid operation type.
+ */
+uint32_t conn_mw_ble_gatts_value_get(uint8_t const * const p_rx_buf,
+ uint32_t rx_buf_len,
+ uint8_t * const p_tx_buf,
+ uint32_t * const p_tx_buf_len);
+
+/**@brief Handles @ref conn_mw_ble_gatts_hvx command and prepares response.
+ *
+ * @param[in] p_rx_buf Pointer to input buffer.
+ * @param[in] rx_buf_len Size of @p p_rx_buf.
+ * @param[out] p_tx_buf Pointer to output buffer.
+ * @param[in,out] p_tx_buf_len \c in: Size of \p p_tx_buf buffer.
+ * \c out: Length of valid data in \p p_tx_buf.
+ *
+ * @retval NRF_SUCCESS Handler success.
+ * @retval NRF_ERROR_NULL Handler failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Handler failure. Incorrect buffer length.
+ * @retval NRF_ERROR_INVALID_PARAM Handler failure. Invalid operation type.
+ */
+uint32_t conn_mw_ble_gatts_hvx(uint8_t const * const p_rx_buf,
+ uint32_t rx_buf_len,
+ uint8_t * const p_tx_buf,
+ uint32_t * const p_tx_buf_len);
+
+/**@brief Handles @ref conn_mw_ble_gatts_service_changed command and prepares response.
+ *
+ * @param[in] p_rx_buf Pointer to input buffer.
+ * @param[in] rx_buf_len Size of @p p_rx_buf.
+ * @param[out] p_tx_buf Pointer to output buffer.
+ * @param[in,out] p_tx_buf_len \c in: Size of \p p_tx_buf buffer.
+ * \c out: Length of valid data in \p p_tx_buf.
+ *
+ * @retval NRF_SUCCESS Handler success.
+ * @retval NRF_ERROR_NULL Handler failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Handler failure. Incorrect buffer length.
+ * @retval NRF_ERROR_INVALID_PARAM Handler failure. Invalid operation type.
+ */
+uint32_t conn_mw_ble_gatts_service_changed(uint8_t const * const p_rx_buf,
+ uint32_t rx_buf_len,
+ uint8_t * const p_tx_buf,
+ uint32_t * const p_tx_buf_len);
+
+/**@brief Handles @ref conn_mw_ble_gatts_rw_authorize_reply command and prepares response.
+ *
+ * @param[in] p_rx_buf Pointer to input buffer.
+ * @param[in] rx_buf_len Size of @p p_rx_buf.
+ * @param[out] p_tx_buf Pointer to output buffer.
+ * @param[in,out] p_tx_buf_len \c in: Size of \p p_tx_buf buffer.
+ * \c out: Length of valid data in \p p_tx_buf.
+ *
+ * @retval NRF_SUCCESS Handler success.
+ * @retval NRF_ERROR_NULL Handler failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Handler failure. Incorrect buffer length.
+ * @retval NRF_ERROR_INVALID_PARAM Handler failure. Invalid operation type.
+ */
+uint32_t conn_mw_ble_gatts_rw_authorize_reply(uint8_t const * const p_rx_buf,
+ uint32_t rx_buf_len,
+ uint8_t * const p_tx_buf,
+ uint32_t * const p_tx_buf_len);
+
+/**@brief Handles @ref conn_mw_ble_gatts_sys_attr_set command and prepares response.
+ *
+ * @param[in] p_rx_buf Pointer to input buffer.
+ * @param[in] rx_buf_len Size of @p p_rx_buf.
+ * @param[out] p_tx_buf Pointer to output buffer.
+ * @param[in,out] p_tx_buf_len \c in: Size of \p p_tx_buf buffer.
+ * \c out: Length of valid data in \p p_tx_buf.
+ *
+ * @retval NRF_SUCCESS Handler success.
+ * @retval NRF_ERROR_NULL Handler failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Handler failure. Incorrect buffer length.
+ * @retval NRF_ERROR_INVALID_PARAM Handler failure. Invalid operation type.
+ */
+uint32_t conn_mw_ble_gatts_sys_attr_set(uint8_t const * const p_rx_buf,
+ uint32_t rx_buf_len,
+ uint8_t * const p_tx_buf,
+ uint32_t * const p_tx_buf_len);
+
+/**@brief Handles @ref conn_mw_ble_gatts_sys_attr_get command and prepares response.
+ *
+ * @param[in] p_rx_buf Pointer to input buffer.
+ * @param[in] rx_buf_len Size of @p p_rx_buf.
+ * @param[out] p_tx_buf Pointer to output buffer.
+ * @param[in,out] p_tx_buf_len \c in: Size of \p p_tx_buf buffer.
+ * \c out: Length of valid data in \p p_tx_buf.
+ *
+ * @retval NRF_SUCCESS Handler success.
+ * @retval NRF_ERROR_NULL Handler failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Handler failure. Incorrect buffer length.
+ * @retval NRF_ERROR_INVALID_PARAM Handler failure. Invalid operation type.
+ */
+uint32_t conn_mw_ble_gatts_sys_attr_get(uint8_t const * const p_rx_buf,
+ uint32_t rx_buf_len,
+ uint8_t * const p_tx_buf,
+ uint32_t * const p_tx_buf_len);
+
+/**@brief Handles @ref conn_mw_ble_gatts_attr_get command and prepares response.
+ *
+ * @param[in] p_rx_buf Pointer to input buffer.
+ * @param[in] rx_buf_len Size of @p p_rx_buf.
+ * @param[out] p_tx_buf Pointer to output buffer.
+ * @param[in,out] p_tx_buf_len \c in: Size of \p p_tx_buf buffer.
+ * \c out: Length of valid data in \p p_tx_buf.
+ *
+ * @retval NRF_SUCCESS Handler success.
+ * @retval NRF_ERROR_NULL Handler failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Handler failure. Incorrect buffer length.
+ * @retval NRF_ERROR_INVALID_PARAM Handler failure. Invalid operation type.
+ */
+uint32_t conn_mw_ble_gatts_attr_get(uint8_t const * const p_rx_buf,
+ uint32_t rx_buf_len,
+ uint8_t * const p_tx_buf,
+ uint32_t * const p_tx_buf_len);
+
+/**@brief Handles @ref conn_mw_ble_gatts_initial_user_handle_get command and prepares response.
+ *
+ * @param[in] p_rx_buf Pointer to input buffer.
+ * @param[in] rx_buf_len Size of @p p_rx_buf.
+ * @param[out] p_tx_buf Pointer to output buffer.
+ * @param[in,out] p_tx_buf_len \c in: Size of \p p_tx_buf buffer.
+ * \c out: Length of valid data in \p p_tx_buf.
+ *
+ * @retval NRF_SUCCESS Handler success.
+ * @retval NRF_ERROR_NULL Handler failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Handler failure. Incorrect buffer length.
+ * @retval NRF_ERROR_INVALID_PARAM Handler failure. Invalid operation type.
+ */
+uint32_t conn_mw_ble_gatts_initial_user_handle_get(uint8_t const * const p_rx_buf,
+ uint32_t rx_buf_len,
+ uint8_t * const p_tx_buf,
+ uint32_t * const p_tx_buf_len);
+
+/**@brief Handles @ref conn_mw_ble_gatts_exchange_mtu_reply command and prepares response.
+ *
+ * @param[in] p_rx_buf Pointer to input buffer.
+ * @param[in] rx_buf_len Size of @p p_rx_buf.
+ * @param[out] p_tx_buf Pointer to output buffer.
+ * @param[in,out] p_tx_buf_len \c in: Size of \p p_tx_buf buffer.
+ * \c out: Length of valid data in \p p_tx_buf.
+ *
+ * @retval NRF_SUCCESS Handler success.
+ * @retval NRF_ERROR_NULL Handler failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Handler failure. Incorrect buffer length.
+ * @retval NRF_ERROR_INVALID_PARAM Handler failure. Invalid operation type.
+ */
+uint32_t conn_mw_ble_gatts_exchange_mtu_reply(uint8_t const * const p_rx_buf,
+ uint32_t rx_buf_len,
+ uint8_t * const p_tx_buf,
+ uint32_t * const p_tx_buf_len);
+
+/** @} */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif //_CONN_MW_BLE_GATTS_H
+
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/connectivity/codecs/ble/middleware/conn_mw_ble_l2cap.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/connectivity/codecs/ble/middleware/conn_mw_ble_l2cap.c
new file mode 100644
index 0000000..8a88ceb
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/connectivity/codecs/ble/middleware/conn_mw_ble_l2cap.c
@@ -0,0 +1,260 @@
+/**
+ * Copyright (c) 2014 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#include "ble_l2cap_conn.h"
+#include "conn_mw_ble_l2cap.h"
+#include "ble_serialization.h"
+
+#if defined(NRF_SD_BLE_API_VERSION) && NRF_SD_BLE_API_VERSION < 4
+uint32_t conn_mw_ble_l2cap_cid_register(uint8_t const * const p_rx_buf,
+ uint32_t rx_buf_len,
+ uint8_t * const p_tx_buf,
+ uint32_t * const p_tx_buf_len)
+{
+ SER_ASSERT_NOT_NULL(p_rx_buf);
+ SER_ASSERT_NOT_NULL(p_tx_buf);
+ SER_ASSERT_NOT_NULL(p_tx_buf_len);
+
+ uint16_t cid;
+
+ uint32_t err_code = NRF_SUCCESS;
+ uint32_t sd_err_code;
+
+ err_code = ble_l2cap_cid_register_req_dec(p_rx_buf, rx_buf_len, &cid);
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code);
+
+ sd_err_code = sd_ble_l2cap_cid_register(cid);
+
+ err_code = ble_l2cap_cid_register_rsp_enc(sd_err_code, p_tx_buf, p_tx_buf_len);
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code);
+
+ return err_code;
+}
+
+uint32_t conn_mw_ble_l2cap_cid_unregister(uint8_t const * const p_rx_buf,
+ uint32_t rx_buf_len,
+ uint8_t * const p_tx_buf,
+ uint32_t * const p_tx_buf_len)
+{
+ SER_ASSERT_NOT_NULL(p_rx_buf);
+ SER_ASSERT_NOT_NULL(p_tx_buf);
+ SER_ASSERT_NOT_NULL(p_tx_buf_len);
+
+ uint16_t cid;
+
+ uint32_t err_code = NRF_SUCCESS;
+ uint32_t sd_err_code;
+
+ err_code = ble_l2cap_cid_unregister_req_dec(p_rx_buf, rx_buf_len, &cid);
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code);
+
+ sd_err_code = sd_ble_l2cap_cid_unregister(cid);
+
+ err_code = ble_l2cap_cid_unregister_rsp_enc(sd_err_code, p_tx_buf, p_tx_buf_len);
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code);
+
+ return err_code;
+}
+
+uint32_t conn_mw_ble_l2cap_tx(uint8_t const * const p_rx_buf,
+ uint32_t rx_buf_len,
+ uint8_t * const p_tx_buf,
+ uint32_t * const p_tx_buf_len)
+{
+ SER_ASSERT_NOT_NULL(p_rx_buf);
+ SER_ASSERT_NOT_NULL(p_tx_buf);
+ SER_ASSERT_NOT_NULL(p_tx_buf_len);
+
+ uint16_t conn_handle;
+ ble_l2cap_header_t l2cap_header;
+ ble_l2cap_header_t * p_l2cap_header = &l2cap_header;
+ uint32_t err_code = NRF_SUCCESS;
+ uint32_t sd_err_code;
+ uint8_t const * p_data = NULL;
+
+ err_code = ble_l2cap_tx_req_dec(p_rx_buf, rx_buf_len, &conn_handle, &p_l2cap_header, &p_data);
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code);
+
+ sd_err_code = sd_ble_l2cap_tx(conn_handle, p_l2cap_header, p_data);
+
+ err_code = ble_l2cap_tx_rsp_enc(sd_err_code, p_tx_buf, p_tx_buf_len);
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code);
+
+ return err_code;
+}
+#endif
+
+#if NRF_SD_BLE_API_VERSION >= 5
+uint32_t conn_mw_l2cap_ch_setup(uint8_t const * const p_rx_buf,
+ uint32_t rx_buf_len,
+ uint8_t * const p_tx_buf,
+ uint32_t * const p_tx_buf_len)
+{
+ SER_ASSERT_NOT_NULL(p_rx_buf);
+ SER_ASSERT_NOT_NULL(p_tx_buf);
+ SER_ASSERT_NOT_NULL(p_tx_buf_len);
+
+ uint16_t conn_handle;
+ uint16_t local_cid;
+ uint16_t * p_local_cid = &local_cid;
+ ble_l2cap_ch_setup_params_t params;
+ ble_l2cap_ch_setup_params_t * p_params = &params;
+ uint32_t sd_err_code;
+ uint32_t err_code = NRF_SUCCESS;
+
+ err_code = ble_l2cap_ch_setup_req_dec(p_rx_buf, rx_buf_len, &conn_handle, &p_local_cid, &p_params);
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code);
+
+ sd_err_code = sd_ble_l2cap_ch_setup(conn_handle, p_local_cid, p_params);
+
+ err_code = ble_l2cap_ch_setup_rsp_enc(sd_err_code, p_tx_buf, p_tx_buf_len, p_local_cid);
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code);
+
+ return err_code;
+}
+
+uint32_t conn_mw_l2cap_ch_release(uint8_t const * const p_rx_buf,
+ uint32_t rx_buf_len,
+ uint8_t * const p_tx_buf,
+ uint32_t * const p_tx_buf_len)
+{
+ SER_ASSERT_NOT_NULL(p_rx_buf);
+ SER_ASSERT_NOT_NULL(p_tx_buf);
+ SER_ASSERT_NOT_NULL(p_tx_buf_len);
+
+ uint16_t conn_handle;
+ uint16_t local_cid;
+ uint32_t sd_err_code;
+ uint32_t err_code = NRF_SUCCESS;
+
+ err_code = ble_l2cap_ch_release_req_dec(p_rx_buf, rx_buf_len, &conn_handle, &local_cid);
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code);
+
+ sd_err_code = sd_ble_l2cap_ch_release(conn_handle, local_cid);
+
+ err_code = ble_l2cap_ch_release_rsp_enc(sd_err_code, p_tx_buf, p_tx_buf_len);
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code);
+
+ return err_code;
+}
+
+uint32_t conn_mw_l2cap_ch_rx(uint8_t const * const p_rx_buf,
+ uint32_t rx_buf_len,
+ uint8_t * const p_tx_buf,
+ uint32_t * const p_tx_buf_len)
+{
+ SER_ASSERT_NOT_NULL(p_rx_buf);
+ SER_ASSERT_NOT_NULL(p_tx_buf);
+ SER_ASSERT_NOT_NULL(p_tx_buf_len);
+
+ uint16_t conn_handle;
+ uint16_t local_cid;
+ ble_data_t ble_data;
+ ble_data_t * p_ble_data = &ble_data;
+ uint32_t sd_err_code;
+ uint32_t err_code = NRF_SUCCESS;
+
+ err_code = ble_l2cap_ch_rx_req_dec(p_rx_buf, rx_buf_len, &conn_handle, &local_cid, &p_ble_data);
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code);
+
+ sd_err_code = sd_ble_l2cap_ch_rx(conn_handle, local_cid, p_ble_data);
+
+ err_code = ble_l2cap_ch_rx_rsp_enc(sd_err_code, p_tx_buf, p_tx_buf_len);
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code);
+
+ return err_code;
+}
+
+uint32_t conn_mw_l2cap_ch_tx(uint8_t const * const p_rx_buf,
+ uint32_t rx_buf_len,
+ uint8_t * const p_tx_buf,
+ uint32_t * const p_tx_buf_len)
+{
+ SER_ASSERT_NOT_NULL(p_rx_buf);
+ SER_ASSERT_NOT_NULL(p_tx_buf);
+ SER_ASSERT_NOT_NULL(p_tx_buf_len);
+
+ uint16_t conn_handle;
+ uint16_t local_cid;
+ ble_data_t ble_data;
+ ble_data_t * p_ble_data = &ble_data;
+ uint32_t sd_err_code;
+ uint32_t err_code = NRF_SUCCESS;
+
+ err_code = ble_l2cap_ch_tx_req_dec(p_rx_buf, rx_buf_len, &conn_handle, &local_cid, &p_ble_data);
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code);
+
+ sd_err_code = sd_ble_l2cap_ch_tx(conn_handle, local_cid, p_ble_data);
+
+ err_code = ble_l2cap_ch_tx_rsp_enc(sd_err_code, p_tx_buf, p_tx_buf_len);
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code);
+
+ return err_code;
+}
+
+uint32_t conn_mw_l2cap_ch_flow_control(uint8_t const * const p_rx_buf,
+ uint32_t rx_buf_len,
+ uint8_t * const p_tx_buf,
+ uint32_t * const p_tx_buf_len)
+{
+ SER_ASSERT_NOT_NULL(p_rx_buf);
+ SER_ASSERT_NOT_NULL(p_tx_buf);
+ SER_ASSERT_NOT_NULL(p_tx_buf_len);
+
+ uint16_t conn_handle;
+ uint16_t local_cid;
+ uint16_t credits;
+ uint16_t out_credits;
+ uint16_t * p_out_credits = &out_credits;
+ uint32_t sd_err_code;
+ uint32_t err_code = NRF_SUCCESS;
+
+ err_code = ble_l2cap_ch_flow_control_req_dec(p_rx_buf, rx_buf_len,
+ &conn_handle, &local_cid, &credits, &p_out_credits);
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code);
+
+ sd_err_code = sd_ble_l2cap_ch_flow_control(conn_handle, local_cid, credits, p_out_credits);
+
+ err_code = ble_l2cap_ch_flow_control_rsp_enc(sd_err_code, p_tx_buf, p_tx_buf_len, p_out_credits);
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code);
+
+ return err_code;
+}
+
+#endif
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/connectivity/codecs/ble/middleware/conn_mw_ble_l2cap.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/connectivity/codecs/ble/middleware/conn_mw_ble_l2cap.h
new file mode 100644
index 0000000..76e2149
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/connectivity/codecs/ble/middleware/conn_mw_ble_l2cap.h
@@ -0,0 +1,206 @@
+/**
+ * Copyright (c) 2014 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#ifndef _CONN_MW_BLE_L2CAP_H_
+#define _CONN_MW_BLE_L2CAP_H_
+
+#include <stdint.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @addtogroup sercon_mw_s132_ble_l2cap L2CAP Middleware command handlers
+ * @{
+ * @ingroup sercon_mw_s132
+ */
+
+/**@brief Handles sd_ble_l2cap_cid_register command and prepares response.
+ *
+ * @param[in] p_rx_buf Pointer to input buffer.
+ * @param[in] rx_buf_len Size of @p p_rx_buf.
+ * @param[out] p_tx_buf Pointer to output buffer.
+ * @param[in,out] p_tx_buf_len \c in: Size of \p p_tx_buf buffer.
+ * \c out: Length of valid data in \p p_tx_buf.
+ *
+ * @retval NRF_SUCCESS Handler success.
+ * @retval NRF_ERROR_NULL Handler failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Handler failure. Incorrect buffer length.
+ * @retval NRF_ERROR_INVALID_PARAM Handler failure. Invalid operation type.
+ */
+uint32_t conn_mw_ble_l2cap_cid_register(uint8_t const * const p_rx_buf,
+ uint32_t rx_buf_len,
+ uint8_t * const p_tx_buf,
+ uint32_t * const p_tx_buf_len);
+
+/**@brief Handles sd_ble_l2cap_cid_unregister command and prepares response.
+ *
+ * @param[in] p_rx_buf Pointer to input buffer.
+ * @param[in] rx_buf_len Size of @p p_rx_buf.
+ * @param[out] p_tx_buf Pointer to output buffer.
+ * @param[in,out] p_tx_buf_len \c in: Size of \p p_tx_buf buffer.
+ * \c out: Length of valid data in \p p_tx_buf.
+ *
+ * @retval NRF_SUCCESS Handler success.
+ * @retval NRF_ERROR_NULL Handler failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Handler failure. Incorrect buffer length.
+ * @retval NRF_ERROR_INVALID_PARAM Handler failure. Invalid operation type.
+ */
+uint32_t conn_mw_ble_l2cap_cid_unregister(uint8_t const * const p_rx_buf,
+ uint32_t rx_buf_len,
+ uint8_t * const p_tx_buf,
+ uint32_t * const p_tx_buf_len);
+
+/**@brief Handles sd_ble_l2cap_tx command and prepares response.
+ *
+ * @param[in] p_rx_buf Pointer to input buffer.
+ * @param[in] rx_buf_len Size of @p p_rx_buf.
+ * @param[out] p_tx_buf Pointer to output buffer.
+ * @param[in,out] p_tx_buf_len \c in: Size of \p p_tx_buf buffer.
+ * \c out: Length of valid data in \p p_tx_buf.
+ *
+ * @retval NRF_SUCCESS Handler success.
+ * @retval NRF_ERROR_NULL Handler failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Handler failure. Incorrect buffer length.
+ * @retval NRF_ERROR_INVALID_PARAM Handler failure. Invalid operation type.
+ */
+uint32_t conn_mw_ble_l2cap_tx(uint8_t const * const p_rx_buf,
+ uint32_t rx_buf_len,
+ uint8_t * const p_tx_buf,
+ uint32_t * const p_tx_buf_len);
+
+
+/**@brief Handles sd_ble_l2cap_ch_setup command and prepares response.
+ *
+ * @param[in] p_rx_buf Pointer to input buffer.
+ * @param[in] rx_buf_len Size of @p p_rx_buf.
+ * @param[out] p_tx_buf Pointer to output buffer.
+ * @param[in,out] p_tx_buf_len \c in: Size of \p p_tx_buf buffer.
+ * \c out: Length of valid data in \p p_tx_buf.
+ *
+ * @retval NRF_SUCCESS Handler success.
+ * @retval NRF_ERROR_NULL Handler failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Handler failure. Incorrect buffer length.
+ * @retval NRF_ERROR_INVALID_PARAM Handler failure. Invalid operation type.
+ */
+uint32_t conn_mw_l2cap_ch_setup(uint8_t const * const p_rx_buf,
+ uint32_t rx_buf_len,
+ uint8_t * const p_tx_buf,
+ uint32_t * const p_tx_buf_len);
+
+/**@brief Handles sd_ble_l2cap_ch_release command and prepares response.
+ *
+ * @param[in] p_rx_buf Pointer to input buffer.
+ * @param[in] rx_buf_len Size of @p p_rx_buf.
+ * @param[out] p_tx_buf Pointer to output buffer.
+ * @param[in,out] p_tx_buf_len \c in: Size of \p p_tx_buf buffer.
+ * \c out: Length of valid data in \p p_tx_buf.
+ *
+ * @retval NRF_SUCCESS Handler success.
+ * @retval NRF_ERROR_NULL Handler failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Handler failure. Incorrect buffer length.
+ * @retval NRF_ERROR_INVALID_PARAM Handler failure. Invalid operation type.
+ */
+uint32_t conn_mw_l2cap_ch_release(uint8_t const * const p_rx_buf,
+ uint32_t rx_buf_len,
+ uint8_t * const p_tx_buf,
+ uint32_t * const p_tx_buf_len);
+
+/**@brief Handles sd_ble_l2cap_ch_rx command and prepares response.
+ *
+ * @param[in] p_rx_buf Pointer to input buffer.
+ * @param[in] rx_buf_len Size of @p p_rx_buf.
+ * @param[out] p_tx_buf Pointer to output buffer.
+ * @param[in,out] p_tx_buf_len \c in: Size of \p p_tx_buf buffer.
+ * \c out: Length of valid data in \p p_tx_buf.
+ *
+ * @retval NRF_SUCCESS Handler success.
+ * @retval NRF_ERROR_NULL Handler failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Handler failure. Incorrect buffer length.
+ * @retval NRF_ERROR_INVALID_PARAM Handler failure. Invalid operation type.
+ */
+uint32_t conn_mw_l2cap_ch_rx(uint8_t const * const p_rx_buf,
+ uint32_t rx_buf_len,
+ uint8_t * const p_tx_buf,
+ uint32_t * const p_tx_buf_len);
+
+/**@brief Handles sd_ble_l2cap_ch_tx command and prepares response.
+ *
+ * @param[in] p_rx_buf Pointer to input buffer.
+ * @param[in] rx_buf_len Size of @p p_rx_buf.
+ * @param[out] p_tx_buf Pointer to output buffer.
+ * @param[in,out] p_tx_buf_len \c in: Size of \p p_tx_buf buffer.
+ * \c out: Length of valid data in \p p_tx_buf.
+ *
+ * @retval NRF_SUCCESS Handler success.
+ * @retval NRF_ERROR_NULL Handler failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Handler failure. Incorrect buffer length.
+ * @retval NRF_ERROR_INVALID_PARAM Handler failure. Invalid operation type.
+ */
+uint32_t conn_mw_l2cap_ch_tx(uint8_t const * const p_rx_buf,
+ uint32_t rx_buf_len,
+ uint8_t * const p_tx_buf,
+ uint32_t * const p_tx_buf_len);
+
+/**@brief Handles sd_ble_l2cap_ch_flow_control command and prepares response.
+ *
+ * @param[in] p_rx_buf Pointer to input buffer.
+ * @param[in] rx_buf_len Size of @p p_rx_buf.
+ * @param[out] p_tx_buf Pointer to output buffer.
+ * @param[in,out] p_tx_buf_len \c in: Size of \p p_tx_buf buffer.
+ * \c out: Length of valid data in \p p_tx_buf.
+ *
+ * @retval NRF_SUCCESS Handler success.
+ * @retval NRF_ERROR_NULL Handler failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Handler failure. Incorrect buffer length.
+ * @retval NRF_ERROR_INVALID_PARAM Handler failure. Invalid operation type.
+ */
+uint32_t conn_mw_l2cap_ch_flow_control(uint8_t const * const p_rx_buf,
+ uint32_t rx_buf_len,
+ uint8_t * const p_tx_buf,
+ uint32_t * const p_tx_buf_len);
+
+/** @} */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/connectivity/codecs/ble/serializers/ble_conn.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/connectivity/codecs/ble/serializers/ble_conn.c
new file mode 100644
index 0000000..a952886
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/connectivity/codecs/ble/serializers/ble_conn.c
@@ -0,0 +1,558 @@
+/**
+ * Copyright (c) 2014 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#include <string.h>
+#include "ble_conn.h"
+#include "ble_serialization.h"
+#include "cond_field_serialization.h"
+#include "ble_struct_serialization.h"
+#include "ble_gap_struct_serialization.h"
+#include "ble_gatt_struct_serialization.h"
+#include "ble_gattc_struct_serialization.h"
+#include "ble_gatts_struct_serialization.h"
+#include "ble_l2cap_struct_serialization.h"
+#include "app_util.h"
+
+#if defined(NRF_SD_BLE_API_VERSION) && NRF_SD_BLE_API_VERSION < 4
+uint32_t ble_enable_req_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ ble_enable_params_t * * const pp_ble_enable_params)
+{
+ SER_REQ_DEC_BEGIN(SD_BLE_ENABLE);
+ SER_PULL_COND(pp_ble_enable_params, ble_enable_params_t_dec);
+ SER_REQ_DEC_END;
+}
+#else
+uint32_t ble_enable_req_dec(uint8_t const * const p_buf,
+ uint32_t packet_len)
+{
+ SER_REQ_DEC_BEGIN(SD_BLE_ENABLE);
+ SER_REQ_DEC_END;
+}
+#endif
+
+uint32_t ble_enable_rsp_enc(uint32_t return_code,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len)
+{
+ SER_RSP_ENC_RESULT_ONLY(SD_BLE_ENABLE);
+}
+
+
+uint32_t ble_opt_get_req_dec(uint8_t const * const p_buf,
+ uint16_t packet_len,
+ uint32_t * const p_opt_id,
+ ble_opt_t **const pp_opt )
+{
+ SER_REQ_DEC_BEGIN(SD_BLE_OPT_GET);
+
+ SER_ASSERT_NOT_NULL(p_opt_id);
+ SER_ASSERT_NOT_NULL(pp_opt);
+ SER_ASSERT_NOT_NULL(*pp_opt);
+
+ SER_PULL_uint32(p_opt_id);
+
+ SER_PULL_COND(pp_opt, NULL);
+
+ SER_REQ_DEC_END;
+}
+
+
+uint32_t ble_opt_get_rsp_enc(uint32_t return_code,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len,
+ uint32_t opt_id,
+ ble_opt_t const * const p_opt)
+{
+ SER_RSP_ENC_BEGIN(SD_BLE_OPT_GET);
+
+ SER_ASSERT_NOT_NULL(p_opt);
+
+ SER_PUSH_uint32(&opt_id);
+
+ field_encoder_handler_t fp_encoder = NULL;
+ void const * p_struct = NULL;
+
+ switch (opt_id)
+ {
+#if defined(NRF_SD_BLE_API_VERSION) && NRF_SD_BLE_API_VERSION < 4
+ case BLE_COMMON_OPT_CONN_BW:
+ fp_encoder = ble_common_opt_conn_bw_t_enc;
+ p_struct = &p_opt->common_opt.conn_bw;
+ break;
+#endif
+ case BLE_COMMON_OPT_PA_LNA:
+ fp_encoder = ble_common_opt_pa_lna_t_enc;
+ p_struct = &p_opt->common_opt.pa_lna;
+ break;
+ case BLE_COMMON_OPT_CONN_EVT_EXT:
+ fp_encoder = ble_common_opt_conn_evt_ext_t_enc;
+ p_struct = &p_opt->common_opt.conn_evt_ext;
+ break;
+ case BLE_GAP_OPT_CH_MAP:
+ fp_encoder = ble_gap_opt_ch_map_t_enc;
+ p_struct = &p_opt->gap_opt.ch_map;
+ break;
+ case BLE_GAP_OPT_LOCAL_CONN_LATENCY:
+ fp_encoder = ble_gap_opt_local_conn_latency_t_enc;
+ p_struct = &p_opt->gap_opt.local_conn_latency;
+ break;
+ case BLE_GAP_OPT_PASSKEY:
+ fp_encoder = ble_gap_opt_passkey_t_enc;
+ p_struct = &p_opt->gap_opt.passkey;
+ break;
+ case BLE_GAP_OPT_AUTH_PAYLOAD_TIMEOUT:
+ fp_encoder = ble_gap_opt_auth_payload_timeout_t_enc;
+ p_struct = &p_opt->gap_opt.auth_payload_timeout;
+ break;
+#if defined(NRF_SD_BLE_API_VERSION) && NRF_SD_BLE_API_VERSION < 4
+ case BLE_GAP_OPT_EXT_LEN:
+ fp_encoder = ble_gap_opt_ext_len_t_enc;
+ p_struct = &p_opt->gap_opt.ext_len;
+ break;
+#endif
+#if defined(NRF_SD_BLE_API_VERSION) && NRF_SD_BLE_API_VERSION < 6
+ case BLE_GAP_OPT_SCAN_REQ_REPORT:
+ fp_encoder = ble_gap_opt_scan_req_report_t_enc;
+ p_struct = &p_opt->gap_opt.scan_req_report;
+ break;
+#endif
+#if defined(NRF_SD_BLE_API_VERSION) && NRF_SD_BLE_API_VERSION < 4
+ case BLE_GAP_OPT_COMPAT_MODE:
+ fp_encoder = ble_gap_opt_compat_mode_t_enc;
+ p_struct = &p_opt->gap_opt.compat_mode;
+ break;
+#else
+#ifndef S112
+ case BLE_GAP_OPT_COMPAT_MODE_1:
+ fp_encoder = ble_gap_opt_compat_mode_1_t_enc;
+ p_struct = &p_opt->gap_opt.compat_mode_1;
+ break;
+#endif
+#endif
+#if defined(NRF_SD_BLE_API_VERSION) && NRF_SD_BLE_API_VERSION == 4
+ case BLE_GAP_OPT_COMPAT_MODE_2:
+ fp_encoder = ble_gap_opt_compat_mode_2_t_enc;
+ p_struct = &p_opt->gap_opt.compat_mode_2;
+ break;
+#endif
+ default:
+ SER_ASSERT(NRF_ERROR_INVALID_PARAM, NRF_ERROR_INVALID_PARAM);
+ break;
+ }
+
+ SER_PUSH_FIELD(p_struct, fp_encoder);
+
+ SER_RSP_ENC_END;
+}
+
+
+uint32_t ble_opt_set_req_dec(uint8_t const * const p_buf,
+ uint16_t packet_len,
+ uint32_t * const p_opt_id,
+ ble_opt_t **const pp_opt )
+{
+ SER_REQ_DEC_BEGIN(SD_BLE_OPT_SET);
+
+ SER_ASSERT_NOT_NULL(p_opt_id);
+ SER_ASSERT_NOT_NULL(pp_opt);
+ SER_ASSERT_NOT_NULL(*pp_opt);
+
+ SER_PULL_uint32(p_opt_id);
+
+ SER_PULL_COND(pp_opt, NULL);
+ if (*pp_opt)
+ {
+ field_decoder_handler_t fp_decoder = NULL;
+ void * p_struct = NULL;
+
+ switch (*p_opt_id)
+ {
+#if defined(NRF_SD_BLE_API_VERSION) && NRF_SD_BLE_API_VERSION < 4
+ case BLE_COMMON_OPT_CONN_BW:
+ fp_decoder = ble_common_opt_conn_bw_t_dec;
+ p_struct = &((*pp_opt)->common_opt.conn_bw);
+ break;
+#endif
+ case BLE_COMMON_OPT_PA_LNA:
+ fp_decoder = ble_common_opt_pa_lna_t_dec;
+ p_struct = &((*pp_opt)->common_opt.pa_lna);
+ break;
+ case BLE_COMMON_OPT_CONN_EVT_EXT:
+ fp_decoder = ble_common_opt_conn_evt_ext_t_dec;
+ p_struct = &((*pp_opt)->common_opt.conn_evt_ext);
+ break;
+ case BLE_GAP_OPT_CH_MAP:
+ fp_decoder = ble_gap_opt_ch_map_t_dec;
+ p_struct = &((*pp_opt)->gap_opt.ch_map);
+ break;
+ case BLE_GAP_OPT_LOCAL_CONN_LATENCY:
+ fp_decoder = ble_gap_opt_local_conn_latency_t_dec;
+ p_struct = &((*pp_opt)->gap_opt.local_conn_latency);
+ break;
+ case BLE_GAP_OPT_PASSKEY:
+ fp_decoder = ble_gap_opt_passkey_t_dec;
+ p_struct = &((*pp_opt)->gap_opt.passkey);
+ break;
+ case BLE_GAP_OPT_AUTH_PAYLOAD_TIMEOUT:
+ fp_decoder = ble_gap_opt_auth_payload_timeout_t_dec;
+ p_struct = &((*pp_opt)->gap_opt.auth_payload_timeout);
+ break;
+#if defined(NRF_SD_BLE_API_VERSION) && NRF_SD_BLE_API_VERSION < 4
+ case BLE_GAP_OPT_EXT_LEN:
+ fp_decoder = ble_gap_opt_ext_len_t_dec;
+ p_struct = &((*pp_opt)->gap_opt.ext_len);
+ break;
+#endif
+#if defined(NRF_SD_BLE_API_VERSION) && NRF_SD_BLE_API_VERSION < 6
+ case BLE_GAP_OPT_SCAN_REQ_REPORT:
+ fp_decoder = ble_gap_opt_scan_req_report_t_dec;
+ p_struct = &((*pp_opt)->gap_opt.scan_req_report);
+ break;
+#endif
+#if defined(NRF_SD_BLE_API_VERSION) && NRF_SD_BLE_API_VERSION < 4
+ case BLE_GAP_OPT_COMPAT_MODE:
+ fp_decoder = ble_gap_opt_compat_mode_t_dec;
+ p_struct = &((*pp_opt)->gap_opt.compat_mode);
+ break;
+#else
+#ifndef S112
+ case BLE_GAP_OPT_COMPAT_MODE_1:
+ fp_decoder = ble_gap_opt_compat_mode_1_t_dec;
+ p_struct = &((*pp_opt)->gap_opt.compat_mode_1);
+ break;
+#endif
+ case BLE_GAP_OPT_SLAVE_LATENCY_DISABLE:
+ fp_decoder = ble_gap_opt_slave_latency_disable_t_dec;
+ p_struct = &((*pp_opt)->gap_opt.slave_latency_disable);
+ break;
+#endif
+#if defined(NRF_SD_BLE_API_VERSION) && NRF_SD_BLE_API_VERSION == 4
+ case BLE_GAP_OPT_COMPAT_MODE_2:
+ fp_decoder = ble_gap_opt_compat_mode_2_t_dec;
+ p_struct = &((*pp_opt)->gap_opt.compat_mode_2);
+ break;
+#endif
+ default:
+ SER_ASSERT(NRF_ERROR_INVALID_PARAM,NRF_ERROR_INVALID_PARAM);
+ break;
+ }
+
+ SER_PULL_FIELD(p_struct, fp_decoder);
+ }
+
+ SER_REQ_DEC_END;
+}
+
+
+uint32_t ble_opt_set_rsp_enc(uint32_t return_code,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len)
+{
+ SER_RSP_ENC_RESULT_ONLY(SD_BLE_OPT_SET);
+}
+
+#if defined(NRF_SD_BLE_API_VERSION) && NRF_SD_BLE_API_VERSION < 4
+uint32_t ble_tx_packet_count_get_req_dec(uint8_t const * const p_buf,
+ uint16_t packet_len,
+ uint16_t * const p_conn_handle,
+ uint8_t * * const pp_count)
+{
+ SER_REQ_DEC_BEGIN(SD_BLE_TX_PACKET_COUNT_GET);
+
+ SER_PULL_uint16(p_conn_handle);
+ SER_PULL_COND(pp_count, NULL);
+
+ SER_REQ_DEC_END;
+}
+
+
+uint32_t ble_tx_packet_count_get_rsp_enc(uint32_t return_code,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len,
+ uint8_t const * const p_count)
+{
+ SER_RSP_ENC_BEGIN(SD_BLE_TX_PACKET_COUNT_GET);
+ SER_PUSH_COND(p_count, uint8_t_enc);
+ SER_RSP_ENC_END;
+}
+#endif
+
+uint32_t ble_user_mem_reply_req_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ uint16_t * const p_conn_handle,
+ ble_user_mem_block_t * * const pp_mem_block)
+{
+ SER_REQ_DEC_BEGIN(SD_BLE_USER_MEM_REPLY);
+
+ SER_ASSERT_NOT_NULL(p_conn_handle);
+ SER_ASSERT_NOT_NULL(pp_mem_block);
+ SER_ASSERT_NOT_NULL(*pp_mem_block);
+
+ SER_PULL_uint16(p_conn_handle);
+ SER_PULL_COND(pp_mem_block, ble_user_mem_block_t_dec);
+
+ SER_REQ_DEC_END;
+}
+
+
+uint32_t ble_user_mem_reply_rsp_enc(uint32_t return_code,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len)
+{
+ SER_RSP_ENC_RESULT_ONLY(SD_BLE_USER_MEM_REPLY);
+}
+
+uint32_t ble_uuid_decode_req_dec(uint8_t const * const p_buf,
+ uint32_t const packet_len,
+ uint8_t * p_uuid_le_len,
+ uint8_t * * const pp_uuid_le,
+ ble_uuid_t * * const pp_uuid)
+{
+ SER_REQ_DEC_BEGIN(SD_BLE_UUID_DECODE);
+
+ SER_PULL_len8data(pp_uuid_le, p_uuid_le_len);
+ SER_PULL_COND(pp_uuid, NULL);
+
+ SER_REQ_DEC_END;
+}
+
+uint32_t ble_uuid_decode_rsp_enc(uint32_t return_code,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len,
+ ble_uuid_t const * const p_uuid)
+{
+ SER_RSP_ENC_BEGIN(SD_BLE_UUID_DECODE);
+ SER_PUSH_COND(p_uuid, ble_uuid_t_enc);
+ SER_RSP_ENC_END;
+}
+
+uint32_t ble_uuid_encode_req_dec(uint8_t const * const p_buf,
+ uint16_t packet_len,
+ ble_uuid_t * * const pp_uuid,
+ uint8_t * * const pp_uuid_le_len,
+ uint8_t * * const pp_uuid_le)
+{
+ SER_REQ_DEC_BEGIN(SD_BLE_UUID_ENCODE);
+
+ SER_ASSERT_NOT_NULL(pp_uuid);
+ SER_ASSERT_NOT_NULL(pp_uuid_le_len);
+ SER_ASSERT_NOT_NULL(pp_uuid_le);
+ SER_ASSERT_NOT_NULL(*pp_uuid);
+ SER_ASSERT_NOT_NULL(*pp_uuid_le_len);
+ SER_ASSERT_NOT_NULL(*pp_uuid_le);
+
+ SER_PULL_COND(pp_uuid, ble_uuid_t_dec);
+ SER_PULL_COND(pp_uuid_le_len, NULL);
+ SER_PULL_COND(pp_uuid_le, NULL);
+
+ SER_REQ_DEC_END;
+}
+
+
+uint32_t ble_uuid_encode_rsp_enc(uint32_t return_code,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len,
+ uint8_t uuid_le_len,
+ uint8_t const * const p_uuid_le)
+{
+ SER_RSP_ENC_BEGIN(SD_BLE_UUID_ENCODE);
+
+ SER_PUSH_uint8(&uuid_le_len);
+ if (p_uuid_le != NULL)
+ {
+ SER_PUSH_uint8array(p_uuid_le, uuid_le_len);
+ }
+
+ SER_RSP_ENC_END;
+}
+
+uint32_t ble_uuid_vs_add_req_dec(uint8_t const * const p_buf,
+ uint16_t packet_len,
+ ble_uuid128_t * * const pp_uuid,
+ uint8_t * * const pp_uuid_type)
+{
+ SER_REQ_DEC_BEGIN(SD_BLE_UUID_VS_ADD);
+
+ SER_ASSERT_NOT_NULL(pp_uuid);
+ SER_ASSERT_NOT_NULL(pp_uuid_type);
+ SER_ASSERT_NOT_NULL(*pp_uuid);
+ SER_ASSERT_NOT_NULL(*pp_uuid_type);
+
+ SER_PULL_COND(pp_uuid, ble_uuid128_t_dec);
+ SER_PULL_COND(pp_uuid_type, NULL);
+
+ SER_REQ_DEC_END;
+}
+
+
+uint32_t ble_uuid_vs_add_rsp_enc(uint32_t return_code,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len,
+ uint8_t const * const p_uuid_type)
+{
+ SER_RSP_ENC_BEGIN(SD_BLE_UUID_VS_ADD);
+ SER_PUSH_COND(p_uuid_type, uint8_t_enc);
+ SER_RSP_ENC_END;
+}
+
+uint32_t ble_version_get_req_dec(uint8_t const * const p_buf,
+ uint16_t packet_len,
+ ble_version_t * * const pp_version)
+{
+ SER_REQ_DEC_BEGIN(SD_BLE_VERSION_GET);
+
+ SER_ASSERT_NOT_NULL(pp_version);
+ SER_ASSERT_NOT_NULL(*pp_version);
+
+ SER_PULL_COND(pp_version, NULL);
+
+ SER_REQ_DEC_END;
+}
+
+
+uint32_t ble_version_get_rsp_enc(uint32_t return_code,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len,
+ ble_version_t const * const p_version)
+{
+ SER_RSP_ENC_BEGIN(SD_BLE_VERSION_GET);
+ SER_PUSH_FIELD(p_version, ble_version_t_enc);
+ SER_RSP_ENC_END;
+}
+
+
+
+uint32_t ble_opt_id_pre_dec(uint8_t const * const p_buf,
+ uint16_t packet_len,
+ uint32_t * const p_opt_id)
+{
+ SER_REQ_DEC_BEGIN(SD_BLE_OPT_SET);
+
+ SER_ASSERT_NOT_NULL(p_opt_id);
+ SER_PULL_uint32(p_opt_id);
+
+ // Pre-decoding; do not check if the whole packet was processed.
+ return NRF_SUCCESS;
+}
+#if NRF_SD_BLE_API_VERSION >= 4
+
+uint32_t ble_cfg_set_req_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ uint32_t * p_cfg_id,
+ ble_cfg_t * * const pp_cfg)
+{
+ SER_REQ_DEC_BEGIN(SD_BLE_CFG_SET);
+ SER_PULL_uint32(p_cfg_id);
+ SER_PULL_COND(pp_cfg, NULL);
+
+ if (*pp_cfg)
+ {
+
+ field_decoder_handler_t fp_decoder = NULL;
+ void * p_struct = NULL;
+
+ switch (*p_cfg_id)
+ {
+ case BLE_CONN_CFG_GAP:
+ fp_decoder = ble_gap_conn_cfg_t_dec;
+ p_struct = &((*pp_cfg)->conn_cfg.params.gap_conn_cfg);
+ break;
+ case BLE_CONN_CFG_GATTC:
+ fp_decoder = ble_gattc_conn_cfg_t_dec;
+ p_struct = &((*pp_cfg)->conn_cfg.params.gattc_conn_cfg);
+ break;
+ case BLE_CONN_CFG_GATTS:
+ fp_decoder = ble_gatts_conn_cfg_t_dec;
+ p_struct = &((*pp_cfg)->conn_cfg.params.gatts_conn_cfg);
+ break;
+ case BLE_CONN_CFG_GATT:
+ fp_decoder = ble_gatt_conn_cfg_t_dec;
+ p_struct = &((*pp_cfg)->conn_cfg.params.gatt_conn_cfg);
+ break;
+#if defined(NRF_SD_BLE_API_VERSION) && NRF_SD_BLE_API_VERSION >= 5 && !defined(S112)
+ case BLE_CONN_CFG_L2CAP:
+ fp_decoder = ble_l2cap_conn_cfg_t_dec;
+ p_struct = &((*pp_cfg)->conn_cfg.params.l2cap_conn_cfg);
+ break;
+#endif
+ case BLE_COMMON_CFG_VS_UUID:
+ fp_decoder = ble_common_cfg_vs_uuid_t_dec;
+ p_struct = &((*pp_cfg)->common_cfg.vs_uuid_cfg);
+ break;
+ case BLE_GAP_CFG_ROLE_COUNT:
+ fp_decoder = ble_gap_cfg_role_count_t_dec;
+ p_struct = &((*pp_cfg)->gap_cfg.role_count_cfg);
+ break;
+ case BLE_GAP_CFG_DEVICE_NAME:
+ fp_decoder = ble_gap_cfg_device_name_t_dec;
+ p_struct = &((*pp_cfg)->gap_cfg.device_name_cfg);
+ break;
+ case BLE_GATTS_CFG_SERVICE_CHANGED:
+ fp_decoder = ble_gatts_cfg_service_changed_t_dec;
+ p_struct = &((*pp_cfg)->gatts_cfg.service_changed);
+ break;
+ case BLE_GATTS_CFG_ATTR_TAB_SIZE:
+ fp_decoder = ble_gatts_cfg_attr_tab_size_t_dec;
+ p_struct = &((*pp_cfg)->gatts_cfg.attr_tab_size);
+ break;
+ default:
+ SER_ASSERT(NRF_ERROR_INVALID_PARAM,NRF_ERROR_INVALID_PARAM);
+ break;
+ }
+
+ if (*p_cfg_id >= BLE_CONN_CFG_BASE && *p_cfg_id <= BLE_CONN_CFG_GATT)
+ {
+ SER_PULL_uint8(&(*pp_cfg)->conn_cfg.conn_cfg_tag);
+ }
+ SER_PULL_FIELD(p_struct, fp_decoder);
+ }
+ SER_REQ_DEC_END;
+}
+
+
+
+uint32_t ble_cfg_set_rsp_enc(uint32_t return_code,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len)
+{
+ SER_RSP_ENC_RESULT_ONLY(SD_BLE_CFG_SET);
+}
+
+#endif
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/connectivity/codecs/ble/serializers/ble_conn.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/connectivity/codecs/ble/serializers/ble_conn.h
new file mode 100644
index 0000000..bcf4c73
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/connectivity/codecs/ble/serializers/ble_conn.h
@@ -0,0 +1,521 @@
+/**
+ * Copyright (c) 2013 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#ifndef BLE_CONN_H__
+#define BLE_CONN_H__
+
+/**
+ * @addtogroup ser_conn_s130_codecs Connectivity codecs for S132 and S140
+ * @ingroup ser_codecs_conn
+ */
+
+/**@file
+ *
+ * @defgroup ble_conn Connectivity command request decoders and command response encoders
+ * @{
+ * @ingroup ser_conn_s130_codecs
+ *
+ * @brief Connectivity command request decoders and command response encoders.
+ */
+#include "ble.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#if defined(NRF_SD_BLE_API_VERSION) && NRF_SD_BLE_API_VERSION < 4
+/**@brief Decodes @ref sd_ble_tx_packet_count_get command request.
+ *
+ * @sa @ref ble_tx_packet_count_get_rsp_enc for response encoding.
+ *
+ * @param[in] p_buf Pointer to beginning of command request packet.
+ * @param[in] packet_len Length (in bytes) of response packet.
+ * @param[out] p_conn_handle Pointer to connection handle.
+ * @param[out] pp_count Pointer to pointer to location for count.
+ *
+ * @retval NRF_SUCCESS Decoding success.
+ * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length.
+ * @retval NRF_ERROR_INVALID_PARAM Decoding failure. Invalid operation type.
+ */
+uint32_t ble_tx_packet_count_get_req_dec(uint8_t const * const p_buf,
+ uint16_t packet_len,
+ uint16_t * const p_conn_handle,
+ uint8_t * * const pp_count);
+
+/**@brief Encodes @ref sd_ble_tx_packet_count_get command response.
+ *
+ * @sa @ref ble_tx_packet_count_get_req_dec for request decoding.
+ *
+ * @param[in] return_code Return code indicating if command was successful or not.
+ * @param[out] p_buf Pointer to buffer where encoded data command response will be
+ * returned.
+ * @param[in,out] p_buf_len \c in: size of \p p_buf buffer.
+ * \c out: Length of encoded command response packet.
+ * @param[in] p_count Pointer to count value.
+ *
+ * @retval NRF_SUCCESS Encoding success.
+ * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length.
+ */
+uint32_t ble_tx_packet_count_get_rsp_enc(uint32_t return_code,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len,
+ uint8_t const * const p_count);
+#endif
+
+/**@brief Event encoding dispatcher.
+ *
+ * The event encoding dispatcher will route the event packet to the correct encoder which in turn
+ * encodes the contents of the event and updates the \p p_buf buffer.
+ *
+ * @param[in] p_event Pointer to the \ref ble_evt_t buffer that shall be encoded.
+ * @param[in] event_len Size (in bytes) of \p p_event buffer.
+ * @param[out] p_buf Pointer to the beginning of a buffer for encoded event packet.
+ * @param[in,out] p_buf_len \c in: Size (in bytes) of \p p_buf buffer.
+ * \c out: Length of encoded contents in \p p_buf.
+ *
+ * @retval NRF_SUCCESS Encoding success.
+ * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length.
+ * @retval NRF_ERROR_NOT_SUPPORTED Event encoder is not implemented.
+ */
+uint32_t ble_event_enc(ble_evt_t const * const p_event,
+ uint32_t event_len,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len);
+
+/**@brief Decodes @ref sd_ble_version_get command request.
+ *
+ * @sa @ref ble_version_get_rsp_enc for response encoding.
+ *
+ * @param[in] p_buf Pointer to beginning of command request packet.
+ * @param[in] packet_len Length (in bytes) of response packet.
+ * @param[out] pp_version Pointer to pointer to @ref ble_version_t address.
+ *
+ * @retval NRF_SUCCESS Decoding success.
+ * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length.
+ * @retval NRF_ERROR_INVALID_PARAM Decoding failure. Invalid operation type.
+ */
+uint32_t ble_version_get_req_dec(uint8_t const * const p_buf,
+ uint16_t packet_len,
+ ble_version_t * * const pp_version);
+
+/**@brief Encodes @ref sd_ble_version_get command response.
+ *
+ * @sa @ref ble_version_get_req_dec for request decoding.
+ *
+ * @param[in] return_code Return code indicating if command was successful or not.
+ * @param[out] p_buf Pointer to buffer where encoded data command response will be
+ * returned.
+ * @param[in,out] p_buf_len \c in: size of \p p_buf buffer.
+ * \c out: Length of encoded command response packet.
+ * @param[in] p_version Pointer to @ref ble_version_t address.
+ *
+ * @retval NRF_SUCCESS Encoding success.
+ * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length.
+ */
+uint32_t ble_version_get_rsp_enc(uint32_t return_code,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len,
+ ble_version_t const * const p_version);
+
+
+/**@brief Decodes @ref sd_ble_opt_get command request.
+ *
+ * @sa @ref ble_opt_get_rsp_enc for response encoding.
+ *
+ * @param[in] p_buf Pointer to beginning of command request packet.
+ * @param[in] packet_len Length (in bytes) of response packet.
+ * @param[out] p_opt_id Pointer to pointer to @ref ble_version_t address.
+ * @param[out] pp_opt Pointer to pointer to @ref ble_opt_t address.
+ *
+ * @retval NRF_SUCCESS Decoding success.
+ * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length.
+ * @retval NRF_ERROR_INVALID_PARAM Decoding failure. Invalid operation type.
+ */
+uint32_t ble_opt_get_req_dec(uint8_t const * const p_buf,
+ uint16_t packet_len,
+ uint32_t * const p_opt_id,
+ ble_opt_t **const pp_opt );
+
+
+/**@brief Encodes @ref sd_ble_opt_get command response.
+ *
+ * @sa @ref ble_opt_get_req_dec for request decoding.
+ *
+ * @param[in] return_code Return code indicating if command was successful or not.
+ * @param[out] p_buf Pointer to buffer where encoded data command response will be
+ * returned.
+ * @param[in,out] p_buf_len \c in: size of \p p_buf buffer.
+ * \c out: Length of encoded command response packet.
+ * @param[in] opt_id identifies type of ble_opt_t union
+ * @param[in] p_opt Pointer to @ref ble_opt_t union.
+ *
+ * @retval NRF_SUCCESS Encoding success.
+ * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length.
+ */
+
+uint32_t ble_opt_get_rsp_enc(uint32_t return_code,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len,
+ uint32_t opt_id,
+ ble_opt_t const * const p_opt);
+
+
+/**@brief Decodes @ref sd_ble_opt_set command request.
+ *
+ * @sa @ref ble_opt_set_rsp_enc for response encoding.
+ *
+ * @param[in] p_buf Pointer to beginning of command request packet.
+ * @param[in] packet_len Length (in bytes) of response packet.
+ * @param[out] p_opt_id Pointer to @ref ble_opt_t union type identifier.
+ * @param[out] pp_opt Pointer to pointer to @ref ble_opt_t union.
+ *
+ * @retval NRF_SUCCESS Decoding success.
+ * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length.
+ * @retval NRF_ERROR_INVALID_PARAM Decoding failure. Invalid operation type.
+ */
+uint32_t ble_opt_set_req_dec(uint8_t const * const p_buf,
+ uint16_t packet_len,
+ uint32_t * const p_opt_id,
+ ble_opt_t **const pp_opt );
+
+
+/**@brief Encodes @ref sd_ble_opt_set command response.
+ *
+ * @sa @ref ble_opt_set_req_dec for request decoding.
+ *
+ * @param[in] return_code Return code indicating if command was successful or not.
+ * @param[out] p_buf Pointer to buffer where encoded data command response will be
+ * returned.
+ * @param[in,out] p_buf_len \c in: size of \p p_buf buffer.
+ * \c out: Length of encoded command response packet.
+ *
+ * @retval NRF_SUCCESS Encoding success.
+ * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length.
+ */
+
+uint32_t ble_opt_set_rsp_enc(uint32_t return_code,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len);
+
+
+/**@brief Decodes @ref sd_ble_uuid_encode command request.
+ *
+ * @sa @ref ble_uuid_encode_rsp_enc for response encoding.
+ *
+ * @param[in] p_buf Pointer to beginning of command request packet.
+ * @param[in] packet_len Length (in bytes) of response packet.
+ * @param[out] pp_uuid Pointer to pointer to @ref ble_uuid_t structure.
+ * @param[out] pp_uuid_le_len Pointer to pointer to the length of encoded UUID.
+ * @param[out] pp_uuid_le Pointer to pointer to buffer where encoded UUID will be stored.
+ *
+ * @retval NRF_SUCCESS Decoding success.
+ * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length.
+ * @retval NRF_ERROR_INVALID_PARAM Decoding failure. Invalid operation type.
+ */
+uint32_t ble_uuid_encode_req_dec(uint8_t const * const p_buf,
+ uint16_t packet_len,
+ ble_uuid_t * * const pp_uuid,
+ uint8_t * * const pp_uuid_le_len,
+ uint8_t * * const pp_uuid_le);
+
+/**@brief Encodes @ref sd_ble_uuid_encode command response.
+ *
+ * @sa @ref ble_uuid_encode_req_dec for request decoding.
+ *
+ * @param[in] return_code Return code indicating if command was successful or not.
+ * @param[out] p_buf Pointer to buffer where encoded data command response will be
+ * returned.
+ * @param[in,out] p_buf_len \c in: size of \p p_buf buffer.
+ * \c out: Length of encoded command response packet.
+ * @param[in] uuid_le_len Length of the encoded UUID.
+ * @param[in] p_uuid_le Pointer to the buffer with encoded UUID.
+ *
+ * @retval NRF_SUCCESS Encoding success.
+ * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length.
+ */
+uint32_t ble_uuid_encode_rsp_enc(uint32_t return_code,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len,
+ uint8_t uuid_le_len,
+ uint8_t const * const p_uuid_le);
+
+/**@brief Decodes @ref sd_ble_uuid_decode command request.
+ *
+ * @sa @ref ble_uuid_decode_rsp_enc for response encoding.
+ *
+ * @param[in] p_buf Pointer to beginning of command request packet.
+ * @param[in] packet_len Length (in bytes) of response packet.
+ * @param[out] p_uuid_le_len Pointer to the length of encoded UUID.
+ * @param[out] pp_uuid_le Pointer to pointer to buffer where encoded UUID will be stored.
+ * @param[out] pp_uuid Pointer to pointer to @ref ble_uuid_t structure.
+ * \c It will be set to NULL if p_uuid is not present in the packet.
+ *
+ * @retval NRF_SUCCESS Decoding success.
+ * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length.
+ */
+uint32_t ble_uuid_decode_req_dec(uint8_t const * const p_buf,
+ uint32_t const packet_len,
+ uint8_t * p_uuid_le_len,
+ uint8_t * * const pp_uuid_le,
+ ble_uuid_t * * const pp_uuid);
+
+/**@brief Encodes @ref sd_ble_uuid_decode command response.
+ *
+ * @sa @ref ble_uuid_decode_req_dec for request decoding.
+ *
+ * @param[in] return_code Return code indicating if command was successful or not.
+ * @param[out] p_buf Pointer to buffer where encoded data command response will be
+ * returned.
+ * @param[in,out] p_buf_len \c in: size of \p p_buf buffer.
+ * \c out: Length of encoded command response packet.
+ * @param[in] p_uuid Pointer to the buffer with encoded UUID.
+ *
+ * @retval NRF_SUCCESS Encoding success.
+ * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length.
+ */
+uint32_t ble_uuid_decode_rsp_enc(uint32_t return_code,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len,
+ ble_uuid_t const * const p_uuid);
+
+/**@brief Decodes @ref sd_ble_uuid_vs_add command request.
+ *
+ * @sa @ref ble_uuid_vs_add_rsp_enc for response encoding.
+ *
+ * @param[in] p_buf Pointer to beginning of command request packet.
+ * @param[in] packet_len Length (in bytes) of response packet.
+ * @param[out] pp_uuid Pointer to pointer to UUID.
+ * \c It will be set to NULL if p_uuid is not present in the packet.
+ * @param[out] pp_uuid_type Pointer to pointer to UUID type.
+ * \c It will be set to NULL if p_uuid_type is not present in the packet.
+ *
+ * @retval NRF_SUCCESS Decoding success.
+ * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length.
+ */
+uint32_t ble_uuid_vs_add_req_dec(uint8_t const * const p_buf,
+ uint16_t packet_len,
+ ble_uuid128_t * * const pp_uuid,
+ uint8_t * * const pp_uuid_type);
+
+/**@brief Encodes @ref sd_ble_uuid_vs_add command response.
+ *
+ * @sa @ref ble_uuid_vs_add_req_dec for request decoding.
+ *
+ * @param[in] return_code Return code indicating if command was successful or not.
+ * @param[out] p_buf Pointer to buffer where encoded data command response will be
+ * returned.
+ * @param[in,out] p_buf_len \c in: size of \p p_buf buffer.
+ * \c out: Length of encoded command response packet.
+ * @param[in] p_uuid_type Pointer to the UUID type.
+ *
+ * @retval NRF_SUCCESS Encoding success.
+ * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length.
+ */
+uint32_t ble_uuid_vs_add_rsp_enc(uint32_t return_code,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len,
+ uint8_t const * const p_uuid_type);
+
+#if defined(NRF_SD_BLE_API_VERSION) && NRF_SD_BLE_API_VERSION < 4
+/**@brief Decodes @ref sd_ble_enable command request.
+ *
+ * @sa @ref ble_enable_rsp_enc for response encoding.
+ *
+ * @param[in] p_buf Pointer to beginning of command request packet.
+ * @param[in] packet_len Length (in bytes) of response packet.
+ * @param[out] pp_ble_enable_params Pointer to pointer to ble_enable_params_t.
+ * \c It will be set to NULL if p_ble_enable_params is not present in the packet.
+ *
+ * @retval NRF_SUCCESS Decoding success.
+ * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length.
+ */
+uint32_t ble_enable_req_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ ble_enable_params_t * * const pp_ble_enable_params);
+#else
+/**@brief Decodes @ref sd_ble_enable command request.
+ *
+ * @sa @ref ble_enable_rsp_enc for response encoding.
+ *
+ * @param[in] p_buf Pointer to beginning of command request packet.
+ * @param[in] packet_len Length (in bytes) of response packet.
+ *
+ * @retval NRF_SUCCESS Decoding success.
+ * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length.
+ */
+uint32_t ble_enable_req_dec(uint8_t const * const p_buf,
+ uint32_t packet_len);
+
+#endif
+/**@brief Encodes @ref sd_ble_enable command response.
+ *
+ * @sa @ref ble_enable_req_dec for request decoding.
+ *
+ * @param[in] return_code Return code indicating if command was successful or not.
+ * @param[out] p_buf Pointer to buffer where encoded data command response will be
+ * returned.
+ * @param[in,out] p_buf_len \c in: size of \p p_buf buffer.
+ * \c out: Length of encoded command response packet.
+ *
+ * @retval NRF_SUCCESS Encoding success.
+ * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length.
+ */
+uint32_t ble_enable_rsp_enc(uint32_t return_code,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len);
+
+/**@brief Pre-decodes opt_id of @ref ble_opt_t for middleware.
+ *
+ * @param[out] p_buf Pointer to buffer where encoded data command response will be
+ * returned.
+ * @param[in,out] packet_len \c in: size of \p p_buf buffer.
+ * \c out: Length of encoded command response packet.
+ * @param[in,out] p_opt_id Pointer to opt_id which identifies type of @ref ble_opt_t union.
+ *
+ * @retval NRF_SUCCESS Encoding success.
+ * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length.
+ */
+uint32_t ble_opt_id_pre_dec(uint8_t const * const p_buf,
+ uint16_t packet_len,
+ uint32_t * const p_opt_id);
+
+/**@brief Decodes @ref sd_ble_user_mem_reply command request.
+ *
+ * @sa @ref ble_user_mem_reply_rsp_enc for response encoding.
+ *
+ * @param[in] p_buf Pointer to beginning of command request packet.
+ * @param[in] packet_len Length (in bytes) of response packet.
+ * @param[in] p_conn_handle Pointer to Connection Handle.
+ * @param[in,out] pp_block Pointer to pointer to ble_user_mem_block_t.
+ * \c It will be set to NULL if p_block is not present in the packet.
+ *
+ * @retval NRF_SUCCESS Decoding success.
+ * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length.
+ */
+uint32_t ble_user_mem_reply_req_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ uint16_t * const p_conn_handle,
+ ble_user_mem_block_t * * const pp_block);
+
+/**@brief Encodes @ref sd_ble_user_mem_reply command response.
+ *
+ * @sa @ref ble_user_mem_reply_req_dec for request decoding.
+ *
+ * @param[in] return_code Return code indicating if command was successful or not.
+ * @param[out] p_buf Pointer to buffer where encoded data command response will be
+ * returned.
+ * @param[in,out] p_buf_len \c in: size of \p p_buf buffer.
+ * \c out: Length of encoded command response packet.
+ *
+ * @retval NRF_SUCCESS Encoding success.
+ * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length.
+ */
+uint32_t ble_user_mem_reply_rsp_enc(uint32_t return_code,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len);
+
+#if NRF_SD_BLE_API_VERSION >= 4
+/**@brief Decodes @ref sd_ble_cfg_set command request.
+ *
+ * @sa @ref ble_cfg_set_rsp_enc for response encoding.
+ *
+ * @param[in] p_buf Pointer to beginning of command request packet.
+ * @param[in] packet_len Length (in bytes) of response packet.
+ * @param[in] p_cfg_id Pointer to ConfigurationId.
+ * @param[in,out] pp_cfg Pointer to pointer to configuration struct.
+ * \c It will be set to NULL if p_block is not present in the packet.
+ *
+ * @retval NRF_SUCCESS Decoding success.
+ * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length.
+ */
+uint32_t ble_cfg_set_req_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ uint32_t * p_cfg_id,
+ ble_cfg_t * * const pp_cfg);
+
+/**@brief Encodes @ref sd_ble_cfg_set command response.
+ *
+ * @sa @ref ble_cfg_set_req_dec for request decoding.
+ *
+ * @param[in] return_code Return code indicating if command was successful or not.
+ * @param[out] p_buf Pointer to buffer where encoded data command response will be
+ * returned.
+ * @param[in,out] p_buf_len \c in: size of \p p_buf buffer.
+ * \c out: Length of encoded command response packet.
+ *
+ * @retval NRF_SUCCESS Encoding success.
+ * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length.
+ */
+uint32_t ble_cfg_set_rsp_enc(uint32_t return_code,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len);
+
+#endif
+
+/** @} */
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/connectivity/codecs/ble/serializers/ble_event_enc.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/connectivity/codecs/ble/serializers/ble_event_enc.c
new file mode 100644
index 0000000..ff075f1
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/connectivity/codecs/ble/serializers/ble_event_enc.c
@@ -0,0 +1,295 @@
+/**
+ * Copyright (c) 2013 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#include "ble_conn.h"
+#include "ble_evt_conn.h"
+#include "ble_gap_evt_conn.h"
+#include "ble_gattc_evt_conn.h"
+#include "ble_gatts_evt_conn.h"
+#include "ble_l2cap_evt_conn.h"
+#include "ble_serialization.h"
+#include "app_util.h"
+#include "nrf_log.h"
+
+uint32_t ble_event_enc(ble_evt_t const * const p_event,
+ uint32_t event_len,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len)
+{
+ uint32_t ret_val = NRF_SUCCESS;
+
+ SER_ASSERT_NOT_NULL(p_buf);
+ SER_ASSERT_NOT_NULL(p_buf_len);
+ SER_ASSERT_NOT_NULL(p_event);
+
+ switch (p_event->header.evt_id)
+ {
+#if defined(NRF_SD_BLE_API_VERSION) && NRF_SD_BLE_API_VERSION < 4
+ case BLE_EVT_TX_COMPLETE:
+ ret_val = ble_evt_tx_complete_enc(p_event, event_len, p_buf, p_buf_len);
+ break;
+#endif
+ case BLE_EVT_USER_MEM_RELEASE:
+ ret_val = ble_evt_user_mem_release_enc(p_event, event_len, p_buf, p_buf_len);
+ break;
+
+ case BLE_EVT_USER_MEM_REQUEST:
+ ret_val = ble_evt_user_mem_request_enc(p_event, event_len, p_buf, p_buf_len);
+ break;
+#if defined(NRF_SD_BLE_API_VERSION) && NRF_SD_BLE_API_VERSION < 4
+ case BLE_EVT_DATA_LENGTH_CHANGED:
+ ret_val = ble_evt_data_length_changed_enc(p_event, event_len, p_buf, p_buf_len);
+ break;
+#endif
+
+ case BLE_GAP_EVT_CONN_PARAM_UPDATE:
+ ret_val = ble_gap_evt_conn_param_update_enc(p_event, event_len, p_buf, p_buf_len);
+ break;
+#ifndef S112
+ case BLE_GAP_EVT_CONN_PARAM_UPDATE_REQUEST:
+ ret_val = ble_gap_evt_conn_param_update_request_enc(p_event, event_len, p_buf, p_buf_len);
+ break;
+#endif //!S112
+ case BLE_GAP_EVT_SEC_PARAMS_REQUEST:
+ ret_val = ble_gap_evt_sec_params_request_enc(p_event, event_len, p_buf, p_buf_len);
+ break;
+
+ case BLE_GAP_EVT_SEC_INFO_REQUEST:
+ ret_val = ble_gap_evt_sec_info_request_enc(p_event, event_len, p_buf, p_buf_len);
+ break;
+
+ case BLE_GAP_EVT_AUTH_STATUS:
+ ret_val = ble_gap_evt_auth_status_enc(p_event, event_len, p_buf, p_buf_len);
+ break;
+
+ case BLE_GAP_EVT_PASSKEY_DISPLAY:
+ ret_val = ble_gap_evt_passkey_display_enc(p_event, event_len, p_buf, p_buf_len);
+ break;
+
+ case BLE_GAP_EVT_AUTH_KEY_REQUEST:
+ ret_val = ble_gap_evt_auth_key_request_enc(p_event, event_len, p_buf, p_buf_len);
+ break;
+
+ case BLE_GAP_EVT_CONN_SEC_UPDATE:
+ ret_val = ble_gap_evt_conn_sec_update_enc(p_event, event_len, p_buf, p_buf_len);
+ break;
+
+ case BLE_GAP_EVT_RSSI_CHANGED:
+ ret_val = ble_gap_evt_rssi_changed_enc(p_event, event_len, p_buf, p_buf_len);
+ break;
+
+ case BLE_GAP_EVT_TIMEOUT:
+ ret_val = ble_gap_evt_timeout_enc(p_event, event_len, p_buf, p_buf_len);
+ break;
+
+ case BLE_GAP_EVT_DISCONNECTED:
+ ret_val = ble_gap_evt_disconnected_enc(p_event, event_len, p_buf, p_buf_len);
+ break;
+
+ case BLE_GAP_EVT_CONNECTED:
+ ret_val = ble_gap_evt_connected_enc(p_event, event_len, p_buf, p_buf_len);
+ break;
+
+ case BLE_GAP_EVT_SEC_REQUEST:
+ ret_val = ble_gap_evt_sec_request_enc(p_event, event_len, p_buf, p_buf_len);
+ break;
+ case BLE_GAP_EVT_KEY_PRESSED:
+ ret_val = ble_gap_evt_key_pressed_enc(p_event, event_len, p_buf, p_buf_len);
+ break;
+ case BLE_GAP_EVT_LESC_DHKEY_REQUEST:
+ ret_val = ble_gap_evt_lesc_dhkey_request_enc(p_event, event_len, p_buf, p_buf_len);
+ break;
+#if NRF_SD_BLE_API_VERSION >= 5
+ case BLE_GAP_EVT_PHY_UPDATE:
+ ret_val = ble_gap_evt_phy_update_enc(p_event, event_len, p_buf, p_buf_len);
+ break;
+ case BLE_GAP_EVT_PHY_UPDATE_REQUEST:
+ ret_val = ble_gap_evt_phy_update_request_enc(p_event, event_len, p_buf, p_buf_len);
+ break;
+#endif
+#if NRF_SD_BLE_API_VERSION >= 4 && !defined(S112)
+ case BLE_GAP_EVT_DATA_LENGTH_UPDATE_REQUEST:
+ ret_val = ble_gap_evt_data_length_update_request_enc(p_event, event_len, p_buf, p_buf_len);
+ break;
+ case BLE_GAP_EVT_DATA_LENGTH_UPDATE:
+ ret_val = ble_gap_evt_data_length_update_enc(p_event, event_len, p_buf, p_buf_len);
+ break;
+#endif //NRF_SD_BLE_API_VERSION >= 4 && !defined(S112)
+ case BLE_GATTC_EVT_CHAR_DISC_RSP:
+ ret_val = ble_gattc_evt_char_disc_rsp_enc(p_event, event_len, p_buf, p_buf_len);
+ break;
+
+ case BLE_GATTC_EVT_DESC_DISC_RSP:
+ ret_val = ble_gattc_evt_desc_disc_rsp_enc(p_event, event_len, p_buf, p_buf_len);
+ break;
+
+ case BLE_GATTC_EVT_CHAR_VAL_BY_UUID_READ_RSP:
+ ret_val = ble_gattc_evt_char_val_by_uuid_read_rsp_enc(p_event,
+ event_len,
+ p_buf,
+ p_buf_len);
+ break;
+
+ case BLE_GATTC_EVT_PRIM_SRVC_DISC_RSP:
+ ret_val = ble_gattc_evt_prim_srvc_disc_rsp_enc(p_event, event_len, p_buf, p_buf_len);
+ break;
+
+ case BLE_GATTC_EVT_HVX:
+ ret_val = ble_gattc_evt_hvx_enc(p_event, event_len, p_buf, p_buf_len);
+ break;
+
+ case BLE_GATTC_EVT_READ_RSP:
+ ret_val = ble_gattc_evt_read_rsp_enc(p_event, event_len, p_buf, p_buf_len);
+ break;
+
+ case BLE_GATTC_EVT_TIMEOUT:
+ ret_val = ble_gattc_evt_timeout_enc(p_event, event_len, p_buf, p_buf_len);
+ break;
+
+ case BLE_GATTC_EVT_WRITE_RSP:
+ ret_val = ble_gattc_evt_write_rsp_enc(p_event, event_len, p_buf, p_buf_len);
+ break;
+
+ case BLE_GATTC_EVT_REL_DISC_RSP:
+ ret_val = ble_gattc_evt_rel_disc_rsp_enc(p_event, event_len, p_buf, p_buf_len);
+ break;
+
+ case BLE_GATTC_EVT_CHAR_VALS_READ_RSP:
+ ret_val = ble_gattc_evt_char_vals_read_rsp_enc(p_event, event_len, p_buf, p_buf_len);
+ break;
+
+ case BLE_GATTC_EVT_ATTR_INFO_DISC_RSP:
+ ret_val = ble_gattc_evt_attr_info_disc_rsp_enc(p_event, event_len, p_buf, p_buf_len);
+ break;
+
+ case BLE_GATTC_EVT_EXCHANGE_MTU_RSP:
+ ret_val = ble_gattc_evt_exchange_mtu_rsp_enc(p_event, event_len, p_buf, p_buf_len);
+ break;
+#if NRF_SD_BLE_API_VERSION >= 4
+ case BLE_GATTC_EVT_WRITE_CMD_TX_COMPLETE:
+ ret_val = ble_gattc_evt_write_cmd_tx_complete_enc(p_event, event_len, p_buf, p_buf_len);
+ break;
+#endif
+
+ case BLE_GATTS_EVT_HVC:
+ ret_val = ble_gatts_evt_hvc_enc(p_event, event_len, p_buf, p_buf_len);
+ break;
+
+ case BLE_GATTS_EVT_TIMEOUT:
+ ret_val = ble_gatts_evt_timeout_enc(p_event, event_len, p_buf, p_buf_len);
+ break;
+
+ case BLE_GATTS_EVT_SC_CONFIRM:
+ ret_val = ble_gatts_evt_sc_confirm_enc(p_event, event_len, p_buf, p_buf_len);
+ break;
+
+ case BLE_GATTS_EVT_WRITE:
+ ret_val = ble_gatts_evt_write_enc(p_event, event_len, p_buf, p_buf_len);
+ break;
+
+ case BLE_GATTS_EVT_RW_AUTHORIZE_REQUEST:
+ ret_val = ble_gatts_evt_rw_authorize_request_enc(p_event, event_len, p_buf, p_buf_len);
+ break;
+
+ case BLE_GATTS_EVT_SYS_ATTR_MISSING:
+ ret_val = ble_gatts_evt_sys_attr_missing_enc(p_event, event_len, p_buf, p_buf_len);
+ break;
+
+ case BLE_GATTS_EVT_EXCHANGE_MTU_REQUEST:
+ ret_val = ble_gatts_evt_exchange_mtu_request_enc(p_event, event_len, p_buf, p_buf_len);
+ break;
+#if NRF_SD_BLE_API_VERSION >= 4
+ case BLE_GATTS_EVT_HVN_TX_COMPLETE:
+ ret_val = ble_gatts_evt_hvn_tx_complete_enc(p_event, event_len, p_buf, p_buf_len);
+ break;
+#endif
+#if defined(NRF_SD_BLE_API_VERSION) && NRF_SD_BLE_API_VERSION < 4
+ case BLE_L2CAP_EVT_RX:
+ ret_val = ble_l2cap_evt_rx_enc(p_event, event_len, p_buf, p_buf_len);
+ break;
+#endif
+#if defined(NRF_SD_BLE_API_VERSION) && NRF_SD_BLE_API_VERSION >= 5 && !defined(S112)
+ case BLE_L2CAP_EVT_CH_SETUP_REQUEST:
+ ret_val = ble_l2cap_evt_ch_setup_request_enc(p_event, event_len, p_buf, p_buf_len);
+ break;
+ case BLE_L2CAP_EVT_CH_SETUP_REFUSED:
+ ret_val = ble_l2cap_evt_ch_setup_refused_enc(p_event, event_len, p_buf, p_buf_len);
+ break;
+
+ case BLE_L2CAP_EVT_CH_SETUP:
+ ret_val = ble_l2cap_evt_ch_setup_enc(p_event, event_len, p_buf, p_buf_len);
+ break;
+
+ case BLE_L2CAP_EVT_CH_RELEASED:
+ ret_val = ble_l2cap_evt_ch_released_enc(p_event, event_len, p_buf, p_buf_len);
+ break;
+
+ case BLE_L2CAP_EVT_CH_SDU_BUF_RELEASED:
+ ret_val = ble_l2cap_evt_ch_sdu_buf_released_enc(p_event, event_len, p_buf, p_buf_len);
+ break;
+
+ case BLE_L2CAP_EVT_CH_CREDIT:
+ ret_val = ble_l2cap_evt_ch_credit_enc(p_event, event_len, p_buf, p_buf_len);
+ break;
+
+ case BLE_L2CAP_EVT_CH_RX:
+ ret_val = ble_l2cap_evt_ch_rx_enc(p_event, event_len, p_buf, p_buf_len);
+ break;
+
+ case BLE_L2CAP_EVT_CH_TX:
+ ret_val = ble_l2cap_evt_ch_tx_enc(p_event, event_len, p_buf, p_buf_len);
+ break;
+#endif //defined(NRF_SD_BLE_API_VERSION) && NRF_SD_BLE_API_VERSION >= 5 && !defined(S112)
+#ifndef S112
+ case BLE_GAP_EVT_ADV_REPORT:
+ ret_val = ble_gap_evt_adv_report_enc(p_event, event_len, p_buf, p_buf_len);
+ break;
+#endif //!S112
+ case BLE_GAP_EVT_SCAN_REQ_REPORT:
+ ret_val = ble_gap_evt_scan_req_report_enc(p_event, event_len, p_buf, p_buf_len);
+ break;
+
+ default:
+ ret_val = NRF_ERROR_NOT_SUPPORTED;
+ *p_buf_len = 0;
+ break;
+ }
+
+ return ret_val;
+}
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/connectivity/codecs/ble/serializers/ble_evt_conn.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/connectivity/codecs/ble/serializers/ble_evt_conn.c
new file mode 100644
index 0000000..1cc3654
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/connectivity/codecs/ble/serializers/ble_evt_conn.c
@@ -0,0 +1,108 @@
+/**
+ * Copyright (c) 2013 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#include "ble_evt_conn.h"
+#include <string.h>
+#include "ble_serialization.h"
+#include "ble_struct_serialization.h"
+#include "app_util.h"
+#include "conn_ble_user_mem.h"
+
+uint32_t ble_evt_user_mem_release_enc(ble_evt_t const * const p_event,
+ uint32_t event_len,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len)
+{
+ SER_EVT_ENC_BEGIN(BLE_EVT_USER_MEM_RELEASE);
+
+ SER_PUSH_uint16(&p_event->evt.common_evt.conn_handle);
+ SER_PUSH_uint8(&p_event->evt.common_evt.params.user_mem_release.type);
+ SER_PUSH_uint16(&p_event->evt.common_evt.params.user_mem_release.mem_block.len);
+ SER_PUSH_COND(p_event->evt.common_evt.params.user_mem_release.mem_block.p_mem, NULL);
+
+ // Now user memory context can be released
+ err_code = conn_ble_user_mem_context_destroy(p_event->evt.common_evt.conn_handle);
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code);
+
+ SER_EVT_ENC_END;
+}
+
+
+#if defined(NRF_SD_BLE_API_VERSION) && NRF_SD_BLE_API_VERSION < 4
+uint32_t ble_evt_tx_complete_enc(ble_evt_t const * const p_event,
+ uint32_t event_len,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len)
+{
+ SER_EVT_ENC_BEGIN(BLE_EVT_TX_COMPLETE);
+
+ SER_PUSH_uint16(&p_event->evt.common_evt.conn_handle);
+ SER_PUSH_uint8(&p_event->evt.common_evt.params.tx_complete.count);
+
+ SER_EVT_ENC_END;
+}
+#endif
+
+uint32_t ble_evt_user_mem_request_enc(ble_evt_t const * const p_event,
+ uint32_t event_len,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len)
+{
+ SER_EVT_ENC_BEGIN(BLE_EVT_USER_MEM_REQUEST);
+
+ SER_PUSH_uint16(&p_event->evt.gap_evt.conn_handle);
+ SER_PUSH_uint8(&p_event->evt.common_evt.params.user_mem_request.type);
+
+ SER_EVT_ENC_END;
+}
+
+#if defined(NRF_SD_BLE_API_VERSION) && NRF_SD_BLE_API_VERSION < 4
+uint32_t ble_evt_data_length_changed_enc(ble_evt_t const * const p_event,
+ uint32_t event_len,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len)
+{
+ SER_EVT_ENC_BEGIN(BLE_EVT_DATA_LENGTH_CHANGED);
+
+ SER_PUSH_uint16(&p_event->evt.gap_evt.conn_handle);
+ SER_PUSH_FIELD(&p_event->evt.common_evt.params.data_length_changed, ble_evt_data_length_changed_t_enc);
+
+ SER_EVT_ENC_END;
+}
+#endif
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/connectivity/codecs/ble/serializers/ble_evt_conn.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/connectivity/codecs/ble/serializers/ble_evt_conn.h
new file mode 100644
index 0000000..ea94c93
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/connectivity/codecs/ble/serializers/ble_evt_conn.h
@@ -0,0 +1,138 @@
+/**
+ * Copyright (c) 2014 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#ifndef BLE_EVT_CONN_H__
+#define BLE_EVT_CONN_H__
+
+
+/**@file
+ *
+ * @defgroup ble_evt_conn Connectivity event encoders
+ * @{
+ * @ingroup ser_conn_s130_codecs
+ *
+ * @brief Connectivity event encoders.
+ */
+#include "ble.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#if defined(NRF_SD_BLE_API_VERSION) && NRF_SD_BLE_API_VERSION < 4
+/**
+ * @brief Encodes ble_evt_tx_complete event.
+ *
+ * @param[in] p_event Pointer to the \ref ble_evt_t buffer that will be encoded.
+ * @param[in] event_len Size (in bytes) of \p p_event buffer.
+ * @param[out] p_buf Pointer to the beginning of a buffer for encoded event packet.
+ * @param[in,out] p_buf_len \c in: Size (in bytes) of \p p_buf buffer.
+ * \c out: Length of encoded contents in \p p_buf.
+ *
+ * @retval NRF_SUCCESS Encoding success.
+ * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length.
+ */
+uint32_t ble_evt_tx_complete_enc(ble_evt_t const * const p_event,
+ uint32_t event_len,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len);
+#endif
+/**
+ * @brief Encodes ble_evt_user_mem_release event.
+ *
+ * @param[in] p_event Pointer to the \ref ble_evt_t buffer that shall be encoded.
+ * @param[in] event_len Size (in bytes) of \p p_event buffer.
+ * @param[out] p_buf Pointer to the beginning of a buffer for encoded event packet.
+ * @param[in,out] p_buf_len \c in: Size (in bytes) of \p p_buf buffer.
+ * \c out: Length of encoded contents in \p p_buf.
+ *
+ * @retval NRF_SUCCESS Encoding success.
+ * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length.
+ */
+uint32_t ble_evt_user_mem_release_enc(ble_evt_t const * const p_event,
+ uint32_t event_len,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len);
+
+/**
+ * @brief Encodes ble_evt_user_mem_request event.
+ *
+ * @param[in] p_event Pointer to the \ref ble_evt_t buffer that will be encoded.
+ * @param[in] event_len Size (in bytes) of \p p_event buffer.
+ * @param[out] p_buf Pointer to the beginning of a buffer for encoded event packet.
+ * @param[in,out] p_buf_len \c in: Size (in bytes) of \p p_buf buffer.
+ * \c out: Length of encoded contents in \p p_buf.
+ *
+ * @retval NRF_SUCCESS Encoding success.
+ * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length.
+ */
+uint32_t ble_evt_user_mem_request_enc(ble_evt_t const * const p_event,
+ uint32_t event_len,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len);
+
+#if defined(NRF_SD_BLE_API_VERSION) && NRF_SD_BLE_API_VERSION < 4
+/**
+ * @brief Encodes ble_evt_data_length_changed event.
+ *
+ * @param[in] p_event Pointer to the \ref ble_evt_t buffer that will be encoded.
+ * @param[in] event_len Size (in bytes) of \p p_event buffer.
+ * @param[out] p_buf Pointer to the beginning of a buffer for encoded event packet.
+ * @param[in,out] p_buf_len \c in: Size (in bytes) of \p p_buf buffer.
+ * \c out: Length of encoded contents in \p p_buf.
+ *
+ * @retval NRF_SUCCESS Encoding success.
+ * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length.
+ */
+uint32_t ble_evt_data_length_changed_enc(ble_evt_t const * const p_event,
+ uint32_t event_len,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len);
+#endif
+/** @} */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/connectivity/codecs/ble/serializers/ble_gap_conn.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/connectivity/codecs/ble/serializers/ble_gap_conn.c
new file mode 100644
index 0000000..e99044f
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/connectivity/codecs/ble/serializers/ble_gap_conn.c
@@ -0,0 +1,1111 @@
+/**
+ * Copyright (c) 2013 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#include "ble_gap_conn.h"
+#include <string.h>
+#include "ble_serialization.h"
+#include "cond_field_serialization.h"
+#include "ble_gap_struct_serialization.h"
+#include "ble_struct_serialization.h"
+#include "app_util.h"
+
+#if defined(NRF_SD_BLE_API_VERSION) && NRF_SD_BLE_API_VERSION < 6
+uint32_t ble_gap_adv_data_set_req_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ uint8_t * * const pp_data,
+ uint8_t * p_dlen,
+ uint8_t * * const pp_sr_data,
+ uint8_t * p_srdlen)
+{
+ SER_REQ_DEC_BEGIN(SD_BLE_GAP_ADV_DATA_SET);
+
+ SER_ASSERT_NOT_NULL(p_dlen);
+ SER_ASSERT_NOT_NULL(p_srdlen);
+ SER_PULL_len8data(pp_data, p_dlen);
+ SER_PULL_len8data(pp_sr_data, p_srdlen);
+
+ SER_REQ_DEC_END;
+}
+
+
+uint32_t ble_gap_adv_data_set_rsp_enc(uint32_t return_code,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len)
+{
+ SER_RSP_ENC_RESULT_ONLY(SD_BLE_GAP_ADV_DATA_SET);
+}
+#endif
+
+uint32_t ble_gap_adv_start_req_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+#if NRF_SD_BLE_API_VERSION > 5
+ uint8_t * p_adv_handle
+#else
+ ble_gap_adv_params_t * * const pp_adv_params
+#endif
+#if NRF_SD_BLE_API_VERSION >= 4
+ ,uint8_t * p_conn_cfg_tag
+#endif
+ )
+{
+ SER_REQ_DEC_BEGIN(SD_BLE_GAP_ADV_START);
+#if NRF_SD_BLE_API_VERSION > 5
+ SER_PULL_uint8(p_adv_handle);
+#else
+ SER_ASSERT_NOT_NULL(pp_adv_params);
+ SER_ASSERT_NOT_NULL(*pp_adv_params);
+ SER_ASSERT_NOT_NULL((*pp_adv_params)->p_peer_addr);
+
+ SER_PULL_COND(pp_adv_params, ble_gap_adv_params_t_dec);
+#endif
+#if NRF_SD_BLE_API_VERSION >= 4
+ SER_PULL_uint8(p_conn_cfg_tag);
+#endif
+ SER_REQ_DEC_END;
+}
+
+
+uint32_t ble_gap_adv_start_rsp_enc(uint32_t return_code,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len
+ )
+{
+ SER_RSP_ENC_RESULT_ONLY(SD_BLE_GAP_ADV_START);
+}
+
+#if NRF_SD_BLE_API_VERSION > 5
+uint32_t ble_gap_adv_stop_req_dec(uint8_t const * const p_buf,
+ uint16_t packet_len,
+ uint8_t * p_adv_handle)
+{
+ SER_REQ_DEC_BEGIN(SD_BLE_GAP_ADV_STOP);
+
+ SER_PULL_uint8(p_adv_handle);
+
+ SER_REQ_DEC_END;
+}
+#endif
+
+uint32_t ble_gap_adv_stop_rsp_enc(uint32_t return_code,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len)
+{
+ SER_RSP_ENC_RESULT_ONLY(SD_BLE_GAP_ADV_STOP);
+}
+
+
+uint32_t ble_gap_appearance_get_req_dec(uint8_t const * const p_buf,
+ uint16_t packet_len,
+ uint16_t * * const pp_appearance)
+{
+ SER_REQ_DEC_BEGIN(SD_BLE_GAP_APPEARANCE_GET);
+
+ SER_ASSERT_NOT_NULL(pp_appearance);
+ SER_ASSERT_NOT_NULL(*pp_appearance);
+ SER_PULL_COND(pp_appearance, NULL);
+
+ SER_REQ_DEC_END;
+}
+
+
+uint32_t ble_gap_appearance_get_rsp_enc(uint32_t return_code,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len,
+ uint16_t const * const p_appearance)
+{
+ SER_RSP_ENC_BEGIN(SD_BLE_GAP_APPEARANCE_GET);
+
+ SER_PUSH_COND(p_appearance, uint16_t_enc);
+ SER_RSP_ENC_END;
+}
+
+uint32_t ble_gap_appearance_set_req_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ uint16_t * const p_appearance)
+{
+ SER_REQ_DEC_BEGIN(SD_BLE_GAP_APPEARANCE_SET);
+
+ SER_ASSERT_NOT_NULL(p_appearance);
+ SER_PULL_uint16(p_appearance);
+
+ SER_REQ_DEC_END;
+}
+
+
+uint32_t ble_gap_appearance_set_rsp_enc(uint32_t return_code,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len)
+{
+ SER_RSP_ENC_RESULT_ONLY(SD_BLE_GAP_APPEARANCE_SET);
+}
+
+uint32_t ble_gap_auth_key_reply_req_dec(uint8_t const * const p_buf,
+ uint16_t packet_len,
+ uint16_t * p_conn_handle,
+ uint8_t * p_key_type,
+ uint8_t * * const pp_key)
+{
+ SER_REQ_DEC_BEGIN(SD_BLE_GAP_AUTH_KEY_REPLY);
+
+ SER_ASSERT_NOT_NULL(p_conn_handle);
+ SER_ASSERT_NOT_NULL(p_key_type);
+ SER_PULL_uint16(p_conn_handle);
+ SER_PULL_uint8(p_key_type);
+
+ uint8_t key_len;
+ switch (*p_key_type)
+ {
+ case BLE_GAP_AUTH_KEY_TYPE_NONE:
+ key_len = 0;
+ break;
+
+ case BLE_GAP_AUTH_KEY_TYPE_PASSKEY:
+ key_len = 6;
+ break;
+
+ case BLE_GAP_AUTH_KEY_TYPE_OOB:
+ key_len = 16;
+ break;
+
+ default:
+ return NRF_ERROR_INVALID_PARAM;
+ }
+
+ SER_PULL_buf(pp_key, key_len, key_len);
+ SER_REQ_DEC_END;
+}
+
+uint32_t ble_gap_auth_key_reply_rsp_enc(uint32_t return_code,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len)
+{
+ SER_RSP_ENC_RESULT_ONLY(SD_BLE_GAP_AUTH_KEY_REPLY);
+}
+
+
+uint32_t ble_gap_authenticate_req_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ uint16_t * const p_conn_handle,
+ ble_gap_sec_params_t * * const pp_sec_params)
+{
+ SER_REQ_DEC_BEGIN(SD_BLE_GAP_AUTHENTICATE);
+
+ SER_ASSERT_NOT_NULL(p_conn_handle);
+ SER_ASSERT_NOT_NULL(pp_sec_params);
+ SER_ASSERT_NOT_NULL(*pp_sec_params);
+ SER_PULL_uint16(p_conn_handle);
+ SER_PULL_COND(pp_sec_params, ble_gap_sec_params_t_dec);
+
+ SER_REQ_DEC_END;
+}
+
+
+uint32_t ble_gap_authenticate_rsp_enc(uint32_t return_code,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len)
+{
+ SER_RSP_ENC_RESULT_ONLY(SD_BLE_GAP_AUTHENTICATE);
+}
+
+uint32_t ble_gap_conn_param_update_req_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ uint16_t * p_conn_handle,
+ ble_gap_conn_params_t * * const pp_conn_params)
+{
+ SER_REQ_DEC_BEGIN(SD_BLE_GAP_CONN_PARAM_UPDATE);
+
+ SER_ASSERT_NOT_NULL(p_conn_handle);
+ SER_ASSERT_NOT_NULL(pp_conn_params);
+ SER_ASSERT_NOT_NULL(*pp_conn_params);
+ SER_PULL_uint16(p_conn_handle);
+ SER_PULL_COND(pp_conn_params, ble_gap_conn_params_t_dec);
+
+ SER_REQ_DEC_END;
+}
+
+
+uint32_t ble_gap_conn_param_update_rsp_enc(uint32_t return_code,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len)
+{
+ SER_RSP_ENC_RESULT_ONLY(SD_BLE_GAP_CONN_PARAM_UPDATE);
+}
+
+uint32_t ble_gap_conn_sec_get_req_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ uint16_t * p_conn_handle,
+ ble_gap_conn_sec_t * * const pp_conn_sec)
+{
+ SER_REQ_DEC_BEGIN(SD_BLE_GAP_CONN_SEC_GET);
+
+ SER_ASSERT_NOT_NULL(p_conn_handle);
+ SER_PULL_uint16(p_conn_handle);
+ SER_PULL_COND(pp_conn_sec, NULL);
+
+ SER_REQ_DEC_END;
+}
+
+uint32_t ble_gap_conn_sec_get_rsp_enc(uint32_t return_code,
+ ble_gap_conn_sec_t * const p_conn_sec,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len)
+{
+ SER_RSP_ENC_BEGIN(SD_BLE_GAP_CONN_SEC_GET);
+
+ SER_PUSH_COND(p_conn_sec, ble_gap_conn_sec_t_enc);
+
+ SER_RSP_ENC_END;
+}
+
+uint32_t ble_gap_device_name_get_req_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ uint8_t * * pp_name,
+ uint16_t * * pp_name_len)
+{
+ SER_REQ_DEC_BEGIN(SD_BLE_GAP_DEVICE_NAME_GET);
+
+ SER_ASSERT_NOT_NULL(pp_name_len);
+
+ SER_PULL_COND(pp_name_len, uint16_t_dec);
+ SER_PULL_COND(pp_name, NULL);
+
+ SER_REQ_DEC_END;
+}
+
+
+uint32_t ble_gap_device_name_get_rsp_enc(uint32_t return_code,
+ uint8_t const * const p_dev_name,
+ uint16_t * p_dev_name_len,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len)
+{
+ SER_RSP_ENC_BEGIN(SD_BLE_GAP_DEVICE_NAME_GET);
+
+ SER_PUSH_COND(p_dev_name_len, uint16_t_enc);
+
+ if (p_dev_name_len)
+ {
+ SER_PUSH_uint8array(p_dev_name, *p_dev_name_len);
+ }
+
+ SER_RSP_ENC_END;
+}
+
+uint32_t ble_gap_device_name_set_req_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ ble_gap_conn_sec_mode_t * * const pp_write_perm,
+ uint8_t * * const pp_dev_name,
+ uint16_t * const p_dev_name_len)
+{
+ SER_REQ_DEC_BEGIN(SD_BLE_GAP_DEVICE_NAME_SET);
+
+ SER_ASSERT_NOT_NULL(pp_write_perm);
+ SER_ASSERT_NOT_NULL(pp_dev_name);
+ SER_ASSERT_NOT_NULL(p_dev_name_len);
+
+ SER_PULL_COND(pp_write_perm, ble_gap_conn_sec_mode_t_dec);
+ SER_PULL_len16data(pp_dev_name, p_dev_name_len);
+
+ SER_REQ_DEC_END;
+}
+
+
+uint32_t ble_gap_device_name_set_rsp_enc(uint32_t return_code,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len)
+{
+ SER_RSP_ENC_RESULT_ONLY(SD_BLE_GAP_DEVICE_NAME_SET);
+}
+
+uint32_t ble_gap_disconnect_req_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ uint16_t * const p_conn_handle,
+ uint8_t * const p_hci_status)
+{
+ SER_REQ_DEC_BEGIN(SD_BLE_GAP_DISCONNECT);
+
+ SER_ASSERT_NOT_NULL(p_conn_handle);
+ SER_ASSERT_NOT_NULL(p_hci_status);
+
+ SER_PULL_uint16(p_conn_handle);
+ SER_PULL_uint8(p_hci_status);
+
+ SER_REQ_DEC_END;
+}
+
+uint32_t ble_gap_disconnect_rsp_enc(uint32_t return_code,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len)
+{
+ SER_RSP_ENC_RESULT_ONLY(SD_BLE_GAP_DISCONNECT);
+}
+
+#ifndef S112
+uint32_t ble_gap_encrypt_req_dec(uint8_t const * const p_buf,
+ uint16_t packet_len,
+ uint16_t * const p_conn_handle,
+ ble_gap_master_id_t ** const pp_master_id,
+ ble_gap_enc_info_t ** const pp_enc_info)
+{
+ SER_REQ_DEC_BEGIN(SD_BLE_GAP_ENCRYPT);
+
+ SER_ASSERT_NOT_NULL(p_conn_handle);
+ SER_ASSERT_NOT_NULL(pp_enc_info);
+ SER_ASSERT_NOT_NULL(pp_master_id);
+ SER_ASSERT_NOT_NULL(*pp_enc_info);
+ SER_ASSERT_NOT_NULL(*pp_master_id);
+
+ SER_PULL_uint16(p_conn_handle);
+ SER_PULL_COND(pp_master_id, ble_gap_master_id_t_dec);
+ SER_PULL_COND(pp_enc_info, ble_gap_enc_info_t_dec);
+
+ SER_REQ_DEC_END;
+}
+
+uint32_t ble_gap_encrypt_rsp_enc(uint32_t return_code,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len)
+{
+ SER_RSP_ENC_RESULT_ONLY(SD_BLE_GAP_ENCRYPT);
+}
+#endif
+
+uint32_t ble_gap_keypress_notify_req_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ uint16_t * p_conn_handle,
+ uint8_t * p_kp_not)
+{
+ SER_REQ_DEC_BEGIN(SD_BLE_GAP_KEYPRESS_NOTIFY);
+
+ SER_ASSERT_NOT_NULL(p_conn_handle);
+ SER_ASSERT_NOT_NULL(p_kp_not);
+
+ SER_PULL_uint16(p_conn_handle);
+ SER_PULL_uint8(p_kp_not);
+
+ SER_REQ_DEC_END;
+}
+
+uint32_t ble_gap_keypress_notify_rsp_enc(uint32_t return_code,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len)
+{
+ SER_RSP_ENC_RESULT_ONLY(SD_BLE_GAP_KEYPRESS_NOTIFY);
+}
+
+uint32_t ble_gap_lesc_dhkey_reply_req_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ uint16_t * p_conn_handle,
+ ble_gap_lesc_dhkey_t * * pp_dhkey)
+{
+ SER_REQ_DEC_BEGIN(SD_BLE_GAP_LESC_DHKEY_REPLY);
+
+ SER_ASSERT_NOT_NULL(p_conn_handle);
+ SER_ASSERT_NOT_NULL(pp_dhkey);
+
+ SER_PULL_uint16(p_conn_handle);
+ SER_PULL_COND(pp_dhkey, ble_gap_lesc_dhkey_t_dec);
+
+ SER_REQ_DEC_END;
+}
+
+uint32_t ble_gap_lesc_dhkey_reply_rsp_enc(uint32_t return_code,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len)
+{
+ SER_RSP_ENC_RESULT_ONLY(SD_BLE_GAP_LESC_DHKEY_REPLY);
+}
+
+uint32_t ble_gap_lesc_oob_data_get_req_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ uint16_t * p_conn_handle,
+ ble_gap_lesc_p256_pk_t * * pp_pk_own,
+ ble_gap_lesc_oob_data_t * * pp_oobd_own)
+{
+ SER_REQ_DEC_BEGIN(SD_BLE_GAP_LESC_OOB_DATA_GET);
+
+ SER_ASSERT_NOT_NULL(p_conn_handle);
+ SER_ASSERT_NOT_NULL(pp_oobd_own);
+ SER_ASSERT_NOT_NULL(pp_pk_own);
+
+ SER_PULL_uint16(p_conn_handle);
+ SER_PULL_COND(pp_pk_own, ble_gap_lesc_p256_pk_t_dec);
+ SER_PULL_COND(pp_oobd_own, NULL);
+
+ SER_REQ_DEC_END;
+}
+
+uint32_t ble_gap_lesc_oob_data_get_rsp_enc(uint32_t return_code,
+ ble_gap_lesc_oob_data_t * p_oobd_own,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len)
+{
+ SER_RSP_ENC_BEGIN(SD_BLE_GAP_LESC_OOB_DATA_GET);
+
+ SER_PUSH_COND(p_oobd_own, ble_gap_lesc_oob_data_t_enc);
+
+ SER_RSP_ENC_END;
+}
+
+uint32_t ble_gap_lesc_oob_data_set_req_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ uint16_t * p_conn_handle,
+ ble_gap_lesc_oob_data_t * * pp_oobd_own,
+ ble_gap_lesc_oob_data_t * * pp_oobd_peer)
+{
+ SER_REQ_DEC_BEGIN(SD_BLE_GAP_LESC_OOB_DATA_SET);
+
+ SER_ASSERT_NOT_NULL(p_conn_handle);
+ SER_ASSERT_NOT_NULL(pp_oobd_own);
+ SER_ASSERT_NOT_NULL(pp_oobd_peer);
+
+ SER_PULL_uint16(p_conn_handle);
+ SER_PULL_COND(pp_oobd_own, ble_gap_lesc_oob_data_t_dec);
+ SER_PULL_COND(pp_oobd_peer, ble_gap_lesc_oob_data_t_dec);
+
+ SER_REQ_DEC_END;
+}
+
+uint32_t ble_gap_lesc_oob_data_set_rsp_enc(uint32_t return_code,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len)
+{
+ SER_RSP_ENC_RESULT_ONLY(SD_BLE_GAP_LESC_OOB_DATA_SET);
+}
+
+uint32_t ble_gap_ppcp_get_req_dec(uint8_t const * const p_buf,
+ uint16_t packet_len,
+ ble_gap_conn_params_t * * const pp_conn_params)
+{
+ SER_REQ_DEC_BEGIN(SD_BLE_GAP_PPCP_GET);
+
+ SER_ASSERT_NOT_NULL(pp_conn_params);
+ SER_ASSERT_NOT_NULL(*pp_conn_params);
+ SER_ASSERT_LENGTH_LEQ(2, packet_len);
+
+ SER_PULL_COND(pp_conn_params, NULL);
+
+ SER_REQ_DEC_END;
+}
+
+
+uint32_t ble_gap_ppcp_get_rsp_enc(uint32_t return_code,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len,
+ ble_gap_conn_params_t const * const p_conn_params)
+{
+ SER_RSP_ENC_BEGIN(SD_BLE_GAP_PPCP_GET);
+
+ SER_PUSH_COND(p_conn_params, ble_gap_conn_params_t_enc);
+
+ SER_RSP_ENC_END;
+}
+
+
+uint32_t ble_gap_ppcp_set_req_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ ble_gap_conn_params_t * * const pp_conn_params)
+{
+ SER_REQ_DEC_BEGIN(SD_BLE_GAP_PPCP_SET);
+
+ SER_ASSERT_NOT_NULL(pp_conn_params);
+ SER_PULL_COND(pp_conn_params, ble_gap_conn_params_t_dec);
+
+ SER_REQ_DEC_END;
+}
+
+
+uint32_t ble_gap_ppcp_set_rsp_enc(uint32_t return_code,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len)
+{
+ SER_RSP_ENC_RESULT_ONLY(SD_BLE_GAP_PPCP_SET);
+}
+
+uint32_t ble_gap_rssi_get_req_dec(uint8_t const * const p_buf,
+ uint16_t packet_len,
+ uint16_t * p_conn_handle,
+ int8_t * * const pp_rssi
+#if NRF_SD_BLE_API_VERSION > 5
+ ,uint8_t * * const pp_ch_index
+#endif
+ )
+{
+ SER_REQ_DEC_BEGIN(SD_BLE_GAP_RSSI_GET);
+
+ SER_ASSERT_NOT_NULL(p_conn_handle);
+ SER_ASSERT_NOT_NULL(pp_rssi);
+ SER_ASSERT_NOT_NULL(*pp_rssi);
+
+ SER_PULL_uint16(p_conn_handle);
+ SER_PULL_COND(pp_rssi, NULL);
+#if NRF_SD_BLE_API_VERSION > 5
+ SER_ASSERT_NOT_NULL(pp_ch_index);
+ SER_ASSERT_NOT_NULL(*pp_ch_index);
+ SER_PULL_COND(pp_ch_index, NULL);
+#endif
+ SER_REQ_DEC_END;
+}
+
+
+uint32_t ble_gap_rssi_get_rsp_enc(uint32_t return_code,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len,
+ int8_t * p_rssi
+#if NRF_SD_BLE_API_VERSION > 5
+ ,uint8_t * p_ch_index
+#endif
+ )
+{
+ SER_RSP_ENC_BEGIN(SD_BLE_GAP_RSSI_GET);
+
+ SER_PUSH_COND(p_rssi, uint8_t_enc);
+#if NRF_SD_BLE_API_VERSION > 5
+ SER_PUSH_COND(p_ch_index, uint8_t_enc);
+#endif
+
+ SER_RSP_ENC_END;
+}
+
+uint32_t ble_gap_rssi_start_req_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ uint16_t * p_conn_handle,
+ uint8_t * p_threshold_dbm,
+ uint8_t * p_skip_count)
+{
+ SER_REQ_DEC_BEGIN(SD_BLE_GAP_RSSI_START);
+
+ SER_ASSERT_NOT_NULL(p_conn_handle);
+ SER_ASSERT_NOT_NULL(p_threshold_dbm);
+ SER_ASSERT_NOT_NULL(p_skip_count);
+
+ SER_PULL_uint16(p_conn_handle);
+ SER_PULL_uint8(p_threshold_dbm);
+ SER_PULL_uint8(p_skip_count);
+
+ SER_REQ_DEC_END;
+}
+
+uint32_t ble_gap_rssi_start_rsp_enc(uint32_t return_code,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len)
+{
+ SER_RSP_ENC_RESULT_ONLY(SD_BLE_GAP_RSSI_START);
+}
+
+uint32_t ble_gap_rssi_stop_req_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ uint16_t * p_conn_handle)
+{
+ SER_REQ_DEC_BEGIN(SD_BLE_GAP_RSSI_STOP);
+
+ SER_ASSERT_NOT_NULL(p_conn_handle);
+ SER_PULL_uint16(p_conn_handle);
+
+ SER_REQ_DEC_END;
+}
+
+uint32_t ble_gap_rssi_stop_rsp_enc(uint32_t return_code,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len)
+{
+ SER_RSP_ENC_RESULT_ONLY(SD_BLE_GAP_RSSI_STOP);
+}
+
+#ifndef S112
+uint32_t ble_gap_scan_start_req_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ ble_gap_scan_params_t * * const pp_scan_params
+#if defined(NRF_SD_BLE_API_VERSION) && NRF_SD_BLE_API_VERSION > 5
+ ,ble_data_t * * const pp_adv_report_buffer
+#endif
+ )
+{
+ SER_REQ_DEC_BEGIN(SD_BLE_GAP_SCAN_START);
+
+ SER_ASSERT_NOT_NULL(pp_scan_params);
+ SER_ASSERT_NOT_NULL(*pp_scan_params);
+
+ SER_PULL_COND(pp_scan_params, ble_gap_scan_params_t_dec);
+#if defined(NRF_SD_BLE_API_VERSION) && NRF_SD_BLE_API_VERSION > 5
+ SER_PULL_COND(pp_adv_report_buffer, ble_data_t_dec);
+#endif
+
+ SER_REQ_DEC_END;
+}
+
+uint32_t ble_gap_scan_start_rsp_enc(uint32_t return_code,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len)
+{
+ SER_RSP_ENC_RESULT_ONLY(SD_BLE_GAP_SCAN_START);
+}
+
+uint32_t ble_gap_scan_stop_rsp_enc(uint32_t return_code,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len)
+{
+ SER_RSP_ENC_RESULT_ONLY(SD_BLE_GAP_SCAN_STOP);
+}
+
+uint32_t ble_gap_connect_req_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ ble_gap_addr_t * * const pp_addr,
+ ble_gap_scan_params_t * * const pp_scan_params,
+ ble_gap_conn_params_t * * const pp_conn_params
+#if NRF_SD_BLE_API_VERSION >= 4
+ ,uint8_t * p_conn_cfg_tag
+#endif
+ )
+{
+ SER_REQ_DEC_BEGIN(SD_BLE_GAP_CONNECT);
+
+ SER_ASSERT_NOT_NULL(pp_addr);
+ SER_ASSERT_NOT_NULL(*pp_addr);
+ SER_ASSERT_NOT_NULL(pp_scan_params);
+ SER_ASSERT_NOT_NULL(*pp_scan_params);
+ SER_ASSERT_NOT_NULL(pp_conn_params);
+ SER_ASSERT_NOT_NULL(*pp_conn_params);
+
+ SER_PULL_COND(pp_addr, ble_gap_addr_t_dec);
+ SER_PULL_COND(pp_scan_params, ble_gap_scan_params_t_dec);
+ SER_PULL_COND(pp_conn_params, ble_gap_conn_params_t_dec);
+#if NRF_SD_BLE_API_VERSION >= 4
+ SER_PULL_uint8(p_conn_cfg_tag);
+#endif
+
+ SER_REQ_DEC_END;
+}
+
+uint32_t ble_gap_connect_rsp_enc(uint32_t return_code,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len)
+{
+ SER_RSP_ENC_RESULT_ONLY(SD_BLE_GAP_CONNECT);
+}
+uint32_t ble_gap_connect_cancel_rsp_enc(uint32_t return_code,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len)
+{
+ SER_RSP_ENC_RESULT_ONLY(SD_BLE_GAP_CONNECT_CANCEL);
+}
+#endif //S112
+
+uint32_t ble_gap_sec_info_reply_req_dec(uint8_t const * const p_buf,
+ uint16_t packet_len,
+ uint16_t * p_conn_handle,
+ ble_gap_enc_info_t * * const pp_enc_info,
+ ble_gap_irk_t * * const pp_id_info,
+ ble_gap_sign_info_t * * const pp_sign_info)
+{
+ SER_REQ_DEC_BEGIN(SD_BLE_GAP_SEC_INFO_REPLY);
+
+ SER_ASSERT_NOT_NULL(p_conn_handle);
+ SER_ASSERT_NOT_NULL(pp_enc_info);
+ SER_ASSERT_NOT_NULL(pp_id_info);
+ SER_ASSERT_NOT_NULL(pp_sign_info);
+ SER_ASSERT_NOT_NULL(*pp_enc_info);
+ SER_ASSERT_NOT_NULL(*pp_id_info);
+ SER_ASSERT_NOT_NULL(*pp_sign_info);
+
+ SER_PULL_uint16(p_conn_handle);
+ SER_PULL_COND(pp_enc_info, ble_gap_enc_info_t_dec);
+ SER_PULL_COND(pp_id_info, ble_gap_irk_t_dec);
+ SER_PULL_COND(pp_sign_info, ble_gap_sign_info_t_dec);
+
+ SER_REQ_DEC_END;
+}
+
+uint32_t ble_gap_sec_info_reply_rsp_enc(uint32_t return_code,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len)
+{
+ SER_RSP_ENC_RESULT_ONLY(SD_BLE_GAP_SEC_INFO_REPLY);
+}
+
+uint32_t ble_gap_sec_params_reply_req_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ uint16_t * p_conn_handle,
+ uint8_t * p_sec_status,
+ ble_gap_sec_params_t * * const pp_sec_params,
+ ble_gap_sec_keyset_t * * const pp_sec_keyset)
+{
+ SER_REQ_DEC_BEGIN(SD_BLE_GAP_SEC_PARAMS_REPLY);
+
+ SER_ASSERT_NOT_NULL(p_conn_handle);
+ SER_ASSERT_NOT_NULL(p_sec_status);
+ SER_ASSERT_NOT_NULL(pp_sec_params);
+ SER_ASSERT_NOT_NULL(*pp_sec_params);
+ SER_ASSERT_NOT_NULL(pp_sec_keyset);
+ SER_ASSERT_NOT_NULL(*pp_sec_keyset);
+
+ SER_PULL_uint16(p_conn_handle);
+ SER_PULL_uint8(p_sec_status);
+ SER_PULL_COND(pp_sec_params, ble_gap_sec_params_t_dec);
+ SER_PULL_COND(pp_sec_keyset, ble_gap_sec_keyset_t_dec);
+
+ SER_REQ_DEC_END;
+}
+
+uint32_t ble_gap_sec_params_reply_rsp_enc(uint32_t return_code,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len,
+ ble_gap_sec_keyset_t * const p_sec_keyset)
+{
+ SER_RSP_ENC_BEGIN(SD_BLE_GAP_SEC_PARAMS_REPLY);
+ SER_PUSH_COND(p_sec_keyset, ble_gap_sec_keyset_t_enc);
+ SER_RSP_ENC_END;
+}
+
+uint32_t ble_gap_tx_power_set_req_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+#if NRF_SD_BLE_API_VERSION > 5
+ uint8_t * p_role, uint16_t * p_handle,
+#endif
+ int8_t * p_tx_power)
+{
+ SER_REQ_DEC_BEGIN(SD_BLE_GAP_TX_POWER_SET);
+
+ SER_ASSERT_NOT_NULL(p_tx_power);
+#if NRF_SD_BLE_API_VERSION > 5
+ SER_PULL_uint8(p_role);
+ SER_PULL_uint16(p_handle);
+#endif
+ SER_PULL_int8(p_tx_power);
+
+ SER_REQ_DEC_END;
+}
+
+uint32_t ble_gap_tx_power_set_rsp_enc(uint32_t return_code,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len)
+{
+ SER_RSP_ENC_RESULT_ONLY(SD_BLE_GAP_TX_POWER_SET);
+}
+
+
+uint32_t ble_gap_addr_get_req_dec(uint8_t const * const p_buf,
+ uint16_t packet_len,
+ ble_gap_addr_t * * const pp_address)
+{
+ SER_REQ_DEC_BEGIN(SD_BLE_GAP_ADDR_GET);
+ SER_PULL_COND(pp_address, NULL);
+ SER_REQ_DEC_END;
+}
+
+
+uint32_t ble_gap_addr_get_rsp_enc(uint32_t return_code,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len,
+ ble_gap_addr_t const * const p_address)
+{
+ SER_RSP_ENC_BEGIN(SD_BLE_GAP_ADDR_GET);
+ SER_PUSH_FIELD(p_address, ble_gap_addr_t_enc);
+ SER_RSP_ENC_END;
+}
+
+
+uint32_t ble_gap_addr_set_req_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ ble_gap_addr_t * * const pp_addr)
+{
+ SER_REQ_DEC_BEGIN(SD_BLE_GAP_ADDR_SET);
+ SER_PULL_COND(pp_addr, ble_gap_addr_t_dec);
+ SER_REQ_DEC_END;
+}
+
+
+uint32_t ble_gap_addr_set_rsp_enc(uint32_t return_code,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len)
+{
+ SER_RSP_ENC_RESULT_ONLY(SD_BLE_GAP_ADDR_SET);
+}
+
+uint32_t ble_gap_privacy_set_req_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ ble_gap_privacy_params_t * * const pp_privacy_params)
+{
+ SER_REQ_DEC_BEGIN(SD_BLE_GAP_PRIVACY_SET);
+ SER_PULL_COND(pp_privacy_params, ble_gap_privacy_params_t_dec);
+ SER_REQ_DEC_END;
+}
+
+uint32_t ble_gap_privacy_set_rsp_enc(uint32_t return_code,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len)
+{
+ SER_RSP_ENC_RESULT_ONLY(SD_BLE_GAP_PRIVACY_SET);
+}
+
+uint32_t ble_gap_privacy_get_req_dec(uint8_t const * const p_buf,
+ uint16_t packet_len,
+ ble_gap_privacy_params_t * * const pp_privacy_params)
+{
+ SER_REQ_DEC_BEGIN(SD_BLE_GAP_PRIVACY_GET);
+ SER_PULL_COND(pp_privacy_params, ble_gap_privacy_params_t_dec);
+ SER_REQ_DEC_END;
+}
+
+uint32_t ble_gap_privacy_get_rsp_enc(uint32_t return_code,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len,
+ ble_gap_privacy_params_t const * const p_privacy_params)
+{
+ SER_RSP_ENC_BEGIN(SD_BLE_GAP_PRIVACY_GET);
+ SER_PUSH_COND(p_privacy_params, ble_gap_privacy_params_t_enc);
+ SER_RSP_ENC_END;
+}
+
+uint32_t ble_gap_whitelist_set_req_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ ble_gap_addr_t * * * const ppp_wl_addrs,
+ uint8_t * const p_len)
+{
+ SER_REQ_DEC_BEGIN(SD_BLE_GAP_WHITELIST_SET);
+
+ SER_ASSERT_NOT_NULL(ppp_wl_addrs);
+ SER_ASSERT_NOT_NULL(*ppp_wl_addrs);
+ SER_ASSERT_NOT_NULL(**ppp_wl_addrs);
+
+ uint8_t presence;
+ SER_PULL_uint8(p_len);
+
+ SER_PULL_uint8(&presence);
+ if (presence == SER_FIELD_PRESENT)
+ {
+ ble_gap_addr_t * * const pp_wl_addrs = *ppp_wl_addrs;
+ for (uint32_t i = 0; i < *p_len; ++i)
+ {
+ SER_PULL_COND(&(pp_wl_addrs[i]), ble_gap_addr_t_dec);
+ }
+ }
+ else
+ {
+ *ppp_wl_addrs = NULL;
+ }
+
+ SER_REQ_DEC_END;
+}
+
+uint32_t ble_gap_whitelist_set_rsp_enc(uint32_t return_code,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len)
+{
+ SER_RSP_ENC_RESULT_ONLY(SD_BLE_GAP_WHITELIST_SET);
+}
+
+uint32_t ble_gap_device_identities_set_req_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ ble_gap_id_key_t * * * const ppp_id_keys,
+ ble_gap_irk_t * * * const ppp_local_irks,
+ uint8_t * const p_len)
+{
+ SER_REQ_DEC_BEGIN(SD_BLE_GAP_DEVICE_IDENTITIES_SET);
+
+ SER_ASSERT_NOT_NULL(ppp_id_keys);
+ SER_ASSERT_NOT_NULL(*ppp_id_keys);
+ SER_ASSERT_NOT_NULL(**ppp_id_keys);
+ SER_ASSERT_NOT_NULL(ppp_local_irks);
+ SER_ASSERT_NOT_NULL(*ppp_local_irks);
+ SER_ASSERT_NOT_NULL(**ppp_local_irks);
+
+ uint8_t presence;
+ SER_PULL_uint8(p_len);
+
+ SER_PULL_uint8(&presence);
+ if (presence == SER_FIELD_PRESENT)
+ {
+ ble_gap_id_key_t * * const pp_id_keys = *ppp_id_keys;
+ for (uint32_t i = 0; i < *p_len; ++i)
+ {
+ SER_PULL_COND(&(pp_id_keys[i]), ble_gap_id_key_t_dec);
+ }
+ }
+ else
+ {
+ *ppp_id_keys = NULL;
+ }
+ SER_PULL_uint8(&presence);
+ if (presence == SER_FIELD_PRESENT)
+ {
+ ble_gap_irk_t * * const pp_local_irks = *ppp_local_irks;
+ for (uint32_t i = 0; i < *p_len; ++i)
+ {
+ SER_PULL_COND(&(pp_local_irks[i]), ble_gap_irk_t_dec);
+ }
+ }
+ else
+ {
+ *ppp_local_irks = NULL;
+ }
+
+ SER_REQ_DEC_END;
+}
+
+uint32_t ble_gap_device_identities_set_rsp_enc(uint32_t return_code,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len)
+{
+ SER_RSP_ENC_RESULT_ONLY(SD_BLE_GAP_DEVICE_IDENTITIES_SET);
+}
+
+#if NRF_SD_BLE_API_VERSION >= 4 && !defined(S112)
+uint32_t ble_gap_data_length_update_req_dec(uint8_t const * const p_buf,
+ uint16_t packet_len,
+ uint16_t * p_conn_handle,
+ ble_gap_data_length_params_t * * const pp_dl_params,
+ ble_gap_data_length_limitation_t * * const pp_dl_limitation)
+{
+ SER_REQ_DEC_BEGIN(SD_BLE_GAP_DATA_LENGTH_UPDATE);
+ SER_PULL_uint16(p_conn_handle);
+ SER_PULL_COND(pp_dl_params, ble_gap_data_length_params_t_dec);
+ SER_PULL_COND(pp_dl_limitation, NULL);
+ SER_REQ_DEC_END;
+}
+
+
+uint32_t ble_gap_data_length_update_rsp_enc(uint32_t return_code,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len,
+ ble_gap_data_length_limitation_t const * const p_dl_limitation)
+{
+ SER_RSP_ENC_BEGIN(SD_BLE_GAP_DATA_LENGTH_UPDATE);
+ SER_PUSH_COND(p_dl_limitation, ble_gap_data_length_limitation_t_enc);
+ SER_RSP_ENC_END;
+}
+#endif //NRF_SD_BLE_API_VERSION >= 4 && !defined(S112)
+
+#if NRF_SD_BLE_API_VERSION >= 5
+uint32_t ble_gap_phy_update_req_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ uint16_t * const p_conn_handle,
+ ble_gap_phys_t * * const pp_gap_phys)
+{
+ SER_REQ_DEC_BEGIN(SD_BLE_GAP_PHY_UPDATE);
+
+ SER_ASSERT_NOT_NULL(p_conn_handle);
+ SER_ASSERT_NOT_NULL(pp_gap_phys);
+ SER_ASSERT_NOT_NULL(*pp_gap_phys);
+ SER_PULL_uint16(p_conn_handle);
+ SER_PULL_COND(pp_gap_phys, ble_gap_phys_t_dec);
+
+ SER_REQ_DEC_END;
+}
+
+
+uint32_t ble_gap_phy_update_rsp_enc(uint32_t return_code,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len)
+{
+ SER_RSP_ENC_RESULT_ONLY(SD_BLE_GAP_PHY_UPDATE);
+}
+#endif //RF_SD_BLE_API_VERSION >= 5
+
+#if defined(NRF_SD_BLE_API_VERSION) && NRF_SD_BLE_API_VERSION > 5
+uint32_t ble_gap_adv_set_configure_req_dec(uint8_t const * const p_buf,
+ uint16_t packet_len,
+ uint8_t * * const pp_adv_handle,
+ ble_gap_adv_data_t **const pp_adv_data,
+ ble_gap_adv_params_t **const pp_adv_params)
+{
+ SER_REQ_DEC_BEGIN(SD_BLE_GAP_ADV_SET_CONFIGURE);
+
+ SER_ASSERT_NOT_NULL(pp_adv_handle);
+ SER_ASSERT_NOT_NULL(*pp_adv_handle);
+ SER_ASSERT_NOT_NULL(pp_adv_data);
+ SER_ASSERT_NOT_NULL(*pp_adv_data);
+ SER_ASSERT_NOT_NULL(pp_adv_params);
+ SER_ASSERT_NOT_NULL(*pp_adv_params);
+
+ SER_PULL_COND(pp_adv_handle, uint8_t_dec);
+ SER_PULL_COND(pp_adv_data, ble_gap_adv_data_t_dec);
+ SER_PULL_COND(pp_adv_params, ble_gap_adv_params_t_dec);
+
+ SER_REQ_DEC_END;
+}
+
+
+uint32_t ble_gap_adv_set_configure_rsp_enc(uint32_t return_code,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len,
+ uint8_t const * const p_adv_handle)
+{
+ SER_RSP_ENC_BEGIN(SD_BLE_GAP_ADV_SET_CONFIGURE);
+
+ SER_PUSH_COND(p_adv_handle, uint8_t_enc);
+ SER_RSP_ENC_END;
+}
+
+#ifndef S112
+uint32_t ble_gap_qos_channel_survey_start_req_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ uint32_t * const p_interval_us)
+{
+ SER_REQ_DEC_BEGIN(SD_BLE_GAP_QOS_CHANNEL_SURVEY_START);
+
+ SER_ASSERT_NOT_NULL(p_interval_us);
+ SER_PULL_uint32(p_interval_us);
+ SER_REQ_DEC_END;
+}
+
+
+uint32_t ble_gap_qos_channel_survey_start_rsp_enc(uint32_t return_code,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len)
+{
+ SER_RSP_ENC_RESULT_ONLY(SD_BLE_GAP_QOS_CHANNEL_SURVEY_START);
+}
+
+uint32_t ble_gap_qos_channel_survey_stop_req_dec(uint8_t const * const p_buf,
+ uint32_t packet_len)
+{
+ SER_REQ_DEC_BEGIN(SD_BLE_GAP_QOS_CHANNEL_SURVEY_STOP);
+ SER_REQ_DEC_END;
+}
+
+
+uint32_t ble_gap_qos_channel_survey_stop_rsp_enc(uint32_t return_code,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len)
+{
+ SER_RSP_ENC_RESULT_ONLY(SD_BLE_GAP_QOS_CHANNEL_SURVEY_STOP);
+}
+#endif
+#endif
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/connectivity/codecs/ble/serializers/ble_gap_conn.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/connectivity/codecs/ble/serializers/ble_gap_conn.h
new file mode 100644
index 0000000..4464552
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/connectivity/codecs/ble/serializers/ble_gap_conn.h
@@ -0,0 +1,1526 @@
+/**
+ * Copyright (c) 2013 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#ifndef BLE_GAP_CONN_H__
+#define BLE_GAP_CONN_H__
+
+/**@file
+ *
+ * @defgroup ble_gap_conn GAP Connectivity command request decoders and command response encoders
+ * @{
+ * @ingroup ser_conn_s130_codecs
+ *
+ * @brief GAP Connectivity command request decoders and command response encoders
+ */
+#include "ble_gap.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**@brief Decodes @ref sd_ble_gap_authenticate command request.
+ *
+ * @sa @ref ble_gap_authenticate_rsp_enc for response encoding.
+ *
+ * @param[in] p_buf Pointer to beginning of command request packet.
+ * @param[in] packet_len Length (in bytes) of response packet.
+ * @param[out] p_conn_handle Pointer to connection handle
+ * @param[out] pp_sec_params Pointer to pointer to security parameters.
+ *
+ * @retval NRF_SUCCESS Decoding success.
+ * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length.
+ * @retval NRF_ERROR_INVALID_PARAM Decoding failure. Invalid operation type.
+ */
+uint32_t ble_gap_authenticate_req_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ uint16_t * const p_conn_handle,
+ ble_gap_sec_params_t * * const pp_sec_params);
+
+/**@brief Encodes @ref sd_ble_gap_authenticate command response.
+ *
+ * @sa @ref ble_gap_authenticate_req_dec for request decoding.
+ *
+ * @param[in] return_code Return code indicating if command was successful or not.
+ * @param[out] p_buf Pointer to buffer where encoded data command response will be
+ * returned.
+ * @param[in,out] p_buf_len \c in: size of \p p_buf buffer.
+ * \c out: Length of encoded command response packet.
+ *
+ * @retval NRF_SUCCESS Encoding success.
+ * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length.
+ */
+uint32_t ble_gap_authenticate_rsp_enc(uint32_t return_code,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len);
+
+#if defined(NRF_SD_BLE_API_VERSION) && (NRF_SD_BLE_API_VERSION <= 5)
+/**@brief Decodes @ref sd_ble_gap_adv_data_set command request.
+ *
+ * @sa @ref ble_gap_adv_data_set_rsp_enc for response encoding.
+ *
+ * @param[in] p_buf Pointer to beginning of command request packet.
+ * @param[in] packet_len Length (in bytes) of request packet.
+ * @param[out] pp_data Pointer to the buffer raw data to be placed in advertisement packet.
+ * @param[out] p_dlen Pointer to data length for p_data.
+ * @param[out] pp_sr_data Pointer to the buffer raw data to be placed in scan response packet.
+ * @param[out] p_srdlen Pointer to data length for p_sr_data.
+ *
+ * @retval NRF_SUCCESS Decoding success.
+ * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length.
+ */
+uint32_t ble_gap_adv_data_set_req_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ uint8_t * * const pp_data,
+ uint8_t * p_dlen,
+ uint8_t * * const pp_sr_data,
+ uint8_t * p_srdlen);
+
+/**@brief Encodes @ref sd_ble_gap_adv_data_set command response.
+ *
+ * @sa @ref ble_gap_adv_data_set_req_dec for request decoding.
+ *
+ * @param[in] return_code Return code indicating if command was successful or not.
+ * @param[out] p_buf Pointer to buffer where encoded data command response will be
+ * returned.
+ * @param[in,out] p_buf_len \c in: size of \p p_buf buffer.
+ * \c out: Length of encoded command response packet.
+ *
+ * @retval NRF_SUCCESS Encoding success.
+ * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length.
+ */
+uint32_t ble_gap_adv_data_set_rsp_enc(uint32_t return_code,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len);
+#endif
+/**@brief Decodes @ref sd_ble_gap_adv_start command request.
+ *
+ * @sa @ref ble_gap_adv_start_rsp_enc for response encoding.
+ *
+ * @param[in] p_buf Pointer to beginning of command request packet.
+ * @param[in] packet_len Length (in bytes) of response packet.
+ * @param[out] pp_adv_params Pointer to pointer to advertising parameters.
+ *
+ * @retval NRF_SUCCESS Decoding success.
+ * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length.
+ * @retval NRF_ERROR_INVALID_PARAM Decoding failure. Invalid operation type.
+ */
+uint32_t ble_gap_adv_start_req_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+#if NRF_SD_BLE_API_VERSION > 5
+ uint8_t * p_adv_handle
+#else
+ ble_gap_adv_params_t * * const pp_adv_params
+#endif
+#if NRF_SD_BLE_API_VERSION >= 4
+ ,uint8_t * p_conn_cfg_tag
+#endif
+ );
+
+/**@brief Encodes @ref sd_ble_gap_adv_start command response.
+ *
+ * @sa @ref ble_gap_adv_start_req_dec for request decoding.
+ *
+ * @param[in] return_code Return code indicating if command was successful or not.
+ * @param[out] p_buf Pointer to buffer where encoded data command response will be
+ * returned.
+ * @param[in,out] p_buf_len \c in: size of \p p_buf buffer.
+ * \c out: Length of encoded command response packet.
+ *
+ * @retval NRF_SUCCESS Encoding success.
+ * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length.
+ */
+uint32_t ble_gap_adv_start_rsp_enc(uint32_t return_code,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len);
+
+/**@brief Decodes @ref sd_ble_gap_device_name_get command request.
+ *
+ * @sa @ref ble_gap_device_name_get_rsp_enc for response encoding.
+ *
+ * @param[in] p_buf Pointer to beginning of command request packet.
+ * @param[in] packet_len Length (in bytes) of response packet.
+ * @param[out] pp_dev_name Pointer to pointer to device name buffer.
+ * @param[out] pp_dev_name_len Pointer to pointer to device name length location.
+ *
+ * @retval NRF_SUCCESS Decoding success.
+ * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length.
+ */
+uint32_t ble_gap_device_name_get_req_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ uint8_t * * pp_dev_name,
+ uint16_t * * pp_dev_name_len);
+
+/**@brief Encodes @ref sd_ble_gap_device_name_get command response.
+ *
+ * @param[in] return_code Return code indicating if command was successful or not.
+ * @param[in] p_dev_name Pointer to device name buffer.
+ * @param[in] p_dev_name_len Length of device name buffer.
+ * @param[in] p_buf Pointer to buffer where encoded data command response will be
+ * returned.
+ * @param[in, out] p_buf_len \c in: size of \p p_buf buffer.
+ * \c out: Length of encoded command response packet.
+ *
+ * @retval NRF_SUCCESS Encoding success.
+ * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length.
+ */
+uint32_t ble_gap_device_name_get_rsp_enc(uint32_t return_code,
+ uint8_t const * const p_dev_name,
+ uint16_t * p_dev_name_len,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len);
+
+/**@brief Decodes @ref sd_ble_gap_conn_param_update command request.
+ *
+ * @sa @ref ble_gap_conn_param_update_rsp_enc for response encoding.
+ *
+ * @param[in] p_buf Pointer to beginning of command request packet.
+ * @param[in] packet_len Length (in bytes) of response packet.
+ * @param[out] p_conn_handle Pointer to connection handle.
+ * @param[out] pp_conn_params Pointer to pointer to connection parameters.
+ *
+ * @retval NRF_SUCCESS Decoding success.
+ * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length.
+ * @retval NRF_ERROR_INVALID_PARAM Decoding failure. Invalid operation type.
+ * @retval NRF_ERROR_INVALID_DATA Decoding failure. Invalid value for connection
+ * parameters field present.
+ */
+uint32_t ble_gap_conn_param_update_req_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ uint16_t * p_conn_handle,
+ ble_gap_conn_params_t * * const pp_conn_params);
+
+/**@brief Encodes @ref sd_ble_gap_conn_param_update command response.
+ *
+ * @param[in] return_code Return code indicating if command was successful or not.
+ * @param[in] p_buf Pointer to buffer where encoded data command response will be
+ * returned.
+ * @param[in, out] p_buf_len \c in: size of \p p_buf buffer.
+ * \c out: Length of encoded command response packet.
+ *
+ * @retval NRF_SUCCESS Encoding success.
+ * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length.
+ */
+uint32_t ble_gap_conn_param_update_rsp_enc(uint32_t return_code,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len);
+
+
+/**@brief Decodes @ref sd_ble_gap_disconnect command request.
+ *
+ * @sa @ref ble_gap_disconnect_rsp_enc for response encoding.
+ *
+ * @param[in] p_buf Pointer to beginning of command request packet.
+ * @param[in] packet_len Length (in bytes) of response packet.
+ * @param[in] p_conn_handle Pointer to Connection Handle.
+ * @param[in] p_hci_status Pointer to HCI Status Code.
+ *
+ * @retval NRF_SUCCESS Decoding success.
+ * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length.
+ * @retval NRF_ERROR_INVALID_PARAM Decoding failure. Invalid operation type.
+ */
+uint32_t ble_gap_disconnect_req_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ uint16_t * const p_conn_handle,
+ uint8_t * const p_hci_status);
+
+/**@brief Encodes @ref sd_ble_gap_disconnect command response.
+ *
+ * @param[in] return_code Return code indicating if command was successful or not.
+ * @param[in] p_buf Pointer to buffer where encoded data command response will be
+ * returned.
+ * @param[in, out] p_buf_len \c in: size of \p p_buf buffer.
+ * \c out: Length of encoded command response packet.
+ *
+ * @retval NRF_SUCCESS Encoding success.
+ * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length.
+ */
+uint32_t ble_gap_disconnect_rsp_enc(uint32_t return_code,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len);
+
+/**@brief Decodes @ref sd_ble_gap_tx_power_set command request.
+ *
+ * @sa @ref ble_gap_tx_power_set_rsp_enc for response encoding.
+ *
+ * @param[in] p_buf Pointer to beginning of command request packet.
+ * @param[in] packet_len Length (in bytes) of response packet.
+ * @param[in] p_tx_power Pointer to TX power value.
+ *
+ * @retval NRF_SUCCESS Decoding success.
+ * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length.
+ * @retval NRF_ERROR_INVALID_PARAM Decoding failure. Invalid operation type.
+ */
+uint32_t ble_gap_tx_power_set_req_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+#if NRF_SD_BLE_API_VERSION > 5
+ uint8_t * p_role, uint16_t * p_handle,
+#endif
+ int8_t * p_tx_power);
+
+/**@brief Encodes @ref sd_ble_gap_tx_power_set command response.
+ *
+ * @param[in] return_code Return code indicating if command was successful or not.
+ * @param[in] p_buf Pointer to buffer where encoded data command response will be
+ * returned.
+ * @param[in, out] p_buf_len \c in: size of \p p_buf buffer.
+ * \c out: Length of encoded command response packet.
+ *
+ * @retval NRF_SUCCESS Encoding success.
+ * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length.
+ */
+uint32_t ble_gap_tx_power_set_rsp_enc(uint32_t return_code,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len);
+
+/**@brief Decodes @ref sd_ble_gap_ppcp_set command request.
+ *
+ * @sa @ref ble_gap_ppcp_set_rsp_enc for response encoding.
+ *
+ * @param[in] p_buf Pointer to beginning of command request packet.
+ * @param[in] packet_len Length (in bytes) of response packet.
+ * @param[out] pp_conn_params Pointer to pointer to connection parameters to be set.
+ *
+ * @retval NRF_SUCCESS Decoding success.
+ * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length.
+ * @retval NRF_ERROR_INVALID_PARAM Decoding failure. Invalid operation type.
+ * @retval NRF_ERROR_INVALID_DATA Decoding failure. Invalid value for connection
+ * parameters field present.
+ */
+uint32_t ble_gap_ppcp_set_req_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ ble_gap_conn_params_t * * const pp_conn_params);
+
+/**@brief Encodes @ref sd_ble_gap_ppcp_set command response.
+ *
+ * @param[in] return_code Return code indicating if command was successful or not.
+ * @param[in] p_buf Pointer to buffer where encoded data command response will be
+ * returned.
+ * @param[in, out] p_buf_len \c in: size of \p p_buf buffer.
+ * \c out: Length of encoded command response packet.
+ *
+ * @retval NRF_SUCCESS Encoding success.
+ * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length.
+ */
+uint32_t ble_gap_ppcp_set_rsp_enc(uint32_t return_code,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len);
+
+
+/**@brief Decodes @ref sd_ble_gap_ppcp_get command request.
+ *
+ * @sa @ref ble_gap_ppcp_get_rsp_enc for response encoding.
+ *
+ * @param[in] p_buf Pointer to beginning of command request packet.
+ * @param[in] packet_len Length (in bytes) of response packet.
+ * @param[out] pp_conn_params Pointer to pointer to ble_gap_conn_params_t.
+ *
+ * @retval NRF_SUCCESS Decoding success.
+ * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length.
+ * @retval NRF_ERROR_INVALID_PARAM Decoding failure. Invalid operation type.
+ */
+uint32_t ble_gap_ppcp_get_req_dec(uint8_t const * const p_buf,
+ uint16_t packet_len,
+ ble_gap_conn_params_t * * const pp_conn_params);
+
+/**@brief Encodes @ref sd_ble_gap_ppcp_get command response.
+ *
+ * @sa @ref ble_gap_ppcp_get_req_dec for request decoding.
+ *
+ * @param[in] return_code Return code indicating if command was successful or not.
+ * @param[out] p_buf Pointer to buffer where encoded data command response will be
+ * returned.
+ * @param[in,out] p_buf_len \c in: size of \p p_buf buffer.
+ * \c out: Length of encoded command response packet.
+ * @param[in] p_conn_params Pointer to ble_gap_conn_params_t.
+ *
+ * @retval NRF_SUCCESS Encoding success.
+ * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length.
+ */
+uint32_t ble_gap_ppcp_get_rsp_enc(uint32_t return_code,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len,
+ ble_gap_conn_params_t const * const p_conn_params);
+
+
+uint32_t ble_gap_adv_stop_req_dec(uint8_t const * const p_buf,
+ uint16_t packet_len,
+ uint8_t * p_adv_handle);
+/**@brief Encodes @ref sd_ble_gap_adv_stop command response.
+ *
+ * @param[in] return_code Return code indicating if command was successful or not.
+ * @param[in] p_buf Pointer to buffer where encoded data command response will be
+ * returned.
+ * @param[in, out] p_buf_len \c in: size of \p p_buf buffer.
+ * \c out: Length of encoded command response packet.
+ *
+ * @retval NRF_SUCCESS Encoding success.
+ * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length.
+ */
+uint32_t ble_gap_adv_stop_rsp_enc(uint32_t return_code,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len);
+
+/**@brief Decodes @ref sd_ble_gap_auth_key_reply command request.
+ *
+ * @sa @ref ble_gap_auth_key_reply_rsp_enc for response encoding.
+ *
+ * @param[in] p_buf Pointer to beginning of command request packet.
+ * @param[in] packet_len Length (in bytes) of response packet.
+ * @param[out] p_conn_handle Pointer to connection handle.
+ * @param[out] p_key_type Pointer to key type.
+ * @param[out] pp_key Pointer to pointer to buffer for incoming key.
+ *
+ * @retval NRF_SUCCESS Decoding success.
+ * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length.
+ * @retval NRF_ERROR_INVALID_PARAM Decoding failure. Invalid operation type.
+ */
+uint32_t ble_gap_auth_key_reply_req_dec(uint8_t const * const p_buf,
+ uint16_t packet_len,
+ uint16_t * p_conn_handle,
+ uint8_t * p_key_type,
+ uint8_t * * const pp_key);
+
+/**@brief Encodes @ref sd_ble_gap_auth_key_reply command response.
+ *
+ * @param[in] return_code Return code indicating if command was successful or not.
+ * @param[in] p_buf Pointer to buffer where encoded data command response will be
+ * returned.
+ * @param[in, out] p_buf_len \c in: size of \p p_buf buffer.
+ * \c out: Length of encoded command response packet.
+ *
+ * @retval NRF_SUCCESS Encoding success.
+ * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length.
+ */
+uint32_t ble_gap_auth_key_reply_rsp_enc(uint32_t return_code,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len);
+
+/**@brief Decodes @ref sd_ble_gap_sec_params_reply command request.
+ *
+ * @sa @ref ble_gap_sec_params_reply_rsp_enc for response encoding.
+ *
+ * @param[in] p_buf Pointer to beginning of command request packet.
+ * @param[in] packet_len Length (in bytes) of response packet.
+ * @param[out] p_conn_handle Pointer to connection handle.
+ * @param[out] p_sec_status Pointer to security status.
+ * @param[out] pp_sec_params Pointer to pointer to security parameters structure.
+ * @param[out] pp_sec_keyset Pointer to pointer to security keyset structure.
+ *
+ * @retval NRF_SUCCESS Decoding success.
+ * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length.
+ * @retval NRF_ERROR_INVALID_PARAM Decoding failure. Invalid operation type.
+ * @retval NRF_ERROR_INVALID_DATA Decoding failure. Invalid value for connection
+ * parameters field present.
+ */
+uint32_t ble_gap_sec_params_reply_req_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ uint16_t * p_conn_handle,
+ uint8_t * p_sec_status,
+ ble_gap_sec_params_t * * const pp_sec_params,
+ ble_gap_sec_keyset_t * * const pp_sec_keyset);
+
+/**@brief Encodes @ref sd_ble_gap_sec_params_reply command response.
+ *
+ * @param[in] return_code Return code indicating if command was successful or not.
+ * @param[in] p_buf Pointer to buffer where encoded data command response will be
+ * returned.
+ * @param[in] p_sec_keyset Pointer to security keyset structure.
+ * @param[in, out] p_buf_len \c in: size of \p p_buf buffer.
+ * \c out: Length of encoded command response packet.
+ *
+ * @retval NRF_SUCCESS Encoding success.
+ * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length.
+ */
+uint32_t ble_gap_sec_params_reply_rsp_enc(uint32_t return_code,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len,
+ ble_gap_sec_keyset_t * const p_sec_keyset);
+
+/**@brief Decodes @ref sd_ble_gap_rssi_start command request.
+ *
+ * @sa @ref ble_gap_rssi_start_rsp_enc for response encoding.
+ *
+ * @param[in] p_buf Pointer to beginning of command request packet.
+ * @param[in] packet_len Length (in bytes) of response packet.
+ * @param[out] p_conn_handle Pointer to connection handle.
+ * @param[out] p_threshold_dbm Pointer to threshold in dBm.
+ * @param[out] p_skip_count Pointer to sample skip count.
+ *
+ * @retval NRF_SUCCESS Decoding success.
+ * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length.
+ * @retval NRF_ERROR_INVALID_PARAM Decoding failure. Invalid operation type.
+ */
+uint32_t ble_gap_rssi_start_req_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ uint16_t * p_conn_handle,
+ uint8_t * p_threshold_dbm,
+ uint8_t * p_skip_count);
+
+/**@brief Encodes @ref sd_ble_gap_rssi_start command response.
+ *
+ * @param[in] return_code Return code indicating if command was successful or not.
+ * @param[in] p_buf Pointer to buffer where encoded data command response will be
+ * returned.
+ * @param[in, out] p_buf_len \c in: size of \p p_buf buffer.
+ * \c out: Length of encoded command response packet.
+ *
+ * @retval NRF_SUCCESS Encoding success.
+ * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length.
+ */
+
+uint32_t ble_gap_rssi_start_rsp_enc(uint32_t return_code,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len);
+
+/**@brief Decodes @ref sd_ble_gap_rssi_stop command request.
+ *
+ * @sa @ref ble_gap_rssi_stop_rsp_enc for response encoding.
+ *
+ * @param[in] p_buf Pointer to beginning of command request packet.
+ * @param[in] packet_len Length (in bytes) of response packet.
+ * @param[out] conn_handle Pointer to connection handle.
+ *
+ * @retval NRF_SUCCESS Decoding success.
+ * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length.
+ * @retval NRF_ERROR_INVALID_PARAM Decoding failure. Invalid operation type.
+ */
+
+uint32_t ble_gap_rssi_stop_req_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ uint16_t * conn_handle);
+
+/**@brief Encodes @ref sd_ble_gap_rssi_stop command response.
+ *
+ * @param[in] return_code Return code indicating if command was successful or not.
+ * @param[in] p_buf Pointer to buffer where encoded data command response will be
+ * returned.
+ * @param[in, out] p_buf_len \c in: size of \p p_buf buffer.
+ * \c out: Length of encoded command response packet.
+ *
+ * @retval NRF_SUCCESS Encoding success.
+ * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length.
+ */
+
+uint32_t ble_gap_rssi_stop_rsp_enc(uint32_t return_code,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len);
+
+/**@brief Decodes @ref sd_ble_gap_appearance_get command request.
+ *
+ * @sa @ref ble_gap_appearance_get_rsp_enc for response encoding.
+ *
+ * @param[in] p_buf Pointer to beginning of command request packet.
+ * @param[in] packet_len Length (in bytes) of response packet.
+ * @param[out] pp_appearance Pointer to pointer to uint16_t appearance.
+ *
+ * @retval NRF_SUCCESS Decoding success.
+ * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length.
+ * @retval NRF_ERROR_INVALID_PARAM Decoding failure. Invalid operation type.
+ */
+uint32_t ble_gap_appearance_get_req_dec(uint8_t const * const p_buf,
+ uint16_t packet_len,
+ uint16_t * * const pp_appearance);
+
+/**@brief Encodes @ref sd_ble_gap_appearance_get command response.
+ *
+ * @sa @ref ble_gap_appearance_get_req_dec for request decoding.
+ *
+ * @param[in] return_code Return code indicating if command was successful or not.
+ * @param[out] p_buf Pointer to buffer where encoded data command response will be
+ * returned.
+ * @param[in,out] p_buf_len \c in: size of \p p_buf buffer.
+ * \c out: Length of encoded command response packet.
+ * @param[in] p_appearance Pointer to uint16_t appearance.
+ *
+ * @retval NRF_SUCCESS Encoding success.
+ * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length.
+ */
+uint32_t ble_gap_appearance_get_rsp_enc(uint32_t return_code,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len,
+ uint16_t const * const p_appearance);
+
+
+/**@brief Decodes @ref sd_ble_gap_appearance_set command request.
+ *
+ * @sa @ref ble_gap_tx_power_set_rsp_enc for response encoding.
+ *
+ * @param[in] p_buf Pointer to beginning of command request packet.
+ * @param[in] buf_len Length (in bytes) of the packet.
+ * @param[out] p_appearance Pointer to the appearance.
+ *
+ * @retval NRF_SUCCESS Decoding success.
+ * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length.
+ */
+uint32_t ble_gap_appearance_set_req_dec(uint8_t const * const p_buf,
+ uint32_t buf_len,
+ uint16_t * const p_appearance);
+
+/**@brief Encodes @ref sd_ble_gap_appearance_set command response.
+ *
+ * @param[in] return_code Return code indicating if command was successful or not.
+ * @param[in] p_buf Pointer to buffer where encoded data command response will be
+ * returned.
+ * @param[in, out] p_buf_len \c in: size of \p p_buf buffer.
+ * \c out: Length of encoded command response packet.
+ *
+ * @retval NRF_SUCCESS Encoding success.
+ * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length.
+ */
+uint32_t ble_gap_appearance_set_rsp_enc(uint32_t return_code,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len);
+
+
+/**@brief Decodes @ref sd_ble_gap_sec_info_reply command request.
+ *
+ * @sa @ref ble_gap_sec_info_reply_rsp_enc for response encoding.
+ *
+ * @param[in] p_buf Pointer to beginning of command request packet.
+ * @param[in] packet_len Length (in bytes) of the packet.
+ * @param[out] p_conn_handle Pointer to the Connection Handle.
+ * @param[out] pp_enc_info Pointer to pointer to Encryption Information.
+ * @param[out] pp_id_info Pointer to pointer to ID Information.
+ * @param[out] pp_sign_info Pointer to pointer to Signing Information.
+ *
+ * @retval NRF_SUCCESS Decoding success.
+ * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length.
+ */
+uint32_t ble_gap_sec_info_reply_req_dec(uint8_t const * const p_buf,
+ uint16_t packet_len,
+ uint16_t * p_conn_handle,
+ ble_gap_enc_info_t * * const pp_enc_info,
+ ble_gap_irk_t * * const pp_id_info,
+ ble_gap_sign_info_t * * const pp_sign_info);
+
+/**@brief Encodes @ref sd_ble_gap_sec_info_reply command response.
+ *
+ * @param[in] return_code Return code indicating if command was successful or not.
+ * @param[in] p_buf Pointer to buffer where encoded data command response will be
+ * returned.
+ * @param[in, out] p_buf_len \c in: size of \p p_buf buffer.
+ * \c out: Length of encoded command response packet.
+ *
+ * @retval NRF_SUCCESS Encoding success.
+ * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length.
+ */
+uint32_t ble_gap_sec_info_reply_rsp_enc(uint32_t return_code,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len);
+
+/**@brief Decodes @ref sd_ble_gap_device_name_set command request.
+ *
+ * @sa @ref ble_gap_device_name_set_rsp_enc for response encoding.
+ *
+ * @param[in] p_buf Pointer to beginning of command request packet.
+ * @param[in] packet_len Length (in bytes) of the packet.
+ * @param[out] pp_write_perm Pointer to pointer to write permissions filed.
+ * @param[out] pp_dev_name Pointer to pointer to device name string.
+ * @param[out] p_dev_name_len Pointer to device name string length.
+ *
+ * @retval NRF_SUCCESS Decoding success.
+ * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length.
+ */
+uint32_t ble_gap_device_name_set_req_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ ble_gap_conn_sec_mode_t * * const pp_write_perm,
+ uint8_t * * const pp_dev_name,
+ uint16_t * const p_dev_name_len);
+
+
+/**@brief Encodes @ref sd_ble_gap_device_name_set command response.
+ *
+ * @param[in] return_code Return code indicating if command was successful or not.
+ * @param[in] p_buf Pointer to buffer where encoded data command response will be
+ * returned.
+ * @param[in, out] p_buf_len \c in: size of \p p_buf buffer.
+ * \c out: Length of encoded command response packet.
+ *
+ * @retval NRF_SUCCESS Encoding success.
+ * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length.
+ */
+uint32_t ble_gap_device_name_set_rsp_enc(uint32_t return_code,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len);
+
+/**@brief Decodes @ref sd_ble_gap_conn_sec_get command request.
+ *
+ * @sa @ref ble_gap_conn_sec_get_rsp_enc for response encoding.
+ *
+ * @param[in] p_buf Pointer to beginning of command request packet.
+ * @param[in] packet_len Length (in bytes) of response packet.
+ * @param[out] p_conn_handle Pointer to Connection Handle.
+ * @param[out] pp_conn_sec Pointer to pointer to @ref ble_gap_conn_sec_t to be filled by
+ * the SoftDevice.
+ *
+ * @retval NRF_SUCCESS Decoding success.
+ * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length.
+ * @retval NRF_ERROR_INVALID_PARAM Decoding failure. Invalid operation type.
+ */
+uint32_t ble_gap_conn_sec_get_req_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ uint16_t * p_conn_handle,
+ ble_gap_conn_sec_t * * const pp_conn_sec);
+
+/**@brief Encodes @ref sd_ble_gap_conn_sec_get command response.
+ *
+ * @sa @ref ble_gap_conn_sec_get_req_dec for request decoding.
+ *
+ * @param[in] return_code Return code indicating if command was successful or not.
+ * @param[in] p_conn_sec Pointer to @ref ble_gap_conn_sec_t to be encoded.
+ * @param[out] p_buf Pointer to buffer where encoded data command response will be
+ * returned.
+ * @param[in, out] p_buf_len \c in: size of \p p_buf buffer.
+ * \c out: Length of encoded command response packet.
+ *
+ * @retval NRF_SUCCESS Encoding success.
+ * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length.
+ */
+uint32_t ble_gap_conn_sec_get_rsp_enc(uint32_t return_code,
+ ble_gap_conn_sec_t * const p_conn_sec,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len);
+
+#ifndef S112
+/**@brief Encodes @ref sd_ble_gap_scan_stop command response.
+ *
+ * @param[in] return_code Return code indicating if command was successful or not.
+ * @param[in] p_buf Pointer to buffer where encoded data command response will be
+ * returned.
+ * @param[in, out] p_buf_len \c in: size of \p p_buf buffer.
+ * \c out: Length of encoded command response packet.
+ *
+ * @retval NRF_SUCCESS Encoding success.
+ * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length.
+ */
+uint32_t ble_gap_scan_stop_rsp_enc(uint32_t return_code,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len);
+
+/**@brief Decodes @ref sd_ble_gap_connect command request.
+ *
+ * @sa @ref ble_gap_connect_rsp_enc for response encoding.
+ *
+ * @param[in] p_buf Pointer to beginning of command request packet.
+ * @param[in] packet_len Length (in bytes) of response packet.
+ * @param[out] pp_addr Pointer to pointer to peer address @ref ble_gap_addr_t.
+ * @param[out] pp_scan_params Pointer to pointer to @ref ble_gap_scan_params_t.
+ * @param[out] pp_conn_params Pointer to pointer to @ref ble_gap_conn_params_t.
+ *
+ * @retval NRF_SUCCESS Decoding success.
+ * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length.
+ * @retval NRF_ERROR_INVALID_PARAM Decoding failure. Invalid operation type.
+ */
+uint32_t ble_gap_connect_req_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ ble_gap_addr_t * * const pp_addr,
+ ble_gap_scan_params_t * * const pp_scan_params,
+ ble_gap_conn_params_t * * const pp_conn_params
+#if NRF_SD_BLE_API_VERSION >= 4
+ ,uint8_t * p_conn_cfg_tag
+#endif
+ );
+
+/**@brief Encodes @ref sd_ble_gap_connect command response.
+ *
+ * @sa @ref ble_gap_connect_req_dec for request decoding.
+ *
+ * @param[in] return_code Return code indicating if command was successful or not.
+ * @param[out] p_buf Pointer to buffer where encoded data command response will be
+ * returned.
+ * @param[in, out] p_buf_len \c in: size of \p p_buf buffer.
+ * \c out: Length of encoded command response packet.
+ *
+ * @retval NRF_SUCCESS Encoding success.
+ * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length.
+ */
+uint32_t ble_gap_connect_rsp_enc(uint32_t return_code,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len);
+
+/**@brief Decodes @ref sd_ble_gap_scan_start command request.
+ *
+ * @sa @ref ble_gap_scan_start_rsp_enc for response encoding.
+ *
+ * @param[in] p_buf Pointer to beginning of command request packet.
+ * @param[in] packet_len Length (in bytes) of response packet.
+ * @param[out] pp_scan_params Pointer to pointer to @ref ble_gap_scan_params_t.
+ *
+ * @retval NRF_SUCCESS Decoding success.
+ * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length.
+ * @retval NRF_ERROR_INVALID_PARAM Decoding failure. Invalid operation type.
+ */
+uint32_t ble_gap_scan_start_req_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ ble_gap_scan_params_t * * const pp_scan_params
+#if defined(NRF_SD_BLE_API_VERSION) && NRF_SD_BLE_API_VERSION > 5
+ ,ble_data_t * * const pp_adv_report_buffer
+#endif
+ );
+
+/**@brief Encodes @ref sd_ble_gap_scan_start command response.
+ *
+ * @sa @ref ble_gap_scan_start_req_dec for request decoding.
+ *
+ * @param[in] return_code Return code indicating if command was successful or not.
+ * @param[out] p_buf Pointer to buffer where encoded data command response will be
+ * returned.
+ * @param[in, out] p_buf_len \c in: size of \p p_buf buffer.
+ * \c out: Length of encoded command response packet.
+ *
+ * @retval NRF_SUCCESS Encoding success.
+ * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length.
+ */
+uint32_t ble_gap_scan_start_rsp_enc(uint32_t return_code,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len);
+
+/**@brief Encodes @ref sd_ble_gap_connect_cancel command response.
+ *
+ * @param[in] return_code Return code indicating if command was successful or not.
+ * @param[out] p_buf Pointer to buffer where encoded data command response will be
+ * returned.
+ * @param[in, out] p_buf_len \c in: size of \p p_buf buffer.
+ * \c out: Length of encoded command response packet.
+ *
+ * @retval NRF_SUCCESS Encoding success.
+ * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length.
+ */
+uint32_t ble_gap_connect_cancel_rsp_enc(uint32_t return_code,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len);
+
+
+/**@brief Decodes @ref sd_ble_gap_encrypt command request.
+ *
+ * @sa @ref ble_gap_encrypt_rsp_enc for response encoding.
+ *
+ * @param[in] p_buf Pointer to beginning of command request packet.
+ * @param[in] packet_len Length (in bytes) of response packet.
+ * @param[out] p_conn_handle Pointer connection_handle.
+ * @param[out] pp_master_id Pointer to pointer to @ref ble_gap_master_id_t.
+ * @param[out] pp_enc_info Pointer to pointer to @ref ble_gap_enc_info_t.
+ *
+ * @retval NRF_SUCCESS Decoding success.
+ * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length.
+ * @retval NRF_ERROR_INVALID_PARAM Decoding failure. Invalid operation type.
+ */
+
+uint32_t ble_gap_encrypt_req_dec(uint8_t const * const p_buf,
+ uint16_t packet_len,
+ uint16_t * const p_conn_handle,
+ ble_gap_master_id_t ** const pp_master_id,
+ ble_gap_enc_info_t ** const pp_enc_info);
+
+/**@brief Encodes @ref sd_ble_gap_encrypt command response.
+ *
+ * @param[in] return_code Return code indicating if command was successful or not.
+ * @param[out] p_buf Pointer to buffer where encoded data command response will be
+ * returned.
+ * @param[in, out] p_buf_len \c in: size of \p p_buf buffer.
+ * \c out: Length of encoded command response packet.
+ *
+ * @retval NRF_SUCCESS Encoding success.
+ * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length.
+ */
+uint32_t ble_gap_encrypt_rsp_enc(uint32_t return_code,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len);
+
+#endif
+
+/**@brief Decodes @ref sd_ble_gap_rssi_get command request.
+ *
+ * @sa @ref ble_gap_rssi_get_rsp_enc for response encoding.
+ *
+ * @param[in] p_buf Pointer to beginning of command request packet.
+ * @param[in] packet_len Length (in bytes) of response packet.
+ * @param[in] p_conn_handle Connection handle.
+ * @param[out] pp_rssi Pointer to pointer to RSSI value.
+ *
+ * @retval NRF_SUCCESS Decoding success.
+ * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length.
+ * @retval NRF_ERROR_INVALID_PARAM Decoding failure. Invalid operation type.
+ */
+uint32_t ble_gap_rssi_get_req_dec(uint8_t const * const p_buf,
+ uint16_t packet_len,
+ uint16_t * p_conn_handle,
+ int8_t * * const pp_rssi
+#if NRF_SD_BLE_API_VERSION > 5
+ ,uint8_t * * const pp_ch_index
+#endif
+ );
+
+/**@brief Encodes @ref sd_ble_gap_rssi_get command response.
+ *
+ * @sa @ref ble_gap_rssi_get_req_dec for request decoding.
+ *
+ * @param[in] return_code Return code indicating if command was successful or not.
+ * @param[out] p_buf Pointer to buffer where encoded data command response will be
+ * returned.
+ * @param[in,out] p_buf_len \c in: size of \p p_buf buffer.
+ * \c out: Length of encoded command response packet.
+ * @param[in] p_rssi RSSI value.
+ *
+ * @retval NRF_SUCCESS Encoding success.
+ * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length.
+ */
+uint32_t ble_gap_rssi_get_rsp_enc(uint32_t return_code,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len,
+ int8_t * p_rssi
+#if NRF_SD_BLE_API_VERSION > 5
+ ,uint8_t * p_ch_index
+#endif
+ );
+
+/**@brief Decodes @ref sd_ble_gap_keypress_notify command request.
+ *
+ * @sa @ref ble_gap_keypress_notify_rsp_enc for response encoding.
+ *
+ * @param[in] p_buf Pointer to beginning of command request packet.
+ * @param[in] packet_len Length (in bytes) of response packet.
+ * @param[out] p_conn_handle Connection handle.
+ * @param[out] p_kp_not Pointer kp_not value.
+ *
+ * @retval NRF_SUCCESS Decoding success.
+ * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length.
+ * @retval NRF_ERROR_INVALID_PARAM Decoding failure. Invalid operation type.
+ */
+uint32_t ble_gap_keypress_notify_req_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ uint16_t * p_conn_handle,
+ uint8_t * p_kp_not);
+
+/**@brief Encodes @ref sd_ble_gap_keypress_notify command response.
+ *
+ * @sa @ref ble_gap_keypress_notify_req_dec for request decoding.
+ *
+ * @param[in] return_code Return code indicating if command was successful or not.
+ * @param[out] p_buf Pointer to buffer where encoded data command response will be
+ * returned.
+ * @param[in,out] p_buf_len \c in: size of \p p_buf buffer.
+ * \c out: Length of encoded command response packet.
+ *
+ * @retval NRF_SUCCESS Encoding success.
+ * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length.
+ */
+uint32_t ble_gap_keypress_notify_rsp_enc(uint32_t return_code,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len);
+
+/**@brief Decodes @ref sd_ble_gap_lesc_dhkey_reply command request.
+ *
+ * @sa @ref ble_gap_lesc_dhkey_reply_rsp_enc for response encoding.
+ *
+ * @param[in] p_buf Pointer to beginning of command request packet.
+ * @param[in] packet_len Length (in bytes) of response packet.
+ * @param[out] p_conn_handle Connection handle.
+ * @param[out] pp_dhkey Pointer to pointer to dhkey struct.
+ *
+ * @retval NRF_SUCCESS Decoding success.
+ * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length.
+ * @retval NRF_ERROR_INVALID_PARAM Decoding failure. Invalid operation type.
+ */
+uint32_t ble_gap_lesc_dhkey_reply_req_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ uint16_t * p_conn_handle,
+ ble_gap_lesc_dhkey_t * * pp_dhkey);
+
+/**@brief Encodes @ref sd_ble_gap_lesc_dhkey_reply command response.
+ *
+ * @sa @ref ble_gap_lesc_dhkey_reply_req_dec for request decoding.
+ *
+ * @param[in] return_code Return code indicating if command was successful or not.
+ * @param[out] p_buf Pointer to buffer where encoded data command response will be
+ * returned.
+ * @param[in,out] p_buf_len \c in: size of \p p_buf buffer.
+ * \c out: Length of encoded command response packet.
+ *
+ * @retval NRF_SUCCESS Encoding success.
+ * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length.
+ */
+uint32_t ble_gap_lesc_dhkey_reply_rsp_enc(uint32_t return_code,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len);
+
+/**@brief Decodes @ref sd_ble_gap_lesc_oob_data_set command request.
+ *
+ * @sa @ref ble_gap_lesc_oob_data_set_rsp_enc for response encoding.
+ *
+ * @param[in] p_buf Pointer to beginning of command request packet.
+ * @param[in] packet_len Length (in bytes) of response packet.
+ * @param[out] p_conn_handle Connection handle.
+ * @param[out] pp_oobd_own Pointer to pointer to own OOB data struct.
+ * @param[out] pp_oobd_peer Pointer to pointer to peer OOB data struct.
+ *
+ * @retval NRF_SUCCESS Decoding success.
+ * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length.
+ * @retval NRF_ERROR_INVALID_PARAM Decoding failure. Invalid operation type.
+ */
+uint32_t ble_gap_lesc_oob_data_set_req_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ uint16_t * p_conn_handle,
+ ble_gap_lesc_oob_data_t * * pp_oobd_own,
+ ble_gap_lesc_oob_data_t * * pp_oobd_peer);
+
+/**@brief Encodes @ref sd_ble_gap_lesc_oob_data_set command response.
+ *
+ * @sa @ref ble_gap_lesc_oob_data_set_req_dec for request decoding.
+ *
+ * @param[in] return_code Return code indicating if command was successful or not.
+ * @param[out] p_buf Pointer to buffer where encoded data command response will be
+ * returned.
+ * @param[in,out] p_buf_len \c in: size of \p p_buf buffer.
+ * \c out: Length of encoded command response packet.
+ *
+ * @retval NRF_SUCCESS Encoding success.
+ * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length.
+ */
+uint32_t ble_gap_lesc_oob_data_set_rsp_enc(uint32_t return_code,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len);
+
+/**@brief Decodes @ref sd_ble_gap_lesc_oob_data_get command request.
+ *
+ * @sa @ref ble_gap_lesc_oob_data_get_rsp_enc for response encoding.
+ *
+ * @param[in] p_buf Pointer to beginning of command request packet.
+ * @param[in] packet_len Length (in bytes) of response packet.
+ * @param[out] p_conn_handle Connection handle.
+ * @param[out] pp_pk_own Pointer to pointer to PK.
+ * @param[out] pp_oobd_own Pointer to pointer to own OOB data struct.
+ *
+ * @retval NRF_SUCCESS Decoding success.
+ * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length.
+ * @retval NRF_ERROR_INVALID_PARAM Decoding failure. Invalid operation type.
+ */
+uint32_t ble_gap_lesc_oob_data_get_req_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ uint16_t * p_conn_handle,
+ ble_gap_lesc_p256_pk_t * * pp_pk_own,
+ ble_gap_lesc_oob_data_t * * pp_oobd_own);
+
+/**@brief Encodes @ref sd_ble_gap_lesc_oob_data_get command response.
+ *
+ * @sa @ref ble_gap_lesc_oob_data_get_req_dec for request decoding.
+ *
+ * @param[in] return_code Return code indicating if command was successful or not.
+ * @param[in] p_oobd_own Pointer to OOB data.
+ * @param[out] p_buf Pointer to buffer where encoded data command response will be
+ * returned.
+ * @param[in,out] p_buf_len \c in: size of \p p_buf buffer.
+ * \c out: Length of encoded command response packet.
+ *
+ * @retval NRF_SUCCESS Encoding success.
+ * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length.
+ */
+uint32_t ble_gap_lesc_oob_data_get_rsp_enc(uint32_t return_code,
+ ble_gap_lesc_oob_data_t * p_oobd_own,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len);
+
+/**@brief Decodes @ref sd_ble_gap_addr_get command request.
+ *
+ * @sa @ref ble_gap_addr_get_rsp_enc for response encoding.
+ *
+ * @param[in] p_buf Pointer to beginning of command request packet.
+ * @param[in] packet_len Length (in bytes) of response packet.
+ * @param[out] pp_address Pointer to pointer to address.
+ *
+ * @retval NRF_SUCCESS Decoding success.
+ * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length.
+ * @retval NRF_ERROR_INVALID_PARAM Decoding failure. Invalid operation type.
+ */
+uint32_t ble_gap_addr_get_req_dec(uint8_t const * const p_buf,
+ uint16_t packet_len,
+ ble_gap_addr_t * * const pp_address);
+
+/**@brief Encodes @ref sd_ble_gap_addr_get command response.
+ *
+ * @sa @ref ble_gap_addr_get_req_dec for request decoding.
+ *
+ * @param[in] return_code Return code indicating if command was successful or not.
+ * @param[out] p_buf Pointer to buffer where encoded data command response will be
+ * returned.
+ * @param[in,out] p_buf_len \c in: size of \p p_buf buffer.
+ * \c out: Length of encoded command response packet.
+ * @param[in] p_address Pointer to @ref ble_gap_addr_t address
+ *
+ * @retval NRF_SUCCESS Encoding success.
+ * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length.
+ */
+uint32_t ble_gap_addr_get_rsp_enc(uint32_t return_code,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len,
+ ble_gap_addr_t const * const p_address);
+
+/** @brief Decodes @ref sd_ble_gap_addr_set command request.
+ *
+ * @sa @ref ble_gap_addr_set_rsp_enc for response encoding.
+ *
+ * @param[in] p_buf Pointer to beginning of command request packet.
+ * @param[in] packet_len Length (in bytes) of request packet.
+ * @param[out] pp_addr Pointer to pointer to the address structure.
+
+ * @retval NRF_SUCCESS Decoding success.
+ * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length.
+ */
+uint32_t ble_gap_addr_set_req_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ ble_gap_addr_t * * const pp_addr);
+
+/**@brief Encodes @ref sd_ble_gap_addr_set command response.
+ *
+ * @sa @ref ble_gap_addr_set_req_dec for request decoding.
+ *
+ * @param[in] return_code Return code indicating if command was successful or not.
+ * @param[out] p_buf Pointer to buffer where encoded data command response will be
+ * returned.
+ * @param[in,out] p_buf_len \c in: size of \p p_buf buffer.
+ * \c out: Length of encoded command response packet.
+ *
+ * @retval NRF_SUCCESS Encoding success.
+ * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length.
+ */
+uint32_t ble_gap_addr_set_rsp_enc(uint32_t return_code,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len);
+
+/** @brief Decodes @ref sd_ble_gap_privacy_set command request.
+ *
+ * @sa @ref ble_gap_privacy_set_rsp_enc for response encoding.
+ *
+ * @param[in] p_buf Pointer to beginning of command request packet.
+ * @param[in] packet_len Length (in bytes) of request packet.
+ * @param[out] pp_privacy_params Pointer to pointer to the privacy settings structure.
+
+ * @retval NRF_SUCCESS Decoding success.
+ * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length.
+ */
+uint32_t ble_gap_privacy_set_req_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ ble_gap_privacy_params_t * * const pp_privacy_params);
+
+/**@brief Encodes @ref sd_ble_gap_privacy_set command response.
+ *
+ * @sa @ref ble_gap_privacy_set_req_dec for request decoding.
+ *
+ * @param[in] return_code Return code indicating if command was successful or not.
+ * @param[out] p_buf Pointer to buffer where encoded data command response will be
+ * returned.
+ * @param[in,out] p_buf_len \c in: size of \p p_buf buffer.
+ * \c out: Length of encoded command response packet.
+ *
+ * @retval NRF_SUCCESS Encoding success.
+ * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length.
+ */
+uint32_t ble_gap_privacy_set_rsp_enc(uint32_t return_code,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len);
+
+/** @brief Decodes @ref sd_ble_gap_privacy_get command request.
+ *
+ * @sa @ref ble_gap_privacy_get_rsp_enc for response encoding.
+ *
+ * @param[in] p_buf Pointer to beginning of command request packet.
+ * @param[in] packet_len Length (in bytes) of request packet.
+ * @param[out] pp_privacy_params Pointer to pointer to the privacy settings structure.
+
+ * @retval NRF_SUCCESS Decoding success.
+ * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length.
+ */
+uint32_t ble_gap_privacy_get_req_dec(uint8_t const * const p_buf,
+ uint16_t packet_len,
+ ble_gap_privacy_params_t * * const pp_privacy_params);
+
+/**@brief Encodes @ref sd_ble_gap_privacy_set command response.
+ *
+ * @sa @ref ble_gap_privacy_set_req_dec for request decoding.
+ *
+ * @param[in] return_code Return code indicating if command was successful or not.
+ * @param[out] p_buf Pointer to buffer where encoded data command response will be
+ * returned.
+ * @param[in,out] p_buf_len \c in: size of \p p_buf buffer.
+ * \c out: Length of encoded command response packet.
+ * @param[out] p_privacy_params Pointer to privacy settings structure.
+ *
+ * @retval NRF_SUCCESS Encoding success.
+ * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length.
+ */
+uint32_t ble_gap_privacy_get_rsp_enc(uint32_t return_code,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len,
+ ble_gap_privacy_params_t const * const p_privacy_params);
+
+/** @brief Decodes @ref sd_ble_gap_whitelist_set command request.
+ *
+ * @sa @ref ble_gap_whitelist_set_rsp_enc for response encoding.
+ *
+ * @param[in] p_buf Pointer to beginning of command request packet.
+ * @param[in] packet_len Length (in bytes) of request packet.
+ * @param[out] ppp_wl_addrs Pointer to a whitelist of peer addresses.
+ * @param[out] p_len Pointer to a length of the whitelist.
+ *
+ * @retval NRF_SUCCESS Decoding success.
+ * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length.
+ */
+uint32_t ble_gap_whitelist_set_req_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ ble_gap_addr_t * * * const ppp_wl_addrs,
+ uint8_t * const p_len);
+
+/**@brief Encodes @ref sd_ble_gap_whitelist_set command response.
+ *
+ * @sa @ref ble_gap_whitelist_set_req_dec for request decoding.
+ *
+ * @param[in] return_code Return code indicating if command was successful or not.
+ * @param[out] p_buf Pointer to buffer where encoded data command response will be
+ * returned.
+ * @param[in,out] p_buf_len \c in: size of \p p_buf buffer.
+ * \c out: Length of encoded command response packet.
+ *
+ * @retval NRF_SUCCESS Encoding success.
+ * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length.
+ */
+uint32_t ble_gap_whitelist_set_rsp_enc(uint32_t return_code,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len);
+
+/** @brief Decodes @ref sd_ble_gap_device_identities_set command request.
+ *
+ * @sa @ref ble_gap_device_identities_set_rsp_enc for response encoding.
+ *
+ * @param[in] p_buf Pointer to beginning of command request packet.
+ * @param[in] packet_len Length (in bytes) of request packet.
+ * @param[out] ppp_id_keys Pointer to an array of peer identity addresses and peer IRKs.
+ * @param[out] ppp_local_irks Pointer to an array of local IRKs.
+ * @param[out] p_len Pointer to a length of the device identity list.
+ *
+ * @retval NRF_SUCCESS Decoding success.
+ * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length.
+ */
+uint32_t ble_gap_device_identities_set_req_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ ble_gap_id_key_t * * * const ppp_id_keys,
+ ble_gap_irk_t * * * const ppp_local_irks,
+ uint8_t * const p_len);
+
+/**@brief Encodes @ref sd_ble_gap_device_identities_set command response.
+ *
+ * @sa @ref ble_gap_device_identities_set_req_dec for request decoding.
+ *
+ * @param[in] return_code Return code indicating if command was successful or not.
+ * @param[out] p_buf Pointer to buffer where encoded data command response will be
+ * returned.
+ * @param[in,out] p_buf_len \c in: size of \p p_buf buffer.
+ * \c out: Length of encoded command response packet.
+ *
+ * @retval NRF_SUCCESS Encoding success.
+ * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length.
+ */
+uint32_t ble_gap_device_identities_set_rsp_enc(uint32_t return_code,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len);
+#if NRF_SD_BLE_API_VERSION >= 4 && !defined(S112)
+/** @brief Decodes @ref sd_bble_gap_data_length_update command request.
+ *
+ * @sa @ref ble_gap_data_length_update_rsp_enc for response encoding.
+ *
+ * @param[in] p_buf Pointer to beginning of command request packet.
+ * @param[in] packet_len Length (in bytes) of request packet.
+ * @param[out] p_conn_handle Pointer to a connection handle.
+ * @param[out] pp_dl_params Pointer to pointer to a data length params structure.
+ * @param[out] pp_dl_limitation Pointer to pointer to a data length limitation structure.
+ *
+ * @retval NRF_SUCCESS Decoding success.
+ * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length.
+ */
+uint32_t ble_gap_data_length_update_req_dec(uint8_t const * const p_buf,
+ uint16_t packet_len,
+ uint16_t * p_conn_handle,
+ ble_gap_data_length_params_t * * const pp_dl_params,
+ ble_gap_data_length_limitation_t * * const pp_dl_limitation);
+
+/**@brief Encodes @ref sd_ble_gap_data_length_update command response.
+ *
+ * @sa @ref ble_gap_data_length_update_req_dec for request decoding.
+ *
+ * @param[in] return_code Return code indicating if command was successful or not.
+ * @param[out] p_buf Pointer to buffer where encoded data command response will be
+ * returned.
+ * @param[in,out] p_buf_len \c in: size of \p p_buf buffer.
+ * \c out: Length of encoded command response packet.
+ *
+ * @retval NRF_SUCCESS Encoding success.
+ * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length.
+ */
+uint32_t ble_gap_data_length_update_rsp_enc(uint32_t return_code,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len,
+ ble_gap_data_length_limitation_t const * const p_dl_limitation);
+#endif
+#if NRF_SD_BLE_API_VERSION >= 5
+/**@brief Decodes @ref sd_ble_gap_phy_update command request.
+ *
+ * @sa @ref ble_gap_phy_update_rsp_enc for response encoding.
+ *
+ * @param[in] p_buf Pointer to beginning of command request packet.
+ * @param[in] packet_len Length (in bytes) of response packet.
+ * @param[out] p_conn_handle Pointer to connection handle
+ * @param[out] pp_gap_phys Pointer to pointer to the struct.
+ *
+ * @retval NRF_SUCCESS Decoding success.
+ * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length.
+ * @retval NRF_ERROR_INVALID_PARAM Decoding failure. Invalid operation type.
+ */
+uint32_t ble_gap_phy_update_req_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ uint16_t * const p_conn_handle,
+ ble_gap_phys_t * * const pp_gap_phys);
+
+/**@brief Encodes @ref sd_ble_gap_phy_update command response.
+ *
+ * @sa @ref ble_gap_phy_update_req_dec for request decoding.
+ *
+ * @param[in] return_code Return code indicating if command was successful or not.
+ * @param[out] p_buf Pointer to buffer where encoded data command response will be
+ * returned.
+ * @param[in,out] p_buf_len \c in: size of \p p_buf buffer.
+ * \c out: Length of encoded command response packet.
+ *
+ * @retval NRF_SUCCESS Encoding success.
+ * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length.
+ */
+uint32_t ble_gap_phy_update_rsp_enc(uint32_t return_code,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len);
+#endif
+
+#if NRF_SD_BLE_API_VERSION >= 6
+/**@brief Decodes @ref sd_ble_gap_adv_set_configure command request.
+ *
+ * @sa @ref ble_gap_adv_set_configure_rsp_enc for response encoding.
+ *
+ * @param[in] p_buf Pointer to beginning of command request packet.
+ * @param[in] packet_len Length (in bytes) of response packet.
+ * @param[out] p_conn_handle Pointer to connection handle
+ * @param[out] pp_adv_handle Pointer to pointer to the struct.
+ * @param[out] pp_adv_data Pointer to pointer to the struct.
+ * @param[out] pp_adv_params Pointer to pointer to the struct.
+ *
+ * @retval NRF_SUCCESS Decoding success.
+ * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length.
+ * @retval NRF_ERROR_INVALID_PARAM Decoding failure. Invalid operation type.
+ */
+uint32_t ble_gap_adv_set_configure_req_dec(uint8_t const * const p_buf,
+ uint16_t packet_len,
+ uint8_t * * const pp_adv_handle,
+ ble_gap_adv_data_t **const pp_adv_data,
+ ble_gap_adv_params_t **const pp_adv_params);
+
+
+/**@brief Encodes @ref sd_ble_gap_adv_set_configure command response.
+ *
+ * @sa @ref ble_gap_adv_set_configure_req_dec for request decoding.
+ *
+ * @param[in] return_code Return code indicating if command was successful or not.
+ * @param[out] p_buf Pointer to buffer where encoded data command response will be
+ * returned.
+ * @param[in,out] p_buf_len \c in: size of \p p_buf buffer.
+ * \c out: Length of encoded command response packet.
+ * @param[in] p_adv_handle Pointer to the field to be encoded.
+ *
+ * @retval NRF_SUCCESS Encoding success.
+ * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length.
+ */
+uint32_t ble_gap_adv_set_configure_rsp_enc(uint32_t return_code,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len,
+ uint8_t const * const p_adv_handle);
+
+#ifndef S112
+/**@brief Decodes @ref sd_ble_gap_qos_channel_survey_start command request.
+ *
+ * @sa @ref ble_gap_qos_channel_survey_start_rsp_enc for response encoding.
+ *
+ * @param[in] p_buf Pointer to beginning of command request packet.
+ * @param[in] packet_len Length (in bytes) of response packet.
+ * @param[out] p_interval_us Pointer to interval.
+ *
+ * @retval NRF_SUCCESS Decoding success.
+ * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length.
+ * @retval NRF_ERROR_INVALID_PARAM Decoding failure. Invalid operation type.
+ */
+uint32_t ble_gap_qos_channel_survey_start_req_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ uint32_t * const p_interval_us);
+
+/**@brief Encodes @ref sd_ble_gap_qos_channel_survey_start command response.
+ *
+ * @sa @ref ble_gap_qos_channel_survey_start_req_dec for request decoding.
+ *
+ * @param[in] return_code Return code indicating if command was successful or not.
+ * @param[out] p_buf Pointer to buffer where encoded data command response will be
+ * returned.
+ * @param[in,out] p_buf_len \c in: size of \p p_buf buffer.
+ * \c out: Length of encoded command response packet.
+ *
+ * @retval NRF_SUCCESS Encoding success.
+ * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length.
+ */
+uint32_t ble_gap_qos_channel_survey_start_rsp_enc(uint32_t return_code,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len);
+
+/**@brief Decodes @ref sd_ble_gap_qos_channel_survey_stop command request.
+ *
+ * @sa @ref ble_gap_qos_channel_survey_stop_rsp_enc for response encoding.
+ *
+ * @param[in] p_buf Pointer to beginning of command request packet.
+ * @param[in] packet_len Length (in bytes) of response packet.
+ *
+ * @retval NRF_SUCCESS Decoding success.
+ * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length.
+ * @retval NRF_ERROR_INVALID_PARAM Decoding failure. Invalid operation type.
+ */
+uint32_t ble_gap_qos_channel_survey_stop_req_dec(uint8_t const * const p_buf,
+ uint32_t packet_len);
+
+/**@brief Encodes @ref sd_ble_gap_qos_channel_survey_stop command response.
+ *
+ * @sa @ref ble_gap_qos_channel_survey_stop_req_dec for request decoding.
+ *
+ * @param[in] return_code Return code indicating if command was successful or not.
+ * @param[out] p_buf Pointer to buffer where encoded data command response will be
+ * returned.
+ * @param[in,out] p_buf_len \c in: size of \p p_buf buffer.
+ * \c out: Length of encoded command response packet.
+ *
+ * @retval NRF_SUCCESS Encoding success.
+ * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length.
+ */
+uint32_t ble_gap_qos_channel_survey_stop_rsp_enc(uint32_t return_code,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len);
+#endif //!defined(S112)
+#endif
+/** @} */
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/connectivity/codecs/ble/serializers/ble_gap_evt_conn.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/connectivity/codecs/ble/serializers/ble_gap_evt_conn.c
new file mode 100644
index 0000000..f1c67e8
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/connectivity/codecs/ble/serializers/ble_gap_evt_conn.c
@@ -0,0 +1,401 @@
+/**
+ * Copyright (c) 2014 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#include "ble.h"
+#include "ble_gap_evt_conn.h"
+#include <string.h>
+#include "ble_serialization.h"
+#include "cond_field_serialization.h"
+#include "ble_gap_struct_serialization.h"
+#include "conn_ble_gap_sec_keys.h"
+#include "app_util.h"
+
+extern ser_ble_gap_conn_keyset_t m_conn_keys_table[];
+
+#ifndef S112
+uint32_t ble_gap_evt_adv_report_enc(ble_evt_t const * const p_event,
+ uint32_t event_len,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len)
+{
+ SER_EVT_ENC_BEGIN(BLE_GAP_EVT_ADV_REPORT);
+
+ SER_PUSH_uint16(&p_event->evt.gap_evt.conn_handle);
+ SER_PUSH_FIELD(&p_event->evt.gap_evt.params.adv_report, ble_gap_evt_adv_report_t_enc);
+
+ SER_EVT_ENC_END;
+}
+#endif //!S112
+
+uint32_t ble_gap_evt_auth_key_request_enc(ble_evt_t const * const p_event,
+ uint32_t event_len,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len)
+{
+ SER_EVT_ENC_BEGIN(BLE_GAP_EVT_AUTH_KEY_REQUEST);
+
+ SER_PUSH_uint16(&p_event->evt.gap_evt.conn_handle);
+ SER_PUSH_uint8(&p_event->evt.gap_evt.params.auth_key_request.key_type);
+
+ SER_EVT_ENC_END;
+}
+
+uint32_t ble_gap_evt_auth_status_enc(ble_evt_t const * const p_event,
+ uint32_t event_len,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len)
+{
+ SER_EVT_ENC_BEGIN(BLE_GAP_EVT_AUTH_STATUS);
+
+ SER_PUSH_uint16(&p_event->evt.gap_evt.conn_handle);
+ SER_PUSH_FIELD(&p_event->evt.gap_evt.params.auth_status, ble_gap_evt_auth_status_t_enc);
+
+ // keyset is an extension of standard event data - used to synchronize keys at application
+ uint32_t conn_index;
+ err_code = conn_ble_gap_sec_context_find(p_event->evt.gap_evt.conn_handle, &conn_index);
+ if (err_code == NRF_SUCCESS)
+ {
+ SER_PUSH_FIELD(&(m_conn_keys_table[conn_index].keyset), ble_gap_sec_keyset_t_enc);
+
+ err_code = conn_ble_gap_sec_context_destroy(p_event->evt.gap_evt.conn_handle);
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code);
+ }
+ else
+ {
+ err_code = NRF_SUCCESS;
+ }
+
+ SER_EVT_ENC_END;
+}
+
+
+uint32_t ble_gap_evt_conn_param_update_enc(ble_evt_t const * const p_event,
+ uint32_t event_len,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len)
+{
+ SER_EVT_ENC_BEGIN(BLE_GAP_EVT_CONN_PARAM_UPDATE);
+
+ SER_PUSH_uint16(&p_event->evt.gap_evt.conn_handle);
+ SER_PUSH_FIELD(&p_event->evt.gap_evt.params.conn_param_update, ble_gap_evt_conn_param_update_t_enc);
+
+ SER_EVT_ENC_END;
+}
+
+#ifndef S112
+uint32_t ble_gap_evt_conn_param_update_request_enc(ble_evt_t const * const p_event,
+ uint32_t event_len,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len)
+{
+ SER_EVT_ENC_BEGIN(BLE_GAP_EVT_CONN_PARAM_UPDATE_REQUEST);
+
+ SER_PUSH_uint16(&p_event->evt.gap_evt.conn_handle);
+ SER_PUSH_FIELD(&p_event->evt.gap_evt.params.conn_param_update_request,
+ ble_gap_evt_conn_param_update_request_t_enc);
+
+ SER_EVT_ENC_END;
+}
+#endif //!S112
+
+uint32_t ble_gap_evt_conn_sec_update_enc(ble_evt_t const * const p_event,
+ uint32_t event_len,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len)
+{
+ SER_EVT_ENC_BEGIN(BLE_GAP_EVT_CONN_SEC_UPDATE);
+
+ SER_PUSH_uint16(&p_event->evt.gap_evt.conn_handle);
+ SER_PUSH_FIELD(&p_event->evt.gap_evt.params.conn_sec_update, ble_gap_evt_conn_sec_update_t_enc);
+
+ SER_EVT_ENC_END;
+}
+
+uint32_t ble_gap_evt_connected_enc(ble_evt_t const * const p_event,
+ uint32_t event_len,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len)
+{
+ SER_EVT_ENC_BEGIN(BLE_GAP_EVT_CONNECTED);
+
+ SER_PUSH_uint16(&p_event->evt.gap_evt.conn_handle);
+ SER_PUSH_FIELD(&p_event->evt.gap_evt.params.connected, ble_gap_evt_connected_t_enc);
+
+ SER_EVT_ENC_END;
+}
+
+uint32_t ble_gap_evt_disconnected_enc(ble_evt_t const * const p_event,
+ uint32_t event_len,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len)
+{
+ SER_EVT_ENC_BEGIN(BLE_GAP_EVT_DISCONNECTED);
+
+ SER_PUSH_uint16(&p_event->evt.gap_evt.conn_handle);
+ SER_PUSH_FIELD(&p_event->evt.gap_evt.params.disconnected, ble_gap_evt_disconnected_t_enc);
+
+ // If disconnected and context is not yet destroyed, destroy it now
+ uint32_t conn_index;
+ err_code = conn_ble_gap_sec_context_find(p_event->evt.gap_evt.conn_handle, &conn_index);
+ if (err_code == NRF_SUCCESS)
+ {
+ err_code = conn_ble_gap_sec_context_destroy(p_event->evt.gap_evt.conn_handle);
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code);
+ }
+ err_code = NRF_SUCCESS;
+
+ SER_EVT_ENC_END;
+}
+
+uint32_t ble_gap_evt_key_pressed_enc(ble_evt_t const * const p_event,
+ uint32_t event_len,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len)
+{
+ SER_EVT_ENC_BEGIN(BLE_GAP_EVT_KEY_PRESSED);
+
+ SER_PUSH_uint16(&p_event->evt.gap_evt.conn_handle);
+ SER_PUSH_uint8(&p_event->evt.gap_evt.params.key_pressed.kp_not);
+
+ SER_EVT_ENC_END;
+}
+
+uint32_t ble_gap_evt_lesc_dhkey_request_enc(ble_evt_t const * const p_event,
+ uint32_t event_len,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len)
+{
+ SER_EVT_ENC_BEGIN(BLE_GAP_EVT_LESC_DHKEY_REQUEST);
+
+ uint8_t ser_data = p_event->evt.gap_evt.params.lesc_dhkey_request.oobd_req & 0x01;
+ SER_PUSH_uint16(&p_event->evt.gap_evt.conn_handle);
+ SER_PUSH_COND(p_event->evt.gap_evt.params.lesc_dhkey_request.p_pk_peer, ble_gap_lesc_p256_pk_t_enc);
+ SER_PUSH_uint8(&ser_data);
+
+ SER_EVT_ENC_END;
+}
+
+#define PASSKEY_LEN sizeof (p_event->evt.gap_evt.params.passkey_display.passkey)
+
+
+uint32_t ble_gap_evt_passkey_display_enc(ble_evt_t const * const p_event,
+ uint32_t event_len,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len)
+{
+ SER_EVT_ENC_BEGIN(BLE_GAP_EVT_PASSKEY_DISPLAY);
+
+ uint8_t ser_data = p_event->evt.gap_evt.params.passkey_display.match_request & 0x01;
+ SER_PUSH_uint16(&p_event->evt.gap_evt.conn_handle);
+ SER_PUSH_uint8array(p_event->evt.gap_evt.params.passkey_display.passkey, BLE_GAP_PASSKEY_LEN);
+ SER_PUSH_uint8(&ser_data);
+
+ SER_EVT_ENC_END;
+}
+
+uint32_t ble_gap_evt_rssi_changed_enc(ble_evt_t const * const p_event,
+ uint32_t event_len,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len)
+{
+ SER_EVT_ENC_BEGIN(BLE_GAP_EVT_RSSI_CHANGED);
+
+ SER_PUSH_uint16(&p_event->evt.gap_evt.conn_handle);
+ SER_PUSH_int8(&p_event->evt.gap_evt.params.rssi_changed.rssi);
+#if defined(NRF_SD_BLE_API_VERSION) && NRF_SD_BLE_API_VERSION > 5
+ SER_PUSH_uint8(&p_event->evt.gap_evt.params.rssi_changed.ch_index);
+#endif
+
+ SER_EVT_ENC_END;
+}
+
+uint32_t ble_gap_evt_scan_req_report_enc(ble_evt_t const * const p_event,
+ uint32_t event_len,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len)
+{
+ SER_EVT_ENC_BEGIN(BLE_GAP_EVT_SCAN_REQ_REPORT);
+
+ SER_PUSH_uint16(&p_event->evt.gap_evt.conn_handle);
+#if defined(NRF_SD_BLE_API_VERSION) && NRF_SD_BLE_API_VERSION > 5
+ SER_PUSH_uint8(&p_event->evt.gap_evt.params.scan_req_report.adv_handle);
+#endif
+ SER_PUSH_FIELD(&p_event->evt.gap_evt.params.scan_req_report.peer_addr, ble_gap_addr_t_enc);
+ SER_PUSH_int8(&p_event->evt.gap_evt.params.scan_req_report.rssi);
+
+ SER_EVT_ENC_END;
+}
+
+uint32_t ble_gap_evt_sec_info_request_enc(ble_evt_t const * const p_event,
+ uint32_t event_len,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len)
+{
+ SER_EVT_ENC_BEGIN(BLE_GAP_EVT_SEC_INFO_REQUEST);
+
+ SER_PUSH_uint16(&p_event->evt.gap_evt.conn_handle);
+ SER_PUSH_FIELD(&p_event->evt.gap_evt.params.sec_info_request, ble_gap_evt_sec_info_request_t_enc);
+
+ SER_EVT_ENC_END;
+}
+
+uint32_t ble_gap_evt_sec_params_request_enc(ble_evt_t const * const p_event,
+ uint32_t event_len,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len)
+{
+ SER_EVT_ENC_BEGIN(BLE_GAP_EVT_SEC_PARAMS_REQUEST);
+
+ SER_PUSH_uint16(&p_event->evt.gap_evt.conn_handle);
+ SER_PUSH_FIELD(&p_event->evt.gap_evt.params.sec_params_request, ble_gap_evt_sec_params_request_t_enc);
+
+ SER_EVT_ENC_END;
+}
+
+uint32_t ble_gap_evt_sec_request_enc(ble_evt_t const * const p_event,
+ uint32_t event_len,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len)
+{
+ SER_EVT_ENC_BEGIN(BLE_GAP_EVT_SEC_REQUEST);
+
+ SER_PUSH_uint16(&p_event->evt.gap_evt.conn_handle);
+ SER_PUSH_FIELD(&p_event->evt.gap_evt.params.sec_request, ble_gap_evt_sec_request_t_enc);
+
+ SER_EVT_ENC_END;
+}
+
+uint32_t ble_gap_evt_timeout_enc(ble_evt_t const * const p_event,
+ uint32_t event_len,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len)
+{
+ SER_EVT_ENC_BEGIN(BLE_GAP_EVT_TIMEOUT);
+
+ SER_PUSH_uint16(&p_event->evt.gap_evt.conn_handle);
+ SER_PUSH_uint8(&p_event->evt.gap_evt.params.timeout.src);
+#if defined(NRF_SD_BLE_API_VERSION) && NRF_SD_BLE_API_VERSION > 5 && !defined(S112)
+ if (p_event->evt.gap_evt.params.timeout.src == BLE_GAP_TIMEOUT_SRC_SCAN)
+ {
+ SER_PUSH_uint16(&p_event->evt.gap_evt.params.timeout.params.adv_report_buffer.len);
+ }
+#endif
+ SER_EVT_ENC_END;
+}
+
+#if NRF_SD_BLE_API_VERSION >= 5
+uint32_t ble_gap_evt_phy_update_enc(ble_evt_t const * const p_event,
+ uint32_t event_len,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len)
+{
+ SER_EVT_ENC_BEGIN(BLE_GAP_EVT_PHY_UPDATE);
+
+ SER_PUSH_uint16(&p_event->evt.gap_evt.conn_handle);
+ SER_PUSH_uint8(&p_event->evt.gap_evt.params.phy_update.status);
+ SER_PUSH_uint8(&p_event->evt.gap_evt.params.phy_update.tx_phy);
+ SER_PUSH_uint8(&p_event->evt.gap_evt.params.phy_update.rx_phy);
+
+ SER_EVT_ENC_END;
+}
+
+uint32_t ble_gap_evt_phy_update_request_enc(ble_evt_t const * const p_event,
+ uint32_t event_len,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len)
+{
+ SER_EVT_ENC_BEGIN(BLE_GAP_EVT_PHY_UPDATE_REQUEST);
+
+ SER_PUSH_uint16(&p_event->evt.gap_evt.conn_handle);
+ SER_PUSH_FIELD(&p_event->evt.gap_evt.params.phy_update_request, ble_gap_phys_t_enc);
+
+ SER_EVT_ENC_END;
+}
+#endif
+#if NRF_SD_BLE_API_VERSION >= 4 && !defined(S112)
+uint32_t ble_gap_evt_data_length_update_request_enc(ble_evt_t const * const p_event,
+ uint32_t event_len,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len)
+{
+ SER_EVT_ENC_BEGIN(BLE_GAP_EVT_DATA_LENGTH_UPDATE_REQUEST);
+
+ SER_PUSH_uint16(&p_event->evt.gap_evt.conn_handle);
+ SER_PUSH_FIELD(&p_event->evt.gap_evt.params.data_length_update_request.peer_params, ble_gap_data_length_params_t_enc);
+
+ SER_EVT_ENC_END;
+}
+uint32_t ble_gap_evt_data_length_update_enc(ble_evt_t const * const p_event,
+ uint32_t event_len,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len)
+{
+ SER_EVT_ENC_BEGIN(BLE_GAP_EVT_DATA_LENGTH_UPDATE);
+
+ SER_PUSH_uint16(&p_event->evt.gap_evt.conn_handle);
+ SER_PUSH_FIELD(&p_event->evt.gap_evt.params.data_length_update.effective_params, ble_gap_data_length_params_t_enc);
+
+ SER_EVT_ENC_END;
+}
+#endif // NRF_SD_BLE_API_VERSION >= 4 && !defined(S112)
+
+#if NRF_SD_BLE_API_VERSION > 5
+uint32_t ble_gap_evt_adv_set_terminated_enc(ble_evt_t const * const p_event,
+ uint32_t event_len,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len)
+{
+ SER_EVT_ENC_BEGIN(BLE_GAP_EVT_ADV_SET_TERMINATED);
+
+ SER_PUSH_uint16(&p_event->evt.gap_evt.conn_handle);
+ SER_PUSH_FIELD(&p_event->evt.gap_evt.params.adv_set_terminated, ble_gap_evt_adv_set_terminated_t_enc);
+
+ if (p_event->evt.gap_evt.params.adv_set_terminated.adv_data.adv_data.p_data)
+ {
+ conn_ble_gap_ble_data_buf_free(p_event->evt.gap_evt.params.adv_set_terminated.adv_data.adv_data.p_data);
+ }
+
+ if (p_event->evt.gap_evt.params.adv_set_terminated.adv_data.scan_rsp_data.p_data)
+ {
+ conn_ble_gap_ble_data_buf_free(p_event->evt.gap_evt.params.adv_set_terminated.adv_data.scan_rsp_data.p_data);
+ }
+
+ SER_EVT_ENC_END;
+}
+#endif
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/connectivity/codecs/ble/serializers/ble_gap_evt_conn.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/connectivity/codecs/ble/serializers/ble_gap_evt_conn.h
new file mode 100644
index 0000000..889d0b6
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/connectivity/codecs/ble/serializers/ble_gap_evt_conn.h
@@ -0,0 +1,443 @@
+/**
+ * Copyright (c) 2014 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#ifndef BLE_GAP_EVT_CONN_H__
+#define BLE_GAP_EVT_CONN_H__
+
+/**@file
+ *
+ * @defgroup ble_gap_evt_conn GAP Connectivity event encoders
+ * @{
+ * @ingroup ser_conn_s130_codecs
+ *
+ * @brief GAP Connectivity event encoders.
+ */
+#include "ble.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @brief Encodes ble_gap_evt_auth_key_request event.
+ *
+ * @param[in] p_event Pointer to the \ref ble_evt_t buffer that shall be encoded.
+ * @param[in] event_len Size (in bytes) of \p p_event buffer.
+ * @param[out] p_buf Pointer to the beginning of a buffer for encoded event packet.
+ * @param[in,out] p_buf_len \c in: Size (in bytes) of \p p_buf buffer.
+ * \c out: Length of encoded contents in \p p_buf.
+ *
+ * @retval NRF_SUCCESS Encoding success.
+ * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length.
+ */
+uint32_t ble_gap_evt_auth_key_request_enc(ble_evt_t const * const p_event,
+ uint32_t event_len,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len);
+
+/**
+ * @brief Encodes ble_gap_evt_auth_status event.
+ *
+ * @param[in] p_event Pointer to the \ref ble_evt_t buffer that shall be encoded.
+ * @param[in] event_len Size (in bytes) of \p p_event buffer.
+ * @param[out] p_buf Pointer to the beginning of a buffer for encoded event packet.
+ * @param[in,out] p_buf_len \c in: Size (in bytes) of \p p_buf buffer.
+ * \c out: Length of encoded contents in \p p_buf.
+ *
+ * @retval NRF_SUCCESS Encoding success.
+ * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length.
+ */
+uint32_t ble_gap_evt_auth_status_enc(ble_evt_t const * const p_event,
+ uint32_t event_len,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len);
+
+/**
+ * @brief Encodes ble_gap_evt_conn_param_update event.
+ *
+ * @param[in] p_event Pointer to the \ref ble_evt_t buffer that shall be encoded.
+ * @param[in] event_len Size (in bytes) of \p p_event buffer.
+ * @param[out] p_buf Pointer to the beginning of a buffer for encoded event packet.
+ * @param[in,out] p_buf_len \c in: Size (in bytes) of \p p_buf buffer.
+ * \c out: Length of encoded contents in \p p_buf.
+ *
+ * @retval NRF_SUCCESS Encoding success.
+ * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length.
+ */
+uint32_t ble_gap_evt_conn_param_update_enc(ble_evt_t const * const p_event,
+ uint32_t event_len,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len);
+
+/**
+ * @brief Encodes ble_gap_evt_conn_sec_update event.
+ *
+ * @param[in] p_event Pointer to the \ref ble_evt_t buffer that shall be encoded.
+ * @param[in] event_len Size (in bytes) of \p p_event buffer.
+ * @param[out] p_buf Pointer to the beginning of a buffer for encoded event packet.
+ * @param[in,out] p_buf_len \c in: Size (in bytes) of \p p_buf buffer.
+ * \c out: Length of encoded contents in \p p_buf.
+ *
+ * @retval NRF_SUCCESS Encoding success.
+ * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length.
+ */
+uint32_t ble_gap_evt_conn_sec_update_enc(ble_evt_t const * const p_event,
+ uint32_t event_len,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len);
+
+/**
+ * @brief Encodes ble_gap_evt_connected event.
+ *
+ * @param[in] p_event Pointer to the \ref ble_evt_t buffer that shall be encoded.
+ * @param[in] event_len Size (in bytes) of \p p_event buffer.
+ * @param[out] p_buf Pointer to the beginning of a buffer for encoded event packet.
+ * @param[in,out] p_buf_len \c in: Size (in bytes) of \p p_buf buffer.
+ * \c out: Length of encoded contents in \p p_buf.
+ *
+ * @retval NRF_SUCCESS Encoding success.
+ * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length.
+ */
+uint32_t ble_gap_evt_connected_enc(ble_evt_t const * const p_event,
+ uint32_t event_len,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len);
+
+/**
+ * @brief Encodes ble_gap_evt_disconnected event.
+ *
+ * @param[in] p_event Pointer to the \ref ble_evt_t buffer that shall be encoded.
+ * @param[in] event_len Size (in bytes) of \p p_event buffer.
+ * @param[out] p_buf Pointer to the beginning of a buffer for encoded event packet.
+ * @param[in,out] p_buf_len \c in: Size (in bytes) of \p p_buf buffer.
+ * \c out: Length of encoded contents in \p p_buf.
+ *
+ * @retval NRF_SUCCESS Encoding success.
+ * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length.
+ */
+uint32_t ble_gap_evt_disconnected_enc(ble_evt_t const * const p_event,
+ uint32_t event_len,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len);
+
+/**
+ * @brief Encodes ble_gap_evt_passkey_display event.
+ *
+ * @param[in] p_event Pointer to the \ref ble_evt_t buffer that shall be encoded.
+ * @param[in] event_len Size (in bytes) of \p p_event buffer.
+ * @param[out] p_buf Pointer to the beginning of a buffer for encoded event packet.
+ * @param[in,out] p_buf_len \c in: Size (in bytes) of \p p_buf buffer.
+ * \c out: Length of encoded contents in \p p_buf.
+ *
+ * @retval NRF_SUCCESS Encoding success.
+ * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length.
+ */
+uint32_t ble_gap_evt_passkey_display_enc(ble_evt_t const * const p_event,
+ uint32_t event_len,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len);
+
+/**
+ * @brief Encodes ble_gap_evt_rssi_changed event.
+ *
+ * @param[in] p_event Pointer to the \ref ble_evt_t buffer that shall be encoded.
+ * @param[in] event_len Size (in bytes) of \p p_event buffer.
+ * @param[out] p_buf Pointer to the beginning of a buffer for encoded event packet.
+ * @param[in,out] p_buf_len \c in: Size (in bytes) of \p p_buf buffer.
+ * \c out: Length of encoded contents in \p p_buf.
+ *
+ * @retval NRF_SUCCESS Encoding success.
+ * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length.
+ */
+uint32_t ble_gap_evt_rssi_changed_enc(ble_evt_t const * const p_event,
+ uint32_t event_len,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len);
+
+/**
+ * @brief Encodes ble_gap_evt_sec_info_request event.
+ *
+ * @param[in] p_event Pointer to the \ref ble_evt_t buffer that shall be encoded.
+ * @param[in] event_len Size (in bytes) of \p p_event buffer.
+ * @param[out] p_buf Pointer to the beginning of a buffer for encoded event packet.
+ * @param[in,out] p_buf_len \c in: Size (in bytes) of \p p_buf buffer.
+ * \c out: Length of encoded contents in \p p_buf.
+ *
+ * @retval NRF_SUCCESS Encoding success.
+ * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length.
+ */
+uint32_t ble_gap_evt_sec_info_request_enc(ble_evt_t const * const p_event,
+ uint32_t event_len,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len);
+
+/**
+ * @brief Encodes ble_gap_evt_sec_params_request event.
+ *
+ * @param[in] p_event Pointer to the \ref ble_evt_t buffer that shall be encoded.
+ * @param[in] event_len Size (in bytes) of \p p_event buffer.
+ * @param[out] p_buf Pointer to the beginning of a buffer for encoded event packet.
+ * @param[in,out] p_buf_len \c in: Size (in bytes) of \p p_buf buffer.
+ * \c out: Length of encoded contents in \p p_buf.
+ *
+ * @retval NRF_SUCCESS Encoding success.
+ * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length.
+ */
+uint32_t ble_gap_evt_sec_params_request_enc(ble_evt_t const * const p_event,
+ uint32_t event_len,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len);
+
+/**
+ * @brief Encodes ble_gap_evt_timeout event.
+ *
+ * @param[in] p_event Pointer to the \ref ble_evt_t buffer that shall be encoded.
+ * @param[in] event_len Size (in bytes) of \p p_event buffer.
+ * @param[out] p_buf Pointer to the beginning of a buffer for encoded event packet.
+ * @param[in,out] p_buf_len \c in: Size (in bytes) of \p p_buf buffer.
+ * \c out: Length of encoded contents in \p p_buf.
+ *
+ * @retval NRF_SUCCESS Encoding success.
+ * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length.
+ */
+uint32_t ble_gap_evt_timeout_enc(ble_evt_t const * const p_event,
+ uint32_t event_len,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len);
+
+/**
+ * @brief Encodes ble_gap_evt_sec_request event.
+ *
+ * @param[in] p_event Pointer to the \ref ble_evt_t buffer that shall be encoded.
+ * @param[in] event_len Size (in bytes) of \p p_event buffer.
+ * @param[out] p_buf Pointer to the beginning of a buffer for encoded event packet.
+ * @param[in,out] p_buf_len \c in: Size (in bytes) of \p p_buf buffer.
+ * \c out: Length of encoded contents in \p p_buf.
+ *
+ * @retval NRF_SUCCESS Encoding success.
+ * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length.
+ */
+uint32_t ble_gap_evt_sec_request_enc(ble_evt_t const * const p_event,
+ uint32_t event_len,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len);
+
+/**
+ * @brief Encodes ble_gap_evt_conn_param_update_request event.
+ *
+ * @param[in] p_event Pointer to the \ref ble_evt_t buffer that shall be encoded.
+ * @param[in] event_len Size (in bytes) of \p p_event buffer.
+ * @param[out] p_buf Pointer to the beginning of a buffer for encoded event packet.
+ * @param[in,out] p_buf_len \c in: Size (in bytes) of \p p_buf buffer.
+ * \c out: Length of encoded contents in \p p_buf.
+ *
+ * @retval NRF_SUCCESS Encoding success.
+ * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length.
+ */
+uint32_t ble_gap_evt_conn_param_update_request_enc(ble_evt_t const * const p_event,
+ uint32_t event_len,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len);
+
+/**
+ * @brief Encodes ble_gap_evt_adv_report event.
+ *
+ * @param[in] p_event Pointer to the \ref ble_evt_t buffer that shall be encoded.
+ * @param[in] event_len Size (in bytes) of \p p_event buffer.
+ * @param[out] p_buf Pointer to the beginning of a buffer for encoded event packet.
+ * @param[in,out] p_buf_len \c in: Size (in bytes) of \p p_buf buffer.
+ * \c out: Length of encoded contents in \p p_buf.
+ *
+ * @retval NRF_SUCCESS Encoding success.
+ * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length.
+ */
+uint32_t ble_gap_evt_adv_report_enc(ble_evt_t const * const p_event,
+ uint32_t event_len,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len);
+
+/**
+ * @brief Encodes ble_gap_evt_scan_req_report event.
+ *
+ * @param[in] p_event Pointer to the \ref ble_evt_t buffer that shall be encoded.
+ * @param[in] event_len Size (in bytes) of \p p_event buffer.
+ * @param[out] p_buf Pointer to the beginning of a buffer for encoded event packet.
+ * @param[in,out] p_buf_len \c in: Size (in bytes) of \p p_buf buffer.
+ * \c out: Length of encoded contents in \p p_buf.
+ *
+ * @retval NRF_SUCCESS Encoding success.
+ * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length.
+ */
+uint32_t ble_gap_evt_scan_req_report_enc(ble_evt_t const * const p_event,
+ uint32_t event_len,
+ uint8_t * const p_buf,
+
+ uint32_t * const p_buf_len);
+/**
+ * @brief Encodes ble_gap_evt_key_pressed event.
+ *
+ * @param[in] p_event Pointer to the \ref ble_evt_t buffer that shall be encoded.
+ * @param[in] event_len Size (in bytes) of \p p_event buffer.
+ * @param[out] p_buf Pointer to the beginning of a buffer for encoded event packet.
+ * @param[in,out] p_buf_len \c in: Size (in bytes) of \p p_buf buffer.
+ * \c out: Length of encoded contents in \p p_buf.
+ *
+ * @retval NRF_SUCCESS Encoding success.
+ * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length.
+ */
+uint32_t ble_gap_evt_key_pressed_enc(ble_evt_t const * const p_event,
+ uint32_t event_len,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len);
+
+/**
+ * @brief Encodes ble_gap_evt_lesc_dhkey_request event.
+ *
+ * @param[in] p_event Pointer to the \ref ble_evt_t buffer that shall be encoded.
+ * @param[in] event_len Size (in bytes) of \p p_event buffer.
+ * @param[out] p_buf Pointer to the beginning of a buffer for encoded event packet.
+ * @param[in,out] p_buf_len \c in: Size (in bytes) of \p p_buf buffer.
+ * \c out: Length of encoded contents in \p p_buf.
+ *
+ * @retval NRF_SUCCESS Encoding success.
+ * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length.
+ */
+uint32_t ble_gap_evt_lesc_dhkey_request_enc(ble_evt_t const * const p_event,
+ uint32_t event_len,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len);
+
+#if NRF_SD_BLE_API_VERSION >= 5
+/**
+ * @brief Encodes ble_gap_evt_phy_update event.
+ *
+ * @param[in] p_event Pointer to the \ref ble_evt_t buffer that shall be encoded.
+ * @param[in] event_len Size (in bytes) of \p p_event buffer.
+ * @param[out] p_buf Pointer to the beginning of a buffer for encoded event packet.
+ * @param[in,out] p_buf_len \c in: Size (in bytes) of \p p_buf buffer.
+ * \c out: Length of encoded contents in \p p_buf.
+ *
+ * @retval NRF_SUCCESS Encoding success.
+ * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length.
+ */
+uint32_t ble_gap_evt_phy_update_enc(ble_evt_t const * const p_event,
+ uint32_t event_len,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len);
+
+/**
+ * @brief Encodes ble_gap_evt_phy_update_request event.
+ *
+ * @param[in] p_event Pointer to the \ref ble_evt_t buffer that shall be encoded.
+ * @param[in] event_len Size (in bytes) of \p p_event buffer.
+ * @param[out] p_buf Pointer to the beginning of a buffer for encoded event packet.
+ * @param[in,out] p_buf_len \c in: Size (in bytes) of \p p_buf buffer.
+ * \c out: Length of encoded contents in \p p_buf.
+ *
+ * @retval NRF_SUCCESS Encoding success.
+ * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length.
+ */
+uint32_t ble_gap_evt_phy_update_request_enc(ble_evt_t const * const p_event,
+ uint32_t event_len,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len);
+#endif
+
+#if NRF_SD_BLE_API_VERSION >= 4
+/**
+ * @brief Encodes ble_gap_evt_data_length_update_request event.
+ *
+ * @param[in] p_event Pointer to the \ref ble_evt_t buffer that shall be encoded.
+ * @param[in] event_len Size (in bytes) of \p p_event buffer.
+ * @param[out] p_buf Pointer to the beginning of a buffer for encoded event packet.
+ * @param[in,out] p_buf_len \c in: Size (in bytes) of \p p_buf buffer.
+ * \c out: Length of encoded contents in \p p_buf.
+ *
+ * @retval NRF_SUCCESS Encoding success.
+ * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length.
+ */
+uint32_t ble_gap_evt_data_length_update_request_enc(ble_evt_t const * const p_event,
+ uint32_t event_len,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len);
+/**
+ * @brief Encodes ble_gap_evt_data_length_update event.
+ *
+ * @param[in] p_event Pointer to the \ref ble_evt_t buffer that shall be encoded.
+ * @param[in] event_len Size (in bytes) of \p p_event buffer.
+ * @param[out] p_buf Pointer to the beginning of a buffer for encoded event packet.
+ * @param[in,out] p_buf_len \c in: Size (in bytes) of \p p_buf buffer.
+ * \c out: Length of encoded contents in \p p_buf.
+ *
+ * @retval NRF_SUCCESS Encoding success.
+ * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length.
+ */
+uint32_t ble_gap_evt_data_length_update_enc(ble_evt_t const * const p_event,
+ uint32_t event_len,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len);
+#endif
+/** @} */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/connectivity/codecs/ble/serializers/ble_gattc_conn.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/connectivity/codecs/ble/serializers/ble_gattc_conn.c
new file mode 100644
index 0000000..a84e429
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/connectivity/codecs/ble/serializers/ble_gattc_conn.c
@@ -0,0 +1,299 @@
+/**
+ * Copyright (c) 2014 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#include "ble_gattc_conn.h"
+#include "ble_serialization.h"
+#include "ble_struct_serialization.h"
+#include "ble_gattc_struct_serialization.h"
+#include "cond_field_serialization.h"
+#include "app_util.h"
+#include <string.h>
+
+
+uint32_t ble_gattc_attr_info_discover_req_dec(uint8_t const * const p_buf,
+ uint16_t packet_len,
+ uint16_t * const p_conn_handle,
+ ble_gattc_handle_range_t * * const pp_handle_range)
+{
+ SER_REQ_DEC_BEGIN(SD_BLE_GATTC_ATTR_INFO_DISCOVER);
+
+ SER_ASSERT_NOT_NULL(p_conn_handle);
+ SER_ASSERT_NOT_NULL(pp_handle_range);
+ SER_ASSERT_NOT_NULL(*pp_handle_range);
+
+ SER_PULL_uint16(p_conn_handle);
+ SER_PULL_COND(pp_handle_range, ble_gattc_handle_range_t_dec);
+
+ SER_REQ_DEC_END;
+}
+
+uint32_t ble_gattc_attr_info_discover_rsp_enc(uint32_t return_code,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len)
+{
+ SER_RSP_ENC_RESULT_ONLY(SD_BLE_GATTC_ATTR_INFO_DISCOVER);
+}
+
+uint32_t ble_gattc_char_value_by_uuid_read_req_dec(uint8_t const * const p_buf,
+ uint16_t packet_len,
+ uint16_t * const p_conn_handle,
+ ble_uuid_t * * const pp_uuid,
+ ble_gattc_handle_range_t * * const
+ pp_handle_range)
+{
+ SER_REQ_DEC_BEGIN(SD_BLE_GATTC_CHAR_VALUE_BY_UUID_READ);
+
+ SER_ASSERT_NOT_NULL(p_conn_handle);
+ SER_ASSERT_NOT_NULL(pp_uuid);
+ SER_ASSERT_NOT_NULL(*pp_uuid);
+ SER_ASSERT_NOT_NULL(pp_handle_range);
+ SER_ASSERT_NOT_NULL(*pp_handle_range);
+
+ SER_PULL_uint16(p_conn_handle);
+ SER_PULL_COND(pp_uuid, ble_uuid_t_dec);
+ SER_PULL_COND(pp_handle_range, ble_gattc_handle_range_t_dec);
+
+ SER_REQ_DEC_END;
+}
+
+
+uint32_t ble_gattc_char_value_by_uuid_read_rsp_enc(uint32_t return_code,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len)
+{
+ SER_RSP_ENC_RESULT_ONLY(SD_BLE_GATTC_CHAR_VALUE_BY_UUID_READ);
+}
+
+
+uint32_t ble_gattc_char_values_read_req_dec(uint8_t const * const p_buf,
+ uint16_t packet_len,
+ uint16_t * const p_conn_handle,
+ uint16_t * * const pp_handles,
+ uint16_t * const p_handle_count)
+{
+ SER_REQ_DEC_BEGIN(SD_BLE_GATTC_CHAR_VALUES_READ);
+
+ SER_ASSERT_NOT_NULL(p_conn_handle);
+ SER_ASSERT_NOT_NULL(pp_handles);
+ SER_ASSERT_NOT_NULL(*pp_handles);
+ SER_ASSERT_NOT_NULL(p_handle_count);
+
+ SER_PULL_uint16(p_conn_handle);
+ SER_PULL_len16data16(pp_handles, p_handle_count);
+
+ SER_REQ_DEC_END;
+}
+
+
+uint32_t ble_gattc_char_values_read_rsp_enc(uint32_t return_code,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len)
+{
+ SER_RSP_ENC_RESULT_ONLY(SD_BLE_GATTC_CHAR_VALUES_READ);
+}
+
+uint32_t ble_gattc_characteristics_discover_req_dec(
+ uint8_t const * const p_buf,
+ uint16_t packet_len,
+ uint16_t * const p_conn_handle,
+ ble_gattc_handle_range_t * * const pp_handle_range)
+{
+ SER_REQ_DEC_BEGIN(SD_BLE_GATTC_CHARACTERISTICS_DISCOVER);
+
+ SER_PULL_uint16(p_conn_handle);
+ SER_PULL_COND(pp_handle_range, ble_gattc_handle_range_t_dec);
+
+ SER_REQ_DEC_END;
+}
+
+
+uint32_t ble_gattc_characteristics_discover_rsp_enc(uint32_t return_code,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len)
+{
+ SER_RSP_ENC_RESULT_ONLY(SD_BLE_GATTC_CHARACTERISTICS_DISCOVER);
+}
+
+
+uint32_t ble_gattc_descriptors_discover_req_dec(uint8_t const * const p_buf,
+ uint16_t packet_len,
+ uint16_t * const p_conn_handle,
+ ble_gattc_handle_range_t * * const pp_handle_range)
+{
+ SER_REQ_DEC_BEGIN(SD_BLE_GATTC_DESCRIPTORS_DISCOVER);
+
+ SER_PULL_uint16(p_conn_handle);
+ SER_PULL_COND(pp_handle_range, ble_gattc_handle_range_t_dec);
+
+ SER_REQ_DEC_END;
+}
+
+
+uint32_t ble_gattc_descriptors_discover_rsp_enc(uint32_t return_code,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len)
+{
+ SER_RSP_ENC_RESULT_ONLY(SD_BLE_GATTC_DESCRIPTORS_DISCOVER);
+}
+
+uint32_t ble_gattc_hv_confirm_req_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ uint16_t * const p_conn_handle,
+ uint16_t * const p_handle)
+{
+ SER_REQ_DEC_BEGIN(SD_BLE_GATTC_HV_CONFIRM);
+
+ SER_PULL_uint16(p_conn_handle);
+ SER_PULL_uint16(p_handle);
+
+ SER_REQ_DEC_END;
+}
+
+uint32_t ble_gattc_hv_confirm_rsp_enc(uint32_t return_code,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len)
+{
+ SER_RSP_ENC_RESULT_ONLY(SD_BLE_GATTC_HV_CONFIRM);
+}
+
+uint32_t ble_gattc_primary_services_discover_req_dec(uint8_t const * const p_buf,
+ uint16_t packet_len,
+ uint16_t * const p_conn_handle,
+ uint16_t * const p_start_handle,
+ ble_uuid_t * * const pp_srvc_uuid)
+{
+ SER_REQ_DEC_BEGIN(SD_BLE_GATTC_PRIMARY_SERVICES_DISCOVER);
+
+ SER_PULL_uint16(p_conn_handle);
+ SER_PULL_uint16(p_start_handle);
+ SER_PULL_COND(pp_srvc_uuid, ble_uuid_t_dec);
+
+ SER_REQ_DEC_END;
+}
+
+
+uint32_t ble_gattc_primary_services_discover_rsp_enc(uint32_t return_code,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len)
+{
+ SER_RSP_ENC_RESULT_ONLY(SD_BLE_GATTC_PRIMARY_SERVICES_DISCOVER);
+}
+
+uint32_t ble_gattc_read_req_dec(uint8_t const * const p_buf,
+ uint16_t packet_len,
+ uint16_t * const p_conn_handle,
+ uint16_t * const p_handle,
+ uint16_t * const p_offset)
+{
+ SER_REQ_DEC_BEGIN(SD_BLE_GATTC_READ);
+
+ SER_PULL_uint16(p_conn_handle);
+ SER_PULL_uint16(p_handle);
+ SER_PULL_uint16(p_offset);
+
+ SER_REQ_DEC_END;
+}
+
+uint32_t ble_gattc_read_rsp_enc(uint32_t return_code,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len)
+{
+ SER_RSP_ENC_RESULT_ONLY(SD_BLE_GATTC_READ);
+}
+
+uint32_t ble_gattc_relationships_discover_req_dec(uint8_t const * const p_buf,
+ uint16_t packet_len,
+ uint16_t * const p_conn_handle,
+ ble_gattc_handle_range_t * * const pp_handle_range)
+{
+ SER_REQ_DEC_BEGIN(SD_BLE_GATTC_RELATIONSHIPS_DISCOVER);
+
+ SER_PULL_uint16(p_conn_handle);
+ SER_PULL_COND(pp_handle_range, ble_gattc_handle_range_t_dec);
+
+ SER_REQ_DEC_END;
+}
+
+
+uint32_t ble_gattc_relationships_discover_rsp_enc(uint32_t return_code,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len)
+{
+ SER_RSP_ENC_RESULT_ONLY(SD_BLE_GATTC_RELATIONSHIPS_DISCOVER);
+}
+
+uint32_t ble_gattc_write_req_dec(uint8_t const * const p_buf,
+ uint16_t packet_len,
+ uint16_t * const p_conn_handle,
+ ble_gattc_write_params_t * * const pp_write_params)
+{
+ SER_REQ_DEC_BEGIN(SD_BLE_GATTC_WRITE);
+
+ SER_PULL_uint16(p_conn_handle);
+ SER_PULL_COND(pp_write_params, ble_gattc_write_params_t_dec);
+
+ SER_REQ_DEC_END;
+}
+
+uint32_t ble_gattc_write_rsp_enc(uint32_t return_code,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len)
+{
+ SER_RSP_ENC_RESULT_ONLY(SD_BLE_GATTC_WRITE);
+}
+
+uint32_t ble_gattc_exchange_mtu_request_req_dec(uint8_t const * const p_buf,
+ uint16_t packet_len,
+ uint16_t * const p_conn_handle,
+ uint16_t * const p_client_rx_mtu)
+{
+ SER_REQ_DEC_BEGIN(SD_BLE_GATTC_EXCHANGE_MTU_REQUEST);
+
+ SER_PULL_uint16(p_conn_handle);
+ SER_PULL_uint16(p_client_rx_mtu);
+
+ SER_REQ_DEC_END;
+}
+
+uint32_t ble_gattc_exchange_mtu_request_rsp_enc(uint32_t return_code,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len)
+{
+ SER_RSP_ENC_RESULT_ONLY(SD_BLE_GATTC_EXCHANGE_MTU_REQUEST);
+}
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/connectivity/codecs/ble/serializers/ble_gattc_conn.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/connectivity/codecs/ble/serializers/ble_gattc_conn.h
new file mode 100644
index 0000000..1654f9c
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/connectivity/codecs/ble/serializers/ble_gattc_conn.h
@@ -0,0 +1,481 @@
+/**
+ * Copyright (c) 2013 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#ifndef BLE_GATTC_CONN_H__
+#define BLE_GATTC_CONN_H__
+
+/**@file
+ *
+ * @defgroup ble_gatc_conn GATTC connectivity command request decoders and command response encoders
+ * @{
+ * @ingroup ser_conn_s130_codecs
+ *
+ * @brief GATTC Connectivity command request decoders and command response encoders
+ */
+#include "ble_gattc.h"
+#include "ble.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**@brief Decodes @ref sd_ble_gattc_characteristics_discover command request.
+ *
+ * @sa @ref ble_gattc_characteristics_discover_rsp_enc for response encoding.
+ *
+ * @param[in] p_buf Pointer to beginning of command request packet.
+ * @param[in] packet_len Length (in bytes) of response packet.
+ * @param[out] p_conn_handle Pointer to connection handle.
+ * @param[out] pp_handle_range Pointer to pointer to handle range.
+ *
+ * @retval NRF_SUCCESS Decoding success.
+ * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length.
+ * @retval NRF_ERROR_INVALID_DATA Decoding failure. Invalid value for handle range field present.
+ */
+uint32_t ble_gattc_characteristics_discover_req_dec
+ (uint8_t const * const p_buf,
+ uint16_t packet_len,
+ uint16_t * const p_conn_handle,
+ ble_gattc_handle_range_t * * const pp_handle_range);
+
+/**@brief Encodes @ref sd_ble_gattc_characteristics_discover command response.
+ *
+ * @sa @ref ble_gattc_characteristics_discover_req_dec for request decoding.
+ *
+ * @param[in] return_code Return code indicating if command was successful or not.
+ * @param[in] p_buf Pointer to buffer where encoded data command response will be
+ * returned.
+ * @param[in, out] p_buf_len \c in: size of \p p_buf buffer.
+ * \c out: Length of encoded command response packet.
+ *
+ * @retval NRF_SUCCESS Encoding success.
+ * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length.
+ */
+uint32_t ble_gattc_characteristics_discover_rsp_enc(uint32_t return_code,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len);
+
+/**@brief Decodes @ref sd_ble_gattc_descriptors_discover command request.
+ *
+ * @sa @ref ble_gattc_descriptors_discover_rsp_enc for response encoding.
+ *
+ * @param[in] p_buf Pointer to beginning of command request packet.
+ * @param[in] packet_len Length (in bytes) of response packet.
+ * @param[out] p_conn_handle Pointer to connection handle.
+ * @param[out] pp_handle_range Pointer to pointer to handle range.
+ *
+ * @retval NRF_SUCCESS Decoding success.
+ * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length.
+ * @retval NRF_ERROR_INVALID_DATA Decoding failure. Invalid value for handle range field present.
+ */
+uint32_t ble_gattc_descriptors_discover_req_dec(uint8_t const * const p_buf,
+ uint16_t packet_len,
+ uint16_t * const p_conn_handle,
+ ble_gattc_handle_range_t * * const pp_handle_range);
+
+/**@brief Encodes @ref sd_ble_gattc_descriptors_discover command response.
+ *
+ * @sa @ref ble_gattc_descriptors_discover_req_dec for request decoding.
+ *
+ * @param[in] return_code Return code indicating if command was successful or not.
+ * @param[in] p_buf Pointer to buffer where encoded data command response will be
+ * returned.
+ * @param[in, out] p_buf_len \c in: size of \p p_buf buffer.
+ * \c out: Length of encoded command response packet.
+ *
+ * @retval NRF_SUCCESS Encoding success.
+ * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length.
+ */
+uint32_t ble_gattc_descriptors_discover_rsp_enc(uint32_t return_code,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len);
+
+/**@brief Decodes @ref sd_ble_gattc_relationships_discover command request.
+ *
+ * @sa @ref ble_gattc_relationships_discover_rsp_enc for response encoding.
+ *
+ * @param[in] p_buf Pointer to beginning of command request packet.
+ * @param[in] packet_len Length (in bytes) of response packet.
+ * @param[out] p_conn_handle Pointer to connection handle.
+ * @param[out] pp_handle_range Pointer to pointer to handle range.
+ *
+ * @retval NRF_SUCCESS Decoding success.
+ * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length.
+ * @retval NRF_ERROR_INVALID_DATA Decoding failure. Invalid value for handle range field present.
+ */
+uint32_t ble_gattc_relationships_discover_req_dec
+ (uint8_t const * const p_buf,
+ uint16_t packet_len,
+ uint16_t * const p_conn_handle,
+ ble_gattc_handle_range_t * * const pp_handle_range);
+
+/**@brief Encodes @ref sd_ble_gattc_relationships_discover command response.
+ *
+ * @sa @ref ble_gattc_relationships_discover_req_dec for request decoding.
+ *
+ * @param[in] return_code Return code indicating if command was successful or not.
+ * @param[in] p_buf Pointer to buffer where encoded data command response will be
+ * returned.
+ * @param[in, out] p_buf_len \c in: size of \p p_buf buffer.
+ * \c out: Length of encoded command response packet.
+ *
+ * @retval NRF_SUCCESS Encoding success.
+ * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length.
+ */
+uint32_t ble_gattc_relationships_discover_rsp_enc(uint32_t return_code,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len);
+
+/**@brief Decodes @ref sd_ble_gattc_primary_services_discover command request.
+ *
+ * @sa @ref ble_gattc_primary_services_discover_rsp_enc for response encoding.
+ *
+ * @param[in] p_buf Pointer to beginning of command request packet.
+ * @param[in] packet_len Length (in bytes) of response packet.
+ * @param[out] p_conn_handle Pointer to connection handle.
+ * @param[out] p_start_handle Pointer to start handle.
+ * @param[out] pp_srvc_uuid Pointer to pointer to service uuid.
+ *
+ * @retval NRF_SUCCESS Decoding success.
+ * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length.
+ * @retval NRF_ERROR_INVALID_DATA Decoding failure. Invalid value for uuid field present.
+ */
+uint32_t ble_gattc_primary_services_discover_req_dec(uint8_t const * const p_buf,
+ uint16_t packet_len,
+ uint16_t * const p_conn_handle,
+ uint16_t * const p_start_handle,
+ ble_uuid_t * * const pp_srvc_uuid);
+
+/**@brief Encodes @ref sd_ble_gattc_primary_services_discover command response.
+ *
+ * @sa @ref ble_gattc_primary_services_discover_req_dec for request decoding.
+ *
+ * @param[in] return_code Return code indicating if command was successful or not.
+ * @param[in] p_buf Pointer to buffer where encoded data command response will be
+ * returned.
+ * @param[in, out] p_buf_len \c in: size of \p p_buf buffer.
+ * \c out: Length of encoded command response packet.
+ *
+ * @retval NRF_SUCCESS Encoding success.
+ * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length.
+ */
+uint32_t ble_gattc_primary_services_discover_rsp_enc(uint32_t return_code,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len);
+
+/**@brief Decodes @ref sd_ble_gattc_read command request.
+ *
+ * @sa @ref ble_gattc_read_rsp_enc for response encoding.
+ *
+ * @param[in] p_buf Pointer to beginning of command response packet.
+ * @param[in] packet_len Length (in bytes) of response packet.
+ * @param[out] p_conn_handle Pointer to connection handle.
+ * @param[out] p_handle Pointer to handle.
+ * @param[out] p_offset Pointer to offset.
+ *
+ * @retval NRF_SUCCESS Decoding success.
+ * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length.
+ */
+uint32_t ble_gattc_read_req_dec(uint8_t const * const p_buf,
+ uint16_t packet_len,
+ uint16_t * const p_conn_handle,
+ uint16_t * const p_handle,
+ uint16_t * const p_offset);
+
+/**@brief Encodes @ref sd_ble_gattc_read command response.
+ *
+ * @sa @ref ble_gattc_read_req_dec for request decoding.
+ *
+ * @param[in] return_code Return code indicating if command was successful or not.
+ * @param[in] p_buf Pointer to buffer where encoded data command response will be
+ * returned.
+ * @param[in, out] p_buf_len \c in: size of \p p_buf buffer.
+ * \c out: Length of encoded command response packet.
+ *
+ * @retval NRF_SUCCESS Encoding success.
+ * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length.
+ */
+uint32_t ble_gattc_read_rsp_enc(uint32_t return_code,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len);
+
+/**@brief Decodes @ref sd_ble_gattc_char_values_read command request.
+ *
+ * @sa @ref ble_gattc_char_values_read_rsp_enc for response encoding.
+ *
+ * @param[in] p_buf Pointer to beginning of command response packet.
+ * @param[in] packet_len Length (in bytes) of response packet.
+ * @param[out] p_conn_handle Pointer to connection handle.
+ * @param[out] pp_handles Pointer to pointer to handle table.
+ * @param[out] p_handle_count Pointer to handle handle table count.
+ *
+ * @retval NRF_SUCCESS Decoding success.
+ * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length.
+ */
+
+uint32_t ble_gattc_char_values_read_req_dec(uint8_t const * const p_buf,
+ uint16_t packet_len,
+ uint16_t * const p_conn_handle,
+ uint16_t * * const pp_handles,
+ uint16_t * const p_handle_count);
+
+/**@brief Encodes @ref sd_ble_gattc_char_values_read command response.
+ *
+ * @sa @ref ble_gattc_char_values_read_req_dec for request decoding.
+ *
+ * @param[in] return_code Return code indicating if command was successful or not.
+ * @param[in] p_buf Pointer to buffer where encoded data command response will be
+ * returned.
+ * @param[in, out] p_buf_len \c in: size of \p p_buf buffer.
+ * \c out: Length of encoded command response packet.
+ *
+ * @retval NRF_SUCCESS Encoding success.
+ * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length.
+ */
+uint32_t ble_gattc_char_values_read_rsp_enc(uint32_t return_code,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len);
+
+/**@brief Decodes @ref sd_ble_gattc_write command request.
+ *
+ * @sa @ref ble_gattc_write_rsp_enc for response encoding.
+ *
+ * @param[in] p_buf Pointer to beginning of command response packet.
+ * @param[in] packet_len Length (in bytes) of response packet.
+ * @param[out] p_conn_handle Pointer to connection handle.
+ * @param[out] pp_write_params Pointer to pointer to write parameters.
+ *
+ * @retval NRF_SUCCESS Decoding success.
+ * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length.
+ */
+uint32_t ble_gattc_write_req_dec(uint8_t const * const p_buf,
+ uint16_t packet_len,
+ uint16_t * const p_conn_handle,
+ ble_gattc_write_params_t * * const pp_write_params);
+
+/**@brief Encodes @ref sd_ble_gattc_write command response.
+ *
+ * @sa @ref ble_gattc_write_req_dec for request decoding.
+ *
+ * @param[in] return_code Return code indicating if command was successful or not.
+ * @param[in] p_buf Pointer to buffer where encoded data command response will be
+ * returned.
+ * @param[in, out] p_buf_len \c in: size of \p p_buf buffer.
+ * \c out: Length of encoded command response packet.
+ *
+ * @retval NRF_SUCCESS Encoding success.
+ * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length.
+ */
+uint32_t ble_gattc_write_rsp_enc(uint32_t return_code,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len);
+
+/**@brief Decodes @ref sd_ble_gattc_hv_confirm command request.
+ *
+ * @sa @ref ble_gattc_hv_confirm_rsp_enc for response encoding.
+ *
+ * @param[in] p_buf Pointer to beginning of command response packet.
+ * @param[in] packet_len Length (in bytes) of response packet.
+ * @param[out] p_conn_handle Pointer to connection handle.
+ * @param[out] p_handle Pointer to handle of the attribute in the indication.
+ *
+ * @retval NRF_SUCCESS Decoding success.
+ * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length.
+ */
+uint32_t ble_gattc_hv_confirm_req_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ uint16_t * const p_conn_handle,
+ uint16_t * const p_handle);
+
+/**@brief Encodes @ref sd_ble_gattc_hv_confirm command response.
+ *
+ * @sa @ref ble_gattc_hv_confirm_req_dec for request decoding.
+ *
+ * @param[in] return_code Return code indicating if command was successful or not.
+ * @param[in] p_buf Pointer to buffer where encoded data command response will be
+ * returned.
+ * @param[in, out] p_buf_len \c in: size of \p p_buf buffer.
+ * \c out: Length of encoded command response packet.
+ *
+ * @retval NRF_SUCCESS Encoding success.
+ * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length.
+ */
+uint32_t ble_gattc_hv_confirm_rsp_enc(uint32_t return_code,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len);
+
+/**@brief Decodes @ref sd_ble_gattc_char_value_by_uuid_read command request.
+ *
+ * @sa @ref ble_gattc_char_value_by_uuid_read_rsp_enc for response encoding.
+ *
+ * @param[in] p_buf Pointer to beginning of command request packet.
+ * @param[in] packet_len Length (in bytes) of request packet.
+ * @param[out] p_conn_handle Pointer to connection handle of the connection.
+ * @param[out] pp_uuid Pointer to pointer to a characteristic value UUID to read.
+ * @param[out] pp_handle_range Pointer to pointer to the range of handles to perform this
+ * procedure on.
+ *
+ * @retval NRF_SUCCESS Decoding success.
+ * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length.
+ * @retval NRF_ERROR_INVALID_DATA Decoding failure. Invalid operation type.
+ */
+uint32_t ble_gattc_char_value_by_uuid_read_req_dec
+ (uint8_t const * const p_buf,
+ uint16_t packet_len,
+ uint16_t * const p_conn_handle,
+ ble_uuid_t * * const pp_uuid,
+ ble_gattc_handle_range_t * * const pp_handle_range);
+
+/**@brief Encodes @ref sd_ble_gattc_char_value_by_uuid_read command response.
+ *
+ * @sa @ref ble_gattc_char_value_by_uuid_read_req_dec for request decoding.
+ *
+ * @param[in] return_code Return code indicating if command was successful or not.
+ * @param[in] p_buf Pointer to buffer where encoded data command response will be
+ * returned.
+ * @param[in, out] p_buf_len \c in: size of \p p_buf buffer.
+ * \c out: Length of encoded command response packet.
+ *
+ * @retval NRF_SUCCESS Encoding success.
+ * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length.
+ */
+uint32_t ble_gattc_char_value_by_uuid_read_rsp_enc(uint32_t return_code,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len);
+
+/**@brief Decodes @ref sd_ble_gattc_attr_info_discover command request.
+ *
+ * @sa @ref ble_gattc_attr_info_discover_rsp_enc for response encoding.
+ *
+ * @param[in] p_buf Pointer to beginning of command request packet.
+ * @param[in] buf_len Length (in bytes) of request packet.
+ * @param[out] p_conn_handle Pointer to connection handle of the connection.
+ * @param[out] pp_handle_range Pointer to pointer to the range of handles.
+ *
+ * @retval NRF_SUCCESS Decoding success.
+ * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length.
+ * @retval NRF_ERROR_INVALID_DATA Decoding failure. Invalid operation type.
+ */
+uint32_t ble_gattc_attr_info_discover_req_dec(uint8_t const * const p_buf,
+ uint16_t buf_len,
+ uint16_t * const p_conn_handle,
+ ble_gattc_handle_range_t * * const pp_handle_range);
+
+/**@brief Encodes @ref sd_ble_gattc_attr_info_discover command response.
+ *
+ * @sa @ref ble_gattc_attr_info_discover_req_dec for request decoding.
+ *
+ * @param[in] return_code Return code indicating if command was successful or not.
+ * @param[in] p_buf Pointer to buffer where encoded data command response will be
+ * returned.
+ * @param[in, out] p_buf_len \c in: size of \p p_buf buffer.
+ * \c out: Length of encoded command response packet.
+ *
+ * @retval NRF_SUCCESS Encoding success.
+ * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length.
+ */
+uint32_t ble_gattc_attr_info_discover_rsp_enc(uint32_t return_code,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len);
+
+/**@brief Decodes @ref sd_ble_gattc_exchange_mtu_request command request.
+ *
+ * @sa @ref ble_gattc_exchange_mtu_request_rsp_enc for response encoding.
+ *
+ * @param[in] p_buf Pointer to beginning of command request packet.
+ * @param[in] packet_len Length (in bytes) of request packet.
+ * @param[out] p_conn_handle Pointer to connection handle of the connection.
+ * @param[out] p_client_rx_mtu Pointer to Client RX MTU size.
+ *
+ * @retval NRF_SUCCESS Decoding success.
+ * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length.
+ * @retval NRF_ERROR_INVALID_DATA Decoding failure. Invalid operation type.
+ */
+uint32_t ble_gattc_exchange_mtu_request_req_dec(uint8_t const * const p_buf,
+ uint16_t packet_len,
+ uint16_t * const p_conn_handle,
+ uint16_t * const p_client_rx_mtu);
+
+/**@brief Encodes @ref sd_ble_gattc_exchange_mtu_request command response.
+ *
+ * @sa @ref ble_gattc_exchange_mtu_request_req_dec for request decoding.
+ *
+ * @param[in] return_code Return code indicating if command was successful or not.
+ * @param[in] p_buf Pointer to buffer where encoded data command response will be
+ * returned.
+ * @param[in, out] p_buf_len \c in: size of \p p_buf buffer.
+ * \c out: Length of encoded command response packet.
+ *
+ * @retval NRF_SUCCESS Encoding success.
+ * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length.
+ */
+uint32_t ble_gattc_exchange_mtu_request_rsp_enc(uint32_t return_code,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len);
+
+/** @} */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/connectivity/codecs/ble/serializers/ble_gattc_evt_conn.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/connectivity/codecs/ble/serializers/ble_gattc_evt_conn.c
new file mode 100644
index 0000000..307e6e2
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/connectivity/codecs/ble/serializers/ble_gattc_evt_conn.c
@@ -0,0 +1,253 @@
+/**
+ * Copyright (c) 2016 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#include "ble_gattc_evt_conn.h"
+#include "ble_serialization.h"
+#include "ble_gattc_struct_serialization.h"
+#include "app_util.h"
+#include <string.h>
+
+uint32_t ble_gattc_evt_attr_info_disc_rsp_enc(ble_evt_t const * const p_event,
+ uint32_t event_len,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len)
+{
+ SER_EVT_ENC_BEGIN(BLE_GATTC_EVT_ATTR_INFO_DISC_RSP);
+
+ SER_PUSH_uint16(&p_event->evt.gattc_evt.conn_handle);
+ SER_PUSH_uint16(&p_event->evt.gattc_evt.gatt_status);
+ SER_PUSH_uint16(&p_event->evt.gattc_evt.error_handle);
+ SER_PUSH_FIELD(&p_event->evt.gattc_evt.params.attr_info_disc_rsp,
+ ble_gattc_evt_attr_info_disc_rsp_t_enc);
+
+ SER_EVT_ENC_END;
+}
+
+uint32_t ble_gattc_evt_char_disc_rsp_enc(ble_evt_t const * const p_event,
+ uint32_t event_len,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len)
+{
+ SER_EVT_ENC_BEGIN(BLE_GATTC_EVT_CHAR_DISC_RSP);
+
+ SER_PUSH_uint16(&p_event->evt.gattc_evt.conn_handle);
+ SER_PUSH_uint16(&p_event->evt.gattc_evt.gatt_status);
+ SER_PUSH_uint16(&p_event->evt.gattc_evt.error_handle);
+ SER_PUSH_FIELD(&p_event->evt.gattc_evt.params.char_disc_rsp,
+ ble_gattc_evt_char_disc_rsp_t_enc);
+
+ SER_EVT_ENC_END;
+}
+
+uint32_t ble_gattc_evt_char_val_by_uuid_read_rsp_enc(ble_evt_t const * const p_event,
+ uint32_t event_len,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len)
+{
+ SER_EVT_ENC_BEGIN(BLE_GATTC_EVT_CHAR_VAL_BY_UUID_READ_RSP);
+
+ SER_PUSH_uint16(&p_event->evt.gattc_evt.conn_handle);
+ SER_PUSH_uint16(&p_event->evt.gattc_evt.gatt_status);
+ SER_PUSH_uint16(&p_event->evt.gattc_evt.error_handle);
+ SER_PUSH_FIELD(&p_event->evt.gattc_evt.params.char_val_by_uuid_read_rsp,
+ ble_gattc_evt_char_val_by_uuid_read_rsp_t_enc);
+
+ SER_EVT_ENC_END;
+}
+
+uint32_t ble_gattc_evt_char_vals_read_rsp_enc(ble_evt_t const * const p_event,
+ uint32_t event_len,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len)
+{
+ SER_EVT_ENC_BEGIN(BLE_GATTC_EVT_CHAR_VALS_READ_RSP);
+
+ SER_PUSH_uint16(&p_event->evt.gattc_evt.conn_handle);
+ SER_PUSH_uint16(&p_event->evt.gattc_evt.gatt_status);
+ SER_PUSH_uint16(&p_event->evt.gattc_evt.error_handle);
+ SER_PUSH_FIELD(&p_event->evt.gattc_evt.params.char_vals_read_rsp,
+ ble_gattc_evt_char_vals_read_rsp_t_enc);
+
+ SER_EVT_ENC_END;
+}
+
+uint32_t ble_gattc_evt_desc_disc_rsp_enc(ble_evt_t const * const p_event,
+ uint32_t event_len,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len)
+{
+ SER_EVT_ENC_BEGIN(BLE_GATTC_EVT_DESC_DISC_RSP);
+
+ SER_PUSH_uint16(&p_event->evt.gattc_evt.conn_handle);
+ SER_PUSH_uint16(&p_event->evt.gattc_evt.gatt_status);
+ SER_PUSH_uint16(&p_event->evt.gattc_evt.error_handle);
+ SER_PUSH_FIELD(&p_event->evt.gattc_evt.params.desc_disc_rsp,
+ ble_gattc_evt_desc_disc_rsp_t_enc);
+
+ SER_EVT_ENC_END;
+}
+
+uint32_t ble_gattc_evt_hvx_enc(ble_evt_t const * const p_event,
+ uint32_t event_len,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len)
+{
+ SER_EVT_ENC_BEGIN(BLE_GATTC_EVT_HVX);
+
+ SER_PUSH_uint16(&p_event->evt.gattc_evt.conn_handle);
+ SER_PUSH_uint16(&p_event->evt.gattc_evt.gatt_status);
+ SER_PUSH_uint16(&p_event->evt.gattc_evt.error_handle);
+ SER_PUSH_FIELD(&p_event->evt.gattc_evt.params.hvx, ble_gattc_evt_hvx_t_enc);
+
+ SER_EVT_ENC_END;
+}
+
+uint32_t ble_gattc_evt_prim_srvc_disc_rsp_enc(ble_evt_t const * const p_event,
+ uint32_t event_len,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len)
+{
+ SER_EVT_ENC_BEGIN(BLE_GATTC_EVT_PRIM_SRVC_DISC_RSP);
+
+ SER_PUSH_uint16(&p_event->evt.gattc_evt.conn_handle);
+ SER_PUSH_uint16(&p_event->evt.gattc_evt.gatt_status);
+ SER_PUSH_uint16(&p_event->evt.gattc_evt.error_handle);
+ SER_PUSH_FIELD(&p_event->evt.gattc_evt.params.prim_srvc_disc_rsp,
+ ble_gattc_evt_prim_srvc_disc_rsp_t_enc);
+
+ SER_EVT_ENC_END;
+}
+
+uint32_t ble_gattc_evt_read_rsp_enc(ble_evt_t const * const p_event,
+ uint32_t event_len,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len)
+{
+ SER_EVT_ENC_BEGIN(BLE_GATTC_EVT_READ_RSP);
+
+ SER_PUSH_uint16(&p_event->evt.gattc_evt.conn_handle);
+ SER_PUSH_uint16(&p_event->evt.gattc_evt.gatt_status);
+ SER_PUSH_uint16(&p_event->evt.gattc_evt.error_handle);
+ SER_PUSH_FIELD(&p_event->evt.gattc_evt.params.read_rsp,
+ ble_gattc_evt_read_rsp_t_enc);
+
+ SER_EVT_ENC_END;
+}
+
+uint32_t ble_gattc_evt_rel_disc_rsp_enc(ble_evt_t const * const p_event,
+ uint32_t event_len,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len)
+{
+ SER_EVT_ENC_BEGIN(BLE_GATTC_EVT_REL_DISC_RSP);
+
+ SER_PUSH_uint16(&p_event->evt.gattc_evt.conn_handle);
+ SER_PUSH_uint16(&p_event->evt.gattc_evt.gatt_status);
+ SER_PUSH_uint16(&p_event->evt.gattc_evt.error_handle);
+ SER_PUSH_FIELD(&p_event->evt.gattc_evt.params.rel_disc_rsp,
+ ble_gattc_evt_rel_disc_rsp_t_enc);
+
+ SER_EVT_ENC_END;
+}
+
+uint32_t ble_gattc_evt_timeout_enc(ble_evt_t const * const p_event,
+ uint32_t event_len,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len)
+{
+ SER_EVT_ENC_BEGIN(BLE_GATTC_EVT_TIMEOUT);
+
+ SER_PUSH_uint16(&p_event->evt.gattc_evt.conn_handle);
+ SER_PUSH_uint16(&p_event->evt.gattc_evt.gatt_status);
+ SER_PUSH_uint16(&p_event->evt.gattc_evt.error_handle);
+ SER_PUSH_FIELD(&p_event->evt.gattc_evt.params.timeout,
+ ble_gattc_evt_timeout_t_enc);
+
+ SER_EVT_ENC_END;
+}
+
+uint32_t ble_gattc_evt_write_rsp_enc(ble_evt_t const * const p_event,
+ uint32_t event_len,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len)
+{
+ SER_EVT_ENC_BEGIN(BLE_GATTC_EVT_WRITE_RSP);
+
+ SER_PUSH_uint16(&p_event->evt.gattc_evt.conn_handle);
+ SER_PUSH_uint16(&p_event->evt.gattc_evt.gatt_status);
+ SER_PUSH_uint16(&p_event->evt.gattc_evt.error_handle);
+ SER_PUSH_FIELD(&p_event->evt.gattc_evt.params.write_rsp,
+ ble_gattc_evt_write_rsp_t_enc);
+
+ SER_EVT_ENC_END;
+}
+
+uint32_t ble_gattc_evt_exchange_mtu_rsp_enc(ble_evt_t const * const p_event,
+ uint32_t event_len,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len)
+{
+ SER_EVT_ENC_BEGIN(BLE_GATTC_EVT_EXCHANGE_MTU_RSP);
+
+ SER_PUSH_uint16(&p_event->evt.gattc_evt.conn_handle);
+ SER_PUSH_uint16(&p_event->evt.gattc_evt.gatt_status);
+ SER_PUSH_uint16(&p_event->evt.gattc_evt.error_handle);
+ SER_PUSH_FIELD(&p_event->evt.gattc_evt.params.exchange_mtu_rsp,
+ ble_gattc_evt_exchange_mtu_rsp_t_enc);
+
+ SER_EVT_ENC_END;
+}
+
+#if NRF_SD_BLE_API_VERSION >= 4
+
+uint32_t ble_gattc_evt_write_cmd_tx_complete_enc(ble_evt_t const * const p_event,
+ uint32_t event_len,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len)
+{
+ SER_EVT_ENC_BEGIN(BLE_GATTC_EVT_WRITE_CMD_TX_COMPLETE);
+
+ SER_PUSH_uint16(&p_event->evt.gattc_evt.conn_handle);
+ SER_PUSH_uint16(&p_event->evt.gattc_evt.gatt_status);
+ SER_PUSH_uint16(&p_event->evt.gattc_evt.error_handle);
+ SER_PUSH_uint8(&p_event->evt.gattc_evt.params.write_cmd_tx_complete.count);
+
+ SER_EVT_ENC_END;
+}
+#endif
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/connectivity/codecs/ble/serializers/ble_gattc_evt_conn.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/connectivity/codecs/ble/serializers/ble_gattc_evt_conn.h
new file mode 100644
index 0000000..efecb20
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/connectivity/codecs/ble/serializers/ble_gattc_evt_conn.h
@@ -0,0 +1,300 @@
+/**
+ * Copyright (c) 2014 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#ifndef BLE_GATTC_EVT_CONN_H__
+#define BLE_GATTC_EVT_CONN_H__
+
+/**@file
+ *
+ * @defgroup ble_gattc_evt_conn GATTC Connectivity event encoders
+ * @{
+ * @ingroup ser_conn_s130_codecs
+ *
+ * @brief GATTC Connectivity event encoders.
+ */
+#include "ble.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @brief Encodes ble_gattc_evt_char_disc_rsp event.
+ *
+ * @param[in] p_event Pointer to the \ref ble_evt_t buffer that shall be encoded.
+ * @param[in] event_len Size (in bytes) of \p p_event buffer.
+ * @param[out] p_buf Pointer to the beginning of a buffer for encoded event packet.
+ * @param[in,out] p_buf_len \c in: Size (in bytes) of \p p_buf buffer.
+ * \c out: Length of encoded contents in \p p_buf.
+ *
+ * @retval NRF_SUCCESS Encoding success.
+ * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length.
+ */
+uint32_t ble_gattc_evt_char_disc_rsp_enc(ble_evt_t const * const p_event,
+ uint32_t event_len,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len);
+
+/**
+ * @brief Encodes ble_gattc_evt_char_val_by_uuid_read_rsp event.
+ *
+ * @param[in] p_event Pointer to the \ref ble_evt_t buffer that shall be encoded.
+ * @param[in] event_len Size (in bytes) of \p p_event buffer.
+ * @param[out] p_buf Pointer to the beginning of a buffer for encoded event packet.
+ * @param[in,out] p_buf_len \c in: Size (in bytes) of \p p_buf buffer.
+ * \c out: Length of encoded contents in \p p_buf.
+ *
+ * @retval NRF_SUCCESS Encoding success.
+ * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length.
+ */
+uint32_t ble_gattc_evt_char_val_by_uuid_read_rsp_enc(ble_evt_t const * const p_event,
+ uint32_t event_len,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len);
+
+/**
+ * @brief Encodes ble_gattc_evt_char_vals_read_rsp event.
+ *
+ * @param[in] p_event Pointer to the \ref ble_evt_t buffer that shall be encoded.
+ * @param[in] event_len Size (in bytes) of \p p_event buffer.
+ * @param[out] p_buf Pointer to the beginning of a buffer for encoded event packet.
+ * @param[in,out] p_buf_len \c in: Size (in bytes) of \p p_buf buffer.
+ * \c out: Length of encoded contents in \p p_buf.
+ *
+ * @retval NRF_SUCCESS Encoding success.
+ * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length.
+ */
+uint32_t ble_gattc_evt_char_vals_read_rsp_enc(ble_evt_t const * const p_event,
+ uint32_t event_len,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len);
+
+/**
+ * @brief Encodes ble_gattc_evt_desc_disc_rsp event.
+ *
+ * @param[in] p_event Pointer to the \ref ble_evt_t buffer that shall be encoded.
+ * @param[in] event_len Size (in bytes) of \p p_event buffer.
+ * @param[out] p_buf Pointer to the beginning of a buffer for encoded event packet.
+ * @param[in,out] p_buf_len \c in: Size (in bytes) of \p p_buf buffer.
+ * \c out: Length of encoded contents in \p p_buf.
+ *
+ * @retval NRF_SUCCESS Encoding success.
+ * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length.
+ */
+uint32_t ble_gattc_evt_desc_disc_rsp_enc(ble_evt_t const * const p_event,
+ uint32_t event_len,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len);
+
+/**
+ * @brief Encodes ble_gattc_evt_hvx event.
+ *
+ * @param[in] p_event Pointer to the \ref ble_evt_t buffer that shall be encoded.
+ * @param[in] event_len Size (in bytes) of \p p_event buffer.
+ * @param[out] p_buf Pointer to the beginning of a buffer for encoded event packet.
+ * @param[in,out] p_buf_len \c in: Size (in bytes) of \p p_buf buffer.
+ * \c out: Length of encoded contents in \p p_buf.
+ *
+ * @retval NRF_SUCCESS Encoding success.
+ * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length.
+ */
+uint32_t ble_gattc_evt_hvx_enc(ble_evt_t const * const p_event,
+ uint32_t event_len,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len);
+
+/**
+ * @brief Encodes ble_gattc_evt_prim_srvc_disc_rsp event.
+ *
+ * @param[in] p_event Pointer to the \ref ble_evt_t buffer that shall be encoded.
+ * @param[in] event_len Size (in bytes) of \p p_event buffer.
+ * @param[out] p_buf Pointer to the beginning of a buffer for encoded event packet.
+ * @param[in,out] p_buf_len \c in: Size (in bytes) of \p p_buf buffer.
+ * \c out: Length of encoded contents in \p p_buf.
+ *
+ * @retval NRF_SUCCESS Encoding success.
+ * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length.
+ */
+uint32_t ble_gattc_evt_prim_srvc_disc_rsp_enc(ble_evt_t const * const p_event,
+ uint32_t event_len,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len);
+
+/**
+ * @brief Encodes ble_gattc_evt_read_rsp event.
+ *
+ * @param[in] p_event Pointer to the \ref ble_evt_t buffer that shall be encoded.
+ * @param[in] event_len Size (in bytes) of \p p_event buffer.
+ * @param[out] p_buf Pointer to the beginning of a buffer for encoded event packet.
+ * @param[in,out] p_buf_len \c in: Size (in bytes) of \p p_buf buffer.
+ * \c out: Length of encoded contents in \p p_buf.
+ *
+ * @retval NRF_SUCCESS Encoding success.
+ * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length.
+ */
+uint32_t ble_gattc_evt_read_rsp_enc(ble_evt_t const * const p_event,
+ uint32_t event_len,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len);
+
+/**
+ * @brief Encodes ble_gattc_evt_rel_disc_rsp event.
+ *
+ * @param[in] p_event Pointer to the \ref ble_evt_t buffer that shall be encoded.
+ * @param[in] event_len Size (in bytes) of \p p_event buffer.
+ * @param[out] p_buf Pointer to the beginning of a buffer for encoded event packet.
+ * @param[in,out] p_buf_len \c in: Size (in bytes) of \p p_buf buffer.
+ * \c out: Length of encoded contents in \p p_buf.
+ *
+ * @retval NRF_SUCCESS Encoding success.
+ * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length.
+ */
+uint32_t ble_gattc_evt_rel_disc_rsp_enc(ble_evt_t const * const p_event,
+ uint32_t event_len,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len);
+
+/**
+ * @brief Encodes ble_gattc_evt_timeout event.
+ *
+ * @param[in] p_event Pointer to the \ref ble_evt_t buffer that shall be encoded.
+ * @param[in] event_len Size (in bytes) of \p p_event buffer.
+ * @param[out] p_buf Pointer to the beginning of a buffer for encoded event packet.
+ * @param[in,out] p_buf_len \c in: Size (in bytes) of \p p_buf buffer.
+ * \c out: Length of encoded contents in \p p_buf.
+ *
+ * @retval NRF_SUCCESS Encoding success.
+ * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length.
+ */
+uint32_t ble_gattc_evt_timeout_enc(ble_evt_t const * const p_event,
+ uint32_t event_len,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len);
+
+/**
+ * @brief Encodes ble_gattc_evt_write_rsp event.
+ *
+ * @param[in] p_event Pointer to the \ref ble_evt_t buffer that shall be encoded.
+ * @param[in] event_len Size (in bytes) of \p p_event buffer.
+ * @param[out] p_buf Pointer to the beginning of a buffer for encoded event packet.
+ * @param[in,out] p_buf_len \c in: Size (in bytes) of \p p_buf buffer.
+ * \c out: Length of encoded contents in \p p_buf.
+ *
+ * @retval NRF_SUCCESS Encoding success.
+ * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length.
+ */
+uint32_t ble_gattc_evt_write_rsp_enc(ble_evt_t const * const p_event,
+ uint32_t event_len,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len);
+
+/**
+ * @brief Encodes ble_gattc_evt_attr_info_disc_rsp event.
+ *
+ * @param[in] p_event Pointer to the \ref ble_evt_t buffer that shall be encoded.
+ * @param[in] event_len Size (in bytes) of \p p_event buffer.
+ * @param[out] p_buf Pointer to the beginning of a buffer for encoded event packet.
+ * @param[in,out] p_buf_len \c in: Size (in bytes) of \p p_buf buffer.
+ * \c out: Length of encoded contents in \p p_buf.
+ *
+ * @retval NRF_SUCCESS Encoding success.
+ * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length.
+ */
+uint32_t ble_gattc_evt_attr_info_disc_rsp_enc(ble_evt_t const * const p_event,
+ uint32_t event_len,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len);
+
+/**
+ * @brief Encodes ble_gattc_evt_exchange_mtu_rsp event.
+ *
+ *
+ * @param[in] p_event Pointer to the \ref ble_evt_t buffer that shall be encoded.
+ * @param[in] event_len Size (in bytes) of \p p_event buffer.
+ * @param[out] p_buf Pointer to the beginning of a buffer for encoded event packet.
+ * @param[in,out] p_buf_len \c in: Size (in bytes) of \p p_buf buffer.
+ * \c out: Length of encoded contents in \p p_buf.
+ *
+ * @retval NRF_SUCCESS Encoding success.
+ * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length.
+ */
+
+uint32_t ble_gattc_evt_exchange_mtu_rsp_enc(ble_evt_t const * const p_event,
+ uint32_t event_len,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len);
+
+#if NRF_SD_BLE_API_VERSION >= 4
+/**
+ * @brief Encodes @ref BLE_gattc_EVT_WRITE_CMD_TX_COMPLETE event.
+ *
+ * @param[in] p_event Pointer to the \ref ble_evt_t buffer that shall be encoded.
+ * @param[in] event_len Size (in bytes) of \p p_event buffer.
+ * @param[out] p_buf Pointer to the beginning of a buffer for encoded event packet.
+ * @param[in,out] p_buf_len \c in: Size (in bytes) of \p p_buf buffer.
+ * \c out: Length of encoded contents in \p p_buf.
+ *
+ * @retval NRF_SUCCESS Encoding success.
+ * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length.
+ */
+uint32_t ble_gattc_evt_write_cmd_tx_complete_enc(ble_evt_t const * const p_event,
+ uint32_t event_len,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len);
+#endif
+/** @} */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/connectivity/codecs/ble/serializers/ble_gatts_conn.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/connectivity/codecs/ble/serializers/ble_gatts_conn.c
new file mode 100644
index 0000000..1feb000
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/connectivity/codecs/ble/serializers/ble_gatts_conn.c
@@ -0,0 +1,421 @@
+/**
+ * Copyright (c) 2014 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#include "ble_gatts_conn.h"
+#include <string.h>
+#include "ble_serialization.h"
+#include "ble_struct_serialization.h"
+#include "ble_gatts_struct_serialization.h"
+#include "app_util.h"
+#include "cond_field_serialization.h"
+
+uint32_t ble_gatts_attr_get_req_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ uint16_t * p_handle,
+ ble_uuid_t * * pp_uuid,
+ ble_gatts_attr_md_t * * pp_md)
+{
+ SER_REQ_DEC_BEGIN(SD_BLE_GATTS_ATTR_GET);
+
+ SER_PULL_uint16(p_handle);
+ SER_PULL_COND(pp_uuid, NULL);
+ SER_PULL_COND(pp_md, NULL);
+
+ SER_REQ_DEC_END;
+}
+
+
+uint32_t ble_gatts_attr_get_rsp_enc(uint32_t return_code,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len,
+ ble_uuid_t * p_uuid,
+ ble_gatts_attr_md_t * p_md)
+{
+ SER_RSP_ENC_BEGIN(SD_BLE_GATTS_ATTR_GET);
+
+ SER_PUSH_COND(p_uuid, ble_uuid_t_enc);
+ SER_PUSH_COND(p_md, ble_gatts_attr_md_t_enc);
+
+ SER_RSP_ENC_END;
+}
+
+uint32_t ble_gatts_characteristic_add_req_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ uint16_t * p_service_handle,
+ ble_gatts_char_md_t * * const pp_char_md,
+ ble_gatts_attr_t * * const pp_attr_char_value,
+ ble_gatts_char_handles_t * * const pp_handles)
+{
+ SER_REQ_DEC_BEGIN(SD_BLE_GATTS_CHARACTERISTIC_ADD);
+
+ SER_PULL_uint16(p_service_handle);
+ SER_PULL_COND(pp_char_md, ble_gatts_char_md_t_dec);
+ SER_PULL_COND(pp_attr_char_value, ble_gatts_attr_t_dec);
+ SER_PULL_COND(pp_handles, NULL);
+
+ SER_REQ_DEC_END;
+}
+
+uint32_t ble_gatts_characteristic_add_rsp_enc(uint32_t return_code,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len,
+ ble_gatts_char_handles_t const * const p_handles)
+{
+ SER_RSP_ENC_BEGIN(SD_BLE_GATTS_CHARACTERISTIC_ADD);
+
+ SER_PUSH_COND(p_handles, ble_gatts_char_handles_t_enc);
+
+ SER_RSP_ENC_END;
+}
+
+uint32_t ble_gatts_descriptor_add_req_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ uint16_t * const p_char_handle,
+ ble_gatts_attr_t * * const pp_attr,
+ uint16_t * * const pp_handle)
+{
+ SER_REQ_DEC_BEGIN(SD_BLE_GATTS_DESCRIPTOR_ADD);
+
+ SER_PULL_uint16(p_char_handle);
+ SER_PULL_COND(pp_attr, ble_gatts_attr_t_dec);
+ SER_PULL_COND(pp_handle, NULL);
+
+ SER_REQ_DEC_END;
+}
+
+uint32_t ble_gatts_descriptor_add_rsp_enc(uint32_t return_code,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len,
+ uint16_t * p_handle)
+{
+ SER_RSP_ENC_BEGIN(SD_BLE_GATTS_DESCRIPTOR_ADD);
+
+ SER_PUSH_COND(p_handle,uint16_t_enc);
+
+ SER_RSP_ENC_END;
+}
+
+uint32_t ble_gatts_hvx_req_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ uint16_t * const p_conn_handle,
+ ble_gatts_hvx_params_t * * const pp_hvx_params)
+{
+ SER_REQ_DEC_BEGIN(SD_BLE_GATTS_HVX);
+
+ SER_PULL_uint16(p_conn_handle);
+ SER_PULL_COND(pp_hvx_params, ble_gatts_hvx_params_t_dec);
+
+ SER_REQ_DEC_END;
+}
+
+uint32_t ble_gatts_hvx_rsp_enc(uint32_t return_code,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len,
+ uint16_t const * const p_bytes_written)
+{
+ SER_RSP_ENC_BEGIN(SD_BLE_GATTS_HVX);
+
+ SER_PUSH_COND(p_bytes_written, uint16_t_enc);
+
+ SER_RSP_ENC_END;
+}
+
+uint32_t ble_gatts_include_add_req_dec(uint8_t const * const p_buf,
+ uint16_t packet_len,
+ uint16_t * const p_service_handle,
+ uint16_t * const p_inc_srvc_handle,
+ uint16_t * * const pp_include_handle)
+{
+ SER_REQ_DEC_BEGIN(SD_BLE_GATTS_INCLUDE_ADD);
+
+ SER_PULL_uint16(p_service_handle);
+ SER_PULL_uint16(p_inc_srvc_handle);
+ SER_PULL_COND(pp_include_handle, NULL);
+
+ SER_REQ_DEC_END;
+}
+
+
+uint32_t ble_gatts_include_add_rsp_enc(uint32_t return_code,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len,
+ uint16_t const * const p_include_handle)
+{
+ SER_RSP_ENC_BEGIN(SD_BLE_GATTS_INCLUDE_ADD);
+
+ SER_PUSH_COND(p_include_handle, uint16_t_enc);
+
+ SER_RSP_ENC_END;
+}
+
+uint32_t ble_gatts_initial_user_handle_get_req_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ uint16_t * * pp_handle)
+{
+ SER_REQ_DEC_BEGIN(SD_BLE_GATTS_INITIAL_USER_HANDLE_GET);
+
+ SER_PULL_COND(pp_handle, NULL);
+
+ SER_REQ_DEC_END;
+}
+
+
+uint32_t ble_gatts_initial_user_handle_get_rsp_enc(uint32_t return_code,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len,
+ uint16_t * p_handle)
+{
+ SER_RSP_ENC_BEGIN(SD_BLE_GATTS_INITIAL_USER_HANDLE_GET);
+
+ SER_PUSH_COND(p_handle, uint16_t_enc);
+
+ SER_RSP_ENC_END;
+}
+
+uint32_t ble_gatts_rw_authorize_reply_req_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ uint16_t * p_conn_handle,
+ ble_gatts_rw_authorize_reply_params_t * * const pp_reply_params)
+{
+ SER_REQ_DEC_BEGIN(SD_BLE_GATTS_RW_AUTHORIZE_REPLY);
+
+ SER_PULL_uint16(p_conn_handle);
+ SER_PULL_COND(pp_reply_params, ble_gatts_rw_authorize_reply_params_t_dec);
+ SER_REQ_DEC_END;
+}
+
+uint32_t ble_gatts_rw_authorize_reply_rsp_enc(uint32_t return_code,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len)
+{
+ SER_RSP_ENC_RESULT_ONLY(SD_BLE_GATTS_RW_AUTHORIZE_REPLY);
+}
+
+uint32_t ble_gatts_service_add_req_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ uint8_t * const p_type,
+ ble_uuid_t * * const pp_uuid,
+ uint16_t * * const pp_handle)
+{
+ SER_REQ_DEC_BEGIN(SD_BLE_GATTS_SERVICE_ADD);
+
+ SER_PULL_uint8(p_type);
+ SER_PULL_COND(pp_uuid, ble_uuid_t_dec);
+ SER_PULL_COND(pp_handle, NULL);
+
+ SER_REQ_DEC_END;
+}
+
+uint32_t ble_gatts_service_add_rsp_enc(uint32_t return_code,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len,
+ uint16_t const * const p_handle)
+{
+ SER_RSP_ENC_BEGIN(SD_BLE_GATTS_SERVICE_ADD);
+
+ SER_PUSH_COND(p_handle, uint16_t_enc);
+ //SER_PUSH_uint16(p_handle);
+
+ SER_RSP_ENC_END;
+}
+
+uint32_t ble_gatts_service_changed_req_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ uint16_t * p_conn_handle,
+ uint16_t * p_start_handle,
+ uint16_t * p_end_handle)
+{
+ SER_REQ_DEC_BEGIN(SD_BLE_GATTS_SERVICE_CHANGED);
+
+ SER_PULL_uint16(p_conn_handle);
+ SER_PULL_uint16(p_start_handle);
+ SER_PULL_uint16(p_end_handle);
+
+ SER_REQ_DEC_END;
+}
+
+
+uint32_t ble_gatts_service_changed_rsp_enc(uint32_t return_code,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len)
+{
+ SER_RSP_ENC_RESULT_ONLY(SD_BLE_GATTS_SERVICE_CHANGED);
+}
+
+uint32_t ble_gatts_sys_attr_get_req_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ uint16_t * const p_conn_handle,
+ uint8_t * * const pp_sys_attr_data,
+ uint16_t * * const pp_sys_attr_data_len,
+ uint32_t * const p_flags)
+{
+ SER_REQ_DEC_BEGIN(SD_BLE_GATTS_SYS_ATTR_GET);
+
+ SER_PULL_uint16(p_conn_handle);
+ SER_PULL_COND(pp_sys_attr_data_len, uint16_t_dec);
+ SER_PULL_COND(pp_sys_attr_data, NULL);
+ SER_PULL_uint32(p_flags);
+
+ SER_REQ_DEC_END;
+}
+
+
+uint32_t ble_gatts_sys_attr_get_rsp_enc(uint32_t return_code,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len,
+ uint8_t const * const p_sys_attr_data,
+ uint16_t const * const p_sys_attr_data_len)
+{
+ SER_RSP_ENC_BEGIN(SD_BLE_GATTS_SYS_ATTR_GET);
+
+ SER_PUSH_COND(p_sys_attr_data_len, uint16_t_enc);
+ if (p_sys_attr_data_len)
+ {
+ SER_PUSH_buf(p_sys_attr_data, *p_sys_attr_data_len);
+ }
+
+ SER_RSP_ENC_END;
+}
+
+uint32_t ble_gatts_sys_attr_set_req_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ uint16_t * const p_conn_handle,
+ uint8_t * * const pp_sys_attr_data,
+ uint16_t * const p_sys_attr_data_len,
+ uint32_t * const p_flags)
+{
+ SER_REQ_DEC_BEGIN(SD_BLE_GATTS_SYS_ATTR_SET);
+
+ SER_PULL_uint16(p_conn_handle);
+ SER_PULL_len16data(pp_sys_attr_data, p_sys_attr_data_len);
+ SER_PULL_uint32(p_flags);
+
+ SER_REQ_DEC_END;
+}
+
+uint32_t ble_gatts_sys_attr_set_rsp_enc(uint32_t return_code,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len)
+{
+ SER_RSP_ENC_RESULT_ONLY(SD_BLE_GATTS_SYS_ATTR_SET);
+}
+
+uint32_t ble_gatts_value_get_req_dec(uint8_t const * const p_buf,
+ uint16_t packet_len,
+ uint16_t * const p_conn_handle,
+ uint16_t * const p_handle,
+ ble_gatts_value_t * * const pp_value)
+{
+ SER_REQ_DEC_BEGIN(SD_BLE_GATTS_VALUE_GET);
+
+ SER_PULL_uint16(p_conn_handle);
+ SER_PULL_uint16(p_handle);
+
+ //Special case: skip the data.
+ SER_PULL_COND(pp_value, NULL);
+ if (*pp_value)
+ {
+ SER_PULL_uint16(&(*pp_value)->offset);
+ SER_PULL_uint16(&(*pp_value)->len);
+ SER_PULL_COND(&(*pp_value)->p_value, NULL);
+ }
+
+ SER_REQ_DEC_END;
+}
+
+uint32_t ble_gatts_value_get_rsp_enc(uint32_t return_code,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len,
+ ble_gatts_value_t * const p_value)
+{
+ SER_RSP_ENC_BEGIN(SD_BLE_GATTS_VALUE_GET);
+
+ SER_PUSH_COND(p_value, ble_gatts_value_t_enc);
+
+ SER_RSP_ENC_END;
+}
+
+uint32_t ble_gatts_value_set_req_dec(uint8_t const * const p_buf,
+ uint16_t packet_len,
+ uint16_t * p_conn_handle,
+ uint16_t * p_handle,
+ ble_gatts_value_t * * const pp_value)
+{
+ SER_REQ_DEC_BEGIN(SD_BLE_GATTS_VALUE_SET);
+
+ SER_PULL_uint16(p_conn_handle);
+ SER_PULL_uint16(p_handle);
+ SER_PULL_COND(pp_value, ble_gatts_value_t_dec);
+
+ SER_REQ_DEC_END;
+}
+
+
+uint32_t ble_gatts_value_set_rsp_enc(uint32_t return_code,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len,
+ ble_gatts_value_t * p_value)
+{
+ SER_RSP_ENC_BEGIN(SD_BLE_GATTS_VALUE_SET);
+
+ SER_PUSH_COND(p_value, ble_gatts_value_t_enc);
+
+ SER_RSP_ENC_END;
+}
+
+
+uint32_t ble_gatts_exchange_mtu_reply_req_dec(uint8_t const * const p_buf,
+ uint16_t packet_len,
+ uint16_t * const p_conn_handle,
+ uint16_t * const p_server_rx_mtu)
+{
+ SER_REQ_DEC_BEGIN(SD_BLE_GATTS_EXCHANGE_MTU_REPLY);
+
+ SER_PULL_uint16(p_conn_handle);
+ SER_PULL_uint16(p_server_rx_mtu);
+
+ SER_REQ_DEC_END;
+}
+
+uint32_t ble_gatts_exchange_mtu_reply_rsp_enc(uint32_t return_code,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len)
+{
+ SER_RSP_ENC_RESULT_ONLY(SD_BLE_GATTS_EXCHANGE_MTU_REPLY);
+}
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/connectivity/codecs/ble/serializers/ble_gatts_conn.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/connectivity/codecs/ble/serializers/ble_gatts_conn.h
new file mode 100644
index 0000000..0d56e0f
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/connectivity/codecs/ble/serializers/ble_gatts_conn.h
@@ -0,0 +1,634 @@
+/**
+ * Copyright (c) 2013 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#ifndef BLE_GATTS_CONN_H__
+#define BLE_GATTS_CONN_H__
+
+/**@file
+ *
+ * @defgroup ble_gatts_conn GATTS Connectivity command request decoders and command response encoders
+ * @{
+ * @ingroup ser_conn_s130_codecs
+ *
+ * @brief GATTS Connectivity command request decoders and command response encoders.
+ */
+
+#include "ble_gatts.h"
+#include "ble.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**@brief Decodes @ref sd_ble_gatts_value_get command request.
+ *
+ * @sa @ref ble_gatts_value_get_rsp_enc for response encoding.
+ *
+ * @param[in] p_buf Pointer to beginning of command request packet.
+ * @param[in] packet_len Length (in bytes) of request packet.
+ * @param[out] p_conn_handle Pointer to the connection_handle.
+ * @param[out] p_handle Pointer to the attribute_handle.
+ * @param[out] pp_value Pointer to pointer to the Attribute Value structure.
+ *
+ * @retval NRF_SUCCESS Decoding success.
+ * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length.
+ */
+uint32_t ble_gatts_value_get_req_dec(uint8_t const * const p_buf,
+ uint16_t packet_len,
+ uint16_t * const p_conn_handle,
+ uint16_t * const p_handle,
+ ble_gatts_value_t * * const pp_value);
+
+/**@brief Encodes @ref sd_ble_gatts_value_get command response.
+ *
+ * @sa @ref ble_gatts_value_get_req_dec for request decoding.
+ *
+ * @param[in] return_code Return code indicating if command was successful or not.
+ * @param[out] p_buf Pointer to buffer where encoded data command response will be
+ * returned.
+ * @param[in,out] p_buf_len \c in: size of \p p_buf buffer.
+ * \c out: Length of encoded command response packet.
+ * @param[in] p_value Pointer to Attribute Value structure.
+ *
+ * @retval NRF_SUCCESS Encoding success.
+ * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length.
+ */
+uint32_t ble_gatts_value_get_rsp_enc(uint32_t return_code,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len,
+ ble_gatts_value_t * const p_value);
+
+/**@brief Decodes @ref sd_ble_gatts_characteristic_add command request.
+ *
+ * @sa @ref ble_gatts_characteristic_add_rsp_enc for response encoding.
+ *
+ * @param[in] p_buf Pointer to beginning of command request packet.
+ * @param[in] packet_len Length (in bytes) of request packet.
+ * @param[out] p_service_handle Pointer to the service_handle.
+ * @param[out] constpp_char_md Pointer to pointer to the location where Characteristic metadata
+ * will be decoded.
+ * @param[out] pp_attr_char_value Pointer to pointer to the location where GATT Attribute will be
+ * decoded.
+ * @param[out] pp_handles Pointer to pointer to the location where Characteristic definition
+ * handles will be decoded.
+ *
+ * @retval NRF_SUCCESS Decoding success.
+ * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length.
+ */
+uint32_t ble_gatts_characteristic_add_req_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ uint16_t * p_service_handle,
+ ble_gatts_char_md_t * * constpp_char_md,
+ ble_gatts_attr_t * * const pp_attr_char_value,
+ ble_gatts_char_handles_t * * const pp_handles);
+
+/**@brief Encodes @ref ble_gatts_sys_attr_get_rsp_enc command response.
+ *
+ * @sa @ref ble_gatts_sys_attr_get_req_dec for request decoding.
+ *
+ * @param[in] return_code Return code indicating if command was successful or not.
+ * @param[out] p_buf Pointer to buffer where encoded data command response will be
+ * returned.
+ * @param[in,out] p_buf_len \c in: size of \p p_buf buffer.
+ * \c out: Length of encoded command response packet.
+ * @param[in] p_handles Pointer to handle struct to be encoded.
+ *
+ * @retval NRF_SUCCESS Encoding success.
+ * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length.
+ */
+uint32_t ble_gatts_characteristic_add_rsp_enc(uint32_t return_code,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len,
+ ble_gatts_char_handles_t const * const p_handles);
+
+/**@brief Decodes @ref sd_ble_gatts_include_add command request.
+ *
+ * @sa @ref ble_gatts_include_add_rsp_enc for response encoding.
+ *
+ * @param[in] p_buf Pointer to beginning of command request packet.
+ * @param[in] packet_len Length (in bytes) of request packet.
+ * @param[out] p_service_handle Pointer to the service_handle.
+ * @param[out] p_inc_srvc_handle Pointer to the handle of the included service.
+ * @param[out] pp_include_handle Pointer to Pointer to 16-bit word where the assigned handle will be stored.
+ *
+ * @retval NRF_SUCCESS Decoding success.
+ * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length.
+ */
+
+uint32_t ble_gatts_include_add_req_dec(uint8_t const * const p_buf,
+ uint16_t packet_len,
+ uint16_t * const p_service_handle,
+ uint16_t * const p_inc_srvc_handle,
+ uint16_t * * const pp_include_handle);
+
+/**@brief Encodes @ref ble_gatts_include_add_rsp_enc command response.
+ *
+ * @param[in] return_code Return code indicating if command was successful or not.
+ * @param[out] p_buf Pointer to buffer where encoded data command response will be
+ * returned.
+ * @param[in,out] p_buf_len \c in: size of \p p_buf buffer.
+ * \c out: Length of encoded command response packet.
+ * @param[in] p_include_handle Pointer to a 16-bit word where the assigned handle was stored.
+ *
+ * @retval NRF_SUCCESS Encoding success.
+ * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length.
+ */
+
+uint32_t ble_gatts_include_add_rsp_enc(uint32_t return_code,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len,
+ uint16_t const * const p_include_handle);
+
+/**@brief Decodes @ref sd_ble_gatts_service_add command request.
+ *
+ * @sa @ref ble_gatts_service_add_rsp_enc for response encoding.
+ *
+ * @param[in] p_buf Pointer to beginning of command request packet.
+ * @param[in] packet_len Length (in bytes) of request packet.
+ * @param[out] p_type Pointer to the service type.
+ * @param[out] pp_uuid Pointer to pointer to service UUID.
+ * @param[out] pp_handle Pointer to pointer to a 16-bit word where the assigned handle will be stored.
+ *
+ * @retval NRF_SUCCESS Decoding success.
+ * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length.
+ */
+
+uint32_t ble_gatts_service_add_req_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ uint8_t * const p_type,
+ ble_uuid_t * * const pp_uuid,
+ uint16_t * * const pp_handle);
+
+/**@brief Encodes @ref ble_gatts_service_add_rsp_enc command response.
+ *
+ * @param[in] return_code Return code indicating if command was successful or not.
+ * @param[out] p_buf Pointer to buffer where encoded data command response will be
+ * returned.
+ * @param[in,out] p_buf_len \c in: size of \p p_buf buffer.
+ * \c out: Length of encoded command response packet.
+ * @param[in] p_handle Pointer to a 16-bit word where the assigned handle was stored.
+ *
+ * @retval NRF_SUCCESS Encoding success.
+ * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length.
+ */
+
+uint32_t ble_gatts_service_add_rsp_enc(uint32_t return_code,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len,
+ uint16_t const * const p_handle);
+
+/**@brief Decodes @ref ble_gatts_sys_attr_get_req_dec command request.
+ *
+ * @sa @ref ble_gatts_sys_attr_get_rsp_enc for response encoding.
+ *
+ * @param[in] p_buf Pointer to beginning of command request packet.
+ * @param[in] packet_len Length (in bytes) of response packet.
+ * @param[out] p_conn_handle Pointer to connectiton handle.
+ * @param[out] pp_sys_attr_data Pointer to pointer to buffer where system attributes data will be filled in.
+ * @param[out] pp_sys_attr_data_len Pointer to pointer to variable which contains size of buffer for system attributes.
+ * @param[out] p_flags Pointer to additional optional flags.
+ *
+ * @retval NRF_SUCCESS Decoding success.
+ * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length.
+ * @retval NRF_ERROR_INVALID_PARAM Decoding failure. Invalid operation type.
+ */
+uint32_t ble_gatts_sys_attr_get_req_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ uint16_t * const p_conn_handle,
+ uint8_t * * const pp_sys_attr_data,
+ uint16_t * * const pp_sys_attr_data_len,
+ uint32_t * const p_flags);
+
+/**@brief Encodes @ref ble_gatts_sys_attr_get_rsp_enc command response.
+ *
+ * @sa @ref ble_gatts_sys_attr_get_req_dec for request decoding.
+ *
+ * @param[in] return_code Return code indicating if command was successful or not.
+ * @param[out] p_buf Pointer to buffer where encoded data command response will be
+ * returned.
+ * @param[in,out] p_buf_len \c in: size of \p p_buf buffer.
+ * \c out: Length of encoded command response packet.
+ * @param[in] p_sys_attr_data Pointer to buffer where system attributes data are stored.
+ * @param[in] p_sys_attr_data_len Pointer to variable which contains size of buffer for system attributes.
+ *
+ * @retval NRF_SUCCESS Encoding success.
+ * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length.
+ */
+uint32_t ble_gatts_sys_attr_get_rsp_enc(uint32_t return_code,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len,
+ uint8_t const * const p_sys_attr_data,
+ uint16_t const * const p_sys_attr_data_len);
+
+/**@brief Decodes @ref sd_ble_gatts_value_set command request.
+ *
+ * @sa @ref ble_gatts_value_set_rsp_enc for response encoding.
+ *
+ * @param[in] p_buf Pointer to beginning of command request packet.
+ * @param[in] packet_len Length (in bytes) of response packet.
+ * @param[out] p_conn_handle Pointer to connection handle.
+ * @param[out] p_handle Pointer to attribute handle.
+ * @param[out] pp_value Pointer to pointer to attribute value structure.
+ *
+ * @retval NRF_SUCCESS Decoding success.
+ * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length.
+ * @retval NRF_ERROR_INVALID_PARAM Decoding failure. Invalid operation type.
+ */
+
+uint32_t ble_gatts_value_set_req_dec(uint8_t const * const p_buf,
+ uint16_t packet_len,
+ uint16_t * p_conn_handle,
+ uint16_t * p_handle,
+ ble_gatts_value_t * * const pp_value);
+
+/**@brief Encodes @ref sd_ble_gatts_value_set command response.
+ *
+ * @param[in] return_code Return code indicating if command was successful or not.
+ * @param[in] p_buf Pointer to buffer where encoded data command response will be
+ * returned.
+ * @param[in, out] p_buf_len \c in: size of \p p_buf buffer.
+ * \c out: Length of encoded command response packet.
+ * @param[in] p_value \c in: size of value returned when value was written with success
+ *
+ * @retval NRF_SUCCESS Encoding success.
+ * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length.
+ */
+uint32_t ble_gatts_value_set_rsp_enc(uint32_t return_code,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len,
+ ble_gatts_value_t * p_value);
+
+/**@brief Decodes @ref sd_ble_gatts_sys_attr_set command request.
+ *
+ * @sa @ref ble_gatts_sys_attr_set_rsp_enc for response encoding.
+ *
+ * @param[in] p_buf Pointer to beginning of command request packet.
+ * @param[in] packet_len Length (in bytes) of request packet.
+ * @param[out] p_conn_handle Pointer to the buffer raw data to be placed in advertisement packet.
+ * @param[out] pp_sys_attr_data Pointer to pointer to system attribute data.
+ * @param[out] p_sys_attr_data_len Pointer to data length for system attribute data.
+ * @param[out] p_flags Pointer to additional optional flags.
+ *
+ * @retval NRF_SUCCESS Decoding success.
+ * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length.
+ */
+uint32_t ble_gatts_sys_attr_set_req_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ uint16_t * const p_conn_handle,
+ uint8_t * * const pp_sys_attr_data,
+ uint16_t * const p_sys_attr_data_len,
+ uint32_t * const p_flags);
+
+/**@brief Encodes @ref sd_ble_gatts_sys_attr_set command response.
+ *
+ * @sa @ref ble_gatts_sys_attr_set_req_dec for request decoding.
+ *
+ * @param[in] return_code Return code indicating if command was successful or not.
+ * @param[out] p_buf Pointer to buffer where encoded data command response will be
+ * returned.
+ * @param[in,out] p_buf_len \c in: size of \p p_buf buffer.
+ * \c out: Length of encoded command response packet.
+ *
+ * @retval NRF_SUCCESS Encoding success.
+ * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length.
+ */
+uint32_t ble_gatts_sys_attr_set_rsp_enc(uint32_t return_code,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len);
+
+/**@brief Decodes @ref ble_gatts_hvx_req_dec command request.
+ *
+ * @sa @ref ble_gatts_hvx_rsp_enc for response encoding.
+ *
+ * @param[in] p_buf Pointer to beginning of command request packet.
+ * @param[in] packet_len Length (in bytes) of request packet.
+ * @param[out] p_conn_handle Pointer to the buffer raw data to be placed in advertisement packet.
+ * @param[out] pp_hvx_params Pointer to an HVx parameters structure.
+ *
+ * @retval NRF_SUCCESS Decoding success.
+ * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length.
+ */
+uint32_t ble_gatts_hvx_req_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ uint16_t * const p_conn_handle,
+ ble_gatts_hvx_params_t * * const pp_hvx_params);
+
+/**@brief Encodes @ref ble_gatts_hvx_rsp_enc command response.
+ *
+ * @sa @ref ble_gatts_hvx_req_dec for request decoding.
+ *
+ * @param[in] return_code Return code indicating if command was successful or not.
+ * @param[out] p_buf Pointer to buffer where encoded data command response will be
+ * returned.
+ * @param[in,out] p_buf_len \c in: size of \p p_buf buffer.
+ * \c out: Length of encoded command response packet.
+ * @param[in] p_bytes_written Pointer to number of bytes written.
+ *
+ * @retval NRF_SUCCESS Encoding success.
+ * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length.
+ */
+uint32_t ble_gatts_hvx_rsp_enc(uint32_t return_code,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len,
+ uint16_t const * const p_bytes_written);
+
+/**@brief Decodes @ref sd_ble_gatts_descriptor_add command request.
+ *
+ * @sa @ref ble_gatts_descriptor_add_rsp_enc for response encoding.
+ *
+ * @param[in] p_buf Pointer to beginning of command request packet.
+ * @param[in] packet_len Length (in bytes) of request packet.
+ * @param[out] p_char_handle Pointer to buffer where characteristic handle will be.
+ returned.
+ * @param[out] pp_attr Pointer to pointer to an attribute structure.
+ * @param[out] pp_handle Pointer to pointer to descriptor handle.
+ *
+ * @retval NRF_SUCCESS Decoding success.
+ * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length.
+ */
+uint32_t ble_gatts_descriptor_add_req_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ uint16_t * const p_char_handle,
+ ble_gatts_attr_t * * const pp_attr,
+ uint16_t * * const pp_handle);
+
+/**@brief Encodes @ref sd_ble_gatts_descriptor_add command response.
+ *
+ * @sa @ref ble_gatts_descriptor_add_req_dec for request decoding.
+ *
+ * @param[in] return_code Return code indicating if command was successful or not.
+ * @param[out] p_buf Pointer to buffer where encoded data command response will be
+ * returned.
+ * @param[in,out] p_buf_len \c in: size of \p p_buf buffer.
+ * \c out: Length of encoded command response packet.
+ * @param[in] p_handle Pointer to descriptor handle value.
+ *
+ * @retval NRF_SUCCESS Encoding success.
+ * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length.
+ */
+uint32_t ble_gatts_descriptor_add_rsp_enc(uint32_t return_code,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len,
+ uint16_t * p_handle);
+
+/**@brief Decodes @ref sd_ble_gatts_rw_authorize_reply command request.
+ *
+ * @sa @ref ble_gatts_rw_authorize_reply_rsp_enc for response encoding.
+ *
+ * @param[in] p_buf Pointer to beginning of command request packet.
+ * @param[in] packet_len Length (in bytes) of response packet.
+ * @param[out] p_conn_handle Pointer to connection handle.
+ * @param[out] pp_reply_params Pointer to pointer to \ref ble_gatts_rw_authorize_reply_params_t .
+ *
+ * @retval NRF_SUCCESS Decoding success.
+ * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length.
+ * @retval NRF_ERROR_INVALID_PARAM Decoding failure. Invalid operation type.
+ */
+
+uint32_t ble_gatts_rw_authorize_reply_req_dec(
+ uint8_t const * const p_buf,
+ uint32_t
+ packet_len,
+ uint16_t *
+ p_conn_handle,
+ ble_gatts_rw_authorize_reply_params_t * * const
+ pp_reply_params);
+
+/**@brief Encodes @ref sd_ble_gatts_rw_authorize_reply command response.
+ *
+ * @sa @ref ble_gatts_rw_authorize_reply_req_dec for request decoding.
+ *
+ * @param[in] return_code Return code indicating if command was successful or not.
+ * @param[out] p_buf Pointer to buffer where encoded data command response will be
+ * returned.
+ * @param[in,out] p_buf_len \c in: size of \p p_buf buffer.
+ * \c out: Length of encoded command response packet.
+ *
+ * @retval NRF_SUCCESS Encoding success.
+ * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length.
+ */
+uint32_t ble_gatts_rw_authorize_reply_rsp_enc(uint32_t return_code,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len);
+
+/**@brief Decodes @ref sd_ble_gatts_service_changed command request.
+ *
+ * @sa @ref ble_gatts_service_changed_rsp_enc for response encoding.
+ *
+ * @param[in] p_buf Pointer to beginning of command request packet.
+ * @param[in] packet_len Length (in bytes) of response packet.
+ * @param[out] p_conn_handle Pointer to connection handle.
+ * @param[out] p_start_handle Pointer to start handle.
+ * @param[out] p_end_handle Pointer to end handle.
+ *
+ * @retval NRF_SUCCESS Decoding success.
+ * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length.
+ * @retval NRF_ERROR_INVALID_PARAM Decoding failure. Invalid operation type.
+ */
+uint32_t ble_gatts_service_changed_req_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ uint16_t * p_conn_handle,
+ uint16_t * p_start_handle,
+ uint16_t * p_end_handle);
+
+/**@brief Encodes @ref sd_ble_gatts_service_changed command response.
+ *
+ * @sa @ref ble_gatts_service_changed_req_dec for request decoding.
+ *
+ * @param[in] return_code Return code indicating if command was successful or not.
+ * @param[out] p_buf Pointer to buffer where encoded data command response will be
+ * returned.
+ * @param[in,out] p_buf_len \c in: size of \p p_buf buffer.
+ * \c out: Length of encoded command response packet.
+ *
+ * @retval NRF_SUCCESS Encoding success.
+ * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length.
+ */
+uint32_t ble_gatts_service_changed_rsp_enc(uint32_t return_code,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len);
+
+/**@brief Decodes @ref ble_gatts_attr_get_req_dec command request.
+ *
+ * @sa @ref ble_gatts_attr_get_rsp_enc for response encoding.
+ *
+ * @param[in] p_buf Pointer to beginning of command request packet.
+ * @param[in] packet_len Length (in bytes) of response packet.
+ * @param[out] p_handle Pointer to handle.
+ * @param[out] pp_uuid Pointer to pointer to location for decoded uuid structure.
+ * @param[out] pp_md Pointer to pointer to location for md structure.
+ *
+ * @retval NRF_SUCCESS Decoding success.
+ * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length.
+ * @retval NRF_ERROR_INVALID_PARAM Decoding failure. Invalid operation type.
+ */
+uint32_t ble_gatts_attr_get_req_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ uint16_t * p_handle,
+ ble_uuid_t * * pp_uuid,
+ ble_gatts_attr_md_t * * pp_md);
+
+/**@brief Encodes @ref ble_gatts_attr_get_rsp_enc command response.
+ *
+ * @sa @ref ble_gatts_attr_get_req_dec for request decoding.
+ *
+ * @param[in] return_code Return code indicating if command was successful or not.
+ * @param[out] p_buf Pointer to buffer where encoded data command response will be
+ * returned.
+ * @param[in,out] p_buf_len \c in: size of \p p_buf buffer.
+ * \c out: Length of encoded command response packet.
+ * @param[in] p_uuid Pointer to structure to be encoded.
+ * @param[in] p_md Pointer to structure to be encoded.
+ *
+ * @retval NRF_SUCCESS Encoding success.
+ * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length.
+ */
+uint32_t ble_gatts_attr_get_rsp_enc(uint32_t return_code,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len,
+ ble_uuid_t * p_uuid,
+ ble_gatts_attr_md_t * p_md);
+
+/**@brief Decodes @ref ble_gatts_initial_user_handle_get_req_dec command request.
+ *
+ * @sa @ref ble_gatts_initial_user_handle_get_rsp_enc for response encoding.
+ *
+ * @param[in] p_buf Pointer to beginning of command request packet.
+ * @param[in] packet_len Length (in bytes) of response packet.
+ * @param[out] pp_handle Pointer to pointer to handle.
+ *
+ * @retval NRF_SUCCESS Decoding success.
+ * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length.
+ * @retval NRF_ERROR_INVALID_PARAM Decoding failure. Invalid operation type.
+ */
+uint32_t ble_gatts_initial_user_handle_get_req_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ uint16_t * * pp_handle);
+
+/**@brief Encodes @ref ble_gatts_initial_user_handle_get_rsp_enc command response.
+ *
+ * @sa @ref ble_gatts_initial_user_handle_get_req_dec for request decoding.
+ *
+ * @param[in] return_code Return code indicating if command was successful or not.
+ * @param[out] p_buf Pointer to buffer where encoded data command response will be
+ * returned.
+ * @param[in,out] p_buf_len \c in: size of \p p_buf buffer.
+ * \c out: Length of encoded command response packet.
+ * @param[in] p_handle Pointer to handle to be encoded.
+ *
+ * @retval NRF_SUCCESS Encoding success.
+ * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length.
+ */
+uint32_t ble_gatts_initial_user_handle_get_rsp_enc(uint32_t return_code,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len,
+ uint16_t * p_handle);
+
+/**@brief Decodes @ref sd_ble_gatts_rw_authorize_reply command request.
+ *
+ * @ref ble_gatts_exchange_mtu_reply_rsp_enc for response encoding.
+ *
+ * @param[in] p_buf Pointer to beginning of command request packet.
+ * @param[in] packet_len Length (in bytes) of response packet.
+ * @param[out] p_conn_handle Pointer to connection handle.
+ * @param[out] p_server_rx_mtu Pointer to Server RX MTU size.
+ *
+ * @retval NRF_SUCCESS Decoding success.
+ * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length.
+ * @retval NRF_ERROR_INVALID_PARAM Decoding failure. Invalid operation type.
+ */
+
+uint32_t ble_gatts_exchange_mtu_reply_req_dec(uint8_t const * const p_buf,
+ uint16_t packet_len,
+ uint16_t * const p_conn_handle,
+ uint16_t * const p_server_rx_mtu);
+
+/**@brief Encodes @ref sd_ble_gatts_rw_authorize_reply command response.
+ *
+ * @ref ble_gatts_exchange_mtu_reply_req_dec for request decoding.
+ *
+ * @param[in] return_code Return code indicating if command was successful or not.
+ * @param[out] p_buf Pointer to buffer where encoded data command response will be
+ * returned.
+ * @param[in,out] p_buf_len \c in: size of \p p_buf buffer.
+ * \c out: Length of encoded command response packet.
+ *
+ * @retval NRF_SUCCESS Encoding success.
+ * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length.
+ */
+uint32_t ble_gatts_exchange_mtu_reply_rsp_enc(uint32_t return_code,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len);
+
+/** @} */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif //BLE_GATTS_CONN_H__
+
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/connectivity/codecs/ble/serializers/ble_gatts_evt_conn.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/connectivity/codecs/ble/serializers/ble_gatts_evt_conn.c
new file mode 100644
index 0000000..252c571
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/connectivity/codecs/ble/serializers/ble_gatts_evt_conn.c
@@ -0,0 +1,178 @@
+/**
+ * Copyright (c) 2014 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#include "ble_gatts_evt_conn.h"
+#include "ble_serialization.h"
+#include "ble_gatts_struct_serialization.h"
+#include "conn_ble_user_mem.h"
+#include "app_util.h"
+
+extern sercon_ble_user_mem_t m_conn_user_mem_table[];
+
+
+uint32_t ble_gatts_evt_rw_authorize_request_enc(ble_evt_t const * const p_event,
+ uint32_t event_len,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len)
+{
+ SER_EVT_ENC_BEGIN(BLE_GATTS_EVT_RW_AUTHORIZE_REQUEST);
+
+ SER_PUSH_uint16(&p_event->evt.gatts_evt.conn_handle);
+ SER_PUSH_FIELD(&p_event->evt.gatts_evt.params.authorize_request, ble_gatts_evt_rw_authorize_request_t_enc);
+
+ if ((p_event->evt.gatts_evt.params.authorize_request.type == BLE_GATTS_AUTHORIZE_TYPE_WRITE) &&
+ ((p_event->evt.gatts_evt.params.authorize_request.request.write.op == BLE_GATTS_OP_EXEC_WRITE_REQ_NOW) ||
+ (p_event->evt.gatts_evt.params.authorize_request.request.write.op == BLE_GATTS_OP_PREP_WRITE_REQ)))
+ {
+ uint32_t conn_index;
+
+ if (conn_ble_user_mem_context_find(p_event->evt.gatts_evt.conn_handle, &conn_index) != NRF_ERROR_NOT_FOUND)
+ {
+ err_code = len16data_enc(m_conn_user_mem_table[conn_index].mem_block.p_mem, m_conn_user_mem_table[conn_index].mem_block.len, p_buf, *p_buf_len, &index);
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code);
+ }
+ }
+
+ SER_EVT_ENC_END;
+}
+
+
+uint32_t ble_gatts_evt_hvc_enc(ble_evt_t const * const p_event,
+ uint32_t event_len,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len)
+{
+ SER_EVT_ENC_BEGIN(BLE_GATTS_EVT_HVC);
+
+ SER_PUSH_uint16(&p_event->evt.gatts_evt.conn_handle);
+ SER_PUSH_FIELD(&p_event->evt.gatts_evt.params.hvc, ble_gatts_evt_hvc_t_enc);
+
+ SER_EVT_ENC_END;
+}
+
+
+uint32_t ble_gatts_evt_sc_confirm_enc(ble_evt_t const * const p_event,
+ uint32_t event_len,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len)
+{
+ SER_EVT_ENC_BEGIN(BLE_GATTS_EVT_HVC);
+ SER_PUSH_uint16(&p_event->evt.gatts_evt.conn_handle);
+ SER_EVT_ENC_END;
+}
+
+
+uint32_t ble_gatts_evt_sys_attr_missing_enc(ble_evt_t const * const p_event,
+ uint32_t event_len,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len)
+{
+ SER_EVT_ENC_BEGIN(BLE_GATTS_EVT_SYS_ATTR_MISSING);
+
+ SER_PUSH_uint16(&p_event->evt.gatts_evt.conn_handle);
+ SER_PUSH_FIELD(&p_event->evt.gatts_evt.params.sys_attr_missing, ble_gatts_evt_sys_attr_missing_t_enc);
+
+ SER_EVT_ENC_END;
+}
+
+
+uint32_t ble_gatts_evt_timeout_enc(ble_evt_t const * const p_event,
+ uint32_t event_len,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len)
+{
+ SER_EVT_ENC_BEGIN(BLE_GATTS_EVT_TIMEOUT);
+
+ SER_PUSH_uint16(&p_event->evt.gatts_evt.conn_handle);
+ SER_PUSH_FIELD(&p_event->evt.gatts_evt.params.timeout, ble_gatts_evt_timeout_t_enc);
+
+ SER_EVT_ENC_END;
+}
+
+
+uint32_t ble_gatts_evt_write_enc(ble_evt_t const * const p_event,
+ uint32_t event_len,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len)
+{
+ SER_EVT_ENC_BEGIN(BLE_GATTS_EVT_WRITE);
+
+ SER_PUSH_uint16(&p_event->evt.gatts_evt.conn_handle);
+ SER_PUSH_FIELD(&p_event->evt.gatts_evt.params.write, ble_gatts_evt_write_t_enc);
+
+ if ((p_event->evt.gatts_evt.params.write.op == BLE_GATTS_OP_WRITE_REQ) || (p_event->evt.gatts_evt.params.write.op == BLE_GATTS_OP_EXEC_WRITE_REQ_NOW))
+ {
+ uint32_t conn_index;
+ if (conn_ble_user_mem_context_find(p_event->evt.gatts_evt.conn_handle, &conn_index) != NRF_ERROR_NOT_FOUND)
+ {
+ SER_PUSH_len16data(m_conn_user_mem_table[conn_index].mem_block.p_mem, m_conn_user_mem_table[conn_index].mem_block.len);
+ }
+ }
+
+ SER_EVT_ENC_END;
+}
+
+
+uint32_t ble_gatts_evt_exchange_mtu_request_enc(ble_evt_t const * const p_event,
+ uint32_t event_len,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len)
+{
+ SER_EVT_ENC_BEGIN(BLE_GATTS_EVT_EXCHANGE_MTU_REQUEST);
+
+ SER_PUSH_uint16(&p_event->evt.gatts_evt.conn_handle);
+ SER_PUSH_FIELD(&p_event->evt.gatts_evt.params.exchange_mtu_request, ble_gatts_evt_exchange_mtu_request_t_enc);
+
+ SER_EVT_ENC_END;
+}
+
+#if NRF_SD_BLE_API_VERSION >= 4
+uint32_t ble_gatts_evt_hvn_tx_complete_enc(ble_evt_t const * const p_event,
+ uint32_t event_len,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len)
+{
+ SER_EVT_ENC_BEGIN(BLE_GATTS_EVT_HVN_TX_COMPLETE);
+
+ SER_PUSH_uint16(&p_event->evt.gatts_evt.conn_handle);
+ SER_PUSH_uint8(&p_event->evt.gatts_evt.params.hvn_tx_complete.count);
+
+ SER_EVT_ENC_END;
+}
+#endif
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/connectivity/codecs/ble/serializers/ble_gatts_evt_conn.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/connectivity/codecs/ble/serializers/ble_gatts_evt_conn.h
new file mode 100644
index 0000000..a7d1749
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/connectivity/codecs/ble/serializers/ble_gatts_evt_conn.h
@@ -0,0 +1,208 @@
+/**
+ * Copyright (c) 2014 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#ifndef BLE_GATTS_EVT_CONN_H__
+#define BLE_GATTS_EVT_CONN_H__
+
+/**@file
+ *
+ * @defgroup ble_gatts_evt_conn GATTS Connectivity event encoders
+ * @{
+ * @ingroup ser_conn_s130_codecs
+ *
+ * @brief GATTS Connectivity event encoders.
+ */
+#include "ble.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @brief Encodes @ref BLE_GATTS_EVT_HVC event.
+ *
+ * @param[in] p_event Pointer to the \ref ble_evt_t buffer that shall be encoded.
+ * @param[in] event_len Size (in bytes) of \p p_event buffer.
+ * @param[out] p_buf Pointer to the beginning of a buffer for encoded event packet.
+ * @param[in,out] p_buf_len \c in: Size (in bytes) of \p p_buf buffer.
+ * \c out: Length of encoded contents in \p p_buf.
+ *
+ * @retval NRF_SUCCESS Encoding success.
+ * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length.
+ */
+uint32_t ble_gatts_evt_hvc_enc(ble_evt_t const * const p_event,
+ uint32_t event_len,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len);
+
+/**
+ * @brief Encodes @ref BLE_GATTS_EVT_RW_AUTHORIZE_REQUEST event.
+ *
+ * @param[in] p_event Pointer to the \ref ble_evt_t buffer that shall be encoded.
+ * @param[in] event_len Size (in bytes) of \p p_event buffer.
+ * @param[out] p_buf Pointer to the beginning of a buffer for encoded event packet.
+ * @param[in,out] p_buf_len \c in: Size (in bytes) of \p p_buf buffer.
+ * \c out: Length of encoded contents in \p p_buf.
+ *
+ * @retval NRF_SUCCESS Encoding success.
+ * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length.
+ */
+uint32_t ble_gatts_evt_rw_authorize_request_enc(ble_evt_t const * const p_event,
+ uint32_t event_len,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len);
+
+/**
+ * @brief Encodes @ref BLE_GATTS_EVT_SC_CONFIRM event.
+ *
+ * @param[in] p_event Pointer to the \ref ble_evt_t buffer that shall be encoded.
+ * @param[in] event_len Size (in bytes) of \p p_event buffer.
+ * @param[out] p_buf Pointer to the beginning of a buffer for encoded event packet.
+ * @param[in,out] p_buf_len \c in: Size (in bytes) of \p p_buf buffer.
+ * \c out: Length of encoded contents in \p p_buf.
+ *
+ * @retval NRF_SUCCESS Encoding success.
+ * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length.
+ */
+uint32_t ble_gatts_evt_sc_confirm_enc(ble_evt_t const * const p_event,
+ uint32_t event_len,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len);
+
+/**
+ * @brief Encodes @ref BLE_GATTS_EVT_SYS_ATTR_MISSING event.
+ *
+ * @param[in] p_event Pointer to the \ref ble_evt_t buffer that shall be encoded.
+ * @param[in] event_len Size (in bytes) of \p p_event buffer.
+ * @param[out] p_buf Pointer to the beginning of a buffer for encoded event packet.
+ * @param[in,out] p_buf_len \c in: Size (in bytes) of \p p_buf buffer.
+ * \c out: Length of encoded contents in \p p_buf.
+ *
+ * @retval NRF_SUCCESS Encoding success.
+ * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length.
+ */
+uint32_t ble_gatts_evt_sys_attr_missing_enc(ble_evt_t const * const p_event,
+ uint32_t event_len,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len);
+
+/**
+ * @brief Encodes @ref BLE_GATTS_EVT_TIMEOUT event.
+ *
+ * @param[in] p_event Pointer to the \ref ble_evt_t buffer that shall be encoded.
+ * @param[in] event_len Size (in bytes) of \p p_event buffer.
+ * @param[out] p_buf Pointer to the beginning of a buffer for encoded event packet.
+ * @param[in,out] p_buf_len \c in: Size (in bytes) of \p p_buf buffer.
+ * \c out: Length of encoded contents in \p p_buf.
+ *
+ * @retval NRF_SUCCESS Encoding success.
+ * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length.
+ */
+uint32_t ble_gatts_evt_timeout_enc(ble_evt_t const * const p_event,
+ uint32_t event_len,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len);
+
+/**
+ * @brief Encodes @ref BLE_GATTS_EVT_WRITE event.
+ *
+ * @param[in] p_event Pointer to the \ref ble_evt_t buffer that shall be encoded.
+ * @param[in] event_len Size (in bytes) of \p p_event buffer.
+ * @param[out] p_buf Pointer to the beginning of a buffer for encoded event packet.
+ * @param[in,out] p_buf_len \c in: Size (in bytes) of \p p_buf buffer.
+ * \c out: Length of encoded contents in \p p_buf.
+ *
+ * @retval NRF_SUCCESS Encoding success.
+ * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length.
+ */
+uint32_t ble_gatts_evt_write_enc(ble_evt_t const * const p_event,
+ uint32_t event_len,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len);
+
+/**
+ * @brief Encodes @ref BLE_GATTS_EVT_EXCHANGE_MTU_REQUEST event.
+ *
+ * @param[in] p_event Pointer to the \ref ble_evt_t buffer that shall be encoded.
+ * @param[in] event_len Size (in bytes) of \p p_event buffer.
+ * @param[out] p_buf Pointer to the beginning of a buffer for encoded event packet.
+ * @param[in,out] p_buf_len \c in: Size (in bytes) of \p p_buf buffer.
+ * \c out: Length of encoded contents in \p p_buf.
+ *
+ * @retval NRF_SUCCESS Encoding success.
+ * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length.
+ */
+uint32_t ble_gatts_evt_exchange_mtu_request_enc(ble_evt_t const * const p_event,
+ uint32_t event_len,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len);
+#if NRF_SD_BLE_API_VERSION >= 4
+
+/**
+ * @brief Encodes @ref BLE_GATTS_EVT_HVN_TX_COMPLETE event.
+ *
+ * @param[in] p_event Pointer to the \ref ble_evt_t buffer that shall be encoded.
+ * @param[in] event_len Size (in bytes) of \p p_event buffer.
+ * @param[out] p_buf Pointer to the beginning of a buffer for encoded event packet.
+ * @param[in,out] p_buf_len \c in: Size (in bytes) of \p p_buf buffer.
+ * \c out: Length of encoded contents in \p p_buf.
+ *
+ * @retval NRF_SUCCESS Encoding success.
+ * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length.
+ */
+uint32_t ble_gatts_evt_hvn_tx_complete_enc(ble_evt_t const * const p_event,
+ uint32_t event_len,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len);
+#endif
+/** @} */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/connectivity/codecs/ble/serializers/ble_l2cap_conn.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/connectivity/codecs/ble/serializers/ble_l2cap_conn.c
new file mode 100644
index 0000000..0a6a910
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/connectivity/codecs/ble/serializers/ble_l2cap_conn.c
@@ -0,0 +1,323 @@
+/**
+ * Copyright (c) 2014 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#include <stdlib.h>
+#include <string.h>
+#include "ble_l2cap_conn.h"
+#include "ble_serialization.h"
+#include "ble_struct_serialization.h"
+#include "ble_l2cap_struct_serialization.h"
+#include "cond_field_serialization.h"
+#include "conn_ble_l2cap_sdu_pool.h"
+#include "app_util.h"
+
+
+#if defined(NRF_SD_BLE_API_VERSION) && NRF_SD_BLE_API_VERSION < 4
+uint32_t ble_l2cap_cid_register_req_dec(uint8_t const * const p_buf,
+ uint32_t buf_len,
+ uint16_t * p_cid)
+{
+ uint32_t index = 0;
+ uint32_t err_code = NRF_SUCCESS;
+
+ SER_ASSERT_NOT_NULL(p_cid);
+ SER_ASSERT_NOT_NULL(p_buf);
+ SER_ASSERT_LENGTH_EQ(3, buf_len);
+ SER_ASSERT(p_buf[index] == SD_BLE_L2CAP_CID_REGISTER, NRF_ERROR_INVALID_PARAM);
+
+ index++;
+ err_code = uint16_t_dec(p_buf, buf_len, &index, p_cid);
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code);
+
+ SER_ASSERT_LENGTH_EQ(index, buf_len);
+
+ return err_code;
+}
+
+
+uint32_t ble_l2cap_cid_register_rsp_enc(uint32_t return_code,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len)
+{
+ return ser_ble_cmd_rsp_status_code_enc(SD_BLE_L2CAP_CID_REGISTER, return_code,
+ p_buf, p_buf_len);
+}
+
+uint32_t ble_l2cap_cid_unregister_req_dec(uint8_t const * const p_buf,
+ uint32_t buf_len,
+ uint16_t * p_cid)
+{
+ uint32_t index = 0;
+ uint32_t err_code = NRF_SUCCESS;
+
+ SER_ASSERT_NOT_NULL(p_cid);
+ SER_ASSERT_NOT_NULL(p_buf);
+ SER_ASSERT_LENGTH_EQ(3, buf_len);
+ SER_ASSERT(p_buf[index] == SD_BLE_L2CAP_CID_UNREGISTER, NRF_ERROR_INVALID_PARAM);
+
+ index++;
+ err_code = uint16_t_dec(p_buf, buf_len, &index, p_cid);
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code);
+
+ SER_ASSERT_LENGTH_EQ(index, buf_len);
+
+ return err_code;
+}
+
+
+uint32_t ble_l2cap_cid_unregister_rsp_enc(uint32_t return_code,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len)
+{
+ return ser_ble_cmd_rsp_status_code_enc(SD_BLE_L2CAP_CID_UNREGISTER, return_code,
+ p_buf, p_buf_len);
+}
+
+
+uint32_t ble_l2cap_tx_req_dec(uint8_t const * const p_buf,
+ uint32_t const buf_len,
+ uint16_t * p_conn_handle,
+ ble_l2cap_header_t * * const pp_l2cap_header,
+ uint8_t const * * pp_data)
+{
+ SER_ASSERT_NOT_NULL(p_buf);
+ SER_ASSERT_NOT_NULL(p_conn_handle);
+ SER_ASSERT_NOT_NULL(pp_l2cap_header);
+ SER_ASSERT_NOT_NULL(*pp_l2cap_header);
+ SER_ASSERT_NOT_NULL(pp_data);
+ //SER_ASSERT_NOT_NULL(*pp_data);
+
+ uint32_t err_code = NRF_SUCCESS;
+ uint32_t index = SER_CMD_DATA_POS;
+
+ err_code = uint16_t_dec(p_buf, buf_len, &index, p_conn_handle);
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code);
+
+ err_code = cond_field_dec(p_buf, buf_len, &index, (void * *)pp_l2cap_header,
+ ble_l2cap_header_t_dec);
+
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code);
+
+ if (*pp_l2cap_header != NULL)
+ {
+ *pp_data = p_buf + index + 1;
+ index += 1 + (*pp_l2cap_header)->len;
+ }
+ else
+ {
+ *pp_data = NULL;
+ index++;
+ }
+
+ SER_ASSERT_LENGTH_EQ(index, buf_len);
+
+ return err_code;
+}
+
+uint32_t ble_l2cap_tx_rsp_enc(uint32_t return_code,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len)
+{
+ return ser_ble_cmd_rsp_status_code_enc(SD_BLE_L2CAP_TX, return_code,
+ p_buf, p_buf_len);
+}
+#endif
+
+#if NRF_SD_BLE_API_VERSION >= 5
+uint32_t ble_l2cap_ch_setup_req_dec(uint8_t const * const p_buf,
+ uint16_t packet_len,
+ uint16_t * p_conn_handle,
+ uint16_t * * pp_local_cid,
+ ble_l2cap_ch_setup_params_t * * const pp_params)
+{
+ SER_REQ_DEC_BEGIN(SD_BLE_L2CAP_CH_SETUP);
+ SER_PULL_uint16(p_conn_handle);
+ SER_PULL_COND(pp_local_cid, uint16_t_dec);
+ SER_PULL_COND(pp_params, ble_l2cap_ch_setup_params_t_dec);
+
+ if (*pp_params && (*pp_params)->rx_params.sdu_buf.p_data)
+ {
+ SER_ASSERT_LENGTH_LEQ((*pp_params)->rx_params.sdu_buf.len, CONN_BLE_L2CAP_SDU_MAX_BUFFER_SIZE);
+ uint8_t * p_data = conn_ble_l2cap_sdu_pool_alloc((*pp_params)->rx_params.sdu_buf.len,
+ (uint32_t)((*pp_params)->rx_params.sdu_buf.p_data));
+ (*pp_params)->rx_params.sdu_buf.p_data = p_data;
+ }
+ SER_REQ_DEC_END;
+}
+
+uint32_t ble_l2cap_ch_setup_rsp_enc(uint32_t return_code,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len,
+ uint16_t * p_local_cid)
+{
+ SER_RSP_ENC_BEGIN(SD_BLE_L2CAP_CH_SETUP);
+
+ SER_PUSH_COND(p_local_cid, uint16_t_enc);
+ SER_RSP_ENC_END;
+}
+
+uint32_t ble_l2cap_ch_release_req_dec(uint8_t const * const p_buf,
+ uint16_t packet_len,
+ uint16_t * p_conn_handle,
+ uint16_t * p_local_cid)
+{
+ SER_REQ_DEC_BEGIN(SD_BLE_L2CAP_CH_RELEASE);
+ SER_PULL_uint16(p_conn_handle);
+ SER_PULL_uint16(p_local_cid);
+ SER_REQ_DEC_END;
+}
+
+
+uint32_t ble_l2cap_ch_release_rsp_enc(uint32_t return_code,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len)
+{
+ SER_RSP_ENC_RESULT_ONLY(SD_BLE_L2CAP_CH_RELEASE);
+}
+
+uint32_t ble_l2cap_ch_rx_req_dec(uint8_t const * const p_buf,
+ uint16_t packet_len,
+ uint16_t * p_conn_handle,
+ uint16_t * p_local_cid,
+ ble_data_t * * pp_sdu_buf)
+{
+ SER_REQ_DEC_BEGIN(SD_BLE_L2CAP_CH_RX);
+ SER_PULL_uint16(p_conn_handle);
+ SER_PULL_uint16(p_local_cid);
+
+ uint8_t * p_tmp = (uint8_t *)1;
+ SER_PULL_COND(&p_tmp, NULL);
+ if (p_tmp)
+ {
+ SER_PULL_uint16((uint16_t*)&(*pp_sdu_buf)->len);
+ uint32_t addr;
+ SER_PULL_uint32(&addr);
+ SER_ASSERT_LENGTH_LEQ((*pp_sdu_buf)->len, CONN_BLE_L2CAP_SDU_MAX_BUFFER_SIZE);
+ uint8_t * p_data = conn_ble_l2cap_sdu_pool_alloc((*pp_sdu_buf)->len, addr);
+ (*pp_sdu_buf)->p_data = p_data;
+ }
+ else
+ {
+ *pp_sdu_buf = NULL;
+ }
+
+ SER_REQ_DEC_END;
+}
+
+
+uint32_t ble_l2cap_ch_rx_rsp_enc(uint32_t return_code,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len)
+{
+ SER_RSP_ENC_RESULT_ONLY(SD_BLE_L2CAP_CH_RX);
+}
+
+uint32_t ble_l2cap_ch_tx_req_dec(uint8_t const * const p_buf,
+ uint16_t packet_len,
+ uint16_t * p_conn_handle,
+ uint16_t * p_local_cid,
+ ble_data_t * * const pp_sdu_buf)
+{
+ SER_REQ_DEC_BEGIN(SD_BLE_L2CAP_CH_TX);
+ SER_PULL_uint16(p_conn_handle);
+ SER_PULL_uint16(p_local_cid);
+
+ uint8_t * p_tmp = (uint8_t *)1;
+ SER_PULL_COND(&p_tmp, NULL);
+
+ if (p_tmp)
+ {
+ uint32_t id;
+ uint16_t len;
+ SER_PULL_uint32(&id);
+ SER_PULL_uint16(&len);
+
+ SER_ASSERT_LENGTH_LEQ(len, CONN_BLE_L2CAP_SDU_MAX_BUFFER_SIZE);
+ uint8_t * p_data = conn_ble_l2cap_sdu_pool_alloc(len, id);
+ if (p_data)
+ {
+ SER_PULL_buf(&p_data, len, len);
+ }
+ (*pp_sdu_buf)->p_data = p_data;
+ (*pp_sdu_buf)->len = len;
+
+ }
+ else
+ {
+ *pp_sdu_buf = NULL;
+ }
+
+ SER_REQ_DEC_END;
+}
+
+
+uint32_t ble_l2cap_ch_tx_rsp_enc(uint32_t return_code,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len)
+{
+ SER_RSP_ENC_RESULT_ONLY(SD_BLE_L2CAP_CH_TX);
+}
+
+uint32_t ble_l2cap_ch_flow_control_req_dec(uint8_t const * const p_buf,
+ uint16_t packet_len,
+ uint16_t * p_conn_handle,
+ uint16_t * p_local_cid,
+ uint16_t * p_credits,
+ uint16_t * * pp_credits)
+{
+ SER_REQ_DEC_BEGIN(SD_BLE_L2CAP_CH_FLOW_CONTROL);
+ SER_PULL_uint16(p_conn_handle);
+ SER_PULL_uint16(p_local_cid);
+ SER_PULL_uint16(p_credits);
+ SER_PULL_COND(pp_credits, NULL);
+ SER_REQ_DEC_END;
+}
+
+
+uint32_t ble_l2cap_ch_flow_control_rsp_enc(uint32_t return_code,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len,
+ uint16_t const * const p_credits)
+{
+ SER_RSP_ENC_BEGIN(SD_BLE_L2CAP_CH_FLOW_CONTROL);
+
+ SER_PUSH_COND(p_credits, uint16_t_enc);
+ SER_RSP_ENC_END;
+}
+#endif //NRF_SD_BLE_API_VERSION >= 5
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/connectivity/codecs/ble/serializers/ble_l2cap_conn.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/connectivity/codecs/ble/serializers/ble_l2cap_conn.h
new file mode 100644
index 0000000..b254cae
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/connectivity/codecs/ble/serializers/ble_l2cap_conn.h
@@ -0,0 +1,384 @@
+/**
+ * Copyright (c) 2011 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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
+ *
+ * @defgroup ble_l2cap_conn L2CAP Connectivity command request decoders and command response encoders
+ * @{
+ * @ingroup ser_conn_s130_codecs
+ *
+ * @brief L2CAP Connectivity command request decoders and command response encoders.
+ */
+
+#ifndef BLE_L2CAP_CONN_H__
+#define BLE_L2CAP_CONN_H__
+
+#include "ble.h"
+#include "ble_types.h"
+#include "ble_ranges.h"
+#include "ble_err.h"
+#include "ble_l2cap.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+#if defined(NRF_SD_BLE_API_VERSION) && NRF_SD_BLE_API_VERSION < 4
+/**@brief Decodes @ref sd_ble_l2cap_cid_register command request.
+ *
+ * @sa @ref ble_l2cap_cid_register_rsp_enc for response encoding.
+ *
+ * @param[in] p_buf Pointer to beginning of command request packet.
+ * @param[in] buf_len Length (in bytes) of response packet.
+ * @param[in] p_cid Pointer to L2CAP CID.
+ *
+ * @retval NRF_SUCCESS Decoding success.
+ * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length.
+ * @retval NRF_ERROR_INVALID_PARAM Decoding failure. Invalid operation type.
+ */
+uint32_t ble_l2cap_cid_register_req_dec(uint8_t const * const p_buf,
+ uint32_t buf_len,
+ uint16_t * p_cid);
+
+/**@brief Encodes @ref sd_ble_l2cap_cid_register command response.
+ *
+ * @sa @ref ble_l2cap_cid_register_req_dec for request decoding.
+ *
+ * @param[in] return_code Return code indicating if command was successful or not.
+ * @param[out] p_buf Pointer to buffer where encoded data command response will be
+ * returned.
+ * @param[in,out] p_buf_len \c in: size of \p p_buf buffer.
+ * \c out: Length of encoded command response packet.
+ *
+ * @retval NRF_SUCCESS Encoding success.
+ * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length.
+ */
+uint32_t ble_l2cap_cid_register_rsp_enc(uint32_t return_code,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len);
+
+/**@brief Decodes @ref sd_ble_l2cap_cid_unregister command request.
+ *
+ * @sa @ref ble_l2cap_cid_unregister_rsp_enc for response encoding.
+ *
+ * @param[in] p_buf Pointer to beginning of command request packet.
+ * @param[in] buf_len Length (in bytes) of response packet.
+ * @param[in] p_cid Pointer to L2CAP CID.
+ *
+ * @retval NRF_SUCCESS Decoding success.
+ * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length.
+ * @retval NRF_ERROR_INVALID_PARAM Decoding failure. Invalid operation type.
+ */
+uint32_t ble_l2cap_cid_unregister_req_dec(uint8_t const * const p_buf,
+ uint32_t buf_len,
+ uint16_t * p_cid);
+
+/**@brief Encodes @ref sd_ble_l2cap_cid_unregister command response.
+ *
+ * @sa @ref ble_l2cap_cid_unregister_req_dec for request decoding.
+ *
+ * @param[in] return_code Return code indicating if command was successful or not.
+ * @param[out] p_buf Pointer to buffer where encoded data command response will be
+ * returned.
+ * @param[in,out] p_buf_len \c in: size of \p p_buf buffer.
+ * \c out: Length of encoded command response packet.
+ *
+ * @retval NRF_SUCCESS Encoding success.
+ * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length.
+ */
+uint32_t ble_l2cap_cid_unregister_rsp_enc(uint32_t return_code,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len);
+
+/**@brief Decodes @ref sd_ble_l2cap_tx command request.
+ *
+ * @sa @ref ble_l2cap_tx_rsp_enc for response encoding.
+ *
+ * @param[in] p_buf Pointer to beginning of command request packet.
+ * @param[in] buf_len Length (in bytes) of response packet.
+ * @param[in] p_conn_handle Pointer to connection handle.
+ * @param[in] pp_l2cap_header Pointer to pointer to L2CAP header.
+ * @param[in] pp_data Pointer to pointer L2CAP data.
+ *
+ * @retval NRF_SUCCESS Decoding success.
+ * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length.
+ * @retval NRF_ERROR_INVALID_PARAM Decoding failure. Invalid operation type.
+ */
+uint32_t ble_l2cap_tx_req_dec(uint8_t const * const p_buf,
+ uint32_t const buf_len,
+ uint16_t * p_conn_handle,
+ ble_l2cap_header_t * * const pp_l2cap_header,
+ uint8_t const * * pp_data);
+
+/**@brief Encodes @ref sd_ble_l2cap_tx command response.
+ *
+ * @sa @ref ble_l2cap_tx_req_dec for request decoding.
+ *
+ * @param[in] return_code Return code indicating if command was successful or not.
+ * @param[out] p_buf Pointer to buffer where encoded data command response will be
+ * returned.
+ * @param[in,out] p_buf_len \c in: size of \p p_buf buffer.
+ * \c out: Length of encoded command response packet.
+ *
+ * @retval NRF_SUCCESS Encoding success.
+ * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length.
+ */
+uint32_t ble_l2cap_tx_rsp_enc(uint32_t return_code,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len);
+
+#endif
+
+#if defined(NRF_SD_BLE_API_VERSION) && NRF_SD_BLE_API_VERSION >= 5
+
+/**@brief Decodes @ref sd_ble_l2cap_ch_setup command request.
+ *
+ * @sa @ref ble_l2cap_ch_setup_rsp_enc for response encoding.
+ *
+ * @param[in] p_buf Pointer to beginning of command request packet.
+ * @param[in] buf_len Length (in bytes) of response packet.
+ * @param[in] p_conn_handle Pointer to connection handle.
+ * @param[in, out] pp_local_cid Pointer to pointer to local cid.
+ * @param[in, out] pp_params Pointer to pointer to params.
+ *
+ * @retval NRF_SUCCESS Decoding success.
+ * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length.
+ * @retval NRF_ERROR_INVALID_PARAM Decoding failure. Invalid operation type.
+ */
+uint32_t ble_l2cap_ch_setup_req_dec(uint8_t const * const p_buf,
+ uint16_t packet_len,
+ uint16_t * p_conn_handle,
+ uint16_t * * pp_local_cid,
+ ble_l2cap_ch_setup_params_t * * const pp_params);
+
+/**@brief Encodes @ref sd_ble_l2cap_ch_setup command response.
+ *
+ * @sa @ref ble_l2cap_ch_setup_req_dec for request decoding.
+ *
+ * @param[in] return_code Return code indicating if command was successful or not.
+ * @param[out] p_buf Pointer to buffer where encoded data command response will be
+ * returned.
+ * @param[in,out] p_buf_len \c in: size of \p p_buf buffer.
+ * \c out: Length of encoded command response packet.
+ * @param[p_local_cid Pointer to local cid.
+ *
+ * @retval NRF_SUCCESS Encoding success.
+ * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length.
+ */
+uint32_t ble_l2cap_ch_setup_rsp_enc(uint32_t return_code,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len,
+ uint16_t * p_local_cid);
+
+/**@brief Decodes @ref sd_ble_l2cap_ch_release command request.
+ *
+ * @sa @ref ble_l2cap_ch_release_rsp_enc for response encoding.
+ *
+ * @param[in] p_buf Pointer to beginning of command request packet.
+ * @param[in] buf_len Length (in bytes) of response packet.
+ * @param[in] p_conn_handle Pointer to connection handle.
+ * @param[in] p_local_cid Pointer to local cid.
+ * @param[in] pp_data Pointer to pointer L2CAP data.
+ *
+ * @retval NRF_SUCCESS Decoding success.
+ * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length.
+ * @retval NRF_ERROR_INVALID_PARAM Decoding failure. Invalid operation type.
+ */
+uint32_t ble_l2cap_ch_release_req_dec(uint8_t const * const p_buf,
+ uint16_t packet_len,
+ uint16_t * p_conn_handle,
+ uint16_t * p_local_cid);
+
+/**@brief Encodes @ref sd_ble_l2cap_ch_releasecommand response.
+ *
+ * @sa @ref ble_l2cap_ch_release_req_dec for request decoding.
+ *
+ * @param[in] return_code Return code indicating if command was successful or not.
+ * @param[out] p_buf Pointer to buffer where encoded data command response will be
+ * returned.
+ * @param[in,out] p_buf_len \c in: size of \p p_buf buffer.
+ * \c out: Length of encoded command response packet.
+ *
+ * @retval NRF_SUCCESS Encoding success.
+ * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length.
+ */
+uint32_t ble_l2cap_ch_release_rsp_enc(uint32_t return_code,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len);
+
+/**@brief Decodes @ref sd_ble_l2cap_ch_rx command request.
+ *
+ * @sa @ref ble_l2cap_ch_rx_rsp_enc for response encoding.
+ *
+ * @param[in] p_buf Pointer to beginning of command request packet.
+ * @param[in] buf_len Length (in bytes) of response packet.
+ * @param[in] p_conn_handle Pointer to connection handle.
+ * @param[in] p_local_cid Pointer to local cid.
+ * @param[in] pp_sdu_buf Pointer to pointer to SDU buf.
+ *
+ * @retval NRF_SUCCESS Decoding success.
+ * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length.
+ * @retval NRF_ERROR_INVALID_PARAM Decoding failure. Invalid operation type.
+ */
+uint32_t ble_l2cap_ch_rx_req_dec(uint8_t const * const p_buf,
+ uint16_t packet_len,
+ uint16_t * p_conn_handle,
+ uint16_t * p_local_cid,
+ ble_data_t * * pp_sdu_buf);
+
+/**@brief Encodes @ref sd_ble_l2cap_ch_rx command response.
+ *
+ * @sa @ref ble_l2cap_ch_rx_req_dec for request decoding.
+ *
+ * @param[in] return_code Return code indicating if command was successful or not.
+ * @param[out] p_buf Pointer to buffer where encoded data command response will be
+ * returned.
+ * @param[in,out] p_buf_len \c in: size of \p p_buf buffer.
+ * \c out: Length of encoded command response packet.
+ *
+ * @retval NRF_SUCCESS Encoding success.
+ * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length.
+ */
+uint32_t ble_l2cap_ch_rx_rsp_enc(uint32_t return_code,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len);
+
+/**@brief Decodes @ref sd_ble_l2cap_ch_tx command request.
+ *
+ * @sa @ref ble_l2cap_ch_tx_rsp_enc for response encoding.
+ *
+ * @param[in] p_buf Pointer to beginning of command request packet.
+ * @param[in] buf_len Length (in bytes) of response packet.
+ * @param[in] p_conn_handle Pointer to connection handle.
+ * @param[in] p_local_cid Pointer to local cid.
+ * @param[in] pp_sdu_buf Pointer to pointer to SDU buf.
+ *
+ * @retval NRF_SUCCESS Decoding success.
+ * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length.
+ * @retval NRF_ERROR_INVALID_PARAM Decoding failure. Invalid operation type.
+ */
+uint32_t ble_l2cap_ch_tx_req_dec(uint8_t const * const p_buf,
+ uint16_t packet_len,
+ uint16_t * p_conn_handle,
+ uint16_t * p_local_cid,
+ ble_data_t * * const pp_sdu_buf);
+
+
+/**@brief Encodes @ref sd_ble_l2cap_ch_tx command response.
+ *
+ * @sa @ref ble_l2cap_ch_tx_req_dec for request decoding.
+ *
+ * @param[in] return_code Return code indicating if command was successful or not.
+ * @param[out] p_buf Pointer to buffer where encoded data command response will be
+ * returned.
+ * @param[in,out] p_buf_len \c in: size of \p p_buf buffer.
+ * \c out: Length of encoded command response packet.
+ *
+ * @retval NRF_SUCCESS Encoding success.
+ * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length.
+ */
+uint32_t ble_l2cap_ch_tx_rsp_enc(uint32_t return_code,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len);
+
+/**@brief Decodes @ref sd_ble_l2cap_ch_flow_control command request.
+ *
+ * @sa @ref ble_l2cap_ch_flow_control_rsp_enc for response encoding.
+ *
+ * @param[in] p_buf Pointer to beginning of command request packet.
+ * @param[in] buf_len Length (in bytes) of response packet.
+ * @param[in] p_conn_handle Pointer to connection handle.
+ * @param[in] p_local_cid Pointer to local cid.
+ * @param[in] p_credits Pointer to credits.
+ * @param[in,out] pp_credits Pointer to pointer to credits.
+ *
+ * @retval NRF_SUCCESS Decoding success.
+ * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length.
+ * @retval NRF_ERROR_INVALID_PARAM Decoding failure. Invalid operation type.
+ */
+uint32_t ble_l2cap_ch_flow_control_req_dec(uint8_t const * const p_buf,
+ uint16_t packet_len,
+ uint16_t * p_conn_handle,
+ uint16_t * p_local_cid,
+ uint16_t * p_credits,
+ uint16_t * * pp_credits);
+
+/**@brief Encodes @ref sd_ble_l2cap_ch_flow_control command response.
+ *
+ * @sa @ref ble_l2cap_ch_flow_control_req_dec for request decoding.
+ *
+ * @param[in] return_code Return code indicating if command was successful or not.
+ * @param[out] p_buf Pointer to buffer where encoded data command response will be
+ * returned.
+ * @param[in,out] p_buf_len \c in: size of \p p_buf buffer.
+ * \c out: Length of encoded command response packet.
+ * @param[in] p_credits Pointer to credits.
+ *
+ * @retval NRF_SUCCESS Encoding success.
+ * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length.
+ */
+uint32_t ble_l2cap_ch_flow_control_rsp_enc(uint32_t return_code,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len,
+ uint16_t const * const p_credits);
+#endif
+#ifdef __cplusplus
+}
+#endif
+
+#endif //BLE_L2CAP_CONN_H__
+
+/**
+ @}
+ */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/connectivity/codecs/ble/serializers/ble_l2cap_evt_conn.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/connectivity/codecs/ble/serializers/ble_l2cap_evt_conn.c
new file mode 100644
index 0000000..c4078f5
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/connectivity/codecs/ble/serializers/ble_l2cap_evt_conn.c
@@ -0,0 +1,199 @@
+/**
+ * Copyright (c) 2014 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#include "ble_l2cap_evt_conn.h"
+#include <string.h>
+#include "ble_serialization.h"
+#include "ble_struct_serialization.h"
+#include "ble_l2cap_struct_serialization.h"
+#include "app_util.h"
+#include "conn_ble_l2cap_sdu_pool.h"
+
+#if defined(NRF_SD_BLE_API_VERSION) && NRF_SD_BLE_API_VERSION < 4
+uint32_t ble_l2cap_evt_rx_enc(ble_evt_t const * const p_event,
+ uint32_t event_len,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len)
+{
+ SER_EVT_ENC_BEGIN(BLE_L2CAP_EVT_RX);
+
+ SER_PUSH_uint16(&p_event->evt.l2cap_evt.conn_handle);
+ SER_PUSH_FIELD(&p_event->evt.l2cap_evt.params.rx, ble_l2cap_evt_rx_t_enc);
+
+ SER_EVT_ENC_END;
+}
+#endif
+
+#if defined(NRF_SD_BLE_API_VERSION) && NRF_SD_BLE_API_VERSION >= 5
+uint32_t ble_l2cap_evt_ch_setup_request_enc(ble_evt_t const * const p_event,
+ uint32_t event_len,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len)
+{
+ SER_EVT_ENC_BEGIN(BLE_L2CAP_EVT_CH_SETUP_REQUEST);
+
+ SER_PUSH_uint16(&p_event->evt.l2cap_evt.conn_handle);
+ SER_PUSH_uint16(&p_event->evt.l2cap_evt.local_cid);
+ SER_PUSH_uint16(&p_event->evt.l2cap_evt.params.ch_setup_request.le_psm);
+ SER_PUSH_FIELD(&p_event->evt.l2cap_evt.params.ch_setup_request.tx_params, ble_l2cap_ch_tx_params_t_enc);
+
+ SER_EVT_ENC_END;
+}
+
+uint32_t ble_l2cap_evt_ch_setup_refused_enc(ble_evt_t const * const p_event,
+ uint32_t event_len,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len)
+{
+ SER_EVT_ENC_BEGIN(BLE_L2CAP_EVT_CH_SETUP_REFUSED);
+
+ SER_PUSH_uint16(&p_event->evt.l2cap_evt.conn_handle);
+ SER_PUSH_uint16(&p_event->evt.l2cap_evt.local_cid);
+ SER_PUSH_uint8(&p_event->evt.l2cap_evt.params.ch_setup_refused.source);
+ SER_PUSH_uint16(&p_event->evt.l2cap_evt.params.ch_setup_refused.status);
+
+ SER_EVT_ENC_END;
+}
+
+uint32_t ble_l2cap_evt_ch_setup_enc(ble_evt_t const * const p_event,
+ uint32_t event_len,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len)
+{
+ SER_EVT_ENC_BEGIN(BLE_L2CAP_EVT_CH_SETUP);
+
+ SER_PUSH_uint16(&p_event->evt.l2cap_evt.conn_handle);
+ SER_PUSH_uint16(&p_event->evt.l2cap_evt.local_cid);
+ SER_PUSH_FIELD(&p_event->evt.l2cap_evt.params.ch_setup.tx_params, ble_l2cap_ch_tx_params_t_enc);
+
+ SER_EVT_ENC_END;
+}
+
+uint32_t ble_l2cap_evt_ch_released_enc(ble_evt_t const * const p_event,
+ uint32_t event_len,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len)
+{
+ SER_EVT_ENC_BEGIN(BLE_L2CAP_EVT_CH_RELEASED);
+
+ SER_PUSH_uint16(&p_event->evt.l2cap_evt.conn_handle);
+ SER_PUSH_uint16(&p_event->evt.l2cap_evt.local_cid);
+
+ SER_EVT_ENC_END;
+}
+
+uint32_t ble_l2cap_evt_ch_sdu_buf_released_enc(ble_evt_t const * const p_event,
+ uint32_t event_len,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len)
+{
+ SER_EVT_ENC_BEGIN(BLE_L2CAP_EVT_CH_SDU_BUF_RELEASED);
+
+ SER_PUSH_uint16(&p_event->evt.l2cap_evt.conn_handle);
+ SER_PUSH_uint16(&p_event->evt.l2cap_evt.local_cid);
+ SER_PUSH_uint16(&p_event->evt.l2cap_evt.params.ch_sdu_buf_released.sdu_buf.len);
+
+ uint32_t * p_data = (uint32_t *)p_event->evt.l2cap_evt.params.ch_sdu_buf_released.sdu_buf.p_data;
+ if (p_data)
+ {
+ uint32_t id = *(p_data - 1);
+ conn_ble_l2cap_sdu_pool_free(p_data);
+ SER_PUSH_uint32(&id);
+ }
+
+ SER_EVT_ENC_END;
+}
+
+uint32_t ble_l2cap_evt_ch_credit_enc(ble_evt_t const * const p_event,
+ uint32_t event_len,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len)
+{
+ SER_EVT_ENC_BEGIN(BLE_L2CAP_EVT_CH_CREDIT);
+
+ SER_PUSH_uint16(&p_event->evt.l2cap_evt.conn_handle);
+ SER_PUSH_uint16(&p_event->evt.l2cap_evt.local_cid);
+ SER_PUSH_uint16(&p_event->evt.l2cap_evt.params.credit.credits);
+
+ SER_EVT_ENC_END;
+}
+
+uint32_t ble_l2cap_evt_ch_rx_enc(ble_evt_t const * const p_event,
+ uint32_t event_len,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len)
+{
+ SER_EVT_ENC_BEGIN(BLE_L2CAP_EVT_CH_RX);
+
+ SER_PUSH_uint16(&p_event->evt.l2cap_evt.conn_handle);
+ SER_PUSH_uint16(&p_event->evt.l2cap_evt.local_cid);
+ SER_PUSH_uint16(&p_event->evt.l2cap_evt.params.rx.sdu_len);
+ SER_PUSH_uint16(&p_event->evt.l2cap_evt.params.rx.sdu_buf.len);
+
+ uint32_t * p_data = (uint32_t *)p_event->evt.l2cap_evt.params.rx.sdu_buf.p_data;
+ uint32_t id = *(p_data - 1);
+ SER_PUSH_uint32(&id);
+ SER_PUSH_buf(p_event->evt.l2cap_evt.params.rx.sdu_buf.p_data, p_event->evt.l2cap_evt.params.rx.sdu_buf.len);
+ conn_ble_l2cap_sdu_pool_free(p_data);
+
+ SER_EVT_ENC_END;
+}
+
+uint32_t ble_l2cap_evt_ch_tx_enc(ble_evt_t const * const p_event,
+ uint32_t event_len,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len)
+{
+ SER_EVT_ENC_BEGIN(BLE_L2CAP_EVT_CH_TX);
+
+ SER_PUSH_uint16(&p_event->evt.l2cap_evt.conn_handle);
+ SER_PUSH_uint16(&p_event->evt.l2cap_evt.local_cid);
+ SER_PUSH_uint16(&p_event->evt.l2cap_evt.params.tx.sdu_buf.len);
+
+ uint32_t * p_data = (uint32_t *)p_event->evt.l2cap_evt.params.tx.sdu_buf.p_data;
+ if (p_data)
+ {
+ uint32_t id = *(p_data - 1);
+ conn_ble_l2cap_sdu_pool_free(p_data);
+ SER_PUSH_uint32(&id);
+ }
+
+ SER_EVT_ENC_END;
+}
+#endif
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/connectivity/codecs/ble/serializers/ble_l2cap_evt_conn.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/connectivity/codecs/ble/serializers/ble_l2cap_evt_conn.h
new file mode 100644
index 0000000..65709ee
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/connectivity/codecs/ble/serializers/ble_l2cap_evt_conn.h
@@ -0,0 +1,121 @@
+/**
+ * Copyright (c) 2014 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#ifndef BLE_L2CAP_EVT_CONN_H__
+#define BLE_L2CAP_EVT_CONN_H__
+
+/**@file
+ *
+ * @defgroup ble_l2cap_evt_conn L2CAP Connectivity event encoders
+ * @{
+ * @ingroup ser_conn_s130_codecs
+ *
+ * @brief L2CAP Connectivity event encoders.
+ */
+#include "ble.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @brief Encodes ble_l2cap_evt_rx event.
+ *
+ * @param[in] p_event Pointer to the \ref ble_evt_t buffer that shall be encoded.
+ * @param[in] event_len Size (in bytes) of \p p_event buffer.
+ * @param[out] p_buf Pointer to the beginning of a buffer for encoded event packet.
+ * @param[in,out] p_buf_len \c in: Size (in bytes) of \p p_buf buffer.
+ * \c out: Length of encoded contents in \p p_buf.
+ *
+ * @retval NRF_SUCCESS Encoding success.
+ * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length.
+ */
+uint32_t ble_l2cap_evt_rx_enc(ble_evt_t const * const p_event,
+ uint32_t event_len,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len);
+
+uint32_t ble_l2cap_evt_ch_setup_request_enc(ble_evt_t const * const p_event,
+ uint32_t event_len,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len);
+
+uint32_t ble_l2cap_evt_ch_setup_refused_enc(ble_evt_t const * const p_event,
+ uint32_t event_len,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len);
+
+uint32_t ble_l2cap_evt_ch_setup_enc(ble_evt_t const * const p_event,
+ uint32_t event_len,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len);
+
+
+uint32_t ble_l2cap_evt_ch_released_enc(ble_evt_t const * const p_event,
+ uint32_t event_len,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len);
+
+uint32_t ble_l2cap_evt_ch_sdu_buf_released_enc(ble_evt_t const * const p_event,
+ uint32_t event_len,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len);
+
+uint32_t ble_l2cap_evt_ch_credit_enc(ble_evt_t const * const p_event,
+ uint32_t event_len,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len);
+
+uint32_t ble_l2cap_evt_ch_rx_enc(ble_evt_t const * const p_event,
+ uint32_t event_len,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len);
+
+uint32_t ble_l2cap_evt_ch_tx_enc(ble_evt_t const * const p_event,
+ uint32_t event_len,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len);
+/** @} */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/connectivity/codecs/ble/serializers/conn_ble_gap_sec_keys.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/connectivity/codecs/ble/serializers/conn_ble_gap_sec_keys.c
new file mode 100644
index 0000000..1013d5e
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/connectivity/codecs/ble/serializers/conn_ble_gap_sec_keys.c
@@ -0,0 +1,155 @@
+/**
+ * Copyright (c) 2014 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#include "conn_ble_gap_sec_keys.h"
+#include "ser_config.h"
+#include "nrf_error.h"
+#include "nordic_common.h"
+#include <stddef.h>
+
+ser_ble_gap_conn_keyset_t m_conn_keys_table[SER_MAX_CONNECTIONS];
+#if NRF_SD_BLE_API_VERSION >= 6
+
+typedef struct
+{
+ uint32_t id;
+ uint8_t ble_data[SER_MAX_ADV_DATA];
+} ble_data_item_t;
+
+ble_data_item_t m_ble_data_pool[8];
+
+#endif
+uint32_t conn_ble_gap_sec_context_create(uint32_t *p_index)
+{
+ uint32_t err_code = NRF_ERROR_NO_MEM;
+ uint32_t i;
+
+ for (i=0; i<SER_MAX_CONNECTIONS; i++ )
+ {
+ if ( ! m_conn_keys_table[i].conn_active )
+ {
+ m_conn_keys_table[i].conn_active = 1;
+ *p_index = i;
+ err_code = NRF_SUCCESS;
+ break;
+ }
+ }
+
+ return err_code;
+}
+
+uint32_t conn_ble_gap_sec_context_destroy(uint16_t conn_handle)
+{
+ uint32_t err_code = NRF_ERROR_NOT_FOUND;
+ uint32_t i;
+
+ for (i=0; i<SER_MAX_CONNECTIONS; i++ )
+ {
+ if ( m_conn_keys_table[i].conn_handle == conn_handle )
+ {
+ m_conn_keys_table[i].conn_active = 0;
+ err_code = NRF_SUCCESS;
+ break;
+ }
+ }
+
+ return err_code;
+}
+
+uint32_t conn_ble_gap_sec_context_find(uint16_t conn_handle, uint32_t *p_index)
+{
+ uint32_t err_code = NRF_ERROR_NOT_FOUND;
+ uint32_t i;
+
+ for (i=0; i<SER_MAX_CONNECTIONS; i++ )
+ {
+ if ( (m_conn_keys_table[i].conn_handle == conn_handle) && (m_conn_keys_table[i].conn_active == 1) )
+ {
+ *p_index = i;
+ err_code = NRF_SUCCESS;
+ break;
+ }
+ }
+
+ return err_code;
+}
+
+#if NRF_SD_BLE_API_VERSION >= 6
+uint8_t * conn_ble_gap_ble_data_buf_alloc(uint32_t id)
+{
+ uint32_t i;
+
+ /* First find if given id already allocated the buffer. */
+ for (i = 0; i < ARRAY_SIZE(m_ble_data_pool); i++)
+ {
+ if (m_ble_data_pool[i].id == id)
+ {
+ return m_ble_data_pool[i].ble_data;
+ }
+ }
+
+ for (i = 0; i < ARRAY_SIZE(m_ble_data_pool); i++)
+ {
+ if (m_ble_data_pool[i].id == 0)
+ {
+ m_ble_data_pool[i].id = id;
+ return m_ble_data_pool[i].ble_data;
+ }
+ }
+
+ return NULL;
+}
+
+
+void conn_ble_gap_ble_data_buf_free(uint8_t * p_data)
+{
+ uint32_t i;
+
+ /* First find if given id already allocated the buffer. */
+ for (i = 0; i < ARRAY_SIZE(m_ble_data_pool); i++)
+ {
+ if (m_ble_data_pool[i].ble_data == p_data)
+ {
+ m_ble_data_pool[i].id = 0;
+ return;
+ }
+ }
+}
+#endif
+
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/connectivity/codecs/ble/serializers/conn_ble_gap_sec_keys.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/connectivity/codecs/ble/serializers/conn_ble_gap_sec_keys.h
new file mode 100644
index 0000000..9212457
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/connectivity/codecs/ble/serializers/conn_ble_gap_sec_keys.h
@@ -0,0 +1,128 @@
+/**
+ * Copyright (c) 2014 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#ifndef _CONN_BLE_GAP_SEC_KEYS_H
+#define _CONN_BLE_GAP_SEC_KEYS_H
+
+/**@file
+ *
+ * @defgroup conn_ble_gap_sec_keys GAP Functions for managing memory for security keys on connectivity device
+ * @{
+ * @ingroup ser_conn_s130_codecs
+ *
+ * @brief GAP Connectivity auxiliary functions for providing static memory required by the SoftDevice. This memory is used to store GAP security keys.
+ */
+
+#include "ble_gap.h"
+#include <stdint.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifndef SER_MAX_CONNECTIONS
+#define SER_MAX_CONNECTIONS 8
+#endif
+
+/**@brief GAP connection - keyset mapping structure.
+ *
+ * @note This structure is used to map keysets to connection instances, and will be stored in a static table.
+ */
+typedef struct
+{
+ uint16_t conn_handle; /**< Connection handle. */
+ uint8_t conn_active; /**< Indication that keys for this connection are used by the SoftDevice. 0: keys used; 1: keys not used. */
+ ble_gap_sec_keyset_t keyset; /**< Keyset structure, see @ref ble_gap_sec_keyset_t. */
+ ble_gap_enc_key_t enc_key_own; /**< Own Encryption Key, see @ref ble_gap_enc_key_t. */
+ ble_gap_id_key_t id_key_own; /**< Own Identity Key, see @ref ble_gap_id_key_t. */
+ ble_gap_sign_info_t sign_key_own; /**< Own Signing Information, see @ref ble_gap_sign_info_t. */
+ ble_gap_lesc_p256_pk_t pk_own; /**< Own Public key, see @ref ble_gap_lesc_p256_pk_t. */
+ ble_gap_enc_key_t enc_key_peer; /**< Peer Encryption Key, see @ref ble_gap_enc_key_t. */
+ ble_gap_id_key_t id_key_peer; /**< Peer Identity Key, see @ref ble_gap_id_key_t. */
+ ble_gap_sign_info_t sign_key_peer; /**< Peer Signing Information, see @ref ble_gap_sign_info_t. */
+ ble_gap_lesc_p256_pk_t pk_peer; /**< Peer Public key, see @ref ble_gap_lesc_p256_pk_t. */
+} ser_ble_gap_conn_keyset_t;
+
+/**@brief Allocates instance in m_conn_keys_table[] for storage of encryption keys.
+ *
+ * @param[out] p_index Pointer to the index of allocated instance.
+ *
+ * @retval NRF_SUCCESS Success.
+ * @retval NRF_ERROR_NO_MEM No free instance available.
+ */
+uint32_t conn_ble_gap_sec_context_create(uint32_t *p_index);
+
+/**@brief Releases the instance identified by a connection handle.
+ *
+ * @param[in] conn_handle conn_handle
+ *
+ * @retval NRF_SUCCESS Context released.
+ * @retval NRF_ERROR_NOT_FOUND Instance with conn_handle not found.
+ */
+uint32_t conn_ble_gap_sec_context_destroy(uint16_t conn_handle);
+
+/**@brief Finds index of the instance identified by a connection handle in m_conn_keys_table[].
+ *
+ * @param[in] conn_handle conn_handle
+ *
+ * @param[out] p_index Pointer to the index of entry in the context table corresponding to the given conn_handle.
+ *
+ * @retval NRF_SUCCESS Context table entry found.
+ * @retval NRF_ERROR_NOT_FOUND Instance with the conn_handle not found.
+ */
+uint32_t conn_ble_gap_sec_context_find(uint16_t conn_handle, uint32_t *p_index);
+/** @} */
+
+/** @brief Function allocates data from the pool.
+ *
+ * @param id ID used for buffer identification. If buffer with given ID is already allocated the pointer to that buffer is returned.
+ * @return Allocated buffer of NULL.
+ */
+uint8_t * conn_ble_gap_ble_data_buf_alloc(uint32_t id);
+
+/** @brief Function for freeing the buffer.
+ * @param p_data Buffer to be freed.
+ */
+void conn_ble_gap_ble_data_buf_free(uint8_t * p_data);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif //_CONN_BLE_GAP_SEC_KEYS_H
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/connectivity/codecs/ble/serializers/conn_ble_l2cap_sdu_pool.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/connectivity/codecs/ble/serializers/conn_ble_l2cap_sdu_pool.c
new file mode 100644
index 0000000..7075577
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/connectivity/codecs/ble/serializers/conn_ble_l2cap_sdu_pool.c
@@ -0,0 +1,84 @@
+/**
+ * Copyright (c) 2014 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+
+#include "conn_ble_l2cap_sdu_pool.h"
+#include "app_util.h"
+#include "nrf_balloc.h"
+
+
+#define MAX_NUM_OF_BUFFERS 8
+
+#define ID_SIZE 4
+
+#define TOTAL_BUF_SIZE (CONN_BLE_L2CAP_SDU_MAX_BUFFER_SIZE+ID_SIZE)
+
+NRF_BALLOC_DEF(m_pool, TOTAL_BUF_SIZE, MAX_NUM_OF_BUFFERS);
+
+void conn_ble_l2cap_sdu_pool_init(void)
+{
+ (void)nrf_balloc_init(&m_pool);
+}
+
+uint8_t * conn_ble_l2cap_sdu_pool_alloc(uint16_t length, uint32_t id)
+{
+ if (length > CONN_BLE_L2CAP_SDU_MAX_BUFFER_SIZE)
+ {
+ return NULL;
+ }
+
+ uint32_t * p_buf = nrf_balloc_alloc(&m_pool);
+ *p_buf = id;
+ p_buf++;
+ return (uint8_t *)p_buf;
+}
+
+uint32_t conn_ble_l2cap_sdu_pool_id_get(void * p_data)
+{
+ uint32_t * p_buf = (uint32_t *)p_data;
+ p_buf--;
+ return *p_buf;
+}
+
+void conn_ble_l2cap_sdu_pool_free(void * p_data)
+{
+ uint32_t * p_buf = (uint32_t *)p_data;
+ p_buf--;
+ nrf_balloc_free(&m_pool, p_buf);
+}
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/connectivity/codecs/ble/serializers/conn_ble_l2cap_sdu_pool.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/connectivity/codecs/ble/serializers/conn_ble_l2cap_sdu_pool.h
new file mode 100644
index 0000000..537d46b
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/connectivity/codecs/ble/serializers/conn_ble_l2cap_sdu_pool.h
@@ -0,0 +1,53 @@
+/**
+ * Copyright (c) 2014 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+
+#ifndef CONN_BLE_L2CAP_SDU_POOL_H
+#define CONN_BLE_L2CAP_SDU_POOL_H
+
+#include <stdint.h>
+
+#define CONN_BLE_L2CAP_SDU_MAX_BUFFER_SIZE 124
+
+void conn_ble_l2cap_sdu_pool_init(void);
+uint8_t * conn_ble_l2cap_sdu_pool_alloc(uint16_t length, uint32_t id);
+uint32_t conn_ble_l2cap_sdu_pool_id_get(void * p_data);
+void conn_ble_l2cap_sdu_pool_free(void * p_data);
+
+#endif //CONN_BLE_L2CAP_SDU_POOL_H
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/connectivity/codecs/ble/serializers/conn_ble_user_mem.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/connectivity/codecs/ble/serializers/conn_ble_user_mem.c
new file mode 100644
index 0000000..96f925b
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/connectivity/codecs/ble/serializers/conn_ble_user_mem.c
@@ -0,0 +1,105 @@
+/**
+ * Copyright (c) 2014 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#include "conn_ble_user_mem.h"
+#include "ser_config.h"
+#include "nrf_error.h"
+#include <stddef.h>
+
+
+
+sercon_ble_user_mem_t m_conn_user_mem_table[SER_MAX_CONNECTIONS];
+
+uint32_t conn_ble_user_mem_context_create(uint32_t *p_index)
+{
+ uint32_t err_code = NRF_ERROR_NO_MEM;
+ uint32_t i;
+
+ for (i=0; i<SER_MAX_CONNECTIONS; i++ )
+ {
+ if ( ! m_conn_user_mem_table[i].conn_active )
+ {
+ m_conn_user_mem_table[i].conn_active = 1;
+ m_conn_user_mem_table[i].mem_block.p_mem = m_conn_user_mem_table[i].mem_table;
+ *p_index = i;
+ err_code = NRF_SUCCESS;
+ break;
+ }
+ }
+
+ return err_code;
+}
+
+uint32_t conn_ble_user_mem_context_destroy(uint16_t conn_handle)
+{
+ uint32_t err_code = NRF_ERROR_NOT_FOUND;
+ uint32_t i;
+
+ for (i=0; i<SER_MAX_CONNECTIONS; i++ )
+ {
+ if ( m_conn_user_mem_table[i].conn_handle == conn_handle )
+ {
+ m_conn_user_mem_table[i].conn_active = 0;
+ m_conn_user_mem_table[i].mem_block.p_mem = NULL;
+ err_code = NRF_SUCCESS;
+ break;
+ }
+ }
+
+ return err_code;
+}
+
+uint32_t conn_ble_user_mem_context_find(uint16_t conn_handle, uint32_t *p_index)
+{
+ uint32_t err_code = NRF_ERROR_NOT_FOUND;
+ uint32_t i;
+
+ for (i=0; i<SER_MAX_CONNECTIONS; i++ )
+ {
+ if ( (m_conn_user_mem_table[i].conn_handle == conn_handle) && (m_conn_user_mem_table[i].conn_active == 1) )
+ {
+ *p_index = i;
+ err_code = NRF_SUCCESS;
+ break;
+ }
+ }
+
+ return err_code;
+}
+
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/connectivity/codecs/ble/serializers/conn_ble_user_mem.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/connectivity/codecs/ble/serializers/conn_ble_user_mem.h
new file mode 100644
index 0000000..3cb0439
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/connectivity/codecs/ble/serializers/conn_ble_user_mem.h
@@ -0,0 +1,108 @@
+/**
+ * Copyright (c) 2014 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#ifndef _CONN_BLE_USER_MEM_H
+#define _CONN_BLE_USER_MEM_H
+
+/**@file
+ *
+ * @defgroup conn_ble_user_mem Functions for managing memory for user memory request on connectivity device.
+ * @{
+ * @ingroup ser_conn_s130_codecs
+ *
+ * @brief Connectivity auxiliary functions for providing static memory required by the SoftDevice.
+ */
+
+#include "ble.h"
+#include "ser_config.h"
+#include <stdint.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**@brief Connection - user memory mapping structure.
+ *
+ * @note This structure is used to map keysets to connection instances, and will be stored in a static table.
+ */
+//lint -esym(452,ser_ble_user_mem_t)
+typedef struct
+{
+ uint16_t conn_handle; /**< Connection handle.*/
+ uint8_t conn_active; /**< Indication that user memory for this connection is used by the SoftDevice. 0: memory used; 1: memory not used. */
+ ble_user_mem_block_t mem_block; /**< User memory block structure, see @ref ble_user_mem_block_t. */
+ uint8_t mem_table[64]; /**< Memory table. */
+} sercon_ble_user_mem_t;
+
+/**@brief Allocates instance in m_user_mem_table[] for storage.
+ *
+ * @param[out] p_index Pointer to the index of allocated instance.
+ *
+ * @retval NRF_SUCCESS Success.
+ * @retval NRF_ERROR_NO_MEM No free instance available.
+ */
+uint32_t conn_ble_user_mem_context_create(uint32_t *p_index);
+
+/**@brief Releases the instance identified by a connection handle.
+ *
+ * @param[in] conn_handle conn_handle
+ *
+ * @retval NRF_SUCCESS Context released.
+ * @retval NRF_ERROR_NOT_FOUND Instance with the conn_handle not found.
+ */
+uint32_t conn_ble_user_mem_context_destroy(uint16_t conn_handle);
+
+/**@brief Finds index of the instance identified by a connection handle in m_user_mem_table[].
+ *
+ * @param[in] conn_handle conn_handle
+ *
+ * @param[out] p_index Pointer to the index of entry in the context table corresponding to the given conn_handle.
+ *
+ * @retval NRF_SUCCESS Context table entry found.
+ * @retval NRF_ERROR_NOT_FOUND Instance with the conn_handle not found.
+ */
+uint32_t conn_ble_user_mem_context_find(uint16_t conn_handle, uint32_t *p_index);
+/** @} */
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif //_CONN_BLE_USER_MEM_H
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/connectivity/codecs/ble/serializers/nrf_soc_conn.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/connectivity/codecs/ble/serializers/nrf_soc_conn.c
new file mode 100644
index 0000000..b000f4b
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/connectivity/codecs/ble/serializers/nrf_soc_conn.c
@@ -0,0 +1,89 @@
+/**
+ * Copyright (c) 2014 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#include "nrf_soc.h"
+#include "nrf_soc_conn.h"
+#include "nrf_error.h"
+#include "ble_serialization.h"
+#include "cond_field_serialization.h"
+#include "nrf_soc_struct_serialization.h"
+
+uint32_t ecb_block_encrypt_req_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ nrf_ecb_hal_data_t * * const pp_ecb_data)
+{
+ SER_REQ_DEC_BEGIN(SD_ECB_BLOCK_ENCRYPT);
+ SER_PULL_COND(pp_ecb_data, nrf_ecb_hal_data_t_in_dec);
+ SER_REQ_DEC_END;
+}
+
+uint32_t ecb_block_encrypt_rsp_enc(uint32_t return_code,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len,
+ nrf_ecb_hal_data_t * const p_ecb_data)
+{
+ SER_RSP_ENC_BEGIN(SD_ECB_BLOCK_ENCRYPT);
+ SER_PUSH_COND(p_ecb_data, nrf_ecb_hal_data_t_out_enc);
+ SER_RSP_ENC_END;
+}
+uint32_t power_system_off_req_dec(uint8_t const * const p_buf,
+ uint16_t packet_len)
+{
+ SER_REQ_DEC_BEGIN(SD_POWER_SYSTEM_OFF);
+ SER_REQ_DEC_END;
+}
+
+uint32_t temp_get_req_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ int32_t * * const pp_temp)
+{
+ SER_REQ_DEC_BEGIN(SD_TEMP_GET);
+ SER_PULL_COND(pp_temp, NULL);
+ SER_REQ_DEC_END;
+}
+
+uint32_t temp_get_rsp_enc(uint32_t return_code,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len,
+ int32_t * const p_temp)
+{
+ SER_RSP_ENC_BEGIN(SD_TEMP_GET);
+ SER_PUSH_COND(p_temp, uint32_t_enc);
+ SER_RSP_ENC_END;
+}
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/connectivity/codecs/ble/serializers/nrf_soc_conn.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/connectivity/codecs/ble/serializers/nrf_soc_conn.h
new file mode 100644
index 0000000..d7c52bf
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/connectivity/codecs/ble/serializers/nrf_soc_conn.h
@@ -0,0 +1,148 @@
+/**
+ * Copyright (c) 2014 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#ifndef NRF_SOC_CONN_H__
+#define NRF_SOC_CONN_H__
+
+/**@file
+ *
+ * @defgroup soc_conn SOC Connectivity command request decoders and command response encoders
+ * @{
+ * @ingroup ser_conn_s130_codecs
+ *
+ * @brief SOC Connectivity command request decoders and command response encoders.
+ */
+#include "nrf_soc.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**@brief Decodes @ref sd_power_system_off command request.
+ *
+ * @param[in] p_buf Pointer to buffer where encoded data command will be returned.
+ * @param[in] packet_len Length (in bytes) of request packet.
+ *
+ * @retval NRF_SUCCESS Encoding success.
+ * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_PARAM Encoding failure. Incorrect parameter.
+ */
+uint32_t power_system_off_req_dec(uint8_t const * const p_buf, uint16_t packet_len);
+
+
+/**@brief Decodes @ref sd_temp_get command request.
+ *
+ * @sa @ref temp_get_rsp_enc for response encoding.
+ *
+ * @param[in] p_buf Pointer to buffer where encoded data command will be returned.
+ * @param[in] packet_len Length (in bytes) of request packet.
+ * @param[out] pp_temp Pointer to pointer to result of temperature measurement.
+ *
+ * @retval NRF_SUCCESS Encoding success.
+ * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_PARAM Encoding failure. Incorrect parameter.
+ */
+uint32_t temp_get_req_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ int32_t * * const pp_temp);
+
+/**@brief Encodes @ref sd_temp_get command response.
+ *
+ * @sa @ref temp_get_req_dec for request decoding.
+ *
+ * @param[in] return_code Return code indicating if command was successful or not.
+ * @param[out] p_buf Pointer to buffer where encoded data command response will be
+ * returned.
+ * @param[in,out] p_buf_len \c in: size of \p p_buf buffer.
+ * \c out: Length of encoded command response packet.
+ * @param[in] p_temp Pointer to result of temperature measurement.
+ *
+ * @retval NRF_SUCCESS Encoding success.
+ * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length.
+ */
+uint32_t temp_get_rsp_enc(uint32_t return_code,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len,
+ int32_t * const p_temp);
+
+/**@brief Decodes @ref sd_ecb_block_encrypt command request.
+ *
+ * @sa @ref ecb_block_encrypt_rsp_enc for response encoding.
+ *
+ * @param[in] p_buf Pointer to buffer where encoded data command will be returned.
+ * @param[in] packet_len Length (in bytes) of request packet.
+ * @param[out] pp_ecb_data Pointer to pointer to ECB data.
+ *
+ * @retval NRF_SUCCESS Encoding success.
+ * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied
+ * @retval NRF_ERROR_INVALID_PARAM Encoding failure. Incorrect parameter.
+ */
+uint32_t ecb_block_encrypt_req_dec(uint8_t const * const p_buf,
+ uint32_t packet_len,
+ nrf_ecb_hal_data_t * * const pp_ecb_data);
+
+/**@brief Encodes @ref sd_ecb_block_encrypt command response.
+ *
+ * @sa @ref ecb_block_encrypt_req_dec for request decoding.
+ *
+ * @param[in] return_code Return code indicating if command was successful or not.
+ * @param[out] p_buf Pointer to buffer where encoded data command response will be
+ * returned.
+ * @param[in,out] p_buf_len \c in: size of \p p_buf buffer.
+ * \c out: Length of encoded command response packet.
+ * @param[in] p_ecb_data Pointer to ECB data.
+ *
+ * @retval NRF_SUCCESS Encoding success.
+ * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length.
+ */
+uint32_t ecb_block_encrypt_rsp_enc(uint32_t return_code,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len,
+ nrf_ecb_hal_data_t * const p_ecb_data);
+
+/** @} */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/connectivity/codecs/common/ble_dtm_conn.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/connectivity/codecs/common/ble_dtm_conn.h
new file mode 100644
index 0000000..53a80d2
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/connectivity/codecs/common/ble_dtm_conn.h
@@ -0,0 +1,113 @@
+/**
+ * Copyright (c) 2014 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#ifndef BLE_DTM_CONN_H__
+#define BLE_DTM_CONN_H__
+
+/**
+ * @addtogroup ser_codecs_conn Connectivity codecs
+ * @ingroup ser_codecs
+ */
+
+/**
+ * @addtogroup ser_conn_common_codecs Connectivity common codecs
+ * @ingroup ser_codecs_conn
+ */
+
+/**@file
+ *
+ * @defgroup ble_dtm_conn DTM Connectivity command request decoder and command response encoder
+ * @{
+ * @ingroup ser_conn_common_codecs
+ *
+ * @brief DTM Connectivity command request decoder and command response encoder.
+ */
+
+#include "dtm_uart.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**@brief Decodes @ref ble_dtm_init command request.
+ *
+ * @sa @ref encoding_data for packet format,
+ * @ref ble_dtm_init_rsp_enc for response encoding.
+ *
+ * @param[in] p_buf Pointer to beginning of command request packet.
+ * @param[in] packet_len Length (in bytes) of request packet.
+ * @param[in] p_comm_params Pointer to the structure with DTM UART configuration.
+
+ *
+ * @retval NRF_SUCCESS Decoding success.
+ * @retval NRF_ERROR_NULL Decoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Decoding failure. Incorrect buffer length.
+ */
+uint32_t ble_dtm_init_req_dec(uint8_t const * const p_buf,
+ uint16_t packet_len,
+ app_uart_stream_comm_params_t * p_comm_params);
+
+
+/**@brief Encodes @ref ble_dtm_init command response.
+ *
+ * @sa @ref encoding_data for packet format.
+ * @ref ble_dtm_init_req_dec for request decoding.
+ *
+ * @param[in] return_code Return code indicating if command was successful or not.
+ * @param[out] p_buf Pointer to buffer where encoded data command response will be
+ * returned.
+ * @param[in,out] p_buf_len \c in: size of \p p_buf buffer.
+ * \c out: Length of encoded command response packet.
+ *
+ * @retval NRF_SUCCESS Encoding success.
+ * @retval NRF_ERROR_NULL Encoding failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Encoding failure. Incorrect buffer length.
+ */
+uint32_t ble_dtm_init_rsp_enc(uint32_t return_code,
+ uint8_t * const p_buf,
+ uint32_t * const p_buf_len);
+
+/** @} */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // BLE_DTM_CONN_H__
+
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/connectivity/codecs/common/ble_dtm_init.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/connectivity/codecs/common/ble_dtm_init.c
new file mode 100644
index 0000000..e9dfefa
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/connectivity/codecs/common/ble_dtm_init.c
@@ -0,0 +1,83 @@
+/**
+ * Copyright (c) 2014 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#include "ble_dtm_conn.h"
+#include "dtm_uart.h"
+#include "nrf_error.h"
+#include "ble_serialization.h"
+
+uint32_t ble_dtm_init_req_dec(uint8_t const * const p_buf, uint16_t packet_len,
+ app_uart_stream_comm_params_t * p_comm_params)
+{
+ SER_ASSERT_NOT_NULL(p_buf);
+ SER_ASSERT_NOT_NULL(p_comm_params);
+
+ uint32_t index = 0;
+ uint32_t err_code = NRF_SUCCESS;
+
+ err_code = uint8_t_dec(p_buf, packet_len, &index, &p_comm_params->tx_pin_no);
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code);
+
+ err_code = uint8_t_dec(p_buf, packet_len, &index, &p_comm_params->rx_pin_no);
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code);
+
+ err_code = uint8_t_dec(p_buf, packet_len, &index, &p_comm_params->baud_rate);
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code);
+
+ SER_ASSERT(index == packet_len, NRF_ERROR_INVALID_LENGTH);
+
+ return err_code;
+}
+
+uint32_t ble_dtm_init_rsp_enc(uint32_t return_code, uint8_t * const p_buf,
+ uint32_t * const p_buf_len)
+{
+ SER_ASSERT_NOT_NULL(p_buf);
+ SER_ASSERT_NOT_NULL(p_buf_len);
+
+ uint32_t index = 0;
+ uint32_t err_code = NRF_SUCCESS;
+
+ err_code = uint32_t_enc(&return_code, p_buf, *p_buf_len, &index);
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code);
+
+ *p_buf_len = index;
+
+ return err_code;
+}
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/connectivity/codecs/common/conn_mw.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/connectivity/codecs/common/conn_mw.c
new file mode 100644
index 0000000..fcd780c
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/connectivity/codecs/common/conn_mw.c
@@ -0,0 +1,107 @@
+/**
+ * Copyright (c) 2014 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#include <stddef.h>
+
+#include "ble_serialization.h"
+#include "nrf_soc.h"
+
+/**@brief Connectivity middleware handler type. */
+typedef uint32_t (*conn_mw_handler_t)(uint8_t const * const p_rx_buf,
+ uint32_t rx_buf_len,
+ uint8_t * const p_tx_buf,
+ uint32_t * const p_tx_buf_len);
+
+/**@brief Connectivity middleware item. */
+typedef struct
+{
+ uint8_t opcode; /**< Opcode by which specific codec is identified */
+ conn_mw_handler_t fp_handler; /**< Function pointer to handler associated with given opcode */
+} conn_mw_item_t;
+
+/* Include handlers for given softdevice */
+#include "conn_mw_items.c"
+
+/**@brief Number of registered connectivity middleware handlers. */
+static const uint32_t conn_mw_item_len = sizeof (conn_mw_item) / sizeof (conn_mw_item[0]);
+
+/**@brief Local function for finding connectivity middleware handler in the table.. */
+static conn_mw_handler_t conn_mw_handler_get(uint8_t opcode)
+{
+ conn_mw_handler_t fp_handler = NULL;
+ uint32_t i;
+
+ for (i = 0; i < conn_mw_item_len; i++)
+ {
+ if (opcode == conn_mw_item[i].opcode)
+ {
+ fp_handler = conn_mw_item[i].fp_handler;
+ break;
+ }
+ }
+
+ return fp_handler;
+}
+
+uint32_t conn_mw_handler(uint8_t const * const p_rx_buf,
+ uint32_t rx_buf_len,
+ uint8_t * const p_tx_buf,
+ uint32_t * const p_tx_buf_len)
+{
+ SER_ASSERT_NOT_NULL(p_rx_buf);
+ SER_ASSERT_NOT_NULL(p_tx_buf);
+ SER_ASSERT_NOT_NULL(p_tx_buf_len);
+
+ conn_mw_handler_t fp_handler;
+ uint32_t err_code = NRF_SUCCESS;
+ uint8_t opcode = p_rx_buf[SER_CMD_OP_CODE_POS];
+
+ fp_handler = conn_mw_handler_get(opcode);
+
+ if (fp_handler)
+ {
+ err_code = fp_handler(p_rx_buf, rx_buf_len, p_tx_buf, p_tx_buf_len);
+ }
+ else
+ {
+ err_code = NRF_ERROR_NOT_SUPPORTED;
+ }
+
+ return err_code;
+}
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/connectivity/codecs/common/conn_mw.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/connectivity/codecs/common/conn_mw.h
new file mode 100644
index 0000000..4ff3c8e
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/connectivity/codecs/common/conn_mw.h
@@ -0,0 +1,88 @@
+/**
+ * Copyright (c) 2014 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#ifndef _CONN_MW_H
+#define _CONN_MW_H
+
+/**
+ * @addtogroup ser_codecs_mw Connectivity middleware codecs
+ * @ingroup ser_codecs
+ */
+
+/**
+ * @addtogroup ser_mw_common_codecs Connectivity middleware common codecs
+ * @{
+ * @ingroup ser_codecs_mw
+ */
+
+#include <stdint.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**@brief Connectivity Middleware dispatcher function
+ *
+ * @details It will handle decode the opcode from the RX buffer and based on the opcode it will search
+ * for registered handler. Handler is called once it is found.
+ *
+ * @param[in] p_rx_buf Pointer to input buffer.
+ * @param[in] rx_buf_len Size of @p p_rx_buf.
+ * @param[out] p_tx_buf Pointer to output buffer.
+ * @param[in,out] p_tx_buf_len \c in: Size of \p p_tx_buf buffer.
+ * \c out: Length of valid data in \p p_tx_buf.
+ *
+ * @retval NRF_SUCCESS Handler success.
+ * @retval NRF_ERROR_NULL Handler failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Handler failure. Incorrect buffer length.
+ * @retval NRF_ERROR_INVALID_PARAM Handler failure. Invalid operation type.
+ * @retval NRF_ERROR_NOT_SUPPORTED Handler failure. Opcode not supported.
+ */
+uint32_t conn_mw_handler (uint8_t const * const p_rx_buf,
+ uint32_t rx_buf_len,
+ uint8_t * const p_tx_buf,
+ uint32_t * const p_tx_buf_len);
+
+#ifdef __cplusplus
+}
+#endif
+
+/** @} */
+
+#endif //_CONN_MW_H
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/connectivity/codecs/common/conn_mw_items.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/connectivity/codecs/common/conn_mw_items.c
new file mode 100644
index 0000000..0502ada
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/connectivity/codecs/common/conn_mw_items.c
@@ -0,0 +1,224 @@
+/**
+ * Copyright (c) 2014 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#include "conn_mw_nrf_soc.h"
+#if defined(BLE_STACK_SUPPORT_REQD)
+#include "ble.h"
+#include "ble_gap.h"
+#include "ble_gattc.h"
+#include "ble_gatts.h"
+
+#ifndef S112
+#include "ble_l2cap.h"
+#endif //!S112
+
+#include "conn_mw_ble.h"
+#include "conn_mw_ble_l2cap.h"
+#include "conn_mw_ble_gap.h"
+#include "conn_mw_ble_gatts.h"
+#include "conn_mw_ble_gattc.h"
+#endif // defined(BLE_STACK_SUPPORT_REQD)
+#if defined(ANT_STACK_SUPPORT_REQD)
+#include "conn_mw_ant.h"
+#include "ant_interface.h"
+#endif // defined(ANT_STACK_SUPPORT_REQD)
+
+/**@brief Connectivity middleware handlers table. */
+static const conn_mw_item_t conn_mw_item[] = {
+ //Functions from nrf_soc.h
+ {SD_POWER_SYSTEM_OFF, conn_mw_power_system_off},
+ {SD_TEMP_GET, conn_mw_temp_get},
+ {SD_ECB_BLOCK_ENCRYPT, conn_mw_ecb_block_encrypt},
+#if defined(BLE_STACK_SUPPORT_REQD)
+ //Functions from ble.h
+#if defined(NRF_SD_BLE_API_VERSION) && NRF_SD_BLE_API_VERSION < 4
+ {SD_BLE_TX_PACKET_COUNT_GET, conn_mw_ble_tx_packet_count_get},
+#endif
+ {SD_BLE_UUID_VS_ADD, conn_mw_ble_uuid_vs_add},
+ {SD_BLE_UUID_DECODE, conn_mw_ble_uuid_decode},
+ {SD_BLE_UUID_ENCODE, conn_mw_ble_uuid_encode},
+ {SD_BLE_VERSION_GET, conn_mw_ble_version_get},
+ {SD_BLE_OPT_GET, conn_mw_ble_opt_get},
+ {SD_BLE_OPT_SET, conn_mw_ble_opt_set},
+ {SD_BLE_ENABLE, conn_mw_ble_enable},
+ {SD_BLE_USER_MEM_REPLY, conn_mw_ble_user_mem_reply},
+#if NRF_SD_BLE_API_VERSION >= 4
+ {SD_BLE_CFG_SET, conn_mw_ble_cfg_set},
+#endif
+ //Functions from ble_l2cap.h
+#ifndef S112
+#if defined(NRF_SD_BLE_API_VERSION) && NRF_SD_BLE_API_VERSION < 4
+ {SD_BLE_L2CAP_CID_REGISTER, conn_mw_ble_l2cap_cid_register},
+ {SD_BLE_L2CAP_CID_UNREGISTER, conn_mw_ble_l2cap_cid_unregister},
+ {SD_BLE_L2CAP_TX, conn_mw_ble_l2cap_tx},
+#elif defined(NRF_SD_BLE_API_VERSION) && NRF_SD_BLE_API_VERSION >= 5
+ {SD_BLE_L2CAP_CH_SETUP, conn_mw_l2cap_ch_setup},
+ {SD_BLE_L2CAP_CH_RELEASE, conn_mw_l2cap_ch_release},
+ {SD_BLE_L2CAP_CH_RX, conn_mw_l2cap_ch_rx},
+ {SD_BLE_L2CAP_CH_TX, conn_mw_l2cap_ch_tx},
+ {SD_BLE_L2CAP_CH_FLOW_CONTROL, conn_mw_l2cap_ch_flow_control},
+#endif
+#endif //!S112
+ //Functions from ble_gap.h
+ {SD_BLE_GAP_ADDR_SET, conn_mw_ble_gap_addr_set},
+ {SD_BLE_GAP_ADDR_GET, conn_mw_ble_gap_addr_get},
+ {SD_BLE_GAP_PRIVACY_SET, conn_mw_ble_gap_privacy_set},
+ {SD_BLE_GAP_PRIVACY_GET, conn_mw_ble_gap_privacy_get},
+ {SD_BLE_GAP_WHITELIST_SET, conn_mw_ble_gap_whitelist_set},
+ {SD_BLE_GAP_DEVICE_IDENTITIES_SET, conn_mw_ble_gap_device_identities_set},
+#ifndef S112
+ {SD_BLE_GAP_SCAN_START, conn_mw_ble_gap_scan_start},
+ {SD_BLE_GAP_SCAN_STOP, conn_mw_ble_gap_scan_stop},
+ {SD_BLE_GAP_CONNECT, conn_mw_ble_gap_connect},
+ {SD_BLE_GAP_CONNECT_CANCEL, conn_mw_ble_gap_connect_cancel},
+ {SD_BLE_GAP_ENCRYPT, conn_mw_ble_gap_encrypt},
+#endif
+ {SD_BLE_GAP_SEC_INFO_REPLY, conn_mw_ble_gap_sec_info_reply},
+#if defined(NRF_SD_BLE_API_VERSION) && NRF_SD_BLE_API_VERSION < 6
+ {SD_BLE_GAP_ADV_DATA_SET, conn_mw_ble_gap_adv_data_set},
+#endif
+ {SD_BLE_GAP_ADV_START, conn_mw_ble_gap_adv_start},
+ {SD_BLE_GAP_ADV_STOP, conn_mw_ble_gap_adv_stop},
+ {SD_BLE_GAP_CONN_PARAM_UPDATE, conn_mw_ble_gap_conn_param_update},
+ {SD_BLE_GAP_DISCONNECT, conn_mw_ble_gap_disconnect},
+ {SD_BLE_GAP_TX_POWER_SET, conn_mw_ble_gap_tx_power_set},
+ {SD_BLE_GAP_APPEARANCE_SET, conn_mw_ble_gap_appearance_set},
+ {SD_BLE_GAP_APPEARANCE_GET, conn_mw_ble_gap_appearance_get},
+ {SD_BLE_GAP_PPCP_SET, conn_mw_ble_gap_ppcp_set},
+ {SD_BLE_GAP_PPCP_GET, conn_mw_ble_gap_ppcp_get},
+ {SD_BLE_GAP_DEVICE_NAME_SET, conn_mw_ble_gap_device_name_set},
+ {SD_BLE_GAP_DEVICE_NAME_GET, conn_mw_ble_gap_device_name_get},
+ {SD_BLE_GAP_AUTHENTICATE, conn_mw_ble_gap_authenticate},
+ {SD_BLE_GAP_SEC_PARAMS_REPLY, conn_mw_ble_gap_sec_params_reply},
+ {SD_BLE_GAP_AUTH_KEY_REPLY, conn_mw_ble_gap_auth_key_reply},
+ {SD_BLE_GAP_SEC_INFO_REPLY, conn_mw_ble_gap_sec_info_reply},
+ {SD_BLE_GAP_CONN_SEC_GET, conn_mw_ble_gap_conn_sec_get},
+ {SD_BLE_GAP_RSSI_START, conn_mw_ble_gap_rssi_start},
+ {SD_BLE_GAP_RSSI_STOP, conn_mw_ble_gap_rssi_stop},
+ {SD_BLE_GAP_KEYPRESS_NOTIFY, conn_mw_ble_gap_keypress_notify},
+ {SD_BLE_GAP_LESC_DHKEY_REPLY, conn_mw_ble_gap_lesc_dhkey_reply},
+ {SD_BLE_GAP_LESC_OOB_DATA_SET, conn_mw_ble_gap_lesc_oob_data_set},
+ {SD_BLE_GAP_LESC_OOB_DATA_GET, conn_mw_ble_gap_lesc_oob_data_get},
+ {SD_BLE_GAP_RSSI_GET, conn_mw_ble_gap_rssi_get},
+#if NRF_SD_BLE_API_VERSION >= 5
+ {SD_BLE_GAP_PHY_UPDATE, conn_mw_ble_gap_phy_update},
+#endif
+#if NRF_SD_BLE_API_VERSION >= 4 && !defined(S112)
+ {SD_BLE_GAP_DATA_LENGTH_UPDATE, conn_mw_ble_gap_data_length_update},
+#endif
+#if NRF_SD_BLE_API_VERSION > 5
+ {SD_BLE_GAP_ADV_SET_CONFIGURE, conn_mw_ble_gap_adv_set_configure},
+#ifndef S112
+ {SD_BLE_GAP_QOS_CHANNEL_SURVEY_START, conn_mw_ble_gap_qos_channel_survey_start},
+ {SD_BLE_GAP_QOS_CHANNEL_SURVEY_STOP, conn_mw_ble_gap_qos_channel_survey_stop},
+#endif //!S112
+#endif
+ //Functions from ble_gattc.h
+ {SD_BLE_GATTC_PRIMARY_SERVICES_DISCOVER, conn_mw_ble_gattc_primary_services_discover},
+ {SD_BLE_GATTC_RELATIONSHIPS_DISCOVER, conn_mw_ble_gattc_relationships_discover},
+ {SD_BLE_GATTC_CHARACTERISTICS_DISCOVER, conn_mw_ble_gattc_characteristics_discover},
+ {SD_BLE_GATTC_DESCRIPTORS_DISCOVER, conn_mw_ble_gattc_descriptors_discover},
+ {SD_BLE_GATTC_CHAR_VALUE_BY_UUID_READ, conn_mw_ble_gattc_char_value_by_uuid_read},
+ {SD_BLE_GATTC_READ, conn_mw_ble_gattc_read},
+ {SD_BLE_GATTC_CHAR_VALUES_READ, conn_mw_ble_gattc_char_values_read},
+ {SD_BLE_GATTC_WRITE, conn_mw_ble_gattc_write},
+ {SD_BLE_GATTC_HV_CONFIRM, conn_mw_ble_gattc_hv_confirm},
+ {SD_BLE_GATTC_ATTR_INFO_DISCOVER, conn_mw_ble_gattc_attr_info_discover},
+ {SD_BLE_GATTC_EXCHANGE_MTU_REQUEST, conn_mw_ble_gattc_exchange_mtu_request},
+ //Functions from ble_gatts.h
+ {SD_BLE_GATTS_SERVICE_ADD, conn_mw_ble_gatts_service_add},
+ {SD_BLE_GATTS_INCLUDE_ADD, conn_mw_ble_gatts_include_add},
+ {SD_BLE_GATTS_CHARACTERISTIC_ADD, conn_mw_ble_gatts_characteristic_add},
+ {SD_BLE_GATTS_DESCRIPTOR_ADD, conn_mw_ble_gatts_descriptor_add},
+ {SD_BLE_GATTS_VALUE_SET, conn_mw_ble_gatts_value_set},
+ {SD_BLE_GATTS_VALUE_GET, conn_mw_ble_gatts_value_get},
+ {SD_BLE_GATTS_HVX, conn_mw_ble_gatts_hvx},
+ {SD_BLE_GATTS_SERVICE_CHANGED, conn_mw_ble_gatts_service_changed},
+ {SD_BLE_GATTS_RW_AUTHORIZE_REPLY, conn_mw_ble_gatts_rw_authorize_reply},
+ {SD_BLE_GATTS_SYS_ATTR_SET, conn_mw_ble_gatts_sys_attr_set},
+ {SD_BLE_GATTS_SYS_ATTR_GET, conn_mw_ble_gatts_sys_attr_get},
+ {SD_BLE_GATTS_INITIAL_USER_HANDLE_GET, conn_mw_ble_gatts_initial_user_handle_get},
+ {SD_BLE_GATTS_ATTR_GET, conn_mw_ble_gatts_attr_get},
+ {SD_BLE_GATTS_EXCHANGE_MTU_REPLY, conn_mw_ble_gatts_exchange_mtu_reply},
+#endif // // defined(BLE_STACK_SUPPORT_REQD)
+#if defined(ANT_STACK_SUPPORT_REQD)
+ //Functions from ant_interface.h
+ {SVC_ANT_ENABLE, conn_mw_ant_enable},
+ {SVC_ANT_CHANNEL_ASSIGN, conn_ant_channel_assign},
+ {SVC_ANT_CHANNEL_OPEN, conn_ant_channel_open_with_offset},
+ {SVC_ANT_CHANNEL_ID_SET, conn_ant_channel_id_set},
+ {SVC_ANT_CHANNEL_PERIOD_SET, conn_ant_channel_period_set},
+ {SVC_ANT_CHANNEL_RADIO_FREQ_SET, conn_ant_channel_radio_freq_set},
+ {SVC_ANT_TX_BROADCAST_MESSAGE, conn_ant_broadcast_message_tx},
+ {SVC_ANT_TX_ACKNOWLEDGED_MESSAGE, conn_ant_acknowledge_message_tx},
+ {SVC_ANT_CHANNEL_UNASSIGN, conn_ant_channel_unassign},
+ {SVC_ANT_CHANNEL_CLOSE, conn_ant_channel_close},
+ {SVC_ANT_NETWORK_KEY_SET, conn_ant_network_address_set},
+ {SVC_ANT_CHANNEL_RADIO_TX_POWER_SET, conn_ant_channel_radio_tx_power_set},
+ {SVC_ANT_CHANNEL_SEARCH_TIMEOUT_SET, conn_ant_channel_rx_search_timeout_set},
+ {SVC_ANT_CHANNEL_LOW_PRIO_RX_SEARCH_TIMEOUT_SET, conn_ant_channel_low_priority_rx_search_timeout_set},
+ {SVC_ANT_PROX_SEARCH_SET, conn_ant_prox_search_set},
+ {SVC_ANT_SEARCH_WAVEFORM_SET, conn_ant_search_waveform_set},
+ {SVC_ANT_CHANNEL_ID_GET, conn_ant_channel_id_get},
+ {SVC_ANT_CHANNEL_RADIO_FREQ_GET, conn_ant_channel_radio_freq_get},
+ {SVC_ANT_CHANNEL_PERIOD_GET, conn_ant_channel_period_get},
+ {SVC_ANT_SEARCH_CHANNEL_PRIORITY_SET, conn_ant_search_channel_priority_set},
+ {SVC_ANT_ACTIVE_SEARCH_SHARING_CYCLES_SET, conn_ant_active_search_sharing_cycles_set},
+ {SVC_ANT_LIB_CONFIG_SET, conn_ant_lib_config_set},
+ {SVC_ANT_ACTIVE_SEARCH_SHARING_CYCLES_GET, conn_ant_active_search_sharing_cycles_get},
+ {SVC_ANT_LIB_CONFIG_GET, conn_ant_lib_config_get},
+ {SVC_ANT_LIB_CONFIG_CLEAR, conn_ant_lib_config_clear},
+ {SVC_ANT_STACK_INIT, conn_ant_stack_reset},
+ {SVC_ANT_RX_SCAN_MODE_START, conn_ant_rx_scan_mode_start},
+ {SVC_ANT_ID_LIST_ADD, conn_ant_id_list_add},
+ {SVC_ANT_ID_LIST_CONFIG, conn_ant_id_list_config},
+ {SVC_ANT_CHANNEL_STATUS_GET, conn_ant_channel_status_get},
+ {SVC_ANT_INIT_CW_TEST_MODE, conn_ant_cw_test_mode_init},
+ {SVC_ANT_CW_TEST_MODE, conn_ant_cw_test_mode},
+ {SVC_ANT_VERSION, conn_ant_version_get},
+ {SVC_ANT_CAPABILITIES, conn_ant_capabilities_get},
+ {SVC_ANT_CRYPTO_CHANNEL_ENABLE, conn_ant_crypto_channel_enable},
+ {SVC_ANT_ADV_BURST_CONFIG_SET, conn_ant_adv_burst_config_set},
+ {SVC_ANT_CRYPTO_KEY_SET, conn_ant_crypto_key_set},
+ {SVC_ANT_CRYPTO_INFO_SET, conn_ant_crypto_info_set},
+ {SVC_ANT_CRYPTO_INFO_GET, conn_ant_crypto_info_get},
+ {SVC_ANT_COEX_CONFIG_SET, conn_ant_coex_config_set},
+ {SVC_ANT_COEX_CONFIG_GET, conn_ant_coex_config_get},
+#endif // // defined(ANT_STACK_SUPPORT_REQD)
+};
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/connectivity/codecs/common/conn_mw_nrf_soc.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/connectivity/codecs/common/conn_mw_nrf_soc.c
new file mode 100644
index 0000000..62d034e
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/connectivity/codecs/common/conn_mw_nrf_soc.c
@@ -0,0 +1,114 @@
+/**
+ * Copyright (c) 2014 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#include "nrf_soc_conn.h"
+#include "conn_mw_nrf_soc.h"
+#include "ble_serialization.h"
+
+uint32_t conn_mw_power_system_off(uint8_t const * const p_rx_buf,
+ uint32_t rx_buf_len,
+ uint8_t * const p_tx_buf,
+ uint32_t * const p_tx_buf_len)
+{
+ SER_ASSERT_NOT_NULL(p_rx_buf);
+ SER_ASSERT_NOT_NULL(p_tx_buf);
+ SER_ASSERT_NOT_NULL(p_tx_buf_len);
+
+ uint32_t err_code = NRF_SUCCESS;
+
+ err_code = power_system_off_req_dec(p_rx_buf, rx_buf_len);
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code);
+
+ err_code = sd_power_system_off();
+ /* There should be no return from sd_power_system_off() */
+
+ return err_code;
+}
+
+uint32_t conn_mw_temp_get(uint8_t const * const p_rx_buf,
+ uint32_t rx_buf_len,
+ uint8_t * const p_tx_buf,
+ uint32_t * const p_tx_buf_len)
+{
+ SER_ASSERT_NOT_NULL(p_rx_buf);
+ SER_ASSERT_NOT_NULL(p_tx_buf);
+ SER_ASSERT_NOT_NULL(p_tx_buf_len);
+
+ int32_t temperature;
+ int32_t * p_temperature = &temperature;
+
+ uint32_t err_code = NRF_SUCCESS;
+ uint32_t sd_err_code;
+
+ err_code = temp_get_req_dec(p_rx_buf, rx_buf_len, &p_temperature);
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code);
+
+ sd_err_code = sd_temp_get(p_temperature);
+
+ err_code = temp_get_rsp_enc(sd_err_code, p_tx_buf, p_tx_buf_len, p_temperature);
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code);
+
+ return err_code;
+}
+
+uint32_t conn_mw_ecb_block_encrypt(uint8_t const * const p_rx_buf,
+ uint32_t rx_buf_len,
+ uint8_t * const p_tx_buf,
+ uint32_t * const p_tx_buf_len)
+{
+ SER_ASSERT_NOT_NULL(p_rx_buf);
+ SER_ASSERT_NOT_NULL(p_tx_buf);
+ SER_ASSERT_NOT_NULL(p_tx_buf_len);
+
+ nrf_ecb_hal_data_t ecb_data;
+ nrf_ecb_hal_data_t * p_ecb_data = &ecb_data;
+
+ uint32_t err_code = NRF_SUCCESS;
+ uint32_t sd_err_code;
+
+ err_code = ecb_block_encrypt_req_dec(p_rx_buf, rx_buf_len, &p_ecb_data);
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code);
+
+ sd_err_code = sd_ecb_block_encrypt(p_ecb_data);
+
+ err_code = ecb_block_encrypt_rsp_enc(sd_err_code, p_tx_buf, p_tx_buf_len, p_ecb_data);
+ SER_ASSERT(err_code == NRF_SUCCESS, err_code);
+
+ return err_code;
+}
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/connectivity/codecs/common/conn_mw_nrf_soc.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/connectivity/codecs/common/conn_mw_nrf_soc.h
new file mode 100644
index 0000000..7e029db
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/connectivity/codecs/common/conn_mw_nrf_soc.h
@@ -0,0 +1,118 @@
+/**
+ * Copyright (c) 2014 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#ifndef CONN_MW_NRF_SOC_H__
+#define CONN_MW_NRF_SOC_H__
+
+/**
+ * @addtogroup ser_mw_common_codecs
+ * @{
+ */
+
+#include <stdint.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**@brief Handles @ref sd_power_system_off command request.
+ *
+ * @param[in] p_rx_buf Pointer to input buffer.
+ * @param[in] rx_buf_len Size of @p p_rx_buf.
+ * @param[out] p_tx_buf Pointer to output buffer.
+ * @param[in,out] p_tx_buf_len \c in: Size of \p p_tx_buf buffer.
+ * \c out: Length of valid data in \p p_tx_buf.
+ *
+ * @retval NRF_SUCCESS Handler success.
+ * @retval NRF_ERROR_NULL Handler failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Handler failure. Incorrect buffer length.
+ * @retval NRF_ERROR_INVALID_PARAM Handler failure. Invalid operation type.
+ * @retval NRF_ERROR_NOT_SUPPORTED Handler failure. Opcode not supported.
+ */
+uint32_t conn_mw_power_system_off(uint8_t const * const p_rx_buf,
+ uint32_t rx_buf_len,
+ uint8_t * const p_tx_buf,
+ uint32_t * const p_tx_buf_len);
+
+/**@brief Handles @ref sd_temp_get command request and prepares response.
+ *
+ * @param[in] p_rx_buf Pointer to input buffer.
+ * @param[in] rx_buf_len Size of @p p_rx_buf.
+ * @param[out] p_tx_buf Pointer to output buffer.
+ * @param[in,out] p_tx_buf_len \c in: Size of \p p_tx_buf buffer.
+ * \c out: Length of valid data in \p p_tx_buf.
+ *
+ * @retval NRF_SUCCESS Handler success.
+ * @retval NRF_ERROR_NULL Handler failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Handler failure. Incorrect buffer length.
+ * @retval NRF_ERROR_INVALID_PARAM Handler failure. Invalid operation type.
+ * @retval NRF_ERROR_NOT_SUPPORTED Handler failure. Opcode not supported.
+ */
+uint32_t conn_mw_temp_get(uint8_t const * const p_rx_buf,
+ uint32_t rx_buf_len,
+ uint8_t * const p_tx_buf,
+ uint32_t * const p_tx_buf_len);
+
+/**@brief Handles @ref sd_ecb_block_encrypt command request and prepares response.
+ *
+ * @param[in] p_rx_buf Pointer to input buffer.
+ * @param[in] rx_buf_len Size of @p p_rx_buf.
+ * @param[out] p_tx_buf Pointer to output buffer.
+ * @param[in,out] p_tx_buf_len \c in: Size of \p p_tx_buf buffer.
+ * \c out: Length of valid data in \p p_tx_buf.
+ *
+ * @retval NRF_SUCCESS Handler success.
+ * @retval NRF_ERROR_NULL Handler failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INVALID_LENGTH Handler failure. Incorrect buffer length.
+ * @retval NRF_ERROR_INVALID_PARAM Handler failure. Invalid operation type.
+ * @retval NRF_ERROR_NOT_SUPPORTED Handler failure. Opcode not supported.
+ */
+uint32_t conn_mw_ecb_block_encrypt(uint8_t const * const p_rx_buf,
+ uint32_t rx_buf_len,
+ uint8_t * const p_tx_buf,
+ uint32_t * const p_tx_buf_len);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+/** @} */
+
+#endif
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/connectivity/hal/dtm_uart.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/connectivity/hal/dtm_uart.c
new file mode 100644
index 0000000..ea4f9b3
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/connectivity/hal/dtm_uart.c
@@ -0,0 +1,268 @@
+/**
+ * Copyright (c) 2012 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+/**
+ @defgroup dtm_standalone main.c
+ @{
+ @ingroup ble_sdk_app_dtm_serial
+ @brief Stand-alone DTM application for UART interface.
+
+ */
+
+#include <stdint.h>
+#include <stdbool.h>
+#include "nrf.h"
+#include "ble_dtm.h"
+#include "nrf_gpio.h"
+#include "dtm_uart.h"
+#include "nrf_error.h"
+#include "app_util.h"
+#include "nrf_drv_uart.h"
+#include "nrf_peripherals.h"
+#include "app_util_platform.h"
+
+//Configuration parameters.
+#define BITRATE UART_BAUDRATE_BAUDRATE_Baud57600 /**< Serial bitrate on the UART */
+
+//@note: The BLE DTM 2-wire UART standard specifies 8 data bits, 1 stop bit, no flow control.
+//These parameters are not configurable in the BLE standard.
+
+/**@details Maximum iterations needed in the main loop between stop bit 1st byte and start bit 2nd
+ * byte. DTM standard allows 5000us delay between stop bit 1st byte and start bit 2nd byte.
+ * As the time is only known when a byte is received, then the time between between stop bit 1st
+ * byte and stop bit 2nd byte becomes:
+ * 5000us + transmission time of 2nd byte.
+ *
+ * Byte transmission time is (Baud rate of 19200):
+ * 10bits * 1/19200 = approx. 520 us/byte (8 data bits + start & stop bit).
+ *
+ * Loop time on polling UART register for received byte is defined in ble_dtm.c as:
+ * UART_POLL_CYCLE = 260 us
+ *
+ * The max time between two bytes thus becomes (loop time: 260us / iteration):
+ * (5000us + 520us) / 260us / iteration = 21.2 iterations.
+ *
+ * This is rounded down to 21.
+ *
+ * @note If UART bit rate is changed, this value should be recalculated as well.
+ */
+
+static uint32_t m_baud_rates[] = {[UART_BAUD_RATE_1200] = NRF_UART_BAUDRATE_1200,
+ [UART_BAUD_RATE_2400] = NRF_UART_BAUDRATE_2400,
+ [UART_BAUD_RATE_4800] = NRF_UART_BAUDRATE_4800,
+ [UART_BAUD_RATE_9600] = NRF_UART_BAUDRATE_9600,
+ [UART_BAUD_RATE_14400] = NRF_UART_BAUDRATE_14400,
+ [UART_BAUD_RATE_19200] = NRF_UART_BAUDRATE_19200,
+ [UART_BAUD_RATE_28800] = NRF_UART_BAUDRATE_28800,
+ [UART_BAUD_RATE_38400] = NRF_UART_BAUDRATE_38400,
+ [UART_BAUD_RATE_57600] = NRF_UART_BAUDRATE_57600,
+ [UART_BAUD_RATE_76800] = NRF_UART_BAUDRATE_76800,
+ [UART_BAUD_RATE_115200] = NRF_UART_BAUDRATE_115200 };
+
+
+static uint32_t m_iteration[] = {[UART_BAUD_RATE_1200] = 51,
+ [UART_BAUD_RATE_2400] = 35,
+ [UART_BAUD_RATE_4800] = 27,
+ [UART_BAUD_RATE_9600] = 23,
+ [UART_BAUD_RATE_14400] = 21,
+ [UART_BAUD_RATE_19200] = 21,
+ [UART_BAUD_RATE_28800] = 20,
+ [UART_BAUD_RATE_38400] = 20,
+ [UART_BAUD_RATE_57600] = 19,
+ [UART_BAUD_RATE_76800] = 19,
+ [UART_BAUD_RATE_115200] = 19, };
+
+static uint32_t m_iterations_next_byte_max = 51;
+
+static nrf_drv_uart_t m_dtm_uart_driver = NRF_DRV_UART_INSTANCE(0);
+
+/**@brief Function for UART initialization.
+ */
+static uint32_t uart_init(app_uart_stream_comm_params_t * p_comm_params)
+{
+ if (p_comm_params->baud_rate > UART_BAUD_RATE_115200)
+ {
+ return NRF_ERROR_INVALID_PARAM;
+ }
+
+ nrf_drv_uart_config_t config = NRF_DRV_UART_DEFAULT_CONFIG;
+
+ config.pselrxd = p_comm_params->rx_pin_no;
+ config.pseltxd = p_comm_params->tx_pin_no;
+ config.baudrate = (nrf_uart_baudrate_t) m_baud_rates[p_comm_params->baud_rate];
+ config.hwfc = NRF_UART_HWFC_DISABLED;
+ config.parity = NRF_UART_PARITY_EXCLUDED;
+#ifdef UART_PRESENT
+ //Current implementation of DTM requires legacy UART features and
+ // it will not work on nrf52810.
+ config.use_easy_dma = false;
+#endif
+ nrf_drv_uart_uninit(&m_dtm_uart_driver);
+ uint32_t err_code = nrf_drv_uart_init(&m_dtm_uart_driver, &config, NULL);
+ if (err_code != NRF_SUCCESS)
+ {
+ return err_code;
+ }
+ nrf_drv_uart_rx_enable(&m_dtm_uart_driver);
+
+ m_iterations_next_byte_max = m_iteration[p_comm_params->baud_rate];
+
+ return NRF_SUCCESS;
+}
+
+
+/**@brief Function for splitting UART command bit fields into separate command parameters for the DTM library.
+ *
+ * @param[in] command The packed UART command.
+ * @return result status from dtmlib.
+ */
+static uint32_t dtm_cmd_put(uint16_t command)
+{
+ dtm_cmd_t command_code = (command >> 14) & 0x03;
+ dtm_freq_t freq = (command >> 8) & 0x3F;
+ uint32_t length = (command >> 2) & 0x3F;
+ dtm_pkt_type_t payload = command & 0x03;
+
+ //Check for Vendor Specific payload.
+ if (payload == 0x03)
+ {
+ /* Note that in a HCI adaption layer, as well as in the DTM PDU format,
+ the value 0x03 is a distinct bit pattern (PRBS15). Even though BLE does not
+ support PRBS15, this implementation re-maps 0x03 to DTM_PKT_VENDORSPECIFIC,
+ to avoid the risk of confusion, should the code be extended to greater coverage.
+ */
+ payload = DTM_PKT_VENDORSPECIFIC;
+ }
+ return dtm_cmd(command_code, freq, length, payload);
+}
+
+
+/**@brief Function for application main entry.
+ *
+ * @details This function serves as an adaptation layer between a 2-wire UART interface and the
+ * dtmlib. After initialization, DTM commands submitted through the UART are forwarded to
+ * dtmlib and events (i.e. results from the command) is reported back through the UART.
+ */
+uint32_t dtm_start(app_uart_stream_comm_params_t uart_comm_params)
+{
+ uint32_t current_time;
+ uint32_t dtm_error_code;
+ uint32_t msb_time = 0; //Time when MSB of the DTM command was read. Used to catch stray bytes from "misbehaving" testers.
+ bool is_msb_read = false; //True when MSB of the DTM command has been read and the application is waiting for LSB.
+ uint16_t dtm_cmd_from_uart = 0; //Packed command containing command_code:freqency:length:payload in 2:6:6:2 bits.
+ uint8_t rx_byte; //Last byte read from UART.
+ dtm_event_t result; //Result of a DTM operation.
+ uint32_t err_code;
+
+ err_code = uart_init(&uart_comm_params);
+
+ if (err_code != NRF_SUCCESS)
+ {
+ return err_code;
+ }
+
+ dtm_error_code = dtm_init();
+
+ if (dtm_error_code != DTM_SUCCESS)
+ {
+ //If DTM cannot be correctly initialized, then we just return.
+ return NRF_ERROR_INTERNAL;
+ }
+
+ for (;; )
+ {
+ //Will return every timeout, 625 us.
+ current_time = dtm_wait();
+
+ if (NRF_SUCCESS != nrf_drv_uart_rx(&m_dtm_uart_driver, &rx_byte,1))
+ {
+ return NRF_ERROR_INTERNAL;
+ }
+
+ if (!is_msb_read)
+ {
+ //This is first byte of two-byte command.
+ is_msb_read = true;
+ dtm_cmd_from_uart = ((dtm_cmd_t)rx_byte) << 8;
+ msb_time = current_time;
+
+ //Go back and wait for 2nd byte of command word.
+ continue;
+ }
+
+ //This is the second byte read; combine it with the first and process command
+ if (current_time > (msb_time + m_iterations_next_byte_max))
+ {
+ //More than ~5mS after msb: Drop old byte, take the new byte as MSB.
+ //The variable is_msb_read will remains true.
+ //Go back and wait for 2nd byte of the command word.
+ dtm_cmd_from_uart = ((dtm_cmd_t)rx_byte) << 8;
+ msb_time = current_time;
+ continue;
+ }
+
+ //2-byte UART command received.
+ is_msb_read = false;
+ dtm_cmd_from_uart |= (dtm_cmd_t)rx_byte;
+
+ if (dtm_cmd_put(dtm_cmd_from_uart) != DTM_SUCCESS)
+ {
+ //Extended error handling may be put here.
+ //Default behavior is to return the event on the UART (see below);
+ //the event report will reflect any lack of success.
+ }
+
+ //Retrieve result of the operation. This implementation will busy-loop
+ //for the duration of the byte transmissions on the UART.
+ if (dtm_event_get(&result))
+ {
+ //Report command status on the UART.
+ uint8_t tx_byte = (result >> 8) & 0xFF;
+
+ //Transmit MSB of the result.
+ (void)nrf_drv_uart_tx(&m_dtm_uart_driver, &tx_byte, 1);
+
+ //Transmit LSB of the result.
+ tx_byte = result & 0xFF;
+ (void)nrf_drv_uart_tx(&m_dtm_uart_driver, &tx_byte, 1);
+ }
+ }
+}
+
+/// @}
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/connectivity/hal/dtm_uart.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/connectivity/hal/dtm_uart.h
new file mode 100644
index 0000000..081bfb0
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/connectivity/hal/dtm_uart.h
@@ -0,0 +1,59 @@
+/**
+ * Copyright (c) 2013 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#ifndef DTM_UART_H__
+#define DTM_UART_H__
+
+#include <stdint.h>
+#include "dtm_uart_params.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define UART_PIN_DISCONNECTED 0xFFFFFFFF /**< Value indicating that no pin is connected to this UART register. */
+
+uint32_t dtm_start(app_uart_stream_comm_params_t uart_comm_params);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // DTM_UART_H__
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/connectivity/pstorage_platform.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/connectivity/pstorage_platform.h
new file mode 100644
index 0000000..f9a542f
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/connectivity/pstorage_platform.h
@@ -0,0 +1,103 @@
+/**
+ * Copyright (c) 2013 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+/** @cond To make doxygen skip this file */
+
+/** @file
+ * This header contains defines regarding persistent storage that are specific to
+ * persistent storage implementation and application use case.
+ */
+#ifndef PSTORAGE_PL_H__
+#define PSTORAGE_PL_H__
+
+#include <stdint.h>
+#include "nrf.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+static __INLINE uint16_t pstorage_flash_page_size()
+{
+ return (uint16_t)NRF_FICR->CODEPAGESIZE;
+}
+
+#define PSTORAGE_FLASH_PAGE_SIZE pstorage_flash_page_size() /**< Size of one flash page. */
+#define PSTORAGE_FLASH_EMPTY_MASK 0xFFFFFFFF /**< Bit mask that defines an empty address in flash. */
+
+static __INLINE uint32_t pstorage_flash_page_end()
+{
+ uint32_t bootloader_addr = NRF_UICR->NRFFW[0];
+
+ return ((bootloader_addr != PSTORAGE_FLASH_EMPTY_MASK) ?
+ (bootloader_addr/ PSTORAGE_FLASH_PAGE_SIZE) : NRF_FICR->CODESIZE);
+}
+
+#define PSTORAGE_FLASH_PAGE_END pstorage_flash_page_end()
+
+#define PSTORAGE_NUM_OF_PAGES 2 /**< Number of flash pages allocated for the pstorage module excluding the swap page, configurable based on system requirements. */
+#define PSTORAGE_MIN_BLOCK_SIZE 0x0010 /**< Minimum size of block that can be registered with the module. Should be configured based on system requirements, recommendation for this value is to have at least the size of a word. */
+
+#define PSTORAGE_DATA_START_ADDR ((PSTORAGE_FLASH_PAGE_END - PSTORAGE_NUM_OF_PAGES) \
+ * PSTORAGE_FLASH_PAGE_SIZE) /**< Start address for persistent data, configurable according to system requirements. */
+#define PSTORAGE_DATA_END_ADDR (PSTORAGE_FLASH_PAGE_END * PSTORAGE_FLASH_PAGE_SIZE) /**< End address for persistent data, configurable according to system requirements. */
+#define PSTORAGE_MAX_BLOCK_SIZE PSTORAGE_FLASH_PAGE_SIZE /**< Maximum size of block that can be registered with the module. Should be configured based on system requirements. Also, should be greater than or equal to the minimum size. */
+#define PSTORAGE_CMD_QUEUE_SIZE 30 /**< Maximum number of flash access commands that can be maintained by the module for all applications. Configurable. */
+
+
+/** Abstracts persistently memory block identifier. */
+typedef uint32_t pstorage_block_t;
+
+typedef struct
+{
+ uint32_t module_id; /**< Module ID.*/
+ pstorage_block_t block_id; /**< Block ID.*/
+} pstorage_handle_t;
+
+typedef uint16_t pstorage_size_t; /** Size of length and offset fields. */
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // PSTORAGE_PL_H__
+
+/** @} */
+/** @endcond */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/connectivity/ser_conn_cmd_decoder.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/connectivity/ser_conn_cmd_decoder.c
new file mode 100644
index 0000000..4107666
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/connectivity/ser_conn_cmd_decoder.c
@@ -0,0 +1,138 @@
+/**
+ * Copyright (c) 2014 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#include <stdint.h>
+#include <string.h>
+#include "nordic_common.h"
+#include "app_error.h"
+#include "ble_serialization.h"
+#include "ser_config.h"
+#include "conn_mw.h"
+#include "ser_hal_transport.h"
+#include "ser_conn_cmd_decoder.h"
+#include "ser_conn_handlers.h"
+#include "nrf_log_ctrl.h"
+
+#define NRF_LOG_MODULE_NAME ser_conn_dec
+#include "nrf_log.h"
+NRF_LOG_MODULE_REGISTER();
+
+uint32_t ser_conn_command_process(uint8_t * p_command, uint16_t command_len)
+{
+ SER_ASSERT_NOT_NULL(p_command);
+ SER_ASSERT_LENGTH_LEQ(SER_OP_CODE_SIZE, command_len);
+
+ uint32_t err_code = NRF_SUCCESS;
+ uint8_t * p_tx_buf = NULL;
+ uint32_t tx_buf_len = 0;
+ uint8_t opcode = p_command[SER_CMD_OP_CODE_POS];
+ uint32_t index = 0;
+
+ /* Allocate a memory buffer from HAL Transport layer for transmitting the Command Response.
+ * Loop until a buffer is available. */
+ NRF_LOG_INFO("Command process start");
+ do
+ {
+ err_code = ser_hal_transport_tx_pkt_alloc(&p_tx_buf, (uint16_t *)&tx_buf_len);
+ if (err_code == NRF_ERROR_NO_MEM)
+ {
+ ser_conn_on_no_mem_handler();
+ }
+ }
+ while (NRF_ERROR_NO_MEM == err_code);
+
+ NRF_LOG_INFO("Tx buffer allocated");
+ if (NRF_SUCCESS == err_code)
+ {
+ /* Create a new response packet. */
+ p_tx_buf[SER_PKT_TYPE_POS] = SER_PKT_TYPE_RESP;
+ tx_buf_len -= SER_PKT_TYPE_SIZE;
+
+ /* Decode a request, pass a memory for a response command (opcode + data) and encode it. */
+ err_code = conn_mw_handler
+ (p_command, command_len, &p_tx_buf[SER_PKT_OP_CODE_POS], &tx_buf_len);
+
+
+ /* Command decoder not found. */
+ if (NRF_ERROR_NOT_SUPPORTED == err_code)
+ {
+ NRF_LOG_ERROR("Command not supported opcode:%d", p_tx_buf[SER_PKT_OP_CODE_POS]);
+ APP_ERROR_CHECK(SER_WARNING_CODE);
+ err_code = op_status_enc
+ (opcode, NRF_ERROR_NOT_SUPPORTED,
+ &p_tx_buf[SER_PKT_OP_CODE_POS], &tx_buf_len, &index);
+ if (NRF_SUCCESS == err_code)
+ {
+ tx_buf_len += SER_PKT_TYPE_SIZE;
+ err_code = ser_hal_transport_tx_pkt_send(p_tx_buf, (uint16_t)tx_buf_len);
+ /* TX buffer is going to be freed automatically in the HAL Transport layer. */
+ if (NRF_SUCCESS != err_code)
+ {
+ err_code = NRF_ERROR_INTERNAL;
+ }
+ }
+ else
+ {
+ err_code = NRF_ERROR_INTERNAL;
+ }
+ }
+ else if (NRF_SUCCESS == err_code) /* Send a response. */
+ {
+ tx_buf_len += SER_PKT_TYPE_SIZE;
+ err_code = ser_hal_transport_tx_pkt_send(p_tx_buf, (uint16_t)tx_buf_len);
+
+ /* TX buffer is going to be freed automatically in the HAL Transport layer. */
+ if (NRF_SUCCESS != err_code)
+ {
+ err_code = NRF_ERROR_INTERNAL;
+ }
+ }
+ else
+ {
+ NRF_LOG_ERROR("Internal error during command decoding.");
+ err_code = NRF_ERROR_INTERNAL;
+ }
+ }
+ else
+ {
+ err_code = NRF_ERROR_INTERNAL;
+ }
+
+ return err_code;
+}
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/connectivity/ser_conn_cmd_decoder.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/connectivity/ser_conn_cmd_decoder.h
new file mode 100644
index 0000000..0b3d505
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/connectivity/ser_conn_cmd_decoder.h
@@ -0,0 +1,89 @@
+/**
+ * Copyright (c) 2014 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+/**
+ * @addtogroup ser_conn Connectivity application code
+ * @ingroup ble_sdk_lib_serialization
+ */
+
+/** @file
+ *
+ * @defgroup ser_cmd_decoder Command decoder in the Connectivity Chip
+ * @{
+ * @ingroup ser_conn
+ *
+ * @brief Decoder for serialized commands from the Application Chip.
+ *
+ * @details This file contains declaration of common function used for commands decoding and sending
+ * responses back to the Application Chip after a command is processed.
+ */
+
+#ifndef SER_CONN_CMD_DECODER_H__
+#define SER_CONN_CMD_DECODER_H__
+
+#include <stdint.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**@brief A function decodes an encoded command and sends a response to the Application Chip.
+ *
+ * @details The function decodes an encoded command and calls a SoftDevice API function when a
+ * command decoder is found or forms a common response with error code
+ * NRF_ERROR_NOT_SUPPORTED otherwise. Then the function sends a SoftDevice response or
+ * the response with NRF_ERROR_NOT_SUPPORTED error code to the Application Chip.
+ *
+ * @param[in] p_command The encoded command.
+ * @param[in] command_len Length of the encoded command including opcode.
+ *
+ * @retval NRF_SUCCESS Operation success.
+ * @retval NRF_ERROR_NULL Operation failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INTERNAL Operation failure. Internal error ocurred. .
+ */
+uint32_t ser_conn_command_process(uint8_t * p_command, uint16_t command_len);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* SER_CONN_CMD_DECODER_H__ */
+
+/** @} */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/connectivity/ser_conn_dtm_cmd_decoder.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/connectivity/ser_conn_dtm_cmd_decoder.c
new file mode 100644
index 0000000..8a76238
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/connectivity/ser_conn_dtm_cmd_decoder.c
@@ -0,0 +1,126 @@
+/**
+ * Copyright (c) 2014 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#include "app_util.h"
+#include "ble_dtm_conn.h"
+#include "ble_serialization.h"
+#include "nrf_error.h"
+#include "nrf_sdm.h"
+#include "ser_conn_dtm_cmd_decoder.h"
+#include "ser_conn_handlers.h"
+#include "ser_hal_transport.h"
+
+static bool m_is_ready_to_enter_dtm = false;
+static app_uart_stream_comm_params_t m_comm_params = { 0 };
+
+uint32_t ser_conn_dtm_command_process(uint8_t * p_command, uint16_t command_len)
+{
+ SER_ASSERT_NOT_NULL(p_command);
+
+ uint32_t err_code = NRF_SUCCESS;
+ uint8_t * p_tx_buf = NULL;
+ uint32_t tx_buf_len = 0;
+
+ /* Allocate a memory buffer from HAL Transport layer for transmitting the Command Response.
+ * Loop until a buffer is available. */
+ do
+ {
+ err_code = ser_hal_transport_tx_pkt_alloc(&p_tx_buf, (uint16_t *)&tx_buf_len);
+ if (err_code == NRF_ERROR_NO_MEM)
+ {
+ ser_conn_on_no_mem_handler();
+ }
+ }
+ while (NRF_ERROR_NO_MEM == err_code);
+
+ if (err_code == NRF_SUCCESS)
+ {
+ p_tx_buf[SER_PKT_TYPE_POS] = SER_PKT_TYPE_DTM_RESP;
+ tx_buf_len -= SER_PKT_TYPE_SIZE;
+
+ err_code = ble_dtm_init_req_dec(p_command, command_len, &m_comm_params);
+
+ if (NRF_SUCCESS == err_code)
+ {
+ err_code = ble_dtm_init_rsp_enc(NRF_SUCCESS,
+ &p_tx_buf[SER_PKT_TYPE_SIZE],
+ &tx_buf_len);
+
+ if (err_code != NRF_SUCCESS)
+ {
+ return NRF_ERROR_INTERNAL;
+ }
+
+ tx_buf_len += SER_PKT_TYPE_SIZE;
+
+ /* Set a flag that device is ready to enter DTM mode. */
+ m_is_ready_to_enter_dtm = true;
+
+ err_code = ser_hal_transport_tx_pkt_send(p_tx_buf, (uint16_t)tx_buf_len);
+ if (err_code != NRF_SUCCESS)
+ {
+ err_code = NRF_ERROR_INTERNAL;
+ }
+
+ /* TX buffer is going to be freed automatically in the HAL Transport layer. */
+ }
+ else
+ {
+ err_code = NRF_ERROR_INTERNAL;
+ }
+ }
+
+ return err_code;
+}
+
+
+void ser_conn_is_ready_to_enter_dtm(void)
+{
+ if (m_is_ready_to_enter_dtm)
+ {
+ /* Disable SoftDevice. */
+ (void)sd_softdevice_disable();
+
+ /* Close HAL Transport Layer. */
+ ser_hal_transport_close();
+
+ /* Start DTM mode. */
+ (void)dtm_start(m_comm_params);
+ }
+}
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/connectivity/ser_conn_dtm_cmd_decoder.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/connectivity/ser_conn_dtm_cmd_decoder.h
new file mode 100644
index 0000000..13e6bdb
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/connectivity/ser_conn_dtm_cmd_decoder.h
@@ -0,0 +1,98 @@
+/**
+ * Copyright (c) 2014 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+/**
+ * @addtogroup ser_conn Connectivity application code
+ * @ingroup ble_sdk_lib_serialization
+ */
+
+/** @file
+ *
+ * @defgroup ser_dtm_decoder DTM Command Decoder in the Connectivity Chip
+ * @{
+ * @ingroup ser_conn
+ *
+ * @brief Decoder for serialized DTM commands from the Application Chip.
+ *
+ * @details This file contains declaration of common function used for DTM commands decoding and
+ * sending responses back to the Application Chip after a DTM command is processed.
+ */
+
+#ifndef SER_CONN_DTM_CMD_DECODER_H__
+#define SER_CONN_DTM_CMD_DECODER_H__
+
+#include <stdint.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**@brief A function for processing the encoded DTM commands from the Application Chip.
+ *
+ * @details The function decodes encoded DTM commands and calls the appropriate DTM API.
+ * Then creates a DTM Command Response packet with the return value from the
+ * DTM API encoded in it and sends it to the Application Chip.
+ *
+ * @param[in] p_command The encoded command.
+ * @param[in] command_len Length of the encoded command.
+ *
+ * @retval NRF_SUCCESS If the decoding of the command was successful, the DTM API
+ * was called, and the command response was sent to peer, otherwise an
+ * error code.
+ */
+uint32_t ser_conn_dtm_command_process(uint8_t * p_command, uint16_t command_len);
+
+
+/**@brief A function for checking if the Connectivity Chip is ready to enter the DTM mode.
+ *
+ * @details The function checks if the Connectivity Chip is ready to enter into DTM mode.
+ * If it is ready, then it disables the SoftDevice, closes HAL Transport Layer,
+ * and starts DTM mode.
+ */
+void ser_conn_is_ready_to_enter_dtm(void);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* SER_CONN_DTM_CMD_DECODER_H__ */
+
+/** @} */
+
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/connectivity/ser_conn_error_handling.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/connectivity/ser_conn_error_handling.c
new file mode 100644
index 0000000..459bc14
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/connectivity/ser_conn_error_handling.c
@@ -0,0 +1,138 @@
+/**
+ * Copyright (c) 2014 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#include "nrf_assert.h"
+#include "app_error.h"
+#include "ser_config.h"
+
+#include "boards.h"
+
+/** @file
+ *
+ * @defgroup ser_conn_error_handling Errors handling for the Connectivity Chip.
+ * @{
+ * @ingroup sdk_lib_serialization
+ *
+ * @brief A module to handle the Connectivity Chip errors and warnings.
+ *
+ * @details This file contains definitions of functions used for handling the Connectivity Chip
+ * errors and warnings.
+ */
+
+/**@brief Function for handling the Connectivity Chip errors and warnings.
+ *
+ * @details This function will be called if the ASSERT macro in the connectivity application fails.
+ * Function declaration can be found in the app_error.h file.
+ *
+ * @param[in] error_code Error code supplied to the handler.
+ * @param[in] line_num Line number where the handler is called.
+ * @param[in] p_file_name Pointer to the file name.
+ */
+
+#include "app_util_platform.h"
+#include "nrf_soc.h"
+#include "nrf_log.h"
+#include "nrf_log_ctrl.h"
+
+// uint32_t m_error_code;
+// uint32_t m_error_line_num;
+// const uint8_t *m_p_error_file_name;
+
+/*lint -save -e14 */
+void app_error_fault_handler(uint32_t id, uint32_t pc, uint32_t info)
+{
+ // disable INTs
+ CRITICAL_REGION_ENTER();
+
+ NRF_LOG_ERROR("Fatal error");
+ NRF_LOG_FINAL_FLUSH();
+
+ #if LEDS_NUMBER > 0
+
+ /* Light a LED on error or warning. */
+ // nrf_gpio_cfg_output(SER_CONN_ASSERT_LED_PIN);
+ // nrf_gpio_pin_set(SER_CONN_ASSERT_LED_PIN);
+
+ #endif
+
+ // m_p_error_file_name = p_file_name;
+ // m_error_code = error_code;
+ // m_error_line_num = line_num;
+
+ /* Do not reset when warning. */
+ if (SER_WARNING_CODE != id)
+ {
+ /* This call can be used for debug purposes during application development.
+ * @note CAUTION: Activating code below will write the stack to flash on an error.
+ * This function should NOT be used in a final product.
+ * It is intended STRICTLY for development/debugging purposes.
+ * The flash write will happen EVEN if the radio is active, thus interrupting any communication.
+ * Use with care. Un-comment the line below to use. */
+
+ /* ble_debug_assert_handler(error_code, line_num, p_file_name); */
+
+#ifndef DEBUG
+ /* Reset the chip. Should be used in the release version. */
+ NVIC_SystemReset();
+#else /* Debug version. */
+ /* To be able to see function parameters in a debugger. */
+ uint32_t temp = 1;
+ while (temp);
+#endif
+
+ }
+
+ CRITICAL_REGION_EXIT();
+}
+/*lint -restore */
+
+
+/**@brief Callback function for asserts in the SoftDevice.
+ *
+ * @details This function will be called if the ASSERT macro in the SoftDevice fails. Function
+ * declaration can be found in the nrf_assert.h file.
+ *
+ * @param[in] line_num Line number of the failing ASSERT call.
+ * @param[in] p_file_name File name of the failing ASSERT call.
+ */
+void assert_nrf_callback(uint16_t line_num, const uint8_t * p_file_name)
+{
+ app_error_handler(SER_SD_ERROR_CODE, line_num, p_file_name);
+}
+/** @} */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/connectivity/ser_conn_event_encoder.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/connectivity/ser_conn_event_encoder.c
new file mode 100644
index 0000000..c6a0a37
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/connectivity/ser_conn_event_encoder.c
@@ -0,0 +1,169 @@
+/**
+ * Copyright (c) 2014 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#include <string.h>
+#include <stdint.h>
+#include "app_error.h"
+#include "app_scheduler.h"
+#include "ble_serialization.h"
+#include "ser_config.h"
+#include "ser_hal_transport.h"
+#include "ser_conn_event_encoder.h"
+#include "ser_conn_handlers.h"
+#ifdef BLE_STACK_SUPPORT_REQD
+#include "ble_conn.h"
+#endif // BLE_STACK_SUPPORT_REQD
+
+#ifdef ANT_STACK_SUPPORT_REQD
+#include "ant_event.h"
+#endif // ANT_STACK_SUPPORT_REQD
+
+#ifdef BLE_STACK_SUPPORT_REQD
+void ser_conn_ble_event_encoder(void * p_event_data, uint16_t event_size)
+{
+ if (NULL == p_event_data)
+ {
+ APP_ERROR_CHECK(NRF_ERROR_NULL);
+ }
+ UNUSED_PARAMETER(event_size);
+
+ uint32_t err_code = NRF_SUCCESS;
+ uint8_t * p_tx_buf = NULL;
+ uint32_t tx_buf_len = 0;
+ ble_evt_t * p_ble_evt = (ble_evt_t *)p_event_data;
+
+ /* Allocate a memory buffer from HAL Transport layer for transmitting an event.
+ * Loop until a buffer is available. */
+ do
+ {
+ err_code = ser_hal_transport_tx_pkt_alloc(&p_tx_buf, (uint16_t *)&tx_buf_len);
+ if (err_code == NRF_ERROR_NO_MEM)
+ {
+ ser_conn_on_no_mem_handler();
+ }
+ }
+ while (err_code == NRF_ERROR_NO_MEM);
+ APP_ERROR_CHECK(err_code);
+
+ /* Create a new packet. */
+ p_tx_buf[SER_PKT_TYPE_POS] = SER_PKT_TYPE_EVT;
+ tx_buf_len -= SER_PKT_TYPE_SIZE;
+
+ /* Pass a memory for an event (opcode + data) and encode it. */
+ err_code = ble_event_enc(p_ble_evt, 0, &p_tx_buf[SER_PKT_OP_CODE_POS], &tx_buf_len);
+
+ if (NRF_ERROR_NOT_SUPPORTED != err_code)
+ {
+ APP_ERROR_CHECK(err_code);
+ tx_buf_len += SER_PKT_TYPE_SIZE;
+ err_code = ser_hal_transport_tx_pkt_send(p_tx_buf, (uint16_t)tx_buf_len);
+ APP_ERROR_CHECK(err_code);
+ /* TX buffer is going to be freed automatically in the HAL Transport layer.
+ * Scheduler must be paused because this function returns before a packet is physically sent
+ * by transport layer. This can cause start processing of a next event from the application
+ * scheduler queue. In result the next event reserves the TX buffer before the current
+ * packet is sent. If in meantime a command arrives a command response cannot be sent in
+ * result. Pausing the scheduler temporary prevents processing a next event. */
+ app_sched_pause();
+ }
+ else
+ {
+ /* Event was NOT encoded, therefore the buffer is freed immediately. */
+ err_code = ser_hal_transport_tx_pkt_free(p_tx_buf);
+ APP_ERROR_CHECK(err_code);
+ APP_ERROR_CHECK(SER_WARNING_CODE);
+ }
+}
+#endif // BLE_STACK_SUPPORT_REQD
+
+#ifdef ANT_STACK_SUPPORT_REQD
+void ser_conn_ant_event_encoder(void * p_event_data, uint16_t event_size)
+{
+
+ if (NULL == p_event_data)
+ {
+ APP_ERROR_CHECK(NRF_ERROR_NULL);
+ }
+ UNUSED_PARAMETER(event_size);
+
+ uint32_t err_code = NRF_SUCCESS;
+ uint8_t * p_tx_buf = NULL;
+ uint32_t tx_buf_len = 0;
+ ant_evt_t * p_ant_evt = (ant_evt_t *)p_event_data;
+
+ /* Allocate a memory buffer from HAL Transport layer for transmitting an event.
+ * Loop until a buffer is available. */
+ do
+ {
+ err_code = ser_hal_transport_tx_pkt_alloc(&p_tx_buf, (uint16_t *)&tx_buf_len);
+ }
+ while (err_code == NRF_ERROR_NO_MEM);
+ APP_ERROR_CHECK(err_code);
+
+ /* Create a new packet. */
+ p_tx_buf[SER_PKT_TYPE_POS] = SER_PKT_TYPE_ANT_EVT;
+ tx_buf_len -= SER_PKT_TYPE_SIZE;
+
+ /* Pass a memory for an event (opcode + data) and encode it. */
+ err_code = ant_event_enc(p_ant_evt, 0, &p_tx_buf[SER_PKT_OP_CODE_POS], &tx_buf_len);
+
+ if (NRF_ERROR_NOT_SUPPORTED != err_code)
+ {
+ APP_ERROR_CHECK(err_code);
+ tx_buf_len += SER_PKT_TYPE_SIZE;
+ err_code = ser_hal_transport_tx_pkt_send(p_tx_buf, (uint16_t)tx_buf_len);
+ APP_ERROR_CHECK(err_code);
+ /* TX buffer is going to be freed automatically in the HAL Transport layer.
+ * Scheduler must be paused because this function returns before a packet is physically sent
+ * by transport layer. This can cause start processing of a next event from the application
+ * scheduler queue. In result the next event reserves the TX buffer before the current
+ * packet is sent. If in meantime a command arrives a command response cannot be sent in
+ * result. Pausing the scheduler temporary prevents processing a next event. */
+ app_sched_pause();
+ }
+ else
+ {
+ /* Event was NOT encoded, therefore the buffer is freed immediately. */
+ err_code = ser_hal_transport_tx_pkt_free(p_tx_buf);
+ APP_ERROR_CHECK(err_code);
+ APP_ERROR_CHECK(SER_WARNING_CODE);
+ }
+
+}
+#endif
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/connectivity/ser_conn_event_encoder.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/connectivity/ser_conn_event_encoder.h
new file mode 100644
index 0000000..b5bf698
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/connectivity/ser_conn_event_encoder.h
@@ -0,0 +1,99 @@
+/**
+ * Copyright (c) 2014 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+/**
+ * @addtogroup ser_conn Connectivity application code
+ * @ingroup ble_sdk_lib_serialization
+ * @brief Encoders, decoders, and event handlers related to the Connectivity Chip.
+ */
+
+/** @file
+ *
+ * @defgroup ser_event_encoder Events encoder in the Connectivity Chip
+ * @{
+ * @ingroup ser_conn
+ *
+ * @brief Events encoder for BLE SoftDevice.
+ *
+ * @details This file contains declaration of common function used for serializing BLE SoftDevice
+ * events.
+ *
+ */
+#ifndef SER_CONN_EVENT_ENCODER_H__
+#define SER_CONN_EVENT_ENCODER_H__
+
+#include <stdint.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**@brief A function for encoding a @ref ble_evt_t. The function passes the serialized byte stream
+ * to the transport layer after encoding.
+ *
+ * @details The function is called by the application scheduler to process an event previously
+ * pulled from BLE SoftDevice.
+ * The function creates a new packet, calls an appropriate event encoder and sends the
+ * packet to the Application Chip.
+ *
+ * @param[in] p_event_data Pointer to event data of type @ref ble_evt_t.
+ * @param[in] event_size Event data size.
+ */
+void ser_conn_ble_event_encoder(void * p_event_data, uint16_t event_size);
+
+/**@brief A function for encoding a @ref ant_evt_t. The function passes the serialized byte stream
+ * to the transport layer after encoding.
+ *
+ * @details The function is called by the application scheduler to process an event previously
+ * pulled from ANT SoftDevice.
+ * The function creates a new packet, calls an appropriate event encoder and sends the
+ * packet to the Application Chip.
+ *
+ * @param[in] p_event_data Pointer to event data of type @ref ant_evt_t.
+ * @param[in] event_size Event data size.
+ */
+void ser_conn_ant_event_encoder(void * p_event_data, uint16_t event_size);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* SER_CONN_EVENT_ENCODER_H__ */
+
+/** @} */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/connectivity/ser_conn_handlers.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/connectivity/ser_conn_handlers.c
new file mode 100644
index 0000000..fbcf901
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/connectivity/ser_conn_handlers.c
@@ -0,0 +1,207 @@
+/**
+ * Copyright (c) 2014 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#include <string.h>
+#include "app_error.h"
+#include "app_scheduler.h"
+#include "ser_config.h"
+#include "ser_conn_handlers.h"
+#include "ser_conn_event_encoder.h"
+#include "ser_conn_pkt_decoder.h"
+#include "ser_conn_dtm_cmd_decoder.h"
+#include "nrf_sdh.h"
+#ifdef BLE_STACK_SUPPORT_REQD
+#include "conn_ble_gap_sec_keys.h"
+#endif
+
+/** @file
+ *
+ * @defgroup ser_conn_handlers Events handlers for the Connectivity Chip.
+ * @{
+ * @ingroup sdk_lib_serialization
+ *
+ * @brief A module to handle the Connectivity application events.
+ *
+ * @details There are two types of events in the Connectivity application: BLE events generated by
+ * the SoftDevice and events generated by the HAL Transport layer.
+ */
+
+/** Parameters of a received packet. */
+static ser_hal_transport_evt_rx_pkt_received_params_t m_rx_pkt_received_params;
+
+/** Indicator of received packet that should be process. */
+static bool m_rx_pkt_to_process = false;
+
+static ser_conn_on_no_mem_t m_on_no_mem_handler;
+
+void ser_conn_on_no_mem_handler_set(ser_conn_on_no_mem_t handler)
+{
+ m_on_no_mem_handler = handler;
+}
+
+void ser_conn_on_no_mem_handler(void)
+{
+ if (m_on_no_mem_handler)
+ {
+ m_on_no_mem_handler();
+ }
+}
+void ser_conn_hal_transport_event_handle(ser_hal_transport_evt_t event)
+{
+ switch (event.evt_type)
+ {
+ case SER_HAL_TRANSP_EVT_TX_PKT_SENT:
+ {
+ /* SoftDevice event or response to received packet was sent, so unblock the application
+ * scheduler to process a next event. */
+ app_sched_resume();
+
+ /* Check if chip is ready to enter DTM mode. */
+ ser_conn_is_ready_to_enter_dtm();
+
+ break;
+ }
+
+ case SER_HAL_TRANSP_EVT_RX_PKT_RECEIVING:
+ {
+ /* The connectivity side has started receiving a packet. Temporary block processing
+ * SoftDevice events. It is going to be unblocked when a response for the packet will
+ * be sent. This prevents communication block. */
+ app_sched_pause();
+ break;
+ }
+
+ case SER_HAL_TRANSP_EVT_RX_PKT_RECEIVED:
+ {
+ /* We can NOT add received packets as events to the application scheduler queue because
+ * received packets have to be processed before SoftDevice events but the scheduler
+ * queue do not have priorities. */
+ memcpy(&m_rx_pkt_received_params, &event.evt_params.rx_pkt_received,
+ sizeof (ser_hal_transport_evt_rx_pkt_received_params_t));
+ m_rx_pkt_to_process = true;
+ break;
+ }
+
+ case SER_HAL_TRANSP_EVT_RX_PKT_DROPPED:
+ {
+ APP_ERROR_CHECK(SER_WARNING_CODE);
+ break;
+ }
+
+ case SER_HAL_TRANSP_EVT_PHY_ERROR:
+ {
+ APP_ERROR_CHECK(NRF_ERROR_FORBIDDEN);
+ break;
+ }
+
+ default:
+ {
+ /* do nothing */
+ break;
+ }
+ }
+}
+
+
+uint32_t ser_conn_rx_process(void)
+{
+ uint32_t err_code = NRF_SUCCESS;
+
+ if (m_rx_pkt_to_process)
+ {
+ /* No critical section needed on m_rx_pkt_to_process parameter because it is not possible
+ * to get next packet before sending a response. */
+ m_rx_pkt_to_process = false;
+ err_code = ser_conn_received_pkt_process(&m_rx_pkt_received_params);
+ }
+
+ return err_code;
+}
+
+#ifdef BLE_STACK_SUPPORT_REQD
+
+NRF_SDH_BLE_OBSERVER(m_ble_observer, 0, ser_conn_ble_event_handle, NULL);
+
+void ser_conn_ble_event_handle(ble_evt_t const * p_ble_evt, void * p_context)
+{
+ uint32_t err_code = NRF_SUCCESS;
+
+ /* We can NOT encode and send BLE events here. SoftDevice handler implemented in
+ * softdevice_handler.c pull all available BLE events at once but we need to reschedule between
+ * encoding and sending every BLE event because sending a response on received packet has higher
+ * priority than sending a BLE event. Solution for that is to put BLE events into application
+ * scheduler queue to be processed at a later time. */
+ err_code = app_sched_event_put(p_ble_evt, p_ble_evt->header.evt_len,
+ ser_conn_ble_event_encoder);
+ APP_ERROR_CHECK(err_code);
+ uint16_t free_space = app_sched_queue_space_get();
+ if (!free_space)
+ {
+ // Queue is full. Do not pull new events.
+ nrf_sdh_suspend();
+ }
+}
+#endif // BLE_STACK_SUPPORT_REQD
+
+#ifdef ANT_STACK_SUPPORT_REQD
+
+NRF_SDH_ANT_OBSERVER(m_ant_observer, 0, ser_conn_ant_event_handle, NULL);
+
+void ser_conn_ant_event_handle(ant_evt_t * p_ant_evt, void * p_context)
+{
+ uint32_t err_code = NRF_SUCCESS;
+
+ /* We can NOT encode and send ANT events here. SoftDevice handler implemented in
+ * softdevice_handler.c pull all available ANT events at once but we need to reschedule between
+ * encoding and sending every ANT event because sending a response on received packet has higher
+ * priority than sending an ANT event. Solution for that is to put ANT events into application
+ * scheduler queue to be processed at a later time. */
+ err_code = app_sched_event_put(p_ant_evt, sizeof (ant_evt_t),
+ ser_conn_ant_event_encoder);
+ APP_ERROR_CHECK(err_code);
+ uint16_t free_space = app_sched_queue_space_get();
+ if (!free_space)
+ {
+ // Queue is full. Do not pull new events.
+ nrf_sdh_suspend();
+ }
+}
+#endif // ANT_STACK_SUPPORT_REQD
+
+/** @} */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/connectivity/ser_conn_handlers.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/connectivity/ser_conn_handlers.h
new file mode 100644
index 0000000..7843a71
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/connectivity/ser_conn_handlers.h
@@ -0,0 +1,162 @@
+/**
+ * Copyright (c) 2014 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+/**
+ * @addtogroup ser_conn Connectivity application code
+ * @ingroup ble_sdk_lib_serialization
+ */
+
+
+/** @file
+ *
+ * @defgroup ser_conn_handlers Events handlers in the Connectivity Chip
+ * @{
+ * @ingroup ser_conn
+ *
+ * @brief Events handlers used to process high level events in the connectivity application.
+ *
+ * @details This file contains functions: processing the HAL Transport layer events, processing BLE
+ * SoftDevice events, starting processing received packets.
+ */
+
+#ifndef SER_CONN_HANDLERS_H__
+#define SER_CONN_HANDLERS_H__
+
+#include <stdint.h>
+#include "nordic_common.h"
+#include "app_util.h"
+#include "ser_hal_transport.h"
+
+#ifdef BLE_STACK_SUPPORT_REQD
+#include "ble.h"
+#include "nrf_sdh_ble.h"
+#endif // BLE_STACK_SUPPORT_REQD
+
+#ifdef ANT_STACK_SUPPORT_REQD
+#include "nrf_sdh_ant.h"
+#endif // ANT_STACK_SUPPORT_REQD
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Maximum number of events in the application scheduler queue. */
+#define SER_CONN_SCHED_QUEUE_SIZE 4u
+
+/** Maximum size of events data in the application scheduler queue aligned to 32 bits - this is
+ * size of the buffers of the SoftDevice handler, which stores events pulled from the SoftDevice.
+ */
+
+#if defined(BLE_STACK_SUPPORT_REQD) && defined(ANT_STACK_SUPPORT_REQD)
+#define STACK_EVENT_MAX_SIZE MAX(NRF_SDH_BLE_EVT_BUF_SIZE, NRF_SDH_ANT_EVT_BUF_SIZE)
+#elif defined(BLE_STACK_SUPPORT_REQD)
+#define STACK_EVENT_MAX_SIZE NRF_SDH_BLE_EVT_BUF_SIZE
+#elif defined(ANT_STACK_SUPPORT_REQD)
+#define STACK_EVENT_MAX_SIZE NRF_SDH_ANT_EVT_BUF_SIZE
+#endif
+
+
+#define SER_CONN_SCHED_MAX_EVENT_DATA_SIZE ((CEIL_DIV(MAX(STACK_EVENT_MAX_SIZE, \
+ sizeof(uint32_t)), \
+ sizeof(uint32_t))) * \
+ sizeof(uint32_t))
+
+/** @brief Prototype for function called when there is no free TX buffer and system is blocked */
+typedef void (*ser_conn_on_no_mem_t)(void);
+
+/**
+ * @brief A function for setting handler which should be called when serialization
+ * is blocked waiting for TX buffer.
+ *
+ * @param handler Handler to be called whenever serialization failed to allocate TX buffer
+ *
+ */
+void ser_conn_on_no_mem_handler_set(ser_conn_on_no_mem_t handler);
+
+/**
+ * @brief A function called when TX buffer allocation failed. Serialization is always allocating TX
+ * buffer in main context expecting that it will be freed from interrupt context.
+ */
+void ser_conn_on_no_mem_handler(void);
+
+
+/**@brief A function for processing the HAL Transport layer events.
+ *
+ * @param[in] event HAL Transport layer event.
+ */
+void ser_conn_hal_transport_event_handle(ser_hal_transport_evt_t event);
+
+
+/**@brief A function to call the function to process a packet when it is fully received.
+ *
+ * @retval NRF_SUCCESS Operation success.
+ * @retval NRF_ERROR_NULL Operation failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INTERNAL Operation failure. Internal error ocurred.
+ */
+uint32_t ser_conn_rx_process(void);
+
+
+#ifdef BLE_STACK_SUPPORT_REQD
+/**@brief A function for processing BLE SoftDevice events.
+ *
+ * @details BLE events are put into application scheduler queue to be processed at a later time.
+ *
+ * @param[in] p_ble_evt A pointer to a BLE event.
+ * @param[in] p_context A parameter to the handler. Not used.
+ */
+void ser_conn_ble_event_handle(ble_evt_t const * p_ble_evt, void * p_context);
+#endif // BLE_STACK_SUPPORT_REQD
+
+#ifdef ANT_STACK_SUPPORT_REQD
+/**@brief A function for processing ANT SoftDevice events.
+ *
+ * @details ANT events are put into application scheduler queue to be processed at a later time.
+ *
+ * @param[in] p_ant_evt A pointer to a BLE event.
+ * @param[in] p_context A parameter to the handler. Not used.
+ */
+void ser_conn_ant_event_handle(ant_evt_t * p_ant_evt, void * p_context);
+#endif // ANT_STACK_SUPPORT_REQD
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* SER_CONN_HANDLERS_H__ */
+/** @} */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/connectivity/ser_conn_pkt_decoder.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/connectivity/ser_conn_pkt_decoder.c
new file mode 100644
index 0000000..4ddd558
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/connectivity/ser_conn_pkt_decoder.c
@@ -0,0 +1,124 @@
+/**
+ * Copyright (c) 2014 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#include <stdint.h>
+#include <string.h>
+#include "nordic_common.h"
+#include "app_error.h"
+#include "ble_serialization.h"
+#include "ser_config.h"
+#include "ser_hal_transport.h"
+#include "ser_conn_pkt_decoder.h"
+#include "ser_conn_cmd_decoder.h"
+#include "ser_conn_dtm_cmd_decoder.h"
+#include "ser_conn_reset_cmd_decoder.h"
+#include "ser_dbg_sd_str.h"
+
+#define NRF_LOG_MODULE_NAME ser_conn
+#include "nrf_log.h"
+NRF_LOG_MODULE_REGISTER();
+
+uint32_t ser_conn_received_pkt_process(
+ ser_hal_transport_evt_rx_pkt_received_params_t * p_rx_pkt_params)
+{
+ uint32_t err_code = NRF_SUCCESS;
+
+ if (NULL != p_rx_pkt_params)
+ {
+ /* For further processing pass only command (opcode + data). */
+ uint8_t * p_command = &p_rx_pkt_params->p_buffer[SER_PKT_OP_CODE_POS];
+ uint16_t command_len = p_rx_pkt_params->num_of_bytes - SER_PKT_TYPE_SIZE;
+
+ NRF_LOG_DEBUG("[SD_CALL]:%s",
+ (uint32_t)ser_dbg_sd_call_str_get(*p_command));
+
+ switch (p_rx_pkt_params->p_buffer[SER_PKT_TYPE_POS])
+ {
+ #if defined(ANT_STACK_SUPPORT_REQD)
+ case SER_PKT_TYPE_ANT_CMD:
+ //!! INTENTIONAL FALLTHROUGH
+ #endif
+ case SER_PKT_TYPE_CMD:
+ {
+ err_code = ser_conn_command_process(p_command, command_len);
+ break;
+ }
+
+ case SER_PKT_TYPE_DTM_CMD:
+ {
+ err_code = ser_conn_dtm_command_process(p_command, command_len);
+ break;
+ }
+
+ case SER_PKT_TYPE_RESET_CMD:
+ {
+ ser_conn_reset_command_process();
+ break;
+ }
+
+ default:
+ {
+ APP_ERROR_CHECK(SER_WARNING_CODE);
+ break;
+ }
+ }
+
+ if (NRF_SUCCESS == err_code)
+ {
+ /* Free a received packet. */
+ err_code = ser_hal_transport_rx_pkt_free(p_rx_pkt_params->p_buffer);
+
+ if (NRF_SUCCESS != err_code)
+ {
+ err_code = NRF_ERROR_INTERNAL;
+ }
+ }
+ else
+ {
+ NRF_LOG_ERROR("Command processing error:%d", err_code);
+ err_code = NRF_ERROR_INTERNAL;
+ }
+ }
+ else
+ {
+ err_code = NRF_ERROR_NULL;
+ }
+
+ return err_code;
+}
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/connectivity/ser_conn_pkt_decoder.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/connectivity/ser_conn_pkt_decoder.h
new file mode 100644
index 0000000..bf612ba
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/connectivity/ser_conn_pkt_decoder.h
@@ -0,0 +1,90 @@
+/**
+ * Copyright (c) 2014 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+/**
+ * @addtogroup ser_conn Connectivity application code
+ * @ingroup ble_sdk_lib_serialization
+ */
+
+/** @file
+ *
+ * @defgroup ser_pkt_decoder Packets decoder in the Connectivity Chip
+ * @{
+ * @ingroup ser_conn
+ *
+ * @brief Decoder for serialized packets from the Application Chip.
+ *
+ * @details This file contains declaration of common function used for processing packets (packets
+ * dispatcher) received by the transport layer.
+ */
+
+#ifndef SER_CONN_PKT_DECODER_H__
+#define SER_CONN_PKT_DECODER_H__
+
+#include <stdint.h>
+#include "ser_hal_transport.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**@brief A function for dispatching packets from the Application Chip to an appropriate decoder.
+ *
+ * @details The function is called to process received packets from a transport layer.
+ * The function analyzes packet type and calls appropriate command decoder which among
+ * other things processes command and sends a response. Then a received packet is freed.
+ *
+ * @param[in] p_rx_pkt_params A pointer to a transport layer event of type
+ * @ref ser_hal_transport_evt_rx_pkt_received_params_t.
+ *
+ * @retval NRF_SUCCESS Operation success.
+ * @retval NRF_ERROR_NULL Operation failure. NULL pointer supplied.
+ * @retval NRF_ERROR_INTERNAL Operation failure. Internal error ocurred.
+ */
+uint32_t ser_conn_received_pkt_process(
+ ser_hal_transport_evt_rx_pkt_received_params_t * p_rx_pkt_params);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* SER_CONN_PKT_DECODER_H__ */
+
+/** @} */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/connectivity/ser_conn_reset_cmd_decoder.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/connectivity/ser_conn_reset_cmd_decoder.c
new file mode 100644
index 0000000..924a932
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/connectivity/ser_conn_reset_cmd_decoder.c
@@ -0,0 +1,47 @@
+/**
+ * Copyright (c) 2014 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#include "nrf_nvic.h"
+#include "ser_conn_reset_cmd_decoder.h"
+
+void ser_conn_reset_command_process()
+{
+ (void)sd_nvic_SystemReset();
+ while (1);
+}
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/connectivity/ser_conn_reset_cmd_decoder.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/connectivity/ser_conn_reset_cmd_decoder.h
new file mode 100644
index 0000000..6d539cd
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/serialization/connectivity/ser_conn_reset_cmd_decoder.h
@@ -0,0 +1,81 @@
+/**
+ * Copyright (c) 2014 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+/**
+ * @addtogroup ser_conn Connectivity application code
+ * @ingroup ble_sdk_lib_serialization
+ */
+
+/** @file
+ *
+ * @defgroup ser_reset_cmd_decoder Reset Command Decoder in the connectivity chip
+ * @{
+ * @ingroup ser_conn
+ *
+ * @brief Decoder for serialized reset command from the Application Chip.
+ *
+ * @details This file contains declaration of common function used for reset command decoding and
+ * sending responses back to the Application Chip after a command is processed.
+ */
+
+#ifndef SER_CONN_RESET_CMD_DECODER_H__
+#define SER_CONN_RESET_CMD_DECODER_H__
+
+#include <stdint.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**@brief A function for processing the encoded reset commands from the Application Chip.
+ *
+ * @details The function decodes encoded system reset command and performs software reset.
+ * This command does not send back the Command Response packet to the Application Chip.
+ */
+void ser_conn_reset_command_process(void);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* SER_CONN_RESET_CMD_DECODER_H__ */
+
+/** @} */
+
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/softdevice/common/nrf_sdh.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/softdevice/common/nrf_sdh.c
new file mode 100644
index 0000000..39a861f
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/softdevice/common/nrf_sdh.c
@@ -0,0 +1,430 @@
+/**
+ * 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+
+#include "sdk_common.h"
+#if NRF_MODULE_ENABLED(NRF_SDH)
+
+#include "nrf_sdh.h"
+
+#include <stdint.h>
+
+#include "nrf_sdm.h"
+#include "nrf_nvic.h"
+#include "sdk_config.h"
+#include "app_error.h"
+#include "app_util_platform.h"
+
+
+#define NRF_LOG_MODULE_NAME nrf_sdh
+#if NRF_SDH_LOG_ENABLED
+ #define NRF_LOG_LEVEL NRF_SDH_LOG_LEVEL
+ #define NRF_LOG_INFO_COLOR NRF_SDH_INFO_COLOR
+ #define NRF_LOG_DEBUG_COLOR NRF_SDH_DEBUG_COLOR
+#else
+ #define NRF_LOG_LEVEL 0
+#endif // NRF_SDH_LOG_ENABLED
+#include "nrf_log.h"
+NRF_LOG_MODULE_REGISTER();
+
+
+// Validate configuration options.
+
+#if (NRF_SDH_DISPATCH_MODEL == NRF_SDH_DISPATCH_MODEL_APPSH)
+ #if (!APP_SCHEDULER_ENABLED)
+ #error app_scheduler is required when NRF_SDH_DISPATCH_MODEL is set to NRF_SDH_DISPATCH_MODEL_APPSH
+ #endif
+ #include "app_scheduler.h"
+#endif
+
+#if ( (NRF_SDH_CLOCK_LF_SRC == NRF_CLOCK_LF_SRC_RC) \
+ && (NRF_SDH_CLOCK_LF_ACCURACY != NRF_CLOCK_LF_ACCURACY_500_PPM))
+ #warning Please select NRF_CLOCK_LF_ACCURACY_500_PPM when using NRF_CLOCK_LF_SRC_RC
+#endif
+
+
+// Create section "sdh_req_observers".
+NRF_SECTION_SET_DEF(sdh_req_observers, nrf_sdh_req_observer_t, NRF_SDH_REQ_OBSERVER_PRIO_LEVELS);
+
+// Create section "sdh_state_observers".
+NRF_SECTION_SET_DEF(sdh_state_observers, nrf_sdh_state_observer_t, NRF_SDH_STATE_OBSERVER_PRIO_LEVELS);
+
+// Create section "sdh_stack_observers".
+NRF_SECTION_SET_DEF(sdh_stack_observers, nrf_sdh_stack_observer_t, NRF_SDH_STACK_OBSERVER_PRIO_LEVELS);
+
+
+static bool m_nrf_sdh_enabled; /**< Variable to indicate whether the SoftDevice is enabled. */
+static bool m_nrf_sdh_suspended; /**< Variable to indicate whether this module is suspended. */
+static bool m_nrf_sdh_continue; /**< Variable to indicate whether enable/disable process was started. */
+
+
+/**@brief Function for notifying request observers.
+ *
+ * @param[in] evt Type of request event.
+ */
+static ret_code_t sdh_request_observer_notify(nrf_sdh_req_evt_t req)
+{
+ nrf_section_iter_t iter;
+
+ NRF_LOG_DEBUG("State request: 0x%08X", req);
+
+ for (nrf_section_iter_init(&iter, &sdh_req_observers);
+ nrf_section_iter_get(&iter) != NULL;
+ nrf_section_iter_next(&iter))
+ {
+ nrf_sdh_req_observer_t * p_observer;
+ nrf_sdh_req_evt_handler_t handler;
+
+ p_observer = (nrf_sdh_req_observer_t *) nrf_section_iter_get(&iter);
+ handler = p_observer->handler;
+
+ if (handler(req, p_observer->p_context))
+ {
+ NRF_LOG_DEBUG("Notify observer 0x%08X => ready", p_observer);
+ }
+ else
+ {
+ // Process is stopped.
+ NRF_LOG_DEBUG("Notify observer 0x%08X => blocking", p_observer);
+ return NRF_ERROR_BUSY;
+ }
+ }
+ return NRF_SUCCESS;
+}
+
+
+/**@brief Function for stage request observers.
+ *
+ * @param[in] evt Type of stage event.
+ */
+static void sdh_state_observer_notify(nrf_sdh_state_evt_t evt)
+{
+ nrf_section_iter_t iter;
+
+ NRF_LOG_DEBUG("State change: 0x%08X", evt);
+
+ for (nrf_section_iter_init(&iter, &sdh_state_observers);
+ nrf_section_iter_get(&iter) != NULL;
+ nrf_section_iter_next(&iter))
+ {
+ nrf_sdh_state_observer_t * p_observer;
+ nrf_sdh_state_evt_handler_t handler;
+
+ p_observer = (nrf_sdh_state_observer_t *) nrf_section_iter_get(&iter);
+ handler = p_observer->handler;
+
+ handler(evt, p_observer->p_context);
+ }
+}
+
+
+static void softdevices_evt_irq_enable(void)
+{
+#ifdef SOFTDEVICE_PRESENT
+ ret_code_t ret_code = sd_nvic_EnableIRQ((IRQn_Type)SD_EVT_IRQn);
+ APP_ERROR_CHECK(ret_code);
+#else
+ // In case of serialization, NVIC must be accessed directly.
+ NVIC_EnableIRQ(SD_EVT_IRQn);
+#endif
+}
+
+
+static void softdevice_evt_irq_disable(void)
+{
+#ifdef SOFTDEVICE_PRESENT
+ ret_code_t ret_code = sd_nvic_DisableIRQ((IRQn_Type)SD_EVT_IRQn);
+ APP_ERROR_CHECK(ret_code);
+#else
+ // In case of serialization, NVIC must be accessed directly.
+ NVIC_DisableIRQ(SD_EVT_IRQn);
+#endif
+}
+
+
+#ifndef S140
+static void swi_interrupt_priority_workaround(void)
+{
+ // The priority of SoftDevice SWI SD_EVT_IRQn and RADIO_NOTIFICATION_IRQn in
+ // S132 v5.0.0, S112 v5.0.0, S212 v5.0.0 and S332 v5.0.0 is set to 6.
+ // Change it to APP_IRQ_PRIORITY_LOWEST (7) so that they do not preempt peripherals' interrupts.
+
+#ifdef SOFTDEVICE_PRESENT
+ ret_code_t ret_code;
+ ret_code = sd_nvic_SetPriority(SD_EVT_IRQn, APP_IRQ_PRIORITY_LOWEST);
+ APP_ERROR_CHECK(ret_code);
+ ret_code = sd_nvic_SetPriority(RADIO_NOTIFICATION_IRQn, APP_IRQ_PRIORITY_LOWEST);
+ APP_ERROR_CHECK(ret_code);
+#else
+ // In case of serialization, NVIC must be accessed directly.
+ NVIC_SetPriority(SD_EVT_IRQn, APP_IRQ_PRIORITY_LOWEST);
+ NVIC_SetPriority(RADIO_NOTIFICATION_IRQn, APP_IRQ_PRIORITY_LOWEST);
+#endif
+}
+#endif
+
+
+ret_code_t nrf_sdh_enable_request(void)
+{
+ ret_code_t ret_code;
+
+ if (m_nrf_sdh_enabled)
+ {
+ return NRF_ERROR_INVALID_STATE;
+ }
+
+ m_nrf_sdh_continue = true;
+
+ // Notify observers about SoftDevice enable request.
+ if (sdh_request_observer_notify(NRF_SDH_EVT_ENABLE_REQUEST) == NRF_ERROR_BUSY)
+ {
+ // Enable process was stopped.
+ return NRF_SUCCESS;
+ }
+
+ // Notify observers about starting SoftDevice enable process.
+ sdh_state_observer_notify(NRF_SDH_EVT_STATE_ENABLE_PREPARE);
+
+ nrf_clock_lf_cfg_t const clock_lf_cfg =
+ {
+ .source = NRF_SDH_CLOCK_LF_SRC,
+ .rc_ctiv = NRF_SDH_CLOCK_LF_RC_CTIV,
+ .rc_temp_ctiv = NRF_SDH_CLOCK_LF_RC_TEMP_CTIV,
+ .accuracy = NRF_SDH_CLOCK_LF_ACCURACY
+ };
+
+ CRITICAL_REGION_ENTER();
+#ifdef ANT_LICENSE_KEY
+ ret_code = sd_softdevice_enable(&clock_lf_cfg, app_error_fault_handler, ANT_LICENSE_KEY);
+#else
+ ret_code = sd_softdevice_enable(&clock_lf_cfg, app_error_fault_handler);
+#endif
+ m_nrf_sdh_enabled = (ret_code == NRF_SUCCESS);
+ CRITICAL_REGION_EXIT();
+
+ if (ret_code != NRF_SUCCESS)
+ {
+ return ret_code;
+ }
+
+ m_nrf_sdh_continue = false;
+ m_nrf_sdh_suspended = false;
+
+#ifndef S140
+ // Set the interrupt priority after enabling the SoftDevice, since
+ // sd_softdevice_enable() sets the SoftDevice interrupt priority.
+ swi_interrupt_priority_workaround();
+#endif
+
+ // Enable event interrupt.
+ // Interrupt priority has already been set by the stack.
+ softdevices_evt_irq_enable();
+
+ // Notify observers about a finished SoftDevice enable process.
+ sdh_state_observer_notify(NRF_SDH_EVT_STATE_ENABLED);
+
+ return NRF_SUCCESS;
+}
+
+
+ret_code_t nrf_sdh_disable_request(void)
+{
+ ret_code_t ret_code;
+
+ if (!m_nrf_sdh_enabled)
+ {
+ return NRF_ERROR_INVALID_STATE;
+ }
+
+ m_nrf_sdh_continue = true;
+
+ // Notify observers about SoftDevice disable request.
+ if (sdh_request_observer_notify(NRF_SDH_EVT_DISABLE_REQUEST) == NRF_ERROR_BUSY)
+ {
+ // Disable process was stopped.
+ return NRF_SUCCESS;
+ }
+
+ // Notify observers about starting SoftDevice disable process.
+ sdh_state_observer_notify(NRF_SDH_EVT_STATE_DISABLE_PREPARE);
+
+ CRITICAL_REGION_ENTER();
+ ret_code = sd_softdevice_disable();
+ m_nrf_sdh_enabled = false;
+ CRITICAL_REGION_EXIT();
+
+ if (ret_code != NRF_SUCCESS)
+ {
+ return ret_code;
+ }
+
+ m_nrf_sdh_continue = false;
+
+ softdevice_evt_irq_disable();
+
+ // Notify observers about a finished SoftDevice enable process.
+ sdh_state_observer_notify(NRF_SDH_EVT_STATE_DISABLED);
+
+ return NRF_SUCCESS;
+}
+
+
+ret_code_t nrf_sdh_request_continue(void)
+{
+ if (!m_nrf_sdh_continue)
+ {
+ return NRF_ERROR_INVALID_STATE;
+ }
+
+ if (m_nrf_sdh_enabled)
+ {
+ return nrf_sdh_disable_request();
+ }
+ else
+ {
+ return nrf_sdh_enable_request();
+ }
+}
+
+
+bool nrf_sdh_is_enabled(void)
+{
+ return m_nrf_sdh_enabled;
+}
+
+
+void nrf_sdh_suspend(void)
+{
+ if (!m_nrf_sdh_enabled)
+ {
+ return;
+ }
+
+ softdevice_evt_irq_disable();
+ m_nrf_sdh_suspended = true;
+}
+
+
+void nrf_sdh_resume(void)
+{
+ if ((!m_nrf_sdh_suspended) || (!m_nrf_sdh_enabled))
+ {
+ return;
+ }
+
+ // Force calling ISR again to make sure that events not previously pulled have been processed.
+#ifdef SOFTDEVICE_PRESENT
+ ret_code_t ret_code = sd_nvic_SetPendingIRQ((IRQn_Type)SD_EVT_IRQn);
+ APP_ERROR_CHECK(ret_code);
+#else
+ NVIC_SetPendingIRQ((IRQn_Type)SD_EVT_IRQn);
+#endif
+
+ softdevices_evt_irq_enable();
+
+ m_nrf_sdh_suspended = false;
+}
+
+
+bool nrf_sdh_is_suspended(void)
+{
+ return (!m_nrf_sdh_enabled) || (m_nrf_sdh_suspended);
+}
+
+
+void nrf_sdh_evts_poll(void)
+{
+ nrf_section_iter_t iter;
+
+ // Notify observers about pending SoftDevice event.
+ for (nrf_section_iter_init(&iter, &sdh_stack_observers);
+ nrf_section_iter_get(&iter) != NULL;
+ nrf_section_iter_next(&iter))
+ {
+ nrf_sdh_stack_observer_t * p_observer;
+ nrf_sdh_stack_evt_handler_t handler;
+
+ p_observer = (nrf_sdh_stack_observer_t *) nrf_section_iter_get(&iter);
+ handler = p_observer->handler;
+
+ handler(p_observer->p_context);
+ }
+}
+
+
+#if (NRF_SDH_DISPATCH_MODEL == NRF_SDH_DISPATCH_MODEL_INTERRUPT)
+
+void SD_EVT_IRQHandler(void)
+{
+ nrf_sdh_evts_poll();
+}
+
+#elif (NRF_SDH_DISPATCH_MODEL == NRF_SDH_DISPATCH_MODEL_APPSH)
+
+/**@brief Function for polling SoftDevice events.
+ *
+ * @note This function is compatible with @ref app_sched_event_handler_t.
+ *
+ * @param[in] p_event_data Pointer to the event data.
+ * @param[in] event_size Size of the event data.
+ */
+static void appsh_events_poll(void * p_event_data, uint16_t event_size)
+{
+ UNUSED_PARAMETER(p_event_data);
+ UNUSED_PARAMETER(event_size);
+
+ nrf_sdh_evts_poll();
+}
+
+
+void SD_EVT_IRQHandler(void)
+{
+ ret_code_t ret_code = app_sched_event_put(NULL, 0, appsh_events_poll);
+ APP_ERROR_CHECK(ret_code);
+}
+
+#elif (NRF_SDH_DISPATCH_MODEL == NRF_SDH_DISPATCH_MODEL_POLLING)
+
+#else
+
+#error "Unknown SoftDevice handler dispatch model."
+
+#endif // NRF_SDH_DISPATCH_MODEL
+
+#endif // NRF_MODULE_ENABLED(NRF_SDH)
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/softdevice/common/nrf_sdh.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/softdevice/common/nrf_sdh.h
new file mode 100644
index 0000000..a63e4cb
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/softdevice/common/nrf_sdh.h
@@ -0,0 +1,305 @@
+/**
+ * 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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
+ *
+ * @defgroup nrf_sdh SoftDevice Handler
+ * @{
+ * @ingroup app_common
+ * @brief API for initializing and disabling the SoftDevice.
+ */
+
+#ifndef NRF_SDH_H__
+#define NRF_SDH_H__
+
+#include <stdbool.h>
+#include "sdk_config.h"
+#include "sdk_errors.h"
+#include "nrf_section_iter.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @name Softdevice Handler dispatch models
+ * @{
+ * @ingroup nrf_sdh */
+
+/**@brief SoftDevice events are passed to the application from the interrupt context. */
+#define NRF_SDH_DISPATCH_MODEL_INTERRUPT 0
+
+/**@brief SoftDevice events are passed to the application using @ref app_scheduler.
+ *
+ * @note @ref app_scheduler must be initialized before enabling the SoftDevice handler.
+ */
+#define NRF_SDH_DISPATCH_MODEL_APPSH 1
+
+/**@brief SoftDevice events are polled manually using @ref nrf_sdh_evts_poll().
+ *
+ * @note In this mode, a user application can also implement SD_EVT_IRQHandler() to receive a
+ * notification about incoming events.
+ */
+#define NRF_SDH_DISPATCH_MODEL_POLLING 2
+
+/** @} */
+
+/**
+ * @name SoftDevice Handler state change requests
+ * @{
+ * @ingroup nrf_sdh */
+
+/**@brief SoftDevice Handler state requests. */
+typedef enum
+{
+ NRF_SDH_EVT_ENABLE_REQUEST, //!< Request to enable the SoftDevice.
+ NRF_SDH_EVT_DISABLE_REQUEST, //!< Request to disable the SoftDevice.
+} nrf_sdh_req_evt_t;
+
+/**@brief SoftDevice Handler state request handler.
+ *
+ * @retval true If ready for the SoftDevice to change state.
+ * @retval false If not ready for the SoftDevice to change state.
+ * If false is returned, the state change is aborted.
+ */
+typedef bool (*nrf_sdh_req_evt_handler_t)(nrf_sdh_req_evt_t request, void * p_context);
+
+/**@brief SoftDevice Handler state request observer. */
+typedef struct
+{
+ nrf_sdh_req_evt_handler_t handler; //!< Request handler.
+ void * p_context; //!< A parameter to the handler function.
+} const nrf_sdh_req_observer_t;
+
+/**@brief Macro for registering a SoftDevice state change request observer.
+ *
+ * An observer of SoftDevice state change requests receives requests to change the state of the
+ * SoftDevice from enabled to disabled and vice versa. These requests may or may not be acknowledged
+ * by the observer, depending on the value returned by its request handler function. Thus, a
+ * request observer has the capability to defer the change of state of the SoftDevice. If it does
+ * so, it has the responsibility to call @ref nrf_sdh_request_continue when it is ready to let the
+ * SoftDevice change its state. If such capability is not necessary and you only need to be informed
+ * about changes of the SoftDevice state, use the @ref NRF_SDH_STATE_OBSERVER macro instead.
+ *
+ * @note This macro places the observer in a section named "sdh_req_observers".
+ *
+ * @param[in] _observer Name of the observer.
+ * @param[in] _prio Priority of the observer's event handler.
+ * The smaller the number, the higher the priority.
+ * @hideinitializer
+ */
+#define NRF_SDH_REQUEST_OBSERVER(_observer, _prio) \
+STATIC_ASSERT(NRF_SDH_ENABLED, "NRF_SDH_ENABLED not set!"); \
+STATIC_ASSERT(_prio < NRF_SDH_REQ_OBSERVER_PRIO_LEVELS, "Priority level unavailable."); \
+/*lint -esym(528,*_observer) -esym(529,*_observer) : Symbol not referenced. */ \
+NRF_SECTION_SET_ITEM_REGISTER(sdh_req_observers, _prio, nrf_sdh_req_observer_t const _observer)
+
+/** @} */
+
+/**
+ * @name SoftDevice Handler state events
+ * @{
+ * @ingroup nrf_sdh */
+
+/**@brief SoftDevice Handler state events. */
+typedef enum
+{
+ NRF_SDH_EVT_STATE_ENABLE_PREPARE, //!< SoftDevice is going to be enabled.
+ NRF_SDH_EVT_STATE_ENABLED, //!< SoftDevice is enabled.
+ NRF_SDH_EVT_STATE_DISABLE_PREPARE, //!< SoftDevice is going to be disabled.
+ NRF_SDH_EVT_STATE_DISABLED, //!< SoftDevice is disabled.
+} nrf_sdh_state_evt_t;
+
+/**@brief SoftDevice Handler state event handler. */
+typedef void (*nrf_sdh_state_evt_handler_t)(nrf_sdh_state_evt_t state, void * p_context);
+
+/**@brief SoftDevice Handler state observer. */
+typedef struct
+{
+ nrf_sdh_state_evt_handler_t handler; //!< State event handler.
+ void * p_context; //!< A parameter to the event handler.
+} const nrf_sdh_state_observer_t;
+
+/**@brief Macro for registering a SoftDevice state observer.
+ *
+ * A SoftDevice state observer receives events when the SoftDevice state has changed or is
+ * about to change. These events are only meant to inform the state observer, which, contrary
+ * to a state change request observer, does not have the capability to defer the change of state.
+ * If such capability is required, use the @ref NRF_SDH_REQUEST_OBSERVER macro instead.
+ *
+ * This macro places the observer in a section named "sdh_state_observers".
+ *
+ * @param[in] _observer Name of the observer.
+ * @param[in] _prio Priority of the observer's event handler.
+ * The smaller the number, the higher the priority.
+ * @hideinitializer
+ */
+#define NRF_SDH_STATE_OBSERVER(_observer, _prio) \
+STATIC_ASSERT(NRF_SDH_ENABLED, "NRF_SDH_ENABLED not set!"); \
+STATIC_ASSERT(_prio < NRF_SDH_STATE_OBSERVER_PRIO_LEVELS, "Priority level unavailable."); \
+/*lint -esym(528,*_observer) -esym(529,*_observer) : Symbol not referenced. */ \
+NRF_SECTION_SET_ITEM_REGISTER(sdh_state_observers, _prio, static nrf_sdh_state_observer_t const _observer)
+
+/** @} */
+
+/**
+ * @name SoftDevice stack events
+ * @{
+ * @ingroup nrf_sdh */
+
+/**@brief SoftDevice stack event handler. */
+typedef void (*nrf_sdh_stack_evt_handler_t)(void * p_evt);
+
+/**@brief SoftDevice stack event observer. */
+typedef struct
+{
+ nrf_sdh_stack_evt_handler_t handler; //!< SoftDevice event handler.
+ void * p_context; //!< A parameter to the event handler.
+} const nrf_sdh_stack_observer_t;
+
+/**@brief Macro for registering a SoftDevice stack events observer.
+ *
+ * A SoftDevice stack event observer receives all events from the SoftDevice. These events can be
+ * either BLE, ANT, or SoC events. If you need to receive BLE, ANT, or SoC events separately, use the
+ * @ref NRF_SDH_BLE_OBSERVER, @ref NRF_SDH_ANT_OBSERVER, or @ref NRF_SDH_SOC_OBSERVER macros
+ * respectively.
+ *
+ * @note This macro places the observer in a section named "sdh_stack_observers".
+ *
+ * @param[in] _observer Name of the observer.
+ * @param[in] _prio Priority of the observer's event handler.
+ * The smaller the number, the higher the priority.
+ ** @hideinitializer
+ */
+#define NRF_SDH_STACK_OBSERVER(_observer, _prio) \
+STATIC_ASSERT(NRF_SDH_ENABLED, "NRF_SDH_ENABLED not set!"); \
+STATIC_ASSERT(_prio < NRF_SDH_STACK_OBSERVER_PRIO_LEVELS, "Priority level unavailable."); \
+/*lint -esym(528,*_observer) -esym(529,*_observer) : Symbol not referenced. */ \
+NRF_SECTION_SET_ITEM_REGISTER(sdh_stack_observers, _prio, static nrf_sdh_stack_observer_t const _observer)
+
+/** @} */
+
+/**@brief Function for requesting to enable the SoftDevice.
+ *
+ * This function issues a @ref NRF_SDH_EVT_ENABLE_REQUEST request to all observers that
+ * were registered using the @ref NRF_SDH_REQUEST_OBSERVER macro. The observers may or
+ * may not acknowledge the request. If all observers acknowledge the request, the
+ * SoftDevice will be enabled. Otherwise, the process will be stopped and the observers
+ * that did not acknowledge have the responsibility to restart it by calling
+ * @ref nrf_sdh_request_continue when they are ready for the SoftDevice to change state.
+ *
+ * @retval NRF_SUCCESS The process is started.
+ * @retval NRF_ERROR_INVALID_STATE The SoftDevice is already enabled.
+ */
+ret_code_t nrf_sdh_enable_request(void);
+
+
+/**@brief Function for requesting to disable the SoftDevice.
+ *
+ * This function issues a @ref NRF_SDH_EVT_DISABLE_REQUEST request to all observers that
+ * were registered using the @ref NRF_SDH_REQUEST_OBSERVER macro. The observers may or
+ * may not acknowledge the request. If all observers acknowledge the request, the
+ * SoftDevice will be disabled. Otherwise, the process will be stopped and the observers
+ * that did not acknowledge have the responsibility to restart it by calling
+ * @ref nrf_sdh_request_continue when they are ready for the SoftDevice to change state.
+ *
+ * @retval NRF_SUCCESS The process is started.
+ * @retval NRF_ERROR_INVALID_STATE The SoftDevice is already disabled.
+ */
+ret_code_t nrf_sdh_disable_request(void);
+
+
+/**@brief Function for restarting the SoftDevice Enable/Disable process.
+ *
+ * Modules which did not acknowledge a @ref NRF_SDH_EVT_ENABLE_REQUEST or
+ * @ref NRF_SDH_EVT_DISABLE_REQUEST request must call this function to restart the
+ * SoftDevice state change process.
+ *
+ * @retval NRF_SUCCESS The process is restarted.
+ * @retval NRF_ERROR_INVALID_STATE No state change request was pending.
+ */
+ret_code_t nrf_sdh_request_continue(void);
+
+
+/**@brief Function for retrieving the SoftDevice state.
+ *
+ * @retval true If the SoftDevice is enabled.
+ * @retval false If the SoftDevice is disabled.
+ */
+bool nrf_sdh_is_enabled(void);
+
+
+/**@brief Function for stopping the incoming stack events.
+ *
+ * This function disables the SoftDevice interrupt. To resume polling for events,
+ * call @ref nrf_sdh_resume.
+ */
+void nrf_sdh_suspend(void);
+
+
+/**@brief Function for resuming polling incoming events from the SoftDevice. */
+void nrf_sdh_resume(void);
+
+
+/**@brief Function for retrieving the information about the module state.
+ *
+ * @retval true The SoftDevice handler is paused, and it will not fetch events from the stack.
+ * @retval false The SoftDevice handler is running, and it will fetch and dispatch events from
+ * the stack to the registered stack observers.
+ */
+bool nrf_sdh_is_suspended(void);
+
+
+/**@brief Function for polling stack events from the SoftDevice.
+ *
+ * The events are passed to the application using the registered event handlers.
+ *
+ * @note @ref NRF_SDH_DISPATCH_MODEL_POLLING must be selected to use this function.
+ */
+void nrf_sdh_evts_poll(void);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // NRF_SDH_H__
+
+/** @} */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/softdevice/common/nrf_sdh_ant.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/softdevice/common/nrf_sdh_ant.c
new file mode 100644
index 0000000..27d1ed5
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/softdevice/common/nrf_sdh_ant.c
@@ -0,0 +1,162 @@
+/**
+ * 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+
+#include "sdk_common.h"
+#if NRF_MODULE_ENABLED(NRF_SDH_ANT)
+
+#include "nrf_sdh_ant.h"
+
+#include "nrf_sdh.h"
+#include "app_error.h"
+#include "nrf_strerror.h"
+#include "ant_interface.h"
+
+
+#define NRF_LOG_MODULE_NAME nrf_sdh_ant
+#if NRF_SDH_ANT_LOG_ENABLED
+ #define NRF_LOG_LEVEL NRF_SDH_ANT_LOG_LEVEL
+ #define NRF_LOG_INFO_COLOR NRF_SDH_ANT_INFO_COLOR
+ #define NRF_LOG_DEBUG_COLOR NRF_SDH_ANT_DEBUG_COLOR
+#else
+ #define NRF_LOG_LEVEL 0
+#endif // NRF_SDH_ANT_LOG_ENABLED
+#include "nrf_log.h"
+NRF_LOG_MODULE_REGISTER();
+
+
+STATIC_ASSERT(NRF_SDH_ANT_TOTAL_CHANNELS_ALLOCATED <= MAX_ANT_CHANNELS);
+STATIC_ASSERT(NRF_SDH_ANT_ENCRYPTED_CHANNELS <= NRF_SDH_ANT_TOTAL_CHANNELS_ALLOCATED);
+
+// Create section set "sdh_ant_observers".
+NRF_SECTION_SET_DEF(sdh_ant_observers, nrf_sdh_ant_evt_observer_t, NRF_SDH_ANT_OBSERVER_PRIO_LEVELS);
+
+// Memory buffer provided in order to support channel configuration.
+__ALIGN(4) static uint8_t m_ant_stack_buffer[NRF_SDH_ANT_BUF_SIZE];
+
+
+static bool m_stack_is_enabled;
+
+
+ret_code_t nrf_sdh_ant_enable(void)
+{
+ ANT_ENABLE ant_enable_cfg =
+ {
+ .ucTotalNumberOfChannels = NRF_SDH_ANT_TOTAL_CHANNELS_ALLOCATED,
+ .ucNumberOfEncryptedChannels = NRF_SDH_ANT_ENCRYPTED_CHANNELS,
+ .usNumberOfEvents = NRF_SDH_ANT_EVENT_QUEUE_SIZE,
+ .pucMemoryBlockStartLocation = m_ant_stack_buffer,
+ .usMemoryBlockByteSize = sizeof(m_ant_stack_buffer),
+ };
+
+ ret_code_t ret_code = sd_ant_enable(&ant_enable_cfg);
+ if (ret_code == NRF_SUCCESS)
+ {
+ m_stack_is_enabled = true;
+ }
+ else
+ {
+ NRF_LOG_ERROR("sd_ant_enable() returned %s.", nrf_strerror_get(ret_code));
+ }
+
+ return ret_code;
+}
+
+
+/**@brief Function for polling ANT events.
+ *
+ * @param[in] p_context Context of the observer.
+ */
+static void nrf_sdh_ant_evts_poll(void * p_context)
+{
+ UNUSED_VARIABLE(p_context);
+
+ ret_code_t ret_code;
+
+#ifndef SER_CONNECTIVITY
+ if (!m_stack_is_enabled)
+ {
+ return;
+ }
+#else
+ UNUSED_VARIABLE(m_stack_is_enabled);
+#endif // SER_CONNECTIVITY
+
+ while (true)
+ {
+ ant_evt_t ant_evt;
+
+ ret_code = sd_ant_event_get(&ant_evt.channel, &ant_evt.event, ant_evt.message.aucMessage);
+ if (ret_code != NRF_SUCCESS)
+ {
+ break;
+ }
+
+ NRF_LOG_DEBUG("ANT Event 0x%02X Channel 0x%02X", ant_evt.event, ant_evt.channel);
+
+ // Forward the event to ANT observers.
+ nrf_section_iter_t iter;
+ for (nrf_section_iter_init(&iter, &sdh_ant_observers);
+ nrf_section_iter_get(&iter) != NULL;
+ nrf_section_iter_next(&iter))
+ {
+ nrf_sdh_ant_evt_observer_t * p_observer;
+ nrf_sdh_ant_evt_handler_t handler;
+
+ p_observer = (nrf_sdh_ant_evt_observer_t *) nrf_section_iter_get(&iter);
+ handler = p_observer->handler;
+
+ handler(&ant_evt, p_observer->p_context);
+ }
+ }
+
+ if (ret_code != NRF_ERROR_NOT_FOUND)
+ {
+ APP_ERROR_HANDLER(ret_code);
+ }
+}
+
+
+NRF_SDH_STACK_OBSERVER(m_nrf_sdh_ant_evts_poll, NRF_SDH_ANT_STACK_OBSERVER_PRIO) =
+{
+ .handler = nrf_sdh_ant_evts_poll,
+ .p_context = NULL,
+};
+
+#endif // NRF_MODULE_ENABLED(NRF_SDH_ANT)
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/softdevice/common/nrf_sdh_ant.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/softdevice/common/nrf_sdh_ant.h
new file mode 100644
index 0000000..10811d4
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/softdevice/common/nrf_sdh_ant.h
@@ -0,0 +1,182 @@
+/**
+ * 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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
+ *
+ * @defgroup nrf_sdh_ant ANT support in SoftDevice Handler
+ * @{
+ * @ingroup nrf_sdh
+ * @brief This file contains the declarations of types and functions required for ANT stack support.
+ */
+
+#ifndef NRF_SDH_ANT_H__
+#define NRF_SDH_ANT_H__
+
+#include "ant_parameters.h"
+#include "app_util.h"
+#include "nrf_section_iter.h"
+#include "sdk_errors.h"
+
+#include <stdint.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define NRF_SDH_ANT_EVT_CHANNEL_FIELD_SIZE 1 //!< Size of the channel field in ANT stack event
+#define NRF_SDH_ANT_EVT_EVENT_FIELD_SIZE 1 //!< Size of the event field in ANT stack event
+
+/**@brief Size of the buffer provided to the ANT SoftDevice.
+ * @hideinitializer
+ */
+#define NRF_SDH_ANT_BUF_SIZE ANT_ENABLE_GET_REQUIRED_SPACE( \
+ NRF_SDH_ANT_TOTAL_CHANNELS_ALLOCATED, \
+ NRF_SDH_ANT_ENCRYPTED_CHANNELS, \
+ NRF_SDH_ANT_BURST_QUEUE_SIZE, \
+ NRF_SDH_ANT_EVENT_QUEUE_SIZE)
+
+/**@brief Size of the buffer provided to the ANT SoftDevice to receive ANT events. */
+#define NRF_SDH_ANT_MESSAGE_SIZE ((CEIL_DIV(MESG_BUFFER_SIZE, sizeof(uint32_t))) * sizeof(uint32_t))
+
+/**@brief Size of the buffer provided to the Events Scheduler to hold ANT events. */
+#define NRF_SDH_ANT_EVT_BUF_SIZE ((CEIL_DIV(NRF_SDH_ANT_MESSAGE_SIZE + \
+ NRF_SDH_ANT_EVT_CHANNEL_FIELD_SIZE + \
+ NRF_SDH_ANT_EVT_EVENT_FIELD_SIZE, \
+ sizeof(uint32_t))) * sizeof(uint32_t))
+
+
+#if !(defined(__LINT__))
+/**@brief Macro for registering an ANT observer. Modules that want to be
+ * notified about ANT events must register the handler using this macro.
+ *
+ * @details This macro places the observer in a section named "sdh_ant_observers".
+ *
+ * @param[in] _name Observer name.
+ * @param[in] _prio Priority of the observer event handler.
+ * The smaller the number, the higher the priority.
+ * @param[in] _handler ANT event handler.
+ * @param[in] _context Parameter to the event handler.
+ * @hideinitializer
+ */
+#define NRF_SDH_ANT_OBSERVER(_name, _prio, _handler, _context) \
+STATIC_ASSERT(NRF_SDH_ANT_ENABLED, "NRF_SDH_ANT_ENABLED not set!"); \
+STATIC_ASSERT(_prio < NRF_SDH_ANT_OBSERVER_PRIO_LEVELS, "Priority level unavailable."); \
+NRF_SECTION_SET_ITEM_REGISTER(sdh_ant_observers, _prio, static nrf_sdh_ant_evt_observer_t _name) = \
+{ \
+ .handler = _handler, \
+ .p_context = _context \
+}
+
+/**@brief Macro for registering an array of @ref nrf_sdh_ant_evt_observer_t.
+ * Modules that want to be notified about ANT events must register the handler using
+ * this macro.
+ *
+ * Each observer's handler will be dispatched an event with its relative context from @p _context.
+ * This macro places the observer in a section named "sdh_ant_observers".
+ *
+ * @param[in] _name Observer name.
+ * @param[in] _prio Priority of the observer event handler.
+ * The smaller the number, the higher the priority.
+ * @param[in] _handler ANT event handler.
+ * @param[in] _context An array of parameters to the event handler.
+ * @param[in] _cnt Number of observers to register.
+ * @hideinitializer
+ */
+#define NRF_SDH_ANT_OBSERVERS(_name, _prio, _handler, _context, _cnt) \
+STATIC_ASSERT(NRF_SDH_ANT_ENABLED, "NRF_SDH_ANT_ENABLED not set!"); \
+STATIC_ASSERT(_prio < NRF_SDH_ANT_OBSERVER_PRIO_LEVELS, "Priority level unavailable."); \
+NRF_SECTION_SET_ITEM_REGISTER(sdh_ant_observers, _prio, static nrf_sdh_ant_evt_observer_t _name[_cnt]) = \
+{ \
+ MACRO_REPEAT_FOR(_cnt, HANDLER_SET, _handler, _context) \
+}
+
+#if !(defined(DOXYGEN))
+#define HANDLER_SET(_idx, _handler, _context) \
+{ \
+ .handler = _handler, \
+ .p_context = _context[_idx], \
+},
+#endif
+
+#else // __LINT__
+
+/* Swallow semicolons */
+/*lint -save -esym(528, *) -esym(529, *) : Symbol not referenced. */
+#define NRF_SDH_ANT_OBSERVER(A, B, C, D) static int semicolon_swallow_##A
+#define NRF_SDH_ANT_OBSERVERS(A, B, C, D, E) static int semicolon_swallow_##A
+/*lint -restore */
+
+#endif
+
+
+/**@brief ANT stack event. */
+typedef struct
+{
+ ANT_MESSAGE message; //!< ANT Message.
+ uint8_t channel; //!< Channel number.
+ uint8_t event; //!< Event code.
+} ant_evt_t;
+
+/**@brief ANT stack event handler. */
+typedef void (*nrf_sdh_ant_evt_handler_t)(ant_evt_t * p_ant_evt, void * p_context);
+
+/**@brief ANT event observer. */
+typedef struct
+{
+ nrf_sdh_ant_evt_handler_t handler; //!< ANT event handler.
+ void * p_context; //!< A parameter to the event handler.
+} const nrf_sdh_ant_evt_observer_t;
+
+
+/**@brief Function for configuring and enabling the ANT stack.
+ *
+ * @details The function sets the channel configuration for the stack using the parameters
+ * provided in the @c sdk_config file. It also assigns a correspondingly large
+ * buffer as a static resource.
+ */
+ret_code_t nrf_sdh_ant_enable(void);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // NRF_SDH_ANT_H__
+
+/** @} */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/softdevice/common/nrf_sdh_ble.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/softdevice/common/nrf_sdh_ble.c
new file mode 100644
index 0000000..ed882dc
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/softdevice/common/nrf_sdh_ble.c
@@ -0,0 +1,324 @@
+/**
+ * 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+
+#include "sdk_common.h"
+#if NRF_MODULE_ENABLED(NRF_SDH_BLE)
+
+#include "nrf_sdh_ble.h"
+
+#include "nrf_sdh.h"
+#include "app_error.h"
+#include "nrf_strerror.h"
+
+
+#define NRF_LOG_MODULE_NAME nrf_sdh_ble
+#if NRF_SDH_BLE_LOG_ENABLED
+ #define NRF_LOG_LEVEL NRF_SDH_BLE_LOG_LEVEL
+ #define NRF_LOG_INFO_COLOR NRF_SDH_BLE_INFO_COLOR
+ #define NRF_LOG_DEBUG_COLOR NRF_SDH_BLE_DEBUG_COLOR
+#else
+ #define NRF_LOG_LEVEL 0
+#endif // NRF_SDH_BLE_LOG_ENABLED
+#include "nrf_log.h"
+NRF_LOG_MODULE_REGISTER();
+
+
+// Create section set "sdh_ble_observers".
+NRF_SECTION_SET_DEF(sdh_ble_observers, nrf_sdh_ble_evt_observer_t, NRF_SDH_BLE_OBSERVER_PRIO_LEVELS);
+
+
+//lint -save -e10 -e19 -e40 -e27 Illegal character (0x24)
+#if defined(__CC_ARM)
+ extern uint32_t Image$$RW_IRAM1$$Base;
+ uint32_t const * const m_ram_start = &Image$$RW_IRAM1$$Base;
+#elif defined(__ICCARM__)
+ extern uint32_t __ICFEDIT_region_RAM_start__;
+ uint32_t const * const m_ram_start = &__ICFEDIT_region_RAM_start__;
+#elif defined(__SES_ARM)
+ extern uint32_t __app_ram_start__;
+ uint32_t const * const m_ram_start = &__app_ram_start__;
+#elif defined(__GNUC__)
+ extern uint32_t __data_start__;
+ uint32_t const * const m_ram_start = &__data_start__;
+#endif
+//lint -restore
+
+#define RAM_START 0x20000000
+#define APP_RAM_START (uint32_t)m_ram_start
+
+
+static bool m_stack_is_enabled;
+
+
+ret_code_t nrf_sdh_ble_app_ram_start_get(uint32_t * p_app_ram_start)
+{
+ if (p_app_ram_start == NULL)
+ {
+ return NRF_ERROR_NULL;
+ }
+
+ *p_app_ram_start = APP_RAM_START;
+
+ return NRF_SUCCESS;
+}
+
+
+ret_code_t nrf_sdh_ble_default_cfg_set(uint8_t conn_cfg_tag, uint32_t * p_ram_start)
+{
+ uint32_t ret_code;
+
+ ret_code = nrf_sdh_ble_app_ram_start_get(p_ram_start);
+ if (ret_code != NRF_SUCCESS)
+ {
+ return ret_code;
+ }
+
+#ifdef S112
+ STATIC_ASSERT(NRF_SDH_BLE_CENTRAL_LINK_COUNT == 0, "When using s112, NRF_SDH_BLE_CENTRAL_LINK_COUNT must be 0.");
+#endif
+
+ // Overwrite some of the default settings of the BLE stack.
+ // If any of the calls to sd_ble_cfg_set() fail, log the error but carry on so that
+ // wrong RAM settings can be caught by nrf_sdh_ble_enable() and a meaningful error
+ // message will be printed to the user suggesting the correct value.
+ ble_cfg_t ble_cfg;
+
+#if (NRF_SDH_BLE_TOTAL_LINK_COUNT != 0)
+ // Configure the connection count.
+ memset(&ble_cfg, 0, sizeof(ble_cfg));
+ ble_cfg.conn_cfg.conn_cfg_tag = conn_cfg_tag;
+ ble_cfg.conn_cfg.params.gap_conn_cfg.conn_count = NRF_SDH_BLE_TOTAL_LINK_COUNT;
+ ble_cfg.conn_cfg.params.gap_conn_cfg.event_length = NRF_SDH_BLE_GAP_EVENT_LENGTH;
+
+ ret_code = sd_ble_cfg_set(BLE_CONN_CFG_GAP, &ble_cfg, *p_ram_start);
+ if (ret_code != NRF_SUCCESS)
+ {
+ NRF_LOG_ERROR("sd_ble_cfg_set() returned %s when attempting to set BLE_CONN_CFG_GAP.",
+ nrf_strerror_get(ret_code));
+ }
+
+ // Configure the connection roles.
+ memset(&ble_cfg, 0, sizeof(ble_cfg));
+ ble_cfg.gap_cfg.role_count_cfg.periph_role_count = NRF_SDH_BLE_PERIPHERAL_LINK_COUNT;
+#ifndef S112
+ ble_cfg.gap_cfg.role_count_cfg.central_role_count = NRF_SDH_BLE_CENTRAL_LINK_COUNT;
+ ble_cfg.gap_cfg.role_count_cfg.central_sec_count = MIN(NRF_SDH_BLE_CENTRAL_LINK_COUNT,
+ BLE_GAP_ROLE_COUNT_CENTRAL_SEC_DEFAULT);
+#endif
+
+ ret_code = sd_ble_cfg_set(BLE_GAP_CFG_ROLE_COUNT, &ble_cfg, *p_ram_start);
+ if (ret_code != NRF_SUCCESS)
+ {
+ NRF_LOG_ERROR("sd_ble_cfg_set() returned %s when attempting to set BLE_GAP_CFG_ROLE_COUNT.",
+ nrf_strerror_get(ret_code));
+ }
+
+ // Configure the maximum ATT MTU.
+#if (NRF_SDH_BLE_GATT_MAX_MTU_SIZE != 23)
+ memset(&ble_cfg, 0x00, sizeof(ble_cfg));
+ ble_cfg.conn_cfg.conn_cfg_tag = conn_cfg_tag;
+ ble_cfg.conn_cfg.params.gatt_conn_cfg.att_mtu = NRF_SDH_BLE_GATT_MAX_MTU_SIZE;
+
+ ret_code = sd_ble_cfg_set(BLE_CONN_CFG_GATT, &ble_cfg, *p_ram_start);
+ if (ret_code != NRF_SUCCESS)
+ {
+ NRF_LOG_ERROR("sd_ble_cfg_set() returned %s when attempting to set BLE_CONN_CFG_GATT.",
+ nrf_strerror_get(ret_code));
+ }
+#endif // NRF_SDH_BLE_GATT_MAX_MTU_SIZE != 23
+#endif // NRF_SDH_BLE_TOTAL_LINK_COUNT != 0
+
+ // Configure number of custom UUIDS.
+ memset(&ble_cfg, 0, sizeof(ble_cfg));
+ ble_cfg.common_cfg.vs_uuid_cfg.vs_uuid_count = NRF_SDH_BLE_VS_UUID_COUNT;
+
+ ret_code = sd_ble_cfg_set(BLE_COMMON_CFG_VS_UUID, &ble_cfg, *p_ram_start);
+ if (ret_code != NRF_SUCCESS)
+ {
+ NRF_LOG_ERROR("sd_ble_cfg_set() returned %s when attempting to set BLE_COMMON_CFG_VS_UUID.",
+ nrf_strerror_get(ret_code));
+ }
+
+ // Configure the GATTS attribute table.
+ memset(&ble_cfg, 0x00, sizeof(ble_cfg));
+ ble_cfg.gatts_cfg.attr_tab_size.attr_tab_size = NRF_SDH_BLE_GATTS_ATTR_TAB_SIZE;
+
+ ret_code = sd_ble_cfg_set(BLE_GATTS_CFG_ATTR_TAB_SIZE, &ble_cfg, *p_ram_start);
+ if (ret_code != NRF_SUCCESS)
+ {
+ NRF_LOG_ERROR("sd_ble_cfg_set() returned %s when attempting to set BLE_GATTS_CFG_ATTR_TAB_SIZE.",
+ nrf_strerror_get(ret_code));
+ }
+
+ // Configure Service Changed characteristic.
+ memset(&ble_cfg, 0x00, sizeof(ble_cfg));
+ ble_cfg.gatts_cfg.service_changed.service_changed = NRF_SDH_BLE_SERVICE_CHANGED;
+
+ ret_code = sd_ble_cfg_set(BLE_GATTS_CFG_SERVICE_CHANGED, &ble_cfg, *p_ram_start);
+ if (ret_code != NRF_SUCCESS)
+ {
+ NRF_LOG_ERROR("sd_ble_cfg_set() returned %s when attempting to set BLE_GATTS_CFG_SERVICE_CHANGED.",
+ nrf_strerror_get(ret_code));
+ }
+
+ return NRF_SUCCESS;
+}
+
+
+/**@brief Function for finding the end address of the RAM. */
+static uint32_t ram_end_address_get(void)
+{
+ uint32_t ram_total_size;
+
+#ifdef NRF51
+ uint32_t block_size = NRF_FICR->SIZERAMBLOCKS;
+ ram_total_size = block_size * NRF_FICR->NUMRAMBLOCK;
+#else
+ ram_total_size = NRF_FICR->INFO.RAM * 1024;
+#endif
+
+ return RAM_START + ram_total_size;
+}
+
+
+ret_code_t nrf_sdh_ble_enable(uint32_t * const p_app_ram_start)
+{
+ // Start of RAM, obtained from linker symbol.
+ uint32_t const app_ram_start_link = *p_app_ram_start;
+
+ ret_code_t ret_code = sd_ble_enable(p_app_ram_start);
+ if (*p_app_ram_start > app_ram_start_link)
+ {
+ NRF_LOG_WARNING("Insufficient RAM allocated for the SoftDevice.");
+
+ NRF_LOG_WARNING("Change the RAM start location from 0x%x to 0x%x.",
+ app_ram_start_link, *p_app_ram_start);
+ NRF_LOG_WARNING("Maximum RAM size for application is 0x%x.",
+ ram_end_address_get() - (*p_app_ram_start));
+ }
+ else
+ {
+ NRF_LOG_DEBUG("RAM starts at 0x%x", app_ram_start_link);
+ if (*p_app_ram_start != app_ram_start_link)
+ {
+ NRF_LOG_DEBUG("RAM start location can be adjusted to 0x%x.", *p_app_ram_start);
+
+ NRF_LOG_DEBUG("RAM size for application can be adjusted to 0x%x.",
+ ram_end_address_get() - (*p_app_ram_start));
+ }
+ }
+
+ if (ret_code == NRF_SUCCESS)
+ {
+ m_stack_is_enabled = true;
+ }
+ else
+ {
+ NRF_LOG_ERROR("sd_ble_enable() returned %s.", nrf_strerror_get(ret_code));
+ }
+
+ return ret_code;
+}
+
+
+/**@brief Function for polling BLE events.
+ *
+ * @param[in] p_context Context of the observer.
+ */
+static void nrf_sdh_ble_evts_poll(void * p_context)
+{
+ UNUSED_VARIABLE(p_context);
+
+ ret_code_t ret_code;
+
+ if (!m_stack_is_enabled)
+ {
+ return;
+ }
+
+ while (true)
+ {
+ /*lint -save -e(587) */
+ __ALIGN(4) uint8_t evt_buffer[NRF_SDH_BLE_EVT_BUF_SIZE];
+ /*lint -restore */
+
+ ble_evt_t * p_ble_evt;
+ uint16_t evt_len = (uint16_t)sizeof(evt_buffer);
+
+ ret_code = sd_ble_evt_get(evt_buffer, &evt_len);
+ if (ret_code != NRF_SUCCESS)
+ {
+ break;
+ }
+
+ p_ble_evt = (ble_evt_t *)evt_buffer;
+
+ NRF_LOG_DEBUG("BLE event: 0x%x.", p_ble_evt->header.evt_id);
+
+ // Forward the event to BLE observers.
+ nrf_section_iter_t iter;
+ for (nrf_section_iter_init(&iter, &sdh_ble_observers);
+ nrf_section_iter_get(&iter) != NULL;
+ nrf_section_iter_next(&iter))
+ {
+ nrf_sdh_ble_evt_observer_t * p_observer;
+ nrf_sdh_ble_evt_handler_t handler;
+
+ p_observer = (nrf_sdh_ble_evt_observer_t *)nrf_section_iter_get(&iter);
+ handler = p_observer->handler;
+
+ handler(p_ble_evt, p_observer->p_context);
+ }
+ }
+
+ if (ret_code != NRF_ERROR_NOT_FOUND)
+ {
+ APP_ERROR_HANDLER(ret_code);
+ }
+}
+
+
+NRF_SDH_STACK_OBSERVER(m_nrf_sdh_ble_evts_poll, NRF_SDH_BLE_STACK_OBSERVER_PRIO) =
+{
+ .handler = nrf_sdh_ble_evts_poll,
+ .p_context = NULL,
+};
+
+#endif // NRF_MODULE_ENABLED(NRF_SDH_BLE)
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/softdevice/common/nrf_sdh_ble.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/softdevice/common/nrf_sdh_ble.h
new file mode 100644
index 0000000..b737e1f
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/softdevice/common/nrf_sdh_ble.h
@@ -0,0 +1,184 @@
+/**
+ * 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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
+ *
+ * @defgroup nrf_sdh_ble BLE support in SoftDevice Handler
+ * @{
+ * @ingroup nrf_sdh
+ * @brief This file contains the declarations of types and functions required for BLE stack
+ * support.
+ */
+
+#ifndef NRF_SDH_BLE_H__
+#define NRF_SDH_BLE_H__
+
+#include "app_util.h"
+#include "ble.h"
+#include "nrf_section_iter.h"
+#include "sdk_config.h"
+#include "sdk_errors.h"
+
+#include <stdint.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** @brief Size of the buffer for a BLE event. */
+#define NRF_SDH_BLE_EVT_BUF_SIZE BLE_EVT_LEN_MAX(NRF_SDH_BLE_GATT_MAX_MTU_SIZE)
+
+
+#if !(defined(__LINT__))
+/**@brief Macro for registering @ref nrf_sdh_soc_evt_observer_t. Modules that want to be
+ * notified about SoC events must register the handler using this macro.
+ *
+ * @details This macro places the observer in a section named "sdh_soc_observers".
+ *
+ * @param[in] _name Observer name.
+ * @param[in] _prio Priority of the observer event handler.
+ * The smaller the number, the higher the priority.
+ * @param[in] _handler BLE event handler.
+ * @param[in] _context Parameter to the event handler.
+ * @hideinitializer
+ */
+#define NRF_SDH_BLE_OBSERVER(_name, _prio, _handler, _context) \
+STATIC_ASSERT(NRF_SDH_BLE_ENABLED, "NRF_SDH_BLE_ENABLED not set!"); \
+STATIC_ASSERT(_prio < NRF_SDH_BLE_OBSERVER_PRIO_LEVELS, "Priority level unavailable."); \
+NRF_SECTION_SET_ITEM_REGISTER(sdh_ble_observers, _prio, static nrf_sdh_ble_evt_observer_t _name) = \
+{ \
+ .handler = _handler, \
+ .p_context = _context \
+}
+
+/**@brief Macro for registering an array of @ref nrf_sdh_ble_evt_observer_t.
+ * Modules that want to be notified about SoC events must register the handler using
+ * this macro.
+ *
+ * Each observer's handler will be dispatched an event with its relative context from @p _context.
+ * This macro places the observer in a section named "sdh_ble_observers".
+ *
+ * @param[in] _name Observer name.
+ * @param[in] _prio Priority of the observer event handler.
+ * The smaller the number, the higher the priority.
+ * @param[in] _handler BLE event handler.
+ * @param[in] _context An array of parameters to the event handler.
+ * @param[in] _cnt Number of observers to register.
+ * @hideinitializer
+ */
+#define NRF_SDH_BLE_OBSERVERS(_name, _prio, _handler, _context, _cnt) \
+STATIC_ASSERT(NRF_SDH_BLE_ENABLED, "NRF_SDH_BLE_ENABLED not set!"); \
+STATIC_ASSERT(_prio < NRF_SDH_BLE_OBSERVER_PRIO_LEVELS, "Priority level unavailable."); \
+NRF_SECTION_SET_ITEM_REGISTER(sdh_ble_observers, _prio, static nrf_sdh_ble_evt_observer_t _name[_cnt]) = \
+{ \
+ MACRO_REPEAT_FOR(_cnt, HANDLER_SET, _handler, _context) \
+}
+
+#if !(defined(DOXYGEN))
+#define HANDLER_SET(_idx, _handler, _context) \
+{ \
+ .handler = _handler, \
+ .p_context = _context[_idx], \
+},
+#endif
+
+#else // __LINT__
+
+/* Swallow semicolons */
+/*lint -save -esym(528, *) -esym(529, *) : Symbol not referenced. */
+#define NRF_SDH_BLE_OBSERVER(A, B, C, D) static int semicolon_swallow_##A
+#define NRF_SDH_BLE_OBSERVERS(A, B, C, D, E) static int semicolon_swallow_##A
+/*lint -restore */
+
+#endif
+
+
+/**@brief BLE stack event handler. */
+typedef void (*nrf_sdh_ble_evt_handler_t)(ble_evt_t const * p_ble_evt, void * p_context);
+
+/**@brief BLE event observer. */
+typedef struct
+{
+ nrf_sdh_ble_evt_handler_t handler; //!< BLE event handler.
+ void * p_context; //!< A parameter to the event handler.
+} const nrf_sdh_ble_evt_observer_t;
+
+
+/**@brief Function for retrieving the address of the start of application's RAM.
+ *
+ * @param[out] p_app_ram_start Address of the start of application's RAM.
+ *
+ * @retval NRF_SUCCESS If the address was successfully retrieved.
+ * @retval NRF_ERROR_NULL If @p p_app_ram_start was @c NULL.
+ */
+ret_code_t nrf_sdh_ble_app_ram_start_get(uint32_t * p_app_ram_start);
+
+
+/**@brief Set the default BLE stack configuration.
+ *
+ * This function configures the BLE stack with the settings specified in the
+ * SoftDevice handler BLE configuration. The following configurations will be set:
+ * - Number of peripheral links
+ * - Number of central links
+ * - ATT MTU size (for the given connection)
+ * - Vendor specific UUID count
+ * - GATTS Attribute table size
+ * - Service changed
+ *
+ * @param[in] conn_cfg_tag The connection to configure.
+ * @param[out] p_ram_start Application RAM start address.
+ */
+ret_code_t nrf_sdh_ble_default_cfg_set(uint8_t conn_cfg_tag, uint32_t * p_ram_start);
+
+
+/**@brief Function for configuring and enabling the BLE stack.
+ *
+ * @param[in] p_app_ram_start Address of the start of application's RAM.
+ */
+ret_code_t nrf_sdh_ble_enable(uint32_t * p_app_ram_start);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // NRF_SDH_BLE_H__
+
+/** @} */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/softdevice/common/nrf_sdh_freertos.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/softdevice/common/nrf_sdh_freertos.c
new file mode 100644
index 0000000..34d8263
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/softdevice/common/nrf_sdh_freertos.c
@@ -0,0 +1,109 @@
+/**
+ * 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+
+#include "nrf_sdh_freertos.h"
+#include "nrf_sdh.h"
+
+/* Group of FreeRTOS-related includes. */
+#include "FreeRTOS.h"
+#include "task.h"
+#include "queue.h"
+#include "semphr.h"
+
+#define NRF_LOG_MODULE_NAME nrf_sdh_freertos
+#include "nrf_log.h"
+NRF_LOG_MODULE_REGISTER();
+
+#define NRF_BLE_FREERTOS_SDH_TASK_STACK 256
+
+
+static TaskHandle_t m_softdevice_task; //!< Reference to SoftDevice FreeRTOS task.
+static nrf_sdh_freertos_task_hook_t m_task_hook; //!< A hook function run by the SoftDevice task before entering its loop.
+
+
+void SD_EVT_IRQHandler(void)
+{
+ BaseType_t xYieldRequired;
+
+ xYieldRequired = xTaskResumeFromISR( m_softdevice_task );
+
+ if( xYieldRequired == pdTRUE )
+ {
+ portYIELD_FROM_ISR(xYieldRequired);
+ }
+}
+
+
+/* This function gets events from the SoftDevice and processes them. */
+static void softdevice_task(void * pvParameter)
+{
+ NRF_LOG_DEBUG("Enter softdevice_task.");
+
+ if (m_task_hook != NULL)
+ {
+ m_task_hook(pvParameter);
+ }
+
+ while (true)
+ {
+ nrf_sdh_evts_poll(); // Let the handlers run first, in case the EVENT occured before creating this task.
+ vTaskSuspend(NULL);
+ }
+}
+
+
+void nrf_sdh_freertos_init(nrf_sdh_freertos_task_hook_t hook_fn, void * p_context)
+{
+ NRF_LOG_DEBUG("Creating a SoftDevice task.");
+
+ m_task_hook = hook_fn;
+
+ BaseType_t xReturned = xTaskCreate(softdevice_task,
+ "BLE",
+ NRF_BLE_FREERTOS_SDH_TASK_STACK,
+ p_context,
+ 2,
+ &m_softdevice_task);
+ if (xReturned != pdPASS)
+ {
+ NRF_LOG_ERROR("SoftDevice task not created.");
+ APP_ERROR_HANDLER(NRF_ERROR_NO_MEM);
+ }
+}
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/softdevice/common/nrf_sdh_freertos.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/softdevice/common/nrf_sdh_freertos.h
new file mode 100644
index 0000000..2c408ea
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/softdevice/common/nrf_sdh_freertos.h
@@ -0,0 +1,72 @@
+/**
+ * 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+
+#ifndef NRF_SDH_FREERTOS_H__
+#define NRF_SDH_FREERTOS_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @name FreeRTOS implementation of SoftDevice Handler
+ * @{
+ * @ingroup nrf_sdh
+ */
+
+typedef void (*nrf_sdh_freertos_task_hook_t)(void * p_context);
+
+/**@brief Function for creating a task to retrieve SoftDevice events.
+ * @param[in] hook Function to run in the SoftDevice FreeRTOS task,
+ * before entering the task loop.
+ * @param[in] p_context Parameter for the function @p hook.
+ */
+void nrf_sdh_freertos_init(nrf_sdh_freertos_task_hook_t hook, void * p_context);
+
+/**
+ * @}
+ */
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* NRF_SDH_FREERTOS_H__ */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/softdevice/common/nrf_sdh_soc.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/softdevice/common/nrf_sdh_soc.c
new file mode 100644
index 0000000..496e731
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/softdevice/common/nrf_sdh_soc.c
@@ -0,0 +1,118 @@
+/**
+ * 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+
+#include "sdk_common.h"
+#if NRF_MODULE_ENABLED(NRF_SDH_SOC)
+
+#include "nrf_sdh_soc.h"
+
+#include "nrf_sdh.h"
+#include "nrf_soc.h"
+#include "app_error.h"
+
+
+#define NRF_LOG_MODULE_NAME nrf_sdh_soc
+#if NRF_SDH_SOC_LOG_ENABLED
+ #define NRF_LOG_LEVEL NRF_SDH_SOC_LOG_LEVEL
+ #define NRF_LOG_INFO_COLOR NRF_SDH_SOC_INFO_COLOR
+ #define NRF_LOG_DEBUG_COLOR NRF_SDH_SOC_DEBUG_COLOR
+#else
+ #define NRF_LOG_LEVEL 0
+#endif // NRF_SDH_SOC_LOG_ENABLED
+#include "nrf_log.h"
+NRF_LOG_MODULE_REGISTER();
+
+
+// Create section set "sdh_soc_observers".
+NRF_SECTION_SET_DEF(sdh_soc_observers, nrf_sdh_soc_evt_observer_t, NRF_SDH_SOC_OBSERVER_PRIO_LEVELS);
+
+
+/**@brief Function for polling SoC events.
+ *
+ * @param[in] p_context Context of the observer.
+ */
+static void nrf_sdh_soc_evts_poll(void * p_context)
+{
+ ret_code_t ret_code;
+
+ UNUSED_VARIABLE(p_context);
+
+ while (true)
+ {
+ uint32_t evt_id;
+
+ ret_code = sd_evt_get(&evt_id);
+ if (ret_code != NRF_SUCCESS)
+ {
+ break;
+ }
+
+ NRF_LOG_DEBUG("SoC event: 0x%x.", evt_id);
+
+ // Forward the event to SoC observers.
+ nrf_section_iter_t iter;
+ for (nrf_section_iter_init(&iter, &sdh_soc_observers);
+ nrf_section_iter_get(&iter) != NULL;
+ nrf_section_iter_next(&iter))
+ {
+ nrf_sdh_soc_evt_observer_t * p_observer;
+ nrf_sdh_soc_evt_handler_t handler;
+
+ p_observer = (nrf_sdh_soc_evt_observer_t *) nrf_section_iter_get(&iter);
+ handler = p_observer->handler;
+
+ handler(evt_id, p_observer->p_context);
+ }
+ }
+
+ if (ret_code != NRF_ERROR_NOT_FOUND)
+ {
+ APP_ERROR_HANDLER(ret_code);
+ }
+}
+
+
+NRF_SDH_STACK_OBSERVER(m_nrf_sdh_soc_evts_poll, NRF_SDH_SOC_STACK_OBSERVER_PRIO) =
+{
+ .handler = nrf_sdh_soc_evts_poll,
+ .p_context = NULL,
+};
+
+#endif // NRF_MODULE_ENABLED(NRF_SDH_SOC)
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/softdevice/common/nrf_sdh_soc.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/softdevice/common/nrf_sdh_soc.h
new file mode 100644
index 0000000..295ce09
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/softdevice/common/nrf_sdh_soc.h
@@ -0,0 +1,143 @@
+/**
+ * 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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
+ *
+ * @defgroup nrf_sdh_soc SoC support in SoftDevice Handler
+ * @{
+ * @ingroup nrf_sdh
+ * @brief This file contains the declarations of types and functions required for SoftDevice Handler
+ * SoC support.
+ */
+
+#ifndef NRF_SDH_SOC_H__
+#define NRF_SDH_SOC_H__
+
+#include "sdk_common.h"
+#include "nrf_section_iter.h"
+#include "nrf_soc.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+#if !(defined(__LINT__))
+/**@brief Macro for registering @ref nrf_sdh_soc_evt_observer_t. Modules that want to be
+ * notified about SoC events must register the handler using this macro.
+ *
+ * @details This macro places the observer in a section named "sdh_soc_observers".
+ *
+ * @param[in] _name Observer name.
+ * @param[in] _prio Priority of the observer event handler.
+ * The smaller the number, the higher the priority.
+ * @param[in] _handler SoC event handler.
+ * @param[in] _context Parameter to the event handler.
+ * @hideinitializer
+ */
+#define NRF_SDH_SOC_OBSERVER(_name, _prio, _handler, _context) \
+STATIC_ASSERT(NRF_SDH_SOC_ENABLED, "NRF_SDH_SOC_ENABLED not set!"); \
+STATIC_ASSERT(_prio < NRF_SDH_SOC_OBSERVER_PRIO_LEVELS, "Priority level unavailable."); \
+NRF_SECTION_SET_ITEM_REGISTER(sdh_soc_observers, _prio, static nrf_sdh_soc_evt_observer_t _name) = \
+{ \
+ .handler = _handler, \
+ .p_context = _context \
+}
+
+/**@brief Macro for registering an array of @ref nrf_sdh_soc_evt_observer_t.
+ * Modules that want to be notified about SoC events must register the handler using
+ * this macro.
+ *
+ * Each observer's handler will be dispatched an event with its relative context from @p _context.
+ * This macro places the observer in a section named "sdh_soc_observers".
+ *
+ * @param[in] _name Observer name.
+ * @param[in] _prio Priority of the observer event handler.
+ * The smaller the number, the higher the priority.
+ * @param[in] _handler SoC event handler.
+ * @param[in] _context An array of parameters to the event handler.
+ * @param[in] _cnt Number of observers to register.
+ * @hideinitializer
+ */
+#define NRF_SDH_SOC_EVENT_OBSERVERS(_name, _prio, _handler, _context, _cnt) \
+STATIC_ASSERT(NRF_SDH_SOC_ENABLED, "NRF_SDH_SOC_ENABLED not set!"); \
+STATIC_ASSERT(_prio < NRF_SDH_SOC_OBSERVER_PRIO_LEVELS, "Priority level unavailable."); \
+NRF_SECTION_SET_ITEM_REGISTER(sdh_soc_observers, _prio, static nrf_sdh_soc_evt_observer_t _name[_cnt]) = \
+{ \
+ MACRO_REPEAT_FOR(_cnt, HANDLER_SET, _handler, _context) \
+}
+
+#if !(defined(DOXYGEN))
+#define HANDLER_SET(_idx, _handler, _context) \
+{ \
+ .handler = _handler, \
+ .p_context = _context[_idx], \
+},
+#endif
+
+#else // __LINT__
+
+/* Swallow semicolons */
+/*lint -save -esym(528, *) -esym(529, *) : Symbol not referenced. */
+#define NRF_SDH_SOC_OBSERVER(A, B, C, D) static int semicolon_swallow_##A
+#define NRF_SDH_SOC_OBSERVERS(A, B, C, D, E) static int semicolon_swallow_##A
+/*lint -restore */
+
+#endif
+
+
+/**@brief SoC event handler. */
+typedef void (*nrf_sdh_soc_evt_handler_t) (uint32_t evt_id, void * p_context);
+
+/**@brief SoC event observer. */
+typedef struct
+{
+ nrf_sdh_soc_evt_handler_t handler; //!< SoC event handler.
+ void * p_context; //!< A parameter to the event handler.
+} const nrf_sdh_soc_evt_observer_t;
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // NRF_SDH_SOC_H__
+
+/** @} */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/softdevice/mbr/nrf52810/headers b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/softdevice/mbr/nrf52810/headers
new file mode 100644
index 0000000..292c692
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/softdevice/mbr/nrf52810/headers
@@ -0,0 +1,90 @@
+/*
+ * Copyright (c) 2012 - 2017, 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ */
+
+#ifndef NRF_SVC__
+#define NRF_SVC__
+
+#include "stdint.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifdef SVCALL_AS_NORMAL_FUNCTION
+#define SVCALL(number, return_type, signature) return_type signature
+#else
+
+#ifndef SVCALL
+#if defined (__CC_ARM)
+#define SVCALL(number, return_type, signature) return_type __svc(number) signature
+#elif defined (__GNUC__)
+#ifdef __cplusplus
+#define GCC_CAST_CPP (uint16_t)
+#else
+#define GCC_CAST_CPP
+#endif
+#define SVCALL(number, return_type, signature) \
+ _Pragma("GCC diagnostic push") \
+ _Pragma("GCC diagnostic ignored \"-Wreturn-type\"") \
+ __attribute__((naked)) \
+ __attribute__((unused)) \
+ static return_type signature \
+ { \
+ __asm( \
+ "svc %0\n" \
+ "bx r14" : : "I" (GCC_CAST_CPP number) : "r0" \
+ ); \
+ } \
+ _Pragma("GCC diagnostic pop")
+
+#elif defined (__ICCARM__)
+#define PRAGMA(x) _Pragma(#x)
+#define SVCALL(number, return_type, signature) \
+PRAGMA(swi_number = (number)) \
+ __swi return_type signature;
+#else
+#define SVCALL(number, return_type, signature) return_type signature
+#endif
+#endif // SVCALL
+
+#endif // SVCALL_AS_NORMAL_FUNCTION
+
+#ifdef __cplusplus
+}
+#endif
+#endif // NRF_SVC__
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/softdevice/mbr/nrf52810/hex/mbr_nrf52_2.2.2_licence-agreement.txt b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/softdevice/mbr/nrf52810/hex/mbr_nrf52_2.2.2_licence-agreement.txt
new file mode 100644
index 0000000..a71adee
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/softdevice/mbr/nrf52810/hex/mbr_nrf52_2.2.2_licence-agreement.txt
@@ -0,0 +1,35 @@
+Copyright (c) 2007 - 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, except as embedded into a Nordic
+ Semiconductor ASA integrated circuit in a product or a software update for
+ such product, 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.
+
+4. This software, with or without modification, must only be used with a
+ Nordic Semiconductor ASA integrated circuit.
+
+5. Any software provided in binary form under this license must not be reverse
+ engineered, decompiled, modified and/or disassembled.
+
+THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/softdevice/mbr/nrf52810/hex/mbr_nrf52_2.2.2_mbr.hex b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/softdevice/mbr/nrf52810/hex/mbr_nrf52_2.2.2_mbr.hex
new file mode 100644
index 0000000..1944f66
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/softdevice/mbr/nrf52810/hex/mbr_nrf52_2.2.2_mbr.hex
@@ -0,0 +1,154 @@
+:020000040000FA
+:1000000000040020E90800007D050000C908000088
+:1000100087050000910500009B050000000000001E
+:100020000000000000000000000000000D090000BA
+:10003000A505000000000000AF050000B9050000A4
+:10004000C3050000CD050000D7050000E105000054
+:10005000EB050000F5050000FF05000009060000A3
+:10006000130600001D0600002706000031060000F0
+:100070003B060000450600004F0600005906000040
+:10008000630600006D060000770600008106000090
+:100090008B060000950600009F060000A9060000E0
+:1000A000B3060000BD060000C7060000D106000030
+:1000B000DB060000E5060000EF060000F906000080
+:1000C000030700000D0700001707000021070000CC
+:1000D0002B070000350700003F070000490700001C
+:1000E000530700005D07000067070000710700006C
+:1000F0007B070000850700008F07000099070000BC
+:10010000A30700001FB500F003F88DE80F001FBD26
+:1001100000F0E0BB1FB56FF00100009040100390AD
+:10012000029001904FF010208069000B420900F00E
+:100130001F045DF822300120A04083434DF8223097
+:10014000684600F045F91FBDF0B54FF6FF734FF458
+:10015000B4751A466E1E11E0A94201D3344600E080
+:100160000C46091B30F8027B641E3B441A44F9D14B
+:100170009CB204EB134394B204EB12420029EBD17E
+:1001800098B200EB134002EB124140EA0140F0BD8F
+:10019000DE4992B00446D1E90001CDE91001FF2209
+:1001A0004021684600F03CFB94E80F008DE80F000A
+:1001B000684610A902E004C841F8042D8842FAD12B
+:1001C00010216846FFF7C0FF1090AA208DF8440068
+:1001D000FFF7A0FF00F0F3F84FF01024A069102201
+:1001E0006946803000F002F9A069082210A900F0E9
+:1001F000FDF800F0D8F84FF080510A6949690068AD
+:100200004A43824201D8102070470020704710B541
+:10021000D0E900214FF0805002EB8103026944696C
+:100220006243934209D84FF01022536903EB8103D4
+:100230000169406941438B4201D9092010BD5069D1
+:10024000401C01D0002010BD0F2010BD70B501680A
+:100250000446AF4D4FF01020072952D2DFE801F0DD
+:10026000330419293C1E2500D4E902656468294637
+:10027000304600F0CDF82A462146304600F0B6F868
+:10028000AA002146304600F09FFA002800D0032043
+:1002900070BD00F051FB4FF4805007E0201DFFF7C8
+:1002A000AAFF0028F4D100F047FB60682860002016
+:1002B00070BD241D94E80700920000F085FA002824
+:1002C000F6D00E2070BD8069401C12D0201DFFF7B3
+:1002D0009EFF0028F6D109E08069401C09D0201D4E
+:1002E000FFF789FF0028EDD1606820B12046FFF7B5
+:1002F0004FFF042070BDFFF70DFF00F060F800F025
+:1003000052F8072070BD10B50C46182802D0012005
+:10031000086010BD2068FFF799FF206010BD4FF006
+:100320001024A069401C05D0A569A66980353079E4
+:10033000AA2808D06069401C2DD060690068401C64
+:1003400029D060692CE010212846FFF7FDFE3168B6
+:1003500081421CD1A16901F18002C03105E030B1B8
+:1003600008CA51F8040D984201D1012000E0002094
+:100370008A42F4D158B1286810B1042803D0FEE7AE
+:10038000284600F057F862496868086008E000F005
+:1003900016F800F008F84FF480500168491C01D0AD
+:1003A00000F0A4FAFEE7BFF34F8F5A4801685A4A9B
+:1003B00001F4E06111430160BFF34F8FFEE74FF09E
+:1003C00010208169491C02D0806900F0AEB87047E6
+:1003D000524A01681160121D416811604F4A8168DC
+:1003E00010321160111DC068086070472DE9F0419E
+:1003F00017460D460646002406E03046296800F000
+:10040000A7F8641C2D1D361DBC42F6D3BDE8F08153
+:1004100070B50C4605464FF4806608E0284600F0AB
+:1004200084F8B44205D3A4F5806405F58055002C0A
+:10043000F4D170BD4168044609B1012500E00025F2
+:100440004FF010267069A268920000F0BDF9C8B1A3
+:10045000204600F01AF89DB17669A56864684FF4EB
+:10046000002084420AD2854208D229463046FFF74E
+:10047000CFFF2A4621463046FFF7B8FFFFF79FFF20
+:10048000FFF791FFFFF746FEF8E72DE9FF414FF038
+:100490001024616980680D0B01EB800000F6FF708D
+:1004A000010B0020009001900290024603906846E4
+:1004B00001230BE0560902F01F0C50F8267003FAD6
+:1004C0000CFC47EA0C0740F82670521CAA42F1D3F4
+:1004D0000AE04A0901F01F0650F8225003FA06F616
+:1004E000354340F82250491C8029F2D3A169090BF9
+:1004F0004A0901F01F0150F822408B409C4340F80C
+:100500002240FFF765FFBDE8FF8100005C090000A5
+:10051000000000200CED00E00400FA050006004099
+:10052000144801680029FCD07047134A0221116069
+:1005300010490B68002BFCD00F4B1B1D186008687E
+:100540000028FCD00020106008680028FCD070470C
+:10055000094B10B501221A60064A1468002CFCD021
+:10056000016010680028FCD0002018601068002886
+:10057000FCD010BD00E4014004E5014008208F4993
+:1005800009680958084710208C4909680958084724
+:1005900014208A49096809580847182087490968BA
+:1005A0000958084730208549096809580847382004
+:1005B00082490968095808473C2080490968095858
+:1005C000084740207D4909680958084744207B496D
+:1005D00009680958084748207849096809580847B0
+:1005E0004C20764909680958084750207349096822
+:1005F0000958084754207149096809580847582084
+:100600006E490968095808475C206C49096809580F
+:100610000847602069490968095808476420674904
+:100620000968095808476820644909680958084753
+:100630006C20624909680958084770205F490968B9
+:100640000958084774205D49096809580847782007
+:100650005A490968095808477C20584909680958C7
+:10066000084780205549096809580847842053499C
+:1006700009680958084788205049096809580847F7
+:100680008C204E4909680958084790204B49096851
+:10069000095808479420494909680958084798208B
+:1006A00046490968095808479C204449096809587F
+:1006B0000847A0204149096809580847A4203F4934
+:1006C000096809580847A8203C490968095808479B
+:1006D000AC203A49096809580847B02037490968E9
+:1006E00009580847B4203549096809580847B8200F
+:1006F0003249096809580847BC2030490968095837
+:100700000847C0202D49096809580847C4202B49CB
+:10071000096809580847C82028490968095808473E
+:10072000CC202649096809580847D0202349096880
+:1007300009580847D4202149096809580847D82092
+:100740001E49096809580847DC201C4909680958EE
+:100750000847E0201949096809580847E420174963
+:10076000096809580847E8201449096809580847E2
+:10077000EC201249096809580847F0200F49096818
+:1007800009580847F4200D49096809580847F82016
+:100790000A49096809580847FC20084909680958A6
+:1007A00008475FF480700549096809580847000048
+:1007B00003480449024A034B704700000000002030
+:1007C000680900006809000040EA010310B59B07B2
+:1007D0000FD1042A0DD310C808C9121F9C42F8D0AB
+:1007E00020BA19BA884201D9012010BD4FF0FF305C
+:1007F00010BD1AB1D30703D0521C07E0002010BD72
+:1008000010F8013B11F8014B1B1B07D110F8013BFD
+:1008100011F8014B1B1B01D1921EF1D1184610BDDE
+:1008200002F0FF0343EA032242EA024200F005B865
+:100830007047704770474FF000020429C0F01280E3
+:1008400010F0030C00F01B80CCF1040CBCF1020F83
+:1008500018BF00F8012BA8BF20F8022BA1EB0C0158
+:1008600000F00DB85FEAC17C24BF00F8012B00F84E
+:10087000012B48BF00F8012B70474FF0000200B574
+:10088000134694469646203922BFA0E80C50A0E8B3
+:100890000C50B1F12001BFF4F7AF090728BFA0E861
+:1008A0000C5048BF0CC05DF804EB890028BF40F82D
+:1008B000042B08BF704748BF20F8022B11F0804F6F
+:1008C00018BF00F8012B7047014B1B68DB68184705
+:1008D0000000002009480A497047FFF7FBFFFFF7B7
+:1008E00011FC00BD20BFFDE7064B1847064A10600B
+:1008F000016881F30888406800470000680900002B
+:10090000680900001F030000000000201EF0040F13
+:100910000CBFEFF30881EFF3098188690238007892
+:10092000182803D100E00000074A1047074A126860
+:100930002C3212681047000000B5054B1B68054AB1
+:100940009B58984700BD00000703000000000020EE
+:100950005809000004000000001000000000000022
+:0809600000FFFFFF0090D0032F
+:04000005000008E906
+:00000001FF
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/softdevice/mbr/nrf52832/headers/nrf_mbr.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/softdevice/mbr/nrf52832/headers/nrf_mbr.h
new file mode 100644
index 0000000..cc5971c
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/softdevice/mbr/nrf52832/headers/nrf_mbr.h
@@ -0,0 +1,241 @@
+/*
+ * Copyright (c) 2014 - 2017, 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ */
+
+/**
+ @defgroup nrf_mbr_api Master Boot Record API
+ @{
+
+ @brief APIs for updating SoftDevice and BootLoader
+
+*/
+
+#ifndef NRF_MBR_H__
+#define NRF_MBR_H__
+
+#include "nrf_svc.h"
+#include <stdint.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** @addtogroup NRF_MBR_DEFINES Defines
+ * @{ */
+
+/**@brief MBR SVC Base number. */
+#define MBR_SVC_BASE (0x18)
+
+/**@brief Page size in words. */
+#define MBR_PAGE_SIZE_IN_WORDS (1024)
+
+/** @brief The size that must be reserved for the MBR when a SoftDevice is written to flash.
+This is the offset where the first byte of the SoftDevice hex file is written.*/
+#define MBR_SIZE (0x1000)
+
+/** @} */
+
+/** @addtogroup NRF_MBR_ENUMS Enumerations
+ * @{ */
+
+/**@brief nRF Master Boot Record API SVC numbers. */
+enum NRF_MBR_SVCS
+{
+ SD_MBR_COMMAND = MBR_SVC_BASE, /**< ::sd_mbr_command */
+};
+
+/**@brief Possible values for ::sd_mbr_command_t.command */
+enum NRF_MBR_COMMANDS
+{
+ SD_MBR_COMMAND_COPY_BL, /**< Copy a new BootLoader. @see ::sd_mbr_command_copy_bl_t*/
+ SD_MBR_COMMAND_COPY_SD, /**< Copy a new SoftDevice. @see ::sd_mbr_command_copy_sd_t*/
+ SD_MBR_COMMAND_INIT_SD, /**< Initialize forwarding interrupts to SD, and run reset function in SD. Does not require any parameters in ::sd_mbr_command_t params.*/
+ SD_MBR_COMMAND_COMPARE, /**< This command works like memcmp. @see ::sd_mbr_command_compare_t*/
+ SD_MBR_COMMAND_VECTOR_TABLE_BASE_SET, /**< Change the address the MBR starts after a reset. @see ::sd_mbr_command_vector_table_base_set_t*/
+ SD_MBR_COMMAND_RESERVED,
+ SD_MBR_COMMAND_IRQ_FORWARD_ADDRESS_SET, /**< Start forwarding all interrupts to this address. @see ::sd_mbr_command_irq_forward_address_set_t*/
+};
+
+/** @} */
+
+/** @addtogroup NRF_MBR_TYPES Types
+ * @{ */
+
+/**@brief This command copies part of a new SoftDevice
+ *
+ * The destination area is erased before copying.
+ * If dst is in the middle of a flash page, that whole flash page will be erased.
+ * If (dst+len) is in the middle of a flash page, that whole flash page will be erased.
+ *
+ * The user of this function is responsible for setting the BPROT registers.
+ *
+ * @retval ::NRF_SUCCESS indicates that the contents of the memory blocks where copied correctly.
+ * @retval ::NRF_ERROR_INTERNAL indicates that the contents of the memory blocks where not verified correctly after copying.
+ */
+typedef struct
+{
+ uint32_t *src; /**< Pointer to the source of data to be copied.*/
+ uint32_t *dst; /**< Pointer to the destination where the content is to be copied.*/
+ uint32_t len; /**< Number of 32 bit words to copy. Must be a multiple of @ref MBR_PAGE_SIZE_IN_WORDS words.*/
+} sd_mbr_command_copy_sd_t;
+
+
+/**@brief This command works like memcmp, but takes the length in words.
+ *
+ * @retval ::NRF_SUCCESS indicates that the contents of both memory blocks are equal.
+ * @retval ::NRF_ERROR_NULL indicates that the contents of the memory blocks are not equal.
+ */
+typedef struct
+{
+ uint32_t *ptr1; /**< Pointer to block of memory. */
+ uint32_t *ptr2; /**< Pointer to block of memory. */
+ uint32_t len; /**< Number of 32 bit words to compare.*/
+} sd_mbr_command_compare_t;
+
+
+/**@brief This command copies a new BootLoader.
+ *
+ * With this command, destination of BootLoader is always the address written in
+ * NRF_UICR->BOOTADDR.
+ *
+ * Destination is erased by this function.
+ * If (destination+bl_len) is in the middle of a flash page, that whole flash page will be erased.
+ *
+ * This function will use PROTENSET to protect the flash that is not intended to be written.
+ *
+ * On success, this function will not return. It will start the new BootLoader from reset-vector as normal.
+ *
+ * @retval ::NRF_ERROR_INTERNAL indicates an internal error that should not happen.
+ * @retval ::NRF_ERROR_FORBIDDEN if NRF_UICR->BOOTADDR is not set.
+ * @retval ::NRF_ERROR_INVALID_LENGTH if parameters attempts to read or write outside flash area.
+ * @retval ::NRF_ERROR_NO_MEM if no parameter page is provided (see SoftDevice Specification for more info)
+ */
+typedef struct
+{
+ uint32_t *bl_src; /**< Pointer to the source of the Bootloader to be be copied.*/
+ uint32_t bl_len; /**< Number of 32 bit words to copy for BootLoader. */
+} sd_mbr_command_copy_bl_t;
+
+/**@brief Change the address the MBR starts after a reset
+ *
+ * Once this function has been called, this address is where the MBR will start to forward
+ * interrupts to after a reset.
+ *
+ * To restore default forwarding this function should be called with @ref address set to 0. The
+ * MBR will then start forwarding interrupts to the address in NFR_UICR->BOOTADDR or to the
+ * SoftDevice if the BOOTADDR is not set.
+ *
+ * On success, this function will not return. It will reset the device.
+ *
+ * @retval ::NRF_ERROR_INTERNAL indicates an internal error that should not happen.
+ * @retval ::NRF_ERROR_INVALID_ADDR if parameter address is outside of the flash size.
+ * @retval ::NRF_ERROR_NO_MEM if no parameter page is provided (see SoftDevice Specification for more info)
+ */
+typedef struct
+{
+ uint32_t address; /**< The base address of the interrupt vector table for forwarded interrupts.*/
+} sd_mbr_command_vector_table_base_set_t;
+
+/**@brief Sets the base address of the interrupt vector table for interrupts forwarded from the MBR
+ *
+ * Unlike sd_mbr_command_vector_table_base_set_t, this function does not reset, and it does not
+ * change where the MBR starts after reset.
+ *
+ * @retval ::NRF_SUCCESS
+ */
+typedef struct
+{
+ uint32_t address; /**< The base address of the interrupt vector table for forwarded interrupts.*/
+} sd_mbr_command_irq_forward_address_set_t;
+
+/**@brief Input structure containing data used when calling ::sd_mbr_command
+ *
+ * Depending on what command value that is set, the corresponding params value type must also be
+ * set. See @ref NRF_MBR_COMMANDS for command types and corresponding params value type. If command
+ * @ref SD_MBR_COMMAND_INIT_SD is set, it is not necessary to set any values under params.
+ */
+typedef struct
+{
+ uint32_t command; /**< Type of command to be issued. See @ref NRF_MBR_COMMANDS. */
+ union
+ {
+ sd_mbr_command_copy_sd_t copy_sd; /**< Parameters for copy SoftDevice.*/
+ sd_mbr_command_compare_t compare; /**< Parameters for verify.*/
+ sd_mbr_command_copy_bl_t copy_bl; /**< Parameters for copy BootLoader. Requires parameter page. */
+ sd_mbr_command_vector_table_base_set_t base_set; /**< Parameters for vector table base set. Requires parameter page.*/
+ sd_mbr_command_irq_forward_address_set_t irq_forward_address_set; /**< Parameters for irq forward address set*/
+ } params; /**< Command parameters. */
+} sd_mbr_command_t;
+
+/** @} */
+
+/** @addtogroup NRF_MBR_FUNCTIONS Functions
+ * @{ */
+
+/**@brief Issue Master Boot Record commands
+ *
+ * Commands used when updating a SoftDevice and bootloader.
+ *
+ * The @ref SD_MBR_COMMAND_COPY_BL and @ref SD_MBR_COMMAND_VECTOR_TABLE_BASE_SET requires
+ * parameters to be retained by the MBR when resetting the IC. This is done in a separate flash
+ * page provided by the application. The UICR register UICR.NRFFW[1] must be set to an address
+ * corresponding to a page in the application flash space. This page will be cleared by the MBR and
+ * used to store the command before reset. When the UICR.NRFFW[1] field is set the page it refers
+ * to must not be used by the application. If the UICR.NRFFW[1] is set to 0xFFFFFFFF (the default)
+ * MBR commands which use flash will be unavailable and return @ref NRF_ERROR_NO_MEM.
+ *
+ * @param[in] param Pointer to a struct describing the command.
+ *
+ * @note For return values, see ::sd_mbr_command_copy_sd_t, ::sd_mbr_command_copy_bl_t,
+ * ::sd_mbr_command_compare_t, ::sd_mbr_command_vector_table_base_set_t,
+ * ::sd_mbr_command_irq_forward_address_set_t
+ *
+ * @retval ::NRF_ERROR_NO_MEM if UICR.NRFFW[1] is not set (i.e. is 0xFFFFFFFF).
+ * @retval ::NRF_ERROR_INVALID_PARAM if an invalid command is given.
+*/
+SVCALL(SD_MBR_COMMAND, uint32_t, sd_mbr_command(sd_mbr_command_t* param));
+
+/** @} */
+
+#ifdef __cplusplus
+}
+#endif
+#endif // NRF_MBR_H__
+
+/**
+ @}
+*/
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/softdevice/mbr/nrf52832/headers/nrf_svc.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/softdevice/mbr/nrf52832/headers/nrf_svc.h
new file mode 100644
index 0000000..292c692
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/softdevice/mbr/nrf52832/headers/nrf_svc.h
@@ -0,0 +1,90 @@
+/*
+ * Copyright (c) 2012 - 2017, 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ */
+
+#ifndef NRF_SVC__
+#define NRF_SVC__
+
+#include "stdint.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifdef SVCALL_AS_NORMAL_FUNCTION
+#define SVCALL(number, return_type, signature) return_type signature
+#else
+
+#ifndef SVCALL
+#if defined (__CC_ARM)
+#define SVCALL(number, return_type, signature) return_type __svc(number) signature
+#elif defined (__GNUC__)
+#ifdef __cplusplus
+#define GCC_CAST_CPP (uint16_t)
+#else
+#define GCC_CAST_CPP
+#endif
+#define SVCALL(number, return_type, signature) \
+ _Pragma("GCC diagnostic push") \
+ _Pragma("GCC diagnostic ignored \"-Wreturn-type\"") \
+ __attribute__((naked)) \
+ __attribute__((unused)) \
+ static return_type signature \
+ { \
+ __asm( \
+ "svc %0\n" \
+ "bx r14" : : "I" (GCC_CAST_CPP number) : "r0" \
+ ); \
+ } \
+ _Pragma("GCC diagnostic pop")
+
+#elif defined (__ICCARM__)
+#define PRAGMA(x) _Pragma(#x)
+#define SVCALL(number, return_type, signature) \
+PRAGMA(swi_number = (number)) \
+ __swi return_type signature;
+#else
+#define SVCALL(number, return_type, signature) return_type signature
+#endif
+#endif // SVCALL
+
+#endif // SVCALL_AS_NORMAL_FUNCTION
+
+#ifdef __cplusplus
+}
+#endif
+#endif // NRF_SVC__
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/softdevice/mbr/nrf52832/hex/mbr_nrf52_2.2.2_licence-agreement.txt b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/softdevice/mbr/nrf52832/hex/mbr_nrf52_2.2.2_licence-agreement.txt
new file mode 100644
index 0000000..a71adee
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/softdevice/mbr/nrf52832/hex/mbr_nrf52_2.2.2_licence-agreement.txt
@@ -0,0 +1,35 @@
+Copyright (c) 2007 - 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, except as embedded into a Nordic
+ Semiconductor ASA integrated circuit in a product or a software update for
+ such product, 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.
+
+4. This software, with or without modification, must only be used with a
+ Nordic Semiconductor ASA integrated circuit.
+
+5. Any software provided in binary form under this license must not be reverse
+ engineered, decompiled, modified and/or disassembled.
+
+THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/softdevice/mbr/nrf52832/hex/mbr_nrf52_2.2.2_mbr.hex b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/softdevice/mbr/nrf52832/hex/mbr_nrf52_2.2.2_mbr.hex
new file mode 100644
index 0000000..1944f66
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/softdevice/mbr/nrf52832/hex/mbr_nrf52_2.2.2_mbr.hex
@@ -0,0 +1,154 @@
+:020000040000FA
+:1000000000040020E90800007D050000C908000088
+:1000100087050000910500009B050000000000001E
+:100020000000000000000000000000000D090000BA
+:10003000A505000000000000AF050000B9050000A4
+:10004000C3050000CD050000D7050000E105000054
+:10005000EB050000F5050000FF05000009060000A3
+:10006000130600001D0600002706000031060000F0
+:100070003B060000450600004F0600005906000040
+:10008000630600006D060000770600008106000090
+:100090008B060000950600009F060000A9060000E0
+:1000A000B3060000BD060000C7060000D106000030
+:1000B000DB060000E5060000EF060000F906000080
+:1000C000030700000D0700001707000021070000CC
+:1000D0002B070000350700003F070000490700001C
+:1000E000530700005D07000067070000710700006C
+:1000F0007B070000850700008F07000099070000BC
+:10010000A30700001FB500F003F88DE80F001FBD26
+:1001100000F0E0BB1FB56FF00100009040100390AD
+:10012000029001904FF010208069000B420900F00E
+:100130001F045DF822300120A04083434DF8223097
+:10014000684600F045F91FBDF0B54FF6FF734FF458
+:10015000B4751A466E1E11E0A94201D3344600E080
+:100160000C46091B30F8027B641E3B441A44F9D14B
+:100170009CB204EB134394B204EB12420029EBD17E
+:1001800098B200EB134002EB124140EA0140F0BD8F
+:10019000DE4992B00446D1E90001CDE91001FF2209
+:1001A0004021684600F03CFB94E80F008DE80F000A
+:1001B000684610A902E004C841F8042D8842FAD12B
+:1001C00010216846FFF7C0FF1090AA208DF8440068
+:1001D000FFF7A0FF00F0F3F84FF01024A069102201
+:1001E0006946803000F002F9A069082210A900F0E9
+:1001F000FDF800F0D8F84FF080510A6949690068AD
+:100200004A43824201D8102070470020704710B541
+:10021000D0E900214FF0805002EB8103026944696C
+:100220006243934209D84FF01022536903EB8103D4
+:100230000169406941438B4201D9092010BD5069D1
+:10024000401C01D0002010BD0F2010BD70B501680A
+:100250000446AF4D4FF01020072952D2DFE801F0DD
+:10026000330419293C1E2500D4E902656468294637
+:10027000304600F0CDF82A462146304600F0B6F868
+:10028000AA002146304600F09FFA002800D0032043
+:1002900070BD00F051FB4FF4805007E0201DFFF7C8
+:1002A000AAFF0028F4D100F047FB60682860002016
+:1002B00070BD241D94E80700920000F085FA002824
+:1002C000F6D00E2070BD8069401C12D0201DFFF7B3
+:1002D0009EFF0028F6D109E08069401C09D0201D4E
+:1002E000FFF789FF0028EDD1606820B12046FFF7B5
+:1002F0004FFF042070BDFFF70DFF00F060F800F025
+:1003000052F8072070BD10B50C46182802D0012005
+:10031000086010BD2068FFF799FF206010BD4FF006
+:100320001024A069401C05D0A569A66980353079E4
+:10033000AA2808D06069401C2DD060690068401C64
+:1003400029D060692CE010212846FFF7FDFE3168B6
+:1003500081421CD1A16901F18002C03105E030B1B8
+:1003600008CA51F8040D984201D1012000E0002094
+:100370008A42F4D158B1286810B1042803D0FEE7AE
+:10038000284600F057F862496868086008E000F005
+:1003900016F800F008F84FF480500168491C01D0AD
+:1003A00000F0A4FAFEE7BFF34F8F5A4801685A4A9B
+:1003B00001F4E06111430160BFF34F8FFEE74FF09E
+:1003C00010208169491C02D0806900F0AEB87047E6
+:1003D000524A01681160121D416811604F4A8168DC
+:1003E00010321160111DC068086070472DE9F0419E
+:1003F00017460D460646002406E03046296800F000
+:10040000A7F8641C2D1D361DBC42F6D3BDE8F08153
+:1004100070B50C4605464FF4806608E0284600F0AB
+:1004200084F8B44205D3A4F5806405F58055002C0A
+:10043000F4D170BD4168044609B1012500E00025F2
+:100440004FF010267069A268920000F0BDF9C8B1A3
+:10045000204600F01AF89DB17669A56864684FF4EB
+:10046000002084420AD2854208D229463046FFF74E
+:10047000CFFF2A4621463046FFF7B8FFFFF79FFF20
+:10048000FFF791FFFFF746FEF8E72DE9FF414FF038
+:100490001024616980680D0B01EB800000F6FF708D
+:1004A000010B0020009001900290024603906846E4
+:1004B00001230BE0560902F01F0C50F8267003FAD6
+:1004C0000CFC47EA0C0740F82670521CAA42F1D3F4
+:1004D0000AE04A0901F01F0650F8225003FA06F616
+:1004E000354340F82250491C8029F2D3A169090BF9
+:1004F0004A0901F01F0150F822408B409C4340F80C
+:100500002240FFF765FFBDE8FF8100005C090000A5
+:10051000000000200CED00E00400FA050006004099
+:10052000144801680029FCD07047134A0221116069
+:1005300010490B68002BFCD00F4B1B1D186008687E
+:100540000028FCD00020106008680028FCD070470C
+:10055000094B10B501221A60064A1468002CFCD021
+:10056000016010680028FCD0002018601068002886
+:10057000FCD010BD00E4014004E5014008208F4993
+:1005800009680958084710208C4909680958084724
+:1005900014208A49096809580847182087490968BA
+:1005A0000958084730208549096809580847382004
+:1005B00082490968095808473C2080490968095858
+:1005C000084740207D4909680958084744207B496D
+:1005D00009680958084748207849096809580847B0
+:1005E0004C20764909680958084750207349096822
+:1005F0000958084754207149096809580847582084
+:100600006E490968095808475C206C49096809580F
+:100610000847602069490968095808476420674904
+:100620000968095808476820644909680958084753
+:100630006C20624909680958084770205F490968B9
+:100640000958084774205D49096809580847782007
+:100650005A490968095808477C20584909680958C7
+:10066000084780205549096809580847842053499C
+:1006700009680958084788205049096809580847F7
+:100680008C204E4909680958084790204B49096851
+:10069000095808479420494909680958084798208B
+:1006A00046490968095808479C204449096809587F
+:1006B0000847A0204149096809580847A4203F4934
+:1006C000096809580847A8203C490968095808479B
+:1006D000AC203A49096809580847B02037490968E9
+:1006E00009580847B4203549096809580847B8200F
+:1006F0003249096809580847BC2030490968095837
+:100700000847C0202D49096809580847C4202B49CB
+:10071000096809580847C82028490968095808473E
+:10072000CC202649096809580847D0202349096880
+:1007300009580847D4202149096809580847D82092
+:100740001E49096809580847DC201C4909680958EE
+:100750000847E0201949096809580847E420174963
+:10076000096809580847E8201449096809580847E2
+:10077000EC201249096809580847F0200F49096818
+:1007800009580847F4200D49096809580847F82016
+:100790000A49096809580847FC20084909680958A6
+:1007A00008475FF480700549096809580847000048
+:1007B00003480449024A034B704700000000002030
+:1007C000680900006809000040EA010310B59B07B2
+:1007D0000FD1042A0DD310C808C9121F9C42F8D0AB
+:1007E00020BA19BA884201D9012010BD4FF0FF305C
+:1007F00010BD1AB1D30703D0521C07E0002010BD72
+:1008000010F8013B11F8014B1B1B07D110F8013BFD
+:1008100011F8014B1B1B01D1921EF1D1184610BDDE
+:1008200002F0FF0343EA032242EA024200F005B865
+:100830007047704770474FF000020429C0F01280E3
+:1008400010F0030C00F01B80CCF1040CBCF1020F83
+:1008500018BF00F8012BA8BF20F8022BA1EB0C0158
+:1008600000F00DB85FEAC17C24BF00F8012B00F84E
+:10087000012B48BF00F8012B70474FF0000200B574
+:10088000134694469646203922BFA0E80C50A0E8B3
+:100890000C50B1F12001BFF4F7AF090728BFA0E861
+:1008A0000C5048BF0CC05DF804EB890028BF40F82D
+:1008B000042B08BF704748BF20F8022B11F0804F6F
+:1008C00018BF00F8012B7047014B1B68DB68184705
+:1008D0000000002009480A497047FFF7FBFFFFF7B7
+:1008E00011FC00BD20BFFDE7064B1847064A10600B
+:1008F000016881F30888406800470000680900002B
+:10090000680900001F030000000000201EF0040F13
+:100910000CBFEFF30881EFF3098188690238007892
+:10092000182803D100E00000074A1047074A126860
+:100930002C3212681047000000B5054B1B68054AB1
+:100940009B58984700BD00000703000000000020EE
+:100950005809000004000000001000000000000022
+:0809600000FFFFFF0090D0032F
+:04000005000008E906
+:00000001FF
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/softdevice/mbr/nrf52840/headers/nrf_mbr.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/softdevice/mbr/nrf52840/headers/nrf_mbr.h
new file mode 100644
index 0000000..e0c80e2
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/softdevice/mbr/nrf52840/headers/nrf_mbr.h
@@ -0,0 +1,242 @@
+/*
+ * Copyright (c) 2014 - 2017, 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ */
+
+/**
+ @defgroup nrf_mbr_api Master Boot Record API
+ @{
+
+ @brief APIs for updating SoftDevice and BootLoader
+
+*/
+
+#ifndef NRF_MBR_H__
+#define NRF_MBR_H__
+
+#include "nrf_svc.h"
+#include <stdint.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** @addtogroup NRF_MBR_DEFINES Defines
+ * @{ */
+
+/**@brief MBR SVC Base number. */
+#define MBR_SVC_BASE (0x18)
+
+/**@brief Page size in words. */
+#define MBR_PAGE_SIZE_IN_WORDS (1024)
+
+/** @brief The size that must be reserved for the MBR when a SoftDevice is written to flash.
+This is the offset where the first byte of the SoftDevice hex file is written.*/
+#define MBR_SIZE (0x1000)
+
+/** @} */
+
+/** @addtogroup NRF_MBR_ENUMS Enumerations
+ * @{ */
+
+/**@brief nRF Master Boot Record API SVC numbers. */
+enum NRF_MBR_SVCS
+{
+ SD_MBR_COMMAND = MBR_SVC_BASE, /**< ::sd_mbr_command */
+};
+
+/**@brief Possible values for ::sd_mbr_command_t.command */
+enum NRF_MBR_COMMANDS
+{
+ SD_MBR_COMMAND_COPY_BL, /**< Copy a new BootLoader. @see ::sd_mbr_command_copy_bl_t*/
+ SD_MBR_COMMAND_COPY_SD, /**< Copy a new SoftDevice. @see ::sd_mbr_command_copy_sd_t*/
+ SD_MBR_COMMAND_INIT_SD, /**< Initialize forwarding interrupts to SD, and run reset function in SD. Does not require any parameters in ::sd_mbr_command_t params.*/
+ SD_MBR_COMMAND_COMPARE, /**< This command works like memcmp. @see ::sd_mbr_command_compare_t*/
+ SD_MBR_COMMAND_VECTOR_TABLE_BASE_SET, /**< Change the address the MBR starts after a reset. @see ::sd_mbr_command_vector_table_base_set_t*/
+ SD_MBR_COMMAND_RESERVED,
+ SD_MBR_COMMAND_IRQ_FORWARD_ADDRESS_SET, /**< Start forwarding all interrupts to this address. @see ::sd_mbr_command_irq_forward_address_set_t*/
+};
+
+/** @} */
+
+/** @addtogroup NRF_MBR_TYPES Types
+ * @{ */
+
+/**@brief This command copies part of a new SoftDevice
+ *
+ * The destination area is erased before copying.
+ * If dst is in the middle of a flash page, that whole flash page will be erased.
+ * If (dst+len) is in the middle of a flash page, that whole flash page will be erased.
+ *
+ * The user of this function is responsible for setting the BPROT registers.
+ *
+ * @retval ::NRF_SUCCESS indicates that the contents of the memory blocks where copied correctly.
+ * @retval ::NRF_ERROR_INTERNAL indicates that the contents of the memory blocks where not verified correctly after copying.
+ */
+typedef struct
+{
+ uint32_t *src; /**< Pointer to the source of data to be copied.*/
+ uint32_t *dst; /**< Pointer to the destination where the content is to be copied.*/
+ uint32_t len; /**< Number of 32 bit words to copy. Must be a multiple of @ref MBR_PAGE_SIZE_IN_WORDS words.*/
+} sd_mbr_command_copy_sd_t;
+
+
+/**@brief This command works like memcmp, but takes the length in words.
+ *
+ * @retval ::NRF_SUCCESS indicates that the contents of both memory blocks are equal.
+ * @retval ::NRF_ERROR_NULL indicates that the contents of the memory blocks are not equal.
+ */
+typedef struct
+{
+ uint32_t *ptr1; /**< Pointer to block of memory. */
+ uint32_t *ptr2; /**< Pointer to block of memory. */
+ uint32_t len; /**< Number of 32 bit words to compare.*/
+} sd_mbr_command_compare_t;
+
+
+/**@brief This command copies a new BootLoader.
+ *
+ * With this command, destination of BootLoader is always the address written in
+ * NRF_UICR->BOOTADDR.
+ *
+ * Destination is erased by this function.
+ * If (destination+bl_len) is in the middle of a flash page, that whole flash page will be erased.
+ *
+ * This function will use the flash protect peripheral (BPROT or ACL) to protect the flash that is
+ * not intended to be written.
+ *
+ * On success, this function will not return. It will start the new BootLoader from reset-vector as normal.
+ *
+ * @retval ::NRF_ERROR_INTERNAL indicates an internal error that should not happen.
+ * @retval ::NRF_ERROR_FORBIDDEN if NRF_UICR->BOOTADDR is not set.
+ * @retval ::NRF_ERROR_INVALID_LENGTH if parameters attempts to read or write outside flash area.
+ * @retval ::NRF_ERROR_NO_MEM if no parameter page is provided (see SoftDevice Specification for more info)
+ */
+typedef struct
+{
+ uint32_t *bl_src; /**< Pointer to the source of the Bootloader to be be copied.*/
+ uint32_t bl_len; /**< Number of 32 bit words to copy for BootLoader. */
+} sd_mbr_command_copy_bl_t;
+
+/**@brief Change the address the MBR starts after a reset
+ *
+ * Once this function has been called, this address is where the MBR will start to forward
+ * interrupts to after a reset.
+ *
+ * To restore default forwarding this function should be called with @ref address set to 0. The
+ * MBR will then start forwarding interrupts to the address in NFR_UICR->BOOTADDR or to the
+ * SoftDevice if the BOOTADDR is not set.
+ *
+ * On success, this function will not return. It will reset the device.
+ *
+ * @retval ::NRF_ERROR_INTERNAL indicates an internal error that should not happen.
+ * @retval ::NRF_ERROR_INVALID_ADDR if parameter address is outside of the flash size.
+ * @retval ::NRF_ERROR_NO_MEM if no parameter page is provided (see SoftDevice Specification for more info)
+ */
+typedef struct
+{
+ uint32_t address; /**< The base address of the interrupt vector table for forwarded interrupts.*/
+} sd_mbr_command_vector_table_base_set_t;
+
+/**@brief Sets the base address of the interrupt vector table for interrupts forwarded from the MBR
+ *
+ * Unlike sd_mbr_command_vector_table_base_set_t, this function does not reset, and it does not
+ * change where the MBR starts after reset.
+ *
+ * @retval ::NRF_SUCCESS
+ */
+typedef struct
+{
+ uint32_t address; /**< The base address of the interrupt vector table for forwarded interrupts.*/
+} sd_mbr_command_irq_forward_address_set_t;
+
+/**@brief Input structure containing data used when calling ::sd_mbr_command
+ *
+ * Depending on what command value that is set, the corresponding params value type must also be
+ * set. See @ref NRF_MBR_COMMANDS for command types and corresponding params value type. If command
+ * @ref SD_MBR_COMMAND_INIT_SD is set, it is not necessary to set any values under params.
+ */
+typedef struct
+{
+ uint32_t command; /**< Type of command to be issued. See @ref NRF_MBR_COMMANDS. */
+ union
+ {
+ sd_mbr_command_copy_sd_t copy_sd; /**< Parameters for copy SoftDevice.*/
+ sd_mbr_command_compare_t compare; /**< Parameters for verify.*/
+ sd_mbr_command_copy_bl_t copy_bl; /**< Parameters for copy BootLoader. Requires parameter page. */
+ sd_mbr_command_vector_table_base_set_t base_set; /**< Parameters for vector table base set. Requires parameter page.*/
+ sd_mbr_command_irq_forward_address_set_t irq_forward_address_set; /**< Parameters for irq forward address set*/
+ } params; /**< Command parameters. */
+} sd_mbr_command_t;
+
+/** @} */
+
+/** @addtogroup NRF_MBR_FUNCTIONS Functions
+ * @{ */
+
+/**@brief Issue Master Boot Record commands
+ *
+ * Commands used when updating a SoftDevice and bootloader.
+ *
+ * The @ref SD_MBR_COMMAND_COPY_BL and @ref SD_MBR_COMMAND_VECTOR_TABLE_BASE_SET requires
+ * parameters to be retained by the MBR when resetting the IC. This is done in a separate flash
+ * page provided by the application. The UICR register UICR.NRFFW[1] must be set to an address
+ * corresponding to a page in the application flash space. This page will be cleared by the MBR and
+ * used to store the command before reset. When the UICR.NRFFW[1] field is set the page it refers
+ * to must not be used by the application. If the UICR.NRFFW[1] is set to 0xFFFFFFFF (the default)
+ * MBR commands which use flash will be unavailable and return @ref NRF_ERROR_NO_MEM.
+ *
+ * @param[in] param Pointer to a struct describing the command.
+ *
+ * @note For return values, see ::sd_mbr_command_copy_sd_t, ::sd_mbr_command_copy_bl_t,
+ * ::sd_mbr_command_compare_t, ::sd_mbr_command_vector_table_base_set_t,
+ * ::sd_mbr_command_irq_forward_address_set_t
+ *
+ * @retval ::NRF_ERROR_NO_MEM if UICR.NRFFW[1] is not set (i.e. is 0xFFFFFFFF).
+ * @retval ::NRF_ERROR_INVALID_PARAM if an invalid command is given.
+*/
+SVCALL(SD_MBR_COMMAND, uint32_t, sd_mbr_command(sd_mbr_command_t* param));
+
+/** @} */
+
+#ifdef __cplusplus
+}
+#endif
+#endif // NRF_MBR_H__
+
+/**
+ @}
+*/
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/softdevice/mbr/nrf52840/headers/nrf_svc.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/softdevice/mbr/nrf52840/headers/nrf_svc.h
new file mode 100644
index 0000000..292c692
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/softdevice/mbr/nrf52840/headers/nrf_svc.h
@@ -0,0 +1,90 @@
+/*
+ * Copyright (c) 2012 - 2017, 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ */
+
+#ifndef NRF_SVC__
+#define NRF_SVC__
+
+#include "stdint.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifdef SVCALL_AS_NORMAL_FUNCTION
+#define SVCALL(number, return_type, signature) return_type signature
+#else
+
+#ifndef SVCALL
+#if defined (__CC_ARM)
+#define SVCALL(number, return_type, signature) return_type __svc(number) signature
+#elif defined (__GNUC__)
+#ifdef __cplusplus
+#define GCC_CAST_CPP (uint16_t)
+#else
+#define GCC_CAST_CPP
+#endif
+#define SVCALL(number, return_type, signature) \
+ _Pragma("GCC diagnostic push") \
+ _Pragma("GCC diagnostic ignored \"-Wreturn-type\"") \
+ __attribute__((naked)) \
+ __attribute__((unused)) \
+ static return_type signature \
+ { \
+ __asm( \
+ "svc %0\n" \
+ "bx r14" : : "I" (GCC_CAST_CPP number) : "r0" \
+ ); \
+ } \
+ _Pragma("GCC diagnostic pop")
+
+#elif defined (__ICCARM__)
+#define PRAGMA(x) _Pragma(#x)
+#define SVCALL(number, return_type, signature) \
+PRAGMA(swi_number = (number)) \
+ __swi return_type signature;
+#else
+#define SVCALL(number, return_type, signature) return_type signature
+#endif
+#endif // SVCALL
+
+#endif // SVCALL_AS_NORMAL_FUNCTION
+
+#ifdef __cplusplus
+}
+#endif
+#endif // NRF_SVC__
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/softdevice/mbr/nrf52840/hex/mbr_nrf52_2.3.0_licence-agreement.txt b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/softdevice/mbr/nrf52840/hex/mbr_nrf52_2.3.0_licence-agreement.txt
new file mode 100644
index 0000000..a71adee
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/softdevice/mbr/nrf52840/hex/mbr_nrf52_2.3.0_licence-agreement.txt
@@ -0,0 +1,35 @@
+Copyright (c) 2007 - 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, except as embedded into a Nordic
+ Semiconductor ASA integrated circuit in a product or a software update for
+ such product, 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.
+
+4. This software, with or without modification, must only be used with a
+ Nordic Semiconductor ASA integrated circuit.
+
+5. Any software provided in binary form under this license must not be reverse
+ engineered, decompiled, modified and/or disassembled.
+
+THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/softdevice/mbr/nrf52840/hex/mbr_nrf52_2.3.0_mbr.hex b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/softdevice/mbr/nrf52840/hex/mbr_nrf52_2.3.0_mbr.hex
new file mode 100644
index 0000000..cf47635
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/softdevice/mbr/nrf52840/hex/mbr_nrf52_2.3.0_mbr.hex
@@ -0,0 +1,165 @@
+:020000040000FA
+:1000000000040020990900002D0600007909000075
+:1000100037060000410600004B060000000000000B
+:10002000000000000000000000000000BD0900000A
+:1000300055060000000000005F0600006906000091
+:10004000730600007D060000870600009106000090
+:100050009B060000A5060000AF060000B9060000E0
+:10006000C3060000CD060000D7060000E106000030
+:10007000EB060000F5060000FF060000090700007F
+:10008000130700001D0700002707000031070000CC
+:100090003B070000450700004F070000590700001C
+:1000A000630700006D07000077070000810700006C
+:1000B0008B070000950700009F070000A9070000BC
+:1000C000B3070000BD070000C7070000D10700000C
+:1000D000DB070000E5070000EF070000F90700005C
+:1000E000030800000D0800001708000021080000A8
+:1000F0002B080000350800003F08000049080000F8
+:10010000530800001FB500F003F88DE80F001FBD75
+:1001100000F038BC70B50B46010B184400F6FF70B8
+:10012000040B4FF080500022090303692403406947
+:1001300043431D1B104600F0E9F929462046BDE85F
+:10014000704000F0E3B9F0B54FF6FF734FF4B475AB
+:100150001A466E1E12E0A94201D3344600E00C4656
+:10016000B1EB040130F8027B641E3B441A44F9D120
+:100170009CB204EB134394B204EB12420029EAD17F
+:1001800098B200EB134002EB124140EA0140F0BD8F
+:10019000C34992B00446D1E90001CDE91001FF2224
+:1001A0004021684600F094FB94E80F008DE80F00B2
+:1001B000684610A902E004C841F8042D8842FAD12B
+:1001C00010216846FFF7BFFF1090AA208DF8440069
+:1001D00000F0FAF800F0DDF84FF01024A0691022CA
+:1001E0006946803000F0DEF8A069082210A900F00E
+:1001F000D9F800F0C2F870B504460068A94D072888
+:1002000069D2DFE800F033041929561E2500D4E92D
+:10021000026564682946304600F0FDF82A4621460A
+:10022000304600F0BFF8AA002146304600F024FB1B
+:10023000002800D0032070BD00F0D6FB4FF48050A2
+:1002400007E0201D00F0C6F80028F4D100F0CCFB38
+:1002500060682860002070BD241D94E807009200AB
+:1002600000F00AFB0028F6D00E2070BD00F0BEF8AA
+:100270000028FAD1D4E9010100EB81034FF080504E
+:10028000026945696A43934209D84FF010225369C5
+:1002900003EB81030169406941438B4201D9092085
+:1002A00070BD5069401C01D10F2070BD2046FFF782
+:1002B0006FFF00F09BF80028F7D1201D00F08AF8AE
+:1002C0000028F2D160680028F0D100F07DF800F03D
+:1002D00060F800F052F8072070BD10B50C461828E1
+:1002E00002D00120086010BD2068FFF784FF206065
+:1002F00010BD4FF01024A069401C05D0A569A66967
+:1003000080353079AA2808D06069401C2DD06069FA
+:100310000068401C29D060692CE010212846FFF7B6
+:1003200012FF316881421CD1A16901F18002C03104
+:1003300005E030B108CA51F8040D984201D10120FE
+:1003400000E000208A42F4D158B1286810B1042896
+:1003500003D0FEE7284600F070F85249686808604C
+:1003600008E000F016F800F008F84FF4805001683B
+:10037000491C01D000F012FBFEE7BFF34F8F4A4843
+:1003800001684A4A01F4E06111430160BFF34F8FF5
+:10039000FEE74FF010208169491C02D0806900F00F
+:1003A0008CB870472DE9F04117460D4606460024EB
+:1003B00006E03046296800F093F8641C2D1D361DB8
+:1003C000BC42F6D3BDE8F0814FF0102080694FF4B5
+:1003D00080519FE64FF080510A69496900684A439D
+:1003E000824201D810207047002070474FF08050A3
+:1003F0000169406941434FF01020826902F5805243
+:10040000914201D2092070478069401C01D0002030
+:1004100070470420704770B50C4605464FF480665F
+:1004200008E0284600F049F8B44205D3A4F58064FA
+:1004300005F58055002CF4D170BD4168044609B122
+:10044000012600E000264FF010256869A26892009E
+:1004500000F012FAF8B1A06881006869FFF75AFE4F
+:10046000BEB16E694FF08050A56864680169426949
+:100470005143A1420DD9016940694143A94208D9BC
+:1004800029463046FFF7C7FF2A4621463046FFF788
+:1004900089FFFFF772FFFFF797FFFFF77AFFF8E793
+:1004A0000C0A0000000000200CED00E00400FA053A
+:1004B000144801680029FCD07047134A02211160DA
+:1004C00010490B68002BFCD00F4B1B1D18600868EF
+:1004D0000028FCD00020106008680028FCD070477D
+:1004E000094B10B501221A60064A1468002CFCD092
+:1004F000016010680028FCD00020186010680028F7
+:10050000FCD010BD00E4014004E5014070B50C468C
+:10051000054600F073F810B900F07EF828B12146C6
+:100520002846BDE8704000F007B821462846BDE8DF
+:10053000704000F037B800007FB5002200920192B1
+:10054000029203920A0B000B6946012302440AE05F
+:10055000440900F01F0651F8245003FA06F635430B
+:1005600041F82450401C8242F2D80D490868009A94
+:1005700010430860081D0168019A1143016000F0F2
+:100580003DF800280AD0064910310868029A104345
+:100590000860091D0868039A104308607FBD0000C9
+:1005A0000006004030B50F4C002200BF04EB0213E0
+:1005B000D3F800582DB9D3F8045815B9D3F8085812
+:1005C0001DB1521C082AF1D330BD082AFCD204EB1D
+:1005D0000212C2F80008C3F804180220C3F8080881
+:1005E00030BD000000E001404FF08050D0F83001F5
+:1005F000082801D000207047012070474FF080503C
+:10060000D0F83011062905D0D0F83001401C01D0B7
+:1006100000207047012070474FF08050D0F8300123
+:100620000A2801D0002070470120704708208F4918
+:1006300009680958084710208C4909680958084773
+:1006400014208A4909680958084718208749096809
+:100650000958084730208549096809580847382053
+:1006600082490968095808473C20804909680958A7
+:10067000084740207D4909680958084744207B49BC
+:1006800009680958084748207849096809580847FF
+:100690004C20764909680958084750207349096871
+:1006A00009580847542071490968095808475820D3
+:1006B0006E490968095808475C206C49096809585F
+:1006C0000847602069490968095808476420674954
+:1006D00009680958084768206449096809580847A3
+:1006E0006C20624909680958084770205F49096809
+:1006F0000958084774205D49096809580847782057
+:100700005A490968095808477C2058490968095816
+:1007100008478020554909680958084784205349EB
+:100720000968095808478820504909680958084746
+:100730008C204E4909680958084790204B490968A0
+:1007400009580847942049490968095808479820DA
+:1007500046490968095808479C20444909680958CE
+:100760000847A0204149096809580847A4203F4983
+:10077000096809580847A8203C49096809580847EA
+:10078000AC203A49096809580847B0203749096838
+:1007900009580847B4203549096809580847B8205E
+:1007A0003249096809580847BC2030490968095886
+:1007B0000847C0202D49096809580847C4202B491B
+:1007C000096809580847C82028490968095808478E
+:1007D000CC202649096809580847D02023490968D0
+:1007E00009580847D4202149096809580847D820E2
+:1007F0001E49096809580847DC201C49096809583E
+:100800000847E0201949096809580847E4201749B2
+:10081000096809580847E820144909680958084731
+:10082000EC201249096809580847F0200F49096867
+:1008300009580847F4200D49096809580847F82065
+:100840000A49096809580847FC20084909680958F5
+:1008500008475FF480700549096809580847000097
+:1008600003480449024A034B70470000000000207F
+:10087000180A0000180A000040EA010310B59B079F
+:100880000FD1042A0DD310C808C9121F9C42F8D0FA
+:1008900020BA19BA884201D9012010BD4FF0FF30AB
+:1008A00010BD1AB1D30703D0521C07E0002010BDC1
+:1008B00010F8013B11F8014B1B1B07D110F8013B4D
+:1008C00011F8014B1B1B01D1921EF1D1184610BD2E
+:1008D00002F0FF0343EA032242EA024200F005B8B5
+:1008E0007047704770474FF000020429C0F0128033
+:1008F00010F0030C00F01B80CCF1040CBCF1020FD3
+:1009000018BF00F8012BA8BF20F8022BA1EB0C01A7
+:1009100000F00DB85FEAC17C24BF00F8012B00F89D
+:10092000012B48BF00F8012B70474FF0000200B5C3
+:10093000134694469646203922BFA0E80C50A0E802
+:100940000C50B1F12001BFF4F7AF090728BFA0E8B0
+:100950000C5048BF0CC05DF804EB890028BF40F87C
+:10096000042B08BF704748BF20F8022B11F0804FBE
+:1009700018BF00F8012B7047014B1B68DB68184754
+:100980000000002009480A497047FFF7FBFFFFF706
+:10099000B9FB00BD20BFFDE7064B1847064A1060B3
+:1009A000016881F30888406800470000180A0000C9
+:1009B000180A0000F3020000000000201EF0040FDF
+:1009C0000CBFEFF30881EFF30981886902380078E2
+:1009D000182803D100E00000074A1047074A1268B0
+:1009E0002C3212681047000000B5054B1B68054A01
+:1009F0009B58984700BD0000DB020000000000206B
+:100A0000080A0000040000000010000000000000C0
+:080A100000FFFFFF0090D0037E
+:040000050000099955
+:00000001FF
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/softdevice/s112/doc/s112_nrf52_6.0.0_licence-agreement.txt b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/softdevice/s112/doc/s112_nrf52_6.0.0_licence-agreement.txt
new file mode 100644
index 0000000..a71adee
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/softdevice/s112/doc/s112_nrf52_6.0.0_licence-agreement.txt
@@ -0,0 +1,35 @@
+Copyright (c) 2007 - 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, except as embedded into a Nordic
+ Semiconductor ASA integrated circuit in a product or a software update for
+ such product, 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.
+
+4. This software, with or without modification, must only be used with a
+ Nordic Semiconductor ASA integrated circuit.
+
+5. Any software provided in binary form under this license must not be reverse
+ engineered, decompiled, modified and/or disassembled.
+
+THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/softdevice/s112/doc/s112_nrf52_6.0.0_migration-document.pdf b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/softdevice/s112/doc/s112_nrf52_6.0.0_migration-document.pdf
new file mode 100644
index 0000000..6427793
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/softdevice/s112/doc/s112_nrf52_6.0.0_migration-document.pdf
Binary files differ
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/softdevice/s112/doc/s112_nrf52_6.0.0_release-notes.pdf b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/softdevice/s112/doc/s112_nrf52_6.0.0_release-notes.pdf
new file mode 100644
index 0000000..4bbce7a
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/softdevice/s112/doc/s112_nrf52_6.0.0_release-notes.pdf
Binary files differ
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/softdevice/s112/headers/ble.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/softdevice/s112/headers/ble.h
new file mode 100644
index 0000000..ad6b58f
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/softdevice/s112/headers/ble.h
@@ -0,0 +1,617 @@
+/*
+ * Copyright (c) 2012 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ */
+
+/**
+ @addtogroup BLE_COMMON BLE SoftDevice Common
+ @{
+ @defgroup ble_api Events, type definitions and API calls
+ @{
+
+ @brief Module independent events, type definitions and API calls for the BLE SoftDevice.
+
+ */
+
+#ifndef BLE_H__
+#define BLE_H__
+
+#include <stdint.h>
+#include "nrf_svc.h"
+#include "nrf_error.h"
+#include "ble_err.h"
+#include "ble_gap.h"
+#include "ble_gatt.h"
+#include "ble_gattc.h"
+#include "ble_gatts.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** @addtogroup BLE_COMMON_ENUMERATIONS Enumerations
+ * @{ */
+
+/**
+ * @brief Common API SVC numbers.
+ */
+enum BLE_COMMON_SVCS
+{
+ SD_BLE_ENABLE = BLE_SVC_BASE, /**< Enable and initialize the BLE stack */
+ SD_BLE_EVT_GET, /**< Get an event from the pending events queue. */
+ SD_BLE_UUID_VS_ADD, /**< Add a Vendor Specific UUID. */
+ SD_BLE_UUID_DECODE, /**< Decode UUID bytes. */
+ SD_BLE_UUID_ENCODE, /**< Encode UUID bytes. */
+ SD_BLE_VERSION_GET, /**< Get the local version information (company ID, Link Layer Version, Link Layer Subversion). */
+ SD_BLE_USER_MEM_REPLY, /**< User Memory Reply. */
+ SD_BLE_OPT_SET, /**< Set a BLE option. */
+ SD_BLE_OPT_GET, /**< Get a BLE option. */
+ SD_BLE_CFG_SET, /**< Add a configuration to the BLE stack. */
+};
+
+/**
+ * @brief BLE Module Independent Event IDs.
+ */
+enum BLE_COMMON_EVTS
+{
+ BLE_EVT_USER_MEM_REQUEST = BLE_EVT_BASE + 0, /**< User Memory request. @ref ble_evt_user_mem_request_t */
+ BLE_EVT_USER_MEM_RELEASE = BLE_EVT_BASE + 1, /**< User Memory release. @ref ble_evt_user_mem_release_t */
+};
+
+/**@brief BLE Connection Configuration IDs.
+ *
+ * IDs that uniquely identify a connection configuration.
+ */
+enum BLE_CONN_CFGS
+{
+ BLE_CONN_CFG_GAP = BLE_CONN_CFG_BASE + 0, /**< BLE GAP specific connection configuration. */
+ BLE_CONN_CFG_GATTC = BLE_CONN_CFG_BASE + 1, /**< BLE GATTC specific connection configuration. */
+ BLE_CONN_CFG_GATTS = BLE_CONN_CFG_BASE + 2, /**< BLE GATTS specific connection configuration. */
+ BLE_CONN_CFG_GATT = BLE_CONN_CFG_BASE + 3, /**< BLE GATT specific connection configuration. */
+};
+
+/**@brief BLE Common Configuration IDs.
+ *
+ * IDs that uniquely identify a common configuration.
+ */
+enum BLE_COMMON_CFGS
+{
+ BLE_COMMON_CFG_VS_UUID = BLE_CFG_BASE, /**< Vendor specific UUID configuration */
+};
+
+/**@brief Common Option IDs.
+ * IDs that uniquely identify a common option.
+ */
+enum BLE_COMMON_OPTS
+{
+ BLE_COMMON_OPT_PA_LNA = BLE_OPT_BASE + 0, /**< PA and LNA options */
+ BLE_COMMON_OPT_CONN_EVT_EXT = BLE_OPT_BASE + 1, /**< Extended connection events option */
+};
+
+/** @} */
+
+/** @addtogroup BLE_COMMON_DEFINES Defines
+ * @{ */
+
+/** @brief Required pointer alignment for BLE Events.
+*/
+#define BLE_EVT_PTR_ALIGNMENT 4
+
+/** @brief Leaves the maximum of the two arguments.
+*/
+#define BLE_MAX(a, b) ((a) < (b) ? (b) : (a))
+
+/** @brief Maximum possible length for BLE Events.
+ * @note The highest value used for @ref ble_gatt_conn_cfg_t::att_mtu in any connection configuration shall be used as a parameter.
+ * If that value has not been configured for any connections then @ref BLE_GATT_ATT_MTU_DEFAULT must be used instead.
+*/
+#define BLE_EVT_LEN_MAX(ATT_MTU) ( \
+ offsetof(ble_evt_t, evt.gattc_evt.params.prim_srvc_disc_rsp.services) + ((ATT_MTU) - 1) / 4 * sizeof(ble_gattc_service_t) \
+)
+
+/** @defgroup BLE_USER_MEM_TYPES User Memory Types
+ * @{ */
+#define BLE_USER_MEM_TYPE_INVALID 0x00 /**< Invalid User Memory Types. */
+#define BLE_USER_MEM_TYPE_GATTS_QUEUED_WRITES 0x01 /**< User Memory for GATTS queued writes. */
+/** @} */
+
+/** @defgroup BLE_UUID_VS_COUNTS Vendor Specific UUID counts
+ * @{
+ */
+#define BLE_UUID_VS_COUNT_DEFAULT 10 /**< Default VS UUID count. */
+#define BLE_UUID_VS_COUNT_MAX 254 /**< Maximum VS UUID count. */
+/** @} */
+
+/** @defgroup BLE_COMMON_CFG_DEFAULTS Configuration defaults.
+ * @{
+ */
+#define BLE_CONN_CFG_TAG_DEFAULT 0 /**< Default configuration tag, SoftDevice default connection configuration. */
+
+/** @} */
+
+/** @} */
+
+/** @addtogroup BLE_COMMON_STRUCTURES Structures
+ * @{ */
+
+/**@brief User Memory Block. */
+typedef struct
+{
+ uint8_t *p_mem; /**< Pointer to the start of the user memory block. */
+ uint16_t len; /**< Length in bytes of the user memory block. */
+} ble_user_mem_block_t;
+
+/**@brief Event structure for @ref BLE_EVT_USER_MEM_REQUEST. */
+typedef struct
+{
+ uint8_t type; /**< User memory type, see @ref BLE_USER_MEM_TYPES. */
+} ble_evt_user_mem_request_t;
+
+/**@brief Event structure for @ref BLE_EVT_USER_MEM_RELEASE. */
+typedef struct
+{
+ uint8_t type; /**< User memory type, see @ref BLE_USER_MEM_TYPES. */
+ ble_user_mem_block_t mem_block; /**< User memory block */
+} ble_evt_user_mem_release_t;
+
+/**@brief Event structure for events not associated with a specific function module. */
+typedef struct
+{
+ uint16_t conn_handle; /**< Connection Handle on which this event occurred. */
+ union
+ {
+ ble_evt_user_mem_request_t user_mem_request; /**< User Memory Request Event Parameters. */
+ ble_evt_user_mem_release_t user_mem_release; /**< User Memory Release Event Parameters. */
+ } params; /**< Event parameter union. */
+} ble_common_evt_t;
+
+/**@brief BLE Event header. */
+typedef struct
+{
+ uint16_t evt_id; /**< Value from a BLE_<module>_EVT series. */
+ uint16_t evt_len; /**< Length in octets including this header. */
+} ble_evt_hdr_t;
+
+/**@brief Common BLE Event type, wrapping the module specific event reports. */
+typedef struct
+{
+ ble_evt_hdr_t header; /**< Event header. */
+ union
+ {
+ ble_common_evt_t common_evt; /**< Common Event, evt_id in BLE_EVT_* series. */
+ ble_gap_evt_t gap_evt; /**< GAP originated event, evt_id in BLE_GAP_EVT_* series. */
+ ble_gattc_evt_t gattc_evt; /**< GATT client originated event, evt_id in BLE_GATTC_EVT* series. */
+ ble_gatts_evt_t gatts_evt; /**< GATT server originated event, evt_id in BLE_GATTS_EVT* series. */
+ } evt; /**< Event union. */
+} ble_evt_t;
+
+
+/**
+ * @brief Version Information.
+ */
+typedef struct
+{
+ uint8_t version_number; /**< Link Layer Version number. See https://www.bluetooth.org/en-us/specification/assigned-numbers/link-layer for assigned values. */
+ uint16_t company_id; /**< Company ID, Nordic Semiconductor's company ID is 89 (0x0059) (https://www.bluetooth.org/apps/content/Default.aspx?doc_id=49708). */
+ uint16_t subversion_number; /**< Link Layer Sub Version number, corresponds to the SoftDevice Config ID or Firmware ID (FWID). */
+} ble_version_t;
+
+/**
+ * @brief Configuration parameters for the PA and LNA.
+ */
+typedef struct
+{
+ uint8_t enable :1; /**< Enable toggling for this amplifier */
+ uint8_t active_high :1; /**< Set the pin to be active high */
+ uint8_t gpio_pin :6; /**< The GPIO pin to toggle for this amplifier */
+} ble_pa_lna_cfg_t;
+
+/**
+ * @brief PA & LNA GPIO toggle configuration
+ *
+ * This option configures the SoftDevice to toggle pins when the radio is active for use with a power amplifier and/or
+ * a low noise amplifier.
+ *
+ * Toggling the pins is achieved by using two PPI channels and a GPIOTE channel. The hardware channel IDs are provided
+ * by the application and should be regarded as reserved as long as any PA/LNA toggling is enabled.
+ *
+ * @note @ref sd_ble_opt_get is not supported for this option.
+ * @note Setting this option while the radio is in use (i.e. any of the roles are active) may have undefined consequences
+ * and must be avoided by the application.
+ */
+typedef struct
+{
+ ble_pa_lna_cfg_t pa_cfg; /**< Power Amplifier configuration */
+ ble_pa_lna_cfg_t lna_cfg; /**< Low Noise Amplifier configuration */
+
+ uint8_t ppi_ch_id_set; /**< PPI channel used for radio pin setting */
+ uint8_t ppi_ch_id_clr; /**< PPI channel used for radio pin clearing */
+ uint8_t gpiote_ch_id; /**< GPIOTE channel used for radio pin toggling */
+} ble_common_opt_pa_lna_t;
+
+/**
+ * @brief Configuration of extended BLE connection events.
+ *
+ * When enabled the SoftDevice will dynamically extend the connection event when possible.
+ *
+ * The connection event length is controlled by the connection configuration as set by @ref ble_gap_conn_cfg_t::event_length.
+ * The connection event can be extended if there is time to send another packet pair before the start of the next connection interval,
+ * and if there are no conflicts with other BLE roles requesting radio time.
+ *
+ * @note @ref sd_ble_opt_get is not supported for this option.
+ */
+typedef struct
+{
+ uint8_t enable : 1; /**< Enable extended BLE connection events, disabled by default. */
+} ble_common_opt_conn_evt_ext_t;
+
+/**@brief Option structure for common options. */
+typedef union
+{
+ ble_common_opt_pa_lna_t pa_lna; /**< Parameters for controlling PA and LNA pin toggling. */
+ ble_common_opt_conn_evt_ext_t conn_evt_ext; /**< Parameters for enabling extended connection events. */
+} ble_common_opt_t;
+
+/**@brief Common BLE Option type, wrapping the module specific options. */
+typedef union
+{
+ ble_common_opt_t common_opt; /**< COMMON options, opt_id in @ref BLE_COMMON_OPTS series. */
+ ble_gap_opt_t gap_opt; /**< GAP option, opt_id in @ref BLE_GAP_OPTS series. */
+} ble_opt_t;
+
+/**@brief BLE connection configuration type, wrapping the module specific configurations, set with
+ * @ref sd_ble_cfg_set.
+ *
+ * @note Connection configurations don't have to be set.
+ * In the case that no configurations has been set, or fewer connection configurations has been set than enabled connections,
+ * the default connection configuration will be automatically added for the remaining connections.
+ * When creating connections with the default configuration, @ref BLE_CONN_CFG_TAG_DEFAULT should be used in
+ * place of @ref ble_conn_cfg_t::conn_cfg_tag.
+ *
+ * @sa sd_ble_gap_adv_start()
+ *
+ * @mscs
+ * @mmsc{@ref BLE_CONN_CFG}
+ * @endmscs
+
+ */
+typedef struct
+{
+ uint8_t conn_cfg_tag; /**< The application chosen tag it can use with the
+ @ref sd_ble_gap_adv_start() call
+ to select this configuration when creating a connection.
+ Must be different for all connection configurations added and not @ref BLE_CONN_CFG_TAG_DEFAULT. */
+ union {
+ ble_gap_conn_cfg_t gap_conn_cfg; /**< GAP connection configuration, cfg_id is @ref BLE_CONN_CFG_GAP. */
+ ble_gattc_conn_cfg_t gattc_conn_cfg; /**< GATTC connection configuration, cfg_id is @ref BLE_CONN_CFG_GATTC. */
+ ble_gatts_conn_cfg_t gatts_conn_cfg; /**< GATTS connection configuration, cfg_id is @ref BLE_CONN_CFG_GATTS. */
+ ble_gatt_conn_cfg_t gatt_conn_cfg; /**< GATT connection configuration, cfg_id is @ref BLE_CONN_CFG_GATT. */
+ } params; /**< Connection configuration union. */
+} ble_conn_cfg_t;
+
+/**
+ * @brief Configuration of Vendor Specific UUIDs, set with @ref sd_ble_cfg_set.
+ *
+ * @retval ::NRF_ERROR_INVALID_PARAM Too many UUIDs configured.
+ */
+typedef struct
+{
+ uint8_t vs_uuid_count; /**< Number of 128-bit Vendor Specific UUID bases to allocate memory for.
+ Default value is @ref BLE_UUID_VS_COUNT_DEFAULT. Maximum value is
+ @ref BLE_UUID_VS_COUNT_MAX. */
+} ble_common_cfg_vs_uuid_t;
+
+/**@brief Common BLE Configuration type, wrapping the common configurations. */
+typedef union
+{
+ ble_common_cfg_vs_uuid_t vs_uuid_cfg; /**< Vendor specific UUID configuration, cfg_id is @ref BLE_COMMON_CFG_VS_UUID. */
+} ble_common_cfg_t;
+
+/**@brief BLE Configuration type, wrapping the module specific configurations. */
+typedef union
+{
+ ble_conn_cfg_t conn_cfg; /**< Connection specific configurations, cfg_id in @ref BLE_CONN_CFGS series. */
+ ble_common_cfg_t common_cfg; /**< Global common configurations, cfg_id in @ref BLE_COMMON_CFGS series. */
+ ble_gap_cfg_t gap_cfg; /**< Global GAP configurations, cfg_id in @ref BLE_GAP_CFGS series. */
+ ble_gatts_cfg_t gatts_cfg; /**< Global GATTS configuration, cfg_id in @ref BLE_GATTS_CFGS series. */
+} ble_cfg_t;
+
+/** @} */
+
+/** @addtogroup BLE_COMMON_FUNCTIONS Functions
+ * @{ */
+
+/**@brief Enable the BLE stack
+ *
+ * @param[in, out] p_app_ram_base Pointer to a variable containing the start address of the
+ * application RAM region (APP_RAM_BASE). On return, this will
+ * contain the minimum start address of the application RAM region
+ * required by the SoftDevice for this configuration.
+ *
+ * @note The memory requirement for a specific configuration will not increase between SoftDevices
+ * with the same major version number.
+ *
+ * @note The value of *p_app_ram_base when the app has done no custom configuration of the
+ * SoftDevice, i.e. the app has not called @ref sd_ble_cfg_set before @ref sd_ble_enable, can
+ * be found in the release notes.
+ *
+ * @note At runtime the IC's RAM is split into 2 regions: The SoftDevice RAM region is located
+ * between 0x20000000 and APP_RAM_BASE-1 and the application's RAM region is located between
+ * APP_RAM_BASE and the start of the call stack.
+ *
+ * @details This call initializes the BLE stack, no BLE related function other than @ref
+ * sd_ble_cfg_set can be called before this one.
+ *
+ * @mscs
+ * @mmsc{@ref BLE_COMMON_ENABLE}
+ * @endmscs
+ *
+ * @retval ::NRF_SUCCESS The BLE stack has been initialized successfully.
+ * @retval ::NRF_ERROR_INVALID_STATE The BLE stack had already been initialized and cannot be reinitialized.
+ * @retval ::NRF_ERROR_INVALID_ADDR Invalid or not sufficiently aligned pointer supplied.
+ * @retval ::NRF_ERROR_NO_MEM The amount of memory assigned to the SoftDevice by *p_app_ram_base is not
+ * large enough to fit this configuration's memory requirement. Check *p_app_ram_base
+ * and set the start address of the application RAM region accordingly.
+ */
+SVCALL(SD_BLE_ENABLE, uint32_t, sd_ble_enable(uint32_t * p_app_ram_base));
+
+/**@brief Add configurations for the BLE stack
+ *
+ * @param[in] cfg_id Config ID, see @ref BLE_CONN_CFGS, @ref BLE_COMMON_CFGS, @ref
+ * BLE_GAP_CFGS or @ref BLE_GATTS_CFGS.
+ * @param[in] p_cfg Pointer to a ble_cfg_t structure containing the configuration value.
+ * @param[in] app_ram_base The start address of the application RAM region (APP_RAM_BASE).
+ * See @ref sd_ble_enable for details about APP_RAM_BASE.
+ *
+ * @note The memory requirement for a specific configuration will not increase between SoftDevices
+ * with the same major version number.
+ *
+ * @note If a configuration is set more than once, the last one set is the one that takes effect on
+ * @ref sd_ble_enable.
+ *
+ * @note Any part of the BLE stack that is NOT configured with @ref sd_ble_cfg_set will have default
+ * configuration.
+ *
+ * @note @ref sd_ble_cfg_set may be called at any time when the SoftDevice is enabled (see @ref
+ * sd_softdevice_enable) while the BLE part of the SoftDevice is not enabled (see @ref
+ * sd_ble_enable).
+ *
+ * @note Error codes for the configurations are described in the configuration structs.
+ *
+ * @mscs
+ * @mmsc{@ref BLE_COMMON_ENABLE}
+ * @endmscs
+ *
+ * @retval ::NRF_SUCCESS The configuration has been added successfully.
+ * @retval ::NRF_ERROR_INVALID_STATE The BLE stack had already been initialized.
+ * @retval ::NRF_ERROR_INVALID_ADDR Invalid or not sufficiently aligned pointer supplied.
+ * @retval ::NRF_ERROR_INVALID_PARAM Invalid cfg_id supplied.
+ * @retval ::NRF_ERROR_NO_MEM The amount of memory assigned to the SoftDevice by app_ram_base is not
+ * large enough to fit this configuration's memory requirement.
+ */
+SVCALL(SD_BLE_CFG_SET, uint32_t, sd_ble_cfg_set(uint32_t cfg_id, ble_cfg_t const * p_cfg, uint32_t app_ram_base));
+
+/**@brief Get an event from the pending events queue.
+ *
+ * @param[out] p_dest Pointer to buffer to be filled in with an event, or NULL to retrieve the event length.
+ * This buffer <b>must be aligned to the extend defined by @ref BLE_EVT_PTR_ALIGNMENT</b>.
+ * The buffer should be interpreted as a @ref ble_evt_t struct.
+ * @param[in, out] p_len Pointer the length of the buffer, on return it is filled with the event length.
+ *
+ * @details This call allows the application to pull a BLE event from the BLE stack. The application is signaled that
+ * an event is available from the BLE stack by the triggering of the SD_EVT_IRQn interrupt.
+ * The application is free to choose whether to call this function from thread mode (main context) or directly from the
+ * Interrupt Service Routine that maps to SD_EVT_IRQn. In any case however, and because the BLE stack runs at a higher
+ * priority than the application, this function should be called in a loop (until @ref NRF_ERROR_NOT_FOUND is returned)
+ * every time SD_EVT_IRQn is raised to ensure that all available events are pulled from the BLE stack. Failure to do so
+ * could potentially leave events in the internal queue without the application being aware of this fact.
+ *
+ * Sizing the p_dest buffer is equally important, since the application needs to provide all the memory necessary for the event to
+ * be copied into application memory. If the buffer provided is not large enough to fit the entire contents of the event,
+ * @ref NRF_ERROR_DATA_SIZE will be returned and the application can then call again with a larger buffer size.
+ * The maximum possible event length is defined by @ref BLE_EVT_LEN_MAX. The application may also "peek" the event length
+ * by providing p_dest as a NULL pointer and inspecting the value of *p_len upon return:
+ *
+ * \code
+ * uint16_t len;
+ * errcode = sd_ble_evt_get(NULL, &len);
+ * \endcode
+ *
+ * @mscs
+ * @mmsc{@ref BLE_COMMON_IRQ_EVT_MSC}
+ * @mmsc{@ref BLE_COMMON_THREAD_EVT_MSC}
+ * @endmscs
+ *
+ * @retval ::NRF_SUCCESS Event pulled and stored into the supplied buffer.
+ * @retval ::NRF_ERROR_INVALID_ADDR Invalid or not sufficiently aligned pointer supplied.
+ * @retval ::NRF_ERROR_NOT_FOUND No events ready to be pulled.
+ * @retval ::NRF_ERROR_DATA_SIZE Event ready but could not fit into the supplied buffer.
+ */
+SVCALL(SD_BLE_EVT_GET, uint32_t, sd_ble_evt_get(uint8_t *p_dest, uint16_t *p_len));
+
+
+/**@brief Add a Vendor Specific base UUID.
+ *
+ * @details This call enables the application to add a vendor specific base UUID to the BLE stack's table, for later
+ * use with all other modules and APIs. This then allows the application to use the shorter, 24-bit @ref ble_uuid_t
+ * format when dealing with both 16-bit and 128-bit UUIDs without having to check for lengths and having split code
+ * paths. This is accomplished by extending the grouping mechanism that the Bluetooth SIG standard base UUID uses
+ * for all other 128-bit UUIDs. The type field in the @ref ble_uuid_t structure is an index (relative to
+ * @ref BLE_UUID_TYPE_VENDOR_BEGIN) to the table populated by multiple calls to this function, and the UUID field
+ * in the same structure contains the 2 bytes at indexes 12 and 13. The number of possible 128-bit UUIDs available to
+ * the application is therefore the number of Vendor Specific UUIDs added with the help of this function times 65536,
+ * although restricted to modifying bytes 12 and 13 for each of the entries in the supplied array.
+ *
+ * @note Bytes 12 and 13 of the provided UUID will not be used internally, since those are always replaced by
+ * the 16-bit uuid field in @ref ble_uuid_t.
+ *
+ * @note If a UUID is already present in the BLE stack's internal table, the corresponding index will be returned in
+ * p_uuid_type along with an @ref NRF_SUCCESS error code.
+ *
+ * @param[in] p_vs_uuid Pointer to a 16-octet (128-bit) little endian Vendor Specific UUID disregarding
+ * bytes 12 and 13.
+ * @param[out] p_uuid_type Pointer to a uint8_t where the type field in @ref ble_uuid_t corresponding to this UUID will be stored.
+ *
+ * @retval ::NRF_SUCCESS Successfully added the Vendor Specific UUID.
+ * @retval ::NRF_ERROR_INVALID_ADDR If p_vs_uuid or p_uuid_type is NULL or invalid.
+ * @retval ::NRF_ERROR_NO_MEM If there are no more free slots for VS UUIDs.
+ */
+SVCALL(SD_BLE_UUID_VS_ADD, uint32_t, sd_ble_uuid_vs_add(ble_uuid128_t const *p_vs_uuid, uint8_t *p_uuid_type));
+
+
+/** @brief Decode little endian raw UUID bytes (16-bit or 128-bit) into a 24 bit @ref ble_uuid_t structure.
+ *
+ * @details The raw UUID bytes excluding bytes 12 and 13 (i.e. bytes 0-11 and 14-15) of p_uuid_le are compared
+ * to the corresponding ones in each entry of the table of vendor specific UUIDs populated with @ref sd_ble_uuid_vs_add
+ * to look for a match. If there is such a match, bytes 12 and 13 are returned as p_uuid->uuid and the index
+ * relative to @ref BLE_UUID_TYPE_VENDOR_BEGIN as p_uuid->type.
+ *
+ * @note If the UUID length supplied is 2, then the type set by this call will always be @ref BLE_UUID_TYPE_BLE.
+ *
+ * @param[in] uuid_le_len Length in bytes of the buffer pointed to by p_uuid_le (must be 2 or 16 bytes).
+ * @param[in] p_uuid_le Pointer pointing to little endian raw UUID bytes.
+ * @param[out] p_uuid Pointer to a @ref ble_uuid_t structure to be filled in.
+ *
+ * @retval ::NRF_SUCCESS Successfully decoded into the @ref ble_uuid_t structure.
+ * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied.
+ * @retval ::NRF_ERROR_INVALID_LENGTH Invalid UUID length.
+ * @retval ::NRF_ERROR_NOT_FOUND For a 128-bit UUID, no match in the populated table of UUIDs.
+ */
+SVCALL(SD_BLE_UUID_DECODE, uint32_t, sd_ble_uuid_decode(uint8_t uuid_le_len, uint8_t const *p_uuid_le, ble_uuid_t *p_uuid));
+
+
+/** @brief Encode a @ref ble_uuid_t structure into little endian raw UUID bytes (16-bit or 128-bit).
+ *
+ * @note The pointer to the destination buffer p_uuid_le may be NULL, in which case only the validity and size of p_uuid is computed.
+ *
+ * @param[in] p_uuid Pointer to a @ref ble_uuid_t structure that will be encoded into bytes.
+ * @param[out] p_uuid_le_len Pointer to a uint8_t that will be filled with the encoded length (2 or 16 bytes).
+ * @param[out] p_uuid_le Pointer to a buffer where the little endian raw UUID bytes (2 or 16) will be stored.
+ *
+ * @retval ::NRF_SUCCESS Successfully encoded into the buffer.
+ * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied.
+ * @retval ::NRF_ERROR_INVALID_PARAM Invalid UUID type.
+ */
+SVCALL(SD_BLE_UUID_ENCODE, uint32_t, sd_ble_uuid_encode(ble_uuid_t const *p_uuid, uint8_t *p_uuid_le_len, uint8_t *p_uuid_le));
+
+
+/**@brief Get Version Information.
+ *
+ * @details This call allows the application to get the BLE stack version information.
+ *
+ * @param[out] p_version Pointer to a ble_version_t structure to be filled in.
+ *
+ * @retval ::NRF_SUCCESS Version information stored successfully.
+ * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied.
+ * @retval ::NRF_ERROR_BUSY The BLE stack is busy (typically doing a locally-initiated disconnection procedure).
+ */
+SVCALL(SD_BLE_VERSION_GET, uint32_t, sd_ble_version_get(ble_version_t *p_version));
+
+
+/**@brief Provide a user memory block.
+ *
+ * @note This call can only be used as a response to a @ref BLE_EVT_USER_MEM_REQUEST event issued to the application.
+ *
+ * @param[in] conn_handle Connection handle.
+ * @param[in] p_block Pointer to a user memory block structure or NULL if memory is managed by the application.
+ *
+ * @mscs
+ * @mmsc{@ref BLE_GATTS_QUEUED_WRITE_PEER_CANCEL_MSC}
+ * @mmsc{@ref BLE_GATTS_QUEUED_WRITE_NOBUF_AUTH_MSC}
+ * @mmsc{@ref BLE_GATTS_QUEUED_WRITE_NOBUF_NOAUTH_MSC}
+ * @mmsc{@ref BLE_GATTS_QUEUED_WRITE_BUF_AUTH_MSC}
+ * @mmsc{@ref BLE_GATTS_QUEUED_WRITE_BUF_NOAUTH_MSC}
+ * @mmsc{@ref BLE_GATTS_QUEUED_WRITE_QUEUE_FULL_MSC}
+ * @endmscs
+ *
+ * @retval ::NRF_SUCCESS Successfully queued a response to the peer.
+ * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied.
+ * @retval ::NRF_ERROR_BUSY The stack is busy, process pending events and retry.
+ * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid Connection Handle.
+ * @retval ::NRF_ERROR_INVALID_LENGTH Invalid user memory block length supplied.
+ * @retval ::NRF_ERROR_INVALID_STATE Invalid Connection state or no user memory request pending.
+ */
+SVCALL(SD_BLE_USER_MEM_REPLY, uint32_t, sd_ble_user_mem_reply(uint16_t conn_handle, ble_user_mem_block_t const *p_block));
+
+/**@brief Set a BLE option.
+ *
+ * @details This call allows the application to set the value of an option.
+ *
+ * @mscs
+ * @mmsc{@ref BLE_GAP_PERIPH_BONDING_STATIC_PK_MSC}
+ * @endmscs
+ *
+ * @param[in] opt_id Option ID, see @ref BLE_COMMON_OPTS and @ref BLE_GAP_OPTS.
+ * @param[in] p_opt Pointer to a ble_opt_t structure containing the option value.
+ *
+ * @retval ::NRF_SUCCESS Option set successfully.
+ * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied.
+ * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid Connection Handle.
+ * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied, check parameter limits and constraints.
+ * @retval ::NRF_ERROR_INVALID_STATE Unable to set the parameter at this time.
+ * @retval ::NRF_ERROR_BUSY The BLE stack is busy or the previous procedure has not completed.
+ */
+SVCALL(SD_BLE_OPT_SET, uint32_t, sd_ble_opt_set(uint32_t opt_id, ble_opt_t const *p_opt));
+
+
+/**@brief Get a BLE option.
+ *
+ * @details This call allows the application to retrieve the value of an option.
+ *
+ * @param[in] opt_id Option ID, see @ref BLE_COMMON_OPTS and @ref BLE_GAP_OPTS.
+ * @param[out] p_opt Pointer to a ble_opt_t structure to be filled in.
+ *
+ * @retval ::NRF_SUCCESS Option retrieved successfully.
+ * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied.
+ * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid Connection Handle.
+ * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied, check parameter limits and constraints.
+ * @retval ::NRF_ERROR_INVALID_STATE Unable to retrieve the parameter at this time.
+ * @retval ::NRF_ERROR_BUSY The BLE stack is busy or the previous procedure has not completed.
+ * @retval ::NRF_ERROR_NOT_SUPPORTED This option is not supported.
+ *
+ */
+SVCALL(SD_BLE_OPT_GET, uint32_t, sd_ble_opt_get(uint32_t opt_id, ble_opt_t *p_opt));
+
+/** @} */
+#ifdef __cplusplus
+}
+#endif
+#endif /* BLE_H__ */
+
+/**
+ @}
+ @}
+*/
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/softdevice/s112/headers/ble_err.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/softdevice/s112/headers/ble_err.h
new file mode 100644
index 0000000..1b4820d
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/softdevice/s112/headers/ble_err.h
@@ -0,0 +1,93 @@
+/*
+ * Copyright (c) 2012 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ */
+
+/**
+ @addtogroup BLE_COMMON
+ @{
+ @addtogroup nrf_error
+ @{
+ @ingroup BLE_COMMON
+ @}
+
+ @defgroup ble_err General error codes
+ @{
+
+ @brief General error code definitions for the BLE API.
+
+ @ingroup BLE_COMMON
+*/
+#ifndef NRF_BLE_ERR_H__
+#define NRF_BLE_ERR_H__
+
+#include "nrf_error.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* @defgroup BLE_ERRORS Error Codes
+ * @{ */
+#define BLE_ERROR_NOT_ENABLED (NRF_ERROR_STK_BASE_NUM+0x001) /**< @ref sd_ble_enable has not been called. */
+#define BLE_ERROR_INVALID_CONN_HANDLE (NRF_ERROR_STK_BASE_NUM+0x002) /**< Invalid connection handle. */
+#define BLE_ERROR_INVALID_ATTR_HANDLE (NRF_ERROR_STK_BASE_NUM+0x003) /**< Invalid attribute handle. */
+#define BLE_ERROR_INVALID_ADV_HANDLE (NRF_ERROR_STK_BASE_NUM+0x004) /**< Invalid advertising handle. */
+#define BLE_ERROR_INVALID_ROLE (NRF_ERROR_STK_BASE_NUM+0x005) /**< Invalid role. */
+#define BLE_ERROR_BLOCKED_BY_OTHER_LINKS (NRF_ERROR_STK_BASE_NUM+0x006) /**< The attempt to change link settings failed due to the scheduling of other links. */
+/** @} */
+
+
+/** @defgroup BLE_ERROR_SUBRANGES Module specific error code subranges
+ * @brief Assignment of subranges for module specific error codes.
+ * @note For specific error codes, see ble_<module>.h or ble_error_<module>.h.
+ * @{ */
+#define NRF_L2CAP_ERR_BASE (NRF_ERROR_STK_BASE_NUM+0x100) /**< L2CAP specific errors. */
+#define NRF_GAP_ERR_BASE (NRF_ERROR_STK_BASE_NUM+0x200) /**< GAP specific errors. */
+#define NRF_GATTC_ERR_BASE (NRF_ERROR_STK_BASE_NUM+0x300) /**< GATT client specific errors. */
+#define NRF_GATTS_ERR_BASE (NRF_ERROR_STK_BASE_NUM+0x400) /**< GATT server specific errors. */
+/** @} */
+
+#ifdef __cplusplus
+}
+#endif
+#endif
+
+
+/**
+ @}
+ @}
+*/
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/softdevice/s112/headers/ble_gap.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/softdevice/s112/headers/ble_gap.h
new file mode 100644
index 0000000..2bf80e2
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/softdevice/s112/headers/ble_gap.h
@@ -0,0 +1,2023 @@
+/*
+ * Copyright (c) 2011 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ */
+
+/**
+ @addtogroup BLE_GAP Generic Access Profile (GAP)
+ @{
+ @brief Definitions and prototypes for the GAP interface.
+ */
+
+#ifndef BLE_GAP_H__
+#define BLE_GAP_H__
+
+#include <stdint.h>
+#include "nrf_svc.h"
+#include "nrf_error.h"
+#include "ble_hci.h"
+#include "ble_ranges.h"
+#include "ble_types.h"
+#include "ble_err.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**@addtogroup BLE_GAP_ENUMERATIONS Enumerations
+ * @{ */
+
+/**@brief GAP API SVC numbers.
+ */
+enum BLE_GAP_SVCS
+{
+ SD_BLE_GAP_ADDR_SET = BLE_GAP_SVC_BASE, /**< Set own Bluetooth Address. */
+ SD_BLE_GAP_ADDR_GET = BLE_GAP_SVC_BASE + 1, /**< Get own Bluetooth Address. */
+ SD_BLE_GAP_WHITELIST_SET = BLE_GAP_SVC_BASE + 2, /**< Set active whitelist. */
+ SD_BLE_GAP_DEVICE_IDENTITIES_SET = BLE_GAP_SVC_BASE + 3, /**< Set device identity list. */
+ SD_BLE_GAP_PRIVACY_SET = BLE_GAP_SVC_BASE + 4, /**< Set Privacy settings*/
+ SD_BLE_GAP_PRIVACY_GET = BLE_GAP_SVC_BASE + 5, /**< Get Privacy settings*/
+ SD_BLE_GAP_ADV_SET_CONFIGURE = BLE_GAP_SVC_BASE + 6, /**< Configure an advertising set. */
+ SD_BLE_GAP_ADV_START = BLE_GAP_SVC_BASE + 7, /**< Start Advertising. */
+ SD_BLE_GAP_ADV_STOP = BLE_GAP_SVC_BASE + 8, /**< Stop Advertising. */
+ SD_BLE_GAP_CONN_PARAM_UPDATE = BLE_GAP_SVC_BASE + 9, /**< Connection Parameter Update. */
+ SD_BLE_GAP_DISCONNECT = BLE_GAP_SVC_BASE + 10, /**< Disconnect. */
+ SD_BLE_GAP_TX_POWER_SET = BLE_GAP_SVC_BASE + 11, /**< Set TX Power. */
+ SD_BLE_GAP_APPEARANCE_SET = BLE_GAP_SVC_BASE + 12, /**< Set Appearance. */
+ SD_BLE_GAP_APPEARANCE_GET = BLE_GAP_SVC_BASE + 13, /**< Get Appearance. */
+ SD_BLE_GAP_PPCP_SET = BLE_GAP_SVC_BASE + 14, /**< Set PPCP. */
+ SD_BLE_GAP_PPCP_GET = BLE_GAP_SVC_BASE + 15, /**< Get PPCP. */
+ SD_BLE_GAP_DEVICE_NAME_SET = BLE_GAP_SVC_BASE + 16, /**< Set Device Name. */
+ SD_BLE_GAP_DEVICE_NAME_GET = BLE_GAP_SVC_BASE + 17, /**< Get Device Name. */
+ SD_BLE_GAP_AUTHENTICATE = BLE_GAP_SVC_BASE + 18, /**< Initiate Pairing/Bonding. */
+ SD_BLE_GAP_SEC_PARAMS_REPLY = BLE_GAP_SVC_BASE + 19, /**< Reply with Security Parameters. */
+ SD_BLE_GAP_AUTH_KEY_REPLY = BLE_GAP_SVC_BASE + 20, /**< Reply with an authentication key. */
+ SD_BLE_GAP_LESC_DHKEY_REPLY = BLE_GAP_SVC_BASE + 21, /**< Reply with an LE Secure Connections DHKey. */
+ SD_BLE_GAP_KEYPRESS_NOTIFY = BLE_GAP_SVC_BASE + 22, /**< Notify of a keypress during an authentication procedure. */
+ SD_BLE_GAP_LESC_OOB_DATA_GET = BLE_GAP_SVC_BASE + 23, /**< Get the local LE Secure Connections OOB data. */
+ SD_BLE_GAP_LESC_OOB_DATA_SET = BLE_GAP_SVC_BASE + 24, /**< Set the remote LE Secure Connections OOB data. */
+ SD_BLE_GAP_SEC_INFO_REPLY = BLE_GAP_SVC_BASE + 26, /**< Reply with Security Information. */
+ SD_BLE_GAP_CONN_SEC_GET = BLE_GAP_SVC_BASE + 27, /**< Obtain connection security level. */
+ SD_BLE_GAP_RSSI_START = BLE_GAP_SVC_BASE + 28, /**< Start reporting of changes in RSSI. */
+ SD_BLE_GAP_RSSI_STOP = BLE_GAP_SVC_BASE + 29, /**< Stop reporting of changes in RSSI. */
+ SD_BLE_GAP_RSSI_GET = BLE_GAP_SVC_BASE + 34, /**< Get the last RSSI sample. */
+ SD_BLE_GAP_PHY_UPDATE = BLE_GAP_SVC_BASE + 35, /**< Initiate or respond to a PHY Update Procedure. */
+};
+
+/**@brief GAP Event IDs.
+ * IDs that uniquely identify an event coming from the stack to the application.
+ */
+enum BLE_GAP_EVTS
+{
+ BLE_GAP_EVT_CONNECTED = BLE_GAP_EVT_BASE,
+ BLE_GAP_EVT_DISCONNECTED = BLE_GAP_EVT_BASE + 1, /**< Disconnected from peer. \n See @ref ble_gap_evt_disconnected_t. */
+ BLE_GAP_EVT_CONN_PARAM_UPDATE = BLE_GAP_EVT_BASE + 2, /**< Connection Parameters updated. \n See @ref ble_gap_evt_conn_param_update_t. */
+ BLE_GAP_EVT_SEC_PARAMS_REQUEST = BLE_GAP_EVT_BASE + 3, /**< Request to provide security parameters. \n Reply with @ref sd_ble_gap_sec_params_reply. \n See @ref ble_gap_evt_sec_params_request_t. */
+ BLE_GAP_EVT_SEC_INFO_REQUEST = BLE_GAP_EVT_BASE + 4, /**< Request to provide security information. \n Reply with @ref sd_ble_gap_sec_info_reply. \n See @ref ble_gap_evt_sec_info_request_t. */
+ BLE_GAP_EVT_PASSKEY_DISPLAY = BLE_GAP_EVT_BASE + 5, /**< Request to display a passkey to the user. \n In LESC Numeric Comparison, reply with @ref sd_ble_gap_auth_key_reply. \n See @ref ble_gap_evt_passkey_display_t. */
+ BLE_GAP_EVT_KEY_PRESSED = BLE_GAP_EVT_BASE + 6, /**< Notification of a keypress on the remote device.\n See @ref ble_gap_evt_key_pressed_t */
+ BLE_GAP_EVT_AUTH_KEY_REQUEST = BLE_GAP_EVT_BASE + 7, /**< Request to provide an authentication key. \n Reply with @ref sd_ble_gap_auth_key_reply. \n See @ref ble_gap_evt_auth_key_request_t. */
+ BLE_GAP_EVT_LESC_DHKEY_REQUEST = BLE_GAP_EVT_BASE + 8, /**< Request to calculate an LE Secure Connections DHKey. \n Reply with @ref sd_ble_gap_lesc_dhkey_reply. \n See @ref ble_gap_evt_lesc_dhkey_request_t */
+ BLE_GAP_EVT_AUTH_STATUS = BLE_GAP_EVT_BASE + 9, /**< Authentication procedure completed with status. \n See @ref ble_gap_evt_auth_status_t. */
+ BLE_GAP_EVT_CONN_SEC_UPDATE = BLE_GAP_EVT_BASE + 10, /**< Connection security updated. \n See @ref ble_gap_evt_conn_sec_update_t. */
+ BLE_GAP_EVT_TIMEOUT = BLE_GAP_EVT_BASE + 11, /**< Timeout expired. \n See @ref ble_gap_evt_timeout_t. */
+ BLE_GAP_EVT_RSSI_CHANGED = BLE_GAP_EVT_BASE + 12, /**< RSSI report. \n See @ref ble_gap_evt_rssi_changed_t. */
+ BLE_GAP_EVT_SEC_REQUEST = BLE_GAP_EVT_BASE + 14, /**< Security Request. \n See @ref ble_gap_evt_sec_request_t. */
+ BLE_GAP_EVT_SCAN_REQ_REPORT = BLE_GAP_EVT_BASE + 16, /**< Scan request report. \n See @ref ble_gap_evt_scan_req_report_t. */
+ BLE_GAP_EVT_PHY_UPDATE_REQUEST = BLE_GAP_EVT_BASE + 17, /**< PHY Update Request. \n Reply with @ref sd_ble_gap_phy_update. \n See @ref ble_gap_evt_phy_update_request_t. */
+ BLE_GAP_EVT_PHY_UPDATE = BLE_GAP_EVT_BASE + 18, /**< PHY Update Procedure is complete. \n See @ref ble_gap_evt_phy_update_t. */
+ BLE_GAP_EVT_ADV_SET_TERMINATED = BLE_GAP_EVT_BASE + 22, /**< Advertising set terminated. \n See @ref ble_gap_evt_adv_set_terminated_t. */
+};
+
+/**@brief GAP Option IDs.
+ * IDs that uniquely identify a GAP option.
+ */
+enum BLE_GAP_OPTS
+{
+ BLE_GAP_OPT_CH_MAP = BLE_GAP_OPT_BASE, /**< Channel Map. @ref ble_gap_opt_ch_map_t */
+ BLE_GAP_OPT_LOCAL_CONN_LATENCY = BLE_GAP_OPT_BASE + 1, /**< Local connection latency. @ref ble_gap_opt_local_conn_latency_t */
+ BLE_GAP_OPT_PASSKEY = BLE_GAP_OPT_BASE + 2, /**< Set passkey. @ref ble_gap_opt_passkey_t */
+ BLE_GAP_OPT_AUTH_PAYLOAD_TIMEOUT = BLE_GAP_OPT_BASE + 4, /**< Set Authenticated payload timeout. @ref ble_gap_opt_auth_payload_timeout_t */
+ BLE_GAP_OPT_SLAVE_LATENCY_DISABLE = BLE_GAP_OPT_BASE + 5, /**< Disable slave latency. @ref ble_gap_opt_slave_latency_disable_t */
+};
+
+/**@brief GAP Configuration IDs.
+ *
+ * IDs that uniquely identify a GAP configuration.
+ */
+enum BLE_GAP_CFGS
+{
+ BLE_GAP_CFG_ROLE_COUNT = BLE_GAP_CFG_BASE, /**< Role count configuration. */
+ BLE_GAP_CFG_DEVICE_NAME = BLE_GAP_CFG_BASE + 1, /**< Device name configuration. */
+};
+
+/**@brief GAP TX Power roles.
+ */
+enum BLE_GAP_TX_POWER_ROLES
+{
+ BLE_GAP_TX_POWER_ROLE_ADV = 1, /**< Advertiser role. */
+ BLE_GAP_TX_POWER_ROLE_CONN = 3, /**< Connection role. */
+};
+
+/** @} */
+
+/**@addtogroup BLE_GAP_DEFINES Defines
+ * @{ */
+
+/**@defgroup BLE_ERRORS_GAP SVC return values specific to GAP
+ * @{ */
+#define BLE_ERROR_GAP_UUID_LIST_MISMATCH (NRF_GAP_ERR_BASE + 0x000) /**< UUID list does not contain an integral number of UUIDs. */
+#define BLE_ERROR_GAP_DISCOVERABLE_WITH_WHITELIST (NRF_GAP_ERR_BASE + 0x001) /**< Use of Whitelist not permitted with discoverable advertising. */
+#define BLE_ERROR_GAP_INVALID_BLE_ADDR (NRF_GAP_ERR_BASE + 0x002) /**< The upper two bits of the address do not correspond to the specified address type. */
+#define BLE_ERROR_GAP_WHITELIST_IN_USE (NRF_GAP_ERR_BASE + 0x003) /**< Attempt to modify the whitelist while already in use by another operation. */
+#define BLE_ERROR_GAP_DEVICE_IDENTITIES_IN_USE (NRF_GAP_ERR_BASE + 0x004) /**< Attempt to modify the device identity list while already in use by another operation. */
+#define BLE_ERROR_GAP_DEVICE_IDENTITIES_DUPLICATE (NRF_GAP_ERR_BASE + 0x005) /**< The device identity list contains entries with duplicate identity addresses. */
+/**@} */
+
+
+/**@defgroup BLE_GAP_ROLES GAP Roles
+ * @{ */
+#define BLE_GAP_ROLE_INVALID 0x0 /**< Invalid Role. */
+#define BLE_GAP_ROLE_PERIPH 0x1 /**< Peripheral Role. */
+/**@} */
+
+
+/**@defgroup BLE_GAP_TIMEOUT_SOURCES GAP Timeout sources
+ * @{ */
+#define BLE_GAP_TIMEOUT_SRC_CONN 0x02 /**< Connection timeout. */
+#define BLE_GAP_TIMEOUT_SRC_AUTH_PAYLOAD 0x03 /**< Authenticated payload timeout. */
+/**@} */
+
+
+/**@defgroup BLE_GAP_ADDR_TYPES GAP Address types
+ * @{ */
+#define BLE_GAP_ADDR_TYPE_PUBLIC 0x00 /**< Public (identity) address.*/
+#define BLE_GAP_ADDR_TYPE_RANDOM_STATIC 0x01 /**< Random static (identity) address. */
+#define BLE_GAP_ADDR_TYPE_RANDOM_PRIVATE_RESOLVABLE 0x02 /**< Random private resolvable address. */
+#define BLE_GAP_ADDR_TYPE_RANDOM_PRIVATE_NON_RESOLVABLE 0x03 /**< Random private non-resolvable address. */
+/**@} */
+
+
+/**@brief The default interval in seconds at which a private address is refreshed. */
+#define BLE_GAP_DEFAULT_PRIVATE_ADDR_CYCLE_INTERVAL_S (900) /* 15 minutes. */
+/**@brief The maximum interval in seconds at which a private address can be refreshed. */
+#define BLE_GAP_MAX_PRIVATE_ADDR_CYCLE_INTERVAL_S (41400) /* 11 hours 30 minutes. */
+
+
+/** @brief BLE address length. */
+#define BLE_GAP_ADDR_LEN (6)
+
+/**@defgroup BLE_GAP_PRIVACY_MODES Privacy modes
+ * @{ */
+#define BLE_GAP_PRIVACY_MODE_OFF 0x00 /**< Device will send and accept its identity address for its own address. */
+#define BLE_GAP_PRIVACY_MODE_DEVICE_PRIVACY 0x01 /**< Device will send and accept only private addresses for its own address. */
+#define BLE_GAP_PRIVACY_MODE_NETWORK_PRIVACY 0x02 /**< Device will send and accept only private addresses for its own address,
+ and will not accept a peer using identity address as sender address when
+ the peer IRK is exchanged, non-zero and added to the identity list. */
+/**@} */
+
+/** @brief Invalid power level. */
+#define BLE_GAP_POWER_LEVEL_INVALID 127
+
+/** @brief Advertising set handle not set. */
+#define BLE_GAP_ADV_SET_HANDLE_NOT_SET (0xFF)
+
+/** @brief The default number of advertising sets. */
+#define BLE_GAP_ADV_SET_COUNT_DEFAULT (1)
+
+/** @brief The maximum number of advertising sets supported by this SoftDevice. */
+#define BLE_GAP_ADV_SET_COUNT_MAX (1)
+
+/**@defgroup BLE_GAP_ADV_SET_DATA_SIZES Advertising data sizes.
+ * @{ */
+#define BLE_GAP_ADV_SET_DATA_SIZE_MAX (31) /**< Maximum data length for an advertising set. */
+/**@}. */
+
+/** @brief Set ID not available in advertising report. */
+#define BLE_GAP_ADV_REPORT_SET_ID_NOT_AVAILABLE 0xFF
+
+/**@defgroup BLE_GAP_EVT_ADV_SET_TERMINATED_REASON GAP Advertising Set Terminated reasons
+ * @{ */
+#define BLE_GAP_EVT_ADV_SET_TERMINATED_REASON_TIMEOUT 0x01 /**< Timeout value reached. */
+#define BLE_GAP_EVT_ADV_SET_TERMINATED_REASON_LIMIT_REACHED 0x02 /**< @ref ble_gap_adv_params_t::max_adv_evts was reached. */
+/**@} */
+
+/**@defgroup BLE_GAP_AD_TYPE_DEFINITIONS GAP Advertising and Scan Response Data format
+ * @note Found at https://www.bluetooth.org/Technical/AssignedNumbers/generic_access_profile.htm
+ * @{ */
+#define BLE_GAP_AD_TYPE_FLAGS 0x01 /**< Flags for discoverability. */
+#define BLE_GAP_AD_TYPE_16BIT_SERVICE_UUID_MORE_AVAILABLE 0x02 /**< Partial list of 16 bit service UUIDs. */
+#define BLE_GAP_AD_TYPE_16BIT_SERVICE_UUID_COMPLETE 0x03 /**< Complete list of 16 bit service UUIDs. */
+#define BLE_GAP_AD_TYPE_32BIT_SERVICE_UUID_MORE_AVAILABLE 0x04 /**< Partial list of 32 bit service UUIDs. */
+#define BLE_GAP_AD_TYPE_32BIT_SERVICE_UUID_COMPLETE 0x05 /**< Complete list of 32 bit service UUIDs. */
+#define BLE_GAP_AD_TYPE_128BIT_SERVICE_UUID_MORE_AVAILABLE 0x06 /**< Partial list of 128 bit service UUIDs. */
+#define BLE_GAP_AD_TYPE_128BIT_SERVICE_UUID_COMPLETE 0x07 /**< Complete list of 128 bit service UUIDs. */
+#define BLE_GAP_AD_TYPE_SHORT_LOCAL_NAME 0x08 /**< Short local device name. */
+#define BLE_GAP_AD_TYPE_COMPLETE_LOCAL_NAME 0x09 /**< Complete local device name. */
+#define BLE_GAP_AD_TYPE_TX_POWER_LEVEL 0x0A /**< Transmit power level. */
+#define BLE_GAP_AD_TYPE_CLASS_OF_DEVICE 0x0D /**< Class of device. */
+#define BLE_GAP_AD_TYPE_SIMPLE_PAIRING_HASH_C 0x0E /**< Simple Pairing Hash C. */
+#define BLE_GAP_AD_TYPE_SIMPLE_PAIRING_RANDOMIZER_R 0x0F /**< Simple Pairing Randomizer R. */
+#define BLE_GAP_AD_TYPE_SECURITY_MANAGER_TK_VALUE 0x10 /**< Security Manager TK Value. */
+#define BLE_GAP_AD_TYPE_SECURITY_MANAGER_OOB_FLAGS 0x11 /**< Security Manager Out Of Band Flags. */
+#define BLE_GAP_AD_TYPE_SLAVE_CONNECTION_INTERVAL_RANGE 0x12 /**< Slave Connection Interval Range. */
+#define BLE_GAP_AD_TYPE_SOLICITED_SERVICE_UUIDS_16BIT 0x14 /**< List of 16-bit Service Solicitation UUIDs. */
+#define BLE_GAP_AD_TYPE_SOLICITED_SERVICE_UUIDS_128BIT 0x15 /**< List of 128-bit Service Solicitation UUIDs. */
+#define BLE_GAP_AD_TYPE_SERVICE_DATA 0x16 /**< Service Data - 16-bit UUID. */
+#define BLE_GAP_AD_TYPE_PUBLIC_TARGET_ADDRESS 0x17 /**< Public Target Address. */
+#define BLE_GAP_AD_TYPE_RANDOM_TARGET_ADDRESS 0x18 /**< Random Target Address. */
+#define BLE_GAP_AD_TYPE_APPEARANCE 0x19 /**< Appearance. */
+#define BLE_GAP_AD_TYPE_ADVERTISING_INTERVAL 0x1A /**< Advertising Interval. */
+#define BLE_GAP_AD_TYPE_LE_BLUETOOTH_DEVICE_ADDRESS 0x1B /**< LE Bluetooth Device Address. */
+#define BLE_GAP_AD_TYPE_LE_ROLE 0x1C /**< LE Role. */
+#define BLE_GAP_AD_TYPE_SIMPLE_PAIRING_HASH_C256 0x1D /**< Simple Pairing Hash C-256. */
+#define BLE_GAP_AD_TYPE_SIMPLE_PAIRING_RANDOMIZER_R256 0x1E /**< Simple Pairing Randomizer R-256. */
+#define BLE_GAP_AD_TYPE_SERVICE_DATA_32BIT_UUID 0x20 /**< Service Data - 32-bit UUID. */
+#define BLE_GAP_AD_TYPE_SERVICE_DATA_128BIT_UUID 0x21 /**< Service Data - 128-bit UUID. */
+#define BLE_GAP_AD_TYPE_LESC_CONFIRMATION_VALUE 0x22 /**< LE Secure Connections Confirmation Value */
+#define BLE_GAP_AD_TYPE_LESC_RANDOM_VALUE 0x23 /**< LE Secure Connections Random Value */
+#define BLE_GAP_AD_TYPE_URI 0x24 /**< URI */
+#define BLE_GAP_AD_TYPE_3D_INFORMATION_DATA 0x3D /**< 3D Information Data. */
+#define BLE_GAP_AD_TYPE_MANUFACTURER_SPECIFIC_DATA 0xFF /**< Manufacturer Specific Data. */
+/**@} */
+
+
+/**@defgroup BLE_GAP_ADV_FLAGS GAP Advertisement Flags
+ * @{ */
+#define BLE_GAP_ADV_FLAG_LE_LIMITED_DISC_MODE (0x01) /**< LE Limited Discoverable Mode. */
+#define BLE_GAP_ADV_FLAG_LE_GENERAL_DISC_MODE (0x02) /**< LE General Discoverable Mode. */
+#define BLE_GAP_ADV_FLAG_BR_EDR_NOT_SUPPORTED (0x04) /**< BR/EDR not supported. */
+#define BLE_GAP_ADV_FLAG_LE_BR_EDR_CONTROLLER (0x08) /**< Simultaneous LE and BR/EDR, Controller. */
+#define BLE_GAP_ADV_FLAG_LE_BR_EDR_HOST (0x10) /**< Simultaneous LE and BR/EDR, Host. */
+#define BLE_GAP_ADV_FLAGS_LE_ONLY_LIMITED_DISC_MODE (BLE_GAP_ADV_FLAG_LE_LIMITED_DISC_MODE | BLE_GAP_ADV_FLAG_BR_EDR_NOT_SUPPORTED) /**< LE Limited Discoverable Mode, BR/EDR not supported. */
+#define BLE_GAP_ADV_FLAGS_LE_ONLY_GENERAL_DISC_MODE (BLE_GAP_ADV_FLAG_LE_GENERAL_DISC_MODE | BLE_GAP_ADV_FLAG_BR_EDR_NOT_SUPPORTED) /**< LE General Discoverable Mode, BR/EDR not supported. */
+/**@} */
+
+
+/**@defgroup BLE_GAP_ADV_INTERVALS GAP Advertising interval max and min
+ * @{ */
+#define BLE_GAP_ADV_INTERVAL_MIN 0x000020 /**< Minimum Advertising interval in 625 us units, i.e. 20 ms. */
+#define BLE_GAP_ADV_INTERVAL_MAX 0x004000 /**< Maximum Advertising interval in 625 us units, i.e. 10.24 s.
+ @note Support for values above @ref BLE_GAP_ADV_INTERVAL_MAX
+ is experimental. Values above 0xFFFFFF, i.e 10,485.759375 s
+ are not supported. */
+ /**@} */
+
+
+
+/**@defgroup BLE_GAP_ADV_TYPES GAP Advertising types
+ *
+ * Advertising types defined in Bluetooth Core Specification v5.0, Vol 6, Part B, Section 4.4.2.
+ *
+ * The maximum advertising data length is defined by @ref BLE_GAP_ADV_SET_DATA_SIZE_MAX.
+ * Note that some of the advertising types do not support advertising data. Non-scannable types do not support
+ * scan response data.
+ *
+ * @note Extended advertising is not supported in this SoftDevice.
+ * @{ */
+#define BLE_GAP_ADV_TYPE_CONNECTABLE_SCANNABLE_UNDIRECTED 0x01 /**< Connectable and scannable undirected
+ advertising events. */
+#define BLE_GAP_ADV_TYPE_CONNECTABLE_NONSCANNABLE_DIRECTED_HIGH_DUTY_CYCLE 0x02 /**< Connectable non-scannable directed advertising
+ events. Advertising interval is less that 3.75 ms.
+ Use this type for fast reconnections.
+ @note Advertising data is not supported. */
+#define BLE_GAP_ADV_TYPE_CONNECTABLE_NONSCANNABLE_DIRECTED 0x03 /**< Connectable non-scannable directed advertising
+ events.
+ @note Advertising data is not supported. */
+#define BLE_GAP_ADV_TYPE_NONCONNECTABLE_SCANNABLE_UNDIRECTED 0x04 /**< Non-connectable scannable undirected
+ advertising events. */
+#define BLE_GAP_ADV_TYPE_NONCONNECTABLE_NONSCANNABLE_UNDIRECTED 0x05 /**< Non-connectable non-scannable undirected
+ advertising events. */
+/**@} */
+
+/**@defgroup BLE_GAP_ADV_FILTER_POLICIES GAP Advertising filter policies
+ * @{ */
+#define BLE_GAP_ADV_FP_ANY 0x00 /**< Allow scan requests and connect requests from any device. */
+#define BLE_GAP_ADV_FP_FILTER_SCANREQ 0x01 /**< Filter scan requests with whitelist. */
+#define BLE_GAP_ADV_FP_FILTER_CONNREQ 0x02 /**< Filter connect requests with whitelist. */
+#define BLE_GAP_ADV_FP_FILTER_BOTH 0x03 /**< Filter both scan and connect requests with whitelist. */
+/**@} */
+
+
+/**@defgroup BLE_GAP_ADV_TIMEOUT_VALUES GAP Advertising timeout values in 10 ms units
+ * @{ */
+#define BLE_GAP_ADV_TIMEOUT_HIGH_DUTY_MAX (128) /**< Maximum high duty advertising time in 10 ms units. Corresponds to 1.28 s. */
+#define BLE_GAP_ADV_TIMEOUT_LIMITED_MAX (18000) /**< Maximum advertising time in 10 ms units corresponding to TGAP(lim_adv_timeout) = 180 s in limited discoverable mode. */
+#define BLE_GAP_ADV_TIMEOUT_GENERAL_UNLIMITED (0) /**< Unlimited advertising in general discoverable mode.
+ For high duty cycle advertising, this corresponds to @ref BLE_GAP_ADV_TIMEOUT_HIGH_DUTY_MAX. */
+/**@} */
+
+
+/**@defgroup BLE_GAP_DISC_MODES GAP Discovery modes
+ * @{ */
+#define BLE_GAP_DISC_MODE_NOT_DISCOVERABLE 0x00 /**< Not discoverable discovery Mode. */
+#define BLE_GAP_DISC_MODE_LIMITED 0x01 /**< Limited Discovery Mode. */
+#define BLE_GAP_DISC_MODE_GENERAL 0x02 /**< General Discovery Mode. */
+/**@} */
+
+
+/**@defgroup BLE_GAP_IO_CAPS GAP IO Capabilities
+ * @{ */
+#define BLE_GAP_IO_CAPS_DISPLAY_ONLY 0x00 /**< Display Only. */
+#define BLE_GAP_IO_CAPS_DISPLAY_YESNO 0x01 /**< Display and Yes/No entry. */
+#define BLE_GAP_IO_CAPS_KEYBOARD_ONLY 0x02 /**< Keyboard Only. */
+#define BLE_GAP_IO_CAPS_NONE 0x03 /**< No I/O capabilities. */
+#define BLE_GAP_IO_CAPS_KEYBOARD_DISPLAY 0x04 /**< Keyboard and Display. */
+/**@} */
+
+
+/**@defgroup BLE_GAP_AUTH_KEY_TYPES GAP Authentication Key Types
+ * @{ */
+#define BLE_GAP_AUTH_KEY_TYPE_NONE 0x00 /**< No key (may be used to reject). */
+#define BLE_GAP_AUTH_KEY_TYPE_PASSKEY 0x01 /**< 6-digit Passkey. */
+#define BLE_GAP_AUTH_KEY_TYPE_OOB 0x02 /**< Out Of Band data. */
+/**@} */
+
+
+/**@defgroup BLE_GAP_KP_NOT_TYPES GAP Keypress Notification Types
+ * @{ */
+#define BLE_GAP_KP_NOT_TYPE_PASSKEY_START 0x00 /**< Passkey entry started. */
+#define BLE_GAP_KP_NOT_TYPE_PASSKEY_DIGIT_IN 0x01 /**< Passkey digit entered. */
+#define BLE_GAP_KP_NOT_TYPE_PASSKEY_DIGIT_OUT 0x02 /**< Passkey digit erased. */
+#define BLE_GAP_KP_NOT_TYPE_PASSKEY_CLEAR 0x03 /**< Passkey cleared. */
+#define BLE_GAP_KP_NOT_TYPE_PASSKEY_END 0x04 /**< Passkey entry completed. */
+/**@} */
+
+
+/**@defgroup BLE_GAP_SEC_STATUS GAP Security status
+ * @{ */
+#define BLE_GAP_SEC_STATUS_SUCCESS 0x00 /**< Procedure completed with success. */
+#define BLE_GAP_SEC_STATUS_TIMEOUT 0x01 /**< Procedure timed out. */
+#define BLE_GAP_SEC_STATUS_PDU_INVALID 0x02 /**< Invalid PDU received. */
+#define BLE_GAP_SEC_STATUS_RFU_RANGE1_BEGIN 0x03 /**< Reserved for Future Use range #1 begin. */
+#define BLE_GAP_SEC_STATUS_RFU_RANGE1_END 0x80 /**< Reserved for Future Use range #1 end. */
+#define BLE_GAP_SEC_STATUS_PASSKEY_ENTRY_FAILED 0x81 /**< Passkey entry failed (user canceled or other). */
+#define BLE_GAP_SEC_STATUS_OOB_NOT_AVAILABLE 0x82 /**< Out of Band Key not available. */
+#define BLE_GAP_SEC_STATUS_AUTH_REQ 0x83 /**< Authentication requirements not met. */
+#define BLE_GAP_SEC_STATUS_CONFIRM_VALUE 0x84 /**< Confirm value failed. */
+#define BLE_GAP_SEC_STATUS_PAIRING_NOT_SUPP 0x85 /**< Pairing not supported. */
+#define BLE_GAP_SEC_STATUS_ENC_KEY_SIZE 0x86 /**< Encryption key size. */
+#define BLE_GAP_SEC_STATUS_SMP_CMD_UNSUPPORTED 0x87 /**< Unsupported SMP command. */
+#define BLE_GAP_SEC_STATUS_UNSPECIFIED 0x88 /**< Unspecified reason. */
+#define BLE_GAP_SEC_STATUS_REPEATED_ATTEMPTS 0x89 /**< Too little time elapsed since last attempt. */
+#define BLE_GAP_SEC_STATUS_INVALID_PARAMS 0x8A /**< Invalid parameters. */
+#define BLE_GAP_SEC_STATUS_DHKEY_FAILURE 0x8B /**< DHKey check failure. */
+#define BLE_GAP_SEC_STATUS_NUM_COMP_FAILURE 0x8C /**< Numeric Comparison failure. */
+#define BLE_GAP_SEC_STATUS_BR_EDR_IN_PROG 0x8D /**< BR/EDR pairing in progress. */
+#define BLE_GAP_SEC_STATUS_X_TRANS_KEY_DISALLOWED 0x8E /**< BR/EDR Link Key cannot be used for LE keys. */
+#define BLE_GAP_SEC_STATUS_RFU_RANGE2_BEGIN 0x8F /**< Reserved for Future Use range #2 begin. */
+#define BLE_GAP_SEC_STATUS_RFU_RANGE2_END 0xFF /**< Reserved for Future Use range #2 end. */
+/**@} */
+
+
+/**@defgroup BLE_GAP_SEC_STATUS_SOURCES GAP Security status sources
+ * @{ */
+#define BLE_GAP_SEC_STATUS_SOURCE_LOCAL 0x00 /**< Local failure. */
+#define BLE_GAP_SEC_STATUS_SOURCE_REMOTE 0x01 /**< Remote failure. */
+/**@} */
+
+
+/**@defgroup BLE_GAP_CP_LIMITS GAP Connection Parameters Limits
+ * @{ */
+#define BLE_GAP_CP_MIN_CONN_INTVL_NONE 0xFFFF /**< No new minimum connection interval specified in connect parameters. */
+#define BLE_GAP_CP_MIN_CONN_INTVL_MIN 0x0006 /**< Lowest minimum connection interval permitted, in units of 1.25 ms, i.e. 7.5 ms. */
+#define BLE_GAP_CP_MIN_CONN_INTVL_MAX 0x0C80 /**< Highest minimum connection interval permitted, in units of 1.25 ms, i.e. 4 s. */
+#define BLE_GAP_CP_MAX_CONN_INTVL_NONE 0xFFFF /**< No new maximum connection interval specified in connect parameters. */
+#define BLE_GAP_CP_MAX_CONN_INTVL_MIN 0x0006 /**< Lowest maximum connection interval permitted, in units of 1.25 ms, i.e. 7.5 ms. */
+#define BLE_GAP_CP_MAX_CONN_INTVL_MAX 0x0C80 /**< Highest maximum connection interval permitted, in units of 1.25 ms, i.e. 4 s. */
+#define BLE_GAP_CP_SLAVE_LATENCY_MAX 0x01F3 /**< Highest slave latency permitted, in connection events. */
+#define BLE_GAP_CP_CONN_SUP_TIMEOUT_NONE 0xFFFF /**< No new supervision timeout specified in connect parameters. */
+#define BLE_GAP_CP_CONN_SUP_TIMEOUT_MIN 0x000A /**< Lowest supervision timeout permitted, in units of 10 ms, i.e. 100 ms. */
+#define BLE_GAP_CP_CONN_SUP_TIMEOUT_MAX 0x0C80 /**< Highest supervision timeout permitted, in units of 10 ms, i.e. 32 s. */
+/**@} */
+
+
+/**@defgroup BLE_GAP_DEVNAME GAP device name defines.
+ * @{ */
+#define BLE_GAP_DEVNAME_DEFAULT "nRF5x" /**< Default device name value. */
+#define BLE_GAP_DEVNAME_DEFAULT_LEN 31 /**< Default number of octets in device name. */
+#define BLE_GAP_DEVNAME_MAX_LEN 248 /**< Maximum number of octets in device name. */
+/**@} */
+
+
+/**@brief Disable RSSI events for connections */
+#define BLE_GAP_RSSI_THRESHOLD_INVALID 0xFF
+
+/**@defgroup BLE_GAP_PHYS GAP PHYs
+ * @{ */
+#define BLE_GAP_PHY_AUTO 0x00 /**< Automatic PHY selection. Refer @ref sd_ble_gap_phy_update for more information.*/
+#define BLE_GAP_PHY_1MBPS 0x01 /**< 1 Mbps PHY. */
+#define BLE_GAP_PHY_2MBPS 0x02 /**< 2 Mbps PHY. */
+#define BLE_GAP_PHY_CODED 0x04 /**< Coded PHY. */
+#define BLE_GAP_PHY_NOT_SET 0xFF /**< PHY is not configured. */
+
+/**@brief Supported PHYs in connections and for advertising. */
+#define BLE_GAP_PHYS_SUPPORTED (BLE_GAP_PHY_1MBPS | BLE_GAP_PHY_2MBPS) /**< All PHYs except @ref BLE_GAP_PHY_CODED are supported. */
+
+/**@} */
+
+/**@defgroup BLE_GAP_CONN_SEC_MODE_SET_MACROS GAP attribute security requirement setters
+ *
+ * See @ref ble_gap_conn_sec_mode_t.
+ * @{ */
+/**@brief Set sec_mode pointed to by ptr to have no access rights.*/
+#define BLE_GAP_CONN_SEC_MODE_SET_NO_ACCESS(ptr) do {(ptr)->sm = 0; (ptr)->lv = 0;} while(0)
+/**@brief Set sec_mode pointed to by ptr to require no protection, open link.*/
+#define BLE_GAP_CONN_SEC_MODE_SET_OPEN(ptr) do {(ptr)->sm = 1; (ptr)->lv = 1;} while(0)
+/**@brief Set sec_mode pointed to by ptr to require encryption, but no MITM protection.*/
+#define BLE_GAP_CONN_SEC_MODE_SET_ENC_NO_MITM(ptr) do {(ptr)->sm = 1; (ptr)->lv = 2;} while(0)
+/**@brief Set sec_mode pointed to by ptr to require encryption and MITM protection.*/
+#define BLE_GAP_CONN_SEC_MODE_SET_ENC_WITH_MITM(ptr) do {(ptr)->sm = 1; (ptr)->lv = 3;} while(0)
+/**@brief Set sec_mode pointed to by ptr to require LESC encryption and MITM protection.*/
+#define BLE_GAP_CONN_SEC_MODE_SET_LESC_ENC_WITH_MITM(ptr) do {(ptr)->sm = 1; (ptr)->lv = 4;} while(0)
+/**@brief Set sec_mode pointed to by ptr to require signing or encryption, no MITM protection needed.*/
+#define BLE_GAP_CONN_SEC_MODE_SET_SIGNED_NO_MITM(ptr) do {(ptr)->sm = 2; (ptr)->lv = 1;} while(0)
+/**@brief Set sec_mode pointed to by ptr to require signing or encryption with MITM protection.*/
+#define BLE_GAP_CONN_SEC_MODE_SET_SIGNED_WITH_MITM(ptr) do {(ptr)->sm = 2; (ptr)->lv = 2;} while(0)
+/**@} */
+
+
+/**@brief GAP Security Random Number Length. */
+#define BLE_GAP_SEC_RAND_LEN 8
+
+
+/**@brief GAP Security Key Length. */
+#define BLE_GAP_SEC_KEY_LEN 16
+
+
+/**@brief GAP LE Secure Connections Elliptic Curve Diffie-Hellman P-256 Public Key Length. */
+#define BLE_GAP_LESC_P256_PK_LEN 64
+
+
+/**@brief GAP LE Secure Connections Elliptic Curve Diffie-Hellman DHKey Length. */
+#define BLE_GAP_LESC_DHKEY_LEN 32
+
+
+/**@brief GAP Passkey Length. */
+#define BLE_GAP_PASSKEY_LEN 6
+
+
+/**@brief Maximum amount of addresses in the whitelist. */
+#define BLE_GAP_WHITELIST_ADDR_MAX_COUNT (8)
+
+
+/**@brief Maximum amount of identities in the device identities list. */
+#define BLE_GAP_DEVICE_IDENTITIES_MAX_COUNT (8)
+
+
+/**@brief Default connection count for a configuration. */
+#define BLE_GAP_CONN_COUNT_DEFAULT (1)
+
+
+/**@defgroup BLE_GAP_EVENT_LENGTH GAP event length defines.
+ * @{ */
+#define BLE_GAP_EVENT_LENGTH_MIN (2) /**< Minimum event length, in 1.25 ms units. */
+#define BLE_GAP_EVENT_LENGTH_DEFAULT (3) /**< Default event length, in 1.25 ms units. */
+/**@} */
+
+
+/**@defgroup BLE_GAP_ROLE_COUNT GAP concurrent connection count defines.
+ * @{ */
+#define BLE_GAP_ROLE_COUNT_PERIPH_DEFAULT (1) /**< Default maximum number of connections concurrently acting as peripherals. */
+#define BLE_GAP_ROLE_COUNT_COMBINED_MAX (20) /**< Maximum supported number of concurrent connections in the peripheral roles. */
+
+/**@} */
+
+
+/**@defgroup BLE_GAP_AUTH_PAYLOAD_TIMEOUT Authenticated payload timeout defines.
+ * @{ */
+#define BLE_GAP_AUTH_PAYLOAD_TIMEOUT_MAX (48000) /**< Maximum authenticated payload timeout in 10 ms units, i.e. 8 minutes. */
+#define BLE_GAP_AUTH_PAYLOAD_TIMEOUT_MIN (1) /**< Minimum authenticated payload timeout in 10 ms units, i.e. 10 ms. */
+/**@} */
+
+/**@defgroup GAP_SEC_MODES GAP Security Modes
+ * @{ */
+#define BLE_GAP_SEC_MODE 0x00 /**< No key (may be used to reject). */
+/**@} */
+
+/** @} */
+
+
+/**@addtogroup BLE_GAP_STRUCTURES Structures
+ * @{ */
+
+/**@brief Advertising event properties. */
+typedef struct
+{
+ uint8_t type; /**< Advertising type. See @ref BLE_GAP_ADV_TYPES. */
+ uint8_t anonymous : 1; /**< This feature is not supported on this SoftDevice. */
+ uint8_t include_tx_power : 1; /**< This feature is not supported on this SoftDevice. */
+} ble_gap_adv_properties_t;
+
+
+
+/**@brief Bluetooth Low Energy address. */
+typedef struct
+{
+ uint8_t addr_id_peer : 1; /**< Only valid for peer addresses.
+ Reference to peer in device identities list (as set with @ref sd_ble_gap_device_identities_set) when peer is using privacy. */
+ uint8_t addr_type : 7; /**< See @ref BLE_GAP_ADDR_TYPES. */
+ uint8_t addr[BLE_GAP_ADDR_LEN]; /**< 48-bit address, LSB format. */
+} ble_gap_addr_t;
+
+
+/**@brief GAP connection parameters.
+ *
+ * @note When ble_conn_params_t is received in an event, both min_conn_interval and
+ * max_conn_interval will be equal to the connection interval set by the central.
+ *
+ * @note If both conn_sup_timeout and max_conn_interval are specified, then the following constraint applies:
+ * conn_sup_timeout * 4 > (1 + slave_latency) * max_conn_interval
+ * that corresponds to the following Bluetooth Spec requirement:
+ * The Supervision_Timeout in milliseconds shall be larger than
+ * (1 + Conn_Latency) * Conn_Interval_Max * 2, where Conn_Interval_Max is given in milliseconds.
+ */
+typedef struct
+{
+ uint16_t min_conn_interval; /**< Minimum Connection Interval in 1.25 ms units, see @ref BLE_GAP_CP_LIMITS.*/
+ uint16_t max_conn_interval; /**< Maximum Connection Interval in 1.25 ms units, see @ref BLE_GAP_CP_LIMITS.*/
+ uint16_t slave_latency; /**< Slave Latency in number of connection events, see @ref BLE_GAP_CP_LIMITS.*/
+ uint16_t conn_sup_timeout; /**< Connection Supervision Timeout in 10 ms units, see @ref BLE_GAP_CP_LIMITS.*/
+} ble_gap_conn_params_t;
+
+
+/**@brief GAP connection security modes.
+ *
+ * Security Mode 0 Level 0: No access permissions at all (this level is not defined by the Bluetooth Core specification).\n
+ * Security Mode 1 Level 1: No security is needed (aka open link).\n
+ * Security Mode 1 Level 2: Encrypted link required, MITM protection not necessary.\n
+ * Security Mode 1 Level 3: MITM protected encrypted link required.\n
+ * Security Mode 1 Level 4: LESC MITM protected encrypted link using a 128-bit strength encryption key required.\n
+ * Security Mode 2 Level 1: Signing or encryption required, MITM protection not necessary.\n
+ * Security Mode 2 Level 2: MITM protected signing required, unless link is MITM protected encrypted.\n
+ */
+typedef struct
+{
+ uint8_t sm : 4; /**< Security Mode (1 or 2), 0 for no permissions at all. */
+ uint8_t lv : 4; /**< Level (1, 2, 3 or 4), 0 for no permissions at all. */
+
+} ble_gap_conn_sec_mode_t;
+
+
+/**@brief GAP connection security status.*/
+typedef struct
+{
+ ble_gap_conn_sec_mode_t sec_mode; /**< Currently active security mode for this connection.*/
+ uint8_t encr_key_size; /**< Length of currently active encryption key, 7 to 16 octets (only applicable for bonding procedures). */
+} ble_gap_conn_sec_t;
+
+/**@brief Identity Resolving Key. */
+typedef struct
+{
+ uint8_t irk[BLE_GAP_SEC_KEY_LEN]; /**< Array containing IRK. */
+} ble_gap_irk_t;
+
+
+/**@brief Channel mask (40 bits).
+ * Every channel is represented with a bit positioned as per channel index defined in Bluetooth Core Specification v5.0,
+ * Vol 6, Part B, Section 1.4.1. The LSB contained in array element 0 represents channel index 0, and bit 39 represents
+ * channel index 39. If a bit is set to 1, the channel is not used.
+ */
+typedef uint8_t ble_gap_ch_mask_t[5];
+
+
+/**@brief GAP advertising parameters. */
+typedef struct
+{
+ ble_gap_adv_properties_t properties; /**< The properties of the advertising events. */
+ ble_gap_addr_t const *p_peer_addr; /**< Address of a known peer.
+ - When privacy is enabled and the local device uses
+ @ref BLE_GAP_ADDR_TYPE_RANDOM_PRIVATE_RESOLVABLE addresses,
+ the device identity list is searched for a matching entry. If
+ the local IRK for that device identity is set, the local IRK
+ for that device will be used to generate the advertiser address
+ field in the advertising packet.
+ - If @ref ble_gap_adv_properties_t::type is directed, this must be
+ set to the targeted scanner or initiator. If the peer address is
+ in the device identity list, the peer IRK for that device will be
+ used to generate @ref BLE_GAP_ADDR_TYPE_RANDOM_PRIVATE_RESOLVABLE
+ target addresses used in the advertising event PDUs. */
+ uint32_t interval; /**< Advertising interval in 625 us units. @sa BLE_GAP_ADV_INTERVALS.
+ @note If @ref ble_gap_adv_properties_t::type is set to
+ @ref BLE_GAP_ADV_TYPE_CONNECTABLE_NONSCANNABLE_DIRECTED_HIGH_DUTY_CYCLE
+ advertising, this parameter is ignored. */
+ uint16_t duration; /**< Advertising duration in 10 ms units. When timeout is reached,
+ an event of type @ref BLE_GAP_EVT_ADV_SET_TERMINATED is raised.
+ @sa BLE_GAP_ADV_TIMEOUT_VALUES. */
+ uint8_t max_adv_evts; /**< Maximum advertising events that shall be sent prior to disabling
+ advertising. Setting the value to 0 disables the limitation. When
+ the count of advertising events specified by this parameter
+ (if not 0) is reached, advertising will be automatically stopped
+ and an event of type @ref BLE_GAP_EVT_ADV_SET_TERMINATED is raised
+ @note If @ref ble_gap_adv_properties_t::type is set to
+ @ref BLE_GAP_ADV_TYPE_CONNECTABLE_NONSCANNABLE_DIRECTED_HIGH_DUTY_CYCLE,
+ this parameter is ignored.
+ @note Setting max_adv_evts to a values not equal to 0 is only supported
+ as an experimental feature in this SoftDevice. */
+ ble_gap_ch_mask_t channel_mask; /**< Channel mask for primary channels.
+ At least one of the primary channels, that is channel index 37-39, must be used. */
+ uint8_t filter_policy; /**< Filter Policy. @sa BLE_GAP_ADV_FILTER_POLICIES. */
+ uint8_t primary_phy; /**< Indicates the PHY on which the primary advertising channel packets
+ are transmitted. If set to @ref BLE_GAP_PHY_AUTO, @ref BLE_GAP_PHY_1MBPS
+ will be used.
+ The only supported value by this SoftDevice is @ref BLE_GAP_PHY_1MBPS. */
+ uint8_t secondary_phy; /**< This field is ignored on this SoftDevice. */
+ uint8_t set_id:4; /**< This field is ignored on this SoftDevice. */
+ uint8_t scan_req_notification:1; /**< Enable scan request notifications for this advertising set. When a
+ scan request is received and the scanner address is allowed
+ by the filter policy, @ref BLE_GAP_EVT_SCAN_REQ_REPORT is raised.
+ @note This parameter will be ignored when
+ @ref ble_gap_adv_properties_t::type is a non-scannable
+ advertising type. */
+} ble_gap_adv_params_t;
+
+
+/**@brief GAP advertising data buffers.
+ *
+ * The application must provide the buffers for advertisement. The memory shall reside in application RAM, and
+ * shall never be modified while advertising. The data shall be kept alive until either:
+ * - @ref BLE_GAP_EVT_ADV_SET_TERMINATED is raised.
+ * - @ref BLE_GAP_EVT_CONNECTED is raised with @ref ble_gap_evt_connected_t::adv_handle set to the corresponding
+ * advertising handle.
+ * - Advertising is stopped.
+ * - Advertising data is changed.
+ * To update advertising data while advertising, provide new buffers to @ref sd_ble_gap_adv_set_configure. */
+typedef struct
+{
+ ble_data_t adv_data; /**< Advertising data.
+ @note
+ Advertising data can only be specified for a @ref ble_gap_adv_properties_t::type
+ that is allowed to contain advertising data. */
+ ble_data_t scan_rsp_data; /**< Scan response data.
+ @note
+ Scan response data can only be specified for a @ref ble_gap_adv_properties_t::type
+ that is scannable. */
+} ble_gap_adv_data_t;
+
+
+/**@brief Privacy.
+ *
+ * The privacy feature provides a way for the device to avoid being tracked over a period of time.
+ * The privacy feature, when enabled, hides the local device identity and replaces it with a private address
+ * that is automatically refreshed at a specified interval.
+ *
+ * If a device still wants to be recognized by other peers, it needs to share it's Identity Resolving Key (IRK).
+ * With this key, a device can generate a random private address that can only be recognized by peers in possession of that key,
+ * and devices can establish connections without revealing their real identities.
+ *
+ * Both network privacy (@ref BLE_GAP_PRIVACY_MODE_NETWORK_PRIVACY) and device privacy (@ref BLE_GAP_PRIVACY_MODE_DEVICE_PRIVACY)
+ * are supported.
+ *
+ * @note If the device IRK is updated, the new IRK becomes the one to be distributed in all
+ * bonding procedures performed after @ref sd_ble_gap_privacy_set returns.
+ * The IRK distributed during bonding procedure is the device IRK that is active when @ref sd_ble_gap_sec_params_reply is called.
+ */
+typedef struct
+{
+ uint8_t privacy_mode; /**< Privacy mode, see @ref BLE_GAP_PRIVACY_MODES. Default is @ref BLE_GAP_PRIVACY_MODE_OFF. */
+ uint8_t private_addr_type; /**< The private address type must be either @ref BLE_GAP_ADDR_TYPE_RANDOM_PRIVATE_RESOLVABLE or @ref BLE_GAP_ADDR_TYPE_RANDOM_PRIVATE_NON_RESOLVABLE. */
+ uint16_t private_addr_cycle_s; /**< Private address cycle interval in seconds. Providing an address cycle value of 0 will use the default value defined by @ref BLE_GAP_DEFAULT_PRIVATE_ADDR_CYCLE_INTERVAL_S. */
+ ble_gap_irk_t *p_device_irk; /**< When used as input, pointer to IRK structure that will be used as the default IRK. If NULL, the device default IRK will be used.
+ When used as output, pointer to IRK structure where the current default IRK will be written to. If NULL, this argument is ignored.
+ By default, the default IRK is used to generate random private resolvable addresses for the local device unless instructed otherwise. */
+} ble_gap_privacy_params_t;
+
+
+/**@brief PHY preferences for TX and RX
+ * @note tx_phys and rx_phys are bit fields. Multiple bits can be set in them to indicate multiple preferred PHYs for each direction.
+ * @code
+ * p_gap_phys->tx_phys = BLE_GAP_PHY_1MBPS | BLE_GAP_PHY_2MBPS;
+ * p_gap_phys->rx_phys = BLE_GAP_PHY_1MBPS | BLE_GAP_PHY_2MBPS;
+ * @endcode
+ *
+ */
+typedef struct
+{
+ uint8_t tx_phys; /**< Preferred transmit PHYs, see @ref BLE_GAP_PHYS. */
+ uint8_t rx_phys; /**< Preferred receive PHYs, see @ref BLE_GAP_PHYS. */
+} ble_gap_phys_t;
+
+/** @brief Keys that can be exchanged during a bonding procedure. */
+typedef struct
+{
+ uint8_t enc : 1; /**< Long Term Key and Master Identification. */
+ uint8_t id : 1; /**< Identity Resolving Key and Identity Address Information. */
+ uint8_t sign : 1; /**< Connection Signature Resolving Key. */
+ uint8_t link : 1; /**< Derive the Link Key from the LTK. */
+} ble_gap_sec_kdist_t;
+
+
+/**@brief GAP security parameters. */
+typedef struct
+{
+ uint8_t bond : 1; /**< Perform bonding. */
+ uint8_t mitm : 1; /**< Enable Man In The Middle protection. */
+ uint8_t lesc : 1; /**< Enable LE Secure Connection pairing. */
+ uint8_t keypress : 1; /**< Enable generation of keypress notifications. */
+ uint8_t io_caps : 3; /**< IO capabilities, see @ref BLE_GAP_IO_CAPS. */
+ uint8_t oob : 1; /**< The OOB data flag.
+ - In LE legacy pairing, this flag is set if a device has out of band authentication data.
+ The OOB method is used if both of the devices have out of band authentication data.
+ - In LE Secure Connections pairing, this flag is set if a device has the peer device's out of band authentication data.
+ The OOB method is used if at least one device has the peer device's OOB data available. */
+ uint8_t min_key_size; /**< Minimum encryption key size in octets between 7 and 16. If 0 then not applicable in this instance. */
+ uint8_t max_key_size; /**< Maximum encryption key size in octets between min_key_size and 16. */
+ ble_gap_sec_kdist_t kdist_own; /**< Key distribution bitmap: keys that the local device will distribute. */
+ ble_gap_sec_kdist_t kdist_peer; /**< Key distribution bitmap: keys that the remote device will distribute. */
+} ble_gap_sec_params_t;
+
+
+/**@brief GAP Encryption Information. */
+typedef struct
+{
+ uint8_t ltk[BLE_GAP_SEC_KEY_LEN]; /**< Long Term Key. */
+ uint8_t lesc : 1; /**< Key generated using LE Secure Connections. */
+ uint8_t auth : 1; /**< Authenticated Key. */
+ uint8_t ltk_len : 6; /**< LTK length in octets. */
+} ble_gap_enc_info_t;
+
+
+/**@brief GAP Master Identification. */
+typedef struct
+{
+ uint16_t ediv; /**< Encrypted Diversifier. */
+ uint8_t rand[BLE_GAP_SEC_RAND_LEN]; /**< Random Number. */
+} ble_gap_master_id_t;
+
+
+/**@brief GAP Signing Information. */
+typedef struct
+{
+ uint8_t csrk[BLE_GAP_SEC_KEY_LEN]; /**< Connection Signature Resolving Key. */
+} ble_gap_sign_info_t;
+
+
+/**@brief GAP LE Secure Connections P-256 Public Key. */
+typedef struct
+{
+ uint8_t pk[BLE_GAP_LESC_P256_PK_LEN]; /**< LE Secure Connections Elliptic Curve Diffie-Hellman P-256 Public Key. Stored in the standard SMP protocol format: {X,Y} both in little-endian. */
+} ble_gap_lesc_p256_pk_t;
+
+
+/**@brief GAP LE Secure Connections DHKey. */
+typedef struct
+{
+ uint8_t key[BLE_GAP_LESC_DHKEY_LEN]; /**< LE Secure Connections Elliptic Curve Diffie-Hellman Key. Stored in little-endian. */
+} ble_gap_lesc_dhkey_t;
+
+
+/**@brief GAP LE Secure Connections OOB data. */
+typedef struct
+{
+ ble_gap_addr_t addr; /**< Bluetooth address of the device. */
+ uint8_t r[BLE_GAP_SEC_KEY_LEN]; /**< Random Number. */
+ uint8_t c[BLE_GAP_SEC_KEY_LEN]; /**< Confirm Value. */
+} ble_gap_lesc_oob_data_t;
+
+
+/**@brief Event structure for @ref BLE_GAP_EVT_CONNECTED. */
+typedef struct
+{
+ ble_gap_addr_t peer_addr; /**< Bluetooth address of the peer device. If the peer_addr resolved: @ref ble_gap_addr_t::addr_id_peer is set to 1
+ and the address is the device's identity address. */
+ uint8_t role; /**< BLE role for this connection, see @ref BLE_GAP_ROLES */
+ ble_gap_conn_params_t conn_params; /**< GAP Connection Parameters. */
+ uint8_t adv_handle; /**< Advertising handle in which advertising has ended.
+ This variable is only set if role is set to @ref BLE_GAP_ROLE_PERIPH. */
+ ble_gap_adv_data_t adv_data; /**< Advertising buffers corresponding to the terminated
+ advertising set. The advertising buffers provided in
+ @ref sd_ble_gap_adv_set_configure are now released.
+ This variable is only set if role is set to @ref BLE_GAP_ROLE_PERIPH. */
+} ble_gap_evt_connected_t;
+
+
+/**@brief Event structure for @ref BLE_GAP_EVT_DISCONNECTED. */
+typedef struct
+{
+ uint8_t reason; /**< HCI error code, see @ref BLE_HCI_STATUS_CODES. */
+} ble_gap_evt_disconnected_t;
+
+
+/**@brief Event structure for @ref BLE_GAP_EVT_CONN_PARAM_UPDATE. */
+typedef struct
+{
+ ble_gap_conn_params_t conn_params; /**< GAP Connection Parameters. */
+} ble_gap_evt_conn_param_update_t;
+
+/**@brief Event structure for @ref BLE_GAP_EVT_PHY_UPDATE_REQUEST. */
+typedef struct
+{
+ ble_gap_phys_t peer_preferred_phys; /**< The PHYs the peer prefers to use. */
+} ble_gap_evt_phy_update_request_t;
+
+/**@brief Event Structure for @ref BLE_GAP_EVT_PHY_UPDATE. */
+typedef struct
+{
+ uint8_t status; /**< Status of the procedure, see @ref BLE_HCI_STATUS_CODES.*/
+ uint8_t tx_phy; /**< TX PHY for this connection, see @ref BLE_GAP_PHYS. */
+ uint8_t rx_phy; /**< RX PHY for this connection, see @ref BLE_GAP_PHYS. */
+} ble_gap_evt_phy_update_t;
+
+/**@brief Event structure for @ref BLE_GAP_EVT_SEC_PARAMS_REQUEST. */
+typedef struct
+{
+ ble_gap_sec_params_t peer_params; /**< Initiator Security Parameters. */
+} ble_gap_evt_sec_params_request_t;
+
+
+/**@brief Event structure for @ref BLE_GAP_EVT_SEC_INFO_REQUEST. */
+typedef struct
+{
+ ble_gap_addr_t peer_addr; /**< Bluetooth address of the peer device. */
+ ble_gap_master_id_t master_id; /**< Master Identification for LTK lookup. */
+ uint8_t enc_info : 1; /**< If 1, Encryption Information required. */
+ uint8_t id_info : 1; /**< If 1, Identity Information required. */
+ uint8_t sign_info : 1; /**< If 1, Signing Information required. */
+} ble_gap_evt_sec_info_request_t;
+
+
+/**@brief Event structure for @ref BLE_GAP_EVT_PASSKEY_DISPLAY. */
+typedef struct
+{
+ uint8_t passkey[BLE_GAP_PASSKEY_LEN]; /**< 6-digit passkey in ASCII ('0'-'9' digits only). */
+ uint8_t match_request : 1; /**< If 1 requires the application to report the match using @ref sd_ble_gap_auth_key_reply
+ with either @ref BLE_GAP_AUTH_KEY_TYPE_NONE if there is no match or
+ @ref BLE_GAP_AUTH_KEY_TYPE_PASSKEY if there is a match. */
+} ble_gap_evt_passkey_display_t;
+
+/**@brief Event structure for @ref BLE_GAP_EVT_KEY_PRESSED. */
+typedef struct
+{
+ uint8_t kp_not; /**< Keypress notification type, see @ref BLE_GAP_KP_NOT_TYPES. */
+} ble_gap_evt_key_pressed_t;
+
+
+/**@brief Event structure for @ref BLE_GAP_EVT_AUTH_KEY_REQUEST. */
+typedef struct
+{
+ uint8_t key_type; /**< See @ref BLE_GAP_AUTH_KEY_TYPES. */
+} ble_gap_evt_auth_key_request_t;
+
+/**@brief Event structure for @ref BLE_GAP_EVT_LESC_DHKEY_REQUEST. */
+typedef struct
+{
+ ble_gap_lesc_p256_pk_t *p_pk_peer; /**< LE Secure Connections remote P-256 Public Key. This will point to the application-supplied memory
+ inside the keyset during the call to @ref sd_ble_gap_sec_params_reply. */
+ uint8_t oobd_req :1; /**< LESC OOB data required. A call to @ref sd_ble_gap_lesc_oob_data_set is required to complete the procedure. */
+} ble_gap_evt_lesc_dhkey_request_t;
+
+
+/**@brief Security levels supported.
+ * @note See Bluetooth Specification Version 4.2 Volume 3, Part C, Chapter 10, Section 10.2.1.
+*/
+typedef struct
+{
+ uint8_t lv1 : 1; /**< If 1: Level 1 is supported. */
+ uint8_t lv2 : 1; /**< If 1: Level 2 is supported. */
+ uint8_t lv3 : 1; /**< If 1: Level 3 is supported. */
+ uint8_t lv4 : 1; /**< If 1: Level 4 is supported. */
+} ble_gap_sec_levels_t;
+
+
+/**@brief Encryption Key. */
+typedef struct
+{
+ ble_gap_enc_info_t enc_info; /**< Encryption Information. */
+ ble_gap_master_id_t master_id; /**< Master Identification. */
+} ble_gap_enc_key_t;
+
+
+/**@brief Identity Key. */
+typedef struct
+{
+ ble_gap_irk_t id_info; /**< Identity Resolving Key. */
+ ble_gap_addr_t id_addr_info; /**< Identity Address. */
+} ble_gap_id_key_t;
+
+
+/**@brief Security Keys. */
+typedef struct
+{
+ ble_gap_enc_key_t *p_enc_key; /**< Encryption Key, or NULL. */
+ ble_gap_id_key_t *p_id_key; /**< Identity Key, or NULL. */
+ ble_gap_sign_info_t *p_sign_key; /**< Signing Key, or NULL. */
+ ble_gap_lesc_p256_pk_t *p_pk; /**< LE Secure Connections P-256 Public Key. When in debug mode the application must use the value defined
+ in the Core Bluetooth Specification v4.2 Vol.3, Part H, Section 2.3.5.6.1 */
+} ble_gap_sec_keys_t;
+
+
+/**@brief Security key set for both local and peer keys. */
+typedef struct
+{
+ ble_gap_sec_keys_t keys_own; /**< Keys distributed by the local device. For LE Secure Connections the encryption key will be generated locally and will always be stored if bonding. */
+ ble_gap_sec_keys_t keys_peer; /**< Keys distributed by the remote device. For LE Secure Connections, p_enc_key must always be NULL. */
+} ble_gap_sec_keyset_t;
+
+
+/**@brief Event structure for @ref BLE_GAP_EVT_AUTH_STATUS. */
+typedef struct
+{
+ uint8_t auth_status; /**< Authentication status, see @ref BLE_GAP_SEC_STATUS. */
+ uint8_t error_src : 2; /**< On error, source that caused the failure, see @ref BLE_GAP_SEC_STATUS_SOURCES. */
+ uint8_t bonded : 1; /**< Procedure resulted in a bond. */
+ uint8_t lesc : 1; /**< Procedure resulted in a LE Secure Connection. */
+ ble_gap_sec_levels_t sm1_levels; /**< Levels supported in Security Mode 1. */
+ ble_gap_sec_levels_t sm2_levels; /**< Levels supported in Security Mode 2. */
+ ble_gap_sec_kdist_t kdist_own; /**< Bitmap stating which keys were exchanged (distributed) by the local device. If bonding with LE Secure Connections, the enc bit will be always set. */
+ ble_gap_sec_kdist_t kdist_peer; /**< Bitmap stating which keys were exchanged (distributed) by the remote device. If bonding with LE Secure Connections, the enc bit will never be set. */
+} ble_gap_evt_auth_status_t;
+
+
+/**@brief Event structure for @ref BLE_GAP_EVT_CONN_SEC_UPDATE. */
+typedef struct
+{
+ ble_gap_conn_sec_t conn_sec; /**< Connection security level. */
+} ble_gap_evt_conn_sec_update_t;
+
+
+/**@brief Event structure for @ref BLE_GAP_EVT_TIMEOUT. */
+typedef struct
+{
+ uint8_t src; /**< Source of timeout event, see @ref BLE_GAP_TIMEOUT_SOURCES. */
+} ble_gap_evt_timeout_t;
+
+
+/**@brief Event structure for @ref BLE_GAP_EVT_RSSI_CHANGED. */
+typedef struct
+{
+ int8_t rssi; /**< Received Signal Strength Indication in dBm. */
+ uint8_t ch_index; /**< Data Channel Index on which the Signal Strength is measured (0-36). */
+} ble_gap_evt_rssi_changed_t;
+
+/**@brief Event structure for @ref BLE_GAP_EVT_ADV_SET_TERMINATED */
+typedef struct
+{
+ uint8_t reason; /**< Reason for why the advertising set terminated. See
+ @ref BLE_GAP_EVT_ADV_SET_TERMINATED_REASON. */
+ uint8_t adv_handle; /**< Advertising handle in which advertising has ended. */
+ uint8_t num_completed_adv_events; /**< If @ref ble_gap_adv_params_t::max_adv_evts was not set to 0,
+ this field indicates the number of completed advertising events. */
+ ble_gap_adv_data_t adv_data; /**< Advertising buffers corresponding to the terminated
+ advertising set. The advertising buffers provided in
+ @ref sd_ble_gap_adv_set_configure are now released. */
+} ble_gap_evt_adv_set_terminated_t;
+
+/**@brief Event structure for @ref BLE_GAP_EVT_SEC_REQUEST. */
+typedef struct
+{
+ uint8_t bond : 1; /**< Perform bonding. */
+ uint8_t mitm : 1; /**< Man In The Middle protection requested. */
+ uint8_t lesc : 1; /**< LE Secure Connections requested. */
+ uint8_t keypress : 1; /**< Generation of keypress notifications requested. */
+} ble_gap_evt_sec_request_t;
+
+
+/**@brief Event structure for @ref BLE_GAP_EVT_SCAN_REQ_REPORT. */
+typedef struct
+{
+ uint8_t adv_handle; /**< Advertising handle for the advertising set which received the Scan Request */
+ int8_t rssi; /**< Received Signal Strength Indication in dBm. */
+ ble_gap_addr_t peer_addr; /**< Bluetooth address of the peer device. If the peer_addr resolved: @ref ble_gap_addr_t::addr_id_peer is set to 1
+ and the address is the device's identity address. */
+} ble_gap_evt_scan_req_report_t;
+
+
+
+/**@brief GAP event structure. */
+typedef struct
+{
+ uint16_t conn_handle; /**< Connection Handle on which event occurred. */
+ union /**< union alternative identified by evt_id in enclosing struct. */
+ {
+ ble_gap_evt_connected_t connected; /**< Connected Event Parameters. */
+ ble_gap_evt_disconnected_t disconnected; /**< Disconnected Event Parameters. */
+ ble_gap_evt_conn_param_update_t conn_param_update; /**< Connection Parameter Update Parameters. */
+ ble_gap_evt_sec_params_request_t sec_params_request; /**< Security Parameters Request Event Parameters. */
+ ble_gap_evt_sec_info_request_t sec_info_request; /**< Security Information Request Event Parameters. */
+ ble_gap_evt_passkey_display_t passkey_display; /**< Passkey Display Event Parameters. */
+ ble_gap_evt_key_pressed_t key_pressed; /**< Key Pressed Event Parameters. */
+ ble_gap_evt_auth_key_request_t auth_key_request; /**< Authentication Key Request Event Parameters. */
+ ble_gap_evt_lesc_dhkey_request_t lesc_dhkey_request; /**< LE Secure Connections DHKey calculation request. */
+ ble_gap_evt_auth_status_t auth_status; /**< Authentication Status Event Parameters. */
+ ble_gap_evt_conn_sec_update_t conn_sec_update; /**< Connection Security Update Event Parameters. */
+ ble_gap_evt_timeout_t timeout; /**< Timeout Event Parameters. */
+ ble_gap_evt_rssi_changed_t rssi_changed; /**< RSSI Event Parameters. */
+ ble_gap_evt_adv_set_terminated_t adv_set_terminated; /**< Advertising Set Terminated Event Parameters. */
+ ble_gap_evt_sec_request_t sec_request; /**< Security Request Event Parameters. */
+ ble_gap_evt_scan_req_report_t scan_req_report; /**< Scan Request Report Parameters. */
+ ble_gap_evt_phy_update_request_t phy_update_request; /**< PHY Update Request Event Parameters. */
+ ble_gap_evt_phy_update_t phy_update; /**< PHY Update Parameters. */
+ } params; /**< Event Parameters. */
+} ble_gap_evt_t;
+
+
+/**
+ * @brief BLE GAP connection configuration parameters, set with @ref sd_ble_cfg_set.
+ *
+ * @retval ::NRF_ERROR_CONN_COUNT The connection count for the connection configurations is zero.
+ * @retval ::NRF_ERROR_INVALID_PARAM One or more of the following is true:
+ * - The sum of conn_count for all connection configurations combined exceeds UINT8_MAX.
+ * - The event length is smaller than @ref BLE_GAP_EVENT_LENGTH_MIN.
+ */
+typedef struct
+{
+ uint8_t conn_count; /**< The number of concurrent connections the application can create with this configuration.
+ The default and minimum value is @ref BLE_GAP_CONN_COUNT_DEFAULT. */
+ uint16_t event_length; /**< The time set aside for this connection on every connection interval in 1.25 ms units.
+ The default value is @ref BLE_GAP_EVENT_LENGTH_DEFAULT, the minimum value is @ref BLE_GAP_EVENT_LENGTH_MIN.
+ The event length and the connection interval are the primary parameters
+ for setting the throughput of a connection.
+ See the SoftDevice Specification for details on throughput. */
+} ble_gap_conn_cfg_t;
+
+
+/**
+ * @brief Configuration of maximum concurrent connections in the peripheral role, set with
+ * @ref sd_ble_cfg_set.
+ *
+ * @retval ::NRF_ERROR_CONN_COUNT The periph_role_count is too large. The maximum
+ * supported sum of concurrent connections is
+ * @ref BLE_GAP_ROLE_COUNT_COMBINED_MAX.
+ * @retval ::NRF_ERROR_RESOURCES The adv_set_count is too large. The maximum
+ * supported advertising handles is
+ * @ref BLE_GAP_ADV_SET_COUNT_MAX.
+ */
+typedef struct
+{
+ uint8_t adv_set_count; /**< Maximum number of advertising sets. Default value is @ref BLE_GAP_ADV_SET_COUNT_DEFAULT. */
+ uint8_t periph_role_count; /**< Maximum number of connections concurrently acting as a peripheral. Default value is @ref BLE_GAP_ROLE_COUNT_PERIPH_DEFAULT. */
+} ble_gap_cfg_role_count_t;
+
+
+/**
+ * @brief Device name and its properties, set with @ref sd_ble_cfg_set.
+ *
+ * @note If the device name is not configured, the default device name will be
+ * @ref BLE_GAP_DEVNAME_DEFAULT, the maximum device name length will be
+ * @ref BLE_GAP_DEVNAME_DEFAULT_LEN, vloc will be set to @ref BLE_GATTS_VLOC_STACK and the device name
+ * will have no write access.
+ *
+ * @note If @ref max_len is more than @ref BLE_GAP_DEVNAME_DEFAULT_LEN and vloc is set to @ref BLE_GATTS_VLOC_STACK,
+ * the attribute table size must be increased to have room for the longer device name (see
+ * @ref sd_ble_cfg_set and @ref ble_gatts_cfg_attr_tab_size_t).
+ *
+ * @note If vloc is @ref BLE_GATTS_VLOC_STACK :
+ * - p_value must point to non-volatile memory (flash) or be NULL.
+ * - If p_value is NULL, the device name will initially be empty.
+ *
+ * @note If vloc is @ref BLE_GATTS_VLOC_USER :
+ * - p_value cannot be NULL.
+ * - If the device name is writable, p_value must point to volatile memory (RAM).
+ *
+ * @retval ::NRF_ERROR_INVALID_PARAM One or more of the following is true:
+ * - Invalid device name location (vloc).
+ * - Invalid device name security mode.
+ * @retval ::NRF_ERROR_INVALID_LENGTH One or more of the following is true:
+ * - The device name length is invalid (must be between 0 and @ref BLE_GAP_DEVNAME_MAX_LEN).
+ * - The device name length is too long for the given Attribute Table.
+ * @retval ::NRF_ERROR_NOT_SUPPORTED Device name security mode is not supported.
+ */
+typedef struct
+{
+ ble_gap_conn_sec_mode_t write_perm; /**< Write permissions. */
+ uint8_t vloc:2; /**< Value location, see @ref BLE_GATTS_VLOCS.*/
+ uint8_t *p_value; /**< Pointer to where the value (device name) is stored or will be stored. */
+ uint16_t current_len; /**< Current length in bytes of the memory pointed to by p_value.*/
+ uint16_t max_len; /**< Maximum length in bytes of the memory pointed to by p_value.*/
+} ble_gap_cfg_device_name_t;
+
+
+/**@brief Configuration structure for GAP configurations. */
+typedef union
+{
+ ble_gap_cfg_role_count_t role_count_cfg; /**< Role count configuration, cfg_id is @ref BLE_GAP_CFG_ROLE_COUNT. */
+ ble_gap_cfg_device_name_t device_name_cfg; /**< Device name configuration, cfg_id is @ref BLE_GAP_CFG_DEVICE_NAME. */
+} ble_gap_cfg_t;
+
+
+/**@brief Channel Map option.
+ *
+ * @details Used with @ref sd_ble_opt_get to get the current channel map
+ * or @ref sd_ble_opt_set to set a new channel map. When setting the
+ * channel map, it applies to all current and future connections. When getting the
+ * current channel map, it applies to a single connection and the connection handle
+ * must be supplied.
+ *
+ * @note Setting the channel map may take some time, depending on connection parameters.
+ * The time taken may be different for each connection and the get operation will
+ * return the previous channel map until the new one has taken effect.
+ *
+ * @note After setting the channel map, by spec it can not be set again until at least 1 s has passed.
+ * See Bluetooth Specification Version 4.1 Volume 2, Part E, Section 7.3.46.
+ *
+ * @retval ::NRF_SUCCESS Get or set successful.
+ * @retval ::NRF_ERROR_INVALID_PARAM One or more of the following is true:
+ * - Less then two bits in @ref ch_map are set.
+ * - Bits for primary advertising channels (37-39) are set.
+ * @retval ::NRF_ERROR_BUSY Channel map was set again before enough time had passed.
+ * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid connection handle supplied for get.
+ * @retval ::NRF_ERROR_NOT_SUPPORTED Returned by @ref sd_ble_opt_set in peripheral-only SoftDevices.
+ *
+ */
+typedef struct
+{
+ uint16_t conn_handle; /**< Connection Handle (only applicable for get) */
+ uint8_t ch_map[5]; /**< Channel Map (37-bit). */
+} ble_gap_opt_ch_map_t;
+
+
+/**@brief Local connection latency option.
+ *
+ * @details Local connection latency is a feature which enables the slave to improve
+ * current consumption by ignoring the slave latency set by the peer. The
+ * local connection latency can only be set to a multiple of the slave latency,
+ * and cannot be longer than half of the supervision timeout.
+ *
+ * @details Used with @ref sd_ble_opt_set to set the local connection latency. The
+ * @ref sd_ble_opt_get is not supported for this option, but the actual
+ * local connection latency (unless set to NULL) is set as a return parameter
+ * when setting the option.
+ *
+ * @note The latency set will be truncated down to the closest slave latency event
+ * multiple, or the nearest multiple before half of the supervision timeout.
+ *
+ * @note The local connection latency is disabled by default, and needs to be enabled for new
+ * connections and whenever the connection is updated.
+ *
+ * @retval ::NRF_SUCCESS Set successfully.
+ * @retval ::NRF_ERROR_NOT_SUPPORTED Get is not supported.
+ * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid connection handle parameter.
+ */
+typedef struct
+{
+ uint16_t conn_handle; /**< Connection Handle */
+ uint16_t requested_latency; /**< Requested local connection latency. */
+ uint16_t * p_actual_latency; /**< Pointer to storage for the actual local connection latency (can be set to NULL to skip return value). */
+} ble_gap_opt_local_conn_latency_t;
+
+/**@brief Disable slave latency
+ *
+ * @details Used with @ref sd_ble_opt_set to temporarily disable slave latency of a peripheral connection
+ * (see @ref ble_gap_conn_params_t::slave_latency). And to re-enable it again. When disabled, the
+ * peripheral will ignore the slave_latency set by the central.
+ *
+ * @note Shall only be called on peripheral links.
+ *
+ * @retval ::NRF_SUCCESS Set successfully.
+ * @retval ::NRF_ERROR_NOT_SUPPORTED Get is not supported.
+ * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid connection handle parameter.
+ */
+typedef struct
+{
+ uint16_t conn_handle; /**< Connection Handle */
+ uint8_t disable : 1; /**< Set to 1 to disable slave latency. Set to 0 enable it again.*/
+} ble_gap_opt_slave_latency_disable_t;
+
+/**@brief Passkey Option.
+ *
+ * @details Structure containing the passkey to be used during pairing. This can be used with @ref
+ * sd_ble_opt_set to make the SoftDevice use a preprogrammed passkey for authentication
+ * instead of generating a random one.
+ *
+ * @note Repeated pairing attempts using the same preprogrammed passkey makes pairing vulnerable to MITM attacks.
+ *
+ * @note @ref sd_ble_opt_get is not supported for this option.
+ *
+ */
+typedef struct
+{
+ uint8_t const * p_passkey; /**< Pointer to 6-digit ASCII string (digit 0..9 only, no NULL termination) passkey to be used during pairing. If this is NULL, the SoftDevice will generate a random passkey if required.*/
+} ble_gap_opt_passkey_t;
+
+
+/**@brief Authenticated payload timeout option.
+ *
+ * @details This can be used with @ref sd_ble_opt_set to change the Authenticated payload timeout to a value other
+ * than the default of @ref BLE_GAP_AUTH_PAYLOAD_TIMEOUT_MAX.
+ *
+ * @note The authenticated payload timeout event ::BLE_GAP_TIMEOUT_SRC_AUTH_PAYLOAD will be generated
+ * if auth_payload_timeout time has elapsed without receiving a packet with a valid MIC on an encrypted
+ * link.
+ *
+ * @note The LE ping procedure will be initiated before the timer expires to give the peer a chance
+ * to reset the timer. In addition the stack will try to prioritize running of LE ping over other
+ * activities to increase chances of finishing LE ping before timer expires. To avoid side-effects
+ * on other activities, it is recommended to use high timeout values.
+ * Recommended timeout > 2*(connInterval * (6 + connSlaveLatency)).
+ *
+ * @retval ::NRF_SUCCESS Set successfully.
+ * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied. auth_payload_timeout was outside of allowed range.
+ * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid connection handle parameter.
+ */
+typedef struct
+{
+ uint16_t conn_handle; /**< Connection Handle */
+ uint16_t auth_payload_timeout; /**< Requested timeout in 10 ms unit, see @ref BLE_GAP_AUTH_PAYLOAD_TIMEOUT. */
+} ble_gap_opt_auth_payload_timeout_t;
+
+/**@brief Option structure for GAP options. */
+typedef union
+{
+ ble_gap_opt_ch_map_t ch_map; /**< Parameters for the Channel Map option. */
+ ble_gap_opt_local_conn_latency_t local_conn_latency; /**< Parameters for the Local connection latency option */
+ ble_gap_opt_passkey_t passkey; /**< Parameters for the Passkey option.*/
+ ble_gap_opt_auth_payload_timeout_t auth_payload_timeout; /**< Parameters for the authenticated payload timeout option.*/
+ ble_gap_opt_slave_latency_disable_t slave_latency_disable; /**< Parameters for the Disable slave latency option */
+} ble_gap_opt_t;
+/**@} */
+
+
+/**@addtogroup BLE_GAP_FUNCTIONS Functions
+ * @{ */
+
+/**@brief Set the local Bluetooth identity address.
+ *
+ * The local Bluetooth identity address is the address that identifies this device to other peers.
+ * The address type must be either @ref BLE_GAP_ADDR_TYPE_PUBLIC or @ref BLE_GAP_ADDR_TYPE_RANDOM_STATIC.
+ *
+ * @note The identity address cannot be changed while advertising.
+ *
+ * @note This address will be distributed to the peer during bonding.
+ * If the address changes, the address stored in the peer device will not be valid and the ability to
+ * reconnect using the old address will be lost.
+ *
+ * @note By default the SoftDevice will set an address of type @ref BLE_GAP_ADDR_TYPE_RANDOM_STATIC upon being
+ * enabled. The address is a random number populated during the IC manufacturing process and remains unchanged
+ * for the lifetime of each IC.
+ *
+ * @mscs
+ * @mmsc{@ref BLE_GAP_ADV_MSC}
+ * @endmscs
+ *
+ * @param[in] p_addr Pointer to address structure.
+ *
+ * @retval ::NRF_SUCCESS Address successfully set.
+ * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied.
+ * @retval ::BLE_ERROR_GAP_INVALID_BLE_ADDR Invalid address.
+ * @retval ::NRF_ERROR_BUSY The stack is busy, process pending events and retry.
+ * @retval ::NRF_ERROR_INVALID_STATE The identity address cannot be changed while advertising.
+ */
+SVCALL(SD_BLE_GAP_ADDR_SET, uint32_t, sd_ble_gap_addr_set(ble_gap_addr_t const *p_addr));
+
+
+/**@brief Get local Bluetooth identity address.
+ *
+ * @note This will always return the identity address irrespective of the privacy settings,
+ * i.e. the address type will always be either @ref BLE_GAP_ADDR_TYPE_PUBLIC or @ref BLE_GAP_ADDR_TYPE_RANDOM_STATIC.
+ *
+ * @param[out] p_addr Pointer to address structure to be filled in.
+ *
+ * @retval ::NRF_SUCCESS Address successfully retrieved.
+ * @retval ::NRF_ERROR_INVALID_ADDR Invalid or NULL pointer supplied.
+ */
+SVCALL(SD_BLE_GAP_ADDR_GET, uint32_t, sd_ble_gap_addr_get(ble_gap_addr_t *p_addr));
+
+
+/**@brief Set the active whitelist in the SoftDevice.
+ *
+ * @note Only one whitelist can be used at a time and the whitelist is shared between the BLE roles.
+ * The whitelist cannot be set if a BLE role is using the whitelist.
+ *
+ * @note If an address is resolved using the information in the device identity list, then the whitelist
+ * filter policy applies to the peer identity address and not the resolvable address sent on air.
+ *
+ * @param[in] pp_wl_addrs Pointer to a whitelist of peer addresses, if NULL the whitelist will be cleared.
+ * @param[in] len Length of the whitelist, maximum @ref BLE_GAP_WHITELIST_ADDR_MAX_COUNT.
+ *
+ * @retval ::NRF_SUCCESS The whitelist is successfully set/cleared.
+ * @retval ::NRF_ERROR_INVALID_ADDR The whitelist (or one of its entries) provided is invalid.
+ * @retval ::BLE_ERROR_GAP_WHITELIST_IN_USE The whitelist is in use by a BLE role and cannot be set or cleared.
+ * @retval ::BLE_ERROR_GAP_INVALID_BLE_ADDR Invalid address type is supplied.
+ * @retval ::NRF_ERROR_DATA_SIZE The given whitelist size is invalid (zero or too large); this can only return when
+ * pp_wl_addrs is not NULL.
+ */
+SVCALL(SD_BLE_GAP_WHITELIST_SET, uint32_t, sd_ble_gap_whitelist_set(ble_gap_addr_t const * const * pp_wl_addrs, uint8_t len));
+
+
+/**@brief Set device identity list.
+ *
+ * @note Only one device identity list can be used at a time and the list is shared between the BLE roles.
+ * The device identity list cannot be set if a BLE role is using the list.
+ *
+ * @param[in] pp_id_keys Pointer to an array of peer identity addresses and peer IRKs, if NULL the device identity list will be cleared.
+ * @param[in] pp_local_irks Pointer to an array of local IRKs. Each entry in the array maps to the entry in pp_id_keys at the same index.
+ * To fill in the list with the currently set device IRK for all peers, set to NULL.
+ * @param[in] len Length of the device identity list, maximum @ref BLE_GAP_DEVICE_IDENTITIES_MAX_COUNT.
+ *
+ * @mscs
+ * @mmsc{@ref BLE_GAP_PRIVACY_ADV_MSC}
+ * @mmsc{@ref BLE_GAP_PRIVACY_ADV_DIR_PRIV_MSC}
+ * @mmsc{@ref BLE_GAP_PERIPH_CONN_PRIV_MSC}
+ * @endmscs
+ *
+ * @retval ::NRF_SUCCESS The device identity list successfully set/cleared.
+ * @retval ::NRF_ERROR_INVALID_ADDR The device identity list (or one of its entries) provided is invalid.
+ * This code may be returned if the local IRK list also has an invalid entry.
+ * @retval ::BLE_ERROR_GAP_DEVICE_IDENTITIES_IN_USE The device identity list is in use and cannot be set or cleared.
+ * @retval ::BLE_ERROR_GAP_DEVICE_IDENTITIES_DUPLICATE The device identity list contains multiple entries with the same identity address.
+ * @retval ::BLE_ERROR_GAP_INVALID_BLE_ADDR Invalid address type is supplied.
+ * @retval ::NRF_ERROR_DATA_SIZE The given device identity list size invalid (zero or too large); this can
+ * only return when pp_id_keys is not NULL.
+ */
+SVCALL(SD_BLE_GAP_DEVICE_IDENTITIES_SET, uint32_t, sd_ble_gap_device_identities_set(ble_gap_id_key_t const * const * pp_id_keys, ble_gap_irk_t const * const * pp_local_irks, uint8_t len));
+
+
+/**@brief Set privacy settings.
+ *
+ * @note Privacy settings cannot be changed while advertising.
+ *
+ * @param[in] p_privacy_params Privacy settings.
+ *
+ * @mscs
+ * @mmsc{@ref BLE_GAP_PRIVACY_ADV_MSC}
+ * @mmsc{@ref BLE_GAP_PRIVACY_ADV_DIR_PRIV_MSC}
+ * @endmscs
+ *
+ * @retval ::NRF_SUCCESS Set successfully.
+ * @retval ::NRF_ERROR_BUSY The stack is busy, process pending events and retry.
+ * @retval ::BLE_ERROR_GAP_INVALID_BLE_ADDR Invalid address type is supplied.
+ * @retval ::NRF_ERROR_INVALID_ADDR The pointer to privacy settings is NULL or invalid.
+ * Otherwise, the p_device_irk pointer in privacy parameter is an invalid pointer.
+ * @retval ::NRF_ERROR_INVALID_PARAM Out of range parameters are provided.
+ * @retval ::NRF_ERROR_INVALID_STATE Privacy settings cannot be changed while advertising.
+ */
+SVCALL(SD_BLE_GAP_PRIVACY_SET, uint32_t, sd_ble_gap_privacy_set(ble_gap_privacy_params_t const *p_privacy_params));
+
+
+/**@brief Get privacy settings.
+ *
+ * @note ::ble_gap_privacy_params_t::p_device_irk must be initialized to NULL or a valid address before this function is called.
+ * If it is initialized to a valid address, the address pointed to will contain the current device IRK on return.
+ *
+ * @param[in,out] p_privacy_params Privacy settings.
+ *
+ * @retval ::NRF_SUCCESS Privacy settings read.
+ * @retval ::NRF_ERROR_INVALID_ADDR The pointer given for returning the privacy settings may be NULL or invalid.
+ * Otherwise, the p_device_irk pointer in privacy parameter is an invalid pointer.
+ */
+SVCALL(SD_BLE_GAP_PRIVACY_GET, uint32_t, sd_ble_gap_privacy_get(ble_gap_privacy_params_t *p_privacy_params));
+
+
+/**@brief Configure an advertising set. Set, clear or update advertising and scan response data.
+ *
+ * @note The format of the advertising data will be checked by this call to ensure interoperability.
+ * Limitations imposed by this API call to the data provided include having a flags data type in the scan response data and
+ * duplicating the local name in the advertising data and scan response data.
+ *
+ * @note In order to update advertising data while advertising, new advertising buffers must be provided.
+ *
+ * @mscs
+ * @mmsc{@ref BLE_GAP_ADV_MSC}
+ * @endmscs
+ *
+ * @param[in,out] p_adv_handle Provide a pointer to a handle containing @ref BLE_GAP_ADV_SET_HANDLE_NOT_SET to configure
+ * a new advertising set. On success, a new handle is then returned through the pointer.
+ * Provide a pointer to an existing advertising handle to configure an existing advertising set.
+ * @param[in] p_adv_data Advertising data. If set to NULL, no advertising data will be used. See @ref ble_gap_adv_data_t.
+ * @param[in] p_adv_params Advertising parameters. When this function is used to update advertising data while advertising,
+ * this parameter must be NULL. See @ref ble_gap_adv_params_t.
+ *
+ * @retval ::NRF_SUCCESS Advertising set successfully configured.
+ * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied:
+ * - Invalid advertising data configuration specified. See @ref ble_gap_adv_data_t.
+ * - Invalid configuration of p_adv_params. See @ref ble_gap_adv_params_t.
+ * - Use of whitelist requested but whitelist has not been set,
+ * see @ref sd_ble_gap_whitelist_set.
+ * @retval ::BLE_ERROR_GAP_INVALID_BLE_ADDR ble_gap_adv_params_t::p_peer_addr is invalid.
+ * @retval ::NRF_ERROR_INVALID_STATE Invalid state to perform operation.
+ * - It is invalid to provide non-NULL advertising set parameters while advertising.
+ * - It is invalid to provide the same data buffers while advertising. To update
+ * advertising data, provide new advertising buffers.
+ * @retval ::BLE_ERROR_GAP_DISCOVERABLE_WITH_WHITELIST Discoverable mode and whitelist incompatible.
+ * @retval ::BLE_ERROR_INVALID_ADV_HANDLE The provided advertising handle was not found. Use @ref BLE_GAP_ADV_SET_HANDLE_NOT_SET to
+ * configure a new advertising handle.
+ * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied.
+ * @retval ::NRF_ERROR_INVALID_FLAGS Invalid combination of advertising flags supplied.
+ * @retval ::NRF_ERROR_INVALID_DATA Invalid data type(s) supplied. Check the advertising data format specification
+ * given in Bluetooth Specification Version 5.0, Volume 3, Part C, Chapter 11.
+ * @retval ::NRF_ERROR_INVALID_LENGTH Invalid data length(s) supplied.
+ * @retval ::NRF_ERROR_NOT_SUPPORTED Unsupported data length or advertising parameter configuration.
+ * @retval ::NRF_ERROR_NO_MEM Not enough memory to configure a new advertising handle. Update an
+ * existing advertising handle instead.
+ * @retval ::BLE_ERROR_GAP_UUID_LIST_MISMATCH Invalid UUID list supplied.
+ */
+SVCALL(SD_BLE_GAP_ADV_SET_CONFIGURE, uint32_t, sd_ble_gap_adv_set_configure(uint8_t *p_adv_handle, ble_gap_adv_data_t const *p_adv_data, ble_gap_adv_params_t const *p_adv_params));
+
+
+/**@brief Start advertising (GAP Discoverable, Connectable modes, Broadcast Procedure).
+ *
+ * @note Only one advertiser may be active at any time.
+ *
+ * @events
+ * @event{@ref BLE_GAP_EVT_CONNECTED, Generated after connection has been established through connectable advertising.}
+ * @event{@ref BLE_GAP_EVT_ADV_SET_TERMINATED, Advertising set has terminated.}
+ * @event{@ref BLE_GAP_EVT_SCAN_REQ_REPORT, A scan request was received.}
+ * @endevents
+ *
+ * @mscs
+ * @mmsc{@ref BLE_GAP_ADV_MSC}
+ * @mmsc{@ref BLE_GAP_PERIPH_CONN_PRIV_MSC}
+ * @mmsc{@ref BLE_GAP_PRIVACY_ADV_DIR_PRIV_MSC}
+ * @endmscs
+ *
+ * @param[in] adv_handle Advertising handle to advertise on, received from @ref sd_ble_gap_adv_set_configure.
+ * @param[in] conn_cfg_tag Tag identifying a configuration set by @ref sd_ble_cfg_set or
+ * @ref BLE_CONN_CFG_TAG_DEFAULT to use the default connection configuration. For non-connectable
+ * advertising, this is ignored.
+ *
+ * @retval ::NRF_SUCCESS The BLE stack has started advertising.
+ * @retval ::NRF_ERROR_INVALID_STATE Invalid state to perform operation. adv_handle is not configured or already advertising.
+ * @retval ::NRF_ERROR_CONN_COUNT The limit of available connections has been reached; connectable advertiser cannot be started.
+ * @retval ::BLE_ERROR_INVALID_ADV_HANDLE Advertising handle not found. Configure a new adveriting handle with @ref sd_ble_gap_adv_set_configure.
+ * @retval ::NRF_ERROR_NOT_FOUND conn_cfg_tag not found.
+ * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied:
+ * - Invalid configuration of p_adv_params. See @ref ble_gap_adv_params_t.
+ * - Use of whitelist requested but whitelist has not been set, see @ref sd_ble_gap_whitelist_set.
+ * @retval ::NRF_ERROR_RESOURCES Either:
+ * - adv_handle is configured with connectable advertising, but the event_length parameter
+ * associated with conn_cfg_tag is too small to be able to establish a connection on
+ * the selected advertising phys. Use @ref sd_ble_cfg_set to increase the event length.
+ * - Not enough BLE role slots available.
+ * Stop one or more currently active roles (Peripheral or Broadcaster) and try again
+ * - p_adv_params is configured with connectable advertising, but the event_length parameter
+ * associated with conn_cfg_tag is too small to be able to establish a connection on
+ * the selected advertising phys. Use @ref sd_ble_cfg_set to increase the event length.
+ * @retval ::NRF_ERROR_NOT_SUPPORTED Unsupported PHYs supplied to the call.
+ */
+SVCALL(SD_BLE_GAP_ADV_START, uint32_t, sd_ble_gap_adv_start(uint8_t adv_handle, uint8_t conn_cfg_tag));
+
+
+/**@brief Stop advertising (GAP Discoverable, Connectable modes, Broadcast Procedure).
+ *
+ * @mscs
+ * @mmsc{@ref BLE_GAP_ADV_MSC}
+ * @endmscs
+ *
+ * @param[in] adv_handle The advertising handle that should stop advertising.
+ *
+ * @retval ::NRF_SUCCESS The BLE stack has stopped advertising.
+ * @retval ::BLE_ERROR_INVALID_ADV_HANDLE Invalid advertising handle.
+ * @retval ::NRF_ERROR_INVALID_STATE The advertising handle is not advertising.
+ */
+SVCALL(SD_BLE_GAP_ADV_STOP, uint32_t, sd_ble_gap_adv_stop(uint8_t adv_handle));
+
+
+
+/**@brief Update connection parameters.
+ *
+ * @details In the peripheral role, this will send the corresponding L2CAP request and wait for
+ * the central to perform the procedure. Regardless of success or failure, the application
+ * will be informed of the result with a @ref BLE_GAP_EVT_CONN_PARAM_UPDATE event.
+ *
+ * @events
+ * @event{@ref BLE_GAP_EVT_CONN_PARAM_UPDATE, Result of the connection parameter update procedure.}
+ * @endevents
+ *
+ * @mscs
+ * @mmsc{@ref BLE_GAP_CPU_MSC}
+ * @endmscs
+ *
+ * @param[in] conn_handle Connection handle.
+ * @param[in] p_conn_params Pointer to desired connection parameters. If NULL is provided on a peripheral role,
+ * the parameters in the PPCP characteristic of the GAP service will be used instead.
+ *
+ * @retval ::NRF_SUCCESS The Connection Update procedure has been started successfully.
+ * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied.
+ * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied, check parameter limits and constraints.
+ * @retval ::NRF_ERROR_INVALID_STATE Invalid state to perform operation.
+ * @retval ::NRF_ERROR_BUSY Procedure already in progress, wait for pending procedures to complete and retry.
+ * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid connection handle supplied.
+ * @retval ::NRF_ERROR_NO_MEM Not enough memory to complete operation.
+ */
+SVCALL(SD_BLE_GAP_CONN_PARAM_UPDATE, uint32_t, sd_ble_gap_conn_param_update(uint16_t conn_handle, ble_gap_conn_params_t const *p_conn_params));
+
+
+/**@brief Disconnect (GAP Link Termination).
+ *
+ * @details This call initiates the disconnection procedure, and its completion will be communicated to the application
+ * with a @ref BLE_GAP_EVT_DISCONNECTED event.
+ *
+ * @events
+ * @event{@ref BLE_GAP_EVT_DISCONNECTED, Generated when disconnection procedure is complete.}
+ * @endevents
+ *
+ * @mscs
+ * @mmsc{@ref BLE_GAP_CONN_MSC}
+ * @endmscs
+ *
+ * @param[in] conn_handle Connection handle.
+ * @param[in] hci_status_code HCI status code, see @ref BLE_HCI_STATUS_CODES (accepted values are @ref BLE_HCI_REMOTE_USER_TERMINATED_CONNECTION and @ref BLE_HCI_CONN_INTERVAL_UNACCEPTABLE).
+ *
+ * @retval ::NRF_SUCCESS The disconnection procedure has been started successfully.
+ * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied.
+ * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid connection handle supplied.
+ * @retval ::NRF_ERROR_INVALID_STATE Invalid state to perform operation (disconnection is already in progress).
+ */
+SVCALL(SD_BLE_GAP_DISCONNECT, uint32_t, sd_ble_gap_disconnect(uint16_t conn_handle, uint8_t hci_status_code));
+
+
+/**@brief Set the radio's transmit power.
+ *
+ * @param[in] role The role to set the transmit power for, see @ref BLE_GAP_TX_POWER_ROLES for
+ * possible roles.
+ * @param[in] handle The handle parameter is interpreted depending on role:
+ * - If role is @ref BLE_GAP_TX_POWER_ROLE_CONN, this value is the specific connection handle.
+ * - If role is @ref BLE_GAP_TX_POWER_ROLE_ADV, the advertising set identified with the advertising handle,
+ * will use the specified transmit power, and include it in the advertising packet headers if
+ * @ref ble_gap_adv_properties_t::include_tx_power set.
+ * - For all other roles handle is ignored.
+ * @param[in] tx_power Radio transmit power in dBm (see note for accepted values).
+ *
+ * @note Supported tx_power values: -40dBm, -20dBm, -16dBm, -12dBm, -8dBm, -4dBm, 0dBm, +3dBm and +4dBm.
+ * @note The initiator will have the same transmit power as the scanner.
+ * @note When a connection is created it will inherit the transmit power from the initiator or
+ * advertiser leading to the connection.
+ *
+ * @retval ::NRF_SUCCESS Successfully changed the transmit power.
+ * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied.
+ * @retval ::BLE_ERROR_INVALID_ADV_HANDLE Advertising handle not found.
+ * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid connection handle supplied.
+ */
+SVCALL(SD_BLE_GAP_TX_POWER_SET, uint32_t, sd_ble_gap_tx_power_set(uint8_t role, uint16_t handle, int8_t tx_power));
+
+
+/**@brief Set GAP Appearance value.
+ *
+ * @param[in] appearance Appearance (16-bit), see @ref BLE_APPEARANCES.
+ *
+ * @retval ::NRF_SUCCESS Appearance value set successfully.
+ * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied.
+ */
+SVCALL(SD_BLE_GAP_APPEARANCE_SET, uint32_t, sd_ble_gap_appearance_set(uint16_t appearance));
+
+
+/**@brief Get GAP Appearance value.
+ *
+ * @param[out] p_appearance Pointer to appearance (16-bit) to be filled in, see @ref BLE_APPEARANCES.
+ *
+ * @retval ::NRF_SUCCESS Appearance value retrieved successfully.
+ * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied.
+ */
+SVCALL(SD_BLE_GAP_APPEARANCE_GET, uint32_t, sd_ble_gap_appearance_get(uint16_t *p_appearance));
+
+
+/**@brief Set GAP Peripheral Preferred Connection Parameters.
+ *
+ * @param[in] p_conn_params Pointer to a @ref ble_gap_conn_params_t structure with the desired parameters.
+ *
+ * @retval ::NRF_SUCCESS Peripheral Preferred Connection Parameters set successfully.
+ * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied.
+ * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied.
+ */
+SVCALL(SD_BLE_GAP_PPCP_SET, uint32_t, sd_ble_gap_ppcp_set(ble_gap_conn_params_t const *p_conn_params));
+
+
+/**@brief Get GAP Peripheral Preferred Connection Parameters.
+ *
+ * @param[out] p_conn_params Pointer to a @ref ble_gap_conn_params_t structure where the parameters will be stored.
+ *
+ * @retval ::NRF_SUCCESS Peripheral Preferred Connection Parameters retrieved successfully.
+ * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied.
+ */
+SVCALL(SD_BLE_GAP_PPCP_GET, uint32_t, sd_ble_gap_ppcp_get(ble_gap_conn_params_t *p_conn_params));
+
+
+/**@brief Set GAP device name.
+ *
+ * @note If the device name is located in application flash memory (see @ref ble_gap_cfg_device_name_t),
+ * it cannot be changed. Then @ref NRF_ERROR_FORBIDDEN will be returned.
+ *
+ * @param[in] p_write_perm Write permissions for the Device Name characteristic, see @ref ble_gap_conn_sec_mode_t.
+ * @param[in] p_dev_name Pointer to a UTF-8 encoded, <b>non NULL-terminated</b> string.
+ * @param[in] len Length of the UTF-8, <b>non NULL-terminated</b> string pointed to by p_dev_name in octets (must be smaller or equal than @ref BLE_GAP_DEVNAME_MAX_LEN).
+ *
+ * @retval ::NRF_SUCCESS GAP device name and permissions set successfully.
+ * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied.
+ * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied.
+ * @retval ::NRF_ERROR_DATA_SIZE Invalid data size(s) supplied.
+ * @retval ::NRF_ERROR_FORBIDDEN Device name is not writable.
+ */
+SVCALL(SD_BLE_GAP_DEVICE_NAME_SET, uint32_t, sd_ble_gap_device_name_set(ble_gap_conn_sec_mode_t const *p_write_perm, uint8_t const *p_dev_name, uint16_t len));
+
+
+/**@brief Get GAP device name.
+ *
+ * @note If the device name is longer than the size of the supplied buffer,
+ * p_len will return the complete device name length,
+ * and not the number of bytes actually returned in p_dev_name.
+ * The application may use this information to allocate a suitable buffer size.
+ *
+ * @param[out] p_dev_name Pointer to an empty buffer where the UTF-8 <b>non NULL-terminated</b> string will be placed. Set to NULL to obtain the complete device name length.
+ * @param[in,out] p_len Length of the buffer pointed by p_dev_name, complete device name length on output.
+ *
+ * @retval ::NRF_SUCCESS GAP device name retrieved successfully.
+ * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied.
+ * @retval ::NRF_ERROR_DATA_SIZE Invalid data size(s) supplied.
+ */
+SVCALL(SD_BLE_GAP_DEVICE_NAME_GET, uint32_t, sd_ble_gap_device_name_get(uint8_t *p_dev_name, uint16_t *p_len));
+
+
+/**@brief Initiate the GAP Authentication procedure.
+ *
+ * @details In the peripheral role, this function will send an SMP Security Request.
+ *
+ * @events
+ * @event{Depending on the security parameters set and the packet exchanges with the peer\, the following events may be generated:}
+ * @event{@ref BLE_GAP_EVT_SEC_PARAMS_REQUEST}
+ * @event{@ref BLE_GAP_EVT_SEC_INFO_REQUEST}
+ * @event{@ref BLE_GAP_EVT_PASSKEY_DISPLAY}
+ * @event{@ref BLE_GAP_EVT_KEY_PRESSED}
+ * @event{@ref BLE_GAP_EVT_AUTH_KEY_REQUEST}
+ * @event{@ref BLE_GAP_EVT_LESC_DHKEY_REQUEST}
+ * @event{@ref BLE_GAP_EVT_CONN_SEC_UPDATE}
+ * @event{@ref BLE_GAP_EVT_AUTH_STATUS}
+ * @event{@ref BLE_GAP_EVT_TIMEOUT}
+ * @endevents
+ *
+ * @mscs
+ * @mmsc{@ref BLE_GAP_PERIPH_SEC_REQ_MSC}
+ * @endmscs
+ *
+ * @param[in] conn_handle Connection handle.
+ * @param[in] p_sec_params Pointer to the @ref ble_gap_sec_params_t structure with the security parameters to be used during the pairing or bonding procedure.
+ * In the peripheral role, only the bond, mitm, lesc and keypress fields of this structure are used.
+ *
+ * @retval ::NRF_SUCCESS Successfully initiated authentication procedure.
+ * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied.
+ * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied.
+ * @retval ::NRF_ERROR_INVALID_STATE Invalid state to perform operation.
+ * @retval ::NRF_ERROR_NO_MEM The maximum number of authentication procedures that can run in parallel for the given role is reached.
+ * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid connection handle supplied.
+ */
+SVCALL(SD_BLE_GAP_AUTHENTICATE, uint32_t, sd_ble_gap_authenticate(uint16_t conn_handle, ble_gap_sec_params_t const *p_sec_params));
+
+
+/**@brief Reply with GAP security parameters.
+ *
+ * @details This function is only used to reply to a @ref BLE_GAP_EVT_SEC_PARAMS_REQUEST, calling it at other times will result in an @ref NRF_ERROR_INVALID_STATE.
+ * @note If the call returns an error code, the request is still pending, and the reply call may be repeated with corrected parameters.
+ *
+ * @events
+ * @event{This function is used during authentication procedures\, see the list of events in the documentation of @ref sd_ble_gap_authenticate.}
+ * @endevents
+ *
+ * @mscs
+ * @mmsc{@ref BLE_GAP_PERIPH_PAIRING_JW_MSC}
+ * @mmsc{@ref BLE_GAP_PERIPH_BONDING_JW_MSC}
+ * @mmsc{@ref BLE_GAP_PERIPH_BONDING_PK_PERIPH_MSC}
+ * @mmsc{@ref BLE_GAP_PERIPH_BONDING_PK_CENTRAL_OOB_MSC}
+ * @mmsc{@ref BLE_GAP_PERIPH_BONDING_STATIC_PK_MSC}
+ * @mmsc{@ref BLE_GAP_PERIPH_PAIRING_CONFIRM_FAIL_MSC}
+ * @mmsc{@ref BLE_GAP_PERIPH_LESC_PAIRING_JW_MSC}
+ * @mmsc{@ref BLE_GAP_PERIPH_LESC_BONDING_NC_MSC}
+ * @mmsc{@ref BLE_GAP_PERIPH_LESC_BONDING_PKE_PD_MSC}
+ * @mmsc{@ref BLE_GAP_PERIPH_LESC_BONDING_PKE_CD_MSC}
+ * @mmsc{@ref BLE_GAP_PERIPH_LESC_BONDING_OOB_MSC}
+ * @mmsc{@ref BLE_GAP_PERIPH_PAIRING_KS_TOO_SMALL_MSC}
+ * @mmsc{@ref BLE_GAP_PERIPH_PAIRING_APP_ERROR_MSC}
+ * @mmsc{@ref BLE_GAP_PERIPH_PAIRING_REMOTE_PAIRING_FAIL_MSC}
+ * @mmsc{@ref BLE_GAP_PERIPH_PAIRING_TIMEOUT_MSC}
+ * @endmscs
+ *
+ * @param[in] conn_handle Connection handle.
+ * @param[in] sec_status Security status, see @ref BLE_GAP_SEC_STATUS.
+ * @param[in] p_sec_params Pointer to a @ref ble_gap_sec_params_t security parameters structure.
+ * @param[in,out] p_sec_keyset Pointer to a @ref ble_gap_sec_keyset_t security keyset structure. Any keys generated and/or distributed as a result of the ongoing security procedure
+ * will be stored into the memory referenced by the pointers inside this structure. The keys will be stored and available to the application
+ * upon reception of a @ref BLE_GAP_EVT_AUTH_STATUS event.
+ * Note that the SoftDevice expects the application to provide memory for storing the
+ * peer's keys. So it must be ensured that the relevant pointers inside this structure are not NULL. The pointers to the local key
+ * can, however, be NULL, in which case, the local key data will not be available to the application upon reception of the
+ * @ref BLE_GAP_EVT_AUTH_STATUS event.
+ *
+ * @retval ::NRF_SUCCESS Successfully accepted security parameter from the application.
+ * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied.
+ * @retval ::NRF_ERROR_BUSY The stack is busy, process pending events and retry.
+ * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied.
+ * @retval ::NRF_ERROR_INVALID_STATE Invalid state to perform operation.
+ * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid connection handle supplied.
+ * @retval ::NRF_ERROR_NOT_SUPPORTED Setting of sign or link fields in @ref ble_gap_sec_kdist_t not supported.
+ */
+SVCALL(SD_BLE_GAP_SEC_PARAMS_REPLY, uint32_t, sd_ble_gap_sec_params_reply(uint16_t conn_handle, uint8_t sec_status, ble_gap_sec_params_t const *p_sec_params, ble_gap_sec_keyset_t const *p_sec_keyset));
+
+
+/**@brief Reply with an authentication key.
+ *
+ * @details This function is only used to reply to a @ref BLE_GAP_EVT_AUTH_KEY_REQUEST or a @ref BLE_GAP_EVT_PASSKEY_DISPLAY, calling it at other times will result in an @ref NRF_ERROR_INVALID_STATE.
+ * @note If the call returns an error code, the request is still pending, and the reply call may be repeated with corrected parameters.
+ *
+ * @events
+ * @event{This function is used during authentication procedures\, see the list of events in the documentation of @ref sd_ble_gap_authenticate.}
+ * @endevents
+ *
+ * @mscs
+ * @mmsc{@ref BLE_GAP_PERIPH_BONDING_PK_CENTRAL_OOB_MSC}
+ * @mmsc{@ref BLE_GAP_PERIPH_LESC_BONDING_NC_MSC}
+ * @mmsc{@ref BLE_GAP_PERIPH_LESC_BONDING_PKE_CD_MSC}
+ * @endmscs
+ *
+ * @param[in] conn_handle Connection handle.
+ * @param[in] key_type See @ref BLE_GAP_AUTH_KEY_TYPES.
+ * @param[in] p_key If key type is @ref BLE_GAP_AUTH_KEY_TYPE_NONE, then NULL.
+ * If key type is @ref BLE_GAP_AUTH_KEY_TYPE_PASSKEY, then a 6-byte ASCII string (digit 0..9 only, no NULL termination)
+ * or NULL when confirming LE Secure Connections Numeric Comparison.
+ * If key type is @ref BLE_GAP_AUTH_KEY_TYPE_OOB, then a 16-byte OOB key value in little-endian format.
+ *
+ * @retval ::NRF_SUCCESS Authentication key successfully set.
+ * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied.
+ * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied.
+ * @retval ::NRF_ERROR_INVALID_STATE Invalid state to perform operation.
+ * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid connection handle supplied.
+ */
+SVCALL(SD_BLE_GAP_AUTH_KEY_REPLY, uint32_t, sd_ble_gap_auth_key_reply(uint16_t conn_handle, uint8_t key_type, uint8_t const *p_key));
+
+
+/**@brief Reply with an LE Secure connections DHKey.
+ *
+ * @details This function is only used to reply to a @ref BLE_GAP_EVT_LESC_DHKEY_REQUEST, calling it at other times will result in an @ref NRF_ERROR_INVALID_STATE.
+ * @note If the call returns an error code, the request is still pending, and the reply call may be repeated with corrected parameters.
+ *
+ * @events
+ * @event{This function is used during authentication procedures\, see the list of events in the documentation of @ref sd_ble_gap_authenticate.}
+ * @endevents
+ *
+ * @mscs
+ * @mmsc{@ref BLE_GAP_PERIPH_LESC_PAIRING_JW_MSC}
+ * @mmsc{@ref BLE_GAP_PERIPH_LESC_BONDING_NC_MSC}
+ * @mmsc{@ref BLE_GAP_PERIPH_LESC_BONDING_PKE_PD_MSC}
+ * @mmsc{@ref BLE_GAP_PERIPH_LESC_BONDING_PKE_CD_MSC}
+ * @mmsc{@ref BLE_GAP_PERIPH_LESC_BONDING_OOB_MSC}
+ * @endmscs
+ *
+ * @param[in] conn_handle Connection handle.
+ * @param[in] p_dhkey LE Secure Connections DHKey.
+ *
+ * @retval ::NRF_SUCCESS DHKey successfully set.
+ * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied.
+ * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied.
+ * @retval ::NRF_ERROR_INVALID_STATE Invalid state to perform operation.
+ * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid connection handle supplied.
+ */
+SVCALL(SD_BLE_GAP_LESC_DHKEY_REPLY, uint32_t, sd_ble_gap_lesc_dhkey_reply(uint16_t conn_handle, ble_gap_lesc_dhkey_t const *p_dhkey));
+
+
+/**@brief Notify the peer of a local keypress.
+ *
+ * @mscs
+ * @mmsc{@ref BLE_GAP_PERIPH_LESC_BONDING_PKE_CD_MSC}
+ * @endmscs
+ *
+ * @param[in] conn_handle Connection handle.
+ * @param[in] kp_not See @ref BLE_GAP_KP_NOT_TYPES.
+ *
+ * @retval ::NRF_SUCCESS Keypress notification successfully queued for transmission.
+ * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied.
+ * @retval ::NRF_ERROR_INVALID_STATE Invalid state to perform operation. Either not entering a passkey or keypresses have not been enabled by both peers.
+ * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid connection handle supplied.
+ * @retval ::NRF_ERROR_BUSY The BLE stack is busy. Retry at later time.
+ */
+SVCALL(SD_BLE_GAP_KEYPRESS_NOTIFY, uint32_t, sd_ble_gap_keypress_notify(uint16_t conn_handle, uint8_t kp_not));
+
+
+/**@brief Generate a set of OOB data to send to a peer out of band.
+ *
+ * @note The @ref ble_gap_addr_t included in the OOB data returned will be the currently active one (or, if a connection has already been established,
+ * the one used during connection setup). The application may manually overwrite it with an updated value.
+ *
+ * @mscs
+ * @mmsc{@ref BLE_GAP_PERIPH_LESC_BONDING_OOB_MSC}
+ * @endmscs
+ *
+ * @param[in] conn_handle Connection handle. Can be @ref BLE_CONN_HANDLE_INVALID if a BLE connection has not been established yet.
+ * @param[in] p_pk_own LE Secure Connections local P-256 Public Key.
+ * @param[out] p_oobd_own The OOB data to be sent out of band to a peer.
+ *
+ * @retval ::NRF_SUCCESS OOB data successfully generated.
+ * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied.
+ * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid connection handle supplied.
+ */
+SVCALL(SD_BLE_GAP_LESC_OOB_DATA_GET, uint32_t, sd_ble_gap_lesc_oob_data_get(uint16_t conn_handle, ble_gap_lesc_p256_pk_t const *p_pk_own, ble_gap_lesc_oob_data_t *p_oobd_own));
+
+/**@brief Provide the OOB data sent/received out of band.
+ *
+ * @note An authentication procedure with OOB selected as an algorithm must be in progress when calling this function.
+ * @note A @ref BLE_GAP_EVT_LESC_DHKEY_REQUEST event with the oobd_req set to 1 must have been received prior to calling this function.
+ *
+ * @events
+ * @event{This function is used during authentication procedures\, see the list of events in the documentation of @ref sd_ble_gap_authenticate.}
+ * @endevents
+ *
+ * @mscs
+ * @mmsc{@ref BLE_GAP_PERIPH_LESC_BONDING_OOB_MSC}
+ * @endmscs
+ *
+ * @param[in] conn_handle Connection handle.
+ * @param[in] p_oobd_own The OOB data sent out of band to a peer or NULL if the peer has not received OOB data.
+ * Must correspond to @ref ble_gap_sec_params_t::oob flag in @ref BLE_GAP_EVT_SEC_PARAMS_REQUEST.
+ * @param[in] p_oobd_peer The OOB data received out of band from a peer or NULL if none received.
+ * Must correspond to @ref sd_ble_gap_sec_params_reply in the peripheral role.
+ *
+ * @retval ::NRF_SUCCESS OOB data accepted.
+ * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied.
+ * @retval ::NRF_ERROR_INVALID_STATE Invalid state to perform operation.
+ * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid connection handle supplied.
+ */
+SVCALL(SD_BLE_GAP_LESC_OOB_DATA_SET, uint32_t, sd_ble_gap_lesc_oob_data_set(uint16_t conn_handle, ble_gap_lesc_oob_data_t const *p_oobd_own, ble_gap_lesc_oob_data_t const *p_oobd_peer));
+
+
+/**@brief Reply with GAP security information.
+ *
+ * @details This function is only used to reply to a @ref BLE_GAP_EVT_SEC_INFO_REQUEST, calling it at other times will result in @ref NRF_ERROR_INVALID_STATE.
+ * @note If the call returns an error code, the request is still pending, and the reply call may be repeated with corrected parameters.
+ * @note Data signing is not yet supported, and p_sign_info must therefore be NULL.
+ *
+ * @mscs
+ * @mmsc{@ref BLE_GAP_PERIPH_ENC_MSC}
+ * @endmscs
+ *
+ * @param[in] conn_handle Connection handle.
+ * @param[in] p_enc_info Pointer to a @ref ble_gap_enc_info_t encryption information structure. May be NULL to signal none is available.
+ * @param[in] p_id_info Pointer to a @ref ble_gap_irk_t identity information structure. May be NULL to signal none is available.
+ * @param[in] p_sign_info Pointer to a @ref ble_gap_sign_info_t signing information structure. May be NULL to signal none is available.
+ *
+ * @retval ::NRF_SUCCESS Successfully accepted security information.
+ * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied.
+ * @retval ::NRF_ERROR_INVALID_STATE Invalid state to perform operation.
+ * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid connection handle supplied.
+ */
+SVCALL(SD_BLE_GAP_SEC_INFO_REPLY, uint32_t, sd_ble_gap_sec_info_reply(uint16_t conn_handle, ble_gap_enc_info_t const *p_enc_info, ble_gap_irk_t const *p_id_info, ble_gap_sign_info_t const *p_sign_info));
+
+
+/**@brief Get the current connection security.
+ *
+ * @param[in] conn_handle Connection handle.
+ * @param[out] p_conn_sec Pointer to a @ref ble_gap_conn_sec_t structure to be filled in.
+ *
+ * @retval ::NRF_SUCCESS Current connection security successfully retrieved.
+ * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied.
+ * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid connection handle supplied.
+ */
+SVCALL(SD_BLE_GAP_CONN_SEC_GET, uint32_t, sd_ble_gap_conn_sec_get(uint16_t conn_handle, ble_gap_conn_sec_t *p_conn_sec));
+
+
+/**@brief Start reporting the received signal strength to the application.
+ *
+ * A new event is reported whenever the RSSI value changes, until @ref sd_ble_gap_rssi_stop is called.
+ *
+ * @events
+ * @event{@ref BLE_GAP_EVT_RSSI_CHANGED, New RSSI data available. How often the event is generated is
+ * dependent on the settings of the <code>threshold_dbm</code>
+ * and <code>skip_count</code> input parameters.}
+ * @endevents
+ *
+ * @mscs
+ * @mmsc{@ref BLE_GAP_CENTRAL_RSSI_READ_MSC}
+ * @mmsc{@ref BLE_GAP_RSSI_FILT_MSC}
+ * @endmscs
+ *
+ * @param[in] conn_handle Connection handle.
+ * @param[in] threshold_dbm Minimum change in dBm before triggering the @ref BLE_GAP_EVT_RSSI_CHANGED event. Events are disabled if threshold_dbm equals @ref BLE_GAP_RSSI_THRESHOLD_INVALID.
+ * @param[in] skip_count Number of RSSI samples with a change of threshold_dbm or more before sending a new @ref BLE_GAP_EVT_RSSI_CHANGED event.
+ *
+ * @retval ::NRF_SUCCESS Successfully activated RSSI reporting.
+ * @retval ::NRF_ERROR_INVALID_STATE RSSI reporting is already ongoing.
+ * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid connection handle supplied.
+ */
+SVCALL(SD_BLE_GAP_RSSI_START, uint32_t, sd_ble_gap_rssi_start(uint16_t conn_handle, uint8_t threshold_dbm, uint8_t skip_count));
+
+
+/**@brief Stop reporting the received signal strength.
+ *
+ * @note An RSSI change detected before the call but not yet received by the application
+ * may be reported after @ref sd_ble_gap_rssi_stop has been called.
+ *
+ * @mscs
+ * @mmsc{@ref BLE_GAP_CENTRAL_RSSI_READ_MSC}
+ * @mmsc{@ref BLE_GAP_RSSI_FILT_MSC}
+ * @endmscs
+ *
+ * @param[in] conn_handle Connection handle.
+ *
+ * @retval ::NRF_SUCCESS Successfully deactivated RSSI reporting.
+ * @retval ::NRF_ERROR_INVALID_STATE RSSI reporting is not ongoing.
+ * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid connection handle supplied.
+ */
+SVCALL(SD_BLE_GAP_RSSI_STOP, uint32_t, sd_ble_gap_rssi_stop(uint16_t conn_handle));
+
+
+/**@brief Get the received signal strength for the last connection event.
+ *
+ * @ref sd_ble_gap_rssi_start must be called to start reporting RSSI before using this function. @ref NRF_ERROR_NOT_FOUND
+ * will be returned until RSSI was sampled for the first time after calling @ref sd_ble_gap_rssi_start.
+ * @mscs
+ * @mmsc{@ref BLE_GAP_CENTRAL_RSSI_READ_MSC}
+ * @endmscs
+ *
+ * @param[in] conn_handle Connection handle.
+ * @param[out] p_rssi Pointer to the location where the RSSI measurement shall be stored.
+ * @param[out] p_ch_index Pointer to the location where Channel Index for the RSSI measurement shall be stored.
+ *
+ * @retval ::NRF_SUCCESS Successfully read the RSSI.
+ * @retval ::NRF_ERROR_NOT_FOUND No sample is available.
+ * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied.
+ * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid connection handle supplied.
+ * @retval ::NRF_ERROR_INVALID_STATE RSSI reporting is not ongoing.
+ */
+SVCALL(SD_BLE_GAP_RSSI_GET, uint32_t, sd_ble_gap_rssi_get(uint16_t conn_handle, int8_t *p_rssi, uint8_t *p_ch_index));
+
+
+/**@brief Initiate or respond to a PHY Update Procedure
+ *
+ * @details This function is used to initiate or respond to a PHY Update Procedure. It will always
+ * generate a @ref BLE_GAP_EVT_PHY_UPDATE event if successfully executed.
+ * If this function is used to initiate a PHY Update procedure and the only option
+ * provided in @ref ble_gap_phys_t::tx_phys and @ref ble_gap_phys_t::rx_phys is the
+ * currently active PHYs in the respective directions, the SoftDevice will generate a
+ * @ref BLE_GAP_EVT_PHY_UPDATE with the current PHYs set and will not initiate the
+ * procedure in the Link Layer.
+ *
+ * If @ref ble_gap_phys_t::tx_phys or @ref ble_gap_phys_t::rx_phys is @ref BLE_GAP_PHY_AUTO,
+ * then the stack will select PHYs based on the peer's PHY preferences and the local link
+ * configuration. The PHY Update procedure will for this case result in a PHY combination
+ * that respects the time constraints configured with @ref sd_ble_cfg_set and the current
+ * link layer data length.
+ *
+ * If the peer does not support the PHY Update Procedure, then the resulting
+ * @ref BLE_GAP_EVT_PHY_UPDATE event will have a status set to
+ * @ref BLE_HCI_UNSUPPORTED_REMOTE_FEATURE.
+ *
+ * If the PHY procedure was rejected by the peer due to a procedure collision, the status
+ * will be @ref BLE_HCI_STATUS_CODE_LMP_ERROR_TRANSACTION_COLLISION or
+ * @ref BLE_HCI_DIFFERENT_TRANSACTION_COLLISION.
+ * If the peer responds to the PHY Update procedure with invalid parameters, the status
+ * will be @ref BLE_HCI_STATUS_CODE_INVALID_LMP_PARAMETERS.
+ * If the PHY procedure was rejected by the peer for a different reason, the status will
+ * contain the reason as specified by the peer.
+ *
+ * @events
+ * @event{@ref BLE_GAP_EVT_PHY_UPDATE, Result of the PHY Update Procedure.}
+ * @endevents
+ *
+ * @mscs
+ * @mmsc{@ref BLE_GAP_PERIPHERAL_PHY_UPDATE}
+ * @endmscs
+ *
+ * @param[in] conn_handle Connection handle to indicate the connection for which the PHY Update is requested.
+ * @param[in] p_gap_phys Pointer to PHY structure.
+ *
+ * @retval ::NRF_SUCCESS Successfully requested a PHY Update.
+ * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied.
+ * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid connection handle supplied.
+ * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied.
+ * @retval ::NRF_ERROR_NOT_SUPPORTED Unsupported PHYs supplied to the call.
+ * @retval ::NRF_ERROR_INVALID_STATE Invalid state to perform operation.
+ * @retval ::NRF_ERROR_BUSY Procedure is already in progress or not allowed at this time. Process pending events and wait for the pending procedure to complete and retry.
+ *
+ */
+SVCALL(SD_BLE_GAP_PHY_UPDATE, uint32_t, sd_ble_gap_phy_update(uint16_t conn_handle, ble_gap_phys_t const *p_gap_phys));
+
+
+
+/** @} */
+
+#ifdef __cplusplus
+}
+#endif
+#endif // BLE_GAP_H__
+
+/**
+ @}
+*/
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/softdevice/s112/headers/ble_gatt.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/softdevice/s112/headers/ble_gatt.h
new file mode 100644
index 0000000..98a7a15
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/softdevice/s112/headers/ble_gatt.h
@@ -0,0 +1,228 @@
+/*
+ * Copyright (c) 2013 - 2017, 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ */
+
+/**
+ @addtogroup BLE_GATT Generic Attribute Profile (GATT) Common
+ @{
+ @brief Common definitions and prototypes for the GATT interfaces.
+ */
+
+#ifndef BLE_GATT_H__
+#define BLE_GATT_H__
+
+#include <stdint.h>
+#include "nrf_svc.h"
+#include "nrf_error.h"
+#include "ble_hci.h"
+#include "ble_ranges.h"
+#include "ble_types.h"
+#include "ble_err.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** @addtogroup BLE_GATT_DEFINES Defines
+ * @{ */
+
+/** @brief Default ATT MTU, in bytes. */
+#define BLE_GATT_ATT_MTU_DEFAULT 23
+
+/**@brief Invalid Attribute Handle. */
+#define BLE_GATT_HANDLE_INVALID 0x0000
+
+/**@brief First Attribute Handle. */
+#define BLE_GATT_HANDLE_START 0x0001
+
+/**@brief Last Attribute Handle. */
+#define BLE_GATT_HANDLE_END 0xFFFF
+
+/** @defgroup BLE_GATT_TIMEOUT_SOURCES GATT Timeout sources
+ * @{ */
+#define BLE_GATT_TIMEOUT_SRC_PROTOCOL 0x00 /**< ATT Protocol timeout. */
+/** @} */
+
+/** @defgroup BLE_GATT_WRITE_OPS GATT Write operations
+ * @{ */
+#define BLE_GATT_OP_INVALID 0x00 /**< Invalid Operation. */
+#define BLE_GATT_OP_WRITE_REQ 0x01 /**< Write Request. */
+#define BLE_GATT_OP_WRITE_CMD 0x02 /**< Write Command. */
+#define BLE_GATT_OP_SIGN_WRITE_CMD 0x03 /**< Signed Write Command. */
+#define BLE_GATT_OP_PREP_WRITE_REQ 0x04 /**< Prepare Write Request. */
+#define BLE_GATT_OP_EXEC_WRITE_REQ 0x05 /**< Execute Write Request. */
+/** @} */
+
+/** @defgroup BLE_GATT_EXEC_WRITE_FLAGS GATT Execute Write flags
+ * @{ */
+#define BLE_GATT_EXEC_WRITE_FLAG_PREPARED_CANCEL 0x00 /**< Cancel prepared write. */
+#define BLE_GATT_EXEC_WRITE_FLAG_PREPARED_WRITE 0x01 /**< Execute prepared write. */
+/** @} */
+
+/** @defgroup BLE_GATT_HVX_TYPES GATT Handle Value operations
+ * @{ */
+#define BLE_GATT_HVX_INVALID 0x00 /**< Invalid Operation. */
+#define BLE_GATT_HVX_NOTIFICATION 0x01 /**< Handle Value Notification. */
+#define BLE_GATT_HVX_INDICATION 0x02 /**< Handle Value Indication. */
+/** @} */
+
+/** @defgroup BLE_GATT_STATUS_CODES GATT Status Codes
+ * @{ */
+#define BLE_GATT_STATUS_SUCCESS 0x0000 /**< Success. */
+#define BLE_GATT_STATUS_UNKNOWN 0x0001 /**< Unknown or not applicable status. */
+#define BLE_GATT_STATUS_ATTERR_INVALID 0x0100 /**< ATT Error: Invalid Error Code. */
+#define BLE_GATT_STATUS_ATTERR_INVALID_HANDLE 0x0101 /**< ATT Error: Invalid Attribute Handle. */
+#define BLE_GATT_STATUS_ATTERR_READ_NOT_PERMITTED 0x0102 /**< ATT Error: Read not permitted. */
+#define BLE_GATT_STATUS_ATTERR_WRITE_NOT_PERMITTED 0x0103 /**< ATT Error: Write not permitted. */
+#define BLE_GATT_STATUS_ATTERR_INVALID_PDU 0x0104 /**< ATT Error: Used in ATT as Invalid PDU. */
+#define BLE_GATT_STATUS_ATTERR_INSUF_AUTHENTICATION 0x0105 /**< ATT Error: Authenticated link required. */
+#define BLE_GATT_STATUS_ATTERR_REQUEST_NOT_SUPPORTED 0x0106 /**< ATT Error: Used in ATT as Request Not Supported. */
+#define BLE_GATT_STATUS_ATTERR_INVALID_OFFSET 0x0107 /**< ATT Error: Offset specified was past the end of the attribute. */
+#define BLE_GATT_STATUS_ATTERR_INSUF_AUTHORIZATION 0x0108 /**< ATT Error: Used in ATT as Insufficient Authorization. */
+#define BLE_GATT_STATUS_ATTERR_PREPARE_QUEUE_FULL 0x0109 /**< ATT Error: Used in ATT as Prepare Queue Full. */
+#define BLE_GATT_STATUS_ATTERR_ATTRIBUTE_NOT_FOUND 0x010A /**< ATT Error: Used in ATT as Attribute not found. */
+#define BLE_GATT_STATUS_ATTERR_ATTRIBUTE_NOT_LONG 0x010B /**< ATT Error: Attribute cannot be read or written using read/write blob requests. */
+#define BLE_GATT_STATUS_ATTERR_INSUF_ENC_KEY_SIZE 0x010C /**< ATT Error: Encryption key size used is insufficient. */
+#define BLE_GATT_STATUS_ATTERR_INVALID_ATT_VAL_LENGTH 0x010D /**< ATT Error: Invalid value size. */
+#define BLE_GATT_STATUS_ATTERR_UNLIKELY_ERROR 0x010E /**< ATT Error: Very unlikely error. */
+#define BLE_GATT_STATUS_ATTERR_INSUF_ENCRYPTION 0x010F /**< ATT Error: Encrypted link required. */
+#define BLE_GATT_STATUS_ATTERR_UNSUPPORTED_GROUP_TYPE 0x0110 /**< ATT Error: Attribute type is not a supported grouping attribute. */
+#define BLE_GATT_STATUS_ATTERR_INSUF_RESOURCES 0x0111 /**< ATT Error: Encrypted link required. */
+#define BLE_GATT_STATUS_ATTERR_RFU_RANGE1_BEGIN 0x0112 /**< ATT Error: Reserved for Future Use range #1 begin. */
+#define BLE_GATT_STATUS_ATTERR_RFU_RANGE1_END 0x017F /**< ATT Error: Reserved for Future Use range #1 end. */
+#define BLE_GATT_STATUS_ATTERR_APP_BEGIN 0x0180 /**< ATT Error: Application range begin. */
+#define BLE_GATT_STATUS_ATTERR_APP_END 0x019F /**< ATT Error: Application range end. */
+#define BLE_GATT_STATUS_ATTERR_RFU_RANGE2_BEGIN 0x01A0 /**< ATT Error: Reserved for Future Use range #2 begin. */
+#define BLE_GATT_STATUS_ATTERR_RFU_RANGE2_END 0x01DF /**< ATT Error: Reserved for Future Use range #2 end. */
+#define BLE_GATT_STATUS_ATTERR_RFU_RANGE3_BEGIN 0x01E0 /**< ATT Error: Reserved for Future Use range #3 begin. */
+#define BLE_GATT_STATUS_ATTERR_RFU_RANGE3_END 0x01FC /**< ATT Error: Reserved for Future Use range #3 end. */
+#define BLE_GATT_STATUS_ATTERR_CPS_CCCD_CONFIG_ERROR 0x01FD /**< ATT Common Profile and Service Error: Client Characteristic Configuration Descriptor improperly configured. */
+#define BLE_GATT_STATUS_ATTERR_CPS_PROC_ALR_IN_PROG 0x01FE /**< ATT Common Profile and Service Error: Procedure Already in Progress. */
+#define BLE_GATT_STATUS_ATTERR_CPS_OUT_OF_RANGE 0x01FF /**< ATT Common Profile and Service Error: Out Of Range. */
+/** @} */
+
+
+/** @defgroup BLE_GATT_CPF_FORMATS Characteristic Presentation Formats
+ * @note Found at http://developer.bluetooth.org/gatt/descriptors/Pages/DescriptorViewer.aspx?u=org.bluetooth.descriptor.gatt.characteristic_presentation_format.xml
+ * @{ */
+#define BLE_GATT_CPF_FORMAT_RFU 0x00 /**< Reserved For Future Use. */
+#define BLE_GATT_CPF_FORMAT_BOOLEAN 0x01 /**< Boolean. */
+#define BLE_GATT_CPF_FORMAT_2BIT 0x02 /**< Unsigned 2-bit integer. */
+#define BLE_GATT_CPF_FORMAT_NIBBLE 0x03 /**< Unsigned 4-bit integer. */
+#define BLE_GATT_CPF_FORMAT_UINT8 0x04 /**< Unsigned 8-bit integer. */
+#define BLE_GATT_CPF_FORMAT_UINT12 0x05 /**< Unsigned 12-bit integer. */
+#define BLE_GATT_CPF_FORMAT_UINT16 0x06 /**< Unsigned 16-bit integer. */
+#define BLE_GATT_CPF_FORMAT_UINT24 0x07 /**< Unsigned 24-bit integer. */
+#define BLE_GATT_CPF_FORMAT_UINT32 0x08 /**< Unsigned 32-bit integer. */
+#define BLE_GATT_CPF_FORMAT_UINT48 0x09 /**< Unsigned 48-bit integer. */
+#define BLE_GATT_CPF_FORMAT_UINT64 0x0A /**< Unsigned 64-bit integer. */
+#define BLE_GATT_CPF_FORMAT_UINT128 0x0B /**< Unsigned 128-bit integer. */
+#define BLE_GATT_CPF_FORMAT_SINT8 0x0C /**< Signed 2-bit integer. */
+#define BLE_GATT_CPF_FORMAT_SINT12 0x0D /**< Signed 12-bit integer. */
+#define BLE_GATT_CPF_FORMAT_SINT16 0x0E /**< Signed 16-bit integer. */
+#define BLE_GATT_CPF_FORMAT_SINT24 0x0F /**< Signed 24-bit integer. */
+#define BLE_GATT_CPF_FORMAT_SINT32 0x10 /**< Signed 32-bit integer. */
+#define BLE_GATT_CPF_FORMAT_SINT48 0x11 /**< Signed 48-bit integer. */
+#define BLE_GATT_CPF_FORMAT_SINT64 0x12 /**< Signed 64-bit integer. */
+#define BLE_GATT_CPF_FORMAT_SINT128 0x13 /**< Signed 128-bit integer. */
+#define BLE_GATT_CPF_FORMAT_FLOAT32 0x14 /**< IEEE-754 32-bit floating point. */
+#define BLE_GATT_CPF_FORMAT_FLOAT64 0x15 /**< IEEE-754 64-bit floating point. */
+#define BLE_GATT_CPF_FORMAT_SFLOAT 0x16 /**< IEEE-11073 16-bit SFLOAT. */
+#define BLE_GATT_CPF_FORMAT_FLOAT 0x17 /**< IEEE-11073 32-bit FLOAT. */
+#define BLE_GATT_CPF_FORMAT_DUINT16 0x18 /**< IEEE-20601 format. */
+#define BLE_GATT_CPF_FORMAT_UTF8S 0x19 /**< UTF-8 string. */
+#define BLE_GATT_CPF_FORMAT_UTF16S 0x1A /**< UTF-16 string. */
+#define BLE_GATT_CPF_FORMAT_STRUCT 0x1B /**< Opaque Structure. */
+/** @} */
+
+/** @defgroup BLE_GATT_CPF_NAMESPACES GATT Bluetooth Namespaces
+ * @{
+ */
+#define BLE_GATT_CPF_NAMESPACE_BTSIG 0x01 /**< Bluetooth SIG defined Namespace. */
+#define BLE_GATT_CPF_NAMESPACE_DESCRIPTION_UNKNOWN 0x0000 /**< Namespace Description Unknown. */
+/** @} */
+
+/** @} */
+
+/** @addtogroup BLE_GATT_STRUCTURES Structures
+ * @{ */
+
+/**
+ * @brief BLE GATT connection configuration parameters, set with @ref sd_ble_cfg_set.
+ *
+ * @retval ::NRF_ERROR_INVALID_PARAM att_mtu is smaller than @ref BLE_GATT_ATT_MTU_DEFAULT.
+ */
+typedef struct
+{
+ uint16_t att_mtu; /**< Maximum size of ATT packet the SoftDevice can send or receive.
+ The default and minimum value is @ref BLE_GATT_ATT_MTU_DEFAULT.
+ @mscs
+ @mmsc{@ref BLE_GATTC_MTU_EXCHANGE}
+ @mmsc{@ref BLE_GATTS_MTU_EXCHANGE}
+ @endmscs
+ */
+} ble_gatt_conn_cfg_t;
+
+/**@brief GATT Characteristic Properties. */
+typedef struct
+{
+ /* Standard properties */
+ uint8_t broadcast :1; /**< Broadcasting of the value permitted. */
+ uint8_t read :1; /**< Reading the value permitted. */
+ uint8_t write_wo_resp :1; /**< Writing the value with Write Command permitted. */
+ uint8_t write :1; /**< Writing the value with Write Request permitted. */
+ uint8_t notify :1; /**< Notification of the value permitted. */
+ uint8_t indicate :1; /**< Indications of the value permitted. */
+ uint8_t auth_signed_wr :1; /**< Writing the value with Signed Write Command permitted. */
+} ble_gatt_char_props_t;
+
+/**@brief GATT Characteristic Extended Properties. */
+typedef struct
+{
+ /* Extended properties */
+ uint8_t reliable_wr :1; /**< Writing the value with Queued Write operations permitted. */
+ uint8_t wr_aux :1; /**< Writing the Characteristic User Description descriptor permitted. */
+} ble_gatt_char_ext_props_t;
+
+/** @} */
+
+#ifdef __cplusplus
+}
+#endif
+#endif // BLE_GATT_H__
+
+/** @} */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/softdevice/s112/headers/ble_gattc.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/softdevice/s112/headers/ble_gattc.h
new file mode 100644
index 0000000..7fb3920
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/softdevice/s112/headers/ble_gattc.h
@@ -0,0 +1,715 @@
+/*
+ * Copyright (c) 2011 - 2017, 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ */
+
+/**
+ @addtogroup BLE_GATTC Generic Attribute Profile (GATT) Client
+ @{
+ @brief Definitions and prototypes for the GATT Client interface.
+ */
+
+#ifndef BLE_GATTC_H__
+#define BLE_GATTC_H__
+
+#include <stdint.h>
+#include "nrf.h"
+#include "nrf_svc.h"
+#include "nrf_error.h"
+#include "ble_ranges.h"
+#include "ble_types.h"
+#include "ble_err.h"
+#include "ble_gatt.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** @addtogroup BLE_GATTC_ENUMERATIONS Enumerations
+ * @{ */
+
+/**@brief GATTC API SVC numbers. */
+enum BLE_GATTC_SVCS
+{
+ SD_BLE_GATTC_PRIMARY_SERVICES_DISCOVER = BLE_GATTC_SVC_BASE, /**< Primary Service Discovery. */
+ SD_BLE_GATTC_RELATIONSHIPS_DISCOVER, /**< Relationship Discovery. */
+ SD_BLE_GATTC_CHARACTERISTICS_DISCOVER, /**< Characteristic Discovery. */
+ SD_BLE_GATTC_DESCRIPTORS_DISCOVER, /**< Characteristic Descriptor Discovery. */
+ SD_BLE_GATTC_ATTR_INFO_DISCOVER, /**< Attribute Information Discovery. */
+ SD_BLE_GATTC_CHAR_VALUE_BY_UUID_READ, /**< Read Characteristic Value by UUID. */
+ SD_BLE_GATTC_READ, /**< Generic read. */
+ SD_BLE_GATTC_CHAR_VALUES_READ, /**< Read multiple Characteristic Values. */
+ SD_BLE_GATTC_WRITE, /**< Generic write. */
+ SD_BLE_GATTC_HV_CONFIRM, /**< Handle Value Confirmation. */
+ SD_BLE_GATTC_EXCHANGE_MTU_REQUEST, /**< Exchange MTU Request. */
+};
+
+/**
+ * @brief GATT Client Event IDs.
+ */
+enum BLE_GATTC_EVTS
+{
+ BLE_GATTC_EVT_PRIM_SRVC_DISC_RSP = BLE_GATTC_EVT_BASE, /**< Primary Service Discovery Response event. \n See @ref ble_gattc_evt_prim_srvc_disc_rsp_t. */
+ BLE_GATTC_EVT_REL_DISC_RSP, /**< Relationship Discovery Response event. \n See @ref ble_gattc_evt_rel_disc_rsp_t. */
+ BLE_GATTC_EVT_CHAR_DISC_RSP, /**< Characteristic Discovery Response event. \n See @ref ble_gattc_evt_char_disc_rsp_t. */
+ BLE_GATTC_EVT_DESC_DISC_RSP, /**< Descriptor Discovery Response event. \n See @ref ble_gattc_evt_desc_disc_rsp_t. */
+ BLE_GATTC_EVT_ATTR_INFO_DISC_RSP, /**< Attribute Information Response event. \n See @ref ble_gattc_evt_attr_info_disc_rsp_t. */
+ BLE_GATTC_EVT_CHAR_VAL_BY_UUID_READ_RSP, /**< Read By UUID Response event. \n See @ref ble_gattc_evt_char_val_by_uuid_read_rsp_t. */
+ BLE_GATTC_EVT_READ_RSP, /**< Read Response event. \n See @ref ble_gattc_evt_read_rsp_t. */
+ BLE_GATTC_EVT_CHAR_VALS_READ_RSP, /**< Read multiple Response event. \n See @ref ble_gattc_evt_char_vals_read_rsp_t. */
+ BLE_GATTC_EVT_WRITE_RSP, /**< Write Response event. \n See @ref ble_gattc_evt_write_rsp_t. */
+ BLE_GATTC_EVT_HVX, /**< Handle Value Notification or Indication event. \n Confirm indication with @ref sd_ble_gattc_hv_confirm. \n See @ref ble_gattc_evt_hvx_t. */
+ BLE_GATTC_EVT_EXCHANGE_MTU_RSP, /**< Exchange MTU Response event. \n See @ref ble_gattc_evt_exchange_mtu_rsp_t. */
+ BLE_GATTC_EVT_TIMEOUT, /**< Timeout event. \n See @ref ble_gattc_evt_timeout_t. */
+ BLE_GATTC_EVT_WRITE_CMD_TX_COMPLETE /**< Write without Response transmission complete. \n See @ref ble_gattc_evt_write_cmd_tx_complete_t. */
+};
+
+/** @} */
+
+/** @addtogroup BLE_GATTC_DEFINES Defines
+ * @{ */
+
+/** @defgroup BLE_ERRORS_GATTC SVC return values specific to GATTC
+ * @{ */
+#define BLE_ERROR_GATTC_PROC_NOT_PERMITTED (NRF_GATTC_ERR_BASE + 0x000) /**< Procedure not Permitted. */
+/** @} */
+
+/** @defgroup BLE_GATTC_ATTR_INFO_FORMAT Attribute Information Formats
+ * @{ */
+#define BLE_GATTC_ATTR_INFO_FORMAT_16BIT 1 /**< 16-bit Attribute Information Format. */
+#define BLE_GATTC_ATTR_INFO_FORMAT_128BIT 2 /**< 128-bit Attribute Information Format. */
+/** @} */
+
+/** @defgroup BLE_GATTC_DEFAULTS GATT Client defaults
+ * @{ */
+#define BLE_GATTC_WRITE_CMD_TX_QUEUE_SIZE_DEFAULT 1 /**< Default number of Write without Response that can be queued for transmission. */
+/** @} */
+
+/** @} */
+
+/** @addtogroup BLE_GATTC_STRUCTURES Structures
+ * @{ */
+
+/**
+ * @brief BLE GATTC connection configuration parameters, set with @ref sd_ble_cfg_set.
+ */
+typedef struct
+{
+ uint8_t write_cmd_tx_queue_size; /**< The guaranteed minimum number of Write without Response that can be queued for transmission.
+ The default value is @ref BLE_GATTC_WRITE_CMD_TX_QUEUE_SIZE_DEFAULT */
+} ble_gattc_conn_cfg_t;
+
+/**@brief Operation Handle Range. */
+typedef struct
+{
+ uint16_t start_handle; /**< Start Handle. */
+ uint16_t end_handle; /**< End Handle. */
+} ble_gattc_handle_range_t;
+
+
+/**@brief GATT service. */
+typedef struct
+{
+ ble_uuid_t uuid; /**< Service UUID. */
+ ble_gattc_handle_range_t handle_range; /**< Service Handle Range. */
+} ble_gattc_service_t;
+
+
+/**@brief GATT include. */
+typedef struct
+{
+ uint16_t handle; /**< Include Handle. */
+ ble_gattc_service_t included_srvc; /**< Handle of the included service. */
+} ble_gattc_include_t;
+
+
+/**@brief GATT characteristic. */
+typedef struct
+{
+ ble_uuid_t uuid; /**< Characteristic UUID. */
+ ble_gatt_char_props_t char_props; /**< Characteristic Properties. */
+ uint8_t char_ext_props : 1; /**< Extended properties present. */
+ uint16_t handle_decl; /**< Handle of the Characteristic Declaration. */
+ uint16_t handle_value; /**< Handle of the Characteristic Value. */
+} ble_gattc_char_t;
+
+
+/**@brief GATT descriptor. */
+typedef struct
+{
+ uint16_t handle; /**< Descriptor Handle. */
+ ble_uuid_t uuid; /**< Descriptor UUID. */
+} ble_gattc_desc_t;
+
+
+/**@brief Write Parameters. */
+typedef struct
+{
+ uint8_t write_op; /**< Write Operation to be performed, see @ref BLE_GATT_WRITE_OPS. */
+ uint8_t flags; /**< Flags, see @ref BLE_GATT_EXEC_WRITE_FLAGS. */
+ uint16_t handle; /**< Handle to the attribute to be written. */
+ uint16_t offset; /**< Offset in bytes. @note For WRITE_CMD and WRITE_REQ, offset must be 0. */
+ uint16_t len; /**< Length of data in bytes. */
+ uint8_t const *p_value; /**< Pointer to the value data. */
+} ble_gattc_write_params_t;
+
+/**@brief Attribute Information for 16-bit Attribute UUID. */
+typedef struct
+{
+ uint16_t handle; /**< Attribute handle. */
+ ble_uuid_t uuid; /**< 16-bit Attribute UUID. */
+} ble_gattc_attr_info16_t;
+
+/**@brief Attribute Information for 128-bit Attribute UUID. */
+typedef struct
+{
+ uint16_t handle; /**< Attribute handle. */
+ ble_uuid128_t uuid; /**< 128-bit Attribute UUID. */
+} ble_gattc_attr_info128_t;
+
+/**@brief Event structure for @ref BLE_GATTC_EVT_PRIM_SRVC_DISC_RSP. */
+typedef struct
+{
+ uint16_t count; /**< Service count. */
+ ble_gattc_service_t services[1]; /**< Service data. @note This is a variable length array. The size of 1 indicated is only a placeholder for compilation.
+ See @ref sd_ble_evt_get for more information on how to use event structures with variable length array members. */
+} ble_gattc_evt_prim_srvc_disc_rsp_t;
+
+/**@brief Event structure for @ref BLE_GATTC_EVT_REL_DISC_RSP. */
+typedef struct
+{
+ uint16_t count; /**< Include count. */
+ ble_gattc_include_t includes[1]; /**< Include data. @note This is a variable length array. The size of 1 indicated is only a placeholder for compilation.
+ See @ref sd_ble_evt_get for more information on how to use event structures with variable length array members. */
+} ble_gattc_evt_rel_disc_rsp_t;
+
+/**@brief Event structure for @ref BLE_GATTC_EVT_CHAR_DISC_RSP. */
+typedef struct
+{
+ uint16_t count; /**< Characteristic count. */
+ ble_gattc_char_t chars[1]; /**< Characteristic data. @note This is a variable length array. The size of 1 indicated is only a placeholder for compilation.
+ See @ref sd_ble_evt_get for more information on how to use event structures with variable length array members. */
+} ble_gattc_evt_char_disc_rsp_t;
+
+/**@brief Event structure for @ref BLE_GATTC_EVT_DESC_DISC_RSP. */
+typedef struct
+{
+ uint16_t count; /**< Descriptor count. */
+ ble_gattc_desc_t descs[1]; /**< Descriptor data. @note This is a variable length array. The size of 1 indicated is only a placeholder for compilation.
+ See @ref sd_ble_evt_get for more information on how to use event structures with variable length array members. */
+} ble_gattc_evt_desc_disc_rsp_t;
+
+/**@brief Event structure for @ref BLE_GATTC_EVT_ATTR_INFO_DISC_RSP. */
+typedef struct
+{
+ uint16_t count; /**< Attribute count. */
+ uint8_t format; /**< Attribute information format, see @ref BLE_GATTC_ATTR_INFO_FORMAT. */
+ union {
+ ble_gattc_attr_info16_t attr_info16[1]; /**< Attribute information for 16-bit Attribute UUID.
+ @note This is a variable length array. The size of 1 indicated is only a placeholder for compilation.
+ See @ref sd_ble_evt_get for more information on how to use event structures with variable length array members. */
+ ble_gattc_attr_info128_t attr_info128[1]; /**< Attribute information for 128-bit Attribute UUID.
+ @note This is a variable length array. The size of 1 indicated is only a placeholder for compilation.
+ See @ref sd_ble_evt_get for more information on how to use event structures with variable length array members. */
+ } info; /**< Attribute information union. */
+} ble_gattc_evt_attr_info_disc_rsp_t;
+
+/**@brief GATT read by UUID handle value pair. */
+typedef struct
+{
+ uint16_t handle; /**< Attribute Handle. */
+ uint8_t *p_value; /**< Pointer to the Attribute Value, length is available in @ref ble_gattc_evt_char_val_by_uuid_read_rsp_t::value_len. */
+} ble_gattc_handle_value_t;
+
+/**@brief Event structure for @ref BLE_GATTC_EVT_CHAR_VAL_BY_UUID_READ_RSP. */
+typedef struct
+{
+ uint16_t count; /**< Handle-Value Pair Count. */
+ uint16_t value_len; /**< Length of the value in Handle-Value(s) list. */
+ uint8_t handle_value[1]; /**< Handle-Value(s) list. To iterate through the list use @ref sd_ble_gattc_evt_char_val_by_uuid_read_rsp_iter.
+ @note This is a variable length array. The size of 1 indicated is only a placeholder for compilation.
+ See @ref sd_ble_evt_get for more information on how to use event structures with variable length array members. */
+} ble_gattc_evt_char_val_by_uuid_read_rsp_t;
+
+/**@brief Event structure for @ref BLE_GATTC_EVT_READ_RSP. */
+typedef struct
+{
+ uint16_t handle; /**< Attribute Handle. */
+ uint16_t offset; /**< Offset of the attribute data. */
+ uint16_t len; /**< Attribute data length. */
+ uint8_t data[1]; /**< Attribute data. @note This is a variable length array. The size of 1 indicated is only a placeholder for compilation.
+ See @ref sd_ble_evt_get for more information on how to use event structures with variable length array members. */
+} ble_gattc_evt_read_rsp_t;
+
+/**@brief Event structure for @ref BLE_GATTC_EVT_CHAR_VALS_READ_RSP. */
+typedef struct
+{
+ uint16_t len; /**< Concatenated Attribute values length. */
+ uint8_t values[1]; /**< Attribute values. @note This is a variable length array. The size of 1 indicated is only a placeholder for compilation.
+ See @ref sd_ble_evt_get for more information on how to use event structures with variable length array members. */
+} ble_gattc_evt_char_vals_read_rsp_t;
+
+/**@brief Event structure for @ref BLE_GATTC_EVT_WRITE_RSP. */
+typedef struct
+{
+ uint16_t handle; /**< Attribute Handle. */
+ uint8_t write_op; /**< Type of write operation, see @ref BLE_GATT_WRITE_OPS. */
+ uint16_t offset; /**< Data offset. */
+ uint16_t len; /**< Data length. */
+ uint8_t data[1]; /**< Data. @note This is a variable length array. The size of 1 indicated is only a placeholder for compilation.
+ See @ref sd_ble_evt_get for more information on how to use event structures with variable length array members. */
+} ble_gattc_evt_write_rsp_t;
+
+/**@brief Event structure for @ref BLE_GATTC_EVT_HVX. */
+typedef struct
+{
+ uint16_t handle; /**< Handle to which the HVx operation applies. */
+ uint8_t type; /**< Indication or Notification, see @ref BLE_GATT_HVX_TYPES. */
+ uint16_t len; /**< Attribute data length. */
+ uint8_t data[1]; /**< Attribute data. @note This is a variable length array. The size of 1 indicated is only a placeholder for compilation.
+ See @ref sd_ble_evt_get for more information on how to use event structures with variable length array members. */
+} ble_gattc_evt_hvx_t;
+
+/**@brief Event structure for @ref BLE_GATTC_EVT_EXCHANGE_MTU_RSP. */
+typedef struct
+{
+ uint16_t server_rx_mtu; /**< Server RX MTU size. */
+} ble_gattc_evt_exchange_mtu_rsp_t;
+
+/**@brief Event structure for @ref BLE_GATTC_EVT_TIMEOUT. */
+typedef struct
+{
+ uint8_t src; /**< Timeout source, see @ref BLE_GATT_TIMEOUT_SOURCES. */
+} ble_gattc_evt_timeout_t;
+
+/**@brief Event structure for @ref BLE_GATTC_EVT_WRITE_CMD_TX_COMPLETE. */
+typedef struct
+{
+ uint8_t count; /**< Number of write without response transmissions completed. */
+} ble_gattc_evt_write_cmd_tx_complete_t;
+
+/**@brief GATTC event structure. */
+typedef struct
+{
+ uint16_t conn_handle; /**< Connection Handle on which event occurred. */
+ uint16_t gatt_status; /**< GATT status code for the operation, see @ref BLE_GATT_STATUS_CODES. */
+ uint16_t error_handle; /**< In case of error: The handle causing the error. In all other cases @ref BLE_GATT_HANDLE_INVALID. */
+ union
+ {
+ ble_gattc_evt_prim_srvc_disc_rsp_t prim_srvc_disc_rsp; /**< Primary Service Discovery Response Event Parameters. */
+ ble_gattc_evt_rel_disc_rsp_t rel_disc_rsp; /**< Relationship Discovery Response Event Parameters. */
+ ble_gattc_evt_char_disc_rsp_t char_disc_rsp; /**< Characteristic Discovery Response Event Parameters. */
+ ble_gattc_evt_desc_disc_rsp_t desc_disc_rsp; /**< Descriptor Discovery Response Event Parameters. */
+ ble_gattc_evt_char_val_by_uuid_read_rsp_t char_val_by_uuid_read_rsp; /**< Characteristic Value Read by UUID Response Event Parameters. */
+ ble_gattc_evt_read_rsp_t read_rsp; /**< Read Response Event Parameters. */
+ ble_gattc_evt_char_vals_read_rsp_t char_vals_read_rsp; /**< Characteristic Values Read Response Event Parameters. */
+ ble_gattc_evt_write_rsp_t write_rsp; /**< Write Response Event Parameters. */
+ ble_gattc_evt_hvx_t hvx; /**< Handle Value Notification/Indication Event Parameters. */
+ ble_gattc_evt_exchange_mtu_rsp_t exchange_mtu_rsp; /**< Exchange MTU Response Event Parameters. */
+ ble_gattc_evt_timeout_t timeout; /**< Timeout Event Parameters. */
+ ble_gattc_evt_attr_info_disc_rsp_t attr_info_disc_rsp; /**< Attribute Information Discovery Event Parameters. */
+ ble_gattc_evt_write_cmd_tx_complete_t write_cmd_tx_complete; /**< Write without Response transmission complete Event Parameters. */
+ } params; /**< Event Parameters. @note Only valid if @ref gatt_status == @ref BLE_GATT_STATUS_SUCCESS. */
+} ble_gattc_evt_t;
+/** @} */
+
+/** @addtogroup BLE_GATTC_FUNCTIONS Functions
+ * @{ */
+
+/**@brief Initiate or continue a GATT Primary Service Discovery procedure.
+ *
+ * @details This function initiates or resumes a Primary Service discovery procedure, starting from the supplied handle.
+ * If the last service has not been reached, this function must be called again with an updated start handle value to continue the search.
+ *
+ * @note If any of the discovered services have 128-bit UUIDs which are not present in the table provided to ble_vs_uuids_assign, a UUID structure with
+ * type @ref BLE_UUID_TYPE_UNKNOWN will be received in the corresponding event.
+ *
+ * @events
+ * @event{@ref BLE_GATTC_EVT_PRIM_SRVC_DISC_RSP}
+ * @endevents
+ *
+ * @mscs
+ * @mmsc{@ref BLE_GATTC_PRIM_SRVC_DISC_MSC}
+ * @endmscs
+ *
+ * @param[in] conn_handle The connection handle identifying the connection to perform this procedure on.
+ * @param[in] start_handle Handle to start searching from.
+ * @param[in] p_srvc_uuid Pointer to the service UUID to be found. If it is NULL, all primary services will be returned.
+ *
+ * @retval ::NRF_SUCCESS Successfully started or resumed the Primary Service Discovery procedure.
+ * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid Connection Handle.
+ * @retval ::NRF_ERROR_INVALID_STATE Invalid Connection State.
+ * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied.
+ * @retval ::NRF_ERROR_BUSY Client procedure already in progress.
+ * @retval ::NRF_ERROR_TIMEOUT There has been a GATT procedure timeout. No new GATT procedure can be performed without reestablishing the connection.
+ */
+SVCALL(SD_BLE_GATTC_PRIMARY_SERVICES_DISCOVER, uint32_t, sd_ble_gattc_primary_services_discover(uint16_t conn_handle, uint16_t start_handle, ble_uuid_t const *p_srvc_uuid));
+
+
+/**@brief Initiate or continue a GATT Relationship Discovery procedure.
+ *
+ * @details This function initiates or resumes the Find Included Services sub-procedure. If the last included service has not been reached,
+ * this must be called again with an updated handle range to continue the search.
+ *
+ * @events
+ * @event{@ref BLE_GATTC_EVT_REL_DISC_RSP}
+ * @endevents
+ *
+ * @mscs
+ * @mmsc{@ref BLE_GATTC_REL_DISC_MSC}
+ * @endmscs
+ *
+ * @param[in] conn_handle The connection handle identifying the connection to perform this procedure on.
+ * @param[in] p_handle_range A pointer to the range of handles of the Service to perform this procedure on.
+ *
+ * @retval ::NRF_SUCCESS Successfully started or resumed the Relationship Discovery procedure.
+ * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid Connection Handle.
+ * @retval ::NRF_ERROR_INVALID_STATE Invalid Connection State.
+ * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied.
+ * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied.
+ * @retval ::NRF_ERROR_BUSY Client procedure already in progress.
+ * @retval ::NRF_ERROR_TIMEOUT There has been a GATT procedure timeout. No new GATT procedure can be performed without reestablishing the connection.
+ */
+SVCALL(SD_BLE_GATTC_RELATIONSHIPS_DISCOVER, uint32_t, sd_ble_gattc_relationships_discover(uint16_t conn_handle, ble_gattc_handle_range_t const *p_handle_range));
+
+
+/**@brief Initiate or continue a GATT Characteristic Discovery procedure.
+ *
+ * @details This function initiates or resumes a Characteristic discovery procedure. If the last Characteristic has not been reached,
+ * this must be called again with an updated handle range to continue the discovery.
+ *
+ * @note If any of the discovered characteristics have 128-bit UUIDs which are not present in the table provided to ble_vs_uuids_assign, a UUID structure with
+ * type @ref BLE_UUID_TYPE_UNKNOWN will be received in the corresponding event.
+ *
+ * @events
+ * @event{@ref BLE_GATTC_EVT_CHAR_DISC_RSP}
+ * @endevents
+ *
+ * @mscs
+ * @mmsc{@ref BLE_GATTC_CHAR_DISC_MSC}
+ * @endmscs
+ *
+ * @param[in] conn_handle The connection handle identifying the connection to perform this procedure on.
+ * @param[in] p_handle_range A pointer to the range of handles of the Service to perform this procedure on.
+ *
+ * @retval ::NRF_SUCCESS Successfully started or resumed the Characteristic Discovery procedure.
+ * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid Connection Handle.
+ * @retval ::NRF_ERROR_INVALID_STATE Invalid Connection State.
+ * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied.
+ * @retval ::NRF_ERROR_BUSY Client procedure already in progress.
+ * @retval ::NRF_ERROR_TIMEOUT There has been a GATT procedure timeout. No new GATT procedure can be performed without reestablishing the connection.
+ */
+SVCALL(SD_BLE_GATTC_CHARACTERISTICS_DISCOVER, uint32_t, sd_ble_gattc_characteristics_discover(uint16_t conn_handle, ble_gattc_handle_range_t const *p_handle_range));
+
+
+/**@brief Initiate or continue a GATT Characteristic Descriptor Discovery procedure.
+ *
+ * @details This function initiates or resumes a Characteristic Descriptor discovery procedure. If the last Descriptor has not been reached,
+ * this must be called again with an updated handle range to continue the discovery.
+ *
+ * @events
+ * @event{@ref BLE_GATTC_EVT_DESC_DISC_RSP}
+ * @endevents
+ *
+ * @mscs
+ * @mmsc{@ref BLE_GATTC_DESC_DISC_MSC}
+ * @endmscs
+ *
+ * @param[in] conn_handle The connection handle identifying the connection to perform this procedure on.
+ * @param[in] p_handle_range A pointer to the range of handles of the Characteristic to perform this procedure on.
+ *
+ * @retval ::NRF_SUCCESS Successfully started or resumed the Descriptor Discovery procedure.
+ * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid Connection Handle.
+ * @retval ::NRF_ERROR_INVALID_STATE Invalid Connection State.
+ * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied.
+ * @retval ::NRF_ERROR_BUSY Client procedure already in progress.
+ * @retval ::NRF_ERROR_TIMEOUT There has been a GATT procedure timeout. No new GATT procedure can be performed without reestablishing the connection.
+ */
+SVCALL(SD_BLE_GATTC_DESCRIPTORS_DISCOVER, uint32_t, sd_ble_gattc_descriptors_discover(uint16_t conn_handle, ble_gattc_handle_range_t const *p_handle_range));
+
+
+/**@brief Initiate or continue a GATT Read using Characteristic UUID procedure.
+ *
+ * @details This function initiates or resumes a Read using Characteristic UUID procedure. If the last Characteristic has not been reached,
+ * this must be called again with an updated handle range to continue the discovery.
+ *
+ * @events
+ * @event{@ref BLE_GATTC_EVT_CHAR_VAL_BY_UUID_READ_RSP}
+ * @endevents
+ *
+ * @mscs
+ * @mmsc{@ref BLE_GATTC_READ_UUID_MSC}
+ * @endmscs
+ *
+ * @param[in] conn_handle The connection handle identifying the connection to perform this procedure on.
+ * @param[in] p_uuid Pointer to a Characteristic value UUID to read.
+ * @param[in] p_handle_range A pointer to the range of handles to perform this procedure on.
+ *
+ * @retval ::NRF_SUCCESS Successfully started or resumed the Read using Characteristic UUID procedure.
+ * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid Connection Handle.
+ * @retval ::NRF_ERROR_INVALID_STATE Invalid Connection State.
+ * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied.
+ * @retval ::NRF_ERROR_BUSY Client procedure already in progress.
+ * @retval ::NRF_ERROR_TIMEOUT There has been a GATT procedure timeout. No new GATT procedure can be performed without reestablishing the connection.
+ */
+SVCALL(SD_BLE_GATTC_CHAR_VALUE_BY_UUID_READ, uint32_t, sd_ble_gattc_char_value_by_uuid_read(uint16_t conn_handle, ble_uuid_t const *p_uuid, ble_gattc_handle_range_t const *p_handle_range));
+
+
+/**@brief Initiate or continue a GATT Read (Long) Characteristic or Descriptor procedure.
+ *
+ * @details This function initiates or resumes a GATT Read (Long) Characteristic or Descriptor procedure. If the Characteristic or Descriptor
+ * to be read is longer than ATT_MTU - 1, this function must be called multiple times with appropriate offset to read the
+ * complete value.
+ *
+ * @events
+ * @event{@ref BLE_GATTC_EVT_READ_RSP}
+ * @endevents
+ *
+ * @mscs
+ * @mmsc{@ref BLE_GATTC_VALUE_READ_MSC}
+ * @endmscs
+ *
+ * @param[in] conn_handle The connection handle identifying the connection to perform this procedure on.
+ * @param[in] handle The handle of the attribute to be read.
+ * @param[in] offset Offset into the attribute value to be read.
+ *
+ * @retval ::NRF_SUCCESS Successfully started or resumed the Read (Long) procedure.
+ * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid Connection Handle.
+ * @retval ::NRF_ERROR_INVALID_STATE Invalid Connection State.
+ * @retval ::NRF_ERROR_BUSY Client procedure already in progress.
+ * @retval ::NRF_ERROR_TIMEOUT There has been a GATT procedure timeout. No new GATT procedure can be performed without reestablishing the connection.
+ */
+SVCALL(SD_BLE_GATTC_READ, uint32_t, sd_ble_gattc_read(uint16_t conn_handle, uint16_t handle, uint16_t offset));
+
+
+/**@brief Initiate a GATT Read Multiple Characteristic Values procedure.
+ *
+ * @details This function initiates a GATT Read Multiple Characteristic Values procedure.
+ *
+ * @events
+ * @event{@ref BLE_GATTC_EVT_CHAR_VALS_READ_RSP}
+ * @endevents
+ *
+ * @mscs
+ * @mmsc{@ref BLE_GATTC_READ_MULT_MSC}
+ * @endmscs
+ *
+ * @param[in] conn_handle The connection handle identifying the connection to perform this procedure on.
+ * @param[in] p_handles A pointer to the handle(s) of the attribute(s) to be read.
+ * @param[in] handle_count The number of handles in p_handles.
+ *
+ * @retval ::NRF_SUCCESS Successfully started the Read Multiple Characteristic Values procedure.
+ * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid Connection Handle.
+ * @retval ::NRF_ERROR_INVALID_STATE Invalid Connection State.
+ * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied.
+ * @retval ::NRF_ERROR_BUSY Client procedure already in progress.
+ * @retval ::NRF_ERROR_TIMEOUT There has been a GATT procedure timeout. No new GATT procedure can be performed without reestablishing the connection.
+ */
+SVCALL(SD_BLE_GATTC_CHAR_VALUES_READ, uint32_t, sd_ble_gattc_char_values_read(uint16_t conn_handle, uint16_t const *p_handles, uint16_t handle_count));
+
+
+/**@brief Perform a Write (Characteristic Value or Descriptor, with or without response, signed or not, long or reliable) procedure.
+ *
+ * @details This function can perform all write procedures described in GATT.
+ *
+ * @note Only one write with response procedure can be ongoing per connection at a time.
+ * If the application tries to write with response while another write with response procedure is ongoing,
+ * the function call will return @ref NRF_ERROR_BUSY.
+ * A @ref BLE_GATTC_EVT_WRITE_RSP event will be issued as soon as the write response arrives from the peer.
+ *
+ * @note The number of Write without Response that can be queued is configured by @ref ble_gattc_conn_cfg_t::write_cmd_tx_queue_size
+ * When the queue is full, the function call will return @ref NRF_ERROR_RESOURCES.
+ * A @ref BLE_GATTC_EVT_WRITE_CMD_TX_COMPLETE event will be issued as soon as the transmission of the write without response is complete.
+ *
+ * @note The application can keep track of the available queue element count for writes without responses by following the procedure below:
+ * - Store initial queue element count in a variable.
+ * - Decrement the variable, which stores the currently available queue element count, by one when a call to this function returns @ref NRF_SUCCESS.
+ * - Increment the variable, which stores the current available queue element count, by the count variable in @ref BLE_GATTC_EVT_WRITE_CMD_TX_COMPLETE event.
+ *
+ * @events
+ * @event{@ref BLE_GATTC_EVT_WRITE_CMD_TX_COMPLETE, Write without response transmission complete.}
+ * @event{@ref BLE_GATTC_EVT_WRITE_RSP, Write response received from the peer.}
+ * @endevents
+ *
+ * @mscs
+ * @mmsc{@ref BLE_GATTC_VALUE_WRITE_WITHOUT_RESP_MSC}
+ * @mmsc{@ref BLE_GATTC_VALUE_WRITE_MSC}
+ * @mmsc{@ref BLE_GATTC_VALUE_LONG_WRITE_MSC}
+ * @mmsc{@ref BLE_GATTC_VALUE_RELIABLE_WRITE_MSC}
+ * @endmscs
+ *
+ * @param[in] conn_handle The connection handle identifying the connection to perform this procedure on.
+ * @param[in] p_write_params A pointer to a write parameters structure.
+ *
+ * @retval ::NRF_SUCCESS Successfully started the Write procedure.
+ * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid Connection Handle.
+ * @retval ::NRF_ERROR_INVALID_STATE Invalid Connection State.
+ * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied.
+ * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied.
+ * @retval ::NRF_ERROR_DATA_SIZE Invalid data size(s) supplied.
+ * @retval ::NRF_ERROR_BUSY For write with response, procedure already in progress. Wait for a @ref BLE_GATTC_EVT_WRITE_RSP event and retry.
+ * @retval ::NRF_ERROR_RESOURCES Too many writes without responses queued.
+ * Wait for a @ref BLE_GATTC_EVT_WRITE_CMD_TX_COMPLETE event and retry.
+ * @retval ::NRF_ERROR_TIMEOUT There has been a GATT procedure timeout. No new GATT procedure can be performed without reestablishing the connection.
+ */
+SVCALL(SD_BLE_GATTC_WRITE, uint32_t, sd_ble_gattc_write(uint16_t conn_handle, ble_gattc_write_params_t const *p_write_params));
+
+
+/**@brief Send a Handle Value Confirmation to the GATT Server.
+ *
+ * @mscs
+ * @mmsc{@ref BLE_GATTC_HVI_MSC}
+ * @endmscs
+ *
+ * @param[in] conn_handle The connection handle identifying the connection to perform this procedure on.
+ * @param[in] handle The handle of the attribute in the indication.
+ *
+ * @retval ::NRF_SUCCESS Successfully queued the Handle Value Confirmation for transmission.
+ * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid Connection Handle.
+ * @retval ::NRF_ERROR_INVALID_STATE Invalid Connection State or no Indication pending to be confirmed.
+ * @retval ::BLE_ERROR_INVALID_ATTR_HANDLE Invalid attribute handle.
+ * @retval ::NRF_ERROR_TIMEOUT There has been a GATT procedure timeout. No new GATT procedure can be performed without reestablishing the connection.
+ */
+SVCALL(SD_BLE_GATTC_HV_CONFIRM, uint32_t, sd_ble_gattc_hv_confirm(uint16_t conn_handle, uint16_t handle));
+
+/**@brief Discovers information about a range of attributes on a GATT server.
+ *
+ * @events
+ * @event{@ref BLE_GATTC_EVT_ATTR_INFO_DISC_RSP, Generated when information about a range of attributes has been received.}
+ * @endevents
+ *
+ * @param[in] conn_handle The connection handle identifying the connection to perform this procedure on.
+ * @param[in] p_handle_range The range of handles to request information about.
+ *
+ * @retval ::NRF_SUCCESS Successfully started an attribute information discovery procedure.
+ * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid connection handle.
+ * @retval ::NRF_ERROR_INVALID_STATE Invalid connection state
+ * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied.
+ * @retval ::NRF_ERROR_BUSY Client procedure already in progress.
+ * @retval ::NRF_ERROR_TIMEOUT There has been a GATT procedure timeout. No new GATT procedure can be performed without reestablishing the connection.
+ */
+SVCALL(SD_BLE_GATTC_ATTR_INFO_DISCOVER, uint32_t, sd_ble_gattc_attr_info_discover(uint16_t conn_handle, ble_gattc_handle_range_t const * p_handle_range));
+
+/**@brief Start an ATT_MTU exchange by sending an Exchange MTU Request to the server.
+ *
+ * @details The SoftDevice sets ATT_MTU to the minimum of:
+ * - The Client RX MTU value, and
+ * - The Server RX MTU value from @ref BLE_GATTC_EVT_EXCHANGE_MTU_RSP.
+ *
+ * However, the SoftDevice never sets ATT_MTU lower than @ref BLE_GATT_ATT_MTU_DEFAULT.
+ *
+ * @events
+ * @event{@ref BLE_GATTC_EVT_EXCHANGE_MTU_RSP}
+ * @endevents
+ *
+ * @mscs
+ * @mmsc{@ref BLE_GATTC_MTU_EXCHANGE}
+ * @endmscs
+ *
+ * @param[in] conn_handle The connection handle identifying the connection to perform this procedure on.
+ * @param[in] client_rx_mtu Client RX MTU size.
+ * - The minimum value is @ref BLE_GATT_ATT_MTU_DEFAULT.
+ * - The maximum value is @ref ble_gatt_conn_cfg_t::att_mtu in the connection configuration
+ used for this connection.
+ * - The value must be equal to Server RX MTU size given in @ref sd_ble_gatts_exchange_mtu_reply
+ * if an ATT_MTU exchange has already been performed in the other direction.
+ *
+ * @retval ::NRF_SUCCESS Successfully sent request to the server.
+ * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid connection handle.
+ * @retval ::NRF_ERROR_INVALID_STATE Invalid connection state or an ATT_MTU exchange was already requested once.
+ * @retval ::NRF_ERROR_INVALID_PARAM Invalid Client RX MTU size supplied.
+ * @retval ::NRF_ERROR_BUSY Client procedure already in progress.
+ * @retval ::NRF_ERROR_TIMEOUT There has been a GATT procedure timeout. No new GATT procedure can be performed without reestablishing the connection.
+ */
+SVCALL(SD_BLE_GATTC_EXCHANGE_MTU_REQUEST, uint32_t, sd_ble_gattc_exchange_mtu_request(uint16_t conn_handle, uint16_t client_rx_mtu));
+
+/**@brief Iterate through Handle-Value(s) list in @ref BLE_GATTC_EVT_CHAR_VAL_BY_UUID_READ_RSP event.
+ *
+ * @param[in] p_gattc_evt Pointer to event buffer containing @ref BLE_GATTC_EVT_CHAR_VAL_BY_UUID_READ_RSP event.
+ * @note If the buffer contains different event, behavior is undefined.
+ * @param[in,out] p_iter Iterator, points to @ref ble_gattc_handle_value_t structure that will be filled in with
+ * the next Handle-Value pair in each iteration. If the function returns other than
+ * @ref NRF_SUCCESS, it will not be changed.
+ * - To start iteration, initialize the structure to zero.
+ * - To continue, pass the value from previous iteration.
+ *
+ * \code
+ * ble_gattc_handle_value_t iter;
+ * memset(&iter, 0, sizeof(ble_gattc_handle_value_t));
+ * while (sd_ble_gattc_evt_char_val_by_uuid_read_rsp_iter(&ble_evt.evt.gattc_evt, &iter) == NRF_SUCCESS)
+ * {
+ * app_handle = iter.handle;
+ * memcpy(app_value, iter.p_value, ble_evt.evt.gattc_evt.params.char_val_by_uuid_read_rsp.value_len);
+ * }
+ * \endcode
+ *
+ * @retval ::NRF_SUCCESS Successfully retrieved the next Handle-Value pair.
+ * @retval ::NRF_ERROR_NOT_FOUND No more Handle-Value pairs available in the list.
+ */
+__STATIC_INLINE uint32_t sd_ble_gattc_evt_char_val_by_uuid_read_rsp_iter(ble_gattc_evt_t *p_gattc_evt, ble_gattc_handle_value_t *p_iter);
+
+/** @} */
+
+#ifndef SUPPRESS_INLINE_IMPLEMENTATION
+
+__STATIC_INLINE uint32_t sd_ble_gattc_evt_char_val_by_uuid_read_rsp_iter(ble_gattc_evt_t *p_gattc_evt, ble_gattc_handle_value_t *p_iter)
+{
+ uint32_t value_len = p_gattc_evt->params.char_val_by_uuid_read_rsp.value_len;
+ uint8_t *p_first = p_gattc_evt->params.char_val_by_uuid_read_rsp.handle_value;
+ uint8_t *p_next = p_iter->p_value ? p_iter->p_value + value_len : p_first;
+
+ if ((p_next - p_first) / (sizeof(uint16_t) + value_len) < p_gattc_evt->params.char_val_by_uuid_read_rsp.count)
+ {
+ p_iter->handle = (uint16_t)p_next[1] << 8 | p_next[0];
+ p_iter->p_value = p_next + sizeof(uint16_t);
+ return NRF_SUCCESS;
+ }
+ else
+ {
+ return NRF_ERROR_NOT_FOUND;
+ }
+}
+
+#endif /* SUPPRESS_INLINE_IMPLEMENTATION */
+
+#ifdef __cplusplus
+}
+#endif
+#endif /* BLE_GATTC_H__ */
+
+/**
+ @}
+*/
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/softdevice/s112/headers/ble_gatts.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/softdevice/s112/headers/ble_gatts.h
new file mode 100644
index 0000000..e437b6e
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/softdevice/s112/headers/ble_gatts.h
@@ -0,0 +1,845 @@
+/*
+ * Copyright (c) 2011 - 2017, 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ */
+
+/**
+ @addtogroup BLE_GATTS Generic Attribute Profile (GATT) Server
+ @{
+ @brief Definitions and prototypes for the GATTS interface.
+ */
+
+#ifndef BLE_GATTS_H__
+#define BLE_GATTS_H__
+
+#include <stdint.h>
+#include "nrf_svc.h"
+#include "nrf_error.h"
+#include "ble_hci.h"
+#include "ble_ranges.h"
+#include "ble_types.h"
+#include "ble_err.h"
+#include "ble_gatt.h"
+#include "ble_gap.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** @addtogroup BLE_GATTS_ENUMERATIONS Enumerations
+ * @{ */
+
+/**
+ * @brief GATTS API SVC numbers.
+ */
+enum BLE_GATTS_SVCS
+{
+ SD_BLE_GATTS_SERVICE_ADD = BLE_GATTS_SVC_BASE, /**< Add a service. */
+ SD_BLE_GATTS_INCLUDE_ADD, /**< Add an included service. */
+ SD_BLE_GATTS_CHARACTERISTIC_ADD, /**< Add a characteristic. */
+ SD_BLE_GATTS_DESCRIPTOR_ADD, /**< Add a generic attribute. */
+ SD_BLE_GATTS_VALUE_SET, /**< Set an attribute value. */
+ SD_BLE_GATTS_VALUE_GET, /**< Get an attribute value. */
+ SD_BLE_GATTS_HVX, /**< Handle Value Notification or Indication. */
+ SD_BLE_GATTS_SERVICE_CHANGED, /**< Perform a Service Changed Indication to one or more peers. */
+ SD_BLE_GATTS_RW_AUTHORIZE_REPLY, /**< Reply to an authorization request for a read or write operation on one or more attributes. */
+ SD_BLE_GATTS_SYS_ATTR_SET, /**< Set the persistent system attributes for a connection. */
+ SD_BLE_GATTS_SYS_ATTR_GET, /**< Retrieve the persistent system attributes. */
+ SD_BLE_GATTS_INITIAL_USER_HANDLE_GET, /**< Retrieve the first valid user handle. */
+ SD_BLE_GATTS_ATTR_GET, /**< Retrieve the UUID and/or metadata of an attribute. */
+ SD_BLE_GATTS_EXCHANGE_MTU_REPLY /**< Reply to Exchange MTU Request. */
+};
+
+/**
+ * @brief GATT Server Event IDs.
+ */
+enum BLE_GATTS_EVTS
+{
+ BLE_GATTS_EVT_WRITE = BLE_GATTS_EVT_BASE, /**< Write operation performed. \n See @ref ble_gatts_evt_write_t. */
+ BLE_GATTS_EVT_RW_AUTHORIZE_REQUEST, /**< Read/Write Authorization request. \n Reply with @ref sd_ble_gatts_rw_authorize_reply. \n See @ref ble_gatts_evt_rw_authorize_request_t. */
+ BLE_GATTS_EVT_SYS_ATTR_MISSING, /**< A persistent system attribute access is pending. \n Respond with @ref sd_ble_gatts_sys_attr_set. \n See @ref ble_gatts_evt_sys_attr_missing_t. */
+ BLE_GATTS_EVT_HVC, /**< Handle Value Confirmation. \n See @ref ble_gatts_evt_hvc_t. */
+ BLE_GATTS_EVT_SC_CONFIRM, /**< Service Changed Confirmation. \n No additional event structure applies. */
+ BLE_GATTS_EVT_EXCHANGE_MTU_REQUEST, /**< Exchange MTU Request. \n Reply with @ref sd_ble_gatts_exchange_mtu_reply. \n See @ref ble_gatts_evt_exchange_mtu_request_t. */
+ BLE_GATTS_EVT_TIMEOUT, /**< Peer failed to respond to an ATT request in time. \n See @ref ble_gatts_evt_timeout_t. */
+ BLE_GATTS_EVT_HVN_TX_COMPLETE /**< Handle Value Notification transmission complete. \n See @ref ble_gatts_evt_hvn_tx_complete_t. */
+};
+
+/**@brief GATTS Configuration IDs.
+ *
+ * IDs that uniquely identify a GATTS configuration.
+ */
+enum BLE_GATTS_CFGS
+{
+ BLE_GATTS_CFG_SERVICE_CHANGED = BLE_GATTS_CFG_BASE, /**< Service changed configuration. */
+ BLE_GATTS_CFG_ATTR_TAB_SIZE, /**< Attribute table size configuration. */
+};
+
+/** @} */
+
+/** @addtogroup BLE_GATTS_DEFINES Defines
+ * @{ */
+
+/** @defgroup BLE_ERRORS_GATTS SVC return values specific to GATTS
+ * @{ */
+#define BLE_ERROR_GATTS_INVALID_ATTR_TYPE (NRF_GATTS_ERR_BASE + 0x000) /**< Invalid attribute type. */
+#define BLE_ERROR_GATTS_SYS_ATTR_MISSING (NRF_GATTS_ERR_BASE + 0x001) /**< System Attributes missing. */
+/** @} */
+
+/** @defgroup BLE_GATTS_ATTR_LENS_MAX Maximum attribute lengths
+ * @{ */
+#define BLE_GATTS_FIX_ATTR_LEN_MAX (510) /**< Maximum length for fixed length Attribute Values. */
+#define BLE_GATTS_VAR_ATTR_LEN_MAX (512) /**< Maximum length for variable length Attribute Values. */
+/** @} */
+
+/** @defgroup BLE_GATTS_SRVC_TYPES GATT Server Service Types
+ * @{ */
+#define BLE_GATTS_SRVC_TYPE_INVALID 0x00 /**< Invalid Service Type. */
+#define BLE_GATTS_SRVC_TYPE_PRIMARY 0x01 /**< Primary Service. */
+#define BLE_GATTS_SRVC_TYPE_SECONDARY 0x02 /**< Secondary Type. */
+/** @} */
+
+
+/** @defgroup BLE_GATTS_ATTR_TYPES GATT Server Attribute Types
+ * @{ */
+#define BLE_GATTS_ATTR_TYPE_INVALID 0x00 /**< Invalid Attribute Type. */
+#define BLE_GATTS_ATTR_TYPE_PRIM_SRVC_DECL 0x01 /**< Primary Service Declaration. */
+#define BLE_GATTS_ATTR_TYPE_SEC_SRVC_DECL 0x02 /**< Secondary Service Declaration. */
+#define BLE_GATTS_ATTR_TYPE_INC_DECL 0x03 /**< Include Declaration. */
+#define BLE_GATTS_ATTR_TYPE_CHAR_DECL 0x04 /**< Characteristic Declaration. */
+#define BLE_GATTS_ATTR_TYPE_CHAR_VAL 0x05 /**< Characteristic Value. */
+#define BLE_GATTS_ATTR_TYPE_DESC 0x06 /**< Descriptor. */
+#define BLE_GATTS_ATTR_TYPE_OTHER 0x07 /**< Other, non-GATT specific type. */
+/** @} */
+
+
+/** @defgroup BLE_GATTS_OPS GATT Server Operations
+ * @{ */
+#define BLE_GATTS_OP_INVALID 0x00 /**< Invalid Operation. */
+#define BLE_GATTS_OP_WRITE_REQ 0x01 /**< Write Request. */
+#define BLE_GATTS_OP_WRITE_CMD 0x02 /**< Write Command. */
+#define BLE_GATTS_OP_SIGN_WRITE_CMD 0x03 /**< Signed Write Command. */
+#define BLE_GATTS_OP_PREP_WRITE_REQ 0x04 /**< Prepare Write Request. */
+#define BLE_GATTS_OP_EXEC_WRITE_REQ_CANCEL 0x05 /**< Execute Write Request: Cancel all prepared writes. */
+#define BLE_GATTS_OP_EXEC_WRITE_REQ_NOW 0x06 /**< Execute Write Request: Immediately execute all prepared writes. */
+/** @} */
+
+/** @defgroup BLE_GATTS_VLOCS GATT Value Locations
+ * @{ */
+#define BLE_GATTS_VLOC_INVALID 0x00 /**< Invalid Location. */
+#define BLE_GATTS_VLOC_STACK 0x01 /**< Attribute Value is located in stack memory, no user memory is required. */
+#define BLE_GATTS_VLOC_USER 0x02 /**< Attribute Value is located in user memory. This requires the user to maintain a valid buffer through the lifetime of the attribute, since the stack
+ will read and write directly to the memory using the pointer provided in the APIs. There are no alignment requirements for the buffer. */
+/** @} */
+
+/** @defgroup BLE_GATTS_AUTHORIZE_TYPES GATT Server Authorization Types
+ * @{ */
+#define BLE_GATTS_AUTHORIZE_TYPE_INVALID 0x00 /**< Invalid Type. */
+#define BLE_GATTS_AUTHORIZE_TYPE_READ 0x01 /**< Authorize a Read Operation. */
+#define BLE_GATTS_AUTHORIZE_TYPE_WRITE 0x02 /**< Authorize a Write Request Operation. */
+/** @} */
+
+/** @defgroup BLE_GATTS_SYS_ATTR_FLAGS System Attribute Flags
+ * @{ */
+#define BLE_GATTS_SYS_ATTR_FLAG_SYS_SRVCS (1 << 0) /**< Restrict system attributes to system services only. */
+#define BLE_GATTS_SYS_ATTR_FLAG_USR_SRVCS (1 << 1) /**< Restrict system attributes to user services only. */
+/** @} */
+
+/** @defgroup BLE_GATTS_SERVICE_CHANGED Service Changed Inclusion Values
+ * @{
+ */
+#define BLE_GATTS_SERVICE_CHANGED_DEFAULT (1) /**< Default is to include the Service Changed characteristic in the Attribute Table. */
+/** @} */
+
+/** @defgroup BLE_GATTS_ATTR_TAB_SIZE Attribute Table size
+ * @{
+ */
+#define BLE_GATTS_ATTR_TAB_SIZE_MIN (248) /**< Minimum Attribute Table size */
+#define BLE_GATTS_ATTR_TAB_SIZE_DEFAULT (1408) /**< Default Attribute Table size. */
+/** @} */
+
+/** @defgroup BLE_GATTS_DEFAULTS GATT Server defaults
+ * @{
+ */
+#define BLE_GATTS_HVN_TX_QUEUE_SIZE_DEFAULT 1 /**< Default number of Handle Value Notifications that can be queued for transmission. */
+/** @} */
+
+/** @} */
+
+/** @addtogroup BLE_GATTS_STRUCTURES Structures
+ * @{ */
+
+/**
+ * @brief BLE GATTS connection configuration parameters, set with @ref sd_ble_cfg_set.
+ */
+typedef struct
+{
+ uint8_t hvn_tx_queue_size; /**< Minimum guaranteed number of Handle Value Notifications that can be queued for transmission.
+ The default value is @ref BLE_GATTS_HVN_TX_QUEUE_SIZE_DEFAULT */
+} ble_gatts_conn_cfg_t;
+
+/**@brief Attribute metadata. */
+typedef struct
+{
+ ble_gap_conn_sec_mode_t read_perm; /**< Read permissions. */
+ ble_gap_conn_sec_mode_t write_perm; /**< Write permissions. */
+ uint8_t vlen :1; /**< Variable length attribute. */
+ uint8_t vloc :2; /**< Value location, see @ref BLE_GATTS_VLOCS.*/
+ uint8_t rd_auth :1; /**< Read authorization and value will be requested from the application on every read operation. */
+ uint8_t wr_auth :1; /**< Write authorization will be requested from the application on every Write Request operation (but not Write Command). */
+} ble_gatts_attr_md_t;
+
+
+/**@brief GATT Attribute. */
+typedef struct
+{
+ ble_uuid_t const *p_uuid; /**< Pointer to the attribute UUID. */
+ ble_gatts_attr_md_t const *p_attr_md; /**< Pointer to the attribute metadata structure. */
+ uint16_t init_len; /**< Initial attribute value length in bytes. */
+ uint16_t init_offs; /**< Initial attribute value offset in bytes. If different from zero, the first init_offs bytes of the attribute value will be left uninitialized. */
+ uint16_t max_len; /**< Maximum attribute value length in bytes, see @ref BLE_GATTS_ATTR_LENS_MAX for maximum values. */
+ uint8_t *p_value; /**< Pointer to the attribute data. Please note that if the @ref BLE_GATTS_VLOC_USER value location is selected in the attribute metadata, this will have to point to a buffer
+ that remains valid through the lifetime of the attribute. This excludes usage of automatic variables that may go out of scope or any other temporary location.
+ The stack may access that memory directly without the application's knowledge. For writable characteristics, this value must not be a location in flash memory.*/
+} ble_gatts_attr_t;
+
+/**@brief GATT Attribute Value. */
+typedef struct
+{
+ uint16_t len; /**< Length in bytes to be written or read. Length in bytes written or read after successful return.*/
+ uint16_t offset; /**< Attribute value offset. */
+ uint8_t *p_value; /**< Pointer to where value is stored or will be stored.
+ If value is stored in user memory, only the attribute length is updated when p_value == NULL.
+ Set to NULL when reading to obtain the complete length of the attribute value */
+} ble_gatts_value_t;
+
+
+/**@brief GATT Characteristic Presentation Format. */
+typedef struct
+{
+ uint8_t format; /**< Format of the value, see @ref BLE_GATT_CPF_FORMATS. */
+ int8_t exponent; /**< Exponent for integer data types. */
+ uint16_t unit; /**< Unit from Bluetooth Assigned Numbers. */
+ uint8_t name_space; /**< Namespace from Bluetooth Assigned Numbers, see @ref BLE_GATT_CPF_NAMESPACES. */
+ uint16_t desc; /**< Namespace description from Bluetooth Assigned Numbers, see @ref BLE_GATT_CPF_NAMESPACES. */
+} ble_gatts_char_pf_t;
+
+
+/**@brief GATT Characteristic metadata. */
+typedef struct
+{
+ ble_gatt_char_props_t char_props; /**< Characteristic Properties. */
+ ble_gatt_char_ext_props_t char_ext_props; /**< Characteristic Extended Properties. */
+ uint8_t const *p_char_user_desc; /**< Pointer to a UTF-8 encoded string (non-NULL terminated), NULL if the descriptor is not required. */
+ uint16_t char_user_desc_max_size; /**< The maximum size in bytes of the user description descriptor. */
+ uint16_t char_user_desc_size; /**< The size of the user description, must be smaller or equal to char_user_desc_max_size. */
+ ble_gatts_char_pf_t const *p_char_pf; /**< Pointer to a presentation format structure or NULL if the CPF descriptor is not required. */
+ ble_gatts_attr_md_t const *p_user_desc_md; /**< Attribute metadata for the User Description descriptor, or NULL for default values. */
+ ble_gatts_attr_md_t const *p_cccd_md; /**< Attribute metadata for the Client Characteristic Configuration Descriptor, or NULL for default values. */
+ ble_gatts_attr_md_t const *p_sccd_md; /**< Attribute metadata for the Server Characteristic Configuration Descriptor, or NULL for default values. */
+} ble_gatts_char_md_t;
+
+
+/**@brief GATT Characteristic Definition Handles. */
+typedef struct
+{
+ uint16_t value_handle; /**< Handle to the characteristic value. */
+ uint16_t user_desc_handle; /**< Handle to the User Description descriptor, or @ref BLE_GATT_HANDLE_INVALID if not present. */
+ uint16_t cccd_handle; /**< Handle to the Client Characteristic Configuration Descriptor, or @ref BLE_GATT_HANDLE_INVALID if not present. */
+ uint16_t sccd_handle; /**< Handle to the Server Characteristic Configuration Descriptor, or @ref BLE_GATT_HANDLE_INVALID if not present. */
+} ble_gatts_char_handles_t;
+
+
+/**@brief GATT HVx parameters. */
+typedef struct
+{
+ uint16_t handle; /**< Characteristic Value Handle. */
+ uint8_t type; /**< Indication or Notification, see @ref BLE_GATT_HVX_TYPES. */
+ uint16_t offset; /**< Offset within the attribute value. */
+ uint16_t *p_len; /**< Length in bytes to be written, length in bytes written after return. */
+ uint8_t const *p_data; /**< Actual data content, use NULL to use the current attribute value. */
+} ble_gatts_hvx_params_t;
+
+/**@brief GATT Authorization parameters. */
+typedef struct
+{
+ uint16_t gatt_status; /**< GATT status code for the operation, see @ref BLE_GATT_STATUS_CODES. */
+ uint8_t update : 1; /**< If set, data supplied in p_data will be used to update the attribute value.
+ Please note that for @ref BLE_GATTS_AUTHORIZE_TYPE_WRITE operations this bit must always be set,
+ as the data to be written needs to be stored and later provided by the application. */
+ uint16_t offset; /**< Offset of the attribute value being updated. */
+ uint16_t len; /**< Length in bytes of the value in p_data pointer, see @ref BLE_GATTS_ATTR_LENS_MAX. */
+ uint8_t const *p_data; /**< Pointer to new value used to update the attribute value. */
+} ble_gatts_authorize_params_t;
+
+/**@brief GATT Read or Write Authorize Reply parameters. */
+typedef struct
+{
+ uint8_t type; /**< Type of authorize operation, see @ref BLE_GATTS_AUTHORIZE_TYPES. */
+ union {
+ ble_gatts_authorize_params_t read; /**< Read authorization parameters. */
+ ble_gatts_authorize_params_t write; /**< Write authorization parameters. */
+ } params; /**< Reply Parameters. */
+} ble_gatts_rw_authorize_reply_params_t;
+
+/**@brief Service Changed Inclusion configuration parameters, set with @ref sd_ble_cfg_set. */
+typedef struct
+{
+ uint8_t service_changed : 1; /**< If 1, include the Service Changed characteristic in the Attribute Table. Default is @ref BLE_GATTS_SERVICE_CHANGED_DEFAULT. */
+} ble_gatts_cfg_service_changed_t;
+
+/**@brief Attribute table size configuration parameters, set with @ref sd_ble_cfg_set.
+ *
+ * @retval ::NRF_ERROR_INVALID_LENGTH One or more of the following is true:
+ * - The specified Attribute Table size is too small.
+ * The minimum acceptable size is defined by @ref BLE_GATTS_ATTR_TAB_SIZE_MIN.
+ * - The specified Attribute Table size is not a multiple of 4.
+ */
+typedef struct
+{
+ uint32_t attr_tab_size; /**< Attribute table size. Default is @ref BLE_GATTS_ATTR_TAB_SIZE_DEFAULT, minimum is @ref BLE_GATTS_ATTR_TAB_SIZE_MIN. */
+} ble_gatts_cfg_attr_tab_size_t;
+
+/**@brief Config structure for GATTS configurations. */
+typedef union
+{
+ ble_gatts_cfg_service_changed_t service_changed; /**< Include service changed characteristic, cfg_id is @ref BLE_GATTS_CFG_SERVICE_CHANGED. */
+ ble_gatts_cfg_attr_tab_size_t attr_tab_size; /**< Attribute table size, cfg_id is @ref BLE_GATTS_CFG_ATTR_TAB_SIZE. */
+} ble_gatts_cfg_t;
+
+
+/**@brief Event structure for @ref BLE_GATTS_EVT_WRITE. */
+typedef struct
+{
+ uint16_t handle; /**< Attribute Handle. */
+ ble_uuid_t uuid; /**< Attribute UUID. */
+ uint8_t op; /**< Type of write operation, see @ref BLE_GATTS_OPS. */
+ uint8_t auth_required; /**< Writing operation deferred due to authorization requirement. Application may use @ref sd_ble_gatts_value_set to finalize the writing operation. */
+ uint16_t offset; /**< Offset for the write operation. */
+ uint16_t len; /**< Length of the received data. */
+ uint8_t data[1]; /**< Received data. @note This is a variable length array. The size of 1 indicated is only a placeholder for compilation.
+ See @ref sd_ble_evt_get for more information on how to use event structures with variable length array members. */
+} ble_gatts_evt_write_t;
+
+/**@brief Event substructure for authorized read requests, see @ref ble_gatts_evt_rw_authorize_request_t. */
+typedef struct
+{
+ uint16_t handle; /**< Attribute Handle. */
+ ble_uuid_t uuid; /**< Attribute UUID. */
+ uint16_t offset; /**< Offset for the read operation. */
+} ble_gatts_evt_read_t;
+
+/**@brief Event structure for @ref BLE_GATTS_EVT_RW_AUTHORIZE_REQUEST. */
+typedef struct
+{
+ uint8_t type; /**< Type of authorize operation, see @ref BLE_GATTS_AUTHORIZE_TYPES. */
+ union {
+ ble_gatts_evt_read_t read; /**< Attribute Read Parameters. */
+ ble_gatts_evt_write_t write; /**< Attribute Write Parameters. */
+ } request; /**< Request Parameters. */
+} ble_gatts_evt_rw_authorize_request_t;
+
+/**@brief Event structure for @ref BLE_GATTS_EVT_SYS_ATTR_MISSING. */
+typedef struct
+{
+ uint8_t hint; /**< Hint (currently unused). */
+} ble_gatts_evt_sys_attr_missing_t;
+
+
+/**@brief Event structure for @ref BLE_GATTS_EVT_HVC. */
+typedef struct
+{
+ uint16_t handle; /**< Attribute Handle. */
+} ble_gatts_evt_hvc_t;
+
+/**@brief Event structure for @ref BLE_GATTS_EVT_EXCHANGE_MTU_REQUEST. */
+typedef struct
+{
+ uint16_t client_rx_mtu; /**< Client RX MTU size. */
+} ble_gatts_evt_exchange_mtu_request_t;
+
+/**@brief Event structure for @ref BLE_GATTS_EVT_TIMEOUT. */
+typedef struct
+{
+ uint8_t src; /**< Timeout source, see @ref BLE_GATT_TIMEOUT_SOURCES. */
+} ble_gatts_evt_timeout_t;
+
+/**@brief Event structure for @ref BLE_GATTS_EVT_HVN_TX_COMPLETE. */
+typedef struct
+{
+ uint8_t count; /**< Number of notification transmissions completed. */
+} ble_gatts_evt_hvn_tx_complete_t;
+
+/**@brief GATTS event structure. */
+typedef struct
+{
+ uint16_t conn_handle; /**< Connection Handle on which the event occurred. */
+ union
+ {
+ ble_gatts_evt_write_t write; /**< Write Event Parameters. */
+ ble_gatts_evt_rw_authorize_request_t authorize_request; /**< Read or Write Authorize Request Parameters. */
+ ble_gatts_evt_sys_attr_missing_t sys_attr_missing; /**< System attributes missing. */
+ ble_gatts_evt_hvc_t hvc; /**< Handle Value Confirmation Event Parameters. */
+ ble_gatts_evt_exchange_mtu_request_t exchange_mtu_request; /**< Exchange MTU Request Event Parameters. */
+ ble_gatts_evt_timeout_t timeout; /**< Timeout Event. */
+ ble_gatts_evt_hvn_tx_complete_t hvn_tx_complete; /**< Handle Value Notification transmission complete Event Parameters. */
+ } params; /**< Event Parameters. */
+} ble_gatts_evt_t;
+
+/** @} */
+
+/** @addtogroup BLE_GATTS_FUNCTIONS Functions
+ * @{ */
+
+/**@brief Add a service declaration to the Attribute Table.
+ *
+ * @note Secondary Services are only relevant in the context of the entity that references them, it is therefore forbidden to
+ * add a secondary service declaration that is not referenced by another service later in the Attribute Table.
+ *
+ * @mscs
+ * @mmsc{@ref BLE_GATTS_ATT_TABLE_POP_MSC}
+ * @endmscs
+ *
+ * @param[in] type Toggles between primary and secondary services, see @ref BLE_GATTS_SRVC_TYPES.
+ * @param[in] p_uuid Pointer to service UUID.
+ * @param[out] p_handle Pointer to a 16-bit word where the assigned handle will be stored.
+ *
+ * @retval ::NRF_SUCCESS Successfully added a service declaration.
+ * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied.
+ * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied, Vendor Specific UUIDs need to be present in the table.
+ * @retval ::NRF_ERROR_FORBIDDEN Forbidden value supplied, certain UUIDs are reserved for the stack.
+ * @retval ::NRF_ERROR_NO_MEM Not enough memory to complete operation.
+ */
+SVCALL(SD_BLE_GATTS_SERVICE_ADD, uint32_t, sd_ble_gatts_service_add(uint8_t type, ble_uuid_t const *p_uuid, uint16_t *p_handle));
+
+
+/**@brief Add an include declaration to the Attribute Table.
+ *
+ * @note It is currently only possible to add an include declaration to the last added service (i.e. only sequential population is supported at this time).
+ *
+ * @note The included service must already be present in the Attribute Table prior to this call.
+ *
+ * @mscs
+ * @mmsc{@ref BLE_GATTS_ATT_TABLE_POP_MSC}
+ * @endmscs
+ *
+ * @param[in] service_handle Handle of the service where the included service is to be placed, if @ref BLE_GATT_HANDLE_INVALID is used, it will be placed sequentially.
+ * @param[in] inc_srvc_handle Handle of the included service.
+ * @param[out] p_include_handle Pointer to a 16-bit word where the assigned handle will be stored.
+ *
+ * @retval ::NRF_SUCCESS Successfully added an include declaration.
+ * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied.
+ * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied, handle values need to match previously added services.
+ * @retval ::NRF_ERROR_INVALID_STATE Invalid state to perform operation.
+ * @retval ::NRF_ERROR_NOT_SUPPORTED Feature is not supported, service_handle must be that of the last added service.
+ * @retval ::NRF_ERROR_FORBIDDEN Forbidden value supplied, self inclusions are not allowed.
+ * @retval ::NRF_ERROR_NO_MEM Not enough memory to complete operation.
+ * @retval ::NRF_ERROR_NOT_FOUND Attribute not found.
+ */
+SVCALL(SD_BLE_GATTS_INCLUDE_ADD, uint32_t, sd_ble_gatts_include_add(uint16_t service_handle, uint16_t inc_srvc_handle, uint16_t *p_include_handle));
+
+
+/**@brief Add a characteristic declaration, a characteristic value declaration and optional characteristic descriptor declarations to the Attribute Table.
+ *
+ * @note It is currently only possible to add a characteristic to the last added service (i.e. only sequential population is supported at this time).
+ *
+ * @note Several restrictions apply to the parameters, such as matching permissions between the user description descriptor and the writable auxiliaries bits,
+ * readable (no security) and writable (selectable) CCCDs and SCCDs and valid presentation format values.
+ *
+ * @note If no metadata is provided for the optional descriptors, their permissions will be derived from the characteristic permissions.
+ *
+ * @mscs
+ * @mmsc{@ref BLE_GATTS_ATT_TABLE_POP_MSC}
+ * @endmscs
+ *
+ * @param[in] service_handle Handle of the service where the characteristic is to be placed, if @ref BLE_GATT_HANDLE_INVALID is used, it will be placed sequentially.
+ * @param[in] p_char_md Characteristic metadata.
+ * @param[in] p_attr_char_value Pointer to the attribute structure corresponding to the characteristic value.
+ * @param[out] p_handles Pointer to the structure where the assigned handles will be stored.
+ *
+ * @retval ::NRF_SUCCESS Successfully added a characteristic.
+ * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied.
+ * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied, service handle, Vendor Specific UUIDs, lengths, and permissions need to adhere to the constraints.
+ * @retval ::NRF_ERROR_INVALID_STATE Invalid state to perform operation, a service context is required.
+ * @retval ::NRF_ERROR_FORBIDDEN Forbidden value supplied, certain UUIDs are reserved for the stack.
+ * @retval ::NRF_ERROR_NO_MEM Not enough memory to complete operation.
+ * @retval ::NRF_ERROR_DATA_SIZE Invalid data size(s) supplied, attribute lengths are restricted by @ref BLE_GATTS_ATTR_LENS_MAX.
+ */
+SVCALL(SD_BLE_GATTS_CHARACTERISTIC_ADD, uint32_t, sd_ble_gatts_characteristic_add(uint16_t service_handle, ble_gatts_char_md_t const *p_char_md, ble_gatts_attr_t const *p_attr_char_value, ble_gatts_char_handles_t *p_handles));
+
+
+/**@brief Add a descriptor to the Attribute Table.
+ *
+ * @note It is currently only possible to add a descriptor to the last added characteristic (i.e. only sequential population is supported at this time).
+ *
+ * @mscs
+ * @mmsc{@ref BLE_GATTS_ATT_TABLE_POP_MSC}
+ * @endmscs
+ *
+ * @param[in] char_handle Handle of the characteristic where the descriptor is to be placed, if @ref BLE_GATT_HANDLE_INVALID is used, it will be placed sequentially.
+ * @param[in] p_attr Pointer to the attribute structure.
+ * @param[out] p_handle Pointer to a 16-bit word where the assigned handle will be stored.
+ *
+ * @retval ::NRF_SUCCESS Successfully added a descriptor.
+ * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied.
+ * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied, characteristic handle, Vendor Specific UUIDs, lengths, and permissions need to adhere to the constraints.
+ * @retval ::NRF_ERROR_INVALID_STATE Invalid state to perform operation, a characteristic context is required.
+ * @retval ::NRF_ERROR_FORBIDDEN Forbidden value supplied, certain UUIDs are reserved for the stack.
+ * @retval ::NRF_ERROR_NO_MEM Not enough memory to complete operation.
+ * @retval ::NRF_ERROR_DATA_SIZE Invalid data size(s) supplied, attribute lengths are restricted by @ref BLE_GATTS_ATTR_LENS_MAX.
+ */
+SVCALL(SD_BLE_GATTS_DESCRIPTOR_ADD, uint32_t, sd_ble_gatts_descriptor_add(uint16_t char_handle, ble_gatts_attr_t const *p_attr, uint16_t *p_handle));
+
+/**@brief Set the value of a given attribute.
+ *
+ * @note Values other than system attributes can be set at any time, regardless of whether any active connections exist.
+ *
+ * @mscs
+ * @mmsc{@ref BLE_GATTS_QUEUED_WRITE_QUEUE_FULL_MSC}
+ * @mmsc{@ref BLE_GATTS_QUEUED_WRITE_NOBUF_NOAUTH_MSC}
+ * @endmscs
+ *
+ * @param[in] conn_handle Connection handle. Ignored if the value does not belong to a system attribute.
+ * @param[in] handle Attribute handle.
+ * @param[in,out] p_value Attribute value information.
+ *
+ * @retval ::NRF_SUCCESS Successfully set the value of the attribute.
+ * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied.
+ * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied.
+ * @retval ::NRF_ERROR_NOT_FOUND Attribute not found.
+ * @retval ::NRF_ERROR_FORBIDDEN Forbidden handle supplied, certain attributes are not modifiable by the application.
+ * @retval ::NRF_ERROR_DATA_SIZE Invalid data size(s) supplied, attribute lengths are restricted by @ref BLE_GATTS_ATTR_LENS_MAX.
+ * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid connection handle supplied on a system attribute.
+ */
+SVCALL(SD_BLE_GATTS_VALUE_SET, uint32_t, sd_ble_gatts_value_set(uint16_t conn_handle, uint16_t handle, ble_gatts_value_t *p_value));
+
+/**@brief Get the value of a given attribute.
+ *
+ * @note If the attribute value is longer than the size of the supplied buffer,
+ * @ref ble_gatts_value_t::len will return the total attribute value length (excluding offset),
+ * and not the number of bytes actually returned in @ref ble_gatts_value_t::p_value.
+ * The application may use this information to allocate a suitable buffer size.
+ *
+ * @note When retrieving system attribute values with this function, the connection handle
+ * may refer to an already disconnected connection. Refer to the documentation of
+ * @ref sd_ble_gatts_sys_attr_get for further information.
+ *
+ * @param[in] conn_handle Connection handle. Ignored if the value does not belong to a system attribute.
+ * @param[in] handle Attribute handle.
+ * @param[in,out] p_value Attribute value information.
+ *
+ * @retval ::NRF_SUCCESS Successfully retrieved the value of the attribute.
+ * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied.
+ * @retval ::NRF_ERROR_NOT_FOUND Attribute not found.
+ * @retval ::NRF_ERROR_INVALID_PARAM Invalid attribute offset supplied.
+ * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid connection handle supplied on a system attribute.
+ * @retval ::BLE_ERROR_GATTS_SYS_ATTR_MISSING System attributes missing, use @ref sd_ble_gatts_sys_attr_set to set them to a known value.
+ */
+SVCALL(SD_BLE_GATTS_VALUE_GET, uint32_t, sd_ble_gatts_value_get(uint16_t conn_handle, uint16_t handle, ble_gatts_value_t *p_value));
+
+/**@brief Notify or Indicate an attribute value.
+ *
+ * @details This function checks for the relevant Client Characteristic Configuration descriptor value to verify that the relevant operation
+ * (notification or indication) has been enabled by the client. It is also able to update the attribute value before issuing the PDU, so that
+ * the application can atomically perform a value update and a server initiated transaction with a single API call.
+ *
+ * @note The local attribute value may be updated even if an outgoing packet is not sent to the peer due to an error during execution.
+ * The Attribute Table has been updated if one of the following error codes is returned: @ref NRF_ERROR_INVALID_STATE, @ref NRF_ERROR_BUSY,
+ * @ref NRF_ERROR_FORBIDDEN, @ref BLE_ERROR_GATTS_SYS_ATTR_MISSING and @ref NRF_ERROR_RESOURCES.
+ * The caller can check whether the value has been updated by looking at the contents of *(@ref ble_gatts_hvx_params_t::p_len).
+ *
+ * @note Only one indication procedure can be ongoing per connection at a time.
+ * If the application tries to indicate an attribute value while another indication procedure is ongoing,
+ * the function call will return @ref NRF_ERROR_BUSY.
+ * A @ref BLE_GATTS_EVT_HVC event will be issued as soon as the confirmation arrives from the peer.
+ *
+ * @note The number of Handle Value Notifications that can be queued is configured by @ref ble_gatts_conn_cfg_t::hvn_tx_queue_size
+ * When the queue is full, the function call will return @ref NRF_ERROR_RESOURCES.
+ * A @ref BLE_GATTS_EVT_HVN_TX_COMPLETE event will be issued as soon as the transmission of the notification is complete.
+ *
+ * @note The application can keep track of the available queue element count for notifications by following the procedure below:
+ * - Store initial queue element count in a variable.
+ * - Decrement the variable, which stores the currently available queue element count, by one when a call to this function returns @ref NRF_SUCCESS.
+ * - Increment the variable, which stores the current available queue element count, by the count variable in @ref BLE_GATTS_EVT_HVN_TX_COMPLETE event.
+ *
+ * @events
+ * @event{@ref BLE_GATTS_EVT_HVN_TX_COMPLETE, Notification transmission complete.}
+ * @event{@ref BLE_GATTS_EVT_HVC, Confirmation received from the peer.}
+ * @endevents
+ *
+ * @mscs
+ * @mmsc{@ref BLE_GATTS_HVX_SYS_ATTRS_MISSING_MSC}
+ * @mmsc{@ref BLE_GATTS_HVN_MSC}
+ * @mmsc{@ref BLE_GATTS_HVI_MSC}
+ * @mmsc{@ref BLE_GATTS_HVX_DISABLED_MSC}
+ * @endmscs
+ *
+ * @param[in] conn_handle Connection handle.
+ * @param[in,out] p_hvx_params Pointer to an HVx parameters structure. If @ref ble_gatts_hvx_params_t::p_data
+ * contains a non-NULL pointer the attribute value will be updated with the contents
+ * pointed by it before sending the notification or indication. If the attribute value
+ * is updated, @ref ble_gatts_hvx_params_t::p_len is updated by the SoftDevice to
+ * contain the number of actual bytes written, else it will be set to 0.
+ *
+ * @retval ::NRF_SUCCESS Successfully queued a notification or indication for transmission, and optionally updated the attribute value.
+ * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid Connection Handle.
+ * @retval ::NRF_ERROR_INVALID_STATE One or more of the following is true:
+ * - Invalid Connection State
+ * - Notifications and/or indications not enabled in the CCCD
+ * - An ATT_MTU exchange is ongoing
+ * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied.
+ * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied.
+ * @retval ::BLE_ERROR_INVALID_ATTR_HANDLE Invalid attribute handle(s) supplied. Only attributes added directly by the application are available to notify and indicate.
+ * @retval ::BLE_ERROR_GATTS_INVALID_ATTR_TYPE Invalid attribute type(s) supplied, only characteristic values may be notified and indicated.
+ * @retval ::NRF_ERROR_NOT_FOUND Attribute not found.
+ * @retval ::NRF_ERROR_FORBIDDEN The connection's current security level is lower than the one required by the write permissions of the CCCD associated with this characteristic.
+ * @retval ::NRF_ERROR_DATA_SIZE Invalid data size(s) supplied.
+ * @retval ::NRF_ERROR_BUSY For @ref BLE_GATT_HVX_INDICATION Procedure already in progress. Wait for a @ref BLE_GATTS_EVT_HVC event and retry.
+ * @retval ::BLE_ERROR_GATTS_SYS_ATTR_MISSING System attributes missing, use @ref sd_ble_gatts_sys_attr_set to set them to a known value.
+ * @retval ::NRF_ERROR_RESOURCES Too many notifications queued.
+ * Wait for a @ref BLE_GATTS_EVT_HVN_TX_COMPLETE event and retry.
+ * @retval ::NRF_ERROR_TIMEOUT There has been a GATT procedure timeout. No new GATT procedure can be performed without reestablishing the connection.
+ */
+SVCALL(SD_BLE_GATTS_HVX, uint32_t, sd_ble_gatts_hvx(uint16_t conn_handle, ble_gatts_hvx_params_t const *p_hvx_params));
+
+/**@brief Indicate the Service Changed attribute value.
+ *
+ * @details This call will send a Handle Value Indication to one or more peers connected to inform them that the Attribute
+ * Table layout has changed. As soon as the peer has confirmed the indication, a @ref BLE_GATTS_EVT_SC_CONFIRM event will
+ * be issued.
+ *
+ * @note Some of the restrictions and limitations that apply to @ref sd_ble_gatts_hvx also apply here.
+ *
+ * @events
+ * @event{@ref BLE_GATTS_EVT_SC_CONFIRM, Confirmation of attribute table change received from peer.}
+ * @endevents
+ *
+ * @mscs
+ * @mmsc{@ref BLE_GATTS_SC_MSC}
+ * @endmscs
+ *
+ * @param[in] conn_handle Connection handle.
+ * @param[in] start_handle Start of affected attribute handle range.
+ * @param[in] end_handle End of affected attribute handle range.
+ *
+ * @retval ::NRF_SUCCESS Successfully queued the Service Changed indication for transmission.
+ * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid Connection Handle.
+ * @retval ::NRF_ERROR_NOT_SUPPORTED Service Changed not enabled at initialization. See @ref
+ * sd_ble_cfg_set and @ref ble_gatts_cfg_service_changed_t.
+ * @retval ::NRF_ERROR_INVALID_STATE One or more of the following is true:
+ * - Invalid Connection State
+ * - Notifications and/or indications not enabled in the CCCD
+ * - An ATT_MTU exchange is ongoing
+ * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied.
+ * @retval ::BLE_ERROR_INVALID_ATTR_HANDLE Invalid attribute handle(s) supplied, handles must be in the range populated by the application.
+ * @retval ::NRF_ERROR_BUSY Procedure already in progress.
+ * @retval ::BLE_ERROR_GATTS_SYS_ATTR_MISSING System attributes missing, use @ref sd_ble_gatts_sys_attr_set to set them to a known value.
+ * @retval ::NRF_ERROR_TIMEOUT There has been a GATT procedure timeout. No new GATT procedure can be performed without reestablishing the connection.
+ */
+SVCALL(SD_BLE_GATTS_SERVICE_CHANGED, uint32_t, sd_ble_gatts_service_changed(uint16_t conn_handle, uint16_t start_handle, uint16_t end_handle));
+
+/**@brief Respond to a Read/Write authorization request.
+ *
+ * @note This call should only be used as a response to a @ref BLE_GATTS_EVT_RW_AUTHORIZE_REQUEST event issued to the application.
+ *
+ * @mscs
+ * @mmsc{@ref BLE_GATTS_QUEUED_WRITE_NOBUF_AUTH_MSC}
+ * @mmsc{@ref BLE_GATTS_QUEUED_WRITE_BUF_AUTH_MSC}
+ * @mmsc{@ref BLE_GATTS_QUEUED_WRITE_NOBUF_NOAUTH_MSC}
+ * @mmsc{@ref BLE_GATTS_READ_REQ_AUTH_MSC}
+ * @mmsc{@ref BLE_GATTS_WRITE_REQ_AUTH_MSC}
+ * @mmsc{@ref BLE_GATTS_QUEUED_WRITE_QUEUE_FULL_MSC}
+ * @mmsc{@ref BLE_GATTS_QUEUED_WRITE_PEER_CANCEL_MSC}
+ * @endmscs
+ *
+ * @param[in] conn_handle Connection handle.
+ * @param[in] p_rw_authorize_reply_params Pointer to a structure with the attribute provided by the application.
+ *
+ * @note @ref ble_gatts_authorize_params_t::p_data is ignored when this function is used to respond
+ * to a @ref BLE_GATTS_AUTHORIZE_TYPE_READ event if @ref ble_gatts_authorize_params_t::update
+ * is set to 0.
+ *
+ * @retval ::NRF_SUCCESS Successfully queued a response to the peer, and in the case of a write operation, Attribute Table updated.
+ * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid Connection Handle.
+ * @retval ::NRF_ERROR_BUSY The stack is busy, process pending events and retry.
+ * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied.
+ * @retval ::NRF_ERROR_INVALID_STATE Invalid Connection State or no authorization request pending.
+ * @retval ::NRF_ERROR_INVALID_PARAM Authorization op invalid,
+ * handle supplied does not match requested handle,
+ * or invalid data to be written provided by the application.
+ * @retval ::NRF_ERROR_TIMEOUT There has been a GATT procedure timeout. No new GATT procedure can be performed without reestablishing the connection.
+ */
+SVCALL(SD_BLE_GATTS_RW_AUTHORIZE_REPLY, uint32_t, sd_ble_gatts_rw_authorize_reply(uint16_t conn_handle, ble_gatts_rw_authorize_reply_params_t const *p_rw_authorize_reply_params));
+
+
+/**@brief Update persistent system attribute information.
+ *
+ * @details Supply information about persistent system attributes to the stack,
+ * previously obtained using @ref sd_ble_gatts_sys_attr_get.
+ * This call is only allowed for active connections, and is usually
+ * made immediately after a connection is established with an known bonded device,
+ * often as a response to a @ref BLE_GATTS_EVT_SYS_ATTR_MISSING.
+ *
+ * p_sysattrs may point directly to the application's stored copy of the system attributes
+ * obtained using @ref sd_ble_gatts_sys_attr_get.
+ * If the pointer is NULL, the system attribute info is initialized, assuming that
+ * the application does not have any previously saved system attribute data for this device.
+ *
+ * @note The state of persistent system attributes is reset upon connection establishment and then remembered for its duration.
+ *
+ * @note If this call returns with an error code different from @ref NRF_SUCCESS, the storage of persistent system attributes may have been completed only partially.
+ * This means that the state of the attribute table is undefined, and the application should either provide a new set of attributes using this same call or
+ * reset the SoftDevice to return to a known state.
+ *
+ * @note When the @ref BLE_GATTS_SYS_ATTR_FLAG_SYS_SRVCS is used with this function, only the system attributes included in system services will be modified.
+ * @note When the @ref BLE_GATTS_SYS_ATTR_FLAG_USR_SRVCS is used with this function, only the system attributes included in user services will be modified.
+ *
+ * @mscs
+ * @mmsc{@ref BLE_GATTS_HVX_SYS_ATTRS_MISSING_MSC}
+ * @mmsc{@ref BLE_GATTS_SYS_ATTRS_UNK_PEER_MSC}
+ * @mmsc{@ref BLE_GATTS_SYS_ATTRS_BONDED_PEER_MSC}
+ * @endmscs
+ *
+ * @param[in] conn_handle Connection handle.
+ * @param[in] p_sys_attr_data Pointer to a saved copy of system attributes supplied to the stack, or NULL.
+ * @param[in] len Size of data pointed by p_sys_attr_data, in octets.
+ * @param[in] flags Optional additional flags, see @ref BLE_GATTS_SYS_ATTR_FLAGS
+ *
+ * @retval ::NRF_SUCCESS Successfully set the system attribute information.
+ * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid Connection Handle.
+ * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied.
+ * @retval ::NRF_ERROR_INVALID_STATE Invalid Connection State.
+ * @retval ::NRF_ERROR_INVALID_PARAM Invalid flags supplied.
+ * @retval ::NRF_ERROR_INVALID_DATA Invalid data supplied, the data should be exactly the same as retrieved with @ref sd_ble_gatts_sys_attr_get.
+ * @retval ::NRF_ERROR_NO_MEM Not enough memory to complete operation.
+ */
+SVCALL(SD_BLE_GATTS_SYS_ATTR_SET, uint32_t, sd_ble_gatts_sys_attr_set(uint16_t conn_handle, uint8_t const *p_sys_attr_data, uint16_t len, uint32_t flags));
+
+
+/**@brief Retrieve persistent system attribute information from the stack.
+ *
+ * @details This call is used to retrieve information about values to be stored persistently by the application
+ * during the lifetime of a connection or after it has been terminated. When a new connection is established with the same bonded device,
+ * the system attribute information retrieved with this function should be restored using using @ref sd_ble_gatts_sys_attr_set.
+ * If retrieved after disconnection, the data should be read before a new connection established. The connection handle for
+ * the previous, now disconnected, connection will remain valid until a new one is created to allow this API call to refer to it.
+ * Connection handles belonging to active connections can be used as well, but care should be taken since the system attributes
+ * may be written to at any time by the peer during a connection's lifetime.
+ *
+ * @note When the @ref BLE_GATTS_SYS_ATTR_FLAG_SYS_SRVCS is used with this function, only the system attributes included in system services will be returned.
+ * @note When the @ref BLE_GATTS_SYS_ATTR_FLAG_USR_SRVCS is used with this function, only the system attributes included in user services will be returned.
+ *
+ * @mscs
+ * @mmsc{@ref BLE_GATTS_SYS_ATTRS_BONDED_PEER_MSC}
+ * @endmscs
+ *
+ * @param[in] conn_handle Connection handle of the recently terminated connection.
+ * @param[out] p_sys_attr_data Pointer to a buffer where updated information about system attributes will be filled in. The format of the data is described
+ * in @ref BLE_GATTS_SYS_ATTRS_FORMAT. NULL can be provided to obtain the length of the data.
+ * @param[in,out] p_len Size of application buffer if p_sys_attr_data is not NULL. Unconditionally updated to actual length of system attribute data.
+ * @param[in] flags Optional additional flags, see @ref BLE_GATTS_SYS_ATTR_FLAGS
+ *
+ * @retval ::NRF_SUCCESS Successfully retrieved the system attribute information.
+ * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid Connection Handle.
+ * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied.
+ * @retval ::NRF_ERROR_INVALID_PARAM Invalid flags supplied.
+ * @retval ::NRF_ERROR_DATA_SIZE The system attribute information did not fit into the provided buffer.
+ * @retval ::NRF_ERROR_NOT_FOUND No system attributes found.
+ */
+SVCALL(SD_BLE_GATTS_SYS_ATTR_GET, uint32_t, sd_ble_gatts_sys_attr_get(uint16_t conn_handle, uint8_t *p_sys_attr_data, uint16_t *p_len, uint32_t flags));
+
+
+/**@brief Retrieve the first valid user attribute handle.
+ *
+ * @param[out] p_handle Pointer to an integer where the handle will be stored.
+ *
+ * @retval ::NRF_SUCCESS Successfully retrieved the handle.
+ * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied.
+ */
+SVCALL(SD_BLE_GATTS_INITIAL_USER_HANDLE_GET, uint32_t, sd_ble_gatts_initial_user_handle_get(uint16_t *p_handle));
+
+/**@brief Retrieve the attribute UUID and/or metadata.
+ *
+ * @param[in] handle Attribute handle
+ * @param[out] p_uuid UUID of the attribute. Use NULL to omit this field.
+ * @param[out] p_md Metadata of the attribute. Use NULL to omit this field.
+ *
+ * @retval ::NRF_SUCCESS Successfully retrieved the attribute metadata,
+ * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied.
+ * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameters supplied. Returned when both @c p_uuid and @c p_md are NULL.
+ * @retval ::NRF_ERROR_NOT_FOUND Attribute was not found.
+ */
+SVCALL(SD_BLE_GATTS_ATTR_GET, uint32_t, sd_ble_gatts_attr_get(uint16_t handle, ble_uuid_t * p_uuid, ble_gatts_attr_md_t * p_md));
+
+/**@brief Reply to an ATT_MTU exchange request by sending an Exchange MTU Response to the client.
+ *
+ * @details This function is only used to reply to a @ref BLE_GATTS_EVT_EXCHANGE_MTU_REQUEST event.
+ *
+ * @details The SoftDevice sets ATT_MTU to the minimum of:
+ * - The Client RX MTU value from @ref BLE_GATTS_EVT_EXCHANGE_MTU_REQUEST, and
+ * - The Server RX MTU value.
+ *
+ * However, the SoftDevice never sets ATT_MTU lower than @ref BLE_GATT_ATT_MTU_DEFAULT.
+ *
+ * @mscs
+ * @mmsc{@ref BLE_GATTS_MTU_EXCHANGE}
+ * @endmscs
+ *
+ * @param[in] conn_handle The connection handle identifying the connection to perform this procedure on.
+ * @param[in] server_rx_mtu Server RX MTU size.
+ * - The minimum value is @ref BLE_GATT_ATT_MTU_DEFAULT.
+ * - The maximum value is @ref ble_gatt_conn_cfg_t::att_mtu in the connection configuration
+ * used for this connection.
+ * - The value must be equal to Client RX MTU size given in @ref sd_ble_gattc_exchange_mtu_request
+ * if an ATT_MTU exchange has already been performed in the other direction.
+ *
+ * @retval ::NRF_SUCCESS Successfully sent response to the client.
+ * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid Connection Handle.
+ * @retval ::NRF_ERROR_INVALID_STATE Invalid Connection State or no ATT_MTU exchange request pending.
+ * @retval ::NRF_ERROR_INVALID_PARAM Invalid Server RX MTU size supplied.
+ * @retval ::NRF_ERROR_TIMEOUT There has been a GATT procedure timeout. No new GATT procedure can be performed without reestablishing the connection.
+ */
+SVCALL(SD_BLE_GATTS_EXCHANGE_MTU_REPLY, uint32_t, sd_ble_gatts_exchange_mtu_reply(uint16_t conn_handle, uint16_t server_rx_mtu));
+/** @} */
+
+#ifdef __cplusplus
+}
+#endif
+#endif // BLE_GATTS_H__
+
+/**
+ @}
+*/
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/softdevice/s112/headers/ble_hci.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/softdevice/s112/headers/ble_hci.h
new file mode 100644
index 0000000..f0dde9a
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/softdevice/s112/headers/ble_hci.h
@@ -0,0 +1,135 @@
+/*
+ * Copyright (c) 2012 - 2017, 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ */
+
+/**
+ @addtogroup BLE_COMMON
+ @{
+*/
+
+
+#ifndef BLE_HCI_H__
+#define BLE_HCI_H__
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** @defgroup BLE_HCI_STATUS_CODES Bluetooth status codes
+ * @{ */
+
+#define BLE_HCI_STATUS_CODE_SUCCESS 0x00 /**< Success. */
+#define BLE_HCI_STATUS_CODE_UNKNOWN_BTLE_COMMAND 0x01 /**< Unknown BLE Command. */
+#define BLE_HCI_STATUS_CODE_UNKNOWN_CONNECTION_IDENTIFIER 0x02 /**< Unknown Connection Identifier. */
+/*0x03 Hardware Failure
+0x04 Page Timeout
+*/
+#define BLE_HCI_AUTHENTICATION_FAILURE 0x05 /**< Authentication Failure. */
+#define BLE_HCI_STATUS_CODE_PIN_OR_KEY_MISSING 0x06 /**< Pin or Key missing. */
+#define BLE_HCI_MEMORY_CAPACITY_EXCEEDED 0x07 /**< Memory Capacity Exceeded. */
+#define BLE_HCI_CONNECTION_TIMEOUT 0x08 /**< Connection Timeout. */
+/*0x09 Connection Limit Exceeded
+0x0A Synchronous Connection Limit To A Device Exceeded
+0x0B ACL Connection Already Exists*/
+#define BLE_HCI_STATUS_CODE_COMMAND_DISALLOWED 0x0C /**< Command Disallowed. */
+/*0x0D Connection Rejected due to Limited Resources
+0x0E Connection Rejected Due To Security Reasons
+0x0F Connection Rejected due to Unacceptable BD_ADDR
+0x10 Connection Accept Timeout Exceeded
+0x11 Unsupported Feature or Parameter Value*/
+#define BLE_HCI_STATUS_CODE_INVALID_BTLE_COMMAND_PARAMETERS 0x12 /**< Invalid BLE Command Parameters. */
+#define BLE_HCI_REMOTE_USER_TERMINATED_CONNECTION 0x13 /**< Remote User Terminated Connection. */
+#define BLE_HCI_REMOTE_DEV_TERMINATION_DUE_TO_LOW_RESOURCES 0x14 /**< Remote Device Terminated Connection due to low resources.*/
+#define BLE_HCI_REMOTE_DEV_TERMINATION_DUE_TO_POWER_OFF 0x15 /**< Remote Device Terminated Connection due to power off. */
+#define BLE_HCI_LOCAL_HOST_TERMINATED_CONNECTION 0x16 /**< Local Host Terminated Connection. */
+/*
+0x17 Repeated Attempts
+0x18 Pairing Not Allowed
+0x19 Unknown LMP PDU
+*/
+#define BLE_HCI_UNSUPPORTED_REMOTE_FEATURE 0x1A /**< Unsupported Remote Feature. */
+/*
+0x1B SCO Offset Rejected
+0x1C SCO Interval Rejected
+0x1D SCO Air Mode Rejected*/
+#define BLE_HCI_STATUS_CODE_INVALID_LMP_PARAMETERS 0x1E /**< Invalid LMP Parameters. */
+#define BLE_HCI_STATUS_CODE_UNSPECIFIED_ERROR 0x1F /**< Unspecified Error. */
+/*0x20 Unsupported LMP Parameter Value
+0x21 Role Change Not Allowed
+*/
+#define BLE_HCI_STATUS_CODE_LMP_RESPONSE_TIMEOUT 0x22 /**< LMP Response Timeout. */
+#define BLE_HCI_STATUS_CODE_LMP_ERROR_TRANSACTION_COLLISION 0x23 /**< LMP Error Transaction Collision/LL Procedure Collision. */
+#define BLE_HCI_STATUS_CODE_LMP_PDU_NOT_ALLOWED 0x24 /**< LMP PDU Not Allowed. */
+/*0x25 Encryption Mode Not Acceptable
+0x26 Link Key Can Not be Changed
+0x27 Requested QoS Not Supported
+*/
+#define BLE_HCI_INSTANT_PASSED 0x28 /**< Instant Passed. */
+#define BLE_HCI_PAIRING_WITH_UNIT_KEY_UNSUPPORTED 0x29 /**< Pairing with Unit Key Unsupported. */
+#define BLE_HCI_DIFFERENT_TRANSACTION_COLLISION 0x2A /**< Different Transaction Collision. */
+/*
+0x2B Reserved
+0x2C QoS Unacceptable Parameter
+0x2D QoS Rejected
+0x2E Channel Classification Not Supported
+0x2F Insufficient Security
+*/
+#define BLE_HCI_PARAMETER_OUT_OF_MANDATORY_RANGE 0x30 /**< Parameter Out Of Mandatory Range. */
+/*
+0x31 Reserved
+0x32 Role Switch Pending
+0x33 Reserved
+0x34 Reserved Slot Violation
+0x35 Role Switch Failed
+0x36 Extended Inquiry Response Too Large
+0x37 Secure Simple Pairing Not Supported By Host.
+0x38 Host Busy - Pairing
+0x39 Connection Rejected due to No Suitable Channel Found*/
+#define BLE_HCI_CONTROLLER_BUSY 0x3A /**< Controller Busy. */
+#define BLE_HCI_CONN_INTERVAL_UNACCEPTABLE 0x3B /**< Connection Interval Unacceptable. */
+#define BLE_HCI_DIRECTED_ADVERTISER_TIMEOUT 0x3C /**< Directed Advertisement Timeout. */
+#define BLE_HCI_CONN_TERMINATED_DUE_TO_MIC_FAILURE 0x3D /**< Connection Terminated due to MIC Failure. */
+#define BLE_HCI_CONN_FAILED_TO_BE_ESTABLISHED 0x3E /**< Connection Failed to be Established. */
+
+/** @} */
+
+
+#ifdef __cplusplus
+}
+#endif
+#endif // BLE_HCI_H__
+
+/** @} */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/softdevice/s112/headers/ble_ranges.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/softdevice/s112/headers/ble_ranges.h
new file mode 100644
index 0000000..493dd43
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/softdevice/s112/headers/ble_ranges.h
@@ -0,0 +1,148 @@
+/*
+ * Copyright (c) 2012 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ */
+
+/**
+ @addtogroup BLE_COMMON
+ @{
+ @defgroup ble_ranges Module specific SVC, event and option number subranges
+ @{
+
+ @brief Definition of SVC, event and option number subranges for each API module.
+
+ @note
+ SVCs, event and option numbers are split into subranges for each API module.
+ Each module receives its entire allocated range of SVC calls, whether implemented or not,
+ but return BLE_ERROR_NOT_SUPPORTED for unimplemented or undefined calls in its range.
+
+ Note that the symbols BLE_<module>_SVC_LAST is the end of the allocated SVC range,
+ rather than the last SVC function call actually defined and implemented.
+
+ Specific SVC, event and option values are defined in each module's ble_<module>.h file,
+ which defines names of each individual SVC code based on the range start value.
+*/
+
+#ifndef BLE_RANGES_H__
+#define BLE_RANGES_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define BLE_SVC_BASE 0x60 /**< Common BLE SVC base. */
+#define BLE_SVC_LAST 0x6B /**< Common BLE SVC last. */
+
+#define BLE_GAP_SVC_BASE 0x6C /**< GAP BLE SVC base. */
+#define BLE_GAP_SVC_LAST 0x9A /**< GAP BLE SVC last. */
+
+#define BLE_GATTC_SVC_BASE 0x9B /**< GATTC BLE SVC base. */
+#define BLE_GATTC_SVC_LAST 0xA7 /**< GATTC BLE SVC last. */
+
+#define BLE_GATTS_SVC_BASE 0xA8 /**< GATTS BLE SVC base. */
+#define BLE_GATTS_SVC_LAST 0xB7 /**< GATTS BLE SVC last. */
+
+
+
+#define BLE_EVT_INVALID 0x00 /**< Invalid BLE Event. */
+
+#define BLE_EVT_BASE 0x01 /**< Common BLE Event base. */
+#define BLE_EVT_LAST 0x0F /**< Common BLE Event last. */
+
+#define BLE_GAP_EVT_BASE 0x10 /**< GAP BLE Event base. */
+#define BLE_GAP_EVT_LAST 0x2F /**< GAP BLE Event last. */
+
+#define BLE_GATTC_EVT_BASE 0x30 /**< GATTC BLE Event base. */
+#define BLE_GATTC_EVT_LAST 0x4F /**< GATTC BLE Event last. */
+
+#define BLE_GATTS_EVT_BASE 0x50 /**< GATTS BLE Event base. */
+#define BLE_GATTS_EVT_LAST 0x6F /**< GATTS BLE Event last. */
+
+
+
+#define BLE_OPT_INVALID 0x00 /**< Invalid BLE Option. */
+
+#define BLE_OPT_BASE 0x01 /**< Common BLE Option base. */
+#define BLE_OPT_LAST 0x1F /**< Common BLE Option last. */
+
+#define BLE_GAP_OPT_BASE 0x20 /**< GAP BLE Option base. */
+#define BLE_GAP_OPT_LAST 0x3F /**< GAP BLE Option last. */
+
+#define BLE_GATT_OPT_BASE 0x40 /**< GATT BLE Option base. */
+#define BLE_GATT_OPT_LAST 0x5F /**< GATT BLE Option last. */
+
+#define BLE_GATTC_OPT_BASE 0x60 /**< GATTC BLE Option base. */
+#define BLE_GATTC_OPT_LAST 0x7F /**< GATTC BLE Option last. */
+
+#define BLE_GATTS_OPT_BASE 0x80 /**< GATTS BLE Option base. */
+#define BLE_GATTS_OPT_LAST 0x9F /**< GATTS BLE Option last. */
+
+
+
+#define BLE_CFG_INVALID 0x00 /**< Invalid BLE configuration. */
+
+#define BLE_CFG_BASE 0x01 /**< Common BLE configuration base. */
+#define BLE_CFG_LAST 0x1F /**< Common BLE configuration last. */
+
+#define BLE_CONN_CFG_BASE 0x20 /**< BLE connection configuration base. */
+#define BLE_CONN_CFG_LAST 0x3F /**< BLE connection configuration last. */
+
+#define BLE_GAP_CFG_BASE 0x40 /**< GAP BLE configuration base. */
+#define BLE_GAP_CFG_LAST 0x5F /**< GAP BLE configuration last. */
+
+#define BLE_GATT_CFG_BASE 0x60 /**< GATT BLE configuration base. */
+#define BLE_GATT_CFG_LAST 0x7F /**< GATT BLE configuration last. */
+
+#define BLE_GATTC_CFG_BASE 0x80 /**< GATTC BLE configuration base. */
+#define BLE_GATTC_CFG_LAST 0x9F /**< GATTC BLE configuration last. */
+
+#define BLE_GATTS_CFG_BASE 0xA0 /**< GATTS BLE configuration base. */
+#define BLE_GATTS_CFG_LAST 0xBF /**< GATTS BLE configuration last. */
+
+
+
+
+
+
+#ifdef __cplusplus
+}
+#endif
+#endif /* BLE_RANGES_H__ */
+
+/**
+ @}
+ @}
+*/
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/softdevice/s112/headers/ble_types.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/softdevice/s112/headers/ble_types.h
new file mode 100644
index 0000000..88c9318
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/softdevice/s112/headers/ble_types.h
@@ -0,0 +1,215 @@
+/*
+ * Copyright (c) 2012 - 2017, 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ */
+
+/**
+ @addtogroup BLE_COMMON
+ @{
+ @defgroup ble_types Common types and macro definitions
+ @{
+
+ @brief Common types and macro definitions for the BLE SoftDevice.
+ */
+
+#ifndef BLE_TYPES_H__
+#define BLE_TYPES_H__
+
+#include <stdint.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** @addtogroup BLE_TYPES_DEFINES Defines
+ * @{ */
+
+/** @defgroup BLE_CONN_HANDLES BLE Connection Handles
+ * @{ */
+#define BLE_CONN_HANDLE_INVALID 0xFFFF /**< Invalid Connection Handle. */
+#define BLE_CONN_HANDLE_ALL 0xFFFE /**< Applies to all Connection Handles. */
+/** @} */
+
+
+/** @defgroup BLE_UUID_VALUES Assigned Values for BLE UUIDs
+ * @{ */
+/* Generic UUIDs, applicable to all services */
+#define BLE_UUID_UNKNOWN 0x0000 /**< Reserved UUID. */
+#define BLE_UUID_SERVICE_PRIMARY 0x2800 /**< Primary Service. */
+#define BLE_UUID_SERVICE_SECONDARY 0x2801 /**< Secondary Service. */
+#define BLE_UUID_SERVICE_INCLUDE 0x2802 /**< Include. */
+#define BLE_UUID_CHARACTERISTIC 0x2803 /**< Characteristic. */
+#define BLE_UUID_DESCRIPTOR_CHAR_EXT_PROP 0x2900 /**< Characteristic Extended Properties Descriptor. */
+#define BLE_UUID_DESCRIPTOR_CHAR_USER_DESC 0x2901 /**< Characteristic User Description Descriptor. */
+#define BLE_UUID_DESCRIPTOR_CLIENT_CHAR_CONFIG 0x2902 /**< Client Characteristic Configuration Descriptor. */
+#define BLE_UUID_DESCRIPTOR_SERVER_CHAR_CONFIG 0x2903 /**< Server Characteristic Configuration Descriptor. */
+#define BLE_UUID_DESCRIPTOR_CHAR_PRESENTATION_FORMAT 0x2904 /**< Characteristic Presentation Format Descriptor. */
+#define BLE_UUID_DESCRIPTOR_CHAR_AGGREGATE_FORMAT 0x2905 /**< Characteristic Aggregate Format Descriptor. */
+/* GATT specific UUIDs */
+#define BLE_UUID_GATT 0x1801 /**< Generic Attribute Profile. */
+#define BLE_UUID_GATT_CHARACTERISTIC_SERVICE_CHANGED 0x2A05 /**< Service Changed Characteristic. */
+/* GAP specific UUIDs */
+#define BLE_UUID_GAP 0x1800 /**< Generic Access Profile. */
+#define BLE_UUID_GAP_CHARACTERISTIC_DEVICE_NAME 0x2A00 /**< Device Name Characteristic. */
+#define BLE_UUID_GAP_CHARACTERISTIC_APPEARANCE 0x2A01 /**< Appearance Characteristic. */
+#define BLE_UUID_GAP_CHARACTERISTIC_RECONN_ADDR 0x2A03 /**< Reconnection Address Characteristic. */
+#define BLE_UUID_GAP_CHARACTERISTIC_PPCP 0x2A04 /**< Peripheral Preferred Connection Parameters Characteristic. */
+#define BLE_UUID_GAP_CHARACTERISTIC_CAR 0x2AA6 /**< Central Address Resolution Characteristic. */
+#define BLE_UUID_GAP_CHARACTERISTIC_RPA_ONLY 0x2AC9 /**< Resolvable Private Address Only Characteristic. */
+/** @} */
+
+
+/** @defgroup BLE_UUID_TYPES Types of UUID
+ * @{ */
+#define BLE_UUID_TYPE_UNKNOWN 0x00 /**< Invalid UUID type. */
+#define BLE_UUID_TYPE_BLE 0x01 /**< Bluetooth SIG UUID (16-bit). */
+#define BLE_UUID_TYPE_VENDOR_BEGIN 0x02 /**< Vendor UUID types start at this index (128-bit). */
+/** @} */
+
+
+/** @defgroup BLE_APPEARANCES Bluetooth Appearance values
+ * @note Retrieved from http://developer.bluetooth.org/gatt/characteristics/Pages/CharacteristicViewer.aspx?u=org.bluetooth.characteristic.gap.appearance.xml
+ * @{ */
+#define BLE_APPEARANCE_UNKNOWN 0 /**< Unknown. */
+#define BLE_APPEARANCE_GENERIC_PHONE 64 /**< Generic Phone. */
+#define BLE_APPEARANCE_GENERIC_COMPUTER 128 /**< Generic Computer. */
+#define BLE_APPEARANCE_GENERIC_WATCH 192 /**< Generic Watch. */
+#define BLE_APPEARANCE_WATCH_SPORTS_WATCH 193 /**< Watch: Sports Watch. */
+#define BLE_APPEARANCE_GENERIC_CLOCK 256 /**< Generic Clock. */
+#define BLE_APPEARANCE_GENERIC_DISPLAY 320 /**< Generic Display. */
+#define BLE_APPEARANCE_GENERIC_REMOTE_CONTROL 384 /**< Generic Remote Control. */
+#define BLE_APPEARANCE_GENERIC_EYE_GLASSES 448 /**< Generic Eye-glasses. */
+#define BLE_APPEARANCE_GENERIC_TAG 512 /**< Generic Tag. */
+#define BLE_APPEARANCE_GENERIC_KEYRING 576 /**< Generic Keyring. */
+#define BLE_APPEARANCE_GENERIC_MEDIA_PLAYER 640 /**< Generic Media Player. */
+#define BLE_APPEARANCE_GENERIC_BARCODE_SCANNER 704 /**< Generic Barcode Scanner. */
+#define BLE_APPEARANCE_GENERIC_THERMOMETER 768 /**< Generic Thermometer. */
+#define BLE_APPEARANCE_THERMOMETER_EAR 769 /**< Thermometer: Ear. */
+#define BLE_APPEARANCE_GENERIC_HEART_RATE_SENSOR 832 /**< Generic Heart rate Sensor. */
+#define BLE_APPEARANCE_HEART_RATE_SENSOR_HEART_RATE_BELT 833 /**< Heart Rate Sensor: Heart Rate Belt. */
+#define BLE_APPEARANCE_GENERIC_BLOOD_PRESSURE 896 /**< Generic Blood Pressure. */
+#define BLE_APPEARANCE_BLOOD_PRESSURE_ARM 897 /**< Blood Pressure: Arm. */
+#define BLE_APPEARANCE_BLOOD_PRESSURE_WRIST 898 /**< Blood Pressure: Wrist. */
+#define BLE_APPEARANCE_GENERIC_HID 960 /**< Human Interface Device (HID). */
+#define BLE_APPEARANCE_HID_KEYBOARD 961 /**< Keyboard (HID Subtype). */
+#define BLE_APPEARANCE_HID_MOUSE 962 /**< Mouse (HID Subtype). */
+#define BLE_APPEARANCE_HID_JOYSTICK 963 /**< Joystick (HID Subtype). */
+#define BLE_APPEARANCE_HID_GAMEPAD 964 /**< Gamepad (HID Subtype). */
+#define BLE_APPEARANCE_HID_DIGITIZERSUBTYPE 965 /**< Digitizer Tablet (HID Subtype). */
+#define BLE_APPEARANCE_HID_CARD_READER 966 /**< Card Reader (HID Subtype). */
+#define BLE_APPEARANCE_HID_DIGITAL_PEN 967 /**< Digital Pen (HID Subtype). */
+#define BLE_APPEARANCE_HID_BARCODE 968 /**< Barcode Scanner (HID Subtype). */
+#define BLE_APPEARANCE_GENERIC_GLUCOSE_METER 1024 /**< Generic Glucose Meter. */
+#define BLE_APPEARANCE_GENERIC_RUNNING_WALKING_SENSOR 1088 /**< Generic Running Walking Sensor. */
+#define BLE_APPEARANCE_RUNNING_WALKING_SENSOR_IN_SHOE 1089 /**< Running Walking Sensor: In-Shoe. */
+#define BLE_APPEARANCE_RUNNING_WALKING_SENSOR_ON_SHOE 1090 /**< Running Walking Sensor: On-Shoe. */
+#define BLE_APPEARANCE_RUNNING_WALKING_SENSOR_ON_HIP 1091 /**< Running Walking Sensor: On-Hip. */
+#define BLE_APPEARANCE_GENERIC_CYCLING 1152 /**< Generic Cycling. */
+#define BLE_APPEARANCE_CYCLING_CYCLING_COMPUTER 1153 /**< Cycling: Cycling Computer. */
+#define BLE_APPEARANCE_CYCLING_SPEED_SENSOR 1154 /**< Cycling: Speed Sensor. */
+#define BLE_APPEARANCE_CYCLING_CADENCE_SENSOR 1155 /**< Cycling: Cadence Sensor. */
+#define BLE_APPEARANCE_CYCLING_POWER_SENSOR 1156 /**< Cycling: Power Sensor. */
+#define BLE_APPEARANCE_CYCLING_SPEED_CADENCE_SENSOR 1157 /**< Cycling: Speed and Cadence Sensor. */
+#define BLE_APPEARANCE_GENERIC_PULSE_OXIMETER 3136 /**< Generic Pulse Oximeter. */
+#define BLE_APPEARANCE_PULSE_OXIMETER_FINGERTIP 3137 /**< Fingertip (Pulse Oximeter subtype). */
+#define BLE_APPEARANCE_PULSE_OXIMETER_WRIST_WORN 3138 /**< Wrist Worn(Pulse Oximeter subtype). */
+#define BLE_APPEARANCE_GENERIC_WEIGHT_SCALE 3200 /**< Generic Weight Scale. */
+#define BLE_APPEARANCE_GENERIC_OUTDOOR_SPORTS_ACT 5184 /**< Generic Outdoor Sports Activity. */
+#define BLE_APPEARANCE_OUTDOOR_SPORTS_ACT_LOC_DISP 5185 /**< Location Display Device (Outdoor Sports Activity subtype). */
+#define BLE_APPEARANCE_OUTDOOR_SPORTS_ACT_LOC_AND_NAV_DISP 5186 /**< Location and Navigation Display Device (Outdoor Sports Activity subtype). */
+#define BLE_APPEARANCE_OUTDOOR_SPORTS_ACT_LOC_POD 5187 /**< Location Pod (Outdoor Sports Activity subtype). */
+#define BLE_APPEARANCE_OUTDOOR_SPORTS_ACT_LOC_AND_NAV_POD 5188 /**< Location and Navigation Pod (Outdoor Sports Activity subtype). */
+/** @} */
+
+/** @brief Set .type and .uuid fields of ble_uuid_struct to specified UUID value. */
+#define BLE_UUID_BLE_ASSIGN(instance, value) do {\
+ instance.type = BLE_UUID_TYPE_BLE; \
+ instance.uuid = value;} while(0)
+
+/** @brief Copy type and uuid members from src to dst ble_uuid_t pointer. Both pointers must be valid/non-null. */
+#define BLE_UUID_COPY_PTR(dst, src) do {\
+ (dst)->type = (src)->type; \
+ (dst)->uuid = (src)->uuid;} while(0)
+
+/** @brief Copy type and uuid members from src to dst ble_uuid_t struct. */
+#define BLE_UUID_COPY_INST(dst, src) do {\
+ (dst).type = (src).type; \
+ (dst).uuid = (src).uuid;} while(0)
+
+/** @brief Compare for equality both type and uuid members of two (valid, non-null) ble_uuid_t pointers. */
+#define BLE_UUID_EQ(p_uuid1, p_uuid2) \
+ (((p_uuid1)->type == (p_uuid2)->type) && ((p_uuid1)->uuid == (p_uuid2)->uuid))
+
+/** @brief Compare for difference both type and uuid members of two (valid, non-null) ble_uuid_t pointers. */
+#define BLE_UUID_NEQ(p_uuid1, p_uuid2) \
+ (((p_uuid1)->type != (p_uuid2)->type) || ((p_uuid1)->uuid != (p_uuid2)->uuid))
+
+/** @} */
+
+/** @addtogroup BLE_TYPES_STRUCTURES Structures
+ * @{ */
+
+/** @brief 128 bit UUID values. */
+typedef struct
+{
+ uint8_t uuid128[16]; /**< Little-Endian UUID bytes. */
+} ble_uuid128_t;
+
+/** @brief Bluetooth Low Energy UUID type, encapsulates both 16-bit and 128-bit UUIDs. */
+typedef struct
+{
+ uint16_t uuid; /**< 16-bit UUID value or octets 12-13 of 128-bit UUID. */
+ uint8_t type; /**< UUID type, see @ref BLE_UUID_TYPES. If type is @ref BLE_UUID_TYPE_UNKNOWN, the value of uuid is undefined. */
+} ble_uuid_t;
+
+/**@brief Data structure. */
+typedef struct
+{
+ uint8_t *p_data; /**< Pointer to the data buffer provided to/from the application. */
+ uint16_t len; /**< Length of the data buffer, in bytes. */
+} ble_data_t;
+
+/** @} */
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* BLE_TYPES_H__ */
+
+/**
+ @}
+ @}
+*/
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/softdevice/s112/headers/nrf52/nrf_mbr.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/softdevice/s112/headers/nrf52/nrf_mbr.h
new file mode 100644
index 0000000..cc5971c
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/softdevice/s112/headers/nrf52/nrf_mbr.h
@@ -0,0 +1,241 @@
+/*
+ * Copyright (c) 2014 - 2017, 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ */
+
+/**
+ @defgroup nrf_mbr_api Master Boot Record API
+ @{
+
+ @brief APIs for updating SoftDevice and BootLoader
+
+*/
+
+#ifndef NRF_MBR_H__
+#define NRF_MBR_H__
+
+#include "nrf_svc.h"
+#include <stdint.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** @addtogroup NRF_MBR_DEFINES Defines
+ * @{ */
+
+/**@brief MBR SVC Base number. */
+#define MBR_SVC_BASE (0x18)
+
+/**@brief Page size in words. */
+#define MBR_PAGE_SIZE_IN_WORDS (1024)
+
+/** @brief The size that must be reserved for the MBR when a SoftDevice is written to flash.
+This is the offset where the first byte of the SoftDevice hex file is written.*/
+#define MBR_SIZE (0x1000)
+
+/** @} */
+
+/** @addtogroup NRF_MBR_ENUMS Enumerations
+ * @{ */
+
+/**@brief nRF Master Boot Record API SVC numbers. */
+enum NRF_MBR_SVCS
+{
+ SD_MBR_COMMAND = MBR_SVC_BASE, /**< ::sd_mbr_command */
+};
+
+/**@brief Possible values for ::sd_mbr_command_t.command */
+enum NRF_MBR_COMMANDS
+{
+ SD_MBR_COMMAND_COPY_BL, /**< Copy a new BootLoader. @see ::sd_mbr_command_copy_bl_t*/
+ SD_MBR_COMMAND_COPY_SD, /**< Copy a new SoftDevice. @see ::sd_mbr_command_copy_sd_t*/
+ SD_MBR_COMMAND_INIT_SD, /**< Initialize forwarding interrupts to SD, and run reset function in SD. Does not require any parameters in ::sd_mbr_command_t params.*/
+ SD_MBR_COMMAND_COMPARE, /**< This command works like memcmp. @see ::sd_mbr_command_compare_t*/
+ SD_MBR_COMMAND_VECTOR_TABLE_BASE_SET, /**< Change the address the MBR starts after a reset. @see ::sd_mbr_command_vector_table_base_set_t*/
+ SD_MBR_COMMAND_RESERVED,
+ SD_MBR_COMMAND_IRQ_FORWARD_ADDRESS_SET, /**< Start forwarding all interrupts to this address. @see ::sd_mbr_command_irq_forward_address_set_t*/
+};
+
+/** @} */
+
+/** @addtogroup NRF_MBR_TYPES Types
+ * @{ */
+
+/**@brief This command copies part of a new SoftDevice
+ *
+ * The destination area is erased before copying.
+ * If dst is in the middle of a flash page, that whole flash page will be erased.
+ * If (dst+len) is in the middle of a flash page, that whole flash page will be erased.
+ *
+ * The user of this function is responsible for setting the BPROT registers.
+ *
+ * @retval ::NRF_SUCCESS indicates that the contents of the memory blocks where copied correctly.
+ * @retval ::NRF_ERROR_INTERNAL indicates that the contents of the memory blocks where not verified correctly after copying.
+ */
+typedef struct
+{
+ uint32_t *src; /**< Pointer to the source of data to be copied.*/
+ uint32_t *dst; /**< Pointer to the destination where the content is to be copied.*/
+ uint32_t len; /**< Number of 32 bit words to copy. Must be a multiple of @ref MBR_PAGE_SIZE_IN_WORDS words.*/
+} sd_mbr_command_copy_sd_t;
+
+
+/**@brief This command works like memcmp, but takes the length in words.
+ *
+ * @retval ::NRF_SUCCESS indicates that the contents of both memory blocks are equal.
+ * @retval ::NRF_ERROR_NULL indicates that the contents of the memory blocks are not equal.
+ */
+typedef struct
+{
+ uint32_t *ptr1; /**< Pointer to block of memory. */
+ uint32_t *ptr2; /**< Pointer to block of memory. */
+ uint32_t len; /**< Number of 32 bit words to compare.*/
+} sd_mbr_command_compare_t;
+
+
+/**@brief This command copies a new BootLoader.
+ *
+ * With this command, destination of BootLoader is always the address written in
+ * NRF_UICR->BOOTADDR.
+ *
+ * Destination is erased by this function.
+ * If (destination+bl_len) is in the middle of a flash page, that whole flash page will be erased.
+ *
+ * This function will use PROTENSET to protect the flash that is not intended to be written.
+ *
+ * On success, this function will not return. It will start the new BootLoader from reset-vector as normal.
+ *
+ * @retval ::NRF_ERROR_INTERNAL indicates an internal error that should not happen.
+ * @retval ::NRF_ERROR_FORBIDDEN if NRF_UICR->BOOTADDR is not set.
+ * @retval ::NRF_ERROR_INVALID_LENGTH if parameters attempts to read or write outside flash area.
+ * @retval ::NRF_ERROR_NO_MEM if no parameter page is provided (see SoftDevice Specification for more info)
+ */
+typedef struct
+{
+ uint32_t *bl_src; /**< Pointer to the source of the Bootloader to be be copied.*/
+ uint32_t bl_len; /**< Number of 32 bit words to copy for BootLoader. */
+} sd_mbr_command_copy_bl_t;
+
+/**@brief Change the address the MBR starts after a reset
+ *
+ * Once this function has been called, this address is where the MBR will start to forward
+ * interrupts to after a reset.
+ *
+ * To restore default forwarding this function should be called with @ref address set to 0. The
+ * MBR will then start forwarding interrupts to the address in NFR_UICR->BOOTADDR or to the
+ * SoftDevice if the BOOTADDR is not set.
+ *
+ * On success, this function will not return. It will reset the device.
+ *
+ * @retval ::NRF_ERROR_INTERNAL indicates an internal error that should not happen.
+ * @retval ::NRF_ERROR_INVALID_ADDR if parameter address is outside of the flash size.
+ * @retval ::NRF_ERROR_NO_MEM if no parameter page is provided (see SoftDevice Specification for more info)
+ */
+typedef struct
+{
+ uint32_t address; /**< The base address of the interrupt vector table for forwarded interrupts.*/
+} sd_mbr_command_vector_table_base_set_t;
+
+/**@brief Sets the base address of the interrupt vector table for interrupts forwarded from the MBR
+ *
+ * Unlike sd_mbr_command_vector_table_base_set_t, this function does not reset, and it does not
+ * change where the MBR starts after reset.
+ *
+ * @retval ::NRF_SUCCESS
+ */
+typedef struct
+{
+ uint32_t address; /**< The base address of the interrupt vector table for forwarded interrupts.*/
+} sd_mbr_command_irq_forward_address_set_t;
+
+/**@brief Input structure containing data used when calling ::sd_mbr_command
+ *
+ * Depending on what command value that is set, the corresponding params value type must also be
+ * set. See @ref NRF_MBR_COMMANDS for command types and corresponding params value type. If command
+ * @ref SD_MBR_COMMAND_INIT_SD is set, it is not necessary to set any values under params.
+ */
+typedef struct
+{
+ uint32_t command; /**< Type of command to be issued. See @ref NRF_MBR_COMMANDS. */
+ union
+ {
+ sd_mbr_command_copy_sd_t copy_sd; /**< Parameters for copy SoftDevice.*/
+ sd_mbr_command_compare_t compare; /**< Parameters for verify.*/
+ sd_mbr_command_copy_bl_t copy_bl; /**< Parameters for copy BootLoader. Requires parameter page. */
+ sd_mbr_command_vector_table_base_set_t base_set; /**< Parameters for vector table base set. Requires parameter page.*/
+ sd_mbr_command_irq_forward_address_set_t irq_forward_address_set; /**< Parameters for irq forward address set*/
+ } params; /**< Command parameters. */
+} sd_mbr_command_t;
+
+/** @} */
+
+/** @addtogroup NRF_MBR_FUNCTIONS Functions
+ * @{ */
+
+/**@brief Issue Master Boot Record commands
+ *
+ * Commands used when updating a SoftDevice and bootloader.
+ *
+ * The @ref SD_MBR_COMMAND_COPY_BL and @ref SD_MBR_COMMAND_VECTOR_TABLE_BASE_SET requires
+ * parameters to be retained by the MBR when resetting the IC. This is done in a separate flash
+ * page provided by the application. The UICR register UICR.NRFFW[1] must be set to an address
+ * corresponding to a page in the application flash space. This page will be cleared by the MBR and
+ * used to store the command before reset. When the UICR.NRFFW[1] field is set the page it refers
+ * to must not be used by the application. If the UICR.NRFFW[1] is set to 0xFFFFFFFF (the default)
+ * MBR commands which use flash will be unavailable and return @ref NRF_ERROR_NO_MEM.
+ *
+ * @param[in] param Pointer to a struct describing the command.
+ *
+ * @note For return values, see ::sd_mbr_command_copy_sd_t, ::sd_mbr_command_copy_bl_t,
+ * ::sd_mbr_command_compare_t, ::sd_mbr_command_vector_table_base_set_t,
+ * ::sd_mbr_command_irq_forward_address_set_t
+ *
+ * @retval ::NRF_ERROR_NO_MEM if UICR.NRFFW[1] is not set (i.e. is 0xFFFFFFFF).
+ * @retval ::NRF_ERROR_INVALID_PARAM if an invalid command is given.
+*/
+SVCALL(SD_MBR_COMMAND, uint32_t, sd_mbr_command(sd_mbr_command_t* param));
+
+/** @} */
+
+#ifdef __cplusplus
+}
+#endif
+#endif // NRF_MBR_H__
+
+/**
+ @}
+*/
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/softdevice/s112/headers/nrf_error.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/softdevice/s112/headers/nrf_error.h
new file mode 100644
index 0000000..6badee9
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/softdevice/s112/headers/nrf_error.h
@@ -0,0 +1,90 @@
+/*
+ * Copyright (c) 2014 - 2017, 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ */
+
+ /**
+ @defgroup nrf_error SoftDevice Global Error Codes
+ @{
+
+ @brief Global Error definitions
+*/
+
+/* Header guard */
+#ifndef NRF_ERROR_H__
+#define NRF_ERROR_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** @defgroup NRF_ERRORS_BASE Error Codes Base number definitions
+ * @{ */
+#define NRF_ERROR_BASE_NUM (0x0) ///< Global error base
+#define NRF_ERROR_SDM_BASE_NUM (0x1000) ///< SDM error base
+#define NRF_ERROR_SOC_BASE_NUM (0x2000) ///< SoC error base
+#define NRF_ERROR_STK_BASE_NUM (0x3000) ///< STK error base
+/** @} */
+
+#define NRF_SUCCESS (NRF_ERROR_BASE_NUM + 0) ///< Successful command
+#define NRF_ERROR_SVC_HANDLER_MISSING (NRF_ERROR_BASE_NUM + 1) ///< SVC handler is missing
+#define NRF_ERROR_SOFTDEVICE_NOT_ENABLED (NRF_ERROR_BASE_NUM + 2) ///< SoftDevice has not been enabled
+#define NRF_ERROR_INTERNAL (NRF_ERROR_BASE_NUM + 3) ///< Internal Error
+#define NRF_ERROR_NO_MEM (NRF_ERROR_BASE_NUM + 4) ///< No Memory for operation
+#define NRF_ERROR_NOT_FOUND (NRF_ERROR_BASE_NUM + 5) ///< Not found
+#define NRF_ERROR_NOT_SUPPORTED (NRF_ERROR_BASE_NUM + 6) ///< Not supported
+#define NRF_ERROR_INVALID_PARAM (NRF_ERROR_BASE_NUM + 7) ///< Invalid Parameter
+#define NRF_ERROR_INVALID_STATE (NRF_ERROR_BASE_NUM + 8) ///< Invalid state, operation disallowed in this state
+#define NRF_ERROR_INVALID_LENGTH (NRF_ERROR_BASE_NUM + 9) ///< Invalid Length
+#define NRF_ERROR_INVALID_FLAGS (NRF_ERROR_BASE_NUM + 10) ///< Invalid Flags
+#define NRF_ERROR_INVALID_DATA (NRF_ERROR_BASE_NUM + 11) ///< Invalid Data
+#define NRF_ERROR_DATA_SIZE (NRF_ERROR_BASE_NUM + 12) ///< Invalid Data size
+#define NRF_ERROR_TIMEOUT (NRF_ERROR_BASE_NUM + 13) ///< Operation timed out
+#define NRF_ERROR_NULL (NRF_ERROR_BASE_NUM + 14) ///< Null Pointer
+#define NRF_ERROR_FORBIDDEN (NRF_ERROR_BASE_NUM + 15) ///< Forbidden Operation
+#define NRF_ERROR_INVALID_ADDR (NRF_ERROR_BASE_NUM + 16) ///< Bad Memory Address
+#define NRF_ERROR_BUSY (NRF_ERROR_BASE_NUM + 17) ///< Busy
+#define NRF_ERROR_CONN_COUNT (NRF_ERROR_BASE_NUM + 18) ///< Maximum connection count exceeded.
+#define NRF_ERROR_RESOURCES (NRF_ERROR_BASE_NUM + 19) ///< Not enough resources for operation
+
+#ifdef __cplusplus
+}
+#endif
+#endif // NRF_ERROR_H__
+
+/**
+ @}
+*/
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/softdevice/s112/headers/nrf_error_sdm.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/softdevice/s112/headers/nrf_error_sdm.h
new file mode 100644
index 0000000..530959b
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/softdevice/s112/headers/nrf_error_sdm.h
@@ -0,0 +1,70 @@
+/*
+ * Copyright (c) 2012 - 2017, 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ */
+
+ /**
+ @addtogroup nrf_sdm_api
+ @{
+ @defgroup nrf_sdm_error SoftDevice Manager Error Codes
+ @{
+
+ @brief Error definitions for the SDM API
+*/
+
+/* Header guard */
+#ifndef NRF_ERROR_SDM_H__
+#define NRF_ERROR_SDM_H__
+
+#include "nrf_error.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define NRF_ERROR_SDM_LFCLK_SOURCE_UNKNOWN (NRF_ERROR_SDM_BASE_NUM + 0) ///< Unknown LFCLK source.
+#define NRF_ERROR_SDM_INCORRECT_INTERRUPT_CONFIGURATION (NRF_ERROR_SDM_BASE_NUM + 1) ///< Incorrect interrupt configuration (can be caused by using illegal priority levels, or having enabled SoftDevice interrupts).
+#define NRF_ERROR_SDM_INCORRECT_CLENR0 (NRF_ERROR_SDM_BASE_NUM + 2) ///< Incorrect CLENR0 (can be caused by erroneous SoftDevice flashing).
+
+#ifdef __cplusplus
+}
+#endif
+#endif // NRF_ERROR_SDM_H__
+
+/**
+ @}
+ @}
+*/
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/softdevice/s112/headers/nrf_error_soc.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/softdevice/s112/headers/nrf_error_soc.h
new file mode 100644
index 0000000..1e784b8
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/softdevice/s112/headers/nrf_error_soc.h
@@ -0,0 +1,85 @@
+/*
+ * Copyright (c) 2012 - 2017, 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ */
+
+/**
+ @addtogroup nrf_soc_api
+ @{
+ @defgroup nrf_soc_error SoC Library Error Codes
+ @{
+
+ @brief Error definitions for the SoC library
+
+*/
+
+/* Header guard */
+#ifndef NRF_ERROR_SOC_H__
+#define NRF_ERROR_SOC_H__
+
+#include "nrf_error.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Mutex Errors */
+#define NRF_ERROR_SOC_MUTEX_ALREADY_TAKEN (NRF_ERROR_SOC_BASE_NUM + 0) ///< Mutex already taken
+
+/* NVIC errors */
+#define NRF_ERROR_SOC_NVIC_INTERRUPT_NOT_AVAILABLE (NRF_ERROR_SOC_BASE_NUM + 1) ///< NVIC interrupt not available
+#define NRF_ERROR_SOC_NVIC_INTERRUPT_PRIORITY_NOT_ALLOWED (NRF_ERROR_SOC_BASE_NUM + 2) ///< NVIC interrupt priority not allowed
+#define NRF_ERROR_SOC_NVIC_SHOULD_NOT_RETURN (NRF_ERROR_SOC_BASE_NUM + 3) ///< NVIC should not return
+
+/* Power errors */
+#define NRF_ERROR_SOC_POWER_MODE_UNKNOWN (NRF_ERROR_SOC_BASE_NUM + 4) ///< Power mode unknown
+#define NRF_ERROR_SOC_POWER_POF_THRESHOLD_UNKNOWN (NRF_ERROR_SOC_BASE_NUM + 5) ///< Power POF threshold unknown
+#define NRF_ERROR_SOC_POWER_OFF_SHOULD_NOT_RETURN (NRF_ERROR_SOC_BASE_NUM + 6) ///< Power off should not return
+
+/* Rand errors */
+#define NRF_ERROR_SOC_RAND_NOT_ENOUGH_VALUES (NRF_ERROR_SOC_BASE_NUM + 7) ///< RAND not enough values
+
+/* PPI errors */
+#define NRF_ERROR_SOC_PPI_INVALID_CHANNEL (NRF_ERROR_SOC_BASE_NUM + 8) ///< Invalid PPI Channel
+#define NRF_ERROR_SOC_PPI_INVALID_GROUP (NRF_ERROR_SOC_BASE_NUM + 9) ///< Invalid PPI Group
+
+#ifdef __cplusplus
+}
+#endif
+#endif // NRF_ERROR_SOC_H__
+/**
+ @}
+ @}
+*/
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/softdevice/s112/headers/nrf_nvic.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/softdevice/s112/headers/nrf_nvic.h
new file mode 100644
index 0000000..f5c7e8e
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/softdevice/s112/headers/nrf_nvic.h
@@ -0,0 +1,486 @@
+/*
+ * Copyright (c) 2016 - 2017, 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ */
+
+/**
+ * @defgroup nrf_nvic_api SoftDevice NVIC API
+ * @{
+ *
+ * @note In order to use this module, the following code has to be added to a .c file:
+ * \code
+ * nrf_nvic_state_t nrf_nvic_state = {0};
+ * \endcode
+ *
+ * @note Definitions and declarations starting with __ (double underscore) in this header file are
+ * not intended for direct use by the application.
+ *
+ * @brief APIs for the accessing NVIC when using a SoftDevice.
+ *
+ */
+
+#ifndef NRF_NVIC_H__
+#define NRF_NVIC_H__
+
+#include <stdint.h>
+#include "nrf.h"
+#include "nrf_svc.h"
+#include "nrf_error.h"
+#include "nrf_error_soc.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**@addtogroup NRF_NVIC_DEFINES Defines
+ * @{ */
+
+/**@defgroup NRF_NVIC_ISER_DEFINES SoftDevice NVIC internal definitions
+ * @{ */
+
+#define __NRF_NVIC_NVMC_IRQn (30) /**< The peripheral ID of the NVMC. IRQ numbers are used to identify peripherals, but the NVMC doesn't have an IRQ number in the MDK. */
+
+#define __NRF_NVIC_ISER_COUNT (2) /**< The number of ISER/ICER registers in the NVIC that are used. */
+
+/**@brief Interrupts used by the SoftDevice, with IRQn in the range 0-31. */
+#define __NRF_NVIC_SD_IRQS_0 ((uint32_t)( \
+ (1U << POWER_CLOCK_IRQn) \
+ | (1U << RADIO_IRQn) \
+ | (1U << RTC0_IRQn) \
+ | (1U << TIMER0_IRQn) \
+ | (1U << RNG_IRQn) \
+ | (1U << ECB_IRQn) \
+ | (1U << CCM_AAR_IRQn) \
+ | (1U << TEMP_IRQn) \
+ | (1U << __NRF_NVIC_NVMC_IRQn) \
+ | (1U << (uint32_t)SWI5_IRQn) \
+ ))
+
+/**@brief Interrupts used by the SoftDevice, with IRQn in the range 32-63. */
+#define __NRF_NVIC_SD_IRQS_1 ((uint32_t)0)
+
+/**@brief Interrupts available for to application, with IRQn in the range 0-31. */
+#define __NRF_NVIC_APP_IRQS_0 (~__NRF_NVIC_SD_IRQS_0)
+
+/**@brief Interrupts available for to application, with IRQn in the range 32-63. */
+#define __NRF_NVIC_APP_IRQS_1 (~__NRF_NVIC_SD_IRQS_1)
+
+/**@} */
+
+/**@} */
+
+/**@addtogroup NRF_NVIC_VARIABLES Variables
+ * @{ */
+
+/**@brief Type representing the state struct for the SoftDevice NVIC module. */
+typedef struct
+{
+ uint32_t volatile __irq_masks[__NRF_NVIC_ISER_COUNT]; /**< IRQs enabled by the application in the NVIC. */
+ uint32_t volatile __cr_flag; /**< Non-zero if already in a critical region */
+} nrf_nvic_state_t;
+
+/**@brief Variable keeping the state for the SoftDevice NVIC module. This must be declared in an
+ * application source file. */
+extern nrf_nvic_state_t nrf_nvic_state;
+
+/**@} */
+
+/**@addtogroup NRF_NVIC_INTERNAL_FUNCTIONS SoftDevice NVIC internal functions
+ * @{ */
+
+/**@brief Disables IRQ interrupts globally, including the SoftDevice's interrupts.
+ *
+ * @retval The value of PRIMASK prior to disabling the interrupts.
+ */
+__STATIC_INLINE int __sd_nvic_irq_disable(void);
+
+/**@brief Enables IRQ interrupts globally, including the SoftDevice's interrupts.
+ */
+__STATIC_INLINE void __sd_nvic_irq_enable(void);
+
+/**@brief Checks if IRQn is available to application
+ * @param[in] IRQn IRQ to check
+ *
+ * @retval 1 (true) if the IRQ to check is available to the application
+ */
+__STATIC_INLINE uint32_t __sd_nvic_app_accessible_irq(IRQn_Type IRQn);
+
+/**@brief Checks if priority is available to application
+ * @param[in] priority priority to check
+ *
+ * @retval 1 (true) if the priority to check is available to the application
+ */
+__STATIC_INLINE uint32_t __sd_nvic_is_app_accessible_priority(uint32_t priority);
+
+/**@} */
+
+/**@addtogroup NRF_NVIC_FUNCTIONS SoftDevice NVIC public functions
+ * @{ */
+
+/**@brief Enable External Interrupt.
+ * @note Corresponds to NVIC_EnableIRQ in CMSIS.
+ *
+ * @pre IRQn is valid and not reserved by the stack.
+ *
+ * @param[in] IRQn See the NVIC_EnableIRQ documentation in CMSIS.
+ *
+ * @retval ::NRF_SUCCESS The interrupt was enabled.
+ * @retval ::NRF_ERROR_SOC_NVIC_INTERRUPT_NOT_AVAILABLE The interrupt is not available for the application.
+ * @retval ::NRF_ERROR_SOC_NVIC_INTERRUPT_PRIORITY_NOT_ALLOWED The interrupt has a priority not available for the application.
+ */
+__STATIC_INLINE uint32_t sd_nvic_EnableIRQ(IRQn_Type IRQn);
+
+/**@brief Disable External Interrupt.
+ * @note Corresponds to NVIC_DisableIRQ in CMSIS.
+ *
+ * @pre IRQn is valid and not reserved by the stack.
+ *
+ * @param[in] IRQn See the NVIC_DisableIRQ documentation in CMSIS.
+ *
+ * @retval ::NRF_SUCCESS The interrupt was disabled.
+ * @retval ::NRF_ERROR_SOC_NVIC_INTERRUPT_NOT_AVAILABLE The interrupt is not available for the application.
+ */
+__STATIC_INLINE uint32_t sd_nvic_DisableIRQ(IRQn_Type IRQn);
+
+/**@brief Get Pending Interrupt.
+ * @note Corresponds to NVIC_GetPendingIRQ in CMSIS.
+ *
+ * @pre IRQn is valid and not reserved by the stack.
+ *
+ * @param[in] IRQn See the NVIC_GetPendingIRQ documentation in CMSIS.
+ * @param[out] p_pending_irq Return value from NVIC_GetPendingIRQ.
+ *
+ * @retval ::NRF_SUCCESS The interrupt is available for the application.
+ * @retval ::NRF_ERROR_SOC_NVIC_INTERRUPT_NOT_AVAILABLE IRQn is not available for the application.
+ */
+__STATIC_INLINE uint32_t sd_nvic_GetPendingIRQ(IRQn_Type IRQn, uint32_t * p_pending_irq);
+
+/**@brief Set Pending Interrupt.
+ * @note Corresponds to NVIC_SetPendingIRQ in CMSIS.
+ *
+ * @pre IRQn is valid and not reserved by the stack.
+ *
+ * @param[in] IRQn See the NVIC_SetPendingIRQ documentation in CMSIS.
+ *
+ * @retval ::NRF_SUCCESS The interrupt is set pending.
+ * @retval ::NRF_ERROR_SOC_NVIC_INTERRUPT_NOT_AVAILABLE IRQn is not available for the application.
+ */
+__STATIC_INLINE uint32_t sd_nvic_SetPendingIRQ(IRQn_Type IRQn);
+
+/**@brief Clear Pending Interrupt.
+ * @note Corresponds to NVIC_ClearPendingIRQ in CMSIS.
+ *
+ * @pre IRQn is valid and not reserved by the stack.
+ *
+ * @param[in] IRQn See the NVIC_ClearPendingIRQ documentation in CMSIS.
+ *
+ * @retval ::NRF_SUCCESS The interrupt pending flag is cleared.
+ * @retval ::NRF_ERROR_SOC_NVIC_INTERRUPT_NOT_AVAILABLE IRQn is not available for the application.
+ */
+__STATIC_INLINE uint32_t sd_nvic_ClearPendingIRQ(IRQn_Type IRQn);
+
+/**@brief Set Interrupt Priority.
+ * @note Corresponds to NVIC_SetPriority in CMSIS.
+ *
+ * @pre IRQn is valid and not reserved by the stack.
+ * @pre Priority is valid and not reserved by the stack.
+ *
+ * @param[in] IRQn See the NVIC_SetPriority documentation in CMSIS.
+ * @param[in] priority A valid IRQ priority for use by the application.
+ *
+ * @retval ::NRF_SUCCESS The interrupt and priority level is available for the application.
+ * @retval ::NRF_ERROR_SOC_NVIC_INTERRUPT_NOT_AVAILABLE IRQn is not available for the application.
+ * @retval ::NRF_ERROR_SOC_NVIC_INTERRUPT_PRIORITY_NOT_ALLOWED The interrupt priority is not available for the application.
+ */
+__STATIC_INLINE uint32_t sd_nvic_SetPriority(IRQn_Type IRQn, uint32_t priority);
+
+/**@brief Get Interrupt Priority.
+ * @note Corresponds to NVIC_GetPriority in CMSIS.
+ *
+ * @pre IRQn is valid and not reserved by the stack.
+ *
+ * @param[in] IRQn See the NVIC_GetPriority documentation in CMSIS.
+ * @param[out] p_priority Return value from NVIC_GetPriority.
+ *
+ * @retval ::NRF_SUCCESS The interrupt priority is returned in p_priority.
+ * @retval ::NRF_ERROR_SOC_NVIC_INTERRUPT_NOT_AVAILABLE - IRQn is not available for the application.
+ */
+__STATIC_INLINE uint32_t sd_nvic_GetPriority(IRQn_Type IRQn, uint32_t * p_priority);
+
+/**@brief System Reset.
+ * @note Corresponds to NVIC_SystemReset in CMSIS.
+ *
+ * @retval ::NRF_ERROR_SOC_NVIC_SHOULD_NOT_RETURN
+ */
+__STATIC_INLINE uint32_t sd_nvic_SystemReset(void);
+
+/**@brief Enter critical region.
+ *
+ * @post Application interrupts will be disabled.
+ * @note sd_nvic_critical_region_enter() and ::sd_nvic_critical_region_exit() must be called in matching pairs inside each
+ * execution context
+ * @sa sd_nvic_critical_region_exit
+ *
+ * @param[out] p_is_nested_critical_region If 1, the application is now in a nested critical region.
+ *
+ * @retval ::NRF_SUCCESS
+ */
+__STATIC_INLINE uint32_t sd_nvic_critical_region_enter(uint8_t * p_is_nested_critical_region);
+
+/**@brief Exit critical region.
+ *
+ * @pre Application has entered a critical region using ::sd_nvic_critical_region_enter.
+ * @post If not in a nested critical region, the application interrupts will restored to the state before ::sd_nvic_critical_region_enter was called.
+ *
+ * @param[in] is_nested_critical_region If this is set to 1, the critical region won't be exited. @sa sd_nvic_critical_region_enter.
+ *
+ * @retval ::NRF_SUCCESS
+ */
+__STATIC_INLINE uint32_t sd_nvic_critical_region_exit(uint8_t is_nested_critical_region);
+
+/**@} */
+
+#ifndef SUPPRESS_INLINE_IMPLEMENTATION
+
+__STATIC_INLINE int __sd_nvic_irq_disable(void)
+{
+ int pm = __get_PRIMASK();
+ __disable_irq();
+ return pm;
+}
+
+__STATIC_INLINE void __sd_nvic_irq_enable(void)
+{
+ __enable_irq();
+}
+
+__STATIC_INLINE uint32_t __sd_nvic_app_accessible_irq(IRQn_Type IRQn)
+{
+ if (IRQn < 32)
+ {
+ return ((1UL<<IRQn) & __NRF_NVIC_APP_IRQS_0) != 0;
+ }
+ else if (IRQn < 64)
+ {
+ return ((1UL<<(IRQn-32)) & __NRF_NVIC_APP_IRQS_1) != 0;
+ }
+ else
+ {
+ return 1;
+ }
+}
+
+__STATIC_INLINE uint32_t __sd_nvic_is_app_accessible_priority(uint32_t priority)
+{
+ if(priority >= (1 << __NVIC_PRIO_BITS))
+ {
+ return 0;
+ }
+ if( priority == 0
+ || priority == 1
+ || priority == 4
+ )
+ {
+ return 0;
+ }
+ return 1;
+}
+
+
+__STATIC_INLINE uint32_t sd_nvic_EnableIRQ(IRQn_Type IRQn)
+{
+ if (!__sd_nvic_app_accessible_irq(IRQn))
+ {
+ return NRF_ERROR_SOC_NVIC_INTERRUPT_NOT_AVAILABLE;
+ }
+ if (!__sd_nvic_is_app_accessible_priority(NVIC_GetPriority(IRQn)))
+ {
+ return NRF_ERROR_SOC_NVIC_INTERRUPT_PRIORITY_NOT_ALLOWED;
+ }
+
+ if (nrf_nvic_state.__cr_flag)
+ {
+ nrf_nvic_state.__irq_masks[(uint32_t)((int32_t)IRQn) >> 5] |= (uint32_t)(1 << ((uint32_t)((int32_t)IRQn) & (uint32_t)0x1F));
+ }
+ else
+ {
+ NVIC_EnableIRQ(IRQn);
+ }
+ return NRF_SUCCESS;
+}
+
+__STATIC_INLINE uint32_t sd_nvic_DisableIRQ(IRQn_Type IRQn)
+{
+ if (!__sd_nvic_app_accessible_irq(IRQn))
+ {
+ return NRF_ERROR_SOC_NVIC_INTERRUPT_NOT_AVAILABLE;
+ }
+
+ if (nrf_nvic_state.__cr_flag)
+ {
+ nrf_nvic_state.__irq_masks[(uint32_t)((int32_t)IRQn) >> 5] &= ~(1UL << ((uint32_t)(IRQn) & 0x1F));
+ }
+ else
+ {
+ NVIC_DisableIRQ(IRQn);
+ }
+
+ return NRF_SUCCESS;
+}
+
+__STATIC_INLINE uint32_t sd_nvic_GetPendingIRQ(IRQn_Type IRQn, uint32_t * p_pending_irq)
+{
+ if (__sd_nvic_app_accessible_irq(IRQn))
+ {
+ *p_pending_irq = NVIC_GetPendingIRQ(IRQn);
+ return NRF_SUCCESS;
+ }
+ else
+ {
+ return NRF_ERROR_SOC_NVIC_INTERRUPT_NOT_AVAILABLE;
+ }
+}
+
+__STATIC_INLINE uint32_t sd_nvic_SetPendingIRQ(IRQn_Type IRQn)
+{
+ if (__sd_nvic_app_accessible_irq(IRQn))
+ {
+ NVIC_SetPendingIRQ(IRQn);
+ return NRF_SUCCESS;
+ }
+ else
+ {
+ return NRF_ERROR_SOC_NVIC_INTERRUPT_NOT_AVAILABLE;
+ }
+}
+
+__STATIC_INLINE uint32_t sd_nvic_ClearPendingIRQ(IRQn_Type IRQn)
+{
+ if (__sd_nvic_app_accessible_irq(IRQn))
+ {
+ NVIC_ClearPendingIRQ(IRQn);
+ return NRF_SUCCESS;
+ }
+ else
+ {
+ return NRF_ERROR_SOC_NVIC_INTERRUPT_NOT_AVAILABLE;
+ }
+}
+
+__STATIC_INLINE uint32_t sd_nvic_SetPriority(IRQn_Type IRQn, uint32_t priority)
+{
+ if (!__sd_nvic_app_accessible_irq(IRQn))
+ {
+ return NRF_ERROR_SOC_NVIC_INTERRUPT_NOT_AVAILABLE;
+ }
+
+ if (!__sd_nvic_is_app_accessible_priority(priority))
+ {
+ return NRF_ERROR_SOC_NVIC_INTERRUPT_PRIORITY_NOT_ALLOWED;
+ }
+
+ NVIC_SetPriority(IRQn, (uint32_t)priority);
+ return NRF_SUCCESS;
+}
+
+__STATIC_INLINE uint32_t sd_nvic_GetPriority(IRQn_Type IRQn, uint32_t * p_priority)
+{
+ if (__sd_nvic_app_accessible_irq(IRQn))
+ {
+ *p_priority = (NVIC_GetPriority(IRQn) & 0xFF);
+ return NRF_SUCCESS;
+ }
+ else
+ {
+ return NRF_ERROR_SOC_NVIC_INTERRUPT_NOT_AVAILABLE;
+ }
+}
+
+__STATIC_INLINE uint32_t sd_nvic_SystemReset(void)
+{
+ NVIC_SystemReset();
+ return NRF_ERROR_SOC_NVIC_SHOULD_NOT_RETURN;
+}
+
+__STATIC_INLINE uint32_t sd_nvic_critical_region_enter(uint8_t * p_is_nested_critical_region)
+{
+ int was_masked = __sd_nvic_irq_disable();
+ if (!nrf_nvic_state.__cr_flag)
+ {
+ nrf_nvic_state.__cr_flag = 1;
+ nrf_nvic_state.__irq_masks[0] = ( NVIC->ICER[0] & __NRF_NVIC_APP_IRQS_0 );
+ NVIC->ICER[0] = __NRF_NVIC_APP_IRQS_0;
+ nrf_nvic_state.__irq_masks[1] = ( NVIC->ICER[1] & __NRF_NVIC_APP_IRQS_1 );
+ NVIC->ICER[1] = __NRF_NVIC_APP_IRQS_1;
+ *p_is_nested_critical_region = 0;
+ }
+ else
+ {
+ *p_is_nested_critical_region = 1;
+ }
+ if (!was_masked)
+ {
+ __sd_nvic_irq_enable();
+ }
+ return NRF_SUCCESS;
+}
+
+__STATIC_INLINE uint32_t sd_nvic_critical_region_exit(uint8_t is_nested_critical_region)
+{
+ if (nrf_nvic_state.__cr_flag && (is_nested_critical_region == 0))
+ {
+ int was_masked = __sd_nvic_irq_disable();
+ NVIC->ISER[0] = nrf_nvic_state.__irq_masks[0];
+ NVIC->ISER[1] = nrf_nvic_state.__irq_masks[1];
+ nrf_nvic_state.__cr_flag = 0;
+ if (!was_masked)
+ {
+ __sd_nvic_irq_enable();
+ }
+ }
+
+ return NRF_SUCCESS;
+}
+
+#endif /* SUPPRESS_INLINE_IMPLEMENTATION */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // NRF_NVIC_H__
+
+/**@} */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/softdevice/s112/headers/nrf_sd_def.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/softdevice/s112/headers/nrf_sd_def.h
new file mode 100644
index 0000000..c9ab241
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/softdevice/s112/headers/nrf_sd_def.h
@@ -0,0 +1,59 @@
+/**
+ * Copyright (c) 2015 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#ifndef NRF_SD_DEF_H__
+#define NRF_SD_DEF_H__
+
+#include <stdint.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define SD_PPI_CHANNELS_USED 0xFFFE0000uL /**< PPI channels utilized by SotfDevice (not available to the application). */
+#define SD_PPI_GROUPS_USED 0x0000000CuL /**< PPI groups utilized by SoftDevice (not available to the application). */
+#define SD_TIMERS_USED 0x00000001uL /**< Timers used by SoftDevice. */
+#define SD_SWI_USED 0x0000003CuL /**< Software interrupts used by SoftDevice */
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* NRF_SD_DEF_H__ */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/softdevice/s112/headers/nrf_sdm.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/softdevice/s112/headers/nrf_sdm.h
new file mode 100644
index 0000000..8c48d93
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/softdevice/s112/headers/nrf_sdm.h
@@ -0,0 +1,358 @@
+/*
+ * Copyright (c) 2015 - 2017, 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ */
+
+/**
+ @defgroup nrf_sdm_api SoftDevice Manager API
+ @{
+
+ @brief APIs for SoftDevice management.
+
+*/
+
+#ifndef NRF_SDM_H__
+#define NRF_SDM_H__
+
+#include <stdint.h>
+#include "nrf.h"
+#include "nrf_svc.h"
+#include "nrf_error.h"
+#include "nrf_error_sdm.h"
+#include "nrf_soc.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** @addtogroup NRF_SDM_DEFINES Defines
+ * @{ */
+#ifdef NRFSOC_DOXYGEN
+/// Declared in nrf_mbr.h
+#define MBR_SIZE 0
+#warning test
+#endif
+
+/** @brief The major version for the SoftDevice binary distributed with this header file. */
+#define SD_MAJOR_VERSION (6)
+
+/** @brief The minor version for the SoftDevice binary distributed with this header file. */
+#define SD_MINOR_VERSION (0)
+
+/** @brief The bugfix version for the SoftDevice binary distributed with this header file. */
+#define SD_BUGFIX_VERSION (0)
+
+/** @brief The full version number for the SoftDevice binary this header file was distributed
+ * with, as 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 SD_VERSION (SD_MAJOR_VERSION * 1000000 + SD_MINOR_VERSION * 1000 + SD_BUGFIX_VERSION)
+
+/** @brief SoftDevice Manager SVC Base number. */
+#define SDM_SVC_BASE 0x10
+
+/** @brief SoftDevice unique string size in bytes. */
+#define SD_UNIQUE_STR_SIZE 20
+
+/** @brief Invalid info field. Returned when an info field does not exist. */
+#define SDM_INFO_FIELD_INVALID (0)
+
+/** @brief Defines the SoftDevice Information Structure location (address) as an offset from
+the start of the SoftDevice (without MBR)*/
+#define SOFTDEVICE_INFO_STRUCT_OFFSET (0x2000)
+
+/** @brief Defines the absolute SoftDevice Information Structure location (address) when the
+ * SoftDevice is installed just above the MBR (the usual case). */
+#define SOFTDEVICE_INFO_STRUCT_ADDRESS (SOFTDEVICE_INFO_STRUCT_OFFSET + MBR_SIZE)
+
+/** @brief Defines the offset for the SoftDevice Information Structure size value relative to the
+ * SoftDevice base address. The size value is of type uint8_t. */
+#define SD_INFO_STRUCT_SIZE_OFFSET (SOFTDEVICE_INFO_STRUCT_OFFSET)
+
+/** @brief Defines the offset for the SoftDevice size value relative to the SoftDevice base address.
+ * The size value is of type uint32_t. */
+#define SD_SIZE_OFFSET (SOFTDEVICE_INFO_STRUCT_OFFSET + 0x08)
+
+/** @brief Defines the offset for FWID value relative to the SoftDevice base address. The FWID value
+ * is of type uint16_t. */
+#define SD_FWID_OFFSET (SOFTDEVICE_INFO_STRUCT_OFFSET + 0x0C)
+
+/** @brief Defines the offset for the SoftDevice ID relative to the SoftDevice base address. The ID
+ * is of type uint32_t. */
+#define SD_ID_OFFSET (SOFTDEVICE_INFO_STRUCT_OFFSET + 0x10)
+
+/** @brief Defines the offset for the SoftDevice version relative to the SoftDevice base address in
+ * the same format as @ref SD_VERSION, stored as an uint32_t. */
+#define SD_VERSION_OFFSET (SOFTDEVICE_INFO_STRUCT_OFFSET + 0x14)
+
+/** @brief Defines the offset for the SoftDevice unique string relative to the SoftDevice base address.
+ * The SD_UNIQUE_STR is stored as an array of uint8_t. The size of array is @ref SD_UNIQUE_STR_SIZE.
+ */
+#define SD_UNIQUE_STR_OFFSET (SOFTDEVICE_INFO_STRUCT_OFFSET + 0x18)
+
+/** @brief Defines a macro for retrieving the actual SoftDevice Information Structure size value
+ * from a given base address. Use @ref MBR_SIZE as the argument when the SoftDevice is
+ * installed just above the MBR (the usual case). */
+#define SD_INFO_STRUCT_SIZE_GET(baseaddr) (*((uint8_t *) ((baseaddr) + SD_INFO_STRUCT_SIZE_OFFSET)))
+
+/** @brief Defines a macro for retrieving the actual SoftDevice size value from a given base
+ * address. Use @ref MBR_SIZE as the argument when the SoftDevice is installed just above
+ * the MBR (the usual case). */
+#define SD_SIZE_GET(baseaddr) (*((uint32_t *) ((baseaddr) + SD_SIZE_OFFSET)))
+
+/** @brief Defines a macro for retrieving the actual FWID value from a given base address. Use
+ * @ref MBR_SIZE as the argument when the SoftDevice is installed just above the MBR (the usual
+ * case). */
+#define SD_FWID_GET(baseaddr) (*((uint16_t *) ((baseaddr) + SD_FWID_OFFSET)))
+
+/** @brief Defines a macro for retrieving the actual SoftDevice ID from a given base address. Use
+ * @ref MBR_SIZE as the argument when the SoftDevice is installed just above the MBR (the
+ * usual case). */
+#define SD_ID_GET(baseaddr) ((SD_INFO_STRUCT_SIZE_GET(baseaddr) > (SD_ID_OFFSET - SOFTDEVICE_INFO_STRUCT_OFFSET)) \
+ ? (*((uint32_t *) ((baseaddr) + SD_ID_OFFSET))) : SDM_INFO_FIELD_INVALID)
+
+/** @brief Defines a macro for retrieving the actual SoftDevice version from a given base address.
+ * Use @ref MBR_SIZE as the argument when the SoftDevice is installed just above the MBR
+ * (the usual case). */
+#define SD_VERSION_GET(baseaddr) ((SD_INFO_STRUCT_SIZE_GET(baseaddr) > (SD_VERSION_OFFSET - SOFTDEVICE_INFO_STRUCT_OFFSET)) \
+ ? (*((uint32_t *) ((baseaddr) + SD_VERSION_OFFSET))) : SDM_INFO_FIELD_INVALID)
+
+/** @brief Defines a macro for retrieving the address of SoftDevice unique str based on a given base address.
+ * Use @ref MBR_SIZE as the argument when the SoftDevice is installed just above the MBR
+ * (the usual case). */
+#define SD_UNIQUE_STR_ADDR_GET(baseaddr) ((SD_INFO_STRUCT_SIZE_GET(baseaddr) > (SD_UNIQUE_STR_OFFSET - SOFTDEVICE_INFO_STRUCT_OFFSET)) \
+ ? (((uint8_t *) ((baseaddr) + SD_UNIQUE_STR_OFFSET))) : SDM_INFO_FIELD_INVALID)
+
+/**@defgroup NRF_FAULT_ID_RANGES Fault ID ranges
+ * @{ */
+#define NRF_FAULT_ID_SD_RANGE_START 0x00000000 /**< SoftDevice ID range start. */
+#define NRF_FAULT_ID_APP_RANGE_START 0x00001000 /**< Application ID range start. */
+/**@} */
+
+/**@defgroup NRF_FAULT_IDS Fault ID types
+ * @{ */
+#define NRF_FAULT_ID_SD_ASSERT (NRF_FAULT_ID_SD_RANGE_START + 1) /**< SoftDevice assertion. The info parameter is reserved for future used. */
+#define NRF_FAULT_ID_APP_MEMACC (NRF_FAULT_ID_APP_RANGE_START + 1) /**< Application invalid memory access. The info parameter will contain 0x00000000,
+ in case of SoftDevice RAM access violation. In case of SoftDevice peripheral
+ register violation the info parameter will contain the sub-region number of
+ PREGION[0], on whose address range the disallowed write access caused the
+ memory access fault. */
+/**@} */
+
+/** @} */
+
+/** @addtogroup NRF_SDM_ENUMS Enumerations
+ * @{ */
+
+/**@brief nRF SoftDevice Manager API SVC numbers. */
+enum NRF_SD_SVCS
+{
+ SD_SOFTDEVICE_ENABLE = SDM_SVC_BASE, /**< ::sd_softdevice_enable */
+ SD_SOFTDEVICE_DISABLE, /**< ::sd_softdevice_disable */
+ SD_SOFTDEVICE_IS_ENABLED, /**< ::sd_softdevice_is_enabled */
+ SD_SOFTDEVICE_VECTOR_TABLE_BASE_SET, /**< ::sd_softdevice_vector_table_base_set */
+ SVC_SDM_LAST /**< Placeholder for last SDM SVC */
+};
+
+/** @} */
+
+/** @addtogroup NRF_SDM_DEFINES Defines
+ * @{ */
+
+/**@defgroup NRF_CLOCK_LF_ACCURACY Clock accuracy
+ * @{ */
+
+#define NRF_CLOCK_LF_ACCURACY_250_PPM (0) /**< Default: 250 ppm */
+#define NRF_CLOCK_LF_ACCURACY_500_PPM (1) /**< 500 ppm */
+#define NRF_CLOCK_LF_ACCURACY_150_PPM (2) /**< 150 ppm */
+#define NRF_CLOCK_LF_ACCURACY_100_PPM (3) /**< 100 ppm */
+#define NRF_CLOCK_LF_ACCURACY_75_PPM (4) /**< 75 ppm */
+#define NRF_CLOCK_LF_ACCURACY_50_PPM (5) /**< 50 ppm */
+#define NRF_CLOCK_LF_ACCURACY_30_PPM (6) /**< 30 ppm */
+#define NRF_CLOCK_LF_ACCURACY_20_PPM (7) /**< 20 ppm */
+#define NRF_CLOCK_LF_ACCURACY_10_PPM (8) /**< 10 ppm */
+#define NRF_CLOCK_LF_ACCURACY_5_PPM (9) /**< 5 ppm */
+#define NRF_CLOCK_LF_ACCURACY_2_PPM (10) /**< 2 ppm */
+#define NRF_CLOCK_LF_ACCURACY_1_PPM (11) /**< 1 ppm */
+
+/** @} */
+
+/**@defgroup NRF_CLOCK_LF_SRC Possible LFCLK oscillator sources
+ * @{ */
+
+#define NRF_CLOCK_LF_SRC_RC (0) /**< LFCLK RC oscillator. */
+#define NRF_CLOCK_LF_SRC_XTAL (1) /**< LFCLK crystal oscillator. */
+#define NRF_CLOCK_LF_SRC_SYNTH (2) /**< LFCLK Synthesized from HFCLK. */
+
+/** @} */
+
+/** @} */
+
+/** @addtogroup NRF_SDM_TYPES Types
+ * @{ */
+
+/**@brief Type representing LFCLK oscillator source. */
+typedef struct
+{
+ uint8_t source; /**< LF oscillator clock source, see @ref NRF_CLOCK_LF_SRC. */
+ uint8_t rc_ctiv; /**< Only for ::NRF_CLOCK_LF_SRC_RC: Calibration timer interval in 1/4 second
+ units (nRF52: 1-32).
+ @note To avoid excessive clock drift, 0.5 degrees Celsius is the
+ maximum temperature change allowed in one calibration timer
+ interval. The interval should be selected to ensure this.
+
+ @note Must be 0 if source is not ::NRF_CLOCK_LF_SRC_RC. */
+ uint8_t rc_temp_ctiv; /**< Only for ::NRF_CLOCK_LF_SRC_RC: How often (in number of calibration
+ intervals) the RC oscillator shall be calibrated if the temperature
+ hasn't changed.
+ 0: Always calibrate even if the temperature hasn't changed.
+ 1: Only calibrate if the temperature has changed (legacy - nRF51 only).
+ 2-33: Check the temperature and only calibrate if it has changed,
+ however calibration will take place every rc_temp_ctiv
+ intervals in any case.
+
+ @note Must be 0 if source is not ::NRF_CLOCK_LF_SRC_RC.
+
+ @note For nRF52, the application must ensure calibration at least once
+ every 8 seconds to ensure +/-500 ppm clock stability. The
+ recommended configuration for ::NRF_CLOCK_LF_SRC_RC on nRF52 is
+ rc_ctiv=16 and rc_temp_ctiv=2. This will ensure calibration at
+ least once every 8 seconds and for temperature changes of 0.5
+ degrees Celsius every 4 seconds. See the Product Specification
+ for the nRF52 device being used for more information.*/
+ uint8_t accuracy; /**< External clock accuracy used in the LL to compute timing
+ windows, see @ref NRF_CLOCK_LF_ACCURACY.*/
+} nrf_clock_lf_cfg_t;
+
+/**@brief Fault Handler type.
+ *
+ * When certain unrecoverable errors occur within the application or SoftDevice the fault handler will be called back.
+ * The protocol stack will be in an undefined state when this happens and the only way to recover will be to
+ * perform a reset, using e.g. CMSIS NVIC_SystemReset().
+ * If the application returns from the fault handler the SoftDevice will call NVIC_SystemReset().
+ *
+ * @note This callback is executed in HardFault context, thus SVC functions cannot be called from the fault callback.
+ *
+ * @param[in] id Fault identifier. See @ref NRF_FAULT_IDS.
+ * @param[in] pc The program counter of the instruction that triggered the fault.
+ * @param[in] info Optional additional information regarding the fault. Refer to each Fault identifier for details.
+ *
+ * @note When id is set to @ref NRF_FAULT_ID_APP_MEMACC, pc will contain the address of the instruction being executed at the time when
+ * the fault is detected by the CPU. The CPU program counter may have advanced up to 2 instructions (no branching) after the one that triggered the fault.
+ */
+typedef void (*nrf_fault_handler_t)(uint32_t id, uint32_t pc, uint32_t info);
+
+/** @} */
+
+/** @addtogroup NRF_SDM_FUNCTIONS Functions
+ * @{ */
+
+/**@brief Enables the SoftDevice and by extension the protocol stack.
+ *
+ * @note Some care must be taken if a low frequency clock source is already running when calling this function:
+ * If the LF clock has a different source then the one currently running, it will be stopped. Then, the new
+ * clock source will be started.
+ *
+ * @note This function has no effect when returning with an error.
+ *
+ * @post If return code is ::NRF_SUCCESS
+ * - SoC library and protocol stack APIs are made available.
+ * - A portion of RAM will be unavailable (see relevant SDS documentation).
+ * - Some peripherals will be unavailable or available only through the SoC API (see relevant SDS documentation).
+ * - Interrupts will not arrive from protected peripherals or interrupts.
+ * - nrf_nvic_ functions must be used instead of CMSIS NVIC_ functions for reliable usage of the SoftDevice.
+ * - Interrupt latency may be affected by the SoftDevice (see relevant SDS documentation).
+ * - Chosen low frequency clock source will be running.
+ *
+ * @param p_clock_lf_cfg Low frequency clock source and accuracy.
+ If NULL the clock will be configured as an RC source with rc_ctiv = 16 and .rc_temp_ctiv = 2
+ In the case of XTAL source, the PPM accuracy of the chosen clock source must be greater than or equal to the actual characteristics of your XTAL clock.
+ * @param fault_handler Callback to be invoked in case of fault, cannot be NULL.
+ *
+ * @retval ::NRF_SUCCESS
+ * @retval ::NRF_ERROR_INVALID_ADDR Invalid or NULL pointer supplied.
+ * @retval ::NRF_ERROR_INVALID_STATE SoftDevice is already enabled, and the clock source and fault handler cannot be updated.
+ * @retval ::NRF_ERROR_SDM_INCORRECT_INTERRUPT_CONFIGURATION SoftDevice interrupt is already enabled, or an enabled interrupt has an illegal priority level.
+ * @retval ::NRF_ERROR_SDM_LFCLK_SOURCE_UNKNOWN Unknown low frequency clock source selected.
+ * @retval ::NRF_ERROR_INVALID_PARAM Invalid clock source configuration supplied in p_clock_lf_cfg.
+ */
+SVCALL(SD_SOFTDEVICE_ENABLE, uint32_t, sd_softdevice_enable(nrf_clock_lf_cfg_t const * p_clock_lf_cfg, nrf_fault_handler_t fault_handler));
+
+
+/**@brief Disables the SoftDevice and by extension the protocol stack.
+ *
+ * Idempotent function to disable the SoftDevice.
+ *
+ * @post SoC library and protocol stack APIs are made unavailable.
+ * @post All interrupts that was protected by the SoftDevice will be disabled and initialized to priority 0 (highest).
+ * @post All peripherals used by the SoftDevice will be reset to default values.
+ * @post All of RAM become available.
+ * @post All interrupts are forwarded to the application.
+ * @post LFCLK source chosen in ::sd_softdevice_enable will be left running.
+ *
+ * @retval ::NRF_SUCCESS
+ */
+SVCALL(SD_SOFTDEVICE_DISABLE, uint32_t, sd_softdevice_disable(void));
+
+/**@brief Check if the SoftDevice is enabled.
+ *
+ * @param[out] p_softdevice_enabled If the SoftDevice is enabled: 1 else 0.
+ *
+ * @retval ::NRF_SUCCESS
+ */
+SVCALL(SD_SOFTDEVICE_IS_ENABLED, uint32_t, sd_softdevice_is_enabled(uint8_t * p_softdevice_enabled));
+
+/**@brief Sets the base address of the interrupt vector table for interrupts forwarded from the SoftDevice
+ *
+ * This function is only intended to be called when a bootloader is enabled.
+ *
+ * @param[in] address The base address of the interrupt vector table for forwarded interrupts.
+
+ * @retval ::NRF_SUCCESS
+ */
+SVCALL(SD_SOFTDEVICE_VECTOR_TABLE_BASE_SET, uint32_t, sd_softdevice_vector_table_base_set(uint32_t address));
+
+/** @} */
+
+#ifdef __cplusplus
+}
+#endif
+#endif // NRF_SDM_H__
+
+/**
+ @}
+*/
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/softdevice/s112/headers/nrf_soc.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/softdevice/s112/headers/nrf_soc.h
new file mode 100644
index 0000000..2c4d958
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/softdevice/s112/headers/nrf_soc.h
@@ -0,0 +1,964 @@
+/*
+ * Copyright (c) 2015 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ */
+
+/**
+ * @defgroup nrf_soc_api SoC Library API
+ * @{
+ *
+ * @brief APIs for the SoC library.
+ *
+ */
+
+#ifndef NRF_SOC_H__
+#define NRF_SOC_H__
+
+#include <stdint.h>
+#include "nrf.h"
+#include "nrf_svc.h"
+#include "nrf_error.h"
+#include "nrf_error_soc.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**@addtogroup NRF_SOC_DEFINES Defines
+ * @{ */
+
+/**@brief The number of the lowest SVC number reserved for the SoC library. */
+#define SOC_SVC_BASE (0x20) /**< Base value for SVCs that are available when the SoftDevice is disabled. */
+#define SOC_SVC_BASE_NOT_AVAILABLE (0x2C) /**< Base value for SVCs that are not available when the SoftDevice is disabled. */
+
+/**@brief Guaranteed time for application to process radio inactive notification. */
+#define NRF_RADIO_NOTIFICATION_INACTIVE_GUARANTEED_TIME_US (62)
+
+/**@brief The minimum allowed timeslot extension time. */
+#define NRF_RADIO_MINIMUM_TIMESLOT_LENGTH_EXTENSION_TIME_US (200)
+
+/**@brief The maximum processing time to handle a timeslot extension. */
+#define NRF_RADIO_MAX_EXTENSION_PROCESSING_TIME_US (17)
+
+/**@brief The latest time before the end of a timeslot the timeslot can be extended. */
+#define NRF_RADIO_MIN_EXTENSION_MARGIN_US (79)
+
+#define SOC_ECB_KEY_LENGTH (16) /**< ECB key length. */
+#define SOC_ECB_CLEARTEXT_LENGTH (16) /**< ECB cleartext length. */
+#define SOC_ECB_CIPHERTEXT_LENGTH (SOC_ECB_CLEARTEXT_LENGTH) /**< ECB ciphertext length. */
+
+#define SD_EVT_IRQn (SWI2_IRQn) /**< SoftDevice Event IRQ number. Used for both protocol events and SoC events. */
+#define SD_EVT_IRQHandler (SWI2_IRQHandler) /**< SoftDevice Event IRQ handler. Used for both protocol events and SoC events.
+ The default interrupt priority for this handler is set to 4 */
+#define RADIO_NOTIFICATION_IRQn (SWI1_IRQn) /**< The radio notification IRQ number. */
+#define RADIO_NOTIFICATION_IRQHandler (SWI1_IRQHandler) /**< The radio notification IRQ handler.
+ The default interrupt priority for this handler is set to 4 */
+#define NRF_RADIO_LENGTH_MIN_US (100) /**< The shortest allowed radio timeslot, in microseconds. */
+#define NRF_RADIO_LENGTH_MAX_US (100000) /**< The longest allowed radio timeslot, in microseconds. */
+
+#define NRF_RADIO_DISTANCE_MAX_US (128000000UL - 1UL) /**< The longest timeslot distance, in microseconds, allowed for the distance parameter (see @ref nrf_radio_request_normal_t) in the request. */
+
+#define NRF_RADIO_EARLIEST_TIMEOUT_MAX_US (128000000UL - 1UL) /**< The longest timeout, in microseconds, allowed when requesting the earliest possible timeslot. */
+
+#define NRF_RADIO_START_JITTER_US (2) /**< The maximum jitter in @ref NRF_RADIO_CALLBACK_SIGNAL_TYPE_START relative to the requested start time. */
+
+/**@} */
+
+/**@addtogroup NRF_SOC_ENUMS Enumerations
+ * @{ */
+
+/**@brief The SVC numbers used by the SVC functions in the SoC library. */
+enum NRF_SOC_SVCS
+{
+ SD_PPI_CHANNEL_ENABLE_GET = SOC_SVC_BASE,
+ SD_PPI_CHANNEL_ENABLE_SET = SOC_SVC_BASE + 1,
+ SD_PPI_CHANNEL_ENABLE_CLR = SOC_SVC_BASE + 2,
+ SD_PPI_CHANNEL_ASSIGN = SOC_SVC_BASE + 3,
+ SD_PPI_GROUP_TASK_ENABLE = SOC_SVC_BASE + 4,
+ SD_PPI_GROUP_TASK_DISABLE = SOC_SVC_BASE + 5,
+ SD_PPI_GROUP_ASSIGN = SOC_SVC_BASE + 6,
+ SD_PPI_GROUP_GET = SOC_SVC_BASE + 7,
+ SD_FLASH_PAGE_ERASE = SOC_SVC_BASE + 8,
+ SD_FLASH_WRITE = SOC_SVC_BASE + 9,
+ SD_FLASH_PROTECT = SOC_SVC_BASE + 10,
+ SD_PROTECTED_REGISTER_WRITE = SOC_SVC_BASE + 11,
+ SD_MUTEX_NEW = SOC_SVC_BASE_NOT_AVAILABLE,
+ SD_MUTEX_ACQUIRE = SOC_SVC_BASE_NOT_AVAILABLE + 1,
+ SD_MUTEX_RELEASE = SOC_SVC_BASE_NOT_AVAILABLE + 2,
+ SD_RAND_APPLICATION_POOL_CAPACITY_GET = SOC_SVC_BASE_NOT_AVAILABLE + 3,
+ SD_RAND_APPLICATION_BYTES_AVAILABLE_GET = SOC_SVC_BASE_NOT_AVAILABLE + 4,
+ SD_RAND_APPLICATION_VECTOR_GET = SOC_SVC_BASE_NOT_AVAILABLE + 5,
+ SD_POWER_MODE_SET = SOC_SVC_BASE_NOT_AVAILABLE + 6,
+ SD_POWER_SYSTEM_OFF = SOC_SVC_BASE_NOT_AVAILABLE + 7,
+ SD_POWER_RESET_REASON_GET = SOC_SVC_BASE_NOT_AVAILABLE + 8,
+ SD_POWER_RESET_REASON_CLR = SOC_SVC_BASE_NOT_AVAILABLE + 9,
+ SD_POWER_POF_ENABLE = SOC_SVC_BASE_NOT_AVAILABLE + 10,
+ SD_POWER_POF_THRESHOLD_SET = SOC_SVC_BASE_NOT_AVAILABLE + 11,
+ SD_POWER_RAM_POWER_SET = SOC_SVC_BASE_NOT_AVAILABLE + 13,
+ SD_POWER_RAM_POWER_CLR = SOC_SVC_BASE_NOT_AVAILABLE + 14,
+ SD_POWER_RAM_POWER_GET = SOC_SVC_BASE_NOT_AVAILABLE + 15,
+ SD_POWER_GPREGRET_SET = SOC_SVC_BASE_NOT_AVAILABLE + 16,
+ SD_POWER_GPREGRET_CLR = SOC_SVC_BASE_NOT_AVAILABLE + 17,
+ SD_POWER_GPREGRET_GET = SOC_SVC_BASE_NOT_AVAILABLE + 18,
+ SD_POWER_DCDC_MODE_SET = SOC_SVC_BASE_NOT_AVAILABLE + 19,
+ SD_APP_EVT_WAIT = SOC_SVC_BASE_NOT_AVAILABLE + 21,
+ SD_CLOCK_HFCLK_REQUEST = SOC_SVC_BASE_NOT_AVAILABLE + 22,
+ SD_CLOCK_HFCLK_RELEASE = SOC_SVC_BASE_NOT_AVAILABLE + 23,
+ SD_CLOCK_HFCLK_IS_RUNNING = SOC_SVC_BASE_NOT_AVAILABLE + 24,
+ SD_RADIO_NOTIFICATION_CFG_SET = SOC_SVC_BASE_NOT_AVAILABLE + 25,
+ SD_ECB_BLOCK_ENCRYPT = SOC_SVC_BASE_NOT_AVAILABLE + 26,
+ SD_ECB_BLOCKS_ENCRYPT = SOC_SVC_BASE_NOT_AVAILABLE + 27,
+ SD_RADIO_SESSION_OPEN = SOC_SVC_BASE_NOT_AVAILABLE + 28,
+ SD_RADIO_SESSION_CLOSE = SOC_SVC_BASE_NOT_AVAILABLE + 29,
+ SD_RADIO_REQUEST = SOC_SVC_BASE_NOT_AVAILABLE + 30,
+ SD_EVT_GET = SOC_SVC_BASE_NOT_AVAILABLE + 31,
+ SD_TEMP_GET = SOC_SVC_BASE_NOT_AVAILABLE + 32,
+ SVC_SOC_LAST = SOC_SVC_BASE_NOT_AVAILABLE + 37
+};
+
+/**@brief Possible values of a ::nrf_mutex_t. */
+enum NRF_MUTEX_VALUES
+{
+ NRF_MUTEX_FREE,
+ NRF_MUTEX_TAKEN
+};
+
+/**@brief Power modes. */
+enum NRF_POWER_MODES
+{
+ NRF_POWER_MODE_CONSTLAT, /**< Constant latency mode. See power management in the reference manual. */
+ NRF_POWER_MODE_LOWPWR /**< Low power mode. See power management in the reference manual. */
+};
+
+
+/**@brief Power failure thresholds */
+enum NRF_POWER_THRESHOLDS
+{
+ NRF_POWER_THRESHOLD_V17 = 4UL, /**< 1.7 Volts power failure threshold. */
+ NRF_POWER_THRESHOLD_V18, /**< 1.8 Volts power failure threshold. */
+ NRF_POWER_THRESHOLD_V19, /**< 1.9 Volts power failure threshold. */
+ NRF_POWER_THRESHOLD_V20, /**< 2.0 Volts power failure threshold. */
+ NRF_POWER_THRESHOLD_V21, /**< 2.1 Volts power failure threshold. */
+ NRF_POWER_THRESHOLD_V22, /**< 2.2 Volts power failure threshold. */
+ NRF_POWER_THRESHOLD_V23, /**< 2.3 Volts power failure threshold. */
+ NRF_POWER_THRESHOLD_V24, /**< 2.4 Volts power failure threshold. */
+ NRF_POWER_THRESHOLD_V25, /**< 2.5 Volts power failure threshold. */
+ NRF_POWER_THRESHOLD_V26, /**< 2.6 Volts power failure threshold. */
+ NRF_POWER_THRESHOLD_V27, /**< 2.7 Volts power failure threshold. */
+ NRF_POWER_THRESHOLD_V28 /**< 2.8 Volts power failure threshold. */
+};
+
+
+
+/**@brief DC/DC converter modes. */
+enum NRF_POWER_DCDC_MODES
+{
+ NRF_POWER_DCDC_DISABLE, /**< The DCDC is disabled. */
+ NRF_POWER_DCDC_ENABLE /**< The DCDC is enabled. */
+};
+
+/**@brief Radio notification distances. */
+enum NRF_RADIO_NOTIFICATION_DISTANCES
+{
+ NRF_RADIO_NOTIFICATION_DISTANCE_NONE = 0, /**< The event does not have a notification. */
+ NRF_RADIO_NOTIFICATION_DISTANCE_800US, /**< The distance from the active notification to start of radio activity. */
+ NRF_RADIO_NOTIFICATION_DISTANCE_1740US, /**< The distance from the active notification to start of radio activity. */
+ NRF_RADIO_NOTIFICATION_DISTANCE_2680US, /**< The distance from the active notification to start of radio activity. */
+ NRF_RADIO_NOTIFICATION_DISTANCE_3620US, /**< The distance from the active notification to start of radio activity. */
+ NRF_RADIO_NOTIFICATION_DISTANCE_4560US, /**< The distance from the active notification to start of radio activity. */
+ NRF_RADIO_NOTIFICATION_DISTANCE_5500US /**< The distance from the active notification to start of radio activity. */
+};
+
+
+/**@brief Radio notification types. */
+enum NRF_RADIO_NOTIFICATION_TYPES
+{
+ NRF_RADIO_NOTIFICATION_TYPE_NONE = 0, /**< The event does not have a radio notification signal. */
+ NRF_RADIO_NOTIFICATION_TYPE_INT_ON_ACTIVE, /**< Using interrupt for notification when the radio will be enabled. */
+ NRF_RADIO_NOTIFICATION_TYPE_INT_ON_INACTIVE, /**< Using interrupt for notification when the radio has been disabled. */
+ NRF_RADIO_NOTIFICATION_TYPE_INT_ON_BOTH, /**< Using interrupt for notification both when the radio will be enabled and disabled. */
+};
+
+/**@brief The Radio signal callback types. */
+enum NRF_RADIO_CALLBACK_SIGNAL_TYPE
+{
+ NRF_RADIO_CALLBACK_SIGNAL_TYPE_START, /**< This signal indicates the start of the radio timeslot. */
+ NRF_RADIO_CALLBACK_SIGNAL_TYPE_TIMER0, /**< This signal indicates the NRF_TIMER0 interrupt. */
+ NRF_RADIO_CALLBACK_SIGNAL_TYPE_RADIO, /**< This signal indicates the NRF_RADIO interrupt. */
+ NRF_RADIO_CALLBACK_SIGNAL_TYPE_EXTEND_FAILED, /**< This signal indicates extend action failed. */
+ NRF_RADIO_CALLBACK_SIGNAL_TYPE_EXTEND_SUCCEEDED /**< This signal indicates extend action succeeded. */
+};
+
+/**@brief The actions requested by the signal callback.
+ *
+ * This code gives the SOC instructions about what action to take when the signal callback has
+ * returned.
+ */
+enum NRF_RADIO_SIGNAL_CALLBACK_ACTION
+{
+ NRF_RADIO_SIGNAL_CALLBACK_ACTION_NONE, /**< Return without action. */
+ NRF_RADIO_SIGNAL_CALLBACK_ACTION_EXTEND, /**< Request an extension of the current
+ timeslot. Maximum execution time for this action:
+ @ref NRF_RADIO_MAX_EXTENSION_PROCESSING_TIME_US.
+ This action must be started at least
+ @ref NRF_RADIO_MIN_EXTENSION_MARGIN_US before
+ the end of the timeslot. */
+ NRF_RADIO_SIGNAL_CALLBACK_ACTION_END, /**< End the current radio timeslot. */
+ NRF_RADIO_SIGNAL_CALLBACK_ACTION_REQUEST_AND_END /**< Request a new radio timeslot and end the current timeslot. */
+};
+
+/**@brief Radio timeslot high frequency clock source configuration. */
+enum NRF_RADIO_HFCLK_CFG
+{
+ NRF_RADIO_HFCLK_CFG_XTAL_GUARANTEED, /**< The SoftDevice will guarantee that the high frequency clock source is the
+ external crystal for the whole duration of the timeslot. This should be the
+ preferred option for events that use the radio or require high timing accuracy.
+ @note The SoftDevice will automatically turn on and off the external crystal,
+ at the beginning and end of the timeslot, respectively. The crystal may also
+ intentionally be left running after the timeslot, in cases where it is needed
+ by the SoftDevice shortly after the end of the timeslot. */
+ NRF_RADIO_HFCLK_CFG_NO_GUARANTEE /**< This configuration allows for earlier and tighter scheduling of timeslots.
+ The RC oscillator may be the clock source in part or for the whole duration of the timeslot.
+ The RC oscillator's accuracy must therefore be taken into consideration.
+ @note If the application will use the radio peripheral in timeslots with this configuration,
+ it must make sure that the crystal is running and stable before starting the radio. */
+};
+
+/**@brief Radio timeslot priorities. */
+enum NRF_RADIO_PRIORITY
+{
+ NRF_RADIO_PRIORITY_HIGH, /**< High (equal priority as the normal connection priority of the SoftDevice stack(s)). */
+ NRF_RADIO_PRIORITY_NORMAL, /**< Normal (equal priority as the priority of secondary activities of the SoftDevice stack(s)). */
+};
+
+/**@brief Radio timeslot request type. */
+enum NRF_RADIO_REQUEST_TYPE
+{
+ NRF_RADIO_REQ_TYPE_EARLIEST, /**< Request radio timeslot as early as possible. This should always be used for the first request in a session. */
+ NRF_RADIO_REQ_TYPE_NORMAL /**< Normal radio timeslot request. */
+};
+
+/**@brief SoC Events. */
+enum NRF_SOC_EVTS
+{
+ NRF_EVT_HFCLKSTARTED, /**< Event indicating that the HFCLK has started. */
+ NRF_EVT_POWER_FAILURE_WARNING, /**< Event indicating that a power failure warning has occurred. */
+ NRF_EVT_FLASH_OPERATION_SUCCESS, /**< Event indicating that the ongoing flash operation has completed successfully. */
+ NRF_EVT_FLASH_OPERATION_ERROR, /**< Event indicating that the ongoing flash operation has timed out with an error. */
+ NRF_EVT_RADIO_BLOCKED, /**< Event indicating that a radio timeslot was blocked. */
+ NRF_EVT_RADIO_CANCELED, /**< Event indicating that a radio timeslot was canceled by SoftDevice. */
+ NRF_EVT_RADIO_SIGNAL_CALLBACK_INVALID_RETURN, /**< Event indicating that a radio timeslot signal callback handler return was invalid. */
+ NRF_EVT_RADIO_SESSION_IDLE, /**< Event indicating that a radio timeslot session is idle. */
+ NRF_EVT_RADIO_SESSION_CLOSED, /**< Event indicating that a radio timeslot session is closed. */
+ NRF_EVT_NUMBER_OF_EVTS
+};
+
+/**@} */
+
+
+/**@addtogroup NRF_SOC_STRUCTURES Structures
+ * @{ */
+
+/**@brief Represents a mutex for use with the nrf_mutex functions.
+ * @note Accessing the value directly is not safe, use the mutex functions!
+ */
+typedef volatile uint8_t nrf_mutex_t;
+
+/**@brief Parameters for a request for a timeslot as early as possible. */
+typedef struct
+{
+ uint8_t hfclk; /**< High frequency clock source, see @ref NRF_RADIO_HFCLK_CFG. */
+ uint8_t priority; /**< The radio timeslot priority, see @ref NRF_RADIO_PRIORITY. */
+ uint32_t length_us; /**< The radio timeslot length (in the range 100 to 100,000] microseconds). */
+ uint32_t timeout_us; /**< Longest acceptable delay until the start of the requested timeslot (up to @ref NRF_RADIO_EARLIEST_TIMEOUT_MAX_US microseconds). */
+} nrf_radio_request_earliest_t;
+
+/**@brief Parameters for a normal radio timeslot request. */
+typedef struct
+{
+ uint8_t hfclk; /**< High frequency clock source, see @ref NRF_RADIO_HFCLK_CFG. */
+ uint8_t priority; /**< The radio timeslot priority, see @ref NRF_RADIO_PRIORITY. */
+ uint32_t distance_us; /**< Distance from the start of the previous radio timeslot (up to @ref NRF_RADIO_DISTANCE_MAX_US microseconds). */
+ uint32_t length_us; /**< The radio timeslot length (in the range [100..100,000] microseconds). */
+} nrf_radio_request_normal_t;
+
+/**@brief Radio timeslot request parameters. */
+typedef struct
+{
+ uint8_t request_type; /**< Type of request, see @ref NRF_RADIO_REQUEST_TYPE. */
+ union
+ {
+ nrf_radio_request_earliest_t earliest; /**< Parameters for requesting a radio timeslot as early as possible. */
+ nrf_radio_request_normal_t normal; /**< Parameters for requesting a normal radio timeslot. */
+ } params; /**< Parameter union. */
+} nrf_radio_request_t;
+
+/**@brief Return parameters of the radio timeslot signal callback. */
+typedef struct
+{
+ uint8_t callback_action; /**< The action requested by the application when returning from the signal callback, see @ref NRF_RADIO_SIGNAL_CALLBACK_ACTION. */
+ union
+ {
+ struct
+ {
+ nrf_radio_request_t * p_next; /**< The request parameters for the next radio timeslot. */
+ } request; /**< Additional parameters for return_code @ref NRF_RADIO_SIGNAL_CALLBACK_ACTION_REQUEST_AND_END. */
+ struct
+ {
+ uint32_t length_us; /**< Requested extension of the radio timeslot duration (microseconds) (for minimum time see @ref NRF_RADIO_MINIMUM_TIMESLOT_LENGTH_EXTENSION_TIME_US). */
+ } extend; /**< Additional parameters for return_code @ref NRF_RADIO_SIGNAL_CALLBACK_ACTION_EXTEND. */
+ } params; /**< Parameter union. */
+} nrf_radio_signal_callback_return_param_t;
+
+/**@brief The radio timeslot signal callback type.
+ *
+ * @note In case of invalid return parameters, the radio timeslot will automatically end
+ * immediately after returning from the signal callback and the
+ * @ref NRF_EVT_RADIO_SIGNAL_CALLBACK_INVALID_RETURN event will be sent.
+ * @note The returned struct pointer must remain valid after the signal callback
+ * function returns. For instance, this means that it must not point to a stack variable.
+ *
+ * @param[in] signal_type Type of signal, see @ref NRF_RADIO_CALLBACK_SIGNAL_TYPE.
+ *
+ * @return Pointer to structure containing action requested by the application.
+ */
+typedef nrf_radio_signal_callback_return_param_t * (*nrf_radio_signal_callback_t) (uint8_t signal_type);
+
+/**@brief AES ECB parameter typedefs */
+typedef uint8_t soc_ecb_key_t[SOC_ECB_KEY_LENGTH]; /**< Encryption key type. */
+typedef uint8_t soc_ecb_cleartext_t[SOC_ECB_CLEARTEXT_LENGTH]; /**< Cleartext data type. */
+typedef uint8_t soc_ecb_ciphertext_t[SOC_ECB_CIPHERTEXT_LENGTH]; /**< Ciphertext data type. */
+
+/**@brief AES ECB data structure */
+typedef struct
+{
+ soc_ecb_key_t key; /**< Encryption key. */
+ soc_ecb_cleartext_t cleartext; /**< Cleartext data. */
+ soc_ecb_ciphertext_t ciphertext; /**< Ciphertext data. */
+} nrf_ecb_hal_data_t;
+
+/**@brief AES ECB block. Used to provide multiple blocks in a single call
+ to @ref sd_ecb_blocks_encrypt.*/
+typedef struct
+{
+ soc_ecb_key_t const * p_key; /**< Pointer to the Encryption key. */
+ soc_ecb_cleartext_t const * p_cleartext; /**< Pointer to the Cleartext data. */
+ soc_ecb_ciphertext_t * p_ciphertext; /**< Pointer to the Ciphertext data. */
+} nrf_ecb_hal_data_block_t;
+
+/**@} */
+
+/**@addtogroup NRF_SOC_FUNCTIONS Functions
+ * @{ */
+
+/**@brief Initialize a mutex.
+ *
+ * @param[in] p_mutex Pointer to the mutex to initialize.
+ *
+ * @retval ::NRF_SUCCESS
+ */
+SVCALL(SD_MUTEX_NEW, uint32_t, sd_mutex_new(nrf_mutex_t * p_mutex));
+
+/**@brief Attempt to acquire a mutex.
+ *
+ * @param[in] p_mutex Pointer to the mutex to acquire.
+ *
+ * @retval ::NRF_SUCCESS The mutex was successfully acquired.
+ * @retval ::NRF_ERROR_SOC_MUTEX_ALREADY_TAKEN The mutex could not be acquired.
+ */
+SVCALL(SD_MUTEX_ACQUIRE, uint32_t, sd_mutex_acquire(nrf_mutex_t * p_mutex));
+
+/**@brief Release a mutex.
+ *
+ * @param[in] p_mutex Pointer to the mutex to release.
+ *
+ * @retval ::NRF_SUCCESS
+ */
+SVCALL(SD_MUTEX_RELEASE, uint32_t, sd_mutex_release(nrf_mutex_t * p_mutex));
+
+/**@brief Query the capacity of the application random pool.
+ *
+ * @param[out] p_pool_capacity The capacity of the pool.
+ *
+ * @retval ::NRF_SUCCESS
+ */
+SVCALL(SD_RAND_APPLICATION_POOL_CAPACITY_GET, uint32_t, sd_rand_application_pool_capacity_get(uint8_t * p_pool_capacity));
+
+/**@brief Get number of random bytes available to the application.
+ *
+ * @param[out] p_bytes_available The number of bytes currently available in the pool.
+ *
+ * @retval ::NRF_SUCCESS
+ */
+SVCALL(SD_RAND_APPLICATION_BYTES_AVAILABLE_GET, uint32_t, sd_rand_application_bytes_available_get(uint8_t * p_bytes_available));
+
+/**@brief Get random bytes from the application pool.
+ *
+ * @param[out] p_buff Pointer to unit8_t buffer for storing the bytes.
+ * @param[in] length Number of bytes to take from pool and place in p_buff.
+ *
+ * @retval ::NRF_SUCCESS The requested bytes were written to p_buff.
+ * @retval ::NRF_ERROR_SOC_RAND_NOT_ENOUGH_VALUES No bytes were written to the buffer, because there were not enough bytes available.
+*/
+SVCALL(SD_RAND_APPLICATION_VECTOR_GET, uint32_t, sd_rand_application_vector_get(uint8_t * p_buff, uint8_t length));
+
+/**@brief Gets the reset reason register.
+ *
+ * @param[out] p_reset_reason Contents of the NRF_POWER->RESETREAS register.
+ *
+ * @retval ::NRF_SUCCESS
+ */
+SVCALL(SD_POWER_RESET_REASON_GET, uint32_t, sd_power_reset_reason_get(uint32_t * p_reset_reason));
+
+/**@brief Clears the bits of the reset reason register.
+ *
+ * @param[in] reset_reason_clr_msk Contains the bits to clear from the reset reason register.
+ *
+ * @retval ::NRF_SUCCESS
+ */
+SVCALL(SD_POWER_RESET_REASON_CLR, uint32_t, sd_power_reset_reason_clr(uint32_t reset_reason_clr_msk));
+
+/**@brief Sets the power mode when in CPU sleep.
+ *
+ * @param[in] power_mode The power mode to use when in CPU sleep, see @ref NRF_POWER_MODES. @sa sd_app_evt_wait
+ *
+ * @retval ::NRF_SUCCESS The power mode was set.
+ * @retval ::NRF_ERROR_SOC_POWER_MODE_UNKNOWN The power mode was unknown.
+ */
+SVCALL(SD_POWER_MODE_SET, uint32_t, sd_power_mode_set(uint8_t power_mode));
+
+/**@brief Puts the chip in System OFF mode.
+ *
+ * @retval ::NRF_ERROR_SOC_POWER_OFF_SHOULD_NOT_RETURN
+ */
+SVCALL(SD_POWER_SYSTEM_OFF, uint32_t, sd_power_system_off(void));
+
+/**@brief Enables or disables the power-fail comparator.
+ *
+ * Enabling this will give a SoftDevice event (NRF_EVT_POWER_FAILURE_WARNING) when the power failure warning occurs.
+ * The event can be retrieved with sd_evt_get();
+ *
+ * @param[in] pof_enable True if the power-fail comparator should be enabled, false if it should be disabled.
+ *
+ * @retval ::NRF_SUCCESS
+ */
+SVCALL(SD_POWER_POF_ENABLE, uint32_t, sd_power_pof_enable(uint8_t pof_enable));
+
+
+/**@brief Sets the power failure comparator threshold value.
+ *
+ *
+ * @param[in] threshold The power-fail threshold value to use, see @ref NRF_POWER_THRESHOLDS.
+ *
+ * @retval ::NRF_SUCCESS The power failure threshold was set.
+ * @retval ::NRF_ERROR_SOC_POWER_POF_THRESHOLD_UNKNOWN The power failure threshold is unknown.
+ */
+SVCALL(SD_POWER_POF_THRESHOLD_SET, uint32_t, sd_power_pof_threshold_set(uint8_t threshold));
+
+
+/**@brief Writes the NRF_POWER->RAM[index].POWERSET register.
+ *
+ * @param[in] index Contains the index in the NRF_POWER->RAM[index].POWERSET register to write to.
+ * @param[in] ram_powerset Contains the word to write to the NRF_POWER->RAM[index].POWERSET register.
+ *
+ * @retval ::NRF_SUCCESS
+ */
+SVCALL(SD_POWER_RAM_POWER_SET, uint32_t, sd_power_ram_power_set(uint8_t index, uint32_t ram_powerset));
+
+/**@brief Writes the NRF_POWER->RAM[index].POWERCLR register.
+ *
+ * @param[in] index Contains the index in the NRF_POWER->RAM[index].POWERCLR register to write to.
+ * @param[in] ram_powerclr Contains the word to write to the NRF_POWER->RAM[index].POWERCLR register.
+ *
+ * @retval ::NRF_SUCCESS
+ */
+SVCALL(SD_POWER_RAM_POWER_CLR, uint32_t, sd_power_ram_power_clr(uint8_t index, uint32_t ram_powerclr));
+
+/**@brief Get contents of NRF_POWER->RAM[index].POWER register, indicates power status of RAM[index] blocks.
+ *
+ * @param[in] index Contains the index in the NRF_POWER->RAM[index].POWER register to read from.
+ * @param[out] p_ram_power Content of NRF_POWER->RAM[index].POWER register.
+ *
+ * @retval ::NRF_SUCCESS
+ */
+SVCALL(SD_POWER_RAM_POWER_GET, uint32_t, sd_power_ram_power_get(uint8_t index, uint32_t * p_ram_power));
+
+/**@brief Set bits in the general purpose retention registers (NRF_POWER->GPREGRET*).
+ *
+ * @param[in] gpregret_id 0 for GPREGRET, 1 for GPREGRET2.
+ * @param[in] gpregret_msk Bits to be set in the GPREGRET register.
+ *
+ * @retval ::NRF_SUCCESS
+ */
+SVCALL(SD_POWER_GPREGRET_SET, uint32_t, sd_power_gpregret_set(uint32_t gpregret_id, uint32_t gpregret_msk));
+
+/**@brief Clear bits in the general purpose retention registers (NRF_POWER->GPREGRET*).
+ *
+ * @param[in] gpregret_id 0 for GPREGRET, 1 for GPREGRET2.
+ * @param[in] gpregret_msk Bits to be clear in the GPREGRET register.
+ *
+ * @retval ::NRF_SUCCESS
+ */
+SVCALL(SD_POWER_GPREGRET_CLR, uint32_t, sd_power_gpregret_clr(uint32_t gpregret_id, uint32_t gpregret_msk));
+
+/**@brief Get contents of the general purpose retention registers (NRF_POWER->GPREGRET*).
+ *
+ * @param[in] gpregret_id 0 for GPREGRET, 1 for GPREGRET2.
+ * @param[out] p_gpregret Contents of the GPREGRET register.
+ *
+ * @retval ::NRF_SUCCESS
+ */
+SVCALL(SD_POWER_GPREGRET_GET, uint32_t, sd_power_gpregret_get(uint32_t gpregret_id, uint32_t *p_gpregret));
+
+/**@brief Enable or disable the DC/DC regulator.
+ *
+ * @param[in] dcdc_mode The mode of the DCDC, see @ref NRF_POWER_DCDC_MODES.
+ *
+ * @retval ::NRF_SUCCESS
+ * @retval ::NRF_ERROR_INVALID_PARAM The DCDC mode is invalid.
+ */
+SVCALL(SD_POWER_DCDC_MODE_SET, uint32_t, sd_power_dcdc_mode_set(uint8_t dcdc_mode));
+
+
+/**@brief Request the high frequency crystal oscillator.
+ *
+ * Will start the high frequency crystal oscillator, the startup time of the crystal varies
+ * and the ::sd_clock_hfclk_is_running function can be polled to check if it has started.
+ *
+ * @see sd_clock_hfclk_is_running
+ * @see sd_clock_hfclk_release
+ *
+ * @retval ::NRF_SUCCESS
+ */
+SVCALL(SD_CLOCK_HFCLK_REQUEST, uint32_t, sd_clock_hfclk_request(void));
+
+/**@brief Releases the high frequency crystal oscillator.
+ *
+ * Will stop the high frequency crystal oscillator, this happens immediately.
+ *
+ * @see sd_clock_hfclk_is_running
+ * @see sd_clock_hfclk_request
+ *
+ * @retval ::NRF_SUCCESS
+ */
+SVCALL(SD_CLOCK_HFCLK_RELEASE, uint32_t, sd_clock_hfclk_release(void));
+
+/**@brief Checks if the high frequency crystal oscillator is running.
+ *
+ * @see sd_clock_hfclk_request
+ * @see sd_clock_hfclk_release
+ *
+ * @param[out] p_is_running 1 if the external crystal oscillator is running, 0 if not.
+ *
+ * @retval ::NRF_SUCCESS
+ */
+SVCALL(SD_CLOCK_HFCLK_IS_RUNNING, uint32_t, sd_clock_hfclk_is_running(uint32_t * p_is_running));
+
+/**@brief Waits for an application event.
+ *
+ * An application event is either an application interrupt or a pended interrupt when the interrupt
+ * is disabled.
+ *
+ * When the application waits for an application event by calling this function, an interrupt that
+ * is enabled will be taken immediately on pending since this function will wait in thread mode,
+ * then the execution will return in the application's main thread.
+ *
+ * In order to wake up from disabled interrupts, the SEVONPEND flag has to be set in the Cortex-M
+ * MCU's System Control Register (SCR), CMSIS_SCB. In that case, when a disabled interrupt gets
+ * pended, this function will return to the application's main thread.
+ *
+ * @note The application must ensure that the pended flag is cleared using ::sd_nvic_ClearPendingIRQ
+ * in order to sleep using this function. This is only necessary for disabled interrupts, as
+ * the interrupt handler will clear the pending flag automatically for enabled interrupts.
+ *
+ * @note If an application interrupt has happened since the last time sd_app_evt_wait was
+ * called this function will return immediately and not go to sleep. This is to avoid race
+ * conditions that can occur when a flag is updated in the interrupt handler and processed
+ * in the main loop.
+ *
+ * @post An application interrupt has happened or a interrupt pending flag is set.
+ *
+ * @retval ::NRF_SUCCESS
+ */
+SVCALL(SD_APP_EVT_WAIT, uint32_t, sd_app_evt_wait(void));
+
+/**@brief Get PPI channel enable register contents.
+ *
+ * @param[out] p_channel_enable The contents of the PPI CHEN register.
+ *
+ * @retval ::NRF_SUCCESS
+ */
+SVCALL(SD_PPI_CHANNEL_ENABLE_GET, uint32_t, sd_ppi_channel_enable_get(uint32_t * p_channel_enable));
+
+/**@brief Set PPI channel enable register.
+ *
+ * @param[in] channel_enable_set_msk Mask containing the bits to set in the PPI CHEN register.
+ *
+ * @retval ::NRF_SUCCESS
+ */
+SVCALL(SD_PPI_CHANNEL_ENABLE_SET, uint32_t, sd_ppi_channel_enable_set(uint32_t channel_enable_set_msk));
+
+/**@brief Clear PPI channel enable register.
+ *
+ * @param[in] channel_enable_clr_msk Mask containing the bits to clear in the PPI CHEN register.
+ *
+ * @retval ::NRF_SUCCESS
+ */
+SVCALL(SD_PPI_CHANNEL_ENABLE_CLR, uint32_t, sd_ppi_channel_enable_clr(uint32_t channel_enable_clr_msk));
+
+/**@brief Assign endpoints to a PPI channel.
+ *
+ * @param[in] channel_num Number of the PPI channel to assign.
+ * @param[in] evt_endpoint Event endpoint of the PPI channel.
+ * @param[in] task_endpoint Task endpoint of the PPI channel.
+ *
+ * @retval ::NRF_ERROR_SOC_PPI_INVALID_CHANNEL The channel number is invalid.
+ * @retval ::NRF_SUCCESS
+ */
+SVCALL(SD_PPI_CHANNEL_ASSIGN, uint32_t, sd_ppi_channel_assign(uint8_t channel_num, const volatile void * evt_endpoint, const volatile void * task_endpoint));
+
+/**@brief Task to enable a channel group.
+ *
+ * @param[in] group_num Number of the channel group.
+ *
+ * @retval ::NRF_ERROR_SOC_PPI_INVALID_GROUP The group number is invalid
+ * @retval ::NRF_SUCCESS
+ */
+SVCALL(SD_PPI_GROUP_TASK_ENABLE, uint32_t, sd_ppi_group_task_enable(uint8_t group_num));
+
+/**@brief Task to disable a channel group.
+ *
+ * @param[in] group_num Number of the PPI group.
+ *
+ * @retval ::NRF_ERROR_SOC_PPI_INVALID_GROUP The group number is invalid.
+ * @retval ::NRF_SUCCESS
+ */
+SVCALL(SD_PPI_GROUP_TASK_DISABLE, uint32_t, sd_ppi_group_task_disable(uint8_t group_num));
+
+/**@brief Assign PPI channels to a channel group.
+ *
+ * @param[in] group_num Number of the channel group.
+ * @param[in] channel_msk Mask of the channels to assign to the group.
+ *
+ * @retval ::NRF_ERROR_SOC_PPI_INVALID_GROUP The group number is invalid.
+ * @retval ::NRF_SUCCESS
+ */
+SVCALL(SD_PPI_GROUP_ASSIGN, uint32_t, sd_ppi_group_assign(uint8_t group_num, uint32_t channel_msk));
+
+/**@brief Gets the PPI channels of a channel group.
+ *
+ * @param[in] group_num Number of the channel group.
+ * @param[out] p_channel_msk Mask of the channels assigned to the group.
+ *
+ * @retval ::NRF_ERROR_SOC_PPI_INVALID_GROUP The group number is invalid.
+ * @retval ::NRF_SUCCESS
+ */
+SVCALL(SD_PPI_GROUP_GET, uint32_t, sd_ppi_group_get(uint8_t group_num, uint32_t * p_channel_msk));
+
+/**@brief Configures the Radio Notification signal.
+ *
+ * @note
+ * - The notification signal latency depends on the interrupt priority settings of SWI used
+ * for notification signal.
+ * - To ensure that the radio notification signal behaves in a consistent way, the radio
+ * notifications must be configured when there is no protocol stack or other SoftDevice
+ * activity in progress. It is recommended that the radio notification signal is
+ * configured directly after the SoftDevice has been enabled.
+ * - In the period between the ACTIVE signal and the start of the Radio Event, the SoftDevice
+ * will interrupt the application to do Radio Event preparation.
+ * - Using the Radio Notification feature may limit the bandwidth, as the SoftDevice may have
+ * to shorten the connection events to have time for the Radio Notification signals.
+ *
+ * @param[in] type Type of notification signal, see @ref NRF_RADIO_NOTIFICATION_TYPES.
+ * @ref NRF_RADIO_NOTIFICATION_TYPE_NONE shall be used to turn off radio
+ * notification. Using @ref NRF_RADIO_NOTIFICATION_DISTANCE_NONE is
+ * recommended (but not required) to be used with
+ * @ref NRF_RADIO_NOTIFICATION_TYPE_NONE.
+ *
+ * @param[in] distance Distance between the notification signal and start of radio activity, see @ref NRF_RADIO_NOTIFICATION_DISTANCES.
+ * This parameter is ignored when @ref NRF_RADIO_NOTIFICATION_TYPE_NONE or
+ * @ref NRF_RADIO_NOTIFICATION_TYPE_INT_ON_INACTIVE is used.
+ *
+ * @retval ::NRF_ERROR_INVALID_PARAM The group number is invalid.
+ * @retval ::NRF_ERROR_INVALID_STATE A protocol stack or other SoftDevice is running. Stop all
+ * running activities and retry.
+ * @retval ::NRF_SUCCESS
+ */
+SVCALL(SD_RADIO_NOTIFICATION_CFG_SET, uint32_t, sd_radio_notification_cfg_set(uint8_t type, uint8_t distance));
+
+/**@brief Encrypts a block according to the specified parameters.
+ *
+ * 128-bit AES encryption.
+ *
+ * @note:
+ * - The application may set the SEVONPEND bit in the SCR to 1 to make the SoftDevice sleep while
+ * the ECB is running. The SEVONPEND bit should only be cleared (set to 0) from application
+ * main or low interrupt level.
+ *
+ * @param[in, out] p_ecb_data Pointer to the ECB parameters' struct (two input
+ * parameters and one output parameter).
+ *
+ * @retval ::NRF_SUCCESS
+ */
+SVCALL(SD_ECB_BLOCK_ENCRYPT, uint32_t, sd_ecb_block_encrypt(nrf_ecb_hal_data_t * p_ecb_data));
+
+/**@brief Encrypts multiple data blocks provided as an array of data block structures.
+ *
+ * @details: Performs 128-bit AES encryption on multiple data blocks
+ *
+ * @note:
+ * - The application may set the SEVONPEND bit in the SCR to 1 to make the SoftDevice sleep while
+ * the ECB is running. The SEVONPEND bit should only be cleared (set to 0) from application
+ * main or low interrupt level.
+ *
+ * @param[in] block_count Count of blocks in the p_data_blocks array.
+ * @param[in,out] p_data_blocks Pointer to the first entry in a contiguous array of
+ * @ref nrf_ecb_hal_data_block_t structures.
+ *
+ * @retval ::NRF_SUCCESS
+ */
+SVCALL(SD_ECB_BLOCKS_ENCRYPT, uint32_t, sd_ecb_blocks_encrypt(uint8_t block_count, nrf_ecb_hal_data_block_t * p_data_blocks));
+
+/**@brief Gets any pending events generated by the SoC API.
+ *
+ * The application should keep calling this function to get events, until ::NRF_ERROR_NOT_FOUND is returned.
+ *
+ * @param[out] p_evt_id Set to one of the values in @ref NRF_SOC_EVTS, if any events are pending.
+ *
+ * @retval ::NRF_SUCCESS An event was pending. The event id is written in the p_evt_id parameter.
+ * @retval ::NRF_ERROR_NOT_FOUND No pending events.
+ */
+SVCALL(SD_EVT_GET, uint32_t, sd_evt_get(uint32_t * p_evt_id));
+
+/**@brief Get the temperature measured on the chip
+ *
+ * This function will block until the temperature measurement is done.
+ * It takes around 50 us from call to return.
+ *
+ * @param[out] p_temp Result of temperature measurement. Die temperature in 0.25 degrees Celsius.
+ *
+ * @retval ::NRF_SUCCESS A temperature measurement was done, and the temperature was written to temp
+ */
+SVCALL(SD_TEMP_GET, uint32_t, sd_temp_get(int32_t * p_temp));
+
+/**@brief Flash Write
+*
+* Commands to write a buffer to flash
+*
+* If the SoftDevice is enabled:
+* This call initiates the flash access command, and its completion will be communicated to the
+* application with exactly one of the following events:
+* - @ref NRF_EVT_FLASH_OPERATION_SUCCESS - The command was successfully completed.
+* - @ref NRF_EVT_FLASH_OPERATION_ERROR - The command could not be started.
+*
+* If the SoftDevice is not enabled no event will be generated, and this call will return @ref NRF_SUCCESS when the
+ * write has been completed
+*
+* @note
+* - This call takes control over the radio and the CPU during flash erase and write to make sure that
+* they will not interfere with the flash access. This means that all interrupts will be blocked
+* for a predictable time (depending on the NVMC specification in the device's Product Specification
+* and the command parameters).
+* - The data in the p_src buffer should not be modified before the @ref NRF_EVT_FLASH_OPERATION_SUCCESS
+* or the @ref NRF_EVT_FLASH_OPERATION_ERROR have been received if the SoftDevice is enabled.
+* - This call will make the SoftDevice trigger a hardfault when the page is written, if it is
+* protected.
+*
+*
+* @param[in] p_dst Pointer to start of flash location to be written.
+* @param[in] p_src Pointer to buffer with data to be written.
+* @param[in] size Number of 32-bit words to write. Maximum size is the number of words in one
+* flash page. See the device's Product Specification for details.
+*
+* @retval ::NRF_ERROR_INVALID_ADDR Tried to write to a non existing flash address, or p_dst or p_src was unaligned.
+* @retval ::NRF_ERROR_BUSY The previous command has not yet completed.
+* @retval ::NRF_ERROR_INVALID_LENGTH Size was 0, or higher than the maximum allowed size.
+* @retval ::NRF_ERROR_FORBIDDEN Tried to write to an address outside the application flash area.
+* @retval ::NRF_SUCCESS The command was accepted.
+*/
+SVCALL(SD_FLASH_WRITE, uint32_t, sd_flash_write(uint32_t * p_dst, uint32_t const * p_src, uint32_t size));
+
+
+/**@brief Flash Erase page
+*
+* Commands to erase a flash page
+* If the SoftDevice is enabled:
+* This call initiates the flash access command, and its completion will be communicated to the
+* application with exactly one of the following events:
+* - @ref NRF_EVT_FLASH_OPERATION_SUCCESS - The command was successfully completed.
+* - @ref NRF_EVT_FLASH_OPERATION_ERROR - The command could not be started.
+*
+* If the SoftDevice is not enabled no event will be generated, and this call will return @ref NRF_SUCCESS when the
+* erase has been completed
+*
+* @note
+* - This call takes control over the radio and the CPU during flash erase and write to make sure that
+* they will not interfere with the flash access. This means that all interrupts will be blocked
+* for a predictable time (depending on the NVMC specification in the device's Product Specification
+* and the command parameters).
+* - This call will make the SoftDevice trigger a hardfault when the page is erased, if it is
+* protected.
+*
+*
+* @param[in] page_number Page number of the page to erase
+*
+* @retval ::NRF_ERROR_INTERNAL If a new session could not be opened due to an internal error.
+* @retval ::NRF_ERROR_INVALID_ADDR Tried to erase to a non existing flash page.
+* @retval ::NRF_ERROR_BUSY The previous command has not yet completed.
+* @retval ::NRF_ERROR_FORBIDDEN Tried to erase a page outside the application flash area.
+* @retval ::NRF_SUCCESS The command was accepted.
+*/
+SVCALL(SD_FLASH_PAGE_ERASE, uint32_t, sd_flash_page_erase(uint32_t page_number));
+
+
+/**@brief Flash Protection set
+ *
+ * Commands to set the flash protection configuration registers.
+ This sets the CONFIGx registers of the BPROT peripheral.
+ *
+ * @note Not all parameters are valid for all products. Some bits in each parameter may not be
+ * valid for your product. Please refer your Product Specification for more details.
+ *
+ * @note To read the values read them directly. They are only write-protected.
+ *
+ * @note It is possible to use @ref sd_protected_register_write instead of this function.
+ *
+ * @param[in] block_cfg0 Value to be written to the configuration register.
+ * @param[in] block_cfg1 Value to be written to the configuration register.
+ * @param[in] block_cfg2 Value to be written to the configuration register.
+ * @param[in] block_cfg3 Value to be written to the configuration register.
+ *
+ * @retval ::NRF_ERROR_NOT_SUPPORTED Non-zero value supplied to one or more of the unsupported parameters.
+ * @retval ::NRF_SUCCESS Values successfully written to configuration registers.
+ */
+SVCALL(SD_FLASH_PROTECT, uint32_t, sd_flash_protect(uint32_t block_cfg0, uint32_t block_cfg1, uint32_t block_cfg2, uint32_t block_cfg3));
+
+/**@brief Opens a session for radio timeslot requests.
+ *
+ * @note Only one session can be open at a time.
+ * @note p_radio_signal_callback(@ref NRF_RADIO_CALLBACK_SIGNAL_TYPE_START) will be called when the radio timeslot
+ * starts. From this point the NRF_RADIO and NRF_TIMER0 peripherals can be freely accessed
+ * by the application.
+ * @note p_radio_signal_callback(@ref NRF_RADIO_CALLBACK_SIGNAL_TYPE_TIMER0) is called whenever the NRF_TIMER0
+ * interrupt occurs.
+ * @note p_radio_signal_callback(@ref NRF_RADIO_CALLBACK_SIGNAL_TYPE_RADIO) is called whenever the NRF_RADIO
+ * interrupt occurs.
+ * @note p_radio_signal_callback() will be called at ARM interrupt priority level 0. This
+ * implies that none of the sd_* API calls can be used from p_radio_signal_callback().
+ *
+ * @param[in] p_radio_signal_callback The signal callback.
+ *
+ * @retval ::NRF_ERROR_INVALID_ADDR p_radio_signal_callback is an invalid function pointer.
+ * @retval ::NRF_ERROR_BUSY If session cannot be opened.
+ * @retval ::NRF_ERROR_INTERNAL If a new session could not be opened due to an internal error.
+ * @retval ::NRF_SUCCESS Otherwise.
+ */
+ SVCALL(SD_RADIO_SESSION_OPEN, uint32_t, sd_radio_session_open(nrf_radio_signal_callback_t p_radio_signal_callback));
+
+/**@brief Closes a session for radio timeslot requests.
+ *
+ * @note Any current radio timeslot will be finished before the session is closed.
+ * @note If a radio timeslot is scheduled when the session is closed, it will be canceled.
+ * @note The application cannot consider the session closed until the @ref NRF_EVT_RADIO_SESSION_CLOSED
+ * event is received.
+ *
+ * @retval ::NRF_ERROR_FORBIDDEN If session not opened.
+ * @retval ::NRF_ERROR_BUSY If session is currently being closed.
+ * @retval ::NRF_SUCCESS Otherwise.
+ */
+ SVCALL(SD_RADIO_SESSION_CLOSE, uint32_t, sd_radio_session_close(void));
+
+/**@brief Requests a radio timeslot.
+ *
+ * @note The request type is determined by p_request->request_type, and can be one of @ref NRF_RADIO_REQ_TYPE_EARLIEST
+ * and @ref NRF_RADIO_REQ_TYPE_NORMAL. The first request in a session must always be of type @ref NRF_RADIO_REQ_TYPE_EARLIEST.
+ * @note For a normal request (@ref NRF_RADIO_REQ_TYPE_NORMAL), the start time of a radio timeslot is specified by
+ * p_request->distance_us and is given relative to the start of the previous timeslot.
+ * @note A too small p_request->distance_us will lead to a @ref NRF_EVT_RADIO_BLOCKED event.
+ * @note Timeslots scheduled too close will lead to a @ref NRF_EVT_RADIO_BLOCKED event.
+ * @note See the SoftDevice Specification for more on radio timeslot scheduling, distances and lengths.
+ * @note If an opportunity for the first radio timeslot is not found before 100 ms after the call to this
+ * function, it is not scheduled, and instead a @ref NRF_EVT_RADIO_BLOCKED event is sent.
+ * The application may then try to schedule the first radio timeslot again.
+ * @note Successful requests will result in nrf_radio_signal_callback_t(@ref NRF_RADIO_CALLBACK_SIGNAL_TYPE_START).
+ * Unsuccessful requests will result in a @ref NRF_EVT_RADIO_BLOCKED event, see @ref NRF_SOC_EVTS.
+ * @note The jitter in the start time of the radio timeslots is +/- @ref NRF_RADIO_START_JITTER_US us.
+ * @note The nrf_radio_signal_callback_t(@ref NRF_RADIO_CALLBACK_SIGNAL_TYPE_START) call has a latency relative to the
+ * specified radio timeslot start, but this does not affect the actual start time of the timeslot.
+ * @note NRF_TIMER0 is reset at the start of the radio timeslot, and is clocked at 1MHz from the high frequency
+ * (16 MHz) clock source. If p_request->hfclk_force_xtal is true, the high frequency clock is
+ * guaranteed to be clocked from the external crystal.
+ * @note The SoftDevice will neither access the NRF_RADIO peripheral nor the NRF_TIMER0 peripheral
+ * during the radio timeslot.
+ *
+ * @param[in] p_request Pointer to the request parameters.
+ *
+ * @retval ::NRF_ERROR_FORBIDDEN If session not opened or the session is not IDLE.
+ * @retval ::NRF_ERROR_INVALID_ADDR If the p_request pointer is invalid.
+ * @retval ::NRF_ERROR_INVALID_PARAM If the parameters of p_request are not valid.
+ * @retval ::NRF_SUCCESS Otherwise.
+ */
+ SVCALL(SD_RADIO_REQUEST, uint32_t, sd_radio_request(nrf_radio_request_t const * p_request));
+
+/**@brief Write register protected by the SoftDevice
+ *
+ * This function writes to a register that is write-protected by the SoftDevice. Please refer to your
+ * SoftDevice Specification for more details about which registers that are protected by SoftDevice.
+ * This function can write to the following protected peripheral:
+ * - BPROT
+ *
+ * @note Protected registers may be read directly.
+ * @note Register that are write-once will return @ref NRF_SUCCESS on second set, even the value in
+ * the register has not changed. See the Product Specification for more details about register
+ * properties.
+ *
+ * @param[in] p_register Pointer to register to be written.
+ * @param[in] value Value to be written to the register.
+ *
+ * @retval ::NRF_ERROR_INVALID_ADDR This function can not write to the reguested register.
+ * @retval ::NRF_SUCCESS Value successfully written to register.
+ *
+ */
+SVCALL(SD_PROTECTED_REGISTER_WRITE, uint32_t, sd_protected_register_write(volatile uint32_t * p_register, uint32_t value));
+
+/**@} */
+
+#ifdef __cplusplus
+}
+#endif
+#endif // NRF_SOC_H__
+
+/**@} */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/softdevice/s112/headers/nrf_svc.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/softdevice/s112/headers/nrf_svc.h
new file mode 100644
index 0000000..292c692
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/softdevice/s112/headers/nrf_svc.h
@@ -0,0 +1,90 @@
+/*
+ * Copyright (c) 2012 - 2017, 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ */
+
+#ifndef NRF_SVC__
+#define NRF_SVC__
+
+#include "stdint.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifdef SVCALL_AS_NORMAL_FUNCTION
+#define SVCALL(number, return_type, signature) return_type signature
+#else
+
+#ifndef SVCALL
+#if defined (__CC_ARM)
+#define SVCALL(number, return_type, signature) return_type __svc(number) signature
+#elif defined (__GNUC__)
+#ifdef __cplusplus
+#define GCC_CAST_CPP (uint16_t)
+#else
+#define GCC_CAST_CPP
+#endif
+#define SVCALL(number, return_type, signature) \
+ _Pragma("GCC diagnostic push") \
+ _Pragma("GCC diagnostic ignored \"-Wreturn-type\"") \
+ __attribute__((naked)) \
+ __attribute__((unused)) \
+ static return_type signature \
+ { \
+ __asm( \
+ "svc %0\n" \
+ "bx r14" : : "I" (GCC_CAST_CPP number) : "r0" \
+ ); \
+ } \
+ _Pragma("GCC diagnostic pop")
+
+#elif defined (__ICCARM__)
+#define PRAGMA(x) _Pragma(#x)
+#define SVCALL(number, return_type, signature) \
+PRAGMA(swi_number = (number)) \
+ __swi return_type signature;
+#else
+#define SVCALL(number, return_type, signature) return_type signature
+#endif
+#endif // SVCALL
+
+#endif // SVCALL_AS_NORMAL_FUNCTION
+
+#ifdef __cplusplus
+}
+#endif
+#endif // NRF_SVC__
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/softdevice/s112/hex/s112_nrf52_6.0.0_licence-agreement.txt b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/softdevice/s112/hex/s112_nrf52_6.0.0_licence-agreement.txt
new file mode 100644
index 0000000..a71adee
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/softdevice/s112/hex/s112_nrf52_6.0.0_licence-agreement.txt
@@ -0,0 +1,35 @@
+Copyright (c) 2007 - 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, except as embedded into a Nordic
+ Semiconductor ASA integrated circuit in a product or a software update for
+ such product, 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.
+
+4. This software, with or without modification, must only be used with a
+ Nordic Semiconductor ASA integrated circuit.
+
+5. Any software provided in binary form under this license must not be reverse
+ engineered, decompiled, modified and/or disassembled.
+
+THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/softdevice/s112/hex/s112_nrf52_6.0.0_softdevice.hex b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/softdevice/s112/hex/s112_nrf52_6.0.0_softdevice.hex
new file mode 100644
index 0000000..874d0d1
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/softdevice/s112/hex/s112_nrf52_6.0.0_softdevice.hex
@@ -0,0 +1,6143 @@
+:020000040000FA
+:1000000000040020E90800007D050000C908000088
+:1000100087050000910500009B050000000000001E
+:100020000000000000000000000000000D090000BA
+:10003000A505000000000000AF050000B9050000A4
+:10004000C3050000CD050000D7050000E105000054
+:10005000EB050000F5050000FF05000009060000A3
+:10006000130600001D0600002706000031060000F0
+:100070003B060000450600004F0600005906000040
+:10008000630600006D060000770600008106000090
+:100090008B060000950600009F060000A9060000E0
+:1000A000B3060000BD060000C7060000D106000030
+:1000B000DB060000E5060000EF060000F906000080
+:1000C000030700000D0700001707000021070000CC
+:1000D0002B070000350700003F070000490700001C
+:1000E000530700005D07000067070000710700006C
+:1000F0007B070000850700008F07000099070000BC
+:10010000A30700001FB500F003F88DE80F001FBD26
+:1001100000F0E0BB1FB56FF00100009040100390AD
+:10012000029001904FF010208069000B420900F00E
+:100130001F045DF822300120A04083434DF8223097
+:10014000684600F045F91FBDF0B54FF6FF734FF458
+:10015000B4751A466E1E11E0A94201D3344600E080
+:100160000C46091B30F8027B641E3B441A44F9D14B
+:100170009CB204EB134394B204EB12420029EBD17E
+:1001800098B200EB134002EB124140EA0140F0BD8F
+:10019000DE4992B00446D1E90001CDE91001FF2209
+:1001A0004021684600F03CFB94E80F008DE80F000A
+:1001B000684610A902E004C841F8042D8842FAD12B
+:1001C00010216846FFF7C0FF1090AA208DF8440068
+:1001D000FFF7A0FF00F0F3F84FF01024A069102201
+:1001E0006946803000F002F9A069082210A900F0E9
+:1001F000FDF800F0D8F84FF080510A6949690068AD
+:100200004A43824201D8102070470020704710B541
+:10021000D0E900214FF0805002EB8103026944696C
+:100220006243934209D84FF01022536903EB8103D4
+:100230000169406941438B4201D9092010BD5069D1
+:10024000401C01D0002010BD0F2010BD70B501680A
+:100250000446AF4D4FF01020072952D2DFE801F0DD
+:10026000330419293C1E2500D4E902656468294637
+:10027000304600F0CDF82A462146304600F0B6F868
+:10028000AA002146304600F09FFA002800D0032043
+:1002900070BD00F051FB4FF4805007E0201DFFF7C8
+:1002A000AAFF0028F4D100F047FB60682860002016
+:1002B00070BD241D94E80700920000F085FA002824
+:1002C000F6D00E2070BD8069401C12D0201DFFF7B3
+:1002D0009EFF0028F6D109E08069401C09D0201D4E
+:1002E000FFF789FF0028EDD1606820B12046FFF7B5
+:1002F0004FFF042070BDFFF70DFF00F060F800F025
+:1003000052F8072070BD10B50C46182802D0012005
+:10031000086010BD2068FFF799FF206010BD4FF006
+:100320001024A069401C05D0A569A66980353079E4
+:10033000AA2808D06069401C2DD060690068401C64
+:1003400029D060692CE010212846FFF7FDFE3168B6
+:1003500081421CD1A16901F18002C03105E030B1B8
+:1003600008CA51F8040D984201D1012000E0002094
+:100370008A42F4D158B1286810B1042803D0FEE7AE
+:10038000284600F057F862496868086008E000F005
+:1003900016F800F008F84FF480500168491C01D0AD
+:1003A00000F0A4FAFEE7BFF34F8F5A4801685A4A9B
+:1003B00001F4E06111430160BFF34F8FFEE74FF09E
+:1003C00010208169491C02D0806900F0AEB87047E6
+:1003D000524A01681160121D416811604F4A8168DC
+:1003E00010321160111DC068086070472DE9F0419E
+:1003F00017460D460646002406E03046296800F000
+:10040000A7F8641C2D1D361DBC42F6D3BDE8F08153
+:1004100070B50C4605464FF4806608E0284600F0AB
+:1004200084F8B44205D3A4F5806405F58055002C0A
+:10043000F4D170BD4168044609B1012500E00025F2
+:100440004FF010267069A268920000F0BDF9C8B1A3
+:10045000204600F01AF89DB17669A56864684FF4EB
+:10046000002084420AD2854208D229463046FFF74E
+:10047000CFFF2A4621463046FFF7B8FFFFF79FFF20
+:10048000FFF791FFFFF746FEF8E72DE9FF414FF038
+:100490001024616980680D0B01EB800000F6FF708D
+:1004A000010B0020009001900290024603906846E4
+:1004B00001230BE0560902F01F0C50F8267003FAD6
+:1004C0000CFC47EA0C0740F82670521CAA42F1D3F4
+:1004D0000AE04A0901F01F0650F8225003FA06F616
+:1004E000354340F82250491C8029F2D3A169090BF9
+:1004F0004A0901F01F0150F822408B409C4340F80C
+:100500002240FFF765FFBDE8FF8100005C090000A5
+:10051000000000200CED00E00400FA050006004099
+:10052000144801680029FCD07047134A0221116069
+:1005300010490B68002BFCD00F4B1B1D186008687E
+:100540000028FCD00020106008680028FCD070470C
+:10055000094B10B501221A60064A1468002CFCD021
+:10056000016010680028FCD0002018601068002886
+:10057000FCD010BD00E4014004E5014008208F4993
+:1005800009680958084710208C4909680958084724
+:1005900014208A49096809580847182087490968BA
+:1005A0000958084730208549096809580847382004
+:1005B00082490968095808473C2080490968095858
+:1005C000084740207D4909680958084744207B496D
+:1005D00009680958084748207849096809580847B0
+:1005E0004C20764909680958084750207349096822
+:1005F0000958084754207149096809580847582084
+:100600006E490968095808475C206C49096809580F
+:100610000847602069490968095808476420674904
+:100620000968095808476820644909680958084753
+:100630006C20624909680958084770205F490968B9
+:100640000958084774205D49096809580847782007
+:100650005A490968095808477C20584909680958C7
+:10066000084780205549096809580847842053499C
+:1006700009680958084788205049096809580847F7
+:100680008C204E4909680958084790204B49096851
+:10069000095808479420494909680958084798208B
+:1006A00046490968095808479C204449096809587F
+:1006B0000847A0204149096809580847A4203F4934
+:1006C000096809580847A8203C490968095808479B
+:1006D000AC203A49096809580847B02037490968E9
+:1006E00009580847B4203549096809580847B8200F
+:1006F0003249096809580847BC2030490968095837
+:100700000847C0202D49096809580847C4202B49CB
+:10071000096809580847C82028490968095808473E
+:10072000CC202649096809580847D0202349096880
+:1007300009580847D4202149096809580847D82092
+:100740001E49096809580847DC201C4909680958EE
+:100750000847E0201949096809580847E420174963
+:10076000096809580847E8201449096809580847E2
+:10077000EC201249096809580847F0200F49096818
+:1007800009580847F4200D49096809580847F82016
+:100790000A49096809580847FC20084909680958A6
+:1007A00008475FF480700549096809580847000048
+:1007B00003480449024A034B704700000000002030
+:1007C000680900006809000040EA010310B59B07B2
+:1007D0000FD1042A0DD310C808C9121F9C42F8D0AB
+:1007E00020BA19BA884201D9012010BD4FF0FF305C
+:1007F00010BD1AB1D30703D0521C07E0002010BD72
+:1008000010F8013B11F8014B1B1B07D110F8013BFD
+:1008100011F8014B1B1B01D1921EF1D1184610BDDE
+:1008200002F0FF0343EA032242EA024200F005B865
+:100830007047704770474FF000020429C0F01280E3
+:1008400010F0030C00F01B80CCF1040CBCF1020F83
+:1008500018BF00F8012BA8BF20F8022BA1EB0C0158
+:1008600000F00DB85FEAC17C24BF00F8012B00F84E
+:10087000012B48BF00F8012B70474FF0000200B574
+:10088000134694469646203922BFA0E80C50A0E8B3
+:100890000C50B1F12001BFF4F7AF090728BFA0E861
+:1008A0000C5048BF0CC05DF804EB890028BF40F82D
+:1008B000042B08BF704748BF20F8022B11F0804F6F
+:1008C00018BF00F8012B7047014B1B68DB68184705
+:1008D0000000002009480A497047FFF7FBFFFFF7B7
+:1008E00011FC00BD20BFFDE7064B1847064A10600B
+:1008F000016881F30888406800470000680900002B
+:10090000680900001F030000000000201EF0040F13
+:100910000CBFEFF30881EFF3098188690238007892
+:10092000182803D100E00000074A1047074A126860
+:100930002C3212681047000000B5054B1B68054AB1
+:100940009B58984700BD00000703000000000020EE
+:100950005809000004000000001000000000000022
+:0809600000FFFFFF0090D0032F
+:10100000900D0020A9800100AD2E00001B80010082
+:10101000AD2E0000AD2E0000AD2E0000000000003F
+:10102000000000000000000000000000018101003D
+:10103000AD2E000000000000AD2E0000AD2E00001F
+:10104000698101006F810100AD2E0000AD2E00000E
+:10105000AD2E0000AD2E0000AD2E0000AD2E000024
+:1010600075810100AD2E0000AD2E00007B810100D6
+:10107000AD2E000081810100878101008D8101007A
+:10108000AD2E0000AD2E0000AD2E0000AD2E0000F4
+:10109000AD2E0000AD2E0000AD2E0000AD2E0000E4
+:1010A000AD2E000093810100AD2E0000AD2E00009A
+:1010B000AD2E0000AD2E0000AD2E0000AD2E0000C4
+:1010C00099810100AD2E0000AD2E0000AD2E000074
+:1010D000AD2E0000AD2E0000AD2E0000AD2E0000A4
+:1010E000AD2E0000AD2E0000AD2E0000AD2E000094
+:1010F000AD2E0000AD2E0000AD2E0000AD2E000084
+:10110000AD2E0000AD2E000000F002F816F0B9FF81
+:101110000AA090E8000C82448344AAF10107DA4552
+:1011200001D116F0AEFFAFF2090EBAE80F0013F0CE
+:10113000010F18BFFB1A43F001031847B8740100F0
+:10114000D87401000A4410F8014B14F00F0508BFD1
+:1011500010F8015B240908BF10F8014B6D1E05D083
+:1011600010F8013B6D1E01F8013BF9D1641E03D05C
+:10117000641E01F8015BFBD19142E4D3704700008B
+:101180000023002400250026103A28BF78C1FBD890
+:10119000520728BF30C148BF0B6070471FB500F031
+:1011A00031F88DE80F001FBD8269034981614FF05E
+:1011B0000100104470470000BD11000001B41EB4CE
+:1011C00000B501F0FBFE01B40198864601BC01B0F8
+:1011D0001EBD0000F0B44046494652465B460FB47F
+:1011E00002A0013001B50648004700BF01BC864699
+:1011F0000FBC8046894692469B46F0BC7047000073
+:101200000911000016F03ABF70B51B4C05460920C5
+:101210002070A01C00F061F85920A08029462046CB
+:10122000BDE8704006F058BD06F061BD70B50C46D3
+:101230001249097829B1A0F160015E2908D3012083
+:1012400013E0602804D0692802D043F201000CE0CA
+:1012500020CC0B4E94E80E0006EB8000A0F58050E9
+:10126000241FD0F8806E2846B047206070BD012052
+:101270007047062070470000080000201C00002076
+:10128000C881010010B504460021012000F032F8A9
+:1012900000210B2000F02EF80421192000F02AF87C
+:1012A00004210D2000F026F804210E2000F022F881
+:1012B00004210F2000F01EF80421C84300F01AF8A2
+:1012C0000621162000F016F80621152000F012F86D
+:1012D0002046FFF799FF002010BDA721018070472D
+:1012E000FFF7A2BF002070470A487047FFF79EBF74
+:1012F000704770474907090E002806DA00F00F0012
+:1013000000F1E02080F8141D704700F1E02080F823
+:101310000014704703F9004230B5FF4D0446062C17
+:10132000A9780ED2DFE804F0030E0E0E0509FFDFE8
+:1013300008E0022906D0FFDF04E0032902D0FFDF26
+:1013400000E0FFDFAC7030BDF34810B5407E4108CF
+:10135000F14800F11A0005D00AF07BFBBDE810400F
+:1013600006F058BB0AF05CFBF8E730B50446A1F183
+:1013700020000D460A2847D2DFE800F005070C19C7
+:10138000202532373C41FFDF3FE0207820283CD148
+:10139000FFDF3AE0E0488078052836D0207824281E
+:1013A00033D0252831D023282FD0FFDF2DE020781F
+:1013B00022282AD0232828D8FFDF26E020782228D8
+:1013C00023D0FFDF21E0207822281ED024281CD043
+:1013D00026281AD0272818D0292816D0FFDF14E095
+:1013E0002078252811D0FFDF0FE0207825280CD0A9
+:1013F000FFDF0AE02078252807D0FFDF05E020780E
+:10140000282802D0FFDF00E0FFDF257030BD1FB5C8
+:101410000022ADF800200C88ADF802404B88ADF8F2
+:101420000430CA88ADF808208988ADF8061000217C
+:10143000ADF80A10ADF80C1080B14FF6FF70062120
+:10144000844201D1ADF80210834201D1ADF80410FD
+:10145000824203D14FF44860ADF8080068460AF0B4
+:101460002DFC06F0D7FA04B010BD70B514460D4639
+:1014700006460FF00FFA60B90DB1A54201D90C2054
+:1014800070BD002409E000BF56F824000FF002FAF6
+:1014900008B1102070BD641CE4B2AC42F4D300204B
+:1014A00070BD2DE9F04105461F4690460E460024CA
+:1014B00000680FF03CFA10B11020BDE8F0812868F8
+:1014C0000028A88802D0B84202D84FE00028F4D003
+:1014D0000920F2E72868025DB2B1611C475C152F54
+:1014E0002DD03BDC3AD2DFE807F03912222228283F
+:1014F0002A2A3131393939393939393939392200DA
+:10150000025D32BB641CA4B2A142F9D833E0022AC6
+:10151000DED1A21C805C88F80000072801D24007B9
+:1015200001D40A20C9E7307840F0010015E0D0432B
+:10153000C00707E0012A07D010E00620BDE710072A
+:10154000A0F180500028F5D01846B6E73078820721
+:1015500001D50B20B1E740F0020030702868005D33
+:10156000084484B2A888A04202D2B1E74FF448539D
+:1015700081B2A142AED800209FE710B5027854088E
+:1015800009D0012243F20223012C07D0022C0DD0F6
+:10159000032C13D10FE00020087005E080790324AC
+:1015A000B4EB901F0AD10A70002010BD8079B2EB15
+:1015B000901F03D1F7E780798009F4D0184610BD59
+:1015C00038B50C460546694601F089F800280DD16A
+:1015D0009DF80010207861F34700207055F8010F46
+:1015E000C4F80100A888A4F80500002038BD38B56B
+:1015F0001378C0B1022816D048A46D462468009420
+:101600004C7905EB9414247864F347031370032892
+:101610000ED003F0FE0010700868C2F80100888840
+:10162000A2F8050038BD23F0FE0313700228EED1A6
+:10163000D8B240F00100EEE702210BF07DBC38B5D6
+:101640000C460978222901D2082038BDADF80000E7
+:101650008DF8022068460AF038FA06F0DBF905003A
+:1016600003D121212046FFF780FE284638BD1CB556
+:1016700000208DF80000CDF80100ADF805002648E7
+:1016800090F82200022801D0012000E000208DF80F
+:10169000070068460AF086FA002800D0FFDF1CBD6C
+:1016A0002DE9FF478CB00026BDF8347082461C46F9
+:1016B00090468DF81C60780703D560680FF0EAF853
+:1016C00068B9154D4FF0010995F8220058B195F809
+:1016D0002300022807D160680FF029F918B1102003
+:1016E00010B0BDE8F087380702D5A08980281AD845
+:1016F000780704D4B8F1000F01D0287E98B1E07DBE
+:10170000C0F300108DF81B00617D072069B101292D
+:101710000BD00229E4D003E0900100200302FF0176
+:101720000429DDD118E00720DAE78DF817908DF84D
+:1017300019908DF8158060684F4678B107A9FFF7BA
+:101740001CFF0028CCD1606850F8011FCDF80F10A5
+:101750008088ADF8130005E00620C1E7CDF80F60E2
+:10176000ADF81360E07B0028F6D1207C0028F3D18F
+:10177000607C0028F0D1A07C0028EDD1E07CC00680
+:10178000EAD18DF800A0BDF83400ADF80200A068E1
+:101790000190A0680290FEA0D0E90010CDE90A10E7
+:1017A000E07C0AA901EB50101B3900788DF80C0081
+:1017B00095F8220030B195F82300022818D00328AC
+:1017C00004D119E0F44800F08AFF00B1FFDF9DF872
+:1017D0001C008DF80E008DF818608DF816608DF8DD
+:1017E0001A6009A968460AF0A5FA06F013F977E726
+:1017F00003208DF80D00EAE78DF80D70E7E7F0B5EE
+:101800009DB000228DF868208DF858208DF860205A
+:1018100005468DF86C20129213921492159219B10C
+:101820000FC912AC84E80F00DB4C193CA0780528E6
+:1018300001D004280CD112986168884200D120B9E7
+:101840001498E168884203D110B108201DB0F0BDA2
+:101850001F26334618AA1AA912A8FFF722FE00284D
+:10186000F4D133461BAA16A914A8FFF71AFE0028C4
+:10187000ECD19DF85800C00701D00A20E6E7A08A05
+:10188000410708D4A17D31B19DF86010890702D0CD
+:1018900043F20120DAE79DF86010C90709D040073C
+:1018A00007D4208818B144F25061884201D907203A
+:1018B000CCE78DF8005003268DF8016001278DF8E4
+:1018C0000270BDF84C208DF8032001A8129916F083
+:1018D000D6FA68460AF08DFA06F09CF80028B5D1D1
+:1018E0008DF824508DF825608DF82670BDF85420B1
+:1018F0008DF827200AA8149916F0C1FA09A80AF051
+:101900009CFA06F087F80028A0D112AD241D95E8B6
+:101910000F0084E80F00002098E72DE9FE43040043
+:1019200000D1FFDF20789C4E20F00F00801C20F0BB
+:10193000F000703020706068193E0178C91F1229CC
+:1019400029D2DFE801F04BFD2809FDFD38FB2828EE
+:1019500064FBFA2828FBFBF986883046FFF76CFE0B
+:101960000546304609F0B1FCB8B16068807985F869
+:101970003E0021212846FFF7F8FC304603F07FFAAD
+:10198000304604F0E9FB314601200EF037FFA87F16
+:1019900020F01000A877BDE8FE83207820F0F0004A
+:1019A0002030207006202072668060688079607226
+:1019B00006F013FADDE785882846FFF73DFE00B9FB
+:1019C000FFDF60688078012800D0FFDF60688179E0
+:1019D00003B02846BDE8F04309F0A6BD868830462E
+:1019E000FFF72AFE050000D1FFDF06F0F6F9606878
+:1019F0003146C088288160680089688160684089B4
+:101A0000A88101200EF0FAFE0020A875C3E78078B7
+:101A1000022808D000B1FFDF06F0DFF96568A87979
+:101A2000AD1C10B102E0FFDFB5E7FFDFF778B5F8D6
+:101A30000290B046384605F08DFF060000D1FFDF6A
+:101A40000022022148460BF06EFA040000D1FFDFAD
+:101A500022212046FFF789FCA17F012060F30101CC
+:101A6000A177298B2181698B6181A98BA18184F860
+:101A700022708DF8080002AA032148460BF053FAA1
+:101A800000B9FFDFB088ADF80400B0788DF806002B
+:101A900001AA052148460BF046FA00B9FFDFB088DD
+:101AA000ADF80000F0788DF802006A46042148463F
+:101AB0000BF039FA00B9FFDF062105F1120000F042
+:101AC0002BFE08B36879800700D5FFDF6979E07DD8
+:101AD00061F34700E075D5F80600A0616889A0832E
+:101AE000062105F10C0000F017FEB8B198F81910A6
+:101AF0004A08617862F347016170D8F81A10C4F897
+:101B00000210B8F81E0012E0E07D20F0FE00801CFC
+:101B1000E075D5F81200A061E88AE0E7607820F06F
+:101B2000FE00801C6070E868C4F80200288AE0802B
+:101B30000320FFF7F1FB2EE707E012E00DE0FFE7DF
+:101B40002046BDE8FE4301F020BD06F046F916F838
+:101B5000240F40F0040030701DE7BDE8FE4306F09E
+:101B60003CB9B178052908D00429E4D106F035F94B
+:101B70000220BDE8FE43FFF7CFBB80780028DAD013
+:101B8000F07800F093FD06F028F90320F1E700005B
+:101B90000706050403020100A90100202DE9F04712
+:101BA000054600780027000991460C463E4601286C
+:101BB00073D0022872D0072809D00A2824D0FFDF6A
+:101BC000A9F800600CB127806680002089E5D5F86F
+:101BD00004C0DFF8AC874FF0010A9CF800004FF614
+:101BE000FF7113287AD008DC07280ED00E281FD0EA
+:101BF000112826D0122806D186E016280BD01728E7
+:101C000059D018286CD02146FBE012271026BCF8CA
+:101C100004002146B8E01C270A26ECB3BCF80200F9
+:101C2000A080686800792072686840796072C7E7B0
+:101C30001B27092684B30320207268684088A0808F
+:101C4000BEE79CF802003C28BAD010272C260CF1E5
+:101C5000020C0CB3BCF80200A080BCF81800608233
+:101C6000BCF818002082BCF81A00A082BCF81C0046
+:101C7000E0829CF8050004F108020CF10601FFF770
+:101C8000B6FC9CF8040001289AD184F80FA000202B
+:101C9000207608F1040002E00AE06DE077E090E8C9
+:101CA0000E00D8F81000C4E90930C4E9071287E72C
+:101CB000A9F8006089E720271126002CF8D0A18020
+:101CC000686804F10A02807820726868807A60721D
+:101CD0006968C878091DFFF78AFC71E729E0FFE70A
+:101CE00021270A26002CE3D0BCF80200A0806868F7
+:101CF0000079207268684079607298F8241021F0A9
+:101D0000040188F824105BE722270B26002CCFD093
+:101D1000BCF80400A08068688078207268688079C8
+:101D200000F009FD60726868C07900F004FDA072DF
+:101D300046E726271C26002CBAD0A1806868C07808
+:101D4000607268688079A07208F1040090E80E0063
+:101D5000D8F81000C4E90530C4E903126868807837
+:101D60003C2803D0432804D0FFDF29E784F808A0EB
+:101D700026E70220207223E7287A022801D0FFDF1D
+:101D80001EE712271026688800F0B3FC18E7287AAF
+:101D9000032836D0042834D0052832D0062801D0B4
+:101DA000FFDF0DE711270926002C81D0B5F802804E
+:101DB0004046FFF741FC90F822A0A4F80480687A1E
+:101DC0002072042140460BF0C9F8052140460BF073
+:101DD000C5F8002140460BF0C1F8012140460BF048
+:101DE000BDF8032140460BF0B9F8022140460BF044
+:101DF000B5F8062140460BF0B1F8504600F056FC0D
+:101E0000DEE62846BDE8F04701F0F6BC70B50128D3
+:101E100001D0FFDF70BD8DB22846FFF70DFC040036
+:101E200000D1FFDF20782128F4D005F0D3FF80B166
+:101E3000017821F00F01891C21F0F00110310170AF
+:101E40000221017245800020A075BDE8704005F0B8
+:101E5000C4BF21462846BDE870401322FFF7EFBB00
+:101E60002DE9F04116460C00804600D1FFDF3078A6
+:101E700020F00F00801C20F0F0001030307020782F
+:101E8000022802D0FFDFBDE8F0814046FFF7D4FB17
+:101E9000050000D1FFDF61884FF6FF700027814207
+:101EA00002D1A288824203D0814201D1A08848B1E8
+:101EB00005F093FF2068B0606068F0602089308290
+:101EC000AF75E0E7A87D0128DDD1782300224146E7
+:101ED0000EF0EAFB0220A875D5E738B505460C469A
+:101EE00008460EF0D7FC68B9203D062D30D2DFE859
+:101EF00005F00305222F271B062038BD60680EF071
+:101F00000DFD08B1102038BD618820886A460AF0AE
+:101F1000D5F805F07FFD0028F5D161680029F2D0E1
+:101F2000BDF800200A8038BDA07800F001012088AB
+:101F30000AF0F5F808E02068BDE8384001F092BEEC
+:101F4000618820880AF053F8BDE8384005F062BD8A
+:101F5000072038BD70B505460C4608460EF0C0FC9B
+:101F600008B1102070BD202D07D0212D0DD0222DBD
+:101F70000BD0252D09D0072070BD2088A11C09F0A9
+:101F8000F7FDBDE8704005F045BD062070BDFC487A
+:101F90001930704708B52821F94816F011F80120CA
+:101FA000FFF7BAF9F64968461A3105F0A9FEF44878
+:101FB0009DF80020417E62F3470121F00101417646
+:101FC000002180F822104FF461710184022180F811
+:101FD0002310FFF7B9F900B1FFDF00F0DDFB01F0DE
+:101FE000A7FA08BD10B50C464021204615F0C6FFE3
+:101FF000A07F20F00300A077202020700020A07593
+:1020000084F8230010BD70472DE9FC4107460EF00F
+:1020100041FC10B11020BDE8FC81D94E06F1190138
+:10202000D6F819000090B6F81D50ADF80450F47FB2
+:102030008DF806403846FFF7C3FA0028EBD1FFF7CA
+:1020400083F90028E7D0009946F8191FB580B471CC
+:10205000E1E710B504460EF043FC08B1102010BDB6
+:10206000C748C7492246407E1A314008FFF7BFFAE9
+:10207000002010BDFEB50D4604004FF0000712D041
+:102080000822FFF7F2F9002812D1002609E000BF6C
+:1020900054F826006946FFF770FA002808D1761C2C
+:1020A000F6B2AE42F4D309F012FC10B143F20320B1
+:1020B000FEBDB34E3776FCB100271AE054F8270076
+:1020C00002A9FFF75AFA00B1FFDF9DF808008DF86A
+:1020D000000054F8270050F8011FCDF80110808847
+:1020E000ADF80500684609F017FC00B1FFDF7F1C62
+:1020F000FFB2AF42E2D335760020FEBD2DE9F047B6
+:102100008AB01546894604001DD00F46082229468C
+:10211000FFF7ABF9002810D1002612E054F8260092
+:102120006946103000F0DBFA002806D13FB157F8BD
+:1021300026000EF0AFFB10B110200AB046E5761C69
+:10214000F6B2AE42EAD30026A5F101081CE000BFBA
+:1021500006F1010A0AF0FF0712E000BF54F826005A
+:10216000017C4A0854F827100B7CB2EB530F05D1C1
+:1021700006221130113115F056FE58B17F1CFFB206
+:10218000AF42EBD30AF0FF064645E1DB4E4624B1F1
+:10219000012003E043F20520CFE7002009F0DCFB3B
+:1021A00010B909F0E5FB10B143F20420C5E75CB3B8
+:1021B00000270DF1170825E054F827006946103074
+:1021C00000F08DFA00B1FFDF54F82700102250F81C
+:1021D000111FCDF801108088ADF8050054F82710C4
+:1021E0000DF1070015F04BFE96B156F8271010229E
+:1021F000404615F044FE684609F073FB00B1FFDF6E
+:102200007F1CFFB2AF42D7D3FFF731FA002094E72B
+:10221000404601F01BFDEEE730B585B004460EF0F8
+:1022200039FB18B960680EF082FB10B1102005B0C0
+:1022300030BD60884AF2B811884206D82078504DE7
+:1022400028B1012806D0022804D00720EFE7FFF7C5
+:102250007BF818E06078022804D0032802D043F20B
+:102260000220E4E785F82300C1B200200090ADF819
+:10227000040002292CD0032927D0FFDF684609F08B
+:10228000E8FB05F0C7FB0028D1D1606801F0D1FC64
+:10229000207858B101208DF800000DF1010001F007
+:1022A000D5FC684609F08EFF00B1FFDF207885F885
+:1022B0002200FFF7DCF9608860B1288480B209F061
+:1022C00043FB00B1FFDF0020B1E78DF80500D5E743
+:1022D0004020FAE74FF46170EFE710B504460EF0C6
+:1022E000FFFA20B9606838B10EF018FB08B1102071
+:1022F00010BD606801F0AAFC214830F8201F618001
+:10230000C178617080782070002010BD2DE9F843FD
+:102310001446894606460EF0E3FAA0B948460EF088
+:1023200006FB80B920460EF002FB60B9144DA87878
+:10233000012800D13CB13178FF2906D049B143F2E0
+:102340000400BDE8F8831020FBE7012801D0042039
+:10235000F7E74FF00008B4B3052813D0042811D0D4
+:102360006946204600F0F2F90028EAD1207D58B1F4
+:1023700001280BD002280BD003280BD00720E0E760
+:10238000900100200820DCE7424604E0012202E040
+:10239000022200E003222346174600200099FFF79F
+:1023A0007FF90028CDD1A0892880A07BE875BDF8F1
+:1023B0000000A882AF75BDF80000000701D5A08914
+:1023C00088B1A089288049460020FFF718FA002824
+:1023D000B7D1A87805280BD0042809D0287DC007DC
+:1023E00003D0032002E08020ECE70220FEF794FFF8
+:1023F00086F800800020A4E72DE9FC41E54C064664
+:102400000D46A078022803D0032801D0082002E658
+:1024100016B143F20400FEE506200AF041FD10B9B2
+:10242000A078032845D00CF093FC07460DF027FE5A
+:10243000381A00F0FF0806200AF02AFD0746062099
+:102440000AF02EFD391AA078042809D00022114480
+:10245000A8EB010111F0FF0F04D0032804D00DE018
+:102460000122F4E71320D6E5284605F073FAF0B10F
+:102470004078F0B1284605F054FDE57001208DF854
+:1024800000008DF801008DF802602088ADF804008E
+:10249000E07D8DF80600684609F06CFD05F0BAFA9B
+:1024A0000028B4D1A078032805D0042010E005202E
+:1024B000B1E51220AFE5E07805F04CFA040000D158
+:1024C000FFDF607800B9FFDF6078401E6070052094
+:1024D000FEF722FF00209EE51CB510B143F2040078
+:1024E0001CBDAC4CA078042803D0052801D00820DE
+:1024F0001CBD00208DF8000001218DF801108DF821
+:102500000200684609F036FD05F084FA0028EFD194
+:10251000A078052804D00220FEF7FEFE00201CBD96
+:10252000E07800F0C3F80320F6E72DE9FC4180468F
+:102530000D46032608460EF0FAF908B110206AE5A8
+:102540004046FFF779F8040004D02078222804D20E
+:10255000082060E543F202005DE5A07F00F003077C
+:102560003DB1012F0AD000202946FEF750FF06009A
+:10257000E5D1012F04D0FFDF30464CE50120F3E721
+:10258000A07D2946022801D011B107E0112042E5C3
+:10259000684600F00EFA0028D1D16946404608F09E
+:1025A000A3FF0600E8D10120A075E5E770B50C4651
+:1025B0000546FFF741F8010005D022462846BDE850
+:1025C0007040FFF73CB843F2020070BD10B501281F
+:1025D00007D1704B9B78012B00D011B143F204005E
+:1025E00010BD09F0E3F9BDE8104005F013BA01236E
+:1025F00000F066B800231A46194600F061B870B5BD
+:10260000064615460C4608460EF06AF918B92846E3
+:102610000EF066F908B1102070BD2A4621463046FA
+:1026200009F034FD05F0F6F90028F5D121787F296D
+:10263000F2D1052070BD7CB505460C4608460EF06B
+:1026400029F908B110207CBD2846FEF7F5FF20B11E
+:102650000078222804D208207CBD43F202007CBD11
+:102660004C4890F82400400701D511207CBD21780A
+:10267000C80802D16078C20801D007207CBD890853
+:1026800001D1800801D006207CBDADF80050207833
+:102690008DF8020060788DF803000220ADF8040088
+:1026A000684609F0DCFA05F0B5F97CBD10B505F017
+:1026B00051F9040000D1FFDF6078401C607010BD4C
+:1026C0001CB5ADF800008DF802308DF803108DF8C0
+:1026D0000420684609F0A9FC05F09CF91CBD0278AD
+:1026E000520804D0012A02D043F202207047FEF7BC
+:1026F00044BF70B50C0006460DD0FEF79DFF0500E7
+:1027000000D1FFDFA680288920812889608168891F
+:10271000A081A889E08170BD10B500231A4603E0AE
+:10272000845C2343521CD2B28A42F9D30BB10020FD
+:1027300010BD012010BD00B530B1012803D0022822
+:1027400001D0FFDF002000BDFF2000BD00220A8075
+:1027500092B222F060020A800078062817D2DFE8E1
+:1027600000F0160306090C1142F0110007E042F0D8
+:102770001D0009E042F0150006E042F0100040F0B4
+:10278000020001E042F0100008800020704707209E
+:102790007047000090010020FE4800210160416068
+:1027A000018170472DE9F743044692B09146406895
+:1027B0000EF0B4F840B160680EF0B9F820B9607856
+:1027C00000F00300022801D0012000E00020F14EBB
+:1027D000307248460EF05EF818B1102015B0BDE812
+:1027E000F08349460120FEF712FE0028F6D10125AC
+:1027F0008DF842504FF4C050ADF84000002210A9AF
+:10280000284603F06FFF0028E8D18DF842504FF4BE
+:1028100028504FF00008ADF8400047461C2168469C
+:10282000CDF81C8015F0CCFB9DF81C0008AA20F008
+:102830000F00401C20F0F00010308DF81C002078B4
+:102840008DF81D0061789DF81E0061F3420040F094
+:1028500001008DF81E009DF800000AA940F002005A
+:102860008DF800002089ADF83000ADF83270608935
+:1028700007AFADF834000B97606810AC0E900A9467
+:10288000684603F024FD0028A8D1BDF82000308060
+:102890008DF8425042F60120ADF840009DF81E0030
+:1028A00008AA20F00600801C20F001008DF81E0010
+:1028B0000220ADF83000ADF8340013A80E900AA93C
+:1028C000684603F004FD002888D1BDF82000708020
+:1028D000311D484600F033F9002887D18DF8425069
+:1028E00042F6A620ADF840001C216846CDF81C80B9
+:1028F00015F066FB9DF81C00ADF8345020F00F0079
+:10290000401C20F0F00010308DF81C009DF81D00D8
+:1029100008AA20F0FF008DF81D009DF81E000AA9EE
+:1029200020F0060040F00100801C8DF81E009DF88C
+:1029300000008DF8445040F002008DF80000CDE911
+:102940000A4711A80E90ADF83050684603F0BFFC5E
+:10295000002899D1BDF82000F08000203EE73EB568
+:1029600004460820ADF8000020460DF093FF08B1A2
+:1029700010203EBD21460120FEF749FD0028F8D178
+:102980002088ADF804006088ADF80600A088ADF896
+:102990000800E088ADF80A007E4801AB6A468088EE
+:1029A000002104F099F8BDF800100829E1D00320B7
+:1029B0003EBD1FB50446002002900820ADF8080077
+:1029C000CDF80CD020460DF065FF10B1102004B0FA
+:1029D00010BD704802AA81884FF6FF7004F0BEFA5D
+:1029E0000028F4D1BDF80810082901D00320EEE733
+:1029F000BDF800102180BDF802106180BDF8041000
+:102A0000A180BDF80610E180E1E701B582B00220A7
+:102A1000ADF800005F4802AB6A464088002104F030
+:102A20005BF8BDF80010022900D003200EBD1CB5D4
+:102A3000002100910221ADF8001001900DF050FF2F
+:102A400008B110201CBD53486A4641884FF6FF70FC
+:102A500004F084FABDF800100229F3D003201CBD55
+:102A6000FEB54C4C06461546207A0F46C00705D0E9
+:102A700008460DF00FFF18B11020FEBD0F20FEBD5F
+:102A8000F82D01D90C20FEBD30460DF003FF18BB18
+:102A9000208801A903F064F90028F4D130788DF87A
+:102AA0000500208801A903F0F6FF0028EBD1009073
+:102AB0009DF800009DF8051040F002008DF8000020
+:102AC000090703D040F008008DF80000208869460F
+:102AD00003F07EFF0028D6D1ADF8085020883B4691
+:102AE00002AA002103F0F8FFBDF80810A942CAD0DD
+:102AF0000320FEBD7CB505460020009001900888AB
+:102B0000ADF800000C46284601950DF007FF18B9F6
+:102B100020460DF0E5FE08B110207CBD15B1BDF8D2
+:102B2000000050B11B486A4601884FF6FF7004F060
+:102B300015FABDF8001021807CBD0C207CBD30B59D
+:102B400093B0044600200D460090142101A815F012
+:102B500037FA1C2108A815F033FA9DF80000CDF8CB
+:102B600008D020F00F00401C20F0F00010308DF84D
+:102B700000009DF8010020F0FF008DF801009DF895
+:102B8000200040F002008DF8200001208DF8460062
+:102B900002E00000B801002042F60420ADF8440035
+:102BA00011A801902088ADF83C006088ADF83E0087
+:102BB000A088ADF84000E088ADF842009DF8020022
+:102BC00006AA20F00600801C20F001008DF802000B
+:102BD0000820ADF80C00ADF810000FA8059001A971
+:102BE00008A803F074FB002803D1BDF81800288062
+:102BF000002013B030BD00004FF0E0224FF4004140
+:102C00000020C2F880111D4908701D49900208601B
+:102C1000704770B5194D04462878A04202D00CB117
+:102C200000B1FFDF2878A0420DD01649144A2C705D
+:102C30000020CCB1134E144B1436151F012C03D0B9
+:102C4000022C08D0FFDF70BD0860022008603360EE
+:102C50004FF0407005E008600320086033604FF4D7
+:102C600000001060286070BD086008604FF0607060
+:102C7000106070BD00B5FFDF00BD0000180000202F
+:102C800008F5014000F50040380200200CF04DBF6F
+:102C90000449002008604FF0E0210220C1F88002C2
+:102CA00070470000FC1F004010B50D2000F067F8D1
+:102CB000C4B26FF0040000F062F8C0B2844200D0E9
+:102CC000FFDF36490120086010BD70B50D2000F00F
+:102CD00040F8334C0020C4F800010125C4F8045327
+:102CE0000D2000F041F825604FF0E0216014C1F89C
+:102CF000000170BD10B50D2000F02BF8284801210F
+:102D000041600021C0F80011BDE810400D2000F026
+:102D10002BB8234910B5D1F80001012801D0FFDFFD
+:102D200010BD1E48001D00680022C0B2C1F800217D
+:102D3000BDE810400DF0D6BA10B51948D0F8001112
+:102D40000029FBD0FFF7E5FFBDE810400D2000F0A3
+:102D50000BB800F01F02012191404009800000F1F2
+:102D6000E020C0F88011704700F01F02012191405F
+:102D70004009800000F1E020C0F880127047002870
+:102D800006DA00F00F0000F1E02090F8140D03E0E7
+:102D900000F1E02090F800044009704704D500409D
+:102DA00000D00040704770477047704770477047C9
+:102DB000704700004FF0E0214FF00070C1F8800133
+:102DC000C1F88002334B802283F80024C1F800014F
+:102DD000704700B5024604202F4903E001EBC00311
+:102DE0001B792BB1401EC0B2F8D2FFDFFF2000BD1F
+:102DF00041F8302001EBC00100224A718A710122A2
+:102E00000A7100BD244A002102EBC0000171704725
+:102E100010B50446042800D3FFDF1F4800EBC404AC
+:102E20002079012800D0FFDF6079A179401CC0B271
+:102E3000814200D060714FF0E0214FF00070C1F886
+:102E4000000210BD70B51348042590F80004124E1E
+:102E50004009124C042818D0FFDF16E0217806EB59
+:102E6000C1000279012A08D1427983799A4204D0BB
+:102E70004279827156F8310080472078401CC0B2F8
+:102E80002070042801D3002020706D1EEDB2E5D221
+:102E900070BD000019E000E0880400204800002018
+:102EA0000F4A12680D498A420CD118470C4A126821
+:102EB0000A4B9A4206D101B500F074F8FFF774FF8F
+:102EC000BDE801400749096809580847064807490D
+:102ED000054A064B7047000000000000BEBAFECA5B
+:102EE000A400002004000020900D0020900D002080
+:102EF00070B50C46054606F021FB21462846BDE884
+:102F0000704007F006BC10B50DF07DFEFFF774FEB3
+:102F10000DF038FDBDE810400DF0CABD70B5034698
+:102F2000002002466FF02F050EE09C5CA4F13006F5
+:102F30000A2E02D34FF0FF3070BD00EB800005EB8E
+:102F40004000521C2044D2B28A42EED370BD30B54C
+:102F50000A240AE0B0FBF4F304FB13008D183030B0
+:102F600005F8010C521E1846D2B2002AF2D130BD2B
+:102F700030B500234FF6FF7510E0040A44EA002044
+:102F800084B2C85C6040C0F30314604005EA0034BA
+:102F90004440E0B25B1C84EA40109BB29342ECD305
+:102FA00030BD000070B5154D2878401CC4B268785B
+:102FB000844202D0FFF7FBFE2C7070BD2DE9F0417A
+:102FC0000E4C4FF0E02600BFFFF7EFFE20BF40BFE2
+:102FD00020BF677820786070D6F80052FEF784F939
+:102FE000854305D1D6F8040210B92078B842EBD059
+:102FF000FFF7DAFE0020BDE8F0810000A00000200D
+:103000002CFFFFFFDBE5B15100900100A700FFFF9F
+:1030100070000000808D5B0016425791AD5F58BC78
+:103020008E702F5A0FAA100DBCD52BFD10B504467B
+:103030000DF030FC08B1102010BD2078C0F3021054
+:10304000042807D86078072804D3A178102901D86C
+:10305000814201D2072010BDE078410706D42179D2
+:103060004A0703D4000701D4080701D5062010BD84
+:10307000002010BD70B514460D46064604F0AAFEA9
+:1030800080B10178182221F00F01891C21F0F00194
+:10309000A03100F8081B214614F036FFBDE870404F
+:1030A00004F09BBE29463046BDE870401322FEF76F
+:1030B000C6BA2DE9F047064608A8894690E83004CC
+:1030C0001F4690461421284614F07AFF0021CAF8C2
+:1030D0000010B8F1000F03D0B9F1000F03D114E0D4
+:1030E0003878C00711D020680DF0FAFBC0BBB8F1EA
+:1030F000000F07D120681230286020681430686003
+:103100002068A8602168CAF800103878800724D5A4
+:1031100060680DF003FC18BBB9F1000F21D0FEF779
+:1031200036FF0168C6F868118188A6F86C118079AD
+:1031300086F86E0101F03BFAF84FEF60626862B109
+:1031400096F8680106F2691140081032FEF74FFA4E
+:1031500010223946606814F092FE0020BDE8F08726
+:1031600006E0606820B1E8606068C6F86401F4E7D2
+:103170001020F3E730B5054608780C4620F00F0024
+:10318000401C20F0F001103121700020607095F893
+:10319000230030B104280FD0052811D0062814D000
+:1031A000FFDF20780121B1EB101F04D295F8200039
+:1031B00000F01F00607030BD21F0F000203002E010
+:1031C00021F0F00030302070EBE721F0F0004030CB
+:1031D000F9E7F0B591B0022715460C4606463A4687
+:1031E000ADF80870082103AB07F074FF04900028C5
+:1031F00010D004208DF804008DF80170E034099699
+:1032000005948DF818500AA968460BF087FB00B1A9
+:10321000FFDF012011B0F0BD2DE9F84F0646808A8E
+:103220000C4680B28246FEF707FA0546BB4F30785F
+:10323000203F4FF005094FF000080F287CD2DFE84F
+:1032400000F07BA39D082C5B6A7CBADAFD97489757
+:1032500097000121504609F06FFE040000D1FFDF06
+:1032600097F85C00C00701D0386E0BE0032104F131
+:103270001D000DF018F8D4F81D00A949B0FBF1F2BB
+:1032800001FB1200C4F81D0070686067B068A06799
+:103290002878252872D0FFDF70E00121504609F020
+:1032A0004BFE060000D1FFDF3078810702D5297878
+:1032B000252904D040F001003070BDE8F88F0220CD
+:1032C0002070307F207106F11D002D36C4E9020602
+:1032D000F3E70121504609F02FFE050000D1FFDF82
+:1032E0002878C10604D5072020703D356560E4E7E5
+:1032F00040F008002870E0E7E87F000700D5FFDF16
+:10330000307CB28800F0010301B05046BDE8F04FB8
+:10331000082108F014B805B9FFDF716821B1102247
+:1033200005F1240014F0ABFD28212846FEF71DF816
+:10333000307A85F82000C0E7F8E00121504609F016
+:10334000FBFD050000D1FFDF022105F185000CF037
+:10335000AAFF0420207005F5B4706060B5F8850000
+:1033600020826E4810387C356561C4E90270A4E79C
+:103370000121504609F0E0FD00B9FFDF3246294641
+:103380005046BDE8F84F75E605B9FFDF28782128DB
+:1033900093D93079012803D1E87F40F00800E8771D
+:1033A000324629465046FFF765FE2846BDE8F84FED
+:1033B0002321FDF7DABF3279A28004F10803082146
+:1033C000504607F087FEE06010B184F8009074E783
+:1033D00045460121504609F0AFFD040000D1FFDF52
+:1033E00004F1620102231022081F09F04AFC057053
+:1033F0003179417061E70121504609F09DFD0400DB
+:1034000000D1FFDF94F8840000F00300012859D1B7
+:10341000E87F10F0010003D194F8A010C9072AD06A
+:10342000D4F8602132B394F88330117C63F38701C0
+:103430001174AA7FD30963F3410100E072E0D4F86C
+:1034400060211174D4F8602160F30001117490B10F
+:10345000D4F86001102205F12401883414F00FFD26
+:10346000207E40F001002076207820F0010004F852
+:10347000880919E0C0B994F88810C90714D0D4F8A5
+:103480005C218AB194F88330117C63F38701117455
+:10349000AA7FD309D4F85C2163F341011174D4F8F5
+:1034A0005C2160F30001117494F88800800709D54D
+:1034B00094F87C00D4F86421400804F17D011032B6
+:1034C000FEF795F88DF8009094F884006A4600F0B5
+:1034D00003008DF8010094F888108DF8021094F81C
+:1034E000A0008DF803002946504601F049F82878DD
+:1034F000252805D0212807D0FFDF2878222803D9E6
+:1035000022212846FDF731FF0121504609F026FD12
+:1035100000283FF4DDAEFFDFCFE60000E40100202D
+:1035200040420F00716881F80180C6E6FFDFC4E603
+:1035300070B5FE4C002584F85C5025660BF0BBF995
+:1035400004F11001204604F001FC84F8305070BDF5
+:1035500070B50D46FEF770F8040000D1FFDF4FF4A0
+:10356000B871284614F02CFD2434012105F1E00047
+:103570002C610BF0A1F9002800D0FFDF70BD0A46D6
+:10358000014602F1E0000BF0B7B970B5054640689E
+:1035900086B00178082906D00B2933D00C292FD00A
+:1035A000FFDF06B070BD46883046FEF745F80400E0
+:1035B00000D1FFDF20782128F3D028281BD16868AC
+:1035C00002210C3000F0A6FFA8B168680821001D98
+:1035D00000F0A0FF78B104F12401304608F0CCFCE3
+:1035E00004F018FA00B1FFDF06B02046BDE87040D5
+:1035F0002921FDF7BABE06B0BDE8704004F0EDBB6E
+:1036000001218171686886883046FEF715F804004C
+:1036100000D1FFDF20782128C3D06868817909B103
+:10362000807808B1FFDFBCE704F0D7FBA07F00067D
+:1036300023D5E07FC00705D094F8200000F01F00DC
+:10364000102818D05FF0050084F82300207829287E
+:1036500015D02428A5D1314604200DF0CFF8222121
+:103660002046FDF782FE0121304609F077FC002854
+:1036700097D0FFDF95E70620E6E70420E4E7012185
+:10368000304609F059FC050000D1FFDF2521204616
+:10369000FDF76BFE03208DF80000694605F1E000A0
+:1036A0000BF021F90228BED00028BCD0FFDF78E75C
+:1036B0002DE9F04788B09A46164688468146FDF7C0
+:1036C000BBFF05003AD02878222837D3232835D0ED
+:1036D000E87F000732D400270121484609F02CFC7E
+:1036E000040005D101210022484609F01CFC0446D3
+:1036F000694600F06CFF009800B9FFDF00983CB10C
+:10370000E03404612878222804D0242802D005E07F
+:10371000076103E025212846FDF727FE00980121D7
+:103720004170C0F824908680C0E9028A01A90BF09C
+:10373000F5F8022802D0002800D0FFDF08B00DE520
+:1037400070B586B00546FDF777FF0078222814D9BA
+:103750000121284609F0F0FB04002CD1FFDF2AE00C
+:10376000B4F85E0004F1620630440178427829B171
+:1037700021462846FFF72DFDB0B912E7ADF8042029
+:103780000821284602AB07F0A5FC03900028F4D0DE
+:1037900005208DF80000694604F1E0000BF0A3F865
+:1037A000022801D000B1FFDF02231022314604F1CC
+:1037B0005E0009F09CFAB4F860000028D0D1F0E671
+:1037C00010B586B00446FDF737FF0078222811D9DE
+:1037D0000121204609F0B0FB040000D1FFDF0620E4
+:1037E0008DF80000694604F1E0000BF07CF8002839
+:1037F00000D0FFDF06B010BD2DE9F84F0546007878
+:103800000C460027010904F1080090463E46BA46DE
+:10381000009002297ED0072902D00A2909D142E06E
+:1038200068680178082905D00B292CD00C292AD0EA
+:10383000FFDF73E114271C26002C6CD04088A08089
+:10384000FDF7FAFE5FEA000900D1FFDF99F81700E3
+:1038500009F118014008009AFDF7C9FE68688089DF
+:10386000208268684168C4F812108068C4F81600A5
+:10387000A07E20F0060040F00100A07699F81E001E
+:1038800040F020014FE01A270A26002CD5D080886E
+:10389000A080FDF7D1FE050000D1FFDF284600998A
+:1038A000FFF768FC3AE10CB1A88BA080287A4FF0B2
+:1038B000010B0B287ED006DC01287CD0022808D022
+:1038C000032804D137E00D2876D00E2875D0FFDF0D
+:1038D00024E11E270926002CAFD0A088FDF7ACFEFE
+:1038E0005FEA000900D1FFDF287B00F00300012818
+:1038F000207A1DD020F001002072297B890861F315
+:1039000041002072297BC90861F382002072297B63
+:10391000090901E0F7E0AEE061F3C300207299F815
+:103920001E0040F0400189F81E10F7E0C40100209D
+:1039300040F00100E0E713270D26002CA6D0A08858
+:10394000FDF77AFE81460121A08809F0F5FA05000D
+:1039500000D1FFDF686F817801F003010129217A2E
+:1039600050D021F00101217283789B0863F341015B
+:1039700021728378DB0863F38201217283781B094B
+:1039800063F3C3012172037863F306112172437854
+:1039900063F3C711217284F809A0C178A17202797A
+:1039A000E17A62F30001E1720279520862F34101A7
+:1039B000E17203E029E067E04EE05FE002799208FF
+:1039C00062F38201E1720279D20862F3C301E1720B
+:1039D0004279217B62F3000121734279520862F33C
+:1039E000410121734279920862F382012173407987
+:1039F000C00860F3C301217399F8000023282AD975
+:103A0000262139E041F00101ADE71827102694B3D3
+:103A1000A088FDF711FE00900121A08809F08CFA22
+:103A20005FEA000900D1FFDFE868A06099F80000B4
+:103A300040F0040189F8001099F80100800708D5CA
+:103A400084F80CB000980078232867D927210098C3
+:103A500052E084F80CA061E015270F265CB1A08825
+:103A6000FDF7EAFD81460622E8680099FFF76FFA44
+:103A700084F80EB086E042E048463DE0162709266D
+:103A8000ECB3287B207249E0287B19270E26B4B3BB
+:103A9000C4F808A0A4F80CA0012807D0022808D078
+:103AA00003280CD004280AD0FFDF15E084F808B002
+:103AB00001E002202072607A20F003000BE0697BB5
+:103AC000042801F00F0141F080012172F3D1607AE6
+:103AD00020F00300401C6072A088FDF7ADFD054694
+:103AE000007821281AD0232800D0FFDF0121A088E8
+:103AF00009F034FA22212846FDF737FC0EE0FFE7F3
+:103B0000A8F800600FE00CB16888A080287A03282C
+:103B100022D0042809D005283AD0FFDFA8F8006099
+:103B20000CB127806680002005E415270F26002CA5
+:103B3000E6D0A088FDF780FD0121A08809F0FCF9FE
+:103B4000050000D1FFDFD5F81D0006220099FFF720
+:103B5000FEF984F80EA0E1E717270926002CCFD044
+:103B6000A088FDF769FD81460121A08809F0E4F9EC
+:103B7000050000D1FFDF6878800701D5022000E052
+:103B80000120207299F800002328C7D9272173E764
+:103B900019270E26002CB3D0A088FDF74DFD5FEA53
+:103BA000000900D1FFDFC4F808A0A4F80CA084F835
+:103BB00008A0A07A40F00300A07299F81E10C9096D
+:103BC00061F38200A07299F81F2099F81E1012EA82
+:103BD000D11F05D099F8201001F01F01102925D020
+:103BE00020F00800A07299F81F10607A61F3C300FA
+:103BF0006072697A01F0030101298FD140F004005D
+:103C00006072E87A217B60F300012173AA7A607BFD
+:103C100062F300006073EA7A520862F34101217393
+:103C2000A97A490861F34100607377E740F0080022
+:103C3000D8E710B5FA4C30B10146102204F120004B
+:103C400014F01DF9012084F8300010BD10B50446B1
+:103C500000F0ADFCF24920461022BDE810402031B2
+:103C600014F00DB970B5EE4D06004FF0000413D0FE
+:103C70000CF010FE08B110240CE006213046FFF7CE
+:103C80004DF9411C05D028665FF0010085F85C0005
+:103C900000E00724204670BD0020F7E7007810F010
+:103CA0000F0204D0012A05D0022A0CD110E000092D
+:103CB00009D10AE00009012807D0022805D003280D
+:103CC00003D0042801D007207047087000207047F7
+:103CD0000620704705282AD2DFE800F003070F17F7
+:103CE0001F00087820F0FF001EE0087820F00F0089
+:103CF000401C20F0F000103016E0087820F00F0093
+:103D0000401C20F0F00020300EE0087820F00F007A
+:103D1000401C20F0F000303006E0087820F00F0062
+:103D2000401C20F0F0004030087000207047072051
+:103D300070472DE9F043804687B00D464FF00009EB
+:103D400008460CF0F4FDA8B94046FDF775FC0600E6
+:103D500003D0307822280BD104E043F2020007B0F0
+:103D6000BDE8F08335B1B07FC10601D4000703D5AB
+:103D70000820F4E71020F2E7F07F000701D50D20BE
+:103D8000EDE700270121404609F0D6F8040006D1EE
+:103D900001210022404609F0C6F8040005D069461A
+:103DA00000F015FC009818B901E00420D7E7FFDF08
+:103DB00000980221E0344170C0F8248044610781FA
+:103DC00001210171297801F00102017E62F30101F4
+:103DD00001762A78520862F3820101762A789208E5
+:103DE00062F3C30101762A78D20862F304110176E6
+:103DF00024213046FDF7B9FA01A900980AF08EFD9A
+:103E0000022801D000B1FFDF4846A8E72DE9FF4FA7
+:103E10009046844A0E4697B09A4607CA14AB4FF0B4
+:103E2000000983E807001798FDF706FC050006D097
+:103E30002878262806D008201BB0BDE8F08F43F272
+:103E40000200F9E726B94046FFF7F0F80028F3D161
+:103E50000121179809F070F8040000D1FFDF852ECA
+:103E600027D007DCEEB1812E1DD0822E1DD0832EEF
+:103E700008D11CE0862E1ED0882E1ED0892E1ED082
+:103E80008A2E1ED00F2020710F281CD003F0A2FF15
+:103E9000D8B101208DF82C00201D0C902079B0B1F4
+:103EA00032E10020EFE70120EDE70220EBE70320FD
+:103EB000E9E70520E7E70620E5E70820E3E7092032
+:103EC000E1E70A20DFE70720B6E71120B4E798F81A
+:103ED0000000D4E91D764208A87F002162F3C710D4
+:103EE000A87798F800008208E87F62F30000E8777E
+:103EF00098F80000C209607862F34100607098F899
+:103F000000000209207862F34710207098F8000042
+:103F1000C208607862F30000607098F80100607178
+:103F200098F8000000F00102B07862F30100B07070
+:103F3000AA7FD20962F38200B070EA7F62F3C30005
+:103F4000B070627862F30410B0702278C0F3C000E1
+:103F5000520932706278C2F34002727098F80220FF
+:103F6000F27071713171B978C1F3C00108405FEA34
+:103F7000000B2ED050460CF08DFC98BBDAF80C00EC
+:103F80000CF088FC70BBDAF81C000CF083FC48BB1A
+:103F9000DAF80C00A060DAF81C00E060797860784C
+:103FA00001F0010140EA41006070B978C0B2C1F38C
+:103FB0000011891E084060700020207705F117006D
+:103FC0006061681CA061B07800F0030001280AD08D
+:103FD0004AE07978607801F00101FD2242EA41016E
+:103FE0000840E1E719E0B87800F0030001283BD170
+:103FF000321D711D404600F099FA30793979084038
+:104000008DF8480071797A7911408DF828100843AD
+:104010002AD050460CF03EFC30B110200CE70000D6
+:10402000C40100203C8301000AF1100004F5AE73C6
+:1040300004F18C028DE80D00002112AB5A46204697
+:10404000FFF737F80028E9D104F5B07204F1A403B2
+:10405000CDF800A0CDE9013201210AAB5A46204635
+:10406000FFF727F80028D9D16078800722D4B078EC
+:10407000B978C0F38000C1F3800108431AD03078CA
+:1040800014AA397832F810204B00DA4002F0030904
+:10409000B9F1030F01D14FF00209BBF1000F09D0B4
+:1040A000012801D0042805D1012901D0042901D11A
+:1040B0004FF00409A87F40F08000A877E87F6BF3F9
+:1040C0000000E877607881074FF003000CD5A071FD
+:1040D000BBF1000F18D100BF8DF84C0013AA294680
+:1040E000179800F04DFA0FE00221B9F1020F1AD033
+:1040F000B9F1010F19D0B9F1040F22D00020A0713D
+:10410000A87F20F08000A87725212846FDF72DF90B
+:104110000BA904F1E0000AF0E6FB10B1022800D080
+:10412000FFDF002088E6A171D6E7A1710D2104F11F
+:10413000200013F045FF207840F00200207004209A
+:10414000CAE70120A071DFE72DE9F04387B0904670
+:10415000894604460025FDF76FFA070004D0387839
+:10416000272804D00820FAE543F20200F7E50121F0
+:10417000204608F0E1FE040000D1FFDFA6795FEAE7
+:10418000090005D0012821D0B9F1020F26D110E095
+:10419000B8F1000F22D1012E05D0022E05D0032E3A
+:1041A00005D0FFDF2DE00C252BE0012529E00225BD
+:1041B00027E040460CF06EFBB0B9032E0ED1102262
+:1041C000414604F11D0013F05AFE1AE0012E02D000
+:1041D000022E03D104E0B8F1000F12D00720BEE593
+:1041E00040460CF057FB08B11020B8E5102104F14F
+:1041F0001D0013F0C3FE06214046FEF78FFEC4F8F3
+:104200001D002078252140F0020020703846FDF77F
+:10421000ACF82078C10713D020F0010020700220F4
+:104220008DF8000004F11D0002908DF804506946DD
+:10423000C3300AF058FB022803D010B1FFDF00E0C2
+:10424000257700208BE530B587B00D460446FDF795
+:10425000F3F960B10121204608F06EFE04000CD095
+:1042600028460CF017FB28B1102007B030BD43F2F0
+:104270000200FAE72078400701D40820F5E7294634
+:1042800004F13D002022054613F0F9FD207840F0AE
+:104290001000207001070FD520F0080020700720C3
+:1042A0008DF80000694604F1E00001950AF01BFB5F
+:1042B000022801D000B1FFDF0020D6E770B50D461F
+:1042C0000646FDF7B9F918B10078272817D102E0A2
+:1042D00043F2020070BD0121304608F02DFE0400BB
+:1042E00000D1FFDFA079022809D16078C00706D08D
+:1042F0002A4621463046FEF76CFF10B10FE0082039
+:1043000070BDB4F860000E280BD204F162010223E4
+:104310001022081F08F0B5FC012101704570002033
+:1043200070BD112070BD70B5064614460D46084696
+:104330000CF0B0FA18B920460CF0D2FA08B11020EF
+:1043400070BDA6F57F40FF380ED03046FDF774F9FA
+:1043500038B1417822464B08811C1846FDF747F9D1
+:1043600007E043F2020070BD2046FDF772FE002810
+:10437000F9D11021E01D0BF096FFE21D294604F152
+:10438000170000F034F9002070BD2DE9F04104461B
+:104390008AB015460E46002708460CF0C8FA18B930
+:1043A00028460CF0C4FA18B110200AB0BDE8F0811C
+:1043B0002046FDF741F95FEA000804D098F80000B4
+:1043C000272810D102E043F20200EEE70121204647
+:1043D00008F0B2FD040000D1FFDF2078400702D5CD
+:1043E0006078800701D40820DFE7D4E91D0149780F
+:1043F00001B18DB1407800B176B1ADB1EA1D06A82A
+:10440000E16800F0F4F8102206A905F1170013F096
+:104410000AFD18B1042707E00720C6E71022E91DAE
+:1044200004F12D0013F02BFD2EB11022F11D04F12B
+:104430001D0013F024FD2078252140F0020020709B
+:104440004046FCF792FF2078C10715D020F001000C
+:10445000207002208DF8000004F11D000290103041
+:1044600003908DF804706946B3300AF03CFA0228D4
+:1044700003D010B1FFDF00E02777002095E770B58B
+:104480000D4606460BB1072070BDFDF7D5F80400B8
+:1044900007D02078222802D3A07F800604D40820E9
+:1044A00070BD43F2020070BDADB12946304607F041
+:1044B00063FD03F0AFFA297C4A08A17F62F3C711BC
+:1044C000A177297CE27F61F30002E277297C8908E9
+:1044D00084F8201004E0304607F071FD03F09AFAEA
+:1044E000A17F21F02001A17770BD70B50D46FDF7C9
+:1044F000A3F8040005D028460CF0F2F920B11020F2
+:1045000070BD43F2020070BD29462046FEF732FE20
+:10451000002070BD05E000BF10F8012B0AB100209B
+:104520007047491E89B2F7D20120704710B5C47890
+:104530000B7864F300030B70C478640864F34103E0
+:104540000B70C478A40864F382030B70C478E40889
+:1045500064F3C3030B700379117863F300011170E6
+:1045600003795B0863F34101117003799B0863F3DE
+:10457000820111700079C00860F3C301117010BD91
+:1045800070B51546064603F025FC040000D1FFDF98
+:10459000207820F00F00801C20F0F00020302070E8
+:1045A00066802868A060BDE8704003F016BC10B5B6
+:1045B000134C94F83000002808D104F12001A1F137
+:1045C00010000AF0D2F9012084F8300010BD10B1BB
+:1045D00090F8B9202AB10A4890F8350018B10020A7
+:1045E00003E0B83001E0064834300860704708B591
+:1045F0000023009313460A4608F099FE08BD000008
+:10460000C4010020F0B5007B059F1E4614460D46F0
+:10461000012800D0FFDF0C2030803A203880002CA9
+:1046200008D0287A032806D0287B012800D0FFDF95
+:1046300017206081F0BDA889FBE72DE9F04786B01F
+:10464000144691F80C900E9A0D46B9F1010F0BD05B
+:104650001021007B2E8A8846052807D0062833D0F3
+:10466000FFDF06B0BDE8F0870221F2E7E8890C2100
+:1046700000EB400001EB4000188033201080002C3C
+:10468000EFD0E889608100271AE00096688808F179
+:10469000020301AA696900F084FF06EB0800801C90
+:1046A00007EB470186B204EB4102BDF8040090819C
+:1046B0000DF1060140460E320AF0C0F97F1CBFB270
+:1046C0006089B842E1D8CCE734201080E889B9F19C
+:1046D000010F11D0122148430E301880002CC0D099
+:1046E000E88960814846B9F1010F00D002202073AB
+:1046F00000270DF1040A1FE00621ECE70096688808
+:1047000008F1020301AA696900F04BFF06EB0800FB
+:10471000801C86B2B9F1010F12D007EBC70004EB81
+:104720004000BDF80410C18110220AF102011030CE
+:1047300013F0A5FB7F1CBFB26089B842DED890E7BA
+:1047400007EB470104EB4102BDF80400D0810AF1F8
+:104750000201404610320AF071F9EBE72DE9F0470B
+:104760000E4688B090F80CC096F80C80378AF58910
+:104770000C20109902F10C044FF0000ABCF1030F59
+:1047800008D0BCF1040F3ED0BCF1070F7DD0FFDF95
+:1047900008B067E705EB850C00EB4C001880312072
+:1047A0000880002AF4D0A8F1060000F0FF09558126
+:1047B00025E0182101A813F003FC009770884346F8
+:1047C00001AA716900F0EDFEBDF804002080BDF87B
+:1047D0000600E080BDF808002081A21C0DF10A014E
+:1047E00048460AF02BF9B9F1000F00D018B184F84F
+:1047F00004A0A4F802A007EB080087B20A346D1EDB
+:10480000ADB2D6D2C4E705EB850C00EB4C001880A6
+:1048100032200880002ABBD0A8F1050000F0FF0973
+:10482000558137E000977088434601AA716900F00E
+:10483000B8FE9DF80600BDF80410E1802179420819
+:1048400060F3000162F34101820862F38201C20851
+:1048500062F3C301020962F30411420962F34511D4
+:10486000820962F386112171C0096071BDF80700E9
+:10487000208122460DF1090148460AF0DFF818B1FF
+:1048800084F802A0A4F800A000E007E007EB08000D
+:1048900087B20A346D1EADB2C4D279E7A8F1020026
+:1048A00084B205FB08F000F10E0CA3F800C035231C
+:1048B0000B80002AA6D055819481009783B270881E
+:1048C0000E32716900F06DFE62E72DE9F84F1E4669
+:1048D0000A9D0C4681462AB1607A00F58070D0802E
+:1048E000E089108199F80C000C274FF000084FF078
+:1048F0000E0A0D2873D2DFE800F09E070E1C283048
+:104900003846556A73737300214648460095FFF791
+:1049100079FEBDE8F88F207B9146082802D0032855
+:1049200000D0FFDF378030200AE000BFA9F80A80FE
+:10493000EFE7207B9146042800D0FFDF378031204D
+:104940002880B9F1000FF1D1E3E7207B91460428DC
+:1049500000D0FFDF37803220F2E7207B914602282B
+:1049600000D0FFDF37803320EAE7207B174602289C
+:1049700000D0FFDF3420A6F800A02880002FC8D088
+:10498000A7F80A80C5E7207B1746042800D0FFDF80
+:104990003520A6F800A02880002FBAD04046A7F8FE
+:1049A0000A8012E0207B1746052802D0062800D096
+:1049B000FFDF1020308036202880002FA9D0E0892A
+:1049C0007881A7F80E80B9F80E00B881A1E7207BA6
+:1049D0009146072800D0FFDF37803720B0E72AE074
+:1049E0004FF0120018804FF038001700288090D048
+:1049F000E0897881A7F80E80A7F8108099F80C005C
+:104A00000A2805D00B2809D00C280DD0FFDF80E73D
+:104A1000207B0A2800D0FFDF01200AE0207B0B2842
+:104A200000D0FFDF042004E0207B0C2800D0FFDF53
+:104A3000052038736DE7FFDF6BE770B50C46054660
+:104A4000FCF7FAFD20B10078222804D2082070BDBE
+:104A500043F2020070BD0521284608F06DFA20607F
+:104A600008B1002070BD032070BD30B448800878C4
+:104A700020F00F00C01C20F0F000903001F8080B6F
+:104A80001DCA81E81D0030BC03F0A7B92DE9FF471E
+:104A900084B00027824602970798904689461230D4
+:104AA00004F03CFA401D20F00306079828B907A936
+:104AB0005046FFF7C2FF002854D1B9F1000F05D0CE
+:104AC0000798017B19BB052504681BE098F80000D6
+:104AD000092803D00D2812D0FFDF46E007990325EF
+:104AE0004868B0B3497B42887143914239D98AB250
+:104AF000B3B2011D08F0B1F80446078002E0079C3C
+:104B0000042508340CB1208810B1032D29D02CE0E5
+:104B100007980121123004F033FAADF80C00024678
+:104B200002AB2946504606F0D5FA070001D1A01C79
+:104B3000029007983A461230C8F80400A8F802A07C
+:104B400003A94046029B04F028FAD8B10A2817D2DC
+:104B500000E006E0DFE800F007091414100B0D1464
+:104B60001412132014E6002012E6112010E608208B
+:104B70000EE643F203000BE6072009E60D2007E6E8
+:104B8000032005E6BDF80C002346CDE900702A4657
+:104B90005046079900F015FD57B9032D08D1079825
+:104BA000B3B2417B406871438AB2011D08F069F8D5
+:104BB000B9F1000FD7D0079981F80C90D3E72DE910
+:104BC000FE4F91461A881C468A468046FAB102ABCF
+:104BD000494606F07FFA050019D04046A61C2788F2
+:104BE00008F0EEFA3246072629463B46009607F0C3
+:104BF0001AFF20882346CDE900504A4651464046D8
+:104C000000F0DFFC002020800120BDE8FE8F0020A6
+:104C1000FBE710B586B01C46AAB104238DF800301E
+:104C20001388ADF808305288ADF80A208A788DF8DC
+:104C30000E200988ADF80C1000236A462146FFF7C4
+:104C400025FF06B010BD1020FBE770B50D4605210D
+:104C500008F072F9040000D1FFDF294604F11200C8
+:104C6000BDE8704004F075B92DE9F8430D46804663
+:104C7000002603F0AFF804462878102878D2DFE841
+:104C800000F0773B34533131123131310831313159
+:104C900031312879001FC0B2022801D0102810D16C
+:104CA00014BBFFDF35E004B9FFDF0521404608F003
+:104CB00043F9007B032806D004280BD0072828D00E
+:104CC000FFDF072655E02879801FC0B2022820D0D8
+:104CD00050B1F6E72879401FC0B2022819D0102839
+:104CE00017D0EEE704B9FFDF13E004B9FFDF28793E
+:104CF00001280ED1172137E00521404608F01CF9A4
+:104D0000070000D1FFDF07F11201404604F0FEF872
+:104D10002CB12A4621464046FFF7A7FE29E0132181
+:104D20004046FDF743FC24E004B9FFDF052140467F
+:104D300008F002F9060000D1FFDF694606F1120013
+:104D400004F0EEF8060000D0FFDFA988172901D291
+:104D5000172200E00A46BDF80000824202D901464F
+:104D600002E005E01729C5D3404600F03AFCD0E741
+:104D7000FFDF3046BDE8F883401D20F0030219B183
+:104D800002FB01F0001D00E000201044704713B545
+:104D9000009848B10024684607F009FF002C02D1B2
+:104DA000F74A009911601CBD01240020F4E72DE9A9
+:104DB000F0470C4615462421204613F001F905B9A9
+:104DC000FFDFA87860732888DFF8B4A3401D20F0C7
+:104DD0000301AF788946DAF8000007F006FF060005
+:104DE00000D1FFDF4FF000082660A6F8008077B101
+:104DF00009FB07F1091D0AD0DAF8000007F0F5FEFB
+:104E0000060000D1FFDF6660C6F8008001E0C4F84C
+:104E10000480298804F11200BDE8F04704F068B866
+:104E20002DE9F047804601F112000D46814604F05D
+:104E300075F8401DD24F20F003026E7B144629689E
+:104E4000386807F0FDFE3EB104FB06F2121D03D0E8
+:104E50006968386807F0F4FE052008F019F8044680
+:104E6000052008F01DF8201A012802D1386807F043
+:104E7000B1FE49464046BDE8F04704F04EB870B573
+:104E80000546052108F058F8040000D1FFDF04F1C1
+:104E900012012846BDE8704004F038B82DE9F04F03
+:104EA00091B04FF0000BADF834B0ADF804B04788C6
+:104EB0000C46054692460521384608F03DF80600A6
+:104EC00000D1FFDF24B1A780A4F806B0A4F808B091
+:104ED000297809220B20B2EB111F7DD12A7A04F127
+:104EE000100138274FF00C084FF001090391102AE8
+:104EF00073D2DFE802F072F2F1F07F08D2888D9F62
+:104F00003DDBF3EEB6B6307B022800D0FFDFA88988
+:104F100008EBC001ADF804103021ADF83410002CBE
+:104F200025D06081B5F80E9000271DE004EBC7087E
+:104F3000317C88F80E10F189A8F80C10CDF800909B
+:104F40006888042304AA296900F02BFBBDF810101F
+:104F5000A8F8101009F10400BDF812107F1C1FFA08
+:104F600080F9A8F81210BFB26089B842DED80DE10E
+:104F7000307B022800D0FFDFE98908EBC100ADF8E3
+:104F800004003020ADF83400287B0A90001FC0B226
+:104F90000F90002CEBD06181B5F81090002725E030
+:104FA000CDF800906888696903AA0A9B00F0F9FAB5
+:104FB0000A9804EBC70848441FFA80F908F10C026C
+:104FC00004A90F9809F03AFD18B188F80EB0A8F8B6
+:104FD0000CB0BDF80C1001E0D4E0CFE0A8F8101040
+:104FE000BDF80E107F1CA8F81210BFB26089B8423D
+:104FF000D6D8CBE00DA8009001AB2246294630461A
+:10500000FFF71BFBC2E0307B082805D0FFDF03E081
+:10501000307B082800D0FFDFE8891030ADF80400AD
+:105020003620ADF83400002C3FD0A9896181F18988
+:10503000A18127E0307B092800D0FFDFA88900F19B
+:105040000C01ADF804103721ADF83410002C2CD031
+:105050006081E8890090AB89688804F10C022969B5
+:1050600056E0E8893921103080B2ADF80400ADF87F
+:105070003410002C74D0A9896181287A0E280AD0B6
+:1050800002212173E989E181288A0090EB896888EF
+:105090006969039A3CE00121F3E70DA8009001AB98
+:1050A000224629463046FFF759FB6FE0307B0A283D
+:1050B00000D0FFDF1220ADF80400ADF834704CB31F
+:1050C000A9896181A4F810B0A4F80EB084F80C90FE
+:1050D0005CE020E002E031E039E042E0307B0B2888
+:1050E00000D0FFDF288AADF834701230ADF804002C
+:1050F00084B104212173A9896181E989E181298A27
+:105100002182688A00902B8A688804F112026969FA
+:1051100000F047FA3AE0307B0C2800D0FFDF122085
+:10512000ADF80400ADF834703CB305212173A4F848
+:105130000AB0A4F80EB0A4F810B027E00DA80090B3
+:1051400001AB224629463046FFF75CFA1EE00DA867
+:10515000009001AB224629463046FFF7B6FB15E02A
+:1051600034E03B21ADF80400ADF8341074B3A4F87A
+:105170000690A4F808B084F80AB007E0FFDF05E065
+:1051800010000020297A012917D0FFDFBDF80400A4
+:10519000AAF800006CB1BDF834002080BDF804000E
+:1051A0006080BDF83400392803D03C2801D086F84F
+:1051B0000CB011B00020BDE8F08F3C21ADF8040028
+:1051C000ADF8341014B1697AA172DFE7AAF80000D3
+:1051D000EFE72DE9F84356880F468046154605212E
+:1051E000304607F0A9FE040000D1FFDF123400941E
+:1051F0003B46414630466A6804F003F8BAE570B5AC
+:105200000D46052107F098FE040000D1FFDF294676
+:1052100004F11200BDE8704003F08DBE70B50D467C
+:10522000052107F089FE040000D1FFDF294604F1C3
+:105230001200BDE8704003F0ABBE70B50546052115
+:1052400007F07AFE040000D1FFDF04F108032146D5
+:105250002846BDE870400422B1E470B5054605213A
+:1052600007F06AFE040000D1FFDF214628462368CC
+:10527000BDE870400522A2E470B50646052107F09E
+:105280005BFE040000D1FFDF04F1120003F046FED4
+:10529000401D20F0030511E0011D00880322431882
+:1052A00021463046FFF78BFC00280BD0607BABB269
+:1052B000684382B26068011D07F019FD606841888B
+:1052C0000029E9D170BD70B50E46054602F082FD99
+:1052D000040000D1FFDF0120207266726580207813
+:1052E00020F00F00C01C20F0F00030302070BDE82E
+:1052F000704002F072BD2DE9F0438BB00D461446AC
+:10530000814606A9FFF799FB002814D14FF6FF76D6
+:1053100001274FF420588CB103208DF80000102095
+:10532000ADF8100007A8059007AA204604A909F0C7
+:10533000A4FB78B107200BB0BDE8F0830820ADF8DE
+:1053400008508DF80E708DF80000ADF80A60ADF8C9
+:105350000C800CE00698A17801742188C1818DF839
+:105360000E70ADF80850ADF80C80ADF80A606A46D2
+:1053700002214846069BFFF789FBDCE708B50122BE
+:105380008DF8022042F60202ADF800200A460323FF
+:105390006946FFF73EFC08BD08B501228DF80220E2
+:1053A00042F60302ADF800200A4604236946FFF7DF
+:1053B00030FC08BD00B587B079B102228DF800201D
+:1053C0000A88ADF808204988ADF80A1000236A461B
+:1053D0000521FFF75BFB07B000BD1020FBE709B11B
+:1053E000072316E40720704770B588B00D461446B1
+:1053F000064606A9FFF721FB00280ED17CB1062046
+:10540000ADF808508DF80000ADF80A40069B6A46DA
+:105410000821DC813046FFF739FB08B070BD05205C
+:105420008DF80000ADF80850F0E700B587B059B12D
+:1054300007238DF80030ADF80820039100236A4659
+:105440000921FFF723FBC6E71020C4E770B588B039
+:105450000C460646002506A9FFF7EFFA0028DCD126
+:1054600006980121123003F08BFD9CB121780629AA
+:1054700021D2DFE801F0200505160318801E80B256
+:10548000C01EE28880B20AB1A3681BB1824203D970
+:105490000C20C2E71020C0E7042904D0A08850B92E
+:1054A00001E00620B9E7012913D0022905D004291B
+:1054B0001CD005292AD00720AFE709208DF800006D
+:1054C0006088ADF80800E088ADF80A00A068039095
+:1054D00023E00A208DF800006088ADF80800E0881D
+:1054E000ADF80A00A0680A25039016E00B208DF89D
+:1054F00000006088ADF80800A088ADF80A00E088D8
+:10550000ADF80C00A0680B25049006E00C208DF887
+:10551000000060788DF808000C256A462946304660
+:10552000069BFFF7B3FA78E700B587B00D228DF838
+:105530000020ADF8081000236A461946FFF7A6FAC6
+:1055400049E700B587B071B102228DF800200A88C2
+:10555000ADF808204988ADF80A1000236A460621F4
+:10556000FFF794FA37E7102035E770B586B00646A6
+:1055700001200D46ADF808108DF80000014600230B
+:105580006A463046FFF782FA040008D129463046C1
+:1055900001F0BCFA0021304601F0D6FA204606B0F0
+:1055A00070BDF8B51C4615460E46069F07F0F6FD81
+:1055B0002346FF1DBCB231462A46009407F0FFF98E
+:1055C000F8BD30B41146DDE902423CB1032903D0F5
+:1055D000002330BC05F0B3BE0123FAE71A8030BCCB
+:1055E000704770B50C460546FFF72FFB214628464D
+:1055F00001F09BFA2846BDE87040012101F0A4BAF1
+:1056000018B18178012938D101E010207047018854
+:1056100042F60112881A914231D018DC42F601029A
+:10562000A1EB020091422AD00CDC41B3B1F5C05F7E
+:1056300025D06FF4C050081821D0A0F57060FF3855
+:105640001BD11CE001281AD002280AD117E0B0F5BE
+:10565000807F14D008DC012811D002280FD0032845
+:105660000DD0FF2809D10AE0B0F5817F07D0A0F561
+:105670008070033803D0012801D0002070470F202C
+:1056800070470A281ED007DC18D2DFE800F0191B8B
+:105690001F1F171F231D1F21102815D008DC0B28E2
+:1056A00012D00C2810D00D2816D00F2806D10DE0EE
+:1056B00011280BD084280BD087280FD003207047E7
+:1056C0000020704705207047072070470F20704763
+:1056D00004207047062070470C20704743F20200F8
+:1056E000704738B50C46050041D06946FEF7D6FA3A
+:1056F000002819D19DF80010607861F302006070F5
+:105700006946681CFEF7CAFA00280DD19DF8001002
+:10571000607861F3C5006070A978C1F34101012987
+:1057200003D0022905D0072038BD217821F02001BF
+:1057300002E0217841F020012170410704D0A978CE
+:10574000C90861F386106070607810F0380F07D0D8
+:10575000A978090961F3C710607010F0380F02D101
+:105760006078400603D5207840F04000207000208B
+:1057700038BD70B504460020088015466068FFF704
+:10578000B0FF002816D12089A189884211D860680D
+:105790008078C0070AD0B1F5007F0AD840F2012016
+:1057A000B1FBF0F200FB1210288007E0B1F5FF7F9B
+:1057B00001D90C2070BD01F201212980002070BDAB
+:1057C00010B50478137864F3000313700478640848
+:1057D00064F3410313700478A40864F38203137024
+:1057E0000478E40864F3C30313700478240964F3B1
+:1057F000041313700478640964F34513137000787C
+:10580000800960F38613137031B10878C10701D1A4
+:10581000800701D5012000E0002060F3C71313705A
+:1058200010BD4278530702D002F0070306E012F0E1
+:10583000380F02D0C2F3C20300E001234A7863F3B9
+:1058400002024A70407810F0380F02D0C0F3C20054
+:1058500005E0430702D000F0070000E0012060F3FC
+:10586000C5024A7070472DE9F04F95B00D00824691
+:1058700012D01221284612F081FB4FF6FF7B05AAB9
+:105880000121584605F021FA0024264637464FF4F8
+:1058900020586FF4205972E0102015B0BDE8F08F49
+:1058A0009DF81E0001280AD1BDF81C1041450BD0FF
+:1058B00011EB09000AD001280CD002280CD0042CCE
+:1058C0000ED0052C0FD10DE0012400E00224BDF81C
+:1058D0001A6008E0032406E00424BDF81A7002E010
+:1058E000052400E00624BDF81A10514547D12C7458
+:1058F000BEB34FF0000810AA4FF0070ACDE90282AC
+:10590000CDE900A80DF13C091023CDF810904246D6
+:105910003146584605F08CFA08BBBDF83C002A46D3
+:10592000C0B210A909F08AF8C8B9AE81CFB1CDE9EB
+:1059300000A80DF1080C0AAE40468CE84102132382
+:1059400000223946584605F073FA40B9BDF83C00CC
+:10595000F11CC01EC0B22A1D09F070F810B103205E
+:105960009BE70AE0BDF82900E881062C05D19DF8E7
+:105970001E00A872BDF81C00288100208DE705A834
+:1059800005F0AFF900288BD0FFF77BFE85E72DE906
+:10599000F0471C46DDE90978DDF8209015460E0039
+:1059A000824600D1FFDF0CB1208818B1D5B111209B
+:1059B000BDE8F087022D01D0012100E0002106F1B1
+:1059C000140004F071F8A8F8000002463B4629468E
+:1059D000504605F07FFBC9F8000008B9A41C3C60E4
+:1059E0000020E5E71320E3E7F0B41446DDE90452B4
+:1059F0008DB1002314B1022C09D101E0012306E08E
+:105A00000D7CEE0703D025F0010501230D7421461E
+:105A1000F0BC05F094BC1A80F0BC70472DE9FE4F35
+:105A200091461A881C468A468046FAB102AB49461E
+:105A300005F050FB050019D04046A61C278807F04A
+:105A4000BFFB3246072629463B46009606F0EBFF91
+:105A500020882346CDE900504A4651464046FFF78C
+:105A6000C3FF002020800120BDE8FE8F0020FBE75F
+:105A70002DE9F04786B09146DDE90E460F46824695
+:105A800003AA05A904A8109D8DE807009846324690
+:105A900021465046FFF77BFF049909B1012200E03F
+:105AA00000222A70002818D1F94A03AB1060059A29
+:105AB000009104F11400CDE901204A4639465046D0
+:105AC00004F0A9FBA8B1092811D2DFE800F005080D
+:105AD0000510100A0C0C0E00002006B068E711201B
+:105AE000FBE70720F9E70820F7E70D20F5E703209B
+:105AF000F3E7BDF80C100498CDE9000143463246A7
+:105B000021465046FFF770FFE6E72DE9F04389B0E4
+:105B10000D46DDE9108781461C461646142103A870
+:105B200012F04EFA012002218DF810108DF80C00B1
+:105B30008DF81170ADF8146064B1A278D20709D065
+:105B40008DF81600E088ADF81A00A088ADF81800AE
+:105B5000A068079008A80095CDE90110424603A966
+:105B600048466B68FFF784FF09B0BDE8F083F0B5E5
+:105B70008BB000240646069407940727089405A8CE
+:105B80000994019400970294CDE903400D46102337
+:105B90002246304605F04CF978B90AA806A90194C6
+:105BA00000970294CDE90310BDF814300022294675
+:105BB000304604F013FF002801D0FFF762FD0BB060
+:105BC000F0BD04F0B3BD2DE9FC410C468046002633
+:105BD00002F000F9054620780D287DD2DFE800F0BC
+:105BE000BC0713B325BD49496383AF959B00A84803
+:105BF000006820B1417841F010014170ADE04046AD
+:105C000002F018F9A9E00421404607F095F90700D1
+:105C100000D1FFDF07F11401404603F0D9FEA5BB18
+:105C200013214046FCF7C2FC97E00421404607F0F0
+:105C300083F9070000D1FFDFE088ADF80000002005
+:105C4000B8819DF80000010704D5C00602D5A088E0
+:105C5000B88105E09DF8010040067ED5A088F88156
+:105C600005B9FFDF22462946404601F063FC0226C3
+:105C700073E0E188ADF800109DF8011009060FD51A
+:105C8000072803D006280AD00AE024E00421404671
+:105C900007F052F9060000D1FFDFA088F08102264C
+:105CA000CDB9FFDF17E00421404607F045F90700B2
+:105CB00000D1FFDF07F1140004F06FFD90F0010F39
+:105CC00002D1E079000648D5387C022640F0020077
+:105CD000387405B9FFDF00E03EE022462946404621
+:105CE00001F028FC39E00421404607F025F9017C49
+:105CF000002D01F00206C1F340016171017C21F029
+:105D000002010174E7D1FFDFE5E7022601214046E9
+:105D100002F0C2F821E00421404607F00DF90546E3
+:105D2000606800902089ADF8040001226946404671
+:105D300002F0D3F8287C20F0020028740DE0002D3A
+:105D4000C9D1FFDFC7E7022600214046FFF766FA08
+:105D5000002DC0D1FFDFBEE7FFDF3046BDE8FC818C
+:105D60003EB50C0009D001466B4601AA002005F0A3
+:105D7000E1F820B1FFF785FC3EBD10203EBD0020BC
+:105D80002080A0709DF8050002A900F00700FDF733
+:105D9000A1FF50B99DF8080020709DF8050002A9E8
+:105DA000C0F3C200FDF796FF08B103203EBD9DF889
+:105DB000080060709DF80500C109A07861F3041027
+:105DC000A0709DF80510890961F3C300A0709DF8CB
+:105DD0000410890601D5022100E0012161F342008F
+:105DE0009DF8001061F30000A07000203EBD70B56A
+:105DF000144606460D4651EA040005D075B1084622
+:105E00000AF08CFD78B901E0072070BD29463046C4
+:105E100005F0F1F810B1BDE8704032E454B120460D
+:105E20000AF07CFD08B1102070BD21463046BDE867
+:105E3000704095E7002070BD2DE9FC5F0C46904650
+:105E40000546002701780822007A3E46B2EB111F72
+:105E50007ED104F10A0100910A31821E4FF0020A3C
+:105E600004F1080B0191092A73D2DFE802F0ECDF9C
+:105E700005F427277AA9CD006888042107F05CF88B
+:105E8000060000D1FFDFB08920B152270726C2E00B
+:105E90002802002051271026002C7DD06888A08081
+:105EA0000120A071A88900220099FFF7A0FF002817
+:105EB00073D1A8892081288AE081D1E0B5F81290B9
+:105EC000072824D1E87B000621D5512709F11400C9
+:105ED00086B2002CE1D0A88900220099FFF787FF45
+:105EE00000285AD16888A08084F806A0A88920815B
+:105EF0000120A073288A2082A4F81290A88A00901A
+:105F000068884B46A969019A01F0F1FAA8E0502788
+:105F100009F1120086B2002C3ED0A8890022594611
+:105F2000FFF765FF002838D16888A080A889E08045
+:105F3000287A072813D002202073288AE081E87B82
+:105F4000C0096073A4F81090A88A0090688801E0E6
+:105F500083E080E04B4604F11202A969D4E70120F6
+:105F6000EAE7B5F81290512709F1140086B2002C27
+:105F700066D06888042106F0DFFF83466888A08029
+:105F8000A88900220099FFF732FF00286ED184F81B
+:105F900006A0A889208101E052E067E00420A073F8
+:105FA000288A2082A4F81290A88A009068884B461C
+:105FB000A969019A01F09BFAA989ABF80E104FE08C
+:105FC0006888FBF739FB07466888042106F0B4FFB0
+:105FD000064607B9FFDF06B9FFDF687BC00702D0BE
+:105FE0005127142601E0502712264CB36888A08060
+:105FF000502F06D084F806A0287B594601F087FA76
+:106000002EE0287BA11DF9E7FE49A8894989814234
+:1060100005D1542706269CB16888A08020E053272C
+:106020000BE06888A080A889E08019E068880421D6
+:1060300006F082FF00B9FFDF55270826002CF0D1BB
+:10604000A8F8006011E056270726002CF8D06888D1
+:10605000A080002013E0FFDF02E0012808D0FFDF6E
+:10606000A8F800600CB1278066800020BDE8FC9F86
+:1060700057270726002CE3D06888A080687AA07193
+:10608000EEE7401D20F0030009B14143091D01EB7B
+:106090004000704713B5DB4A00201071009848B1EA
+:1060A0000024684606F083FD002C02D1D64A0099F0
+:1060B00011601CBD01240020F4E770B50D460646B2
+:1060C00086B014465C21284611F07AFF04B9FFDF40
+:1060D000A0786874A2782188284601F042FA00204E
+:1060E000A881E881228805F11401304603F055FCAF
+:1060F0006A460121304604F0E8FD19E09DF80300EE
+:10610000000715D5BDF806103046FFF730FD9DF8A5
+:106110000300BDF8061040F010008DF80300BDF834
+:106120000300ADF81400FF233046059A04F02EFF5B
+:10613000684604F0D6FD0028E0D006B070BD10B56A
+:106140000C4601F1140003F05FFC0146627C20461E
+:10615000BDE8104001F03ABA70B50546042106F0DA
+:10616000EBFE040000D1FFDF04F114010C462846C9
+:1061700003F02EFC21462846BDE8704003F02FBCFA
+:1061800070B58AB00C460646FBF756FA050014D0E7
+:106190002878222827D30CB1A08890B101208DF84F
+:1061A0000C0003208DF8100000208DF8110054B170
+:1061B000A088ADF81800206807E043F202000AB09A
+:1061C00070BD0920FBE7ADF81800059004213046AA
+:1061D00006F0B2FE040000D1FFDF04F1140003F06A
+:1061E0002AFC000701D40820E9E701F0F3FD60B1C3
+:1061F00008A802210094CDE9011095F8232003A9F5
+:1062000030466368FFF734FCD9E71120D7E72DE962
+:10621000F04FB2F802A0834689B015468946504631
+:10622000FBF70AFA07460421504606F085FE0026D1
+:10623000044605964FF002080696ADF81C6007B9B3
+:10624000FFDF04B9FFDF4146504605F0F7F950B9CA
+:1062500007AA06A905A88DE8070042462146504630
+:106260006368FFF794FB674807AB0660DDE905123A
+:1062700004F11400CDF80090CDE90320CDE90131FF
+:1062800097F82320594650466B6803F01DFC060022
+:106290000AD0022E04D0032E14D0042E00D0FFDF2B
+:1062A00009B03046BDE8F08FBDF81C000028F7D0DB
+:1062B0000599CDE900104246214650466368FFF734
+:1062C00093FBEDE7687840F008006870E8E72DE997
+:1062D000F04F9BB004464FF000084A48ADF8548098
+:1062E000ADF83080ADF85080A0F80880ADF814808B
+:1062F000ADF81880ADF82080ADF81C800079164606
+:106300000D464746012808D0022806D0032804D0AD
+:10631000042802D008201BB0C4E720460AF0BAFACD
+:10632000D0BB28460AF0B6FAB0BB60680AF0FFFAA4
+:1063300090BB606848B160892189884202D8B1F574
+:10634000007F01D90C20E6E780460BAA06A9284663
+:10635000FFF70FFA0028DED168688078C0F34100AB
+:10636000022808D19DF8190010F0380F03D02869D1
+:106370000AF0D4FA80B905A92069FFF7B2F900281C
+:10638000C9D1206950B1607880079DF8150000F0F0
+:10639000380002D5D0B301E011E0B8BB9DF814007D
+:1063A00080060ED59DF8150010F0380F03D06068F8
+:1063B0000AF0B4FA18B960680AF0B9FA08B1102006
+:1063C000A9E707A96069FFF78CF90028A3D16069E4
+:1063D00040B19DF81D0000F0070101293FD110F0E8
+:1063E000380F3CD008A9A069FFF77BF9002892D1AB
+:1063F0009DF81C00800632D49DF8200080062ED423
+:10640000A06904E0280200201400002027E040B129
+:106410009DF8210000F00701012920D110F0380F6C
+:106420001DD0E06818B10078C8B11C2817D20EAA98
+:10643000611C2046FFF7C4F90120B94660F30F271D
+:10644000BA4607468DF84E0042F60300ADF84C0000
+:106450000DF13B0217A9286808F00FFB08B10720CF
+:1064600059E79DF85C0016A9CDF80090C01CCDE955
+:10647000019100F0FF0B00230BF20122514613A8FB
+:1064800004F066FBF0BBBDF858000990FE482A896D
+:1064900029690092CDE901106B89BDF82C2028688C
+:1064A000069904F055FB01007ED120784FF0020AD6
+:1064B000C10601D480062BD5ADF80C90606950B9A7
+:1064C00007A906A8FFF7ADF99DF81D0020F0070009
+:1064D000401C8DF81D009DF81C008DF84E7040F09A
+:1064E000C8008DF81C0042F60210ADF84C000CA953
+:1064F00003AACDF800A0CDE90121002340F2032238
+:1065000013A800E01EE0079904F022FB01004BD124
+:10651000DD484D4608385B460089ADF839000EA8C5
+:10652000CDE90290CDF80490CDF810904FF0070916
+:106530000022CDF80090BDF858104FF6FF7004F01F
+:106540004DFA10B1FFF79DF8E5E69DF8380000061A
+:1065500025D52946012060F30F218DF84E704FF4A8
+:106560002450ADF84C00ADF8105062789DF8100042
+:10657000002362F300008DF810006278CDF800A0CF
+:10658000520862F341008DF8100004AACDE90125FC
+:1065900040F2032213A804F0DBFA010004D1606882
+:1065A00088B32069A8B900E086E005A906A8FFF72E
+:1065B00038F96078800706D49DF8150020F038007F
+:1065C0008DF8150005E09DF8140040F040008DF8AE
+:1065D00014008DF84E7042F60110ADF84C00208981
+:1065E00040F20121B0FBF1F201FB1202606814AB32
+:1065F000CDF80080CDE90103002313A8059904F02C
+:10660000A7FA010058D12078C00729D0ADF80C5066
+:10661000A06950B908A906A8FFF703F99DF8210061
+:1066200020F00700401C8DF821009DF820008DF817
+:106630004E7040F040008DF8200042F60310ADF897
+:106640004C0015A903AACDF800A0CDE90121002333
+:1066500040F2032213A8089904F07AFA01002BD122
+:10666000E06868B32946012060F30F218DF84E7071
+:1066700042F60410ADF84C00E068002302788DF873
+:10668000602040788DF86100E06818AA4088ADF875
+:106690006200E06800798DF86400E068C088ADF8B9
+:1066A0006500CDF80090CDE901254FF4027213A8E2
+:1066B00004F04EFA010003D0099800F0B3FF2AE677
+:1066C000714803210838017156B100893080BDF846
+:1066D00050007080BDF83000B080BDF85400F080EC
+:1066E000002018E670B501258AB016460B46012831
+:1066F00002D0022816D104E08DF80E504FF420503D
+:1067000003E08DF80E5042F60100ADF80C005BB1CD
+:106710000024601C60F30F2404AA08A9184608F09E
+:10672000ACF918B107204AE5102048E504A99DF806
+:1067300020205548CDE90021801E029000232146EB
+:1067400003A802F2012204F003FA10B1FEF799FF48
+:1067500035E54D4808380EB1C188318005710020FB
+:106760002DE5F0B593B0074601268DF83E6041F661
+:106770000100ADF83C0012AA0FA93046FFF7B2FFA6
+:10678000002848D1404C0025083CE7B31C2102A852
+:1067900011F016FC9DF808008DF83E6040F02000D6
+:1067A0008DF8080042F60520ADF83C000E959DF8E6
+:1067B0003A00119520F00600801C8DF83A009DF8F3
+:1067C00038006A4620F0FF008DF838009DF8390047
+:1067D00009A920F0FF008DF839000420ADF82C0045
+:1067E000ADF830000EA80A9011A80D900FA80990DE
+:1067F000ADF82E5002A8FFF76AFD00280BD1BDF8B6
+:106800000000608100E008E0BDF80400A081401CA9
+:10681000E0812571002013B0F0BD6581A581BDF830
+:106820004800F4E72DE9F74F1749A0B000240839D4
+:1068300017940A79A146012A04D0022A02D008201E
+:1068400023B02FE5CA88824201D00620F8E72198BC
+:106850008A46824201D10720F2E701202146ADF8A5
+:1068600048004FF6FF7860F30F21ADF84A808DF8AD
+:106870006E0042F6020B06918DF87240ADF86CB0D6
+:10688000ADF870401CA901E0300200201391ADF872
+:10689000508012A804F049FA00252E462F460DAB71
+:1068A000072212A9404604F043FA78B10A285DD1C4
+:1068B00095B38EB3ADF86450ADF866609DF85E0098
+:1068C0008DF8144019AC012864D06BE09DF83A00B3
+:1068D0001FB3012859D1BDF8381059451FD118A848
+:1068E00009A901940294CDE9031007200090BDF896
+:1068F000361010230022404604F09AFAB0BBBDF8CF
+:106900006000042801D006284AD1BDF8241021983F
+:1069100081423AD10F2093E73AE0012835D1BDF802
+:106920003800B0F5205F03D042F6010188422CD137
+:10693000BAF80600BDF83610884201D1012700E000
+:10694000002705B19EB1219881421ED118A809AA3D
+:1069500001940294CDE90320072000900D461023F6
+:106960000022404604F064FA00B902E02DE04E46F1
+:106970000BE0BDF86000022801D0102810D1C0B291
+:1069800017AA09A908F05AF850B9BDF8369086E759
+:10699000052055E705A917A8221D08F06EF808B1D3
+:1069A00003204DE79DF814000023001DC2B28DF8AE
+:1069B000142022980092CDE901401BA8069904F00A
+:1069C000C7F810B902228AF80420FEF75AFE37E70A
+:1069D00010B50B46401E88B084B205AA00211846A7
+:1069E000FEF7EEFE00200DF1080C06AA05A90190A5
+:1069F0008CE80700072000900123002221464FF673
+:106A0000FF7003F0EBFF0446BDF81800012800D02A
+:106A1000FFDF2046FEF735FE08B010BDF0B5FF4F92
+:106A2000044687B038790E46032804D0042802D0E3
+:106A3000082007B0F0BD04AA03A92046FEF799FE7E
+:106A40000500F6D160688078C0F3410002280AD1C1
+:106A50009DF80D0010F0380F05D0206909F05EFF99
+:106A600008B11020E5E7208905AA21698DE8070013
+:106A70006389BDF810202068039904F069F810B10B
+:106A8000FEF7FFFDD5E716B1BDF8140030800420F5
+:106A900038712846CDE7F8B50C0006460BD0014604
+:106AA0004FF6FF7500236A46284604F043FA20B1EA
+:106AB000FEF7E7FDF8BD1020F8BD69462046FEF759
+:106AC00010FE0028F8D1A078314600F001032846D6
+:106AD000009A04F05BFAEBE730B587B01446002269
+:106AE0000DF1080C05AD01928CE82C0007220092F4
+:106AF0000A46014623884FF6FF7003F06FFFBDF88A
+:106B000014102180FEF7BDFD07B030BD70B50D46F5
+:106B1000042106F011FA040000D1FFDF294604F138
+:106B20001400BDE8704002F07FBF70B50D4604212F
+:106B300006F002FA040000D1FFDF294604F1140038
+:106B4000BDE8704002F093BF70B50D46042106F019
+:106B5000F3F9040000D1FFDF294604F11400BDE879
+:106B6000704002F0ABBF70B50546042106F0E4F9B1
+:106B7000040000D1FFDF214628462368BDE87040AD
+:106B80000122FEF74BBF70B50646042106F0D4F98A
+:106B9000040000D1FFDF04F1140002F035FF401DB6
+:106BA00020F0030511E0011D008800224318214652
+:106BB0003046FEF733FF00280BD0607CABB2684351
+:106BC00082B2A068011D06F092F8A06841880029F1
+:106BD000E9D170BD70B50546042106F0ADF9040099
+:106BE00000D1FFDF214628466368BDE870400222DD
+:106BF000FEF714BF70B50E46054601F0EBF8040031
+:106C000000D1FFDF0120207266726580207820F0BD
+:106C10000F00001D20F0F00040302070BDE87040F3
+:106C200001F0DBB810B50446012900D0FFDF204693
+:106C3000BDE810400121FEF7F1BA2DE9F04F97B001
+:106C40004FF0000A0C008346ADF814A0D04619D0CE
+:106C5000E06830B1A068A8B10188ADF81410A0F8C0
+:106C600000A05846FAF7E8FC070043F2020961D099
+:106C7000387822285CD30421584606F05DF90500D7
+:106C800005D103E0102017B0BDE8F08FFFDF05F15C
+:106C9000140002F0B9FE401D20F00306A078012880
+:106CA00003D0022801D00720EDE7218807AA584623
+:106CB00004F00BF830BB07A804F013F810BB07A8CA
+:106CC00004F00FF848B99DF82600012805D1BDF859
+:106CD0002400A0F52451023902D04FF45050D2E7DD
+:106CE000E068B0B1CDE902A00720009005AACDF878
+:106CF00004A00492A2882188BDF81430584603F0FD
+:106D00006DFE10B1FEF7BDFCBDE7A168BDF8140033
+:106D100008809DF81F00C00602D543F20140B2E78B
+:106D20000B9838B1A1780078012905D080071AD4D2
+:106D30000820A8E74846A6E7C007F9D002208DF84A
+:106D40003C00A8684FF00009A0B1697C42887143FB
+:106D500091420FD98AB2B3B2011D05F07EFF804681
+:106D6000A0F800A006E003208DF83C00D5F80080D4
+:106D70004FF001099DF8200010F0380F00D1FFDF1F
+:106D80009DF820002649C0F3C200084497F823105C
+:106D900010F8010C884201D90F2074E72088ADF863
+:106DA000400014A90095CDE90191434607220FA99F
+:106DB0005846FEF75DFE002891D19DF8500050B96D
+:106DC000A078012807D1687CB3B2704382B2A8686A
+:106DD000011D05F056FF002055E770B50646154623
+:106DE0000C460846FEF70CFC002805D12A46214631
+:106DF0003046BDE8704075E470BD13E570B51E46C1
+:106E000014460D000ED06CB1616859B160B10349F0
+:106E1000C988814208D0072070BD000028020020E8
+:106E2000468301001020F7E72068FEF7E9FB002801
+:106E3000F2D1324621462846BDE87040FFF747BAF6
+:106E400070B515460C0006D038B1FE49098981425B
+:106E500003D00720E0E71020DEE72068FEF7D0FB34
+:106E60000028D9D129462046BDE87040D6E570B546
+:106E7000064686B00D461446104609F031FDD0BBDB
+:106E8000606809F054FDB0BBA6F57F40FF3803D021
+:106E90003046FAF7D1FB80B128466946FEF7E3FC9D
+:106EA00000280CD19DF810100F2008293CD2DFE8F3
+:106EB00001F008060606060A0A0843F2020006B0B8
+:106EC000AAE70320FBE79DF80210012908D1BDF8CD
+:106ED0000010B1F5C05FF2D06FF4C052D142EED0D5
+:106EE0009DF8061001290DD1BDF80410A1F5285117
+:106EF000062907D200E028E0DFE801F003030403DD
+:106F00000303DCE79DF80A1001290ED1BDF8081033
+:106F1000B1F5245FD3D0A1F524510239CFD0012996
+:106F2000CDD0022901D1CAE7FFDF606878B900231C
+:106F300005AA2946304603F0FDFF10B1FEF7A1FB7C
+:106F4000BDE79DF81400800601D41020B7E76188E2
+:106F5000224628466368FFF7BFFDB0E72DE9F043FE
+:106F6000814687B088461446104609F0B9FC18B12E
+:106F7000102007B0BDE8F083002306AA414648462A
+:106F800003F0D8FF18B100BFFEF77BFBF1E79DF8D7
+:106F90001800C00602D543F20140EAE700250727A2
+:106FA00005A8019500970295CDE9035062884FF638
+:106FB000FF734146484603F03BFF060013D160686B
+:106FC00009F08EFC60B960680195CDE90250009728
+:106FD0000495238862884146484603F029FF064607
+:106FE000BDF8140020803046CEE739B1954B0A88B1
+:106FF0009B899A4202D843F2030070471DE610B500
+:1070000086B0904C0423ADF81430638943B1A48951
+:107010008C4201D2914205D943F2030006B010BD63
+:107020000620FBE7ADF81010002100910191ADF8AA
+:10703000003002218DF8021005A9029104A90391E4
+:10704000ADF812206946FFF7F8FDE7E72DE9FC47A8
+:1070500081460E46084609F01DFC88BB4846FAF7F3
+:10706000EBFA5FEA00080AD098F80000222829D33A
+:107070000421484605F060FF070005D103E043F214
+:107080000200BDE8FC87FFDF07F1140002F0D3FC2B
+:1070900005463078012803D0022804D00720F0E705
+:1070A000A8070FD502E015F01C0F0BD0B079341DE6
+:1070B000C00709D0E08838B1A06809F0EBFB18B12F
+:1070C0001020DEE70820DCE732782088002628B38D
+:1070D000A0F201130721112B18D20CD2DFE803F024
+:1070E0000B090D0B1D0B121D100B0B1D1D1D1D0B78
+:1070F0001D00022A11D10846C3E7012AFBD00CE08B
+:107100002A0700E0EA06002AF5DA06E0A0F5C072D8
+:107110001F2A02D97D3A022AEDD8C6B200F05AFEE3
+:1071200050B198F82300CDE90006FA892346394684
+:107130004846FEF7EAFCA4E71120A2E72DE9F04F4C
+:107140008BB01F4615460C4683460026FAF774FAA4
+:1071500028B10078222805D208200BB094E543F22C
+:107160000200FAE7B80801D00720F6E7032F00D1A4
+:1071700000274FF6FF79CCB1022D73D3204609F0DA
+:10718000D6FB30B904EB0508A8F1010009F0CFFBEC
+:1071900008B11020E1E7AD1EAAB221464846FBF730
+:1071A000E7FE38F8021C88425CD1ADB22549B80729
+:1071B00002D58889401C00E001201FFA80F8F807FA
+:1071C00001D08F8900E04F4605AA4146584603F09A
+:1071D0007CFD4FF0070A4FF00009ACB3204608E0F1
+:1071E000408810283ED8361D304486B2AE4239D28F
+:1071F000A01902884245F3D354E000BF9DF8170060
+:1072000002074FD584B304EB0608361DB8F80230E8
+:10721000B6B2102B26D89A19AA4223D8B8F8002063
+:1072200091421FD1C00620D5CDE900A90DF1080C6F
+:107230000AAAA11948468CE80700B8F800100022F5
+:10724000584603E0280200202CE00BE003F0C6FBC8
+:1072500010B1FEF716FA80E7B8F80200BDF8281062
+:10726000884202D00B2078E704E0B8F802003044EE
+:1072700086B206E0C00604D55846FEF778FC002822
+:1072800088D19DF81700BDF81A1020F010008DF875
+:107290001700BDF81700ADF80000FF235846009A0C
+:1072A00003F074FE05A803F01CFD18B9BDF81A1010
+:1072B000B942A3D90421584605F03EFE040000D18E
+:1072C000FFDFA2895AB1CDE900A94D46002321462E
+:1072D0005846FEF71AFC0028BDD1A5813DE70020E5
+:1072E0003BE72DE9FF4F8BB01E4617000D464FF0D0
+:1072F000000412D0B00802D007200FB0C4E4032E5F
+:1073000000D100265DB1084609F008FB28B938888D
+:10731000691E084409F002FB08B11020EDE7C74AD6
+:10732000B00701D5D18900E00121F0074FF6FF78C1
+:1073300002D0D089401E00E0404686B206AA0B98D3
+:1073400003F0C3FC4FF000094FF0070B0DF1140AD6
+:1073500039E000BF9DF81B00000734D5CDF804903C
+:10736000CDF800B0CDF80890CDE9039A434600224D
+:107370000B9803F05DFD60BB05B3BDF814103A88AF
+:1073800021442819091D8A4230D3BDF81E2020F857
+:10739000022BBDF8142020F8022BCDE900B9CDE96D
+:1073A0000290CDF810A0BDF81E10BDF814300022D8
+:1073B0000B9803F03DFD08B103209EE7BDF81400D3
+:1073C0002044001D84B206A803F08BFC20B10A28DB
+:1073D00006D0FEF756F990E7BDF81E10B142B9D9B4
+:1073E00034B17DB13888A11C884203D20C2084E7D7
+:1073F000052082E7224629464046FBF7B9FD0146B3
+:1074000028190180A41C3C80002076E710B50446B2
+:1074100009F066FA08B1102010BD8848C0892080A4
+:10742000002010BDF0B58BB00D460646142103A810
+:1074300010F0C6FD01208DF80C008DF81000002022
+:107440008DF81100ADF814503046FAF7F5F848B150
+:107450000078222812D30421304605F06DFD040087
+:1074600005D103E043F202000BB0F0BDFFDF04F1F1
+:107470001400074602F0DFFA800601D40820F3E783
+:10748000207C022140F00100207409A80094CDE97D
+:107490000110072203A930466368FEF7E9FA20B11C
+:1074A000217C21F001012174DEE729463046FDF7F9
+:1074B000A6FE08A9384602F0ADFA00B1FFDFBDF81C
+:1074C0002040172C01D2172000E02046A84201D905
+:1074D0002C4602E0172C00D2172421463046FFF735
+:1074E00024FB21463046FDF7B0FB0020BCE7F8B591
+:1074F0001C4615460E46069F05F050FE2346FF1D0E
+:10750000BCB231462A46009405F059FAF8BD70B570
+:107510000C4605460E21204610F030FD002020804C
+:107520002DB1012D01D0FFDF76E4062000E005201B
+:10753000A07171E410B548800878134620F00F0060
+:10754000001D20F0F00080300C460870142219460F
+:1075500004F1080010F0D8FC00F03FFC374804604C
+:1075600010BD2DE9F047DFF8D890491D064621F0FF
+:10757000030117460C46D9F8000005F036FB05005C
+:1075800000D1FFDF4FF000083560A5F800802146EC
+:10759000D9F8000005F029FB050000D1FFDF756078
+:1075A000A5F800807FB104FB07F1091D0BD0D9F8C5
+:1075B000000005F01AFB040000D1FFDFB460C4F83E
+:1075C0000080BDE8F087C6F80880FAE72DE9F041B1
+:1075D0001746491D21F00302194D0646016814465D
+:1075E000286805F02DFB22467168286805F028FB05
+:1075F0003FB104FB07F2121D03D0B168286805F003
+:107600001FFB042005F044FC0446042005F048FC60
+:10761000201A012804D12868BDE8F04105F0DABA43
+:10762000BDE8F08110B50C4603F01BFB00B1FFDF95
+:107630002046BDE81040FEF724B8000028020020D4
+:107640001400002038B582880A800C46C188121DBB
+:1076500090B26A4604F091FDBDF80000032800D303
+:107660000320C1B2208800F077FF38BD38B582888A
+:107670000A800C46C188121D90B26A4604F07DFD56
+:10768000BDF80000022800D30220C1B2208800F01B
+:1076900063FF401CC0B238BD2DE9FE4F0C46F849CF
+:1076A00081464022D1E90201CDE9010109F103003F
+:1076B00020F00301C91C21F0030100916846114626
+:1076C00005F075FAEF4E002C02D1EF4A0099916057
+:1076D000009901440091357E05F1010504D1E8B21D
+:1076E00007F052F900B1FFDF009800EB0510C01C55
+:1076F00020F00301009144B9727A00200870B08B29
+:1077000080B203F036F900B1FFDF0098F169084458
+:1077100000902146684600F0E6FE0098C01C20F06C
+:1077200003000090717A04B1002005F02AFB009953
+:10773000084400902146684600F019FF00273D46A6
+:10774000B24696F801800CE0284600F0AFFE0646EF
+:1077500081788088FDF710FB71786D1C00FB017744
+:10776000EDB24545F0D10098C01C20F00300009018
+:1077700004B100203946FDF70AFB009900270844B0
+:1077800000903D469AF801800CE0284600F08EFEFD
+:107790000646C1788088FEF774FC71786D1C00FB8A
+:1077A0000177EDB24545F0D10098C01C20F00300F0
+:1077B000009004B100203946FEF76CFC00990844A3
+:1077C00000210090084603F064FD2146684600F061
+:1077D00050FE0098C01D20F0070200922CBBAB4960
+:1077E0000020FBF7E3FAFAF7D5FBA64801AA00212F
+:1077F0000C30FAF7D7FF00B1FFDF9AF81900FEF757
+:10780000B0FF00B1FFDF9F484FF4F671383010F041
+:10781000D7FB9C480421383080F8E91180F8EA1140
+:10782000062180F8EB11032101710099A1EB0900F9
+:10783000BDE8FE8F70B5934C06463834207804EBD3
+:107840004015E078083590B9A01990F8E8010028B3
+:107850000ED0A0780F2800D3FFDF2021284610F09B
+:10786000AFFB687866F3020068700120E07028467C
+:1078700070BD2DE9F04105460C4600270078052132
+:1078800090463E46B1EB101F00D0FFDF287A58B17A
+:1078900001280FD0FFDF00BFA8F800600CB12780DF
+:1078A00066800020BDE8F0810127092674B1688850
+:1078B000A08008E00227142644B16888A0802869C7
+:1078C000E060A88A2082287B2072E5E7A8F80060A3
+:1078D000E7E710B56C4C6068C11D21F007018142DB
+:1078E00000D0FFDF67480121002201704270017261
+:1078F00041720273052282821F22C282417364A2F6
+:1079000002610A22027641764FF4B061C16161687A
+:10791000416010BD30B55C4C1568636808339D420A
+:1079200002D20420136030BD564B5D785A6802EBDA
+:10793000C502107051700320D08017209080012064
+:10794000D07090705878401C587060680830606043
+:10795000002030BD70B506464A480024457807E04F
+:10796000204600F0A3FD0178B14204D0641CE4B2CB
+:10797000AC42F5D1002070BDF7B5064608780C463C
+:10798000F8B1FFF7E7FF0546202E06D0212E1AD0CA
+:10799000222E18D0232E14D110E000F092FD0DB14C
+:1079A000697800E00021401A81B2A0780144FF29E3
+:1079B00007D830B1A088022805D202E060881728D5
+:1079C00001D20720FEBD65B9207802AA0121FFF788
+:1079D000A1FF0028F6D12078FFF7BCFF050000D1F9
+:1079E000FFDF202E08D0212E0ED0222E0FD0232EE6
+:1079F00007D0FFDF0020FEBDA0786870A088E88077
+:107A0000F8E76088A880F5E7A078A870F2E7A0788A
+:107A1000E870EFE71A2841D00DDC13283ED2DFE8EA
+:107A200000F01B3D203D3D272723252D3D3D293DD1
+:107A30003D3D3D3B0F00302802D003DC1E282DD1F8
+:107A4000072070473A38092828D2DFE800F01527C8
+:107A50000F272727272707000020704743F204003D
+:107A6000704743F202007047042070470D207047B2
+:107A70000F2070470820704711207047132070476F
+:107A80004C830100640200201C0000200000002044
+:107A90006E524635780000000620F0E70320EEE73E
+:107AA00010B5007800F0010004F062FBBDE8104062
+:107AB000B0E70EB5017801F001018DF800104178B2
+:107AC00001F001018DF801100178C1F340018DF83A
+:107AD00002104178C1F340018DF803100178890844
+:107AE0008DF80410417889088DF8051081788DF89B
+:107AF0000610C1788DF8071000798DF808006846E7
+:107B000003F0B4FFFFF786FF0EBD2DE9F84FDFF855
+:107B1000F883FE4C00261FE0012000F06BFD0120E1
+:107B2000FFF788FE054640214746D8F8080005F0D3
+:107B30005CF8686000B9FFDF686803F084FEA8B1F4
+:107B40002846F9F7EAFE284600F05AFD20B94022FF
+:107B50006968B86805F074F894F9E9010428DBDA7B
+:107B6000022005F095F907460025A6E04022696845
+:107B7000D8F8080005F064F8F2E7B8F802104046BB
+:107B8000491C89B2A8F80210B94201D300214180F2
+:107B90000221B8F8020005F0CFF9002865D0B8F846
+:107BA0000200694604F063FAFFF734FF00B1FFDF1B
+:107BB0009DF8000078B1B8F8020005F001FB5FEA1B
+:107BC000000900D1FFDF484604F08DFD18B1B8F878
+:107BD000020003F022FDB8F8020005F0DFFA5FEAC8
+:107BE000000900D1FFDF484604F075FDE8BB032122
+:107BF000B8F8020005F0A0F95FEA000B48D1FFDFFA
+:107C000046E000BFDBF80C0010B10078FF2849D037
+:107C1000022000F0EFFC0220FFF70CFE82464846EF
+:107C200004F065FECAF8040000B9FFDFDAF80400CA
+:107C300004F02DFF002100900170B8F802105046AA
+:107C4000AAF8021003F0C2FB484604F022FF00B974
+:107C5000FFDF504600F0D4FC18B99AF80100000785
+:107C600004D50099CBF80C1012E024E0DBF80C00EE
+:107C700038B10178491C11F0FF01017008D1FFDF14
+:107C800006E000221146484600F0F1FB00B9FFDF94
+:107C900094F9EA01022805DBB8F8020003F071FB51
+:107CA0000028AFD194F9E901042804DB484604F028
+:107CB00054FF00B101266D1CEDB2BD4204D294F90F
+:107CC000EA010228BFF659AF002E7FF423AFBDE8CA
+:107CD000F84F032000F08EBC10B58B4CE0600868B4
+:107CE0002061AFF2D910FBF774F8607010BD8748BF
+:107CF0000021383801708448017085494160BEE632
+:107D000070B505464FF080500C46D0F8A410491CC1
+:107D100005D1D0F8A810C9430904090C0BD050F8BC
+:107D2000A01F01F001012970416821608068A080D6
+:107D3000287830B970BD0621204608F0B4FA012039
+:107D40002870607940F0C000607170BD70B54FF070
+:107D500080540D46D4F88010491C0BD1D4F88410FF
+:107D6000491C07D1D4F88810491C03D1D4F88C10D1
+:107D7000491C0CD0D4F880100160D4F88410416004
+:107D8000D4F888108160D4F88C10C16002E0102112
+:107D900008F089FAD4F89000401C0BD1D4F8940074
+:107DA000401C07D1D4F89800401C03D1D4F89C00A3
+:107DB000401C09D054F8900F286060686860A06883
+:107DC000A860E068E86070BD2846BDE870401021FA
+:107DD00008F069BA4D4800792CE570B54B4CE07855
+:107DE00030B3207804EB4010407A00F007002044C4
+:107DF00090F9E801002800DCFFDF2078002504EB83
+:107E00004010407A00F00700011991F8E801401E87
+:107E100081F8E8012078401CC0B220700F2800D102
+:107E20002570A078401CA07008F070F9E57070BD56
+:107E3000FFDF70BD3EB50546032105F07DF8044621
+:107E4000284605F0ABF9054604B9FFDFE06818B134
+:107E50000078FF2800D1FFDF01AA6946284600F01C
+:107E600006FB60B9FFDF0AE0002202A9284600F005
+:107E7000FEFA00B9FFDF9DF8080000B1FFDF9DF8B2
+:107E80000000411E8DF80010EED2E0680199884292
+:107E900001D10020E0603EBD70B50546A0F57F40F1
+:107EA0000C46FF3800D1FFDF012C01D0FFDF70BD91
+:107EB000FFF790FF040000D1FFDF207820F00F00D3
+:107EC000401D20F0F00050302070658000202072AE
+:107ED00001202073BDE870407FE72DE9F041164690
+:107EE0000D460746FFF776FF040000D1FFDF20783C
+:107EF00020F00F00401D20F0F0005030207067800F
+:107F000001202072286805E01C0000209C0200204F
+:107F1000100E00202061A888A0822673BDE8F041E1
+:107F20005BE77FB5FFF716FD040000D1FFDF02A974
+:107F30002046FFF787FB054603A92046FFF796FB7F
+:107F40008DF800508DF80100BDF80800001DADF857
+:107F50000200BDF80C00001DADF80400E088ADF88B
+:107F60000600684604F0EDF8002800D0FFDF7FBD72
+:107F70002DE9F05FFA4E04464FF00008307810B15A
+:107F80000820BDE8F09F204608F0AAFC08B11020A8
+:107F9000F7E7F44D287808B9FFF79BFC6D7A00F0FD
+:107FA00090FAA84208D2281AC1B222460020FFF750
+:107FB000B1FC5FEA0008E4D1E9484168C91C21F03E
+:107FC000030100274160E7483E46BA46BB463D46AE
+:107FD00090F8019007E0284600F068FA40786D1CA0
+:107FE0000644EDB27F1C4D45F5D1DE4D0BEB87000D
+:107FF000C6EBC60100EB8100697ADFF8649300EB01
+:108000008A0000EBC100D9F8041047180121384656
+:10801000FFF742FB064621683844884202D8B6F58D
+:10802000803F15D320600020FFF794FC04000DD0A2
+:1080300004F10B00D9F8041020F003004E468842EA
+:1080400000D0FFDF6878401E68707460042098E7F5
+:1080500000213846FFF720FB0546AE4200D0FFDF87
+:10806000E919C9F8041021604FF6FF71A9F8021050
+:10807000012189F80010404683E72DE9F0410446CC
+:10808000B74817460D46007808B108200AE40846AC
+:1080900008F000FC08B1102004E4B24E307808B9B2
+:1080A000FFF717FC601E1E2807D8012C3DD1287849
+:1080B000FE283AD830760020E8E7A4F120001F28F7
+:1080C00005D8E0B23A462946BDE8F04154E4A4F1AF
+:1080D00040004FF000081F281FD8402C02D0412C30
+:1080E00023D115E028786C78012801D91320CDE739
+:1080F000FF2C08D806F02CFE074607F0C0FF381A00
+:10810000401EA04201DA1220C0E72888308124E016
+:108110002846BDE8F04100F09BBAA4F1A0001F285A
+:1081200003D8A02C03D0A12C06D00720AEE72878D6
+:1081300000F00100707610E029680920F829A5D325
+:108140008A07A3D1727B02F00302012A04D1F28ACA
+:10815000D73293B28B4299D8F161404696E72DE928
+:10816000F04781460E46084608F0BAFB48B9484633
+:1081700008F0D4FB28B909F1030020F003014945B8
+:1081800002D01020BDE8F08776484FF0000A383062
+:10819000817869B14178804600EB41140834378812
+:1081A00032460021204600F039FA050004D027E0CD
+:1081B000A6F800A00520E5E7B9F1000F24D030882B
+:1081C000B84201D90C251FE0607800F00705284669
+:1081D00000F010FA08EB0507324697F8E801494627
+:1081E000401C87F8E801204607F5F47700F016FAFE
+:1081F00005463878401E3870032000F0FBF92DB199
+:108200000C2D01D0A6F800A02846BBE76078544E9C
+:1082100000F00701012923D002290CD0032933D013
+:10822000FFDF98F801104046491CC9B288F80110D8
+:108230000F2934D035E0616821B1000702D460888D
+:10824000FFF7F8FD98F8EA014746012802D1707857
+:10825000FAF7DEFD97F9EA010428E2DBFFDFE0E749
+:10826000616819B14022B06804F0EAFC98F8E901AD
+:108270004746032802D17078FAF7CAFD97F9E90159
+:108280000428CEDBFFDFCCE7C00602D56088FFF70D
+:10829000D1FD98F9EB010628C3DBFFDFC1E780F8C9
+:1082A00001A08178491E8170617801F0070101EB1E
+:1082B000080090F8E811491C80F8E811A4E770B5AF
+:1082C0000D46044608F0E6FA18B9284608F008FBFF
+:1082D00008B1102070BD29462046BDE8704006F068
+:1082E0008ABB70B5044615460E46084608F0D2FA19
+:1082F00018B9284608F0F4FA08B1102070BD022C15
+:1083000003D0102C01D0092070BD2A4631462046EA
+:1083100006F094FB0028F7D0052070BD70B5144618
+:108320000D46064608F0B6FA38B9284608F0D8FADD
+:1083300018B9204608F0F2FA08B1102070BD2246A4
+:108340002946304606F099FB0028F7D0072070BD7B
+:108350003EB5044608F0C4FA30B110203EBD00001E
+:108360001C00002064020020684603F00EFBFFF7AB
+:1083700051FB0028F2D19DF806002070BDF80800DE
+:108380006080BDF80A00A0800020E7E770B50546D0
+:108390000C46084608F0C2FA20B93CB1206808F043
+:1083A0009FFA08B1102070BDA08828B12146284648
+:1083B000BDE87040FDF7E4BE092070BD70B504460D
+:1083C0000D46084608F066FA30B9601E1E2814D81B
+:1083D000284608F05FFA08B1102070BD022C01D9C0
+:1083E000072070BD04B9FFDFBF4800EB840050F8E0
+:1083F000041C2846BDE870400847A4F120001F284F
+:1084000005D829462046BDE87040F9F766BDF02C36
+:10841000E6D1A86808F03EFA0028DDD1284603F02E
+:10842000E2FEBDE87040FFF7F5BA70B504460D46B0
+:10843000084608F055FA30B9601E1E280DD82846A7
+:1084400008F028FA08B1102070BD012C01D0022CD0
+:1084500001D1062070BD072070BDA4F120001F28A7
+:10846000F9D829462046BDE87040F9F773BD04F0FD
+:1084700001B908B5002918D1FAF745FD9B4800223B
+:108480004178C06803F0B5F998481030C0788DF88D
+:10849000000010B1012802D004E0012000E000201B
+:1084A0008DF80000684603F0C8FA08BD30B5904D5D
+:1084B00004466878A04200D8FFDF686800EBC4007B
+:1084C00030BD70B58A4800252C46467807E0204626
+:1084D000FFF7ECFF4078641C2844C5B2E4B2B44214
+:1084E000F5D1284670BD2DE9F041054680480C467F
+:1084F000427A9600761CFF2E00D9FFDF2868F6B27C
+:10850000C01C20F003022A600CBB794833460621C8
+:10851000203008F099F8002408E0062C0FD2DFE89C
+:1085200004F0050307070903724804E0724802E0FB
+:10853000724800E0724808F0A7F8074600E0FFDF45
+:10854000A74200D0FFDF641CE4B2062CE5D3286804
+:1085500000EB0610286099E5021D5143452900D221
+:1085600045210844C01CB0FBF2F0C0B270472DE9B1
+:10857000FC5F06465E484FF000088B46474644467F
+:1085800090F8019022E02046FFF790FF050000D10F
+:10859000FFDF687869463844C7B22846FFF752F8CB
+:1085A000824601A92846FFF761F80346BDF804009A
+:1085B0005246001D81B2BDF80000001D80B204F0DB
+:1085C00039FD6A78641C00FB0288E4B24C45DAD1BC
+:1085D0003068C01C20F003003060BBF1000F00D0F9
+:1085E00000204246394604F033FD316808443060CB
+:1085F000BDE8FC9F3E49383108710020C8707047C3
+:108600003B493831CA782AB10A7801EB4211083166
+:10861000814201D001207047002070472DE9F041D0
+:1086200006460078154600F00F0400201080601EFA
+:108630000F46052800D3FFDF2B482A46103000EBF9
+:108640008400394650F8043C3046BDE8F0411847F4
+:1086500038B50446407800F00300012803D0022812
+:108660000BD0072038BD606858B108F060F9D0B968
+:10867000606808F053F920B915E0606808F00AF95D
+:1086800088B969462046FBF709FB0028EAD16078E3
+:1086900000F00300022808D19DF8000028B16068AE
+:1086A00008F03CF908B1102038BD6189F8290DD8CF
+:1086B000208988420AD8607800F003020C48012A19
+:1086C00006D1D731C26989B28A4201D2092038BDA8
+:1086D00094E80E0000F10C0585E80E000AB90021AF
+:1086E0008182002038BD00004C8301001C00002066
+:1086F000640200200D1E0000DDB20000F12E00001B
+:108700007BE7000070B50B2000F0AFF9082000F007
+:10871000ACF900210B2000F0BEF90021082000F088
+:10872000BAF9E54C01256560A5600020C4F8400158
+:10873000C4F84401C4F848010B2000F0A1F9082056
+:1087400000F09EF90B2000F085F9256070BD10B592
+:108750000B2000F08AF9082000F087F9D6480121A3
+:1087600041608160D5490A68002AFCD10021C0F827
+:108770004011C0F84411C0F848110B2000F080F9F6
+:10878000BDE81040082000F07BB910B50B2000F0C8
+:1087900077F9BDE81040082000F072B900B530B19B
+:1087A000012806D0022806D0FFDF002000BDC44803
+:1087B00000BDC44800BDC348001D00BD70B5C2491E
+:1087C0004FF000400860C14DC00BC5F80803C04819
+:1087D00000240460C5F840410820C43500F045F984
+:1087E000C5F83C41BB48047070BD08B5B24A0021D1
+:1087F00028B1012811D002281CD0FFDF08BD4FF49A
+:108800008030C2F80803C2F84803AC483C3001602D
+:10881000C2F84011BDE80840D0E74FF40030C2F87C
+:108820000803C2F84803A54840300160C2F844116B
+:10883000A4480CE04FF48020C2F80803C2F84803B3
+:108840009E4844300160C2F848119E48001D0068EF
+:10885000009008BD70B516460D460446022800D9A2
+:10886000FFDF00229448012304F110018B4000EB4C
+:108870008401C1F8405526B1C1F84021C0F8043345
+:1088800003E0C0F80833C1F84021C0F8443370BD9C
+:108890002DE9F0411C46154630B1012834D002289C
+:1088A00039D0FFDFBDE8F081891E002221F07F4131
+:1088B0001046FFF7CFFF012C24D00020854E834FB8
+:1088C000012470703C61824900203C39086002201C
+:1088D000091D08607E490420303908607C483D3518
+:1088E0000560C7F80042082000F0CAF82004C7F865
+:1088F0000403082000F0AEF87349E007091F086080
+:108900003470CFE70120D9E7012B02D000220120EB
+:1089100005E00122FBE7012B04D000220220BDE884
+:10892000F04197E70122F9E764480068704770B5A5
+:10893000614CD4F840010025012809D1D4F808037E
+:10894000C00305D54FF48030C4F80803C4F8405183
+:10895000D4F8440101280CD1D4F80803800308D5C9
+:108960004FF40030C4F80803C4F84451012007F064
+:1089700048F8D4F8480101280ED1D4F80803400380
+:108980000AD54FF48020C4F80803C4F84851BDE864
+:108990007040022007F035B870BD10B54D4C2078FE
+:1089A00050B1FFF70BFF6078002807D000206070FF
+:1089B000BDE8104007F025B80320F9E710BD4FF0DF
+:1089C000E0214FF40010C1F800027047152000F0BC
+:1089D00057B83E4901200861082000F051B83B49D2
+:1089E0004FF47C10C1F808030020024601EB80031D
+:1089F000C3F84025C3F84021401CC0B20628F5D377
+:108A00007047410A43F609525143C0F3080010FB76
+:108A100002F000F5807001EB5020704710B5430B59
+:108A200048F2376463431B0C5C020C602A4C03FB66
+:108A300004002A4B4CF2F72443435B0D13FB04F470
+:108A400004EB402000F58070401210700868184454
+:108A5000086010BD00F01F02012191404009800014
+:108A600000F1E020C0F80011704700F01F02012162
+:108A700091404009800000F1E020C0F8801170476B
+:108A800000F01F02012191404009800000F1E02028
+:108A9000C0F8801270474907090E002806DA00F076
+:108AA0000F0000F1E02080F8141D704700F1E02075
+:108AB00080F800147047000000B0004004B500408A
+:108AC0004081004044B1004008F501400080004072
+:108AD0004085004030000020F7C2FFFF6F0C01000E
+:108AE00010B5EFF3108000F0010472B6F048417841
+:108AF000491C41704078012801D107F02FFB002C60
+:108B000000D162B610BD70B5E94CE07848B90125D6
+:108B1000E570FFF7E5FF07F029FB20B1002007F023
+:108B2000FCFA002070BD4FF080406571C0F804531E
+:108B3000F7E770B5EFF3108000F0010572B6DC4C7A
+:108B4000607800B9FFDF6078401E6070607808B917
+:108B500007F008FB002D00D162B670BDD44810B5F7
+:108B6000C17821B100214171C170FFF7E2FF0020FF
+:108B700010BD10B5044607F0F9FACD49C978084090
+:108B800000D001202060002010BD2DE9F05FDFF84B
+:108B900020934278817889F80620002589F807100B
+:108BA000064689F8085000782F4620B101280FD0DA
+:108BB00002280FD0FFDF07F0E6FA98B107F0EAFAD3
+:108BC000A8420FD1284607F0E9FA0028FAD047E07A
+:108BD0000125F0E7FFF784FF07F0C8FA0028FBD073
+:108BE0000225E8E701208407E060C4F80471B14978
+:108BF0000D600107D1F84412AE4AC1F3423124326C
+:108C00001160AC49343108604FF0020BC4F804B372
+:108C1000A060DFF8A4A2DAF80010C94341F3001104
+:108C200001F10108DAF8001041F01001CAF8001053
+:108C300000E020BFD4F804010028FAD0284607F04D
+:108C4000ADFA0028FAD0B8F1000F05D1DAF800101B
+:108C500021F01001CAF80010C4F808B3C4F8047178
+:108C600099F807004C4670B1307860B907F07EFA89
+:108C7000064607F0B1FB6FF0004116B1C4E90310DE
+:108C800001E0C4E9030115B12771BDE8F09F01209F
+:108C90002071BDE8F05F00F0AFB870B5050000D1FD
+:108CA000FFDF4FF080424FF0FF30C2F80803002191
+:108CB000C2F80011C2F80411C2F80C11C2F8101168
+:108CC0007B4C617007F058FA10B10120E0706070C1
+:108CD0002846BDE8704058E72DE9F05F4FF080442A
+:108CE000D4F8080110B14FF0010801E04FF000087E
+:108CF000D4F8000100B101208146D4F8040108B184
+:108D0000012700E00027D4F80C0100B101208246C1
+:108D1000D4F8100108B1012600E0002648EA090154
+:108D200027EA010020EA0A00B04300D0FFDF002557
+:108D3000B8F1000F04D0C4F80851012007F0EDF994
+:108D40005FEA0900DFF87491DFF864814FF0010BEE
+:108D500015D0C4F8005198F8050020B188F80550E6
+:108D6000002007F0DAF998F80010404639B1057094
+:108D700088F802B00222C9F80020C4F810B00FB180
+:108D8000C4F80451BAF1000F0DD0C4F80C5198F892
+:108D90000200474600B9FFDFC9F80050BD70C4F8B3
+:108DA00014B0FFF7C6FE002E09D0C4F8105198F891
+:108DB0000400002803D0BDE8F05F00F041B864E78C
+:108DC00070B53B4DE87808B907F0CCF9012084076D
+:108DD000A061A87858B100BFD4F80C0120B90020D8
+:108DE00007F0DCF90028F7D10020C4F80C014FF09F
+:108DF000FF30C4F8080370BD2DE9F0411926B4070F
+:108E0000C4F808630125A5610020C4F80001C4F876
+:108E10000C01C4F8100107F0A9F9254F28B1274922
+:108E2000BD7002200860256100E03D70FFF758FE2C
+:108E30002049B87920310860C4F80463BDE8F081A6
+:108E40002DE9F0411A4C4FF080470125E079F0B14F
+:108E5000012803D0217A401E814218DA07F086F9F2
+:108E6000064607F0B9FAE179012902D9217A491CAD
+:108E700021720EB1216900E0E168411A022902DA8B
+:108E800011F1020F0EDC0EB1206100E0E060FFF78F
+:108E900027FE07F06BF938B10849022008603D61F0
+:108EA000A57002E07D61C9E7257000202072C5E74A
+:108EB000340000201805004010ED00E0340C0040A4
+:108EC000F8B51D46DDE906470E000AD004F078F932
+:108ED0002346FF1DBCB231462A46009403F0A3FD91
+:108EE000F8BDD019224619460EF0C9FF2046F8BD3C
+:108EF00070B50D46044610210FF040F8258117206B
+:108F00006081A07B40F00A00A07370BD4FF6FF7235
+:108F10000A800146022007F071BC70470089704743
+:108F2000827BD30701D1920703D480890880002077
+:108F3000704705207047827B920700D5818170477A
+:108F400001460020098841F6FE52114200D001205E
+:108F5000704700B50346807BC00701D0052000BDE7
+:108F600059811846FFF7ECFFC00703D0987B40F00B
+:108F700004009873987B40F001009873002000BDB6
+:108F8000827B520700D509B140897047172070478E
+:108F9000827B61F3C302827370472DE9FC5F0E464A
+:108FA000044601789646012000FA01F14DF6FF5281
+:108FB00001EA020962684FF6FF7B1188594502D128
+:108FC0000920BDE8FC9FB9F1000F05D041F6FE5520
+:108FD000294201D00120F4E741EA090111801D0076
+:108FE00014D04FF0000C85F800C02378052103222F
+:108FF00067464FF0020A0E2B74D2DFE803F0F8093F
+:10900000252F47626974479092B3D0D70420D8E7E0
+:10901000616820898B7B9B077DD5172848D30B89F6
+:10902000834245D38989172901D3814240D185F8EC
+:1090300000A0A5F801003280616888816068817BAA
+:1090400021F002018173C5E0042028702089A5F871
+:1090500001006089A5F803003180BBE0208A3188D7
+:10906000C01D1FFA80F8414522D3062028702089B0
+:10907000A5F801006089A5F80300A089A5F80500FE
+:109080000721208ACDE9000163693EE0082B10D05A
+:10909000082028702089A5F801006089A5F8030040
+:1090A00031806A1D694604F10C0005F0E6FC10B140
+:1090B0005FE01020EDE730889DF800100844308014
+:1090C00088E00A2028702089A5F80100328045E058
+:1090D0000C2028702089A5F801006089A5F80300FC
+:1090E00031803BE083E02189338800EB41021FFAA5
+:1090F00082F843453DD3B8F1050F3AD30E222A70CA
+:109100000BEA4101CDE90010E36860882A46714608
+:10911000FFF7D6FE00E04DE0A6F800805AE04020C0
+:10912000287060893188C01C1FFA80F8414520D31F
+:109130002878714620F03F00123028702089A5F869
+:1091400001006089CDE9000260882A46E368FFF7E4
+:10915000B7FEA6F80080287840063BD461682089D5
+:10916000888037E0A0893288401D1FFA80F8424588
+:1091700001D204273EE0162028702089A5F80100BE
+:109180006089A5F80300A089CDE9000160882A461E
+:1091900071462369FFF794FEA6F80080DEE71820E9
+:1091A0002870207A6870A6F800A013E061680A8829
+:1091B000920401D405271DE0C9882289914201D07B
+:1091C000062717E01E21297030806068018821F48D
+:1091D00000510180B9F1000F0CD061887823002282
+:1091E000022007F061FA61682078887007E0A6F82D
+:1091F00000C003276068018821EA09010180384620
+:10920000DFE62DE9FF4F85B01746129C0D001E4684
+:109210001CD03078C10703D000F03F00192801D9D5
+:10922000012100E000212046FFF7AAFEA8420DD34D
+:109230002088A0F57F41FF3908D03078410601D45D
+:10924000000605D5082009B0BDE8F08F0720FAE731
+:1092500000208DF800008DF8010030786B1E00F0C2
+:109260003F0C0121A81E4FF0050A4FF002094FF0F4
+:10927000030B9AB2BCF1200F75D2DFE80CF08B1013
+:10928000745E7468748C749C74B674BB74C974D541
+:1092900074E2747474F274F074EF74EE748B052DD0
+:1092A00078D18DF80090A0788DF804007088ADF822
+:1092B000060030798DF80100707800F03F000C282E
+:1092C00029D00ADCA0F10200092863D2DFE800F00F
+:1092D000126215621A621D622000122824D004DC7A
+:1092E0000E281BD01028DBD11BE016281FD0182811
+:1092F000D6D11FE02078800701E0207840070028C1
+:1093000048DAEFE020780007F9E72078C006F6E7B2
+:1093100020788006F3E720784006F0E72078000602
+:10932000EDE72088C005EAE720884005E7E72088C8
+:109330000005E4E72088C004E1E72078800729D50C
+:10934000032D27D18DF800B0B6F8010082E0217816
+:1093500049071FD5062D1DD381B27078012803D08F
+:10936000022817D102E0CAE0022000E01020042207
+:109370008DF8002072788DF80420801CB1FBF0F28B
+:10938000ADF8062092B242438A4203D10397ADF86A
+:109390000890A7E07AE02078000777D598B2820895
+:1093A0008DF800A0ADF80420B0EB820F6ED10297CB
+:1093B000ADF8061096E02178C90667D5022D65D371
+:1093C00081B206208DF80000707802285ED300BFBD
+:1093D000B1FBF0F28DF80400ADF8062092B24243E2
+:1093E0008A4253D1ADF808907BE0207880064DD5B5
+:1093F000072003E0207840067FD508208DF8000084
+:10940000A088ADF80400ADF80620ADF8081068E0BB
+:109410002078000671D50920ADF804208DF80000F1
+:10942000ADF8061002975DE02188C90565D5022DCB
+:1094300063D381B20A208DF80000707804285CD3D1
+:10944000C6E72088400558D5012D56D10B208DF850
+:109450000000A088ADF8040044E021E026E016E01A
+:10946000FFE72088000548D5052D46D30C208DF850
+:109470000000A088ADF80400B6F803006D1FADF839
+:109480000850ADF80600ADF80AA02AE035E02088C3
+:10949000C00432D5012D30D10D208DF8000021E01F
+:1094A0002088800429D4B6F80100E080A07B000762
+:1094B00023D5032D21D3307800F03F001B2818D08E
+:1094C0000F208DF80000208840F40050A4F8000020
+:1094D000B6F80100ADF80400ED1EADF80650ADF889
+:1094E00008B0039769460598FBF7BEFB050008D056
+:1094F00016E00E208DF80000EAE7072510E00825A9
+:109500000EE0307800F03F001B2809D01D2807D05E
+:109510000220059907F072F9208800F4005020809D
+:10952000A07B400708D52046FFF70AFDC00703D1FE
+:10953000A07B20F00400A073284684E61FB5022813
+:1095400006D101208DF8000088B26946FBF78CFB3C
+:109550001FBD0000F8B51D46DDE906470E000AD024
+:1095600003F02EFE2346FF1DBCB231462A4600946E
+:1095700003F059FAF8BDD019224619460EF07FFCC7
+:109580002046F8BD2DE9FF4F8DB09B46DDE91B5706
+:10959000DDF87CA00C46082B05D0E06901F002F94B
+:1095A00050B11020D2E02888092140F01000288016
+:1095B0008AF80010022617E0E16901208871E2694B
+:1095C0004FF420519180E1698872E06942F601010F
+:1095D0000181E069002181732888112140F0200079
+:1095E00028808AF80010042638780A900A203870FB
+:1095F0004FF0020904F118004D460C9001F095FB64
+:10960000B04681E0BBF1100F0ED1022D0CD0A9EBBA
+:109610000800801C80B20221CDE9001005AB524643
+:109620001E990D98FFF796FFBDF816101A98814203
+:1096300003D9F74800790F9004E003D10A9808B1E4
+:1096400038702FE04FF00201CDE900190DF116033B
+:1096500052461E990D98FFF77DFF1D980088401B0C
+:10966000801B83B2C6F1FF00984200D203461E99C8
+:109670000BA8D9B15FF00002DDF878C0CDE9032076
+:1096800009EB060189B2CDE901C10F980090BDF840
+:10969000161000220D9801F0CBFB387070B1C0B2EB
+:1096A000832807D0BDF8160020833AE00AEB0901B1
+:1096B0008A19E1E7022011B0BDE8F08FBDF82C0057
+:1096C000811901F0FF08022D0DD09AF801204245C2
+:1096D00006D1BDF82010814207D0B8F1FF0F04D0A9
+:1096E0009AF801801FE08AF80180C9480068017873
+:1096F000052902D1BDF81610818009EB08001FFA78
+:1097000080F905EB080085B2DDE90C1005AB0F9A76
+:1097100001F00EFB28B91D980088411B4145BFF69A
+:1097200071AF022D13D0BBF1100F0CD1A9EB0800C3
+:10973000801C81B20220CDE9000105AB52461E9982
+:109740000D98FFF707FF1D98058000203870002056
+:10975000B1E72DE9F8439C46089E13460027B26BFB
+:109760009AB3491F8CB2F18FA1F57F45FF3D05D01B
+:109770005518AD882944891D8DB200E000252919AE
+:10978000B6F83C800831414520D82A44BCF8011085
+:1097900022F8021BBCF8031022F8021B984622F89C
+:1097A000024B914603F0FAFC4FF00C0C41464A463E
+:1097B0002346CDF800C003F002F9F587B16B002015
+:1097C0002944A41D2144088003E001E0092700E0AA
+:1097D00083273846BDE8F88310B50B88848F9C42F8
+:1097E0000CD9846BE018048844B1848824F40044C4
+:1097F000A41D23440B801060002010BD0A2010BD62
+:109800002DE9F0478AB00025904689468246ADF89A
+:10981000185007274BE0059806888088000446D436
+:10982000A8F8006007A8019500970295CDE90350BC
+:109830004FF4007300223146504601F0F9FA04005B
+:109840003CD1BDF81800ADF8200005980488818847
+:10985000B44216D10A0414D401950295039521F45B
+:1098600000410097049541F48043428821465046C8
+:1098700001F0B4F804000BD10598818841F400414F
+:10988000818005AA08A94846FFF7A6FF0400DCD09E
+:109890000097059802950195039504950188BDF8F8
+:1098A0001C300022504601F099F80A2C06D105AA76
+:1098B00006A94846FFF790FF0400ACD0ADF8185059
+:1098C00004E00598818821F40041818005AA06A959
+:1098D0004846FFF781FF0028F3D00A2C03D020462A
+:1098E0000AB0BDE8F0870020FAE710B50C46896B96
+:1098F00086B051B10C218DF80010A18FADF8081081
+:10990000A16B01916946FCF75EF900204FF6FF71EB
+:10991000A063E187A08706B010BD2DE9F0410D4698
+:109920000746896B0020069E1446002911D0012BA2
+:109930000FD1324629463846FFF762FF002808D18A
+:10994000002C06D0324629463846BDE8F04100F0EA
+:1099500038BFBDE8F0812DE9FC411446DDE9087C03
+:109960000E46DDE90A15521DBCF800E092B296459C
+:1099700002D20720BDE8FC81ACF8002017222A7033
+:10998000A5F80160A5F803300522CDE900423B4669
+:109990002A46FFF7DFFD0020ECE770B50C461546C0
+:1099A000482120460EF00CFB04F1080044F81C0F7F
+:1099B00000204FF6FF71E06161842084A5841720A8
+:1099C000E08494F82A0040F00A0084F82A0070BD70
+:1099D0004FF6FF720A800146032006F00FBF30B534
+:1099E00085B00C460546FFF780FFA18E284629B1B9
+:1099F00001218DF800106946FCF7E5F80020E062CF
+:109A00002063606305B030BDB0F8400070470000CF
+:109A10004C00002090F84620920703D4408808802C
+:109A20000020F3E70620F1E790F846209207EDD5F5
+:109A3000A0F84410EAE70146002009880A0700D58B
+:109A4000012011F0F00F01D040F00200CA0501D54D
+:109A500040F004008A0501D540F008004A0501D510
+:109A600040F010000905D1D540F02000CEE700B548
+:109A7000034690F84600C00701D0062000BDA3F8B9
+:109A800042101846FFF7D7FF10F03E0F05D093F8AD
+:109A9000460040F0040083F8460013F8460F40F0FB
+:109AA00001001870002000BD90F84620520700D534
+:109AB00011B1B0F84200A9E71720A7E710F8462F28
+:109AC00061F3C3020270A1E72DE9FF4F9BB00E00C6
+:109AD000DDE92B34DDE92978289D24D02878C107D9
+:109AE00003D000F03F00192801D9012100E0002136
+:109AF0002046FFF7D9FFB04215D32878410600F081
+:109B00003F010CD41E290CD0218811F47F6F0AD19B
+:109B10003A8842B1A1F57F42FF3A04D001E0122910
+:109B200001D1000602D504201FB0C5E5F9491D98F2
+:109B30004FF0000A08718DF818A08DF83CA00FAA0C
+:109B40000A60ADF81CA0ADF850A02978994601F044
+:109B50003F02701F5B1C04F1180C4FF0060E4FF013
+:109B6000040BCDF858C01F2A7ED2DFE802F07D7DBD
+:109B7000107D267DAC7DF47DF37DF27DF17DF47D5D
+:109B8000F07D7D7DEF7DEE7D7D7D7D7DED0094F82A
+:109B90004610B5F80100890701D5032E02D08DF8D3
+:109BA00018B022E34FF40061ADF85010608003213B
+:109BB0008DF83C10ADF84000D8E2052EEFD1B5F895
+:109BC00001002083ADF81C00B5F80310618308B1D3
+:109BD000884201D901207FE10020A07220814FF648
+:109BE000FF702084169801F0A0F8052089F8000085
+:109BF0000220029083460AAB1D9A16991B9801F029
+:109C000097F890BB9DF82E00012804D0022089F817
+:109C10000100102003E0012089F8010002200590D6
+:109C2000002203A90BA804F028FFE8BB9DF80C0054
+:109C3000059981423DD13A88801CA2EB0B018142FB
+:109C400037DB02990220CDE900010DF12A034A46D3
+:109C500041461B98FFF77EFC02980BF1020B801C1B
+:109C600080B217AA03A901E0A0E228E002900BA8A5
+:109C700004F003FF02999DF80C00CDE9000117AB39
+:109C80004A4641461B98FFF765FC9DF80C100AAB4D
+:109C90000BEB01001FFA80FB02981D9A084480B26A
+:109CA000029016991B9800E003E001F041F80028AB
+:109CB000B6D0BBF1020F02D0A7F800B053E20A20E1
+:109CC0008DF818004FE200210391072EFFF467AFD3
+:109CD000B5F801002083ADF81C00B5F803206283BD
+:109CE00000283FF477AF90423FF674AF0120A07296
+:109CF000B5F8050020810020A073E06900F052FD56
+:109D000078B9E16901208871E2694FF420519180AE
+:109D1000E1698872E06942F601010181E069002190
+:109D20008173F01F20841E9860620720608416985B
+:109D300000F0FBFF072089F800000120049002904A
+:109D40000020ADF82A0028E01DE2A3E13AE1EAE0B4
+:109D500016E2AEE086E049E00298012814D0E069FE
+:109D60008079012803D1BDF82800ADF80E000498D1
+:109D700003ABCDE900B04A4641461B98FFF7EAFB2A
+:109D80000498001D80B20490BDF82A00ADF80C00C4
+:109D9000ADF80E00059880B202900AAB1D9A169994
+:109DA0001B9800F0C5FF28B902983988001D05905E
+:109DB0008142D1D20298012881D0E06980790128BE
+:109DC00005D0BDF82810A1F57F40FF3803D1BDF8BC
+:109DD0002800ADF80E00049803ABCDE900B04A4668
+:109DE00041461B98FFF7B6FB0298BBE1072E02D055
+:109DF000152E7FF4D4AEB5F801102183ADF81C10F8
+:109E0000B5F80320628300293FF4E4AE91423FF6A7
+:109E1000E1AE0121A1724FF0000BA4F808B084F864
+:109E20000EB0052E07D0C0B2691DE26904F006FE2F
+:109E300000287FF444AF4FF6FF70208401A906AAE2
+:109E400014A8CDF800B081E885032878214600F0F9
+:109E50003F031D9A1B98FFF795FB8246208BADF8B8
+:109E60001C0080E10120032EC3D14021ADF8501029
+:109E7000B5F801102183ADF81C100AAAB8F1000F43
+:109E800000D00023CDE9020304921D98CDF8048090
+:109E9000009038880022401E83B21B9800F0C8FF53
+:109EA0008DF8180090BB0B2089F80000BDF8280041
+:109EB00037E04FF0010C052E9BD18020ADF850000B
+:109EC000B5F801102183B5F803002084ADF81C100B
+:109ED000B0F5007F03D907208DF8180085E140F424
+:109EE0007C4222840CA8B8F1000F00D00023CDE9F9
+:109EF0000330CDE9018C1D9800903888401E83B254
+:109F00001B9800F095FF8DF8180028B18328A8D180
+:109F10000220BDE04C0000200D2189F80010BDF8A2
+:109F20003000401C1EE1032E04D248067FF537AEF8
+:109F3000002017E1B5F80110ADF81C102878400694
+:109F400002D58DF83CE002E007208DF83C004FF090
+:109F500000080320CDE902081E9BCDF810801D9853
+:109F60000193A6F1030B00901FFA8BF342461B9856
+:109F700000F034FD8DF818008DF83C8029784906F2
+:109F80000DD52088C00506D5208BBDF81C10884251
+:109F900001D1C4F8248040468DF81880E2E083287F
+:109FA00001D14FF0020A4FF48070ADF85000BDF8B7
+:109FB0001C002083A4F820B01E98606203206084F7
+:109FC0001321CCE0052EFFF4EAADB5F80110ADF891
+:109FD0001C10A28F62B3A2F57F43FE3B28D008225B
+:109FE0008DF83C204FF0000B0523CDE9023BDDF856
+:109FF00078C0CDF810B01D9A80B2CDF804C040F4FE
+:10A0000000430092B5F803201B9800F0E7FC8DF8A0
+:10A010003CB04FF400718DF81800ADF85010832853
+:10A0200010D0F8B1A18FA1F57F40FE3807D0DCE059
+:10A030000B228DF83C204FF6FE72A287D2E7A4F8DF
+:10A040003CB0D2E000942B4631461E9A1B98FFF795
+:10A0500080FB8DF8180008B183284BD1BDF81C0097
+:10A06000208355E700942B4631461E9A1B98FFF734
+:10A0700070FB8DF81800E8BBE18FA06B0844811DD0
+:10A080008DE882034388828801881B98FFF763FC70
+:10A09000824668E095F80180022E70D15FEA0800E0
+:10A0A00002D0B8F1010F6AD109208DF83C0007A851
+:10A0B00000908DF840804346002221461B98FFF710
+:10A0C0002CFC8DF842004FF0000B8DF843B050B9D6
+:10A0D000B8F1010F12D0B8F1000F04D1A18FA1F592
+:10A0E0007F40FF380AD0A08F40B18DF83CB04FF4CC
+:10A0F000806000E037E0ADF850000DE00FA91B983C
+:10A10000FBF761FD82468DF83CB04FF48060ADF8FE
+:10A110005000BAF1020F06D0FC480068C07928B19F
+:10A120008DF8180027E0A4F8188044E0BAF1000F79
+:10A1300003D081208DF818003DE007A80090434629
+:10A14000012221461B98FFF7E8FB8DF818002146F5
+:10A150001B98FFF7CAFB9DF8180020B9192189F850
+:10A160000010012038809DF83C0020B10FA91B98F9
+:10A17000FBF729FD8246BAF1000F33D01BE018E04F
+:10A180008DF818E031E02078000712D5012E10D1AB
+:10A190000A208DF83C00E088ADF8400003201B99B0
+:10A1A00006F02CFB0820ADF85000C1E648067FF50C
+:10A1B000F6AC4FF0040A2088BDF850100843208008
+:10A1C000BDF8500080050BD5A18FA1F57F40FE386A
+:10A1D00006D11E98E06228982063A6864FF0030AF5
+:10A1E0005046A1E49DF8180078B1012089F80000DC
+:10A1F000297889F80110BDF81C10A9F802109DF803
+:10A20000181089F80410052038802088BDF85010F7
+:10A2100088432080E4E72DE9FF4F8846087895B011
+:10A22000012181404FF20900249C0140ADF820102B
+:10A230002088DDF88890A0F57F424FF0000AFF3AB1
+:10A2400006D039B1000705D5012019B0BDE8F08F5F
+:10A250000820FAE7239E4FF0000B0EA886F800B006
+:10A2600018995D460988ADF83410A8498DF81CB0DE
+:10A27000179A0A718DF838B0086098F80000012824
+:10A280003BD0022809D003286FD1307820F03F005E
+:10A290001D303070B8F80400E08098F800100320FA
+:10A2A000022904D1317821F03F011B31317094F83B
+:10A2B0004610090759D505ABB9F1000F13D000219D
+:10A2C00002AA82E80B000720CDE90009BDF834009E
+:10A2D000B8F80410C01E83B20022159800F0A8FD43
+:10A2E0000028D1D101E0F11CEAE7B8F80400A6F893
+:10A2F0000100BDF81400C01C04E198F805108DF8A9
+:10A300001C1098F80400012806D04FF4007A0228A7
+:10A310002CD00328B8D16CE12188B8F8080011F4DA
+:10A320000061ADF8201020D017281CD3B4F84010DD
+:10A33000814218D3B4F84410172901D3814212D1B5
+:10A34000317821F03F01C91C3170A6F801000321CA
+:10A35000ADF83410A4F8440094F8460020F0020050
+:10A3600084F8460065E105257EE177E1208808F163
+:10A37000080700F4FE60ADF8200010F0F00F1BD0CD
+:10A3800010F0C00F03D03888228B9042EBD199B9DE
+:10A39000B878C00710D0B9680720CDE902B1CDF870
+:10A3A00004B00090CDF810B0FB88BA8839881598B1
+:10A3B00000F014FB0028D6D12398BDF82010401CD3
+:10A3C00080294ED006DC10290DD020290BD0402941
+:10A3D00087D124E0B1F5807F6ED051457ED0B1F5B4
+:10A3E000806F97D1DEE0C80601D5082000E010207C
+:10A3F00082460DA907AA0520CDE902218DF8380073
+:10A40000ADF83CB0CDE9049608A93888CDE9000143
+:10A410005346072221461598FFF7B4F8A8E09DF8A7
+:10A420001C2001214FF00A0A002A9BD105ABB9F18B
+:10A43000000F00D00020CDE902100720CDE900096F
+:10A44000BDF834000493401E83B2218B002215987E
+:10A4500000F0EEFC8DF81C000B203070BDF81400ED
+:10A4600020E09DF81C2001214FF00C0A002A22D187
+:10A4700013ABB9F1000F00D00020CDE90210072086
+:10A48000CDE900090493BDF83400228C401E83B24C
+:10A49000218B159800F0CCFC8DF81C000D2030703D
+:10A4A000BDF84C00401CADF8340005208DF8380094
+:10A4B000208BADF83C00BCE03888218B88427FF4CB
+:10A4C00052AF9DF81C004FF0120A00281CD1606AA0
+:10A4D000A8B1B878C0073FF446AF00E018E0BA680A
+:10A4E0000720CDE902B2CDF804B00090CDF810B04D
+:10A4F000FB88BA88159800F071FA8DF81C001320BB
+:10A5000030700120ADF8340093E000004C000020D2
+:10A510003988208B8142D2D19DF81C004FF0160A59
+:10A520000028A06B08D0E0B34FF6FF7000215F4613
+:10A53000ADF808B0019027E068B1B978C907BED17D
+:10A54000E18F0DAB0844821D03968DE80C02438811
+:10A550008288018809E0B878C007BCD0BA680DAB22
+:10A5600003968DE80C02BB88FA881598FFF7F3F97B
+:10A5700005005ED0072D72D076E0019005AA02A9F1
+:10A580002046FFF729F90146E28FBDF80800824214
+:10A5900001D00029F1D0E08FA16B08440780019819
+:10A5A000E08746E09DF81C004FF0180A40B1208B70
+:10A5B000C8B13888208321461598FFF796F938E00E
+:10A5C00004F118000090237E012221461598FFF720
+:10A5D000A4F98DF81C000028EDD11920307001205D
+:10A5E000ADF83400E7E7052521461598FFF77DF91A
+:10A5F0003AE0208800F40070ADF8200050452DD1DD
+:10A60000A08FA0F57F41FE3901D006252CE0D8F8B7
+:10A6100008004FF0160A48B1A063B8F80C10A187E3
+:10A620004FF6FF71E187A0F800B002E04FF6FF702F
+:10A63000A087BDF8200030F47F611AD07823002273
+:10A640000320159906F030F898F800002071208852
+:10A65000BDF82010084320800EE000E00725208888
+:10A66000BDF8201088432080208810F47F6F1CD014
+:10A670003AE02188814321809DF8380020B10EA95D
+:10A680001598FBF7A0FA05469DF81C000028EBD0B2
+:10A6900086F801A001203070208B70809DF81C008E
+:10A6A00030710520ADF83400DEE7A18EE1B11898D5
+:10A6B0000DAB0088ADF834002398CDE90304CDE953
+:10A6C0000139206B0090E36A179A1598FFF7FCF99F
+:10A6D000054601208DF838000EA91598FBF773FA8E
+:10A6E00000B10546A4F834B094F8460040070AD5F6
+:10A6F0002046FFF7A0F910F03E0F04D114F8460FE2
+:10A7000020F0040020701898BDF83410018028460D
+:10A710009BE500B585B0032806D102208DF8000026
+:10A7200088B26946FBF74FFA05B000BD10B5384C4A
+:10A730000B782268012B02D0022B2AD111E013786A
+:10A740000BB1052B01D10423137023688A889A80EA
+:10A750002268CB88D38022680B8913814989518173
+:10A760000DE08B8893802268CB88D38022680B8988
+:10A7700013814B8953818B89938109691161216808
+:10A78000FBF721FA226800210228117003D000286B
+:10A7900000D0812010BD832010BD806B002800D028
+:10A7A000012070478178012909D10088B0F5205F28
+:10A7B00003D042F60101884201D1002070470720F2
+:10A7C0007047F0B587B0002415460E460746ADF831
+:10A7D000144010E0069801882980811DCDE90241CE
+:10A7E00007210194049400918388428801883846A7
+:10A7F00000F0F4F830B906AA05A93046FEF7ECFFE0
+:10A800000028E7D00A2800D1002007B0F0BD0000E2
+:10A810004C00002010B58B7883B102789A4205D1A4
+:10A820000B885BB102E08B79091D4BB18B789A42A2
+:10A83000F9D1B0F801300C88A342F4D1002010BD4A
+:10A84000812010BD072826D012B1012A27D103E0AC
+:10A85000497801F0070102E04978C1F3C2010529F6
+:10A860001DD2DFE801F00318080C12000AB1032022
+:10A8700070470220704704280DD250B10DE0052822
+:10A8800009D2801E022808D303E0062803D003283B
+:10A8900003D005207047002070470F2070478120AB
+:10A8A0007047C0B282060BD4000607D5FE48807AF6
+:10A8B0004143C01D01EBD00080B27047084670478D
+:10A8C0000020704770B513880B800B781C0625D5C7
+:10A8D000F54CA47A844204D843F01000087000209C
+:10A8E00070BD956800F0070605EBD0052D78F540A2
+:10A8F00065F304130B701378D17803F0030341EA76
+:10A90000032140F20123B1FBF3F503FB151192681B
+:10A91000E41D00FB012000EBD40070BD906870BD09
+:10A9200037B51446BDF8041011809DF804100A06CE
+:10A930001ED5C1F30013DC49A568897A814208D885
+:10A94000FE2811D1C91DC9085A4228460DF00EFB38
+:10A950000AE005EBD00100F00702012508789540D8
+:10A96000A843934018430870207820F0100020700E
+:10A970003EBD2DE9F0410746C81C0E4620F00300FD
+:10A98000B04202D08620BDE8F081C74D0020344699
+:10A990002E60AF802881AA72E8801AE0E988491CFD
+:10A9A000E980810614D4E17800F0030041EA002038
+:10A9B00040F20121B0FBF1F201FB12012068FFF728
+:10A9C00070FF2989084480B22881381A3044A06079
+:10A9D0000C3420784107E1D40020D4E72DE9FF4F63
+:10A9E00089B01646DDE9168A0F46994623F440459C
+:10A9F000084600F00DFB04000FD0099802F066FA3B
+:10AA00000290207800060AD5A748817A02988142F0
+:10AA100005D887200DB0BDE8F08F0120FAE7224667
+:10AA200001A90298FFF74EFF834600208DF80C0025
+:10AA30004046B8F1070F1AD001222146FFF702FF66
+:10AA40000028E7D12078400611D502208DF80C00AF
+:10AA5000ADF81070BDF80400ADF81200ADF8146048
+:10AA60001898ADF81650CDF81CA0ADF818005FEAA4
+:10AA7000094004D500252E46A84601270CE0217880
+:10AA8000E07801F0030140EA012040F20121B0FB2F
+:10AA9000F1F2804601FB12875FEA494009D5B845CB
+:10AAA00007D1A178207901F0030140EA0120B042EA
+:10AAB00001D3BE4201D90720ACE7A8191FFA80F9DB
+:10AAC000B94501D90D20A5E79DF80C0028B103A9CF
+:10AAD0000998FBF776F800289CD1B84507D1A078F3
+:10AAE0004FEA192161F30100A07084F804901A98CC
+:10AAF00000B10580199850EA0A0027D0199830B1A2
+:10AB00000BEB06002A4619990DF0B9F90EE00BEB94
+:10AB100006085746189E099802F040FB2B46F61D82
+:10AB2000B5B239464246009501F049FF224601A9D7
+:10AB30000298FFF7C7FE9DF80400224620F010009F
+:10AB40008DF80400DDE90110FFF7EAFE002061E75F
+:10AB50002DE9FF4FDFF8509182461746B9F80610ED
+:10AB6000D9F8000001EB410100EB810440F2012023
+:10AB7000B2FBF0F185B000FB11764D46DDF84C805C
+:10AB800031460698FFF78DFE29682A898B46611A9F
+:10AB90000C3101441144AB8889B28B4202D8842025
+:10ABA00009B038E70699CDB2290603D5A90601D523
+:10ABB0000620F5E7B9F806C00CF1010C1FFA8CFC71
+:10ABC000A9F806C0149909B1A1F800C0A90602D5D8
+:10ABD000C4F8088007E0104480B2A9F80800191AE8
+:10ABE00001EB0B00A0602246FE200699FFF798FEBD
+:10ABF000E77026712078390A61F30100320AA178E2
+:10AC000040F0040062F30101A17020709AF8020084
+:10AC10006071BAF80000E08000262673280602D58D
+:10AC200099F80A7000E00127A80601D54FF0000846
+:10AC30004D4600244FF007090FE0CDE90268019668
+:10AC4000CDF800900496E9882046129B089AFFF7F9
+:10AC5000C5FE0028A4D1641CE4B2BC42EDD30020A0
+:10AC60009EE72DE9F047804600F0D2F9070005D0B5
+:10AC7000002644460C4D40F2012919E00120BDE8B0
+:10AC8000F087204600F0C4F90278C17802F0030290
+:10AC900041EA0222B2FBF9F309FB13210068FFF736
+:10ACA00000FE304486B201E0A8040020641CA4B277
+:10ACB000E988601E8142E4DCA8F10100E88028896F
+:10ACC000801B288100203870D9E710B5144631B1B7
+:10ACD000491E218002F0FAF8A070002010BD01206A
+:10ACE00010BD10B5D24904460088CA88904201D3ED
+:10ACF0000A2010BD096800EB400001EB800250798A
+:10AD0000A072D08820819178107901F0030140EA87
+:10AD10000120A081A078E11CFFF7D4FD20612088EC
+:10AD2000401C2080E080002010BD0121018270477E
+:10AD30002DE9FF4F85B04FF6FF788246A3F80080DB
+:10AD400048681F460D4680788DF8060048680088E0
+:10AD5000ADF8040000208DF80A00088A0C88A04293
+:10AD600000D304462C8241E0288A401C2882701DB2
+:10AD70006968FFF74FFDB8BB3988414501D1601EB6
+:10AD800038806888A04236D3B178307901F0030169
+:10AD900040EA012901A9701DFFF73CFD20BB29896C
+:10ADA00041452CD0002231460798FFF74BFDD8B91A
+:10ADB0002989494518D1E9680391B5F80AC0D6F840
+:10ADC00008B05046CDF800C002F0E8F9DDF800C048
+:10ADD0005A460CF1070C1FFA8CFC4B460399CDF830
+:10ADE00000C001F0B6FD50B1641CA4B2204600F0D2
+:10ADF0000FF90600B8D1641E2C820A20D0E67C80B0
+:10AE00007079B871F088B8803178F07801F003017A
+:10AE100040EA01207881A7F80C90504602F056F8DD
+:10AE2000324607F10801FFF74DFD38610020B7E613
+:10AE30002DE9FF4F87B081461C469246DDF860B091
+:10AE4000DDF85480089800F0E3F805000CD048467F
+:10AE500002F03CF82978090608D57549897A8142BB
+:10AE600004D887200BB0D6E50120FBE7CAF309061A
+:10AE70002A4601A9FFF726FD0746149807281CD08B
+:10AE800000222946FFF7DEFC0028EBD12878400697
+:10AE900013D501208DF808000898ADF80C00BDF816
+:10AEA0000400ADF80E00ADF81060ADF8124002A934
+:10AEB0004846FAF786FE0028D4D12978E87801F0D0
+:10AEC000030140EA0121AA78287902F0030240EA4E
+:10AED0000220564507D0B1F5007F04D9611E81429A
+:10AEE00001DD0B20BEE7864201D90720BAE7801BAF
+:10AEF00085B2A54200D92546BBF1000F01D0ABF8C1
+:10AF00000050179818B1B9192A460CF0B8FFB8F1DB
+:10AF1000000F0DD03E4448464446169F02F050F9BB
+:10AF20002146FF1DBCB232462B46009401F07BFD4A
+:10AF3000002097E72DE9F04107461D4616460846D2
+:10AF400000F066F804000BD0384601F0BFFF21780E
+:10AF5000090607D53649897A814203D8872012E548
+:10AF6000012010E522463146FFF7ACFC65B121789F
+:10AF7000E07801F0030140EA0120B0F5007F01D83C
+:10AF8000012000E0002028700020FCE42DE9F041C1
+:10AF900007461D461646084600F03AF804000BD056
+:10AFA000384601F093FF2178090607D52049897AB0
+:10AFB000814203D88720E6E40120E4E422463146BA
+:10AFC000FFF7AEFCFF2D14D02178E07801F00302EA
+:10AFD00040EA022040F20122B0FBF2F302FB130030
+:10AFE00015B900F2012080B2E070000A60F301019F
+:10AFF00021700020C7E410B50C4600F009F828B114
+:10B00000C18821804079A070002010BD012010BDB2
+:10B010000749CA88824209D340B1096800EB400061
+:10B020006FF00B0202EB800008447047002070476D
+:10B03000A804002070B514460B880122A2401342D8
+:10B0400007D113430B8001230922011D01F019FED2
+:10B05000047070BD2DE9FF4F81B00878DDE90E7BEB
+:10B060009A4691460E4640072CD4019802F0A8F863
+:10B07000040000D1FFDF07F1040820461FFA88F121
+:10B0800001F005FA050000D1FFDF204629466A4697
+:10B0900001F04FFC0098A0F80370A0F805A0284626
+:10B0A00001F0F5FC017869F306016BF3C71101703B
+:10B0B00020461FFA88F101F02DFA00B9FFDF019850
+:10B0C00000F048FB06EB0900017E491C017605B043
+:10B0D000BDE8F08F2DE9F84F0E469A469146074697
+:10B0E000032101F029FF0446808CDFF888850025C4
+:10B0F00018B198F80000B0421ED1384602F060F84E
+:10B10000070000D1FFDF09F10401384689B201F0E0
+:10B11000BEF9050010D0384629466A4601F009FC00
+:10B12000009800210A460180817000F07DFB0098A4
+:10B13000C01DCAF8000021E098F80000B04216D106
+:10B1400004F1220734F8301F012000FA06F911EA51
+:10B15000090F00D0FFDF2088012340EA090020808A
+:10B160000922391D384601F0A7FD067006E0324677
+:10B1700004F1300104F12200FFF75CFF092188F897
+:10B1800000102846BDE8F88FFEB514460D46064669
+:10B1900002AB0C220621FFF79DFF002826D0029962
+:10B1A000687812220A70801C487008224A80A870B1
+:10B1B000208888806088C880A0880881E0884881CD
+:10B1C00000240C20CDE90004052306222946304640
+:10B1D000FFF740FF2146002266F31F41F02310468F
+:10B1E00005F062FA6878801C68700120FEBD10B519
+:10B1F0000446032101F0A0FE014600F110022046A2
+:10B20000BDE81040C0E72DE9FE4381465078164660
+:10B21000884640B1FFDF3168C8F804107168C8F88B
+:10B220000810BDE8FE83B778022417B1022F13D0AF
+:10B23000FFDF251D2A4602AB07214846FFF74AFFDC
+:10B240000028E8D002980121022F01703178417066
+:10B250004480878002D005E00624EAE7B188C180F7
+:10B26000F18801810024CDE90054052307224146DD
+:10B270004846FFF7EFFE88F80440D2E710B50446D1
+:10B28000032101F059FE0146021D2046BDE8104091
+:10B29000B9E7F84A002009211170704770B50C46D3
+:10B2A0001546342120460CF08BFE012060700921E8
+:10B2B00004F118000CF084FE05B9FFDF297820782E
+:10B2C00061F30100207070BD7047002110B560F37C
+:10B2D0001F41002005F092FA002010BDFEB5064681
+:10B2E0000F0CFCF777FD050007D06F80032138466F
+:10B2F00001F022FE040008D106E003B03846BDE8A4
+:10B30000F0401321F7F752B9FFDF0EB1FFDFFEBDAA
+:10B3100020782A4620F00800207002208DF80000D6
+:10B320004FF6FF70ADF80200ADF8040069463846EC
+:10B33000F6F796FDFEBD00B5FFDF002000BD2DE94C
+:10B34000FC410C461E4617468046032101F0F4FDE1
+:10B350000546092C0AD2DFE804F0050505050505B8
+:10B3600009090700042303E0062301E0FFDF0023AF
+:10B37000CDE90076224629464046FFF76BFEBDE840
+:10B38000FC8138B50546A0F57F40FF381CD0284623
+:10B3900001F004FF040000D1FFDF204601F0A7FA0E
+:10B3A000002810D001466A46204601F0C2FA0098F3
+:10B3B0000321B0F80540284601F0BEFD052C03D15D
+:10B3C000007908B1002038BD012038BD2DE9F041D9
+:10B3D000044686B0408801F0E1FE050000D1FFDFA1
+:10B3E00003AA2846616800F034F9039D001F80B26B
+:10B3F00035F8032F698882420AD104290BD0052928
+:10B4000018D0062904D16088291D6368F8F750F91F
+:10B4100006B0BDE8F08116462D1D2246294630466D
+:10B42000F9F7D7FE0828F3D1224629463046FAF725
+:10B43000EEFEEDE716466088032101F07DFD002158
+:10B440008DF80010042EE3D36A79002AE0D02B791E
+:10B4500002274FF6FF78012B28D0122B01D0132B97
+:10B460000BD00491059169798DF81010638801461D
+:10B4700004AA1846FFF7C7FECAE783789342C7D1EC
+:10B4800002781307C4D5062EC2D122F0080202703A
+:10B49000608860F31F41002005F0B0F98DF800705E
+:10B4A000ADF802802889ADF8040017E0062EAFD36E
+:10B4B00083789342ACD102781307A9D522F0080211
+:10B4C0000270608860F31F41002005F097F98DF845
+:10B4D00000702889ADF80200ADF80480608822462B
+:10B4E0006946F6F7BDFC93E770B50D4606460321A5
+:10B4F00001F022FD040004D02078000704D51120BB
+:10B5000070BD43F2020070BD2A4621463046FFF767
+:10B510003BFE18B92868206168686061207840F0B7
+:10B5200008002070002070BD2DE9F04F0E4691B04C
+:10B530008046032101F000FD0446404601F040FE34
+:10B5400007460020079008900990ADF830000A9057
+:10B5500002900390049004B9FFDF0DF10809FFB9D0
+:10B56000FFDF1DE038460BA9002201F083F89DF8AB
+:10B570002C0000F07F05092D00D3FFDF6019017E4C
+:10B58000491E01769DF82C00000609D52A460CA913
+:10B5900007A8FFF74FFD19F80510491C09F8051019
+:10B5A000761EF6B2DED204F13000324D04F1220BE9
+:10B5B000DFF8C4A004F12607069010E0584606996B
+:10B5C00000F049F806462870092800D3FFDF5AF832
+:10B5D000261040468847608CC05DB04202D0A08CE7
+:10B5E0000028EBD109202870234D4E4624350EE06B
+:10B5F0000CA907A800F02FF80446375D55F8240081
+:10B6000000B9FFDF55F82420394640469047BDF881
+:10B610001E000028ECD111B05AE510B5032101F04D
+:10B620008BFC040000D1FFDF092104F118000CF0AD
+:10B63000C7FC207840F00400207010BD10B50C4607
+:10B64000032101F079FC2044007E002800D0012075
+:10B6500010BD01F06EB910B50C4601230922011D81
+:10B6600001F045FB0078218801228240914321802E
+:10B6700010BD000054000020748301002DE9FC4738
+:10B680000C460646694600F006FE002860D106F02A
+:10B6900009FAB0425CD02146304609F0C4F828BB14
+:10B6A000019D95F8EC00383518B9E87E08B1012005
+:10B6B00000E00020814695F837004FF000084FF079
+:10B6C000010AA0B195F83800800710D584F80180F0
+:10B6D00084F800A084F80280A68095F83910A17142
+:10B6E000698F2181A98F618185F837802DE03046EF
+:10B6F00001F066FD070000D1FFDF384600F094FF3F
+:10B7000040B184F801800D212170A680E08084F88A
+:10B7100002A01AE0304601F041FD070000D1FFDF32
+:10B72000B9F1000F14D0384600F0D5FF80B1304693
+:10B7300006F05DF884F801800A21217084F8028007
+:10B74000A680297FA17185F81B800120BDE8FC87B8
+:10B750000020FBE71CB5694600F09DFD00B1FFDF4E
+:10B76000684600F0A5FDFC4900208968A1F8B200F8
+:10B770001CBD2DE9FC4104460E46062001F088FB65
+:10B7800000250746A846064417E02088401C80B2E2
+:10B790002080B04202D34046A4F8008080B2B84274
+:10B7A00004D3B04202D20020BDE8FC81694600F01B
+:10B7B00072FD0028F8D06D1CEDB2AE42E5D84FF610
+:10B7C000FF7020801220EFE710B506F081F80AF034
+:10B7D000A0FBE2484FF6FF710422418181810021E4
+:10B7E000017003218170C2701B228280C28001819E
+:10B7F00010BD70B5D84C0D466060217005F0F5FFA6
+:10B8000000F066FDFFF7E0FF207809F057FE2846BC
+:10B8100007F092FC06F082F92178606809F0C5F81B
+:10B82000BDE870400AF075BB10B501240AB10020D4
+:10B8300010BD21B1012903D00024204610BD0221F2
+:10B840000BF0D7F8F9E72DE9F041040000D1FFDF54
+:10B85000C24802210C308046FFF78BFF00B1FFDFAA
+:10B86000BE4D0620AF8901F013FB0646A889B04201
+:10B870001CD1204606F0BBF8F8B106F051FBC8B168
+:10B880002078132816D1A078A0B1A088062101F055
+:10B8900053FB050000D1FFDF288805F0A8FFA08832
+:10B8A000062101F05BFB28B1FFDF03E02146FFF733
+:10B8B000E5FE10B10120BDE8F08102214046FFF70E
+:10B8C00058FF10B9A889B842D0D10020F3E710B5CD
+:10B8D00000F0C2FC08B10C2010BD0AF053FB0020A0
+:10B8E00010BD10B50446007818B1012801D012200F
+:10B8F00010BD00F0BCFC20B10AF0A1FB08B10C2087
+:10B9000010BD207800F092FCE21D04F11703611CC9
+:10B91000BDE810400AF04ABB10B50446007818B1E3
+:10B92000012801D0122010BD00F096FC08B10C20B7
+:10B9300010BD207800F07AFC611C0AF0FDFA08B115
+:10B94000002010BD072010BD10B50AF07CFB08B127
+:10B95000002010BD302010BD10B5044600F087FC5B
+:10B9600008B10C2010BD20460AF065FB002010BD78
+:10B9700010B500F07CFC20B10AF061FB08B10C208E
+:10B9800010BD0AF04AFB002010BDFF2181704FF668
+:10B99000FF718180704949680A7882718A880281C2
+:10B9A0004988418101214170002070471CB5002465
+:10B9B00012F1080F15D00CDC12F1280F11D012F182
+:10B9C000140F0ED012F1100F0BD012F10C0F0CD17E
+:10B9D00007E012F1040F04D01AB1032A01D0042A9F
+:10B9E00003D1012804D0032806D0122420461CBD10
+:10B9F000104606F090FAF9E708461446694600F04A
+:10BA00004AFC08B10224F1E7019880F8374000248D
+:10BA1000ECE710B5134601220AF047FD002010BDE7
+:10BA200010B5044600F023FC08B10C2010BD2146DF
+:10BA3000002005F04EFF002010BD10B5044607F0B1
+:10BA4000B3FD20B1207807F09DFB002010BD0C2035
+:10BA500010BD10B5044600F00AFC08B10C2010BD62
+:10BA60002146012005F035FF002010BD38B5044601
+:10BA70004FF6FF70ADF80000A079E179884213D04D
+:10BA800021791F2910D861791F290DD8002211466C
+:10BA90000BF0DCFB40B90022E07911460BF0D6FB3D
+:10BAA00010B9207A072801D9122038BD07F088FD87
+:10BAB00048B900216846FFF75CFE20B1204605F03A
+:10BAC000E1F8002038BD0C2038BD2DE9FC4181781B
+:10BAD00004461A2925D00EDC16292DD2DFE801F004
+:10BAE0002C2C2C2C2C212C2C2C2C2C2C2C2C2C2CA1
+:10BAF0002C2C2C2121212A291ED00BDCA1F11E0186
+:10BB00000C2919D2DFE801F018181818181818189D
+:10BB10001818180D3A3904290ED2DFE801F00D0289
+:10BB20000D022088B0F5706F06D20127694600F03B
+:10BB3000B2FB18B1022037E6122035E6019D6846B7
+:10BB40002E4605F5A87506F2511600F097FB08B1D0
+:10BB5000287828B10C2027E658000020B4040020E3
+:10BB60002F70A0783070684600F0A2FB00201BE622
+:10BB70001CB50C46694600F08EFB002118B121600F
+:10BB8000217102201CBD01980246383080F8401017
+:10BB900093682360137B237190F84030002BF5D11C
+:10BBA00000201CBD10B5044600F061FB20B10AF076
+:10BBB00046FA08B10C2010BD207800F037FBE2797E
+:10BBC000611C0AF018FB08B1002010BD022010BD56
+:10BBD000887800B90320C97801B903211070197061
+:10BBE000002070471FB50446008801A900F053FBF0
+:10BBF000002806D1A08830B1012804D0022802D044
+:10BC0000122004B010BD6B4603AA214601A8FFF71D
+:10BC1000DFFF0028F5D1029A012182F87B11029AF8
+:10BC200092F8AE213AB9029A92F87A211AB9029A98
+:10BC300092F85D200AB13A200CE0029A82F87A115B
+:10BC4000029A9DF80C1082F87C11029A9DF800105F
+:10BC500082F87D11029A002182F87B11D1E7817868
+:10BC6000CA0802D1C278D30801D012207047490710
+:10BC700001D4510701D511207047B3E7F0B5871FF4
+:10BC8000DDE9056540F67B44A74213D28F1FA7422A
+:10BC900010D288420ED8B2F5FA7F0BD2A3F10A0077
+:10BCA000241FA04206D2521C4A43B2EB830F01DA92
+:10BCB000AE4201D90020F0BD0120F0BD1CB5828943
+:10BCC0004189CDE900120389C28881884088FFF745
+:10BCD000D5FF08B100201CBD30201CBDF8B51546AD
+:10BCE0000E46044607F06CFC08B10C20F8BD204657
+:10BCF00000F002FB0028F9D161884FF01100CA065C
+:10BD0000F4D5E27D032AF1D04906EFD4002030704B
+:10BD1000A07555B9FF208DF800006946002006F097
+:10BD2000E6F86946002006F0CCF82046BDE8F84069
+:10BD300006F00FB80022D1E770B514460D4606464E
+:10BD4000FB2919D813B11F2916D81BE006F001F9F9
+:10BD500020B11F2D10D8032C0ED104E0032C02D0EB
+:10BD6000042C00D045B107F02BFC38B1032C05D0D2
+:10BD7000042C03D00C2070BD122070BD304605F09D
+:10BD8000DBFE08B1002070BD422070BD70B50446D6
+:10BD9000C0780E46122510B106F03FF818B1607851
+:10BDA000042802D010E0284670BD07F009FC0028E6
+:10BDB000F9D006F07DF80028F5D106F0CAF8002881
+:10BDC000F1D1E0780028EED16278E178207833462E
+:10BDD000FFF7B2FF0028E7D16178E07800F0D7FAEA
+:10BDE00028B1E078211D06F082F8002070BD1120F6
+:10BDF00070BD0021CAE770B50446C0780D46122612
+:10BE000010B106F094F8A0B16278042A11D0E1785C
+:10BE100020782B46FFF790FF002809D16178E07861
+:10BE200000F0B5FA38B1E078211D06F04AF800209C
+:10BE300070BD304670BD112070BD0021DBE77CB5C0
+:10BE4000044640784225012808D8A07805F074FE01
+:10BE500020B120781225012802D090B128467CBD5F
+:10BE600006F06EF820B1A0880028F7D08028F5D819
+:10BE700006F06DF860B160780028EFD020780128D6
+:10BE800008D006F047FD044607F01FF9002865D0EA
+:10BE90000C207CBD05F091FE10B906F04FF868B398
+:10BEA00007F08EFB0028F3D105F0FCFDA0F57F41E3
+:10BEB000FF39EDD105F002FFA68842F2107046432B
+:10BEC000A079314605F0B3FF06F02AF8C0B1002290
+:10BED000062101A801F002F8040018D0FA48032155
+:10BEE000846020460AF035FA204606F0D3F906F0C1
+:10BEF00030F8F64D68B1288901210EE012207CBD92
+:10BF00003146002007F041F938B3FFDF30E0092067
+:10BF10007CBD06F020F80146288907F0FAF90146B1
+:10BF2000A0620022204606F01CFD06F012F808B9B7
+:10BF300006F011F8E8780090AB78EA88A9882088A4
+:10BF400001F0B5F800B1FFDF208805F04FFC314665
+:10BF5000204607F01AF900B1FFDF09E044B120885C
+:10BF600005F045FC2088062100F0F8FF00B1FFDF56
+:10BF700000207CBD002162E770B50D46062100F06F
+:10BF8000DBFF040003D094F8530110B10AE0022053
+:10BF900070BD94F84500142801D0152802D194F8FA
+:10BFA000940108B10C2070BD1022294604F5AA7036
+:10BFB0000BF065FF012084F85301002070BD10B51F
+:10BFC000062100F0B9FF18B190F8531111B107E044
+:10BFD000022010BD90F84510142903D0152901D076
+:10BFE0000C2010BD022180F85311002010BD2DE956
+:10BFF000FC410D464BF680321221954213D895B183
+:10C00000694600F048F900280CD1019EB41C38366E
+:10C0100027882A46394630460AF091F92088B842E6
+:10C02000F6D1002087E5084685E51CB50446008862
+:10C03000694600F030F9002808D10199A378084634
+:10C0400091F82C2038319A4201D10C201CBD7F225E
+:10C050000A728A720022CA72E17880F82D10217962
+:10C0600080F82E10A17880F82C1010461CBD1CB54D
+:10C070000C46694600F00FF9002806D1019890F8A7
+:10C08000530000B10120207000201CBD7CB50D467E
+:10C090001446694600F0FFF8002805D1019890F891
+:10C0A0002C00012801D00C207CBD019890F8401094
+:10C0B000297090F84100207000207CBD70B50D46BD
+:10C0C0001646062100F038FF18B381880124C38882
+:10C0D000428804EB4104AC4217D842F21074634327
+:10C0E000A4106243B3FBF2F2521E94B24FF4FA7200
+:10C0F000944200D91446A54200D22C46491C641C27
+:10C10000B4FBF1F24A43521E91B290F880211AB961
+:10C1100001E0022070BD01843180002070BD10B5A7
+:10C120000C46062100F008FF48B180F8BF4024B15A
+:10C1300090F8BD1009B107F011F9002010BD0220E0
+:10C1400010BD017891B1417881B141881B290DD38F
+:10C1500081881B290AD3C188022907D35B49026859
+:10C1600041F8022F40684860002070471220704755
+:10C1700010B507F09CF8002010BD70B514460A46B3
+:10C18000064600250121104607F0C3F8002800D814
+:10C19000284605460121304600F04FF806460121A9
+:10C1A000002000F04AF83118012296318D4206D95C
+:10C1B00001F19600691AB1FBF0F0401C82B22280B6
+:10C1C000002070BD10B5044600F051F808B10C20F5
+:10C1D00010BD601C09F0FCFF207800F0010005F0A4
+:10C1E00006FD002010BD10B50446062000F042FEFA
+:10C1F00008B10C2010BD2078C00711D00022607853
+:10C2000011460BF023F808B1122010BDA06808F009
+:10C2100020FF6078D4F8041008F024FF002010BD3F
+:10C22000002008F016FF00210846F5E718B10228A3
+:10C2300001D0012070470020704710B5012904D0BB
+:10C24000022905D0FFDF204610BDC000503001E0BC
+:10C2500080002C3084B2F6E710B507F0B1F920B1B8
+:10C2600005F0A3FC08B1012010BD002010BD10B5E1
+:10C2700007F0A6F9002800D0012010BD416891F810
+:10C28000EC0091F8531021B918B1042801D0012015
+:10C2900070470020704710B50C46062100F04CFE98
+:10C2A000606018B101202070002010BD022010BD78
+:10C2B000416891F8BD20002A05D0002281F8BD20F8
+:10C2C000406807F04BB8704758000020B4040020C5
+:10C2D00008B54FF6FF70ADF8000006E00621BDF886
+:10C2E000000000F03BFE00B1FFDF00216846FFF7D1
+:10C2F00040FA0028F2D008BD38B504460078EF288F
+:10C3000041D86088ADF80000009800F048F888B384
+:10C310006188080708D4D4E90120824233D8202A52
+:10C3200031D3B0F1807F2ED2207B18B307282AD8D2
+:10C33000607B28B1012803D0022801D0032822D134
+:10C340004A0703D4022801D0032805D1A07B08B1F5
+:10C35000012818D1480707D4607D28B1012803D0EF
+:10C36000022801D003280ED1C806E07D03D501289C
+:10C3700009D104E007E0012801D0032803D1E07EC1
+:10C3800018B1012801D0122038BD002038BD1F2867
+:10C3900001D8032901D0002095E7012093E780B25E
+:10C3A000C1060CD401071AD481064FEAC07103D527
+:10C3B000A9B9800713D410E079B180070BE0C10759
+:10C3C0004FEA807104D0002902DB400705D406E063
+:10C3D000010704D44007002801DB012073E7002097
+:10C3E00071E7000030B5058825F4004421448CB283
+:10C3F0004FF4004194420AD2121B92B21B339A426C
+:10C4000001D2A94307E005F40041214303E0A21A49
+:10C4100092B2A9431143018030BD08440830504313
+:10C420004A31084480B2704770B51D4616460B4627
+:10C43000044629463046049AFFF7EFFF0646B3420A
+:10C4400000D2FFDF282120460BF0BAFD4FF6FF7027
+:10C45000A082283EB0B265776080B0F5004F00D969
+:10C46000FFDF618805F13C00814200D2FFDF608878
+:10C470000835401B343880B220801B2800D21B2096
+:10C4800020800020A07770BD8161886170472DE910
+:10C49000F05F0D46C188044600F12809008921F4A7
+:10C4A000004620F4004800F062FB10B10020BDE817
+:10C4B000F09F4FF0000A4FF0010BB0450CD9617F9F
+:10C4C000A8EB0600401A0838854219DC09EB060083
+:10C4D0000021058041801AE06088617F801B471A37
+:10C4E000083F0DD41B2F00DAFFDFBD4201DC2946D7
+:10C4F00000E0B9B2681A0204120C04D0424502DD11
+:10C5000084F817A0D2E709EB06000180428084F886
+:10C5100017B0CCE770B5044600F12802C088E37D6F
+:10C5200020F400402BB110440288438813448B420E
+:10C5300001D2002070BD00258A4202D301804580CF
+:10C5400008E0891A0904090C418003D0A01D00F0FD
+:10C550001EFB08E0637F00880833184481B26288BC
+:10C56000A01DFFF73FFFE575012070BD70B50346C4
+:10C5700000F12804C588808820F400462644A8429B
+:10C5800002D10020188270BD98893588A84206D350
+:10C59000401B75882D1A2044ADB2C01E05E02C1A30
+:10C5A000A5B25C7F20443044401D0C88AC4200D9C9
+:10C5B0000D809C8924B1002414700988198270BDF3
+:10C5C0000124F9E770B5044600F12801808820F4C1
+:10C5D00000404518208A002825D0A189084480B24F
+:10C5E000A08129886A881144814200D2FFDF28880F
+:10C5F000698800260844A189884212D1A069807FF9
+:10C600002871698819B1201D00F0C1FA08E0637F24
+:10C6100028880833184481B26288201DFFF7E2FEA3
+:10C62000A6812682012070BD2DE9F04141898788CD
+:10C630000026044600F12805B94218D004F10A0882
+:10C6400021F400402844418819B1404600F09FFA87
+:10C6500008E0637F00880833184481B2628840464E
+:10C66000FFF7C0FE761C6189B6B2B942E8D1304608
+:10C67000BDE8F0812DE9F04104460B4627892830BA
+:10C68000A68827F40041B4F80A8001440D46B74259
+:10C6900001D10020ECE70AB1481D106023B1627F90
+:10C6A000691D18460BF0EBFB2E88698804F1080021
+:10C6B00021B18A1996B200F06AFA06E0637F6288B7
+:10C6C0000833991989B2FFF78DFE474501D12089BA
+:10C6D00060813046CCE78188C088814201D1012049
+:10C6E00070470020704701898088814201D1012074
+:10C6F00070470020704770B58588C38800F1280412
+:10C7000025F4004223F4004114449D421AD0838949
+:10C71000058A5E1925886388EC18A64214D313B1E4
+:10C720008B4211D30EE0437F08325C1922444088CB
+:10C7300092B2801A80B22333984201D211B103E041
+:10C740008A4201D1002070BD012070BD2DE9F04763
+:10C750008846C1880446008921F4004604F1280770
+:10C7600020F4004507EB060900F001FA002178BB30
+:10C77000B54204D9627FA81B801A002503E06088B7
+:10C78000627F801B801A083823D4E28962B1B9F82D
+:10C790000020B9F802303BB1E81A2177404518DB98
+:10C7A000E0893844801A09E0801A217740450ADB85
+:10C7B000607FE1890830304439440844C01EA4F841
+:10C7C0001280BDE8F087454503DB01202077E7E7CD
+:10C7D000FFE761820020F4E72DE9F74F044600F1FE
+:10C7E0002805C088884620F4004A608A05EB0A06BE
+:10C7F00008B1404502D20020BDE8FE8FE08978B143
+:10C800003788B6F8029007EB0901884200D0FFDFB5
+:10C81000207F4FF0000B50EA090106D088B33BE0BF
+:10C820000027A07FB9463071F2E7E18959B1607FF6
+:10C830002944083050440844B4F81F1020F8031D60
+:10C8400094F821108170E28907EB080002EB0801DF
+:10C85000E1813080A6F802B002985F4650B1637F54
+:10C8600030880833184481B26288A01DFFF7BAFDF2
+:10C87000E78121E0607FE189083050442944084481
+:10C880002DE0FFE7E089B4F81F102844C01B20F812
+:10C89000031D94F82110817009EB0800E28981B230
+:10C8A00002EB0800E081378071800298A0B1A01DE2
+:10C8B00000F06DF9A4F80EB0A07F401CA077A07D19
+:10C8C00008B1E088A08284F816B000BFA4F812B0C6
+:10C8D00084F817B001208FE7E0892844C01B30F8A6
+:10C8E000031DA4F81F10807884F82100EEE710B52E
+:10C8F000818800F1280321F400442344848AC288FB
+:10C90000A14212D0914210D0818971B9826972B16D
+:10C910001046FFF7E8FE50B91089283220F4004095
+:10C92000104419790079884201D1002010BD1846C1
+:10C9300010BD00F12803407F08300844C01E10607D
+:10C94000088808B9DB1E136008884988084480B24B
+:10C9500070472DE9F04100F12806407F1C46083061
+:10C960009046431808884D88069ADB1EA0B1C01C6B
+:10C9700080B2904214D9801AA04200DB204687B2D0
+:10C9800098183A4641460BF04EFA002816D1E01BA3
+:10C9900084B2B844002005E0ED1CADB2F61EE8E715
+:10C9A000101A80B20119A94206D8304422464146E5
+:10C9B000BDE8F0410BF037BA4FF0FF3058E62DE9F3
+:10C9C000F04100F12804407F1E460830904643188D
+:10C9D000002508884F88069ADB1E90B1C01C80B2E3
+:10C9E000904212D9801AB04200DB304685B29918C5
+:10C9F0002A4640460BF043FA701B86B2A84400203A
+:10CA000005E0FF1CBFB2E41EEAE7101A80B28119EC
+:10CA1000B94206D82118324640460BF030FAA81920
+:10CA200085B2284624E62DE9F04100F12804407F34
+:10CA30001E46083090464318002508884F88069AFD
+:10CA4000DB1E90B1C01C80B2904212D9801AB04255
+:10CA500000DB304685B298182A4641460BF00FFAA3
+:10CA6000701B86B2A844002005E0FF1CBFB2E41E84
+:10CA7000EAE7101A80B28119B94206D8204432463A
+:10CA800041460BF0FCF9A81985B22846F0E5401D97
+:10CA9000704710B5044600F12801C288808820F450
+:10CAA00000431944904206D0A28922B9228A12B9C1
+:10CAB000A28A904201D1002010BD0888498831B176
+:10CAC000201D00F064F800202082012010BD637F4B
+:10CAD00062880833184481B2201DFFF783FCF2E717
+:10CAE0000021C18101774182C1758175704703883A
+:10CAF0001380C28942B1C28822F4004300F12802A7
+:10CB00001A440A60C08970470020704710B5044677
+:10CB1000808AA0F57F41FF3900D0FFDFE088A08246
+:10CB2000E08900B10120A07510BD4FF6FF71818230
+:10CB300000218175704710B50446808AA0F57F41B9
+:10CB4000FF3900D1FFDFA07D28B9A088A18A8842E3
+:10CB500001D1002010BD012010BD8188828A914240
+:10CB600001D1807D08B1002070470120704720F47A
+:10CB7000004221F400439A4207D100F4004001F43E
+:10CB80000041884201D0012070470020704730B535
+:10CB9000044600880D4620F40040A84200D2FFDF82
+:10CBA00021884FF4004088432843208030BD70B571
+:10CBB0000C00054609D0082C00D2FFDF1DB1A1B240
+:10CBC000286800F044F8201D70BD0DB100202860D9
+:10CBD000002070BD0021026803E0938812681944A8
+:10CBE00089B2002AF9D100F032B870B500260D469E
+:10CBF0000446082900D2FFDF206808B91EE0044679
+:10CC000020688188A94202D001680029F7D1818873
+:10CC10000646A94201D100680DE005F1080293B271
+:10CC20000022994209D32844491B0260818021686F
+:10CC3000096821600160206000E00026304670BD78
+:10CC400000230B608A8002680A600160704700233D
+:10CC50004360021D018102607047F0B50F460188F4
+:10CC6000408815460C181E46AC4200D3641B304465
+:10CC7000A84200D9FFDFA019A84200D9FFDF381968
+:10CC8000F0BD2DE9F04188460646018840881546EA
+:10CC90000C181F46AC4200D3641B3844A84200D98C
+:10CCA000FFDFE019A84200D9FFDF708838447080A8
+:10CCB00008EB0400BDE8F0812DE9F041054600884D
+:10CCC0001E461746841B8846BC4200D33C442C8039
+:10CCD00068883044B84200D9FFDFA019B84200D9B3
+:10CCE000FFDF68883044688008EB0400E2E72DE944
+:10CCF000F04106881D460446701980B217468846E2
+:10CD00002080B84201D3C01B20806088A84200D296
+:10CD1000FFDF7019B84200D9FFDF6088401B6080D8
+:10CD200008EB0600C6E700002DE9F041BF4D0446C0
+:10CD30009046A8780E46A04200D8FFDF05EB860794
+:10CD4000786A50F8240000B1FFDFB868002816D0D8
+:10CD5000304600F032F90146B868FFF746FF05009B
+:10CD60000CD0786A072E40F8245000D3FFDFB0487B
+:10CD70004246294650F82630204698472846BDE8C6
+:10CD8000F0812DE9F84305000C46009524D00026DB
+:10CD9000E81C20F00300A84200D0FFDFDFF88C82FF
+:10CDA0000027314688F8007088F8014088F8024072
+:10CDB00088F8034088F8044088F8054088F8064061
+:10CDC000684600F003F9002042460099C91C21F092
+:10CDD0000301009116B10FE00126D9E702EB8003B1
+:10CDE0005962002106E000BFD3F824C04CF821703E
+:10CDF000491CC9B2A142F7D30099401C01EB840140
+:10CE0000C0B200910728E0D3481BBDE8F88310B5F5
+:10CE1000044603F065FD08B1102010BD2078834A58
+:10CE2000618802EB800092780EE0436A53F821306B
+:10CE300043B14A1C6280A180406A50F82100A06082
+:10CE4000002010BD491C89B28A42EED861800520BD
+:10CE500010BD70B505460C46084603F041FD08B10B
+:10CE6000102070BD072D01D3072070BD2570002054
+:10CE7000608070BD0EB56946FFF7EBFF00B1FFDFC4
+:10CE80006846FFF7C4FF08B100200EBD01200EBDAB
+:10CE900010B50446072800D3FFDF6448005D10BDCD
+:10CEA0003EB5054600246946FFF7D3FF18B1FFDF02
+:10CEB00001E0641CE4B26846FFF7A9FF0028F8D03F
+:10CEC0002846FFF7E5FF001BC0B23EBD57498978F1
+:10CED000814201D9C0B27047FF2070472DE9F0416F
+:10CEE00006291BD1514C00273B464FF6FF7604EB39
+:10CEF000810514F801C00AE0DC19D5F824E0A4B2D9
+:10CF00005EF824E0BEF1000F04D05B1C9BB29C4590
+:10CF1000F2D8344604802046B44201D100202EE7E6
+:10CF2000BDE8F04100E7A0F57F43FF3B01D00729B2
+:10CF300001D300207047F7E6A0F57F42FF3A0BD0FF
+:10CF4000072909D2394A9378834205D902EB810136
+:10CF5000496A51F820007047002070472DE9F041E0
+:10CF600004460D46A4F57F4143F20200FF3902D08A
+:10CF7000072D01D3072002E72C494FF000088A78DB
+:10CF8000A242F8D901EB8506726A52F82470002F8C
+:10CF9000F1D0274839461C3050F8252020469047CC
+:10CFA000716A284641F8248000F007F802463946A5
+:10CFB000B068FFF745FE0020E1E61D49383131F841
+:10CFC00010004FF6FC71C01C084070472DE9F84373
+:10CFD000164E8846054600242868C01C20F0030031
+:10CFE00028602046FFF7E9FF315D4843B8F1000FA4
+:10CFF00001D0002200E02A680146009232B10027E9
+:10D000004FEA0D00FFF7D3FD1FB106E00127002016
+:10D01000F8E706EB8401009A8A602968641C0844DA
+:10D02000E4B22860072CD7D3EFE60000C404002048
+:10D03000BC83010070B50E461D46114600F0D4F8C1
+:10D0400004462946304600F0D8F82044001D70BD43
+:10D050002DE9F04190460D4604004FF0000610D037
+:10D060000027E01C20F00300A04200D0FFDFDDB16C
+:10D0700041460020FFF79BFD0C3000EB850617B101
+:10D0800012E00127EDE7614F04F10C00A9003C60BC
+:10D090002572606000EB8500206060680AF090FFF8
+:10D0A00041463868FFF783FD3046BDE8F0812DE941
+:10D0B000FF4F564C804681B020689A46934600B98F
+:10D0C000FFDF2068027A424503D9416851F8280001
+:10D0D00020B143F2020005B0BDE8F08F514602983E
+:10D0E00000F082F886B258460E9900F086F885B2B4
+:10D0F0007019001D87B22068A14639460068FFF705
+:10D1000074FD04001FD0678025802946201D0E9DD8
+:10D1100007465A4601230095FFF786F920883146D5
+:10D1200038440123029ACDF800A0FFF77DF920884A
+:10D13000C1193846FFF7A8F9D9F800004168002066
+:10D1400041F82840C7E70420C5E770B52F4C0546D5
+:10D15000206800B9FFDF2068017AA9420ED9426831
+:10D1600052F8251051B1002342F825304A88006852
+:10D17000FFF766FD216800200A7A08E043F202000A
+:10D1800070BD4B6853F8203033B9401CC0B28242A6
+:10D19000F7D80868FFF71EFD002070BD70B51B4E64
+:10D1A00005460024306800B9FFDF3068017AA942E3
+:10D1B00004D9406850F8250000B1041D204670BD18
+:10D1C00070B5124E05460024306800B9FFDF3068A4
+:10D1D000017AA94206D9406850F8251011B131F8FA
+:10D1E000040B4418204670BD10B50A460121FFF714
+:10D1F00014F9C01C20F0030010BD10B50A4601212F
+:10D20000FFF70BF9C01C20F0030010BD64000020E4
+:10D2100070B50446C2F1100528190AF030FE15F069
+:10D22000FF0108D0491EC9B2802060542046BDE8E5
+:10D2300070400AF0A3BE70BD30B505E05B1EDBB2E6
+:10D24000CC5CD55C6C40C454002BF7D130BD10B51C
+:10D25000002409E00B78521E44EA430300F8013B26
+:10D2600011F8013BD2B2DC09002AF3D110BD2DE93F
+:10D27000F04389B01E46DDE9107990460D00044662
+:10D2800022D002460846F949FEF7C3FB1022214688
+:10D290003846FFF7DCFFE07B000606D5F34A394647
+:10D2A000102310320846FFF7C7FF102239464846C0
+:10D2B000FFF7CDFFF87B000606D5EC4A4946102360
+:10D2C00010320846FFF7B8FF102120460AF056FE3C
+:10D2D0000DE0103EB6B208EB060110232246684668
+:10D2E000FFF7AAFF224628466946FEF792FB102E5A
+:10D2F000EFD818D0F2B241466846FFF789FF1023F5
+:10D300004A46694604A8FFF797FF1023224604A95E
+:10D310006846FFF791FF224628466946FEF779FBEB
+:10D3200009B0BDE8F08310233A464146EAE770B5FC
+:10D330009CB01E460546134620980C468DF8080002
+:10D34000202219460DF109000AF099FD20222146FC
+:10D350000DF129000AF093FD17A913A8CDE90001EA
+:10D36000412302AA31462846FFF781FF1CB070BD59
+:10D370002DE9FF4F9FB014AEDDE92D5410AFBB492E
+:10D38000CDE90076202320311AA8FFF770FF4FF077
+:10D3900000088DF808804FF001098DF8099054F8C5
+:10D3A000010FCDF80A00A088ADF80E0014F8010CAA
+:10D3B0001022C0F340008DF8100055F8010FCDF891
+:10D3C0001100A888ADF8150015F8010C2C99C0F3D0
+:10D3D00040008DF8170006A882460AF050FD0AA802
+:10D3E0008346102222990AF04AFDA04835230838C6
+:10D3F00002AA40688DF83C80CDE900760E901AA90B
+:10D400001F98FFF734FF8DF808808DF80990206889
+:10D41000CDF80A00A088ADF80E0014F8010C102217
+:10D42000C0F340008DF810002868CDF81100A888DE
+:10D43000ADF8150015F8010C2C99C0F340008DF8DB
+:10D44000170050460AF01BFD5846102222990AF098
+:10D4500016FD86483523083802AA40688DF83C90AE
+:10D46000CDE900760E901AA92098FFF700FF23B0AF
+:10D47000BDE8F08FF0B59BB00C460546DDE9221003
+:10D480001E461746DDE92032D0F801C0CDF808C0AD
+:10D49000B0F805C0ADF80CC00078C0F340008DF8BE
+:10D4A0000E00D1F80100CDF80F00B1F80500ADF87D
+:10D4B000130008781946C0F340008DF81500108855
+:10D4C000ADF8160090788DF818000DF119001022B3
+:10D4D0000AF0D5FC0DF12900102231460AF0CFFCEC
+:10D4E0000DF13900102239460AF0C9FC17A913A81A
+:10D4F000CDE90001412302AA21462846FFF7B7FEE5
+:10D500001BB0F0BDF0B5A3B017460D4604461E464D
+:10D51000102202A828990AF0B2FC06A82022394657
+:10D520000AF0ADFC0EA8202229460AF0A8FC1EA98C
+:10D530001AA8CDE90001502302AA314616A8FFF728
+:10D5400096FE1698206023B0F0BDF0B589B0044671
+:10D55000DDE90E070D463978109EC1F340018DF8C4
+:10D56000001031789446C1F340018DF8011019681C
+:10D57000CDF802109988ADF8061099798DF8081049
+:10D580000168CDF809108188ADF80D1080798DF80B
+:10D590000F0010236A46614604A8FFF74DFE22469D
+:10D5A000284604A9FEF735FAD6F801000090B6F82F
+:10D5B0000500ADF80400D7F80100CDF80600B7F873
+:10D5C0000500ADF80A000020039010236A462146AA
+:10D5D00004A8FFF731FE2246284604A9FEF719FAEF
+:10D5E00009B0F0BD1FB51C6800945B680193136817
+:10D5F000029352680392024608466946FEF709FA0A
+:10D600001FBD10B588B0044610680490506805909E
+:10D6100000200690079008466A4604A9FEF7F9F92B
+:10D62000BDF80000208008B010BD1FB51288ADF80D
+:10D6300000201A88ADF80220002201920292039283
+:10D64000024608466946FEF7E4F91FBD7FB5074B61
+:10D6500014460546083B9A1C6846FFF7E6FF22463B
+:10D6600069462846FFF7CDFF7FBD00000A84010010
+:10D6700070B5044600780E46012813D0052802D064
+:10D68000092813D10EE0A06861690578042003F031
+:10D69000B5F8052D0AD0782300220420616903F033
+:10D6A00003F803E00420616903F0A8F8314620463E
+:10D6B000BDE8704001F086B810B500F12D02C379C5
+:10D6C0009478411D64F003042340C371DB070DD03F
+:10D6D0004B79547923404B710B79127913400B71BC
+:10D6E0008278C9788A4200D9817010BD00224A71BF
+:10D6F0000A71F5E74178012900D00C2101707047CB
+:10D700002DE9F04F93B04FF0000B0C690D468DF8EA
+:10D7100020B0097801260C2017464FF00D084FF075
+:10D72000110A4FF008091B2975D2DFE811F01B0020
+:10D73000C30206031E035D037003A203B703F803CD
+:10D74000190461049304A004EC042A05340552056D
+:10D750005D05EE053106340663067F06F9061D07F2
+:10D76000E606EB0614B120781D282AD0D5F80880EB
+:10D770005FEA08004FD001208DF82000686A02227D
+:10D780000D908DF824200A208DF82500A8690A90B4
+:10D79000A8880028EED098F8001091B10F2910D277
+:10D7A0007ED2DFE801F07D1349DEFEFDFCFBFAF9D5
+:10D7B00038089CF8F70002282DD124B120780C28D5
+:10D7C00001D00026EFE38DF82020CBE10420696A28
+:10D7D00003F014F8A8880728EED1204600F0EDFFEA
+:10D7E000022809D0204600F0E8FF032807D9204688
+:10D7F00000F0E3FF072802D20120207004E0002C93
+:10D80000B8D020780128D7D198F80400C11F0A2980
+:10D8100002D30A2061E0C4E1A070D8F80010E162F0
+:10D82000B8F80410218698F8060084F83200012028
+:10D8300028700320207044E00728BDD1002C99D027
+:10D8400020780D28B8D198F8031094F82F20C1F350
+:10D85000C000C2F3C002104201D0062000E0072041
+:10D86000890707D198F805100142D2D198F806101F
+:10D870000142CED194F8312098F8051020EA020236
+:10D880001142C6D194F8322098F806109043014214
+:10D89000BFD198F80400C11F0A29BAD2617D00E007
+:10D8A00006E281427ED8D8F800106160B8F8041012
+:10D8B000218198F80600A072012028700E202070A7
+:10D8C00003208DF82000686A0D9004F12D00099066
+:10D8D000601D0A900F300B9022E12875FDE341286E
+:10D8E00091D1204600F069FF042802D1E078C007FA
+:10D8F00004D1204600F061FF0F2884D1A88CD5F810
+:10D900000C8080B24FF0400BE669FFF747FC3246CF
+:10D9100041465B464E46CDF80090FFF750F80B208D
+:10D920008DF82000686A0D90E0690990002108A830
+:10D93000FFF79EFE2078042806D0A07D58B101286C
+:10D9400009D003280AD049E305202070032028705D
+:10D950008DF82060CDE184F800A032E7122020701D
+:10D96000E9E11128BCD1204600F027FF042802D1AC
+:10D97000E078C00719D0204600F01FFF062805D127
+:10D98000E078C00711D1A07D02280ED0204600F01B
+:10D9900014FF08E0CAE081E06FE14EE121E101E11E
+:10D9A000E7E017E0ADE111289AD1102208F101015A
+:10D9B00004F13C000AF063FA607801287ED012205E
+:10D9C0002070E078C00760D0A07D0028C8D0012872
+:10D9D000C6D05AE0112890D1204600F0EEFE08286B
+:10D9E00004D0204600F0E9FE132886D104F16C0033
+:10D9F000102208F1010106460AF041FA20780828B1
+:10DA00000DD014202070E178C8070DD0A07D022829
+:10DA10000AD06278022A04D00328A1D035E0092078
+:10DA2000F0E708B1012837D1C80713D0A07D02283C
+:10DA30001DD000200090D4E9062133460EA8FFF740
+:10DA400076FC10220EA904F13C000AF0ECF9C8B1F2
+:10DA5000042042E7D4E90912201D8DE8070004F1F3
+:10DA60002C0332460EA8616BFFF76FFDE9E7606B90
+:10DA7000C1F34401491E0068C84000F0010040F0B5
+:10DA80008000D7E72078092806D185F800908DF826
+:10DA9000209033E32870ECE30920FBE711289AD1AA
+:10DAA000204600F08AFE0A2802D1E078C00704D19F
+:10DAB000204600F082FE15288DD100E08DE104F1B2
+:10DAC0003C00102208F1010106460AF0D8F920783E
+:10DAD0000A2816D016202070D4E90932606B611D27
+:10DAE0008DE80F0004F15C0304F16C0247310EA8CD
+:10DAF000FFF7C0FC10220EA930460AF094F918B1C5
+:10DB0000F5E20B20207071E22046FFF7D5FDA078EA
+:10DB1000216A0A18C0F1100110460AF02FFA23E317
+:10DB2000394608A8FFF7A4FD06463BE20228B6D115
+:10DB3000204600F042FE042804D3204600F03DFEBB
+:10DB4000082809D3204600F038FE0E2829D32046A5
+:10DB500000F033FE122824D2A07D02289FD10E208F
+:10DB60008DF82000686A0D9098F801008DF8240067
+:10DB7000F0E3022893D1204600F01FFE002810D0C9
+:10DB8000204600F01AFE0128F9D0204600F015FECC
+:10DB90000C28F4D004208DF8240098F801008DF8AA
+:10DBA00025005EE21128FCD1002CFAD0207817283D
+:10DBB000F7D16178606A022911D0002101EB41019F
+:10DBC000182606EBC1011022405808F101010AF0A5
+:10DBD00056F90420696A00F0E3FD2670F1E50121A1
+:10DBE000ECE70B28DDD1002CDBD020781828D8D129
+:10DBF0006078616A02281CD05FF0000000EB4002F0
+:10DC0000102000EBC2000958B8F8010008806078C5
+:10DC1000616A02280FD0002000EB4002142000EBC4
+:10DC2000C2000958404650F8032F0A604068486017
+:10DC300039E00120E2E70120EEE71128B1D1002C04
+:10DC4000AFD020781928ACD16178606A022912D04F
+:10DC50005FF0000101EB41011C2202EBC101102227
+:10DC6000405808F101010AF00AF90420696A00F03D
+:10DC700097FD1A20B6E00121ECE7082891D1002C8D
+:10DC80008FD020781A288CD1606A98F8012001780A
+:10DC900062F347010170616AD8F8022041F8012F50
+:10DCA000B8F8060088800420696A00F079FD8EE2E9
+:10DCB000072012E63878012894D1182204F11400C4
+:10DCC00079680AF021F9E079C10894F82F0001EA97
+:10DCD000D001E07861F30000E070217D002974D16B
+:10DCE0002178032909D0C00725D0032028708DF89A
+:10DCF0002090686A0D90412004E3607DA1788842FD
+:10DD000001D90620E9E502262671E179204621F0B5
+:10DD1000E001E171617A21F0F0016172A17A21F0F4
+:10DD2000F001A172FFF7C8FC2E708DF82090686A90
+:10DD30000D900720E6E20420ACE6387805289DD156
+:10DD40008DF82000686A0D90B8680A900720ADF839
+:10DD500024000A988DF830B06168016021898180C3
+:10DD6000A17A817104202070F4E23978052985D1E7
+:10DD70008DF82010696A0D91391D09AE0EC986E82B
+:10DD80000E004121ADF824108DF830B01070A88C31
+:10DD9000D7F80C8080B24026A769FFF711FA4146F8
+:10DDA0003A463346C846CDF80090FEF73CFE0021C7
+:10DDB00008A8FFF75DFCE07820F03E00801CE070D2
+:10DDC0002078052802D00F200CE049E1A07D20B189
+:10DDD000012802D0032802D002E10720BFE584F821
+:10DDE0000080EEE42070ECE4102104F15C0002F00D
+:10DDF0005AFA606BB0BBA07D18B1012801D0052094
+:10DE0000FDE006202870F7486063A063BEE2387822
+:10DE1000022894D1387908B12875B3E3A07D02288F
+:10DE200002D0032805D022E0B8680028F5D060634E
+:10DE30001CE06078012806D0A07994F82E10012803
+:10DE400005D0E84806E0A17994F82E00F7E7B86815
+:10DE50000028E2D06063E078C00701D0012902D039
+:10DE6000E04803E003E0F8680028D6D0A06306206D
+:10DE700010E68DF82090696A0D91E1784846C9074F
+:10DE800009D06178022903D1A17D29B1012903D0EC
+:10DE9000A17D032900D00720287031E138780528BA
+:10DEA000BBD1207807281ED084F800A005208DF86B
+:10DEB0002000686A0D90B8680A90ADF824A08DF82B
+:10DEC00030B003210170E178CA070FD0A27D022A89
+:10DED0001AD000210091D4E9061204F15C03401C21
+:10DEE000FFF725FA67E384F80090DFE7D4E9092318
+:10DEF000211D8DE80E0004F12C0304F15C02401C8E
+:10DF0000616BFFF722FB56E3626BC1F34401491ECC
+:10DF10001268CA4002F0010141F08001DAE7387866
+:10DF20000528BDD18DF82000686A0D90B8680A9068
+:10DF3000ADF824A08DF830B0042100F8011B1022A8
+:10DF400004F15C0109F09BFF002108A8FFF790FB9A
+:10DF50002078092801D0132044E70A2020709BE58F
+:10DF6000E078C10742D0A17D012902D0022927D043
+:10DF700038E0617808A8012916D004F16C010091FD
+:10DF8000D4E9061204F15C03001DFFF7BBFA0A2076
+:10DF9000287003268DF82080686A0D90002108A85B
+:10DFA000FFF766FBDDE2C3E204F15C010091D4E916
+:10DFB000062104F16C03001DFFF7A4FA0026E9E72F
+:10DFC000C0F3440114290DD24FF0006101EBB010F1
+:10DFD0004FEAB060E0706078012801D01020BEE404
+:10DFE0000620FFE6607801283FF4B7AC0A2051E52F
+:10DFF000E178C90708D0A17D012903D10B20287041
+:10E0000004202FE028702DE00E2028706078616BCE
+:10E01000012817D004F15C0304F16C020EA8FFF78D
+:10E02000E1FA2046FFF748FBA0780EAEC0F11001E0
+:10E03000304409F0A3FF06208DF82000686A099695
+:10E040000D909AE004F16C0304F15C020EA8FFF756
+:10E05000C9FAE9E73978022903D139790029D1D001
+:10E0600029758FE28DF82000686A0D9058E53878A0
+:10E070000728F6D1D4E909216078012808D004F1F5
+:10E080006C00CDE90002029105D104F16C0304E0BB
+:10E0900004F15C00F5E704F15C0304F14C007A68DC
+:10E0A0000646216AFFF764F96078012821D1A0783B
+:10E0B000216A0A18C0F11001104609F05FFFD4E987
+:10E0C0000923606B04F12D018DE80F0004F15C035E
+:10E0D00004F16C0231460EA800E055E2FFF7CAF9E0
+:10E0E00010220EA904F13C0009F09DFE08B10B209E
+:10E0F000AFE485F8008000BF8DF82090686A0D902D
+:10E100008DF824A00CE538780528AAD18DF82000D8
+:10E11000686A0D90B8680A90ADF824A08DF830B008
+:10E1200080F80080617801291AD0D4E9093204F11D
+:10E130002D01A66B03920096CDE9011304F16C0347
+:10E1400004F15C0204F14C01401CFFF793F900213B
+:10E1500008A8FFF78DFA6078012805D0152041E660
+:10E16000D4E90923611DE4E70E20287006208DF80C
+:10E170002000686ACDF824B00D90A0788DF82800B2
+:10E18000CEE438780328C0D1E079C00770D00F20E2
+:10E190002870072066E7387804286BD11422391DCF
+:10E1A00004F1140009F0B0FE616A208CA1F80900A6
+:10E1B000616AA078C871E179626A01F003011172A5
+:10E1C000616A627A0A73616AA07A81F82400162073
+:10E1D00060E485F800A08DF82090696A50460D91A2
+:10E1E00090E000000A8401003878052842D1B86820
+:10E1F000A8616178606A022901D0012100E0002154
+:10E2000001EB4101142606EBC1014058082102F040
+:10E210004AF86178606A022901D0012100E00021FA
+:10E2200001EB410106EBC101425802A8E169FFF789
+:10E230000DFA6078626A022801D0012000E0002017
+:10E2400000EB4001102000EBC1000223105802A98E
+:10E250000932FEF7F1FF626AFD4B0EA80932A1698F
+:10E26000FFF7E3F96178606A022904D0012103E035
+:10E2700042E18BE0BDE0002101EB4101182606EBF5
+:10E28000C101A27840580EA909F0F9FD6178606AD1
+:10E29000022901D0012100E0002101EB410106EB40
+:10E2A000C1014058A1780844C1F1100109F066FE8F
+:10E2B00005208DF82000686A0D90A8690A90ADF8D5
+:10E2C00024A08DF830B0062101706278616A022ABC
+:10E2D00001D0012200E0002202EB420206EBC20262
+:10E2E000401C8958102209F0CAFD002108A8FFF738
+:10E2F000BFF91220C5F818B028708DF82090686A10
+:10E300000D900B208DF824000AE43878052870D190
+:10E310008DF82000686A0D90B8680A900B20ADF85F
+:10E3200024000A98072101706178626A022901D0ED
+:10E33000012100E0002101EB4103102101EBC301A9
+:10E3400051580988A0F801106178626A022902D048
+:10E35000012101E02FE1002101EB4103142101EB38
+:10E36000C30151580A6840F8032F4968416059E0D9
+:10E370001920287001208DF8300077E616202870CB
+:10E380008DF830B0002108A8FFF772F9032617E1D5
+:10E3900014202870B0E6387805282AD18DF820009E
+:10E3A000686A0D90B8680A90ADF824A08DF830B076
+:10E3B00080F800906278616A4E46022A01D00122FC
+:10E3C00000E0002202EB42021C2303EBC202401CCD
+:10E3D0008958102209F053FD002108A8FFF748F9D9
+:10E3E000152028708DF82060686A0D908DF82460E3
+:10E3F0003CE680E0387805287DD18DF82000686AF9
+:10E400000D90B8680A90ADF82490092101706169F7
+:10E41000097849084170616951F8012FC0F802205C
+:10E420008988C18020781C28A8D1A1E7E078C0079E
+:10E4300002D04FF0060C01E04FF0070C6078022884
+:10E440000AD04FF0000000BF00EB040101F1090108
+:10E4500005D04FF0010004E04FF00100F4E74FF069
+:10E4600000000B78204413EA0C030B7010F8092FFE
+:10E4700002EA0C02027004D14FF01B0C84F800C0B9
+:10E48000D2B394F801C0BCF1010F00D09BB990F851
+:10E4900000C0E0465FEACC7C04D028F0010606709C
+:10E4A000102606E05FEA887C05D528F00206067093
+:10E4B00013262E70032694F801C0BCF1020F00D081
+:10E4C00092B991F800C05FEACC7804D02CF0010634
+:10E4D0000E70172106E05FEA8C7805D52CF0020655
+:10E4E0000E701921217000260078D0BBCAB3C3BBBF
+:10E4F0001C20207035E012E002E03878062841D177
+:10E500001A2019E4207801283CD00C283AD0204663
+:10E51000FFF7F0F809208DF82000686A0D9031E0CF
+:10E520003878052805D00620387003261820287072
+:10E5300046E005218DF82010686A0D90B8680A90B1
+:10E540000220ADF8240001208DF830000A980170F7
+:10E55000297D4170394608A8FFF78AF80646182039
+:10E560002870012E0ED02BE001208DF82000686A63
+:10E570000D9003208DF82400287D8DF8250085F866
+:10E5800014B012E0287D80B11D2020701720287063
+:10E590008DF82090686A0D9002208DF8240039468D
+:10E5A00008A8FFF765F806460AE00CB1FE202070C7
+:10E5B0009DF8200020B1002108A8FFF759F810E4C9
+:10E5C00013B03046BDE8F08F2DE9F04387B00C461C
+:10E5D0004E6900218DF8041001202578034602279A
+:10E5E0004FF007094FF0050C85B1012D53D0022DD6
+:10E5F00039D1FE2030708DF80030606A059003201C
+:10E600008DF80400207E8DF8050063E02179012952
+:10E6100025D002292DD0032928D0042923D1B17D6A
+:10E62000022920D131780D1F042D04D30A3D032D7A
+:10E6300001D31D2917D12189022914D38DF8047023
+:10E64000237020899DF8041088421BD2082001E025
+:10E65000028401008DF80000606A059057E0707830
+:10E660000128EBD0052007B0BDE8F0831D203070F5
+:10E67000E4E771780229F5D131780C29F3D18DF8CE
+:10E680000490DDE7083402F804CB94E80B0082E83C
+:10E690000B000320E7E71578052DE4D18DF800C0C5
+:10E6A000656A0595956802958DF8101094F80480B8
+:10E6B000B8F1010F13D0B8F1020F2DD0B8F1030F4C
+:10E6C0001CD0B8F1040FCED1ADF804700E20287024
+:10E6D000207E687000216846FEF7CAFF0CE0ADF8A6
+:10E6E00004700B202870207E002100F01F0068704D
+:10E6F0006846FEF7BDFF37700020B4E7ADF8047040
+:10E700008DF8103085F800C0207E687027701146A3
+:10E710006846FEF7ADFFA6E7ADF804902B70207FAA
+:10E720006870607F00F00100A870A07F00F01F00FB
+:10E73000E870E27F2A71C0071CD094F8200000F036
+:10E740000700687194F8210000F00700A87100210B
+:10E750006846FEF78DFF2868F062A8883086A879A1
+:10E7600086F83200A069407870752879B0700D2065
+:10E770003070C1E7A9716971E9E700B587B0042875
+:10E780000CD101208DF800008DF8040000200591C7
+:10E790008DF8050001466846FEF76AFF07B000BD28
+:10E7A00070B50C46054602F029F821462846BDE81A
+:10E7B00070407823002201F077BF08B100787047DD
+:10E7C0000C20704770B50C0005784FF000010CD09C
+:10E7D00021702146F4F720FD69482178405D884288
+:10E7E00001D1032070BD022070BDF4F715FD00209B
+:10E7F00070BD0279012A05D000220A704B78012BE6
+:10E8000002D003E0042070470A758A610279930000
+:10E81000521C0271C15003207047F0B587B00F46FB
+:10E8200005460124287905EB800050F8046C7078C7
+:10E83000411E02290AD252493A46083901EB8000AA
+:10E84000314650F8043C2846984704460CB1012C48
+:10E8500011D12879401E10F0FF00287101D0032447
+:10E86000E0E70A208DF80000706A0590002101960B
+:10E870006846FFF7A7FF032CD4D007B02046F0BDB1
+:10E8800070B515460A46044629461046FFF7C5FFEF
+:10E89000064674B12078FE280BD1207C30B10020D0
+:10E8A0002870294604F10C00FFF7B7FF2046FEF759
+:10E8B00021FF304670BD704770B50E4604467C217E
+:10E8C00009F07EFB0225012E03D0022E04D0052084
+:10E8D00070BD0120607000E065702046FEF70AFF01
+:10E8E000A575002070BD28B1027C1AB10A4600F15E
+:10E8F0000C01C5E70120704710B5044686B004201E
+:10E9000001F07CFF2078FE2806D000208DF8000062
+:10E9100069462046FFF7E7FF06B010BD7CB50E46FE
+:10E9200000218DF804104178012903D0022903D079
+:10E93000002405E0046900E044690CB1217C89B140
+:10E940006D4601462846FFF754FF032809D1324699
+:10E9500029462046FFF794FF9DF80410002900D0B7
+:10E9600004207CBD04F10C05EBE730B40C460146F5
+:10E97000034A204630BC034B0C3AFEF756BE00005B
+:10E98000488401000284010070B50D46040011D0D6
+:10E9900085B12101284609F0F1FA10224E49284696
+:10E9A00009F06DFA4C480121083801804480456027
+:10E9B000002070BD012070BD70B5474E0024054693
+:10E9C000083E10E07068AA7B00EB0410817B914246
+:10E9D00008D1C17BEA7B914204D10C22294609F07F
+:10E9E00022FA30B1641C30888442EBDB4FF0FF30F8
+:10E9F00070BD204670BD70B50D46060006D02DB125
+:10EA0000FFF7DAFF002803DB401C14E0102070BD84
+:10EA1000314C083C20886288411C914201D9042075
+:10EA200070BD6168102201EB0010314609F027FA31
+:10EA30002088401C20802870002070BD70B51446CE
+:10EA40000D0018D0BCB10021A170022802D01028FE
+:10EA500011D105E0288870B10121A170108008E073
+:10EA60002846FFF7A9FF002805DB401CA070A889F5
+:10EA70002080002070BD012070BD70B50546144691
+:10EA80000E000BD000203070A878012808D005D9DE
+:10EA90001149A1F108010A8890420AD9012070BDEC
+:10EAA00024B1287820702888000A5070022008704D
+:10EAB0000FE064B14968102201EB001120461039C3
+:10EAC00009F0DDF9287820732888000A6073102087
+:10EAD0003070002070BD0000700000202DE9F04172
+:10EAE00090460C4607460025FE48072F00EB881687
+:10EAF00007D2DFE807F00707070704040400012531
+:10EB000000E0FFDF06F81470002D13D0F5488030C8
+:10EB100000EB880191F82700202803D006EB400085
+:10EB2000447001E081F8264006EB4402202050703A
+:10EB300081F82740BDE8F081F0B51F4614460E4627
+:10EB40000546202A00D1FFDFE649E648803100EB88
+:10EB5000871C0CEB440001EB8702202E07D00CEB46
+:10EB6000460140784B784870184620210AE092F818
+:10EB70002530407882F82500F6E701460CEB41008D
+:10EB800005704078A142F8D192F82740202C03D09C
+:10EB90000CEB4404637001E082F826300CEB410476
+:10EBA0002023637082F82710F0BD30B50D46CE4BA0
+:10EBB00044190022181A72EB020100D2FFDFCB4881
+:10EBC000854200DDFFDFC9484042854200DAFFDFB1
+:10EBD000C548401C844207DA002C01DB204630BDCA
+:10EBE000C148401C201830BDBF48C043FAE710B5EB
+:10EBF00004460168407ABE4A52F82020114450B1C0
+:10EC00000220084420F07F40F9F7FBFE94F9081039
+:10EC1000BDE81040C9E70420F3E72DE9F047B14E05
+:10EC2000803696F82D50DFF8BC9206EB850090F800
+:10EC3000264034E009EB85174FF0070817F8140059
+:10EC4000012806D004282ED005282ED0062800D072
+:10EC5000FFDF01F0E3F8014607EB4400427806EBE2
+:10EC6000850080F8262090F82720A24202D1202299
+:10EC700080F82720084601F0DCF82A4621460120CA
+:10EC8000FFF72CFF9B48414600EB0410026820462A
+:10EC9000904796F82D5006EB850090F82640202CE2
+:10ECA000C8D1BDE8F087022000E003208046D0E70D
+:10ECB00010B58C4C2021803484F8251084F826105F
+:10ECC00084F82710002084F8280084F82D0084F8A8
+:10ECD0002E10411EA16044F8100B20746074207344
+:10ECE0006073A0738449E077207508704870002134
+:10ECF0007C4A103C02F81100491CC9B22029F9D302
+:10ED00000120F9F772FD0020F9F76FFD012084F86A
+:10ED10002200F4F74FF87948F4F75BF8764CA41E1C
+:10ED200020707748F4F755F86070BDE81040F9F7A7
+:10ED3000E9BC10B5F9F70BFD6F4CA41E2078F4F771
+:10ED400061F86078F4F75EF8BDE8104001F09EB815
+:10ED5000202070472DE9F34F624E0025803606EBE8
+:10ED6000810A89B09AF82500202822D0691E0291D4
+:10ED70006049009501EB00108146D0E90112C0689E
+:10ED80000391CDE90420B08BADF81C00B07F8DF865
+:10ED90001E009DF81500C8B10227554951F82040C2
+:10EDA0000399E219114421F07F41019184B10221BC
+:10EDB0000FE00120F9F719FD0020F9F716FDF9F72A
+:10EDC000E4FC01F063F886F82F50A0E00427E4E7A4
+:10EDD00000218DF81810022801D0012820D10398B5
+:10EDE000391901440998081A9DF81C1020F07F4039
+:10EDF00001B10221333181420BD203208DF815007D
+:10EE00000398C4F13201401A20F07F40322403906D
+:10EE10000CE096F8240018B901F0A8F900284CD0AD
+:10EE2000322C03D214B101F025F801E001F02EF8E4
+:10EE3000314A107818B393465278039B121B002175
+:10EE40009DF81840984601281AD0032818D00020B1
+:10EE50008DF81E00002A04DD981A039001208DF819
+:10EE600018009DF81C0000B102210398254A20F0EB
+:10EE70007F40039003AB099801F014F810B110E043
+:10EE80000120E5E79DF81D0018B99BF80000032854
+:10EE900012D08DF81C50CDF80C808DF818408DF8EC
+:10EEA0001E509DF8180058B103980123C119002283
+:10EEB0001846F9F7EDFC06E000200BB0BDE8F08F36
+:10EEC0000120F9F792FC99F90C2001230020019907
+:10EED000F9F7DEFC012086F82F008AF8285020225E
+:10EEE000694611E004070020FF7F841E0020A1076F
+:10EEF000588401000405002082000020570501000D
+:10EF00001BEC0000FFFF3F00F94808F0FDFF012067
+:10EF1000D3E72DE9F05FDFF8D883064608EB8600DB
+:10EF200090F82550202D1FD0A8F180002C4600EB32
+:10EF30008617A0F50079DFF8BCB305E0A24607EB21
+:10EF40004A004478202C0AD0F9F7EEFC09EB0413B0
+:10EF50005A4601211B1D00F0A5FF0028EED0AC424F
+:10EF600002D0334652461EE0E34808B1AFF30080BA
+:10EF7000F9F7DAFC98F82F206AB1D8F80C20411C78
+:10EF8000891A0902CA1701EB12610912002902DD70
+:10EF90000020BDE8F09F3146FFF7DCFE08B10120FC
+:10EFA000F7E733462A4620210420FFF7C5FDEFE7A7
+:10EFB0002DE9F041CE4C2569F9F7B6FC401B000263
+:10EFC000C11700EB1160001200D4FFDF94F822009B
+:10EFD00000B1FFDF012784F8227094F82E0020286A
+:10EFE00000D1FFDF94F82E60202084F82E00002549
+:10EFF00084F82F5084F8205084F82150BF482560B1
+:10F000000078022833D0032831D000202077A06870
+:10F01000401C05D04FF0FF30A0600120F9F7E5FB60
+:10F020000020F9F7E2FBF9F7DAFCF9F7D2FCF9F77F
+:10F03000ACFB08F0A7F9B248056005604FF0E0218D
+:10F040004FF40040B846C1F88002F3F721FE94F86F
+:10F050002D703846FFF75DFF0028FAD0A4488038AD
+:10F0600000EB871010F81600022802D006E00120FD
+:10F07000CCE73A4631460620FFF730FD84F823807E
+:10F0800004EB870090F82600202804D09B48801EBF
+:10F090004078F3F7BDFE207F002803D0F9F78FFCFE
+:10F0A0002577657746E50146914810B590F82D2003
+:10F0B0000024803800EB821010F814302BB1641C4F
+:10F0C000E4B2202CF8D3202010BD8E4800EB0410B1
+:10F0D000016021460120FFF701FD204610BD10B55B
+:10F0E000012801D0032800D171B3814A92F82D3054
+:10F0F0007F4C0022803C04EB831300BF13F81240C6
+:10F100000CB1082010BD521CD2B2202AF6D37B4A83
+:10F1100048B1022807D0072916D2DFE801F015060A
+:10F12000080A0C0E100000210AE01B2108E03A2119
+:10F1300006E0582104E0772102E0962100E0B521A5
+:10F1400051701070002010BD072010BD6B4810B525
+:10F150004078F9F756FC80B210BD10B5202811D2C6
+:10F16000634991F82D30A1F1800202EB831414F869
+:10F1700010303BB191F82D3002EB831212F81020C1
+:10F18000012A01D0002010BD91F82D200146002059
+:10F19000FFF7A4FC012010BD10B5F9F7C5FBBDE8D1
+:10F1A0001040F9F72EBC2DE9F0410E46504F017882
+:10F1B0002025803F0C4607EB831303E0254603EB35
+:10F1C00045046478944202D0202CF7D108E0202C2A
+:10F1D00006D0A14206D103EB41014978017007E056
+:10F1E0000020A7E403EB440003EB4501407848709E
+:10F1F000454F7EB127B1002140F2DA30AFF30080F5
+:10F200003078A04206D127B1002140F2DD30AFF3C3
+:10F210000080357027B1002140F2E230AFF300806A
+:10F22000012087E410B542680B689A1A1202D417BD
+:10F2300002EB1462121216D4497A91B1427A82B961
+:10F24000324A006852F82110126819441044001D17
+:10F25000891C081A0002C11700EB11600012322845
+:10F2600001DB012010BD002010BD2DE9F0478146D3
+:10F270001F48244E00EB8100984690F8254020203E
+:10F28000107006F50070154600EB81170BE000BF0B
+:10F2900006EB04104946001DFFF7C4FF28B107EB39
+:10F2A00044002C704478202CF2D1297888F8001082
+:10F2B00013E000BF06EB0415291D4846FFF7B2FF17
+:10F2C00068B988F80040A97B99F80A00814201D802
+:10F2D0000020E6E407EB44004478202CEAD101202A
+:10F2E000DFE42DE9FC410E4607460024054D18E0F9
+:10F2F00084070020FFFF3F00000000008200002084
+:10F3000000F50040040500200000000058840100C2
+:10F310009DF8000005EB00108168384600F0D6FD2E
+:10F3200001246B4601AA31463846FFF79EFF0028AC
+:10F33000EED02046BDE8FC8170B50446FF480125AB
+:10F34000A54300EB841100EB8510402208F097FDE7
+:10F35000FB4E26B1002140F25C40AFF30080F7483D
+:10F36000803000EB850100EB8400D0F82500C1F867
+:10F37000250026B100214FF48C60AFF300802846B1
+:10F3800070BD2DE9FC418446EC481546089C00EB15
+:10F3900085170E4617F81400012803D0022801D063
+:10F3A0000020C7E70B46E74A0121604600F07AFDDE
+:10F3B000A8B101AB6A4629463046FFF756FF70B147
+:10F3C000DE489DF804209DF80010803000EB850693
+:10F3D0008A4208D02B460520FFF7AEFB0BE02A46F9
+:10F3E0002146042014E0202903D007EB4100407897
+:10F3F00001E096F8250007EB440148709DF80000F5
+:10F40000202809D007EB400044702A4621460320FB
+:10F41000FFF764FB01208DE706F8254F0120F0700F
+:10F42000F3E7C94901EB0010001DFFF7E0BB7CB515
+:10F430001D46134604460E4600F1080221461846B2
+:10F44000F9F7ECFA94F908000F2804DD1F38207250
+:10F450002068401C206096B10220BC4951F826105B
+:10F46000461820686946801B20F07F40206094F990
+:10F4700008002844C01C1F2803DA012009E00420EA
+:10F48000EBE701AAF9F7CAFA9DF8040010B1009859
+:10F49000401C00900099206831440844C01C20F0B2
+:10F4A0007F4060607CBD2DE9FE430C46064609782E
+:10F4B00060799072207998461546507241B19F4804
+:10F4C000803090F82E1020290AD00069401D0BE0F2
+:10F4D000D4E90223217903B02846BDE8F043A6E72A
+:10F4E0009B484178701D084420F07F472179002215
+:10F4F0002846A368FFF79BFF3946284600F0E6FC44
+:10F50000D4E9023221796846FFF791FF4146284647
+:10F51000019CFFF7E6FE2B4622460021304600F014
+:10F52000C1FC002803D13146284600F0CFFCBDE8DD
+:10F53000FE832DE9FE4F814600F084FC30B10027A8
+:10F5400099F8000020B10020BDE8FE8F0127F7E701
+:10F550007A4D7B4C4FF0000A803524B1002140F2F7
+:10F56000D340AFF3008095F82D8085F823A00026C6
+:10F5700024B100214FF49B60AFF300801FB94046D7
+:10F58000FFF7DAFE804624B100214FF49C60AFF310
+:10F590000080F9F7C9F943466A464946FFF783FFF9
+:10F5A00024B1002140F2E640AFF3008095F82E0030
+:10F5B00020280CD029690098401A0002C21700EBDD
+:10F5C0001260001203D5684600F080FC012624B1C9
+:10F5D00000214FF49E60AFF3008095F823000028CF
+:10F5E000BBD124B1002140F2F640AFF30080F9F71F
+:10F5F0009BF96B46534A002100F054FC0028A3D02D
+:10F6000027B941466846FFF76CFE064326B16846B7
+:10F61000FFF7EDFAC9F8080024B1002140F20950C3
+:10F62000AFF3008001208FE72DE9FF5F8A46814616
+:10F6300000F008FC414C803410B39AF80000002719
+:10F6400010B1012800D0FFDF3D4D25B1002140F26F
+:10F650007F50AFF300800120A84600905FEA0806C3
+:10F6600004D0002140F28750AFF30080009800F0F2
+:10F67000E0FB94F82D50002084F8230067B119E0D6
+:10F6800094F82E000127202800D1FFDF9AF800000F
+:10F690000028D9D0FFDFD7E72846FFF74DFE054603
+:10F6A00026B1002140F29150AFF3008094F823007E
+:10F6B0000028D3D126B1002140F29B50AFF3008047
+:10F6C000F9F732F983462B4601AA5146FFF7EBFEC4
+:10F6D0005FEA060804D0002140F2A250AFF3008098
+:10F6E0003B462A4601A95846CDF80090FFF749FE4F
+:10F6F000064604EB850090F828B0B8F1000F04D05E
+:10F70000002140F2A950AFF3008000F087FB009089
+:10F71000B8F1000F04D0002140F2AF50AFF30080E9
+:10F7200094F82300002899D1B8F1000F04D00021EB
+:10F7300040F2B750AFF3008003490BE0040700200C
+:10F7400000000000FFFF3F00040500205884010076
+:10F750008200002001EB09100DF1040C00F10400FF
+:10F760009CE80E0080E80E004EB35FEA080604D065
+:10F77000002140F2C450AFF300803BEA070012D0F2
+:10F7800094F82E0020280ED126B1002140F2C95055
+:10F79000AFF300802846FFF7BCFB20B99AF80000C1
+:10F7A000D8B3012849D0B8F1000F04D0002140F2AD
+:10F7B000E650AFF30080284600F029FB01265FEAFF
+:10F7C000080504D0002140F2EF50AFF3008000980C
+:10F7D00000F02FFB25B1002140F2F350AFF3008081
+:10F7E0008EB194F82D0004EB800090F826002028BC
+:10F7F00009D025B1002140F2FA50AFF30080F9485A
+:10F800004078F3F705FB25B1002140F2FF50AFF33C
+:10F81000008004B03046BDE8F09FFFE7B8F1000F6C
+:10F8200004D0002140F2D150AFF3008094F82D2095
+:10F8300049460420FFF752F9C0E7002E3FF40EAF0F
+:10F84000002140F2DC50AFF3008007E72DE9F84FCC
+:10F85000E54D814695F82D004FF00008E34C4FF040
+:10F86000010B474624B1002140F20D60AFF3008048
+:10F87000584600F0DEFA85F8237024B1002140F2EA
+:10F880001260AFF3008095F82D00FFF755FD064696
+:10F8900095F8230028B1002CE4D000214FF4C36078
+:10F8A0004BE024B1002140F21C60AFF30080CE4851
+:10F8B000803800EB861111F81900032856D1334621
+:10F8C00005EB830A4A469AF82500904201D10120AF
+:10F8D00000E0002000900AF125000021FFF763FC02
+:10F8E00001460098014203D001228AF82820AF7710
+:10F8F000E1B324B1002140F22160AFF30080324631
+:10F9000049460120FFF7EAF89AF828A024B100211F
+:10F9100040F22C60AFF3008000F080FA834624B1FF
+:10F92000002140F23160AFF3008095F8230038B138
+:10F93000002C97D0002140F23560AFF3008091E7B2
+:10F94000BAF1000F07D095F82E00202803D13046D9
+:10F95000FFF7DFFAE0B124B1002140F24960AFF3D4
+:10F960000080304600F053FA4FF0010824B1002126
+:10F9700040F25260AFF30080584600F05AFA24B1CA
+:10F98000002140F25660AFF300804046BDE8F88F9A
+:10F99000002CF1D0002140F24460AFF30080E6E794
+:10F9A0000020F8F7FBBE0120F8F7F8BE8D4800787C
+:10F9B00070472DE9F0418C4C94F82E0020281FD17F
+:10F9C00094F82D6004EB860797F82550202D00D180
+:10F9D000FFDF8549803901EB861000EB4500407858
+:10F9E00007F8250F0120F87084F82300294684F8D1
+:10F9F0002E50324602202234FFF770F8002020708B
+:10FA00000FE42DE9F0417A4E774C012538B10128F9
+:10FA100021D0022879D003287DD0FFDFF0E700F065
+:10FA200029FAFFF7C6FF207E00B1FFDF84F82150DE
+:10FA30000020F8F7DAFEA168481C04D00123002258
+:10FA40001846F8F725FF14F82E0F217806EB011160
+:10FA50000A68012154E0FFF7ACFF0120F8F7C5FE6A
+:10FA600094F8210050B1A068401C07D014F82E0F64
+:10FA7000217806EB01110A68062141E0207EDFF8BB
+:10FA80006481002708F10208012803D002281ED053
+:10FA9000FFDFB5E7A777F8F792FF98F80000032893
+:10FAA00001D165772577607D524951F8200094F89F
+:10FAB000201051B948B161680123091A0022184683
+:10FAC000F8F7E6FE022020769AE7277698E784F892
+:10FAD000205000F0CFF9A07F50B198F80100616884
+:10FAE0000123091A00221846F8F7D2FE257600E015
+:10FAF000277614F82E0F217806EB01110A680021F1
+:10FB0000BDE8F041104700E005E036480078BDE868
+:10FB1000F041F3F77DB9FFF74CFF14F82E0F217871
+:10FB200006EB01110A680521EAE710B52E4C94F89E
+:10FB30002E00202800D1FFDF14F82E0F21782C4A48
+:10FB400002EB01110A68BDE81040042110477CB5A2
+:10FB5000254C054694F82E00202800D1FFDFA06830
+:10FB6000401C00D0FFDF94F82E00214901AA01EBD0
+:10FB70000010694690F90C002844F8F74FFF9DF9F2
+:10FB800004000F2801DD012000E000200099084456
+:10FB90006168084420F07F41A16094F821000028AA
+:10FBA00007D002B00123BDE8704000221846F8F7E4
+:10FBB0006FBE7CBD30B5104A0B1A541CB3EB940FCA
+:10FBC0001ED3451AB5EB940F1AD3934203D9101ADA
+:10FBD00043185B1C14E0954210D9511A0844401C8C
+:10FBE00043420DE080000020840700200000000058
+:10FBF0000405002058840100FF7F841EFFDF0023DE
+:10FC0000184630BD0123002201460220F8F740BE0D
+:10FC10000220F8F7EABDF8F787BE2DE9FC47B14CA2
+:10FC2000054694F82E00202800D1FFDF642D58D31C
+:10FC3000AD4A0021521B71EB010052D394F82E20E3
+:10FC4000A0462046DFF8A49290F82D7009EB02142C
+:10FC5000D8F8000001AA28446946F8F7DFFE9DF9AC
+:10FC60000400002802DD0098401C0090A068009964
+:10FC700062684618B21A22F07F42B2F5800F30D285
+:10FC800008EB8702444692F82520202A0AD009EB87
+:10FC900002125268101A0002C21700EB1260001222
+:10FCA00088421EDBA068401C10D0F8F73DFEA1681A
+:10FCB000081A0002C11700EB11600012022810DDC3
+:10FCC0000120F8F792FD4FF0FF30A0602068284433
+:10FCD000206026F07F402061012084F82300BDE8E9
+:10FCE000FC870020FBE72DE9F0477E4C074694F89F
+:10FCF0002D00A4F1800606EB801010F8170000B963
+:10FD0000FFDF94F82D50A046794C24B1002140F635
+:10FD10006500AFF3008040F6710940F67A0A06EB01
+:10FD2000851600BF16F81700012818D0042810D037
+:10FD300005280ED006280CD01CB100214846AFF390
+:10FD4000008020BF002CEDD000215046AFF3008092
+:10FD5000E8E72A4639460120FEF7C0FEF2E74FF0F9
+:10FD6000010A4FF00009454624B1002140F6810008
+:10FD7000AFF30080504600F05CF885F8239024B182
+:10FD8000002140F68600AFF3008095F82D00FFF7C4
+:10FD9000D3FA064695F8230028B1002CE4D00021C0
+:10FDA00040F68C001FE024B100214FF40960AFF34E
+:10FDB000008005EB860000F1270133463A462630E5
+:10FDC000FFF7F1F924B1002140F69400AFF3008071
+:10FDD00000F024F8824695F8230038B1002CC3D0F7
+:10FDE000002140F69A00AFF30080BDE785F82D6052
+:10FDF000012085F82300504600F01BF8002C04D0A9
+:10FE0000002140F6A700AFF30080BDE8F087354938
+:10FE100081F82D00012081F82300704710B5354886
+:10FE200008B1AFF30080EFF3108000F0010072B66C
+:10FE300010BD10B5002804D12F4808B1AFF30080E1
+:10FE400062B610BD2D480068C005C00D10D0103836
+:10FE500040B2002806DA00F00F0000F1E02090F830
+:10FE6000140D03E000F1E02090F800044009704711
+:10FE70000820704710B51B4C94F82400002804D1CA
+:10FE8000F8F72EFE012084F8240010BD10B5154CA3
+:10FE900094F82400002804D0F8F74BFE002084F8E2
+:10FEA000240010BD10B51C685B68241A181A24F0D1
+:10FEB0007F4420F07F40A14206D8B4F5800F03D2E2
+:10FEC000904201D8012010BD002010BDD0E90032C1
+:10FED000D21A21F07F43114421F07F41C0E9003163
+:10FEE0007047000084070020FF1FA10704050020C1
+:10FEF00000000000000000000000000004ED00E031
+:10FF00002DE9F041044680074FF000054FF001064F
+:10FF100004D55C480560066024F00204E0044FF05C
+:10FF2000FF3705D558484660C0F8087324F480545C
+:10FF3000600003D55548056024F08044E0050FD5E6
+:10FF40005348C0F80052C0F8087352490D60091DAB
+:10FF50000D60504A04210C321160066124F4807453
+:10FF6000A00409D54C484660C0F80052C0F8087398
+:10FF70004A48056024F40054C4F38030C4F3C0310F
+:10FF8000884200D0FFDF14F4404F14D0444846604C
+:10FF9000C0F8087343488660C0F80052C0F8087380
+:10FFA00041490D600A1D16608660C0F808730D6037
+:10FFB000166024F4404420050AD53C48466086601B
+:10FFC000C0F80873C0F848733948056024F4006429
+:10FFD00007F0B2F93748044200D0FFDFBDE8F081F6
+:10FFE00070B520250022134620FA02F1C90719D066
+:10FFF00051B201F01F060124B4404E09B60006F1CB
+:020000040001F9
+:10000000E026C6F88041C6F88042002906DA01F0F1
+:100010000F0101F1E02181F8143D03E001F1E0213D
+:1000200081F80034521CAA42DED370BD70B5224C58
+:100030000D462060FFF764FF2068FFF7D1FF2846D8
+:10004000F8F72BFE06F0EEFD00F0DDF807F074F98E
+:1000500007F0BFF8F2F7AEFEBDE8704006F090BEC4
+:1000600010B5154C2068FFF74BFF2068FFF7B8FF6D
+:1000700007F062F9F8F7A4FE0020206010BD0A2006
+:1000800070470000FC1F004000C0004004E5014034
+:10009000008000400485004000D0004004D50040AE
+:1000A00000E0004000F0004000F5004000B00040DB
+:1000B00008B50040FEFF0FFD8400002070B5264902
+:1000C0000A680AB30022154601244B685B1C4B608A
+:1000D000092B00D34D600E7904FA06F30E681E4218
+:1000E0000FD0EFF3108212F0010272B600D001229D
+:1000F0000C689C430C6002B962B64968016000203C
+:1001000070BD521C092AE0D3052070BD4FF0E021DC
+:100110004FF48000C1F800027047EFF3108111F036
+:10012000010F72B64FF0010202FA00F20A480368AA
+:1001300042EA0302026000D162B6E7E70648002106
+:100140000160416070470121814003480068084018
+:1001500000D00120704700008800002001208107A6
+:1001600008607047012081074860704712480068A6
+:10017000C00700D0012070470F48001F0068C0076B
+:1001800000D0012070470C4808300068C00700D03C
+:1001900001207047084810300068704706490C314C
+:1001A0000A68D20306D5096801F00301814201D132
+:1001B00001207047002070470C0400402DE9F041F9
+:1001C00015460E460446002700F0E7F8A84215D36E
+:1001D000002341200FE000BF94F84220A25CF254BB
+:1001E00094F84210491CB1FBF0F200FB12115B1CA9
+:1001F00084F84210DBB2AB42EED3012700F0D9F80D
+:100200003846BDE8F081704910B5802081F80004BF
+:100210006E49002081F8420081F84100433181F8A5
+:10022000420081F84100433181F8420081F84100E9
+:10023000674806F017FF6648401C06F013FFF2F708
+:1002400033FDBDE8104000F0B4B8402070475F486F
+:1002500000F0A3B80A4601465C48AFE7402070476B
+:100260005A48433000F099B80A460146574843308F
+:10027000A4E7402101700020704710B504465348A0
+:10028000863000F08AF82070002010BD0A46014632
+:100290004E4810B58630FFF791FF08B1002010BD21
+:1002A00042F2070010BD70B50C460546412900D941
+:1002B000FFDF48480068103840B200F050F8C6B27E
+:1002C0000D2000F04CF8C0B2864203D2FFDF01E0FF
+:1002D000F2F732FD224629463C48FFF76FFF00281F
+:1002E000F6D070BD2DE9F041394F002506463F1D7F
+:1002F00057F82540204600F041F810B36D1CEDB2D0
+:10030000032DF5D33148433000F038F8002825D0CC
+:100310002E4800F033F8002820D02C48863000F01A
+:100320002DF800281AD0F2F7E5FC294806F0A2FEC5
+:10033000B0F5005F00D0FFDFBDE8F041244806F0D3
+:10034000AFBE94F841004121265414F8410F401CDF
+:10035000B0FBF1F201FB12002070D3E751E7002857
+:1003600006DA00F00F0000F1E02090F8140D03E031
+:1003700000F1E02090F800044009704710F8411F98
+:100380004122491CB1FBF2F302FB13114078814278
+:1003900001D1012070470020704710F8411F4078BC
+:1003A000814201D3081A02E0C0F141000844C0B202
+:1003B000704710B5064806F05DFE002803D1BDE881
+:1003C0001040F2F782BC10BD0DE000E0B407002041
+:1003D0009000002004ED00E02DE9F0410125280304
+:1003E0004FF0E0210026C1F880011E4CC4F80061E6
+:1003F0000C2000F02CF81C4801680268C94341F346
+:10040000001142F010020260C4F804532560491C38
+:1004100000E020BFD4F80021002AFAD019B9016801
+:1004200021F010010160114807686560C4F80853A5
+:10043000C4F800610C2000F00AF83846BDE8F081ED
+:1004400010B50446FFF7C8FF2060002010BD00F083
+:100450001F02012191404009800000F1E020C0F816
+:100460008012704700C0004010ED00E008C5004059
+:100470002DE9F047FF4C0646FF21A06800EB06126D
+:1004800011702178FF2910D04FF0080909EB0111F4
+:1004900009EB06174158C05900F0F4F9002807DDB0
+:1004A000A168207801EB061108702670BDE8F0877E
+:1004B00094F8008045460DE0A06809EB051141580D
+:1004C000C05900F0DFF9002806DCA068A84600EB60
+:1004D00008100578FF2DEFD1A06800EB061100EBA6
+:1004E00008100D700670E1E7F0B5E24B04460020FD
+:1004F00001259A680C269B780CE000BF05EB0017DD
+:10050000D75DA74204D106EB0017D7598F4204D01C
+:10051000401CC0B28342F1D8FF20F0BD70B5FFF798
+:100520007AFBD44C08252278A16805EB0212895881
+:1005300000F0A8F9012808DD2178A06805EB011179
+:100540004058BDE87040FFF75DBBFFF72FFABDE8EC
+:100550007040F2F75DBC2DE9F041C64C2578FFF7FD
+:100560005AFBFF2D6ED04FF00808A26808EB051665
+:10057000915900F087F90228A06801DD80595DE0FB
+:1005800000EB051109782170022101EB0511425C95
+:100590005AB1521E4254815901F5800121F07F4128
+:1005A00081512846FFF764FF34E00423012203EB66
+:1005B000051302EB051250F803C0875CBCF1000F75
+:1005C00010D0BCF5007F10D9CCF3080250F806C05B
+:1005D0000CEB423C2CF07F4C40F806C0C3589A1AF2
+:1005E000520A09E0FF2181540AE0825902EB4C32A1
+:1005F00022F07F428251002242542846FFF738FF02
+:100600000C21A06801EB05114158E06850F8272043
+:10061000384690472078FF2814D0FFF7FCFA22785C
+:10062000A16808EB02124546895800F02BF9012811
+:1006300093DD2178A06805EB01114058BDE8F04139
+:10064000FFF7E0BABDE8F081F0B51D4614460E464E
+:100650000746FF2B00D3FFDFA00700D0FFDF854850
+:10066000FF210022C0E90247C57006710170427087
+:1006700082701046012204E002EB0013401CE1549A
+:10068000C0B2A842F8D3F0BD70B57A4C0646657882
+:100690002079854200D3FFDFE06840F8256060786C
+:1006A000401C6070284670BD2DE9FF5F1D468B46DB
+:1006B0000746FF24FFF7AFFADFF8B891064699F82E
+:1006C0000100B84200D8FFDF00214FF001084FF0D1
+:1006D0000C0A99F80220D9F808000EE008EB011383
+:1006E000C35CFF2B0ED0BB4205D10AEB011350F8BF
+:1006F00003C0DC450CD0491CC9B28A42EED8FF2C9D
+:1007000002D00DE00C46F6E799F803108A4203D1B7
+:10071000FF2004B0BDE8F09F1446521C89F8022067
+:1007200008EB04110AEB0412475440F802B004210C
+:10073000029B0022012B01EB04110CD040F8012098
+:100740004FF4007808234FF0020C454513D9E90512
+:10075000C90D02D002E04550F2E7414606EB4132B6
+:1007600003EB041322F07F42C250691A0CEB04120F
+:10077000490A81540BE005B9012506EB453103EB2D
+:10078000041321F07F41C1500CEB0411425499F83D
+:1007900000502046FFF76CFE99F80000A84201D0F7
+:1007A000FFF7BCFE3846B4E770B50C460546FFF7C8
+:1007B00032FA064621462846FFF796FE0446FF28F1
+:1007C0001AD02C4D082101EB0411A868415830467D
+:1007D00000F058F800F58050C11700EBD1404013ED
+:1007E0000221AA6801EB0411515C09B100EB412020
+:1007F000002800DC012070BD002070BD2DE9F0470D
+:1008000088468146FFF770FE0746FF281BD0194D2A
+:100810002E78A8683146344605E0BC4206D026460C
+:1008200000EB06121478FF2CF7D10CE0FF2C0AD055
+:10083000A6420CD100EB011000782870FF2804D0EC
+:10084000FFF76CFE03E0002030E6FFF7E1F94146D8
+:100850004846FFF7A9FF0123A968024603EB0413EA
+:10086000FF20C854A878401EB84200D1A87001EB00
+:10087000041001E08008002001EB061100780870E8
+:10088000104613E6081A0002C11700EB11600012AF
+:100890007047000070B50446A0F500002D4EB0F181
+:1008A000786F02D23444A4F500042B48844201D26C
+:1008B000012500E0002500F043F848B125B9B44215
+:1008C00004D32648006808E0012070BD002070BDF8
+:1008D000002DF9D1B442F9D321488442F6D2F3E78E
+:1008E00010B50446A0F50000B0F1786F03D21948A6
+:1008F0000444A4F5000400F023F84FF0804130B127
+:100900001648006804E08C4204D2012003E0144839
+:100910008442F8D2002080F0010010BD10B520B153
+:10092000FFF7DEFF08B1012010BD002010BD10B59B
+:1009300020B1FFF7AFFF08B1012010BD002010BDAE
+:10094000084809490068884201D101207047002009
+:1009500070470000000000200090010020000020EF
+:1009600008000020A4000020BEBAFECA0348044AC2
+:100970000168914201D1002101607047A40000206C
+:10098000BEBAFECA45480021017041701021817035
+:10099000704770B5054616460C460220F2F739F945
+:1009A0003E490120F61E08703D4806603C48083864
+:1009B0000560001F046070BD10B50220F2F729F930
+:1009C00036490120087000F051F836494FF4000014
+:1009D000086010BD10B5314C207888B131494FF412
+:1009E0000000091D086000F04AF8002120B1012034
+:1009F00060702D48006801E061701020A0702170C7
+:100A0000BDE810400020F2F704B9244810B5017881
+:100A100059B12648D0F8000128B100F030F800287C
+:100A200000D0012010BD022010BD407810BD10B5CF
+:100A3000C824641EE4B2FFF7E8FF022803D00128AF
+:100A400000D0002010BD002CF3D1FFDFF9E71348E0
+:100A500010B5017841B100F012F818B112480068E1
+:100A6000C0B210BD102010BD807810BD0F4800210D
+:100A7000C0F80011C0F80411C0F8081170470B4805
+:100A8000D0F8001129B1D0F8041111B1D0F8080143
+:100A900008B100207047012070470000A800002026
+:100AA00010F5004004F5014000F4004000F0004063
+:100AB0004548002101704170704770B506461446E4
+:100AC0000D460120F2F7A5F840480660001D0460BD
+:100AD000001D056070BD70B53B4B012540EA024228
+:100AE0001D703A4B1B1F1A60384A10321160384C87
+:100AF0000026C4F80461374A4FF04071116058B1C4
+:100B0000012800D0FFDFC4F80062256031494FF0B2
+:100B10000070091F086070BDC4F80052256070BDE8
+:100B20002948017871B12B4A4FF040711160284972
+:100B3000D1F8042100211AB1274A1268427000E05E
+:100B4000417001700020F2F764B81F48017841B18C
+:100B50001F48D0F80401002802D01F480068C0B226
+:100B600070474078704770B5002827D01648007845
+:100B700000B9FFDF1648D0F8041100291ED1022366
+:100B8000C0F8043315490A680C68D24342F30012D6
+:100B900044F010040C609C034FF0E025521C02E06E
+:100BA000C5F8804220BFD0F80461002EF8D01AB9F1
+:100BB0000A6822F010020A60C0F8083370BD0449C8
+:100BC0000120886070470000AB00002008F500405D
+:100BD00000F0004008F5014000F4004010ED00E096
+:100BE000FA4808B50021C0F80011C0F80C11C0F88F
+:100BF0001011C0F80411C0F81411C0F81811F4480D
+:100C00000068009008BD70B5F24D00246C702C7027
+:100C100000F02FFD85F82140AC62092105F1140098
+:100C20006C6307F0CDF9EC49601E0860091D08608F
+:100C3000091D0C60091D0860091D0C60091D086074
+:100C4000091D0860091D0860091D0860091D08606C
+:100C5000091D0860091D0860091D0860091D08605C
+:100C600070BDDE4800B5016801F00F01032905D011
+:100C7000006800F00F00042802D0FFDF012000BD53
+:100C8000022000BD70B5D3490268D54C4A61426864
+:100C90008A61007A08770C3C0A7DD14B251F012020
+:100CA00042B10E7E00FA06F21A608E7D0EB122600D
+:100CB00000E02A604A7D002A05D04A7E90401860F4
+:100CC000C97D09B1206070BD286070BD00F0D8BC3E
+:100CD00010B500F0D5FCBD48D0F80001002800D0C8
+:100CE000FFDF10BD10B5012000F0ADFCBD480024B1
+:100CF000046001210160B94A40F25B602832106053
+:100D0000121F40F203101060101F0160B34903204E
+:100D10000860B249962034310860B449B24808608E
+:100D2000B249B3489C310860A9480838091F0860D7
+:100D3000012000F093FCA5491020C1F80403A54848
+:100D400080F82D4010BDA34A0368C2F802308088A5
+:100D5000D080117270479F4890F8210070479D4ADB
+:100D6000517010707047F0B50546840097488B8825
+:100D70002044C0F820360B78D1F8011043EA012155
+:100D8000C0F8001605F1080001279A4C07FA00F692
+:100D900052B1012A00D0FFDF206830432060206874
+:100DA000AF4038432060F0BD2068B043F6E706F05E
+:100DB000FBBB884890F82E007047884AC1781432EF
+:100DC00011600068854900020C31086070472528D1
+:100DD00007D0262807D0272807D00A2807D80422BA
+:100DE00006E0022107E01A2105E0502103E0062277
+:100DF00002EB4001C9B2794A083A1160774944319F
+:100E0000086070477348817A012915D0022912D1F0
+:100E1000417D00290FD0827E0121C37E01FA02F2BA
+:100E200099400A4371490A60007F734A002102EB2E
+:100E30008000C0F810157047017DEAE72DE9F04702
+:100E400082466448847A012C10D0022C7DD1437DE7
+:100E5000002B7AD0694BDFF8A8914FF47A77012CF8
+:100E600006D0467EC47D7CB3012535E0037DEFE7E7
+:100E7000067E847D0CB1012500E000254FF4C86496
+:100E800040F6980C40F6E44801290ED0022A1CD006
+:100E9000012A03D0042A1BD05A4B4446191901F5E4
+:100EA000FA7100BFB1FBF7F123E0022A08D0012A52
+:100EB00002D0042A06D0444649F6FC612144F1E7F9
+:100EC0003C46F9E76446F7E705E04F4B3C46E5E76B
+:100ED0004B466446E2E70025012940D0022A40D073
+:100EE000012A02D0042A3FD0484B03F2E143B3FB6E
+:100EF000F7F1474A491F514411603D4A0021403AE9
+:100F0000C2F84C11310285F0010241EA025141F070
+:100F10000313027F384901EB8204C4F81035847E44
+:100F20003C4D01EB820305EBC401C1F814353A4A8C
+:100F3000C1F81025C27E05EBC200C0F81435244963
+:100F40000839C0F81015012000E006E000FA04F1AD
+:100F5000904001432548001F0160BDE8F08729212A
+:100F6000C7E7294B643BC0E74B46BEE72DE9F0419C
+:100F70000F461649054603201646C1F800021B4CD1
+:100F80002648241F2060384606F046FB304606F00F
+:100F900035FB104815B1012D09D011E001218172F6
+:100FA000416B41F4801141634FF4801007E002214E
+:100FB0008172416B41F4001141634FF400102060D5
+:100FC00032463946BDE8F041002037E700100040C6
+:100FD0001811004090080020000E0040101500403D
+:100FE00018050050FC1F004000000C0408F50140EB
+:100FF000408000404016004000600040A2240200F3
+:10100000D0FB010030D3010068360200C0D40100DB
+:101010004C85004000F001404C8100400000040479
+:1010200008B5FF208DF80000F8480021C0F8101125
+:101030000121016105E000BF9DF80010491E8DF8F7
+:1010400000109DF8001019B1D0F810110029F3D04C
+:101050009DF80000002800D1FFDF08BD2DE9FF5FEB
+:10106000EA4E0746002503209B468946C6F8000243
+:10107000DFF8A083E649C8F80010029806F0CCFA21
+:10108000584606F0BBFAE348E34CA8304FF0010A9B
+:1010900017B1012F1DD02EE0066094F82D00012815
+:1010A00005D002280BD0FFDF84F80AA023E094F8D3
+:1010B0002C205B464846029906F02CFB06E094F88B
+:1010C0002C305A464846029906F0B3FAA16A4518F0
+:1010D000EAE7CE49091D016094F82D0094F82C2010
+:1010E000012802995B4648463BD006F05CFBA16AAA
+:1010F00045180220A072C9480560C649C848A431F5
+:101100000860606B40F400206063D6F80072102421
+:10111000C6F808430020C6F80002BE494FF48029F3
+:10112000091DC1F8009006F50076FFF779FFFFF77B
+:1011300057FD3760C8F80090C6F80441E103C8F8CD
+:101140000010B849C1F84CA0B448001D0068A8427E
+:1011500000D3FFDF029904B05A462846BDE8F05F8D
+:101160006CE606F0A3FAC2E72DE9F041A74CD4F8EB
+:10117000000220F00B06D4F804031027C0F300157A
+:10118000C4F808734FF00008C4F80082A149A648CB
+:10119000091D086004F50074FFF734FEFFF740FFF7
+:1011A00044F8F08C00F065FA2660A4F50074002D78
+:1011B00001D0C4F80473BDE8F08100689B4920F0B9
+:1011C0007F400860704710B5012000F03CFABDE890
+:1011D0001040012000F042BA4FF0E0210220C1F897
+:1011E000000170479249087070479049383908608B
+:1011F000704770B5884D0446A86AA04200D3FFDF4F
+:1012000001202873874900202C61C1F844018348DC
+:10121000001F0460BDE8704000F048BA70B57E4C15
+:10122000064602200D462073FFF71BFD024694F888
+:101230002D0094F82C1001280ED0304606F00BFB40
+:10124000784920610020C1F844012169A06A08445E
+:101250007249091F086070BD2B46304606F0CBFA74
+:10126000EEE76C494FF48000091D08606A48416B45
+:1012700021F4800141630021017370476E4A10B56B
+:1012800002EBC0026B4BC2F81035C2F814150121F5
+:101290008140604801606048426B0A43426310BD70
+:1012A000604801214160C1600021C0F844115B48E1
+:1012B000001F01605848816270475C492431086012
+:1012C0005248D0F8001241F04001C0F800127047B7
+:1012D0004E48D0F8001221F04001C0F800125349E6
+:1012E00000202431086070474848D0F8001221F0EF
+:1012F0001001C0F8001201218161704743480021AC
+:10130000C0F81C11D0F8001241F01001C0F8001212
+:1013100070473E4908B5D1F81C21012A01D00020B0
+:1013200008BD424A0C32126802F07F02524202703B
+:101330000020C1F81C013F481830006800900120CF
+:1013400008BD30B50C00054600D1FFDFE00702D034
+:10135000012C00D0FFDF55B102212F480129417235
+:10136000C4722A4805D0022908D0FFDF30BD012110
+:10137000F3E7D0F8001241F0040103E0D0F80012C6
+:1013800041F00801C0F8001230BD70B5224C1F4B6F
+:101390002246E17A527A8D074FF0010603D5850780
+:1013A00001D5450713D4CD0605D594F82F5015B1B6
+:1013B00094F831505DB10D0702D594F8205035B93D
+:1013C000490702D594F8211009B1C00703D082B1B2
+:1013D000BDE87040C8E662B10025012A2ED0022A7D
+:1013E0003CD0FFDFA06A01222844BDE87040002104
+:1013F00024E508490648091D0860D3F8000220F0DA
+:101400000300C3F80002E67270BD00000010004047
+:101410000000040404F501409008002048850040C5
+:10142000488100400080004000000C043C15004052
+:10143000AD0000200411004000F00140D3F800028C
+:1014400020F00400C3F8000200F013F90123A67293
+:101450001A460021962006F0ECF80FE0D3F80002BF
+:1014600020F00800C3F8000200F003F90220A07287
+:1014700001231A460021962006F018F90546B1E727
+:101480002DE9F047BF4F3878042800D3FFDFDFF89D
+:10149000F8A2DAF84C0108B1FFF7B4FCBB4CBC4928
+:1014A000606B08600026666300F00BF9DFF8E482E9
+:1014B0000546D8F800006062A8F104000068A06248
+:1014C000FFF7CFFB84F82C00A07ADFF8CC9284F8E9
+:1014D0002D00022808D1607830B1D9F800100978C1
+:1014E0000140207888430ED084F82060A80706D5F4
+:1014F0003978AA4A4908606A52F821108847E807F3
+:1015000005D000210AE0012084F82000EEE7A807BA
+:1015100001D5012102E0280707D502219F4A3B7827
+:101520004832A06A52F8232090473878C0071DD16E
+:10153000D9F800104846097801F00F01072913D2A5
+:1015400001680622A01C093106F06DFC40B9217A21
+:10155000D9F800000078B1EBD01F01D1012000E0E4
+:10156000002084F8210001E084F821602846FFF77C
+:101570000CFFE80702D08948083014E0A80709D515
+:1015800086483978183050F8211045F38000401C07
+:1015900088470EE0280702D58048283003E0E80697
+:1015A00006D57E483830397850F82100804700E071
+:1015B000FFDFA07A022819D1207B002816D0CAF8B4
+:1015C000446102280ED0012800D0FFDFA16A206903
+:1015D000884200D8FFDF2169C8F80010BDE8F04755
+:1015E00000F064B82169A06A0144F5E7B5E400B5EC
+:1015F000012802D0022802D0FFDF282000BD1820D9
+:1016000000BD10B541F6A474012802D0022802D012
+:10161000FFDF204610BD41F2883010BD10B541F209
+:10162000D474012802D0022802D0FFDF204610BD6A
+:1016300041F2040010BD00B5012802D0022800D0FC
+:10164000FFDF002000BD00F01F0201219140400992
+:10165000800000F1E020C0F88011704700F01F0208
+:10166000012191404009800000F1E020C0F8801283
+:10167000704746480021417281720121C172704752
+:1016800030B500240546012902D002290BD0FFDF26
+:1016900043480443404810300460424805433E48F4
+:1016A0001430056030BD4FF08074F1E73748416B6E
+:1016B00041F48001416336494FF48000091F0860FE
+:1016C0007047F8B5314C304E0020217B19B1D6F867
+:1016D0004411012907D00023A27A3349012A04D0FA
+:1016E000022A0AD019E00123F6E7D1F80C010128FB
+:1016F00001D0002011E008200FE0D1F80C010128F2
+:1017000006D0002229480068012803D0042002E006
+:101710000222F7E7002010431843D1F81021012AD4
+:101720002ED0002505432248026812F0FF0F03D097
+:10173000D1F81421012A00D0002284F82E2000685C
+:1017400010F0FF0F03D0D1F81801012800D00020BD
+:1017500084F82F0015481030006884F83000FFF737
+:1017600054F9012800D0002084F83100FFF738FA3E
+:101770000020C6F844010F48006800902846F8BDD4
+:101780001025CFE7AD000020008000409008002029
+:1017900008F50140448500400415004070840100B4
+:1017A0000801100000000302001000400014004077
+:1017B000401600404481004010B54348222106F005
+:1017C000DDFB41480024017821F010010170012166
+:1017D00005F00FF93C494FF6FF70263981F8224099
+:1017E00088843A490880488010BDE5E7704700F0DA
+:1017F0005FB8354901607047344908807047324905
+:1018000026398A8CA2F57F43FF3B02D0002101607C
+:1018100008E091F822202C492639012A02D00160E3
+:1018200001207047002070472748263810F8221FF3
+:10183000012908D001210170244823492639008854
+:1018400088840120704700207047204948807047F5
+:101850001D491E4B26398A8C5B889A4205D191F826
+:10186000222012B101600120704700207047164805
+:10187000164A2638818C5288914209D14FF6FF7161
+:10188000818410F8221F19B10021017001207047D6
+:10189000002070470C480D4A2638818C52889142AE
+:1018A00004D190F8220008B1002070470120704751
+:1018B000054926398A8C824205D1002081F8220010
+:1018C0004FF6FF7088847047EE080020AE000020BD
+:1018D00070473C4A012338B1012804D113700868CD
+:1018E000906088889081704753700868C2F8020041
+:1018F0008888D0807047334A10B1012807D00EE0A5
+:10190000507860B1D2F802000860D08804E0107806
+:1019100028B1906808609089888001207047002075
+:101920007047284910B1012802D005E0487800E04E
+:10193000087808B1012070470020704730B50C4688
+:1019400005468DB04FF0030104F1030012B1FEF71C
+:101950008BFC01E0FEF7A7FC60790D2120F0C000B0
+:1019600040F04000607104A806F02AFBE0788DF892
+:101970001F0020798DF81E0060798DF81D0010225F
+:101980002946684606F07BFA684605F0E5F99DF8B9
+:101990002F0020709DF82E0060709DF82D00A07023
+:1019A0000DB030BD10B5002904464FF0060102D03D
+:1019B000FEF75AFC01E0FEF776FC607920F0C000EB
+:1019C000607110BDB2000020FE4A137882F8EF303B
+:1019D000A2F8F00082F8EE10012082F8EC0092F8F4
+:1019E000C00008B192F8BC0082F8F200704770B5F0
+:1019F000F54E0446316891F8FA00002501280DD013
+:101A000091F8F400012818D091F8CA0001281ED0DE
+:101A100091F8EC00012838D0002070BD65701720C7
+:101A2000207051F8FB0FC4F802004868C4F80600A3
+:101A3000087AA07201F8015C32E065700520207020
+:101A4000D1F8F600C4F8020081F8F45028E065707F
+:101A5000112020702022A01CCC3106F010FA0121A8
+:101A6000A171306880F8CA50D648B0F8CE20A0F8EE
+:101A7000F6207268537B80F8F83080F8F4101088F4
+:101A8000FBF78CFBFBF751F80AE065701320207020
+:101A900051F8EE0FC4F802008888E08001F8025C7B
+:101AA000012070BDC848006890F8CA1011B1B0F8A4
+:101AB000CE0070474FF6FF70704770B5C24C20687B
+:101AC00000B9FFDF2068417811B10C25284670BDB0
+:101AD00000254FF4827106F073FA2168FF20087028
+:101AE0007F2081F8360013204884282081F8C80020
+:101AF000012081F8B800002081F8BB00FFF7E8FB67
+:101B0000FEF768FFB14804F0E1FEB048283004F069
+:101B1000DDFEAE48503004F0D9FED7E710B5AA4C30
+:101B2000206800B9FFDF216800204870FFF7C5FF7B
+:101B3000002800D0FFDF10BDA34909680978814261
+:101B400001D101207047002070479F4800B501680F
+:101B500091F82400498CC0F38002C0F340031A447A
+:101B600000F001001044132915D004DC102909D01D
+:101B7000122904D10FE0152908D01D2904D0FFDF58
+:101B8000002000BD924903E0924800BD9049083111
+:101B900031F8100000BD8E490839F9E78A4840F253
+:101BA00071210068806A484370478748006890F850
+:101BB0003500002800D00120704710B5814C207BF3
+:101BC00000F024FE40B1207D04F1150104F04BFA31
+:101BD000082801D0012010BD207B30B1022804D09C
+:101BE0000120BDE81040FFF79CBE0020F9E77649D0
+:101BF000096881F83000704770B50546714890F863
+:101C00002D0004F045FA040018D0102104F031FC36
+:101C1000002813D16C4E01202A463168C876204630
+:101C20001C31FFF78BFE316868481C3104F07BFEE5
+:101C3000BDE870400121654804F084BE70BD2DE907
+:101C4000F041604C074694F82D0004F017FA064660
+:101C500094F82F0004F10E0528B126B1102130466A
+:101C600004F007FCA0B194F83000002824D094F8C8
+:101C70002E00002820D0607B294600F0D8FDA8B1B6
+:101C800004F0ABFA3A462946BDE8F041FFF756BEEC
+:101C9000012060733A4629463046FFF74FFE94F81C
+:101CA0002D102846BDE8F04104F081BA3946284697
+:101CB000BDE8F041FFF776BEBDE8F08170B5424C5B
+:101CC0002168087BB0B1022814D0012048730E317E
+:101CD000FFF711FE2068007B00F098FD216881F875
+:101CE0002F00082081F82D00487B0E3100F096FD72
+:101CF00040B901E00020E9E72168487B0E3100F09F
+:101D000096FD00B10120216881F82E0091F82F0086
+:101D100018B991F82200400706D5087D153104F066
+:101D2000A2F9216881F82D00206800254560FDF7A3
+:101D300033FA216888600020FFF781FF2068C576AC
+:101D400090F82200400703D5BDE87040002053E71B
+:101D500070BD78B51B4904461B4D407B08732A684B
+:101D6000207810706088ADF8000080B200F00101AA
+:101D7000C0F3400341EA4301C0F3800341EA830119
+:101D8000C0F3C00341EAC301C0F3001341EA0311E9
+:101D9000C0F3401341EA4311C0F3801041EA8010C0
+:101DA0005084E07D012830D0022830D0FFDF286841
+:101DB00080F8BA60217B80F82410418C1D2928D03E
+:101DC000616809E010090020C0000020140A00200A
+:101DD000D8840100F18913008162617D80F835109B
+:101DE000A17BC1B1022916D00121017554F80F1F42
+:101DF000C0F81510A188A0F81910217B012900D086
+:101E0000002180F83410002078BD0126CFE702269B
+:101E1000CDE70021D5E70021E7E7FE48006890F80C
+:101E20002200400701D50020704701207047F94A81
+:101E300010B512680023C2F8BC30548C1D2C0BD096
+:101E400079B1936A40F2712463431944491EB1FB8E
+:101E5000F3F1C2F8C41006E0C2F8C43082F8C03012
+:101E600010BDC2F8C43082F8C00010BD0346E94876
+:101E700010B50168D1F8C4204AB1D1F8BC4034B1E2
+:101E80009A4206D90124D01AC1F8C4000EE00124F8
+:101E90000CE091F822100024C90703D040684321C8
+:101EA000008801E043210020FFF78EFD204610BD91
+:101EB000D848006890F8B70008B1002070470120AA
+:101EC000704770B51F2801D2044600E01F24D14D91
+:101ED0000022286880F8B9202246783005F0CFFF2C
+:101EE0002868012180F8974080F8B91070BD10B5BE
+:101EF0001F2800D31F20C74CC2B20023206880F8DF
+:101F0000B83080F8B720983005F0B9FF216801207B
+:101F100081F8B80010BDBF49096881F8BB0070475F
+:101F2000BC48006890F8220000F001007047B948F2
+:101F3000006890F82200C0F340007047002070470E
+:101F4000B448006890F82200C0F3C0007047012038
+:101F50007047012070470120704770B500F085FC84
+:101F6000AC4C206850F8BC1F491C016010F8890C6B
+:101F7000002530B1FFF7ACF9FEF72CFD206880F8A2
+:101F800033502068457090F8C01089B1D0F8BC205B
+:101F900091420DD8022001F09DFA206890F82200AD
+:101FA000C00703D060684321008816E043211BE08E
+:101FB000D0F8C41019B1D0F8BC20914202D990F8E1
+:101FC0003700A8B1022001F085FA206890F82200BD
+:101FD000C00708D060683C210088FFF7F5FCBDE829
+:101FE000704000F038BC3C21BDE870400020EBE4BC
+:101FF000BDE87040002001F06DBA10B501280DD089
+:1020000002280DD004280FD0FFDF8248006890F826
+:10201000BA10BDE810402520FEF758BE252000E08C
+:102020002620FEF7D4FEF0E72720FAE7024600203C
+:10203000D30701D0CB0705D0930705D58B0703D471
+:1020400002207047012070475207FCD54907FAD497
+:10205000042070472DE9F0416E4C206800B9FFDF85
+:1020600020684178B1BB0178FF2934D0002580F881
+:102070003150857080F837502846FFF7B3F8FEF7E7
+:1020800031FE206890F9BB00FEF791FE6248FEF732
+:1020900094FE6148C01EFFF790F82068002190F878
+:1020A0002400FFF7C3FFFFF7A8FF206880F82C503B
+:1020B000FFF792F82068002190F8BA200846FEF752
+:1020C00055FF0F210520FEF74AFE206890F82E10DC
+:1020D00051B902E0FFE70C20EEE590F82F1019B996
+:1020E00090F8220040072AD5FDF756F806462068EA
+:1020F00031468068FDF75EFD484990FBF1F701FB32
+:10210000170041423046FCF750FD014620688160CF
+:1021100041683944416003F0A2FF014620684268EB
+:1021200091420CD8C0E901560120FFF788FD2068D4
+:1021300090F82200400702D50120FFF75DFD2068DE
+:10214000417B0E30FEF7FFFD206890F8B81059B1C2
+:1021500090F8B72080F8772000F19801583005F00A
+:10216000D3FE206880F8B850206890F8B91059B1B3
+:1021700090F8972080F8572000F17801383005F06A
+:10218000C3FE206880F8B9502068254E0021C77E24
+:102190003580304600F056FB2068408C13284FD025
+:1021A00004DC102871D0122804D16BE0152850D01F
+:1021B0001D284ED0FFDF1A491948F639884604F029
+:1021C000ACFB184F1648797B04F0B3FB2168488CB0
+:1021D0001D2807D0152805D091F8772030465831B2
+:1021E00004F0B7FB0E4E042150363046358004F023
+:1021F00070FB4146304604F090FB797B304604F09A
+:1022000098FB2168304691F85720383104F0B1FB33
+:102210000AE00000C0000020CB84010040420F0013
+:10222000140A00201009002003F079FF032106F1B1
+:10223000280003F0AAFF216881F8330000203BE565
+:102240000021304604F045FB0121304600F0FAFA47
+:10225000B1E70121304604F03CFB0121304600F09B
+:10226000F1FA2168304627B11C3104F05CFB0121F2
+:1022700004E0153104F057FB2068017D304604F07E
+:1022800061FB98E7062101E0FFE70221304604F0F8
+:1022900020FB90E7FE494860704770B5FC4C06464D
+:1022A000206890F8312032B1408C1D2800D1FFDF2A
+:1022B000BDE8704051E6002938D1F648FEF795FF99
+:1022C000206890F82C1090F82400FFF7AFFE054628
+:1022D00046B1FFF792FE002201234FF4967110469B
+:1022E000FEF7BCFE216891F82C00284381F82C00F1
+:1022F00091F8242082434FF0010004D14A8C1D2A1A
+:102300000BD081F831004870488C13280FD008DCBE
+:1023100010280BD0122808D109E0002281F82C20C7
+:10232000F1E7152803D01D2801D0FFDF70BDBDE8FF
+:10233000704001210846FFF704B8D54810B5006881
+:10234000417841B90078FF2805D000210846FFF701
+:10235000A4FF002010BD00F088FA0C2010BDCC496D
+:102360000120096881F837007047C949096881F878
+:102370003200704770B5002500F09CFF50B1C44C8E
+:1023800020684178012908D0022901D0032938D0DA
+:10239000FFDF70BDBDE87040DFE581780029F8D12E
+:1023A000418C102917D090F8330020B1FEF704FBC0
+:1023B0004020FEF782FFB7487830FEF716FF20680E
+:1023C00090F8221049070ED490F83500012804D067
+:1023D000032802D002E0002117E0102545F00E018D
+:1023E0000020FEF7AEFF206890F8340008B1FEF739
+:1023F00085FF00219620FEF711FF2168022048701A
+:1024000070BD81780029FBD18178BDE87040012042
+:1024100043E7A2E510B59E4C206890F8340008B15F
+:1024200000F02EFA206890F8330018B1FEF750FF44
+:10243000FEF7D0FA00F03EFF88B12068407802280D
+:1024400000D0FFDF00210120FFF727FF206841783F
+:10245000002903D04078012800D0FFDF10BDBDE87F
+:1024600010407AE510B503F0FEFD044603F0B7FE18
+:1024700038B1204603F00CFE18B1102103F0F9FF2B
+:1024800008B1002010BD012010BD2DE9F041804CA5
+:1024900005460F46206890F8CA0000B1FFDF2168AA
+:1024A000002681F8CC602888A1F8CE006888A1F8C1
+:1024B000E400A888A1F8E600E888A1F8E80095F80B
+:1024C0004C0181F8EA0091F82F0020B1487B0E31D1
+:1024D00000F0ADF940B9216891F8300068B1487B4F
+:1024E0000E3100F09BF940B12068D0F80E10C0F812
+:1024F000D810418AA0F8DC1003E0206840F8D86FBB
+:102500008680644863497830091F0078FF2FC0F344
+:102510008010687651F87F0FC5F81A008988E98322
+:10252000216813D0C1F8DE00E88BA1F8E20001F1C8
+:10253000D2023846D13103F0B5FD00B9FFDF206883
+:1025400010F8D11F41F002010170C5E501F1D20080
+:1025500041F8DE6F8E806A7E01F80D2CD5F81A10D6
+:102560000160E98B8180B7E52DE9F047DFF820A114
+:102570000F460646032809D0FFF7D2FC0446DAF8D6
+:10258000000090F8320020B1012003E0FFF7CFFCFB
+:10259000044600208046FEF70CFC0546032E2CD096
+:1025A0000120814634EA080451D0DAF80000394CA1
+:1025B000564690F83300783460B103F096FD3870D9
+:1025C0000146FF2806D0E01C03F083FD387803F0B5
+:1025D00096FD0543316820780A7DC0F38010904253
+:1025E00005D10622E01C153105F01DFC38B1002094
+:1025F0003978FF290BD0D0B903E00220D1E70120C0
+:10260000F6E7306890F82D00884210D007E030B12E
+:102610002078E11CC0F38010FFF724FF38B10020C0
+:10262000316891F82210490703D598B90FE00120CD
+:10263000F6E77DB9184890F8350008B1484506D14D
+:102640002078E11CC0F38010FFF70CFF10B10020D0
+:10265000BDE8F0870120FBE7F8B5FF208DF800000A
+:10266000012569460520FFF77FFF002859D0084C57
+:1026700022689078E8BB07496068783111F80F6BE1
+:10268000437BC6F3401633404373012306E000004A
+:10269000C0000020140A00201009002051F8086929
+:1026A000C0F80E608E8946828E7B0675CE7B46759D
+:1026B0000E8AC6824E8A46808E8A8680CE8AC680E0
+:1026C0008E6986600E7F06734E7F06F01F060676C3
+:1026D000497F490980F84C1180F8343080F8353052
+:1026E00092F8C81080F8361092F8BB1080F83710B6
+:1026F00000E017E09DF80010FFF7C7FE20680121F9
+:1027000000F8CA1F81788088FFF75EF900F0A3F80F
+:1027100021680020487000F0A8F8012000F0DAFEDF
+:1027200000E000252846F8BDF8B5784C074600259E
+:1027300020684078022800D0FFDF206890F834003D
+:1027400008B100F09DF8724804F0E3F806465FB364
+:102750006F4804F01EF938B3FEF7FDFA20B3062ED9
+:1027600022D2DFE806F021212103213BFF208DF852
+:10277000000069460320FFF7F7FE0028206811D00B
+:1027800090F8341031B190F8FA0018B99DF80000B3
+:1027900000F085F85E482838FEF727FD2168032001
+:1027A000487002E0807800B90125206890F8330075
+:1027B00018B1FEF78DFDFEF70DF91DB100210120C6
+:1027C000FFF76BFD20684178002906D04178012988
+:1027D00003D04078032800D0FFDFF8BDFFF73CFFAF
+:1027E000E1E770B5494E05460C4630688078002810
+:1027F0000BD1FEF736FA03463068214690F8BA202E
+:102800002846BDE8704000F09CBE70BD022803D091
+:10281000032801D00020704701207047012802D111
+:102820004879800901D000207047012070470128B5
+:1028300006D148790121B1EB901F01D101207047E9
+:10284000002070470278202322F0200203EA411181
+:102850000A43027070472D4810B540680088FAF7A7
+:102860009DFCBDE81040FAF751B910B5FEF718FD10
+:10287000FEF7F7FCFEF778FCBDE81040FEF7A3BCBE
+:1028800010B5224C20683630FEF743FD18B9216898
+:102890007F2081F83600BDE81040FEF725BD70B5F9
+:1028A0001A4C0122216881F8FA200A7881F8FB206D
+:1028B000FF280DD001F1FD02FC3103F0F3FB00B95C
+:1028C000FFDF206810F8FC1F41F0020101700DE0ED
+:1028D0000F480078C0F3801081F8FC000C487C3869
+:1028E00050F87F2F41F8FD2F80888880256895F863
+:1028F000360005F203157F2800D1FFDF206810F8AD
+:10290000361F29707F21017070BD0000C0000020BB
+:102910008C0A0020FE484068704770B506460D4698
+:1029200014461046FEF76DFE022C14D0012C14D074
+:10293000042C14D0F74908444FF47A7100F2E140B6
+:10294000B0FBF1F000EB460005442046FEF74FFED9
+:102950002844603070BDF049EDE7F049EBE7F049FD
+:10296000E9E72DE9F0410E460746014614460120ED
+:1029700003F08AFE054697F83500FEF742FE014651
+:1029800097F8350002281CD001281CD004281CD040
+:10299000E04840F2712208444FF47A7100F2E140BD
+:1029A000B0FBF1F178885043C1EB4000041BA4F563
+:1029B000597402F051FB00B11E3CAE4207D22846CA
+:1029C00006E0D548E5E7D548E3E7D548E1E73046F6
+:1029D000A04204D2AE4201D22C4600E034467C62D2
+:1029E000BDE8F0812DE9FF4F89B0044690F83580AD
+:1029F00016989A4640EA0A00079094F84500002588
+:102A0000164619460D2803D00020059011B131E07B
+:102A10000120FAE794F8EC0003282BD1059848B37D
+:102A2000B4F86E01B04225D1D4F8F400C4F8E00047
+:102A3000608840F2E2414843C4F8E400B4F83A0147
+:102A4000B4F8C6100844C4F8E800204602F00EFBB3
+:102A5000B4F87201E08294F870016075B4F8740102
+:102A60006080B4F87601A080B4F87801E08002209C
+:102A700084F8EC00D4F844010490B4F8C600D4F80B
+:102A800040B10090B4F83811D4F834010390BAF191
+:102A9000000F04D094F8000100287DD108E004F56F
+:102AA0009A70029004F5907704F1C009001D07E0C8
+:102AB00004F58C70029004F5827704F58A79001D84
+:102AC0000690208F301A00B20190701A00B20028D0
+:102AD00005DAD4F83001039001200790019894F8AA
+:102AE000EC1041B301297DD002297CD003297BD091
+:102AF000FFDF29460398FCF758F80299012540F2B8
+:102B00007122086006980680002038703D71029896
+:102B10000068B8606088D4F8F4105043C1EB4001FD
+:102B20008048A1F54D718161406988427BD9084692
+:102B3000C9F8001079E1BBF1000F00D1FFDF0121DE
+:102B4000002003F008FE8046E18A40F271204143F4
+:102B500008EB41000A9900F075FDC4F8F0006088A8
+:102B600040F2E24148430A9900F06CFDC4F8F400D9
+:102B700082B22046A16AFFF7F4FE14F8350FFEF783
+:102B80005AFD4FF47A7100F2E140B0FBF1F101EB34
+:102B90000B000090207800E07EE1FEF74CFD02463D
+:102BA00014F8350902283FD001283FD004283FD02F
+:102BB00058495518FEF725FD28444FF47A7100F264
+:102BC000DB50B0FBF1F2E08A40F27121484308EBA0
+:102BD0004000811AD4F8F0000A1A0099551894F8A8
+:102BE000352002E0A8E025E0C6E0617D40F2E24346
+:102BF00011FB03F1203DFFF790FE4A49801C48611C
+:102C000094F83500FEF717FD4FF47A7100F2E140B9
+:102C1000B0FBF1F101EB0B00281AB0F53D7FBFF4DA
+:102C200068AFFFDF65E7FEE03B49C2E73B49C0E72D
+:102C30003B49BEE7E08A40F27122D4F8E4105043E9
+:102C400001EB40000A9900F0FDFCC4F8F000608838
+:102C500040F2E24148430A9900F0F4FCC4F8F40061
+:102C600082B22046A16AFFF77CFE009880BB1698CE
+:102C700070B394F835804046FEF7C3FC0146B8F1C6
+:102C8000020F21D0B8F1010F20D0B8F1040F20D0ED
+:102C9000204840F2712308444FF47A7100F2E14079
+:102CA000B0FBF1F0D4F8F010D4F8E4200144E08A4D
+:102CB000584302EB4000451A4046FEF798FC049941
+:102CC000081A0544203D11E01348E2E71348E0E705
+:102CD00001E01348DDE7E08A40F27122D4F8E41005
+:102CE000504301EB4000D4F8F010451AD4F8E82026
+:102CF000D4F8E010D4F8F00040F2E24301FB020007
+:102D000094F83520617D11FB03F1D0340CE0000014
+:102D1000B40A0020C0D4010004360200A22402003C
+:102D2000D0FB0100C8000020FFF7F7FDFC49486117
+:102D300001202077D03CDCE6628840F27123D4F891
+:102D4000F4105A43C1EB42054543DDE9000210444B
+:102D5000D4F8E820D4F8E0C0801AD4F8F030401E4F
+:102D60000CFB023200FB012094F83520617D40F21B
+:102D7000E24311FB03F14BE0618840F27123D4F888
+:102D8000F4205943C2EB4105454394F844002128FF
+:102D900003D094F84500212809D1B4F86E01301A07
+:102DA00000B2002803DB94F8710100B18046079857
+:102DB00030B3009820BB049810B1BBF1000F00D1D4
+:102DC000FFDF94F83500FEF71CFC0146B8F1020F56
+:102DD00023D0B8F1010F22D0B8F1040F21D0D1488F
+:102DE00008444FF47A7100F2E140B0FBF1F02D1A83
+:102DF00094F83500FEF7FBFB0499081A0544203DC2
+:102E0000DDE900010844D4F8F410424648430021AB
+:102E1000FFF783FDC24948616BE6C348E0E7C3485A
+:102E2000DEE7C348DCE7C9F80000616A084400F542
+:102E3000D270F86002F010F910B1F8681E30F86036
+:102E40007D71B4F8B000801B00B2002801DD0320C2
+:102E5000787105980028169822D0B8B1B4F8D81027
+:102E6000B9B3B4F8DA0000BFA4F8DA0094F8DC20B3
+:102E7000401C42438A4209D27879401E002805DD71
+:102E80007D71B4F8DA00401CA4F8DA00BAF1000F42
+:102E900026D094F80001F8B102200DB0BDE8F08F03
+:102EA0000028DBD194F8EC000028EFD0608840F2D5
+:102EB0007122D4F8F4105043C1EB4001384603F0BE
+:102EC00098FB0004000CE1D0179901B108800120A3
+:102ED000E3E7FFE70020C7E794F83C01FCF7B6FC06
+:102EE00094F83C01394600F093FB18B18AF00100D8
+:102EF00084F801010020D0E7FEB50446FCF74CF948
+:102F00000146D4F83001FCF755FE214600F0A4FB41
+:102F100094F845100D2909D0228FB4F8FE1013182B
+:102F2000994206DB491CA4F8FE1006E0B4F8FE0046
+:102F30000CE0401C1044A4F8FE0094F8020140B9D3
+:102F4000B4F8FE00B4F8B410884202D1401CA4F8D2
+:102F5000FE00B4F83A01724D401CA4F83A01B4F8EE
+:102F60006000B4F85E10401A218F401E084486B2FB
+:102F700018E0287800F039FB074694F84C0100F07F
+:102F800034FB384481B2002002AACDE90002034696
+:102F9000B4F8FE202046FFF725FD002821D00128A7
+:102FA00017D0FFDFB4F8FE00301A00B20028E0DAD4
+:102FB000082084F85400012084F85300204601F0D2
+:102FC000FEFC204600F026FB2879BDE8FE40EFF726
+:102FD0001FBFB4F8FE00BDF808100844A4F8FE00B6
+:102FE000E0E7FEBD2DE9F041524C0327012527758E
+:102FF0000020207494F8280004F1100650B14FF41A
+:103000007A71A069FBF7D1FDA0610021304603F081
+:10301000F0FA10E0002000F05EFB0546FEF7BEFD72
+:1030200005442946A069FBF7C0FDA061294630464A
+:1030300003F0DFFA451C208C411C0A2901D22844E8
+:103040002084606830B1208C401C0A2802D3022002
+:10305000607500E067752846FEF708FF002809D074
+:10306000607A002806D1207B314600F0D1FA002892
+:1030700000D1FFDFB4E42DE9F04106462D480F46AC
+:103080000178274D032909D1017BB14206D140685F
+:1030900028613846BDE8F04100F032BB304600F010
+:1030A000ADFA0621F9F748FF040000D1FFDF3046F2
+:1030B00000F0A4FA2188884200D0FFDF214638467C
+:1030C0002C61BDE8F04100F0D4BA10B5194C20785D
+:1030D00048B101206072FFF748F92078032804D036
+:1030E000207A002800D00C2010BD207BFCF7AEFB1E
+:1030F000207BFCF7F8FD207BFCF72FF800B9FFDF01
+:103100000020207010BD10B5FFF7DFFF00F025FB99
+:103110000848002180F82810C172084610BD000040
+:10312000C8000020C0D4010004360200A22402001E
+:10313000D0FB0100B40A002070B50446012000F065
+:1031400045FAC5B20B2000F041FAC0B2854200D06A
+:10315000FFDF6FF0040000F039FAC5B2192000F06B
+:1031600035FAC0B2854200D0FFDFFE4900200122BF
+:103170000C7188700A704870C870FB490870BDE80F
+:103180007040C0E7F749087070472DE9F047F64CEA
+:10319000064689462078D8BBF448FBF784FF2073A5
+:1031A000202840D0032766602770002565722572AD
+:1031B0007EB1012106F1DC00FDF775F80620F9F774
+:1031C00067FE16F8DC1FB1FBF0F200FB1210401C8A
+:1031D0003070FBF7BBFF40F2F651884200D2084640
+:1031E00000F23D1086B2FEF7B0FCE061FEF7D6FCBF
+:1031F0004FF00108D0B184F80A80002000F06BFA8B
+:103200000644FBF7C9FF3146FBF7CFFCA06100E0A5
+:1032100009E027756775D4492574207B103100F0CB
+:10322000F7F988B90FE00C20BDE8F087FBF7B4FF91
+:103230003146FBF7BAFCA061A57284F82880A9F298
+:103240002650E062E3E7FFDF25840020FFF78DF8DA
+:103250000020E9E77CB50025044680F8EC50A0F892
+:103260003851C048007800F0C0F9064694F84C0187
+:1032700000F0BBF9304481B2002300951A46204685
+:103280000195FFF7AFFB00B1FFDF44F8E85F0120D5
+:1032900044F8085C2071E582A582A57634F8B00C6C
+:1032A000401E24F8B00CA4F8525000207CBDAD495B
+:1032B00048707047AC4810B5417A012409B1002428
+:1032C00009E090F8281031B1416AC06A814202D900
+:1032D0000024FFF744F8204620E770B5A14C0646CD
+:1032E000E088401CE080D4E902016278D6F84051C1
+:1032F00012B12A4603F0A7F9A060854205D896F8D6
+:10330000EC00012801D0E07808B1002070BD012058
+:1033100070BD70B505460C460846FEF772F9022CE2
+:1033200014D0012C14D0042C14D0914908444FF42B
+:103330007A7100F2E140B0FBF1F040F2E2414D431E
+:1033400000F54D70854207D9281A70BD8949EDE70F
+:103350008949EBE78949E9E7002070BDFEB5002601
+:10336000044680F8006190F8BE00002849D194F826
+:10337000EC00032845D1FBF70FFF0146D4F83001DC
+:10338000FCF718FC00283CDD214600F065F9411CE3
+:10339000208F0144A4F8FC10B4F8FC10B4F8B42059
+:1033A000511A09B200292CDD012184F80211B4F868
+:1033B0006010B4F85E20891A491E084485B21AE0EC
+:1033C0006848007800F011F9074694F84C0100F0C5
+:1033D0000CF9384481B202A8CDE90060B4F8FC20B1
+:1033E00001232046FFF7FEFA00280AD0012809D061
+:1033F000022806D0FFDFB4F8FC00281A00B200282B
+:10340000DEDAFEBDB4F8FC00BDF808100844A4F8EC
+:10341000FC00F0E72DE9FC4100250446012902D11A
+:103420005048C17869B1042084F8EC00FBF7C0FD76
+:10343000A4F83A51208FA4F8FE0084F80251BDE8A8
+:10344000FC81007800F0D1F886B294F8EC000127F6
+:10345000032813D00128E9D194F84C0100F0C5F8F5
+:10346000CDE900753044B4F8B42081B20023204681
+:10347000FFF7B8FA0028D9D0FFDFD7E7C4F8E85043
+:10348000C4F8E05094F84C01B43400F0AEF8CDE943
+:103490000075304481B234F8B429E7E710B5062945
+:1034A00016D2DFE801F00509030C0C0D002100E045
+:1034B0000121BDE81040ADE7032180F8EC102DE6B6
+:1034C000B0F8F4108AB2816ABDE81040FFF749BA3B
+:1034D000FFDF23E610B530B12349012807D00228C9
+:1034E0000BD0FFDF1AE6BDE8104000F062B9486A71
+:1034F000BDE81040002100F082B9002081F82800CA
+:10350000FBF756FD17480079BDE81040EFF780BC87
+:1035100070B5144CA178022912D1E18800290FD18D
+:103520002569C5F8440195F83500C835FEF75FF800
+:10353000E96F081AA1680144A160E1680844E060ED
+:1035400070BD70B5054607488478022C18D0064C2B
+:10355000243439B34FF47A76012915D0022917D0D3
+:10356000FFDF70BDC8000020B40A002077300100E2
+:10357000C0D4010004360200A2240200D0FB0100E6
+:10358000046904F5A074E4E71846FEF754F802E075
+:103590001046FEF743F800F2E140B0FBF6F0281ABF
+:1035A0002060DEE72560DCE7EF4810B5007808B161
+:1035B0000020B3E50620F9F75DFC80F00100ADE5E1
+:1035C000E9480078002800D001207047002806DA7A
+:1035D00000F00F0000F1E02090F8140D03E000F17E
+:1035E000E02090F800044009704710B504460C280C
+:1035F00000D3FFDFDD4830F814008FE510B5044636
+:10360000202800D3FFDFD848303030F8140085E59B
+:10361000FCF70AB870B50446002084F8EC0094F872
+:103620003C514FF6FF76202D00D3FFDFCE483030DF
+:1036300020F8156094F83C01FBF78FFD202084F8FA
+:103640003C018EE702460020002904D0C8485143BF
+:10365000B1FBF0F0401C7047002809D0D1F8F420ED
+:10366000498840F271235943C2EB4101B0FBF1F0AC
+:10367000704770B50125BF4E0C46082829D2DFE8F7
+:1036800000F0040F17171228281B204600F02BF912
+:10369000204600F0E3F884F800510220B07060E7A3
+:1036A00001F0D5FC01E0FDF7EBFE84F8005158E78E
+:1036B0002046BDE870401FE494F8EC00042800D0D8
+:1036C000FFDF2046FFF7A6FF3079BDE87040EFF737
+:1036D0009FBBFFDF45E708B500284FF001016846B2
+:1036E00002D0FCF7C1FD01E0FCF7B4FD9DF800003D
+:1036F00042F210710002B0FBF1F201FB120008BDB2
+:1037000070B5994C05462078032800D0FFDF0026CD
+:10371000082D20D2DFE805F0040D1717131F1F1A1C
+:103720006662FEF797FC00B1FFDF924903208870C4
+:1037300017E7FEF702FE0028FAD0FFDF11E7BDE829
+:103740007040FDF79DBEBDE870404BE4207BFBF769
+:1037500004FD267005E7FFDF03E7FEB5854C012079
+:10376000E0704FF6FF750CE00621F9F7E5FB060067
+:1037700000D1FFDF96F83C01FCF7B5FA3046FFF7C1
+:1037800049FF69460620F9F764FB50B1FFDF08E006
+:10379000029830B190F8EC1019B10088A842E3D13A
+:1037A00004E06846F9F733FB0028F1D00020E07010
+:1037B000FEBD70B56C4C0025A07A18B10120FFF752
+:1037C0008AFF0546FEF7EAF94119A069FBF7EDF912
+:1037D0000025A061257403206075607A30B96249C4
+:1037E000207B1031FFF714FF00B9FFDF2584FBF7C2
+:1037F000DFFB60480079BDE87040EFF709BB2DE9B9
+:10380000F041594C0746002084F82800A669E07270
+:103810002070012020720021606802F09AFD60682B
+:10382000C0F83061257B80F83C51C0F84071C0F889
+:1038300034610688202D00D3FFDF4B48303020F85C
+:1038400015606068FFF706FD00B1FFDFFBF7B0FB16
+:1038500048480079BDE8F041EFF7DABA70B505469F
+:10386000FBF774FC95F8356004463046FDF7C9FE59
+:10387000022E2AD0012E2AD0042E2AD03E4940F210
+:10388000712208444FF47A7100F2E140B0FBF1F08C
+:10389000D5F8F410014468885043C1EB4006303E2F
+:1038A000B72C00D8B7242946012002F0EDFE2044B1
+:1038B000341A29460120A4F2193402F0E5FE696A9F
+:1038C0009C30814207D9081A06E02C49D7E72C49D9
+:1038D000D5E72C49D3E700202649A042CC6000D38D
+:1038E000204688603DE610B5044622490020C4F811
+:1038F0004001C880C4F8440194F8010138B9FBF7CD
+:103900004BFCD4F80C11FCF755F9002811DCB4F885
+:10391000FE10208F814201D1B4F8B410081AA4F827
+:10392000B6002187D4F82801C4F80C01C4F830018E
+:1039300014E034F8FC0F34F8C41C401A24F8460C88
+:10394000208824F8C40C2069E0626063A06944F810
+:103950003C0CE069A063208CA087FC3C2046BDE8BD
+:10396000104001F061BA0000B40A0020E8840100B0
+:1039700040420F00C8000020C0D4010004360200FD
+:10398000A2240200D0FB01002DE9F0410E460446BE
+:1039900003F0F3F80546204603F0F1F8044602F080
+:1039A00091FEFA4F010015D0386990F834208A4210
+:1039B00010D090F87A311BB190F87C3123421FD09F
+:1039C0002EB990F83130234201D18A4218D890F8AC
+:1039D0007A01A8B1284602F075FE70B1396991F8F4
+:1039E0003520824209D091F87A0118B191F87D0111
+:1039F000284205D091F87A0110B10120BDE8F0818C
+:103A00000020FBE730B5E14C85B0E06900285CD0D0
+:103A10001421684604F0D4FA206990F83500FDF7C7
+:103A2000F0FD4FF47A7100F5FA70B0FBF1F5206902
+:103A300090F83500FDF7DBFD2844ADF8060020695D
+:103A40000188ADF80010018FADF804104188ADF881
+:103A5000021090F8660130B1A069C11C039102F018
+:103A6000C6FF8DF81000206990F865018DF80800F8
+:103A7000E169684688472069002180F8661180F86E
+:103A800065110399002920D090F8641100291CD1F8
+:103A900090F84410242918D09DF81010039A00299A
+:103AA00013D013780124FF2B11D0072B0DD102293D
+:103AB0000BD15178FF2908D180F864410399C0F8EF
+:103AC00068119DF8101080F8671105B030BD1B29F2
+:103AD000F2D9FAE770B5AD4C206990F845001B2883
+:103AE00000D0FFDF2069002580F86D5090F88C0130
+:103AF00000B1FFDF206990F86E1041B180F86E5080
+:103B00000188A0F8901180F88E510C2108E00188FE
+:103B1000A0F8901180F88E51012180F892110B21AC
+:103B200080F88C110088F9F739FBF8F7EFFF20795E
+:103B3000EFF76EF9206980F8455070BD70B5934C71
+:103B4000A079800729D5A078002826D1626920466F
+:103B5000D17805690C2905F1380069D00CDCA1F198
+:103B600002014FF001060A2916D2DFE801F017150D
+:103B7000414D5E2415291537132967D006DC0D2920
+:103B800049D0112947D0122906D155E0162966D00F
+:103B9000172973D0FF2979D0FFDF70BD012395F875
+:103BA0004720194602F0E1FC0028F6D121690820DF
+:103BB00081F8470070BD1079BDE8704001F0F1BA9E
+:103BC00095F84600C00700D1FFDF01F0A9FA20698F
+:103BD00010F8461F21F00101017070BD95F84500F5
+:103BE000102800D0FFDF2069112180F86D6008E007
+:103BF00095F84500142800D0FFDF2069152180F8D2
+:103C00006D6080F8451070BD95F84500152800D00E
+:103C1000FFDF172005E095F84500152800D0FFDFED
+:103C20001920216981F8450070BDBDE8704051E759
+:103C3000BDE8704001F089BA95F8442001230021C5
+:103C400002F093FC00B9FFDF0E2011E015F8460FDB
+:103C500020F004002870BDE8704001F061BA95F8CA
+:103C600044200123002102F080FC00B9FFDF1C206A
+:103C7000216981F8440070BD00E007E095F8450037
+:103C80001E2801D000B1FFDF1F20CAE7BDE8704049
+:103C900001F052BA3D48016991F84620130702D558
+:103CA00001218170704742F0080281F84620806946
+:103CB000C07881F8A90001F02ABA10B5334C216907
+:103CC0000A88A1F8B82181F8B60191F8340001F012
+:103CD00012FA216981F8BA0191F8350001F00BFA66
+:103CE000216981F8BB01012081F8B401002081F82D
+:103CF0007A012079BDE81040EFF78AB810B5234C5F
+:103D000001230921206990F84420383002F02DFC6D
+:103D100038B12169002001F85C0F087301F8180C14
+:103D200010BD0120A07010BD70B5184C01232146B4
+:103D30002069896990F8442009790E2A01D1122955
+:103D400003D000251D2A03D004E0BDE87040D5E76C
+:103D5000162906D0232A01D1162902D0172909D005
+:103D60000CE000F8445F80F8245040781E2882D090
+:103D70001A2019E090F845201F2A09D0E269002A8C
+:103D800003D0FF2901D180F8663174E7E4000020F8
+:103D900080F8455001F0C4F9206980F85D5090F832
+:103DA0007A010028F1D00020BDE8704085E72DE9B8
+:103DB000F843FE4C206990F844101D2908D00027D4
+:103DC00090F845101F2905D077B300F1440503E0B2
+:103DD0000127F5E700F1450510F8761F41F00401D1
+:103DE0000170A06902F0CFFE4FF001080026F8B183
+:103DF0003946A069FFF7C8FDD0B16A46A1692069BC
+:103E000002F06EFC80B3A06902F0BBFE2169A1F84C
+:103E10006E01098F01F055F938B32069282180F827
+:103E2000541080F8538047E00220A070BDE8F8836A
+:103E3000206990F87A0110B11E20FFF73EFFAFB164
+:103E4000A0692169C07881F8AA0008FA00F1C1F3DD
+:103E5000006000B9FFDF20690A2180F8441090F863
+:103E6000680040B9FFDF06E009E01AE02E7001F0BB
+:103E700057F9FFF70FFF206980F85D60D6E72069EA
+:103E800090F87A0118B10020FFF717FF2E70206913
+:103E900000F1450180F85D608D420DD180F84560EC
+:103EA0000AE020699DF8001080F870119DF801105B
+:103EB00080F8711121202870206900F145018D42A0
+:103EC00003D1BDE8F84301F02BB980F86860ADE795
+:103ED00070B5B64C01230B21206990F8452038308D
+:103EE00002F043FB202650BB20690123002190F8FB
+:103EF0004520383002F039FB0125F0B1206990F8F7
+:103F0000440021281BD0A06902F02DFEC8B1206911
+:103F100090F8761041F0040180F87610A1694A7992
+:103F200002F0070280F83120097901F0070180F8DA
+:103F3000301090F87B311BBB06E0A5709BE6A670A5
+:103F400099E6BDE87040A5E690F87A31C3B900F172
+:103F500034035E788E4205D11978914202D180F8FF
+:103F60005D500DE000F5D7710D7002884A8090F821
+:103F700030200A7190F8310048712079EEF748FF3F
+:103F800021691E2081F84500BDE8704001F0BFB8EE
+:103F900070B5864C206990F84610890707D590F8CF
+:103FA000442001230821383002F0DFFAE8B120690B
+:103FB00090F87000800712D4A06902F0C8FD216952
+:103FC00081F87100A06930F8052FA1F872204088AF
+:103FD000A1F8740011F8700F40F002000870206919
+:103FE00090F87010C90703D00FE00120A07042E6DE
+:103FF00090F84600800700D5FFDF206910F8461FC3
+:1040000041F00201017001F082F82069002590F86A
+:104010004410062906D180F8445080F86850207971
+:10402000EEF7F6FE206990F86C110429DFD180F8D4
+:104030006C512079EEF7ECFE206990F844100029CD
+:10404000D5D180F8685016E670B5584C0123002190
+:10405000206990F84520383002F087FA012578B9B8
+:10406000206990F84520122A0AD001230521383012
+:1040700002F07BFA10B10820A070FCE5A570FAE50B
+:10408000206990F86E0008B901F041F82169A06933
+:10409000C83102F04AFD2169A069A03102F04BFD50
+:1040A000206990F8940100B1FFDF21690888A1F828
+:1040B000960101F5CC71A06902F02FFD2169A0697C
+:1040C00001F5D07102F02EFD206980F89451142181
+:1040D00080F845102079BDE87040EEF799BE70B5C4
+:1040E000324C01230021206990F84520383002F03D
+:1040F0003CFA0125A0B1A06902F0E5FC90B1A069ED
+:104100002169B0F80D00A1F86E01098F00F0D9FF08
+:1041100058B12069282180F8541080F85350AAE53E
+:10412000A570A8E5BDE87040B4E5A06921690279F1
+:1041300081F87021B0F80520A1F8722102F0BAFCD4
+:104140002169A1F87401A06902F0B7FC2169A1F806
+:104150007601A06902F0B4FC2169A1F878010D2074
+:1041600081F8450087E57CB5104CA079C00736D0B2
+:10417000A06901230521C578206990F845203830D1
+:1041800002F0F3F968B1AD1E0A2D06D2DFE805F0A2
+:1041900009090505090905050909A07840F0080085
+:1041A000A070A07800281AD1A06901E0E4000020E6
+:1041B000C57802261DB1012D01D0162D18D1206918
+:1041C00090F8440002F0B9F990B1216991F84400E7
+:1041D0001C280DD01D2803D0162D15D0A6707CBD2F
+:1041E000232081F84400162D02D02A20FFF765FD18
+:1041F0000B2D3AD00BDC76D2DFE805F0312E1B40D8
+:104200009F9F4396549F34002020A0707CBD0120C6
+:10421000132D6AD006DC0C2D41D0112D6FD0122D3C
+:1042200061D165E0162D76D0182D77D0FF2D5AD1AB
+:104230007DE020690123194690F84720383002F0CC
+:1042400094F920BBA06902F066FC216981F8520153
+:10425000072081F8470072E001F007F86FE0FFF7F0
+:104260003EFF6CE000F0E1FF69E0206990F8451046
+:1042700011290BD1122180F8451060E0FFF7E4FE10
+:104280005DE0206990F84500172801D0A67056E03F
+:1042900000F046FF21691B2081F845004FE0FFF741
+:1042A00077FE4CE0206990F84600C00703D0A07864
+:1042B00040F0010021E06946A06902F04AFC9DF847
+:1042C000000000F00501206900F8761F9DF801103C
+:1042D00001F04101417000F01AFF206910F8461FFB
+:1042E00041F0010115E028E0FFE7FFF707FD26E0B8
+:1042F000216991F84610490704D5A0701FE010E02D
+:1043000009E00BE000F003FF206910F8461F41F0C0
+:104310000401017013E0FFF7DBFD10E0FFF747FD3C
+:104320000DE000F061FF0AE0FFF7FEFC07E0E16945
+:1043300019B1216981F8660101E0FFF7ABFC206942
+:10434000F0E92212491C42F10002C0E900127CBDD2
+:1043500070B5F84CA07900074AD5A078002847D15D
+:10436000206990F8AB00FE2800D1FFDF2069FE2114
+:10437000002580F8AB1090F84510192906D180F877
+:104380006D5000F0CDFE206980F84550206990F80E
+:1043900044101C2902D0242921D119E090F84500AD
+:1043A00002F0CBF878B120692321012380F8441072
+:1043B00090F845200B21383002F0D7F878B92A2040
+:1043C000FFF77BFC0BE021691D2081F8440006E02B
+:1043D000012180F8651180F8445080F86850206908
+:1043E00090F84710082903D10221217080F8AB1002
+:1043F00041E4D049096991F870210AB991F8342053
+:1044000081F8342091F871210AB991F8352081F8AA
+:104410003520002801D000204FE4704770B5C54C0E
+:1044200006460D46206990F8AB00FE2800D0FFDF5D
+:104430002269002082F8AB6015B1A2F86A001AE484
+:1044400022F8640F0120107115E470B5B94C0123F6
+:104450000021206990F84420383002F086F80028C6
+:104460003FD0206990F87A1139B390F87B1121BBC5
+:1044700090F8452001230B21383002F076F8E0B99E
+:10448000206990F8340000F036FE0546206990F867
+:10449000350000F030FE0646206990F87C11284671
+:1044A00000F01BFE50B1206990F87D11304600F0FD
+:1044B00014FE18B10020FFF700FC11E02069012371
+:1044C000032190F84520383002F04FF840B92069B8
+:1044D0000123022190F84520383002F046F808B157
+:1044E000002052E400211620FFF798FF01204CE441
+:1044F00070B5904C206990F8AB10FE2978D1A17866
+:10450000002975D190F8472001231946383002F070
+:104510002CF800286CD1206990F8501149B1002185
+:10452000A0F8621090F8511180F8AC100021022020
+:104530005BE090F8452001230421383002F015F8A3
+:10454000054600F0F5FE002852D1284600F01AFF7B
+:1045500000284DD120690123002190F844203830F3
+:1045600002F003F878B120690123042190F8452076
+:10457000383001F0FAFF30B9206990F85C0010B1D2
+:104580000021122031E0206990F844200A2A0DD041
+:10459000002D2DD101230021383001F0E6FF78B144
+:1045A000206990F86C1104290AD105E010F8AA1FBF
+:1045B00081700021072018E090F87000800718D063
+:1045C000FFF743FF002813D120690123002190F851
+:1045D0004420383001F0C9FF002809D0206990F844
+:1045E0006401002804D00021FF20BDE8704015E7D9
+:1045F00009E000210C20FFF711FF206910F8701F5F
+:1046000041F00101017099E43EB505466846FDF7A9
+:10461000F6F800B9FFDF2221009803F0AFFC032178
+:10462000009802F0FBF90098017821F01001017068
+:10463000294602F022FA3F4C0C2D27D00ADCA5F1C6
+:1046400002050A2D16D2DFE805F01C154416161CCB
+:10465000154F1516132D0ED006DC0D2D2CD0112D57
+:1046600021D0122D06D106E0162D29D0172D4CD0C1
+:10467000FF2D55D0FFDFFDF7D7F8002800D1FFDF71
+:104680003EBD2169009891F8AC1017E0E2680098EF
+:104690001178017191884171090A81715188C17144
+:1046A000090A0172E7E70321009802F084FA062163
+:1046B000009802F084FADEE7009806210171DAE73B
+:1046C0000098216991F87C21027191F87D11417166
+:1046D000D1E721690098D03102F031FA21690098C0
+:1046E000A43102F031FAC6E71349D1E90001CDE95E
+:1046F0000101206901A990F8760000F005008DF80D
+:104700000400009802F02AFAB5E7216991F87A01CD
+:1047100000280098D6D111F8342F02714978D6E7D5
+:10472000206990F86721D0F86811009802F0B3F979
+:10473000A1E70000E400002000850100F84810B562
+:10474000006990F84A1041B990F8452001230621EC
+:10475000383001F00AFF002800D0012010BD70B5EC
+:10476000EF4D286990F8481039B1012905D0022988
+:1047700006D0032904D0FFDF39E4B0F8B41041E0DB
+:1047800090F84710082934D0B0F85E10B0F86020D7
+:1047900000248B1C9A4206D3511A891E0C04240C47
+:1047A00001D0641EA4B290F85C1039B190F8442096
+:1047B00001230921383001F0D8FE30B3FFF7BEFFE6
+:1047C00078B129690020B1F85820B1F856108B1C37
+:1047D0009A4203D3501A801E00D0401EA04200D23D
+:1047E00084B20CB1641EA4B22869B0F8B41021449C
+:1047F00008E0B0F85E100329BFD3018FB0F8602045
+:104800001144491CA0F8B0101DE40024ECE770B579
+:104810000C4605464FF4E071204603F0D1FB25809D
+:1048200011E4F8F792BC2DE9F0410D460746062148
+:10483000F8F782FB04003DD094F880010026B8B15F
+:104840006E70072028700DE0268484F88061D4F80B
+:104850008201C5F80200D4F88601C5F80600B4F854
+:104860008A01688194F880010028EDD1AE7094E04F
+:1048700094F88C0190B394F88C010B2813D00C2879
+:1048800001D0FFDF89E02088F8F788FC0746F8F7B9
+:1048900052F978B96E700C20287094F88E01A870C7
+:1048A0002088A88014E02088F8F778FC0746F8F7FD
+:1048B00042F910B10020BDE8F0816E700B20287025
+:1048C00094F88E01A8702088A88094F89201A871AD
+:1048D00084F88C613846F8F728F95EE0FFE794F831
+:1048E000AC0130B16E700E20287084F8AC616F801E
+:1048F00053E094F8940180B16E70082028702088ED
+:104900006880D4F898116960D4F89C11A960B4F853
+:10491000A001A88184F894613FE094F8A20140B11D
+:104920006E7015202870B4F8A401688084F8A26124
+:1049300033E094F8A60170B16E701620287005E07F
+:1049400084F8A661D4F8A801C5F8020094F8A6017D
+:104950000028F5D121E094F8AE0140B1182028706C
+:1049600084F8AE61D4F8B001C5F8020015E094F8FF
+:10497000B40100289FD06E701220287009E000BF9B
+:1049800084F8B461D4F8B601C5F80200B4F8BA01ED
+:10499000E88094F8B4010028F2D101208BE7604848
+:1049A0000021C16101620846704730B55C4D0C467C
+:1049B000E860FFF7F4FF00B1FFDF2C7130BD00218C
+:1049C00080F8441080F8451080F8481090F8BE1028
+:1049D00009B1022100E00321FEF760BD2DE9F0419D
+:1049E0004F4C0546206909B1002104E0B0F8C6101B
+:1049F000B0F8B6201144A0F8C61090F8501139B99B
+:104A000090F8472001231946383001F0AEFD30B14F
+:104A1000206930F8621FB0F85420114401802069E9
+:104A200090F8683033B1B0F86410B0F8B620114493
+:104A3000A0F8641090F96C70002F06DDB0F86A10D1
+:104A4000B0F8B6201144A0F86A1001213D2615B136
+:104A500080F8546013E02278022A0AD0012A11D08B
+:104A6000A2782AB380F8531012F0140F0DD01E2133
+:104A700013E090F8AC20062A3CD016223AE080F8E9
+:104A8000531044E090F8522134E0110702D580F829
+:104A900054603CE0910603D5232180F8541036E0A1
+:104AA000900700D1FFDF21692A2081F854002AE015
+:104AB0002BB1B0F86420B0F866309A4210D2002FC3
+:104AC00005DDB0F86A20B0F866309A4208D2B0F836
+:104AD0006230B0F86020934204D390F850310BB1AB
+:104AE000222207E090F848303BB1B0F85E309342A4
+:104AF00009D3082280F85420C1E7B0F85E20062AC6
+:104B000001D33E22F6E7206990F8531019B12069CD
+:104B1000BDE8F04153E7BDE8F0410021FEF7BEBC1F
+:104B2000E40000202DE9F047FF4C81460D46206946
+:104B30000088F8F745FB060000D1FFDFA078284386
+:104B4000A070A0794FF000058006206904D5A0F878
+:104B50005E5080F8C45003E030F85E1F491C0180AD
+:104B6000FFF7ECFD012740B3E088000506D520697A
+:104B700090F84A1011B1A0F856501EE02069B0F824
+:104B80005610491C89B2A0F85610B0F858208A4235
+:104B900001D3531A00E00023B4F808C00CF1050C4F
+:104BA000634501D880F85C70914206D3A0F8565056
+:104BB00080F8AC712079EEF72BF9A0794FF002085C
+:104BC00010F0600F0ED0206990F8481011B1032941
+:104BD00008D102E080F8487001E080F848800121A7
+:104BE000FEF75CFC206990F84810012904D1E188A7
+:104BF000C90501D580F84880B9F1000F70D1E1886E
+:104C0000890502D5A0F8D85003E030F8D81F491C18
+:104C1000018000F054FBFEF7F5FEFFF769FC00F0A1
+:104C20006AFD0028206902D0A0F8B85003E030F8EF
+:104C3000B81F491C018000F061FD38B1216991F86D
+:104C4000C400022807D8401C81F8C400206990F8ED
+:104C5000C400022804D9206920F8B85F4580057394
+:104C600020690123002190F84520383001F07DFCB7
+:104C700020B9206990F845000C2859D120690123FA
+:104C8000002190F84420383001F06FFC48B32069CF
+:104C90000123002190F84720383001F066FC00B372
+:104CA000206990F84810022942D190F8C400C0B998
+:104CB0003046F7F710FDA0B1216991F8AB00FE284E
+:104CC00036D1B1F8B200012832D981F8BD70B1F8FF
+:104CD0006000B1F85E20831E9A4203DB012004E0ED
+:104CE00031E025E0801A401E80B2B1F8B820238957
+:104CF0009A4201D3012202E09A1A521C92B29042C7
+:104D000000D91046012801D181F8BD5091F8482101
+:104D100092B1B1F8BA20B1F84A118A4201D3012107
+:104D200002E0891A491C89B2884205D9084603E085
+:104D30002169012081F8BD5021690A8F1044A1F832
+:104D4000B400FFF70CFDE088C0F340214846FFF7B0
+:104D500045FE206980F8BE50BDE8F047FCF787BDEE
+:104D6000714902468878CB7818430DD1084600690E
+:104D700042B18979090703D590F84700082803D084
+:104D800001207047FEF7A9BA0020704770B5664C45
+:104D900005460E46E0882843E080A80703D5E807CB
+:104DA00000D0FFDF6661EA074FF000014FF001001D
+:104DB0001AD0A661F278062A02D00B2A14D10AE092
+:104DC000226992F84530172B0ED10023E2E92033F7
+:104DD00002F8370C08E0226992F84530112B03D114
+:104DE00082F8491082F86E00AA0718D56269D27855
+:104DF000052A02D00B2A12D10AE0216991F8452038
+:104E0000152A0CD10022E1E9222201F83E0C06E02D
+:104E1000206990F84520102A01D180F84A10280610
+:104E200001D50820E070A7E42DE9F84F3E4C00259D
+:104E30004FF00108E580A570E5704146257061F3EB
+:104E4000070220619246814680F8BE800088F8F70C
+:104E5000B7F9070000D1FFDF20690088FCF7CCFC20
+:104E600020690088FCF7F1FC2069B0F8B21071B13C
+:104E700090F8AB10FE290FD190F8501191B190F835
+:104E8000472001231946383001F06FFB80B12069BB
+:104E900090F8AB00FE2805D0206990F8AB0000BF69
+:104EA000FFF7B2FB206990F8BF1089B1258118E0A7
+:104EB0002069A0F8625090F8511180F8AC100021E0
+:104EC0000220FFF7ABFA206980F8BD500220E7E727
+:104ED00090F8801119B9018C8288914200D881889C
+:104EE0002181B0F8B610491E8EB2B0F8B810314426
+:104EF000A0F8B81090F8BC1021B1A0F8BA5080F812
+:104F0000BC5004E0B0F8BA103144A0F8BA1030F840
+:104F10005E1F31440180FFF711FC20B1206930F899
+:104F2000561F3144018001E0E40000202069B0F800
+:104F3000B210012902D8491CA0F8B2100EB180F8B5
+:104F4000C45090F8BD10A1B1B0F8B80021898842D2
+:104F50000FD23846F7F7BFFB58B1206990F84811D7
+:104F600039B1B0F8BA10B0F84A01814201D300F06B
+:104F7000C8FB206980F8BD5090F845100B2901D07E
+:104F80000C2915D1028FB0F86E31D21A12B2002A54
+:104F90000EDBD0F87011816090F87411017302215A
+:104FA00001F0D7F9206980F8455080F8788024E036
+:104FB00021290FD1018FB0F86E21891A09B2002979
+:104FC00008DB90F87A01FFF714FA206900F8455FD2
+:104FD000057612E090F84410212901D022290CD145
+:104FE000018FB0F86E01081A00B2002805DB01201D
+:104FF000FFF7FFF9206980F8445020690146B0F8B6
+:10500000B620383001F022FA206990F8481109B131
+:10501000A0F8BA50F9480090F94BFA4A4946504670
+:1050200000F0DCFA216A11B16078FCF727F92069F9
+:105030000123052190F84520383001F096FA002828
+:1050400003D0BDE8F84F00F042BABDE8F88F00F099
+:1050500022BBED49C8617047EB48C069002800D009
+:1050600001207047E84A50701162704710B504463D
+:10507000B0F874214388B0F87611B0F878019A42FC
+:1050800005D1A388994202D1E38898420FD02388A2
+:10509000A4F88431A4F88621A4F88811A4F88A0120
+:1050A000012084F88001D8480079EDF7B1FE012194
+:1050B000204601F04EF9002004F8450F0320E0706F
+:1050C00010BD401A00B247F6FE71884201DC00288C
+:1050D00001DC0120704700207047012802D002281F
+:1050E00005D102E0012904D001E0022901D000200D
+:1050F00070470120704710B5012804D0022804D061
+:10510000FFDF204610BD0124FBE70224F9E7BE487B
+:105110000021006920F86A1F8178491C817070475E
+:10512000B94800B5016911F86C0F401E40B2087013
+:10513000002800DAFFDF00BDB3482421006980F8B1
+:105140004410002180F86411704710B5AE4C2069FE
+:1051500090F86C11042916D190F844200123002105
+:10516000383001F002FA00B9FFDF206990F87010C2
+:10517000890703D4062180F8441004E0002180F858
+:10518000681080F86C11206990F84600800707D5F8
+:10519000FFF7C6FF206910F8461F21F002010170D9
+:1051A00010BD994910B5096991F844200A2A09D11E
+:1051B00091F8AA20824205D1002081F8440081F8AC
+:1051C000680010BD91F84620130706D522F00800AC
+:1051D00081F84600BDE81040A2E7FF2801D0FFDFBC
+:1051E00010BDBDE81040A7E710B5874C206910F846
+:1051F000761F41F004010170A06901F0DEFC162861
+:1052000006D1206990F844001D2802D0232805D03B
+:1052100010BDA06901F0D5FCFEF74FFD216900200B
+:1052200081F8440081F8680010BD10B5764C012368
+:105230000021206990F84520383001F096F930B10E
+:10524000FFF765FF2169102081F8450010BD206936
+:105250000123052190F84520383001F086F908B186
+:10526000082000E00120A07010BD70B5664C01233D
+:105270000021206990F84520383001F076F90125A9
+:1052800080B1A06901F044FC2169A1F86E01098F89
+:10529000FFF717FF40B12069282180F8541080F8EB
+:1052A0005350C0E5A570BEE52169A06901F5B8714C
+:1052B00001F029FC21690B2081F84500B3E510B508
+:1052C000FFF746F8FEF74FFF4F4CA079400708D58F
+:1052D000A07830B9206990F84700072801D1012053
+:1052E0002070FEF72BFCA079C00609D5A07838B94C
+:1052F000206990F845100B2902D10C2180F8451047
+:10530000E07800070ED520690123052190F845209B
+:10531000383001F02AF930B10820A070216900204E
+:1053200081F88C0110BDBDE81040002000F048BBA2
+:1053300010B528BB344C216991F84600C20702D051
+:105340000121092018E082070AD501210C20FFF76E
+:1053500065F8206910F8701F41F0010101700DE03F
+:10536000420702D50121132006E0000708D511F8F5
+:10537000A90FC87001210720FFF750F8012010BDC8
+:10538000002010BD10B5204C216991F8452040B394
+:10539000102A06D0142A07D0152A19D01B2A2BD17F
+:1053A00019E001210B2018E0FAF75AFF0C2816D358
+:1053B00020690821D030FAF757FF28B1206904216D
+:1053C000A430FAF751FF00B9FFDF0121042004E007
+:1053D00000F01FF803E001210620FFF71FF801206D
+:1053E00010BD1E2A08D191F85D0078B991F87A01B4
+:1053F00010B191F87B0148B1002010BD254B010090
+:10540000614D01008D4D0100E400002001211720B5
+:10541000E3E770B5174C0025206990F85311012976
+:105420000AD0022925D190F86E10A9B1062180F882
+:10543000AC100121022017E090F88C11002918D13E
+:1054400000F1900300F1C801002200F5AA7001F0FC
+:105450002CF80121052007E090F87600400701D5DF
+:10546000112000E00D200121FEF7D8FF206980F80F
+:105470005351D8E4E400002011F00C0F6FF00D023E
+:105480000BD0B0F5747F01D2002070475038C1179F
+:1054900000EB916002EBA01003E0022903D002EBC5
+:1054A000D00080B270476FF00E0101EB9000F8E77A
+:1054B000F8480078002800D00C20704710B504464A
+:1054C000FFF7F6FF00B1FFDFF248447210BDF1496B
+:1054D00001200872704770B5EE4934314C6804F110
+:1054E000380580B194F83510204601F0BEF882B23C
+:1054F0001B2114F8353FA87C00F008FC2178BDE89A
+:105500007040FBF7E5BB1F2094F83410F7E72DE956
+:10551000F047E04E814634367468204694F83510E2
+:1055200001F0A3F880B294F83510FFF7A5FF1B2116
+:105530001B2800D90846D74D0746D74868627668C9
+:1055400001203836FFF7C7FFB07C4FF0000840B3AA
+:1055500006F15801D04891E80E1000F1480A8AE897
+:105560000E10B16EC0F86110F16EC0F865102230F7
+:10557000FBF73BFEC848012148300176D6E91412FA
+:10558000C0E90412A0F12602696AFBF796FA94F8C2
+:10559000350000F0B1FB0246F9B20120FBF79BFA9F
+:1055A00004E0686AFBF721FEFBF7BAFAB9F1000FD5
+:1055B0000AD1012294F8353096211046FBF74EFDB2
+:1055C00041469620FBF72AFE94F82C00012801D1D1
+:1055D000FBF794FE02202870BDE8F0872DE9F04724
+:1055E000AC4C8046089F20781D461646894610B967
+:1055F0000EB105B107B9FFDFE761C4E90565002019
+:10560000C4E90D892072E0712071E0706071A14FD2
+:10561000A071A0703437A0817E68354636F8380B0B
+:10562000F7F7CEFDE0622888F7F7B8FD2063FBF7B7
+:1056300059FB95F93700FBF7BAFB05F11200FBF7B0
+:10564000BCFD05F10E00FBF7B8FB0120FBF7CAFD1E
+:10565000B07EFBF7BCFBFBF7BFFD95F83510284685
+:1056600001F003F882B21B2115F8353FB07C00F041
+:105670004DFB2C782146FBF72BFB22460021012015
+:10568000FBF774FC7868D0F8C000FBF7B2FDBDE80A
+:10569000F04701203BE77F4800B50078022800D0A2
+:1056A000FFDF00BD7B4810B534304468FBF7F8FDE0
+:1056B000FBF7D7FDFBF758FDFBF785FDFBF730FA4D
+:1056C00094F82C00012801D1FBF70EFE714CA08943
+:1056D00000F02BFBE269E179E07890470020207030
+:1056E00010BD6C4810B50078022800D0FFDFBDE87F
+:1056F0001040D7E7D6E7674840797047654800799A
+:1057000070476449012088717047624810B5343091
+:10571000446804F13800017B21290BD0407B21280B
+:1057200008D01C2909D01D2907D01F280FD094F8B4
+:10573000340010BD94F8701106E01F2807D094F8CB
+:105740007C0100F0CFFA014694F8340008E094F8A8
+:105750007C0114F8311F084000F0C4FA0146E078DB
+:10576000BDE8104000F0ECBA2DE9F14F4948494F2F
+:105770003430A0F1140B466882B006F138041B25C2
+:1057800060794FF0000A4FF0010958B3012868D042
+:1057900002286AD0032875D0FFDF386A0825B8468A
+:1057A000017821F008010170A37905EAC3031943C8
+:1057B00021F004010170E379042505EA830319430C
+:1057C00021F0100101706779D8F82C00F6F793FFEB
+:1057D0000546FCF75FF8022F60D0012F5ED0032F43
+:1057E0005FD061E0FFF791FF8046FFF78EFF014633
+:1057F000304600F03DFF80B24146FFF73DFE1B28DA
+:1058000000D92846ADF804005846FCF721F830B11D
+:105810004FF48060396A00F08DFA03201FE06A4679
+:1058200001A9F86A00F05CFA386210B194F83510FA
+:1058300029B15846FBF7DDFF84F80590ADE79DF8E8
+:10584000001031B9A0F800A080F802A0012101F0F9
+:10585000E5F8BDF80410386A01F0B5F9022060716E
+:105860009BE75846FBF7C5FF97E7ADF804506A463B
+:1058700001A9F86A00F034FA386200288DD1FFDF00
+:105880008BE7FFE75846FBF7E3FF002885D1FFDFF2
+:1058900083E703E008010020280B0020A84301D083
+:1058A00002E00DB1012100E00021D8F820004546BA
+:1058B000027842EA01110170617C51B361790129DA
+:1058C00027D004F15801FC488EC900F1480888E847
+:1058D0008E00A16EC0F86110E16EC0F86510223034
+:1058E000FBF783FCF448483080F818A0D4E9121282
+:1058F000C0E90412A0F126012A6AFBF7DEF896F847
+:10590000340000F0F9F90246FB210020FBF7E3F830
+:1059100003E0FBF76AFCFBF703F9029830B996F84D
+:105920003430012296210020FBF798FB85F8059082
+:10593000296A0A88EA818978297485F80090BDE887
+:10594000FE8F70B5DD4C054639B9012D05D12079A2
+:10595000401CC0B22071012820D8A1692846884780
+:10596000E0B1A179D44831B1012D04D1417811B908
+:105970000178C90612D5E17981B98DB9CF490E31C7
+:105980000978CA0602D40078C00607D5A07828B9DD
+:10599000A06A28B9608918B1C80601D4012070BD79
+:1059A000002070BD10B5C54CA06A00B9FFDF628948
+:1059B000D4E90910D21C02F062FAA06A606210BD3C
+:1059C0002DE9F0470600BD48BC4D00F134004468A5
+:1059D000686A04F13804477801D0012E03D1296B9D
+:1059E00001F072FF687068784FF000084FF001090D
+:1059F00038B1012817D0022830D0032845D0FFDF66
+:105A0000EAE5012E31D0FFF7CDFF39460122286BA0
+:105A1000F6F7E2FE27E000BF84F8078030E000BF21
+:105A200084F807902CE0012E08D0FFF7BBFF394621
+:105A30000022286BF6F7D0FE022EE1D0D4E9140143
+:105A4000401C41F10001C4E91401E079012802D0B1
+:105A500084F80790C0E584F80780BDE5012E04D0E6
+:105A6000286BF7F73DF8022ECAD0D4E91401401C88
+:105A700041F10001C4E91401E0790128D0D1CBE75C
+:105A8000687ABDE8F047EDF7C3B9012EB8D0286BAE
+:105A9000F7F726F8F4E72DE9F04101468748874DEE
+:105AA000343000274468686A01263834027802F0EE
+:105AB0000302012A1BD0022A19D0032A03D0E87955
+:105AC00040F0040011E000F0C2FF20B3A670A889E6
+:105AD00040F40060A8810120696A00F02BF91EE003
+:105AE000E771BDE8F081E671FBE7E871F9E740781E
+:105AF000A8B1AA8942F40062AA81AA6A002AF0D059
+:105B00001B2808D8287A20B1BDE8F041802000F099
+:105B10000CB90E70E5E7E87940F01000E5E7E079B0
+:105B20000128E0D1DCE770B56448644D3430446846
+:105B300028783834012800D0FFDFA078012630B162
+:105B40000020A0700146042000F0F4F82671286AB5
+:105B50000078C043800706D1E07820B9E6700220C3
+:105B6000296A00F0E7F801210020FFF7EAFE10B1F2
+:105B7000BDE8704096E5BDE870400020C7E42DE91F
+:105B8000F84F4E4F4D4C343700267D6882468DF8D5
+:105B9000006020783835022800D0FFDFA08940F46B
+:105BA0000070A0810020FFF796FCA87CBAF1000FDE
+:105BB0005BD0FAF7D8FFFAF7C8FF4FF0010968B9D0
+:105BC000A87C58B1606A417841B10078E979C0F3A6
+:105BD000C000884202D184F8039059E0606A41789D
+:105BE000618121B1206BF6F7B1FDA06200E0A662F1
+:105BF000A089B84640F02000A0812671786800F1A5
+:105C00003807064690F82C00012816D1FBF76CFBEC
+:105C10003946304600F067FC78B1D8F80400318886
+:105C2000A0F8A811397A80F8AA11797A80F8AB1116
+:105C300080F8A691607AEDF7EBF8606AA9790078B0
+:105C4000C0F38000884205D000F084F8A08940F4B9
+:105C50008070A081606AE9790078C0F3C000884252
+:105C60000AD16846FFF717FF06E008B1FAF7A7FF69
+:105C7000A08940F04000A08151460120FFF761FE5D
+:105C800000289DF8000007D010B10020FFF798FE13
+:105C9000FFF708FDBDE8F88F10B10120FFF790FE77
+:105CA0000020FFF761FD9DF800000028F2D00220DF
+:105CB000FFF786FEEEE70000280B00200801002019
+:105CC00070B5064642480D464468FAF7CAFF0346D7
+:105CD00094F8342029463046BDE87040FDF731BCC9
+:105CE000F6F744BCC10701D001207047800701D5F9
+:105CF000022070470020704700B5012802D002281A
+:105D000002D0FFDF002000BD012000BD70B50C46B1
+:105D1000054619461046FFF7AFFB844200D22046E5
+:105D20000DB1001D80B2C0B270BD294A0021343AC5
+:105D300052691047264A0123343A9370526910473A
+:105D4000002904D0012803D0012901D00220704786
+:105D50000120704770B51E48446894F83D003834FF
+:105D6000002832D0022810D1194D343DE86AF6F7E8
+:105D700029FC00B9FFDFD4E91201401C41F1000108
+:105D8000C4E91201687AEDF743F8002565712079BE
+:105D900020B1257100211020FFF7CCFFE07878B109
+:105DA000E570FBF764FD00B9FFDF00210820FFF775
+:105DB000C1FFD4E91201401C41F10001C4E9120104
+:105DC000A079012802D00120A07170BDA57170BD1D
+:105DD0003C0100202DE9F0410F4606460024FA4D13
+:105DE0000FE000BF05EBC40090F84311B14206D1AB
+:105DF0000622394600F5A27002F015F838B1641C8D
+:105E0000E4B22878A042EDD81020BDE8F081204609
+:105E1000FBE7F0B50746EC4816460478621C0270B2
+:105E200000EBC4050868C5F844018888A5F8480156
+:105E3000102C00D3FFDF85F8437185F84A612046B6
+:105E4000F0BD70B5054600F0F9F910281CD1DE4C04
+:105E50002078401EC0B22070A84215D004EBC002CA
+:105E600004EBC50102F58070D2F84321C1F843214B
+:105E7000D0F84700C1F84701207800F0DFF910287A
+:105E800002D0204480F8035170BD2DE9F047CE4C7C
+:105E90000646A719A078401EC5B2A57097F80381E1
+:105EA000AE422AD004EB051A04EB06190AF10301ED
+:105EB00009F10300102201F0E2FF0AF1830109F168
+:105EC0008300102201F0DBFF601905EB450290F81A
+:105ED000031187F8031106EB460104EB420204EBC1
+:105EE0004101D2F80B31C1F80B31B2F80F21A1F802
+:105EF0000F2190F83B0187F83B0104EBC80090F8B4
+:105F00004A01C00703D14046BDE8F04799E7BDE824
+:105F1000F08710B540F2C311AB4802F02FF8FF2212
+:105F20000821AA4802F022F8A84800210A38417046
+:105F30004FF46171418010BD70B50D460646FFF704
+:105F400049FFA14C102807D004EBC00191F84A1179
+:105F5000C90701D0012070BD6178082910D210282E
+:105F600008D004EBC000012180F84A116078401C81
+:105F70006070EFE7012229463046FFF74AFFF5E758
+:105F8000002070BD70B5904D2878401E44B20AE0E4
+:105F900005EBC40090F84A01C00702D0E0B200F05F
+:105FA0005EF9641E64B2002CF2DA70BD2DE9F04790
+:105FB000984691460C460746FFF70CFF0546102809
+:105FC00005D000F03BF9102801D012209FE77E4E4B
+:105FD000B07808281FD2102D05D10022214638465E
+:105FE000FFF717FF0546B4781022601CB07006EB6F
+:105FF0000417F81C494600F04BFA07F18300102201
+:10600000414600F045FA3019002180F8035180F82C
+:106010003B1108467BE7072079E76B4810B580788D
+:10602000401E44B204E0E0B2FFF72FFF641E64B2EA
+:10603000002CF8DA10BD65490A394870704763488A
+:106040000A384078704740B14AF2B811884204D803
+:106050005E490A39488001207047002070475B483C
+:106060000A384088704710B5FFF7B4FE102803D0F7
+:1060700000F0E4F8102800D1082010BD52498A78B9
+:10608000824203D901EB0010833070470020704733
+:106090004D498A78824203D901EB0010C01C704739
+:1060A00000207047484B10B59C7884420FD91844A3
+:1060B00090F8030103EBC00090F843310B70D0F867
+:1060C00044111160B0F848019080012010BD0020FB
+:1060D00010BD3D4A114491F803213C490A390A7028
+:1060E00002684A6080880881704710B5FAF79FFC03
+:1060F00018B1BDE81040FAF7AABCFF2010BD324924
+:106100008A78824209D9084490F8030101EBC00063
+:1061100090F84A0100F001007047002070472DE917
+:10612000F04700252F46284E2BE000BF06EBC704A2
+:1061300004F5A271884694F84301FFF794FF814665
+:10614000FFF7A6FF94F84A11C90718D060B1B9F15A
+:10615000080F05D206EB090191F83B11012903D084
+:10616000102100F086F950B11849284601F8059031
+:106170006D1C94F843214146EDB2FAF7F4FD7F1C03
+:10618000FFB23078B842D1D8C1E603460F4810B507
+:106190000A380A46407840B10B48817829B11A4440
+:1061A000C01CFAF7F6FB012010BD002010BD064A06
+:1061B00001EB410102EB41010268C1F80B2180882B
+:1061C000A1F80F0170470000980B00204E0100203D
+:1061D00001461022274800F05BB92648F2E726491D
+:1061E0008A78824203D9084490F83B0108B1002024
+:1061F000E8E70120E6E72DE9F0410E46074615469F
+:106200000621304600F035F91B4C58B1002004E05F
+:106210002118401C81F83B51C0B2A1788142F7D8C7
+:106220000120F2E531463846FFF71DFF082803D06C
+:10623000204480F83B51F3E70020E6E50E4910B515
+:10624000034600208A7806E00C1894F803419C422B
+:1062500004D0401CC0B28242F6D8102010BD0649BE
+:106260004A78521E4A7001EBC001002281F84A218F
+:10627000E7E500005B0D0020980B002000F0010115
+:10628000400800F001021144400800F001021144EE
+:10629000400800F001021144400800F001021144DE
+:1062A000400800F001021144400800F001021144CE
+:1062B00001EB5000704710B50024C484448DDB000E
+:1062C0004C43B3FBF2F394FBF2F45B1C44859BB2AA
+:1062D00003FB02F40385B4F5C84F01DD5B1E0385A3
+:1062E0004FF4FA43B3FBF2F35B1CC385438C02EB20
+:1062F000C3035B1EB3FBF2F30384C38B4B43B3FBBB
+:10630000F2F1C18310BD70B50546087B0E4600F062
+:106310001F0008730020287604463019007AFFF722
+:10632000ADFF2919641CC874297EE4B2084428769C
+:10633000052CF2D3C0B2252800D9FFDF70BD0023A1
+:10634000C383428401EBC202521EB2FBF1F101840D
+:10635000704770B50025044600F13806032909D0BE
+:10636000E9B3012967D002294ED101463046BDE884
+:106370007040C8E77821304601F022FEB571F57112
+:1063800035737573F573357475717576B57601204F
+:1063900086F83E00412186F83F10FE2186F87310F2
+:1063A00084F82C50258484F8340084F835002821A2
+:1063B00084F8361060734FF448606080A4F8B050E1
+:1063C000A4F8B250A4F8B450A4F8B650A4F8B85049
+:1063D000A4F8BA5084F8BD5084F8BF5000E014E02F
+:1063E000A4F8C65084F8C450A4F8D850A4F8DA50E1
+:1063F00084F87A5184F87B5184F8485184F85051DC
+:1064000084F8535184F86C5170BDA4F8C65084F8D8
+:10641000BE506188F9480A460844B0FBF1F0A4F880
+:1064200058004BF68030A4F85A00E3883046FFF756
+:1064300042FF21469AE7A4F8C6504188B4F8783163
+:10644000B4F874213046BDE8704034E7037E0BB1E8
+:10645000252B01D9122070472AB14B7B2BB1012B80
+:1064600005D01F2070470020704700F0EEB900F003
+:1064700092B910B500231A4603E0845C2343521CF2
+:10648000D2B28A42F9D30BB1002010BD012010BD59
+:1064900030B5134606E0CC18D51A14F8014C5B1E33
+:1064A0004455DBB2002BF6D130BD70B50E468CB032
+:1064B000144601461D4610226846FFF7E9FF1022E8
+:1064C000314604A8FFF7E4FF684600F045FC08A940
+:1064D0004FF0100228461CB1FFF7DAFF0CB070BD78
+:1064E00001F0CDFCFAE738B505460C466846FAF7E8
+:1064F00010FF002820D09DF900002072A17E61725B
+:1065000094F90A100022411A00D5494295F82D301D
+:106510008B4210DCFF2B0ED0E17A491CC9B2E1722C
+:1065200095F82E30994202D8A17A7F2903D1A07222
+:106530000020E0720122104638BD0C2813D00B2831
+:1065400011D00D280FD01C280DD01D280BD01E28CF
+:1065500009D01F2807D0202805D0212803D02328C0
+:1065600001D0002070470120704710B5A2F10F0341
+:106570000C2939D2DFE801F006080D1215181C3875
+:106580002436382792B32FE0072A30D0082A2ED09D
+:106590002AE00C2A2BD00B2A29D025E00D2A26D060
+:1065A00022E00C2B23D91FE0103A0B2A1FD91BE045
+:1065B000032B1CD990F83600B0B11B2A17D913E071
+:1065C000062A14D010E01C2A11D01D2A0FD01E2A32
+:1065D0000DD01F2A0BD0202A09D0212A07D0232A28
+:1065E00005D001E00E2A02D0002010BDFFE70120F7
+:1065F000FBE72DE9F0410C46054640F2337786680B
+:1066000006E000BFF8F7C8FD3946F8F7CEFAA860F3
+:106610002846F8F78EFF0028F4D094B13046A968D8
+:10662000F9F7C8FA00280CDD2044401EB0FBF4F74F
+:1066300007FB04F13046F8F7B8FAA8603846BDE821
+:10664000F0810020FBE770B5044690420AD2101B8F
+:10665000642800D2642025188D4204D8F9F7DDFAA9
+:1066600008B1284670BD204670BD4FF4A470704735
+:106670004FF4A47070470844184498300AB10421BC
+:1066800000E00021084470472DE9F0410E461B2729
+:10669000384691F8341000F06DF84FF4A474A0421D
+:1066A00000D920460546384696F8351000F062F8C5
+:1066B000A04200D9204601462846BDE8F04100220C
+:1066C0001346D8E7C10701D001207047810701D5E3
+:1066D00002207047400701D508207047002070470E
+:1066E0002DE9F0410546164688460124084600F08B
+:1066F00044FA0746404600F042FA0346FFF7E2FF3D
+:1067000002463846FFF7DEFF52EA000100D10024BE
+:10671000990700D10022B90700D1002095F8341064
+:10672000914200D10022327095F83510814200D19B
+:10673000002070706AB960B9404600F022FA298FD3
+:10674000401A00B247F6FE71884201DC002800DCE6
+:106750000024204673E710B540F6C41254100129F6
+:1067600003D0022902D0FFDF02E008B110463CE767
+:1067700020463AE711F00C0F04D04FF4747101EB8E
+:10678000801006E0022902D0C000703001E08000D5
+:106790003C3080B27047F0B50C7C8B7BCD7B5C408D
+:1067A0004B7C02886B4044EA0323067E5A40002457
+:1067B000D5B2120A95FAA5F592FAA2F22D0E120E92
+:1067C00045EA022202EB0212641C1A44E4B292B2BD
+:1067D000032CEDD35A402523B2FBF3F403FB14231F
+:1067E00001EBD30543762F7A03F00704012505FA60
+:1067F00004F4274204D083761DE00000FFDB05008F
+:106800005643320C521CD2B20023C418E47C94428A
+:1068100013D30024CE18367A05FA04F73E4201D08D
+:10682000521ED2B222B1641CE4B2082CF4D306E0AA
+:1068300004EBC30181760020F0BD121BD2B25B1CB9
+:10684000DBB2052BE1D31F20F0BDF0B5437E0C7EFB
+:10685000012504FB02322523B2FBF3F403FB1422CF
+:1068600001EBD204427602F00703247A05FA03F31F
+:106870001C4201D082761EE0037EB2FBF3F403FBE0
+:106880001422521CD2B20023C418E47C944214D3C4
+:106890000024CE1896F8086005FA04F73E4201D0AD
+:1068A000521ED2B222B1641CE4B2082CF4D306E02A
+:1068B00004EBC30181760020F0BD121BD2B25B1C39
+:1068C000DBB2052BE0D31F20F0BD0000282101F032
+:1068D00055BB30B50546007801F00F0220F00F00DF
+:1068E00010432870092910D2DFE801F005070507D9
+:1068F0000509050B0D00062409E00C2407E02224FD
+:1069000005E0012403E00E2401E00024FFDF6C70A9
+:1069100030BD007800F00F0070470A6840F8032F80
+:106920008988818070470A6840F8092F89888180AA
+:1069300070470278402322F0400203EA81110A43A3
+:1069400002707047027822F0800242EAC11202709F
+:10695000704770B514460E4605461F2A00D9FFDF62
+:106960002246314605F1090001F089FAA41D6C7038
+:1069700070BD70B514460E4605461F2A00D9FFDFCC
+:106980002246314605F1090001F079FAA41D6C7028
+:1069900070BD30B5017801F00F01032920D0052921
+:1069A00021D14578B0F81910B0F81B40B0F8173075
+:1069B000827D222D17D1062915D34FF44865A942AF
+:1069C00011D8B4F5FA7F0ED26AB1082A0BD88A42E0
+:1069D00009D28B4207D8B0F81D00A84205D902E0C1
+:1069E00040780C2801D0002030BD012030BD407817
+:1069F000704700B5027801F0030322F003021A4346
+:106A00000270012905D0022903D0032903D0FFDF3A
+:106A100000BD002100E00121417000BD00B50278F9
+:106A200001F0030322F003021A430270012905D08A
+:106A3000022903D0032903D0FFDF00BD002100E0BD
+:106A40000121417000BD007800F0030070474178DB
+:106A500089B1C0780E2805D00F2803D0102801D0A6
+:106A6000192802D31B2904D905E05B4A105C88422F
+:106A700001D1012070470020704730B50124054640
+:106A8000C170192902D25448445C02E0FF2900D0A9
+:106A9000FFDF6C7030BD70B514460E4605461B2AEC
+:106AA00000D9FFDF6C7022463146E81CBDE870401B
+:106AB00001F0E5B9B0F807007047B0F80900704779
+:106AC000B0F80B00704770B5B0F80720B0F8094077
+:106AD000B0F805300179951F40F67A46B54210D8D6
+:106AE000B4F5FA7F0DD261B108290AD8914208D2D3
+:106AF000934206D8B0F80B00B0F5486F01D80120DA
+:106B000070BD002070BD42680A60007A087170474D
+:106B1000B0F8090070470079704742680A608068E1
+:106B20004860704780890880704750F80E2F0A60CF
+:106B3000406848607047D0F81600086070470A68DF
+:106B400042604968816070470968C1607047007998
+:106B5000704742680A608068486070470A6842600F
+:106B60004968816070470179490704D0407940073E
+:106B700001D00120704700207047007970474079AC
+:106B80007047C08870470CB514A2D2E90012CDE955
+:106B900000120179407901F0070269461DF80220D0
+:106BA000012A04D800F00700085C012801D9002060
+:106BB0000CBD01200CBD0171704700797047417117
+:106BC00070474079704730B50C4605461B2900D9FF
+:106BD000FFDF6C7030BD000008850100000101027C
+:106BE0000102020370B50C46A0F12001312901D346
+:106BF00001200CE041280CD020CC094E94E80E0076
+:106C000006EB8000241F50F8806C2846B0472060B7
+:106C100070BD2046EAF7C8FAF9E706207047000081
+:106C20002485010010B5524800F01CFA00B1FFDFC6
+:106C30004F48401C00F016FA002800D0FFDF10BDBE
+:106C40002DE9F14F4B4ED6F800B00127484800F02F
+:106C500011FADFF81C8128B95FF0000708F1010084
+:106C600000F01EFA444C00254FF00309012060603B
+:106C7000C4F80051C4F80451009931602060DFF875
+:106C8000FCA018E0DAF80000C00614D50E2000F0D1
+:106C900064F8EFF3108010F0010072B600D001200C
+:106CA000C4F80493D4F8001119B9D4F8041101B947
+:106CB00020BF00B962B6D4F8000118B9D4F80401B5
+:106CC0000028DFD0D4F804010028CFD137B1C6F8AE
+:106CD00000B008F1010000F0CDF911E008F1010069
+:106CE00000F0C8F90028B9D1C4F80893C4F80451D9
+:106CF000C4F800510E2000F030F81D4800F0D0F923
+:106D00000020BDE8F88F2DE9F0438DB00D46064612
+:106D100000240DF110090DF1200817E004EB4407E1
+:106D2000102255F82710684601F0A9F805EB8707EF
+:106D300010224846796801F0A2F86846FFF780FF04
+:106D400010224146B86801F09AF8641CB442E5DBB1
+:106D50000DB00020BDE8F08372E700F01F020121B2
+:106D600091404009800000F1E020C0F88012704797
+:106D70005601002004E5004000E0004010ED00E076
+:106D8000AE4900200870704770B5AD4D01232B60EF
+:106D9000AC4B1C68002CFCD0002407E00E68066099
+:106DA0001E68002EFCD0001D091D641C9442F5D302
+:106DB0000020286018680028FCD070BD70B59F4E78
+:106DC0000446A14D3078022800D0FFDFAC4200D34A
+:106DD000FFDF71699D48012903D847F23052944280
+:106DE00001DD03224271491C7161291BC160974971
+:106DF0007078F8F719FC002800D1FFDF70BD70B57E
+:106E00008E4C0D466178884200D0FFDF8E4E082DF3
+:106E10004BD2DFE805F04A041E2D4A4A4A38207852
+:106E2000022800D0FFDF03202070A078012801D0C5
+:106E300020B108E0A06800F07FFD04E004F1080044
+:106E400007C8FFF7A1FF05202070BDE87040F8F7E4
+:106E5000AFB8F8F7A1F901466068F8F7ABFEB042A9
+:106E600002D2616902290BD30320F9F756F912E027
+:106E7000F8F792F901466068F8F79CFEB042F3D249
+:106E8000BDE870409AE7207802280AD0052806D08D
+:106E9000FFDF04202070BDE8704000F0C5B802207C
+:106EA00000E00320F9F739F9F3E7FFDF70BD70B5B3
+:106EB0000546F8F771F9614C60602078012800D030
+:106EC000FFDF6249012008700020087104208D60F6
+:106ED00048715D48C860022020706078F8F7A4FB14
+:106EE000002800D1FFDF70BD10B5544C207838B9B0
+:106EF0000220F9F728F918B90320F9F724F908B1A5
+:106F0000112010BD5248F8F7CEF86070202804D048
+:106F1000012020700020606110BD032010BD2DE90C
+:106F2000F041144600EB84070E4605463F1F00F073
+:106F300016FD4FF080521169484306EB8401091F8A
+:106F4000B14201D2012100E000211CB11269B4EB71
+:106F5000920F02D90920BDE8F0813E4A95420ED336
+:106F6000AF420CD3854205D2874203D245EA0600E0
+:106F7000800701D01020EEE7964200D309B10F2020
+:106F8000E9E7354835490068884205D02246314650
+:106F90002846FFF7F9FE10E0FFF7A6FF0028DAD138
+:106FA000264800218560C0E9036481704FF4A9710F
+:106FB00004FB01F01830FFF77AFF0020CBE770B533
+:106FC0004FF08055044628692249B1FBF0F0844215
+:106FD00001D20F2070BD00F0C2FCA04201D81020E9
+:106FE00070BD1D481D490068884204D0286960436F
+:106FF00000F0A2FC0CE0FFF777FF0028F0D1296930
+:107000000E4861438160012181701548FFF74FFFF1
+:10701000002070BD30B452EA030402D030BC062018
+:10702000704730BC00F0E4BE10B5044C6078F8F74F
+:1070300094F800B9FFDF0020207010BD5801002037
+:1070400004E5014000E40140105C0C006C0D0020E0
+:10705000FF6D010000900100A4000020BEBAFECA2E
+:107060007C5E010000210170084670470146002047
+:1070700008707047EFF3108101F0010172B60278D9
+:10708000012A01D0012200E000220123037001B98E
+:1070900062B60AB1002070474FF400507047E9E72C
+:1070A000EFF3108111F0010F72B64FF00002027081
+:1070B00000D162B600207047F2E700004C49096831
+:1070C0000160002070474A49086000207047012194
+:1070D0008A0720B1012804D042F20400704791676A
+:1070E00000E0D1670020704742490120086042F269
+:1070F0000600704708B504233E4A1907103230B124
+:10710000C1F80433106840F0010010600BE0106813
+:1071100020F001001060C1F808330020C1F8080118
+:10712000354800680090002008BD011F0B2909D8D0
+:10713000304910310A6822F01E0242EA400008601D
+:107140000020704742F205007047000100F18040C6
+:10715000C0F8041900207047000100F18040C0F819
+:10716000081900207047000100F18040D0F80009A4
+:10717000086000207047012801D9072070471F4A86
+:1071800052F8200002680A4302600020704701287C
+:1071900001D907207047194A52F8200002688A4333
+:1071A000026000207047012801D907207047134A68
+:1071B00052F8200000680860002070470200104963
+:1071C0004FF0000003D0012A01D0072070470A6069
+:1071D00070474FF080410020C1F808014FF0E020D7
+:1071E000802180F800140121C0F8001170470000D0
+:1071F000000400400005004008010040E88501004F
+:10720000780500406249634B0A6863499A420968FD
+:1072100001D1C1F310010160002070475C495D4B52
+:107220000A685D49091D9A4201D1C0F31000086047
+:10723000002070475649574B0A68574908319A420F
+:1072400001D1C0F3100008600020704730B5504BEA
+:10725000504D1C6842F20803AC4202D0142802D2FE
+:1072600003E0112801D3184630BDC3004B48184431
+:10727000C0F81015C0F81425002030BD4449454B16
+:107280000A6842F209019A4202D0062802D203E0BB
+:10729000042801D308467047404A012142F83010C3
+:1072A000002070473A493B4B0A6842F209019A4272
+:1072B00002D0062802D203E0042801D30846704712
+:1072C000364A012102EBC00041600020704770B5D2
+:1072D0002F4A304E314C156842F2090304EB80020C
+:1072E000B54204D0062804D2C2F8001807E00428EA
+:1072F00001D3184670BDC1F31000C2F80008002089
+:1073000070BD70B5224A234E244C156842F2090321
+:1073100004EB8002B54204D0062804D2D2F800085B
+:1073200007E0042801D3184670BDD2F80008C0F366
+:1073300010000860002070BD174910B508311848CA
+:1073400008601120154A002102EBC003C3F8101594
+:10735000C3F81415401C1428F6D3002006E00428B6
+:1073600004D302EB8003C3F8001807E002EB8003AC
+:10737000D3F80048C4F31004C3F80048401C0628A2
+:10738000EDD310BD0449064808310860704700007D
+:10739000A4000020BEBAFECA00F5014000F0014082
+:1073A0000000FEFF784B1B6803B19847BFF34F8F77
+:1073B00076480168764A01F4E06111430160BFF349
+:1073C0004F8FFEE710B5EFF3108010F0010F72B68B
+:1073D00001D0012400E0002400F0CDF850B1E9F71D
+:1073E0007FFFF7F7A6FCF8F73BFEEBF7DCFC6949FB
+:1073F0000020086004B962B6002010BD70B50C46CC
+:107400000546EFF3108010F0010F72B601D001268F
+:1074100000E0002600F0AFF818B106B962B6082007
+:1074200070BDE9F7D7FEE9F75FFF02460020430988
+:107430009B0003F1E02300F01F01D3F80031CB40A3
+:10744000D9071BD0202803D222FA00F1C90722D184
+:1074500041B2002906DA01F00F0101F1E02191F8B3
+:10746000141D03E001F1E02191F8001449090829F5
+:1074700011D281B101290ED004290CD0401C6428FE
+:10748000D5D3EBF78FFC4349434808602046F9F712
+:1074900001FA60B904E006B962B641F2010070BDBC
+:1074A000394804602DB12846F9F741FA18B1102483
+:1074B0002CE03A4D19E02878022802D94FF4805484
+:1074C00024E007240028687801D0F8B908E0E8B182
+:1074D00020281BD8A878212818D8012816D001E028
+:1074E000A87898B9E8780B2810D82D49802081F821
+:1074F000140DE9F7F9FE2946F8F798FDF7F7D8FBE0
+:1075000000F060FA2846E9F7BDFE044606B962B607
+:107510001CB1FFF757FF204670BD002070BD10B5AD
+:10752000044600F028F800B101202070002010BDB2
+:107530001C4908600020704710B50C46102808D080
+:1075400011280BD012280CD013280ED0012008606F
+:1075500010BDD4E90001FFF751FF0AE0FFF732FF49
+:1075600007E02068FFF7DBFF03E00E4920680860B2
+:107570000020206010BD074807490068884201D1FB
+:107580000120704700207047700100200CED00E0E2
+:107590000400FA05A4000020BEBAFECAF08501006E
+:1075A0000BE000E00400002000B5C04910F1080F16
+:1075B00019D00CDC10F1280F1DD010F1140F18D0C9
+:1075C00010F1100F13D010F10C0F08D10DE010F1D5
+:1075D000040F06D080B103280ED004280CD0FFDFA2
+:1075E00000BDFC2008E0F82006E0F42004E0F020D4
+:1075F00002E0EC2000E0D820086000BDAB4900B5F7
+:10760000091D012803D0022803D0FFDF00BD03209D
+:1076100000E00420086000BDA54930B1012803D175
+:10762000086840F0010008607047086820F0010019
+:10763000F9E72DE9F0411E4604464FF4C86040F6D4
+:10764000980340F6E4474FF47A75012917D0022ACF
+:1076500024D0012A25D0042A25D0964938460F186F
+:107660003046F9F7CEFF07443046F9F7E4FF3844D7
+:1076700000F27120B0FBF5F0201ABDE8F081022A7B
+:1076800008D0012A02D0042A06D0384649F608510B
+:107690004718E5E72846F9E71846F7E786492846F8
+:1076A000DDE78649DBE786491846D8E770B514461A
+:1076B000064601291CD0022B1DD0012B1ED0042B05
+:1076C0001ED0804DFA351046F9F7A8FF4FF47A71B5
+:1076D000012C17D0022C17D0042C18D0CA00AA1ADB
+:1076E000104400F28920B0FBF1F0301A801E70BD0A
+:1076F00049F6CA65E7E7704D643DE3E76F4DE1E7A2
+:107700006F4DDFE70A46EAE74FF4FA72E7E74FF416
+:10771000FA62E4E72DE9F041144605464FF4C860EB
+:1077200040F6980240F6E4474FF47A7601291BD0E0
+:10773000022B28D0012B29D0042B29D05D493846B3
+:107740000F182046F9F76AFF0146012C23D0022CBE
+:1077500023D0042C24D04FF4FA50381A084464384B
+:10776000B0FBF6F0281A88E7022B08D0012B02D0D4
+:10777000042B06D0384649F608514718E1E7304651
+:10778000F9E71046F7E74C493046D9E74B49D7E7C8
+:107790004B491046D4E73046DFE74FF4FA70DCE798
+:1077A0004FF4FA60D9E770B516460546012918D09E
+:1077B000022B19D0012B1AD0042B1AD0414CFA34C9
+:1077C0001046F9F71EFF04443046F9F734FF204411
+:1077D0004FF47A7100F2E140B0FBF1F0281A801EFC
+:1077E00070BD49F6CA64EBE7334C643CE7E7334CC1
+:1077F000E5E7334CE3E72DE9F04106461D460C462C
+:107800009046104600F048F806EB4601C1EBC61161
+:1078100000EBC1004FF47A76012C14D0022C14D066
+:10782000042C15D0F10047182046F9F7F7FE381A56
+:1078300000F60F60B0FBF6F44046F9F7D8FE20449E
+:107840002844401D19E73146EDE74FF4FA71EAE7A5
+:107850004FF4FA61E7E770B5044615460E46084650
+:10786000F9F7CFFE04EB4401C1EBC411C0EBC10436
+:107870003046F9F7E0FE241A284600F00DF82044BF
+:107880004FF47A7100F6B730B0FBF1F42846F9F7FF
+:10789000AEFE2044401D70BD082803D0042801D04E
+:1078A000F9F7AFBE4DF68830704700000C15004068
+:1078B0005016004030D3010068360200A2240200B6
+:1078C000D0FB0100C0D401002DE9FE430C468046E8
+:1078D000FFF7B9F8074698F80160204601A96A4603
+:1078E000F5F705F905000DD0012F02D00320BDE802
+:1078F000FE83204602AA0199F5F71BF80298B0F81A
+:1079000003000AE0022F14D1042E12D3B8F80300AA
+:10791000BDF80020011D914204D8001D80B2A919B4
+:10792000814202D14FF00000E1E702D24FF00100A6
+:10793000DDE74FF00200DAE70B4A022111600B4944
+:107940000B68002BFCD0084B1B1D18600868002832
+:10795000FCD00020106008680028FCD070474FF071
+:10796000805040697047000004E5014000E4014098
+:1079700002000B464FF00000014620D0012A04D03F
+:10798000022A04D0032A0DD103E0012002E00220E4
+:1079900015E00320072B05D2DFE803F00406080AF0
+:1079A0000C0E100007207047012108E0022106E0BC
+:1079B000032104E0042102E0052100E00621F7F79D
+:1079C0008EBB0000F94805218170002101704170D3
+:1079D0007047F7490A78012A05D0CA681044C86080
+:1079E0004038F8F7B4B88A6810448860F8E700288F
+:1079F00019D00378EF49F04A13B1012B0ED011E0F2
+:107A00000379012B00D06BB943790BB1012B09D15C
+:107A10008368643B8B4205D2C0680EE00379012B7A
+:107A200002D00BB10020704743790BB1012BF9D183
+:107A3000C368643B8B42F5D280689042F2D8012043
+:107A40007047DB4910B501220A700279A2B1002209
+:107A50000A71427992B104224A718268D34C52323F
+:107A60008A60C0681434C8606060F7F795FBCF493E
+:107A700020600220887010BD0322E9E70322EBE7B3
+:107A800070B5044609B1012000E00320C84D002173
+:107A90002970217901B100202871607968B1042032
+:107AA000C24E6871A168F068F7F77FF8A860E068D7
+:107AB0005230E8600320B07070BD0320F0E72DE97C
+:107AC000F04105460226F7F76EFF006800B1FFDFC0
+:107AD000B64C01273DB12878B0B1012805D0022865
+:107AE00010D0032813D027710CE06868C82807D38A
+:107AF000F8F793F820B16868FFF76BFF012603E001
+:107B0000002601E000F05CF93046BDE8F081207805
+:107B10000028F7D16868FFF76AFF0028E3D068689B
+:107B2000017879B1A078042800D0FFDF01216868CE
+:107B3000FFF7A6FF9E49E078F7F776FD0028E1D130
+:107B4000FFDFDFE7FFF77DFF6770DBE72DE9F04739
+:107B5000964C8846E178884200D0FFDFDFF84C92EF
+:107B600000250127924E09F11409B8F1080F75D2CA
+:107B7000DFE808F0040C28527A808D95A07803285D
+:107B800002D0022800D0FFDFBDE8F087A0780328EC
+:107B900002D0022800D0FFDF0420A07025712078D9
+:107BA000002878D1FFF715FF3078012806D0B0689B
+:107BB000E06000F024F92061002060E0E078F7F751
+:107BC00030FCF5E7A078032802D0022800D0FFDFC0
+:107BD000207800286DD1A078032816D0F7F7DCFABA
+:107BE00001464F46D9F80000F7F7E4FF00280EDB06
+:107BF000796881420BDB081AF0606D49E078F7F78D
+:107C000013FD0028C0D1FFDFBEE7042028E00420D8
+:107C1000F8F783FAA570B7E7A078032802D0022806
+:107C200000D0FFDF207888BBA078032817D0F7F7B3
+:107C3000B3FA01464F46D9F80000F7F7BBFF00281A
+:107C4000E5DB79688142E2DB081AF0605849E078A8
+:107C5000F7F7EAFC002897D1FFDF95E740E0052021
+:107C6000F8F75BFAA7708FE7A078042800D0FFDF51
+:107C7000022004E0A078042800D0FFDF0120A168E2
+:107C80008847FFF71CFF054630E004E011E0A078CC
+:107C9000042800D0FFDFBDE8F04700F091B8A078DD
+:107CA000042804D0617809B1022800D0FFDF2078D1
+:107CB00018B1BDE8F04700F08CB8207920B106205B
+:107CC000F8F72BFA2571CDE7607838B13849E078BC
+:107CD000F7F7AAFC00B9FFDF657055E70720BFE79B
+:107CE000FFDF51E73DB1012D03D0FFDF022DF9D1B8
+:107CF0004AE70420C3E70320C1E770B5050004D0BC
+:107D00002A4CA078052806D101E0102070BD08207B
+:107D1000F8F719FA08B1112070BD2848F7F7C3F930
+:107D2000E070202803D00020A560A07070BD032063
+:107D300070BD1E4810B5017809B1112010BD8178C1
+:107D4000052906D0012906D029B1012101700020A2
+:107D500010BD0F2010BD00F03CF8F8E770B5134CD3
+:107D60000546A07808B1012809D155B12846FFF78A
+:107D70003EFE40B1287840B1A078012809D00F20FC
+:107D800070BD102070BD072070BD2846FFF759FE5A
+:107D900003E000212846FFF773FE0549E078F7F776
+:107DA00043FC00B9FFDF002070BD0000740100201B
+:107DB0007C0D00203D860100FF1FA1074D7B0100C7
+:107DC0000A4810B5006900F019F8BDE81040F7F74F
+:107DD000EFB8064810B5C078F7F7BFF900B9FFDF74
+:107DE0000820F8F79AF9BDE81040EBE5740100208F
+:107DF000094A1060101D0160002070477047002084
+:107E00007047054B02465B4210201344FC2B01D8FF
+:107E10001160002070470000000600407047704766
+:107E200070477047704740EA010310B59B070FD1B8
+:107E3000042A0DD310C808C9121F9C42F8D020BADA
+:107E400019BA884201D9012010BD4FF0FF3010BD92
+:107E50001AB1D30703D0521C07E0002010BD10F860
+:107E6000013B11F8014B1B1B07D110F8013B11F826
+:107E7000014B1B1B01D1921EF1D1184610BD032AE4
+:107E800040F2308010F0030C00F0158011F8013B37
+:107E9000BCF1020F624498BF11F801CB00F8013B1E
+:107EA00038BF11F8013BA2F1040298BF00F801CBE2
+:107EB00038BF00F8013B11F0030300F02580083AB9
+:107EC000C0F0088051F8043B083A51F804CBA0E810
+:107ED0000810F5E7121D5CBF51F8043B40F8043B65
+:107EE000AFF30080D20724BF11F8013B11F801CB9A
+:107EF00048BF11F8012B24BF00F8013B00F801CB6B
+:107F000048BF00F8012B704710B5203AC0F00B8035
+:107F1000B1E81850203AA0E81850B1E81850A0E88D
+:107F20001850BFF4F5AF5FEA027C24BFB1E81850E7
+:107F3000A0E8185044BF18C918C0BDE810405FEA57
+:107F4000827C24BF51F8043B40F8043B08BF7047D3
+:107F5000D20728BF31F8023B48BF11F8012B28BFD8
+:107F600020F8023B48BF00F8012B704702F0FF03E6
+:107F700043EA032242EA024200F002B84FF0000254
+:107F80000429C0F0128010F0030C00F01B80CCF12B
+:107F9000040CBCF1020F18BF00F8012BA8BF20F899
+:107FA000022BA1EB0C0100F00DB85FEAC17C24BFED
+:107FB00000F8012B00F8012B48BF00F8012B704797
+:107FC0004FF0000200B5134694469646203922BF72
+:107FD000A0E80C50A0E80C50B1F12001BFF4F7AFBD
+:107FE000090728BFA0E80C5048BF0CC05DF804EB9F
+:107FF000890028BF40F8042B08BF704748BF20F80D
+:10800000022B11F0804F18BF00F8012B704770470A
+:108010007047704770470000FEDF04207146084239
+:1080200019D10699124A914215DC0699023948780D
+:10803000DF2810D10878FE2807D0FF280BD14FF099
+:1080400001004FF000020B4B184741F2010000996C
+:10805000019A084B1847084B002B02D01B68DB68BD
+:1080600018474FF0FF3071464FF00002014B1847A0
+:1080700000900100A5730100040000201848194970
+:108080007047FFF7FBFFE9F789F800BD4FF4805018
+:1080900015490968884203D1144A13605B68184780
+:1080A00000BD000020BFFDE74FF480500E49096875
+:1080B000884210D10E4B18684FF0FF318842F1D042
+:1080C00080F308884FF02021884204DD09480268C7
+:1080D00003210A4302600848804708488047FFDFC1
+:1080E000900D0020900D00200000002004000020D2
+:1080F00000900100140900406D0901008D8001000D
+:1081000004207146084202D0EFF3098101E0EFF349
+:108110000881886902380078102813DB20280FDBDB
+:108120002C280BDB0A4A12680A4B9A4203D16028BA
+:1081300004DB094A1047022008607047074A1047CD
+:10814000074A1047074A12682C321268104700008D
+:10815000A4000020BEBAFECAED120000E56B0100CB
+:1081600039750100040000200D4B0E4908470E4BE5
+:108170000C4908470D4B0B4908470D4B0949084767
+:108180000C4B084908470C4B064908470B4B05495F
+:1081900008470B4B034908470A4B024908470000B0
+:1081A000D98C0000A12E00008D2C00009B890000BE
+:1081B0002F890000132D0000F3120000752C000021
+:1081C000452E0000A9110000717F00005F810000B2
+:1081D000BF820000E38200001D8300005183000085
+:1081E0008D830000BD8300002B8400007B80000095
+:1081F0006F1200006F1200000920000053200000E1
+:1082000075200000FD20000019220000DB22000084
+:108210000D230000F9230000D92400002B250000C5
+:10822000AD250000CD2500000B2A00002F2A0000FC
+:108230005F290000B3290000612A0000F52A000030
+:10824000333D00000D3E0000494100004742000060
+:10825000BD420000274300008B4300007312000062
+:108260007F440000EB440000EF250000F5250000EE
+:1082700073120000731200007312000073120000EA
+:10828000FF25000037260000731200007312000063
+:10829000731200006F1200006F1200006F120000D6
+:1082A0006F1200006F1200006F1200006F120000CA
+:1082B0006F120000F75200007D5300009953000038
+:1082C000B553000043550000DF530000E9530000A0
+:1082D0002B5400004D540000295500006B55000040
+:1082E0006F1200006F120000DB6D0000FB6D0000DC
+:1082F000FD6D0000416E00006F6E00005D6F0000BC
+:10830000EB6F0000FF6F00004D7000003D7100003A
+:10831000E37200000D740000EF5D000025740000A2
+:108320006F1200006F120000731200007312000041
+:10833000731200007312000073120000100110018C
+:108340003A0200001A02000405060000B37A000099
+:10835000A17A0000FFFFFFFF0000FFFF37B300001E
+:108360009D1B00009D4E0000395E000073780000E8
+:1083700000000000876B0000676B0000D56B0000F9
+:10838000795200003B5200005B520000EFB1000048
+:108390007DB2000041370000F56B000000000000D6
+:1083A000256C0000C7520000000000000000000023
+:1083B0000000000000000000C1370000513500003F
+:1083C00051350000E51F00009DB20000BB600000B9
+:1083D000AF4D00000F4801007F3500007F350000E1
+:1083E00007200000C9B200003F610000214E0000DC
+:1083F0002348010070017001400034005C0024003B
+:10840000C00100000300656C746200000000000001
+:1084100000000000000000000000870000000000D5
+:1084200000000000000000000000BE83605ADB0B6B
+:10843000376038A5F5AA9183886C00000100000020
+:1084400001D70000C9E50000000000010206030496
+:10845000050000000700000000000000060000000A
+:108460000A0000003200000073000000B4000000A9
+:10847000113501000000000015240100E356010041
+:108480000000000000000000292701007F5B0100C0
+:10849000000000000000000075230100275B0100C0
+:1084A000000000000000000013240100F556010048
+:1084B0000000000000000000E3270100C15C010093
+:1084C0000000000000000000555555D6BE898E0002
+:1084D0000000C706C70CC71200006B030F06B308E5
+:1084E0000000B704A708970CF401FA009600640096
+:1084F0004B0032001E0014000A00050002000100BB
+:1085000000410000000000000C0802170D010102EC
+:1085100009090101060209181803010109090303E9
+:1085200005000000057201001D7201003572010096
+:108530004D7201007D720100A5720100CF72010031
+:1085400003730100BF6F01001F6F01001570010070
+:10855000037E01006570010075700100A1700100CB
+:10856000730201007B0201008D020100CF70010047
+:10857000E9700100BD700100C7700100F5700100D5
+:108580002B7101001B6C01004B710100597101003E
+:1085900067710100777101008F710100A7710100FF
+:1085A000BD7101001B6C010000000000078B000082
+:1085B0005D8B0000738B000071790100416C01003C
+:1085C000076D0100FB7C0100337D01005D7D010032
+:1085D000BD000100410401001B6C01001B6C010087
+:1085E0001B6C01001B6C01001C05004020050040B5
+:1085F000001002001486010008000020880100001D
+:10860000441100004886010090010020000C000089
+:108610008011000001190545100E002036010001EF
+:1086200000703720FB349B5F80041B8000100D21FD
+:10863000F7070020B40700203A0800200581100940
+:088640000020024C10000000B4
+:00000001FF
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/softdevice/s112/toolchain/armgcc/armgcc_s112_nrf52810_xxaa.ld b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/softdevice/s112/toolchain/armgcc/armgcc_s112_nrf52810_xxaa.ld
new file mode 100644
index 0000000..fa349c7
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/softdevice/s112/toolchain/armgcc/armgcc_s112_nrf52810_xxaa.ld
@@ -0,0 +1,33 @@
+/* Linker script to configure memory regions. */
+
+SEARCH_DIR(.)
+GROUP(-lgcc -lc -lnosys)
+
+MEMORY
+{
+ FLASH (rx) : ORIGIN = 0x19000, LENGTH = 0x17000
+ RAM (rwx) : ORIGIN = 0x20000e00, LENGTH = 0x5200
+}
+
+SECTIONS
+{
+}
+
+SECTIONS
+{
+ . = ALIGN(4);
+ .mem_section_dummy_ram :
+ {
+ }
+
+} INSERT AFTER .data;
+
+SECTIONS
+{
+ .mem_section_dummy_rom :
+ {
+ }
+
+} INSERT AFTER .text
+
+INCLUDE "nrf_common.ld"
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/softdevice/s112/toolchain/iar/iar_s112_nrf52810_xxaa.icf b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/softdevice/s112/toolchain/iar/iar_s112_nrf52810_xxaa.icf
new file mode 100644
index 0000000..e2e04b9
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/softdevice/s112/toolchain/iar/iar_s112_nrf52810_xxaa.icf
@@ -0,0 +1,36 @@
+/*###ICF### Section handled by ICF editor, don't touch! ****/
+/*-Editor annotation file-*/
+/* IcfEditorFile="$TOOLKIT_DIR$\config\ide\IcfEditor\cortex_v1_0.xml" */
+/*-Specials-*/
+define symbol __ICFEDIT_intvec_start__ = 0x19000;
+/*-Memory Regions-*/
+define symbol __ICFEDIT_region_ROM_start__ = 0x19000;
+define symbol __ICFEDIT_region_ROM_end__ = 0x2ffff;
+define symbol __ICFEDIT_region_RAM_start__ = 0x20000e00;
+define symbol __ICFEDIT_region_RAM_end__ = 0x20005fff;
+export symbol __ICFEDIT_region_RAM_start__;
+export symbol __ICFEDIT_region_RAM_end__;
+/*-Sizes-*/
+define symbol __ICFEDIT_size_cstack__ = ;
+define symbol __ICFEDIT_size_heap__ = ;
+/**** End of ICF editor section. ###ICF###*/
+
+define memory mem with size = 4G;
+define region ROM_region = mem:[from __ICFEDIT_region_ROM_start__ to __ICFEDIT_region_ROM_end__];
+define region RAM_region = mem:[from __ICFEDIT_region_RAM_start__ to __ICFEDIT_region_RAM_end__];
+
+define block CSTACK with alignment = 8, size = __ICFEDIT_size_cstack__ { };
+define block HEAP with alignment = 8, size = __ICFEDIT_size_heap__ { };
+define block RO_END with alignment = 8, size = 0 { };
+
+initialize by copy { readwrite };
+do not initialize { section .noinit };
+
+keep { section .intvec };
+place at address mem:__ICFEDIT_intvec_start__ { readonly section .intvec };
+place in ROM_region { readonly,
+ block RO_END };
+place in RAM_region { readwrite,
+ block CSTACK,
+ block HEAP };
+
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/softdevice/s132/doc/s132_nrf52_6.0.0_licence-agreement.txt b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/softdevice/s132/doc/s132_nrf52_6.0.0_licence-agreement.txt
new file mode 100644
index 0000000..a71adee
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/softdevice/s132/doc/s132_nrf52_6.0.0_licence-agreement.txt
@@ -0,0 +1,35 @@
+Copyright (c) 2007 - 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, except as embedded into a Nordic
+ Semiconductor ASA integrated circuit in a product or a software update for
+ such product, 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.
+
+4. This software, with or without modification, must only be used with a
+ Nordic Semiconductor ASA integrated circuit.
+
+5. Any software provided in binary form under this license must not be reverse
+ engineered, decompiled, modified and/or disassembled.
+
+THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/softdevice/s132/doc/s132_nrf52_6.0.0_migration-document.pdf b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/softdevice/s132/doc/s132_nrf52_6.0.0_migration-document.pdf
new file mode 100644
index 0000000..e88cd69
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/softdevice/s132/doc/s132_nrf52_6.0.0_migration-document.pdf
Binary files differ
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/softdevice/s132/doc/s132_nrf52_6.0.0_release-notes.pdf b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/softdevice/s132/doc/s132_nrf52_6.0.0_release-notes.pdf
new file mode 100644
index 0000000..827c06b
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/softdevice/s132/doc/s132_nrf52_6.0.0_release-notes.pdf
Binary files differ
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/softdevice/s132/headers/ble.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/softdevice/s132/headers/ble.h
new file mode 100644
index 0000000..9ebb41f
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/softdevice/s132/headers/ble.h
@@ -0,0 +1,622 @@
+/*
+ * Copyright (c) 2012 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ */
+
+/**
+ @addtogroup BLE_COMMON BLE SoftDevice Common
+ @{
+ @defgroup ble_api Events, type definitions and API calls
+ @{
+
+ @brief Module independent events, type definitions and API calls for the BLE SoftDevice.
+
+ */
+
+#ifndef BLE_H__
+#define BLE_H__
+
+#include <stdint.h>
+#include "nrf_svc.h"
+#include "nrf_error.h"
+#include "ble_err.h"
+#include "ble_gap.h"
+#include "ble_l2cap.h"
+#include "ble_gatt.h"
+#include "ble_gattc.h"
+#include "ble_gatts.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** @addtogroup BLE_COMMON_ENUMERATIONS Enumerations
+ * @{ */
+
+/**
+ * @brief Common API SVC numbers.
+ */
+enum BLE_COMMON_SVCS
+{
+ SD_BLE_ENABLE = BLE_SVC_BASE, /**< Enable and initialize the BLE stack */
+ SD_BLE_EVT_GET, /**< Get an event from the pending events queue. */
+ SD_BLE_UUID_VS_ADD, /**< Add a Vendor Specific UUID. */
+ SD_BLE_UUID_DECODE, /**< Decode UUID bytes. */
+ SD_BLE_UUID_ENCODE, /**< Encode UUID bytes. */
+ SD_BLE_VERSION_GET, /**< Get the local version information (company ID, Link Layer Version, Link Layer Subversion). */
+ SD_BLE_USER_MEM_REPLY, /**< User Memory Reply. */
+ SD_BLE_OPT_SET, /**< Set a BLE option. */
+ SD_BLE_OPT_GET, /**< Get a BLE option. */
+ SD_BLE_CFG_SET, /**< Add a configuration to the BLE stack. */
+};
+
+/**
+ * @brief BLE Module Independent Event IDs.
+ */
+enum BLE_COMMON_EVTS
+{
+ BLE_EVT_USER_MEM_REQUEST = BLE_EVT_BASE + 0, /**< User Memory request. @ref ble_evt_user_mem_request_t */
+ BLE_EVT_USER_MEM_RELEASE = BLE_EVT_BASE + 1, /**< User Memory release. @ref ble_evt_user_mem_release_t */
+};
+
+/**@brief BLE Connection Configuration IDs.
+ *
+ * IDs that uniquely identify a connection configuration.
+ */
+enum BLE_CONN_CFGS
+{
+ BLE_CONN_CFG_GAP = BLE_CONN_CFG_BASE + 0, /**< BLE GAP specific connection configuration. */
+ BLE_CONN_CFG_GATTC = BLE_CONN_CFG_BASE + 1, /**< BLE GATTC specific connection configuration. */
+ BLE_CONN_CFG_GATTS = BLE_CONN_CFG_BASE + 2, /**< BLE GATTS specific connection configuration. */
+ BLE_CONN_CFG_GATT = BLE_CONN_CFG_BASE + 3, /**< BLE GATT specific connection configuration. */
+ BLE_CONN_CFG_L2CAP = BLE_CONN_CFG_BASE + 4, /**< BLE L2CAP specific connection configuration. */
+};
+
+/**@brief BLE Common Configuration IDs.
+ *
+ * IDs that uniquely identify a common configuration.
+ */
+enum BLE_COMMON_CFGS
+{
+ BLE_COMMON_CFG_VS_UUID = BLE_CFG_BASE, /**< Vendor specific UUID configuration */
+};
+
+/**@brief Common Option IDs.
+ * IDs that uniquely identify a common option.
+ */
+enum BLE_COMMON_OPTS
+{
+ BLE_COMMON_OPT_PA_LNA = BLE_OPT_BASE + 0, /**< PA and LNA options */
+ BLE_COMMON_OPT_CONN_EVT_EXT = BLE_OPT_BASE + 1, /**< Extended connection events option */
+};
+
+/** @} */
+
+/** @addtogroup BLE_COMMON_DEFINES Defines
+ * @{ */
+
+/** @brief Required pointer alignment for BLE Events.
+*/
+#define BLE_EVT_PTR_ALIGNMENT 4
+
+/** @brief Leaves the maximum of the two arguments.
+*/
+#define BLE_MAX(a, b) ((a) < (b) ? (b) : (a))
+
+/** @brief Maximum possible length for BLE Events.
+ * @note The highest value used for @ref ble_gatt_conn_cfg_t::att_mtu in any connection configuration shall be used as a parameter.
+ * If that value has not been configured for any connections then @ref BLE_GATT_ATT_MTU_DEFAULT must be used instead.
+*/
+#define BLE_EVT_LEN_MAX(ATT_MTU) ( \
+ offsetof(ble_evt_t, evt.gattc_evt.params.prim_srvc_disc_rsp.services) + ((ATT_MTU) - 1) / 4 * sizeof(ble_gattc_service_t) \
+)
+
+/** @defgroup BLE_USER_MEM_TYPES User Memory Types
+ * @{ */
+#define BLE_USER_MEM_TYPE_INVALID 0x00 /**< Invalid User Memory Types. */
+#define BLE_USER_MEM_TYPE_GATTS_QUEUED_WRITES 0x01 /**< User Memory for GATTS queued writes. */
+/** @} */
+
+/** @defgroup BLE_UUID_VS_COUNTS Vendor Specific UUID counts
+ * @{
+ */
+#define BLE_UUID_VS_COUNT_DEFAULT 10 /**< Default VS UUID count. */
+#define BLE_UUID_VS_COUNT_MAX 254 /**< Maximum VS UUID count. */
+/** @} */
+
+/** @defgroup BLE_COMMON_CFG_DEFAULTS Configuration defaults.
+ * @{
+ */
+#define BLE_CONN_CFG_TAG_DEFAULT 0 /**< Default configuration tag, SoftDevice default connection configuration. */
+
+/** @} */
+
+/** @} */
+
+/** @addtogroup BLE_COMMON_STRUCTURES Structures
+ * @{ */
+
+/**@brief User Memory Block. */
+typedef struct
+{
+ uint8_t *p_mem; /**< Pointer to the start of the user memory block. */
+ uint16_t len; /**< Length in bytes of the user memory block. */
+} ble_user_mem_block_t;
+
+/**@brief Event structure for @ref BLE_EVT_USER_MEM_REQUEST. */
+typedef struct
+{
+ uint8_t type; /**< User memory type, see @ref BLE_USER_MEM_TYPES. */
+} ble_evt_user_mem_request_t;
+
+/**@brief Event structure for @ref BLE_EVT_USER_MEM_RELEASE. */
+typedef struct
+{
+ uint8_t type; /**< User memory type, see @ref BLE_USER_MEM_TYPES. */
+ ble_user_mem_block_t mem_block; /**< User memory block */
+} ble_evt_user_mem_release_t;
+
+/**@brief Event structure for events not associated with a specific function module. */
+typedef struct
+{
+ uint16_t conn_handle; /**< Connection Handle on which this event occurred. */
+ union
+ {
+ ble_evt_user_mem_request_t user_mem_request; /**< User Memory Request Event Parameters. */
+ ble_evt_user_mem_release_t user_mem_release; /**< User Memory Release Event Parameters. */
+ } params; /**< Event parameter union. */
+} ble_common_evt_t;
+
+/**@brief BLE Event header. */
+typedef struct
+{
+ uint16_t evt_id; /**< Value from a BLE_<module>_EVT series. */
+ uint16_t evt_len; /**< Length in octets including this header. */
+} ble_evt_hdr_t;
+
+/**@brief Common BLE Event type, wrapping the module specific event reports. */
+typedef struct
+{
+ ble_evt_hdr_t header; /**< Event header. */
+ union
+ {
+ ble_common_evt_t common_evt; /**< Common Event, evt_id in BLE_EVT_* series. */
+ ble_gap_evt_t gap_evt; /**< GAP originated event, evt_id in BLE_GAP_EVT_* series. */
+ ble_gattc_evt_t gattc_evt; /**< GATT client originated event, evt_id in BLE_GATTC_EVT* series. */
+ ble_gatts_evt_t gatts_evt; /**< GATT server originated event, evt_id in BLE_GATTS_EVT* series. */
+ ble_l2cap_evt_t l2cap_evt; /**< L2CAP originated event, evt_id in BLE_L2CAP_EVT* series. */
+ } evt; /**< Event union. */
+} ble_evt_t;
+
+
+/**
+ * @brief Version Information.
+ */
+typedef struct
+{
+ uint8_t version_number; /**< Link Layer Version number. See https://www.bluetooth.org/en-us/specification/assigned-numbers/link-layer for assigned values. */
+ uint16_t company_id; /**< Company ID, Nordic Semiconductor's company ID is 89 (0x0059) (https://www.bluetooth.org/apps/content/Default.aspx?doc_id=49708). */
+ uint16_t subversion_number; /**< Link Layer Sub Version number, corresponds to the SoftDevice Config ID or Firmware ID (FWID). */
+} ble_version_t;
+
+/**
+ * @brief Configuration parameters for the PA and LNA.
+ */
+typedef struct
+{
+ uint8_t enable :1; /**< Enable toggling for this amplifier */
+ uint8_t active_high :1; /**< Set the pin to be active high */
+ uint8_t gpio_pin :6; /**< The GPIO pin to toggle for this amplifier */
+} ble_pa_lna_cfg_t;
+
+/**
+ * @brief PA & LNA GPIO toggle configuration
+ *
+ * This option configures the SoftDevice to toggle pins when the radio is active for use with a power amplifier and/or
+ * a low noise amplifier.
+ *
+ * Toggling the pins is achieved by using two PPI channels and a GPIOTE channel. The hardware channel IDs are provided
+ * by the application and should be regarded as reserved as long as any PA/LNA toggling is enabled.
+ *
+ * @note @ref sd_ble_opt_get is not supported for this option.
+ * @note Setting this option while the radio is in use (i.e. any of the roles are active) may have undefined consequences
+ * and must be avoided by the application.
+ */
+typedef struct
+{
+ ble_pa_lna_cfg_t pa_cfg; /**< Power Amplifier configuration */
+ ble_pa_lna_cfg_t lna_cfg; /**< Low Noise Amplifier configuration */
+
+ uint8_t ppi_ch_id_set; /**< PPI channel used for radio pin setting */
+ uint8_t ppi_ch_id_clr; /**< PPI channel used for radio pin clearing */
+ uint8_t gpiote_ch_id; /**< GPIOTE channel used for radio pin toggling */
+} ble_common_opt_pa_lna_t;
+
+/**
+ * @brief Configuration of extended BLE connection events.
+ *
+ * When enabled the SoftDevice will dynamically extend the connection event when possible.
+ *
+ * The connection event length is controlled by the connection configuration as set by @ref ble_gap_conn_cfg_t::event_length.
+ * The connection event can be extended if there is time to send another packet pair before the start of the next connection interval,
+ * and if there are no conflicts with other BLE roles requesting radio time.
+ *
+ * @note @ref sd_ble_opt_get is not supported for this option.
+ */
+typedef struct
+{
+ uint8_t enable : 1; /**< Enable extended BLE connection events, disabled by default. */
+} ble_common_opt_conn_evt_ext_t;
+
+/**@brief Option structure for common options. */
+typedef union
+{
+ ble_common_opt_pa_lna_t pa_lna; /**< Parameters for controlling PA and LNA pin toggling. */
+ ble_common_opt_conn_evt_ext_t conn_evt_ext; /**< Parameters for enabling extended connection events. */
+} ble_common_opt_t;
+
+/**@brief Common BLE Option type, wrapping the module specific options. */
+typedef union
+{
+ ble_common_opt_t common_opt; /**< COMMON options, opt_id in @ref BLE_COMMON_OPTS series. */
+ ble_gap_opt_t gap_opt; /**< GAP option, opt_id in @ref BLE_GAP_OPTS series. */
+} ble_opt_t;
+
+/**@brief BLE connection configuration type, wrapping the module specific configurations, set with
+ * @ref sd_ble_cfg_set.
+ *
+ * @note Connection configurations don't have to be set.
+ * In the case that no configurations has been set, or fewer connection configurations has been set than enabled connections,
+ * the default connection configuration will be automatically added for the remaining connections.
+ * When creating connections with the default configuration, @ref BLE_CONN_CFG_TAG_DEFAULT should be used in
+ * place of @ref ble_conn_cfg_t::conn_cfg_tag.
+ *
+ * @sa sd_ble_gap_adv_start()
+ * @sa sd_ble_gap_connect()
+ *
+ * @mscs
+ * @mmsc{@ref BLE_CONN_CFG}
+ * @endmscs
+
+ */
+typedef struct
+{
+ uint8_t conn_cfg_tag; /**< The application chosen tag it can use with the
+ @ref sd_ble_gap_adv_start() and @ref sd_ble_gap_connect() calls
+ to select this configuration when creating a connection.
+ Must be different for all connection configurations added and not @ref BLE_CONN_CFG_TAG_DEFAULT. */
+ union {
+ ble_gap_conn_cfg_t gap_conn_cfg; /**< GAP connection configuration, cfg_id is @ref BLE_CONN_CFG_GAP. */
+ ble_gattc_conn_cfg_t gattc_conn_cfg; /**< GATTC connection configuration, cfg_id is @ref BLE_CONN_CFG_GATTC. */
+ ble_gatts_conn_cfg_t gatts_conn_cfg; /**< GATTS connection configuration, cfg_id is @ref BLE_CONN_CFG_GATTS. */
+ ble_gatt_conn_cfg_t gatt_conn_cfg; /**< GATT connection configuration, cfg_id is @ref BLE_CONN_CFG_GATT. */
+ ble_l2cap_conn_cfg_t l2cap_conn_cfg; /**< L2CAP connection configuration, cfg_id is @ref BLE_CONN_CFG_L2CAP. */
+ } params; /**< Connection configuration union. */
+} ble_conn_cfg_t;
+
+/**
+ * @brief Configuration of Vendor Specific UUIDs, set with @ref sd_ble_cfg_set.
+ *
+ * @retval ::NRF_ERROR_INVALID_PARAM Too many UUIDs configured.
+ */
+typedef struct
+{
+ uint8_t vs_uuid_count; /**< Number of 128-bit Vendor Specific UUID bases to allocate memory for.
+ Default value is @ref BLE_UUID_VS_COUNT_DEFAULT. Maximum value is
+ @ref BLE_UUID_VS_COUNT_MAX. */
+} ble_common_cfg_vs_uuid_t;
+
+/**@brief Common BLE Configuration type, wrapping the common configurations. */
+typedef union
+{
+ ble_common_cfg_vs_uuid_t vs_uuid_cfg; /**< Vendor specific UUID configuration, cfg_id is @ref BLE_COMMON_CFG_VS_UUID. */
+} ble_common_cfg_t;
+
+/**@brief BLE Configuration type, wrapping the module specific configurations. */
+typedef union
+{
+ ble_conn_cfg_t conn_cfg; /**< Connection specific configurations, cfg_id in @ref BLE_CONN_CFGS series. */
+ ble_common_cfg_t common_cfg; /**< Global common configurations, cfg_id in @ref BLE_COMMON_CFGS series. */
+ ble_gap_cfg_t gap_cfg; /**< Global GAP configurations, cfg_id in @ref BLE_GAP_CFGS series. */
+ ble_gatts_cfg_t gatts_cfg; /**< Global GATTS configuration, cfg_id in @ref BLE_GATTS_CFGS series. */
+} ble_cfg_t;
+
+/** @} */
+
+/** @addtogroup BLE_COMMON_FUNCTIONS Functions
+ * @{ */
+
+/**@brief Enable the BLE stack
+ *
+ * @param[in, out] p_app_ram_base Pointer to a variable containing the start address of the
+ * application RAM region (APP_RAM_BASE). On return, this will
+ * contain the minimum start address of the application RAM region
+ * required by the SoftDevice for this configuration.
+ *
+ * @note The memory requirement for a specific configuration will not increase between SoftDevices
+ * with the same major version number.
+ *
+ * @note The value of *p_app_ram_base when the app has done no custom configuration of the
+ * SoftDevice, i.e. the app has not called @ref sd_ble_cfg_set before @ref sd_ble_enable, can
+ * be found in the release notes.
+ *
+ * @note At runtime the IC's RAM is split into 2 regions: The SoftDevice RAM region is located
+ * between 0x20000000 and APP_RAM_BASE-1 and the application's RAM region is located between
+ * APP_RAM_BASE and the start of the call stack.
+ *
+ * @details This call initializes the BLE stack, no BLE related function other than @ref
+ * sd_ble_cfg_set can be called before this one.
+ *
+ * @mscs
+ * @mmsc{@ref BLE_COMMON_ENABLE}
+ * @endmscs
+ *
+ * @retval ::NRF_SUCCESS The BLE stack has been initialized successfully.
+ * @retval ::NRF_ERROR_INVALID_STATE The BLE stack had already been initialized and cannot be reinitialized.
+ * @retval ::NRF_ERROR_INVALID_ADDR Invalid or not sufficiently aligned pointer supplied.
+ * @retval ::NRF_ERROR_NO_MEM The amount of memory assigned to the SoftDevice by *p_app_ram_base is not
+ * large enough to fit this configuration's memory requirement. Check *p_app_ram_base
+ * and set the start address of the application RAM region accordingly.
+ */
+SVCALL(SD_BLE_ENABLE, uint32_t, sd_ble_enable(uint32_t * p_app_ram_base));
+
+/**@brief Add configurations for the BLE stack
+ *
+ * @param[in] cfg_id Config ID, see @ref BLE_CONN_CFGS, @ref BLE_COMMON_CFGS, @ref
+ * BLE_GAP_CFGS or @ref BLE_GATTS_CFGS.
+ * @param[in] p_cfg Pointer to a ble_cfg_t structure containing the configuration value.
+ * @param[in] app_ram_base The start address of the application RAM region (APP_RAM_BASE).
+ * See @ref sd_ble_enable for details about APP_RAM_BASE.
+ *
+ * @note The memory requirement for a specific configuration will not increase between SoftDevices
+ * with the same major version number.
+ *
+ * @note If a configuration is set more than once, the last one set is the one that takes effect on
+ * @ref sd_ble_enable.
+ *
+ * @note Any part of the BLE stack that is NOT configured with @ref sd_ble_cfg_set will have default
+ * configuration.
+ *
+ * @note @ref sd_ble_cfg_set may be called at any time when the SoftDevice is enabled (see @ref
+ * sd_softdevice_enable) while the BLE part of the SoftDevice is not enabled (see @ref
+ * sd_ble_enable).
+ *
+ * @note Error codes for the configurations are described in the configuration structs.
+ *
+ * @mscs
+ * @mmsc{@ref BLE_COMMON_ENABLE}
+ * @endmscs
+ *
+ * @retval ::NRF_SUCCESS The configuration has been added successfully.
+ * @retval ::NRF_ERROR_INVALID_STATE The BLE stack had already been initialized.
+ * @retval ::NRF_ERROR_INVALID_ADDR Invalid or not sufficiently aligned pointer supplied.
+ * @retval ::NRF_ERROR_INVALID_PARAM Invalid cfg_id supplied.
+ * @retval ::NRF_ERROR_NO_MEM The amount of memory assigned to the SoftDevice by app_ram_base is not
+ * large enough to fit this configuration's memory requirement.
+ */
+SVCALL(SD_BLE_CFG_SET, uint32_t, sd_ble_cfg_set(uint32_t cfg_id, ble_cfg_t const * p_cfg, uint32_t app_ram_base));
+
+/**@brief Get an event from the pending events queue.
+ *
+ * @param[out] p_dest Pointer to buffer to be filled in with an event, or NULL to retrieve the event length.
+ * This buffer <b>must be aligned to the extend defined by @ref BLE_EVT_PTR_ALIGNMENT</b>.
+ * The buffer should be interpreted as a @ref ble_evt_t struct.
+ * @param[in, out] p_len Pointer the length of the buffer, on return it is filled with the event length.
+ *
+ * @details This call allows the application to pull a BLE event from the BLE stack. The application is signaled that
+ * an event is available from the BLE stack by the triggering of the SD_EVT_IRQn interrupt.
+ * The application is free to choose whether to call this function from thread mode (main context) or directly from the
+ * Interrupt Service Routine that maps to SD_EVT_IRQn. In any case however, and because the BLE stack runs at a higher
+ * priority than the application, this function should be called in a loop (until @ref NRF_ERROR_NOT_FOUND is returned)
+ * every time SD_EVT_IRQn is raised to ensure that all available events are pulled from the BLE stack. Failure to do so
+ * could potentially leave events in the internal queue without the application being aware of this fact.
+ *
+ * Sizing the p_dest buffer is equally important, since the application needs to provide all the memory necessary for the event to
+ * be copied into application memory. If the buffer provided is not large enough to fit the entire contents of the event,
+ * @ref NRF_ERROR_DATA_SIZE will be returned and the application can then call again with a larger buffer size.
+ * The maximum possible event length is defined by @ref BLE_EVT_LEN_MAX. The application may also "peek" the event length
+ * by providing p_dest as a NULL pointer and inspecting the value of *p_len upon return:
+ *
+ * \code
+ * uint16_t len;
+ * errcode = sd_ble_evt_get(NULL, &len);
+ * \endcode
+ *
+ * @mscs
+ * @mmsc{@ref BLE_COMMON_IRQ_EVT_MSC}
+ * @mmsc{@ref BLE_COMMON_THREAD_EVT_MSC}
+ * @endmscs
+ *
+ * @retval ::NRF_SUCCESS Event pulled and stored into the supplied buffer.
+ * @retval ::NRF_ERROR_INVALID_ADDR Invalid or not sufficiently aligned pointer supplied.
+ * @retval ::NRF_ERROR_NOT_FOUND No events ready to be pulled.
+ * @retval ::NRF_ERROR_DATA_SIZE Event ready but could not fit into the supplied buffer.
+ */
+SVCALL(SD_BLE_EVT_GET, uint32_t, sd_ble_evt_get(uint8_t *p_dest, uint16_t *p_len));
+
+
+/**@brief Add a Vendor Specific base UUID.
+ *
+ * @details This call enables the application to add a vendor specific base UUID to the BLE stack's table, for later
+ * use with all other modules and APIs. This then allows the application to use the shorter, 24-bit @ref ble_uuid_t
+ * format when dealing with both 16-bit and 128-bit UUIDs without having to check for lengths and having split code
+ * paths. This is accomplished by extending the grouping mechanism that the Bluetooth SIG standard base UUID uses
+ * for all other 128-bit UUIDs. The type field in the @ref ble_uuid_t structure is an index (relative to
+ * @ref BLE_UUID_TYPE_VENDOR_BEGIN) to the table populated by multiple calls to this function, and the UUID field
+ * in the same structure contains the 2 bytes at indexes 12 and 13. The number of possible 128-bit UUIDs available to
+ * the application is therefore the number of Vendor Specific UUIDs added with the help of this function times 65536,
+ * although restricted to modifying bytes 12 and 13 for each of the entries in the supplied array.
+ *
+ * @note Bytes 12 and 13 of the provided UUID will not be used internally, since those are always replaced by
+ * the 16-bit uuid field in @ref ble_uuid_t.
+ *
+ * @note If a UUID is already present in the BLE stack's internal table, the corresponding index will be returned in
+ * p_uuid_type along with an @ref NRF_SUCCESS error code.
+ *
+ * @param[in] p_vs_uuid Pointer to a 16-octet (128-bit) little endian Vendor Specific UUID disregarding
+ * bytes 12 and 13.
+ * @param[out] p_uuid_type Pointer to a uint8_t where the type field in @ref ble_uuid_t corresponding to this UUID will be stored.
+ *
+ * @retval ::NRF_SUCCESS Successfully added the Vendor Specific UUID.
+ * @retval ::NRF_ERROR_INVALID_ADDR If p_vs_uuid or p_uuid_type is NULL or invalid.
+ * @retval ::NRF_ERROR_NO_MEM If there are no more free slots for VS UUIDs.
+ */
+SVCALL(SD_BLE_UUID_VS_ADD, uint32_t, sd_ble_uuid_vs_add(ble_uuid128_t const *p_vs_uuid, uint8_t *p_uuid_type));
+
+
+/** @brief Decode little endian raw UUID bytes (16-bit or 128-bit) into a 24 bit @ref ble_uuid_t structure.
+ *
+ * @details The raw UUID bytes excluding bytes 12 and 13 (i.e. bytes 0-11 and 14-15) of p_uuid_le are compared
+ * to the corresponding ones in each entry of the table of vendor specific UUIDs populated with @ref sd_ble_uuid_vs_add
+ * to look for a match. If there is such a match, bytes 12 and 13 are returned as p_uuid->uuid and the index
+ * relative to @ref BLE_UUID_TYPE_VENDOR_BEGIN as p_uuid->type.
+ *
+ * @note If the UUID length supplied is 2, then the type set by this call will always be @ref BLE_UUID_TYPE_BLE.
+ *
+ * @param[in] uuid_le_len Length in bytes of the buffer pointed to by p_uuid_le (must be 2 or 16 bytes).
+ * @param[in] p_uuid_le Pointer pointing to little endian raw UUID bytes.
+ * @param[out] p_uuid Pointer to a @ref ble_uuid_t structure to be filled in.
+ *
+ * @retval ::NRF_SUCCESS Successfully decoded into the @ref ble_uuid_t structure.
+ * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied.
+ * @retval ::NRF_ERROR_INVALID_LENGTH Invalid UUID length.
+ * @retval ::NRF_ERROR_NOT_FOUND For a 128-bit UUID, no match in the populated table of UUIDs.
+ */
+SVCALL(SD_BLE_UUID_DECODE, uint32_t, sd_ble_uuid_decode(uint8_t uuid_le_len, uint8_t const *p_uuid_le, ble_uuid_t *p_uuid));
+
+
+/** @brief Encode a @ref ble_uuid_t structure into little endian raw UUID bytes (16-bit or 128-bit).
+ *
+ * @note The pointer to the destination buffer p_uuid_le may be NULL, in which case only the validity and size of p_uuid is computed.
+ *
+ * @param[in] p_uuid Pointer to a @ref ble_uuid_t structure that will be encoded into bytes.
+ * @param[out] p_uuid_le_len Pointer to a uint8_t that will be filled with the encoded length (2 or 16 bytes).
+ * @param[out] p_uuid_le Pointer to a buffer where the little endian raw UUID bytes (2 or 16) will be stored.
+ *
+ * @retval ::NRF_SUCCESS Successfully encoded into the buffer.
+ * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied.
+ * @retval ::NRF_ERROR_INVALID_PARAM Invalid UUID type.
+ */
+SVCALL(SD_BLE_UUID_ENCODE, uint32_t, sd_ble_uuid_encode(ble_uuid_t const *p_uuid, uint8_t *p_uuid_le_len, uint8_t *p_uuid_le));
+
+
+/**@brief Get Version Information.
+ *
+ * @details This call allows the application to get the BLE stack version information.
+ *
+ * @param[out] p_version Pointer to a ble_version_t structure to be filled in.
+ *
+ * @retval ::NRF_SUCCESS Version information stored successfully.
+ * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied.
+ * @retval ::NRF_ERROR_BUSY The BLE stack is busy (typically doing a locally-initiated disconnection procedure).
+ */
+SVCALL(SD_BLE_VERSION_GET, uint32_t, sd_ble_version_get(ble_version_t *p_version));
+
+
+/**@brief Provide a user memory block.
+ *
+ * @note This call can only be used as a response to a @ref BLE_EVT_USER_MEM_REQUEST event issued to the application.
+ *
+ * @param[in] conn_handle Connection handle.
+ * @param[in] p_block Pointer to a user memory block structure or NULL if memory is managed by the application.
+ *
+ * @mscs
+ * @mmsc{@ref BLE_GATTS_QUEUED_WRITE_PEER_CANCEL_MSC}
+ * @mmsc{@ref BLE_GATTS_QUEUED_WRITE_NOBUF_AUTH_MSC}
+ * @mmsc{@ref BLE_GATTS_QUEUED_WRITE_NOBUF_NOAUTH_MSC}
+ * @mmsc{@ref BLE_GATTS_QUEUED_WRITE_BUF_AUTH_MSC}
+ * @mmsc{@ref BLE_GATTS_QUEUED_WRITE_BUF_NOAUTH_MSC}
+ * @mmsc{@ref BLE_GATTS_QUEUED_WRITE_QUEUE_FULL_MSC}
+ * @endmscs
+ *
+ * @retval ::NRF_SUCCESS Successfully queued a response to the peer.
+ * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied.
+ * @retval ::NRF_ERROR_BUSY The stack is busy, process pending events and retry.
+ * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid Connection Handle.
+ * @retval ::NRF_ERROR_INVALID_LENGTH Invalid user memory block length supplied.
+ * @retval ::NRF_ERROR_INVALID_STATE Invalid Connection state or no user memory request pending.
+ */
+SVCALL(SD_BLE_USER_MEM_REPLY, uint32_t, sd_ble_user_mem_reply(uint16_t conn_handle, ble_user_mem_block_t const *p_block));
+
+/**@brief Set a BLE option.
+ *
+ * @details This call allows the application to set the value of an option.
+ *
+ * @mscs
+ * @mmsc{@ref BLE_GAP_PERIPH_BONDING_STATIC_PK_MSC}
+ * @endmscs
+ *
+ * @param[in] opt_id Option ID, see @ref BLE_COMMON_OPTS and @ref BLE_GAP_OPTS.
+ * @param[in] p_opt Pointer to a ble_opt_t structure containing the option value.
+ *
+ * @retval ::NRF_SUCCESS Option set successfully.
+ * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied.
+ * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid Connection Handle.
+ * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied, check parameter limits and constraints.
+ * @retval ::NRF_ERROR_INVALID_STATE Unable to set the parameter at this time.
+ * @retval ::NRF_ERROR_BUSY The BLE stack is busy or the previous procedure has not completed.
+ */
+SVCALL(SD_BLE_OPT_SET, uint32_t, sd_ble_opt_set(uint32_t opt_id, ble_opt_t const *p_opt));
+
+
+/**@brief Get a BLE option.
+ *
+ * @details This call allows the application to retrieve the value of an option.
+ *
+ * @param[in] opt_id Option ID, see @ref BLE_COMMON_OPTS and @ref BLE_GAP_OPTS.
+ * @param[out] p_opt Pointer to a ble_opt_t structure to be filled in.
+ *
+ * @retval ::NRF_SUCCESS Option retrieved successfully.
+ * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied.
+ * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid Connection Handle.
+ * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied, check parameter limits and constraints.
+ * @retval ::NRF_ERROR_INVALID_STATE Unable to retrieve the parameter at this time.
+ * @retval ::NRF_ERROR_BUSY The BLE stack is busy or the previous procedure has not completed.
+ * @retval ::NRF_ERROR_NOT_SUPPORTED This option is not supported.
+ *
+ */
+SVCALL(SD_BLE_OPT_GET, uint32_t, sd_ble_opt_get(uint32_t opt_id, ble_opt_t *p_opt));
+
+/** @} */
+#ifdef __cplusplus
+}
+#endif
+#endif /* BLE_H__ */
+
+/**
+ @}
+ @}
+*/
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/softdevice/s132/headers/ble_err.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/softdevice/s132/headers/ble_err.h
new file mode 100644
index 0000000..1b4820d
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/softdevice/s132/headers/ble_err.h
@@ -0,0 +1,93 @@
+/*
+ * Copyright (c) 2012 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ */
+
+/**
+ @addtogroup BLE_COMMON
+ @{
+ @addtogroup nrf_error
+ @{
+ @ingroup BLE_COMMON
+ @}
+
+ @defgroup ble_err General error codes
+ @{
+
+ @brief General error code definitions for the BLE API.
+
+ @ingroup BLE_COMMON
+*/
+#ifndef NRF_BLE_ERR_H__
+#define NRF_BLE_ERR_H__
+
+#include "nrf_error.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* @defgroup BLE_ERRORS Error Codes
+ * @{ */
+#define BLE_ERROR_NOT_ENABLED (NRF_ERROR_STK_BASE_NUM+0x001) /**< @ref sd_ble_enable has not been called. */
+#define BLE_ERROR_INVALID_CONN_HANDLE (NRF_ERROR_STK_BASE_NUM+0x002) /**< Invalid connection handle. */
+#define BLE_ERROR_INVALID_ATTR_HANDLE (NRF_ERROR_STK_BASE_NUM+0x003) /**< Invalid attribute handle. */
+#define BLE_ERROR_INVALID_ADV_HANDLE (NRF_ERROR_STK_BASE_NUM+0x004) /**< Invalid advertising handle. */
+#define BLE_ERROR_INVALID_ROLE (NRF_ERROR_STK_BASE_NUM+0x005) /**< Invalid role. */
+#define BLE_ERROR_BLOCKED_BY_OTHER_LINKS (NRF_ERROR_STK_BASE_NUM+0x006) /**< The attempt to change link settings failed due to the scheduling of other links. */
+/** @} */
+
+
+/** @defgroup BLE_ERROR_SUBRANGES Module specific error code subranges
+ * @brief Assignment of subranges for module specific error codes.
+ * @note For specific error codes, see ble_<module>.h or ble_error_<module>.h.
+ * @{ */
+#define NRF_L2CAP_ERR_BASE (NRF_ERROR_STK_BASE_NUM+0x100) /**< L2CAP specific errors. */
+#define NRF_GAP_ERR_BASE (NRF_ERROR_STK_BASE_NUM+0x200) /**< GAP specific errors. */
+#define NRF_GATTC_ERR_BASE (NRF_ERROR_STK_BASE_NUM+0x300) /**< GATT client specific errors. */
+#define NRF_GATTS_ERR_BASE (NRF_ERROR_STK_BASE_NUM+0x400) /**< GATT server specific errors. */
+/** @} */
+
+#ifdef __cplusplus
+}
+#endif
+#endif
+
+
+/**
+ @}
+ @}
+*/
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/softdevice/s132/headers/ble_gap.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/softdevice/s132/headers/ble_gap.h
new file mode 100644
index 0000000..8b13816
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/softdevice/s132/headers/ble_gap.h
@@ -0,0 +1,2653 @@
+/*
+ * Copyright (c) 2011 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ */
+
+/**
+ @addtogroup BLE_GAP Generic Access Profile (GAP)
+ @{
+ @brief Definitions and prototypes for the GAP interface.
+ */
+
+#ifndef BLE_GAP_H__
+#define BLE_GAP_H__
+
+#include <stdint.h>
+#include "nrf_svc.h"
+#include "nrf_error.h"
+#include "ble_hci.h"
+#include "ble_ranges.h"
+#include "ble_types.h"
+#include "ble_err.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**@addtogroup BLE_GAP_ENUMERATIONS Enumerations
+ * @{ */
+
+/**@brief GAP API SVC numbers.
+ */
+enum BLE_GAP_SVCS
+{
+ SD_BLE_GAP_ADDR_SET = BLE_GAP_SVC_BASE, /**< Set own Bluetooth Address. */
+ SD_BLE_GAP_ADDR_GET = BLE_GAP_SVC_BASE + 1, /**< Get own Bluetooth Address. */
+ SD_BLE_GAP_WHITELIST_SET = BLE_GAP_SVC_BASE + 2, /**< Set active whitelist. */
+ SD_BLE_GAP_DEVICE_IDENTITIES_SET = BLE_GAP_SVC_BASE + 3, /**< Set device identity list. */
+ SD_BLE_GAP_PRIVACY_SET = BLE_GAP_SVC_BASE + 4, /**< Set Privacy settings*/
+ SD_BLE_GAP_PRIVACY_GET = BLE_GAP_SVC_BASE + 5, /**< Get Privacy settings*/
+ SD_BLE_GAP_ADV_SET_CONFIGURE = BLE_GAP_SVC_BASE + 6, /**< Configure an advertising set. */
+ SD_BLE_GAP_ADV_START = BLE_GAP_SVC_BASE + 7, /**< Start Advertising. */
+ SD_BLE_GAP_ADV_STOP = BLE_GAP_SVC_BASE + 8, /**< Stop Advertising. */
+ SD_BLE_GAP_CONN_PARAM_UPDATE = BLE_GAP_SVC_BASE + 9, /**< Connection Parameter Update. */
+ SD_BLE_GAP_DISCONNECT = BLE_GAP_SVC_BASE + 10, /**< Disconnect. */
+ SD_BLE_GAP_TX_POWER_SET = BLE_GAP_SVC_BASE + 11, /**< Set TX Power. */
+ SD_BLE_GAP_APPEARANCE_SET = BLE_GAP_SVC_BASE + 12, /**< Set Appearance. */
+ SD_BLE_GAP_APPEARANCE_GET = BLE_GAP_SVC_BASE + 13, /**< Get Appearance. */
+ SD_BLE_GAP_PPCP_SET = BLE_GAP_SVC_BASE + 14, /**< Set PPCP. */
+ SD_BLE_GAP_PPCP_GET = BLE_GAP_SVC_BASE + 15, /**< Get PPCP. */
+ SD_BLE_GAP_DEVICE_NAME_SET = BLE_GAP_SVC_BASE + 16, /**< Set Device Name. */
+ SD_BLE_GAP_DEVICE_NAME_GET = BLE_GAP_SVC_BASE + 17, /**< Get Device Name. */
+ SD_BLE_GAP_AUTHENTICATE = BLE_GAP_SVC_BASE + 18, /**< Initiate Pairing/Bonding. */
+ SD_BLE_GAP_SEC_PARAMS_REPLY = BLE_GAP_SVC_BASE + 19, /**< Reply with Security Parameters. */
+ SD_BLE_GAP_AUTH_KEY_REPLY = BLE_GAP_SVC_BASE + 20, /**< Reply with an authentication key. */
+ SD_BLE_GAP_LESC_DHKEY_REPLY = BLE_GAP_SVC_BASE + 21, /**< Reply with an LE Secure Connections DHKey. */
+ SD_BLE_GAP_KEYPRESS_NOTIFY = BLE_GAP_SVC_BASE + 22, /**< Notify of a keypress during an authentication procedure. */
+ SD_BLE_GAP_LESC_OOB_DATA_GET = BLE_GAP_SVC_BASE + 23, /**< Get the local LE Secure Connections OOB data. */
+ SD_BLE_GAP_LESC_OOB_DATA_SET = BLE_GAP_SVC_BASE + 24, /**< Set the remote LE Secure Connections OOB data. */
+ SD_BLE_GAP_ENCRYPT = BLE_GAP_SVC_BASE + 25, /**< Initiate encryption procedure. */
+ SD_BLE_GAP_SEC_INFO_REPLY = BLE_GAP_SVC_BASE + 26, /**< Reply with Security Information. */
+ SD_BLE_GAP_CONN_SEC_GET = BLE_GAP_SVC_BASE + 27, /**< Obtain connection security level. */
+ SD_BLE_GAP_RSSI_START = BLE_GAP_SVC_BASE + 28, /**< Start reporting of changes in RSSI. */
+ SD_BLE_GAP_RSSI_STOP = BLE_GAP_SVC_BASE + 29, /**< Stop reporting of changes in RSSI. */
+ SD_BLE_GAP_SCAN_START = BLE_GAP_SVC_BASE + 30, /**< Start Scanning. */
+ SD_BLE_GAP_SCAN_STOP = BLE_GAP_SVC_BASE + 31, /**< Stop Scanning. */
+ SD_BLE_GAP_CONNECT = BLE_GAP_SVC_BASE + 32, /**< Connect. */
+ SD_BLE_GAP_CONNECT_CANCEL = BLE_GAP_SVC_BASE + 33, /**< Cancel ongoing connection procedure. */
+ SD_BLE_GAP_RSSI_GET = BLE_GAP_SVC_BASE + 34, /**< Get the last RSSI sample. */
+ SD_BLE_GAP_PHY_UPDATE = BLE_GAP_SVC_BASE + 35, /**< Initiate or respond to a PHY Update Procedure. */
+ SD_BLE_GAP_DATA_LENGTH_UPDATE = BLE_GAP_SVC_BASE + 36, /**< Initiate or respond to a Data Length Update Procedure. */
+ SD_BLE_GAP_QOS_CHANNEL_SURVEY_START = BLE_GAP_SVC_BASE + 37, /**< Start Quality of Service (QoS) channel survey module. */
+ SD_BLE_GAP_QOS_CHANNEL_SURVEY_STOP = BLE_GAP_SVC_BASE + 38, /**< Stop Quality of Service (QoS) channel survey module. */
+};
+
+/**@brief GAP Event IDs.
+ * IDs that uniquely identify an event coming from the stack to the application.
+ */
+enum BLE_GAP_EVTS
+{
+ BLE_GAP_EVT_CONNECTED = BLE_GAP_EVT_BASE,
+ BLE_GAP_EVT_DISCONNECTED = BLE_GAP_EVT_BASE + 1, /**< Disconnected from peer. \n See @ref ble_gap_evt_disconnected_t. */
+ BLE_GAP_EVT_CONN_PARAM_UPDATE = BLE_GAP_EVT_BASE + 2, /**< Connection Parameters updated. \n See @ref ble_gap_evt_conn_param_update_t. */
+ BLE_GAP_EVT_SEC_PARAMS_REQUEST = BLE_GAP_EVT_BASE + 3, /**< Request to provide security parameters. \n Reply with @ref sd_ble_gap_sec_params_reply. \n See @ref ble_gap_evt_sec_params_request_t. */
+ BLE_GAP_EVT_SEC_INFO_REQUEST = BLE_GAP_EVT_BASE + 4, /**< Request to provide security information. \n Reply with @ref sd_ble_gap_sec_info_reply. \n See @ref ble_gap_evt_sec_info_request_t. */
+ BLE_GAP_EVT_PASSKEY_DISPLAY = BLE_GAP_EVT_BASE + 5, /**< Request to display a passkey to the user. \n In LESC Numeric Comparison, reply with @ref sd_ble_gap_auth_key_reply. \n See @ref ble_gap_evt_passkey_display_t. */
+ BLE_GAP_EVT_KEY_PRESSED = BLE_GAP_EVT_BASE + 6, /**< Notification of a keypress on the remote device.\n See @ref ble_gap_evt_key_pressed_t */
+ BLE_GAP_EVT_AUTH_KEY_REQUEST = BLE_GAP_EVT_BASE + 7, /**< Request to provide an authentication key. \n Reply with @ref sd_ble_gap_auth_key_reply. \n See @ref ble_gap_evt_auth_key_request_t. */
+ BLE_GAP_EVT_LESC_DHKEY_REQUEST = BLE_GAP_EVT_BASE + 8, /**< Request to calculate an LE Secure Connections DHKey. \n Reply with @ref sd_ble_gap_lesc_dhkey_reply. \n See @ref ble_gap_evt_lesc_dhkey_request_t */
+ BLE_GAP_EVT_AUTH_STATUS = BLE_GAP_EVT_BASE + 9, /**< Authentication procedure completed with status. \n See @ref ble_gap_evt_auth_status_t. */
+ BLE_GAP_EVT_CONN_SEC_UPDATE = BLE_GAP_EVT_BASE + 10, /**< Connection security updated. \n See @ref ble_gap_evt_conn_sec_update_t. */
+ BLE_GAP_EVT_TIMEOUT = BLE_GAP_EVT_BASE + 11, /**< Timeout expired. \n See @ref ble_gap_evt_timeout_t. */
+ BLE_GAP_EVT_RSSI_CHANGED = BLE_GAP_EVT_BASE + 12, /**< RSSI report. \n See @ref ble_gap_evt_rssi_changed_t. */
+ BLE_GAP_EVT_ADV_REPORT = BLE_GAP_EVT_BASE + 13, /**< Advertising report. \n See @ref ble_gap_evt_adv_report_t. */
+ BLE_GAP_EVT_SEC_REQUEST = BLE_GAP_EVT_BASE + 14, /**< Security Request. \n See @ref ble_gap_evt_sec_request_t. */
+ BLE_GAP_EVT_CONN_PARAM_UPDATE_REQUEST = BLE_GAP_EVT_BASE + 15, /**< Connection Parameter Update Request. \n Reply with @ref sd_ble_gap_conn_param_update. \n See @ref ble_gap_evt_conn_param_update_request_t. */
+ BLE_GAP_EVT_SCAN_REQ_REPORT = BLE_GAP_EVT_BASE + 16, /**< Scan request report. \n See @ref ble_gap_evt_scan_req_report_t. */
+ BLE_GAP_EVT_PHY_UPDATE_REQUEST = BLE_GAP_EVT_BASE + 17, /**< PHY Update Request. \n Reply with @ref sd_ble_gap_phy_update. \n See @ref ble_gap_evt_phy_update_request_t. */
+ BLE_GAP_EVT_PHY_UPDATE = BLE_GAP_EVT_BASE + 18, /**< PHY Update Procedure is complete. \n See @ref ble_gap_evt_phy_update_t. */
+ BLE_GAP_EVT_DATA_LENGTH_UPDATE_REQUEST = BLE_GAP_EVT_BASE + 19, /**< Data Length Update Request. \n Reply with @ref sd_ble_gap_data_length_update.\n See @ref ble_gap_evt_data_length_update_request_t. */
+ BLE_GAP_EVT_DATA_LENGTH_UPDATE = BLE_GAP_EVT_BASE + 20, /**< LL Data Channel PDU payload length updated. \n See @ref ble_gap_evt_data_length_update_t. */
+ BLE_GAP_EVT_QOS_CHANNEL_SURVEY_REPORT = BLE_GAP_EVT_BASE + 21, /**< Channel survey report. \n See @ref ble_gap_evt_qos_channel_survey_report_t. */
+ BLE_GAP_EVT_ADV_SET_TERMINATED = BLE_GAP_EVT_BASE + 22, /**< Advertising set terminated. \n See @ref ble_gap_evt_adv_set_terminated_t. */
+};
+
+/**@brief GAP Option IDs.
+ * IDs that uniquely identify a GAP option.
+ */
+enum BLE_GAP_OPTS
+{
+ BLE_GAP_OPT_CH_MAP = BLE_GAP_OPT_BASE, /**< Channel Map. @ref ble_gap_opt_ch_map_t */
+ BLE_GAP_OPT_LOCAL_CONN_LATENCY = BLE_GAP_OPT_BASE + 1, /**< Local connection latency. @ref ble_gap_opt_local_conn_latency_t */
+ BLE_GAP_OPT_PASSKEY = BLE_GAP_OPT_BASE + 2, /**< Set passkey. @ref ble_gap_opt_passkey_t */
+ BLE_GAP_OPT_COMPAT_MODE_1 = BLE_GAP_OPT_BASE + 3, /**< Compatibility mode. @ref ble_gap_opt_compat_mode_1_t */
+ BLE_GAP_OPT_AUTH_PAYLOAD_TIMEOUT = BLE_GAP_OPT_BASE + 4, /**< Set Authenticated payload timeout. @ref ble_gap_opt_auth_payload_timeout_t */
+ BLE_GAP_OPT_SLAVE_LATENCY_DISABLE = BLE_GAP_OPT_BASE + 5, /**< Disable slave latency. @ref ble_gap_opt_slave_latency_disable_t */
+};
+
+/**@brief GAP Configuration IDs.
+ *
+ * IDs that uniquely identify a GAP configuration.
+ */
+enum BLE_GAP_CFGS
+{
+ BLE_GAP_CFG_ROLE_COUNT = BLE_GAP_CFG_BASE, /**< Role count configuration. */
+ BLE_GAP_CFG_DEVICE_NAME = BLE_GAP_CFG_BASE + 1, /**< Device name configuration. */
+};
+
+/**@brief GAP TX Power roles.
+ */
+enum BLE_GAP_TX_POWER_ROLES
+{
+ BLE_GAP_TX_POWER_ROLE_ADV = 1, /**< Advertiser role. */
+ BLE_GAP_TX_POWER_ROLE_SCAN_INIT = 2, /**< Scanner and initiator role. */
+ BLE_GAP_TX_POWER_ROLE_CONN = 3, /**< Connection role. */
+};
+
+/** @} */
+
+/**@addtogroup BLE_GAP_DEFINES Defines
+ * @{ */
+
+/**@defgroup BLE_ERRORS_GAP SVC return values specific to GAP
+ * @{ */
+#define BLE_ERROR_GAP_UUID_LIST_MISMATCH (NRF_GAP_ERR_BASE + 0x000) /**< UUID list does not contain an integral number of UUIDs. */
+#define BLE_ERROR_GAP_DISCOVERABLE_WITH_WHITELIST (NRF_GAP_ERR_BASE + 0x001) /**< Use of Whitelist not permitted with discoverable advertising. */
+#define BLE_ERROR_GAP_INVALID_BLE_ADDR (NRF_GAP_ERR_BASE + 0x002) /**< The upper two bits of the address do not correspond to the specified address type. */
+#define BLE_ERROR_GAP_WHITELIST_IN_USE (NRF_GAP_ERR_BASE + 0x003) /**< Attempt to modify the whitelist while already in use by another operation. */
+#define BLE_ERROR_GAP_DEVICE_IDENTITIES_IN_USE (NRF_GAP_ERR_BASE + 0x004) /**< Attempt to modify the device identity list while already in use by another operation. */
+#define BLE_ERROR_GAP_DEVICE_IDENTITIES_DUPLICATE (NRF_GAP_ERR_BASE + 0x005) /**< The device identity list contains entries with duplicate identity addresses. */
+/**@} */
+
+
+/**@defgroup BLE_GAP_ROLES GAP Roles
+ * @{ */
+#define BLE_GAP_ROLE_INVALID 0x0 /**< Invalid Role. */
+#define BLE_GAP_ROLE_PERIPH 0x1 /**< Peripheral Role. */
+#define BLE_GAP_ROLE_CENTRAL 0x2 /**< Central Role. */
+/**@} */
+
+
+/**@defgroup BLE_GAP_TIMEOUT_SOURCES GAP Timeout sources
+ * @{ */
+#define BLE_GAP_TIMEOUT_SRC_SCAN 0x01 /**< Scanning timeout. */
+#define BLE_GAP_TIMEOUT_SRC_CONN 0x02 /**< Connection timeout. */
+#define BLE_GAP_TIMEOUT_SRC_AUTH_PAYLOAD 0x03 /**< Authenticated payload timeout. */
+/**@} */
+
+
+/**@defgroup BLE_GAP_ADDR_TYPES GAP Address types
+ * @{ */
+#define BLE_GAP_ADDR_TYPE_PUBLIC 0x00 /**< Public (identity) address.*/
+#define BLE_GAP_ADDR_TYPE_RANDOM_STATIC 0x01 /**< Random static (identity) address. */
+#define BLE_GAP_ADDR_TYPE_RANDOM_PRIVATE_RESOLVABLE 0x02 /**< Random private resolvable address. */
+#define BLE_GAP_ADDR_TYPE_RANDOM_PRIVATE_NON_RESOLVABLE 0x03 /**< Random private non-resolvable address. */
+#define BLE_GAP_ADDR_TYPE_ANONYMOUS 0x7F /**< An advertiser may advertise without its address.
+ This type of advertising is called anonymous. */
+/**@} */
+
+
+/**@brief The default interval in seconds at which a private address is refreshed. */
+#define BLE_GAP_DEFAULT_PRIVATE_ADDR_CYCLE_INTERVAL_S (900) /* 15 minutes. */
+/**@brief The maximum interval in seconds at which a private address can be refreshed. */
+#define BLE_GAP_MAX_PRIVATE_ADDR_CYCLE_INTERVAL_S (41400) /* 11 hours 30 minutes. */
+
+
+/** @brief BLE address length. */
+#define BLE_GAP_ADDR_LEN (6)
+
+/**@defgroup BLE_GAP_PRIVACY_MODES Privacy modes
+ * @{ */
+#define BLE_GAP_PRIVACY_MODE_OFF 0x00 /**< Device will send and accept its identity address for its own address. */
+#define BLE_GAP_PRIVACY_MODE_DEVICE_PRIVACY 0x01 /**< Device will send and accept only private addresses for its own address. */
+#define BLE_GAP_PRIVACY_MODE_NETWORK_PRIVACY 0x02 /**< Device will send and accept only private addresses for its own address,
+ and will not accept a peer using identity address as sender address when
+ the peer IRK is exchanged, non-zero and added to the identity list. */
+/**@} */
+
+/** @brief Invalid power level. */
+#define BLE_GAP_POWER_LEVEL_INVALID 127
+
+/** @brief Advertising set handle not set. */
+#define BLE_GAP_ADV_SET_HANDLE_NOT_SET (0xFF)
+
+/** @brief The default number of advertising sets. */
+#define BLE_GAP_ADV_SET_COUNT_DEFAULT (1)
+
+/** @brief The maximum number of advertising sets supported by this SoftDevice. */
+#define BLE_GAP_ADV_SET_COUNT_MAX (1)
+
+/**@defgroup BLE_GAP_ADV_SET_DATA_SIZES Advertising data sizes.
+ * @{ */
+#define BLE_GAP_ADV_SET_DATA_SIZE_MAX (31) /**< Maximum data length for an advertising set. */
+/**@}. */
+
+/** @brief Set ID not available in advertising report. */
+#define BLE_GAP_ADV_REPORT_SET_ID_NOT_AVAILABLE 0xFF
+
+/**@defgroup BLE_GAP_EVT_ADV_SET_TERMINATED_REASON GAP Advertising Set Terminated reasons
+ * @{ */
+#define BLE_GAP_EVT_ADV_SET_TERMINATED_REASON_TIMEOUT 0x01 /**< Timeout value reached. */
+#define BLE_GAP_EVT_ADV_SET_TERMINATED_REASON_LIMIT_REACHED 0x02 /**< @ref ble_gap_adv_params_t::max_adv_evts was reached. */
+/**@} */
+
+/**@defgroup BLE_GAP_AD_TYPE_DEFINITIONS GAP Advertising and Scan Response Data format
+ * @note Found at https://www.bluetooth.org/Technical/AssignedNumbers/generic_access_profile.htm
+ * @{ */
+#define BLE_GAP_AD_TYPE_FLAGS 0x01 /**< Flags for discoverability. */
+#define BLE_GAP_AD_TYPE_16BIT_SERVICE_UUID_MORE_AVAILABLE 0x02 /**< Partial list of 16 bit service UUIDs. */
+#define BLE_GAP_AD_TYPE_16BIT_SERVICE_UUID_COMPLETE 0x03 /**< Complete list of 16 bit service UUIDs. */
+#define BLE_GAP_AD_TYPE_32BIT_SERVICE_UUID_MORE_AVAILABLE 0x04 /**< Partial list of 32 bit service UUIDs. */
+#define BLE_GAP_AD_TYPE_32BIT_SERVICE_UUID_COMPLETE 0x05 /**< Complete list of 32 bit service UUIDs. */
+#define BLE_GAP_AD_TYPE_128BIT_SERVICE_UUID_MORE_AVAILABLE 0x06 /**< Partial list of 128 bit service UUIDs. */
+#define BLE_GAP_AD_TYPE_128BIT_SERVICE_UUID_COMPLETE 0x07 /**< Complete list of 128 bit service UUIDs. */
+#define BLE_GAP_AD_TYPE_SHORT_LOCAL_NAME 0x08 /**< Short local device name. */
+#define BLE_GAP_AD_TYPE_COMPLETE_LOCAL_NAME 0x09 /**< Complete local device name. */
+#define BLE_GAP_AD_TYPE_TX_POWER_LEVEL 0x0A /**< Transmit power level. */
+#define BLE_GAP_AD_TYPE_CLASS_OF_DEVICE 0x0D /**< Class of device. */
+#define BLE_GAP_AD_TYPE_SIMPLE_PAIRING_HASH_C 0x0E /**< Simple Pairing Hash C. */
+#define BLE_GAP_AD_TYPE_SIMPLE_PAIRING_RANDOMIZER_R 0x0F /**< Simple Pairing Randomizer R. */
+#define BLE_GAP_AD_TYPE_SECURITY_MANAGER_TK_VALUE 0x10 /**< Security Manager TK Value. */
+#define BLE_GAP_AD_TYPE_SECURITY_MANAGER_OOB_FLAGS 0x11 /**< Security Manager Out Of Band Flags. */
+#define BLE_GAP_AD_TYPE_SLAVE_CONNECTION_INTERVAL_RANGE 0x12 /**< Slave Connection Interval Range. */
+#define BLE_GAP_AD_TYPE_SOLICITED_SERVICE_UUIDS_16BIT 0x14 /**< List of 16-bit Service Solicitation UUIDs. */
+#define BLE_GAP_AD_TYPE_SOLICITED_SERVICE_UUIDS_128BIT 0x15 /**< List of 128-bit Service Solicitation UUIDs. */
+#define BLE_GAP_AD_TYPE_SERVICE_DATA 0x16 /**< Service Data - 16-bit UUID. */
+#define BLE_GAP_AD_TYPE_PUBLIC_TARGET_ADDRESS 0x17 /**< Public Target Address. */
+#define BLE_GAP_AD_TYPE_RANDOM_TARGET_ADDRESS 0x18 /**< Random Target Address. */
+#define BLE_GAP_AD_TYPE_APPEARANCE 0x19 /**< Appearance. */
+#define BLE_GAP_AD_TYPE_ADVERTISING_INTERVAL 0x1A /**< Advertising Interval. */
+#define BLE_GAP_AD_TYPE_LE_BLUETOOTH_DEVICE_ADDRESS 0x1B /**< LE Bluetooth Device Address. */
+#define BLE_GAP_AD_TYPE_LE_ROLE 0x1C /**< LE Role. */
+#define BLE_GAP_AD_TYPE_SIMPLE_PAIRING_HASH_C256 0x1D /**< Simple Pairing Hash C-256. */
+#define BLE_GAP_AD_TYPE_SIMPLE_PAIRING_RANDOMIZER_R256 0x1E /**< Simple Pairing Randomizer R-256. */
+#define BLE_GAP_AD_TYPE_SERVICE_DATA_32BIT_UUID 0x20 /**< Service Data - 32-bit UUID. */
+#define BLE_GAP_AD_TYPE_SERVICE_DATA_128BIT_UUID 0x21 /**< Service Data - 128-bit UUID. */
+#define BLE_GAP_AD_TYPE_LESC_CONFIRMATION_VALUE 0x22 /**< LE Secure Connections Confirmation Value */
+#define BLE_GAP_AD_TYPE_LESC_RANDOM_VALUE 0x23 /**< LE Secure Connections Random Value */
+#define BLE_GAP_AD_TYPE_URI 0x24 /**< URI */
+#define BLE_GAP_AD_TYPE_3D_INFORMATION_DATA 0x3D /**< 3D Information Data. */
+#define BLE_GAP_AD_TYPE_MANUFACTURER_SPECIFIC_DATA 0xFF /**< Manufacturer Specific Data. */
+/**@} */
+
+
+/**@defgroup BLE_GAP_ADV_FLAGS GAP Advertisement Flags
+ * @{ */
+#define BLE_GAP_ADV_FLAG_LE_LIMITED_DISC_MODE (0x01) /**< LE Limited Discoverable Mode. */
+#define BLE_GAP_ADV_FLAG_LE_GENERAL_DISC_MODE (0x02) /**< LE General Discoverable Mode. */
+#define BLE_GAP_ADV_FLAG_BR_EDR_NOT_SUPPORTED (0x04) /**< BR/EDR not supported. */
+#define BLE_GAP_ADV_FLAG_LE_BR_EDR_CONTROLLER (0x08) /**< Simultaneous LE and BR/EDR, Controller. */
+#define BLE_GAP_ADV_FLAG_LE_BR_EDR_HOST (0x10) /**< Simultaneous LE and BR/EDR, Host. */
+#define BLE_GAP_ADV_FLAGS_LE_ONLY_LIMITED_DISC_MODE (BLE_GAP_ADV_FLAG_LE_LIMITED_DISC_MODE | BLE_GAP_ADV_FLAG_BR_EDR_NOT_SUPPORTED) /**< LE Limited Discoverable Mode, BR/EDR not supported. */
+#define BLE_GAP_ADV_FLAGS_LE_ONLY_GENERAL_DISC_MODE (BLE_GAP_ADV_FLAG_LE_GENERAL_DISC_MODE | BLE_GAP_ADV_FLAG_BR_EDR_NOT_SUPPORTED) /**< LE General Discoverable Mode, BR/EDR not supported. */
+/**@} */
+
+
+/**@defgroup BLE_GAP_ADV_INTERVALS GAP Advertising interval max and min
+ * @{ */
+#define BLE_GAP_ADV_INTERVAL_MIN 0x000020 /**< Minimum Advertising interval in 625 us units, i.e. 20 ms. */
+#define BLE_GAP_ADV_INTERVAL_MAX 0x004000 /**< Maximum Advertising interval in 625 us units, i.e. 10.24 s.
+ @note Support for values above @ref BLE_GAP_ADV_INTERVAL_MAX
+ is experimental. Values above 0xFFFFFF, i.e 10,485.759375 s
+ are not supported. */
+ /**@} */
+
+
+/**@defgroup BLE_GAP_SCAN_INTERVALS GAP Scan interval max and min
+ * @{ */
+#define BLE_GAP_SCAN_INTERVAL_MIN 0x0004 /**< Minimum Scan interval in 625 us units, i.e. 2.5 ms. */
+#define BLE_GAP_SCAN_INTERVAL_MAX 0xFFFF /**< Maximum Scan interval in 625 us units, i.e. 40,959.375 s. */
+ /** @} */
+
+
+/**@defgroup BLE_GAP_SCAN_WINDOW GAP Scan window max and min
+ * @{ */
+#define BLE_GAP_SCAN_WINDOW_MIN 0x0004 /**< Minimum Scan window in 625 us units, i.e. 2.5 ms. */
+#define BLE_GAP_SCAN_WINDOW_MAX 0xFFFF /**< Maximum Scan window in 625 us units, i.e. 40,959.375 s. */
+ /** @} */
+
+
+/**@defgroup BLE_GAP_SCAN_TIMEOUT GAP Scan timeout max and min
+ * @{ */
+#define BLE_GAP_SCAN_TIMEOUT_MIN 0x0001 /**< Minimum Scan timeout in 10 ms units, i.e 10 ms. */
+#define BLE_GAP_SCAN_TIMEOUT_UNLIMITED 0x0000 /**< Continue to scan forever. */
+ /** @} */
+
+/**@defgroup BLE_GAP_SCAN_BUFFER_SIZE GAP Minimum scanner buffer size
+ *
+ * Scan buffers are used for storing advertising data received from an advertiser.
+ * If ble_gap_scan_params_t::extended is set to 0, @ref BLE_GAP_SCAN_BUFFER_MIN is the minimum scan buffer length.
+ * else the minimum scan buffer size is @ref BLE_GAP_SCAN_BUFFER_EXTENDED_MIN.
+ * @{ */
+#define BLE_GAP_SCAN_BUFFER_MIN (31) /**< Minimum data length for an
+ advertising set. */
+#define BLE_GAP_SCAN_BUFFER_MAX (31) /**< Maximum data length for an
+ advertising set. */
+#define BLE_GAP_SCAN_BUFFER_EXTENDED_MIN (255) /**< Minimum data length for an
+ extended advertising set. */
+#define BLE_GAP_SCAN_BUFFER_EXTENDED_MAX (1650) /**< Maximum data length for an
+ extended advertising set.
+ @note Extended scanning is only
+ supported as an experimental
+ feature in this SoftDevice.
+ The scanner will only receive
+ advertising data up to 31 bytes. */
+/** @} */
+
+/**@defgroup BLE_GAP_ADV_TYPES GAP Advertising types
+ *
+ * Advertising types defined in Bluetooth Core Specification v5.0, Vol 6, Part B, Section 4.4.2.
+ *
+ * The maximum advertising data length is defined by @ref BLE_GAP_ADV_SET_DATA_SIZE_MAX.
+ * Note that some of the advertising types do not support advertising data. Non-scannable types do not support
+ * scan response data.
+ *
+ * @{ */
+#define BLE_GAP_ADV_TYPE_CONNECTABLE_SCANNABLE_UNDIRECTED 0x01 /**< Connectable and scannable undirected
+ advertising events. */
+#define BLE_GAP_ADV_TYPE_CONNECTABLE_NONSCANNABLE_DIRECTED_HIGH_DUTY_CYCLE 0x02 /**< Connectable non-scannable directed advertising
+ events. Advertising interval is less that 3.75 ms.
+ Use this type for fast reconnections.
+ @note Advertising data is not supported. */
+#define BLE_GAP_ADV_TYPE_CONNECTABLE_NONSCANNABLE_DIRECTED 0x03 /**< Connectable non-scannable directed advertising
+ events.
+ @note Advertising data is not supported. */
+#define BLE_GAP_ADV_TYPE_NONCONNECTABLE_SCANNABLE_UNDIRECTED 0x04 /**< Non-connectable scannable undirected
+ advertising events. */
+#define BLE_GAP_ADV_TYPE_NONCONNECTABLE_NONSCANNABLE_UNDIRECTED 0x05 /**< Non-connectable non-scannable undirected
+ advertising events. */
+#define BLE_GAP_ADV_TYPE_EXTENDED_CONNECTABLE_NONSCANNABLE_UNDIRECTED 0x06 /**< Connectable non-scannable undirected advertising
+ events using extended advertising PDUs.
+ @note Extended advertising types are only
+ supported as experimental features in this
+ SoftDevice. */
+#define BLE_GAP_ADV_TYPE_EXTENDED_CONNECTABLE_NONSCANNABLE_DIRECTED 0x07 /**< Connectable non-scannable directed advertising
+ events using extended advertising PDUs.
+ @note Extended advertising types are only
+ supported as experimental features in this
+ SoftDevice. */
+#define BLE_GAP_ADV_TYPE_EXTENDED_NONCONNECTABLE_SCANNABLE_UNDIRECTED 0x08 /**< Non-connectable scannable undirected advertising
+ events using extended advertising PDUs.
+ @note Only scan response data is supported.
+ @note Extended advertising types are only
+ supported as experimental features in this
+ SoftDevice. */
+#define BLE_GAP_ADV_TYPE_EXTENDED_NONCONNECTABLE_SCANNABLE_DIRECTED 0x09 /**< Non-connectable scannable directed advertising
+ events using extended advertising PDUs.
+ @note Only scan response data is supported.
+ @note Extended advertising types are only
+ supported as experimental features in this
+ SoftDevice. */
+#define BLE_GAP_ADV_TYPE_EXTENDED_NONCONNECTABLE_NONSCANNABLE_UNDIRECTED 0x0A /**< Non-connectable non-scannable undirected advertising
+ events using extended advertising PDUs.
+ @note Extended advertising types are only
+ supported as experimental features in this
+ SoftDevice. */
+#define BLE_GAP_ADV_TYPE_EXTENDED_NONCONNECTABLE_NONSCANNABLE_DIRECTED 0x0B /**< Non-connectable non-scannable directed advertising
+ events using extended advertising PDUs.
+ @note Extended advertising types are only
+ supported as experimental features in this
+ SoftDevice. */
+/**@} */
+
+/**@defgroup BLE_GAP_ADV_FILTER_POLICIES GAP Advertising filter policies
+ * @{ */
+#define BLE_GAP_ADV_FP_ANY 0x00 /**< Allow scan requests and connect requests from any device. */
+#define BLE_GAP_ADV_FP_FILTER_SCANREQ 0x01 /**< Filter scan requests with whitelist. */
+#define BLE_GAP_ADV_FP_FILTER_CONNREQ 0x02 /**< Filter connect requests with whitelist. */
+#define BLE_GAP_ADV_FP_FILTER_BOTH 0x03 /**< Filter both scan and connect requests with whitelist. */
+/**@} */
+
+/**@defgroup BLE_GAP_ADV_DATA_STATUS GAP Advertising data status
+ * @{ */
+#define BLE_GAP_ADV_DATA_STATUS_COMPLETE 0x00 /**< All data in the advertising event have been received. */
+#define BLE_GAP_ADV_DATA_STATUS_INCOMPLETE_MORE_DATA 0x01 /**< More data to be received. */
+#define BLE_GAP_ADV_DATA_STATUS_INCOMPLETE_TRUNCATED 0x02 /**< Incomplete data. Buffer size insufficient to receive more. */
+#define BLE_GAP_ADV_DATA_STATUS_INCOMPLETE_MISSED 0x03 /**< Failed to receive the remaining data. */
+/**@} */
+
+/**@defgroup BLE_GAP_SCAN_FILTER_POLICIES GAP Scanner filter policies
+ * @{ */
+#define BLE_GAP_SCAN_FP_ACCEPT_ALL 0x00 /**< Accept all advertising packets except directed advertising packets
+ not addressed to this device. */
+#define BLE_GAP_SCAN_FP_WHITELIST 0x01 /**< Accept advertising packets from devices in the whitelist except directed
+ packets not addressed to this device. */
+#define BLE_GAP_SCAN_FP_ALL_NOT_RESOLVED_DIRECTED 0x02 /**< Accept all advertising packets specified in @ref BLE_GAP_SCAN_FP_ACCEPT_ALL.
+ In addition, accept directed advertising packets, where the advertiser's
+ address is a resolvable private address that cannot be resolved. */
+#define BLE_GAP_SCAN_FP_WHITELIST_NOT_RESOLVED_DIRECTED 0x03 /**< Accept all advertising packets specified in @ref BLE_GAP_SCAN_FP_WHITELIST.
+ In addition, accept directed advertising packets, where the advertiser's
+ address is a resolvable private address that cannot be resolved. */
+/**@} */
+
+/**@defgroup BLE_GAP_ADV_TIMEOUT_VALUES GAP Advertising timeout values in 10 ms units
+ * @{ */
+#define BLE_GAP_ADV_TIMEOUT_HIGH_DUTY_MAX (128) /**< Maximum high duty advertising time in 10 ms units. Corresponds to 1.28 s. */
+#define BLE_GAP_ADV_TIMEOUT_LIMITED_MAX (18000) /**< Maximum advertising time in 10 ms units corresponding to TGAP(lim_adv_timeout) = 180 s in limited discoverable mode. */
+#define BLE_GAP_ADV_TIMEOUT_GENERAL_UNLIMITED (0) /**< Unlimited advertising in general discoverable mode.
+ For high duty cycle advertising, this corresponds to @ref BLE_GAP_ADV_TIMEOUT_HIGH_DUTY_MAX. */
+/**@} */
+
+
+/**@defgroup BLE_GAP_DISC_MODES GAP Discovery modes
+ * @{ */
+#define BLE_GAP_DISC_MODE_NOT_DISCOVERABLE 0x00 /**< Not discoverable discovery Mode. */
+#define BLE_GAP_DISC_MODE_LIMITED 0x01 /**< Limited Discovery Mode. */
+#define BLE_GAP_DISC_MODE_GENERAL 0x02 /**< General Discovery Mode. */
+/**@} */
+
+
+/**@defgroup BLE_GAP_IO_CAPS GAP IO Capabilities
+ * @{ */
+#define BLE_GAP_IO_CAPS_DISPLAY_ONLY 0x00 /**< Display Only. */
+#define BLE_GAP_IO_CAPS_DISPLAY_YESNO 0x01 /**< Display and Yes/No entry. */
+#define BLE_GAP_IO_CAPS_KEYBOARD_ONLY 0x02 /**< Keyboard Only. */
+#define BLE_GAP_IO_CAPS_NONE 0x03 /**< No I/O capabilities. */
+#define BLE_GAP_IO_CAPS_KEYBOARD_DISPLAY 0x04 /**< Keyboard and Display. */
+/**@} */
+
+
+/**@defgroup BLE_GAP_AUTH_KEY_TYPES GAP Authentication Key Types
+ * @{ */
+#define BLE_GAP_AUTH_KEY_TYPE_NONE 0x00 /**< No key (may be used to reject). */
+#define BLE_GAP_AUTH_KEY_TYPE_PASSKEY 0x01 /**< 6-digit Passkey. */
+#define BLE_GAP_AUTH_KEY_TYPE_OOB 0x02 /**< Out Of Band data. */
+/**@} */
+
+
+/**@defgroup BLE_GAP_KP_NOT_TYPES GAP Keypress Notification Types
+ * @{ */
+#define BLE_GAP_KP_NOT_TYPE_PASSKEY_START 0x00 /**< Passkey entry started. */
+#define BLE_GAP_KP_NOT_TYPE_PASSKEY_DIGIT_IN 0x01 /**< Passkey digit entered. */
+#define BLE_GAP_KP_NOT_TYPE_PASSKEY_DIGIT_OUT 0x02 /**< Passkey digit erased. */
+#define BLE_GAP_KP_NOT_TYPE_PASSKEY_CLEAR 0x03 /**< Passkey cleared. */
+#define BLE_GAP_KP_NOT_TYPE_PASSKEY_END 0x04 /**< Passkey entry completed. */
+/**@} */
+
+
+/**@defgroup BLE_GAP_SEC_STATUS GAP Security status
+ * @{ */
+#define BLE_GAP_SEC_STATUS_SUCCESS 0x00 /**< Procedure completed with success. */
+#define BLE_GAP_SEC_STATUS_TIMEOUT 0x01 /**< Procedure timed out. */
+#define BLE_GAP_SEC_STATUS_PDU_INVALID 0x02 /**< Invalid PDU received. */
+#define BLE_GAP_SEC_STATUS_RFU_RANGE1_BEGIN 0x03 /**< Reserved for Future Use range #1 begin. */
+#define BLE_GAP_SEC_STATUS_RFU_RANGE1_END 0x80 /**< Reserved for Future Use range #1 end. */
+#define BLE_GAP_SEC_STATUS_PASSKEY_ENTRY_FAILED 0x81 /**< Passkey entry failed (user canceled or other). */
+#define BLE_GAP_SEC_STATUS_OOB_NOT_AVAILABLE 0x82 /**< Out of Band Key not available. */
+#define BLE_GAP_SEC_STATUS_AUTH_REQ 0x83 /**< Authentication requirements not met. */
+#define BLE_GAP_SEC_STATUS_CONFIRM_VALUE 0x84 /**< Confirm value failed. */
+#define BLE_GAP_SEC_STATUS_PAIRING_NOT_SUPP 0x85 /**< Pairing not supported. */
+#define BLE_GAP_SEC_STATUS_ENC_KEY_SIZE 0x86 /**< Encryption key size. */
+#define BLE_GAP_SEC_STATUS_SMP_CMD_UNSUPPORTED 0x87 /**< Unsupported SMP command. */
+#define BLE_GAP_SEC_STATUS_UNSPECIFIED 0x88 /**< Unspecified reason. */
+#define BLE_GAP_SEC_STATUS_REPEATED_ATTEMPTS 0x89 /**< Too little time elapsed since last attempt. */
+#define BLE_GAP_SEC_STATUS_INVALID_PARAMS 0x8A /**< Invalid parameters. */
+#define BLE_GAP_SEC_STATUS_DHKEY_FAILURE 0x8B /**< DHKey check failure. */
+#define BLE_GAP_SEC_STATUS_NUM_COMP_FAILURE 0x8C /**< Numeric Comparison failure. */
+#define BLE_GAP_SEC_STATUS_BR_EDR_IN_PROG 0x8D /**< BR/EDR pairing in progress. */
+#define BLE_GAP_SEC_STATUS_X_TRANS_KEY_DISALLOWED 0x8E /**< BR/EDR Link Key cannot be used for LE keys. */
+#define BLE_GAP_SEC_STATUS_RFU_RANGE2_BEGIN 0x8F /**< Reserved for Future Use range #2 begin. */
+#define BLE_GAP_SEC_STATUS_RFU_RANGE2_END 0xFF /**< Reserved for Future Use range #2 end. */
+/**@} */
+
+
+/**@defgroup BLE_GAP_SEC_STATUS_SOURCES GAP Security status sources
+ * @{ */
+#define BLE_GAP_SEC_STATUS_SOURCE_LOCAL 0x00 /**< Local failure. */
+#define BLE_GAP_SEC_STATUS_SOURCE_REMOTE 0x01 /**< Remote failure. */
+/**@} */
+
+
+/**@defgroup BLE_GAP_CP_LIMITS GAP Connection Parameters Limits
+ * @{ */
+#define BLE_GAP_CP_MIN_CONN_INTVL_NONE 0xFFFF /**< No new minimum connection interval specified in connect parameters. */
+#define BLE_GAP_CP_MIN_CONN_INTVL_MIN 0x0006 /**< Lowest minimum connection interval permitted, in units of 1.25 ms, i.e. 7.5 ms. */
+#define BLE_GAP_CP_MIN_CONN_INTVL_MAX 0x0C80 /**< Highest minimum connection interval permitted, in units of 1.25 ms, i.e. 4 s. */
+#define BLE_GAP_CP_MAX_CONN_INTVL_NONE 0xFFFF /**< No new maximum connection interval specified in connect parameters. */
+#define BLE_GAP_CP_MAX_CONN_INTVL_MIN 0x0006 /**< Lowest maximum connection interval permitted, in units of 1.25 ms, i.e. 7.5 ms. */
+#define BLE_GAP_CP_MAX_CONN_INTVL_MAX 0x0C80 /**< Highest maximum connection interval permitted, in units of 1.25 ms, i.e. 4 s. */
+#define BLE_GAP_CP_SLAVE_LATENCY_MAX 0x01F3 /**< Highest slave latency permitted, in connection events. */
+#define BLE_GAP_CP_CONN_SUP_TIMEOUT_NONE 0xFFFF /**< No new supervision timeout specified in connect parameters. */
+#define BLE_GAP_CP_CONN_SUP_TIMEOUT_MIN 0x000A /**< Lowest supervision timeout permitted, in units of 10 ms, i.e. 100 ms. */
+#define BLE_GAP_CP_CONN_SUP_TIMEOUT_MAX 0x0C80 /**< Highest supervision timeout permitted, in units of 10 ms, i.e. 32 s. */
+/**@} */
+
+
+/**@defgroup BLE_GAP_DEVNAME GAP device name defines.
+ * @{ */
+#define BLE_GAP_DEVNAME_DEFAULT "nRF5x" /**< Default device name value. */
+#define BLE_GAP_DEVNAME_DEFAULT_LEN 31 /**< Default number of octets in device name. */
+#define BLE_GAP_DEVNAME_MAX_LEN 248 /**< Maximum number of octets in device name. */
+/**@} */
+
+
+/**@brief Disable RSSI events for connections */
+#define BLE_GAP_RSSI_THRESHOLD_INVALID 0xFF
+
+/**@defgroup BLE_GAP_PHYS GAP PHYs
+ * @{ */
+#define BLE_GAP_PHY_AUTO 0x00 /**< Automatic PHY selection. Refer @ref sd_ble_gap_phy_update for more information.*/
+#define BLE_GAP_PHY_1MBPS 0x01 /**< 1 Mbps PHY. */
+#define BLE_GAP_PHY_2MBPS 0x02 /**< 2 Mbps PHY. */
+#define BLE_GAP_PHY_CODED 0x04 /**< Coded PHY. */
+#define BLE_GAP_PHY_NOT_SET 0xFF /**< PHY is not configured. */
+
+/**@brief Supported PHYs in connections, for scanning, and for advertising. */
+#define BLE_GAP_PHYS_SUPPORTED (BLE_GAP_PHY_1MBPS | BLE_GAP_PHY_2MBPS) /**< All PHYs except @ref BLE_GAP_PHY_CODED are supported. */
+
+/**@} */
+
+/**@defgroup BLE_GAP_CONN_SEC_MODE_SET_MACROS GAP attribute security requirement setters
+ *
+ * See @ref ble_gap_conn_sec_mode_t.
+ * @{ */
+/**@brief Set sec_mode pointed to by ptr to have no access rights.*/
+#define BLE_GAP_CONN_SEC_MODE_SET_NO_ACCESS(ptr) do {(ptr)->sm = 0; (ptr)->lv = 0;} while(0)
+/**@brief Set sec_mode pointed to by ptr to require no protection, open link.*/
+#define BLE_GAP_CONN_SEC_MODE_SET_OPEN(ptr) do {(ptr)->sm = 1; (ptr)->lv = 1;} while(0)
+/**@brief Set sec_mode pointed to by ptr to require encryption, but no MITM protection.*/
+#define BLE_GAP_CONN_SEC_MODE_SET_ENC_NO_MITM(ptr) do {(ptr)->sm = 1; (ptr)->lv = 2;} while(0)
+/**@brief Set sec_mode pointed to by ptr to require encryption and MITM protection.*/
+#define BLE_GAP_CONN_SEC_MODE_SET_ENC_WITH_MITM(ptr) do {(ptr)->sm = 1; (ptr)->lv = 3;} while(0)
+/**@brief Set sec_mode pointed to by ptr to require LESC encryption and MITM protection.*/
+#define BLE_GAP_CONN_SEC_MODE_SET_LESC_ENC_WITH_MITM(ptr) do {(ptr)->sm = 1; (ptr)->lv = 4;} while(0)
+/**@brief Set sec_mode pointed to by ptr to require signing or encryption, no MITM protection needed.*/
+#define BLE_GAP_CONN_SEC_MODE_SET_SIGNED_NO_MITM(ptr) do {(ptr)->sm = 2; (ptr)->lv = 1;} while(0)
+/**@brief Set sec_mode pointed to by ptr to require signing or encryption with MITM protection.*/
+#define BLE_GAP_CONN_SEC_MODE_SET_SIGNED_WITH_MITM(ptr) do {(ptr)->sm = 2; (ptr)->lv = 2;} while(0)
+/**@} */
+
+
+/**@brief GAP Security Random Number Length. */
+#define BLE_GAP_SEC_RAND_LEN 8
+
+
+/**@brief GAP Security Key Length. */
+#define BLE_GAP_SEC_KEY_LEN 16
+
+
+/**@brief GAP LE Secure Connections Elliptic Curve Diffie-Hellman P-256 Public Key Length. */
+#define BLE_GAP_LESC_P256_PK_LEN 64
+
+
+/**@brief GAP LE Secure Connections Elliptic Curve Diffie-Hellman DHKey Length. */
+#define BLE_GAP_LESC_DHKEY_LEN 32
+
+
+/**@brief GAP Passkey Length. */
+#define BLE_GAP_PASSKEY_LEN 6
+
+
+/**@brief Maximum amount of addresses in the whitelist. */
+#define BLE_GAP_WHITELIST_ADDR_MAX_COUNT (8)
+
+
+/**@brief Maximum amount of identities in the device identities list. */
+#define BLE_GAP_DEVICE_IDENTITIES_MAX_COUNT (8)
+
+
+/**@brief Default connection count for a configuration. */
+#define BLE_GAP_CONN_COUNT_DEFAULT (1)
+
+
+/**@defgroup BLE_GAP_EVENT_LENGTH GAP event length defines.
+ * @{ */
+#define BLE_GAP_EVENT_LENGTH_MIN (2) /**< Minimum event length, in 1.25 ms units. */
+#define BLE_GAP_EVENT_LENGTH_DEFAULT (3) /**< Default event length, in 1.25 ms units. */
+/**@} */
+
+
+/**@defgroup BLE_GAP_ROLE_COUNT GAP concurrent connection count defines.
+ * @{ */
+#define BLE_GAP_ROLE_COUNT_PERIPH_DEFAULT (1) /**< Default maximum number of connections concurrently acting as peripherals. */
+#define BLE_GAP_ROLE_COUNT_CENTRAL_DEFAULT (3) /**< Default maximum number of connections concurrently acting as centrals. */
+#define BLE_GAP_ROLE_COUNT_CENTRAL_SEC_DEFAULT (1) /**< Default number of SMP instances shared between all connections acting as centrals. */
+#define BLE_GAP_ROLE_COUNT_COMBINED_MAX (20) /**< Maximum supported number of concurrent connections in the peripheral and central roles combined. */
+
+/**@} */
+
+/**@brief Automatic data length parameter. */
+#define BLE_GAP_DATA_LENGTH_AUTO 0
+
+/**@defgroup BLE_GAP_AUTH_PAYLOAD_TIMEOUT Authenticated payload timeout defines.
+ * @{ */
+#define BLE_GAP_AUTH_PAYLOAD_TIMEOUT_MAX (48000) /**< Maximum authenticated payload timeout in 10 ms units, i.e. 8 minutes. */
+#define BLE_GAP_AUTH_PAYLOAD_TIMEOUT_MIN (1) /**< Minimum authenticated payload timeout in 10 ms units, i.e. 10 ms. */
+/**@} */
+
+/**@defgroup GAP_SEC_MODES GAP Security Modes
+ * @{ */
+#define BLE_GAP_SEC_MODE 0x00 /**< No key (may be used to reject). */
+/**@} */
+
+/**@brief The total number of channels in Bluetooth Low Energy. */
+#define BLE_GAP_CHANNEL_COUNT (40)
+
+/**@defgroup BLE_GAP_QOS_CHANNEL_SURVEY_INTERVALS Quality of Service (QoS) Channel survey interval defines
+ * @{ */
+#define BLE_GAP_QOS_CHANNEL_SURVEY_INTERVAL_CONTINUOUS (0) /**< Continuous channel survey. */
+#define BLE_GAP_QOS_CHANNEL_SURVEY_INTERVAL_MIN_US (7500) /**< Minimum channel survey interval in microseconds (7.5 ms). */
+#define BLE_GAP_QOS_CHANNEL_SURVEY_INTERVAL_MAX_US (4000000) /**< Maximum channel survey interval in microseconds (4 s). */
+ /**@} */
+
+/** @} */
+
+
+/**@addtogroup BLE_GAP_STRUCTURES Structures
+ * @{ */
+
+/**@brief Advertising event properties. */
+typedef struct
+{
+ uint8_t type; /**< Advertising type. See @ref BLE_GAP_ADV_TYPES. */
+ uint8_t anonymous : 1; /**< Omit advertiser's address from all PDUs.
+ @note Anonymous advertising is only available for
+ @ref BLE_GAP_ADV_TYPE_EXTENDED_NONCONNECTABLE_NONSCANNABLE_UNDIRECTED and
+ @ref BLE_GAP_ADV_TYPE_EXTENDED_NONCONNECTABLE_NONSCANNABLE_DIRECTED. */
+ uint8_t include_tx_power : 1; /**< Include TxPower set by @ref sd_ble_gap_tx_power_set in the extended header
+ of the advertising PDU.
+ @note TxPower can only be added to the extended header when @ref type is an extended advertising type. */
+} ble_gap_adv_properties_t;
+
+
+/**@brief Advertising report type. */
+typedef struct
+{
+ uint16_t connectable : 1; /**< Connectable advertising event type. */
+ uint16_t scannable : 1; /**< Scannable advertising event type. */
+ uint16_t directed : 1; /**< Directed advertising event type. */
+ uint16_t scan_response : 1; /**< Received a scan response. */
+ uint16_t extended_pdu : 1; /**< Received an extended advertising set. */
+ uint16_t status : 2; /**< Data status. See @ref BLE_GAP_ADV_DATA_STATUS. */
+ uint16_t reserved : 9; /**< Reserved for future use. */
+} ble_gap_adv_report_type_t;
+
+/**@brief Advertising Auxiliary Pointer. */
+typedef struct
+{
+ uint16_t aux_offset; /**< Time offset from the beginning of advertising packet to the auxiliary packet in 100 us units. */
+ uint8_t aux_phy; /**< Indicates the PHY on which the auxiliary advertising packet is sent. See @ref BLE_GAP_PHYS. */
+} ble_gap_aux_pointer_t;
+
+/**@brief Bluetooth Low Energy address. */
+typedef struct
+{
+ uint8_t addr_id_peer : 1; /**< Only valid for peer addresses.
+ Reference to peer in device identities list (as set with @ref sd_ble_gap_device_identities_set) when peer is using privacy. */
+ uint8_t addr_type : 7; /**< See @ref BLE_GAP_ADDR_TYPES. */
+ uint8_t addr[BLE_GAP_ADDR_LEN]; /**< 48-bit address, LSB format.
+ addr is not used if addr_type is @ref BLE_GAP_ADDR_TYPE_ANONYMOUS. */
+} ble_gap_addr_t;
+
+
+/**@brief GAP connection parameters.
+ *
+ * @note When ble_conn_params_t is received in an event, both min_conn_interval and
+ * max_conn_interval will be equal to the connection interval set by the central.
+ *
+ * @note If both conn_sup_timeout and max_conn_interval are specified, then the following constraint applies:
+ * conn_sup_timeout * 4 > (1 + slave_latency) * max_conn_interval
+ * that corresponds to the following Bluetooth Spec requirement:
+ * The Supervision_Timeout in milliseconds shall be larger than
+ * (1 + Conn_Latency) * Conn_Interval_Max * 2, where Conn_Interval_Max is given in milliseconds.
+ */
+typedef struct
+{
+ uint16_t min_conn_interval; /**< Minimum Connection Interval in 1.25 ms units, see @ref BLE_GAP_CP_LIMITS.*/
+ uint16_t max_conn_interval; /**< Maximum Connection Interval in 1.25 ms units, see @ref BLE_GAP_CP_LIMITS.*/
+ uint16_t slave_latency; /**< Slave Latency in number of connection events, see @ref BLE_GAP_CP_LIMITS.*/
+ uint16_t conn_sup_timeout; /**< Connection Supervision Timeout in 10 ms units, see @ref BLE_GAP_CP_LIMITS.*/
+} ble_gap_conn_params_t;
+
+
+/**@brief GAP connection security modes.
+ *
+ * Security Mode 0 Level 0: No access permissions at all (this level is not defined by the Bluetooth Core specification).\n
+ * Security Mode 1 Level 1: No security is needed (aka open link).\n
+ * Security Mode 1 Level 2: Encrypted link required, MITM protection not necessary.\n
+ * Security Mode 1 Level 3: MITM protected encrypted link required.\n
+ * Security Mode 1 Level 4: LESC MITM protected encrypted link using a 128-bit strength encryption key required.\n
+ * Security Mode 2 Level 1: Signing or encryption required, MITM protection not necessary.\n
+ * Security Mode 2 Level 2: MITM protected signing required, unless link is MITM protected encrypted.\n
+ */
+typedef struct
+{
+ uint8_t sm : 4; /**< Security Mode (1 or 2), 0 for no permissions at all. */
+ uint8_t lv : 4; /**< Level (1, 2, 3 or 4), 0 for no permissions at all. */
+
+} ble_gap_conn_sec_mode_t;
+
+
+/**@brief GAP connection security status.*/
+typedef struct
+{
+ ble_gap_conn_sec_mode_t sec_mode; /**< Currently active security mode for this connection.*/
+ uint8_t encr_key_size; /**< Length of currently active encryption key, 7 to 16 octets (only applicable for bonding procedures). */
+} ble_gap_conn_sec_t;
+
+/**@brief Identity Resolving Key. */
+typedef struct
+{
+ uint8_t irk[BLE_GAP_SEC_KEY_LEN]; /**< Array containing IRK. */
+} ble_gap_irk_t;
+
+
+/**@brief Channel mask (40 bits).
+ * Every channel is represented with a bit positioned as per channel index defined in Bluetooth Core Specification v5.0,
+ * Vol 6, Part B, Section 1.4.1. The LSB contained in array element 0 represents channel index 0, and bit 39 represents
+ * channel index 39. If a bit is set to 1, the channel is not used.
+ */
+typedef uint8_t ble_gap_ch_mask_t[5];
+
+
+/**@brief GAP advertising parameters. */
+typedef struct
+{
+ ble_gap_adv_properties_t properties; /**< The properties of the advertising events. */
+ ble_gap_addr_t const *p_peer_addr; /**< Address of a known peer.
+ @note ble_gap_addr_t::addr_type cannot be
+ @ref BLE_GAP_ADDR_TYPE_ANONYMOUS.
+ - When privacy is enabled and the local device uses
+ @ref BLE_GAP_ADDR_TYPE_RANDOM_PRIVATE_RESOLVABLE addresses,
+ the device identity list is searched for a matching entry. If
+ the local IRK for that device identity is set, the local IRK
+ for that device will be used to generate the advertiser address
+ field in the advertising packet.
+ - If @ref ble_gap_adv_properties_t::type is directed, this must be
+ set to the targeted scanner or initiator. If the peer address is
+ in the device identity list, the peer IRK for that device will be
+ used to generate @ref BLE_GAP_ADDR_TYPE_RANDOM_PRIVATE_RESOLVABLE
+ target addresses used in the advertising event PDUs. */
+ uint32_t interval; /**< Advertising interval in 625 us units. @sa BLE_GAP_ADV_INTERVALS.
+ @note If @ref ble_gap_adv_properties_t::type is set to
+ @ref BLE_GAP_ADV_TYPE_CONNECTABLE_NONSCANNABLE_DIRECTED_HIGH_DUTY_CYCLE
+ advertising, this parameter is ignored. */
+ uint16_t duration; /**< Advertising duration in 10 ms units. When timeout is reached,
+ an event of type @ref BLE_GAP_EVT_ADV_SET_TERMINATED is raised.
+ @sa BLE_GAP_ADV_TIMEOUT_VALUES. */
+ uint8_t max_adv_evts; /**< Maximum advertising events that shall be sent prior to disabling
+ advertising. Setting the value to 0 disables the limitation. When
+ the count of advertising events specified by this parameter
+ (if not 0) is reached, advertising will be automatically stopped
+ and an event of type @ref BLE_GAP_EVT_ADV_SET_TERMINATED is raised
+ @note If @ref ble_gap_adv_properties_t::type is set to
+ @ref BLE_GAP_ADV_TYPE_CONNECTABLE_NONSCANNABLE_DIRECTED_HIGH_DUTY_CYCLE,
+ this parameter is ignored.
+ @note Setting max_adv_evts to a values not equal to 0 is only supported
+ as an experimental feature in this SoftDevice. */
+ ble_gap_ch_mask_t channel_mask; /**< Channel mask for primary and secondary advertising channels.
+ At least one of the primary channels, that is channel index 37-39, must be used.
+ Masking away secondary advertising channels is not supported. */
+ uint8_t filter_policy; /**< Filter Policy. @sa BLE_GAP_ADV_FILTER_POLICIES. */
+ uint8_t primary_phy; /**< Indicates the PHY on which the primary advertising channel packets
+ are transmitted. If set to @ref BLE_GAP_PHY_AUTO, @ref BLE_GAP_PHY_1MBPS
+ will be used.
+ The only supported value by this SoftDevice is @ref BLE_GAP_PHY_1MBPS. */
+ uint8_t secondary_phy; /**< Indicates the PHY on which the secondary advertising channel packets
+ are transmitted.
+ If set to @ref BLE_GAP_PHY_AUTO, @ref BLE_GAP_PHY_1MBPS will be used.
+ Valid values are
+ @ref BLE_GAP_PHY_1MBPS and @ref BLE_GAP_PHY_2MBPS. @ref BLE_GAP_PHY_CODED
+ is not supported by this SoftDevice.
+ If @ref ble_gap_adv_properties_t::type is an extended advertising type
+ and connectable, this is the PHY that will be used to establish a
+ connection and send AUX_ADV_IND packets on.
+ @note This parameter will be ignored when
+ @ref ble_gap_adv_properties_t::type is not an extended advertising type. */
+ uint8_t set_id:4; /**< The advertising set identifier distinguishes this advertising set from other
+ advertising sets transmitted by this and other devices.
+ @note This parameter will be ignored when
+ @ref ble_gap_adv_properties_t::type is not an extended advertising type. */
+ uint8_t scan_req_notification:1; /**< Enable scan request notifications for this advertising set. When a
+ scan request is received and the scanner address is allowed
+ by the filter policy, @ref BLE_GAP_EVT_SCAN_REQ_REPORT is raised.
+ @note This parameter will be ignored when
+ @ref ble_gap_adv_properties_t::type is a non-scannable
+ advertising type. */
+} ble_gap_adv_params_t;
+
+
+/**@brief GAP advertising data buffers.
+ *
+ * The application must provide the buffers for advertisement. The memory shall reside in application RAM, and
+ * shall never be modified while advertising. The data shall be kept alive until either:
+ * - @ref BLE_GAP_EVT_ADV_SET_TERMINATED is raised.
+ * - @ref BLE_GAP_EVT_CONNECTED is raised with @ref ble_gap_evt_connected_t::adv_handle set to the corresponding
+ * advertising handle.
+ * - Advertising is stopped.
+ * - Advertising data is changed.
+ * To update advertising data while advertising, provide new buffers to @ref sd_ble_gap_adv_set_configure. */
+typedef struct
+{
+ ble_data_t adv_data; /**< Advertising data.
+ @note
+ Advertising data can only be specified for a @ref ble_gap_adv_properties_t::type
+ that is allowed to contain advertising data. */
+ ble_data_t scan_rsp_data; /**< Scan response data.
+ @note
+ Scan response data can only be specified for a @ref ble_gap_adv_properties_t::type
+ that is scannable. */
+} ble_gap_adv_data_t;
+
+
+/**@brief GAP scanning parameters. */
+typedef struct
+{
+ uint8_t extended : 1; /**< If 1, the scanner will accept extended advertising packets.
+ If set to 0, the scanner will not receive advertising packets
+ on secondary advertising channels, and will not be able
+ to receive long advertising PDUs.
+ @note Extended scanning is only supported as an experimental feature in this
+ SoftDevice. */
+ uint8_t report_incomplete_evts : 1; /**< If 1, events of type @ref ble_gap_evt_adv_report_t may have
+ @ref ble_gap_adv_report_type_t::status set to
+ @ref BLE_GAP_ADV_DATA_STATUS_INCOMPLETE_MORE_DATA.
+ This parameter is ignored when used with @ref sd_ble_gap_connect
+ @note This may be used to abort receiving more packets from an extended
+ advertising event, and is only available for extended
+ scanning, see @ref sd_ble_gap_scan_start.
+ @note This feature is not supported by this SoftDevice. */
+ uint8_t active : 1; /**< If 1, perform active scanning by sending scan requests.
+ This parameter is ignored when used with @ref sd_ble_gap_connect. */
+ uint8_t filter_policy : 2; /**< Scanning filter policy. @sa BLE_GAP_SCAN_FILTER_POLICIES.
+ @note Only @ref BLE_GAP_SCAN_FP_ACCEPT_ALL and
+ @ref BLE_GAP_SCAN_FP_WHITELIST are valid when used with
+ @ref sd_ble_gap_connect */
+ uint8_t scan_phys; /**< Bitfield of PHYs to scan on. If set to @ref BLE_GAP_PHY_AUTO,
+ scan_phys will default to @ref BLE_GAP_PHY_1MBPS.
+ - If @ref ble_gap_scan_params_t::extended is set to 0, the only
+ supported PHY is @ref BLE_GAP_PHY_1MBPS.
+ - When used with @ref sd_ble_gap_scan_start,
+ the bitfield indicates the PHYs the scanner will use for scanning
+ on primary advertising channels. The scanner will accept
+ @ref BLE_GAP_PHYS_SUPPORTED as secondary advertising channel PHYs.
+ - When used with @ref sd_ble_gap_connect, the
+ bitfield indicates the PHYs on where a connection may be initiated.
+ If scan_phys contains @ref BLE_GAP_PHY_1MBPS and/or @ref BLE_GAP_PHY_2MBPS,
+ the primary scan PHY is @ref BLE_GAP_PHY_1MBPS. */
+ uint16_t interval; /**< Scan interval in 625 us units. @sa BLE_GAP_SCAN_INTERVALS. */
+ uint16_t window; /**< Scan window in 625 us units. @sa BLE_GAP_SCAN_WINDOW. */
+ uint16_t timeout; /**< Scan timeout in 10 ms units. @sa BLE_GAP_SCAN_TIMEOUT. */
+ ble_gap_ch_mask_t channel_mask; /**< Channel mask for primary and secondary advertising channels.
+ At least one of the primary channels, that is channel index 37-39, must be
+ set to 0.
+ Masking away secondary channels is not supported. */
+} ble_gap_scan_params_t;
+
+
+/**@brief Privacy.
+ *
+ * The privacy feature provides a way for the device to avoid being tracked over a period of time.
+ * The privacy feature, when enabled, hides the local device identity and replaces it with a private address
+ * that is automatically refreshed at a specified interval.
+ *
+ * If a device still wants to be recognized by other peers, it needs to share it's Identity Resolving Key (IRK).
+ * With this key, a device can generate a random private address that can only be recognized by peers in possession of that key,
+ * and devices can establish connections without revealing their real identities.
+ *
+ * Both network privacy (@ref BLE_GAP_PRIVACY_MODE_NETWORK_PRIVACY) and device privacy (@ref BLE_GAP_PRIVACY_MODE_DEVICE_PRIVACY)
+ * are supported.
+ *
+ * @note If the device IRK is updated, the new IRK becomes the one to be distributed in all
+ * bonding procedures performed after @ref sd_ble_gap_privacy_set returns.
+ * The IRK distributed during bonding procedure is the device IRK that is active when @ref sd_ble_gap_sec_params_reply is called.
+ */
+typedef struct
+{
+ uint8_t privacy_mode; /**< Privacy mode, see @ref BLE_GAP_PRIVACY_MODES. Default is @ref BLE_GAP_PRIVACY_MODE_OFF. */
+ uint8_t private_addr_type; /**< The private address type must be either @ref BLE_GAP_ADDR_TYPE_RANDOM_PRIVATE_RESOLVABLE or @ref BLE_GAP_ADDR_TYPE_RANDOM_PRIVATE_NON_RESOLVABLE. */
+ uint16_t private_addr_cycle_s; /**< Private address cycle interval in seconds. Providing an address cycle value of 0 will use the default value defined by @ref BLE_GAP_DEFAULT_PRIVATE_ADDR_CYCLE_INTERVAL_S. */
+ ble_gap_irk_t *p_device_irk; /**< When used as input, pointer to IRK structure that will be used as the default IRK. If NULL, the device default IRK will be used.
+ When used as output, pointer to IRK structure where the current default IRK will be written to. If NULL, this argument is ignored.
+ By default, the default IRK is used to generate random private resolvable addresses for the local device unless instructed otherwise. */
+} ble_gap_privacy_params_t;
+
+
+/**@brief PHY preferences for TX and RX
+ * @note tx_phys and rx_phys are bit fields. Multiple bits can be set in them to indicate multiple preferred PHYs for each direction.
+ * @code
+ * p_gap_phys->tx_phys = BLE_GAP_PHY_1MBPS | BLE_GAP_PHY_2MBPS;
+ * p_gap_phys->rx_phys = BLE_GAP_PHY_1MBPS | BLE_GAP_PHY_2MBPS;
+ * @endcode
+ *
+ */
+typedef struct
+{
+ uint8_t tx_phys; /**< Preferred transmit PHYs, see @ref BLE_GAP_PHYS. */
+ uint8_t rx_phys; /**< Preferred receive PHYs, see @ref BLE_GAP_PHYS. */
+} ble_gap_phys_t;
+
+/** @brief Keys that can be exchanged during a bonding procedure. */
+typedef struct
+{
+ uint8_t enc : 1; /**< Long Term Key and Master Identification. */
+ uint8_t id : 1; /**< Identity Resolving Key and Identity Address Information. */
+ uint8_t sign : 1; /**< Connection Signature Resolving Key. */
+ uint8_t link : 1; /**< Derive the Link Key from the LTK. */
+} ble_gap_sec_kdist_t;
+
+
+/**@brief GAP security parameters. */
+typedef struct
+{
+ uint8_t bond : 1; /**< Perform bonding. */
+ uint8_t mitm : 1; /**< Enable Man In The Middle protection. */
+ uint8_t lesc : 1; /**< Enable LE Secure Connection pairing. */
+ uint8_t keypress : 1; /**< Enable generation of keypress notifications. */
+ uint8_t io_caps : 3; /**< IO capabilities, see @ref BLE_GAP_IO_CAPS. */
+ uint8_t oob : 1; /**< The OOB data flag.
+ - In LE legacy pairing, this flag is set if a device has out of band authentication data.
+ The OOB method is used if both of the devices have out of band authentication data.
+ - In LE Secure Connections pairing, this flag is set if a device has the peer device's out of band authentication data.
+ The OOB method is used if at least one device has the peer device's OOB data available. */
+ uint8_t min_key_size; /**< Minimum encryption key size in octets between 7 and 16. If 0 then not applicable in this instance. */
+ uint8_t max_key_size; /**< Maximum encryption key size in octets between min_key_size and 16. */
+ ble_gap_sec_kdist_t kdist_own; /**< Key distribution bitmap: keys that the local device will distribute. */
+ ble_gap_sec_kdist_t kdist_peer; /**< Key distribution bitmap: keys that the remote device will distribute. */
+} ble_gap_sec_params_t;
+
+
+/**@brief GAP Encryption Information. */
+typedef struct
+{
+ uint8_t ltk[BLE_GAP_SEC_KEY_LEN]; /**< Long Term Key. */
+ uint8_t lesc : 1; /**< Key generated using LE Secure Connections. */
+ uint8_t auth : 1; /**< Authenticated Key. */
+ uint8_t ltk_len : 6; /**< LTK length in octets. */
+} ble_gap_enc_info_t;
+
+
+/**@brief GAP Master Identification. */
+typedef struct
+{
+ uint16_t ediv; /**< Encrypted Diversifier. */
+ uint8_t rand[BLE_GAP_SEC_RAND_LEN]; /**< Random Number. */
+} ble_gap_master_id_t;
+
+
+/**@brief GAP Signing Information. */
+typedef struct
+{
+ uint8_t csrk[BLE_GAP_SEC_KEY_LEN]; /**< Connection Signature Resolving Key. */
+} ble_gap_sign_info_t;
+
+
+/**@brief GAP LE Secure Connections P-256 Public Key. */
+typedef struct
+{
+ uint8_t pk[BLE_GAP_LESC_P256_PK_LEN]; /**< LE Secure Connections Elliptic Curve Diffie-Hellman P-256 Public Key. Stored in the standard SMP protocol format: {X,Y} both in little-endian. */
+} ble_gap_lesc_p256_pk_t;
+
+
+/**@brief GAP LE Secure Connections DHKey. */
+typedef struct
+{
+ uint8_t key[BLE_GAP_LESC_DHKEY_LEN]; /**< LE Secure Connections Elliptic Curve Diffie-Hellman Key. Stored in little-endian. */
+} ble_gap_lesc_dhkey_t;
+
+
+/**@brief GAP LE Secure Connections OOB data. */
+typedef struct
+{
+ ble_gap_addr_t addr; /**< Bluetooth address of the device. */
+ uint8_t r[BLE_GAP_SEC_KEY_LEN]; /**< Random Number. */
+ uint8_t c[BLE_GAP_SEC_KEY_LEN]; /**< Confirm Value. */
+} ble_gap_lesc_oob_data_t;
+
+
+/**@brief Event structure for @ref BLE_GAP_EVT_CONNECTED. */
+typedef struct
+{
+ ble_gap_addr_t peer_addr; /**< Bluetooth address of the peer device. If the peer_addr resolved: @ref ble_gap_addr_t::addr_id_peer is set to 1
+ and the address is the device's identity address. */
+ uint8_t role; /**< BLE role for this connection, see @ref BLE_GAP_ROLES */
+ ble_gap_conn_params_t conn_params; /**< GAP Connection Parameters. */
+ uint8_t adv_handle; /**< Advertising handle in which advertising has ended.
+ This variable is only set if role is set to @ref BLE_GAP_ROLE_PERIPH. */
+ ble_gap_adv_data_t adv_data; /**< Advertising buffers corresponding to the terminated
+ advertising set. The advertising buffers provided in
+ @ref sd_ble_gap_adv_set_configure are now released.
+ This variable is only set if role is set to @ref BLE_GAP_ROLE_PERIPH. */
+} ble_gap_evt_connected_t;
+
+
+/**@brief Event structure for @ref BLE_GAP_EVT_DISCONNECTED. */
+typedef struct
+{
+ uint8_t reason; /**< HCI error code, see @ref BLE_HCI_STATUS_CODES. */
+} ble_gap_evt_disconnected_t;
+
+
+/**@brief Event structure for @ref BLE_GAP_EVT_CONN_PARAM_UPDATE. */
+typedef struct
+{
+ ble_gap_conn_params_t conn_params; /**< GAP Connection Parameters. */
+} ble_gap_evt_conn_param_update_t;
+
+/**@brief Event structure for @ref BLE_GAP_EVT_PHY_UPDATE_REQUEST. */
+typedef struct
+{
+ ble_gap_phys_t peer_preferred_phys; /**< The PHYs the peer prefers to use. */
+} ble_gap_evt_phy_update_request_t;
+
+/**@brief Event Structure for @ref BLE_GAP_EVT_PHY_UPDATE. */
+typedef struct
+{
+ uint8_t status; /**< Status of the procedure, see @ref BLE_HCI_STATUS_CODES.*/
+ uint8_t tx_phy; /**< TX PHY for this connection, see @ref BLE_GAP_PHYS. */
+ uint8_t rx_phy; /**< RX PHY for this connection, see @ref BLE_GAP_PHYS. */
+} ble_gap_evt_phy_update_t;
+
+/**@brief Event structure for @ref BLE_GAP_EVT_SEC_PARAMS_REQUEST. */
+typedef struct
+{
+ ble_gap_sec_params_t peer_params; /**< Initiator Security Parameters. */
+} ble_gap_evt_sec_params_request_t;
+
+
+/**@brief Event structure for @ref BLE_GAP_EVT_SEC_INFO_REQUEST. */
+typedef struct
+{
+ ble_gap_addr_t peer_addr; /**< Bluetooth address of the peer device. */
+ ble_gap_master_id_t master_id; /**< Master Identification for LTK lookup. */
+ uint8_t enc_info : 1; /**< If 1, Encryption Information required. */
+ uint8_t id_info : 1; /**< If 1, Identity Information required. */
+ uint8_t sign_info : 1; /**< If 1, Signing Information required. */
+} ble_gap_evt_sec_info_request_t;
+
+
+/**@brief Event structure for @ref BLE_GAP_EVT_PASSKEY_DISPLAY. */
+typedef struct
+{
+ uint8_t passkey[BLE_GAP_PASSKEY_LEN]; /**< 6-digit passkey in ASCII ('0'-'9' digits only). */
+ uint8_t match_request : 1; /**< If 1 requires the application to report the match using @ref sd_ble_gap_auth_key_reply
+ with either @ref BLE_GAP_AUTH_KEY_TYPE_NONE if there is no match or
+ @ref BLE_GAP_AUTH_KEY_TYPE_PASSKEY if there is a match. */
+} ble_gap_evt_passkey_display_t;
+
+/**@brief Event structure for @ref BLE_GAP_EVT_KEY_PRESSED. */
+typedef struct
+{
+ uint8_t kp_not; /**< Keypress notification type, see @ref BLE_GAP_KP_NOT_TYPES. */
+} ble_gap_evt_key_pressed_t;
+
+
+/**@brief Event structure for @ref BLE_GAP_EVT_AUTH_KEY_REQUEST. */
+typedef struct
+{
+ uint8_t key_type; /**< See @ref BLE_GAP_AUTH_KEY_TYPES. */
+} ble_gap_evt_auth_key_request_t;
+
+/**@brief Event structure for @ref BLE_GAP_EVT_LESC_DHKEY_REQUEST. */
+typedef struct
+{
+ ble_gap_lesc_p256_pk_t *p_pk_peer; /**< LE Secure Connections remote P-256 Public Key. This will point to the application-supplied memory
+ inside the keyset during the call to @ref sd_ble_gap_sec_params_reply. */
+ uint8_t oobd_req :1; /**< LESC OOB data required. A call to @ref sd_ble_gap_lesc_oob_data_set is required to complete the procedure. */
+} ble_gap_evt_lesc_dhkey_request_t;
+
+
+/**@brief Security levels supported.
+ * @note See Bluetooth Specification Version 4.2 Volume 3, Part C, Chapter 10, Section 10.2.1.
+*/
+typedef struct
+{
+ uint8_t lv1 : 1; /**< If 1: Level 1 is supported. */
+ uint8_t lv2 : 1; /**< If 1: Level 2 is supported. */
+ uint8_t lv3 : 1; /**< If 1: Level 3 is supported. */
+ uint8_t lv4 : 1; /**< If 1: Level 4 is supported. */
+} ble_gap_sec_levels_t;
+
+
+/**@brief Encryption Key. */
+typedef struct
+{
+ ble_gap_enc_info_t enc_info; /**< Encryption Information. */
+ ble_gap_master_id_t master_id; /**< Master Identification. */
+} ble_gap_enc_key_t;
+
+
+/**@brief Identity Key. */
+typedef struct
+{
+ ble_gap_irk_t id_info; /**< Identity Resolving Key. */
+ ble_gap_addr_t id_addr_info; /**< Identity Address. */
+} ble_gap_id_key_t;
+
+
+/**@brief Security Keys. */
+typedef struct
+{
+ ble_gap_enc_key_t *p_enc_key; /**< Encryption Key, or NULL. */
+ ble_gap_id_key_t *p_id_key; /**< Identity Key, or NULL. */
+ ble_gap_sign_info_t *p_sign_key; /**< Signing Key, or NULL. */
+ ble_gap_lesc_p256_pk_t *p_pk; /**< LE Secure Connections P-256 Public Key. When in debug mode the application must use the value defined
+ in the Core Bluetooth Specification v4.2 Vol.3, Part H, Section 2.3.5.6.1 */
+} ble_gap_sec_keys_t;
+
+
+/**@brief Security key set for both local and peer keys. */
+typedef struct
+{
+ ble_gap_sec_keys_t keys_own; /**< Keys distributed by the local device. For LE Secure Connections the encryption key will be generated locally and will always be stored if bonding. */
+ ble_gap_sec_keys_t keys_peer; /**< Keys distributed by the remote device. For LE Secure Connections, p_enc_key must always be NULL. */
+} ble_gap_sec_keyset_t;
+
+
+/**@brief Data Length Update Procedure parameters. */
+typedef struct
+{
+ uint16_t max_tx_octets; /**< Maximum number of payload octets that a Controller supports for transmission of a single Link Layer Data Channel PDU. */
+ uint16_t max_rx_octets; /**< Maximum number of payload octets that a Controller supports for reception of a single Link Layer Data Channel PDU. */
+ uint16_t max_tx_time_us; /**< Maximum time, in microseconds, that a Controller supports for transmission of a single Link Layer Data Channel PDU. */
+ uint16_t max_rx_time_us; /**< Maximum time, in microseconds, that a Controller supports for reception of a single Link Layer Data Channel PDU. */
+} ble_gap_data_length_params_t;
+
+
+/**@brief Data Length Update Procedure local limitation. */
+typedef struct
+{
+ uint16_t tx_payload_limited_octets; /**< If > 0, the requested TX packet length is too long by this many octets. */
+ uint16_t rx_payload_limited_octets; /**< If > 0, the requested RX packet length is too long by this many octets. */
+ uint16_t tx_rx_time_limited_us; /**< If > 0, the requested combination of TX and RX packet lengths is too long by this many microseconds. */
+} ble_gap_data_length_limitation_t;
+
+
+/**@brief Event structure for @ref BLE_GAP_EVT_AUTH_STATUS. */
+typedef struct
+{
+ uint8_t auth_status; /**< Authentication status, see @ref BLE_GAP_SEC_STATUS. */
+ uint8_t error_src : 2; /**< On error, source that caused the failure, see @ref BLE_GAP_SEC_STATUS_SOURCES. */
+ uint8_t bonded : 1; /**< Procedure resulted in a bond. */
+ uint8_t lesc : 1; /**< Procedure resulted in a LE Secure Connection. */
+ ble_gap_sec_levels_t sm1_levels; /**< Levels supported in Security Mode 1. */
+ ble_gap_sec_levels_t sm2_levels; /**< Levels supported in Security Mode 2. */
+ ble_gap_sec_kdist_t kdist_own; /**< Bitmap stating which keys were exchanged (distributed) by the local device. If bonding with LE Secure Connections, the enc bit will be always set. */
+ ble_gap_sec_kdist_t kdist_peer; /**< Bitmap stating which keys were exchanged (distributed) by the remote device. If bonding with LE Secure Connections, the enc bit will never be set. */
+} ble_gap_evt_auth_status_t;
+
+
+/**@brief Event structure for @ref BLE_GAP_EVT_CONN_SEC_UPDATE. */
+typedef struct
+{
+ ble_gap_conn_sec_t conn_sec; /**< Connection security level. */
+} ble_gap_evt_conn_sec_update_t;
+
+
+/**@brief Event structure for @ref BLE_GAP_EVT_TIMEOUT. */
+typedef struct
+{
+ uint8_t src; /**< Source of timeout event, see @ref BLE_GAP_TIMEOUT_SOURCES. */
+ union
+ {
+ ble_data_t adv_report_buffer; /**< If source is set to @ref BLE_GAP_TIMEOUT_SRC_SCAN, the released
+ scan buffer is contained in this field. */
+ } params; /**< Event Parameters. */
+} ble_gap_evt_timeout_t;
+
+
+/**@brief Event structure for @ref BLE_GAP_EVT_RSSI_CHANGED. */
+typedef struct
+{
+ int8_t rssi; /**< Received Signal Strength Indication in dBm. */
+ uint8_t ch_index; /**< Data Channel Index on which the Signal Strength is measured (0-36). */
+} ble_gap_evt_rssi_changed_t;
+
+/**@brief Event structure for @ref BLE_GAP_EVT_ADV_SET_TERMINATED */
+typedef struct
+{
+ uint8_t reason; /**< Reason for why the advertising set terminated. See
+ @ref BLE_GAP_EVT_ADV_SET_TERMINATED_REASON. */
+ uint8_t adv_handle; /**< Advertising handle in which advertising has ended. */
+ uint8_t num_completed_adv_events; /**< If @ref ble_gap_adv_params_t::max_adv_evts was not set to 0,
+ this field indicates the number of completed advertising events. */
+ ble_gap_adv_data_t adv_data; /**< Advertising buffers corresponding to the terminated
+ advertising set. The advertising buffers provided in
+ @ref sd_ble_gap_adv_set_configure are now released. */
+} ble_gap_evt_adv_set_terminated_t;
+
+/**@brief Event structure for @ref BLE_GAP_EVT_ADV_REPORT.
+ *
+ * @note If @ref ble_gap_adv_report_type_t::status is set to @ref BLE_GAP_ADV_DATA_STATUS_INCOMPLETE_MORE_DATA,
+ * not all fields in the advertising report may be available.
+ *
+ * @note When ble_gap_adv_report_type_t::status is not set to @ref BLE_GAP_ADV_DATA_STATUS_INCOMPLETE_MORE_DATA,
+ * scanning will be paused. To continue scanning, call @ref sd_ble_gap_scan_start.
+ */
+typedef struct
+{
+ ble_gap_adv_report_type_t type; /**< Advertising report type. See @ref ble_gap_adv_report_type_t. */
+ ble_gap_addr_t peer_addr; /**< Bluetooth address of the peer device. If the peer_addr is resolved:
+ @ref ble_gap_addr_t::addr_id_peer is set to 1 and the address is the
+ peer's identity address. */
+ ble_gap_addr_t direct_addr; /**< Contains the target address of the advertising event if
+ @ref ble_gap_adv_report_type_t::directed is set to 1. If the
+ SoftDevice was able to resolve the address,
+ @ref ble_gap_addr_t::addr_id_peer is set to 1 and the direct_addr
+ contains the local identity address. If the target address of the
+ advertising event is @ref BLE_GAP_ADDR_TYPE_RANDOM_PRIVATE_RESOLVABLE,
+ and the SoftDevice was unable to resolve it, the application may try
+ to resolve this address to find out if the advertising event was
+ directed to us. */
+ uint8_t primary_phy; /**< Indicates the PHY on which the primary advertising packet was received on.
+ See @ref BLE_GAP_PHYS. */
+ uint8_t secondary_phy; /**< Indicates the PHY on which the secondary advertising packet was received on.
+ See @ref BLE_GAP_PHYS. This field is to 0 if no packets where received on
+ a secondary advertising channel. */
+ int8_t tx_power; /**< TX Power reported by the advertiser in the last packet header received.
+ This field is set to @ref BLE_GAP_POWER_LEVEL_INVALID if the
+ last received packet did not contain the Tx Power field.
+ @note TX Power is only included in extended advertising packets. */
+ int8_t rssi; /**< Received Signal Strength Indication in dBm of the last packet received. */
+ uint8_t ch_index; /**< Channel Index on which the last advertising packet is received (0-39). */
+ uint8_t set_id; /**< Set ID of the received advertising data. Set ID is not present
+ if set to @ref BLE_GAP_ADV_REPORT_SET_ID_NOT_AVAILABLE. */
+ uint16_t data_id:12; /**< The advertising data ID of the received advertising data. Data ID
+ is not present if @ref ble_gap_evt_adv_report_t::set_id is set to
+ @ref BLE_GAP_ADV_REPORT_SET_ID_NOT_AVAILABLE. */
+ ble_data_t data; /**< Received advertising or scan response data. If
+ @ref ble_gap_adv_report_type_t::status is not set to
+ @ref BLE_GAP_ADV_DATA_STATUS_INCOMPLETE_MORE_DATA, the data buffer provided
+ in @ref sd_ble_gap_scan_start is now released. */
+ ble_gap_aux_pointer_t aux_pointer; /**< The offset and PHY of the next advertising packet in this extended advertising
+ event. @note This field is only set if @ref ble_gap_adv_report_type_t::status
+ is set to @ref BLE_GAP_ADV_DATA_STATUS_INCOMPLETE_MORE_DATA. */
+} ble_gap_evt_adv_report_t;
+
+
+/**@brief Event structure for @ref BLE_GAP_EVT_SEC_REQUEST. */
+typedef struct
+{
+ uint8_t bond : 1; /**< Perform bonding. */
+ uint8_t mitm : 1; /**< Man In The Middle protection requested. */
+ uint8_t lesc : 1; /**< LE Secure Connections requested. */
+ uint8_t keypress : 1; /**< Generation of keypress notifications requested. */
+} ble_gap_evt_sec_request_t;
+
+
+/**@brief Event structure for @ref BLE_GAP_EVT_CONN_PARAM_UPDATE_REQUEST. */
+typedef struct
+{
+ ble_gap_conn_params_t conn_params; /**< GAP Connection Parameters. */
+} ble_gap_evt_conn_param_update_request_t;
+
+
+/**@brief Event structure for @ref BLE_GAP_EVT_SCAN_REQ_REPORT. */
+typedef struct
+{
+ uint8_t adv_handle; /**< Advertising handle for the advertising set which received the Scan Request */
+ int8_t rssi; /**< Received Signal Strength Indication in dBm. */
+ ble_gap_addr_t peer_addr; /**< Bluetooth address of the peer device. If the peer_addr resolved: @ref ble_gap_addr_t::addr_id_peer is set to 1
+ and the address is the device's identity address. */
+} ble_gap_evt_scan_req_report_t;
+
+
+/**@brief Event structure for @ref BLE_GAP_EVT_DATA_LENGTH_UPDATE_REQUEST. */
+typedef struct
+{
+ ble_gap_data_length_params_t peer_params; /**< Peer data length parameters. */
+} ble_gap_evt_data_length_update_request_t;
+
+/**@brief Event structure for @ref BLE_GAP_EVT_DATA_LENGTH_UPDATE. */
+typedef struct
+{
+ ble_gap_data_length_params_t effective_params; /**< The effective data length parameters. */
+} ble_gap_evt_data_length_update_t;
+
+
+/**@brief Event structure for @ref BLE_GAP_EVT_QOS_CHANNEL_SURVEY_REPORT. */
+typedef struct
+{
+ int8_t channel_energy[BLE_GAP_CHANNEL_COUNT]; /**< The measured energy on the Bluetooth Low Energy
+ channels, in dBm, indexed by Channel Index.
+ If no measurement is available for the given channel, channel_energy is set to
+ @ref BLE_GAP_POWER_LEVEL_INVALID. */
+} ble_gap_evt_qos_channel_survey_report_t;
+
+/**@brief GAP event structure. */
+typedef struct
+{
+ uint16_t conn_handle; /**< Connection Handle on which event occurred. */
+ union /**< union alternative identified by evt_id in enclosing struct. */
+ {
+ ble_gap_evt_connected_t connected; /**< Connected Event Parameters. */
+ ble_gap_evt_disconnected_t disconnected; /**< Disconnected Event Parameters. */
+ ble_gap_evt_conn_param_update_t conn_param_update; /**< Connection Parameter Update Parameters. */
+ ble_gap_evt_sec_params_request_t sec_params_request; /**< Security Parameters Request Event Parameters. */
+ ble_gap_evt_sec_info_request_t sec_info_request; /**< Security Information Request Event Parameters. */
+ ble_gap_evt_passkey_display_t passkey_display; /**< Passkey Display Event Parameters. */
+ ble_gap_evt_key_pressed_t key_pressed; /**< Key Pressed Event Parameters. */
+ ble_gap_evt_auth_key_request_t auth_key_request; /**< Authentication Key Request Event Parameters. */
+ ble_gap_evt_lesc_dhkey_request_t lesc_dhkey_request; /**< LE Secure Connections DHKey calculation request. */
+ ble_gap_evt_auth_status_t auth_status; /**< Authentication Status Event Parameters. */
+ ble_gap_evt_conn_sec_update_t conn_sec_update; /**< Connection Security Update Event Parameters. */
+ ble_gap_evt_timeout_t timeout; /**< Timeout Event Parameters. */
+ ble_gap_evt_rssi_changed_t rssi_changed; /**< RSSI Event Parameters. */
+ ble_gap_evt_adv_report_t adv_report; /**< Advertising Report Event Parameters. */
+ ble_gap_evt_adv_set_terminated_t adv_set_terminated; /**< Advertising Set Terminated Event Parameters. */
+ ble_gap_evt_sec_request_t sec_request; /**< Security Request Event Parameters. */
+ ble_gap_evt_conn_param_update_request_t conn_param_update_request; /**< Connection Parameter Update Parameters. */
+ ble_gap_evt_scan_req_report_t scan_req_report; /**< Scan Request Report Parameters. */
+ ble_gap_evt_phy_update_request_t phy_update_request; /**< PHY Update Request Event Parameters. */
+ ble_gap_evt_phy_update_t phy_update; /**< PHY Update Parameters. */
+ ble_gap_evt_data_length_update_request_t data_length_update_request; /**< Data Length Update Request Event Parameters. */
+ ble_gap_evt_data_length_update_t data_length_update; /**< Data Length Update Event Parameters. */
+ ble_gap_evt_qos_channel_survey_report_t qos_channel_survey_report; /**< Quality of Service (QoS) Channel Survey Report Parameters. */
+ } params; /**< Event Parameters. */
+} ble_gap_evt_t;
+
+
+/**
+ * @brief BLE GAP connection configuration parameters, set with @ref sd_ble_cfg_set.
+ *
+ * @retval ::NRF_ERROR_CONN_COUNT The connection count for the connection configurations is zero.
+ * @retval ::NRF_ERROR_INVALID_PARAM One or more of the following is true:
+ * - The sum of conn_count for all connection configurations combined exceeds UINT8_MAX.
+ * - The event length is smaller than @ref BLE_GAP_EVENT_LENGTH_MIN.
+ */
+typedef struct
+{
+ uint8_t conn_count; /**< The number of concurrent connections the application can create with this configuration.
+ The default and minimum value is @ref BLE_GAP_CONN_COUNT_DEFAULT. */
+ uint16_t event_length; /**< The time set aside for this connection on every connection interval in 1.25 ms units.
+ The default value is @ref BLE_GAP_EVENT_LENGTH_DEFAULT, the minimum value is @ref BLE_GAP_EVENT_LENGTH_MIN.
+ The event length and the connection interval are the primary parameters
+ for setting the throughput of a connection.
+ See the SoftDevice Specification for details on throughput. */
+} ble_gap_conn_cfg_t;
+
+
+/**
+ * @brief Configuration of maximum concurrent connections in the different connected roles, set with
+ * @ref sd_ble_cfg_set.
+ *
+ * @retval ::NRF_ERROR_CONN_COUNT The sum of periph_role_count and central_role_count is too
+ * large. The maximum supported sum of concurrent connections is
+ * @ref BLE_GAP_ROLE_COUNT_COMBINED_MAX.
+ * @retval ::NRF_ERROR_INVALID_PARAM central_sec_count is larger than central_role_count.
+ * @retval ::NRF_ERROR_RESOURCES The adv_set_count is too large. The maximum
+ * supported advertising handles is
+ * @ref BLE_GAP_ADV_SET_COUNT_MAX.
+ */
+typedef struct
+{
+ uint8_t adv_set_count; /**< Maximum number of advertising sets. Default value is @ref BLE_GAP_ADV_SET_COUNT_DEFAULT. */
+ uint8_t periph_role_count; /**< Maximum number of connections concurrently acting as a peripheral. Default value is @ref BLE_GAP_ROLE_COUNT_PERIPH_DEFAULT. */
+ uint8_t central_role_count; /**< Maximum number of connections concurrently acting as a central. Default value is @ref BLE_GAP_ROLE_COUNT_CENTRAL_DEFAULT. */
+ uint8_t central_sec_count; /**< Number of SMP instances shared between all connections acting as a central. Default value is @ref BLE_GAP_ROLE_COUNT_CENTRAL_SEC_DEFAULT. */
+ uint8_t qos_channel_survey_role_available:1; /**< If set, the Quality of Service (QoS) channel survey module is available to the
+ application using @ref sd_ble_gap_qos_channel_survey_start. */
+} ble_gap_cfg_role_count_t;
+
+
+/**
+ * @brief Device name and its properties, set with @ref sd_ble_cfg_set.
+ *
+ * @note If the device name is not configured, the default device name will be
+ * @ref BLE_GAP_DEVNAME_DEFAULT, the maximum device name length will be
+ * @ref BLE_GAP_DEVNAME_DEFAULT_LEN, vloc will be set to @ref BLE_GATTS_VLOC_STACK and the device name
+ * will have no write access.
+ *
+ * @note If @ref max_len is more than @ref BLE_GAP_DEVNAME_DEFAULT_LEN and vloc is set to @ref BLE_GATTS_VLOC_STACK,
+ * the attribute table size must be increased to have room for the longer device name (see
+ * @ref sd_ble_cfg_set and @ref ble_gatts_cfg_attr_tab_size_t).
+ *
+ * @note If vloc is @ref BLE_GATTS_VLOC_STACK :
+ * - p_value must point to non-volatile memory (flash) or be NULL.
+ * - If p_value is NULL, the device name will initially be empty.
+ *
+ * @note If vloc is @ref BLE_GATTS_VLOC_USER :
+ * - p_value cannot be NULL.
+ * - If the device name is writable, p_value must point to volatile memory (RAM).
+ *
+ * @retval ::NRF_ERROR_INVALID_PARAM One or more of the following is true:
+ * - Invalid device name location (vloc).
+ * - Invalid device name security mode.
+ * @retval ::NRF_ERROR_INVALID_LENGTH One or more of the following is true:
+ * - The device name length is invalid (must be between 0 and @ref BLE_GAP_DEVNAME_MAX_LEN).
+ * - The device name length is too long for the given Attribute Table.
+ * @retval ::NRF_ERROR_NOT_SUPPORTED Device name security mode is not supported.
+ */
+typedef struct
+{
+ ble_gap_conn_sec_mode_t write_perm; /**< Write permissions. */
+ uint8_t vloc:2; /**< Value location, see @ref BLE_GATTS_VLOCS.*/
+ uint8_t *p_value; /**< Pointer to where the value (device name) is stored or will be stored. */
+ uint16_t current_len; /**< Current length in bytes of the memory pointed to by p_value.*/
+ uint16_t max_len; /**< Maximum length in bytes of the memory pointed to by p_value.*/
+} ble_gap_cfg_device_name_t;
+
+
+/**@brief Configuration structure for GAP configurations. */
+typedef union
+{
+ ble_gap_cfg_role_count_t role_count_cfg; /**< Role count configuration, cfg_id is @ref BLE_GAP_CFG_ROLE_COUNT. */
+ ble_gap_cfg_device_name_t device_name_cfg; /**< Device name configuration, cfg_id is @ref BLE_GAP_CFG_DEVICE_NAME. */
+} ble_gap_cfg_t;
+
+
+/**@brief Channel Map option.
+ *
+ * @details Used with @ref sd_ble_opt_get to get the current channel map
+ * or @ref sd_ble_opt_set to set a new channel map. When setting the
+ * channel map, it applies to all current and future connections. When getting the
+ * current channel map, it applies to a single connection and the connection handle
+ * must be supplied.
+ *
+ * @note Setting the channel map may take some time, depending on connection parameters.
+ * The time taken may be different for each connection and the get operation will
+ * return the previous channel map until the new one has taken effect.
+ *
+ * @note After setting the channel map, by spec it can not be set again until at least 1 s has passed.
+ * See Bluetooth Specification Version 4.1 Volume 2, Part E, Section 7.3.46.
+ *
+ * @retval ::NRF_SUCCESS Get or set successful.
+ * @retval ::NRF_ERROR_INVALID_PARAM One or more of the following is true:
+ * - Less then two bits in @ref ch_map are set.
+ * - Bits for primary advertising channels (37-39) are set.
+ * @retval ::NRF_ERROR_BUSY Channel map was set again before enough time had passed.
+ * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid connection handle supplied for get.
+ *
+ */
+typedef struct
+{
+ uint16_t conn_handle; /**< Connection Handle (only applicable for get) */
+ uint8_t ch_map[5]; /**< Channel Map (37-bit). */
+} ble_gap_opt_ch_map_t;
+
+
+/**@brief Local connection latency option.
+ *
+ * @details Local connection latency is a feature which enables the slave to improve
+ * current consumption by ignoring the slave latency set by the peer. The
+ * local connection latency can only be set to a multiple of the slave latency,
+ * and cannot be longer than half of the supervision timeout.
+ *
+ * @details Used with @ref sd_ble_opt_set to set the local connection latency. The
+ * @ref sd_ble_opt_get is not supported for this option, but the actual
+ * local connection latency (unless set to NULL) is set as a return parameter
+ * when setting the option.
+ *
+ * @note The latency set will be truncated down to the closest slave latency event
+ * multiple, or the nearest multiple before half of the supervision timeout.
+ *
+ * @note The local connection latency is disabled by default, and needs to be enabled for new
+ * connections and whenever the connection is updated.
+ *
+ * @retval ::NRF_SUCCESS Set successfully.
+ * @retval ::NRF_ERROR_NOT_SUPPORTED Get is not supported.
+ * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid connection handle parameter.
+ */
+typedef struct
+{
+ uint16_t conn_handle; /**< Connection Handle */
+ uint16_t requested_latency; /**< Requested local connection latency. */
+ uint16_t * p_actual_latency; /**< Pointer to storage for the actual local connection latency (can be set to NULL to skip return value). */
+} ble_gap_opt_local_conn_latency_t;
+
+/**@brief Disable slave latency
+ *
+ * @details Used with @ref sd_ble_opt_set to temporarily disable slave latency of a peripheral connection
+ * (see @ref ble_gap_conn_params_t::slave_latency). And to re-enable it again. When disabled, the
+ * peripheral will ignore the slave_latency set by the central.
+ *
+ * @note Shall only be called on peripheral links.
+ *
+ * @retval ::NRF_SUCCESS Set successfully.
+ * @retval ::NRF_ERROR_NOT_SUPPORTED Get is not supported.
+ * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid connection handle parameter.
+ */
+typedef struct
+{
+ uint16_t conn_handle; /**< Connection Handle */
+ uint8_t disable : 1; /**< Set to 1 to disable slave latency. Set to 0 enable it again.*/
+} ble_gap_opt_slave_latency_disable_t;
+
+/**@brief Passkey Option.
+ *
+ * @details Structure containing the passkey to be used during pairing. This can be used with @ref
+ * sd_ble_opt_set to make the SoftDevice use a preprogrammed passkey for authentication
+ * instead of generating a random one.
+ *
+ * @note Repeated pairing attempts using the same preprogrammed passkey makes pairing vulnerable to MITM attacks.
+ *
+ * @note @ref sd_ble_opt_get is not supported for this option.
+ *
+ */
+typedef struct
+{
+ uint8_t const * p_passkey; /**< Pointer to 6-digit ASCII string (digit 0..9 only, no NULL termination) passkey to be used during pairing. If this is NULL, the SoftDevice will generate a random passkey if required.*/
+} ble_gap_opt_passkey_t;
+
+
+/**@brief Compatibility mode 1 option.
+ *
+ * @details This can be used with @ref sd_ble_opt_set to enable and disable
+ * compatibility mode 1. Compatibility mode 1 is disabled by default.
+ *
+ * @note Compatibility mode 1 enables interoperability with devices that do not support a value of
+ * 0 for the WinOffset parameter in the Link Layer CONNECT_IND packet. This applies to a
+ * limited set of legacy peripheral devices from another vendor. Enabling this compatibility
+ * mode will only have an effect if the local device will act as a central device and
+ * initiate a connection to a peripheral device. In that case it may lead to the connection
+ * creation taking up to one connection interval longer to complete for all connections.
+ *
+ * @retval ::NRF_SUCCESS Set successfully.
+ * @retval ::NRF_ERROR_INVALID_STATE When connection creation is ongoing while mode 1 is set.
+ */
+typedef struct
+{
+ uint8_t enable : 1; /**< Enable compatibility mode 1.*/
+} ble_gap_opt_compat_mode_1_t;
+
+
+/**@brief Authenticated payload timeout option.
+ *
+ * @details This can be used with @ref sd_ble_opt_set to change the Authenticated payload timeout to a value other
+ * than the default of @ref BLE_GAP_AUTH_PAYLOAD_TIMEOUT_MAX.
+ *
+ * @note The authenticated payload timeout event ::BLE_GAP_TIMEOUT_SRC_AUTH_PAYLOAD will be generated
+ * if auth_payload_timeout time has elapsed without receiving a packet with a valid MIC on an encrypted
+ * link.
+ *
+ * @note The LE ping procedure will be initiated before the timer expires to give the peer a chance
+ * to reset the timer. In addition the stack will try to prioritize running of LE ping over other
+ * activities to increase chances of finishing LE ping before timer expires. To avoid side-effects
+ * on other activities, it is recommended to use high timeout values.
+ * Recommended timeout > 2*(connInterval * (6 + connSlaveLatency)).
+ *
+ * @retval ::NRF_SUCCESS Set successfully.
+ * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied. auth_payload_timeout was outside of allowed range.
+ * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid connection handle parameter.
+ */
+typedef struct
+{
+ uint16_t conn_handle; /**< Connection Handle */
+ uint16_t auth_payload_timeout; /**< Requested timeout in 10 ms unit, see @ref BLE_GAP_AUTH_PAYLOAD_TIMEOUT. */
+} ble_gap_opt_auth_payload_timeout_t;
+
+/**@brief Option structure for GAP options. */
+typedef union
+{
+ ble_gap_opt_ch_map_t ch_map; /**< Parameters for the Channel Map option. */
+ ble_gap_opt_local_conn_latency_t local_conn_latency; /**< Parameters for the Local connection latency option */
+ ble_gap_opt_passkey_t passkey; /**< Parameters for the Passkey option.*/
+ ble_gap_opt_compat_mode_1_t compat_mode_1; /**< Parameters for the compatibility mode 1 option.*/
+ ble_gap_opt_auth_payload_timeout_t auth_payload_timeout; /**< Parameters for the authenticated payload timeout option.*/
+ ble_gap_opt_slave_latency_disable_t slave_latency_disable; /**< Parameters for the Disable slave latency option */
+} ble_gap_opt_t;
+/**@} */
+
+
+/**@addtogroup BLE_GAP_FUNCTIONS Functions
+ * @{ */
+
+/**@brief Set the local Bluetooth identity address.
+ *
+ * The local Bluetooth identity address is the address that identifies this device to other peers.
+ * The address type must be either @ref BLE_GAP_ADDR_TYPE_PUBLIC or @ref BLE_GAP_ADDR_TYPE_RANDOM_STATIC.
+ *
+ * @note The identity address cannot be changed while advertising, scanning or creating a connection.
+ *
+ * @note This address will be distributed to the peer during bonding.
+ * If the address changes, the address stored in the peer device will not be valid and the ability to
+ * reconnect using the old address will be lost.
+ *
+ * @note By default the SoftDevice will set an address of type @ref BLE_GAP_ADDR_TYPE_RANDOM_STATIC upon being
+ * enabled. The address is a random number populated during the IC manufacturing process and remains unchanged
+ * for the lifetime of each IC.
+ *
+ * @mscs
+ * @mmsc{@ref BLE_GAP_ADV_MSC}
+ * @endmscs
+ *
+ * @param[in] p_addr Pointer to address structure.
+ *
+ * @retval ::NRF_SUCCESS Address successfully set.
+ * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied.
+ * @retval ::BLE_ERROR_GAP_INVALID_BLE_ADDR Invalid address.
+ * @retval ::NRF_ERROR_BUSY The stack is busy, process pending events and retry.
+ * @retval ::NRF_ERROR_INVALID_STATE The identity address cannot be changed while advertising,
+ * scanning or creating a connection.
+ */
+SVCALL(SD_BLE_GAP_ADDR_SET, uint32_t, sd_ble_gap_addr_set(ble_gap_addr_t const *p_addr));
+
+
+/**@brief Get local Bluetooth identity address.
+ *
+ * @note This will always return the identity address irrespective of the privacy settings,
+ * i.e. the address type will always be either @ref BLE_GAP_ADDR_TYPE_PUBLIC or @ref BLE_GAP_ADDR_TYPE_RANDOM_STATIC.
+ *
+ * @param[out] p_addr Pointer to address structure to be filled in.
+ *
+ * @retval ::NRF_SUCCESS Address successfully retrieved.
+ * @retval ::NRF_ERROR_INVALID_ADDR Invalid or NULL pointer supplied.
+ */
+SVCALL(SD_BLE_GAP_ADDR_GET, uint32_t, sd_ble_gap_addr_get(ble_gap_addr_t *p_addr));
+
+
+/**@brief Set the active whitelist in the SoftDevice.
+ *
+ * @note Only one whitelist can be used at a time and the whitelist is shared between the BLE roles.
+ * The whitelist cannot be set if a BLE role is using the whitelist.
+ *
+ * @note If an address is resolved using the information in the device identity list, then the whitelist
+ * filter policy applies to the peer identity address and not the resolvable address sent on air.
+ *
+ * @mscs
+ * @mmsc{@ref BLE_GAP_WL_SHARE_MSC}
+ * @mmsc{@ref BLE_GAP_PRIVACY_SCAN_PRIVATE_SCAN_MSC}
+ * @endmscs
+ *
+ * @param[in] pp_wl_addrs Pointer to a whitelist of peer addresses, if NULL the whitelist will be cleared.
+ * @param[in] len Length of the whitelist, maximum @ref BLE_GAP_WHITELIST_ADDR_MAX_COUNT.
+ *
+ * @retval ::NRF_SUCCESS The whitelist is successfully set/cleared.
+ * @retval ::NRF_ERROR_INVALID_ADDR The whitelist (or one of its entries) provided is invalid.
+ * @retval ::BLE_ERROR_GAP_WHITELIST_IN_USE The whitelist is in use by a BLE role and cannot be set or cleared.
+ * @retval ::BLE_ERROR_GAP_INVALID_BLE_ADDR Invalid address type is supplied.
+ * @retval ::NRF_ERROR_DATA_SIZE The given whitelist size is invalid (zero or too large); this can only return when
+ * pp_wl_addrs is not NULL.
+ */
+SVCALL(SD_BLE_GAP_WHITELIST_SET, uint32_t, sd_ble_gap_whitelist_set(ble_gap_addr_t const * const * pp_wl_addrs, uint8_t len));
+
+
+/**@brief Set device identity list.
+ *
+ * @note Only one device identity list can be used at a time and the list is shared between the BLE roles.
+ * The device identity list cannot be set if a BLE role is using the list.
+ *
+ * @param[in] pp_id_keys Pointer to an array of peer identity addresses and peer IRKs, if NULL the device identity list will be cleared.
+ * @param[in] pp_local_irks Pointer to an array of local IRKs. Each entry in the array maps to the entry in pp_id_keys at the same index.
+ * To fill in the list with the currently set device IRK for all peers, set to NULL.
+ * @param[in] len Length of the device identity list, maximum @ref BLE_GAP_DEVICE_IDENTITIES_MAX_COUNT.
+ *
+ * @mscs
+ * @mmsc{@ref BLE_GAP_PRIVACY_ADV_MSC}
+ * @mmsc{@ref BLE_GAP_PRIVACY_SCAN_MSC}
+ * @mmsc{@ref BLE_GAP_PRIVACY_SCAN_PRIVATE_SCAN_MSC}
+ * @mmsc{@ref BLE_GAP_PRIVACY_ADV_DIR_PRIV_MSC}
+ * @mmsc{@ref BLE_GAP_PERIPH_CONN_PRIV_MSC}
+ * @mmsc{@ref BLE_GAP_CENTRAL_CONN_PRIV_MSC}
+ * @endmscs
+ *
+ * @retval ::NRF_SUCCESS The device identity list successfully set/cleared.
+ * @retval ::NRF_ERROR_INVALID_ADDR The device identity list (or one of its entries) provided is invalid.
+ * This code may be returned if the local IRK list also has an invalid entry.
+ * @retval ::BLE_ERROR_GAP_DEVICE_IDENTITIES_IN_USE The device identity list is in use and cannot be set or cleared.
+ * @retval ::BLE_ERROR_GAP_DEVICE_IDENTITIES_DUPLICATE The device identity list contains multiple entries with the same identity address.
+ * @retval ::BLE_ERROR_GAP_INVALID_BLE_ADDR Invalid address type is supplied.
+ * @retval ::NRF_ERROR_DATA_SIZE The given device identity list size invalid (zero or too large); this can
+ * only return when pp_id_keys is not NULL.
+ */
+SVCALL(SD_BLE_GAP_DEVICE_IDENTITIES_SET, uint32_t, sd_ble_gap_device_identities_set(ble_gap_id_key_t const * const * pp_id_keys, ble_gap_irk_t const * const * pp_local_irks, uint8_t len));
+
+
+/**@brief Set privacy settings.
+ *
+ * @note Privacy settings cannot be changed while advertising, scanning or creating a connection.
+ *
+ * @param[in] p_privacy_params Privacy settings.
+ *
+ * @mscs
+ * @mmsc{@ref BLE_GAP_PRIVACY_ADV_MSC}
+ * @mmsc{@ref BLE_GAP_PRIVACY_SCAN_MSC}
+ * @mmsc{@ref BLE_GAP_PRIVACY_ADV_DIR_PRIV_MSC}
+ * @endmscs
+ *
+ * @retval ::NRF_SUCCESS Set successfully.
+ * @retval ::NRF_ERROR_BUSY The stack is busy, process pending events and retry.
+ * @retval ::BLE_ERROR_GAP_INVALID_BLE_ADDR Invalid address type is supplied.
+ * @retval ::NRF_ERROR_INVALID_ADDR The pointer to privacy settings is NULL or invalid.
+ * Otherwise, the p_device_irk pointer in privacy parameter is an invalid pointer.
+ * @retval ::NRF_ERROR_INVALID_PARAM Out of range parameters are provided.
+ * @retval ::NRF_ERROR_INVALID_STATE Privacy settings cannot be changed while advertising, scanning
+ * or creating a connection.
+ */
+SVCALL(SD_BLE_GAP_PRIVACY_SET, uint32_t, sd_ble_gap_privacy_set(ble_gap_privacy_params_t const *p_privacy_params));
+
+
+/**@brief Get privacy settings.
+ *
+ * @note ::ble_gap_privacy_params_t::p_device_irk must be initialized to NULL or a valid address before this function is called.
+ * If it is initialized to a valid address, the address pointed to will contain the current device IRK on return.
+ *
+ * @param[in,out] p_privacy_params Privacy settings.
+ *
+ * @retval ::NRF_SUCCESS Privacy settings read.
+ * @retval ::NRF_ERROR_INVALID_ADDR The pointer given for returning the privacy settings may be NULL or invalid.
+ * Otherwise, the p_device_irk pointer in privacy parameter is an invalid pointer.
+ */
+SVCALL(SD_BLE_GAP_PRIVACY_GET, uint32_t, sd_ble_gap_privacy_get(ble_gap_privacy_params_t *p_privacy_params));
+
+
+/**@brief Configure an advertising set. Set, clear or update advertising and scan response data.
+ *
+ * @note The format of the advertising data will be checked by this call to ensure interoperability.
+ * Limitations imposed by this API call to the data provided include having a flags data type in the scan response data and
+ * duplicating the local name in the advertising data and scan response data.
+ *
+ * @note In order to update advertising data while advertising, new advertising buffers must be provided.
+ *
+ * @mscs
+ * @mmsc{@ref BLE_GAP_ADV_MSC}
+ * @mmsc{@ref BLE_GAP_WL_SHARE_MSC}
+ * @endmscs
+ *
+ * @param[in,out] p_adv_handle Provide a pointer to a handle containing @ref BLE_GAP_ADV_SET_HANDLE_NOT_SET to configure
+ * a new advertising set. On success, a new handle is then returned through the pointer.
+ * Provide a pointer to an existing advertising handle to configure an existing advertising set.
+ * @param[in] p_adv_data Advertising data. If set to NULL, no advertising data will be used. See @ref ble_gap_adv_data_t.
+ * @param[in] p_adv_params Advertising parameters. When this function is used to update advertising data while advertising,
+ * this parameter must be NULL. See @ref ble_gap_adv_params_t.
+ *
+ * @retval ::NRF_SUCCESS Advertising set successfully configured.
+ * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied:
+ * - Invalid advertising data configuration specified. See @ref ble_gap_adv_data_t.
+ * - Invalid configuration of p_adv_params. See @ref ble_gap_adv_params_t.
+ * - Use of whitelist requested but whitelist has not been set,
+ * see @ref sd_ble_gap_whitelist_set.
+ * @retval ::BLE_ERROR_GAP_INVALID_BLE_ADDR ble_gap_adv_params_t::p_peer_addr is invalid.
+ * @retval ::NRF_ERROR_INVALID_STATE Invalid state to perform operation.
+ * - It is invalid to provide non-NULL advertising set parameters while advertising.
+ * - It is invalid to provide the same data buffers while advertising. To update
+ * advertising data, provide new advertising buffers.
+ * @retval ::BLE_ERROR_GAP_DISCOVERABLE_WITH_WHITELIST Discoverable mode and whitelist incompatible.
+ * @retval ::BLE_ERROR_INVALID_ADV_HANDLE The provided advertising handle was not found. Use @ref BLE_GAP_ADV_SET_HANDLE_NOT_SET to
+ * configure a new advertising handle.
+ * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied.
+ * @retval ::NRF_ERROR_INVALID_FLAGS Invalid combination of advertising flags supplied.
+ * @retval ::NRF_ERROR_INVALID_DATA Invalid data type(s) supplied. Check the advertising data format specification
+ * given in Bluetooth Specification Version 5.0, Volume 3, Part C, Chapter 11.
+ * @retval ::NRF_ERROR_INVALID_LENGTH Invalid data length(s) supplied.
+ * @retval ::NRF_ERROR_NOT_SUPPORTED Unsupported data length or advertising parameter configuration.
+ * @retval ::NRF_ERROR_NO_MEM Not enough memory to configure a new advertising handle. Update an
+ * existing advertising handle instead.
+ * @retval ::BLE_ERROR_GAP_UUID_LIST_MISMATCH Invalid UUID list supplied.
+ */
+SVCALL(SD_BLE_GAP_ADV_SET_CONFIGURE, uint32_t, sd_ble_gap_adv_set_configure(uint8_t *p_adv_handle, ble_gap_adv_data_t const *p_adv_data, ble_gap_adv_params_t const *p_adv_params));
+
+
+/**@brief Start advertising (GAP Discoverable, Connectable modes, Broadcast Procedure).
+ *
+ * @note Only one advertiser may be active at any time.
+ *
+ * @events
+ * @event{@ref BLE_GAP_EVT_CONNECTED, Generated after connection has been established through connectable advertising.}
+ * @event{@ref BLE_GAP_EVT_ADV_SET_TERMINATED, Advertising set has terminated.}
+ * @event{@ref BLE_GAP_EVT_SCAN_REQ_REPORT, A scan request was received.}
+ * @endevents
+ *
+ * @mscs
+ * @mmsc{@ref BLE_GAP_ADV_MSC}
+ * @mmsc{@ref BLE_GAP_PERIPH_CONN_PRIV_MSC}
+ * @mmsc{@ref BLE_GAP_PRIVACY_ADV_DIR_PRIV_MSC}
+ * @mmsc{@ref BLE_GAP_WL_SHARE_MSC}
+ * @endmscs
+ *
+ * @param[in] adv_handle Advertising handle to advertise on, received from @ref sd_ble_gap_adv_set_configure.
+ * @param[in] conn_cfg_tag Tag identifying a configuration set by @ref sd_ble_cfg_set or
+ * @ref BLE_CONN_CFG_TAG_DEFAULT to use the default connection configuration. For non-connectable
+ * advertising, this is ignored.
+ *
+ * @retval ::NRF_SUCCESS The BLE stack has started advertising.
+ * @retval ::NRF_ERROR_INVALID_STATE Invalid state to perform operation. adv_handle is not configured or already advertising.
+ * @retval ::NRF_ERROR_CONN_COUNT The limit of available connections has been reached; connectable advertiser cannot be started.
+ * @retval ::BLE_ERROR_INVALID_ADV_HANDLE Advertising handle not found. Configure a new adveriting handle with @ref sd_ble_gap_adv_set_configure.
+ * @retval ::NRF_ERROR_NOT_FOUND conn_cfg_tag not found.
+ * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied:
+ * - Invalid configuration of p_adv_params. See @ref ble_gap_adv_params_t.
+ * - Use of whitelist requested but whitelist has not been set, see @ref sd_ble_gap_whitelist_set.
+ * @retval ::NRF_ERROR_RESOURCES Either:
+ * - adv_handle is configured with connectable advertising, but the event_length parameter
+ * associated with conn_cfg_tag is too small to be able to establish a connection on
+ * the selected advertising phys. Use @ref sd_ble_cfg_set to increase the event length.
+ * - Not enough BLE role slots available.
+ Stop one or more currently active roles (Central, Peripheral, Broadcaster or Observer) and try again.
+ * - p_adv_params is configured with connectable advertising, but the event_length parameter
+ * associated with conn_cfg_tag is too small to be able to establish a connection on
+ * the selected advertising phys. Use @ref sd_ble_cfg_set to increase the event length.
+ * @retval ::NRF_ERROR_NOT_SUPPORTED Unsupported PHYs supplied to the call.
+ */
+SVCALL(SD_BLE_GAP_ADV_START, uint32_t, sd_ble_gap_adv_start(uint8_t adv_handle, uint8_t conn_cfg_tag));
+
+
+/**@brief Stop advertising (GAP Discoverable, Connectable modes, Broadcast Procedure).
+ *
+ * @mscs
+ * @mmsc{@ref BLE_GAP_ADV_MSC}
+ * @mmsc{@ref BLE_GAP_WL_SHARE_MSC}
+ * @endmscs
+ *
+ * @param[in] adv_handle The advertising handle that should stop advertising.
+ *
+ * @retval ::NRF_SUCCESS The BLE stack has stopped advertising.
+ * @retval ::BLE_ERROR_INVALID_ADV_HANDLE Invalid advertising handle.
+ * @retval ::NRF_ERROR_INVALID_STATE The advertising handle is not advertising.
+ */
+SVCALL(SD_BLE_GAP_ADV_STOP, uint32_t, sd_ble_gap_adv_stop(uint8_t adv_handle));
+
+
+
+/**@brief Update connection parameters.
+ *
+ * @details In the central role this will initiate a Link Layer connection parameter update procedure,
+ * otherwise in the peripheral role, this will send the corresponding L2CAP request and wait for
+ * the central to perform the procedure. In both cases, and regardless of success or failure, the application
+ * will be informed of the result with a @ref BLE_GAP_EVT_CONN_PARAM_UPDATE event.
+ *
+ * @details This function can be used as a central both to reply to a @ref BLE_GAP_EVT_CONN_PARAM_UPDATE_REQUEST or to start the procedure unrequested.
+ *
+ * @events
+ * @event{@ref BLE_GAP_EVT_CONN_PARAM_UPDATE, Result of the connection parameter update procedure.}
+ * @endevents
+ *
+ * @mscs
+ * @mmsc{@ref BLE_GAP_CPU_MSC}
+ * @mmsc{@ref BLE_GAP_CENTRAL_ENC_AUTH_MUTEX_MSC}
+ * @mmsc{@ref BLE_GAP_MULTILINK_CPU_MSC}
+ * @mmsc{@ref BLE_GAP_MULTILINK_CTRL_PROC_MSC}
+ * @mmsc{@ref BLE_GAP_CENTRAL_CPU_MSC}
+ * @endmscs
+ *
+ * @param[in] conn_handle Connection handle.
+ * @param[in] p_conn_params Pointer to desired connection parameters. If NULL is provided on a peripheral role,
+ * the parameters in the PPCP characteristic of the GAP service will be used instead.
+ * If NULL is provided on a central role and in response to a @ref BLE_GAP_EVT_CONN_PARAM_UPDATE_REQUEST, the peripheral request will be rejected
+ *
+ * @retval ::NRF_SUCCESS The Connection Update procedure has been started successfully.
+ * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied.
+ * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied, check parameter limits and constraints.
+ * @retval ::NRF_ERROR_INVALID_STATE Invalid state to perform operation.
+ * @retval ::NRF_ERROR_BUSY Procedure already in progress, wait for pending procedures to complete and retry.
+ * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid connection handle supplied.
+ * @retval ::NRF_ERROR_NO_MEM Not enough memory to complete operation.
+ */
+SVCALL(SD_BLE_GAP_CONN_PARAM_UPDATE, uint32_t, sd_ble_gap_conn_param_update(uint16_t conn_handle, ble_gap_conn_params_t const *p_conn_params));
+
+
+/**@brief Disconnect (GAP Link Termination).
+ *
+ * @details This call initiates the disconnection procedure, and its completion will be communicated to the application
+ * with a @ref BLE_GAP_EVT_DISCONNECTED event.
+ *
+ * @events
+ * @event{@ref BLE_GAP_EVT_DISCONNECTED, Generated when disconnection procedure is complete.}
+ * @endevents
+ *
+ * @mscs
+ * @mmsc{@ref BLE_GAP_CONN_MSC}
+ * @endmscs
+ *
+ * @param[in] conn_handle Connection handle.
+ * @param[in] hci_status_code HCI status code, see @ref BLE_HCI_STATUS_CODES (accepted values are @ref BLE_HCI_REMOTE_USER_TERMINATED_CONNECTION and @ref BLE_HCI_CONN_INTERVAL_UNACCEPTABLE).
+ *
+ * @retval ::NRF_SUCCESS The disconnection procedure has been started successfully.
+ * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied.
+ * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid connection handle supplied.
+ * @retval ::NRF_ERROR_INVALID_STATE Invalid state to perform operation (disconnection is already in progress).
+ */
+SVCALL(SD_BLE_GAP_DISCONNECT, uint32_t, sd_ble_gap_disconnect(uint16_t conn_handle, uint8_t hci_status_code));
+
+
+/**@brief Set the radio's transmit power.
+ *
+ * @param[in] role The role to set the transmit power for, see @ref BLE_GAP_TX_POWER_ROLES for
+ * possible roles.
+ * @param[in] handle The handle parameter is interpreted depending on role:
+ * - If role is @ref BLE_GAP_TX_POWER_ROLE_CONN, this value is the specific connection handle.
+ * - If role is @ref BLE_GAP_TX_POWER_ROLE_ADV, the advertising set identified with the advertising handle,
+ * will use the specified transmit power, and include it in the advertising packet headers if
+ * @ref ble_gap_adv_properties_t::include_tx_power set.
+ * - For all other roles handle is ignored.
+ * @param[in] tx_power Radio transmit power in dBm (see note for accepted values).
+ *
+ * @note Supported tx_power values: -40dBm, -20dBm, -16dBm, -12dBm, -8dBm, -4dBm, 0dBm, +3dBm and +4dBm.
+ * @note The initiator will have the same transmit power as the scanner.
+ * @note When a connection is created it will inherit the transmit power from the initiator or
+ * advertiser leading to the connection.
+ *
+ * @retval ::NRF_SUCCESS Successfully changed the transmit power.
+ * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied.
+ * @retval ::BLE_ERROR_INVALID_ADV_HANDLE Advertising handle not found.
+ * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid connection handle supplied.
+ */
+SVCALL(SD_BLE_GAP_TX_POWER_SET, uint32_t, sd_ble_gap_tx_power_set(uint8_t role, uint16_t handle, int8_t tx_power));
+
+
+/**@brief Set GAP Appearance value.
+ *
+ * @param[in] appearance Appearance (16-bit), see @ref BLE_APPEARANCES.
+ *
+ * @retval ::NRF_SUCCESS Appearance value set successfully.
+ * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied.
+ */
+SVCALL(SD_BLE_GAP_APPEARANCE_SET, uint32_t, sd_ble_gap_appearance_set(uint16_t appearance));
+
+
+/**@brief Get GAP Appearance value.
+ *
+ * @param[out] p_appearance Pointer to appearance (16-bit) to be filled in, see @ref BLE_APPEARANCES.
+ *
+ * @retval ::NRF_SUCCESS Appearance value retrieved successfully.
+ * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied.
+ */
+SVCALL(SD_BLE_GAP_APPEARANCE_GET, uint32_t, sd_ble_gap_appearance_get(uint16_t *p_appearance));
+
+
+/**@brief Set GAP Peripheral Preferred Connection Parameters.
+ *
+ * @param[in] p_conn_params Pointer to a @ref ble_gap_conn_params_t structure with the desired parameters.
+ *
+ * @retval ::NRF_SUCCESS Peripheral Preferred Connection Parameters set successfully.
+ * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied.
+ * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied.
+ */
+SVCALL(SD_BLE_GAP_PPCP_SET, uint32_t, sd_ble_gap_ppcp_set(ble_gap_conn_params_t const *p_conn_params));
+
+
+/**@brief Get GAP Peripheral Preferred Connection Parameters.
+ *
+ * @param[out] p_conn_params Pointer to a @ref ble_gap_conn_params_t structure where the parameters will be stored.
+ *
+ * @retval ::NRF_SUCCESS Peripheral Preferred Connection Parameters retrieved successfully.
+ * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied.
+ */
+SVCALL(SD_BLE_GAP_PPCP_GET, uint32_t, sd_ble_gap_ppcp_get(ble_gap_conn_params_t *p_conn_params));
+
+
+/**@brief Set GAP device name.
+ *
+ * @note If the device name is located in application flash memory (see @ref ble_gap_cfg_device_name_t),
+ * it cannot be changed. Then @ref NRF_ERROR_FORBIDDEN will be returned.
+ *
+ * @param[in] p_write_perm Write permissions for the Device Name characteristic, see @ref ble_gap_conn_sec_mode_t.
+ * @param[in] p_dev_name Pointer to a UTF-8 encoded, <b>non NULL-terminated</b> string.
+ * @param[in] len Length of the UTF-8, <b>non NULL-terminated</b> string pointed to by p_dev_name in octets (must be smaller or equal than @ref BLE_GAP_DEVNAME_MAX_LEN).
+ *
+ * @retval ::NRF_SUCCESS GAP device name and permissions set successfully.
+ * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied.
+ * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied.
+ * @retval ::NRF_ERROR_DATA_SIZE Invalid data size(s) supplied.
+ * @retval ::NRF_ERROR_FORBIDDEN Device name is not writable.
+ */
+SVCALL(SD_BLE_GAP_DEVICE_NAME_SET, uint32_t, sd_ble_gap_device_name_set(ble_gap_conn_sec_mode_t const *p_write_perm, uint8_t const *p_dev_name, uint16_t len));
+
+
+/**@brief Get GAP device name.
+ *
+ * @note If the device name is longer than the size of the supplied buffer,
+ * p_len will return the complete device name length,
+ * and not the number of bytes actually returned in p_dev_name.
+ * The application may use this information to allocate a suitable buffer size.
+ *
+ * @param[out] p_dev_name Pointer to an empty buffer where the UTF-8 <b>non NULL-terminated</b> string will be placed. Set to NULL to obtain the complete device name length.
+ * @param[in,out] p_len Length of the buffer pointed by p_dev_name, complete device name length on output.
+ *
+ * @retval ::NRF_SUCCESS GAP device name retrieved successfully.
+ * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied.
+ * @retval ::NRF_ERROR_DATA_SIZE Invalid data size(s) supplied.
+ */
+SVCALL(SD_BLE_GAP_DEVICE_NAME_GET, uint32_t, sd_ble_gap_device_name_get(uint8_t *p_dev_name, uint16_t *p_len));
+
+
+/**@brief Initiate the GAP Authentication procedure.
+ *
+ * @details In the central role, this function will send an SMP Pairing Request (or an SMP Pairing Failed if rejected),
+ * otherwise in the peripheral role, an SMP Security Request will be sent.
+ *
+ * @events
+ * @event{Depending on the security parameters set and the packet exchanges with the peer\, the following events may be generated:}
+ * @event{@ref BLE_GAP_EVT_SEC_PARAMS_REQUEST}
+ * @event{@ref BLE_GAP_EVT_SEC_INFO_REQUEST}
+ * @event{@ref BLE_GAP_EVT_PASSKEY_DISPLAY}
+ * @event{@ref BLE_GAP_EVT_KEY_PRESSED}
+ * @event{@ref BLE_GAP_EVT_AUTH_KEY_REQUEST}
+ * @event{@ref BLE_GAP_EVT_LESC_DHKEY_REQUEST}
+ * @event{@ref BLE_GAP_EVT_CONN_SEC_UPDATE}
+ * @event{@ref BLE_GAP_EVT_AUTH_STATUS}
+ * @event{@ref BLE_GAP_EVT_TIMEOUT}
+ * @endevents
+ *
+ * @mscs
+ * @mmsc{@ref BLE_GAP_PERIPH_SEC_REQ_MSC}
+ * @mmsc{@ref BLE_GAP_CENTRAL_SEC_REQ_MSC}
+ * @mmsc{@ref BLE_GAP_CENTRAL_ENC_AUTH_MUTEX_MSC}
+ * @mmsc{@ref BLE_GAP_CENTRAL_PAIRING_JW_MSC}
+ * @mmsc{@ref BLE_GAP_CENTRAL_BONDING_JW_MSC}
+ * @mmsc{@ref BLE_GAP_CENTRAL_BONDING_PK_PERIPH_MSC}
+ * @mmsc{@ref BLE_GAP_CENTRAL_BONDING_PK_PERIPH_OOB_MSC}
+ * @mmsc{@ref BLE_GAP_CENTRAL_LESC_PAIRING_JW_MSC}
+ * @mmsc{@ref BLE_GAP_CENTRAL_LESC_BONDING_NC_MSC}
+ * @mmsc{@ref BLE_GAP_CENTRAL_LESC_BONDING_PKE_PD_MSC}
+ * @mmsc{@ref BLE_GAP_CENTRAL_LESC_BONDING_PKE_CD_MSC}
+ * @mmsc{@ref BLE_GAP_CENTRAL_LESC_BONDING_OOB_MSC}
+ * @endmscs
+ *
+ * @param[in] conn_handle Connection handle.
+ * @param[in] p_sec_params Pointer to the @ref ble_gap_sec_params_t structure with the security parameters to be used during the pairing or bonding procedure.
+ * In the peripheral role, only the bond, mitm, lesc and keypress fields of this structure are used.
+ * In the central role, this pointer may be NULL to reject a Security Request.
+ *
+ * @retval ::NRF_SUCCESS Successfully initiated authentication procedure.
+ * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied.
+ * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied.
+ * @retval ::NRF_ERROR_INVALID_STATE Invalid state to perform operation.
+ * @retval ::NRF_ERROR_NO_MEM The maximum number of authentication procedures that can run in parallel for the given role is reached.
+ * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid connection handle supplied.
+ * @retval ::NRF_ERROR_NOT_SUPPORTED Setting of sign or link fields in @ref ble_gap_sec_kdist_t not supported.
+ * @retval ::NRF_ERROR_TIMEOUT A SMP timeout has occurred, and further SMP operations on this link is prohibited.
+ */
+SVCALL(SD_BLE_GAP_AUTHENTICATE, uint32_t, sd_ble_gap_authenticate(uint16_t conn_handle, ble_gap_sec_params_t const *p_sec_params));
+
+
+/**@brief Reply with GAP security parameters.
+ *
+ * @details This function is only used to reply to a @ref BLE_GAP_EVT_SEC_PARAMS_REQUEST, calling it at other times will result in an @ref NRF_ERROR_INVALID_STATE.
+ * @note If the call returns an error code, the request is still pending, and the reply call may be repeated with corrected parameters.
+ *
+ * @events
+ * @event{This function is used during authentication procedures\, see the list of events in the documentation of @ref sd_ble_gap_authenticate.}
+ * @endevents
+ *
+ * @mscs
+ * @mmsc{@ref BLE_GAP_PERIPH_PAIRING_JW_MSC}
+ * @mmsc{@ref BLE_GAP_PERIPH_BONDING_JW_MSC}
+ * @mmsc{@ref BLE_GAP_PERIPH_BONDING_PK_PERIPH_MSC}
+ * @mmsc{@ref BLE_GAP_PERIPH_BONDING_PK_CENTRAL_OOB_MSC}
+ * @mmsc{@ref BLE_GAP_PERIPH_BONDING_STATIC_PK_MSC}
+ * @mmsc{@ref BLE_GAP_PERIPH_PAIRING_CONFIRM_FAIL_MSC}
+ * @mmsc{@ref BLE_GAP_PERIPH_LESC_PAIRING_JW_MSC}
+ * @mmsc{@ref BLE_GAP_PERIPH_LESC_BONDING_NC_MSC}
+ * @mmsc{@ref BLE_GAP_PERIPH_LESC_BONDING_PKE_PD_MSC}
+ * @mmsc{@ref BLE_GAP_PERIPH_LESC_BONDING_PKE_CD_MSC}
+ * @mmsc{@ref BLE_GAP_PERIPH_LESC_BONDING_OOB_MSC}
+ * @mmsc{@ref BLE_GAP_PERIPH_PAIRING_KS_TOO_SMALL_MSC}
+ * @mmsc{@ref BLE_GAP_PERIPH_PAIRING_APP_ERROR_MSC}
+ * @mmsc{@ref BLE_GAP_PERIPH_PAIRING_REMOTE_PAIRING_FAIL_MSC}
+ * @mmsc{@ref BLE_GAP_PERIPH_PAIRING_TIMEOUT_MSC}
+ * @mmsc{@ref BLE_GAP_CENTRAL_PAIRING_JW_MSC}
+ * @mmsc{@ref BLE_GAP_CENTRAL_BONDING_JW_MSC}
+ * @mmsc{@ref BLE_GAP_CENTRAL_BONDING_PK_PERIPH_MSC}
+ * @mmsc{@ref BLE_GAP_CENTRAL_BONDING_PK_PERIPH_OOB_MSC}
+ * @mmsc{@ref BLE_GAP_CENTRAL_LESC_PAIRING_JW_MSC}
+ * @mmsc{@ref BLE_GAP_CENTRAL_LESC_BONDING_NC_MSC}
+ * @mmsc{@ref BLE_GAP_CENTRAL_LESC_BONDING_PKE_PD_MSC}
+ * @mmsc{@ref BLE_GAP_CENTRAL_LESC_BONDING_PKE_CD_MSC}
+ * @mmsc{@ref BLE_GAP_CENTRAL_LESC_BONDING_OOB_MSC}
+ * @endmscs
+ *
+ * @param[in] conn_handle Connection handle.
+ * @param[in] sec_status Security status, see @ref BLE_GAP_SEC_STATUS.
+ * @param[in] p_sec_params Pointer to a @ref ble_gap_sec_params_t security parameters structure. In the central role this must be set to NULL, as the parameters have
+ * already been provided during a previous call to @ref sd_ble_gap_authenticate.
+ * @param[in,out] p_sec_keyset Pointer to a @ref ble_gap_sec_keyset_t security keyset structure. Any keys generated and/or distributed as a result of the ongoing security procedure
+ * will be stored into the memory referenced by the pointers inside this structure. The keys will be stored and available to the application
+ * upon reception of a @ref BLE_GAP_EVT_AUTH_STATUS event.
+ * Note that the SoftDevice expects the application to provide memory for storing the
+ * peer's keys. So it must be ensured that the relevant pointers inside this structure are not NULL. The pointers to the local key
+ * can, however, be NULL, in which case, the local key data will not be available to the application upon reception of the
+ * @ref BLE_GAP_EVT_AUTH_STATUS event.
+ *
+ * @retval ::NRF_SUCCESS Successfully accepted security parameter from the application.
+ * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied.
+ * @retval ::NRF_ERROR_BUSY The stack is busy, process pending events and retry.
+ * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied.
+ * @retval ::NRF_ERROR_INVALID_STATE Invalid state to perform operation.
+ * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid connection handle supplied.
+ * @retval ::NRF_ERROR_NOT_SUPPORTED Setting of sign or link fields in @ref ble_gap_sec_kdist_t not supported.
+ */
+SVCALL(SD_BLE_GAP_SEC_PARAMS_REPLY, uint32_t, sd_ble_gap_sec_params_reply(uint16_t conn_handle, uint8_t sec_status, ble_gap_sec_params_t const *p_sec_params, ble_gap_sec_keyset_t const *p_sec_keyset));
+
+
+/**@brief Reply with an authentication key.
+ *
+ * @details This function is only used to reply to a @ref BLE_GAP_EVT_AUTH_KEY_REQUEST or a @ref BLE_GAP_EVT_PASSKEY_DISPLAY, calling it at other times will result in an @ref NRF_ERROR_INVALID_STATE.
+ * @note If the call returns an error code, the request is still pending, and the reply call may be repeated with corrected parameters.
+ *
+ * @events
+ * @event{This function is used during authentication procedures\, see the list of events in the documentation of @ref sd_ble_gap_authenticate.}
+ * @endevents
+ *
+ * @mscs
+ * @mmsc{@ref BLE_GAP_PERIPH_BONDING_PK_CENTRAL_OOB_MSC}
+ * @mmsc{@ref BLE_GAP_PERIPH_LESC_BONDING_NC_MSC}
+ * @mmsc{@ref BLE_GAP_PERIPH_LESC_BONDING_PKE_CD_MSC}
+ * @mmsc{@ref BLE_GAP_CENTRAL_BONDING_PK_PERIPH_OOB_MSC}
+ * @mmsc{@ref BLE_GAP_CENTRAL_LESC_BONDING_NC_MSC}
+ * @mmsc{@ref BLE_GAP_CENTRAL_LESC_BONDING_PKE_CD_MSC}
+ * @endmscs
+ *
+ * @param[in] conn_handle Connection handle.
+ * @param[in] key_type See @ref BLE_GAP_AUTH_KEY_TYPES.
+ * @param[in] p_key If key type is @ref BLE_GAP_AUTH_KEY_TYPE_NONE, then NULL.
+ * If key type is @ref BLE_GAP_AUTH_KEY_TYPE_PASSKEY, then a 6-byte ASCII string (digit 0..9 only, no NULL termination)
+ * or NULL when confirming LE Secure Connections Numeric Comparison.
+ * If key type is @ref BLE_GAP_AUTH_KEY_TYPE_OOB, then a 16-byte OOB key value in little-endian format.
+ *
+ * @retval ::NRF_SUCCESS Authentication key successfully set.
+ * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied.
+ * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied.
+ * @retval ::NRF_ERROR_INVALID_STATE Invalid state to perform operation.
+ * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid connection handle supplied.
+ */
+SVCALL(SD_BLE_GAP_AUTH_KEY_REPLY, uint32_t, sd_ble_gap_auth_key_reply(uint16_t conn_handle, uint8_t key_type, uint8_t const *p_key));
+
+
+/**@brief Reply with an LE Secure connections DHKey.
+ *
+ * @details This function is only used to reply to a @ref BLE_GAP_EVT_LESC_DHKEY_REQUEST, calling it at other times will result in an @ref NRF_ERROR_INVALID_STATE.
+ * @note If the call returns an error code, the request is still pending, and the reply call may be repeated with corrected parameters.
+ *
+ * @events
+ * @event{This function is used during authentication procedures\, see the list of events in the documentation of @ref sd_ble_gap_authenticate.}
+ * @endevents
+ *
+ * @mscs
+ * @mmsc{@ref BLE_GAP_PERIPH_LESC_PAIRING_JW_MSC}
+ * @mmsc{@ref BLE_GAP_PERIPH_LESC_BONDING_NC_MSC}
+ * @mmsc{@ref BLE_GAP_PERIPH_LESC_BONDING_PKE_PD_MSC}
+ * @mmsc{@ref BLE_GAP_PERIPH_LESC_BONDING_PKE_CD_MSC}
+ * @mmsc{@ref BLE_GAP_PERIPH_LESC_BONDING_OOB_MSC}
+ * @mmsc{@ref BLE_GAP_CENTRAL_LESC_PAIRING_JW_MSC}
+ * @mmsc{@ref BLE_GAP_CENTRAL_LESC_BONDING_NC_MSC}
+ * @mmsc{@ref BLE_GAP_CENTRAL_LESC_BONDING_PKE_PD_MSC}
+ * @mmsc{@ref BLE_GAP_CENTRAL_LESC_BONDING_PKE_CD_MSC}
+ * @mmsc{@ref BLE_GAP_CENTRAL_LESC_BONDING_OOB_MSC}
+ * @endmscs
+ *
+ * @param[in] conn_handle Connection handle.
+ * @param[in] p_dhkey LE Secure Connections DHKey.
+ *
+ * @retval ::NRF_SUCCESS DHKey successfully set.
+ * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied.
+ * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied.
+ * @retval ::NRF_ERROR_INVALID_STATE Invalid state to perform operation.
+ * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid connection handle supplied.
+ */
+SVCALL(SD_BLE_GAP_LESC_DHKEY_REPLY, uint32_t, sd_ble_gap_lesc_dhkey_reply(uint16_t conn_handle, ble_gap_lesc_dhkey_t const *p_dhkey));
+
+
+/**@brief Notify the peer of a local keypress.
+ *
+ * @mscs
+ * @mmsc{@ref BLE_GAP_PERIPH_LESC_BONDING_PKE_CD_MSC}
+ * @mmsc{@ref BLE_GAP_CENTRAL_LESC_BONDING_PKE_CD_MSC}
+ * @endmscs
+ *
+ * @param[in] conn_handle Connection handle.
+ * @param[in] kp_not See @ref BLE_GAP_KP_NOT_TYPES.
+ *
+ * @retval ::NRF_SUCCESS Keypress notification successfully queued for transmission.
+ * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied.
+ * @retval ::NRF_ERROR_INVALID_STATE Invalid state to perform operation. Either not entering a passkey or keypresses have not been enabled by both peers.
+ * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid connection handle supplied.
+ * @retval ::NRF_ERROR_BUSY The BLE stack is busy. Retry at later time.
+ */
+SVCALL(SD_BLE_GAP_KEYPRESS_NOTIFY, uint32_t, sd_ble_gap_keypress_notify(uint16_t conn_handle, uint8_t kp_not));
+
+
+/**@brief Generate a set of OOB data to send to a peer out of band.
+ *
+ * @note The @ref ble_gap_addr_t included in the OOB data returned will be the currently active one (or, if a connection has already been established,
+ * the one used during connection setup). The application may manually overwrite it with an updated value.
+ *
+ * @mscs
+ * @mmsc{@ref BLE_GAP_PERIPH_LESC_BONDING_OOB_MSC}
+ * @mmsc{@ref BLE_GAP_CENTRAL_LESC_BONDING_OOB_MSC}
+ * @endmscs
+ *
+ * @param[in] conn_handle Connection handle. Can be @ref BLE_CONN_HANDLE_INVALID if a BLE connection has not been established yet.
+ * @param[in] p_pk_own LE Secure Connections local P-256 Public Key.
+ * @param[out] p_oobd_own The OOB data to be sent out of band to a peer.
+ *
+ * @retval ::NRF_SUCCESS OOB data successfully generated.
+ * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied.
+ * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid connection handle supplied.
+ */
+SVCALL(SD_BLE_GAP_LESC_OOB_DATA_GET, uint32_t, sd_ble_gap_lesc_oob_data_get(uint16_t conn_handle, ble_gap_lesc_p256_pk_t const *p_pk_own, ble_gap_lesc_oob_data_t *p_oobd_own));
+
+/**@brief Provide the OOB data sent/received out of band.
+ *
+ * @note An authentication procedure with OOB selected as an algorithm must be in progress when calling this function.
+ * @note A @ref BLE_GAP_EVT_LESC_DHKEY_REQUEST event with the oobd_req set to 1 must have been received prior to calling this function.
+ *
+ * @events
+ * @event{This function is used during authentication procedures\, see the list of events in the documentation of @ref sd_ble_gap_authenticate.}
+ * @endevents
+ *
+ * @mscs
+ * @mmsc{@ref BLE_GAP_PERIPH_LESC_BONDING_OOB_MSC}
+ * @mmsc{@ref BLE_GAP_CENTRAL_LESC_BONDING_OOB_MSC}
+ * @endmscs
+ *
+ * @param[in] conn_handle Connection handle.
+ * @param[in] p_oobd_own The OOB data sent out of band to a peer or NULL if the peer has not received OOB data.
+ * Must correspond to @ref ble_gap_sec_params_t::oob flag in @ref BLE_GAP_EVT_SEC_PARAMS_REQUEST.
+ * @param[in] p_oobd_peer The OOB data received out of band from a peer or NULL if none received.
+ * Must correspond to @ref ble_gap_sec_params_t::oob flag in @ref sd_ble_gap_authenticate in the central role
+ * or @ref sd_ble_gap_sec_params_reply in the peripheral role.
+ *
+ * @retval ::NRF_SUCCESS OOB data accepted.
+ * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied.
+ * @retval ::NRF_ERROR_INVALID_STATE Invalid state to perform operation.
+ * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid connection handle supplied.
+ */
+SVCALL(SD_BLE_GAP_LESC_OOB_DATA_SET, uint32_t, sd_ble_gap_lesc_oob_data_set(uint16_t conn_handle, ble_gap_lesc_oob_data_t const *p_oobd_own, ble_gap_lesc_oob_data_t const *p_oobd_peer));
+
+
+/**@brief Initiate GAP Encryption procedure.
+ *
+ * @details In the central role, this function will initiate the encryption procedure using the encryption information provided.
+ *
+ * @events
+ * @event{@ref BLE_GAP_EVT_CONN_SEC_UPDATE, The connection security has been updated.}
+ * @endevents
+ *
+ * @mscs
+ * @mmsc{@ref BLE_GAP_CENTRAL_ENC_AUTH_MUTEX_MSC}
+ * @mmsc{@ref BLE_GAP_CENTRAL_ENC_MSC}
+ * @mmsc{@ref BLE_GAP_MULTILINK_CTRL_PROC_MSC}
+ * @mmsc{@ref BLE_GAP_CENTRAL_SEC_REQ_MSC}
+ * @endmscs
+ *
+ * @param[in] conn_handle Connection handle.
+ * @param[in] p_master_id Pointer to a @ref ble_gap_master_id_t master identification structure.
+ * @param[in] p_enc_info Pointer to a @ref ble_gap_enc_info_t encryption information structure.
+ *
+ * @retval ::NRF_SUCCESS Successfully initiated authentication procedure.
+ * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied.
+ * @retval ::NRF_ERROR_INVALID_STATE Invalid state to perform operation.
+ * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid connection handle supplied.
+ * @retval ::BLE_ERROR_INVALID_ROLE Operation is not supported in the Peripheral role.
+ * @retval ::NRF_ERROR_BUSY Procedure already in progress or not allowed at this time, wait for pending procedures to complete and retry.
+ */
+SVCALL(SD_BLE_GAP_ENCRYPT, uint32_t, sd_ble_gap_encrypt(uint16_t conn_handle, ble_gap_master_id_t const *p_master_id, ble_gap_enc_info_t const *p_enc_info));
+
+
+/**@brief Reply with GAP security information.
+ *
+ * @details This function is only used to reply to a @ref BLE_GAP_EVT_SEC_INFO_REQUEST, calling it at other times will result in @ref NRF_ERROR_INVALID_STATE.
+ * @note If the call returns an error code, the request is still pending, and the reply call may be repeated with corrected parameters.
+ * @note Data signing is not yet supported, and p_sign_info must therefore be NULL.
+ *
+ * @mscs
+ * @mmsc{@ref BLE_GAP_PERIPH_ENC_MSC}
+ * @endmscs
+ *
+ * @param[in] conn_handle Connection handle.
+ * @param[in] p_enc_info Pointer to a @ref ble_gap_enc_info_t encryption information structure. May be NULL to signal none is available.
+ * @param[in] p_id_info Pointer to a @ref ble_gap_irk_t identity information structure. May be NULL to signal none is available.
+ * @param[in] p_sign_info Pointer to a @ref ble_gap_sign_info_t signing information structure. May be NULL to signal none is available.
+ *
+ * @retval ::NRF_SUCCESS Successfully accepted security information.
+ * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied.
+ * @retval ::NRF_ERROR_INVALID_STATE Invalid state to perform operation.
+ * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid connection handle supplied.
+ */
+SVCALL(SD_BLE_GAP_SEC_INFO_REPLY, uint32_t, sd_ble_gap_sec_info_reply(uint16_t conn_handle, ble_gap_enc_info_t const *p_enc_info, ble_gap_irk_t const *p_id_info, ble_gap_sign_info_t const *p_sign_info));
+
+
+/**@brief Get the current connection security.
+ *
+ * @param[in] conn_handle Connection handle.
+ * @param[out] p_conn_sec Pointer to a @ref ble_gap_conn_sec_t structure to be filled in.
+ *
+ * @retval ::NRF_SUCCESS Current connection security successfully retrieved.
+ * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied.
+ * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid connection handle supplied.
+ */
+SVCALL(SD_BLE_GAP_CONN_SEC_GET, uint32_t, sd_ble_gap_conn_sec_get(uint16_t conn_handle, ble_gap_conn_sec_t *p_conn_sec));
+
+
+/**@brief Start reporting the received signal strength to the application.
+ *
+ * A new event is reported whenever the RSSI value changes, until @ref sd_ble_gap_rssi_stop is called.
+ *
+ * @events
+ * @event{@ref BLE_GAP_EVT_RSSI_CHANGED, New RSSI data available. How often the event is generated is
+ * dependent on the settings of the <code>threshold_dbm</code>
+ * and <code>skip_count</code> input parameters.}
+ * @endevents
+ *
+ * @mscs
+ * @mmsc{@ref BLE_GAP_CENTRAL_RSSI_READ_MSC}
+ * @mmsc{@ref BLE_GAP_RSSI_FILT_MSC}
+ * @endmscs
+ *
+ * @param[in] conn_handle Connection handle.
+ * @param[in] threshold_dbm Minimum change in dBm before triggering the @ref BLE_GAP_EVT_RSSI_CHANGED event. Events are disabled if threshold_dbm equals @ref BLE_GAP_RSSI_THRESHOLD_INVALID.
+ * @param[in] skip_count Number of RSSI samples with a change of threshold_dbm or more before sending a new @ref BLE_GAP_EVT_RSSI_CHANGED event.
+ *
+ * @retval ::NRF_SUCCESS Successfully activated RSSI reporting.
+ * @retval ::NRF_ERROR_INVALID_STATE RSSI reporting is already ongoing.
+ * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid connection handle supplied.
+ */
+SVCALL(SD_BLE_GAP_RSSI_START, uint32_t, sd_ble_gap_rssi_start(uint16_t conn_handle, uint8_t threshold_dbm, uint8_t skip_count));
+
+
+/**@brief Stop reporting the received signal strength.
+ *
+ * @note An RSSI change detected before the call but not yet received by the application
+ * may be reported after @ref sd_ble_gap_rssi_stop has been called.
+ *
+ * @mscs
+ * @mmsc{@ref BLE_GAP_CENTRAL_RSSI_READ_MSC}
+ * @mmsc{@ref BLE_GAP_RSSI_FILT_MSC}
+ * @endmscs
+ *
+ * @param[in] conn_handle Connection handle.
+ *
+ * @retval ::NRF_SUCCESS Successfully deactivated RSSI reporting.
+ * @retval ::NRF_ERROR_INVALID_STATE RSSI reporting is not ongoing.
+ * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid connection handle supplied.
+ */
+SVCALL(SD_BLE_GAP_RSSI_STOP, uint32_t, sd_ble_gap_rssi_stop(uint16_t conn_handle));
+
+
+/**@brief Get the received signal strength for the last connection event.
+ *
+ * @ref sd_ble_gap_rssi_start must be called to start reporting RSSI before using this function. @ref NRF_ERROR_NOT_FOUND
+ * will be returned until RSSI was sampled for the first time after calling @ref sd_ble_gap_rssi_start.
+ * @mscs
+ * @mmsc{@ref BLE_GAP_CENTRAL_RSSI_READ_MSC}
+ * @endmscs
+ *
+ * @param[in] conn_handle Connection handle.
+ * @param[out] p_rssi Pointer to the location where the RSSI measurement shall be stored.
+ * @param[out] p_ch_index Pointer to the location where Channel Index for the RSSI measurement shall be stored.
+ *
+ * @retval ::NRF_SUCCESS Successfully read the RSSI.
+ * @retval ::NRF_ERROR_NOT_FOUND No sample is available.
+ * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied.
+ * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid connection handle supplied.
+ * @retval ::NRF_ERROR_INVALID_STATE RSSI reporting is not ongoing.
+ */
+SVCALL(SD_BLE_GAP_RSSI_GET, uint32_t, sd_ble_gap_rssi_get(uint16_t conn_handle, int8_t *p_rssi, uint8_t *p_ch_index));
+
+
+/**@brief Start or continue scanning (GAP Discovery procedure, Observer Procedure).
+ *
+ * @note A call to this function will require the application to keep the memory pointed by
+ * p_adv_report_buffer alive until the buffer is released. The buffer is released when the scanner is stopped
+ * or when this function is called with another buffer.
+ *
+ * @note The scanner will automatically stop in the following cases:
+ * - @ref sd_ble_gap_scan_stop is called.
+ * - @ref sd_ble_gap_connect is called.
+ * - A @ref BLE_GAP_EVT_TIMEOUT with source set to @ref BLE_GAP_TIMEOUT_SRC_SCAN is received.
+ * - When a @ref BLE_GAP_EVT_ADV_REPORT event is received and @ref ble_gap_adv_report_type_t::status is not set to
+ * @ref BLE_GAP_ADV_DATA_STATUS_INCOMPLETE_MORE_DATA. In this case scanning is only paused to let the application
+ * access received data. The application must call this function to continue scanning, or call @ref sd_ble_gap_scan_stop
+ * to stop scanning.
+ *
+ * @note If a @ref BLE_GAP_EVT_ADV_REPORT event is received with @ref ble_gap_adv_report_type_t::status set to
+ * @ref BLE_GAP_ADV_DATA_STATUS_INCOMPLETE_MORE_DATA, the scanner will continue scanning, and the application will
+ * receive more reports from this advertising event. The following reports will include the old and new received data.
+ * The application can stop the scanner from receiving more packets from this advertising event by calling this function.
+ * This might be useful when receiving data from extended advertising events where @ref ble_gap_evt_adv_report_t::aux_pointer
+ * is large.
+ *
+ * @events
+ * @event{@ref BLE_GAP_EVT_ADV_REPORT, An advertising or scan response packet has been received.}
+ * @event{@ref BLE_GAP_EVT_TIMEOUT, Scanner has timed out.}
+ * @endevents
+ *
+ * @mscs
+ * @mmsc{@ref BLE_GAP_SCAN_MSC}
+ * @mmsc{@ref BLE_GAP_WL_SHARE_MSC}
+ * @endmscs
+ *
+ * @param[in] p_scan_params Pointer to scan parameters structure. When this function is used to continue
+ * scanning, this parameter must be NULL.
+ * @param[in] p_adv_report_buffer Pointer to buffer used to store incoming advertising data.
+ * The memory pointed to should be kept alive until the scanning is stopped.
+ * See @ref BLE_GAP_SCAN_BUFFER_SIZE for minimum and maximum buffer size.
+ * If the scanner receives advertising data larger than can be stored in the buffer,
+ * a @ref BLE_GAP_EVT_ADV_REPORT will be raised with @ref ble_gap_adv_report_type_t::status
+ * set to @ref BLE_GAP_ADV_DATA_STATUS_INCOMPLETE_TRUNCATED.
+ *
+ * @retval ::NRF_SUCCESS Successfully initiated scanning procedure.
+ * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied.
+ * @retval ::NRF_ERROR_INVALID_STATE Invalid state to perform operation. Either:
+ * - Scanning is already ongoing and p_scan_params was not NULL
+ * - Scanning is not running and p_scan_params was NULL.
+ * - The scanner has timed out when this function is called to continue scanning.
+ * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied. See @ref ble_gap_scan_params_t.
+ * @retval ::NRF_ERROR_NOT_SUPPORTED Unsupported parameters supplied. See @ref ble_gap_scan_params_t.
+ * @retval ::NRF_ERROR_INVALID_LENGTH The provided buffer length is invalid. See @ref BLE_GAP_SCAN_BUFFER_MIN.
+ * @retval ::NRF_ERROR_RESOURCES Not enough BLE role slots available.
+ * Stop one or more currently active roles (Central, Peripheral or Broadcaster) and try again
+ * @retval ::NRF_ERROR_NOT_SUPPORTED Unsupported PHYs supplied to the call.
+ */
+SVCALL(SD_BLE_GAP_SCAN_START, uint32_t, sd_ble_gap_scan_start(ble_gap_scan_params_t const *p_scan_params, ble_data_t const * p_adv_report_buffer));
+
+
+/**@brief Stop scanning (GAP Discovery procedure, Observer Procedure).
+ *
+ * @note The buffer provided in @ref sd_ble_gap_scan_start is released.
+ *
+ * @mscs
+ * @mmsc{@ref BLE_GAP_SCAN_MSC}
+ * @mmsc{@ref BLE_GAP_WL_SHARE_MSC}
+ * @endmscs
+ *
+ * @retval ::NRF_SUCCESS Successfully stopped scanning procedure.
+ * @retval ::NRF_ERROR_INVALID_STATE Invalid state to perform operation. Not in the scanning state.
+ */
+SVCALL(SD_BLE_GAP_SCAN_STOP, uint32_t, sd_ble_gap_scan_stop(void));
+
+
+/**@brief Create a connection (GAP Link Establishment).
+ *
+ * @note If a scanning procedure is currently in progress it will be automatically stopped when calling this function.
+ * The scanning procedure will be stopped even if the function returns an error.
+ *
+ * @mscs
+ * @mmsc{@ref BLE_GAP_WL_SHARE_MSC}
+ * @mmsc{@ref BLE_GAP_CENTRAL_CONN_PRIV_MSC}
+ * @mmsc{@ref BLE_GAP_CENTRAL_CONN_MSC}
+ * @endmscs
+ *
+ * @param[in] p_peer_addr Pointer to peer identity address. If @ref ble_gap_scan_params_t::filter_policy is set to use
+ * whitelist, then p_peer_addr is ignored.
+ * @param[in] p_scan_params Pointer to scan parameters structure.
+ * @param[in] p_conn_params Pointer to desired connection parameters.
+ * @param[in] conn_cfg_tag Tag identifying a configuration set by @ref sd_ble_cfg_set or
+ * @ref BLE_CONN_CFG_TAG_DEFAULT to use the default connection configuration.
+ *
+ * @retval ::NRF_SUCCESS Successfully initiated connection procedure.
+ * @retval ::NRF_ERROR_INVALID_ADDR Invalid parameter(s) pointer supplied.
+ * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied.
+ * - Invalid parameter(s) in p_scan_params or p_conn_params.
+ * - Use of whitelist requested but whitelist has not been set, see @ref sd_ble_gap_whitelist_set.
+ * - Peer address was not present in the device identity list, see @ref sd_ble_gap_device_identities_set.
+ * @retval ::NRF_ERROR_NOT_FOUND conn_cfg_tag not found.
+ * @retval ::NRF_ERROR_INVALID_STATE The SoftDevice is in an invalid state to perform this operation. This may be due to an
+ * existing locally initiated connect procedure, which must complete before initiating again.
+ * @retval ::BLE_ERROR_GAP_INVALID_BLE_ADDR Invalid Peer address.
+ * @retval ::NRF_ERROR_CONN_COUNT The limit of available connections has been reached.
+ * @retval ::NRF_ERROR_RESOURCES Either:
+ * - Not enough BLE role slots available.
+ * Stop one or more currently active roles (Central, Peripheral or Observer) and try again.
+ * - The event_length parameter associated with conn_cfg_tag is too small to be able to
+ * establish a connection on the selected @ref ble_gap_scan_params_t::scan_phys.
+ * Use @ref sd_ble_cfg_set to increase the event length.
+ * @retval ::NRF_ERROR_NOT_SUPPORTED Unsupported PHYs supplied to the call.
+ */
+SVCALL(SD_BLE_GAP_CONNECT, uint32_t, sd_ble_gap_connect(ble_gap_addr_t const *p_peer_addr, ble_gap_scan_params_t const *p_scan_params, ble_gap_conn_params_t const *p_conn_params, uint8_t conn_cfg_tag));
+
+
+/**@brief Cancel a connection establishment.
+ *
+ * @mscs
+ * @mmsc{@ref BLE_GAP_CENTRAL_CONN_MSC}
+ * @endmscs
+ *
+ * @retval ::NRF_SUCCESS Successfully canceled an ongoing connection procedure.
+ * @retval ::NRF_ERROR_INVALID_STATE Invalid state to perform operation.
+ */
+SVCALL(SD_BLE_GAP_CONNECT_CANCEL, uint32_t, sd_ble_gap_connect_cancel(void));
+
+
+/**@brief Initiate or respond to a PHY Update Procedure
+ *
+ * @details This function is used to initiate or respond to a PHY Update Procedure. It will always
+ * generate a @ref BLE_GAP_EVT_PHY_UPDATE event if successfully executed.
+ * If this function is used to initiate a PHY Update procedure and the only option
+ * provided in @ref ble_gap_phys_t::tx_phys and @ref ble_gap_phys_t::rx_phys is the
+ * currently active PHYs in the respective directions, the SoftDevice will generate a
+ * @ref BLE_GAP_EVT_PHY_UPDATE with the current PHYs set and will not initiate the
+ * procedure in the Link Layer.
+ *
+ * If @ref ble_gap_phys_t::tx_phys or @ref ble_gap_phys_t::rx_phys is @ref BLE_GAP_PHY_AUTO,
+ * then the stack will select PHYs based on the peer's PHY preferences and the local link
+ * configuration. The PHY Update procedure will for this case result in a PHY combination
+ * that respects the time constraints configured with @ref sd_ble_cfg_set and the current
+ * link layer data length.
+ *
+ * When acting as a central, the SoftDevice will select the fastest common PHY in each direction.
+ *
+ * If the peer does not support the PHY Update Procedure, then the resulting
+ * @ref BLE_GAP_EVT_PHY_UPDATE event will have a status set to
+ * @ref BLE_HCI_UNSUPPORTED_REMOTE_FEATURE.
+ *
+ * If the PHY procedure was rejected by the peer due to a procedure collision, the status
+ * will be @ref BLE_HCI_STATUS_CODE_LMP_ERROR_TRANSACTION_COLLISION or
+ * @ref BLE_HCI_DIFFERENT_TRANSACTION_COLLISION.
+ * If the peer responds to the PHY Update procedure with invalid parameters, the status
+ * will be @ref BLE_HCI_STATUS_CODE_INVALID_LMP_PARAMETERS.
+ * If the PHY procedure was rejected by the peer for a different reason, the status will
+ * contain the reason as specified by the peer.
+ *
+ * @events
+ * @event{@ref BLE_GAP_EVT_PHY_UPDATE, Result of the PHY Update Procedure.}
+ * @endevents
+ *
+ * @mscs
+ * @mmsc{@ref BLE_GAP_CENTRAL_PHY_UPDATE}
+ * @mmsc{@ref BLE_GAP_PERIPHERAL_PHY_UPDATE}
+ * @endmscs
+ *
+ * @param[in] conn_handle Connection handle to indicate the connection for which the PHY Update is requested.
+ * @param[in] p_gap_phys Pointer to PHY structure.
+ *
+ * @retval ::NRF_SUCCESS Successfully requested a PHY Update.
+ * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied.
+ * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid connection handle supplied.
+ * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied.
+ * @retval ::NRF_ERROR_NOT_SUPPORTED Unsupported PHYs supplied to the call.
+ * @retval ::NRF_ERROR_INVALID_STATE Invalid state to perform operation.
+ * @retval ::NRF_ERROR_BUSY Procedure is already in progress or not allowed at this time. Process pending events and wait for the pending procedure to complete and retry.
+ *
+ */
+SVCALL(SD_BLE_GAP_PHY_UPDATE, uint32_t, sd_ble_gap_phy_update(uint16_t conn_handle, ble_gap_phys_t const *p_gap_phys));
+
+
+/**@brief Initiate or respond to a Data Length Update Procedure.
+ *
+ * @note If the application uses @ref BLE_GAP_DATA_LENGTH_AUTO for one or more members of
+ * p_dl_params, the SoftDevice will choose the highest value supported in current
+ * configuration and connection parameters.
+ *
+ * @param[in] conn_handle Connection handle.
+ * @param[in] p_dl_params Pointer to local parameters to be used in Data Length Update
+ * Procedure. Set any member to @ref BLE_GAP_DATA_LENGTH_AUTO to let
+ * the SoftDevice automatically decide the value for that member.
+ * Set to NULL to use automatic values for all members.
+ * @param[out] p_dl_limitation Pointer to limitation to be written when local device does not
+ * have enough resources or does not support the requested Data Length
+ * Update parameters. Ignored if NULL.
+ *
+ * @mscs
+ * @mmsc{@ref BLE_GAP_DATA_LENGTH_UPDATE_PROCEDURE_MSC}
+ * @endmscs
+ *
+ * @retval ::NRF_SUCCESS Successfully set Data Length Extension initiation/response parameters.
+ * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied.
+ * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid connection handle parameter supplied.
+ * @retval ::NRF_ERROR_INVALID_STATE Invalid state to perform operation.
+ * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameters supplied.
+ * @retval ::NRF_ERROR_NOT_SUPPORTED The requested parameters are not supported by the SoftDevice. Inspect
+ * p_dl_limitation to see which parameter is not supported.
+ * @retval ::NRF_ERROR_RESOURCES The connection event length configured for this link is not sufficient for the requested parameters.
+ * Use @ref sd_ble_cfg_set with @ref BLE_CONN_CFG_GAP to increase the connection event length.
+ * Inspect p_dl_limitation to see where the limitation is.
+ * @retval ::NRF_ERROR_BUSY Peer has already initiated a Data Length Update Procedure. Process the
+ * pending @ref BLE_GAP_EVT_DATA_LENGTH_UPDATE_REQUEST event to respond.
+ */
+SVCALL(SD_BLE_GAP_DATA_LENGTH_UPDATE, uint32_t, sd_ble_gap_data_length_update(uint16_t conn_handle, ble_gap_data_length_params_t const *p_dl_params, ble_gap_data_length_limitation_t *p_dl_limitation));
+
+/**@brief Start the Quality of Service (QoS) channel survey module.
+ *
+ * @details The channel survey module provides measurements of the energy levels on
+ * the Bluetooth Low Energy channels. When the module is enabled, @ref BLE_GAP_EVT_QOS_CHANNEL_SURVEY_REPORT
+ * events will periodically report the measured energy levels for each channel.
+ *
+ * @note The measurements are scheduled with lower priority than other Bluetooth Low Energy roles,
+ * Radio Timeslot API events and Flash API events.
+ *
+ * @note The channel survey module will attempt to do measurements so that the average interval
+ * between measurements will be interval_us. However due to the channel survey module
+ * having the lowest priority of all roles and modules, this may not be possible. In that
+ * case fewer than expected channel survey reports may be given.
+ *
+ * @note In order to use the channel survey module, @ref ble_gap_cfg_role_count_t::qos_channel_survey_role_available
+ * must be set. This is done using @ref sd_ble_cfg_set.
+ *
+ * @param[in] interval_us Requested average interval for the measurements and reports. See
+ * @ref BLE_GAP_QOS_CHANNEL_SURVEY_INTERVALS for valid ranges. If set
+ * to @ref BLE_GAP_QOS_CHANNEL_SURVEY_INTERVAL_CONTINUOUS, the channel
+ * survey role will be scheduled at every available opportunity.
+ *
+ * @retval ::NRF_SUCCESS The module is successfully started.
+ * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter supplied. interval_us is out of the
+ * allowed range.
+ * @retval ::NRF_ERROR_INVALID_STATE Trying to start the module when already running.
+ * @retval ::NRF_ERROR_RESOURCES The channel survey module is not available to the application.
+ * Set @ref ble_gap_cfg_role_count_t::qos_channel_survey_role_available using
+ * @ref sd_ble_cfg_set.
+ */
+SVCALL(SD_BLE_GAP_QOS_CHANNEL_SURVEY_START, uint32_t, sd_ble_gap_qos_channel_survey_start(uint32_t interval_us));
+
+/**@brief Stop the Quality of Service (QoS) channel survey module.
+ *
+ * @retval ::NRF_SUCCESS The module is successfully stopped.
+ * @retval ::NRF_ERROR_INVALID_STATE Trying to stop the module when it is not running.
+ */
+SVCALL(SD_BLE_GAP_QOS_CHANNEL_SURVEY_STOP, uint32_t, sd_ble_gap_qos_channel_survey_stop(void));
+
+
+/** @} */
+
+#ifdef __cplusplus
+}
+#endif
+#endif // BLE_GAP_H__
+
+/**
+ @}
+*/
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/softdevice/s132/headers/ble_gatt.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/softdevice/s132/headers/ble_gatt.h
new file mode 100644
index 0000000..98a7a15
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/softdevice/s132/headers/ble_gatt.h
@@ -0,0 +1,228 @@
+/*
+ * Copyright (c) 2013 - 2017, 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ */
+
+/**
+ @addtogroup BLE_GATT Generic Attribute Profile (GATT) Common
+ @{
+ @brief Common definitions and prototypes for the GATT interfaces.
+ */
+
+#ifndef BLE_GATT_H__
+#define BLE_GATT_H__
+
+#include <stdint.h>
+#include "nrf_svc.h"
+#include "nrf_error.h"
+#include "ble_hci.h"
+#include "ble_ranges.h"
+#include "ble_types.h"
+#include "ble_err.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** @addtogroup BLE_GATT_DEFINES Defines
+ * @{ */
+
+/** @brief Default ATT MTU, in bytes. */
+#define BLE_GATT_ATT_MTU_DEFAULT 23
+
+/**@brief Invalid Attribute Handle. */
+#define BLE_GATT_HANDLE_INVALID 0x0000
+
+/**@brief First Attribute Handle. */
+#define BLE_GATT_HANDLE_START 0x0001
+
+/**@brief Last Attribute Handle. */
+#define BLE_GATT_HANDLE_END 0xFFFF
+
+/** @defgroup BLE_GATT_TIMEOUT_SOURCES GATT Timeout sources
+ * @{ */
+#define BLE_GATT_TIMEOUT_SRC_PROTOCOL 0x00 /**< ATT Protocol timeout. */
+/** @} */
+
+/** @defgroup BLE_GATT_WRITE_OPS GATT Write operations
+ * @{ */
+#define BLE_GATT_OP_INVALID 0x00 /**< Invalid Operation. */
+#define BLE_GATT_OP_WRITE_REQ 0x01 /**< Write Request. */
+#define BLE_GATT_OP_WRITE_CMD 0x02 /**< Write Command. */
+#define BLE_GATT_OP_SIGN_WRITE_CMD 0x03 /**< Signed Write Command. */
+#define BLE_GATT_OP_PREP_WRITE_REQ 0x04 /**< Prepare Write Request. */
+#define BLE_GATT_OP_EXEC_WRITE_REQ 0x05 /**< Execute Write Request. */
+/** @} */
+
+/** @defgroup BLE_GATT_EXEC_WRITE_FLAGS GATT Execute Write flags
+ * @{ */
+#define BLE_GATT_EXEC_WRITE_FLAG_PREPARED_CANCEL 0x00 /**< Cancel prepared write. */
+#define BLE_GATT_EXEC_WRITE_FLAG_PREPARED_WRITE 0x01 /**< Execute prepared write. */
+/** @} */
+
+/** @defgroup BLE_GATT_HVX_TYPES GATT Handle Value operations
+ * @{ */
+#define BLE_GATT_HVX_INVALID 0x00 /**< Invalid Operation. */
+#define BLE_GATT_HVX_NOTIFICATION 0x01 /**< Handle Value Notification. */
+#define BLE_GATT_HVX_INDICATION 0x02 /**< Handle Value Indication. */
+/** @} */
+
+/** @defgroup BLE_GATT_STATUS_CODES GATT Status Codes
+ * @{ */
+#define BLE_GATT_STATUS_SUCCESS 0x0000 /**< Success. */
+#define BLE_GATT_STATUS_UNKNOWN 0x0001 /**< Unknown or not applicable status. */
+#define BLE_GATT_STATUS_ATTERR_INVALID 0x0100 /**< ATT Error: Invalid Error Code. */
+#define BLE_GATT_STATUS_ATTERR_INVALID_HANDLE 0x0101 /**< ATT Error: Invalid Attribute Handle. */
+#define BLE_GATT_STATUS_ATTERR_READ_NOT_PERMITTED 0x0102 /**< ATT Error: Read not permitted. */
+#define BLE_GATT_STATUS_ATTERR_WRITE_NOT_PERMITTED 0x0103 /**< ATT Error: Write not permitted. */
+#define BLE_GATT_STATUS_ATTERR_INVALID_PDU 0x0104 /**< ATT Error: Used in ATT as Invalid PDU. */
+#define BLE_GATT_STATUS_ATTERR_INSUF_AUTHENTICATION 0x0105 /**< ATT Error: Authenticated link required. */
+#define BLE_GATT_STATUS_ATTERR_REQUEST_NOT_SUPPORTED 0x0106 /**< ATT Error: Used in ATT as Request Not Supported. */
+#define BLE_GATT_STATUS_ATTERR_INVALID_OFFSET 0x0107 /**< ATT Error: Offset specified was past the end of the attribute. */
+#define BLE_GATT_STATUS_ATTERR_INSUF_AUTHORIZATION 0x0108 /**< ATT Error: Used in ATT as Insufficient Authorization. */
+#define BLE_GATT_STATUS_ATTERR_PREPARE_QUEUE_FULL 0x0109 /**< ATT Error: Used in ATT as Prepare Queue Full. */
+#define BLE_GATT_STATUS_ATTERR_ATTRIBUTE_NOT_FOUND 0x010A /**< ATT Error: Used in ATT as Attribute not found. */
+#define BLE_GATT_STATUS_ATTERR_ATTRIBUTE_NOT_LONG 0x010B /**< ATT Error: Attribute cannot be read or written using read/write blob requests. */
+#define BLE_GATT_STATUS_ATTERR_INSUF_ENC_KEY_SIZE 0x010C /**< ATT Error: Encryption key size used is insufficient. */
+#define BLE_GATT_STATUS_ATTERR_INVALID_ATT_VAL_LENGTH 0x010D /**< ATT Error: Invalid value size. */
+#define BLE_GATT_STATUS_ATTERR_UNLIKELY_ERROR 0x010E /**< ATT Error: Very unlikely error. */
+#define BLE_GATT_STATUS_ATTERR_INSUF_ENCRYPTION 0x010F /**< ATT Error: Encrypted link required. */
+#define BLE_GATT_STATUS_ATTERR_UNSUPPORTED_GROUP_TYPE 0x0110 /**< ATT Error: Attribute type is not a supported grouping attribute. */
+#define BLE_GATT_STATUS_ATTERR_INSUF_RESOURCES 0x0111 /**< ATT Error: Encrypted link required. */
+#define BLE_GATT_STATUS_ATTERR_RFU_RANGE1_BEGIN 0x0112 /**< ATT Error: Reserved for Future Use range #1 begin. */
+#define BLE_GATT_STATUS_ATTERR_RFU_RANGE1_END 0x017F /**< ATT Error: Reserved for Future Use range #1 end. */
+#define BLE_GATT_STATUS_ATTERR_APP_BEGIN 0x0180 /**< ATT Error: Application range begin. */
+#define BLE_GATT_STATUS_ATTERR_APP_END 0x019F /**< ATT Error: Application range end. */
+#define BLE_GATT_STATUS_ATTERR_RFU_RANGE2_BEGIN 0x01A0 /**< ATT Error: Reserved for Future Use range #2 begin. */
+#define BLE_GATT_STATUS_ATTERR_RFU_RANGE2_END 0x01DF /**< ATT Error: Reserved for Future Use range #2 end. */
+#define BLE_GATT_STATUS_ATTERR_RFU_RANGE3_BEGIN 0x01E0 /**< ATT Error: Reserved for Future Use range #3 begin. */
+#define BLE_GATT_STATUS_ATTERR_RFU_RANGE3_END 0x01FC /**< ATT Error: Reserved for Future Use range #3 end. */
+#define BLE_GATT_STATUS_ATTERR_CPS_CCCD_CONFIG_ERROR 0x01FD /**< ATT Common Profile and Service Error: Client Characteristic Configuration Descriptor improperly configured. */
+#define BLE_GATT_STATUS_ATTERR_CPS_PROC_ALR_IN_PROG 0x01FE /**< ATT Common Profile and Service Error: Procedure Already in Progress. */
+#define BLE_GATT_STATUS_ATTERR_CPS_OUT_OF_RANGE 0x01FF /**< ATT Common Profile and Service Error: Out Of Range. */
+/** @} */
+
+
+/** @defgroup BLE_GATT_CPF_FORMATS Characteristic Presentation Formats
+ * @note Found at http://developer.bluetooth.org/gatt/descriptors/Pages/DescriptorViewer.aspx?u=org.bluetooth.descriptor.gatt.characteristic_presentation_format.xml
+ * @{ */
+#define BLE_GATT_CPF_FORMAT_RFU 0x00 /**< Reserved For Future Use. */
+#define BLE_GATT_CPF_FORMAT_BOOLEAN 0x01 /**< Boolean. */
+#define BLE_GATT_CPF_FORMAT_2BIT 0x02 /**< Unsigned 2-bit integer. */
+#define BLE_GATT_CPF_FORMAT_NIBBLE 0x03 /**< Unsigned 4-bit integer. */
+#define BLE_GATT_CPF_FORMAT_UINT8 0x04 /**< Unsigned 8-bit integer. */
+#define BLE_GATT_CPF_FORMAT_UINT12 0x05 /**< Unsigned 12-bit integer. */
+#define BLE_GATT_CPF_FORMAT_UINT16 0x06 /**< Unsigned 16-bit integer. */
+#define BLE_GATT_CPF_FORMAT_UINT24 0x07 /**< Unsigned 24-bit integer. */
+#define BLE_GATT_CPF_FORMAT_UINT32 0x08 /**< Unsigned 32-bit integer. */
+#define BLE_GATT_CPF_FORMAT_UINT48 0x09 /**< Unsigned 48-bit integer. */
+#define BLE_GATT_CPF_FORMAT_UINT64 0x0A /**< Unsigned 64-bit integer. */
+#define BLE_GATT_CPF_FORMAT_UINT128 0x0B /**< Unsigned 128-bit integer. */
+#define BLE_GATT_CPF_FORMAT_SINT8 0x0C /**< Signed 2-bit integer. */
+#define BLE_GATT_CPF_FORMAT_SINT12 0x0D /**< Signed 12-bit integer. */
+#define BLE_GATT_CPF_FORMAT_SINT16 0x0E /**< Signed 16-bit integer. */
+#define BLE_GATT_CPF_FORMAT_SINT24 0x0F /**< Signed 24-bit integer. */
+#define BLE_GATT_CPF_FORMAT_SINT32 0x10 /**< Signed 32-bit integer. */
+#define BLE_GATT_CPF_FORMAT_SINT48 0x11 /**< Signed 48-bit integer. */
+#define BLE_GATT_CPF_FORMAT_SINT64 0x12 /**< Signed 64-bit integer. */
+#define BLE_GATT_CPF_FORMAT_SINT128 0x13 /**< Signed 128-bit integer. */
+#define BLE_GATT_CPF_FORMAT_FLOAT32 0x14 /**< IEEE-754 32-bit floating point. */
+#define BLE_GATT_CPF_FORMAT_FLOAT64 0x15 /**< IEEE-754 64-bit floating point. */
+#define BLE_GATT_CPF_FORMAT_SFLOAT 0x16 /**< IEEE-11073 16-bit SFLOAT. */
+#define BLE_GATT_CPF_FORMAT_FLOAT 0x17 /**< IEEE-11073 32-bit FLOAT. */
+#define BLE_GATT_CPF_FORMAT_DUINT16 0x18 /**< IEEE-20601 format. */
+#define BLE_GATT_CPF_FORMAT_UTF8S 0x19 /**< UTF-8 string. */
+#define BLE_GATT_CPF_FORMAT_UTF16S 0x1A /**< UTF-16 string. */
+#define BLE_GATT_CPF_FORMAT_STRUCT 0x1B /**< Opaque Structure. */
+/** @} */
+
+/** @defgroup BLE_GATT_CPF_NAMESPACES GATT Bluetooth Namespaces
+ * @{
+ */
+#define BLE_GATT_CPF_NAMESPACE_BTSIG 0x01 /**< Bluetooth SIG defined Namespace. */
+#define BLE_GATT_CPF_NAMESPACE_DESCRIPTION_UNKNOWN 0x0000 /**< Namespace Description Unknown. */
+/** @} */
+
+/** @} */
+
+/** @addtogroup BLE_GATT_STRUCTURES Structures
+ * @{ */
+
+/**
+ * @brief BLE GATT connection configuration parameters, set with @ref sd_ble_cfg_set.
+ *
+ * @retval ::NRF_ERROR_INVALID_PARAM att_mtu is smaller than @ref BLE_GATT_ATT_MTU_DEFAULT.
+ */
+typedef struct
+{
+ uint16_t att_mtu; /**< Maximum size of ATT packet the SoftDevice can send or receive.
+ The default and minimum value is @ref BLE_GATT_ATT_MTU_DEFAULT.
+ @mscs
+ @mmsc{@ref BLE_GATTC_MTU_EXCHANGE}
+ @mmsc{@ref BLE_GATTS_MTU_EXCHANGE}
+ @endmscs
+ */
+} ble_gatt_conn_cfg_t;
+
+/**@brief GATT Characteristic Properties. */
+typedef struct
+{
+ /* Standard properties */
+ uint8_t broadcast :1; /**< Broadcasting of the value permitted. */
+ uint8_t read :1; /**< Reading the value permitted. */
+ uint8_t write_wo_resp :1; /**< Writing the value with Write Command permitted. */
+ uint8_t write :1; /**< Writing the value with Write Request permitted. */
+ uint8_t notify :1; /**< Notification of the value permitted. */
+ uint8_t indicate :1; /**< Indications of the value permitted. */
+ uint8_t auth_signed_wr :1; /**< Writing the value with Signed Write Command permitted. */
+} ble_gatt_char_props_t;
+
+/**@brief GATT Characteristic Extended Properties. */
+typedef struct
+{
+ /* Extended properties */
+ uint8_t reliable_wr :1; /**< Writing the value with Queued Write operations permitted. */
+ uint8_t wr_aux :1; /**< Writing the Characteristic User Description descriptor permitted. */
+} ble_gatt_char_ext_props_t;
+
+/** @} */
+
+#ifdef __cplusplus
+}
+#endif
+#endif // BLE_GATT_H__
+
+/** @} */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/softdevice/s132/headers/ble_gattc.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/softdevice/s132/headers/ble_gattc.h
new file mode 100644
index 0000000..7fb3920
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/softdevice/s132/headers/ble_gattc.h
@@ -0,0 +1,715 @@
+/*
+ * Copyright (c) 2011 - 2017, 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ */
+
+/**
+ @addtogroup BLE_GATTC Generic Attribute Profile (GATT) Client
+ @{
+ @brief Definitions and prototypes for the GATT Client interface.
+ */
+
+#ifndef BLE_GATTC_H__
+#define BLE_GATTC_H__
+
+#include <stdint.h>
+#include "nrf.h"
+#include "nrf_svc.h"
+#include "nrf_error.h"
+#include "ble_ranges.h"
+#include "ble_types.h"
+#include "ble_err.h"
+#include "ble_gatt.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** @addtogroup BLE_GATTC_ENUMERATIONS Enumerations
+ * @{ */
+
+/**@brief GATTC API SVC numbers. */
+enum BLE_GATTC_SVCS
+{
+ SD_BLE_GATTC_PRIMARY_SERVICES_DISCOVER = BLE_GATTC_SVC_BASE, /**< Primary Service Discovery. */
+ SD_BLE_GATTC_RELATIONSHIPS_DISCOVER, /**< Relationship Discovery. */
+ SD_BLE_GATTC_CHARACTERISTICS_DISCOVER, /**< Characteristic Discovery. */
+ SD_BLE_GATTC_DESCRIPTORS_DISCOVER, /**< Characteristic Descriptor Discovery. */
+ SD_BLE_GATTC_ATTR_INFO_DISCOVER, /**< Attribute Information Discovery. */
+ SD_BLE_GATTC_CHAR_VALUE_BY_UUID_READ, /**< Read Characteristic Value by UUID. */
+ SD_BLE_GATTC_READ, /**< Generic read. */
+ SD_BLE_GATTC_CHAR_VALUES_READ, /**< Read multiple Characteristic Values. */
+ SD_BLE_GATTC_WRITE, /**< Generic write. */
+ SD_BLE_GATTC_HV_CONFIRM, /**< Handle Value Confirmation. */
+ SD_BLE_GATTC_EXCHANGE_MTU_REQUEST, /**< Exchange MTU Request. */
+};
+
+/**
+ * @brief GATT Client Event IDs.
+ */
+enum BLE_GATTC_EVTS
+{
+ BLE_GATTC_EVT_PRIM_SRVC_DISC_RSP = BLE_GATTC_EVT_BASE, /**< Primary Service Discovery Response event. \n See @ref ble_gattc_evt_prim_srvc_disc_rsp_t. */
+ BLE_GATTC_EVT_REL_DISC_RSP, /**< Relationship Discovery Response event. \n See @ref ble_gattc_evt_rel_disc_rsp_t. */
+ BLE_GATTC_EVT_CHAR_DISC_RSP, /**< Characteristic Discovery Response event. \n See @ref ble_gattc_evt_char_disc_rsp_t. */
+ BLE_GATTC_EVT_DESC_DISC_RSP, /**< Descriptor Discovery Response event. \n See @ref ble_gattc_evt_desc_disc_rsp_t. */
+ BLE_GATTC_EVT_ATTR_INFO_DISC_RSP, /**< Attribute Information Response event. \n See @ref ble_gattc_evt_attr_info_disc_rsp_t. */
+ BLE_GATTC_EVT_CHAR_VAL_BY_UUID_READ_RSP, /**< Read By UUID Response event. \n See @ref ble_gattc_evt_char_val_by_uuid_read_rsp_t. */
+ BLE_GATTC_EVT_READ_RSP, /**< Read Response event. \n See @ref ble_gattc_evt_read_rsp_t. */
+ BLE_GATTC_EVT_CHAR_VALS_READ_RSP, /**< Read multiple Response event. \n See @ref ble_gattc_evt_char_vals_read_rsp_t. */
+ BLE_GATTC_EVT_WRITE_RSP, /**< Write Response event. \n See @ref ble_gattc_evt_write_rsp_t. */
+ BLE_GATTC_EVT_HVX, /**< Handle Value Notification or Indication event. \n Confirm indication with @ref sd_ble_gattc_hv_confirm. \n See @ref ble_gattc_evt_hvx_t. */
+ BLE_GATTC_EVT_EXCHANGE_MTU_RSP, /**< Exchange MTU Response event. \n See @ref ble_gattc_evt_exchange_mtu_rsp_t. */
+ BLE_GATTC_EVT_TIMEOUT, /**< Timeout event. \n See @ref ble_gattc_evt_timeout_t. */
+ BLE_GATTC_EVT_WRITE_CMD_TX_COMPLETE /**< Write without Response transmission complete. \n See @ref ble_gattc_evt_write_cmd_tx_complete_t. */
+};
+
+/** @} */
+
+/** @addtogroup BLE_GATTC_DEFINES Defines
+ * @{ */
+
+/** @defgroup BLE_ERRORS_GATTC SVC return values specific to GATTC
+ * @{ */
+#define BLE_ERROR_GATTC_PROC_NOT_PERMITTED (NRF_GATTC_ERR_BASE + 0x000) /**< Procedure not Permitted. */
+/** @} */
+
+/** @defgroup BLE_GATTC_ATTR_INFO_FORMAT Attribute Information Formats
+ * @{ */
+#define BLE_GATTC_ATTR_INFO_FORMAT_16BIT 1 /**< 16-bit Attribute Information Format. */
+#define BLE_GATTC_ATTR_INFO_FORMAT_128BIT 2 /**< 128-bit Attribute Information Format. */
+/** @} */
+
+/** @defgroup BLE_GATTC_DEFAULTS GATT Client defaults
+ * @{ */
+#define BLE_GATTC_WRITE_CMD_TX_QUEUE_SIZE_DEFAULT 1 /**< Default number of Write without Response that can be queued for transmission. */
+/** @} */
+
+/** @} */
+
+/** @addtogroup BLE_GATTC_STRUCTURES Structures
+ * @{ */
+
+/**
+ * @brief BLE GATTC connection configuration parameters, set with @ref sd_ble_cfg_set.
+ */
+typedef struct
+{
+ uint8_t write_cmd_tx_queue_size; /**< The guaranteed minimum number of Write without Response that can be queued for transmission.
+ The default value is @ref BLE_GATTC_WRITE_CMD_TX_QUEUE_SIZE_DEFAULT */
+} ble_gattc_conn_cfg_t;
+
+/**@brief Operation Handle Range. */
+typedef struct
+{
+ uint16_t start_handle; /**< Start Handle. */
+ uint16_t end_handle; /**< End Handle. */
+} ble_gattc_handle_range_t;
+
+
+/**@brief GATT service. */
+typedef struct
+{
+ ble_uuid_t uuid; /**< Service UUID. */
+ ble_gattc_handle_range_t handle_range; /**< Service Handle Range. */
+} ble_gattc_service_t;
+
+
+/**@brief GATT include. */
+typedef struct
+{
+ uint16_t handle; /**< Include Handle. */
+ ble_gattc_service_t included_srvc; /**< Handle of the included service. */
+} ble_gattc_include_t;
+
+
+/**@brief GATT characteristic. */
+typedef struct
+{
+ ble_uuid_t uuid; /**< Characteristic UUID. */
+ ble_gatt_char_props_t char_props; /**< Characteristic Properties. */
+ uint8_t char_ext_props : 1; /**< Extended properties present. */
+ uint16_t handle_decl; /**< Handle of the Characteristic Declaration. */
+ uint16_t handle_value; /**< Handle of the Characteristic Value. */
+} ble_gattc_char_t;
+
+
+/**@brief GATT descriptor. */
+typedef struct
+{
+ uint16_t handle; /**< Descriptor Handle. */
+ ble_uuid_t uuid; /**< Descriptor UUID. */
+} ble_gattc_desc_t;
+
+
+/**@brief Write Parameters. */
+typedef struct
+{
+ uint8_t write_op; /**< Write Operation to be performed, see @ref BLE_GATT_WRITE_OPS. */
+ uint8_t flags; /**< Flags, see @ref BLE_GATT_EXEC_WRITE_FLAGS. */
+ uint16_t handle; /**< Handle to the attribute to be written. */
+ uint16_t offset; /**< Offset in bytes. @note For WRITE_CMD and WRITE_REQ, offset must be 0. */
+ uint16_t len; /**< Length of data in bytes. */
+ uint8_t const *p_value; /**< Pointer to the value data. */
+} ble_gattc_write_params_t;
+
+/**@brief Attribute Information for 16-bit Attribute UUID. */
+typedef struct
+{
+ uint16_t handle; /**< Attribute handle. */
+ ble_uuid_t uuid; /**< 16-bit Attribute UUID. */
+} ble_gattc_attr_info16_t;
+
+/**@brief Attribute Information for 128-bit Attribute UUID. */
+typedef struct
+{
+ uint16_t handle; /**< Attribute handle. */
+ ble_uuid128_t uuid; /**< 128-bit Attribute UUID. */
+} ble_gattc_attr_info128_t;
+
+/**@brief Event structure for @ref BLE_GATTC_EVT_PRIM_SRVC_DISC_RSP. */
+typedef struct
+{
+ uint16_t count; /**< Service count. */
+ ble_gattc_service_t services[1]; /**< Service data. @note This is a variable length array. The size of 1 indicated is only a placeholder for compilation.
+ See @ref sd_ble_evt_get for more information on how to use event structures with variable length array members. */
+} ble_gattc_evt_prim_srvc_disc_rsp_t;
+
+/**@brief Event structure for @ref BLE_GATTC_EVT_REL_DISC_RSP. */
+typedef struct
+{
+ uint16_t count; /**< Include count. */
+ ble_gattc_include_t includes[1]; /**< Include data. @note This is a variable length array. The size of 1 indicated is only a placeholder for compilation.
+ See @ref sd_ble_evt_get for more information on how to use event structures with variable length array members. */
+} ble_gattc_evt_rel_disc_rsp_t;
+
+/**@brief Event structure for @ref BLE_GATTC_EVT_CHAR_DISC_RSP. */
+typedef struct
+{
+ uint16_t count; /**< Characteristic count. */
+ ble_gattc_char_t chars[1]; /**< Characteristic data. @note This is a variable length array. The size of 1 indicated is only a placeholder for compilation.
+ See @ref sd_ble_evt_get for more information on how to use event structures with variable length array members. */
+} ble_gattc_evt_char_disc_rsp_t;
+
+/**@brief Event structure for @ref BLE_GATTC_EVT_DESC_DISC_RSP. */
+typedef struct
+{
+ uint16_t count; /**< Descriptor count. */
+ ble_gattc_desc_t descs[1]; /**< Descriptor data. @note This is a variable length array. The size of 1 indicated is only a placeholder for compilation.
+ See @ref sd_ble_evt_get for more information on how to use event structures with variable length array members. */
+} ble_gattc_evt_desc_disc_rsp_t;
+
+/**@brief Event structure for @ref BLE_GATTC_EVT_ATTR_INFO_DISC_RSP. */
+typedef struct
+{
+ uint16_t count; /**< Attribute count. */
+ uint8_t format; /**< Attribute information format, see @ref BLE_GATTC_ATTR_INFO_FORMAT. */
+ union {
+ ble_gattc_attr_info16_t attr_info16[1]; /**< Attribute information for 16-bit Attribute UUID.
+ @note This is a variable length array. The size of 1 indicated is only a placeholder for compilation.
+ See @ref sd_ble_evt_get for more information on how to use event structures with variable length array members. */
+ ble_gattc_attr_info128_t attr_info128[1]; /**< Attribute information for 128-bit Attribute UUID.
+ @note This is a variable length array. The size of 1 indicated is only a placeholder for compilation.
+ See @ref sd_ble_evt_get for more information on how to use event structures with variable length array members. */
+ } info; /**< Attribute information union. */
+} ble_gattc_evt_attr_info_disc_rsp_t;
+
+/**@brief GATT read by UUID handle value pair. */
+typedef struct
+{
+ uint16_t handle; /**< Attribute Handle. */
+ uint8_t *p_value; /**< Pointer to the Attribute Value, length is available in @ref ble_gattc_evt_char_val_by_uuid_read_rsp_t::value_len. */
+} ble_gattc_handle_value_t;
+
+/**@brief Event structure for @ref BLE_GATTC_EVT_CHAR_VAL_BY_UUID_READ_RSP. */
+typedef struct
+{
+ uint16_t count; /**< Handle-Value Pair Count. */
+ uint16_t value_len; /**< Length of the value in Handle-Value(s) list. */
+ uint8_t handle_value[1]; /**< Handle-Value(s) list. To iterate through the list use @ref sd_ble_gattc_evt_char_val_by_uuid_read_rsp_iter.
+ @note This is a variable length array. The size of 1 indicated is only a placeholder for compilation.
+ See @ref sd_ble_evt_get for more information on how to use event structures with variable length array members. */
+} ble_gattc_evt_char_val_by_uuid_read_rsp_t;
+
+/**@brief Event structure for @ref BLE_GATTC_EVT_READ_RSP. */
+typedef struct
+{
+ uint16_t handle; /**< Attribute Handle. */
+ uint16_t offset; /**< Offset of the attribute data. */
+ uint16_t len; /**< Attribute data length. */
+ uint8_t data[1]; /**< Attribute data. @note This is a variable length array. The size of 1 indicated is only a placeholder for compilation.
+ See @ref sd_ble_evt_get for more information on how to use event structures with variable length array members. */
+} ble_gattc_evt_read_rsp_t;
+
+/**@brief Event structure for @ref BLE_GATTC_EVT_CHAR_VALS_READ_RSP. */
+typedef struct
+{
+ uint16_t len; /**< Concatenated Attribute values length. */
+ uint8_t values[1]; /**< Attribute values. @note This is a variable length array. The size of 1 indicated is only a placeholder for compilation.
+ See @ref sd_ble_evt_get for more information on how to use event structures with variable length array members. */
+} ble_gattc_evt_char_vals_read_rsp_t;
+
+/**@brief Event structure for @ref BLE_GATTC_EVT_WRITE_RSP. */
+typedef struct
+{
+ uint16_t handle; /**< Attribute Handle. */
+ uint8_t write_op; /**< Type of write operation, see @ref BLE_GATT_WRITE_OPS. */
+ uint16_t offset; /**< Data offset. */
+ uint16_t len; /**< Data length. */
+ uint8_t data[1]; /**< Data. @note This is a variable length array. The size of 1 indicated is only a placeholder for compilation.
+ See @ref sd_ble_evt_get for more information on how to use event structures with variable length array members. */
+} ble_gattc_evt_write_rsp_t;
+
+/**@brief Event structure for @ref BLE_GATTC_EVT_HVX. */
+typedef struct
+{
+ uint16_t handle; /**< Handle to which the HVx operation applies. */
+ uint8_t type; /**< Indication or Notification, see @ref BLE_GATT_HVX_TYPES. */
+ uint16_t len; /**< Attribute data length. */
+ uint8_t data[1]; /**< Attribute data. @note This is a variable length array. The size of 1 indicated is only a placeholder for compilation.
+ See @ref sd_ble_evt_get for more information on how to use event structures with variable length array members. */
+} ble_gattc_evt_hvx_t;
+
+/**@brief Event structure for @ref BLE_GATTC_EVT_EXCHANGE_MTU_RSP. */
+typedef struct
+{
+ uint16_t server_rx_mtu; /**< Server RX MTU size. */
+} ble_gattc_evt_exchange_mtu_rsp_t;
+
+/**@brief Event structure for @ref BLE_GATTC_EVT_TIMEOUT. */
+typedef struct
+{
+ uint8_t src; /**< Timeout source, see @ref BLE_GATT_TIMEOUT_SOURCES. */
+} ble_gattc_evt_timeout_t;
+
+/**@brief Event structure for @ref BLE_GATTC_EVT_WRITE_CMD_TX_COMPLETE. */
+typedef struct
+{
+ uint8_t count; /**< Number of write without response transmissions completed. */
+} ble_gattc_evt_write_cmd_tx_complete_t;
+
+/**@brief GATTC event structure. */
+typedef struct
+{
+ uint16_t conn_handle; /**< Connection Handle on which event occurred. */
+ uint16_t gatt_status; /**< GATT status code for the operation, see @ref BLE_GATT_STATUS_CODES. */
+ uint16_t error_handle; /**< In case of error: The handle causing the error. In all other cases @ref BLE_GATT_HANDLE_INVALID. */
+ union
+ {
+ ble_gattc_evt_prim_srvc_disc_rsp_t prim_srvc_disc_rsp; /**< Primary Service Discovery Response Event Parameters. */
+ ble_gattc_evt_rel_disc_rsp_t rel_disc_rsp; /**< Relationship Discovery Response Event Parameters. */
+ ble_gattc_evt_char_disc_rsp_t char_disc_rsp; /**< Characteristic Discovery Response Event Parameters. */
+ ble_gattc_evt_desc_disc_rsp_t desc_disc_rsp; /**< Descriptor Discovery Response Event Parameters. */
+ ble_gattc_evt_char_val_by_uuid_read_rsp_t char_val_by_uuid_read_rsp; /**< Characteristic Value Read by UUID Response Event Parameters. */
+ ble_gattc_evt_read_rsp_t read_rsp; /**< Read Response Event Parameters. */
+ ble_gattc_evt_char_vals_read_rsp_t char_vals_read_rsp; /**< Characteristic Values Read Response Event Parameters. */
+ ble_gattc_evt_write_rsp_t write_rsp; /**< Write Response Event Parameters. */
+ ble_gattc_evt_hvx_t hvx; /**< Handle Value Notification/Indication Event Parameters. */
+ ble_gattc_evt_exchange_mtu_rsp_t exchange_mtu_rsp; /**< Exchange MTU Response Event Parameters. */
+ ble_gattc_evt_timeout_t timeout; /**< Timeout Event Parameters. */
+ ble_gattc_evt_attr_info_disc_rsp_t attr_info_disc_rsp; /**< Attribute Information Discovery Event Parameters. */
+ ble_gattc_evt_write_cmd_tx_complete_t write_cmd_tx_complete; /**< Write without Response transmission complete Event Parameters. */
+ } params; /**< Event Parameters. @note Only valid if @ref gatt_status == @ref BLE_GATT_STATUS_SUCCESS. */
+} ble_gattc_evt_t;
+/** @} */
+
+/** @addtogroup BLE_GATTC_FUNCTIONS Functions
+ * @{ */
+
+/**@brief Initiate or continue a GATT Primary Service Discovery procedure.
+ *
+ * @details This function initiates or resumes a Primary Service discovery procedure, starting from the supplied handle.
+ * If the last service has not been reached, this function must be called again with an updated start handle value to continue the search.
+ *
+ * @note If any of the discovered services have 128-bit UUIDs which are not present in the table provided to ble_vs_uuids_assign, a UUID structure with
+ * type @ref BLE_UUID_TYPE_UNKNOWN will be received in the corresponding event.
+ *
+ * @events
+ * @event{@ref BLE_GATTC_EVT_PRIM_SRVC_DISC_RSP}
+ * @endevents
+ *
+ * @mscs
+ * @mmsc{@ref BLE_GATTC_PRIM_SRVC_DISC_MSC}
+ * @endmscs
+ *
+ * @param[in] conn_handle The connection handle identifying the connection to perform this procedure on.
+ * @param[in] start_handle Handle to start searching from.
+ * @param[in] p_srvc_uuid Pointer to the service UUID to be found. If it is NULL, all primary services will be returned.
+ *
+ * @retval ::NRF_SUCCESS Successfully started or resumed the Primary Service Discovery procedure.
+ * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid Connection Handle.
+ * @retval ::NRF_ERROR_INVALID_STATE Invalid Connection State.
+ * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied.
+ * @retval ::NRF_ERROR_BUSY Client procedure already in progress.
+ * @retval ::NRF_ERROR_TIMEOUT There has been a GATT procedure timeout. No new GATT procedure can be performed without reestablishing the connection.
+ */
+SVCALL(SD_BLE_GATTC_PRIMARY_SERVICES_DISCOVER, uint32_t, sd_ble_gattc_primary_services_discover(uint16_t conn_handle, uint16_t start_handle, ble_uuid_t const *p_srvc_uuid));
+
+
+/**@brief Initiate or continue a GATT Relationship Discovery procedure.
+ *
+ * @details This function initiates or resumes the Find Included Services sub-procedure. If the last included service has not been reached,
+ * this must be called again with an updated handle range to continue the search.
+ *
+ * @events
+ * @event{@ref BLE_GATTC_EVT_REL_DISC_RSP}
+ * @endevents
+ *
+ * @mscs
+ * @mmsc{@ref BLE_GATTC_REL_DISC_MSC}
+ * @endmscs
+ *
+ * @param[in] conn_handle The connection handle identifying the connection to perform this procedure on.
+ * @param[in] p_handle_range A pointer to the range of handles of the Service to perform this procedure on.
+ *
+ * @retval ::NRF_SUCCESS Successfully started or resumed the Relationship Discovery procedure.
+ * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid Connection Handle.
+ * @retval ::NRF_ERROR_INVALID_STATE Invalid Connection State.
+ * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied.
+ * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied.
+ * @retval ::NRF_ERROR_BUSY Client procedure already in progress.
+ * @retval ::NRF_ERROR_TIMEOUT There has been a GATT procedure timeout. No new GATT procedure can be performed without reestablishing the connection.
+ */
+SVCALL(SD_BLE_GATTC_RELATIONSHIPS_DISCOVER, uint32_t, sd_ble_gattc_relationships_discover(uint16_t conn_handle, ble_gattc_handle_range_t const *p_handle_range));
+
+
+/**@brief Initiate or continue a GATT Characteristic Discovery procedure.
+ *
+ * @details This function initiates or resumes a Characteristic discovery procedure. If the last Characteristic has not been reached,
+ * this must be called again with an updated handle range to continue the discovery.
+ *
+ * @note If any of the discovered characteristics have 128-bit UUIDs which are not present in the table provided to ble_vs_uuids_assign, a UUID structure with
+ * type @ref BLE_UUID_TYPE_UNKNOWN will be received in the corresponding event.
+ *
+ * @events
+ * @event{@ref BLE_GATTC_EVT_CHAR_DISC_RSP}
+ * @endevents
+ *
+ * @mscs
+ * @mmsc{@ref BLE_GATTC_CHAR_DISC_MSC}
+ * @endmscs
+ *
+ * @param[in] conn_handle The connection handle identifying the connection to perform this procedure on.
+ * @param[in] p_handle_range A pointer to the range of handles of the Service to perform this procedure on.
+ *
+ * @retval ::NRF_SUCCESS Successfully started or resumed the Characteristic Discovery procedure.
+ * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid Connection Handle.
+ * @retval ::NRF_ERROR_INVALID_STATE Invalid Connection State.
+ * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied.
+ * @retval ::NRF_ERROR_BUSY Client procedure already in progress.
+ * @retval ::NRF_ERROR_TIMEOUT There has been a GATT procedure timeout. No new GATT procedure can be performed without reestablishing the connection.
+ */
+SVCALL(SD_BLE_GATTC_CHARACTERISTICS_DISCOVER, uint32_t, sd_ble_gattc_characteristics_discover(uint16_t conn_handle, ble_gattc_handle_range_t const *p_handle_range));
+
+
+/**@brief Initiate or continue a GATT Characteristic Descriptor Discovery procedure.
+ *
+ * @details This function initiates or resumes a Characteristic Descriptor discovery procedure. If the last Descriptor has not been reached,
+ * this must be called again with an updated handle range to continue the discovery.
+ *
+ * @events
+ * @event{@ref BLE_GATTC_EVT_DESC_DISC_RSP}
+ * @endevents
+ *
+ * @mscs
+ * @mmsc{@ref BLE_GATTC_DESC_DISC_MSC}
+ * @endmscs
+ *
+ * @param[in] conn_handle The connection handle identifying the connection to perform this procedure on.
+ * @param[in] p_handle_range A pointer to the range of handles of the Characteristic to perform this procedure on.
+ *
+ * @retval ::NRF_SUCCESS Successfully started or resumed the Descriptor Discovery procedure.
+ * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid Connection Handle.
+ * @retval ::NRF_ERROR_INVALID_STATE Invalid Connection State.
+ * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied.
+ * @retval ::NRF_ERROR_BUSY Client procedure already in progress.
+ * @retval ::NRF_ERROR_TIMEOUT There has been a GATT procedure timeout. No new GATT procedure can be performed without reestablishing the connection.
+ */
+SVCALL(SD_BLE_GATTC_DESCRIPTORS_DISCOVER, uint32_t, sd_ble_gattc_descriptors_discover(uint16_t conn_handle, ble_gattc_handle_range_t const *p_handle_range));
+
+
+/**@brief Initiate or continue a GATT Read using Characteristic UUID procedure.
+ *
+ * @details This function initiates or resumes a Read using Characteristic UUID procedure. If the last Characteristic has not been reached,
+ * this must be called again with an updated handle range to continue the discovery.
+ *
+ * @events
+ * @event{@ref BLE_GATTC_EVT_CHAR_VAL_BY_UUID_READ_RSP}
+ * @endevents
+ *
+ * @mscs
+ * @mmsc{@ref BLE_GATTC_READ_UUID_MSC}
+ * @endmscs
+ *
+ * @param[in] conn_handle The connection handle identifying the connection to perform this procedure on.
+ * @param[in] p_uuid Pointer to a Characteristic value UUID to read.
+ * @param[in] p_handle_range A pointer to the range of handles to perform this procedure on.
+ *
+ * @retval ::NRF_SUCCESS Successfully started or resumed the Read using Characteristic UUID procedure.
+ * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid Connection Handle.
+ * @retval ::NRF_ERROR_INVALID_STATE Invalid Connection State.
+ * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied.
+ * @retval ::NRF_ERROR_BUSY Client procedure already in progress.
+ * @retval ::NRF_ERROR_TIMEOUT There has been a GATT procedure timeout. No new GATT procedure can be performed without reestablishing the connection.
+ */
+SVCALL(SD_BLE_GATTC_CHAR_VALUE_BY_UUID_READ, uint32_t, sd_ble_gattc_char_value_by_uuid_read(uint16_t conn_handle, ble_uuid_t const *p_uuid, ble_gattc_handle_range_t const *p_handle_range));
+
+
+/**@brief Initiate or continue a GATT Read (Long) Characteristic or Descriptor procedure.
+ *
+ * @details This function initiates or resumes a GATT Read (Long) Characteristic or Descriptor procedure. If the Characteristic or Descriptor
+ * to be read is longer than ATT_MTU - 1, this function must be called multiple times with appropriate offset to read the
+ * complete value.
+ *
+ * @events
+ * @event{@ref BLE_GATTC_EVT_READ_RSP}
+ * @endevents
+ *
+ * @mscs
+ * @mmsc{@ref BLE_GATTC_VALUE_READ_MSC}
+ * @endmscs
+ *
+ * @param[in] conn_handle The connection handle identifying the connection to perform this procedure on.
+ * @param[in] handle The handle of the attribute to be read.
+ * @param[in] offset Offset into the attribute value to be read.
+ *
+ * @retval ::NRF_SUCCESS Successfully started or resumed the Read (Long) procedure.
+ * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid Connection Handle.
+ * @retval ::NRF_ERROR_INVALID_STATE Invalid Connection State.
+ * @retval ::NRF_ERROR_BUSY Client procedure already in progress.
+ * @retval ::NRF_ERROR_TIMEOUT There has been a GATT procedure timeout. No new GATT procedure can be performed without reestablishing the connection.
+ */
+SVCALL(SD_BLE_GATTC_READ, uint32_t, sd_ble_gattc_read(uint16_t conn_handle, uint16_t handle, uint16_t offset));
+
+
+/**@brief Initiate a GATT Read Multiple Characteristic Values procedure.
+ *
+ * @details This function initiates a GATT Read Multiple Characteristic Values procedure.
+ *
+ * @events
+ * @event{@ref BLE_GATTC_EVT_CHAR_VALS_READ_RSP}
+ * @endevents
+ *
+ * @mscs
+ * @mmsc{@ref BLE_GATTC_READ_MULT_MSC}
+ * @endmscs
+ *
+ * @param[in] conn_handle The connection handle identifying the connection to perform this procedure on.
+ * @param[in] p_handles A pointer to the handle(s) of the attribute(s) to be read.
+ * @param[in] handle_count The number of handles in p_handles.
+ *
+ * @retval ::NRF_SUCCESS Successfully started the Read Multiple Characteristic Values procedure.
+ * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid Connection Handle.
+ * @retval ::NRF_ERROR_INVALID_STATE Invalid Connection State.
+ * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied.
+ * @retval ::NRF_ERROR_BUSY Client procedure already in progress.
+ * @retval ::NRF_ERROR_TIMEOUT There has been a GATT procedure timeout. No new GATT procedure can be performed without reestablishing the connection.
+ */
+SVCALL(SD_BLE_GATTC_CHAR_VALUES_READ, uint32_t, sd_ble_gattc_char_values_read(uint16_t conn_handle, uint16_t const *p_handles, uint16_t handle_count));
+
+
+/**@brief Perform a Write (Characteristic Value or Descriptor, with or without response, signed or not, long or reliable) procedure.
+ *
+ * @details This function can perform all write procedures described in GATT.
+ *
+ * @note Only one write with response procedure can be ongoing per connection at a time.
+ * If the application tries to write with response while another write with response procedure is ongoing,
+ * the function call will return @ref NRF_ERROR_BUSY.
+ * A @ref BLE_GATTC_EVT_WRITE_RSP event will be issued as soon as the write response arrives from the peer.
+ *
+ * @note The number of Write without Response that can be queued is configured by @ref ble_gattc_conn_cfg_t::write_cmd_tx_queue_size
+ * When the queue is full, the function call will return @ref NRF_ERROR_RESOURCES.
+ * A @ref BLE_GATTC_EVT_WRITE_CMD_TX_COMPLETE event will be issued as soon as the transmission of the write without response is complete.
+ *
+ * @note The application can keep track of the available queue element count for writes without responses by following the procedure below:
+ * - Store initial queue element count in a variable.
+ * - Decrement the variable, which stores the currently available queue element count, by one when a call to this function returns @ref NRF_SUCCESS.
+ * - Increment the variable, which stores the current available queue element count, by the count variable in @ref BLE_GATTC_EVT_WRITE_CMD_TX_COMPLETE event.
+ *
+ * @events
+ * @event{@ref BLE_GATTC_EVT_WRITE_CMD_TX_COMPLETE, Write without response transmission complete.}
+ * @event{@ref BLE_GATTC_EVT_WRITE_RSP, Write response received from the peer.}
+ * @endevents
+ *
+ * @mscs
+ * @mmsc{@ref BLE_GATTC_VALUE_WRITE_WITHOUT_RESP_MSC}
+ * @mmsc{@ref BLE_GATTC_VALUE_WRITE_MSC}
+ * @mmsc{@ref BLE_GATTC_VALUE_LONG_WRITE_MSC}
+ * @mmsc{@ref BLE_GATTC_VALUE_RELIABLE_WRITE_MSC}
+ * @endmscs
+ *
+ * @param[in] conn_handle The connection handle identifying the connection to perform this procedure on.
+ * @param[in] p_write_params A pointer to a write parameters structure.
+ *
+ * @retval ::NRF_SUCCESS Successfully started the Write procedure.
+ * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid Connection Handle.
+ * @retval ::NRF_ERROR_INVALID_STATE Invalid Connection State.
+ * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied.
+ * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied.
+ * @retval ::NRF_ERROR_DATA_SIZE Invalid data size(s) supplied.
+ * @retval ::NRF_ERROR_BUSY For write with response, procedure already in progress. Wait for a @ref BLE_GATTC_EVT_WRITE_RSP event and retry.
+ * @retval ::NRF_ERROR_RESOURCES Too many writes without responses queued.
+ * Wait for a @ref BLE_GATTC_EVT_WRITE_CMD_TX_COMPLETE event and retry.
+ * @retval ::NRF_ERROR_TIMEOUT There has been a GATT procedure timeout. No new GATT procedure can be performed without reestablishing the connection.
+ */
+SVCALL(SD_BLE_GATTC_WRITE, uint32_t, sd_ble_gattc_write(uint16_t conn_handle, ble_gattc_write_params_t const *p_write_params));
+
+
+/**@brief Send a Handle Value Confirmation to the GATT Server.
+ *
+ * @mscs
+ * @mmsc{@ref BLE_GATTC_HVI_MSC}
+ * @endmscs
+ *
+ * @param[in] conn_handle The connection handle identifying the connection to perform this procedure on.
+ * @param[in] handle The handle of the attribute in the indication.
+ *
+ * @retval ::NRF_SUCCESS Successfully queued the Handle Value Confirmation for transmission.
+ * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid Connection Handle.
+ * @retval ::NRF_ERROR_INVALID_STATE Invalid Connection State or no Indication pending to be confirmed.
+ * @retval ::BLE_ERROR_INVALID_ATTR_HANDLE Invalid attribute handle.
+ * @retval ::NRF_ERROR_TIMEOUT There has been a GATT procedure timeout. No new GATT procedure can be performed without reestablishing the connection.
+ */
+SVCALL(SD_BLE_GATTC_HV_CONFIRM, uint32_t, sd_ble_gattc_hv_confirm(uint16_t conn_handle, uint16_t handle));
+
+/**@brief Discovers information about a range of attributes on a GATT server.
+ *
+ * @events
+ * @event{@ref BLE_GATTC_EVT_ATTR_INFO_DISC_RSP, Generated when information about a range of attributes has been received.}
+ * @endevents
+ *
+ * @param[in] conn_handle The connection handle identifying the connection to perform this procedure on.
+ * @param[in] p_handle_range The range of handles to request information about.
+ *
+ * @retval ::NRF_SUCCESS Successfully started an attribute information discovery procedure.
+ * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid connection handle.
+ * @retval ::NRF_ERROR_INVALID_STATE Invalid connection state
+ * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied.
+ * @retval ::NRF_ERROR_BUSY Client procedure already in progress.
+ * @retval ::NRF_ERROR_TIMEOUT There has been a GATT procedure timeout. No new GATT procedure can be performed without reestablishing the connection.
+ */
+SVCALL(SD_BLE_GATTC_ATTR_INFO_DISCOVER, uint32_t, sd_ble_gattc_attr_info_discover(uint16_t conn_handle, ble_gattc_handle_range_t const * p_handle_range));
+
+/**@brief Start an ATT_MTU exchange by sending an Exchange MTU Request to the server.
+ *
+ * @details The SoftDevice sets ATT_MTU to the minimum of:
+ * - The Client RX MTU value, and
+ * - The Server RX MTU value from @ref BLE_GATTC_EVT_EXCHANGE_MTU_RSP.
+ *
+ * However, the SoftDevice never sets ATT_MTU lower than @ref BLE_GATT_ATT_MTU_DEFAULT.
+ *
+ * @events
+ * @event{@ref BLE_GATTC_EVT_EXCHANGE_MTU_RSP}
+ * @endevents
+ *
+ * @mscs
+ * @mmsc{@ref BLE_GATTC_MTU_EXCHANGE}
+ * @endmscs
+ *
+ * @param[in] conn_handle The connection handle identifying the connection to perform this procedure on.
+ * @param[in] client_rx_mtu Client RX MTU size.
+ * - The minimum value is @ref BLE_GATT_ATT_MTU_DEFAULT.
+ * - The maximum value is @ref ble_gatt_conn_cfg_t::att_mtu in the connection configuration
+ used for this connection.
+ * - The value must be equal to Server RX MTU size given in @ref sd_ble_gatts_exchange_mtu_reply
+ * if an ATT_MTU exchange has already been performed in the other direction.
+ *
+ * @retval ::NRF_SUCCESS Successfully sent request to the server.
+ * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid connection handle.
+ * @retval ::NRF_ERROR_INVALID_STATE Invalid connection state or an ATT_MTU exchange was already requested once.
+ * @retval ::NRF_ERROR_INVALID_PARAM Invalid Client RX MTU size supplied.
+ * @retval ::NRF_ERROR_BUSY Client procedure already in progress.
+ * @retval ::NRF_ERROR_TIMEOUT There has been a GATT procedure timeout. No new GATT procedure can be performed without reestablishing the connection.
+ */
+SVCALL(SD_BLE_GATTC_EXCHANGE_MTU_REQUEST, uint32_t, sd_ble_gattc_exchange_mtu_request(uint16_t conn_handle, uint16_t client_rx_mtu));
+
+/**@brief Iterate through Handle-Value(s) list in @ref BLE_GATTC_EVT_CHAR_VAL_BY_UUID_READ_RSP event.
+ *
+ * @param[in] p_gattc_evt Pointer to event buffer containing @ref BLE_GATTC_EVT_CHAR_VAL_BY_UUID_READ_RSP event.
+ * @note If the buffer contains different event, behavior is undefined.
+ * @param[in,out] p_iter Iterator, points to @ref ble_gattc_handle_value_t structure that will be filled in with
+ * the next Handle-Value pair in each iteration. If the function returns other than
+ * @ref NRF_SUCCESS, it will not be changed.
+ * - To start iteration, initialize the structure to zero.
+ * - To continue, pass the value from previous iteration.
+ *
+ * \code
+ * ble_gattc_handle_value_t iter;
+ * memset(&iter, 0, sizeof(ble_gattc_handle_value_t));
+ * while (sd_ble_gattc_evt_char_val_by_uuid_read_rsp_iter(&ble_evt.evt.gattc_evt, &iter) == NRF_SUCCESS)
+ * {
+ * app_handle = iter.handle;
+ * memcpy(app_value, iter.p_value, ble_evt.evt.gattc_evt.params.char_val_by_uuid_read_rsp.value_len);
+ * }
+ * \endcode
+ *
+ * @retval ::NRF_SUCCESS Successfully retrieved the next Handle-Value pair.
+ * @retval ::NRF_ERROR_NOT_FOUND No more Handle-Value pairs available in the list.
+ */
+__STATIC_INLINE uint32_t sd_ble_gattc_evt_char_val_by_uuid_read_rsp_iter(ble_gattc_evt_t *p_gattc_evt, ble_gattc_handle_value_t *p_iter);
+
+/** @} */
+
+#ifndef SUPPRESS_INLINE_IMPLEMENTATION
+
+__STATIC_INLINE uint32_t sd_ble_gattc_evt_char_val_by_uuid_read_rsp_iter(ble_gattc_evt_t *p_gattc_evt, ble_gattc_handle_value_t *p_iter)
+{
+ uint32_t value_len = p_gattc_evt->params.char_val_by_uuid_read_rsp.value_len;
+ uint8_t *p_first = p_gattc_evt->params.char_val_by_uuid_read_rsp.handle_value;
+ uint8_t *p_next = p_iter->p_value ? p_iter->p_value + value_len : p_first;
+
+ if ((p_next - p_first) / (sizeof(uint16_t) + value_len) < p_gattc_evt->params.char_val_by_uuid_read_rsp.count)
+ {
+ p_iter->handle = (uint16_t)p_next[1] << 8 | p_next[0];
+ p_iter->p_value = p_next + sizeof(uint16_t);
+ return NRF_SUCCESS;
+ }
+ else
+ {
+ return NRF_ERROR_NOT_FOUND;
+ }
+}
+
+#endif /* SUPPRESS_INLINE_IMPLEMENTATION */
+
+#ifdef __cplusplus
+}
+#endif
+#endif /* BLE_GATTC_H__ */
+
+/**
+ @}
+*/
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/softdevice/s132/headers/ble_gatts.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/softdevice/s132/headers/ble_gatts.h
new file mode 100644
index 0000000..e437b6e
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/softdevice/s132/headers/ble_gatts.h
@@ -0,0 +1,845 @@
+/*
+ * Copyright (c) 2011 - 2017, 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ */
+
+/**
+ @addtogroup BLE_GATTS Generic Attribute Profile (GATT) Server
+ @{
+ @brief Definitions and prototypes for the GATTS interface.
+ */
+
+#ifndef BLE_GATTS_H__
+#define BLE_GATTS_H__
+
+#include <stdint.h>
+#include "nrf_svc.h"
+#include "nrf_error.h"
+#include "ble_hci.h"
+#include "ble_ranges.h"
+#include "ble_types.h"
+#include "ble_err.h"
+#include "ble_gatt.h"
+#include "ble_gap.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** @addtogroup BLE_GATTS_ENUMERATIONS Enumerations
+ * @{ */
+
+/**
+ * @brief GATTS API SVC numbers.
+ */
+enum BLE_GATTS_SVCS
+{
+ SD_BLE_GATTS_SERVICE_ADD = BLE_GATTS_SVC_BASE, /**< Add a service. */
+ SD_BLE_GATTS_INCLUDE_ADD, /**< Add an included service. */
+ SD_BLE_GATTS_CHARACTERISTIC_ADD, /**< Add a characteristic. */
+ SD_BLE_GATTS_DESCRIPTOR_ADD, /**< Add a generic attribute. */
+ SD_BLE_GATTS_VALUE_SET, /**< Set an attribute value. */
+ SD_BLE_GATTS_VALUE_GET, /**< Get an attribute value. */
+ SD_BLE_GATTS_HVX, /**< Handle Value Notification or Indication. */
+ SD_BLE_GATTS_SERVICE_CHANGED, /**< Perform a Service Changed Indication to one or more peers. */
+ SD_BLE_GATTS_RW_AUTHORIZE_REPLY, /**< Reply to an authorization request for a read or write operation on one or more attributes. */
+ SD_BLE_GATTS_SYS_ATTR_SET, /**< Set the persistent system attributes for a connection. */
+ SD_BLE_GATTS_SYS_ATTR_GET, /**< Retrieve the persistent system attributes. */
+ SD_BLE_GATTS_INITIAL_USER_HANDLE_GET, /**< Retrieve the first valid user handle. */
+ SD_BLE_GATTS_ATTR_GET, /**< Retrieve the UUID and/or metadata of an attribute. */
+ SD_BLE_GATTS_EXCHANGE_MTU_REPLY /**< Reply to Exchange MTU Request. */
+};
+
+/**
+ * @brief GATT Server Event IDs.
+ */
+enum BLE_GATTS_EVTS
+{
+ BLE_GATTS_EVT_WRITE = BLE_GATTS_EVT_BASE, /**< Write operation performed. \n See @ref ble_gatts_evt_write_t. */
+ BLE_GATTS_EVT_RW_AUTHORIZE_REQUEST, /**< Read/Write Authorization request. \n Reply with @ref sd_ble_gatts_rw_authorize_reply. \n See @ref ble_gatts_evt_rw_authorize_request_t. */
+ BLE_GATTS_EVT_SYS_ATTR_MISSING, /**< A persistent system attribute access is pending. \n Respond with @ref sd_ble_gatts_sys_attr_set. \n See @ref ble_gatts_evt_sys_attr_missing_t. */
+ BLE_GATTS_EVT_HVC, /**< Handle Value Confirmation. \n See @ref ble_gatts_evt_hvc_t. */
+ BLE_GATTS_EVT_SC_CONFIRM, /**< Service Changed Confirmation. \n No additional event structure applies. */
+ BLE_GATTS_EVT_EXCHANGE_MTU_REQUEST, /**< Exchange MTU Request. \n Reply with @ref sd_ble_gatts_exchange_mtu_reply. \n See @ref ble_gatts_evt_exchange_mtu_request_t. */
+ BLE_GATTS_EVT_TIMEOUT, /**< Peer failed to respond to an ATT request in time. \n See @ref ble_gatts_evt_timeout_t. */
+ BLE_GATTS_EVT_HVN_TX_COMPLETE /**< Handle Value Notification transmission complete. \n See @ref ble_gatts_evt_hvn_tx_complete_t. */
+};
+
+/**@brief GATTS Configuration IDs.
+ *
+ * IDs that uniquely identify a GATTS configuration.
+ */
+enum BLE_GATTS_CFGS
+{
+ BLE_GATTS_CFG_SERVICE_CHANGED = BLE_GATTS_CFG_BASE, /**< Service changed configuration. */
+ BLE_GATTS_CFG_ATTR_TAB_SIZE, /**< Attribute table size configuration. */
+};
+
+/** @} */
+
+/** @addtogroup BLE_GATTS_DEFINES Defines
+ * @{ */
+
+/** @defgroup BLE_ERRORS_GATTS SVC return values specific to GATTS
+ * @{ */
+#define BLE_ERROR_GATTS_INVALID_ATTR_TYPE (NRF_GATTS_ERR_BASE + 0x000) /**< Invalid attribute type. */
+#define BLE_ERROR_GATTS_SYS_ATTR_MISSING (NRF_GATTS_ERR_BASE + 0x001) /**< System Attributes missing. */
+/** @} */
+
+/** @defgroup BLE_GATTS_ATTR_LENS_MAX Maximum attribute lengths
+ * @{ */
+#define BLE_GATTS_FIX_ATTR_LEN_MAX (510) /**< Maximum length for fixed length Attribute Values. */
+#define BLE_GATTS_VAR_ATTR_LEN_MAX (512) /**< Maximum length for variable length Attribute Values. */
+/** @} */
+
+/** @defgroup BLE_GATTS_SRVC_TYPES GATT Server Service Types
+ * @{ */
+#define BLE_GATTS_SRVC_TYPE_INVALID 0x00 /**< Invalid Service Type. */
+#define BLE_GATTS_SRVC_TYPE_PRIMARY 0x01 /**< Primary Service. */
+#define BLE_GATTS_SRVC_TYPE_SECONDARY 0x02 /**< Secondary Type. */
+/** @} */
+
+
+/** @defgroup BLE_GATTS_ATTR_TYPES GATT Server Attribute Types
+ * @{ */
+#define BLE_GATTS_ATTR_TYPE_INVALID 0x00 /**< Invalid Attribute Type. */
+#define BLE_GATTS_ATTR_TYPE_PRIM_SRVC_DECL 0x01 /**< Primary Service Declaration. */
+#define BLE_GATTS_ATTR_TYPE_SEC_SRVC_DECL 0x02 /**< Secondary Service Declaration. */
+#define BLE_GATTS_ATTR_TYPE_INC_DECL 0x03 /**< Include Declaration. */
+#define BLE_GATTS_ATTR_TYPE_CHAR_DECL 0x04 /**< Characteristic Declaration. */
+#define BLE_GATTS_ATTR_TYPE_CHAR_VAL 0x05 /**< Characteristic Value. */
+#define BLE_GATTS_ATTR_TYPE_DESC 0x06 /**< Descriptor. */
+#define BLE_GATTS_ATTR_TYPE_OTHER 0x07 /**< Other, non-GATT specific type. */
+/** @} */
+
+
+/** @defgroup BLE_GATTS_OPS GATT Server Operations
+ * @{ */
+#define BLE_GATTS_OP_INVALID 0x00 /**< Invalid Operation. */
+#define BLE_GATTS_OP_WRITE_REQ 0x01 /**< Write Request. */
+#define BLE_GATTS_OP_WRITE_CMD 0x02 /**< Write Command. */
+#define BLE_GATTS_OP_SIGN_WRITE_CMD 0x03 /**< Signed Write Command. */
+#define BLE_GATTS_OP_PREP_WRITE_REQ 0x04 /**< Prepare Write Request. */
+#define BLE_GATTS_OP_EXEC_WRITE_REQ_CANCEL 0x05 /**< Execute Write Request: Cancel all prepared writes. */
+#define BLE_GATTS_OP_EXEC_WRITE_REQ_NOW 0x06 /**< Execute Write Request: Immediately execute all prepared writes. */
+/** @} */
+
+/** @defgroup BLE_GATTS_VLOCS GATT Value Locations
+ * @{ */
+#define BLE_GATTS_VLOC_INVALID 0x00 /**< Invalid Location. */
+#define BLE_GATTS_VLOC_STACK 0x01 /**< Attribute Value is located in stack memory, no user memory is required. */
+#define BLE_GATTS_VLOC_USER 0x02 /**< Attribute Value is located in user memory. This requires the user to maintain a valid buffer through the lifetime of the attribute, since the stack
+ will read and write directly to the memory using the pointer provided in the APIs. There are no alignment requirements for the buffer. */
+/** @} */
+
+/** @defgroup BLE_GATTS_AUTHORIZE_TYPES GATT Server Authorization Types
+ * @{ */
+#define BLE_GATTS_AUTHORIZE_TYPE_INVALID 0x00 /**< Invalid Type. */
+#define BLE_GATTS_AUTHORIZE_TYPE_READ 0x01 /**< Authorize a Read Operation. */
+#define BLE_GATTS_AUTHORIZE_TYPE_WRITE 0x02 /**< Authorize a Write Request Operation. */
+/** @} */
+
+/** @defgroup BLE_GATTS_SYS_ATTR_FLAGS System Attribute Flags
+ * @{ */
+#define BLE_GATTS_SYS_ATTR_FLAG_SYS_SRVCS (1 << 0) /**< Restrict system attributes to system services only. */
+#define BLE_GATTS_SYS_ATTR_FLAG_USR_SRVCS (1 << 1) /**< Restrict system attributes to user services only. */
+/** @} */
+
+/** @defgroup BLE_GATTS_SERVICE_CHANGED Service Changed Inclusion Values
+ * @{
+ */
+#define BLE_GATTS_SERVICE_CHANGED_DEFAULT (1) /**< Default is to include the Service Changed characteristic in the Attribute Table. */
+/** @} */
+
+/** @defgroup BLE_GATTS_ATTR_TAB_SIZE Attribute Table size
+ * @{
+ */
+#define BLE_GATTS_ATTR_TAB_SIZE_MIN (248) /**< Minimum Attribute Table size */
+#define BLE_GATTS_ATTR_TAB_SIZE_DEFAULT (1408) /**< Default Attribute Table size. */
+/** @} */
+
+/** @defgroup BLE_GATTS_DEFAULTS GATT Server defaults
+ * @{
+ */
+#define BLE_GATTS_HVN_TX_QUEUE_SIZE_DEFAULT 1 /**< Default number of Handle Value Notifications that can be queued for transmission. */
+/** @} */
+
+/** @} */
+
+/** @addtogroup BLE_GATTS_STRUCTURES Structures
+ * @{ */
+
+/**
+ * @brief BLE GATTS connection configuration parameters, set with @ref sd_ble_cfg_set.
+ */
+typedef struct
+{
+ uint8_t hvn_tx_queue_size; /**< Minimum guaranteed number of Handle Value Notifications that can be queued for transmission.
+ The default value is @ref BLE_GATTS_HVN_TX_QUEUE_SIZE_DEFAULT */
+} ble_gatts_conn_cfg_t;
+
+/**@brief Attribute metadata. */
+typedef struct
+{
+ ble_gap_conn_sec_mode_t read_perm; /**< Read permissions. */
+ ble_gap_conn_sec_mode_t write_perm; /**< Write permissions. */
+ uint8_t vlen :1; /**< Variable length attribute. */
+ uint8_t vloc :2; /**< Value location, see @ref BLE_GATTS_VLOCS.*/
+ uint8_t rd_auth :1; /**< Read authorization and value will be requested from the application on every read operation. */
+ uint8_t wr_auth :1; /**< Write authorization will be requested from the application on every Write Request operation (but not Write Command). */
+} ble_gatts_attr_md_t;
+
+
+/**@brief GATT Attribute. */
+typedef struct
+{
+ ble_uuid_t const *p_uuid; /**< Pointer to the attribute UUID. */
+ ble_gatts_attr_md_t const *p_attr_md; /**< Pointer to the attribute metadata structure. */
+ uint16_t init_len; /**< Initial attribute value length in bytes. */
+ uint16_t init_offs; /**< Initial attribute value offset in bytes. If different from zero, the first init_offs bytes of the attribute value will be left uninitialized. */
+ uint16_t max_len; /**< Maximum attribute value length in bytes, see @ref BLE_GATTS_ATTR_LENS_MAX for maximum values. */
+ uint8_t *p_value; /**< Pointer to the attribute data. Please note that if the @ref BLE_GATTS_VLOC_USER value location is selected in the attribute metadata, this will have to point to a buffer
+ that remains valid through the lifetime of the attribute. This excludes usage of automatic variables that may go out of scope or any other temporary location.
+ The stack may access that memory directly without the application's knowledge. For writable characteristics, this value must not be a location in flash memory.*/
+} ble_gatts_attr_t;
+
+/**@brief GATT Attribute Value. */
+typedef struct
+{
+ uint16_t len; /**< Length in bytes to be written or read. Length in bytes written or read after successful return.*/
+ uint16_t offset; /**< Attribute value offset. */
+ uint8_t *p_value; /**< Pointer to where value is stored or will be stored.
+ If value is stored in user memory, only the attribute length is updated when p_value == NULL.
+ Set to NULL when reading to obtain the complete length of the attribute value */
+} ble_gatts_value_t;
+
+
+/**@brief GATT Characteristic Presentation Format. */
+typedef struct
+{
+ uint8_t format; /**< Format of the value, see @ref BLE_GATT_CPF_FORMATS. */
+ int8_t exponent; /**< Exponent for integer data types. */
+ uint16_t unit; /**< Unit from Bluetooth Assigned Numbers. */
+ uint8_t name_space; /**< Namespace from Bluetooth Assigned Numbers, see @ref BLE_GATT_CPF_NAMESPACES. */
+ uint16_t desc; /**< Namespace description from Bluetooth Assigned Numbers, see @ref BLE_GATT_CPF_NAMESPACES. */
+} ble_gatts_char_pf_t;
+
+
+/**@brief GATT Characteristic metadata. */
+typedef struct
+{
+ ble_gatt_char_props_t char_props; /**< Characteristic Properties. */
+ ble_gatt_char_ext_props_t char_ext_props; /**< Characteristic Extended Properties. */
+ uint8_t const *p_char_user_desc; /**< Pointer to a UTF-8 encoded string (non-NULL terminated), NULL if the descriptor is not required. */
+ uint16_t char_user_desc_max_size; /**< The maximum size in bytes of the user description descriptor. */
+ uint16_t char_user_desc_size; /**< The size of the user description, must be smaller or equal to char_user_desc_max_size. */
+ ble_gatts_char_pf_t const *p_char_pf; /**< Pointer to a presentation format structure or NULL if the CPF descriptor is not required. */
+ ble_gatts_attr_md_t const *p_user_desc_md; /**< Attribute metadata for the User Description descriptor, or NULL for default values. */
+ ble_gatts_attr_md_t const *p_cccd_md; /**< Attribute metadata for the Client Characteristic Configuration Descriptor, or NULL for default values. */
+ ble_gatts_attr_md_t const *p_sccd_md; /**< Attribute metadata for the Server Characteristic Configuration Descriptor, or NULL for default values. */
+} ble_gatts_char_md_t;
+
+
+/**@brief GATT Characteristic Definition Handles. */
+typedef struct
+{
+ uint16_t value_handle; /**< Handle to the characteristic value. */
+ uint16_t user_desc_handle; /**< Handle to the User Description descriptor, or @ref BLE_GATT_HANDLE_INVALID if not present. */
+ uint16_t cccd_handle; /**< Handle to the Client Characteristic Configuration Descriptor, or @ref BLE_GATT_HANDLE_INVALID if not present. */
+ uint16_t sccd_handle; /**< Handle to the Server Characteristic Configuration Descriptor, or @ref BLE_GATT_HANDLE_INVALID if not present. */
+} ble_gatts_char_handles_t;
+
+
+/**@brief GATT HVx parameters. */
+typedef struct
+{
+ uint16_t handle; /**< Characteristic Value Handle. */
+ uint8_t type; /**< Indication or Notification, see @ref BLE_GATT_HVX_TYPES. */
+ uint16_t offset; /**< Offset within the attribute value. */
+ uint16_t *p_len; /**< Length in bytes to be written, length in bytes written after return. */
+ uint8_t const *p_data; /**< Actual data content, use NULL to use the current attribute value. */
+} ble_gatts_hvx_params_t;
+
+/**@brief GATT Authorization parameters. */
+typedef struct
+{
+ uint16_t gatt_status; /**< GATT status code for the operation, see @ref BLE_GATT_STATUS_CODES. */
+ uint8_t update : 1; /**< If set, data supplied in p_data will be used to update the attribute value.
+ Please note that for @ref BLE_GATTS_AUTHORIZE_TYPE_WRITE operations this bit must always be set,
+ as the data to be written needs to be stored and later provided by the application. */
+ uint16_t offset; /**< Offset of the attribute value being updated. */
+ uint16_t len; /**< Length in bytes of the value in p_data pointer, see @ref BLE_GATTS_ATTR_LENS_MAX. */
+ uint8_t const *p_data; /**< Pointer to new value used to update the attribute value. */
+} ble_gatts_authorize_params_t;
+
+/**@brief GATT Read or Write Authorize Reply parameters. */
+typedef struct
+{
+ uint8_t type; /**< Type of authorize operation, see @ref BLE_GATTS_AUTHORIZE_TYPES. */
+ union {
+ ble_gatts_authorize_params_t read; /**< Read authorization parameters. */
+ ble_gatts_authorize_params_t write; /**< Write authorization parameters. */
+ } params; /**< Reply Parameters. */
+} ble_gatts_rw_authorize_reply_params_t;
+
+/**@brief Service Changed Inclusion configuration parameters, set with @ref sd_ble_cfg_set. */
+typedef struct
+{
+ uint8_t service_changed : 1; /**< If 1, include the Service Changed characteristic in the Attribute Table. Default is @ref BLE_GATTS_SERVICE_CHANGED_DEFAULT. */
+} ble_gatts_cfg_service_changed_t;
+
+/**@brief Attribute table size configuration parameters, set with @ref sd_ble_cfg_set.
+ *
+ * @retval ::NRF_ERROR_INVALID_LENGTH One or more of the following is true:
+ * - The specified Attribute Table size is too small.
+ * The minimum acceptable size is defined by @ref BLE_GATTS_ATTR_TAB_SIZE_MIN.
+ * - The specified Attribute Table size is not a multiple of 4.
+ */
+typedef struct
+{
+ uint32_t attr_tab_size; /**< Attribute table size. Default is @ref BLE_GATTS_ATTR_TAB_SIZE_DEFAULT, minimum is @ref BLE_GATTS_ATTR_TAB_SIZE_MIN. */
+} ble_gatts_cfg_attr_tab_size_t;
+
+/**@brief Config structure for GATTS configurations. */
+typedef union
+{
+ ble_gatts_cfg_service_changed_t service_changed; /**< Include service changed characteristic, cfg_id is @ref BLE_GATTS_CFG_SERVICE_CHANGED. */
+ ble_gatts_cfg_attr_tab_size_t attr_tab_size; /**< Attribute table size, cfg_id is @ref BLE_GATTS_CFG_ATTR_TAB_SIZE. */
+} ble_gatts_cfg_t;
+
+
+/**@brief Event structure for @ref BLE_GATTS_EVT_WRITE. */
+typedef struct
+{
+ uint16_t handle; /**< Attribute Handle. */
+ ble_uuid_t uuid; /**< Attribute UUID. */
+ uint8_t op; /**< Type of write operation, see @ref BLE_GATTS_OPS. */
+ uint8_t auth_required; /**< Writing operation deferred due to authorization requirement. Application may use @ref sd_ble_gatts_value_set to finalize the writing operation. */
+ uint16_t offset; /**< Offset for the write operation. */
+ uint16_t len; /**< Length of the received data. */
+ uint8_t data[1]; /**< Received data. @note This is a variable length array. The size of 1 indicated is only a placeholder for compilation.
+ See @ref sd_ble_evt_get for more information on how to use event structures with variable length array members. */
+} ble_gatts_evt_write_t;
+
+/**@brief Event substructure for authorized read requests, see @ref ble_gatts_evt_rw_authorize_request_t. */
+typedef struct
+{
+ uint16_t handle; /**< Attribute Handle. */
+ ble_uuid_t uuid; /**< Attribute UUID. */
+ uint16_t offset; /**< Offset for the read operation. */
+} ble_gatts_evt_read_t;
+
+/**@brief Event structure for @ref BLE_GATTS_EVT_RW_AUTHORIZE_REQUEST. */
+typedef struct
+{
+ uint8_t type; /**< Type of authorize operation, see @ref BLE_GATTS_AUTHORIZE_TYPES. */
+ union {
+ ble_gatts_evt_read_t read; /**< Attribute Read Parameters. */
+ ble_gatts_evt_write_t write; /**< Attribute Write Parameters. */
+ } request; /**< Request Parameters. */
+} ble_gatts_evt_rw_authorize_request_t;
+
+/**@brief Event structure for @ref BLE_GATTS_EVT_SYS_ATTR_MISSING. */
+typedef struct
+{
+ uint8_t hint; /**< Hint (currently unused). */
+} ble_gatts_evt_sys_attr_missing_t;
+
+
+/**@brief Event structure for @ref BLE_GATTS_EVT_HVC. */
+typedef struct
+{
+ uint16_t handle; /**< Attribute Handle. */
+} ble_gatts_evt_hvc_t;
+
+/**@brief Event structure for @ref BLE_GATTS_EVT_EXCHANGE_MTU_REQUEST. */
+typedef struct
+{
+ uint16_t client_rx_mtu; /**< Client RX MTU size. */
+} ble_gatts_evt_exchange_mtu_request_t;
+
+/**@brief Event structure for @ref BLE_GATTS_EVT_TIMEOUT. */
+typedef struct
+{
+ uint8_t src; /**< Timeout source, see @ref BLE_GATT_TIMEOUT_SOURCES. */
+} ble_gatts_evt_timeout_t;
+
+/**@brief Event structure for @ref BLE_GATTS_EVT_HVN_TX_COMPLETE. */
+typedef struct
+{
+ uint8_t count; /**< Number of notification transmissions completed. */
+} ble_gatts_evt_hvn_tx_complete_t;
+
+/**@brief GATTS event structure. */
+typedef struct
+{
+ uint16_t conn_handle; /**< Connection Handle on which the event occurred. */
+ union
+ {
+ ble_gatts_evt_write_t write; /**< Write Event Parameters. */
+ ble_gatts_evt_rw_authorize_request_t authorize_request; /**< Read or Write Authorize Request Parameters. */
+ ble_gatts_evt_sys_attr_missing_t sys_attr_missing; /**< System attributes missing. */
+ ble_gatts_evt_hvc_t hvc; /**< Handle Value Confirmation Event Parameters. */
+ ble_gatts_evt_exchange_mtu_request_t exchange_mtu_request; /**< Exchange MTU Request Event Parameters. */
+ ble_gatts_evt_timeout_t timeout; /**< Timeout Event. */
+ ble_gatts_evt_hvn_tx_complete_t hvn_tx_complete; /**< Handle Value Notification transmission complete Event Parameters. */
+ } params; /**< Event Parameters. */
+} ble_gatts_evt_t;
+
+/** @} */
+
+/** @addtogroup BLE_GATTS_FUNCTIONS Functions
+ * @{ */
+
+/**@brief Add a service declaration to the Attribute Table.
+ *
+ * @note Secondary Services are only relevant in the context of the entity that references them, it is therefore forbidden to
+ * add a secondary service declaration that is not referenced by another service later in the Attribute Table.
+ *
+ * @mscs
+ * @mmsc{@ref BLE_GATTS_ATT_TABLE_POP_MSC}
+ * @endmscs
+ *
+ * @param[in] type Toggles between primary and secondary services, see @ref BLE_GATTS_SRVC_TYPES.
+ * @param[in] p_uuid Pointer to service UUID.
+ * @param[out] p_handle Pointer to a 16-bit word where the assigned handle will be stored.
+ *
+ * @retval ::NRF_SUCCESS Successfully added a service declaration.
+ * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied.
+ * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied, Vendor Specific UUIDs need to be present in the table.
+ * @retval ::NRF_ERROR_FORBIDDEN Forbidden value supplied, certain UUIDs are reserved for the stack.
+ * @retval ::NRF_ERROR_NO_MEM Not enough memory to complete operation.
+ */
+SVCALL(SD_BLE_GATTS_SERVICE_ADD, uint32_t, sd_ble_gatts_service_add(uint8_t type, ble_uuid_t const *p_uuid, uint16_t *p_handle));
+
+
+/**@brief Add an include declaration to the Attribute Table.
+ *
+ * @note It is currently only possible to add an include declaration to the last added service (i.e. only sequential population is supported at this time).
+ *
+ * @note The included service must already be present in the Attribute Table prior to this call.
+ *
+ * @mscs
+ * @mmsc{@ref BLE_GATTS_ATT_TABLE_POP_MSC}
+ * @endmscs
+ *
+ * @param[in] service_handle Handle of the service where the included service is to be placed, if @ref BLE_GATT_HANDLE_INVALID is used, it will be placed sequentially.
+ * @param[in] inc_srvc_handle Handle of the included service.
+ * @param[out] p_include_handle Pointer to a 16-bit word where the assigned handle will be stored.
+ *
+ * @retval ::NRF_SUCCESS Successfully added an include declaration.
+ * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied.
+ * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied, handle values need to match previously added services.
+ * @retval ::NRF_ERROR_INVALID_STATE Invalid state to perform operation.
+ * @retval ::NRF_ERROR_NOT_SUPPORTED Feature is not supported, service_handle must be that of the last added service.
+ * @retval ::NRF_ERROR_FORBIDDEN Forbidden value supplied, self inclusions are not allowed.
+ * @retval ::NRF_ERROR_NO_MEM Not enough memory to complete operation.
+ * @retval ::NRF_ERROR_NOT_FOUND Attribute not found.
+ */
+SVCALL(SD_BLE_GATTS_INCLUDE_ADD, uint32_t, sd_ble_gatts_include_add(uint16_t service_handle, uint16_t inc_srvc_handle, uint16_t *p_include_handle));
+
+
+/**@brief Add a characteristic declaration, a characteristic value declaration and optional characteristic descriptor declarations to the Attribute Table.
+ *
+ * @note It is currently only possible to add a characteristic to the last added service (i.e. only sequential population is supported at this time).
+ *
+ * @note Several restrictions apply to the parameters, such as matching permissions between the user description descriptor and the writable auxiliaries bits,
+ * readable (no security) and writable (selectable) CCCDs and SCCDs and valid presentation format values.
+ *
+ * @note If no metadata is provided for the optional descriptors, their permissions will be derived from the characteristic permissions.
+ *
+ * @mscs
+ * @mmsc{@ref BLE_GATTS_ATT_TABLE_POP_MSC}
+ * @endmscs
+ *
+ * @param[in] service_handle Handle of the service where the characteristic is to be placed, if @ref BLE_GATT_HANDLE_INVALID is used, it will be placed sequentially.
+ * @param[in] p_char_md Characteristic metadata.
+ * @param[in] p_attr_char_value Pointer to the attribute structure corresponding to the characteristic value.
+ * @param[out] p_handles Pointer to the structure where the assigned handles will be stored.
+ *
+ * @retval ::NRF_SUCCESS Successfully added a characteristic.
+ * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied.
+ * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied, service handle, Vendor Specific UUIDs, lengths, and permissions need to adhere to the constraints.
+ * @retval ::NRF_ERROR_INVALID_STATE Invalid state to perform operation, a service context is required.
+ * @retval ::NRF_ERROR_FORBIDDEN Forbidden value supplied, certain UUIDs are reserved for the stack.
+ * @retval ::NRF_ERROR_NO_MEM Not enough memory to complete operation.
+ * @retval ::NRF_ERROR_DATA_SIZE Invalid data size(s) supplied, attribute lengths are restricted by @ref BLE_GATTS_ATTR_LENS_MAX.
+ */
+SVCALL(SD_BLE_GATTS_CHARACTERISTIC_ADD, uint32_t, sd_ble_gatts_characteristic_add(uint16_t service_handle, ble_gatts_char_md_t const *p_char_md, ble_gatts_attr_t const *p_attr_char_value, ble_gatts_char_handles_t *p_handles));
+
+
+/**@brief Add a descriptor to the Attribute Table.
+ *
+ * @note It is currently only possible to add a descriptor to the last added characteristic (i.e. only sequential population is supported at this time).
+ *
+ * @mscs
+ * @mmsc{@ref BLE_GATTS_ATT_TABLE_POP_MSC}
+ * @endmscs
+ *
+ * @param[in] char_handle Handle of the characteristic where the descriptor is to be placed, if @ref BLE_GATT_HANDLE_INVALID is used, it will be placed sequentially.
+ * @param[in] p_attr Pointer to the attribute structure.
+ * @param[out] p_handle Pointer to a 16-bit word where the assigned handle will be stored.
+ *
+ * @retval ::NRF_SUCCESS Successfully added a descriptor.
+ * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied.
+ * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied, characteristic handle, Vendor Specific UUIDs, lengths, and permissions need to adhere to the constraints.
+ * @retval ::NRF_ERROR_INVALID_STATE Invalid state to perform operation, a characteristic context is required.
+ * @retval ::NRF_ERROR_FORBIDDEN Forbidden value supplied, certain UUIDs are reserved for the stack.
+ * @retval ::NRF_ERROR_NO_MEM Not enough memory to complete operation.
+ * @retval ::NRF_ERROR_DATA_SIZE Invalid data size(s) supplied, attribute lengths are restricted by @ref BLE_GATTS_ATTR_LENS_MAX.
+ */
+SVCALL(SD_BLE_GATTS_DESCRIPTOR_ADD, uint32_t, sd_ble_gatts_descriptor_add(uint16_t char_handle, ble_gatts_attr_t const *p_attr, uint16_t *p_handle));
+
+/**@brief Set the value of a given attribute.
+ *
+ * @note Values other than system attributes can be set at any time, regardless of whether any active connections exist.
+ *
+ * @mscs
+ * @mmsc{@ref BLE_GATTS_QUEUED_WRITE_QUEUE_FULL_MSC}
+ * @mmsc{@ref BLE_GATTS_QUEUED_WRITE_NOBUF_NOAUTH_MSC}
+ * @endmscs
+ *
+ * @param[in] conn_handle Connection handle. Ignored if the value does not belong to a system attribute.
+ * @param[in] handle Attribute handle.
+ * @param[in,out] p_value Attribute value information.
+ *
+ * @retval ::NRF_SUCCESS Successfully set the value of the attribute.
+ * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied.
+ * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied.
+ * @retval ::NRF_ERROR_NOT_FOUND Attribute not found.
+ * @retval ::NRF_ERROR_FORBIDDEN Forbidden handle supplied, certain attributes are not modifiable by the application.
+ * @retval ::NRF_ERROR_DATA_SIZE Invalid data size(s) supplied, attribute lengths are restricted by @ref BLE_GATTS_ATTR_LENS_MAX.
+ * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid connection handle supplied on a system attribute.
+ */
+SVCALL(SD_BLE_GATTS_VALUE_SET, uint32_t, sd_ble_gatts_value_set(uint16_t conn_handle, uint16_t handle, ble_gatts_value_t *p_value));
+
+/**@brief Get the value of a given attribute.
+ *
+ * @note If the attribute value is longer than the size of the supplied buffer,
+ * @ref ble_gatts_value_t::len will return the total attribute value length (excluding offset),
+ * and not the number of bytes actually returned in @ref ble_gatts_value_t::p_value.
+ * The application may use this information to allocate a suitable buffer size.
+ *
+ * @note When retrieving system attribute values with this function, the connection handle
+ * may refer to an already disconnected connection. Refer to the documentation of
+ * @ref sd_ble_gatts_sys_attr_get for further information.
+ *
+ * @param[in] conn_handle Connection handle. Ignored if the value does not belong to a system attribute.
+ * @param[in] handle Attribute handle.
+ * @param[in,out] p_value Attribute value information.
+ *
+ * @retval ::NRF_SUCCESS Successfully retrieved the value of the attribute.
+ * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied.
+ * @retval ::NRF_ERROR_NOT_FOUND Attribute not found.
+ * @retval ::NRF_ERROR_INVALID_PARAM Invalid attribute offset supplied.
+ * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid connection handle supplied on a system attribute.
+ * @retval ::BLE_ERROR_GATTS_SYS_ATTR_MISSING System attributes missing, use @ref sd_ble_gatts_sys_attr_set to set them to a known value.
+ */
+SVCALL(SD_BLE_GATTS_VALUE_GET, uint32_t, sd_ble_gatts_value_get(uint16_t conn_handle, uint16_t handle, ble_gatts_value_t *p_value));
+
+/**@brief Notify or Indicate an attribute value.
+ *
+ * @details This function checks for the relevant Client Characteristic Configuration descriptor value to verify that the relevant operation
+ * (notification or indication) has been enabled by the client. It is also able to update the attribute value before issuing the PDU, so that
+ * the application can atomically perform a value update and a server initiated transaction with a single API call.
+ *
+ * @note The local attribute value may be updated even if an outgoing packet is not sent to the peer due to an error during execution.
+ * The Attribute Table has been updated if one of the following error codes is returned: @ref NRF_ERROR_INVALID_STATE, @ref NRF_ERROR_BUSY,
+ * @ref NRF_ERROR_FORBIDDEN, @ref BLE_ERROR_GATTS_SYS_ATTR_MISSING and @ref NRF_ERROR_RESOURCES.
+ * The caller can check whether the value has been updated by looking at the contents of *(@ref ble_gatts_hvx_params_t::p_len).
+ *
+ * @note Only one indication procedure can be ongoing per connection at a time.
+ * If the application tries to indicate an attribute value while another indication procedure is ongoing,
+ * the function call will return @ref NRF_ERROR_BUSY.
+ * A @ref BLE_GATTS_EVT_HVC event will be issued as soon as the confirmation arrives from the peer.
+ *
+ * @note The number of Handle Value Notifications that can be queued is configured by @ref ble_gatts_conn_cfg_t::hvn_tx_queue_size
+ * When the queue is full, the function call will return @ref NRF_ERROR_RESOURCES.
+ * A @ref BLE_GATTS_EVT_HVN_TX_COMPLETE event will be issued as soon as the transmission of the notification is complete.
+ *
+ * @note The application can keep track of the available queue element count for notifications by following the procedure below:
+ * - Store initial queue element count in a variable.
+ * - Decrement the variable, which stores the currently available queue element count, by one when a call to this function returns @ref NRF_SUCCESS.
+ * - Increment the variable, which stores the current available queue element count, by the count variable in @ref BLE_GATTS_EVT_HVN_TX_COMPLETE event.
+ *
+ * @events
+ * @event{@ref BLE_GATTS_EVT_HVN_TX_COMPLETE, Notification transmission complete.}
+ * @event{@ref BLE_GATTS_EVT_HVC, Confirmation received from the peer.}
+ * @endevents
+ *
+ * @mscs
+ * @mmsc{@ref BLE_GATTS_HVX_SYS_ATTRS_MISSING_MSC}
+ * @mmsc{@ref BLE_GATTS_HVN_MSC}
+ * @mmsc{@ref BLE_GATTS_HVI_MSC}
+ * @mmsc{@ref BLE_GATTS_HVX_DISABLED_MSC}
+ * @endmscs
+ *
+ * @param[in] conn_handle Connection handle.
+ * @param[in,out] p_hvx_params Pointer to an HVx parameters structure. If @ref ble_gatts_hvx_params_t::p_data
+ * contains a non-NULL pointer the attribute value will be updated with the contents
+ * pointed by it before sending the notification or indication. If the attribute value
+ * is updated, @ref ble_gatts_hvx_params_t::p_len is updated by the SoftDevice to
+ * contain the number of actual bytes written, else it will be set to 0.
+ *
+ * @retval ::NRF_SUCCESS Successfully queued a notification or indication for transmission, and optionally updated the attribute value.
+ * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid Connection Handle.
+ * @retval ::NRF_ERROR_INVALID_STATE One or more of the following is true:
+ * - Invalid Connection State
+ * - Notifications and/or indications not enabled in the CCCD
+ * - An ATT_MTU exchange is ongoing
+ * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied.
+ * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied.
+ * @retval ::BLE_ERROR_INVALID_ATTR_HANDLE Invalid attribute handle(s) supplied. Only attributes added directly by the application are available to notify and indicate.
+ * @retval ::BLE_ERROR_GATTS_INVALID_ATTR_TYPE Invalid attribute type(s) supplied, only characteristic values may be notified and indicated.
+ * @retval ::NRF_ERROR_NOT_FOUND Attribute not found.
+ * @retval ::NRF_ERROR_FORBIDDEN The connection's current security level is lower than the one required by the write permissions of the CCCD associated with this characteristic.
+ * @retval ::NRF_ERROR_DATA_SIZE Invalid data size(s) supplied.
+ * @retval ::NRF_ERROR_BUSY For @ref BLE_GATT_HVX_INDICATION Procedure already in progress. Wait for a @ref BLE_GATTS_EVT_HVC event and retry.
+ * @retval ::BLE_ERROR_GATTS_SYS_ATTR_MISSING System attributes missing, use @ref sd_ble_gatts_sys_attr_set to set them to a known value.
+ * @retval ::NRF_ERROR_RESOURCES Too many notifications queued.
+ * Wait for a @ref BLE_GATTS_EVT_HVN_TX_COMPLETE event and retry.
+ * @retval ::NRF_ERROR_TIMEOUT There has been a GATT procedure timeout. No new GATT procedure can be performed without reestablishing the connection.
+ */
+SVCALL(SD_BLE_GATTS_HVX, uint32_t, sd_ble_gatts_hvx(uint16_t conn_handle, ble_gatts_hvx_params_t const *p_hvx_params));
+
+/**@brief Indicate the Service Changed attribute value.
+ *
+ * @details This call will send a Handle Value Indication to one or more peers connected to inform them that the Attribute
+ * Table layout has changed. As soon as the peer has confirmed the indication, a @ref BLE_GATTS_EVT_SC_CONFIRM event will
+ * be issued.
+ *
+ * @note Some of the restrictions and limitations that apply to @ref sd_ble_gatts_hvx also apply here.
+ *
+ * @events
+ * @event{@ref BLE_GATTS_EVT_SC_CONFIRM, Confirmation of attribute table change received from peer.}
+ * @endevents
+ *
+ * @mscs
+ * @mmsc{@ref BLE_GATTS_SC_MSC}
+ * @endmscs
+ *
+ * @param[in] conn_handle Connection handle.
+ * @param[in] start_handle Start of affected attribute handle range.
+ * @param[in] end_handle End of affected attribute handle range.
+ *
+ * @retval ::NRF_SUCCESS Successfully queued the Service Changed indication for transmission.
+ * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid Connection Handle.
+ * @retval ::NRF_ERROR_NOT_SUPPORTED Service Changed not enabled at initialization. See @ref
+ * sd_ble_cfg_set and @ref ble_gatts_cfg_service_changed_t.
+ * @retval ::NRF_ERROR_INVALID_STATE One or more of the following is true:
+ * - Invalid Connection State
+ * - Notifications and/or indications not enabled in the CCCD
+ * - An ATT_MTU exchange is ongoing
+ * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied.
+ * @retval ::BLE_ERROR_INVALID_ATTR_HANDLE Invalid attribute handle(s) supplied, handles must be in the range populated by the application.
+ * @retval ::NRF_ERROR_BUSY Procedure already in progress.
+ * @retval ::BLE_ERROR_GATTS_SYS_ATTR_MISSING System attributes missing, use @ref sd_ble_gatts_sys_attr_set to set them to a known value.
+ * @retval ::NRF_ERROR_TIMEOUT There has been a GATT procedure timeout. No new GATT procedure can be performed without reestablishing the connection.
+ */
+SVCALL(SD_BLE_GATTS_SERVICE_CHANGED, uint32_t, sd_ble_gatts_service_changed(uint16_t conn_handle, uint16_t start_handle, uint16_t end_handle));
+
+/**@brief Respond to a Read/Write authorization request.
+ *
+ * @note This call should only be used as a response to a @ref BLE_GATTS_EVT_RW_AUTHORIZE_REQUEST event issued to the application.
+ *
+ * @mscs
+ * @mmsc{@ref BLE_GATTS_QUEUED_WRITE_NOBUF_AUTH_MSC}
+ * @mmsc{@ref BLE_GATTS_QUEUED_WRITE_BUF_AUTH_MSC}
+ * @mmsc{@ref BLE_GATTS_QUEUED_WRITE_NOBUF_NOAUTH_MSC}
+ * @mmsc{@ref BLE_GATTS_READ_REQ_AUTH_MSC}
+ * @mmsc{@ref BLE_GATTS_WRITE_REQ_AUTH_MSC}
+ * @mmsc{@ref BLE_GATTS_QUEUED_WRITE_QUEUE_FULL_MSC}
+ * @mmsc{@ref BLE_GATTS_QUEUED_WRITE_PEER_CANCEL_MSC}
+ * @endmscs
+ *
+ * @param[in] conn_handle Connection handle.
+ * @param[in] p_rw_authorize_reply_params Pointer to a structure with the attribute provided by the application.
+ *
+ * @note @ref ble_gatts_authorize_params_t::p_data is ignored when this function is used to respond
+ * to a @ref BLE_GATTS_AUTHORIZE_TYPE_READ event if @ref ble_gatts_authorize_params_t::update
+ * is set to 0.
+ *
+ * @retval ::NRF_SUCCESS Successfully queued a response to the peer, and in the case of a write operation, Attribute Table updated.
+ * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid Connection Handle.
+ * @retval ::NRF_ERROR_BUSY The stack is busy, process pending events and retry.
+ * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied.
+ * @retval ::NRF_ERROR_INVALID_STATE Invalid Connection State or no authorization request pending.
+ * @retval ::NRF_ERROR_INVALID_PARAM Authorization op invalid,
+ * handle supplied does not match requested handle,
+ * or invalid data to be written provided by the application.
+ * @retval ::NRF_ERROR_TIMEOUT There has been a GATT procedure timeout. No new GATT procedure can be performed without reestablishing the connection.
+ */
+SVCALL(SD_BLE_GATTS_RW_AUTHORIZE_REPLY, uint32_t, sd_ble_gatts_rw_authorize_reply(uint16_t conn_handle, ble_gatts_rw_authorize_reply_params_t const *p_rw_authorize_reply_params));
+
+
+/**@brief Update persistent system attribute information.
+ *
+ * @details Supply information about persistent system attributes to the stack,
+ * previously obtained using @ref sd_ble_gatts_sys_attr_get.
+ * This call is only allowed for active connections, and is usually
+ * made immediately after a connection is established with an known bonded device,
+ * often as a response to a @ref BLE_GATTS_EVT_SYS_ATTR_MISSING.
+ *
+ * p_sysattrs may point directly to the application's stored copy of the system attributes
+ * obtained using @ref sd_ble_gatts_sys_attr_get.
+ * If the pointer is NULL, the system attribute info is initialized, assuming that
+ * the application does not have any previously saved system attribute data for this device.
+ *
+ * @note The state of persistent system attributes is reset upon connection establishment and then remembered for its duration.
+ *
+ * @note If this call returns with an error code different from @ref NRF_SUCCESS, the storage of persistent system attributes may have been completed only partially.
+ * This means that the state of the attribute table is undefined, and the application should either provide a new set of attributes using this same call or
+ * reset the SoftDevice to return to a known state.
+ *
+ * @note When the @ref BLE_GATTS_SYS_ATTR_FLAG_SYS_SRVCS is used with this function, only the system attributes included in system services will be modified.
+ * @note When the @ref BLE_GATTS_SYS_ATTR_FLAG_USR_SRVCS is used with this function, only the system attributes included in user services will be modified.
+ *
+ * @mscs
+ * @mmsc{@ref BLE_GATTS_HVX_SYS_ATTRS_MISSING_MSC}
+ * @mmsc{@ref BLE_GATTS_SYS_ATTRS_UNK_PEER_MSC}
+ * @mmsc{@ref BLE_GATTS_SYS_ATTRS_BONDED_PEER_MSC}
+ * @endmscs
+ *
+ * @param[in] conn_handle Connection handle.
+ * @param[in] p_sys_attr_data Pointer to a saved copy of system attributes supplied to the stack, or NULL.
+ * @param[in] len Size of data pointed by p_sys_attr_data, in octets.
+ * @param[in] flags Optional additional flags, see @ref BLE_GATTS_SYS_ATTR_FLAGS
+ *
+ * @retval ::NRF_SUCCESS Successfully set the system attribute information.
+ * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid Connection Handle.
+ * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied.
+ * @retval ::NRF_ERROR_INVALID_STATE Invalid Connection State.
+ * @retval ::NRF_ERROR_INVALID_PARAM Invalid flags supplied.
+ * @retval ::NRF_ERROR_INVALID_DATA Invalid data supplied, the data should be exactly the same as retrieved with @ref sd_ble_gatts_sys_attr_get.
+ * @retval ::NRF_ERROR_NO_MEM Not enough memory to complete operation.
+ */
+SVCALL(SD_BLE_GATTS_SYS_ATTR_SET, uint32_t, sd_ble_gatts_sys_attr_set(uint16_t conn_handle, uint8_t const *p_sys_attr_data, uint16_t len, uint32_t flags));
+
+
+/**@brief Retrieve persistent system attribute information from the stack.
+ *
+ * @details This call is used to retrieve information about values to be stored persistently by the application
+ * during the lifetime of a connection or after it has been terminated. When a new connection is established with the same bonded device,
+ * the system attribute information retrieved with this function should be restored using using @ref sd_ble_gatts_sys_attr_set.
+ * If retrieved after disconnection, the data should be read before a new connection established. The connection handle for
+ * the previous, now disconnected, connection will remain valid until a new one is created to allow this API call to refer to it.
+ * Connection handles belonging to active connections can be used as well, but care should be taken since the system attributes
+ * may be written to at any time by the peer during a connection's lifetime.
+ *
+ * @note When the @ref BLE_GATTS_SYS_ATTR_FLAG_SYS_SRVCS is used with this function, only the system attributes included in system services will be returned.
+ * @note When the @ref BLE_GATTS_SYS_ATTR_FLAG_USR_SRVCS is used with this function, only the system attributes included in user services will be returned.
+ *
+ * @mscs
+ * @mmsc{@ref BLE_GATTS_SYS_ATTRS_BONDED_PEER_MSC}
+ * @endmscs
+ *
+ * @param[in] conn_handle Connection handle of the recently terminated connection.
+ * @param[out] p_sys_attr_data Pointer to a buffer where updated information about system attributes will be filled in. The format of the data is described
+ * in @ref BLE_GATTS_SYS_ATTRS_FORMAT. NULL can be provided to obtain the length of the data.
+ * @param[in,out] p_len Size of application buffer if p_sys_attr_data is not NULL. Unconditionally updated to actual length of system attribute data.
+ * @param[in] flags Optional additional flags, see @ref BLE_GATTS_SYS_ATTR_FLAGS
+ *
+ * @retval ::NRF_SUCCESS Successfully retrieved the system attribute information.
+ * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid Connection Handle.
+ * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied.
+ * @retval ::NRF_ERROR_INVALID_PARAM Invalid flags supplied.
+ * @retval ::NRF_ERROR_DATA_SIZE The system attribute information did not fit into the provided buffer.
+ * @retval ::NRF_ERROR_NOT_FOUND No system attributes found.
+ */
+SVCALL(SD_BLE_GATTS_SYS_ATTR_GET, uint32_t, sd_ble_gatts_sys_attr_get(uint16_t conn_handle, uint8_t *p_sys_attr_data, uint16_t *p_len, uint32_t flags));
+
+
+/**@brief Retrieve the first valid user attribute handle.
+ *
+ * @param[out] p_handle Pointer to an integer where the handle will be stored.
+ *
+ * @retval ::NRF_SUCCESS Successfully retrieved the handle.
+ * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied.
+ */
+SVCALL(SD_BLE_GATTS_INITIAL_USER_HANDLE_GET, uint32_t, sd_ble_gatts_initial_user_handle_get(uint16_t *p_handle));
+
+/**@brief Retrieve the attribute UUID and/or metadata.
+ *
+ * @param[in] handle Attribute handle
+ * @param[out] p_uuid UUID of the attribute. Use NULL to omit this field.
+ * @param[out] p_md Metadata of the attribute. Use NULL to omit this field.
+ *
+ * @retval ::NRF_SUCCESS Successfully retrieved the attribute metadata,
+ * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied.
+ * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameters supplied. Returned when both @c p_uuid and @c p_md are NULL.
+ * @retval ::NRF_ERROR_NOT_FOUND Attribute was not found.
+ */
+SVCALL(SD_BLE_GATTS_ATTR_GET, uint32_t, sd_ble_gatts_attr_get(uint16_t handle, ble_uuid_t * p_uuid, ble_gatts_attr_md_t * p_md));
+
+/**@brief Reply to an ATT_MTU exchange request by sending an Exchange MTU Response to the client.
+ *
+ * @details This function is only used to reply to a @ref BLE_GATTS_EVT_EXCHANGE_MTU_REQUEST event.
+ *
+ * @details The SoftDevice sets ATT_MTU to the minimum of:
+ * - The Client RX MTU value from @ref BLE_GATTS_EVT_EXCHANGE_MTU_REQUEST, and
+ * - The Server RX MTU value.
+ *
+ * However, the SoftDevice never sets ATT_MTU lower than @ref BLE_GATT_ATT_MTU_DEFAULT.
+ *
+ * @mscs
+ * @mmsc{@ref BLE_GATTS_MTU_EXCHANGE}
+ * @endmscs
+ *
+ * @param[in] conn_handle The connection handle identifying the connection to perform this procedure on.
+ * @param[in] server_rx_mtu Server RX MTU size.
+ * - The minimum value is @ref BLE_GATT_ATT_MTU_DEFAULT.
+ * - The maximum value is @ref ble_gatt_conn_cfg_t::att_mtu in the connection configuration
+ * used for this connection.
+ * - The value must be equal to Client RX MTU size given in @ref sd_ble_gattc_exchange_mtu_request
+ * if an ATT_MTU exchange has already been performed in the other direction.
+ *
+ * @retval ::NRF_SUCCESS Successfully sent response to the client.
+ * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid Connection Handle.
+ * @retval ::NRF_ERROR_INVALID_STATE Invalid Connection State or no ATT_MTU exchange request pending.
+ * @retval ::NRF_ERROR_INVALID_PARAM Invalid Server RX MTU size supplied.
+ * @retval ::NRF_ERROR_TIMEOUT There has been a GATT procedure timeout. No new GATT procedure can be performed without reestablishing the connection.
+ */
+SVCALL(SD_BLE_GATTS_EXCHANGE_MTU_REPLY, uint32_t, sd_ble_gatts_exchange_mtu_reply(uint16_t conn_handle, uint16_t server_rx_mtu));
+/** @} */
+
+#ifdef __cplusplus
+}
+#endif
+#endif // BLE_GATTS_H__
+
+/**
+ @}
+*/
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/softdevice/s132/headers/ble_hci.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/softdevice/s132/headers/ble_hci.h
new file mode 100644
index 0000000..f0dde9a
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/softdevice/s132/headers/ble_hci.h
@@ -0,0 +1,135 @@
+/*
+ * Copyright (c) 2012 - 2017, 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ */
+
+/**
+ @addtogroup BLE_COMMON
+ @{
+*/
+
+
+#ifndef BLE_HCI_H__
+#define BLE_HCI_H__
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** @defgroup BLE_HCI_STATUS_CODES Bluetooth status codes
+ * @{ */
+
+#define BLE_HCI_STATUS_CODE_SUCCESS 0x00 /**< Success. */
+#define BLE_HCI_STATUS_CODE_UNKNOWN_BTLE_COMMAND 0x01 /**< Unknown BLE Command. */
+#define BLE_HCI_STATUS_CODE_UNKNOWN_CONNECTION_IDENTIFIER 0x02 /**< Unknown Connection Identifier. */
+/*0x03 Hardware Failure
+0x04 Page Timeout
+*/
+#define BLE_HCI_AUTHENTICATION_FAILURE 0x05 /**< Authentication Failure. */
+#define BLE_HCI_STATUS_CODE_PIN_OR_KEY_MISSING 0x06 /**< Pin or Key missing. */
+#define BLE_HCI_MEMORY_CAPACITY_EXCEEDED 0x07 /**< Memory Capacity Exceeded. */
+#define BLE_HCI_CONNECTION_TIMEOUT 0x08 /**< Connection Timeout. */
+/*0x09 Connection Limit Exceeded
+0x0A Synchronous Connection Limit To A Device Exceeded
+0x0B ACL Connection Already Exists*/
+#define BLE_HCI_STATUS_CODE_COMMAND_DISALLOWED 0x0C /**< Command Disallowed. */
+/*0x0D Connection Rejected due to Limited Resources
+0x0E Connection Rejected Due To Security Reasons
+0x0F Connection Rejected due to Unacceptable BD_ADDR
+0x10 Connection Accept Timeout Exceeded
+0x11 Unsupported Feature or Parameter Value*/
+#define BLE_HCI_STATUS_CODE_INVALID_BTLE_COMMAND_PARAMETERS 0x12 /**< Invalid BLE Command Parameters. */
+#define BLE_HCI_REMOTE_USER_TERMINATED_CONNECTION 0x13 /**< Remote User Terminated Connection. */
+#define BLE_HCI_REMOTE_DEV_TERMINATION_DUE_TO_LOW_RESOURCES 0x14 /**< Remote Device Terminated Connection due to low resources.*/
+#define BLE_HCI_REMOTE_DEV_TERMINATION_DUE_TO_POWER_OFF 0x15 /**< Remote Device Terminated Connection due to power off. */
+#define BLE_HCI_LOCAL_HOST_TERMINATED_CONNECTION 0x16 /**< Local Host Terminated Connection. */
+/*
+0x17 Repeated Attempts
+0x18 Pairing Not Allowed
+0x19 Unknown LMP PDU
+*/
+#define BLE_HCI_UNSUPPORTED_REMOTE_FEATURE 0x1A /**< Unsupported Remote Feature. */
+/*
+0x1B SCO Offset Rejected
+0x1C SCO Interval Rejected
+0x1D SCO Air Mode Rejected*/
+#define BLE_HCI_STATUS_CODE_INVALID_LMP_PARAMETERS 0x1E /**< Invalid LMP Parameters. */
+#define BLE_HCI_STATUS_CODE_UNSPECIFIED_ERROR 0x1F /**< Unspecified Error. */
+/*0x20 Unsupported LMP Parameter Value
+0x21 Role Change Not Allowed
+*/
+#define BLE_HCI_STATUS_CODE_LMP_RESPONSE_TIMEOUT 0x22 /**< LMP Response Timeout. */
+#define BLE_HCI_STATUS_CODE_LMP_ERROR_TRANSACTION_COLLISION 0x23 /**< LMP Error Transaction Collision/LL Procedure Collision. */
+#define BLE_HCI_STATUS_CODE_LMP_PDU_NOT_ALLOWED 0x24 /**< LMP PDU Not Allowed. */
+/*0x25 Encryption Mode Not Acceptable
+0x26 Link Key Can Not be Changed
+0x27 Requested QoS Not Supported
+*/
+#define BLE_HCI_INSTANT_PASSED 0x28 /**< Instant Passed. */
+#define BLE_HCI_PAIRING_WITH_UNIT_KEY_UNSUPPORTED 0x29 /**< Pairing with Unit Key Unsupported. */
+#define BLE_HCI_DIFFERENT_TRANSACTION_COLLISION 0x2A /**< Different Transaction Collision. */
+/*
+0x2B Reserved
+0x2C QoS Unacceptable Parameter
+0x2D QoS Rejected
+0x2E Channel Classification Not Supported
+0x2F Insufficient Security
+*/
+#define BLE_HCI_PARAMETER_OUT_OF_MANDATORY_RANGE 0x30 /**< Parameter Out Of Mandatory Range. */
+/*
+0x31 Reserved
+0x32 Role Switch Pending
+0x33 Reserved
+0x34 Reserved Slot Violation
+0x35 Role Switch Failed
+0x36 Extended Inquiry Response Too Large
+0x37 Secure Simple Pairing Not Supported By Host.
+0x38 Host Busy - Pairing
+0x39 Connection Rejected due to No Suitable Channel Found*/
+#define BLE_HCI_CONTROLLER_BUSY 0x3A /**< Controller Busy. */
+#define BLE_HCI_CONN_INTERVAL_UNACCEPTABLE 0x3B /**< Connection Interval Unacceptable. */
+#define BLE_HCI_DIRECTED_ADVERTISER_TIMEOUT 0x3C /**< Directed Advertisement Timeout. */
+#define BLE_HCI_CONN_TERMINATED_DUE_TO_MIC_FAILURE 0x3D /**< Connection Terminated due to MIC Failure. */
+#define BLE_HCI_CONN_FAILED_TO_BE_ESTABLISHED 0x3E /**< Connection Failed to be Established. */
+
+/** @} */
+
+
+#ifdef __cplusplus
+}
+#endif
+#endif // BLE_HCI_H__
+
+/** @} */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/softdevice/s132/headers/ble_l2cap.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/softdevice/s132/headers/ble_l2cap.h
new file mode 100644
index 0000000..eaeb4b7
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/softdevice/s132/headers/ble_l2cap.h
@@ -0,0 +1,506 @@
+/*
+ * Copyright (c) 2011 - 2017, 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ */
+
+/**
+ @addtogroup BLE_L2CAP Logical Link Control and Adaptation Protocol (L2CAP)
+ @{
+ @brief Definitions and prototypes for the L2CAP interface.
+ */
+
+#ifndef BLE_L2CAP_H__
+#define BLE_L2CAP_H__
+
+#include <stdint.h>
+#include "nrf_svc.h"
+#include "nrf_error.h"
+#include "ble_ranges.h"
+#include "ble_types.h"
+#include "ble_err.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**@addtogroup BLE_L2CAP_TERMINOLOGY Terminology
+ * @{
+ * @details
+ *
+ * L2CAP SDU
+ * - A data unit that the application can send/receive to/from a peer.
+ *
+ * L2CAP PDU
+ * - A data unit that is exchanged between local and remote L2CAP entities.
+ * It consists of L2CAP protocol control information and payload fields.
+ * The payload field can contain an L2CAP SDU or a part of an L2CAP SDU.
+ *
+ * L2CAP MTU
+ * - The maximum length of an L2CAP SDU.
+ *
+ * L2CAP MPS
+ * - The maximum length of an L2CAP PDU payload field.
+ *
+ * Credits
+ * - A value indicating the number of L2CAP PDUs that the receiver of the credit can send to the peer.
+ * @} */
+
+/**@addtogroup BLE_L2CAP_ENUMERATIONS Enumerations
+ * @{ */
+
+/**@brief L2CAP API SVC numbers. */
+enum BLE_L2CAP_SVCS
+{
+ SD_BLE_L2CAP_CH_SETUP = BLE_L2CAP_SVC_BASE + 0, /**< Set up an L2CAP channel. */
+ SD_BLE_L2CAP_CH_RELEASE = BLE_L2CAP_SVC_BASE + 1, /**< Release an L2CAP channel. */
+ SD_BLE_L2CAP_CH_RX = BLE_L2CAP_SVC_BASE + 2, /**< Receive an SDU on an L2CAP channel. */
+ SD_BLE_L2CAP_CH_TX = BLE_L2CAP_SVC_BASE + 3, /**< Transmit an SDU on an L2CAP channel. */
+ SD_BLE_L2CAP_CH_FLOW_CONTROL = BLE_L2CAP_SVC_BASE + 4, /**< Advanced SDU reception flow control. */
+};
+
+/**@brief L2CAP Event IDs. */
+enum BLE_L2CAP_EVTS
+{
+ BLE_L2CAP_EVT_CH_SETUP_REQUEST = BLE_L2CAP_EVT_BASE + 0, /**< L2CAP Channel Setup Request event.
+ \n See @ref ble_l2cap_evt_ch_setup_request_t. */
+ BLE_L2CAP_EVT_CH_SETUP_REFUSED = BLE_L2CAP_EVT_BASE + 1, /**< L2CAP Channel Setup Refused event.
+ \n See @ref ble_l2cap_evt_ch_setup_refused_t. */
+ BLE_L2CAP_EVT_CH_SETUP = BLE_L2CAP_EVT_BASE + 2, /**< L2CAP Channel Setup Completed event.
+ \n See @ref ble_l2cap_evt_ch_setup_t. */
+ BLE_L2CAP_EVT_CH_RELEASED = BLE_L2CAP_EVT_BASE + 3, /**< L2CAP Channel Released event.
+ \n No additional event structure applies. */
+ BLE_L2CAP_EVT_CH_SDU_BUF_RELEASED = BLE_L2CAP_EVT_BASE + 4, /**< L2CAP Channel SDU data buffer released event.
+ \n See @ref ble_l2cap_evt_ch_sdu_buf_released_t. */
+ BLE_L2CAP_EVT_CH_CREDIT = BLE_L2CAP_EVT_BASE + 5, /**< L2CAP Channel Credit received.
+ \n See @ref ble_l2cap_evt_ch_credit_t. */
+ BLE_L2CAP_EVT_CH_RX = BLE_L2CAP_EVT_BASE + 6, /**< L2CAP Channel SDU received.
+ \n See @ref ble_l2cap_evt_ch_rx_t. */
+ BLE_L2CAP_EVT_CH_TX = BLE_L2CAP_EVT_BASE + 7, /**< L2CAP Channel SDU transmitted.
+ \n See @ref ble_l2cap_evt_ch_tx_t. */
+};
+
+/** @} */
+
+/**@addtogroup BLE_L2CAP_DEFINES Defines
+ * @{ */
+
+/**@brief Maximum number of L2CAP channels per connection. */
+#define BLE_L2CAP_CH_COUNT_MAX (64)
+
+/**@brief Minimum L2CAP MTU, in bytes. */
+#define BLE_L2CAP_MTU_MIN (23)
+
+/**@brief Minimum L2CAP MPS, in bytes. */
+#define BLE_L2CAP_MPS_MIN (23)
+
+/**@brief Invalid CID. */
+#define BLE_L2CAP_CID_INVALID (0x0000)
+
+/**@brief Default number of credits for @ref sd_ble_l2cap_ch_flow_control. */
+#define BLE_L2CAP_CREDITS_DEFAULT (1)
+
+/**@defgroup BLE_L2CAP_CH_SETUP_REFUSED_SRCS L2CAP channel setup refused sources
+ * @{ */
+#define BLE_L2CAP_CH_SETUP_REFUSED_SRC_LOCAL (0x01) /**< Local. */
+#define BLE_L2CAP_CH_SETUP_REFUSED_SRC_REMOTE (0x02) /**< Remote. */
+ /** @} */
+
+ /** @defgroup BLE_L2CAP_CH_STATUS_CODES L2CAP channel status codes
+ * @{ */
+#define BLE_L2CAP_CH_STATUS_CODE_SUCCESS (0x0000) /**< Success. */
+#define BLE_L2CAP_CH_STATUS_CODE_LE_PSM_NOT_SUPPORTED (0x0002) /**< LE_PSM not supported. */
+#define BLE_L2CAP_CH_STATUS_CODE_NO_RESOURCES (0x0004) /**< No resources available. */
+#define BLE_L2CAP_CH_STATUS_CODE_INSUFF_AUTHENTICATION (0x0005) /**< Insufficient authentication. */
+#define BLE_L2CAP_CH_STATUS_CODE_INSUFF_AUTHORIZATION (0x0006) /**< Insufficient authorization. */
+#define BLE_L2CAP_CH_STATUS_CODE_INSUFF_ENC_KEY_SIZE (0x0007) /**< Insufficient encryption key size. */
+#define BLE_L2CAP_CH_STATUS_CODE_INSUFF_ENC (0x0008) /**< Insufficient encryption. */
+#define BLE_L2CAP_CH_STATUS_CODE_INVALID_SCID (0x0009) /**< Invalid Source CID. */
+#define BLE_L2CAP_CH_STATUS_CODE_SCID_ALLOCATED (0x000A) /**< Source CID already allocated. */
+#define BLE_L2CAP_CH_STATUS_CODE_UNACCEPTABLE_PARAMS (0x000B) /**< Unacceptable parameters. */
+#define BLE_L2CAP_CH_STATUS_CODE_NOT_UNDERSTOOD (0x8000) /**< Command Reject received instead of LE Credit Based Connection Response. */
+#define BLE_L2CAP_CH_STATUS_CODE_TIMEOUT (0xC000) /**< Operation timed out. */
+/** @} */
+
+/** @} */
+
+/**@addtogroup BLE_L2CAP_STRUCTURES Structures
+ * @{ */
+
+/**
+ * @brief BLE L2CAP connection configuration parameters, set with @ref sd_ble_cfg_set.
+ *
+ * @note These parameters are set per connection, so all L2CAP channels created on this connection
+ * will have the same parameters.
+ *
+ * @retval ::NRF_ERROR_INVALID_PARAM One or more of the following is true:
+ * - rx_mps is smaller than @ref BLE_L2CAP_MPS_MIN.
+ * - tx_mps is smaller than @ref BLE_L2CAP_MPS_MIN.
+ * - ch_count is greater than @ref BLE_L2CAP_CH_COUNT_MAX.
+ * @retval ::NRF_ERROR_NO_MEM rx_mps or tx_mps is set too high.
+ */
+typedef struct
+{
+ uint16_t rx_mps; /**< The maximum L2CAP PDU payload size, in bytes, that L2CAP shall
+ be able to receive on L2CAP channels on connections with this
+ configuration. The minimum value is @ref BLE_L2CAP_MPS_MIN. */
+ uint16_t tx_mps; /**< The maximum L2CAP PDU payload size, in bytes, that L2CAP shall
+ be able to transmit on L2CAP channels on connections with this
+ configuration. The minimum value is @ref BLE_L2CAP_MPS_MIN. */
+ uint8_t rx_queue_size; /**< Number of SDU data buffers that can be queued for reception per
+ L2CAP channel. The minimum value is one. */
+ uint8_t tx_queue_size; /**< Number of SDU data buffers that can be queued for transmission
+ per L2CAP channel. The minimum value is one. */
+ uint8_t ch_count; /**< Number of L2CAP channels the application can create per connection
+ with this configuration. The default value is zero, the maximum
+ value is @ref BLE_L2CAP_CH_COUNT_MAX.
+ @note if this parameter is set to zero, all other parameters in
+ @ref ble_l2cap_conn_cfg_t are ignored. */
+} ble_l2cap_conn_cfg_t;
+
+/**@brief L2CAP channel RX parameters. */
+typedef struct
+{
+ uint16_t rx_mtu; /**< The maximum L2CAP SDU size, in bytes, that L2CAP shall be able to
+ receive on this L2CAP channel.
+ - Must be equal to or greater than @ref BLE_L2CAP_MTU_MIN. */
+ uint16_t rx_mps; /**< The maximum L2CAP PDU payload size, in bytes, that L2CAP shall be
+ able to receive on this L2CAP channel.
+ - Must be equal to or greater than @ref BLE_L2CAP_MPS_MIN.
+ - Must be equal to or less than @ref ble_l2cap_conn_cfg_t::rx_mps. */
+ ble_data_t sdu_buf; /**< SDU data buffer for reception.
+ - If @ref ble_data_t::p_data is non-NULL, initial credits are
+ issued to the peer.
+ - If @ref ble_data_t::p_data is NULL, no initial credits are
+ issued to the peer. */
+} ble_l2cap_ch_rx_params_t;
+
+/**@brief L2CAP channel setup parameters. */
+typedef struct
+{
+ ble_l2cap_ch_rx_params_t rx_params; /**< L2CAP channel RX parameters. */
+ uint16_t le_psm; /**< LE Protocol/Service Multiplexer. Used when requesting
+ setup of an L2CAP channel, ignored otherwise. */
+ uint16_t status; /**< Status code, see @ref BLE_L2CAP_CH_STATUS_CODES.
+ Used when replying to a setup request of an L2CAP
+ channel, ignored otherwise. */
+} ble_l2cap_ch_setup_params_t;
+
+/**@brief L2CAP channel TX parameters. */
+typedef struct
+{
+ uint16_t tx_mtu; /**< The maximum L2CAP SDU size, in bytes, that L2CAP is able to
+ transmit on this L2CAP channel. */
+ uint16_t peer_mps; /**< The maximum L2CAP PDU payload size, in bytes, that the peer is
+ able to receive on this L2CAP channel. */
+ uint16_t tx_mps; /**< The maximum L2CAP PDU payload size, in bytes, that L2CAP is able
+ to transmit on this L2CAP channel. This is effective tx_mps,
+ selected by the SoftDevice as
+ MIN( @ref ble_l2cap_ch_tx_params_t::peer_mps, @ref ble_l2cap_conn_cfg_t::tx_mps ) */
+ uint16_t credits; /**< Initial credits given by the peer. */
+} ble_l2cap_ch_tx_params_t;
+
+/**@brief L2CAP Channel Setup Request event. */
+typedef struct
+{
+ ble_l2cap_ch_tx_params_t tx_params; /**< L2CAP channel TX parameters. */
+ uint16_t le_psm; /**< LE Protocol/Service Multiplexer. */
+} ble_l2cap_evt_ch_setup_request_t;
+
+/**@brief L2CAP Channel Setup Refused event. */
+typedef struct
+{
+ uint8_t source; /**< Source, see @ref BLE_L2CAP_CH_SETUP_REFUSED_SRCS */
+ uint16_t status; /**< Status code, see @ref BLE_L2CAP_CH_STATUS_CODES */
+} ble_l2cap_evt_ch_setup_refused_t;
+
+/**@brief L2CAP Channel Setup Completed event. */
+typedef struct
+{
+ ble_l2cap_ch_tx_params_t tx_params; /**< L2CAP channel TX parameters. */
+} ble_l2cap_evt_ch_setup_t;
+
+/**@brief L2CAP Channel SDU Data Duffer Released event. */
+typedef struct
+{
+ ble_data_t sdu_buf; /**< Returned reception or transmission SDU data buffer. The SoftDevice
+ returns SDU data buffers supplied by the application, which have
+ not yet been returned previously via a @ref BLE_L2CAP_EVT_CH_RX or
+ @ref BLE_L2CAP_EVT_CH_TX event. */
+} ble_l2cap_evt_ch_sdu_buf_released_t;
+
+/**@brief L2CAP Channel Credit received event. */
+typedef struct
+{
+ uint16_t credits; /**< Additional credits given by the peer. */
+} ble_l2cap_evt_ch_credit_t;
+
+/**@brief L2CAP Channel received SDU event. */
+typedef struct
+{
+ uint16_t sdu_len; /**< Total SDU length, in bytes. */
+ ble_data_t sdu_buf; /**< SDU data buffer.
+ @note If there is not enough space in the buffer
+ (sdu_buf.len < sdu_len) then the rest of the SDU will be
+ silently discarded by the SoftDevice. */
+} ble_l2cap_evt_ch_rx_t;
+
+/**@brief L2CAP Channel transmitted SDU event. */
+typedef struct
+{
+ ble_data_t sdu_buf; /**< SDU data buffer. */
+} ble_l2cap_evt_ch_tx_t;
+
+/**@brief L2CAP event structure. */
+typedef struct
+{
+ uint16_t conn_handle; /**< Connection Handle on which the event occured. */
+ uint16_t local_cid; /**< Local Channel ID of the L2CAP channel, or
+ @ref BLE_L2CAP_CID_INVALID if not present. */
+ union
+ {
+ ble_l2cap_evt_ch_setup_request_t ch_setup_request; /**< L2CAP Channel Setup Request Event Parameters. */
+ ble_l2cap_evt_ch_setup_refused_t ch_setup_refused; /**< L2CAP Channel Setup Refused Event Parameters. */
+ ble_l2cap_evt_ch_setup_t ch_setup; /**< L2CAP Channel Setup Completed Event Parameters. */
+ ble_l2cap_evt_ch_sdu_buf_released_t ch_sdu_buf_released;/**< L2CAP Channel SDU Data Buffer Released Event Parameters. */
+ ble_l2cap_evt_ch_credit_t credit; /**< L2CAP Channel Credit Received Event Parameters. */
+ ble_l2cap_evt_ch_rx_t rx; /**< L2CAP Channel SDU Received Event Parameters. */
+ ble_l2cap_evt_ch_tx_t tx; /**< L2CAP Channel SDU Transmitted Event Parameters. */
+ } params; /**< Event Parameters. */
+} ble_l2cap_evt_t;
+
+/** @} */
+
+/**@addtogroup BLE_L2CAP_FUNCTIONS Functions
+ * @{ */
+
+/**@brief Set up an L2CAP channel.
+ *
+ * @details This function is used to:
+ * - Request setup of an L2CAP channel: sends an LE Credit Based Connection Request packet to a peer.
+ * - Reply to a setup request of an L2CAP channel (if called in response to a
+ * @ref BLE_L2CAP_EVT_CH_SETUP_REQUEST event): sends an LE Credit Based Connection
+ * Response packet to a peer.
+ *
+ * @note A call to this function will require the application to keep the SDU data buffer alive
+ * until the SDU data buffer is returned in @ref BLE_L2CAP_EVT_CH_RX or
+ * @ref BLE_L2CAP_EVT_CH_SDU_BUF_RELEASED event.
+ *
+ * @events
+ * @event{@ref BLE_L2CAP_EVT_CH_SETUP, Setup successful.}
+ * @event{@ref BLE_L2CAP_EVT_CH_SETUP_REFUSED, Setup failed.}
+ * @endevents
+ *
+ * @mscs
+ * @mmsc{@ref BLE_L2CAP_CH_SETUP_MSC}
+ * @endmscs
+ *
+ * @param[in] conn_handle Connection Handle.
+ * @param[in,out] p_local_cid Pointer to a uint16_t containing Local Channel ID of the L2CAP channel:
+ * - As input: @ref BLE_L2CAP_CID_INVALID when requesting setup of an L2CAP
+ * channel or local_cid provided in the @ref BLE_L2CAP_EVT_CH_SETUP_REQUEST
+ * event when replying to a setup request of an L2CAP channel.
+ * - As output: local_cid for this channel.
+ * @param[in] p_params L2CAP channel parameters.
+ *
+ * @retval ::NRF_SUCCESS Successfully queued request or response for transmission.
+ * @retval ::NRF_ERROR_BUSY The stack is busy, process pending events and retry.
+ * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied.
+ * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid Connection Handle.
+ * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied.
+ * @retval ::NRF_ERROR_INVALID_LENGTH Supplied higher rx_mps than has been configured on this link.
+ * @retval ::NRF_ERROR_INVALID_STATE Invalid State to perform operation (L2CAP channel already set up).
+ * @retval ::NRF_ERROR_NOT_FOUND CID not found.
+ * @retval ::NRF_ERROR_RESOURCES The limit has been reached for available L2CAP channels,
+ * see @ref ble_l2cap_conn_cfg_t::ch_count.
+ */
+SVCALL(SD_BLE_L2CAP_CH_SETUP, uint32_t, sd_ble_l2cap_ch_setup(uint16_t conn_handle, uint16_t *p_local_cid, ble_l2cap_ch_setup_params_t const *p_params));
+
+/**@brief Release an L2CAP channel.
+ *
+ * @details This sends a Disconnection Request packet to a peer.
+ *
+ * @events
+ * @event{@ref BLE_L2CAP_EVT_CH_RELEASED, Release complete.}
+ * @endevents
+ *
+ * @mscs
+ * @mmsc{@ref BLE_L2CAP_CH_RELEASE_MSC}
+ * @endmscs
+ *
+ * @param[in] conn_handle Connection Handle.
+ * @param[in] local_cid Local Channel ID of the L2CAP channel.
+ *
+ * @retval ::NRF_SUCCESS Successfully queued request for transmission.
+ * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid Connection Handle.
+ * @retval ::NRF_ERROR_INVALID_STATE Invalid State to perform operation (Setup or release is
+ * in progress for the L2CAP channel).
+ * @retval ::NRF_ERROR_NOT_FOUND CID not found.
+ */
+SVCALL(SD_BLE_L2CAP_CH_RELEASE, uint32_t, sd_ble_l2cap_ch_release(uint16_t conn_handle, uint16_t local_cid));
+
+/**@brief Receive an SDU on an L2CAP channel.
+ *
+ * @details This may issue additional credits to the peer using an LE Flow Control Credit packet.
+ *
+ * @note A call to this function will require the application to keep the memory pointed by
+ * @ref ble_data_t::p_data alive until the SDU data buffer is returned in @ref BLE_L2CAP_EVT_CH_RX
+ * or @ref BLE_L2CAP_EVT_CH_SDU_BUF_RELEASED event.
+ *
+ * @note The SoftDevice can queue up to @ref ble_l2cap_conn_cfg_t::rx_queue_size SDU data buffers
+ * for reception per L2CAP channel.
+ *
+ * @events
+ * @event{@ref BLE_L2CAP_EVT_CH_RX, The SDU is received.}
+ * @endevents
+ *
+ * @mscs
+ * @mmsc{@ref BLE_L2CAP_CH_RX_MSC}
+ * @endmscs
+ *
+ * @param[in] conn_handle Connection Handle.
+ * @param[in] local_cid Local Channel ID of the L2CAP channel.
+ * @param[in] p_sdu_buf Pointer to the SDU data buffer.
+ *
+ * @retval ::NRF_SUCCESS Buffer accepted.
+ * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied.
+ * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid Connection Handle.
+ * @retval ::NRF_ERROR_INVALID_STATE Invalid State to perform operation (Setup or release is
+ * in progress for an L2CAP channel).
+ * @retval ::NRF_ERROR_NOT_FOUND CID not found.
+ * @retval ::NRF_ERROR_RESOURCES Too many SDU data buffers supplied. Wait for a
+ * @ref BLE_L2CAP_EVT_CH_RX event and retry.
+ */
+SVCALL(SD_BLE_L2CAP_CH_RX, uint32_t, sd_ble_l2cap_ch_rx(uint16_t conn_handle, uint16_t local_cid, ble_data_t const *p_sdu_buf));
+
+/**@brief Transmit an SDU on an L2CAP channel.
+ *
+ * @note A call to this function will require the application to keep the memory pointed by
+ * @ref ble_data_t::p_data alive until the SDU data buffer is returned in @ref BLE_L2CAP_EVT_CH_TX
+ * or @ref BLE_L2CAP_EVT_CH_SDU_BUF_RELEASED event.
+ *
+ * @note The SoftDevice can queue up to @ref ble_l2cap_conn_cfg_t::tx_queue_size SDUs for
+ * transmission per L2CAP channel.
+ *
+ * @note The application can keep track of the available credits for transmission by following
+ * the procedure below:
+ * - Store initial credits given by the peer in a variable.
+ * (Initial credits are provided in a @ref BLE_L2CAP_EVT_CH_SETUP event.)
+ * - Decrement the variable, which stores the currently available credits, by
+ * ceiling((@ref ble_data_t::len + 2) / tx_mps) when a call to this function returns
+ * @ref NRF_SUCCESS. (tx_mps is provided in a @ref BLE_L2CAP_EVT_CH_SETUP event.)
+ * - Increment the variable, which stores the currently available credits, by additional
+ * credits given by the peer in a @ref BLE_L2CAP_EVT_CH_CREDIT event.
+ *
+ * @events
+ * @event{@ref BLE_L2CAP_EVT_CH_TX, The SDU is transmitted.}
+ * @endevents
+ *
+ * @mscs
+ * @mmsc{@ref BLE_L2CAP_CH_TX_MSC}
+ * @endmscs
+ *
+ * @param[in] conn_handle Connection Handle.
+ * @param[in] local_cid Local Channel ID of the L2CAP channel.
+ * @param[in] p_sdu_buf Pointer to the SDU data buffer.
+ *
+ * @retval ::NRF_SUCCESS Successfully queued L2CAP SDU for transmission.
+ * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied.
+ * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid Connection Handle.
+ * @retval ::NRF_ERROR_INVALID_STATE Invalid State to perform operation (Setup or release is
+ * in progress for the L2CAP channel).
+ * @retval ::NRF_ERROR_NOT_FOUND CID not found.
+ * @retval ::NRF_ERROR_DATA_SIZE Invalid SDU length supplied, must not be more than
+ * @ref ble_l2cap_ch_tx_params_t::tx_mtu provided in
+ * @ref BLE_L2CAP_EVT_CH_SETUP event.
+ * @retval ::NRF_ERROR_RESOURCES Too many SDUs queued for transmission. Wait for a
+ * @ref BLE_L2CAP_EVT_CH_TX event and retry.
+ */
+SVCALL(SD_BLE_L2CAP_CH_TX, uint32_t, sd_ble_l2cap_ch_tx(uint16_t conn_handle, uint16_t local_cid, ble_data_t const *p_sdu_buf));
+
+/**@brief Advanced SDU reception flow control.
+ *
+ * @details Adjust the way the SoftDevice issues credits to the peer.
+ * This may issue additional credits to the peer using an LE Flow Control Credit packet.
+ *
+ * @mscs
+ * @mmsc{@ref BLE_L2CAP_CH_FLOW_CONTROL_MSC}
+ * @endmscs
+ *
+ * @param[in] conn_handle Connection Handle.
+ * @param[in] local_cid Local Channel ID of the L2CAP channel or @ref BLE_L2CAP_CID_INVALID to set
+ * the value that will be used for newly created channels.
+ * @param[in] credits Number of credits that the SoftDevice will make sure the peer has every
+ * time it starts using a new reception buffer.
+ * - @ref BLE_L2CAP_CREDITS_DEFAULT is the default value the SoftDevice will
+ * use if this function is not called.
+ * - If set to zero, the SoftDevice will stop issuing credits for new reception
+ * buffers the application provides or has provided. SDU reception that is
+ * currently ongoing will be allowed to complete.
+ * @param[out] p_credits NULL or pointer to a uint16_t. If a valid pointer is provided, it will be
+ * written by the SoftDevice with the number of credits that is or will be
+ * available to the peer. If the value written by the SoftDevice is 0 when
+ * credits parameter was set to 0, the peer will not be able to send more
+ * data until more credits are provided by calling this function again with
+ * credits > 0. This parameter is ignored when local_cid is set to
+ * @ref BLE_L2CAP_CID_INVALID.
+ *
+ * @note Application should take care when setting number of credits higher than default value. In
+ * this case the application must make sure that the SoftDevice always has reception buffers
+ * available (see @ref sd_ble_l2cap_ch_rx) for that channel. If the SoftDevice does not have
+ * such buffers available, packets may be NACKed on the Link Layer and all Bluetooth traffic
+ * on the connection handle may be stalled until the SoftDevice again has an available
+ * reception buffer. This applies even if the application has used this call to set the
+ * credits back to default, or zero.
+ *
+ * @retval ::NRF_SUCCESS Flow control parameters accepted.
+ * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied.
+ * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid Connection Handle.
+ * @retval ::NRF_ERROR_INVALID_STATE Invalid State to perform operation (Setup or release is
+ * in progress for an L2CAP channel).
+ * @retval ::NRF_ERROR_NOT_FOUND CID not found.
+ */
+SVCALL(SD_BLE_L2CAP_CH_FLOW_CONTROL, uint32_t, sd_ble_l2cap_ch_flow_control(uint16_t conn_handle, uint16_t local_cid, uint16_t credits, uint16_t *p_credits));
+
+/** @} */
+
+#ifdef __cplusplus
+}
+#endif
+#endif // BLE_L2CAP_H__
+
+/**
+ @}
+*/
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/softdevice/s132/headers/ble_ranges.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/softdevice/s132/headers/ble_ranges.h
new file mode 100644
index 0000000..0935bca
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/softdevice/s132/headers/ble_ranges.h
@@ -0,0 +1,156 @@
+/*
+ * Copyright (c) 2012 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ */
+
+/**
+ @addtogroup BLE_COMMON
+ @{
+ @defgroup ble_ranges Module specific SVC, event and option number subranges
+ @{
+
+ @brief Definition of SVC, event and option number subranges for each API module.
+
+ @note
+ SVCs, event and option numbers are split into subranges for each API module.
+ Each module receives its entire allocated range of SVC calls, whether implemented or not,
+ but return BLE_ERROR_NOT_SUPPORTED for unimplemented or undefined calls in its range.
+
+ Note that the symbols BLE_<module>_SVC_LAST is the end of the allocated SVC range,
+ rather than the last SVC function call actually defined and implemented.
+
+ Specific SVC, event and option values are defined in each module's ble_<module>.h file,
+ which defines names of each individual SVC code based on the range start value.
+*/
+
+#ifndef BLE_RANGES_H__
+#define BLE_RANGES_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define BLE_SVC_BASE 0x60 /**< Common BLE SVC base. */
+#define BLE_SVC_LAST 0x6B /**< Common BLE SVC last. */
+
+#define BLE_GAP_SVC_BASE 0x6C /**< GAP BLE SVC base. */
+#define BLE_GAP_SVC_LAST 0x9A /**< GAP BLE SVC last. */
+
+#define BLE_GATTC_SVC_BASE 0x9B /**< GATTC BLE SVC base. */
+#define BLE_GATTC_SVC_LAST 0xA7 /**< GATTC BLE SVC last. */
+
+#define BLE_GATTS_SVC_BASE 0xA8 /**< GATTS BLE SVC base. */
+#define BLE_GATTS_SVC_LAST 0xB7 /**< GATTS BLE SVC last. */
+
+#define BLE_L2CAP_SVC_BASE 0xB8 /**< L2CAP BLE SVC base. */
+#define BLE_L2CAP_SVC_LAST 0xBF /**< L2CAP BLE SVC last. */
+
+
+#define BLE_EVT_INVALID 0x00 /**< Invalid BLE Event. */
+
+#define BLE_EVT_BASE 0x01 /**< Common BLE Event base. */
+#define BLE_EVT_LAST 0x0F /**< Common BLE Event last. */
+
+#define BLE_GAP_EVT_BASE 0x10 /**< GAP BLE Event base. */
+#define BLE_GAP_EVT_LAST 0x2F /**< GAP BLE Event last. */
+
+#define BLE_GATTC_EVT_BASE 0x30 /**< GATTC BLE Event base. */
+#define BLE_GATTC_EVT_LAST 0x4F /**< GATTC BLE Event last. */
+
+#define BLE_GATTS_EVT_BASE 0x50 /**< GATTS BLE Event base. */
+#define BLE_GATTS_EVT_LAST 0x6F /**< GATTS BLE Event last. */
+
+#define BLE_L2CAP_EVT_BASE 0x70 /**< L2CAP BLE Event base. */
+#define BLE_L2CAP_EVT_LAST 0x8F /**< L2CAP BLE Event last. */
+
+
+#define BLE_OPT_INVALID 0x00 /**< Invalid BLE Option. */
+
+#define BLE_OPT_BASE 0x01 /**< Common BLE Option base. */
+#define BLE_OPT_LAST 0x1F /**< Common BLE Option last. */
+
+#define BLE_GAP_OPT_BASE 0x20 /**< GAP BLE Option base. */
+#define BLE_GAP_OPT_LAST 0x3F /**< GAP BLE Option last. */
+
+#define BLE_GATT_OPT_BASE 0x40 /**< GATT BLE Option base. */
+#define BLE_GATT_OPT_LAST 0x5F /**< GATT BLE Option last. */
+
+#define BLE_GATTC_OPT_BASE 0x60 /**< GATTC BLE Option base. */
+#define BLE_GATTC_OPT_LAST 0x7F /**< GATTC BLE Option last. */
+
+#define BLE_GATTS_OPT_BASE 0x80 /**< GATTS BLE Option base. */
+#define BLE_GATTS_OPT_LAST 0x9F /**< GATTS BLE Option last. */
+
+#define BLE_L2CAP_OPT_BASE 0xA0 /**< L2CAP BLE Option base. */
+#define BLE_L2CAP_OPT_LAST 0xBF /**< L2CAP BLE Option last. */
+
+
+#define BLE_CFG_INVALID 0x00 /**< Invalid BLE configuration. */
+
+#define BLE_CFG_BASE 0x01 /**< Common BLE configuration base. */
+#define BLE_CFG_LAST 0x1F /**< Common BLE configuration last. */
+
+#define BLE_CONN_CFG_BASE 0x20 /**< BLE connection configuration base. */
+#define BLE_CONN_CFG_LAST 0x3F /**< BLE connection configuration last. */
+
+#define BLE_GAP_CFG_BASE 0x40 /**< GAP BLE configuration base. */
+#define BLE_GAP_CFG_LAST 0x5F /**< GAP BLE configuration last. */
+
+#define BLE_GATT_CFG_BASE 0x60 /**< GATT BLE configuration base. */
+#define BLE_GATT_CFG_LAST 0x7F /**< GATT BLE configuration last. */
+
+#define BLE_GATTC_CFG_BASE 0x80 /**< GATTC BLE configuration base. */
+#define BLE_GATTC_CFG_LAST 0x9F /**< GATTC BLE configuration last. */
+
+#define BLE_GATTS_CFG_BASE 0xA0 /**< GATTS BLE configuration base. */
+#define BLE_GATTS_CFG_LAST 0xBF /**< GATTS BLE configuration last. */
+
+#define BLE_L2CAP_CFG_BASE 0xC0 /**< L2CAP BLE configuration base. */
+#define BLE_L2CAP_CFG_LAST 0xDF /**< L2CAP BLE configuration last. */
+
+
+
+
+
+#ifdef __cplusplus
+}
+#endif
+#endif /* BLE_RANGES_H__ */
+
+/**
+ @}
+ @}
+*/
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/softdevice/s132/headers/ble_types.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/softdevice/s132/headers/ble_types.h
new file mode 100644
index 0000000..88c9318
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/softdevice/s132/headers/ble_types.h
@@ -0,0 +1,215 @@
+/*
+ * Copyright (c) 2012 - 2017, 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ */
+
+/**
+ @addtogroup BLE_COMMON
+ @{
+ @defgroup ble_types Common types and macro definitions
+ @{
+
+ @brief Common types and macro definitions for the BLE SoftDevice.
+ */
+
+#ifndef BLE_TYPES_H__
+#define BLE_TYPES_H__
+
+#include <stdint.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** @addtogroup BLE_TYPES_DEFINES Defines
+ * @{ */
+
+/** @defgroup BLE_CONN_HANDLES BLE Connection Handles
+ * @{ */
+#define BLE_CONN_HANDLE_INVALID 0xFFFF /**< Invalid Connection Handle. */
+#define BLE_CONN_HANDLE_ALL 0xFFFE /**< Applies to all Connection Handles. */
+/** @} */
+
+
+/** @defgroup BLE_UUID_VALUES Assigned Values for BLE UUIDs
+ * @{ */
+/* Generic UUIDs, applicable to all services */
+#define BLE_UUID_UNKNOWN 0x0000 /**< Reserved UUID. */
+#define BLE_UUID_SERVICE_PRIMARY 0x2800 /**< Primary Service. */
+#define BLE_UUID_SERVICE_SECONDARY 0x2801 /**< Secondary Service. */
+#define BLE_UUID_SERVICE_INCLUDE 0x2802 /**< Include. */
+#define BLE_UUID_CHARACTERISTIC 0x2803 /**< Characteristic. */
+#define BLE_UUID_DESCRIPTOR_CHAR_EXT_PROP 0x2900 /**< Characteristic Extended Properties Descriptor. */
+#define BLE_UUID_DESCRIPTOR_CHAR_USER_DESC 0x2901 /**< Characteristic User Description Descriptor. */
+#define BLE_UUID_DESCRIPTOR_CLIENT_CHAR_CONFIG 0x2902 /**< Client Characteristic Configuration Descriptor. */
+#define BLE_UUID_DESCRIPTOR_SERVER_CHAR_CONFIG 0x2903 /**< Server Characteristic Configuration Descriptor. */
+#define BLE_UUID_DESCRIPTOR_CHAR_PRESENTATION_FORMAT 0x2904 /**< Characteristic Presentation Format Descriptor. */
+#define BLE_UUID_DESCRIPTOR_CHAR_AGGREGATE_FORMAT 0x2905 /**< Characteristic Aggregate Format Descriptor. */
+/* GATT specific UUIDs */
+#define BLE_UUID_GATT 0x1801 /**< Generic Attribute Profile. */
+#define BLE_UUID_GATT_CHARACTERISTIC_SERVICE_CHANGED 0x2A05 /**< Service Changed Characteristic. */
+/* GAP specific UUIDs */
+#define BLE_UUID_GAP 0x1800 /**< Generic Access Profile. */
+#define BLE_UUID_GAP_CHARACTERISTIC_DEVICE_NAME 0x2A00 /**< Device Name Characteristic. */
+#define BLE_UUID_GAP_CHARACTERISTIC_APPEARANCE 0x2A01 /**< Appearance Characteristic. */
+#define BLE_UUID_GAP_CHARACTERISTIC_RECONN_ADDR 0x2A03 /**< Reconnection Address Characteristic. */
+#define BLE_UUID_GAP_CHARACTERISTIC_PPCP 0x2A04 /**< Peripheral Preferred Connection Parameters Characteristic. */
+#define BLE_UUID_GAP_CHARACTERISTIC_CAR 0x2AA6 /**< Central Address Resolution Characteristic. */
+#define BLE_UUID_GAP_CHARACTERISTIC_RPA_ONLY 0x2AC9 /**< Resolvable Private Address Only Characteristic. */
+/** @} */
+
+
+/** @defgroup BLE_UUID_TYPES Types of UUID
+ * @{ */
+#define BLE_UUID_TYPE_UNKNOWN 0x00 /**< Invalid UUID type. */
+#define BLE_UUID_TYPE_BLE 0x01 /**< Bluetooth SIG UUID (16-bit). */
+#define BLE_UUID_TYPE_VENDOR_BEGIN 0x02 /**< Vendor UUID types start at this index (128-bit). */
+/** @} */
+
+
+/** @defgroup BLE_APPEARANCES Bluetooth Appearance values
+ * @note Retrieved from http://developer.bluetooth.org/gatt/characteristics/Pages/CharacteristicViewer.aspx?u=org.bluetooth.characteristic.gap.appearance.xml
+ * @{ */
+#define BLE_APPEARANCE_UNKNOWN 0 /**< Unknown. */
+#define BLE_APPEARANCE_GENERIC_PHONE 64 /**< Generic Phone. */
+#define BLE_APPEARANCE_GENERIC_COMPUTER 128 /**< Generic Computer. */
+#define BLE_APPEARANCE_GENERIC_WATCH 192 /**< Generic Watch. */
+#define BLE_APPEARANCE_WATCH_SPORTS_WATCH 193 /**< Watch: Sports Watch. */
+#define BLE_APPEARANCE_GENERIC_CLOCK 256 /**< Generic Clock. */
+#define BLE_APPEARANCE_GENERIC_DISPLAY 320 /**< Generic Display. */
+#define BLE_APPEARANCE_GENERIC_REMOTE_CONTROL 384 /**< Generic Remote Control. */
+#define BLE_APPEARANCE_GENERIC_EYE_GLASSES 448 /**< Generic Eye-glasses. */
+#define BLE_APPEARANCE_GENERIC_TAG 512 /**< Generic Tag. */
+#define BLE_APPEARANCE_GENERIC_KEYRING 576 /**< Generic Keyring. */
+#define BLE_APPEARANCE_GENERIC_MEDIA_PLAYER 640 /**< Generic Media Player. */
+#define BLE_APPEARANCE_GENERIC_BARCODE_SCANNER 704 /**< Generic Barcode Scanner. */
+#define BLE_APPEARANCE_GENERIC_THERMOMETER 768 /**< Generic Thermometer. */
+#define BLE_APPEARANCE_THERMOMETER_EAR 769 /**< Thermometer: Ear. */
+#define BLE_APPEARANCE_GENERIC_HEART_RATE_SENSOR 832 /**< Generic Heart rate Sensor. */
+#define BLE_APPEARANCE_HEART_RATE_SENSOR_HEART_RATE_BELT 833 /**< Heart Rate Sensor: Heart Rate Belt. */
+#define BLE_APPEARANCE_GENERIC_BLOOD_PRESSURE 896 /**< Generic Blood Pressure. */
+#define BLE_APPEARANCE_BLOOD_PRESSURE_ARM 897 /**< Blood Pressure: Arm. */
+#define BLE_APPEARANCE_BLOOD_PRESSURE_WRIST 898 /**< Blood Pressure: Wrist. */
+#define BLE_APPEARANCE_GENERIC_HID 960 /**< Human Interface Device (HID). */
+#define BLE_APPEARANCE_HID_KEYBOARD 961 /**< Keyboard (HID Subtype). */
+#define BLE_APPEARANCE_HID_MOUSE 962 /**< Mouse (HID Subtype). */
+#define BLE_APPEARANCE_HID_JOYSTICK 963 /**< Joystick (HID Subtype). */
+#define BLE_APPEARANCE_HID_GAMEPAD 964 /**< Gamepad (HID Subtype). */
+#define BLE_APPEARANCE_HID_DIGITIZERSUBTYPE 965 /**< Digitizer Tablet (HID Subtype). */
+#define BLE_APPEARANCE_HID_CARD_READER 966 /**< Card Reader (HID Subtype). */
+#define BLE_APPEARANCE_HID_DIGITAL_PEN 967 /**< Digital Pen (HID Subtype). */
+#define BLE_APPEARANCE_HID_BARCODE 968 /**< Barcode Scanner (HID Subtype). */
+#define BLE_APPEARANCE_GENERIC_GLUCOSE_METER 1024 /**< Generic Glucose Meter. */
+#define BLE_APPEARANCE_GENERIC_RUNNING_WALKING_SENSOR 1088 /**< Generic Running Walking Sensor. */
+#define BLE_APPEARANCE_RUNNING_WALKING_SENSOR_IN_SHOE 1089 /**< Running Walking Sensor: In-Shoe. */
+#define BLE_APPEARANCE_RUNNING_WALKING_SENSOR_ON_SHOE 1090 /**< Running Walking Sensor: On-Shoe. */
+#define BLE_APPEARANCE_RUNNING_WALKING_SENSOR_ON_HIP 1091 /**< Running Walking Sensor: On-Hip. */
+#define BLE_APPEARANCE_GENERIC_CYCLING 1152 /**< Generic Cycling. */
+#define BLE_APPEARANCE_CYCLING_CYCLING_COMPUTER 1153 /**< Cycling: Cycling Computer. */
+#define BLE_APPEARANCE_CYCLING_SPEED_SENSOR 1154 /**< Cycling: Speed Sensor. */
+#define BLE_APPEARANCE_CYCLING_CADENCE_SENSOR 1155 /**< Cycling: Cadence Sensor. */
+#define BLE_APPEARANCE_CYCLING_POWER_SENSOR 1156 /**< Cycling: Power Sensor. */
+#define BLE_APPEARANCE_CYCLING_SPEED_CADENCE_SENSOR 1157 /**< Cycling: Speed and Cadence Sensor. */
+#define BLE_APPEARANCE_GENERIC_PULSE_OXIMETER 3136 /**< Generic Pulse Oximeter. */
+#define BLE_APPEARANCE_PULSE_OXIMETER_FINGERTIP 3137 /**< Fingertip (Pulse Oximeter subtype). */
+#define BLE_APPEARANCE_PULSE_OXIMETER_WRIST_WORN 3138 /**< Wrist Worn(Pulse Oximeter subtype). */
+#define BLE_APPEARANCE_GENERIC_WEIGHT_SCALE 3200 /**< Generic Weight Scale. */
+#define BLE_APPEARANCE_GENERIC_OUTDOOR_SPORTS_ACT 5184 /**< Generic Outdoor Sports Activity. */
+#define BLE_APPEARANCE_OUTDOOR_SPORTS_ACT_LOC_DISP 5185 /**< Location Display Device (Outdoor Sports Activity subtype). */
+#define BLE_APPEARANCE_OUTDOOR_SPORTS_ACT_LOC_AND_NAV_DISP 5186 /**< Location and Navigation Display Device (Outdoor Sports Activity subtype). */
+#define BLE_APPEARANCE_OUTDOOR_SPORTS_ACT_LOC_POD 5187 /**< Location Pod (Outdoor Sports Activity subtype). */
+#define BLE_APPEARANCE_OUTDOOR_SPORTS_ACT_LOC_AND_NAV_POD 5188 /**< Location and Navigation Pod (Outdoor Sports Activity subtype). */
+/** @} */
+
+/** @brief Set .type and .uuid fields of ble_uuid_struct to specified UUID value. */
+#define BLE_UUID_BLE_ASSIGN(instance, value) do {\
+ instance.type = BLE_UUID_TYPE_BLE; \
+ instance.uuid = value;} while(0)
+
+/** @brief Copy type and uuid members from src to dst ble_uuid_t pointer. Both pointers must be valid/non-null. */
+#define BLE_UUID_COPY_PTR(dst, src) do {\
+ (dst)->type = (src)->type; \
+ (dst)->uuid = (src)->uuid;} while(0)
+
+/** @brief Copy type and uuid members from src to dst ble_uuid_t struct. */
+#define BLE_UUID_COPY_INST(dst, src) do {\
+ (dst).type = (src).type; \
+ (dst).uuid = (src).uuid;} while(0)
+
+/** @brief Compare for equality both type and uuid members of two (valid, non-null) ble_uuid_t pointers. */
+#define BLE_UUID_EQ(p_uuid1, p_uuid2) \
+ (((p_uuid1)->type == (p_uuid2)->type) && ((p_uuid1)->uuid == (p_uuid2)->uuid))
+
+/** @brief Compare for difference both type and uuid members of two (valid, non-null) ble_uuid_t pointers. */
+#define BLE_UUID_NEQ(p_uuid1, p_uuid2) \
+ (((p_uuid1)->type != (p_uuid2)->type) || ((p_uuid1)->uuid != (p_uuid2)->uuid))
+
+/** @} */
+
+/** @addtogroup BLE_TYPES_STRUCTURES Structures
+ * @{ */
+
+/** @brief 128 bit UUID values. */
+typedef struct
+{
+ uint8_t uuid128[16]; /**< Little-Endian UUID bytes. */
+} ble_uuid128_t;
+
+/** @brief Bluetooth Low Energy UUID type, encapsulates both 16-bit and 128-bit UUIDs. */
+typedef struct
+{
+ uint16_t uuid; /**< 16-bit UUID value or octets 12-13 of 128-bit UUID. */
+ uint8_t type; /**< UUID type, see @ref BLE_UUID_TYPES. If type is @ref BLE_UUID_TYPE_UNKNOWN, the value of uuid is undefined. */
+} ble_uuid_t;
+
+/**@brief Data structure. */
+typedef struct
+{
+ uint8_t *p_data; /**< Pointer to the data buffer provided to/from the application. */
+ uint16_t len; /**< Length of the data buffer, in bytes. */
+} ble_data_t;
+
+/** @} */
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* BLE_TYPES_H__ */
+
+/**
+ @}
+ @}
+*/
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/softdevice/s132/headers/nrf52/nrf_mbr.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/softdevice/s132/headers/nrf52/nrf_mbr.h
new file mode 100644
index 0000000..cc5971c
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/softdevice/s132/headers/nrf52/nrf_mbr.h
@@ -0,0 +1,241 @@
+/*
+ * Copyright (c) 2014 - 2017, 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ */
+
+/**
+ @defgroup nrf_mbr_api Master Boot Record API
+ @{
+
+ @brief APIs for updating SoftDevice and BootLoader
+
+*/
+
+#ifndef NRF_MBR_H__
+#define NRF_MBR_H__
+
+#include "nrf_svc.h"
+#include <stdint.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** @addtogroup NRF_MBR_DEFINES Defines
+ * @{ */
+
+/**@brief MBR SVC Base number. */
+#define MBR_SVC_BASE (0x18)
+
+/**@brief Page size in words. */
+#define MBR_PAGE_SIZE_IN_WORDS (1024)
+
+/** @brief The size that must be reserved for the MBR when a SoftDevice is written to flash.
+This is the offset where the first byte of the SoftDevice hex file is written.*/
+#define MBR_SIZE (0x1000)
+
+/** @} */
+
+/** @addtogroup NRF_MBR_ENUMS Enumerations
+ * @{ */
+
+/**@brief nRF Master Boot Record API SVC numbers. */
+enum NRF_MBR_SVCS
+{
+ SD_MBR_COMMAND = MBR_SVC_BASE, /**< ::sd_mbr_command */
+};
+
+/**@brief Possible values for ::sd_mbr_command_t.command */
+enum NRF_MBR_COMMANDS
+{
+ SD_MBR_COMMAND_COPY_BL, /**< Copy a new BootLoader. @see ::sd_mbr_command_copy_bl_t*/
+ SD_MBR_COMMAND_COPY_SD, /**< Copy a new SoftDevice. @see ::sd_mbr_command_copy_sd_t*/
+ SD_MBR_COMMAND_INIT_SD, /**< Initialize forwarding interrupts to SD, and run reset function in SD. Does not require any parameters in ::sd_mbr_command_t params.*/
+ SD_MBR_COMMAND_COMPARE, /**< This command works like memcmp. @see ::sd_mbr_command_compare_t*/
+ SD_MBR_COMMAND_VECTOR_TABLE_BASE_SET, /**< Change the address the MBR starts after a reset. @see ::sd_mbr_command_vector_table_base_set_t*/
+ SD_MBR_COMMAND_RESERVED,
+ SD_MBR_COMMAND_IRQ_FORWARD_ADDRESS_SET, /**< Start forwarding all interrupts to this address. @see ::sd_mbr_command_irq_forward_address_set_t*/
+};
+
+/** @} */
+
+/** @addtogroup NRF_MBR_TYPES Types
+ * @{ */
+
+/**@brief This command copies part of a new SoftDevice
+ *
+ * The destination area is erased before copying.
+ * If dst is in the middle of a flash page, that whole flash page will be erased.
+ * If (dst+len) is in the middle of a flash page, that whole flash page will be erased.
+ *
+ * The user of this function is responsible for setting the BPROT registers.
+ *
+ * @retval ::NRF_SUCCESS indicates that the contents of the memory blocks where copied correctly.
+ * @retval ::NRF_ERROR_INTERNAL indicates that the contents of the memory blocks where not verified correctly after copying.
+ */
+typedef struct
+{
+ uint32_t *src; /**< Pointer to the source of data to be copied.*/
+ uint32_t *dst; /**< Pointer to the destination where the content is to be copied.*/
+ uint32_t len; /**< Number of 32 bit words to copy. Must be a multiple of @ref MBR_PAGE_SIZE_IN_WORDS words.*/
+} sd_mbr_command_copy_sd_t;
+
+
+/**@brief This command works like memcmp, but takes the length in words.
+ *
+ * @retval ::NRF_SUCCESS indicates that the contents of both memory blocks are equal.
+ * @retval ::NRF_ERROR_NULL indicates that the contents of the memory blocks are not equal.
+ */
+typedef struct
+{
+ uint32_t *ptr1; /**< Pointer to block of memory. */
+ uint32_t *ptr2; /**< Pointer to block of memory. */
+ uint32_t len; /**< Number of 32 bit words to compare.*/
+} sd_mbr_command_compare_t;
+
+
+/**@brief This command copies a new BootLoader.
+ *
+ * With this command, destination of BootLoader is always the address written in
+ * NRF_UICR->BOOTADDR.
+ *
+ * Destination is erased by this function.
+ * If (destination+bl_len) is in the middle of a flash page, that whole flash page will be erased.
+ *
+ * This function will use PROTENSET to protect the flash that is not intended to be written.
+ *
+ * On success, this function will not return. It will start the new BootLoader from reset-vector as normal.
+ *
+ * @retval ::NRF_ERROR_INTERNAL indicates an internal error that should not happen.
+ * @retval ::NRF_ERROR_FORBIDDEN if NRF_UICR->BOOTADDR is not set.
+ * @retval ::NRF_ERROR_INVALID_LENGTH if parameters attempts to read or write outside flash area.
+ * @retval ::NRF_ERROR_NO_MEM if no parameter page is provided (see SoftDevice Specification for more info)
+ */
+typedef struct
+{
+ uint32_t *bl_src; /**< Pointer to the source of the Bootloader to be be copied.*/
+ uint32_t bl_len; /**< Number of 32 bit words to copy for BootLoader. */
+} sd_mbr_command_copy_bl_t;
+
+/**@brief Change the address the MBR starts after a reset
+ *
+ * Once this function has been called, this address is where the MBR will start to forward
+ * interrupts to after a reset.
+ *
+ * To restore default forwarding this function should be called with @ref address set to 0. The
+ * MBR will then start forwarding interrupts to the address in NFR_UICR->BOOTADDR or to the
+ * SoftDevice if the BOOTADDR is not set.
+ *
+ * On success, this function will not return. It will reset the device.
+ *
+ * @retval ::NRF_ERROR_INTERNAL indicates an internal error that should not happen.
+ * @retval ::NRF_ERROR_INVALID_ADDR if parameter address is outside of the flash size.
+ * @retval ::NRF_ERROR_NO_MEM if no parameter page is provided (see SoftDevice Specification for more info)
+ */
+typedef struct
+{
+ uint32_t address; /**< The base address of the interrupt vector table for forwarded interrupts.*/
+} sd_mbr_command_vector_table_base_set_t;
+
+/**@brief Sets the base address of the interrupt vector table for interrupts forwarded from the MBR
+ *
+ * Unlike sd_mbr_command_vector_table_base_set_t, this function does not reset, and it does not
+ * change where the MBR starts after reset.
+ *
+ * @retval ::NRF_SUCCESS
+ */
+typedef struct
+{
+ uint32_t address; /**< The base address of the interrupt vector table for forwarded interrupts.*/
+} sd_mbr_command_irq_forward_address_set_t;
+
+/**@brief Input structure containing data used when calling ::sd_mbr_command
+ *
+ * Depending on what command value that is set, the corresponding params value type must also be
+ * set. See @ref NRF_MBR_COMMANDS for command types and corresponding params value type. If command
+ * @ref SD_MBR_COMMAND_INIT_SD is set, it is not necessary to set any values under params.
+ */
+typedef struct
+{
+ uint32_t command; /**< Type of command to be issued. See @ref NRF_MBR_COMMANDS. */
+ union
+ {
+ sd_mbr_command_copy_sd_t copy_sd; /**< Parameters for copy SoftDevice.*/
+ sd_mbr_command_compare_t compare; /**< Parameters for verify.*/
+ sd_mbr_command_copy_bl_t copy_bl; /**< Parameters for copy BootLoader. Requires parameter page. */
+ sd_mbr_command_vector_table_base_set_t base_set; /**< Parameters for vector table base set. Requires parameter page.*/
+ sd_mbr_command_irq_forward_address_set_t irq_forward_address_set; /**< Parameters for irq forward address set*/
+ } params; /**< Command parameters. */
+} sd_mbr_command_t;
+
+/** @} */
+
+/** @addtogroup NRF_MBR_FUNCTIONS Functions
+ * @{ */
+
+/**@brief Issue Master Boot Record commands
+ *
+ * Commands used when updating a SoftDevice and bootloader.
+ *
+ * The @ref SD_MBR_COMMAND_COPY_BL and @ref SD_MBR_COMMAND_VECTOR_TABLE_BASE_SET requires
+ * parameters to be retained by the MBR when resetting the IC. This is done in a separate flash
+ * page provided by the application. The UICR register UICR.NRFFW[1] must be set to an address
+ * corresponding to a page in the application flash space. This page will be cleared by the MBR and
+ * used to store the command before reset. When the UICR.NRFFW[1] field is set the page it refers
+ * to must not be used by the application. If the UICR.NRFFW[1] is set to 0xFFFFFFFF (the default)
+ * MBR commands which use flash will be unavailable and return @ref NRF_ERROR_NO_MEM.
+ *
+ * @param[in] param Pointer to a struct describing the command.
+ *
+ * @note For return values, see ::sd_mbr_command_copy_sd_t, ::sd_mbr_command_copy_bl_t,
+ * ::sd_mbr_command_compare_t, ::sd_mbr_command_vector_table_base_set_t,
+ * ::sd_mbr_command_irq_forward_address_set_t
+ *
+ * @retval ::NRF_ERROR_NO_MEM if UICR.NRFFW[1] is not set (i.e. is 0xFFFFFFFF).
+ * @retval ::NRF_ERROR_INVALID_PARAM if an invalid command is given.
+*/
+SVCALL(SD_MBR_COMMAND, uint32_t, sd_mbr_command(sd_mbr_command_t* param));
+
+/** @} */
+
+#ifdef __cplusplus
+}
+#endif
+#endif // NRF_MBR_H__
+
+/**
+ @}
+*/
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/softdevice/s132/headers/nrf_error.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/softdevice/s132/headers/nrf_error.h
new file mode 100644
index 0000000..6badee9
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/softdevice/s132/headers/nrf_error.h
@@ -0,0 +1,90 @@
+/*
+ * Copyright (c) 2014 - 2017, 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ */
+
+ /**
+ @defgroup nrf_error SoftDevice Global Error Codes
+ @{
+
+ @brief Global Error definitions
+*/
+
+/* Header guard */
+#ifndef NRF_ERROR_H__
+#define NRF_ERROR_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** @defgroup NRF_ERRORS_BASE Error Codes Base number definitions
+ * @{ */
+#define NRF_ERROR_BASE_NUM (0x0) ///< Global error base
+#define NRF_ERROR_SDM_BASE_NUM (0x1000) ///< SDM error base
+#define NRF_ERROR_SOC_BASE_NUM (0x2000) ///< SoC error base
+#define NRF_ERROR_STK_BASE_NUM (0x3000) ///< STK error base
+/** @} */
+
+#define NRF_SUCCESS (NRF_ERROR_BASE_NUM + 0) ///< Successful command
+#define NRF_ERROR_SVC_HANDLER_MISSING (NRF_ERROR_BASE_NUM + 1) ///< SVC handler is missing
+#define NRF_ERROR_SOFTDEVICE_NOT_ENABLED (NRF_ERROR_BASE_NUM + 2) ///< SoftDevice has not been enabled
+#define NRF_ERROR_INTERNAL (NRF_ERROR_BASE_NUM + 3) ///< Internal Error
+#define NRF_ERROR_NO_MEM (NRF_ERROR_BASE_NUM + 4) ///< No Memory for operation
+#define NRF_ERROR_NOT_FOUND (NRF_ERROR_BASE_NUM + 5) ///< Not found
+#define NRF_ERROR_NOT_SUPPORTED (NRF_ERROR_BASE_NUM + 6) ///< Not supported
+#define NRF_ERROR_INVALID_PARAM (NRF_ERROR_BASE_NUM + 7) ///< Invalid Parameter
+#define NRF_ERROR_INVALID_STATE (NRF_ERROR_BASE_NUM + 8) ///< Invalid state, operation disallowed in this state
+#define NRF_ERROR_INVALID_LENGTH (NRF_ERROR_BASE_NUM + 9) ///< Invalid Length
+#define NRF_ERROR_INVALID_FLAGS (NRF_ERROR_BASE_NUM + 10) ///< Invalid Flags
+#define NRF_ERROR_INVALID_DATA (NRF_ERROR_BASE_NUM + 11) ///< Invalid Data
+#define NRF_ERROR_DATA_SIZE (NRF_ERROR_BASE_NUM + 12) ///< Invalid Data size
+#define NRF_ERROR_TIMEOUT (NRF_ERROR_BASE_NUM + 13) ///< Operation timed out
+#define NRF_ERROR_NULL (NRF_ERROR_BASE_NUM + 14) ///< Null Pointer
+#define NRF_ERROR_FORBIDDEN (NRF_ERROR_BASE_NUM + 15) ///< Forbidden Operation
+#define NRF_ERROR_INVALID_ADDR (NRF_ERROR_BASE_NUM + 16) ///< Bad Memory Address
+#define NRF_ERROR_BUSY (NRF_ERROR_BASE_NUM + 17) ///< Busy
+#define NRF_ERROR_CONN_COUNT (NRF_ERROR_BASE_NUM + 18) ///< Maximum connection count exceeded.
+#define NRF_ERROR_RESOURCES (NRF_ERROR_BASE_NUM + 19) ///< Not enough resources for operation
+
+#ifdef __cplusplus
+}
+#endif
+#endif // NRF_ERROR_H__
+
+/**
+ @}
+*/
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/softdevice/s132/headers/nrf_error_sdm.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/softdevice/s132/headers/nrf_error_sdm.h
new file mode 100644
index 0000000..530959b
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/softdevice/s132/headers/nrf_error_sdm.h
@@ -0,0 +1,70 @@
+/*
+ * Copyright (c) 2012 - 2017, 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ */
+
+ /**
+ @addtogroup nrf_sdm_api
+ @{
+ @defgroup nrf_sdm_error SoftDevice Manager Error Codes
+ @{
+
+ @brief Error definitions for the SDM API
+*/
+
+/* Header guard */
+#ifndef NRF_ERROR_SDM_H__
+#define NRF_ERROR_SDM_H__
+
+#include "nrf_error.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define NRF_ERROR_SDM_LFCLK_SOURCE_UNKNOWN (NRF_ERROR_SDM_BASE_NUM + 0) ///< Unknown LFCLK source.
+#define NRF_ERROR_SDM_INCORRECT_INTERRUPT_CONFIGURATION (NRF_ERROR_SDM_BASE_NUM + 1) ///< Incorrect interrupt configuration (can be caused by using illegal priority levels, or having enabled SoftDevice interrupts).
+#define NRF_ERROR_SDM_INCORRECT_CLENR0 (NRF_ERROR_SDM_BASE_NUM + 2) ///< Incorrect CLENR0 (can be caused by erroneous SoftDevice flashing).
+
+#ifdef __cplusplus
+}
+#endif
+#endif // NRF_ERROR_SDM_H__
+
+/**
+ @}
+ @}
+*/
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/softdevice/s132/headers/nrf_error_soc.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/softdevice/s132/headers/nrf_error_soc.h
new file mode 100644
index 0000000..1e784b8
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/softdevice/s132/headers/nrf_error_soc.h
@@ -0,0 +1,85 @@
+/*
+ * Copyright (c) 2012 - 2017, 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ */
+
+/**
+ @addtogroup nrf_soc_api
+ @{
+ @defgroup nrf_soc_error SoC Library Error Codes
+ @{
+
+ @brief Error definitions for the SoC library
+
+*/
+
+/* Header guard */
+#ifndef NRF_ERROR_SOC_H__
+#define NRF_ERROR_SOC_H__
+
+#include "nrf_error.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Mutex Errors */
+#define NRF_ERROR_SOC_MUTEX_ALREADY_TAKEN (NRF_ERROR_SOC_BASE_NUM + 0) ///< Mutex already taken
+
+/* NVIC errors */
+#define NRF_ERROR_SOC_NVIC_INTERRUPT_NOT_AVAILABLE (NRF_ERROR_SOC_BASE_NUM + 1) ///< NVIC interrupt not available
+#define NRF_ERROR_SOC_NVIC_INTERRUPT_PRIORITY_NOT_ALLOWED (NRF_ERROR_SOC_BASE_NUM + 2) ///< NVIC interrupt priority not allowed
+#define NRF_ERROR_SOC_NVIC_SHOULD_NOT_RETURN (NRF_ERROR_SOC_BASE_NUM + 3) ///< NVIC should not return
+
+/* Power errors */
+#define NRF_ERROR_SOC_POWER_MODE_UNKNOWN (NRF_ERROR_SOC_BASE_NUM + 4) ///< Power mode unknown
+#define NRF_ERROR_SOC_POWER_POF_THRESHOLD_UNKNOWN (NRF_ERROR_SOC_BASE_NUM + 5) ///< Power POF threshold unknown
+#define NRF_ERROR_SOC_POWER_OFF_SHOULD_NOT_RETURN (NRF_ERROR_SOC_BASE_NUM + 6) ///< Power off should not return
+
+/* Rand errors */
+#define NRF_ERROR_SOC_RAND_NOT_ENOUGH_VALUES (NRF_ERROR_SOC_BASE_NUM + 7) ///< RAND not enough values
+
+/* PPI errors */
+#define NRF_ERROR_SOC_PPI_INVALID_CHANNEL (NRF_ERROR_SOC_BASE_NUM + 8) ///< Invalid PPI Channel
+#define NRF_ERROR_SOC_PPI_INVALID_GROUP (NRF_ERROR_SOC_BASE_NUM + 9) ///< Invalid PPI Group
+
+#ifdef __cplusplus
+}
+#endif
+#endif // NRF_ERROR_SOC_H__
+/**
+ @}
+ @}
+*/
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/softdevice/s132/headers/nrf_nvic.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/softdevice/s132/headers/nrf_nvic.h
new file mode 100644
index 0000000..f5c7e8e
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/softdevice/s132/headers/nrf_nvic.h
@@ -0,0 +1,486 @@
+/*
+ * Copyright (c) 2016 - 2017, 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ */
+
+/**
+ * @defgroup nrf_nvic_api SoftDevice NVIC API
+ * @{
+ *
+ * @note In order to use this module, the following code has to be added to a .c file:
+ * \code
+ * nrf_nvic_state_t nrf_nvic_state = {0};
+ * \endcode
+ *
+ * @note Definitions and declarations starting with __ (double underscore) in this header file are
+ * not intended for direct use by the application.
+ *
+ * @brief APIs for the accessing NVIC when using a SoftDevice.
+ *
+ */
+
+#ifndef NRF_NVIC_H__
+#define NRF_NVIC_H__
+
+#include <stdint.h>
+#include "nrf.h"
+#include "nrf_svc.h"
+#include "nrf_error.h"
+#include "nrf_error_soc.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**@addtogroup NRF_NVIC_DEFINES Defines
+ * @{ */
+
+/**@defgroup NRF_NVIC_ISER_DEFINES SoftDevice NVIC internal definitions
+ * @{ */
+
+#define __NRF_NVIC_NVMC_IRQn (30) /**< The peripheral ID of the NVMC. IRQ numbers are used to identify peripherals, but the NVMC doesn't have an IRQ number in the MDK. */
+
+#define __NRF_NVIC_ISER_COUNT (2) /**< The number of ISER/ICER registers in the NVIC that are used. */
+
+/**@brief Interrupts used by the SoftDevice, with IRQn in the range 0-31. */
+#define __NRF_NVIC_SD_IRQS_0 ((uint32_t)( \
+ (1U << POWER_CLOCK_IRQn) \
+ | (1U << RADIO_IRQn) \
+ | (1U << RTC0_IRQn) \
+ | (1U << TIMER0_IRQn) \
+ | (1U << RNG_IRQn) \
+ | (1U << ECB_IRQn) \
+ | (1U << CCM_AAR_IRQn) \
+ | (1U << TEMP_IRQn) \
+ | (1U << __NRF_NVIC_NVMC_IRQn) \
+ | (1U << (uint32_t)SWI5_IRQn) \
+ ))
+
+/**@brief Interrupts used by the SoftDevice, with IRQn in the range 32-63. */
+#define __NRF_NVIC_SD_IRQS_1 ((uint32_t)0)
+
+/**@brief Interrupts available for to application, with IRQn in the range 0-31. */
+#define __NRF_NVIC_APP_IRQS_0 (~__NRF_NVIC_SD_IRQS_0)
+
+/**@brief Interrupts available for to application, with IRQn in the range 32-63. */
+#define __NRF_NVIC_APP_IRQS_1 (~__NRF_NVIC_SD_IRQS_1)
+
+/**@} */
+
+/**@} */
+
+/**@addtogroup NRF_NVIC_VARIABLES Variables
+ * @{ */
+
+/**@brief Type representing the state struct for the SoftDevice NVIC module. */
+typedef struct
+{
+ uint32_t volatile __irq_masks[__NRF_NVIC_ISER_COUNT]; /**< IRQs enabled by the application in the NVIC. */
+ uint32_t volatile __cr_flag; /**< Non-zero if already in a critical region */
+} nrf_nvic_state_t;
+
+/**@brief Variable keeping the state for the SoftDevice NVIC module. This must be declared in an
+ * application source file. */
+extern nrf_nvic_state_t nrf_nvic_state;
+
+/**@} */
+
+/**@addtogroup NRF_NVIC_INTERNAL_FUNCTIONS SoftDevice NVIC internal functions
+ * @{ */
+
+/**@brief Disables IRQ interrupts globally, including the SoftDevice's interrupts.
+ *
+ * @retval The value of PRIMASK prior to disabling the interrupts.
+ */
+__STATIC_INLINE int __sd_nvic_irq_disable(void);
+
+/**@brief Enables IRQ interrupts globally, including the SoftDevice's interrupts.
+ */
+__STATIC_INLINE void __sd_nvic_irq_enable(void);
+
+/**@brief Checks if IRQn is available to application
+ * @param[in] IRQn IRQ to check
+ *
+ * @retval 1 (true) if the IRQ to check is available to the application
+ */
+__STATIC_INLINE uint32_t __sd_nvic_app_accessible_irq(IRQn_Type IRQn);
+
+/**@brief Checks if priority is available to application
+ * @param[in] priority priority to check
+ *
+ * @retval 1 (true) if the priority to check is available to the application
+ */
+__STATIC_INLINE uint32_t __sd_nvic_is_app_accessible_priority(uint32_t priority);
+
+/**@} */
+
+/**@addtogroup NRF_NVIC_FUNCTIONS SoftDevice NVIC public functions
+ * @{ */
+
+/**@brief Enable External Interrupt.
+ * @note Corresponds to NVIC_EnableIRQ in CMSIS.
+ *
+ * @pre IRQn is valid and not reserved by the stack.
+ *
+ * @param[in] IRQn See the NVIC_EnableIRQ documentation in CMSIS.
+ *
+ * @retval ::NRF_SUCCESS The interrupt was enabled.
+ * @retval ::NRF_ERROR_SOC_NVIC_INTERRUPT_NOT_AVAILABLE The interrupt is not available for the application.
+ * @retval ::NRF_ERROR_SOC_NVIC_INTERRUPT_PRIORITY_NOT_ALLOWED The interrupt has a priority not available for the application.
+ */
+__STATIC_INLINE uint32_t sd_nvic_EnableIRQ(IRQn_Type IRQn);
+
+/**@brief Disable External Interrupt.
+ * @note Corresponds to NVIC_DisableIRQ in CMSIS.
+ *
+ * @pre IRQn is valid and not reserved by the stack.
+ *
+ * @param[in] IRQn See the NVIC_DisableIRQ documentation in CMSIS.
+ *
+ * @retval ::NRF_SUCCESS The interrupt was disabled.
+ * @retval ::NRF_ERROR_SOC_NVIC_INTERRUPT_NOT_AVAILABLE The interrupt is not available for the application.
+ */
+__STATIC_INLINE uint32_t sd_nvic_DisableIRQ(IRQn_Type IRQn);
+
+/**@brief Get Pending Interrupt.
+ * @note Corresponds to NVIC_GetPendingIRQ in CMSIS.
+ *
+ * @pre IRQn is valid and not reserved by the stack.
+ *
+ * @param[in] IRQn See the NVIC_GetPendingIRQ documentation in CMSIS.
+ * @param[out] p_pending_irq Return value from NVIC_GetPendingIRQ.
+ *
+ * @retval ::NRF_SUCCESS The interrupt is available for the application.
+ * @retval ::NRF_ERROR_SOC_NVIC_INTERRUPT_NOT_AVAILABLE IRQn is not available for the application.
+ */
+__STATIC_INLINE uint32_t sd_nvic_GetPendingIRQ(IRQn_Type IRQn, uint32_t * p_pending_irq);
+
+/**@brief Set Pending Interrupt.
+ * @note Corresponds to NVIC_SetPendingIRQ in CMSIS.
+ *
+ * @pre IRQn is valid and not reserved by the stack.
+ *
+ * @param[in] IRQn See the NVIC_SetPendingIRQ documentation in CMSIS.
+ *
+ * @retval ::NRF_SUCCESS The interrupt is set pending.
+ * @retval ::NRF_ERROR_SOC_NVIC_INTERRUPT_NOT_AVAILABLE IRQn is not available for the application.
+ */
+__STATIC_INLINE uint32_t sd_nvic_SetPendingIRQ(IRQn_Type IRQn);
+
+/**@brief Clear Pending Interrupt.
+ * @note Corresponds to NVIC_ClearPendingIRQ in CMSIS.
+ *
+ * @pre IRQn is valid and not reserved by the stack.
+ *
+ * @param[in] IRQn See the NVIC_ClearPendingIRQ documentation in CMSIS.
+ *
+ * @retval ::NRF_SUCCESS The interrupt pending flag is cleared.
+ * @retval ::NRF_ERROR_SOC_NVIC_INTERRUPT_NOT_AVAILABLE IRQn is not available for the application.
+ */
+__STATIC_INLINE uint32_t sd_nvic_ClearPendingIRQ(IRQn_Type IRQn);
+
+/**@brief Set Interrupt Priority.
+ * @note Corresponds to NVIC_SetPriority in CMSIS.
+ *
+ * @pre IRQn is valid and not reserved by the stack.
+ * @pre Priority is valid and not reserved by the stack.
+ *
+ * @param[in] IRQn See the NVIC_SetPriority documentation in CMSIS.
+ * @param[in] priority A valid IRQ priority for use by the application.
+ *
+ * @retval ::NRF_SUCCESS The interrupt and priority level is available for the application.
+ * @retval ::NRF_ERROR_SOC_NVIC_INTERRUPT_NOT_AVAILABLE IRQn is not available for the application.
+ * @retval ::NRF_ERROR_SOC_NVIC_INTERRUPT_PRIORITY_NOT_ALLOWED The interrupt priority is not available for the application.
+ */
+__STATIC_INLINE uint32_t sd_nvic_SetPriority(IRQn_Type IRQn, uint32_t priority);
+
+/**@brief Get Interrupt Priority.
+ * @note Corresponds to NVIC_GetPriority in CMSIS.
+ *
+ * @pre IRQn is valid and not reserved by the stack.
+ *
+ * @param[in] IRQn See the NVIC_GetPriority documentation in CMSIS.
+ * @param[out] p_priority Return value from NVIC_GetPriority.
+ *
+ * @retval ::NRF_SUCCESS The interrupt priority is returned in p_priority.
+ * @retval ::NRF_ERROR_SOC_NVIC_INTERRUPT_NOT_AVAILABLE - IRQn is not available for the application.
+ */
+__STATIC_INLINE uint32_t sd_nvic_GetPriority(IRQn_Type IRQn, uint32_t * p_priority);
+
+/**@brief System Reset.
+ * @note Corresponds to NVIC_SystemReset in CMSIS.
+ *
+ * @retval ::NRF_ERROR_SOC_NVIC_SHOULD_NOT_RETURN
+ */
+__STATIC_INLINE uint32_t sd_nvic_SystemReset(void);
+
+/**@brief Enter critical region.
+ *
+ * @post Application interrupts will be disabled.
+ * @note sd_nvic_critical_region_enter() and ::sd_nvic_critical_region_exit() must be called in matching pairs inside each
+ * execution context
+ * @sa sd_nvic_critical_region_exit
+ *
+ * @param[out] p_is_nested_critical_region If 1, the application is now in a nested critical region.
+ *
+ * @retval ::NRF_SUCCESS
+ */
+__STATIC_INLINE uint32_t sd_nvic_critical_region_enter(uint8_t * p_is_nested_critical_region);
+
+/**@brief Exit critical region.
+ *
+ * @pre Application has entered a critical region using ::sd_nvic_critical_region_enter.
+ * @post If not in a nested critical region, the application interrupts will restored to the state before ::sd_nvic_critical_region_enter was called.
+ *
+ * @param[in] is_nested_critical_region If this is set to 1, the critical region won't be exited. @sa sd_nvic_critical_region_enter.
+ *
+ * @retval ::NRF_SUCCESS
+ */
+__STATIC_INLINE uint32_t sd_nvic_critical_region_exit(uint8_t is_nested_critical_region);
+
+/**@} */
+
+#ifndef SUPPRESS_INLINE_IMPLEMENTATION
+
+__STATIC_INLINE int __sd_nvic_irq_disable(void)
+{
+ int pm = __get_PRIMASK();
+ __disable_irq();
+ return pm;
+}
+
+__STATIC_INLINE void __sd_nvic_irq_enable(void)
+{
+ __enable_irq();
+}
+
+__STATIC_INLINE uint32_t __sd_nvic_app_accessible_irq(IRQn_Type IRQn)
+{
+ if (IRQn < 32)
+ {
+ return ((1UL<<IRQn) & __NRF_NVIC_APP_IRQS_0) != 0;
+ }
+ else if (IRQn < 64)
+ {
+ return ((1UL<<(IRQn-32)) & __NRF_NVIC_APP_IRQS_1) != 0;
+ }
+ else
+ {
+ return 1;
+ }
+}
+
+__STATIC_INLINE uint32_t __sd_nvic_is_app_accessible_priority(uint32_t priority)
+{
+ if(priority >= (1 << __NVIC_PRIO_BITS))
+ {
+ return 0;
+ }
+ if( priority == 0
+ || priority == 1
+ || priority == 4
+ )
+ {
+ return 0;
+ }
+ return 1;
+}
+
+
+__STATIC_INLINE uint32_t sd_nvic_EnableIRQ(IRQn_Type IRQn)
+{
+ if (!__sd_nvic_app_accessible_irq(IRQn))
+ {
+ return NRF_ERROR_SOC_NVIC_INTERRUPT_NOT_AVAILABLE;
+ }
+ if (!__sd_nvic_is_app_accessible_priority(NVIC_GetPriority(IRQn)))
+ {
+ return NRF_ERROR_SOC_NVIC_INTERRUPT_PRIORITY_NOT_ALLOWED;
+ }
+
+ if (nrf_nvic_state.__cr_flag)
+ {
+ nrf_nvic_state.__irq_masks[(uint32_t)((int32_t)IRQn) >> 5] |= (uint32_t)(1 << ((uint32_t)((int32_t)IRQn) & (uint32_t)0x1F));
+ }
+ else
+ {
+ NVIC_EnableIRQ(IRQn);
+ }
+ return NRF_SUCCESS;
+}
+
+__STATIC_INLINE uint32_t sd_nvic_DisableIRQ(IRQn_Type IRQn)
+{
+ if (!__sd_nvic_app_accessible_irq(IRQn))
+ {
+ return NRF_ERROR_SOC_NVIC_INTERRUPT_NOT_AVAILABLE;
+ }
+
+ if (nrf_nvic_state.__cr_flag)
+ {
+ nrf_nvic_state.__irq_masks[(uint32_t)((int32_t)IRQn) >> 5] &= ~(1UL << ((uint32_t)(IRQn) & 0x1F));
+ }
+ else
+ {
+ NVIC_DisableIRQ(IRQn);
+ }
+
+ return NRF_SUCCESS;
+}
+
+__STATIC_INLINE uint32_t sd_nvic_GetPendingIRQ(IRQn_Type IRQn, uint32_t * p_pending_irq)
+{
+ if (__sd_nvic_app_accessible_irq(IRQn))
+ {
+ *p_pending_irq = NVIC_GetPendingIRQ(IRQn);
+ return NRF_SUCCESS;
+ }
+ else
+ {
+ return NRF_ERROR_SOC_NVIC_INTERRUPT_NOT_AVAILABLE;
+ }
+}
+
+__STATIC_INLINE uint32_t sd_nvic_SetPendingIRQ(IRQn_Type IRQn)
+{
+ if (__sd_nvic_app_accessible_irq(IRQn))
+ {
+ NVIC_SetPendingIRQ(IRQn);
+ return NRF_SUCCESS;
+ }
+ else
+ {
+ return NRF_ERROR_SOC_NVIC_INTERRUPT_NOT_AVAILABLE;
+ }
+}
+
+__STATIC_INLINE uint32_t sd_nvic_ClearPendingIRQ(IRQn_Type IRQn)
+{
+ if (__sd_nvic_app_accessible_irq(IRQn))
+ {
+ NVIC_ClearPendingIRQ(IRQn);
+ return NRF_SUCCESS;
+ }
+ else
+ {
+ return NRF_ERROR_SOC_NVIC_INTERRUPT_NOT_AVAILABLE;
+ }
+}
+
+__STATIC_INLINE uint32_t sd_nvic_SetPriority(IRQn_Type IRQn, uint32_t priority)
+{
+ if (!__sd_nvic_app_accessible_irq(IRQn))
+ {
+ return NRF_ERROR_SOC_NVIC_INTERRUPT_NOT_AVAILABLE;
+ }
+
+ if (!__sd_nvic_is_app_accessible_priority(priority))
+ {
+ return NRF_ERROR_SOC_NVIC_INTERRUPT_PRIORITY_NOT_ALLOWED;
+ }
+
+ NVIC_SetPriority(IRQn, (uint32_t)priority);
+ return NRF_SUCCESS;
+}
+
+__STATIC_INLINE uint32_t sd_nvic_GetPriority(IRQn_Type IRQn, uint32_t * p_priority)
+{
+ if (__sd_nvic_app_accessible_irq(IRQn))
+ {
+ *p_priority = (NVIC_GetPriority(IRQn) & 0xFF);
+ return NRF_SUCCESS;
+ }
+ else
+ {
+ return NRF_ERROR_SOC_NVIC_INTERRUPT_NOT_AVAILABLE;
+ }
+}
+
+__STATIC_INLINE uint32_t sd_nvic_SystemReset(void)
+{
+ NVIC_SystemReset();
+ return NRF_ERROR_SOC_NVIC_SHOULD_NOT_RETURN;
+}
+
+__STATIC_INLINE uint32_t sd_nvic_critical_region_enter(uint8_t * p_is_nested_critical_region)
+{
+ int was_masked = __sd_nvic_irq_disable();
+ if (!nrf_nvic_state.__cr_flag)
+ {
+ nrf_nvic_state.__cr_flag = 1;
+ nrf_nvic_state.__irq_masks[0] = ( NVIC->ICER[0] & __NRF_NVIC_APP_IRQS_0 );
+ NVIC->ICER[0] = __NRF_NVIC_APP_IRQS_0;
+ nrf_nvic_state.__irq_masks[1] = ( NVIC->ICER[1] & __NRF_NVIC_APP_IRQS_1 );
+ NVIC->ICER[1] = __NRF_NVIC_APP_IRQS_1;
+ *p_is_nested_critical_region = 0;
+ }
+ else
+ {
+ *p_is_nested_critical_region = 1;
+ }
+ if (!was_masked)
+ {
+ __sd_nvic_irq_enable();
+ }
+ return NRF_SUCCESS;
+}
+
+__STATIC_INLINE uint32_t sd_nvic_critical_region_exit(uint8_t is_nested_critical_region)
+{
+ if (nrf_nvic_state.__cr_flag && (is_nested_critical_region == 0))
+ {
+ int was_masked = __sd_nvic_irq_disable();
+ NVIC->ISER[0] = nrf_nvic_state.__irq_masks[0];
+ NVIC->ISER[1] = nrf_nvic_state.__irq_masks[1];
+ nrf_nvic_state.__cr_flag = 0;
+ if (!was_masked)
+ {
+ __sd_nvic_irq_enable();
+ }
+ }
+
+ return NRF_SUCCESS;
+}
+
+#endif /* SUPPRESS_INLINE_IMPLEMENTATION */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // NRF_NVIC_H__
+
+/**@} */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/softdevice/s132/headers/nrf_sd_def.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/softdevice/s132/headers/nrf_sd_def.h
new file mode 100644
index 0000000..c9ab241
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/softdevice/s132/headers/nrf_sd_def.h
@@ -0,0 +1,59 @@
+/**
+ * Copyright (c) 2015 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#ifndef NRF_SD_DEF_H__
+#define NRF_SD_DEF_H__
+
+#include <stdint.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define SD_PPI_CHANNELS_USED 0xFFFE0000uL /**< PPI channels utilized by SotfDevice (not available to the application). */
+#define SD_PPI_GROUPS_USED 0x0000000CuL /**< PPI groups utilized by SoftDevice (not available to the application). */
+#define SD_TIMERS_USED 0x00000001uL /**< Timers used by SoftDevice. */
+#define SD_SWI_USED 0x0000003CuL /**< Software interrupts used by SoftDevice */
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* NRF_SD_DEF_H__ */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/softdevice/s132/headers/nrf_sdm.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/softdevice/s132/headers/nrf_sdm.h
new file mode 100644
index 0000000..8c48d93
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/softdevice/s132/headers/nrf_sdm.h
@@ -0,0 +1,358 @@
+/*
+ * Copyright (c) 2015 - 2017, 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ */
+
+/**
+ @defgroup nrf_sdm_api SoftDevice Manager API
+ @{
+
+ @brief APIs for SoftDevice management.
+
+*/
+
+#ifndef NRF_SDM_H__
+#define NRF_SDM_H__
+
+#include <stdint.h>
+#include "nrf.h"
+#include "nrf_svc.h"
+#include "nrf_error.h"
+#include "nrf_error_sdm.h"
+#include "nrf_soc.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** @addtogroup NRF_SDM_DEFINES Defines
+ * @{ */
+#ifdef NRFSOC_DOXYGEN
+/// Declared in nrf_mbr.h
+#define MBR_SIZE 0
+#warning test
+#endif
+
+/** @brief The major version for the SoftDevice binary distributed with this header file. */
+#define SD_MAJOR_VERSION (6)
+
+/** @brief The minor version for the SoftDevice binary distributed with this header file. */
+#define SD_MINOR_VERSION (0)
+
+/** @brief The bugfix version for the SoftDevice binary distributed with this header file. */
+#define SD_BUGFIX_VERSION (0)
+
+/** @brief The full version number for the SoftDevice binary this header file was distributed
+ * with, as 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 SD_VERSION (SD_MAJOR_VERSION * 1000000 + SD_MINOR_VERSION * 1000 + SD_BUGFIX_VERSION)
+
+/** @brief SoftDevice Manager SVC Base number. */
+#define SDM_SVC_BASE 0x10
+
+/** @brief SoftDevice unique string size in bytes. */
+#define SD_UNIQUE_STR_SIZE 20
+
+/** @brief Invalid info field. Returned when an info field does not exist. */
+#define SDM_INFO_FIELD_INVALID (0)
+
+/** @brief Defines the SoftDevice Information Structure location (address) as an offset from
+the start of the SoftDevice (without MBR)*/
+#define SOFTDEVICE_INFO_STRUCT_OFFSET (0x2000)
+
+/** @brief Defines the absolute SoftDevice Information Structure location (address) when the
+ * SoftDevice is installed just above the MBR (the usual case). */
+#define SOFTDEVICE_INFO_STRUCT_ADDRESS (SOFTDEVICE_INFO_STRUCT_OFFSET + MBR_SIZE)
+
+/** @brief Defines the offset for the SoftDevice Information Structure size value relative to the
+ * SoftDevice base address. The size value is of type uint8_t. */
+#define SD_INFO_STRUCT_SIZE_OFFSET (SOFTDEVICE_INFO_STRUCT_OFFSET)
+
+/** @brief Defines the offset for the SoftDevice size value relative to the SoftDevice base address.
+ * The size value is of type uint32_t. */
+#define SD_SIZE_OFFSET (SOFTDEVICE_INFO_STRUCT_OFFSET + 0x08)
+
+/** @brief Defines the offset for FWID value relative to the SoftDevice base address. The FWID value
+ * is of type uint16_t. */
+#define SD_FWID_OFFSET (SOFTDEVICE_INFO_STRUCT_OFFSET + 0x0C)
+
+/** @brief Defines the offset for the SoftDevice ID relative to the SoftDevice base address. The ID
+ * is of type uint32_t. */
+#define SD_ID_OFFSET (SOFTDEVICE_INFO_STRUCT_OFFSET + 0x10)
+
+/** @brief Defines the offset for the SoftDevice version relative to the SoftDevice base address in
+ * the same format as @ref SD_VERSION, stored as an uint32_t. */
+#define SD_VERSION_OFFSET (SOFTDEVICE_INFO_STRUCT_OFFSET + 0x14)
+
+/** @brief Defines the offset for the SoftDevice unique string relative to the SoftDevice base address.
+ * The SD_UNIQUE_STR is stored as an array of uint8_t. The size of array is @ref SD_UNIQUE_STR_SIZE.
+ */
+#define SD_UNIQUE_STR_OFFSET (SOFTDEVICE_INFO_STRUCT_OFFSET + 0x18)
+
+/** @brief Defines a macro for retrieving the actual SoftDevice Information Structure size value
+ * from a given base address. Use @ref MBR_SIZE as the argument when the SoftDevice is
+ * installed just above the MBR (the usual case). */
+#define SD_INFO_STRUCT_SIZE_GET(baseaddr) (*((uint8_t *) ((baseaddr) + SD_INFO_STRUCT_SIZE_OFFSET)))
+
+/** @brief Defines a macro for retrieving the actual SoftDevice size value from a given base
+ * address. Use @ref MBR_SIZE as the argument when the SoftDevice is installed just above
+ * the MBR (the usual case). */
+#define SD_SIZE_GET(baseaddr) (*((uint32_t *) ((baseaddr) + SD_SIZE_OFFSET)))
+
+/** @brief Defines a macro for retrieving the actual FWID value from a given base address. Use
+ * @ref MBR_SIZE as the argument when the SoftDevice is installed just above the MBR (the usual
+ * case). */
+#define SD_FWID_GET(baseaddr) (*((uint16_t *) ((baseaddr) + SD_FWID_OFFSET)))
+
+/** @brief Defines a macro for retrieving the actual SoftDevice ID from a given base address. Use
+ * @ref MBR_SIZE as the argument when the SoftDevice is installed just above the MBR (the
+ * usual case). */
+#define SD_ID_GET(baseaddr) ((SD_INFO_STRUCT_SIZE_GET(baseaddr) > (SD_ID_OFFSET - SOFTDEVICE_INFO_STRUCT_OFFSET)) \
+ ? (*((uint32_t *) ((baseaddr) + SD_ID_OFFSET))) : SDM_INFO_FIELD_INVALID)
+
+/** @brief Defines a macro for retrieving the actual SoftDevice version from a given base address.
+ * Use @ref MBR_SIZE as the argument when the SoftDevice is installed just above the MBR
+ * (the usual case). */
+#define SD_VERSION_GET(baseaddr) ((SD_INFO_STRUCT_SIZE_GET(baseaddr) > (SD_VERSION_OFFSET - SOFTDEVICE_INFO_STRUCT_OFFSET)) \
+ ? (*((uint32_t *) ((baseaddr) + SD_VERSION_OFFSET))) : SDM_INFO_FIELD_INVALID)
+
+/** @brief Defines a macro for retrieving the address of SoftDevice unique str based on a given base address.
+ * Use @ref MBR_SIZE as the argument when the SoftDevice is installed just above the MBR
+ * (the usual case). */
+#define SD_UNIQUE_STR_ADDR_GET(baseaddr) ((SD_INFO_STRUCT_SIZE_GET(baseaddr) > (SD_UNIQUE_STR_OFFSET - SOFTDEVICE_INFO_STRUCT_OFFSET)) \
+ ? (((uint8_t *) ((baseaddr) + SD_UNIQUE_STR_OFFSET))) : SDM_INFO_FIELD_INVALID)
+
+/**@defgroup NRF_FAULT_ID_RANGES Fault ID ranges
+ * @{ */
+#define NRF_FAULT_ID_SD_RANGE_START 0x00000000 /**< SoftDevice ID range start. */
+#define NRF_FAULT_ID_APP_RANGE_START 0x00001000 /**< Application ID range start. */
+/**@} */
+
+/**@defgroup NRF_FAULT_IDS Fault ID types
+ * @{ */
+#define NRF_FAULT_ID_SD_ASSERT (NRF_FAULT_ID_SD_RANGE_START + 1) /**< SoftDevice assertion. The info parameter is reserved for future used. */
+#define NRF_FAULT_ID_APP_MEMACC (NRF_FAULT_ID_APP_RANGE_START + 1) /**< Application invalid memory access. The info parameter will contain 0x00000000,
+ in case of SoftDevice RAM access violation. In case of SoftDevice peripheral
+ register violation the info parameter will contain the sub-region number of
+ PREGION[0], on whose address range the disallowed write access caused the
+ memory access fault. */
+/**@} */
+
+/** @} */
+
+/** @addtogroup NRF_SDM_ENUMS Enumerations
+ * @{ */
+
+/**@brief nRF SoftDevice Manager API SVC numbers. */
+enum NRF_SD_SVCS
+{
+ SD_SOFTDEVICE_ENABLE = SDM_SVC_BASE, /**< ::sd_softdevice_enable */
+ SD_SOFTDEVICE_DISABLE, /**< ::sd_softdevice_disable */
+ SD_SOFTDEVICE_IS_ENABLED, /**< ::sd_softdevice_is_enabled */
+ SD_SOFTDEVICE_VECTOR_TABLE_BASE_SET, /**< ::sd_softdevice_vector_table_base_set */
+ SVC_SDM_LAST /**< Placeholder for last SDM SVC */
+};
+
+/** @} */
+
+/** @addtogroup NRF_SDM_DEFINES Defines
+ * @{ */
+
+/**@defgroup NRF_CLOCK_LF_ACCURACY Clock accuracy
+ * @{ */
+
+#define NRF_CLOCK_LF_ACCURACY_250_PPM (0) /**< Default: 250 ppm */
+#define NRF_CLOCK_LF_ACCURACY_500_PPM (1) /**< 500 ppm */
+#define NRF_CLOCK_LF_ACCURACY_150_PPM (2) /**< 150 ppm */
+#define NRF_CLOCK_LF_ACCURACY_100_PPM (3) /**< 100 ppm */
+#define NRF_CLOCK_LF_ACCURACY_75_PPM (4) /**< 75 ppm */
+#define NRF_CLOCK_LF_ACCURACY_50_PPM (5) /**< 50 ppm */
+#define NRF_CLOCK_LF_ACCURACY_30_PPM (6) /**< 30 ppm */
+#define NRF_CLOCK_LF_ACCURACY_20_PPM (7) /**< 20 ppm */
+#define NRF_CLOCK_LF_ACCURACY_10_PPM (8) /**< 10 ppm */
+#define NRF_CLOCK_LF_ACCURACY_5_PPM (9) /**< 5 ppm */
+#define NRF_CLOCK_LF_ACCURACY_2_PPM (10) /**< 2 ppm */
+#define NRF_CLOCK_LF_ACCURACY_1_PPM (11) /**< 1 ppm */
+
+/** @} */
+
+/**@defgroup NRF_CLOCK_LF_SRC Possible LFCLK oscillator sources
+ * @{ */
+
+#define NRF_CLOCK_LF_SRC_RC (0) /**< LFCLK RC oscillator. */
+#define NRF_CLOCK_LF_SRC_XTAL (1) /**< LFCLK crystal oscillator. */
+#define NRF_CLOCK_LF_SRC_SYNTH (2) /**< LFCLK Synthesized from HFCLK. */
+
+/** @} */
+
+/** @} */
+
+/** @addtogroup NRF_SDM_TYPES Types
+ * @{ */
+
+/**@brief Type representing LFCLK oscillator source. */
+typedef struct
+{
+ uint8_t source; /**< LF oscillator clock source, see @ref NRF_CLOCK_LF_SRC. */
+ uint8_t rc_ctiv; /**< Only for ::NRF_CLOCK_LF_SRC_RC: Calibration timer interval in 1/4 second
+ units (nRF52: 1-32).
+ @note To avoid excessive clock drift, 0.5 degrees Celsius is the
+ maximum temperature change allowed in one calibration timer
+ interval. The interval should be selected to ensure this.
+
+ @note Must be 0 if source is not ::NRF_CLOCK_LF_SRC_RC. */
+ uint8_t rc_temp_ctiv; /**< Only for ::NRF_CLOCK_LF_SRC_RC: How often (in number of calibration
+ intervals) the RC oscillator shall be calibrated if the temperature
+ hasn't changed.
+ 0: Always calibrate even if the temperature hasn't changed.
+ 1: Only calibrate if the temperature has changed (legacy - nRF51 only).
+ 2-33: Check the temperature and only calibrate if it has changed,
+ however calibration will take place every rc_temp_ctiv
+ intervals in any case.
+
+ @note Must be 0 if source is not ::NRF_CLOCK_LF_SRC_RC.
+
+ @note For nRF52, the application must ensure calibration at least once
+ every 8 seconds to ensure +/-500 ppm clock stability. The
+ recommended configuration for ::NRF_CLOCK_LF_SRC_RC on nRF52 is
+ rc_ctiv=16 and rc_temp_ctiv=2. This will ensure calibration at
+ least once every 8 seconds and for temperature changes of 0.5
+ degrees Celsius every 4 seconds. See the Product Specification
+ for the nRF52 device being used for more information.*/
+ uint8_t accuracy; /**< External clock accuracy used in the LL to compute timing
+ windows, see @ref NRF_CLOCK_LF_ACCURACY.*/
+} nrf_clock_lf_cfg_t;
+
+/**@brief Fault Handler type.
+ *
+ * When certain unrecoverable errors occur within the application or SoftDevice the fault handler will be called back.
+ * The protocol stack will be in an undefined state when this happens and the only way to recover will be to
+ * perform a reset, using e.g. CMSIS NVIC_SystemReset().
+ * If the application returns from the fault handler the SoftDevice will call NVIC_SystemReset().
+ *
+ * @note This callback is executed in HardFault context, thus SVC functions cannot be called from the fault callback.
+ *
+ * @param[in] id Fault identifier. See @ref NRF_FAULT_IDS.
+ * @param[in] pc The program counter of the instruction that triggered the fault.
+ * @param[in] info Optional additional information regarding the fault. Refer to each Fault identifier for details.
+ *
+ * @note When id is set to @ref NRF_FAULT_ID_APP_MEMACC, pc will contain the address of the instruction being executed at the time when
+ * the fault is detected by the CPU. The CPU program counter may have advanced up to 2 instructions (no branching) after the one that triggered the fault.
+ */
+typedef void (*nrf_fault_handler_t)(uint32_t id, uint32_t pc, uint32_t info);
+
+/** @} */
+
+/** @addtogroup NRF_SDM_FUNCTIONS Functions
+ * @{ */
+
+/**@brief Enables the SoftDevice and by extension the protocol stack.
+ *
+ * @note Some care must be taken if a low frequency clock source is already running when calling this function:
+ * If the LF clock has a different source then the one currently running, it will be stopped. Then, the new
+ * clock source will be started.
+ *
+ * @note This function has no effect when returning with an error.
+ *
+ * @post If return code is ::NRF_SUCCESS
+ * - SoC library and protocol stack APIs are made available.
+ * - A portion of RAM will be unavailable (see relevant SDS documentation).
+ * - Some peripherals will be unavailable or available only through the SoC API (see relevant SDS documentation).
+ * - Interrupts will not arrive from protected peripherals or interrupts.
+ * - nrf_nvic_ functions must be used instead of CMSIS NVIC_ functions for reliable usage of the SoftDevice.
+ * - Interrupt latency may be affected by the SoftDevice (see relevant SDS documentation).
+ * - Chosen low frequency clock source will be running.
+ *
+ * @param p_clock_lf_cfg Low frequency clock source and accuracy.
+ If NULL the clock will be configured as an RC source with rc_ctiv = 16 and .rc_temp_ctiv = 2
+ In the case of XTAL source, the PPM accuracy of the chosen clock source must be greater than or equal to the actual characteristics of your XTAL clock.
+ * @param fault_handler Callback to be invoked in case of fault, cannot be NULL.
+ *
+ * @retval ::NRF_SUCCESS
+ * @retval ::NRF_ERROR_INVALID_ADDR Invalid or NULL pointer supplied.
+ * @retval ::NRF_ERROR_INVALID_STATE SoftDevice is already enabled, and the clock source and fault handler cannot be updated.
+ * @retval ::NRF_ERROR_SDM_INCORRECT_INTERRUPT_CONFIGURATION SoftDevice interrupt is already enabled, or an enabled interrupt has an illegal priority level.
+ * @retval ::NRF_ERROR_SDM_LFCLK_SOURCE_UNKNOWN Unknown low frequency clock source selected.
+ * @retval ::NRF_ERROR_INVALID_PARAM Invalid clock source configuration supplied in p_clock_lf_cfg.
+ */
+SVCALL(SD_SOFTDEVICE_ENABLE, uint32_t, sd_softdevice_enable(nrf_clock_lf_cfg_t const * p_clock_lf_cfg, nrf_fault_handler_t fault_handler));
+
+
+/**@brief Disables the SoftDevice and by extension the protocol stack.
+ *
+ * Idempotent function to disable the SoftDevice.
+ *
+ * @post SoC library and protocol stack APIs are made unavailable.
+ * @post All interrupts that was protected by the SoftDevice will be disabled and initialized to priority 0 (highest).
+ * @post All peripherals used by the SoftDevice will be reset to default values.
+ * @post All of RAM become available.
+ * @post All interrupts are forwarded to the application.
+ * @post LFCLK source chosen in ::sd_softdevice_enable will be left running.
+ *
+ * @retval ::NRF_SUCCESS
+ */
+SVCALL(SD_SOFTDEVICE_DISABLE, uint32_t, sd_softdevice_disable(void));
+
+/**@brief Check if the SoftDevice is enabled.
+ *
+ * @param[out] p_softdevice_enabled If the SoftDevice is enabled: 1 else 0.
+ *
+ * @retval ::NRF_SUCCESS
+ */
+SVCALL(SD_SOFTDEVICE_IS_ENABLED, uint32_t, sd_softdevice_is_enabled(uint8_t * p_softdevice_enabled));
+
+/**@brief Sets the base address of the interrupt vector table for interrupts forwarded from the SoftDevice
+ *
+ * This function is only intended to be called when a bootloader is enabled.
+ *
+ * @param[in] address The base address of the interrupt vector table for forwarded interrupts.
+
+ * @retval ::NRF_SUCCESS
+ */
+SVCALL(SD_SOFTDEVICE_VECTOR_TABLE_BASE_SET, uint32_t, sd_softdevice_vector_table_base_set(uint32_t address));
+
+/** @} */
+
+#ifdef __cplusplus
+}
+#endif
+#endif // NRF_SDM_H__
+
+/**
+ @}
+*/
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/softdevice/s132/headers/nrf_soc.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/softdevice/s132/headers/nrf_soc.h
new file mode 100644
index 0000000..2c4d958
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/softdevice/s132/headers/nrf_soc.h
@@ -0,0 +1,964 @@
+/*
+ * Copyright (c) 2015 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ */
+
+/**
+ * @defgroup nrf_soc_api SoC Library API
+ * @{
+ *
+ * @brief APIs for the SoC library.
+ *
+ */
+
+#ifndef NRF_SOC_H__
+#define NRF_SOC_H__
+
+#include <stdint.h>
+#include "nrf.h"
+#include "nrf_svc.h"
+#include "nrf_error.h"
+#include "nrf_error_soc.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**@addtogroup NRF_SOC_DEFINES Defines
+ * @{ */
+
+/**@brief The number of the lowest SVC number reserved for the SoC library. */
+#define SOC_SVC_BASE (0x20) /**< Base value for SVCs that are available when the SoftDevice is disabled. */
+#define SOC_SVC_BASE_NOT_AVAILABLE (0x2C) /**< Base value for SVCs that are not available when the SoftDevice is disabled. */
+
+/**@brief Guaranteed time for application to process radio inactive notification. */
+#define NRF_RADIO_NOTIFICATION_INACTIVE_GUARANTEED_TIME_US (62)
+
+/**@brief The minimum allowed timeslot extension time. */
+#define NRF_RADIO_MINIMUM_TIMESLOT_LENGTH_EXTENSION_TIME_US (200)
+
+/**@brief The maximum processing time to handle a timeslot extension. */
+#define NRF_RADIO_MAX_EXTENSION_PROCESSING_TIME_US (17)
+
+/**@brief The latest time before the end of a timeslot the timeslot can be extended. */
+#define NRF_RADIO_MIN_EXTENSION_MARGIN_US (79)
+
+#define SOC_ECB_KEY_LENGTH (16) /**< ECB key length. */
+#define SOC_ECB_CLEARTEXT_LENGTH (16) /**< ECB cleartext length. */
+#define SOC_ECB_CIPHERTEXT_LENGTH (SOC_ECB_CLEARTEXT_LENGTH) /**< ECB ciphertext length. */
+
+#define SD_EVT_IRQn (SWI2_IRQn) /**< SoftDevice Event IRQ number. Used for both protocol events and SoC events. */
+#define SD_EVT_IRQHandler (SWI2_IRQHandler) /**< SoftDevice Event IRQ handler. Used for both protocol events and SoC events.
+ The default interrupt priority for this handler is set to 4 */
+#define RADIO_NOTIFICATION_IRQn (SWI1_IRQn) /**< The radio notification IRQ number. */
+#define RADIO_NOTIFICATION_IRQHandler (SWI1_IRQHandler) /**< The radio notification IRQ handler.
+ The default interrupt priority for this handler is set to 4 */
+#define NRF_RADIO_LENGTH_MIN_US (100) /**< The shortest allowed radio timeslot, in microseconds. */
+#define NRF_RADIO_LENGTH_MAX_US (100000) /**< The longest allowed radio timeslot, in microseconds. */
+
+#define NRF_RADIO_DISTANCE_MAX_US (128000000UL - 1UL) /**< The longest timeslot distance, in microseconds, allowed for the distance parameter (see @ref nrf_radio_request_normal_t) in the request. */
+
+#define NRF_RADIO_EARLIEST_TIMEOUT_MAX_US (128000000UL - 1UL) /**< The longest timeout, in microseconds, allowed when requesting the earliest possible timeslot. */
+
+#define NRF_RADIO_START_JITTER_US (2) /**< The maximum jitter in @ref NRF_RADIO_CALLBACK_SIGNAL_TYPE_START relative to the requested start time. */
+
+/**@} */
+
+/**@addtogroup NRF_SOC_ENUMS Enumerations
+ * @{ */
+
+/**@brief The SVC numbers used by the SVC functions in the SoC library. */
+enum NRF_SOC_SVCS
+{
+ SD_PPI_CHANNEL_ENABLE_GET = SOC_SVC_BASE,
+ SD_PPI_CHANNEL_ENABLE_SET = SOC_SVC_BASE + 1,
+ SD_PPI_CHANNEL_ENABLE_CLR = SOC_SVC_BASE + 2,
+ SD_PPI_CHANNEL_ASSIGN = SOC_SVC_BASE + 3,
+ SD_PPI_GROUP_TASK_ENABLE = SOC_SVC_BASE + 4,
+ SD_PPI_GROUP_TASK_DISABLE = SOC_SVC_BASE + 5,
+ SD_PPI_GROUP_ASSIGN = SOC_SVC_BASE + 6,
+ SD_PPI_GROUP_GET = SOC_SVC_BASE + 7,
+ SD_FLASH_PAGE_ERASE = SOC_SVC_BASE + 8,
+ SD_FLASH_WRITE = SOC_SVC_BASE + 9,
+ SD_FLASH_PROTECT = SOC_SVC_BASE + 10,
+ SD_PROTECTED_REGISTER_WRITE = SOC_SVC_BASE + 11,
+ SD_MUTEX_NEW = SOC_SVC_BASE_NOT_AVAILABLE,
+ SD_MUTEX_ACQUIRE = SOC_SVC_BASE_NOT_AVAILABLE + 1,
+ SD_MUTEX_RELEASE = SOC_SVC_BASE_NOT_AVAILABLE + 2,
+ SD_RAND_APPLICATION_POOL_CAPACITY_GET = SOC_SVC_BASE_NOT_AVAILABLE + 3,
+ SD_RAND_APPLICATION_BYTES_AVAILABLE_GET = SOC_SVC_BASE_NOT_AVAILABLE + 4,
+ SD_RAND_APPLICATION_VECTOR_GET = SOC_SVC_BASE_NOT_AVAILABLE + 5,
+ SD_POWER_MODE_SET = SOC_SVC_BASE_NOT_AVAILABLE + 6,
+ SD_POWER_SYSTEM_OFF = SOC_SVC_BASE_NOT_AVAILABLE + 7,
+ SD_POWER_RESET_REASON_GET = SOC_SVC_BASE_NOT_AVAILABLE + 8,
+ SD_POWER_RESET_REASON_CLR = SOC_SVC_BASE_NOT_AVAILABLE + 9,
+ SD_POWER_POF_ENABLE = SOC_SVC_BASE_NOT_AVAILABLE + 10,
+ SD_POWER_POF_THRESHOLD_SET = SOC_SVC_BASE_NOT_AVAILABLE + 11,
+ SD_POWER_RAM_POWER_SET = SOC_SVC_BASE_NOT_AVAILABLE + 13,
+ SD_POWER_RAM_POWER_CLR = SOC_SVC_BASE_NOT_AVAILABLE + 14,
+ SD_POWER_RAM_POWER_GET = SOC_SVC_BASE_NOT_AVAILABLE + 15,
+ SD_POWER_GPREGRET_SET = SOC_SVC_BASE_NOT_AVAILABLE + 16,
+ SD_POWER_GPREGRET_CLR = SOC_SVC_BASE_NOT_AVAILABLE + 17,
+ SD_POWER_GPREGRET_GET = SOC_SVC_BASE_NOT_AVAILABLE + 18,
+ SD_POWER_DCDC_MODE_SET = SOC_SVC_BASE_NOT_AVAILABLE + 19,
+ SD_APP_EVT_WAIT = SOC_SVC_BASE_NOT_AVAILABLE + 21,
+ SD_CLOCK_HFCLK_REQUEST = SOC_SVC_BASE_NOT_AVAILABLE + 22,
+ SD_CLOCK_HFCLK_RELEASE = SOC_SVC_BASE_NOT_AVAILABLE + 23,
+ SD_CLOCK_HFCLK_IS_RUNNING = SOC_SVC_BASE_NOT_AVAILABLE + 24,
+ SD_RADIO_NOTIFICATION_CFG_SET = SOC_SVC_BASE_NOT_AVAILABLE + 25,
+ SD_ECB_BLOCK_ENCRYPT = SOC_SVC_BASE_NOT_AVAILABLE + 26,
+ SD_ECB_BLOCKS_ENCRYPT = SOC_SVC_BASE_NOT_AVAILABLE + 27,
+ SD_RADIO_SESSION_OPEN = SOC_SVC_BASE_NOT_AVAILABLE + 28,
+ SD_RADIO_SESSION_CLOSE = SOC_SVC_BASE_NOT_AVAILABLE + 29,
+ SD_RADIO_REQUEST = SOC_SVC_BASE_NOT_AVAILABLE + 30,
+ SD_EVT_GET = SOC_SVC_BASE_NOT_AVAILABLE + 31,
+ SD_TEMP_GET = SOC_SVC_BASE_NOT_AVAILABLE + 32,
+ SVC_SOC_LAST = SOC_SVC_BASE_NOT_AVAILABLE + 37
+};
+
+/**@brief Possible values of a ::nrf_mutex_t. */
+enum NRF_MUTEX_VALUES
+{
+ NRF_MUTEX_FREE,
+ NRF_MUTEX_TAKEN
+};
+
+/**@brief Power modes. */
+enum NRF_POWER_MODES
+{
+ NRF_POWER_MODE_CONSTLAT, /**< Constant latency mode. See power management in the reference manual. */
+ NRF_POWER_MODE_LOWPWR /**< Low power mode. See power management in the reference manual. */
+};
+
+
+/**@brief Power failure thresholds */
+enum NRF_POWER_THRESHOLDS
+{
+ NRF_POWER_THRESHOLD_V17 = 4UL, /**< 1.7 Volts power failure threshold. */
+ NRF_POWER_THRESHOLD_V18, /**< 1.8 Volts power failure threshold. */
+ NRF_POWER_THRESHOLD_V19, /**< 1.9 Volts power failure threshold. */
+ NRF_POWER_THRESHOLD_V20, /**< 2.0 Volts power failure threshold. */
+ NRF_POWER_THRESHOLD_V21, /**< 2.1 Volts power failure threshold. */
+ NRF_POWER_THRESHOLD_V22, /**< 2.2 Volts power failure threshold. */
+ NRF_POWER_THRESHOLD_V23, /**< 2.3 Volts power failure threshold. */
+ NRF_POWER_THRESHOLD_V24, /**< 2.4 Volts power failure threshold. */
+ NRF_POWER_THRESHOLD_V25, /**< 2.5 Volts power failure threshold. */
+ NRF_POWER_THRESHOLD_V26, /**< 2.6 Volts power failure threshold. */
+ NRF_POWER_THRESHOLD_V27, /**< 2.7 Volts power failure threshold. */
+ NRF_POWER_THRESHOLD_V28 /**< 2.8 Volts power failure threshold. */
+};
+
+
+
+/**@brief DC/DC converter modes. */
+enum NRF_POWER_DCDC_MODES
+{
+ NRF_POWER_DCDC_DISABLE, /**< The DCDC is disabled. */
+ NRF_POWER_DCDC_ENABLE /**< The DCDC is enabled. */
+};
+
+/**@brief Radio notification distances. */
+enum NRF_RADIO_NOTIFICATION_DISTANCES
+{
+ NRF_RADIO_NOTIFICATION_DISTANCE_NONE = 0, /**< The event does not have a notification. */
+ NRF_RADIO_NOTIFICATION_DISTANCE_800US, /**< The distance from the active notification to start of radio activity. */
+ NRF_RADIO_NOTIFICATION_DISTANCE_1740US, /**< The distance from the active notification to start of radio activity. */
+ NRF_RADIO_NOTIFICATION_DISTANCE_2680US, /**< The distance from the active notification to start of radio activity. */
+ NRF_RADIO_NOTIFICATION_DISTANCE_3620US, /**< The distance from the active notification to start of radio activity. */
+ NRF_RADIO_NOTIFICATION_DISTANCE_4560US, /**< The distance from the active notification to start of radio activity. */
+ NRF_RADIO_NOTIFICATION_DISTANCE_5500US /**< The distance from the active notification to start of radio activity. */
+};
+
+
+/**@brief Radio notification types. */
+enum NRF_RADIO_NOTIFICATION_TYPES
+{
+ NRF_RADIO_NOTIFICATION_TYPE_NONE = 0, /**< The event does not have a radio notification signal. */
+ NRF_RADIO_NOTIFICATION_TYPE_INT_ON_ACTIVE, /**< Using interrupt for notification when the radio will be enabled. */
+ NRF_RADIO_NOTIFICATION_TYPE_INT_ON_INACTIVE, /**< Using interrupt for notification when the radio has been disabled. */
+ NRF_RADIO_NOTIFICATION_TYPE_INT_ON_BOTH, /**< Using interrupt for notification both when the radio will be enabled and disabled. */
+};
+
+/**@brief The Radio signal callback types. */
+enum NRF_RADIO_CALLBACK_SIGNAL_TYPE
+{
+ NRF_RADIO_CALLBACK_SIGNAL_TYPE_START, /**< This signal indicates the start of the radio timeslot. */
+ NRF_RADIO_CALLBACK_SIGNAL_TYPE_TIMER0, /**< This signal indicates the NRF_TIMER0 interrupt. */
+ NRF_RADIO_CALLBACK_SIGNAL_TYPE_RADIO, /**< This signal indicates the NRF_RADIO interrupt. */
+ NRF_RADIO_CALLBACK_SIGNAL_TYPE_EXTEND_FAILED, /**< This signal indicates extend action failed. */
+ NRF_RADIO_CALLBACK_SIGNAL_TYPE_EXTEND_SUCCEEDED /**< This signal indicates extend action succeeded. */
+};
+
+/**@brief The actions requested by the signal callback.
+ *
+ * This code gives the SOC instructions about what action to take when the signal callback has
+ * returned.
+ */
+enum NRF_RADIO_SIGNAL_CALLBACK_ACTION
+{
+ NRF_RADIO_SIGNAL_CALLBACK_ACTION_NONE, /**< Return without action. */
+ NRF_RADIO_SIGNAL_CALLBACK_ACTION_EXTEND, /**< Request an extension of the current
+ timeslot. Maximum execution time for this action:
+ @ref NRF_RADIO_MAX_EXTENSION_PROCESSING_TIME_US.
+ This action must be started at least
+ @ref NRF_RADIO_MIN_EXTENSION_MARGIN_US before
+ the end of the timeslot. */
+ NRF_RADIO_SIGNAL_CALLBACK_ACTION_END, /**< End the current radio timeslot. */
+ NRF_RADIO_SIGNAL_CALLBACK_ACTION_REQUEST_AND_END /**< Request a new radio timeslot and end the current timeslot. */
+};
+
+/**@brief Radio timeslot high frequency clock source configuration. */
+enum NRF_RADIO_HFCLK_CFG
+{
+ NRF_RADIO_HFCLK_CFG_XTAL_GUARANTEED, /**< The SoftDevice will guarantee that the high frequency clock source is the
+ external crystal for the whole duration of the timeslot. This should be the
+ preferred option for events that use the radio or require high timing accuracy.
+ @note The SoftDevice will automatically turn on and off the external crystal,
+ at the beginning and end of the timeslot, respectively. The crystal may also
+ intentionally be left running after the timeslot, in cases where it is needed
+ by the SoftDevice shortly after the end of the timeslot. */
+ NRF_RADIO_HFCLK_CFG_NO_GUARANTEE /**< This configuration allows for earlier and tighter scheduling of timeslots.
+ The RC oscillator may be the clock source in part or for the whole duration of the timeslot.
+ The RC oscillator's accuracy must therefore be taken into consideration.
+ @note If the application will use the radio peripheral in timeslots with this configuration,
+ it must make sure that the crystal is running and stable before starting the radio. */
+};
+
+/**@brief Radio timeslot priorities. */
+enum NRF_RADIO_PRIORITY
+{
+ NRF_RADIO_PRIORITY_HIGH, /**< High (equal priority as the normal connection priority of the SoftDevice stack(s)). */
+ NRF_RADIO_PRIORITY_NORMAL, /**< Normal (equal priority as the priority of secondary activities of the SoftDevice stack(s)). */
+};
+
+/**@brief Radio timeslot request type. */
+enum NRF_RADIO_REQUEST_TYPE
+{
+ NRF_RADIO_REQ_TYPE_EARLIEST, /**< Request radio timeslot as early as possible. This should always be used for the first request in a session. */
+ NRF_RADIO_REQ_TYPE_NORMAL /**< Normal radio timeslot request. */
+};
+
+/**@brief SoC Events. */
+enum NRF_SOC_EVTS
+{
+ NRF_EVT_HFCLKSTARTED, /**< Event indicating that the HFCLK has started. */
+ NRF_EVT_POWER_FAILURE_WARNING, /**< Event indicating that a power failure warning has occurred. */
+ NRF_EVT_FLASH_OPERATION_SUCCESS, /**< Event indicating that the ongoing flash operation has completed successfully. */
+ NRF_EVT_FLASH_OPERATION_ERROR, /**< Event indicating that the ongoing flash operation has timed out with an error. */
+ NRF_EVT_RADIO_BLOCKED, /**< Event indicating that a radio timeslot was blocked. */
+ NRF_EVT_RADIO_CANCELED, /**< Event indicating that a radio timeslot was canceled by SoftDevice. */
+ NRF_EVT_RADIO_SIGNAL_CALLBACK_INVALID_RETURN, /**< Event indicating that a radio timeslot signal callback handler return was invalid. */
+ NRF_EVT_RADIO_SESSION_IDLE, /**< Event indicating that a radio timeslot session is idle. */
+ NRF_EVT_RADIO_SESSION_CLOSED, /**< Event indicating that a radio timeslot session is closed. */
+ NRF_EVT_NUMBER_OF_EVTS
+};
+
+/**@} */
+
+
+/**@addtogroup NRF_SOC_STRUCTURES Structures
+ * @{ */
+
+/**@brief Represents a mutex for use with the nrf_mutex functions.
+ * @note Accessing the value directly is not safe, use the mutex functions!
+ */
+typedef volatile uint8_t nrf_mutex_t;
+
+/**@brief Parameters for a request for a timeslot as early as possible. */
+typedef struct
+{
+ uint8_t hfclk; /**< High frequency clock source, see @ref NRF_RADIO_HFCLK_CFG. */
+ uint8_t priority; /**< The radio timeslot priority, see @ref NRF_RADIO_PRIORITY. */
+ uint32_t length_us; /**< The radio timeslot length (in the range 100 to 100,000] microseconds). */
+ uint32_t timeout_us; /**< Longest acceptable delay until the start of the requested timeslot (up to @ref NRF_RADIO_EARLIEST_TIMEOUT_MAX_US microseconds). */
+} nrf_radio_request_earliest_t;
+
+/**@brief Parameters for a normal radio timeslot request. */
+typedef struct
+{
+ uint8_t hfclk; /**< High frequency clock source, see @ref NRF_RADIO_HFCLK_CFG. */
+ uint8_t priority; /**< The radio timeslot priority, see @ref NRF_RADIO_PRIORITY. */
+ uint32_t distance_us; /**< Distance from the start of the previous radio timeslot (up to @ref NRF_RADIO_DISTANCE_MAX_US microseconds). */
+ uint32_t length_us; /**< The radio timeslot length (in the range [100..100,000] microseconds). */
+} nrf_radio_request_normal_t;
+
+/**@brief Radio timeslot request parameters. */
+typedef struct
+{
+ uint8_t request_type; /**< Type of request, see @ref NRF_RADIO_REQUEST_TYPE. */
+ union
+ {
+ nrf_radio_request_earliest_t earliest; /**< Parameters for requesting a radio timeslot as early as possible. */
+ nrf_radio_request_normal_t normal; /**< Parameters for requesting a normal radio timeslot. */
+ } params; /**< Parameter union. */
+} nrf_radio_request_t;
+
+/**@brief Return parameters of the radio timeslot signal callback. */
+typedef struct
+{
+ uint8_t callback_action; /**< The action requested by the application when returning from the signal callback, see @ref NRF_RADIO_SIGNAL_CALLBACK_ACTION. */
+ union
+ {
+ struct
+ {
+ nrf_radio_request_t * p_next; /**< The request parameters for the next radio timeslot. */
+ } request; /**< Additional parameters for return_code @ref NRF_RADIO_SIGNAL_CALLBACK_ACTION_REQUEST_AND_END. */
+ struct
+ {
+ uint32_t length_us; /**< Requested extension of the radio timeslot duration (microseconds) (for minimum time see @ref NRF_RADIO_MINIMUM_TIMESLOT_LENGTH_EXTENSION_TIME_US). */
+ } extend; /**< Additional parameters for return_code @ref NRF_RADIO_SIGNAL_CALLBACK_ACTION_EXTEND. */
+ } params; /**< Parameter union. */
+} nrf_radio_signal_callback_return_param_t;
+
+/**@brief The radio timeslot signal callback type.
+ *
+ * @note In case of invalid return parameters, the radio timeslot will automatically end
+ * immediately after returning from the signal callback and the
+ * @ref NRF_EVT_RADIO_SIGNAL_CALLBACK_INVALID_RETURN event will be sent.
+ * @note The returned struct pointer must remain valid after the signal callback
+ * function returns. For instance, this means that it must not point to a stack variable.
+ *
+ * @param[in] signal_type Type of signal, see @ref NRF_RADIO_CALLBACK_SIGNAL_TYPE.
+ *
+ * @return Pointer to structure containing action requested by the application.
+ */
+typedef nrf_radio_signal_callback_return_param_t * (*nrf_radio_signal_callback_t) (uint8_t signal_type);
+
+/**@brief AES ECB parameter typedefs */
+typedef uint8_t soc_ecb_key_t[SOC_ECB_KEY_LENGTH]; /**< Encryption key type. */
+typedef uint8_t soc_ecb_cleartext_t[SOC_ECB_CLEARTEXT_LENGTH]; /**< Cleartext data type. */
+typedef uint8_t soc_ecb_ciphertext_t[SOC_ECB_CIPHERTEXT_LENGTH]; /**< Ciphertext data type. */
+
+/**@brief AES ECB data structure */
+typedef struct
+{
+ soc_ecb_key_t key; /**< Encryption key. */
+ soc_ecb_cleartext_t cleartext; /**< Cleartext data. */
+ soc_ecb_ciphertext_t ciphertext; /**< Ciphertext data. */
+} nrf_ecb_hal_data_t;
+
+/**@brief AES ECB block. Used to provide multiple blocks in a single call
+ to @ref sd_ecb_blocks_encrypt.*/
+typedef struct
+{
+ soc_ecb_key_t const * p_key; /**< Pointer to the Encryption key. */
+ soc_ecb_cleartext_t const * p_cleartext; /**< Pointer to the Cleartext data. */
+ soc_ecb_ciphertext_t * p_ciphertext; /**< Pointer to the Ciphertext data. */
+} nrf_ecb_hal_data_block_t;
+
+/**@} */
+
+/**@addtogroup NRF_SOC_FUNCTIONS Functions
+ * @{ */
+
+/**@brief Initialize a mutex.
+ *
+ * @param[in] p_mutex Pointer to the mutex to initialize.
+ *
+ * @retval ::NRF_SUCCESS
+ */
+SVCALL(SD_MUTEX_NEW, uint32_t, sd_mutex_new(nrf_mutex_t * p_mutex));
+
+/**@brief Attempt to acquire a mutex.
+ *
+ * @param[in] p_mutex Pointer to the mutex to acquire.
+ *
+ * @retval ::NRF_SUCCESS The mutex was successfully acquired.
+ * @retval ::NRF_ERROR_SOC_MUTEX_ALREADY_TAKEN The mutex could not be acquired.
+ */
+SVCALL(SD_MUTEX_ACQUIRE, uint32_t, sd_mutex_acquire(nrf_mutex_t * p_mutex));
+
+/**@brief Release a mutex.
+ *
+ * @param[in] p_mutex Pointer to the mutex to release.
+ *
+ * @retval ::NRF_SUCCESS
+ */
+SVCALL(SD_MUTEX_RELEASE, uint32_t, sd_mutex_release(nrf_mutex_t * p_mutex));
+
+/**@brief Query the capacity of the application random pool.
+ *
+ * @param[out] p_pool_capacity The capacity of the pool.
+ *
+ * @retval ::NRF_SUCCESS
+ */
+SVCALL(SD_RAND_APPLICATION_POOL_CAPACITY_GET, uint32_t, sd_rand_application_pool_capacity_get(uint8_t * p_pool_capacity));
+
+/**@brief Get number of random bytes available to the application.
+ *
+ * @param[out] p_bytes_available The number of bytes currently available in the pool.
+ *
+ * @retval ::NRF_SUCCESS
+ */
+SVCALL(SD_RAND_APPLICATION_BYTES_AVAILABLE_GET, uint32_t, sd_rand_application_bytes_available_get(uint8_t * p_bytes_available));
+
+/**@brief Get random bytes from the application pool.
+ *
+ * @param[out] p_buff Pointer to unit8_t buffer for storing the bytes.
+ * @param[in] length Number of bytes to take from pool and place in p_buff.
+ *
+ * @retval ::NRF_SUCCESS The requested bytes were written to p_buff.
+ * @retval ::NRF_ERROR_SOC_RAND_NOT_ENOUGH_VALUES No bytes were written to the buffer, because there were not enough bytes available.
+*/
+SVCALL(SD_RAND_APPLICATION_VECTOR_GET, uint32_t, sd_rand_application_vector_get(uint8_t * p_buff, uint8_t length));
+
+/**@brief Gets the reset reason register.
+ *
+ * @param[out] p_reset_reason Contents of the NRF_POWER->RESETREAS register.
+ *
+ * @retval ::NRF_SUCCESS
+ */
+SVCALL(SD_POWER_RESET_REASON_GET, uint32_t, sd_power_reset_reason_get(uint32_t * p_reset_reason));
+
+/**@brief Clears the bits of the reset reason register.
+ *
+ * @param[in] reset_reason_clr_msk Contains the bits to clear from the reset reason register.
+ *
+ * @retval ::NRF_SUCCESS
+ */
+SVCALL(SD_POWER_RESET_REASON_CLR, uint32_t, sd_power_reset_reason_clr(uint32_t reset_reason_clr_msk));
+
+/**@brief Sets the power mode when in CPU sleep.
+ *
+ * @param[in] power_mode The power mode to use when in CPU sleep, see @ref NRF_POWER_MODES. @sa sd_app_evt_wait
+ *
+ * @retval ::NRF_SUCCESS The power mode was set.
+ * @retval ::NRF_ERROR_SOC_POWER_MODE_UNKNOWN The power mode was unknown.
+ */
+SVCALL(SD_POWER_MODE_SET, uint32_t, sd_power_mode_set(uint8_t power_mode));
+
+/**@brief Puts the chip in System OFF mode.
+ *
+ * @retval ::NRF_ERROR_SOC_POWER_OFF_SHOULD_NOT_RETURN
+ */
+SVCALL(SD_POWER_SYSTEM_OFF, uint32_t, sd_power_system_off(void));
+
+/**@brief Enables or disables the power-fail comparator.
+ *
+ * Enabling this will give a SoftDevice event (NRF_EVT_POWER_FAILURE_WARNING) when the power failure warning occurs.
+ * The event can be retrieved with sd_evt_get();
+ *
+ * @param[in] pof_enable True if the power-fail comparator should be enabled, false if it should be disabled.
+ *
+ * @retval ::NRF_SUCCESS
+ */
+SVCALL(SD_POWER_POF_ENABLE, uint32_t, sd_power_pof_enable(uint8_t pof_enable));
+
+
+/**@brief Sets the power failure comparator threshold value.
+ *
+ *
+ * @param[in] threshold The power-fail threshold value to use, see @ref NRF_POWER_THRESHOLDS.
+ *
+ * @retval ::NRF_SUCCESS The power failure threshold was set.
+ * @retval ::NRF_ERROR_SOC_POWER_POF_THRESHOLD_UNKNOWN The power failure threshold is unknown.
+ */
+SVCALL(SD_POWER_POF_THRESHOLD_SET, uint32_t, sd_power_pof_threshold_set(uint8_t threshold));
+
+
+/**@brief Writes the NRF_POWER->RAM[index].POWERSET register.
+ *
+ * @param[in] index Contains the index in the NRF_POWER->RAM[index].POWERSET register to write to.
+ * @param[in] ram_powerset Contains the word to write to the NRF_POWER->RAM[index].POWERSET register.
+ *
+ * @retval ::NRF_SUCCESS
+ */
+SVCALL(SD_POWER_RAM_POWER_SET, uint32_t, sd_power_ram_power_set(uint8_t index, uint32_t ram_powerset));
+
+/**@brief Writes the NRF_POWER->RAM[index].POWERCLR register.
+ *
+ * @param[in] index Contains the index in the NRF_POWER->RAM[index].POWERCLR register to write to.
+ * @param[in] ram_powerclr Contains the word to write to the NRF_POWER->RAM[index].POWERCLR register.
+ *
+ * @retval ::NRF_SUCCESS
+ */
+SVCALL(SD_POWER_RAM_POWER_CLR, uint32_t, sd_power_ram_power_clr(uint8_t index, uint32_t ram_powerclr));
+
+/**@brief Get contents of NRF_POWER->RAM[index].POWER register, indicates power status of RAM[index] blocks.
+ *
+ * @param[in] index Contains the index in the NRF_POWER->RAM[index].POWER register to read from.
+ * @param[out] p_ram_power Content of NRF_POWER->RAM[index].POWER register.
+ *
+ * @retval ::NRF_SUCCESS
+ */
+SVCALL(SD_POWER_RAM_POWER_GET, uint32_t, sd_power_ram_power_get(uint8_t index, uint32_t * p_ram_power));
+
+/**@brief Set bits in the general purpose retention registers (NRF_POWER->GPREGRET*).
+ *
+ * @param[in] gpregret_id 0 for GPREGRET, 1 for GPREGRET2.
+ * @param[in] gpregret_msk Bits to be set in the GPREGRET register.
+ *
+ * @retval ::NRF_SUCCESS
+ */
+SVCALL(SD_POWER_GPREGRET_SET, uint32_t, sd_power_gpregret_set(uint32_t gpregret_id, uint32_t gpregret_msk));
+
+/**@brief Clear bits in the general purpose retention registers (NRF_POWER->GPREGRET*).
+ *
+ * @param[in] gpregret_id 0 for GPREGRET, 1 for GPREGRET2.
+ * @param[in] gpregret_msk Bits to be clear in the GPREGRET register.
+ *
+ * @retval ::NRF_SUCCESS
+ */
+SVCALL(SD_POWER_GPREGRET_CLR, uint32_t, sd_power_gpregret_clr(uint32_t gpregret_id, uint32_t gpregret_msk));
+
+/**@brief Get contents of the general purpose retention registers (NRF_POWER->GPREGRET*).
+ *
+ * @param[in] gpregret_id 0 for GPREGRET, 1 for GPREGRET2.
+ * @param[out] p_gpregret Contents of the GPREGRET register.
+ *
+ * @retval ::NRF_SUCCESS
+ */
+SVCALL(SD_POWER_GPREGRET_GET, uint32_t, sd_power_gpregret_get(uint32_t gpregret_id, uint32_t *p_gpregret));
+
+/**@brief Enable or disable the DC/DC regulator.
+ *
+ * @param[in] dcdc_mode The mode of the DCDC, see @ref NRF_POWER_DCDC_MODES.
+ *
+ * @retval ::NRF_SUCCESS
+ * @retval ::NRF_ERROR_INVALID_PARAM The DCDC mode is invalid.
+ */
+SVCALL(SD_POWER_DCDC_MODE_SET, uint32_t, sd_power_dcdc_mode_set(uint8_t dcdc_mode));
+
+
+/**@brief Request the high frequency crystal oscillator.
+ *
+ * Will start the high frequency crystal oscillator, the startup time of the crystal varies
+ * and the ::sd_clock_hfclk_is_running function can be polled to check if it has started.
+ *
+ * @see sd_clock_hfclk_is_running
+ * @see sd_clock_hfclk_release
+ *
+ * @retval ::NRF_SUCCESS
+ */
+SVCALL(SD_CLOCK_HFCLK_REQUEST, uint32_t, sd_clock_hfclk_request(void));
+
+/**@brief Releases the high frequency crystal oscillator.
+ *
+ * Will stop the high frequency crystal oscillator, this happens immediately.
+ *
+ * @see sd_clock_hfclk_is_running
+ * @see sd_clock_hfclk_request
+ *
+ * @retval ::NRF_SUCCESS
+ */
+SVCALL(SD_CLOCK_HFCLK_RELEASE, uint32_t, sd_clock_hfclk_release(void));
+
+/**@brief Checks if the high frequency crystal oscillator is running.
+ *
+ * @see sd_clock_hfclk_request
+ * @see sd_clock_hfclk_release
+ *
+ * @param[out] p_is_running 1 if the external crystal oscillator is running, 0 if not.
+ *
+ * @retval ::NRF_SUCCESS
+ */
+SVCALL(SD_CLOCK_HFCLK_IS_RUNNING, uint32_t, sd_clock_hfclk_is_running(uint32_t * p_is_running));
+
+/**@brief Waits for an application event.
+ *
+ * An application event is either an application interrupt or a pended interrupt when the interrupt
+ * is disabled.
+ *
+ * When the application waits for an application event by calling this function, an interrupt that
+ * is enabled will be taken immediately on pending since this function will wait in thread mode,
+ * then the execution will return in the application's main thread.
+ *
+ * In order to wake up from disabled interrupts, the SEVONPEND flag has to be set in the Cortex-M
+ * MCU's System Control Register (SCR), CMSIS_SCB. In that case, when a disabled interrupt gets
+ * pended, this function will return to the application's main thread.
+ *
+ * @note The application must ensure that the pended flag is cleared using ::sd_nvic_ClearPendingIRQ
+ * in order to sleep using this function. This is only necessary for disabled interrupts, as
+ * the interrupt handler will clear the pending flag automatically for enabled interrupts.
+ *
+ * @note If an application interrupt has happened since the last time sd_app_evt_wait was
+ * called this function will return immediately and not go to sleep. This is to avoid race
+ * conditions that can occur when a flag is updated in the interrupt handler and processed
+ * in the main loop.
+ *
+ * @post An application interrupt has happened or a interrupt pending flag is set.
+ *
+ * @retval ::NRF_SUCCESS
+ */
+SVCALL(SD_APP_EVT_WAIT, uint32_t, sd_app_evt_wait(void));
+
+/**@brief Get PPI channel enable register contents.
+ *
+ * @param[out] p_channel_enable The contents of the PPI CHEN register.
+ *
+ * @retval ::NRF_SUCCESS
+ */
+SVCALL(SD_PPI_CHANNEL_ENABLE_GET, uint32_t, sd_ppi_channel_enable_get(uint32_t * p_channel_enable));
+
+/**@brief Set PPI channel enable register.
+ *
+ * @param[in] channel_enable_set_msk Mask containing the bits to set in the PPI CHEN register.
+ *
+ * @retval ::NRF_SUCCESS
+ */
+SVCALL(SD_PPI_CHANNEL_ENABLE_SET, uint32_t, sd_ppi_channel_enable_set(uint32_t channel_enable_set_msk));
+
+/**@brief Clear PPI channel enable register.
+ *
+ * @param[in] channel_enable_clr_msk Mask containing the bits to clear in the PPI CHEN register.
+ *
+ * @retval ::NRF_SUCCESS
+ */
+SVCALL(SD_PPI_CHANNEL_ENABLE_CLR, uint32_t, sd_ppi_channel_enable_clr(uint32_t channel_enable_clr_msk));
+
+/**@brief Assign endpoints to a PPI channel.
+ *
+ * @param[in] channel_num Number of the PPI channel to assign.
+ * @param[in] evt_endpoint Event endpoint of the PPI channel.
+ * @param[in] task_endpoint Task endpoint of the PPI channel.
+ *
+ * @retval ::NRF_ERROR_SOC_PPI_INVALID_CHANNEL The channel number is invalid.
+ * @retval ::NRF_SUCCESS
+ */
+SVCALL(SD_PPI_CHANNEL_ASSIGN, uint32_t, sd_ppi_channel_assign(uint8_t channel_num, const volatile void * evt_endpoint, const volatile void * task_endpoint));
+
+/**@brief Task to enable a channel group.
+ *
+ * @param[in] group_num Number of the channel group.
+ *
+ * @retval ::NRF_ERROR_SOC_PPI_INVALID_GROUP The group number is invalid
+ * @retval ::NRF_SUCCESS
+ */
+SVCALL(SD_PPI_GROUP_TASK_ENABLE, uint32_t, sd_ppi_group_task_enable(uint8_t group_num));
+
+/**@brief Task to disable a channel group.
+ *
+ * @param[in] group_num Number of the PPI group.
+ *
+ * @retval ::NRF_ERROR_SOC_PPI_INVALID_GROUP The group number is invalid.
+ * @retval ::NRF_SUCCESS
+ */
+SVCALL(SD_PPI_GROUP_TASK_DISABLE, uint32_t, sd_ppi_group_task_disable(uint8_t group_num));
+
+/**@brief Assign PPI channels to a channel group.
+ *
+ * @param[in] group_num Number of the channel group.
+ * @param[in] channel_msk Mask of the channels to assign to the group.
+ *
+ * @retval ::NRF_ERROR_SOC_PPI_INVALID_GROUP The group number is invalid.
+ * @retval ::NRF_SUCCESS
+ */
+SVCALL(SD_PPI_GROUP_ASSIGN, uint32_t, sd_ppi_group_assign(uint8_t group_num, uint32_t channel_msk));
+
+/**@brief Gets the PPI channels of a channel group.
+ *
+ * @param[in] group_num Number of the channel group.
+ * @param[out] p_channel_msk Mask of the channels assigned to the group.
+ *
+ * @retval ::NRF_ERROR_SOC_PPI_INVALID_GROUP The group number is invalid.
+ * @retval ::NRF_SUCCESS
+ */
+SVCALL(SD_PPI_GROUP_GET, uint32_t, sd_ppi_group_get(uint8_t group_num, uint32_t * p_channel_msk));
+
+/**@brief Configures the Radio Notification signal.
+ *
+ * @note
+ * - The notification signal latency depends on the interrupt priority settings of SWI used
+ * for notification signal.
+ * - To ensure that the radio notification signal behaves in a consistent way, the radio
+ * notifications must be configured when there is no protocol stack or other SoftDevice
+ * activity in progress. It is recommended that the radio notification signal is
+ * configured directly after the SoftDevice has been enabled.
+ * - In the period between the ACTIVE signal and the start of the Radio Event, the SoftDevice
+ * will interrupt the application to do Radio Event preparation.
+ * - Using the Radio Notification feature may limit the bandwidth, as the SoftDevice may have
+ * to shorten the connection events to have time for the Radio Notification signals.
+ *
+ * @param[in] type Type of notification signal, see @ref NRF_RADIO_NOTIFICATION_TYPES.
+ * @ref NRF_RADIO_NOTIFICATION_TYPE_NONE shall be used to turn off radio
+ * notification. Using @ref NRF_RADIO_NOTIFICATION_DISTANCE_NONE is
+ * recommended (but not required) to be used with
+ * @ref NRF_RADIO_NOTIFICATION_TYPE_NONE.
+ *
+ * @param[in] distance Distance between the notification signal and start of radio activity, see @ref NRF_RADIO_NOTIFICATION_DISTANCES.
+ * This parameter is ignored when @ref NRF_RADIO_NOTIFICATION_TYPE_NONE or
+ * @ref NRF_RADIO_NOTIFICATION_TYPE_INT_ON_INACTIVE is used.
+ *
+ * @retval ::NRF_ERROR_INVALID_PARAM The group number is invalid.
+ * @retval ::NRF_ERROR_INVALID_STATE A protocol stack or other SoftDevice is running. Stop all
+ * running activities and retry.
+ * @retval ::NRF_SUCCESS
+ */
+SVCALL(SD_RADIO_NOTIFICATION_CFG_SET, uint32_t, sd_radio_notification_cfg_set(uint8_t type, uint8_t distance));
+
+/**@brief Encrypts a block according to the specified parameters.
+ *
+ * 128-bit AES encryption.
+ *
+ * @note:
+ * - The application may set the SEVONPEND bit in the SCR to 1 to make the SoftDevice sleep while
+ * the ECB is running. The SEVONPEND bit should only be cleared (set to 0) from application
+ * main or low interrupt level.
+ *
+ * @param[in, out] p_ecb_data Pointer to the ECB parameters' struct (two input
+ * parameters and one output parameter).
+ *
+ * @retval ::NRF_SUCCESS
+ */
+SVCALL(SD_ECB_BLOCK_ENCRYPT, uint32_t, sd_ecb_block_encrypt(nrf_ecb_hal_data_t * p_ecb_data));
+
+/**@brief Encrypts multiple data blocks provided as an array of data block structures.
+ *
+ * @details: Performs 128-bit AES encryption on multiple data blocks
+ *
+ * @note:
+ * - The application may set the SEVONPEND bit in the SCR to 1 to make the SoftDevice sleep while
+ * the ECB is running. The SEVONPEND bit should only be cleared (set to 0) from application
+ * main or low interrupt level.
+ *
+ * @param[in] block_count Count of blocks in the p_data_blocks array.
+ * @param[in,out] p_data_blocks Pointer to the first entry in a contiguous array of
+ * @ref nrf_ecb_hal_data_block_t structures.
+ *
+ * @retval ::NRF_SUCCESS
+ */
+SVCALL(SD_ECB_BLOCKS_ENCRYPT, uint32_t, sd_ecb_blocks_encrypt(uint8_t block_count, nrf_ecb_hal_data_block_t * p_data_blocks));
+
+/**@brief Gets any pending events generated by the SoC API.
+ *
+ * The application should keep calling this function to get events, until ::NRF_ERROR_NOT_FOUND is returned.
+ *
+ * @param[out] p_evt_id Set to one of the values in @ref NRF_SOC_EVTS, if any events are pending.
+ *
+ * @retval ::NRF_SUCCESS An event was pending. The event id is written in the p_evt_id parameter.
+ * @retval ::NRF_ERROR_NOT_FOUND No pending events.
+ */
+SVCALL(SD_EVT_GET, uint32_t, sd_evt_get(uint32_t * p_evt_id));
+
+/**@brief Get the temperature measured on the chip
+ *
+ * This function will block until the temperature measurement is done.
+ * It takes around 50 us from call to return.
+ *
+ * @param[out] p_temp Result of temperature measurement. Die temperature in 0.25 degrees Celsius.
+ *
+ * @retval ::NRF_SUCCESS A temperature measurement was done, and the temperature was written to temp
+ */
+SVCALL(SD_TEMP_GET, uint32_t, sd_temp_get(int32_t * p_temp));
+
+/**@brief Flash Write
+*
+* Commands to write a buffer to flash
+*
+* If the SoftDevice is enabled:
+* This call initiates the flash access command, and its completion will be communicated to the
+* application with exactly one of the following events:
+* - @ref NRF_EVT_FLASH_OPERATION_SUCCESS - The command was successfully completed.
+* - @ref NRF_EVT_FLASH_OPERATION_ERROR - The command could not be started.
+*
+* If the SoftDevice is not enabled no event will be generated, and this call will return @ref NRF_SUCCESS when the
+ * write has been completed
+*
+* @note
+* - This call takes control over the radio and the CPU during flash erase and write to make sure that
+* they will not interfere with the flash access. This means that all interrupts will be blocked
+* for a predictable time (depending on the NVMC specification in the device's Product Specification
+* and the command parameters).
+* - The data in the p_src buffer should not be modified before the @ref NRF_EVT_FLASH_OPERATION_SUCCESS
+* or the @ref NRF_EVT_FLASH_OPERATION_ERROR have been received if the SoftDevice is enabled.
+* - This call will make the SoftDevice trigger a hardfault when the page is written, if it is
+* protected.
+*
+*
+* @param[in] p_dst Pointer to start of flash location to be written.
+* @param[in] p_src Pointer to buffer with data to be written.
+* @param[in] size Number of 32-bit words to write. Maximum size is the number of words in one
+* flash page. See the device's Product Specification for details.
+*
+* @retval ::NRF_ERROR_INVALID_ADDR Tried to write to a non existing flash address, or p_dst or p_src was unaligned.
+* @retval ::NRF_ERROR_BUSY The previous command has not yet completed.
+* @retval ::NRF_ERROR_INVALID_LENGTH Size was 0, or higher than the maximum allowed size.
+* @retval ::NRF_ERROR_FORBIDDEN Tried to write to an address outside the application flash area.
+* @retval ::NRF_SUCCESS The command was accepted.
+*/
+SVCALL(SD_FLASH_WRITE, uint32_t, sd_flash_write(uint32_t * p_dst, uint32_t const * p_src, uint32_t size));
+
+
+/**@brief Flash Erase page
+*
+* Commands to erase a flash page
+* If the SoftDevice is enabled:
+* This call initiates the flash access command, and its completion will be communicated to the
+* application with exactly one of the following events:
+* - @ref NRF_EVT_FLASH_OPERATION_SUCCESS - The command was successfully completed.
+* - @ref NRF_EVT_FLASH_OPERATION_ERROR - The command could not be started.
+*
+* If the SoftDevice is not enabled no event will be generated, and this call will return @ref NRF_SUCCESS when the
+* erase has been completed
+*
+* @note
+* - This call takes control over the radio and the CPU during flash erase and write to make sure that
+* they will not interfere with the flash access. This means that all interrupts will be blocked
+* for a predictable time (depending on the NVMC specification in the device's Product Specification
+* and the command parameters).
+* - This call will make the SoftDevice trigger a hardfault when the page is erased, if it is
+* protected.
+*
+*
+* @param[in] page_number Page number of the page to erase
+*
+* @retval ::NRF_ERROR_INTERNAL If a new session could not be opened due to an internal error.
+* @retval ::NRF_ERROR_INVALID_ADDR Tried to erase to a non existing flash page.
+* @retval ::NRF_ERROR_BUSY The previous command has not yet completed.
+* @retval ::NRF_ERROR_FORBIDDEN Tried to erase a page outside the application flash area.
+* @retval ::NRF_SUCCESS The command was accepted.
+*/
+SVCALL(SD_FLASH_PAGE_ERASE, uint32_t, sd_flash_page_erase(uint32_t page_number));
+
+
+/**@brief Flash Protection set
+ *
+ * Commands to set the flash protection configuration registers.
+ This sets the CONFIGx registers of the BPROT peripheral.
+ *
+ * @note Not all parameters are valid for all products. Some bits in each parameter may not be
+ * valid for your product. Please refer your Product Specification for more details.
+ *
+ * @note To read the values read them directly. They are only write-protected.
+ *
+ * @note It is possible to use @ref sd_protected_register_write instead of this function.
+ *
+ * @param[in] block_cfg0 Value to be written to the configuration register.
+ * @param[in] block_cfg1 Value to be written to the configuration register.
+ * @param[in] block_cfg2 Value to be written to the configuration register.
+ * @param[in] block_cfg3 Value to be written to the configuration register.
+ *
+ * @retval ::NRF_ERROR_NOT_SUPPORTED Non-zero value supplied to one or more of the unsupported parameters.
+ * @retval ::NRF_SUCCESS Values successfully written to configuration registers.
+ */
+SVCALL(SD_FLASH_PROTECT, uint32_t, sd_flash_protect(uint32_t block_cfg0, uint32_t block_cfg1, uint32_t block_cfg2, uint32_t block_cfg3));
+
+/**@brief Opens a session for radio timeslot requests.
+ *
+ * @note Only one session can be open at a time.
+ * @note p_radio_signal_callback(@ref NRF_RADIO_CALLBACK_SIGNAL_TYPE_START) will be called when the radio timeslot
+ * starts. From this point the NRF_RADIO and NRF_TIMER0 peripherals can be freely accessed
+ * by the application.
+ * @note p_radio_signal_callback(@ref NRF_RADIO_CALLBACK_SIGNAL_TYPE_TIMER0) is called whenever the NRF_TIMER0
+ * interrupt occurs.
+ * @note p_radio_signal_callback(@ref NRF_RADIO_CALLBACK_SIGNAL_TYPE_RADIO) is called whenever the NRF_RADIO
+ * interrupt occurs.
+ * @note p_radio_signal_callback() will be called at ARM interrupt priority level 0. This
+ * implies that none of the sd_* API calls can be used from p_radio_signal_callback().
+ *
+ * @param[in] p_radio_signal_callback The signal callback.
+ *
+ * @retval ::NRF_ERROR_INVALID_ADDR p_radio_signal_callback is an invalid function pointer.
+ * @retval ::NRF_ERROR_BUSY If session cannot be opened.
+ * @retval ::NRF_ERROR_INTERNAL If a new session could not be opened due to an internal error.
+ * @retval ::NRF_SUCCESS Otherwise.
+ */
+ SVCALL(SD_RADIO_SESSION_OPEN, uint32_t, sd_radio_session_open(nrf_radio_signal_callback_t p_radio_signal_callback));
+
+/**@brief Closes a session for radio timeslot requests.
+ *
+ * @note Any current radio timeslot will be finished before the session is closed.
+ * @note If a radio timeslot is scheduled when the session is closed, it will be canceled.
+ * @note The application cannot consider the session closed until the @ref NRF_EVT_RADIO_SESSION_CLOSED
+ * event is received.
+ *
+ * @retval ::NRF_ERROR_FORBIDDEN If session not opened.
+ * @retval ::NRF_ERROR_BUSY If session is currently being closed.
+ * @retval ::NRF_SUCCESS Otherwise.
+ */
+ SVCALL(SD_RADIO_SESSION_CLOSE, uint32_t, sd_radio_session_close(void));
+
+/**@brief Requests a radio timeslot.
+ *
+ * @note The request type is determined by p_request->request_type, and can be one of @ref NRF_RADIO_REQ_TYPE_EARLIEST
+ * and @ref NRF_RADIO_REQ_TYPE_NORMAL. The first request in a session must always be of type @ref NRF_RADIO_REQ_TYPE_EARLIEST.
+ * @note For a normal request (@ref NRF_RADIO_REQ_TYPE_NORMAL), the start time of a radio timeslot is specified by
+ * p_request->distance_us and is given relative to the start of the previous timeslot.
+ * @note A too small p_request->distance_us will lead to a @ref NRF_EVT_RADIO_BLOCKED event.
+ * @note Timeslots scheduled too close will lead to a @ref NRF_EVT_RADIO_BLOCKED event.
+ * @note See the SoftDevice Specification for more on radio timeslot scheduling, distances and lengths.
+ * @note If an opportunity for the first radio timeslot is not found before 100 ms after the call to this
+ * function, it is not scheduled, and instead a @ref NRF_EVT_RADIO_BLOCKED event is sent.
+ * The application may then try to schedule the first radio timeslot again.
+ * @note Successful requests will result in nrf_radio_signal_callback_t(@ref NRF_RADIO_CALLBACK_SIGNAL_TYPE_START).
+ * Unsuccessful requests will result in a @ref NRF_EVT_RADIO_BLOCKED event, see @ref NRF_SOC_EVTS.
+ * @note The jitter in the start time of the radio timeslots is +/- @ref NRF_RADIO_START_JITTER_US us.
+ * @note The nrf_radio_signal_callback_t(@ref NRF_RADIO_CALLBACK_SIGNAL_TYPE_START) call has a latency relative to the
+ * specified radio timeslot start, but this does not affect the actual start time of the timeslot.
+ * @note NRF_TIMER0 is reset at the start of the radio timeslot, and is clocked at 1MHz from the high frequency
+ * (16 MHz) clock source. If p_request->hfclk_force_xtal is true, the high frequency clock is
+ * guaranteed to be clocked from the external crystal.
+ * @note The SoftDevice will neither access the NRF_RADIO peripheral nor the NRF_TIMER0 peripheral
+ * during the radio timeslot.
+ *
+ * @param[in] p_request Pointer to the request parameters.
+ *
+ * @retval ::NRF_ERROR_FORBIDDEN If session not opened or the session is not IDLE.
+ * @retval ::NRF_ERROR_INVALID_ADDR If the p_request pointer is invalid.
+ * @retval ::NRF_ERROR_INVALID_PARAM If the parameters of p_request are not valid.
+ * @retval ::NRF_SUCCESS Otherwise.
+ */
+ SVCALL(SD_RADIO_REQUEST, uint32_t, sd_radio_request(nrf_radio_request_t const * p_request));
+
+/**@brief Write register protected by the SoftDevice
+ *
+ * This function writes to a register that is write-protected by the SoftDevice. Please refer to your
+ * SoftDevice Specification for more details about which registers that are protected by SoftDevice.
+ * This function can write to the following protected peripheral:
+ * - BPROT
+ *
+ * @note Protected registers may be read directly.
+ * @note Register that are write-once will return @ref NRF_SUCCESS on second set, even the value in
+ * the register has not changed. See the Product Specification for more details about register
+ * properties.
+ *
+ * @param[in] p_register Pointer to register to be written.
+ * @param[in] value Value to be written to the register.
+ *
+ * @retval ::NRF_ERROR_INVALID_ADDR This function can not write to the reguested register.
+ * @retval ::NRF_SUCCESS Value successfully written to register.
+ *
+ */
+SVCALL(SD_PROTECTED_REGISTER_WRITE, uint32_t, sd_protected_register_write(volatile uint32_t * p_register, uint32_t value));
+
+/**@} */
+
+#ifdef __cplusplus
+}
+#endif
+#endif // NRF_SOC_H__
+
+/**@} */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/softdevice/s132/headers/nrf_svc.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/softdevice/s132/headers/nrf_svc.h
new file mode 100644
index 0000000..292c692
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/softdevice/s132/headers/nrf_svc.h
@@ -0,0 +1,90 @@
+/*
+ * Copyright (c) 2012 - 2017, 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ */
+
+#ifndef NRF_SVC__
+#define NRF_SVC__
+
+#include "stdint.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifdef SVCALL_AS_NORMAL_FUNCTION
+#define SVCALL(number, return_type, signature) return_type signature
+#else
+
+#ifndef SVCALL
+#if defined (__CC_ARM)
+#define SVCALL(number, return_type, signature) return_type __svc(number) signature
+#elif defined (__GNUC__)
+#ifdef __cplusplus
+#define GCC_CAST_CPP (uint16_t)
+#else
+#define GCC_CAST_CPP
+#endif
+#define SVCALL(number, return_type, signature) \
+ _Pragma("GCC diagnostic push") \
+ _Pragma("GCC diagnostic ignored \"-Wreturn-type\"") \
+ __attribute__((naked)) \
+ __attribute__((unused)) \
+ static return_type signature \
+ { \
+ __asm( \
+ "svc %0\n" \
+ "bx r14" : : "I" (GCC_CAST_CPP number) : "r0" \
+ ); \
+ } \
+ _Pragma("GCC diagnostic pop")
+
+#elif defined (__ICCARM__)
+#define PRAGMA(x) _Pragma(#x)
+#define SVCALL(number, return_type, signature) \
+PRAGMA(swi_number = (number)) \
+ __swi return_type signature;
+#else
+#define SVCALL(number, return_type, signature) return_type signature
+#endif
+#endif // SVCALL
+
+#endif // SVCALL_AS_NORMAL_FUNCTION
+
+#ifdef __cplusplus
+}
+#endif
+#endif // NRF_SVC__
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/softdevice/s132/hex/s132_nrf52_6.0.0_licence-agreement.txt b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/softdevice/s132/hex/s132_nrf52_6.0.0_licence-agreement.txt
new file mode 100644
index 0000000..a71adee
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/softdevice/s132/hex/s132_nrf52_6.0.0_licence-agreement.txt
@@ -0,0 +1,35 @@
+Copyright (c) 2007 - 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, except as embedded into a Nordic
+ Semiconductor ASA integrated circuit in a product or a software update for
+ such product, 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.
+
+4. This software, with or without modification, must only be used with a
+ Nordic Semiconductor ASA integrated circuit.
+
+5. Any software provided in binary form under this license must not be reverse
+ engineered, decompiled, modified and/or disassembled.
+
+THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/softdevice/s132/hex/s132_nrf52_6.0.0_softdevice.hex b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/softdevice/s132/hex/s132_nrf52_6.0.0_softdevice.hex
new file mode 100644
index 0000000..f30de08
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/softdevice/s132/hex/s132_nrf52_6.0.0_softdevice.hex
@@ -0,0 +1,9278 @@
+:020000040000FA
+:1000000000040020E90800007D050000C908000088
+:1000100087050000910500009B050000000000001E
+:100020000000000000000000000000000D090000BA
+:10003000A505000000000000AF050000B9050000A4
+:10004000C3050000CD050000D7050000E105000054
+:10005000EB050000F5050000FF05000009060000A3
+:10006000130600001D0600002706000031060000F0
+:100070003B060000450600004F0600005906000040
+:10008000630600006D060000770600008106000090
+:100090008B060000950600009F060000A9060000E0
+:1000A000B3060000BD060000C7060000D106000030
+:1000B000DB060000E5060000EF060000F906000080
+:1000C000030700000D0700001707000021070000CC
+:1000D0002B070000350700003F070000490700001C
+:1000E000530700005D07000067070000710700006C
+:1000F0007B070000850700008F07000099070000BC
+:10010000A30700001FB500F003F88DE80F001FBD26
+:1001100000F0E0BB1FB56FF00100009040100390AD
+:10012000029001904FF010208069000B420900F00E
+:100130001F045DF822300120A04083434DF8223097
+:10014000684600F045F91FBDF0B54FF6FF734FF458
+:10015000B4751A466E1E11E0A94201D3344600E080
+:100160000C46091B30F8027B641E3B441A44F9D14B
+:100170009CB204EB134394B204EB12420029EBD17E
+:1001800098B200EB134002EB124140EA0140F0BD8F
+:10019000DE4992B00446D1E90001CDE91001FF2209
+:1001A0004021684600F03CFB94E80F008DE80F000A
+:1001B000684610A902E004C841F8042D8842FAD12B
+:1001C00010216846FFF7C0FF1090AA208DF8440068
+:1001D000FFF7A0FF00F0F3F84FF01024A069102201
+:1001E0006946803000F002F9A069082210A900F0E9
+:1001F000FDF800F0D8F84FF080510A6949690068AD
+:100200004A43824201D8102070470020704710B541
+:10021000D0E900214FF0805002EB8103026944696C
+:100220006243934209D84FF01022536903EB8103D4
+:100230000169406941438B4201D9092010BD5069D1
+:10024000401C01D0002010BD0F2010BD70B501680A
+:100250000446AF4D4FF01020072952D2DFE801F0DD
+:10026000330419293C1E2500D4E902656468294637
+:10027000304600F0CDF82A462146304600F0B6F868
+:10028000AA002146304600F09FFA002800D0032043
+:1002900070BD00F051FB4FF4805007E0201DFFF7C8
+:1002A000AAFF0028F4D100F047FB60682860002016
+:1002B00070BD241D94E80700920000F085FA002824
+:1002C000F6D00E2070BD8069401C12D0201DFFF7B3
+:1002D0009EFF0028F6D109E08069401C09D0201D4E
+:1002E000FFF789FF0028EDD1606820B12046FFF7B5
+:1002F0004FFF042070BDFFF70DFF00F060F800F025
+:1003000052F8072070BD10B50C46182802D0012005
+:10031000086010BD2068FFF799FF206010BD4FF006
+:100320001024A069401C05D0A569A66980353079E4
+:10033000AA2808D06069401C2DD060690068401C64
+:1003400029D060692CE010212846FFF7FDFE3168B6
+:1003500081421CD1A16901F18002C03105E030B1B8
+:1003600008CA51F8040D984201D1012000E0002094
+:100370008A42F4D158B1286810B1042803D0FEE7AE
+:10038000284600F057F862496868086008E000F005
+:1003900016F800F008F84FF480500168491C01D0AD
+:1003A00000F0A4FAFEE7BFF34F8F5A4801685A4A9B
+:1003B00001F4E06111430160BFF34F8FFEE74FF09E
+:1003C00010208169491C02D0806900F0AEB87047E6
+:1003D000524A01681160121D416811604F4A8168DC
+:1003E00010321160111DC068086070472DE9F0419E
+:1003F00017460D460646002406E03046296800F000
+:10040000A7F8641C2D1D361DBC42F6D3BDE8F08153
+:1004100070B50C4605464FF4806608E0284600F0AB
+:1004200084F8B44205D3A4F5806405F58055002C0A
+:10043000F4D170BD4168044609B1012500E00025F2
+:100440004FF010267069A268920000F0BDF9C8B1A3
+:10045000204600F01AF89DB17669A56864684FF4EB
+:10046000002084420AD2854208D229463046FFF74E
+:10047000CFFF2A4621463046FFF7B8FFFFF79FFF20
+:10048000FFF791FFFFF746FEF8E72DE9FF414FF038
+:100490001024616980680D0B01EB800000F6FF708D
+:1004A000010B0020009001900290024603906846E4
+:1004B00001230BE0560902F01F0C50F8267003FAD6
+:1004C0000CFC47EA0C0740F82670521CAA42F1D3F4
+:1004D0000AE04A0901F01F0650F8225003FA06F616
+:1004E000354340F82250491C8029F2D3A169090BF9
+:1004F0004A0901F01F0150F822408B409C4340F80C
+:100500002240FFF765FFBDE8FF8100005C090000A5
+:10051000000000200CED00E00400FA050006004099
+:10052000144801680029FCD07047134A0221116069
+:1005300010490B68002BFCD00F4B1B1D186008687E
+:100540000028FCD00020106008680028FCD070470C
+:10055000094B10B501221A60064A1468002CFCD021
+:10056000016010680028FCD0002018601068002886
+:10057000FCD010BD00E4014004E5014008208F4993
+:1005800009680958084710208C4909680958084724
+:1005900014208A49096809580847182087490968BA
+:1005A0000958084730208549096809580847382004
+:1005B00082490968095808473C2080490968095858
+:1005C000084740207D4909680958084744207B496D
+:1005D00009680958084748207849096809580847B0
+:1005E0004C20764909680958084750207349096822
+:1005F0000958084754207149096809580847582084
+:100600006E490968095808475C206C49096809580F
+:100610000847602069490968095808476420674904
+:100620000968095808476820644909680958084753
+:100630006C20624909680958084770205F490968B9
+:100640000958084774205D49096809580847782007
+:100650005A490968095808477C20584909680958C7
+:10066000084780205549096809580847842053499C
+:1006700009680958084788205049096809580847F7
+:100680008C204E4909680958084790204B49096851
+:10069000095808479420494909680958084798208B
+:1006A00046490968095808479C204449096809587F
+:1006B0000847A0204149096809580847A4203F4934
+:1006C000096809580847A8203C490968095808479B
+:1006D000AC203A49096809580847B02037490968E9
+:1006E00009580847B4203549096809580847B8200F
+:1006F0003249096809580847BC2030490968095837
+:100700000847C0202D49096809580847C4202B49CB
+:10071000096809580847C82028490968095808473E
+:10072000CC202649096809580847D0202349096880
+:1007300009580847D4202149096809580847D82092
+:100740001E49096809580847DC201C4909680958EE
+:100750000847E0201949096809580847E420174963
+:10076000096809580847E8201449096809580847E2
+:10077000EC201249096809580847F0200F49096818
+:1007800009580847F4200D49096809580847F82016
+:100790000A49096809580847FC20084909680958A6
+:1007A00008475FF480700549096809580847000048
+:1007B00003480449024A034B704700000000002030
+:1007C000680900006809000040EA010310B59B07B2
+:1007D0000FD1042A0DD310C808C9121F9C42F8D0AB
+:1007E00020BA19BA884201D9012010BD4FF0FF305C
+:1007F00010BD1AB1D30703D0521C07E0002010BD72
+:1008000010F8013B11F8014B1B1B07D110F8013BFD
+:1008100011F8014B1B1B01D1921EF1D1184610BDDE
+:1008200002F0FF0343EA032242EA024200F005B865
+:100830007047704770474FF000020429C0F01280E3
+:1008400010F0030C00F01B80CCF1040CBCF1020F83
+:1008500018BF00F8012BA8BF20F8022BA1EB0C0158
+:1008600000F00DB85FEAC17C24BF00F8012B00F84E
+:10087000012B48BF00F8012B70474FF0000200B574
+:10088000134694469646203922BFA0E80C50A0E8B3
+:100890000C50B1F12001BFF4F7AF090728BFA0E861
+:1008A0000C5048BF0CC05DF804EB890028BF40F82D
+:1008B000042B08BF704748BF20F8022B11F0804F6F
+:1008C00018BF00F8012B7047014B1B68DB68184705
+:1008D0000000002009480A497047FFF7FBFFFFF7B7
+:1008E00011FC00BD20BFFDE7064B1847064A10600B
+:1008F000016881F30888406800470000680900002B
+:10090000680900001F030000000000201EF0040F13
+:100910000CBFEFF30881EFF3098188690238007892
+:10092000182803D100E00000074A1047074A126860
+:100930002C3212681047000000B5054B1B68054AB1
+:100940009B58984700BD00000703000000000020EE
+:100950005809000004000000001000000000000022
+:0809600000FFFFFF0090D0032F
+:10100000E0120020D1430200192F000043430200E8
+:10101000192F0000192F0000192F000000000000F8
+:101020000000000000000000000000002944020051
+:10103000192F000000000000192F0000192F0000D8
+:101040009144020097440200192F0000192F00005C
+:10105000192F0000192F0000192F0000192F000070
+:101060009D440200192F0000192F0000A344020024
+:10107000192F0000A9440200AF440200B544020049
+:10108000192F0000192F0000192F0000192F000040
+:10109000192F0000192F0000192F0000192F000030
+:1010A000192F0000BB440200192F0000192F000067
+:1010B000192F0000192F0000192F0000192F000010
+:1010C000C1440200192F0000192F0000192F000041
+:1010D000192F0000192F0000192F0000192F0000F0
+:1010E000192F0000192F0000192F0000192F0000E0
+:1010F000192F0000192F0000192F0000192F0000D0
+:10110000192F0000192F000000F002F823F04DF90C
+:101110000AA090E8000C82448344AAF10107DA4552
+:1011200001D123F042F9AFF2090EBAE80F0013F033
+:10113000010F18BFFB1A43F0010318479038020053
+:10114000B03802000A444FF0000C10F8013B13F0D5
+:10115000070408BF10F8014B1D1108BF10F8015B10
+:10116000641E05D010F8016B641E01F8016BF9D103
+:1011700013F0080F1EBF10F8014BAD1C0C1B09D15A
+:101180006D1E58BF01F801CBFAD505E014F8016BCC
+:1011900001F8016B6D1EF9D59142D6D3704700005E
+:1011A0000023002400250026103A28BF78C1FBD870
+:1011B000520728BF30C148BF0B6070471FB500F011
+:1011C0003DF88DE80F001FBD1EF0040F0CBFEFF3BC
+:1011D0000880EFF30980014A10470000752E0000D7
+:1011E0008269034981614FF001001044704700009B
+:1011F000F511000001B41EB400B512F00FFE01B4E9
+:101200000198864601BC01B01EBD0000F0B4404606
+:10121000494652465B460FB402A0013001B506486C
+:10122000004700BF01BC86460FBC804689469246F7
+:101230009B46F0BC704700000911000023F0B2B8D3
+:1012400070B51A4C054609202070A01C00F05FF80C
+:101250005920A08029462046BDE8704008F05CB8BF
+:1012600008F065B870B50C461149097829B1A0F1AC
+:1012700060015E2908D3012013E0602804D06928AA
+:1012800002D043F201000CE020CC0A4E94E80E009C
+:1012900006EB8000A0F58050241FD0F8806E284611
+:1012A000B047206070BD012070470000080000209A
+:1012B0001C0000202845020010B504460021012032
+:1012C00000F03DF800210B2000F039F8042119202E
+:1012D00000F035F804210D2000F031F804210E2033
+:1012E00000F02DF804210F2000F029F80421C84354
+:1012F00000F025F80621162000F021F8062115201F
+:1013000000F01DF82046FFF79BFF002010BDA8212C
+:1013100001807047FFF7A4BF11487047104870471D
+:10132000104A10B514680F4B0F4A08331A60FFF7C4
+:1013300099FF0C48001D046010BD704770474907B5
+:10134000090E002806DA00F00F0000F1E02080F816
+:10135000141D704700F1E02080F800147047000071
+:1013600003F900421005024001000001FE4800217F
+:1013700001604160018170472DE9F743044692B056
+:101380009146406813F00EF840B1606813F013F80E
+:1013900020B9607800F00300022801D0012000E0AD
+:1013A0000020F14E3072484612F0B8FF18B11020FC
+:1013B00015B0BDE8F0834946012001F018FF002870
+:1013C000F6D101258DF842504FF4C050ADF84000E1
+:1013D000002210A9284606F047FC0028E8D18DF825
+:1013E00042504FF428504FF00008ADF840004746F7
+:1013F0001C216846CDF81C8022F07BFF9DF81C0064
+:1014000008AA20F00F00401C20F0F00010308DF8EA
+:101410001C0020788DF81D0061789DF81E0061F396
+:10142000420040F001008DF81E009DF800000AA95E
+:1014300040F002008DF800002089ADF83000ADF8D2
+:101440003270608907AFADF834000B97606810AC5C
+:101450000E900A94684606F0FCF90028A8D1BDF861
+:10146000200030808DF8425042F60120ADF8400057
+:101470009DF81E0008AA20F00600801C20F0010044
+:101480008DF81E000220ADF83000ADF8340013A82E
+:101490000E900AA9684606F0DCF9002888D1BDF84C
+:1014A00020007080311D484600F033F9002887D1B4
+:1014B0008DF8425042F6A620ADF840001C21684647
+:1014C000CDF81C8022F015FF9DF81C00ADF83450BB
+:1014D00020F00F00401C20F0F00010308DF81C00B0
+:1014E0009DF81D0008AA20F0FF008DF81D009DF852
+:1014F0001E000AA920F0060040F00100801C8DF8B3
+:101500001E009DF800008DF8445040F002008DF858
+:101510000000CDE90A4711A80E90ADF8305068469A
+:1015200006F097F9002899D1BDF82000F08000203E
+:101530003EE73EB504460820ADF80000204612F014
+:10154000EDFE08B110203EBD2146012001F04FFE06
+:101550000028F8D12088ADF804006088ADF80600B6
+:10156000A088ADF80800E088ADF80A007E4801AB1D
+:101570006A468088002106F071FDBDF80010082938
+:10158000E1D003203EBD1FB5044600200290082094
+:10159000ADF80800CDF80CD0204612F0BFFE10B117
+:1015A000102004B010BD704802AA81884FF6FF7069
+:1015B00006F096FF0028F4D1BDF80810082901D0E4
+:1015C0000320EEE7BDF800102180BDF80210618015
+:1015D000BDF80410A180BDF80610E180E1E701B577
+:1015E00082B00220ADF800005F4802AB6A46408836
+:1015F000002106F033FDBDF80010022900D00320C1
+:101600000EBD1CB5002100910221ADF80010019023
+:1016100012F0AAFE08B110201CBD53486A4641884A
+:101620004FF6FF7006F05CFFBDF800100229F3D002
+:1016300003201CBDFEB54C4C06461546207A0F46CD
+:10164000C00705D0084612F069FE18B11020FEBD93
+:101650000F20FEBDF82D01D90C20FEBD304612F042
+:101660005DFE18BB208801A905F03CFE0028F4D1DE
+:1016700030788DF80500208801A906F0CEFC0028FE
+:10168000EBD100909DF800009DF8051040F002009D
+:101690008DF80000090703D040F008008DF8000025
+:1016A0002088694606F056FC0028D6D1ADF80850CF
+:1016B00020883B4602AA002106F0D0FCBDF80810A5
+:1016C000A942CAD00320FEBD7CB50546002000908B
+:1016D00001900888ADF800000C462846019512F0EC
+:1016E00061FE18B9204612F03FFE08B110207CBD03
+:1016F00015B1BDF8000050B11B486A4601884FF68D
+:10170000FF7006F0EDFEBDF8001021807CBD0C20BE
+:101710007CBD30B593B0044600200D4600901421E6
+:1017200001A822F0E6FD1C2108A822F0E2FD9DF8A8
+:101730000000CDF808D020F00F00401C20F0F00091
+:1017400010308DF800009DF8010020F0FF008DF8AA
+:1017500001009DF8200040F002008DF820000120DB
+:101760008DF8460002E000000C02002042F6042042
+:10177000ADF8440011A801902088ADF83C006088C5
+:10178000ADF83E00A088ADF84000E088ADF842001A
+:101790009DF8020006AA20F00600801C20F001003F
+:1017A0008DF802000820ADF80C00ADF810000FA86D
+:1017B000059001A908A806F04CF8002803D1BDF84F
+:1017C00018002880002013B030BD0000F0B5007B69
+:1017D000059F1E4614460D46012800D0FFDF0C2051
+:1017E00030803A203880002C08D0287A032806D090
+:1017F000287B012800D0FFDF17206081F0BDA88979
+:10180000FBE72DE9F04786B0144691F80C900E9A4C
+:101810000D46B9F1010F0BD01021007B2E8A8846AE
+:10182000052807D0062833D0FFDF06B0BDE8F087D3
+:101830000221F2E7E8890C2100EB400001EB4000B7
+:10184000188033201080002CEFD0E88960810027B9
+:101850001AE00096688808F1020301AA696900F09D
+:1018600084FF06EB0800801C07EB470186B204EBFF
+:101870004102BDF8040090810DF1060140460E3290
+:1018800010F018FE7F1CBFB26089B842E1D8CCE7E7
+:1018900034201080E889B9F1010F11D0122148439A
+:1018A0000E301880002CC0D0E88960814846B9F11C
+:1018B000010F00D00220207300270DF1040A1FE061
+:1018C0000621ECE70096688808F1020301AA69691D
+:1018D00000F04BFF06EB0800801C86B2B9F1010F47
+:1018E00012D007EBC70004EB4000BDF80410C18123
+:1018F00010220AF10201103022F05AFC7F1CBFB204
+:101900006089B842DED890E707EB470104EB41025B
+:10191000BDF80400D0810AF102014046103210F0F7
+:10192000C9FDEBE72DE9F0470E4688B090F80CC0F2
+:1019300096F80C80378AF5890C20109902F10C0476
+:101940004FF0000ABCF1030F08D0BCF1040F3ED0E9
+:10195000BCF1070F7DD0FFDF08B067E705EB850C12
+:1019600000EB4C00188031200880002AF4D0A8F148
+:10197000060000F0FF09558125E0182101A822F09A
+:10198000B8FC00977088434601AA716900F0EDFE2B
+:10199000BDF804002080BDF80600E080BDF8080016
+:1019A0002081A21C0DF10A01484610F083FDB9F117
+:1019B000000F00D018B184F804A0A4F802A007EB2F
+:1019C000080087B20A346D1EADB2D6D2C4E705EB6B
+:1019D000850C00EB4C00188032200880002ABBD018
+:1019E000A8F1050000F0FF09558137E000977088E5
+:1019F000434601AA716900F0B8FE9DF80600BDF8E3
+:101A00000410E1802179420860F3000162F3410192
+:101A1000820862F38201C20862F3C301020962F321
+:101A20000411420962F34511820962F386112171A2
+:101A3000C0096071BDF80700208122460DF109013F
+:101A4000484610F037FD18B184F802A0A4F800A0B1
+:101A500000E007E007EB080087B20A346D1EADB264
+:101A6000C4D279E7A8F1020084B205FB08F000F1C6
+:101A70000E0CA3F800C035230B80002AA6D0558198
+:101A80009481009783B270880E32716900F06DFE08
+:101A900062E72DE9F84F1E460A9D0C4681462AB1A1
+:101AA000607A00F58070D080E089108199F80C0090
+:101AB0000C274FF000084FF00E0A0D2873D2DFE814
+:101AC00000F09E070E1C28303846556A7373730069
+:101AD000214648460095FFF779FEBDE8F88F207B48
+:101AE0009146082802D0032800D0FFDF378030203D
+:101AF0000AE000BFA9F80A80EFE7207B914604289E
+:101B000000D0FFDF378031202880B9F1000FF1D1FC
+:101B1000E3E7207B9146042800D0FFDF37803220A6
+:101B2000F2E7207B9146022800D0FFDF3780332088
+:101B3000EAE7207B1746022800D0FFDF3420A6F812
+:101B400000A02880002FC8D0A7F80A80C5E7207B16
+:101B50001746042800D0FFDF3520A6F800A0288013
+:101B6000002FBAD04046A7F80A8012E0207B174623
+:101B7000052802D0062800D0FFDF10203080362054
+:101B80002880002FA9D0E0897881A7F80E80B9F8C5
+:101B90000E00B881A1E7207B9146072800D0FFDF27
+:101BA00037803720B0E72AE04FF0120018804FF05E
+:101BB00038001700288090D0E0897881A7F80E803F
+:101BC000A7F8108099F80C000A2805D00B2809D036
+:101BD0000C280DD0FFDF80E7207B0A2800D0FFDF34
+:101BE00001200AE0207B0B2800D0FFDF042004E066
+:101BF000207B0C2800D0FFDF052038736DE7FFDF66
+:101C00006BE770B50C46054601F025FC20B1007865
+:101C1000222804D2082070BD43F2020070BD0521C5
+:101C200028460EF0C5FE206008B1002070BD0320DC
+:101C300070BD30B44880087820F00F00C01C20F040
+:101C4000F000903001F8080B1DCA81E81D0030BC7F
+:101C500007F0E3BB2DE9FF4784B0002782460297D7
+:101C600007989046894612300AF014F9401D20F07A
+:101C70000306079828B907A95046FFF7C2FF0028B6
+:101C800054D1B9F1000F05D00798017B19BB052588
+:101C900004681BE098F80000092803D00D2812D032
+:101CA000FFDF46E0079903254868B0B3497B4288C7
+:101CB0007143914239D98AB2B3B2011D0EF0EBFCE7
+:101CC0000446078002E0079C042508340CB12088F4
+:101CD00010B1032D29D02CE00798012112300AF011
+:101CE0000BF9ADF80C00024602AB2946504608F04D
+:101CF000F0F9070001D1A01C029007983A46123073
+:101D0000C8F80400A8F802A003A94046029B0AF004
+:101D100000F9D8B10A2817D200E006E0DFE800F0A9
+:101D200007091414100B0D141412132014E60020CC
+:101D300012E6112010E608200EE643F203000BE63F
+:101D4000072009E60D2007E6032005E6BDF80C0094
+:101D50002346CDE900702A465046079900F015FD4C
+:101D600057B9032D08D10798B3B2417B406871433E
+:101D70008AB2011D0EF0A3FCB9F1000FD7D007996C
+:101D800081F80C90D3E72DE9FE4F91461A881C4646
+:101D90008A468046FAB102AB494608F09AF9050036
+:101DA00019D04046A61C27880EF046FF324607266B
+:101DB00029463B4600960EF054FB20882346CDE989
+:101DC00000504A465146404600F0DFFC002020808B
+:101DD0000120BDE8FE8F0020FBE710B586B01C4651
+:101DE000AAB104238DF800301388ADF8083052886A
+:101DF000ADF80A208A788DF80E200988ADF80C100D
+:101E000000236A462146FFF725FF06B010BD1020CB
+:101E1000FBE770B50D4605210EF0CAFD040000D1A8
+:101E2000FFDF294604F11200BDE870400AF04DB80A
+:101E30002DE9F8430D468046002607F0EBFA0446EC
+:101E40002878102878D2DFE800F0773B345331311E
+:101E5000123131310831313131312879001FC0B2AE
+:101E6000022801D0102810D114BBFFDF35E004B9DF
+:101E7000FFDF052140460EF09BFD007B032806D0C6
+:101E800004280BD0072828D0FFDF072655E0287943
+:101E9000801FC0B2022820D050B1F6E72879401F39
+:101EA000C0B2022819D0102817D0EEE704B9FFDF1E
+:101EB00013E004B9FFDF287901280ED1172137E09C
+:101EC000052140460EF074FD070000D1FFDF07F149
+:101ED0001201404609F0D6FF2CB12A462146404661
+:101EE000FFF7A7FE29E01321404602F0A7FD24E0FA
+:101EF00004B9FFDF052140460EF05AFD060000D16F
+:101F0000FFDF694606F1120009F0C6FF060000D0A7
+:101F1000FFDFA988172901D2172200E00A46BDF881
+:101F20000000824202D9014602E005E01729C5D32C
+:101F3000404600F03AFCD0E7FFDF3046BDE8F883CA
+:101F4000401D20F0030219B102FB01F0001D00E06A
+:101F500000201044704713B5009848B1002468462B
+:101F60000EF043FB002C02D1F74A009911601CBD12
+:101F700001240020F4E72DE9F0470C461546242102
+:101F8000204622F0B6F905B9FFDFA87860732888EB
+:101F9000DFF8B4A3401D20F00301AF788946DAF8DA
+:101FA00000000EF040FB060000D1FFDF4FF00008FC
+:101FB0002660A6F8008077B109FB07F1091D0AD059
+:101FC000DAF800000EF02FFB060000D1FFDF66609C
+:101FD000C6F8008001E0C4F80480298804F11200EA
+:101FE000BDE8F04709F040BF2DE9F047804601F118
+:101FF00012000D46814609F04DFF401DD24F20F0E2
+:1020000003026E7B1446296838680EF037FB3EB138
+:1020100004FB06F2121D03D0696838680EF02EFB2F
+:1020200005200EF06DFC044605200EF071FC201A10
+:10203000012802D138680EF0EBFA49464046BDE867
+:10204000F04709F026BF70B5054605210EF0B0FC3B
+:10205000040000D1FFDF04F112012846BDE8704002
+:1020600009F010BF2DE9F04F91B04FF0000BADF823
+:1020700034B0ADF804B047880C46054692460521B9
+:1020800038460EF095FC060000D1FFDF24B1A78092
+:10209000A4F806B0A4F808B0297809220B20B2EB06
+:1020A000111F7DD12A7A04F1100138274FF00C0856
+:1020B0004FF001090391102A73D2DFE802F072F2A7
+:1020C000F1F07F08D2888D9F3DDBF3EEB6B6307B12
+:1020D000022800D0FFDFA88908EBC001ADF804108A
+:1020E0003021ADF83410002C25D06081B5F80E9069
+:1020F00000271DE004EBC708317C88F80E10F18939
+:10210000A8F80C10CDF800906888042304AA296967
+:1021100000F02BFBBDF81010A8F8101009F1040016
+:10212000BDF812107F1C1FFA80F9A8F81210BFB278
+:102130006089B842DED80DE1307B022800D0FFDF95
+:10214000E98908EBC100ADF804003020ADF8340097
+:10215000287B0A90001FC0B20F90002CEBD0618149
+:10216000B5F81090002725E0CDF8009068886969DF
+:1021700003AA0A9B00F0F9FA0A9804EBC70848443E
+:102180001FFA80F908F10C0204A90F9810F092F9D7
+:1021900018B188F80EB0A8F80CB0BDF80C1001E02A
+:1021A000D4E0CFE0A8F81010BDF80E107F1CA8F8FE
+:1021B0001210BFB26089B842D6D8CBE00DA800900B
+:1021C00001AB224629463046FFF71BFBC2E0307BBD
+:1021D000082805D0FFDF03E0307B082800D0FFDFB0
+:1021E000E8891030ADF804003620ADF83400002C3A
+:1021F0003FD0A9896181F189A18127E0307B09283D
+:1022000000D0FFDFA88900F10C01ADF804103721E0
+:10221000ADF83410002C2CD06081E8890090AB8997
+:10222000688804F10C02296956E0E88939211030E8
+:1022300080B2ADF80400ADF83410002C74D0A98938
+:102240006181287A0E280AD002212173E989E1816F
+:10225000288A0090EB8968886969039A3CE001212B
+:10226000F3E70DA8009001AB224629463046FFF760
+:1022700059FB6FE0307B0A2800D0FFDF1220ADF859
+:102280000400ADF834704CB3A9896181A4F810B092
+:10229000A4F80EB084F80C905CE020E002E031E09D
+:1022A00039E042E0307B0B2800D0FFDF288AADF810
+:1022B00034701230ADF8040084B104212173A9896F
+:1022C0006181E989E181298A2182688A00902B8ACB
+:1022D000688804F11202696900F047FA3AE0307B3D
+:1022E0000C2800D0FFDF1220ADF80400ADF83470E8
+:1022F0003CB305212173A4F80AB0A4F80EB0A4F8E9
+:1023000010B027E00DA8009001AB224629463046C8
+:10231000FFF75CFA1EE00DA8009001AB22462946AB
+:102320003046FFF7B6FB15E034E03B21ADF8040082
+:10233000ADF8341074B3A4F80690A4F808B084F88B
+:102340000AB007E0FFDF05E010000020297A01292C
+:1023500017D0FFDFBDF80400AAF800006CB1BDF88B
+:1023600034002080BDF804006080BDF834003928B6
+:1023700003D03C2801D086F80CB011B00020BDE895
+:10238000F08F3C21ADF80400ADF8341014B1697A37
+:10239000A172DFE7AAF80000EFE72DE9F8435688BD
+:1023A0000F4680461546052130460EF001FB04001D
+:1023B00000D1FFDF123400943B46414630466A6844
+:1023C00009F0DBFEBAE570B50D4605210EF0F0FA16
+:1023D000040000D1FFDF294604F11200BDE870407F
+:1023E00009F065BD70B50D4605210EF0E1FA040057
+:1023F00000D1FFDF294604F11200BDE8704009F06A
+:1024000083BD70B5054605210EF0D2FA040000D157
+:10241000FFDF04F1080321462846BDE8704004228E
+:10242000B1E470B5054605210EF0C2FA040000D1F2
+:10243000FFDF214628462368BDE870400522A2E45C
+:1024400070B5064605210EF0B3FA040000D1FFDF97
+:1024500004F1120009F01EFD401D20F0030511E0FB
+:10246000011D00880322431821463046FFF78BFCEC
+:1024700000280BD0607BABB2684382B26068011D5C
+:102480000EF053F9606841880029E9D170BD70B53C
+:102490000E46054606F0BEFF040000D1FFDF012016
+:1024A000207266726580207820F00F00C01C20F03A
+:1024B000F00030302070BDE8704006F0AEBF2DE96E
+:1024C000F0438BB00D461446814606A9FFF799FBF1
+:1024D000002814D14FF6FF7601274FF420588CB115
+:1024E00003208DF800001020ADF8100007A805901B
+:1024F00007AA204604A90FF0FCFF78B107200BB013
+:10250000BDE8F0830820ADF808508DF80E708DF806
+:102510000000ADF80A60ADF80C800CE00698A178D8
+:1025200001742188C1818DF80E70ADF80850ADF8A6
+:102530000C80ADF80A606A4602214846069BFFF708
+:1025400089FBDCE708B501228DF8022042F6020281
+:10255000ADF800200A4603236946FFF73EFC08BD9C
+:1025600008B501228DF8022042F60302ADF80020E2
+:102570000A4604236946FFF730FC08BD00B587B062
+:1025800079B102228DF800200A88ADF80820498828
+:10259000ADF80A1000236A460521FFF75BFB07B080
+:1025A00000BD1020FBE709B1072316E407207047A0
+:1025B00070B588B00D461446064606A9FFF721FB04
+:1025C00000280ED17CB10620ADF808508DF800002F
+:1025D000ADF80A40069B6A460821DC813046FFF7C9
+:1025E00039FB08B070BD05208DF80000ADF808502B
+:1025F000F0E700B587B059B107238DF80030ADF88A
+:102600000820039100236A460921FFF723FBC6E750
+:102610001020C4E770B588B00C460646002506A910
+:10262000FFF7EFFA0028DCD106980121123009F0FB
+:1026300063FC9CB12178062921D2DFE801F0200556
+:1026400005160318801E80B2C01EE28880B20AB14F
+:10265000A3681BB1824203D90C20C2E71020C0E757
+:10266000042904D0A08850B901E00620B9E7012967
+:1026700013D0022905D004291CD005292AD007200F
+:10268000AFE709208DF800006088ADF80800E08809
+:10269000ADF80A00A068039023E00A208DF800003E
+:1026A0006088ADF80800E088ADF80A00A0680A2547
+:1026B000039016E00B208DF800006088ADF808004C
+:1026C000A088ADF80A00E088ADF80C00A0680B25E2
+:1026D000049006E00C208DF8000060788DF808006A
+:1026E0000C256A4629463046069BFFF7B3FA78E781
+:1026F00000B587B00D228DF80020ADF8081000233A
+:102700006A461946FFF7A6FA49E700B587B071B1E6
+:1027100002228DF800200A88ADF808204988ADF81B
+:102720000A1000236A460621FFF794FA37E71020C3
+:1027300035E770B586B0064601200D46ADF80810A5
+:102740008DF80000014600236A463046FFF782FA02
+:10275000040008D12946304605F09AFC0021304695
+:1027600005F0B4FC204606B070BDF8B51C46154611
+:102770000E46069F0EF04EFA2346FF1DBCB23146B0
+:102780002A4600940DF039FEF8BD30B41146DDE95B
+:1027900002423CB1032903D0002330BC08F022BB25
+:1027A0000123FAE71A8030BC704770B50C46054625
+:1027B000FFF72FFB2146284605F079FC2846BDE8A7
+:1027C0007040012105F082BC4FF0E0224FF400413F
+:1027D0000020C2F88011204908702049900208604A
+:1027E000704730B51C4D04462878A04218BF002C15
+:1027F00002D0002818BFFFDF2878A04208BF30BDF4
+:102800002C701749154A0020ECB1164DDFF858C05E
+:10281000131F012C0DD0022C1CBFFFDF30BD086040
+:1028200003200860CCF800504FF4000010601860DE
+:1028300030BD086002200860CCF800504FF04070B6
+:102840001060186030BD086008604FF06070106064
+:1028500030BD00B5FFDF00BD1800002008F50140C5
+:1028600000F500408C02002014F5004070B50B20EC
+:1028700000F0B5F9082000F0B2F900210B2000F0BB
+:10288000C4F90021082000F0C0F9EC4C0125656076
+:10289000A5600020C4F84001C4F84401C4F8480110
+:1028A0000B2000F0A7F9082000F0A4F90B2000F09D
+:1028B0008BF9256070BD10B50B2000F090F9082051
+:1028C00000F08DF9DD48012141608160DC490A6832
+:1028D000002AFCD10021C0F84011C0F84411C0F812
+:1028E00048110B2000F086F9BDE81040082000F0E8
+:1028F00081B910B50B2000F07DF9BDE8104008202B
+:1029000000F078B900B530B1012806D0022806D011
+:10291000FFDF002000BDCB4800BDCB4800BDCA484A
+:10292000001D00BD70B5C9494FF000400860C84D9A
+:10293000C00BC5F80803C74800240460C5F840412F
+:102940000820C43500F04BF9C5F83C41C24804707A
+:1029500070BD08B5B94A002128B1012811D002285C
+:102960001CD0FFDF08BD4FF48030C2F80803C2F866
+:102970004803B3483C300160C2F84011BDE808404C
+:10298000D0E74FF40030C2F80803C2F84803AC485F
+:1029900040300160C2F84411AB480CE04FF4802095
+:1029A000C2F80803C2F84803A54844300160C2F8E1
+:1029B0004811A548001D0068009008BD70B5164676
+:1029C0000D460446022800D9FFDF00229B48012360
+:1029D00004F110018B4000EB8401C1F8405526B191
+:1029E000C1F84021C0F8043303E0C0F80833C1F84F
+:1029F0004021C0F8443370BD2DE9F0411C46154616
+:102A000030B1012834D0022839D0FFDFBDE8F08191
+:102A1000891E002221F07F411046FFF7CFFF012CD5
+:102A200024D000208C4E8A4F012470703C6189496B
+:102A300000203C3908600220091D086085490420F7
+:102A40003039086083483D350560C7F800420820EA
+:102A500000F0D0F82004C7F80403082000F0B4F810
+:102A60007A49E007091F08603470CFE70120D9E7F1
+:102A7000012B02D00022012005E00122FBE7012BFF
+:102A800004D000220220BDE8F04197E70122F9E7D7
+:102A90006B480068704770B500F0C7F8674C054692
+:102AA000D4F840010026012809D1D4F80803C00356
+:102AB00005D54FF48030C4F80803C4F84061D4F859
+:102AC000440101280CD1D4F80803800308D54FF441
+:102AD0000030C4F80803C4F84461012010F0CDFCB4
+:102AE000D4F8480101280CD1D4F80803400308D5D4
+:102AF0004FF48020C4F80803C4F84861022010F0A5
+:102B0000BCFC5648056070BD70B500F08EF8524DA3
+:102B10000446287858B1FFF705FF687820B10020F7
+:102B200085F8010010F0A9FC4C48046070BD03203A
+:102B3000F8E74FF0E0214FF40010C1F800027047B1
+:102B4000152000F057B8424901200861082000F024
+:102B500051B83F494FF47C10C1F8080300200246E9
+:102B600001EB8003C3F84025C3F84021401CC0B2EC
+:102B70000628F5D37047410A43F609525143C0F382
+:102B8000080010FB02F000F5807001EB5020704748
+:102B900010B5430B48F2376463431B0C5C020C60B6
+:102BA0002F4C03FB04002F4B4CF2F72443435B0DE7
+:102BB00013FB04F404EB402000F580704012107009
+:102BC00008681844086010BD00F01F020121914000
+:102BD0004009800000F1E020C0F80011704700F0CB
+:102BE0001F02012191404009800000F1E020C0F85F
+:102BF0008011704700F01F020121914040098000C0
+:102C000000F1E020C0F8801270474907090E002843
+:102C100006DA00F00F0000F1E02080F8141D704784
+:102C200000F1E02080F8001470470C48001F006895
+:102C30000A4A0D49121D11607047000000B00040A3
+:102C400004B500404081004044B1004008F5014017
+:102C500000800040408500403800002014050240FC
+:102C6000F7C2FFFF6F0C0100010000010A4810B518
+:102C70000468094909480831086010F092FC0648C8
+:102C8000001D046010BD0649002008604FF0E021DF
+:102C90000220C1F8800270471005024001000001C7
+:102CA000FC1F004010B50D2000F06FF8C4B26FF0AB
+:102CB000040000F06AF8C0B2844200D0FFDF3A4955
+:102CC0000120086010BD70B50D2000F048F8374CA9
+:102CD0000020C4F800010125C4F804530D2000F0C1
+:102CE00049F825604FF0E0216014C1F8000170BD83
+:102CF00010B50D2000F033F82C480121416000216F
+:102D0000C0F80011BDE810400D2000F033B828488D
+:102D100010B5046826492748083108602349D1F8CE
+:102D20000001012804D0FFDF2148001D046010BD10
+:102D30001D48001D00680022C0B2C1F8002110F03B
+:102D4000E7FFF1E710B51948D0F800110029FBD0D2
+:102D5000FFF7DDFFBDE810400D2000F00BB800F0DC
+:102D60001F02012191404009800000F1E020C0F8DD
+:102D70008011704700F01F0201219140400980003E
+:102D800000F1E020C0F880127047002806DA00F059
+:102D90000F0000F1E02090F8140D03E000F1E020B6
+:102DA00090F800044009704704D5004000D000406E
+:102DB000100502400100000110B5202000F082F84B
+:102DC000202000F08AF84A49202081F8000449496F
+:102DD00000060860091D48480860FEF79DFA45494D
+:102DE000C83108604548D0F8041341F00101C0F82B
+:102DF0000413D0F8041341F08071C0F804133C4967
+:102E000001201C39C1F8000110BD10B5202000F0D0
+:102E100059F8384800210160001D0160354A481EFC
+:102E2000E83A1060354AC2F80803324BC8331960DB
+:102E3000C2F80001C2F8600131490860BDE81040E5
+:102E4000202000F04AB82B492E48EC390860704722
+:102E500028492C48E8390860704726480160001D61
+:102E6000521E0260704723490120E8390860BFF311
+:102E70004F8F704770B51F4A8069E83A2149116049
+:102E80001E49D1F8006100231F4D1D4A5C1E1EB172
+:102E9000A84206D300210FE0D1F8606186B1A842B4
+:102EA00009D2C1F80031C1F860311460BDE870404A
+:102EB000202000F012B81168BDE8704021F040BA3F
+:102EC000FFDF70BD00F01F0201219140400980002A
+:102ED00000F1E020C0F88011704700F01F020121CE
+:102EE00091404009800000F1E020C0F88012704756
+:102EF00020E000E000060240C41400200000024070
+:102F00000004024001000001006002000F4A126844
+:102F10000D498A420CD118470C4A12680A4B9A4252
+:102F200006D101B510F06EFFFFF78DFFBDE801403F
+:102F3000074909680958084706480749054A064BE2
+:102F40007047000000000000BEBAFECAB0000020BA
+:102F500004000020E0120020E012002070B50C46B2
+:102F6000054609F0A7FA21462846BDE870400AF058
+:102F70008CBB10B511F0B0FBFFF726FC11F04CFA3A
+:102F8000BDE8104011F0FEBA0120810708607047CB
+:102F9000012081074860704712480068C00700D0D0
+:102FA000012070470F48001F0068C00700D00120B3
+:102FB00070470C4808300068C00700D001207047F7
+:102FC000084810300068704706490C310A68D2037F
+:102FD00006D5096801F00301814201D10120704743
+:102FE000002070470C0400407047704770477047DE
+:102FF000704770477047704770470004050600002F
+:103000002CFFFFFFDBE5B15100600200A800FFFFCD
+:1030100084000000808D5B0016425791AD5F58BC64
+:103020008E702F5A0FAA100DBCD52BFD30B5FC4D5C
+:103030000446062CA9780ED2DFE804F0030E0E0E2B
+:103040000509FFDF08E0022906D0FFDF04E00329BD
+:1030500002D0FFDF00E0FFDFAC7030BD30B50446CA
+:103060001038EF4D07280CD2DFE800F0040C060CF6
+:103070000C0C0C00FFDF05E0287E112802D0FFDFDA
+:1030800000E0FFDF2C7630BD2DE9F0410FF09CFB16
+:10309000044610F038FD201AC5B206200DF030FCB1
+:1030A000044606200DF034FC211ADD4C207E122847
+:1030B00018D000200F1807200DF022FC064607202C
+:1030C0000DF026FC301A3918207E13280CD0002071
+:1030D0000144A078042809D000200844281AC0B26E
+:1030E000BDE8F0810120E5E70120F1E70120F4E7E8
+:1030F000CB4810B590F825004108C94800F12600DA
+:1031000005D00BF0B6FABDE8104005F0AFBF0BF0EC
+:1031100089FAF8E730B50446A1F120000D460A28E7
+:103120004AD2DFE800F005070C1C2328353A3F445B
+:10313000FFDF42E0207820283FD1FFDF3DE0B848A4
+:103140008178052939D0007E122836D020782428AD
+:1031500033D0252831D023282FD0FFDF2DE0207851
+:1031600022282AD0232828D8FFDF26E0207822280A
+:1031700023D0FFDF21E0207822281ED024281CD075
+:1031800026281AD0272818D0292816D0FFDF14E0C7
+:103190002078252811D0FFDF0FE0207825280CD0DB
+:1031A000FFDF0AE02078252807D0FFDF05E0207840
+:1031B000282802D0FFDF00E0FFDF257030BD10B50A
+:1031C000012803D0022805D0FFDF10BDBDE8104064
+:1031D00003202BE79248007E122800D0FFDF002159
+:1031E000052011F04FF8BDE81040112036E71FB55B
+:1031F00004466A46002001F01FFEB4B1BDF802206B
+:103200004FF6FF700621824201D1ADF80210BDF8E1
+:103210000420824201D1ADF80410BDF808108142AB
+:1032200003D14FF44860ADF8080068460BF089FF01
+:1032300005F01CFF04B010BD70B514460D460646DF
+:1032400011F06CF858B90DB1A54201D90C2070BD30
+:10325000002408E056F8240011F060F808B11020AE
+:1032600070BD641CE4B2AC42F4D3002070BD2DE903
+:10327000F04105461F4690460E460024006811F0B6
+:103280009AF808B110202BE728680028A88802D0F7
+:10329000B84202D84FE00028F5D0092020E728687E
+:1032A000025DB2B1611C475C152F2DD03BDC3AD2D8
+:1032B000DFE807F03912222228282A2A3131393949
+:1032C00039393939393939392200025D32BB641C48
+:1032D000A4B2A142F9D833E0022ADED1A21C805C5C
+:1032E00088F80000072801D2400701D40A20F7E639
+:1032F000307840F0010015E0D043C00707E0012A14
+:1033000007D010E00620EBE61007A0F1805000285F
+:10331000F5D01846E4E63078820701D50B20DFE6C9
+:1033200040F0020030702868005D084484B2A8882C
+:10333000A04202D2B1E74FF4485381B2A142AED8C5
+:103340000020CDE610B5027843F202235408012292
+:10335000022C12D003DC3CB1012C16D106E0032C68
+:1033600010D07F2C11D112E0002011E080790324CD
+:10337000B4EB901F09D10A700BE08079B2EB901F7B
+:1033800003D1F8E780798009F5D0184610BDFF20F9
+:103390000870002010BD224991F82E2042B191F80A
+:1033A0002F10022909D0032909D043F202207047C7
+:1033B00001461B48253001F092BD032100E00121A8
+:1033C00001700020704738B50C460546694601F08B
+:1033D00086FD00280DD19DF80010207861F347008C
+:1033E000207055F8010FC4F80100A888A4F8050062
+:1033F000002038BD38B51378B0B1022814D0FF28AA
+:103400001BD008A46D46246800944C7905EB9414F5
+:10341000247864F34703137003280AD010E00000F7
+:10342000D80100200302FF0123F0FE0313700228DD
+:10343000F2D1D8B240F0010005E043F0FE00107078
+:10344000107820F0010010700868C2F80100888828
+:10345000A2F8050038BD02210DF0AABA38B50C4615
+:103460000978222901D2082038BDADF800008DF876
+:10347000022068460BF044F905F0F8FD050003D181
+:1034800021212046FFF746FE284638BD1CB5002006
+:103490008DF80000CDF80100ADF80500FE4890F869
+:1034A0002E00022801D0012000E000208DF8070046
+:1034B00068460BF056FB002800D0FFDF1CBD002241
+:1034C0000A80437892B263F345120A8043785B081E
+:1034D00063F386120A8000780C282BD2DFE800F014
+:1034E0002A06090E1116191C1F220C2742F0110082
+:1034F00009E042F01D0008800020704742F01100F2
+:1035000012E042F0100040F00200F4E742F0100038
+:10351000F1E742F00100EEE742F0010004E042F082
+:103520000200E8E742F0020040F00400E3E742F066
+:103530000400E0E7072070472DE9FF478AB0002527
+:10354000BDF82C6082461C4690468DF81C507007D2
+:1035500003D5606810F0E2FE68B9CF4F4FF0010963
+:1035600097F82E0058B197F82F00022807D160680D
+:1035700010F021FF18B110200EB0BDE8F087300721
+:1035800002D5A089802816D8700705D4B8F1000F9D
+:1035900002D097F8240070B1E07DC0F300108DF8E0
+:1035A0001B00617D072041B1012906D00229E3D02B
+:1035B0000429E1D12CE00720DEE749468DF8179079
+:1035C000F00609D4A27D072032B1012A04D0022AD4
+:1035D00005D0042AD0D11BE08DF8191002E002209A
+:1035E0008DF819008DF815806068B0B107A9FFF754
+:1035F000A9FE0028C0D19DF81C00FF280AD06068F1
+:1036000050F8011FCDF80F108088ADF8130008E0C6
+:103610000620B1E743F20220AEE7CDF80F50ADF837
+:103620001350E07B0028F3D1207C0028F0D1607C8F
+:103630000028EDD1A07C0028EAD1E07CC006E7D1CB
+:103640008DF800A0BDF82C00ADF80200A068019034
+:10365000A068029004F10F0001F035FC8DF80C0019
+:103660000DF10D00FFF797FE00B1FFDF9DF81C0084
+:103670008DF80E008DF816508DF81850E07D08A9D1
+:1036800000F00F008DF81A0068460BF036FF05F0C9
+:10369000EDFC71E7F0B59DB000228DF868208DF843
+:1036A00058208DF8602005468DF86C2012921392F8
+:1036B0001492159219B10FC912AC84E80F00764C20
+:1036C000A078052801D004280CD11298616888429E
+:1036D00000D120B91498E168884203D110B10820C4
+:1036E0001DB0F0BD1F26334618AA1AA912A8FFF76D
+:1036F000BEFD0028F4D133461BAA16A914A8FFF773
+:10370000B6FD0028ECD19DF85800C00701D00A2072
+:10371000E6E7A08A410708D4A17D31B19DF8601089
+:10372000890702D043F20120DAE79DF86010C9074B
+:1037300009D0400707D4208818B144F2506188426C
+:1037400001D90720CCE78DF8005003268DF80160E1
+:1037500001278DF80270BDF84C208DF8032001A8D8
+:10376000129920F025FD68460BF028FF05F07EFC3D
+:103770000028B5D18DF824508DF825608DF826707D
+:10378000BDF854208DF827200AA8149920F010FDC8
+:1037900009A80BF060FF05F069FC0028A0D112AD6C
+:1037A000241D95E80F0084E80F00002098E770B50D
+:1037B00086B00D46040005D010F0FDFD20B11020AC
+:1037C00006B070BD0820FBE72078C107A98802D0A9
+:1037D000FF2902D303E01F2901D20920F0E7800767
+:1037E00061D4FFF751FC38B12078C0F3C101012941
+:1037F00004D0032902D005E01320E1E7264991F81F
+:10380000241041B1C0074FF000054FF0010604D06D
+:103810008DF80F6003E00720D2E78DF80F5068465F
+:10382000FFF7B9FD00B1FFDF2078C0F3C1008DF8CC
+:1038300001008DF80250607808B98DF80260607858
+:10384000C00705D09DF8020040F001008DF802008D
+:103850006078800705D59DF8020040F002008DF8E1
+:1038600002006078400705D59DF8020040F0040092
+:103870008DF802002078C0F380008DF80300608886
+:10388000ADF80600A088ADF80A00207A58B9607A31
+:1038900048B9A07A38B901E0D8010020E07A10B91F
+:1038A000207BC00601D006208AE704F1080001F061
+:1038B0000AFB8DF80E0068460BF087F905F0D6FB81
+:1038C00000288BD18DF810608DF81150ADF8125092
+:1038D000ADF8145004A80BF0FDF905F0C7FB002863
+:1038E0008BD1E08864280AD248B1012001F001FBA5
+:1038F000002891D12078C00705D0152004E064216C
+:10390000B0FBF1F0F2E71320FFF7A8FB002057E728
+:103910002DE9FF470220FF4E8DF804000027708E2E
+:10392000ADF80600B84643F202094CE001A80CF0DD
+:10393000A6FF050006D0708EA8B3A6F83280ADF8B9
+:1039400006803EE0039CA07F01072DD504F12400F2
+:103950000090A28EBDF80800214604F1360301F064
+:1039600054FC050005D04D452AD0112D3CD0FFDF79
+:103970003AE0A07F20F00801E07F420862F3C7111F
+:10398000A177810861F30000E07794F8210000F04E
+:103990001F0084F820002078282826D129212046DD
+:1039A000FFF7B8FB21E014E040070AD5BDF8080096
+:1039B00004F10E0101F0ABFA05000DD04D4510D118
+:1039C00000257F1CFFB202200CF09AFF401CB84279
+:1039D000ACD8052D11D008E0A07F20F00400A0771E
+:1039E00003E0112D00D0FFDF0025BDF80600708632
+:1039F000052D04D0284604B0BFE5A6F8328000208B
+:103A0000F9E770B50646FFF726FD054605F002FD0D
+:103A1000040000D1FFDF6680207820F00F00801CBA
+:103A200020F0F000203020700620207295F83E0033
+:103A30006072BDE8704005F0F0BC2DE9F04786B03B
+:103A4000040000D1FFDF2078B24D20F00F00801C71
+:103A500020F0F0007030207060680178491F1B2949
+:103A600033D2DFE801F0FE32323255FD320EFDFD79
+:103A700042FC32323278FCFCFB323232FCFCFAF986
+:103A8000FC00C6883046FFF7E6FC0546304607F0E6
+:103A9000A7F8E0B16068007A85F83E002121284649
+:103AA000FFF738FB3046FEF7CEFA304603F016FE3D
+:103AB0003146012010F0E6FBA87F20F01000A87727
+:103AC000FFF726FF002800D0FFDF06B055E520787D
+:103AD00020F0F000203020700620207266806068A0
+:103AE000007A607205F099FCD8E7C5882846FFF790
+:103AF000B2FC00B9FFDF60680079012800D0FFDF69
+:103B00006068017A06B02846BDE8F04707F044BC7B
+:103B1000C6883046FFF79FFC050000D1FFDF05F0A7
+:103B20007CFC606831460089288160684089688132
+:103B300060688089A881012010F0A4FB0020A8758E
+:103B4000A87F00F003000228BFD1FFF7E1FE0028A4
+:103B5000BBD0FFDFB9E70079022811D000B1FFDF49
+:103B600005F05BFC6668B6F806A0307A361D0128C1
+:103B70000CD0687E814605F0E5F9070009D107E021
+:103B800006B00220BDE8F047FFF719BBE878F1E77F
+:103B9000FFDF0022022150460CF001FF040000D19B
+:103BA000FFDF22212046FFF7B5FA3079012800D047
+:103BB0000220A17F804668F30101A177308B20812C
+:103BC000708B6081B08BA08184F822908DF8088082
+:103BD000B8680090F86801906A46032150460CF0DE
+:103BE000DEFE00B9FFDFB888ADF81000B8788DF8B8
+:103BF000120004AA052150460CF0D1FE00B9FFDFE7
+:103C0000B888ADF80C00F8788DF80E0003AA0421EE
+:103C100050460CF0C4FE00B9FFDF062106F1120089
+:103C200001F093F938B37079800700D5FFDF71791F
+:103C3000E07D61F34700E075D6F80600A061708969
+:103C4000A083062106F10C0001F07FF9E8B195F898
+:103C500025004108607805E032E02AE047E03FE0D7
+:103C600021E035E061F347006070D5F82600C4F824
+:103C70000200688D12E0E07D20F0FE00801CE075FF
+:103C8000D6F81200A061F08ADAE7607820F0FE0032
+:103C9000801C6070F068C4F80200308AE080404602
+:103CA000FFF78DFA11E706B02046BDE8F04701F0B6
+:103CB00035BD05F0B2FB15F8300F40F0020005E00D
+:103CC00005F0ABFB15F8300F40F004002870FCE65F
+:103CD000287E132809D01528E4D11620FFF7BEF955
+:103CE00006B0BDE8F04705F098BB1420F6E7A978C8
+:103CF000052909D00429D5D105F08FFB022006B093
+:103D0000BDE8F047FFF792B900790028CAD0E878FB
+:103D100002E00000D801002001F0BCF805F07DFBB6
+:103D20000320ECE72DE9F05F054600784FF000082E
+:103D30000009DFF820A891460C46464601287AD0B3
+:103D400001274FF0020C4FF6FF73022874D00728AA
+:103D50000BD00A2871D0FFDFA9F8006014B1A4F8D5
+:103D6000008066800020BDE8F09F696804F10800CB
+:103D70000A78172A70D010DC4FF0000B142A31D0CB
+:103D800006DC052A6DD0092A0FD0102A7ED11FE04B
+:103D9000152A7CD0162AF9D1F0E01B3A052A75D2F3
+:103DA000DFE802F009C5FDDAFC00C8884FF0120810
+:103DB0001026214675E14FF01C080A26D4B38888E6
+:103DC000A0806868807920726868C0796072C3E7F3
+:103DD0004FF01B0814266CB303202072686880889B
+:103DE000A080B9E70A793C2AB6D00D1D4FF0100823
+:103DF0002C26FCB16988A180298B6182298B2182C4
+:103E0000698BA182A98BE1826B790246A91D1846B4
+:103E1000FFF7F0FA2879012810D084F80FC0FF20AE
+:103E20002076C4F81CB0C4F820B0C4F824B0C4F89C
+:103E300028B091E712E013E13BE135E1E7730AF1C5
+:103E4000040084F818B090E80E00DAF81000C4E915
+:103E50000930C4E907127FE7A8E002E0A9F8006092
+:103E600080E72C264FF01D08002CF7D00546A380D4
+:103E7000887B2A880F1D60F300022A80887B400817
+:103E800060F341022A80887B800801E0E6E0ADE033
+:103E900060F382022A80887BB91CC00860F3C302E9
+:103EA0002A80B87A0011401C60F3041202F07F00EF
+:103EB00028807878AA1CFFF79DFA387D05F1090261
+:103EC00007F11501FFF796FA387B01F04DF82874D9
+:103ED000787B01F049F86874F87EA874787AE87401
+:103EE00097F83B002875B87B6875A5F816B0DAF826
+:103EF0001C00A861397ABAF82000884201D2014634
+:103F000010E0B87AC0F3411002280BD0012809D084
+:103F1000288820F060002880A1840A4607F11C014F
+:103F2000A86998E0288820F060004030F3E7112667
+:103F30004FF02008002C91D0A380686804F10A0299
+:103F4000007920726868007B607269688B1D48790F
+:103F50001946FFF74FFAFFE60A264FF02108002C1A
+:103F6000E9D08888A0806868807920726868C07904
+:103F700060729AF8301021F004018BE00B264FF0AC
+:103F80002208002CD7D0C888A080686800792072E9
+:103F90006868007A00F0E8FF607201E052E039E002
+:103FA0006868407A00F0E0FFA072D5E61C264FF06A
+:103FB0002608002CBFD0A3806868407960726868CA
+:103FC000007AA0720AF1040090E80E00DAF81000FE
+:103FD000C4E90530C4E90312686800793C2803D0BD
+:103FE00043287DD0FFDFB7E62772B5E610264FF0F5
+:103FF0002408002C9FD08888A08068688079208160
+:104000006868807A608168680089A08168688089B2
+:10401000E081A1E610264FF02308002C8BD0888881
+:10402000A0806868C08820816868008960816868AD
+:104030004089A08168688089E0819AF8301021F079
+:10404000020127E030264FF02508002C88D0A380FD
+:1040500069682822496820F0ABF87DE64A4677E097
+:10406000287A012803D0022817D0FFDF74E6102633
+:104070004FF01F08002C85D06888A080A889208177
+:10408000E8896081288AA081688AE0819AF83010E6
+:1040900021F001018AF830105EE64FF01208102678
+:1040A000688800F03FFF57E62846BDE8F05F01F062
+:1040B000BFBC287A07284DD2DFE800F04C38384AD8
+:1040C0004A4A040009264FF01108002C92D06F884C
+:1040D0003846FFF7C0F990F822A0A780687A00E080
+:1040E0002DE02072042138460CF074FC052138467E
+:1040F0000CF070FC002138460CF06CFC01213846B5
+:104100000CF068FC032138460CF064FC02213846B0
+:104110000CF060FC062138460CF05CFC07213846A8
+:104120000CF058FC504600F0B5FE15E614264FF092
+:104130001B08002C8AD0A380287A012802D084F89A
+:1041400008C009E62772DAE90710C4E9031003E69C
+:104150002146A9E7FFDFFFE570B5FE4D287E122856
+:1041600001D0082070BD0AF0C3FF04F07FFF0400F7
+:1041700002D1687E00F08EFE0021052010F082F84A
+:10418000204670BD1CB5F348007E132801D20820DC
+:104190001CBD00208DF8000068460AF09BFD04F06D
+:1041A00065FF0028F4D10021052010F06BF81120E4
+:1041B000FEF754FF00201CBD70B5012805D005286E
+:1041C00025D0062800D0FFDF70BD8DB22846FFF74E
+:1041D00042F9040000D1FFDF20782128F4D005F057
+:1041E00019F968B1017821F00F01891C21F0F00163
+:1041F000103101700221017245800020A07528E075
+:1042000021462846BDE870401322FFF727B9D14860
+:10421000047EA4F1120005281FD2DFE800F0060397
+:1042200003030300FFF7AEFF01E0FFF795FF00284F
+:10423000CAD105F0EFF80028C6D0017821F00F01AF
+:10424000891C21F0F00120310170132C07D00221CC
+:104250000172BDE8704005F0E0B8FFDF70BD0121DC
+:10426000F6E72DE9F04116460C00804600D1FFDF4D
+:10427000307820F00F00801C20F0F00010303070FB
+:104280002078012804D0022818D0FFDFBDE8F08193
+:104290004046FFF7E0F8050000D1FFDF0320A875D6
+:1042A00005F0BBF894E80F00083686E80F00A9482F
+:1042B00010F8301F41F001010170E7E74046FFF7B9
+:1042C000CAF8050000D1FFDFA1884FF6FF70002774
+:1042D000814202D1E288824203D0814201D1E0884A
+:1042E00040B105F09AF894E80F00083686E80F0010
+:1042F000AF75CBE7A87D0128C8D1782300224146BD
+:104300000FF016FF0220A875C0E738B505460C4629
+:10431000084610F003F818BB203D062D4AD2DFE80E
+:1043200005F0031B373C4230002106200FF080FFD0
+:1043300008B1112038BDA01C0AF0AFFF04F096FEB2
+:10434000050038D100220823114606200FF0F0FEA8
+:10435000062830D0FFDF2EE0606810F023F808B1A7
+:10436000102038BD618820886A460BF05FFB04F09E
+:104370007DFE05001FD16068E8B1BDF80010018026
+:1043800019E0A07800F0010120880BF085FB0EE019
+:10439000206801F0FBFD05460DE0207800F00100EB
+:1043A0000AF033F903E0618820880BF0C4FA04F0C6
+:1043B0005DFEF0E70725284638BD70B505460C467A
+:1043C00008460FF0D1FF08B1102070BD202D07D096
+:1043D000212D0DD0222D0BD0252D09D0072070BD09
+:1043E0002088A11C0AF006FABDE8704004F03EBE29
+:1043F000062070BD57482530704708B53421554810
+:104400001FF077FF0120FEF711FE1120FEF726FEB8
+:1044100050496846263104F093FF4E489DF800202D
+:1044200010F8251F62F3470121F0010101700021FE
+:1044300041724FF46171A0F8071002218172FEF7FA
+:1044400057FE00B1FFDFFCF791FF01F032F908BD24
+:1044500010B50C46402120461FF029FFA07F20F018
+:104460000300A077202020700020A07584F823008E
+:1044700010BD70472DE9FC4107460FF04FFF10B10A
+:104480001020BDE8FC81334E06F12501D6F8250049
+:104490000090B6F82950ADF8045096F82B408DF8EE
+:1044A00006403846FEF78FFF0028EAD1FEF720FECF
+:1044B0000028E6D0009946F8251FB580B471E0E7E2
+:1044C00010B504460FF050FF08B1102010BD214870
+:1044D0002049224690F8250026314008FEF78AFF41
+:1044E000002010BDFEB50D4604004FF0000712D0AD
+:1044F0000822FEF7A1FE002812D1002609E000BF25
+:1045000054F826006946FEF71DFF002808D1761CE6
+:10451000F6B2AE42F4D309F07CFF10B143F20320AF
+:10452000FEBD0C4E86F8247024B300271EE000BFA9
+:1045300054F8270002A9FEF705FF00B1FFDF9DF840
+:1045400008008DF8000054F8270050F8011FCDF83E
+:10455000011001E0D80100208088ADF80500684610
+:1045600009F0A1FF00B1FFDF7F1CFFB2AF42DFD334
+:1045700086F824500020FEBD2DE9F0478AB015468C
+:10458000894604001ED00F4608222946FEF754FE35
+:10459000002810D1002613E054F826006946103098
+:1045A00000F09DFC002806D147B157F826000FF017
+:1045B000B5FE18B110200AB0BDE8F087761CF6B23F
+:1045C000AE42E9D30026A5F101081BE006F1010A7D
+:1045D0000AF0FF0712E000BF54F82600017C4A08E9
+:1045E00054F827100B7CB2EB530F05D10622113083
+:1045F00011311FF0B1FD58B17F1CFFB2AF42EBD3B8
+:104600000AF0FF064645E1DB4E4624B1012003E0F7
+:1046100043F20520CFE7002009F076FF10B909F03A
+:1046200087FF10B143F20420C5E75CB300270DF10A
+:10463000170825E054F827006946103000F04FFCB9
+:1046400000B1FFDF54F82700102250F8111FCDF8F9
+:1046500001108088ADF8050054F827100DF107000F
+:104660001FF0A6FD96B156F82710102240461FF005
+:104670009FFD684609F0F0FE00B1FFDF7F1CFFB22E
+:10468000AF42D7D3FEF702FF002094E7404601F087
+:1046900071FCEEE730B585B004460FF03FFE18B967
+:1046A00060680FF088FE10B1102005B030BD608842
+:1046B0004AF2B811884206D82078FB4D28B101286B
+:1046C00006D0022804D00720EFE7FEF711FD18E01E
+:1046D0006078022804D0032802D043F20220E4E7E5
+:1046E00085F82F00C1B200200090ADF80400022927
+:1046F0002CD0032927D0FFDF684609F0BAFF04F069
+:10470000B5FC0028D1D1606801F027FC207858B1B1
+:1047100001208DF800000DF1010001F02BFC68462E
+:104720000BF018FA00B1FFDF207885F82E00FEF7B5
+:10473000ADFE608860B1A88580B209F0DDFE00B1F1
+:10474000FFDF0020B1E78DF80500D5E74020FAE74C
+:104750004FF46170EFE710B504460FF005FE20B985
+:10476000606838B10FF01EFE08B1102010BD6068FF
+:1047700001F000FCCC4830F82C1F6180C1786170DA
+:1047800080782070002010BD2DE9F843144689463A
+:1047900006460FF0E9FDA0B948460FF00CFE80B9BF
+:1047A00020460FF008FE60B9BF4DA878012800D15F
+:1047B0003CB13178FF2906D049B143F20400BDE88D
+:1047C000F8831020FBE7012801D00420F7E74FF021
+:1047D0000008A4B3052811D004280FD0694620464C
+:1047E000FEF76DFE0028EAD1207D48B1012809D0EE
+:1047F000022809D0032809D00720E0E70820DEE7D7
+:10480000424604E0012202E0022200E003222346A5
+:10481000174600200099FEF78FFE0028CFD1A0890F
+:104820002880A07BE875BDF80000A882AF75BDF8B0
+:104830000000000701D5A08988B1A08928804946D9
+:104840000020FEF727FF0028B9D1A87805280BD053
+:10485000042809D0287DC00703D0032002E080206F
+:10486000ECE70220FEF7E2FB86F800800020A6E7D6
+:104870007CB58D4C05460E46A078022803D003284F
+:1048800001D008207CBD15B143F204007CBD072097
+:104890000CF03EF810B9A078032806D0FEF7F4FB20
+:1048A00028B1A078032804D009E012207CBD132091
+:1048B0007CBD304600F0CDFA0028F9D1E670012029
+:1048C0008DF800008DF801008DF802502088ADF8B9
+:1048D0000400E07D8DF8060068460AF0EAFF04F067
+:1048E000C5FB0028E4D1A078032805D05FF00400C0
+:1048F000FEF79CFB00207CBDE07800F0BAFA0520B2
+:10490000F6E71CB510B143F204001CBD664CA0785C
+:10491000042803D0052801D008201CBD00208DF8F4
+:10492000000001218DF801108DF8020068460AF0A0
+:10493000C0FF04F09BFB0028EFD1A078052805D02C
+:104940005FF00200FEF772FB00201CBDE07800F073
+:10495000A1FA0320F6E72DE9FC4180460E46032527
+:1049600008460FF028FD002866D14046FEF773FD8B
+:10497000040004D02078222804D2082081E543F2E4
+:1049800002007EE5A07F00F003073EB1012F0CD0AE
+:1049900000203146FEF72BFC0500EFD1012F06D099
+:1049A000022F1AD0FFDF28466BE50120F1E7A07D3A
+:1049B0003146022801D011B107E0112061E56846B7
+:1049C000FCF7E1FD0028D9D16946404606F0A7FC76
+:1049D0000500E8D10120A075E5E7A07D032804D1FA
+:1049E000314890F83000C00701D02EB30EE026B158
+:1049F000A07F40071ED4002100E00121404606F0C0
+:104A0000AEFC0500CFD1A075002ECCD0314640467B
+:104A100000F07DFA05461128C5D1A07F4107C2D418
+:104A2000316844F80E1F7168616040F00400207422
+:104A30000025B8E71125B6E7102022E570B50C4631
+:104A40000546FEF708FD010005D022462846BDE8D0
+:104A50007040FEF703BD43F2020070BD10B501289F
+:104A600007D1114B9B78012B00D011B143F2040008
+:104A700010BD09F084FDBDE8104004F0F7BA012331
+:104A800000F012BA00231A46194600F00DBA70B5AC
+:104A900006460C4608460FF041FC18B920680FF096
+:104AA00063FC18B1102070BDD8010020F74D2A7E9C
+:104AB000112A04D0132A00D33EB10820F3E721467F
+:104AC0003046FEF774FE60B1EDE70920132A0DD0E1
+:104AD000142A0BD0A188FF29E5D31520FEF7BEFAD2
+:104AE0000020D4E90012C5E90712DCE7A1881F29DC
+:104AF000D9D31320F2E72DE9F047DFF8908307467A
+:104B000090B098F818009A4615460C46132803D31F
+:104B1000FFF738FB002822D120460FF0FFFBA0BB97
+:104B200028460FF0FBFB80BB20784FF00101C00747
+:104B30004FF0000602D08DF83A1001E08DF83A608F
+:104B40002078C0F3C1008DF800006278072042B1E0
+:104B5000012A06D0022A02D0042A00D1062010B071
+:104B60002AE58DF809106088ADF80A00A088ADF834
+:104B7000100020788946C0F3C10001281FD0032807
+:104B80001DD038460FF0CAFB08B11020E7E738788F
+:104B9000400808D0012809D0022807D0032805D0F2
+:104BA00043F20220DBE78DF8026001E08DF802900D
+:104BB00057F8010FCDF80300B888ADF807000DF1E4
+:104BC0000100FEF7E8FB08B10320C8E72888ADF82C
+:104BD00016006888ADF81C00A888ADF82200E888A7
+:104BE000ADF82800ADF82E60ADF8346068460AF0E4
+:104BF000BDF8E8B998F818004546112801D00820FA
+:104C0000ADE706200BF084FE38B12078C0F3C10078
+:104C1000012804D0032802D004E012209FE795F871
+:104C2000240028B1FEF730FA022803D2132096E7B9
+:104C3000072094E7504600F00CF900288FD185F842
+:104C400019A068460AF051FA04F010FA002886D13B
+:104C5000687E00F00EF9E08864280AD248B101208D
+:104C600000F047F9040091D11220FEF7F7F9204631
+:104C700075E76421B0FBF1F0F2E770B50646154622
+:104C80000C4608460FF070FB18B928460FF06CFB75
+:104C900008B1102007E72A46214630460AF0A9FE4F
+:104CA00004F0E4F90028F5D121787F29F2D105201C
+:104CB000F9E67CB505460C4608460FF02FFB08B117
+:104CC00010207CBD2846FEF7C6FB20B100782228C4
+:104CD00004D208207CBD43F202007CBD6B4890F8F2
+:104CE0003000400701D511207CBD2178C80802D1D1
+:104CF0006078C20801D007207CBD890801D18008F6
+:104D000001D006207CBDADF8005020788DF802005F
+:104D100060788DF803000220ADF80400684609F0C1
+:104D200042FF04F0A3F97CBD70B586B014460D4671
+:104D30000646FEF790FB28B10078222805D208200D
+:104D400006B0B0E643F20200FAE728460FF033FB64
+:104D500020B944B120460FF025FB08B11020EFE741
+:104D600000202060A080494890F83000800701D5DD
+:104D70001120E5E703A9304609F0BDFD18B100BFD9
+:104D800004F074F9DCE7ADF80060BDF81400ADF88C
+:104D90000200BDF81600ADF80400BDF81000BDF823
+:104DA0001210ADF80600ADF808107DB1298809B1E0
+:104DB000ADF80610698809B1ADF80210A98809B1EB
+:104DC000ADF80810E98809B1ADF80410DCB1BDF800
+:104DD0000610814201D9081A2080BDF80210BDF8E2
+:104DE0001400814201D9081A6080BDF80800BDF89E
+:104DF0000410BDF816200144BDF812001044814291
+:104E000001D9081AA080684609F0AAFEB8E71CB5C7
+:104E10001F490968CDE90010684609F0AAFF04F0AF
+:104E200025F91CBD1CB5002000900190684609F0D2
+:104E3000A0FF04F01BF91CBD108008885080488832
+:104E40009080C88810818888D0800020508190810F
+:104E5000704710B5044604F075F830B1407830B1B1
+:104E6000204604F07EFB002010BD052010BD12205E
+:104E700010BD10B504F066F8040000D1FFDF6078C3
+:104E800000B9FFDF6078401E607010BDD8010020BF
+:104E90009C46020010B504F055F8040000D1FFDF75
+:104EA0006078401C6070F0E71CB5ADF800008DF82C
+:104EB00002308DF803108DF8042068460AF05EFD7C
+:104EC00004F0D4F81CBD0CB52DA2D2E90012CDE936
+:104ED00000120079694601EB501000780CBD027891
+:104EE000520804D0012A02D043F202207047FEF794
+:104EF00029BA10B548B183000022114605200FF0F1
+:104F000017F9052801D00320BFE70020BDE71FB532
+:104F10006A46FFF791FF68460AF04CF904F0A6F8DC
+:104F200004B0B2E770B50C0006460DD0FEF793FA58
+:104F3000050000D1FFDFA6802889208128896081B3
+:104F40006889A081A889E081ADE510B500231A46E3
+:104F500003E0845C2343521CD2B28A42F9D30BB1E2
+:104F6000002092E7012090E700B530B1012803D07E
+:104F7000022801D0FFDF002000BDFF2000BD00009F
+:104F8000070605040302010010B504460FF0C6F938
+:104F900008B1102010BD2078C0F30210042807D8F3
+:104FA0006078072804D3A178102901D8814201D262
+:104FB000072010BDE078410706D421794A0703D4C1
+:104FC000000701D4080701D5062010BD002010BD40
+:104FD00010B513785C08837F64F3C7138377137865
+:104FE0009C08C37F64F30003C3771078C309487833
+:104FF00063F34100487013781C090B7864F347137E
+:105000000B701378DB0863F3000048705078487128
+:1050100010BD10B5C4780B7864F300030B70C4782E
+:10502000640864F341030B70C478A40864F382033A
+:105030000B70C478E40864F3C3030B700379117830
+:1050400063F30001117003795B0863F34101117090
+:1050500003799B0863F3820111700079C00860F343
+:10506000C301117010BD70B514460D46064604F01C
+:10507000D1F980B10178182221F00F01891C21F0AB
+:10508000F001A03100F8081B21461FF0D6F8BDE85A
+:10509000704004F0C2B929463046BDE87040132282
+:1050A000FEF7DCB92DE9F047064608A8894690E8E6
+:1050B00030041F469046142128461FF01AF900219B
+:1050C000CAF80010B8F1000F03D0B9F1000F03D1F6
+:1050D00014E03878C00711D020680FF045F9C0BB44
+:1050E000B8F1000F07D12068123028602068143012
+:1050F00068602068A8602168CAF8001038788007C6
+:1051000024D560680FF04EF918BBB9F1000F21D01B
+:10511000FFF770F90168C6F868118188A6F86C116C
+:10512000807986F86E0101F002FDF94FEF60626848
+:1051300062B196F8680106F2691140081032FEF774
+:1051400059F91022394660681FF032F80020BDE896
+:10515000F08706E0606820B1E8606068C6F8640126
+:10516000F4E71020F3E730B5054608780C4620F048
+:105170000F00401C20F0F001103121700020607001
+:1051800095F8230030B104280FD0052811D0062847
+:1051900014D0FFDF20780121B1EB101F04D295F865
+:1051A000200000F01F00607030BD21F0F0002030C2
+:1051B00002E021F0F00030302070EBE721F0F00049
+:1051C0004030F9E7F0B591B0022715460C46064687
+:1051D0003A46ADF80870092103AB04F07AFF049059
+:1051E000002810D004208DF804008DF80170E03400
+:1051F000099605948DF818500AA968460DF0CAF86A
+:1052000000B1FFDF012011B0F0BD10B588B00C4631
+:105210000A99ADF80000C3B11868CDF802005868CB
+:10522000CDF80600ADF80A20102203A81EF0C0FF3A
+:1052300068460AF062F803F019FF002803D1A17F45
+:1052400041F01001A17708B010BD0020CDF8020098
+:10525000E6E72DE9F84F0646808A0D4680B2824681
+:10526000FEF7F9F804463078DFF8A48200274FF003
+:105270000509A8F120080F2870D2DFE800F06FF2CE
+:105280003708387D8CC8F1F0EFF35FF3F300A07FAF
+:1052900000F00300022809D05FF0000080F0010157
+:1052A00050460BF085FB050003D101E00120F5E736
+:1052B000FFDF98F85C10C90702D0D8F860000BE057
+:1052C000032105F11D000EF004FDD5F81D009149E4
+:1052D000B0FBF1F201FB1200C5F81D0070686867B1
+:1052E000B068A8672078252800D0FFDFCAE0A07F3B
+:1052F00000F00300022809D05FF0000080F00101F7
+:1053000050460BF055FB060003D101E00120F5E704
+:10531000FFDF3078810702D52178252904D040F0BD
+:1053200001003070BDE8F88F02202870307F2871AE
+:1053300006F11D002D36C5E90206F3E7A07F00F057
+:105340000300022808D0002080F0010150460BF035
+:105350002FFB040004D102E00120F5E7A7E1FFDF05
+:105360002078C10604D5072028703D346C60D9E749
+:1053700040F008002070D5E7E07F000700D5FFDF90
+:10538000307CB28800F0010301B05046BDE8F04F18
+:10539000092105F027BD04B9FFDF716821B1102292
+:1053A00004F124001EF004FF28212046FDF7B2FE80
+:1053B000A07F00F0030002280ED104F12400002396
+:1053C00000901A4621465046FFF71FFF112807D0CC
+:1053D00029212046FDF79EFE307A84F82000A1E7BF
+:1053E000A07F000700D5FFDF14F81E0F40F0080073
+:1053F0002070E782A761E761C109607861F341002D
+:10540000014660F382016170307AE0708AE7A07F24
+:1054100000F00300022809D05FF0000080F00101D5
+:1054200050460BF0C5FA040003D101E00120F5E776
+:10543000FFDF022104F185000EF04BFC04202870F0
+:1054400004F5B4706860B4F88500288230481038DC
+:105450007C346C61C5E9028064E703E024E15BE031
+:105460002DE015E0A07F00F00300022807D0002007
+:1054700080F0010150460BF09BFA18B901E00120C1
+:10548000F6E7FFDF324621465046BDE8F84FEAE531
+:1054900004B9FFDF20782128A1D93079012803D170
+:1054A000E07F40F00800E077324621465046FFF7A3
+:1054B000DAFD2046BDE8F84F2321FDF72BBE3279F7
+:1054C000AA8005F108030921504604F002FEE860B5
+:1054D00010B185F8009025E7A07F00F003000228B6
+:1054E00008D0002080F0010150460BF061FA040062
+:1054F00003D101E00120F5E7FFDF04F1620102239F
+:105500001022081F0BF0DBF807703179417009E7B2
+:105510003802002040420F00A07F00F00300022864
+:1055200008D0002080F0010150460BF041FA050040
+:1055300003D101E00120F5E7FFDF95F8840000F0DA
+:10554000030001287AD1A07F00F00307E07F10F06C
+:10555000010602D0022F04D133E095F8A000C00765
+:105560002BD0D5F8601121B395F88320087C62F325
+:1055700087000874A17FCA09D5F8601162F3410061
+:105580000874D5F8601166F300000874AEB1D5F860
+:105590006001102204F1240188351EF009FE287EE6
+:1055A00040F001002876287820F0010005F88809ED
+:1055B00000E016B1022F04D02DE095F88800C00756
+:1055C00027D0D5F85C1121B395F88320087C62F3CD
+:1055D00087000874A17FCA09D5F85C1162F3410005
+:1055E0000874D5F85C1166F3000008748EB1D5F824
+:1055F0005C01102204F1240188351EF0D9FD2878C1
+:1056000040F0010005F8180B287820F0010005F89B
+:10561000A009022F44D0002000EB400005EBC000A1
+:1056200090F88800800709D595F87C00D5F86421AA
+:10563000400805F17D011032FDF7DCFE8DF8009089
+:1056400095F884006A4600F003008DF8010095F893
+:1056500088108DF8021095F8A0008DF803002146FF
+:10566000504601F04DFA2078252805D0212807D092
+:10567000FFDF2078222803D922212046FDF74AFDAA
+:10568000A07F00F0030002280CD0002080F0010170
+:1056900050460BF09FF900283FF44FAEFFDF41E684
+:1056A0000120B9E70120F1E7706847703AE6FFDFB3
+:1056B00038E670B5FE4C002584F85C5025660CF089
+:1056C00036FE04F11001204603F060FE84F83050ED
+:1056D00070BD70B50D46FDF7BEFE040000D1FFDFC2
+:1056E0004FF4B87128461EF004FE04F1240028612E
+:1056F000A07F00F00300022808D0012105F1E0009E
+:105700000CF016FE002800D0FFDF70BD0221F5E787
+:105710000A46014602F1E0000CF02ABE70B50546CB
+:10572000406886B001780A2906D00D2933D00E29A9
+:105730002FD0FFDF06B070BD86883046FDF78BFEA8
+:10574000040000D1FFDF20782128F3D028281BD1C6
+:10575000686802210E3001F0C8F9A8B16868082114
+:10576000801D01F0C2F978B104F1240130460AF03D
+:10577000A2F803F07BFC00B1FFDF06B02046BDE8D5
+:1057800070402921FDF7C6BC06B0BDE8704003F0AB
+:1057900044BE012101726868C6883046FDF75BFE91
+:1057A000040000D1FFDFA07F00F00301022902D135
+:1057B00020F01000A077207821280AD06868017AAC
+:1057C00009B1007980B1A07F00F00300022862D007
+:1057D000FFDFA07F00F003000228ABD1FEF798F8AE
+:1057E0000028A7D0FFDFA5E703F017FEA17F08067A
+:1057F0002BD5E07FC00705D094F8200000F01F00F3
+:10580000102820D05FF0050084F823002078292894
+:105810001DD02428DDD1314604200EF033FD222195
+:105820002046FDF777FCA07F00F00300022830D06F
+:105830005FF0000080F0010130460BF0CBF800284B
+:10584000C7D0FFDFC5E70620DEE70420DCE701F074
+:105850000300022808D0002080F0010130460BF040
+:10586000A7F8050003D101E00120F5E7FFDF2521BE
+:105870002046FDF74FFC03208DF80000694605F136
+:10588000E0000CF06CFD0228A3D00028A1D0FFDFBF
+:105890009FE70120CEE703F0C0FD9AE72DE9F04332
+:1058A00087B09946164688460746FDF7D4FD0400A2
+:1058B0004BD02078222848D3232846D0E07F000709
+:1058C00043D4A07F00F00300022809D05FF000005D
+:1058D00080F0010138460BF06BF8050002D00CE0B7
+:1058E0000120F5E7A07F00F00300022805D0012188
+:1058F000002238460BF053F805466946284601F069
+:1059000026F9009800B9FFDF45B10098E035056140
+:105910002078222806D0242804D007E0009900200F
+:10592000086103E025212046FDF7F4FB00980121E2
+:1059300041704762868001A9C0E902890CF02AFD06
+:10594000022802D0002800D0FFDF07B0BDE8F083B6
+:1059500070B586B00546FDF77EFD017822291ED977
+:10596000807F00F00300022808D0002080F00101B1
+:1059700028460BF01DF804002FD101E00120F5E7C7
+:10598000FFDF2AE0B4F85E0004F1620630440178DB
+:10599000427829B121462846FFF714FCB0B9C9E680
+:1059A000ADF804200921284602AB04F092FB0390D5
+:1059B0000028F4D005208DF80000694604F1E000CD
+:1059C0000CF0CDFC022801D000B1FFDF0223102231
+:1059D000314604F15E000AF0A8FEB4F86000002829
+:1059E000D0D1A7E610B586B00446FDF734FD0178A6
+:1059F00022291BD9807F00F00300022808D0002054
+:105A000080F0010120460AF0D3FF040003D101E039
+:105A10000120F5E7FFDF06208DF80000694604F15C
+:105A2000E0000CF09CFC002800D0FFDF06B010BDA9
+:105A30002DE9F05F05460C460027007890460109E5
+:105A40003E4604F1080BBA4602297DD0072902D050
+:105A50000A2909D146E0686801780A2905D00D298C
+:105A600030D00E292ED0FFDFBCE114271C26002CDD
+:105A70006BD08088A080FDF7EEFC5FEA000900D1C2
+:105A8000FFDF99F817005A46400809F11801FDF7A1
+:105A9000B1FC6868C0892082696851F8060FC4F8B3
+:105AA00012004868C4F81600A07E20F0060001E04D
+:105AB0001802002040F00100A07699F81E0040F086
+:105AC00020014DE01A270A26002CD1D0C088A080E2
+:105AD000FDF7C1FC050000D1FFDF59462846FFF75E
+:105AE00042FB7FE10CB1A88BA080287A0B287DD0E7
+:105AF00006DC01287BD0022808D0032804D135E039
+:105B00000D2875D00E2874D0FFDF6BE11E27092603
+:105B1000002CADD0A088FDF79EFC5FEA000900D103
+:105B2000FFDF287B00F003000128207A1BD020F043
+:105B300001002072297B890861F341002072297BD2
+:105B4000C90861F3820001E041E1F2E02072297BA3
+:105B5000090961F3C300207299F81E0040F040016A
+:105B600089F81E103EE140F00100E2E713270D2600
+:105B7000002CAAD0A088FDF76EFC8146807F00F043
+:105B80000300022808D0002080F00101A0880AF05C
+:105B90000FFF050003D101E00120F5E7FFDF99F8D1
+:105BA0001E0000F00302022A50D0686F817801F0D5
+:105BB00003010129217A4BD021F001012172837860
+:105BC0009B0863F3410121728378DB0863F3820150
+:105BD000217283781B0963F3C3012172037863F395
+:105BE00006112172437863F3C71103E061E0A9E075
+:105BF00090E0A1E0217284F809A0C178A172022A84
+:105C000029D00279E17A62F30001E1720279520847
+:105C100062F34101E1720279920862F38201E1725A
+:105C20000279D20862F3C301E1724279217B62F307
+:105C3000000121734279520862F3410121734279D4
+:105C4000920862F382012173407928E0A86FADE7E2
+:105C500041F00101B2E74279E17A62F30001E172B9
+:105C60004279520862F34101E1724279920862F38B
+:105C70008201E1724279D20862F3C301E1720279D2
+:105C8000217B62F3000121730279520862F3410122
+:105C900021730279920862F3820121730079C008AE
+:105CA00060F3C301217399F80000232831D926211C
+:105CB00040E018271026E4B3A088FDF7CCFB83460C
+:105CC000807F00F00300022809D0002080F001014D
+:105CD000A0880AF06DFE5FEA000903D101E001200F
+:105CE000F4E7FFDFE868A06099F8000040F00401E5
+:105CF00089F8001099F80100800708D50120207369
+:105D00009BF8000023286DD92721584651E084F8DC
+:105D10000CA067E015270F265CB1A088FDF79BFB60
+:105D2000814606225946E86808F059F90120A07317
+:105D3000A2E041E048463CE016270926E4B3287B70
+:105D400020724FE0287B19270E26ACB3C4F808A0B8
+:105D5000A4F80CA0012807D0022805D0032805D0FC
+:105D6000042803D0FFDF0DE0207207E0697B0428E0
+:105D700001F00F0141F0800121721ED0607A20F005
+:105D800003006072A088FDF766FB054600782128B5
+:105D900028D0232800D0FFDFA87F00F003000228CE
+:105DA00013D0002080F00101A0880AF013FE222108
+:105DB0002846FDF7AFF915E004E0607A20F0030013
+:105DC000401CDEE7A8F8006011E00120EAE70CB112
+:105DD0006888A080287A03282ED004280AD00528B5
+:105DE00050D0FFDFA8F800600CB12780668000204B
+:105DF000BDE8F09F15270F26002CE3D0A088FDF703
+:105E00002AFB807F00F00300022809D05FF0000029
+:105E100080F00101A0880AF0CBFD050003D101E06C
+:105E20000120F5E7FFDFD5F81D000622594608F0EE
+:105E3000D6F884F80EA0D5E717270926002CC1D084
+:105E4000A088FDF708FB8146807F00F00300022850
+:105E500008D0002080F00101A0880AF0A9FD05000B
+:105E600003D101E00120F5E7FFDF6878800701D565
+:105E7000022000E00120207299F800002328B1D907
+:105E8000272157E719270E26002C9BD0A088FDF765
+:105E9000E2FA5FEA000900D1FFDFC4F808A0A4F825
+:105EA0000CA084F808A0A07A40F00300A07299F832
+:105EB0001E10C90961F38200A07299F81F2099F899
+:105EC0001E1012EAD11F05D099F8201001F01F0111
+:105ED00010292BD020F00800A07299F81F10607ACA
+:105EE00061F3C3006072697A01F003010129A2D154
+:105EF00040F00400607299F81E0000F003000228D0
+:105F0000E87A16D0217B60F300012173AA7A607BC6
+:105F100062F300006073EA7A520862F34101217370
+:105F2000A97A490861F3410060735BE740F008001B
+:105F3000D2E7617B60F300016173AA7A207B62F390
+:105F400000002073EA7A520862F341016173A97A72
+:105F5000490861F34100207344E710B5FE4C30B1AD
+:105F60000146102204F120001EF022F9012084F8DD
+:105F7000300010BD10B5044600F0D9FDF6492046AA
+:105F80001022BDE8104020311EF012B970B5F24D5C
+:105F900006004FF0000413D00EF0C0F908B1102431
+:105FA0000CE00621304608F001F8411C05D02866B7
+:105FB0005FF0010085F85C0000E00724204670BD1A
+:105FC0000020F7E7007810F00F0204D0012A05D076
+:105FD000022A0CD110E0000909D10AE000090128C9
+:105FE00007D0022805D0032803D0042801D00720B9
+:105FF00070470870002070470620704705282AD295
+:10600000DFE800F003070F171F00087820F0FF00FB
+:106010001EE0087820F00F00401C20F0F000103047
+:1060200016E0087820F00F00401C20F0F00020302F
+:106030000EE0087820F00F00401C20F0F000303017
+:1060400006E0087820F00F00401C20F0F0004030FF
+:10605000087000207047072070472DE9F041804606
+:1060600088B00D46002708460EF0A5F9A8B94046AD
+:10607000FDF7F1F9040003D02078222815D104E0BF
+:1060800043F2020008B0BDE8F08145B9A07F4106A7
+:1060900003D500F00300022801D01020F2E7A07F12
+:1060A000C10601D4010702D50DB10820EAE7E17F5E
+:1060B000090701D50D20E5E700F00300022805D10E
+:1060C00025B12846FEF760FF0700DBD1A07F00F076
+:1060D0000300022808D0002080F0010140460AF0A9
+:1060E00067FC060002D00FE00120F5E7A07F00F07A
+:1060F000030002280ED0002080F00101002240465B
+:106100000AF04DFC060007D0A07F00F00300022833
+:1061100004D009E00120EFE70420B3E725B12A46C7
+:1061200031462046FEF754FF6946304600F00FFD29
+:10613000009800B9FFDF0099022006F1E0024870E4
+:10614000C1F824804A6100220A81A27F02F0030282
+:10615000022A1CD001200871287800F00102087E74
+:1061600062F3010008762A78520862F3820008760A
+:106170002A78920862F3C30008762A78D20862F37C
+:106180000410087624212046FCF7C4FF33E035B321
+:106190000871301D88613078400908777078C0F345
+:1061A00040004877287800F00102887F62F3010000
+:1061B0008877A27FD20962F382008877E27F62F358
+:1061C000C3008877727862F304108877A878C8775C
+:1061D00001F1210228462031FEF71BFF03E00320D6
+:1061E00008710520087625212046FCF793FFA07F43
+:1061F00020F04000A07701A900980CF0CBF802280D
+:1062000001D000B1FFDF38463CE72DE9FF4F534A8C
+:106210000D4699B09A4607CA0BAB002783E80700E2
+:106220001998FDF718F9060006D03078262806D010
+:1062300008201DB0BDE8F08F43F20200F9E7B07FFF
+:1062400000F00309B9F1020F03D00020284302D067
+:1062500006E00120FAE71B98FEF796FE0028E8D139
+:10626000B07F00F00300022801D11B9979BB0228FE
+:1062700008D0002080F0010119980AF099FB040071
+:1062800003D101E00120F5E7FFDF852D28D007DCF1
+:10629000F5B1812D1ED0822D1ED0832D08D11DE099
+:1062A000862D1FD0882D1FD0892D1FD08A2D1FD05D
+:1062B0000F2020710F281DD003F0ACF8E0B10120B1
+:1062C0008DF84000201D11902079B8B167E111E0F0
+:1062D0000020EEE70120ECE70220EAE70320E8E7F0
+:1062E0000520E6E70620E4E70820E2E70920E0E7EA
+:1062F0000A20DEE707209CE711209AE7B9F1020F98
+:1063000003D0A56F03D1A06F02E0656FFAE7606F5D
+:10631000804632D04FF0010000904FF00200019013
+:10632000214630461B9AFEF753FE1B98007800F07A
+:106330000101A87861F30100A870B17FC90961F378
+:106340008200A870F17F61F3C300A870617861F3E7
+:106350000410A870207803E018020020A446020070
+:10636000400928706078C0F3400068701B988078FE
+:10637000E87000206871287103E00220009001207D
+:106380000190A87898F80210C0F3C000C1F3C001D2
+:1063900008405FEA000B2CD050460DF0BFFF90BBC9
+:1063A000DAF80C000DF0BAFF68BBDAF81C000DF04B
+:1063B000B5FF40BBDAF80C00A060DAF81C00E06022
+:1063C00098F80100617800F0010041EA4000607037
+:1063D00098F80210C0B2C1F30011891E0840607025
+:1063E00000202077019906F1170002290CD0012125
+:1063F0000BE098F80110607801F00101FD2242EAFB
+:1064000041010840E3E732E0002104EB81014861EB
+:106410000099701C022901D0012100E0002104EB49
+:1064200081014861A87800F00300012858D198F84C
+:10643000020000F00300012852D1B9F1020F04D08C
+:106440002A1D691D1B98FEF7E4FD297998F80400C0
+:1064500001408DF83810687998F8052010408DF8C3
+:106460003C0001433CD050460DF058FF08B11020CD
+:10647000DFE60AF110010491B9F1020F18D00846C5
+:106480005FF0000104F18C03CDE9000304F5AE7266
+:1064900002920EAB5A462046FEF704FE0028E7D1D2
+:1064A000B9F1020F08D0504608D14FF0010107E0C2
+:1064B00050464FF00101E5E70498F5E74FF0000181
+:1064C00004F1A403CDE9000304F5B072029281F057
+:1064D00001010FAB5A462046FEF7E4FD0028C7D164
+:1064E0006078800734D4A87898F80210C0F3800050
+:1064F000C1F3800108432BD0297898F800000BAA3B
+:10650000B9F1020F06D032F811204300DA4002F050
+:1065100003070AE032F810204B00DA4012F00307BC
+:1065200005D0012F0BD0022F0BD0032F07D0BBF1CA
+:10653000000F0DD0012906D0042904D008E002275D
+:10654000F5E70127F3E7012801D0042800D104274B
+:10655000B07F40F08000B077F17F6BF30001F177FE
+:10656000607881074FF003000CD5A071BBF1000FDC
+:1065700015D100BF8DF85C0017AA3146199800F0BC
+:10658000BFFA0CE00221022F18D0012F18D0042FDF
+:1065900022D00020A071B07F20F08000B0772521AC
+:1065A0003046FCF7B7FD10A904F1E0000BF0D7FE70
+:1065B00010B1022800D0FFDF00203AE6A171D9E730
+:1065C000A1710D2104F120001DF093FE207840F010
+:1065D000020020700420CDE70120A071DFE72DE943
+:1065E000F04387B09046894604460025FCF733FF08
+:1065F000060006D03078272806D0082007B0BDE86E
+:10660000F08343F20200F9E7B07F00F003000228B4
+:1066100008D0002080F0010120460AF0C9F90400EA
+:1066200003D101E00120F5E7FFDFA7795FEA090068
+:1066300005D0012821D0B9F1020F26D110E0B8F120
+:10664000000F22D1012F05D0022F05D0032F05D036
+:10665000FFDF2DE00C252BE0012529E0022527E0B6
+:1066600040460DF05BFEB0B9032F0ED1102241461B
+:1066700004F11D001DF09CFD1AE0012F02D0022F35
+:1066800003D104E0B8F1000F12D00720B6E740466E
+:106690000DF044FE08B11020B0E7102104F11D00F8
+:1066A0001DF005FE0621404607F080FCC4F81D00E1
+:1066B0002078252140F0020020703046FCF72AFDAA
+:1066C0002078C10713D020F00100207002208DF83F
+:1066D000000004F11D0002908DF804506946C3309B
+:1066E0000BF03DFE022803D010B1FFDF00E025775C
+:1066F000002083E730B587B00D460446FCF7ABFEBB
+:10670000A0B1807F00F00300022812D05FF00000EB
+:1067100080F0010120460AF04BF904000ED0284613
+:106720000DF0FCFD38B1102007B030BD43F202007F
+:10673000FAE70120ECE72078400701D40820F3E7CE
+:10674000294604F13D00202205461DF031FD207848
+:1067500040F01000207001070FD520F008002070D5
+:1067600007208DF80000694604F1E00001950BF068
+:10677000F6FD022801D000B1FFDF0020D4E770B59C
+:106780000D460646FCF767FE18B10178272921D18E
+:1067900002E043F2020070BD807F00F00300022897
+:1067A00008D0002080F0010130460AF001F9040011
+:1067B00003D101E00120F5E7FFDFA079022809D12C
+:1067C0006078C00706D02A4621463046FEF7FAFC1C
+:1067D00010B10FE0082070BDB4F860000E280BD295
+:1067E00004F1620102231022081F09F068FF012151
+:1067F00001704570002070BD112070BD70B5064657
+:1068000014460D4608460DF089FD18B920460DF0D6
+:10681000ABFD08B1102070BDA6F57F40FF380ED04B
+:106820003046FCF718FE38B1417822464B08811CEF
+:106830001846FCF7DFFD07E043F2020070BD20467A
+:10684000FDF73EFE0028F9D11021E01D0DF041FAC0
+:10685000E21D294604F1170000F089F9002070BDFF
+:106860002DE9F04104468AB01546884600270846BF
+:106870000DF0A1FD18B928460DF09DFD18B11020AE
+:106880000AB0BDE8F0812046FCF7E5FD060003D024
+:10689000307827281BD102E043F20200F0E7B07FF6
+:1068A00000F00300022809D05FF0000080F0010131
+:1068B00020460AF07DF8040003D101E00120F5E74D
+:1068C000FFDF2078400702D56078800701D40820D8
+:1068D000D6E7B07F00F00300022803D0A06F03D1F9
+:1068E000A16F02E0606FFAE7616F407800B19DB17F
+:1068F000487810B1B8F1000F0ED0ADB1EA1D06A86E
+:10690000E16800F034F9102206A905F117001DF026
+:1069100023FC18B1042707E00720B1E71022E91D86
+:1069200004F12D001DF044FCB8F1000F06D0102238
+:1069300008F1070104F11D001DF03AFC2078252123
+:1069400040F0020020703046FCF7E4FB2078C107DD
+:1069500015D020F00100207002208DF8000004F115
+:106960001D000290103003908DF804706946B3301A
+:106970000BF0F5FC022803D010B1FFDF00E0277711
+:1069800000207DE7F8B515460E460746FCF763FD87
+:10699000040004D02078222804D00820F8BD43F257
+:1069A0000200F8BDA07F00F00300022802D043F2ED
+:1069B0000500F8BD30460DF0B1FC18B928460DF0C1
+:1069C000ADFC08B11020F8BD00953288B31C2146FB
+:1069D0003846FEF71AFC112815D00028F3D1297C7F
+:1069E0004A08A17F62F3C711A177297CE27F61F396
+:1069F0000002E277297C890884F82010A17F21F029
+:106A00004001A177F8BDA17F0907FBD4D6F80200A9
+:106A1000C4F83600D6F80600C4F83A003088A086DC
+:106A20001022294604F124001DF0C2FB287C4108F5
+:106A3000E07F61F34100E077297C61F38200E07739
+:106A4000287C800884F82100A07F40F00800A0770F
+:106A50000020D3E770B50D4606460BB1072070BD88
+:106A6000FCF7F9FC040007D02078222802D3A07F8D
+:106A7000800604D4082070BD43F2020070BDADB1A1
+:106A80002946304608F017FF02F0F0FA297C4A0840
+:106A9000A17F62F3C711A177297CE27F61F3000235
+:106AA000E277297C890884F8201004E0304608F059
+:106AB0002AFF02F0DBFAA17F21F02001A17770BD4F
+:106AC00070B50D46FCF7C7FC040005D028460DF054
+:106AD0004BFC20B1102070BD43F2020070BD29466E
+:106AE0002046FEF740FB002070BD04E010F8012BAB
+:106AF0000AB100207047491E89B2F7D201207047C1
+:106B000070B51546064602F085FC040000D1FFDF93
+:106B1000207820F00F00801C20F0F0002030207042
+:106B200066802868A060BDE8704002F076BC10B5B1
+:106B3000134C94F83000002808D104F12001A1F191
+:106B400010000BF04EFC012084F8300010BD10B195
+:106B500090F8B9202AB10A4890F8350018B1002001
+:106B600003E0B83001E0064834300860704708B5EB
+:106B70000023009313460A460AF015F908BD0000E9
+:106B80001802002018B18178012938D101E01020C5
+:106B90007047018842F60112881A914231D018DC00
+:106BA00042F60102A1EB020091422AD00CDC41B373
+:106BB000B1F5C05F25D06FF4C050081821D0A0F502
+:106BC0007060FF381BD11CE001281AD002280AD1BE
+:106BD00017E0B0F5807F14D008DC012811D002281E
+:106BE0000FD003280DD0FF2809D10AE0B0F5817F2E
+:106BF00007D0A0F58070033803D0012801D0002011
+:106C000070470F2070470A281ED007DC18D2DFE833
+:106C100000F0191B1F1F171F231D1F21102815D03F
+:106C200008DC0B2812D00C2810D00D2816D00F2805
+:106C300006D10DE011280BD084280BD087280FD067
+:106C400003207047002070470520704707207047D9
+:106C50000F20704704207047062070470C207047B3
+:106C600043F20200704738B50C46050041D0694632
+:106C7000FFF7A8F9002819D19DF80010607861F39A
+:106C8000020060706946681CFFF79CF900280DD16E
+:106C90009DF80010607861F3C5006070A978C1F3B9
+:106CA0004101012903D0022905D0072038BD2178F0
+:106CB00021F0200102E0217841F0200121704107FC
+:106CC00004D0A978C90861F386106070607810F06C
+:106CD000380F07D0A978090961F3C710607010F068
+:106CE000380F02D16078400603D5207840F040008C
+:106CF0002070002038BD70B504460020088015467D
+:106D00006068FFF7B0FF002816D12089A18988426A
+:106D100011D860688078C0070AD0B1F5007F0AD822
+:106D200040F20120B1FBF0F200FB1210288007E0D6
+:106D3000B1F5FF7F01D90C2070BD01F2012129803E
+:106D4000002070BD10B50478137864F3000313704D
+:106D50000478640864F3410313700478A40864F3AE
+:106D6000820313700478E40864F3C3031370047897
+:106D7000240964F3041313700478640964F345135D
+:106D800013700078800960F38613137031B10878AE
+:106D9000C10701D1800701D5012000E0002060F388
+:106DA000C713137010BD4278530702D002F00703D7
+:106DB00006E012F0380F02D0C2F3C20300E0012354
+:106DC0004A7863F302024A70407810F0380F02D01C
+:106DD000C0F3C20005E0430702D000F0070000E066
+:106DE000012060F3C5024A7070472DE9F04F95B05D
+:106DF0000D00824612D0122128461DF058FA4FF697
+:106E0000FF7B05AA0121584606F01BFF00242646F9
+:106E100037464FF420586FF4205972E0102015B017
+:106E2000BDE8F08F9DF81E0001280AD1BDF81C10A6
+:106E300041450BD011EB09000AD001280CD00228E3
+:106E40000CD0042C0ED0052C0FD10DE0012400E055
+:106E50000224BDF81A6008E0032406E00424BDF80B
+:106E60001A7002E0052400E00624BDF81A1051450E
+:106E700047D12C74BEB34FF0000810AA4FF0070A98
+:106E8000CDE90282CDE900A80DF13C091023CDF82F
+:106E9000109042463146584606F086FF08BBBDF8C2
+:106EA0003C002A46C0B210A90BF004FBC8B9AE8161
+:106EB000CFB1CDE900A80DF1080C0AAE40468CE830
+:106EC0004102132300223946584606F06DFF40B9AF
+:106ED000BDF83C00F11CC01EC0B22A1D0BF0EAFA3E
+:106EE00010B103209BE70AE0BDF82900E881062CD9
+:106EF00005D19DF81E00A872BDF81C002881002055
+:106F00008DE705A806F0A9FE00288BD0FFF77BFED1
+:106F100085E72DE9F0471C46DDE90978DDF820908A
+:106F200015460E00824600D1FFDF0CB1208818B153
+:106F3000D5B11120BDE8F087022D01D0012100E07C
+:106F4000002106F1140005F06BFDA8F800000246D0
+:106F50003B462946504603F0BCF8C9F8000008B982
+:106F6000A41C3C600020E5E71320E3E7F0B41446DE
+:106F7000DDE904528DB1002314B1022C09D101E0E6
+:106F8000012306E00D7CEE0703D025F00105012367
+:106F90000D742146F0BC03F025BF1A80F0BC704789
+:106FA0002DE9FE4F91461A881C468A468046FAB162
+:106FB00002AB494603F08DF8050019D04046A61CE7
+:106FC000278809F039FE3246072629463B460096B7
+:106FD00009F047FA20882346CDE900504A46514639
+:106FE0004046FFF7C3FF002020800120BDE8FE8F50
+:106FF0000020FBE72DE9F04786B09146DDE90E461B
+:107000000F46824603AA05A904A8109D8DE8070033
+:107010009846324621465046FFF77BFF049909B156
+:10702000012200E000222A70002818D1F94A03AB9F
+:107030001060059A009104F11400CDE901204A4640
+:107040003946504606F0A3F8A8B1092811D2DFE866
+:1070500000F005080510100A0C0C0E00002006B008
+:1070600068E71120FBE70720F9E70820F7E70D2084
+:10707000F5E70320F3E7BDF80C100498CDE9000113
+:107080004346324621465046FFF770FFE6E72DE9BA
+:10709000F04389B00D46DDE9108781461C4616464F
+:1070A000142103A81DF025F9012002218DF81010EC
+:1070B0008DF80C008DF81170ADF8146064B1A278F1
+:1070C000D20709D08DF81600E088ADF81A00A08824
+:1070D000ADF81800A068079008A80095CDE9011048
+:1070E000424603A948466B68FFF784FF09B0BDE834
+:1070F000F083F0B58BB0002406460694079407276A
+:10710000089405A80994019400970294CDE90340DE
+:107110000D4610232246304606F046FE78B90AA8EE
+:1071200006A9019400970294CDE90310BDF814302C
+:1071300000222946304606F00DFC002801D0FFF75A
+:1071400062FD0BB0F0BD06F0ADBA2DE9FC410C4676
+:107150008046002602F05EF9054620780D287DD293
+:10716000DFE800F0BC0713B325BD49496383AF9541
+:107170009B00A848006820B1417841F0100141709F
+:10718000ADE0404602F076F9A9E00421404609F05E
+:107190000FFC070000D1FFDF07F11401404605F0A6
+:1071A000D3FBA5BB13214046FDF748FC97E0042123
+:1071B000404609F0FDFB070000D1FFDFE088ADF895
+:1071C00000000020B8819DF80000010704D5C0062A
+:1071D00002D5A088B88105E09DF8010040067ED563
+:1071E000A088F88105B9FFDF22462946404601F014
+:1071F00063FC022673E0E188ADF800109DF80110F1
+:1072000009060FD5072803D006280AD00AE024E093
+:107210000421404609F0CCFB060000D1FFDFA08826
+:10722000F0810226CDB9FFDF17E00421404609F0C6
+:10723000BFFB070000D1FFDF07F1140006F069FA79
+:1072400090F0010F02D1E079000648D5387C022683
+:1072500040F00200387405B9FFDF00E03EE022464E
+:107260002946404601F028FC39E00421404609F057
+:107270009FFB017C002D01F00206C1F3400161710A
+:10728000017C21F002010174E7D1FFDFE5E702266E
+:107290000121404602F020F921E00421404609F096
+:1072A00087FB0546606800902089ADF80400012244
+:1072B0006946404602F031F9287C20F0020028742B
+:1072C0000DE0002DC9D1FFDFC7E7022600214046AF
+:1072D000FBF788F8002DC0D1FFDFBEE7FFDF3046A7
+:1072E000BDE8FC813EB50C0009D001466B4601AA01
+:1072F000002006F0DBFD20B1FFF785FC3EBD10202D
+:107300003EBD00202080A0709DF8050002A900F07D
+:107310000700FEF773FE50B99DF8080020709DF835
+:10732000050002A9C0F3C200FEF768FE08B1032001
+:107330003EBD9DF8080060709DF80500C109A07869
+:1073400061F30410A0709DF80510890961F3C30072
+:10735000A0709DF80410890601D5022100E00121EA
+:1073600061F342009DF8001061F30000A07000205E
+:107370003EBD70B5144606460D4651EA040005D0E0
+:1073800075B108460DF00EF878B901E0072070BD20
+:107390002946304606F0EBFD10B1BDE8704032E4FE
+:1073A00054B120460CF0FEFF08B1102070BD2146FC
+:1073B0003046BDE8704095E7002070BD2DE9FC5FC8
+:1073C0000C4690460546002701780822007A3E4682
+:1073D000B2EB111F7ED104F10A0100910A31821E25
+:1073E0004FF0020A04F1080B0191092A73D2DFE879
+:1073F00002F0ECDF05F427277AA9CD006888042184
+:1074000009F0D6FA060000D1FFDFB08920B152277B
+:107410000726C2E07C02002051271026002C7DD0D8
+:107420006888A0800120A071A88900220099FFF738
+:10743000A0FF002873D1A8892081288AE081D1E0AB
+:10744000B5F81290072824D1E87B000621D55127F2
+:1074500009F1140086B2002CE1D0A889002200991D
+:10746000FFF787FF00285AD16888A08084F806A01B
+:10747000A88920810120A073288A2082A4F8129074
+:10748000A88A009068884B46A969019A01F0F1FA30
+:10749000A8E0502709F1120086B2002C3ED0A8893E
+:1074A00000225946FFF765FF002838D16888A08080
+:1074B000A889E080287A072813D002202073288A20
+:1074C000E081E87BC0096073A4F81090A88A00905E
+:1074D000688801E083E080E04B4604F11202A9696C
+:1074E000D4E70120EAE7B5F81290512709F114001A
+:1074F00086B2002C66D06888042109F059FA8346C8
+:107500006888A080A88900220099FFF732FF002830
+:107510006ED184F806A0A889208101E052E067E0DE
+:107520000420A073288A2082A4F81290A88A0090D0
+:1075300068884B46A969019A01F09BFAA989ABF8C2
+:107540000E104FE06888FBF786FF07466888042125
+:1075500009F02EFA064607B9FFDF06B9FFDF687BA0
+:10756000C00702D05127142601E0502712264CB341
+:107570006888A080502F06D084F806A0287B594642
+:1075800001F087FA2EE0287BA11DF9E7FE49A889C2
+:107590004989814205D1542706269CB16888A0807C
+:1075A00020E053270BE06888A080A889E08019E0DC
+:1075B0006888042109F0FCF900B9FFDF5527082687
+:1075C000002CF0D1A8F8006011E056270726002C07
+:1075D000F8D06888A080002013E0FFDF02E00128D7
+:1075E00008D0FFDFA8F800600CB12780668000207B
+:1075F000BDE8FC9F57270726002CE3D06888A080B1
+:10760000687AA071EEE7401D20F0030009B1414304
+:10761000091D01EB4000704713B5DB4A00201071D3
+:10762000009848B10024684608F0DFFF002C02D122
+:10763000D64A009911601CBD01240020F4E770B502
+:107640000D46064686B014465C2128461CF051FEC5
+:1076500004B9FFDFA0786874A2782188284601F079
+:1076600042FA0020A881E881228805F11401304601
+:1076700005F04FF96A460121304606F0E2FA19E0BA
+:107680009DF80300000715D5BDF806103046FFF73A
+:1076900030FD9DF80300BDF8061040F010008DF895
+:1076A0000300BDF80300ADF81400FF233046059A2F
+:1076B00006F028FC684606F0D0FA0028E0D006B0B4
+:1076C00070BD10B50C4601F1140005F059F90146E2
+:1076D000627C2046BDE8104001F03ABA70B505461C
+:1076E000042109F065F9040000D1FFDF04F1140161
+:1076F0000C46284605F028F921462846BDE870408A
+:1077000005F029B970B58AB00C460646FBF7A3FE12
+:10771000050014D02878222827D30CB1A08890B176
+:1077200001208DF80C0003208DF8100000208DF84A
+:10773000110054B1A088ADF81800206807E043F2AA
+:1077400002000AB070BD0920FBE7ADF818000590F3
+:107750000421304609F02CF9040000D1FFDF04F1C8
+:10776000140005F024F9000701D40820E9E701F02E
+:1077700051FE60B108A802210094CDE9011095F8EE
+:10778000232003A930466368FFF734FCD9E71120B2
+:10779000D7E72DE9F04FB2F802A0834689B015462D
+:1077A00089465046FBF757FE07460421504609F02C
+:1077B000FFF80026044605964FF002080696ADF83D
+:1077C0001C6007B9FFDF04B9FFDF4146504603F0F4
+:1077D00070FE50B907AA06A905A88DE80700424621
+:1077E000214650466368FFF794FB674807AB066085
+:1077F000DDE9051204F11400CDF80090CDE9032075
+:10780000CDE9013197F82320594650466B6805F0C1
+:1078100017F906000AD0022E04D0032E14D0042E2D
+:1078200000D0FFDF09B03046BDE8F08FBDF81C0086
+:107830000028F7D00599CDE9001042462146504670
+:107840006368FFF793FBEDE7687840F00800687025
+:10785000E8E72DE9F04F9BB004464FF000084A4896
+:10786000ADF85480ADF83080ADF85080A0F80880B5
+:10787000ADF81480ADF81880ADF82080ADF81C800C
+:10788000007916460D464746012808D0022806D042
+:10789000032804D0042802D008201BB0C4E72046E7
+:1078A0000CF03CFDD0BB28460CF038FDB0BB606846
+:1078B0000CF081FD90BB606848B1608921898842E5
+:1078C00002D8B1F5007F01D90C20E6E780460BAA6B
+:1078D00006A92846FFF70FFA0028DED168688078ED
+:1078E000C0F34100022808D19DF8190010F0380FAC
+:1078F00003D028690CF056FD80B905A92069FFF76F
+:10790000B2F90028C9D1206950B1607880079DF88C
+:10791000150000F0380002D5D0B301E011E0B8BB8B
+:107920009DF8140080060ED59DF8150010F0380F54
+:1079300003D060680CF036FD18B960680CF03BFDB0
+:1079400008B11020A9E707A96069FFF78CF90028A2
+:10795000A3D1606940B19DF81D0000F00701012925
+:107960003FD110F0380F3CD008A9A069FFF77BF990
+:10797000002892D19DF81C00800632D49DF820008A
+:1079800080062ED4A06904E07C02002014000020B0
+:1079900027E040B19DF8210000F00701012920D126
+:1079A00010F0380F1DD0E06818B10078C8B11C285D
+:1079B00017D20EAA611C2046FFF7C4F90120B94670
+:1079C00060F30F27BA4607468DF84E0042F60300D3
+:1079D000ADF84C000DF13B0217A928680AF089FDAB
+:1079E00008B1072059E79DF85C0016A9CDF8009072
+:1079F000C01CCDE9019100F0FF0B00230BF2012226
+:107A0000514613A806F060F8F0BBBDF85800099085
+:107A1000FE482A8929690092CDE901106B89BDF8D9
+:107A20002C202868069906F04FF801007ED12078B6
+:107A30004FF0020AC10601D480062BD5ADF80C9098
+:107A4000606950B907A906A8FFF7ADF99DF81D00B8
+:107A500020F00700401C8DF81D009DF81C008DF8DB
+:107A60004E7040F0C8008DF81C0042F60210ADF8D0
+:107A70004C000CA903AACDF800A0CDE901210023F8
+:107A800040F2032213A800E01EE0079906F01CF85C
+:107A900001004BD1DD484D4608385B460089ADF802
+:107AA00039000EA8CDE90290CDF80490CDF81090E1
+:107AB0004FF007090022CDF80090BDF858104FF69E
+:107AC000FF7005F047FF10B1FFF79DF8E5E69DF860
+:107AD0003800000625D52946012060F30F218DF8D6
+:107AE0004E704FF42450ADF84C00ADF81050627851
+:107AF0009DF81000002362F300008DF810006278FA
+:107B0000CDF800A0520862F341008DF8100004AADD
+:107B1000CDE9012540F2032213A805F0D5FF0100AD
+:107B200004D1606888B32069A8B900E086E005A99F
+:107B300006A8FFF738F96078800706D49DF815008D
+:107B400020F038008DF8150005E09DF8140040F095
+:107B500040008DF814008DF84E7042F60110ADF81B
+:107B60004C00208940F20121B0FBF1F201FB12022E
+:107B7000606814ABCDF80080CDE90103002313A8A1
+:107B8000059905F0A1FF010058D12078C00729D040
+:107B9000ADF80C50A06950B908A906A8FFF703F981
+:107BA0009DF8210020F00700401C8DF821009DF871
+:107BB00020008DF84E7040F040008DF8200042F615
+:107BC0000310ADF84C0015A903AACDF800A0CDE92B
+:107BD0000121002340F2032213A8089905F074FF45
+:107BE00001002BD1E06868B32946012060F30F2122
+:107BF0008DF84E7042F60410ADF84C00E06800239A
+:107C000002788DF8602040788DF86100E06818AA4D
+:107C10004088ADF86200E06800798DF86400E068A3
+:107C2000C088ADF86500CDF80090CDE901254FF48E
+:107C3000027213A805F048FF010003D0099800F074
+:107C4000B3FF2AE6714803210838017156B1008953
+:107C50003080BDF850007080BDF83000B080BDF8B5
+:107C60005400F080002018E670B501258AB0164651
+:107C70000B46012802D0022816D104E08DF80E50E0
+:107C80004FF4205003E08DF80E5042F60100ADF89D
+:107C90000C005BB10024601C60F30F2404AA08A947
+:107CA00018460AF026FC18B107204AE5102048E5DE
+:107CB00004A99DF820205548CDE90021801E02909E
+:107CC0000023214603A802F2012205F0FDFE10B1B7
+:107CD000FEF799FF35E54D4808380EB1C18831806F
+:107CE000057100202DE5F0B593B0074601268DF80B
+:107CF0003E6041F60100ADF83C0012AA0FA93046E3
+:107D0000FFF7B2FF002848D1404C0025083CE7B3FC
+:107D10001C2102A81CF0EDFA9DF808008DF83E60C9
+:107D200040F020008DF8080042F60520ADF83C0038
+:107D30000E959DF83A00119520F00600801C8DF8F4
+:107D40003A009DF838006A4620F0FF008DF83800B0
+:107D50009DF8390009A920F0FF008DF839000420B2
+:107D6000ADF82C00ADF830000EA80A9011A80D90C7
+:107D70000FA80990ADF82E5002A8FFF76AFD002861
+:107D80000BD1BDF80000608100E008E0BDF8040000
+:107D9000A081401CE0812571002013B0F0BD6581F9
+:107DA000A581BDF84800F4E72DE9F74F1749A0B0C9
+:107DB0000024083917940A79A146012A04D0022A1E
+:107DC00002D0082023B02FE5CA88824201D00620C5
+:107DD000F8E721988A46824201D10720F2E7012084
+:107DE0002146ADF848004FF6FF7860F30F21ADF85B
+:107DF0004A808DF86E0042F6020B06918DF87240B3
+:107E0000ADF86CB0ADF870401CA901E08402002010
+:107E10001391ADF8508012A805F043FF00252E46BF
+:107E20002F460DAB072212A9404605F03DFF78B161
+:107E30000A285DD195B38EB3ADF86450ADF8666095
+:107E40009DF85E008DF8144019AC012864D06BE0F9
+:107E50009DF83A001FB3012859D1BDF83810594593
+:107E60001FD118A809A901940294CDE90310072095
+:107E70000090BDF8361010230022404605F094FF14
+:107E8000B0BBBDF86000042801D006284AD1BDF877
+:107E90002410219881423AD10F2093E73AE001283B
+:107EA00035D1BDF83800B0F5205F03D042F60101AE
+:107EB00088422CD1BAF80600BDF83610884201D1AC
+:107EC000012700E0002705B19EB1219881421ED113
+:107ED00018A809AA01940294CDE903200720009074
+:107EE0000D4610230022404605F05EFF00B902E077
+:107EF0002DE04E460BE0BDF86000022801D01028AE
+:107F000010D1C0B217AA09A90AF0D4FA50B9BDF825
+:107F1000369086E7052055E705A917A8221D0AF027
+:107F2000E8FA08B103204DE79DF814000023001D76
+:107F3000C2B28DF8142022980092CDE901401BA80E
+:107F4000069905F0C1FD10B902228AF80420FEF757
+:107F50005AFE37E710B50B46401E88B084B205AA1A
+:107F600000211846FEF7EEFE00200DF1080C06AACF
+:107F700005A901908CE8070007200090012300224A
+:107F800021464FF6FF7005F0E5FC0446BDF81800E9
+:107F9000012800D0FFDF2046FEF735FE08B010BDF7
+:107FA000F0B5FF4F044687B038790E46032804D059
+:107FB000042802D0082007B0F0BD04AA03A9204677
+:107FC000FEF799FE0500F6D160688078C0F34100A5
+:107FD00002280AD19DF80D0010F0380F05D0206955
+:107FE0000CF0E0F908B11020E5E7208905AA216925
+:107FF0008DE807006389BDF810202068039905F01B
+:1080000063FD10B1FEF7FFFDD5E716B1BDF8140012
+:108010003080042038712846CDE7F8B50C000646BC
+:108020000BD001464FF6FF7500236A46284605F03F
+:108030003DFF20B1FEF7E7FDF8BD1020F8BD694611
+:108040002046FEF710FE0028F8D1A078314600F057
+:1080500001032846009A05F055FFEBE730B587B0DD
+:10806000144600220DF1080C05AD01928CE82C009D
+:10807000072200920A46014623884FF6FF7005F05A
+:1080800069FCBDF814102180FEF7BDFD07B030BDBE
+:1080900070B50D46042108F08BFC040000D1FFDF11
+:1080A000294604F11400BDE8704004F079BC70B5B5
+:1080B0000D46042108F07CFC040000D1FFDF2946B6
+:1080C00004F11400BDE8704004F08DBC70B50D469D
+:1080D000042108F06DFC040000D1FFDF294604F103
+:1080E0001400BDE8704004F0A5BC70B5054604213D
+:1080F00008F05EFC040000D1FFDF2146284623681B
+:10810000BDE870400122FEF74BBF70B50646042162
+:1081100008F04EFC040000D1FFDF04F1140004F06D
+:108120002FFC401D20F0030511E0011D00880022F6
+:10813000431821463046FEF733FF00280BD0607C01
+:10814000ABB2684382B2A068011D08F0EEFAA068E5
+:1081500041880029E9D170BD70B50546042108F0B9
+:1081600027FC040000D1FFDF214628466368BDE8F4
+:1081700070400222FEF714BF70B50E46054601F0AE
+:1081800049F9040000D1FFDF01202072667265808A
+:10819000207820F00F00001D20F0F000403020700B
+:1081A000BDE8704001F039B910B50446012900D08E
+:1081B000FFDF2046BDE810400121FAF713B92DE991
+:1081C000F04F97B04FF0000A0C008346ADF814A0B2
+:1081D000D04619D0E06830B1A068A8B10188ADF8E8
+:1081E0001410A0F800A05846FBF735F9070043F239
+:1081F000020961D0387822285CD30421584608F05F
+:10820000D7FB050005D103E0102017B0BDE8F08FC3
+:10821000FFDF05F1140004F0B3FB401D20F003065E
+:10822000A078012803D0022801D00720EDE721889B
+:1082300007AA584605F005FD30BB07A805F00DFD5F
+:1082400010BB07A805F009FD48B99DF826000128D4
+:1082500005D1BDF82400A0F52451023902D04FF415
+:108260005050D2E7E068B0B1CDE902A007200090FD
+:1082700005AACDF804A00492A2882188BDF8143084
+:10828000584605F067FB10B1FEF7BDFCBDE7A168DD
+:10829000BDF8140008809DF81F00C00602D543F207
+:1082A0000140B2E70B9838B1A1780078012905D0D8
+:1082B00080071AD40820A8E74846A6E7C007F9D0E7
+:1082C00002208DF83C00A8684FF00009A0B1697C3D
+:1082D0004288714391420FD98AB2B3B2011D08F0AE
+:1082E000DAF98046A0F800A006E003208DF83C00F3
+:1082F000D5F800804FF001099DF8200010F0380FEC
+:1083000000D1FFDF9DF820002649C0F3C2000844D9
+:1083100097F8231010F8010C884201D90F2074E758
+:108320002088ADF8400014A90095CDE9019143469D
+:1083300007220FA95846FEF75DFE002891D19DF84F
+:10834000500050B9A078012807D1687CB3B27043BF
+:1083500082B2A868011D08F0B2F9002055E770B597
+:10836000064615460C460846FEF70CFC002805D1CB
+:108370002A4621463046BDE8704075E470BD13E5DD
+:1083800070B51E4614460D000ED06CB1616859B12F
+:1083900060B10349C988814208D0072070BD000040
+:1083A0007C020020FA2F00001020F7E72068FEF77B
+:1083B000E9FB0028F2D1324621462846BDE870404C
+:1083C000FFF747BA70B515460C0006D038B1FE4924
+:1083D0000989814203D00720E0E71020DEE720680A
+:1083E000FEF7D0FB0028D9D129462046BDE87040D1
+:1083F000D6E570B5064686B00D46144610460BF01D
+:10840000B3FFD0BB60680BF0D6FFB0BBA6F57F40D2
+:10841000FF3803D03046FBF71EF880B12846694686
+:10842000FEF7E3FC00280CD19DF810100F2008295E
+:108430003CD2DFE801F008060606060A0A0843F205
+:10844000020006B0AAE70320FBE79DF8021001290D
+:1084500008D1BDF80010B1F5C05FF2D06FF4C05282
+:10846000D142EED09DF8061001290DD1BDF80410BF
+:10847000A1F52851062907D200E028E0DFE801F045
+:10848000030304030303DCE79DF80A1001290ED15E
+:10849000BDF80810B1F5245FD3D0A1F524510239FD
+:1084A000CFD00129CDD0022901D1CAE7FFDF606812
+:1084B00078B9002305AA2946304605F0F7FC10B12B
+:1084C000FEF7A1FBBDE79DF81400800601D4102043
+:1084D000B7E76188224628466368FFF7BFFDB0E72B
+:1084E0002DE9F043814687B08846144610460BF0CC
+:1084F0003BFF18B1102007B0BDE8F083002306AAA7
+:108500004146484605F0D2FC18B100BFFEF77BFBA0
+:10851000F1E79DF81800C00602D543F20140EAE7F2
+:108520000025072705A8019500970295CDE903507E
+:1085300062884FF6FF734146484605F035FC060059
+:1085400013D160680BF010FF60B960680195CDE948
+:10855000025000970495238862884146484605F0FA
+:1085600023FC0646BDF8140020803046CEE739B122
+:10857000954B0A889B899A4202D843F203007047C0
+:108580001DE610B586B0904C0423ADF81430638915
+:1085900043B1A4898C4201D2914205D943F2030030
+:1085A00006B010BD0620FBE7ADF8101000210091C9
+:1085B0000191ADF8003002218DF8021005A9029159
+:1085C00004A90391ADF812206946FFF7F8FDE7E72B
+:1085D0002DE9FC4781460E4608460BF09FFE88BBFE
+:1085E0004846FAF738FF5FEA00080AD098F800001A
+:1085F000222829D30421484608F0DAF9070005D1DA
+:1086000003E043F20200BDE8FC87FFDF07F114003E
+:1086100004F0CDF905463078012803D0022804D0B3
+:108620000720F0E7A8070FD502E015F01C0F0BD0CC
+:10863000B079341DC00709D0E08838B1A0680BF0CC
+:108640006DFE18B11020DEE70820DCE732782088C4
+:10865000002628B3A0F201130721112B18D20CD247
+:10866000DFE803F00B090D0B1D0B121D100B0B1D8A
+:108670001D1D1D0B1D00022A11D10846C3E7012A4A
+:10868000FBD00CE02A0700E0EA06002AF5DA06E053
+:10869000A0F5C0721F2A02D97D3A022AEDD8C6B2CF
+:1086A00000F0B8FE50B198F82300CDE90006FA8931
+:1086B000234639464846FEF7EAFCA4E71120A2E724
+:1086C0002DE9F04F8BB01F4615460C468346002619
+:1086D000FAF7C1FE28B10078222805D208200BB095
+:1086E00094E543F20200FAE7B80801D00720F6E764
+:1086F000032F00D100274FF6FF79CCB1022D73D3A1
+:1087000020460BF058FE30B904EB0508A8F1010033
+:108710000BF051FE08B11020E1E7AD1EAAB22146D0
+:10872000484605F06DFC38F8021C88425CD1ADB2B9
+:108730002549B80702D58889401C00E001201FFAAE
+:1087400080F8F80701D08F8900E04F4605AA41461E
+:10875000584605F076FA4FF0070A4FF00009ACB31F
+:10876000204608E0408810283ED8361D304486B2A6
+:10877000AE4239D2A01902884245F3D354E000BF7B
+:108780009DF8170002074FD584B304EB0608361D89
+:10879000B8F80230B6B2102B26D89A19AA4223D8BC
+:1087A000B8F8002091421FD1C00620D5CDE900A91C
+:1087B0000DF1080C0AAAA11948468CE80700B8F880
+:1087C00000100022584603E07C0200202CE00BE061
+:1087D00005F0C0F810B1FEF716FA80E7B8F802000D
+:1087E000BDF82810884202D00B2078E704E0B8F8E2
+:1087F0000200304486B206E0C00604D55846FEF7B3
+:1088000078FC002888D19DF81700BDF81A1020F0D8
+:1088100010008DF81700BDF81700ADF80000FF2319
+:108820005846009A05F06EFB05A805F016FA18B92F
+:10883000BDF81A10B942A3D90421584608F0B8F877
+:10884000040000D1FFDFA2895AB1CDE900A94D464D
+:10885000002321465846FEF71AFC0028BDD1A58109
+:108860003DE700203BE72DE9FF4F8BB01E46170088
+:108870000D464FF0000412D0B00802D007200FB010
+:10888000C4E4032E00D100265DB108460BF08AFD3A
+:1088900028B93888691E08440BF084FD08B11020FF
+:1088A000EDE7C74AB00701D5D18900E00121F00703
+:1088B0004FF6FF7802D0D089401E00E0404686B2D5
+:1088C00006AA0B9805F0BDF94FF000094FF0070B11
+:1088D0000DF1140A39E000BF9DF81B00000734D5E4
+:1088E000CDF80490CDF800B0CDF80890CDE9039A0A
+:1088F000434600220B9805F057FA60BB05B3BDF85C
+:1089000014103A8821442819091D8A4230D3BDF831
+:108910001E2020F8022BBDF8142020F8022BCDE9F0
+:1089200000B9CDE90290CDF810A0BDF81E10BDF839
+:10893000143000220B9805F037FA08B103209EE7A7
+:10894000BDF814002044001D84B206A805F085F986
+:1089500020B10A2806D0FEF756F990E7BDF81E10A0
+:10896000B142B9D934B17DB13888A11C884203D253
+:108970000C2084E7052082E722462946404605F080
+:108980003FFB014628190180A41C3C80002076E7AB
+:1089900010B504460BF0E8FC08B1102010BD884863
+:1089A000C0892080002010BDF0B58BB00D46064672
+:1089B000142103A81BF09DFC01208DF80C008DF8FC
+:1089C000100000208DF81100ADF814503046FAF771
+:1089D00042FD48B10078222812D30421304607F026
+:1089E000E7FF040005D103E043F202000BB0F0BD45
+:1089F000FFDF04F11400074603F0D9FF800601D41D
+:108A00000820F3E7207C022140F00100207409A82F
+:108A10000094CDE90110072203A930466368FEF7F0
+:108A2000E9FA20B1217C21F001012174DEE7294619
+:108A30003046F9F7C8FC08A9384603F0A7FF00B193
+:108A4000FFDFBDF82040172C01D2172000E02046A0
+:108A5000A84201D92C4602E0172C00D21724214647
+:108A60003046FFF724FB21463046F9F7D2F90020C3
+:108A7000BCE7F8B51C4615460E46069F08F0CAF836
+:108A80002346FF1DBCB231462A46009407F0B5FCD0
+:108A9000F8BD70B50C4605460E2120461BF007FCBC
+:108AA000002020802DB1012D01D0FFDF76E40620CB
+:108AB00000E00520A07171E410B5488008781346E5
+:108AC00020F00F00001D20F0F00080300C460870F0
+:108AD0001422194604F108001BF0AFFB00F09DFCC6
+:108AE0003748046010BD2DE9F047DFF8D890491DE4
+:108AF000064621F0030117460C46D9F8000007F09E
+:108B000092FD050000D1FFDF4FF000083560A5F8A9
+:108B100000802146D9F8000007F085FD050000D14E
+:108B2000FFDF7560A5F800807FB104FB07F1091D28
+:108B30000BD0D9F8000007F076FD040000D1FFDF6C
+:108B4000B460C4F80080BDE8F087C6F80880FAE792
+:108B50002DE9F0411746491D21F00302194D064643
+:108B600001681446286807F089FD22467168286864
+:108B700007F084FD3FB104FB07F2121D03D0B1687A
+:108B8000286807F07BFD042007F0BAFE04460420A5
+:108B900007F0BEFE201A012804D12868BDE8F04184
+:108BA00007F036BDBDE8F08110B50C4605F015F8AC
+:108BB00000B1FFDF2046BDE81040FEF724B80000FA
+:108BC0007C0200201400002038B50C468288817B8E
+:108BD00019B14189914200D90A462280C188121DEB
+:108BE00090B26A4606F092FFBDF80000032800D359
+:108BF0000320C1B2208800F0A3FF38BD38B50C4671
+:108C00008288817B19B10189914200D90A4622806C
+:108C1000C188121D90B26A4606F078FFBDF80000C8
+:108C2000022800D30220C1B2208800F089FF401C36
+:108C3000C0B238BD2DE9FE4F0C46FD4981464022A9
+:108C4000D1E90201CDE9010109F1030020F003019E
+:108C5000C91C21F0030100916846114607F0C5FCCC
+:108C6000F44E002C02D1F44A00999160009901441D
+:108C70000091357F05F1010504D1E8B209F0C0FB90
+:108C800000B1FFDF009800EB0510C01C20F00301CD
+:108C900000915CB9707AB27A1044C2B200200870B8
+:108CA000308C80B204F021FE00B1FFDF0098316A01
+:108CB000084400902146684600F00DFF0098C01C53
+:108CC00020F003000090B37AF27A717A04B10020A8
+:108CD00007F081FD0099084400902146684600F0A5
+:108CE0003AFF00273D46B24696F801800CE0284640
+:108CF00000F0D4FE064681788088F9F721F9717872
+:108D00006D1C00FB0177EDB24545F0D10098C01C09
+:108D100020F00300009004B100203946F9F71BF958
+:108D200000990027084400903D469AF801800CE025
+:108D3000284600F0B3FE0646C1788088FEF763FC43
+:108D400071786D1C00FB0177EDB24545F0D10098BC
+:108D5000C01C20F00300009004B100203946FEF74B
+:108D60005BFC00994FF000080844009045469AF8D3
+:108D700001700EE0284600F091FE0646807B30B17F
+:108D800006F1080001F0DDFE727800FB02886D1C20
+:108D9000EDB2BD42EED10098C01C20F0030000905F
+:108DA00004B10020414601F0D0FE00990844009033
+:108DB0002146684600F049FE0098C01D20F00702D9
+:108DC00000922CBB9D490020FAF747F8FBF715FBF2
+:108DD000984801AA00211030F8F7CEFA00B1FFDF61
+:108DE0009AF81D00FEF77FFF00B1FFDF91484FF4B6
+:108DF000F67144301BF07DFA8E480421443080F82F
+:108E0000E91180F8EA11062180F8EB1103210171C4
+:108E10000099A1EB0900BDE8FE8F70B5854C0646B0
+:108E20004434207804EB4015E078083590B9A01957
+:108E300090F8E80100280ED0A0780F2800D3FFDFBB
+:108E4000202128461BF055FA687866F30200687006
+:108E50000120E070284670BD2DE9F04105460C4622
+:108E600000270078052190463E46B1EB101F00D048
+:108E7000FFDF287A50B101280ED0FFDFA8F800608C
+:108E80000CB1278066800020BDE8F081012709260B
+:108E900074B16888A08008E00227142644B168886D
+:108EA000A0802869E060A88A2082287B2072E5E7FC
+:108EB000A8F80060E7E710B55F4C6068C11D21F0BD
+:108EC0000701814200D0FFDF5A48012100220170D2
+:108ED00042700172417203238372C1720273027481
+:108EE000052202831F224283417455A242610A2255
+:108EF000027741774FF4B06101626168416010BD53
+:108F000030B54D4C1568636810339D4202D2042081
+:108F1000136030BD474B5D785A6802EB0512107044
+:108F200051700320D080172090800120D070907065
+:108F3000002090735878401C587060681030606052
+:108F4000002030BD70B506463A480024457807E059
+:108F5000204600F0A3FD0178B14204D0641CE4B2C5
+:108F6000AC42F5D1002070BDF7B5074608780C4635
+:108F700010B3FFF7E7FF0546A7F12006202F06D024
+:108F8000052E19D2DFE806F00F2B2B151A0000F082
+:108F900090FD0DB1697800E00021401AA17880B2FF
+:108FA0000844FF2808D8A07830B1A088022824D22D
+:108FB00002E06088172820D20720FEBD207AE0B1A9
+:108FC00061881729F8D3A1881729F5D3A179002939
+:108FD000F2D0E1790029EFD0402804D9ECE7242F22
+:108FE0000BD1207A48B161884FF6FB70814202D8DC
+:108FF000A188814201D90420FEBD65B9207802AA6A
+:109000000121FFF77DFF0028F6D12078FFF79AFFB6
+:10901000050000D1FFDF052E25D2DFE806F003189A
+:109020001B151E00A0786870A088E8801CE0000076
+:10903000B0460200980300201C0000200000002021
+:109040006E524635780000006088A8800CE0A07859
+:10905000A87009E0A078E87006E054F8020FA86054
+:109060006068E86000E0FFDF0020FEBD1A2835D010
+:109070000DDC132832D2DFE800F01B31203131271C
+:109080002723252D313129313131312F0F0030285F
+:1090900002D003DC1E2821D1072070473A38092866
+:1090A0001CD2DFE800F0151B0F1B1B1B1B1B07004E
+:1090B0000020704743F20400704743F202007047FB
+:1090C000042070470D2070470F207047082070471C
+:1090D0001120704713207047062070470320704707
+:1090E00010B5007800F0010006F001FDBDE8104069
+:1090F000BCE70EB5017801F001018DF80010417850
+:1091000001F001018DF801100178C1F340018DF8E3
+:1091100002104178C1F340018DF8031001788908ED
+:109120008DF80410417889088DF8051081788DF844
+:109130000610C1788DF8071000798DF80800684690
+:1091400005F0ACFAFFF792FF0EBD2DE9F84FDFF8FE
+:10915000F883FE4C00261FE0012000F03FFD0120B7
+:10916000FFF75BFE054640214746D8F8080007F0A8
+:109170005AFA686000B9FFDF686805F03EF8A8B1E8
+:109180002846FAF75AFC284600F02EFD20B9402266
+:109190006968B86807F072FA94F9E9010428DBDA23
+:1091A000022007F0ADFB07460025A6E040226968D3
+:1091B000D8F8080007F062FAF2E7B8F80210404663
+:1091C000491C89B2A8F80210B94201D3002141809C
+:1091D0000221B8F8020007F0EBFB002865D0B8F8D0
+:1091E0000200694606F0F1FBFFF740FF00B1FFDF28
+:1091F0009DF8000078B1B8F8020007F01DFD5FEAA5
+:10920000000900D1FFDF484606F08BFF18B1B8F81F
+:10921000020002F03DF9B8F8020007F0FBFC5FEA3B
+:10922000000900D1FFDF484606F073FFE8BB0321C9
+:10923000B8F8020007F0BCFB5FEA000B48D1FFDF83
+:1092400046E000BFDBF8100010B10078FF2849D0DD
+:10925000022000F0C3FC0220FFF7DFFD82464846F3
+:1092600007F063F8CAF8040000B9FFDFDAF8040079
+:1092700007F02BF9002100900170B8F80210504659
+:10928000AAF8021001F00AFE484607F020F900B9DA
+:10929000FFDF504600F0A8FC18B99AF8010000075B
+:1092A00004D50099CBF8101012E024E0DBF8100090
+:1092B00038B10178491C11F0FF01017008D1FFDFBE
+:1092C00006E000221146484600F0BDFB00B9FFDF72
+:1092D00094F9EA01022805DBB8F8020001F0A3FDC9
+:1092E0000028AFD194F9E901042804DB484607F0CF
+:1092F00052F900B101266D1CEDB2BD4204D294F9C1
+:10930000EA010228BFF659AF002E7FF423AFBDE873
+:10931000F84F032000F062BC10B58B4CE060086889
+:109320002061AFF2D91002F012FD607010BD8748C5
+:1093300000214438017084480170854941607047BC
+:1093400070B505464FF080500C46D0F8A410491C6B
+:1093500005D1D0F8A810C9430904090C0BD050F866
+:10936000A01F01F001012970416821608068A08080
+:10937000287830B970BD062120460AF0AAFC0120E9
+:109380002870607940F0C000607170BD70B54FF01A
+:1093900080540D46D4F88010491C0BD1D4F88410A9
+:1093A000491C07D1D4F88810491C03D1D4F88C107B
+:1093B000491C0CD0D4F880100160D4F884104160AE
+:1093C000D4F888108160D4F88C10C16002E01021BC
+:1093D0000AF07FFCD4F89000401C0BD1D4F8940024
+:1093E000401C07D1D4F89800401C03D1D4F89C004D
+:1093F000401C09D054F8900F286060686860A0682D
+:10940000A860E068E86070BD2846BDE870401021A3
+:109410000AF05FBC4D480079FFE470B54B4CE07832
+:1094200030B3207804EB4010407A00F0070020446D
+:1094300090F9E801002800DCFFDF2078002504EB2C
+:109440004010407A00F00700011991F8E801401E31
+:1094500081F8E8012078401CC0B220700F2800D1AC
+:109460002570A078401CA0700AF096FBE57070BDD6
+:10947000FFDF70BD3EB50546032107F099FA0446AB
+:10948000284607F0C7FB054604B9FFDF206918B17D
+:109490000078FF2800D1FFDF01AA6946284600F0C6
+:1094A000D2FA60B9FFDF0AE0002202A9284600F0E4
+:1094B000CAFA00B9FFDF9DF8080000B1FFDF9DF890
+:1094C0000000411E8DF80010EED2206901998842FB
+:1094D00001D1002020613EBD70B50546A0F57F405A
+:1094E0000C46FF3800D1FFDF012C01D0FFDF70BD3B
+:1094F000FFF790FF040000D1FFDF207820F00F007D
+:10950000401D20F0F0005030207065800020207257
+:1095100001202073BDE870407FE72DE9F041164639
+:109520000D460746FFF776FF040000D1FFDF2078E5
+:1095300020F00F00401D20F0F000503020706780B8
+:1095400001202072286805E01C000020DC030020B8
+:10955000C81400202061A888A0822673BDE8F041CD
+:109560005BE77FB5FFF7EEFC040000D1FFDF02A947
+:109570002046FFF729FB054603A92046FFF73EFBDF
+:109580008DF800508DF80100BDF80800001DADF801
+:109590000200BDF80C00001DADF80400E088ADF835
+:1095A0000600684606F08CFA002800D0FFDF7FBD79
+:1095B0002DE9F047DFF8FC930546002799F80000F5
+:1095C00010B10820BDE8F08728460AF0CDFE08B1AA
+:1095D0001020F7E7F84C207808B9FFF76CFCA07A68
+:1095E000617A0844C6B200F064FAB04207D2301A79
+:1095F000C1B22A460020FFF783FC0700E2D1D9F868
+:1096000004004E46C01C20F00300C9F8040000F01E
+:1096100040FB716800EB010801214046FFF70AFB9F
+:10962000064629684044884202D8B6F5803F15D3E3
+:1096300028600020FFF786FC05000DD005F113001F
+:10964000D9F8041020F003004E46884200D0FFDF16
+:109650006078401E607075600420B3E700214046CA
+:10966000FFF7E8FA0446A64200D0FFDF04EB08014A
+:10967000C9F8041029604FF6FF71A9F80210012102
+:1096800089F8001038469DE72DE9F0410446C948A5
+:1096900017460E46007810B10820BDE8F081084654
+:1096A0000AF03CFE08B11020F7E7C34D287808B94E
+:1096B000FFF701FC601E1E2807D8012C22D130784C
+:1096C000FE281FD828770020E7E7A4F120001F28F4
+:1096D00005D8E0B23A463146BDE8F04144E4A4F191
+:1096E00040001F2805D831462046BDE8F04100F073
+:1096F000A3BAA4F1A0001F2804D80020A02C03D0F6
+:10970000A12C06D00720C8E7317801F00101697764
+:10971000C3E731680922F82901D38B0701D010462D
+:10972000BBE76B7C03F00303012B04D16B8BD733B6
+:109730009CB28C42F3D82962AFE72DE9F04781460D
+:109740000E4608460AF010FE48B948460AF02AFEBE
+:1097500028B909F1030020F00301494501D0102088
+:1097600030E795484FF0000A4430817869B141787C
+:10977000804600EB411408343788324600212046E9
+:1097800000F040FA050004D027E0A6F800A005206C
+:1097900018E7B9F1000F24D03088B84201D90C2560
+:1097A0001FE0607800F00705284600F017FA08EB84
+:1097B0000507324697F8E8014946401C87F8E8015A
+:1097C000204607F5F47700F01DFA05463878401E6C
+:1097D0003870032000F002FA2DB10C2D01D0A6F84C
+:1097E00000A02846EEE66078724E00F007010129DD
+:1097F00023D002290CD0032933D0FFDF98F80110C1
+:109800004046491CC9B288F801100F2934D035E010
+:10981000616821B1000702D46088FFF72BFE98F839
+:10982000EA014746012802D1707802F0AFFA97F9B1
+:10983000EA010428E2DBFFDFE0E7616819B14022BA
+:10984000B06806F01BFF98F8E9014746032802D1EB
+:10985000707802F09BFA97F9E9010428CEDBFFDF6C
+:10986000CCE7C00602D56088FFF704FE98F9EB014B
+:109870000628C3DBFFDFC1E780F801A08178491E1D
+:109880008170617801F0070101EB080090F8E811A0
+:10989000491C80F8E811A4E770B50D4604460AF0AB
+:1098A0003DFD18B928460AF05FFD08B1102070BDD3
+:1098B00029462046BDE8704008F0D9BD70B5044681
+:1098C00015460E4608460AF029FD18B928460AF042
+:1098D0004BFD08B1102070BD022C03D0102C01D01C
+:1098E000092070BD2A463146204608F0E3FD0028D5
+:1098F000F7D0052070BD70B514460D4606460AF037
+:109900000DFD38B928460AF02FFD18B920460AF097
+:1099100049FD08B1102070BD22462946304608F0A6
+:10992000E8FD0028F7D0072070BD3EB504460AF0D8
+:109930001BFD08B110203EBD684604F00FFEFFF786
+:1099400095FB0028F7D19DF806002070BDF80800AF
+:109950006080BDF80A00A08000203EBD70B50546BD
+:109960000C4608460AF01EFD20B93CB120680AF0FA
+:10997000FBFC08B1102070BDA08828B12146284604
+:10998000BDE87040FDF7BEBE092070BD70B504464D
+:109990000D4608460AF0C2FC30B9601E1E2818D8D1
+:1099A00028460AF0BBFC08B1102070BD022C05D976
+:1099B000072070BD1C0000209803002004B9FFDFC1
+:1099C000F94800EB840050F8041C2846BDE87040BC
+:1099D0000847A4F120001F2805D829462046BDE8E5
+:1099E0007040FAF792BCF02CE2D1A8680AF096FC1D
+:1099F0000028D9D1284606F0CBF8BDE87040FFF723
+:109A000035BB70B504460D4608460AF0ADFC30B9CA
+:109A1000601E1E280DD828460AF080FC08B11020D0
+:109A2000C7E7012C01D0022C01D10620C1E7072095
+:109A3000BFE7A4F120001F28F9D829462046BDE839
+:109A40007040FAF7BABC06F033BB38B50446D748C5
+:109A5000007B00F00105D9B9F9F78BFA0DB1226846
+:109A600000E00022D2484178C06804F06EFBD04884
+:109A70001030C0788DF8000010B1012802D004E049
+:109A8000012000E000208DF80000684604F0DFFDB2
+:109A9000002D02D020682830206038BD30B5C34D7D
+:109AA00004466878A04200D8FFDF686800EB041025
+:109AB00030BD70B5BD4800252C46467807E02046ED
+:109AC000FFF7ECFF4078641C2844C5B2E4B2B4420E
+:109AD000F5D128466DE72DE9F0410C46064600F029
+:109AE00006F907463068C01C20F00302326014BB40
+:109AF000AE483B46082124300AF0EAFA002409E087
+:109B0000082C10D2DFE804F0060408080A04040652
+:109B1000A84804E0A84802E0A84800E0A8480AF0E5
+:109B2000F7FA054600E0FFDFA54200D0FFDF641C26
+:109B3000E4B2082CE4D3306800EB07103060ACE5E9
+:109B4000021D5143452900D245210844C01CB0FBE9
+:109B5000F2F0C0B270472DE9FC5F064693484FF023
+:109B600000088B464746444690F8019022E0204684
+:109B7000FFF794FF050000D1FFDF6878694638449D
+:109B8000C7B22846FFF720F8824601A92846FFF70A
+:109B900035F80346BDF804005246001D81B2BDF8F9
+:109BA0000000001D80B206F081FF6A78641C00FB93
+:109BB0000288E4B24C45DAD13068C01C20F00300C2
+:109BC0003060BBF1000F00D000204246394606F05D
+:109BD0007BFF316808443060BDE8FC9F7349443125
+:109BE00008710020C870704770494431CA782AB1A2
+:109BF0000A7801EB42110831814201D001207047FF
+:109C0000002070472DE9F04106460078154600F027
+:109C10000F0400201080601E0F46052800D3FFDFD0
+:109C200061482A46103000EB8400394650F8043C65
+:109C30003046BDE8F041184770B50C46402802D0C8
+:109C4000412806D120E0A07861780D18E1788142A2
+:109C500001D90720ADE62078012801D91320A8E614
+:109C6000FF2D08D808F0B0FD064609F04CFF301A69
+:109C7000801EA84201DA12209BE64C4821688160D0
+:109C800021790173002094E6BDE87040084600F099
+:109C90005EB82DE9F0470027DFF810A13E463D46AB
+:109CA000B9463C469AF801800AE02046FFF7F6FEE6
+:109CB0004178807B0E4410FB0155641CE4B27F1C8C
+:109CC0004445F2D109EB8700C6EBC60100EB8100E9
+:109CD0009AF8092000EB850101EBC2019AF80A20ED
+:109CE0009AF80B0001EBC20101EB80006AE42DE958
+:109CF000F047DFF8B8900026344699F8090099F843
+:109D00000A2099F801700244D5B299F80B2010444A
+:109D100000F0FF0808E02046FFF7C0FE817B407896
+:109D200011FB0066641CE4B2BC42F4D199F809004E
+:109D300099F80A10284428444044401C01B10121EC
+:109D400008448419FF2C00D9FFDFE0B23AE438B5AB
+:109D50000446407800F00300012803D002280BD00D
+:109D6000072038BD606858B10AF025FBD0B960689B
+:109D70000AF018FB20B915E060680AF0CFFA88B93C
+:109D800069462046FCF71EF90028EAD1607800F009
+:109D90000300022816D19DF8000098B160680AF00F
+:109DA00001FB78B1102038BDB046020098030020B6
+:109DB0001C000020B941000017AC00005D2F00001E
+:109DC000F32101006189F8290DD8208988420AD839
+:109DD000607800F003020A48012A06D1D731026AEE
+:109DE00089B28A4201D20920DDE794E80E0000F131
+:109DF000100585E80E000AB9002101830020D2E792
+:109E0000980300202DE9F04107461446884608468D
+:109E100001F01CFD064608EB88001C22796802EB65
+:109E2000C0000D18688C58B14146384601F016FD47
+:109E3000014678680078C200082305F120000CE094
+:109E4000E88CA8B14146384601F00FFD014678681C
+:109E500008234078C20005F1240006F066FC38B102
+:109E6000062121726681D0E90010C4E9031009E0DF
+:109E7000287809280BD00520207266816868E06088
+:109E8000002028702046BDE8F04101F0D5BC072035
+:109E900020726681F4E72DE9F04116460D4607462B
+:109EA000406801EB85011C2202EBC10144182046E9
+:109EB00001F0FDFC40B10021708865F30F2160F3D3
+:109EC0001F4107200AF0DEF909202070324629469A
+:109ED0003846BDE8F04195E72DE9F0410E460746CA
+:109EE00000241C21F07816E004EB8403726801EB77
+:109EF000C303D25C6AB1FFF78DFA050000D1FFDF22
+:109F00006F802A4621463046FFF7C5FF0120BDE895
+:109F1000F081641CE4B2A042E6D80020F7E770B5F7
+:109F2000064600241C21C0780AE000BF04EB84032D
+:109F3000726801EBC303D5182A782AB1641CE4B215
+:109F4000A042F3D8402070BD282128461AF0AFF96E
+:109F5000706880892881204670BD70B50346002056
+:109F60001C25DC780DE000BF00EB80065A6805EB8D
+:109F7000C6063244167816B1128A8A4204D0401CB2
+:109F8000C0B28442F0D8402070BDF0B50446002035
+:109F90001C26E5780EE000BF00EB8007636806EB47
+:109FA000C7073B441F788F4202D15B78934204D0AD
+:109FB000401CC0B28542EFD84020F0BD0078032895
+:109FC00001D000207047012070470078022801D09E
+:109FD00000207047012070470078072801D000203A
+:109FE0007047012070472DE9F041064688461078F9
+:109FF000F1781546884200D3FFDF2C781C27641CBB
+:10A00000F078E4B2A04201D8201AC4B204EB840173
+:10A01000706807EBC1010844017821B141468847C7
+:10A0200008B12C7073E72878A042E8D1402028704E
+:10A030006DE770B514460B880122A240134207D188
+:10A0400013430B8001230A22011D06F038FB047024
+:10A0500070BD2DE9FF4F81B00878DDE90E7B9A468F
+:10A0600091460E4640072CD4019806F0E5FD040009
+:10A0700000D1FFDF07F1040820461FFA88F105F040
+:10A0800024FF050000D1FFDF204629466A4606F07E
+:10A090006EF90098A0F80370A0F805A0284606F015
+:10A0A00014FA017869F306016BF3C71101702046B9
+:10A0B0001FFA88F105F04CFF00B9FFDF019803F0AB
+:10A0C000B9FF06EB0900017F491C017705B0BDE827
+:10A0D000F08F2DE9F84F0E469A4691460746032128
+:10A0E00006F066FC0446008DDFF8B485002518B143
+:10A0F00098F80000B0421ED1384606F09DFD0700DA
+:10A1000000D1FFDF09F10401384689B205F0DDFE18
+:10A11000050010D0384629466A4606F028F900980E
+:10A1200000210A460180817004F054F80098C01D97
+:10A13000CAF8000021E098F80000B04216D104F1FE
+:10A14000260734F8341F012000FA06F911EA090F36
+:10A1500000D0FFDF2088012340EA090020800A2286
+:10A16000391D384606F0C6FA067006E0324604F19C
+:10A17000340104F12600FFF75CFF0A2188F8001083
+:10A180002846BDE8F88FFEB514460D46064602ABDC
+:10A190000C220621FFF79DFF002826D0029968783F
+:10A1A00012220A70801C487008224A80A8702088F9
+:10A1B00088806088C880A0880881E0884881002461
+:10A1C0000C20CDE900040523062229463046FFF77E
+:10A1D00040FF2146002266F31F41F023104609F09C
+:10A1E000A7FF6878801C68700120FEBDFEB514468C
+:10A1F0000D460622064602AB1146FFF76AFF00280D
+:10A2000012D0029B132000211870A87858700220E9
+:10A2100058809C800620CDE900010246052329468E
+:10A220003046FFF716FF0120FEBD2DE9FE430C4628
+:10A23000804644E002AB0E2207214046FFF749FF6B
+:10A24000002841D060681C2267788678BF1C06EB26
+:10A25000860102EBC1014518029814210170477074
+:10A260000A214180698A0181E98A4181A988818026
+:10A27000A9898181304601F0E9FA02990523072274
+:10A28000C8806F700420287000250E20CDE90005DD
+:10A2900021464046FFF7DDFE294666F30F2168F3AD
+:10A2A0001F41F0230022072009F042FF6078FD499A
+:10A2B000801C607062682046921CFFF794FE606804
+:10A2C00080784028B6D10120BDE8FE83FEB50D465A
+:10A2D000064638E002AB0E2207213046FFF7F9FEB2
+:10A2E000002835D068681C23C17801EB810203EB9C
+:10A2F000C2028418029815220270627842700A2203
+:10A300004280A2894281A2888281084601F09EFA99
+:10A31000014602988180618AC180E18A0181A0881A
+:10A32000B8B10020207000210E20CDE900010523E6
+:10A33000072229463046FFF78CFE6A68DA4928462C
+:10A34000D21CFFF750FE6868C0784028C2D10120B7
+:10A35000FEBD0620E6E72DE9FE430C46814644E0BB
+:10A36000204601F08EFAD0B302AB082207214846FE
+:10A37000FFF7AFFE0028A7D060681C226578067939
+:10A38000AD1C06EB860102EBC10147180298B7F835
+:10A39000108006210170457004214180304601F093
+:10A3A00055FA0146029805230722C180A0F80480CF
+:10A3B0007D70082038700025CDE90005214648460B
+:10A3C000FFF747FE294666F30F2169F31F41F0238B
+:10A3D0000022072009F0ACFE6078801C6070626883
+:10A3E000B2492046121DFFF7FEFD60680179402941
+:10A3F000B6D1012068E72DE9F34F83B00E4680E027
+:10A40000304601F03EFA002875D071681C2091F8A2
+:10A41000068008EB880200EBC2000C18414630466B
+:10A4200001F023FA0146A078C30070684078C200AA
+:10A4300004F1240006F095F907468088E18B401A64
+:10A4400080B2002581B3AA46218B814200D80846FC
+:10A450008146024602AB07210398FFF73AFE01004E
+:10A4600028D0BAF1000F03D0029AB88802251080D4
+:10A470008B46E28B3968A9EB05001FFA80FA0A4483
+:10A480000398009206F0D8FBED1D009A59465346FA
+:10A49000009505F0E6FFE08B504480B2E083B98878
+:10A4A000884209D1012508E0FFE7801C4FF0010A2E
+:10A4B00080B2C9E7002009E60025CDE90095238A8E
+:10A4C000072231460398FFF7C4FDE089401EE08172
+:10A4D0008DB1A078401CA0707068F178427811FBB3
+:10A4E00002F1CAB2816901230E3006F0E8F880F863
+:10A4F00000800020E08372686D493046921DFFF7AE
+:10A5000072FD7068817940297FF47AAF0120DDE522
+:10A5100070B5064648680D4614468179402910D129
+:10A5200004EB84011C2202EBC101084401F0E0F9B4
+:10A53000002806D06868294684713046BDE870401E
+:10A5400059E770BDFEB50C460746002645E020469B
+:10A5500001F097F9D8B360681C22417901EB8101C1
+:10A5600002EBC1014518688900B9FFDF02AB082280
+:10A5700007213846FFF7ADFD002833D002996078F7
+:10A5800016220A70801C4870042048806068407958
+:10A5900001F05CF901460298052307228180698950
+:10A5A000C1800820CDE9000621463846FFF751FD5D
+:10A5B0006078801C6070A88969890844B0F5803F84
+:10A5C00000D3FFDFA88969890844A8816E81626889
+:10A5D00038492046521DFFF706FD60684179402941
+:10A5E000B5D10120FEBD30B5438C458BC3F3C70404
+:10A5F000002345B1838B641EED1AC38A6D1E1D4472
+:10A6000095FBF3F3E4B22CB1008918B1A04200D855
+:10A61000204603444FF6FF70834200D30346138065
+:10A620000C7030BD2DE9FC41074616460D464868C2
+:10A6300002EB86011C2202EBC10144186A4601A903
+:10A640002046FFF7D0FFA089618901448AB2BDF896
+:10A650000010914212D0081A00D50020608168686D
+:10A66000407940280AD1204601F038F9002805D069
+:10A670006868294646713846FFF764FFBDE8FC81EB
+:10A680002DE9FE4F8946804615465088032106F085
+:10A690008FF98346B8F8020040280DD240200CE024
+:10A6A00030000020BD9F0000CB9F0000D99F00001C
+:10A6B000F1B80000DDB80000403880B282460146A3
+:10A6C000584601F0DEF800287ED00AEB8A001C22F2
+:10A6D000DBF8041002EBC0000C18204601F0E7F88C
+:10A6E000002877D1B8F80000E18A88423CD8A189D7
+:10A6F000D1B348456ED100265146584601F0AEF818
+:10A70000218C0F18608B48B9B9F1020F62D3B8F8E9
+:10A7100004006083618A884226D80226A9EB0600DD
+:10A720001FFA80F9B888A28B801A002814DD4946E8
+:10A73000814500DA084683B2688869680291396801
+:10A740000A44CDE9003206F065FADDE90121F61D83
+:10A75000009B009605F051FEA18B01EB090080B231
+:10A76000A083618B884207D9688803B05246594656
+:10A77000BDE8F04F01F0D9B81FD14FF009002872A1
+:10A78000B8F802006881D7E90001C5E90401608BCF
+:10A79000A881284601F050F85146584601F05EF86D
+:10A7A0000146DBF8040008230078C20004F1200011
+:10A7B00005F0BBFF0020A0836083A0890AF0FF02A0
+:10A7C000401EA081688800E004E003B05946BDE85F
+:10A7D000F04F27E7BDE8FE8F2DE9F041064615460C
+:10A7E0000F461C46184609F099FD18B9206809F073
+:10A7F000BBFD08B1102015E47168688C0978B0EBD6
+:10A80000C10F01D313200DE43946304601F026F87C
+:10A810000146706808230078C20005F1200005F0A9
+:10A820004EFFD4E90012C0E900120020E3E710B5A2
+:10A830000446032106F0BCF80146007800F003004E
+:10A84000022805D02046BDE8104001F114029AE428
+:10A850008A8A2046BDE81040C8E470B5044603214A
+:10A8600006F0A6F8054601462046FFF774FD0028CD
+:10A8700016D029462046FFF765FE002810D029464D
+:10A880002046FFF723FD00280AD029462046FFF77F
+:10A89000CCFC002804D029462046BDE87040AAE53B
+:10A8A00070BD2DE9F0410C4680461EE0E17842780B
+:10A8B00011FB02F1CAB2816901230E3005F035FFA8
+:10A8C000077860681C22C179491EC17107EB8701B6
+:10A8D000606802EBC10146183946204600F0D1FFFE
+:10A8E00018B1304600F0DCFF20B16068C179002962
+:10A8F000DCD180E7FEF78EFD050000D1FFDF0A20E6
+:10A900002872384600F0A2FF68813946204600F0E0
+:10A91000ACFF0146606808234078C20006F12400BD
+:10A9200005F003FFD0E90010C5E90310A5F8028087
+:10A93000284600F081FFB07800B9FFDFB078401EF4
+:10A94000B07058E770B50C460546032106F030F8A4
+:10A9500001464068C2792244C2712846BDE8704071
+:10A960009FE72DE9FE4F8246507814460F464FF080
+:10A97000000800284FD0012807D0022822D0FFDF8E
+:10A980002068B8606068F86024E702AB0E220821F6
+:10A990005046FFF79EFB0028F2D0029815210523B0
+:10A9A0000170217841700A214180C0F80480C0F80C
+:10A9B0000880A0F80C80628882810E20CDE9000812
+:10A9C000082221E0A678304600F040FF054606EB5D
+:10A9D00086012C22786802EBC1010822465A02AB9C
+:10A9E00011465046FFF775FB0028C9D00298072191
+:10A9F0000170217841700421418008218580C68042
+:10AA0000CDE9001805230A4639465046FFF721FBD9
+:10AA100087F80880DEE6A678022516B1022E13D04C
+:10AA2000FFDF2A1D914602AB08215046FFF751FB7C
+:10AA30000028A5D002980121022E017021784170D2
+:10AA40004580868002D005E00625EAE7A188C1801E
+:10AA5000E1880181CDE90098052308223946504656
+:10AA6000D4E710B50446032105F0A2FF014600F12A
+:10AA700008022046BDE8104073E72DE9F05F0C4660
+:10AA800001281DD0957992F80480567905EB85014F
+:10AA90001F2202EBC10121F0030B08EB060111FBA1
+:10AAA00005F14FF6FF7202EAC10909F1030115FB36
+:10AAB0000611F94F21F0031A40B101283DD124E0DD
+:10AAC0006168E57891F800804E78DFE7594678684C
+:10AAD00005F0A9FD606000B9FFDF5946606819F014
+:10AAE00008FCE5705146786805F09DFD6168486195
+:10AAF00000B9FFDF6068426902EB090181616068AB
+:10AB000080F800806068467017E0606852464169CE
+:10AB1000786805F0B3FD5A466168786805F0AEFDC7
+:10AB2000032005F0EDFE0446032005F0F1FE201A97
+:10AB3000012802D1786805F06BFD0BEB0A00BDE837
+:10AB4000F09F02460021022097E773B5D24D0A20FC
+:10AB50002870009848B100244FEA0D0005F045FD2B
+:10AB6000002C01D1009969607CBD01240020F5E72B
+:10AB700070B50C4615463821204619F0BAFB01265F
+:10AB800066700A2104F11C0019F0B3FB05B9FFDF60
+:10AB9000297A207861F301002070A879002817D065
+:10ABA0002A4621460020FFF768FF61684020887030
+:10ABB0006168C8706168087161684871616888710E
+:10ABC0006168288808816168688848816068868132
+:10ABD00070BDC878002802D0002201204DE77047E0
+:10ABE00070B50546002165F31F41002009F04AFBBE
+:10ABF0000321284605F0DCFE040000D1FFDF2146DA
+:10AC00002846FFF769F9002804D0207840F01000AA
+:10AC10002070012070BD2DE9FF4180460E460F0CCB
+:10AC2000FEF7F8FB050007D06F800321384605F0DA
+:10AC3000BFFE040008D106E004B03846BDE8F0418C
+:10AC40001321F9F7FBBEFFDF5FEA080005D0B8F17A
+:10AC5000070F18D0FFDFBDE8FF8120782A4620F0DB
+:10AC6000080020700020ADF8020002208DF80000DE
+:10AC70004FF6FF70ADF80400ADF80600694638469F
+:10AC8000F9F7EFFAE7E7C6F3072101EB81021C238E
+:10AC9000606803EBC202805C042803D008280AD055
+:10ACA000FFDFD8E7012000904FF440432A462046BA
+:10ACB00000F004FECFE704B02A462046BDE8F0418C
+:10ACC000FFF7E9B82DE9F05F0027B0F80A90904649
+:10ACD0000C4605463E46B9F1400F01D2402001E046
+:10ACE000A9F140001FFA80FA287AC01E08286BD20A
+:10ACF000DFE800F00D04192058363C477227102673
+:10AD0000002C6CD0D5E90301C4E902015CE0702796
+:10AD10001226002C63D00A2205F10C0104F1080070
+:10AD200019F08BFA50E071270C26002C57D0E868F8
+:10AD3000A06049E0742710269CB3D5E90301C4E95B
+:10AD400002016888032105F033FE8346FEF762FBAB
+:10AD500002466888508051465846FFF753F833E062
+:10AD600075270A26ECB1A88920812DE076271426C4
+:10AD7000BCB105F10C0004F1080307C883E8070023
+:10AD800022E07727102664B1D5E90301C4E9020166
+:10AD90006888032105F00CFE01466888FFF781FDF5
+:10ADA00012E01CE073270826CCB16888032105F067
+:10ADB000FFFD01460078C00606D56888FFF78CF8CD
+:10ADC00010B96888F8F71DFEA8F800602CB127803C
+:10ADD000A4F8069066806888A0800020AFE6A8F8F6
+:10ADE0000060FAE72DE9FC410C461E4617468046F6
+:10ADF000032105F0DDFD05460A2C0AD2DFE804F048
+:10AE000005050505050509090907042303E00623CF
+:10AE100001E0FFDF0023CDE90076224629464046C7
+:10AE2000FFF717F92AE438B50546A0F57F40FF384B
+:10AE300030D0284605F0EEFE040000D1FFDF2046AA
+:10AE400005F073FA002815D001466A46204605F041
+:10AE50008EFA00980321B0F80540284605F0A8FDB9
+:10AE60000546052C03D0402C05D2402404E0007A8E
+:10AE700080B1002038BD403CA4B2214600F001FD65
+:10AE800040B1686804EB84013E2202EBC101405AE4
+:10AE90000028EFD0012038BD300000202DE9F04F10
+:10AEA000044689B0408805F0B5FE050000D1FFDFFB
+:10AEB00006AA2846616800F0BDFC069D001F81B20D
+:10AEC00035F8032F6B888A4205D1042B0AD0052B55
+:10AED0001DD0062B15D022462846FFF7D1FB09B01E
+:10AEE000BDE8F08F16462D1D224629463046F7F75D
+:10AEF00054FA0828F3D1224629463046FCF749FC8B
+:10AF0000EDE76088291D6368FAF7C8FCE7E7174694
+:10AF10006088032105F04CFD4FF000088DF8048097
+:10AF20000646ADF80680042FD9D36A79002AD6D018
+:10AF300028794FF6FF794FF01C0A13282CD008DC33
+:10AF4000012878D0062847D0072875D0122874D158
+:10AF500006E0142872D0152871D016286DD1ACE106
+:10AF60000C2F6AD1307800F00301022965D140F03E
+:10AF7000080030706879B07001208DF804002889CD
+:10AF8000ADF808006889ADF80A00A889ADF80C0092
+:10AF9000E889ADF80E0019E0B07890429FD1307882
+:10AFA00001079CD5062F9AD120F0080030706088E8
+:10AFB000414660F31F41002009F064F902208DF83A
+:10AFC0000400ADF808902889ADF80A006088224690
+:10AFD00001A9F9F746F982E7082F80D12F89B5F842
+:10AFE0000A90402F01D2402001E0A7F1400080B23A
+:10AFF00080460146304600F044FC08B3716808EB17
+:10B0000088002C2202EBC000095A4945E3D1FE48D2
+:10B0100007AAD0E90210CDE9071068798DF81C0065
+:10B0200008F0FF058DF81E5060883146FFF799FC47
+:10B030002246294639E0B6E014E03CE039E0E6E09B
+:10B04000F148D0E90010CDE907106879ADF820701B
+:10B050008DF81C00ADF82290608807AA3146FFF7F2
+:10B0600080FC3CE7082FB6D16889B5F808804028F5
+:10B0700001D2402000E0403887B23946304600F027
+:10B0800000FC0028A7D007EB870271680AEBC2001A
+:10B090000844028A42459ED1017808299BD1407814
+:10B0A0006979884297D1F9B222463046FEF7F3FE1D
+:10B0B00015E70E2F07D0CDF81C80CDF820806879D9
+:10B0C0008DF81C00C8E76989EF898B46B5F80C90AC
+:10B0D0003046FEF742FFABF14001402901D3092081
+:10B0E0004AE0B9F1170F01D3172F01D20B2043E02B
+:10B0F00040280ED000EB800271680AEBC2000844C1
+:10B100000178012903D1407869798842A9D00A20C1
+:10B1100032E03046FEF703FF014640282BD001EB1A
+:10B12000810372680AEBC30002EB0008012288F871
+:10B1300000206A7988F8012070682A894089B8421D
+:10B1400000D938462D8A03232372A282E781208208
+:10B15000A4F80C906582084600F078FB6081A8F89E
+:10B160001490A8F81870A8F80E50A8F810B020464F
+:10B1700000F062FBB3E6042005212172A4F80A80E6
+:10B18000E08101212173A049D1E90421CDE9072102
+:10B1900069798DF81C10ADF81E00608807AA314649
+:10B1A000FFF7DFFBE3E7062FE4D3B078904215D139
+:10B1B0003078010712D520F00800307060884146D1
+:10B1C00060F31F41002009F05DF802208DF80400B3
+:10B1D0002889ADF80800ADF80A90F7E6042130465A
+:10B1E000FEF7D3FE05464028C4D00220830300901A
+:10B1F00022462946304600F061FB4146608865F3EF
+:10B200000F2160F31F41072009F03CF867E60E2F7D
+:10B21000B0D104213046FEF7B8FE81464028A9D0BF
+:10B220004146608869F30F2160F31F41072009F050
+:10B2300029F8288A0790E88900907068AF894089CA
+:10B24000B84200D938468346B5F80A802889059067
+:10B25000484600F0FBFA6081079840B10220079B46
+:10B26000009022464946304600F028FB37E6B8F108
+:10B27000170F1ED3172F1CD3042020720098608252
+:10B28000E781A4F810B0A4F80C8009EB890271687A
+:10B290000AEBC2000D1800990598A5F81480A5F8CE
+:10B2A00018B0E9812882204600F0C6FA06202870EE
+:10B2B00015E601200B230090D3E7082FA6D129899A
+:10B2C0003046FEF74AFE074640289FD007EB87022C
+:10B2D00071680AEBC2000844804600F0E8FA0028D2
+:10B2E00094D16D89B8F80E002844B0F5803F05D39D
+:10B2F00060883A46314600F018FBF0E5002D85D015
+:10B30000A8F80E0060883A463146FFF701F9082098
+:10B310002072384600F09AFA6081A58127E770B55F
+:10B320000D460646032105F043FB040004D02078B7
+:10B33000000704D5112070BD43F2020070BD2A46FB
+:10B3400021463046FEF71FFF18B92868606168681B
+:10B35000A061207840F008002070002070BD70B51A
+:10B360000D460646032105F023FB040004D0207897
+:10B37000000704D4082070BD43F2020070BD2A46C5
+:10B3800021463046FEF732FF00B9A582207820F032
+:10B3900008002070002070BD2DE9F04F0E4691B0DE
+:10B3A0008046032105F004FB0446404605F044FCBA
+:10B3B00007460020079008900990ADF830000A90E9
+:10B3C00002900390049004B9FFDF0DF1080917BB48
+:10B3D000FFDF20E038460BA9002204F069FE9DF84B
+:10B3E0002C0000F07F050A2D00D3FFDF6019017FDC
+:10B3F000491E01779DF82C0000060CD52A460CA9A1
+:10B4000007A8FEF716FE01E0D846020019F805105D
+:10B41000491C09F80510761EF6B2DBD204F134009F
+:10B42000FA4D04F1260BDFF8E8A304F12A07069091
+:10B4300010E05846069900F06AFA064628700A2875
+:10B4400000D3FFDF5AF8261040468847E08CC05DE5
+:10B45000B04202D0208D0028EBD10A202870EC4D9C
+:10B460004E4628350EE00CA907A800F050FA044615
+:10B47000375D55F8240000B9FFDF55F82420394620
+:10B4800040469047BDF81E000028ECD111B027E5DA
+:10B4900010B5032105F08CFA040000D1FFDF0A216A
+:10B4A00004F11C0018F025FF207840F00400207003
+:10B4B00010BD10B50C46032105F07AFA2044007F38
+:10B4C000002800D0012010BD2DE9F84F894615460F
+:10B4D0008246032105F06CFA070004D0284608F0E4
+:10B4E0001DFF40B903E043F20200BDE8F88F484673
+:10B4F00008F03AFF08B11020F7E7786828B16988AA
+:10B500000089814201D90920EFE7B9F800001C2425
+:10B5100018B1402809D2402008E03846FEF7FFFC69
+:10B520008046402819D11320DFE7403880B280469A
+:10B530000146384600F0A5F948B108EB8800796863
+:10B5400004EBC000085C012803D00820CDE70520EB
+:10B55000CBE7FDF75FFF06000BD008EB88007968AA
+:10B5600004EBC0000C18B9F8000020B1E88910B154
+:10B5700013E01120B9E72888172802D36888172814
+:10B5800001D20720B1E7686838B12B1D2246414639
+:10B590003846FFF721F90028A7D104F10C026946CB
+:10B5A0002046FFF720F8288860826888E082B9F892
+:10B5B000000030B102202070E889A080E889A0B1A5
+:10B5C0002BE003202070A889A0807868817840292A
+:10B5D00005D180F8028039465046FEF726FE4046E7
+:10B5E00000F034F9A9F8000021E07868218B408947
+:10B5F000884200D908462083A6F802A004203072B1
+:10B60000B9F800007081E0897082F181208B30826E
+:10B61000A08AB081304600F00FF97868C1784029DF
+:10B6200005D180F8038039465046FEF74FFE0020D2
+:10B630005BE770B50D460646032105F0B9F9040035
+:10B6400003D0402D04D2402503E043F2020070BD38
+:10B65000403DADB2294600F014F958B105EB850123
+:10B660001C22606802EBC101084400F020F918B107
+:10B67000082070BD052070BD2A462146304600F0E6
+:10B6800054F9002070BD2DE9F0410D461646804664
+:10B69000032105F08DF90446402D01D2402500E03C
+:10B6A000403DADB28CB1294600F0EBF880B105EB1E
+:10B6B00085011C22606802EBC1014718384600F082
+:10B6C000F6F838B10820BDE8F08143F20200FAE74D
+:10B6D0000520F8E733463A4629462046FFF77CF82E
+:10B6E0000028F0D1EAB221464046FEF79BFF002039
+:10B6F000E9E72DE9F0410D4616468046032105F0A5
+:10B7000057F90446402D01D2402500E0403DAFB23C
+:10B7100024B1304608F002FE38B902E043F20200DC
+:10B72000D1E7306808F0FAFD08B11020CBE73946C0
+:10B73000204600F0A6F860B107EB87011C22606884
+:10B7400002EBC1014518284600F0B1F818B10820F5
+:10B75000B9E70520B7E7B088A98A884201D90C204B
+:10B76000B1E76168E88C4978B0EBC10F01D31320D1
+:10B77000A9E73946204600F078F8014660680823BA
+:10B780004078C20005F1240004F099FFD6E90012C8
+:10B79000C0E90012FAB221464046FEF7B9FE002089
+:10B7A00091E72DE9F0470D461F469046814603215B
+:10B7B00005F0FEF80446402D01D2402001E0A5F13D
+:10B7C000400086B23CB14DB1384608F0EBFD50B1B7
+:10B7D0001020BDE8F08743F20200FAE76068C8B1C4
+:10B7E000A0F80C8024E03146204600F04AF888B1E9
+:10B7F00006EB86011C22606802EBC1014518284651
+:10B8000000F055F840B10820E3E7000030000020C8
+:10B81000F04602000520DCE7A5F80880F2B22146D8
+:10B820004846FEF7FFFE1FB1A889698908443880A1
+:10B830000020CEE704F09BBD017821F00F01491CE8
+:10B8400021F0F00110310170FDF7E7BD10B504469D
+:10B85000402800D9FFDF4034A0B210BD40684269E3
+:10B860000078484302EBC0007047C2784068037814
+:10B8700012FB03F24378406901FB032100EBC10096
+:10B880007047C2788A4209D9406801EB81011C22C5
+:10B8900002EBC101405C08B10120704700207047F5
+:10B8A0000078062801D901207047002070470078F1
+:10B8B000062801D00120704700207047F0B401EB4A
+:10B8C00081061C27446807EBC6063444049D052600
+:10B8D0002670E3802571F0BCFEF794BA10B541895B
+:10B8E00011B1FFF7DDFF08B1002010BD012010BD30
+:10B8F00010B5C18C8278B1EBC20F04D9C18911B1E6
+:10B90000FFF7CEFF08B1002010BD012010BD10B51B
+:10B910000C4601230A22011D04F007FF007821884C
+:10B92000012282409143218010BDF0B402EB8205D8
+:10B930001C264C6806EBC505072363554B681C792C
+:10B94000402C03D11A71F0BCFEF705BDF0BC704766
+:10B9500010B5EFF3108000F0010472B6EE484178A4
+:10B96000491C41704078012801D1F7F70DFB002CEC
+:10B9700000D162B610BD70B5E74CE07848B901253A
+:10B98000E570FFF7E5FFF7F707FB20B1002008F0AF
+:10B990000AF9002070BD4FF080406571C0F8045373
+:10B9A000F7E770B5EFF3108000F0010572B6DA4CDE
+:10B9B000607800B9FFDF6078401E6070607808B979
+:10B9C000F7F7E6FA002D00D162B670BDD24810B587
+:10B9D000C17821B100214171C170FFF7E2FF002061
+:10B9E00010BD10B50446F7F7D7FACB49C97808401F
+:10B9F00000D001202060002010BD2DE9F05FDFF8AD
+:10BA000018934278817889F80620002589F8071074
+:10BA1000064689F8085000782F4620B101280FD03B
+:10BA200002280FD0FFDFF7F7C4FA98B1F7F7C8FA8A
+:10BA3000A8420FD12846F7F7C7FA0028FAD047E006
+:10BA40000125F0E7FFF784FFF7F7A6FA0028FBD0FF
+:10BA50000225E8E701208407E060C4F80471AF49DB
+:10BA60000D600107D1F84412AC4AC1F342312432CF
+:10BA70001160AA49343108604FF0020BC4F804B3D6
+:10BA8000A060DFF89CA2DAF80010C94341F300116E
+:10BA900001F10108DAF8001041F01001CAF80010B5
+:10BAA00000E020BFD4F804010028FAD02846F7F7B8
+:10BAB0008BFA0028FAD0B8F1000F05D1DAF800109F
+:10BAC00021F01001CAF80010C4F808B3C4F80471DA
+:10BAD00099F807004C4670B1307860B9F7F75CFA16
+:10BAE000064608F0BDF96FF0004116B1C4E9031035
+:10BAF00001E0C4E9030115B12771BDE8F09F012001
+:10BB00002071BDE8F05F00F0ABB870B5050000D162
+:10BB1000FFDF4FF080424FF0FF30C2F808030021F2
+:10BB2000C2F80011C2F80411C2F80C11C2F81011C9
+:10BB3000794C6170F7F736FA10B10120E07060704F
+:10BB40002846BDE8704058E72DE9F05F7548D0F809
+:10BB500000B0744A7449083211608406D4F80801B0
+:10BB600008B1012600E00026D4F8000110B14FF022
+:10BB7000010801E04FF00008D4F8040108B10127E2
+:10BB800000E00027D4F80C0100B101208246D4F86F
+:10BB9000100108B1012100E00021894646EA0801B0
+:10BBA00027EA010020EA0A0030EA090000D0FFDF9E
+:10BBB000002526B1C4F80851012007F0F4FF564EC5
+:10BBC000B8F1000F10D0C4F80051707918B1757138
+:10BBD000002007F0E8FF307830B10120534935707C
+:10BBE000B07002220A6020610FB1C4F80451BAF1AA
+:10BBF000000F0BD0C4F80C51B07800B9FFDF4B48F0
+:10BC00000560B57001206061FFF7CBFEB9F1000F50
+:10BC100005D0C4F81051307908B100F045F8414919
+:10BC2000091DC1F800B068E770B53B4DE87808B968
+:10BC3000F7F7AEF901208407A061A87858B100BFDA
+:10BC4000D4F80C0120B90020F7F7BEF90028F7D18D
+:10BC50000020C4F80C014FF0FF30C4F8080370BD99
+:10BC60002DE9F0411926B407C4F808630125A56140
+:10BC70000020C4F80001C4F80C01C4F81001F7F763
+:10BC80008BF9254F28B12949BD7002200860256134
+:10BC900000E03D70FFF75CFE2049B8792031086074
+:10BCA000C4F80463BDE8F0812DE9F0411A4C4FF06F
+:10BCB00080470125E079F0B1012803D0217A401EA8
+:10BCC000814218DAF7F768F9064608F0C9F8E17911
+:10BCD000012902D9217A491C21720EB1216900E0A3
+:10BCE000E168411A022902DA11F1020F0EDC0EB1ED
+:10BCF000206100E0E060FFF72BFEF7F74DF938B167
+:10BD00000A49022008603D61A57002E07D61C9E733
+:10BD1000257000202072C5E73C0000201805004077
+:10BD200010ED00E01005024001000001340C00405D
+:10BD30004FF0E0214FF00070C1F88001C1F880029F
+:10BD4000384B802283F80024C1F80001704700B509
+:10BD500002460420344903E001EBC0031B792BB1F8
+:10BD6000401EC0B2F8D2FFDFFF2000BD41F83020F6
+:10BD700001EBC00100224A718A7101220A7100BDE3
+:10BD8000294A002102EBC0000171704710B504463A
+:10BD9000042800D3FFDF244800EBC40420790128E5
+:10BDA00000D0FFDF6079A179401CC0B2814200D091
+:10BDB00060714FF0E0214FF00070C1F8000210BD3B
+:10BDC0002DE9F041194805681849194808310860FB
+:10BDD0001448042690F80004134F4009154C042819
+:10BDE00018D0FFDF16E0217807EBC1000279012AA5
+:10BDF00008D1427983799A4204D04279827157F806
+:10BE0000310080472078401CC0B22070042801D344
+:10BE100000202070761EF6B2E5D20448001D0560B1
+:10BE2000BDE8F08119E000E0C805002010050240DF
+:10BE30000100000150000020F8B51D46DDE906476D
+:10BE40000E000AD004F0F8FE2346FF1DBCB23146B6
+:10BE50002A46009404F005FBF8BDD0192246194685
+:10BE600018F0A6F92046F8BD70B50D46044610211D
+:10BE700018F01DFA258117206081A07B40F00A0090
+:10BE8000A07370BD4FF6FF720A800146022008F0D1
+:10BE9000F9B9704700897047827BD30701D19207B7
+:10BEA00003D4808908800020704705207047827B7A
+:10BEB000920700D58181704701460020098841F62C
+:10BEC000FE52114200D00120704700B50346807B2E
+:10BED000C00701D0052000BD59811846FFF7ECFFCF
+:10BEE000C00703D0987B40F004009873987B40F023
+:10BEF00001009873002000BD827B520700D509B174
+:10BF00004089704717207047827B61F3C3028273B8
+:10BF100070472DE9FC5F0E460446017896460120E5
+:10BF200000FA01F14DF6FF5201EA020962684FF68C
+:10BF3000FF7B1188594502D10920BDE8FC9FB9F16A
+:10BF4000000F05D041F6FE55294201D00120F4E74B
+:10BF500041EA090111801D0014D04FF0000C85F852
+:10BF600000C023780521032267464FF0020A0E2BFA
+:10BF700074D2DFE803F0F809252F4762697447900F
+:10BF800092B3D0D70420D8E7616820898B7B9B07C8
+:10BF90007DD5172848D30B89834245D38989172932
+:10BFA00001D3814240D185F800A0A5F8010032807C
+:10BFB000616888816068817B21F002018173C5E03E
+:10BFC000042028702089A5F801006089A5F80300E5
+:10BFD0003180BBE0208A3188C01D1FFA80F84145BE
+:10BFE00022D3062028702089A5F801006089A5F8D1
+:10BFF0000300A089A5F805000721208ACDE90001EA
+:10C0000063693EE0082B10D0082028702089A5F82D
+:10C0100001006089A5F8030031806A1D694604F1BA
+:10C020000C0006F066FA10B15FE01020EDE73088F2
+:10C030009DF800100844308088E00A20287020898C
+:10C04000A5F80100328045E00C2028702089A5F871
+:10C0500001006089A5F8030031803BE083E021897D
+:10C06000338800EB41021FFA82F843453DD3B8F113
+:10C07000050F3AD30E222A700BEA4101CDE90010D8
+:10C08000E36860882A467146FFF7D6FE00E04DE07F
+:10C09000A6F800805AE04020287060893188C01CD2
+:10C0A0001FFA80F8414520D32878714620F03F00E0
+:10C0B000123028702089A5F801006089CDE90002BE
+:10C0C00060882A46E368FFF7B7FEA6F80080287864
+:10C0D00040063BD461682089888037E0A089328897
+:10C0E000401D1FFA80F8424501D204273EE0162089
+:10C0F00028702089A5F801006089A5F80300A089AF
+:10C10000CDE9000160882A4671462369FFF794FE55
+:10C11000A6F80080DEE718202870207A6870A6F85C
+:10C1200000A013E061680A88920401D405271DE08D
+:10C13000C9882289914201D0062717E01E21297063
+:10C1400030806068018821F400510180B9F1000F4E
+:10C150000CD0618878230022022007F0E9FF616893
+:10C160002078887007E0A6F800C00327606801887F
+:10C1700021EA090101803846DFE62DE9FF4F85B04D
+:10C180001746129C0D001E461CD03078C10703D004
+:10C1900000F03F00192801D9012100E000212046CC
+:10C1A000FFF7AAFEA8420DD32088A0F57F41FF39F2
+:10C1B00008D03078410601D4000605D5082009B022
+:10C1C000BDE8F08F0720FAE700208DF800008DF819
+:10C1D000010030786B1E00F03F0C0121A81E4FF0CB
+:10C1E000050A4FF002094FF0030B9AB2BCF1200F81
+:10C1F00075D2DFE80CF08B10745E7468748C749CDC
+:10C2000074B674BB74C974D574E2747474F274F047
+:10C2100074EF74EE748B052D78D18DF80090A078B2
+:10C220008DF804007088ADF8060030798DF80100B3
+:10C23000707800F03F000C2829D00ADCA0F1020041
+:10C24000092863D2DFE800F0126215621A621D62EB
+:10C250002000122824D004DC0E281BD01028DBD1AB
+:10C260001BE016281FD01828D6D11FE020788007A1
+:10C2700001E020784007002848DAEFE02078000746
+:10C28000F9E72078C006F6E720788006F3E7207803
+:10C290004006F0E720780006EDE72088C005EAE7D1
+:10C2A00020884005E7E720880005E4E72088C004EF
+:10C2B000E1E72078800729D5032D27D18DF800B03C
+:10C2C000B6F8010082E0217849071FD5062D1DD35D
+:10C2D00081B27078012803D0022817D102E0CAE0A9
+:10C2E000022000E0102004228DF8002072788DF8E2
+:10C2F0000420801CB1FBF0F2ADF8062092B242435C
+:10C300008A4203D10397ADF80890A7E07AE020783D
+:10C31000000777D598B282088DF800A0ADF8042008
+:10C32000B0EB820F6ED10297ADF8061096E021783F
+:10C33000C90667D5022D65D381B206208DF80000AD
+:10C34000707802285ED300BFB1FBF0F28DF80400D4
+:10C35000ADF8062092B242438A4253D1ADF808901C
+:10C360007BE0207880064DD5072003E0207840064A
+:10C370007FD508208DF80000A088ADF80400ADF846
+:10C380000620ADF8081068E02078000671D5092075
+:10C39000ADF804208DF80000ADF8061002975DE0BE
+:10C3A0002188C90565D5022D63D381B20A208DF895
+:10C3B0000000707804285CD3C6E72088400558D573
+:10C3C000012D56D10B208DF80000A088ADF8040097
+:10C3D00044E021E026E016E0FFE72088000548D58C
+:10C3E000052D46D30C208DF80000A088ADF8040080
+:10C3F000B6F803006D1FADF80850ADF80600ADF8B3
+:10C400000AA02AE035E02088C00432D5012D30D1C1
+:10C410000D208DF8000021E02088800429D4B6F892
+:10C420000100E080A07B000723D5032D21D33078C5
+:10C4300000F03F001B2818D00F208DF80000208846
+:10C4400040F40050A4F80000B6F80100ADF8040074
+:10C45000ED1EADF80650ADF808B003976946059893
+:10C46000F5F7E6FC050008D016E00E208DF8000078
+:10C47000EAE7072510E008250EE0307800F03F00DD
+:10C480001B2809D01D2807D00220059907F0FAFEC5
+:10C49000208800F400502080A07B400708D520466B
+:10C4A000FFF70AFDC00703D1A07B20F00400A073B2
+:10C4B000284684E61FB5022806D101208DF8000029
+:10C4C00088B26946F5F7B4FC1FBD0000F8B51D46FB
+:10C4D000DDE906470E000AD004F0AEFB2346FF1D3F
+:10C4E000BCB231462A46009403F0BBFFF8BDD01918
+:10C4F0002246194617F05CFE2046F8BD2DE9FF4F95
+:10C500008DB09B46DDE91B57DDF87CA00C46082B5F
+:10C5100005D0E06901F002F950B11020D2E028887E
+:10C52000092140F0100028808AF80010022617E048
+:10C53000E16901208871E2694FF420519180E1693D
+:10C540008872E06942F601010181E069002181738E
+:10C550002888112140F0200028808AF80010042645
+:10C5600038780A900A2038704FF0020904F1180058
+:10C570004D460C9001F095FBB04681E0BBF1100FE9
+:10C580000ED1022D0CD0A9EB0800801C80B2022134
+:10C59000CDE9001005AB52461E990D98FFF796FFA6
+:10C5A000BDF816101A98814203D9F74800790F9008
+:10C5B00004E003D10A9808B138702FE04FF002016F
+:10C5C000CDE900190DF1160352461E990D98FFF79B
+:10C5D0007DFF1D980088401B801B83B2C6F1FF00C1
+:10C5E000984200D203461E990BA8D9B15FF0000211
+:10C5F000DDF878C0CDE9032009EB060189B2CDE969
+:10C6000001C10F980090BDF8161000220D9801F09E
+:10C61000CBFB387070B1C0B2832807D0BDF81600CC
+:10C6200020833AE00AEB09018A19E1E7022011B000
+:10C63000BDE8F08FBDF82C00811901F0FF08022D34
+:10C640000DD09AF80120424506D1BDF82010814254
+:10C6500007D0B8F1FF0F04D09AF801801FE08AF8E4
+:10C660000180C94800680178052902D1BDF816107B
+:10C67000818009EB08001FFA80F905EB080085B2FC
+:10C68000DDE90C1005AB0F9A01F00EFB28B91D98DF
+:10C690000088411B4145BFF671AF022D13D0BBF19D
+:10C6A000100F0CD1A9EB0800801C81B20220CDE94B
+:10C6B000000105AB52461E990D98FFF707FF1D9824
+:10C6C0000580002038700020B1E72DE9F8439C4632
+:10C6D000089E13460027B26B9AB3491F8CB2F18FA4
+:10C6E000A1F57F45FF3D05D05518AD882944891D2A
+:10C6F0008DB200E000252919B6F83C80083141458B
+:10C7000020D82A44BCF8011022F8021BBCF8031000
+:10C7100022F8021B984622F8024B914604F07AFA5E
+:10C720004FF00C0C41464A462346CDF800C003F0BA
+:10C7300064FEF587B16B00202944A41D21440880C4
+:10C7400003E001E0092700E083273846BDE8F883CD
+:10C7500010B50B88848F9C420CD9846BE018048838
+:10C7600044B1848824F40044A41D23440B80106049
+:10C77000002010BD0A2010BD2DE9F0478AB0002529
+:10C78000904689468246ADF8185007274BE0059839
+:10C7900006888088000446D4A8F8006007A80195A0
+:10C7A00000970295CDE903504FF400730022314603
+:10C7B000504601F0F9FA04003CD1BDF81800ADF87C
+:10C7C0002000059804888188B44216D10A0414D444
+:10C7D00001950295039521F400410097049541F4D9
+:10C7E000804342882146504601F0B4F804000BD142
+:10C7F0000598818841F40041818005AA08A948462E
+:10C80000FFF7A6FF0400DCD000970598029501957C
+:10C81000039504950188BDF81C300022504601F0B4
+:10C8200099F80A2C06D105AA06A94846FFF790FFF9
+:10C830000400ACD0ADF8185004E00598818821F4CC
+:10C840000041818005AA06A94846FFF781FF00281C
+:10C85000F3D00A2C03D020460AB0BDE8F0870020B0
+:10C86000FAE710B50C46896B86B051B10C218DF8F2
+:10C870000010A18FADF80810A16B01916946FAF77D
+:10C8800064FC00204FF6FF71A063E187A08706B02B
+:10C8900010BD2DE9F0410D460746896B0020069E2C
+:10C8A0001446002911D0012B0FD1324629463846B3
+:10C8B000FFF762FF002808D1002C06D03246294637
+:10C8C0003846BDE8F04100F038BFBDE8F0812DE901
+:10C8D000FC411446DDE9087C0E46DDE90A15521DCF
+:10C8E000BCF800E092B2964502D20720BDE8FC8178
+:10C8F000ACF8002017222A70A5F80160A5F80330D3
+:10C900000522CDE900423B462A46FFF7DFFD002025
+:10C91000ECE770B50C4615464821204617F0E9FCB7
+:10C9200004F1080044F81C0F00204FF6FF71E0618D
+:10C9300061842084A5841720E08494F82A0040F0C4
+:10C940000A0084F82A0070BD4FF6FF720A80014683
+:10C95000032007F097BC30B585B00C460546FFF7BD
+:10C9600080FFA18E284629B101218DF8001069466B
+:10C97000FAF7EBFB0020E0622063606305B030BD96
+:10C98000B0F84000704700005400002090F84620A6
+:10C99000920703D4408808800020F3E70620F1E7DF
+:10C9A00090F846209207EDD5A0F84410EAE701463A
+:10C9B000002009880A0700D5012011F0F00F01D0EE
+:10C9C00040F00200CA0501D540F004008A0501D5F7
+:10C9D00040F008004A0501D540F010000905D1D506
+:10C9E00040F02000CEE700B5034690F84600C007AF
+:10C9F00001D0062000BDA3F842101846FFF7D7FF6C
+:10CA000010F03E0F05D093F8460040F0040083F884
+:10CA1000460013F8460F40F001001870002000BDDA
+:10CA200090F84620520700D511B1B0F84200A9E7AE
+:10CA30001720A7E710F8462F61F3C3020270A1E7A1
+:10CA40002DE9FF4F9BB00E00DDE92B34DDE929789D
+:10CA5000289D24D02878C10703D000F03F00192872
+:10CA600001D9012100E000212046FFF7D9FFB042A3
+:10CA700015D32878410600F03F010CD41E290CD0B4
+:10CA8000218811F47F6F0AD13A8842B1A1F57F4223
+:10CA9000FF3A04D001E0122901D1000602D504209A
+:10CAA0001FB0C5E5F9491D984FF0000A08718DF8CF
+:10CAB00018A08DF83CA00FAA0A60ADF81CA0ADF834
+:10CAC00050A02978994601F03F02701F5B1C04F1C9
+:10CAD000180C4FF0060E4FF0040BCDF858C01F2A6B
+:10CAE0007ED2DFE802F07D7D107D267DAC7DF47D79
+:10CAF000F37DF27DF17DF47DF07D7D7DEF7DEE7D3A
+:10CB00007D7D7D7DED0094F84610B5F80100890724
+:10CB100001D5032E02D08DF818B022E34FF4006146
+:10CB2000ADF85010608003218DF83C10ADF8400046
+:10CB3000D8E2052EEFD1B5F801002083ADF81C0036
+:10CB4000B5F80310618308B1884201D901207FE163
+:10CB50000020A07220814FF6FF702084169801F00B
+:10CB6000A0F8052089F800000220029083460AAB55
+:10CB70001D9A16991B9801F097F890BB9DF82E000E
+:10CB8000012804D0022089F80100102003E00120D0
+:10CB900089F8010002200590002203A90BA805F0E6
+:10CBA000A8FCE8BB9DF80C00059981423DD13A886C
+:10CBB000801CA2EB0B01814237DB02990220CDE9F8
+:10CBC00000010DF12A034A4641461B98FFF77EFCFF
+:10CBD00002980BF1020B801C80B217AA03A901E096
+:10CBE000A0E228E002900BA805F083FC02999DF8D2
+:10CBF0000C00CDE9000117AB4A4641461B98FFF7F0
+:10CC000065FC9DF80C100AAB0BEB01001FFA80FBD2
+:10CC100002981D9A084480B2029016991B9800E071
+:10CC200003E001F041F80028B6D0BBF1020F02D0BA
+:10CC3000A7F800B053E20A208DF818004FE2002157
+:10CC40000391072EFFF467AFB5F801002083ADF81C
+:10CC50001C00B5F80320628300283FF477AF9042B0
+:10CC60003FF674AF0120A072B5F8050020810020C6
+:10CC7000A073E06900F052FD78B9E1690120887184
+:10CC8000E2694FF420519180E1698872E06942F6CF
+:10CC900001010181E06900218173F01F20841E9849
+:10CCA000606207206084169800F0FBFF072089F877
+:10CCB00000000120049002900020ADF82A0028E036
+:10CCC0001DE2A3E13AE1EAE016E2AEE086E049E0E7
+:10CCD0000298012814D0E0698079012803D1BDF8B9
+:10CCE0002800ADF80E00049803ABCDE900B04A4629
+:10CCF00041461B98FFF7EAFB0498001D80B20490A0
+:10CD0000BDF82A00ADF80C00ADF80E00059880B211
+:10CD100002900AAB1D9A16991B9800F0C5FF28B91E
+:10CD200002983988001D05908142D1D202980128CD
+:10CD300081D0E0698079012805D0BDF82810A1F5DF
+:10CD40007F40FF3803D1BDF82800ADF80E000498ED
+:10CD500003ABCDE900B04A4641461B98FFF7B6FB4E
+:10CD60000298BBE1072E02D0152E7FF4D4AEB5F8A1
+:10CD700001102183ADF81C10B5F80320628300294F
+:10CD80003FF4E4AE91423FF6E1AE0121A1724FF0D3
+:10CD9000000BA4F808B084F80EB0052E07D0C0B27E
+:10CDA000691DE26905F086FB00287FF444AF4FF669
+:10CDB000FF70208401A906AA14A8CDF800B081E86C
+:10CDC00085032878214600F03F031D9A1B98FFF742
+:10CDD00095FB8246208BADF81C0080E10120032EDC
+:10CDE000C3D14021ADF85010B5F801102183ADF842
+:10CDF0001C100AAAB8F1000F00D00023CDE90203ED
+:10CE000004921D98CDF80480009038880022401EBE
+:10CE100083B21B9800F0C8FF8DF8180090BB0B2060
+:10CE200089F80000BDF8280037E04FF0010C052E0E
+:10CE30009BD18020ADF85000B5F801102183B5F8E2
+:10CE400003002084ADF81C10B0F5007F03D9072043
+:10CE50008DF8180085E140F47C4222840CA8B8F1DA
+:10CE6000000F00D00023CDE90330CDE9018C1D98DF
+:10CE700000903888401E83B21B9800F095FF8DF813
+:10CE8000180028B18328A8D10220BDE0540000205A
+:10CE90000D2189F80010BDF83000401C1EE1032E62
+:10CEA00004D248067FF537AE002017E1B5F801102F
+:10CEB000ADF81C102878400602D58DF83CE002E061
+:10CEC00007208DF83C004FF000080320CDE9020850
+:10CED0001E9BCDF810801D980193A6F1030B0090C6
+:10CEE0001FFA8BF342461B9800F034FD8DF81800B2
+:10CEF0008DF83C80297849060DD52088C00506D5D7
+:10CF0000208BBDF81C10884201D1C4F82480404613
+:10CF10008DF81880E2E0832801D14FF0020A4FF427
+:10CF20008070ADF85000BDF81C002083A4F820B03C
+:10CF30001E986062032060841321CCE0052EFFF46C
+:10CF4000EAADB5F80110ADF81C10A28F62B3A2F5DE
+:10CF50007F43FE3B28D008228DF83C204FF0000B89
+:10CF60000523CDE9023BDDF878C0CDF810B01D9A5D
+:10CF700080B2CDF804C040F400430092B5F803201D
+:10CF80001B9800F0E7FC8DF83CB04FF400718DF871
+:10CF90001800ADF85010832810D0F8B1A18FA1F57A
+:10CFA0007F40FE3807D0DCE00B228DF83C204FF6A6
+:10CFB000FE72A287D2E7A4F83CB0D2E000942B46E0
+:10CFC00031461E9A1B98FFF780FB8DF8180008B1B8
+:10CFD00083284BD1BDF81C00208355E700942B46D5
+:10CFE00031461E9A1B98FFF770FB8DF81800E8BBBE
+:10CFF000E18FA06B0844811D8DE8820343888288FD
+:10D0000001881B98FFF763FC824668E095F8018071
+:10D01000022E70D15FEA080002D0B8F1010F6AD188
+:10D0200009208DF83C0007A800908DF84080434609
+:10D03000002221461B98FFF72CFC8DF842004FF090
+:10D04000000B8DF843B050B9B8F1010F12D0B8F110
+:10D05000000F04D1A18FA1F57F40FF380AD0A08F27
+:10D0600040B18DF83CB04FF4806000E037E0ADF89F
+:10D0700050000DE00FA91B98FAF767F882468DF86B
+:10D080003CB04FF48060ADF85000BAF1020F06D00A
+:10D09000FC480068C07928B18DF8180027E0A4F892
+:10D0A000188044E0BAF1000F03D081208DF81800F9
+:10D0B0003DE007A800904346012221461B98FFF758
+:10D0C000E8FB8DF8180021461B98FFF7CAFB9DF876
+:10D0D000180020B9192189F80010012038809DF826
+:10D0E0003C0020B10FA91B98FAF72FF88246BAF13D
+:10D0F000000F33D01BE018E08DF818E031E0207805
+:10D10000000712D5012E10D10A208DF83C00E088CE
+:10D11000ADF8400003201B9907F0B4F80820ADF8E3
+:10D120005000C1E648067FF5F6AC4FF0040A2088AF
+:10D13000BDF8501008432080BDF8500080050BD585
+:10D14000A18FA1F57F40FE3806D11E98E062289895
+:10D150002063A6864FF0030A5046A1E49DF818000C
+:10D1600078B1012089F80000297889F80110BDF80C
+:10D170001C10A9F802109DF8181089F80410052059
+:10D1800038802088BDF8501088432080E4E72DE9DE
+:10D19000FF4F8846087895B0012181404FF2090081
+:10D1A000249C0140ADF820102088DDF88890A0F57F
+:10D1B0007F424FF0000AFF3A06D039B1000705D58B
+:10D1C000012019B0BDE8F08F0820FAE7239E4FF048
+:10D1D000000B0EA886F800B018995D460988ADF8D6
+:10D1E0003410A8498DF81CB0179A0A718DF838B020
+:10D1F000086098F8000001283BD0022809D00328D5
+:10D200006FD1307820F03F001D303070B8F8040046
+:10D21000E08098F800100320022904D1317821F031
+:10D220003F011B31317094F84610090759D505AB01
+:10D23000B9F1000F13D0002102AA82E80B000720E9
+:10D24000CDE90009BDF83400B8F80410C01E83B25F
+:10D250000022159800F0A8FD0028D1D101E0F11CB2
+:10D26000EAE7B8F80400A6F80100BDF81400C01CF5
+:10D2700004E198F805108DF81C1098F804000128B6
+:10D2800006D04FF4007A02282CD00328B8D16CE1E4
+:10D290002188B8F8080011F40061ADF8201020D002
+:10D2A00017281CD3B4F84010814218D3B4F84410A6
+:10D2B000172901D3814212D1317821F03F01C91CD5
+:10D2C0003170A6F801000321ADF83410A4F8440031
+:10D2D00094F8460020F0020084F8460065E1052538
+:10D2E0007EE177E1208808F1080700F4FE60ADF8E0
+:10D2F000200010F0F00F1BD010F0C00F03D03888C2
+:10D30000228B9042EBD199B9B878C00710D0B96898
+:10D310000720CDE902B1CDF804B00090CDF810B0EF
+:10D32000FB88BA883988159800F014FB0028D6D1FC
+:10D330002398BDF82010401C80294ED006DC10290F
+:10D340000DD020290BD0402987D124E0B1F5807F72
+:10D350006ED051457ED0B1F5806F97D1DEE0C80622
+:10D3600001D5082000E0102082460DA907AA05205B
+:10D37000CDE902218DF83800ADF83CB0CDE9049636
+:10D3800008A93888CDE9000153460722214615989F
+:10D39000FFF7B4F8A8E09DF81C2001214FF00A0A1D
+:10D3A000002A9BD105ABB9F1000F00D00020CDE9D8
+:10D3B00002100720CDE90009BDF834000493401E97
+:10D3C00083B2218B0022159800F0EEFC8DF81C0032
+:10D3D0000B203070BDF8140020E09DF81C200121C6
+:10D3E0004FF00C0A002A22D113ABB9F1000F00D084
+:10D3F0000020CDE902100720CDE900090493BDF813
+:10D400003400228C401E83B2218B159800F0CCFC96
+:10D410008DF81C000D203070BDF84C00401CADF89C
+:10D42000340005208DF83800208BADF83C00BCE0BE
+:10D430003888218B88427FF452AF9DF81C004FF052
+:10D44000120A00281CD1606AA8B1B878C0073FF45E
+:10D4500046AF00E018E0BA680720CDE902B2CDF887
+:10D4600004B00090CDF810B0FB88BA88159800F091
+:10D4700071FA8DF81C00132030700120ADF83400D3
+:10D4800093E00000540000203988208B8142D2D1E3
+:10D490009DF81C004FF0160A0028A06B08D0E0B3DE
+:10D4A0004FF6FF7000215F46ADF808B0019027E00D
+:10D4B00068B1B978C907BED1E18F0DAB0844821DB0
+:10D4C00003968DE80C0243888288018809E0B878C9
+:10D4D000C007BCD0BA680DAB03968DE80C02BB88C0
+:10D4E000FA881598FFF7F3F905005ED0072D72D082
+:10D4F00076E0019005AA02A92046FFF729F9014626
+:10D50000E28FBDF80800824201D00029F1D0E08FFF
+:10D51000A16B084407800198E08746E09DF81C0055
+:10D520004FF0180A40B1208BC8B1388820832146BB
+:10D530001598FFF796F938E004F118000090237E63
+:10D54000012221461598FFF7A4F98DF81C00002848
+:10D55000EDD1192030700120ADF83400E7E7052542
+:10D5600021461598FFF77DF93AE0208800F4007015
+:10D57000ADF8200050452DD1A08FA0F57F41FE3998
+:10D5800001D006252CE0D8F808004FF0160A48B163
+:10D59000A063B8F80C10A1874FF6FF71E187A0F8DF
+:10D5A00000B002E04FF6FF70A087BDF8200030F415
+:10D5B0007F611AD0782300220320159906F0B8FD68
+:10D5C00098F8000020712088BDF8201008432080C2
+:10D5D0000EE000E007252088BDF820108843208059
+:10D5E000208810F47F6F1CD03AE02188814321808D
+:10D5F0009DF8380020B10EA91598F9F7A6FD05464B
+:10D600009DF81C000028EBD086F801A001203070A6
+:10D61000208B70809DF81C0030710520ADF834001F
+:10D62000DEE7A18EE1B118980DAB0088ADF83400AB
+:10D630002398CDE90304CDE90139206B0090E36A1A
+:10D64000179A1598FFF7FCF9054601208DF8380068
+:10D650000EA91598F9F779FD00B10546A4F834B084
+:10D6600094F8460040070AD52046FFF7A0F910F0CD
+:10D670003E0F04D114F8460F20F0040020701898D3
+:10D68000BDF83410018028469BE500B585B003281D
+:10D6900006D102208DF8000088B26946F9F755FDE1
+:10D6A00005B000BD10B5384C0B782268012B02D0B4
+:10D6B000022B2AD111E013780BB1052B01D10423E1
+:10D6C000137023688A889A802268CB88D380226866
+:10D6D0000B891381498951810DE08B8893802268E1
+:10D6E000CB88D38022680B8913814B8953818B8926
+:10D6F0009381096911612168F9F727FD22680021EA
+:10D700000228117003D0002800D0812010BD832092
+:10D7100010BD806B002800D001207047817801295E
+:10D7200009D10088B0F5205F03D042F6010188429C
+:10D7300001D10020704707207047F0B587B0002462
+:10D7400015460E460746ADF8144010E006980188CD
+:10D750002980811DCDE902410721019404940091A3
+:10D76000838842880188384600F0F4F830B906AA68
+:10D7700005A93046FEF7ECFF0028E7D00A2800D1C3
+:10D78000002007B0F0BD00005400002010B58B78D9
+:10D7900083B102789A4205D10B885BB102E08B79A4
+:10D7A000091D4BB18B789A42F9D1B0F801300C8841
+:10D7B000A342F4D1002010BD812010BD072826D03F
+:10D7C00012B1012A27D103E0497801F0070102E0F4
+:10D7D0004978C1F3C20105291DD2DFE801F0031821
+:10D7E000080C12000AB10320704702207047042879
+:10D7F0000DD250B10DE0052809D2801E022808D3B1
+:10D8000003E0062803D0032803D00520704700203A
+:10D8100070470F20704781207047C0B282060BD43A
+:10D82000000607D5FE48807A4143C01D01EBD000B9
+:10D8300080B27047084670470020704770B5138863
+:10D840000B800B781C0625D5F54CA47A844204D8AD
+:10D8500043F010000870002070BD956800F00706C6
+:10D8600005EBD0052D78F54065F304130B701378A4
+:10D87000D17803F0030341EA032140F20123B1FB15
+:10D88000F3F503FB15119268E41D00FB012000EB8A
+:10D89000D40070BD906870BD37B51446BDF8041053
+:10D8A00011809DF804100A061ED5C1F30013DC494F
+:10D8B000A568897A814208D8FE2811D1C91DC908F6
+:10D8C0005A42284616F0EBFC0AE005EBD00100F0C6
+:10D8D0000702012508789540A84393401843087033
+:10D8E000207820F0100020703EBD2DE9F041074661
+:10D8F000C81C0E4620F00300B04202D08620BDE8CE
+:10D90000F081C74D002034462E60AF802881AA7276
+:10D91000E8801AE0E988491CE980810614D4E1789E
+:10D9200000F0030041EA002040F20121B0FBF1F2D7
+:10D9300001FB12012068FFF770FF2989084480B2BB
+:10D940002881381A3044A0600C3420784107E1D493
+:10D950000020D4E72DE9FF4F89B01646DDE9168A8D
+:10D960000F46994623F44045084600F00DFB04009D
+:10D970000FD0099802F0E2FF0290207800060AD545
+:10D98000A748817A0298814205D887200DB0BDE86A
+:10D99000F08F0120FAE7224601A90298FFF74EFF17
+:10D9A000834600208DF80C004046B8F1070F1AD0CE
+:10D9B00001222146FFF702FF0028E7D12078400628
+:10D9C00011D502208DF80C00ADF81070BDF80400E0
+:10D9D000ADF81200ADF814601898ADF81650CDF8F7
+:10D9E0001CA0ADF818005FEA094004D500252E46BA
+:10D9F000A84601270CE02178E07801F0030140EA15
+:10DA0000012040F20121B0FBF1F2804601FB1287B8
+:10DA10005FEA494009D5B84507D1A178207901F0DE
+:10DA2000030140EA0120B04201D3BE4201D90720E0
+:10DA3000ACE7A8191FFA80F9B94501D90D20A5E76F
+:10DA40009DF80C0028B103A90998F9F77CFB002880
+:10DA50009CD1B84507D1A0784FEA192161F30100A4
+:10DA6000A07084F804901A9800B10580199850EAC3
+:10DA70000A0027D0199830B10BEB06002A461999F5
+:10DA800016F096FB0EE00BEB06085746189E099819
+:10DA900003F0C0F82B46F61DB5B239464246009554
+:10DAA00002F0ABFC224601A90298FFF7C7FE9DF8E1
+:10DAB0000400224620F010008DF80400DDE901107A
+:10DAC000FFF7EAFE002061E72DE9FF4FDFF85091F4
+:10DAD00082461746B9F80610D9F8000001EB41015B
+:10DAE00000EB810440F20120B2FBF0F185B000FBB5
+:10DAF00011764D46DDF84C8031460698FFF78DFED5
+:10DB000029682A898B46611A0C3101441144AB887B
+:10DB100089B28B4202D8842009B038E70699CDB289
+:10DB2000290603D5A90601D50620F5E7B9F806C0F0
+:10DB30000CF1010C1FFA8CFCA9F806C0149909B16C
+:10DB4000A1F800C0A90602D5C4F8088007E0104477
+:10DB500080B2A9F80800191A01EB0B00A060224658
+:10DB6000FE200699FFF798FEE77026712078390AA3
+:10DB700061F30100320AA17840F0040062F3010170
+:10DB8000A17020709AF802006071BAF80000E0807D
+:10DB900000262673280602D599F80A7000E00127AE
+:10DBA000A80601D54FF000084D4600244FF00709A4
+:10DBB0000FE0CDE902680196CDF800900496E9885F
+:10DBC0002046129B089AFFF7C5FE0028A4D1641CCA
+:10DBD000E4B2BC42EDD300209EE72DE9F047804639
+:10DBE00000F0D2F9070005D0002644460C4D40F263
+:10DBF000012919E00120BDE8F087204600F0C4F9B2
+:10DC00000278C17802F0030241EA0222B2FBF9F382
+:10DC100009FB13210068FFF700FE304486B201E0E3
+:10DC2000E8050020641CA4B2E988601E8142E4DC9F
+:10DC3000A8F10100E8802889801B28810020387025
+:10DC4000D9E710B5144631B1491E218002F076FEA5
+:10DC5000A070002010BD012010BD10B5D2490446AF
+:10DC60000088CA88904201D30A2010BD096800EBE1
+:10DC7000400001EB80025079A072D0882081917819
+:10DC8000107901F0030140EA0120A081A078E11C95
+:10DC9000FFF7D4FD20612088401C2080E080002018
+:10DCA00010BD0121018270472DE9FF4F85B04FF66D
+:10DCB000FF788246A3F8008048681F460D468078AA
+:10DCC0008DF8060048680088ADF8040000208DF843
+:10DCD0000A00088A0C88A04200D304462C8241E046
+:10DCE000288A401C2882701D6968FFF74FFDB8BB69
+:10DCF0003988414501D1601E38806888A04236D3FA
+:10DD0000B178307901F0030140EA012901A9701DC1
+:10DD1000FFF73CFD20BB298941452CD0002231462C
+:10DD20000798FFF74BFDD8B92989494518D1E9680B
+:10DD30000391B5F80AC0D6F808B05046CDF800C037
+:10DD400002F068FFDDF800C05A460CF1070C1FFA1C
+:10DD50008CFC4B460399CDF800C002F018FB50B183
+:10DD6000641CA4B2204600F00FF90600B8D1641E6E
+:10DD70002C820A20D0E67C807079B871F088B88057
+:10DD80003178F07801F0030140EA01207881A7F8AA
+:10DD90000C90504602F0D2FD324607F10801FFF721
+:10DDA0004DFD38610020B7E62DE9FF4F87B0814671
+:10DDB0001C469246DDF860B0DDF85480089800F00B
+:10DDC000E3F805000CD0484602F0B8FD29780906B2
+:10DDD00008D57549897A814204D887200BB0D6E5E9
+:10DDE0000120FBE7CAF309062A4601A9FFF726FD31
+:10DDF0000746149807281CD000222946FFF7DEFCAE
+:10DE00000028EBD12878400613D501208DF80800B2
+:10DE10000898ADF80C00BDF80400ADF80E00ADF8A0
+:10DE20001060ADF8124002A94846F9F78CF90028B5
+:10DE3000D4D12978E87801F0030140EA0121AA78D9
+:10DE4000287902F0030240EA0220564507D0B1F5D6
+:10DE5000007F04D9611E814201DD0B20BEE78642AE
+:10DE600001D90720BAE7801B85B2A54200D9254613
+:10DE7000BBF1000F01D0ABF80050179818B1B919D9
+:10DE80002A4616F095F9B8F1000F0DD03E444846E9
+:10DE90004446169F02F0D0FE2146FF1DBCB232461A
+:10DEA0002B46009402F0DDFA002097E72DE9F041BF
+:10DEB00007461D461646084600F066F804000BD0DB
+:10DEC000384602F03BFD2178090607D53649897AA4
+:10DED000814203D8872012E5012010E52246314611
+:10DEE000FFF7ACFC65B12178E07801F0030140EA6E
+:10DEF0000120B0F5007F01D8012000E0002028704B
+:10DF00000020FCE42DE9F04107461D461646084670
+:10DF100000F03AF804000BD0384602F00FFD2178EB
+:10DF2000090607D52049897A814203D88720E6E48B
+:10DF30000120E4E422463146FFF7AEFCFF2D14D069
+:10DF40002178E07801F0030240EA022040F2012249
+:10DF5000B0FBF2F302FB130015B900F2012080B20E
+:10DF6000E070000A60F3010121700020C7E410B5E1
+:10DF70000C4600F009F828B1C18821804079A070D2
+:10DF8000002010BD012010BD0749CA88824209D374
+:10DF900040B1096800EB40006FF00B0202EB80001B
+:10DFA0000844704700207047E805002070B503461C
+:10DFB000002002466FF02F050EE09C5CA4F13006B5
+:10DFC0000A2E02D34FF0FF3070BD00EB800005EB4E
+:10DFD0004000521C2044D2B28A42EED370BD30B50C
+:10DFE0000A240AE0B0FBF4F304FB13008D18303070
+:10DFF00005F8010C521E1846D2B2002AF2D130BDEB
+:10E0000030B500234FF6FF7510E0040A44EA002003
+:10E0100084B2C85C6040C0F30314604005EA003479
+:10E020004440E0B25B1C84EA40109BB29342ECD3C4
+:10E0300030BD000010B582B0694601F0D1FD002866
+:10E0400018BFFFDF9DF80000002448B1019890F848
+:10E05000DD0028B1019880F8DD4001980AF0AFF9A1
+:10E06000F8488068A0F8D24002B010BD2DE9F04712
+:10E0700004460D46062002F043FC0646072002F047
+:10E080003FFC304400F0FF08002718EB050618BFDE
+:10E090004FF000091DD02088401C80B22080B04283
+:10E0A00028BFA4F800902588454501D3B54209D37F
+:10E0B0000621284602F07CFC20B90721284602F000
+:10E0C00077FC10B10020BDE8F087781CC7B2BE42D3
+:10E0D000E1D84FF6FF7020801220BDE8F08770B5C0
+:10E0E00082B007F073FB0DF0AFF9D74C4FF6FF7617
+:10E0F00000256683A683D5A12570D1E90001CDE96D
+:10E10000000165706946A01C16F008FAA11C601C8D
+:10E1100014F04CF825721B2060814FF4A471A1818A
+:10E12000E08121820321A1740422E274A082E082B2
+:10E13000A4F13E00218305704680C6480570A4F115
+:10E1400010000570468002B070BDF8B5BD4D174691
+:10E150000E466860297007F0B3FA4FF6FF70ADF80D
+:10E16000000000216846FFF781FFA0B90621BDF835
+:10E17000000002F02FFC04460721BDF8000002F069
+:10E1800029FC002C1CBF0028FFDF00216846FFF798
+:10E190006DFF0028EAD0FFF7A2FF287812F07CF884
+:10E1A0000FF0A0FC2978686813F013FF28780CF0B2
+:10E1B000ABFB30460AF00FF807F020FC29786868BE
+:10E1C0000BF048FA3946287814F0ADFDBDE8F84068
+:10E1D0000DF03AB910B50124002A1CBF002010BD73
+:10E1E000002908BF022105D0012918BF002401D051
+:10E1F000204610BD0EF088FEFAE72DE9F04F8BB0F7
+:10E20000040008BFFFDF02218F4E06F11C00FFF75C
+:10E210002DFF002818BFFFDFB6F81CA0062002F073
+:10E220006FFB0546072002F06BFB284400F0FF0857
+:10E2300008F1010000F0FF094FF0000BB78B4745D4
+:10E2400025D120460FF022F8002840F0CE8030780B
+:10E25000002800F0CE8084F801B014202070C4F8AB
+:10E2600004B0C4F808B0C4F80CB0C4F810B0C4F8D6
+:10E2700014B0C4F818B0C4F81CB00220C4F820B020
+:10E28000207186F800B00BB00120BDE8F08F4F453B
+:10E2900020D1204607F04CFB00287DD007F02AFF54
+:10E2A000002859D02078172856D12079002853D03B
+:10E2B000E088072102F07CFB050008BFFFDF28880B
+:10E2C00007F017FAE088072102F084FB002818BF46
+:10E2D000FFDF8AE004A9384601F082FC00285BD108
+:10E2E0009DF8100048B107F07EFBB84254D021469B
+:10E2F00038460BF0B8F880B377E00FF05AF8B84220
+:10E3000077D02146384613F085FD00286DD1059859
+:10E3100000F1580590F8D00018B9E87E08B1012046
+:10E3200000E00020079095F8370000281CBF95F802
+:10E33000380010F0020F1CD084F801B001202070CA
+:10E3400084F804B0E78095F839002072688F608106
+:10E35000A88FA08185F837B047E0FFE7059800F166
+:10E36000580590F80C010028DBD1E87E0028D8D0B1
+:10E37000D5E7384602F060FC0290002808BFFFDFB6
+:10E38000029801F06FFE50B184F801B00F212170A6
+:10E39000E7802081012000E02BE0207125E0384655
+:10E3A00002F038FC0290002808BFFFDF079800B396
+:10E3B000029801F0AEFEE0B19DF8100038B9059862
+:10E3C000D0F8F8004188B94208BF80F800B038465C
+:10E3D00007F08FF984F801B00C20207084F804B0A5
+:10E3E000E780287F207285F81BB00BB00120BDE8C4
+:10E3F000F08F022106F11C00FFF738FE18B9B08B30
+:10E4000050457FF41BAF0BB02046BDE8F04F14F031
+:10E41000D0BC10B512F08AFC042803D012F086FCA0
+:10E42000052802D10FF078FD28B90AF0A9F920B12A
+:10E4300007F08AFC08B10C2010BD0DF051F8002047
+:10E4400010BD00005C00002032060020FFFFFFFF2F
+:10E450001F0000006800002010B504460078002866
+:10E460001EBF0128122010BD12F060FC042806D047
+:10E4700012F05CFC052802D00AF082F928B10DF0F8
+:10E480007EF900281CBF0C2010BD2078002816BF84
+:10E4900002280020012004F11703E21D611CBDE8E1
+:10E4A00010400DF075B810B50446007800281EBF66
+:10E4B0000128122010BD12F039FC042803D012F0FC
+:10E4C00035FC052802D10FF027FD28B90AF058F9CC
+:10E4D00020B107F039FC08B10C2010BD20780028CD
+:10E4E00016BF022800200120611C0CF0BFFF00288D
+:10E4F00014BF0020072010BD10B50DF043F900280F
+:10E5000014BF0020302010BD10B5044612F00EFCE0
+:10E51000042806D012F00AFC052802D00AF030F9CF
+:10E5200008B10C2010BD20460DF026F9002010BDCA
+:10E5300010B512F0FBFB042806D012F0F7FB0528FB
+:10E5400002D00AF01DF928B10DF019F900281CBFFE
+:10E550000C2010BD0DF075F8002010BDFF2181705A
+:10E560004FF6FF718180FE4949680A7882718A8876
+:10E57000028149884181012141700020704710B516
+:10E58000002482B012F1080F16D00CDC12F1280F13
+:10E5900018BF12F1140F0FD012F1100F18BF12F1A3
+:10E5A0000C0F09D00EE012F1040F18BF002A03D09F
+:10E5B000032A18BF042A05D1012807D0022809D050
+:10E5C00003280BD0122402B0204610BD104607F0DD
+:10E5D0008CFDF8E710460FF03AFAF4E708461446C7
+:10E5E000694601F0FDFA002818BF0224EBD19DF81E
+:10E5F0000000019880F857400024E4E710B5134666
+:10E6000001220DF0A6FF002010BD10B5044612F047
+:10E610008DFB052804BF0C2010BD204611F02AFEFA
+:10E62000002010BD10B5044612F080FB042806D06F
+:10E6300012F07CFB052802D00AF0A2F808B10C20E9
+:10E6400010BD2146002007F0C2F8002010BD10B513
+:10E65000044611F0B9FE50B10AF085F838B12078BF
+:10E6600009F0DDFD20780FF090FC002010BD0C209B
+:10E6700010BD10B5044612F059FB042806D012F064
+:10E6800055FB052802D00AF07BF808B10C2010BD1C
+:10E690002146012007F09BF8002010BD38B5044644
+:10E6A0004FF6FF70ADF80000A079E179884213D0F1
+:10E6B00021791F299CBF61791F290DD8002211469D
+:10E6C00014F030FF40B90022E079114614F02AFF1F
+:10E6D00010B9207A072801D9122038BD0AF050F865
+:10E6E00060B912F023FB48B900216846FFF7BEFC71
+:10E6F00020B1204606F031F8002038BD0C2038BD8E
+:10E7000070B504468078002582B01A2825D00EDC2A
+:10E71000162844D2DFE800F04343434343214343F8
+:10E7200043434343434343434343432121212A2853
+:10E7300035D00BDCA0F11E000C2830D2DFE800F051
+:10E740002F2F2F2F2F2F2F2F2F2F2F0D3A38042819
+:10E7500025D2DFE800F0240224022088B0F5706F93
+:10E760001DD20126694601F03BFA00281EBF022097
+:10E7700002B070BD9DF80000002801980BBF00F1A9
+:10E78000F40100F5B87100F1F50300F271130246CF
+:10E7900012D192F8D00092F8732052B903E002B07F
+:10E7A0004FF0120070BD002818BF042801D008786F
+:10E7B00068B102B00C2070BD92F80C0192F8732081
+:10E7C000002AF6D1002818BF0428F0D1F1E70E7016
+:10E7D000A07818709DF8000048B1019890F8DD000D
+:10E7E00028B1019880F8DD50019809F0E8FD02B0E9
+:10E7F000002070BDF0B583B00C46694601F0F0F919
+:10E8000028B1204615F074FE03B00220F0BD019837
+:10E81000002700F1580500F1080600BF85F8407098
+:10E820003146204615F07AFE95F840000028F5D1D3
+:10E8300003B0F0BD2DE9F0410D4604460189808802
+:10E8400000230DF0BCFF696A814228BFBDE8F0815A
+:10E85000401A401C4108A0884FF0000C401A80B2BA
+:10E86000A08022896FF00E07511A8AB2228195F892
+:10E870005460618816F00C0F6FF00D0328D0B0F5CE
+:10E88000747F38BF604606D35038C61700EB9660D9
+:10E8900003EBA01080B2814238BF0846608095F833
+:10E8A0005510E08811F00C0F1BD0B2F5747F09D31E
+:10E8B000A2F15001CA1701EB926103EBA11100BF55
+:10E8C0001FFA81FC604528BF6046E080BDE8F0810A
+:10E8D000022E1ABF03EBD00080B207EB9000DAD112
+:10E8E000D8E702291ABF03EBD2011FFA81FC07EB1C
+:10E8F0009201E7D1E4E7F0B587B00C46054604A9DC
+:10E9000001F06EF900281CBF07B0F0BD9DF81000A3
+:10E91000002814BF002201220599B1F84A30FB2BD0
+:10E9200028BFFB23B1F84CC0BCF1FB0F28BF4FF050
+:10E93000FB0C0C4FD7E90006BF68009001960297C8
+:10E94000ADF80230ADF806C06846FFF773FF65808A
+:10E95000BDF80400E080BDF80800608104E000001C
+:10E960005C00002040470200BDF80200A080BDF816
+:10E970000600208107B00020F0BD2DE9F04F89B0DE
+:10E9800004460088694601F02BF95FEA00081CBFC5
+:10E9900009B0BDE8F08FB4F806C02289ACF11B01C4
+:10E9A0001220E12924BF09B0BDE8F08FB2F5A47FA1
+:10E9B0003CBF09B0BDE8F08F44F29025AA4284BF65
+:10E9C00009B0BDE8F08F00276388A188A3F11B067A
+:10E9D000E12E24BF09B0BDE8F08FB1F5A47F2EBFB2
+:10E9E0008D4209B0BDE8F08F1120BCF1FB0F99BF3B
+:10E9F00040F64806B24209B0BDE8F08FFB2B92BF4B
+:10EA0000B14209B0BDE8F08F208806A901F0E8F80E
+:10EA1000002818BFFFDF35D19DF8180000280CBF73
+:10EA2000012200220799B1F84A00FB2828BFFB20E9
+:10EA3000B1F84C30FB2B28BFFB23DFF858B7DBF8CD
+:10EA400000C0DBF804A0DBF808B0CDF808C0CDF8B2
+:10EA50000CA0CDF810B0ADF80A00ADF80E3002A849
+:10EA6000FFF7E8FEBDF80C0060F31F45BDF810008D
+:10EA700060F31F49BDF80A0060F30F05BDF80E00F2
+:10EA800060F30F0962881FFA89F1092091423CBFA7
+:10EA900009B0BDE8F08FA9B2E28891423CBF09B04D
+:10EAA000BDE8F08F4FEA1941A288238901EB154197
+:10EAB0001A4491423CBF09B0BDE8F08F9DF80000B8
+:10EAC0004FF001090028019808D000F5CD7580F8B5
+:10EAD0009B91019890F8DE0148B307E000F582753C
+:10EAE00080F80591019890F8280110B14FF03A088C
+:10EAF00018E0E08868806088E8802089A880A08885
+:10EB00002881012228460199FFF794FEA888B04287
+:10EB100028BF40F64800A8802889B0421DD228812D
+:10EB200085F800906F7009B04046BDE8F08FE0882E
+:10EB300068806088E8802089A880A08828810022D9
+:10EB400028460199FFF776FEA888B04228BF40F614
+:10EB50004800A8802889B042E1D340F64800DEE7AB
+:10EB60000BE710B5044612F0E1F8042806D012F0C5
+:10EB7000DDF8052802D009F003FE28B10CF0FFFDF6
+:10EB800000281CBF0C2010BD2078002816BF0228CA
+:10EB900000200120E279611C0CF075FF002814BFF1
+:10EBA0000020022010BD817831F0070207BFC27833
+:10EBB00032F007031220704711F0040F0EBF12F05D
+:10EBC000040F1120704701F023B810B504460178F6
+:10EBD000122084B0012918BF002904D002291EBFC9
+:10EBE000032904B010BD6178002918BF012904D0A1
+:10EBF00002291EBF032904B010BDE17B21B9A17811
+:10EC000001291CBF04B010BDA17831F005021CBF62
+:10EC100004B010BD11F0050F04BF04B010BD11F019
+:10EC2000040F1EBF112004B010BDE178E388628993
+:10EC300000291EBF012904B010BD042B2EBF042AD9
+:10EC400004B010BDA17B002904BF04B010BD07298A
+:10EC500084BF04B010BD12F069F8042837D012F058
+:10EC600065F8052833D0A0788DF80800A0788DF8D5
+:10EC7000000060788DF8040020788DF80300A07BF8
+:10EC80008DF80500E07B002818BF01208DF80600F4
+:10EC9000A07810F0010F10D0E078012808BF022002
+:10ECA00003D000280CBF012000208DF80100E0886F
+:10ECB000ADF80A006089ADF80C0002A811F091FBD4
+:10ECC000002804BF68460FF065F904B010BD04B019
+:10ECD0000C2010BD10B5044602781220012A0FD076
+:10ECE000002A18BF10BD012A26D012F01FF80528EF
+:10ECF00004D011F0F6F9002808BF10BD0C2010BD9B
+:10ED00006178002918BF012906D0022918BF10BD5B
+:10ED1000A188002908BF10BD6388002B1CBFA188F3
+:10ED20000029E0D003EB83035B0001EB8101B3EB2F
+:10ED3000012F28BF10BDD6E70FF01DF8002804BF33
+:10ED4000122010BD0FF02CF800200FF0D3F800288F
+:10ED500018BF10BD60780FF0B1F8002818BF10BDC3
+:10ED6000A1886088BDE8104011F064BB002100F06C
+:10ED7000B1BF017811F0010F02D0406813F0ECBF71
+:10ED800013F0B9BF2DE9F04F8FB00D460246AFF634
+:10ED90004411D1E90001CDE90B011146284600F0EC
+:10EDA00099FF00281CBF0FB0BDE8F08F11F0BEFF27
+:10EDB00004280CD011F0BAFF052808D0F64F387897
+:10EDC00028B90EF0F6FAA0F57F41FF3903D00FB055
+:10EDD0000C20BDE8F08FF1480890F1480990F14807
+:10EDE0000A9008AA06210DA801F0B0FD040002BF98
+:10EDF00009200FB0BDE8F08F03210DF052F9B98A58
+:10EE0000A4F84A10FA8AA4F84C20F87C0090BB7C45
+:10EE1000208801F088FE002818BFFFDF208806F058
+:10EE200067FC268804F10E094FF0000B4FF00A0A28
+:10EE30000421484604F04DFF48460DF001FB062032
+:10EE400001F05EFD80461CE005A9062001F039FDB9
+:10EE500005A801F014FD5FEA000B10D1BDF8180001
+:10EE6000B04206D00798042249460E3015F074F9D6
+:10EE700070B105A801F003FD5FEA000BEED0A8F128
+:10EE80000108B8F1000F07DDBBF1000FDCD007E08F
+:10EE900048460DF0DEFAF2E7BBF1000F08BFFFDFD6
+:10EEA000D9F800000CF07AFFBAF1010A01D000286D
+:10EEB000BED0BDA004F1120600680190032101A894
+:10EEC00004F0DEFE002001A90A5C3254401CC0B2EE
+:10EED0000328F9D3A88B6080688CA080288DE080FF
+:10EEE000687A10F0010F18BF01217CD0388B0A46D8
+:10EEF00011F009FB0146A062204611F030FB4FF0F3
+:10EF0000000884F85E8084F85F80A878002816BF27
+:10EF10000228002001206076D5F80300C4F81A000A
+:10EF2000B5F80700E0830BA904F1080015F0F6FA24
+:10EF30004FF0010984F80091B4F84C0004F5827692
+:10EF40004A46FB2828BFFB207989814238BF084602
+:10EF500094F855104FF4747A11F00C0F1CBF0AEBA3
+:10EF600080111FFA81FC72D0B989614538BF8C4687
+:10EF7000B4F84A10FB2928BFFB21FB898B4238BF1C
+:10EF8000194694F854B01BF00C0F1CBF0AEB811308
+:10EF90009BB265D03F8A9F4238BF3B461B2918BFB2
+:10EFA000B3F5A47F65D0F080A6F808C07180B38067
+:10EFB00021463046FFF73EFCB08840F648018842C3
+:10EFC00028BF40F64800B0803089884228BF40F60C
+:10EFD0004800308186F800908DF800800121684655
+:10EFE00004F04EFE00E02BE09DF8000000F0070169
+:10EFF000C0F3C1021144C0F3401008448DF8000072
+:10F00000401D207609283CBF08302076002120468C
+:10F010000DF047F868780EF0B9FEA9782878EA1C58
+:10F020000EF087FE002808BF122650D00EF0B8FE62
+:10F03000A9782878EA1C0EF01BFF06001FD046E0D6
+:10F0400010F0020F14BF022100214FE7FFE7022951
+:10F0500007BF81003C31C10070311FFA81FC83E79A
+:10F06000BBF1020F07BF8B003C33CB0070339BB268
+:10F0700090E71B2818BFBCF5A47F94D1ACE7012012
+:10F080000EF04CFE060022D1214603200EF028FF90
+:10F0900006001CD1687A8DF8000010F0010F05D031
+:10F0A0006889ADF80200288AADF80400684611F0BE
+:10F0B00098F9064695F83A00002818BF01200EF08E
+:10F0C00033FE26B9204611F026F9060009D0208823
+:10F0D00006F00FFB2088062101F07CFC002818BFF9
+:10F0E000FFDF30460FB0BDE8F08F0146002049E653
+:10F0F00038B5294C207870B911F018FE052805D0D4
+:10F100000EF057F9A0F57F41FF3904D0684611F0A1
+:10F11000CCF910B113E00C2038BD0098008806F03F
+:10F12000E8FA00980621008801F054FC002818BF76
+:10F13000FFDF012020701D480078FCF727FE00202B
+:10F1400038BD70B4B0F802C08188C3880289448990
+:10F150008089ACF1060640F67B45AE423CBF8E1F6F
+:10F16000AE4214D28C4598BFB3F5FA7F3EBFA2F1F0
+:10F170000A0C0F4D15EB0C0509D25B1C5943B1EB82
+:10F18000820F04DA84429EBF002070BC704730209A
+:10F1900070BC70474047020032060020F405002092
+:10F1A0006800002022060020112233005C000020AD
+:10F1B00089F3FFFF2DE9F047B0F802C004468188CB
+:10F1C000C388028947898689ACF1060940F67B48E5
+:10F1D00030200025C1453ABFA1F10609C145BDE86F
+:10F1E000F0878C4598BFB3F5FA7F3DBFA2F10A0CBA
+:10F1F000DFF8B48418EB0C08BDE8F0875B1C5943BA
+:10F20000B1EB820FA8BFBDE8F087B74288BFBDE869
+:10F21000F0872088062101F0CBFB68B190F8D01070
+:10F2200090F8732042B9002918BF042904D0D0F8FF
+:10F23000F8100A781AB106E00220BDE8F087D0F88D
+:10F240004421127812B13A20BDE8F08705228A7174
+:10F25000D0F8F8100D81D0F8F820A1885181D0F8AD
+:10F26000F820E1889181D0F8F8202189D181D0F867
+:10F27000F8100A894B899A429EBF8A79082A9A42D5
+:10F2800024BF1220BDE8F08722884A80D0F8F80019
+:10F29000022101700020BDE8F087F0B583B005467B
+:10F2A0000DF0F2F8002802BF122003B0F0BD0026D6
+:10F2B000FE4F012429467C70B81C15F02FF97E7092
+:10F2C0006946062001F0FDFA002818BFFFDF6846F6
+:10F2D00001F0D5FA002808BFBDF804500AD1029801
+:10F2E00080F80041684601F0CAFA18B9BDF8040078
+:10F2F000A842F4D103B00020F0BD10B50446008848
+:10F30000062101F055FB68B190F8D01090F87320F9
+:10F3100042B9002918BF042904D0D0F8F8100A789F
+:10F3200012B105E0022010BDD0F8442112780AB1D4
+:10F330003A2010BD90F8962012F0010F04BF0C2067
+:10F3400010BDD4F80220D4F806304A608B60D0F8A3
+:10F35000F81062898A81D0F8F810E268C1F80E20AE
+:10F360002269C1F812206269C1F81620A269C1F8A9
+:10F370001A20D0F8F82003211170D0F8F800218865
+:10F380004180002010BDF8B515460E46044609F030
+:10F39000F7F900281CBF0C20F8BD20781223EF28B5
+:10F3A00073D86088ADF8000010F0100F4FF0000126
+:10F3B0000CD010F0010F00F002021BD0B2B110F01F
+:10F3C000080F08BF10F0040F1ED01AE010F0080F4D
+:10F3D0007ED110F0200F18BF10F0030F78D110F07D
+:10F3E000010F18BF10F0020F72D10DE010F0040FE2
+:10F3F0000AD106E02AB110F0080F08BF10F0040F80
+:10F4000002D010F00F0F63D1608810F0080F09D1FF
+:10F41000D4E901C2624528BFBCF1200F58D3B2F134
+:10F42000807F55D2227B002A52D0072A50D894F8E8
+:10F430000DC0BCF1000F18BFBCF1010F05D0BCF12D
+:10F44000020F18BFBCF1030F42D110F0040F05D119
+:10F45000BCF1020F18BFBCF1030F07D1A27B002A39
+:10F4600018BF012A34D110F0040F08D1627D002AA0
+:10F4700018BF012A03D0022A18BF032A28D1E27D2F
+:10F4800010F0100F02D0012A10D021E0012A18BF7D
+:10F49000032A1DD110F0100F08D1627E012A1CBF73
+:10F4A000022A032A14D1A27E0F2A11D8E27E002A52
+:10F4B00018BF012A0CD1E27D1123032A08D010F0D5
+:10F4C000100F04BF627E032A02D010F0400F01D05B
+:10F4D0001846F8BD3170A17555B9FF208DF80000B0
+:10F4E0006946002006F0EDFD6946002006F0D4FDD7
+:10F4F0002046BDE8F84006F004BD002243E72DE9B0
+:10F50000F0470446C0780F46122510B106F063FD9F
+:10F5100050B1607804280AD094F8038094F80090E1
+:10F520006678B8F1FB0F12D92846BDE8F08709F0DC
+:10F5300027F90028F8D006F0A6FD0028F4D106F03F
+:10F540009AFA002804BFE0780028EDD1E4E71FB163
+:10F55000B8F11F0F23D9E7E706F08DFA28B1B8F10B
+:10F560001F0F98BF032E07D0DEE7032E18BF042E0F
+:10F5700002D0B8F1000FD7D009F002F9002818BF67
+:10F58000032E04D0042E1CBF0C20BDE8F087484693
+:10F5900006F069FA002804BF4220BDE8F087E07851
+:10F5A00061781F2898BF03291CBF1120BDE8F08790
+:10F5B000211D06F086FD0020BDE8F08700219EE7B2
+:10F5C0002DE9F0470446C0788846122710B106F0AE
+:10F5D00098FD38B16578042D04D0E67894F8009051
+:10F5E000FB2E02D93846BDE8F087B8F1000F02D0F3
+:10F5F0001F2E21D9F6E706F03EFA20B11F2E98BF44
+:10F60000032D06D0EEE7032D18BF042D01D0002EE8
+:10F61000E8D009F0B5F8002818BF032D04D0042D58
+:10F620001CBF0C20BDE8F087484606F01CFA0028F5
+:10F6300004BF4220BDE8F087E07861781F2898BFBA
+:10F6400003291CBF1120BDE8F087211D06F024FD11
+:10F650000020BDE8F0870021B2E72DE9F041044623
+:10F660004078422582B0012808D8A07806F0FBF93E
+:10F6700020B120781225012804D0A0B102B028467C
+:10F68000BDE8F08106F04BFD20B1A0880028F5D040
+:10F690008028F3D806F050FD90B160780028EDD0B6
+:10F6A0002078012810D003E089F3FFFF3206002004
+:10F6B00007F0EAFE044608F0DBFC002800F0EA80D0
+:10F6C00002B00C20BDE8F08106F046FB38B906F028
+:10F6D0001FFD002802BF122002B0BDE8F08109F032
+:10F6E0004FF80028ECD106F07EF9A0F57F41FF39F4
+:10F6F000E6D106F050FBA08842F2107100FB01F643
+:10F70000A079314606F078FC06F0F4FC18B300222C
+:10F71000072101A801F01AF9040002BF092002B074
+:10F72000BDE8F081F6480321846020460CF072FBAE
+:10F73000204607F0EBF8F34DA88AA4F84A00E88ABF
+:10F74000A4F84C0006F097F968B1288B012108F065
+:10F7500013FEA0620FE03146002008F063FD002890
+:10F7600018BFFFDFA1E006F0E9FC2A8B0146104636
+:10F7700008F002FEA06201460022204607F087FE44
+:10F7800006F079F9002808BF06F0D8FCE87C009064
+:10F79000AB7CEA8AA98A208801F0C5F9002818BF45
+:10F7A000FFDF208805F0A4FF3146204608F03AFD2F
+:10F7B000002818BFFFDF2146B4F84C00002204F5F2
+:10F7C000CD76FB2828BFFB206B89834238BF1846C3
+:10F7D00091F855304FF4747413F00C0F1CBF04EB08
+:10F7E00080131FFA83FC38D0AF89674528BF67466E
+:10F7F000B1F84A30FB2B28BFFB23B5F80EC09C455F
+:10F8000038BF634691F854C01CF00C0F1CBF04EBCA
+:10F81000831C1FFA8CF829D02C8A444528BF444603
+:10F820001B2B18BFB4F5A47F2ED0F08037817380D6
+:10F83000B4803046FEF7FEFFB08840F648018842AB
+:10F8400028BF40F64800B0803089884228BF40F683
+:10F85000480030810120307027E0022B07BF830071
+:10F860003C33C30070331FFA83FCBDE7BCF1020FC9
+:10F8700007BF4FEA830C0CF13C0C4FEAC30C0CF1B0
+:10F88000700C1FFA8CF8C7E71B2818BFB7F5A47FC8
+:10F89000CBD10AE04CB1208805F02BFF208807214E
+:10F8A00001F098F8002818BFFFDF002002B0BDE883
+:10F8B000F0810021D1E610B50C46072101F078F85F
+:10F8C000002804BF022010BD90F8731109B10C206C
+:10F8D00010BD90F86510142912BF152990F8C011B9
+:10F8E0000029F4D12168C0F874116168C0F878115A
+:10F8F000A168C0F87C11E168C0F88011012180F88E
+:10F900007311002010BD10B5072101F051F8002837
+:10F9100004BF022010BD90F8731109B10C2010BD76
+:10F9200090F86510142918BF1529F7D1022180F825
+:10F930007311002010BDF0B50E464BF68032122137
+:10F9400083B0964217D8B6B1694600F049F900284D
+:10F950001CBF03B0F0BD019800F15807841C258836
+:10F960003246294638460CF00FFA2088A842F6D1D4
+:10F9700003B00020F0BD03B00846F0BD10B582B062
+:10F9800004460088694600F02BF900281CBF02B02D
+:10F9900010BD0198A37800F1580190F82C209A42EC
+:10F9A00002BF0C2002B010BD7F220A728A720022B0
+:10F9B000CA72E17880F82D10217980F82E10A17894
+:10F9C00080F82C1002B0104610BD10B582B00C4665
+:10F9D000694600F005F900281CBF02B010BD01986F
+:10F9E00090F87300002818BF0120207002B000209A
+:10F9F00010BD30B583B00D461446694600F0F0F8EE
+:10FA000000281CBF03B030BD019890F82C000128DD
+:10FA10001EBF0C2003B030BD019890F86010297013
+:10FA200090F86100207003B0002030BD70B50D4625
+:10FA30001646072100F0BCFF002804BF022070BD5D
+:10FA400083884FF0010CC28841880CEB430C65455C
+:10FA50001AD342F2107C02FB0CF240F6C41C01FBEC
+:10FA60000CF1B2FBF1F1491E8CB2B4F5FA7F88BFFC
+:10FA70004FF4FA74A54238BF2C46621C591CB2FBE5
+:10FA8000F1F25143491E8BB290F8AC11002908BF26
+:10FA900003843380002070BD10B50C46072100F0B0
+:10FAA00087FF002804BF022010BD80F8DF40002C33
+:10FAB0001EBF90F8DD10002908F081FC002010BD69
+:10FAC000017800291CBF417800290ED041881B29EC
+:10FAD00021BF81881B29C188022906D30A490268EF
+:10FAE00040680A654865002070471220704710B5CD
+:10FAF000044610F005FD204608F009FC002010BD6A
+:10FB00005C00002032060020F40500202DE9F041C1
+:10FB100016460F46044601221146384610F0F3FC03
+:10FB200005460121384608F027FC854228BF2846B3
+:10FB30000123E100503189B2E631884206D901F152
+:10FB40009602401AB0FBF2F0401C83B233800020D2
+:10FB5000BDE8F08110B5044611F0E8F8042806D09D
+:10FB600011F0E4F8052802D008F00AFE08B10C20D4
+:10FB700010BD601C0BF05DFF207800F0010006F066
+:10FB800005F9207800F001000EF005F9002010BD05
+:10FB900010B50446072000F0A5FE00281CBF0C206D
+:10FBA00010BD207810F0010F11D0002260781146AE
+:10FBB00013F0B8FC00281CBF122010BDA0680AF08A
+:10FBC00048FA607861680AF04DFA002010BD002004
+:10FBD0000AF03FFA002108460AF044FA002010BD5E
+:10FBE00070B50C460546062100F0E2FE606010B1DB
+:10FBF0000020207070BD0721284600F0D9FE60600B
+:10FC0000002804BF022070BD01202070002070BDBC
+:10FC100010B582B0044600886946FFF7E1FF020094
+:10FC20001CBF02B010BDA088002818BF012804D056
+:10FC300002281EBF122002B010BDA178002908BF03
+:10FC40000321E078002808BF03204FF0000C9DF846
+:10FC500000400123002C019C06D084F8A531019CB2
+:10FC600094F8F241ECB124E084F80F31019C94F84F
+:10FC700034413CB9019C94F80E411CB9019C94F8A4
+:10FC80007D400CB13A2208E0019C84F80E31019BC2
+:10FC900083F81011019981F81101019880F80FC1C2
+:10FCA00015E0019C94F8A4411CB9019C94F87D4096
+:10FCB0000CB13A2208E0019C84F8A431019B83F83E
+:10FCC000A611019981F8A701019880F8A5C102B099
+:10FCD000104610BD427A12F0070F10D032F0070321
+:10FCE0000DD112F0040F01D011207047012A18BF66
+:10FCF000022AF9D190F83A301BB9012A01D012201A
+:10FD000070472DE9F0074FF0000C12F0010F40F69C
+:10FD1000774740F67B4337D069B14489B0F810C0CB
+:10FD2000261F43F6FD75AE423CBFACF10406AE4261
+:10FD300026D2644524D3C68AB0F81CC0448C058DF5
+:10FD4000B0F82E90B0F83480A6F1060A9A453CBF70
+:10FD5000ACF1060A9A4513D2664598BFB4F5FA7F0E
+:10FD60003CBFA5F10A06BE420AD2641C04FB0CFC8F
+:10FD7000BCEB850F04DAC14598BF4FF0010C03D9E5
+:10FD8000BDE8F0073020704712F0020F22D000EBE0
+:10FD90004C02D68AB2F81CC0558C148DB2F82E8055
+:10FDA000928EA6F106094B4584BFACF106094B457E
+:10FDB000E6D9664598BFB5F5FA7F3CBFA4F10A03C2
+:10FDC000BB42DDD26B1C03FB0CF3B3EB840FD7DA21
+:10FDD0009045D5D802782AB1012A13D0BDE8F007A2
+:10FDE000122070470029817808D0002918BF012906
+:10FDF00008D0022918BF032904D0EFE7002918BF53
+:10FE00000129EBD14078002818BF012803D002282F
+:10FE100018BF0328E2D1BDE8F007002070470000BA
+:10FE200030B5058825F4004421448CB24FF40041DC
+:10FE300094420AD2121B92B21B339A4201D2A943B6
+:10FE400007E005F40041214303E0A21A92B2A9435E
+:10FE50001143018030BD0844083050434A31084402
+:10FE600080B2704770B51D4616460B4604462946BB
+:10FE70003046049AFFF7EFFF0646B34200D2FFDF99
+:10FE80002821204614F035FA4FF6FF70A082283E54
+:10FE9000B0B265776080B0F5004F00D9FFDF6188B0
+:10FEA00005F13C00814200D2FFDF60880835401B2D
+:10FEB000343880B220801B2800D21B2020800020F4
+:10FEC000A07770BD8161886170472DE9F05F0D46B4
+:10FED000C188044600F12809008921F4004620F475
+:10FEE000004800F062FB10B10020BDE8F09F4FF029
+:10FEF000000A4FF0010BB0450CD9617FA8EB06005A
+:10FF0000401A0838854219DC09EB060000210580FB
+:10FF100041801AE06088617F801B471A083F0DD43A
+:10FF20001B2F00DAFFDFBD4201DC294600E0B9B239
+:10FF3000681A0204120C04D0424502DD84F817A0AE
+:10FF4000D2E709EB06000180428084F817B0CCE7C5
+:10FF500070B5044600F12802C088E37D20F400401B
+:10FF60002BB110440288438813448B4201D20020F5
+:10FF700070BD00258A4202D30180458008E0891ABD
+:10FF80000904090C418003D0A01D00F01EFB08E00D
+:10FF9000637F00880833184481B26288A01DFFF790
+:10FFA0003FFFE575012070BD70B5034600F12804E0
+:10FFB000C588808820F400462644A84202D100204B
+:10FFC000188270BD98893588A84206D3401B758871
+:10FFD0002D1A2044ADB2C01E05E02C1AA5B25C7FDC
+:10FFE00020443044401D0C88AC4200D90D809C89CF
+:10FFF00024B1002414700988198270BD0124F9E726
+:020000040001F9
+:1000000070B5044600F12801808820F400404518AE
+:10001000208A002825D0A189084480B2A08129889F
+:100020006A881144814200D2FFDF2888698800264F
+:100030000844A189884212D1A069807F287169880B
+:1000400019B1201D00F0C1FA08E0637F2888083349
+:10005000184481B26288201DFFF7E2FEA681268245
+:10006000012070BD2DE9F0414189878800260446B2
+:1000700000F12805B94218D004F10A0821F4004023
+:100080002844418819B1404600F09FFA08E0637F98
+:1000900000880833184481B262884046FFF7C0FEEA
+:1000A000761C6189B6B2B942E8D13046BDE8F0812C
+:1000B0002DE9F04104460B4627892830A68827F40D
+:1000C0000041B4F80A8001440D46B74201D1002036
+:1000D000ECE70AB1481D106023B1627F691D184624
+:1000E00014F066F82E88698804F1080021B18A1995
+:1000F00096B200F06AFA06E0637F628808339919C5
+:1001000089B2FFF78DFE474501D1208960813046D5
+:10011000CCE78188C088814201D10120704700204E
+:10012000704701898088814201D1012070470020F9
+:10013000704770B58588C38800F1280425F4004213
+:1001400023F4004114449D421AD08389058A5E1924
+:1001500025886388EC18A64214D313B18B4211D3BF
+:100160000EE0437F08325C192244408892B2801A24
+:1001700080B22333984201D211B103E08A4201D107
+:10018000002070BD012070BD2DE9F0478846C18870
+:100190000446008921F4004604F1280720F40045B4
+:1001A00007EB060900F001FA002178BBB54204D93B
+:1001B000627FA81B801A002503E06088627F801B95
+:1001C000801A083823D4E28962B1B9F80020B9F85E
+:1001D00002303BB1E81A2177404518DBE08938440A
+:1001E000801A09E0801A217740450ADB607FE189A7
+:1001F0000830304439440844C01EA4F81280BDE8D9
+:10020000F087454503DB01202077E7E7FFE76182C0
+:100210000020F4E72DE9F74F044600F12805C088D7
+:10022000884620F4004A608A05EB0A0608B140457A
+:1002300002D20020BDE8FE8FE08978B13788B6F899
+:10024000029007EB0901884200D0FFDF207F4FF0CA
+:10025000000B50EA090106D088B33BE00027A07FDD
+:10026000B9463071F2E7E18959B1607F294408301D
+:1002700050440844B4F81F1020F8031D94F82110CE
+:100280008170E28907EB080002EB0801E181308010
+:10029000A6F802B002985F4650B1637F30880833F9
+:1002A000184481B26288A01DFFF7BAFDE78121E002
+:1002B000607FE18908305044294408442DE0FFE77D
+:1002C000E089B4F81F102844C01B20F8031D94F8DF
+:1002D0002110817009EB0800E28981B202EB08006D
+:1002E000E081378071800298A0B1A01D00F06DF907
+:1002F000A4F80EB0A07F401CA077A07D08B1E088D4
+:10030000A08284F816B000BFA4F812B084F817B029
+:1003100001208FE7E0892844C01B30F8031DA4F8B2
+:100320001F10807884F82100EEE710B5818800F175
+:10033000280321F400442344848AC288A14212D0B5
+:10034000914210D0818971B9826972B11046FFF76C
+:10035000E8FE50B91089283220F400401044197981
+:100360000079884201D1002010BD184610BD00F16F
+:100370002803407F08300844C01E1060088808B970
+:10038000DB1E136008884988084480B270472DE955
+:10039000F04100F12806407F1C4608309046431883
+:1003A00008884D88069ADB1EA0B1C01C80B290421E
+:1003B00014D9801AA04200DB204687B298183A462A
+:1003C000414613F0C9FE002816D1E01B84B2B844A0
+:1003D000002005E0ED1CADB2F61EE8E7101A80B271
+:1003E0000119A94206D8304422464146BDE8F041F1
+:1003F00013F0B2BE4FF0FF3058E62DE9F04100F1A6
+:100400002804407F1E46083090464318002508887F
+:100410004F88069ADB1E90B1C01C80B2904212D960
+:10042000801AB04200DB304685B299182A46404611
+:1004300013F0BEFE701B86B2A844002005E0FF1C2E
+:10044000BFB2E41EEAE7101A80B28119B94206D899
+:1004500021183246404613F0ABFEA81985B2284653
+:1004600024E62DE9F04100F12804407F1E460830C3
+:1004700090464318002508884F88069ADB1E90B1E5
+:10048000C01C80B2904212D9801AB04200DB3046C4
+:1004900085B298182A46414613F08AFE701B86B230
+:1004A000A844002005E0FF1CBFB2E41EEAE7101AD2
+:1004B00080B28119B94206D820443246414613F031
+:1004C00077FEA81985B22846F0E5401D704710B5A3
+:1004D000044600F12801C288808820F400431944B2
+:1004E000904206D0A28922B9228A12B9A28A9042E9
+:1004F00001D1002010BD0888498831B1201D00F0CD
+:1005000064F800202082012010BD637F62880833D8
+:10051000184481B2201DFFF783FCF2E70021C1815E
+:1005200001774182C1758175704703881380C28944
+:1005300042B1C28822F4004300F128021A440A6042
+:10054000C08970470020704710B50446808AA0F526
+:100550007F41FF3900D0FFDFE088A082E08900B151
+:100560000120A07510BD4FF6FF71818200218175B9
+:10057000704710B50446808AA0F57F41FF3900D14D
+:10058000FFDFA07D28B9A088A18A884201D1002080
+:1005900010BD012010BD8188828A914201D1807DE9
+:1005A00008B1002070470120704720F4004221F478
+:1005B00000439A4207D100F4004001F40041884210
+:1005C00001D0012070470020704730B504460088F4
+:1005D0000D4620F40040A84200D2FFDF21884FF4EE
+:1005E000004088432843208030BD70B50C0005468C
+:1005F00009D0082C00D2FFDF1DB1A1B2286800F09D
+:1006000044F8201D70BD0DB100202860002070BD91
+:100610000021026803E093881268194489B2002A15
+:10062000F9D100F032B870B500260D46044608290D
+:1006300000D2FFDF206808B91EE0044620688188E8
+:10064000A94202D001680029F7D181880646A94253
+:1006500001D100680DE005F1080293B20022994231
+:1006600009D32844491B0260818021680968216000
+:100670000160206000E00026304670BD00230B6062
+:100680008A8002680A600160704700234360021D8F
+:10069000018102607047F0B50F4601884088154619
+:1006A0000C181E46AC4200D3641B3044A84200D94B
+:1006B000FFDFA019A84200D9FFDF3819F0BD2DE9EE
+:1006C000F041884606460188408815460C181F46AA
+:1006D000AC4200D3641B3844A84200D9FFDFE019C4
+:1006E000A84200D9FFDF70883844708008EB04000E
+:1006F000BDE8F0812DE9F041054600881E46174609
+:10070000841B8846BC4200D33C442C80688830441B
+:10071000B84200D9FFDFA019B84200D9FFDF6888CE
+:100720003044688008EB0400E2E72DE9F0410688D8
+:100730001D460446701980B2174688462080B8428C
+:1007400001D3C01B20806088A84200D2FFDF70194F
+:10075000B84200D9FFDF6088401B608008EB0600CC
+:10076000C6E730B50D460188CC18944200D3A41AD0
+:100770004088984200D8FFDF281930BD2DE9F041AC
+:10078000C84D04469046A8780E46A04200D8FFDF28
+:1007900005EB8607B86A50F8240000B1FFDFB8689F
+:1007A000002816D0304600F044F90146B868FFF73B
+:1007B0003AFF05000CD0B86A082E40F8245000D348
+:1007C000FFDFB9484246294650F826302046984770
+:1007D0002846BDE8F0812DE9F8431E468C19914664
+:1007E0000F460546FF2C00D9FFDFB14500D9FFDFDA
+:1007F000E4B200954DB300208046E81C20F00300D1
+:10080000A84200D0FFDF4946DFF89892684689F891
+:10081000001089F8017089F8024089F8034089F8CE
+:10082000044089F8054089F8066089F80770414658
+:1008300000F008F9002142460F464B460098C01CC4
+:1008400020F00300009012B10EE00120D4E703EB8A
+:100850008106B062002005E0D6F828C04CF8207070
+:10086000401CC0B2A042F7D30098491C00EB8400A2
+:10087000C9B200900829E1D3401BBDE8F88310B548
+:10088000044603F071FD08B1102010BD2078854AA0
+:10089000618802EB800092780EE0836A53F8213081
+:1008A00043B14A1C6280A180806A50F82100A06098
+:1008B000002010BD491C89B28A42EED86180052013
+:1008C00010BD70B505460C46084603F04DFD08B155
+:1008D000102070BD082D01D3072070BD25700020A9
+:1008E000608070BD0EB56946FFF7EBFF00B1FFDF1A
+:1008F0006846FFF7C4FF08B100200EBD01200EBD01
+:1009000010B50446082800D3FFDF6648005D10BD1F
+:100910003EB5054600246946FFF7D3FF18B1FFDF57
+:1009200001E0641CE4B26846FFF7A9FF0028F8D094
+:100930002846FFF7E5FF001BC0B23EBD5949897844
+:10094000814201D9C0B27047FF2070472DE9F041C4
+:10095000544B062903D007291CD19D7900E00025BE
+:1009600000244FF6FF7603EB810713F801C00AE07D
+:100970006319D7F828E09BB25EF823E0BEF1000FC0
+:1009800004D0641CA4B2A445F2D8334603801846B0
+:10099000B34201D100201CE7BDE8F041EEE6A0F52E
+:1009A0007F43FF3B01D0082901D300207047E5E6D3
+:1009B000A0F57F42FF3A0BD0082909D2394A937833
+:1009C000834205D902EB8101896A51F82000704702
+:1009D000002070472DE9F04104460D46A4F57F4103
+:1009E00043F20200FF3902D0082D01D30720F0E6C0
+:1009F0002C494FF000088A78A242F8D901EB85060D
+:100A0000B26A52F82470002FF1D0274839462030BE
+:100A100050F8252020469047B16A284641F82480A6
+:100A200000F007F802463946B068FFF727FE0020BD
+:100A3000CFE61D49403131F810004FF6FC71C01C63
+:100A4000084070472DE9F843164E884605460024B5
+:100A50002868C01C20F0030028602046FFF7E9FF4B
+:100A6000315D4843B8F1000F01D0002200E02A6850
+:100A70000146009232B100274FEA0D00FFF7B5FDA5
+:100A80001FB106E001270020F8E706EB8401009A79
+:100A90008A602968641C0844E4B22860082CD7D313
+:100AA000EBE60000500600204C47020070B50E46F1
+:100AB0001D46114600F0D4F804462946304600F0A1
+:100AC000D8F82044001D70BD2DE9F04190460D4638
+:100AD00004004FF0000610D00027E01C20F00300B7
+:100AE000A04200D0FFDFDDB141460020FFF77DFDD1
+:100AF0000C3000EB850617B112E00127EDE7614FDE
+:100B000004F10C00A9003C602572606000EB8500D8
+:100B10002060606813F0EDFB41463868FFF765FD23
+:100B20003046BDE8F0812DE9FF4F564C804681B03C
+:100B300020689A46934600B9FFDF2068027A424552
+:100B400003D9416851F8280020B143F2020005B0F2
+:100B5000BDE8F08F5146029800F082F886B2584600
+:100B60000E9900F086F885B27019001D87B22068D2
+:100B7000A14639460068FFF756FD04001FD0678084
+:100B800025802946201D0E9D07465A4601230095C3
+:100B9000FFF768F92088314638440123029ACDF8DE
+:100BA00000A0FFF75FF92088C1193846FFF78AF9DE
+:100BB000D9F800004168002041F82840C7E7042028
+:100BC000C5E770B52F4C0546206800B9FFDF2068E7
+:100BD000017AA9420ED9426852F8251051B100237A
+:100BE00042F825304A880068FFF748FD2168002058
+:100BF0000A7A08E043F2020070BD4B6853F82030D7
+:100C000033B9401CC0B28242F7D80868FFF700FD34
+:100C1000002070BD70B51B4E05460024306800B939
+:100C2000FFDF3068017AA94204D9406850F82500F6
+:100C300000B1041D204670BD70B5124E054600245B
+:100C4000306800B9FFDF3068017AA94206D94068F0
+:100C500050F8251011B131F8040B4418204670BD2E
+:100C600010B50A460121FFF7F6F8C01C20F003007A
+:100C700010BD10B50A460121FFF7EDF8C01C20F0A9
+:100C8000030010BD7000002070B50446C2F11005CD
+:100C9000281913F08DFA15F0FF0108D0491EC9B2CA
+:100CA000802060542046BDE8704013F000BB70BD4A
+:100CB00030B505E05B1EDBB2CC5CD55C6C40C45447
+:100CC000002BF7D130BD10B5002409E00B78521E7F
+:100CD00044EA430300F8013B11F8013BD2B2DC09BE
+:100CE000002AF3D110BD2DE9F04389B01E46DDE99D
+:100CF000107990460D00044622D002460846F94974
+:100D0000FDF77CFC102221463846FFF7DCFFE07B34
+:100D1000000606D5F34A3946102310320846FFF77D
+:100D2000C7FF102239464846FFF7CDFFF87B000683
+:100D300006D5EC4A4946102310320846FFF7B8FFA3
+:100D40001021204613F0B3FA0DE0103EB6B208EBC6
+:100D50000601102322466846FFF7AAFF22462846CE
+:100D60006946FDF74BFC102EEFD818D0F2B2414681
+:100D70006846FFF789FF10234A46694604A8FFF733
+:100D800097FF1023224604A96846FFF791FF2246E9
+:100D900028466946FDF732FC09B0BDE8F083102310
+:100DA0003A464146EAE770B59CB01E4605461346F2
+:100DB00020980C468DF80800202219460DF10900F4
+:100DC00013F0F6F9202221460DF1290013F0F0F975
+:100DD00017A913A8CDE90001412302AA31462846EC
+:100DE000FFF781FF1CB070BD2DE9FF4F9FB014AE1F
+:100DF000DDE92D5410AFBB49CDE900762023203129
+:100E00001AA8FFF770FF4FF000088DF808804FF028
+:100E100001098DF8099054F8010FCDF80A00A08857
+:100E2000ADF80E0014F8010C1022C0F340008DF84C
+:100E3000100055F8010FCDF81100A888ADF8150085
+:100E400015F8010C2C99C0F340008DF8170006A886
+:100E5000824613F0ADF90AA883461022229913F0B6
+:100E6000A7F9A0483523083802AA40688DF83C80CD
+:100E7000CDE900760E901AA91F98FFF734FF8DF880
+:100E800008808DF809902068CDF80A00A088ADF898
+:100E90000E0014F8010C1022C0F340008DF8100071
+:100EA0002868CDF81100A888ADF8150015F8010CD8
+:100EB0002C99C0F340008DF81700504613F078F9D4
+:100EC00058461022229913F073F9864835230838C2
+:100ED00002AA40688DF83C90CDE900760E901AA9E0
+:100EE0002098FFF700FF23B0BDE8F08FF0B59BB06E
+:100EF0000C460546DDE922101E461746DDE9203284
+:100F0000D0F801C0CDF808C0B0F805C0ADF80CC0ED
+:100F10000078C0F340008DF80E00D1F80100CDF844
+:100F20000F00B1F80500ADF8130008781946C0F3BA
+:100F300040008DF815001088ADF8160090788DF8F7
+:100F400018000DF11900102213F032F90DF12900EB
+:100F50001022314613F02CF90DF1390010223946D8
+:100F600013F026F917A913A8CDE90001412302AA1D
+:100F700021462846FFF7B7FE1BB0F0BDF0B5A3B081
+:100F800017460D4604461E46102202A8289913F063
+:100F90000FF906A82022394613F00AF90EA82022DC
+:100FA000294613F005F91EA91AA8CDE9000150231E
+:100FB00002AA314616A8FFF796FE1698206023B0C5
+:100FC000F0BDF0B589B00446DDE90E070D4639786D
+:100FD000109EC1F340018DF8001031789446C1F3A2
+:100FE00040018DF801101968CDF802109988ADF80C
+:100FF000061099798DF808100168CDF809108188DC
+:10100000ADF80D1080798DF80F0010236A46614607
+:1010100004A8FFF74DFE2246284604A9FDF7EEFA84
+:10102000D6F801000090B6F80500ADF80400D7F836
+:101030000100CDF80600B7F80500ADF80A00002061
+:10104000039010236A46214604A8FFF731FE22468A
+:10105000284604A9FDF7D2FA09B0F0BD1FB51C68F7
+:1010600000945B68019313680293526803920246EE
+:1010700008466946FDF7C2FA1FBD10B588B00446A0
+:10108000106804905068059000200690079008466C
+:101090006A4604A9FDF7B2FABDF80000208008B046
+:1010A00010BD1FB51288ADF800201A88ADF80220D7
+:1010B0000022019202920392024608466946FDF719
+:1010C0009DFA1FBD7FB5074B14460546083B9A1C89
+:1010D0006846FFF7E6FF224669462846FFF7CDFF40
+:1010E0007FBD0000A447020070B5044600780E469C
+:1010F000012813D0052802D0092813D10EE0A068DA
+:1011000061690578042003F0BDF8052D0AD0782325
+:1011100000220420616903F00BF803E004206169F8
+:1011200003F0B0F831462046BDE8704001F086B8C3
+:1011300010B500F12D02C3799478411D64F00304C9
+:101140002340C371DB070DD04B79547923404B7199
+:101150000B79127913400B718278C9788A4200D9D1
+:10116000817010BD00224A710A71F5E741780129AA
+:1011700000D00C21017070472DE9F04F93B04FF073
+:10118000000B0C690D468DF820B0097801260C2063
+:1011900017464FF00D084FF0110A4FF008091B29B0
+:1011A00075D2DFE811F01B00C30206031E035D03C6
+:1011B0007003A203B703F803190461049304A004A5
+:1011C000EC042A05340552055D05EE0531063406AA
+:1011D00063067F06F9061D07E606EB0614B12078C4
+:1011E0001D282AD0D5F808805FEA08004FD00120DA
+:1011F0008DF82000686A02220D908DF824200A20C4
+:101200008DF82500A8690A90A8880028EED098F8E3
+:10121000001091B10F2910D27ED2DFE801F07D13CA
+:1012200049DEFEFDFCFBFAF938089CF8F7000228BD
+:101230002DD124B120780C2801D00026EFE38DF8C1
+:101240002020CBE10420696A03F01CF8A888072855
+:10125000EED1204600F0EDFF022809D0204600F034
+:10126000E8FF032807D9204600F0E3FF072802D251
+:101270000120207004E0002CB8D020780128D7D1BC
+:1012800098F80400C11F0A2902D30A2061E0C4E1D2
+:10129000A070D8F80010E162B8F80410218698F820
+:1012A000060084F83200012028700320207044E0FA
+:1012B0000728BDD1002C99D020780D28B8D198F8F6
+:1012C000031094F82F20C1F3C000C2F3C0021042F3
+:1012D00001D0062000E00720890707D198F8051003
+:1012E0000142D2D198F806100142CED194F83120B3
+:1012F00098F8051020EA02021142C6D194F8322073
+:1013000098F8061090430142BFD198F80400C11F1D
+:101310000A29BAD2617D00E006E281427ED8D8F87F
+:1013200000106160B8F80410218198F80600A072DE
+:10133000012028700E20207003208DF82000686A9C
+:101340000D9004F12D000990601D0A900F300B9054
+:1013500022E12875FDE3412891D1204600F069FF84
+:10136000042802D1E078C00704D1204600F061FFD4
+:101370000F2884D1A88CD5F80C8080B24FF0400B98
+:10138000E669FFF747FC324641465B464E46CDF8DC
+:101390000090FFF732F80B208DF82000686A0D905E
+:1013A000E0690990002108A8FFF79EFE2078042834
+:1013B00006D0A07D58B1012809D003280AD049E3FE
+:1013C00005202070032028708DF82060CDE184F87E
+:1013D00000A032E712202070E9E11128BCD120469C
+:1013E00000F027FF042802D1E078C00719D020467A
+:1013F00000F01FFF062805D1E078C00711D1A07DBD
+:1014000002280ED0204600F014FF08E0CAE081E078
+:101410006FE14EE121E101E1E7E017E0ADE11128E4
+:101420009AD1102208F1010104F13C0012F0C0FE33
+:10143000607801287ED012202070E078C00760D04C
+:10144000A07D0028C8D00128C6D05AE0112890D12C
+:10145000204600F0EEFE082804D0204600F0E9FE09
+:10146000132886D104F16C00102208F10101064610
+:1014700012F09EFE207808280DD014202070E1780C
+:10148000C8070DD0A07D02280AD06278022A04D0B5
+:101490000328A1D035E00920F0E708B1012837D1B1
+:1014A000C80713D0A07D02281DD000200090D4E9E9
+:1014B000062133460EA8FFF776FC10220EA904F190
+:1014C0003C0012F049FEC8B1042042E7D4E90912F9
+:1014D000201D8DE8070004F12C0332460EA8616B35
+:1014E000FFF76FFDE9E7606BC1F34401491E006837
+:1014F000C84000F0010040F08000D7E720780928BC
+:1015000006D185F800908DF8209033E32870ECE345
+:101510000920FBE711289AD1204600F08AFE0A280C
+:1015200002D1E078C00704D1204600F082FE1528E1
+:101530008DD100E08DE104F13C00102208F10101A1
+:10154000064612F035FE20780A2816D016202070A4
+:10155000D4E90932606B611D8DE80F0004F15C0372
+:1015600004F16C0247310EA8FFF7C0FC10220EA94F
+:10157000304612F0F1FD18B1F5E20B20207071E257
+:101580002046FFF7D5FDA078216A0A18C0F11001A6
+:10159000104612F08CFE23E3394608A8FFF7A4FD9D
+:1015A00006463BE20228B6D1204600F042FE04285F
+:1015B00004D3204600F03DFE082809D3204600F061
+:1015C00038FE0E2829D3204600F033FE122824D2FC
+:1015D000A07D02289FD10E208DF82000686A0D9012
+:1015E00098F801008DF82400F0E3022893D12046FA
+:1015F00000F01FFE002810D0204600F01AFE01283F
+:10160000F9D0204600F015FE0C28F4D004208DF807
+:10161000240098F801008DF825005EE21128FCD125
+:10162000002CFAD020781728F7D16178606A022957
+:1016300011D0002101EB4101182606EBC101102257
+:10164000405808F1010112F0B3FD0420696A00F06E
+:10165000E3FD2670F1E50121ECE70B28DDD1002C3C
+:10166000DBD020781828D8D16078616A02281CD095
+:101670005FF0000000EB4002102000EBC2000958B0
+:10168000B8F8010008806078616A02280FD0002055
+:1016900000EB4002142000EBC2000958404650F80D
+:1016A000032F0A604068486039E00120E2E701202A
+:1016B000EEE71128B1D1002CAFD020781928ACD199
+:1016C0006178606A022912D05FF0000101EB4101EC
+:1016D0001C2202EBC1011022405808F1010112F056
+:1016E00067FD0420696A00F097FD1A20B6E0012129
+:1016F000ECE7082891D1002C8FD020781A288CD1C3
+:10170000606A98F80120017862F347010170616A0C
+:10171000D8F8022041F8012FB8F80600888004208C
+:10172000696A00F079FD8EE2072012E63878012818
+:1017300094D1182204F11400796812F07EFDE0794A
+:10174000C10894F82F0001EAD001E07861F30000AD
+:10175000E070217D002974D12178032909D0C007C8
+:1017600025D0032028708DF82090686A0D904120C4
+:1017700004E3607DA178884201D90620E9E50226CC
+:101780002671E179204621F0E001E171617A21F0D2
+:10179000F0016172A17A21F0F001A172FFF7C8FC9B
+:1017A0002E708DF82090686A0D900720E6E20420E4
+:1017B000ACE6387805289DD18DF82000686A0D9038
+:1017C000B8680A900720ADF824000A988DF830B068
+:1017D0006168016021898180A17A81710420207073
+:1017E000F4E23978052985D18DF82010696A0D91C8
+:1017F000391D09AE0EC986E80E004121ADF824104E
+:101800008DF830B01070A88CD7F80C8080B24026CC
+:10181000A769FFF711FA41463A463346C846CDF864
+:101820000090FEF71EFE002108A8FFF75DFCE0789F
+:1018300020F03E00801CE0702078052802D00F20A8
+:101840000CE049E1A07D20B1012802D0032802D09C
+:1018500002E10720BFE584F80080EEE42070ECE4AC
+:10186000102104F15C0002F034FA606BB0BBA07D83
+:1018700018B1012801D00520FDE006202870F748A6
+:101880006063A063BEE23878022894D1387908B149
+:101890002875B3E3A07D022802D0032805D022E0FA
+:1018A000B8680028F5D060631CE06078012806D095
+:1018B000A07994F82E10012805D0E84806E0A17917
+:1018C00094F82E00F7E7B8680028E2D06063E0786B
+:1018D000C00701D0012902D0E04803E003E0F86826
+:1018E0000028D6D0A063062010E68DF82090696A03
+:1018F0000D91E1784846C90709D06178022903D1E2
+:10190000A17D29B1012903D0A17D032900D00720A1
+:10191000287031E138780528BBD1207807281ED0FF
+:1019200084F800A005208DF82000686A0D90B86842
+:101930000A90ADF824A08DF830B003210170E17851
+:10194000CA070FD0A27D022A1AD000210091D4E943
+:10195000061204F15C03401CFFF725FA67E384F8E4
+:101960000090DFE7D4E90923211D8DE80E0004F182
+:101970002C0304F15C02401C616BFFF722FB56E371
+:10198000626BC1F34401491E1268CA4002F00101B2
+:1019900041F08001DAE738780528BDD18DF82000C4
+:1019A000686A0D90B8680A90ADF824A08DF830B040
+:1019B000042100F8011B102204F15C0112F0F8FB75
+:1019C000002108A8FFF790FB2078092801D01320F8
+:1019D00044E70A2020709BE5E078C10742D0A17D52
+:1019E000012902D0022927D038E0617808A801290E
+:1019F00016D004F16C010091D4E9061204F15C03E5
+:101A0000001DFFF7BBFA0A20287003268DF82080FE
+:101A1000686A0D90002108A8FFF766FBDDE2C3E2CB
+:101A200004F15C010091D4E9062104F16C03001D6E
+:101A3000FFF7A4FA0026E9E7C0F3440114290DD208
+:101A40004FF0006101EBB0104FEAB060E0706078D9
+:101A5000012801D01020BEE40620FFE660780128AE
+:101A60003FF4B7AC0A2051E5E178C90708D0A17D61
+:101A7000012903D10B20287004202FE028702DE0CD
+:101A80000E2028706078616B012817D004F15C0388
+:101A900004F16C020EA8FFF7E1FA2046FFF748FBBD
+:101AA000A0780EAEC0F11001304412F000FC062008
+:101AB0008DF82000686A09960D909AE004F16C0395
+:101AC00004F15C020EA8FFF7C9FAE9E739780229A8
+:101AD00003D139790029D1D029758FE28DF8200002
+:101AE000686A0D9058E538780728F6D1D4E90921BD
+:101AF0006078012808D004F16C00CDE90002029161
+:101B000005D104F16C0304E004F15C00F5E704F195
+:101B10005C0304F14C007A680646216AFFF764F919
+:101B20006078012821D1A078216A0A18C0F110013B
+:101B3000104612F0BCFBD4E90923606B04F12D01BF
+:101B40008DE80F0004F15C0304F16C0231460EA82D
+:101B500000E055E2FFF7CAF910220EA904F13C009B
+:101B600012F0FAFA08B10B20AFE485F8008000BF4C
+:101B70008DF82090686A0D908DF824A00CE53878D7
+:101B80000528AAD18DF82000686A0D90B8680A90DF
+:101B9000ADF824A08DF830B080F80080617801297C
+:101BA0001AD0D4E9093204F12D01A66B03920096F4
+:101BB000CDE9011304F16C0304F15C0204F14C0162
+:101BC000401CFFF793F9002108A8FFF78DFA607811
+:101BD000012805D0152041E6D4E90923611DE4E779
+:101BE0000E20287006208DF82000686ACDF824B0F9
+:101BF0000D90A0788DF82800CEE438780328C0D165
+:101C0000E079C00770D00F202870072066E7387889
+:101C100004286BD11422391D04F1140012F00DFBBD
+:101C2000616A208CA1F80900616AA078C871E17925
+:101C3000626A01F003011172616A627A0A73616A71
+:101C4000A07A81F82400162060E485F800A08DF8C1
+:101C50002090696A50460D9190E00000A447020070
+:101C60003878052842D1B868A8616178606A02298D
+:101C700001D0012100E0002101EB4101142606EB17
+:101C8000C1014058082102F024F86178606A0229F5
+:101C900001D0012100E0002101EB410106EBC1016F
+:101CA000425802A8E169FFF70DFA6078626A0228DB
+:101CB00001D0012000E0002000EB4001102000EBEB
+:101CC000C1000223105802A90932FEF7F1FF626A2F
+:101CD000FD4B0EA80932A169FFF7E3F96178606A4C
+:101CE000022904D0012103E042E18BE0BDE00021A4
+:101CF00001EB4101182606EBC101A27840580EA95C
+:101D000012F056FA6178606A022901D0012100E0E0
+:101D1000002101EB410106EBC1014058A1780844C4
+:101D2000C1F1100112F0C3FA05208DF82000686A95
+:101D30000D90A8690A90ADF824A08DF830B0062166
+:101D400001706278616A022A01D0012200E000225B
+:101D500002EB420206EBC202401C8958102212F02C
+:101D600027FA002108A8FFF7BFF91220C5F818B01C
+:101D700028708DF82090686A0D900B208DF8240053
+:101D80000AE43878052870D18DF82000686A0D9033
+:101D9000B8680A900B20ADF824000A98072101705A
+:101DA0006178626A022901D0012100E0002101EB83
+:101DB0004103102101EBC30151580988A0F801101B
+:101DC0006178626A022902D0012101E02FE100213D
+:101DD00001EB4103142101EBC30151580A6840F89B
+:101DE000032F4968416059E01920287001208DF8BF
+:101DF000300077E6162028708DF830B0002108A852
+:101E0000FFF772F9032617E114202870B0E638783E
+:101E100005282AD18DF82000686A0D90B8680A90CC
+:101E2000ADF824A08DF830B080F800906278616A37
+:101E30004E46022A01D0012200E0002202EB4202BB
+:101E40001C2303EBC202401C8958102212F0B0F987
+:101E5000002108A8FFF748F9152028708DF82060A8
+:101E6000686A0D908DF824603CE680E0387805289B
+:101E70007DD18DF82000686A0D90B8680A90ADF8A1
+:101E800024900921017061690978490841706169EC
+:101E900051F8012FC0F802208988C18020781C28C1
+:101EA000A8D1A1E7E078C00702D04FF0060C01E00E
+:101EB0004FF0070C607802280AD04FF0000000BFF6
+:101EC00000EB040101F1090105D04FF0010004E02D
+:101ED0004FF00100F4E74FF000000B78204413EAC4
+:101EE0000C030B7010F8092F02EA0C02027004D1E7
+:101EF0004FF01B0C84F800C0D2B394F801C0BCF1C1
+:101F0000010F00D09BB990F800C0E0465FEACC7C9E
+:101F100004D028F001060670102606E05FEA887CEF
+:101F200005D528F00206067013262E70032694F8B5
+:101F300001C0BCF1020F00D092B991F800C05FEA75
+:101F4000CC7804D02CF001060E70172106E05FEA71
+:101F50008C7805D52CF002060E7019212170002610
+:101F60000078D0BBCAB3C3BB1C20207035E012E0A0
+:101F700002E03878062841D11A2019E42078012897
+:101F80003CD00C283AD02046FFF7F0F809208DF815
+:101F90002000686A0D9031E03878052805D00620C9
+:101FA000387003261820287046E005218DF820108F
+:101FB000686A0D90B8680A900220ADF824000120EC
+:101FC0008DF830000A980170297D4170394608A8C3
+:101FD000FFF78AF8064618202870012E0ED02BE055
+:101FE00001208DF82000686A0D9003208DF82400F0
+:101FF000287D8DF8250085F814B012E0287D80B189
+:102000001D202070172028708DF82090686A0D9090
+:1020100002208DF82400394608A8FFF765F8064627
+:102020000AE00CB1FE2020709DF8200020B10021B4
+:1020300008A8FFF759F810E413B03046BDE8F08F58
+:102040002DE9F04387B00C464E6900218DF804104D
+:1020500001202578034602274FF007094FF0050CB1
+:1020600085B1012D53D0022D39D1FE2030708DF86D
+:102070000030606A059003208DF80400207E8DF802
+:10208000050063E02179012925D002292DD00329FB
+:1020900028D0042923D1B17D022920D131780D1F08
+:1020A000042D04D30A3D032D01D31D2917D1218905
+:1020B000022914D38DF80470237020899DF8041030
+:1020C00088421BD2082001E09C4702008DF80000E6
+:1020D000606A059057E070780128EBD0052007B0C2
+:1020E000BDE8F0831D203070E4E771780229F5D156
+:1020F00031780C29F3D18DF80490DDE7083402F82B
+:1021000004CB94E80B0082E80B000320E7E7157886
+:10211000052DE4D18DF800C0656A05959568029596
+:102120008DF8101094F80480B8F1010F13D0B8F1B5
+:10213000020F2DD0B8F1030F1CD0B8F1040FCED18F
+:10214000ADF804700E202870207E6870002168466B
+:10215000FEF7CAFF0CE0ADF804700B202870207E5B
+:10216000002100F01F0068706846FEF7BDFF377061
+:102170000020B4E7ADF804708DF8103085F800C089
+:10218000207E6870277011466846FEF7ADFFA6E70F
+:10219000ADF804902B70207F6870607F00F0010024
+:1021A000A870A07F00F01F00E870E27F2A71C007CE
+:1021B0001CD094F8200000F00700687194F821000A
+:1021C00000F00700A87100216846FEF78DFF28681F
+:1021D000F062A8883086A87986F83200A069407835
+:1021E00070752879B0700D203070C1E7A9716971E0
+:1021F000E9E700B587B004280CD101208DF8000074
+:102200008DF80400002005918DF805000146684610
+:10221000FEF76AFF07B000BD70B50C46054602F038
+:1022200031F821462846BDE870407823002201F0AD
+:102230007FBF08B1007870470C20704770B50C0064
+:1022400005784FF000010CD021702146F3F701F81A
+:1022500069482178405D884201D1032070BD022089
+:1022600070BDF2F7F6FF002070BD0279012A05D09B
+:1022700000220A704B78012B02D003E00420704743
+:102280000A758A6102799300521C0271C1500320C1
+:102290007047F0B587B00F4605460124287905EB55
+:1022A000800050F8046C7078411E02290AD252490D
+:1022B0003A46083901EB8000314650F8043C284684
+:1022C000984704460CB1012C11D12879401E10F01A
+:1022D000FF00287101D00324E0E70A208DF80000F8
+:1022E000706A0590002101966846FFF7A7FF032C4E
+:1022F000D4D007B02046F0BD70B515460A46044656
+:1023000029461046FFF7C5FF064674B12078FE281F
+:102310000BD1207C30B100202870294604F10C003C
+:10232000FFF7B7FF2046FEF721FF304670BD70472C
+:1023300070B50E4604467C2111F0DBFF0225012E0C
+:1023400003D0022E04D0052070BD0120607000E093
+:1023500065702046FEF70AFFA575002070BD28B104
+:10236000027C1AB10A4600F10C01C5E70120704752
+:1023700010B5044686B0042001F084FF2078FE28C2
+:1023800006D000208DF8000069462046FFF7E7FFE1
+:1023900006B010BD7CB50E4600218DF804104178C2
+:1023A000012903D0022903D0002405E0046900E0DC
+:1023B00044690CB1217C89B16D4601462846FFF77E
+:1023C00054FF032809D1324629462046FFF794FFDF
+:1023D0009DF80410002900D004207CBD04F10C05F8
+:1023E000EBE730B40C460146034A204630BC034BB1
+:1023F0000C3AFEF756BE0000E04702009C47020080
+:1024000070B50D46040011D085B12101284611F0A8
+:102410004EFF10224E49284611F0CAFE4C480121B9
+:102420000838018044804560002070BD012070BDE7
+:1024300070B5474E00240546083E10E07068AA7B40
+:1024400000EB0410817B914208D1C17BEA7B914271
+:1024500004D10C22294611F07FFE30B1641C308873
+:102460008442EBDB4FF0FF3070BD204670BD70B58D
+:102470000D46060006D02DB1FFF7DAFF002803DB7A
+:10248000401C14E0102070BD314C083C208862884C
+:10249000411C914201D9042070BD6168102201EBFA
+:1024A0000010314611F084FE2088401C20802870E6
+:1024B000002070BD70B514460D0018D0BCB10021CD
+:1024C000A170022802D0102811D105E0288870B12F
+:1024D0000121A170108008E02846FFF7A9FF00281D
+:1024E00005DB401CA070A8892080002070BD012061
+:1024F00070BD70B5054614460E000BD0002030703C
+:10250000A878012808D005D91149A1F108010A8845
+:1025100090420AD9012070BD24B128782070288803
+:10252000000A5070022008700FE064B14968102260
+:1025300001EB00112046103911F03AFE2878207383
+:102540002888000A607310203070002070BD0000E1
+:102550007C0000202DE9F04190460C4607460025FE
+:10256000FE48072F00EB881607D2DFE807F00707C1
+:10257000070704040400012500E0FFDF06F81470DB
+:10258000002D13D0F548803000EB880191F827002A
+:10259000202803D006EB4000447001E081F826407B
+:1025A00006EB44022020507081F82740BDE8F081FE
+:1025B000F0B51F4614460E460546202A00D1FFDF1F
+:1025C000E649E648803100EB871C0CEB440001EB48
+:1025D0008702202E07D00CEB460140784B784870DC
+:1025E000184620210AE092F82530407882F825002C
+:1025F000F6E701460CEB410005704078A142F8D1A6
+:1026000092F82740202C03D00CEB4404637001E0C7
+:1026100082F826300CEB41042023637082F82710E7
+:10262000F0BD30B50D46CE4B44190022181A72EB9E
+:10263000020100D2FFDFCB48854200DDFFDFC94841
+:102640004042854200DAFFDFC548401C844207DA79
+:10265000002C01DB204630BDC148401C201830BD95
+:10266000BF48C043FAE710B504460168407ABE4A45
+:1026700052F82020114450B10220084420F07F403D
+:10268000F0F779FA94F90810BDE81040C9E7042082
+:10269000F3E72DE9F047B14E803696F82D50DFF87C
+:1026A000BC9206EB850090F8264034E009EB8517D4
+:1026B0004FF0070817F81400012806D004282ED080
+:1026C00005282ED0062800D0FFDF01F0E3F80146F0
+:1026D00007EB4400427806EB850080F8262090F84E
+:1026E0002720A24202D1202280F82720084601F0AC
+:1026F000DCF82A4621460120FFF72CFF9B48414683
+:1027000000EB041002682046904796F82D5006EB27
+:10271000850090F82640202CC8D1BDE8F087022023
+:1027200000E003208046D0E710B58C4C2021803497
+:1027300084F8251084F8261084F82710002084F8E7
+:10274000280084F82D0084F82E10411EA16044F862
+:10275000100B2074607420736073A0738449E07759
+:1027600020750870487000217C4A103C02F8110066
+:10277000491CC9B22029F9D30120F0F7EAF800205A
+:10278000F0F7E7F8012084F82200F9F7D1FA794848
+:10279000F9F7DDFA764CA41E20707748F9F7D7FADE
+:1027A0006070BDE81040F0F761B810B5F0F783F83D
+:1027B0006F4CA41E2078F9F7E3FA6078F9F7E0FA95
+:1027C000BDE8104001F09EB8202070472DE9F34F7E
+:1027D000624E0025803606EB810A89B09AF8250002
+:1027E000202822D0691E02916049009501EB00105B
+:1027F0008146D0E90112C0680391CDE90420B08B75
+:10280000ADF81C00B07F8DF81E009DF81500C8B112
+:102810000227554951F820400399E219114421F04B
+:102820007F41019184B102210FE00120F0F791F87E
+:102830000020F0F78EF8F0F75CF801F063F886F806
+:102840002F50A0E00427E4E700218DF8181002289B
+:1028500001D0012820D10398391901440998081A98
+:102860009DF81C1020F07F4001B1022133318142DC
+:102870000BD203208DF815000398C4F13201401AE1
+:1028800020F07F40322403900CE096F8240018B921
+:10289000F0F782FB00284CD0322C03D214B101F0A7
+:1028A00025F801E001F02EF8314A107818B393466C
+:1028B0005278039B121B00219DF81840984601286E
+:1028C0001AD0032818D000208DF81E00002A04DD3D
+:1028D000981A039001208DF818009DF81C0000B193
+:1028E00002210398254A20F07F40039003AB09980A
+:1028F00001F014F810B110E00120E5E79DF81D008B
+:1029000018B99BF80000032812D08DF81C50CDF8A0
+:102910000C808DF818408DF81E509DF8180058B1A5
+:1029200003980123C11900221846F0F765F806E064
+:1029300000200BB0BDE8F08F0120F0F70AF899F9FC
+:102940000C20012300200199F0F756F8012086F8A9
+:102950002F008AF828502022694611E098080020AC
+:10296000FF7F841E0020A107F04702009806002088
+:102970008E000020DF3F010093260100FFFF3F0093
+:10298000F94811F05AFC0120D3E72DE9F05FDFF898
+:10299000D883064608EB860090F82550202D1FD0DE
+:1029A000A8F180002C4600EB8617A0F50079DFF82F
+:1029B000BCB305E0A24607EB4A004478202C0AD0BD
+:1029C000F0F766F809EB04135A4601211B1D00F0CD
+:1029D000A5FF0028EED0AC4202D0334652461EE09E
+:1029E000E34808B1AFF30080F0F752F898F82F20D1
+:1029F0006AB1D8F80C20411C891A0902CA1701EBE8
+:102A000012610912002902DD0020BDE8F09F314665
+:102A1000FFF7DCFE08B10120F7E733462A46202104
+:102A20000420FFF7C5FDEFE72DE9F041CE4C256905
+:102A3000F0F72EF8401B0002C11700EB11600012E6
+:102A400000D4FFDF94F8220000B1FFDF012784F8F3
+:102A5000227094F82E00202800D1FFDF94F82E6019
+:102A6000202084F82E00002584F82F5084F8205070
+:102A700084F82150BF4825600078022833D003280D
+:102A800031D000202077A068401C05D04FF0FF30E7
+:102A9000A0600120EFF75DFF0020EFF75AFFF0F78D
+:102AA00058F8F0F750F8EFF724FF10F0D7FDB248D0
+:102AB000056005604FF0E0214FF40040B846C1F8D2
+:102AC0008002F0F7E0F894F82D703846FFF75DFFCC
+:102AD0000028FAD0A448803800EB871010F81600C0
+:102AE000022802D006E00120CCE73A463146062013
+:102AF000FFF730FD84F8238004EB870090F8260070
+:102B0000202804D09B48801E4078F9F73FF9207FA9
+:102B1000002803D0F0F70DF82577657746E50146E4
+:102B2000914810B590F82D200024803800EB8210D9
+:102B300010F814302BB1641CE4B2202CF8D3202000
+:102B400010BD8E4800EB0410016021460120FFF704
+:102B500001FD204610BD10B5012801D0032800D189
+:102B600071B3814A92F82D307F4C0022803C04EBF7
+:102B7000831300BF13F812400CB1082010BD521C83
+:102B8000D2B2202AF6D37B4A48B1022807D00729BF
+:102B900016D2DFE801F01506080A0C0E100000211D
+:102BA0000AE01B2108E03A2106E0582104E07721E1
+:102BB00002E0962100E0B52151701070002010BD98
+:102BC000072010BD6B4810B54078EFF7D4FF80B2F6
+:102BD00010BD10B5202811D2634991F82D30A1F114
+:102BE000800202EB831414F810303BB191F82D30C1
+:102BF00002EB831212F81020012A01D0002010BD30
+:102C000091F82D2001460020FFF7A4FC012010BD03
+:102C100010B5EFF73DFFBDE81040EFF7ACBF2DE971
+:102C2000F0410E46504F01782025803F0C4607EBBF
+:102C3000831303E0254603EB45046478944202D0F5
+:102C4000202CF7D108E0202C06D0A14206D103EBBE
+:102C500041014978017007E00020A7E403EB44003C
+:102C600003EB450140784870454F7EB127B1002104
+:102C700040F2DA30AFF300803078A04206D127B1BD
+:102C8000002140F2DD30AFF30080357027B1002124
+:102C900040F2E230AFF30080012087E410B54268D3
+:102CA0000B689A1A1202D41702EB1462121216D48D
+:102CB000497A91B1427A82B9324A006852F82110B9
+:102CC000126819441044001D891C081A0002C1171B
+:102CD00000EB11600012322801DB012010BD002042
+:102CE00010BD2DE9F04781461F48244E00EB8100BE
+:102CF000984690F825402020107006F50070154683
+:102D000000EB81170BE000BF06EB04104946001DE5
+:102D1000FFF7C4FF28B107EB44002C704478202C47
+:102D2000F2D1297888F8001013E000BF06EB0415F3
+:102D3000291D4846FFF7B2FF68B988F80040A97B13
+:102D400099F80A00814201D80020E6E407EB44002C
+:102D50004478202CEAD10120DFE42DE9FC410E4625
+:102D600007460024054D18E018090020FFFF3F002A
+:102D7000000000008E00002000F5004098060020B2
+:102D800000000000F04702009DF8000005EB001075
+:102D90008168384600F0D6FD01246B4601AA314611
+:102DA0003846FFF79EFF0028EED02046BDE8FC81A4
+:102DB00070B50446FF480125A54300EB841100EBE4
+:102DC0008510402211F0F4F9FB4E26B1002140F2AB
+:102DD0005C40AFF30080F748803000EB850100EBEA
+:102DE0008400D0F82500C1F8250026B100214FF459
+:102DF0008C60AFF30080284670BD2DE9FC4184460D
+:102E0000EC481546089C00EB85170E4617F8140091
+:102E1000012803D0022801D00020C7E70B46E74A6B
+:102E20000121604600F07AFDA8B101AB6A4629464F
+:102E30003046FFF756FF70B1DE489DF804209DF83C
+:102E40000010803000EB85068A4208D02B46052012
+:102E5000FFF7AEFB0BE02A462146042014E02029B0
+:102E600003D007EB4100407801E096F8250007EB1E
+:102E7000440148709DF80000202809D007EB40006D
+:102E800044702A4621460320FFF764FB01208DE7AA
+:102E900006F8254F0120F070F3E7C94901EB001057
+:102EA000001DFFF7E0BB7CB51D46134604460E46E9
+:102EB00000F1080221461846EFF76AFE94F908006F
+:102EC0000F2804DD1F3820722068401C206096B156
+:102ED0000220BC4951F82610461820686946801B1C
+:102EE00020F07F40206094F908002844C01C1F286F
+:102EF00003DA012009E00420EBE701AAEFF748FE1E
+:102F00009DF8040010B10098401C009000992068C2
+:102F100031440844C01C20F07F4060607CBD2DE936
+:102F2000FE430C46064609786079907220799846EF
+:102F30001546507241B19F48803090F82E102029DC
+:102F40000AD00069401D0BE0D4E90223217903B0C7
+:102F50002846BDE8F043A6E79B484178701D084429
+:102F600020F07F47217900222846A368FFF79BFFC6
+:102F70003946284600F0E6FCD4E902322179684659
+:102F8000FFF791FF41462846019CFFF7E6FE2B46DE
+:102F900022460021304600F0C1FC002803D1314612
+:102FA000284600F0CFFCBDE8FE832DE9FE4F8146A8
+:102FB00000F084FC30B1002799F8000020B1002017
+:102FC000BDE8FE8F0127F7E77A4D7B4C4FF0000AF2
+:102FD000803524B1002140F2D340AFF3008095F852
+:102FE0002D8085F823A0002624B100214FF49B609A
+:102FF000AFF300801FB94046FFF7DAFE804624B1E8
+:1030000000214FF49C60AFF30080EFF741FD434691
+:103010006A464946FFF783FF24B1002140F2E640AB
+:10302000AFF3008095F82E0020280CD02969009875
+:10303000401A0002C21700EB1260001203D5684666
+:1030400000F080FC012624B100214FF49E60AFF314
+:10305000008095F823000028BBD124B1002140F264
+:10306000F640AFF30080EFF713FD6B46534A0021A3
+:1030700000F054FC0028A3D027B941466846FFF76A
+:103080006CFE064326B16846FFF7EDFAC9F8080062
+:1030900024B1002140F20950AFF3008001208FE7F6
+:1030A0002DE9FF5F8A46814600F008FC414C8034E0
+:1030B00010B39AF80000002710B1012800D0FFDFFC
+:1030C0003D4D25B1002140F27F50AFF3008001203B
+:1030D000A84600905FEA080604D0002140F287501D
+:1030E000AFF30080009800F0E0FB94F82D50002032
+:1030F00084F8230067B119E094F82E0001272028F6
+:1031000000D1FFDF9AF800000028D9D0FFDFD7E711
+:103110002846FFF74DFE054626B1002140F29150AA
+:10312000AFF3008094F823000028D3D126B100210A
+:1031300040F29B50AFF30080EFF7AAFC83462B468A
+:1031400001AA5146FFF7EBFE5FEA060804D0002112
+:1031500040F2A250AFF300803B462A4601A95846F0
+:10316000CDF80090FFF749FE064604EB850090F885
+:1031700028B0B8F1000F04D0002140F2A950AFF3FD
+:10318000008000F087FB0090B8F1000F04D0002110
+:1031900040F2AF50AFF3008094F82300002899D19B
+:1031A000B8F1000F04D0002140F2B750AFF3008017
+:1031B00003490BE09808002000000000FFFF3F00DB
+:1031C00098060020F04702008E00002001EB091055
+:1031D0000DF1040C00F104009CE80E0080E80E00E4
+:1031E0004EB35FEA080604D0002140F2C450AFF3AA
+:1031F00000803BEA070012D094F82E0020280ED160
+:1032000026B1002140F2C950AFF300802846FFF7F5
+:10321000BCFB20B99AF80000D8B3012849D0B8F116
+:10322000000F04D0002140F2E650AFF300802846A2
+:1032300000F029FB01265FEA080504D0002140F2D6
+:10324000EF50AFF30080009800F02FFB25B1002174
+:1032500040F2F350AFF300808EB194F82D0004EBF0
+:10326000800090F82600202809D025B1002140F2E6
+:10327000FA50AFF30080F9484078F8F787FD25B1A0
+:10328000002140F2FF50AFF3008004B03046BDE8AB
+:10329000F09FFFE7B8F1000F04D0002140F2D150B9
+:1032A000AFF3008094F82D2049460420FFF752F92F
+:1032B000C0E7002E3FF40EAF002140F2DC50AFF328
+:1032C000008007E72DE9F84FE54D814695F82D0080
+:1032D0004FF00008E34C4FF0010B474624B10021AA
+:1032E00040F20D60AFF30080584600F0DEFA85F83A
+:1032F000237024B1002140F21260AFF3008095F8F2
+:103300002D00FFF755FD064695F8230028B1002C47
+:10331000E4D000214FF4C3604BE024B1002140F21F
+:103320001C60AFF30080CE48803800EB861111F8A6
+:103330001900032856D1334605EB830A4A469AF80A
+:103340002500904201D1012000E0002000900AF108
+:1033500025000021FFF763FC01460098014203D0DD
+:1033600001228AF82820AF77E1B324B1002140F28E
+:103370002160AFF30080324649460120FFF7EAF8AA
+:103380009AF828A024B1002140F22C60AFF300800D
+:1033900000F080FA834624B1002140F23160AFF39F
+:1033A000008095F8230038B1002C97D0002140F21E
+:1033B0003560AFF3008091E7BAF1000F07D095F8C0
+:1033C0002E00202803D13046FFF7DFFAE0B124B108
+:1033D000002140F24960AFF30080304600F053FA1C
+:1033E0004FF0010824B1002140F25260AFF3008099
+:1033F000584600F05AFA24B1002140F25660AFF36B
+:1034000000804046BDE8F88F002CF1D0002140F24A
+:103410004460AFF30080E6E70020EFF773BA0120C5
+:10342000EFF770BA8D48007870472DE9F0418C4C69
+:1034300094F82E0020281FD194F82D6004EB860705
+:1034400097F82550202D00D1FFDF8549803901EB09
+:10345000861000EB4500407807F8250F0120F87032
+:1034600084F82300294684F82E5032460220223464
+:10347000FFF770F8002020700FE42DE9F0417A4E3C
+:10348000774C012538B1012821D0022879D00328B2
+:103490007DD0FFDFF0E700F029FAFFF7C6FF207EBE
+:1034A00000B1FFDF84F821500020EFF752FAA16845
+:1034B000481C04D0012300221846EFF79DFA14F8A7
+:1034C0002E0F217806EB01110A68012154E0FFF765
+:1034D000ACFF0120EFF73DFA94F8210050B1A0684D
+:1034E000401C07D014F82E0F217806EB01110A6852
+:1034F000062141E0207EDFF86481002708F1020800
+:10350000012803D002281ED0FFDFB5E7A777EFF729
+:1035100010FB98F80000032801D165772577607DBE
+:10352000524951F8200094F8201051B948B161680F
+:103530000123091A00221846EFF75EFA02202076CE
+:103540009AE7277698E784F8205000F0CFF9A07F1B
+:1035500050B198F8010061680123091A0022184649
+:10356000EFF74AFA257600E0277614F82E0F217837
+:1035700006EB01110A680021BDE8F041104700E0A8
+:1035800005E036480078BDE8F041F8F7FFBBFFF7EB
+:103590004CFF14F82E0F217806EB01110A68052163
+:1035A000EAE710B52E4C94F82E00202800D1FFDF5A
+:1035B00014F82E0F21782C4A02EB01110A68BDE89D
+:1035C0001040042110477CB5254C054694F82E0088
+:1035D000202800D1FFDFA068401C00D0FFDF94F856
+:1035E0002E00214901AA01EB0010694690F90C0058
+:1035F0002844EFF7CDFA9DF904000F2801DD0120E2
+:1036000000E00020009908446168084420F07F41F0
+:10361000A16094F82100002807D002B00123BDE882
+:10362000704000221846EFF7E7B97CBD30B5104A6C
+:103630000B1A541CB3EB940F1ED3451AB5EB940F21
+:103640001AD3934203D9101A43185B1C14E0954215
+:1036500010D9511A0844401C43420DE08C00002050
+:10366000180900200000000098060020F047020022
+:10367000FF7F841EFFDF0023184630BD0123002298
+:1036800001460220EFF7B8B90220EFF762B9EFF771
+:10369000FFB92DE9FC47B14C054694F82E002028CF
+:1036A00000D1FFDF642D58D3AD4A0021521B71EBCE
+:1036B000010052D394F82E20A0462046DFF8A492B1
+:1036C00090F82D7009EB0214D8F8000001AA2844E4
+:1036D0006946EFF75DFA9DF90400002802DD0098C5
+:1036E000401C0090A068009962684618B21A22F047
+:1036F0007F42B2F5800F30D208EB8702444692F841
+:103700002520202A0AD009EB02125268101A000262
+:10371000C21700EB1260001288421EDBA068401C3A
+:1037200010D0EFF7B5F9A168081A0002C11700EB35
+:1037300011600012022810DD0120EFF70AF94FF0A6
+:10374000FF30A06020682844206026F07F40206180
+:10375000012084F82300BDE8FC870020FBE72DE969
+:10376000F0477E4C074694F82D00A4F1800606EB46
+:10377000801010F8170000B9FFDF94F82D50A04614
+:10378000794C24B1002140F66500AFF3008040F68B
+:10379000710940F67A0A06EB851600BF16F8170085
+:1037A000012818D0042810D005280ED006280CD0E7
+:1037B0001CB100214846AFF3008020BF002CEDD0A3
+:1037C00000215046AFF30080E8E72A463946012041
+:1037D000FEF7C0FEF2E74FF0010A4FF00009454640
+:1037E00024B1002140F68100AFF30080504600F084
+:1037F0005CF885F8239024B1002140F68600AFF3F1
+:10380000008095F82D00FFF7D3FA064695F82300BF
+:1038100028B1002CE4D0002140F68C001FE024B138
+:1038200000214FF40960AFF3008005EB860000F142
+:10383000270133463A462630FFF7F1F924B100213B
+:1038400040F69400AFF3008000F024F8824695F82B
+:10385000230038B1002CC3D0002140F69A00AFF30A
+:103860000080BDE785F82D60012085F823005046D3
+:1038700000F01BF8002C04D0002140F6A700AFF3A5
+:103880000080BDE8F087354981F82D00012081F8DE
+:103890002300704710B5354808B1AFF30080EFF34F
+:1038A000108000F0010072B610BD10B5002804D1E0
+:1038B0002F4808B1AFF3008062B610BD2D480068F4
+:1038C000C005C00D10D0103840B2002806DA00F054
+:1038D0000F0000F1E02090F8140D03E000F1E0206B
+:1038E00090F80004400970470820704710B51B4C41
+:1038F00094F82400002804D1F8F72AF8012084F86D
+:10390000240010BD10B5154C94F82400002804D0F4
+:10391000F8F747F8002084F8240010BD10B51C68A3
+:103920005B68241A181A24F07F4420F07F40A142DB
+:1039300006D8B4F5800F03D2904201D8012010BD03
+:10394000002010BDD0E90032D21A21F07F4311448B
+:1039500021F07F41C0E900317047000018090020C4
+:10396000FF1FA107980600200000000000000000D3
+:103970000000000004ED00E02DE9F041044680075E
+:103980004FF000054FF001060CD560480560066059
+:103990000FF0C6FC20B15E48016841F4806101600F
+:1039A00024F00204E0044FF0FF3705D55948466083
+:1039B000C0F8087324F48054600003D556480560AD
+:1039C00024F08044E0050FD55448C0F80052C0F8F8
+:1039D000087353490D60091D0D60514A04210C32D2
+:1039E0001160066124F48074A00409D54D48466036
+:1039F000C0F80052C0F808734B48056024F4005426
+:103A0000C4F38030C4F3C031884200D0FFDF14F427
+:103A1000404F14D045484660C0F80873444886605B
+:103A2000C0F80052C0F8087342490D600A1D1660C4
+:103A30008660C0F808730D60166024F440442005C9
+:103A40000AD53D4846608660C0F80873C0F84873E0
+:103A50003A48056024F400640FF0DAFD3848044267
+:103A600000D0FFDFBDE8F08170B5202500221346AD
+:103A700020FA02F1C90719D051B201F01F06012442
+:103A8000B4404E09B60006F1E026C6F88041C6F8FB
+:103A90008042002906DA01F00F0101F1E02181F8EE
+:103AA000143D03E001F1E02181F80034521CAA42E8
+:103AB000DED370BD70B5234C0D462060FFF75CFF70
+:103AC0002068FFF7D1FF2846F8F71FF80FF0FAF942
+:103AD00000F0AFF80FF09CFD0FF0E7FCF8F728F9C5
+:103AE000BDE870400FF09CBA10B5164C2068FFF787
+:103AF00043FF2068FFF7B8FF0FF08AFDF8F794F84E
+:103B00000020206010BD0A2070470000FC1F00400C
+:103B10003C17004000C0004004E501400080004028
+:103B20000485004000D0004004D5004000E0004083
+:103B300000F0004000F5004000B0004008B5004033
+:103B4000FEFF0FFD9000002070B526490A680AB3F9
+:103B50000022154601244B685B1C4B60092B00D3E7
+:103B60004D600E7904FA06F30E681E420FD0EFF393
+:103B7000108212F0010272B600D001220C689C4340
+:103B80000C6002B962B649680160002070BD521C29
+:103B9000092AE0D3052070BD4FF0E0214FF48000EA
+:103BA000C1F800027047EFF3108111F0010F72B6F7
+:103BB0004FF0010202FA00F20A48036842EA0302E7
+:103BC000026000D162B6E7E706480021016041606B
+:103BD00070470121814003480068084000D001205F
+:103BE00070470000940000202DE9F04115460E4674
+:103BF0000446002700F0E7F8A84215D3002341202F
+:103C00000FE000BF94F84220A25CF25494F84210F6
+:103C1000491CB1FBF0F200FB12115B1C84F842104E
+:103C2000DBB2AB42EED3012700F0D9F83846BDE84D
+:103C3000F081704910B5802081F800046E490020A1
+:103C400081F8420081F84100433181F8420081F857
+:103C50004100433181F8420081F8410067480FF08C
+:103C60006DFB6648401C0FF069FBEFF71BF8BDE8E1
+:103C7000104000F0B4B8402070475F4800F0A3B88F
+:103C80000A4601465C48AFE7402070475A48433037
+:103C900000F099B80A46014657484330A4E740214E
+:103CA00001700020704710B504465348863000F07C
+:103CB0008AF82070002010BD0A4601464E4810B513
+:103CC0008630FFF791FF08B1002010BD42F20700D7
+:103CD00010BD70B50C460546412900D9FFDF4848A4
+:103CE0000068103840B200F050F8C6B20D2000F065
+:103CF0004CF8C0B2864203D2FFDF01E0EFF722F8B2
+:103D0000224629463C48FFF76FFF0028F6D070BDD9
+:103D10002DE9F041394F002506463F1D57F8254053
+:103D2000204600F041F810B36D1CEDB2032DF5D321
+:103D30003148433000F038F8002825D02E4800F0F4
+:103D400033F8002820D02C48863000F02DF80028C9
+:103D50001AD0EEF7CDFF29480FF0F8FAB0F5005F62
+:103D600000D0FFDFBDE8F04124480FF005BB94F818
+:103D700041004121265414F8410F401CB0FBF1F2E0
+:103D800001FB12002070D3E751E7002806DA00F0AB
+:103D90000F0000F1E02090F8140D03E000F1E020A6
+:103DA00090F800044009704710F8411F4122491C57
+:103DB000B1FBF2F302FB13114078814201D10120E3
+:103DC00070470020704710F8411F4078814201D3AE
+:103DD000081A02E0C0F141000844C0B2704710B5B3
+:103DE00006480FF0B3FA002803D1BDE81040EEF703
+:103DF0006ABF10BD0DE000E0480900209C000020D3
+:103E000004ED00E070B5154D2878401CC4B2687808
+:103E1000844202D0EFF727F82C7070BD2DE9F041F5
+:103E20000E4C4FF0E02600BFEFF712F820BF40BF66
+:103E300020BF677820786070D6F80052EDF76EFAF0
+:103E4000854305D1D6F8040210B92078B842EBD0EA
+:103E5000EEF7F9FF0020BDE8F0810000AC00002083
+:103E60002DE9F041012528034FF0E0210026C1F89B
+:103E700080011E4CC4F800610C2000F02CF81C4896
+:103E800001680268C94341F3001142F01002026068
+:103E9000C4F804532560491C00E020BFD4F8002179
+:103EA000002AFAD019B9016821F010010160114807
+:103EB00007686560C4F80853C4F800610C2000F07E
+:103EC0000AF83846BDE8F08110B50446FFF7C8FF90
+:103ED0002060002010BD00F01F0201219140400928
+:103EE000800000F1E020C0F88012704700C0004060
+:103EF00010ED00E008C500402DE9F047FF4C0646F4
+:103F0000FF21A06800EB061211702178FF2910D064
+:103F10004FF0080909EB011109EB06174158C05988
+:103F200000F0F4F9002807DDA168207801EB061104
+:103F300008702670BDE8F08794F8008045460DE0D3
+:103F4000A06809EB05114158C05900F0DFF90028BD
+:103F500006DCA068A84600EB08100578FF2DEFD11D
+:103F6000A06800EB061100EB08100D700670E1E789
+:103F7000F0B5E24B0446002001259A680C269B7898
+:103F80000CE000BF05EB0017D75DA74204D106EB9C
+:103F90000017D7598F4204D0401CC0B28342F1D8D9
+:103FA000FF20F0BD70B5FFF772FBD44C08252278D6
+:103FB000A16805EB0212895800F0A8F9012808DD74
+:103FC0002178A06805EB01114058BDE87040FFF76B
+:103FD00055BBFFF727FABDE87040F7F7D7BE2DE9CC
+:103FE000F041C64C2578FFF752FBFF2D6ED04FF005
+:103FF0000808A26808EB0516915900F087F9022815
+:10400000A06801DD80595DE000EB051109782170A1
+:10401000022101EB0511425C5AB1521E42548159F2
+:1040200001F5800121F07F4181512846FFF764FFAF
+:1040300034E00423012203EB051302EB051250F8D0
+:1040400003C0875CBCF1000F10D0BCF5007F10D915
+:10405000CCF3080250F806C00CEB423C2CF07F4C2D
+:1040600040F806C0C3589A1A520A09E0FF21815449
+:104070000AE0825902EB4C3222F07F428251002248
+:1040800042542846FFF738FF0C21A06801EB0511C8
+:104090004158E06850F82720384690472078FF289C
+:1040A00014D0FFF7F4FA2278A16808EB0212454613
+:1040B000895800F02BF9012893DD2178A06805EBE1
+:1040C00001114058BDE8F041FFF7D8BABDE8F081D2
+:1040D000F0B51D4614460E460746FF2B00D3FFDF02
+:1040E000A00700D0FFDF8548FF210022C0E902477A
+:1040F000C57006710170427082701046012204E0A2
+:1041000002EB0013401CE154C0B2A842F8D3F0BD4A
+:1041100070B57A4C064665782079854200D3FFDF7A
+:10412000E06840F825606078401C6070284670BDEB
+:104130002DE9FF5F1D468B460746FF24FFF7A7FAD0
+:10414000DFF8B891064699F80100B84200D8FFDFC1
+:1041500000214FF001084FF00C0A99F80220D9F81D
+:1041600008000EE008EB0113C35CFF2B0ED0BB422E
+:1041700005D10AEB011350F803C0DC450CD0491CF3
+:10418000C9B28A42EED8FF2C02D00DE00C46F6E709
+:1041900099F803108A4203D1FF2004B0BDE8F09FD4
+:1041A0001446521C89F8022008EB04110AEB041291
+:1041B000475440F802B00421029B0022012B01EB7E
+:1041C00004110CD040F801204FF4007808234FF080
+:1041D000020C454513D9E905C90D02D002E045504E
+:1041E000F2E7414606EB413203EB041322F07F4233
+:1041F000C250691A0CEB0412490A81540BE005B94C
+:10420000012506EB453103EB041321F07F41C1503A
+:104210000CEB0411425499F800502046FFF76CFE55
+:1042200099F80000A84201D0FFF7BCFE3846B4E779
+:1042300070B50C460546FFF72AFA06462146284681
+:10424000FFF796FE0446FF281AD02C4D082101EBFB
+:104250000411A8684158304600F058F800F5805025
+:10426000C11700EBD14040130221AA6801EB0411F1
+:10427000515C09B100EB4120002800DC012070BD39
+:10428000002070BD2DE9F04788468146FFF770FE9B
+:104290000746FF281BD0194D2E78A86831463446B2
+:1042A00005E0BC4206D0264600EB06121478FF2C2F
+:1042B000F7D10CE0FF2C0AD0A6420CD100EB011084
+:1042C00000782870FF2804D0FFF76CFE03E0002080
+:1042D00030E6FFF7D9F941464846FFF7A9FF012329
+:1042E000A968024603EB0413FF20C854A878401EB7
+:1042F000B84200D1A87001EB041001E0140A0020BC
+:1043000001EB061100780870104613E6081A000247
+:10431000C11700EB116000127047000070B5044631
+:10432000A0F500002D4EB0F1786F02D23444A4F510
+:1043300000042B48844201D2012500E0002500F052
+:1043400043F848B125B9B44204D32648006808E0D0
+:10435000012070BD002070BD002DF9D1B442F9D309
+:1043600021488442F6D2F3E710B50446A0F50000D8
+:10437000B0F1786F03D219480444A4F5000400F0AA
+:1043800023F84FF0804130B11648006804E08C42B9
+:1043900004D2012003E014488442F8D2002080F0C7
+:1043A000010010BD10B520B1FFF7DEFF08B10120FC
+:1043B00010BD002010BD10B520B1FFF7AFFF08B150
+:1043C000012010BD002010BD08480949006888423E
+:1043D00001D101207047002070470000000000203C
+:1043E000006002002000002008000020B000002033
+:1043F000BEBAFECA0548064A0168914201D10021B1
+:10440000016004490120086070470000B0000020EE
+:10441000BEBAFECA40E50140534800210170417018
+:1044200010218170704770B5054616460C46022073
+:10443000EEF7D7F94C49012008704C49F01E08608E
+:104440004B480560001F046070BD10B50220EEF7F8
+:10445000C8F945490120087046480021C0F80011FC
+:10446000C0F80411C0F8081143494FF40000086077
+:1044700010BD3D480178C9B1404A4FF400011160B8
+:104480003C49D1F800310022002B1CBFD1F8043187
+:10449000002B02D0D1F8081111B14270102103E0B5
+:1044A0000121417036490968817002700020EEF7E1
+:1044B00098B92D480178002904BF407870472D48ED
+:1044C000D0F80011002904BF02207047D0F8001175
+:1044D00000291CBFD0F80411002905D0D0F808012C
+:1044E000002804BF01207047002070471E4800B517
+:1044F0000278204B4078C821491EC9B282B1D3F856
+:1045000000C1BCF1000F10D0D3F8000100281CBF7F
+:10451000D3F8040100280BD0D3F8080150B107E00C
+:10452000022802D0012805D002E00029E4D1FFDFF3
+:10453000002000BD012000BD0B480178002904BF08
+:10454000807870470B48D0F8001100291CBFD0F8C4
+:104550000411002902D0D0F8080108B110207047DA
+:1045600007480068C0B27047B400002010F5004052
+:1045700008F5004000F0004004F5014008F5014056
+:1045800000F400404C48002101704170704770B544
+:10459000064614460D460120EEF723F9474806600B
+:1045A000001D0460001D056070BD70B54249012505
+:1045B0000D7040EA0241424A41F080711160414C65
+:1045C0000026C4F80461404A4FF040711160002891
+:1045D00002BFC4F80052256070BD012818BFFFDF7C
+:1045E000C4F8006225604FF000703849086070BD63
+:1045F0003148017879B1344A4FF040711160314946
+:10460000D1F804210021002A08BF417002D0304AAD
+:104610001268427001700020EEF7E3B82648017876
+:10462000002904BF407870472648D0F804010028CC
+:1046300008BF704726480068C0B27047002808BF0E
+:10464000704730B51C480078002808BFFFDF1D48C0
+:10465000D0F80411002918BF30BD0224C0F804436B
+:10466000DFF870C0DCF80010C1F30015DCF80010B2
+:1046700041F01001CCF80010D0F80411002904BF5B
+:104680004FF400414FF0E02207D100BFC2F8801282
+:1046900020BFD0F80431002BF8D02DB9DCF8001081
+:1046A00021F01001CCF80010C0F8084330BD0549D6
+:1046B0000120886070470000B700002008F5004026
+:1046C00004F5004000F0004008F5014004F5014009
+:1046D00000F4004010ED00E010B5FF480024012177
+:1046E0004470047044728472C17280F82140846204
+:1046F000446314300FF004FFF849601E0860091D80
+:104700000860091D0C60091D0860091D0C60091D69
+:104710000860091D0860091D0860091D0860091D61
+:104720000860091D0860091D0860091D0860091D51
+:10473000086010BDEA48016801F00F01032904BFB9
+:1047400001207047006800F00F00042804BF022019
+:10475000704700B5FFDF012000BD30B4DE490268BC
+:10476000DFF884C34A6142688A61007A08770A7D6B
+:10477000DC4BACF1040401204AB10A7E00FA02F2DB
+:104780001A608D7D002D0CBF2260CCF800204A7D80
+:10479000002A04BF30BC70474A7E90401860C97D33
+:1047A00000290CBF2060CCF8000030BC704730B549
+:1047B00000250446012904D002290CBF4FF0807562
+:1047C000FFDF45F4847040F48010C849086044F469
+:1047D0004030091D40F00070086030BD30B5002544
+:1047E0000446012904D002290CBF4FF08075FFDF79
+:1047F00045F4847040F48010BC49086044F44030B3
+:10480000091D40F000700860B948D0F80001002888
+:1048100018BFFFDF30BD2DE9F04102264FF0E02741
+:1048200001240025C7F88061B248056004600EF0DD
+:1048300077FDB14918B1086840F4806008600868E5
+:1048400020F0770040F0880040F0004008600EF053
+:1048500051FD30B1A948016821F47F4141F4B051C4
+:1048600001600EF047FD9C4940B1A5484E770660B7
+:10487000A54AA4481060121FA4481060A44A40F240
+:104880005B601060121F40F203101060101F046084
+:10489000934A032010609F4A96201060487F0028AA
+:1048A00014BF4FF4C0209C4840F440209B4A106045
+:1048B0009C4A9B481060121F9B481060C7F880629A
+:1048C0008B4A1020C2F8040381F82D50BDE8F08116
+:1048D0009648016821F0010141F080710160704744
+:1048E0007D4A0368C2F802308088D0801172704718
+:1048F000794B10B51A7A8A4208D101460622981CD3
+:104900000FF02AFC002804BF012010BD002010BDBC
+:10491000714890F8210070476F4A517010707047CD
+:10492000F0B50546800000F1804000F580508B888E
+:10493000C0F820360B78D1F8011043EA0121C0F805
+:10494000001605F10800012707FA00F6784C002A46
+:1049500004BF2068B04304D0012A18BFFFDF2068DD
+:1049600030432060206807FA05F108432060F0BD5D
+:104970000EF096BF584890F82E007047564890F8B1
+:10498000300070476B4AC178116000686A490002C4
+:1049900008607047252808BF02210ED0262808BFCE
+:1049A0001A210AD0272808BF502106D00A2894BF10
+:1049B0000422062202EB4001C9B2604A116060493C
+:1049C00008607047F0B4444B9D7A012D61D0022DF0
+:1049D0001CBFF0BC704793F815C0BCF1000F04BFBA
+:1049E000F0BC70474FF47A7C012D564C564F57D08F
+:1049F000DE7D5D7E002E18BF0126012908BF29211A
+:104A00000CD0022A0CBF514C012A03D0042A0CBF3F
+:104A10003C464F4C04F2E141B1FBFCF1491F084414
+:104A20004C4908604C490020C1F84C01280286F02E
+:104A3000010140EA015040F00311187F820002F1A9
+:104A4000804202F5C042C2F81015444901EB8002D1
+:104A5000997EC80000F1804000F5F830C0F81425B8
+:104A6000DFF8FCC0C0F810C5D87EC30003F1804356
+:104A700003F5F833C3F814252B4AC3F81025012297
+:104A800002FA01F102FA00F0084336490860F0BC6E
+:104A9000704793F814C0BCF1000FA3D1F0BC70476D
+:104AA0009E7D1D7E002E18BF0126012965D0022A99
+:104AB00004BF2D4C4FF47A710CD0012A08BF4FF47B
+:104AC000C86107D0042A07BF3C4640F69801274C2E
+:104AD00040F6E44121444BE0240A0020000E00404F
+:104AE00010150040180500500C050050141500402A
+:104AF00000100040FC1F00403C17004040170040E1
+:104B000060150040448000409CF5014028110040A1
+:104B100038150040441500400000040408F5014029
+:104B200040800040A4F5014010110040741700407F
+:104B300040160040241500401C1500400815004098
+:104B400054150040A2240200D0FB010004360200EC
+:104B5000C0D401004C85004000800040006000404F
+:104B60004C81004004F501406836020030D301005A
+:104B700001F5FA71B1FBFCF150E7022A08BF4FF4CE
+:104B80007A710AD0012A08BF4FF4C86105D0042AFF
+:104B90000CBF40F6980140F6E44149F6FC6211442E
+:104BA000E8E72DE9F047FC4E80460320154689468C
+:104BB000C6F80002F94F787F002814BF4FF4C020D8
+:104BC000F748F849086048460EF0A5FE28460EF062
+:104BD00095FE0124B8F1000F03D0B8F1010F16D0F3
+:104BE00018E00EF087FB78B1EF490A684806022DFD
+:104BF000D0F820030CBFC0F30660C0F3062022F4F7
+:104C0000FE4242EA00200860BC72346002E00220EA
+:104C1000B8727460E548C464E54800682A464946AD
+:104C2000BDE8F047CEE62DE9F0418846DA4907466F
+:104C300003201546C1F80002D84C607F002814BF3D
+:104C40004FF4C020D648D74E306040460EF063FE89
+:104C500028460EF053FE17B1012F1CD024E00EF0B1
+:104C600049FB78B1D04A11685006022DD0F82003D4
+:104C70000CBFC0F30660C0F3062021F4FE4141EAF8
+:104C8000002010600120A072606B40F4801060630F
+:104C90004FF4801007E00220A072606B40F4001017
+:104CA00060634FF4001030602A464146BDE8F04191
+:104CB000002087E62DE9FF4FB74C8346002581B0E1
+:104CC00003208946C4F80002B44E707F002814BF48
+:104CD0004FF4C020B248B34F386003980EF01BFE6B
+:104CE00004980EF00BFEDFF8CCA24FF00108BBF1E8
+:104CF000000F03D0BBF1010F35D046E00EF0FAFAF9
+:104D000080B1A94A0498116853060228D3F82003F9
+:104D10000CBFC0F30660C0F3062021F4FE4141EA57
+:104D200000201060CAF8004096F82D00012806D037
+:104D3000022818BFFFDF0CD086F80A8025E0DDE9E5
+:104D4000031396F82C2048460EF066FEB16A45180B
+:104D5000F2E7DDE9031296F82C3048460EF0EAFD42
+:104D6000B16A4518E8E79448CAF8000096F82D00A3
+:104D7000DDE90313012896F82C20484624D00EF0D4
+:104D800095FEB16A45180220B0728C4805608D49C5
+:104D90008B480860706B40F400207063D4F8009278
+:104DA0004FF0100AC4F808A30026C4F80062864831
+:104DB0004FF4802BC0F800B0FF208DF80000C4F83D
+:104DC0001061C4F810800AE00EF0F2FDB16A4518D7
+:104DD000D9E700BF9DF80000401E8DF800009DF847
+:104DE000000018B1D4F810010028F3D09DF800009D
+:104DF000002808BFFFDFC4F80061C4F80C61C4F8E4
+:104E00001061C4F80461C4F81461C4F818610EF0AC
+:104E100071FA002818BFC4F828616C480068009037
+:104E2000C4F80092C7F800B0C4F804A34FF40020FF
+:104E300038605E48C0F84C805D480068A84228BFD2
+:104E4000FFDF2846DDE9031205B0BDE8F04FB9E504
+:104E50002DE9F84F504CD4F8000220F00B09D4F89B
+:104E600004034FF0100AC0F30018C4F808A300268A
+:104E7000C4F80062494D687F002814BF4FF4C02079
+:104E8000474840F4402150480160A97A0127012990
+:104E900002D0022903D014E0297D11B911E0697D07
+:104EA00079B1A97EEA7E07FA01F107FA02F211430D
+:104EB0000160287F800000F1804000F5C040C0F80C
+:104EC0001065FF208DF80000C4F81061276104E030
+:104ED0009DF80000401E8DF800009DF8000018B1FC
+:104EE000D4F810010028F3D09DF80000002808BF76
+:104EF000FFDFC4F810610EF0FDF9002818BFC4F8F8
+:104F000028616E72AE72EF72C4F80092B8F1000FB1
+:104F100018BFC4F804A3BDE8F88F00682C4920F03E
+:104F20007F40086070474FF0E0200221C0F88011F8
+:104F3000C0F8801270474FF0E0210220C1F8000154
+:104F4000704724490870704723490860704730B59E
+:104F5000124C0546A06AA84228BFFFDF012020733B
+:104F60002561607F40B1284420610B48D0F80012D1
+:104F700041F04001C0F800120C490020C1F8440182
+:104F8000164920690860606B064940F48000606340
+:104F90004FF48000086030BD00100040240A00205B
+:104FA0000000040404F50140881500400080004022
+:104FB0004C850040ACF5014004100040488500409D
+:104FC00048810040A8F5014008F501401811004053
+:104FD0003C150040B9000020041500404485004005
+:104FE00070B505460E460220FE4C2073FE4801684F
+:104FF00001F00F01032908BF012207D0006800F06B
+:105000000F0004280EBF0222FFDF012294F82D00BA
+:1050100094F82C10012819D028460EF0A5FD206127
+:10502000607F48B1216908442061F048D0F800123F
+:1050300041F04001C0F80012ED490020C1F84401E0
+:105040002169A06A0844EB49086070BD33462846D0
+:105050000EF053FDE3E7E8494FF480000860E148B3
+:10506000416B21F480014163002101737047C2004C
+:1050700002F1804202F5F832E04BC2F81035C2F876
+:10508000141501218140DE480160D648426B11436E
+:1050900041637047D64801214160C1600021C0F8DA
+:1050A0004411D4480160CF488162704710B504466E
+:1050B0000EF020F900281CBFCA484477D14804608C
+:1050C000CA48D0F8001241F04001C0F8001210BDEB
+:1050D000C64810B5D0F8001221F04001C0F8001207
+:1050E0000EF008F9C749002818BF0220086010BD5B
+:1050F000BE48D0F8001221F01001C0F800120121C2
+:1051000081617047B9480021C0F81C11D0F8001225
+:1051100041F01001C0F800127047B44981B0D1F8D5
+:105120001C21012A1EBF002001B07047B64A126838
+:1051300002F07F02524202700020C1F81C01B34805
+:1051400000680090012001B0704730B50C000546A2
+:1051500008BFFFDF14F0010F1CBF012CFFDF002D83
+:105160000CBF012002209F4901284872CC729F4940
+:1051700004BFD1F8000240F0040007D0022807BFA6
+:10518000D1F8000240F00800FFDF30BDC1F8000296
+:1051900030BD2DE9F84FDFF8789299F80000042827
+:1051A00028BFFFDFDFF848A2DAF84C1192488D4C97
+:1051B00000274FF00108D1B1A17A012902D00229BC
+:1051C00003D014E0217D11B911E0617D79B1A17E98
+:1051D000E27E08FA01F108FA02F211430160217F30
+:1051E000890001F1804101F5C041C1F81075824884
+:1051F000616B01606763217B002019B1DAF844110B
+:10520000012900D00021A27A784E012A6ED0022A0C
+:1052100074D000BFD6F8101101290CBF1021002155
+:1052200041EA00057B48016811F0FF0F03D0D6F872
+:105230001411012900D0002184F82E10006810F00C
+:10524000FF0F03D0D6F81801012800D0002084F801
+:105250002F007148006884F83000FFF72AF9012810
+:1052600018BF002084F83100C6F80071C6F80C7130
+:10527000C6F81071C6F80471C6F81471C6F8187132
+:105280000EF038F8002818BFC6F828716348006887
+:1052900000905748C0F8447161480068DFF854A195
+:1052A0000090DAF800006062617F00291CBF401A9C
+:1052B00060625C480068A0624B48016801F00F0121
+:1052C000032908BF012007D0006800F00F00042860
+:1052D0000EBF0220FFDF012084F82C00A07ADFF847
+:1052E00048B184F82D00022824D116E0D6F80C012C
+:1052F000012814BF002008208CE7FFE7D6F80C0136
+:10530000012814BF00200220484A1268012A14BF55
+:1053100004220022104308437CE7607850B1DBF898
+:10532000001009780840217831EA000008BF84F8AD
+:10533000208001D084F8207015F0020F07D099F872
+:1053400000103B4A4908606A52F82110884715F05E
+:10535000010F18BF00210DD0364A99F80030A06A1D
+:1053600052F82320904700BF99F8000010F0010F79
+:105370002AD10AE015F0020F18BF0121ECD115F077
+:10538000080F18BF0221E7D1EEE7DBF80000007834
+:1053900000F00F00072828BF84F8217014D2DBF832
+:1053A0000000062200F10901A01C0EF0D5FE40B954
+:1053B000207ADBF800100978B0EBD11F08BF01207C
+:1053C00000D0002084F82100E17A002011F0020FC3
+:1053D0001CBF15F0020F15F0040F45D111F0100F8E
+:1053E0002AE00000240A00201015004000100040B0
+:1053F000008000404485004008F501400411004051
+:1054000004F5014060150040481500401C110040A3
+:10541000B900002040160040101400401811004050
+:1054200044810040408500400415004000140040C5
+:1054300008480200504802001CBF94F82F20002AA0
+:1054400002D094F831207AB111F0080F1CBF94F803
+:105450002020002A08D111F0040F02D094F8211066
+:1054600011B115F0010F00D00120617A19B198B186
+:10547000FFF7EEFC1EE0607F002814BF4FF4C02150
+:105480007F4980480160D6F8000220F00300C6F88A
+:10549000000284F80B800DE04FF0000B012913D0BF
+:1054A000022918BFFFDF21D0A06A01225844002141
+:1054B000FFF788FA15F0010F2BD0734899F8001008
+:1054C00050F82100804745E0D6F8000220F00400A3
+:1054D000C6F80002677284F80B80012384F80A8002
+:1054E0001A46002196200EF025FA10E0D6F80002A8
+:1054F00020F00800C6F80002677284F80B800220D2
+:10550000A07201231A46002196200EF051FA83461C
+:10551000CAE715F0020F08D05C4999F8002028EA84
+:10552000950051F82210884714E015F0080F06D0B6
+:10553000574899F8001050F8210080470AE015F00C
+:10554000100F08BFFFDF05D0524899F8001050F83F
+:1055500021008047A07A022818BFBDE8F88F207B81
+:10556000002808BFBDE8F88F4B49C1F844710228F4
+:1055700014D0012818BFFFDFA16A2069884298BFB4
+:10558000FFDF2069CAF80000606B444940F48000E6
+:1055900060634FF480000860BDE8F88F2169A06A5D
+:1055A0000844EFE738B500253D4C002818BFC4F883
+:1055B0000052C4F80051C4F80C51C4F81051C4F89A
+:1055C0000451C4F81451C4F818510DF093FE00288A
+:1055D00018BFC4F8285133480068009038BD01282E
+:1055E00004BF28207047022804BF1820704700B568
+:1055F000FFDF282000BD012804BF41F6A4707047DA
+:10560000022804BF41F28830704700B5FFDF41F641
+:10561000A47000BD012804BF41F2D4707047022875
+:1056200004BF41F20400704700B5FFDF41F2D470BF
+:1056300000BD012812BF02280020704700B5FFDF1F
+:10564000002000BD16490820C1F800021648407F1E
+:10565000002814BF4FF4C02009480A4908601449C3
+:1056600012480860091D13480860091D12480860A7
+:10567000091D1248086009494FF44020086070472E
+:105680000000040408F50140104802002048020010
+:1056900030480200404802000080004004F501400C
+:1056A0000010004018110040240A002000110040A2
+:1056B000A0F50140141000401C11004010100040E3
+:1056C00010B53F4822210EF0F2FD3D48017821F04F
+:1056D00010010170012107F017FC3A49002081F800
+:1056E00022004FF6FF70888437490880488010BD3B
+:1056F000704734498A8C824218BF7047002081F875
+:1057000022004FF6FF70888470472D490160704772
+:105710002D49088070472B498A8CA2F57F43FF3BB7
+:1057200003D0002101600846704791F822202549E6
+:10573000012A1ABF0160012000207047214901F1B0
+:10574000220091F82220012A04BF00207047012284
+:1057500002701D4800888884104670471A494880A6
+:1057600070471849184B8A8C5B889A4206D191F889
+:105770002220002A1EBF01600120704700207047D0
+:105780001048114A818C5288914209D14FF6FF711D
+:10579000818410F8221F19B1002101700120704787
+:1057A000002070470748084A818C5288914205D1F1
+:1057B00090F8220000281CBF00207047012070478D
+:1057C000820A00205C0A0020BA0000207047574A75
+:1057D000012340B1012818BF70471370086890601A
+:1057E00088889081704753700868C2F802008888E2
+:1057F000D08070474D4A10B1012807D00EE0507894
+:1058000060B1D2F802000860D08804E0107828B1B6
+:105810009068086090898880012070470020704758
+:10582000424910B1012803D006E0487810B903E0DE
+:10583000087808B1012070470020704730B58DB05E
+:105840000C4605460D2104A80EF053FDE0788DF8B6
+:105850001F0020798DF81E0060798DF81D002868E2
+:10586000009068680190A8680290E8680390684614
+:105870000DF0C2FB20789DF82F1088420CD1607883
+:105880009DF82E10884207D1A0789DF82D108842EF
+:1058900002BF01200DB030BD00200DB030BD30B5CD
+:1058A0000C4605468DB04FF0030104F1030012B120
+:1058B000FEF7F0F901E0FEF70CFA60790D2120F017
+:1058C000C00040F04000607104A80EF012FDE078C6
+:1058D0008DF81F0020798DF81E0060798DF81D006D
+:1058E0002868009068680190A8680290E8680390B2
+:1058F00068460DF081FB9DF82F0020709DF82E006A
+:1059000060709DF82D00A0700DB030BD10B500295D
+:1059100004464FF0060102D0FEF7BCF901E0FEF7A5
+:10592000D8F9607920F0C000607110BDBE00002081
+:1059300070B5F84E0446306890F800110025012932
+:1059400019D090F8FA10012924D090F8D01001292C
+:105950002AD090F8F21001291CBF002070BD65709C
+:1059600017212170D0F8F4106160B0F8F81021818F
+:1059700080F8F25016E065701C212170D0F80111FA
+:105980006160D0F80511A16090F80911217380F8C9
+:10599000005107E0657007212170D0F8FC106160AC
+:1059A00080F8FA50012070BD65701421217000F15B
+:1059B000D2012022201D0EF0FBFB01212172306854
+:1059C00080F8D050D448B0F8D420A0F8FC207268F9
+:1059D000537B80F8FE3080F8FA101088FBF71AF934
+:1059E000FAF7C1FDDEE7CB48006890F8D010002937
+:1059F00014BFB0F8D4004FF6FF70704770B5C54CB7
+:105A00002068002808BFFFDF0025206845700028B7
+:105A100008BFFFDF2068417800291CBFFFDF70BD91
+:105A20004FF486710EF065FC2068FF2101707F2124
+:105A300080F8361013214184282180F8CC100121F0
+:105A400080F8B81080F8BD50FFF742FBFEF711FD5B
+:105A5000B24806F0E5FFB24806F0E2FFBDE870404C
+:105A6000B04806F0DDBFAB490968097881420CBF38
+:105A7000012000207047A748006890F82200C0F37A
+:105A8000001070472DE9F04FA248016891F82400FA
+:105A9000B1F822C0C0F38002C0F340031A4400F002
+:105AA00001001044CCF300121AB3BCF1130F1BD049
+:105AB0000BDCBCF1100F02BF9B4931F81000BDE8B0
+:105AC000F08FBCF1120F0FD00AE0BCF1150F08BF28
+:105AD00096490AD0BCF11D0F04BF9548BDE8F08F70
+:105AE000FFDF0020BDE8F08F924931F81000BDE8DB
+:105AF000F08F002491F8BA2091F8BB108E4E8F4F92
+:105B00001CF0030F4FF47A7B4FF0190A25464FF42F
+:105B1000C8784FF4BF794FF018037DD01CF0010F07
+:105B20001BD0082904BF44464FF0400C0FD0042975
+:105B300004BF4C464FF0100C09D0022907BF05F1F5
+:105B400018044FF0040C05F128044FF0080C0CEB7E
+:105B50004C0E0EEB0C1CA44417E0082904BFC446ED
+:105B600040240CD0042904BFCC46102407D00229BD
+:105B700007BF05F1180C042405F1280C082404EBD8
+:105B8000C40404EB44040CEB440C022A04BF6C4E26
+:105B90004FF47A740CD0012A08BF4FF4C86407D0C0
+:105BA000042A07BF674E40F698043E4640F6E44498
+:105BB000344404F2E734B4FBFBF4C0EB001606EB0C
+:105BC000860604EB8604082A30D0042A29D0022A4B
+:105BD00007BF05F11802042505F128024FF0190A44
+:105BE00018BF08251AFB052212FB0040082922D005
+:105BF000042925D0022904BF0421C03004D0282361
+:105C000003F5A87108440821C1EBC10101EB410172
+:105C100003EB4101084400E017E0604400F52674FE
+:105C200018E04A464FF0140A1025DBE742464FF0D1
+:105C3000140A4025D6E74346402100F53D60E3E7DE
+:105C40004B46102100F57C70DEE71CF0020F18BFF8
+:105C5000FFDF02D02046BDE8F08F022A04BF384E95
+:105C60004FF47A7C0CD0012A08BF4FF4C86C07D0DF
+:105C7000042A07BF334E40F6980C3E4640F6E44CEB
+:105C8000B4440CF2E73CBCFBFBFCC0EB001404EB9F
+:105C900084040CEB840C082A04BF4FF0140A402241
+:105CA0000CD0042A29D0022A07BF05F118080422C3
+:105CB00005F128084FF0190A18BF08221AFB0282C2
+:105CC00012FB00C0082904BF4FF4A87340210AD07A
+:105CD000042904BF4FF4A873102104D002290EBF79
+:105CE000042128230821C1EBC10101EB410103EB91
+:105CF0004101084400F5B274ACE7C8464FF0140AFD
+:105D00001022DBE7034840F271210068806A4843B3
+:105D100070470000CC000020A40A0020B00B002037
+:105D2000D80B0020000C0020744802007C480200C0
+:105D3000F18913006C480200A224020030D3010054
+:105D400068360200D0FB0100F848006890F8350082
+:105D5000002818BF0120704710B5F54C207B0228A1
+:105D600018BF032808D1207D04F1150105F018FDA6
+:105D700008281CBF012010BD207B002816BF022868
+:105D800000200120BDE81040FFF74ABDE74909683F
+:105D900081F8300070472DE9F047E44D2968087B11
+:105DA000002816BF02280020012048730E31FFF79B
+:105DB00021FD2968087B022816BF03280122002242
+:105DC00081F82F20082081F82D00487B012600272C
+:105DD00001F10E03012804BF5B7913F0C00F0AD054
+:105DE00001F10E03012804D1587900F0C0004028C9
+:105DF00001D0002000E0012081F82E00002A04BF1D
+:105E000091F8220010F0040F06D0087D153105F03E
+:105E1000C7FC296881F82D0028684760FCF7F8FE68
+:105E20002968C34C4FF00009886094F82D0005F0F4
+:105E3000D3FC804694F82F00002818BFB8F1000F5B
+:105E400004D01021404606F050FB68B194F83000B1
+:105E500000281CBF94F82E0000281DD0607B04F1A0
+:105E60000E0101280ED012E066734A4604F10E01BD
+:105E70004046FFF714FD94F82D1004F10E0005F0D4
+:105E8000A4FD09E0487900F0C000402831D039462F
+:105E900004F10E00FFF73AFD2868C77690F822005B
+:105EA00010F0040F08BFBDE8F087002794F82D001C
+:105EB00005F09BFC040008BFBDE8F087102106F048
+:105EC00014FB002818BFBDE8F08728683A4600F1A7
+:105ED0001C01C6762046FFF7E2FC286800F11C0191
+:105EE000944806F0D4FDBDE8F0470121914806F042
+:105EF000E9BD05F0A3FD4A4604F10E01FFF7CFFC12
+:105F0000CAE778B58A490446884D407B08732968FA
+:105F1000207808706088ADF8000080B200F00102BF
+:105F2000C0F3400342EA4302C0F3800342EA830223
+:105F3000C0F3C00342EAC302C0F3001342EA0312F3
+:105F4000C0F3401342EA4312C0F3801042EA8010CB
+:105F50004884E07D012808BF012603D0022814BF31
+:105F6000FFDF0226286880F8BA60607E012808BF3B
+:105F7000012603D0022814BFFFDF0226286880F81C
+:105F8000BB60217B80F82410418C1D290CBF0021AF
+:105F900061688162617D80F83510A17B002916BFA0
+:105FA0000229002101210175D4F80F10C0F8151045
+:105FB000B4F81310A0F81910A17EB0F8CE2061F348
+:105FC0000302A0F8CE20E17E012918BF002180F84D
+:105FD0003410002078BD55480068408CC0F3001193
+:105FE00019B110F0040F05D002E010F0020F01D03B
+:105FF00000207047012070474C4A00231268C2F805
+:10600000C030B2F822C0BCF11D0F02BFC2F8C830C8
+:1060100082F8C4307047002908BFC2F8C8300AD0DF
+:10602000936A40F2712C03FB0CF31944491EB1FB37
+:10603000F3F1C2F8C81082F8C400704703463B4829
+:1060400010B50168D1F8C820002A1ABFD1F8C0C025
+:10605000BCF1000F012405D09A4205D90124D01AC1
+:10606000C1F8C800204610BD91F82210002411F09C
+:10607000010F1CBF406800884FF0430108BF00209B
+:1060800001F009F9EEE72948006890F8B700002808
+:106090000CBF01200020704770B51F2834BF044694
+:1060A0001F240022214D286880F8B920224678302C
+:1060B0000EF07EF82868012180F8974080F8B9102A
+:1060C00070BD10B51F2828BF1F20C2B2174C002377
+:1060D000206880F8B83080F8B72098300EF068F863
+:1060E0002168012081F8B80010BD1049096881F8C5
+:1060F000BD0070470D48006890F8220000F00100D4
+:1061000070470A48006890F82200C0F340007047CA
+:106110000648006890F82200C0F34010704703481A
+:10612000006890F82200C0F3C0007047CC00002047
+:10613000A40A0020B00B002001207047F748006837
+:1061400090F8BB00704770B5FEF7A4FFFEF783FF21
+:10615000FEF77EFEFEF7E7FEF04C2068D0F8C01098
+:10616000491CC0F8C01090F83300002530B1FEF78C
+:10617000AFFFFEF77EF9206880F833502068457045
+:1061800090F8C410F9B1D0F8C02091421BD8042077
+:1061900002F050FA206890F8220010F0010F0CD0A5
+:1061A00060684321008801F076F860680088FAF79B
+:1061B00031FDBDE87040FAF7C7B9BDE87040432132
+:1061C000002001F068B8D0F8C81019B1D0F8C0208C
+:1061D000914202D990F83700D8B1042002F02AFA8F
+:1061E000206890F8220010F0010F0CD060683C216C
+:1061F000008801F050F860680088FAF70BFDBDE8F0
+:106200007040FAF7A1B9BDE870403C21002001F0D0
+:1062100042B8BDE87040002002F00CBA2DE9F84FFA
+:10622000BE4E8046174630688B464FF0000A458CBC
+:1062300015F0030F10D015F0010F05F0020005D086
+:10624000002808BF4FF0010A06D004E0002818BF5C
+:106250004FF0020A00D1FFDF4FF000094C4615F065
+:10626000010F05F002000BD070B915F0040F0BD030
+:1062700049F00800002F18BF40F0030440D090E020
+:1062800010B115F0040F0DD015F0070F10D015F058
+:10629000010F05F0020036D0002808BF15F0040FEA
+:1062A00027D03DE0002F18BF49F0090479D134E030
+:1062B0002FB149F0080415F0200F14D071E03168B7
+:1062C00005F0200291F87700104308BF49F001045F
+:1062D00067D049F0180415F0200F62D191F8BA1078
+:1062E00008295AD156E0316891F8BA10082951D1DD
+:1062F00053E049F00800002F18BF40F0010450D1CE
+:1063000040F010044DE0002818BF15F0040F07D02E
+:10631000002F18BF49F00B0443D149F0180440E0A6
+:1063200015F0030F3CD115F0040F39D077B1316867
+:1063300049F0080091F8BA1008290CBF40F0020497
+:1063400020F0020415F0200F22D02AE0316805F079
+:10635000200291F87700104308BF49F0030420D0D1
+:1063600049F0180015F0200F09D000BF91F8BA10BD
+:10637000082914BF40F0020420F0020411E091F853
+:10638000BA20082A14BF40F0010020F00100EDE718
+:10639000082902D024F0010403E044F0010400E0E5
+:1063A000FFDF15F0400F18BFFFDFA8F8009098F846
+:1063B0000000072120F0200088F80000404606F089
+:1063C00034FB5146404606F033FD2146404606F078
+:1063D00038FD14F0010F0CD03068062300F10E01D7
+:1063E0000022404606F00AFD3068417B404606F038
+:1063F0005CFB14F0020F1BD03068BBF1000F0BD018
+:1064000000F11C0106230122404606F0F7FC0121A1
+:10641000404606F057FB0BE000F115010623012270
+:10642000404606F0EBFC3068017D404606F04AFB32
+:1064300014F0040F18BFFFDF14F0080F17D0CDF8C9
+:1064400000903068BDF800100223B0F8CE000209B9
+:1064500062F30B01ADF800109DF80110032260F308
+:1064600007118DF801106946404606F0C7FC012F60
+:1064700016D1306890F8770090B1404606F0D4FC11
+:106480003368401CC0B293F87710C0F125008142F8
+:10649000B8BF084682B203F15801404606F0FFFC3F
+:1064A0000020002818BFFFDF0020002818BFFFDFF2
+:1064B0000020002818BFFFDFBDE8F88F2DE9F84362
+:1064C000164C2068002808BFFFDF2068417811BB08
+:1064D0000178FF291FD0002780F83170877080F87D
+:1064E00037703846FEF72DFDFEF795F9206890F9D4
+:1064F000BD00FEF73DFA0A48FEF744FA0948FEF7E8
+:106500000CFD206890F8240010F0010F0CD025201D
+:10651000FEF740FA10E00C20BDE8F883CC00002024
+:10652000684802006548020010F0020F18BF2620DC
+:1065300068D000BFFEF72EFA206890F8BA10252028
+:10654000FEF735F9206880F82C70FEF7F4FC20681F
+:10655000002190F8BA200846FEF765FB0F210520C0
+:10656000FEF7DAF92068FF4D012690F82E10002979
+:1065700001BF90F82F10002990F8220010F0040FAE
+:1065800070D0FCF745FB8046206841468068FDF7E7
+:106590004DF8F54990FBF1F901FB190041424046E5
+:1065A000FCF73FF80146206881604168494441603A
+:1065B00005F0F3F801462068426891426DD8C0E9C1
+:1065C00001784FF0010895F82D0005F005F9814696
+:1065D00095F82F00002818BFB9F1000F04D0102142
+:1065E000484605F082FFA0B195F8300000281CBF96
+:1065F00095F82E00002824D0687B05F10E010128B3
+:1066000015D019E010F0040F14BF2720FFDF91D13F
+:1066100092E732466E7305F10E014846FFF73FF9E7
+:1066200095F82D1005F10E0005F0CFF909E0487935
+:1066300000F0C000402816D0414605F10E00FFF7DB
+:1066400065F9206890F8220010F0040F25D095F825
+:106650002D0005F0CAF85FEA00081ED0102105F0F1
+:1066600044FF40B119E005F0E9F9324605F10E01A9
+:10667000FFF715F9E5E72068324600F11C01C67600
+:106680004046FFF70CF9206800F11C01B74806F0FE
+:10669000FEF90121B54806F015FA2068417B0E305D
+:1066A000FEF71EF9206890F8B81079B390F8B7207B
+:1066B00080F8772000F1980158300DF0BEFD206879
+:1066C00090F82210C1F30011E9B9B0F8CE00022110
+:1066D0000609ADF800606846FDF7DCFA28B1BDF8A0
+:1066E0000000C0F30B00B04204D1BDF80000401C14
+:1066F000ADF800002168BDF80000B1F8CE2060F3CD
+:106700000F12A1F8CE20206880F8B870206890F8A9
+:10671000B91059B190F8972080F8572000F178010E
+:1067200038300DF08AFD206880F8B9702068B0F824
+:10673000CE10D0F8C020090951FA82F190F8BC209F
+:10674000DFF82CC2114463460022E1FB0C3212092F
+:106750006FF0240302FB031180F8BC1090F82210A4
+:10676000824E90F81B80C1F3001106F12809002920
+:106770005DD03780317821F020013170408C1328B2
+:1067800037D01CDC10284DD0122846D0FFDF00BFC8
+:1067900005F10E01754806F06CF9697B734806F047
+:1067A00084F92068418C1D2918BF15297ED090F8E6
+:1067B000772000F15801304606F0ADF97EE015284B
+:1067C00018BF1D28E2D10121304606F02EF930789D
+:1067D000B8F1000F40F020003070206812D000F1B6
+:1067E0001C01304606F053F90121304606F06AF9E3
+:1067F000CEE70021304606F018F9307840F020004E
+:106800003070C5E700F11501304606F040F9206808
+:10681000017D304606F056F9BAE70621304606F00B
+:1068200004F9B5E70221304606F0FFF8B0E7002290
+:1068300041463046FFF7F2FC206890F877100029B7
+:1068400004BF408C10F0010F05D110F0020F08BFFB
+:1068500010F0200F04D0012241464846FFF7DEFC2D
+:10686000F07810F03F0F1CBF307910F0100F25D0DA
+:10687000304606F0D8F82268014692F82400C0F3AA
+:106880008003C0F3400C634400F00100034492F81D
+:106890002C00C0F38002C0F3400C624400F0010001
+:1068A0001044181AC0B200F00AFD00E006E00090A3
+:1068B000032304226946304606F0A0FA206890F8C7
+:1068C0002200C0F30010B0B12A4E042130463780B8
+:1068D00006F0ABF805F10E01304606F0CAF8697B08
+:1068E000304606F0E2F8206800F1380190F85720B1
+:1068F000304606F034F904F0C5FF03211E4805F0C8
+:1069000054F8216881F83300002005E61B494860EF
+:1069100070472DE9F843194C8046206890F83120E3
+:1069200032B1408C1D2808BFFFDFBDE8F8430AE400
+:10693000012639B390F8BC00FEF72CF8206890F8D7
+:10694000BB102520FDF733FF206801224FF496711C
+:1069500090F8BB300020FEF7ADF90948FEF7F4FAD5
+:10696000206810E0A40A002040420F00B00B002075
+:1069700053E4B36E000C0020280C0020CC00002053
+:10698000D80B002005E04670867080F83160BDE8C5
+:10699000F883FE48FEF7D8FA2068002590F8241006
+:1069A00090F82C0021EA000212F0010F18BF012517
+:1069B0000ED111F0020F04D010F0020F08BF022513
+:1069C00006D011F0040F03D010F0040F08BF042507
+:1069D0000027B8F1000F5CD0012D1CD0022D08BF9C
+:1069E00026201CD0042D14BFFFDF272017D02068DD
+:1069F00090F8BA102520FDF7DAFE206890F82210F2
+:106A0000C1F3001171B1002201234FF496711046B9
+:106A1000FEF750F93DE02520FDF7BCFFE7E7FDF765
+:106A2000B9FFE4E790F8BA3001224FF496710020E4
+:106A3000FEF740F9D548C17811F03F0F1CBF00792F
+:106A400010F0100F25D0D14805F0EDFF2368014666
+:106A500093F82420C2F38000C2F3400C604402F09B
+:106A6000010200EB020C93F82C20C2F38000C2F369
+:106A70004003184402F001020244ACEB0200C0B231
+:106A800000F01DFC0090032304226946BF4806F075
+:106A9000B5F9206890F82C10294380F82C1090F854
+:106AA000242032EA010112D04670408C132821D0F4
+:106AB0001CDC102808BFBDE8F88312281AD000BFDC
+:106AC000C0F30010002818BFFFDFBDE8F883418C39
+:106AD0001D2908BF80F82C70E6D0C1F300110029F1
+:106AE00014BF80F8316080F83170DDE7152818BFD9
+:106AF0001D28E5D1BDE8F84301210846FEF725BB76
+:106B0000A34810B50068417841B90078FF2805D046
+:106B100000210846FFF7FDFE002010BDFEF7BAFA7F
+:106B2000FEF799FAFEF794F9FEF7FDF90C2010BD77
+:106B300097490120096881F837007047944909682E
+:106B400081F83200704770B5002501F0E3FB0028A2
+:106B50007CD08F4C2068417800260122012905D085
+:106B6000022901D003297DD0FFDF70BD8178022684
+:106B700039B390F8220010F0030F67D08548FEF774
+:106B8000E3F920680122962190F8BB301046FEF709
+:106B900091F800219620FEF723FA2068467090F8BD
+:106BA000330020B1FDF751FC4020FEF77FFA20684A
+:106BB00090F83400002808BF70BDBDE87040FEF7B3
+:106BC000A1BA418CC1F300129AB1102929D090F8D2
+:106BD000330020B1FDF739FC4020FEF767FA6D481D
+:106BE000FEF7B2F9206890F8221011F0040F1DD0C2
+:106BF00027E090F8242090F82C309A4211D190F898
+:106C00007700002808BF11F0010F05D111F0020F25
+:106C100008BF11F0200F52D0BDE870400121084696
+:106C200077E6BDE870400021012072E690F835005B
+:106C3000012814BF0328102545F00E010020FEF79F
+:106C400084FA206890F83400002801E037E009E079
+:106C500018BFFEF757FA00219620FEF7C1F9206809
+:106C6000467070BD817801B3418C11F0010F21D0C5
+:106C700080F8D02090F8D210B0F8D40000F00BFBD0
+:106C800060680088F9F7C6FFF9F75EFC2068467077
+:106C9000FEF700FAFEF7DFF9FEF7DAF8FEF743F940
+:106CA000BDE87040032001F0C5BC8178BDE87040AC
+:106CB00001202EE611F0020F04BFFFDF70BDBDE81A
+:106CC0007040FFF740BAFFF73EBA10B5304C20686D
+:106CD00090F8341049B13630FEF71FFA18B9216820
+:106CE0007F2081F83600FEF703FA206890F8330021
+:106CF00018B1FEF7EDF9FDF7BCFB01F00BFBA8B1F5
+:106D0000206890F82210C1F3001179B14078022870
+:106D100018BFFFDF00210120FFF7FBFD206841784D
+:106D200000291EBF40780128FFDF10BDBDE81040DC
+:106D3000FFF709BA2DE9F047154F0E4603283A68C8
+:106D4000518C0BD092F8320001F0010410F10009CF
+:106D500018BF4FF001094FF0010805E0C1F34004EE
+:106D60004FF000094FF00208FDF704FE054634EA33
+:106D7000090008BFBDE8F0873868064C90F833007A
+:106D800098B104F064FD3070014605E0B00B0020BE
+:106D9000CC000020280C0020FF2806D0E01C04F0C6
+:106DA0004BFD307804F05EFD05432078C0F3801180
+:106DB0003868027D914209D100F115010622E01CDC
+:106DC0000DF0CAF9002808BF012000D0002031785A
+:106DD000FF2906D0C0B9386890F82D00884215D137
+:106DE00012E098B12078E11CC0F3801004F0D8FCC8
+:106DF000064604F03BFE38B1304604F0F6FC18B10C
+:106E0000102105F072FB08B1012000E00020396874
+:106E100091F8221011F0040F01D0F0B11AE0CDB9B1
+:106E2000FE4890F83500002818BF404515D114F8E9
+:106E3000030B2146C0F3801004F0B2FC044604F0BA
+:106E400015FE38B1204604F0D0FC18B1102105F031
+:106E50004CFB10B10120BDE8F0870020BDE8F087B1
+:106E60002DE9F04FEE4D804683B02868002740782A
+:106E7000022818BFFFDF28687F2490F8341049B13A
+:106E80003630FEF74AF9002804BF286880F83640FB
+:106E9000FEF72EF9E34805F0E8FD0646B8F1000FCD
+:106EA00000F0A381DF4805F079FF002800F09D8104
+:106EB000FDF72EFD002800F098813046D94EFF21C5
+:106EC000DFF864A34FF000084FF0030B4FF0010907
+:106ED000062880F0B981DFE800F0FDFDFD03FD8F9D
+:106EE0008DF8001069460320FFF724FF002828686A
+:106EF0007CD090F8341011B190F8001159B1286885
+:106F0000807801283ED0C948FEF71EF8286880F82E
+:106F100001B000F06EB99DF8003080F80091017862
+:106F200080F80111FF2B10D000F20312511E1846F9
+:106F300004F064FC002808BFFFDF286890F8021105
+:106F400041F0020180F802110DE03178C1F38011A7
+:106F500080F80211B149D1F88721C0F80321B1F8B6
+:106F60008B11A0F80711286800F2091690F8360076
+:106F70007F2808BFFFDF286890F83610317080F84E
+:106F80003640BCE7A94CDAF8049004F12806A4F8CE
+:106F900000800721204605F048FD0021204605F02D
+:106FA00047FF4946204605F04CFF0623002206F124
+:106FB0000901204605F022FF2868417B204605F0A4
+:106FC00074FD286800F1380190F85720204605F03C
+:106FD00066FF2046FDF7B8FF28680122962190F849
+:106FE000BB300020FDF766FE90E7FFE780780028C1
+:106FF00040F0FD8000F0F9B88DF8081002A90520D6
+:10700000FFF798FE0028286800F0EA808278884917
+:10701000002A7DD0A1F11F066C6890F8BB90D6F8CD
+:107020000F00C4F80E00B6F813006082707D207562
+:10703000B07D6075B6F81700E082B6F81900608080
+:10704000B6F81B00A080B6F81D00E08004F108002F
+:107050000DF064FA96F8240000F01F00207696F8F0
+:107060002400400984F86C0184F8549084F8559009
+:10707000286890F8CC1084F8561090F8BD0084F879
+:1070800057009DF80810686800F079F9022001F0B7
+:10709000D1FAA6F12804DAF80090A4F800800821BB
+:1070A000204605F0C2FC0021204605F0C1FE4946FD
+:1070B000204605F0C6FE6946304605F0EFFC304636
+:1070C00005F009FD0146204605F0EFFC06230022ED
+:1070D000694600E0B8E0204605F090FE694630467B
+:1070E00005F0CEFC304605F0E9FC0146204605F0EF
+:1070F000E9FC062301226946204605F07FFE204672
+:10710000FDF722FF28680122962190F8BB3000E0AD
+:1071100006E00020FDF7CEFD286880F801B068E0A9
+:107120006C6832783F4E607BC2F34012104060734F
+:10713000D6F80F00C4F80E00B6F813006082707D18
+:107140002075B07D6075B6F81700E082B6F81900BA
+:107150006080B6F81B00A080B6F81D00E0804FF0FC
+:10716000010A04F108000DF0D9F996F8240000F0A6
+:107170001F00207696F82400400984F86C0184F8FA
+:1071800054A084F855A0286890F8CC1084F85610C4
+:1071900090F8BD0084F857009DF80810686800F06A
+:1071A000EEF8286880F8D09090F8D210B0F8D400AB
+:1071B00000F071F868680088F9F72CFDF9F7C4F958
+:1071C000286880F80180FDF765FFFDF744FFFDF7B3
+:1071D0003FFEFDF7A8FE012001F02CFA09E000BFF8
+:1071E00090F82200C0F3001008B1012701E0FEF77B
+:1071F000AAFF286890F8330018B1FDF769FFFDF782
+:1072000038F91FB100210120FFF783FB286841787E
+:1072100000291ABF4178012903B00BE0A40A00201D
+:10722000CC000020280C002060480200000C002048
+:10723000470C002008BFBDE8F08F4078032818BF36
+:10724000FFDF03B0BDE8F08F286890F82200C0F39C
+:1072500000100028CBD0C8E770B5864C06460D4616
+:107260002068807858B1FDF765FA216803463046FA
+:1072700091F8BB202946BDE8704001F048BAFDF7FF
+:1072800059FA21680346304691F8BA202946BDE8EC
+:10729000704001F03CBA784A137882F8F530A2F8D1
+:1072A000F60082F8F410012082F8F20092F8C4008F
+:1072B000002818BF92F8C00082F8F800704778B52F
+:1072C00004466C4800230093006890F8BA20082A0E
+:1072D00004BF4FF4C87240230DD0042A04BF4FF4FA
+:1072E000BF72102307D0022A07BF03F1180204233C
+:1072F00003F128020823491D01FB032690F8BC2056
+:107300009DF8001062F3050141F040058DF8005032
+:1073100090F8BB00012804BF9DF8020020F0E000B7
+:107320002AD0022818BFFFDF21D000BF25F080003F
+:107330008DF80000C4EB041106FB04F001EB8101A1
+:1073400000EB81044D48844228BFFFDF4C48A0FB7E
+:107350000410BDF80110000960F30C01ADF8011034
+:10736000BDF800009DF8021040EA014078BD9DF88C
+:10737000020020F0E00020308DF80200D6E72DE971
+:10738000F0413C4D04460E46286890F8D000002895
+:1073900018BFFFDF0027286880F8D2702188A0F886
+:1073A000D4106188A0F8EA10A188A0F8EC10E18858
+:1073B000A0F8EE1094F86C1180F8F01090F82F10EF
+:1073C00049B1427B00F10E01012A04D1497901F053
+:1073D000C001402935D090F8301041B1427B00F116
+:1073E0000E01012A04BF497911F0C00F29D0DE3007
+:1073F0000DF082F82348FF2E0078C0F380106076ED
+:107400001D48D0F88711C4F81A10B0F88B01E0833A
+:1074100028681ED0C0F8E410E18BA0F8E81000F155
+:10742000D802511E304604F0E9F9002808BFFFDFFA
+:10743000286890F8D71041F0020180F8D710BDE815
+:10744000F081D0F80E10C0F8DE10418AA0F8E210EA
+:10745000D0E7C0F8E470A0F8E870617E80F8D7103B
+:10746000D4F81A10C0F8D810E18BA0F8DC10BDE8F1
+:10747000F0810000CC000020A40A0020C4BF03005B
+:1074800089888888280C0020FE48406870472DE9CC
+:10749000F0410F46064601461446012005F098F9D2
+:1074A000054696F85500FEF7A6F8014696F85500F1
+:1074B000022808BFF44807D0012808BFF34803D0CA
+:1074C00004280CBFF248F34808444FF47A7100F2E4
+:1074D000E140B0FBF1F0718840F271225143C0EB02
+:1074E0004100001BA0F5597402F0B6FD002818BF3A
+:1074F0001E3CAF4234BF28463846A04203D2AF42BA
+:107500002CBF3C462C467462BDE8F0812DE9FF4F4C
+:107510008FB0044690F855601C98994640EA0900DF
+:10752000039094F86500002790460D280CBF0120B9
+:1075300000200990B9F1000F04BF94F80C01032852
+:107540002BD1099848B3B4F88E01404525D1D4F821
+:107550001401C4F80001608840F2E2414843C4F8D5
+:107560000401B4F85A01B4F8E6100844C4F808015C
+:10757000204602F07BFDB4F89201E08294F890017D
+:107580006075B4F894016080B4F89601A080B4F8F6
+:107590009801E080022084F80C01D4F864010C907A
+:1075A000B4F8E6B0B4F85801D4F860A1D4F8541196
+:1075B0000691B9F1000F03D094F8201149B193E07E
+:1075C00004F1E00107917431089104F5A075091DDB
+:1075D00007E004F59A710791091D089104F5927569
+:1075E000091D0A91B4F85810A8EB0000A8EB01019E
+:1075F00009B200B20091002805DAD4F850010690D3
+:1076000001200390084694F80C11002971D001293B
+:1076100000F03782022900F05F81032918BFFFDFE5
+:1076200000F0728239460698FAF7FBFF08990126A6
+:1076300040F2712208600A98A0F8008000202870AB
+:107640002E7108980068A8606188D4F8140151432D
+:10765000C0EB41009049A0F54D70886149698142B5
+:1076600087BF07990860079801600798616A0068FA
+:10767000084400F5D270E86002F0EEFC10B1E86852
+:107680001E30E8606E71B4F8D000A0EB080000B2C4
+:107690000028C4BF03206871099800281C9800F0D6
+:1076A000A682C0B1B4F8F81000290CBF0020B4F8CD
+:1076B000FA00A4F8FA0094F8FC20401C50438842D9
+:1076C00009D26879401E002805DD6E71B4F8FA0011
+:1076D000401CA4F8FA00B9F1000F00F0AB8294F856
+:1076E0002001002800F0A28213B00220BDE8F08F34
+:1076F000FFE7BAF1000F08BFFFDF94F855106148AB
+:1077000090F8280005F079F90C90E18A40F2712098
+:1077100041430C98002200EB41011098002806D04C
+:1077200000FB01F15D48B1FBF0F000F10102C4F88B
+:107730001021608840F2E24100FB01F210994FF005
+:10774000000006D0554801FB02F1B1FBF0F000F15A
+:107750000100C4F8140186B221464FF00100D4F8AC
+:1077600028B005F035F8074694F85500FDF743FFBB
+:10777000014694F85500022808BF434807D0012865
+:1077800008BF424803D004280CBF41484148084480
+:1077900000F2E1414FF47A70B1FBF0F1608840F201
+:1077A00071225043C1EB4000801BA0F5597602F0D6
+:1077B00053FC002818BF1E3EBB4534BF3846584610
+:1077C000B04203D2BB452CBF5E463E46666294F88B
+:1077D0005500FDF72EFF4FF47A7600F2E140B0FB42
+:1077E000F6F000EB0A0794F85500FDF722FF01467A
+:1077F00094F85500022808BF234A07D0012808BF83
+:10780000224A03D004280CBF214A224A01EB020B72
+:10781000FDF7F1FE584400F2DB514FF47A70B1FBF2
+:10782000F0F1E08A40F2712242430C98D4F810B192
+:1078300000EB4200401AA0EB0B003844A0F12007F7
+:10784000607D40F2E24110FB01F0049094F8556035
+:107850003046FDF7D0FE0146022E08BF0A4807D089
+:10786000012E08BF094803D0042E0CBF0848094860
+:10787000084400F2E1414FF47A70B1FBF0F000EB04
+:107880004B010DE0500C002004360200A22402003F
+:10789000D0FB0100C0D40100D400002040420F0002
+:1078A000049801EB000B3046FDF799FE584400F1B7
+:1078B0006201FD48416194F85500FDF7BAFE00F2FF
+:1078C000E1414FF47A70B1FBF0F05044381AB0F552
+:1078D0003D7F38BFFFDFA5E6E08A40F27121D4F892
+:1078E0000421484302EB400210980021002806D0F2
+:1078F00000FB02F1ED48B1FBF0F000F10101C4F82A
+:107900001011618840F2E24001FB00F210994FF043
+:10791000000006D0E54801FB02F1B1FBF0F000F1F8
+:107920000100C4F8140186B221464FF00100D4F8DA
+:1079300028A004F04DFF074694F85500FDF75BFEC4
+:10794000014694F85500022808BFD94807D00128FD
+:1079500008BFD84803D004280CBFD748D7480844EC
+:1079600000F2E1414FF47A70B1FBF0F1608840F22F
+:1079700071225043C1EB4000801BA0F5597602F004
+:107980006BFB002818BF1E3EBA4534BF3846504630
+:10799000B04203D2BA452CBF56463E466662BBF1A2
+:1079A000000F2ED11C9860B394F855603046FDF757
+:1079B00022FE022E08BFBE4907D0012E08BFBD49D6
+:1079C00003D0042E0CBFBC49BC49084400F2E1417D
+:1079D0004FF47A70B1FBF0F0D4F81011E38A084448
+:1079E00040F27121D4F80421594302EB41010F1AEE
+:1079F0003046FDF7F4FD0C99081A3844A0F1200731
+:107A00000AE0E18A40F27122D4F80401514300EB0C
+:107A10004100D4F81011471AD4F80821D4F8001105
+:107A2000D4F8100101FB020B607D40F2E24110FB33
+:107A300001FA94F855603046FDF7DDFD0146022E4F
+:107A400008BF9B4807D0012E08BF9A4803D0042ED8
+:107A50000CBF99489948084400F2E1414FF47A700C
+:107A6000B1FBF0F000EB4B0082443046FDF7B7FD70
+:107A7000504400F160018C484161012084F80C0100
+:107A8000D0E5628840F27123D4F814115A43C1EB57
+:107A9000420202FB00F70098D4F800C10BEB000291
+:107AA000D4F80801D4F81031121A0CFB0030521E21
+:107AB00002FB010B607D40F2E24110FB01FA94F8F9
+:107AC00055000646FDF797FD0146022E08BF78488F
+:107AD00007D0012E08BF774803D0042E0CBF76488C
+:107AE0007648084400F2E1414FF47A70B1FBF0F0BF
+:107AF00000EB4B0082443046FDF771FD504400F12D
+:107B00006001694841618DE5628840F27123D4F8D3
+:107B100014115A43C1EB420101FB00F794F86400D1
+:107B200024281CBF94F8650024280BD1B4F88E01DA
+:107B3000A8EB000000B2002804DB94F891010028B3
+:107B400018BF0646039850B3BBF1000F27D10C981D
+:107B5000002814BFBAF1000FFFDF94F85500FDF7BD
+:107B60004AFD022E08BF524907D0012E08BF5149D5
+:107B700003D0042E0CBF50495049084400F2E141A3
+:107B80004FF47A70B1FBF0F03F1A94F85500FDF70E
+:107B900026FD01460C98401A3844A0F120070098B1
+:107BA000D4F81411584400FB01FA3046FDF723FDC8
+:107BB0000146022E08BF3E4807D0012E08BF3D48AF
+:107BC00003D0042E0CBF3C483C48084400F2E1417D
+:107BD0004FF47A70B1FBF0F000EB4A0A3046FDF743
+:107BE000FEFC504400F160012F4841611AE5002875
+:107BF0007FF458AD94F80C0100283FF46CAD618817
+:107C000040F27122D4F814015143C0EB41012846DF
+:107C100004F08DFD0004000C3FF45DAD1D990029BA
+:107C200018BF0880012013B0BDE8F08F94F85C0104
+:107C3000FBF748FB94F85C012946FBF731FA002872
+:107C40001CBF89F0010084F82101002013B0BDE8B9
+:107C5000F08F2DE9F04F1A4C074683B02078894603
+:107C6000114E00254FF00208032804BF207BB842C4
+:107C70007ED1606830612078032818BFFFDF0327BA
+:107C8000B9F1080F7FD2DFE809F0041D2828237E10
+:107C90007E796562FEF712FC002818BFFFDFB7701F
+:107CA00003B0BDE8F08F0000D400002040420F0078
+:107CB00004360200A2240200D0FB0100C0D401005F
+:107CC000500C0020FEF71CFF002818BFFFDFE7E77D
+:107CD00003B0BDE8F04FFDF75CBA2775257494F842
+:107CE0002C00012658B14FF47A71A069FAF799FC7B
+:107CF000A061002104F1100004F019FD1AE0012137
+:107D00006846FBF7BDFF9DF8000042F210710002CB
+:107D1000B0FBF1F201FB1205FDF7F4FF0544294623
+:107D2000A069FAF77EFCA061294604F1100004F076
+:107D3000FEFC461C208C411C0A293CBF3044208498
+:107D4000606830B1208C401C0A2828BF84F8158058
+:107D500000D267753046FEF771F90028A0D0607A2E
+:107D600000289DD1207B04F11001FBF799F901E077
+:107D70000BE008E0002808BFFFDF91E7207BFAF75F
+:107D800028FF25708CE7FFDF8AE7202F28BFFFDF61
+:107D9000DFF804A407213AF81700F8F709FE0400F9
+:107DA00008BFFFDF202F28BFFFDFFB48218830F806
+:107DB0001700884218BFFFDF01273461B9F1080FAF
+:107DC00080F05481DFE809F0049EA6A6A1F0F0EF50
+:107DD000C4F86051F580C4F8645194F8210138B9B1
+:107DE000FAF716FFD4F82C11FBF720FC00281BDC57
+:107DF000B4F81E11B4F85800814206D1B4F8D4107A
+:107E0000081AA4F8D600204605E0081AA4F8D600FF
+:107E1000B4F81E112046A4F85810D4F84811C4F83C
+:107E20002C11C0F850111DE0B4F81C11B4F8580022
+:107E3000091AA4F8D610B4F81C112046A4F858105A
+:107E4000D4F82C11C4F84811C4F85011D4F83411E6
+:107E5000C4F8E010D4F83811C4F85411B4F83C1147
+:107E6000A4F8581101F0ACFFFAF7ACFE94F855A055
+:107E700081465046FDF7BFFBBAF1020F08BFC74964
+:107E800009D0BAF1010F08BFC54904D0BAF1040FF7
+:107E90000CBFC449C44908444FF47A7100F2E14070
+:107EA000B0FBF1F1D4F8140140F271220144608872
+:107EB0005043C1EB4000A0F1300AB9F1B70F98BFB1
+:107EC0004FF0B7092146012004F082FC4844AAEB98
+:107ED0000000A0F21939A2462146012004F078FCE6
+:107EE000DAF824109C30814288BF0D1AC6F80C9035
+:107EF0004D4538BFA946C6F8089084F8207186F829
+:107F00000280CDE602F0A3F801E0FDF742F984F823
+:107F10002071C5E6FAF77CFED4F8502101461046E0
+:107F2000FBF784FB48B1628840F27123D4F8141146
+:107F30005A43C1EB4201B0FBF1F094F865100D29F2
+:107F40000FD0B4F85820B4F81E1113189942AEBFE0
+:107F5000481C401C1044A4F81E0194F8220178B972
+:107F600005E0B4F81E01401CA4F81E0108E0B4F8B6
+:107F70001E01B4F8D410884204BF401CA4F81E01AE
+:107F8000B4F85A01DFF82492401CA4F85A01B4F85E
+:107F90008000B4F87E10401AB4F85810401E08440F
+:107FA0001FFA80FB24E053E060E000BF96F80080F9
+:107FB000B8F10C0F28BFFFDF39F8188094F86CA1D6
+:107FC000BAF10C0F28BFFFDF39F81A000023404434
+:107FD00081B202A8CDE90050B4F81E212046FFF777
+:107FE00095FA00283FF45CAE012818BFFFDF27D0C8
+:107FF000B4F81E01ABEB000000B20028D6DA08206E
+:1080000084F8740084F87370204601F02AFB84F829
+:108010000C5194F85C514FF6FF77202D00D3FFDF11
+:108020005D4820F8157094F85C01FAF7D2FD202025
+:1080300084F85C01307903B0BDE8F04FF3F7A6BED9
+:10804000B4F81E01BDF808100844A4F81E01CFE7DB
+:1080500094F80C01042818BFFFDF84F80C5194F841
+:108060005C514FF6FF77202DDAD3D8E7FFDF17E614
+:1080700010B54F4C207850B101206072FEF75EFDC4
+:108080002078032805D0207A002808BF10BD0C20D6
+:1080900010BD207BFBF716F9207BFBF760FB207BF4
+:1080A000FAF797FD002808BFFFDF0020207010BD01
+:1080B0002DE9F04F3E4F83B0387801244FF000088F
+:1080C00040B17C720120FEF739FD3878032818BFD3
+:1080D000387A0DD0DFF8DC9089F803406946072034
+:1080E000F8F7EFFB002818BFFFDF4FF6FF7440E002
+:1080F000387BFBF7E7F8387BFBF731FB387BFAF787
+:1081000068FD002808BFFFDF87F80080E2E70298DB
+:1081100000281CBF90F80C1100292AD00088A0422A
+:108120001CBFDFF874A04FF0200B4AD00721F8F7EE
+:108130003FFC040008BFFFDF94F85C01FBF70FFB76
+:1081400084F80C8194F85C514FF6FF76202D28BFFF
+:10815000FFDF2AF8156094F85C01FAF73AFD84F81D
+:108160005CB169460720F8F7ACFB002818BFFFDFB9
+:1081700022E06846F8F783FB0028C8D021E0029887
+:1081800000281CBF90F80C11002915D00088A0F51C
+:108190007F41FF39CAD114E0840C0020043602006C
+:1081A000A2240200D0FB0100C0D4010084480200D8
+:1081B000500C0020D40000206846F8F760FB00282F
+:1081C000DDD089F8038087F82C8087F80B8003B016
+:1081D0000020BDE8F08F70B50446FD4890F800041B
+:1081E000FC4D400995F800144909884218BFFFDF8B
+:1081F00095F8140D4009F84991F80014490988428E
+:1082000018BFFFDFF549002001220C7188700A7049
+:108210004870C870F2490870BDE8704048E7EF49FF
+:10822000087070472DE9F843ED4C064688462078E3
+:1082300000285CD1EB48FAF772FC2073202856D056
+:10824000032766602770002565722572AEB1012193
+:1082500006F1FC00FBF73DFD0620F8F751FB8146D7
+:108260000720F8F74DFB96F8FC104844B1FBF0F2FC
+:1082700000FB1210401C86F8FC00FAF7A3FCDA4958
+:10828000091838BF40F2F65000F23D1086B2FDF7F3
+:10829000F9FBE061FDF736FD4FF0010950B384F8BA
+:1082A0000A9001216846FBF7EBFC9DF8000042F2C2
+:1082B00010710002B0FBF1F201FB12000644FAF764
+:1082C000A7FC3146FAF7ADF9A061277567752574EB
+:1082D000207B04F11001FAF7E3FE002808BFFFDF5E
+:1082E00025840020FEF72AFC0020BDE8F8830C203E
+:1082F000BDE8F883FAF78CFC3146FAF792F9A061F1
+:10830000A57284F82C90A8F226502063DDE7B349CB
+:1083100048707047B24810B5417A0124002918BF4F
+:10832000002409D190F82C1031B1416A006B8142D0
+:1083300084BF0024FEF7FCFB204610BD70B5A74C9F
+:108340000546E088401CE080D4E902016278D5F857
+:108350006061002A1CBF324604F019FAA060864210
+:1083600008D895F80C01012804D0E078002804BF53
+:10837000012070BD002070BD70B50C4640F2E24196
+:1083800000FB01F52046FDF736F9022C08BF97499E
+:1083900007D0012C08BF964903D0042C0CBF954987
+:1083A000954908444FF47A7100F2E140B0FBF1F0D6
+:1083B00000F54D7085428CBF281A002070BD2DE954
+:1083C000F04F83B04FF00009044680F8209190F8F8
+:1083D000DE00002807BF94F80C01032803B0BDE8B5
+:1083E000F08FFAF715FCD4F8502101461046FBF740
+:1083F0001DF90028DCBF03B0BDE8F08F628840F2B1
+:108400007123D4F814115A43C1EB4201B0FBF1F0CF
+:10841000411CB4F858000144A4F81C11B4F8D4105D
+:10842000B4F81C21891A09B20029DCBF03B0BDE8E9
+:10843000F08F012184F82211B4F88010B4F87E2066
+:108440006E4F891A491E084485B2DFF890A10DF1DC
+:10845000080B25E09AF800600C2E28BFFFDF37F8E4
+:10846000166094F86C81B8F10C0F28BFFFDF37F865
+:108470001800CDE9009B3044B4F81C2181B20123DF
+:108480002046FFF743F8002804BF03B0BDE8F08F93
+:1084900001280FD0022812BFFFDF03B0BDE8F08F24
+:1084A000B4F81C01281A00B20028BCBF03B0BDE814
+:1084B000F08FCFE7B4F81C01BDF808100844A4F809
+:1084C0001C01EDE72DE9F0430422002583B00629C5
+:1084D0007DD2DFE801F0074B03191951044680F8FB
+:1084E0000C2107E004463D48C178002918BF84F8F4
+:1084F0000C210CD0FAF798FAA4F85A51B4F85800A5
+:10850000A4F81E0184F8225103B0BDE8F083067878
+:108510000C2E28BFFFDF394F94F80C0137F8166096
+:108520004FF00109032807D00128E3D194F86C81AA
+:10853000B8F10C0F0AD308E0C4F80851C4F8005190
+:1085400094F86C81B8F10C0F00D3FFDF37F81800F6
+:10855000CDE90095304481B2B4F8D4200023204600
+:10856000FEF7D4FF002818BFFFDFC3E7032180F820
+:108570000C1103B0BDE8F0830546876AB0F814011A
+:10858000294686B2012004F023F9044695F85500E7
+:10859000FDF731F895F85510022908BF134907D0A7
+:1085A000012908BF124903D004290CBF11491249FF
+:1085B00008444FF47A7100F2E140B0FBF1F06988B1
+:1085C00040F271225143C0EB4100801B18E02DE0C6
+:1085D00001E000E00BE000E019E000E0D400002042
+:1085E000500C0020537C01000AFAFFFF0436020001
+:1085F000A2240200D0FB0100C0D401008448020084
+:10860000A0F5597601F028FD002818BF1E3EA742AC
+:1086100034BF20463846B04228BF344602D2A74273
+:1086200028BF3C466C6203B0BDE8F083FFDF03B0B7
+:10863000BDE8F083F8B5894C0246874F0025616894
+:10864000606A052A48D2DFE802F0032F34373E0083
+:10865000A07A002660B101216846FBF71BFB9DF85C
+:10866000000042F210710002B0FBF1F201FB1206B1
+:10867000FDF748FB8119A069F9F7D3FFA0612574C4
+:1086800003206075607A38B9207B04F11001FAF795
+:1086900007FD002808BFFFDF2584FAF7C5F9387900
+:1086A000BDE8F840F3F772BBBDE8F840002100F0E8
+:1086B0006DB8C1F86001F8BDD1F86001BDE8F840BF
+:1086C000012100F063B884F82C50FAF7ADF938793D
+:1086D000BDE8F840F3F75ABBFFDFF8BD70B55E4C5C
+:1086E000A178022906BFE188002970BD2569C5F877
+:1086F000640195F85500FCF772FFD5F86411081A6B
+:10870000A1680144A160E1680844E06070BD70B5F3
+:108710000546514890F802C0BCF1020F06BF00693F
+:1087200000F5B0744E4C002904BF256070BD4FF4B5
+:108730007A7601290DD002291CBFFFDF70BD1046DB
+:10874000FCF768FF00F2E140B0FBF6F0281A206069
+:1087500070BD1846FCF76DFF00F2E140B0FBF6F08B
+:10876000281A206070BD3D48007800281CBF0020FA
+:10877000704710B50720F8F7B5F880F0010010BD7C
+:1087800036480078002818BF012070472DE9F047CF
+:10879000324C82B0002584F82C50D4F8188084F82C
+:1087A0002810E572814625700127277229466068E6
+:1087B00003F030FB6168C1F85081267B81F85C6171
+:1087C000C1F86091C1F85481B1F80080202E28BF13
+:1087D000FFDF244820F81680646884F80C51DFF825
+:1087E0007880A4F8585198F800600C2E28BFFFDF5D
+:1087F000DFF8749039F816A094F86C610C2E28BF3D
+:10880000FFDF39F816000023504481B200951A4664
+:1088100020460195FEF77AFE002818BFFFDFC4F856
+:108820000851C4F8005184F80C71A4F81E51A4F842
+:108830001C5184F82251B4F85800401EA4F8580086
+:10884000A4F85A51FAF7F0F898F8040002B0BDE81D
+:10885000F047F3F79BBA0000D4000020500C002032
+:10886000740C0020840C00208448020070B5FE4C7B
+:1088700021690A88A1F8FC2181F8FA0191F85400D5
+:10888000012808BF012503D0022814BFFFDF0225FD
+:10889000206980F8FE5190F85500012808BF012595
+:1088A00003D0022814BFFFDF02252069012180F8D0
+:1088B000FF5180F8F811002180F8A4112079BDE85B
+:1088C0007040F3F763BA2DE9F04FE74C83B0A0791D
+:1088D00010F0010F04BF03B0BDE8F08FA0690123C1
+:1088E0000521C578206990F86520583003F0B5FE61
+:1088F00068B1A81E0A2806D2DFE800F009090505BC
+:10890000090905050909A07840F00800A070A078C1
+:1089100000281CBF03B0BDE8F08FA06920274FF0EE
+:10892000020890F80390B9F1000F1CBFB9F1010FD4
+:10893000B9F1160F1ED1206990F8640003F076FE9D
+:10894000C0B1216991F864001F2813D0202808D0F5
+:10895000B9F1160F0CBFA77084F8028003B0BDE810
+:10896000F08F262081F86400B9F1160F1CBF2A2071
+:10897000FFF77CFF47F6FE7A012600254FF0280B13
+:10898000B9F10C0F00F049810BDCB9F10C0F80F04C
+:108990005884DFE809F068412BD9F6F6F5F4F3F6D0
+:1089A000AAD0B9F1150F00F0518211DCB9F1110F05
+:1089B00000F0BE83B9F1120F00F0C981B9F1130FB5
+:1089C00000F0B881B9F1140F00F0D58100F039BC86
+:1089D000B9F1160F00F06C82B9F1180F00F0CE82D9
+:1089E000B9F1FF0F00F0268400F02BBC20690123B1
+:1089F000194690F86720583003F02FFE002840F009
+:108A00002284A06904F018FB216981F87201072013
+:108A100081F8670000F017BC20690123002190F85D
+:108A20006520583003F019FE002800F0BA83A069D1
+:108A300004F0FFFA2169A1F88E01B1F85820801ADC
+:108A400000B28245A8BF0028DCBF81F874B081F86D
+:108A5000736040F3F88301F5C871A06904F0E4FA8B
+:108A60000B2021693DE020690123002190F8652059
+:108A7000583003F0F2FD002800F09383A06904F061
+:108A8000AFFA002800F0DD83A0692269B0F80D106C
+:108A9000A2F88E11B2F85830C91A09B28A45A8BF97
+:108AA0000029DCBF82F874B082F8736040F3CB8396
+:108AB000017982F89011B0F80510A2F8921104F033
+:108AC00082FA2169A1F89401A06904F07FFA216972
+:108AD000A1F89601A06904F080FA2169A1F8980133
+:108AE0000D2081F8650000F0AEBB20690123002154
+:108AF00090F86520583003F0B0FD002820690BD0B5
+:108B0000A0F88A5090F88C10491C80F88C10102125
+:108B100080F8651000F097BB90F8652001230521CF
+:108B2000583003F09AFD00281CBF0820A07040F0C8
+:108B30008A8300F036BB206990F86510112908BFC0
+:108B4000122140F09C82E3E720690123002190F884
+:108B50006520583003F081FDA0B9206990F86520A8
+:108B6000122A0FD001230521583003F076FD00288A
+:108B700018BF082000F0158300F097B9B7E0F6E2BF
+:108B800036E05EE3206990F88E1031B9A0F88A5083
+:108B900090F88C10491C80F88C1000F1E801A06955
+:108BA00004F063FA206900F1C001A06904F068FADA
+:108BB000206990F8C001002818BFFFDF20690188F4
+:108BC000A0F8C21100F5E271A06904F03CFA206936
+:108BD00000F5E671A06904F03EFA206980F8C061F2
+:108BE000142180F865102079F3F7D0F800F02BBB42
+:108BF000206990F86510172940F0418290F88C1098
+:108C0000491E49B280F88C100029B8BFFFDF1B2035
+:108C1000216981F8650000F016BB206990F86610A4
+:108C200011F0020F09D090F8642001230821583078
+:108C300003F013FD002800F0B482206990F8900042
+:108C400010F0020F18D1A06904F02EFA216981F802
+:108C50009100A069B0F80520A1F89220B0F80700B3
+:108C6000A1F8940002E00000F000002091F89000CC
+:108C700040F0020081F89000206990F8901011F007
+:108C8000010F05D0206990F8641006291CD114E06A
+:108C900090F8660010F0020F18BFFFDF206990F80F
+:108CA000661041F0020180F86610A0F88A5090F832
+:108CB0008C10491C80F88C10E4E780F8645080F830
+:108CC00088502079F3F762F8206990F88C11042914
+:108CD00040F0B98280F88C512079F3F757F8206979
+:108CE00090F86410002940F0AE8200F01EBA2069AE
+:108CF00090F8660010F0010F77D16946A06904F082
+:108D0000DAF99DF8000000F02501206980F896103E
+:108D10009DF8011001F0410180F89710A0F88A50E9
+:108D200090F88C10491C80F88C1090F8661041F077
+:108D300001011CE020690123092190F864205830CA
+:108D400003F08BFC002840F0248200F02ABA20694E
+:108D500090F8661011F0040F40F02382A0F88A50BA
+:108D600090F88C2041F00401521C80F88C2080F88F
+:108D7000661000F068BA206990F8660010F0300FB5
+:108D800033D1A06904F0B4F9002800F05A822769B1
+:108D9000A06904F0A9F938872769A06904F0A0F94F
+:108DA00078872769A06904F0A1F9B8872769A069C5
+:108DB00004F098F9F887A07910F0020F03D06069E9
+:108DC000C078142812D0206990F864101C290DD0A6
+:108DD00090F84E1001290CD090F89B11002904BF87
+:108DE00090F89A1100290CD003E05BE0206980F82C
+:108DF0004E60206990F8661041F0100180F866100E
+:108E00001AE090F8661041F0200180F866100288A0
+:108E1000A0F8E021028FA0F8E221428FA0F8E4211F
+:108E2000828F00F5D671A0F8E621C08F888781F87F
+:108E300032602079F2F7AAFF2069A0F88A5090F8F2
+:108E40008C10491C80F88C1000F0FDB920690123BA
+:108E50000A2190F86420583003F0FFFB10B3A0699A
+:108E600004F046F9A8B12669A06904F03DF93087FD
+:108E70002669A06904F034F970872669A06904F0B6
+:108E800035F9B0872669A06904F02CF9F08701F064
+:108E9000EDFA206980F8885080F8645001F0B6FA45
+:108EA00000F0D1B9A07840F00100A07000F0CBB97B
+:108EB000206901230B2190F86520583003F0CDFB89
+:108EC00010B1A77000F0BFB920690123002190F80C
+:108ED0006520583003F0C1FB002800F06281206952
+:108EE00090F864002428ECD0A06904F01CF9002854
+:108EF00000F0A781206990F8961041F0040180F8F5
+:108F00009610A1694A7902F0070280F85120097988
+:108F100001F0070180F8501090F8A531002B04BF34
+:108F200090F8A431002B1CD190F855C000F15403E7
+:108F30008C4502BF1978914280F87D6011D000F510
+:108F4000D67180F8F2610288A0F8F42190F85020E0
+:108F500080F8F62190F8510081F84B002079F2F763
+:108F600015FF2069212180F86510A0F88A5090F83B
+:108F70008C10491C80F88C1000F065B9206990F8BD
+:108F80006410202914BF0027012790F865102229BA
+:108F900008BF00F1650804D0002F18BF00F1640875
+:108FA0006DD090F8961041F0040180F89610A069F9
+:108FB00004F0DBF8F0B3D4F81890484604F0C9F890
+:108FC0000090484604F0C9F8814603F03CFC0100DB
+:108FD00018D0206990F854208A4213D090F8A43118
+:108FE00023B190F8A63113EA090F4BD0002F04BF2C
+:108FF00090F8513013EA090F01D18A4242D890F813
+:10900000A401B8B1DDF80090484603F01CFC78B12B
+:10901000216991F8552082420AD091F8A40120B12B
+:1090200091F8A70110EA090F2CD091F8A40108B11A
+:109030006A4600E026E0A169206903F013FCE8B36A
+:10904000A06904F090F82169A1F88E01B1F85820C8
+:10905000801A00B28245A8BF0028DCBF81F874B036
+:1090600081F8736052DD9DF8000081F890019DF851
+:10907000010081F89101242088F8000046E084F87E
+:109080000280E0E0206990F8A40100281CBF1E20A7
+:10909000FFF7ECFBB7B1A0692169C07881F8CA007D
+:1090A00006FA00F010F0807F08BFFFDF0A21206978
+:1090B00080F8641090F88800002800E014E008BFF1
+:1090C000FFDF0DE088F80050216991F88C00401E08
+:1090D00040B281F88C000028B8BFFFDF01F07BF9B7
+:1090E000206980F87D50AEE0206990F8A40120B19D
+:1090F0000020FFF7BBFB88F80050206900F16501F4
+:1091000080F87D50884508BF80F86550206900F1DF
+:109110006501884509D190F88C10491E49B280F844
+:109120008C100029B8BFFFDF8DE080F888508AE0FE
+:10913000206990F8961041F0040180F89610A0691B
+:1091400004F02FF816287ED1206990F864002028BA
+:1091500002D0262805D076E0A06904F026F8FFF7B3
+:1091600085FB206980F8645080F888506BE02069A6
+:1091700090F864200E2A03D1A1690979122902D03E
+:109180001C2A1AD10FE001230921583003F065FA97
+:1091900038B1206980F87C5080F8885080F864509D
+:1091A00051E0A6704FE0A1690979142904BF80F845
+:1091B000645080F888503FF471AE202A03D1A16931
+:1091C0000979162914D0262A03D1A169097916290B
+:1091D0000ED0A1690979172904BF90F86520222AC9
+:1091E00013D0E2691AB1FF2908BF80F886612AE02E
+:1091F00080F8645080F8885090F86500212818BFE6
+:109200001A2020D0FFF732FB1DE080F8655090F85F
+:109210008C10491E49B280F88C100029B8BFFFDFBE
+:10922000206980F87D5090F8A401002818BF002024
+:1092300009D0E7E7E06900281CBF206980F8866153
+:1092400001D101F0C8F82069D0E92A12491C42F185
+:109250000002C0E92A1203B0BDE8F08F70B5FB4EE2
+:1092600005460C46306990F8CB00FE2818BFFFDF9A
+:1092700032690020002C82F8CB501CBFA2F88A0073
+:1092800070BDA2F88400012082F8880070BD30B55E
+:1092900085B005466846FCF73EFA002808BFFFDFA8
+:1092A000222100980BF003F80321009803F040FE00
+:1092B0000098017821F010010170294603F066FE44
+:1092C000E24C0D2D04BF0621009830D00BDCA5F137
+:1092D00002000B2819D2DFE800F0201863191926C4
+:1092E000187018192C00152D7BD008DC112D2DD0ED
+:1092F000122D18BF132D09D0142D30D005E0162DD6
+:1093000046D0172D6BD0FF2D6AD0FFDFFCF716FA81
+:10931000002808BFFFDF05B030BD2069009990F834
+:10932000CC000871F2E72169009891F8CC10017126
+:10933000ECE7E26800981178017191884171090A9F
+:1093400081715188C171090A0172DFE70321009818
+:1093500003F025FF0621009803F025FFD6E72069DA
+:10936000B0F84410009803F0ABFE2069B0F8461046
+:10937000009803F0A9FE2069B0F84010009803F0AF
+:10938000A7FE2069B0F84210009803F0A5FEBDE7E3
+:109390002069009A90F8A611117190F8A7014BE08E
+:1093A000206900F1F001009803F06EFE206900F1E1
+:1093B000C401009803F072FEA8E7A549D1E90001B5
+:1093C000CDE90201206902A990F8960000F025007D
+:1093D0008DF80800009803F09CFE97E701E019E083
+:1093E0002CE02069B0F84010009803F071FE20696D
+:1093F000B0F84210009803F06FFE2069B0F84410F6
+:10940000009803F05DFE2069B0F84610009803F064
+:109410005BFE7BE7206990F8A41139B1009990F8C0
+:10942000A6210A7190F8A70148716FE7009A90F899
+:109430005410117190F85500507167E7206990F849
+:109440008721D0F88811009803F0AEFD5EE770B573
+:109450000C4605464FF4007120460AF04AFF25806D
+:1094600070BDF7F7AEBB2DE9F0410D460746072169
+:10947000F7F79EFA040008BFBDE8F08194F8AC014C
+:109480000026B8B16E700920287094F8AC0178B14C
+:10949000268484F8AC61D4F8AE016860D4F8B201D7
+:1094A000A860B4F8B601A88194F8AC010028EFD107
+:1094B0002E7144E094F8B801002837D094F8B80130
+:1094C0000D2818D00E2818BFFFDF38D12088F7F7F5
+:1094D000A1FB0746F7F74DF8A0B96E700E20287073
+:1094E00094F8BA0128712088E88084F8B861384679
+:1094F000F7F739F823E02088F7F78CFB0746F7F7F2
+:1095000038F810B10020BDE8F0816E700D20287091
+:1095100094F8BA0128712088E88094F8BE01287276
+:1095200084F8B8613846F7F71EF808E094F8F001BF
+:1095300040B16E701020287084F8F061AF80012077
+:10954000BDE8F08194F8C00190B16E700A202870D7
+:109550002088A880D4F8C401D4F8C811C5F8060042
+:10956000C5F80A10B4F8CC01E88184F8C061E6E7D8
+:1095700094F8CE0140B16E701A202870B4F8D00172
+:10958000A88084F8CE61DAE794F8EA0180B16E70C1
+:109590001B20287094F8EA010028D0D084F8EA61F2
+:1095A000D4F8EC01686094F8EA010028F6D1C6E727
+:1095B00094F8D2012F1DA0B16E701520287094F878
+:1095C000D201002818BF04F5EA75B8D084F8D2613A
+:1095D000294638460AF099FF94F8D2010028F5D1BF
+:1095E000ADE794F8DE0150B16E701D20287084F84C
+:1095F000DE6104F5F07138460AF087FF9FE794F8C2
+:10960000F20138B11E20287084F8F261D4F8F40118
+:10961000686094E794F8F801002808BFBDE8F0817D
+:109620006E701620287094F8F801002887D000BFCB
+:1096300084F8F861D4F8FA016860B4F8FE01288172
+:1096400094F8F8010028F3D179E70000F000002039
+:109650009C480200FE4AD0600020D0611062117167
+:109660007047002180F8641080F8651080F8681059
+:1096700090F8DE1011B10221FEF724BF0321FEF79E
+:1096800021BF2DE9F047F24C814686B020690D4696
+:109690000088F7F7D1FA070008BFFFDFA07828435A
+:1096A000A070A0794FF0000510F0200F20691CBFBA
+:1096B000A0F87E5080F8E45004D1B0F87E10491C28
+:1096C000A0F87E102069012690F86A1039B990F848
+:1096D000652001230621583002F0BFFF48B3E0881F
+:1096E00010F4006F07D0206990F86A10002918BFA5
+:1096F000A0F876501DD12069B0F87610491C89B2C7
+:10970000A0F87610B0F878208A422CBF531A0023B4
+:10971000B4F808C00CF1050C634598BF80F87C6074
+:10972000914206D3A0F8765080F8F0612079F2F7E4
+:109730002DFBA0794FF0020A10F0600F11D02069C4
+:1097400090F8681011B1032906D00AE080F868602B
+:109750000121FEF7B7FE04E080F868A00121FEF7C2
+:10976000B1FE206990F86810012905D1E18811F453
+:10977000807F18BF80F868A04FF00808B9F1000F8B
+:1097800040F09981E28812F4007F18BFA0F8F850E9
+:1097900004D1B0F8F810491CA0F8F81012F0080F26
+:1097A00050D0A17800294DD190F8CB00FE2808BFF9
+:1097B000FFDFFE21206980F8CB1090F86510192991
+:1097C00007D0206990F864101F2911D027292AD0CA
+:1097D0002FE080F88D5090F88C10491E49B280F827
+:1097E0008C100029B8BFFFDF206980F86550E8E7DA
+:1097F00090F8650002F01AFF80B12069262101234C
+:1098000080F8641090F865200B21583002F025FF95
+:10981000002804BF2A20FFF729F80AE02169202048
+:1098200081F8640005E080F8856180F8645080F874
+:109830008850206990F86710082904BF84F800A0B8
+:1098400080F8CBA0FFF73FF8A07910F0040F07D005
+:10985000A07828B9206990F86700072808BF26700B
+:1098600000F038FCA07910F0100F09D0A07838B9BA
+:10987000206990F865100B2904BF0C2180F8651051
+:10988000E07810F0080F11D020690123052190F82D
+:109890006520583002F0E1FE28B184F8028020698A
+:1098A00080F8B85102E0002001F0F2FAE0690028E7
+:1098B0005BD000950195029503950495206990F879
+:1098C0005500FBF798FE4FF47A7100F5FA70B0FB83
+:1098D000F1FA206990F85500FBF781FE5044ADF88D
+:1098E000060020690188ADF80010B0F85810ADF8F6
+:1098F00004104188ADF8021090F8860130B1A069DB
+:10990000C11C039103F0FEFA8DF81000206990F855
+:1099100085018DF80800E16968468847206980F86C
+:10992000865180F885510399F9B190F88411E1B915
+:1099300090F86410272918D09DF81010039AA1B14F
+:109940001378FF2B06D0072B02BF02295178FF297D
+:1099500002D00AE01B2908D880F884610399C0F876
+:1099600088119DF8101080F8871100F0CCFD01F0EF
+:1099700085FA0028206918BFA0F8D85004D1B0F8A3
+:10998000D810491CA0F8D81001F07BFA40B1216929
+:1099900091F8E40002289CBF401C81F8E40004D840
+:1099A000206990F8E400022806D92069A0F8D85070
+:1099B000A0F8DA5080F8E45020690123002190F8E3
+:1099C0006520583002F049FE20B9206990F8650002
+:1099D0000C285AD120690123002190F864205830C6
+:1099E00002F03BFEB0B320690123002190F867200C
+:1099F000583002F032FE68B3206990F868100229EE
+:109A000004BF90F8E40000283FD13846F6F781FB08
+:109A100000B3206990F8CB10FE2936D1B0F8D210EF
+:109A2000012932D980F8DD60B0F88010B0F87E20CE
+:109A30008B1E9A42AFBF0121891A491E89B2B0F824
+:109A4000D82023899A422EBF01229A1A521C02E082
+:109A5000F000002019E038BF92B2914288BF114651
+:109A6000012908BF80F8DD5090F869218AB1B0F86B
+:109A7000DA20B0F86A0182422FBF0120801A401C10
+:109A800080B2814288BF014603E02069012180F84D
+:109A9000DD502069B0F85820114489B2A0F8D410E4
+:109AA00090F86830002B18BF012B5DD0022B1CBF33
+:109AB000032BFFDF09D0E088C0F340200028206995
+:109AC00018BFA0F8E65059D151E090F86730082B44
+:109AD00021D0B0F87E10B0F8802000278B1C9A426D
+:109AE00006D3511A891E0F043F0C1CBF791E8FB27A
+:109AF00090F87C1051B190F864200123092158306E
+:109B000002F0ABFD002808BF002729D0206990F89B
+:109B10006A1089B908E0B0F87E30032B24D3B0F87E
+:109B200080101144491C1FE090F865200123062194
+:109B3000583002F092FD78B121690020B1F8782008
+:109B4000B1F876108B1C9A4203D3501A801E18BFAE
+:109B5000401EB84238BF87B2002F1CBF781E87B2A4
+:109B60002069B0F8D4103944A0F8D010A3E7B0F8B9
+:109B7000E610B0F8D6201144A0F8E610206990F85D
+:109B8000701139B990F8672001231946583002F056
+:109B900064FD38B12069B0F88210B0F8D6201144C5
+:109BA000A0F88210206990F8883033B1B0F88410A2
+:109BB000B0F8D6201144A0F8841090F98C20002A27
+:109BC00006DDB0F88A10B0F8D6C06144A0F88A105B
+:109BD0004FF03D0CB9F1000F18BF80F874C049D1A7
+:109BE0002178022911D0012908BF90F872113FD0C5
+:109BF000A17821B380F8736011F0140F18BF1E21F3
+:109C000009D000BF80F8741050E090F8CC100629FD
+:109C100018BF16212CE011F0080F18BF80F874C08F
+:109C200044D111F0200F18BF2321EBD111F0030F05
+:109C300008BFFFDF2A20216981F8740032E02BB1D0
+:109C4000B0F88410B0F88630994210D2002A05DDB1
+:109C5000B0F88A10B0F88620914208D2B0F882207D
+:109C6000B0F880108A4208D390F870212AB12221DE
+:109C700080F8741080F8736018E090F868203AB1AA
+:109C8000B0F87E208A4228BF80F87480F2D209E0C2
+:109C9000B0F87E10062905D33E2180F8741080F8B4
+:109CA000736003E0206990F8731079B1206980F83F
+:109CB000645080F8655080F8685090F8DE100029F4
+:109CC00014BF02210321FEF7FDFB02E00021FEF795
+:109CD000F9FB206980F8DE5006B0BDE8F047FBF7DD
+:109CE0004FBDF84902468878CB78184313D108460F
+:109CF00000694AB1897911F0080F03D090F8670024
+:109D0000082808D001207047B0F84810028E914210
+:109D100001D8FEF713BB0020704770B5E94C05462B
+:109D20000E46E0882843E08015F0020F04D015F0BD
+:109D3000010F18BFFFDF666115F0010F4FF0000241
+:109D40004FF001001AD0A661F178062902D00B2944
+:109D50000BD013E0216991F86530172B0ED1002349
+:109D6000C1E9283381F8690008E0216991F865307C
+:109D7000112B04BF81F8692081F88E0015F0020FC5
+:109D800018D06169C978052902D00B290BD011E0E0
+:109D9000216991F86520152A0CD10022C1E92A22F7
+:109DA00081F86A0006E0206990F86510102908BF64
+:109DB00080F86A2015F0800F1CBF0820E07070BD8D
+:109DC0002DE9F84FBF4C00254FF00108E580A57044
+:109DD000E5702570206168F30709074680F8DE808A
+:109DE0000088F6F729FF5FEA000A08BFFFDF206955
+:109DF0000088FBF78DFC20690088FBF7AFFC206929
+:109E0000B0F8D21071B190F8CB10FE290FD190F8B4
+:109E1000701189B190F8672001231946583002F07B
+:109E20001CFC88B1206990F8CB00FE2804D0206982
+:109E300090F8CB00FFF72BFA206990F8DF1000298B
+:109E400018BF25811BD10FE02069A0F8825090F83F
+:109E5000711180F8CC1000210220FFF7FFF9206972
+:109E600080F8DD500220E5E790F8AC1129B9018CAB
+:109E70008288914288BF218101D881882181B0F8F0
+:109E8000D610491E8EB2B0F8D8103144A0F8D810C0
+:109E900090F8DC1000291CBFA0F8DA5080F8DC50E4
+:109EA00004D1B0F8DA103144A0F8DA10B0F87E101E
+:109EB0003144A0F87E1090F86A1039B990F8652006
+:109EC00001230621583002F0C8FB28B12069B0F800
+:109ED00076103144A0F876102069B0F8D21001292C
+:109EE0009CBF491CA0F8D210002E18BF80F8E45087
+:109EF00090F8DD10A1B1B0F8D800218988420FD2C6
+:109F00005046F6F706F958B1206990F8691139B151
+:109F1000B0F8DA10B0F86A01814228BF00F0B4FF4F
+:109F2000206980F8DD5090F865100B2918BF0C29C6
+:109F300016D1B0F85820B0F88E31D21A12B2002AD9
+:109F40000EDBD0F89011816090F89411017302211A
+:109F500001F060FF206980F8655080F898804AE041
+:109F6000242924D1B0F85810B0F88E21891A09B2EA
+:109F700000291CDB90F8A42190F89011002908BF5B
+:109F800090F8541080F8541090F89111002908BFEF
+:109F900090F8551080F85510002A1CBF0020FEF7DD
+:109FA00065FC206980F8655080F87D5023E090F8CA
+:109FB0006410242918BF25291DD1B0F85810B0F815
+:109FC0008E21891A09B2002915DB90F89011002919
+:109FD00008BF90F8541080F8541090F8911100299F
+:109FE00008BF90F8551080F855100020FEF73EFC91
+:109FF000206980F86450216901F15800B1F8D62039
+:10A0000002F02CF9206990F86911002918BFA0F816
+:10A01000DA502D4800902D4B2D4A3946484600F025
+:10A0200073FE216A00291CBF6078FBF720F82069C5
+:10A030000123052190F86520583002F00EFB00281E
+:10A0400008BFBDE8F88FBDE8F84F00F066BC00F02F
+:10A05000FBBE1C49C86170471A48C069002818BF78
+:10A0600001207047174A50701162704710B50446BE
+:10A07000B0F894214388B0F89611B0F898019A424C
+:10A0800001BFA3889942E38898420FD02388A4F89F
+:10A09000B031A4F8B221A4F8B411A4F8B60101209B
+:10A0A00084F8AC0107480079F1F770FE01212046E1
+:10A0B00001F0B0FE002084F86500032084F86800F9
+:10A0C00010BD0000F000002083960100E39C010019
+:10A0D0001B9D010070B5FE4CA07910F0020F08BF67
+:10A0E00070BDA078002818BF70BD6169F8482722AC
+:10A0F000CB780E26002500690D2B78D00BDCA3F160
+:10A1000002030B2B1FD2DFE803F0201E808B9F2F52
+:10A110001E591E73D100152B00F02A810BDC112B68
+:10A1200065D0122B00F0F480132B00F0FF80142B6D
+:10A1300000F00E8107E0162B00F03281172B00F0A3
+:10A140003F81FF2B35D0FFDF70BD90F867200123E2
+:10A150001946583002F081FA002818BF70BD082057
+:10A16000216981F8670070BD90F8643009790A2B85
+:10A1700001BF90F8CA308B4280F8645080F8885054
+:10A1800008BF70BD90F8663013F0080F0DD023F0B3
+:10A19000080180F8661090F88C10491E49B280F8CA
+:10A1A0008C100029A8BF70BDCFE0FF291CBFFFDFC6
+:10A1B00070BD80F8642080F8845170BD90F866000E
+:10A1C00010F0010F08BFFFDF216991F88C00401EDD
+:10A1D00040B281F88C000028B8BFFFDF206990F8FA
+:10A1E000661021F0010100BF80F8661070BD21E00B
+:10A1F00090F86500102818BFFFDF0121206980F862
+:10A200008D10112180F8651070BD90F8650014283C
+:10A2100018BFFFDF0121206980F88D101521F1E7BB
+:10A2200090F86500152818BFFFDF1720216981F815
+:10A23000650070BD90F86500152818BFFFDF192074
+:10A24000216981F8650070BD90F865001B2818BF72
+:10A25000FFDF206980F88D5090F8B801002818BF02
+:10A26000FFDF206990F88E1049B180F88E50018888
+:10A27000A0F8BC1180F8BA5180F8B8610AE00188F2
+:10A28000A0F8BC1180F8BA51012180F8BE110D214F
+:10A2900080F8B8110088F6F7BDFCF6F755F920797B
+:10A2A000F1F774FD206980F8655070BD90F88C114D
+:10A2B000042915D0206990F8661011F0020F08BF2C
+:10A2C00070BD90F88C10491E49B280F88C1000299E
+:10A2D000B8BFFFDF206990F8661021F0020183E724
+:10A2E00090F8642001230021583002F0B6F90028CC
+:10A2F00008BFFFDF206990F8901011F0020F07BF30
+:10A30000062180F8641080F8885080F88C51D1E7DD
+:10A3100090F8642001230021583002F09EF90028B3
+:10A3200008BFFFDF206980F8646070BD90F8661098
+:10A3300021F0040180F8661090F88C10491E49B293
+:10A3400080F88C100029A8BF70BDFFDF70BD00BF72
+:10A3500090F8642001230021583002F07EF9002893
+:10A3600008BFFFDF1C20216981F8640070BD00BFB9
+:10A3700090F8660000F03000102818BFFFDF206959
+:10A3800090F8661021F0100180F8661090F88C109B
+:10A39000491E49B280F88C100029A8BF70BDD4E7CF
+:10A3A00090F8642001230021583002F056F900286B
+:10A3B00008BFFFDF1F20216981F8640070BD00BF66
+:10A3C00090F8650021281CBF0028FFDF22202169AA
+:10A3D00081F8650070BD3E49086990F8662012F06A
+:10A3E000080F1EBF01208870704742F0080280F8F5
+:10A3F00066208969C97880F8C9100021A0F88A1000
+:10A4000090F88C10491C80F88C10704710B5304CB7
+:10A4100005212069FEF756F8206990F84E100129B1
+:10A4200002BF022180F84E1010BD00F5D6710288DF
+:10A43000A0F8D421028EA0F8D621828EA0F8D821CF
+:10A44000028FB0F844309A4228BF1A46CA85828FDC
+:10A45000B0F84600824238BF10460886012081F8D5
+:10A4600026002079BDE81040F1F790BC184830B4C0
+:10A47000006990F84E30B0F832C0C48EB0F8401089
+:10A48000428F022B28D08A4238BF11460186C28FE4
+:10A49000B0F842108A4238BF11468186028FB0F868
+:10A4A00044108A4238BF11464186828FB0F8461068
+:10A4B0008A4238BF1146C186418E614588BF8C46AD
+:10A4C000A0F832C0C18EA14288BF0C46C48601E00C
+:10A4D000F000002030BC7047038E9A4228BF1A4615
+:10A4E000C58F838E9D4238BF2B468A4238BF1146A6
+:10A4F0000186B0F842108B4228BF0B4683860021AC
+:10A5000080F84E10CAE770B5FE4C206990F8CB1069
+:10A51000FE2906BFA178002970BD90F867200123AD
+:10A520001946583002F099F8002818BF70BD20690C
+:10A53000002590F8701159B1A0F8825090F871116F
+:10A5400080F8CC10BDE8704000210220FEF786BEE6
+:10A5500090F8652001230421583002F07EF80600AF
+:10A560000CD0D4F810C09CF86500102861D01428D5
+:10A5700065D015287BD01B287ED0BEE0216991F8DC
+:10A58000660010F0010F05D0BDE8704001210920E0
+:10A59000FEF764BE10F0020F0BD001210C20FEF775
+:10A5A0005DFE206990F8901041F0010180F8901054
+:10A5B00070BD10F0040F05D0BDE8704001211320DC
+:10A5C000FEF74CBE10F0080F09D091F8C90081F8D1
+:10A5D000CC00BDE8704001210720FEF73FBE10F01F
+:10A5E000100F02D091F89B0120B191F8650021284D
+:10A5F00073D179E091F89A0188B1B1F89C01A1F882
+:10A600004000B1F89E01A1F84200B1F8A001A1F804
+:10A610004400B1F8A201A1F8460081F89A51FFF771
+:10A6200025FFFFF7F3FEBDE8704001211520FEF77E
+:10A6300015BEBDE8704001210B20FEF70FBEF9F7F3
+:10A6400025FB0C2838BF70BD08212069F030F9F7D0
+:10A6500021FB28B120690421C430F9F71BFB00B9A4
+:10A66000FFDFBDE8704001210420FEF7F7BD9CF834
+:10A67000730101280DD000E030E0022818BF70BD42
+:10A680009CF88E00D8B106208CF8CC000121022065
+:10A690001DE09CF8B801002818BF70BD0CF1B00394
+:10A6A00000220CF1E8010CF5BA7001F052FF012113
+:10A6B0000520FEF7D3FD206980F8735170BD9CF82A
+:10A6C000960010F0040F14BF11200D200121FEF799
+:10A6D000C5FD206980F8735170BD0EE0BDE8704083
+:10A6E00001210620FEF7BABD91F87D00C0B991F8AE
+:10A6F000A40110B191F8A50190B1206901230021B6
+:10A7000090F86420583001F0A8FFC8B120690123F7
+:10A71000042190F86520583001F09FFF30B10FE020
+:10A72000BDE8704001211720FEF798BD206990F820
+:10A730007C0028B1BDE8704000211220FEF78EBDDC
+:10A74000206990F864200A2A2BD0002E18BF70BD13
+:10A7500001230021583001F080FF48B1206990F8B2
+:10A760008C11042904BF90F8900010F0030F22D040
+:10A7700020690123002190F86420583001F06DFF1A
+:10A7800000287DD0206990F89A1111B190F89B11A2
+:10A79000E9B190F8A411002972D090F8A511E9B39D
+:10A7A00092E090F8CA1080F8CC10BDE8704000210B
+:10A7B0000720FEF753BD00210C20FEF74FFD206956
+:10A7C00090F8901041F0010180F8901070BDB0F841
+:10A7D0009C11A0F84010B0F89E11A0F84210B0F8FB
+:10A7E000A011A0F84410B0F8A211A0F8461080F80B
+:10A7F0009A5190F8660010F0200F13D0FFF736FE44
+:10A80000FFF704FE01211520FEF728FD206990F8CE
+:10A81000661021F0200141F0100100E008E080F80E
+:10A82000661070BDBDE8704000211420FEF716BD13
+:10A8300090F8652001230B21583001F00EFFF8B984
+:10A84000206990F85400012808BF012503D0022890
+:10A8500014BFFFDF0225206990F85500012808BFCA
+:10A86000012603D0022814BFFFDF02262069012D34
+:10A8700090F8A61105D0022D08BF022903D00DE0E3
+:10A8800022E001290AD190F8A711012E04D0022E4E
+:10A8900008BF02290BD001E0012908D090F86520FB
+:10A8A00001230321583001F0D8FE68B903E00020ED
+:10A8B000FDF7DCFF08E020690123022190F8652004
+:10A8C000583001F0CAFEB0B120690123002190F890
+:10A8D0006420583001F0C1FE002808BF70BD206917
+:10A8E00090F88401002808BF70BD0021BDE87040C9
+:10A8F000FF20FEF7B3BCBDE8704000211620FEF734
+:10A90000ADBC0000F000002030B5FB4C05462078BF
+:10A91000002818BFFFDF657230BDF74901200872BB
+:10A9200070472DE9F14FF54F39464E68304696F89D
+:10A93000551001F042FF96F8551080B211F00C0F3F
+:10A940006FF00D047FD0B0F5747F38BF002506D3BB
+:10A950005038C11700EB916004EBA01085B2708EE7
+:10A96000A84238BF0546E648DFF88C93C9F82400B2
+:10A97000786800F15808834609F13400BBF832705A
+:10A9800040689BF8551090F86AA0584601F015FFF2
+:10A990009BF8551080B211F00C0F5FD0B0F5747FAA
+:10A9A00038BF002406D35038C21700EB926004EB86
+:10A9B000A01084B2A74238BF3C46BAF1000F1CBFBA
+:10A9C000201D84B2E0B2F9F709FF98F812000028C0
+:10A9D0004FD008F15801CA4891E80E1000F50274F2
+:10A9E00084E80E10D8F86810C0F82112D8F86C105E
+:10A9F000C0F8251200F58170FAF7A6FABF48007872
+:10AA000000280CBF0120002080F00101BD48017624
+:10AA1000D8E91412C0E90412A0F58372D9F8241001
+:10AA2000F9F7B5FD96F85500012808BF002204D0BB
+:10AA300002281ABFFFDF00220122E9B20120F9F744
+:10AA4000B4FD1CE0FFE7022919BF04EBD00085B27A
+:10AA50006FF00E0101EB900081D17FE7022919BF51
+:10AA600004EBD00084B26FF00E0202EB9000A1D193
+:10AA70009FE7D9F82400FAF767FAF9F7B9FD0098CB
+:10AA800050B9012296F8553096211046FAF712F97E
+:10AA900000219620FAF7A4FA96F82C00012808BFA6
+:10AAA000FAF730FB022089F80000BDE8F88F2DE9A5
+:10AAB000F04FDFF8488283B0414681464D68A1F1EE
+:10AAC0001400009095F85D0005F158060127A1F1EA
+:10AAD000340470B3012879D0022878D0032818BF35
+:10AAE000FFDF75D0206A0823017821F0080101708A
+:10AAF000B27903EAC202114321F004010170F27934
+:10AB0000042303EA8202114321F01001017096F838
+:10AB100005B0E06AF5F70DFB8246FAF743FEBBF19C
+:10AB2000020F7AD0BBF1010F78D0BBF1030F76D0C2
+:10AB30008AE0FFE700F0CAFB0146284601F03BFE31
+:10AB40001FFA80FB00F0C2FB10F00C0F6FF00D013C
+:10AB50004FF0000A20D0BBF5747F38BF504607D3B2
+:10AB6000ABF15000C21700EB926001EBA01080B275
+:10AB7000298E814238BF0846ADF80800A5F8480084
+:10AB80000098FAF7EEFD90B1216AA77062694FF460
+:10AB90008060904703202CE0022819BF01EBDB0006
+:10ABA00080B26FF00E0000EB9B00E1D1DFE701AA5D
+:10ABB00002A9E06AF5F7F8F9206210B196F83510AD
+:10ABC00039B10098FAF7A1FD77718BE713E016E031
+:10ABD00026E09DF8041031B9A0F800A080F802A08A
+:10ABE000012102F0A5F9BDF80810206A02F0DFFA91
+:10ABF0000220707176E70098FAF787FD72E7B5F8E2
+:10AC00004800ADF8000001AA6946E06AF5F7CCF902
+:10AC10002062002808BFFFDF64E708E00BE00EE0D9
+:10AC20000098FAF79EFD002808BFFFDF5AE730EAD8
+:10AC30000A0009D106E030EA0A0005D102E0BAF1C3
+:10AC4000000F01D0012100E00021206A027842EAD1
+:10AC500001110170717C00291CBF7179012933D069
+:10AC600006F15801264891E80E1000F5027A8AE8AC
+:10AC70000E10B16EC0F82112F16EC0F8251200F569
+:10AC80008170FAF761F998F8000000280CBF0121E3
+:10AC900000211C480176D6E91212C0E90412A0F581
+:10ACA0008371226AF9F773FC95F85400012808BFF4
+:10ACB000002204D002281ABFFFDF00220122FB215C
+:10ACC0000020F9F772FC03E0FAF73EF9F9F790FC7F
+:10ACD000B9F1000F06D195F85430012296210020D9
+:10ACE000F9F7E8FF6771206A0188E18180782074B4
+:10ACF000277003B0BDE8F08F140100204801002048
+:10AD0000C80C0020D00E00202DE9F0471E46174643
+:10AD100081460C46FE4DDDF82080287828B9002FAA
+:10AD20001CBF002EB8F1000F00D1FFDFC5F81C805A
+:10AD3000C5E90576C5E90D9400272F72EF712F71D3
+:10AD4000EF706F71AF71AF70AF81F24E04F15808C0
+:10AD50002088F5F771FFE8622088F5F75BFF28632C
+:10AD6000F9F759FD94F95700F9F702FE04F11200C2
+:10AD7000FAF7D3F804F10E00F9F704FE3078002852
+:10AD80000CBF03200120FAF7DCF898F81A00F9F755
+:10AD900001FEFAF7D0F83078002804BFFF2094F8BD
+:10ADA000544023D098F81250B4F8328094F85510DB
+:10ADB000204601F002FD94F8554080B214F00C0FCB
+:10ADC0006FF00D012CD0B0F5747F06D35038C21748
+:10ADD00000EB926001EBA01087B24046B84528BF57
+:10ADE0003846002D1CBF001D80B2C0B22146F9F7C5
+:10ADF000F5FC3078F8B1706890F86801002818BF49
+:10AE0000F9F766FD224600210120F9F70CFF706872
+:10AE1000D0F8E000FAF79BF8BDE8F047012080E5A4
+:10AE2000022C19BF01EBD00087B26FF00E0101EBCD
+:10AE30009000D2D1D0E7002122460846F9F7F3FE70
+:10AE4000BDE8F047012032E6B24800B50178343859
+:10AE5000007819B1022818BFFFDF00BD012818BF14
+:10AE6000FFDF00BDAA4810B50078022818BFFFDF39
+:10AE7000BDE8104000F080BA00F07EBAA4484079E6
+:10AE80007047A34800797047A14901208871704735
+:10AE90002DE9F04706009F489D4D406800F1580499
+:10AEA000686A90F8019018BF012E03D1296B08F051
+:10AEB00093FE6870687800274FF00108A0B1012860
+:10AEC0003CD0022860D003281CBFFFDFBDE8F0871C
+:10AED000012E08BFBDE8F087286BF5F71FFB687AE5
+:10AEE000BDE8F047F0F752BF012E14D0A86A002841
+:10AEF00008BFFFDF6889C21CD5E9091009F058F9BD
+:10AF0000A86A686201224946286BF5F783F9022E88
+:10AF100008BFBDE8F087D4E91401401C41F10001ED
+:10AF2000C4E91401E079012801D1E77101E084F856
+:10AF30000780687ABDE8F047F0F728BF012E14D0EB
+:10AF4000A86A002808BFFFDF6889C21CD5E909107C
+:10AF500009F02EF9A86A686200224946286BF5F7C5
+:10AF600059F9022E08BFBDE8F087D4E91410491C36
+:10AF700040F10000C4E91410E07901280CBFE7712A
+:10AF800084F80780BDE8F087012E06D0286BF5F71E
+:10AF9000C5FA022E08BFBDE8F087D4E91410491C99
+:10AFA00040F10000C4E91410E0790128BFD1BCE7EA
+:10AFB0002DE9F041574F3846A7F13404406800F1BD
+:10AFC00058052078012818BFFFDFA878012648B16E
+:10AFD0000021A970A6706269042090473878002883
+:10AFE00018BF2E71206A0321007831EA000004BFE7
+:10AFF000E878002805D1EE70216AA6706269022007
+:10B0000090470121002000F0D6F918B1BDE8F041C9
+:10B0100000F0B2B9BDE8F041002082E42DE9F14F23
+:10B020003C4E4FF000083046A6F1340540683178B8
+:10B0300000F1580A2878C146022818BFFFDFA88906
+:10B0400040F40070A88171683078FF2091F85410A6
+:10B05000F9F7C4FB009800289AF8120000F0FD8070
+:10B06000F9F7ECFAF9F7DAFA012788B99AF8120039
+:10B0700070B1686A417859B100789AF80710C0F346
+:10B08000C000884204D1EF70BDE8F84F00F074B9F9
+:10B09000686A41786981002908BFC5F8288003D013
+:10B0A000286BF5F771F8A862A88940F02000A88104
+:10B0B00085F804803078706800F1580B044690F8E9
+:10B0C0002C0001281AD1FAF713F85946204601F04E
+:10B0D00080FA98B13078002870680CBF00F58A704B
+:10B0E00000F5F570218841809BF8081001719BF8EC
+:10B0F000091041710770687AF0F748FE686A9AF89B
+:10B1000006100078C0F3800088423BD0307803E01E
+:10B110001401002048010020706800F1580490F8E4
+:10B120005D0058B3022847D084F8058030780028A5
+:10B130001CBF2079002806D084F80480AF706A69AB
+:10B14000414610209047E07890B184F80380FAF7E8
+:10B1500017FB002808BFFFDF0820AF706A690021D5
+:10B160009047D4E91202411C42F10000C4E91210D8
+:10B17000A07901280CBF84F80680A771A88940F443
+:10B180008070A881686A9AF807300178C1F3C0021C
+:10B190009A424FD13278726801F0030102F15804EB
+:10B1A000012918BF022932D003291CBFE87940F0D9
+:10B1B000040012D0E8713DE0E86AF4F721FF0028AE
+:10B1C00008BFFFDFD4E91210491C40F10000C4E9B8
+:10B1D0001210687AF0F7DAFDA6E701F0C1FE90B12F
+:10B1E000A770A989384641F40061A981696AAF70E6
+:10B1F0006A699047E079012803D100BF84F807808D
+:10B2000018E0E77116E0E87940F01000D2E74078E6
+:10B21000F8B1A98941F40061A981A96A51B1FB285B
+:10B22000F1D8287A002808BFB94603D080206A697F
+:10B23000002190470120009900F0BDF8B0B1B9F1AC
+:10B24000000F1CBF0020FFF723FEBDE8F84F00F001
+:10B2500093B8E0790128D4D1D0E7002818BFF9F7D6
+:10B2600026FAA88940F04000A881E3E7B9F1000F71
+:10B270001CBF0120FFF70CFE0020FFF718FCB9F1FE
+:10B28000000F08BFBDE8F88F0220BDE8F84FFFE5CA
+:10B2900070B50D4606466848674900784C6850B15D
+:10B2A000F9F748FA034694F8542029463046BDE899
+:10B2B0007040FDF72CBAF9F73DFA034694F8542094
+:10B2C00029463046BDE8704005F00ABD5A4802786C
+:10B2D0004168406801F1580C91F8643090F85400CE
+:10B2E000242B1CBF9CF80DC0BCF1240F13D01F2BC6
+:10B2F00018BF202B24D0BCF1220F18BF7047002AA2
+:10B3000008BF704791F8A62191F85110114011F033
+:10B31000010F27D02EE04AB191F89011002908BF03
+:10B320007047012818BF012924D021E091F8F210BC
+:10B33000002908BF7047012818BF01291AD017E05B
+:10B34000BCF1220FDBD0002A08BF704791F8A6118C
+:10B3500011F0010F0ED111F0020F08BF7047012844
+:10B3600008D005E011F0020F08BF7047012801D096
+:10B3700002207047012070472F4910B54C68F9F73B
+:10B3800089FEF9F768FEF9F763FDF9F7CCFDF9F7E7
+:10B390002FF994F82C00012808BFF9F7A9FE274CD3
+:10B3A00000216269A0899047E269E179E0789047DD
+:10B3B0000020207010BD70B5204C0546002908BF44
+:10B3C000012D05D12079401CC0B22071012831D84F
+:10B3D000A1692846884700282CD0A179184839B19E
+:10B3E000012D01BF41780029017811F0100F21D003
+:10B3F000E179F9B910490978002908BF012D05D074
+:10B4000000290CBF01210021294311D10D490978E0
+:10B4100011F0100F04BF007810F0100F0AD0A078C0
+:10B4200040B9A06A20B9608910B111F0100F01D0A5
+:10B43000002070BD012070BD4801002014010020D3
+:10B44000C80C00202201002010B540F2C311F748BB
+:10B4500008F02DFFFF220821F54808F020FFF548ED
+:10B46000002141704FF46171418010BD2DE9F04120
+:10B470000E46054600F046FBEC4C102816D004EBB7
+:10B48000C00191F84A0110F0010F1CBF0120BDE876
+:10B49000F081607808283CBF012081F84A011CD265
+:10B4A0006078401C60700120BDE8F0816078082859
+:10B4B00013D222780127501C207004EBC208306898
+:10B4C000C8F84401B088A8F84801102A28BFFFDF57
+:10B4D00088F8435188F84A71E2E70020BDE8F0811E
+:10B4E000D2480178491E4BB2002BB8BF704770B4E8
+:10B4F0005FF0000500EBC30191F84A1111F0010F54
+:10B500003BD04278D9B2521E427000EBC10282F8A1
+:10B510004A5190F802C00022BCF1000F0BD98418E8
+:10B5200094F803618E4202D1102A26D103E0521C06
+:10B53000D2B29445F3D80278521ED2B202708A4237
+:10B540001BD000EBC20200EBC10CD2F84341CCF897
+:10B550004341D2F84721CCF84721847890F800C0C5
+:10B560000022002C09D9861896F8036166450AD195
+:10B57000102A1CBF024482F80311591E4BB2002B43
+:10B58000B8DA70BC7047521CD2B29442EBD8F4E7E0
+:10B590002DE9F05F1F4690460E46814600F0B2FA54
+:10B5A000A24D0446102830D0A878002100280ED9DA
+:10B5B0006A1892F80331A34205D110291CBF12204A
+:10B5C000BDE8F09F03E0491CC9B28842F0D80828C2
+:10B5D00034D2102C1CD0AE781022701CA87005EB51
+:10B5E000061909F10300414600F0A2FF09F18300AA
+:10B5F0001022394600F09CFFA819002180F8034171
+:10B6000080F83B110846BDE8F09FA878082815D2BD
+:10B610002C78CA46601C287005EBC4093068C9F84C
+:10B620004401B0884FF0000BA9F84801102C28BF46
+:10B63000FFDF89F843A189F84AB1CCE70720BDE8CC
+:10B64000F09F70B479488178491E4BB2002BBCBF83
+:10B6500070BC704703F0FF0C8178491ECAB282703B
+:10B6600050FA83F191F8031194453ED000EB021596
+:10B6700000EB0C14D5F80360C4F80360D5F807603C
+:10B68000C4F80760D5F80B60C4F80B60D5F80F60FC
+:10B69000C4F80F60D5F88360C4F88360D5F887607C
+:10B6A000C4F88760D5F88B60C4F88B60D5F88F50EC
+:10B6B000C4F88F50851800EB0C0402EB420295F899
+:10B6C00003610CEB4C0C00EB420284F8036100EBCD
+:10B6D0004C0CD2F80B61CCF80B61B2F80F21ACF82E
+:10B6E0000F2195F83B2184F83B2100EBC10292F831
+:10B6F0004A2112F0010F33D190F802C00022BCF1B0
+:10B70000000F0BD9841894F803518D4202D1102AEE
+:10B7100026D103E0521CD2B29445F3D80278521ECF
+:10B72000D2B202708A421BD000EBC20200EBC10C05
+:10B73000D2F84341CCF84341D2F84721CCF8472115
+:10B74000847890F800C00022002C09D9851895F85B
+:10B75000035165450BD1102A1CBF024482F8031126
+:10B76000591E4BB2002BBFF675AF70BC7047521C10
+:10B77000D2B29442EAD8F3E72E49487070472D4878
+:10B780004078704738B14AF2B811884203D8294945
+:10B790004880012070470020704726484088704745
+:10B7A00010B500F0AFF9102814D0204A014600204F
+:10B7B00092F802C0BCF1000F0CD9131893F80331B2
+:10B7C0008B4203D1102818BF10BD03E0401CC0B24B
+:10B7D0008445F2D8082010BD14498A78824286BF79
+:10B7E00001EB001083300020704710498A788242B4
+:10B7F00086BF01EB0010C01C002070470B4B93F874
+:10B8000002C084459CBF00207047184490F8030193
+:10B8100003EBC00090F843310B70D0F84411116075
+:10B82000B0F848019080012070470000F80E002019
+:10B830005A01002050010020FE4A114491F80321D2
+:10B84000FD490A7002684A6080880881704710B517
+:10B85000F8F74CFE002804BFFF2010BDBDE81040E3
+:10B86000F8F76ABEF3498A7882429CBF002070478D
+:10B87000084490F8030101EBC00090F84A0100F081
+:10B88000010070472DE9F047EA4F0026B0463878AE
+:10B89000002886BF4FF0080ADFF8A093BDE8F087C4
+:10B8A00007EBC80505F5A27195F8430100F02AF9E8
+:10B8B000102808BF544610D0B978002400290BD9AD
+:10B8C0003A1992F80321824202D1102C05D103E0EB
+:10B8D000621CD4B2A142F3D80824B878A04286BF33
+:10B8E00007EB0410C01C002095F84A1111F0010F5D
+:10B8F00016D050B1082C04D2391991F83B11012906
+:10B9000003D0102100F0F1FD50B109F80640304697
+:10B91000731C95F8432105F5A271DEB2F9F700F822
+:10B9200008F1010000F0FF0838784045B8D8BDE8BC
+:10B93000F0872DE9F041BF4C00263546A07800285D
+:10B940008CBFBE4FBDE8F0816119C0B291F8038190
+:10B95000A84286BF04EB0510C01C002091F83B11E3
+:10B96000012903D0102100F0C0FD58B104EBC8003C
+:10B97000BD5590F8432100F5A2713046731CDEB22C
+:10B98000F8F7CEFF681CC5B2A078A842DCD8BDE8A5
+:10B99000F08110B5F8F7EEFF002804BF082010BDB5
+:10B9A000F8F7ECFFA549085C10BD0A46A24910B59E
+:10B9B000497841B19F4B997829B10244D81CF8F7D6
+:10B9C00032FD012010BD002010BD9A4A01EB41015B
+:10B9D00002EB41010268C1F80B218088A1F80F0138
+:10B9E00070472DE9F041934D07460024A8780028C0
+:10B9F00098BFBDE8F081C0B2A04213D905EB041096
+:10BA000010F183060ED01021304600F06EFD48B9CB
+:10BA100004EB440005EB400000F20B113A463046BF
+:10BA2000F9F73DFF601CC4B2A878A042E3D8BDE896
+:10BA3000F08101461022824800F07ABD80487047AC
+:10BA400070B57C4D0446A878A04206D905EB0410D9
+:10BA50001021833000F049FD08B1002070BD04EBD7
+:10BA6000440005EB400000F20B1070BD71498A786C
+:10BA7000824206D9084490F83B01002804BF012007
+:10BA80007047002070472DE9F0410E4607461546E5
+:10BA90000621304600F029FD664C98B1A17871B1BD
+:10BAA00004F59D7011F0010F18BF00F8015FA17837
+:10BAB000490804D0457000F8025F491EFAD1012000
+:10BAC000BDE8F0813846314600F01CF8102816D049
+:10BAD000A3780021002B12D9621892F80321824228
+:10BAE00009D1102918BF082909D0601880F83B51E6
+:10BAF0000120BDE8F081491CC9B28B42ECD800207E
+:10BB0000BDE8F0812DE9F0414A4D06460024287831
+:10BB10000F46002812D900BF05EBC40090F843116E
+:10BB2000B14206D10622394600F5A27008F014FB96
+:10BB300038B1601CC4B22878A042EDD81020BDE80E
+:10BB4000F0812046BDE8F0813A4910B44A7801EB13
+:10BB5000C003521E4A70002283F84A2191F802C0A5
+:10BB6000BCF1000F0DD98B1893F80341844204D126
+:10BB7000102A1CBF10BC704703E0521CD2B294457F
+:10BB8000F1D80A78521ED2B20A70824204BF10BCA9
+:10BB9000704701EBC00301EBC202D2F843C1C3F806
+:10BBA00043C1D2F84721C3F847218C7891F800C0EF
+:10BBB0000022002C9CBF10BC70478B1893F80331F7
+:10BBC000634506D1102A1CBF114481F8030110BC43
+:10BBD0007047521CD2B29442EFD810BC704770B478
+:10BBE00014490D188A78521ED3B28B7095F8032130
+:10BBF000984247D001EB031C01EB0014DCF8036012
+:10BC0000C4F80360DCF80760C4F80760DCF80B6078
+:10BC1000C4F80B60DCF80F60C4F80F60DCF88360D8
+:10BC2000C4F88360DCF88760C4F88760DCF88B6058
+:10BC300008E00000F80E0020500100205A0100200A
+:10BC4000BB100020C4F88B60DCF88FC0C4F88FC034
+:10BC500001EB030C03EB43039CF8034100EB4000B2
+:10BC600001EB430385F8034101EB4000D3F80B419E
+:10BC7000C0F80B41B3F80F31A0F80F319CF83B012D
+:10BC800085F83B0101EBC20090F84A0110F0010F6A
+:10BC90001CBF70BC704700208C78002C0DD90B188D
+:10BCA00093F803C1944504D110281CBF70BC7047A1
+:10BCB00003E0401CC0B28442F1D80878401EC0B2F4
+:10BCC0000870904204BF70BC704701EBC20301EBE7
+:10BCD000C000D0F843C1C3F843C1D0F84701C3F84E
+:10BCE00047018C780B780020002C9CBF70BC7047FB
+:10BCF00001EB000C9CF803C19C4506D110281CBF29
+:10BD0000084480F8032170BC7047401CC0B28442D4
+:10BD1000EED870BC7047000010B50A7B02F01F021D
+:10BD20000A73002202768B181B7A03F0010C5B0861
+:10BD300003F00104A4445B0803F00104A4445B087D
+:10BD400003F00104A4445B0803F0010464444FEAD7
+:10BD5000530C0CF0010323444FEA5C0C0CF001047B
+:10BD6000234403EB5C0300EB020C521C8CF81330F1
+:10BD700090F818C0D2B263440376052AD3D3D8B260
+:10BD8000252888BFFFDF10BD0023C383428401EB59
+:10BD9000C202521EB2FBF1F10184704770B46FF021
+:10BDA0001F02010C02EA90251F23A1F5AA40543876
+:10BDB0001CBFA1F5AA40B0F1550009D0A1F528504B
+:10BDC000AA381EBFA1F52A40B0F1AA00012000D177
+:10BDD00000204FF0000C62464FEA0C048CEA01068A
+:10BDE000F6431643B6F1FF3F11D005F001064FEAC6
+:10BDF0005C0C4CEAC63C03F0010652086D085B0877
+:10BE0000641C42EAC632162CE8D370BC704770BC82
+:10BE1000002070472DE9F04701270025044603293B
+:10BE20000FD04FF4FA4200297CD0012900F006819E
+:10BE3000022918BFBDE8F0870146BDE8F047583039
+:10BE40006AE704F158067821304608F052FAB571D5
+:10BE5000F57135737573F573357475717576B576DF
+:10BE6000212086F83E00412086F83F00FE2086F81B
+:10BE7000730084F82C50258484F8547084F855702D
+:10BE8000282084F856001B20208760874FF4A47078
+:10BE9000E087A0871B20208660864FF4A470E08690
+:10BEA000A0861B20A4F84000A4F844004FF4A4701E
+:10BEB000A4F84600A4F842001B20A4F84A00A4F805
+:10BEC0004C00A4F8480067734FF448606080A4F801
+:10BED000D050A4F8D250A4F8D450A4F8D650A4F866
+:10BEE000D850A4F8DA5084F8DD5084F8DF50A4F874
+:10BEF000E65084F8E450A4F8F850A4F8FA5084F816
+:10BF00009A5184F89B5184F8A45184F8A55184F87F
+:10BF1000695184F8705184F8735184F88C51BDE8EC
+:10BF2000F087FFE7A4F8E65084F8DE506088FE4909
+:10BF30000144B1FBF0F1A4F878104BF68031A4F87D
+:10BF40007A10E388A4F87E50B4F882C0DB000CFBC2
+:10BF500000FCB3FBF0F39CFBF0FC5B1CA4F882C07C
+:10BF60009BB203FB00FC04F15801A4F88030BCF53F
+:10BF7000C84FC4BF5B1E0B85B2FBF0F2521CCA85D2
+:10BF800000F5802202F5EE32531EB3FBF0F20A8474
+:10BF9000CB8B03FB00F2B2FBF0F0C883214604F127
+:10BFA0005800FFF7B9FE07F0A5F9E8B3D4F80E1072
+:10BFB0006FF01F02080C02EA91281F26A0F5AA4183
+:10BFC00054391CBFA0F5AA41B1F155010AD0A0F522
+:10BFD0002851AA391EBFA0F52A41B1F1AA014FF09C
+:10BFE000010901D14FF00009002211464FEA020C6D
+:10BFF00082EA0003DB430B43B3F1FF3F1AD008F0A2
+:10C000000103520842EAC33206F0010349087608E8
+:10C010000CF1010C41EAC3314FEA5808BCF1160F8C
+:10C02000E6D3B9F1000F00E000E003D084F86851D6
+:10C03000BDE8F08784F86871BDE8F087A4F8E650A1
+:10C04000B4F89401B4F89831B4F802C004F158017E
+:10C05000A4F87E50B4F88240DB0004FB0CF4B3FB80
+:10C06000F0F394FBF0F45B1C4C859BB203FB00F4F3
+:10C070000B85B4F5C84FC4BF5B1E0B85B2FBF0F255
+:10C08000521CCA854A8C00EBC202521EB2FBF0F26F
+:10C090000A84CA8B02FB0CF2B2FBF0F0C883BDE845
+:10C0A000F08770B50025044603290DD04FF4FA42FD
+:10C0B000002963D001297DD0022918BF70BD014637
+:10C0C000BDE87040583027E604F158067821304624
+:10C0D00008F00FF9B571F57135737573F573357433
+:10C0E00075717576B576212086F83E00412086F878
+:10C0F0003F00FE2086F8730084F82C502584012030
+:10C1000084F8540084F85500282184F856101B2127
+:10C11000218761874FF4A471E187A1871B212186C4
+:10C1200061864FF4A471E186A1861B21A4F840101A
+:10C13000A4F844104FF4A471A4F84610A4F84210D7
+:10C140001B21A4F84A10A4F84C10A4F848106073FE
+:10C15000A4F8D850202084F8DA0084F8D050C4F82D
+:10C16000D45084F8045184F8055184F80E5184F8B1
+:10C170000F5184F8F45084F8005170BD60886A490A
+:10C180000144B1FBF0F1A4F878104BF68031A4F82B
+:10C190007A10E388A4F87E50B4F882C0DB000CFB70
+:10C1A00000FC9CFBF0FCB3FBF0F304F15801A4F895
+:10C1B00082C000E022E05B1C9BB203FB00FCA4F801
+:10C1C0008030BCF5C84FC4BF5B1E0B85B2FBF0F2DC
+:10C1D000521CCA8500F5802202F5EE32531EB3FBD5
+:10C1E000F0F20A84CB8B03FB00F2B2FBF0F0C883C1
+:10C1F000214604F15800BDE870408DE5D4F8F830D0
+:10C20000B4F802C004F158005989DB89A4F87E50C3
+:10C21000B4F88240DB0004FB0CF4B3FBF1F394FBB5
+:10C22000F1F45B1C44859BB203FB01F40385B4F578
+:10C23000C84FC4BF5B1E0385B2FBF1F2521CC2851E
+:10C24000428C01EBC202521EB2FBF1F20284C28B9D
+:10C2500002FB0CF2B2FBF1F1C18370BD2DE9F003DA
+:10C26000047E0CB1252C03D9BDE8F00312207047E1
+:10C27000002A02BF0020BDE8F003704791F80DC00E
+:10C280001F260123294D4FF00008BCF1000F77D085
+:10C29000BCF1010F1EBF1F20BDE8F0037047B0F8CE
+:10C2A00000C00A7C8F7B91F80F907A404F7C87EA20
+:10C2B000090742EA072282EA0C0C00270CF0FF096A
+:10C2C0004FEA1C2C99FAA9F99CFAACFC4FEA1969BF
+:10C2D0004FEA1C6C49EA0C2C0CEB0C1C7F1C9444A0
+:10C2E000FFB21FFA8CFC032FE8D38CEA020C0F4F2D
+:10C2F0000022ECFB057212096FF0240502FB05C257
+:10C30000D2B201EBD207427602F007053F7A03FA78
+:10C3100005F52F4218BF82767ED104FB0CF2120C79
+:10C32000521CD2B2002403E0FFDB050053E4B36EDD
+:10C3300000EB040C9CF813C094453CBFA2EB0C022C
+:10C34000D2B212D30D194FF0000C2D7A03FA0CF76C
+:10C350003D421CBF521ED2B2002A6AD00CF1010C21
+:10C360000CF0FF0CBCF1080FF0D304F1010C0CF041
+:10C37000FF04052CD7D33046BDE8F0037047FFE734
+:10C3800090F819C00C7E474604FB02C2FA4C4FF0ED
+:10C39000000CE2FB054C4FEA1C1C6FF024040CFB64
+:10C3A0000422D2B201EBD204427602F0070C247AC6
+:10C3B00003FA0CFC14EA0C0F1FBF82764046BDE85E
+:10C3C000F003704790F818C0B2FBFCF40CFB142289
+:10C3D000521CD2B25FF0000400EB040C9CF813C0B6
+:10C3E00094453CBFA2EB0C02D2B212D30D194FF010
+:10C3F000000C2D7A03FA0CF815EA080F1CBF521E28
+:10C40000D2B27AB10CF1010C0CF0FF0CBCF1080FA8
+:10C41000F0D304F1010C00E00EE00CF0FF04052C59
+:10C42000DAD3A8E70CEBC40181763846BDE8F00307
+:10C4300070470CEBC40181764046BDE8F0037047BD
+:10C44000CE4A016812681140CD4A1268114301605A
+:10C45000704730B4CB49C94B00244FF0010C0A7827
+:10C46000521CD2B20A70202A08BF0C700D781A68CC
+:10C470000CFA05F52A42F2D0097802680CFA01F1AB
+:10C480005140016030BC7047017931F01F0113BF8A
+:10C49000002000221146704710B4435C491C03F091
+:10C4A000010C5B0803F00104A4445B0803F00104E1
+:10C4B000A4445B0803F00104A4445B0803F00104F6
+:10C4C000A4445B0803F001045B08A44403F00104E6
+:10C4D000A4440CEB53031A44D2B20529DDDB012A34
+:10C4E0008CBF0120002010BC704730B40022A1F1A5
+:10C4F000010CBCF1000F11DD431E11F0010F08BF4C
+:10C5000013F8012F5C785FEA6C0C07D013F8025F18
+:10C5100022435C782A43BCF1010CF7D1491E5CBF71
+:10C52000405C0243002A0CBF0120002030BC704751
+:10C53000130008BF704710B401EB030CD41A1CF8A9
+:10C5400001CC5B1E00F804C013F0FF03F4D110BC53
+:10C550007047F0B58DB0164610251C466A46AC46AD
+:10C5600000EB0C03A5EB0C0713F8013CD355ACF121
+:10C57000010313F0FF0CF3D115461032102084464E
+:10C580000B18ACEB000713F8013C401ED35510F01C
+:10C59000FF00F5D1284606F02FFD86B1102005F1E9
+:10C5A000200201461318A1EB000C13F8013C401EB9
+:10C5B00004F80C3010F0FF00F4D10DB0F0BD089875
+:10C5C0002060099860600A98A0600B98E0600DB048
+:10C5D000F0BD38B505460C466846F8F79EFD0028C4
+:10C5E00008BF38BD9DF900202272A07E607294F9C8
+:10C5F0000A100020511A48BF494295F82D308B424D
+:10C60000C8BF38BDFF2B08BF38BDE17A491CC9B28D
+:10C61000E17295F82E30994203D8A17A7F2918BF8C
+:10C6200038BDA2720020E072012038BD0C2818BF6E
+:10C630000B2810D00D2818BF1F280CD0202818BF99
+:10C64000212808D0222818BF232804D024281EBF60
+:10C65000262800207047012070470C2963D2DFE8AC
+:10C6600001F006090E13161B323C415C484E002AAD
+:10C670005BD058E0072A18BF082A56D053E00C2A8E
+:10C6800018BF0B2A51D04EE00D2A4ED04BE0A2F13C
+:10C690000F000C2849D946E023B1A2F110000B2865
+:10C6A00043D940E0122A18BF112A3ED090F8360034
+:10C6B00020B1122A37D31A2A37D934E0162A32D3B6
+:10C6C0001A2A32D92FE0A2F10F0103292DD990F8AF
+:10C6D000360008B31B2A28D925E0002B08BF042AFE
+:10C6E00021D122E013B1062A1FD01CE0012A1AD161
+:10C6F0001BE01C2A1CBF1D2A1E2A16D013E01F2A6D
+:10C7000018BF202A11D0212A18BF222A0DD0232A8F
+:10C710001CBF242A262A08D005E013B10E2A04D013
+:10C7200001E0052A01D000207047012070472DE963
+:10C73000F04187680D4604462046F6F736FC98B16E
+:10C7400015B33846A168F6F771FF00281CDD2844B0
+:10C75000401EB0FBF5F606FB05F13846F5F761FF24
+:10C76000A0603046BDE8F081F6F752FA40F233712E
+:10C77000F5F757FFA060DFE753E4B36EA44802006B
+:10C78000A8480200620100200020BDE8F08190422C
+:10C7900028BF704770B50446101B642838BF64205A
+:10C7A00025188D4205D8F6F774FF00281CBF2846CF
+:10C7B00070BD204670BD808E7047C08E70470844A3
+:10C7C00018449830002A14BF0421002108447047FF
+:10C7D00030B491F854300A8E13F00C0F4FF4747C7F
+:10C7E0001CBF0CEB821292B21DD08B8E934238BFCD
+:10C7F0001A464B8E91F8554014F00C0F1CBF0CEBF1
+:10C8000083139BB217D0C98E994238BF0B460028BC
+:10C810000CBF01200020D1189831002818BF042037
+:10C82000084430BC7047022B07BF92003C32D20054
+:10C83000703292B2D9E7022C07BF9B003C33DB0079
+:10C8400070339BB2DFE710F0010F1CBF012070476F
+:10C8500010F0020F1CBF0220704710F0040018BF38
+:10C86000082070472DE9F041054617468846012605
+:10C87000084600F06EFC0446404600F06EFC03469D
+:10C8800010F0010F18BF012008D113F0020F18BFDC
+:10C89000022003D113F0040018BF082014F0010F88
+:10C8A00018BF4FF0010C20D050EA0C0108BF002641
+:10C8B00013F0030F08BF002014F0030F08BF4FF060
+:10C8C000000C95F85410814208BF0020387095F88C
+:10C8D0005510614508BF4FF0000C87F801C00028D3
+:10C8E00008BFBCF1000F1CD10DE014F0020F18BFFF
+:10C8F0004FF0020CD8D114F0040F14BF4FF0080C05
+:10C900004FF0000CD0E7404600F02DFCB5F8581071
+:10C91000401A00B247F6FE71884201DC002800DCB4
+:10C9200000263046BDE8F08101281CBF0228002007
+:10C93000704718B4CBB2C1F3072CC1B2C0F30720C3
+:10C94000012B05D0022B08BFBCF1020F1BD002E067
+:10C95000BCF1010F17D0012904D0022908BF022819
+:10C9600011D001E001280ED001EA0C0161F30702A9
+:10C9700010EA030060F30F22D0B210F0020F18BFCC
+:10C9800002200BD106E0084003EA0C01084060F3E6
+:10C990000702EFE710F0010018BF01208DF800003A
+:10C9A000C2F3072010F0020F18BF022003D110F0CD
+:10C9B000010018BF01208DF80100BDF8000018BC6F
+:10C9C0007047162A10D12A220C2818BF0D280FD024
+:10C9D0004FF0230C1F280DD031B10878012818BF63
+:10C9E000002805D0162805D0002070470120704788
+:10C9F0001A70FBE783F800C0F8E7012902D002298A
+:10CA000005D007E0002804BF40F2E240704740F63E
+:10CA1000C410704700B5FFDF40F2E24000BD0000E7
+:10CA2000282107F044BC4078704730B505460078AF
+:10CA300001F00F0220F00F0010432870092910D2D6
+:10CA4000DFE801F0050705070509050B0D000624C1
+:10CA500009E00C2407E0222405E0012403E00E2471
+:10CA600001E00024FFDF6C7030BD007800F00F00A3
+:10CA700070470A68C0F803208988A0F8071070473B
+:10CA8000D0F803200A60B0F80700888070470A6871
+:10CA9000C0F809208988A0F80D107047D0F8092047
+:10CAA0000A60B0F80D00888070470278402322F0B9
+:10CAB000400203EA81111143017070470078C0F30E
+:10CAC000801070470278802322F0800203EAC111AF
+:10CAD0001143017070470078C0097047027802F076
+:10CAE0000F02072A16BF082AD0F80520D0F8032025
+:10CAF000C1F809200CBFB0F80920B0F80720A1F850
+:10CB00000D200A7822F080020A700078800942EA3B
+:10CB1000C0100870704770B514460E4605461F2AAF
+:10CB200088BFFFDF2246314605F1090007F040FBD0
+:10CB3000A01D687070BD70B544780E460546062C81
+:10CB400038BFFFDFA01F84B21F2C88BF1F242246DE
+:10CB500005F10901304607F02BFB204670BD70B58A
+:10CB600014460E4605461F2A88BFFFDF224631467F
+:10CB700005F1090007F01CFBA01D687070BD70B5C1
+:10CB800044780E460546062C38BFFFDFA01F84B24E
+:10CB90001F2C88BFFFDF224605F10901304607F050
+:10CBA00007FB204670BD0968C0F80F1070470A885F
+:10CBB000A0F8132089784175704790F8242001F07F
+:10CBC0001F0122F01F02114380F82410704707292B
+:10CBD00088BF072190F82420E02322F0E00203EA36
+:10CBE0004111114380F8241070471F3007F096BCA4
+:10CBF00010B5044600F0E3FA002818BF204410BD29
+:10CC0000C17811F03F0F1BBF027912F0010F002213
+:10CC1000012211F03F0F1BBF037913F0020F002315
+:10CC200001231A4402EB4202530011F03F0F1BBFD5
+:10CC3000027912F0080F0022012203EB420311F0E7
+:10CC40003F0F1BBF027912F0040F00220122134490
+:10CC500011F03F0F1BBF027912F0200F00220122BA
+:10CC600002EBC20203EB420311F03F0F1BBF02793C
+:10CC700012F0100F0022012202EB42021A4411F0BE
+:10CC80003F0F1BBF007910F0400F0020012010441F
+:10CC900010F0FF0014BF012100210844C0B270470A
+:10CCA00070B50278417802F00F02082A4DD2DFE811
+:10CCB00002F004080B4C4C4C0F14881F1F280AD993
+:10CCC00043E00C2907D040E0881F1F2803D93CE02F
+:10CCD000881F1F2839D8012070BD4A1E242A34D845
+:10CCE0008446C07800258209032A09D000F03F0459
+:10CCF000601C884204D86046FFF782FFA04201D939
+:10CD0000284670BD9CF803004FF0010610F03F0F5D
+:10CD10001EBF1CF10400007810F0100F13D0644601
+:10CD20000421604600F04BFA002818BF14EB000005
+:10CD3000E6D0017801F03F012529E1D28078022177
+:10CD4000B1EB501FDCD3304670BD002070BDC07801
+:10CD5000800970470178002201F00F030121042BA4
+:10CD60000BD0082B1CBF0020704743780E2B04BF4C
+:10CD7000C3785FEA931C04D106E04078801F1F2827
+:10CD800000D911460846704713F03F0F1EBF0079C7
+:10CD900010F0010F10F0020FF4D1F2E710B4017897
+:10CDA00001F00F01032920D0052921D14478B0F8E2
+:10CDB0001910B0F81BC0B0F81730827D222C17D1A3
+:10CDC000062915D3B1F5486F98BFBCF5FA7F0FD28D
+:10CDD00072B1082A98BF8A420AD28B429CBFB0F82F
+:10CDE0001D00B0F5486F03D805E040780C2802D04C
+:10CDF00010BC0020704710BC012070472DE9F041A5
+:10CE00001F4614460D00064608BFFFDF2146304688
+:10CE100000F0D5F9040008BFFFDF30193A46294673
+:10CE2000BDE8F04107F0C4B9C07800F03F0070479A
+:10CE3000C02202EA8111C27802F03F021143C170A0
+:10CE40007047C9B201F00102C1F340031A4402EB7A
+:10CE50004202C1F3800303EB4202C1F3C00302EBC1
+:10CE60004302C1F3001303EB43031A44C1F340131D
+:10CE700003EBC30302EB4302C1F380131A4412F025
+:10CE8000FF0202D0521CD2B20171C37802F03F01FE
+:10CE900003F0C0031943C170511C417070472DE964
+:10CEA000F0410546C078164600F03F04C4F1240066
+:10CEB0000F46B042B8BFFFDF281932463946001D81
+:10CEC00007F076F9A019401C6870BDE8F0812DE9E3
+:10CED000F04105464478C0780F4600F03F06002C2C
+:10CEE00008BFFFDFA01B401E84B21F2C88BF1F2479
+:10CEF0002FB1A819011D2246384607F059F92046DE
+:10CF0000BDE8F0814078704700B5027801F0030376
+:10CF100022F003021A430270012914BF02290021E2
+:10CF200004D0032916BFFFDF012100BD417000BD01
+:10CF300000B5027801F0030322F003021A430270E5
+:10CF4000012914BF0229002104D0032916BFFFDFE5
+:10CF5000012100BD417000BD007800F00300704762
+:10CF6000417889B1C0780E2818BF0F2803D0102847
+:10CF700018BF192802D3FB2904D905E0BF4A105C69
+:10CF8000884201D1012070470020704730B501244C
+:10CF90000546C17019293CBFB848445C02D3FF293B
+:10CFA00018BFFFDF6C7030BD70B515460E460446E5
+:10CFB0001B2A88BFFFDF65702A463146E01CBDE8AA
+:10CFC000704007F0F5B8B0F807007047B0F80900F6
+:10CFD0007047C172090A01737047B0F80B007047BF
+:10CFE00030B4B0F80720A64DB0F809C0B0F805304D
+:10CFF0000179941F2D1998BFBCF5FA7F0ED269B143
+:10D00000082998BF914209D293429FBFB0F80B0004
+:10D01000B0F5486F012030BC98BF7047002030BC8D
+:10D020007047001D07F07ABA021D0846114607F046
+:10D0300075BAB0F809007047007970470A68426015
+:10D0400049688160704742680A608068486070473C
+:10D050000988818170478089088070470A68C0F814
+:10D060000E204968C0F812107047D0F80E200A60F0
+:10D07000D0F81200486070470968C0F81610704771
+:10D08000D0F81600086070470A68426049688160FD
+:10D09000704742680A608068486070470968C160EC
+:10D0A0007047C06808607047007970470A6842603E
+:10D0B00049688160704742680A60806848607047CC
+:10D0C0000171090A417170478171090AC171704784
+:10D0D0000172090A417270478172090AC172704770
+:10D0E00080887047C08870470089704740897047C2
+:10D0F00001891B2924BF4189B1F5A47F07D3818809
+:10D100001B2921BFC088B0F5A47F012070470020F3
+:10D1100070470A68426049688160704742680A60E7
+:10D12000806848607047017911F0070F1BBF407994
+:10D1300010F0070F002001207047017911F0070F50
+:10D140001BBF407910F0070F0020012070470171CC
+:10D15000704700797047417170474079704781711D
+:10D16000090AC1717047C088704746A282B0D2E9EF
+:10D170000012CDE900120179407901F007026946F9
+:10D180001DF80220012A07D800F00700085C0128DA
+:10D190009EBF012002B07047002002B070470171AD
+:10D1A000704700797047417170474079704730B5DA
+:10D1B0000C460546FB2988BFFFDF6C7030BDC37885
+:10D1C000024613F03F0008BF70470520127903F0B4
+:10D1D0003F0312F0010F36D0002914BF0B20704717
+:10D1E00012F0020F32D0012914BF801D704700BF1A
+:10D1F00012F0040F2DD0022914BF401C704700BF4D
+:10D2000012F0080F28D0032914BF801C704700BFFC
+:10D2100012F0100F23D0042914BFC01C704700BFA8
+:10D2200012F0200F1ED005291ABF1230C0B270476D
+:10D2300012F0400F19D006291ABF401CC0B2704727
+:10D24000072918D114E00029CAD114E00129CFD14F
+:10D2500011E00229D4D10EE00329D9D10BE0042931
+:10D26000DED108E00529E3D105E00629E8D102E096
+:10D27000834288BF7047002070470000AC4802001E
+:10D2800086F3FFFF00010102010202032DE9F041D4
+:10D29000FA4D0446284600216A78806801270E4628
+:10D2A00012B1012A1ED006E090F86620002A18BFAD
+:10D2B0006F7000D001216A78C2EB421200EB42028B
+:10D2C00092F82830194324D0667090F8D90002F102
+:10D2D0002A0170B12A22201D06F06AFF0420207066
+:10D2E00027710DE090F82820002A18BF6E70E1D158
+:10D2F000E1E73C22201D06F05BFF0520207027712E
+:10D300006878A968C0EB401001EB400080F8286005
+:10D310001DE090F8A410E9B190F8D900012818BFD9
+:10D32000FFDFA868D0F8A5106160D0F8A910A1604F
+:10D33000D0F8AD10E160D0F8B110216190F8B510CF
+:10D340002175667013212170277180F8A460012077
+:10D35000BDE8F08190F82210012922D0017801293E
+:10D360001CBF0020BDE8F081667014212170811C73
+:10D370002022201D06F01CFF2672A9680E70C048EE
+:10D3800082888284D0F8C420527B80F8262080F8DE
+:10D390002270D1F8C4000088F3F73CFCF3F7E3F8FF
+:10D3A000D5E7667007212170416A616080F82260CC
+:10D3B000CDE7B24880680178002914BF80884FF615
+:10D3C000FF7070472DE9F84F4FF000088946064678
+:10D3D0000127CDF80080FFF748FBBDF80010A74DEE
+:10D3E00021F06004ADF8004008284FD2DFE800F0DB
+:10D3F00004070D4E184E132C44F003000DE044F0CA
+:10D400001500ADF80000474641E044F0100000BFB1
+:10D41000ADF800003BE044F0020040F01000F7E7F8
+:10D42000A86890F8E000052818BFFFDF44F01A0054
+:10D43000ADF80000A96891F8E710002914BF40F08A
+:10D44000010020F00100E3E7A86890F8E01003294C
+:10D450000AD090F8E010062958D090F8E00004288F
+:10D4600018BFFFDF5FD012E03046FFF770FC0028E6
+:10D4700018BFFFDF0AD1F07810F03F0F1FBF3079DF
+:10D4800010F0020F44F00400ADF800004746BDF86C
+:10D4900000000090BDF80000C0F3C00BA868CBEB03
+:10D4A0004B1A00EB4A0090F82800002818BFBDE88E
+:10D4B000F88F3046FFF7D9FA80467048806800EB55
+:10D4C0004A0190F8C90001F12A04012808BF01258A
+:10D4D00003D0022814BFFFDF0225257300206073EC
+:10D4E0006648806890F8E11084F83B10FF21A17332
+:10D4F0007F21E176BDF80010618190F8E0100429E9
+:10D500001CBF90F8E01006293AD044E044F00A012C
+:10D51000ADF8001090F8FA00002814BF41F00400A4
+:10D5200021F0040074E73046FFF711FCD8B1012860
+:10D5300004BF44F00100ADF8000014D0022818BF69
+:10D54000FFDFA4D144F00200ADF80000A96891F813
+:10D55000FA10002914BF40F0040020F00400ADF8D8
+:10D560000000474693E7F07810F03F0F1FBF307977
+:10D5700010F0020FBDF8000040F0040087D047E72C
+:10D5800090F8E200012808BF012503D0022814BF4B
+:10D59000FFDF0225657304F10900384D00902878FB
+:10D5A0007F2808BFFFDF2978009801707F2028704E
+:10D5B0006FB1B8F1070F04F11C01304603D2FFF739
+:10D5C000BAFA207239E0FFF782FC207204E00020F2
+:10D5D0002072B8F1070F30D3B8F1070F0DD1A8684A
+:10D5E00090F8F91001B3D0F8EA10C4F80210B0F8BE
+:10D5F000EE10E18090F8F0006070A07A10F0040F57
+:10D600000ED0A86890F8FA10E9B190F8F7102175DB
+:10D61000D0F8F110C4F81510B0F8F500A4F819000E
+:10D62000B8F1070F38D098E0F07810F03F0F1ABF2C
+:10D63000307910F0010FFF20DED0621CA11C3046B3
+:10D6400001F071FDD9E7B8F1070F1CBFB8F1010F68
+:10D65000FFDFB9F1000F08BFFFDF99F80000207568
+:10D66000B8F1010F03D0B8F1070F0BD075E004F14A
+:10D6700015013046FFF712FA6FE000006401002048
+:10D68000CC10002001213046FFF7B2FA0168C4F83F
+:10D6900015108088A4F81900F07810F03F0F1CBF17
+:10D6A000317911F0080F1AD0A86890F8E020042A08
+:10D6B00006D090F8E000032811D111F0100F0ED021
+:10D6C00003213046FFF794FA407803210009A07344
+:10D6D0003046FFF78DFA0088C0F30B002082F07807
+:10D6E00010F03F0F1CBF307910F0400F13D0FA48F4
+:10D6F000FFF72DFBA96891F8E020032A14D006213A
+:10D700003046FFF775FA0078E076A86890F8E010E8
+:10D71000062922D118E0A86890F8FB10002918BF4C
+:10D7200090F8F800F0D1F0E791F8C910042914BF7F
+:10D7300008290028E3D1F07810F03F0F1CBF3079A2
+:10D7400010F0080FDBD1E0E790F8E9100909A173A8
+:10D75000B0F8E800C0F30B002082A968012001EBBB
+:10D760004A0181F82800BBF1000F14BF06200520F4
+:10D77000BDE8F84F03F0F4B82DE9F041D74DAA68A1
+:10D7800092F8D930002B6ED07F27012611B109788D
+:10D79000FE2914D0804692F82800002818BFBDE862
+:10D7A000F08102F12A044046FFF75FF900210828C2
+:10D7B00079D2DFE800F0515356787878595CC64C3E
+:10D7C00092F8A400002818BFBDE8F08182F8A66096
+:10D7D00092F8DD0018B1F6F76CFE012829D020463A
+:10D7E000FFF76CF90146A86880F8A71000F1A801BE
+:10D7F0002046FFF745F92046FFF76DF90146A86876
+:10D8000080F8AE1000F1AF012046FFF747F9A86895
+:10D8100000F1B50428787F2808BFFFDF2878207042
+:10D820002F70A86880F8A460BDE8F041052003F0DF
+:10D8300097B8F6F781FEA96801F1A802A731FDF7B4
+:10D84000DDFF002808BFFFDFA86890F8A71041F0AF
+:10D85000020180F8A710CEE7A17209E0A67221723A
+:10D860000CE0032001E021E00220A07200E0FFDFD5
+:10D8700004F10B014046FFF75EF92072621CA11C07
+:10D88000404601F050FC287809347F2808BFFFDFAC
+:10D89000287820702F70A86880F82860BDE8F041D3
+:10D8A000052003F05DB82172BDE8F081BDE8F041CC
+:10D8B00088E570B5894C0022A06890F8C910104620
+:10D8C00002F0A8FE002831D0F7F735FBA0688449A4
+:10D8D00090F8DF000D5C2846F7F75CF8A06880F848
+:10D8E000E15090F8C910082916BF04290F202520FF
+:10D8F000F6F75DFFA068002190F8C9200120F7F736
+:10D9000050F97548F7F720FBA068D0F80001F7F749
+:10D910001EFBA06890F8C91080F8E21090F8C800CB
+:10D92000032814BF0228012908D103E0BDE8704094
+:10D9300001F032BC08210020F7F707FCA06890F83E
+:10D94000C91080F8E210F7F7DDFBA06890F8DD0061
+:10D9500020B1F6F77AFD4020F7F7A8FBA168032075
+:10D9600081F8E00070BD2DE9F0410F469046054674
+:10D970000321FFF73DF94078584C0209A06890F860
+:10D98000E91062F3071180F8E91003212846FFF738
+:10D990002FF90188A068B0F8E82061F30B02A0F825
+:10D9A000E82080F8E77090F8C910012905D090F8B8
+:10D9B000E000032808BFBDE8F081E8784FF00106D9
+:10D9C00010F03F0F1CBF287910F0400F09D006213E
+:10D9D0002846FFF70DF90178A06880F8F81080F864
+:10D9E000FB60A06890F8E01003292AD0E97811F0D4
+:10D9F0003F0F1CBF297911F0010F08D000F1F00290
+:10DA0000911F284601F08FFBA06880F8F960E87844
+:10DA100010F03F0F1ABF287910F0020FBDE8F08117
+:10DA200001212846FFF7E4F8A1680268C1F8F12057
+:10DA30008088A1F8F50081F8F78081F8FA60BDE8E8
+:10DA4000F081022F18BF012FD0D1BDE8F08123490A
+:10DA5000896881F80A01704770B5204DA86890F870
+:10DA6000E010022919BF90F8E010012900210C46AE
+:10DA70001CBF0C2070BD00BFC1EB411200EB420285
+:10DA8000034682F82840491CC9B20229F4D3047025
+:10DA900080F8224093F8DD0030B1F7F719FBF6F774
+:10DAA000E8FCA86880F8DD40A868012180F8DC4027
+:10DAB00080F8C11080F8C84080F8DF40282180F845
+:10DAC0000B1180F80A41A0F8E34080F8E5400721F7
+:10DAD00080F8C010002070BDD81100206401002023
+:10DAE000D4480200F74810B58068002180F8E010A3
+:10DAF000012180F8E010FFF7AFFF002818BFFFDF1B
+:10DB000010BD2DE9F047EF4C07460C26A06890F8B1
+:10DB1000E01001291FBF90F8E00002280C20BDE8AA
+:10DB2000F087F6F778FEA06890F90A01F6F720FF73
+:10DB3000A06890F8C91080F8E21090F8C010012594
+:10DB4000002978D090F8C8004FF00009032802D0CF
+:10DB5000022805D008E00521DB4801F0ADFB03E019
+:10DB60000321D94801F0A8FBA06890F8D81000293B
+:10DB700004BF90F8DB00002843D0F5F749F80646CB
+:10DB8000A0683146D0F8D400F5F750FDCF4990FB9E
+:10DB9000F1F801FB180041423046F4F742FD01461E
+:10DBA000A068C0F8D410D0F8D0104144C0F8D0100C
+:10DBB000FDF7F3FD0146A068D0F8D020914220D8AF
+:10DBC000C0E9349690F8DB0000281CBF0120FDF767
+:10DBD00008FF0121A06890F8DC20002A1CBF90F803
+:10DBE000D820002A0DD090F8B93000F1BA02012BEC
+:10DBF00004D1527902F0C002402A14D0BA30F7F7AB
+:10DC000085FEA06890F8B910BA30F6F769FE0F21CA
+:10DC10000720F6F781FEA068002690F8E0100129A1
+:10DC200018D112E007E0FDF709FFA1682A46BA31D2
+:10DC3000F7F735FEE5E790F8E010022904BF80F819
+:10DC4000E0500C2006D1BDE8F08780F80451022195
+:10DC500080F8E010A06890F8C10088B1FDF769FE77
+:10DC600003219B48FDF7A1FE0146A06880F8DD1066
+:10DC7000C0F800719748F7F750F93046BDE8F087D3
+:10DC8000FDF700FEECE738B58E4CA06890F8E01088
+:10DC900002291CBF0C2038BD012180F80511A0F815
+:10DCA000081129208DF800006846F5F7F3FF30B120
+:10DCB000A0689DF8001090F80601884205D1A06880
+:10DCC00090F80601401C8DF80000A1689DF8000046
+:10DCD00081F806010220F7F734F97F48F6F752FE83
+:10DCE000A168DFF8F8C1002091F8C03091F8DF207A
+:10DCF000521CACFB02546408A4EB8404224481F857
+:10DD0000DF2023FA02F212F0010F03D1401CC0B24F
+:10DD10000328EBD3FFF7CDFD002038BD69498968A2
+:10DD200081F8C900002070476649896881F8DA00E7
+:10DD3000704710B5634CA36893F8B830022B14BF3A
+:10DD4000032B00280BD100291ABF02290120002033
+:10DD50001146FDF725FD08281CBF012010BDA06855
+:10DD600090F8B800002816BF022800200120BDE866
+:10DD70001040F7F755BD5348806890F8B800002868
+:10DD800016BF022800200120F7F74ABD4D498968D7
+:10DD900081F8B80070474B49896881F8DC0070470A
+:10DDA00070B5484CA16891F8B800002816BF022849
+:10DDB0000020012081F8B900BA31F7F71BFDA068F7
+:10DDC00090F8B810022916BF03290121002180F81C
+:10DDD000DB1090F8B920002500F1BA03012A04BF36
+:10DDE0005B7913F0C00F0AD000F1BA03012A04D105
+:10DDF0005A7902F0C002402A01D0002200E001223C
+:10DE000080F8D820002A04BF002970BDC0F8D05087
+:10DE1000F4F7FEFEA168C1F8D40091F8DB000028F9
+:10DE20001CBF0020FDF7DDFD0026A06890F8DC1087
+:10DE300000291ABF90F8D810002970BD90F8B920B9
+:10DE400000F1BA01012A04D1497901F0C001402949
+:10DE500005D02946BDE87040BA30F7F757BDFDF749
+:10DE6000EDFDA1683246BDE87040BA31F7F717BD45
+:10DE700070B5144D0C4600280CBF01230023A9687F
+:10DE800081F8C13081F8CB004FF0080081F8CC0058
+:10DE90000CD1002C1ABF022C012000201146FDF7E6
+:10DEA0007FFCA968082881F8CC0001D0002070BD53
+:10DEB000022C14BF032C1220F8D170BD002818BF0B
+:10DEC00011207047640100200012002040420F0022
+:10DED000D8110020D1480200D7480200ABAAAAAA54
+:10DEE0000328FE4A926808BFC2F8C41082F8C8002E
+:10DEF0000020704710B5044602F018FF052809D02D
+:10DF000002F014FF042805D0F448806880F8D94056
+:10DF1000002010BD0C2010BDF048816891F8C800A9
+:10DF2000032804D0012818BF022807D004E091F884
+:10DF3000CB00012808BF70470020704791F8CA0045
+:10DF4000012814BF03280120F6D1704710B5F7F758
+:10DF5000A1F8F7F780F8F6F77BFFF6F7E4FFDF4C60
+:10DF6000A06890F8DD0038B1F7F7B2F8F6F781FA5B
+:10DF7000A168002081F8DD00A068012180F804116B
+:10DF8000022180F8E010002010BDD449896881F892
+:10DF9000FC007047017801291CBF122070474278AD
+:10DFA0000023032ACD49896808BFC1F8C43081F82D
+:10DFB000C820012281F8C920C27881F8B8200279EE
+:10DFC000002A16BF022A0123002381F8C13081F8FC
+:10DFD000CA20427981F8C020807981F8DA000020D7
+:10DFE0007047BE488068704701F0D6B82DE9F84FF9
+:10DFF0004FF00008B948F7F790F8B84C4FF07F0A97
+:10E00000002808BF84F800A0F7F772F8B448FEF7BC
+:10E010002CFDA070A16891F8E220012A18BFFFDF53
+:10E020000AD0A06890F8DD0018B1F7F751F8F6F7BC
+:10E0300020FA4046BDE8F88FA94D0026A5F5867761
+:10E04000072836D291F8C10028B9F6F793FC0028CA
+:10E0500008BF002600D00126A06890F8DD0080B13E
+:10E06000FDF7F5FBA168FF2881F8DE000ED0014620
+:10E07000E81CFDF7E1FBA06890F8DE00FDF7F2FB7D
+:10E080000643A06890F8DE00FF2817D1FDF781FC59
+:10E0900087F8DE0097F8C11081B108280ED12878E2
+:10E0A000E91CC0F38010FDF77BFB082818BF002691
+:10E0B00004E002BF91F8D90000280126A0784FF0B3
+:10E0C00000094FF0010B08281BD2DFE800F035AF44
+:10E0D000041A1A1A12F9002E00F06581A06890F84F
+:10E0E000C800012818BF022840F05D81F6F7B0FE95
+:10E0F0007AE036B1A06890F8C800022806D001285E
+:10E1000072D0F6F7A5FE4FF003088AE700217448A5
+:10E11000FFF732FBA0684FF00808C0F8E790C0F89E
+:10E12000EB90C0F8EF90C0F8F390C0F8F79080F84B
+:10E13000FB9080F8E79074E74FF00008002E00F0A5
+:10E140003281A26892F8C80002282DD001284BD055
+:10E1500003287FF466AFD2F8C400E978837E994241
+:10E160001BD12979C37E994217D16979037F9942DE
+:10E1700013D1A979437F99420FD1E979837F9942DD
+:10E180000BD1297AC37F994207D12978437EC1F305
+:10E190008011994208BF012100D0002192F8CB20C4
+:10E1A000012A26D0A9B3FBE000214D48FFF7E4FA8D
+:10E1B000A06890F8051129B1491E11F0FF0180F8FF
+:10E1C00005117CD1C0F8E790C0F8EB90C0F8EF9053
+:10E1D000C0F8F390C0F8F79080F8FB904FF0080873
+:10E1E00080F8E7B01DE7FFE700213D48FFF7C4FADC
+:10E1F00019E0002965D100BF00F11A013848FEF787
+:10E200003FFC3748FEF75AFCA168D1F8C4104876A5
+:10E21000C6E0FFE797F8CC00082850D097F8DE104A
+:10E2200081424ED0BFE04FF00308FAE6A06890F8B4
+:10E23000DB1000290CBF4FF0010B4FF0000B4FF02B
+:10E240000008297805F10902C90907D0517901F0C0
+:10E25000C001402908BF4FF0010901D04FF000096B
+:10E2600090F8C810032906D190F8C110002918BFF2
+:10E2700090F8CC0001D190F8DE00FDF7ADFA5FEA2E
+:10E28000000A13D01021FEF730F9002818BF4FF014
+:10E29000010BB9F1000F04BFA06890F8B9A00DD030
+:10E2A00005F109015046F7F7C9FA8046A068B9F1AF
+:10E2B000000F90F8B9A018BF4AF0020A02E072E01D
+:10E2C0008CE06DE090F8C810032913D0F6F7C0FD7C
+:10E2D000DEB3F6F71DFB50EA080003E064010020FE
+:10E2E000D811002062D08DF800A06946FD48FFF7E4
+:10E2F00043FA98E7D0F8C400E978827E91421BD1B6
+:10E300002979C27E914217D16979027F914213D156
+:10E31000A979427F91420FD1E979827F91420BD155
+:10E32000297AC27F914207D12978407EC1F38011BA
+:10E33000814208BF012500D0002597F8DE0008289B
+:10E3400008D097F8CC10884200E02FE008BF4FF0CB
+:10E35000010901D04FF00009B8F1000F05D1BBF160
+:10E36000000F04D0F6F7D4FA08B1012000E0002035
+:10E370004EB197F8CB10012903D021B955EA090114
+:10E3800001D0012100E0002108420CD0A06890F8E3
+:10E39000CB10012904BF002DD0F8C4003FF42CAFEE
+:10E3A0004FF00A083DE6F6F753FD3CE7A06890F809
+:10E3B000CA00032818BF02287FF435AFB9F1000F57
+:10E3C0003FF431AFB8F1000F7FF42DAFC648694676
+:10E3D00040680090C348FFF7CFF924E7A06890F8A1
+:10E3E000DA0000283FF48DAEF6F732FDA06890F811
+:10E3F000D91000297FF417AFC0F8E790C0F8EB9070
+:10E40000C0F8EF90C0F8F390C0F8F79080F8FB9058
+:10E4100080F8F8A0B348FEF79AFCE8B301287CD056
+:10E4200002287FF400AFA0684FF0030890F8C800FE
+:10E43000032814BF0020012036EA00003FF4F1ADAC
+:10E44000A84D1820E97811F03F0F3FF4EAAD297983
+:10E4500088437FF4E6AD04212846FEF7C9FB064653
+:10E46000A06890F8E20002F0CCF80146304600F0D7
+:10E47000B5FE00283FF4D5AD002202212846FFF763
+:10E4800072FA2846FEF763FC0146A06880F8E610A1
+:10E490003188A0F8E31000E005E0B17880F8E510DD
+:10E4A0004FF00408BDE5002E3FF4BDAEA06890F823
+:10E4B000C810012918BF02297FF4B5AE894DE9784B
+:10E4C00011F03F0F1CBF297911F0020F05D011F098
+:10E4D000010F18BF4FF0010901D14FF000094FF0B3
+:10E4E0000008B9F1000F52D028780027C609012191
+:10E4F0002846FEF77DFB36B1407900F0C000402889
+:10E5000008BF012600D00026A06890F8C810032993
+:10E5100008D190F8C110002900E0AEE018BF90F8D3
+:10E52000CC0001D190F8DE00FDF756F95FEA000853
+:10E530000CD01021FDF7D9FF46B101212846FEF786
+:10E5400057FB01464046F7F779F90746A068002EC9
+:10E5500090F8B98018BF48F00208E87810F03F0F33
+:10E560001CBF287910F0020F0ED02846FEF7B3FA30
+:10E57000824601212846FEF73BFB5146F6F7B8F9E3
+:10E58000002818BF012000D1002038435FD0E87870
+:10E5900010F03F0F1EBF297911F0100F11F0080F76
+:10E5A00041D004212846FEF723FB0646A06890F8D8
+:10E5B000E20002F026F80146304600F00FFEA0B15E
+:10E5C000424600212846FFF7CEF94648FEF7BFFB3A
+:10E5D0000146A06880F8E6103188A0F8E310B17811
+:10E5E00080F8E5104FF004081BE5A06890F8E20001
+:10E5F00001287FF418AEE87810F03F0F1CBF28798F
+:10E6000010F0010F3FF40FAEB9F1000F04D100215B
+:10E610002846FEF7D7FE06E68DF8008069462846B4
+:10E62000FEF7D0FEFFE510F03F0F1CBF297911F077
+:10E63000100F7FF4F8AD10F03F0F1CBF287910F0D9
+:10E64000010F3FF4F0ADB9F1000FE5D1DFE7A068AD
+:10E6500090F8CA00032818BF02287FF4E4AD002E0A
+:10E660003FF4E1AD002F7FF4DEAD1F48694600683E
+:10E6700000902846FEF7A6FED5E5002E3FF4D3AD68
+:10E68000184D1820E97811F03F0F3FF4CCAD2979EF
+:10E6900088437FF4C8AD04212846FEF7A9FA064650
+:10E6A000A06890F8E20001F0ACFF0146304600F0AF
+:10E6B00095FD00283FF4B7AD002201212846FFF761
+:10E6C00052F92846FEF743FB0146A06880F8E610A1
+:10E6D0003188A0F8E310B17880F8E5104FF0040815
+:10E6E0009FE40000D8110020C84802002DE9F04145
+:10E6F000FD4CA0680078002818BFFFDF0025A06847
+:10E7000001278570D0F8C4100A8882804A88428325
+:10E710008A888283C988C18380F82050F34990F8A1
+:10E72000DB20A1F59A764AB10A78C2F38013CA1C9D
+:10E7300023B1527902F0C002402A33D090F8DC2095
+:10E7400042B111F8032BC2F380121AB1497911F0CA
+:10E75000C00F27D00E3005F0CFFEA06890F8DD0086
+:10E7600018B1F5F7A6FE012824D0A068D0F8C4108F
+:10E770004A7EC271D1F81A208260C98B81814561BD
+:10E780000583A0680770D0F8C42090F80A1182F8B9
+:10E790005710D0F8C4000088F2F73CFABDE8F04109
+:10E7A000F1F7D2BED6F83711C0F80E10B6F83B110B
+:10E7B0004182D2E7F5F7C0FEA16801F10802C91D48
+:10E7C000FDF71CF8002808BFFFDFA068C17941F001
+:10E7D0000201C171D6F80F114161B6F8131101831E
+:10E7E000CFE72DE9F84FC04C0546FF21A068002770
+:10E7F0004FF0010980F8DE1090F8C800BA460128F1
+:10E8000018BF022802D0032818BFFFDF28004FF0EE
+:10E81000040B4FF07F08B54EA6F1280500F04B81A0
+:10E820002846FEF73DFA28B92846FEF793FA002855
+:10E8300000F04181A06890F8E000082880F038815D
+:10E84000DFE800F0FEFEFE04080CCF7BFFF7CEFBF6
+:10E8500000F0C5B800F093FD00F0C1B8A448FEF781
+:10E8600004F92071E878717A88421CD12879B17A4C
+:10E87000884218D16879F17A884214D1A879317B1D
+:10E88000884210D1E879717B88420CD1287AB17B1B
+:10E89000884208D128783178C0F38010B0EBD11FBE
+:10E8A00008BF012500D00025F6F7D2FA8E48F6F70A
+:10E8B00034FC002808BF84F80080F6F719FC2079A2
+:10E8C000042840F04D81002D00F04A81CDF800A0D1
+:10E8D000A2688748694692F8D93053B3064692F841
+:10E8E0006600002840F03C8102F1680582F872B0B1
+:10E8F0006932A91C304600F016FC05F10B013046C8
+:10E90000FEF73DF9C0B228721F2884BF1F2028726D
+:10E91000207809357F2808BFFFDF2078287084F829
+:10E920000080A06880F86690062002F019F800F0D8
+:10E9300017B9FEF747FD00F013B903276A48F6F749
+:10E94000ECFB002808BF84F80080F6F7D1FB68488C
+:10E95000FEF78BF880466648FEF7F9F9B8F1080F24
+:10E9600008BF00283AD1E978032011F03F0F35D0D5
+:10E970002979884332D100215D48FEF739F9062212
+:10E9800006F1090105F0E8FB40BB5948FEF796F88F
+:10E9900080465648FEF79FF880451FD10121544814
+:10E9A000FEF726F90622F11C05F0D6FBB0B9504857
+:10E9B000FEF791F880464D48FEF780F880450DD16E
+:10E9C000F6F768FBF6F747FBF6F742FAF6F7ABFA0D
+:10E9D0000227FFF78BFE042001F0C2FF38460746EE
+:10E9E000B2E0F6F735FA4048F6F797FB002808BF83
+:10E9F00084F80080F6F77CFB3D48FEF736F80746C2
+:10EA00003B48FEF7A4F9072F08BF00284FD1E9784B
+:10EA1000012011F03F0F4AD02979884347D10021C6
+:10EA20003348FEF7E5F8062206F1090105F094FBEC
+:10EA300000283CD12E48FEF741F805462B4800E05F
+:10EA400036E0FEF748F8854231D1A06890F804110D
+:10EA500029B3B0F8082190F80611012A05D9520807
+:10EA6000A0F8082108BFA0F80891012914BF0029C7
+:10EA70000D21C943C1EBC10202EB011190F8052140
+:10EA8000D24302EB8203C3EB82121144B0F8082197
+:10EA9000890CB1FBF2F302FB131180F8051180F829
+:10EAA000049169461248CDF800A0FEF78BFC57E0B0
+:10EAB000FFDFBDE8F88FA06890F8E000082843D297
+:10EAC000DFE800F0424242041F2E3F350648F6F7C9
+:10EAD00024FB002808BF84F80080F6F709FBA06833
+:10EAE00090F8DD0050B105E0640100200012002024
+:10EAF000D8110020F6F7ECFAF5F7BBFCF6F7A8F909
+:10EB00002EE0FE48F6F709FB002808BF84F80080D5
+:10EB1000F6F7EEFAA06890F8DD000028EED0E2E704
+:10EB2000F648F6F7FAFA38B984F8008004E0F348BA
+:10EB3000F6F7F3FA0028F7D0F6F7DAFAF6F788F9DD
+:10EB40000EE000F02FFE0BE00C2F80F01982DFE8C2
+:10EB500007F006FDFC07FBFAFAFA0BF94FBBA8E732
+:10EB6000BDE8F84FFEF7A5BE00220121022001F00A
+:10EB700051FD002800F04181E149A1F12800FDF795
+:10EB8000ADFFA068DE4E90F8B9103046FDF78DFF5E
+:10EB9000A06800F1BA013046FDF76BFFA06890F85D
+:10EBA000DB10C1B190F8C810032906D190F8C1104C
+:10EBB000002918BF90F8CC0001D190F8DE00FCF7D6
+:10EBC0003FFF050007D001213046FDF76EFF2946C3
+:10EBD0003046FDF74EFFCA48F6F7B6F90121084660
+:10EBE000F6F7B3FAA168082081F8E000BDE8F88FD5
+:10EBF000A06890F8E21090F8E2100022032001F0E3
+:10EC000009FD00287ED0BF4F0A2087F8E0000120D0
+:10EC100001F0A6FE07F59A71A1F12800FDF75EFF4D
+:10EC2000A06807F59A7890F8B9104046FDF73DFFC7
+:10EC3000A06800F1BA014046FDF71BFFA06890F8FC
+:10EC4000DB10C9B190F8C810032906D190F8C110A3
+:10EC5000002918BF90F8CC0001D190F8DE00FCF735
+:10EC6000EFFE5FEA000907D001214046FDF71DFFD6
+:10EC700049464046FDF7FDFEA268A149D2F8C4000E
+:10EC8000C08AC875000A0876D2F8C400407DB07505
+:10EC90000846F6F759F99A48D7F8C41020230278A5
+:10ECA000497B22F0200203EA411111430170D7F899
+:10ECB000C4002A78417BC2F340121140417397F897
+:10ECC0000B01D7F8C4106FE0A06890F8E21090F83C
+:10ECD000E2100022052001F09DFC98B1894D0B2027
+:10ECE00085F8E000022001F03BFE05F59A71A1F1E4
+:10ECF0002800FDF7F3FEA06805F59A7790F8B910A3
+:10ED0000384600E079E0FDF7D0FEA06800F1BA01D6
+:10ED10003846FDF7AEFEA06890F8DB10F9B190F828
+:10ED2000C810032906D190F8C110002918BF90F827
+:10ED3000CC0001D190F8DE00FCF782FE5FEA00080B
+:10ED40000DD004E034E01BE18EE085E07FE001219E
+:10ED50003846FDF7AAFE41463846FDF78AFEA2680E
+:10ED60006749D2F8C400C08AC875000A0876D2F88C
+:10ED7000C400407DB0750846F6F7E6F8D5F8C40043
+:10ED800080F80D90A06890F8E230012296210020D2
+:10ED9000F5F790FF5A48017821F020010170A06832
+:10EDA000D5F8C41090F80B0181F85600BDE8F88F33
+:10EDB000A06890F8E21090F8E2100022042001F020
+:10EDC00029FCD0B14E49A1F12800FDF787FEA068CB
+:10EDD0004B4E90F8B9103046FDF767FEA06800F181
+:10EDE000BA013046FDF745FEA06890F8DB10E9B1A6
+:10EDF00090F8C810032904D00AE0BDE8F84F00F0ED
+:10EE0000CBB990F8C110002918BF90F8CC0001D1FF
+:10EE100090F8DE00FCF714FE050007D00121304613
+:10EE2000FDF743FE29463046FDF723FE3448F6F74A
+:10EE30008BF8A06890F8E230012296210020F5F7C7
+:10EE400039FFA168092081F8E000BDE8F88FA068CB
+:10EE500080F8E090BDE8F88FA068022180F8049166
+:10EE600080F8E010BDE8F88FA56815F8E31F11F0F1
+:10EE7000800F0CBF1E204FF49670B5F80120C2F32E
+:10EE80000C0212FB00F6C80908BF4FF01E0906D09D
+:10EE9000002806BFFFDF4FF000094FF49679A878ED
+:10EEA000400908BF012703D0012814BF002702270B
+:10EEB000A06890F8E20001F0A4FBA6EB0008287817
+:10EEC00008EB0906C0F38010002808BF4FF4FA7A57
+:10EED00005D006BFFFDF4FF0000A4FF0320A0948A5
+:10EEE00090F8FC90B9F10C0F28BFFFDF0648074AE5
+:10EEF00030F819000AEB00010AE00000640100206C
+:10EF000000120020CC100020DC4802003F420F001D
+:10EF100001FB0620511CB0FBF1F000F120094E442A
+:10EF2000F6F709F8287800F03F052846F5F732FD96
+:10EF3000A06880F8E15039462520F5F738FC012219
+:10EF4000A8EB09013B461046F5F7B4FEFE48F5F77D
+:10EF5000FBFF00213046F6F743F8A06880F8E27026
+:10EF6000F6F7D0F8A06890F8DD0020B1F5F76DFA5B
+:10EF70005020F6F79BF8A06880F8E0B0BDE8F88F65
+:10EF8000FFDFBDE8F88FF14810B5806890F8E00029
+:10EF90000C285FD2DFE800F05E5E5E5E5E5E5E5E65
+:10EFA0000613472DE848F5F7CFFFF6F7ABF8002139
+:10EFB0009620F6F715F8E5490520896830E0E24823
+:10EFC000F5F7C2FFE14CA06890F8E23001229621EB
+:10EFD0001046F5F76FFEA06890F8E2000021962039
+:10EFE000F5F7FEFFF6F78EF8A168062081F8E0003D
+:10EFF00010BDD548F5F7A8FFD44CA06890F8E230D2
+:10F00000012296211046F5F755FEA06890F8E2001F
+:10F0100000219620F5F7E4FFF6F774F8A1680720C1
+:10F0200081F8E00010BDF6F735F8F6F714F8F5F7BB
+:10F030000FFFF5F778FFC5480121806880F80411BB
+:10F04000022180F8E010FFF751FBBDE810400320DB
+:10F0500001F086BCFFDF10BD70B5BC4CA06890F815
+:10F06000E0007F25082828BF70BDDFE800F03F3FA3
+:10F070003F172304390AB548F6F74FF830B9257021
+:10F0800004E0B248F6F749F80028F8D0F6F730F86F
+:10F09000F5F7DEFEBDE87040FEF70BBCAB48F6F7B7
+:10F0A0003CF8002808BF2570F6F722F8BDE870404C
+:10F0B00000F072B8A548F6F730F8002808BF2570B0
+:10F0C000F6F716F8A06890F8DD0018B1F6F700F82A
+:10F0D000F5F7CFF9F5F7BCFEBDE87040FEF7E9BBE8
+:10F0E00000F060FBBDE87040FEF7E3BB70BD70B59B
+:10F0F000964C06460D46012909D0A06890F8E230EA
+:10F1000090F8E2203046BDE8704001F0E9BDF5F727
+:10F1100011FBA16891F8E220034629463046BDE87C
+:10F12000704001F0DDBD70B50646884814460D46B6
+:10F13000806890F8DD0018B1F5F7BBF901280ED012
+:10F140003046FDF7BBFC20703046FDF78EFC0728EB
+:10F1500013D229463046BDE87040FDF791BCF5F763
+:10F16000EBF92A462146FCF749FB002808BFFFDFE0
+:10F17000207840F00200207070BD3046FDF775FC2D
+:10F18000072818BF70BD00213046FDF731FD01682A
+:10F1900029608088A88070BD10B5F5F77BFFF5F772
+:10F1A0005AFFF5F755FEF5F7BEFE684CA06890F8DB
+:10F1B000DD0038B1F5F78CFFF5F75BF9A1680020A9
+:10F1C00081F8DD00A068012180F80411022180F897
+:10F1D000E010BDE81040002001F0C2BB2DE9F04175
+:10F1E000044680780222B2EB501F26D00D462178CB
+:10F1F00011F0800F0CBF1E204FF49670B4F8012060
+:10F20000C2F30C0212FB00F6C80908BF1E2105D08C
+:10F21000002806BFFFDF00214FF49671701BA27813
+:10F22000520908BF012703D0012A14BF0027022773
+:10F23000B0F5877F28BFAE4202D20020BDE8F08142
+:10F2400045182078C0F38010002808BF4FF4FA76E4
+:10F2500003D006BFFFDF002632263D4890F8FC4071
+:10F260000C2C28BFFFDF3B483B4A30F81400311814
+:10F2700001FB0520511CB0FBF1F020300544334860
+:10F28000806890F8E200F6F7B6F904463846F6F7DB
+:10F29000B2F94FF47A7184423ABF001B00F2E730B2
+:10F2A000201AB0FBF1F034BF42192A1A3946BDE8E2
+:10F2B000F041012001F0AEB970B50D460446FDF7EE
+:10F2C000AFFB032D55D0052D18BF70BD052120467D
+:10F2D000FDF7ABFB1D4DA868D0F8C40000F10E018E
+:10F2E0002046FDF760FCA868D0F8C40000F11201C8
+:10F2F0002046FDF75CFCA868D0F8C410497DA175D4
+:10F30000D0F8C410C98AE175090A2176D0F8C41072
+:10F3100049886176090AA176D0F8C4108988E17617
+:10F32000090A2177D0F8C410C9886177090AA17742
+:10F33000D0F8C40000F108012046FDF756FCA8688B
+:10F34000D0F8C400017E09E0D8110020640100203B
+:10F35000CC100020DC4802003F420F002046FDF7A1
+:10F360002CFCA86890F8FC102046BDE87040FDF722
+:10F370002EBC2046BDE870400321FDF756BB2DE9A9
+:10F38000F84FFD48F5F7C9FEFB4C002804BF7F206D
+:10F390002070F5F7ADFEA06890F8D900002818BFDE
+:10F3A000FFDFF648FDF761FBDFF8D083E0704FF038
+:10F3B000000998F803004D4610F03F0F1CBF98F865
+:10F3C000040010F0080F14D0EC48FDF7C0FC70B139
+:10F3D000012802D002280AD00BE098F8030010F0B0
+:10F3E0003F0F1CBF98F8040010F0010F01D04FF040
+:10F3F0000109A06890F8DD0018B1F5F769FEF5F78E
+:10F4000038F898F803002E4637464FF0000A10F0FF
+:10F410003F0F1CBF98F8040010F0020F43D0A06803
+:10F42000DFF858A3002690F8DB0000280CBF012766
+:10F4300000279AF800000121C5095046FDF7D8FBC6
+:10F4400035B1407900F0C000402808BF012500D048
+:10F450000025A06890F8C810032906D190F8C110C3
+:10F46000002918BF90F8CC0001D190F8DE00FCF71D
+:10F47000B3F95FEA000B0FD01021FDF736F8002832
+:10F4800018BF012745B101215046FDF7B1FB0146E8
+:10F490005846F6F7D3F90646A068002D90F8B9A0B3
+:10F4A00018BF4AF0020AE0784FF0030B072875D125
+:10F4B000B248FDF74CFC002800F0F280012803D090
+:10F4C000022800F031819FE0009700270321AB481C
+:10F4D000FDF78EFBB9F1000F7ED0A16891F8E7200F
+:10F4E000012A79D1427891F8E9301209B2EB131F61
+:10F4F00072D10088B1F8E810C0F30B00C1F30B0122
+:10F50000884269D19D48FDF722FCA16891F8E62068
+:10F51000904261D191F8C800012818BF022802D09A
+:10F5200003283CD0B9E0F5F793FC98F8030010F0FD
+:10F530003F0F1CBF98F8040010F0020F17D08F4F38
+:10F540003846FDF7C8FA804601213846FDF750FBE2
+:10F550004146F5F7CDF9002818BF012030430BD004
+:10F560008DF800A069468548FDF72CFF14E00021C6
+:10F570008248FDF727FF0FE0A06890F8CA00032833
+:10F5800018BF022808D13DB136B97D486946806868
+:10F5900000907A48FDF716FF03277EE034E0002153
+:10F5A0007648FDF725FBA1680622D1F8C4101A3170
+:10F5B00004F0D2FD50B97148FDF780FAA168D1F886
+:10F5C000C410497E884208BF012500D0002598F864
+:10F5D000030010F03F0F00E05CE01CBF98F804004F
+:10F5E00010F0020F01D0CEB127E0A06890F8CB1048
+:10F5F000012901D015B10CE05DB937E090F8DE10BB
+:10F6000090F8CC00814204D0F5F722FC5846BDE8C2
+:10F61000F88FA06890F8E2000B273EE0009870B1E8
+:10F62000564E3046FDF757FA074601213046FDF7A2
+:10F63000DFFA3946F5F75CF908B1012200E0002253
+:10F64000A06890F8CB10012907D041B92DB990F8E6
+:10F65000DE3090F8CC00834201D1012000E0002090
+:10F66000024217D0012908BF002DD2D10021434802
+:10F67000FDF7BEFAA1680268D1F8C410C1F81A20DB
+:10F680008088C8833D48FDF719FAA168D1F8C410F5
+:10F690004876BEE7F5F7DCFB03273846BDE8F88F70
+:10F6A000F5F7D6FB03213548FDF7A2FAB9F1000FB3
+:10F6B00036D0A16891F8E7206ABB427891F8E9302A
+:10F6C0001209B2EB131F2BD10088B1F8E810C0F378
+:10F6D0000B00C1F30B01884222D12848FDF737FB0C
+:10F6E000A16891F8E62090421AD191F8C80001284B
+:10F6F00018BF022814D198F8030010F03F0F1CBF68
+:10F7000098F8040010F0020F06D08DF800A06946AA
+:10F710001A48FDF757FE03E000211848FDF752FE96
+:10F720005846BDE8F88F00BFF5F792FBA06890F847
+:10F73000C80003281CD01148FDF709FBA16891F807
+:10F74000E620904214D198F80320092012F03F0FD0
+:10F750000ED098F8042090430AD1B9F1000F07D0D9
+:10F7600091F8C80002280DD000210448FDF72AFEB8
+:10F770000320BDE8F88F000064010020D8110020AC
+:10F78000C848020091F8050128B1401E10F0FF00A2
+:10F7900081F80501ECD1524601212348FEF7E3F838
+:10F7A0000920E6E710B5F5F753FB2048F5F7B5FC5F
+:10F7B0001E4C002804BF7F202070F5F799FCA0683C
+:10F7C00090F8041119B1002180F8041110BDB0F8AF
+:10F7D000082190F80611FF2A0AD24FF6FF7303EAB8
+:10F7E0004202A0F80821FF2A84BFFF22A0F80821C6
+:10F7F000012914BF00290D21C943C1EBC10202EB4D
+:10F80000011290F80511C94301EB8103C3EB81118B
+:10F810001144B0F80821890CB1FBF2F302FB13117B
+:10F8200080F80511CFE70000D81100206401002006
+:10F830002DE9FF4F07460C46488881B040F2E2416F
+:10F8400048430090E08A002600FB01FB94F8640026
+:10F8500091460D2818BF0C281FD024281EBF94F8ED
+:10F86000650024284FF0000A17D0049818B1012130
+:10F87000204602F0B2FB94F8540094F8558094F8B6
+:10F88000D010054661B101296DD0022952D003295B
+:10F8900018BFFFDF67D000F0D5B84FF0010AE4E7EA
+:10F8A000B9F1000F08BFFFDFFD4EB068002808BFA8
+:10F8B000FFDF94F85410FB4890F82400FDF79DF802
+:10F8C000009094F85400F5F7A5FE00F2E7314FF4EC
+:10F8D0007A79B1FBF9F1F24880680E1894F8540077
+:10F8E000F5F798FE014694F85400022804BFEE484C
+:10F8F0004FF47A720DD0012804BFEC484FF4C8626F
+:10F9000007D0042807BFEA4840F69802E94840F6C5
+:10F91000E4421044084400F2E731B1FBF9F10098E9
+:10F92000401A00EB0B01DE48406930440844061DD4
+:10F93000012015E0DA48A9F101018068084308BFF9
+:10F94000FFDFDD48B9F1000F006800EB0B0606D0C1
+:10F95000D348806800F22230B04288BFFFDF032026
+:10F9600084F8D0006DE094F86410009E24291EBF36
+:10F9700094F86520242A25294FD1B4F85810B4F8FA
+:10F98000F020891A491C09B2002946DB94F8F210CC
+:10F99000002942D00D4694F8F310002918BF88467C
+:10F9A000022804BFC0494FF47A700DD0012804BF6B
+:10F9B000BE494FF4C86007D0042807BFBC4940F6D1
+:10F9C0009800BC4940F6E4400144022D04BFB6480B
+:10F9D0004FF47A720DD0012D04BFB4484FF4C862C1
+:10F9E00007D0042D07BFB24840F69802B14840F650
+:10F9F000E4421044814208D9081A00F5FA714FF424
+:10FA00007A70B1FBF0F0064407E0401A00F5FA7195
+:10FA10004FF47A70B1FBF0F0361AB9F1000F10D044
+:10FA2000DFF87C92D9F8080020B9B9F80200002864
+:10FA300018BFFFDFD9F8080000F22230B04288BFBB
+:10FA4000FFDF06B9FFDF3146D4F8D400F2F7E9FD55
+:10FA5000C4F8D400B860002038704FF0010987F86E
+:10FA60000490204602F0A6FBAAF10101084208BF5B
+:10FA700087F8059006D094F8D00001280CBF02202A
+:10FA8000032078714046D4F824B0F5F7B4FD014660
+:10FA9000022D04BF84484FF47A720DD0012D04BFAB
+:10FAA00082484FF4C86207D0042D07BF804840F653
+:10FAB0009802804840F6E4421044084400F23F6156
+:10FAC0004FF47A70B1FBF0F0584400F5C970F8605B
+:10FAD000049830EA0A0004BF05B0BDE8F08F314653
+:10FAE0003846FCF724FE85B2204602F063FBA842AC
+:10FAF0000FD8054687F8059006FB05F1D4F8D40029
+:10FB0000F2F78FFDB86031463846FCF710FE284406
+:10FB100085B22946204602F060FAB868C4F8D400DD
+:10FB200005B0BDE8F08F2DE9F0430446634885B089
+:10FB30000D4690F80004DFF88891400999F8001408
+:10FB40004909884218BFFFDFDFF85481002708F118
+:10FB50004406082D80F00E81DFE805F0046872721B
+:10FB60006DFEFEB6202C28BFFFDF36F814000621FC
+:10FB7000F0F71EFF050008BFFFDF202C28BFFFDFC6
+:10FB800036F814002988884218BFFFDF95F8D000A6
+:10FB9000002808BFFFDF284601F02EFFC8F80870D4
+:10FBA000A8F8027029460020C8F81470FCF710FE6F
+:10FBB00000F19804686AA04225D995F85500F5F738
+:10FBC0001AFD014695F85400022804BF36484FF448
+:10FBD0007A720DD0012804BF34484FF4C86207D0B0
+:10FBE000042807BF324840F69802324840F6E44203
+:10FBF000104408444FF47A7100F23F60B0FBF1F119
+:10FC0000686A0844071B29460020C8F80C70FCF7F6
+:10FC1000DFFD698840F2E24251439830081AA0F2B1
+:10FC20002230C8F8100005B0BDE8F08305B0BDE88B
+:10FC3000F04302F0ADB805B0BDE8F043F5F7A9BA5E
+:10FC400099F8140D1F49400991F800144909884298
+:10FC500018BFFFDF202C28BFFFDF36F81400062175
+:10FC6000F0F7A6FE050008BFFFDF202C28BFFFDF4E
+:10FC700036F814002988884218BFFFDF00220123CC
+:10FC800029466846FFF7D4FD95F8DA006946F3F790
+:10FC900007FA002808BFFFDF05B0BDE8F0830000C9
+:10FCA000281200204412002068360200A22402001C
+:10FCB000D0FB010030D301007401002001E000E01E
+:10FCC0000BE000E019E000E0202C28BFFFDF36F851
+:10FCD00014000621F0F76CFE050008BFFFDF202CA2
+:10FCE00028BFFFDF36F814002988884218BFFFDFDD
+:10FCF00095F8D000042818BFFFDF85F8D07095F87C
+:10FD0000DA404FF6FF79202C28BFFFDF26F8149049
+:10FD100095F8DA00F2F75DFF002808BFFFDF20202A
+:10FD200085F8DA00D5F8E000002804BFD5F8DC003B
+:10FD3000C8F8180008D0D5E9391211448269114475
+:10FD40008161D5E93701C860D5F8DC0000281CBF07
+:10FD5000D5F8E010016100E00CE004D1D5F8E00036
+:10FD6000002818BF8761FE48007805B0BDE8F04361
+:10FD7000ECF70CB8FFDF05B0BDE8F0832DE9F05FCC
+:10FD8000F84E07468B46F08B7568401CF083307840
+:10FD90004FF00008002808BFFFDF07D0DFF8C89346
+:10FDA00004282ED0052818BFFFDF5BD05846FEF789
+:10FDB00018F9040008BFFFDF29463069F2F731FC6B
+:10FDC000B86087F800800120387194F8C9000228D3
+:10FDD00008BFE64807D0012808BFE54803D004283B
+:10FDE0000CBFE448E4484FF47A7100F2E140B0FB04
+:10FDF000F1F0B168FA300844F860307804287DD119
+:10FE000083E0002AD2D0D6F810A0D9F8184034B335
+:10FE1000A146E468002CFBD1B9F1000F1FD099F87E
+:10FE20000000002808BFFFDFD9F81410D9F804003B
+:10FE300001445046F3F7FAFB002807DA291A491E55
+:10FE400091FBF5F101FB05042A4604E090FBF5F176
+:10FE500001FB15042A46944288BFFFDF00E04446B8
+:10FE60002546A3E7002AA1D0B569002D08BFFFDF12
+:10FE70000024D5F8E420D9F818002346611E58B1B3
+:10FE80008369934228BF994284BF194604460346BA
+:10FE9000C0680028F4D104B91C46C5F8E040D0354C
+:10FEA000002C04BFC5F80C80C9F8185005D0E068D4
+:10FEB000E560E860002818BF0561D5F81090C5F826
+:10FEC0001880B9F1000F0ED0D9F8180048B1D5F854
+:10FED00014A0504538BFFFDFD9F81800A0EB0A0086
+:10FEE000A861C9F81880002C08BFC6F8208009D086
+:10FEF0002078002808BFFFDF616900E00AE0606841
+:10FF00000844306240F6B83550E7F08B0A2838BF15
+:10FF1000032000D302207871F08B012807D93846DE
+:10FF20007168FCF704FC0146F08B0844F083B86864
+:10FF30003061BDE8F09F2DE9F04107468F4884B05D
+:10FF40000D4690F80004DFF83882400998F8001454
+:10FF50004909884218BFFFDF01200026082D814C87
+:10FF600080F0BB80DFE805F004718C8C87B9B9A5FF
+:10FF700060732073607800281CBF04B0BDE8F08176
+:10FF800079488660466126733846FEF72AF80500F0
+:10FF900008BFFFDF95F8C900022804BF79494FF474
+:10FFA0007A720DD0012804BF71494FF4C86207D09E
+:10FFB000042807BF6F4940F69802734940F6E442AF
+:10FFC00011444FF47A7201F2E731B1FBF2F1A26809
+:10FFD0008C18F5F704FB024695F8C900082808BFFD
+:10FFE000082127D004280CBF0221002322D0022898
+:10FFF0000CBF182128211944042816BF08280F23F4
+:020000040002F8
+:1000000025235B1D082808BF402007D0042808BF0F
+:10001000102003D002280CBF0420082013FB00107E
+:10002000801A201AFDF76DFD002818BFFFDF04B00D
+:10003000BDE8F08101EB410101F12803082814BF5C
+:1000400004284FF4A871D6D0D1E7617851B1207B54
+:10005000002808BFFDF77AFF667304B0BDE8F041E1
+:10006000F2F7E2BCA073FDF70EFE002818BFFFDF19
+:1000700004B0BDE8F08104B0BDE8F041F5F789B8FF
+:1000800098F8140D4149400991F800144909884233
+:1000900018BFFFDF002239466846FFF76FFE69464A
+:1000A0003846F2F7FDFF002808BFFFDF04B0BDE8C7
+:1000B000F0812078052818BFFFDF207F002808BFC7
+:1000C000FFDF26772670207DF2F783FD002808BF2A
+:1000D000FFDF267504B0BDE8F081FFDF04B0BDE8A6
+:1000E000F0812DE9F0411F4C0026207804281FBF25
+:1000F000207805280C20BDE8F08101206070607B2D
+:100100000025A8B1EFF3108010F0010F72B60CBFFC
+:1001100000270127607B00281CBFA07B002805D09A
+:10012000FDF714FF6573A573F2F77EFC2FB903E0AA
+:10013000207DF3F7C7F800E062B6207DF3F70FFBF0
+:10014000207F28B125772078052818BFFFDF0C26EF
+:1001500065702570207DF2F73CFD002818E0000056
+:1001600070010020441200202812002004360200F2
+:10017000A2240200D0FB0100C0D4010001E000E095
+:100180000BE000E06836020030D3010019E000E027
+:1001900008BFFFDF25753046BDE8F0812DE9F04F3F
+:1001A000FD4883B00078002818BFFFF79AFF0120B0
+:1001B000DFF8E88388F8000069460620F0F781FB45
+:1001C000002818BFFFDF00274FF6FF7934E00298C0
+:1001D00000281CBF90F8D01000292DD00088484579
+:1001E0001CBFDFF8BCA34FF0200B3BD00621F0F77B
+:1001F000DFFB040008BFFFDF94F8DA00F3F7AFFA83
+:1002000084F8D07094F8DA504FF6FF76202D28BF8E
+:10021000FFDF2AF8156094F8DA00F2F7DAFC00281C
+:1002200008BFFFDF84F8DAB069460620F0F749FB23
+:10023000002818BFFFDF10E06846F0F720FB002819
+:10024000C5D00FE0029800281CBF90F8D0100029FC
+:1002500003D000884845C9D104E06846F0F70FFB99
+:100260000028EFD088F80070C8F8187003B000209C
+:10027000BDE8F08F10B5CB4C60B101280CBF40F643
+:10028000C410FFDF06D0A06841F66A01884228BF8B
+:10029000FFDF10BDA060F6E710B5DFF808C3BE4C65
+:1002A00000238CF80000237063702377237363733B
+:1002B000A3732020A3612075A4F11C004370423079
+:1002C00010214FF6FF72428020F8042F491EFAD108
+:1002D000CCF80830DCF8080041F66A01884228BFF3
+:1002E000FFDFFFF75BFF40F6C41101206160F5F707
+:1002F00082F900F2E7314FF47A70B1FBF0F042F28C
+:1003000010710844A0606168A1F21731884298BF5B
+:100310000146A16010BDF0B59F4C054685B0207820
+:1003200000281EBF0C2005B0F0BD95F8546095F86C
+:1003300055006F6AF5F75FF9022E04BF9A494FF432
+:100340007A720DD0012E04BF98494FF4C86207D0CD
+:10035000042E07BF964940F69802964940F6E442BB
+:10036000114408444FF47A7100F23F60B0FBF1F0A1
+:10037000384400F22230C5F8E400A56195F8D000B9
+:10038000002818BFFFDF0020844948610521217043
+:1003900060702077E0838848F2F7C1FB2075202841
+:1003A00008BFFFDFF2F734FC2061217D012268469F
+:1003B000FFF7E4FC207D6946F2F772FE002808BFD3
+:1003C000FFDF002005B0F0BD7348007800281CBF97
+:1003D0000020704710B50620F0F784FA80F0010085
+:1003E00010BD70B56C4C05462078002818BFFFDFA3
+:1003F000287801281CBF112070BD698840F2712245
+:10040000AD88514301206160F5F7F5F800F2E7315E
+:100410004FF47A70B1FBF0F040F2712105FB01005E
+:10042000A0606168A1F21731884298BF01460020A0
+:10043000A16070BD10B584B008431EBF112004B088
+:1004400010BD554C207800281EBF0C2004B010BDF4
+:100450000020607004212170E0835748F2F75FFBB1
+:100460002075202808BFFFDF4C48806938B101465D
+:10047000C0680028FBD111B1F2F7CAFB05E0F2F722
+:10048000C7FB40F6B831F2F7CCF82061217D01229C
+:100490006846FFF773FC207D6946F2F701FE0028ED
+:1004A00008BFFFDF002004B010BD70B53A4CA16951
+:1004B0000160FFF716FE002300BBA169D1F8E02020
+:1004C0005AB1D1E939C5AC449569AC44C2F818C0F9
+:1004D000D1E9372CCCF80C2005E0DFF8C0C0D1F80A
+:1004E000DC20CCF81820D1F8DC20D1F8E010002A6C
+:1004F00018BF116102D1002918BF8B61A36170BDC3
+:1005000026494870704770B540F2E24300FB03F59E
+:1005100010460C46F5F76FF8022C04BF22494FF441
+:100520007A720DD0012C04BF20494FF4C86207D065
+:10053000042C07BF1E4940F698021E4940F6E442CB
+:10054000114408444FF47A7100F23F60B0FBF1F0BF
+:1005500000F2223085428CBF281A002070BD70B591
+:100560000D46064601460020FCF732F9044696F88F
+:100570005500F5F740F8014696F85400022804BFEC
+:10058000094A4FF47A7020D0012804BF074A4FF47B
+:10059000C8601AD0042811E044120020281200205C
+:1005A0006C1200207001002068360200A2240200B4
+:1005B000D0FB010030D3010037FF010007BFFC4A28
+:1005C00040F69800FB4A40F6E440104408444FF4DB
+:1005D0007A7100F23F60B0FBF1F0718840F2712255
+:1005E0005143C0EB4100A0F22230A54234BF214666
+:1005F0002946814203D2A5422CBF2846204670627C
+:1006000070BD10B5F4F7EBFFEB498A684968511AE1
+:10061000084410BD2DE9F74FE74A00231826D2F809
+:1006200008B028270BF198044FF004084FF0100988
+:100630004FF0080A4FF4C8724FF4BF754FF0400CEA
+:1006400006287CD2DFE800F0034A21472465142005
+:10065000042912D0082909D02A20022911D010FB20
+:100660000A40002328211944441877E010FB0C406D
+:100670004FEA0C034FF4A871F5E710FB09402E2355
+:10068000F8E710FB08401821EDE704F5317465E048
+:10069000082904BF4FF4BA6140200CD0042915D0BA
+:1006A000022903BF03F15C01324604203A461CBF15
+:1006B00003F1B001082000EBC00000EB400002EBAA
+:1006C00040000844204400F19C0447E02A4640F2E0
+:1006D0008E211020EFE704F5B0743FE0082908BF31
+:1006E00040200CD0042904BF2A46102007D002293C
+:1006F00007BF03F11802042003F128020820C0EB11
+:10070000C00000EB400002EB4001029858440C1876
+:1007100024E0082904BF4FF4356140200CD004299F
+:1007200016D0022903BF324603F1B401042003F5B9
+:10073000B0711CBF3A46082000EB400300E00CE01B
+:1007400003EB001010440844204400F19C0405E031
+:100750002A4640F2EE311020EEE7FFDF974880682E
+:10076000A0428CBF0120002003B0BDE8F08F10B57F
+:10077000914C607828B1D4E90301A268FCF707F82E
+:10078000E060D4E9020188429CBF2078002814BFB1
+:100790000020012010BD04222DE9F04F884E894F22
+:1007A000DFF80C82DFF80C9285B04FF47A7A0529D5
+:1007B00080F0D280DFE801F00A2B0331920080F84C
+:1007C000D02005B0BDE8F04FF2F72EB904467A48C4
+:1007D0000078002818BF84F8D02004D005B0BDE808
+:1007E000F04FF2F721B90122002321466846FFF7B6
+:1007F0001FF894F8DA006946F2F752FC002808BFA7
+:10080000FFDFB4F85800401CA4F85800E6E70321C5
+:1008100080F8D01005B0BDE8F08F8346408840F2E4
+:10082000E241484368490860DBF8F800594600890E
+:10083000ABF81600DBF8F80080798BF81500DBF8D0
+:10084000F8004089ABF80200DBF8F8008089ABF8CB
+:100850000400DBF8F800C089ABF806000020DBF8E4
+:100860002850FBF7B5FF04469BF85500F4F7C3FE8C
+:100870009BF85410022908BF4FF47A710DD001295A
+:1008800004BF3E464FF4C86107D0042907BF46465F
+:1008900040F698014E4640F6E4413144084400F2E7
+:1008A0003F60B0FBFAF1BBF8020040F27122504306
+:1008B000C1EB4000A0F22230A54234BF21462946B8
+:1008C000814203D2A5422CBF28462046CBF8240003
+:1008D00002208BF8D00005B0BDE8F08F83460146BA
+:1008E000856A0020FBF774FF04469BF85500F4F777
+:1008F00082FE9BF85410022908BF4FF47A710DD084
+:10090000012904BF3E464FF4C86107D0042907BF40
+:10091000464640F698014E4640F6E44131440844CC
+:1009200000F23F60B0FBFAF0BBF8021040F2712217
+:100930005143C0EB4100A0F22230A54234BF214612
+:100940002946814203D2A5422CBF28462046CBF837
+:10095000240005B0BDE8F08FFFDF05B0BDE8F08FE3
+:100960002DE9F043DFF864800024144D98F800105E
+:1009700085B0072880F0AD81DFE800F0042A2AFC6A
+:10098000FCFBFB00EC830846EBF700FA68780028D4
+:1009900040F05E81297D00226846FFF7EFF9287D4F
+:1009A0006946F2F77DFB002808BFFFDF00F050B971
+:1009B000D0FB010030D30100281200204412002097
+:1009C00068360200A2240200740100207001002099
+:1009D00002280CBF01260026287DFDF702FB04003B
+:1009E00008BFFFDF94F8E2103046FCF706F8DFF8A6
+:1009F000449301462869D9F80820002E024408BF14
+:100A00004FF4FC706ED094F8E20094F8E2000828ED
+:100A10001EBF94F8E2000428002000F0B98000BF57
+:100A200094F8E230082B1ABF94F8E230042B4FF40C
+:100A3000A87305D094F8E230022B0CBF18232823AA
+:100A4000034494F8E200082808BF40200BD094F833
+:100A5000E200042808BF102005D094F8E200022824
+:100A60000CBF04200820C0EBC00C0CEB401003446A
+:100A700094F8E20008281EBF94F8E2000428002041
+:100A800079D000BF94F8E2C0BCF1080F1ABF94F807
+:100A9000E2C0BCF1040F4FF4A87C08D094F8E2C087
+:100AA000BCF1020F0CBF4FF0180C4FF0280C84441F
+:100AB00094F8E200082808BF40200BD094F8E20028
+:100AC000042808BF102005D094F8E20002280CBFCB
+:100AD0000420082000EB400606EB00106044184498
+:100AE00000F59A7010440844061D94F8E200F4F7EB
+:100AF00082FD94F8E210022908BF8F490BD094F8C8
+:100B0000E210012908BF8D4905D094F8E2100429AC
+:100B10000CBF8B498B4994F8E220022A08BF4FF49E
+:100B20007A720ED094F8E220012A08BF4FF4C8620E
+:100B300007D094F8E220042A0CBF40F6980240F651
+:100B4000E442114408444FF47A7100F2E730B0FBFC
+:100B5000F1F0A969301A40F2E2434A88D03102FB31
+:100B600003F6D9F818208A4208BF00272AD0296A3C
+:100B700002E0A8E055E014E0F2F758FD002819DA89
+:100B8000311A4A1E92FBF6F202FB0607314616E0C6
+:100B900094F8E200082818BF022000EB400028303B
+:100BA0003EE794F8E200082818BF022000EB40005E
+:100BB000283067E790FBF6F202FB160731468F42BA
+:100BC00088BFFFDFD8F80800874208D2A86940F242
+:100BD00071224188C1824A4307EB420705E040F297
+:100BE000E240B7FBF0F0A969C88294F8E210A86966
+:100BF00080F8541094F8E21080F8551005214175E2
+:100C0000C08A6FF41C71484307EB400040F6354141
+:100C1000C9F81400B0EB410F28BFFFDF05B0BDE8F5
+:100C2000F08304280CBF01260026EC830846EBF76E
+:100C3000ADF80120287785F82460A8692969C0F8F3
+:100C4000D41080F8D0402978052918BFFFDF06D0DE
+:100C5000F1F7EAFE6C73AC7305B0BDE8F0830028D1
+:100C600008BFFFDFA86990F8D000002818BFFFDF99
+:100C7000A86990F8DA00202818BFFFDF3248F1F7A2
+:100C80004EFFA9690646202881F8DA000F8828BFA0
+:100C9000FFDF2E4820F81670A86990F8DA002028A7
+:100CA00008BFFFDF002301226846A969FEF7C0FDE7
+:100CB000A869694690F8DA00F2F7F2F9002808BF4F
+:100CC000FFDFAC61C4E705B00846BDE8F043EBF7D1
+:100CD0005DB8FFDF05B0BDE8F08316494860704796
+:100CE00070B5144D0446002904BFA86070BD4FF4D0
+:100CF0007A76012910D002291CBFFFDF70BD6888F9
+:100D0000401C68801046F4F785FC00F2E730B0FB29
+:100D1000F6F0201AA86070BD1846F4F78AFC00F2BD
+:100D2000E730B0FBF6F0201AA86070BD08480078E4
+:100D3000704700002812002068360200A22402003A
+:100D4000D0FB010030D3010027FB01006C12002012
+:100D500044120020F7490C28896881F8CB001ABF9B
+:100D6000132818287047002211280FD0072808BF21
+:100D7000704715280AD001281ABF0028022870479A
+:100D8000A1F88420012081F888007047A1F88A200A
+:100D9000704770B5E74CA1680A88A1F83E2181F838
+:100DA0003C0191F85400012808BF012503D0022816
+:100DB00014BFFFDF0225A06880F8405190F855006D
+:100DC000012808BF012503D0022814BFFFDF022538
+:100DD000A068012180F8415180F83A11002180F883
+:100DE0000E11E078BDE87040EAF7D0BFD14A012982
+:100DF00092681BD0002302290FD0032922D030B3E0
+:100E000001282FD0032818BF704792F864001328D8
+:100E10001CBF1628182805D1704792F8CB0000286F
+:100E200008BF7047D2F8F8000370704792F8CB0003
+:100E3000012808BF704700BFD2F8FC000178491EA6
+:100E40000170704792F8CB000328EBD17047D2F8BD
+:100E5000F800B2F858108288891A09B20029A8BF90
+:100E600003707047B2F85800B2F80211401A00B28D
+:100E70000028E1DA70472DE9F041AE4C0026032747
+:100E8000D4F808C0012590B12069C0788CF8CA0058
+:100E900005FA00F010F4000F08BFFFDFA06880F82B
+:100EA0006470A0F8846080F88850BDE8F081002369
+:100EB0009CF8652019460CF15800FBF7CEFB002882
+:100EC00004BF6570BDE8F0816078002818BFBDE8F8
+:100ED000F0812069C178A06880F8C91080F8657039
+:100EE000A0F88A6080F88C50BDE8F08170B5914C14
+:100EF00084B0207910F0010F04BF04B070BD2069E8
+:100F000000230521C578A06890F864205830FBF7CD
+:100F1000A4FB002818BF062D09D020DC022D1CBF21
+:100F2000042D052D03D0607840F0080060706078D3
+:100F300000281CBF04B070BD2069C078801E162830
+:100F400080F00783DFE800F011FF89A7D52CFFFEB2
+:100F5000FF7FFDD2FFFFFFC5FCFBFAF9F8F50B2D73
+:100F60001CBF0D2D112DDED1E1E7A068002301216A
+:100F700090F867205830FBF770FB002840F05C8346
+:100F80002069FCF759F8A16881F8F600072081F87C
+:100F90006700002081F88C0081F8880000F04CBBCD
+:100FA000A0680921002390F864205830FBF755FB16
+:100FB00018B120690079122812D0A0680A210023F4
+:100FC00090F864205830FBF748FB18B1206900798D
+:100FD000142820D020690079162840F02D8324E0C1
+:100FE000A0680125002390F8642009215830FBF700
+:100FF00034FB002808BF657000F01E83607800286D
+:1010000040F01A83A16881F87C0081F8880081F89B
+:10101000640000F011BBA168002081F86400A1F811
+:10102000840081F8880000F035BAA06890F8641058
+:101030001F2940F00183002180F8641080F8881097
+:101040001A2000F0F7BAA06890F864100F2927D191
+:10105000002180F86910122137E0A06890F8641030
+:1010600013291DD1D0F8F81000884988814218BF93
+:10107000FFDFA068D0F8F80000F126012069FCF736
+:1010800008F8A06800F1C4012069FCF70AF81620EE
+:10109000A16800F05BB9A26892F86400162802D03B
+:1010A000022000F03BBAD2F8F80002F1B00300F1E0
+:1010B0001E0100220E30FBF74CFAA0680021C0E9A7
+:1010C0002811012180F86910182180F8641000F0BF
+:1010D000B3BA2069FCF765F8032840F0AD822069B7
+:1010E000FCF763F801F0D0FB00F0A6BA20690079A4
+:1010F000F8E7A06890F864101A29D1D1002580F88B
+:101100008D5080F88850D0F8F810008849888142C6
+:1011100018BFFFDFA068D0F8F8100D70D0F84411A8
+:101120000A78002A18BFFFDF7ED190F88E20DAB14E
+:101130000AE03CE27C010020B6E181E125E1F1E03A
+:1011400008E12BE09EE0A9E180F88E500288CA8079
+:10115000D0F844110D71D0F844210E211170D0F84F
+:1011600044210188518010E00288CA80D0F84411DF
+:101170000D71D0F8442101211172D0F844210D21C4
+:101180001170D0F84421018851800088EFF742FDAA
+:10119000EFF7DAF9E078EAF7F9FDBEE0A06800239E
+:1011A000194690F865205830FBF757FA50B9A068F7
+:1011B0000023082190F864205830FBF74EFA0028ED
+:1011C00000F0FA816078002840F03682A06890F83C
+:1011D000900010F0020F14D12069FBF765FFA168A1
+:1011E00081F891002069B0F80520A1F89220B0F8AC
+:1011F0000700A1F8940091F8900040F0020081F8F7
+:101200009000A06890F8901011F0010F14D190F8A0
+:101210006520002319465830FBF71FFA002808BF45
+:10122000FFDF0121A06800E077E080F8651080F81A
+:101230008C100021A0F88A10A06890F86410012991
+:1012400007D1002180F8641080F88810E078EAF770
+:101250009DFDA168D1F8F800098842888A4204BF40
+:101260000178042940F0E88100250570E078EAF76C
+:101270008DFDA06890F86410002908BF80F88850A0
+:1012800000F0DAB9A0680023072190F864205830F4
+:10129000FBF7E3F9002800F08F816078002840F028
+:1012A000CB8102A92069FBF739FF9DF808000025D2
+:1012B00000F02501A06880F896109DF8091001F053
+:1012C000410180F8971080F88850D0F8F810008815
+:1012D0004988814218BFFFDFA068D0F8F8100D7070
+:1012E000D0F844110A78002A18BFFFDF15D1028810
+:1012F000CA80D0F844110D71D0F84411029A8A6066
+:10130000039ACA60D0F84421082111700188D0F8EE
+:1013100044014180E078EAF739FDA06880F8645024
+:1013200000F08AB9A0680023092190F864205830A1
+:10133000FBF793F9002800F03F816078002840F027
+:101340007B81A16881F87C0081F8880081F86400C5
+:1013500000F072B9A0680023194690F86520583053
+:10136000FBF77BF9002800F027816078002840F027
+:101370006381A0680021A0F88A10012180F88C10F8
+:10138000022180F8651000F057B9A06800231946C3
+:1013900090F865205830FBF760F900287FD020696D
+:1013A000FBF7A6FE002879D0A5682069FBF79CFE14
+:1013B0002887A5682069FBF793FE6887A5682069E0
+:1013C000FBF794FEA887A5682069FBF78BFEE887EA
+:1013D000A06890F864101C2913BF90F84E100121EA
+:1013E00080F84E10012907D090F80511002904BF9C
+:1013F00090F80411002903D01E2180F8651017E031
+:101400001D2180F865100288A0F82A21028FA0F81B
+:101410002C21428FA0F82E21828F00F58A71A0F82E
+:101420003021C08FC88301200875E078EAF7AEFC50
+:10143000A0680021A0F88A10012180F88C10FBE040
+:10144000A06800230A2190F864205830FBF705F9C2
+:1014500018B32069FBF74CFEA8B1A5682069FBF71B
+:1014600043FE2887A5682069FBF73AFE6887A568D0
+:101470002069FBF73BFEA887A5682069FBF732FED1
+:10148000E88700F0FEFEA168002081F8880081F85E
+:10149000640000BF00F0C6FECEE000E059E06078D6
+:1014A00040F001006070C7E0A0680023194690F882
+:1014B00065205830FBF7D1F878B3A06890F8640045
+:1014C000232812BF2428607840F0200026D06846E8
+:1014D000F4F747F9002808BF002104D0009802A9BA
+:1014E000C0788DF80800A06801AB162290F864005F
+:1014F000FBF767FAA0B1A0689DF80420162180F8D8
+:10150000EC2080F8ED10192180F86510012180F899
+:101510008C100021A0F88A108EE04DE060708BE006
+:101520002069FBF700FEA0B12269107900F00701E5
+:10153000A06880F85010527902F0070280F851201C
+:1015400090F80F31002B04BF90F80E31002B04D01F
+:1015500022E00020FFF78FFC6EE090F855C000F10C
+:1015600054038C4501BF19789142012180F87D1008
+:1015700012D00288A0F8362190F8502000F58A7128
+:1015800080F8382190F8510081F82500012081F879
+:101590002000E078EAF7FAFBA068212180F86510C6
+:1015A000012180F88C100021A0F88A1044E0A06886
+:1015B00090F864001F2801D00120AFE72069FBF7F5
+:1015C000BCFD88B32069A2680179407901F0070168
+:1015D00061F30705294600F0070060F30F210120A1
+:1015E00082F888000025A2F88450232082F8640045
+:1015F000566DD2F81001FBF79CF9F2B2C1B28A42E3
+:1016000007BFA16881F8F250A26882F8F210C6F311
+:101610000721C0F30720814219BFA16881F8F300B8
+:10162000A06880F8F35007E0FFE70120FFF723FCF4
+:101630005FF01E00FFF7ADFBA068D0E92A12491C3D
+:1016400042F10002C0E92A1204B070BD2DE9F04752
+:10165000FE4D04464FF0000768780843687028790B
+:1016600010F0200F2846806818BFA0F87E7004D1C3
+:10167000B0F87E10491CA0F87E1090F86A10012680
+:1016800039B990F86420002306215830FAF7E5FFB5
+:1016900058B3A88810F4006F07D0A86890F86A10B3
+:1016A000002918BFA0F876701FD1A868B0F876108E
+:1016B000491C89B2A0F87610B0F878208A422CBF75
+:1016C000511A00218288521D8A4228BF80F87C600E
+:1016D000B0F87610B0F87820914206D3A0F8767072
+:1016E00080F81A61E878EAF751FB287910F0600F6A
+:1016F00008D0A86890F8681021B980F868600121C6
+:10170000FFF749F84FF00808002C56D168780028F8
+:1017100051D1287910F0040F0DD0A86890F864001A
+:10172000032808BFFFDFA86890F86710072904BFE7
+:101730002E7080F8677001F0F7F8287910F0080F24
+:1017400019D06878B8B9A868002190F8CB00FFF7E5
+:101750004DFBA86890F8CB00FE2808BFFFDFFE21F4
+:10176000A86880F8CB1090F86710082903D10221EF
+:10177000297080F86770FFF7B9FBA87810F0080FA0
+:1017800016D0A8680023052190F864205830FAF795
+:1017900064FF50B185F80180A868D0F8441108783A
+:1017A0000D2808BF0020087002E00020F9F770FB48
+:1017B000A86800F0F2FF00F0AEFDA868A14600F1B5
+:1017C000580490F8F40030B9E27B00230121204650
+:1017D000FAF743FF10B1608D401C60853D21B9F1DF
+:1017E000000F18D12878022808BF16200ED0012833
+:1017F00004BFA86890F8F60008D06878E8B110F047
+:10180000140F1CBF1E20207702D005E0207703E0D4
+:1018100010F0080F02D02177E67641E010F0030FB8
+:1018200003D02A202077E6763AE010F0200F08BF98
+:10183000FFDF23202077E67632E094F8300028B1ED
+:10184000A08D411CA185E18D884213D294F834000B
+:1018500028B1608E411C6186E18D88420AD2618D7B
+:10186000208D814203D3AA6892F8F42012B9E28D48
+:10187000914203D322202077E67611E0217C31B11A
+:10188000E18C814228BF84F81C80C5D206E0E08C40
+:10189000062803D33E202077E67601E0E07EA0B163
+:1018A0002773677327740221A868FEF774FFA8687E
+:1018B00090F8CB10012904D1D0F8FC000178491E22
+:1018C0000170E878EAF762FA03E00021A868FEF701
+:1018D00062FFBDE8F047F3F753BF5C4A5178937855
+:1018E000194314D111460128896809D0107910F0E4
+:1018F000040F03D091F86700072808D00120704733
+:10190000B1F84800098E884201D8FEF730BF0020A8
+:10191000704770B54D4C06460D46A0883043A080F8
+:1019200016F0020F04D016F0010F18BFFFDFE560BC
+:1019300016F0010F18BF256116F0020F10D0E878DD
+:10194000062802D00B2837D00AE0A06890F864106F
+:10195000182905D10021C0E92A11012180F86A1057
+:1019600016F0800F1CBF0820A07016F4806F08BF0F
+:1019700070BDA268B2F8580091880844801DE978CB
+:1019800080B2012908BFA2F8020107D0002904BFD4
+:10199000D2F8F810888001D0182915D0E9782846A7
+:1019A00001291CD009B3182918BF70BDB2F8F01076
+:1019B000BDE87040FBF7D3BBA06890F86410122913
+:1019C00008BF0021CCD1C9E792F8F210002902BF6C
+:1019D00092F8F31000290020A2F8F000DEE7B2F838
+:1019E00002114172090AA97270BDD2F8F8108988F3
+:1019F0004173090AA97370BDF0B5144C85B0002677
+:101A0000A060A6806670A670054626700088F3F771
+:101A10007FFEA0680088F3F7A1FEB5F8D800A168A2
+:101A2000401C82B201F15800FAF718FC002818BFD8
+:101A3000FFDF95F8650024280ED1B5F85810B5F8E9
+:101A4000F000081A00B2002802E000007C0100202B
+:101A5000A4BF6078002806D095F86400242818BF39
+:101A600025283BD119E0A06890F8F210002908BFA2
+:101A700090F8541080F8541090F8F310002908BF23
+:101A800090F8551080F855100020FFF782F985F87E
+:101A90006560A16881F87D6020E0B5F85810B5F860
+:101AA000F000081A00B20028A4BF6078002815D101
+:101AB000A06890F8F210002908BF90F8541080F840
+:101AC000541090F8F310002908BF90F8551080F8D2
+:101AD00055100020FFF75DF985F86460A5F8D8601F
+:101AE000A06890F8881039B1B0F88410B0F886205A
+:101AF000914224BF05B0F0BD90F88C1039B1B0F818
+:101B00008A10B0F88620914224BF05B0F0BDB0F82D
+:101B10008220B0F880108A4224BF05B0F0BD90F852
+:101B200068208AB3B0F87E208A4224BF05B0F0BD99
+:101B300090F8CB70FE2F00F012816846F3F7EBFDB2
+:101B4000002808BFFFDF2221009802F0B0FB03212C
+:101B50000098FBF7EDF90098017821F01001017071
+:101B60003946FBF713FA192F71D2DFE807F0271F68
+:101B70001445D6D6D71971D6D7D763D6D6D6D6C9F7
+:101B8000D7D77B94ADD6B600B0F87E10062924BF17
+:101B900005B0F0BDCCE7A168009891F8F51003E01E
+:101BA000A168009891F8CC100171B7E0A068D0F856
+:101BB000FC00411C0098FBF734FAAFE0A1680098E4
+:101BC000D1F8F82092790271D1F8F8201289427187
+:101BD000120A8271D1F8F8205289C271120A027277
+:101BE000D1F8F82092894272120A8272D1F8F81064
+:101BF000C989FBF7EEF991E0A068D0F8F800011D63
+:101C00000098FBF71BFAA068D0F8F80000F10C016F
+:101C10000098FBF71DFAA068D0F8F80000F11E014B
+:101C20000098FBF71BFAA06800F1C0010098FBF7D1
+:101C300023FA73E06269009811780171918841710B
+:101C4000090A81715188C171090A017266E064E074
+:101C5000FD49D1E90001CDE9020102A90098FBF795
+:101C600025FA5BE0A068B0F844100098FBF728FA6A
+:101C7000A068B0F846100098FBF726FAA068B0F804
+:101C800040100098FBF724FAA068B0F842100098C2
+:101C9000FBF722FA42E0A068B0F840100098FBF78A
+:101CA00017FAA068B0F842100098FBF715FAA06880
+:101CB000B0F844100098FBF703FAA068B0F846109B
+:101CC0000098FBF701FA29E0A168009891F810212B
+:101CD000027191F81111417120E0A06890F8F300B1
+:101CE000FAF722FE01460098FBF735FAA06890F853
+:101CF000F200FAF719FE01460098FBF728FA0DE00A
+:101D0000A06890F8ED100098FBF749FAA06890F8E9
+:101D1000EC100098FBF747FA00E0FFDFF3F70EFD49
+:101D2000002808BFFFDF0098C178012903D049B11E
+:101D300018290FD013E0A168B1F802114172090A05
+:101D400081720CE0A168D1F8F81089884173090A02
+:101D5000817304E0A168B1F8F010FBF700FABB480A
+:101D60000090BB4BBB4A29463046F8F7CDFFA06830
+:101D70000023052190F864205830FAF76EFC002803
+:101D800004BF05B0F0BD05B0BDE8F040F8F7C5BD33
+:101D9000B148806890F8881029B1B0F88410B0F884
+:101DA000862091421AD290F88C1029B1B0F88A108E
+:101DB000B0F88620914211D2B0F88220B0F880109D
+:101DC0008A420BD290F86820B0F87E0022B1884297
+:101DD00004D200BFF9F738B80628FBD3002001462B
+:101DE00034E470B50C46064615464FF4A4712046FF
+:101DF00002F07FFA2680002D08BFFFDF2868C4F8B4
+:101E0000F8006868C4F8FC00A868C4F8440170BD14
+:101E1000EEF7D7BE2DE9F0410D4607460621EEF755
+:101E2000C7FD040008BFBDE8F081D4F844110026C6
+:101E3000087858B14A8821888A4207D1092810D0E9
+:101E40000E281DD00D2832D008284CD094F81A0145
+:101E5000002857D06E701020287084F81A61AF8067
+:101E60003EE06E7009202870D4F844014168696032
+:101E70008168A9608089A881D4F8440106702FE0A8
+:101E80000846EEF7C7FE0746EEF773FBB0B96E7073
+:101E90000E202870D4F8440140686860D4F84401EA
+:101EA00006703846EEF75FFB0120BDE8F08108467A
+:101EB000EEF7B0FE0746EEF75CFB10B10020BDE880
+:101EC000F0816E700D202870D4F84401416869607B
+:101ED00000892881D4F8440106703846EEF743FBA8
+:101EE0000120BDE8F0816E7008202870D4F844010C
+:101EF00041688268C0686960AA60E860D4F84401FB
+:101F00000670EDE794F81C01B0B16E7015202870D2
+:101F100094F81C010028E3D084F81C61D4F81E0159
+:101F20006860D4F82201A860B4F82601A88194F86A
+:101F30001C010028F0D1D3E794F8280170B16E702D
+:101F40001D20287084F82861D4F82A016860D4F82C
+:101F50002E01A860B4F83201A881C1E794F83401D9
+:101F600040B16E701E20287084F83461D4F83601B8
+:101F70006860B5E794F8140180B16E701B2028707A
+:101F800094F814010028ABD084F81461D4F8160139
+:101F9000686094F814010028F6D1A1E794F83A019A
+:101FA000002808BFBDE8F0816E701620287094F8F4
+:101FB0003A01002894D000BF84F83A61D4F83C017B
+:101FC0006860B4F84001288194F83A010028F3D100
+:101FD00086E7214A5061D17070472DE9F0470446E9
+:101FE000481E85B238BFBDE8F08704F10808012615
+:101FF000DFF864904FF0090A5FF00007B4F8D800EA
+:10200000401CA4F8D800B4F87E00401CA4F87E0060
+:1020100094F86A0040B994F864200023062104F182
+:102020005800FAF71AFB30B3B4F87600401C80B2BF
+:10203000A4F87600B4F8781081422CBF0A1A002266
+:10204000A3885B1D934209E0F44802004D1602008C
+:10205000DB180200131902007C01002028BF84F85D
+:102060007C60884207D3A4F8767084F81A6199F8E6
+:102070000300E9F78BFE94F8880020B1B4F88400DF
+:10208000401CA4F8840094F88C0020B1B4F88A00B5
+:10209000401CA4F88A0094F8F40040B994F8672032
+:1020A0000023012104F15800FAF7D7FA20B1B4F85F
+:1020B0008200401CA4F8820094F864000C2802D02E
+:1020C0000D2820D067E0B4F85800411CB4F8020194
+:1020D000814260D1D4F8FC00411C404602F01EFA57
+:1020E00002212046F9F7DDFFD4F8FC000078002833
+:1020F00008BFFFDF0121FE20FEF778FE84F8647040
+:1021000084F8986047E0B4F85800411CD4F8F8000F
+:10211000808881423FD1D4F844010178002918BF5A
+:10212000FFDF22D12188C180D4F8F8004189D4F89A
+:1021300044010181D4F8F8008189D4F84401418137
+:10214000D4F8F800C189D4F844018181D4F844015D
+:102150000771D4F8440180F800A0D4F84401218824
+:10216000418099F80300E9F711FE01212046F9F7B3
+:1021700098FF03212046FEF70EFBD9F80800D0F89F
+:10218000F8000078022818BFFFDF0221FE20FEF7CA
+:102190002DFE84F86470B4F85800401C691EA4F841
+:1021A00058008DB2BFF42AAFBDE8F087F84AC2E903
+:1021B0000601704770B50446B0F87E0094F86810C8
+:1021C000002908BFC0F1020503D0B4F88010081A36
+:1021D000051F94F87C0040B194F864200023092185
+:1021E00004F15800FAF739FAA0B1B4F8766094F81F
+:1021F0006A0058B994F864200023062104F15800BD
+:10220000FAF72BFA002808BF284603D0B4F8780064
+:10221000801B001F8542C8BF0546002DD4BF00208B
+:10222000A8B270BD042110B5D94CA068FEF7B3FA6E
+:10223000A06890F84E10012902BF022180F84E10CC
+:1022400010BD00F58A710288A0F81E21028EA0F848
+:102250002021828EA0F82221028FB0F844309A42C9
+:1022600028BF1A460A82828FB0F84600824238BFE1
+:102270001046488201200872E078BDE81040E9F776
+:1022800085BDC34830B4806890F84E30B0F832C095
+:10229000C48EB0F84010428F022B25D08A4238BF3E
+:1022A00011460186C28FB0F842108A4238BF1146EB
+:1022B0008186028FB0F844108A4238BF11464186A9
+:1022C000828FB0F846108A4238BF1146C186418ECF
+:1022D000614588BF8C46A0F832C0C18EA14288BF3C
+:1022E0000C46C48630BC7047038E9A4228BF1A46FB
+:1022F000C58F838E9D4238BF2B468A4238BF114618
+:102300000186B0F842108B4228BF0B46838600211D
+:1023100080F84E10CDE770B59D4CA06890F8CB10BA
+:10232000FE2906BF6178002970BD90F86720002360
+:1023300001215830FAF791F9002818BF70BDA06844
+:1023400090F8F41021B1BDE870400220FEF702BD04
+:1023500090F86420002319465830FAF77EF940B10E
+:10236000A06890F87C0020B1BDE870401220FEF714
+:10237000F1BCA068002590F86420122A1FD004DC6C
+:10238000032A3FD0112A1FD003E0182A35D0232A70
+:1023900043D0002304215830FAF75FF9002818BF12
+:1023A00070BDD4F808C09CF8650019287CD03BDCCF
+:1023B00001286BD0022879D003285DD038E0BDE831
+:1023C00070400B20FEF7C6BCF1F760FC0C2838BF4C
+:1023D00070BDA0680821D0F8F8001E30F1F75AFC53
+:1023E00028B1A0680421C030F1F754FC00B9FFDF28
+:1023F000BDE870400320FEF7ADBCBDE8704006208C
+:10240000FEF7A8BC90F8CA1080F8CC100720FEF7A1
+:10241000A1FCA06880F8645070BD1820FEF79AFCFB
+:10242000A068A0F8845070BD1E2847D021286BD02A
+:10243000DCF8F80001260178002973D04088BCF848
+:10244000001088426ED100239CF8642019460CF1DC
+:102450005800FAF702F9002864D0A068D0F8F81004
+:10246000097802297ED003297DD004297CD0052952
+:1024700008BF082079D0C7E09CF8C9008CF8CC00D0
+:102480000720FEF767FCA06800F06DB90C20FEF78E
+:1024900061FCA068A0F88A5090F8901041F001010A
+:1024A00080F8901000F05FB96DE0FFE71320FEF7B1
+:1024B00051FCA068A0F88A5000F055B99CF80501BD
+:1024C000002818BF70BD9CF8040188B1BCF8060153
+:1024D000ACF84000BCF80801ACF84200BCF80A01B6
+:1024E000ACF84400BCF80C01ACF846008CF8045180
+:1024F000FFF7C7FEFFF796FE1520FEF72BFCA0683E
+:10250000A0F88A5000F02FB99CF87D0058B18CF8E3
+:10251000F2508CF8F3501820FEF71CFCA068A0F8CD
+:102520008A5070BD70E09CF80F01002818BF70BD84
+:102530009CF80E01002808BF70BDDCE91416DCF819
+:102540001001FAF7F6F9F2B2C1B28A4207BFA168E8
+:1025500081F8F250A26882F8F210C6F30721C0F3A6
+:10256000072003E016E01BE03BE022E0814219BFB8
+:10257000A16881F8F300A06880F8F3501820BDE846
+:102580007040FEF7E7BB1120FEF7E4FBA068EAE02D
+:102590007C01002090F86500FAF748F8A0BB08E03D
+:1025A00090F8691041B190F86A00002808BFFFDF79
+:1025B0000A20FEF7CFFB27E0F1F768FB0C2823D3B6
+:1025C000A0680821D0F8F8001E30F1F763FB28B1AD
+:1025D000A0680421C030F1F75DFB00B9FFDF0320E4
+:1025E000E7E790F8900010F0030F0DD10C20FEF7F4
+:1025F000B1FBA068A0F8845080F8886090F8901033
+:1026000041F0010180F89010A06890F8CB10FE29ED
+:1026100018BF70BD90F86420002319465830FAF7AF
+:102620001CF8002808BF70BDA06890F80011E9B33D
+:10263000A1690978D1BB90F86500F9F7F7FFA8BB4D
+:10264000A068B0F858100A2931D900F10801052214
+:10265000E06901F081FD0028A06804BF80F8005106
+:1026600070BDD0F8FC00017861B1411C0522E06921
+:1026700001F072FD002818BF70BDA068D0F8FC0002
+:10268000007830B9A068E169D0F8FC00401C01F086
+:1026900045FFA068D0F8FC000178491C01700120BA
+:1026A000FEF758FBA06880F8005170BDFFE7A068F6
+:1026B00090F8041111B190F8051181B390F80E1142
+:1026C000002908BF70BD90F80F11002918BF70BD18
+:1026D00090F86500F9F7AAFF002818BF70BDA06840
+:1026E00090F85400012808BF012503D0022814BF28
+:1026F000FFDF0225A06890F85500012808BF0126D9
+:1027000003D0022814BFFFDF0226A168012D91F833
+:1027100010012BD0022D08BF022829D033E0FFE79B
+:10272000B0F80611A0F84010B0F80811A0F8421057
+:10273000B0F80A11A0F84410B0F80C11A0F8461037
+:1027400080F8045190F865001D2804D0BDE8704061
+:102750001420FEF7FFBAFFF794FDFFF763FD152085
+:10276000FEF7F8FAA06880F8655070BD01280AD11C
+:1027700091F81101012E04D0022E08BF022807D0C3
+:1027800001E0012804D0BDE870401620FEF7E2BA4F
+:10279000BDE870400020FEF7FCBA70B5044690F822
+:1027A000640000250C2814D00D2818BF70BDB4F8A3
+:1027B0005800D4F8F810401C8988884218BF70BDB2
+:1027C000D4F84401FE4E0178002918BFFFDF45D13F
+:1027D00022E0B4F85800B4F80211401C884218BF37
+:1027E00070BDD4F8FC00411C04F1080001F096FE15
+:1027F00002212046F9F755FCD4F8FC0000780028A7
+:1028000008BFFFDF0121FE20FEF7F0FA84F86450D4
+:10281000012084F8980070BD2188C180D4F8F800A8
+:10282000D4F8441140890881D4F8F800D4F8441150
+:1028300080894881D4F8F800D4F84411C08988818F
+:10284000D4F844010571D4F8441109200870D4F873
+:10285000441120884880F078E9F798FA0121204651
+:10286000F9F71FFC03212046FDF795FFB068D0F86B
+:10287000F8000078022818BFFFDF0221FE20FEF7D3
+:10288000B5FA84F8645070BD70B5CD4CA16891F86C
+:102890006420162A11BF132A91F88E20002A62782C
+:1028A0001BBF02206070002A70BD81F8C80000259F
+:1028B00081F88D5081F88850D1F8F8000988408857
+:1028C000884218BFFFDFA068D0F8F800007803281E
+:1028D00018BFFFDF0321FE20FEF788FAA068D0F8BA
+:1028E00044110A78002A18BFFFDF19D10288CA8074
+:1028F000D0F8442190F8C8101171D0F844110D722D
+:10290000D0F844210D211170D0F844210188518064
+:102910000088EEF77FF9EDF717FEE078E9F736FA71
+:10292000A06880F8645070BD10B5A54C207910F0F7
+:10293000020F08BF10BD6078002818BF10BDE06806
+:10294000C078192880F06981DFE800F05F4F0D8FB3
+:10295000F8F8A6223FF86F83B1F8F8F8F8F7E3E04B
+:10296000F9F5F4F8F300A0680023012190F867203E
+:102970005830F9F772FE002818BF10BD0821A06872
+:1029800080F86710002180F8881080F88C1010BD46
+:10299000A0680023194690F865205830F9F75DFECD
+:1029A00018B1A168002081F88C00A06800231946A6
+:1029B00090F864205830F9F750FE002808BF10BD89
+:1029C0000020A16881F8880010BDA0680023194686
+:1029D00090F864205830F9F740FE002808BFFFDF68
+:1029E0000420A16881F8640010BDA0680023194686
+:1029F00090F864205830F9F730FE002808BFFFDF58
+:102A00000C20A16881F8640010BDA068002319465D
+:102A100090F864205830F9F720FE002808BFFFDF47
+:102A20000D20A16881F8640010BDA068002319463C
+:102A300090F864205830F9F710FE002808BFFFDF37
+:102A40000121A06880F88D105FF00F0180F86410FC
+:102A500010BDA06890F86400122818BFFFDF0121A4
+:102A6000A06880F88E101121F0E7A06800231946B5
+:102A700090F864205830F9F7F0FD28B9A06890F874
+:102A80008E00002808BFFFDF0121A06880F88D10AC
+:102A9000132180F8641010BDA06890F86400182815
+:102AA00018BFFFDF1A20A16881F8640010BDA0687C
+:102AB000D0F8F81003884A889A4204BF097804299C
+:102AC00019D190F86420002319465830F9F7C5FD54
+:102AD000002808BFFFDFA06890F8901011F0020FE7
+:102AE00004BF012180F8641005D0002180F888100F
+:102AF000D0F8F8000170A0680023194690F865200E
+:102B00005830F9F7AAFD002808BF10BD0020A168C1
+:102B100080E0A0680023194690F864205830F9F747
+:102B20009CFD002808BFFFDF0520A16881F8640034
+:102B300010BD30E01FE012E001E067E06DE0A0684A
+:102B40000023194690F864205830F9F786FD0028D4
+:102B500008BFFFDF1C20A16881F86400E8E7A068D7
+:102B60000023194690F865205830F9F776FD0028C3
+:102B700008BFFFDFCAE7A0680023194690F8642069
+:102B80005830F9F76AFD002808BFFFDF1F20A16851
+:102B900081F86400CCE7A06890F8651021291DD069
+:102BA00090F86410232918BFFFDFC1D190F8F2100C
+:102BB000002906BF90F8F3100029242102E000004C
+:102BC0007C01002018BF80F864107FF4F9AE00216A
+:102BD00080F864100846FEF7DCF8F1E690F8F21091
+:102BE000002907BF90F8F3100029242180F8651010
+:102BF0008CD1002180F8651080F87D1090F80E01CE
+:102C000000281CBF0020FEF7C4F87FE7A168002061
+:102C100081F8650081F88C008AE7FFDF88E7000013
+:102C200070B58D4C0829207A63D2DFE801F0041AD0
+:102C30005A5A2662625A80B1F1F7EDFD012211461F
+:102C40001046F1F7F0FFF2F7FDFC0020A072F1F75B
+:102C5000A1FEBDE87040F2F76EB9BDE87040EFF735
+:102C6000E3BED4E90001EFF7DCFC2060A07A401C51
+:102C7000C0B2A07228281CD370BDA07A0025401EC7
+:102C8000C6B2E0683044F2F748FA10B9E1687F2034
+:102C90008855A07A272828BF01252846F2F782FC0C
+:102CA000A07A282809D2401CC0B2A072282828BFC8
+:102CB00070BDBDE87040F1F76DBE207A00281CBFE2
+:102CC000012000F085F8F2F7C3F8F2F72CF90120A3
+:102CD000E07262480078E9F759F8BDE87040EFF714
+:102CE000A3BE002808BF70BD0020BDE8704000F002
+:102CF0006FB8FFDF70BD10B5574C207A002804BFB5
+:102D00000C2010BD00202072E072607AF0F7DAFA31
+:102D1000607AF0F724FD607AEFF75BFF00280CBFC4
+:102D20001F20002010BD002270B54B4C06460D46FA
+:102D3000207A68B12272E272607AF0F7C3FA607AA0
+:102D4000F0F70DFD607AEFF744FF002808BFFFDFC2
+:102D50004248E560067070BD70B5050007D0A5F566
+:102D6000E8503F494C3881429CBF122070BD3A4C1C
+:102D7000E068002804BF092070BD207A00281CBF2D
+:102D80000C2070BD3748EFF7CAFE6072202804BFE0
+:102D90001F2070BDEFF73CFF2060002D1CBF2844B2
+:102DA0002060012065602072002000F011F80020F2
+:102DB00070BD2949CA7A002A04BF002070471F222B
+:102DC000027000224270CB684360CA7201207047D3
+:102DD0002DE9F04184B00746EFF71AFF1E4D8046FB
+:102DE000414668682C6800EB800046002046F0F7FA
+:102DF0001DFCB04206DB6868811B4046EFF711FC02
+:102E00000446286040F2337621464046F0F70EFC37
+:102E1000B04204DA31464046EFF703FC0446002096
+:102E20008DF8000040F2E760039004208DF8050063
+:102E3000002F14BF012003208DF80400684602947F
+:102E4000F0F7B3F8687A6946F0F72AF9002808BF66
+:102E5000FFDF04B0BDE8F081AC1200209C0100202F
+:102E6000B5EB3C00212C02002DE9F0410C46124943
+:102E70000D68114A114908321160A0F12001312971
+:102E800001D301200CE0412810D040CC0C4F94E835
+:102E90000E0007EB8000241F50F8807C3046B847B6
+:102EA00020600548001D0560BDE8F0812046DEF782
+:102EB00097F9F5E706207047100502400100000170
+:102EC000FC48020010B5524800F038FA00B1FFDFAC
+:102ED0004F48401C00F032FA002800D0FFDF10BD40
+:102EE0002DE9F14F4B4ED6F800B00127484800F0CD
+:102EF0002DFADFF81C8128B95FF0000708F1010006
+:102F000000F03AFA444C00254FF0030901206060BC
+:102F1000C4F80051C4F80451009931602060DFF812
+:102F2000FCA018E0DAF80000C00614D50E2000F06E
+:102F300064F8EFF3108010F0010072B600D00120A9
+:102F4000C4F80493D4F8001119B9D4F8041101B9E4
+:102F500020BF00B962B6D4F8000118B9D4F8040152
+:102F60000028DFD0D4F804010028CFD137B1C6F84B
+:102F700000B008F1010000F0E9F911E008F10100EA
+:102F800000F0E4F90028B9D1C4F80893C4F804515A
+:102F9000C4F800510E2000F030F81D4800F0ECF9A4
+:102FA0000020BDE8F88F2DE9F0438DB00D460646B0
+:102FB00000240DF110090DF1200817E004EB44077F
+:102FC000102255F82710684601F0F2F805EB870744
+:102FD00010224846796801F0EBF86846FFF780FF59
+:102FE00010224146B86801F0E3F8641CB442E5DB06
+:102FF0000DB00020BDE8F08372E700F01F02012150
+:1030000091404009800000F1E020C0F88012704734
+:103010009D01002004E5004000E0004010ED00E0CC
+:10302000AA4900200870704770B5A94D01232B6094
+:10303000A84B1C68002CFCD0002407E00E6806603A
+:103040001E68002EFCD0001D091D641C9442F5D39F
+:103050000020286018680028FCD070BD70B59B4E19
+:1030600004469D4D3078022800D0FFDFAC4200D3EB
+:10307000FFDF71699948012903D847F23052944221
+:1030800001DD03224271491C7161291BC160934912
+:103090007078F0F705F8002800D1FFDF70BD70B53B
+:1030A0008A4C0D466178884200D0FFDF8A4E082D99
+:1030B0004BD2DFE805F04A041E2D4A4A4A382078F0
+:1030C000022800D0FFDF03202070A078012801D063
+:1030D00020B108E0A06800F0B7FD04E004F10800AA
+:1030E00007C8FFF7A1FF05202070BDE87040EFF78B
+:1030F0009BBCEFF78DFD01466068F0F797FAB04290
+:1031000002D2616902290BD30320F0F74CFD12E0D3
+:10311000EFF77EFD01466068F0F788FAB042F3D21F
+:10312000BDE870409AE7207802280AD0052806D02A
+:10313000FFDF04202070BDE8704000F0BDB8022021
+:1031400000E00320F0F72FFDF3E7FFDF70BD70B55F
+:103150000546EFF75DFD5D4C60602078012800D0EA
+:10316000FFDF5E49012008700020087104208D6097
+:1031700048715948C860022020706078EFF790FFCE
+:10318000002800D1FFDF70BD10B5504C207838B951
+:103190000220F0F71EFD18B90320F0F71AFD08B160
+:1031A000112010BD4E48EFF7BAFC6070202804D003
+:1031B000012020700020606110BD032010BD2DE9AA
+:1031C000F041144600EB84070E4605463F1F00F011
+:1031D0004EFD4FF080521169484306EB8401091FF0
+:1031E000B14201D2012100E000211CB11269B4EB0F
+:1031F000920F02D90920BDE8F0813A4A95420ED3D8
+:10320000AF420CD3854205D2874203D245EA06007D
+:10321000800701D01020EEE7964200D309B10F20BD
+:10322000E9E7314831490068884205D022463146F5
+:103230002846FFF7F9FE10E0FFF7A6FF0028DAD1D5
+:10324000224800218560C0E9036481704FF4A971B0
+:1032500004FB01F01830FFF77AFF0020CBE770B5D0
+:103260004FF08055044628691E49B1FBF0F08442B6
+:1032700001D20F2070BD00F0FAFCA04201D810204E
+:1032800070BD194819490068884204D02869604314
+:1032900000F0DAFC0CE0FFF777FF0028F0D1296995
+:1032A0000A4861438160012181701148FFF74FFF97
+:1032B000002070BD00F024BF10B5044C6078EFF71B
+:1032C00088FC00B9FFDF0020207010BDA0010020A5
+:1032D00004E5014000E40140105C0C00BC12002039
+:1032E0009F30020000600200B0000020BEBAFECA9B
+:1032F0007C5E01004FF08050D0F83011062903D0D9
+:10330000D0F83011491C07D1D0F83411062905D363
+:10331000D0F83401401C01D00020704701207047D4
+:103320004FF08050D0F83011062905D1D0F8340183
+:10333000062801D30120704700207047002101704A
+:10334000084670470146002008707047EFF310816F
+:1033500001F0010172B60278012A01D0012200E0D9
+:1033600000220123037001B962B60AB10020704740
+:103370004FF400507047E9E7EFF3108111F0010FAF
+:1033800072B64FF00002027000D162B600207047A2
+:10339000F2E700004C4909680160002070474A4983
+:1033A00008600020704701218A0720B1012804D05D
+:1033B00042F204007047916700E0D1670020704737
+:1033C00042490120086042F20600704708B5042314
+:1033D0003E4A1907103230B1C1F80433106840F08A
+:1033E000010010600BE0106820F001001060C1F8CF
+:1033F00008330020C1F8080135480068009000201B
+:1034000008BD011F0B2909D8304910310A6822F084
+:103410001E0242EA400008600020704742F20500A8
+:103420007047000100F18040C0F804190020704787
+:10343000000100F18040C0F8081900207047000129
+:1034400000F18040D0F80009086000207047012892
+:1034500001D9072070471F4A52F8200002680A432A
+:10346000026000207047012801D907207047194ADF
+:1034700052F8200002688A43026000207047012849
+:1034800001D907207047134A52F8200000680860ED
+:1034900000207047020010494FF0000003D0012ABD
+:1034A00001D0072070470A6070474FF0804100202C
+:1034B000C1F808014FF0E020802180F800140121BC
+:1034C000C0F80011704700000004004000050040F3
+:1034D00008010040C0490200780500406249634B82
+:1034E0000A6863499A42096801D1C1F31001016079
+:1034F000002070475C495D4B0A685D49091D9A428E
+:1035000001D1C0F310000860002070475649574BA6
+:103510000A68574908319A4201D1C0F31000086087
+:103520000020704730B5504B504D1C6842F20803E4
+:10353000AC4202D0142802D203E0112801D318466D
+:1035400030BDC3004B481844C0F81015C0F814250E
+:10355000002030BD4449454B0A6842F209019A42B5
+:1035600002D0062802D203E0042801D3084670479F
+:10357000404A012142F83010002070473A493B4B45
+:103580000A6842F209019A4202D0062802D203E0F8
+:10359000042801D308467047364A012102EBC000D7
+:1035A00041600020704770B52F4A304E314C15688D
+:1035B00042F2090304EB8002B54204D0062804D28B
+:1035C000C2F8001807E0042801D3184670BDC1F303
+:1035D0001000C2F80008002070BD70B5224A234ECA
+:1035E000244C156842F2090304EB8002B54204D072
+:1035F000062804D2D2F8000807E0042801D31846B0
+:1036000070BDD2F80008C0F310000860002070BD43
+:10361000174910B50831184808601120154A0021D3
+:1036200002EBC003C3F81015C3F81415401C14288E
+:10363000F6D3002006E0042804D302EB8003C3F88D
+:10364000001807E002EB8003D3F80048C4F310042D
+:10365000C3F80048401C0628EDD310BD04490648B5
+:103660000831086070470000B0000020BEBAFECAF2
+:1036700000F5014000F001400000FEFF7E4B1B689A
+:1036800003B19847BFF34F8F7C4801687C4A01F42F
+:10369000E06111430160BFF34F8FFEE710B5EFF318
+:1036A000108010F0010F72B601D0012400E0002458
+:1036B00000F0D9F850B1DDF72DFEEFF776F8F0F70E
+:1036C00013FADFF7A2FB6F490020086004B962B665
+:1036D000002010BD70B50C460546EFF3108010F0C9
+:1036E000010F72B601D0012600E0002600F0BBF801
+:1036F00018B106B962B6082070BDDDF787FDDDF7A9
+:103700000DFE0246002043099B0003F1E02300F078
+:103710001F01D3F80031CB40D9071BD0202803D29A
+:1037200022FA00F1C90722D141B2002906DA01F0DC
+:103730000F0101F1E02191F8141D03E001F1E021F6
+:1037400091F800144909082911D281B101290ED03C
+:1037500004290CD0401C6428D5D3DFF72DFB494940
+:10376000494808602046F0F7D9FD60B904E006B981
+:1037700062B641F2010070BD3F4804602DB1284699
+:10378000F0F719FE18B110242CE0404D19E028780C
+:10379000022802D94FF4805424E0072400286878D6
+:1037A00001D0F8B908E0E8B120281BD8A878212872
+:1037B00018D8012816D001E0A87898B9E8780B2825
+:1037C00010D83349802081F8140DDDF7A7FD294674
+:1037D000F0F770F9EEF7A8FF00F07CFA2846DDF765
+:1037E0006BFD044606B962B61CB1FFF757FF2046D1
+:1037F00070BD002070BD10B5044600F034F800B173
+:1038000001202070002010BD224908600020704770
+:1038100070B50C4620490D681F49204E08310E60D6
+:10382000102807D011280CD012280FD0132811D03F
+:10383000012013E0D4E90001FFF74CFF354620607A
+:103840000DE0FFF72BFF0025206008E02068FFF760
+:10385000D2FF03E00F4920680860002020600E4876
+:10386000001D056070BD074807490068884201D106
+:103870000120704700207047B80100200CED00E0E7
+:103880000400FA05B0000020BEBAFECAC849020012
+:103890000BE000E0040000201005024001000001E0
+:1038A00000B5C44910F1080F08BFF82024D014DC7B
+:1038B00010F1280F08BFD8201ED010F1140F08BF38
+:1038C000EC2019D010F1100F08BFF02014D010F127
+:1038D0000C0F08BFF4200FD00CE010F1040F08BF4C
+:1038E000FC2009D0002818BF032805D0042804BFF5
+:1038F000086000BDFFDF00BD086000BD00B5AE4937
+:10390000012808BF032004D0022816BFFFDF0420CF
+:1039100000BD086000BDA949002804BF086820F068
+:10392000010005D0012806BF086840F0010070477B
+:103930000860704770B51E460546012924D0022A4A
+:1039400004BF9F484FF47A710DD0012A04BF9D48EF
+:103950004FF4C86107D0042A07BF9B4840F698017E
+:103960009A4840F6E44144181846F1F744FE0444EE
+:103970003046F1F75EFE20444FF47A7100F2712078
+:10398000B0FBF1F0281A70BD022A08BF4FF47A701C
+:103990000AD0012A08BF4FF4C86005D0042A0CBF22
+:1039A00040F6980040F6E44049F608514418DBE739
+:1039B00070B514460546012908BF49F6CA660DD000
+:1039C000022B08BF824807D0012B08BF7D4803D0D7
+:1039D000042B0CBF7C487F4800F1FA061046F1F733
+:1039E00019FE012C08BF4FF47A710AD0022C08BFCF
+:1039F0004FF4FA7105D0042C0CBF4FF4FA614FF468
+:103A0000FA51711A08444FF47A7100F28920B0FB20
+:103A1000F1F0281A801E70BD70B5144606460129C3
+:103A200030D0022B04BF66494FF47A700DD0012BC1
+:103A300004BF64494FF4C86007D0042B07BF624934
+:103A400040F69800614940F6E4400D181046F1F741
+:103A5000E1FD012C08BF4FF47A710AD0022C08BF97
+:103A60004FF4FA7105D0042C0CBF4FF4FA614FF4F7
+:103A7000FA51691A08444FF47A716438B0FBF1F0D6
+:103A8000301A70BD022B08BF4FF47A700AD0012B98
+:103A900008BF4FF4C86005D0042B0CBF40F6980057
+:103AA00040F6E44049F608514518CFE770B5164690
+:103AB0000446012908BF49F6CA650DD0022B08BF8C
+:103AC000434807D0012B08BF3E4803D0042B0CBF4E
+:103AD0003D48404800F1FA051046F1F78CFD0544D9
+:103AE0003046F1F7A6FD28444FF47A7100F2E14028
+:103AF000B0FBF1F0201A801E70BD2DE9F0410746A1
+:103B00001E460C4615461046082A16BF04284DF6D8
+:103B10008830F1F770FD07EB4701C1EBC71100EBEF
+:103B2000C100012C08BF4FF47A710AD0022C08BFE3
+:103B30004FF4FA7105D0042C0CBF4FF4FA614FF426
+:103B4000FA5147182046F1F765FD381A4FF47A719B
+:103B500000F60F60B0FBF1F42846F1F740FD204479
+:103B60003044401DBDE8F08170B5054614460E4650
+:103B70000846F1F740FD05EB4502C2EBC512C0EB6C
+:103B8000C2053046F1F755FD2D1A2046082C16BF08
+:103B900004284DF68830F1F72EFD28444FF47A7151
+:103BA00000F6B730B0FBF1F52046F1F718FD2844D8
+:103BB000401D70BD0C15004010150040501600400F
+:103BC00068360200A2240200D0FB010030D30100BD
+:103BD00004360200C0D401002DE9FE430C468046A5
+:103BE000F9F7BAF9074698F80160204601A96A4634
+:103BF000ECF79BFC05000DD0012F02D00320BDE89F
+:103C0000FE83204602AA0199ECF7B1FB0298B0F8B6
+:103C100003000AE0022F14D1042E12D3B8F80300D7
+:103C2000BDF80020011D914204D8001D80B2A919E1
+:103C3000814202D14FF00000E1E702D24FF00100D3
+:103C4000DDE74FF00200DAE70B4A022111600B4971
+:103C50000B68002BFCD0084B1B1D1860086800285F
+:103C6000FCD00020106008680028FCD070474FF09E
+:103C7000805040697047000004E5014000E40140C5
+:103C800002000B464FF00000014620D0012A04D06C
+:103C9000022A04D0032A0DD103E0012002E0022011
+:103CA00015E00320072B05D2DFE803F00406080A1D
+:103CB0000C0E100007207047012108E0022106E0E9
+:103CC000032104E0042102E0052100E00621EEF7D3
+:103CD00042BF0000F9480521817000210170417048
+:103CE0007047F7490A78012A05D0CA681044C860AD
+:103CF0004038EFF768BC8A6810448860F8E700280D
+:103D000019D00378EF49F04A13B1012B0ED011E01E
+:103D10000379012B00D06BB943790BB1012B09D189
+:103D20008368643B8B4205D2C0680EE00379012BA7
+:103D300002D00BB10020704743790BB1012BF9D1B0
+:103D4000C368643B8B42F5D280689042F2D8012070
+:103D50007047DB4910B501220A700279A2B1002236
+:103D60000A71427992B104224A718268D34C52326C
+:103D70008A60C0681434C8606060EEF749FFCF49BC
+:103D800020600220887010BD0322E9E70322EBE7E0
+:103D900070B5044609B1012000E00320C84D0021A0
+:103DA0002970217901B100202871607968B104205F
+:103DB000C24E6871A168F068EEF733FCA860E06855
+:103DC0005230E8600320B07070BD0320F0E72DE9A9
+:103DD000F04105460226EFF722FB006800B1FFDF45
+:103DE000B64C01273DB12878B0B1012805D0022892
+:103DF00010D0032813D027710CE06868C82807D3B7
+:103E0000EFF747FC20B16868FFF76BFF012603E07E
+:103E1000002601E000F05CF93046BDE8F081207832
+:103E20000028F7D16868FFF76AFF0028E3D06868C8
+:103E3000017879B1A078042800D0FFDF01216868FB
+:103E4000FFF7A6FF9E49E078EFF72AF90028E1D1B5
+:103E5000FFDFDFE7FFF77DFF6770DBE72DE9F04766
+:103E6000964C8846E178884200D0FFDFDFF84C921C
+:103E700000250127924E09F11409B8F1080F75D2F7
+:103E8000DFE808F0040C28527A808D95A07803288A
+:103E900002D0022800D0FFDFBDE8F087A078032819
+:103EA00002D0022800D0FFDF0420A0702571207806
+:103EB000002878D1FFF715FF3078012806D0B068C8
+:103EC000E06000F031F92061002060E0E078EEF77A
+:103ED000E4FFF5E7A078032802D0022800D0FFDF36
+:103EE000207800286DD1A078032816D0EEF790FE38
+:103EF00001464F46D9F80000EFF798FB00280EDB8B
+:103F0000796881420BDB081AF0606D49E078EFF7C1
+:103F1000C7F80028C0D1FFDFBEE7042028E0042056
+:103F2000EFF741FEA570B7E7A078032802D002287A
+:103F300000D0FFDF207888BBA078032817D0EEF7E9
+:103F400067FE01464F46D9F80000EFF76FFB0028E7
+:103F5000E5DB79688142E2DB081AF0605849E078D5
+:103F6000EFF79EF8002897D1FFDF95E740E00520A6
+:103F7000EFF719FEA7708FE7A078042800D0FFDFC5
+:103F8000022004E0A078042800D0FFDF0120A1680F
+:103F90008847FFF71CFF054630E004E011E0A078F9
+:103FA000042800D0FFDFBDE8F04700F091B8A0780A
+:103FB000042804D0617809B1022800D0FFDF2078FE
+:103FC00018B1BDE8F04700F08CB8207920B1062088
+:103FD000EFF7E9FD2571CDE7607838B13849E07831
+:103FE000EFF75EF800B9FFDF657055E70720BFE720
+:103FF000FFDF51E73DB1012D03D0FFDF022DF9D1E5
+:104000004AE70420C3E70320C1E770B5050004D0E8
+:104010002A4CA078052806D101E0102070BD0820A8
+:10402000EFF7D7FD08B1112070BD2848EEF777FDF6
+:10403000E070202803D00020A560A07070BD032090
+:1040400070BD1E4810B5017809B1112010BD8178EE
+:10405000052906D0012906D029B1012101700020CF
+:1040600010BD0F2010BD00F03CF8F8E770B5134C00
+:104070000546A07808B1012809D155B12846FFF7B7
+:104080003EFE40B1287840B1A078012809D00F2029
+:1040900070BD102070BD072070BD2846FFF759FE87
+:1040A00003E000212846FFF773FE0549E078EEF7AC
+:1040B000F7FF00B9FFDF002070BD0000BC01002049
+:1040C000CC1200203D860100FF1FA1075D3E0200CB
+:1040D0000A4810B5006900F01FF8BDE81040EEF77F
+:1040E000A3BC064810B5C078EEF773FD00B9FFDF3A
+:1040F0000820EFF758FDBDE81040EBE5BC010020BB
+:1041000010B5134C2060201D016011481030026072
+:10411000001D0360002010BD0E490A6848F202131A
+:104120009A4302430A6070470A4A116848F2021330
+:1041300001EA0300994311607047054B02465B4258
+:1041400010201344FC2B01D81160002070470000A0
+:1041500000060040C806024040EA010310B59B0774
+:104160000FD1042A0DD310C808C9121F9C42F8D0E1
+:1041700020BA19BA884201D9012010BD4FF0FF3092
+:1041800010BD1AB1D30703D0521C07E0002010BDA8
+:1041900010F8013B11F8014B1B1B07D110F8013B34
+:1041A00011F8014B1B1B01D1921EF1D1184610BD15
+:1041B000032A40F2308010F0030C00F0158011F853
+:1041C000013BBCF1020F624498BF11F801CB00F82B
+:1041D000013B38BF11F8013BA2F1040298BF00F87F
+:1041E00001CB38BF00F8013B11F0030300F025803C
+:1041F000083AC0F0088051F8043B083A51F804CB63
+:10420000A0E80810F5E7121D5CBF51F8043B40F828
+:10421000043BAFF30080D20724BF11F8013B11F833
+:1042200001CB48BF11F8012B24BF00F8013B00F877
+:1042300001CB48BF00F8012B704710B5203AC0F001
+:104240000B80B1E81850203AA0E81850B1E8185097
+:10425000A0E81850BFF4F5AF5FEA027C24BFB1E8D4
+:104260001850A0E8185044BF18C918C0BDE8104045
+:104270005FEA827C24BF51F8043B40F8043B08BF4E
+:104280007047D20728BF31F8023B48BF11F8012B15
+:1042900028BF20F8023B48BF00F8012B704702F00E
+:1042A000FF0343EA032242EA024200F002B84FF061
+:1042B00000020429C0F0128010F0030C00F01B80F3
+:1042C000CCF1040CBCF1020F18BF00F8012BA8BF01
+:1042D00020F8022BA1EB0C0100F00DB85FEAC17CC5
+:1042E00024BF00F8012B00F8012B48BF00F8012B78
+:1042F00070474FF0000200B51346944696462039A9
+:1043000022BFA0E80C50A0E80C50B1F12001BFF48E
+:10431000F7AF090728BFA0E80C5048BF0CC05DF8F4
+:1043200004EB890028BF40F8042B08BF704748BF42
+:1043300020F8022B11F0804F18BF00F8012B7047B6
+:10434000FEDF04207146084219D10699124A9142B3
+:1043500015DC069902394878DF2810D10878FE2844
+:1043600007D0FF280BD14FF001004FF000020B4B9C
+:10437000184741F201000099019A084B1847084B71
+:10438000002B02D01B68DB6818474FF0FF307146E6
+:104390004FF00002014B1847006002007D3602001A
+:1043A00004000020184819497047FFF7FBFFDCF7AD
+:1043B00005FF00BD4FF4805015490968884203D1BC
+:1043C000144A13605B68184700BD000020BFFDE77A
+:1043D0004FF480500E490968884210D10E4B18687E
+:1043E0004FF0FF318842F1D080F308884FF0202150
+:1043F000884204DD0948026803210A430260084834
+:10440000804708488047FFDFE0120020E0120020CC
+:104410000000002004000020006002001409004099
+:10442000F5430100B543020004207146084202D062
+:10443000EFF3098101E0EFF3088188690238007821
+:10444000102813DB20280FDB2C280BDB0A4A12680C
+:104450000A4B9A4203D1602804DB094A1047022024
+:1044600008607047074A1047074A1047074A126812
+:104470002C32126810470000B0000020BEBAFECAFD
+:1044800021130000692E02001138020004000020F0
+:104490000D4B0E4908470E4B0C4908470D4B0B4975
+:1044A00008470D4B094908470C4B084908470C4B76
+:1044B000064908470B4B054908470B4B034908477A
+:1044C0000A4B02490847000049BB00000D2F0000BD
+:1044D0006D2C0000092B0000972A00000F2D000012
+:1044E0003D13000053280000C1BD0000C9110000A9
+:1044F00000210160017170470021016081807047D7
+:10450000002101604160017270470A684B680260D7
+:104510004360B1F808C0A0F808C070470A6802609C
+:104520000B79037170470000B19500003B970000C4
+:1045300099980000BD980000F79800002B990000A2
+:104540005D9900008D990000039A00008996000093
+:10455000A7120000A712000075440000C14400002B
+:10456000E5440000794500009546000057470000EB
+:1045700089470000714800000349000057490000C6
+:104580003D4A00005D4A0000DF15000003160000F0
+:10459000331500008715000035160000C91600000D
+:1045A0005B6000000B620000DF650000F566000044
+:1045B0007F670000FD6700006168000085690000FA
+:1045C000556A0000C16A00007F4A0000854A000069
+:1045D0008F4A000085410000F74A00005941000061
+:1045E0007B4C0000B34C0000294D00000F4E000032
+:1045F000254E0000A7120000A7120000A71200001D
+:10460000A7120000A7120000A7120000A7120000C6
+:10461000A7120000BF24000045250000612500000E
+:104620007D2500000B270000A7250000B125000014
+:10463000F325000015260000F126000033270000B6
+:10464000A7120000A71200005F8300007F83000014
+:1046500081830000C5830000F3830000E184000033
+:104660006F85000083850000D1850000C1860000B1
+:10467000678800009189000073730000A989000019
+:10468000A7120000A7120000C9B4000033B6000052
+:1046900087B60000F3B60000A3B7000001000000D9
+:1046A00000000000100110013A0200001A02000090
+:1046B000F3900000E1900000FFFFFFFF0000FFFF0C
+:1046C000C5AC0000253D000065200000BD73000062
+:1046D000598E0000000000000000020000000000F1
+:1046E00000020000000000000001000000000000C7
+:1046F0000B810000EB800000598100004124000084
+:1047000003240000232400002FA800005BA8000061
+:1047100063AA0000515900007981000000000000E8
+:10472000A98100008F2400000000000000000000AC
+:104730000000000045A9000000000000E55900004D
+:10474000000000004808000048080000D3560000A0
+:10475000D35600005144000071AB00003F760000CA
+:10476000771F0000E31D02004F9401001157000065
+:104770001157000073440000D3AB0000C376000063
+:10478000E91F0000111E0200639401007001700116
+:10479000400038005C0024004801000200000300D3
+:1047A000656C746200000000000000000000000062
+:1047B0000000000087000000000000000000000072
+:1047C00000000000BE83605ADB0B376038A5F5AAF5
+:1047D0009183886C010000007911010041200100E3
+:1047E00000000001020603040500000007000000AD
+:1047F00000000000060000000A0000003200000077
+:1048000073000000B4000000DD860100DB0C020034
+:10481000CB6C010065AE010059F0010065AE0100EE
+:10482000616E01001DB00100E3E701001DB0010051
+:10483000476B0100B1AF010087EF0100B1AF01008C
+:10484000C76C010079AE0100E9DF010079AE01001B
+:104850005972010091B20100EFF0010091B2010024
+:104860000300000001555555D6BE898E0000C706CD
+:10487000C70CC71200006B030F06B3080000B70493
+:10488000A708970CF401FA00960064004B00320070
+:104890001E0014000A000500020001000041000093
+:1048A00000000000AAAED7AB154120100C0802177B
+:1048B0000D0101020909010106020918180301018D
+:1048C0000909030305000000FE000000FE000000CF
+:1048D000FE555555252627D6BE898E00F401FA00CF
+:1048E000960064004B0032001E0014000A00050010
+:1048F000020001002541000000000000DD3402003C
+:10490000F53402000D350200253502005535020050
+:104910007D350200A7350200DB3502005F32020060
+:10492000BF310200B53202003B4102003D330200BC
+:104930004D330200793302009F3C0100A73C010087
+:10494000B93C0100A7330200C133020095330200D5
+:104950009F330200CD33020003340200B52E020063
+:1049600023340200313402003F3402004F3402008D
+:10497000673402007F34020095340200B52E020035
+:104980000000000077B90000CDB90000E3B90000D5
+:10499000813C0200E12E0200A72F02000B40020022
+:1049A000434002006D400200493B0100C93E010046
+:1049B000B52E0200B52E0200B52E0200B52E020063
+:1049C0001C0500402005004000100200EC490200D8
+:1049D00008000020D001000044110000244A020019
+:1049E000D801002008110000A0110000011813C810
+:1049F000140250201A0102227C2720FB349B5F8086
+:104A00001280021A10138B091B2048041ACE0401CD
+:104A1000200B50A40AAC01300912CB637F010B6854
+:044A2000CC10A00016
+:00000001FF
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/softdevice/s132/toolchain/armgcc/armgcc_s132_nrf52832_xxaa.ld b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/softdevice/s132/toolchain/armgcc/armgcc_s132_nrf52832_xxaa.ld
new file mode 100644
index 0000000..d1628c3
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/softdevice/s132/toolchain/armgcc/armgcc_s132_nrf52832_xxaa.ld
@@ -0,0 +1,33 @@
+/* Linker script to configure memory regions. */
+
+SEARCH_DIR(.)
+GROUP(-lgcc -lc -lnosys)
+
+MEMORY
+{
+ FLASH (rx) : ORIGIN = 0x26000, LENGTH = 0x5a000
+ RAM (rwx) : ORIGIN = 0x200014b8, LENGTH = 0xeb48
+}
+
+SECTIONS
+{
+}
+
+SECTIONS
+{
+ . = ALIGN(4);
+ .mem_section_dummy_ram :
+ {
+ }
+
+} INSERT AFTER .data;
+
+SECTIONS
+{
+ .mem_section_dummy_rom :
+ {
+ }
+
+} INSERT AFTER .text
+
+INCLUDE "nrf_common.ld"
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/softdevice/s132/toolchain/iar/iar_s132_nrf52832_xxaa.icf b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/softdevice/s132/toolchain/iar/iar_s132_nrf52832_xxaa.icf
new file mode 100644
index 0000000..47cf577
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/softdevice/s132/toolchain/iar/iar_s132_nrf52832_xxaa.icf
@@ -0,0 +1,36 @@
+/*###ICF### Section handled by ICF editor, don't touch! ****/
+/*-Editor annotation file-*/
+/* IcfEditorFile="$TOOLKIT_DIR$\config\ide\IcfEditor\cortex_v1_0.xml" */
+/*-Specials-*/
+define symbol __ICFEDIT_intvec_start__ = 0x26000;
+/*-Memory Regions-*/
+define symbol __ICFEDIT_region_ROM_start__ = 0x26000;
+define symbol __ICFEDIT_region_ROM_end__ = 0x7ffff;
+define symbol __ICFEDIT_region_RAM_start__ = 0x200014b8;
+define symbol __ICFEDIT_region_RAM_end__ = 0x2000ffff;
+export symbol __ICFEDIT_region_RAM_start__;
+export symbol __ICFEDIT_region_RAM_end__;
+/*-Sizes-*/
+define symbol __ICFEDIT_size_cstack__ = ;
+define symbol __ICFEDIT_size_heap__ = ;
+/**** End of ICF editor section. ###ICF###*/
+
+define memory mem with size = 4G;
+define region ROM_region = mem:[from __ICFEDIT_region_ROM_start__ to __ICFEDIT_region_ROM_end__];
+define region RAM_region = mem:[from __ICFEDIT_region_RAM_start__ to __ICFEDIT_region_RAM_end__];
+
+define block CSTACK with alignment = 8, size = __ICFEDIT_size_cstack__ { };
+define block HEAP with alignment = 8, size = __ICFEDIT_size_heap__ { };
+define block RO_END with alignment = 8, size = 0 { };
+
+initialize by copy { readwrite };
+do not initialize { section .noinit };
+
+keep { section .intvec };
+place at address mem:__ICFEDIT_intvec_start__ { readonly section .intvec };
+place in ROM_region { readonly,
+ block RO_END };
+place in RAM_region { readwrite,
+ block CSTACK,
+ block HEAP };
+
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/softdevice/s140/doc/s140_nrf52_6.0.0_licence-agreement.txt b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/softdevice/s140/doc/s140_nrf52_6.0.0_licence-agreement.txt
new file mode 100644
index 0000000..a71adee
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/softdevice/s140/doc/s140_nrf52_6.0.0_licence-agreement.txt
@@ -0,0 +1,35 @@
+Copyright (c) 2007 - 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, except as embedded into a Nordic
+ Semiconductor ASA integrated circuit in a product or a software update for
+ such product, 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.
+
+4. This software, with or without modification, must only be used with a
+ Nordic Semiconductor ASA integrated circuit.
+
+5. Any software provided in binary form under this license must not be reverse
+ engineered, decompiled, modified and/or disassembled.
+
+THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/softdevice/s140/doc/s140_nrf52_6.0.0_migration-document.pdf b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/softdevice/s140/doc/s140_nrf52_6.0.0_migration-document.pdf
new file mode 100644
index 0000000..1379ecd
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/softdevice/s140/doc/s140_nrf52_6.0.0_migration-document.pdf
Binary files differ
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/softdevice/s140/doc/s140_nrf52_6.0.0_release-notes.pdf b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/softdevice/s140/doc/s140_nrf52_6.0.0_release-notes.pdf
new file mode 100644
index 0000000..3e59275
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/softdevice/s140/doc/s140_nrf52_6.0.0_release-notes.pdf
Binary files differ
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/softdevice/s140/headers/ble.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/softdevice/s140/headers/ble.h
new file mode 100644
index 0000000..9ebb41f
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/softdevice/s140/headers/ble.h
@@ -0,0 +1,622 @@
+/*
+ * Copyright (c) 2012 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ */
+
+/**
+ @addtogroup BLE_COMMON BLE SoftDevice Common
+ @{
+ @defgroup ble_api Events, type definitions and API calls
+ @{
+
+ @brief Module independent events, type definitions and API calls for the BLE SoftDevice.
+
+ */
+
+#ifndef BLE_H__
+#define BLE_H__
+
+#include <stdint.h>
+#include "nrf_svc.h"
+#include "nrf_error.h"
+#include "ble_err.h"
+#include "ble_gap.h"
+#include "ble_l2cap.h"
+#include "ble_gatt.h"
+#include "ble_gattc.h"
+#include "ble_gatts.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** @addtogroup BLE_COMMON_ENUMERATIONS Enumerations
+ * @{ */
+
+/**
+ * @brief Common API SVC numbers.
+ */
+enum BLE_COMMON_SVCS
+{
+ SD_BLE_ENABLE = BLE_SVC_BASE, /**< Enable and initialize the BLE stack */
+ SD_BLE_EVT_GET, /**< Get an event from the pending events queue. */
+ SD_BLE_UUID_VS_ADD, /**< Add a Vendor Specific UUID. */
+ SD_BLE_UUID_DECODE, /**< Decode UUID bytes. */
+ SD_BLE_UUID_ENCODE, /**< Encode UUID bytes. */
+ SD_BLE_VERSION_GET, /**< Get the local version information (company ID, Link Layer Version, Link Layer Subversion). */
+ SD_BLE_USER_MEM_REPLY, /**< User Memory Reply. */
+ SD_BLE_OPT_SET, /**< Set a BLE option. */
+ SD_BLE_OPT_GET, /**< Get a BLE option. */
+ SD_BLE_CFG_SET, /**< Add a configuration to the BLE stack. */
+};
+
+/**
+ * @brief BLE Module Independent Event IDs.
+ */
+enum BLE_COMMON_EVTS
+{
+ BLE_EVT_USER_MEM_REQUEST = BLE_EVT_BASE + 0, /**< User Memory request. @ref ble_evt_user_mem_request_t */
+ BLE_EVT_USER_MEM_RELEASE = BLE_EVT_BASE + 1, /**< User Memory release. @ref ble_evt_user_mem_release_t */
+};
+
+/**@brief BLE Connection Configuration IDs.
+ *
+ * IDs that uniquely identify a connection configuration.
+ */
+enum BLE_CONN_CFGS
+{
+ BLE_CONN_CFG_GAP = BLE_CONN_CFG_BASE + 0, /**< BLE GAP specific connection configuration. */
+ BLE_CONN_CFG_GATTC = BLE_CONN_CFG_BASE + 1, /**< BLE GATTC specific connection configuration. */
+ BLE_CONN_CFG_GATTS = BLE_CONN_CFG_BASE + 2, /**< BLE GATTS specific connection configuration. */
+ BLE_CONN_CFG_GATT = BLE_CONN_CFG_BASE + 3, /**< BLE GATT specific connection configuration. */
+ BLE_CONN_CFG_L2CAP = BLE_CONN_CFG_BASE + 4, /**< BLE L2CAP specific connection configuration. */
+};
+
+/**@brief BLE Common Configuration IDs.
+ *
+ * IDs that uniquely identify a common configuration.
+ */
+enum BLE_COMMON_CFGS
+{
+ BLE_COMMON_CFG_VS_UUID = BLE_CFG_BASE, /**< Vendor specific UUID configuration */
+};
+
+/**@brief Common Option IDs.
+ * IDs that uniquely identify a common option.
+ */
+enum BLE_COMMON_OPTS
+{
+ BLE_COMMON_OPT_PA_LNA = BLE_OPT_BASE + 0, /**< PA and LNA options */
+ BLE_COMMON_OPT_CONN_EVT_EXT = BLE_OPT_BASE + 1, /**< Extended connection events option */
+};
+
+/** @} */
+
+/** @addtogroup BLE_COMMON_DEFINES Defines
+ * @{ */
+
+/** @brief Required pointer alignment for BLE Events.
+*/
+#define BLE_EVT_PTR_ALIGNMENT 4
+
+/** @brief Leaves the maximum of the two arguments.
+*/
+#define BLE_MAX(a, b) ((a) < (b) ? (b) : (a))
+
+/** @brief Maximum possible length for BLE Events.
+ * @note The highest value used for @ref ble_gatt_conn_cfg_t::att_mtu in any connection configuration shall be used as a parameter.
+ * If that value has not been configured for any connections then @ref BLE_GATT_ATT_MTU_DEFAULT must be used instead.
+*/
+#define BLE_EVT_LEN_MAX(ATT_MTU) ( \
+ offsetof(ble_evt_t, evt.gattc_evt.params.prim_srvc_disc_rsp.services) + ((ATT_MTU) - 1) / 4 * sizeof(ble_gattc_service_t) \
+)
+
+/** @defgroup BLE_USER_MEM_TYPES User Memory Types
+ * @{ */
+#define BLE_USER_MEM_TYPE_INVALID 0x00 /**< Invalid User Memory Types. */
+#define BLE_USER_MEM_TYPE_GATTS_QUEUED_WRITES 0x01 /**< User Memory for GATTS queued writes. */
+/** @} */
+
+/** @defgroup BLE_UUID_VS_COUNTS Vendor Specific UUID counts
+ * @{
+ */
+#define BLE_UUID_VS_COUNT_DEFAULT 10 /**< Default VS UUID count. */
+#define BLE_UUID_VS_COUNT_MAX 254 /**< Maximum VS UUID count. */
+/** @} */
+
+/** @defgroup BLE_COMMON_CFG_DEFAULTS Configuration defaults.
+ * @{
+ */
+#define BLE_CONN_CFG_TAG_DEFAULT 0 /**< Default configuration tag, SoftDevice default connection configuration. */
+
+/** @} */
+
+/** @} */
+
+/** @addtogroup BLE_COMMON_STRUCTURES Structures
+ * @{ */
+
+/**@brief User Memory Block. */
+typedef struct
+{
+ uint8_t *p_mem; /**< Pointer to the start of the user memory block. */
+ uint16_t len; /**< Length in bytes of the user memory block. */
+} ble_user_mem_block_t;
+
+/**@brief Event structure for @ref BLE_EVT_USER_MEM_REQUEST. */
+typedef struct
+{
+ uint8_t type; /**< User memory type, see @ref BLE_USER_MEM_TYPES. */
+} ble_evt_user_mem_request_t;
+
+/**@brief Event structure for @ref BLE_EVT_USER_MEM_RELEASE. */
+typedef struct
+{
+ uint8_t type; /**< User memory type, see @ref BLE_USER_MEM_TYPES. */
+ ble_user_mem_block_t mem_block; /**< User memory block */
+} ble_evt_user_mem_release_t;
+
+/**@brief Event structure for events not associated with a specific function module. */
+typedef struct
+{
+ uint16_t conn_handle; /**< Connection Handle on which this event occurred. */
+ union
+ {
+ ble_evt_user_mem_request_t user_mem_request; /**< User Memory Request Event Parameters. */
+ ble_evt_user_mem_release_t user_mem_release; /**< User Memory Release Event Parameters. */
+ } params; /**< Event parameter union. */
+} ble_common_evt_t;
+
+/**@brief BLE Event header. */
+typedef struct
+{
+ uint16_t evt_id; /**< Value from a BLE_<module>_EVT series. */
+ uint16_t evt_len; /**< Length in octets including this header. */
+} ble_evt_hdr_t;
+
+/**@brief Common BLE Event type, wrapping the module specific event reports. */
+typedef struct
+{
+ ble_evt_hdr_t header; /**< Event header. */
+ union
+ {
+ ble_common_evt_t common_evt; /**< Common Event, evt_id in BLE_EVT_* series. */
+ ble_gap_evt_t gap_evt; /**< GAP originated event, evt_id in BLE_GAP_EVT_* series. */
+ ble_gattc_evt_t gattc_evt; /**< GATT client originated event, evt_id in BLE_GATTC_EVT* series. */
+ ble_gatts_evt_t gatts_evt; /**< GATT server originated event, evt_id in BLE_GATTS_EVT* series. */
+ ble_l2cap_evt_t l2cap_evt; /**< L2CAP originated event, evt_id in BLE_L2CAP_EVT* series. */
+ } evt; /**< Event union. */
+} ble_evt_t;
+
+
+/**
+ * @brief Version Information.
+ */
+typedef struct
+{
+ uint8_t version_number; /**< Link Layer Version number. See https://www.bluetooth.org/en-us/specification/assigned-numbers/link-layer for assigned values. */
+ uint16_t company_id; /**< Company ID, Nordic Semiconductor's company ID is 89 (0x0059) (https://www.bluetooth.org/apps/content/Default.aspx?doc_id=49708). */
+ uint16_t subversion_number; /**< Link Layer Sub Version number, corresponds to the SoftDevice Config ID or Firmware ID (FWID). */
+} ble_version_t;
+
+/**
+ * @brief Configuration parameters for the PA and LNA.
+ */
+typedef struct
+{
+ uint8_t enable :1; /**< Enable toggling for this amplifier */
+ uint8_t active_high :1; /**< Set the pin to be active high */
+ uint8_t gpio_pin :6; /**< The GPIO pin to toggle for this amplifier */
+} ble_pa_lna_cfg_t;
+
+/**
+ * @brief PA & LNA GPIO toggle configuration
+ *
+ * This option configures the SoftDevice to toggle pins when the radio is active for use with a power amplifier and/or
+ * a low noise amplifier.
+ *
+ * Toggling the pins is achieved by using two PPI channels and a GPIOTE channel. The hardware channel IDs are provided
+ * by the application and should be regarded as reserved as long as any PA/LNA toggling is enabled.
+ *
+ * @note @ref sd_ble_opt_get is not supported for this option.
+ * @note Setting this option while the radio is in use (i.e. any of the roles are active) may have undefined consequences
+ * and must be avoided by the application.
+ */
+typedef struct
+{
+ ble_pa_lna_cfg_t pa_cfg; /**< Power Amplifier configuration */
+ ble_pa_lna_cfg_t lna_cfg; /**< Low Noise Amplifier configuration */
+
+ uint8_t ppi_ch_id_set; /**< PPI channel used for radio pin setting */
+ uint8_t ppi_ch_id_clr; /**< PPI channel used for radio pin clearing */
+ uint8_t gpiote_ch_id; /**< GPIOTE channel used for radio pin toggling */
+} ble_common_opt_pa_lna_t;
+
+/**
+ * @brief Configuration of extended BLE connection events.
+ *
+ * When enabled the SoftDevice will dynamically extend the connection event when possible.
+ *
+ * The connection event length is controlled by the connection configuration as set by @ref ble_gap_conn_cfg_t::event_length.
+ * The connection event can be extended if there is time to send another packet pair before the start of the next connection interval,
+ * and if there are no conflicts with other BLE roles requesting radio time.
+ *
+ * @note @ref sd_ble_opt_get is not supported for this option.
+ */
+typedef struct
+{
+ uint8_t enable : 1; /**< Enable extended BLE connection events, disabled by default. */
+} ble_common_opt_conn_evt_ext_t;
+
+/**@brief Option structure for common options. */
+typedef union
+{
+ ble_common_opt_pa_lna_t pa_lna; /**< Parameters for controlling PA and LNA pin toggling. */
+ ble_common_opt_conn_evt_ext_t conn_evt_ext; /**< Parameters for enabling extended connection events. */
+} ble_common_opt_t;
+
+/**@brief Common BLE Option type, wrapping the module specific options. */
+typedef union
+{
+ ble_common_opt_t common_opt; /**< COMMON options, opt_id in @ref BLE_COMMON_OPTS series. */
+ ble_gap_opt_t gap_opt; /**< GAP option, opt_id in @ref BLE_GAP_OPTS series. */
+} ble_opt_t;
+
+/**@brief BLE connection configuration type, wrapping the module specific configurations, set with
+ * @ref sd_ble_cfg_set.
+ *
+ * @note Connection configurations don't have to be set.
+ * In the case that no configurations has been set, or fewer connection configurations has been set than enabled connections,
+ * the default connection configuration will be automatically added for the remaining connections.
+ * When creating connections with the default configuration, @ref BLE_CONN_CFG_TAG_DEFAULT should be used in
+ * place of @ref ble_conn_cfg_t::conn_cfg_tag.
+ *
+ * @sa sd_ble_gap_adv_start()
+ * @sa sd_ble_gap_connect()
+ *
+ * @mscs
+ * @mmsc{@ref BLE_CONN_CFG}
+ * @endmscs
+
+ */
+typedef struct
+{
+ uint8_t conn_cfg_tag; /**< The application chosen tag it can use with the
+ @ref sd_ble_gap_adv_start() and @ref sd_ble_gap_connect() calls
+ to select this configuration when creating a connection.
+ Must be different for all connection configurations added and not @ref BLE_CONN_CFG_TAG_DEFAULT. */
+ union {
+ ble_gap_conn_cfg_t gap_conn_cfg; /**< GAP connection configuration, cfg_id is @ref BLE_CONN_CFG_GAP. */
+ ble_gattc_conn_cfg_t gattc_conn_cfg; /**< GATTC connection configuration, cfg_id is @ref BLE_CONN_CFG_GATTC. */
+ ble_gatts_conn_cfg_t gatts_conn_cfg; /**< GATTS connection configuration, cfg_id is @ref BLE_CONN_CFG_GATTS. */
+ ble_gatt_conn_cfg_t gatt_conn_cfg; /**< GATT connection configuration, cfg_id is @ref BLE_CONN_CFG_GATT. */
+ ble_l2cap_conn_cfg_t l2cap_conn_cfg; /**< L2CAP connection configuration, cfg_id is @ref BLE_CONN_CFG_L2CAP. */
+ } params; /**< Connection configuration union. */
+} ble_conn_cfg_t;
+
+/**
+ * @brief Configuration of Vendor Specific UUIDs, set with @ref sd_ble_cfg_set.
+ *
+ * @retval ::NRF_ERROR_INVALID_PARAM Too many UUIDs configured.
+ */
+typedef struct
+{
+ uint8_t vs_uuid_count; /**< Number of 128-bit Vendor Specific UUID bases to allocate memory for.
+ Default value is @ref BLE_UUID_VS_COUNT_DEFAULT. Maximum value is
+ @ref BLE_UUID_VS_COUNT_MAX. */
+} ble_common_cfg_vs_uuid_t;
+
+/**@brief Common BLE Configuration type, wrapping the common configurations. */
+typedef union
+{
+ ble_common_cfg_vs_uuid_t vs_uuid_cfg; /**< Vendor specific UUID configuration, cfg_id is @ref BLE_COMMON_CFG_VS_UUID. */
+} ble_common_cfg_t;
+
+/**@brief BLE Configuration type, wrapping the module specific configurations. */
+typedef union
+{
+ ble_conn_cfg_t conn_cfg; /**< Connection specific configurations, cfg_id in @ref BLE_CONN_CFGS series. */
+ ble_common_cfg_t common_cfg; /**< Global common configurations, cfg_id in @ref BLE_COMMON_CFGS series. */
+ ble_gap_cfg_t gap_cfg; /**< Global GAP configurations, cfg_id in @ref BLE_GAP_CFGS series. */
+ ble_gatts_cfg_t gatts_cfg; /**< Global GATTS configuration, cfg_id in @ref BLE_GATTS_CFGS series. */
+} ble_cfg_t;
+
+/** @} */
+
+/** @addtogroup BLE_COMMON_FUNCTIONS Functions
+ * @{ */
+
+/**@brief Enable the BLE stack
+ *
+ * @param[in, out] p_app_ram_base Pointer to a variable containing the start address of the
+ * application RAM region (APP_RAM_BASE). On return, this will
+ * contain the minimum start address of the application RAM region
+ * required by the SoftDevice for this configuration.
+ *
+ * @note The memory requirement for a specific configuration will not increase between SoftDevices
+ * with the same major version number.
+ *
+ * @note The value of *p_app_ram_base when the app has done no custom configuration of the
+ * SoftDevice, i.e. the app has not called @ref sd_ble_cfg_set before @ref sd_ble_enable, can
+ * be found in the release notes.
+ *
+ * @note At runtime the IC's RAM is split into 2 regions: The SoftDevice RAM region is located
+ * between 0x20000000 and APP_RAM_BASE-1 and the application's RAM region is located between
+ * APP_RAM_BASE and the start of the call stack.
+ *
+ * @details This call initializes the BLE stack, no BLE related function other than @ref
+ * sd_ble_cfg_set can be called before this one.
+ *
+ * @mscs
+ * @mmsc{@ref BLE_COMMON_ENABLE}
+ * @endmscs
+ *
+ * @retval ::NRF_SUCCESS The BLE stack has been initialized successfully.
+ * @retval ::NRF_ERROR_INVALID_STATE The BLE stack had already been initialized and cannot be reinitialized.
+ * @retval ::NRF_ERROR_INVALID_ADDR Invalid or not sufficiently aligned pointer supplied.
+ * @retval ::NRF_ERROR_NO_MEM The amount of memory assigned to the SoftDevice by *p_app_ram_base is not
+ * large enough to fit this configuration's memory requirement. Check *p_app_ram_base
+ * and set the start address of the application RAM region accordingly.
+ */
+SVCALL(SD_BLE_ENABLE, uint32_t, sd_ble_enable(uint32_t * p_app_ram_base));
+
+/**@brief Add configurations for the BLE stack
+ *
+ * @param[in] cfg_id Config ID, see @ref BLE_CONN_CFGS, @ref BLE_COMMON_CFGS, @ref
+ * BLE_GAP_CFGS or @ref BLE_GATTS_CFGS.
+ * @param[in] p_cfg Pointer to a ble_cfg_t structure containing the configuration value.
+ * @param[in] app_ram_base The start address of the application RAM region (APP_RAM_BASE).
+ * See @ref sd_ble_enable for details about APP_RAM_BASE.
+ *
+ * @note The memory requirement for a specific configuration will not increase between SoftDevices
+ * with the same major version number.
+ *
+ * @note If a configuration is set more than once, the last one set is the one that takes effect on
+ * @ref sd_ble_enable.
+ *
+ * @note Any part of the BLE stack that is NOT configured with @ref sd_ble_cfg_set will have default
+ * configuration.
+ *
+ * @note @ref sd_ble_cfg_set may be called at any time when the SoftDevice is enabled (see @ref
+ * sd_softdevice_enable) while the BLE part of the SoftDevice is not enabled (see @ref
+ * sd_ble_enable).
+ *
+ * @note Error codes for the configurations are described in the configuration structs.
+ *
+ * @mscs
+ * @mmsc{@ref BLE_COMMON_ENABLE}
+ * @endmscs
+ *
+ * @retval ::NRF_SUCCESS The configuration has been added successfully.
+ * @retval ::NRF_ERROR_INVALID_STATE The BLE stack had already been initialized.
+ * @retval ::NRF_ERROR_INVALID_ADDR Invalid or not sufficiently aligned pointer supplied.
+ * @retval ::NRF_ERROR_INVALID_PARAM Invalid cfg_id supplied.
+ * @retval ::NRF_ERROR_NO_MEM The amount of memory assigned to the SoftDevice by app_ram_base is not
+ * large enough to fit this configuration's memory requirement.
+ */
+SVCALL(SD_BLE_CFG_SET, uint32_t, sd_ble_cfg_set(uint32_t cfg_id, ble_cfg_t const * p_cfg, uint32_t app_ram_base));
+
+/**@brief Get an event from the pending events queue.
+ *
+ * @param[out] p_dest Pointer to buffer to be filled in with an event, or NULL to retrieve the event length.
+ * This buffer <b>must be aligned to the extend defined by @ref BLE_EVT_PTR_ALIGNMENT</b>.
+ * The buffer should be interpreted as a @ref ble_evt_t struct.
+ * @param[in, out] p_len Pointer the length of the buffer, on return it is filled with the event length.
+ *
+ * @details This call allows the application to pull a BLE event from the BLE stack. The application is signaled that
+ * an event is available from the BLE stack by the triggering of the SD_EVT_IRQn interrupt.
+ * The application is free to choose whether to call this function from thread mode (main context) or directly from the
+ * Interrupt Service Routine that maps to SD_EVT_IRQn. In any case however, and because the BLE stack runs at a higher
+ * priority than the application, this function should be called in a loop (until @ref NRF_ERROR_NOT_FOUND is returned)
+ * every time SD_EVT_IRQn is raised to ensure that all available events are pulled from the BLE stack. Failure to do so
+ * could potentially leave events in the internal queue without the application being aware of this fact.
+ *
+ * Sizing the p_dest buffer is equally important, since the application needs to provide all the memory necessary for the event to
+ * be copied into application memory. If the buffer provided is not large enough to fit the entire contents of the event,
+ * @ref NRF_ERROR_DATA_SIZE will be returned and the application can then call again with a larger buffer size.
+ * The maximum possible event length is defined by @ref BLE_EVT_LEN_MAX. The application may also "peek" the event length
+ * by providing p_dest as a NULL pointer and inspecting the value of *p_len upon return:
+ *
+ * \code
+ * uint16_t len;
+ * errcode = sd_ble_evt_get(NULL, &len);
+ * \endcode
+ *
+ * @mscs
+ * @mmsc{@ref BLE_COMMON_IRQ_EVT_MSC}
+ * @mmsc{@ref BLE_COMMON_THREAD_EVT_MSC}
+ * @endmscs
+ *
+ * @retval ::NRF_SUCCESS Event pulled and stored into the supplied buffer.
+ * @retval ::NRF_ERROR_INVALID_ADDR Invalid or not sufficiently aligned pointer supplied.
+ * @retval ::NRF_ERROR_NOT_FOUND No events ready to be pulled.
+ * @retval ::NRF_ERROR_DATA_SIZE Event ready but could not fit into the supplied buffer.
+ */
+SVCALL(SD_BLE_EVT_GET, uint32_t, sd_ble_evt_get(uint8_t *p_dest, uint16_t *p_len));
+
+
+/**@brief Add a Vendor Specific base UUID.
+ *
+ * @details This call enables the application to add a vendor specific base UUID to the BLE stack's table, for later
+ * use with all other modules and APIs. This then allows the application to use the shorter, 24-bit @ref ble_uuid_t
+ * format when dealing with both 16-bit and 128-bit UUIDs without having to check for lengths and having split code
+ * paths. This is accomplished by extending the grouping mechanism that the Bluetooth SIG standard base UUID uses
+ * for all other 128-bit UUIDs. The type field in the @ref ble_uuid_t structure is an index (relative to
+ * @ref BLE_UUID_TYPE_VENDOR_BEGIN) to the table populated by multiple calls to this function, and the UUID field
+ * in the same structure contains the 2 bytes at indexes 12 and 13. The number of possible 128-bit UUIDs available to
+ * the application is therefore the number of Vendor Specific UUIDs added with the help of this function times 65536,
+ * although restricted to modifying bytes 12 and 13 for each of the entries in the supplied array.
+ *
+ * @note Bytes 12 and 13 of the provided UUID will not be used internally, since those are always replaced by
+ * the 16-bit uuid field in @ref ble_uuid_t.
+ *
+ * @note If a UUID is already present in the BLE stack's internal table, the corresponding index will be returned in
+ * p_uuid_type along with an @ref NRF_SUCCESS error code.
+ *
+ * @param[in] p_vs_uuid Pointer to a 16-octet (128-bit) little endian Vendor Specific UUID disregarding
+ * bytes 12 and 13.
+ * @param[out] p_uuid_type Pointer to a uint8_t where the type field in @ref ble_uuid_t corresponding to this UUID will be stored.
+ *
+ * @retval ::NRF_SUCCESS Successfully added the Vendor Specific UUID.
+ * @retval ::NRF_ERROR_INVALID_ADDR If p_vs_uuid or p_uuid_type is NULL or invalid.
+ * @retval ::NRF_ERROR_NO_MEM If there are no more free slots for VS UUIDs.
+ */
+SVCALL(SD_BLE_UUID_VS_ADD, uint32_t, sd_ble_uuid_vs_add(ble_uuid128_t const *p_vs_uuid, uint8_t *p_uuid_type));
+
+
+/** @brief Decode little endian raw UUID bytes (16-bit or 128-bit) into a 24 bit @ref ble_uuid_t structure.
+ *
+ * @details The raw UUID bytes excluding bytes 12 and 13 (i.e. bytes 0-11 and 14-15) of p_uuid_le are compared
+ * to the corresponding ones in each entry of the table of vendor specific UUIDs populated with @ref sd_ble_uuid_vs_add
+ * to look for a match. If there is such a match, bytes 12 and 13 are returned as p_uuid->uuid and the index
+ * relative to @ref BLE_UUID_TYPE_VENDOR_BEGIN as p_uuid->type.
+ *
+ * @note If the UUID length supplied is 2, then the type set by this call will always be @ref BLE_UUID_TYPE_BLE.
+ *
+ * @param[in] uuid_le_len Length in bytes of the buffer pointed to by p_uuid_le (must be 2 or 16 bytes).
+ * @param[in] p_uuid_le Pointer pointing to little endian raw UUID bytes.
+ * @param[out] p_uuid Pointer to a @ref ble_uuid_t structure to be filled in.
+ *
+ * @retval ::NRF_SUCCESS Successfully decoded into the @ref ble_uuid_t structure.
+ * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied.
+ * @retval ::NRF_ERROR_INVALID_LENGTH Invalid UUID length.
+ * @retval ::NRF_ERROR_NOT_FOUND For a 128-bit UUID, no match in the populated table of UUIDs.
+ */
+SVCALL(SD_BLE_UUID_DECODE, uint32_t, sd_ble_uuid_decode(uint8_t uuid_le_len, uint8_t const *p_uuid_le, ble_uuid_t *p_uuid));
+
+
+/** @brief Encode a @ref ble_uuid_t structure into little endian raw UUID bytes (16-bit or 128-bit).
+ *
+ * @note The pointer to the destination buffer p_uuid_le may be NULL, in which case only the validity and size of p_uuid is computed.
+ *
+ * @param[in] p_uuid Pointer to a @ref ble_uuid_t structure that will be encoded into bytes.
+ * @param[out] p_uuid_le_len Pointer to a uint8_t that will be filled with the encoded length (2 or 16 bytes).
+ * @param[out] p_uuid_le Pointer to a buffer where the little endian raw UUID bytes (2 or 16) will be stored.
+ *
+ * @retval ::NRF_SUCCESS Successfully encoded into the buffer.
+ * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied.
+ * @retval ::NRF_ERROR_INVALID_PARAM Invalid UUID type.
+ */
+SVCALL(SD_BLE_UUID_ENCODE, uint32_t, sd_ble_uuid_encode(ble_uuid_t const *p_uuid, uint8_t *p_uuid_le_len, uint8_t *p_uuid_le));
+
+
+/**@brief Get Version Information.
+ *
+ * @details This call allows the application to get the BLE stack version information.
+ *
+ * @param[out] p_version Pointer to a ble_version_t structure to be filled in.
+ *
+ * @retval ::NRF_SUCCESS Version information stored successfully.
+ * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied.
+ * @retval ::NRF_ERROR_BUSY The BLE stack is busy (typically doing a locally-initiated disconnection procedure).
+ */
+SVCALL(SD_BLE_VERSION_GET, uint32_t, sd_ble_version_get(ble_version_t *p_version));
+
+
+/**@brief Provide a user memory block.
+ *
+ * @note This call can only be used as a response to a @ref BLE_EVT_USER_MEM_REQUEST event issued to the application.
+ *
+ * @param[in] conn_handle Connection handle.
+ * @param[in] p_block Pointer to a user memory block structure or NULL if memory is managed by the application.
+ *
+ * @mscs
+ * @mmsc{@ref BLE_GATTS_QUEUED_WRITE_PEER_CANCEL_MSC}
+ * @mmsc{@ref BLE_GATTS_QUEUED_WRITE_NOBUF_AUTH_MSC}
+ * @mmsc{@ref BLE_GATTS_QUEUED_WRITE_NOBUF_NOAUTH_MSC}
+ * @mmsc{@ref BLE_GATTS_QUEUED_WRITE_BUF_AUTH_MSC}
+ * @mmsc{@ref BLE_GATTS_QUEUED_WRITE_BUF_NOAUTH_MSC}
+ * @mmsc{@ref BLE_GATTS_QUEUED_WRITE_QUEUE_FULL_MSC}
+ * @endmscs
+ *
+ * @retval ::NRF_SUCCESS Successfully queued a response to the peer.
+ * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied.
+ * @retval ::NRF_ERROR_BUSY The stack is busy, process pending events and retry.
+ * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid Connection Handle.
+ * @retval ::NRF_ERROR_INVALID_LENGTH Invalid user memory block length supplied.
+ * @retval ::NRF_ERROR_INVALID_STATE Invalid Connection state or no user memory request pending.
+ */
+SVCALL(SD_BLE_USER_MEM_REPLY, uint32_t, sd_ble_user_mem_reply(uint16_t conn_handle, ble_user_mem_block_t const *p_block));
+
+/**@brief Set a BLE option.
+ *
+ * @details This call allows the application to set the value of an option.
+ *
+ * @mscs
+ * @mmsc{@ref BLE_GAP_PERIPH_BONDING_STATIC_PK_MSC}
+ * @endmscs
+ *
+ * @param[in] opt_id Option ID, see @ref BLE_COMMON_OPTS and @ref BLE_GAP_OPTS.
+ * @param[in] p_opt Pointer to a ble_opt_t structure containing the option value.
+ *
+ * @retval ::NRF_SUCCESS Option set successfully.
+ * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied.
+ * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid Connection Handle.
+ * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied, check parameter limits and constraints.
+ * @retval ::NRF_ERROR_INVALID_STATE Unable to set the parameter at this time.
+ * @retval ::NRF_ERROR_BUSY The BLE stack is busy or the previous procedure has not completed.
+ */
+SVCALL(SD_BLE_OPT_SET, uint32_t, sd_ble_opt_set(uint32_t opt_id, ble_opt_t const *p_opt));
+
+
+/**@brief Get a BLE option.
+ *
+ * @details This call allows the application to retrieve the value of an option.
+ *
+ * @param[in] opt_id Option ID, see @ref BLE_COMMON_OPTS and @ref BLE_GAP_OPTS.
+ * @param[out] p_opt Pointer to a ble_opt_t structure to be filled in.
+ *
+ * @retval ::NRF_SUCCESS Option retrieved successfully.
+ * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied.
+ * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid Connection Handle.
+ * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied, check parameter limits and constraints.
+ * @retval ::NRF_ERROR_INVALID_STATE Unable to retrieve the parameter at this time.
+ * @retval ::NRF_ERROR_BUSY The BLE stack is busy or the previous procedure has not completed.
+ * @retval ::NRF_ERROR_NOT_SUPPORTED This option is not supported.
+ *
+ */
+SVCALL(SD_BLE_OPT_GET, uint32_t, sd_ble_opt_get(uint32_t opt_id, ble_opt_t *p_opt));
+
+/** @} */
+#ifdef __cplusplus
+}
+#endif
+#endif /* BLE_H__ */
+
+/**
+ @}
+ @}
+*/
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/softdevice/s140/headers/ble_err.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/softdevice/s140/headers/ble_err.h
new file mode 100644
index 0000000..1b4820d
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/softdevice/s140/headers/ble_err.h
@@ -0,0 +1,93 @@
+/*
+ * Copyright (c) 2012 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ */
+
+/**
+ @addtogroup BLE_COMMON
+ @{
+ @addtogroup nrf_error
+ @{
+ @ingroup BLE_COMMON
+ @}
+
+ @defgroup ble_err General error codes
+ @{
+
+ @brief General error code definitions for the BLE API.
+
+ @ingroup BLE_COMMON
+*/
+#ifndef NRF_BLE_ERR_H__
+#define NRF_BLE_ERR_H__
+
+#include "nrf_error.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* @defgroup BLE_ERRORS Error Codes
+ * @{ */
+#define BLE_ERROR_NOT_ENABLED (NRF_ERROR_STK_BASE_NUM+0x001) /**< @ref sd_ble_enable has not been called. */
+#define BLE_ERROR_INVALID_CONN_HANDLE (NRF_ERROR_STK_BASE_NUM+0x002) /**< Invalid connection handle. */
+#define BLE_ERROR_INVALID_ATTR_HANDLE (NRF_ERROR_STK_BASE_NUM+0x003) /**< Invalid attribute handle. */
+#define BLE_ERROR_INVALID_ADV_HANDLE (NRF_ERROR_STK_BASE_NUM+0x004) /**< Invalid advertising handle. */
+#define BLE_ERROR_INVALID_ROLE (NRF_ERROR_STK_BASE_NUM+0x005) /**< Invalid role. */
+#define BLE_ERROR_BLOCKED_BY_OTHER_LINKS (NRF_ERROR_STK_BASE_NUM+0x006) /**< The attempt to change link settings failed due to the scheduling of other links. */
+/** @} */
+
+
+/** @defgroup BLE_ERROR_SUBRANGES Module specific error code subranges
+ * @brief Assignment of subranges for module specific error codes.
+ * @note For specific error codes, see ble_<module>.h or ble_error_<module>.h.
+ * @{ */
+#define NRF_L2CAP_ERR_BASE (NRF_ERROR_STK_BASE_NUM+0x100) /**< L2CAP specific errors. */
+#define NRF_GAP_ERR_BASE (NRF_ERROR_STK_BASE_NUM+0x200) /**< GAP specific errors. */
+#define NRF_GATTC_ERR_BASE (NRF_ERROR_STK_BASE_NUM+0x300) /**< GATT client specific errors. */
+#define NRF_GATTS_ERR_BASE (NRF_ERROR_STK_BASE_NUM+0x400) /**< GATT server specific errors. */
+/** @} */
+
+#ifdef __cplusplus
+}
+#endif
+#endif
+
+
+/**
+ @}
+ @}
+*/
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/softdevice/s140/headers/ble_gap.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/softdevice/s140/headers/ble_gap.h
new file mode 100644
index 0000000..6e6cae2
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/softdevice/s140/headers/ble_gap.h
@@ -0,0 +1,2669 @@
+/*
+ * Copyright (c) 2011 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ */
+
+/**
+ @addtogroup BLE_GAP Generic Access Profile (GAP)
+ @{
+ @brief Definitions and prototypes for the GAP interface.
+ */
+
+#ifndef BLE_GAP_H__
+#define BLE_GAP_H__
+
+#include <stdint.h>
+#include "nrf_svc.h"
+#include "nrf_error.h"
+#include "ble_hci.h"
+#include "ble_ranges.h"
+#include "ble_types.h"
+#include "ble_err.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**@addtogroup BLE_GAP_ENUMERATIONS Enumerations
+ * @{ */
+
+/**@brief GAP API SVC numbers.
+ */
+enum BLE_GAP_SVCS
+{
+ SD_BLE_GAP_ADDR_SET = BLE_GAP_SVC_BASE, /**< Set own Bluetooth Address. */
+ SD_BLE_GAP_ADDR_GET = BLE_GAP_SVC_BASE + 1, /**< Get own Bluetooth Address. */
+ SD_BLE_GAP_WHITELIST_SET = BLE_GAP_SVC_BASE + 2, /**< Set active whitelist. */
+ SD_BLE_GAP_DEVICE_IDENTITIES_SET = BLE_GAP_SVC_BASE + 3, /**< Set device identity list. */
+ SD_BLE_GAP_PRIVACY_SET = BLE_GAP_SVC_BASE + 4, /**< Set Privacy settings*/
+ SD_BLE_GAP_PRIVACY_GET = BLE_GAP_SVC_BASE + 5, /**< Get Privacy settings*/
+ SD_BLE_GAP_ADV_SET_CONFIGURE = BLE_GAP_SVC_BASE + 6, /**< Configure an advertising set. */
+ SD_BLE_GAP_ADV_START = BLE_GAP_SVC_BASE + 7, /**< Start Advertising. */
+ SD_BLE_GAP_ADV_STOP = BLE_GAP_SVC_BASE + 8, /**< Stop Advertising. */
+ SD_BLE_GAP_CONN_PARAM_UPDATE = BLE_GAP_SVC_BASE + 9, /**< Connection Parameter Update. */
+ SD_BLE_GAP_DISCONNECT = BLE_GAP_SVC_BASE + 10, /**< Disconnect. */
+ SD_BLE_GAP_TX_POWER_SET = BLE_GAP_SVC_BASE + 11, /**< Set TX Power. */
+ SD_BLE_GAP_APPEARANCE_SET = BLE_GAP_SVC_BASE + 12, /**< Set Appearance. */
+ SD_BLE_GAP_APPEARANCE_GET = BLE_GAP_SVC_BASE + 13, /**< Get Appearance. */
+ SD_BLE_GAP_PPCP_SET = BLE_GAP_SVC_BASE + 14, /**< Set PPCP. */
+ SD_BLE_GAP_PPCP_GET = BLE_GAP_SVC_BASE + 15, /**< Get PPCP. */
+ SD_BLE_GAP_DEVICE_NAME_SET = BLE_GAP_SVC_BASE + 16, /**< Set Device Name. */
+ SD_BLE_GAP_DEVICE_NAME_GET = BLE_GAP_SVC_BASE + 17, /**< Get Device Name. */
+ SD_BLE_GAP_AUTHENTICATE = BLE_GAP_SVC_BASE + 18, /**< Initiate Pairing/Bonding. */
+ SD_BLE_GAP_SEC_PARAMS_REPLY = BLE_GAP_SVC_BASE + 19, /**< Reply with Security Parameters. */
+ SD_BLE_GAP_AUTH_KEY_REPLY = BLE_GAP_SVC_BASE + 20, /**< Reply with an authentication key. */
+ SD_BLE_GAP_LESC_DHKEY_REPLY = BLE_GAP_SVC_BASE + 21, /**< Reply with an LE Secure Connections DHKey. */
+ SD_BLE_GAP_KEYPRESS_NOTIFY = BLE_GAP_SVC_BASE + 22, /**< Notify of a keypress during an authentication procedure. */
+ SD_BLE_GAP_LESC_OOB_DATA_GET = BLE_GAP_SVC_BASE + 23, /**< Get the local LE Secure Connections OOB data. */
+ SD_BLE_GAP_LESC_OOB_DATA_SET = BLE_GAP_SVC_BASE + 24, /**< Set the remote LE Secure Connections OOB data. */
+ SD_BLE_GAP_ENCRYPT = BLE_GAP_SVC_BASE + 25, /**< Initiate encryption procedure. */
+ SD_BLE_GAP_SEC_INFO_REPLY = BLE_GAP_SVC_BASE + 26, /**< Reply with Security Information. */
+ SD_BLE_GAP_CONN_SEC_GET = BLE_GAP_SVC_BASE + 27, /**< Obtain connection security level. */
+ SD_BLE_GAP_RSSI_START = BLE_GAP_SVC_BASE + 28, /**< Start reporting of changes in RSSI. */
+ SD_BLE_GAP_RSSI_STOP = BLE_GAP_SVC_BASE + 29, /**< Stop reporting of changes in RSSI. */
+ SD_BLE_GAP_SCAN_START = BLE_GAP_SVC_BASE + 30, /**< Start Scanning. */
+ SD_BLE_GAP_SCAN_STOP = BLE_GAP_SVC_BASE + 31, /**< Stop Scanning. */
+ SD_BLE_GAP_CONNECT = BLE_GAP_SVC_BASE + 32, /**< Connect. */
+ SD_BLE_GAP_CONNECT_CANCEL = BLE_GAP_SVC_BASE + 33, /**< Cancel ongoing connection procedure. */
+ SD_BLE_GAP_RSSI_GET = BLE_GAP_SVC_BASE + 34, /**< Get the last RSSI sample. */
+ SD_BLE_GAP_PHY_UPDATE = BLE_GAP_SVC_BASE + 35, /**< Initiate or respond to a PHY Update Procedure. */
+ SD_BLE_GAP_DATA_LENGTH_UPDATE = BLE_GAP_SVC_BASE + 36, /**< Initiate or respond to a Data Length Update Procedure. */
+ SD_BLE_GAP_QOS_CHANNEL_SURVEY_START = BLE_GAP_SVC_BASE + 37, /**< Start Quality of Service (QoS) channel survey module. */
+ SD_BLE_GAP_QOS_CHANNEL_SURVEY_STOP = BLE_GAP_SVC_BASE + 38, /**< Stop Quality of Service (QoS) channel survey module. */
+};
+
+/**@brief GAP Event IDs.
+ * IDs that uniquely identify an event coming from the stack to the application.
+ */
+enum BLE_GAP_EVTS
+{
+ BLE_GAP_EVT_CONNECTED = BLE_GAP_EVT_BASE,
+ BLE_GAP_EVT_DISCONNECTED = BLE_GAP_EVT_BASE + 1, /**< Disconnected from peer. \n See @ref ble_gap_evt_disconnected_t. */
+ BLE_GAP_EVT_CONN_PARAM_UPDATE = BLE_GAP_EVT_BASE + 2, /**< Connection Parameters updated. \n See @ref ble_gap_evt_conn_param_update_t. */
+ BLE_GAP_EVT_SEC_PARAMS_REQUEST = BLE_GAP_EVT_BASE + 3, /**< Request to provide security parameters. \n Reply with @ref sd_ble_gap_sec_params_reply. \n See @ref ble_gap_evt_sec_params_request_t. */
+ BLE_GAP_EVT_SEC_INFO_REQUEST = BLE_GAP_EVT_BASE + 4, /**< Request to provide security information. \n Reply with @ref sd_ble_gap_sec_info_reply. \n See @ref ble_gap_evt_sec_info_request_t. */
+ BLE_GAP_EVT_PASSKEY_DISPLAY = BLE_GAP_EVT_BASE + 5, /**< Request to display a passkey to the user. \n In LESC Numeric Comparison, reply with @ref sd_ble_gap_auth_key_reply. \n See @ref ble_gap_evt_passkey_display_t. */
+ BLE_GAP_EVT_KEY_PRESSED = BLE_GAP_EVT_BASE + 6, /**< Notification of a keypress on the remote device.\n See @ref ble_gap_evt_key_pressed_t */
+ BLE_GAP_EVT_AUTH_KEY_REQUEST = BLE_GAP_EVT_BASE + 7, /**< Request to provide an authentication key. \n Reply with @ref sd_ble_gap_auth_key_reply. \n See @ref ble_gap_evt_auth_key_request_t. */
+ BLE_GAP_EVT_LESC_DHKEY_REQUEST = BLE_GAP_EVT_BASE + 8, /**< Request to calculate an LE Secure Connections DHKey. \n Reply with @ref sd_ble_gap_lesc_dhkey_reply. \n See @ref ble_gap_evt_lesc_dhkey_request_t */
+ BLE_GAP_EVT_AUTH_STATUS = BLE_GAP_EVT_BASE + 9, /**< Authentication procedure completed with status. \n See @ref ble_gap_evt_auth_status_t. */
+ BLE_GAP_EVT_CONN_SEC_UPDATE = BLE_GAP_EVT_BASE + 10, /**< Connection security updated. \n See @ref ble_gap_evt_conn_sec_update_t. */
+ BLE_GAP_EVT_TIMEOUT = BLE_GAP_EVT_BASE + 11, /**< Timeout expired. \n See @ref ble_gap_evt_timeout_t. */
+ BLE_GAP_EVT_RSSI_CHANGED = BLE_GAP_EVT_BASE + 12, /**< RSSI report. \n See @ref ble_gap_evt_rssi_changed_t. */
+ BLE_GAP_EVT_ADV_REPORT = BLE_GAP_EVT_BASE + 13, /**< Advertising report. \n See @ref ble_gap_evt_adv_report_t. */
+ BLE_GAP_EVT_SEC_REQUEST = BLE_GAP_EVT_BASE + 14, /**< Security Request. \n See @ref ble_gap_evt_sec_request_t. */
+ BLE_GAP_EVT_CONN_PARAM_UPDATE_REQUEST = BLE_GAP_EVT_BASE + 15, /**< Connection Parameter Update Request. \n Reply with @ref sd_ble_gap_conn_param_update. \n See @ref ble_gap_evt_conn_param_update_request_t. */
+ BLE_GAP_EVT_SCAN_REQ_REPORT = BLE_GAP_EVT_BASE + 16, /**< Scan request report. \n See @ref ble_gap_evt_scan_req_report_t. */
+ BLE_GAP_EVT_PHY_UPDATE_REQUEST = BLE_GAP_EVT_BASE + 17, /**< PHY Update Request. \n Reply with @ref sd_ble_gap_phy_update. \n See @ref ble_gap_evt_phy_update_request_t. */
+ BLE_GAP_EVT_PHY_UPDATE = BLE_GAP_EVT_BASE + 18, /**< PHY Update Procedure is complete. \n See @ref ble_gap_evt_phy_update_t. */
+ BLE_GAP_EVT_DATA_LENGTH_UPDATE_REQUEST = BLE_GAP_EVT_BASE + 19, /**< Data Length Update Request. \n Reply with @ref sd_ble_gap_data_length_update.\n See @ref ble_gap_evt_data_length_update_request_t. */
+ BLE_GAP_EVT_DATA_LENGTH_UPDATE = BLE_GAP_EVT_BASE + 20, /**< LL Data Channel PDU payload length updated. \n See @ref ble_gap_evt_data_length_update_t. */
+ BLE_GAP_EVT_QOS_CHANNEL_SURVEY_REPORT = BLE_GAP_EVT_BASE + 21, /**< Channel survey report. \n See @ref ble_gap_evt_qos_channel_survey_report_t. */
+ BLE_GAP_EVT_ADV_SET_TERMINATED = BLE_GAP_EVT_BASE + 22, /**< Advertising set terminated. \n See @ref ble_gap_evt_adv_set_terminated_t. */
+};
+
+/**@brief GAP Option IDs.
+ * IDs that uniquely identify a GAP option.
+ */
+enum BLE_GAP_OPTS
+{
+ BLE_GAP_OPT_CH_MAP = BLE_GAP_OPT_BASE, /**< Channel Map. @ref ble_gap_opt_ch_map_t */
+ BLE_GAP_OPT_LOCAL_CONN_LATENCY = BLE_GAP_OPT_BASE + 1, /**< Local connection latency. @ref ble_gap_opt_local_conn_latency_t */
+ BLE_GAP_OPT_PASSKEY = BLE_GAP_OPT_BASE + 2, /**< Set passkey. @ref ble_gap_opt_passkey_t */
+ BLE_GAP_OPT_COMPAT_MODE_1 = BLE_GAP_OPT_BASE + 3, /**< Compatibility mode. @ref ble_gap_opt_compat_mode_1_t */
+ BLE_GAP_OPT_AUTH_PAYLOAD_TIMEOUT = BLE_GAP_OPT_BASE + 4, /**< Set Authenticated payload timeout. @ref ble_gap_opt_auth_payload_timeout_t */
+ BLE_GAP_OPT_SLAVE_LATENCY_DISABLE = BLE_GAP_OPT_BASE + 5, /**< Disable slave latency. @ref ble_gap_opt_slave_latency_disable_t */
+};
+
+/**@brief GAP Configuration IDs.
+ *
+ * IDs that uniquely identify a GAP configuration.
+ */
+enum BLE_GAP_CFGS
+{
+ BLE_GAP_CFG_ROLE_COUNT = BLE_GAP_CFG_BASE, /**< Role count configuration. */
+ BLE_GAP_CFG_DEVICE_NAME = BLE_GAP_CFG_BASE + 1, /**< Device name configuration. */
+};
+
+/**@brief GAP TX Power roles.
+ */
+enum BLE_GAP_TX_POWER_ROLES
+{
+ BLE_GAP_TX_POWER_ROLE_ADV = 1, /**< Advertiser role. */
+ BLE_GAP_TX_POWER_ROLE_SCAN_INIT = 2, /**< Scanner and initiator role. */
+ BLE_GAP_TX_POWER_ROLE_CONN = 3, /**< Connection role. */
+};
+
+/** @} */
+
+/**@addtogroup BLE_GAP_DEFINES Defines
+ * @{ */
+
+/**@defgroup BLE_ERRORS_GAP SVC return values specific to GAP
+ * @{ */
+#define BLE_ERROR_GAP_UUID_LIST_MISMATCH (NRF_GAP_ERR_BASE + 0x000) /**< UUID list does not contain an integral number of UUIDs. */
+#define BLE_ERROR_GAP_DISCOVERABLE_WITH_WHITELIST (NRF_GAP_ERR_BASE + 0x001) /**< Use of Whitelist not permitted with discoverable advertising. */
+#define BLE_ERROR_GAP_INVALID_BLE_ADDR (NRF_GAP_ERR_BASE + 0x002) /**< The upper two bits of the address do not correspond to the specified address type. */
+#define BLE_ERROR_GAP_WHITELIST_IN_USE (NRF_GAP_ERR_BASE + 0x003) /**< Attempt to modify the whitelist while already in use by another operation. */
+#define BLE_ERROR_GAP_DEVICE_IDENTITIES_IN_USE (NRF_GAP_ERR_BASE + 0x004) /**< Attempt to modify the device identity list while already in use by another operation. */
+#define BLE_ERROR_GAP_DEVICE_IDENTITIES_DUPLICATE (NRF_GAP_ERR_BASE + 0x005) /**< The device identity list contains entries with duplicate identity addresses. */
+/**@} */
+
+
+/**@defgroup BLE_GAP_ROLES GAP Roles
+ * @{ */
+#define BLE_GAP_ROLE_INVALID 0x0 /**< Invalid Role. */
+#define BLE_GAP_ROLE_PERIPH 0x1 /**< Peripheral Role. */
+#define BLE_GAP_ROLE_CENTRAL 0x2 /**< Central Role. */
+/**@} */
+
+
+/**@defgroup BLE_GAP_TIMEOUT_SOURCES GAP Timeout sources
+ * @{ */
+#define BLE_GAP_TIMEOUT_SRC_SCAN 0x01 /**< Scanning timeout. */
+#define BLE_GAP_TIMEOUT_SRC_CONN 0x02 /**< Connection timeout. */
+#define BLE_GAP_TIMEOUT_SRC_AUTH_PAYLOAD 0x03 /**< Authenticated payload timeout. */
+/**@} */
+
+
+/**@defgroup BLE_GAP_ADDR_TYPES GAP Address types
+ * @{ */
+#define BLE_GAP_ADDR_TYPE_PUBLIC 0x00 /**< Public (identity) address.*/
+#define BLE_GAP_ADDR_TYPE_RANDOM_STATIC 0x01 /**< Random static (identity) address. */
+#define BLE_GAP_ADDR_TYPE_RANDOM_PRIVATE_RESOLVABLE 0x02 /**< Random private resolvable address. */
+#define BLE_GAP_ADDR_TYPE_RANDOM_PRIVATE_NON_RESOLVABLE 0x03 /**< Random private non-resolvable address. */
+#define BLE_GAP_ADDR_TYPE_ANONYMOUS 0x7F /**< An advertiser may advertise without its address.
+ This type of advertising is called anonymous. */
+/**@} */
+
+
+/**@brief The default interval in seconds at which a private address is refreshed. */
+#define BLE_GAP_DEFAULT_PRIVATE_ADDR_CYCLE_INTERVAL_S (900) /* 15 minutes. */
+/**@brief The maximum interval in seconds at which a private address can be refreshed. */
+#define BLE_GAP_MAX_PRIVATE_ADDR_CYCLE_INTERVAL_S (41400) /* 11 hours 30 minutes. */
+
+
+/** @brief BLE address length. */
+#define BLE_GAP_ADDR_LEN (6)
+
+/**@defgroup BLE_GAP_PRIVACY_MODES Privacy modes
+ * @{ */
+#define BLE_GAP_PRIVACY_MODE_OFF 0x00 /**< Device will send and accept its identity address for its own address. */
+#define BLE_GAP_PRIVACY_MODE_DEVICE_PRIVACY 0x01 /**< Device will send and accept only private addresses for its own address. */
+#define BLE_GAP_PRIVACY_MODE_NETWORK_PRIVACY 0x02 /**< Device will send and accept only private addresses for its own address,
+ and will not accept a peer using identity address as sender address when
+ the peer IRK is exchanged, non-zero and added to the identity list. */
+/**@} */
+
+/** @brief Invalid power level. */
+#define BLE_GAP_POWER_LEVEL_INVALID 127
+
+/** @brief Advertising set handle not set. */
+#define BLE_GAP_ADV_SET_HANDLE_NOT_SET (0xFF)
+
+/** @brief The default number of advertising sets. */
+#define BLE_GAP_ADV_SET_COUNT_DEFAULT (1)
+
+/** @brief The maximum number of advertising sets supported by this SoftDevice. */
+#define BLE_GAP_ADV_SET_COUNT_MAX (1)
+
+/**@defgroup BLE_GAP_ADV_SET_DATA_SIZES Advertising data sizes.
+ * @{ */
+#define BLE_GAP_ADV_SET_DATA_SIZE_MAX (31) /**< Maximum data length for an advertising set. */
+/**@}. */
+
+/** @brief Set ID not available in advertising report. */
+#define BLE_GAP_ADV_REPORT_SET_ID_NOT_AVAILABLE 0xFF
+
+/**@defgroup BLE_GAP_EVT_ADV_SET_TERMINATED_REASON GAP Advertising Set Terminated reasons
+ * @{ */
+#define BLE_GAP_EVT_ADV_SET_TERMINATED_REASON_TIMEOUT 0x01 /**< Timeout value reached. */
+#define BLE_GAP_EVT_ADV_SET_TERMINATED_REASON_LIMIT_REACHED 0x02 /**< @ref ble_gap_adv_params_t::max_adv_evts was reached. */
+/**@} */
+
+/**@defgroup BLE_GAP_AD_TYPE_DEFINITIONS GAP Advertising and Scan Response Data format
+ * @note Found at https://www.bluetooth.org/Technical/AssignedNumbers/generic_access_profile.htm
+ * @{ */
+#define BLE_GAP_AD_TYPE_FLAGS 0x01 /**< Flags for discoverability. */
+#define BLE_GAP_AD_TYPE_16BIT_SERVICE_UUID_MORE_AVAILABLE 0x02 /**< Partial list of 16 bit service UUIDs. */
+#define BLE_GAP_AD_TYPE_16BIT_SERVICE_UUID_COMPLETE 0x03 /**< Complete list of 16 bit service UUIDs. */
+#define BLE_GAP_AD_TYPE_32BIT_SERVICE_UUID_MORE_AVAILABLE 0x04 /**< Partial list of 32 bit service UUIDs. */
+#define BLE_GAP_AD_TYPE_32BIT_SERVICE_UUID_COMPLETE 0x05 /**< Complete list of 32 bit service UUIDs. */
+#define BLE_GAP_AD_TYPE_128BIT_SERVICE_UUID_MORE_AVAILABLE 0x06 /**< Partial list of 128 bit service UUIDs. */
+#define BLE_GAP_AD_TYPE_128BIT_SERVICE_UUID_COMPLETE 0x07 /**< Complete list of 128 bit service UUIDs. */
+#define BLE_GAP_AD_TYPE_SHORT_LOCAL_NAME 0x08 /**< Short local device name. */
+#define BLE_GAP_AD_TYPE_COMPLETE_LOCAL_NAME 0x09 /**< Complete local device name. */
+#define BLE_GAP_AD_TYPE_TX_POWER_LEVEL 0x0A /**< Transmit power level. */
+#define BLE_GAP_AD_TYPE_CLASS_OF_DEVICE 0x0D /**< Class of device. */
+#define BLE_GAP_AD_TYPE_SIMPLE_PAIRING_HASH_C 0x0E /**< Simple Pairing Hash C. */
+#define BLE_GAP_AD_TYPE_SIMPLE_PAIRING_RANDOMIZER_R 0x0F /**< Simple Pairing Randomizer R. */
+#define BLE_GAP_AD_TYPE_SECURITY_MANAGER_TK_VALUE 0x10 /**< Security Manager TK Value. */
+#define BLE_GAP_AD_TYPE_SECURITY_MANAGER_OOB_FLAGS 0x11 /**< Security Manager Out Of Band Flags. */
+#define BLE_GAP_AD_TYPE_SLAVE_CONNECTION_INTERVAL_RANGE 0x12 /**< Slave Connection Interval Range. */
+#define BLE_GAP_AD_TYPE_SOLICITED_SERVICE_UUIDS_16BIT 0x14 /**< List of 16-bit Service Solicitation UUIDs. */
+#define BLE_GAP_AD_TYPE_SOLICITED_SERVICE_UUIDS_128BIT 0x15 /**< List of 128-bit Service Solicitation UUIDs. */
+#define BLE_GAP_AD_TYPE_SERVICE_DATA 0x16 /**< Service Data - 16-bit UUID. */
+#define BLE_GAP_AD_TYPE_PUBLIC_TARGET_ADDRESS 0x17 /**< Public Target Address. */
+#define BLE_GAP_AD_TYPE_RANDOM_TARGET_ADDRESS 0x18 /**< Random Target Address. */
+#define BLE_GAP_AD_TYPE_APPEARANCE 0x19 /**< Appearance. */
+#define BLE_GAP_AD_TYPE_ADVERTISING_INTERVAL 0x1A /**< Advertising Interval. */
+#define BLE_GAP_AD_TYPE_LE_BLUETOOTH_DEVICE_ADDRESS 0x1B /**< LE Bluetooth Device Address. */
+#define BLE_GAP_AD_TYPE_LE_ROLE 0x1C /**< LE Role. */
+#define BLE_GAP_AD_TYPE_SIMPLE_PAIRING_HASH_C256 0x1D /**< Simple Pairing Hash C-256. */
+#define BLE_GAP_AD_TYPE_SIMPLE_PAIRING_RANDOMIZER_R256 0x1E /**< Simple Pairing Randomizer R-256. */
+#define BLE_GAP_AD_TYPE_SERVICE_DATA_32BIT_UUID 0x20 /**< Service Data - 32-bit UUID. */
+#define BLE_GAP_AD_TYPE_SERVICE_DATA_128BIT_UUID 0x21 /**< Service Data - 128-bit UUID. */
+#define BLE_GAP_AD_TYPE_LESC_CONFIRMATION_VALUE 0x22 /**< LE Secure Connections Confirmation Value */
+#define BLE_GAP_AD_TYPE_LESC_RANDOM_VALUE 0x23 /**< LE Secure Connections Random Value */
+#define BLE_GAP_AD_TYPE_URI 0x24 /**< URI */
+#define BLE_GAP_AD_TYPE_3D_INFORMATION_DATA 0x3D /**< 3D Information Data. */
+#define BLE_GAP_AD_TYPE_MANUFACTURER_SPECIFIC_DATA 0xFF /**< Manufacturer Specific Data. */
+/**@} */
+
+
+/**@defgroup BLE_GAP_ADV_FLAGS GAP Advertisement Flags
+ * @{ */
+#define BLE_GAP_ADV_FLAG_LE_LIMITED_DISC_MODE (0x01) /**< LE Limited Discoverable Mode. */
+#define BLE_GAP_ADV_FLAG_LE_GENERAL_DISC_MODE (0x02) /**< LE General Discoverable Mode. */
+#define BLE_GAP_ADV_FLAG_BR_EDR_NOT_SUPPORTED (0x04) /**< BR/EDR not supported. */
+#define BLE_GAP_ADV_FLAG_LE_BR_EDR_CONTROLLER (0x08) /**< Simultaneous LE and BR/EDR, Controller. */
+#define BLE_GAP_ADV_FLAG_LE_BR_EDR_HOST (0x10) /**< Simultaneous LE and BR/EDR, Host. */
+#define BLE_GAP_ADV_FLAGS_LE_ONLY_LIMITED_DISC_MODE (BLE_GAP_ADV_FLAG_LE_LIMITED_DISC_MODE | BLE_GAP_ADV_FLAG_BR_EDR_NOT_SUPPORTED) /**< LE Limited Discoverable Mode, BR/EDR not supported. */
+#define BLE_GAP_ADV_FLAGS_LE_ONLY_GENERAL_DISC_MODE (BLE_GAP_ADV_FLAG_LE_GENERAL_DISC_MODE | BLE_GAP_ADV_FLAG_BR_EDR_NOT_SUPPORTED) /**< LE General Discoverable Mode, BR/EDR not supported. */
+/**@} */
+
+
+/**@defgroup BLE_GAP_ADV_INTERVALS GAP Advertising interval max and min
+ * @{ */
+#define BLE_GAP_ADV_INTERVAL_MIN 0x000020 /**< Minimum Advertising interval in 625 us units, i.e. 20 ms. */
+#define BLE_GAP_ADV_INTERVAL_MAX 0x004000 /**< Maximum Advertising interval in 625 us units, i.e. 10.24 s.
+ @note Support for values above @ref BLE_GAP_ADV_INTERVAL_MAX
+ is experimental. Values above 0xFFFFFF, i.e 10,485.759375 s
+ are not supported. */
+ /**@} */
+
+
+/**@defgroup BLE_GAP_SCAN_INTERVALS GAP Scan interval max and min
+ * @{ */
+#define BLE_GAP_SCAN_INTERVAL_MIN 0x0004 /**< Minimum Scan interval in 625 us units, i.e. 2.5 ms. */
+#define BLE_GAP_SCAN_INTERVAL_MAX 0xFFFF /**< Maximum Scan interval in 625 us units, i.e. 40,959.375 s. */
+ /** @} */
+
+
+/**@defgroup BLE_GAP_SCAN_WINDOW GAP Scan window max and min
+ * @{ */
+#define BLE_GAP_SCAN_WINDOW_MIN 0x0004 /**< Minimum Scan window in 625 us units, i.e. 2.5 ms. */
+#define BLE_GAP_SCAN_WINDOW_MAX 0xFFFF /**< Maximum Scan window in 625 us units, i.e. 40,959.375 s. */
+ /** @} */
+
+
+/**@defgroup BLE_GAP_SCAN_TIMEOUT GAP Scan timeout max and min
+ * @{ */
+#define BLE_GAP_SCAN_TIMEOUT_MIN 0x0001 /**< Minimum Scan timeout in 10 ms units, i.e 10 ms. */
+#define BLE_GAP_SCAN_TIMEOUT_UNLIMITED 0x0000 /**< Continue to scan forever. */
+ /** @} */
+
+/**@defgroup BLE_GAP_SCAN_BUFFER_SIZE GAP Minimum scanner buffer size
+ *
+ * Scan buffers are used for storing advertising data received from an advertiser.
+ * If ble_gap_scan_params_t::extended is set to 0, @ref BLE_GAP_SCAN_BUFFER_MIN is the minimum scan buffer length.
+ * else the minimum scan buffer size is @ref BLE_GAP_SCAN_BUFFER_EXTENDED_MIN.
+ * @{ */
+#define BLE_GAP_SCAN_BUFFER_MIN (31) /**< Minimum data length for an
+ advertising set. */
+#define BLE_GAP_SCAN_BUFFER_MAX (31) /**< Maximum data length for an
+ advertising set. */
+#define BLE_GAP_SCAN_BUFFER_EXTENDED_MIN (255) /**< Minimum data length for an
+ extended advertising set. */
+#define BLE_GAP_SCAN_BUFFER_EXTENDED_MAX (1650) /**< Maximum data length for an
+ extended advertising set.
+ @note Extended scanning is only
+ supported as an experimental
+ feature in this SoftDevice.
+ The scanner will only receive
+ advertising data up to 31 bytes. */
+/** @} */
+
+/**@defgroup BLE_GAP_ADV_TYPES GAP Advertising types
+ *
+ * Advertising types defined in Bluetooth Core Specification v5.0, Vol 6, Part B, Section 4.4.2.
+ *
+ * The maximum advertising data length is defined by @ref BLE_GAP_ADV_SET_DATA_SIZE_MAX.
+ * Note that some of the advertising types do not support advertising data. Non-scannable types do not support
+ * scan response data.
+ *
+ * @{ */
+#define BLE_GAP_ADV_TYPE_CONNECTABLE_SCANNABLE_UNDIRECTED 0x01 /**< Connectable and scannable undirected
+ advertising events. */
+#define BLE_GAP_ADV_TYPE_CONNECTABLE_NONSCANNABLE_DIRECTED_HIGH_DUTY_CYCLE 0x02 /**< Connectable non-scannable directed advertising
+ events. Advertising interval is less that 3.75 ms.
+ Use this type for fast reconnections.
+ @note Advertising data is not supported. */
+#define BLE_GAP_ADV_TYPE_CONNECTABLE_NONSCANNABLE_DIRECTED 0x03 /**< Connectable non-scannable directed advertising
+ events.
+ @note Advertising data is not supported. */
+#define BLE_GAP_ADV_TYPE_NONCONNECTABLE_SCANNABLE_UNDIRECTED 0x04 /**< Non-connectable scannable undirected
+ advertising events. */
+#define BLE_GAP_ADV_TYPE_NONCONNECTABLE_NONSCANNABLE_UNDIRECTED 0x05 /**< Non-connectable non-scannable undirected
+ advertising events. */
+#define BLE_GAP_ADV_TYPE_EXTENDED_CONNECTABLE_NONSCANNABLE_UNDIRECTED 0x06 /**< Connectable non-scannable undirected advertising
+ events using extended advertising PDUs.
+ @note Extended advertising types are only
+ supported as experimental features in this
+ SoftDevice. */
+#define BLE_GAP_ADV_TYPE_EXTENDED_CONNECTABLE_NONSCANNABLE_DIRECTED 0x07 /**< Connectable non-scannable directed advertising
+ events using extended advertising PDUs.
+ @note Extended advertising types are only
+ supported as experimental features in this
+ SoftDevice. */
+#define BLE_GAP_ADV_TYPE_EXTENDED_NONCONNECTABLE_SCANNABLE_UNDIRECTED 0x08 /**< Non-connectable scannable undirected advertising
+ events using extended advertising PDUs.
+ @note Only scan response data is supported.
+ @note Extended advertising types are only
+ supported as experimental features in this
+ SoftDevice. */
+#define BLE_GAP_ADV_TYPE_EXTENDED_NONCONNECTABLE_SCANNABLE_DIRECTED 0x09 /**< Non-connectable scannable directed advertising
+ events using extended advertising PDUs.
+ @note Only scan response data is supported.
+ @note Extended advertising types are only
+ supported as experimental features in this
+ SoftDevice. */
+#define BLE_GAP_ADV_TYPE_EXTENDED_NONCONNECTABLE_NONSCANNABLE_UNDIRECTED 0x0A /**< Non-connectable non-scannable undirected advertising
+ events using extended advertising PDUs.
+ @note Extended advertising types are only
+ supported as experimental features in this
+ SoftDevice. */
+#define BLE_GAP_ADV_TYPE_EXTENDED_NONCONNECTABLE_NONSCANNABLE_DIRECTED 0x0B /**< Non-connectable non-scannable directed advertising
+ events using extended advertising PDUs.
+ @note Extended advertising types are only
+ supported as experimental features in this
+ SoftDevice. */
+/**@} */
+
+/**@defgroup BLE_GAP_ADV_FILTER_POLICIES GAP Advertising filter policies
+ * @{ */
+#define BLE_GAP_ADV_FP_ANY 0x00 /**< Allow scan requests and connect requests from any device. */
+#define BLE_GAP_ADV_FP_FILTER_SCANREQ 0x01 /**< Filter scan requests with whitelist. */
+#define BLE_GAP_ADV_FP_FILTER_CONNREQ 0x02 /**< Filter connect requests with whitelist. */
+#define BLE_GAP_ADV_FP_FILTER_BOTH 0x03 /**< Filter both scan and connect requests with whitelist. */
+/**@} */
+
+/**@defgroup BLE_GAP_ADV_DATA_STATUS GAP Advertising data status
+ * @{ */
+#define BLE_GAP_ADV_DATA_STATUS_COMPLETE 0x00 /**< All data in the advertising event have been received. */
+#define BLE_GAP_ADV_DATA_STATUS_INCOMPLETE_MORE_DATA 0x01 /**< More data to be received. */
+#define BLE_GAP_ADV_DATA_STATUS_INCOMPLETE_TRUNCATED 0x02 /**< Incomplete data. Buffer size insufficient to receive more. */
+#define BLE_GAP_ADV_DATA_STATUS_INCOMPLETE_MISSED 0x03 /**< Failed to receive the remaining data. */
+/**@} */
+
+/**@defgroup BLE_GAP_SCAN_FILTER_POLICIES GAP Scanner filter policies
+ * @{ */
+#define BLE_GAP_SCAN_FP_ACCEPT_ALL 0x00 /**< Accept all advertising packets except directed advertising packets
+ not addressed to this device. */
+#define BLE_GAP_SCAN_FP_WHITELIST 0x01 /**< Accept advertising packets from devices in the whitelist except directed
+ packets not addressed to this device. */
+#define BLE_GAP_SCAN_FP_ALL_NOT_RESOLVED_DIRECTED 0x02 /**< Accept all advertising packets specified in @ref BLE_GAP_SCAN_FP_ACCEPT_ALL.
+ In addition, accept directed advertising packets, where the advertiser's
+ address is a resolvable private address that cannot be resolved. */
+#define BLE_GAP_SCAN_FP_WHITELIST_NOT_RESOLVED_DIRECTED 0x03 /**< Accept all advertising packets specified in @ref BLE_GAP_SCAN_FP_WHITELIST.
+ In addition, accept directed advertising packets, where the advertiser's
+ address is a resolvable private address that cannot be resolved. */
+/**@} */
+
+/**@defgroup BLE_GAP_ADV_TIMEOUT_VALUES GAP Advertising timeout values in 10 ms units
+ * @{ */
+#define BLE_GAP_ADV_TIMEOUT_HIGH_DUTY_MAX (128) /**< Maximum high duty advertising time in 10 ms units. Corresponds to 1.28 s. */
+#define BLE_GAP_ADV_TIMEOUT_LIMITED_MAX (18000) /**< Maximum advertising time in 10 ms units corresponding to TGAP(lim_adv_timeout) = 180 s in limited discoverable mode. */
+#define BLE_GAP_ADV_TIMEOUT_GENERAL_UNLIMITED (0) /**< Unlimited advertising in general discoverable mode.
+ For high duty cycle advertising, this corresponds to @ref BLE_GAP_ADV_TIMEOUT_HIGH_DUTY_MAX. */
+/**@} */
+
+
+/**@defgroup BLE_GAP_DISC_MODES GAP Discovery modes
+ * @{ */
+#define BLE_GAP_DISC_MODE_NOT_DISCOVERABLE 0x00 /**< Not discoverable discovery Mode. */
+#define BLE_GAP_DISC_MODE_LIMITED 0x01 /**< Limited Discovery Mode. */
+#define BLE_GAP_DISC_MODE_GENERAL 0x02 /**< General Discovery Mode. */
+/**@} */
+
+
+/**@defgroup BLE_GAP_IO_CAPS GAP IO Capabilities
+ * @{ */
+#define BLE_GAP_IO_CAPS_DISPLAY_ONLY 0x00 /**< Display Only. */
+#define BLE_GAP_IO_CAPS_DISPLAY_YESNO 0x01 /**< Display and Yes/No entry. */
+#define BLE_GAP_IO_CAPS_KEYBOARD_ONLY 0x02 /**< Keyboard Only. */
+#define BLE_GAP_IO_CAPS_NONE 0x03 /**< No I/O capabilities. */
+#define BLE_GAP_IO_CAPS_KEYBOARD_DISPLAY 0x04 /**< Keyboard and Display. */
+/**@} */
+
+
+/**@defgroup BLE_GAP_AUTH_KEY_TYPES GAP Authentication Key Types
+ * @{ */
+#define BLE_GAP_AUTH_KEY_TYPE_NONE 0x00 /**< No key (may be used to reject). */
+#define BLE_GAP_AUTH_KEY_TYPE_PASSKEY 0x01 /**< 6-digit Passkey. */
+#define BLE_GAP_AUTH_KEY_TYPE_OOB 0x02 /**< Out Of Band data. */
+/**@} */
+
+
+/**@defgroup BLE_GAP_KP_NOT_TYPES GAP Keypress Notification Types
+ * @{ */
+#define BLE_GAP_KP_NOT_TYPE_PASSKEY_START 0x00 /**< Passkey entry started. */
+#define BLE_GAP_KP_NOT_TYPE_PASSKEY_DIGIT_IN 0x01 /**< Passkey digit entered. */
+#define BLE_GAP_KP_NOT_TYPE_PASSKEY_DIGIT_OUT 0x02 /**< Passkey digit erased. */
+#define BLE_GAP_KP_NOT_TYPE_PASSKEY_CLEAR 0x03 /**< Passkey cleared. */
+#define BLE_GAP_KP_NOT_TYPE_PASSKEY_END 0x04 /**< Passkey entry completed. */
+/**@} */
+
+
+/**@defgroup BLE_GAP_SEC_STATUS GAP Security status
+ * @{ */
+#define BLE_GAP_SEC_STATUS_SUCCESS 0x00 /**< Procedure completed with success. */
+#define BLE_GAP_SEC_STATUS_TIMEOUT 0x01 /**< Procedure timed out. */
+#define BLE_GAP_SEC_STATUS_PDU_INVALID 0x02 /**< Invalid PDU received. */
+#define BLE_GAP_SEC_STATUS_RFU_RANGE1_BEGIN 0x03 /**< Reserved for Future Use range #1 begin. */
+#define BLE_GAP_SEC_STATUS_RFU_RANGE1_END 0x80 /**< Reserved for Future Use range #1 end. */
+#define BLE_GAP_SEC_STATUS_PASSKEY_ENTRY_FAILED 0x81 /**< Passkey entry failed (user canceled or other). */
+#define BLE_GAP_SEC_STATUS_OOB_NOT_AVAILABLE 0x82 /**< Out of Band Key not available. */
+#define BLE_GAP_SEC_STATUS_AUTH_REQ 0x83 /**< Authentication requirements not met. */
+#define BLE_GAP_SEC_STATUS_CONFIRM_VALUE 0x84 /**< Confirm value failed. */
+#define BLE_GAP_SEC_STATUS_PAIRING_NOT_SUPP 0x85 /**< Pairing not supported. */
+#define BLE_GAP_SEC_STATUS_ENC_KEY_SIZE 0x86 /**< Encryption key size. */
+#define BLE_GAP_SEC_STATUS_SMP_CMD_UNSUPPORTED 0x87 /**< Unsupported SMP command. */
+#define BLE_GAP_SEC_STATUS_UNSPECIFIED 0x88 /**< Unspecified reason. */
+#define BLE_GAP_SEC_STATUS_REPEATED_ATTEMPTS 0x89 /**< Too little time elapsed since last attempt. */
+#define BLE_GAP_SEC_STATUS_INVALID_PARAMS 0x8A /**< Invalid parameters. */
+#define BLE_GAP_SEC_STATUS_DHKEY_FAILURE 0x8B /**< DHKey check failure. */
+#define BLE_GAP_SEC_STATUS_NUM_COMP_FAILURE 0x8C /**< Numeric Comparison failure. */
+#define BLE_GAP_SEC_STATUS_BR_EDR_IN_PROG 0x8D /**< BR/EDR pairing in progress. */
+#define BLE_GAP_SEC_STATUS_X_TRANS_KEY_DISALLOWED 0x8E /**< BR/EDR Link Key cannot be used for LE keys. */
+#define BLE_GAP_SEC_STATUS_RFU_RANGE2_BEGIN 0x8F /**< Reserved for Future Use range #2 begin. */
+#define BLE_GAP_SEC_STATUS_RFU_RANGE2_END 0xFF /**< Reserved for Future Use range #2 end. */
+/**@} */
+
+
+/**@defgroup BLE_GAP_SEC_STATUS_SOURCES GAP Security status sources
+ * @{ */
+#define BLE_GAP_SEC_STATUS_SOURCE_LOCAL 0x00 /**< Local failure. */
+#define BLE_GAP_SEC_STATUS_SOURCE_REMOTE 0x01 /**< Remote failure. */
+/**@} */
+
+
+/**@defgroup BLE_GAP_CP_LIMITS GAP Connection Parameters Limits
+ * @{ */
+#define BLE_GAP_CP_MIN_CONN_INTVL_NONE 0xFFFF /**< No new minimum connection interval specified in connect parameters. */
+#define BLE_GAP_CP_MIN_CONN_INTVL_MIN 0x0006 /**< Lowest minimum connection interval permitted, in units of 1.25 ms, i.e. 7.5 ms. */
+#define BLE_GAP_CP_MIN_CONN_INTVL_MAX 0x0C80 /**< Highest minimum connection interval permitted, in units of 1.25 ms, i.e. 4 s. */
+#define BLE_GAP_CP_MAX_CONN_INTVL_NONE 0xFFFF /**< No new maximum connection interval specified in connect parameters. */
+#define BLE_GAP_CP_MAX_CONN_INTVL_MIN 0x0006 /**< Lowest maximum connection interval permitted, in units of 1.25 ms, i.e. 7.5 ms. */
+#define BLE_GAP_CP_MAX_CONN_INTVL_MAX 0x0C80 /**< Highest maximum connection interval permitted, in units of 1.25 ms, i.e. 4 s. */
+#define BLE_GAP_CP_SLAVE_LATENCY_MAX 0x01F3 /**< Highest slave latency permitted, in connection events. */
+#define BLE_GAP_CP_CONN_SUP_TIMEOUT_NONE 0xFFFF /**< No new supervision timeout specified in connect parameters. */
+#define BLE_GAP_CP_CONN_SUP_TIMEOUT_MIN 0x000A /**< Lowest supervision timeout permitted, in units of 10 ms, i.e. 100 ms. */
+#define BLE_GAP_CP_CONN_SUP_TIMEOUT_MAX 0x0C80 /**< Highest supervision timeout permitted, in units of 10 ms, i.e. 32 s. */
+/**@} */
+
+
+/**@defgroup BLE_GAP_DEVNAME GAP device name defines.
+ * @{ */
+#define BLE_GAP_DEVNAME_DEFAULT "nRF5x" /**< Default device name value. */
+#define BLE_GAP_DEVNAME_DEFAULT_LEN 31 /**< Default number of octets in device name. */
+#define BLE_GAP_DEVNAME_MAX_LEN 248 /**< Maximum number of octets in device name. */
+/**@} */
+
+
+/**@brief Disable RSSI events for connections */
+#define BLE_GAP_RSSI_THRESHOLD_INVALID 0xFF
+
+/**@defgroup BLE_GAP_PHYS GAP PHYs
+ * @{ */
+#define BLE_GAP_PHY_AUTO 0x00 /**< Automatic PHY selection. Refer @ref sd_ble_gap_phy_update for more information.*/
+#define BLE_GAP_PHY_1MBPS 0x01 /**< 1 Mbps PHY. */
+#define BLE_GAP_PHY_2MBPS 0x02 /**< 2 Mbps PHY. */
+#define BLE_GAP_PHY_CODED 0x04 /**< Coded PHY. */
+#define BLE_GAP_PHY_NOT_SET 0xFF /**< PHY is not configured. */
+
+/**@brief Supported PHYs in connections, for scanning, and for advertising. */
+#define BLE_GAP_PHYS_SUPPORTED (BLE_GAP_PHY_1MBPS | BLE_GAP_PHY_2MBPS | BLE_GAP_PHY_CODED) /**< All PHYs are supported.
+ @note Coded PHY is only supported
+ as an experimental feature
+ in this SoftDevice. */
+
+/**@} */
+
+/**@defgroup BLE_GAP_CONN_SEC_MODE_SET_MACROS GAP attribute security requirement setters
+ *
+ * See @ref ble_gap_conn_sec_mode_t.
+ * @{ */
+/**@brief Set sec_mode pointed to by ptr to have no access rights.*/
+#define BLE_GAP_CONN_SEC_MODE_SET_NO_ACCESS(ptr) do {(ptr)->sm = 0; (ptr)->lv = 0;} while(0)
+/**@brief Set sec_mode pointed to by ptr to require no protection, open link.*/
+#define BLE_GAP_CONN_SEC_MODE_SET_OPEN(ptr) do {(ptr)->sm = 1; (ptr)->lv = 1;} while(0)
+/**@brief Set sec_mode pointed to by ptr to require encryption, but no MITM protection.*/
+#define BLE_GAP_CONN_SEC_MODE_SET_ENC_NO_MITM(ptr) do {(ptr)->sm = 1; (ptr)->lv = 2;} while(0)
+/**@brief Set sec_mode pointed to by ptr to require encryption and MITM protection.*/
+#define BLE_GAP_CONN_SEC_MODE_SET_ENC_WITH_MITM(ptr) do {(ptr)->sm = 1; (ptr)->lv = 3;} while(0)
+/**@brief Set sec_mode pointed to by ptr to require LESC encryption and MITM protection.*/
+#define BLE_GAP_CONN_SEC_MODE_SET_LESC_ENC_WITH_MITM(ptr) do {(ptr)->sm = 1; (ptr)->lv = 4;} while(0)
+/**@brief Set sec_mode pointed to by ptr to require signing or encryption, no MITM protection needed.*/
+#define BLE_GAP_CONN_SEC_MODE_SET_SIGNED_NO_MITM(ptr) do {(ptr)->sm = 2; (ptr)->lv = 1;} while(0)
+/**@brief Set sec_mode pointed to by ptr to require signing or encryption with MITM protection.*/
+#define BLE_GAP_CONN_SEC_MODE_SET_SIGNED_WITH_MITM(ptr) do {(ptr)->sm = 2; (ptr)->lv = 2;} while(0)
+/**@} */
+
+
+/**@brief GAP Security Random Number Length. */
+#define BLE_GAP_SEC_RAND_LEN 8
+
+
+/**@brief GAP Security Key Length. */
+#define BLE_GAP_SEC_KEY_LEN 16
+
+
+/**@brief GAP LE Secure Connections Elliptic Curve Diffie-Hellman P-256 Public Key Length. */
+#define BLE_GAP_LESC_P256_PK_LEN 64
+
+
+/**@brief GAP LE Secure Connections Elliptic Curve Diffie-Hellman DHKey Length. */
+#define BLE_GAP_LESC_DHKEY_LEN 32
+
+
+/**@brief GAP Passkey Length. */
+#define BLE_GAP_PASSKEY_LEN 6
+
+
+/**@brief Maximum amount of addresses in the whitelist. */
+#define BLE_GAP_WHITELIST_ADDR_MAX_COUNT (8)
+
+
+/**@brief Maximum amount of identities in the device identities list. */
+#define BLE_GAP_DEVICE_IDENTITIES_MAX_COUNT (8)
+
+
+/**@brief Default connection count for a configuration. */
+#define BLE_GAP_CONN_COUNT_DEFAULT (1)
+
+
+/**@defgroup BLE_GAP_EVENT_LENGTH GAP event length defines.
+ * @{ */
+#define BLE_GAP_EVENT_LENGTH_MIN (2) /**< Minimum event length, in 1.25 ms units. */
+#define BLE_GAP_EVENT_LENGTH_CODED_PHY_MIN (6) /**< The shortest event length in 1.25 ms units supporting LE Coded PHY. */
+#define BLE_GAP_EVENT_LENGTH_DEFAULT (3) /**< Default event length, in 1.25 ms units. */
+/**@} */
+
+
+/**@defgroup BLE_GAP_ROLE_COUNT GAP concurrent connection count defines.
+ * @{ */
+#define BLE_GAP_ROLE_COUNT_PERIPH_DEFAULT (1) /**< Default maximum number of connections concurrently acting as peripherals. */
+#define BLE_GAP_ROLE_COUNT_CENTRAL_DEFAULT (3) /**< Default maximum number of connections concurrently acting as centrals. */
+#define BLE_GAP_ROLE_COUNT_CENTRAL_SEC_DEFAULT (1) /**< Default number of SMP instances shared between all connections acting as centrals. */
+#define BLE_GAP_ROLE_COUNT_COMBINED_MAX (20) /**< Maximum supported number of concurrent connections in the peripheral and central roles combined. */
+
+/**@} */
+
+/**@brief Automatic data length parameter. */
+#define BLE_GAP_DATA_LENGTH_AUTO 0
+
+/**@defgroup BLE_GAP_AUTH_PAYLOAD_TIMEOUT Authenticated payload timeout defines.
+ * @{ */
+#define BLE_GAP_AUTH_PAYLOAD_TIMEOUT_MAX (48000) /**< Maximum authenticated payload timeout in 10 ms units, i.e. 8 minutes. */
+#define BLE_GAP_AUTH_PAYLOAD_TIMEOUT_MIN (1) /**< Minimum authenticated payload timeout in 10 ms units, i.e. 10 ms. */
+/**@} */
+
+/**@defgroup GAP_SEC_MODES GAP Security Modes
+ * @{ */
+#define BLE_GAP_SEC_MODE 0x00 /**< No key (may be used to reject). */
+/**@} */
+
+/**@brief The total number of channels in Bluetooth Low Energy. */
+#define BLE_GAP_CHANNEL_COUNT (40)
+
+/**@defgroup BLE_GAP_QOS_CHANNEL_SURVEY_INTERVALS Quality of Service (QoS) Channel survey interval defines
+ * @{ */
+#define BLE_GAP_QOS_CHANNEL_SURVEY_INTERVAL_CONTINUOUS (0) /**< Continuous channel survey. */
+#define BLE_GAP_QOS_CHANNEL_SURVEY_INTERVAL_MIN_US (7500) /**< Minimum channel survey interval in microseconds (7.5 ms). */
+#define BLE_GAP_QOS_CHANNEL_SURVEY_INTERVAL_MAX_US (4000000) /**< Maximum channel survey interval in microseconds (4 s). */
+ /**@} */
+
+/** @} */
+
+
+/**@addtogroup BLE_GAP_STRUCTURES Structures
+ * @{ */
+
+/**@brief Advertising event properties. */
+typedef struct
+{
+ uint8_t type; /**< Advertising type. See @ref BLE_GAP_ADV_TYPES. */
+ uint8_t anonymous : 1; /**< Omit advertiser's address from all PDUs.
+ @note Anonymous advertising is only available for
+ @ref BLE_GAP_ADV_TYPE_EXTENDED_NONCONNECTABLE_NONSCANNABLE_UNDIRECTED and
+ @ref BLE_GAP_ADV_TYPE_EXTENDED_NONCONNECTABLE_NONSCANNABLE_DIRECTED. */
+ uint8_t include_tx_power : 1; /**< Include TxPower set by @ref sd_ble_gap_tx_power_set in the extended header
+ of the advertising PDU.
+ @note TxPower can only be added to the extended header when @ref type is an extended advertising type. */
+} ble_gap_adv_properties_t;
+
+
+/**@brief Advertising report type. */
+typedef struct
+{
+ uint16_t connectable : 1; /**< Connectable advertising event type. */
+ uint16_t scannable : 1; /**< Scannable advertising event type. */
+ uint16_t directed : 1; /**< Directed advertising event type. */
+ uint16_t scan_response : 1; /**< Received a scan response. */
+ uint16_t extended_pdu : 1; /**< Received an extended advertising set. */
+ uint16_t status : 2; /**< Data status. See @ref BLE_GAP_ADV_DATA_STATUS. */
+ uint16_t reserved : 9; /**< Reserved for future use. */
+} ble_gap_adv_report_type_t;
+
+/**@brief Advertising Auxiliary Pointer. */
+typedef struct
+{
+ uint16_t aux_offset; /**< Time offset from the beginning of advertising packet to the auxiliary packet in 100 us units. */
+ uint8_t aux_phy; /**< Indicates the PHY on which the auxiliary advertising packet is sent. See @ref BLE_GAP_PHYS. */
+} ble_gap_aux_pointer_t;
+
+/**@brief Bluetooth Low Energy address. */
+typedef struct
+{
+ uint8_t addr_id_peer : 1; /**< Only valid for peer addresses.
+ Reference to peer in device identities list (as set with @ref sd_ble_gap_device_identities_set) when peer is using privacy. */
+ uint8_t addr_type : 7; /**< See @ref BLE_GAP_ADDR_TYPES. */
+ uint8_t addr[BLE_GAP_ADDR_LEN]; /**< 48-bit address, LSB format.
+ addr is not used if addr_type is @ref BLE_GAP_ADDR_TYPE_ANONYMOUS. */
+} ble_gap_addr_t;
+
+
+/**@brief GAP connection parameters.
+ *
+ * @note When ble_conn_params_t is received in an event, both min_conn_interval and
+ * max_conn_interval will be equal to the connection interval set by the central.
+ *
+ * @note If both conn_sup_timeout and max_conn_interval are specified, then the following constraint applies:
+ * conn_sup_timeout * 4 > (1 + slave_latency) * max_conn_interval
+ * that corresponds to the following Bluetooth Spec requirement:
+ * The Supervision_Timeout in milliseconds shall be larger than
+ * (1 + Conn_Latency) * Conn_Interval_Max * 2, where Conn_Interval_Max is given in milliseconds.
+ */
+typedef struct
+{
+ uint16_t min_conn_interval; /**< Minimum Connection Interval in 1.25 ms units, see @ref BLE_GAP_CP_LIMITS.*/
+ uint16_t max_conn_interval; /**< Maximum Connection Interval in 1.25 ms units, see @ref BLE_GAP_CP_LIMITS.*/
+ uint16_t slave_latency; /**< Slave Latency in number of connection events, see @ref BLE_GAP_CP_LIMITS.*/
+ uint16_t conn_sup_timeout; /**< Connection Supervision Timeout in 10 ms units, see @ref BLE_GAP_CP_LIMITS.*/
+} ble_gap_conn_params_t;
+
+
+/**@brief GAP connection security modes.
+ *
+ * Security Mode 0 Level 0: No access permissions at all (this level is not defined by the Bluetooth Core specification).\n
+ * Security Mode 1 Level 1: No security is needed (aka open link).\n
+ * Security Mode 1 Level 2: Encrypted link required, MITM protection not necessary.\n
+ * Security Mode 1 Level 3: MITM protected encrypted link required.\n
+ * Security Mode 1 Level 4: LESC MITM protected encrypted link using a 128-bit strength encryption key required.\n
+ * Security Mode 2 Level 1: Signing or encryption required, MITM protection not necessary.\n
+ * Security Mode 2 Level 2: MITM protected signing required, unless link is MITM protected encrypted.\n
+ */
+typedef struct
+{
+ uint8_t sm : 4; /**< Security Mode (1 or 2), 0 for no permissions at all. */
+ uint8_t lv : 4; /**< Level (1, 2, 3 or 4), 0 for no permissions at all. */
+
+} ble_gap_conn_sec_mode_t;
+
+
+/**@brief GAP connection security status.*/
+typedef struct
+{
+ ble_gap_conn_sec_mode_t sec_mode; /**< Currently active security mode for this connection.*/
+ uint8_t encr_key_size; /**< Length of currently active encryption key, 7 to 16 octets (only applicable for bonding procedures). */
+} ble_gap_conn_sec_t;
+
+/**@brief Identity Resolving Key. */
+typedef struct
+{
+ uint8_t irk[BLE_GAP_SEC_KEY_LEN]; /**< Array containing IRK. */
+} ble_gap_irk_t;
+
+
+/**@brief Channel mask (40 bits).
+ * Every channel is represented with a bit positioned as per channel index defined in Bluetooth Core Specification v5.0,
+ * Vol 6, Part B, Section 1.4.1. The LSB contained in array element 0 represents channel index 0, and bit 39 represents
+ * channel index 39. If a bit is set to 1, the channel is not used.
+ */
+typedef uint8_t ble_gap_ch_mask_t[5];
+
+
+/**@brief GAP advertising parameters. */
+typedef struct
+{
+ ble_gap_adv_properties_t properties; /**< The properties of the advertising events. */
+ ble_gap_addr_t const *p_peer_addr; /**< Address of a known peer.
+ @note ble_gap_addr_t::addr_type cannot be
+ @ref BLE_GAP_ADDR_TYPE_ANONYMOUS.
+ - When privacy is enabled and the local device uses
+ @ref BLE_GAP_ADDR_TYPE_RANDOM_PRIVATE_RESOLVABLE addresses,
+ the device identity list is searched for a matching entry. If
+ the local IRK for that device identity is set, the local IRK
+ for that device will be used to generate the advertiser address
+ field in the advertising packet.
+ - If @ref ble_gap_adv_properties_t::type is directed, this must be
+ set to the targeted scanner or initiator. If the peer address is
+ in the device identity list, the peer IRK for that device will be
+ used to generate @ref BLE_GAP_ADDR_TYPE_RANDOM_PRIVATE_RESOLVABLE
+ target addresses used in the advertising event PDUs. */
+ uint32_t interval; /**< Advertising interval in 625 us units. @sa BLE_GAP_ADV_INTERVALS.
+ @note If @ref ble_gap_adv_properties_t::type is set to
+ @ref BLE_GAP_ADV_TYPE_CONNECTABLE_NONSCANNABLE_DIRECTED_HIGH_DUTY_CYCLE
+ advertising, this parameter is ignored. */
+ uint16_t duration; /**< Advertising duration in 10 ms units. When timeout is reached,
+ an event of type @ref BLE_GAP_EVT_ADV_SET_TERMINATED is raised.
+ @sa BLE_GAP_ADV_TIMEOUT_VALUES. */
+ uint8_t max_adv_evts; /**< Maximum advertising events that shall be sent prior to disabling
+ advertising. Setting the value to 0 disables the limitation. When
+ the count of advertising events specified by this parameter
+ (if not 0) is reached, advertising will be automatically stopped
+ and an event of type @ref BLE_GAP_EVT_ADV_SET_TERMINATED is raised
+ @note If @ref ble_gap_adv_properties_t::type is set to
+ @ref BLE_GAP_ADV_TYPE_CONNECTABLE_NONSCANNABLE_DIRECTED_HIGH_DUTY_CYCLE,
+ this parameter is ignored.
+ @note Setting max_adv_evts to a values not equal to 0 is only supported
+ as an experimental feature in this SoftDevice. */
+ ble_gap_ch_mask_t channel_mask; /**< Channel mask for primary and secondary advertising channels.
+ At least one of the primary channels, that is channel index 37-39, must be used.
+ Masking away secondary advertising channels is not supported. */
+ uint8_t filter_policy; /**< Filter Policy. @sa BLE_GAP_ADV_FILTER_POLICIES. */
+ uint8_t primary_phy; /**< Indicates the PHY on which the primary advertising channel packets
+ are transmitted. If set to @ref BLE_GAP_PHY_AUTO, @ref BLE_GAP_PHY_1MBPS
+ will be used.
+ Valid values are @ref BLE_GAP_PHY_1MBPS and @ref BLE_GAP_PHY_CODED.
+ @note The primary_phy shall indicate @ref BLE_GAP_PHY_1MBPS if
+ @ref ble_gap_adv_properties_t::type is not an extended advertising type. */
+ uint8_t secondary_phy; /**< Indicates the PHY on which the secondary advertising channel packets
+ are transmitted.
+ If set to @ref BLE_GAP_PHY_AUTO, @ref BLE_GAP_PHY_1MBPS will be used.
+ Valid values are
+ @ref BLE_GAP_PHY_1MBPS, @ref BLE_GAP_PHY_2MBPS, and @ref BLE_GAP_PHY_CODED.
+ If @ref ble_gap_adv_properties_t::type is an extended advertising type
+ and connectable, this is the PHY that will be used to establish a
+ connection and send AUX_ADV_IND packets on.
+ @note This parameter will be ignored when
+ @ref ble_gap_adv_properties_t::type is not an extended advertising type. */
+ uint8_t set_id:4; /**< The advertising set identifier distinguishes this advertising set from other
+ advertising sets transmitted by this and other devices.
+ @note This parameter will be ignored when
+ @ref ble_gap_adv_properties_t::type is not an extended advertising type. */
+ uint8_t scan_req_notification:1; /**< Enable scan request notifications for this advertising set. When a
+ scan request is received and the scanner address is allowed
+ by the filter policy, @ref BLE_GAP_EVT_SCAN_REQ_REPORT is raised.
+ @note This parameter will be ignored when
+ @ref ble_gap_adv_properties_t::type is a non-scannable
+ advertising type. */
+} ble_gap_adv_params_t;
+
+
+/**@brief GAP advertising data buffers.
+ *
+ * The application must provide the buffers for advertisement. The memory shall reside in application RAM, and
+ * shall never be modified while advertising. The data shall be kept alive until either:
+ * - @ref BLE_GAP_EVT_ADV_SET_TERMINATED is raised.
+ * - @ref BLE_GAP_EVT_CONNECTED is raised with @ref ble_gap_evt_connected_t::adv_handle set to the corresponding
+ * advertising handle.
+ * - Advertising is stopped.
+ * - Advertising data is changed.
+ * To update advertising data while advertising, provide new buffers to @ref sd_ble_gap_adv_set_configure. */
+typedef struct
+{
+ ble_data_t adv_data; /**< Advertising data.
+ @note
+ Advertising data can only be specified for a @ref ble_gap_adv_properties_t::type
+ that is allowed to contain advertising data. */
+ ble_data_t scan_rsp_data; /**< Scan response data.
+ @note
+ Scan response data can only be specified for a @ref ble_gap_adv_properties_t::type
+ that is scannable. */
+} ble_gap_adv_data_t;
+
+
+/**@brief GAP scanning parameters. */
+typedef struct
+{
+ uint8_t extended : 1; /**< If 1, the scanner will accept extended advertising packets.
+ If set to 0, the scanner will not receive advertising packets
+ on secondary advertising channels, and will not be able
+ to receive long advertising PDUs.
+ @note Extended scanning is only supported as an experimental feature in this
+ SoftDevice. */
+ uint8_t report_incomplete_evts : 1; /**< If 1, events of type @ref ble_gap_evt_adv_report_t may have
+ @ref ble_gap_adv_report_type_t::status set to
+ @ref BLE_GAP_ADV_DATA_STATUS_INCOMPLETE_MORE_DATA.
+ This parameter is ignored when used with @ref sd_ble_gap_connect
+ @note This may be used to abort receiving more packets from an extended
+ advertising event, and is only available for extended
+ scanning, see @ref sd_ble_gap_scan_start.
+ @note This feature is not supported by this SoftDevice. */
+ uint8_t active : 1; /**< If 1, perform active scanning by sending scan requests.
+ This parameter is ignored when used with @ref sd_ble_gap_connect. */
+ uint8_t filter_policy : 2; /**< Scanning filter policy. @sa BLE_GAP_SCAN_FILTER_POLICIES.
+ @note Only @ref BLE_GAP_SCAN_FP_ACCEPT_ALL and
+ @ref BLE_GAP_SCAN_FP_WHITELIST are valid when used with
+ @ref sd_ble_gap_connect */
+ uint8_t scan_phys; /**< Bitfield of PHYs to scan on. If set to @ref BLE_GAP_PHY_AUTO,
+ scan_phys will default to @ref BLE_GAP_PHY_1MBPS.
+ - If @ref ble_gap_scan_params_t::extended is set to 0, the only
+ supported PHY is @ref BLE_GAP_PHY_1MBPS.
+ - When used with @ref sd_ble_gap_scan_start,
+ the bitfield indicates the PHYs the scanner will use for scanning
+ on primary advertising channels. The scanner will accept
+ @ref BLE_GAP_PHYS_SUPPORTED as secondary advertising channel PHYs.
+ - When used with @ref sd_ble_gap_connect, the
+ bitfield indicates the PHYs on where a connection may be initiated.
+ If scan_phys contains @ref BLE_GAP_PHY_1MBPS and/or @ref BLE_GAP_PHY_2MBPS,
+ the primary scan PHY is @ref BLE_GAP_PHY_1MBPS.
+ If scan_phys also contains @ref BLE_GAP_PHY_CODED, the primary scan
+ PHY will also contain @ref BLE_GAP_PHY_CODED. If the only scan PHY is
+ @ref BLE_GAP_PHY_CODED, the primary scan PHY is
+ @ref BLE_GAP_PHY_CODED only. */
+ uint16_t interval; /**< Scan interval in 625 us units. @sa BLE_GAP_SCAN_INTERVALS. */
+ uint16_t window; /**< Scan window in 625 us units. @sa BLE_GAP_SCAN_WINDOW. */
+ uint16_t timeout; /**< Scan timeout in 10 ms units. @sa BLE_GAP_SCAN_TIMEOUT. */
+ ble_gap_ch_mask_t channel_mask; /**< Channel mask for primary and secondary advertising channels.
+ At least one of the primary channels, that is channel index 37-39, must be
+ set to 0.
+ Masking away secondary channels is not supported. */
+} ble_gap_scan_params_t;
+
+
+/**@brief Privacy.
+ *
+ * The privacy feature provides a way for the device to avoid being tracked over a period of time.
+ * The privacy feature, when enabled, hides the local device identity and replaces it with a private address
+ * that is automatically refreshed at a specified interval.
+ *
+ * If a device still wants to be recognized by other peers, it needs to share it's Identity Resolving Key (IRK).
+ * With this key, a device can generate a random private address that can only be recognized by peers in possession of that key,
+ * and devices can establish connections without revealing their real identities.
+ *
+ * Both network privacy (@ref BLE_GAP_PRIVACY_MODE_NETWORK_PRIVACY) and device privacy (@ref BLE_GAP_PRIVACY_MODE_DEVICE_PRIVACY)
+ * are supported.
+ *
+ * @note If the device IRK is updated, the new IRK becomes the one to be distributed in all
+ * bonding procedures performed after @ref sd_ble_gap_privacy_set returns.
+ * The IRK distributed during bonding procedure is the device IRK that is active when @ref sd_ble_gap_sec_params_reply is called.
+ */
+typedef struct
+{
+ uint8_t privacy_mode; /**< Privacy mode, see @ref BLE_GAP_PRIVACY_MODES. Default is @ref BLE_GAP_PRIVACY_MODE_OFF. */
+ uint8_t private_addr_type; /**< The private address type must be either @ref BLE_GAP_ADDR_TYPE_RANDOM_PRIVATE_RESOLVABLE or @ref BLE_GAP_ADDR_TYPE_RANDOM_PRIVATE_NON_RESOLVABLE. */
+ uint16_t private_addr_cycle_s; /**< Private address cycle interval in seconds. Providing an address cycle value of 0 will use the default value defined by @ref BLE_GAP_DEFAULT_PRIVATE_ADDR_CYCLE_INTERVAL_S. */
+ ble_gap_irk_t *p_device_irk; /**< When used as input, pointer to IRK structure that will be used as the default IRK. If NULL, the device default IRK will be used.
+ When used as output, pointer to IRK structure where the current default IRK will be written to. If NULL, this argument is ignored.
+ By default, the default IRK is used to generate random private resolvable addresses for the local device unless instructed otherwise. */
+} ble_gap_privacy_params_t;
+
+
+/**@brief PHY preferences for TX and RX
+ * @note tx_phys and rx_phys are bit fields. Multiple bits can be set in them to indicate multiple preferred PHYs for each direction.
+ * @code
+ * p_gap_phys->tx_phys = BLE_GAP_PHY_1MBPS | BLE_GAP_PHY_2MBPS;
+ * p_gap_phys->rx_phys = BLE_GAP_PHY_1MBPS | BLE_GAP_PHY_2MBPS;
+ * @endcode
+ *
+ */
+typedef struct
+{
+ uint8_t tx_phys; /**< Preferred transmit PHYs, see @ref BLE_GAP_PHYS. */
+ uint8_t rx_phys; /**< Preferred receive PHYs, see @ref BLE_GAP_PHYS. */
+} ble_gap_phys_t;
+
+/** @brief Keys that can be exchanged during a bonding procedure. */
+typedef struct
+{
+ uint8_t enc : 1; /**< Long Term Key and Master Identification. */
+ uint8_t id : 1; /**< Identity Resolving Key and Identity Address Information. */
+ uint8_t sign : 1; /**< Connection Signature Resolving Key. */
+ uint8_t link : 1; /**< Derive the Link Key from the LTK. */
+} ble_gap_sec_kdist_t;
+
+
+/**@brief GAP security parameters. */
+typedef struct
+{
+ uint8_t bond : 1; /**< Perform bonding. */
+ uint8_t mitm : 1; /**< Enable Man In The Middle protection. */
+ uint8_t lesc : 1; /**< Enable LE Secure Connection pairing. */
+ uint8_t keypress : 1; /**< Enable generation of keypress notifications. */
+ uint8_t io_caps : 3; /**< IO capabilities, see @ref BLE_GAP_IO_CAPS. */
+ uint8_t oob : 1; /**< The OOB data flag.
+ - In LE legacy pairing, this flag is set if a device has out of band authentication data.
+ The OOB method is used if both of the devices have out of band authentication data.
+ - In LE Secure Connections pairing, this flag is set if a device has the peer device's out of band authentication data.
+ The OOB method is used if at least one device has the peer device's OOB data available. */
+ uint8_t min_key_size; /**< Minimum encryption key size in octets between 7 and 16. If 0 then not applicable in this instance. */
+ uint8_t max_key_size; /**< Maximum encryption key size in octets between min_key_size and 16. */
+ ble_gap_sec_kdist_t kdist_own; /**< Key distribution bitmap: keys that the local device will distribute. */
+ ble_gap_sec_kdist_t kdist_peer; /**< Key distribution bitmap: keys that the remote device will distribute. */
+} ble_gap_sec_params_t;
+
+
+/**@brief GAP Encryption Information. */
+typedef struct
+{
+ uint8_t ltk[BLE_GAP_SEC_KEY_LEN]; /**< Long Term Key. */
+ uint8_t lesc : 1; /**< Key generated using LE Secure Connections. */
+ uint8_t auth : 1; /**< Authenticated Key. */
+ uint8_t ltk_len : 6; /**< LTK length in octets. */
+} ble_gap_enc_info_t;
+
+
+/**@brief GAP Master Identification. */
+typedef struct
+{
+ uint16_t ediv; /**< Encrypted Diversifier. */
+ uint8_t rand[BLE_GAP_SEC_RAND_LEN]; /**< Random Number. */
+} ble_gap_master_id_t;
+
+
+/**@brief GAP Signing Information. */
+typedef struct
+{
+ uint8_t csrk[BLE_GAP_SEC_KEY_LEN]; /**< Connection Signature Resolving Key. */
+} ble_gap_sign_info_t;
+
+
+/**@brief GAP LE Secure Connections P-256 Public Key. */
+typedef struct
+{
+ uint8_t pk[BLE_GAP_LESC_P256_PK_LEN]; /**< LE Secure Connections Elliptic Curve Diffie-Hellman P-256 Public Key. Stored in the standard SMP protocol format: {X,Y} both in little-endian. */
+} ble_gap_lesc_p256_pk_t;
+
+
+/**@brief GAP LE Secure Connections DHKey. */
+typedef struct
+{
+ uint8_t key[BLE_GAP_LESC_DHKEY_LEN]; /**< LE Secure Connections Elliptic Curve Diffie-Hellman Key. Stored in little-endian. */
+} ble_gap_lesc_dhkey_t;
+
+
+/**@brief GAP LE Secure Connections OOB data. */
+typedef struct
+{
+ ble_gap_addr_t addr; /**< Bluetooth address of the device. */
+ uint8_t r[BLE_GAP_SEC_KEY_LEN]; /**< Random Number. */
+ uint8_t c[BLE_GAP_SEC_KEY_LEN]; /**< Confirm Value. */
+} ble_gap_lesc_oob_data_t;
+
+
+/**@brief Event structure for @ref BLE_GAP_EVT_CONNECTED. */
+typedef struct
+{
+ ble_gap_addr_t peer_addr; /**< Bluetooth address of the peer device. If the peer_addr resolved: @ref ble_gap_addr_t::addr_id_peer is set to 1
+ and the address is the device's identity address. */
+ uint8_t role; /**< BLE role for this connection, see @ref BLE_GAP_ROLES */
+ ble_gap_conn_params_t conn_params; /**< GAP Connection Parameters. */
+ uint8_t adv_handle; /**< Advertising handle in which advertising has ended.
+ This variable is only set if role is set to @ref BLE_GAP_ROLE_PERIPH. */
+ ble_gap_adv_data_t adv_data; /**< Advertising buffers corresponding to the terminated
+ advertising set. The advertising buffers provided in
+ @ref sd_ble_gap_adv_set_configure are now released.
+ This variable is only set if role is set to @ref BLE_GAP_ROLE_PERIPH. */
+} ble_gap_evt_connected_t;
+
+
+/**@brief Event structure for @ref BLE_GAP_EVT_DISCONNECTED. */
+typedef struct
+{
+ uint8_t reason; /**< HCI error code, see @ref BLE_HCI_STATUS_CODES. */
+} ble_gap_evt_disconnected_t;
+
+
+/**@brief Event structure for @ref BLE_GAP_EVT_CONN_PARAM_UPDATE. */
+typedef struct
+{
+ ble_gap_conn_params_t conn_params; /**< GAP Connection Parameters. */
+} ble_gap_evt_conn_param_update_t;
+
+/**@brief Event structure for @ref BLE_GAP_EVT_PHY_UPDATE_REQUEST. */
+typedef struct
+{
+ ble_gap_phys_t peer_preferred_phys; /**< The PHYs the peer prefers to use. */
+} ble_gap_evt_phy_update_request_t;
+
+/**@brief Event Structure for @ref BLE_GAP_EVT_PHY_UPDATE. */
+typedef struct
+{
+ uint8_t status; /**< Status of the procedure, see @ref BLE_HCI_STATUS_CODES.*/
+ uint8_t tx_phy; /**< TX PHY for this connection, see @ref BLE_GAP_PHYS. */
+ uint8_t rx_phy; /**< RX PHY for this connection, see @ref BLE_GAP_PHYS. */
+} ble_gap_evt_phy_update_t;
+
+/**@brief Event structure for @ref BLE_GAP_EVT_SEC_PARAMS_REQUEST. */
+typedef struct
+{
+ ble_gap_sec_params_t peer_params; /**< Initiator Security Parameters. */
+} ble_gap_evt_sec_params_request_t;
+
+
+/**@brief Event structure for @ref BLE_GAP_EVT_SEC_INFO_REQUEST. */
+typedef struct
+{
+ ble_gap_addr_t peer_addr; /**< Bluetooth address of the peer device. */
+ ble_gap_master_id_t master_id; /**< Master Identification for LTK lookup. */
+ uint8_t enc_info : 1; /**< If 1, Encryption Information required. */
+ uint8_t id_info : 1; /**< If 1, Identity Information required. */
+ uint8_t sign_info : 1; /**< If 1, Signing Information required. */
+} ble_gap_evt_sec_info_request_t;
+
+
+/**@brief Event structure for @ref BLE_GAP_EVT_PASSKEY_DISPLAY. */
+typedef struct
+{
+ uint8_t passkey[BLE_GAP_PASSKEY_LEN]; /**< 6-digit passkey in ASCII ('0'-'9' digits only). */
+ uint8_t match_request : 1; /**< If 1 requires the application to report the match using @ref sd_ble_gap_auth_key_reply
+ with either @ref BLE_GAP_AUTH_KEY_TYPE_NONE if there is no match or
+ @ref BLE_GAP_AUTH_KEY_TYPE_PASSKEY if there is a match. */
+} ble_gap_evt_passkey_display_t;
+
+/**@brief Event structure for @ref BLE_GAP_EVT_KEY_PRESSED. */
+typedef struct
+{
+ uint8_t kp_not; /**< Keypress notification type, see @ref BLE_GAP_KP_NOT_TYPES. */
+} ble_gap_evt_key_pressed_t;
+
+
+/**@brief Event structure for @ref BLE_GAP_EVT_AUTH_KEY_REQUEST. */
+typedef struct
+{
+ uint8_t key_type; /**< See @ref BLE_GAP_AUTH_KEY_TYPES. */
+} ble_gap_evt_auth_key_request_t;
+
+/**@brief Event structure for @ref BLE_GAP_EVT_LESC_DHKEY_REQUEST. */
+typedef struct
+{
+ ble_gap_lesc_p256_pk_t *p_pk_peer; /**< LE Secure Connections remote P-256 Public Key. This will point to the application-supplied memory
+ inside the keyset during the call to @ref sd_ble_gap_sec_params_reply. */
+ uint8_t oobd_req :1; /**< LESC OOB data required. A call to @ref sd_ble_gap_lesc_oob_data_set is required to complete the procedure. */
+} ble_gap_evt_lesc_dhkey_request_t;
+
+
+/**@brief Security levels supported.
+ * @note See Bluetooth Specification Version 4.2 Volume 3, Part C, Chapter 10, Section 10.2.1.
+*/
+typedef struct
+{
+ uint8_t lv1 : 1; /**< If 1: Level 1 is supported. */
+ uint8_t lv2 : 1; /**< If 1: Level 2 is supported. */
+ uint8_t lv3 : 1; /**< If 1: Level 3 is supported. */
+ uint8_t lv4 : 1; /**< If 1: Level 4 is supported. */
+} ble_gap_sec_levels_t;
+
+
+/**@brief Encryption Key. */
+typedef struct
+{
+ ble_gap_enc_info_t enc_info; /**< Encryption Information. */
+ ble_gap_master_id_t master_id; /**< Master Identification. */
+} ble_gap_enc_key_t;
+
+
+/**@brief Identity Key. */
+typedef struct
+{
+ ble_gap_irk_t id_info; /**< Identity Resolving Key. */
+ ble_gap_addr_t id_addr_info; /**< Identity Address. */
+} ble_gap_id_key_t;
+
+
+/**@brief Security Keys. */
+typedef struct
+{
+ ble_gap_enc_key_t *p_enc_key; /**< Encryption Key, or NULL. */
+ ble_gap_id_key_t *p_id_key; /**< Identity Key, or NULL. */
+ ble_gap_sign_info_t *p_sign_key; /**< Signing Key, or NULL. */
+ ble_gap_lesc_p256_pk_t *p_pk; /**< LE Secure Connections P-256 Public Key. When in debug mode the application must use the value defined
+ in the Core Bluetooth Specification v4.2 Vol.3, Part H, Section 2.3.5.6.1 */
+} ble_gap_sec_keys_t;
+
+
+/**@brief Security key set for both local and peer keys. */
+typedef struct
+{
+ ble_gap_sec_keys_t keys_own; /**< Keys distributed by the local device. For LE Secure Connections the encryption key will be generated locally and will always be stored if bonding. */
+ ble_gap_sec_keys_t keys_peer; /**< Keys distributed by the remote device. For LE Secure Connections, p_enc_key must always be NULL. */
+} ble_gap_sec_keyset_t;
+
+
+/**@brief Data Length Update Procedure parameters. */
+typedef struct
+{
+ uint16_t max_tx_octets; /**< Maximum number of payload octets that a Controller supports for transmission of a single Link Layer Data Channel PDU. */
+ uint16_t max_rx_octets; /**< Maximum number of payload octets that a Controller supports for reception of a single Link Layer Data Channel PDU. */
+ uint16_t max_tx_time_us; /**< Maximum time, in microseconds, that a Controller supports for transmission of a single Link Layer Data Channel PDU. */
+ uint16_t max_rx_time_us; /**< Maximum time, in microseconds, that a Controller supports for reception of a single Link Layer Data Channel PDU. */
+} ble_gap_data_length_params_t;
+
+
+/**@brief Data Length Update Procedure local limitation. */
+typedef struct
+{
+ uint16_t tx_payload_limited_octets; /**< If > 0, the requested TX packet length is too long by this many octets. */
+ uint16_t rx_payload_limited_octets; /**< If > 0, the requested RX packet length is too long by this many octets. */
+ uint16_t tx_rx_time_limited_us; /**< If > 0, the requested combination of TX and RX packet lengths is too long by this many microseconds. */
+} ble_gap_data_length_limitation_t;
+
+
+/**@brief Event structure for @ref BLE_GAP_EVT_AUTH_STATUS. */
+typedef struct
+{
+ uint8_t auth_status; /**< Authentication status, see @ref BLE_GAP_SEC_STATUS. */
+ uint8_t error_src : 2; /**< On error, source that caused the failure, see @ref BLE_GAP_SEC_STATUS_SOURCES. */
+ uint8_t bonded : 1; /**< Procedure resulted in a bond. */
+ uint8_t lesc : 1; /**< Procedure resulted in a LE Secure Connection. */
+ ble_gap_sec_levels_t sm1_levels; /**< Levels supported in Security Mode 1. */
+ ble_gap_sec_levels_t sm2_levels; /**< Levels supported in Security Mode 2. */
+ ble_gap_sec_kdist_t kdist_own; /**< Bitmap stating which keys were exchanged (distributed) by the local device. If bonding with LE Secure Connections, the enc bit will be always set. */
+ ble_gap_sec_kdist_t kdist_peer; /**< Bitmap stating which keys were exchanged (distributed) by the remote device. If bonding with LE Secure Connections, the enc bit will never be set. */
+} ble_gap_evt_auth_status_t;
+
+
+/**@brief Event structure for @ref BLE_GAP_EVT_CONN_SEC_UPDATE. */
+typedef struct
+{
+ ble_gap_conn_sec_t conn_sec; /**< Connection security level. */
+} ble_gap_evt_conn_sec_update_t;
+
+
+/**@brief Event structure for @ref BLE_GAP_EVT_TIMEOUT. */
+typedef struct
+{
+ uint8_t src; /**< Source of timeout event, see @ref BLE_GAP_TIMEOUT_SOURCES. */
+ union
+ {
+ ble_data_t adv_report_buffer; /**< If source is set to @ref BLE_GAP_TIMEOUT_SRC_SCAN, the released
+ scan buffer is contained in this field. */
+ } params; /**< Event Parameters. */
+} ble_gap_evt_timeout_t;
+
+
+/**@brief Event structure for @ref BLE_GAP_EVT_RSSI_CHANGED. */
+typedef struct
+{
+ int8_t rssi; /**< Received Signal Strength Indication in dBm.
+ @note ERRATA-153 requires the rssi sample to be compensated based on a temperature measurement. */
+ uint8_t ch_index; /**< Data Channel Index on which the Signal Strength is measured (0-36). */
+} ble_gap_evt_rssi_changed_t;
+
+/**@brief Event structure for @ref BLE_GAP_EVT_ADV_SET_TERMINATED */
+typedef struct
+{
+ uint8_t reason; /**< Reason for why the advertising set terminated. See
+ @ref BLE_GAP_EVT_ADV_SET_TERMINATED_REASON. */
+ uint8_t adv_handle; /**< Advertising handle in which advertising has ended. */
+ uint8_t num_completed_adv_events; /**< If @ref ble_gap_adv_params_t::max_adv_evts was not set to 0,
+ this field indicates the number of completed advertising events. */
+ ble_gap_adv_data_t adv_data; /**< Advertising buffers corresponding to the terminated
+ advertising set. The advertising buffers provided in
+ @ref sd_ble_gap_adv_set_configure are now released. */
+} ble_gap_evt_adv_set_terminated_t;
+
+/**@brief Event structure for @ref BLE_GAP_EVT_ADV_REPORT.
+ *
+ * @note If @ref ble_gap_adv_report_type_t::status is set to @ref BLE_GAP_ADV_DATA_STATUS_INCOMPLETE_MORE_DATA,
+ * not all fields in the advertising report may be available.
+ *
+ * @note When ble_gap_adv_report_type_t::status is not set to @ref BLE_GAP_ADV_DATA_STATUS_INCOMPLETE_MORE_DATA,
+ * scanning will be paused. To continue scanning, call @ref sd_ble_gap_scan_start.
+ */
+typedef struct
+{
+ ble_gap_adv_report_type_t type; /**< Advertising report type. See @ref ble_gap_adv_report_type_t. */
+ ble_gap_addr_t peer_addr; /**< Bluetooth address of the peer device. If the peer_addr is resolved:
+ @ref ble_gap_addr_t::addr_id_peer is set to 1 and the address is the
+ peer's identity address. */
+ ble_gap_addr_t direct_addr; /**< Contains the target address of the advertising event if
+ @ref ble_gap_adv_report_type_t::directed is set to 1. If the
+ SoftDevice was able to resolve the address,
+ @ref ble_gap_addr_t::addr_id_peer is set to 1 and the direct_addr
+ contains the local identity address. If the target address of the
+ advertising event is @ref BLE_GAP_ADDR_TYPE_RANDOM_PRIVATE_RESOLVABLE,
+ and the SoftDevice was unable to resolve it, the application may try
+ to resolve this address to find out if the advertising event was
+ directed to us. */
+ uint8_t primary_phy; /**< Indicates the PHY on which the primary advertising packet was received on.
+ See @ref BLE_GAP_PHYS. */
+ uint8_t secondary_phy; /**< Indicates the PHY on which the secondary advertising packet was received on.
+ See @ref BLE_GAP_PHYS. This field is to 0 if no packets where received on
+ a secondary advertising channel. */
+ int8_t tx_power; /**< TX Power reported by the advertiser in the last packet header received.
+ This field is set to @ref BLE_GAP_POWER_LEVEL_INVALID if the
+ last received packet did not contain the Tx Power field.
+ @note TX Power is only included in extended advertising packets. */
+ int8_t rssi; /**< Received Signal Strength Indication in dBm of the last packet received.
+ @note ERRATA-153 requires the rssi sample to be compensated based on a temperature measurement. */
+ uint8_t ch_index; /**< Channel Index on which the last advertising packet is received (0-39). */
+ uint8_t set_id; /**< Set ID of the received advertising data. Set ID is not present
+ if set to @ref BLE_GAP_ADV_REPORT_SET_ID_NOT_AVAILABLE. */
+ uint16_t data_id:12; /**< The advertising data ID of the received advertising data. Data ID
+ is not present if @ref ble_gap_evt_adv_report_t::set_id is set to
+ @ref BLE_GAP_ADV_REPORT_SET_ID_NOT_AVAILABLE. */
+ ble_data_t data; /**< Received advertising or scan response data. If
+ @ref ble_gap_adv_report_type_t::status is not set to
+ @ref BLE_GAP_ADV_DATA_STATUS_INCOMPLETE_MORE_DATA, the data buffer provided
+ in @ref sd_ble_gap_scan_start is now released. */
+ ble_gap_aux_pointer_t aux_pointer; /**< The offset and PHY of the next advertising packet in this extended advertising
+ event. @note This field is only set if @ref ble_gap_adv_report_type_t::status
+ is set to @ref BLE_GAP_ADV_DATA_STATUS_INCOMPLETE_MORE_DATA. */
+} ble_gap_evt_adv_report_t;
+
+
+/**@brief Event structure for @ref BLE_GAP_EVT_SEC_REQUEST. */
+typedef struct
+{
+ uint8_t bond : 1; /**< Perform bonding. */
+ uint8_t mitm : 1; /**< Man In The Middle protection requested. */
+ uint8_t lesc : 1; /**< LE Secure Connections requested. */
+ uint8_t keypress : 1; /**< Generation of keypress notifications requested. */
+} ble_gap_evt_sec_request_t;
+
+
+/**@brief Event structure for @ref BLE_GAP_EVT_CONN_PARAM_UPDATE_REQUEST. */
+typedef struct
+{
+ ble_gap_conn_params_t conn_params; /**< GAP Connection Parameters. */
+} ble_gap_evt_conn_param_update_request_t;
+
+
+/**@brief Event structure for @ref BLE_GAP_EVT_SCAN_REQ_REPORT. */
+typedef struct
+{
+ uint8_t adv_handle; /**< Advertising handle for the advertising set which received the Scan Request */
+ int8_t rssi; /**< Received Signal Strength Indication in dBm.
+ @note ERRATA-153 requires the rssi sample to be compensated based on a temperature measurement. */
+ ble_gap_addr_t peer_addr; /**< Bluetooth address of the peer device. If the peer_addr resolved: @ref ble_gap_addr_t::addr_id_peer is set to 1
+ and the address is the device's identity address. */
+} ble_gap_evt_scan_req_report_t;
+
+
+/**@brief Event structure for @ref BLE_GAP_EVT_DATA_LENGTH_UPDATE_REQUEST. */
+typedef struct
+{
+ ble_gap_data_length_params_t peer_params; /**< Peer data length parameters. */
+} ble_gap_evt_data_length_update_request_t;
+
+/**@brief Event structure for @ref BLE_GAP_EVT_DATA_LENGTH_UPDATE. */
+typedef struct
+{
+ ble_gap_data_length_params_t effective_params; /**< The effective data length parameters. */
+} ble_gap_evt_data_length_update_t;
+
+
+/**@brief Event structure for @ref BLE_GAP_EVT_QOS_CHANNEL_SURVEY_REPORT. */
+typedef struct
+{
+ int8_t channel_energy[BLE_GAP_CHANNEL_COUNT]; /**< The measured energy on the Bluetooth Low Energy
+ channels, in dBm, indexed by Channel Index.
+ If no measurement is available for the given channel, channel_energy is set to
+ @ref BLE_GAP_POWER_LEVEL_INVALID. */
+} ble_gap_evt_qos_channel_survey_report_t;
+
+/**@brief GAP event structure. */
+typedef struct
+{
+ uint16_t conn_handle; /**< Connection Handle on which event occurred. */
+ union /**< union alternative identified by evt_id in enclosing struct. */
+ {
+ ble_gap_evt_connected_t connected; /**< Connected Event Parameters. */
+ ble_gap_evt_disconnected_t disconnected; /**< Disconnected Event Parameters. */
+ ble_gap_evt_conn_param_update_t conn_param_update; /**< Connection Parameter Update Parameters. */
+ ble_gap_evt_sec_params_request_t sec_params_request; /**< Security Parameters Request Event Parameters. */
+ ble_gap_evt_sec_info_request_t sec_info_request; /**< Security Information Request Event Parameters. */
+ ble_gap_evt_passkey_display_t passkey_display; /**< Passkey Display Event Parameters. */
+ ble_gap_evt_key_pressed_t key_pressed; /**< Key Pressed Event Parameters. */
+ ble_gap_evt_auth_key_request_t auth_key_request; /**< Authentication Key Request Event Parameters. */
+ ble_gap_evt_lesc_dhkey_request_t lesc_dhkey_request; /**< LE Secure Connections DHKey calculation request. */
+ ble_gap_evt_auth_status_t auth_status; /**< Authentication Status Event Parameters. */
+ ble_gap_evt_conn_sec_update_t conn_sec_update; /**< Connection Security Update Event Parameters. */
+ ble_gap_evt_timeout_t timeout; /**< Timeout Event Parameters. */
+ ble_gap_evt_rssi_changed_t rssi_changed; /**< RSSI Event Parameters. */
+ ble_gap_evt_adv_report_t adv_report; /**< Advertising Report Event Parameters. */
+ ble_gap_evt_adv_set_terminated_t adv_set_terminated; /**< Advertising Set Terminated Event Parameters. */
+ ble_gap_evt_sec_request_t sec_request; /**< Security Request Event Parameters. */
+ ble_gap_evt_conn_param_update_request_t conn_param_update_request; /**< Connection Parameter Update Parameters. */
+ ble_gap_evt_scan_req_report_t scan_req_report; /**< Scan Request Report Parameters. */
+ ble_gap_evt_phy_update_request_t phy_update_request; /**< PHY Update Request Event Parameters. */
+ ble_gap_evt_phy_update_t phy_update; /**< PHY Update Parameters. */
+ ble_gap_evt_data_length_update_request_t data_length_update_request; /**< Data Length Update Request Event Parameters. */
+ ble_gap_evt_data_length_update_t data_length_update; /**< Data Length Update Event Parameters. */
+ ble_gap_evt_qos_channel_survey_report_t qos_channel_survey_report; /**< Quality of Service (QoS) Channel Survey Report Parameters. */
+ } params; /**< Event Parameters. */
+} ble_gap_evt_t;
+
+
+/**
+ * @brief BLE GAP connection configuration parameters, set with @ref sd_ble_cfg_set.
+ *
+ * @retval ::NRF_ERROR_CONN_COUNT The connection count for the connection configurations is zero.
+ * @retval ::NRF_ERROR_INVALID_PARAM One or more of the following is true:
+ * - The sum of conn_count for all connection configurations combined exceeds UINT8_MAX.
+ * - The event length is smaller than @ref BLE_GAP_EVENT_LENGTH_MIN.
+ */
+typedef struct
+{
+ uint8_t conn_count; /**< The number of concurrent connections the application can create with this configuration.
+ The default and minimum value is @ref BLE_GAP_CONN_COUNT_DEFAULT. */
+ uint16_t event_length; /**< The time set aside for this connection on every connection interval in 1.25 ms units.
+ The default value is @ref BLE_GAP_EVENT_LENGTH_DEFAULT, the minimum value is @ref BLE_GAP_EVENT_LENGTH_MIN.
+ The event length and the connection interval are the primary parameters
+ for setting the throughput of a connection.
+ See the SoftDevice Specification for details on throughput. */
+} ble_gap_conn_cfg_t;
+
+
+/**
+ * @brief Configuration of maximum concurrent connections in the different connected roles, set with
+ * @ref sd_ble_cfg_set.
+ *
+ * @retval ::NRF_ERROR_CONN_COUNT The sum of periph_role_count and central_role_count is too
+ * large. The maximum supported sum of concurrent connections is
+ * @ref BLE_GAP_ROLE_COUNT_COMBINED_MAX.
+ * @retval ::NRF_ERROR_INVALID_PARAM central_sec_count is larger than central_role_count.
+ * @retval ::NRF_ERROR_RESOURCES The adv_set_count is too large. The maximum
+ * supported advertising handles is
+ * @ref BLE_GAP_ADV_SET_COUNT_MAX.
+ */
+typedef struct
+{
+ uint8_t adv_set_count; /**< Maximum number of advertising sets. Default value is @ref BLE_GAP_ADV_SET_COUNT_DEFAULT. */
+ uint8_t periph_role_count; /**< Maximum number of connections concurrently acting as a peripheral. Default value is @ref BLE_GAP_ROLE_COUNT_PERIPH_DEFAULT. */
+ uint8_t central_role_count; /**< Maximum number of connections concurrently acting as a central. Default value is @ref BLE_GAP_ROLE_COUNT_CENTRAL_DEFAULT. */
+ uint8_t central_sec_count; /**< Number of SMP instances shared between all connections acting as a central. Default value is @ref BLE_GAP_ROLE_COUNT_CENTRAL_SEC_DEFAULT. */
+ uint8_t qos_channel_survey_role_available:1; /**< If set, the Quality of Service (QoS) channel survey module is available to the
+ application using @ref sd_ble_gap_qos_channel_survey_start. */
+} ble_gap_cfg_role_count_t;
+
+
+/**
+ * @brief Device name and its properties, set with @ref sd_ble_cfg_set.
+ *
+ * @note If the device name is not configured, the default device name will be
+ * @ref BLE_GAP_DEVNAME_DEFAULT, the maximum device name length will be
+ * @ref BLE_GAP_DEVNAME_DEFAULT_LEN, vloc will be set to @ref BLE_GATTS_VLOC_STACK and the device name
+ * will have no write access.
+ *
+ * @note If @ref max_len is more than @ref BLE_GAP_DEVNAME_DEFAULT_LEN and vloc is set to @ref BLE_GATTS_VLOC_STACK,
+ * the attribute table size must be increased to have room for the longer device name (see
+ * @ref sd_ble_cfg_set and @ref ble_gatts_cfg_attr_tab_size_t).
+ *
+ * @note If vloc is @ref BLE_GATTS_VLOC_STACK :
+ * - p_value must point to non-volatile memory (flash) or be NULL.
+ * - If p_value is NULL, the device name will initially be empty.
+ *
+ * @note If vloc is @ref BLE_GATTS_VLOC_USER :
+ * - p_value cannot be NULL.
+ * - If the device name is writable, p_value must point to volatile memory (RAM).
+ *
+ * @retval ::NRF_ERROR_INVALID_PARAM One or more of the following is true:
+ * - Invalid device name location (vloc).
+ * - Invalid device name security mode.
+ * @retval ::NRF_ERROR_INVALID_LENGTH One or more of the following is true:
+ * - The device name length is invalid (must be between 0 and @ref BLE_GAP_DEVNAME_MAX_LEN).
+ * - The device name length is too long for the given Attribute Table.
+ * @retval ::NRF_ERROR_NOT_SUPPORTED Device name security mode is not supported.
+ */
+typedef struct
+{
+ ble_gap_conn_sec_mode_t write_perm; /**< Write permissions. */
+ uint8_t vloc:2; /**< Value location, see @ref BLE_GATTS_VLOCS.*/
+ uint8_t *p_value; /**< Pointer to where the value (device name) is stored or will be stored. */
+ uint16_t current_len; /**< Current length in bytes of the memory pointed to by p_value.*/
+ uint16_t max_len; /**< Maximum length in bytes of the memory pointed to by p_value.*/
+} ble_gap_cfg_device_name_t;
+
+
+/**@brief Configuration structure for GAP configurations. */
+typedef union
+{
+ ble_gap_cfg_role_count_t role_count_cfg; /**< Role count configuration, cfg_id is @ref BLE_GAP_CFG_ROLE_COUNT. */
+ ble_gap_cfg_device_name_t device_name_cfg; /**< Device name configuration, cfg_id is @ref BLE_GAP_CFG_DEVICE_NAME. */
+} ble_gap_cfg_t;
+
+
+/**@brief Channel Map option.
+ *
+ * @details Used with @ref sd_ble_opt_get to get the current channel map
+ * or @ref sd_ble_opt_set to set a new channel map. When setting the
+ * channel map, it applies to all current and future connections. When getting the
+ * current channel map, it applies to a single connection and the connection handle
+ * must be supplied.
+ *
+ * @note Setting the channel map may take some time, depending on connection parameters.
+ * The time taken may be different for each connection and the get operation will
+ * return the previous channel map until the new one has taken effect.
+ *
+ * @note After setting the channel map, by spec it can not be set again until at least 1 s has passed.
+ * See Bluetooth Specification Version 4.1 Volume 2, Part E, Section 7.3.46.
+ *
+ * @retval ::NRF_SUCCESS Get or set successful.
+ * @retval ::NRF_ERROR_INVALID_PARAM One or more of the following is true:
+ * - Less then two bits in @ref ch_map are set.
+ * - Bits for primary advertising channels (37-39) are set.
+ * @retval ::NRF_ERROR_BUSY Channel map was set again before enough time had passed.
+ * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid connection handle supplied for get.
+ *
+ */
+typedef struct
+{
+ uint16_t conn_handle; /**< Connection Handle (only applicable for get) */
+ uint8_t ch_map[5]; /**< Channel Map (37-bit). */
+} ble_gap_opt_ch_map_t;
+
+
+/**@brief Local connection latency option.
+ *
+ * @details Local connection latency is a feature which enables the slave to improve
+ * current consumption by ignoring the slave latency set by the peer. The
+ * local connection latency can only be set to a multiple of the slave latency,
+ * and cannot be longer than half of the supervision timeout.
+ *
+ * @details Used with @ref sd_ble_opt_set to set the local connection latency. The
+ * @ref sd_ble_opt_get is not supported for this option, but the actual
+ * local connection latency (unless set to NULL) is set as a return parameter
+ * when setting the option.
+ *
+ * @note The latency set will be truncated down to the closest slave latency event
+ * multiple, or the nearest multiple before half of the supervision timeout.
+ *
+ * @note The local connection latency is disabled by default, and needs to be enabled for new
+ * connections and whenever the connection is updated.
+ *
+ * @retval ::NRF_SUCCESS Set successfully.
+ * @retval ::NRF_ERROR_NOT_SUPPORTED Get is not supported.
+ * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid connection handle parameter.
+ */
+typedef struct
+{
+ uint16_t conn_handle; /**< Connection Handle */
+ uint16_t requested_latency; /**< Requested local connection latency. */
+ uint16_t * p_actual_latency; /**< Pointer to storage for the actual local connection latency (can be set to NULL to skip return value). */
+} ble_gap_opt_local_conn_latency_t;
+
+/**@brief Disable slave latency
+ *
+ * @details Used with @ref sd_ble_opt_set to temporarily disable slave latency of a peripheral connection
+ * (see @ref ble_gap_conn_params_t::slave_latency). And to re-enable it again. When disabled, the
+ * peripheral will ignore the slave_latency set by the central.
+ *
+ * @note Shall only be called on peripheral links.
+ *
+ * @retval ::NRF_SUCCESS Set successfully.
+ * @retval ::NRF_ERROR_NOT_SUPPORTED Get is not supported.
+ * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid connection handle parameter.
+ */
+typedef struct
+{
+ uint16_t conn_handle; /**< Connection Handle */
+ uint8_t disable : 1; /**< Set to 1 to disable slave latency. Set to 0 enable it again.*/
+} ble_gap_opt_slave_latency_disable_t;
+
+/**@brief Passkey Option.
+ *
+ * @details Structure containing the passkey to be used during pairing. This can be used with @ref
+ * sd_ble_opt_set to make the SoftDevice use a preprogrammed passkey for authentication
+ * instead of generating a random one.
+ *
+ * @note Repeated pairing attempts using the same preprogrammed passkey makes pairing vulnerable to MITM attacks.
+ *
+ * @note @ref sd_ble_opt_get is not supported for this option.
+ *
+ */
+typedef struct
+{
+ uint8_t const * p_passkey; /**< Pointer to 6-digit ASCII string (digit 0..9 only, no NULL termination) passkey to be used during pairing. If this is NULL, the SoftDevice will generate a random passkey if required.*/
+} ble_gap_opt_passkey_t;
+
+
+/**@brief Compatibility mode 1 option.
+ *
+ * @details This can be used with @ref sd_ble_opt_set to enable and disable
+ * compatibility mode 1. Compatibility mode 1 is disabled by default.
+ *
+ * @note Compatibility mode 1 enables interoperability with devices that do not support a value of
+ * 0 for the WinOffset parameter in the Link Layer CONNECT_IND packet. This applies to a
+ * limited set of legacy peripheral devices from another vendor. Enabling this compatibility
+ * mode will only have an effect if the local device will act as a central device and
+ * initiate a connection to a peripheral device. In that case it may lead to the connection
+ * creation taking up to one connection interval longer to complete for all connections.
+ *
+ * @retval ::NRF_SUCCESS Set successfully.
+ * @retval ::NRF_ERROR_INVALID_STATE When connection creation is ongoing while mode 1 is set.
+ */
+typedef struct
+{
+ uint8_t enable : 1; /**< Enable compatibility mode 1.*/
+} ble_gap_opt_compat_mode_1_t;
+
+
+/**@brief Authenticated payload timeout option.
+ *
+ * @details This can be used with @ref sd_ble_opt_set to change the Authenticated payload timeout to a value other
+ * than the default of @ref BLE_GAP_AUTH_PAYLOAD_TIMEOUT_MAX.
+ *
+ * @note The authenticated payload timeout event ::BLE_GAP_TIMEOUT_SRC_AUTH_PAYLOAD will be generated
+ * if auth_payload_timeout time has elapsed without receiving a packet with a valid MIC on an encrypted
+ * link.
+ *
+ * @note The LE ping procedure will be initiated before the timer expires to give the peer a chance
+ * to reset the timer. In addition the stack will try to prioritize running of LE ping over other
+ * activities to increase chances of finishing LE ping before timer expires. To avoid side-effects
+ * on other activities, it is recommended to use high timeout values.
+ * Recommended timeout > 2*(connInterval * (6 + connSlaveLatency)).
+ *
+ * @retval ::NRF_SUCCESS Set successfully.
+ * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied. auth_payload_timeout was outside of allowed range.
+ * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid connection handle parameter.
+ */
+typedef struct
+{
+ uint16_t conn_handle; /**< Connection Handle */
+ uint16_t auth_payload_timeout; /**< Requested timeout in 10 ms unit, see @ref BLE_GAP_AUTH_PAYLOAD_TIMEOUT. */
+} ble_gap_opt_auth_payload_timeout_t;
+
+/**@brief Option structure for GAP options. */
+typedef union
+{
+ ble_gap_opt_ch_map_t ch_map; /**< Parameters for the Channel Map option. */
+ ble_gap_opt_local_conn_latency_t local_conn_latency; /**< Parameters for the Local connection latency option */
+ ble_gap_opt_passkey_t passkey; /**< Parameters for the Passkey option.*/
+ ble_gap_opt_compat_mode_1_t compat_mode_1; /**< Parameters for the compatibility mode 1 option.*/
+ ble_gap_opt_auth_payload_timeout_t auth_payload_timeout; /**< Parameters for the authenticated payload timeout option.*/
+ ble_gap_opt_slave_latency_disable_t slave_latency_disable; /**< Parameters for the Disable slave latency option */
+} ble_gap_opt_t;
+/**@} */
+
+
+/**@addtogroup BLE_GAP_FUNCTIONS Functions
+ * @{ */
+
+/**@brief Set the local Bluetooth identity address.
+ *
+ * The local Bluetooth identity address is the address that identifies this device to other peers.
+ * The address type must be either @ref BLE_GAP_ADDR_TYPE_PUBLIC or @ref BLE_GAP_ADDR_TYPE_RANDOM_STATIC.
+ *
+ * @note The identity address cannot be changed while advertising, scanning or creating a connection.
+ *
+ * @note This address will be distributed to the peer during bonding.
+ * If the address changes, the address stored in the peer device will not be valid and the ability to
+ * reconnect using the old address will be lost.
+ *
+ * @note By default the SoftDevice will set an address of type @ref BLE_GAP_ADDR_TYPE_RANDOM_STATIC upon being
+ * enabled. The address is a random number populated during the IC manufacturing process and remains unchanged
+ * for the lifetime of each IC.
+ *
+ * @mscs
+ * @mmsc{@ref BLE_GAP_ADV_MSC}
+ * @endmscs
+ *
+ * @param[in] p_addr Pointer to address structure.
+ *
+ * @retval ::NRF_SUCCESS Address successfully set.
+ * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied.
+ * @retval ::BLE_ERROR_GAP_INVALID_BLE_ADDR Invalid address.
+ * @retval ::NRF_ERROR_BUSY The stack is busy, process pending events and retry.
+ * @retval ::NRF_ERROR_INVALID_STATE The identity address cannot be changed while advertising,
+ * scanning or creating a connection.
+ */
+SVCALL(SD_BLE_GAP_ADDR_SET, uint32_t, sd_ble_gap_addr_set(ble_gap_addr_t const *p_addr));
+
+
+/**@brief Get local Bluetooth identity address.
+ *
+ * @note This will always return the identity address irrespective of the privacy settings,
+ * i.e. the address type will always be either @ref BLE_GAP_ADDR_TYPE_PUBLIC or @ref BLE_GAP_ADDR_TYPE_RANDOM_STATIC.
+ *
+ * @param[out] p_addr Pointer to address structure to be filled in.
+ *
+ * @retval ::NRF_SUCCESS Address successfully retrieved.
+ * @retval ::NRF_ERROR_INVALID_ADDR Invalid or NULL pointer supplied.
+ */
+SVCALL(SD_BLE_GAP_ADDR_GET, uint32_t, sd_ble_gap_addr_get(ble_gap_addr_t *p_addr));
+
+
+/**@brief Set the active whitelist in the SoftDevice.
+ *
+ * @note Only one whitelist can be used at a time and the whitelist is shared between the BLE roles.
+ * The whitelist cannot be set if a BLE role is using the whitelist.
+ *
+ * @note If an address is resolved using the information in the device identity list, then the whitelist
+ * filter policy applies to the peer identity address and not the resolvable address sent on air.
+ *
+ * @mscs
+ * @mmsc{@ref BLE_GAP_WL_SHARE_MSC}
+ * @mmsc{@ref BLE_GAP_PRIVACY_SCAN_PRIVATE_SCAN_MSC}
+ * @endmscs
+ *
+ * @param[in] pp_wl_addrs Pointer to a whitelist of peer addresses, if NULL the whitelist will be cleared.
+ * @param[in] len Length of the whitelist, maximum @ref BLE_GAP_WHITELIST_ADDR_MAX_COUNT.
+ *
+ * @retval ::NRF_SUCCESS The whitelist is successfully set/cleared.
+ * @retval ::NRF_ERROR_INVALID_ADDR The whitelist (or one of its entries) provided is invalid.
+ * @retval ::BLE_ERROR_GAP_WHITELIST_IN_USE The whitelist is in use by a BLE role and cannot be set or cleared.
+ * @retval ::BLE_ERROR_GAP_INVALID_BLE_ADDR Invalid address type is supplied.
+ * @retval ::NRF_ERROR_DATA_SIZE The given whitelist size is invalid (zero or too large); this can only return when
+ * pp_wl_addrs is not NULL.
+ */
+SVCALL(SD_BLE_GAP_WHITELIST_SET, uint32_t, sd_ble_gap_whitelist_set(ble_gap_addr_t const * const * pp_wl_addrs, uint8_t len));
+
+
+/**@brief Set device identity list.
+ *
+ * @note Only one device identity list can be used at a time and the list is shared between the BLE roles.
+ * The device identity list cannot be set if a BLE role is using the list.
+ *
+ * @param[in] pp_id_keys Pointer to an array of peer identity addresses and peer IRKs, if NULL the device identity list will be cleared.
+ * @param[in] pp_local_irks Pointer to an array of local IRKs. Each entry in the array maps to the entry in pp_id_keys at the same index.
+ * To fill in the list with the currently set device IRK for all peers, set to NULL.
+ * @param[in] len Length of the device identity list, maximum @ref BLE_GAP_DEVICE_IDENTITIES_MAX_COUNT.
+ *
+ * @mscs
+ * @mmsc{@ref BLE_GAP_PRIVACY_ADV_MSC}
+ * @mmsc{@ref BLE_GAP_PRIVACY_SCAN_MSC}
+ * @mmsc{@ref BLE_GAP_PRIVACY_SCAN_PRIVATE_SCAN_MSC}
+ * @mmsc{@ref BLE_GAP_PRIVACY_ADV_DIR_PRIV_MSC}
+ * @mmsc{@ref BLE_GAP_PERIPH_CONN_PRIV_MSC}
+ * @mmsc{@ref BLE_GAP_CENTRAL_CONN_PRIV_MSC}
+ * @endmscs
+ *
+ * @retval ::NRF_SUCCESS The device identity list successfully set/cleared.
+ * @retval ::NRF_ERROR_INVALID_ADDR The device identity list (or one of its entries) provided is invalid.
+ * This code may be returned if the local IRK list also has an invalid entry.
+ * @retval ::BLE_ERROR_GAP_DEVICE_IDENTITIES_IN_USE The device identity list is in use and cannot be set or cleared.
+ * @retval ::BLE_ERROR_GAP_DEVICE_IDENTITIES_DUPLICATE The device identity list contains multiple entries with the same identity address.
+ * @retval ::BLE_ERROR_GAP_INVALID_BLE_ADDR Invalid address type is supplied.
+ * @retval ::NRF_ERROR_DATA_SIZE The given device identity list size invalid (zero or too large); this can
+ * only return when pp_id_keys is not NULL.
+ */
+SVCALL(SD_BLE_GAP_DEVICE_IDENTITIES_SET, uint32_t, sd_ble_gap_device_identities_set(ble_gap_id_key_t const * const * pp_id_keys, ble_gap_irk_t const * const * pp_local_irks, uint8_t len));
+
+
+/**@brief Set privacy settings.
+ *
+ * @note Privacy settings cannot be changed while advertising, scanning or creating a connection.
+ *
+ * @param[in] p_privacy_params Privacy settings.
+ *
+ * @mscs
+ * @mmsc{@ref BLE_GAP_PRIVACY_ADV_MSC}
+ * @mmsc{@ref BLE_GAP_PRIVACY_SCAN_MSC}
+ * @mmsc{@ref BLE_GAP_PRIVACY_ADV_DIR_PRIV_MSC}
+ * @endmscs
+ *
+ * @retval ::NRF_SUCCESS Set successfully.
+ * @retval ::NRF_ERROR_BUSY The stack is busy, process pending events and retry.
+ * @retval ::BLE_ERROR_GAP_INVALID_BLE_ADDR Invalid address type is supplied.
+ * @retval ::NRF_ERROR_INVALID_ADDR The pointer to privacy settings is NULL or invalid.
+ * Otherwise, the p_device_irk pointer in privacy parameter is an invalid pointer.
+ * @retval ::NRF_ERROR_INVALID_PARAM Out of range parameters are provided.
+ * @retval ::NRF_ERROR_INVALID_STATE Privacy settings cannot be changed while advertising, scanning
+ * or creating a connection.
+ */
+SVCALL(SD_BLE_GAP_PRIVACY_SET, uint32_t, sd_ble_gap_privacy_set(ble_gap_privacy_params_t const *p_privacy_params));
+
+
+/**@brief Get privacy settings.
+ *
+ * @note ::ble_gap_privacy_params_t::p_device_irk must be initialized to NULL or a valid address before this function is called.
+ * If it is initialized to a valid address, the address pointed to will contain the current device IRK on return.
+ *
+ * @param[in,out] p_privacy_params Privacy settings.
+ *
+ * @retval ::NRF_SUCCESS Privacy settings read.
+ * @retval ::NRF_ERROR_INVALID_ADDR The pointer given for returning the privacy settings may be NULL or invalid.
+ * Otherwise, the p_device_irk pointer in privacy parameter is an invalid pointer.
+ */
+SVCALL(SD_BLE_GAP_PRIVACY_GET, uint32_t, sd_ble_gap_privacy_get(ble_gap_privacy_params_t *p_privacy_params));
+
+
+/**@brief Configure an advertising set. Set, clear or update advertising and scan response data.
+ *
+ * @note The format of the advertising data will be checked by this call to ensure interoperability.
+ * Limitations imposed by this API call to the data provided include having a flags data type in the scan response data and
+ * duplicating the local name in the advertising data and scan response data.
+ *
+ * @note In order to update advertising data while advertising, new advertising buffers must be provided.
+ *
+ * @mscs
+ * @mmsc{@ref BLE_GAP_ADV_MSC}
+ * @mmsc{@ref BLE_GAP_WL_SHARE_MSC}
+ * @endmscs
+ *
+ * @param[in,out] p_adv_handle Provide a pointer to a handle containing @ref BLE_GAP_ADV_SET_HANDLE_NOT_SET to configure
+ * a new advertising set. On success, a new handle is then returned through the pointer.
+ * Provide a pointer to an existing advertising handle to configure an existing advertising set.
+ * @param[in] p_adv_data Advertising data. If set to NULL, no advertising data will be used. See @ref ble_gap_adv_data_t.
+ * @param[in] p_adv_params Advertising parameters. When this function is used to update advertising data while advertising,
+ * this parameter must be NULL. See @ref ble_gap_adv_params_t.
+ *
+ * @retval ::NRF_SUCCESS Advertising set successfully configured.
+ * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied:
+ * - Invalid advertising data configuration specified. See @ref ble_gap_adv_data_t.
+ * - Invalid configuration of p_adv_params. See @ref ble_gap_adv_params_t.
+ * - Use of whitelist requested but whitelist has not been set,
+ * see @ref sd_ble_gap_whitelist_set.
+ * @retval ::BLE_ERROR_GAP_INVALID_BLE_ADDR ble_gap_adv_params_t::p_peer_addr is invalid.
+ * @retval ::NRF_ERROR_INVALID_STATE Invalid state to perform operation.
+ * - It is invalid to provide non-NULL advertising set parameters while advertising.
+ * - It is invalid to provide the same data buffers while advertising. To update
+ * advertising data, provide new advertising buffers.
+ * @retval ::BLE_ERROR_GAP_DISCOVERABLE_WITH_WHITELIST Discoverable mode and whitelist incompatible.
+ * @retval ::BLE_ERROR_INVALID_ADV_HANDLE The provided advertising handle was not found. Use @ref BLE_GAP_ADV_SET_HANDLE_NOT_SET to
+ * configure a new advertising handle.
+ * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied.
+ * @retval ::NRF_ERROR_INVALID_FLAGS Invalid combination of advertising flags supplied.
+ * @retval ::NRF_ERROR_INVALID_DATA Invalid data type(s) supplied. Check the advertising data format specification
+ * given in Bluetooth Specification Version 5.0, Volume 3, Part C, Chapter 11.
+ * @retval ::NRF_ERROR_INVALID_LENGTH Invalid data length(s) supplied.
+ * @retval ::NRF_ERROR_NOT_SUPPORTED Unsupported data length or advertising parameter configuration.
+ * @retval ::NRF_ERROR_NO_MEM Not enough memory to configure a new advertising handle. Update an
+ * existing advertising handle instead.
+ * @retval ::BLE_ERROR_GAP_UUID_LIST_MISMATCH Invalid UUID list supplied.
+ */
+SVCALL(SD_BLE_GAP_ADV_SET_CONFIGURE, uint32_t, sd_ble_gap_adv_set_configure(uint8_t *p_adv_handle, ble_gap_adv_data_t const *p_adv_data, ble_gap_adv_params_t const *p_adv_params));
+
+
+/**@brief Start advertising (GAP Discoverable, Connectable modes, Broadcast Procedure).
+ *
+ * @note Only one advertiser may be active at any time.
+ *
+ * @events
+ * @event{@ref BLE_GAP_EVT_CONNECTED, Generated after connection has been established through connectable advertising.}
+ * @event{@ref BLE_GAP_EVT_ADV_SET_TERMINATED, Advertising set has terminated.}
+ * @event{@ref BLE_GAP_EVT_SCAN_REQ_REPORT, A scan request was received.}
+ * @endevents
+ *
+ * @mscs
+ * @mmsc{@ref BLE_GAP_ADV_MSC}
+ * @mmsc{@ref BLE_GAP_PERIPH_CONN_PRIV_MSC}
+ * @mmsc{@ref BLE_GAP_PRIVACY_ADV_DIR_PRIV_MSC}
+ * @mmsc{@ref BLE_GAP_WL_SHARE_MSC}
+ * @endmscs
+ *
+ * @param[in] adv_handle Advertising handle to advertise on, received from @ref sd_ble_gap_adv_set_configure.
+ * @param[in] conn_cfg_tag Tag identifying a configuration set by @ref sd_ble_cfg_set or
+ * @ref BLE_CONN_CFG_TAG_DEFAULT to use the default connection configuration. For non-connectable
+ * advertising, this is ignored.
+ *
+ * @retval ::NRF_SUCCESS The BLE stack has started advertising.
+ * @retval ::NRF_ERROR_INVALID_STATE Invalid state to perform operation. adv_handle is not configured or already advertising.
+ * @retval ::NRF_ERROR_CONN_COUNT The limit of available connections has been reached; connectable advertiser cannot be started.
+ * @retval ::BLE_ERROR_INVALID_ADV_HANDLE Advertising handle not found. Configure a new adveriting handle with @ref sd_ble_gap_adv_set_configure.
+ * @retval ::NRF_ERROR_NOT_FOUND conn_cfg_tag not found.
+ * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied:
+ * - Invalid configuration of p_adv_params. See @ref ble_gap_adv_params_t.
+ * - Use of whitelist requested but whitelist has not been set, see @ref sd_ble_gap_whitelist_set.
+ * @retval ::NRF_ERROR_RESOURCES Either:
+ * - adv_handle is configured with connectable advertising, but the event_length parameter
+ * associated with conn_cfg_tag is too small to be able to establish a connection on
+ * the selected advertising phys. Use @ref sd_ble_cfg_set to increase the event length.
+ * - Not enough BLE role slots available.
+ Stop one or more currently active roles (Central, Peripheral, Broadcaster or Observer) and try again.
+ * - p_adv_params is configured with connectable advertising, but the event_length parameter
+ * associated with conn_cfg_tag is too small to be able to establish a connection on
+ * the selected advertising phys. Use @ref sd_ble_cfg_set to increase the event length.
+ */
+SVCALL(SD_BLE_GAP_ADV_START, uint32_t, sd_ble_gap_adv_start(uint8_t adv_handle, uint8_t conn_cfg_tag));
+
+
+/**@brief Stop advertising (GAP Discoverable, Connectable modes, Broadcast Procedure).
+ *
+ * @mscs
+ * @mmsc{@ref BLE_GAP_ADV_MSC}
+ * @mmsc{@ref BLE_GAP_WL_SHARE_MSC}
+ * @endmscs
+ *
+ * @param[in] adv_handle The advertising handle that should stop advertising.
+ *
+ * @retval ::NRF_SUCCESS The BLE stack has stopped advertising.
+ * @retval ::BLE_ERROR_INVALID_ADV_HANDLE Invalid advertising handle.
+ * @retval ::NRF_ERROR_INVALID_STATE The advertising handle is not advertising.
+ */
+SVCALL(SD_BLE_GAP_ADV_STOP, uint32_t, sd_ble_gap_adv_stop(uint8_t adv_handle));
+
+
+
+/**@brief Update connection parameters.
+ *
+ * @details In the central role this will initiate a Link Layer connection parameter update procedure,
+ * otherwise in the peripheral role, this will send the corresponding L2CAP request and wait for
+ * the central to perform the procedure. In both cases, and regardless of success or failure, the application
+ * will be informed of the result with a @ref BLE_GAP_EVT_CONN_PARAM_UPDATE event.
+ *
+ * @details This function can be used as a central both to reply to a @ref BLE_GAP_EVT_CONN_PARAM_UPDATE_REQUEST or to start the procedure unrequested.
+ *
+ * @events
+ * @event{@ref BLE_GAP_EVT_CONN_PARAM_UPDATE, Result of the connection parameter update procedure.}
+ * @endevents
+ *
+ * @mscs
+ * @mmsc{@ref BLE_GAP_CPU_MSC}
+ * @mmsc{@ref BLE_GAP_CENTRAL_ENC_AUTH_MUTEX_MSC}
+ * @mmsc{@ref BLE_GAP_MULTILINK_CPU_MSC}
+ * @mmsc{@ref BLE_GAP_MULTILINK_CTRL_PROC_MSC}
+ * @mmsc{@ref BLE_GAP_CENTRAL_CPU_MSC}
+ * @endmscs
+ *
+ * @param[in] conn_handle Connection handle.
+ * @param[in] p_conn_params Pointer to desired connection parameters. If NULL is provided on a peripheral role,
+ * the parameters in the PPCP characteristic of the GAP service will be used instead.
+ * If NULL is provided on a central role and in response to a @ref BLE_GAP_EVT_CONN_PARAM_UPDATE_REQUEST, the peripheral request will be rejected
+ *
+ * @retval ::NRF_SUCCESS The Connection Update procedure has been started successfully.
+ * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied.
+ * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied, check parameter limits and constraints.
+ * @retval ::NRF_ERROR_INVALID_STATE Invalid state to perform operation.
+ * @retval ::NRF_ERROR_BUSY Procedure already in progress, wait for pending procedures to complete and retry.
+ * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid connection handle supplied.
+ * @retval ::NRF_ERROR_NO_MEM Not enough memory to complete operation.
+ */
+SVCALL(SD_BLE_GAP_CONN_PARAM_UPDATE, uint32_t, sd_ble_gap_conn_param_update(uint16_t conn_handle, ble_gap_conn_params_t const *p_conn_params));
+
+
+/**@brief Disconnect (GAP Link Termination).
+ *
+ * @details This call initiates the disconnection procedure, and its completion will be communicated to the application
+ * with a @ref BLE_GAP_EVT_DISCONNECTED event.
+ *
+ * @events
+ * @event{@ref BLE_GAP_EVT_DISCONNECTED, Generated when disconnection procedure is complete.}
+ * @endevents
+ *
+ * @mscs
+ * @mmsc{@ref BLE_GAP_CONN_MSC}
+ * @endmscs
+ *
+ * @param[in] conn_handle Connection handle.
+ * @param[in] hci_status_code HCI status code, see @ref BLE_HCI_STATUS_CODES (accepted values are @ref BLE_HCI_REMOTE_USER_TERMINATED_CONNECTION and @ref BLE_HCI_CONN_INTERVAL_UNACCEPTABLE).
+ *
+ * @retval ::NRF_SUCCESS The disconnection procedure has been started successfully.
+ * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied.
+ * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid connection handle supplied.
+ * @retval ::NRF_ERROR_INVALID_STATE Invalid state to perform operation (disconnection is already in progress).
+ */
+SVCALL(SD_BLE_GAP_DISCONNECT, uint32_t, sd_ble_gap_disconnect(uint16_t conn_handle, uint8_t hci_status_code));
+
+
+/**@brief Set the radio's transmit power.
+ *
+ * @param[in] role The role to set the transmit power for, see @ref BLE_GAP_TX_POWER_ROLES for
+ * possible roles.
+ * @param[in] handle The handle parameter is interpreted depending on role:
+ * - If role is @ref BLE_GAP_TX_POWER_ROLE_CONN, this value is the specific connection handle.
+ * - If role is @ref BLE_GAP_TX_POWER_ROLE_ADV, the advertising set identified with the advertising handle,
+ * will use the specified transmit power, and include it in the advertising packet headers if
+ * @ref ble_gap_adv_properties_t::include_tx_power set.
+ * - For all other roles handle is ignored.
+ * @param[in] tx_power Radio transmit power in dBm (see note for accepted values).
+ *
+ * @note Supported tx_power values: -40dBm, -20dBm, -16dBm, -12dBm, -8dBm, -4dBm, 0dBm, +2dBm, +3dBm, +4dBm, +5dBm, +6dBm, +7dBm and +8dBm.
+ * @note The initiator will have the same transmit power as the scanner.
+ * @note When a connection is created it will inherit the transmit power from the initiator or
+ * advertiser leading to the connection.
+ *
+ * @retval ::NRF_SUCCESS Successfully changed the transmit power.
+ * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied.
+ * @retval ::BLE_ERROR_INVALID_ADV_HANDLE Advertising handle not found.
+ * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid connection handle supplied.
+ */
+SVCALL(SD_BLE_GAP_TX_POWER_SET, uint32_t, sd_ble_gap_tx_power_set(uint8_t role, uint16_t handle, int8_t tx_power));
+
+
+/**@brief Set GAP Appearance value.
+ *
+ * @param[in] appearance Appearance (16-bit), see @ref BLE_APPEARANCES.
+ *
+ * @retval ::NRF_SUCCESS Appearance value set successfully.
+ * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied.
+ */
+SVCALL(SD_BLE_GAP_APPEARANCE_SET, uint32_t, sd_ble_gap_appearance_set(uint16_t appearance));
+
+
+/**@brief Get GAP Appearance value.
+ *
+ * @param[out] p_appearance Pointer to appearance (16-bit) to be filled in, see @ref BLE_APPEARANCES.
+ *
+ * @retval ::NRF_SUCCESS Appearance value retrieved successfully.
+ * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied.
+ */
+SVCALL(SD_BLE_GAP_APPEARANCE_GET, uint32_t, sd_ble_gap_appearance_get(uint16_t *p_appearance));
+
+
+/**@brief Set GAP Peripheral Preferred Connection Parameters.
+ *
+ * @param[in] p_conn_params Pointer to a @ref ble_gap_conn_params_t structure with the desired parameters.
+ *
+ * @retval ::NRF_SUCCESS Peripheral Preferred Connection Parameters set successfully.
+ * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied.
+ * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied.
+ */
+SVCALL(SD_BLE_GAP_PPCP_SET, uint32_t, sd_ble_gap_ppcp_set(ble_gap_conn_params_t const *p_conn_params));
+
+
+/**@brief Get GAP Peripheral Preferred Connection Parameters.
+ *
+ * @param[out] p_conn_params Pointer to a @ref ble_gap_conn_params_t structure where the parameters will be stored.
+ *
+ * @retval ::NRF_SUCCESS Peripheral Preferred Connection Parameters retrieved successfully.
+ * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied.
+ */
+SVCALL(SD_BLE_GAP_PPCP_GET, uint32_t, sd_ble_gap_ppcp_get(ble_gap_conn_params_t *p_conn_params));
+
+
+/**@brief Set GAP device name.
+ *
+ * @note If the device name is located in application flash memory (see @ref ble_gap_cfg_device_name_t),
+ * it cannot be changed. Then @ref NRF_ERROR_FORBIDDEN will be returned.
+ *
+ * @param[in] p_write_perm Write permissions for the Device Name characteristic, see @ref ble_gap_conn_sec_mode_t.
+ * @param[in] p_dev_name Pointer to a UTF-8 encoded, <b>non NULL-terminated</b> string.
+ * @param[in] len Length of the UTF-8, <b>non NULL-terminated</b> string pointed to by p_dev_name in octets (must be smaller or equal than @ref BLE_GAP_DEVNAME_MAX_LEN).
+ *
+ * @retval ::NRF_SUCCESS GAP device name and permissions set successfully.
+ * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied.
+ * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied.
+ * @retval ::NRF_ERROR_DATA_SIZE Invalid data size(s) supplied.
+ * @retval ::NRF_ERROR_FORBIDDEN Device name is not writable.
+ */
+SVCALL(SD_BLE_GAP_DEVICE_NAME_SET, uint32_t, sd_ble_gap_device_name_set(ble_gap_conn_sec_mode_t const *p_write_perm, uint8_t const *p_dev_name, uint16_t len));
+
+
+/**@brief Get GAP device name.
+ *
+ * @note If the device name is longer than the size of the supplied buffer,
+ * p_len will return the complete device name length,
+ * and not the number of bytes actually returned in p_dev_name.
+ * The application may use this information to allocate a suitable buffer size.
+ *
+ * @param[out] p_dev_name Pointer to an empty buffer where the UTF-8 <b>non NULL-terminated</b> string will be placed. Set to NULL to obtain the complete device name length.
+ * @param[in,out] p_len Length of the buffer pointed by p_dev_name, complete device name length on output.
+ *
+ * @retval ::NRF_SUCCESS GAP device name retrieved successfully.
+ * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied.
+ * @retval ::NRF_ERROR_DATA_SIZE Invalid data size(s) supplied.
+ */
+SVCALL(SD_BLE_GAP_DEVICE_NAME_GET, uint32_t, sd_ble_gap_device_name_get(uint8_t *p_dev_name, uint16_t *p_len));
+
+
+/**@brief Initiate the GAP Authentication procedure.
+ *
+ * @details In the central role, this function will send an SMP Pairing Request (or an SMP Pairing Failed if rejected),
+ * otherwise in the peripheral role, an SMP Security Request will be sent.
+ *
+ * @events
+ * @event{Depending on the security parameters set and the packet exchanges with the peer\, the following events may be generated:}
+ * @event{@ref BLE_GAP_EVT_SEC_PARAMS_REQUEST}
+ * @event{@ref BLE_GAP_EVT_SEC_INFO_REQUEST}
+ * @event{@ref BLE_GAP_EVT_PASSKEY_DISPLAY}
+ * @event{@ref BLE_GAP_EVT_KEY_PRESSED}
+ * @event{@ref BLE_GAP_EVT_AUTH_KEY_REQUEST}
+ * @event{@ref BLE_GAP_EVT_LESC_DHKEY_REQUEST}
+ * @event{@ref BLE_GAP_EVT_CONN_SEC_UPDATE}
+ * @event{@ref BLE_GAP_EVT_AUTH_STATUS}
+ * @event{@ref BLE_GAP_EVT_TIMEOUT}
+ * @endevents
+ *
+ * @mscs
+ * @mmsc{@ref BLE_GAP_PERIPH_SEC_REQ_MSC}
+ * @mmsc{@ref BLE_GAP_CENTRAL_SEC_REQ_MSC}
+ * @mmsc{@ref BLE_GAP_CENTRAL_ENC_AUTH_MUTEX_MSC}
+ * @mmsc{@ref BLE_GAP_CENTRAL_PAIRING_JW_MSC}
+ * @mmsc{@ref BLE_GAP_CENTRAL_BONDING_JW_MSC}
+ * @mmsc{@ref BLE_GAP_CENTRAL_BONDING_PK_PERIPH_MSC}
+ * @mmsc{@ref BLE_GAP_CENTRAL_BONDING_PK_PERIPH_OOB_MSC}
+ * @mmsc{@ref BLE_GAP_CENTRAL_LESC_PAIRING_JW_MSC}
+ * @mmsc{@ref BLE_GAP_CENTRAL_LESC_BONDING_NC_MSC}
+ * @mmsc{@ref BLE_GAP_CENTRAL_LESC_BONDING_PKE_PD_MSC}
+ * @mmsc{@ref BLE_GAP_CENTRAL_LESC_BONDING_PKE_CD_MSC}
+ * @mmsc{@ref BLE_GAP_CENTRAL_LESC_BONDING_OOB_MSC}
+ * @endmscs
+ *
+ * @param[in] conn_handle Connection handle.
+ * @param[in] p_sec_params Pointer to the @ref ble_gap_sec_params_t structure with the security parameters to be used during the pairing or bonding procedure.
+ * In the peripheral role, only the bond, mitm, lesc and keypress fields of this structure are used.
+ * In the central role, this pointer may be NULL to reject a Security Request.
+ *
+ * @retval ::NRF_SUCCESS Successfully initiated authentication procedure.
+ * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied.
+ * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied.
+ * @retval ::NRF_ERROR_INVALID_STATE Invalid state to perform operation.
+ * @retval ::NRF_ERROR_NO_MEM The maximum number of authentication procedures that can run in parallel for the given role is reached.
+ * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid connection handle supplied.
+ * @retval ::NRF_ERROR_NOT_SUPPORTED Setting of sign or link fields in @ref ble_gap_sec_kdist_t not supported.
+ * @retval ::NRF_ERROR_TIMEOUT A SMP timeout has occurred, and further SMP operations on this link is prohibited.
+ */
+SVCALL(SD_BLE_GAP_AUTHENTICATE, uint32_t, sd_ble_gap_authenticate(uint16_t conn_handle, ble_gap_sec_params_t const *p_sec_params));
+
+
+/**@brief Reply with GAP security parameters.
+ *
+ * @details This function is only used to reply to a @ref BLE_GAP_EVT_SEC_PARAMS_REQUEST, calling it at other times will result in an @ref NRF_ERROR_INVALID_STATE.
+ * @note If the call returns an error code, the request is still pending, and the reply call may be repeated with corrected parameters.
+ *
+ * @events
+ * @event{This function is used during authentication procedures\, see the list of events in the documentation of @ref sd_ble_gap_authenticate.}
+ * @endevents
+ *
+ * @mscs
+ * @mmsc{@ref BLE_GAP_PERIPH_PAIRING_JW_MSC}
+ * @mmsc{@ref BLE_GAP_PERIPH_BONDING_JW_MSC}
+ * @mmsc{@ref BLE_GAP_PERIPH_BONDING_PK_PERIPH_MSC}
+ * @mmsc{@ref BLE_GAP_PERIPH_BONDING_PK_CENTRAL_OOB_MSC}
+ * @mmsc{@ref BLE_GAP_PERIPH_BONDING_STATIC_PK_MSC}
+ * @mmsc{@ref BLE_GAP_PERIPH_PAIRING_CONFIRM_FAIL_MSC}
+ * @mmsc{@ref BLE_GAP_PERIPH_LESC_PAIRING_JW_MSC}
+ * @mmsc{@ref BLE_GAP_PERIPH_LESC_BONDING_NC_MSC}
+ * @mmsc{@ref BLE_GAP_PERIPH_LESC_BONDING_PKE_PD_MSC}
+ * @mmsc{@ref BLE_GAP_PERIPH_LESC_BONDING_PKE_CD_MSC}
+ * @mmsc{@ref BLE_GAP_PERIPH_LESC_BONDING_OOB_MSC}
+ * @mmsc{@ref BLE_GAP_PERIPH_PAIRING_KS_TOO_SMALL_MSC}
+ * @mmsc{@ref BLE_GAP_PERIPH_PAIRING_APP_ERROR_MSC}
+ * @mmsc{@ref BLE_GAP_PERIPH_PAIRING_REMOTE_PAIRING_FAIL_MSC}
+ * @mmsc{@ref BLE_GAP_PERIPH_PAIRING_TIMEOUT_MSC}
+ * @mmsc{@ref BLE_GAP_CENTRAL_PAIRING_JW_MSC}
+ * @mmsc{@ref BLE_GAP_CENTRAL_BONDING_JW_MSC}
+ * @mmsc{@ref BLE_GAP_CENTRAL_BONDING_PK_PERIPH_MSC}
+ * @mmsc{@ref BLE_GAP_CENTRAL_BONDING_PK_PERIPH_OOB_MSC}
+ * @mmsc{@ref BLE_GAP_CENTRAL_LESC_PAIRING_JW_MSC}
+ * @mmsc{@ref BLE_GAP_CENTRAL_LESC_BONDING_NC_MSC}
+ * @mmsc{@ref BLE_GAP_CENTRAL_LESC_BONDING_PKE_PD_MSC}
+ * @mmsc{@ref BLE_GAP_CENTRAL_LESC_BONDING_PKE_CD_MSC}
+ * @mmsc{@ref BLE_GAP_CENTRAL_LESC_BONDING_OOB_MSC}
+ * @endmscs
+ *
+ * @param[in] conn_handle Connection handle.
+ * @param[in] sec_status Security status, see @ref BLE_GAP_SEC_STATUS.
+ * @param[in] p_sec_params Pointer to a @ref ble_gap_sec_params_t security parameters structure. In the central role this must be set to NULL, as the parameters have
+ * already been provided during a previous call to @ref sd_ble_gap_authenticate.
+ * @param[in,out] p_sec_keyset Pointer to a @ref ble_gap_sec_keyset_t security keyset structure. Any keys generated and/or distributed as a result of the ongoing security procedure
+ * will be stored into the memory referenced by the pointers inside this structure. The keys will be stored and available to the application
+ * upon reception of a @ref BLE_GAP_EVT_AUTH_STATUS event.
+ * Note that the SoftDevice expects the application to provide memory for storing the
+ * peer's keys. So it must be ensured that the relevant pointers inside this structure are not NULL. The pointers to the local key
+ * can, however, be NULL, in which case, the local key data will not be available to the application upon reception of the
+ * @ref BLE_GAP_EVT_AUTH_STATUS event.
+ *
+ * @retval ::NRF_SUCCESS Successfully accepted security parameter from the application.
+ * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied.
+ * @retval ::NRF_ERROR_BUSY The stack is busy, process pending events and retry.
+ * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied.
+ * @retval ::NRF_ERROR_INVALID_STATE Invalid state to perform operation.
+ * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid connection handle supplied.
+ * @retval ::NRF_ERROR_NOT_SUPPORTED Setting of sign or link fields in @ref ble_gap_sec_kdist_t not supported.
+ */
+SVCALL(SD_BLE_GAP_SEC_PARAMS_REPLY, uint32_t, sd_ble_gap_sec_params_reply(uint16_t conn_handle, uint8_t sec_status, ble_gap_sec_params_t const *p_sec_params, ble_gap_sec_keyset_t const *p_sec_keyset));
+
+
+/**@brief Reply with an authentication key.
+ *
+ * @details This function is only used to reply to a @ref BLE_GAP_EVT_AUTH_KEY_REQUEST or a @ref BLE_GAP_EVT_PASSKEY_DISPLAY, calling it at other times will result in an @ref NRF_ERROR_INVALID_STATE.
+ * @note If the call returns an error code, the request is still pending, and the reply call may be repeated with corrected parameters.
+ *
+ * @events
+ * @event{This function is used during authentication procedures\, see the list of events in the documentation of @ref sd_ble_gap_authenticate.}
+ * @endevents
+ *
+ * @mscs
+ * @mmsc{@ref BLE_GAP_PERIPH_BONDING_PK_CENTRAL_OOB_MSC}
+ * @mmsc{@ref BLE_GAP_PERIPH_LESC_BONDING_NC_MSC}
+ * @mmsc{@ref BLE_GAP_PERIPH_LESC_BONDING_PKE_CD_MSC}
+ * @mmsc{@ref BLE_GAP_CENTRAL_BONDING_PK_PERIPH_OOB_MSC}
+ * @mmsc{@ref BLE_GAP_CENTRAL_LESC_BONDING_NC_MSC}
+ * @mmsc{@ref BLE_GAP_CENTRAL_LESC_BONDING_PKE_CD_MSC}
+ * @endmscs
+ *
+ * @param[in] conn_handle Connection handle.
+ * @param[in] key_type See @ref BLE_GAP_AUTH_KEY_TYPES.
+ * @param[in] p_key If key type is @ref BLE_GAP_AUTH_KEY_TYPE_NONE, then NULL.
+ * If key type is @ref BLE_GAP_AUTH_KEY_TYPE_PASSKEY, then a 6-byte ASCII string (digit 0..9 only, no NULL termination)
+ * or NULL when confirming LE Secure Connections Numeric Comparison.
+ * If key type is @ref BLE_GAP_AUTH_KEY_TYPE_OOB, then a 16-byte OOB key value in little-endian format.
+ *
+ * @retval ::NRF_SUCCESS Authentication key successfully set.
+ * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied.
+ * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied.
+ * @retval ::NRF_ERROR_INVALID_STATE Invalid state to perform operation.
+ * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid connection handle supplied.
+ */
+SVCALL(SD_BLE_GAP_AUTH_KEY_REPLY, uint32_t, sd_ble_gap_auth_key_reply(uint16_t conn_handle, uint8_t key_type, uint8_t const *p_key));
+
+
+/**@brief Reply with an LE Secure connections DHKey.
+ *
+ * @details This function is only used to reply to a @ref BLE_GAP_EVT_LESC_DHKEY_REQUEST, calling it at other times will result in an @ref NRF_ERROR_INVALID_STATE.
+ * @note If the call returns an error code, the request is still pending, and the reply call may be repeated with corrected parameters.
+ *
+ * @events
+ * @event{This function is used during authentication procedures\, see the list of events in the documentation of @ref sd_ble_gap_authenticate.}
+ * @endevents
+ *
+ * @mscs
+ * @mmsc{@ref BLE_GAP_PERIPH_LESC_PAIRING_JW_MSC}
+ * @mmsc{@ref BLE_GAP_PERIPH_LESC_BONDING_NC_MSC}
+ * @mmsc{@ref BLE_GAP_PERIPH_LESC_BONDING_PKE_PD_MSC}
+ * @mmsc{@ref BLE_GAP_PERIPH_LESC_BONDING_PKE_CD_MSC}
+ * @mmsc{@ref BLE_GAP_PERIPH_LESC_BONDING_OOB_MSC}
+ * @mmsc{@ref BLE_GAP_CENTRAL_LESC_PAIRING_JW_MSC}
+ * @mmsc{@ref BLE_GAP_CENTRAL_LESC_BONDING_NC_MSC}
+ * @mmsc{@ref BLE_GAP_CENTRAL_LESC_BONDING_PKE_PD_MSC}
+ * @mmsc{@ref BLE_GAP_CENTRAL_LESC_BONDING_PKE_CD_MSC}
+ * @mmsc{@ref BLE_GAP_CENTRAL_LESC_BONDING_OOB_MSC}
+ * @endmscs
+ *
+ * @param[in] conn_handle Connection handle.
+ * @param[in] p_dhkey LE Secure Connections DHKey.
+ *
+ * @retval ::NRF_SUCCESS DHKey successfully set.
+ * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied.
+ * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied.
+ * @retval ::NRF_ERROR_INVALID_STATE Invalid state to perform operation.
+ * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid connection handle supplied.
+ */
+SVCALL(SD_BLE_GAP_LESC_DHKEY_REPLY, uint32_t, sd_ble_gap_lesc_dhkey_reply(uint16_t conn_handle, ble_gap_lesc_dhkey_t const *p_dhkey));
+
+
+/**@brief Notify the peer of a local keypress.
+ *
+ * @mscs
+ * @mmsc{@ref BLE_GAP_PERIPH_LESC_BONDING_PKE_CD_MSC}
+ * @mmsc{@ref BLE_GAP_CENTRAL_LESC_BONDING_PKE_CD_MSC}
+ * @endmscs
+ *
+ * @param[in] conn_handle Connection handle.
+ * @param[in] kp_not See @ref BLE_GAP_KP_NOT_TYPES.
+ *
+ * @retval ::NRF_SUCCESS Keypress notification successfully queued for transmission.
+ * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied.
+ * @retval ::NRF_ERROR_INVALID_STATE Invalid state to perform operation. Either not entering a passkey or keypresses have not been enabled by both peers.
+ * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid connection handle supplied.
+ * @retval ::NRF_ERROR_BUSY The BLE stack is busy. Retry at later time.
+ */
+SVCALL(SD_BLE_GAP_KEYPRESS_NOTIFY, uint32_t, sd_ble_gap_keypress_notify(uint16_t conn_handle, uint8_t kp_not));
+
+
+/**@brief Generate a set of OOB data to send to a peer out of band.
+ *
+ * @note The @ref ble_gap_addr_t included in the OOB data returned will be the currently active one (or, if a connection has already been established,
+ * the one used during connection setup). The application may manually overwrite it with an updated value.
+ *
+ * @mscs
+ * @mmsc{@ref BLE_GAP_PERIPH_LESC_BONDING_OOB_MSC}
+ * @mmsc{@ref BLE_GAP_CENTRAL_LESC_BONDING_OOB_MSC}
+ * @endmscs
+ *
+ * @param[in] conn_handle Connection handle. Can be @ref BLE_CONN_HANDLE_INVALID if a BLE connection has not been established yet.
+ * @param[in] p_pk_own LE Secure Connections local P-256 Public Key.
+ * @param[out] p_oobd_own The OOB data to be sent out of band to a peer.
+ *
+ * @retval ::NRF_SUCCESS OOB data successfully generated.
+ * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied.
+ * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid connection handle supplied.
+ */
+SVCALL(SD_BLE_GAP_LESC_OOB_DATA_GET, uint32_t, sd_ble_gap_lesc_oob_data_get(uint16_t conn_handle, ble_gap_lesc_p256_pk_t const *p_pk_own, ble_gap_lesc_oob_data_t *p_oobd_own));
+
+/**@brief Provide the OOB data sent/received out of band.
+ *
+ * @note An authentication procedure with OOB selected as an algorithm must be in progress when calling this function.
+ * @note A @ref BLE_GAP_EVT_LESC_DHKEY_REQUEST event with the oobd_req set to 1 must have been received prior to calling this function.
+ *
+ * @events
+ * @event{This function is used during authentication procedures\, see the list of events in the documentation of @ref sd_ble_gap_authenticate.}
+ * @endevents
+ *
+ * @mscs
+ * @mmsc{@ref BLE_GAP_PERIPH_LESC_BONDING_OOB_MSC}
+ * @mmsc{@ref BLE_GAP_CENTRAL_LESC_BONDING_OOB_MSC}
+ * @endmscs
+ *
+ * @param[in] conn_handle Connection handle.
+ * @param[in] p_oobd_own The OOB data sent out of band to a peer or NULL if the peer has not received OOB data.
+ * Must correspond to @ref ble_gap_sec_params_t::oob flag in @ref BLE_GAP_EVT_SEC_PARAMS_REQUEST.
+ * @param[in] p_oobd_peer The OOB data received out of band from a peer or NULL if none received.
+ * Must correspond to @ref ble_gap_sec_params_t::oob flag in @ref sd_ble_gap_authenticate in the central role
+ * or @ref sd_ble_gap_sec_params_reply in the peripheral role.
+ *
+ * @retval ::NRF_SUCCESS OOB data accepted.
+ * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied.
+ * @retval ::NRF_ERROR_INVALID_STATE Invalid state to perform operation.
+ * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid connection handle supplied.
+ */
+SVCALL(SD_BLE_GAP_LESC_OOB_DATA_SET, uint32_t, sd_ble_gap_lesc_oob_data_set(uint16_t conn_handle, ble_gap_lesc_oob_data_t const *p_oobd_own, ble_gap_lesc_oob_data_t const *p_oobd_peer));
+
+
+/**@brief Initiate GAP Encryption procedure.
+ *
+ * @details In the central role, this function will initiate the encryption procedure using the encryption information provided.
+ *
+ * @events
+ * @event{@ref BLE_GAP_EVT_CONN_SEC_UPDATE, The connection security has been updated.}
+ * @endevents
+ *
+ * @mscs
+ * @mmsc{@ref BLE_GAP_CENTRAL_ENC_AUTH_MUTEX_MSC}
+ * @mmsc{@ref BLE_GAP_CENTRAL_ENC_MSC}
+ * @mmsc{@ref BLE_GAP_MULTILINK_CTRL_PROC_MSC}
+ * @mmsc{@ref BLE_GAP_CENTRAL_SEC_REQ_MSC}
+ * @endmscs
+ *
+ * @param[in] conn_handle Connection handle.
+ * @param[in] p_master_id Pointer to a @ref ble_gap_master_id_t master identification structure.
+ * @param[in] p_enc_info Pointer to a @ref ble_gap_enc_info_t encryption information structure.
+ *
+ * @retval ::NRF_SUCCESS Successfully initiated authentication procedure.
+ * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied.
+ * @retval ::NRF_ERROR_INVALID_STATE Invalid state to perform operation.
+ * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid connection handle supplied.
+ * @retval ::BLE_ERROR_INVALID_ROLE Operation is not supported in the Peripheral role.
+ * @retval ::NRF_ERROR_BUSY Procedure already in progress or not allowed at this time, wait for pending procedures to complete and retry.
+ */
+SVCALL(SD_BLE_GAP_ENCRYPT, uint32_t, sd_ble_gap_encrypt(uint16_t conn_handle, ble_gap_master_id_t const *p_master_id, ble_gap_enc_info_t const *p_enc_info));
+
+
+/**@brief Reply with GAP security information.
+ *
+ * @details This function is only used to reply to a @ref BLE_GAP_EVT_SEC_INFO_REQUEST, calling it at other times will result in @ref NRF_ERROR_INVALID_STATE.
+ * @note If the call returns an error code, the request is still pending, and the reply call may be repeated with corrected parameters.
+ * @note Data signing is not yet supported, and p_sign_info must therefore be NULL.
+ *
+ * @mscs
+ * @mmsc{@ref BLE_GAP_PERIPH_ENC_MSC}
+ * @endmscs
+ *
+ * @param[in] conn_handle Connection handle.
+ * @param[in] p_enc_info Pointer to a @ref ble_gap_enc_info_t encryption information structure. May be NULL to signal none is available.
+ * @param[in] p_id_info Pointer to a @ref ble_gap_irk_t identity information structure. May be NULL to signal none is available.
+ * @param[in] p_sign_info Pointer to a @ref ble_gap_sign_info_t signing information structure. May be NULL to signal none is available.
+ *
+ * @retval ::NRF_SUCCESS Successfully accepted security information.
+ * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied.
+ * @retval ::NRF_ERROR_INVALID_STATE Invalid state to perform operation.
+ * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid connection handle supplied.
+ */
+SVCALL(SD_BLE_GAP_SEC_INFO_REPLY, uint32_t, sd_ble_gap_sec_info_reply(uint16_t conn_handle, ble_gap_enc_info_t const *p_enc_info, ble_gap_irk_t const *p_id_info, ble_gap_sign_info_t const *p_sign_info));
+
+
+/**@brief Get the current connection security.
+ *
+ * @param[in] conn_handle Connection handle.
+ * @param[out] p_conn_sec Pointer to a @ref ble_gap_conn_sec_t structure to be filled in.
+ *
+ * @retval ::NRF_SUCCESS Current connection security successfully retrieved.
+ * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied.
+ * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid connection handle supplied.
+ */
+SVCALL(SD_BLE_GAP_CONN_SEC_GET, uint32_t, sd_ble_gap_conn_sec_get(uint16_t conn_handle, ble_gap_conn_sec_t *p_conn_sec));
+
+
+/**@brief Start reporting the received signal strength to the application.
+ *
+ * A new event is reported whenever the RSSI value changes, until @ref sd_ble_gap_rssi_stop is called.
+ *
+ * @events
+ * @event{@ref BLE_GAP_EVT_RSSI_CHANGED, New RSSI data available. How often the event is generated is
+ * dependent on the settings of the <code>threshold_dbm</code>
+ * and <code>skip_count</code> input parameters.}
+ * @endevents
+ *
+ * @mscs
+ * @mmsc{@ref BLE_GAP_CENTRAL_RSSI_READ_MSC}
+ * @mmsc{@ref BLE_GAP_RSSI_FILT_MSC}
+ * @endmscs
+ *
+ * @param[in] conn_handle Connection handle.
+ * @param[in] threshold_dbm Minimum change in dBm before triggering the @ref BLE_GAP_EVT_RSSI_CHANGED event. Events are disabled if threshold_dbm equals @ref BLE_GAP_RSSI_THRESHOLD_INVALID.
+ * @param[in] skip_count Number of RSSI samples with a change of threshold_dbm or more before sending a new @ref BLE_GAP_EVT_RSSI_CHANGED event.
+ *
+ * @retval ::NRF_SUCCESS Successfully activated RSSI reporting.
+ * @retval ::NRF_ERROR_INVALID_STATE RSSI reporting is already ongoing.
+ * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid connection handle supplied.
+ */
+SVCALL(SD_BLE_GAP_RSSI_START, uint32_t, sd_ble_gap_rssi_start(uint16_t conn_handle, uint8_t threshold_dbm, uint8_t skip_count));
+
+
+/**@brief Stop reporting the received signal strength.
+ *
+ * @note An RSSI change detected before the call but not yet received by the application
+ * may be reported after @ref sd_ble_gap_rssi_stop has been called.
+ *
+ * @mscs
+ * @mmsc{@ref BLE_GAP_CENTRAL_RSSI_READ_MSC}
+ * @mmsc{@ref BLE_GAP_RSSI_FILT_MSC}
+ * @endmscs
+ *
+ * @param[in] conn_handle Connection handle.
+ *
+ * @retval ::NRF_SUCCESS Successfully deactivated RSSI reporting.
+ * @retval ::NRF_ERROR_INVALID_STATE RSSI reporting is not ongoing.
+ * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid connection handle supplied.
+ */
+SVCALL(SD_BLE_GAP_RSSI_STOP, uint32_t, sd_ble_gap_rssi_stop(uint16_t conn_handle));
+
+
+/**@brief Get the received signal strength for the last connection event.
+ *
+ * @ref sd_ble_gap_rssi_start must be called to start reporting RSSI before using this function. @ref NRF_ERROR_NOT_FOUND
+ * will be returned until RSSI was sampled for the first time after calling @ref sd_ble_gap_rssi_start.
+ * @note ERRATA-153 requires the rssi sample to be compensated based on a temperature measurement.
+ * @mscs
+ * @mmsc{@ref BLE_GAP_CENTRAL_RSSI_READ_MSC}
+ * @endmscs
+ *
+ * @param[in] conn_handle Connection handle.
+ * @param[out] p_rssi Pointer to the location where the RSSI measurement shall be stored.
+ * @param[out] p_ch_index Pointer to the location where Channel Index for the RSSI measurement shall be stored.
+ *
+ * @retval ::NRF_SUCCESS Successfully read the RSSI.
+ * @retval ::NRF_ERROR_NOT_FOUND No sample is available.
+ * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied.
+ * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid connection handle supplied.
+ * @retval ::NRF_ERROR_INVALID_STATE RSSI reporting is not ongoing.
+ */
+SVCALL(SD_BLE_GAP_RSSI_GET, uint32_t, sd_ble_gap_rssi_get(uint16_t conn_handle, int8_t *p_rssi, uint8_t *p_ch_index));
+
+
+/**@brief Start or continue scanning (GAP Discovery procedure, Observer Procedure).
+ *
+ * @note A call to this function will require the application to keep the memory pointed by
+ * p_adv_report_buffer alive until the buffer is released. The buffer is released when the scanner is stopped
+ * or when this function is called with another buffer.
+ *
+ * @note The scanner will automatically stop in the following cases:
+ * - @ref sd_ble_gap_scan_stop is called.
+ * - @ref sd_ble_gap_connect is called.
+ * - A @ref BLE_GAP_EVT_TIMEOUT with source set to @ref BLE_GAP_TIMEOUT_SRC_SCAN is received.
+ * - When a @ref BLE_GAP_EVT_ADV_REPORT event is received and @ref ble_gap_adv_report_type_t::status is not set to
+ * @ref BLE_GAP_ADV_DATA_STATUS_INCOMPLETE_MORE_DATA. In this case scanning is only paused to let the application
+ * access received data. The application must call this function to continue scanning, or call @ref sd_ble_gap_scan_stop
+ * to stop scanning.
+ *
+ * @note If a @ref BLE_GAP_EVT_ADV_REPORT event is received with @ref ble_gap_adv_report_type_t::status set to
+ * @ref BLE_GAP_ADV_DATA_STATUS_INCOMPLETE_MORE_DATA, the scanner will continue scanning, and the application will
+ * receive more reports from this advertising event. The following reports will include the old and new received data.
+ * The application can stop the scanner from receiving more packets from this advertising event by calling this function.
+ * This might be useful when receiving data from extended advertising events where @ref ble_gap_evt_adv_report_t::aux_pointer
+ * is large.
+ *
+ * @events
+ * @event{@ref BLE_GAP_EVT_ADV_REPORT, An advertising or scan response packet has been received.}
+ * @event{@ref BLE_GAP_EVT_TIMEOUT, Scanner has timed out.}
+ * @endevents
+ *
+ * @mscs
+ * @mmsc{@ref BLE_GAP_SCAN_MSC}
+ * @mmsc{@ref BLE_GAP_WL_SHARE_MSC}
+ * @endmscs
+ *
+ * @param[in] p_scan_params Pointer to scan parameters structure. When this function is used to continue
+ * scanning, this parameter must be NULL.
+ * @param[in] p_adv_report_buffer Pointer to buffer used to store incoming advertising data.
+ * The memory pointed to should be kept alive until the scanning is stopped.
+ * See @ref BLE_GAP_SCAN_BUFFER_SIZE for minimum and maximum buffer size.
+ * If the scanner receives advertising data larger than can be stored in the buffer,
+ * a @ref BLE_GAP_EVT_ADV_REPORT will be raised with @ref ble_gap_adv_report_type_t::status
+ * set to @ref BLE_GAP_ADV_DATA_STATUS_INCOMPLETE_TRUNCATED.
+ *
+ * @retval ::NRF_SUCCESS Successfully initiated scanning procedure.
+ * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied.
+ * @retval ::NRF_ERROR_INVALID_STATE Invalid state to perform operation. Either:
+ * - Scanning is already ongoing and p_scan_params was not NULL
+ * - Scanning is not running and p_scan_params was NULL.
+ * - The scanner has timed out when this function is called to continue scanning.
+ * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied. See @ref ble_gap_scan_params_t.
+ * @retval ::NRF_ERROR_NOT_SUPPORTED Unsupported parameters supplied. See @ref ble_gap_scan_params_t.
+ * @retval ::NRF_ERROR_INVALID_LENGTH The provided buffer length is invalid. See @ref BLE_GAP_SCAN_BUFFER_MIN.
+ * @retval ::NRF_ERROR_RESOURCES Not enough BLE role slots available.
+ * Stop one or more currently active roles (Central, Peripheral or Broadcaster) and try again
+ */
+SVCALL(SD_BLE_GAP_SCAN_START, uint32_t, sd_ble_gap_scan_start(ble_gap_scan_params_t const *p_scan_params, ble_data_t const * p_adv_report_buffer));
+
+
+/**@brief Stop scanning (GAP Discovery procedure, Observer Procedure).
+ *
+ * @note The buffer provided in @ref sd_ble_gap_scan_start is released.
+ *
+ * @mscs
+ * @mmsc{@ref BLE_GAP_SCAN_MSC}
+ * @mmsc{@ref BLE_GAP_WL_SHARE_MSC}
+ * @endmscs
+ *
+ * @retval ::NRF_SUCCESS Successfully stopped scanning procedure.
+ * @retval ::NRF_ERROR_INVALID_STATE Invalid state to perform operation. Not in the scanning state.
+ */
+SVCALL(SD_BLE_GAP_SCAN_STOP, uint32_t, sd_ble_gap_scan_stop(void));
+
+
+/**@brief Create a connection (GAP Link Establishment).
+ *
+ * @note If a scanning procedure is currently in progress it will be automatically stopped when calling this function.
+ * The scanning procedure will be stopped even if the function returns an error.
+ *
+ * @mscs
+ * @mmsc{@ref BLE_GAP_WL_SHARE_MSC}
+ * @mmsc{@ref BLE_GAP_CENTRAL_CONN_PRIV_MSC}
+ * @mmsc{@ref BLE_GAP_CENTRAL_CONN_MSC}
+ * @endmscs
+ *
+ * @param[in] p_peer_addr Pointer to peer identity address. If @ref ble_gap_scan_params_t::filter_policy is set to use
+ * whitelist, then p_peer_addr is ignored.
+ * @param[in] p_scan_params Pointer to scan parameters structure.
+ * @param[in] p_conn_params Pointer to desired connection parameters.
+ * @param[in] conn_cfg_tag Tag identifying a configuration set by @ref sd_ble_cfg_set or
+ * @ref BLE_CONN_CFG_TAG_DEFAULT to use the default connection configuration.
+ *
+ * @retval ::NRF_SUCCESS Successfully initiated connection procedure.
+ * @retval ::NRF_ERROR_INVALID_ADDR Invalid parameter(s) pointer supplied.
+ * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied.
+ * - Invalid parameter(s) in p_scan_params or p_conn_params.
+ * - Use of whitelist requested but whitelist has not been set, see @ref sd_ble_gap_whitelist_set.
+ * - Peer address was not present in the device identity list, see @ref sd_ble_gap_device_identities_set.
+ * @retval ::NRF_ERROR_NOT_FOUND conn_cfg_tag not found.
+ * @retval ::NRF_ERROR_INVALID_STATE The SoftDevice is in an invalid state to perform this operation. This may be due to an
+ * existing locally initiated connect procedure, which must complete before initiating again.
+ * @retval ::BLE_ERROR_GAP_INVALID_BLE_ADDR Invalid Peer address.
+ * @retval ::NRF_ERROR_CONN_COUNT The limit of available connections has been reached.
+ * @retval ::NRF_ERROR_RESOURCES Either:
+ * - Not enough BLE role slots available.
+ * Stop one or more currently active roles (Central, Peripheral or Observer) and try again.
+ * - The event_length parameter associated with conn_cfg_tag is too small to be able to
+ * establish a connection on the selected @ref ble_gap_scan_params_t::scan_phys.
+ * Use @ref sd_ble_cfg_set to increase the event length.
+ */
+SVCALL(SD_BLE_GAP_CONNECT, uint32_t, sd_ble_gap_connect(ble_gap_addr_t const *p_peer_addr, ble_gap_scan_params_t const *p_scan_params, ble_gap_conn_params_t const *p_conn_params, uint8_t conn_cfg_tag));
+
+
+/**@brief Cancel a connection establishment.
+ *
+ * @mscs
+ * @mmsc{@ref BLE_GAP_CENTRAL_CONN_MSC}
+ * @endmscs
+ *
+ * @retval ::NRF_SUCCESS Successfully canceled an ongoing connection procedure.
+ * @retval ::NRF_ERROR_INVALID_STATE Invalid state to perform operation.
+ */
+SVCALL(SD_BLE_GAP_CONNECT_CANCEL, uint32_t, sd_ble_gap_connect_cancel(void));
+
+
+/**@brief Initiate or respond to a PHY Update Procedure
+ *
+ * @details This function is used to initiate or respond to a PHY Update Procedure. It will always
+ * generate a @ref BLE_GAP_EVT_PHY_UPDATE event if successfully executed.
+ * If this function is used to initiate a PHY Update procedure and the only option
+ * provided in @ref ble_gap_phys_t::tx_phys and @ref ble_gap_phys_t::rx_phys is the
+ * currently active PHYs in the respective directions, the SoftDevice will generate a
+ * @ref BLE_GAP_EVT_PHY_UPDATE with the current PHYs set and will not initiate the
+ * procedure in the Link Layer.
+ *
+ * If @ref ble_gap_phys_t::tx_phys or @ref ble_gap_phys_t::rx_phys is @ref BLE_GAP_PHY_AUTO,
+ * then the stack will select PHYs based on the peer's PHY preferences and the local link
+ * configuration. The PHY Update procedure will for this case result in a PHY combination
+ * that respects the time constraints configured with @ref sd_ble_cfg_set and the current
+ * link layer data length.
+ *
+ * When acting as a central, the SoftDevice will select the fastest common PHY in each direction.
+ *
+ * If the peer does not support the PHY Update Procedure, then the resulting
+ * @ref BLE_GAP_EVT_PHY_UPDATE event will have a status set to
+ * @ref BLE_HCI_UNSUPPORTED_REMOTE_FEATURE.
+ *
+ * If the PHY procedure was rejected by the peer due to a procedure collision, the status
+ * will be @ref BLE_HCI_STATUS_CODE_LMP_ERROR_TRANSACTION_COLLISION or
+ * @ref BLE_HCI_DIFFERENT_TRANSACTION_COLLISION.
+ * If the peer responds to the PHY Update procedure with invalid parameters, the status
+ * will be @ref BLE_HCI_STATUS_CODE_INVALID_LMP_PARAMETERS.
+ * If the PHY procedure was rejected by the peer for a different reason, the status will
+ * contain the reason as specified by the peer.
+ *
+ * @note @ref BLE_GAP_PHY_CODED is only supported as an experimental feature in this SoftDevice.
+ * When this function is used to reply to a PHY Update, depending on the peers preferences,
+ * @ref BLE_GAP_PHY_AUTO might result in the PHY to be changed to @ref BLE_GAP_PHY_CODED.
+ *
+ * @events
+ * @event{@ref BLE_GAP_EVT_PHY_UPDATE, Result of the PHY Update Procedure.}
+ * @endevents
+ *
+ * @mscs
+ * @mmsc{@ref BLE_GAP_CENTRAL_PHY_UPDATE}
+ * @mmsc{@ref BLE_GAP_PERIPHERAL_PHY_UPDATE}
+ * @endmscs
+ *
+ * @param[in] conn_handle Connection handle to indicate the connection for which the PHY Update is requested.
+ * @param[in] p_gap_phys Pointer to PHY structure.
+ *
+ * @retval ::NRF_SUCCESS Successfully requested a PHY Update.
+ * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied.
+ * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid connection handle supplied.
+ * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied.
+ * @retval ::NRF_ERROR_INVALID_STATE Invalid state to perform operation.
+ * @retval ::NRF_ERROR_RESOURCES The connection event length configured for this link is not sufficient for the combination of
+ * @ref ble_gap_phys_t::tx_phys, @ref ble_gap_phys_t::rx_phys, and @ref ble_gap_data_length_params_t.
+ * The connection event length is configured with @ref BLE_CONN_CFG_GAP using @ref sd_ble_cfg_set.
+ * @retval ::NRF_ERROR_BUSY Procedure is already in progress or not allowed at this time. Process pending events and wait for the pending procedure to complete and retry.
+ *
+ */
+SVCALL(SD_BLE_GAP_PHY_UPDATE, uint32_t, sd_ble_gap_phy_update(uint16_t conn_handle, ble_gap_phys_t const *p_gap_phys));
+
+
+/**@brief Initiate or respond to a Data Length Update Procedure.
+ *
+ * @note If the application uses @ref BLE_GAP_DATA_LENGTH_AUTO for one or more members of
+ * p_dl_params, the SoftDevice will choose the highest value supported in current
+ * configuration and connection parameters.
+ *
+ * @param[in] conn_handle Connection handle.
+ * @param[in] p_dl_params Pointer to local parameters to be used in Data Length Update
+ * Procedure. Set any member to @ref BLE_GAP_DATA_LENGTH_AUTO to let
+ * the SoftDevice automatically decide the value for that member.
+ * Set to NULL to use automatic values for all members.
+ * @param[out] p_dl_limitation Pointer to limitation to be written when local device does not
+ * have enough resources or does not support the requested Data Length
+ * Update parameters. Ignored if NULL.
+ *
+ * @mscs
+ * @mmsc{@ref BLE_GAP_DATA_LENGTH_UPDATE_PROCEDURE_MSC}
+ * @endmscs
+ *
+ * @retval ::NRF_SUCCESS Successfully set Data Length Extension initiation/response parameters.
+ * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied.
+ * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid connection handle parameter supplied.
+ * @retval ::NRF_ERROR_INVALID_STATE Invalid state to perform operation.
+ * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameters supplied.
+ * @retval ::NRF_ERROR_NOT_SUPPORTED The requested parameters are not supported by the SoftDevice. Inspect
+ * p_dl_limitation to see which parameter is not supported.
+ * @retval ::NRF_ERROR_RESOURCES The connection event length configured for this link is not sufficient for the requested parameters.
+ * Use @ref sd_ble_cfg_set with @ref BLE_CONN_CFG_GAP to increase the connection event length.
+ * Inspect p_dl_limitation to see where the limitation is.
+ * @retval ::NRF_ERROR_BUSY Peer has already initiated a Data Length Update Procedure. Process the
+ * pending @ref BLE_GAP_EVT_DATA_LENGTH_UPDATE_REQUEST event to respond.
+ */
+SVCALL(SD_BLE_GAP_DATA_LENGTH_UPDATE, uint32_t, sd_ble_gap_data_length_update(uint16_t conn_handle, ble_gap_data_length_params_t const *p_dl_params, ble_gap_data_length_limitation_t *p_dl_limitation));
+
+/**@brief Start the Quality of Service (QoS) channel survey module.
+ *
+ * @details The channel survey module provides measurements of the energy levels on
+ * the Bluetooth Low Energy channels. When the module is enabled, @ref BLE_GAP_EVT_QOS_CHANNEL_SURVEY_REPORT
+ * events will periodically report the measured energy levels for each channel.
+ *
+ * @note The measurements are scheduled with lower priority than other Bluetooth Low Energy roles,
+ * Radio Timeslot API events and Flash API events.
+ *
+ * @note The channel survey module will attempt to do measurements so that the average interval
+ * between measurements will be interval_us. However due to the channel survey module
+ * having the lowest priority of all roles and modules, this may not be possible. In that
+ * case fewer than expected channel survey reports may be given.
+ *
+ * @note In order to use the channel survey module, @ref ble_gap_cfg_role_count_t::qos_channel_survey_role_available
+ * must be set. This is done using @ref sd_ble_cfg_set.
+ *
+ * @param[in] interval_us Requested average interval for the measurements and reports. See
+ * @ref BLE_GAP_QOS_CHANNEL_SURVEY_INTERVALS for valid ranges. If set
+ * to @ref BLE_GAP_QOS_CHANNEL_SURVEY_INTERVAL_CONTINUOUS, the channel
+ * survey role will be scheduled at every available opportunity.
+ *
+ * @retval ::NRF_SUCCESS The module is successfully started.
+ * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter supplied. interval_us is out of the
+ * allowed range.
+ * @retval ::NRF_ERROR_INVALID_STATE Trying to start the module when already running.
+ * @retval ::NRF_ERROR_RESOURCES The channel survey module is not available to the application.
+ * Set @ref ble_gap_cfg_role_count_t::qos_channel_survey_role_available using
+ * @ref sd_ble_cfg_set.
+ */
+SVCALL(SD_BLE_GAP_QOS_CHANNEL_SURVEY_START, uint32_t, sd_ble_gap_qos_channel_survey_start(uint32_t interval_us));
+
+/**@brief Stop the Quality of Service (QoS) channel survey module.
+ *
+ * @retval ::NRF_SUCCESS The module is successfully stopped.
+ * @retval ::NRF_ERROR_INVALID_STATE Trying to stop the module when it is not running.
+ */
+SVCALL(SD_BLE_GAP_QOS_CHANNEL_SURVEY_STOP, uint32_t, sd_ble_gap_qos_channel_survey_stop(void));
+
+
+/** @} */
+
+#ifdef __cplusplus
+}
+#endif
+#endif // BLE_GAP_H__
+
+/**
+ @}
+*/
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/softdevice/s140/headers/ble_gatt.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/softdevice/s140/headers/ble_gatt.h
new file mode 100644
index 0000000..98a7a15
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/softdevice/s140/headers/ble_gatt.h
@@ -0,0 +1,228 @@
+/*
+ * Copyright (c) 2013 - 2017, 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ */
+
+/**
+ @addtogroup BLE_GATT Generic Attribute Profile (GATT) Common
+ @{
+ @brief Common definitions and prototypes for the GATT interfaces.
+ */
+
+#ifndef BLE_GATT_H__
+#define BLE_GATT_H__
+
+#include <stdint.h>
+#include "nrf_svc.h"
+#include "nrf_error.h"
+#include "ble_hci.h"
+#include "ble_ranges.h"
+#include "ble_types.h"
+#include "ble_err.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** @addtogroup BLE_GATT_DEFINES Defines
+ * @{ */
+
+/** @brief Default ATT MTU, in bytes. */
+#define BLE_GATT_ATT_MTU_DEFAULT 23
+
+/**@brief Invalid Attribute Handle. */
+#define BLE_GATT_HANDLE_INVALID 0x0000
+
+/**@brief First Attribute Handle. */
+#define BLE_GATT_HANDLE_START 0x0001
+
+/**@brief Last Attribute Handle. */
+#define BLE_GATT_HANDLE_END 0xFFFF
+
+/** @defgroup BLE_GATT_TIMEOUT_SOURCES GATT Timeout sources
+ * @{ */
+#define BLE_GATT_TIMEOUT_SRC_PROTOCOL 0x00 /**< ATT Protocol timeout. */
+/** @} */
+
+/** @defgroup BLE_GATT_WRITE_OPS GATT Write operations
+ * @{ */
+#define BLE_GATT_OP_INVALID 0x00 /**< Invalid Operation. */
+#define BLE_GATT_OP_WRITE_REQ 0x01 /**< Write Request. */
+#define BLE_GATT_OP_WRITE_CMD 0x02 /**< Write Command. */
+#define BLE_GATT_OP_SIGN_WRITE_CMD 0x03 /**< Signed Write Command. */
+#define BLE_GATT_OP_PREP_WRITE_REQ 0x04 /**< Prepare Write Request. */
+#define BLE_GATT_OP_EXEC_WRITE_REQ 0x05 /**< Execute Write Request. */
+/** @} */
+
+/** @defgroup BLE_GATT_EXEC_WRITE_FLAGS GATT Execute Write flags
+ * @{ */
+#define BLE_GATT_EXEC_WRITE_FLAG_PREPARED_CANCEL 0x00 /**< Cancel prepared write. */
+#define BLE_GATT_EXEC_WRITE_FLAG_PREPARED_WRITE 0x01 /**< Execute prepared write. */
+/** @} */
+
+/** @defgroup BLE_GATT_HVX_TYPES GATT Handle Value operations
+ * @{ */
+#define BLE_GATT_HVX_INVALID 0x00 /**< Invalid Operation. */
+#define BLE_GATT_HVX_NOTIFICATION 0x01 /**< Handle Value Notification. */
+#define BLE_GATT_HVX_INDICATION 0x02 /**< Handle Value Indication. */
+/** @} */
+
+/** @defgroup BLE_GATT_STATUS_CODES GATT Status Codes
+ * @{ */
+#define BLE_GATT_STATUS_SUCCESS 0x0000 /**< Success. */
+#define BLE_GATT_STATUS_UNKNOWN 0x0001 /**< Unknown or not applicable status. */
+#define BLE_GATT_STATUS_ATTERR_INVALID 0x0100 /**< ATT Error: Invalid Error Code. */
+#define BLE_GATT_STATUS_ATTERR_INVALID_HANDLE 0x0101 /**< ATT Error: Invalid Attribute Handle. */
+#define BLE_GATT_STATUS_ATTERR_READ_NOT_PERMITTED 0x0102 /**< ATT Error: Read not permitted. */
+#define BLE_GATT_STATUS_ATTERR_WRITE_NOT_PERMITTED 0x0103 /**< ATT Error: Write not permitted. */
+#define BLE_GATT_STATUS_ATTERR_INVALID_PDU 0x0104 /**< ATT Error: Used in ATT as Invalid PDU. */
+#define BLE_GATT_STATUS_ATTERR_INSUF_AUTHENTICATION 0x0105 /**< ATT Error: Authenticated link required. */
+#define BLE_GATT_STATUS_ATTERR_REQUEST_NOT_SUPPORTED 0x0106 /**< ATT Error: Used in ATT as Request Not Supported. */
+#define BLE_GATT_STATUS_ATTERR_INVALID_OFFSET 0x0107 /**< ATT Error: Offset specified was past the end of the attribute. */
+#define BLE_GATT_STATUS_ATTERR_INSUF_AUTHORIZATION 0x0108 /**< ATT Error: Used in ATT as Insufficient Authorization. */
+#define BLE_GATT_STATUS_ATTERR_PREPARE_QUEUE_FULL 0x0109 /**< ATT Error: Used in ATT as Prepare Queue Full. */
+#define BLE_GATT_STATUS_ATTERR_ATTRIBUTE_NOT_FOUND 0x010A /**< ATT Error: Used in ATT as Attribute not found. */
+#define BLE_GATT_STATUS_ATTERR_ATTRIBUTE_NOT_LONG 0x010B /**< ATT Error: Attribute cannot be read or written using read/write blob requests. */
+#define BLE_GATT_STATUS_ATTERR_INSUF_ENC_KEY_SIZE 0x010C /**< ATT Error: Encryption key size used is insufficient. */
+#define BLE_GATT_STATUS_ATTERR_INVALID_ATT_VAL_LENGTH 0x010D /**< ATT Error: Invalid value size. */
+#define BLE_GATT_STATUS_ATTERR_UNLIKELY_ERROR 0x010E /**< ATT Error: Very unlikely error. */
+#define BLE_GATT_STATUS_ATTERR_INSUF_ENCRYPTION 0x010F /**< ATT Error: Encrypted link required. */
+#define BLE_GATT_STATUS_ATTERR_UNSUPPORTED_GROUP_TYPE 0x0110 /**< ATT Error: Attribute type is not a supported grouping attribute. */
+#define BLE_GATT_STATUS_ATTERR_INSUF_RESOURCES 0x0111 /**< ATT Error: Encrypted link required. */
+#define BLE_GATT_STATUS_ATTERR_RFU_RANGE1_BEGIN 0x0112 /**< ATT Error: Reserved for Future Use range #1 begin. */
+#define BLE_GATT_STATUS_ATTERR_RFU_RANGE1_END 0x017F /**< ATT Error: Reserved for Future Use range #1 end. */
+#define BLE_GATT_STATUS_ATTERR_APP_BEGIN 0x0180 /**< ATT Error: Application range begin. */
+#define BLE_GATT_STATUS_ATTERR_APP_END 0x019F /**< ATT Error: Application range end. */
+#define BLE_GATT_STATUS_ATTERR_RFU_RANGE2_BEGIN 0x01A0 /**< ATT Error: Reserved for Future Use range #2 begin. */
+#define BLE_GATT_STATUS_ATTERR_RFU_RANGE2_END 0x01DF /**< ATT Error: Reserved for Future Use range #2 end. */
+#define BLE_GATT_STATUS_ATTERR_RFU_RANGE3_BEGIN 0x01E0 /**< ATT Error: Reserved for Future Use range #3 begin. */
+#define BLE_GATT_STATUS_ATTERR_RFU_RANGE3_END 0x01FC /**< ATT Error: Reserved for Future Use range #3 end. */
+#define BLE_GATT_STATUS_ATTERR_CPS_CCCD_CONFIG_ERROR 0x01FD /**< ATT Common Profile and Service Error: Client Characteristic Configuration Descriptor improperly configured. */
+#define BLE_GATT_STATUS_ATTERR_CPS_PROC_ALR_IN_PROG 0x01FE /**< ATT Common Profile and Service Error: Procedure Already in Progress. */
+#define BLE_GATT_STATUS_ATTERR_CPS_OUT_OF_RANGE 0x01FF /**< ATT Common Profile and Service Error: Out Of Range. */
+/** @} */
+
+
+/** @defgroup BLE_GATT_CPF_FORMATS Characteristic Presentation Formats
+ * @note Found at http://developer.bluetooth.org/gatt/descriptors/Pages/DescriptorViewer.aspx?u=org.bluetooth.descriptor.gatt.characteristic_presentation_format.xml
+ * @{ */
+#define BLE_GATT_CPF_FORMAT_RFU 0x00 /**< Reserved For Future Use. */
+#define BLE_GATT_CPF_FORMAT_BOOLEAN 0x01 /**< Boolean. */
+#define BLE_GATT_CPF_FORMAT_2BIT 0x02 /**< Unsigned 2-bit integer. */
+#define BLE_GATT_CPF_FORMAT_NIBBLE 0x03 /**< Unsigned 4-bit integer. */
+#define BLE_GATT_CPF_FORMAT_UINT8 0x04 /**< Unsigned 8-bit integer. */
+#define BLE_GATT_CPF_FORMAT_UINT12 0x05 /**< Unsigned 12-bit integer. */
+#define BLE_GATT_CPF_FORMAT_UINT16 0x06 /**< Unsigned 16-bit integer. */
+#define BLE_GATT_CPF_FORMAT_UINT24 0x07 /**< Unsigned 24-bit integer. */
+#define BLE_GATT_CPF_FORMAT_UINT32 0x08 /**< Unsigned 32-bit integer. */
+#define BLE_GATT_CPF_FORMAT_UINT48 0x09 /**< Unsigned 48-bit integer. */
+#define BLE_GATT_CPF_FORMAT_UINT64 0x0A /**< Unsigned 64-bit integer. */
+#define BLE_GATT_CPF_FORMAT_UINT128 0x0B /**< Unsigned 128-bit integer. */
+#define BLE_GATT_CPF_FORMAT_SINT8 0x0C /**< Signed 2-bit integer. */
+#define BLE_GATT_CPF_FORMAT_SINT12 0x0D /**< Signed 12-bit integer. */
+#define BLE_GATT_CPF_FORMAT_SINT16 0x0E /**< Signed 16-bit integer. */
+#define BLE_GATT_CPF_FORMAT_SINT24 0x0F /**< Signed 24-bit integer. */
+#define BLE_GATT_CPF_FORMAT_SINT32 0x10 /**< Signed 32-bit integer. */
+#define BLE_GATT_CPF_FORMAT_SINT48 0x11 /**< Signed 48-bit integer. */
+#define BLE_GATT_CPF_FORMAT_SINT64 0x12 /**< Signed 64-bit integer. */
+#define BLE_GATT_CPF_FORMAT_SINT128 0x13 /**< Signed 128-bit integer. */
+#define BLE_GATT_CPF_FORMAT_FLOAT32 0x14 /**< IEEE-754 32-bit floating point. */
+#define BLE_GATT_CPF_FORMAT_FLOAT64 0x15 /**< IEEE-754 64-bit floating point. */
+#define BLE_GATT_CPF_FORMAT_SFLOAT 0x16 /**< IEEE-11073 16-bit SFLOAT. */
+#define BLE_GATT_CPF_FORMAT_FLOAT 0x17 /**< IEEE-11073 32-bit FLOAT. */
+#define BLE_GATT_CPF_FORMAT_DUINT16 0x18 /**< IEEE-20601 format. */
+#define BLE_GATT_CPF_FORMAT_UTF8S 0x19 /**< UTF-8 string. */
+#define BLE_GATT_CPF_FORMAT_UTF16S 0x1A /**< UTF-16 string. */
+#define BLE_GATT_CPF_FORMAT_STRUCT 0x1B /**< Opaque Structure. */
+/** @} */
+
+/** @defgroup BLE_GATT_CPF_NAMESPACES GATT Bluetooth Namespaces
+ * @{
+ */
+#define BLE_GATT_CPF_NAMESPACE_BTSIG 0x01 /**< Bluetooth SIG defined Namespace. */
+#define BLE_GATT_CPF_NAMESPACE_DESCRIPTION_UNKNOWN 0x0000 /**< Namespace Description Unknown. */
+/** @} */
+
+/** @} */
+
+/** @addtogroup BLE_GATT_STRUCTURES Structures
+ * @{ */
+
+/**
+ * @brief BLE GATT connection configuration parameters, set with @ref sd_ble_cfg_set.
+ *
+ * @retval ::NRF_ERROR_INVALID_PARAM att_mtu is smaller than @ref BLE_GATT_ATT_MTU_DEFAULT.
+ */
+typedef struct
+{
+ uint16_t att_mtu; /**< Maximum size of ATT packet the SoftDevice can send or receive.
+ The default and minimum value is @ref BLE_GATT_ATT_MTU_DEFAULT.
+ @mscs
+ @mmsc{@ref BLE_GATTC_MTU_EXCHANGE}
+ @mmsc{@ref BLE_GATTS_MTU_EXCHANGE}
+ @endmscs
+ */
+} ble_gatt_conn_cfg_t;
+
+/**@brief GATT Characteristic Properties. */
+typedef struct
+{
+ /* Standard properties */
+ uint8_t broadcast :1; /**< Broadcasting of the value permitted. */
+ uint8_t read :1; /**< Reading the value permitted. */
+ uint8_t write_wo_resp :1; /**< Writing the value with Write Command permitted. */
+ uint8_t write :1; /**< Writing the value with Write Request permitted. */
+ uint8_t notify :1; /**< Notification of the value permitted. */
+ uint8_t indicate :1; /**< Indications of the value permitted. */
+ uint8_t auth_signed_wr :1; /**< Writing the value with Signed Write Command permitted. */
+} ble_gatt_char_props_t;
+
+/**@brief GATT Characteristic Extended Properties. */
+typedef struct
+{
+ /* Extended properties */
+ uint8_t reliable_wr :1; /**< Writing the value with Queued Write operations permitted. */
+ uint8_t wr_aux :1; /**< Writing the Characteristic User Description descriptor permitted. */
+} ble_gatt_char_ext_props_t;
+
+/** @} */
+
+#ifdef __cplusplus
+}
+#endif
+#endif // BLE_GATT_H__
+
+/** @} */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/softdevice/s140/headers/ble_gattc.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/softdevice/s140/headers/ble_gattc.h
new file mode 100644
index 0000000..7fb3920
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/softdevice/s140/headers/ble_gattc.h
@@ -0,0 +1,715 @@
+/*
+ * Copyright (c) 2011 - 2017, 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ */
+
+/**
+ @addtogroup BLE_GATTC Generic Attribute Profile (GATT) Client
+ @{
+ @brief Definitions and prototypes for the GATT Client interface.
+ */
+
+#ifndef BLE_GATTC_H__
+#define BLE_GATTC_H__
+
+#include <stdint.h>
+#include "nrf.h"
+#include "nrf_svc.h"
+#include "nrf_error.h"
+#include "ble_ranges.h"
+#include "ble_types.h"
+#include "ble_err.h"
+#include "ble_gatt.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** @addtogroup BLE_GATTC_ENUMERATIONS Enumerations
+ * @{ */
+
+/**@brief GATTC API SVC numbers. */
+enum BLE_GATTC_SVCS
+{
+ SD_BLE_GATTC_PRIMARY_SERVICES_DISCOVER = BLE_GATTC_SVC_BASE, /**< Primary Service Discovery. */
+ SD_BLE_GATTC_RELATIONSHIPS_DISCOVER, /**< Relationship Discovery. */
+ SD_BLE_GATTC_CHARACTERISTICS_DISCOVER, /**< Characteristic Discovery. */
+ SD_BLE_GATTC_DESCRIPTORS_DISCOVER, /**< Characteristic Descriptor Discovery. */
+ SD_BLE_GATTC_ATTR_INFO_DISCOVER, /**< Attribute Information Discovery. */
+ SD_BLE_GATTC_CHAR_VALUE_BY_UUID_READ, /**< Read Characteristic Value by UUID. */
+ SD_BLE_GATTC_READ, /**< Generic read. */
+ SD_BLE_GATTC_CHAR_VALUES_READ, /**< Read multiple Characteristic Values. */
+ SD_BLE_GATTC_WRITE, /**< Generic write. */
+ SD_BLE_GATTC_HV_CONFIRM, /**< Handle Value Confirmation. */
+ SD_BLE_GATTC_EXCHANGE_MTU_REQUEST, /**< Exchange MTU Request. */
+};
+
+/**
+ * @brief GATT Client Event IDs.
+ */
+enum BLE_GATTC_EVTS
+{
+ BLE_GATTC_EVT_PRIM_SRVC_DISC_RSP = BLE_GATTC_EVT_BASE, /**< Primary Service Discovery Response event. \n See @ref ble_gattc_evt_prim_srvc_disc_rsp_t. */
+ BLE_GATTC_EVT_REL_DISC_RSP, /**< Relationship Discovery Response event. \n See @ref ble_gattc_evt_rel_disc_rsp_t. */
+ BLE_GATTC_EVT_CHAR_DISC_RSP, /**< Characteristic Discovery Response event. \n See @ref ble_gattc_evt_char_disc_rsp_t. */
+ BLE_GATTC_EVT_DESC_DISC_RSP, /**< Descriptor Discovery Response event. \n See @ref ble_gattc_evt_desc_disc_rsp_t. */
+ BLE_GATTC_EVT_ATTR_INFO_DISC_RSP, /**< Attribute Information Response event. \n See @ref ble_gattc_evt_attr_info_disc_rsp_t. */
+ BLE_GATTC_EVT_CHAR_VAL_BY_UUID_READ_RSP, /**< Read By UUID Response event. \n See @ref ble_gattc_evt_char_val_by_uuid_read_rsp_t. */
+ BLE_GATTC_EVT_READ_RSP, /**< Read Response event. \n See @ref ble_gattc_evt_read_rsp_t. */
+ BLE_GATTC_EVT_CHAR_VALS_READ_RSP, /**< Read multiple Response event. \n See @ref ble_gattc_evt_char_vals_read_rsp_t. */
+ BLE_GATTC_EVT_WRITE_RSP, /**< Write Response event. \n See @ref ble_gattc_evt_write_rsp_t. */
+ BLE_GATTC_EVT_HVX, /**< Handle Value Notification or Indication event. \n Confirm indication with @ref sd_ble_gattc_hv_confirm. \n See @ref ble_gattc_evt_hvx_t. */
+ BLE_GATTC_EVT_EXCHANGE_MTU_RSP, /**< Exchange MTU Response event. \n See @ref ble_gattc_evt_exchange_mtu_rsp_t. */
+ BLE_GATTC_EVT_TIMEOUT, /**< Timeout event. \n See @ref ble_gattc_evt_timeout_t. */
+ BLE_GATTC_EVT_WRITE_CMD_TX_COMPLETE /**< Write without Response transmission complete. \n See @ref ble_gattc_evt_write_cmd_tx_complete_t. */
+};
+
+/** @} */
+
+/** @addtogroup BLE_GATTC_DEFINES Defines
+ * @{ */
+
+/** @defgroup BLE_ERRORS_GATTC SVC return values specific to GATTC
+ * @{ */
+#define BLE_ERROR_GATTC_PROC_NOT_PERMITTED (NRF_GATTC_ERR_BASE + 0x000) /**< Procedure not Permitted. */
+/** @} */
+
+/** @defgroup BLE_GATTC_ATTR_INFO_FORMAT Attribute Information Formats
+ * @{ */
+#define BLE_GATTC_ATTR_INFO_FORMAT_16BIT 1 /**< 16-bit Attribute Information Format. */
+#define BLE_GATTC_ATTR_INFO_FORMAT_128BIT 2 /**< 128-bit Attribute Information Format. */
+/** @} */
+
+/** @defgroup BLE_GATTC_DEFAULTS GATT Client defaults
+ * @{ */
+#define BLE_GATTC_WRITE_CMD_TX_QUEUE_SIZE_DEFAULT 1 /**< Default number of Write without Response that can be queued for transmission. */
+/** @} */
+
+/** @} */
+
+/** @addtogroup BLE_GATTC_STRUCTURES Structures
+ * @{ */
+
+/**
+ * @brief BLE GATTC connection configuration parameters, set with @ref sd_ble_cfg_set.
+ */
+typedef struct
+{
+ uint8_t write_cmd_tx_queue_size; /**< The guaranteed minimum number of Write without Response that can be queued for transmission.
+ The default value is @ref BLE_GATTC_WRITE_CMD_TX_QUEUE_SIZE_DEFAULT */
+} ble_gattc_conn_cfg_t;
+
+/**@brief Operation Handle Range. */
+typedef struct
+{
+ uint16_t start_handle; /**< Start Handle. */
+ uint16_t end_handle; /**< End Handle. */
+} ble_gattc_handle_range_t;
+
+
+/**@brief GATT service. */
+typedef struct
+{
+ ble_uuid_t uuid; /**< Service UUID. */
+ ble_gattc_handle_range_t handle_range; /**< Service Handle Range. */
+} ble_gattc_service_t;
+
+
+/**@brief GATT include. */
+typedef struct
+{
+ uint16_t handle; /**< Include Handle. */
+ ble_gattc_service_t included_srvc; /**< Handle of the included service. */
+} ble_gattc_include_t;
+
+
+/**@brief GATT characteristic. */
+typedef struct
+{
+ ble_uuid_t uuid; /**< Characteristic UUID. */
+ ble_gatt_char_props_t char_props; /**< Characteristic Properties. */
+ uint8_t char_ext_props : 1; /**< Extended properties present. */
+ uint16_t handle_decl; /**< Handle of the Characteristic Declaration. */
+ uint16_t handle_value; /**< Handle of the Characteristic Value. */
+} ble_gattc_char_t;
+
+
+/**@brief GATT descriptor. */
+typedef struct
+{
+ uint16_t handle; /**< Descriptor Handle. */
+ ble_uuid_t uuid; /**< Descriptor UUID. */
+} ble_gattc_desc_t;
+
+
+/**@brief Write Parameters. */
+typedef struct
+{
+ uint8_t write_op; /**< Write Operation to be performed, see @ref BLE_GATT_WRITE_OPS. */
+ uint8_t flags; /**< Flags, see @ref BLE_GATT_EXEC_WRITE_FLAGS. */
+ uint16_t handle; /**< Handle to the attribute to be written. */
+ uint16_t offset; /**< Offset in bytes. @note For WRITE_CMD and WRITE_REQ, offset must be 0. */
+ uint16_t len; /**< Length of data in bytes. */
+ uint8_t const *p_value; /**< Pointer to the value data. */
+} ble_gattc_write_params_t;
+
+/**@brief Attribute Information for 16-bit Attribute UUID. */
+typedef struct
+{
+ uint16_t handle; /**< Attribute handle. */
+ ble_uuid_t uuid; /**< 16-bit Attribute UUID. */
+} ble_gattc_attr_info16_t;
+
+/**@brief Attribute Information for 128-bit Attribute UUID. */
+typedef struct
+{
+ uint16_t handle; /**< Attribute handle. */
+ ble_uuid128_t uuid; /**< 128-bit Attribute UUID. */
+} ble_gattc_attr_info128_t;
+
+/**@brief Event structure for @ref BLE_GATTC_EVT_PRIM_SRVC_DISC_RSP. */
+typedef struct
+{
+ uint16_t count; /**< Service count. */
+ ble_gattc_service_t services[1]; /**< Service data. @note This is a variable length array. The size of 1 indicated is only a placeholder for compilation.
+ See @ref sd_ble_evt_get for more information on how to use event structures with variable length array members. */
+} ble_gattc_evt_prim_srvc_disc_rsp_t;
+
+/**@brief Event structure for @ref BLE_GATTC_EVT_REL_DISC_RSP. */
+typedef struct
+{
+ uint16_t count; /**< Include count. */
+ ble_gattc_include_t includes[1]; /**< Include data. @note This is a variable length array. The size of 1 indicated is only a placeholder for compilation.
+ See @ref sd_ble_evt_get for more information on how to use event structures with variable length array members. */
+} ble_gattc_evt_rel_disc_rsp_t;
+
+/**@brief Event structure for @ref BLE_GATTC_EVT_CHAR_DISC_RSP. */
+typedef struct
+{
+ uint16_t count; /**< Characteristic count. */
+ ble_gattc_char_t chars[1]; /**< Characteristic data. @note This is a variable length array. The size of 1 indicated is only a placeholder for compilation.
+ See @ref sd_ble_evt_get for more information on how to use event structures with variable length array members. */
+} ble_gattc_evt_char_disc_rsp_t;
+
+/**@brief Event structure for @ref BLE_GATTC_EVT_DESC_DISC_RSP. */
+typedef struct
+{
+ uint16_t count; /**< Descriptor count. */
+ ble_gattc_desc_t descs[1]; /**< Descriptor data. @note This is a variable length array. The size of 1 indicated is only a placeholder for compilation.
+ See @ref sd_ble_evt_get for more information on how to use event structures with variable length array members. */
+} ble_gattc_evt_desc_disc_rsp_t;
+
+/**@brief Event structure for @ref BLE_GATTC_EVT_ATTR_INFO_DISC_RSP. */
+typedef struct
+{
+ uint16_t count; /**< Attribute count. */
+ uint8_t format; /**< Attribute information format, see @ref BLE_GATTC_ATTR_INFO_FORMAT. */
+ union {
+ ble_gattc_attr_info16_t attr_info16[1]; /**< Attribute information for 16-bit Attribute UUID.
+ @note This is a variable length array. The size of 1 indicated is only a placeholder for compilation.
+ See @ref sd_ble_evt_get for more information on how to use event structures with variable length array members. */
+ ble_gattc_attr_info128_t attr_info128[1]; /**< Attribute information for 128-bit Attribute UUID.
+ @note This is a variable length array. The size of 1 indicated is only a placeholder for compilation.
+ See @ref sd_ble_evt_get for more information on how to use event structures with variable length array members. */
+ } info; /**< Attribute information union. */
+} ble_gattc_evt_attr_info_disc_rsp_t;
+
+/**@brief GATT read by UUID handle value pair. */
+typedef struct
+{
+ uint16_t handle; /**< Attribute Handle. */
+ uint8_t *p_value; /**< Pointer to the Attribute Value, length is available in @ref ble_gattc_evt_char_val_by_uuid_read_rsp_t::value_len. */
+} ble_gattc_handle_value_t;
+
+/**@brief Event structure for @ref BLE_GATTC_EVT_CHAR_VAL_BY_UUID_READ_RSP. */
+typedef struct
+{
+ uint16_t count; /**< Handle-Value Pair Count. */
+ uint16_t value_len; /**< Length of the value in Handle-Value(s) list. */
+ uint8_t handle_value[1]; /**< Handle-Value(s) list. To iterate through the list use @ref sd_ble_gattc_evt_char_val_by_uuid_read_rsp_iter.
+ @note This is a variable length array. The size of 1 indicated is only a placeholder for compilation.
+ See @ref sd_ble_evt_get for more information on how to use event structures with variable length array members. */
+} ble_gattc_evt_char_val_by_uuid_read_rsp_t;
+
+/**@brief Event structure for @ref BLE_GATTC_EVT_READ_RSP. */
+typedef struct
+{
+ uint16_t handle; /**< Attribute Handle. */
+ uint16_t offset; /**< Offset of the attribute data. */
+ uint16_t len; /**< Attribute data length. */
+ uint8_t data[1]; /**< Attribute data. @note This is a variable length array. The size of 1 indicated is only a placeholder for compilation.
+ See @ref sd_ble_evt_get for more information on how to use event structures with variable length array members. */
+} ble_gattc_evt_read_rsp_t;
+
+/**@brief Event structure for @ref BLE_GATTC_EVT_CHAR_VALS_READ_RSP. */
+typedef struct
+{
+ uint16_t len; /**< Concatenated Attribute values length. */
+ uint8_t values[1]; /**< Attribute values. @note This is a variable length array. The size of 1 indicated is only a placeholder for compilation.
+ See @ref sd_ble_evt_get for more information on how to use event structures with variable length array members. */
+} ble_gattc_evt_char_vals_read_rsp_t;
+
+/**@brief Event structure for @ref BLE_GATTC_EVT_WRITE_RSP. */
+typedef struct
+{
+ uint16_t handle; /**< Attribute Handle. */
+ uint8_t write_op; /**< Type of write operation, see @ref BLE_GATT_WRITE_OPS. */
+ uint16_t offset; /**< Data offset. */
+ uint16_t len; /**< Data length. */
+ uint8_t data[1]; /**< Data. @note This is a variable length array. The size of 1 indicated is only a placeholder for compilation.
+ See @ref sd_ble_evt_get for more information on how to use event structures with variable length array members. */
+} ble_gattc_evt_write_rsp_t;
+
+/**@brief Event structure for @ref BLE_GATTC_EVT_HVX. */
+typedef struct
+{
+ uint16_t handle; /**< Handle to which the HVx operation applies. */
+ uint8_t type; /**< Indication or Notification, see @ref BLE_GATT_HVX_TYPES. */
+ uint16_t len; /**< Attribute data length. */
+ uint8_t data[1]; /**< Attribute data. @note This is a variable length array. The size of 1 indicated is only a placeholder for compilation.
+ See @ref sd_ble_evt_get for more information on how to use event structures with variable length array members. */
+} ble_gattc_evt_hvx_t;
+
+/**@brief Event structure for @ref BLE_GATTC_EVT_EXCHANGE_MTU_RSP. */
+typedef struct
+{
+ uint16_t server_rx_mtu; /**< Server RX MTU size. */
+} ble_gattc_evt_exchange_mtu_rsp_t;
+
+/**@brief Event structure for @ref BLE_GATTC_EVT_TIMEOUT. */
+typedef struct
+{
+ uint8_t src; /**< Timeout source, see @ref BLE_GATT_TIMEOUT_SOURCES. */
+} ble_gattc_evt_timeout_t;
+
+/**@brief Event structure for @ref BLE_GATTC_EVT_WRITE_CMD_TX_COMPLETE. */
+typedef struct
+{
+ uint8_t count; /**< Number of write without response transmissions completed. */
+} ble_gattc_evt_write_cmd_tx_complete_t;
+
+/**@brief GATTC event structure. */
+typedef struct
+{
+ uint16_t conn_handle; /**< Connection Handle on which event occurred. */
+ uint16_t gatt_status; /**< GATT status code for the operation, see @ref BLE_GATT_STATUS_CODES. */
+ uint16_t error_handle; /**< In case of error: The handle causing the error. In all other cases @ref BLE_GATT_HANDLE_INVALID. */
+ union
+ {
+ ble_gattc_evt_prim_srvc_disc_rsp_t prim_srvc_disc_rsp; /**< Primary Service Discovery Response Event Parameters. */
+ ble_gattc_evt_rel_disc_rsp_t rel_disc_rsp; /**< Relationship Discovery Response Event Parameters. */
+ ble_gattc_evt_char_disc_rsp_t char_disc_rsp; /**< Characteristic Discovery Response Event Parameters. */
+ ble_gattc_evt_desc_disc_rsp_t desc_disc_rsp; /**< Descriptor Discovery Response Event Parameters. */
+ ble_gattc_evt_char_val_by_uuid_read_rsp_t char_val_by_uuid_read_rsp; /**< Characteristic Value Read by UUID Response Event Parameters. */
+ ble_gattc_evt_read_rsp_t read_rsp; /**< Read Response Event Parameters. */
+ ble_gattc_evt_char_vals_read_rsp_t char_vals_read_rsp; /**< Characteristic Values Read Response Event Parameters. */
+ ble_gattc_evt_write_rsp_t write_rsp; /**< Write Response Event Parameters. */
+ ble_gattc_evt_hvx_t hvx; /**< Handle Value Notification/Indication Event Parameters. */
+ ble_gattc_evt_exchange_mtu_rsp_t exchange_mtu_rsp; /**< Exchange MTU Response Event Parameters. */
+ ble_gattc_evt_timeout_t timeout; /**< Timeout Event Parameters. */
+ ble_gattc_evt_attr_info_disc_rsp_t attr_info_disc_rsp; /**< Attribute Information Discovery Event Parameters. */
+ ble_gattc_evt_write_cmd_tx_complete_t write_cmd_tx_complete; /**< Write without Response transmission complete Event Parameters. */
+ } params; /**< Event Parameters. @note Only valid if @ref gatt_status == @ref BLE_GATT_STATUS_SUCCESS. */
+} ble_gattc_evt_t;
+/** @} */
+
+/** @addtogroup BLE_GATTC_FUNCTIONS Functions
+ * @{ */
+
+/**@brief Initiate or continue a GATT Primary Service Discovery procedure.
+ *
+ * @details This function initiates or resumes a Primary Service discovery procedure, starting from the supplied handle.
+ * If the last service has not been reached, this function must be called again with an updated start handle value to continue the search.
+ *
+ * @note If any of the discovered services have 128-bit UUIDs which are not present in the table provided to ble_vs_uuids_assign, a UUID structure with
+ * type @ref BLE_UUID_TYPE_UNKNOWN will be received in the corresponding event.
+ *
+ * @events
+ * @event{@ref BLE_GATTC_EVT_PRIM_SRVC_DISC_RSP}
+ * @endevents
+ *
+ * @mscs
+ * @mmsc{@ref BLE_GATTC_PRIM_SRVC_DISC_MSC}
+ * @endmscs
+ *
+ * @param[in] conn_handle The connection handle identifying the connection to perform this procedure on.
+ * @param[in] start_handle Handle to start searching from.
+ * @param[in] p_srvc_uuid Pointer to the service UUID to be found. If it is NULL, all primary services will be returned.
+ *
+ * @retval ::NRF_SUCCESS Successfully started or resumed the Primary Service Discovery procedure.
+ * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid Connection Handle.
+ * @retval ::NRF_ERROR_INVALID_STATE Invalid Connection State.
+ * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied.
+ * @retval ::NRF_ERROR_BUSY Client procedure already in progress.
+ * @retval ::NRF_ERROR_TIMEOUT There has been a GATT procedure timeout. No new GATT procedure can be performed without reestablishing the connection.
+ */
+SVCALL(SD_BLE_GATTC_PRIMARY_SERVICES_DISCOVER, uint32_t, sd_ble_gattc_primary_services_discover(uint16_t conn_handle, uint16_t start_handle, ble_uuid_t const *p_srvc_uuid));
+
+
+/**@brief Initiate or continue a GATT Relationship Discovery procedure.
+ *
+ * @details This function initiates or resumes the Find Included Services sub-procedure. If the last included service has not been reached,
+ * this must be called again with an updated handle range to continue the search.
+ *
+ * @events
+ * @event{@ref BLE_GATTC_EVT_REL_DISC_RSP}
+ * @endevents
+ *
+ * @mscs
+ * @mmsc{@ref BLE_GATTC_REL_DISC_MSC}
+ * @endmscs
+ *
+ * @param[in] conn_handle The connection handle identifying the connection to perform this procedure on.
+ * @param[in] p_handle_range A pointer to the range of handles of the Service to perform this procedure on.
+ *
+ * @retval ::NRF_SUCCESS Successfully started or resumed the Relationship Discovery procedure.
+ * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid Connection Handle.
+ * @retval ::NRF_ERROR_INVALID_STATE Invalid Connection State.
+ * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied.
+ * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied.
+ * @retval ::NRF_ERROR_BUSY Client procedure already in progress.
+ * @retval ::NRF_ERROR_TIMEOUT There has been a GATT procedure timeout. No new GATT procedure can be performed without reestablishing the connection.
+ */
+SVCALL(SD_BLE_GATTC_RELATIONSHIPS_DISCOVER, uint32_t, sd_ble_gattc_relationships_discover(uint16_t conn_handle, ble_gattc_handle_range_t const *p_handle_range));
+
+
+/**@brief Initiate or continue a GATT Characteristic Discovery procedure.
+ *
+ * @details This function initiates or resumes a Characteristic discovery procedure. If the last Characteristic has not been reached,
+ * this must be called again with an updated handle range to continue the discovery.
+ *
+ * @note If any of the discovered characteristics have 128-bit UUIDs which are not present in the table provided to ble_vs_uuids_assign, a UUID structure with
+ * type @ref BLE_UUID_TYPE_UNKNOWN will be received in the corresponding event.
+ *
+ * @events
+ * @event{@ref BLE_GATTC_EVT_CHAR_DISC_RSP}
+ * @endevents
+ *
+ * @mscs
+ * @mmsc{@ref BLE_GATTC_CHAR_DISC_MSC}
+ * @endmscs
+ *
+ * @param[in] conn_handle The connection handle identifying the connection to perform this procedure on.
+ * @param[in] p_handle_range A pointer to the range of handles of the Service to perform this procedure on.
+ *
+ * @retval ::NRF_SUCCESS Successfully started or resumed the Characteristic Discovery procedure.
+ * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid Connection Handle.
+ * @retval ::NRF_ERROR_INVALID_STATE Invalid Connection State.
+ * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied.
+ * @retval ::NRF_ERROR_BUSY Client procedure already in progress.
+ * @retval ::NRF_ERROR_TIMEOUT There has been a GATT procedure timeout. No new GATT procedure can be performed without reestablishing the connection.
+ */
+SVCALL(SD_BLE_GATTC_CHARACTERISTICS_DISCOVER, uint32_t, sd_ble_gattc_characteristics_discover(uint16_t conn_handle, ble_gattc_handle_range_t const *p_handle_range));
+
+
+/**@brief Initiate or continue a GATT Characteristic Descriptor Discovery procedure.
+ *
+ * @details This function initiates or resumes a Characteristic Descriptor discovery procedure. If the last Descriptor has not been reached,
+ * this must be called again with an updated handle range to continue the discovery.
+ *
+ * @events
+ * @event{@ref BLE_GATTC_EVT_DESC_DISC_RSP}
+ * @endevents
+ *
+ * @mscs
+ * @mmsc{@ref BLE_GATTC_DESC_DISC_MSC}
+ * @endmscs
+ *
+ * @param[in] conn_handle The connection handle identifying the connection to perform this procedure on.
+ * @param[in] p_handle_range A pointer to the range of handles of the Characteristic to perform this procedure on.
+ *
+ * @retval ::NRF_SUCCESS Successfully started or resumed the Descriptor Discovery procedure.
+ * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid Connection Handle.
+ * @retval ::NRF_ERROR_INVALID_STATE Invalid Connection State.
+ * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied.
+ * @retval ::NRF_ERROR_BUSY Client procedure already in progress.
+ * @retval ::NRF_ERROR_TIMEOUT There has been a GATT procedure timeout. No new GATT procedure can be performed without reestablishing the connection.
+ */
+SVCALL(SD_BLE_GATTC_DESCRIPTORS_DISCOVER, uint32_t, sd_ble_gattc_descriptors_discover(uint16_t conn_handle, ble_gattc_handle_range_t const *p_handle_range));
+
+
+/**@brief Initiate or continue a GATT Read using Characteristic UUID procedure.
+ *
+ * @details This function initiates or resumes a Read using Characteristic UUID procedure. If the last Characteristic has not been reached,
+ * this must be called again with an updated handle range to continue the discovery.
+ *
+ * @events
+ * @event{@ref BLE_GATTC_EVT_CHAR_VAL_BY_UUID_READ_RSP}
+ * @endevents
+ *
+ * @mscs
+ * @mmsc{@ref BLE_GATTC_READ_UUID_MSC}
+ * @endmscs
+ *
+ * @param[in] conn_handle The connection handle identifying the connection to perform this procedure on.
+ * @param[in] p_uuid Pointer to a Characteristic value UUID to read.
+ * @param[in] p_handle_range A pointer to the range of handles to perform this procedure on.
+ *
+ * @retval ::NRF_SUCCESS Successfully started or resumed the Read using Characteristic UUID procedure.
+ * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid Connection Handle.
+ * @retval ::NRF_ERROR_INVALID_STATE Invalid Connection State.
+ * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied.
+ * @retval ::NRF_ERROR_BUSY Client procedure already in progress.
+ * @retval ::NRF_ERROR_TIMEOUT There has been a GATT procedure timeout. No new GATT procedure can be performed without reestablishing the connection.
+ */
+SVCALL(SD_BLE_GATTC_CHAR_VALUE_BY_UUID_READ, uint32_t, sd_ble_gattc_char_value_by_uuid_read(uint16_t conn_handle, ble_uuid_t const *p_uuid, ble_gattc_handle_range_t const *p_handle_range));
+
+
+/**@brief Initiate or continue a GATT Read (Long) Characteristic or Descriptor procedure.
+ *
+ * @details This function initiates or resumes a GATT Read (Long) Characteristic or Descriptor procedure. If the Characteristic or Descriptor
+ * to be read is longer than ATT_MTU - 1, this function must be called multiple times with appropriate offset to read the
+ * complete value.
+ *
+ * @events
+ * @event{@ref BLE_GATTC_EVT_READ_RSP}
+ * @endevents
+ *
+ * @mscs
+ * @mmsc{@ref BLE_GATTC_VALUE_READ_MSC}
+ * @endmscs
+ *
+ * @param[in] conn_handle The connection handle identifying the connection to perform this procedure on.
+ * @param[in] handle The handle of the attribute to be read.
+ * @param[in] offset Offset into the attribute value to be read.
+ *
+ * @retval ::NRF_SUCCESS Successfully started or resumed the Read (Long) procedure.
+ * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid Connection Handle.
+ * @retval ::NRF_ERROR_INVALID_STATE Invalid Connection State.
+ * @retval ::NRF_ERROR_BUSY Client procedure already in progress.
+ * @retval ::NRF_ERROR_TIMEOUT There has been a GATT procedure timeout. No new GATT procedure can be performed without reestablishing the connection.
+ */
+SVCALL(SD_BLE_GATTC_READ, uint32_t, sd_ble_gattc_read(uint16_t conn_handle, uint16_t handle, uint16_t offset));
+
+
+/**@brief Initiate a GATT Read Multiple Characteristic Values procedure.
+ *
+ * @details This function initiates a GATT Read Multiple Characteristic Values procedure.
+ *
+ * @events
+ * @event{@ref BLE_GATTC_EVT_CHAR_VALS_READ_RSP}
+ * @endevents
+ *
+ * @mscs
+ * @mmsc{@ref BLE_GATTC_READ_MULT_MSC}
+ * @endmscs
+ *
+ * @param[in] conn_handle The connection handle identifying the connection to perform this procedure on.
+ * @param[in] p_handles A pointer to the handle(s) of the attribute(s) to be read.
+ * @param[in] handle_count The number of handles in p_handles.
+ *
+ * @retval ::NRF_SUCCESS Successfully started the Read Multiple Characteristic Values procedure.
+ * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid Connection Handle.
+ * @retval ::NRF_ERROR_INVALID_STATE Invalid Connection State.
+ * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied.
+ * @retval ::NRF_ERROR_BUSY Client procedure already in progress.
+ * @retval ::NRF_ERROR_TIMEOUT There has been a GATT procedure timeout. No new GATT procedure can be performed without reestablishing the connection.
+ */
+SVCALL(SD_BLE_GATTC_CHAR_VALUES_READ, uint32_t, sd_ble_gattc_char_values_read(uint16_t conn_handle, uint16_t const *p_handles, uint16_t handle_count));
+
+
+/**@brief Perform a Write (Characteristic Value or Descriptor, with or without response, signed or not, long or reliable) procedure.
+ *
+ * @details This function can perform all write procedures described in GATT.
+ *
+ * @note Only one write with response procedure can be ongoing per connection at a time.
+ * If the application tries to write with response while another write with response procedure is ongoing,
+ * the function call will return @ref NRF_ERROR_BUSY.
+ * A @ref BLE_GATTC_EVT_WRITE_RSP event will be issued as soon as the write response arrives from the peer.
+ *
+ * @note The number of Write without Response that can be queued is configured by @ref ble_gattc_conn_cfg_t::write_cmd_tx_queue_size
+ * When the queue is full, the function call will return @ref NRF_ERROR_RESOURCES.
+ * A @ref BLE_GATTC_EVT_WRITE_CMD_TX_COMPLETE event will be issued as soon as the transmission of the write without response is complete.
+ *
+ * @note The application can keep track of the available queue element count for writes without responses by following the procedure below:
+ * - Store initial queue element count in a variable.
+ * - Decrement the variable, which stores the currently available queue element count, by one when a call to this function returns @ref NRF_SUCCESS.
+ * - Increment the variable, which stores the current available queue element count, by the count variable in @ref BLE_GATTC_EVT_WRITE_CMD_TX_COMPLETE event.
+ *
+ * @events
+ * @event{@ref BLE_GATTC_EVT_WRITE_CMD_TX_COMPLETE, Write without response transmission complete.}
+ * @event{@ref BLE_GATTC_EVT_WRITE_RSP, Write response received from the peer.}
+ * @endevents
+ *
+ * @mscs
+ * @mmsc{@ref BLE_GATTC_VALUE_WRITE_WITHOUT_RESP_MSC}
+ * @mmsc{@ref BLE_GATTC_VALUE_WRITE_MSC}
+ * @mmsc{@ref BLE_GATTC_VALUE_LONG_WRITE_MSC}
+ * @mmsc{@ref BLE_GATTC_VALUE_RELIABLE_WRITE_MSC}
+ * @endmscs
+ *
+ * @param[in] conn_handle The connection handle identifying the connection to perform this procedure on.
+ * @param[in] p_write_params A pointer to a write parameters structure.
+ *
+ * @retval ::NRF_SUCCESS Successfully started the Write procedure.
+ * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid Connection Handle.
+ * @retval ::NRF_ERROR_INVALID_STATE Invalid Connection State.
+ * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied.
+ * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied.
+ * @retval ::NRF_ERROR_DATA_SIZE Invalid data size(s) supplied.
+ * @retval ::NRF_ERROR_BUSY For write with response, procedure already in progress. Wait for a @ref BLE_GATTC_EVT_WRITE_RSP event and retry.
+ * @retval ::NRF_ERROR_RESOURCES Too many writes without responses queued.
+ * Wait for a @ref BLE_GATTC_EVT_WRITE_CMD_TX_COMPLETE event and retry.
+ * @retval ::NRF_ERROR_TIMEOUT There has been a GATT procedure timeout. No new GATT procedure can be performed without reestablishing the connection.
+ */
+SVCALL(SD_BLE_GATTC_WRITE, uint32_t, sd_ble_gattc_write(uint16_t conn_handle, ble_gattc_write_params_t const *p_write_params));
+
+
+/**@brief Send a Handle Value Confirmation to the GATT Server.
+ *
+ * @mscs
+ * @mmsc{@ref BLE_GATTC_HVI_MSC}
+ * @endmscs
+ *
+ * @param[in] conn_handle The connection handle identifying the connection to perform this procedure on.
+ * @param[in] handle The handle of the attribute in the indication.
+ *
+ * @retval ::NRF_SUCCESS Successfully queued the Handle Value Confirmation for transmission.
+ * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid Connection Handle.
+ * @retval ::NRF_ERROR_INVALID_STATE Invalid Connection State or no Indication pending to be confirmed.
+ * @retval ::BLE_ERROR_INVALID_ATTR_HANDLE Invalid attribute handle.
+ * @retval ::NRF_ERROR_TIMEOUT There has been a GATT procedure timeout. No new GATT procedure can be performed without reestablishing the connection.
+ */
+SVCALL(SD_BLE_GATTC_HV_CONFIRM, uint32_t, sd_ble_gattc_hv_confirm(uint16_t conn_handle, uint16_t handle));
+
+/**@brief Discovers information about a range of attributes on a GATT server.
+ *
+ * @events
+ * @event{@ref BLE_GATTC_EVT_ATTR_INFO_DISC_RSP, Generated when information about a range of attributes has been received.}
+ * @endevents
+ *
+ * @param[in] conn_handle The connection handle identifying the connection to perform this procedure on.
+ * @param[in] p_handle_range The range of handles to request information about.
+ *
+ * @retval ::NRF_SUCCESS Successfully started an attribute information discovery procedure.
+ * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid connection handle.
+ * @retval ::NRF_ERROR_INVALID_STATE Invalid connection state
+ * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied.
+ * @retval ::NRF_ERROR_BUSY Client procedure already in progress.
+ * @retval ::NRF_ERROR_TIMEOUT There has been a GATT procedure timeout. No new GATT procedure can be performed without reestablishing the connection.
+ */
+SVCALL(SD_BLE_GATTC_ATTR_INFO_DISCOVER, uint32_t, sd_ble_gattc_attr_info_discover(uint16_t conn_handle, ble_gattc_handle_range_t const * p_handle_range));
+
+/**@brief Start an ATT_MTU exchange by sending an Exchange MTU Request to the server.
+ *
+ * @details The SoftDevice sets ATT_MTU to the minimum of:
+ * - The Client RX MTU value, and
+ * - The Server RX MTU value from @ref BLE_GATTC_EVT_EXCHANGE_MTU_RSP.
+ *
+ * However, the SoftDevice never sets ATT_MTU lower than @ref BLE_GATT_ATT_MTU_DEFAULT.
+ *
+ * @events
+ * @event{@ref BLE_GATTC_EVT_EXCHANGE_MTU_RSP}
+ * @endevents
+ *
+ * @mscs
+ * @mmsc{@ref BLE_GATTC_MTU_EXCHANGE}
+ * @endmscs
+ *
+ * @param[in] conn_handle The connection handle identifying the connection to perform this procedure on.
+ * @param[in] client_rx_mtu Client RX MTU size.
+ * - The minimum value is @ref BLE_GATT_ATT_MTU_DEFAULT.
+ * - The maximum value is @ref ble_gatt_conn_cfg_t::att_mtu in the connection configuration
+ used for this connection.
+ * - The value must be equal to Server RX MTU size given in @ref sd_ble_gatts_exchange_mtu_reply
+ * if an ATT_MTU exchange has already been performed in the other direction.
+ *
+ * @retval ::NRF_SUCCESS Successfully sent request to the server.
+ * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid connection handle.
+ * @retval ::NRF_ERROR_INVALID_STATE Invalid connection state or an ATT_MTU exchange was already requested once.
+ * @retval ::NRF_ERROR_INVALID_PARAM Invalid Client RX MTU size supplied.
+ * @retval ::NRF_ERROR_BUSY Client procedure already in progress.
+ * @retval ::NRF_ERROR_TIMEOUT There has been a GATT procedure timeout. No new GATT procedure can be performed without reestablishing the connection.
+ */
+SVCALL(SD_BLE_GATTC_EXCHANGE_MTU_REQUEST, uint32_t, sd_ble_gattc_exchange_mtu_request(uint16_t conn_handle, uint16_t client_rx_mtu));
+
+/**@brief Iterate through Handle-Value(s) list in @ref BLE_GATTC_EVT_CHAR_VAL_BY_UUID_READ_RSP event.
+ *
+ * @param[in] p_gattc_evt Pointer to event buffer containing @ref BLE_GATTC_EVT_CHAR_VAL_BY_UUID_READ_RSP event.
+ * @note If the buffer contains different event, behavior is undefined.
+ * @param[in,out] p_iter Iterator, points to @ref ble_gattc_handle_value_t structure that will be filled in with
+ * the next Handle-Value pair in each iteration. If the function returns other than
+ * @ref NRF_SUCCESS, it will not be changed.
+ * - To start iteration, initialize the structure to zero.
+ * - To continue, pass the value from previous iteration.
+ *
+ * \code
+ * ble_gattc_handle_value_t iter;
+ * memset(&iter, 0, sizeof(ble_gattc_handle_value_t));
+ * while (sd_ble_gattc_evt_char_val_by_uuid_read_rsp_iter(&ble_evt.evt.gattc_evt, &iter) == NRF_SUCCESS)
+ * {
+ * app_handle = iter.handle;
+ * memcpy(app_value, iter.p_value, ble_evt.evt.gattc_evt.params.char_val_by_uuid_read_rsp.value_len);
+ * }
+ * \endcode
+ *
+ * @retval ::NRF_SUCCESS Successfully retrieved the next Handle-Value pair.
+ * @retval ::NRF_ERROR_NOT_FOUND No more Handle-Value pairs available in the list.
+ */
+__STATIC_INLINE uint32_t sd_ble_gattc_evt_char_val_by_uuid_read_rsp_iter(ble_gattc_evt_t *p_gattc_evt, ble_gattc_handle_value_t *p_iter);
+
+/** @} */
+
+#ifndef SUPPRESS_INLINE_IMPLEMENTATION
+
+__STATIC_INLINE uint32_t sd_ble_gattc_evt_char_val_by_uuid_read_rsp_iter(ble_gattc_evt_t *p_gattc_evt, ble_gattc_handle_value_t *p_iter)
+{
+ uint32_t value_len = p_gattc_evt->params.char_val_by_uuid_read_rsp.value_len;
+ uint8_t *p_first = p_gattc_evt->params.char_val_by_uuid_read_rsp.handle_value;
+ uint8_t *p_next = p_iter->p_value ? p_iter->p_value + value_len : p_first;
+
+ if ((p_next - p_first) / (sizeof(uint16_t) + value_len) < p_gattc_evt->params.char_val_by_uuid_read_rsp.count)
+ {
+ p_iter->handle = (uint16_t)p_next[1] << 8 | p_next[0];
+ p_iter->p_value = p_next + sizeof(uint16_t);
+ return NRF_SUCCESS;
+ }
+ else
+ {
+ return NRF_ERROR_NOT_FOUND;
+ }
+}
+
+#endif /* SUPPRESS_INLINE_IMPLEMENTATION */
+
+#ifdef __cplusplus
+}
+#endif
+#endif /* BLE_GATTC_H__ */
+
+/**
+ @}
+*/
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/softdevice/s140/headers/ble_gatts.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/softdevice/s140/headers/ble_gatts.h
new file mode 100644
index 0000000..e437b6e
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/softdevice/s140/headers/ble_gatts.h
@@ -0,0 +1,845 @@
+/*
+ * Copyright (c) 2011 - 2017, 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ */
+
+/**
+ @addtogroup BLE_GATTS Generic Attribute Profile (GATT) Server
+ @{
+ @brief Definitions and prototypes for the GATTS interface.
+ */
+
+#ifndef BLE_GATTS_H__
+#define BLE_GATTS_H__
+
+#include <stdint.h>
+#include "nrf_svc.h"
+#include "nrf_error.h"
+#include "ble_hci.h"
+#include "ble_ranges.h"
+#include "ble_types.h"
+#include "ble_err.h"
+#include "ble_gatt.h"
+#include "ble_gap.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** @addtogroup BLE_GATTS_ENUMERATIONS Enumerations
+ * @{ */
+
+/**
+ * @brief GATTS API SVC numbers.
+ */
+enum BLE_GATTS_SVCS
+{
+ SD_BLE_GATTS_SERVICE_ADD = BLE_GATTS_SVC_BASE, /**< Add a service. */
+ SD_BLE_GATTS_INCLUDE_ADD, /**< Add an included service. */
+ SD_BLE_GATTS_CHARACTERISTIC_ADD, /**< Add a characteristic. */
+ SD_BLE_GATTS_DESCRIPTOR_ADD, /**< Add a generic attribute. */
+ SD_BLE_GATTS_VALUE_SET, /**< Set an attribute value. */
+ SD_BLE_GATTS_VALUE_GET, /**< Get an attribute value. */
+ SD_BLE_GATTS_HVX, /**< Handle Value Notification or Indication. */
+ SD_BLE_GATTS_SERVICE_CHANGED, /**< Perform a Service Changed Indication to one or more peers. */
+ SD_BLE_GATTS_RW_AUTHORIZE_REPLY, /**< Reply to an authorization request for a read or write operation on one or more attributes. */
+ SD_BLE_GATTS_SYS_ATTR_SET, /**< Set the persistent system attributes for a connection. */
+ SD_BLE_GATTS_SYS_ATTR_GET, /**< Retrieve the persistent system attributes. */
+ SD_BLE_GATTS_INITIAL_USER_HANDLE_GET, /**< Retrieve the first valid user handle. */
+ SD_BLE_GATTS_ATTR_GET, /**< Retrieve the UUID and/or metadata of an attribute. */
+ SD_BLE_GATTS_EXCHANGE_MTU_REPLY /**< Reply to Exchange MTU Request. */
+};
+
+/**
+ * @brief GATT Server Event IDs.
+ */
+enum BLE_GATTS_EVTS
+{
+ BLE_GATTS_EVT_WRITE = BLE_GATTS_EVT_BASE, /**< Write operation performed. \n See @ref ble_gatts_evt_write_t. */
+ BLE_GATTS_EVT_RW_AUTHORIZE_REQUEST, /**< Read/Write Authorization request. \n Reply with @ref sd_ble_gatts_rw_authorize_reply. \n See @ref ble_gatts_evt_rw_authorize_request_t. */
+ BLE_GATTS_EVT_SYS_ATTR_MISSING, /**< A persistent system attribute access is pending. \n Respond with @ref sd_ble_gatts_sys_attr_set. \n See @ref ble_gatts_evt_sys_attr_missing_t. */
+ BLE_GATTS_EVT_HVC, /**< Handle Value Confirmation. \n See @ref ble_gatts_evt_hvc_t. */
+ BLE_GATTS_EVT_SC_CONFIRM, /**< Service Changed Confirmation. \n No additional event structure applies. */
+ BLE_GATTS_EVT_EXCHANGE_MTU_REQUEST, /**< Exchange MTU Request. \n Reply with @ref sd_ble_gatts_exchange_mtu_reply. \n See @ref ble_gatts_evt_exchange_mtu_request_t. */
+ BLE_GATTS_EVT_TIMEOUT, /**< Peer failed to respond to an ATT request in time. \n See @ref ble_gatts_evt_timeout_t. */
+ BLE_GATTS_EVT_HVN_TX_COMPLETE /**< Handle Value Notification transmission complete. \n See @ref ble_gatts_evt_hvn_tx_complete_t. */
+};
+
+/**@brief GATTS Configuration IDs.
+ *
+ * IDs that uniquely identify a GATTS configuration.
+ */
+enum BLE_GATTS_CFGS
+{
+ BLE_GATTS_CFG_SERVICE_CHANGED = BLE_GATTS_CFG_BASE, /**< Service changed configuration. */
+ BLE_GATTS_CFG_ATTR_TAB_SIZE, /**< Attribute table size configuration. */
+};
+
+/** @} */
+
+/** @addtogroup BLE_GATTS_DEFINES Defines
+ * @{ */
+
+/** @defgroup BLE_ERRORS_GATTS SVC return values specific to GATTS
+ * @{ */
+#define BLE_ERROR_GATTS_INVALID_ATTR_TYPE (NRF_GATTS_ERR_BASE + 0x000) /**< Invalid attribute type. */
+#define BLE_ERROR_GATTS_SYS_ATTR_MISSING (NRF_GATTS_ERR_BASE + 0x001) /**< System Attributes missing. */
+/** @} */
+
+/** @defgroup BLE_GATTS_ATTR_LENS_MAX Maximum attribute lengths
+ * @{ */
+#define BLE_GATTS_FIX_ATTR_LEN_MAX (510) /**< Maximum length for fixed length Attribute Values. */
+#define BLE_GATTS_VAR_ATTR_LEN_MAX (512) /**< Maximum length for variable length Attribute Values. */
+/** @} */
+
+/** @defgroup BLE_GATTS_SRVC_TYPES GATT Server Service Types
+ * @{ */
+#define BLE_GATTS_SRVC_TYPE_INVALID 0x00 /**< Invalid Service Type. */
+#define BLE_GATTS_SRVC_TYPE_PRIMARY 0x01 /**< Primary Service. */
+#define BLE_GATTS_SRVC_TYPE_SECONDARY 0x02 /**< Secondary Type. */
+/** @} */
+
+
+/** @defgroup BLE_GATTS_ATTR_TYPES GATT Server Attribute Types
+ * @{ */
+#define BLE_GATTS_ATTR_TYPE_INVALID 0x00 /**< Invalid Attribute Type. */
+#define BLE_GATTS_ATTR_TYPE_PRIM_SRVC_DECL 0x01 /**< Primary Service Declaration. */
+#define BLE_GATTS_ATTR_TYPE_SEC_SRVC_DECL 0x02 /**< Secondary Service Declaration. */
+#define BLE_GATTS_ATTR_TYPE_INC_DECL 0x03 /**< Include Declaration. */
+#define BLE_GATTS_ATTR_TYPE_CHAR_DECL 0x04 /**< Characteristic Declaration. */
+#define BLE_GATTS_ATTR_TYPE_CHAR_VAL 0x05 /**< Characteristic Value. */
+#define BLE_GATTS_ATTR_TYPE_DESC 0x06 /**< Descriptor. */
+#define BLE_GATTS_ATTR_TYPE_OTHER 0x07 /**< Other, non-GATT specific type. */
+/** @} */
+
+
+/** @defgroup BLE_GATTS_OPS GATT Server Operations
+ * @{ */
+#define BLE_GATTS_OP_INVALID 0x00 /**< Invalid Operation. */
+#define BLE_GATTS_OP_WRITE_REQ 0x01 /**< Write Request. */
+#define BLE_GATTS_OP_WRITE_CMD 0x02 /**< Write Command. */
+#define BLE_GATTS_OP_SIGN_WRITE_CMD 0x03 /**< Signed Write Command. */
+#define BLE_GATTS_OP_PREP_WRITE_REQ 0x04 /**< Prepare Write Request. */
+#define BLE_GATTS_OP_EXEC_WRITE_REQ_CANCEL 0x05 /**< Execute Write Request: Cancel all prepared writes. */
+#define BLE_GATTS_OP_EXEC_WRITE_REQ_NOW 0x06 /**< Execute Write Request: Immediately execute all prepared writes. */
+/** @} */
+
+/** @defgroup BLE_GATTS_VLOCS GATT Value Locations
+ * @{ */
+#define BLE_GATTS_VLOC_INVALID 0x00 /**< Invalid Location. */
+#define BLE_GATTS_VLOC_STACK 0x01 /**< Attribute Value is located in stack memory, no user memory is required. */
+#define BLE_GATTS_VLOC_USER 0x02 /**< Attribute Value is located in user memory. This requires the user to maintain a valid buffer through the lifetime of the attribute, since the stack
+ will read and write directly to the memory using the pointer provided in the APIs. There are no alignment requirements for the buffer. */
+/** @} */
+
+/** @defgroup BLE_GATTS_AUTHORIZE_TYPES GATT Server Authorization Types
+ * @{ */
+#define BLE_GATTS_AUTHORIZE_TYPE_INVALID 0x00 /**< Invalid Type. */
+#define BLE_GATTS_AUTHORIZE_TYPE_READ 0x01 /**< Authorize a Read Operation. */
+#define BLE_GATTS_AUTHORIZE_TYPE_WRITE 0x02 /**< Authorize a Write Request Operation. */
+/** @} */
+
+/** @defgroup BLE_GATTS_SYS_ATTR_FLAGS System Attribute Flags
+ * @{ */
+#define BLE_GATTS_SYS_ATTR_FLAG_SYS_SRVCS (1 << 0) /**< Restrict system attributes to system services only. */
+#define BLE_GATTS_SYS_ATTR_FLAG_USR_SRVCS (1 << 1) /**< Restrict system attributes to user services only. */
+/** @} */
+
+/** @defgroup BLE_GATTS_SERVICE_CHANGED Service Changed Inclusion Values
+ * @{
+ */
+#define BLE_GATTS_SERVICE_CHANGED_DEFAULT (1) /**< Default is to include the Service Changed characteristic in the Attribute Table. */
+/** @} */
+
+/** @defgroup BLE_GATTS_ATTR_TAB_SIZE Attribute Table size
+ * @{
+ */
+#define BLE_GATTS_ATTR_TAB_SIZE_MIN (248) /**< Minimum Attribute Table size */
+#define BLE_GATTS_ATTR_TAB_SIZE_DEFAULT (1408) /**< Default Attribute Table size. */
+/** @} */
+
+/** @defgroup BLE_GATTS_DEFAULTS GATT Server defaults
+ * @{
+ */
+#define BLE_GATTS_HVN_TX_QUEUE_SIZE_DEFAULT 1 /**< Default number of Handle Value Notifications that can be queued for transmission. */
+/** @} */
+
+/** @} */
+
+/** @addtogroup BLE_GATTS_STRUCTURES Structures
+ * @{ */
+
+/**
+ * @brief BLE GATTS connection configuration parameters, set with @ref sd_ble_cfg_set.
+ */
+typedef struct
+{
+ uint8_t hvn_tx_queue_size; /**< Minimum guaranteed number of Handle Value Notifications that can be queued for transmission.
+ The default value is @ref BLE_GATTS_HVN_TX_QUEUE_SIZE_DEFAULT */
+} ble_gatts_conn_cfg_t;
+
+/**@brief Attribute metadata. */
+typedef struct
+{
+ ble_gap_conn_sec_mode_t read_perm; /**< Read permissions. */
+ ble_gap_conn_sec_mode_t write_perm; /**< Write permissions. */
+ uint8_t vlen :1; /**< Variable length attribute. */
+ uint8_t vloc :2; /**< Value location, see @ref BLE_GATTS_VLOCS.*/
+ uint8_t rd_auth :1; /**< Read authorization and value will be requested from the application on every read operation. */
+ uint8_t wr_auth :1; /**< Write authorization will be requested from the application on every Write Request operation (but not Write Command). */
+} ble_gatts_attr_md_t;
+
+
+/**@brief GATT Attribute. */
+typedef struct
+{
+ ble_uuid_t const *p_uuid; /**< Pointer to the attribute UUID. */
+ ble_gatts_attr_md_t const *p_attr_md; /**< Pointer to the attribute metadata structure. */
+ uint16_t init_len; /**< Initial attribute value length in bytes. */
+ uint16_t init_offs; /**< Initial attribute value offset in bytes. If different from zero, the first init_offs bytes of the attribute value will be left uninitialized. */
+ uint16_t max_len; /**< Maximum attribute value length in bytes, see @ref BLE_GATTS_ATTR_LENS_MAX for maximum values. */
+ uint8_t *p_value; /**< Pointer to the attribute data. Please note that if the @ref BLE_GATTS_VLOC_USER value location is selected in the attribute metadata, this will have to point to a buffer
+ that remains valid through the lifetime of the attribute. This excludes usage of automatic variables that may go out of scope or any other temporary location.
+ The stack may access that memory directly without the application's knowledge. For writable characteristics, this value must not be a location in flash memory.*/
+} ble_gatts_attr_t;
+
+/**@brief GATT Attribute Value. */
+typedef struct
+{
+ uint16_t len; /**< Length in bytes to be written or read. Length in bytes written or read after successful return.*/
+ uint16_t offset; /**< Attribute value offset. */
+ uint8_t *p_value; /**< Pointer to where value is stored or will be stored.
+ If value is stored in user memory, only the attribute length is updated when p_value == NULL.
+ Set to NULL when reading to obtain the complete length of the attribute value */
+} ble_gatts_value_t;
+
+
+/**@brief GATT Characteristic Presentation Format. */
+typedef struct
+{
+ uint8_t format; /**< Format of the value, see @ref BLE_GATT_CPF_FORMATS. */
+ int8_t exponent; /**< Exponent for integer data types. */
+ uint16_t unit; /**< Unit from Bluetooth Assigned Numbers. */
+ uint8_t name_space; /**< Namespace from Bluetooth Assigned Numbers, see @ref BLE_GATT_CPF_NAMESPACES. */
+ uint16_t desc; /**< Namespace description from Bluetooth Assigned Numbers, see @ref BLE_GATT_CPF_NAMESPACES. */
+} ble_gatts_char_pf_t;
+
+
+/**@brief GATT Characteristic metadata. */
+typedef struct
+{
+ ble_gatt_char_props_t char_props; /**< Characteristic Properties. */
+ ble_gatt_char_ext_props_t char_ext_props; /**< Characteristic Extended Properties. */
+ uint8_t const *p_char_user_desc; /**< Pointer to a UTF-8 encoded string (non-NULL terminated), NULL if the descriptor is not required. */
+ uint16_t char_user_desc_max_size; /**< The maximum size in bytes of the user description descriptor. */
+ uint16_t char_user_desc_size; /**< The size of the user description, must be smaller or equal to char_user_desc_max_size. */
+ ble_gatts_char_pf_t const *p_char_pf; /**< Pointer to a presentation format structure or NULL if the CPF descriptor is not required. */
+ ble_gatts_attr_md_t const *p_user_desc_md; /**< Attribute metadata for the User Description descriptor, or NULL for default values. */
+ ble_gatts_attr_md_t const *p_cccd_md; /**< Attribute metadata for the Client Characteristic Configuration Descriptor, or NULL for default values. */
+ ble_gatts_attr_md_t const *p_sccd_md; /**< Attribute metadata for the Server Characteristic Configuration Descriptor, or NULL for default values. */
+} ble_gatts_char_md_t;
+
+
+/**@brief GATT Characteristic Definition Handles. */
+typedef struct
+{
+ uint16_t value_handle; /**< Handle to the characteristic value. */
+ uint16_t user_desc_handle; /**< Handle to the User Description descriptor, or @ref BLE_GATT_HANDLE_INVALID if not present. */
+ uint16_t cccd_handle; /**< Handle to the Client Characteristic Configuration Descriptor, or @ref BLE_GATT_HANDLE_INVALID if not present. */
+ uint16_t sccd_handle; /**< Handle to the Server Characteristic Configuration Descriptor, or @ref BLE_GATT_HANDLE_INVALID if not present. */
+} ble_gatts_char_handles_t;
+
+
+/**@brief GATT HVx parameters. */
+typedef struct
+{
+ uint16_t handle; /**< Characteristic Value Handle. */
+ uint8_t type; /**< Indication or Notification, see @ref BLE_GATT_HVX_TYPES. */
+ uint16_t offset; /**< Offset within the attribute value. */
+ uint16_t *p_len; /**< Length in bytes to be written, length in bytes written after return. */
+ uint8_t const *p_data; /**< Actual data content, use NULL to use the current attribute value. */
+} ble_gatts_hvx_params_t;
+
+/**@brief GATT Authorization parameters. */
+typedef struct
+{
+ uint16_t gatt_status; /**< GATT status code for the operation, see @ref BLE_GATT_STATUS_CODES. */
+ uint8_t update : 1; /**< If set, data supplied in p_data will be used to update the attribute value.
+ Please note that for @ref BLE_GATTS_AUTHORIZE_TYPE_WRITE operations this bit must always be set,
+ as the data to be written needs to be stored and later provided by the application. */
+ uint16_t offset; /**< Offset of the attribute value being updated. */
+ uint16_t len; /**< Length in bytes of the value in p_data pointer, see @ref BLE_GATTS_ATTR_LENS_MAX. */
+ uint8_t const *p_data; /**< Pointer to new value used to update the attribute value. */
+} ble_gatts_authorize_params_t;
+
+/**@brief GATT Read or Write Authorize Reply parameters. */
+typedef struct
+{
+ uint8_t type; /**< Type of authorize operation, see @ref BLE_GATTS_AUTHORIZE_TYPES. */
+ union {
+ ble_gatts_authorize_params_t read; /**< Read authorization parameters. */
+ ble_gatts_authorize_params_t write; /**< Write authorization parameters. */
+ } params; /**< Reply Parameters. */
+} ble_gatts_rw_authorize_reply_params_t;
+
+/**@brief Service Changed Inclusion configuration parameters, set with @ref sd_ble_cfg_set. */
+typedef struct
+{
+ uint8_t service_changed : 1; /**< If 1, include the Service Changed characteristic in the Attribute Table. Default is @ref BLE_GATTS_SERVICE_CHANGED_DEFAULT. */
+} ble_gatts_cfg_service_changed_t;
+
+/**@brief Attribute table size configuration parameters, set with @ref sd_ble_cfg_set.
+ *
+ * @retval ::NRF_ERROR_INVALID_LENGTH One or more of the following is true:
+ * - The specified Attribute Table size is too small.
+ * The minimum acceptable size is defined by @ref BLE_GATTS_ATTR_TAB_SIZE_MIN.
+ * - The specified Attribute Table size is not a multiple of 4.
+ */
+typedef struct
+{
+ uint32_t attr_tab_size; /**< Attribute table size. Default is @ref BLE_GATTS_ATTR_TAB_SIZE_DEFAULT, minimum is @ref BLE_GATTS_ATTR_TAB_SIZE_MIN. */
+} ble_gatts_cfg_attr_tab_size_t;
+
+/**@brief Config structure for GATTS configurations. */
+typedef union
+{
+ ble_gatts_cfg_service_changed_t service_changed; /**< Include service changed characteristic, cfg_id is @ref BLE_GATTS_CFG_SERVICE_CHANGED. */
+ ble_gatts_cfg_attr_tab_size_t attr_tab_size; /**< Attribute table size, cfg_id is @ref BLE_GATTS_CFG_ATTR_TAB_SIZE. */
+} ble_gatts_cfg_t;
+
+
+/**@brief Event structure for @ref BLE_GATTS_EVT_WRITE. */
+typedef struct
+{
+ uint16_t handle; /**< Attribute Handle. */
+ ble_uuid_t uuid; /**< Attribute UUID. */
+ uint8_t op; /**< Type of write operation, see @ref BLE_GATTS_OPS. */
+ uint8_t auth_required; /**< Writing operation deferred due to authorization requirement. Application may use @ref sd_ble_gatts_value_set to finalize the writing operation. */
+ uint16_t offset; /**< Offset for the write operation. */
+ uint16_t len; /**< Length of the received data. */
+ uint8_t data[1]; /**< Received data. @note This is a variable length array. The size of 1 indicated is only a placeholder for compilation.
+ See @ref sd_ble_evt_get for more information on how to use event structures with variable length array members. */
+} ble_gatts_evt_write_t;
+
+/**@brief Event substructure for authorized read requests, see @ref ble_gatts_evt_rw_authorize_request_t. */
+typedef struct
+{
+ uint16_t handle; /**< Attribute Handle. */
+ ble_uuid_t uuid; /**< Attribute UUID. */
+ uint16_t offset; /**< Offset for the read operation. */
+} ble_gatts_evt_read_t;
+
+/**@brief Event structure for @ref BLE_GATTS_EVT_RW_AUTHORIZE_REQUEST. */
+typedef struct
+{
+ uint8_t type; /**< Type of authorize operation, see @ref BLE_GATTS_AUTHORIZE_TYPES. */
+ union {
+ ble_gatts_evt_read_t read; /**< Attribute Read Parameters. */
+ ble_gatts_evt_write_t write; /**< Attribute Write Parameters. */
+ } request; /**< Request Parameters. */
+} ble_gatts_evt_rw_authorize_request_t;
+
+/**@brief Event structure for @ref BLE_GATTS_EVT_SYS_ATTR_MISSING. */
+typedef struct
+{
+ uint8_t hint; /**< Hint (currently unused). */
+} ble_gatts_evt_sys_attr_missing_t;
+
+
+/**@brief Event structure for @ref BLE_GATTS_EVT_HVC. */
+typedef struct
+{
+ uint16_t handle; /**< Attribute Handle. */
+} ble_gatts_evt_hvc_t;
+
+/**@brief Event structure for @ref BLE_GATTS_EVT_EXCHANGE_MTU_REQUEST. */
+typedef struct
+{
+ uint16_t client_rx_mtu; /**< Client RX MTU size. */
+} ble_gatts_evt_exchange_mtu_request_t;
+
+/**@brief Event structure for @ref BLE_GATTS_EVT_TIMEOUT. */
+typedef struct
+{
+ uint8_t src; /**< Timeout source, see @ref BLE_GATT_TIMEOUT_SOURCES. */
+} ble_gatts_evt_timeout_t;
+
+/**@brief Event structure for @ref BLE_GATTS_EVT_HVN_TX_COMPLETE. */
+typedef struct
+{
+ uint8_t count; /**< Number of notification transmissions completed. */
+} ble_gatts_evt_hvn_tx_complete_t;
+
+/**@brief GATTS event structure. */
+typedef struct
+{
+ uint16_t conn_handle; /**< Connection Handle on which the event occurred. */
+ union
+ {
+ ble_gatts_evt_write_t write; /**< Write Event Parameters. */
+ ble_gatts_evt_rw_authorize_request_t authorize_request; /**< Read or Write Authorize Request Parameters. */
+ ble_gatts_evt_sys_attr_missing_t sys_attr_missing; /**< System attributes missing. */
+ ble_gatts_evt_hvc_t hvc; /**< Handle Value Confirmation Event Parameters. */
+ ble_gatts_evt_exchange_mtu_request_t exchange_mtu_request; /**< Exchange MTU Request Event Parameters. */
+ ble_gatts_evt_timeout_t timeout; /**< Timeout Event. */
+ ble_gatts_evt_hvn_tx_complete_t hvn_tx_complete; /**< Handle Value Notification transmission complete Event Parameters. */
+ } params; /**< Event Parameters. */
+} ble_gatts_evt_t;
+
+/** @} */
+
+/** @addtogroup BLE_GATTS_FUNCTIONS Functions
+ * @{ */
+
+/**@brief Add a service declaration to the Attribute Table.
+ *
+ * @note Secondary Services are only relevant in the context of the entity that references them, it is therefore forbidden to
+ * add a secondary service declaration that is not referenced by another service later in the Attribute Table.
+ *
+ * @mscs
+ * @mmsc{@ref BLE_GATTS_ATT_TABLE_POP_MSC}
+ * @endmscs
+ *
+ * @param[in] type Toggles between primary and secondary services, see @ref BLE_GATTS_SRVC_TYPES.
+ * @param[in] p_uuid Pointer to service UUID.
+ * @param[out] p_handle Pointer to a 16-bit word where the assigned handle will be stored.
+ *
+ * @retval ::NRF_SUCCESS Successfully added a service declaration.
+ * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied.
+ * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied, Vendor Specific UUIDs need to be present in the table.
+ * @retval ::NRF_ERROR_FORBIDDEN Forbidden value supplied, certain UUIDs are reserved for the stack.
+ * @retval ::NRF_ERROR_NO_MEM Not enough memory to complete operation.
+ */
+SVCALL(SD_BLE_GATTS_SERVICE_ADD, uint32_t, sd_ble_gatts_service_add(uint8_t type, ble_uuid_t const *p_uuid, uint16_t *p_handle));
+
+
+/**@brief Add an include declaration to the Attribute Table.
+ *
+ * @note It is currently only possible to add an include declaration to the last added service (i.e. only sequential population is supported at this time).
+ *
+ * @note The included service must already be present in the Attribute Table prior to this call.
+ *
+ * @mscs
+ * @mmsc{@ref BLE_GATTS_ATT_TABLE_POP_MSC}
+ * @endmscs
+ *
+ * @param[in] service_handle Handle of the service where the included service is to be placed, if @ref BLE_GATT_HANDLE_INVALID is used, it will be placed sequentially.
+ * @param[in] inc_srvc_handle Handle of the included service.
+ * @param[out] p_include_handle Pointer to a 16-bit word where the assigned handle will be stored.
+ *
+ * @retval ::NRF_SUCCESS Successfully added an include declaration.
+ * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied.
+ * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied, handle values need to match previously added services.
+ * @retval ::NRF_ERROR_INVALID_STATE Invalid state to perform operation.
+ * @retval ::NRF_ERROR_NOT_SUPPORTED Feature is not supported, service_handle must be that of the last added service.
+ * @retval ::NRF_ERROR_FORBIDDEN Forbidden value supplied, self inclusions are not allowed.
+ * @retval ::NRF_ERROR_NO_MEM Not enough memory to complete operation.
+ * @retval ::NRF_ERROR_NOT_FOUND Attribute not found.
+ */
+SVCALL(SD_BLE_GATTS_INCLUDE_ADD, uint32_t, sd_ble_gatts_include_add(uint16_t service_handle, uint16_t inc_srvc_handle, uint16_t *p_include_handle));
+
+
+/**@brief Add a characteristic declaration, a characteristic value declaration and optional characteristic descriptor declarations to the Attribute Table.
+ *
+ * @note It is currently only possible to add a characteristic to the last added service (i.e. only sequential population is supported at this time).
+ *
+ * @note Several restrictions apply to the parameters, such as matching permissions between the user description descriptor and the writable auxiliaries bits,
+ * readable (no security) and writable (selectable) CCCDs and SCCDs and valid presentation format values.
+ *
+ * @note If no metadata is provided for the optional descriptors, their permissions will be derived from the characteristic permissions.
+ *
+ * @mscs
+ * @mmsc{@ref BLE_GATTS_ATT_TABLE_POP_MSC}
+ * @endmscs
+ *
+ * @param[in] service_handle Handle of the service where the characteristic is to be placed, if @ref BLE_GATT_HANDLE_INVALID is used, it will be placed sequentially.
+ * @param[in] p_char_md Characteristic metadata.
+ * @param[in] p_attr_char_value Pointer to the attribute structure corresponding to the characteristic value.
+ * @param[out] p_handles Pointer to the structure where the assigned handles will be stored.
+ *
+ * @retval ::NRF_SUCCESS Successfully added a characteristic.
+ * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied.
+ * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied, service handle, Vendor Specific UUIDs, lengths, and permissions need to adhere to the constraints.
+ * @retval ::NRF_ERROR_INVALID_STATE Invalid state to perform operation, a service context is required.
+ * @retval ::NRF_ERROR_FORBIDDEN Forbidden value supplied, certain UUIDs are reserved for the stack.
+ * @retval ::NRF_ERROR_NO_MEM Not enough memory to complete operation.
+ * @retval ::NRF_ERROR_DATA_SIZE Invalid data size(s) supplied, attribute lengths are restricted by @ref BLE_GATTS_ATTR_LENS_MAX.
+ */
+SVCALL(SD_BLE_GATTS_CHARACTERISTIC_ADD, uint32_t, sd_ble_gatts_characteristic_add(uint16_t service_handle, ble_gatts_char_md_t const *p_char_md, ble_gatts_attr_t const *p_attr_char_value, ble_gatts_char_handles_t *p_handles));
+
+
+/**@brief Add a descriptor to the Attribute Table.
+ *
+ * @note It is currently only possible to add a descriptor to the last added characteristic (i.e. only sequential population is supported at this time).
+ *
+ * @mscs
+ * @mmsc{@ref BLE_GATTS_ATT_TABLE_POP_MSC}
+ * @endmscs
+ *
+ * @param[in] char_handle Handle of the characteristic where the descriptor is to be placed, if @ref BLE_GATT_HANDLE_INVALID is used, it will be placed sequentially.
+ * @param[in] p_attr Pointer to the attribute structure.
+ * @param[out] p_handle Pointer to a 16-bit word where the assigned handle will be stored.
+ *
+ * @retval ::NRF_SUCCESS Successfully added a descriptor.
+ * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied.
+ * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied, characteristic handle, Vendor Specific UUIDs, lengths, and permissions need to adhere to the constraints.
+ * @retval ::NRF_ERROR_INVALID_STATE Invalid state to perform operation, a characteristic context is required.
+ * @retval ::NRF_ERROR_FORBIDDEN Forbidden value supplied, certain UUIDs are reserved for the stack.
+ * @retval ::NRF_ERROR_NO_MEM Not enough memory to complete operation.
+ * @retval ::NRF_ERROR_DATA_SIZE Invalid data size(s) supplied, attribute lengths are restricted by @ref BLE_GATTS_ATTR_LENS_MAX.
+ */
+SVCALL(SD_BLE_GATTS_DESCRIPTOR_ADD, uint32_t, sd_ble_gatts_descriptor_add(uint16_t char_handle, ble_gatts_attr_t const *p_attr, uint16_t *p_handle));
+
+/**@brief Set the value of a given attribute.
+ *
+ * @note Values other than system attributes can be set at any time, regardless of whether any active connections exist.
+ *
+ * @mscs
+ * @mmsc{@ref BLE_GATTS_QUEUED_WRITE_QUEUE_FULL_MSC}
+ * @mmsc{@ref BLE_GATTS_QUEUED_WRITE_NOBUF_NOAUTH_MSC}
+ * @endmscs
+ *
+ * @param[in] conn_handle Connection handle. Ignored if the value does not belong to a system attribute.
+ * @param[in] handle Attribute handle.
+ * @param[in,out] p_value Attribute value information.
+ *
+ * @retval ::NRF_SUCCESS Successfully set the value of the attribute.
+ * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied.
+ * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied.
+ * @retval ::NRF_ERROR_NOT_FOUND Attribute not found.
+ * @retval ::NRF_ERROR_FORBIDDEN Forbidden handle supplied, certain attributes are not modifiable by the application.
+ * @retval ::NRF_ERROR_DATA_SIZE Invalid data size(s) supplied, attribute lengths are restricted by @ref BLE_GATTS_ATTR_LENS_MAX.
+ * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid connection handle supplied on a system attribute.
+ */
+SVCALL(SD_BLE_GATTS_VALUE_SET, uint32_t, sd_ble_gatts_value_set(uint16_t conn_handle, uint16_t handle, ble_gatts_value_t *p_value));
+
+/**@brief Get the value of a given attribute.
+ *
+ * @note If the attribute value is longer than the size of the supplied buffer,
+ * @ref ble_gatts_value_t::len will return the total attribute value length (excluding offset),
+ * and not the number of bytes actually returned in @ref ble_gatts_value_t::p_value.
+ * The application may use this information to allocate a suitable buffer size.
+ *
+ * @note When retrieving system attribute values with this function, the connection handle
+ * may refer to an already disconnected connection. Refer to the documentation of
+ * @ref sd_ble_gatts_sys_attr_get for further information.
+ *
+ * @param[in] conn_handle Connection handle. Ignored if the value does not belong to a system attribute.
+ * @param[in] handle Attribute handle.
+ * @param[in,out] p_value Attribute value information.
+ *
+ * @retval ::NRF_SUCCESS Successfully retrieved the value of the attribute.
+ * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied.
+ * @retval ::NRF_ERROR_NOT_FOUND Attribute not found.
+ * @retval ::NRF_ERROR_INVALID_PARAM Invalid attribute offset supplied.
+ * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid connection handle supplied on a system attribute.
+ * @retval ::BLE_ERROR_GATTS_SYS_ATTR_MISSING System attributes missing, use @ref sd_ble_gatts_sys_attr_set to set them to a known value.
+ */
+SVCALL(SD_BLE_GATTS_VALUE_GET, uint32_t, sd_ble_gatts_value_get(uint16_t conn_handle, uint16_t handle, ble_gatts_value_t *p_value));
+
+/**@brief Notify or Indicate an attribute value.
+ *
+ * @details This function checks for the relevant Client Characteristic Configuration descriptor value to verify that the relevant operation
+ * (notification or indication) has been enabled by the client. It is also able to update the attribute value before issuing the PDU, so that
+ * the application can atomically perform a value update and a server initiated transaction with a single API call.
+ *
+ * @note The local attribute value may be updated even if an outgoing packet is not sent to the peer due to an error during execution.
+ * The Attribute Table has been updated if one of the following error codes is returned: @ref NRF_ERROR_INVALID_STATE, @ref NRF_ERROR_BUSY,
+ * @ref NRF_ERROR_FORBIDDEN, @ref BLE_ERROR_GATTS_SYS_ATTR_MISSING and @ref NRF_ERROR_RESOURCES.
+ * The caller can check whether the value has been updated by looking at the contents of *(@ref ble_gatts_hvx_params_t::p_len).
+ *
+ * @note Only one indication procedure can be ongoing per connection at a time.
+ * If the application tries to indicate an attribute value while another indication procedure is ongoing,
+ * the function call will return @ref NRF_ERROR_BUSY.
+ * A @ref BLE_GATTS_EVT_HVC event will be issued as soon as the confirmation arrives from the peer.
+ *
+ * @note The number of Handle Value Notifications that can be queued is configured by @ref ble_gatts_conn_cfg_t::hvn_tx_queue_size
+ * When the queue is full, the function call will return @ref NRF_ERROR_RESOURCES.
+ * A @ref BLE_GATTS_EVT_HVN_TX_COMPLETE event will be issued as soon as the transmission of the notification is complete.
+ *
+ * @note The application can keep track of the available queue element count for notifications by following the procedure below:
+ * - Store initial queue element count in a variable.
+ * - Decrement the variable, which stores the currently available queue element count, by one when a call to this function returns @ref NRF_SUCCESS.
+ * - Increment the variable, which stores the current available queue element count, by the count variable in @ref BLE_GATTS_EVT_HVN_TX_COMPLETE event.
+ *
+ * @events
+ * @event{@ref BLE_GATTS_EVT_HVN_TX_COMPLETE, Notification transmission complete.}
+ * @event{@ref BLE_GATTS_EVT_HVC, Confirmation received from the peer.}
+ * @endevents
+ *
+ * @mscs
+ * @mmsc{@ref BLE_GATTS_HVX_SYS_ATTRS_MISSING_MSC}
+ * @mmsc{@ref BLE_GATTS_HVN_MSC}
+ * @mmsc{@ref BLE_GATTS_HVI_MSC}
+ * @mmsc{@ref BLE_GATTS_HVX_DISABLED_MSC}
+ * @endmscs
+ *
+ * @param[in] conn_handle Connection handle.
+ * @param[in,out] p_hvx_params Pointer to an HVx parameters structure. If @ref ble_gatts_hvx_params_t::p_data
+ * contains a non-NULL pointer the attribute value will be updated with the contents
+ * pointed by it before sending the notification or indication. If the attribute value
+ * is updated, @ref ble_gatts_hvx_params_t::p_len is updated by the SoftDevice to
+ * contain the number of actual bytes written, else it will be set to 0.
+ *
+ * @retval ::NRF_SUCCESS Successfully queued a notification or indication for transmission, and optionally updated the attribute value.
+ * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid Connection Handle.
+ * @retval ::NRF_ERROR_INVALID_STATE One or more of the following is true:
+ * - Invalid Connection State
+ * - Notifications and/or indications not enabled in the CCCD
+ * - An ATT_MTU exchange is ongoing
+ * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied.
+ * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied.
+ * @retval ::BLE_ERROR_INVALID_ATTR_HANDLE Invalid attribute handle(s) supplied. Only attributes added directly by the application are available to notify and indicate.
+ * @retval ::BLE_ERROR_GATTS_INVALID_ATTR_TYPE Invalid attribute type(s) supplied, only characteristic values may be notified and indicated.
+ * @retval ::NRF_ERROR_NOT_FOUND Attribute not found.
+ * @retval ::NRF_ERROR_FORBIDDEN The connection's current security level is lower than the one required by the write permissions of the CCCD associated with this characteristic.
+ * @retval ::NRF_ERROR_DATA_SIZE Invalid data size(s) supplied.
+ * @retval ::NRF_ERROR_BUSY For @ref BLE_GATT_HVX_INDICATION Procedure already in progress. Wait for a @ref BLE_GATTS_EVT_HVC event and retry.
+ * @retval ::BLE_ERROR_GATTS_SYS_ATTR_MISSING System attributes missing, use @ref sd_ble_gatts_sys_attr_set to set them to a known value.
+ * @retval ::NRF_ERROR_RESOURCES Too many notifications queued.
+ * Wait for a @ref BLE_GATTS_EVT_HVN_TX_COMPLETE event and retry.
+ * @retval ::NRF_ERROR_TIMEOUT There has been a GATT procedure timeout. No new GATT procedure can be performed without reestablishing the connection.
+ */
+SVCALL(SD_BLE_GATTS_HVX, uint32_t, sd_ble_gatts_hvx(uint16_t conn_handle, ble_gatts_hvx_params_t const *p_hvx_params));
+
+/**@brief Indicate the Service Changed attribute value.
+ *
+ * @details This call will send a Handle Value Indication to one or more peers connected to inform them that the Attribute
+ * Table layout has changed. As soon as the peer has confirmed the indication, a @ref BLE_GATTS_EVT_SC_CONFIRM event will
+ * be issued.
+ *
+ * @note Some of the restrictions and limitations that apply to @ref sd_ble_gatts_hvx also apply here.
+ *
+ * @events
+ * @event{@ref BLE_GATTS_EVT_SC_CONFIRM, Confirmation of attribute table change received from peer.}
+ * @endevents
+ *
+ * @mscs
+ * @mmsc{@ref BLE_GATTS_SC_MSC}
+ * @endmscs
+ *
+ * @param[in] conn_handle Connection handle.
+ * @param[in] start_handle Start of affected attribute handle range.
+ * @param[in] end_handle End of affected attribute handle range.
+ *
+ * @retval ::NRF_SUCCESS Successfully queued the Service Changed indication for transmission.
+ * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid Connection Handle.
+ * @retval ::NRF_ERROR_NOT_SUPPORTED Service Changed not enabled at initialization. See @ref
+ * sd_ble_cfg_set and @ref ble_gatts_cfg_service_changed_t.
+ * @retval ::NRF_ERROR_INVALID_STATE One or more of the following is true:
+ * - Invalid Connection State
+ * - Notifications and/or indications not enabled in the CCCD
+ * - An ATT_MTU exchange is ongoing
+ * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied.
+ * @retval ::BLE_ERROR_INVALID_ATTR_HANDLE Invalid attribute handle(s) supplied, handles must be in the range populated by the application.
+ * @retval ::NRF_ERROR_BUSY Procedure already in progress.
+ * @retval ::BLE_ERROR_GATTS_SYS_ATTR_MISSING System attributes missing, use @ref sd_ble_gatts_sys_attr_set to set them to a known value.
+ * @retval ::NRF_ERROR_TIMEOUT There has been a GATT procedure timeout. No new GATT procedure can be performed without reestablishing the connection.
+ */
+SVCALL(SD_BLE_GATTS_SERVICE_CHANGED, uint32_t, sd_ble_gatts_service_changed(uint16_t conn_handle, uint16_t start_handle, uint16_t end_handle));
+
+/**@brief Respond to a Read/Write authorization request.
+ *
+ * @note This call should only be used as a response to a @ref BLE_GATTS_EVT_RW_AUTHORIZE_REQUEST event issued to the application.
+ *
+ * @mscs
+ * @mmsc{@ref BLE_GATTS_QUEUED_WRITE_NOBUF_AUTH_MSC}
+ * @mmsc{@ref BLE_GATTS_QUEUED_WRITE_BUF_AUTH_MSC}
+ * @mmsc{@ref BLE_GATTS_QUEUED_WRITE_NOBUF_NOAUTH_MSC}
+ * @mmsc{@ref BLE_GATTS_READ_REQ_AUTH_MSC}
+ * @mmsc{@ref BLE_GATTS_WRITE_REQ_AUTH_MSC}
+ * @mmsc{@ref BLE_GATTS_QUEUED_WRITE_QUEUE_FULL_MSC}
+ * @mmsc{@ref BLE_GATTS_QUEUED_WRITE_PEER_CANCEL_MSC}
+ * @endmscs
+ *
+ * @param[in] conn_handle Connection handle.
+ * @param[in] p_rw_authorize_reply_params Pointer to a structure with the attribute provided by the application.
+ *
+ * @note @ref ble_gatts_authorize_params_t::p_data is ignored when this function is used to respond
+ * to a @ref BLE_GATTS_AUTHORIZE_TYPE_READ event if @ref ble_gatts_authorize_params_t::update
+ * is set to 0.
+ *
+ * @retval ::NRF_SUCCESS Successfully queued a response to the peer, and in the case of a write operation, Attribute Table updated.
+ * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid Connection Handle.
+ * @retval ::NRF_ERROR_BUSY The stack is busy, process pending events and retry.
+ * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied.
+ * @retval ::NRF_ERROR_INVALID_STATE Invalid Connection State or no authorization request pending.
+ * @retval ::NRF_ERROR_INVALID_PARAM Authorization op invalid,
+ * handle supplied does not match requested handle,
+ * or invalid data to be written provided by the application.
+ * @retval ::NRF_ERROR_TIMEOUT There has been a GATT procedure timeout. No new GATT procedure can be performed without reestablishing the connection.
+ */
+SVCALL(SD_BLE_GATTS_RW_AUTHORIZE_REPLY, uint32_t, sd_ble_gatts_rw_authorize_reply(uint16_t conn_handle, ble_gatts_rw_authorize_reply_params_t const *p_rw_authorize_reply_params));
+
+
+/**@brief Update persistent system attribute information.
+ *
+ * @details Supply information about persistent system attributes to the stack,
+ * previously obtained using @ref sd_ble_gatts_sys_attr_get.
+ * This call is only allowed for active connections, and is usually
+ * made immediately after a connection is established with an known bonded device,
+ * often as a response to a @ref BLE_GATTS_EVT_SYS_ATTR_MISSING.
+ *
+ * p_sysattrs may point directly to the application's stored copy of the system attributes
+ * obtained using @ref sd_ble_gatts_sys_attr_get.
+ * If the pointer is NULL, the system attribute info is initialized, assuming that
+ * the application does not have any previously saved system attribute data for this device.
+ *
+ * @note The state of persistent system attributes is reset upon connection establishment and then remembered for its duration.
+ *
+ * @note If this call returns with an error code different from @ref NRF_SUCCESS, the storage of persistent system attributes may have been completed only partially.
+ * This means that the state of the attribute table is undefined, and the application should either provide a new set of attributes using this same call or
+ * reset the SoftDevice to return to a known state.
+ *
+ * @note When the @ref BLE_GATTS_SYS_ATTR_FLAG_SYS_SRVCS is used with this function, only the system attributes included in system services will be modified.
+ * @note When the @ref BLE_GATTS_SYS_ATTR_FLAG_USR_SRVCS is used with this function, only the system attributes included in user services will be modified.
+ *
+ * @mscs
+ * @mmsc{@ref BLE_GATTS_HVX_SYS_ATTRS_MISSING_MSC}
+ * @mmsc{@ref BLE_GATTS_SYS_ATTRS_UNK_PEER_MSC}
+ * @mmsc{@ref BLE_GATTS_SYS_ATTRS_BONDED_PEER_MSC}
+ * @endmscs
+ *
+ * @param[in] conn_handle Connection handle.
+ * @param[in] p_sys_attr_data Pointer to a saved copy of system attributes supplied to the stack, or NULL.
+ * @param[in] len Size of data pointed by p_sys_attr_data, in octets.
+ * @param[in] flags Optional additional flags, see @ref BLE_GATTS_SYS_ATTR_FLAGS
+ *
+ * @retval ::NRF_SUCCESS Successfully set the system attribute information.
+ * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid Connection Handle.
+ * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied.
+ * @retval ::NRF_ERROR_INVALID_STATE Invalid Connection State.
+ * @retval ::NRF_ERROR_INVALID_PARAM Invalid flags supplied.
+ * @retval ::NRF_ERROR_INVALID_DATA Invalid data supplied, the data should be exactly the same as retrieved with @ref sd_ble_gatts_sys_attr_get.
+ * @retval ::NRF_ERROR_NO_MEM Not enough memory to complete operation.
+ */
+SVCALL(SD_BLE_GATTS_SYS_ATTR_SET, uint32_t, sd_ble_gatts_sys_attr_set(uint16_t conn_handle, uint8_t const *p_sys_attr_data, uint16_t len, uint32_t flags));
+
+
+/**@brief Retrieve persistent system attribute information from the stack.
+ *
+ * @details This call is used to retrieve information about values to be stored persistently by the application
+ * during the lifetime of a connection or after it has been terminated. When a new connection is established with the same bonded device,
+ * the system attribute information retrieved with this function should be restored using using @ref sd_ble_gatts_sys_attr_set.
+ * If retrieved after disconnection, the data should be read before a new connection established. The connection handle for
+ * the previous, now disconnected, connection will remain valid until a new one is created to allow this API call to refer to it.
+ * Connection handles belonging to active connections can be used as well, but care should be taken since the system attributes
+ * may be written to at any time by the peer during a connection's lifetime.
+ *
+ * @note When the @ref BLE_GATTS_SYS_ATTR_FLAG_SYS_SRVCS is used with this function, only the system attributes included in system services will be returned.
+ * @note When the @ref BLE_GATTS_SYS_ATTR_FLAG_USR_SRVCS is used with this function, only the system attributes included in user services will be returned.
+ *
+ * @mscs
+ * @mmsc{@ref BLE_GATTS_SYS_ATTRS_BONDED_PEER_MSC}
+ * @endmscs
+ *
+ * @param[in] conn_handle Connection handle of the recently terminated connection.
+ * @param[out] p_sys_attr_data Pointer to a buffer where updated information about system attributes will be filled in. The format of the data is described
+ * in @ref BLE_GATTS_SYS_ATTRS_FORMAT. NULL can be provided to obtain the length of the data.
+ * @param[in,out] p_len Size of application buffer if p_sys_attr_data is not NULL. Unconditionally updated to actual length of system attribute data.
+ * @param[in] flags Optional additional flags, see @ref BLE_GATTS_SYS_ATTR_FLAGS
+ *
+ * @retval ::NRF_SUCCESS Successfully retrieved the system attribute information.
+ * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid Connection Handle.
+ * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied.
+ * @retval ::NRF_ERROR_INVALID_PARAM Invalid flags supplied.
+ * @retval ::NRF_ERROR_DATA_SIZE The system attribute information did not fit into the provided buffer.
+ * @retval ::NRF_ERROR_NOT_FOUND No system attributes found.
+ */
+SVCALL(SD_BLE_GATTS_SYS_ATTR_GET, uint32_t, sd_ble_gatts_sys_attr_get(uint16_t conn_handle, uint8_t *p_sys_attr_data, uint16_t *p_len, uint32_t flags));
+
+
+/**@brief Retrieve the first valid user attribute handle.
+ *
+ * @param[out] p_handle Pointer to an integer where the handle will be stored.
+ *
+ * @retval ::NRF_SUCCESS Successfully retrieved the handle.
+ * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied.
+ */
+SVCALL(SD_BLE_GATTS_INITIAL_USER_HANDLE_GET, uint32_t, sd_ble_gatts_initial_user_handle_get(uint16_t *p_handle));
+
+/**@brief Retrieve the attribute UUID and/or metadata.
+ *
+ * @param[in] handle Attribute handle
+ * @param[out] p_uuid UUID of the attribute. Use NULL to omit this field.
+ * @param[out] p_md Metadata of the attribute. Use NULL to omit this field.
+ *
+ * @retval ::NRF_SUCCESS Successfully retrieved the attribute metadata,
+ * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied.
+ * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameters supplied. Returned when both @c p_uuid and @c p_md are NULL.
+ * @retval ::NRF_ERROR_NOT_FOUND Attribute was not found.
+ */
+SVCALL(SD_BLE_GATTS_ATTR_GET, uint32_t, sd_ble_gatts_attr_get(uint16_t handle, ble_uuid_t * p_uuid, ble_gatts_attr_md_t * p_md));
+
+/**@brief Reply to an ATT_MTU exchange request by sending an Exchange MTU Response to the client.
+ *
+ * @details This function is only used to reply to a @ref BLE_GATTS_EVT_EXCHANGE_MTU_REQUEST event.
+ *
+ * @details The SoftDevice sets ATT_MTU to the minimum of:
+ * - The Client RX MTU value from @ref BLE_GATTS_EVT_EXCHANGE_MTU_REQUEST, and
+ * - The Server RX MTU value.
+ *
+ * However, the SoftDevice never sets ATT_MTU lower than @ref BLE_GATT_ATT_MTU_DEFAULT.
+ *
+ * @mscs
+ * @mmsc{@ref BLE_GATTS_MTU_EXCHANGE}
+ * @endmscs
+ *
+ * @param[in] conn_handle The connection handle identifying the connection to perform this procedure on.
+ * @param[in] server_rx_mtu Server RX MTU size.
+ * - The minimum value is @ref BLE_GATT_ATT_MTU_DEFAULT.
+ * - The maximum value is @ref ble_gatt_conn_cfg_t::att_mtu in the connection configuration
+ * used for this connection.
+ * - The value must be equal to Client RX MTU size given in @ref sd_ble_gattc_exchange_mtu_request
+ * if an ATT_MTU exchange has already been performed in the other direction.
+ *
+ * @retval ::NRF_SUCCESS Successfully sent response to the client.
+ * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid Connection Handle.
+ * @retval ::NRF_ERROR_INVALID_STATE Invalid Connection State or no ATT_MTU exchange request pending.
+ * @retval ::NRF_ERROR_INVALID_PARAM Invalid Server RX MTU size supplied.
+ * @retval ::NRF_ERROR_TIMEOUT There has been a GATT procedure timeout. No new GATT procedure can be performed without reestablishing the connection.
+ */
+SVCALL(SD_BLE_GATTS_EXCHANGE_MTU_REPLY, uint32_t, sd_ble_gatts_exchange_mtu_reply(uint16_t conn_handle, uint16_t server_rx_mtu));
+/** @} */
+
+#ifdef __cplusplus
+}
+#endif
+#endif // BLE_GATTS_H__
+
+/**
+ @}
+*/
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/softdevice/s140/headers/ble_hci.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/softdevice/s140/headers/ble_hci.h
new file mode 100644
index 0000000..f0dde9a
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/softdevice/s140/headers/ble_hci.h
@@ -0,0 +1,135 @@
+/*
+ * Copyright (c) 2012 - 2017, 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ */
+
+/**
+ @addtogroup BLE_COMMON
+ @{
+*/
+
+
+#ifndef BLE_HCI_H__
+#define BLE_HCI_H__
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** @defgroup BLE_HCI_STATUS_CODES Bluetooth status codes
+ * @{ */
+
+#define BLE_HCI_STATUS_CODE_SUCCESS 0x00 /**< Success. */
+#define BLE_HCI_STATUS_CODE_UNKNOWN_BTLE_COMMAND 0x01 /**< Unknown BLE Command. */
+#define BLE_HCI_STATUS_CODE_UNKNOWN_CONNECTION_IDENTIFIER 0x02 /**< Unknown Connection Identifier. */
+/*0x03 Hardware Failure
+0x04 Page Timeout
+*/
+#define BLE_HCI_AUTHENTICATION_FAILURE 0x05 /**< Authentication Failure. */
+#define BLE_HCI_STATUS_CODE_PIN_OR_KEY_MISSING 0x06 /**< Pin or Key missing. */
+#define BLE_HCI_MEMORY_CAPACITY_EXCEEDED 0x07 /**< Memory Capacity Exceeded. */
+#define BLE_HCI_CONNECTION_TIMEOUT 0x08 /**< Connection Timeout. */
+/*0x09 Connection Limit Exceeded
+0x0A Synchronous Connection Limit To A Device Exceeded
+0x0B ACL Connection Already Exists*/
+#define BLE_HCI_STATUS_CODE_COMMAND_DISALLOWED 0x0C /**< Command Disallowed. */
+/*0x0D Connection Rejected due to Limited Resources
+0x0E Connection Rejected Due To Security Reasons
+0x0F Connection Rejected due to Unacceptable BD_ADDR
+0x10 Connection Accept Timeout Exceeded
+0x11 Unsupported Feature or Parameter Value*/
+#define BLE_HCI_STATUS_CODE_INVALID_BTLE_COMMAND_PARAMETERS 0x12 /**< Invalid BLE Command Parameters. */
+#define BLE_HCI_REMOTE_USER_TERMINATED_CONNECTION 0x13 /**< Remote User Terminated Connection. */
+#define BLE_HCI_REMOTE_DEV_TERMINATION_DUE_TO_LOW_RESOURCES 0x14 /**< Remote Device Terminated Connection due to low resources.*/
+#define BLE_HCI_REMOTE_DEV_TERMINATION_DUE_TO_POWER_OFF 0x15 /**< Remote Device Terminated Connection due to power off. */
+#define BLE_HCI_LOCAL_HOST_TERMINATED_CONNECTION 0x16 /**< Local Host Terminated Connection. */
+/*
+0x17 Repeated Attempts
+0x18 Pairing Not Allowed
+0x19 Unknown LMP PDU
+*/
+#define BLE_HCI_UNSUPPORTED_REMOTE_FEATURE 0x1A /**< Unsupported Remote Feature. */
+/*
+0x1B SCO Offset Rejected
+0x1C SCO Interval Rejected
+0x1D SCO Air Mode Rejected*/
+#define BLE_HCI_STATUS_CODE_INVALID_LMP_PARAMETERS 0x1E /**< Invalid LMP Parameters. */
+#define BLE_HCI_STATUS_CODE_UNSPECIFIED_ERROR 0x1F /**< Unspecified Error. */
+/*0x20 Unsupported LMP Parameter Value
+0x21 Role Change Not Allowed
+*/
+#define BLE_HCI_STATUS_CODE_LMP_RESPONSE_TIMEOUT 0x22 /**< LMP Response Timeout. */
+#define BLE_HCI_STATUS_CODE_LMP_ERROR_TRANSACTION_COLLISION 0x23 /**< LMP Error Transaction Collision/LL Procedure Collision. */
+#define BLE_HCI_STATUS_CODE_LMP_PDU_NOT_ALLOWED 0x24 /**< LMP PDU Not Allowed. */
+/*0x25 Encryption Mode Not Acceptable
+0x26 Link Key Can Not be Changed
+0x27 Requested QoS Not Supported
+*/
+#define BLE_HCI_INSTANT_PASSED 0x28 /**< Instant Passed. */
+#define BLE_HCI_PAIRING_WITH_UNIT_KEY_UNSUPPORTED 0x29 /**< Pairing with Unit Key Unsupported. */
+#define BLE_HCI_DIFFERENT_TRANSACTION_COLLISION 0x2A /**< Different Transaction Collision. */
+/*
+0x2B Reserved
+0x2C QoS Unacceptable Parameter
+0x2D QoS Rejected
+0x2E Channel Classification Not Supported
+0x2F Insufficient Security
+*/
+#define BLE_HCI_PARAMETER_OUT_OF_MANDATORY_RANGE 0x30 /**< Parameter Out Of Mandatory Range. */
+/*
+0x31 Reserved
+0x32 Role Switch Pending
+0x33 Reserved
+0x34 Reserved Slot Violation
+0x35 Role Switch Failed
+0x36 Extended Inquiry Response Too Large
+0x37 Secure Simple Pairing Not Supported By Host.
+0x38 Host Busy - Pairing
+0x39 Connection Rejected due to No Suitable Channel Found*/
+#define BLE_HCI_CONTROLLER_BUSY 0x3A /**< Controller Busy. */
+#define BLE_HCI_CONN_INTERVAL_UNACCEPTABLE 0x3B /**< Connection Interval Unacceptable. */
+#define BLE_HCI_DIRECTED_ADVERTISER_TIMEOUT 0x3C /**< Directed Advertisement Timeout. */
+#define BLE_HCI_CONN_TERMINATED_DUE_TO_MIC_FAILURE 0x3D /**< Connection Terminated due to MIC Failure. */
+#define BLE_HCI_CONN_FAILED_TO_BE_ESTABLISHED 0x3E /**< Connection Failed to be Established. */
+
+/** @} */
+
+
+#ifdef __cplusplus
+}
+#endif
+#endif // BLE_HCI_H__
+
+/** @} */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/softdevice/s140/headers/ble_l2cap.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/softdevice/s140/headers/ble_l2cap.h
new file mode 100644
index 0000000..eaeb4b7
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/softdevice/s140/headers/ble_l2cap.h
@@ -0,0 +1,506 @@
+/*
+ * Copyright (c) 2011 - 2017, 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ */
+
+/**
+ @addtogroup BLE_L2CAP Logical Link Control and Adaptation Protocol (L2CAP)
+ @{
+ @brief Definitions and prototypes for the L2CAP interface.
+ */
+
+#ifndef BLE_L2CAP_H__
+#define BLE_L2CAP_H__
+
+#include <stdint.h>
+#include "nrf_svc.h"
+#include "nrf_error.h"
+#include "ble_ranges.h"
+#include "ble_types.h"
+#include "ble_err.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**@addtogroup BLE_L2CAP_TERMINOLOGY Terminology
+ * @{
+ * @details
+ *
+ * L2CAP SDU
+ * - A data unit that the application can send/receive to/from a peer.
+ *
+ * L2CAP PDU
+ * - A data unit that is exchanged between local and remote L2CAP entities.
+ * It consists of L2CAP protocol control information and payload fields.
+ * The payload field can contain an L2CAP SDU or a part of an L2CAP SDU.
+ *
+ * L2CAP MTU
+ * - The maximum length of an L2CAP SDU.
+ *
+ * L2CAP MPS
+ * - The maximum length of an L2CAP PDU payload field.
+ *
+ * Credits
+ * - A value indicating the number of L2CAP PDUs that the receiver of the credit can send to the peer.
+ * @} */
+
+/**@addtogroup BLE_L2CAP_ENUMERATIONS Enumerations
+ * @{ */
+
+/**@brief L2CAP API SVC numbers. */
+enum BLE_L2CAP_SVCS
+{
+ SD_BLE_L2CAP_CH_SETUP = BLE_L2CAP_SVC_BASE + 0, /**< Set up an L2CAP channel. */
+ SD_BLE_L2CAP_CH_RELEASE = BLE_L2CAP_SVC_BASE + 1, /**< Release an L2CAP channel. */
+ SD_BLE_L2CAP_CH_RX = BLE_L2CAP_SVC_BASE + 2, /**< Receive an SDU on an L2CAP channel. */
+ SD_BLE_L2CAP_CH_TX = BLE_L2CAP_SVC_BASE + 3, /**< Transmit an SDU on an L2CAP channel. */
+ SD_BLE_L2CAP_CH_FLOW_CONTROL = BLE_L2CAP_SVC_BASE + 4, /**< Advanced SDU reception flow control. */
+};
+
+/**@brief L2CAP Event IDs. */
+enum BLE_L2CAP_EVTS
+{
+ BLE_L2CAP_EVT_CH_SETUP_REQUEST = BLE_L2CAP_EVT_BASE + 0, /**< L2CAP Channel Setup Request event.
+ \n See @ref ble_l2cap_evt_ch_setup_request_t. */
+ BLE_L2CAP_EVT_CH_SETUP_REFUSED = BLE_L2CAP_EVT_BASE + 1, /**< L2CAP Channel Setup Refused event.
+ \n See @ref ble_l2cap_evt_ch_setup_refused_t. */
+ BLE_L2CAP_EVT_CH_SETUP = BLE_L2CAP_EVT_BASE + 2, /**< L2CAP Channel Setup Completed event.
+ \n See @ref ble_l2cap_evt_ch_setup_t. */
+ BLE_L2CAP_EVT_CH_RELEASED = BLE_L2CAP_EVT_BASE + 3, /**< L2CAP Channel Released event.
+ \n No additional event structure applies. */
+ BLE_L2CAP_EVT_CH_SDU_BUF_RELEASED = BLE_L2CAP_EVT_BASE + 4, /**< L2CAP Channel SDU data buffer released event.
+ \n See @ref ble_l2cap_evt_ch_sdu_buf_released_t. */
+ BLE_L2CAP_EVT_CH_CREDIT = BLE_L2CAP_EVT_BASE + 5, /**< L2CAP Channel Credit received.
+ \n See @ref ble_l2cap_evt_ch_credit_t. */
+ BLE_L2CAP_EVT_CH_RX = BLE_L2CAP_EVT_BASE + 6, /**< L2CAP Channel SDU received.
+ \n See @ref ble_l2cap_evt_ch_rx_t. */
+ BLE_L2CAP_EVT_CH_TX = BLE_L2CAP_EVT_BASE + 7, /**< L2CAP Channel SDU transmitted.
+ \n See @ref ble_l2cap_evt_ch_tx_t. */
+};
+
+/** @} */
+
+/**@addtogroup BLE_L2CAP_DEFINES Defines
+ * @{ */
+
+/**@brief Maximum number of L2CAP channels per connection. */
+#define BLE_L2CAP_CH_COUNT_MAX (64)
+
+/**@brief Minimum L2CAP MTU, in bytes. */
+#define BLE_L2CAP_MTU_MIN (23)
+
+/**@brief Minimum L2CAP MPS, in bytes. */
+#define BLE_L2CAP_MPS_MIN (23)
+
+/**@brief Invalid CID. */
+#define BLE_L2CAP_CID_INVALID (0x0000)
+
+/**@brief Default number of credits for @ref sd_ble_l2cap_ch_flow_control. */
+#define BLE_L2CAP_CREDITS_DEFAULT (1)
+
+/**@defgroup BLE_L2CAP_CH_SETUP_REFUSED_SRCS L2CAP channel setup refused sources
+ * @{ */
+#define BLE_L2CAP_CH_SETUP_REFUSED_SRC_LOCAL (0x01) /**< Local. */
+#define BLE_L2CAP_CH_SETUP_REFUSED_SRC_REMOTE (0x02) /**< Remote. */
+ /** @} */
+
+ /** @defgroup BLE_L2CAP_CH_STATUS_CODES L2CAP channel status codes
+ * @{ */
+#define BLE_L2CAP_CH_STATUS_CODE_SUCCESS (0x0000) /**< Success. */
+#define BLE_L2CAP_CH_STATUS_CODE_LE_PSM_NOT_SUPPORTED (0x0002) /**< LE_PSM not supported. */
+#define BLE_L2CAP_CH_STATUS_CODE_NO_RESOURCES (0x0004) /**< No resources available. */
+#define BLE_L2CAP_CH_STATUS_CODE_INSUFF_AUTHENTICATION (0x0005) /**< Insufficient authentication. */
+#define BLE_L2CAP_CH_STATUS_CODE_INSUFF_AUTHORIZATION (0x0006) /**< Insufficient authorization. */
+#define BLE_L2CAP_CH_STATUS_CODE_INSUFF_ENC_KEY_SIZE (0x0007) /**< Insufficient encryption key size. */
+#define BLE_L2CAP_CH_STATUS_CODE_INSUFF_ENC (0x0008) /**< Insufficient encryption. */
+#define BLE_L2CAP_CH_STATUS_CODE_INVALID_SCID (0x0009) /**< Invalid Source CID. */
+#define BLE_L2CAP_CH_STATUS_CODE_SCID_ALLOCATED (0x000A) /**< Source CID already allocated. */
+#define BLE_L2CAP_CH_STATUS_CODE_UNACCEPTABLE_PARAMS (0x000B) /**< Unacceptable parameters. */
+#define BLE_L2CAP_CH_STATUS_CODE_NOT_UNDERSTOOD (0x8000) /**< Command Reject received instead of LE Credit Based Connection Response. */
+#define BLE_L2CAP_CH_STATUS_CODE_TIMEOUT (0xC000) /**< Operation timed out. */
+/** @} */
+
+/** @} */
+
+/**@addtogroup BLE_L2CAP_STRUCTURES Structures
+ * @{ */
+
+/**
+ * @brief BLE L2CAP connection configuration parameters, set with @ref sd_ble_cfg_set.
+ *
+ * @note These parameters are set per connection, so all L2CAP channels created on this connection
+ * will have the same parameters.
+ *
+ * @retval ::NRF_ERROR_INVALID_PARAM One or more of the following is true:
+ * - rx_mps is smaller than @ref BLE_L2CAP_MPS_MIN.
+ * - tx_mps is smaller than @ref BLE_L2CAP_MPS_MIN.
+ * - ch_count is greater than @ref BLE_L2CAP_CH_COUNT_MAX.
+ * @retval ::NRF_ERROR_NO_MEM rx_mps or tx_mps is set too high.
+ */
+typedef struct
+{
+ uint16_t rx_mps; /**< The maximum L2CAP PDU payload size, in bytes, that L2CAP shall
+ be able to receive on L2CAP channels on connections with this
+ configuration. The minimum value is @ref BLE_L2CAP_MPS_MIN. */
+ uint16_t tx_mps; /**< The maximum L2CAP PDU payload size, in bytes, that L2CAP shall
+ be able to transmit on L2CAP channels on connections with this
+ configuration. The minimum value is @ref BLE_L2CAP_MPS_MIN. */
+ uint8_t rx_queue_size; /**< Number of SDU data buffers that can be queued for reception per
+ L2CAP channel. The minimum value is one. */
+ uint8_t tx_queue_size; /**< Number of SDU data buffers that can be queued for transmission
+ per L2CAP channel. The minimum value is one. */
+ uint8_t ch_count; /**< Number of L2CAP channels the application can create per connection
+ with this configuration. The default value is zero, the maximum
+ value is @ref BLE_L2CAP_CH_COUNT_MAX.
+ @note if this parameter is set to zero, all other parameters in
+ @ref ble_l2cap_conn_cfg_t are ignored. */
+} ble_l2cap_conn_cfg_t;
+
+/**@brief L2CAP channel RX parameters. */
+typedef struct
+{
+ uint16_t rx_mtu; /**< The maximum L2CAP SDU size, in bytes, that L2CAP shall be able to
+ receive on this L2CAP channel.
+ - Must be equal to or greater than @ref BLE_L2CAP_MTU_MIN. */
+ uint16_t rx_mps; /**< The maximum L2CAP PDU payload size, in bytes, that L2CAP shall be
+ able to receive on this L2CAP channel.
+ - Must be equal to or greater than @ref BLE_L2CAP_MPS_MIN.
+ - Must be equal to or less than @ref ble_l2cap_conn_cfg_t::rx_mps. */
+ ble_data_t sdu_buf; /**< SDU data buffer for reception.
+ - If @ref ble_data_t::p_data is non-NULL, initial credits are
+ issued to the peer.
+ - If @ref ble_data_t::p_data is NULL, no initial credits are
+ issued to the peer. */
+} ble_l2cap_ch_rx_params_t;
+
+/**@brief L2CAP channel setup parameters. */
+typedef struct
+{
+ ble_l2cap_ch_rx_params_t rx_params; /**< L2CAP channel RX parameters. */
+ uint16_t le_psm; /**< LE Protocol/Service Multiplexer. Used when requesting
+ setup of an L2CAP channel, ignored otherwise. */
+ uint16_t status; /**< Status code, see @ref BLE_L2CAP_CH_STATUS_CODES.
+ Used when replying to a setup request of an L2CAP
+ channel, ignored otherwise. */
+} ble_l2cap_ch_setup_params_t;
+
+/**@brief L2CAP channel TX parameters. */
+typedef struct
+{
+ uint16_t tx_mtu; /**< The maximum L2CAP SDU size, in bytes, that L2CAP is able to
+ transmit on this L2CAP channel. */
+ uint16_t peer_mps; /**< The maximum L2CAP PDU payload size, in bytes, that the peer is
+ able to receive on this L2CAP channel. */
+ uint16_t tx_mps; /**< The maximum L2CAP PDU payload size, in bytes, that L2CAP is able
+ to transmit on this L2CAP channel. This is effective tx_mps,
+ selected by the SoftDevice as
+ MIN( @ref ble_l2cap_ch_tx_params_t::peer_mps, @ref ble_l2cap_conn_cfg_t::tx_mps ) */
+ uint16_t credits; /**< Initial credits given by the peer. */
+} ble_l2cap_ch_tx_params_t;
+
+/**@brief L2CAP Channel Setup Request event. */
+typedef struct
+{
+ ble_l2cap_ch_tx_params_t tx_params; /**< L2CAP channel TX parameters. */
+ uint16_t le_psm; /**< LE Protocol/Service Multiplexer. */
+} ble_l2cap_evt_ch_setup_request_t;
+
+/**@brief L2CAP Channel Setup Refused event. */
+typedef struct
+{
+ uint8_t source; /**< Source, see @ref BLE_L2CAP_CH_SETUP_REFUSED_SRCS */
+ uint16_t status; /**< Status code, see @ref BLE_L2CAP_CH_STATUS_CODES */
+} ble_l2cap_evt_ch_setup_refused_t;
+
+/**@brief L2CAP Channel Setup Completed event. */
+typedef struct
+{
+ ble_l2cap_ch_tx_params_t tx_params; /**< L2CAP channel TX parameters. */
+} ble_l2cap_evt_ch_setup_t;
+
+/**@brief L2CAP Channel SDU Data Duffer Released event. */
+typedef struct
+{
+ ble_data_t sdu_buf; /**< Returned reception or transmission SDU data buffer. The SoftDevice
+ returns SDU data buffers supplied by the application, which have
+ not yet been returned previously via a @ref BLE_L2CAP_EVT_CH_RX or
+ @ref BLE_L2CAP_EVT_CH_TX event. */
+} ble_l2cap_evt_ch_sdu_buf_released_t;
+
+/**@brief L2CAP Channel Credit received event. */
+typedef struct
+{
+ uint16_t credits; /**< Additional credits given by the peer. */
+} ble_l2cap_evt_ch_credit_t;
+
+/**@brief L2CAP Channel received SDU event. */
+typedef struct
+{
+ uint16_t sdu_len; /**< Total SDU length, in bytes. */
+ ble_data_t sdu_buf; /**< SDU data buffer.
+ @note If there is not enough space in the buffer
+ (sdu_buf.len < sdu_len) then the rest of the SDU will be
+ silently discarded by the SoftDevice. */
+} ble_l2cap_evt_ch_rx_t;
+
+/**@brief L2CAP Channel transmitted SDU event. */
+typedef struct
+{
+ ble_data_t sdu_buf; /**< SDU data buffer. */
+} ble_l2cap_evt_ch_tx_t;
+
+/**@brief L2CAP event structure. */
+typedef struct
+{
+ uint16_t conn_handle; /**< Connection Handle on which the event occured. */
+ uint16_t local_cid; /**< Local Channel ID of the L2CAP channel, or
+ @ref BLE_L2CAP_CID_INVALID if not present. */
+ union
+ {
+ ble_l2cap_evt_ch_setup_request_t ch_setup_request; /**< L2CAP Channel Setup Request Event Parameters. */
+ ble_l2cap_evt_ch_setup_refused_t ch_setup_refused; /**< L2CAP Channel Setup Refused Event Parameters. */
+ ble_l2cap_evt_ch_setup_t ch_setup; /**< L2CAP Channel Setup Completed Event Parameters. */
+ ble_l2cap_evt_ch_sdu_buf_released_t ch_sdu_buf_released;/**< L2CAP Channel SDU Data Buffer Released Event Parameters. */
+ ble_l2cap_evt_ch_credit_t credit; /**< L2CAP Channel Credit Received Event Parameters. */
+ ble_l2cap_evt_ch_rx_t rx; /**< L2CAP Channel SDU Received Event Parameters. */
+ ble_l2cap_evt_ch_tx_t tx; /**< L2CAP Channel SDU Transmitted Event Parameters. */
+ } params; /**< Event Parameters. */
+} ble_l2cap_evt_t;
+
+/** @} */
+
+/**@addtogroup BLE_L2CAP_FUNCTIONS Functions
+ * @{ */
+
+/**@brief Set up an L2CAP channel.
+ *
+ * @details This function is used to:
+ * - Request setup of an L2CAP channel: sends an LE Credit Based Connection Request packet to a peer.
+ * - Reply to a setup request of an L2CAP channel (if called in response to a
+ * @ref BLE_L2CAP_EVT_CH_SETUP_REQUEST event): sends an LE Credit Based Connection
+ * Response packet to a peer.
+ *
+ * @note A call to this function will require the application to keep the SDU data buffer alive
+ * until the SDU data buffer is returned in @ref BLE_L2CAP_EVT_CH_RX or
+ * @ref BLE_L2CAP_EVT_CH_SDU_BUF_RELEASED event.
+ *
+ * @events
+ * @event{@ref BLE_L2CAP_EVT_CH_SETUP, Setup successful.}
+ * @event{@ref BLE_L2CAP_EVT_CH_SETUP_REFUSED, Setup failed.}
+ * @endevents
+ *
+ * @mscs
+ * @mmsc{@ref BLE_L2CAP_CH_SETUP_MSC}
+ * @endmscs
+ *
+ * @param[in] conn_handle Connection Handle.
+ * @param[in,out] p_local_cid Pointer to a uint16_t containing Local Channel ID of the L2CAP channel:
+ * - As input: @ref BLE_L2CAP_CID_INVALID when requesting setup of an L2CAP
+ * channel or local_cid provided in the @ref BLE_L2CAP_EVT_CH_SETUP_REQUEST
+ * event when replying to a setup request of an L2CAP channel.
+ * - As output: local_cid for this channel.
+ * @param[in] p_params L2CAP channel parameters.
+ *
+ * @retval ::NRF_SUCCESS Successfully queued request or response for transmission.
+ * @retval ::NRF_ERROR_BUSY The stack is busy, process pending events and retry.
+ * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied.
+ * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid Connection Handle.
+ * @retval ::NRF_ERROR_INVALID_PARAM Invalid parameter(s) supplied.
+ * @retval ::NRF_ERROR_INVALID_LENGTH Supplied higher rx_mps than has been configured on this link.
+ * @retval ::NRF_ERROR_INVALID_STATE Invalid State to perform operation (L2CAP channel already set up).
+ * @retval ::NRF_ERROR_NOT_FOUND CID not found.
+ * @retval ::NRF_ERROR_RESOURCES The limit has been reached for available L2CAP channels,
+ * see @ref ble_l2cap_conn_cfg_t::ch_count.
+ */
+SVCALL(SD_BLE_L2CAP_CH_SETUP, uint32_t, sd_ble_l2cap_ch_setup(uint16_t conn_handle, uint16_t *p_local_cid, ble_l2cap_ch_setup_params_t const *p_params));
+
+/**@brief Release an L2CAP channel.
+ *
+ * @details This sends a Disconnection Request packet to a peer.
+ *
+ * @events
+ * @event{@ref BLE_L2CAP_EVT_CH_RELEASED, Release complete.}
+ * @endevents
+ *
+ * @mscs
+ * @mmsc{@ref BLE_L2CAP_CH_RELEASE_MSC}
+ * @endmscs
+ *
+ * @param[in] conn_handle Connection Handle.
+ * @param[in] local_cid Local Channel ID of the L2CAP channel.
+ *
+ * @retval ::NRF_SUCCESS Successfully queued request for transmission.
+ * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid Connection Handle.
+ * @retval ::NRF_ERROR_INVALID_STATE Invalid State to perform operation (Setup or release is
+ * in progress for the L2CAP channel).
+ * @retval ::NRF_ERROR_NOT_FOUND CID not found.
+ */
+SVCALL(SD_BLE_L2CAP_CH_RELEASE, uint32_t, sd_ble_l2cap_ch_release(uint16_t conn_handle, uint16_t local_cid));
+
+/**@brief Receive an SDU on an L2CAP channel.
+ *
+ * @details This may issue additional credits to the peer using an LE Flow Control Credit packet.
+ *
+ * @note A call to this function will require the application to keep the memory pointed by
+ * @ref ble_data_t::p_data alive until the SDU data buffer is returned in @ref BLE_L2CAP_EVT_CH_RX
+ * or @ref BLE_L2CAP_EVT_CH_SDU_BUF_RELEASED event.
+ *
+ * @note The SoftDevice can queue up to @ref ble_l2cap_conn_cfg_t::rx_queue_size SDU data buffers
+ * for reception per L2CAP channel.
+ *
+ * @events
+ * @event{@ref BLE_L2CAP_EVT_CH_RX, The SDU is received.}
+ * @endevents
+ *
+ * @mscs
+ * @mmsc{@ref BLE_L2CAP_CH_RX_MSC}
+ * @endmscs
+ *
+ * @param[in] conn_handle Connection Handle.
+ * @param[in] local_cid Local Channel ID of the L2CAP channel.
+ * @param[in] p_sdu_buf Pointer to the SDU data buffer.
+ *
+ * @retval ::NRF_SUCCESS Buffer accepted.
+ * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied.
+ * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid Connection Handle.
+ * @retval ::NRF_ERROR_INVALID_STATE Invalid State to perform operation (Setup or release is
+ * in progress for an L2CAP channel).
+ * @retval ::NRF_ERROR_NOT_FOUND CID not found.
+ * @retval ::NRF_ERROR_RESOURCES Too many SDU data buffers supplied. Wait for a
+ * @ref BLE_L2CAP_EVT_CH_RX event and retry.
+ */
+SVCALL(SD_BLE_L2CAP_CH_RX, uint32_t, sd_ble_l2cap_ch_rx(uint16_t conn_handle, uint16_t local_cid, ble_data_t const *p_sdu_buf));
+
+/**@brief Transmit an SDU on an L2CAP channel.
+ *
+ * @note A call to this function will require the application to keep the memory pointed by
+ * @ref ble_data_t::p_data alive until the SDU data buffer is returned in @ref BLE_L2CAP_EVT_CH_TX
+ * or @ref BLE_L2CAP_EVT_CH_SDU_BUF_RELEASED event.
+ *
+ * @note The SoftDevice can queue up to @ref ble_l2cap_conn_cfg_t::tx_queue_size SDUs for
+ * transmission per L2CAP channel.
+ *
+ * @note The application can keep track of the available credits for transmission by following
+ * the procedure below:
+ * - Store initial credits given by the peer in a variable.
+ * (Initial credits are provided in a @ref BLE_L2CAP_EVT_CH_SETUP event.)
+ * - Decrement the variable, which stores the currently available credits, by
+ * ceiling((@ref ble_data_t::len + 2) / tx_mps) when a call to this function returns
+ * @ref NRF_SUCCESS. (tx_mps is provided in a @ref BLE_L2CAP_EVT_CH_SETUP event.)
+ * - Increment the variable, which stores the currently available credits, by additional
+ * credits given by the peer in a @ref BLE_L2CAP_EVT_CH_CREDIT event.
+ *
+ * @events
+ * @event{@ref BLE_L2CAP_EVT_CH_TX, The SDU is transmitted.}
+ * @endevents
+ *
+ * @mscs
+ * @mmsc{@ref BLE_L2CAP_CH_TX_MSC}
+ * @endmscs
+ *
+ * @param[in] conn_handle Connection Handle.
+ * @param[in] local_cid Local Channel ID of the L2CAP channel.
+ * @param[in] p_sdu_buf Pointer to the SDU data buffer.
+ *
+ * @retval ::NRF_SUCCESS Successfully queued L2CAP SDU for transmission.
+ * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied.
+ * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid Connection Handle.
+ * @retval ::NRF_ERROR_INVALID_STATE Invalid State to perform operation (Setup or release is
+ * in progress for the L2CAP channel).
+ * @retval ::NRF_ERROR_NOT_FOUND CID not found.
+ * @retval ::NRF_ERROR_DATA_SIZE Invalid SDU length supplied, must not be more than
+ * @ref ble_l2cap_ch_tx_params_t::tx_mtu provided in
+ * @ref BLE_L2CAP_EVT_CH_SETUP event.
+ * @retval ::NRF_ERROR_RESOURCES Too many SDUs queued for transmission. Wait for a
+ * @ref BLE_L2CAP_EVT_CH_TX event and retry.
+ */
+SVCALL(SD_BLE_L2CAP_CH_TX, uint32_t, sd_ble_l2cap_ch_tx(uint16_t conn_handle, uint16_t local_cid, ble_data_t const *p_sdu_buf));
+
+/**@brief Advanced SDU reception flow control.
+ *
+ * @details Adjust the way the SoftDevice issues credits to the peer.
+ * This may issue additional credits to the peer using an LE Flow Control Credit packet.
+ *
+ * @mscs
+ * @mmsc{@ref BLE_L2CAP_CH_FLOW_CONTROL_MSC}
+ * @endmscs
+ *
+ * @param[in] conn_handle Connection Handle.
+ * @param[in] local_cid Local Channel ID of the L2CAP channel or @ref BLE_L2CAP_CID_INVALID to set
+ * the value that will be used for newly created channels.
+ * @param[in] credits Number of credits that the SoftDevice will make sure the peer has every
+ * time it starts using a new reception buffer.
+ * - @ref BLE_L2CAP_CREDITS_DEFAULT is the default value the SoftDevice will
+ * use if this function is not called.
+ * - If set to zero, the SoftDevice will stop issuing credits for new reception
+ * buffers the application provides or has provided. SDU reception that is
+ * currently ongoing will be allowed to complete.
+ * @param[out] p_credits NULL or pointer to a uint16_t. If a valid pointer is provided, it will be
+ * written by the SoftDevice with the number of credits that is or will be
+ * available to the peer. If the value written by the SoftDevice is 0 when
+ * credits parameter was set to 0, the peer will not be able to send more
+ * data until more credits are provided by calling this function again with
+ * credits > 0. This parameter is ignored when local_cid is set to
+ * @ref BLE_L2CAP_CID_INVALID.
+ *
+ * @note Application should take care when setting number of credits higher than default value. In
+ * this case the application must make sure that the SoftDevice always has reception buffers
+ * available (see @ref sd_ble_l2cap_ch_rx) for that channel. If the SoftDevice does not have
+ * such buffers available, packets may be NACKed on the Link Layer and all Bluetooth traffic
+ * on the connection handle may be stalled until the SoftDevice again has an available
+ * reception buffer. This applies even if the application has used this call to set the
+ * credits back to default, or zero.
+ *
+ * @retval ::NRF_SUCCESS Flow control parameters accepted.
+ * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied.
+ * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid Connection Handle.
+ * @retval ::NRF_ERROR_INVALID_STATE Invalid State to perform operation (Setup or release is
+ * in progress for an L2CAP channel).
+ * @retval ::NRF_ERROR_NOT_FOUND CID not found.
+ */
+SVCALL(SD_BLE_L2CAP_CH_FLOW_CONTROL, uint32_t, sd_ble_l2cap_ch_flow_control(uint16_t conn_handle, uint16_t local_cid, uint16_t credits, uint16_t *p_credits));
+
+/** @} */
+
+#ifdef __cplusplus
+}
+#endif
+#endif // BLE_L2CAP_H__
+
+/**
+ @}
+*/
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/softdevice/s140/headers/ble_ranges.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/softdevice/s140/headers/ble_ranges.h
new file mode 100644
index 0000000..0935bca
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/softdevice/s140/headers/ble_ranges.h
@@ -0,0 +1,156 @@
+/*
+ * Copyright (c) 2012 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ */
+
+/**
+ @addtogroup BLE_COMMON
+ @{
+ @defgroup ble_ranges Module specific SVC, event and option number subranges
+ @{
+
+ @brief Definition of SVC, event and option number subranges for each API module.
+
+ @note
+ SVCs, event and option numbers are split into subranges for each API module.
+ Each module receives its entire allocated range of SVC calls, whether implemented or not,
+ but return BLE_ERROR_NOT_SUPPORTED for unimplemented or undefined calls in its range.
+
+ Note that the symbols BLE_<module>_SVC_LAST is the end of the allocated SVC range,
+ rather than the last SVC function call actually defined and implemented.
+
+ Specific SVC, event and option values are defined in each module's ble_<module>.h file,
+ which defines names of each individual SVC code based on the range start value.
+*/
+
+#ifndef BLE_RANGES_H__
+#define BLE_RANGES_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define BLE_SVC_BASE 0x60 /**< Common BLE SVC base. */
+#define BLE_SVC_LAST 0x6B /**< Common BLE SVC last. */
+
+#define BLE_GAP_SVC_BASE 0x6C /**< GAP BLE SVC base. */
+#define BLE_GAP_SVC_LAST 0x9A /**< GAP BLE SVC last. */
+
+#define BLE_GATTC_SVC_BASE 0x9B /**< GATTC BLE SVC base. */
+#define BLE_GATTC_SVC_LAST 0xA7 /**< GATTC BLE SVC last. */
+
+#define BLE_GATTS_SVC_BASE 0xA8 /**< GATTS BLE SVC base. */
+#define BLE_GATTS_SVC_LAST 0xB7 /**< GATTS BLE SVC last. */
+
+#define BLE_L2CAP_SVC_BASE 0xB8 /**< L2CAP BLE SVC base. */
+#define BLE_L2CAP_SVC_LAST 0xBF /**< L2CAP BLE SVC last. */
+
+
+#define BLE_EVT_INVALID 0x00 /**< Invalid BLE Event. */
+
+#define BLE_EVT_BASE 0x01 /**< Common BLE Event base. */
+#define BLE_EVT_LAST 0x0F /**< Common BLE Event last. */
+
+#define BLE_GAP_EVT_BASE 0x10 /**< GAP BLE Event base. */
+#define BLE_GAP_EVT_LAST 0x2F /**< GAP BLE Event last. */
+
+#define BLE_GATTC_EVT_BASE 0x30 /**< GATTC BLE Event base. */
+#define BLE_GATTC_EVT_LAST 0x4F /**< GATTC BLE Event last. */
+
+#define BLE_GATTS_EVT_BASE 0x50 /**< GATTS BLE Event base. */
+#define BLE_GATTS_EVT_LAST 0x6F /**< GATTS BLE Event last. */
+
+#define BLE_L2CAP_EVT_BASE 0x70 /**< L2CAP BLE Event base. */
+#define BLE_L2CAP_EVT_LAST 0x8F /**< L2CAP BLE Event last. */
+
+
+#define BLE_OPT_INVALID 0x00 /**< Invalid BLE Option. */
+
+#define BLE_OPT_BASE 0x01 /**< Common BLE Option base. */
+#define BLE_OPT_LAST 0x1F /**< Common BLE Option last. */
+
+#define BLE_GAP_OPT_BASE 0x20 /**< GAP BLE Option base. */
+#define BLE_GAP_OPT_LAST 0x3F /**< GAP BLE Option last. */
+
+#define BLE_GATT_OPT_BASE 0x40 /**< GATT BLE Option base. */
+#define BLE_GATT_OPT_LAST 0x5F /**< GATT BLE Option last. */
+
+#define BLE_GATTC_OPT_BASE 0x60 /**< GATTC BLE Option base. */
+#define BLE_GATTC_OPT_LAST 0x7F /**< GATTC BLE Option last. */
+
+#define BLE_GATTS_OPT_BASE 0x80 /**< GATTS BLE Option base. */
+#define BLE_GATTS_OPT_LAST 0x9F /**< GATTS BLE Option last. */
+
+#define BLE_L2CAP_OPT_BASE 0xA0 /**< L2CAP BLE Option base. */
+#define BLE_L2CAP_OPT_LAST 0xBF /**< L2CAP BLE Option last. */
+
+
+#define BLE_CFG_INVALID 0x00 /**< Invalid BLE configuration. */
+
+#define BLE_CFG_BASE 0x01 /**< Common BLE configuration base. */
+#define BLE_CFG_LAST 0x1F /**< Common BLE configuration last. */
+
+#define BLE_CONN_CFG_BASE 0x20 /**< BLE connection configuration base. */
+#define BLE_CONN_CFG_LAST 0x3F /**< BLE connection configuration last. */
+
+#define BLE_GAP_CFG_BASE 0x40 /**< GAP BLE configuration base. */
+#define BLE_GAP_CFG_LAST 0x5F /**< GAP BLE configuration last. */
+
+#define BLE_GATT_CFG_BASE 0x60 /**< GATT BLE configuration base. */
+#define BLE_GATT_CFG_LAST 0x7F /**< GATT BLE configuration last. */
+
+#define BLE_GATTC_CFG_BASE 0x80 /**< GATTC BLE configuration base. */
+#define BLE_GATTC_CFG_LAST 0x9F /**< GATTC BLE configuration last. */
+
+#define BLE_GATTS_CFG_BASE 0xA0 /**< GATTS BLE configuration base. */
+#define BLE_GATTS_CFG_LAST 0xBF /**< GATTS BLE configuration last. */
+
+#define BLE_L2CAP_CFG_BASE 0xC0 /**< L2CAP BLE configuration base. */
+#define BLE_L2CAP_CFG_LAST 0xDF /**< L2CAP BLE configuration last. */
+
+
+
+
+
+#ifdef __cplusplus
+}
+#endif
+#endif /* BLE_RANGES_H__ */
+
+/**
+ @}
+ @}
+*/
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/softdevice/s140/headers/ble_types.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/softdevice/s140/headers/ble_types.h
new file mode 100644
index 0000000..88c9318
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/softdevice/s140/headers/ble_types.h
@@ -0,0 +1,215 @@
+/*
+ * Copyright (c) 2012 - 2017, 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ */
+
+/**
+ @addtogroup BLE_COMMON
+ @{
+ @defgroup ble_types Common types and macro definitions
+ @{
+
+ @brief Common types and macro definitions for the BLE SoftDevice.
+ */
+
+#ifndef BLE_TYPES_H__
+#define BLE_TYPES_H__
+
+#include <stdint.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** @addtogroup BLE_TYPES_DEFINES Defines
+ * @{ */
+
+/** @defgroup BLE_CONN_HANDLES BLE Connection Handles
+ * @{ */
+#define BLE_CONN_HANDLE_INVALID 0xFFFF /**< Invalid Connection Handle. */
+#define BLE_CONN_HANDLE_ALL 0xFFFE /**< Applies to all Connection Handles. */
+/** @} */
+
+
+/** @defgroup BLE_UUID_VALUES Assigned Values for BLE UUIDs
+ * @{ */
+/* Generic UUIDs, applicable to all services */
+#define BLE_UUID_UNKNOWN 0x0000 /**< Reserved UUID. */
+#define BLE_UUID_SERVICE_PRIMARY 0x2800 /**< Primary Service. */
+#define BLE_UUID_SERVICE_SECONDARY 0x2801 /**< Secondary Service. */
+#define BLE_UUID_SERVICE_INCLUDE 0x2802 /**< Include. */
+#define BLE_UUID_CHARACTERISTIC 0x2803 /**< Characteristic. */
+#define BLE_UUID_DESCRIPTOR_CHAR_EXT_PROP 0x2900 /**< Characteristic Extended Properties Descriptor. */
+#define BLE_UUID_DESCRIPTOR_CHAR_USER_DESC 0x2901 /**< Characteristic User Description Descriptor. */
+#define BLE_UUID_DESCRIPTOR_CLIENT_CHAR_CONFIG 0x2902 /**< Client Characteristic Configuration Descriptor. */
+#define BLE_UUID_DESCRIPTOR_SERVER_CHAR_CONFIG 0x2903 /**< Server Characteristic Configuration Descriptor. */
+#define BLE_UUID_DESCRIPTOR_CHAR_PRESENTATION_FORMAT 0x2904 /**< Characteristic Presentation Format Descriptor. */
+#define BLE_UUID_DESCRIPTOR_CHAR_AGGREGATE_FORMAT 0x2905 /**< Characteristic Aggregate Format Descriptor. */
+/* GATT specific UUIDs */
+#define BLE_UUID_GATT 0x1801 /**< Generic Attribute Profile. */
+#define BLE_UUID_GATT_CHARACTERISTIC_SERVICE_CHANGED 0x2A05 /**< Service Changed Characteristic. */
+/* GAP specific UUIDs */
+#define BLE_UUID_GAP 0x1800 /**< Generic Access Profile. */
+#define BLE_UUID_GAP_CHARACTERISTIC_DEVICE_NAME 0x2A00 /**< Device Name Characteristic. */
+#define BLE_UUID_GAP_CHARACTERISTIC_APPEARANCE 0x2A01 /**< Appearance Characteristic. */
+#define BLE_UUID_GAP_CHARACTERISTIC_RECONN_ADDR 0x2A03 /**< Reconnection Address Characteristic. */
+#define BLE_UUID_GAP_CHARACTERISTIC_PPCP 0x2A04 /**< Peripheral Preferred Connection Parameters Characteristic. */
+#define BLE_UUID_GAP_CHARACTERISTIC_CAR 0x2AA6 /**< Central Address Resolution Characteristic. */
+#define BLE_UUID_GAP_CHARACTERISTIC_RPA_ONLY 0x2AC9 /**< Resolvable Private Address Only Characteristic. */
+/** @} */
+
+
+/** @defgroup BLE_UUID_TYPES Types of UUID
+ * @{ */
+#define BLE_UUID_TYPE_UNKNOWN 0x00 /**< Invalid UUID type. */
+#define BLE_UUID_TYPE_BLE 0x01 /**< Bluetooth SIG UUID (16-bit). */
+#define BLE_UUID_TYPE_VENDOR_BEGIN 0x02 /**< Vendor UUID types start at this index (128-bit). */
+/** @} */
+
+
+/** @defgroup BLE_APPEARANCES Bluetooth Appearance values
+ * @note Retrieved from http://developer.bluetooth.org/gatt/characteristics/Pages/CharacteristicViewer.aspx?u=org.bluetooth.characteristic.gap.appearance.xml
+ * @{ */
+#define BLE_APPEARANCE_UNKNOWN 0 /**< Unknown. */
+#define BLE_APPEARANCE_GENERIC_PHONE 64 /**< Generic Phone. */
+#define BLE_APPEARANCE_GENERIC_COMPUTER 128 /**< Generic Computer. */
+#define BLE_APPEARANCE_GENERIC_WATCH 192 /**< Generic Watch. */
+#define BLE_APPEARANCE_WATCH_SPORTS_WATCH 193 /**< Watch: Sports Watch. */
+#define BLE_APPEARANCE_GENERIC_CLOCK 256 /**< Generic Clock. */
+#define BLE_APPEARANCE_GENERIC_DISPLAY 320 /**< Generic Display. */
+#define BLE_APPEARANCE_GENERIC_REMOTE_CONTROL 384 /**< Generic Remote Control. */
+#define BLE_APPEARANCE_GENERIC_EYE_GLASSES 448 /**< Generic Eye-glasses. */
+#define BLE_APPEARANCE_GENERIC_TAG 512 /**< Generic Tag. */
+#define BLE_APPEARANCE_GENERIC_KEYRING 576 /**< Generic Keyring. */
+#define BLE_APPEARANCE_GENERIC_MEDIA_PLAYER 640 /**< Generic Media Player. */
+#define BLE_APPEARANCE_GENERIC_BARCODE_SCANNER 704 /**< Generic Barcode Scanner. */
+#define BLE_APPEARANCE_GENERIC_THERMOMETER 768 /**< Generic Thermometer. */
+#define BLE_APPEARANCE_THERMOMETER_EAR 769 /**< Thermometer: Ear. */
+#define BLE_APPEARANCE_GENERIC_HEART_RATE_SENSOR 832 /**< Generic Heart rate Sensor. */
+#define BLE_APPEARANCE_HEART_RATE_SENSOR_HEART_RATE_BELT 833 /**< Heart Rate Sensor: Heart Rate Belt. */
+#define BLE_APPEARANCE_GENERIC_BLOOD_PRESSURE 896 /**< Generic Blood Pressure. */
+#define BLE_APPEARANCE_BLOOD_PRESSURE_ARM 897 /**< Blood Pressure: Arm. */
+#define BLE_APPEARANCE_BLOOD_PRESSURE_WRIST 898 /**< Blood Pressure: Wrist. */
+#define BLE_APPEARANCE_GENERIC_HID 960 /**< Human Interface Device (HID). */
+#define BLE_APPEARANCE_HID_KEYBOARD 961 /**< Keyboard (HID Subtype). */
+#define BLE_APPEARANCE_HID_MOUSE 962 /**< Mouse (HID Subtype). */
+#define BLE_APPEARANCE_HID_JOYSTICK 963 /**< Joystick (HID Subtype). */
+#define BLE_APPEARANCE_HID_GAMEPAD 964 /**< Gamepad (HID Subtype). */
+#define BLE_APPEARANCE_HID_DIGITIZERSUBTYPE 965 /**< Digitizer Tablet (HID Subtype). */
+#define BLE_APPEARANCE_HID_CARD_READER 966 /**< Card Reader (HID Subtype). */
+#define BLE_APPEARANCE_HID_DIGITAL_PEN 967 /**< Digital Pen (HID Subtype). */
+#define BLE_APPEARANCE_HID_BARCODE 968 /**< Barcode Scanner (HID Subtype). */
+#define BLE_APPEARANCE_GENERIC_GLUCOSE_METER 1024 /**< Generic Glucose Meter. */
+#define BLE_APPEARANCE_GENERIC_RUNNING_WALKING_SENSOR 1088 /**< Generic Running Walking Sensor. */
+#define BLE_APPEARANCE_RUNNING_WALKING_SENSOR_IN_SHOE 1089 /**< Running Walking Sensor: In-Shoe. */
+#define BLE_APPEARANCE_RUNNING_WALKING_SENSOR_ON_SHOE 1090 /**< Running Walking Sensor: On-Shoe. */
+#define BLE_APPEARANCE_RUNNING_WALKING_SENSOR_ON_HIP 1091 /**< Running Walking Sensor: On-Hip. */
+#define BLE_APPEARANCE_GENERIC_CYCLING 1152 /**< Generic Cycling. */
+#define BLE_APPEARANCE_CYCLING_CYCLING_COMPUTER 1153 /**< Cycling: Cycling Computer. */
+#define BLE_APPEARANCE_CYCLING_SPEED_SENSOR 1154 /**< Cycling: Speed Sensor. */
+#define BLE_APPEARANCE_CYCLING_CADENCE_SENSOR 1155 /**< Cycling: Cadence Sensor. */
+#define BLE_APPEARANCE_CYCLING_POWER_SENSOR 1156 /**< Cycling: Power Sensor. */
+#define BLE_APPEARANCE_CYCLING_SPEED_CADENCE_SENSOR 1157 /**< Cycling: Speed and Cadence Sensor. */
+#define BLE_APPEARANCE_GENERIC_PULSE_OXIMETER 3136 /**< Generic Pulse Oximeter. */
+#define BLE_APPEARANCE_PULSE_OXIMETER_FINGERTIP 3137 /**< Fingertip (Pulse Oximeter subtype). */
+#define BLE_APPEARANCE_PULSE_OXIMETER_WRIST_WORN 3138 /**< Wrist Worn(Pulse Oximeter subtype). */
+#define BLE_APPEARANCE_GENERIC_WEIGHT_SCALE 3200 /**< Generic Weight Scale. */
+#define BLE_APPEARANCE_GENERIC_OUTDOOR_SPORTS_ACT 5184 /**< Generic Outdoor Sports Activity. */
+#define BLE_APPEARANCE_OUTDOOR_SPORTS_ACT_LOC_DISP 5185 /**< Location Display Device (Outdoor Sports Activity subtype). */
+#define BLE_APPEARANCE_OUTDOOR_SPORTS_ACT_LOC_AND_NAV_DISP 5186 /**< Location and Navigation Display Device (Outdoor Sports Activity subtype). */
+#define BLE_APPEARANCE_OUTDOOR_SPORTS_ACT_LOC_POD 5187 /**< Location Pod (Outdoor Sports Activity subtype). */
+#define BLE_APPEARANCE_OUTDOOR_SPORTS_ACT_LOC_AND_NAV_POD 5188 /**< Location and Navigation Pod (Outdoor Sports Activity subtype). */
+/** @} */
+
+/** @brief Set .type and .uuid fields of ble_uuid_struct to specified UUID value. */
+#define BLE_UUID_BLE_ASSIGN(instance, value) do {\
+ instance.type = BLE_UUID_TYPE_BLE; \
+ instance.uuid = value;} while(0)
+
+/** @brief Copy type and uuid members from src to dst ble_uuid_t pointer. Both pointers must be valid/non-null. */
+#define BLE_UUID_COPY_PTR(dst, src) do {\
+ (dst)->type = (src)->type; \
+ (dst)->uuid = (src)->uuid;} while(0)
+
+/** @brief Copy type and uuid members from src to dst ble_uuid_t struct. */
+#define BLE_UUID_COPY_INST(dst, src) do {\
+ (dst).type = (src).type; \
+ (dst).uuid = (src).uuid;} while(0)
+
+/** @brief Compare for equality both type and uuid members of two (valid, non-null) ble_uuid_t pointers. */
+#define BLE_UUID_EQ(p_uuid1, p_uuid2) \
+ (((p_uuid1)->type == (p_uuid2)->type) && ((p_uuid1)->uuid == (p_uuid2)->uuid))
+
+/** @brief Compare for difference both type and uuid members of two (valid, non-null) ble_uuid_t pointers. */
+#define BLE_UUID_NEQ(p_uuid1, p_uuid2) \
+ (((p_uuid1)->type != (p_uuid2)->type) || ((p_uuid1)->uuid != (p_uuid2)->uuid))
+
+/** @} */
+
+/** @addtogroup BLE_TYPES_STRUCTURES Structures
+ * @{ */
+
+/** @brief 128 bit UUID values. */
+typedef struct
+{
+ uint8_t uuid128[16]; /**< Little-Endian UUID bytes. */
+} ble_uuid128_t;
+
+/** @brief Bluetooth Low Energy UUID type, encapsulates both 16-bit and 128-bit UUIDs. */
+typedef struct
+{
+ uint16_t uuid; /**< 16-bit UUID value or octets 12-13 of 128-bit UUID. */
+ uint8_t type; /**< UUID type, see @ref BLE_UUID_TYPES. If type is @ref BLE_UUID_TYPE_UNKNOWN, the value of uuid is undefined. */
+} ble_uuid_t;
+
+/**@brief Data structure. */
+typedef struct
+{
+ uint8_t *p_data; /**< Pointer to the data buffer provided to/from the application. */
+ uint16_t len; /**< Length of the data buffer, in bytes. */
+} ble_data_t;
+
+/** @} */
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* BLE_TYPES_H__ */
+
+/**
+ @}
+ @}
+*/
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/softdevice/s140/headers/nrf52/nrf_mbr.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/softdevice/s140/headers/nrf52/nrf_mbr.h
new file mode 100644
index 0000000..e0c80e2
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/softdevice/s140/headers/nrf52/nrf_mbr.h
@@ -0,0 +1,242 @@
+/*
+ * Copyright (c) 2014 - 2017, 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ */
+
+/**
+ @defgroup nrf_mbr_api Master Boot Record API
+ @{
+
+ @brief APIs for updating SoftDevice and BootLoader
+
+*/
+
+#ifndef NRF_MBR_H__
+#define NRF_MBR_H__
+
+#include "nrf_svc.h"
+#include <stdint.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** @addtogroup NRF_MBR_DEFINES Defines
+ * @{ */
+
+/**@brief MBR SVC Base number. */
+#define MBR_SVC_BASE (0x18)
+
+/**@brief Page size in words. */
+#define MBR_PAGE_SIZE_IN_WORDS (1024)
+
+/** @brief The size that must be reserved for the MBR when a SoftDevice is written to flash.
+This is the offset where the first byte of the SoftDevice hex file is written.*/
+#define MBR_SIZE (0x1000)
+
+/** @} */
+
+/** @addtogroup NRF_MBR_ENUMS Enumerations
+ * @{ */
+
+/**@brief nRF Master Boot Record API SVC numbers. */
+enum NRF_MBR_SVCS
+{
+ SD_MBR_COMMAND = MBR_SVC_BASE, /**< ::sd_mbr_command */
+};
+
+/**@brief Possible values for ::sd_mbr_command_t.command */
+enum NRF_MBR_COMMANDS
+{
+ SD_MBR_COMMAND_COPY_BL, /**< Copy a new BootLoader. @see ::sd_mbr_command_copy_bl_t*/
+ SD_MBR_COMMAND_COPY_SD, /**< Copy a new SoftDevice. @see ::sd_mbr_command_copy_sd_t*/
+ SD_MBR_COMMAND_INIT_SD, /**< Initialize forwarding interrupts to SD, and run reset function in SD. Does not require any parameters in ::sd_mbr_command_t params.*/
+ SD_MBR_COMMAND_COMPARE, /**< This command works like memcmp. @see ::sd_mbr_command_compare_t*/
+ SD_MBR_COMMAND_VECTOR_TABLE_BASE_SET, /**< Change the address the MBR starts after a reset. @see ::sd_mbr_command_vector_table_base_set_t*/
+ SD_MBR_COMMAND_RESERVED,
+ SD_MBR_COMMAND_IRQ_FORWARD_ADDRESS_SET, /**< Start forwarding all interrupts to this address. @see ::sd_mbr_command_irq_forward_address_set_t*/
+};
+
+/** @} */
+
+/** @addtogroup NRF_MBR_TYPES Types
+ * @{ */
+
+/**@brief This command copies part of a new SoftDevice
+ *
+ * The destination area is erased before copying.
+ * If dst is in the middle of a flash page, that whole flash page will be erased.
+ * If (dst+len) is in the middle of a flash page, that whole flash page will be erased.
+ *
+ * The user of this function is responsible for setting the BPROT registers.
+ *
+ * @retval ::NRF_SUCCESS indicates that the contents of the memory blocks where copied correctly.
+ * @retval ::NRF_ERROR_INTERNAL indicates that the contents of the memory blocks where not verified correctly after copying.
+ */
+typedef struct
+{
+ uint32_t *src; /**< Pointer to the source of data to be copied.*/
+ uint32_t *dst; /**< Pointer to the destination where the content is to be copied.*/
+ uint32_t len; /**< Number of 32 bit words to copy. Must be a multiple of @ref MBR_PAGE_SIZE_IN_WORDS words.*/
+} sd_mbr_command_copy_sd_t;
+
+
+/**@brief This command works like memcmp, but takes the length in words.
+ *
+ * @retval ::NRF_SUCCESS indicates that the contents of both memory blocks are equal.
+ * @retval ::NRF_ERROR_NULL indicates that the contents of the memory blocks are not equal.
+ */
+typedef struct
+{
+ uint32_t *ptr1; /**< Pointer to block of memory. */
+ uint32_t *ptr2; /**< Pointer to block of memory. */
+ uint32_t len; /**< Number of 32 bit words to compare.*/
+} sd_mbr_command_compare_t;
+
+
+/**@brief This command copies a new BootLoader.
+ *
+ * With this command, destination of BootLoader is always the address written in
+ * NRF_UICR->BOOTADDR.
+ *
+ * Destination is erased by this function.
+ * If (destination+bl_len) is in the middle of a flash page, that whole flash page will be erased.
+ *
+ * This function will use the flash protect peripheral (BPROT or ACL) to protect the flash that is
+ * not intended to be written.
+ *
+ * On success, this function will not return. It will start the new BootLoader from reset-vector as normal.
+ *
+ * @retval ::NRF_ERROR_INTERNAL indicates an internal error that should not happen.
+ * @retval ::NRF_ERROR_FORBIDDEN if NRF_UICR->BOOTADDR is not set.
+ * @retval ::NRF_ERROR_INVALID_LENGTH if parameters attempts to read or write outside flash area.
+ * @retval ::NRF_ERROR_NO_MEM if no parameter page is provided (see SoftDevice Specification for more info)
+ */
+typedef struct
+{
+ uint32_t *bl_src; /**< Pointer to the source of the Bootloader to be be copied.*/
+ uint32_t bl_len; /**< Number of 32 bit words to copy for BootLoader. */
+} sd_mbr_command_copy_bl_t;
+
+/**@brief Change the address the MBR starts after a reset
+ *
+ * Once this function has been called, this address is where the MBR will start to forward
+ * interrupts to after a reset.
+ *
+ * To restore default forwarding this function should be called with @ref address set to 0. The
+ * MBR will then start forwarding interrupts to the address in NFR_UICR->BOOTADDR or to the
+ * SoftDevice if the BOOTADDR is not set.
+ *
+ * On success, this function will not return. It will reset the device.
+ *
+ * @retval ::NRF_ERROR_INTERNAL indicates an internal error that should not happen.
+ * @retval ::NRF_ERROR_INVALID_ADDR if parameter address is outside of the flash size.
+ * @retval ::NRF_ERROR_NO_MEM if no parameter page is provided (see SoftDevice Specification for more info)
+ */
+typedef struct
+{
+ uint32_t address; /**< The base address of the interrupt vector table for forwarded interrupts.*/
+} sd_mbr_command_vector_table_base_set_t;
+
+/**@brief Sets the base address of the interrupt vector table for interrupts forwarded from the MBR
+ *
+ * Unlike sd_mbr_command_vector_table_base_set_t, this function does not reset, and it does not
+ * change where the MBR starts after reset.
+ *
+ * @retval ::NRF_SUCCESS
+ */
+typedef struct
+{
+ uint32_t address; /**< The base address of the interrupt vector table for forwarded interrupts.*/
+} sd_mbr_command_irq_forward_address_set_t;
+
+/**@brief Input structure containing data used when calling ::sd_mbr_command
+ *
+ * Depending on what command value that is set, the corresponding params value type must also be
+ * set. See @ref NRF_MBR_COMMANDS for command types and corresponding params value type. If command
+ * @ref SD_MBR_COMMAND_INIT_SD is set, it is not necessary to set any values under params.
+ */
+typedef struct
+{
+ uint32_t command; /**< Type of command to be issued. See @ref NRF_MBR_COMMANDS. */
+ union
+ {
+ sd_mbr_command_copy_sd_t copy_sd; /**< Parameters for copy SoftDevice.*/
+ sd_mbr_command_compare_t compare; /**< Parameters for verify.*/
+ sd_mbr_command_copy_bl_t copy_bl; /**< Parameters for copy BootLoader. Requires parameter page. */
+ sd_mbr_command_vector_table_base_set_t base_set; /**< Parameters for vector table base set. Requires parameter page.*/
+ sd_mbr_command_irq_forward_address_set_t irq_forward_address_set; /**< Parameters for irq forward address set*/
+ } params; /**< Command parameters. */
+} sd_mbr_command_t;
+
+/** @} */
+
+/** @addtogroup NRF_MBR_FUNCTIONS Functions
+ * @{ */
+
+/**@brief Issue Master Boot Record commands
+ *
+ * Commands used when updating a SoftDevice and bootloader.
+ *
+ * The @ref SD_MBR_COMMAND_COPY_BL and @ref SD_MBR_COMMAND_VECTOR_TABLE_BASE_SET requires
+ * parameters to be retained by the MBR when resetting the IC. This is done in a separate flash
+ * page provided by the application. The UICR register UICR.NRFFW[1] must be set to an address
+ * corresponding to a page in the application flash space. This page will be cleared by the MBR and
+ * used to store the command before reset. When the UICR.NRFFW[1] field is set the page it refers
+ * to must not be used by the application. If the UICR.NRFFW[1] is set to 0xFFFFFFFF (the default)
+ * MBR commands which use flash will be unavailable and return @ref NRF_ERROR_NO_MEM.
+ *
+ * @param[in] param Pointer to a struct describing the command.
+ *
+ * @note For return values, see ::sd_mbr_command_copy_sd_t, ::sd_mbr_command_copy_bl_t,
+ * ::sd_mbr_command_compare_t, ::sd_mbr_command_vector_table_base_set_t,
+ * ::sd_mbr_command_irq_forward_address_set_t
+ *
+ * @retval ::NRF_ERROR_NO_MEM if UICR.NRFFW[1] is not set (i.e. is 0xFFFFFFFF).
+ * @retval ::NRF_ERROR_INVALID_PARAM if an invalid command is given.
+*/
+SVCALL(SD_MBR_COMMAND, uint32_t, sd_mbr_command(sd_mbr_command_t* param));
+
+/** @} */
+
+#ifdef __cplusplus
+}
+#endif
+#endif // NRF_MBR_H__
+
+/**
+ @}
+*/
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/softdevice/s140/headers/nrf_error.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/softdevice/s140/headers/nrf_error.h
new file mode 100644
index 0000000..6badee9
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/softdevice/s140/headers/nrf_error.h
@@ -0,0 +1,90 @@
+/*
+ * Copyright (c) 2014 - 2017, 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ */
+
+ /**
+ @defgroup nrf_error SoftDevice Global Error Codes
+ @{
+
+ @brief Global Error definitions
+*/
+
+/* Header guard */
+#ifndef NRF_ERROR_H__
+#define NRF_ERROR_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** @defgroup NRF_ERRORS_BASE Error Codes Base number definitions
+ * @{ */
+#define NRF_ERROR_BASE_NUM (0x0) ///< Global error base
+#define NRF_ERROR_SDM_BASE_NUM (0x1000) ///< SDM error base
+#define NRF_ERROR_SOC_BASE_NUM (0x2000) ///< SoC error base
+#define NRF_ERROR_STK_BASE_NUM (0x3000) ///< STK error base
+/** @} */
+
+#define NRF_SUCCESS (NRF_ERROR_BASE_NUM + 0) ///< Successful command
+#define NRF_ERROR_SVC_HANDLER_MISSING (NRF_ERROR_BASE_NUM + 1) ///< SVC handler is missing
+#define NRF_ERROR_SOFTDEVICE_NOT_ENABLED (NRF_ERROR_BASE_NUM + 2) ///< SoftDevice has not been enabled
+#define NRF_ERROR_INTERNAL (NRF_ERROR_BASE_NUM + 3) ///< Internal Error
+#define NRF_ERROR_NO_MEM (NRF_ERROR_BASE_NUM + 4) ///< No Memory for operation
+#define NRF_ERROR_NOT_FOUND (NRF_ERROR_BASE_NUM + 5) ///< Not found
+#define NRF_ERROR_NOT_SUPPORTED (NRF_ERROR_BASE_NUM + 6) ///< Not supported
+#define NRF_ERROR_INVALID_PARAM (NRF_ERROR_BASE_NUM + 7) ///< Invalid Parameter
+#define NRF_ERROR_INVALID_STATE (NRF_ERROR_BASE_NUM + 8) ///< Invalid state, operation disallowed in this state
+#define NRF_ERROR_INVALID_LENGTH (NRF_ERROR_BASE_NUM + 9) ///< Invalid Length
+#define NRF_ERROR_INVALID_FLAGS (NRF_ERROR_BASE_NUM + 10) ///< Invalid Flags
+#define NRF_ERROR_INVALID_DATA (NRF_ERROR_BASE_NUM + 11) ///< Invalid Data
+#define NRF_ERROR_DATA_SIZE (NRF_ERROR_BASE_NUM + 12) ///< Invalid Data size
+#define NRF_ERROR_TIMEOUT (NRF_ERROR_BASE_NUM + 13) ///< Operation timed out
+#define NRF_ERROR_NULL (NRF_ERROR_BASE_NUM + 14) ///< Null Pointer
+#define NRF_ERROR_FORBIDDEN (NRF_ERROR_BASE_NUM + 15) ///< Forbidden Operation
+#define NRF_ERROR_INVALID_ADDR (NRF_ERROR_BASE_NUM + 16) ///< Bad Memory Address
+#define NRF_ERROR_BUSY (NRF_ERROR_BASE_NUM + 17) ///< Busy
+#define NRF_ERROR_CONN_COUNT (NRF_ERROR_BASE_NUM + 18) ///< Maximum connection count exceeded.
+#define NRF_ERROR_RESOURCES (NRF_ERROR_BASE_NUM + 19) ///< Not enough resources for operation
+
+#ifdef __cplusplus
+}
+#endif
+#endif // NRF_ERROR_H__
+
+/**
+ @}
+*/
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/softdevice/s140/headers/nrf_error_sdm.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/softdevice/s140/headers/nrf_error_sdm.h
new file mode 100644
index 0000000..530959b
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/softdevice/s140/headers/nrf_error_sdm.h
@@ -0,0 +1,70 @@
+/*
+ * Copyright (c) 2012 - 2017, 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ */
+
+ /**
+ @addtogroup nrf_sdm_api
+ @{
+ @defgroup nrf_sdm_error SoftDevice Manager Error Codes
+ @{
+
+ @brief Error definitions for the SDM API
+*/
+
+/* Header guard */
+#ifndef NRF_ERROR_SDM_H__
+#define NRF_ERROR_SDM_H__
+
+#include "nrf_error.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define NRF_ERROR_SDM_LFCLK_SOURCE_UNKNOWN (NRF_ERROR_SDM_BASE_NUM + 0) ///< Unknown LFCLK source.
+#define NRF_ERROR_SDM_INCORRECT_INTERRUPT_CONFIGURATION (NRF_ERROR_SDM_BASE_NUM + 1) ///< Incorrect interrupt configuration (can be caused by using illegal priority levels, or having enabled SoftDevice interrupts).
+#define NRF_ERROR_SDM_INCORRECT_CLENR0 (NRF_ERROR_SDM_BASE_NUM + 2) ///< Incorrect CLENR0 (can be caused by erroneous SoftDevice flashing).
+
+#ifdef __cplusplus
+}
+#endif
+#endif // NRF_ERROR_SDM_H__
+
+/**
+ @}
+ @}
+*/
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/softdevice/s140/headers/nrf_error_soc.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/softdevice/s140/headers/nrf_error_soc.h
new file mode 100644
index 0000000..1e784b8
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/softdevice/s140/headers/nrf_error_soc.h
@@ -0,0 +1,85 @@
+/*
+ * Copyright (c) 2012 - 2017, 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ */
+
+/**
+ @addtogroup nrf_soc_api
+ @{
+ @defgroup nrf_soc_error SoC Library Error Codes
+ @{
+
+ @brief Error definitions for the SoC library
+
+*/
+
+/* Header guard */
+#ifndef NRF_ERROR_SOC_H__
+#define NRF_ERROR_SOC_H__
+
+#include "nrf_error.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Mutex Errors */
+#define NRF_ERROR_SOC_MUTEX_ALREADY_TAKEN (NRF_ERROR_SOC_BASE_NUM + 0) ///< Mutex already taken
+
+/* NVIC errors */
+#define NRF_ERROR_SOC_NVIC_INTERRUPT_NOT_AVAILABLE (NRF_ERROR_SOC_BASE_NUM + 1) ///< NVIC interrupt not available
+#define NRF_ERROR_SOC_NVIC_INTERRUPT_PRIORITY_NOT_ALLOWED (NRF_ERROR_SOC_BASE_NUM + 2) ///< NVIC interrupt priority not allowed
+#define NRF_ERROR_SOC_NVIC_SHOULD_NOT_RETURN (NRF_ERROR_SOC_BASE_NUM + 3) ///< NVIC should not return
+
+/* Power errors */
+#define NRF_ERROR_SOC_POWER_MODE_UNKNOWN (NRF_ERROR_SOC_BASE_NUM + 4) ///< Power mode unknown
+#define NRF_ERROR_SOC_POWER_POF_THRESHOLD_UNKNOWN (NRF_ERROR_SOC_BASE_NUM + 5) ///< Power POF threshold unknown
+#define NRF_ERROR_SOC_POWER_OFF_SHOULD_NOT_RETURN (NRF_ERROR_SOC_BASE_NUM + 6) ///< Power off should not return
+
+/* Rand errors */
+#define NRF_ERROR_SOC_RAND_NOT_ENOUGH_VALUES (NRF_ERROR_SOC_BASE_NUM + 7) ///< RAND not enough values
+
+/* PPI errors */
+#define NRF_ERROR_SOC_PPI_INVALID_CHANNEL (NRF_ERROR_SOC_BASE_NUM + 8) ///< Invalid PPI Channel
+#define NRF_ERROR_SOC_PPI_INVALID_GROUP (NRF_ERROR_SOC_BASE_NUM + 9) ///< Invalid PPI Group
+
+#ifdef __cplusplus
+}
+#endif
+#endif // NRF_ERROR_SOC_H__
+/**
+ @}
+ @}
+*/
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/softdevice/s140/headers/nrf_nvic.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/softdevice/s140/headers/nrf_nvic.h
new file mode 100644
index 0000000..f5c7e8e
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/softdevice/s140/headers/nrf_nvic.h
@@ -0,0 +1,486 @@
+/*
+ * Copyright (c) 2016 - 2017, 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ */
+
+/**
+ * @defgroup nrf_nvic_api SoftDevice NVIC API
+ * @{
+ *
+ * @note In order to use this module, the following code has to be added to a .c file:
+ * \code
+ * nrf_nvic_state_t nrf_nvic_state = {0};
+ * \endcode
+ *
+ * @note Definitions and declarations starting with __ (double underscore) in this header file are
+ * not intended for direct use by the application.
+ *
+ * @brief APIs for the accessing NVIC when using a SoftDevice.
+ *
+ */
+
+#ifndef NRF_NVIC_H__
+#define NRF_NVIC_H__
+
+#include <stdint.h>
+#include "nrf.h"
+#include "nrf_svc.h"
+#include "nrf_error.h"
+#include "nrf_error_soc.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**@addtogroup NRF_NVIC_DEFINES Defines
+ * @{ */
+
+/**@defgroup NRF_NVIC_ISER_DEFINES SoftDevice NVIC internal definitions
+ * @{ */
+
+#define __NRF_NVIC_NVMC_IRQn (30) /**< The peripheral ID of the NVMC. IRQ numbers are used to identify peripherals, but the NVMC doesn't have an IRQ number in the MDK. */
+
+#define __NRF_NVIC_ISER_COUNT (2) /**< The number of ISER/ICER registers in the NVIC that are used. */
+
+/**@brief Interrupts used by the SoftDevice, with IRQn in the range 0-31. */
+#define __NRF_NVIC_SD_IRQS_0 ((uint32_t)( \
+ (1U << POWER_CLOCK_IRQn) \
+ | (1U << RADIO_IRQn) \
+ | (1U << RTC0_IRQn) \
+ | (1U << TIMER0_IRQn) \
+ | (1U << RNG_IRQn) \
+ | (1U << ECB_IRQn) \
+ | (1U << CCM_AAR_IRQn) \
+ | (1U << TEMP_IRQn) \
+ | (1U << __NRF_NVIC_NVMC_IRQn) \
+ | (1U << (uint32_t)SWI5_IRQn) \
+ ))
+
+/**@brief Interrupts used by the SoftDevice, with IRQn in the range 32-63. */
+#define __NRF_NVIC_SD_IRQS_1 ((uint32_t)0)
+
+/**@brief Interrupts available for to application, with IRQn in the range 0-31. */
+#define __NRF_NVIC_APP_IRQS_0 (~__NRF_NVIC_SD_IRQS_0)
+
+/**@brief Interrupts available for to application, with IRQn in the range 32-63. */
+#define __NRF_NVIC_APP_IRQS_1 (~__NRF_NVIC_SD_IRQS_1)
+
+/**@} */
+
+/**@} */
+
+/**@addtogroup NRF_NVIC_VARIABLES Variables
+ * @{ */
+
+/**@brief Type representing the state struct for the SoftDevice NVIC module. */
+typedef struct
+{
+ uint32_t volatile __irq_masks[__NRF_NVIC_ISER_COUNT]; /**< IRQs enabled by the application in the NVIC. */
+ uint32_t volatile __cr_flag; /**< Non-zero if already in a critical region */
+} nrf_nvic_state_t;
+
+/**@brief Variable keeping the state for the SoftDevice NVIC module. This must be declared in an
+ * application source file. */
+extern nrf_nvic_state_t nrf_nvic_state;
+
+/**@} */
+
+/**@addtogroup NRF_NVIC_INTERNAL_FUNCTIONS SoftDevice NVIC internal functions
+ * @{ */
+
+/**@brief Disables IRQ interrupts globally, including the SoftDevice's interrupts.
+ *
+ * @retval The value of PRIMASK prior to disabling the interrupts.
+ */
+__STATIC_INLINE int __sd_nvic_irq_disable(void);
+
+/**@brief Enables IRQ interrupts globally, including the SoftDevice's interrupts.
+ */
+__STATIC_INLINE void __sd_nvic_irq_enable(void);
+
+/**@brief Checks if IRQn is available to application
+ * @param[in] IRQn IRQ to check
+ *
+ * @retval 1 (true) if the IRQ to check is available to the application
+ */
+__STATIC_INLINE uint32_t __sd_nvic_app_accessible_irq(IRQn_Type IRQn);
+
+/**@brief Checks if priority is available to application
+ * @param[in] priority priority to check
+ *
+ * @retval 1 (true) if the priority to check is available to the application
+ */
+__STATIC_INLINE uint32_t __sd_nvic_is_app_accessible_priority(uint32_t priority);
+
+/**@} */
+
+/**@addtogroup NRF_NVIC_FUNCTIONS SoftDevice NVIC public functions
+ * @{ */
+
+/**@brief Enable External Interrupt.
+ * @note Corresponds to NVIC_EnableIRQ in CMSIS.
+ *
+ * @pre IRQn is valid and not reserved by the stack.
+ *
+ * @param[in] IRQn See the NVIC_EnableIRQ documentation in CMSIS.
+ *
+ * @retval ::NRF_SUCCESS The interrupt was enabled.
+ * @retval ::NRF_ERROR_SOC_NVIC_INTERRUPT_NOT_AVAILABLE The interrupt is not available for the application.
+ * @retval ::NRF_ERROR_SOC_NVIC_INTERRUPT_PRIORITY_NOT_ALLOWED The interrupt has a priority not available for the application.
+ */
+__STATIC_INLINE uint32_t sd_nvic_EnableIRQ(IRQn_Type IRQn);
+
+/**@brief Disable External Interrupt.
+ * @note Corresponds to NVIC_DisableIRQ in CMSIS.
+ *
+ * @pre IRQn is valid and not reserved by the stack.
+ *
+ * @param[in] IRQn See the NVIC_DisableIRQ documentation in CMSIS.
+ *
+ * @retval ::NRF_SUCCESS The interrupt was disabled.
+ * @retval ::NRF_ERROR_SOC_NVIC_INTERRUPT_NOT_AVAILABLE The interrupt is not available for the application.
+ */
+__STATIC_INLINE uint32_t sd_nvic_DisableIRQ(IRQn_Type IRQn);
+
+/**@brief Get Pending Interrupt.
+ * @note Corresponds to NVIC_GetPendingIRQ in CMSIS.
+ *
+ * @pre IRQn is valid and not reserved by the stack.
+ *
+ * @param[in] IRQn See the NVIC_GetPendingIRQ documentation in CMSIS.
+ * @param[out] p_pending_irq Return value from NVIC_GetPendingIRQ.
+ *
+ * @retval ::NRF_SUCCESS The interrupt is available for the application.
+ * @retval ::NRF_ERROR_SOC_NVIC_INTERRUPT_NOT_AVAILABLE IRQn is not available for the application.
+ */
+__STATIC_INLINE uint32_t sd_nvic_GetPendingIRQ(IRQn_Type IRQn, uint32_t * p_pending_irq);
+
+/**@brief Set Pending Interrupt.
+ * @note Corresponds to NVIC_SetPendingIRQ in CMSIS.
+ *
+ * @pre IRQn is valid and not reserved by the stack.
+ *
+ * @param[in] IRQn See the NVIC_SetPendingIRQ documentation in CMSIS.
+ *
+ * @retval ::NRF_SUCCESS The interrupt is set pending.
+ * @retval ::NRF_ERROR_SOC_NVIC_INTERRUPT_NOT_AVAILABLE IRQn is not available for the application.
+ */
+__STATIC_INLINE uint32_t sd_nvic_SetPendingIRQ(IRQn_Type IRQn);
+
+/**@brief Clear Pending Interrupt.
+ * @note Corresponds to NVIC_ClearPendingIRQ in CMSIS.
+ *
+ * @pre IRQn is valid and not reserved by the stack.
+ *
+ * @param[in] IRQn See the NVIC_ClearPendingIRQ documentation in CMSIS.
+ *
+ * @retval ::NRF_SUCCESS The interrupt pending flag is cleared.
+ * @retval ::NRF_ERROR_SOC_NVIC_INTERRUPT_NOT_AVAILABLE IRQn is not available for the application.
+ */
+__STATIC_INLINE uint32_t sd_nvic_ClearPendingIRQ(IRQn_Type IRQn);
+
+/**@brief Set Interrupt Priority.
+ * @note Corresponds to NVIC_SetPriority in CMSIS.
+ *
+ * @pre IRQn is valid and not reserved by the stack.
+ * @pre Priority is valid and not reserved by the stack.
+ *
+ * @param[in] IRQn See the NVIC_SetPriority documentation in CMSIS.
+ * @param[in] priority A valid IRQ priority for use by the application.
+ *
+ * @retval ::NRF_SUCCESS The interrupt and priority level is available for the application.
+ * @retval ::NRF_ERROR_SOC_NVIC_INTERRUPT_NOT_AVAILABLE IRQn is not available for the application.
+ * @retval ::NRF_ERROR_SOC_NVIC_INTERRUPT_PRIORITY_NOT_ALLOWED The interrupt priority is not available for the application.
+ */
+__STATIC_INLINE uint32_t sd_nvic_SetPriority(IRQn_Type IRQn, uint32_t priority);
+
+/**@brief Get Interrupt Priority.
+ * @note Corresponds to NVIC_GetPriority in CMSIS.
+ *
+ * @pre IRQn is valid and not reserved by the stack.
+ *
+ * @param[in] IRQn See the NVIC_GetPriority documentation in CMSIS.
+ * @param[out] p_priority Return value from NVIC_GetPriority.
+ *
+ * @retval ::NRF_SUCCESS The interrupt priority is returned in p_priority.
+ * @retval ::NRF_ERROR_SOC_NVIC_INTERRUPT_NOT_AVAILABLE - IRQn is not available for the application.
+ */
+__STATIC_INLINE uint32_t sd_nvic_GetPriority(IRQn_Type IRQn, uint32_t * p_priority);
+
+/**@brief System Reset.
+ * @note Corresponds to NVIC_SystemReset in CMSIS.
+ *
+ * @retval ::NRF_ERROR_SOC_NVIC_SHOULD_NOT_RETURN
+ */
+__STATIC_INLINE uint32_t sd_nvic_SystemReset(void);
+
+/**@brief Enter critical region.
+ *
+ * @post Application interrupts will be disabled.
+ * @note sd_nvic_critical_region_enter() and ::sd_nvic_critical_region_exit() must be called in matching pairs inside each
+ * execution context
+ * @sa sd_nvic_critical_region_exit
+ *
+ * @param[out] p_is_nested_critical_region If 1, the application is now in a nested critical region.
+ *
+ * @retval ::NRF_SUCCESS
+ */
+__STATIC_INLINE uint32_t sd_nvic_critical_region_enter(uint8_t * p_is_nested_critical_region);
+
+/**@brief Exit critical region.
+ *
+ * @pre Application has entered a critical region using ::sd_nvic_critical_region_enter.
+ * @post If not in a nested critical region, the application interrupts will restored to the state before ::sd_nvic_critical_region_enter was called.
+ *
+ * @param[in] is_nested_critical_region If this is set to 1, the critical region won't be exited. @sa sd_nvic_critical_region_enter.
+ *
+ * @retval ::NRF_SUCCESS
+ */
+__STATIC_INLINE uint32_t sd_nvic_critical_region_exit(uint8_t is_nested_critical_region);
+
+/**@} */
+
+#ifndef SUPPRESS_INLINE_IMPLEMENTATION
+
+__STATIC_INLINE int __sd_nvic_irq_disable(void)
+{
+ int pm = __get_PRIMASK();
+ __disable_irq();
+ return pm;
+}
+
+__STATIC_INLINE void __sd_nvic_irq_enable(void)
+{
+ __enable_irq();
+}
+
+__STATIC_INLINE uint32_t __sd_nvic_app_accessible_irq(IRQn_Type IRQn)
+{
+ if (IRQn < 32)
+ {
+ return ((1UL<<IRQn) & __NRF_NVIC_APP_IRQS_0) != 0;
+ }
+ else if (IRQn < 64)
+ {
+ return ((1UL<<(IRQn-32)) & __NRF_NVIC_APP_IRQS_1) != 0;
+ }
+ else
+ {
+ return 1;
+ }
+}
+
+__STATIC_INLINE uint32_t __sd_nvic_is_app_accessible_priority(uint32_t priority)
+{
+ if(priority >= (1 << __NVIC_PRIO_BITS))
+ {
+ return 0;
+ }
+ if( priority == 0
+ || priority == 1
+ || priority == 4
+ )
+ {
+ return 0;
+ }
+ return 1;
+}
+
+
+__STATIC_INLINE uint32_t sd_nvic_EnableIRQ(IRQn_Type IRQn)
+{
+ if (!__sd_nvic_app_accessible_irq(IRQn))
+ {
+ return NRF_ERROR_SOC_NVIC_INTERRUPT_NOT_AVAILABLE;
+ }
+ if (!__sd_nvic_is_app_accessible_priority(NVIC_GetPriority(IRQn)))
+ {
+ return NRF_ERROR_SOC_NVIC_INTERRUPT_PRIORITY_NOT_ALLOWED;
+ }
+
+ if (nrf_nvic_state.__cr_flag)
+ {
+ nrf_nvic_state.__irq_masks[(uint32_t)((int32_t)IRQn) >> 5] |= (uint32_t)(1 << ((uint32_t)((int32_t)IRQn) & (uint32_t)0x1F));
+ }
+ else
+ {
+ NVIC_EnableIRQ(IRQn);
+ }
+ return NRF_SUCCESS;
+}
+
+__STATIC_INLINE uint32_t sd_nvic_DisableIRQ(IRQn_Type IRQn)
+{
+ if (!__sd_nvic_app_accessible_irq(IRQn))
+ {
+ return NRF_ERROR_SOC_NVIC_INTERRUPT_NOT_AVAILABLE;
+ }
+
+ if (nrf_nvic_state.__cr_flag)
+ {
+ nrf_nvic_state.__irq_masks[(uint32_t)((int32_t)IRQn) >> 5] &= ~(1UL << ((uint32_t)(IRQn) & 0x1F));
+ }
+ else
+ {
+ NVIC_DisableIRQ(IRQn);
+ }
+
+ return NRF_SUCCESS;
+}
+
+__STATIC_INLINE uint32_t sd_nvic_GetPendingIRQ(IRQn_Type IRQn, uint32_t * p_pending_irq)
+{
+ if (__sd_nvic_app_accessible_irq(IRQn))
+ {
+ *p_pending_irq = NVIC_GetPendingIRQ(IRQn);
+ return NRF_SUCCESS;
+ }
+ else
+ {
+ return NRF_ERROR_SOC_NVIC_INTERRUPT_NOT_AVAILABLE;
+ }
+}
+
+__STATIC_INLINE uint32_t sd_nvic_SetPendingIRQ(IRQn_Type IRQn)
+{
+ if (__sd_nvic_app_accessible_irq(IRQn))
+ {
+ NVIC_SetPendingIRQ(IRQn);
+ return NRF_SUCCESS;
+ }
+ else
+ {
+ return NRF_ERROR_SOC_NVIC_INTERRUPT_NOT_AVAILABLE;
+ }
+}
+
+__STATIC_INLINE uint32_t sd_nvic_ClearPendingIRQ(IRQn_Type IRQn)
+{
+ if (__sd_nvic_app_accessible_irq(IRQn))
+ {
+ NVIC_ClearPendingIRQ(IRQn);
+ return NRF_SUCCESS;
+ }
+ else
+ {
+ return NRF_ERROR_SOC_NVIC_INTERRUPT_NOT_AVAILABLE;
+ }
+}
+
+__STATIC_INLINE uint32_t sd_nvic_SetPriority(IRQn_Type IRQn, uint32_t priority)
+{
+ if (!__sd_nvic_app_accessible_irq(IRQn))
+ {
+ return NRF_ERROR_SOC_NVIC_INTERRUPT_NOT_AVAILABLE;
+ }
+
+ if (!__sd_nvic_is_app_accessible_priority(priority))
+ {
+ return NRF_ERROR_SOC_NVIC_INTERRUPT_PRIORITY_NOT_ALLOWED;
+ }
+
+ NVIC_SetPriority(IRQn, (uint32_t)priority);
+ return NRF_SUCCESS;
+}
+
+__STATIC_INLINE uint32_t sd_nvic_GetPriority(IRQn_Type IRQn, uint32_t * p_priority)
+{
+ if (__sd_nvic_app_accessible_irq(IRQn))
+ {
+ *p_priority = (NVIC_GetPriority(IRQn) & 0xFF);
+ return NRF_SUCCESS;
+ }
+ else
+ {
+ return NRF_ERROR_SOC_NVIC_INTERRUPT_NOT_AVAILABLE;
+ }
+}
+
+__STATIC_INLINE uint32_t sd_nvic_SystemReset(void)
+{
+ NVIC_SystemReset();
+ return NRF_ERROR_SOC_NVIC_SHOULD_NOT_RETURN;
+}
+
+__STATIC_INLINE uint32_t sd_nvic_critical_region_enter(uint8_t * p_is_nested_critical_region)
+{
+ int was_masked = __sd_nvic_irq_disable();
+ if (!nrf_nvic_state.__cr_flag)
+ {
+ nrf_nvic_state.__cr_flag = 1;
+ nrf_nvic_state.__irq_masks[0] = ( NVIC->ICER[0] & __NRF_NVIC_APP_IRQS_0 );
+ NVIC->ICER[0] = __NRF_NVIC_APP_IRQS_0;
+ nrf_nvic_state.__irq_masks[1] = ( NVIC->ICER[1] & __NRF_NVIC_APP_IRQS_1 );
+ NVIC->ICER[1] = __NRF_NVIC_APP_IRQS_1;
+ *p_is_nested_critical_region = 0;
+ }
+ else
+ {
+ *p_is_nested_critical_region = 1;
+ }
+ if (!was_masked)
+ {
+ __sd_nvic_irq_enable();
+ }
+ return NRF_SUCCESS;
+}
+
+__STATIC_INLINE uint32_t sd_nvic_critical_region_exit(uint8_t is_nested_critical_region)
+{
+ if (nrf_nvic_state.__cr_flag && (is_nested_critical_region == 0))
+ {
+ int was_masked = __sd_nvic_irq_disable();
+ NVIC->ISER[0] = nrf_nvic_state.__irq_masks[0];
+ NVIC->ISER[1] = nrf_nvic_state.__irq_masks[1];
+ nrf_nvic_state.__cr_flag = 0;
+ if (!was_masked)
+ {
+ __sd_nvic_irq_enable();
+ }
+ }
+
+ return NRF_SUCCESS;
+}
+
+#endif /* SUPPRESS_INLINE_IMPLEMENTATION */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // NRF_NVIC_H__
+
+/**@} */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/softdevice/s140/headers/nrf_sd_def.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/softdevice/s140/headers/nrf_sd_def.h
new file mode 100644
index 0000000..c9ab241
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/softdevice/s140/headers/nrf_sd_def.h
@@ -0,0 +1,59 @@
+/**
+ * Copyright (c) 2015 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+#ifndef NRF_SD_DEF_H__
+#define NRF_SD_DEF_H__
+
+#include <stdint.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define SD_PPI_CHANNELS_USED 0xFFFE0000uL /**< PPI channels utilized by SotfDevice (not available to the application). */
+#define SD_PPI_GROUPS_USED 0x0000000CuL /**< PPI groups utilized by SoftDevice (not available to the application). */
+#define SD_TIMERS_USED 0x00000001uL /**< Timers used by SoftDevice. */
+#define SD_SWI_USED 0x0000003CuL /**< Software interrupts used by SoftDevice */
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* NRF_SD_DEF_H__ */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/softdevice/s140/headers/nrf_sdm.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/softdevice/s140/headers/nrf_sdm.h
new file mode 100644
index 0000000..8c48d93
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/softdevice/s140/headers/nrf_sdm.h
@@ -0,0 +1,358 @@
+/*
+ * Copyright (c) 2015 - 2017, 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ */
+
+/**
+ @defgroup nrf_sdm_api SoftDevice Manager API
+ @{
+
+ @brief APIs for SoftDevice management.
+
+*/
+
+#ifndef NRF_SDM_H__
+#define NRF_SDM_H__
+
+#include <stdint.h>
+#include "nrf.h"
+#include "nrf_svc.h"
+#include "nrf_error.h"
+#include "nrf_error_sdm.h"
+#include "nrf_soc.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** @addtogroup NRF_SDM_DEFINES Defines
+ * @{ */
+#ifdef NRFSOC_DOXYGEN
+/// Declared in nrf_mbr.h
+#define MBR_SIZE 0
+#warning test
+#endif
+
+/** @brief The major version for the SoftDevice binary distributed with this header file. */
+#define SD_MAJOR_VERSION (6)
+
+/** @brief The minor version for the SoftDevice binary distributed with this header file. */
+#define SD_MINOR_VERSION (0)
+
+/** @brief The bugfix version for the SoftDevice binary distributed with this header file. */
+#define SD_BUGFIX_VERSION (0)
+
+/** @brief The full version number for the SoftDevice binary this header file was distributed
+ * with, as 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 SD_VERSION (SD_MAJOR_VERSION * 1000000 + SD_MINOR_VERSION * 1000 + SD_BUGFIX_VERSION)
+
+/** @brief SoftDevice Manager SVC Base number. */
+#define SDM_SVC_BASE 0x10
+
+/** @brief SoftDevice unique string size in bytes. */
+#define SD_UNIQUE_STR_SIZE 20
+
+/** @brief Invalid info field. Returned when an info field does not exist. */
+#define SDM_INFO_FIELD_INVALID (0)
+
+/** @brief Defines the SoftDevice Information Structure location (address) as an offset from
+the start of the SoftDevice (without MBR)*/
+#define SOFTDEVICE_INFO_STRUCT_OFFSET (0x2000)
+
+/** @brief Defines the absolute SoftDevice Information Structure location (address) when the
+ * SoftDevice is installed just above the MBR (the usual case). */
+#define SOFTDEVICE_INFO_STRUCT_ADDRESS (SOFTDEVICE_INFO_STRUCT_OFFSET + MBR_SIZE)
+
+/** @brief Defines the offset for the SoftDevice Information Structure size value relative to the
+ * SoftDevice base address. The size value is of type uint8_t. */
+#define SD_INFO_STRUCT_SIZE_OFFSET (SOFTDEVICE_INFO_STRUCT_OFFSET)
+
+/** @brief Defines the offset for the SoftDevice size value relative to the SoftDevice base address.
+ * The size value is of type uint32_t. */
+#define SD_SIZE_OFFSET (SOFTDEVICE_INFO_STRUCT_OFFSET + 0x08)
+
+/** @brief Defines the offset for FWID value relative to the SoftDevice base address. The FWID value
+ * is of type uint16_t. */
+#define SD_FWID_OFFSET (SOFTDEVICE_INFO_STRUCT_OFFSET + 0x0C)
+
+/** @brief Defines the offset for the SoftDevice ID relative to the SoftDevice base address. The ID
+ * is of type uint32_t. */
+#define SD_ID_OFFSET (SOFTDEVICE_INFO_STRUCT_OFFSET + 0x10)
+
+/** @brief Defines the offset for the SoftDevice version relative to the SoftDevice base address in
+ * the same format as @ref SD_VERSION, stored as an uint32_t. */
+#define SD_VERSION_OFFSET (SOFTDEVICE_INFO_STRUCT_OFFSET + 0x14)
+
+/** @brief Defines the offset for the SoftDevice unique string relative to the SoftDevice base address.
+ * The SD_UNIQUE_STR is stored as an array of uint8_t. The size of array is @ref SD_UNIQUE_STR_SIZE.
+ */
+#define SD_UNIQUE_STR_OFFSET (SOFTDEVICE_INFO_STRUCT_OFFSET + 0x18)
+
+/** @brief Defines a macro for retrieving the actual SoftDevice Information Structure size value
+ * from a given base address. Use @ref MBR_SIZE as the argument when the SoftDevice is
+ * installed just above the MBR (the usual case). */
+#define SD_INFO_STRUCT_SIZE_GET(baseaddr) (*((uint8_t *) ((baseaddr) + SD_INFO_STRUCT_SIZE_OFFSET)))
+
+/** @brief Defines a macro for retrieving the actual SoftDevice size value from a given base
+ * address. Use @ref MBR_SIZE as the argument when the SoftDevice is installed just above
+ * the MBR (the usual case). */
+#define SD_SIZE_GET(baseaddr) (*((uint32_t *) ((baseaddr) + SD_SIZE_OFFSET)))
+
+/** @brief Defines a macro for retrieving the actual FWID value from a given base address. Use
+ * @ref MBR_SIZE as the argument when the SoftDevice is installed just above the MBR (the usual
+ * case). */
+#define SD_FWID_GET(baseaddr) (*((uint16_t *) ((baseaddr) + SD_FWID_OFFSET)))
+
+/** @brief Defines a macro for retrieving the actual SoftDevice ID from a given base address. Use
+ * @ref MBR_SIZE as the argument when the SoftDevice is installed just above the MBR (the
+ * usual case). */
+#define SD_ID_GET(baseaddr) ((SD_INFO_STRUCT_SIZE_GET(baseaddr) > (SD_ID_OFFSET - SOFTDEVICE_INFO_STRUCT_OFFSET)) \
+ ? (*((uint32_t *) ((baseaddr) + SD_ID_OFFSET))) : SDM_INFO_FIELD_INVALID)
+
+/** @brief Defines a macro for retrieving the actual SoftDevice version from a given base address.
+ * Use @ref MBR_SIZE as the argument when the SoftDevice is installed just above the MBR
+ * (the usual case). */
+#define SD_VERSION_GET(baseaddr) ((SD_INFO_STRUCT_SIZE_GET(baseaddr) > (SD_VERSION_OFFSET - SOFTDEVICE_INFO_STRUCT_OFFSET)) \
+ ? (*((uint32_t *) ((baseaddr) + SD_VERSION_OFFSET))) : SDM_INFO_FIELD_INVALID)
+
+/** @brief Defines a macro for retrieving the address of SoftDevice unique str based on a given base address.
+ * Use @ref MBR_SIZE as the argument when the SoftDevice is installed just above the MBR
+ * (the usual case). */
+#define SD_UNIQUE_STR_ADDR_GET(baseaddr) ((SD_INFO_STRUCT_SIZE_GET(baseaddr) > (SD_UNIQUE_STR_OFFSET - SOFTDEVICE_INFO_STRUCT_OFFSET)) \
+ ? (((uint8_t *) ((baseaddr) + SD_UNIQUE_STR_OFFSET))) : SDM_INFO_FIELD_INVALID)
+
+/**@defgroup NRF_FAULT_ID_RANGES Fault ID ranges
+ * @{ */
+#define NRF_FAULT_ID_SD_RANGE_START 0x00000000 /**< SoftDevice ID range start. */
+#define NRF_FAULT_ID_APP_RANGE_START 0x00001000 /**< Application ID range start. */
+/**@} */
+
+/**@defgroup NRF_FAULT_IDS Fault ID types
+ * @{ */
+#define NRF_FAULT_ID_SD_ASSERT (NRF_FAULT_ID_SD_RANGE_START + 1) /**< SoftDevice assertion. The info parameter is reserved for future used. */
+#define NRF_FAULT_ID_APP_MEMACC (NRF_FAULT_ID_APP_RANGE_START + 1) /**< Application invalid memory access. The info parameter will contain 0x00000000,
+ in case of SoftDevice RAM access violation. In case of SoftDevice peripheral
+ register violation the info parameter will contain the sub-region number of
+ PREGION[0], on whose address range the disallowed write access caused the
+ memory access fault. */
+/**@} */
+
+/** @} */
+
+/** @addtogroup NRF_SDM_ENUMS Enumerations
+ * @{ */
+
+/**@brief nRF SoftDevice Manager API SVC numbers. */
+enum NRF_SD_SVCS
+{
+ SD_SOFTDEVICE_ENABLE = SDM_SVC_BASE, /**< ::sd_softdevice_enable */
+ SD_SOFTDEVICE_DISABLE, /**< ::sd_softdevice_disable */
+ SD_SOFTDEVICE_IS_ENABLED, /**< ::sd_softdevice_is_enabled */
+ SD_SOFTDEVICE_VECTOR_TABLE_BASE_SET, /**< ::sd_softdevice_vector_table_base_set */
+ SVC_SDM_LAST /**< Placeholder for last SDM SVC */
+};
+
+/** @} */
+
+/** @addtogroup NRF_SDM_DEFINES Defines
+ * @{ */
+
+/**@defgroup NRF_CLOCK_LF_ACCURACY Clock accuracy
+ * @{ */
+
+#define NRF_CLOCK_LF_ACCURACY_250_PPM (0) /**< Default: 250 ppm */
+#define NRF_CLOCK_LF_ACCURACY_500_PPM (1) /**< 500 ppm */
+#define NRF_CLOCK_LF_ACCURACY_150_PPM (2) /**< 150 ppm */
+#define NRF_CLOCK_LF_ACCURACY_100_PPM (3) /**< 100 ppm */
+#define NRF_CLOCK_LF_ACCURACY_75_PPM (4) /**< 75 ppm */
+#define NRF_CLOCK_LF_ACCURACY_50_PPM (5) /**< 50 ppm */
+#define NRF_CLOCK_LF_ACCURACY_30_PPM (6) /**< 30 ppm */
+#define NRF_CLOCK_LF_ACCURACY_20_PPM (7) /**< 20 ppm */
+#define NRF_CLOCK_LF_ACCURACY_10_PPM (8) /**< 10 ppm */
+#define NRF_CLOCK_LF_ACCURACY_5_PPM (9) /**< 5 ppm */
+#define NRF_CLOCK_LF_ACCURACY_2_PPM (10) /**< 2 ppm */
+#define NRF_CLOCK_LF_ACCURACY_1_PPM (11) /**< 1 ppm */
+
+/** @} */
+
+/**@defgroup NRF_CLOCK_LF_SRC Possible LFCLK oscillator sources
+ * @{ */
+
+#define NRF_CLOCK_LF_SRC_RC (0) /**< LFCLK RC oscillator. */
+#define NRF_CLOCK_LF_SRC_XTAL (1) /**< LFCLK crystal oscillator. */
+#define NRF_CLOCK_LF_SRC_SYNTH (2) /**< LFCLK Synthesized from HFCLK. */
+
+/** @} */
+
+/** @} */
+
+/** @addtogroup NRF_SDM_TYPES Types
+ * @{ */
+
+/**@brief Type representing LFCLK oscillator source. */
+typedef struct
+{
+ uint8_t source; /**< LF oscillator clock source, see @ref NRF_CLOCK_LF_SRC. */
+ uint8_t rc_ctiv; /**< Only for ::NRF_CLOCK_LF_SRC_RC: Calibration timer interval in 1/4 second
+ units (nRF52: 1-32).
+ @note To avoid excessive clock drift, 0.5 degrees Celsius is the
+ maximum temperature change allowed in one calibration timer
+ interval. The interval should be selected to ensure this.
+
+ @note Must be 0 if source is not ::NRF_CLOCK_LF_SRC_RC. */
+ uint8_t rc_temp_ctiv; /**< Only for ::NRF_CLOCK_LF_SRC_RC: How often (in number of calibration
+ intervals) the RC oscillator shall be calibrated if the temperature
+ hasn't changed.
+ 0: Always calibrate even if the temperature hasn't changed.
+ 1: Only calibrate if the temperature has changed (legacy - nRF51 only).
+ 2-33: Check the temperature and only calibrate if it has changed,
+ however calibration will take place every rc_temp_ctiv
+ intervals in any case.
+
+ @note Must be 0 if source is not ::NRF_CLOCK_LF_SRC_RC.
+
+ @note For nRF52, the application must ensure calibration at least once
+ every 8 seconds to ensure +/-500 ppm clock stability. The
+ recommended configuration for ::NRF_CLOCK_LF_SRC_RC on nRF52 is
+ rc_ctiv=16 and rc_temp_ctiv=2. This will ensure calibration at
+ least once every 8 seconds and for temperature changes of 0.5
+ degrees Celsius every 4 seconds. See the Product Specification
+ for the nRF52 device being used for more information.*/
+ uint8_t accuracy; /**< External clock accuracy used in the LL to compute timing
+ windows, see @ref NRF_CLOCK_LF_ACCURACY.*/
+} nrf_clock_lf_cfg_t;
+
+/**@brief Fault Handler type.
+ *
+ * When certain unrecoverable errors occur within the application or SoftDevice the fault handler will be called back.
+ * The protocol stack will be in an undefined state when this happens and the only way to recover will be to
+ * perform a reset, using e.g. CMSIS NVIC_SystemReset().
+ * If the application returns from the fault handler the SoftDevice will call NVIC_SystemReset().
+ *
+ * @note This callback is executed in HardFault context, thus SVC functions cannot be called from the fault callback.
+ *
+ * @param[in] id Fault identifier. See @ref NRF_FAULT_IDS.
+ * @param[in] pc The program counter of the instruction that triggered the fault.
+ * @param[in] info Optional additional information regarding the fault. Refer to each Fault identifier for details.
+ *
+ * @note When id is set to @ref NRF_FAULT_ID_APP_MEMACC, pc will contain the address of the instruction being executed at the time when
+ * the fault is detected by the CPU. The CPU program counter may have advanced up to 2 instructions (no branching) after the one that triggered the fault.
+ */
+typedef void (*nrf_fault_handler_t)(uint32_t id, uint32_t pc, uint32_t info);
+
+/** @} */
+
+/** @addtogroup NRF_SDM_FUNCTIONS Functions
+ * @{ */
+
+/**@brief Enables the SoftDevice and by extension the protocol stack.
+ *
+ * @note Some care must be taken if a low frequency clock source is already running when calling this function:
+ * If the LF clock has a different source then the one currently running, it will be stopped. Then, the new
+ * clock source will be started.
+ *
+ * @note This function has no effect when returning with an error.
+ *
+ * @post If return code is ::NRF_SUCCESS
+ * - SoC library and protocol stack APIs are made available.
+ * - A portion of RAM will be unavailable (see relevant SDS documentation).
+ * - Some peripherals will be unavailable or available only through the SoC API (see relevant SDS documentation).
+ * - Interrupts will not arrive from protected peripherals or interrupts.
+ * - nrf_nvic_ functions must be used instead of CMSIS NVIC_ functions for reliable usage of the SoftDevice.
+ * - Interrupt latency may be affected by the SoftDevice (see relevant SDS documentation).
+ * - Chosen low frequency clock source will be running.
+ *
+ * @param p_clock_lf_cfg Low frequency clock source and accuracy.
+ If NULL the clock will be configured as an RC source with rc_ctiv = 16 and .rc_temp_ctiv = 2
+ In the case of XTAL source, the PPM accuracy of the chosen clock source must be greater than or equal to the actual characteristics of your XTAL clock.
+ * @param fault_handler Callback to be invoked in case of fault, cannot be NULL.
+ *
+ * @retval ::NRF_SUCCESS
+ * @retval ::NRF_ERROR_INVALID_ADDR Invalid or NULL pointer supplied.
+ * @retval ::NRF_ERROR_INVALID_STATE SoftDevice is already enabled, and the clock source and fault handler cannot be updated.
+ * @retval ::NRF_ERROR_SDM_INCORRECT_INTERRUPT_CONFIGURATION SoftDevice interrupt is already enabled, or an enabled interrupt has an illegal priority level.
+ * @retval ::NRF_ERROR_SDM_LFCLK_SOURCE_UNKNOWN Unknown low frequency clock source selected.
+ * @retval ::NRF_ERROR_INVALID_PARAM Invalid clock source configuration supplied in p_clock_lf_cfg.
+ */
+SVCALL(SD_SOFTDEVICE_ENABLE, uint32_t, sd_softdevice_enable(nrf_clock_lf_cfg_t const * p_clock_lf_cfg, nrf_fault_handler_t fault_handler));
+
+
+/**@brief Disables the SoftDevice and by extension the protocol stack.
+ *
+ * Idempotent function to disable the SoftDevice.
+ *
+ * @post SoC library and protocol stack APIs are made unavailable.
+ * @post All interrupts that was protected by the SoftDevice will be disabled and initialized to priority 0 (highest).
+ * @post All peripherals used by the SoftDevice will be reset to default values.
+ * @post All of RAM become available.
+ * @post All interrupts are forwarded to the application.
+ * @post LFCLK source chosen in ::sd_softdevice_enable will be left running.
+ *
+ * @retval ::NRF_SUCCESS
+ */
+SVCALL(SD_SOFTDEVICE_DISABLE, uint32_t, sd_softdevice_disable(void));
+
+/**@brief Check if the SoftDevice is enabled.
+ *
+ * @param[out] p_softdevice_enabled If the SoftDevice is enabled: 1 else 0.
+ *
+ * @retval ::NRF_SUCCESS
+ */
+SVCALL(SD_SOFTDEVICE_IS_ENABLED, uint32_t, sd_softdevice_is_enabled(uint8_t * p_softdevice_enabled));
+
+/**@brief Sets the base address of the interrupt vector table for interrupts forwarded from the SoftDevice
+ *
+ * This function is only intended to be called when a bootloader is enabled.
+ *
+ * @param[in] address The base address of the interrupt vector table for forwarded interrupts.
+
+ * @retval ::NRF_SUCCESS
+ */
+SVCALL(SD_SOFTDEVICE_VECTOR_TABLE_BASE_SET, uint32_t, sd_softdevice_vector_table_base_set(uint32_t address));
+
+/** @} */
+
+#ifdef __cplusplus
+}
+#endif
+#endif // NRF_SDM_H__
+
+/**
+ @}
+*/
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/softdevice/s140/headers/nrf_soc.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/softdevice/s140/headers/nrf_soc.h
new file mode 100644
index 0000000..3fa1772
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/softdevice/s140/headers/nrf_soc.h
@@ -0,0 +1,1036 @@
+/*
+ * Copyright (c) 2015 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ */
+
+/**
+ * @defgroup nrf_soc_api SoC Library API
+ * @{
+ *
+ * @brief APIs for the SoC library.
+ *
+ */
+
+#ifndef NRF_SOC_H__
+#define NRF_SOC_H__
+
+#include <stdint.h>
+#include "nrf.h"
+#include "nrf_svc.h"
+#include "nrf_error.h"
+#include "nrf_error_soc.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**@addtogroup NRF_SOC_DEFINES Defines
+ * @{ */
+
+/**@brief The number of the lowest SVC number reserved for the SoC library. */
+#define SOC_SVC_BASE (0x20) /**< Base value for SVCs that are available when the SoftDevice is disabled. */
+#define SOC_SVC_BASE_NOT_AVAILABLE (0x2C) /**< Base value for SVCs that are not available when the SoftDevice is disabled. */
+
+/**@brief Guaranteed time for application to process radio inactive notification. */
+#define NRF_RADIO_NOTIFICATION_INACTIVE_GUARANTEED_TIME_US (62)
+
+/**@brief The minimum allowed timeslot extension time. */
+#define NRF_RADIO_MINIMUM_TIMESLOT_LENGTH_EXTENSION_TIME_US (200)
+
+/**@brief The maximum processing time to handle a timeslot extension. */
+#define NRF_RADIO_MAX_EXTENSION_PROCESSING_TIME_US (17)
+
+/**@brief The latest time before the end of a timeslot the timeslot can be extended. */
+#define NRF_RADIO_MIN_EXTENSION_MARGIN_US (79)
+
+#define SOC_ECB_KEY_LENGTH (16) /**< ECB key length. */
+#define SOC_ECB_CLEARTEXT_LENGTH (16) /**< ECB cleartext length. */
+#define SOC_ECB_CIPHERTEXT_LENGTH (SOC_ECB_CLEARTEXT_LENGTH) /**< ECB ciphertext length. */
+
+#define SD_EVT_IRQn (SWI2_IRQn) /**< SoftDevice Event IRQ number. Used for both protocol events and SoC events. */
+#define SD_EVT_IRQHandler (SWI2_IRQHandler) /**< SoftDevice Event IRQ handler. Used for both protocol events and SoC events.
+ The default interrupt priority for this handler is set to 4 */
+#define RADIO_NOTIFICATION_IRQn (SWI1_IRQn) /**< The radio notification IRQ number. */
+#define RADIO_NOTIFICATION_IRQHandler (SWI1_IRQHandler) /**< The radio notification IRQ handler.
+ The default interrupt priority for this handler is set to 4 */
+#define NRF_RADIO_LENGTH_MIN_US (100) /**< The shortest allowed radio timeslot, in microseconds. */
+#define NRF_RADIO_LENGTH_MAX_US (100000) /**< The longest allowed radio timeslot, in microseconds. */
+
+#define NRF_RADIO_DISTANCE_MAX_US (128000000UL - 1UL) /**< The longest timeslot distance, in microseconds, allowed for the distance parameter (see @ref nrf_radio_request_normal_t) in the request. */
+
+#define NRF_RADIO_EARLIEST_TIMEOUT_MAX_US (128000000UL - 1UL) /**< The longest timeout, in microseconds, allowed when requesting the earliest possible timeslot. */
+
+#define NRF_RADIO_START_JITTER_US (2) /**< The maximum jitter in @ref NRF_RADIO_CALLBACK_SIGNAL_TYPE_START relative to the requested start time. */
+
+/**@} */
+
+/**@addtogroup NRF_SOC_ENUMS Enumerations
+ * @{ */
+
+/**@brief The SVC numbers used by the SVC functions in the SoC library. */
+enum NRF_SOC_SVCS
+{
+ SD_PPI_CHANNEL_ENABLE_GET = SOC_SVC_BASE,
+ SD_PPI_CHANNEL_ENABLE_SET = SOC_SVC_BASE + 1,
+ SD_PPI_CHANNEL_ENABLE_CLR = SOC_SVC_BASE + 2,
+ SD_PPI_CHANNEL_ASSIGN = SOC_SVC_BASE + 3,
+ SD_PPI_GROUP_TASK_ENABLE = SOC_SVC_BASE + 4,
+ SD_PPI_GROUP_TASK_DISABLE = SOC_SVC_BASE + 5,
+ SD_PPI_GROUP_ASSIGN = SOC_SVC_BASE + 6,
+ SD_PPI_GROUP_GET = SOC_SVC_BASE + 7,
+ SD_FLASH_PAGE_ERASE = SOC_SVC_BASE + 8,
+ SD_FLASH_WRITE = SOC_SVC_BASE + 9,
+ SD_PROTECTED_REGISTER_WRITE = SOC_SVC_BASE + 11,
+ SD_MUTEX_NEW = SOC_SVC_BASE_NOT_AVAILABLE,
+ SD_MUTEX_ACQUIRE = SOC_SVC_BASE_NOT_AVAILABLE + 1,
+ SD_MUTEX_RELEASE = SOC_SVC_BASE_NOT_AVAILABLE + 2,
+ SD_RAND_APPLICATION_POOL_CAPACITY_GET = SOC_SVC_BASE_NOT_AVAILABLE + 3,
+ SD_RAND_APPLICATION_BYTES_AVAILABLE_GET = SOC_SVC_BASE_NOT_AVAILABLE + 4,
+ SD_RAND_APPLICATION_VECTOR_GET = SOC_SVC_BASE_NOT_AVAILABLE + 5,
+ SD_POWER_MODE_SET = SOC_SVC_BASE_NOT_AVAILABLE + 6,
+ SD_POWER_SYSTEM_OFF = SOC_SVC_BASE_NOT_AVAILABLE + 7,
+ SD_POWER_RESET_REASON_GET = SOC_SVC_BASE_NOT_AVAILABLE + 8,
+ SD_POWER_RESET_REASON_CLR = SOC_SVC_BASE_NOT_AVAILABLE + 9,
+ SD_POWER_POF_ENABLE = SOC_SVC_BASE_NOT_AVAILABLE + 10,
+ SD_POWER_POF_THRESHOLD_SET = SOC_SVC_BASE_NOT_AVAILABLE + 11,
+ SD_POWER_POF_THRESHOLDVDDH_SET = SOC_SVC_BASE_NOT_AVAILABLE + 12,
+ SD_POWER_RAM_POWER_SET = SOC_SVC_BASE_NOT_AVAILABLE + 13,
+ SD_POWER_RAM_POWER_CLR = SOC_SVC_BASE_NOT_AVAILABLE + 14,
+ SD_POWER_RAM_POWER_GET = SOC_SVC_BASE_NOT_AVAILABLE + 15,
+ SD_POWER_GPREGRET_SET = SOC_SVC_BASE_NOT_AVAILABLE + 16,
+ SD_POWER_GPREGRET_CLR = SOC_SVC_BASE_NOT_AVAILABLE + 17,
+ SD_POWER_GPREGRET_GET = SOC_SVC_BASE_NOT_AVAILABLE + 18,
+ SD_POWER_DCDC_MODE_SET = SOC_SVC_BASE_NOT_AVAILABLE + 19,
+ SD_POWER_DCDC0_MODE_SET = SOC_SVC_BASE_NOT_AVAILABLE + 20,
+ SD_APP_EVT_WAIT = SOC_SVC_BASE_NOT_AVAILABLE + 21,
+ SD_CLOCK_HFCLK_REQUEST = SOC_SVC_BASE_NOT_AVAILABLE + 22,
+ SD_CLOCK_HFCLK_RELEASE = SOC_SVC_BASE_NOT_AVAILABLE + 23,
+ SD_CLOCK_HFCLK_IS_RUNNING = SOC_SVC_BASE_NOT_AVAILABLE + 24,
+ SD_RADIO_NOTIFICATION_CFG_SET = SOC_SVC_BASE_NOT_AVAILABLE + 25,
+ SD_ECB_BLOCK_ENCRYPT = SOC_SVC_BASE_NOT_AVAILABLE + 26,
+ SD_ECB_BLOCKS_ENCRYPT = SOC_SVC_BASE_NOT_AVAILABLE + 27,
+ SD_RADIO_SESSION_OPEN = SOC_SVC_BASE_NOT_AVAILABLE + 28,
+ SD_RADIO_SESSION_CLOSE = SOC_SVC_BASE_NOT_AVAILABLE + 29,
+ SD_RADIO_REQUEST = SOC_SVC_BASE_NOT_AVAILABLE + 30,
+ SD_EVT_GET = SOC_SVC_BASE_NOT_AVAILABLE + 31,
+ SD_TEMP_GET = SOC_SVC_BASE_NOT_AVAILABLE + 32,
+ SD_POWER_USBPWRRDY_ENABLE = SOC_SVC_BASE_NOT_AVAILABLE + 33,
+ SD_POWER_USBDETECTED_ENABLE = SOC_SVC_BASE_NOT_AVAILABLE + 34,
+ SD_POWER_USBREMOVED_ENABLE = SOC_SVC_BASE_NOT_AVAILABLE + 35,
+ SD_POWER_USBREGSTATUS_GET = SOC_SVC_BASE_NOT_AVAILABLE + 36,
+ SVC_SOC_LAST = SOC_SVC_BASE_NOT_AVAILABLE + 37
+};
+
+/**@brief Possible values of a ::nrf_mutex_t. */
+enum NRF_MUTEX_VALUES
+{
+ NRF_MUTEX_FREE,
+ NRF_MUTEX_TAKEN
+};
+
+/**@brief Power modes. */
+enum NRF_POWER_MODES
+{
+ NRF_POWER_MODE_CONSTLAT, /**< Constant latency mode. See power management in the reference manual. */
+ NRF_POWER_MODE_LOWPWR /**< Low power mode. See power management in the reference manual. */
+};
+
+
+/**@brief Power failure thresholds */
+enum NRF_POWER_THRESHOLDS
+{
+ NRF_POWER_THRESHOLD_V17 = 4UL, /**< 1.7 Volts power failure threshold. */
+ NRF_POWER_THRESHOLD_V18, /**< 1.8 Volts power failure threshold. */
+ NRF_POWER_THRESHOLD_V19, /**< 1.9 Volts power failure threshold. */
+ NRF_POWER_THRESHOLD_V20, /**< 2.0 Volts power failure threshold. */
+ NRF_POWER_THRESHOLD_V21, /**< 2.1 Volts power failure threshold. */
+ NRF_POWER_THRESHOLD_V22, /**< 2.2 Volts power failure threshold. */
+ NRF_POWER_THRESHOLD_V23, /**< 2.3 Volts power failure threshold. */
+ NRF_POWER_THRESHOLD_V24, /**< 2.4 Volts power failure threshold. */
+ NRF_POWER_THRESHOLD_V25, /**< 2.5 Volts power failure threshold. */
+ NRF_POWER_THRESHOLD_V26, /**< 2.6 Volts power failure threshold. */
+ NRF_POWER_THRESHOLD_V27, /**< 2.7 Volts power failure threshold. */
+ NRF_POWER_THRESHOLD_V28 /**< 2.8 Volts power failure threshold. */
+};
+
+/**@brief Power failure thresholds for high voltage */
+enum NRF_POWER_THRESHOLDVDDHS
+{
+ NRF_POWER_THRESHOLDVDDH_V27, /**< 2.7 Volts power failure threshold. */
+ NRF_POWER_THRESHOLDVDDH_V28, /**< 2.8 Volts power failure threshold. */
+ NRF_POWER_THRESHOLDVDDH_V29, /**< 2.9 Volts power failure threshold. */
+ NRF_POWER_THRESHOLDVDDH_V30, /**< 3.0 Volts power failure threshold. */
+ NRF_POWER_THRESHOLDVDDH_V31, /**< 3.1 Volts power failure threshold. */
+ NRF_POWER_THRESHOLDVDDH_V32, /**< 3.2 Volts power failure threshold. */
+ NRF_POWER_THRESHOLDVDDH_V33, /**< 3.3 Volts power failure threshold. */
+ NRF_POWER_THRESHOLDVDDH_V34, /**< 3.4 Volts power failure threshold. */
+ NRF_POWER_THRESHOLDVDDH_V35, /**< 3.5 Volts power failure threshold. */
+ NRF_POWER_THRESHOLDVDDH_V36, /**< 3.6 Volts power failure threshold. */
+ NRF_POWER_THRESHOLDVDDH_V37, /**< 3.7 Volts power failure threshold. */
+ NRF_POWER_THRESHOLDVDDH_V38, /**< 3.8 Volts power failure threshold. */
+ NRF_POWER_THRESHOLDVDDH_V39, /**< 3.9 Volts power failure threshold. */
+ NRF_POWER_THRESHOLDVDDH_V40, /**< 4.0 Volts power failure threshold. */
+ NRF_POWER_THRESHOLDVDDH_V41, /**< 4.1 Volts power failure threshold. */
+ NRF_POWER_THRESHOLDVDDH_V42 /**< 4.2 Volts power failure threshold. */
+};
+
+
+/**@brief DC/DC converter modes. */
+enum NRF_POWER_DCDC_MODES
+{
+ NRF_POWER_DCDC_DISABLE, /**< The DCDC is disabled. */
+ NRF_POWER_DCDC_ENABLE /**< The DCDC is enabled. */
+};
+
+/**@brief Radio notification distances. */
+enum NRF_RADIO_NOTIFICATION_DISTANCES
+{
+ NRF_RADIO_NOTIFICATION_DISTANCE_NONE = 0, /**< The event does not have a notification. */
+ NRF_RADIO_NOTIFICATION_DISTANCE_800US, /**< The distance from the active notification to start of radio activity. */
+ NRF_RADIO_NOTIFICATION_DISTANCE_1740US, /**< The distance from the active notification to start of radio activity. */
+ NRF_RADIO_NOTIFICATION_DISTANCE_2680US, /**< The distance from the active notification to start of radio activity. */
+ NRF_RADIO_NOTIFICATION_DISTANCE_3620US, /**< The distance from the active notification to start of radio activity. */
+ NRF_RADIO_NOTIFICATION_DISTANCE_4560US, /**< The distance from the active notification to start of radio activity. */
+ NRF_RADIO_NOTIFICATION_DISTANCE_5500US /**< The distance from the active notification to start of radio activity. */
+};
+
+
+/**@brief Radio notification types. */
+enum NRF_RADIO_NOTIFICATION_TYPES
+{
+ NRF_RADIO_NOTIFICATION_TYPE_NONE = 0, /**< The event does not have a radio notification signal. */
+ NRF_RADIO_NOTIFICATION_TYPE_INT_ON_ACTIVE, /**< Using interrupt for notification when the radio will be enabled. */
+ NRF_RADIO_NOTIFICATION_TYPE_INT_ON_INACTIVE, /**< Using interrupt for notification when the radio has been disabled. */
+ NRF_RADIO_NOTIFICATION_TYPE_INT_ON_BOTH, /**< Using interrupt for notification both when the radio will be enabled and disabled. */
+};
+
+/**@brief The Radio signal callback types. */
+enum NRF_RADIO_CALLBACK_SIGNAL_TYPE
+{
+ NRF_RADIO_CALLBACK_SIGNAL_TYPE_START, /**< This signal indicates the start of the radio timeslot. */
+ NRF_RADIO_CALLBACK_SIGNAL_TYPE_TIMER0, /**< This signal indicates the NRF_TIMER0 interrupt. */
+ NRF_RADIO_CALLBACK_SIGNAL_TYPE_RADIO, /**< This signal indicates the NRF_RADIO interrupt. */
+ NRF_RADIO_CALLBACK_SIGNAL_TYPE_EXTEND_FAILED, /**< This signal indicates extend action failed. */
+ NRF_RADIO_CALLBACK_SIGNAL_TYPE_EXTEND_SUCCEEDED /**< This signal indicates extend action succeeded. */
+};
+
+/**@brief The actions requested by the signal callback.
+ *
+ * This code gives the SOC instructions about what action to take when the signal callback has
+ * returned.
+ */
+enum NRF_RADIO_SIGNAL_CALLBACK_ACTION
+{
+ NRF_RADIO_SIGNAL_CALLBACK_ACTION_NONE, /**< Return without action. */
+ NRF_RADIO_SIGNAL_CALLBACK_ACTION_EXTEND, /**< Request an extension of the current
+ timeslot. Maximum execution time for this action:
+ @ref NRF_RADIO_MAX_EXTENSION_PROCESSING_TIME_US.
+ This action must be started at least
+ @ref NRF_RADIO_MIN_EXTENSION_MARGIN_US before
+ the end of the timeslot. */
+ NRF_RADIO_SIGNAL_CALLBACK_ACTION_END, /**< End the current radio timeslot. */
+ NRF_RADIO_SIGNAL_CALLBACK_ACTION_REQUEST_AND_END /**< Request a new radio timeslot and end the current timeslot. */
+};
+
+/**@brief Radio timeslot high frequency clock source configuration. */
+enum NRF_RADIO_HFCLK_CFG
+{
+ NRF_RADIO_HFCLK_CFG_XTAL_GUARANTEED, /**< The SoftDevice will guarantee that the high frequency clock source is the
+ external crystal for the whole duration of the timeslot. This should be the
+ preferred option for events that use the radio or require high timing accuracy.
+ @note The SoftDevice will automatically turn on and off the external crystal,
+ at the beginning and end of the timeslot, respectively. The crystal may also
+ intentionally be left running after the timeslot, in cases where it is needed
+ by the SoftDevice shortly after the end of the timeslot. */
+ NRF_RADIO_HFCLK_CFG_NO_GUARANTEE /**< This configuration allows for earlier and tighter scheduling of timeslots.
+ The RC oscillator may be the clock source in part or for the whole duration of the timeslot.
+ The RC oscillator's accuracy must therefore be taken into consideration.
+ @note If the application will use the radio peripheral in timeslots with this configuration,
+ it must make sure that the crystal is running and stable before starting the radio. */
+};
+
+/**@brief Radio timeslot priorities. */
+enum NRF_RADIO_PRIORITY
+{
+ NRF_RADIO_PRIORITY_HIGH, /**< High (equal priority as the normal connection priority of the SoftDevice stack(s)). */
+ NRF_RADIO_PRIORITY_NORMAL, /**< Normal (equal priority as the priority of secondary activities of the SoftDevice stack(s)). */
+};
+
+/**@brief Radio timeslot request type. */
+enum NRF_RADIO_REQUEST_TYPE
+{
+ NRF_RADIO_REQ_TYPE_EARLIEST, /**< Request radio timeslot as early as possible. This should always be used for the first request in a session. */
+ NRF_RADIO_REQ_TYPE_NORMAL /**< Normal radio timeslot request. */
+};
+
+/**@brief SoC Events. */
+enum NRF_SOC_EVTS
+{
+ NRF_EVT_HFCLKSTARTED, /**< Event indicating that the HFCLK has started. */
+ NRF_EVT_POWER_FAILURE_WARNING, /**< Event indicating that a power failure warning has occurred. */
+ NRF_EVT_FLASH_OPERATION_SUCCESS, /**< Event indicating that the ongoing flash operation has completed successfully. */
+ NRF_EVT_FLASH_OPERATION_ERROR, /**< Event indicating that the ongoing flash operation has timed out with an error. */
+ NRF_EVT_RADIO_BLOCKED, /**< Event indicating that a radio timeslot was blocked. */
+ NRF_EVT_RADIO_CANCELED, /**< Event indicating that a radio timeslot was canceled by SoftDevice. */
+ NRF_EVT_RADIO_SIGNAL_CALLBACK_INVALID_RETURN, /**< Event indicating that a radio timeslot signal callback handler return was invalid. */
+ NRF_EVT_RADIO_SESSION_IDLE, /**< Event indicating that a radio timeslot session is idle. */
+ NRF_EVT_RADIO_SESSION_CLOSED, /**< Event indicating that a radio timeslot session is closed. */
+ NRF_EVT_POWER_USB_POWER_READY, /**< Event indicating that a USB 3.3 V supply is ready. */
+ NRF_EVT_POWER_USB_DETECTED, /**< Event indicating that voltage supply is detected on VBUS. */
+ NRF_EVT_POWER_USB_REMOVED, /**< Event indicating that voltage supply is removed from VBUS. */
+ NRF_EVT_NUMBER_OF_EVTS
+};
+
+/**@} */
+
+
+/**@addtogroup NRF_SOC_STRUCTURES Structures
+ * @{ */
+
+/**@brief Represents a mutex for use with the nrf_mutex functions.
+ * @note Accessing the value directly is not safe, use the mutex functions!
+ */
+typedef volatile uint8_t nrf_mutex_t;
+
+/**@brief Parameters for a request for a timeslot as early as possible. */
+typedef struct
+{
+ uint8_t hfclk; /**< High frequency clock source, see @ref NRF_RADIO_HFCLK_CFG. */
+ uint8_t priority; /**< The radio timeslot priority, see @ref NRF_RADIO_PRIORITY. */
+ uint32_t length_us; /**< The radio timeslot length (in the range 100 to 100,000] microseconds). */
+ uint32_t timeout_us; /**< Longest acceptable delay until the start of the requested timeslot (up to @ref NRF_RADIO_EARLIEST_TIMEOUT_MAX_US microseconds). */
+} nrf_radio_request_earliest_t;
+
+/**@brief Parameters for a normal radio timeslot request. */
+typedef struct
+{
+ uint8_t hfclk; /**< High frequency clock source, see @ref NRF_RADIO_HFCLK_CFG. */
+ uint8_t priority; /**< The radio timeslot priority, see @ref NRF_RADIO_PRIORITY. */
+ uint32_t distance_us; /**< Distance from the start of the previous radio timeslot (up to @ref NRF_RADIO_DISTANCE_MAX_US microseconds). */
+ uint32_t length_us; /**< The radio timeslot length (in the range [100..100,000] microseconds). */
+} nrf_radio_request_normal_t;
+
+/**@brief Radio timeslot request parameters. */
+typedef struct
+{
+ uint8_t request_type; /**< Type of request, see @ref NRF_RADIO_REQUEST_TYPE. */
+ union
+ {
+ nrf_radio_request_earliest_t earliest; /**< Parameters for requesting a radio timeslot as early as possible. */
+ nrf_radio_request_normal_t normal; /**< Parameters for requesting a normal radio timeslot. */
+ } params; /**< Parameter union. */
+} nrf_radio_request_t;
+
+/**@brief Return parameters of the radio timeslot signal callback. */
+typedef struct
+{
+ uint8_t callback_action; /**< The action requested by the application when returning from the signal callback, see @ref NRF_RADIO_SIGNAL_CALLBACK_ACTION. */
+ union
+ {
+ struct
+ {
+ nrf_radio_request_t * p_next; /**< The request parameters for the next radio timeslot. */
+ } request; /**< Additional parameters for return_code @ref NRF_RADIO_SIGNAL_CALLBACK_ACTION_REQUEST_AND_END. */
+ struct
+ {
+ uint32_t length_us; /**< Requested extension of the radio timeslot duration (microseconds) (for minimum time see @ref NRF_RADIO_MINIMUM_TIMESLOT_LENGTH_EXTENSION_TIME_US). */
+ } extend; /**< Additional parameters for return_code @ref NRF_RADIO_SIGNAL_CALLBACK_ACTION_EXTEND. */
+ } params; /**< Parameter union. */
+} nrf_radio_signal_callback_return_param_t;
+
+/**@brief The radio timeslot signal callback type.
+ *
+ * @note In case of invalid return parameters, the radio timeslot will automatically end
+ * immediately after returning from the signal callback and the
+ * @ref NRF_EVT_RADIO_SIGNAL_CALLBACK_INVALID_RETURN event will be sent.
+ * @note The returned struct pointer must remain valid after the signal callback
+ * function returns. For instance, this means that it must not point to a stack variable.
+ *
+ * @param[in] signal_type Type of signal, see @ref NRF_RADIO_CALLBACK_SIGNAL_TYPE.
+ *
+ * @return Pointer to structure containing action requested by the application.
+ */
+typedef nrf_radio_signal_callback_return_param_t * (*nrf_radio_signal_callback_t) (uint8_t signal_type);
+
+/**@brief AES ECB parameter typedefs */
+typedef uint8_t soc_ecb_key_t[SOC_ECB_KEY_LENGTH]; /**< Encryption key type. */
+typedef uint8_t soc_ecb_cleartext_t[SOC_ECB_CLEARTEXT_LENGTH]; /**< Cleartext data type. */
+typedef uint8_t soc_ecb_ciphertext_t[SOC_ECB_CIPHERTEXT_LENGTH]; /**< Ciphertext data type. */
+
+/**@brief AES ECB data structure */
+typedef struct
+{
+ soc_ecb_key_t key; /**< Encryption key. */
+ soc_ecb_cleartext_t cleartext; /**< Cleartext data. */
+ soc_ecb_ciphertext_t ciphertext; /**< Ciphertext data. */
+} nrf_ecb_hal_data_t;
+
+/**@brief AES ECB block. Used to provide multiple blocks in a single call
+ to @ref sd_ecb_blocks_encrypt.*/
+typedef struct
+{
+ soc_ecb_key_t const * p_key; /**< Pointer to the Encryption key. */
+ soc_ecb_cleartext_t const * p_cleartext; /**< Pointer to the Cleartext data. */
+ soc_ecb_ciphertext_t * p_ciphertext; /**< Pointer to the Ciphertext data. */
+} nrf_ecb_hal_data_block_t;
+
+/**@} */
+
+/**@addtogroup NRF_SOC_FUNCTIONS Functions
+ * @{ */
+
+/**@brief Initialize a mutex.
+ *
+ * @param[in] p_mutex Pointer to the mutex to initialize.
+ *
+ * @retval ::NRF_SUCCESS
+ */
+SVCALL(SD_MUTEX_NEW, uint32_t, sd_mutex_new(nrf_mutex_t * p_mutex));
+
+/**@brief Attempt to acquire a mutex.
+ *
+ * @param[in] p_mutex Pointer to the mutex to acquire.
+ *
+ * @retval ::NRF_SUCCESS The mutex was successfully acquired.
+ * @retval ::NRF_ERROR_SOC_MUTEX_ALREADY_TAKEN The mutex could not be acquired.
+ */
+SVCALL(SD_MUTEX_ACQUIRE, uint32_t, sd_mutex_acquire(nrf_mutex_t * p_mutex));
+
+/**@brief Release a mutex.
+ *
+ * @param[in] p_mutex Pointer to the mutex to release.
+ *
+ * @retval ::NRF_SUCCESS
+ */
+SVCALL(SD_MUTEX_RELEASE, uint32_t, sd_mutex_release(nrf_mutex_t * p_mutex));
+
+/**@brief Query the capacity of the application random pool.
+ *
+ * @param[out] p_pool_capacity The capacity of the pool.
+ *
+ * @retval ::NRF_SUCCESS
+ */
+SVCALL(SD_RAND_APPLICATION_POOL_CAPACITY_GET, uint32_t, sd_rand_application_pool_capacity_get(uint8_t * p_pool_capacity));
+
+/**@brief Get number of random bytes available to the application.
+ *
+ * @param[out] p_bytes_available The number of bytes currently available in the pool.
+ *
+ * @retval ::NRF_SUCCESS
+ */
+SVCALL(SD_RAND_APPLICATION_BYTES_AVAILABLE_GET, uint32_t, sd_rand_application_bytes_available_get(uint8_t * p_bytes_available));
+
+/**@brief Get random bytes from the application pool.
+ *
+ * @param[out] p_buff Pointer to unit8_t buffer for storing the bytes.
+ * @param[in] length Number of bytes to take from pool and place in p_buff.
+ *
+ * @retval ::NRF_SUCCESS The requested bytes were written to p_buff.
+ * @retval ::NRF_ERROR_SOC_RAND_NOT_ENOUGH_VALUES No bytes were written to the buffer, because there were not enough bytes available.
+*/
+SVCALL(SD_RAND_APPLICATION_VECTOR_GET, uint32_t, sd_rand_application_vector_get(uint8_t * p_buff, uint8_t length));
+
+/**@brief Gets the reset reason register.
+ *
+ * @param[out] p_reset_reason Contents of the NRF_POWER->RESETREAS register.
+ *
+ * @retval ::NRF_SUCCESS
+ */
+SVCALL(SD_POWER_RESET_REASON_GET, uint32_t, sd_power_reset_reason_get(uint32_t * p_reset_reason));
+
+/**@brief Clears the bits of the reset reason register.
+ *
+ * @param[in] reset_reason_clr_msk Contains the bits to clear from the reset reason register.
+ *
+ * @retval ::NRF_SUCCESS
+ */
+SVCALL(SD_POWER_RESET_REASON_CLR, uint32_t, sd_power_reset_reason_clr(uint32_t reset_reason_clr_msk));
+
+/**@brief Sets the power mode when in CPU sleep.
+ *
+ * @param[in] power_mode The power mode to use when in CPU sleep, see @ref NRF_POWER_MODES. @sa sd_app_evt_wait
+ *
+ * @retval ::NRF_SUCCESS The power mode was set.
+ * @retval ::NRF_ERROR_SOC_POWER_MODE_UNKNOWN The power mode was unknown.
+ */
+SVCALL(SD_POWER_MODE_SET, uint32_t, sd_power_mode_set(uint8_t power_mode));
+
+/**@brief Puts the chip in System OFF mode.
+ *
+ * @retval ::NRF_ERROR_SOC_POWER_OFF_SHOULD_NOT_RETURN
+ */
+SVCALL(SD_POWER_SYSTEM_OFF, uint32_t, sd_power_system_off(void));
+
+/**@brief Enables or disables the power-fail comparator.
+ *
+ * Enabling this will give a SoftDevice event (NRF_EVT_POWER_FAILURE_WARNING) when the power failure warning occurs.
+ * The event can be retrieved with sd_evt_get();
+ *
+ * @param[in] pof_enable True if the power-fail comparator should be enabled, false if it should be disabled.
+ *
+ * @retval ::NRF_SUCCESS
+ */
+SVCALL(SD_POWER_POF_ENABLE, uint32_t, sd_power_pof_enable(uint8_t pof_enable));
+
+/**@brief Enables or disables the USB power ready event.
+ *
+ * Enabling this will give a SoftDevice event (NRF_EVT_POWER_USB_POWER_READY) when a USB 3.3 V supply is ready.
+ * The event can be retrieved with sd_evt_get();
+ *
+ * @param[in] usbpwrrdy_enable True if the power ready event should be enabled, false if it should be disabled.
+ *
+ * @retval ::NRF_SUCCESS
+ */
+SVCALL(SD_POWER_USBPWRRDY_ENABLE, uint32_t, sd_power_usbpwrrdy_enable(uint8_t usbpwrrdy_enable));
+
+/**@brief Enables or disables the power USB-detected event.
+ *
+ * Enabling this will give a SoftDevice event (NRF_EVT_POWER_USB_DETECTED) when a voltage supply is detected on VBUS.
+ * The event can be retrieved with sd_evt_get();
+ *
+ * @param[in] usbdetected_enable True if the power ready event should be enabled, false if it should be disabled.
+ *
+ * @retval ::NRF_SUCCESS
+ */
+SVCALL(SD_POWER_USBDETECTED_ENABLE, uint32_t, sd_power_usbdetected_enable(uint8_t usbdetected_enable));
+
+/**@brief Enables or disables the power USB-removed event.
+ *
+ * Enabling this will give a SoftDevice event (NRF_EVT_POWER_USB_REMOVED) when a voltage supply is removed from VBUS.
+ * The event can be retrieved with sd_evt_get();
+ *
+ * @param[in] usbremoved_enable True if the power ready event should be enabled, false if it should be disabled.
+ *
+ * @retval ::NRF_SUCCESS
+ */
+SVCALL(SD_POWER_USBREMOVED_ENABLE, uint32_t, sd_power_usbremoved_enable(uint8_t usbremoved_enable));
+
+/**@brief Get USB supply status register content.
+ *
+ * @param[out] usbregstatus The content of USBREGSTATUS register.
+ *
+ * @retval ::NRF_SUCCESS
+ */
+SVCALL(SD_POWER_USBREGSTATUS_GET, uint32_t, sd_power_usbregstatus_get(uint32_t * usbregstatus));
+
+/**@brief Sets the power failure comparator threshold value.
+ *
+ * @note: Power failure comparator threshold setting. This setting applies both for normal voltage
+ * mode (supply connected to both VDD and VDDH) and high voltage mode (supply connected to
+ * VDDH only).
+ *
+ * @param[in] threshold The power-fail threshold value to use, see @ref NRF_POWER_THRESHOLDS.
+ *
+ * @retval ::NRF_SUCCESS The power failure threshold was set.
+ * @retval ::NRF_ERROR_SOC_POWER_POF_THRESHOLD_UNKNOWN The power failure threshold is unknown.
+ */
+SVCALL(SD_POWER_POF_THRESHOLD_SET, uint32_t, sd_power_pof_threshold_set(uint8_t threshold));
+
+/**@brief Sets the power failure comparator threshold value for high voltage.
+ *
+ * @note: Power failure comparator threshold setting for high voltage mode (supply connected to
+ * VDDH only). This setting does not apply for normal voltage mode (supply connected to both
+ * VDD and VDDH).
+ *
+ * @param[in] threshold The power-fail threshold value to use, see @ref NRF_POWER_THRESHOLDVDDHS.
+ *
+ * @retval ::NRF_SUCCESS The power failure threshold was set.
+ * @retval ::NRF_ERROR_SOC_POWER_POF_THRESHOLD_UNKNOWN The power failure threshold is unknown.
+ */
+SVCALL(SD_POWER_POF_THRESHOLDVDDH_SET, uint32_t, sd_power_pof_thresholdvddh_set(uint8_t threshold));
+
+/**@brief Writes the NRF_POWER->RAM[index].POWERSET register.
+ *
+ * @param[in] index Contains the index in the NRF_POWER->RAM[index].POWERSET register to write to.
+ * @param[in] ram_powerset Contains the word to write to the NRF_POWER->RAM[index].POWERSET register.
+ *
+ * @retval ::NRF_SUCCESS
+ */
+SVCALL(SD_POWER_RAM_POWER_SET, uint32_t, sd_power_ram_power_set(uint8_t index, uint32_t ram_powerset));
+
+/**@brief Writes the NRF_POWER->RAM[index].POWERCLR register.
+ *
+ * @param[in] index Contains the index in the NRF_POWER->RAM[index].POWERCLR register to write to.
+ * @param[in] ram_powerclr Contains the word to write to the NRF_POWER->RAM[index].POWERCLR register.
+ *
+ * @retval ::NRF_SUCCESS
+ */
+SVCALL(SD_POWER_RAM_POWER_CLR, uint32_t, sd_power_ram_power_clr(uint8_t index, uint32_t ram_powerclr));
+
+/**@brief Get contents of NRF_POWER->RAM[index].POWER register, indicates power status of RAM[index] blocks.
+ *
+ * @param[in] index Contains the index in the NRF_POWER->RAM[index].POWER register to read from.
+ * @param[out] p_ram_power Content of NRF_POWER->RAM[index].POWER register.
+ *
+ * @retval ::NRF_SUCCESS
+ */
+SVCALL(SD_POWER_RAM_POWER_GET, uint32_t, sd_power_ram_power_get(uint8_t index, uint32_t * p_ram_power));
+
+/**@brief Set bits in the general purpose retention registers (NRF_POWER->GPREGRET*).
+ *
+ * @param[in] gpregret_id 0 for GPREGRET, 1 for GPREGRET2.
+ * @param[in] gpregret_msk Bits to be set in the GPREGRET register.
+ *
+ * @retval ::NRF_SUCCESS
+ */
+SVCALL(SD_POWER_GPREGRET_SET, uint32_t, sd_power_gpregret_set(uint32_t gpregret_id, uint32_t gpregret_msk));
+
+/**@brief Clear bits in the general purpose retention registers (NRF_POWER->GPREGRET*).
+ *
+ * @param[in] gpregret_id 0 for GPREGRET, 1 for GPREGRET2.
+ * @param[in] gpregret_msk Bits to be clear in the GPREGRET register.
+ *
+ * @retval ::NRF_SUCCESS
+ */
+SVCALL(SD_POWER_GPREGRET_CLR, uint32_t, sd_power_gpregret_clr(uint32_t gpregret_id, uint32_t gpregret_msk));
+
+/**@brief Get contents of the general purpose retention registers (NRF_POWER->GPREGRET*).
+ *
+ * @param[in] gpregret_id 0 for GPREGRET, 1 for GPREGRET2.
+ * @param[out] p_gpregret Contents of the GPREGRET register.
+ *
+ * @retval ::NRF_SUCCESS
+ */
+SVCALL(SD_POWER_GPREGRET_GET, uint32_t, sd_power_gpregret_get(uint32_t gpregret_id, uint32_t *p_gpregret));
+
+/**@brief Enable or disable the DC/DC regulator for the regulator stage 1 (REG1).
+ *
+ * @param[in] dcdc_mode The mode of the DCDC, see @ref NRF_POWER_DCDC_MODES.
+ *
+ * @retval ::NRF_SUCCESS
+ * @retval ::NRF_ERROR_INVALID_PARAM The DCDC mode is invalid.
+ */
+SVCALL(SD_POWER_DCDC_MODE_SET, uint32_t, sd_power_dcdc_mode_set(uint8_t dcdc_mode));
+
+/**@brief Enable or disable the DC/DC regulator for the regulator stage 0 (REG0).
+ *
+ * For more details on the REG0 stage, please see product specification.
+ *
+ * @param[in] dcdc_mode The mode of the DCDC0, see @ref NRF_POWER_DCDC_MODES.
+ *
+ * @retval ::NRF_SUCCESS
+ * @retval ::NRF_ERROR_INVALID_PARAM The dcdc_mode is invalid.
+ */
+SVCALL(SD_POWER_DCDC0_MODE_SET, uint32_t, sd_power_dcdc0_mode_set(uint8_t dcdc_mode));
+
+/**@brief Request the high frequency crystal oscillator.
+ *
+ * Will start the high frequency crystal oscillator, the startup time of the crystal varies
+ * and the ::sd_clock_hfclk_is_running function can be polled to check if it has started.
+ *
+ * @see sd_clock_hfclk_is_running
+ * @see sd_clock_hfclk_release
+ *
+ * @retval ::NRF_SUCCESS
+ */
+SVCALL(SD_CLOCK_HFCLK_REQUEST, uint32_t, sd_clock_hfclk_request(void));
+
+/**@brief Releases the high frequency crystal oscillator.
+ *
+ * Will stop the high frequency crystal oscillator, this happens immediately.
+ *
+ * @see sd_clock_hfclk_is_running
+ * @see sd_clock_hfclk_request
+ *
+ * @retval ::NRF_SUCCESS
+ */
+SVCALL(SD_CLOCK_HFCLK_RELEASE, uint32_t, sd_clock_hfclk_release(void));
+
+/**@brief Checks if the high frequency crystal oscillator is running.
+ *
+ * @see sd_clock_hfclk_request
+ * @see sd_clock_hfclk_release
+ *
+ * @param[out] p_is_running 1 if the external crystal oscillator is running, 0 if not.
+ *
+ * @retval ::NRF_SUCCESS
+ */
+SVCALL(SD_CLOCK_HFCLK_IS_RUNNING, uint32_t, sd_clock_hfclk_is_running(uint32_t * p_is_running));
+
+/**@brief Waits for an application event.
+ *
+ * An application event is either an application interrupt or a pended interrupt when the interrupt
+ * is disabled.
+ *
+ * When the application waits for an application event by calling this function, an interrupt that
+ * is enabled will be taken immediately on pending since this function will wait in thread mode,
+ * then the execution will return in the application's main thread.
+ *
+ * In order to wake up from disabled interrupts, the SEVONPEND flag has to be set in the Cortex-M
+ * MCU's System Control Register (SCR), CMSIS_SCB. In that case, when a disabled interrupt gets
+ * pended, this function will return to the application's main thread.
+ *
+ * @note The application must ensure that the pended flag is cleared using ::sd_nvic_ClearPendingIRQ
+ * in order to sleep using this function. This is only necessary for disabled interrupts, as
+ * the interrupt handler will clear the pending flag automatically for enabled interrupts.
+ *
+ * @note If an application interrupt has happened since the last time sd_app_evt_wait was
+ * called this function will return immediately and not go to sleep. This is to avoid race
+ * conditions that can occur when a flag is updated in the interrupt handler and processed
+ * in the main loop.
+ *
+ * @post An application interrupt has happened or a interrupt pending flag is set.
+ *
+ * @retval ::NRF_SUCCESS
+ */
+SVCALL(SD_APP_EVT_WAIT, uint32_t, sd_app_evt_wait(void));
+
+/**@brief Get PPI channel enable register contents.
+ *
+ * @param[out] p_channel_enable The contents of the PPI CHEN register.
+ *
+ * @retval ::NRF_SUCCESS
+ */
+SVCALL(SD_PPI_CHANNEL_ENABLE_GET, uint32_t, sd_ppi_channel_enable_get(uint32_t * p_channel_enable));
+
+/**@brief Set PPI channel enable register.
+ *
+ * @param[in] channel_enable_set_msk Mask containing the bits to set in the PPI CHEN register.
+ *
+ * @retval ::NRF_SUCCESS
+ */
+SVCALL(SD_PPI_CHANNEL_ENABLE_SET, uint32_t, sd_ppi_channel_enable_set(uint32_t channel_enable_set_msk));
+
+/**@brief Clear PPI channel enable register.
+ *
+ * @param[in] channel_enable_clr_msk Mask containing the bits to clear in the PPI CHEN register.
+ *
+ * @retval ::NRF_SUCCESS
+ */
+SVCALL(SD_PPI_CHANNEL_ENABLE_CLR, uint32_t, sd_ppi_channel_enable_clr(uint32_t channel_enable_clr_msk));
+
+/**@brief Assign endpoints to a PPI channel.
+ *
+ * @param[in] channel_num Number of the PPI channel to assign.
+ * @param[in] evt_endpoint Event endpoint of the PPI channel.
+ * @param[in] task_endpoint Task endpoint of the PPI channel.
+ *
+ * @retval ::NRF_ERROR_SOC_PPI_INVALID_CHANNEL The channel number is invalid.
+ * @retval ::NRF_SUCCESS
+ */
+SVCALL(SD_PPI_CHANNEL_ASSIGN, uint32_t, sd_ppi_channel_assign(uint8_t channel_num, const volatile void * evt_endpoint, const volatile void * task_endpoint));
+
+/**@brief Task to enable a channel group.
+ *
+ * @param[in] group_num Number of the channel group.
+ *
+ * @retval ::NRF_ERROR_SOC_PPI_INVALID_GROUP The group number is invalid
+ * @retval ::NRF_SUCCESS
+ */
+SVCALL(SD_PPI_GROUP_TASK_ENABLE, uint32_t, sd_ppi_group_task_enable(uint8_t group_num));
+
+/**@brief Task to disable a channel group.
+ *
+ * @param[in] group_num Number of the PPI group.
+ *
+ * @retval ::NRF_ERROR_SOC_PPI_INVALID_GROUP The group number is invalid.
+ * @retval ::NRF_SUCCESS
+ */
+SVCALL(SD_PPI_GROUP_TASK_DISABLE, uint32_t, sd_ppi_group_task_disable(uint8_t group_num));
+
+/**@brief Assign PPI channels to a channel group.
+ *
+ * @param[in] group_num Number of the channel group.
+ * @param[in] channel_msk Mask of the channels to assign to the group.
+ *
+ * @retval ::NRF_ERROR_SOC_PPI_INVALID_GROUP The group number is invalid.
+ * @retval ::NRF_SUCCESS
+ */
+SVCALL(SD_PPI_GROUP_ASSIGN, uint32_t, sd_ppi_group_assign(uint8_t group_num, uint32_t channel_msk));
+
+/**@brief Gets the PPI channels of a channel group.
+ *
+ * @param[in] group_num Number of the channel group.
+ * @param[out] p_channel_msk Mask of the channels assigned to the group.
+ *
+ * @retval ::NRF_ERROR_SOC_PPI_INVALID_GROUP The group number is invalid.
+ * @retval ::NRF_SUCCESS
+ */
+SVCALL(SD_PPI_GROUP_GET, uint32_t, sd_ppi_group_get(uint8_t group_num, uint32_t * p_channel_msk));
+
+/**@brief Configures the Radio Notification signal.
+ *
+ * @note
+ * - The notification signal latency depends on the interrupt priority settings of SWI used
+ * for notification signal.
+ * - To ensure that the radio notification signal behaves in a consistent way, the radio
+ * notifications must be configured when there is no protocol stack or other SoftDevice
+ * activity in progress. It is recommended that the radio notification signal is
+ * configured directly after the SoftDevice has been enabled.
+ * - In the period between the ACTIVE signal and the start of the Radio Event, the SoftDevice
+ * will interrupt the application to do Radio Event preparation.
+ * - Using the Radio Notification feature may limit the bandwidth, as the SoftDevice may have
+ * to shorten the connection events to have time for the Radio Notification signals.
+ *
+ * @param[in] type Type of notification signal, see @ref NRF_RADIO_NOTIFICATION_TYPES.
+ * @ref NRF_RADIO_NOTIFICATION_TYPE_NONE shall be used to turn off radio
+ * notification. Using @ref NRF_RADIO_NOTIFICATION_DISTANCE_NONE is
+ * recommended (but not required) to be used with
+ * @ref NRF_RADIO_NOTIFICATION_TYPE_NONE.
+ *
+ * @param[in] distance Distance between the notification signal and start of radio activity, see @ref NRF_RADIO_NOTIFICATION_DISTANCES.
+ * This parameter is ignored when @ref NRF_RADIO_NOTIFICATION_TYPE_NONE or
+ * @ref NRF_RADIO_NOTIFICATION_TYPE_INT_ON_INACTIVE is used.
+ *
+ * @retval ::NRF_ERROR_INVALID_PARAM The group number is invalid.
+ * @retval ::NRF_ERROR_INVALID_STATE A protocol stack or other SoftDevice is running. Stop all
+ * running activities and retry.
+ * @retval ::NRF_SUCCESS
+ */
+SVCALL(SD_RADIO_NOTIFICATION_CFG_SET, uint32_t, sd_radio_notification_cfg_set(uint8_t type, uint8_t distance));
+
+/**@brief Encrypts a block according to the specified parameters.
+ *
+ * 128-bit AES encryption.
+ *
+ * @note:
+ * - The application may set the SEVONPEND bit in the SCR to 1 to make the SoftDevice sleep while
+ * the ECB is running. The SEVONPEND bit should only be cleared (set to 0) from application
+ * main or low interrupt level.
+ *
+ * @param[in, out] p_ecb_data Pointer to the ECB parameters' struct (two input
+ * parameters and one output parameter).
+ *
+ * @retval ::NRF_SUCCESS
+ */
+SVCALL(SD_ECB_BLOCK_ENCRYPT, uint32_t, sd_ecb_block_encrypt(nrf_ecb_hal_data_t * p_ecb_data));
+
+/**@brief Encrypts multiple data blocks provided as an array of data block structures.
+ *
+ * @details: Performs 128-bit AES encryption on multiple data blocks
+ *
+ * @note:
+ * - The application may set the SEVONPEND bit in the SCR to 1 to make the SoftDevice sleep while
+ * the ECB is running. The SEVONPEND bit should only be cleared (set to 0) from application
+ * main or low interrupt level.
+ *
+ * @param[in] block_count Count of blocks in the p_data_blocks array.
+ * @param[in,out] p_data_blocks Pointer to the first entry in a contiguous array of
+ * @ref nrf_ecb_hal_data_block_t structures.
+ *
+ * @retval ::NRF_SUCCESS
+ */
+SVCALL(SD_ECB_BLOCKS_ENCRYPT, uint32_t, sd_ecb_blocks_encrypt(uint8_t block_count, nrf_ecb_hal_data_block_t * p_data_blocks));
+
+/**@brief Gets any pending events generated by the SoC API.
+ *
+ * The application should keep calling this function to get events, until ::NRF_ERROR_NOT_FOUND is returned.
+ *
+ * @param[out] p_evt_id Set to one of the values in @ref NRF_SOC_EVTS, if any events are pending.
+ *
+ * @retval ::NRF_SUCCESS An event was pending. The event id is written in the p_evt_id parameter.
+ * @retval ::NRF_ERROR_NOT_FOUND No pending events.
+ */
+SVCALL(SD_EVT_GET, uint32_t, sd_evt_get(uint32_t * p_evt_id));
+
+/**@brief Get the temperature measured on the chip
+ *
+ * This function will block until the temperature measurement is done.
+ * It takes around 50 us from call to return.
+ *
+ * @param[out] p_temp Result of temperature measurement. Die temperature in 0.25 degrees Celsius.
+ *
+ * @retval ::NRF_SUCCESS A temperature measurement was done, and the temperature was written to temp
+ */
+SVCALL(SD_TEMP_GET, uint32_t, sd_temp_get(int32_t * p_temp));
+
+/**@brief Flash Write
+*
+* Commands to write a buffer to flash
+*
+* If the SoftDevice is enabled:
+* This call initiates the flash access command, and its completion will be communicated to the
+* application with exactly one of the following events:
+* - @ref NRF_EVT_FLASH_OPERATION_SUCCESS - The command was successfully completed.
+* - @ref NRF_EVT_FLASH_OPERATION_ERROR - The command could not be started.
+*
+* If the SoftDevice is not enabled no event will be generated, and this call will return @ref NRF_SUCCESS when the
+ * write has been completed
+*
+* @note
+* - This call takes control over the radio and the CPU during flash erase and write to make sure that
+* they will not interfere with the flash access. This means that all interrupts will be blocked
+* for a predictable time (depending on the NVMC specification in the device's Product Specification
+* and the command parameters).
+* - The data in the p_src buffer should not be modified before the @ref NRF_EVT_FLASH_OPERATION_SUCCESS
+* or the @ref NRF_EVT_FLASH_OPERATION_ERROR have been received if the SoftDevice is enabled.
+* - This call will make the SoftDevice trigger a hardfault when the page is written, if it is
+* protected.
+*
+*
+* @param[in] p_dst Pointer to start of flash location to be written.
+* @param[in] p_src Pointer to buffer with data to be written.
+* @param[in] size Number of 32-bit words to write. Maximum size is the number of words in one
+* flash page. See the device's Product Specification for details.
+*
+* @retval ::NRF_ERROR_INVALID_ADDR Tried to write to a non existing flash address, or p_dst or p_src was unaligned.
+* @retval ::NRF_ERROR_BUSY The previous command has not yet completed.
+* @retval ::NRF_ERROR_INVALID_LENGTH Size was 0, or higher than the maximum allowed size.
+* @retval ::NRF_ERROR_FORBIDDEN Tried to write to an address outside the application flash area.
+* @retval ::NRF_SUCCESS The command was accepted.
+*/
+SVCALL(SD_FLASH_WRITE, uint32_t, sd_flash_write(uint32_t * p_dst, uint32_t const * p_src, uint32_t size));
+
+
+/**@brief Flash Erase page
+*
+* Commands to erase a flash page
+* If the SoftDevice is enabled:
+* This call initiates the flash access command, and its completion will be communicated to the
+* application with exactly one of the following events:
+* - @ref NRF_EVT_FLASH_OPERATION_SUCCESS - The command was successfully completed.
+* - @ref NRF_EVT_FLASH_OPERATION_ERROR - The command could not be started.
+*
+* If the SoftDevice is not enabled no event will be generated, and this call will return @ref NRF_SUCCESS when the
+* erase has been completed
+*
+* @note
+* - This call takes control over the radio and the CPU during flash erase and write to make sure that
+* they will not interfere with the flash access. This means that all interrupts will be blocked
+* for a predictable time (depending on the NVMC specification in the device's Product Specification
+* and the command parameters).
+* - This call will make the SoftDevice trigger a hardfault when the page is erased, if it is
+* protected.
+*
+*
+* @param[in] page_number Page number of the page to erase
+*
+* @retval ::NRF_ERROR_INTERNAL If a new session could not be opened due to an internal error.
+* @retval ::NRF_ERROR_INVALID_ADDR Tried to erase to a non existing flash page.
+* @retval ::NRF_ERROR_BUSY The previous command has not yet completed.
+* @retval ::NRF_ERROR_FORBIDDEN Tried to erase a page outside the application flash area.
+* @retval ::NRF_SUCCESS The command was accepted.
+*/
+SVCALL(SD_FLASH_PAGE_ERASE, uint32_t, sd_flash_page_erase(uint32_t page_number));
+
+
+
+/**@brief Opens a session for radio timeslot requests.
+ *
+ * @note Only one session can be open at a time.
+ * @note p_radio_signal_callback(@ref NRF_RADIO_CALLBACK_SIGNAL_TYPE_START) will be called when the radio timeslot
+ * starts. From this point the NRF_RADIO and NRF_TIMER0 peripherals can be freely accessed
+ * by the application.
+ * @note p_radio_signal_callback(@ref NRF_RADIO_CALLBACK_SIGNAL_TYPE_TIMER0) is called whenever the NRF_TIMER0
+ * interrupt occurs.
+ * @note p_radio_signal_callback(@ref NRF_RADIO_CALLBACK_SIGNAL_TYPE_RADIO) is called whenever the NRF_RADIO
+ * interrupt occurs.
+ * @note p_radio_signal_callback() will be called at ARM interrupt priority level 0. This
+ * implies that none of the sd_* API calls can be used from p_radio_signal_callback().
+ *
+ * @param[in] p_radio_signal_callback The signal callback.
+ *
+ * @retval ::NRF_ERROR_INVALID_ADDR p_radio_signal_callback is an invalid function pointer.
+ * @retval ::NRF_ERROR_BUSY If session cannot be opened.
+ * @retval ::NRF_ERROR_INTERNAL If a new session could not be opened due to an internal error.
+ * @retval ::NRF_SUCCESS Otherwise.
+ */
+ SVCALL(SD_RADIO_SESSION_OPEN, uint32_t, sd_radio_session_open(nrf_radio_signal_callback_t p_radio_signal_callback));
+
+/**@brief Closes a session for radio timeslot requests.
+ *
+ * @note Any current radio timeslot will be finished before the session is closed.
+ * @note If a radio timeslot is scheduled when the session is closed, it will be canceled.
+ * @note The application cannot consider the session closed until the @ref NRF_EVT_RADIO_SESSION_CLOSED
+ * event is received.
+ *
+ * @retval ::NRF_ERROR_FORBIDDEN If session not opened.
+ * @retval ::NRF_ERROR_BUSY If session is currently being closed.
+ * @retval ::NRF_SUCCESS Otherwise.
+ */
+ SVCALL(SD_RADIO_SESSION_CLOSE, uint32_t, sd_radio_session_close(void));
+
+/**@brief Requests a radio timeslot.
+ *
+ * @note The request type is determined by p_request->request_type, and can be one of @ref NRF_RADIO_REQ_TYPE_EARLIEST
+ * and @ref NRF_RADIO_REQ_TYPE_NORMAL. The first request in a session must always be of type @ref NRF_RADIO_REQ_TYPE_EARLIEST.
+ * @note For a normal request (@ref NRF_RADIO_REQ_TYPE_NORMAL), the start time of a radio timeslot is specified by
+ * p_request->distance_us and is given relative to the start of the previous timeslot.
+ * @note A too small p_request->distance_us will lead to a @ref NRF_EVT_RADIO_BLOCKED event.
+ * @note Timeslots scheduled too close will lead to a @ref NRF_EVT_RADIO_BLOCKED event.
+ * @note See the SoftDevice Specification for more on radio timeslot scheduling, distances and lengths.
+ * @note If an opportunity for the first radio timeslot is not found before 100 ms after the call to this
+ * function, it is not scheduled, and instead a @ref NRF_EVT_RADIO_BLOCKED event is sent.
+ * The application may then try to schedule the first radio timeslot again.
+ * @note Successful requests will result in nrf_radio_signal_callback_t(@ref NRF_RADIO_CALLBACK_SIGNAL_TYPE_START).
+ * Unsuccessful requests will result in a @ref NRF_EVT_RADIO_BLOCKED event, see @ref NRF_SOC_EVTS.
+ * @note The jitter in the start time of the radio timeslots is +/- @ref NRF_RADIO_START_JITTER_US us.
+ * @note The nrf_radio_signal_callback_t(@ref NRF_RADIO_CALLBACK_SIGNAL_TYPE_START) call has a latency relative to the
+ * specified radio timeslot start, but this does not affect the actual start time of the timeslot.
+ * @note NRF_TIMER0 is reset at the start of the radio timeslot, and is clocked at 1MHz from the high frequency
+ * (16 MHz) clock source. If p_request->hfclk_force_xtal is true, the high frequency clock is
+ * guaranteed to be clocked from the external crystal.
+ * @note The SoftDevice will neither access the NRF_RADIO peripheral nor the NRF_TIMER0 peripheral
+ * during the radio timeslot.
+ *
+ * @param[in] p_request Pointer to the request parameters.
+ *
+ * @retval ::NRF_ERROR_FORBIDDEN If session not opened or the session is not IDLE.
+ * @retval ::NRF_ERROR_INVALID_ADDR If the p_request pointer is invalid.
+ * @retval ::NRF_ERROR_INVALID_PARAM If the parameters of p_request are not valid.
+ * @retval ::NRF_SUCCESS Otherwise.
+ */
+ SVCALL(SD_RADIO_REQUEST, uint32_t, sd_radio_request(nrf_radio_request_t const * p_request));
+
+/**@brief Write register protected by the SoftDevice
+ *
+ * This function writes to a register that is write-protected by the SoftDevice. Please refer to your
+ * SoftDevice Specification for more details about which registers that are protected by SoftDevice.
+ * This function can write to the following protected peripheral:
+ * - ACL
+ *
+ * @note Protected registers may be read directly.
+ * @note Register that are write-once will return @ref NRF_SUCCESS on second set, even the value in
+ * the register has not changed. See the Product Specification for more details about register
+ * properties.
+ *
+ * @param[in] p_register Pointer to register to be written.
+ * @param[in] value Value to be written to the register.
+ *
+ * @retval ::NRF_ERROR_INVALID_ADDR This function can not write to the reguested register.
+ * @retval ::NRF_SUCCESS Value successfully written to register.
+ *
+ */
+SVCALL(SD_PROTECTED_REGISTER_WRITE, uint32_t, sd_protected_register_write(volatile uint32_t * p_register, uint32_t value));
+
+/**@} */
+
+#ifdef __cplusplus
+}
+#endif
+#endif // NRF_SOC_H__
+
+/**@} */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/softdevice/s140/headers/nrf_svc.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/softdevice/s140/headers/nrf_svc.h
new file mode 100644
index 0000000..292c692
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/softdevice/s140/headers/nrf_svc.h
@@ -0,0 +1,90 @@
+/*
+ * Copyright (c) 2012 - 2017, 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ */
+
+#ifndef NRF_SVC__
+#define NRF_SVC__
+
+#include "stdint.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifdef SVCALL_AS_NORMAL_FUNCTION
+#define SVCALL(number, return_type, signature) return_type signature
+#else
+
+#ifndef SVCALL
+#if defined (__CC_ARM)
+#define SVCALL(number, return_type, signature) return_type __svc(number) signature
+#elif defined (__GNUC__)
+#ifdef __cplusplus
+#define GCC_CAST_CPP (uint16_t)
+#else
+#define GCC_CAST_CPP
+#endif
+#define SVCALL(number, return_type, signature) \
+ _Pragma("GCC diagnostic push") \
+ _Pragma("GCC diagnostic ignored \"-Wreturn-type\"") \
+ __attribute__((naked)) \
+ __attribute__((unused)) \
+ static return_type signature \
+ { \
+ __asm( \
+ "svc %0\n" \
+ "bx r14" : : "I" (GCC_CAST_CPP number) : "r0" \
+ ); \
+ } \
+ _Pragma("GCC diagnostic pop")
+
+#elif defined (__ICCARM__)
+#define PRAGMA(x) _Pragma(#x)
+#define SVCALL(number, return_type, signature) \
+PRAGMA(swi_number = (number)) \
+ __swi return_type signature;
+#else
+#define SVCALL(number, return_type, signature) return_type signature
+#endif
+#endif // SVCALL
+
+#endif // SVCALL_AS_NORMAL_FUNCTION
+
+#ifdef __cplusplus
+}
+#endif
+#endif // NRF_SVC__
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/softdevice/s140/hex/s140_nrf52_6.0.0_licence-agreement.txt b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/softdevice/s140/hex/s140_nrf52_6.0.0_licence-agreement.txt
new file mode 100644
index 0000000..a71adee
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/softdevice/s140/hex/s140_nrf52_6.0.0_licence-agreement.txt
@@ -0,0 +1,35 @@
+Copyright (c) 2007 - 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, except as embedded into a Nordic
+ Semiconductor ASA integrated circuit in a product or a software update for
+ such product, 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.
+
+4. This software, with or without modification, must only be used with a
+ Nordic Semiconductor ASA integrated circuit.
+
+5. Any software provided in binary form under this license must not be reverse
+ engineered, decompiled, modified and/or disassembled.
+
+THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/softdevice/s140/hex/s140_nrf52_6.0.0_softdevice.hex b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/softdevice/s140/hex/s140_nrf52_6.0.0_softdevice.hex
new file mode 100644
index 0000000..0229a59
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/softdevice/s140/hex/s140_nrf52_6.0.0_softdevice.hex
@@ -0,0 +1,9443 @@
+:020000040000FA
+:1000000000040020990900002D0600007909000075
+:1000100037060000410600004B060000000000000B
+:10002000000000000000000000000000BD0900000A
+:1000300055060000000000005F0600006906000091
+:10004000730600007D060000870600009106000090
+:100050009B060000A5060000AF060000B9060000E0
+:10006000C3060000CD060000D7060000E106000030
+:10007000EB060000F5060000FF060000090700007F
+:10008000130700001D0700002707000031070000CC
+:100090003B070000450700004F070000590700001C
+:1000A000630700006D07000077070000810700006C
+:1000B0008B070000950700009F070000A9070000BC
+:1000C000B3070000BD070000C7070000D10700000C
+:1000D000DB070000E5070000EF070000F90700005C
+:1000E000030800000D0800001708000021080000A8
+:1000F0002B080000350800003F08000049080000F8
+:10010000530800001FB500F003F88DE80F001FBD75
+:1001100000F038BC70B50B46010B184400F6FF70B8
+:10012000040B4FF080500022090303692403406947
+:1001300043431D1B104600F0E9F929462046BDE85F
+:10014000704000F0E3B9F0B54FF6FF734FF4B475AB
+:100150001A466E1E12E0A94201D3344600E00C4656
+:10016000B1EB040130F8027B641E3B441A44F9D120
+:100170009CB204EB134394B204EB12420029EAD17F
+:1001800098B200EB134002EB124140EA0140F0BD8F
+:10019000C34992B00446D1E90001CDE91001FF2224
+:1001A0004021684600F094FB94E80F008DE80F00B2
+:1001B000684610A902E004C841F8042D8842FAD12B
+:1001C00010216846FFF7BFFF1090AA208DF8440069
+:1001D00000F0FAF800F0DDF84FF01024A0691022CA
+:1001E0006946803000F0DEF8A069082210A900F00E
+:1001F000D9F800F0C2F870B504460068A94D072888
+:1002000069D2DFE800F033041929561E2500D4E92D
+:10021000026564682946304600F0FDF82A4621460A
+:10022000304600F0BFF8AA002146304600F024FB1B
+:10023000002800D0032070BD00F0D6FB4FF48050A2
+:1002400007E0201D00F0C6F80028F4D100F0CCFB38
+:1002500060682860002070BD241D94E807009200AB
+:1002600000F00AFB0028F6D00E2070BD00F0BEF8AA
+:100270000028FAD1D4E9010100EB81034FF080504E
+:10028000026945696A43934209D84FF010225369C5
+:1002900003EB81030169406941438B4201D9092085
+:1002A00070BD5069401C01D10F2070BD2046FFF782
+:1002B0006FFF00F09BF80028F7D1201D00F08AF8AE
+:1002C0000028F2D160680028F0D100F07DF800F03D
+:1002D00060F800F052F8072070BD10B50C461828E1
+:1002E00002D00120086010BD2068FFF784FF206065
+:1002F00010BD4FF01024A069401C05D0A569A66967
+:1003000080353079AA2808D06069401C2DD06069FA
+:100310000068401C29D060692CE010212846FFF7B6
+:1003200012FF316881421CD1A16901F18002C03104
+:1003300005E030B108CA51F8040D984201D10120FE
+:1003400000E000208A42F4D158B1286810B1042896
+:1003500003D0FEE7284600F070F85249686808604C
+:1003600008E000F016F800F008F84FF4805001683B
+:10037000491C01D000F012FBFEE7BFF34F8F4A4843
+:1003800001684A4A01F4E06111430160BFF34F8FF5
+:10039000FEE74FF010208169491C02D0806900F00F
+:1003A0008CB870472DE9F04117460D4606460024EB
+:1003B00006E03046296800F093F8641C2D1D361DB8
+:1003C000BC42F6D3BDE8F0814FF0102080694FF4B5
+:1003D00080519FE64FF080510A69496900684A439D
+:1003E000824201D810207047002070474FF08050A3
+:1003F0000169406941434FF01020826902F5805243
+:10040000914201D2092070478069401C01D0002030
+:1004100070470420704770B50C4605464FF480665F
+:1004200008E0284600F049F8B44205D3A4F58064FA
+:1004300005F58055002CF4D170BD4168044609B122
+:10044000012600E000264FF010256869A26892009E
+:1004500000F012FAF8B1A06881006869FFF75AFE4F
+:10046000BEB16E694FF08050A56864680169426949
+:100470005143A1420DD9016940694143A94208D9BC
+:1004800029463046FFF7C7FF2A4621463046FFF788
+:1004900089FFFFF772FFFFF797FFFFF77AFFF8E793
+:1004A0000C0A0000000000200CED00E00400FA053A
+:1004B000144801680029FCD07047134A02211160DA
+:1004C00010490B68002BFCD00F4B1B1D18600868EF
+:1004D0000028FCD00020106008680028FCD070477D
+:1004E000094B10B501221A60064A1468002CFCD092
+:1004F000016010680028FCD00020186010680028F7
+:10050000FCD010BD00E4014004E5014070B50C468C
+:10051000054600F073F810B900F07EF828B12146C6
+:100520002846BDE8704000F007B821462846BDE8DF
+:10053000704000F037B800007FB5002200920192B1
+:10054000029203920A0B000B6946012302440AE05F
+:10055000440900F01F0651F8245003FA06F635430B
+:1005600041F82450401C8242F2D80D490868009A94
+:1005700010430860081D0168019A1143016000F0F2
+:100580003DF800280AD0064910310868029A104345
+:100590000860091D0868039A104308607FBD0000C9
+:1005A0000006004030B50F4C002200BF04EB0213E0
+:1005B000D3F800582DB9D3F8045815B9D3F8085812
+:1005C0001DB1521C082AF1D330BD082AFCD204EB1D
+:1005D0000212C2F80008C3F804180220C3F8080881
+:1005E00030BD000000E001404FF08050D0F83001F5
+:1005F000082801D000207047012070474FF080503C
+:10060000D0F83011062905D0D0F83001401C01D0B7
+:1006100000207047012070474FF08050D0F8300123
+:100620000A2801D0002070470120704708208F4918
+:1006300009680958084710208C4909680958084773
+:1006400014208A4909680958084718208749096809
+:100650000958084730208549096809580847382053
+:1006600082490968095808473C20804909680958A7
+:10067000084740207D4909680958084744207B49BC
+:1006800009680958084748207849096809580847FF
+:100690004C20764909680958084750207349096871
+:1006A00009580847542071490968095808475820D3
+:1006B0006E490968095808475C206C49096809585F
+:1006C0000847602069490968095808476420674954
+:1006D00009680958084768206449096809580847A3
+:1006E0006C20624909680958084770205F49096809
+:1006F0000958084774205D49096809580847782057
+:100700005A490968095808477C2058490968095816
+:1007100008478020554909680958084784205349EB
+:100720000968095808478820504909680958084746
+:100730008C204E4909680958084790204B490968A0
+:1007400009580847942049490968095808479820DA
+:1007500046490968095808479C20444909680958CE
+:100760000847A0204149096809580847A4203F4983
+:10077000096809580847A8203C49096809580847EA
+:10078000AC203A49096809580847B0203749096838
+:1007900009580847B4203549096809580847B8205E
+:1007A0003249096809580847BC2030490968095886
+:1007B0000847C0202D49096809580847C4202B491B
+:1007C000096809580847C82028490968095808478E
+:1007D000CC202649096809580847D02023490968D0
+:1007E00009580847D4202149096809580847D820E2
+:1007F0001E49096809580847DC201C49096809583E
+:100800000847E0201949096809580847E4201749B2
+:10081000096809580847E820144909680958084731
+:10082000EC201249096809580847F0200F49096867
+:1008300009580847F4200D49096809580847F82065
+:100840000A49096809580847FC20084909680958F5
+:1008500008475FF480700549096809580847000097
+:1008600003480449024A034B70470000000000207F
+:10087000180A0000180A000040EA010310B59B079F
+:100880000FD1042A0DD310C808C9121F9C42F8D0FA
+:1008900020BA19BA884201D9012010BD4FF0FF30AB
+:1008A00010BD1AB1D30703D0521C07E0002010BDC1
+:1008B00010F8013B11F8014B1B1B07D110F8013B4D
+:1008C00011F8014B1B1B01D1921EF1D1184610BD2E
+:1008D00002F0FF0343EA032242EA024200F005B8B5
+:1008E0007047704770474FF000020429C0F0128033
+:1008F00010F0030C00F01B80CCF1040CBCF1020FD3
+:1009000018BF00F8012BA8BF20F8022BA1EB0C01A7
+:1009100000F00DB85FEAC17C24BF00F8012B00F89D
+:10092000012B48BF00F8012B70474FF0000200B5C3
+:10093000134694469646203922BFA0E80C50A0E802
+:100940000C50B1F12001BFF4F7AF090728BFA0E8B0
+:100950000C5048BF0CC05DF804EB890028BF40F87C
+:10096000042B08BF704748BF20F8022B11F0804FBE
+:1009700018BF00F8012B7047014B1B68DB68184754
+:100980000000002009480A497047FFF7FBFFFFF706
+:10099000B9FB00BD20BFFDE7064B1847064A1060B3
+:1009A000016881F30888406800470000180A0000C9
+:1009B000180A0000F3020000000000201EF0040FDF
+:1009C0000CBFEFF30881EFF30981886902380078E2
+:1009D000182803D100E00000074A1047074A1268B0
+:1009E0002C3212681047000000B5054B1B68054A01
+:1009F0009B58984700BD0000DB020000000000206B
+:100A0000080A0000040000000010000000000000C0
+:080A100000FFFFFF0090D0037E
+:10100000E0120020754D0200192F0000E74C02008D
+:10101000192F0000192F0000192F000000000000F8
+:10102000000000000000000000000000CD4D0200A4
+:10103000192F000000000000192F0000192F0000D8
+:10104000354E02003B4E0200192F0000192F000000
+:10105000192F0000192F0000192F0000192F000070
+:10106000414E0200192F0000192F0000474E0200C8
+:10107000192F00004D4E0200534E0200594E02003F
+:10108000192F0000192F0000192F0000192F000040
+:10109000192F0000192F0000192F0000192F000030
+:1010A000192F00005F4E0200192F0000192F0000B9
+:1010B000192F0000192F0000192F0000192F000010
+:1010C000654E0200192F0000192F0000192F000093
+:1010D000192F0000192F0000192F0000192F0000F0
+:1010E000192F0000192F0000192F0000192F0000E0
+:1010F000192F0000192F0000192F0000192F0000D0
+:10110000192F0000192F000000F002F823F01FFE35
+:101110000AA090E8000C82448344AAF10107DA4552
+:1011200001D123F014FEAFF2090EBAE80F0013F05C
+:10113000010F18BFFB1A43F00103184734420200A5
+:10114000544202000A444FF0000C10F8013B13F027
+:10115000070408BF10F8014B1D1108BF10F8015B10
+:10116000641E05D010F8016B641E01F8016BF9D103
+:1011700013F0080F1EBF10F8014BAD1C0C1B09D15A
+:101180006D1E58BF01F801CBFAD505E014F8016BCC
+:1011900001F8016B6D1EF9D59142D6D3704700005E
+:1011A0000023002400250026103A28BF78C1FBD870
+:1011B000520728BF30C148BF0B6070471FB500F011
+:1011C0003DF88DE80F001FBD1EF0040F0CBFEFF3BC
+:1011D0000880EFF30980014A10470000752E0000D7
+:1011E0008269034981614FF001001044704700009B
+:1011F000F511000001B41EB400B512F061FF01B496
+:101200000198864601BC01B01EBD0000F0B4404606
+:10121000494652465B460FB402A0013001B506486C
+:10122000004700BF01BC86460FBC804689469246F7
+:101230009B46F0BC704700000911000023F084BDFC
+:1012400070B51A4C054609202070A01C00F05FF80C
+:101250005920A08029462046BDE8704008F060B8BB
+:1012600008F069B870B50C461149097829B1A0F1A8
+:1012700060015E2908D3012013E0602804D06928AA
+:1012800002D043F201000CE020CC0A4E94E80E009C
+:1012900006EB8000A0F58050241FD0F8806E284611
+:1012A000B047206070BD012070470000080000209A
+:1012B0001C000020CC4E020010B504460021012085
+:1012C00000F03DF800210B2000F039F8042119202E
+:1012D00000F035F804210D2000F031F804210E2033
+:1012E00000F02DF804210F2000F029F80421C84354
+:1012F00000F025F80621162000F021F8062115201F
+:1013000000F01DF82046FFF79BFF002010BDA9212B
+:1013100001807047FFF7A4BF11487047104870471D
+:10132000104A10B514680F4B0F4A08331A60FFF7C4
+:1013300099FF0C48001D046010BD704770474907B5
+:10134000090E002806DA00F00F0000F1E02080F816
+:10135000141D704700F1E02080F800147047000071
+:1013600003F900421005024001000001FE4800217F
+:1013700001604160018170472DE9F743044692B056
+:101380009146406813F060F940B1606813F065F968
+:1013900020B9607800F00300022801D0012000E0AD
+:1013A0000020F14E3072484613F00AF918B11020AF
+:1013B00015B0BDE8F0834946012001F018FF002870
+:1013C000F6D101258DF842504FF4C050ADF84000E1
+:1013D000002210A9284606F04BFC0028E8D18DF821
+:1013E00042504FF428504FF00008ADF840004746F7
+:1013F0001C216846CDF81C8023F04DFC9DF81C0094
+:1014000008AA20F00F00401C20F0F00010308DF8EA
+:101410001C0020788DF81D0061789DF81E0061F396
+:10142000420040F001008DF81E009DF800000AA95E
+:1014300040F002008DF800002089ADF83000ADF8D2
+:101440003270608907AFADF834000B97606810AC5C
+:101450000E900A94684606F000FA0028A8D1BDF85C
+:10146000200030808DF8425042F60120ADF8400057
+:101470009DF81E0008AA20F00600801C20F0010044
+:101480008DF81E000220ADF83000ADF8340013A82E
+:101490000E900AA9684606F0E0F9002888D1BDF848
+:1014A00020007080311D484600F033F9002887D1B4
+:1014B0008DF8425042F6A620ADF840001C21684647
+:1014C000CDF81C8023F0E7FB9DF81C00ADF83450EC
+:1014D00020F00F00401C20F0F00010308DF81C00B0
+:1014E0009DF81D0008AA20F0FF008DF81D009DF852
+:1014F0001E000AA920F0060040F00100801C8DF8B3
+:101500001E009DF800008DF8445040F002008DF858
+:101510000000CDE90A4711A80E90ADF8305068469A
+:1015200006F09BF9002899D1BDF82000F08000203A
+:101530003EE73EB504460820ADF80000204613F013
+:101540003FF808B110203EBD2146012001F04FFEBA
+:101550000028F8D12088ADF804006088ADF80600B6
+:10156000A088ADF80800E088ADF80A007E4801AB1D
+:101570006A468088002106F075FDBDF80010082934
+:10158000E1D003203EBD1FB5044600200290082094
+:10159000ADF80800CDF80CD0204613F011F810B1CA
+:1015A000102004B010BD704802AA81884FF6FF7069
+:1015B00006F09AFF0028F4D1BDF80810082901D0E0
+:1015C0000320EEE7BDF800102180BDF80210618015
+:1015D000BDF80410A180BDF80610E180E1E701B577
+:1015E00082B00220ADF800005F4802AB6A46408836
+:1015F000002106F037FDBDF80010022900D00320BD
+:101600000EBD1CB5002100910221ADF80010019023
+:1016100012F0FCFF08B110201CBD53486A464188F7
+:101620004FF6FF7006F060FFBDF800100229F3D0FE
+:1016300003201CBDFEB54C4C06461546207A0F46CD
+:10164000C00705D0084612F0BBFF18B11020FEBD40
+:101650000F20FEBDF82D01D90C20FEBD304612F042
+:10166000AFFF18BB208801A905F040FE0028F4D187
+:1016700030788DF80500208801A906F0D2FC0028FA
+:10168000EBD100909DF800009DF8051040F002009D
+:101690008DF80000090703D040F008008DF8000025
+:1016A0002088694606F05AFC0028D6D1ADF80850CB
+:1016B00020883B4602AA002106F0D4FCBDF80810A1
+:1016C000A942CAD00320FEBD7CB50546002000908B
+:1016D00001900888ADF800000C462846019512F0EC
+:1016E000B3FF18B9204612F091FF08B110207CBD5D
+:1016F00015B1BDF8000050B11B486A4601884FF68D
+:10170000FF7006F0F1FEBDF8001021807CBD0C20BA
+:101710007CBD30B593B0044600200D4600901421E6
+:1017200001A823F0B8FA1C2108A823F0B4FA9DF808
+:101730000000CDF808D020F00F00401C20F0F00091
+:1017400010308DF800009DF8010020F0FF008DF8AA
+:1017500001009DF8200040F002008DF820000120DB
+:101760008DF8460002E000000C02002042F6042042
+:10177000ADF8440011A801902088ADF83C006088C5
+:10178000ADF83E00A088ADF84000E088ADF842001A
+:101790009DF8020006AA20F00600801C20F001003F
+:1017A0008DF802000820ADF80C00ADF810000FA86D
+:1017B000059001A908A806F050F8002803D1BDF84B
+:1017C00018002880002013B030BD0000F0B5007B69
+:1017D000059F1E4614460D46012800D0FFDF0C2051
+:1017E00030803A203880002C08D0287A032806D090
+:1017F000287B012800D0FFDF17206081F0BDA88979
+:10180000FBE72DE9F04786B0144691F80C900E9A4C
+:101810000D46B9F1010F0BD01021007B2E8A8846AE
+:10182000052807D0062833D0FFDF06B0BDE8F087D3
+:101830000221F2E7E8890C2100EB400001EB4000B7
+:10184000188033201080002CEFD0E88960810027B9
+:101850001AE00096688808F1020301AA696900F09D
+:1018600084FF06EB0800801C07EB470186B204EBFF
+:101870004102BDF8040090810DF1060140460E3290
+:1018800010F074FF7F1CBFB26089B842E1D8CCE78A
+:1018900034201080E889B9F1010F11D0122148439A
+:1018A0000E301880002CC0D0E88960814846B9F11C
+:1018B000010F00D00220207300270DF1040A1FE061
+:1018C0000621ECE70096688808F1020301AA69691D
+:1018D00000F04BFF06EB0800801C86B2B9F1010F47
+:1018E00012D007EBC70004EB4000BDF80410C18123
+:1018F00010220AF10201103023F02CF97F1CBFB234
+:101900006089B842DED890E707EB470104EB41025B
+:10191000BDF80400D0810AF102014046103210F0F7
+:1019200025FFEBE72DE9F0470E4688B090F80CC094
+:1019300096F80C80378AF5890C20109902F10C0476
+:101940004FF0000ABCF1030F08D0BCF1040F3ED0E9
+:10195000BCF1070F7DD0FFDF08B067E705EB850C12
+:1019600000EB4C00188031200880002AF4D0A8F148
+:10197000060000F0FF09558125E0182101A823F099
+:101980008AF900977088434601AA716900F0EDFE5C
+:10199000BDF804002080BDF80600E080BDF8080016
+:1019A0002081A21C0DF10A01484610F0DFFEB9F1BA
+:1019B000000F00D018B184F804A0A4F802A007EB2F
+:1019C000080087B20A346D1EADB2D6D2C4E705EB6B
+:1019D000850C00EB4C00188032200880002ABBD018
+:1019E000A8F1050000F0FF09558137E000977088E5
+:1019F000434601AA716900F0B8FE9DF80600BDF8E3
+:101A00000410E1802179420860F3000162F3410192
+:101A1000820862F38201C20862F3C301020962F321
+:101A20000411420962F34511820962F386112171A2
+:101A3000C0096071BDF80700208122460DF109013F
+:101A4000484610F093FE18B184F802A0A4F800A054
+:101A500000E007E007EB080087B20A346D1EADB264
+:101A6000C4D279E7A8F1020084B205FB08F000F1C6
+:101A70000E0CA3F800C035230B80002AA6D0558198
+:101A80009481009783B270880E32716900F06DFE08
+:101A900062E72DE9F84F1E460A9D0C4681462AB1A1
+:101AA000607A00F58070D080E089108199F80C0090
+:101AB0000C274FF000084FF00E0A0D2873D2DFE814
+:101AC00000F09E070E1C28303846556A7373730069
+:101AD000214648460095FFF779FEBDE8F88F207B48
+:101AE0009146082802D0032800D0FFDF378030203D
+:101AF0000AE000BFA9F80A80EFE7207B914604289E
+:101B000000D0FFDF378031202880B9F1000FF1D1FC
+:101B1000E3E7207B9146042800D0FFDF37803220A6
+:101B2000F2E7207B9146022800D0FFDF3780332088
+:101B3000EAE7207B1746022800D0FFDF3420A6F812
+:101B400000A02880002FC8D0A7F80A80C5E7207B16
+:101B50001746042800D0FFDF3520A6F800A0288013
+:101B6000002FBAD04046A7F80A8012E0207B174623
+:101B7000052802D0062800D0FFDF10203080362054
+:101B80002880002FA9D0E0897881A7F80E80B9F8C5
+:101B90000E00B881A1E7207B9146072800D0FFDF27
+:101BA00037803720B0E72AE04FF0120018804FF05E
+:101BB00038001700288090D0E0897881A7F80E803F
+:101BC000A7F8108099F80C000A2805D00B2809D036
+:101BD0000C280DD0FFDF80E7207B0A2800D0FFDF34
+:101BE00001200AE0207B0B2800D0FFDF042004E066
+:101BF000207B0C2800D0FFDF052038736DE7FFDF66
+:101C00006BE770B50C46054601F025FC20B1007865
+:101C1000222804D2082070BD43F2020070BD0521C5
+:101C200028460FF021F8206008B1002070BD032085
+:101C300070BD30B44880087820F00F00C01C20F040
+:101C4000F000903001F8080B1DCA81E81D0030BC7F
+:101C500007F0E7BB2DE9FF4784B0002782460297D3
+:101C600007989046894612300AF048F9401D20F046
+:101C70000306079828B907A95046FFF7C2FF0028B6
+:101C800054D1B9F1000F05D00798017B19BB052588
+:101C900004681BE098F80000092803D00D2812D032
+:101CA000FFDF46E0079903254868B0B3497B4288C7
+:101CB0007143914239D98AB2B3B2011D0EF047FE89
+:101CC0000446078002E0079C042508340CB12088F4
+:101CD00010B1032D29D02CE00798012112300AF011
+:101CE0003FF9ADF80C00024602AB2946504608F019
+:101CF000F4F9070001D1A01C029007983A4612306F
+:101D0000C8F80400A8F802A003A94046029B0AF004
+:101D100034F9D8B10A2817D200E006E0DFE800F075
+:101D200007091414100B0D141412132014E60020CC
+:101D300012E6112010E608200EE643F203000BE63F
+:101D4000072009E60D2007E6032005E6BDF80C0094
+:101D50002346CDE900702A465046079900F015FD4C
+:101D600057B9032D08D10798B3B2417B406871433E
+:101D70008AB2011D0EF0FFFDB9F1000FD7D007990F
+:101D800081F80C90D3E72DE9FE4F91461A881C4646
+:101D90008A468046FAB102AB494608F09EF9050032
+:101DA00019D04046A61C27880FF0A2F83246072615
+:101DB00029463B4600960EF0B0FC20882346CDE92C
+:101DC00000504A465146404600F0DFFC002020808B
+:101DD0000120BDE8FE8F0020FBE710B586B01C4651
+:101DE000AAB104238DF800301388ADF8083052886A
+:101DF000ADF80A208A788DF80E200988ADF80C100D
+:101E000000236A462146FFF725FF06B010BD1020CB
+:101E1000FBE770B50D4605210EF026FF040000D14A
+:101E2000FFDF294604F11200BDE870400AF081B8D6
+:101E30002DE9F8430D468046002607F0EFFA0446E8
+:101E40002878102878D2DFE800F0773B345331311E
+:101E5000123131310831313131312879001FC0B2AE
+:101E6000022801D0102810D114BBFFDF35E004B9DF
+:101E7000FFDF052140460EF0F7FE007B032806D069
+:101E800004280BD0072828D0FFDF072655E0287943
+:101E9000801FC0B2022820D050B1F6E72879401F39
+:101EA000C0B2022819D0102817D0EEE704B9FFDF1E
+:101EB00013E004B9FFDF287901280ED1172137E09C
+:101EC000052140460EF0D0FE070000D1FFDF07F1EC
+:101ED000120140460AF00AF82CB12A462146404633
+:101EE000FFF7A7FE29E01321404602F0A9FD24E0F8
+:101EF00004B9FFDF052140460EF0B6FE060000D112
+:101F0000FFDF694606F1120009F0FAFF060000D073
+:101F1000FFDFA988172901D2172200E00A46BDF881
+:101F20000000824202D9014602E005E01729C5D32C
+:101F3000404600F03AFCD0E7FFDF3046BDE8F883CA
+:101F4000401D20F0030219B102FB01F0001D00E06A
+:101F500000201044704713B5009848B1002468462B
+:101F60000EF09FFC002C02D1F74A009911601CBDB5
+:101F700001240020F4E72DE9F0470C461546242102
+:101F8000204622F088FE05B9FFDFA8786073288814
+:101F9000DFF8B4A3401D20F00301AF788946DAF8DA
+:101FA00000000EF09CFC060000D1FFDF4FF000089F
+:101FB0002660A6F8008077B109FB07F1091D0AD059
+:101FC000DAF800000EF08BFC060000D1FFDF66603F
+:101FD000C6F8008001E0C4F80480298804F11200EA
+:101FE000BDE8F04709F074BF2DE9F047804601F1E4
+:101FF00012000D46814609F081FF401DD24F20F0AE
+:1020000003026E7B1446296838680EF093FC3EB1DB
+:1020100004FB06F2121D03D0696838680EF08AFCD2
+:1020200005200EF0C9FD044605200EF0CDFD201A56
+:10203000012802D138680EF047FC49464046BDE809
+:10204000F04709F05ABF70B5054605210EF00CFEA9
+:10205000040000D1FFDF04F112012846BDE8704002
+:1020600009F044BF2DE9F04F91B04FF0000BADF8EF
+:1020700034B0ADF804B047880C46054692460521B9
+:1020800038460EF0F1FD060000D1FFDF24B1A78035
+:10209000A4F806B0A4F808B0297809220B20B2EB06
+:1020A000111F7DD12A7A04F1100138274FF00C0856
+:1020B0004FF001090391102A73D2DFE802F072F2A7
+:1020C000F1F07F08D2888D9F3DDBF3EEB6B6307B12
+:1020D000022800D0FFDFA88908EBC001ADF804108A
+:1020E0003021ADF83410002C25D06081B5F80E9069
+:1020F00000271DE004EBC708317C88F80E10F18939
+:10210000A8F80C10CDF800906888042304AA296967
+:1021100000F02BFBBDF81010A8F8101009F1040016
+:10212000BDF812107F1C1FFA80F9A8F81210BFB278
+:102130006089B842DED80DE1307B022800D0FFDF95
+:10214000E98908EBC100ADF804003020ADF8340097
+:10215000287B0A90001FC0B20F90002CEBD0618149
+:10216000B5F81090002725E0CDF8009068886969DF
+:1021700003AA0A9B00F0F9FA0A9804EBC70848443E
+:102180001FFA80F908F10C0204A90F9810F0EEFA7A
+:1021900018B188F80EB0A8F80CB0BDF80C1001E02A
+:1021A000D4E0CFE0A8F81010BDF80E107F1CA8F8FE
+:1021B0001210BFB26089B842D6D8CBE00DA800900B
+:1021C00001AB224629463046FFF71BFBC2E0307BBD
+:1021D000082805D0FFDF03E0307B082800D0FFDFB0
+:1021E000E8891030ADF804003620ADF83400002C3A
+:1021F0003FD0A9896181F189A18127E0307B09283D
+:1022000000D0FFDFA88900F10C01ADF804103721E0
+:10221000ADF83410002C2CD06081E8890090AB8997
+:10222000688804F10C02296956E0E88939211030E8
+:1022300080B2ADF80400ADF83410002C74D0A98938
+:102240006181287A0E280AD002212173E989E1816F
+:10225000288A0090EB8968886969039A3CE001212B
+:10226000F3E70DA8009001AB224629463046FFF760
+:1022700059FB6FE0307B0A2800D0FFDF1220ADF859
+:102280000400ADF834704CB3A9896181A4F810B092
+:10229000A4F80EB084F80C905CE020E002E031E09D
+:1022A00039E042E0307B0B2800D0FFDF288AADF810
+:1022B00034701230ADF8040084B104212173A9896F
+:1022C0006181E989E181298A2182688A00902B8ACB
+:1022D000688804F11202696900F047FA3AE0307B3D
+:1022E0000C2800D0FFDF1220ADF80400ADF83470E8
+:1022F0003CB305212173A4F80AB0A4F80EB0A4F8E9
+:1023000010B027E00DA8009001AB224629463046C8
+:10231000FFF75CFA1EE00DA8009001AB22462946AB
+:102320003046FFF7B6FB15E034E03B21ADF8040082
+:10233000ADF8341074B3A4F80690A4F808B084F88B
+:102340000AB007E0FFDF05E010000020297A01292C
+:1023500017D0FFDFBDF80400AAF800006CB1BDF88B
+:1023600034002080BDF804006080BDF834003928B6
+:1023700003D03C2801D086F80CB011B00020BDE895
+:10238000F08F3C21ADF80400ADF8341014B1697A37
+:10239000A172DFE7AAF80000EFE72DE9F8435688BD
+:1023A0000F4680461546052130460EF05DFC0400C0
+:1023B00000D1FFDF123400943B46414630466A6844
+:1023C00009F00FFFBAE570B50D4605210EF04CFC83
+:1023D000040000D1FFDF294604F11200BDE870407F
+:1023E00009F099BD70B50D4605210EF03DFC0400C5
+:1023F00000D1FFDF294604F11200BDE8704009F06A
+:10240000B7BD70B5054605210EF02EFC040000D1C5
+:10241000FFDF04F1080321462846BDE8704004228E
+:10242000B1E470B5054605210EF01EFC040000D194
+:10243000FFDF214628462368BDE870400522A2E45C
+:1024400070B5064605210EF00FFC040000D1FFDF39
+:1024500004F1120009F052FD401D20F0030511E0C7
+:10246000011D00880322431821463046FFF78BFCEC
+:1024700000280BD0607BABB2684382B26068011D5C
+:102480000EF0AFFA606841880029E9D170BD70B5DF
+:102490000E46054606F0C2FF040000D1FFDF012012
+:1024A000207266726580207820F00F00C01C20F03A
+:1024B000F00030302070BDE8704006F0B2BF2DE96A
+:1024C000F0438BB00D461446814606A9FFF799FBF1
+:1024D000002814D14FF6FF7601274FF420588CB115
+:1024E00003208DF800001020ADF8100007A805901B
+:1024F00007AA204604A910F058F978B107200BB0BC
+:10250000BDE8F0830820ADF808508DF80E708DF806
+:102510000000ADF80A60ADF80C800CE00698A178D8
+:1025200001742188C1818DF80E70ADF80850ADF8A6
+:102530000C80ADF80A606A4602214846069BFFF708
+:1025400089FBDCE708B501228DF8022042F6020281
+:10255000ADF800200A4603236946FFF73EFC08BD9C
+:1025600008B501228DF8022042F60302ADF80020E2
+:102570000A4604236946FFF730FC08BD00B587B062
+:1025800079B102228DF800200A88ADF80820498828
+:10259000ADF80A1000236A460521FFF75BFB07B080
+:1025A00000BD1020FBE709B1072316E407207047A0
+:1025B00070B588B00D461446064606A9FFF721FB04
+:1025C00000280ED17CB10620ADF808508DF800002F
+:1025D000ADF80A40069B6A460821DC813046FFF7C9
+:1025E00039FB08B070BD05208DF80000ADF808502B
+:1025F000F0E700B587B059B107238DF80030ADF88A
+:102600000820039100236A460921FFF723FBC6E750
+:102610001020C4E770B588B00C460646002506A910
+:10262000FFF7EFFA0028DCD106980121123009F0FB
+:1026300097FC9CB12178062921D2DFE801F0200522
+:1026400005160318801E80B2C01EE28880B20AB14F
+:10265000A3681BB1824203D90C20C2E71020C0E757
+:10266000042904D0A08850B901E00620B9E7012967
+:1026700013D0022905D004291CD005292AD007200F
+:10268000AFE709208DF800006088ADF80800E08809
+:10269000ADF80A00A068039023E00A208DF800003E
+:1026A0006088ADF80800E088ADF80A00A0680A2547
+:1026B000039016E00B208DF800006088ADF808004C
+:1026C000A088ADF80A00E088ADF80C00A0680B25E2
+:1026D000049006E00C208DF8000060788DF808006A
+:1026E0000C256A4629463046069BFFF7B3FA78E781
+:1026F00000B587B00D228DF80020ADF8081000233A
+:102700006A461946FFF7A6FA49E700B587B071B1E6
+:1027100002228DF800200A88ADF808204988ADF81B
+:102720000A1000236A460621FFF794FA37E71020C3
+:1027300035E770B586B0064601200D46ADF80810A5
+:102740008DF80000014600236A463046FFF782FA02
+:10275000040008D12946304605F09EFC0021304691
+:1027600005F0B8FC204606B070BDF8B51C4615460D
+:102770000E46069F0EF0AAFB2346FF1DBCB2314653
+:102780002A4600940DF095FFF8BD30B41146DDE9FE
+:1027900002423CB1032903D0002330BC08F026BB21
+:1027A0000123FAE71A8030BC704770B50C46054625
+:1027B000FFF72FFB2146284605F07DFC2846BDE8A3
+:1027C0007040012105F086BC4FF0E0224FF400413B
+:1027D0000020C2F88011204908702049900208604A
+:1027E000704730B51C4D04462878A04218BF002C15
+:1027F00002D0002818BFFFDF2878A04208BF30BDF4
+:102800002C701749154A0020ECB1164DDFF858C05E
+:10281000131F012C0DD0022C1CBFFFDF30BD086040
+:1028200003200860CCF800504FF4000010601860DE
+:1028300030BD086002200860CCF800504FF04070B6
+:102840001060186030BD086008604FF06070106064
+:1028500030BD00B5FFDF00BD1800002008F50140C5
+:1028600000F500408C02002014F5004070B50B20EC
+:1028700000F0B5F9082000F0B2F900210B2000F0BB
+:10288000C4F90021082000F0C0F9EC4C0125656076
+:10289000A5600020C4F84001C4F84401C4F8480110
+:1028A0000B2000F0A7F9082000F0A4F90B2000F09D
+:1028B0008BF9256070BD10B50B2000F090F9082051
+:1028C00000F08DF9DD48012141608160DC490A6832
+:1028D000002AFCD10021C0F84011C0F84411C0F812
+:1028E00048110B2000F086F9BDE81040082000F0E8
+:1028F00081B910B50B2000F07DF9BDE8104008202B
+:1029000000F078B900B530B1012806D0022806D011
+:10291000FFDF002000BDCB4800BDCB4800BDCA484A
+:10292000001D00BD70B5C9494FF000400860C84D9A
+:10293000C00BC5F80803C74800240460C5F840412F
+:102940000820C43500F04BF9C5F83C41C24804707A
+:1029500070BD08B5B94A002128B1012811D002285C
+:102960001CD0FFDF08BD4FF48030C2F80803C2F866
+:102970004803B3483C300160C2F84011BDE808404C
+:10298000D0E74FF40030C2F80803C2F84803AC485F
+:1029900040300160C2F84411AB480CE04FF4802095
+:1029A000C2F80803C2F84803A54844300160C2F8E1
+:1029B0004811A548001D0068009008BD70B5164676
+:1029C0000D460446022800D9FFDF00229B48012360
+:1029D00004F110018B4000EB8401C1F8405526B191
+:1029E000C1F84021C0F8043303E0C0F80833C1F84F
+:1029F0004021C0F8443370BD2DE9F0411C46154616
+:102A000030B1012834D0022839D0FFDFBDE8F08191
+:102A1000891E002221F07F411046FFF7CFFF012CD5
+:102A200024D000208C4E8A4F012470703C6189496B
+:102A300000203C3908600220091D086085490420F7
+:102A40003039086083483D350560C7F800420820EA
+:102A500000F0D0F82004C7F80403082000F0B4F810
+:102A60007A49E007091F08603470CFE70120D9E7F1
+:102A7000012B02D00022012005E00122FBE7012BFF
+:102A800004D000220220BDE8F04197E70122F9E7D7
+:102A90006B480068704770B500F0C7F8674C054692
+:102AA000D4F840010026012809D1D4F80803C00356
+:102AB00005D54FF48030C4F80803C4F84061D4F859
+:102AC000440101280CD1D4F80803800308D54FF441
+:102AD0000030C4F80803C4F84461012010F029FE56
+:102AE000D4F8480101280CD1D4F80803400308D5D4
+:102AF0004FF48020C4F80803C4F84861022010F0A5
+:102B000018FE5648056070BD70B500F08EF8524D45
+:102B10000446287858B1FFF705FF687820B10020F7
+:102B200085F8010010F005FE4C48046070BD0320DC
+:102B3000F8E74FF0E0214FF40010C1F800027047B1
+:102B4000152000F057B8424901200861082000F024
+:102B500051B83F494FF47C10C1F8080300200246E9
+:102B600001EB8003C3F84025C3F84021401CC0B2EC
+:102B70000628F5D37047410A43F609525143C0F382
+:102B8000080010FB02F000F5807001EB5020704748
+:102B900010B5430B48F2376463431B0C5C020C60B6
+:102BA0002F4C03FB04002F4B4CF2F72443435B0DE7
+:102BB00013FB04F404EB402000F580704012107009
+:102BC00008681844086010BD00F01F020121914000
+:102BD0004009800000F1E020C0F80011704700F0CB
+:102BE0001F02012191404009800000F1E020C0F85F
+:102BF0008011704700F01F020121914040098000C0
+:102C000000F1E020C0F8801270474907090E002843
+:102C100006DA00F00F0000F1E02080F8141D704784
+:102C200000F1E02080F8001470470C48001F006895
+:102C30000A4A0D49121D11607047000000B00040A3
+:102C400004B500404081004044B1004008F5014017
+:102C500000800040408500403800002014050240FC
+:102C6000F7C2FFFF6F0C0100010000010A4810B518
+:102C70000468094909480831086010F0EEFD06486B
+:102C8000001D046010BD0649002008604FF0E021DF
+:102C90000220C1F8800270471005024001000001C7
+:102CA000FC1F004010B50D2000F06FF8C4B26FF0AB
+:102CB000040000F06AF8C0B2844200D0FFDF3A4955
+:102CC0000120086010BD70B50D2000F048F8374CA9
+:102CD0000020C4F800010125C4F804530D2000F0C1
+:102CE00049F825604FF0E0216014C1F8000170BD83
+:102CF00010B50D2000F033F82C480121416000216F
+:102D0000C0F80011BDE810400D2000F033B828488D
+:102D100010B5046826492748083108602349D1F8CE
+:102D20000001012804D0FFDF2148001D046010BD10
+:102D30001D48001D00680022C0B2C1F8002111F03A
+:102D400039F9F1E710B51948D0F800110029FBD086
+:102D5000FFF7DDFFBDE810400D2000F00BB800F0DC
+:102D60001F02012191404009800000F1E020C0F8DD
+:102D70008011704700F01F0201219140400980003E
+:102D800000F1E020C0F880127047002806DA00F059
+:102D90000F0000F1E02090F8140D03E000F1E020B6
+:102DA00090F800044009704704D5004000D000406E
+:102DB000100502400100000110B5202000F082F84B
+:102DC000202000F08AF84A49202081F8000449496F
+:102DD00000060860091D48480860FEF79DFA45494D
+:102DE000C83108604548D0F8041341F00101C0F82B
+:102DF0000413D0F8041341F08071C0F804133C4967
+:102E000001201C39C1F8000110BD10B5202000F0D0
+:102E100059F8384800210160001D0160354A481EFC
+:102E2000E83A1060354AC2F80803324BC8331960DB
+:102E3000C2F80001C2F8600131490860BDE81040E5
+:102E4000202000F04AB82B492E48EC390860704722
+:102E500028492C48E8390860704726480160001D61
+:102E6000521E0260704723490120E8390860BFF311
+:102E70004F8F704770B51F4A8069E83A2149116049
+:102E80001E49D1F8006100231F4D1D4A5C1E1EB172
+:102E9000A84206D300210FE0D1F8606186B1A842B4
+:102EA00009D2C1F80031C1F860311460BDE870404A
+:102EB000202000F012B81168BDE8704021F012BF68
+:102EC000FFDF70BD00F01F0201219140400980002A
+:102ED00000F1E020C0F88011704700F01F020121CE
+:102EE00091404009800000F1E020C0F88012704756
+:102EF00020E000E000060240C41400200000024070
+:102F00000004024001000001006002000F4A126844
+:102F10000D498A420CD118470C4A12680A4B9A4252
+:102F200006D101B511F0C0F8FFF78DFFBDE80140F3
+:102F3000074909680958084706480749054A064BE2
+:102F40007047000000000000BEBAFECAB0000020BA
+:102F500004000020E0120020E012002070B50C46B2
+:102F6000054609F0DBFA21462846BDE870400AF024
+:102F7000C0BB10B511F01EFDFFF726FC11F09EFB43
+:102F8000BDE8104011F050BC012081070860704777
+:102F9000012081074860704712480068C00700D0D0
+:102FA000012070470F48001F0068C00700D00120B3
+:102FB00070470C4808300068C00700D001207047F7
+:102FC000084810300068704706490C310A68D2037F
+:102FD00006D5096801F00301814201D10120704743
+:102FE000002070470C0400407047704770477047DE
+:102FF000704770477047704770470004050600002F
+:103000002CFFFFFFDBE5B15100600200A900FFFFCC
+:103010008C000000808D5B0016425791AD5F58BC5C
+:103020008E702F5A0FAA100DBCD52BFD30B5FC4D5C
+:103030000446062CA9780ED2DFE804F0030E0E0E2B
+:103040000509FFDF08E0022906D0FFDF04E00329BD
+:1030500002D0FFDF00E0FFDFAC7030BD30B50446CA
+:103060001038EF4D07280CD2DFE800F0040C060CF6
+:103070000C0C0C00FFDF05E0287E112802D0FFDFDA
+:1030800000E0FFDF2C7630BD2DE9F0410FF0F8FCB9
+:10309000044610F08CFE201AC5B206200DF08CFDFF
+:1030A000044606200DF090FD211ADD4C207E1228EA
+:1030B00018D000200F1807200DF07EFD06460720CF
+:1030C0000DF082FD301A3918207E13280CD0002014
+:1030D0000144A078042809D000200844281AC0B26E
+:1030E000BDE8F0810120E5E70120F1E70120F4E7E8
+:1030F000CB4810B590F825004108C94800F12600DA
+:1031000005D00BF0EBFABDE8104005F0B3BF0BF0B3
+:10311000BEFAF8E730B50446A1F120000D460A28B2
+:103120004AD2DFE800F005070C1C2328353A3F445B
+:10313000FFDF42E0207820283FD1FFDF3DE0B848A4
+:103140008178052939D0007E122836D020782428AD
+:1031500033D0252831D023282FD0FFDF2DE0207851
+:1031600022282AD0232828D8FFDF26E0207822280A
+:1031700023D0FFDF21E0207822281ED024281CD075
+:1031800026281AD0272818D0292816D0FFDF14E0C7
+:103190002078252811D0FFDF0FE0207825280CD0DB
+:1031A000FFDF0AE02078252807D0FFDF05E0207840
+:1031B000282802D0FFDF00E0FFDF257030BD10B50A
+:1031C000012803D0022805D0FFDF10BDBDE8104064
+:1031D00003202BE79248007E122800D0FFDF002159
+:1031E000052011F0A1F9BDE81040112036E71FB508
+:1031F00004466A46002001F01FFEB4B1BDF802206B
+:103200004FF6FF700621824201D1ADF80210BDF8E1
+:103210000420824201D1ADF80410BDF808108142AB
+:1032200003D14FF44860ADF8080068460CF06AF925
+:1032300005F020FF04B010BD70B514460D460646DB
+:1032400011F0BEF958B90DB1A54201D90C2070BDDD
+:10325000002408E056F8240011F0B2F908B110205B
+:1032600070BD641CE4B2AC42F4D3002070BD2DE903
+:10327000F04105461F4690460E460024006811F0B6
+:10328000ECF908B110202BE728680028A88802D0A4
+:10329000B84202D84FE00028F5D0092020E728687E
+:1032A000025DB2B1611C475C152F2DD03BDC3AD2D8
+:1032B000DFE807F03912222228282A2A3131393949
+:1032C00039393939393939392200025D32BB641C48
+:1032D000A4B2A142F9D833E0022ADED1A21C805C5C
+:1032E00088F80000072801D2400701D40A20F7E639
+:1032F000307840F0010015E0D043C00707E0012A14
+:1033000007D010E00620EBE61007A0F1805000285F
+:10331000F5D01846E4E63078820701D50B20DFE6C9
+:1033200040F0020030702868005D084484B2A8882C
+:10333000A04202D2B1E74FF4485381B2A142AED8C5
+:103340000020CDE610B5027843F202235408012292
+:10335000022C12D003DC3CB1012C16D106E0032C68
+:1033600010D07F2C11D112E0002011E080790324CD
+:10337000B4EB901F09D10A700BE08079B2EB901F7B
+:1033800003D1F8E780798009F5D0184610BDFF20F9
+:103390000870002010BD224991F82E2042B191F80A
+:1033A0002F10022909D0032909D043F202207047C7
+:1033B00001461B48253001F092BD032100E00121A8
+:1033C00001700020704738B50C460546694601F08B
+:1033D00086FD00280DD19DF80010207861F347008C
+:1033E000207055F8010FC4F80100A888A4F8050062
+:1033F000002038BD38B51378B0B1022814D0FF28AA
+:103400001BD008A46D46246800944C7905EB9414F5
+:10341000247864F34703137003280AD010E00000F7
+:10342000D80100200302FF0123F0FE0313700228DD
+:10343000F2D1D8B240F0010005E043F0FE00107078
+:10344000107820F0010010700868C2F80100888828
+:10345000A2F8050038BD02210DF006BC38B50C46B7
+:103460000978222901D2082038BDADF800008DF876
+:10347000022068460BF079F905F0FCFD050003D148
+:1034800021212046FFF746FE284638BD1CB5002006
+:103490008DF80000CDF80100ADF80500FE4890F869
+:1034A0002E00022801D0012000E000208DF8070046
+:1034B00068460BF092FB002800D0FFDF1CBD002205
+:1034C0000A80437892B263F345120A8043785B081E
+:1034D00063F386120A8000780C282BD2DFE800F014
+:1034E0002A06090E1116191C1F220C2742F0110082
+:1034F00009E042F01D0008800020704742F01100F2
+:1035000012E042F0100040F00200F4E742F0100038
+:10351000F1E742F00100EEE742F0010004E042F082
+:103520000200E8E742F0020040F00400E3E742F066
+:103530000400E0E7072070472DE9FF478AB0002527
+:10354000BDF82C6082461C4691468DF81C507007D1
+:1035500003D5606811F034F868B9CF4F4FF0010817
+:1035600097F82E0058B197F82F00022807D160680D
+:1035700011F073F818B110200EB0BDE8F0873007D5
+:1035800002D5A08980283DD8700705D4B9F1000F75
+:1035900002D097F8240098B3E07DC0F300108DF8B6
+:1035A0001B00627D072003215AB3012A2CD0022A76
+:1035B000E2D0042AE0D18DF81710F00627D4A27DBE
+:1035C000072022B3012A22D0022A23D0042AD3D1F1
+:1035D0008DF819108DF81590606810B307A9FFF7E2
+:1035E000B1FE0028C8D19DF81C00FF2816D06068E5
+:1035F00050F8011FCDF80F108088ADF8130014E0CB
+:1036000000E001E00720B7E78DF81780D5E78DF8D7
+:103610001980DFE702208DF81900DBE743F2022072
+:10362000AAE7CDF80F50ADF81350E07B40B9207CED
+:1036300030B9607C20B9A07C10B9E07CC00601D014
+:10364000062099E78DF800A0BDF82C00ADF8020027
+:10365000A0680190A068029004F10F0001F033FC13
+:103660008DF80C000DF10D00FFF795FE00B1FFDFA6
+:103670009DF81C008DF80E008DF816508DF818502E
+:10368000E07D08A900F00F008DF81A0068460CF0E4
+:10369000F8F805F0EFFC6FE7F0B59DB000228DF86B
+:1036A00068208DF858208DF8602005468DF86C2034
+:1036B000129213921492159219B10FC912AC84E8A8
+:1036C0000F00754CA078052801D004280CD1129861
+:1036D0006168884200D120B91498E168884203D11A
+:1036E00010B108201DB0F0BD1F26334618AA1AA934
+:1036F00012A8FFF7BCFD0028F4D133461BAA16A977
+:1037000014A8FFF7B4FD0028ECD19DF85800C007BD
+:1037100001D00A20E6E7A08A410708D4A17D31B193
+:103720009DF86010890702D043F20120DAE79DF886
+:103730006010C90709D0400707D4208818B144F2A7
+:103740005061884201D90720CCE78DF8005003264C
+:103750008DF8016001278DF80270BDF84C208DF8BE
+:10376000032001A8129921F0F5F968460CF0F0F851
+:1037700005F080FC0028B5D18DF824508DF8256027
+:103780008DF82670BDF854208DF827200AA81499CA
+:1037900021F0E0F909A80CF028F905F06BFC0028ED
+:1037A000A0D112AD241D95E80F0084E80F00002081
+:1037B00098E770B586B00D46040005D010F04DFFB7
+:1037C00020B1102006B070BD0820FBE72078C107AB
+:1037D000A98802D0FF2902D303E01F2901D20920C2
+:1037E000F0E7800761D4FFF74FFC38B12078C0F3D1
+:1037F000C101012904D0032902D005E01320E1E72B
+:10380000254991F8241041B1C0074FF000054FF051
+:10381000010604D08DF80F6003E00720D2E78DF891
+:103820000F506846FFF7B7FD00B1FFDF2078C0F307
+:10383000C1008DF801008DF80250607808B98DF84C
+:1038400002606078C00705D09DF8020040F00100DA
+:103850008DF802006078800705D59DF8020040F0E1
+:1038600002008DF802006078400705D59DF802003F
+:1038700040F004008DF802002078C0F380008DF83D
+:1038800003006088ADF80600A088ADF80A00207A31
+:1038900058B9607A48B901E0D8010020A07A20B96F
+:1038A000E07A10B9207BC00601D006208AE704F137
+:1038B000080001F008FB8DF80E0068460BF090FA46
+:1038C00005F0D8FB00288BD18DF810608DF81150D1
+:1038D000ADF81250ADF8145004A80BF0CBFA05F077
+:1038E000C9FB00288BD1E08864280AD248B10120A6
+:1038F00001F0FFFA002891D12078C00705D01520EB
+:1039000004E06421B0FBF1F0F2E71320FFF7A6FB1F
+:10391000002057E72DE9FF470220FF4E8DF80400F5
+:103920000027708EADF80600B84643F202094CE05D
+:1039300001A80DF000F9050006D0708EA8B3A6F816
+:103940003280ADF806803EE0039CA07F01072DD5B4
+:1039500004F124000090A28EBDF80800214604F175
+:10396000360301F056FC050005D04D452AD0112D37
+:103970003CD0FFDF3AE0A07F20F00801E07F420862
+:1039800062F3C711A177810861F30000E07794F832
+:10399000210000F01F0084F820002078282826D17C
+:1039A00029212046FFF7B6FB21E014E040070AD5A5
+:1039B000BDF8080004F10E0101F0A9FA05000DD0D0
+:1039C0004D4510D100257F1CFFB202200DF0F4F808
+:1039D000401CB842ACD8052D11D008E0A07F20F0E3
+:1039E0000400A07703E0112D00D0FFDF0025BDF813
+:1039F00006007086052D04D0284604B0BDE5A6F863
+:103A000032800020F9E770B50646FFF724FD054631
+:103A100005F004FD040000D1FFDF6680207820F06F
+:103A20000F00801C20F0F000203020700620207253
+:103A300095F83E006072BDE8704005F0F2BC2DE9DB
+:103A4000F04786B0040000D1FFDF2078B24D20F0AF
+:103A50000F00801C20F0F00070302070606801784A
+:103A6000491F1B2933D2DFE801F0FE32323255FD07
+:103A7000320EFDFD42FC32323278FCFCFB32323237
+:103A8000FCFCFAF9FC00C6883046FFF7E4FC05466A
+:103A9000304607F0A9F8E0B16068007A85F83E008A
+:103AA00021212846FFF736FB3046FEF7CCFA304698
+:103AB00003F018FE3146012010F036FDA87F20F0FB
+:103AC0001000A877FFF726FF002800D0FFDF06B020
+:103AD00053E5207820F0F00020302070062020727E
+:103AE00066806068007A607205F09BFCD8E7C58844
+:103AF0002846FFF7B0FC00B9FFDF606800790128B5
+:103B000000D0FFDF6068017A06B02846BDE8F047C4
+:103B100007F046BCC6883046FFF79DFC050000D183
+:103B2000FFDF05F07EFC606831460089288160680F
+:103B30004089688160688089A881012010F0F4FCC8
+:103B40000020A875A87F00F003000228BFD1FFF76E
+:103B5000E1FE0028BBD0FFDFB9E70079022811D0D1
+:103B600000B1FFDF05F05DFC6668B6F806A0307AAC
+:103B7000361D01280CD0687E814605F0E7F9070064
+:103B800009D107E006B00220BDE8F047FFF717BBF8
+:103B9000E878F1E7FFDF0022022150460DF05BF8E4
+:103BA000040000D1FFDF22212046FFF7B3FA30796D
+:103BB000012800D00220A17F804668F30101A1778F
+:103BC000308B2081708B6081B08BA08184F8229033
+:103BD0008DF80880B8680090F86801906A46032163
+:103BE00050460DF038F800B9FFDFB888ADF8100086
+:103BF000B8788DF8120004AA052150460DF02BF874
+:103C000000B9FFDFB888ADF80C00F8788DF80E0029
+:103C100003AA042150460DF01EF800B9FFDF06216B
+:103C200006F1120001F091F938B37079800700D5E0
+:103C3000FFDF7179E07D61F34700E075D6F806009B
+:103C4000A0617089A083062106F10C0001F07DF9C6
+:103C5000E8B195F825004108607805E032E02AE0F7
+:103C600047E03FE021E035E061F347006070D5F8C0
+:103C70002600C4F80200688D12E0E07D20F0FE000E
+:103C8000801CE075D6F81200A061F08ADAE760784F
+:103C900020F0FE00801C6070F068C4F80200308ADA
+:103CA000E0804046FFF78BFA11E706B02046BDE8FA
+:103CB000F04701F037BD05F0B4FB15F8300F40F0C8
+:103CC000020005E005F0ADFB15F8300F40F00400F0
+:103CD0002870FCE6287E132809D01528E4D1162088
+:103CE000FFF7BCF906B0BDE8F04705F09ABB142019
+:103CF000F6E7A978052909D00429D5D105F091FB6B
+:103D0000022006B0BDE8F047FFF790B9007900281F
+:103D1000CAD0E87802E00000D801002001F0BAF82B
+:103D200005F07FFB0320ECE72DE9F05F0546007806
+:103D30004FF000080009DFF820A891460C464646DF
+:103D400001287AD001274FF0020C4FF6FF730228AA
+:103D500074D007280BD00A2871D0FFDFA9F80060C3
+:103D600014B1A4F8008066800020BDE8F09F696867
+:103D700004F108000A78172A70D010DC4FF0000B0D
+:103D8000142A31D006DC052A6DD0092A0FD0102A5A
+:103D90007ED11FE0152A7CD0162AF9D1F0E01B3A1B
+:103DA000052A75D2DFE802F009C5FDDAFC00C888F3
+:103DB0004FF012081026214675E14FF01C080A2624
+:103DC000D4B38888A0806868807920726868C079D8
+:103DD0006072C3E74FF01B0814266CB303202072F7
+:103DE00068688088A080B9E70A793C2AB6D00D1DA2
+:103DF0004FF010082C26FCB16988A180298B6182C4
+:103E0000298B2182698BA182A98BE1826B79024681
+:103E1000A91D1846FFF7EEFA2879012810D084F87A
+:103E20000FC0FF202076C4F81CB0C4F820B0C4F83E
+:103E300024B0C4F828B091E712E013E13BE135E18A
+:103E4000E7730AF1040084F818B090E80E00DAF87D
+:103E50001000C4E90930C4E907127FE7A8E002E0D6
+:103E6000A9F8006080E72C264FF01D08002CF7D041
+:103E70000546A380887B2A880F1D60F300022A80F4
+:103E8000887B400860F341022A80887B800801E03B
+:103E9000E6E0ADE060F382022A80887BB91CC008AE
+:103EA00060F3C3022A80B87A0011401C60F3041248
+:103EB00002F07F0028807878AA1CFFF79BFA387DF3
+:103EC00005F1090207F11501FFF794FA387B01F0BB
+:103ED0004BF82874787B01F047F86874F87EA87472
+:103EE000787AE87497F83B002875B87B6875A5F870
+:103EF00016B0DAF81C00A861397ABAF820008842B6
+:103F000001D2014610E0B87AC0F3411002280BD06C
+:103F1000012809D0288820F060002880A1840A4662
+:103F200007F11C01A86998E0288820F06000403063
+:103F3000F3E711264FF02008002C91D0A380686889
+:103F400004F10A02007920726868007B6072696877
+:103F50008B1D48791946FFF74DFAFFE60A264FF008
+:103F60002108002CE9D08888A080686880792072B8
+:103F70006868C07960729AF8301021F004018BE013
+:103F80000B264FF02208002CD7D0C888A080686884
+:103F9000007920726868007A00F0E6FF607201E044
+:103FA00052E039E06868407A00F0DEFFA072D5E6A2
+:103FB0001C264FF02608002CBFD0A38068684079EB
+:103FC00060726868007AA0720AF1040090E80E003E
+:103FD000DAF81000C4E90530C4E903126868007912
+:103FE0003C2803D043287DD0FFDFB7E62772B5E633
+:103FF00010264FF02408002C9FD08888A080686885
+:10400000807920816868807A608168680089A081F1
+:1040100068688089E081A1E610264FF02308002C13
+:104020008BD08888A0806868C088208168680089F3
+:10403000608168684089A08168688089E0819AF819
+:10404000301021F0020127E030264FF02508002C27
+:1040500088D0A38069682822496820F07BFD7DE62E
+:104060004A4677E0287A012803D0022817D0FFDFDC
+:1040700074E610264FF01F08002C85D06888A080B9
+:10408000A8892081E8896081288AA081688AE081E6
+:104090009AF8301021F001018AF830105EE64FF0F6
+:1040A00012081026688800F03DFF57E62846BDE854
+:1040B000F05F01F0C1BC287A07284DD2DFE800F09C
+:1040C0004C38384A4A4A040009264FF01108002C9F
+:1040D00092D06F883846FFF7BEF990F822A0A780EB
+:1040E000687A00E02DE02072042138460CF0CEFD05
+:1040F000052138460CF0CAFD002138460CF0C6FDFB
+:10410000012138460CF0C2FD032138460CF0BEFDFB
+:10411000022138460CF0BAFD062138460CF0B6FDF7
+:10412000072138460CF0B2FD504600F0B3FE15E60C
+:1041300014264FF01B08002C8AD0A380287A01286F
+:1041400002D084F808C009E62772DAE90710C4E94A
+:10415000031003E62146A9E7FFDFFFE570B5FE4D3A
+:10416000287E122801D0082070BD0BF094F904F0CD
+:1041700081FF040002D1687E00F08CFE0021052042
+:1041800010F0D2F9204670BD1CB5F348007E13280C
+:1041900001D208201CBD00208DF8000068460AF0FE
+:1041A00069FE04F067FF0028F4D10021052010F01B
+:1041B000BBF91120FEF752FF00201CBD70B501288D
+:1041C00005D0052825D0062800D0FFDF70BD8DB2B0
+:1041D0002846FFF740F9040000D1FFDF20782128AE
+:1041E000F4D005F01BF968B1017821F00F01891CAA
+:1041F00021F0F00110310170022101724580002090
+:10420000A07528E021462846BDE870401322FFF73C
+:1042100025B9D148047EA4F1120005281FD2DFE899
+:1042200000F0060303030300FFF7AEFF01E0FFF712
+:1042300095FF0028CAD105F0F1F80028C6D0017812
+:1042400021F00F01891C21F0F00120310170132CA5
+:1042500007D002210172BDE8704005F0E2B8FFDF2F
+:1042600070BD0121F6E72DE9F04116460C008046AD
+:1042700000D1FFDF307820F00F00801C20F0F0002C
+:10428000103030702078012804D0022818D0FFDFC9
+:10429000BDE8F0814046FFF7DEF8050000D1FFDF02
+:1042A0000320A87505F0BDF894E80F00083686E8ED
+:1042B0000F00A94810F8301F41F001010170E7E735
+:1042C0004046FFF7C8F8050000D1FFDFA1884FF690
+:1042D000FF700027814202D1E288824203D08142EE
+:1042E00001D1E08840B105F09CF894E80F00083651
+:1042F00086E80F00AF75CBE7A87D0128C8D17823E9
+:104300000022414610F066F80220A875C0E738B5D3
+:1043100005460C46084610F053F918BB203D062D03
+:104320004AD2DFE805F0031B373C4230002106206B
+:1043300010F0D0F808B1112038BDA01C0BF07EF9A8
+:1043400004F098FE050038D100220823114606200B
+:1043500010F040F8062830D0FFDF2EE0606810F043
+:1043600073F908B1102038BD618820886A460BF0C7
+:104370003BFD04F07FFE05001FD16068E8B1BDF889
+:104380000010018019E0A07800F0010120880BF0F6
+:1043900061FD0EE0206801F0FDFD05460DE020788E
+:1043A00000F001000AF066F903E0618820880BF054
+:1043B000A0FC04F05FFEF0E70725284638BD70B585
+:1043C00005460C46084610F021F908B1102070BDD2
+:1043D000202D07D0212D0DD0222D0BD0252D09D039
+:1043E000072070BD2088A11C0AF039FABDE8704092
+:1043F00004F040BE062070BD57482530704708B510
+:104400003421554820F047FC0120FEF70FFE112013
+:10441000FEF724FE50496846263104F095FF4E48C9
+:104420009DF8002010F8251F62F3470121F00101DB
+:104430000170002141724FF46171A0F80710022150
+:104440008172FEF755FE00B1FFDFFCF78FFF01F030
+:1044500034F908BD10B50C464021204620F0F9FB88
+:10446000A07F20F00300A077202020700020A075FE
+:1044700084F8230010BD70472DE9FC41074610F079
+:104480009FF810B11020BDE8FC81334E06F12501E4
+:10449000D6F825000090B6F82950ADF8045096F8EB
+:1044A0002B408DF806403846FEF78DFF0028EAD1F4
+:1044B000FEF71EFE0028E6D0009946F8251FB580BD
+:1044C000B471E0E710B5044610F0A0F808B1102070
+:1044D00010BD21482049224690F825002631400889
+:1044E000FEF788FF002010BDFEB50D4604004FF01A
+:1044F000000712D00822FEF79FFE002812D10026E6
+:1045000009E000BF54F826006946FEF71BFF0028AB
+:1045100008D1761CF6B2AE42F4D309F0AEFF10B16A
+:1045200043F20320FEBD0C4E86F8247024B300270E
+:104530001EE000BF54F8270002A9FEF703FF00B1F8
+:10454000FFDF9DF808008DF8000054F8270050F8B0
+:10455000011FCDF8011001E0D80100208088ADF8DE
+:104560000500684609F0D3FF00B1FFDF7F1CFFB2F2
+:10457000AF42DFD386F824500020FEBD2DE9F0477E
+:104580008AB01546894604001ED00F4608222946E7
+:10459000FEF752FE002810D1002613E054F8260042
+:1045A0006946103000F09BFC002806D147B157F84F
+:1045B000260010F005F818B110200AB0BDE8F08709
+:1045C000761CF6B2AE42E9D30026A5F101081BE045
+:1045D00006F1010A0AF0FF0712E000BF54F82600B6
+:1045E000017C4A0854F827100B7CB2EB530F05D11D
+:1045F00006221130113120F081FA58B17F1CFFB230
+:10460000AF42EBD30AF0FF064645E1DB4E4624B14C
+:10461000012003E043F20520CFE7002009F0A8FFC6
+:1046200010B909F0B9FF10B143F20420C5E75CB33B
+:1046300000270DF1170825E054F8270069461030CF
+:1046400000F04DFC00B1FFDF54F82700102250F8B5
+:10465000111FCDF801108088ADF8050054F827101F
+:104660000DF1070020F076FA96B156F827101022C7
+:10467000404620F06FFA684609F022FF00B1FFDFE4
+:104680007F1CFFB2AF42D7D3FEF700FF002094E7B4
+:10469000404601F073FCEEE730B585B004460FF0FC
+:1046A0008FFF18B960680FF0D8FF10B1102005B067
+:1046B00030BD60884AF2B811884206D82078FB4D98
+:1046C00028B1012806D0022804D00720EFE7FEF722
+:1046D0000FFD18E06078022804D0032802D043F2CE
+:1046E0000220E4E785F82F00C1B200200090ADF869
+:1046F000040002292CD0032927D0FFDF684609F0E7
+:10470000EDFF04F0B7FC0028D1D1606801F029FC6E
+:10471000207858B101208DF800000DF1010001F062
+:104720002DFC68460BF0F5FB00B1FFDF207885F823
+:104730002E00FEF7ABFE608860B1A88580B209F05C
+:104740000FFF00B1FFDF0020B1E78DF80500D5E7CE
+:104750004020FAE74FF46170EFE710B504460FF020
+:1047600055FF20B9606838B10FF06EFF08B1102016
+:1047700010BD606801F002FCCC4830F82C1F61804D
+:10478000C178617080782070002010BD2DE9F84359
+:104790001446894606460FF039FFA0B948460FF087
+:1047A0005CFF80B920460FF058FF60B9BF4DA87874
+:1047B000012800D13CB13178FF2906D049B143F23C
+:1047C0000400BDE8F8831020FBE7012801D0042095
+:1047D000F7E74FF00008A4B3052811D004280FD044
+:1047E00069462046FEF76BFE0028EAD1207D48B1DD
+:1047F000012809D0022809D0032809D00720E0E7C2
+:104800000820DEE7424604E0012202E0022200E046
+:1048100003222346174600200099FEF78DFE00284C
+:10482000CFD1A0892880A07BE875BDF80000A882C0
+:10483000AF75BDF80000000701D5A08988B1A08937
+:10484000288049460020FEF727FF0028B9D1A87824
+:1048500005280BD0042809D0287DC00703D00320E9
+:1048600002E08020ECE70220FEF7E0FB86F8008003
+:104870000020A6E77CB58D4C05460E46A0780228A0
+:1048800003D0032801D008207CBD15B143F20400F9
+:104890007CBD07200CF098F910B9A078032806D049
+:1048A000FEF7F2FB28B1A078032804D009E012201B
+:1048B0007CBD13207CBD304600F0CBFA0028F9D136
+:1048C000E67001208DF800008DF801008DF802508F
+:1048D0002088ADF80400E07D8DF8060068460BF0F6
+:1048E000C6F904F0C7FB0028E4D1A078032805D05E
+:1048F0005FF00400FEF79AFB00207CBDE07800F03A
+:10490000B8FA0520F6E71CB510B143F204001CBD4F
+:10491000664CA078042803D0052801D008201CBDCF
+:1049200000208DF8000001218DF801108DF80200A3
+:1049300068460BF09CF904F09DFB0028EFD1A078AD
+:10494000052805D05FF00200FEF770FB00201CBDBB
+:10495000E07800F09FFA0320F6E72DE9FC4180465D
+:104960000E46032508460FF078FE002866D1404623
+:10497000FEF771FD040004D02078222804D208201C
+:1049800081E543F202007EE5A07F00F003073EB11F
+:10499000012F0CD000203146FEF729FC0500EFD195
+:1049A000012F06D0022F1AD0FFDF28466BE5012029
+:1049B000F1E7A07D3146022801D011B107E01120B6
+:1049C00061E56846FCF7DFFD0028D9D1694640461D
+:1049D00006F0A9FC0500E8D10120A075E5E7A07D5F
+:1049E000032804D1314890F83000C00701D02EB31D
+:1049F0000EE026B1A07F40071ED4002100E0012177
+:104A0000404606F0B0FC0500CFD1A075002ECCD0FA
+:104A10003146404600F07BFA05461128C5D1A07FFB
+:104A20004107C2D4316844F80E1F7168616040F0DC
+:104A3000040020740025B8E71125B6E7102022E510
+:104A400070B50C460546FEF706FD010005D022466E
+:104A50002846BDE87040FEF701BD43F2020070BD7C
+:104A600010B5012807D1114B9B78012B00D011B153
+:104A700043F2040010BD09F0B6FDBDE8104004F09B
+:104A8000F9BA012300F010BA00231A46194600F0C3
+:104A90000BBA70B506460C4608460FF091FD18B9E2
+:104AA00020680FF0B3FD18B1102070BDD8010020B0
+:104AB000F64D2A7E112A04D0132A00D33EB10820D5
+:104AC000F3E721463046FEF774FE60B1EDE70920BA
+:104AD000132A0DD0142A0BD0A188FF29E5D3152065
+:104AE000FEF7BCFA0020D4E90012C5E90712DCE7A2
+:104AF000A1881F29D9D31320F2E72DE9F047DFF869
+:104B00008C93804690B099F818009A4615460C464A
+:104B1000132803D3FFF738FB002836D120460FF0C7
+:104B20004FFD88BB28460FF04BFD68BB20784FF047
+:104B30000107C0074FF0000602D08DF83A7001E07F
+:104B40008DF83A602078C0F3C1008DF800006178DC
+:104B50000720E1B101291AD0022916D0042914D165
+:104B600004208DF809006088ADF80A00A088ADF82F
+:104B700010002078C0F3C100012825D0032823D0DD
+:104B800040460FF01DFD28B1102010B016E58DF83D
+:104B90000970E8E798F80000400808D0012809D01B
+:104BA000022807D0032805D043F20220EDE78DF854
+:104BB000026001E08DF80270404650F8011FCDF808
+:104BC00003108088ADF807000DF10100FEF7E3FB4C
+:104BD00008B10320D9E72888ADF816006888ADF839
+:104BE0001C00A888ADF82200E888ADF82800ADF8D0
+:104BF0002E60ADF8346068460AF057FAE8B999F8C3
+:104C000018004D46112801D00820BEE706200BF001
+:104C1000DBFF38B12078C0F3C100012804D003289D
+:104C200002D004E01220B0E795F8240028B1FEF786
+:104C30002BFA022803D21320A7E70720A5E7504646
+:104C400000F007F90028A0D185F819A068460AF0FD
+:104C50001FFC04F00FFA002897D1687E00F009F9D4
+:104C6000E08864280BD250B15FF0010000F041F9F8
+:104C700004008AD11220FEF7F1F9204685E764216D
+:104C8000B0FBF1F0F2E770B5064615460C46084653
+:104C90000FF0BCFC18B928460FF0B8FC08B1102082
+:104CA00003E72A46214630460BF081F804F0E2F98A
+:104CB0000028F5D121787F29F2D10520F5E67CB5D1
+:104CC00005460C4608460FF07BFC08B110207CBD61
+:104CD0002846FEF7C0FB20B10078222804D2082025
+:104CE0007CBD43F202007CBD684890F8300040076C
+:104CF00001D511207CBD2078C00802D16078C008A1
+:104D000001D007207CBDADF8005020788DF802005E
+:104D100060788DF803000220ADF8040068460AF0C0
+:104D200055F804F0A7F97CBD70B586B014460D4661
+:104D30000646FEF790FB28B10078222805D208200D
+:104D400006B0B2E643F20200FAE728460FF085FC0F
+:104D500020B944B120460FF077FC08B11020EFE7EE
+:104D600000202060A080494890F83000800701D5DD
+:104D70001120E5E703A9304609F0F7FD18B100BF9F
+:104D800004F078F9DCE7ADF80060BDF81400ADF888
+:104D90000200BDF81600ADF80400BDF81000BDF823
+:104DA0001210ADF80600ADF808107DB1298809B1E0
+:104DB000ADF80610698809B1ADF80210A98809B1EB
+:104DC000ADF80810E98809B1ADF80410DCB1BDF800
+:104DD0000610814201D9081A2080BDF80210BDF8E2
+:104DE0001400814201D9081A6080BDF80800BDF89E
+:104DF0000410BDF816200144BDF812001044814291
+:104E000001D9081AA080684609F0E6FEB8E71CB58B
+:104E10001F490968CDE9001068460AF048F904F016
+:104E200029F91CBD1CB500200090019068460AF0CD
+:104E30003EF904F01FF91CBD108008885080488896
+:104E40009080C88810818888D0800020508190810F
+:104E5000704710B5044604F079F830B1407830B1AD
+:104E6000204604F082FB002010BD052010BD12205A
+:104E700010BD10B504F06AF8040000D1FFDF6078BF
+:104E800000B9FFDF6078401E607010BDD8010020BF
+:104E90004050020010B504F059F8040000D1FFDFC3
+:104EA0006078401C607010BD1CB5ADF800008DF836
+:104EB00002308DF803108DF8042068460AF03CFF9C
+:104EC00004F0D8F81CBD0CB52FA2D2E90012CDE930
+:104ED00000120079694601EB501000780CBD027891
+:104EE000520804D0012A02D043F202207047FEF794
+:104EF00029BA10B548B183000022114605200FF0F1
+:104F000069FA052801D0032010BD002010BD1FB58F
+:104F10006A46FFF791FF68460AF01DFB04F0AAF805
+:104F200004B010BD70B50C0006460DD0FEF793FA24
+:104F3000050000D1FFDFA6802889208128896081B3
+:104F40006889A081A889E081AFE510B500231A46E1
+:104F500003E0845C2343521CD2B28A42F9D30BB1E2
+:104F6000002010BD012010BD00B540B1012805D0C2
+:104F7000022803D0032804D0FFDF002000BDFF205B
+:104F800000BD042000BD0000070605040302010067
+:104F900010B504460FF014FB08B1102010BD2078A6
+:104FA000C0F30210042807D86078072804D3A1783A
+:104FB000102901D8814201D2072010BDE0784107B5
+:104FC00006D421794A0703D4000701D4080701D584
+:104FD000062010BD002010BD10B513785C08837F3B
+:104FE00064F3C713837713789C08C37F64F30003CB
+:104FF000C3771078C309487863F341004870137889
+:105000001C090B7864F347130B701378DB0863F308
+:10501000000048705078487110BD10B5C4780B7806
+:1050200064F300030B70C478640864F341030B70ED
+:10503000C478A40864F382030B70C478E40864F3B2
+:10504000C3030B700379117863F3000111700379C6
+:105050005B0863F34101117003799B0863F38201DC
+:1050600011700079C00860F3C301117010BD70B5F4
+:1050700014460D46064604F0D1F980B10178182295
+:1050800021F00F01891C21F0F001A03100F8081B6C
+:1050900021461FF0A4FDBDE8704004F0C2B92946C6
+:1050A0003046BDE870401322FEF7D8B92DE9F0472D
+:1050B000064608A8894690E830041F469046142109
+:1050C00028461FF0E8FD0021CAF80010B8F1000FD3
+:1050D00003D0B9F1000F03D114E03878C00711D024
+:1050E00020680FF093FAC0BBB8F1000F07D1206819
+:1050F000123028602068143068602068A860216839
+:10510000CAF800103878800724D560680FF09CFA40
+:1051100018BBB9F1000F21D0FFF76EF90168C6F88E
+:1051200068118188A6F86C11807986F86E0101F00B
+:1051300002FDF94FEF60626862B196F8680106F20D
+:10514000691140081032FEF755F91022394660689F
+:105150001FF000FD0020BDE8F08706E0606820B188
+:10516000E8606068C6F86401F4E71020F3E730B542
+:10517000054608780C4620F00F00401C20F0F00196
+:10518000103121700020607095F8230030B10428A0
+:105190000FD0052811D0062814D0FFDF2078012178
+:1051A000B1EB101F04D295F8200000F01F006070D2
+:1051B00030BD21F0F000203002E021F0F00030306E
+:1051C0002070EBE721F0F0004030F9E7F0B591B046
+:1051D000022715460C4606463A46ADF808700921E6
+:1051E00003AB04F07AFF0490002810D004208DF85F
+:1051F00004008DF80170E034099605948DF818507C
+:105200000AA968460DF022FA00B1FFDF012011B0B3
+:10521000F0BD10B588B00C460A99ADF80000C3B1D6
+:105220001868CDF802005868CDF80600ADF80A20DD
+:10523000102203A81FF08EFC68460AF02FFA03F034
+:1052400019FF002803D1A17F41F01001A17708B018
+:1052500010BD0020CDF80200E6E72DE9F84F064624
+:10526000808A0D4680B28246FEF7F5F80446307813
+:10527000DFF8A48200274FF00509A8F120080F28C5
+:1052800070D2DFE800F06FF23708387D8CC8F1F09B
+:10529000EFF35FF3F300A07F00F00300022809D0D2
+:1052A0005FF0000080F0010150460BF0DDFC0500CE
+:1052B00003D101E00120F5E7FFDF98F85C10C90792
+:1052C00002D0D8F860000BE0032105F11D000EF0BC
+:1052D00052FED5F81D009149B0FBF1F201FB12001E
+:1052E000C5F81D0070686867B068A8672078252831
+:1052F00000D0FFDFCAE0A07F00F00300022809D041
+:105300005FF0000080F0010150460BF0ADFC06009C
+:1053100003D101E00120F5E7FFDF3078810702D5F6
+:105320002178252904D040F001003070BDE8F88FC5
+:1053300002202870307F287106F11D002D36C5E946
+:105340000206F3E7A07F00F00300022808D0002047
+:1053500080F0010150460BF087FC040004D102E00C
+:105360000120F5E7A7E1FFDF2078C10604D507207B
+:1053700028703D346C60D9E740F008002070D5E714
+:10538000E07F000700D5FFDF307CB28800F001032A
+:1053900001B05046BDE8F04F092105F027BD04B922
+:1053A000FFDF716821B1102204F124001FF0D2FB4D
+:1053B00028212046FDF7AEFEA07F00F00300022862
+:1053C0000ED104F12400002300901A4621465046D5
+:1053D000FFF71FFF112807D029212046FDF79AFE6D
+:1053E000307A84F82000A1E7A07F000700D5FFDF16
+:1053F00014F81E0F40F008002070E782A761E761F3
+:10540000C109607861F34100014660F38201617077
+:10541000307AE0708AE7A07F00F00300022809D00C
+:105420005FF0000080F0010150460BF01DFC04000D
+:1054300003D101E00120F5E7FFDF022104F185003F
+:105440000EF099FD0420287004F5B4706860B4F87B
+:1054500085002882304810387C346C61C5E90280B0
+:1054600064E703E024E15BE02DE015E0A07F00F0BD
+:105470000300022807D0002080F0010150460BF005
+:10548000F3FB18B901E00120F6E7FFDF32462146C1
+:105490005046BDE8F84FEAE504B9FFDF207821283F
+:1054A000A1D93079012803D1E07F40F00800E077EE
+:1054B000324621465046FFF7DAFD2046BDE8F84F58
+:1054C0002321FDF727BE3279AA8005F108030921BF
+:1054D000504604F002FEE86010B185F8009025E720
+:1054E000A07F00F00300022808D0002080F0010116
+:1054F00050460BF0B9FB040003D101E00120F5E7B1
+:10550000FFDF04F1620102231022081F0BF033FABF
+:1055100007703179417009E73802002040420F00DE
+:10552000A07F00F00300022808D0002080F00101D5
+:1055300050460BF099FB050003D101E00120F5E78F
+:10554000FFDF95F8840000F0030001287AD1A07FE6
+:1055500000F00307E07F10F0010602D0022F04D113
+:1055600033E095F8A000C0072BD0D5F8601121B327
+:1055700095F88320087C62F387000874A17FCA092C
+:10558000D5F8601162F341000874D5F8601166F334
+:1055900000000874AEB1D5F86001102204F12401B6
+:1055A00088351FF0D7FA287E40F001002876287849
+:1055B00020F0010005F8880900E016B1022F04D0A0
+:1055C0002DE095F88800C00727D0D5F85C1121B3ED
+:1055D00095F88320087C62F387000874A17FCA09CC
+:1055E000D5F85C1162F341000874D5F85C1166F3DC
+:1055F000000008748EB1D5F85C01102204F124017A
+:1056000088351FF0A7FA287840F0010005F8180B3C
+:10561000287820F0010005F8A009022F44D00020CE
+:1056200000EB400005EBC00090F88800800709D52A
+:1056300095F87C00D5F86421400805F17D01103211
+:10564000FDF7D8FE8DF8009095F884006A4600F0CA
+:1056500003008DF8010095F888108DF8021095F878
+:10566000A0008DF803002146504601F04DFA207845
+:10567000252805D0212807D0FFDF2078222803D94C
+:1056800022212046FDF746FDA07F00F003000228FE
+:105690000CD0002080F0010150460BF0F7FA0028F2
+:1056A0003FF44FAEFFDF41E60120B9E70120F1E70B
+:1056B000706847703AE6FFDF38E670B5FE4C0025AB
+:1056C00084F85C5025660CF08EFF04F11001204632
+:1056D00003F060FE84F8305070BD70B50D46FDF7E4
+:1056E000BAFE040000D1FFDF4FF4B87128461FF066
+:1056F000D2FA04F124002861A07F00F00300022800
+:1057000008D0012105F1E0000CF06EFF002800D068
+:10571000FFDF70BD0221F5E70A46014602F1E00015
+:105720000CF082BF70B50546406886B001780A2942
+:1057300006D00D2933D00E292FD0FFDF06B070BD63
+:1057400086883046FDF787FE040000D1FFDF207811
+:105750002128F3D028281BD1686802210E3001F0DF
+:10576000C8F9A8B168680821801D01F0C2F978B1B4
+:1057700004F1240130460AF07CFA03F07BFC00B10E
+:10578000FFDF06B02046BDE870402921FDF7C2BC0E
+:1057900006B0BDE8704003F044BE012101726868A4
+:1057A000C6883046FDF757FE040000D1FFDFA07F1A
+:1057B00000F00301022902D120F01000A077207828
+:1057C00021280AD06868017A09B1007980B1A07FE8
+:1057D00000F00300022862D0FFDFA07F00F003008A
+:1057E0000228ABD1FEF796F80028A7D0FFDFA5E787
+:1057F00003F017FEA17F08062BD5E07FC00705D078
+:1058000094F8200000F01F00102820D05FF0050061
+:1058100084F82300207829281DD02428DDD13146A2
+:1058200004200EF081FE22212046FDF773FCA07FAC
+:1058300000F00300022830D05FF0000080F001018A
+:1058400030460BF023FA0028C7D0FFDFC5E706205B
+:10585000DEE70420DCE701F00300022808D0002086
+:1058600080F0010130460BF0FFF9050003D101E0A3
+:105870000120F5E7FFDF25212046FDF74BFC032043
+:105880008DF80000694605F1E0000CF0C4FE022826
+:10589000A3D00028A1D0FFDF9FE70120CEE703F0CF
+:1058A000C0FD9AE72DE9F04387B099461646884631
+:1058B0000746FDF7D0FD04004BD02078222848D3BE
+:1058C000232846D0E07F000743D4A07F00F00300E8
+:1058D000022809D05FF0000080F0010138460BF08B
+:1058E000C3F9050002D00CE00120F5E7A07F00F02D
+:1058F0000300022805D00121002238460BF0ABF945
+:1059000005466946284601F026F9009800B9FFDFF0
+:1059100045B10098E03505612078222806D024287A
+:1059200004D007E000990020086103E0252120460B
+:10593000FDF7F0FB0098012141704762868001A9C4
+:10594000C0E902890CF082FE022802D0002800D0B3
+:10595000FFDF07B0BDE8F08370B586B00546FDF700
+:105960007AFD017822291ED9807F00F003000228E9
+:1059700008D0002080F0010128460BF075F90400E2
+:105980002FD101E00120F5E7FFDF2AE0B4F85E0047
+:1059900004F1620630440178427829B12146284654
+:1059A000FFF714FCB0B9C9E6ADF804200921284678
+:1059B00002AB04F092FB03900028F4D005208DF890
+:1059C0000000694604F1E0000CF025FE022801D039
+:1059D00000B1FFDF02231022314604F15E000BF01C
+:1059E00000F8B4F860000028D0D1A7E610B586B062
+:1059F0000446FDF730FD017822291BD9807F00F095
+:105A00000300022808D0002080F0010120460BF09E
+:105A10002BF9040003D101E00120F5E7FFDF0620A8
+:105A20008DF80000694604F1E0000CF0F4FD002858
+:105A300000D0FFDF06B010BD2DE9F05F05460C4633
+:105A400000270078904601093E4604F1080BBA464B
+:105A500002297DD0072902D00A2909D146E06868C9
+:105A600001780A2905D00D2930D00E292ED0FFDF6C
+:105A7000BCE114271C26002C6BD08088A080FDF789
+:105A8000EAFC5FEA000900D1FFDF99F817005A46E7
+:105A9000400809F11801FDF7ADFC6868C089208253
+:105AA000696851F8060FC4F812004868C4F8160077
+:105AB000A07E20F0060001E01802002040F0010066
+:105AC000A07699F81E0040F020014DE01A270A2622
+:105AD000002CD1D0C088A080FDF7BDFC050000D10E
+:105AE000FFDF59462846FFF742FB7FE10CB1A88B48
+:105AF000A080287A0B287DD006DC01287BD00228E4
+:105B000008D0032804D135E00D2875D00E2874D0B4
+:105B1000FFDF6BE11E270926002CADD0A088FDF722
+:105B20009AFC5FEA000900D1FFDF287B00F0030048
+:105B30000128207A1BD020F001002072297B8908DF
+:105B400061F341002072297BC90861F3820001E002
+:105B500041E1F2E02072297B090961F3C300207260
+:105B600099F81E0040F0400189F81E103EE140F017
+:105B70000100E2E713270D26002CAAD0A088FDF72C
+:105B80006AFC8146807F00F00300022808D00020D4
+:105B900080F00101A0880BF067F8050003D101E057
+:105BA0000120F5E7FFDF99F81E0000F00302022A4A
+:105BB00050D0686F817801F003010129217A4BD020
+:105BC00021F00101217283789B0863F34101217266
+:105BD0008378DB0863F38201217283781B0963F306
+:105BE000C3012172037863F306112172437863F3D2
+:105BF000C71103E061E0A9E090E0A1E0217284F820
+:105C000009A0C178A172022A29D00279E17A62F34F
+:105C10000001E1720279520862F34101E1720279F6
+:105C2000920862F38201E1720279D20862F3C30141
+:105C3000E1724279217B62F30001217342795208BB
+:105C400062F3410121734279920862F38201217368
+:105C5000407928E0A86FADE741F00101B2E7427951
+:105C6000E17A62F30001E1724279520862F3410184
+:105C7000E1724279920862F38201E1724279D208BC
+:105C800062F3C301E1720279217B62F300012173A7
+:105C90000279520862F3410121730279920862F39A
+:105CA000820121730079C00860F3C301217399F860
+:105CB0000000232831D9262140E018271026E4B31C
+:105CC000A088FDF7C8FB8346807F00F00300022810
+:105CD00009D0002080F00101A0880AF0C5FF5FEA2A
+:105CE000000903D101E00120F4E7FFDFE868A060CC
+:105CF00099F8000040F0040189F8001099F80100BB
+:105D0000800708D5012020739BF8000023286DD957
+:105D10002721584651E084F80CA067E015270F268C
+:105D20005CB1A088FDF797FB814606225946E868DA
+:105D300008F089F90120A073A2E041E048463CE068
+:105D400016270926E4B3287B20724FE0287B192709
+:105D50000E26ACB3C4F808A0A4F80CA0012807D004
+:105D6000022805D0032805D0042803D0FFDF0DE06A
+:105D7000207207E0697B042801F00F0141F08001E7
+:105D800021721ED0607A20F003006072A088FDF7B7
+:105D900062FB05460078212828D0232800D0FFDFA9
+:105DA000A87F00F00300022813D0002080F001013A
+:105DB000A0880AF06BFF22212846FDF7ABF915E019
+:105DC00004E0607A20F00300401CDEE7A8F80060E1
+:105DD00011E00120EAE70CB16888A080287A032846
+:105DE0002ED004280AD0052850D0FFDFA8F8006084
+:105DF0000CB1278066800020BDE8F09F15270F2694
+:105E0000002CE3D0A088FDF726FB807F00F0030084
+:105E1000022809D05FF0000080F00101A0880AF09C
+:105E200023FF050003D101E00120F5E7FFDFD5F8EE
+:105E30001D000622594608F006F984F80EA0D5E7A1
+:105E400017270926002CC1D0A088FDF704FB814646
+:105E5000807F00F00300022808D0002080F00101BC
+:105E6000A0880AF001FF050003D101E00120F5E759
+:105E7000FFDF6878800701D5022000E00120207252
+:105E800099F800002328B1D9272157E719270E26B2
+:105E9000002C9BD0A088FDF7DEFA5FEA000900D154
+:105EA000FFDFC4F808A0A4F80CA084F808A0A07A2A
+:105EB00040F00300A07299F81E10C90961F3820036
+:105EC000A07299F81F2099F81E1012EAD11F05D070
+:105ED00099F8201001F01F0110292BD020F00800A4
+:105EE000A07299F81F10607A61F3C3006072697A3A
+:105EF00001F003010129A2D140F00400607299F879
+:105F00001E0000F003000228E87A16D0217B60F31F
+:105F100000012173AA7A607B62F300006073EA7A61
+:105F2000520862F341012173A97A490861F34100E3
+:105F300060735BE740F00800D2E7617B60F300012B
+:105F40006173AA7A207B62F300002073EA7A520818
+:105F500062F341016173A97A490861F3410020733A
+:105F600044E710B5FE4C30B10146102204F1200088
+:105F70001EF0F0FD012084F8300010BD10B504467D
+:105F800000F0D9FDF64920461022BDE8104020312E
+:105F90001EF0E0BD70B5F24D06004FF0000413D0C6
+:105FA0000EF00EFB08B110240CE00621304608F07C
+:105FB00031F8411C05D028665FF0010085F85C00CF
+:105FC00000E00724204670BD0020F7E7007810F0BD
+:105FD0000F0204D0012A05D0022A0CD110E00009DA
+:105FE00009D10AE00009012807D0022805D00328BA
+:105FF00003D0042801D007207047087000207047A4
+:106000000620704705282AD2DFE800F003070F17A3
+:106010001F00087820F0FF001EE0087820F00F0035
+:10602000401C20F0F000103016E0087820F00F003F
+:10603000401C20F0F00020300EE0087820F00F0027
+:10604000401C20F0F000303006E0087820F00F000F
+:10605000401C20F0F00040300870002070470720FE
+:1060600070472DE9F041804688B00D46002708466C
+:106070000EF0F3FAA8B94046FDF7EDF9040003D09D
+:106080002078222815D104E043F2020008B0BDE8D0
+:10609000F08145B9A07F410603D500F00300022836
+:1060A00001D01020F2E7A07FC10601D4010702D57C
+:1060B0000DB10820EAE7E17F090701D50D20E5E7EA
+:1060C00000F00300022805D125B12846FEF760FF45
+:1060D0000700DBD1A07F00F00300022808D00020D9
+:1060E00080F0010140460AF0BFFD060002D00FE03B
+:1060F0000120F5E7A07F00F0030002280ED0002069
+:1061000080F00101002240460AF0A5FD060007D0FC
+:10611000A07F00F00300022804D009E00120EFE78F
+:106120000420B3E725B12A4631462046FEF754FF46
+:106130006946304600F00FFD009800B9FFDF009976
+:10614000022006F1E0024870C1F824804A61002272
+:106150000A81A27F02F00302022A1CD001200871EA
+:10616000287800F00102087E62F3010008762A78A0
+:10617000520862F3820008762A78920862F3C3001C
+:1061800008762A78D20862F3041008762421204683
+:10619000FCF7C0FF33E035B30871301D88613078FB
+:1061A000400908777078C0F340004877287800F0FD
+:1061B0000102887F62F301008877A27FD20962F32F
+:1061C00082008877E27F62F3C3008877727862F397
+:1061D00004108877A878C87701F121022846203179
+:1061E000FEF71BFF03E00320087105200876252138
+:1061F0002046FCF78FFFA07F20F04000A07701A988
+:1062000000980CF023FA022801D000B1FFDF3846D5
+:106210003CE72DE9FF4F534A0D4699B09A4607CA0D
+:106220000BAB002783E807001998FDF714F9060067
+:1062300006D03078262806D008201DB0BDE8F08FA3
+:1062400043F20200F9E7B07F00F00309B9F1020F51
+:1062500003D00020284302D006E00120FAE71B9873
+:10626000FEF796FE0028E8D1B07F00F00300022878
+:1062700001D11B9979BB022808D0002080F00101D0
+:1062800019980AF0F1FC040003D101E00120F5E7C0
+:10629000FFDF852D28D007DCF5B1812D1ED0822DA2
+:1062A0001ED0832D08D11DE0862D1FD0882D1FD034
+:1062B000892D1FD08A2D1FD00F2020710F281DD0AF
+:1062C00003F0ACF8E0B101208DF84000201D1190E2
+:1062D0002079B8B167E111E00020EEE70120ECE79A
+:1062E0000220EAE70320E8E70520E6E70620E4E7E6
+:1062F0000820E2E70920E0E70A20DEE707209CE724
+:1063000011209AE7B9F1020F03D0A56F03D1A06F56
+:1063100002E0656FFAE7606F804632D04FF001000F
+:1063200000904FF002000190214630461B9AFEF784
+:1063300053FE1B98007800F00101A87861F301007A
+:10634000A870B17FC90961F38200A870F17F61F381
+:10635000C300A870617861F30410A870207803E08E
+:106360001802002048500200400928706078C0F3ED
+:10637000400068701B988078E87000206871287170
+:1063800003E00220009001200190A87898F8021004
+:10639000C0F3C000C1F3C00108405FEA000B2CD07D
+:1063A00050460EF00DF990BBDAF80C000EF008F92B
+:1063B00068BBDAF81C000EF003F940BBDAF80C00F9
+:1063C000A060DAF81C00E06098F80100617800F045
+:1063D000010041EA4000607098F80210C0B2C1F3B9
+:1063E0000011891E0840607000202077019906F195
+:1063F000170002290CD001210BE098F801106078F9
+:1064000001F00101FD2242EA41010840E3E732E0E8
+:10641000002104EB810148610099701C022901D020
+:10642000012100E0002104EB81014861A87800F01F
+:106430000300012858D198F8020000F00300012859
+:1064400052D1B9F1020F04D02A1D691D1B98FEF725
+:10645000E4FD297998F8040001408DF83810687936
+:1064600098F8052010408DF83C0001433CD0504680
+:106470000EF0A6F808B11020DFE60AF11001049131
+:10648000B9F1020F18D008465FF0000104F18C0347
+:10649000CDE9000304F5AE7202920EAB5A462046D7
+:1064A000FEF704FE0028E7D1B9F1020F08D05046EC
+:1064B00008D14FF0010107E050464FF00101E5E738
+:1064C0000498F5E74FF0000104F1A403CDE90003BF
+:1064D00004F5B072029281F001010FAB5A462046DA
+:1064E000FEF7E4FD0028C7D16078800734D4A8788F
+:1064F00098F80210C0F38000C1F3800108432BD04C
+:10650000297898F800000BAAB9F1020F06D032F8EA
+:1065100011204300DA4002F003070AE032F81020AD
+:106520004B00DA4012F0030705D0012F0BD0022FE9
+:106530000BD0032F07D0BBF1000F0DD0012906D0DF
+:10654000042904D008E00227F5E70127F3E7012832
+:1065500001D0042800D10427B07F40F08000B0773C
+:10656000F17F6BF30001F177607881074FF0030052
+:106570000CD5A071BBF1000F15D100BF8DF85C00E8
+:1065800017AA3146199800F0BFFA0CE00221022F39
+:1065900018D0012F18D0042F22D00020A071B07F76
+:1065A00020F08000B07725213046FCF7B3FD10A91C
+:1065B00004F1E0000CF02FF810B1022800D0FFDF4A
+:1065C00000203AE6A171D9E7A1710D2104F1200064
+:1065D0001EF061FB207840F0020020700420CDE71F
+:1065E0000120A071DFE72DE9F04387B0904689468E
+:1065F00004460025FCF72FFF060006D03078272838
+:1066000006D0082007B0BDE8F08343F20200F9E7A6
+:10661000B07F00F00300022808D0002080F00101C4
+:1066200020460AF021FB040003D101E00120F5E738
+:10663000FFDFA7795FEA090005D0012821D0B9F171
+:10664000020F26D110E0B8F1000F22D1012F05D0A2
+:10665000022F05D0032F05D0FFDF2DE00C252BE006
+:10666000012529E0022527E040460DF0A9FFB0B939
+:10667000032F0ED11022414604F11D001EF06AFACC
+:106680001AE0012F02D0022F03D104E0B8F1000F6D
+:1066900012D00720B6E740460DF092FF08B1102057
+:1066A000B0E7102104F11D001EF0D3FA0621404688
+:1066B00007F0B0FCC4F81D002078252140F002004E
+:1066C00020703046FCF726FD2078C10713D020F05B
+:1066D0000100207002208DF8000004F11D000290DE
+:1066E0008DF804506946C3300BF095FF022803D0A3
+:1066F00010B1FFDF00E02577002083E730B587B0D9
+:106700000D460446FCF7A7FEA0B1807F00F0030011
+:10671000022812D05FF0000080F0010120460AF04C
+:10672000A3FA04000ED028460DF04AFF38B110201D
+:1067300007B030BD43F20200FAE70120ECE7207811
+:10674000400701D40820F3E7294604F13D00202248
+:1067500005461EF0FFF9207840F010002070010778
+:106760000FD520F00800207007208DF80000694642
+:1067700004F1E00001950BF04EFF022801D000B1BA
+:10678000FFDF0020D4E770B50D460646FCF763FE38
+:1067900018B10178272921D102E043F2020070BD2F
+:1067A000807F00F00300022808D0002080F0010163
+:1067B00030460AF059FA040003D101E00120F5E760
+:1067C000FFDFA079022809D16078C00706D02A46E9
+:1067D00021463046FEF7FAFC10B10FE0082070BDEC
+:1067E000B4F860000E280BD204F1620102231022DB
+:1067F000081F0AF0C0F8012101704570002070BD2B
+:10680000112070BD70B5064614460D4608460DF0C1
+:10681000D7FE18B920460DF0F9FE08B1102070BD62
+:10682000A6F57F40FF380ED03046FCF714FE38B195
+:10683000417822464B08811C1846FCF7DBFD07E037
+:1068400043F2020070BD2046FDF73CFE0028F9D15E
+:106850001021E01D0DF08FFBE21D294604F1170009
+:1068600000F089F9002070BD2DE9F04104468AB09E
+:1068700015468846002708460DF0EFFE18B9284651
+:106880000DF0EBFE18B110200AB0BDE8F0812046F3
+:10689000FCF7E1FD060003D0307827281BD102E089
+:1068A00043F20200F0E7B07F00F00300022809D0B5
+:1068B0005FF0000080F0010120460AF0D5F90400E5
+:1068C00003D101E00120F5E7FFDF2078400702D582
+:1068D0006078800701D40820D6E7B07F00F003007D
+:1068E000022803D0A06F03D1A16F02E0606FFAE726
+:1068F000616F407800B19DB1487810B1B8F1000FD8
+:106900000ED0ADB1EA1D06A8E16800F034F91022FE
+:1069100006A905F117001EF0F1F818B1042707E0E9
+:106920000720B1E71022E91D04F12D001EF012F935
+:10693000B8F1000F06D0102208F1070104F11D0084
+:106940001EF008F92078252140F002002070304622
+:10695000FCF7E0FB2078C10715D020F00100207083
+:1069600002208DF8000004F11D0002901030039009
+:106970008DF804706946B3300BF04DFE022803D049
+:1069800010B1FFDF00E0277700207DE7F8B515465E
+:106990000E460746FCF75FFD040004D0207822284D
+:1069A00004D00820F8BD43F20200F8BDA07F00F03B
+:1069B0000300022802D043F20500F8BD30460DF076
+:1069C000FFFD18B928460DF0FBFD08B11020F8BDF9
+:1069D00000953288B31C21463846FEF71AFC112870
+:1069E00015D00028F3D1297C4A08A17F62F3C71192
+:1069F000A177297CE27F61F30002E277297C890894
+:106A000084F82010A17F21F04001A177F8BDA17F7B
+:106A10000907FBD4D6F80200C4F83600D6F8060001
+:106A2000C4F83A003088A0861022294604F12400D8
+:106A30001EF090F8287C4108E07F61F34100E07788
+:106A4000297C61F38200E077287C800884F82100AB
+:106A5000A07F40F00800A0770020D3E770B50D4676
+:106A600006460BB1072070BDFCF7F5FC040007D00B
+:106A70002078222802D3A07F800604D4082070BD8D
+:106A800043F2020070BDADB12946304609F0F1F87D
+:106A900002F0F0FA297C4A08A17F62F3C711A177BE
+:106AA000297CE27F61F30002E277297C890884F87F
+:106AB000201004E0304609F004F902F0DBFAA17F6F
+:106AC00021F02001A17770BD70B50D46FCF7C3FC25
+:106AD000040005D028460DF099FD20B1102070BDAE
+:106AE00043F2020070BD29462046FEF740FB00201D
+:106AF00070BD04E010F8012B0AB100207047491E58
+:106B000089B2F7D20120704770B51546064602F0EB
+:106B100085FC040000D1FFDF207820F00F00801CEE
+:106B200020F0F0002030207066802868A060BDE86A
+:106B3000704002F076BC10B5134C94F83000002879
+:106B400008D104F12001A1F110000BF0A6FD0120F5
+:106B500084F8300010BD10B190F8B9202AB10A486D
+:106B600090F8350018B1002003E0B83001E0064885
+:106B700034300860704708B50023009313460A4676
+:106B80000AF06DFA08BD00001802002018B18178E3
+:106B9000012938D101E010207047018842F6011226
+:106BA000881A914231D018DC42F60102A1EB0200B2
+:106BB00091422AD00CDC41B3B1F5C05F25D06FF40F
+:106BC000C050081821D0A0F57060FF381BD11CE020
+:106BD00001281AD002280AD117E0B0F5807F14D01E
+:106BE00008DC012811D002280FD003280DD0FF287F
+:106BF00009D10AE0B0F5817F07D0A0F58070033895
+:106C000003D0012801D0002070470F2070470A28C8
+:106C10001ED007DC18D2DFE800F0191B1F1F171F5A
+:106C2000231D1F21102815D008DC0B2812D00C289A
+:106C300010D00D2816D00F2806D10DE011280BD04A
+:106C400084280BD087280FD003207047002070477E
+:106C500005207047072070470F20704704207047B9
+:106C6000062070470C20704743F20200704738B589
+:106C70000C46050041D06946FFF7A8F9002819D154
+:106C80009DF80010607861F3020060706946681C2E
+:106C9000FFF79CF900280DD19DF80010607861F392
+:106CA000C5006070A978C1F34101012903D0022910
+:106CB00005D0072038BD217821F0200102E021789D
+:106CC00041F020012170410704D0A978C90861F37F
+:106CD00086106070607810F0380F07D0A978090925
+:106CE00061F3C710607010F0380F02D16078400671
+:106CF00003D5207840F040002070002038BD70B5EA
+:106D000004460020088015466068FFF7B0FF0028A1
+:106D100016D12089A189884211D860688078C0077F
+:106D20000AD0B1F5007F0AD840F20120B1FBF0F2A1
+:106D300000FB1210288007E0B1F5FF7F01D90C207D
+:106D400070BD01F201212980002070BD10B50478CA
+:106D5000137864F3000313700478640864F3410348
+:106D600013700478A40864F3820313700478E408B1
+:106D700064F3C30313700478240964F304131370D9
+:106D80000478640964F3451313700078800960F394
+:106D90008613137031B10878C10701D1800701D57E
+:106DA000012000E0002060F3C713137010BD42788B
+:106DB000530702D002F0070306E012F0380F02D0AA
+:106DC000C2F3C20300E001234A7863F302024A706F
+:106DD000407810F0380F02D0C0F3C20005E043073E
+:106DE00002D000F0070000E0012060F3C5024A7005
+:106DF00070472DE9F04F95B00D00824612D0122158
+:106E000028461DF026FF4FF6FF7B05AA01215846B4
+:106E100006F04BFF0024264637464FF420586FF407
+:106E2000205972E0102015B0BDE8F08F9DF81E00CB
+:106E300001280AD1BDF81C1041450BD011EB090007
+:106E40000AD001280CD002280CD0042C0ED0052C1E
+:106E50000FD10DE0012400E00224BDF81A6008E023
+:106E6000032406E00424BDF81A7002E0052400E0C3
+:106E70000624BDF81A10514547D12C74BEB34FF00B
+:106E8000000810AA4FF0070ACDE90282CDE900A858
+:106E90000DF13C091023CDF810904246314658467A
+:106EA00006F0B6FF08BBBDF83C002A46C0B210A9E8
+:106EB0000BF05CFCC8B9AE81CFB1CDE900A80DF1F3
+:106EC000080C0AAE40468CE84102132300223946E2
+:106ED000584606F09DFF40B9BDF83C00F11CC01EAD
+:106EE000C0B22A1D0BF042FC10B103209BE70AE060
+:106EF000BDF82900E881062C05D19DF81E00A87276
+:106F0000BDF81C00288100208DE705A806F0D9FEF9
+:106F100000288BD0FFF77BFE85E72DE9F0471C4664
+:106F2000DDE90978DDF8209015460E00824600D193
+:106F3000FFDF0CB1208818B1D5B11120BDE8F08772
+:106F4000022D01D0012100E0002106F1140005F01E
+:106F50009BFDA8F8000002463B462946504603F038
+:106F6000BCF8C9F8000008B9A41C3C600020E5E7A3
+:106F70001320E3E7F0B41446DDE904528DB1002399
+:106F800014B1022C09D101E0012306E00D7CEE07CB
+:106F900003D025F0010501230D742146F0BC03F058
+:106FA00025BF1A80F0BC70472DE9FE4F91461A8824
+:106FB0001C468A468046FAB102AB494603F08DF87A
+:106FC000050019D04046A61C278809F091FF3246DB
+:106FD000072629463B46009609F09FFB208823465A
+:106FE000CDE900504A4651464046FFF7C3FF002016
+:106FF00020800120BDE8FE8F0020FBE72DE9F0474F
+:1070000086B09146DDE90E460F46824603AA05A9E1
+:1070100004A8109D8DE80700984632462146504648
+:10702000FFF77BFF049909B1012200E000222A70DA
+:10703000002818D1F94A03AB1060059A009104F1B9
+:107040001400CDE901204A463946504606F0D3F8EF
+:10705000A8B1092811D2DFE800F005080510100AD0
+:107060000C0C0E00002006B068E71120FBE707209B
+:10707000F9E70820F7E70D20F5E70320F3E7BDF86F
+:107080000C100498CDE90001434632462146504693
+:10709000FFF770FFE6E72DE9F04389B00D46DDE923
+:1070A000108781461C461646142103A81DF0F3FDE7
+:1070B000012002218DF810108DF80C008DF8117050
+:1070C000ADF8146064B1A278D20709D08DF816002B
+:1070D000E088ADF81A00A088ADF81800A068079005
+:1070E00008A80095CDE90110424603A948466B68FF
+:1070F000FFF784FF09B0BDE8F083F0B58BB0002442
+:107100000646069407940727089405A80994019455
+:1071100000970294CDE903400D46102322463046E5
+:1071200006F076FE78B90AA806A9019400970294A1
+:10713000CDE90310BDF8143000222946304606F090
+:107140003DFC002801D0FFF762FD0BB0F0BD06F05A
+:10715000DDBA2DE9FC410C468046002602F05EF9BE
+:10716000054620780D287DD2DFE800F0BC0713B378
+:1071700025BD49496383AF959B00A848006820B1AD
+:10718000417841F010014170ADE0404602F076F9DF
+:10719000A9E00421404609F067FD070000D1FFDFA8
+:1071A00007F11401404605F003FCA5BB132140463E
+:1071B000FDF746FC97E00421404609F055FD070025
+:1071C00000D1FFDFE088ADF800000020B8819DF815
+:1071D0000000010704D5C00602D5A088B88105E0EB
+:1071E0009DF8010040067ED5A088F88105B9FFDF33
+:1071F00022462946404601F063FC022673E0E188FE
+:10720000ADF800109DF8011009060FD5072803D02E
+:1072100006280AD00AE024E00421404609F024FDB3
+:10722000060000D1FFDFA088F0810226CDB9FFDF84
+:1072300017E00421404609F017FD070000D1FFDFE9
+:1072400007F1140006F099FA90F0010F02D1E079ED
+:10725000000648D5387C022640F00200387405B993
+:10726000FFDF00E03EE022462946404601F028FCD0
+:1072700039E00421404609F0F7FC017C002D01F0C3
+:107280000206C1F340016171017C21F00201017429
+:10729000E7D1FFDFE5E702260121404602F020F9B1
+:1072A00021E00421404609F0DFFC054660680090BB
+:1072B0002089ADF8040001226946404602F031F908
+:1072C000287C20F0020028740DE0002DC9D1FFDFDA
+:1072D000C7E7022600214046FBF784F8002DC0D105
+:1072E000FFDFBEE7FFDF3046BDE8FC813EB50C00A6
+:1072F00009D001466B4601AA002006F00BFE20B122
+:10730000FFF785FC3EBD10203EBD00202080A07010
+:107310009DF8050002A900F00700FEF773FE50B9C2
+:107320009DF8080020709DF8050002A9C0F3C20076
+:10733000FEF768FE08B103203EBD9DF808006070AE
+:107340009DF80500C109A07861F30410A0709DF8B4
+:107350000510890961F3C300A0709DF80410890627
+:1073600001D5022100E0012161F342009DF80010E7
+:1073700061F30000A07000203EBD70B514460646C3
+:107380000D4651EA040005D075B108460DF05CF9D0
+:1073900078B901E0072070BD2946304606F01BFE93
+:1073A00010B1BDE8704032E454B120460DF04CF904
+:1073B00008B1102070BD21463046BDE8704095E709
+:1073C000002070BD2DE9FC5F0C4690460546002765
+:1073D00001780822007A3E46B2EB111F7ED104F1FB
+:1073E0000A0100910A31821E4FF0020A04F1080BD3
+:1073F0000191092A73D2DFE802F0ECDF05F42727B8
+:107400007AA9CD006888042109F02EFC060000D17D
+:10741000FFDFB08920B152270726C2E07C0200209E
+:1074200051271026002C7DD06888A0800120A071F3
+:10743000A88900220099FFF7A0FF002873D1A8892E
+:107440002081288AE081D1E0B5F81290072824D164
+:10745000E87B000621D5512709F1140086B2002CE3
+:10746000E1D0A88900220099FFF787FF00285AD1B0
+:107470006888A08084F806A0A88920810120A073D4
+:10748000288A2082A4F81290A88A009068884B4627
+:10749000A969019A01F0F1FAA8E0502709F1120058
+:1074A00086B2002C3ED0A88900225946FFF765FF1E
+:1074B000002838D16888A080A889E080287A072829
+:1074C00013D002202073288AE081E87BC009607312
+:1074D000A4F81090A88A0090688801E083E080E01A
+:1074E0004B4604F11202A969D4E70120EAE7B5F896
+:1074F0001290512709F1140086B2002C66D06888DA
+:10750000042109F0B1FB83466888A080A889002285
+:107510000099FFF732FF00286ED184F806A0A889F1
+:10752000208101E052E067E00420A073288A2082D5
+:10753000A4F81290A88A009068884B46A969019A1D
+:1075400001F09BFAA989ABF80E104FE06888FBF7B1
+:1075500082FF07466888042109F086FB064607B9C2
+:10756000FFDF06B9FFDF687BC00702D05127142672
+:1075700001E0502712264CB36888A080502F06D017
+:1075800084F806A0287B594601F087FA2EE0287B74
+:10759000A11DF9E7FE49A8894989814205D15427EF
+:1075A00006269CB16888A08020E053270BE06888FD
+:1075B000A080A889E08019E06888042109F054FBC4
+:1075C00000B9FFDF55270826002CF0D1A8F800608D
+:1075D00011E056270726002CF8D06888A0800020EC
+:1075E00013E0FFDF02E0012808D0FFDFA8F8006009
+:1075F0000CB1278066800020BDE8FC9F5727072636
+:10760000002CE3D06888A080687AA071EEE7401D66
+:1076100020F0030009B14143091D01EB4000704710
+:1076200013B5DB4A00201071009848B10024684669
+:1076300009F037F9002C02D1D64A009911601CBD1F
+:1076400001240020F4E770B50D46064686B01446C6
+:107650005C2128461DF01FFB04B9FFDFA078687489
+:10766000A2782188284601F042FA0020A881E8810A
+:10767000228805F11401304605F07FF96A460121A0
+:10768000304606F012FB19E09DF80300000715D5FF
+:10769000BDF806103046FFF730FD9DF80300BDF839
+:1076A000061040F010008DF80300BDF80300ADF89F
+:1076B0001400FF233046059A06F058FC684606F091
+:1076C00000FB0028E0D006B070BD10B50C4601F1FB
+:1076D000140005F089F90146627C2046BDE810409F
+:1076E00001F03ABA70B50546042109F0BDFA04006C
+:1076F00000D1FFDF04F114010C46284605F058F9CB
+:1077000021462846BDE8704005F059B970B58AB0E9
+:107710000C460646FBF79FFE050014D02878222869
+:1077200027D30CB1A08890B101208DF80C00032064
+:107730008DF8100000208DF8110054B1A088ADF82C
+:107740001800206807E043F202000AB070BD09206B
+:10775000FBE7ADF8180005900421304609F084FAE3
+:10776000040000D1FFDF04F1140005F054F9000714
+:1077700001D40820E9E701F051FE60B108A8022118
+:107780000094CDE9011095F8232003A930466368E1
+:10779000FFF734FCD9E71120D7E72DE9F04FB2F815
+:1077A00002A0834689B0154689465046FBF753FE32
+:1077B00007460421504609F057FA0026044605966C
+:1077C0004FF002080696ADF81C6007B9FFDF04B958
+:1077D000FFDF4146504603F070FE50B907AA06A9E4
+:1077E00005A88DE807004246214650466368FFF72A
+:1077F00094FB674807AB0660DDE9051204F114004D
+:10780000CDF80090CDE90320CDE9013197F8232090
+:10781000594650466B6805F047F906000AD0022E1B
+:1078200004D0032E14D0042E00D0FFDF09B0304660
+:10783000BDE8F08FBDF81C000028F7D00599CDE910
+:1078400000104246214650466368FFF793FBEDE780
+:10785000687840F008006870E8E72DE9F04F9BB0C9
+:1078600004464FF000084A48ADF85480ADF8308027
+:10787000ADF85080A0F80880ADF81480ADF81880FD
+:10788000ADF82080ADF81C80007916460D464746BD
+:10789000012808D0022806D0032804D0042802D0EA
+:1078A00008201BB0C4E720460CF08AFED0BB284657
+:1078B0000CF086FEB0BB60680CF0CFFE90BB606839
+:1078C00048B160892189884202D8B1F5007F01D989
+:1078D0000C20E6E780460BAA06A92846FFF70FFA18
+:1078E0000028DED168688078C0F34100022808D102
+:1078F0009DF8190010F0380F03D028690CF0A4FE91
+:1079000080B905A92069FFF7B2F90028C9D120691B
+:1079100050B1607880079DF8150000F0380002D55E
+:10792000D0B301E011E0B8BB9DF8140080060ED57D
+:107930009DF8150010F0380F03D060680CF084FE3D
+:1079400018B960680CF089FE08B11020A9E707A9F2
+:107950006069FFF78CF90028A3D1606940B19DF8F8
+:107960001D0000F0070101293FD110F0380F3CD075
+:1079700008A9A069FFF77BF9002892D19DF81C00A7
+:10798000800632D49DF8200080062ED4A06904E041
+:107990007C0200201400002027E040B19DF8210067
+:1079A00000F00701012920D110F0380F1DD0E06848
+:1079B00018B10078C8B11C2817D20EAA611C204645
+:1079C000FFF7C4F90120B94660F30F27BA4607460E
+:1079D0008DF84E0042F60300ADF84C000DF13B026D
+:1079E00017A928680AF0E1FE08B1072059E79DF8B9
+:1079F0005C0016A9CDF80090C01CCDE9019100F003
+:107A0000FF0B00230BF20122514613A806F090F859
+:107A1000F0BBBDF858000990FE482A8929690092F8
+:107A2000CDE901106B89BDF82C202868069906F075
+:107A30007FF801007ED120784FF0020AC10601D400
+:107A400080062BD5ADF80C90606950B907A906A83F
+:107A5000FFF7ADF99DF81D0020F00700401C8DF8E0
+:107A60001D009DF81C008DF84E7040F0C8008DF888
+:107A70001C0042F60210ADF84C000CA903AACDF888
+:107A800000A0CDE90121002340F2032213A800E069
+:107A90001EE0079906F04CF801004BD1DD484D4639
+:107AA00008385B460089ADF839000EA8CDE9029090
+:107AB000CDF80490CDF810904FF007090022CDF8D2
+:107AC0000090BDF858104FF6FF7005F077FF10B129
+:107AD000FFF79DF8E5E69DF83800000625D5294614
+:107AE000012060F30F218DF84E704FF42450ADF853
+:107AF0004C00ADF8105062789DF81000002362F33E
+:107B000000008DF810006278CDF800A0520862F3F2
+:107B100041008DF8100004AACDE9012540F20322AE
+:107B200013A806F005F8010004D1606888B3206945
+:107B3000A8B900E086E005A906A8FFF738F9607843
+:107B4000800706D49DF8150020F038008DF8150048
+:107B500005E09DF8140040F040008DF814008DF809
+:107B60004E7042F60110ADF84C00208940F2012120
+:107B7000B0FBF1F201FB1202606814ABCDF800809B
+:107B8000CDE90103002313A8059905F0D1FF0100F9
+:107B900058D12078C00729D0ADF80C50A06950B951
+:107BA00008A906A8FFF703F99DF8210020F00700B7
+:107BB000401C8DF821009DF820008DF84E7040F09B
+:107BC00040008DF8200042F60310ADF84C0015A9D6
+:107BD00003AACDF800A0CDE90121002340F2032241
+:107BE00013A8089905F0A4FF01002BD1E06868B341
+:107BF0002946012060F30F218DF84E7042F60410E3
+:107C0000ADF84C00E068002302788DF860204078E1
+:107C10008DF86100E06818AA4088ADF86200E0685D
+:107C200000798DF86400E068C088ADF86500CDF893
+:107C30000090CDE901254FF4027213A805F078FFFA
+:107C4000010003D0099800F0B3FF2AE67148032130
+:107C50000838017156B100893080BDF8500070803D
+:107C6000BDF83000B080BDF85400F080002018E668
+:107C700070B501258AB016460B46012802D00228AD
+:107C800016D104E08DF80E504FF4205003E08DF82B
+:107C90000E5042F60100ADF80C005BB10024601CF0
+:107CA00060F30F2404AA08A918460AF07EFD18B153
+:107CB00007204AE5102048E504A99DF820205548F2
+:107CC000CDE90021801E02900023214603A802F284
+:107CD000012205F02DFF10B1FEF799FF35E54D4863
+:107CE00008380EB1C1883180057100202DE5F0B54E
+:107CF00093B0074601268DF83E6041F60100ADF8CD
+:107D00003C0012AA0FA93046FFF7B2FF002848D165
+:107D1000404C0025083CE7B31C2102A81CF0BBFF27
+:107D20009DF808008DF83E6040F020008DF80800B6
+:107D300042F60520ADF83C000E959DF83A001195ED
+:107D400020F00600801C8DF83A009DF838006A4645
+:107D500020F0FF008DF838009DF8390009A920F0C7
+:107D6000FF008DF839000420ADF82C00ADF830008C
+:107D70000EA80A9011A80D900FA80990ADF82E50EA
+:107D800002A8FFF76AFD00280BD1BDF80000608152
+:107D900000E008E0BDF80400A081401CE0812571EE
+:107DA000002013B0F0BD6581A581BDF84800F4E75F
+:107DB0002DE9F74F1749A0B00024083917940A7924
+:107DC000A146012A04D0022A02D0082023B02FE5C0
+:107DD000CA88824201D00620F8E721988A4682426A
+:107DE00001D10720F2E701202146ADF848004FF607
+:107DF000FF7860F30F21ADF84A808DF86E0042F6EF
+:107E0000020B06918DF87240ADF86CB0ADF8704081
+:107E10001CA901E0840200201391ADF8508012A843
+:107E200005F073FF00252E462F460DAB072212A941
+:107E3000404605F06DFF78B10A285DD195B38EB349
+:107E4000ADF86450ADF866609DF85E008DF81440A2
+:107E500019AC012864D06BE09DF83A001FB30128EB
+:107E600059D1BDF8381059451FD118A809A9019456
+:107E70000294CDE9031007200090BDF836101023BE
+:107E80000022404605F0C4FFB0BBBDF860000428E6
+:107E900001D006284AD1BDF82410219881423AD158
+:107EA0000F2093E73AE0012835D1BDF83800B0F54E
+:107EB000205F03D042F6010188422CD1BAF80600B7
+:107EC000BDF83610884201D1012700E0002705B136
+:107ED0009EB1219881421ED118A809AA019402944A
+:107EE000CDE90320072000900D46102300224046D4
+:107EF00005F08EFF00B902E02DE04E460BE0BDF824
+:107F00006000022801D0102810D1C0B217AA09A918
+:107F10000AF02CFC50B9BDF8369086E7052055E7ED
+:107F200005A917A8221D0AF040FC08B103204DE75F
+:107F30009DF814000023001DC2B28DF81420229871
+:107F40000092CDE901401BA8069905F0F1FD10B99A
+:107F500002228AF80420FEF75AFE37E710B50B46D6
+:107F6000401E88B084B205AA00211846FEF7EEFE36
+:107F700000200DF1080C06AA05A901908CE8070065
+:107F8000072000900123002221464FF6FF7005F0E4
+:107F900015FD0446BDF81800012800D0FFDF20467B
+:107FA000FEF735FE08B010BDF0B5FF4F044687B0B0
+:107FB00038790E46032804D0042802D0082007B0E0
+:107FC000F0BD04AA03A92046FEF799FE0500F6D1EC
+:107FD00060688078C0F3410002280AD19DF80D0046
+:107FE00010F0380F05D020690CF02EFB08B11020DE
+:107FF000E5E7208905AA21698DE807006389BDF8B6
+:1080000010202068039905F093FD10B1FEF7FFFDE5
+:10801000D5E716B1BDF81400308004203871284629
+:10802000CDE7F8B50C0006460BD001464FF6FF75BC
+:1080300000236A46284605F06DFF20B1FEF7E7FDF4
+:10804000F8BD1020F8BD69462046FEF710FE002856
+:10805000F8D1A078314600F001032846009A05F0D7
+:1080600085FFEBE730B587B0144600220DF1080C10
+:1080700005AD01928CE82C00072200920A460146C9
+:1080800023884FF6FF7005F099FCBDF8141021808D
+:10809000FEF7BDFD07B030BD70B50D46042108F0F8
+:1080A000E3FD040000D1FFDF294604F11400BDE820
+:1080B000704004F0A9BC70B50D46042108F0D4FD51
+:1080C000040000D1FFDF294604F11400BDE8704030
+:1080D00004F0BDBC70B50D46042108F0C5FD0400D8
+:1080E00000D1FFDF294604F11400BDE8704004F020
+:1080F000D5BC70B50546042108F0B6FD040000D1DA
+:10810000FFDF214628462368BDE870400122FEF7C4
+:108110004BBF70B50646042108F0A6FD040000D14F
+:10812000FFDF04F1140004F05FFC401D20F00305A4
+:1081300011E0011D00880022431821463046FEF759
+:1081400033FF00280BD0607CABB2684382B2A068DA
+:10815000011D08F046FCA06841880029E9D170BDE6
+:1081600070B50546042108F07FFD040000D1FFDF53
+:10817000214628466368BDE870400222FEF714BF1E
+:1081800070B50E46054601F049F9040000D1FFDF45
+:108190000120207266726580207820F00F00001D9B
+:1081A00020F0F00040302070BDE8704001F039B997
+:1081B00010B50446012900D0FFDF2046BDE810407D
+:1081C0000121FAF70FB92DE9F04F97B04FF0000AEF
+:1081D0000C008346ADF814A0D04619D0E06830B149
+:1081E000A068A8B10188ADF81410A0F800A0584606
+:1081F000FBF731F9070043F2020961D038782228F1
+:108200005CD30421584608F02FFD050005D103E09A
+:10821000102017B0BDE8F08FFFDF05F1140004F067
+:10822000E3FB401D20F00306A078012803D00228BC
+:1082300001D00720EDE7218807AA584605F035FD53
+:1082400030BB07A805F03DFD10BB07A805F039FDC0
+:1082500048B99DF82600012805D1BDF82400A0F5F5
+:108260002451023902D04FF45050D2E7E068B0B147
+:10827000CDE902A00720009005AACDF804A0049241
+:10828000A2882188BDF81430584605F097FB10B13C
+:10829000FEF7BDFCBDE7A168BDF8140008809DF89D
+:1082A0001F00C00602D543F20140B2E70B9838B177
+:1082B000A1780078012905D080071AD40820A8E702
+:1082C0004846A6E7C007F9D002208DF83C00A86810
+:1082D0004FF00009A0B1697C4288714391420FD9E7
+:1082E0008AB2B3B2011D08F032FB8046A0F800A0AC
+:1082F00006E003208DF83C00D5F800804FF001091E
+:108300009DF8200010F0380F00D1FFDF9DF820000D
+:108310002649C0F3C200084497F8231010F8010C56
+:10832000884201D90F2074E72088ADF8400014A9D5
+:108330000095CDE90191434607220FA95846FEF763
+:108340005DFE002891D19DF8500050B9A078012819
+:1083500007D1687CB3B2704382B2A868011D08F0EF
+:108360000AFB002055E770B5064615460C46084640
+:10837000FEF70CFC002805D12A4621463046BDE810
+:10838000704075E470BD13E570B51E4614460D00CF
+:108390000ED06CB1616859B160B10349C98881429E
+:1083A00008D0072070BD00007C020020FA2F0000DA
+:1083B0001020F7E72068FEF7E9FB0028F2D13246EB
+:1083C00021462846BDE87040FFF747BA70B515460C
+:1083D0000C0006D038B1FE490989814203D007203C
+:1083E000E0E71020DEE72068FEF7D0FB0028D9D1B7
+:1083F00029462046BDE87040D6E570B5064686B0F1
+:108400000D46144610460CF001F9D0BB60680CF024
+:1084100024F9B0BBA6F57F40FF3803D03046FBF708
+:108420001AF880B128466946FEF7E3FC00280CD113
+:108430009DF810100F2008293CD2DFE801F0080653
+:108440000606060A0A0843F2020006B0AAE703205D
+:10845000FBE79DF80210012908D1BDF80010B1F525
+:10846000C05FF2D06FF4C052D142EED09DF806103A
+:1084700001290DD1BDF80410A1F52851062907D214
+:1084800000E028E0DFE801F0030304030303DCE776
+:108490009DF80A1001290ED1BDF80810B1F5245F2E
+:1084A000D3D0A1F524510239CFD00129CDD0022952
+:1084B00001D1CAE7FFDF606878B9002305AA294621
+:1084C000304605F027FD10B1FEF7A1FBBDE79DF892
+:1084D0001400800601D41020B7E7618822462846A0
+:1084E0006368FFF7BFFDB0E72DE9F043814687B031
+:1084F0008846144610460CF089F818B1102007B0D1
+:10850000BDE8F083002306AA4146484605F002FD77
+:1085100018B100BFFEF77BFBF1E79DF81800C0061D
+:1085200002D543F20140EAE70025072705A8019597
+:1085300000970295CDE9035062884FF6FF734146DC
+:10854000484605F065FC060013D160680CF05EF843
+:1085500060B960680195CDE90250009704952388C1
+:1085600062884146484605F053FC0646BDF81400B3
+:1085700020803046CEE739B1954B0A889B899A42D4
+:1085800002D843F2030070471DE610B586B0904C48
+:108590000423ADF81430638943B1A4898C4201D21D
+:1085A000914205D943F2030006B010BD0620FBE757
+:1085B000ADF81010002100910191ADF800300221BA
+:1085C0008DF8021005A9029104A90391ADF81220BB
+:1085D0006946FFF7F8FDE7E72DE9FC4781460E46BF
+:1085E00008460BF0EDFF88BB4846FAF734FF5FEA18
+:1085F00000080AD098F80000222829D30421484610
+:1086000008F032FB070005D103E043F20200BDE8A9
+:10861000FC87FFDF07F1140004F0FDF90546307810
+:10862000012803D0022804D00720F0E7A8070FD5BF
+:1086300002E015F01C0F0BD0B079341DC00709D033
+:10864000E08838B1A0680BF0BBFF18B11020DEE75E
+:108650000820DCE732782088002628B3A0F2011336
+:108660000721112B18D20CD2DFE803F00B090D0BF8
+:108670001D0B121D100B0B1D1D1D1D0B1D00022AB5
+:1086800011D10846C3E7012AFBD00CE02A0700E01D
+:10869000EA06002AF5DA06E0A0F5C0721F2A02D920
+:1086A0007D3A022AEDD8C6B200F0B8FE50B198F873
+:1086B0002300CDE90006FA89234639464846FEF7ED
+:1086C000EAFCA4E71120A2E72DE9F04F8BB01F468A
+:1086D00015460C4683460026FAF7BDFE28B1007801
+:1086E000222805D208200BB094E543F20200FAE7F5
+:1086F000B80801D00720F6E7032F00D100274FF676
+:10870000FF79CCB1022D73D320460BF0A6FF30B910
+:1087100004EB0508A8F101000BF09FFF08B1102041
+:10872000E1E7AD1EAAB22146484605F09DFC38F8A7
+:10873000021C88425CD1ADB22549B80702D58889B0
+:10874000401C00E001201FFA80F8F80701D08F8953
+:1087500000E04F4605AA4146584605F0A6FA4FF0FC
+:10876000070A4FF00009ACB3204608E04088102803
+:108770003ED8361D304486B2AE4239D2A0190288A6
+:108780004245F3D354E000BF9DF8170002074FD5D0
+:1087900084B304EB0608361DB8F80230B6B2102BCD
+:1087A00026D89A19AA4223D8B8F8002091421FD19E
+:1087B000C00620D5CDE900A90DF1080C0AAAA1191F
+:1087C00048468CE80700B8F800100022584603E03D
+:1087D0007C0200202CE00BE005F0F0F810B1FEF771
+:1087E00016FA80E7B8F80200BDF82810884202D0D7
+:1087F0000B2078E704E0B8F80200304486B206E0C7
+:10880000C00604D55846FEF778FC002888D19DF8AC
+:108810001700BDF81A1020F010008DF81700BDF8F1
+:108820001700ADF80000FF235846009A05F09EFBA4
+:1088300005A805F046FA18B9BDF81A10B942A3D92F
+:108840000421584608F010FA040000D1FFDFA28985
+:108850005AB1CDE900A94D46002321465846FEF7FE
+:108860001AFC0028BDD1A5813DE700203BE72DE99A
+:10887000FF4F8BB01E4617000D464FF0000412D07C
+:10888000B00802D007200FB0C4E4032E00D10026A8
+:108890005DB108460BF0D8FE28B93888691E084437
+:1088A0000BF0D2FE08B11020EDE7C74AB00701D5A2
+:1088B000D18900E00121F0074FF6FF7802D0D0897E
+:1088C000401E00E0404686B206AA0B9805F0EDF97E
+:1088D0004FF000094FF0070B0DF1140A39E000BF0B
+:1088E0009DF81B00000734D5CDF80490CDF800B0FA
+:1088F000CDF80890CDE9039A434600220B9805F085
+:1089000087FA60BB05B3BDF814103A8821442819D2
+:10891000091D8A4230D3BDF81E2020F8022BBDF875
+:10892000142020F8022BCDE900B9CDE90290CDF852
+:1089300010A0BDF81E10BDF8143000220B9805F0F1
+:1089400067FA08B103209EE7BDF814002044001D1B
+:1089500084B206A805F0B5F920B10A2806D0FEF7C2
+:1089600056F990E7BDF81E10B142B9D934B17DB1C6
+:108970003888A11C884203D20C2084E7052082E7B6
+:1089800022462946404605F06FFB01462819018022
+:10899000A41C3C80002076E710B504460BF036FEA0
+:1089A00008B1102010BD8848C0892080002010BD6B
+:1089B000F0B58BB00D460646142103A81CF06BF9E8
+:1089C00001208DF80C008DF8100000208DF81100AA
+:1089D000ADF814503046FAF73EFD48B10078222831
+:1089E00012D30421304608F03FF9040005D103E01A
+:1089F00043F202000BB0F0BDFFDF04F114000746A4
+:108A000004F009F8800601D40820F3E7207C022155
+:108A100040F00100207409A80094CDE9011007225C
+:108A200003A930466368FEF7E9FA20B1217C21F002
+:108A300001012174DEE729463046F9F7C4FC08A994
+:108A4000384603F0D7FF00B1FFDFBDF82040172CF8
+:108A500001D2172000E02046A84201D92C4602E0AE
+:108A6000172C00D2172421463046FFF724FB21465D
+:108A70003046F9F7CEF90020BCE7F8B51C4615469C
+:108A80000E46069F08F022FA2346FF1DBCB231466F
+:108A90002A46009407F00DFEF8BD70B50C46054659
+:108AA0000E2120461CF0D5F8002020802DB1012D8C
+:108AB00001D0FFDF76E4062000E00520A07171E41C
+:108AC00010B548800878134620F00F00001D20F0F4
+:108AD000F00080300C4608701422194604F108009A
+:108AE0001CF07DF800F09DFC3748046010BD2DE9B6
+:108AF000F047DFF8D890491D064621F003011746DC
+:108B00000C46D9F8000007F0EAFE050000D1FFDFAF
+:108B10004FF000083560A5F800802146D9F8000024
+:108B200007F0DDFE050000D1FFDF7560A5F80080CD
+:108B30007FB104FB07F1091D0BD0D9F8000007F045
+:108B4000CEFE040000D1FFDFB460C4F80080BDE8B1
+:108B5000F087C6F80880FAE72DE9F0411746491D6D
+:108B600021F00302194D064601681446286807F0F3
+:108B7000E1FE22467168286807F0DCFE3FB104FB85
+:108B800007F2121D03D0B168286807F0D3FE042055
+:108B900008F012F80446042008F016F8201A0128FC
+:108BA00004D12868BDE8F04107F08EBEBDE8F08131
+:108BB00010B50C4605F045F800B1FFDF2046BDE8D2
+:108BC0001040FEF724B800007C02002014000020B2
+:108BD00038B50C468288817B19B14189914200D910
+:108BE0000A462280C188121D90B26A4607F06DF9CC
+:108BF000BDF80000032800D30320C1B2208800F094
+:108C0000A3FF38BD38B50C468288817B19B1018934
+:108C1000914200D90A462280C188121D90B26A464C
+:108C200007F053F9BDF80000022800D30220C1B2BA
+:108C3000208800F089FF401CC0B238BD2DE9FE4FEE
+:108C40000C46FD4981464022D1E90201CDE90101EE
+:108C500009F1030020F00301C91C21F00301009178
+:108C60006846114607F01DFEF44E002C02D1F44A6E
+:108C700000999160009901440091357F05F101054B
+:108C800004D1E8B209F018FD00B1FFDF009800EB55
+:108C90000510C01C20F0030100915CB9707AB27A13
+:108CA0001044C2B200200870308C80B204F051FE33
+:108CB00000B1FFDF0098316A084400902146684601
+:108CC00000F00DFF0098C01C20F003000090B37A64
+:108CD000F27A717A04B1002007F0D9FE00990844B5
+:108CE00000902146684600F03AFF00273D46B24614
+:108CF00096F801800CE0284600F0D4FE0646817804
+:108D00008088F9F71DF971786D1C00FB0177EDB2D1
+:108D10004545F0D10098C01C20F00300009004B13C
+:108D200000203946F9F717F9009900270844009008
+:108D30003D469AF801800CE0284600F0B3FE064656
+:108D4000C1788088FEF763FC71786D1C00FB0177A9
+:108D5000EDB24545F0D10098C01C20F00300009012
+:108D600004B100203946FEF75BFC00994FF0000883
+:108D70000844009045469AF801700EE0284600F03D
+:108D800091FE0646807B30B106F1080001F0DDFE61
+:108D9000727800FB02886D1CEDB2BD42EED10098E6
+:108DA000C01C20F00300009004B10020414601F0F7
+:108DB000D0FE0099084400902146684600F049FE24
+:108DC0000098C01D20F0070200922CBB9D49002096
+:108DD000FAF743F8FBF713FB984801AA002110307B
+:108DE000F8F7CAFA00B1FFDF9AF81D00FEF77FFF1F
+:108DF00000B1FFDF91484FF4F67144301BF04BFF98
+:108E00008E480421443080F8E91180F8EA110621E7
+:108E100080F8EB11032101710099A1EB0900BDE875
+:108E2000FE8F70B5854C06464434207804EB40151F
+:108E3000E078083590B9A01990F8E80100280ED024
+:108E4000A0780F2800D3FFDF202128461BF023FF46
+:108E5000687866F3020068700120E070284670BDF3
+:108E60002DE9F04105460C46002700780521904683
+:108E70003E46B1EB101F00D0FFDF287A50B1012829
+:108E80000ED0FFDFA8F800600CB1278066800020BC
+:108E9000BDE8F0810127092674B16888A08008E048
+:108EA0000227142644B16888A0802869E060A88A57
+:108EB0002082287B2072E5E7A8F80060E7E710B57C
+:108EC0005F4C6068C11D21F00701814200D0FFDFC7
+:108ED0005A4801210022017042700172417203233D
+:108EE0008372C17202730274052202831F224283BD
+:108EF000417455A242610A22027741774FF4B06172
+:108F000001626168416010BD30B54D4C1568636801
+:108F100010339D4202D20420136030BD474B5D7870
+:108F20005A6802EB0512107051700320D080172090
+:108F300090800120D0709070002090735878401C71
+:108F40005870606810306060002030BD70B5064613
+:108F50003A480024457807E0204600F0A3FD017858
+:108F6000B14204D0641CE4B2AC42F5D1002070BD23
+:108F7000F7B5074608780C4610B3FFF7E7FF05463C
+:108F8000A7F12006202F06D0052E19D2DFE806F023
+:108F90000F2B2B151A0000F090FD0DB1697800E041
+:108FA0000021401AA17880B20844FF2808D8A07890
+:108FB00030B1A088022824D202E06088172820D28D
+:108FC0000720FEBD207AE0B161881729F8D3A18877
+:108FD0001729F5D3A1790029F2D0E1790029EFD042
+:108FE000402804D9ECE7242F0BD1207A48B16188BE
+:108FF0004FF6FB70814202D8A188814201D904203A
+:10900000FEBD65B9207802AA0121FFF77DFF002887
+:10901000F6D12078FFF79AFF050000D1FFDF052E7B
+:1090200025D2DFE806F003181B151E00A078687033
+:10903000A088E8801CE00000545002009803002043
+:109040001C000020000000206E5246357800000011
+:109050006088A8800CE0A078A87009E0A078E8708B
+:1090600006E054F8020FA8606068E86000E0FFDFE7
+:109070000020FEBD1A2835D00DDC132832D2DFE8DF
+:1090800000F01B31203131272723252D31312931A3
+:109090003131312F0F00302802D003DC1E2821D1BE
+:1090A000072070473A3809281CD2DFE800F0151B6A
+:1090B0000F1B1B1B1B1B07000020704743F2040003
+:1090C000704743F202007047042070470D2070473C
+:1090D0000F207047082070471120704713207047F9
+:1090E000062070470320704710B5007800F001009B
+:1090F00006F0E2FEBDE81040BCE70EB5017801F0D5
+:1091000001018DF80010417801F001018DF8011086
+:109110000178C1F340018DF802104178C1F340019C
+:109120008DF80310017889088DF8041041788908BA
+:109130008DF8051081788DF80610C1788DF807102C
+:1091400000798DF80800684605F0DDFAFFF792FF18
+:109150000EBD2DE9F84FDFF8F883FE4C00261FE026
+:10916000012000F03FFD0120FFF75BFE0546402196
+:109170004746D8F8080007F0B2FB686000B9FFDF87
+:10918000686805F06EF8A8B12846FAF758FC28463A
+:1091900000F02EFD20B940226968B86807F0CAFBCC
+:1091A00094F9E9010428DBDA022007F005FD0746FF
+:1091B0000025A6E040226968D8F8080007F0BAFB4D
+:1091C000F2E7B8F802104046491C89B2A8F802102C
+:1091D000B94201D3002141800221B8F8020007F012
+:1091E00043FD002865D0B8F80200694606F0CBFDC3
+:1091F000FFF740FF00B1FFDF9DF8000078B1B8F83D
+:10920000020007F075FE5FEA000900D1FFDF484663
+:1092100007F0E3F818B1B8F8020002F03DF9B8F829
+:10922000020007F053FE5FEA000900D1FFDF484665
+:1092300007F0CBF8E8BB0321B8F8020007F014FDF3
+:109240005FEA000B48D1FFDF46E000BFDBF810000B
+:1092500010B10078FF2849D0022000F0C3FC0220A2
+:10926000FFF7DFFD8246484607F0BBF9CAF8040065
+:1092700000B9FFDFDAF8040007F083FA002100905C
+:109280000170B8F802105046AAF8021001F00AFE68
+:10929000484607F078FA00B9FFDF504600F0A8FC16
+:1092A00018B99AF80100000704D50099CBF81010FE
+:1092B00012E024E0DBF8100038B10178491C11F00D
+:1092C000FF01017008D1FFDF06E000221146484689
+:1092D00000F0BDFB00B9FFDF94F9EA01022805DBCD
+:1092E000B8F8020001F0A3FD0028AFD194F9E9011C
+:1092F000042804DB484607F0AAFA00B101266D1CD9
+:10930000EDB2BD4204D294F9EA010228BFF659AF8A
+:10931000002E7FF423AFBDE8F84F032000F062BCBD
+:1093200010B58B4CE06008682061AFF2D91002F0F4
+:1093300042FD607010BD87480021443801708448A8
+:10934000017085494160704770B505464FF0805007
+:109350000C46D0F8A410491C05D1D0F8A810C94378
+:109360000904090C0BD050F8A01F01F0010129706D
+:10937000416821608068A080287830B970BD0621DE
+:1093800020460AF0F8FD01202870607940F0C00006
+:10939000607170BD70B54FF080540D46D4F88010E8
+:1093A000491C0BD1D4F88410491C07D1D4F888107B
+:1093B000491C03D1D4F88C10491C0CD0D4F880106F
+:1093C0000160D4F884104160D4F888108160D4F82A
+:1093D0008C10C16002E010210AF0CDFDD4F890009D
+:1093E000401C0BD1D4F89400401C07D1D4F898004D
+:1093F000401C03D1D4F89C00401C09D054F8900FB5
+:10940000286060686860A068A860E068E86070BD77
+:109410002846BDE8704010210AF0ADBD4D480079E6
+:10942000FFE470B54B4CE07830B3207804EB40108B
+:10943000407A00F00700204490F9E801002800DCA1
+:10944000FFDF2078002504EB4010407A00F0070091
+:10945000011991F8E801401E81F8E8012078401CCC
+:10946000C0B220700F2800D12570A078401CA070D9
+:109470000AF0E4FCE57070BDFFDF70BD3EB5054647
+:10948000032107F0F1FB0446284607F01FFD0546BF
+:1094900004B9FFDF206918B10078FF2800D1FFDF91
+:1094A00001AA6946284600F0D2FA60B9FFDF0AE057
+:1094B000002202A9284600F0CAFA00B9FFDF9DF891
+:1094C000080000B1FFDF9DF80000411E8DF800107C
+:1094D000EED220690199884201D1002020613EBD71
+:1094E00070B50546A0F57F400C46FF3800D1FFDF80
+:1094F000012C01D0FFDF70BDFFF790FF040000D109
+:10950000FFDF207820F00F00401D20F0F0005030E9
+:10951000207065800020207201202073BDE870401B
+:109520007FE72DE9F04116460D460746FFF776FF27
+:10953000040000D1FFDF207820F00F00401D20F054
+:10954000F00050302070678001202072286805E00C
+:109550001C000020DC030020C81400202061A88823
+:10956000A0822673BDE8F0415BE77FB5FFF7EEFC14
+:10957000040000D1FFDF02A92046FFF729FB0546C2
+:1095800003A92046FFF73EFB8DF800508DF801003F
+:10959000BDF80800001DADF80200BDF80C00001D6C
+:1095A000ADF80400E088ADF80600684606F066FCF9
+:1095B000002800D0FFDF7FBD2DE9F047DFF8FC93E6
+:1095C0000546002799F8000010B10820BDE8F08793
+:1095D00028460BF01BF808B11020F7E7F84C20786C
+:1095E00008B9FFF76CFCA07A617A0844C6B200F0B3
+:1095F00064FAB04207D2301AC1B22A460020FFF7FF
+:1096000083FC0700E2D1D9F804004E46C01C20F0CC
+:109610000300C9F8040000F040FB716800EB01088A
+:1096200001214046FFF70AFB06462968404488426C
+:1096300002D8B6F5803F15D328600020FFF786FCDE
+:1096400005000DD005F11300D9F8041020F0030037
+:109650004E46884200D0FFDF6078401E6070756023
+:109660000420B3E700214046FFF7E8FA0446A6428B
+:1096700000D0FFDF04EB0801C9F8041029604FF6A1
+:10968000FF71A9F80210012189F8001038469DE702
+:109690002DE9F0410446C94817460E46007810B13E
+:1096A0000820BDE8F08108460AF08AFF08B11020C2
+:1096B000F7E7C34D287808B9FFF701FC601E1E28A4
+:1096C00007D8012C22D13078FE281FD82877002017
+:1096D000E7E7A4F120001F2805D8E0B23A4631465A
+:1096E000BDE8F04144E4A4F140001F2805D831460C
+:1096F0002046BDE8F04100F0A3BAA4F1A0001F2865
+:1097000004D80020A02C03D0A12C06D00720C8E745
+:10971000317801F001016977C3E731680922F8293E
+:1097200001D38B0701D01046BBE76B7C03F003032A
+:10973000012B04D16B8BD7339CB28C42F3D82962B6
+:10974000AFE72DE9F04781460E4608460AF05EFF76
+:1097500048B948460AF078FF28B909F1030020F01B
+:109760000301494501D0102030E795484FF0000A29
+:109770004430817869B14178804600EB4114083467
+:10978000378832460021204600F040FA050004D018
+:1097900027E0A6F800A0052018E7B9F1000F24D0B3
+:1097A0003088B84201D90C251FE0607800F0070529
+:1097B000284600F017FA08EB0507324697F8E8014B
+:1097C0004946401C87F8E801204607F5F47700F089
+:1097D0001DFA05463878401E3870032000F002FA62
+:1097E0002DB10C2D01D0A6F800A02846EEE6607839
+:1097F000724E00F00701012923D002290CD0032961
+:1098000033D0FFDF98F801104046491CC9B288F8F0
+:1098100001100F2934D035E0616821B1000702D46E
+:109820006088FFF72BFE98F8EA014746012802D12D
+:10983000707802F0DFFA97F9EA010428E2DBFFDF33
+:10984000E0E7616819B14022B06807F073F898F852
+:10985000E9014746032802D1707802F0CBFA97F964
+:10986000E9010428CEDBFFDFCCE7C00602D5608823
+:10987000FFF704FE98F9EB010628C3DBFFDFC1E721
+:1098800080F801A08178491E8170617801F007019C
+:1098900001EB080090F8E811491C80F8E811A4E7F2
+:1098A00070B50D4604460AF08BFE18B928460AF03A
+:1098B000ADFE08B1102070BD29462046BDE87040BD
+:1098C00008F031BF70B5044615460E4608460AF04A
+:1098D00077FE18B928460AF099FE08B1102070BD2D
+:1098E000022C03D0102C01D0092070BD2A4631462D
+:1098F000204608F03BFF0028F7D0052070BD70B56A
+:1099000014460D4606460AF05BFE38B928460AF0B2
+:109910007DFE18B920460AF097FE08B1102070BDF0
+:1099200022462946304608F040FF0028F7D007209D
+:1099300070BD3EB504460AF069FE08B110203EBD78
+:10994000684604F03FFEFFF795FB0028F7D19DF82D
+:1099500006002070BDF808006080BDF80A00A080F5
+:1099600000203EBD70B505460C4608460AF06CFE68
+:1099700020B93CB120680AF049FE08B1102070BD42
+:10998000A08828B121462846BDE87040FDF7BEBE3C
+:10999000092070BD70B504460D4608460AF010FE59
+:1099A00030B9601E1E2818D828460AF009FE08B1F2
+:1099B000102070BD022C05D9072070BD1C000020AE
+:1099C0009803002004B9FFDFF94800EB840050F849
+:1099D000041C2846BDE870400847A4F120001F2859
+:1099E00005D829462046BDE87040FAF790BCF02C17
+:1099F000E2D1A8680AF0E4FD0028D9D1284606F093
+:109A0000A6FABDE87040FFF735BB70B504460D46B9
+:109A100008460AF0FBFD30B9601E1E280DD8284606
+:109A20000AF0CEFD08B11020C7E7012C01D0022CAE
+:109A300001D10620C1E70720BFE7A4F120001F28BD
+:109A4000F9D829462046BDE87040FAF7B8BC06F0C0
+:109A50008BBC38B50446D748007B00F00105D9B966
+:109A6000F9F787FA0DB1226800E00022D248417868
+:109A7000C06804F09EFBD0481030C0788DF800001C
+:109A800010B1012802D004E0012000E000208DF890
+:109A90000000684604F010FE002D02D02068283037
+:109AA000206038BD30B5C34D04466878A04200D868
+:109AB000FFDF686800EB041030BD70B5BD480025BD
+:109AC0002C46467807E02046FFF7ECFF4078641C00
+:109AD0002844C5B2E4B2B442F5D128466DE72DE979
+:109AE000F0410C46064600F006F907463068C01CF7
+:109AF00020F00302326014BBAE483B4608212430FC
+:109B00000AF038FC002409E0082C10D2DFE804F049
+:109B1000060408080A040406A84804E0A84802E06D
+:109B2000A84800E0A8480AF045FC054600E0FFDF31
+:109B3000A54200D0FFDF641CE4B2082CE4D33068F7
+:109B400000EB07103060ACE5021D5143452900D2FF
+:109B500045210844C01CB0FBF2F0C0B270472DE9AB
+:109B6000FC5F064693484FF000088B464746444644
+:109B700090F8019022E02046FFF794FF050000D105
+:109B8000FFDF687869463844C7B22846FFF720F8F7
+:109B9000824601A92846FFF735F80346BDF80400C0
+:109BA0005246001D81B2BDF80000001D80B207F0D2
+:109BB000D9F86A78641C00FB0288E4B24C45DAD11B
+:109BC0003068C01C20F003003060BBF1000F00D0F3
+:109BD00000204246394607F0D3F831680844306027
+:109BE000BDE8FC9F7349443108710020C87070477C
+:109BF00070494431CA782AB10A7801EB4211083120
+:109C0000814201D001207047002070472DE9F041CA
+:109C100006460078154600F00F0400201080601EF4
+:109C20000F46052800D3FFDF61482A46103000EBBD
+:109C30008400394650F8043C3046BDE8F0411847EE
+:109C400070B50C46402802D0412806D120E0A0780B
+:109C500061780D18E178814201D90720ADE62078BE
+:109C6000012801D91320A8E6FF2D08D808F008FF25
+:109C700006460AF09CF8301A801EA84201DA12202B
+:109C80009BE64C482168816021790173002094E6AD
+:109C9000BDE87040084600F05EB82DE9F0470027A7
+:109CA000DFF810A13E463D46B9463C469AF8018091
+:109CB0000AE02046FFF7F6FE4178807B0E4410FB59
+:109CC0000155641CE4B27F1C4445F2D109EB8700C6
+:109CD000C6EBC60100EB81009AF8092000EB850174
+:109CE00001EBC2019AF80A209AF80B0001EBC201BD
+:109CF00001EB80006AE42DE9F047DFF8B890002618
+:109D0000344699F8090099F80A2099F8017002443C
+:109D1000D5B299F80B20104400F0FF0808E0204667
+:109D2000FFF7C0FE817B407811FB0066641CE4B243
+:109D3000BC42F4D199F8090099F80A102844284443
+:109D40004044401C01B1012108448419FF2C00D972
+:109D5000FFDFE0B23AE438B50446407800F0030093
+:109D6000012803D002280BD0072038BD606858B105
+:109D70000AF073FCD0B960680AF066FC20B915E0FF
+:109D800060680AF01DFC88B969462046FCF71EF998
+:109D90000028EAD1607800F00300022816D19DF86F
+:109DA000000098B160680AF04FFC78B1102038BD0F
+:109DB00054500200980300201C000020BD41000008
+:109DC0001FAC00005D2F0000AB2401006189F82961
+:109DD0000DD8208988420AD8607800F003020A482A
+:109DE000012A06D1D731026A89B28A4201D20920FA
+:109DF000DDE794E80E0000F1100585E80E000AB9D1
+:109E0000002101830020D2E7980300202DE9F041D2
+:109E1000074614468846084601F01CFD064608EB36
+:109E200088001C22796802EBC0000D18688C58B1BC
+:109E30004146384601F016FD014678680078C200B8
+:109E4000082305F120000CE0E88CA8B14146384613
+:109E500001F00FFD0146786808234078C20005F143
+:109E6000240006F0BEFD38B1062121726681D0E9DA
+:109E70000010C4E9031009E0287809280BD0052058
+:109E8000207266816868E060002028702046BDE886
+:109E9000F04101F0D5BC072020726681F4E72DE97E
+:109EA000F04116460D460746406801EB85011C222D
+:109EB00002EBC1014418204601F0FDFC40B1002135
+:109EC000708865F30F2160F31F4107200AF02CFB17
+:109ED00009202070324629463846BDE8F04195E712
+:109EE0002DE9F0410E46074600241C21F07816E0CB
+:109EF00004EB8403726801EBC303D25C6AB1FFF721
+:109F00008DFA050000D1FFDF6F802A4621463046DA
+:109F1000FFF7C5FF0120BDE8F081641CE4B2A04258
+:109F2000E6D80020F7E770B5064600241C21C0786B
+:109F30000AE000BF04EB8403726801EBC303D51889
+:109F40002A782AB1641CE4B2A042F3D8402070BD44
+:109F5000282128461AF07DFE7068808928812046D5
+:109F600070BD70B5034600201C25DC780DE000BFF5
+:109F700000EB80065A6805EBC6063244167816B127
+:109F8000128A8A4204D0401CC0B28442F0D84020D9
+:109F900070BDF0B5044600201C26E5780EE000BF39
+:109FA00000EB8007636806EBC7073B441F788F42CE
+:109FB00002D15B78934204D0401CC0B28542EFD8F6
+:109FC0004020F0BD0078032801D000207047012018
+:109FD00070470078022801D00020704701207047A8
+:109FE0000078072801D000207047012070472DE934
+:109FF000F041064688461078F1781546884200D32D
+:10A00000FFDF2C781C27641CF078E4B2A04201D852
+:10A01000201AC4B204EB8401706807EBC101084444
+:10A02000017821B14146884708B12C7073E7287840
+:10A03000A042E8D1402028706DE770B514460B8827
+:10A040000122A240134207D113430B8001230A22AD
+:10A05000011D06F090FC047070BD2DE9FF4F81B02A
+:10A060000878DDE90E7B9A4691460E4640072CD4CF
+:10A07000019806F03DFF040000D1FFDF07F104085E
+:10A0800020461FFA88F106F07CF8050000D1FFDFBA
+:10A09000204629466A4606F0C6FA0098A0F80370E2
+:10A0A000A0F805A0284606F06CFB017869F30601CC
+:10A0B0006BF3C711017020461FFA88F106F0A4F86F
+:10A0C00000B9FFDF019803F0E9FF06EB0900017F0B
+:10A0D000491C017705B0BDE8F08F2DE9F84F0E4619
+:10A0E0009A4691460746032106F0BEFD0446008DC0
+:10A0F000DFF8B485002518B198F80000B0421ED1F1
+:10A10000384606F0F5FE070000D1FFDF09F1040133
+:10A11000384689B206F035F8050010D03846294691
+:10A120006A4606F080FA009800210A460180817094
+:10A1300004F084F80098C01DCAF8000021E098F8E7
+:10A140000000B04216D104F1260734F8341F012074
+:10A1500000FA06F911EA090F00D0FFDF2088012379
+:10A1600040EA090020800A22391D384606F01EFC0C
+:10A17000067006E0324604F1340104F12600FFF7D0
+:10A180005CFF0A2188F800102846BDE8F88FFEB56C
+:10A1900014460D46064602AB0C220621FFF79DFF32
+:10A1A000002826D00299687812220A70801C487014
+:10A1B00008224A80A870208888806088C880A0888B
+:10A1C0000881E088488100240C20CDE900040523A3
+:10A1D000062229463046FFF740FF2146002266F35B
+:10A1E0001F41F02310460AF0F5F86878801C68706B
+:10A1F0000120FEBDFEB514460D460622064602AB02
+:10A200001146FFF76AFF002812D0029B132000219D
+:10A210001870A8785870022058809C800620CDE9DC
+:10A2200000010246052329463046FFF716FF0120AC
+:10A23000FEBD2DE9FE430C46804644E002AB0E22F3
+:10A2400007214046FFF749FF002841D060681C22E3
+:10A2500067788678BF1C06EB860102EBC1014518C2
+:10A2600002981421017047700A214180698A018196
+:10A27000E98A4181A9888180A9898181304601F0DC
+:10A28000E9FA029905230722C8806F70042028701C
+:10A2900000250E20CDE9000521464046FFF7DDFEF2
+:10A2A000294666F30F2168F31F41F023002207209F
+:10A2B0000AF090F86078FD49801C60706268204662
+:10A2C000921CFFF794FE606880784028B6D1012088
+:10A2D000BDE8FE83FEB50D46064638E002AB0E2211
+:10A2E00007213046FFF7F9FE002835D068681C23A7
+:10A2F000C17801EB810203EBC20284180298152297
+:10A300000270627842700A224280A2894281A28849
+:10A310008281084601F09EFA014602988180618A96
+:10A32000C180E18A0181A088B8B10020207000219D
+:10A330000E20CDE900010523072229463046FFF70C
+:10A340008CFE6A68DA492846D21CFFF750FE68681E
+:10A35000C0784028C2D10120FEBD0620E6E72DE9E5
+:10A36000FE430C46814644E0204601F08EFAD0B30D
+:10A3700002AB082207214846FFF7AFFE0028A7D00E
+:10A3800060681C2265780679AD1C06EB860102EB3D
+:10A39000C10147180298B7F8108006210170457076
+:10A3A00004214180304601F055FA01460298052308
+:10A3B0000722C180A0F804807D7008203870002535
+:10A3C000CDE9000521464846FFF747FE294666F3DA
+:10A3D0000F2169F31F41F0230022072009F0FAFF43
+:10A3E0006078801C60706268B2492046121DFFF7D9
+:10A3F000FEFD606801794029B6D1012068E72DE9AA
+:10A40000F34F83B00E4680E0304601F03EFA00285C
+:10A4100075D071681C2091F8068008EB880200EB6B
+:10A42000C2000C184146304601F023FA0146A078DC
+:10A43000C30070684078C20004F1240006F0EDFA11
+:10A4400007468088E18B401A80B2002581B3AA4676
+:10A45000218B814200D808468146024602AB072183
+:10A460000398FFF73AFE010028D0BAF1000F03D09D
+:10A47000029AB888022510808B46E28B3968A9EBD6
+:10A4800005001FFA80FA0A440398009206F030FD96
+:10A49000ED1D009A59465346009506F03EF9E08BB3
+:10A4A000504480B2E083B988884209D1012508E090
+:10A4B000FFE7801C4FF0010A80B2C9E7002009E6DF
+:10A4C0000025CDE90095238A072231460398FFF73E
+:10A4D000C4FDE089401EE0818DB1A078401CA070D1
+:10A4E0007068F178427811FB02F1CAB281690123E8
+:10A4F0000E3006F040FA80F800800020E083726899
+:10A500006D493046921DFFF772FD706881794029D0
+:10A510007FF47AAF0120DDE570B5064648680D4648
+:10A5200014468179402910D104EB84011C2202EBEE
+:10A53000C101084401F0E0F9002806D06868294606
+:10A5400084713046BDE8704059E770BDFEB50C46D9
+:10A550000746002645E0204601F097F9D8B3606829
+:10A560001C22417901EB810102EBC1014518688988
+:10A5700000B9FFDF02AB082207213846FFF7ADFD27
+:10A58000002833D00299607816220A70801C487027
+:10A59000042048806068407901F05CF90146029827
+:10A5A0000523072281806989C1800820CDE9000642
+:10A5B00021463846FFF751FD6078801C6070A889FD
+:10A5C00069890844B0F5803F00D3FFDFA889698915
+:10A5D0000844A8816E81626838492046521DFFF701
+:10A5E00006FD606841794029B5D10120FEBD30B536
+:10A5F000438C458BC3F3C704002345B1838B641E92
+:10A60000ED1AC38A6D1E1D4495FBF3F3E4B22CB121
+:10A61000008918B1A04200D8204603444FF6FF70CD
+:10A62000834200D3034613800C7030BD2DE9FC41FA
+:10A63000074616460D46486802EB86011C2202EBCF
+:10A64000C10144186A4601A92046FFF7D0FFA0893E
+:10A65000618901448AB2BDF80010914212D0081AF3
+:10A6600000D5002060816868407940280AD12046E2
+:10A6700001F038F9002805D0686829464671384647
+:10A68000FFF764FFBDE8FC812DE9FE4F8946804657
+:10A6900015465088032106F0E7FA8346B8F8020011
+:10A6A00040280DD240200CE030000020C59F000063
+:10A6B000D39F0000E19F0000F9B80000E5B800005A
+:10A6C000403880B282460146584601F0DEF8002844
+:10A6D0007ED00AEB8A001C22DBF8041002EBC000DB
+:10A6E0000C18204601F0E7F8002877D1B8F80000F0
+:10A6F000E18A88423CD8A189D1B348456ED1002671
+:10A700005146584601F0AEF8218C0F18608B48B9BD
+:10A71000B9F1020F62D3B8F804006083618A8842FD
+:10A7200026D80226A9EB06001FFA80F9B888A28B6A
+:10A73000801A002814DD4946814500DA084683B2B4
+:10A7400068886968029139680A44CDE9003206F0E8
+:10A75000BDFBDDE90121F61D009B009605F0A9FF78
+:10A76000A18B01EB090080B2A083618B884207D9DD
+:10A77000688803B052465946BDE8F04F01F0D9B899
+:10A780001FD14FF009002872B8F802006881D7E99C
+:10A790000001C5E90401608BA881284601F050F84A
+:10A7A0005146584601F05EF80146DBF804000823E4
+:10A7B0000078C20004F1200006F013F90020A08305
+:10A7C0006083A0890AF0FF02401EA081688800E033
+:10A7D00004E003B05946BDE8F04F27E7BDE8FE8F1F
+:10A7E0002DE9F041064615460F461C46184609F06D
+:10A7F000E7FE18B9206809F009FF08B1102015E438
+:10A800007168688C0978B0EBC10F01D313200DE497
+:10A810003946304601F026F8014670680823007872
+:10A82000C20005F1200006F0A6F8D4E90012C0E944
+:10A8300000120020E3E710B50446032106F014FAE5
+:10A840000146007800F00300022805D02046BDE84C
+:10A85000104001F114029AE48A8A2046BDE81040B3
+:10A86000C8E470B50446032106F0FEF9054601462A
+:10A870002046FFF774FD002816D029462046FFF732
+:10A8800065FE002810D029462046FFF723FD00284A
+:10A890000AD029462046FFF7CCFC002804D02946E0
+:10A8A0002046BDE87040AAE570BD2DE9F0410C4698
+:10A8B00080461EE0E178427811FB02F1CAB281695C
+:10A8C00001230E3006F08DF8077860681C22C179EC
+:10A8D000491EC17107EB8701606802EBC101461890
+:10A8E0003946204600F0D1FF18B1304600F0DCFFB9
+:10A8F00020B16068C1790029DCD180E7FEF78EFDC8
+:10A90000050000D1FFDF0A202872384600F0A2FFC0
+:10A9100068813946204600F0ACFF01466068082394
+:10A920004078C20006F1240006F05BF8D0E9001080
+:10A93000C5E90310A5F80280284600F081FFB07831
+:10A9400000B9FFDFB078401EB07058E770B50C4614
+:10A950000546032106F088F901464068C279224481
+:10A96000C2712846BDE870409FE72DE9FE4F824640
+:10A97000507814460F464FF0000800284FD00128A9
+:10A9800007D0022822D0FFDF2068B8606068F86036
+:10A9900024E702AB0E2208215046FFF79EFB002859
+:10A9A000F2D00298152105230170217841700A2107
+:10A9B0004180C0F80480C0F80880A0F80C8062884C
+:10A9C00082810E20CDE90008082221E0A6783046D9
+:10A9D00000F040FF054606EB86012C22786802EB6A
+:10A9E000C1010822465A02AB11465046FFF775FBDB
+:10A9F0000028C9D0029807210170217841700421F4
+:10AA0000418008218580C680CDE9001805230A46CB
+:10AA100039465046FFF721FB87F80880DEE6A67826
+:10AA2000022516B1022E13D0FFDF2A1D914602AB7C
+:10AA300008215046FFF751FB0028A5D002980121BC
+:10AA4000022E0170217841704580868002D005E099
+:10AA50000625EAE7A188C180E1880181CDE9009857
+:10AA60000523082239465046D4E710B50446032191
+:10AA700006F0FAF8014600F108022046BDE8104051
+:10AA800073E72DE9F05F0C4601281DD0957992F807
+:10AA90000480567905EB85011F2202EBC10121F0EC
+:10AAA000030B08EB060111FB05F14FF6FF7202EAFA
+:10AAB000C10909F1030115FB0611F94F21F0031A31
+:10AAC00040B101283DD124E06168E57891F800802B
+:10AAD0004E78DFE75946786805F001FF606000B9FD
+:10AAE000FFDF594660681AF0D6F8E570514678687D
+:10AAF00005F0F5FE6168486100B9FFDF60684269F2
+:10AB000002EB09018161606880F80080606846702E
+:10AB100017E0606852464169786805F00BFF5A46B5
+:10AB20006168786805F006FF032006F045F80446E2
+:10AB3000032006F049F8201A012802D1786805F0B0
+:10AB4000C3FE0BEB0A00BDE8F09F02460021022085
+:10AB500097E773B5D24D0A202870009848B10024B9
+:10AB60004FEA0D0005F09DFE002C01D100996960AF
+:10AB70007CBD01240020F5E770B50C461546382150
+:10AB800020461AF088F8012666700A2104F11C009C
+:10AB90001AF081F805B9FFDF297A207861F3010006
+:10ABA0002070A879002817D02A4621460020FFF7F8
+:10ABB00068FF6168402088706168C87061680871CA
+:10ABC0006168487161688871616828880881616876
+:10ABD000688848816068868170BDC878002802D086
+:10ABE000002201204DE7704770B50546002165F34E
+:10ABF0001F41002009F098FC0321284606F034F894
+:10AC0000040000D1FFDF21462846FFF769F900283C
+:10AC100004D0207840F010002070012070BD2DE994
+:10AC2000FF4180460E460F0CFEF7F8FB050007D0EB
+:10AC30006F800321384606F017F8040008D106E0BB
+:10AC400004B03846BDE8F0411321F9F7F9BEFFDF43
+:10AC50005FEA080005D0B8F1070F18D0FFDFBDE8A4
+:10AC6000FF8120782A4620F0080020700020ADF8EF
+:10AC7000020002208DF800004FF6FF70ADF80400CE
+:10AC8000ADF8060069463846F9F7EDFAE7E7C6F38E
+:10AC9000072101EB81021C23606803EBC202805C88
+:10ACA000042803D008280AD0FFDFD8E7012000904D
+:10ACB0004FF440432A46204600F004FECFE704B09C
+:10ACC0002A462046BDE8F041FFF7E9B82DE9F05FDC
+:10ACD0000027B0F80A9090460C4605463E46B9F16A
+:10ACE000400F01D2402001E0A9F140001FFA80FA94
+:10ACF000287AC01E08286BD2DFE800F00D04192066
+:10AD000058363C4772271026002C6CD0D5E9030139
+:10AD1000C4E902015CE070271226002C63D00A22ED
+:10AD200005F10C0104F1080019F059FF50E07127FA
+:10AD30000C26002C57D0E868A06049E07427102644
+:10AD40009CB3D5E90301C4E902016888032105F039
+:10AD50008BFF8346FEF762FB0246688850805146AF
+:10AD60005846FFF753F833E075270A26ECB1A88957
+:10AD700020812DE076271426BCB105F10C0004F1EA
+:10AD8000080307C883E8070022E07727102664B18C
+:10AD9000D5E90301C4E902016888032105F064FFD5
+:10ADA00001466888FFF781FD12E01CE07327082642
+:10ADB000CCB16888032105F057FF01460078C00632
+:10ADC00006D56888FFF78CF810B96888F8F71BFE7D
+:10ADD000A8F800602CB12780A4F8069066806888E7
+:10ADE000A0800020AFE6A8F80060FAE72DE9FC415A
+:10ADF0000C461E4617468046032105F035FF0546E2
+:10AE00000A2C0AD2DFE804F0050505050505090945
+:10AE10000907042303E0062301E0FFDF0023CDE957
+:10AE20000076224629464046FFF717F92AE438B54E
+:10AE30000546A0F57F40FF3830D0284606F046F89A
+:10AE4000040000D1FFDF204605F0CBFB002815D021
+:10AE500001466A46204605F0E6FB00980321B0F85B
+:10AE60000540284605F000FF0546052C03D0402C80
+:10AE700005D2402404E0007A80B1002038BD403C77
+:10AE8000A4B2214600F001FD40B1686804EB8401E2
+:10AE90003E2202EBC101405A0028EFD0012038BD0C
+:10AEA000300000202DE9F04F044689B0408806F0BC
+:10AEB0000DF8050000D1FFDF06AA2846616800F002
+:10AEC000BDFC069D001F81B235F8032F6B888A42B6
+:10AED00005D1042B0AD0052B1DD0062B15D02246F8
+:10AEE0002846FFF7D1FB09B0BDE8F08F16462D1DAF
+:10AEF000224629463046F7F750FA0828F3D1224671
+:10AF000029463046FCF749FCEDE76088291D636857
+:10AF1000FAF7C8FCE7E717466088032105F0A4FEAE
+:10AF20004FF000088DF804800646ADF80680042F27
+:10AF3000D9D36A79002AD6D028794FF6FF794FF015
+:10AF40001C0A13282CD008DC012878D0062847D00A
+:10AF5000072875D0122874D106E0142872D015285D
+:10AF600071D016286DD1ACE10C2F6AD1307800F089
+:10AF70000301022965D140F0080030706879B07093
+:10AF800001208DF804002889ADF808006889ADF823
+:10AF90000A00A889ADF80C00E889ADF80E0019E0A8
+:10AFA000B07890429FD1307801079CD5062F9AD176
+:10AFB00020F0080030706088414660F31F41002097
+:10AFC00009F0B2FA02208DF80400ADF80890288943
+:10AFD000ADF80A006088224601A9F9F744F982E732
+:10AFE000082F80D12F89B5F80A90402F01D2402038
+:10AFF00001E0A7F1400080B280460146304600F0F3
+:10B0000044FC08B3716808EB88002C2202EBC000F6
+:10B01000095A4945E3D1FE4807AAD0E90210CDE913
+:10B02000071068798DF81C0008F0FF058DF81E5098
+:10B0300060883146FFF799FC2246294639E0B6E0A0
+:10B0400014E03CE039E0E6E0F148D0E90010CDE959
+:10B0500007106879ADF820708DF81C00ADF82290CB
+:10B06000608807AA3146FFF780FC3CE7082FB6D17D
+:10B070006889B5F80880402801D2402000E04038B7
+:10B0800087B23946304600F000FC0028A7D007EB15
+:10B09000870271680AEBC2000844028A42459ED1C9
+:10B0A000017808299BD140786979884297D1F9B213
+:10B0B00022463046FEF7F3FE15E70E2F07D0CDF8F7
+:10B0C0001C80CDF8208068798DF81C00C8E769895C
+:10B0D000EF898B46B5F80C903046FEF742FFABF196
+:10B0E0004001402901D309204AE0B9F1170F01D3EB
+:10B0F000172F01D20B2043E040280ED000EB800236
+:10B1000071680AEBC20008440178012903D1407834
+:10B1100069798842A9D00A2032E03046FEF703FF61
+:10B12000014640282BD001EB810372680AEBC30073
+:10B1300002EB0008012288F800206A7988F80120D3
+:10B1400070682A894089B84200D938462D8A03237D
+:10B150002372A282E7812082A4F80C9065820846BF
+:10B1600000F078FB6081A8F81490A8F81870A8F88F
+:10B170000E50A8F810B0204600F062FBB3E60420A1
+:10B1800005212172A4F80A80E08101212173A049E0
+:10B19000D1E90421CDE9072169798DF81C10ADF8BA
+:10B1A0001E00608807AA3146FFF7DFFBE3E7062FA2
+:10B1B000E4D3B078904215D13078010712D520F051
+:10B1C000080030706088414660F31F41002009F09C
+:10B1D000ABF902208DF804002889ADF80800ADF81D
+:10B1E0000A90F7E604213046FEF7D3FE05464028D4
+:10B1F000C4D002208303009022462946304600F046
+:10B2000061FB4146608865F30F2160F31F41072011
+:10B2100009F08AF967E60E2FB0D104213046FEF717
+:10B22000B8FE81464028A9D04146608869F30F21C5
+:10B2300060F31F41072009F077F9288A0790E88911
+:10B2400000907068AF894089B84200D9384683467B
+:10B25000B5F80A8028890590484600F0FBFA60811D
+:10B26000079840B10220079B00902246494630468D
+:10B2700000F028FB37E6B8F1170F1ED3172F1CD3A9
+:10B280000420207200986082E781A4F810B0A4F82E
+:10B290000C8009EB890271680AEBC2000D18009955
+:10B2A0000598A5F81480A5F818B0E98128822046F1
+:10B2B00000F0C6FA0620287015E601200B23009046
+:10B2C000D3E7082FA6D129893046FEF74AFE074664
+:10B2D00040289FD007EB870271680AEBC200084440
+:10B2E000804600F0E8FA002894D16D89B8F80E0085
+:10B2F0002844B0F5803F05D360883A46314600F0D7
+:10B3000018FBF0E5002D85D0A8F80E0060883A46BD
+:10B310003146FFF701F908202072384600F09AFA0A
+:10B320006081A58127E770B50D460646032105F02B
+:10B330009BFC040004D02078000704D5112070BDC8
+:10B3400043F2020070BD2A4621463046FEF71FFF39
+:10B3500018B9286860616868A061207840F008002A
+:10B360002070002070BD70B50D460646032105F023
+:10B370007BFC040004D02078000704D4082070BDB2
+:10B3800043F2020070BD2A4621463046FEF732FFE6
+:10B3900000B9A582207820F008002070002070BD40
+:10B3A0002DE9F04F0E4691B08046032105F05CFC7C
+:10B3B0000446404605F09CFD074600200790089093
+:10B3C0000990ADF830000A9002900390049004B9FF
+:10B3D000FFDF0DF1080917BBFFDF20E038460BA99E
+:10B3E000002204F0C1FF9DF82C0000F07F050A2D1B
+:10B3F00000D3FFDF6019017F491E01779DF82C0003
+:10B4000000060CD52A460CA907A8FEF716FE01E097
+:10B410007C50020019F80510491C09F80510761E29
+:10B42000F6B2DBD204F13400FA4D04F1260BDFF85A
+:10B43000E8A304F12A07069010E05846069900F0A8
+:10B440006AFA064628700A2800D3FFDF5AF8261049
+:10B4500040468847E08CC05DB04202D0208D002875
+:10B46000EBD10A202870EC4D4E4628350EE00CA991
+:10B4700007A800F050FA0446375D55F8240000B9DB
+:10B48000FFDF55F82420394640469047BDF81E009E
+:10B490000028ECD111B027E510B5032105F0E4FB3D
+:10B4A000040000D1FFDF0A2104F11C0019F0F3FBB6
+:10B4B000207840F00400207010BD10B50C46032128
+:10B4C00005F0D2FB2044007F002800D0012010BDF1
+:10B4D0002DE9F84F894615468246032105F0C4FB45
+:10B4E000070004D0284609F06BF840B903E043F2A6
+:10B4F0000200BDE8F88F484609F088F808B110202E
+:10B50000F7E7786828B169880089814201D9092064
+:10B51000EFE7B9F800001C2418B1402809D24020F8
+:10B5200008E03846FEF7FFFC8046402819D113207A
+:10B53000DFE7403880B280460146384600F0A5F982
+:10B5400048B108EB8800796804EBC000085C01286A
+:10B5500003D00820CDE70520CBE7FDF75FFF06000D
+:10B560000BD008EB8800796804EBC0000C18B9F820
+:10B57000000020B1E88910B113E01120B9E7288854
+:10B58000172802D36888172801D20720B1E7686816
+:10B5900038B12B1D224641463846FFF721F90028D5
+:10B5A000A7D104F10C0269462046FFF720F828884D
+:10B5B00060826888E082B9F8000030B10220207013
+:10B5C000E889A080E889A0B12BE003202070A88939
+:10B5D000A08078688178402905D180F802803946BA
+:10B5E0005046FEF726FE404600F034F9A9F8000068
+:10B5F00021E07868218B4089884200D90846208361
+:10B60000A6F802A004203072B9F800007081E08929
+:10B610007082F181208B3082A08AB081304600F0A8
+:10B620000FF97868C178402905D180F80380394640
+:10B630005046FEF74FFE00205BE770B50D4606460C
+:10B64000032105F011FB040003D0402D04D2402556
+:10B6500003E043F2020070BD403DADB2294600F068
+:10B6600014F958B105EB85011C22606802EBC10199
+:10B67000084400F020F918B1082070BD052070BD05
+:10B680002A462146304600F054F9002070BD2DE9CD
+:10B69000F0410D4616468046032105F0E5FA0446C2
+:10B6A000402D01D2402500E0403DADB28CB129468D
+:10B6B00000F0EBF880B105EB85011C22606802EB1D
+:10B6C000C1014718384600F0F6F838B10820BDE847
+:10B6D000F08143F20200FAE70520F8E733463A46E4
+:10B6E00029462046FFF77CF80028F0D1EAB221462F
+:10B6F0004046FEF79BFF0020E9E72DE9F0410D46AB
+:10B7000016468046032105F0AFFA0446402D01D2CB
+:10B71000402500E0403DAFB224B1304608F050FF74
+:10B7200038B902E043F20200D1E7306808F048FF80
+:10B7300008B11020CBE73946204600F0A6F860B1EA
+:10B7400007EB87011C22606802EBC10145182846FF
+:10B7500000F0B1F818B10820B9E70520B7E7B088C4
+:10B76000A98A884201D90C20B1E76168E88C497840
+:10B77000B0EBC10F01D31320A9E73946204600F0F2
+:10B7800078F80146606808234078C20005F124007B
+:10B7900005F0F1F8D6E90012C0E90012FAB221462C
+:10B7A0004046FEF7B9FE002091E72DE9F0470D462F
+:10B7B0001F4690468146032105F056FA0446402D67
+:10B7C00001D2402001E0A5F1400086B23CB14DB16C
+:10B7D000384608F039FF50B11020BDE8F08743F239
+:10B7E0000200FAE76068C8B1A0F80C8024E0314696
+:10B7F000204600F04AF888B106EB86011C226068FA
+:10B8000002EBC1014518284600F055F840B1082068
+:10B81000E3E7000030000020945002000520DCE740
+:10B82000A5F80880F2B221464846FEF7FFFE1FB198
+:10B83000A8896989084438800020CEE704F0F3BE67
+:10B84000017821F00F01491C21F0F0011031017045
+:10B85000FDF7E7BD10B50446402800D9FFDF4034AE
+:10B86000A0B210BD406842690078484302EBC000B6
+:10B870007047C2784068037812FB03F2437840694E
+:10B8800001FB032100EBC1007047C2788A4209D94D
+:10B89000406801EB81011C2202EBC101405C08B150
+:10B8A00001207047002070470078062801D9012048
+:10B8B0007047002070470078062801D001207047AB
+:10B8C00000207047F0B401EB81061C27446807EBA9
+:10B8D000C6063444049D05262670E3802571F0BC1D
+:10B8E000FEF794BA10B5418911B1FFF7DDFF08B139
+:10B8F000002010BD012010BD10B5C18C8278B1EBC5
+:10B90000C20F04D9C18911B1FFF7CEFF08B10020E1
+:10B9100010BD012010BD10B50C4601230A22011DE7
+:10B9200005F05FF800782188012282409143218050
+:10B9300010BDF0B402EB82051C264C6806EBC50571
+:10B94000072363554B681C79402C03D11A71F0BC56
+:10B95000FEF705BDF0BC704710B5EFF3108000F0A6
+:10B96000010472B6F7484178491C417040780128BB
+:10B9700001D1F7F709FB002C00D162B610BD70B5FC
+:10B98000F04CE07848B90125E570FFF7E5FFF7F7DF
+:10B9900003FB20B1002008F058FA002070BD4FF0E2
+:10B9A00080406571C0F80453F7E770B5EFF310807D
+:10B9B00000F0010572B6E34C607800B9FFDF6078F3
+:10B9C000401E6070607808B9F7F7E2FA002D00D1E8
+:10B9D00062B670BDDB4810B5C17821B1002141715C
+:10B9E000C170FFF7E2FF002010BD10B50446F7F765
+:10B9F000D3FAD449C978084000D001202060002043
+:10BA000010BD2DE9F05FDFF83C934278817889F82A
+:10BA10000620002589F80710064689F808500078A6
+:10BA20002F4620B101280FD002280FD0FFDFF7F7F3
+:10BA3000C0FA98B1F7F7C4FAA8420FD12846F7F731
+:10BA4000C3FA0028FAD047E00125F0E7FFF784FFAA
+:10BA5000F7F7A2FA0028FBD00225E8E701208407C7
+:10BA6000E060C4F80471B8490D600107D1F84412D0
+:10BA7000B54AC1F3423124321160B3493431086010
+:10BA80004FF0020BC4F804B3A060DFF8C0A2DAF8EC
+:10BA90000010C94341F3001101F10108DAF8001068
+:10BAA00041F01001CAF8001000E020BFD4F80401F2
+:10BAB0000028FAD02846F7F787FA0028FAD0B8F11C
+:10BAC000000F05D1DAF8001021F01001CAF80010BB
+:10BAD000C4F808B3C4F8047199F807004C4670B173
+:10BAE000307860B9F7F758FA064608F00BFB6FF0AC
+:10BAF000004116B1C4E9031001E0C4E9030115B126
+:10BB00002771BDE8F09F01202071BDE8F05F00F0D3
+:10BB1000D9B870B5050000D1FFDF4FF080424FF07B
+:10BB2000FF30C2F808030021C2F80011C2F8041166
+:10BB3000C2F80C11C2F81011824C6170F7F732FA9A
+:10BB400010B10120E07060702846BDE8704058E7F1
+:10BB50002DE9FE4F7E4800687D4A7E49083211601B
+:10BB60008C070290D4F8080108B1012600E00026F5
+:10BB7000D4F8240100B101208146D4F81C0100B1A1
+:10BB800001208346D4F8200100B101200190D4F8AF
+:10BB9000000110B14FF0010801E04FF00008D4F8A7
+:10BBA000040108B1012700E00027D4F80C0100B11E
+:10BBB00001200090D4F8100108B1012100E000211B
+:10BBC0008A4646EA080127EA01000099884320EAEC
+:10BBD0000A0020EA090030EA0B0000D0FFDF002550
+:10BBE00026B1C4F80851012008F02FF9B9F1000F6F
+:10BBF00004D0C4F82451092008F027F9BBF1000F44
+:10BC000004D0C4F81C510A2008F01FF9019820B193
+:10BC1000C4F820510B2008F018F9DFF83C91494E88
+:10BC20004FF0010BB8F1000F11D0C4F8005170793A
+:10BC300018B17571002008F008F9307838B1357006
+:10BC400086F802B00222C9F80020C4F810B00FB183
+:10BC5000C4F80451009858B1C4F80C51B07800B938
+:10BC6000FFDFC9F80050B570C4F814B0FFF79DFEAF
+:10BC7000BAF1000F05D0C4F81051307908B100F0C6
+:10BC800045F833490298091D0860BDE8FE8F70B57C
+:10BC90002C4DE87808B9F7F77BF901208407A061FB
+:10BCA000A87850B1D4F80C0120B90020F7F78CF92E
+:10BCB0000028F7D10020C4F80C014FF0FF30C4F881
+:10BCC000080370BD2DE9F0411926B407C4F80863D4
+:10BCD0000125A5610020C4F80001C4F80C01C4F8D6
+:10BCE0001001F7F759F9174F28B11B49BD70022011
+:10BCF0000860256100E03D70FFF72EFE1249B8791B
+:10BD000020310860C4F80463BDE8F0812DE9F041FA
+:10BD10000C4C4FF080470125E07940B3012803D057
+:10BD2000217A401E814224DAF7F736F9064608F0F8
+:10BD3000E9F9E179012902D9217A491C21726EB110
+:10BD400021690CE03C0000201805004010ED00E0E7
+:10BD50001005024001000001340C0040E168411A66
+:10BD6000022902DA11F1020F0EDC0EB1206100E0AF
+:10BD7000E060FFF7F1FDF7F70FF938B10549022050
+:10BD800008603D61A57002E07D61BDE7257000207F
+:10BD90002072B9E7340C00404FF0E0214FF0007002
+:10BDA000C1F88001C1F88002384B802283F800245A
+:10BDB000C1F80001704700B502460420344903E091
+:10BDC00001EBC0031B792BB1401EC0B2F8D2FFDFDC
+:10BDD000FF2000BD41F8302001EBC00100224A7174
+:10BDE0008A7101220A7100BD294A002102EBC000BC
+:10BDF0000171704710B50446042800D3FFDF2448C2
+:10BE000000EBC4042079012800D0FFDF6079A1791C
+:10BE1000401CC0B2814200D060714FF0E0214FF071
+:10BE20000070C1F8000210BD2DE9F0411948056805
+:10BE300018491948083108601448042690F800048D
+:10BE4000134F4009154C042818D0FFDF16E0217865
+:10BE500007EBC1000279012A08D1427983799A421D
+:10BE600004D04279827157F8310080472078401C15
+:10BE7000C0B22070042801D300202070761EF6B2D4
+:10BE8000E5D20448001D0560BDE8F08119E000E03E
+:10BE9000C8050020100502400100000150000020EC
+:10BEA000F8B51D46DDE906470E000AD005F020F87A
+:10BEB0002346FF1DBCB231462A46009404F02DFCF7
+:10BEC000F8BDD0192246194618F044FE2046F8BDA8
+:10BED00070B50D460446102118F0BBFE25811720D1
+:10BEE0006081A07B40F00A00A07370BD4FF6FF7226
+:10BEF0000A800146022008F017BB7047008970478E
+:10BF0000827BD30701D1920703D480890880002067
+:10BF1000704705207047827B920700D5818170476A
+:10BF200001460020098841F6FE52114200D001204E
+:10BF3000704700B50346807BC00701D0052000BDD7
+:10BF400059811846FFF7ECFFC00703D0987B40F0FB
+:10BF500004009873987B40F001009873002000BDA6
+:10BF6000827B520700D509B140897047172070477E
+:10BF7000827B61F3C302827370472DE9FC5F0E463A
+:10BF8000044601789646012000FA01F14DF6FF5271
+:10BF900001EA020962684FF6FF7B1188594502D118
+:10BFA0000920BDE8FC9FB9F1000F05D041F6FE5510
+:10BFB000294201D00120F4E741EA090111801D0066
+:10BFC00014D04FF0000C85F800C02378052103221F
+:10BFD00067464FF0020A0E2B74D2DFE803F0F8092F
+:10BFE000252F47626974479092B3D0D70420D8E7D1
+:10BFF000616820898B7B9B077DD5172848D30B89E7
+:10C00000834245D38989172901D3814240D185F8DC
+:10C0100000A0A5F801003280616888816068817B9A
+:10C0200021F002018173C5E0042028702089A5F861
+:10C0300001006089A5F803003180BBE0208A3188C7
+:10C04000C01D1FFA80F8414522D3062028702089A0
+:10C05000A5F801006089A5F80300A089A5F80500EE
+:10C060000721208ACDE9000163693EE0082B10D04A
+:10C07000082028702089A5F801006089A5F8030030
+:10C0800031806A1D694604F10C0006F08EFB10B188
+:10C090005FE01020EDE730889DF800100844308004
+:10C0A00088E00A2028702089A5F80100328045E048
+:10C0B0000C2028702089A5F801006089A5F80300EC
+:10C0C00031803BE083E02189338800EB41021FFA95
+:10C0D00082F843453DD3B8F1050F3AD30E222A70BA
+:10C0E0000BEA4101CDE90010E36860882A467146F9
+:10C0F000FFF7D6FE00E04DE0A6F800805AE04020B1
+:10C10000287060893188C01C1FFA80F8414520D30F
+:10C110002878714620F03F00123028702089A5F859
+:10C1200001006089CDE9000260882A46E368FFF7D4
+:10C13000B7FEA6F80080287840063BD461682089C5
+:10C14000888037E0A0893288401D1FFA80F8424578
+:10C1500001D204273EE0162028702089A5F80100AE
+:10C160006089A5F80300A089CDE9000160882A460E
+:10C1700071462369FFF794FEA6F80080DEE71820D9
+:10C180002870207A6870A6F800A013E061680A8819
+:10C19000920401D405271DE0C9882289914201D06B
+:10C1A000062717E01E21297030806068018821F47D
+:10C1B00000510180B9F1000F0CD061887823002272
+:10C1C000022008F007F961682078887007E0A6F877
+:10C1D00000C003276068018821EA09010180384610
+:10C1E000DFE62DE9FF4F85B01746129C0D001E4675
+:10C1F0001CD03078C10703D000F03F00192801D9C6
+:10C20000012100E000212046FFF7AAFEA8420DD33D
+:10C210002088A0F57F41FF3908D03078410601D44D
+:10C22000000605D5082009B0BDE8F08F0720FAE721
+:10C2300000208DF800008DF8010030786B1E00F0B2
+:10C240003F0C0121A81E4FF0050A4FF002094FF0E4
+:10C25000030B9AB2BCF1200F75D2DFE80CF08B1003
+:10C26000745E7468748C749C74B674BB74C974D531
+:10C2700074E2747474F274F074EF74EE748B052DC0
+:10C2800078D18DF80090A0788DF804007088ADF812
+:10C29000060030798DF80100707800F03F000C281E
+:10C2A00029D00ADCA0F10200092863D2DFE800F0FF
+:10C2B000126215621A621D622000122824D004DC6A
+:10C2C0000E281BD01028DBD11BE016281FD0182801
+:10C2D000D6D11FE02078800701E0207840070028B1
+:10C2E00048DAEFE020780007F9E72078C006F6E7A3
+:10C2F00020788006F3E720784006F0E720780006F3
+:10C30000EDE72088C005EAE720884005E7E72088B8
+:10C310000005E4E72088C004E1E72078800729D5FC
+:10C32000032D27D18DF800B0B6F8010082E0217806
+:10C3300049071FD5062D1DD381B27078012803D07F
+:10C34000022817D102E0CAE0022000E010200422F7
+:10C350008DF8002072788DF80420801CB1FBF0F27B
+:10C36000ADF8062092B242438A4203D10397ADF85A
+:10C370000890A7E07AE02078000777D598B2820885
+:10C380008DF800A0ADF80420B0EB820F6ED10297BB
+:10C39000ADF8061096E02178C90667D5022D65D361
+:10C3A00081B206208DF80000707802285ED300BFAD
+:10C3B000B1FBF0F28DF80400ADF8062092B24243D2
+:10C3C0008A4253D1ADF808907BE0207880064DD5A5
+:10C3D000072003E0207840067FD508208DF8000074
+:10C3E000A088ADF80400ADF80620ADF8081068E0AC
+:10C3F0002078000671D50920ADF804208DF80000E2
+:10C40000ADF8061002975DE02188C90565D5022DBB
+:10C4100063D381B20A208DF80000707804285CD3C1
+:10C42000C6E72088400558D5012D56D10B208DF840
+:10C430000000A088ADF8040044E021E026E016E00A
+:10C44000FFE72088000548D5052D46D30C208DF840
+:10C450000000A088ADF80400B6F803006D1FADF829
+:10C460000850ADF80600ADF80AA02AE035E02088B3
+:10C47000C00432D5012D30D10D208DF8000021E00F
+:10C480002088800429D4B6F80100E080A07B000752
+:10C4900023D5032D21D3307800F03F001B2818D07E
+:10C4A0000F208DF80000208840F40050A4F8000010
+:10C4B000B6F80100ADF80400ED1EADF80650ADF879
+:10C4C00008B0039769460598F5F7B2FC050008D057
+:10C4D00016E00E208DF80000EAE7072510E0082599
+:10C4E0000EE0307800F03F001B2809D01D2807D04F
+:10C4F0000220059908F018F8208800F400502080E8
+:10C50000A07B400708D52046FFF70AFDC00703D1EE
+:10C51000A07B20F00400A073284684E61FB5022803
+:10C5200006D101208DF8000088B26946F5F780FC3D
+:10C530001FBD0000F8B51D46DDE906470E000AD014
+:10C5400004F0D6FC2346FF1DBCB231462A460094B7
+:10C5500004F0E3F8F8BDD0192246194618F0FAFAAB
+:10C560002046F8BD2DE9FF4F8DB09B46DDE91B57F6
+:10C57000DDF87CA00C46082B05D0E06901F002F93B
+:10C5800050B11020D2E02888092140F01000288006
+:10C590008AF80010022617E0E16901208871E2693B
+:10C5A0004FF420519180E1698872E06942F60101FF
+:10C5B0000181E069002181732888112140F0200069
+:10C5C00028808AF80010042638780A900A203870EB
+:10C5D0004FF0020904F118004D460C9001F095FB54
+:10C5E000B04681E0BBF1100F0ED1022D0CD0A9EBAB
+:10C5F0000800801C80B20221CDE9001005AB524634
+:10C600001E990D98FFF796FFBDF816101A988142F3
+:10C6100003D9F74800790F9004E003D10A9808B1D4
+:10C6200038702FE04FF00201CDE900190DF116032B
+:10C6300052461E990D98FFF77DFF1D980088401BFC
+:10C64000801B83B2C6F1FF00984200D203461E99B8
+:10C650000BA8D9B15FF00002DDF878C0CDE9032066
+:10C6600009EB060189B2CDE901C10F980090BDF830
+:10C67000161000220D9801F0CBFB387070B1C0B2DB
+:10C68000832807D0BDF8160020833AE00AEB0901A1
+:10C690008A19E1E7022011B0BDE8F08FBDF82C0047
+:10C6A000811901F0FF08022D0DD09AF801204245B2
+:10C6B00006D1BDF82010814207D0B8F1FF0F04D099
+:10C6C0009AF801801FE08AF80180C9480068017863
+:10C6D000052902D1BDF81610818009EB08001FFA68
+:10C6E00080F905EB080085B2DDE90C1005AB0F9A67
+:10C6F00001F00EFB28B91D980088411B4145BFF68B
+:10C7000071AF022D13D0BBF1100F0CD1A9EB0800B3
+:10C71000801C81B20220CDE9000105AB52461E9972
+:10C720000D98FFF707FF1D98058000203870002046
+:10C73000B1E72DE9F8439C46089E13460027B26BEB
+:10C740009AB3491F8CB2F18FA1F57F45FF3D05D00B
+:10C750005518AD882944891D8DB200E0002529199E
+:10C76000B6F83C800831414520D82A44BCF8011075
+:10C7700022F8021BBCF8031022F8021B984622F88C
+:10C78000024B914604F0A2FB4FF00C0C41464A4686
+:10C790002346CDF800C003F08CFFF587B16B002075
+:10C7A0002944A41D2144088003E001E0092700E09A
+:10C7B00083273846BDE8F88310B50B88848F9C42E8
+:10C7C0000CD9846BE018048844B1848824F40044B4
+:10C7D000A41D23440B801060002010BD0A2010BD52
+:10C7E0002DE9F0478AB00025904689468246ADF88B
+:10C7F000185007274BE0059806888088000446D427
+:10C80000A8F8006007A8019500970295CDE90350AC
+:10C810004FF4007300223146504601F0F9FA04004B
+:10C820003CD1BDF81800ADF8200005980488818837
+:10C83000B44216D10A0414D401950295039521F44B
+:10C8400000410097049541F48043428821465046B8
+:10C8500001F0B4F804000BD10598818841F400413F
+:10C86000818005AA08A94846FFF7A6FF0400DCD08E
+:10C870000097059802950195039504950188BDF8E8
+:10C880001C300022504601F099F80A2C06D105AA66
+:10C8900006A94846FFF790FF0400ACD0ADF8185049
+:10C8A00004E00598818821F40041818005AA06A949
+:10C8B0004846FFF781FF0028F3D00A2C03D020461A
+:10C8C0000AB0BDE8F0870020FAE710B50C46896B86
+:10C8D00086B051B10C218DF80010A18FADF8081071
+:10C8E000A16B01916946FAF734FC00204FF6FF7105
+:10C8F000A063E187A08706B010BD2DE9F0410D4689
+:10C900000746896B0020069E1446002911D0012B92
+:10C910000FD1324629463846FFF762FF002808D17A
+:10C92000002C06D0324629463846BDE8F04100F0DA
+:10C9300038BFBDE8F0812DE9FC411446DDE9087CF3
+:10C940000E46DDE90A15521DBCF800E092B296458C
+:10C9500002D20720BDE8FC81ACF8002017222A7023
+:10C96000A5F80160A5F803300522CDE900423B4659
+:10C970002A46FFF7DFFD0020ECE770B50C461546B0
+:10C980004821204618F087F904F1080044F81C0FEC
+:10C9900000204FF6FF71E06161842084A584172098
+:10C9A000E08494F82A0040F00A0084F82A0070BD60
+:10C9B0004FF6FF720A800146032007F0B5BD30B57F
+:10C9C00085B00C460546FFF780FFA18E284629B1A9
+:10C9D00001218DF800106946FAF7BBFB0020E062E8
+:10C9E0002063606305B030BDB0F8400070470000C0
+:10C9F0005400002090F84620920703D44088088015
+:10CA00000020F3E70620F1E790F846209207EDD5E5
+:10CA1000A0F84410EAE70146002009880A0700D57B
+:10CA2000012011F0F00F01D040F00200CA0501D53D
+:10CA300040F004008A0501D540F008004A0501D500
+:10CA400040F010000905D1D540F02000CEE700B538
+:10CA5000034690F84600C00701D0062000BDA3F8A9
+:10CA600042101846FFF7D7FF10F03E0F05D093F89D
+:10CA7000460040F0040083F8460013F8460F40F0EB
+:10CA800001001870002000BD90F84620520700D524
+:10CA900011B1B0F84200A9E71720A7E710F8462F18
+:10CAA00061F3C3020270A1E72DE9FF4F9BB00E00B6
+:10CAB000DDE92B34DDE92978289D24D02878C107C9
+:10CAC00003D000F03F00192801D9012100E0002126
+:10CAD0002046FFF7D9FFB04215D32878410600F071
+:10CAE0003F010CD41E290CD0218811F47F6F0AD18C
+:10CAF0003A8842B1A1F57F42FF3A04D001E0122901
+:10CB000001D1000602D504201FB0C5E5F9491D98E2
+:10CB10004FF0000A08718DF818A08DF83CA00FAAFC
+:10CB20000A60ADF81CA0ADF850A02978994601F034
+:10CB30003F02701F5B1C04F1180C4FF0060E4FF003
+:10CB4000040BCDF858C01F2A7ED2DFE802F07D7DAD
+:10CB5000107D267DAC7DF47DF37DF27DF17DF47D4D
+:10CB6000F07D7D7DEF7DEE7D7D7D7D7DED0094F81A
+:10CB70004610B5F80100890701D5032E02D08DF8C3
+:10CB800018B022E34FF40061ADF85010608003212B
+:10CB90008DF83C10ADF84000D8E2052EEFD1B5F885
+:10CBA00001002083ADF81C00B5F80310618308B1C3
+:10CBB000884201D901207FE10020A07220814FF638
+:10CBC000FF702084169801F0A0F8052089F8000075
+:10CBD0000220029083460AAB1D9A16991B9801F019
+:10CBE00097F890BB9DF82E00012804D0022089F808
+:10CBF0000100102003E0012089F8010002200590C7
+:10CC0000002203A90BA805F0D0FDE8BB9DF80C009D
+:10CC1000059981423DD13A88801CA2EB0B018142EB
+:10CC200037DB02990220CDE900010DF12A034A46C3
+:10CC300041461B98FFF77EFC02980BF1020B801C0B
+:10CC400080B217AA03A901E0A0E228E002900BA895
+:10CC500005F0ABFD02999DF80C00CDE9000117AB82
+:10CC60004A4641461B98FFF765FC9DF80C100AAB3D
+:10CC70000BEB01001FFA80FB02981D9A084480B25A
+:10CC8000029016991B9800E003E001F041F800289B
+:10CC9000B6D0BBF1020F02D0A7F800B053E20A20D1
+:10CCA0008DF818004FE200210391072EFFF467AFC3
+:10CCB000B5F801002083ADF81C00B5F803206283AD
+:10CCC00000283FF477AF90423FF674AF0120A07286
+:10CCD000B5F8050020810020A073E06900F052FD46
+:10CCE00078B9E16901208871E2694FF4205191809F
+:10CCF000E1698872E06942F601010181E069002181
+:10CD00008173F01F20841E9860620720608416984B
+:10CD100000F0FBFF072089F800000120049002903A
+:10CD20000020ADF82A0028E01DE2A3E13AE1EAE0A4
+:10CD300016E2AEE086E049E00298012814D0E069EE
+:10CD40008079012803D1BDF82800ADF80E000498C1
+:10CD500003ABCDE900B04A4641461B98FFF7EAFB1A
+:10CD60000498001D80B20490BDF82A00ADF80C00B4
+:10CD7000ADF80E00059880B202900AAB1D9A169984
+:10CD80001B9800F0C5FF28B902983988001D05904E
+:10CD90008142D1D20298012881D0E06980790128AE
+:10CDA00005D0BDF82810A1F57F40FF3803D1BDF8AC
+:10CDB0002800ADF80E00049803ABCDE900B04A4658
+:10CDC00041461B98FFF7B6FB0298BBE1072E02D045
+:10CDD000152E7FF4D4AEB5F801102183ADF81C10E8
+:10CDE000B5F80320628300293FF4E4AE91423FF698
+:10CDF000E1AE0121A1724FF0000BA4F808B084F855
+:10CE00000EB0052E07D0C0B2691DE26905F0AEFC78
+:10CE100000287FF444AF4FF6FF70208401A906AAD2
+:10CE200014A8CDF800B081E885032878214600F0E9
+:10CE30003F031D9A1B98FFF795FB8246208BADF8A8
+:10CE40001C0080E10120032EC3D14021ADF8501019
+:10CE5000B5F801102183ADF81C100AAAB8F1000F33
+:10CE600000D00023CDE9020304921D98CDF8048080
+:10CE7000009038880022401E83B21B9800F0C8FF43
+:10CE80008DF8180090BB0B2089F80000BDF8280031
+:10CE900037E04FF0010C052E9BD18020ADF85000FB
+:10CEA000B5F801102183B5F803002084ADF81C10FB
+:10CEB000B0F5007F03D907208DF8180085E140F414
+:10CEC0007C4222840CA8B8F1000F00D00023CDE9E9
+:10CED0000330CDE9018C1D9800903888401E83B244
+:10CEE0001B9800F095FF8DF8180028B18328A8D171
+:10CEF0000220BDE0540000200D2189F80010BDF88B
+:10CF00003000401C1EE1032E04D248067FF537AEE8
+:10CF1000002017E1B5F80110ADF81C102878400684
+:10CF200002D58DF83CE002E007208DF83C004FF080
+:10CF300000080320CDE902081E9BCDF810801D9843
+:10CF40000193A6F1030B00901FFA8BF342461B9846
+:10CF500000F034FD8DF818008DF83C8029784906E2
+:10CF60000DD52088C00506D5208BBDF81C10884241
+:10CF700001D1C4F8248040468DF81880E2E083286F
+:10CF800001D14FF0020A4FF48070ADF85000BDF8A7
+:10CF90001C002083A4F820B01E98606203206084E7
+:10CFA0001321CCE0052EFFF4EAADB5F80110ADF881
+:10CFB0001C10A28F62B3A2F57F43FE3B28D008224B
+:10CFC0008DF83C204FF0000B0523CDE9023BDDF846
+:10CFD00078C0CDF810B01D9A80B2CDF804C040F4EE
+:10CFE00000430092B5F803201B9800F0E7FC8DF891
+:10CFF0003CB04FF400718DF81800ADF85010832844
+:10D0000010D0F8B1A18FA1F57F40FE3807D0DCE049
+:10D010000B228DF83C204FF6FE72A287D2E7A4F8CF
+:10D020003CB0D2E000942B4631461E9A1B98FFF785
+:10D0300080FB8DF8180008B183284BD1BDF81C0087
+:10D04000208355E700942B4631461E9A1B98FFF724
+:10D0500070FB8DF81800E8BBE18FA06B0844811DC0
+:10D060008DE882034388828801881B98FFF763FC60
+:10D07000824668E095F80180022E70D15FEA0800D0
+:10D0800002D0B8F1010F6AD109208DF83C0007A841
+:10D0900000908DF840804346002221461B98FFF700
+:10D0A0002CFC8DF842004FF0000B8DF843B050B9C6
+:10D0B000B8F1010F12D0B8F1000F04D1A18FA1F582
+:10D0C0007F40FF380AD0A08F40B18DF83CB04FF4BC
+:10D0D000806000E037E0ADF850000DE00FA91B982C
+:10D0E000FAF737F882468DF83CB04FF48060ADF81F
+:10D0F0005000BAF1020F06D0FC480068C07928B190
+:10D100008DF8180027E0A4F8188044E0BAF1000F69
+:10D1100003D081208DF818003DE007A80090434619
+:10D12000012221461B98FFF7E8FB8DF818002146E5
+:10D130001B98FFF7CAFB9DF8180020B9192189F840
+:10D140000010012038809DF83C0020B10FA91B98E9
+:10D15000F9F7FFFF8246BAF1000F33D01BE018E069
+:10D160008DF818E031E02078000712D5012E10D19B
+:10D170000A208DF83C00E088ADF8400003201B99A0
+:10D1800007F0D2F90820ADF85000C1E648067FF557
+:10D19000F6AC4FF0040A2088BDF8501008432080F8
+:10D1A000BDF8500080050BD5A18FA1F57F40FE385A
+:10D1B00006D11E98E06228982063A6864FF0030AE5
+:10D1C0005046A1E49DF8180078B1012089F80000CC
+:10D1D000297889F80110BDF81C10A9F802109DF8F3
+:10D1E000181089F80410052038802088BDF85010E8
+:10D1F00088432080E4E72DE9FF4F8846087895B002
+:10D20000012181404FF20900249C0140ADF820101B
+:10D210002088DDF88890A0F57F424FF0000AFF3AA1
+:10D2200006D039B1000705D5012019B0BDE8F08F4F
+:10D230000820FAE7239E4FF0000B0EA886F800B0F6
+:10D2400018995D460988ADF83410A8498DF81CB0CE
+:10D25000179A0A718DF838B0086098F80000012814
+:10D260003BD0022809D003286FD1307820F03F004E
+:10D270001D303070B8F80400E08098F800100320EA
+:10D28000022904D1317821F03F011B31317094F82B
+:10D290004610090759D505ABB9F1000F13D000218D
+:10D2A00002AA82E80B000720CDE90009BDF834008E
+:10D2B000B8F80410C01E83B20022159800F0A8FD33
+:10D2C0000028D1D101E0F11CEAE7B8F80400A6F883
+:10D2D0000100BDF81400C01C04E198F805108DF899
+:10D2E0001C1098F80400012806D04FF4007A022898
+:10D2F0002CD00328B8D16CE12188B8F8080011F4CB
+:10D300000061ADF8201020D017281CD3B4F84010CD
+:10D31000814218D3B4F84410172901D3814212D1A5
+:10D32000317821F03F01C91C3170A6F801000321BA
+:10D33000ADF83410A4F8440094F8460020F0020040
+:10D3400084F8460065E105257EE177E1208808F153
+:10D35000080700F4FE60ADF8200010F0F00F1BD0BD
+:10D3600010F0C00F03D03888228B9042EBD199B9CE
+:10D37000B878C00710D0B9680720CDE902B1CDF860
+:10D3800004B00090CDF810B0FB88BA8839881598A1
+:10D3900000F014FB0028D6D12398BDF82010401CC3
+:10D3A00080294ED006DC10290DD020290BD0402931
+:10D3B00087D124E0B1F5807F6ED051457ED0B1F5A4
+:10D3C000806F97D1DEE0C80601D5082000E010206C
+:10D3D00082460DA907AA0520CDE902218DF8380063
+:10D3E000ADF83CB0CDE9049608A93888CDE9000134
+:10D3F0005346072221461598FFF7B4F8A8E09DF898
+:10D400001C2001214FF00A0A002A9BD105ABB9F17B
+:10D41000000F00D00020CDE902100720CDE900095F
+:10D42000BDF834000493401E83B2218B002215986E
+:10D4300000F0EEFC8DF81C000B203070BDF81400DD
+:10D4400020E09DF81C2001214FF00C0A002A22D177
+:10D4500013ABB9F1000F00D00020CDE90210072076
+:10D46000CDE900090493BDF83400228C401E83B23C
+:10D47000218B159800F0CCFC8DF81C000D2030702D
+:10D48000BDF84C00401CADF8340005208DF8380084
+:10D49000208BADF83C00BCE03888218B88427FF4BB
+:10D4A00052AF9DF81C004FF0120A00281CD1606A90
+:10D4B000A8B1B878C0073FF446AF00E018E0BA68FA
+:10D4C0000720CDE902B2CDF804B00090CDF810B03D
+:10D4D000FB88BA88159800F071FA8DF81C001320AB
+:10D4E00030700120ADF8340093E0000054000020BB
+:10D4F0003988208B8142D2D19DF81C004FF0160A4A
+:10D500000028A06B08D0E0B34FF6FF7000215F4603
+:10D51000ADF808B0019027E068B1B978C907BED16D
+:10D52000E18F0DAB0844821D03968DE80C02438801
+:10D530008288018809E0B878C007BCD0BA680DAB12
+:10D5400003968DE80C02BB88FA881598FFF7F3F96B
+:10D5500005005ED0072D72D076E0019005AA02A9E1
+:10D560002046FFF729F90146E28FBDF80800824204
+:10D5700001D00029F1D0E08FA16B08440780019809
+:10D58000E08746E09DF81C004FF0180A40B1208B60
+:10D59000C8B13888208321461598FFF796F938E0FE
+:10D5A00004F118000090237E012221461598FFF710
+:10D5B000A4F98DF81C000028EDD11920307001204D
+:10D5C000ADF83400E7E7052521461598FFF77DF90A
+:10D5D0003AE0208800F40070ADF8200050452DD1CD
+:10D5E000A08FA0F57F41FE3901D006252CE0D8F8A8
+:10D5F00008004FF0160A48B1A063B8F80C10A187D4
+:10D600004FF6FF71E187A0F800B002E04FF6FF701F
+:10D61000A087BDF8200030F47F611AD07823002263
+:10D620000320159906F0D6FE98F800002071208896
+:10D63000BDF82010084320800EE000E00725208878
+:10D64000BDF8201088432080208810F47F6F1CD004
+:10D650003AE02188814321809DF8380020B10EA94D
+:10D660001598F9F776FD05469DF81C000028EBD0CB
+:10D6700086F801A001203070208B70809DF81C007E
+:10D6800030710520ADF83400DEE7A18EE1B11898C5
+:10D690000DAB0088ADF834002398CDE90304CDE943
+:10D6A0000139206B0090E36A179A1598FFF7FCF98F
+:10D6B000054601208DF838000EA91598F9F749FDA7
+:10D6C00000B10546A4F834B094F8460040070AD5E6
+:10D6D0002046FFF7A0F910F03E0F04D114F8460FD2
+:10D6E00020F0040020701898BDF8341001802846FE
+:10D6F0009BE500B585B0032806D102208DF8000017
+:10D7000088B26946F9F725FD05B000BD10B5384C63
+:10D710000B782268012B02D0022B2AD111E013785A
+:10D720000BB1052B01D10423137023688A889A80DA
+:10D730002268CB88D38022680B8913814989518163
+:10D740000DE08B8893802268CB88D38022680B8978
+:10D7500013814B8953818B899381096911612168F8
+:10D76000F9F7F7FC226800210228117003D0002885
+:10D7700000D0812010BD832010BD806B002800D018
+:10D78000012070478178012909D10088B0F5205F18
+:10D7900003D042F60101884201D1002070470720E2
+:10D7A0007047F0B587B0002415460E460746ADF821
+:10D7B000144010E0069801882980811DCDE90241BE
+:10D7C0000721019404940091838842880188384697
+:10D7D00000F0F4F830B906AA05A93046FEF7ECFFD0
+:10D7E0000028E7D00A2800D1002007B0F0BD0000D3
+:10D7F0005400002010B58B7883B102789A4205D18D
+:10D800000B885BB102E08B79091D4BB18B789A4292
+:10D81000F9D1B0F801300C88A342F4D1002010BD3A
+:10D82000812010BD072826D012B1012A27D103E09C
+:10D83000497801F0070102E04978C1F3C2010529E6
+:10D840001DD2DFE801F00318080C12000AB1032012
+:10D8500070470220704704280DD250B10DE0052812
+:10D8600009D2801E022808D303E0062803D003282B
+:10D8700003D005207047002070470F20704781209B
+:10D880007047C0B282060BD4000607D5FE48807AE6
+:10D890004143C01D01EBD00080B27047084670477D
+:10D8A0000020704770B513880B800B781C0625D5B7
+:10D8B000F54CA47A844204D843F01000087000208C
+:10D8C00070BD956800F0070605EBD0052D78F54092
+:10D8D00065F304130B701378D17803F0030341EA66
+:10D8E000032140F20123B1FBF3F503FB151192680C
+:10D8F000E41D00FB012000EBD40070BD906870BDFA
+:10D9000037B51446BDF8041011809DF804100A06BE
+:10D910001ED5C1F30013DC49A568897A814208D875
+:10D92000FE2811D1C91DC9085A42284617F089F9A5
+:10D930000AE005EBD00100F00702012508789540C8
+:10D94000A843934018430870207820F010002070FE
+:10D950003EBD2DE9F0410746C81C0E4620F00300ED
+:10D96000B04202D08620BDE8F081C74D0020344689
+:10D970002E60AF802881AA72E8801AE0E988491CED
+:10D98000E980810614D4E17800F0030041EA002028
+:10D9900040F20121B0FBF1F201FB12012068FFF718
+:10D9A00070FF2989084480B22881381A3044A06069
+:10D9B0000C3420784107E1D40020D4E72DE9FF4F53
+:10D9C00089B01646DDE9168A0F46994623F440458C
+:10D9D000084600F00DFB04000FD0099803F00AF987
+:10D9E0000290207800060AD5A748817A02988142E1
+:10D9F00005D887200DB0BDE8F08F0120FAE7224658
+:10DA000001A90298FFF74EFF834600208DF80C0015
+:10DA10004046B8F1070F1AD001222146FFF702FF56
+:10DA20000028E7D12078400611D502208DF80C009F
+:10DA3000ADF81070BDF80400ADF81200ADF8146038
+:10DA40001898ADF81650CDF81CA0ADF818005FEA94
+:10DA5000094004D500252E46A84601270CE0217870
+:10DA6000E07801F0030140EA012040F20121B0FB1F
+:10DA7000F1F2804601FB12875FEA494009D5B845BB
+:10DA800007D1A178207901F0030140EA0120B042DA
+:10DA900001D3BE4201D90720ACE7A8191FFA80F9CB
+:10DAA000B94501D90D20A5E79DF80C0028B103A9BF
+:10DAB0000998F9F74CFB00289CD1B84507D1A0780C
+:10DAC0004FEA192161F30100A07084F804901A98BC
+:10DAD00000B10580199850EA0A0027D0199830B192
+:10DAE0000BEB06002A46199917F034F80EE00BEB01
+:10DAF00006085746189E099803F0E8F92B46F61DCC
+:10DB0000B5B239464246009502F0D3FD224601A93E
+:10DB10000298FFF7C7FE9DF80400224620F010008F
+:10DB20008DF80400DDE90110FFF7EAFE002061E74F
+:10DB30002DE9FF4FDFF8509182461746B9F80610DD
+:10DB4000D9F8000001EB410100EB810440F2012013
+:10DB5000B2FBF0F185B000FB11764D46DDF84C804C
+:10DB600031460698FFF78DFE29682A898B46611A8F
+:10DB70000C3101441144AB8889B28B4202D8842015
+:10DB800009B038E70699CDB2290603D5A90601D513
+:10DB90000620F5E7B9F806C00CF1010C1FFA8CFC61
+:10DBA000A9F806C0149909B1A1F800C0A90602D5C8
+:10DBB000C4F8088007E0104480B2A9F80800191AD8
+:10DBC00001EB0B00A0602246FE200699FFF798FEAD
+:10DBD000E77026712078390A61F30100320AA178D2
+:10DBE00040F0040062F30101A17020709AF8020075
+:10DBF0006071BAF80000E08000262673280602D57E
+:10DC000099F80A7000E00127A80601D54FF0000836
+:10DC10004D4600244FF007090FE0CDE90268019658
+:10DC2000CDF800900496E9882046129B089AFFF7E9
+:10DC3000C5FE0028A4D1641CE4B2BC42EDD3002090
+:10DC40009EE72DE9F047804600F0D2F9070005D0A5
+:10DC5000002644460C4D40F2012919E00120BDE8A0
+:10DC6000F087204600F0C4F90278C17802F0030280
+:10DC700041EA0222B2FBF9F309FB13210068FFF726
+:10DC800000FE304486B201E0E8050020641CA4B226
+:10DC9000E988601E8142E4DCA8F10100E88028895F
+:10DCA000801B288100203870D9E710B5144631B1A7
+:10DCB000491E218002F09EFFA070002010BD0120AF
+:10DCC00010BD10B5D24904460088CA88904201D3DD
+:10DCD0000A2010BD096800EB400001EB800250797A
+:10DCE000A072D08820819178107901F0030140EA78
+:10DCF0000120A081A078E11CFFF7D4FD20612088DD
+:10DD0000401C2080E080002010BD0121018270476E
+:10DD10002DE9FF4F85B04FF6FF788246A3F80080CB
+:10DD200048681F460D4680788DF8060048680088D0
+:10DD3000ADF8040000208DF80A00088A0C88A04283
+:10DD400000D304462C8241E0288A401C2882701DA2
+:10DD50006968FFF74FFDB8BB3988414501D1601EA6
+:10DD600038806888A04236D3B178307901F0030159
+:10DD700040EA012901A9701DFFF73CFD20BB29895C
+:10DD800041452CD0002231460798FFF74BFDD8B90A
+:10DD90002989494518D1E9680391B5F80AC0D6F830
+:10DDA00008B05046CDF800C003F090F8DDF800C090
+:10DDB0005A460CF1070C1FFA8CFC4B460399CDF820
+:10DDC00000C002F040FC50B1641CA4B2204600F038
+:10DDD0000FF90600B8D1641E2C820A20D0E67C80A0
+:10DDE0007079B871F088B8803178F07801F003016B
+:10DDF00040EA01207881A7F80C90504602F0FAFE24
+:10DE0000324607F10801FFF74DFD38610020B7E603
+:10DE10002DE9FF4F87B081461C469246DDF860B081
+:10DE2000DDF85480089800F0E3F805000CD048466F
+:10DE300002F0E0FE2978090608D57549897A814201
+:10DE400004D887200BB0D6E50120FBE7CAF309060A
+:10DE50002A4601A9FFF726FD0746149807281CD07B
+:10DE600000222946FFF7DEFC0028EBD12878400687
+:10DE700013D501208DF808000898ADF80C00BDF806
+:10DE80000400ADF80E00ADF81060ADF8124002A924
+:10DE90004846F9F75CF90028D4D12978E87801F0F0
+:10DEA000030140EA0121AA78287902F0030240EA3E
+:10DEB0000220564507D0B1F5007F04D9611E81428A
+:10DEC00001DD0B20BEE7864201D90720BAE7801B9F
+:10DED00085B2A54200D92546BBF1000F01D0ABF8B1
+:10DEE0000050179818B1B9192A4616F033FEB8F148
+:10DEF000000F0DD03E4448464446169F02F0F8FFFE
+:10DF00002146FF1DBCB232462B46009402F005FCB0
+:10DF1000002097E72DE9F04107461D4616460846C2
+:10DF200000F066F804000BD0384602F063FE21785A
+:10DF3000090607D53649897A814203D8872012E538
+:10DF4000012010E522463146FFF7ACFC65B121788F
+:10DF5000E07801F0030140EA0120B0F5007F01D82C
+:10DF6000012000E0002028700020FCE42DE9F041B1
+:10DF700007461D461646084600F03AF804000BD046
+:10DF8000384602F037FE2178090607D52049897AFC
+:10DF9000814203D88720E6E40120E4E422463146AA
+:10DFA000FFF7AEFCFF2D14D02178E07801F00302DA
+:10DFB00040EA022040F20122B0FBF2F302FB130020
+:10DFC00015B900F2012080B2E070000A60F301018F
+:10DFD00021700020C7E410B50C4600F009F828B104
+:10DFE000C18821804079A070002010BD012010BDA3
+:10DFF0000749CA88824209D340B1096800EB400052
+:10E000006FF00B0202EB800008447047002070475D
+:10E01000E805002070B50346002002466FF02F058A
+:10E020000EE09C5CA4F130060A2E02D34FF0FF30C4
+:10E0300070BD00EB800005EB4000521C2044D2B2C2
+:10E040008A42EED370BD30B50A240AE0B0FBF4F387
+:10E0500004FB13008D18303005F8010C521E1846D1
+:10E06000D2B2002AF2D130BD30B500234FF6FF7591
+:10E0700010E0040A44EA002084B2C85C6040C0F3A7
+:10E080000314604005EA00344440E0B25B1C84EABB
+:10E0900040109BB29342ECD330BD000010B582B06B
+:10E0A000694601F07CFF002818BFFFDF9DF80000E3
+:10E0B000002448B1019890F8DD0028B1019880F85B
+:10E0C000DD4001980AF0F1FAF8488068A0F8D240E3
+:10E0D00002B010BD2DE9F04704460D46062002F0BF
+:10E0E0006BFD0646072002F067FD304400F0FF0894
+:10E0F000002718EB050618BF4FF000091DD0208837
+:10E10000401C80B22080B04228BFA4F8009025882F
+:10E11000454501D3B54209D30621284602F0A4FDA6
+:10E1200020B90721284602F09FFD10B10020BDE86C
+:10E13000F087781CC7B2BE42E1D84FF6FF7020804E
+:10E140001220BDE8F08770B582B007F057FC0DF0E3
+:10E150007FFBD74C4FF6FF7600256683A683D5A1BB
+:10E160002570D1E90001CDE9000165706946A01C68
+:10E1700016F0A6FEA11C601C14F073FC25721B2077
+:10E1800060814FF4A471A181E08121820321A174F7
+:10E190000422E274A082E082A4F13E002183057093
+:10E1A0004680C6480570A4F110000570468002B094
+:10E1B00070BDF8B5BD4D17460E466860297007F072
+:10E1C00097FB4FF6FF70ADF8000000216846FFF79F
+:10E1D00081FFA0B90621BDF8000002F057FD0446FA
+:10E1E0000721BDF8000002F051FD002C1CBF0028E3
+:10E1F000FFDF00216846FFF76DFF0028EAD0FFF738
+:10E20000A2FF287812F03CFC10F034F829786868F6
+:10E2100014F039FB28780CF01FFD30460AF051F954
+:10E2200007F004FD297868680BF094FB39462878DC
+:10E2300015F0F5F9BDE8F8400DF00ABB10B5012462
+:10E24000002A1CBF002010BD002908BF022105D0F4
+:10E25000012918BF002401D0204610BD0FF02EF96F
+:10E26000FAE72DE9F04F8BB0040008BFFFDF022171
+:10E270008F4E06F11C00FFF72DFF002818BFFFDFAF
+:10E28000B6F81CA0062002F097FC0546072002F015
+:10E2900093FC284400F0FF0808F1010000F0FF099A
+:10E2A0004FF0000BB78B474525D120460FF0C8FA39
+:10E2B000002840F0CE803078002800F0CE8084F82E
+:10E2C00001B014202070C4F804B0C4F808B0C4F839
+:10E2D0000CB0C4F810B0C4F814B0C4F818B0C4F846
+:10E2E0001CB00220C4F820B0207186F800B00BB03A
+:10E2F0000120BDE8F08F4F4520D1204607F030FCCB
+:10E3000000287DD008F032F8002859D0207817284E
+:10E3100056D12079002853D0E088072102F0A4FCD0
+:10E32000050008BFFFDF288807F0FBFAE088072117
+:10E3300002F0ACFC002818BFFFDF8AE004A93846D1
+:10E3400001F02DFE00285BD19DF8100048B107F0C8
+:10E3500062FCB84254D0214638460BF004FA80B330
+:10E3600077E00FF000FBB84277D02146384614F032
+:10E37000ABF900286DD1059800F1580590F8D00050
+:10E3800018B9E87E08B1012000E00020079095F858
+:10E39000370000281CBF95F8380010F0020F1CD081
+:10E3A00084F801B00120207084F804B0E78095F86B
+:10E3B00039002072688F6081A88FA08185F837B0FE
+:10E3C00047E0FFE7059800F1580590F80C01002898
+:10E3D000DBD1E87E0028D8D0D5E7384602F088FDAA
+:10E3E0000290002808BFFFDF029801F097FF50B1AC
+:10E3F00084F801B00F212170E7802081012000E026
+:10E400002BE0207125E0384602F060FD02900028E4
+:10E4100008BFFFDF079800B3029801F0D6FFE0B114
+:10E420009DF8100038B90598D0F8F8004188B94235
+:10E4300008BF80F800B0384607F073FA84F801B0DE
+:10E440000C20207084F804B0E780287F207285F8C3
+:10E450001BB00BB00120BDE8F08F022106F11C00BB
+:10E46000FFF738FE18B9B08B50457FF41BAF0BB0E7
+:10E470002046BDE8F04F15F018B910B513F08CF830
+:10E48000042803D013F088F8052802D110F00FF902
+:10E4900028B90AF0EBFA20B107F08AFD08B10C2088
+:10E4A00010BD0DF021FA002010BD00005C0000201E
+:10E4B00032060020FFFFFFFF1F0000006800002061
+:10E4C00010B50446007800281EBF0128122010BD98
+:10E4D00013F062F8042806D013F05EF8052802D085
+:10E4E0000AF0C4FA28B10DF04EFB00281CBF0C2026
+:10E4F00010BD2078002816BF02280020012004F15A
+:10E500001703E21D611CBDE810400DF045BA10B5BF
+:10E510000446007800281EBF0128122010BD13F009
+:10E520003BF8042803D013F037F8052802D110F087
+:10E53000BEF828B90AF09AFA20B107F039FD08B1FF
+:10E540000C2010BD2078002816BF022800200120D2
+:10E55000611C0DF08FF9002814BF0020072010BDAA
+:10E5600010B50DF013FB002814BF0020302010BDA3
+:10E5700010B5044613F010F8042806D013F00CF878
+:10E58000052802D00AF072FA08B10C2010BD20460E
+:10E590000DF0F6FA002010BD10B512F0FDFF0428B2
+:10E5A00006D012F0F9FF052802D00AF05FFA28B170
+:10E5B0000DF0E9FA00281CBF0C2010BD0DF045FA43
+:10E5C000002010BDFF2181704FF6FF718180FE4950
+:10E5D00049680A7882718A880281498841810121CB
+:10E5E00041700020704710B5002482B0022A18D074
+:10E5F00014DC12F10C0F14D008DC12F1280F1CBF30
+:10E6000012F1140F12F1100F11D10AE012F1080FDC
+:10E610001CBF12F1040F002A09D102E0D31E052B02
+:10E6200005D8012807D0022809D003280BD01224CE
+:10E6300002B0204610BD104607F093FEF8E71046E2
+:10E640000FF0D4FDF4E708461446694601F0A7FC34
+:10E65000002818BF0224EBD19DF80000019880F833
+:10E6600057400024E4E710B5134601220EF029F9C3
+:10E67000002010BD10B5044612F08EFF052804BF1F
+:10E680000C2010BD204612F0E9F9002010BD10B595
+:10E69000044612F081FF042806D012F07DFF052801
+:10E6A00002D00AF0E3F908B10C2010BD2146002089
+:10E6B00007F0A5F9002010BD10B5044612F078FA55
+:10E6C00050B10AF0C6F938B1207809F01EFF207861
+:10E6D00010F026F8002010BD0C2010BD10B5044627
+:10E6E00012F05AFF042806D012F056FF052802D077
+:10E6F0000AF0BCF908B10C2010BD2146012007F03A
+:10E700007EF9002010BD38B504464FF6FF70ADF815
+:10E710000000A079E179884213D021791F299CBF9C
+:10E7200061791F290DD80022114615F0B1FB40B9BF
+:10E730000022E079114615F0ABFB10B9207A0728CA
+:10E7400001D9122038BD0AF091F960B912F024FF06
+:10E7500048B900216846FFF7BDFC20B1204606F00D
+:10E760007CF9002038BD0C2038BD70B50446807897
+:10E77000002582B01A2825D00EDC162844D2DFE806
+:10E7800000F0434343434321434343434343434311
+:10E7900043434343432121212A2835D00BDCA0F1F8
+:10E7A0001E000C2830D2DFE800F02F2F2F2F2F2F44
+:10E7B0002F2F2F2F2F0D3A38042825D2DFE800F015
+:10E7C000240224022088B0F5706F1DD2012669460C
+:10E7D00001F0E5FB00281EBF022002B070BD9DF8CD
+:10E7E0000000002801980BBF00F1F40100F5B8719A
+:10E7F00000F1F50300F27113024612D192F8D00035
+:10E8000092F8732052B903E002B04FF0120070BDCD
+:10E81000002818BF042801D0087868B102B00C2085
+:10E8200070BD92F80C0192F87320002AF6D10028EE
+:10E8300018BF0428F0D1F1E70E70A07818709DF889
+:10E84000000048B1019890F8DD0028B1019880F8E7
+:10E85000DD50019809F029FF02B0002070BDF0B52D
+:10E8600083B00C46694601F09AFB28B1204616F0A9
+:10E8700011FB03B00220F0BD0198002700F15805FC
+:10E8800000F1080685F840703146204616F018FB66
+:10E8900095F840000028F5D103B0F0BD2DE9F04116
+:10E8A000044691F8550091F856300D4610F00C0FC3
+:10E8B0004FF0000608BF00232189A0880EF068F9F8
+:10E8C000696A814228BFBDE8F081401A401C4108B6
+:10E8D000A0886FF00E07401A80B2A08022896FF0E6
+:10E8E0000D0C511A8BB2238195F85410628811F0E7
+:10E8F0000C0F28D0B0F5747F38BF304606D350389F
+:10E90000C11700EB91600CEBA01080B2824238BFBF
+:10E910001046608095F85510E08811F00C0F1BD060
+:10E92000B3F5747F38BF324607D3A3F15001CA173D
+:10E9300001EB92610CEBA1118AB2904228BF104604
+:10E94000E080BDE8F08102291ABF0CEBD00080B254
+:10E9500007EB9000DAD1D8E702291ABF0CEBD301FC
+:10E960008AB207EB9301E8D1E6E7F0B587B00C4631
+:10E97000054604A901F013FB00281CBF07B0F0BD39
+:10E980009DF81000002814BF002201220599B1F85B
+:10E990004A30FB2B28BFFB23B1F84CC0BCF1FB0F66
+:10E9A00028BF4FF0FB0C094FD7E90006BF68009065
+:10E9B00001960297ADF80230ADF806C06846FFF741
+:10E9C0006DFF658004E000005C000020E450020060
+:10E9D000BDF80400E080BDF808006081BDF80200C9
+:10E9E000A080BDF80600208107B00020F0BD2DE911
+:10E9F000F04788B004460088694601F0D0FA070065
+:10EA00001CBF08B0BDE8F087B4F806C02289ACF19D
+:10EA10001B011220E12924BF08B0BDE8F087B2F540
+:10EA2000A47F3CBF08B0BDE8F08744F29025AA421D
+:10EA300084BF08B0BDE8F08700266388A188A3F1F1
+:10EA40001B08B8F1E10F24BF08B0BDE8F087B1F5AD
+:10EA5000A47F27BF8846454508B0BDE8F087112050
+:10EA6000BCF1FB0F92BFB2F5296F08B0BDE8F0878B
+:10EA7000FB2B92BFB1F5296F08B0BDE8F087208865
+:10EA800006A901F08CFA002818BFFFDF35D19DF8E8
+:10EA9000180000280CBF012200220799B1F84A0093
+:10EAA000FB2828BFFB20B1F84C30FB2B28BFFB23F1
+:10EAB000DFF834AADAF800C0DAF80490DAF808A02F
+:10EAC000CDF808C0CDF80C90CDF810A0ADF80A0034
+:10EAD000ADF80E3002A8FFF7E1FEBDF80C0060F3C0
+:10EAE0001F45BDF8100060F31F48BDF80A0060F331
+:10EAF0000F05BDF80E0060F30F0862881FFA88F159
+:10EB0000092091423CBF08B0BDE8F087A9B2E28875
+:10EB100091423CBF08B0BDE8F0874FEA1841A28897
+:10EB2000238901EB15411A4491423CBF08B0BDE86E
+:10EB3000F0879DF800004FF001090028019840F689
+:10EB4000480808D000F5CD7580F89B91019890F8A1
+:10EB5000DE0140B307E000F5827580F80591019869
+:10EB600090F8280108B13A2718E0E08868806088AA
+:10EB7000E8802089A880A088288101222846019960
+:10EB8000FFF78CFEA888404528BF40F64800A880C3
+:10EB9000288940451DD2288185F800906E7008B004
+:10EBA0003846BDE8F087E08868806088E880208982
+:10EBB000A880A0882881002228460199FFF76EFED0
+:10EBC000A888404528BF40F64800A88028894045CD
+:10EBD000E1D340F64800DEE709E710B5044612F03D
+:10EBE000DBFC042806D012F0D7FC052802D009F07F
+:10EBF0003DFF28B10CF0C7FF00281CBF0C2010BD42
+:10EC00002078002816BF022800200120E279611C2C
+:10EC10000DF03DF9002814BF0020022010BD2DE9A1
+:10EC2000F04383B006460088694601F0B8F9070052
+:10EC30001CBF03B0BDE8F083B088002818BF0128CE
+:10EC400005D002281EBF122003B0BDE8F083E946BC
+:10EC5000B17800290CBF07250D46F07800280CBFBD
+:10EC60000724044615F0040F16BF002900210121D6
+:10EC700014F0040F16BF00280020012001424FF0BD
+:10EC800009080AD001221146484601F0A0F90028DF
+:10EC900038D003B04046BDE8F08381B100220121A5
+:10ECA000484601F094F90028F3D114F0040F29D05C
+:10ECB00001221146484601F08AF918B343E080B1B9
+:10ECC00001220021484601F082F90028E1D115F027
+:10ECD000040F17D001221146484601F078F988B197
+:10ECE00025E015F0040F04F0040023D0C0B1012288
+:10ECF0001146484601F06BF900281CBF25F00405B9
+:10ED000024F0040400219DF800200120002A019A2B
+:10ED10001CD082F8A501019A92F8F221BAB33FE023
+:10ED200000220121484601F052F90028EAD025F0DE
+:10ED30000405E7E70028E5D001220021484601F05C
+:10ED400046F90028DED024F00404DBE782F80F0146
+:10ED5000019A92F834213AB9019A92F80E211AB91F
+:10ED6000019A92F87D200AB13A270CE0019A82F8C4
+:10ED70000E01019880F81051019880F81141019A14
+:10ED8000B088A2F81201019880F80F111AE0FFE78D
+:10ED9000019A92F8A4211AB9019A92F87D200AB139
+:10EDA0003A270CE0019A82F8A401019880F8A65154
+:10EDB000019880F8A741019AB088A2F8A8010198AB
+:10EDC00080F8A51103B03846BDE8F083817831F0B2
+:10EDD000070107BFC17831F00701122070471EE715
+:10EDE00002781221012A18BF002A05D0022A18BF72
+:10EDF000032A01D0084670474278002A18BF012A2A
+:10EE000003D0022A18BF032AF4D1C27B12B9827838
+:10EE1000012AEFD1837833F00502EBD113F0050F0F
+:10EE2000E8D030B4C278C488B0F80AC0002A18BF4D
+:10EE3000012A04D1042C28BFBCF1040F02D230BC3B
+:10EE400008467047052B07D0827B002AF7D0072A97
+:10EE5000F5D830BC01F0D6B80279B0F808C0838983
+:10EE6000002A18BF012AEAD1BCF1040F28BF042BE5
+:10EE7000E5D3E9E710B5044602781220012A0FD045
+:10EE8000002A18BF10BD012A26D012F085FB0528E4
+:10EE900004D011F01AFD002808BF10BD0C2010BDD1
+:10EEA0006178002918BF012906D0022918BF10BDBA
+:10EEB000A188002908BF10BD6388002B1CBFA18852
+:10EEC0000029E0D003EB83035B0001EB8101B3EB8E
+:10EED000012F28BF10BDD6E70FF015FB002804BF97
+:10EEE000122010BD0FF035FB00200FF0CEFB0028E4
+:10EEF00018BF10BD60780FF0BAFB002818BF10BD16
+:10EF0000A1886088BDE8104011F0A0BE427A12F0DE
+:10EF1000070F0FD032F007030CD1012A18BF022AC5
+:10EF200003D0042A1CBF1120704790F83A301BB957
+:10EF3000012A01D0122070472DE9F00F4FF0000C8C
+:10EF400012F0010F40F6774640F67B4337D069B1A7
+:10EF50004489B0F810C0271F43F6FD75AF423CBF8F
+:10EF6000ACF10407AF4226D2644524D3C78AB0F877
+:10EF70001CC0458C048DB0F82E80B0F83490A7F1F9
+:10EF8000060A9A453CBFACF1060A9A4513D267457A
+:10EF900098BFB5F5FA7F3CBFA4F10A07B7420AD281
+:10EFA0006D1C05FB0CFCBCEB840F04DAC84598BF54
+:10EFB0004FF0010C03D9BDE8F00F3020704712F07C
+:10EFC000020F27D000EB4C04B4F81690A58BB4F8D0
+:10EFD0002280278DB4F82EA0A48EA9F1060B5B45E4
+:10EFE00084BFA5F1060B5B45E5D9A94598BFB8F5E7
+:10EFF000FA7F3CBFA7F10A09B145DCD208F101084C
+:10F0000008FB05F5B5EB870FD5DAA24598BF0CF1E3
+:10F01000010CD0D812F0040F22D000EB4C02D78A9A
+:10F02000B2F81CC0558C148DB2F82E80928EA7F1C8
+:10F0300006094B4584BFACF106094B45BBD9674572
+:10F0400098BFB5F5FA7F3CBFA4F10A03B342B2D230
+:10F050006B1C03FB0CF3B3EB840FACDA9045AAD81E
+:10F0600002782AB1012A13D0BDE8F00F12207047B0
+:10F070000029817808D0002918BF012908D0022969
+:10F0800018BF032904D0EFE7002918BF0129EBD1ED
+:10F090004078002818BF012803D0022818BF032891
+:10F0A000E2D1BDE8F00F0020704700212EE7017883
+:10F0B00011F0010F02D0406814F0CABA14F097BAE8
+:10F0C0002DE9F04F91B00D460246AFF61841D1E957
+:10F0D0000001CDE90E0111462846FFF717FF060093
+:10F0E0001CBF11B0BDE8F08F12F056FA04280CD006
+:10F0F00012F052FA052808D0FC4F387828B90EF0E3
+:10F1000032FCA0F57F41FF3903D011B00C20BDE8DF
+:10F11000F08FF7480B90F7480C90F7480D900BAA2A
+:10F12000062110A801F06EFD040002BF092011B0F5
+:10F13000BDE8F08F03210DF02EF9EC48818AA4F888
+:10F140004A10C28AA4F84C20C37C0093837C208898
+:10F1500001F045FE002818BFFFDF208806F0E0FB25
+:10F16000278804F10E094FF0000B4FF00A0A042122
+:10F17000484604F000FF48460DF0DFFA062001F093
+:10F180001BFD80461DE005A9062001F0F6FC05A840
+:10F1900001F0D1FC5FEA000B11D100BFBDF81800EF
+:10F1A000B84206D00798042249460E3015F0A6FC56
+:10F1B00070B105A801F0BFFC5FEA000BEED0A8F12A
+:10F1C0000108B8F1000F07DDBBF1000FDBD007E04D
+:10F1D00048460DF0BBFAF2E7BBF1000F08BFFFDFB6
+:10F1E000D9F800000DF0CDFABAF1010A01D00028DB
+:10F1F000BDD0C2A004F1120700680190032101A84C
+:10F2000004F090FE002001A90A5C3A54401CC0B2F0
+:10F210000328F9D3A88B6080688CA080288DE080BB
+:10F22000687A10F0040F18BF08277CD0DFF8BC8282
+:10F230003A461146B8F8180011F071FD0146A06277
+:10F24000204611F0AFFD17F00C0F09D001231A462C
+:10F25000214600200DF0A5FC616A884288BF09267E
+:10F260004FF0000984F85E9084F85F90A878002839
+:10F2700016BF0228002001206076D5F80300C4F8EC
+:10F280001A00B5F80700E0830EA904F1080015F094
+:10F2900017FE4FF0010A84F800A1CDF81CA0B4F8C5
+:10F2A0004C0004F58277FB2828BFFB20B8F80A1031
+:10F2B000814238BF084694F855104FF4747C11F021
+:10F2C0000C0F1CBF0CEB80118AB26BD0B8F80C107D
+:10F2D000914238BF0A46B4F84A10FB2928BFFB21E7
+:10F2E000B8F80E308B4238BF194694F854B01BF072
+:10F2F0000C0F1CBF0CEB81139BB25BD0B8F810C095
+:10F300009C4538BF63461B2918BFB3F5A47F5AD06C
+:10F31000F8803A817980BB8021463846079AFFF70A
+:10F32000BDFAB88800E031E040F64801884228BFC5
+:10F3300040F64800B8803889884228BF40F6480027
+:10F34000388187F800A000BF8DF800900121684641
+:10F3500004F0E8FD9DF8000000F00701C0F3C102D1
+:10F360001144C0F3401008448DF80000401D207681
+:10F3700009283CBF08302076002120460DF00BF80C
+:10F3800068780FF0CBF8002E74D122E010F0010F56
+:10F3900018BF01277FF44AAF10F0020F14BF0227F5
+:10F3A000002743E7022907BF81003C31C1007031CB
+:10F3B0008AB28BE7BBF1020F07BF8B003C33CB0057
+:10F3C00070339BB29AE71B2818BFB2F5A47F9FD178
+:10F3D000BAE7A9782878EA1C0FF073F8002808BF6C
+:10F3E000122647D00FF0B5F8A9782878EA1C0FF05C
+:10F3F00018F906003ED1687A10F0040F14BF0820F7
+:10F4000001200FF053F8060034D1214603200FF0FD
+:10F4100032F906002ED1697A8DF80010697A11F060
+:10F42000010F06D06889ADF80200288AADF8040003
+:10F430000120697A11F0020F18BF401C11F0040F6F
+:10F4400007D005EB40004189ADF80610008AADF801
+:10F450000800684611F0B9FB064695F83A00002806
+:10F4600018BF01200FF028F826B9204611F047FBFD
+:10F47000060009D0208806F054FA2088062101F001
+:10F4800005FC002818BFFFDF304611B0BDE8F08F43
+:10F490000146002014E638B5144C207870B912F0FB
+:10F4A0007BF8052805D00EF05EFAA0F57F41FF3904
+:10F4B00004D0684611F005FC10B113E00C2038BDF3
+:10F4C0000098008806F02DFA00980621008801F0C7
+:10F4D000DDFB002818BFFFDF0120207008480078FE
+:10F4E000FCF788FC002038BDE45002003206002002
+:10F4F000F4050020680000202206002011223300BD
+:10F500005C00002070B4B0F802C08188C388028912
+:10F5100044898089ACF1060640F67B45AE423CBF8B
+:10F520008E1FAE4214D28C4598BFB3F5FA7F3EBF12
+:10F53000A2F10A0CFE4D15EB0C0509D25B1C5943D8
+:10F54000B1EB820F04DA84429EBF002070BC70478A
+:10F55000302070BC70472DE9F047B0F802C0044677
+:10F560008188C388028947898689ACF1060940F6FB
+:10F570007B4830200025C1453ABFA1F10609C145AD
+:10F58000BDE8F0878C4598BFB3F5FA7F3DBFA2F187
+:10F590000A0CDFF89C8318EB0C08BDE8F0875B1CB5
+:10F5A0005943B1EB820FA8BFBDE8F087B74288BFCF
+:10F5B000BDE8F0872088062101F056FB68B190F87D
+:10F5C000D01090F8732042B9002918BF042904D044
+:10F5D000D0F8F8100A781AB106E00220BDE8F087EA
+:10F5E000D0F84421127812B13A20BDE8F087052204
+:10F5F0008A71D0F8F8100D81D0F8F820A1885181D7
+:10F60000D0F8F820E1889181D0F8F8202189D181C3
+:10F61000D0F8F8100A894B899A429EBF8A79082A45
+:10F620009A4224BF1220BDE8F08722884A80D0F891
+:10F63000F800022101700020BDE8F087F0B583B02A
+:10F6400005460DF0D9F8002802BF122003B0F0BD26
+:10F650000026B84F012429467C70B81C15F030FCF8
+:10F660007E706946062001F088FA002818BFFFDF87
+:10F67000684601F060FA002808BFBDF804500AD1BE
+:10F68000029880F80041684601F055FA18B9BDF8B3
+:10F690000400A842F4D103B00020F0BD10B5044628
+:10F6A0000088062101F0E0FA68B190F8D01090F8D7
+:10F6B000732042B9002918BF042904D0D0F8F810EB
+:10F6C0000A7812B105E0022010BDD0F8442112786A
+:10F6D0000AB13A2010BD90F8962012F0010F04BF35
+:10F6E0000C2010BDD4F80220D4F806304A608B609C
+:10F6F000D0F8F81062898A81D0F8F810E268C1F871
+:10F700000E202269C1F812206269C1F81620A26990
+:10F71000C1F81A20D0F8F82003211170D0F8F800B1
+:10F7200021884180002010BDF8B516460F460446DA
+:10F7300009F09CF900281CBF0C20F8BD207812238A
+:10F74000EF2801D91846F8BD6088ADF8000010F028
+:10F75000100F4FF000050CD010F0010F00F0020167
+:10F760001BD0B1B110F0080F08BF10F0040F1ED06D
+:10F770001AE010F0080FE5D110F0200F18BF10F0BC
+:10F78000030FDFD110F0010F18BF10F0020FD9D115
+:10F790000DE010F0040F0AD106E029B110F0080FB7
+:10F7A00008BF10F0040F02D010F00F0FCAD1B4F848
+:10F7B00002C01CF0080F08D1D4E90110884228BF0C
+:10F7C0002029BFD3B0F1807FBCD2207B0028B9D0E4
+:10F7D0000728B7D8607B002818BF012803D002286B
+:10F7E00018BF0328AED11CF0040F03D1022818BFA4
+:10F7F000032807D1A07B002818BF0128A2D11CF044
+:10F80000040F08D1607D002818BF012803D002280A
+:10F8100018BF032896D1E07D1CF0100F02D00128FC
+:10F8200011D08FE7012818BF03288BD11CF0100FCF
+:10F8300009D1607E01281CBF0228032882D1A07E46
+:10F840000F283FF67FAFE07E002818BF01287FF425
+:10F8500079AF1CF0400F1CBF1120F8BD3D70A5759D
+:10F8600056B9FF208DF800006946002006F065FDBE
+:10F870006946002006F04CFD2046BDE8F84006F041
+:10F8800074BC002250E72DE9F0470446C0780F46CB
+:10F89000122510B106F0DBFC50B1607804280AD0C4
+:10F8A00094F8038094F800906678B8F1FB0F12D9B1
+:10F8B0002846BDE8F08709F0D9F80028F8D006F00E
+:10F8C0001EFD0028F4D106F0EEF9002804BFE07810
+:10F8D0000028EDD1E4E71FB1B8F11F0F23D9E7E706
+:10F8E00006F0E1F928B1B8F11F0F98BF032E07D039
+:10F8F000DEE7032E18BF042E02D0B8F1000FD7D0D8
+:10F9000009F0B4F8002818BF032E04D0042E1CBF41
+:10F910000C20BDE8F087484606F0BDF9002804BF7A
+:10F920004220BDE8F087E07861781F2804E00000FD
+:10F9300089F3FFFF3206002098BF03291CBF112066
+:10F94000BDE8F087211D06F0F8FC0020BDE8F08737
+:10F95000002198E72DE9F0470446C0788846122731
+:10F9600010B106F00AFD38B16578042D04D0E678B0
+:10F9700094F80090FB2E02D93846BDE8F087B8F124
+:10F98000000F02D01F2E21D9F6E706F08CF920B126
+:10F990001F2E98BF032D06D0EEE7032D18BF042DB0
+:10F9A00001D0002EE8D009F061F8002818BF032D1F
+:10F9B00004D0042D1CBF0C20BDE8F087484606F09B
+:10F9C0006AF9002804BF4220BDE8F087E07861783A
+:10F9D0001F2898BF03291CBF1120BDE8F087211DF7
+:10F9E00006F096FC0020BDE8F0870021B2E72DE983
+:10F9F000F04304464078422583B0012808D8A07817
+:10FA000006F049F920B120781225012804D0A0B1D0
+:10FA100003B02846BDE8F08306F0C3FC20B1A088FF
+:10FA20000028F5D08028F3D806F0C2FC68B16078D1
+:10FA30000028EDD0207801280BD007F077FE04468F
+:10FA400008F08CFC002800F0038103B00C20BDE816
+:10FA5000F08306F0B5FA38B906F09CFC002802BF26
+:10FA6000122003B0BDE8F08309F000F80028ECD1C3
+:10FA700006F0D1F8A0F57F41FF39E6D106F0BFFAD4
+:10FA8000A08842F2107100FB01F6A079314606F021
+:10FA9000EFFB06F06BFCF8B10022072101A801F092
+:10FAA000B1F8040049D0FE480321846020460CF0E0
+:10FAB00079FB204607F067F8FA4DA88AA4F84A00B7
+:10FAC000E88AA4F84C0006F0EEF870B1288B01210A
+:10FAD00008F0C8FDA06210E03146002008F018FDD3
+:10FAE000002818BFFFDF00F0BEB806F063FC2A8BC9
+:10FAF0000146104608F0B6FDA062014600222046ED
+:10FB000007F017FE06F0CFF84FF00108C8B906F06D
+:10FB100051FC10F00C0F14D001231A462146184650
+:10FB20000DF03FF8616A88420BD90721BDF8040047
+:10FB300001F0ACF8002818BFFFDF092003B0BDE8D2
+:10FB4000F083E87C0090AB7CEA8AA98A208801F0E7
+:10FB500046F9002818BFFFDF208805F0E1FE314696
+:10FB6000204608F0D5FC002818BFFFDF2146B4F876
+:10FB70004C00002204F5CD76FB2828BFFB206B89C2
+:10FB8000834238BF184691F855304FF4747413F01F
+:10FB90000C0F1CBF04EB80131FFA83FC3BD000BF8B
+:10FBA000B5F80C90E14528BFE146B1F84A30FB2B8F
+:10FBB00028BFFB23B5F80EC09C4538BF634691F8BB
+:10FBC00054C01CF00C0F1CBF04EB831C1FFA8CF7F5
+:10FBD0002AD02C8ABC4228BF3C461B2B18BFB4F548
+:10FBE000A47F2FD0F080A6F808907380B4803046B0
+:10FBF000FEF754FEB08840F64801884228BF40F620
+:10FC00004800B0803089884228BF40F648003081E3
+:10FC100086F8008027E0022B07BF83003C33C30037
+:10FC200070331FFA83FCBBE7BCF1020F07BF4FEA3A
+:10FC3000830C0CF13C0C4FEAC30C0CF1700C1FFA56
+:10FC40008CF7C6E71B2818BFB9F5A47FCAD10AE014
+:10FC50004CB1208805F065FE2088072101F016F8D8
+:10FC6000002818BFFFDF002003B0BDE8F0830021AB
+:10FC7000BDE610B50C46072100F0F6FF002804BFD2
+:10FC8000022010BD90F8731109B10C2010BD90F83E
+:10FC90006510142912BF152990F8C0110029F4D15C
+:10FCA0002168C0F874116168C0F87811A168C0F8C3
+:10FCB0007C11E168C0F88011012180F873110020E7
+:10FCC00010BD10B5072100F0CFFF002804BF0220AF
+:10FCD00010BD90F8731109B10C2010BD90F865109B
+:10FCE000142918BF1529F7D1022180F873110020BB
+:10FCF00010BDF0B50E464BF68032122183B096420D
+:10FD000017D8B6B1694600F04AF900281CBF03B005
+:10FD1000F0BD019800F15807841C25883246294619
+:10FD200038460CF035FA2088A842F6D103B00020FE
+:10FD3000F0BD03B00846F0BD10B582B0044600889F
+:10FD4000694600F02CF900281CBF02B010BD0198D4
+:10FD5000A37800F1580190F82C209A4202BF0C20A1
+:10FD600002B010BD7F220A728A720022CA72E17844
+:10FD700080F82D10217980F82E10A17880F82C10B1
+:10FD800002B0104610BD10B582B00C46694600F0B6
+:10FD900006F900281CBF02B010BD019890F873004E
+:10FDA000002818BF0120207002B0002010BD30B51F
+:10FDB00083B00D461446694600F0F1F800281CBFD8
+:10FDC00003B030BD019890F82C0001281EBF0C2014
+:10FDD00003B030BD019890F86010297090F8610070
+:10FDE000207003B0002030BD70B50D4616460721C7
+:10FDF00000F03AFF002804BF022070BD83884FF056
+:10FE0000010CC28841880CEB430C65451AD342F2C1
+:10FE1000107C02FB0CF240F6C41C01FB0CF1B2FB9F
+:10FE2000F1F1491E8CB2B4F5FA7F88BF4FF4FA7431
+:10FE3000A54238BF2C46621C591CB2FBF1F251435B
+:10FE4000491E8BB290F8AC11002908BF038433809F
+:10FE5000002070BD10B50C46072100F005FF0028FA
+:10FE600004BF022010BD80F8DF40002C1EBF90F8B8
+:10FE7000DD10002908F019FC002010BD01780029D0
+:10FE80001CBF4178002915D041881B2921BF8188DA
+:10FE90001B29C18802290DD302680349406805E087
+:10FEA0005C00002032060020F40500200A65486549
+:10FEB000002070471220704710B5044610F02CFF48
+:10FEC000204608F09AFB002010BD2DE9F0411646AF
+:10FED0000F46044601221146384610F020FF054621
+:10FEE0000121384608F0BEFB854228BF2846012381
+:10FEF000E100503189B2E631884206D901F196021B
+:10FF0000401AB0FBF2F0401C83B233800020BDE801
+:10FF1000F08110B5044611F03FFB042806D011F023
+:10FF20003BFB052802D008F0A1FD08B10C2010BD54
+:10FF3000601C0BF082FF207800F0010006F05AF8F8
+:10FF4000207800F001000EF0FFFA002010BD10B57F
+:10FF50000446072000F022FE00281CBF0C2010BD24
+:10FF6000207810F0010F11D000226078114613F0B4
+:10FF70008FFF00281CBF122010BDA0680AF0E9F90D
+:10FF8000607861680AF0EEF9002010BD00200AF0E8
+:10FF9000E0F9002108460AF0E5F9002010BD70B52F
+:10FFA0000C460546062100F05FFE606010B100209F
+:10FFB000207070BD0721284600F056FE60600028C2
+:10FFC00004BF022070BD01202070002070BD10B55C
+:10FFD00004468C46007813466168624638B10120B9
+:10FFE0000CF0DFFD6168496A884209D906E000200B
+:10FFF0000CF0D7FD6168496A884201D9012010BD23
+:020000040001F9
+:10000000002010BD10B586B0044611F0C5FA0428D2
+:1000100041D011F0C1FA05283DD0A0788DF8080034
+:10002000A0788DF8000060788DF8040020788DF8B5
+:100030000300A07B8DF80500E07B002818BF01209D
+:100040008DF80600A07810F0010F27D0E078012885
+:1000500008BF022003D000280CBF012000208DF82B
+:100060000100E088ADF80A006089ADF80C00A078C6
+:1000700010F0040F26D02079012808BF022003D0F9
+:1000800000280CBF012000208DF802002089ADF867
+:100090000E00A08914E006B00C2010BD10F0040F73
+:1000A00010D0E078012808BF022003D000280CBF40
+:1000B000012000208DF80200E088ADF80E00608974
+:1000C000ADF8100002A810F080FD002804BF6846BB
+:1000D0000EF02BFB06B010BD30B5058825F40044AA
+:1000E00021448CB24FF4004194420AD2121B92B2C6
+:1000F0001B339A4201D2A94307E005F40041214392
+:1001000003E0A21A92B2A9431143018030BD084412
+:10011000083050434A31084480B2704770B51D46DC
+:1001200016460B46044629463046049AFFF7EFFF71
+:100130000646B34200D2FFDF2821204614F0ABFD73
+:100140004FF6FF70A082283EB0B265776080B0F5B0
+:10015000004F00D9FFDF618805F13C00814200D2E9
+:10016000FFDF60880835401B343880B220801B28B0
+:1001700000D21B2020800020A07770BD81618861A3
+:1001800070472DE9F05F0D46C188044600F128094B
+:10019000008921F4004620F4004800F062FB10B111
+:1001A0000020BDE8F09F4FF0000A4FF0010BB04572
+:1001B0000CD9617FA8EB0600401A0838854219DC8B
+:1001C00009EB06000021058041801AE06088617F0C
+:1001D000801B471A083F0DD41B2F00DAFFDFBD42FA
+:1001E00001DC294600E0B9B2681A0204120C04D0FE
+:1001F000424502DD84F817A0D2E709EB0600018032
+:10020000428084F817B0CCE770B5044600F12802AC
+:10021000C088E37D20F400402BB11044028843885D
+:1002200013448B4201D2002070BD00258A4202D3C4
+:100230000180458008E0891A0904090C418003D037
+:10024000A01D00F01EFB08E0637F008808331844FF
+:1002500081B26288A01DFFF73FFFE575012070BDE8
+:1002600070B5034600F12804C588808820F4004654
+:100270002644A84202D10020188270BD9889358892
+:10028000A84206D3401B75882D1A2044ADB2C01E6B
+:1002900005E02C1AA5B25C7F20443044401D0C8838
+:1002A000AC4200D90D809C8924B1002414700988C7
+:1002B000198270BD0124F9E770B5044600F12801E8
+:1002C000808820F400404518208A002825D0A18984
+:1002D000084480B2A08129886A881144814200D2F2
+:1002E000FFDF2888698800260844A189884212D146
+:1002F000A069807F2871698819B1201D00F0C1FABA
+:1003000008E0637F28880833184481B26288201D82
+:10031000FFF7E2FEA6812682012070BD2DE9F041A3
+:10032000418987880026044600F12805B94218D083
+:1003300004F10A0821F400402844418819B14046DC
+:1003400000F09FFA08E0637F00880833184481B208
+:1003500062884046FFF7C0FE761C6189B6B2B9429A
+:10036000E8D13046BDE8F0812DE9F04104460B4666
+:1003700027892830A68827F40041B4F80A80014470
+:100380000D46B74201D10020ECE70AB1481D1060CC
+:1003900023B1627F691D184614F0DCFB2E88698842
+:1003A00004F1080021B18A1996B200F06AFA06E059
+:1003B000637F62880833991989B2FFF78DFE47453C
+:1003C00001D1208960813046CCE78188C088814294
+:1003D00001D1012070470020704701898088814247
+:1003E00001D1012070470020704770B58588C3880F
+:1003F00000F1280425F4004223F4004114449D42F6
+:100400001AD08389058A5E1925886388EC18A6426C
+:1004100014D313B18B4211D30EE0437F08325C1921
+:100420002244408892B2801A80B22333984201D28B
+:1004300011B103E08A4201D1002070BD012070BDDE
+:100440002DE9F0478846C1880446008921F400461A
+:1004500004F1280720F4004507EB060900F001FA33
+:10046000002178BBB54204D9627FA81B801A002501
+:1004700003E06088627F801B801A083823D4E289F9
+:1004800062B1B9F80020B9F802303BB1E81A21771F
+:10049000404518DBE0893844801A09E0801A21774A
+:1004A00040450ADB607FE189083030443944084424
+:1004B000C01EA4F81280BDE8F087454503DB01208B
+:1004C0002077E7E7FFE761820020F4E72DE9F74FA7
+:1004D000044600F12805C088884620F4004A608A56
+:1004E00005EB0A0608B1404502D20020BDE8FE8FA8
+:1004F000E08978B13788B6F8029007EB09018842A5
+:1005000000D0FFDF207F4FF0000B50EA090106D03A
+:1005100088B33BE00027A07FB9463071F2E7E1895C
+:1005200059B1607F2944083050440844B4F81F1082
+:1005300020F8031D94F821108170E28907EB080070
+:1005400002EB0801E1813080A6F802B002985F4614
+:1005500050B1637F30880833184481B26288A01D8F
+:10056000FFF7BAFDE78121E0607FE1890830504460
+:10057000294408442DE0FFE7E089B4F81F1028441F
+:10058000C01B20F8031D94F82110817009EB0800AE
+:10059000E28981B202EB0800E08137807180029825
+:1005A000A0B1A01D00F06DF9A4F80EB0A07F401C12
+:1005B000A077A07D08B1E088A08284F816B000BFC3
+:1005C000A4F812B084F817B001208FE7E08928441E
+:1005D000C01B30F8031DA4F81F10807884F8210098
+:1005E000EEE710B5818800F1280321F4004423448C
+:1005F000848AC288A14212D0914210D0818971B9F7
+:10060000826972B11046FFF7E8FE50B910892832AE
+:1006100020F40040104419790079884201D100206B
+:1006200010BD184610BD00F12803407F0830084473
+:10063000C01E1060088808B9DB1E1360088849884E
+:10064000084480B270472DE9F04100F12806407F50
+:100650001C4608309046431808884D88069ADB1ED1
+:10066000A0B1C01C80B2904214D9801AA04200DB15
+:10067000204687B298183A46414614F03FFA0028BF
+:1006800016D1E01B84B2B844002005E0ED1CADB2E9
+:10069000F61EE8E7101A80B20119A94206D83044C4
+:1006A00022464146BDE8F04114F028BA4FF0FF3031
+:1006B00058E62DE9F04100F12804407F1E4608303D
+:1006C00090464318002508884F88069ADB1E90B193
+:1006D000C01C80B2904212D9801AB04200DB304672
+:1006E00085B299182A46404614F034FA701B86B237
+:1006F000A844002005E0FF1CBFB2E41EEAE7101A80
+:1007000080B28119B94206D821183246404614F009
+:1007100021FAA81985B2284624E62DE9F04100F116
+:100720002804407F1E46083090464318002508885C
+:100730004F88069ADB1E90B1C01C80B2904212D93D
+:10074000801AB04200DB304685B298182A464146EE
+:1007500014F000FA701B86B2A844002005E0FF1CCC
+:10076000BFB2E41EEAE7101A80B28119B94206D876
+:1007700020443246414614F0EDF9A81985B22846C6
+:10078000F0E5401D704710B5044600F12801C2880D
+:10079000808820F400431944904206D0A28922B9EF
+:1007A000228A12B9A28A904201D1002010BD088885
+:1007B000498831B1201D00F064F80020208201201A
+:1007C00010BD637F62880833184481B2201DFFF793
+:1007D00083FCF2E70021C18101774182C1758175F7
+:1007E000704703881380C28942B1C28822F4004353
+:1007F00000F128021A440A60C0897047002070473F
+:1008000010B50446808AA0F57F41FF3900D0FFDF94
+:10081000E088A082E08900B10120A07510BD4FF6EC
+:10082000FF71818200218175704710B50446808A6E
+:10083000A0F57F41FF3900D1FFDFA07D28B9A08856
+:10084000A18A884201D1002010BD012010BD8188FD
+:10085000828A914201D1807D08B100207047012039
+:10086000704720F4004221F400439A4207D100F47B
+:10087000004001F40041884201D00120704700206F
+:10088000704730B5044600880D4620F40040A84269
+:1008900000D2FFDF21884FF40040884328432080A6
+:1008A00030BD70B50C00054609D0082C00D2FFDF22
+:1008B0001DB1A1B2286800F044F8201D70BD0DB133
+:1008C00000202860002070BD0021026803E09388AA
+:1008D0001268194489B2002AF9D100F032B870B513
+:1008E00000260D460446082900D2FFDF206808B91B
+:1008F0001EE0044620688188A94202D001680029D0
+:10090000F7D181880646A94201D100680DE005F1C2
+:10091000080293B20022994209D32844491B02607D
+:1009200081802168096821600160206000E0002664
+:10093000304670BD00230B608A8002680A60016047
+:10094000704700234360021D018102607047F0B5CB
+:100950000F460188408815460C181E46AC4200D34D
+:10096000641B3044A84200D9FFDFA019A84200D977
+:10097000FFDF3819F0BD2DE9F041884606460188B1
+:10098000408815460C181F46AC4200D3641B3844FF
+:10099000A84200D9FFDFE019A84200D9FFDF708824
+:1009A0003844708008EB0400BDE8F0812DE9F04187
+:1009B000054600881E461746841B8846BC4200D365
+:1009C0003C442C8068883044B84200D9FFDFA0192D
+:1009D000B84200D9FFDF68883044688008EB040023
+:1009E000E2E72DE9F04106881D460446701980B201
+:1009F000174688462080B84201D3C01B20806088FB
+:100A0000A84200D2FFDF7019B84200D9FFDF60882A
+:100A1000401B608008EB0600C6E730B50D46018834
+:100A2000CC18944200D3A41A4088984200D8FFDF23
+:100A3000281930BD2DE9F041C84D04469046A878EC
+:100A40000E46A04200D8FFDF05EB8607B86A50F8D3
+:100A5000240000B1FFDFB868002816D0304600F04F
+:100A600044F90146B868FFF73AFF05000CD0B86AB0
+:100A7000082E40F8245000D3FFDFB94842462946EB
+:100A800050F82630204698472846BDE8F0812DE9E9
+:100A9000F8431E468C1991460F460546FF2C00D997
+:100AA000FFDFB14500D9FFDFE4B200954DB3002070
+:100AB0008046E81C20F00300A84200D0FFDF494632
+:100AC000DFF89892684689F8001089F8017089F873
+:100AD000024089F8034089F8044089F8054089F804
+:100AE000066089F80770414600F008F90021424687
+:100AF0000F464B460098C01C20F00300009012B136
+:100B00000EE00120D4E703EB8106B062002005E08F
+:100B1000D6F828C04CF82070401CC0B2A042F7D3D1
+:100B20000098491C00EB8400C9B200900829E1D369
+:100B3000401BBDE8F88310B5044603F067FD08B11B
+:100B4000102010BD2078854A618802EB80009278E1
+:100B50000EE0836A53F8213043B14A1C6280A180C1
+:100B6000806A50F82100A060002010BD491C89B2A5
+:100B70008A42EED86180052010BD70B505460C464E
+:100B8000084603F043FD08B1102070BD082D01D3C5
+:100B9000072070BD25700020608070BD0EB56946CD
+:100BA000FFF7EBFF00B1FFDF6846FFF7C4FF08B1B6
+:100BB00000200EBD01200EBD10B50446082800D34C
+:100BC000FFDF6648005D10BD3EB50546002469465E
+:100BD000FFF7D3FF18B1FFDF01E0641CE4B2684601
+:100BE000FFF7A9FF0028F8D02846FFF7E5FF001B14
+:100BF000C0B23EBD59498978814201D9C0B270471F
+:100C0000FF2070472DE9F041544B062903D00729F6
+:100C10001CD19D7900E0002500244FF6FF7603EB00
+:100C2000810713F801C00AE06319D7F828E09BB2E6
+:100C30005EF823E0BEF1000F04D0641CA4B2A4450A
+:100C4000F2D8334603801846B34201D100201CE796
+:100C5000BDE8F041EEE6A0F57F43FF3B01D0082957
+:100C600001D300207047E5E6A0F57F42FF3A0BD0A4
+:100C7000082909D2394A9378834205D902EB8101C8
+:100C8000896A51F820007047002070472DE9F04133
+:100C900004460D46A4F57F4143F20200FF3902D01D
+:100CA000082D01D30720F0E62C494FF000088A7880
+:100CB000A242F8D901EB8506B26A52F82470002FDF
+:100CC000F1D027483946203050F82520204690475B
+:100CD000B16A284641F8248000F007F802463946F8
+:100CE000B068FFF727FE0020CFE61D49403131F8FC
+:100CF00010004FF6FC71C01C084070472DE9F84306
+:100D0000164E8846054600242868C01C20F00300C3
+:100D100028602046FFF7E9FF315D4843B8F1000F36
+:100D200001D0002200E02A680146009232B100277B
+:100D30004FEA0D00FFF7B5FD1FB106E001270020C7
+:100D4000F8E706EB8401009A8A602968641C08446D
+:100D5000E4B22860082CD7D3EBE600005006002050
+:100D6000F050020070B50E461D46114600F0D4F852
+:100D700004462946304600F0D8F82044001D70BDD6
+:100D80002DE9F04190460D4604004FF0000610D0CA
+:100D90000027E01C20F00300A04200D0FFDFDDB1FF
+:100DA00041460020FFF77DFD0C3000EB850617B1B2
+:100DB00012E00127EDE7614F04F10C00A9003C604F
+:100DC0002572606000EB85002060606813F063FFAF
+:100DD00041463868FFF765FD3046BDE8F0812DE9F2
+:100DE000FF4F564C804681B020689A46934600B922
+:100DF000FFDF2068027A424503D9416851F8280094
+:100E000020B143F2020005B0BDE8F08F51460298D0
+:100E100000F082F886B258460E9900F086F885B246
+:100E20007019001D87B22068A14639460068FFF797
+:100E300056FD04001FD0678025802946201D0E9D89
+:100E400007465A4601230095FFF768F92088314686
+:100E500038440123029ACDF800A0FFF75FF92088FB
+:100E6000C1193846FFF78AF9D9F800004168002017
+:100E700041F82840C7E70420C5E770B52F4C054668
+:100E8000206800B9FFDF2068017AA9420ED94268C4
+:100E900052F8251051B1002342F825304A880068E5
+:100EA000FFF748FD216800200A7A08E043F20200BB
+:100EB00070BD4B6853F8203033B9401CC0B2824239
+:100EC000F7D80868FFF700FD002070BD70B51B4E15
+:100ED00005460024306800B9FFDF3068017AA94276
+:100EE00004D9406850F8250000B1041D204670BDAB
+:100EF00070B5124E05460024306800B9FFDF306837
+:100F0000017AA94206D9406850F8251011B131F88C
+:100F1000040B4418204670BD10B50A460121FFF7A6
+:100F2000F6F8C01C20F0030010BD10B50A460121E0
+:100F3000FFF7EDF8C01C20F0030010BD700000208A
+:100F400070B50446C2F11005281913F003FE15F020
+:100F5000FF0108D0491EC9B2802060542046BDE878
+:100F6000704013F076BE70BD30B505E05B1EDBB29D
+:100F7000CC5CD55C6C40C454002BF7D130BD10B5AF
+:100F8000002409E00B78521E44EA430300F8013BB9
+:100F900011F8013BD2B2DC09002AF3D110BD2DE9D2
+:100FA000F04389B01E46DDE9107990460D000446F5
+:100FB00022D002460846F949FDF755FB102221468A
+:100FC0003846FFF7DCFFE07B000606D5F34A3946DA
+:100FD000102310320846FFF7C7FF10223946484653
+:100FE000FFF7CDFFF87B000606D5EC4A49461023F3
+:100FF00010320846FFF7B8FF1021204613F029FEF3
+:101000000DE0103EB6B208EB0601102322466846FA
+:10101000FFF7AAFF224628466946FDF724FB102E5B
+:10102000EFD818D0F2B241466846FFF789FF102387
+:101030004A46694604A8FFF797FF1023224604A9F1
+:101040006846FFF791FF224628466946FDF70BFBED
+:1010500009B0BDE8F08310233A464146EAE770B58F
+:101060009CB01E460546134620980C468DF8080095
+:10107000202219460DF1090013F06CFD20222146B3
+:101080000DF1290013F066FD17A913A8CDE90001A1
+:10109000412302AA31462846FFF781FF1CB070BDEC
+:1010A0002DE9FF4F9FB014AEDDE92D5410AFBB49C1
+:1010B000CDE90076202320311AA8FFF770FF4FF00A
+:1010C00000088DF808804FF001098DF8099054F858
+:1010D000010FCDF80A00A088ADF80E0014F8010C3D
+:1010E0001022C0F340008DF8100055F8010FCDF824
+:1010F0001100A888ADF8150015F8010C2C99C0F363
+:1011000040008DF8170006A8824613F023FD0AA8B8
+:1011100083461022229913F01DFDA048352308387C
+:1011200002AA40688DF83C80CDE900760E901AA99D
+:101130001F98FFF734FF8DF808808DF8099020681C
+:10114000CDF80A00A088ADF80E0014F8010C1022AA
+:10115000C0F340008DF810002868CDF81100A88871
+:10116000ADF8150015F8010C2C99C0F340008DF86E
+:101170001700504613F0EEFC58461022229913F047
+:10118000E9FC86483523083802AA40688DF83C906F
+:10119000CDE900760E901AA92098FFF700FF23B042
+:1011A000BDE8F08FF0B59BB00C460546DDE9221096
+:1011B0001E461746DDE92032D0F801C0CDF808C040
+:1011C000B0F805C0ADF80CC00078C0F340008DF851
+:1011D0000E00D1F80100CDF80F00B1F80500ADF810
+:1011E000130008781946C0F340008DF815001088E8
+:1011F000ADF8160090788DF818000DF11900102246
+:1012000013F0A8FC0DF129001022314613F0A2FCC6
+:101210000DF139001022394613F09CFC17A913A8D0
+:10122000CDE90001412302AA21462846FFF7B7FE77
+:101230001BB0F0BDF0B5A3B017460D4604461E46E0
+:10124000102202A8289913F085FC06A8202239460E
+:1012500013F080FC0EA82022294613F07BFC1EA967
+:101260001AA8CDE90001502302AA314616A8FFF7BB
+:1012700096FE1698206023B0F0BDF0B589B0044604
+:10128000DDE90E070D463978109EC1F340018DF857
+:10129000001031789446C1F340018DF801101968AF
+:1012A000CDF802109988ADF8061099798DF80810DC
+:1012B0000168CDF809108188ADF80D1080798DF89E
+:1012C0000F0010236A46614604A8FFF74DFE224630
+:1012D000284604A9FDF7C7F9D6F801000090B6F832
+:1012E0000500ADF80400D7F80100CDF80600B7F806
+:1012F0000500ADF80A000020039010236A4621463D
+:1013000004A8FFF731FE2246284604A9FDF7ABF9F1
+:1013100009B0F0BD1FB51C6800945B6801931368A9
+:10132000029352680392024608466946FDF79BF90C
+:101330001FBD10B588B00446106804905068059031
+:1013400000200690079008466A4604A9FDF78BF92D
+:10135000BDF80000208008B010BD1FB51288ADF8A0
+:1013600000201A88ADF80220002201920292039216
+:10137000024608466946FDF776F91FBD7FB5074B63
+:1013800014460546083B9A1C6846FFF7E6FF2246CE
+:1013900069462846FFF7CDFF7FBD00004851020097
+:1013A00070B5044600780E46012813D0052802D0F7
+:1013B000092813D10EE0A06861690578042003F0C4
+:1013C000B3F8052D0AD0782300220420616903F0C8
+:1013D00001F803E00420616903F0A6F831462046D5
+:1013E000BDE8704001F086B810B500F12D02C37958
+:1013F0009478411D64F003042340C371DB070DD0D2
+:101400004B79547923404B710B79127913400B714E
+:101410008278C9788A4200D9817010BD00224A7151
+:101420000A71F5E74178012900D00C21017070475D
+:101430002DE9F04F93B04FF0000B0C690D468DF87D
+:1014400020B0097801260C2017464FF00D084FF008
+:10145000110A4FF008091B2975D2DFE811F01B00B3
+:10146000C30206031E035D037003A203B703F80360
+:10147000190461049304A004EC042A053405520500
+:101480005D05EE053106340663067F06F9061D0785
+:10149000E606EB0614B120781D282AD0D5F808807E
+:1014A0005FEA08004FD001208DF82000686A022210
+:1014B0000D908DF824200A208DF82500A8690A9047
+:1014C000A8880028EED098F8001091B10F2910D20A
+:1014D0007ED2DFE801F07D1349DEFEFDFCFBFAF968
+:1014E00038089CF8F70002282DD124B120780C2868
+:1014F00001D00026EFE38DF82020CBE10420696ABB
+:1015000003F012F8A8880728EED1204600F0EDFF7E
+:10151000022809D0204600F0E8FF032807D920461A
+:1015200000F0E3FF072802D20120207004E0002C25
+:10153000B8D020780128D7D198F80400C11F0A2913
+:1015400002D30A2061E0C4E1A070D8F80010E16283
+:10155000B8F80410218698F8060084F832000120BB
+:1015600028700320207044E00728BDD1002C99D0BA
+:1015700020780D28B8D198F8031094F82F20C1F3E3
+:10158000C000C2F3C002104201D0062000E00720D4
+:10159000890707D198F805100142D2D198F80610B2
+:1015A0000142CED194F8312098F8051020EA0202C9
+:1015B0001142C6D194F8322098F8061090430142A7
+:1015C000BFD198F80400C11F0A29BAD2617D00E09A
+:1015D00006E281427ED8D8F800106160B8F80410A5
+:1015E000218198F80600A072012028700E2020703A
+:1015F00003208DF82000686A0D9004F12D000990F9
+:10160000601D0A900F300B9022E12875FDE3412800
+:1016100091D1204600F069FF042802D1E078C0078C
+:1016200004D1204600F061FF0F2884D1A88CD5F8A2
+:101630000C8080B24FF0400BE669FFF747FC324662
+:1016400041465B464E46CDF80090FFF732F80B203E
+:101650008DF82000686A0D90E0690990002108A8C3
+:10166000FFF79EFE2078042806D0A07D58B10128FF
+:1016700009D003280AD049E30520207003202870F0
+:101680008DF82060CDE184F800A032E712202070B0
+:10169000E9E11128BCD1204600F027FF042802D13F
+:1016A000E078C00719D0204600F01FFF062805D1BA
+:1016B000E078C00711D1A07D02280ED0204600F0AE
+:1016C00014FF08E0CAE081E06FE14EE121E101E1B1
+:1016D000E7E017E0ADE111289AD1102208F10101ED
+:1016E00004F13C0013F036FA607801287ED0122015
+:1016F0002070E078C00760D0A07D0028C8D0012805
+:10170000C6D05AE0112890D1204600F0EEFE0828FD
+:1017100004D0204600F0E9FE132886D104F16C00C5
+:10172000102208F10101064613F014FA2078082867
+:101730000DD014202070E178C8070DD0A07D0228BC
+:101740000AD06278022A04D00328A1D035E009200B
+:10175000F0E708B1012837D1C80713D0A07D0228CF
+:101760001DD000200090D4E9062133460EA8FFF7D3
+:1017700076FC10220EA904F13C0013F0BFF9C8B1A9
+:10178000042042E7D4E90912201D8DE8070004F186
+:101790002C0332460EA8616BFFF76FFDE9E7606B23
+:1017A000C1F34401491E0068C84000F0010040F048
+:1017B0008000D7E72078092806D185F800908DF8B9
+:1017C000209033E32870ECE30920FBE711289AD13D
+:1017D000204600F08AFE0A2802D1E078C00704D132
+:1017E000204600F082FE15288DD100E08DE104F145
+:1017F0003C00102208F10101064613F0ABF92078F5
+:101800000A2816D016202070D4E90932606B611DB9
+:101810008DE80F0004F15C0304F16C0247310EA85F
+:10182000FFF7C0FC10220EA9304613F067F918B17B
+:10183000F5E20B20207071E22046FFF7D5FDA0787D
+:10184000216A0A18C0F11001104613F002FA23E3CE
+:10185000394608A8FFF7A4FD06463BE20228B6D1A8
+:10186000204600F042FE042804D3204600F03DFE4E
+:10187000082809D3204600F038FE0E2829D3204638
+:1018800000F033FE122824D2A07D02289FD10E2022
+:101890008DF82000686A0D9098F801008DF82400FA
+:1018A000F0E3022893D1204600F01FFE002810D05C
+:1018B000204600F01AFE0128F9D0204600F015FE5F
+:1018C0000C28F4D004208DF8240098F801008DF83D
+:1018D00025005EE21128FCD1002CFAD020781728D0
+:1018E000F7D16178606A022911D0002101EB410132
+:1018F000182606EBC1011022405808F1010113F02F
+:1019000029F90420696A00F0E3FD2670F1E5012160
+:10191000ECE70B28DDD1002CDBD020781828D8D1BB
+:101920006078616A02281CD05FF0000000EB400282
+:10193000102000EBC2000958B8F801000880607858
+:10194000616A02280FD0002000EB4002142000EB57
+:10195000C2000958404650F8032F0A6040684860AA
+:1019600039E00120E2E70120EEE71128B1D1002C97
+:10197000AFD020781928ACD16178606A022912D0E2
+:101980005FF0000101EB41011C2202EBC1011022BA
+:10199000405808F1010113F0DDF80420696A00F0F5
+:1019A00097FD1A20B6E00121ECE7082891D1002C20
+:1019B0008FD020781A288CD1606A98F8012001789D
+:1019C00062F347010170616AD8F8022041F8012FE3
+:1019D000B8F8060088800420696A00F079FD8EE27C
+:1019E000072012E63878012894D1182204F1140057
+:1019F000796813F0F4F8E079C10894F82F0001EA4F
+:101A0000D001E07861F30000E070217D002974D1FD
+:101A10002178032909D0C00725D0032028708DF82C
+:101A20002090686A0D90412004E3607DA17888428F
+:101A300001D90620E9E502262671E179204621F048
+:101A4000E001E171617A21F0F0016172A17A21F087
+:101A5000F001A172FFF7C8FC2E708DF82090686A23
+:101A60000D900720E6E20420ACE6387805289DD1E9
+:101A70008DF82000686A0D90B8680A900720ADF8CC
+:101A800024000A988DF830B0616801602189818056
+:101A9000A17A817104202070F4E23978052985D17A
+:101AA0008DF82010696A0D91391D09AE0EC986E8BE
+:101AB0000E004121ADF824108DF830B01070A88CC4
+:101AC000D7F80C8080B24026A769FFF711FA41468B
+:101AD0003A463346C846CDF80090FEF71EFE002178
+:101AE00008A8FFF75DFCE07820F03E00801CE07065
+:101AF0002078052802D00F200CE049E1A07D20B11C
+:101B0000012802D0032802D002E10720BFE584F8B3
+:101B10000080EEE42070ECE4102104F15C0002F09F
+:101B20002AFA606BB0BBA07D18B1012801D0052056
+:101B3000FDE006202870F7486063A063BEE23878B5
+:101B4000022894D1387908B12875B3E3A07D022822
+:101B500002D0032805D022E0B8680028F5D06063E1
+:101B60001CE06078012806D0A07994F82E10012896
+:101B700005D0E84806E0A17994F82E00F7E7B868A8
+:101B80000028E2D06063E078C00701D0012902D0CC
+:101B9000E04803E003E0F8680028D6D0A063062000
+:101BA00010E68DF82090696A0D91E1784846C907E2
+:101BB00009D06178022903D1A17D29B1012903D07F
+:101BC000A17D032900D00720287031E1387805284D
+:101BD000BBD1207807281ED084F800A005208DF8FE
+:101BE0002000686A0D90B8680A90ADF824A08DF8BE
+:101BF00030B003210170E178CA070FD0A27D022A1C
+:101C00001AD000210091D4E9061204F15C03401CB3
+:101C1000FFF725FA67E384F80090DFE7D4E90923AA
+:101C2000211D8DE80E0004F12C0304F15C02401C20
+:101C3000616BFFF722FB56E3626BC1F34401491E5F
+:101C40001268CA4002F0010141F08001DAE73878F9
+:101C50000528BDD18DF82000686A0D90B8680A90FB
+:101C6000ADF824A08DF830B0042100F8011B10223B
+:101C700004F15C0112F06EFF002108A8FFF790FB51
+:101C80002078092801D0132044E70A2020709BE522
+:101C9000E078C10742D0A17D012902D0022927D0D6
+:101CA00038E0617808A8012916D004F16C01009190
+:101CB000D4E9061204F15C03001DFFF7BBFA0A2009
+:101CC000287003268DF82080686A0D90002108A8EE
+:101CD000FFF766FBDDE2C3E204F15C010091D4E9A9
+:101CE000062104F16C03001DFFF7A4FA0026E9E7C2
+:101CF000C0F3440114290DD24FF0006101EBB01084
+:101D00004FEAB060E0706078012801D01020BEE496
+:101D10000620FFE6607801283FF4B7AC0A2051E5C1
+:101D2000E178C90708D0A17D012903D10B202870D3
+:101D300004202FE028702DE00E2028706078616B61
+:101D4000012817D004F15C0304F16C020EA8FFF720
+:101D5000E1FA2046FFF748FBA0780EAEC0F1100173
+:101D6000304412F076FF06208DF82000686A09964C
+:101D70000D909AE004F16C0304F15C020EA8FFF7E9
+:101D8000C9FAE9E73978022903D139790029D1D094
+:101D900029758FE28DF82000686A0D9058E5387833
+:101DA0000728F6D1D4E909216078012808D004F188
+:101DB0006C00CDE90002029105D104F16C0304E04E
+:101DC00004F15C00F5E704F15C0304F14C007A686F
+:101DD0000646216AFFF764F96078012821D1A078CE
+:101DE000216A0A18C0F11001104612F032FFD4E93E
+:101DF0000923606B04F12D018DE80F0004F15C03F1
+:101E000004F16C0231460EA800E055E2FFF7CAF972
+:101E100010220EA904F13C0012F070FE08B10B2054
+:101E2000AFE485F8008000BF8DF82090686A0D90BF
+:101E30008DF824A00CE538780528AAD18DF820006B
+:101E4000686A0D90B8680A90ADF824A08DF830B09B
+:101E500080F80080617801291AD0D4E9093204F1B0
+:101E60002D01A66B03920096CDE9011304F16C03DA
+:101E700004F15C0204F14C01401CFFF793F90021CE
+:101E800008A8FFF78DFA6078012805D0152041E6F3
+:101E9000D4E90923611DE4E70E20287006208DF89F
+:101EA0002000686ACDF824B00D90A0788DF8280045
+:101EB000CEE438780328C0D1E079C00770D00F2075
+:101EC0002870072066E7387804286BD11422391D62
+:101ED00004F1140012F083FE616A208CA1F809005D
+:101EE000616AA078C871E179626A01F00301117238
+:101EF000616A627A0A73616AA07A81F82400162006
+:101F000060E485F800A08DF82090696A50460D9134
+:101F100090E00000485102003878052842D1B868A6
+:101F2000A8616178606A022901D0012100E00021E6
+:101F300001EB4101142606EBC1014058082102F0D3
+:101F40001AF86178606A022901D0012100E00021BD
+:101F500001EB410106EBC101425802A8E169FFF71C
+:101F60000DFA6078626A022801D0012000E00020AA
+:101F700000EB4001102000EBC1000223105802A921
+:101F80000932FEF7F1FF626AFD4B0EA80932A16922
+:101F9000FFF7E3F96178606A022904D0012103E0C8
+:101FA00042E18BE0BDE0002101EB4101182606EB88
+:101FB000C101A27840580EA912F0CCFD6178606A88
+:101FC000022901D0012100E0002101EB410106EBD3
+:101FD000C1014058A1780844C1F1100112F039FE46
+:101FE00005208DF82000686A0D90A8690A90ADF868
+:101FF00024A08DF830B0062101706278616A022A4F
+:1020000001D0012200E0002202EB420206EBC202F4
+:10201000401C8958102212F09DFD002108A8FFF7EE
+:10202000BFF91220C5F818B028708DF82090686AA2
+:102030000D900B208DF824000AE43878052870D123
+:102040008DF82000686A0D90B8680A900B20ADF8F2
+:1020500024000A98072101706178626A022901D080
+:10206000012100E0002101EB4103102101EBC3013C
+:1020700051580988A0F801106178626A022902D0DB
+:10208000012101E02FE1002101EB4103142101EBCB
+:10209000C30151580A6840F8032F4968416059E06C
+:1020A0001920287001208DF8300077E6162028705E
+:1020B0008DF830B0002108A8FFF772F9032617E168
+:1020C00014202870B0E6387805282AD18DF8200031
+:1020D000686A0D90B8680A90ADF824A08DF830B009
+:1020E00080F800906278616A4E46022A01D001228F
+:1020F00000E0002202EB42021C2303EBC202401C60
+:102100008958102212F026FD002108A8FFF748F98F
+:10211000152028708DF82060686A0D908DF8246075
+:102120003CE680E0387805287DD18DF82000686A8B
+:102130000D90B8680A90ADF824900921017061698A
+:10214000097849084170616951F8012FC0F80220EF
+:102150008988C18020781C28A8D1A1E7E078C00731
+:1021600002D04FF0060C01E04FF0070C6078022817
+:102170000AD04FF0000000BF00EB040101F109019B
+:1021800005D04FF0010004E04FF00100F4E74FF0FC
+:1021900000000B78204413EA0C030B7010F8092F91
+:1021A00002EA0C02027004D14FF01B0C84F800C04C
+:1021B000D2B394F801C0BCF1010F00D09BB990F8E4
+:1021C00000C0E0465FEACC7C04D028F0010606702F
+:1021D000102606E05FEA887C05D528F00206067026
+:1021E00013262E70032694F801C0BCF1020F00D014
+:1021F00092B991F800C05FEACC7804D02CF00106C7
+:102200000E70172106E05FEA8C7805D52CF00206E7
+:102210000E701921217000260078D0BBCAB3C3BB51
+:102220001C20207035E012E002E03878062841D109
+:102230001A2019E4207801283CD00C283AD02046F6
+:10224000FFF7F0F809208DF82000686A0D9031E062
+:102250003878052805D00620387003261820287005
+:1022600046E005218DF82010686A0D90B8680A9044
+:102270000220ADF8240001208DF830000A9801708A
+:10228000297D4170394608A8FFF78AF806461820CC
+:102290002870012E0ED02BE001208DF82000686AF6
+:1022A0000D9003208DF82400287D8DF8250085F8F9
+:1022B00014B012E0287D80B11D20207017202870F6
+:1022C0008DF82090686A0D9002208DF82400394620
+:1022D00008A8FFF765F806460AE00CB1FE2020705A
+:1022E0009DF8200020B1002108A8FFF759F810E45C
+:1022F00013B03046BDE8F08F2DE9F04387B00C46AF
+:102300004E6900218DF8041001202578034602272C
+:102310004FF007094FF0050C85B1012D53D0022D68
+:1023200039D1FE2030708DF80030606A05900320AE
+:102330008DF80400207E8DF8050063E021790129E5
+:1023400025D002292DD0032928D0042923D1B17DFD
+:10235000022920D131780D1F042D04D30A3D032D0D
+:1023600001D31D2917D12189022914D38DF80470B6
+:10237000237020899DF8041088421BD2082001E0B8
+:10238000405102008DF80000606A059057E07078B7
+:102390000128EBD0052007B0BDE8F0831D20307088
+:1023A000E4E771780229F5D131780C29F3D18DF861
+:1023B0000490DDE7083402F804CB94E80B0082E8CF
+:1023C0000B000320E7E71578052DE4D18DF800C058
+:1023D000656A0595956802958DF8101094F804804B
+:1023E000B8F1010F13D0B8F1020F2DD0B8F1030FDF
+:1023F0001CD0B8F1040FCED1ADF804700E202870B7
+:10240000207E687000216846FEF7CAFF0CE0ADF838
+:1024100004700B202870207E002100F01F006870DF
+:102420006846FEF7BDFF37700020B4E7ADF80470D2
+:102430008DF8103085F800C0207E68702770114636
+:102440006846FEF7ADFFA6E7ADF804902B70207F3D
+:102450006870607F00F00100A870A07F00F01F008E
+:10246000E870E27F2A71C0071CD094F8200000F0C9
+:102470000700687194F8210000F00700A87100219E
+:102480006846FEF78DFF2868F062A8883086A87934
+:1024900086F83200A069407870752879B0700D20F8
+:1024A0003070C1E7A9716971E9E700B587B0042808
+:1024B0000CD101208DF800008DF80400002005915A
+:1024C0008DF8050001466846FEF76AFF07B000BDBB
+:1024D00070B50C46054602F027F821462846BDE8AF
+:1024E00070407823002201F075BF08B10078704772
+:1024F0000C20704770B50C0005784FF000010CD02F
+:1025000021702146F2F7A9FE69482178405D884292
+:1025100001D1032070BD022070BDF2F79EFE0020A5
+:1025200070BD0279012A05D000220A704B78012B78
+:1025300002D003E0042070470A758A610279930093
+:10254000521C0271C15003207047F0B587B00F468E
+:1025500005460124287905EB800050F8046C70785A
+:10256000411E02290AD252493A46083901EB80003D
+:10257000314650F8043C2846984704460CB1012CDB
+:1025800011D12879401E10F0FF00287101D00324DA
+:10259000E0E70A208DF80000706A0590002101969E
+:1025A0006846FFF7A7FF032CD4D007B02046F0BD44
+:1025B00070B515460A46044629461046FFF7C5FF82
+:1025C000064674B12078FE280BD1207C30B1002063
+:1025D0002870294604F10C00FFF7B7FF2046FEF7EC
+:1025E00021FF304670BD704770B50E4604467C2111
+:1025F00012F051FB0225012E03D0022E04D005203B
+:1026000070BD0120607000E065702046FEF70AFF93
+:10261000A575002070BD28B1027C1AB10A4600F1F0
+:102620000C01C5E70120704710B5044686B00420B0
+:1026300001F07AFF2078FE2806D000208DF80000F7
+:1026400069462046FFF7E7FF06B010BD7CB50E4691
+:1026500000218DF804104178012903D0022903D00C
+:10266000002405E0046900E044690CB1217C89B1D3
+:102670006D4601462846FFF754FF032809D132462C
+:1026800029462046FFF794FF9DF80410002900D04A
+:1026900004207CBD04F10C05EBE730B40C46014688
+:1026A000034A204630BC034B0C3AFEF756BE0000EE
+:1026B000845102004051020070B50D46040011D053
+:1026C00085B12101284612F0C4FA10224E4928464D
+:1026D00012F040FA4C4801210838018044804560DE
+:1026E000002070BD012070BD70B5474E0024054626
+:1026F000083E10E07068AA7B00EB0410817B9142D9
+:1027000008D1C17BEA7B914204D10C22294612F008
+:10271000F5F930B1641C30888442EBDB4FF0FF30B8
+:1027200070BD204670BD70B50D46060006D02DB1B7
+:10273000FFF7DAFF002803DB401C14E0102070BD17
+:10274000314C083C20886288411C914201D9042008
+:1027500070BD6168102201EB0010314612F0FAF9E9
+:102760002088401C20802870002070BD70B5144661
+:102770000D0018D0BCB10021A170022802D0102891
+:1027800011D105E0288870B10121A170108008E006
+:102790002846FFF7A9FF002805DB401CA070A88988
+:1027A0002080002070BD012070BD70B50546144624
+:1027B0000E000BD000203070A878012808D005D971
+:1027C0001149A1F108010A8890420AD9012070BD7F
+:1027D00024B1287820702888000A507002200870E0
+:1027E0000FE064B14968102201EB00112046103956
+:1027F00012F0B0F9287820732888000A607310203E
+:102800003070002070BD00007C0000202DE9F041F8
+:1028100090460C4607460025FE48072F00EB881619
+:1028200007D2DFE807F007070707040404000125C3
+:1028300000E0FFDF06F81470002D13D0F54880305B
+:1028400000EB880191F82700202803D006EB400018
+:10285000447001E081F8264006EB440220205070CD
+:1028600081F82740BDE8F081F0B51F4614460E46BA
+:102870000546202A00D1FFDFE649E648803100EB1B
+:10288000871C0CEB440001EB8702202E07D00CEBD9
+:10289000460140784B784870184620210AE092F8AB
+:1028A0002530407882F82500F6E701460CEB410020
+:1028B00005704078A142F8D192F82740202C03D02F
+:1028C0000CEB4404637001E082F826300CEB410409
+:1028D0002023637082F82710F0BD30B50D46CE4B33
+:1028E00044190022181A72EB020100D2FFDFCB4814
+:1028F000854200DDFFDFC9484042854200DAFFDF44
+:10290000C548401C844207DA002C01DB204630BD5C
+:10291000C148401C201830BDBF48C043FAE710B57D
+:1029200004460168407ABE4A52F82020114450B152
+:102930000220084420F07F40F0F71DF994F90810B8
+:10294000BDE81040C9E70420F3E72DE9F047B14E98
+:10295000803696F82D50DFF8BC9206EB850090F893
+:10296000264034E009EB85174FF0070817F81400EC
+:10297000012806D004282ED005282ED0062800D005
+:10298000FFDF01F0E3F8014607EB4400427806EB75
+:10299000850080F8262090F82720A24202D120222C
+:1029A00080F82720084601F0DCF82A46214601205D
+:1029B000FFF72CFF9B48414600EB041002682046BD
+:1029C000904796F82D5006EB850090F82640202C75
+:1029D000C8D1BDE8F087022000E003208046D0E7A0
+:1029E00010B58C4C2021803484F8251084F82610F2
+:1029F00084F82710002084F8280084F82D0084F83B
+:102A00002E10411EA16044F8100B207460742073D6
+:102A10006073A0738449E0772075087048700021C6
+:102A20007C4A103C02F81100491CC9B22029F9D394
+:102A30000120EFF78EFF0020EFF78BFF012084F8D5
+:102A40002200F9F7A9F97948F9F7B5F9764CA41EEF
+:102A500020707748F9F7AFF96070BDE81040EFF7E4
+:102A600005BF10B5EFF727FF6F4CA41E2078F9F7CC
+:102A7000BBF96078F9F7B8F9BDE8104001F09EB8ED
+:102A8000202070472DE9F34F624E0025803606EB7B
+:102A9000810A89B09AF82500202822D0691E029167
+:102AA0006049009501EB00108146D0E90112C06831
+:102AB0000391CDE90420B08BADF81C00B07F8DF8F8
+:102AC0001E009DF81500C8B10227554951F8204055
+:102AD0000399E219114421F07F41019184B102214F
+:102AE0000FE00120EFF735FF0020EFF732FFEFF79F
+:102AF00000FF01F063F886F82F50A0E00427E4E718
+:102B000000218DF81810022801D0012820D1039847
+:102B1000391901440998081A9DF81C1020F07F40CB
+:102B200001B10221333181420BD203208DF815000F
+:102B30000398C4F13201401A20F07F403224039000
+:102B40000CE096F8240018B9F0F726FA00284CD0CB
+:102B5000322C03D214B101F025F801E001F02EF877
+:102B6000314A107818B393465278039B121B002108
+:102B70009DF81840984601281AD0032818D0002044
+:102B80008DF81E00002A04DD981A039001208DF8AC
+:102B900018009DF81C0000B102210398254A20F07E
+:102BA0007F40039003AB099801F014F810B110E0D6
+:102BB0000120E5E79DF81D0018B99BF800000328E7
+:102BC00012D08DF81C50CDF80C808DF818408DF87F
+:102BD0001E509DF8180058B103980123C119002216
+:102BE0001846EFF709FF06E000200BB0BDE8F08FB4
+:102BF0000120EFF7AEFE99F90C2001230020019986
+:102C0000EFF7FAFE012086F82F008AF828502022DC
+:102C1000694611E098080020FF7F841E0020A1076C
+:102C200094510200980600208E000020834201008B
+:102C30004B290100FFFF3F00F94811F0D0FF0120B0
+:102C4000D3E72DE9F05FDFF8D883064608EB86006E
+:102C500090F82550202D1FD0A8F180002C4600EBC5
+:102C60008617A0F50079DFF8BCB305E0A24607EBB4
+:102C70004A004478202C0AD0EFF70AFF09EB04132E
+:102C80005A4601211B1D00F0A5FF0028EED0AC42E2
+:102C900002D0334652461EE0E34808B1AFF300804D
+:102CA000EFF7F6FE98F82F206AB1D8F80C20411CF7
+:102CB000891A0902CA1701EB12610912002902DD03
+:102CC0000020BDE8F09F3146FFF7DCFE08B101208F
+:102CD000F7E733462A4620210420FFF7C5FDEFE73A
+:102CE0002DE9F041CE4C2569EFF7D2FE401B0002E2
+:102CF000C11700EB1160001200D4FFDF94F822002E
+:102D000000B1FFDF012784F8227094F82E002028FC
+:102D100000D1FFDF94F82E60202084F82E000025DB
+:102D200084F82F5084F8205084F82150BF48256043
+:102D30000078022833D0032831D000202077A06803
+:102D4000401C05D04FF0FF30A0600120EFF701FEDE
+:102D50000020EFF7FEFDEFF7FCFEEFF7F4FEEFF7D4
+:102D6000C8FD11F031F9B248056005604FF0E0216F
+:102D70004FF40040B846C1F88002EFF784FF94F8A2
+:102D80002D703846FFF75DFF0028FAD0A448803840
+:102D900000EB871010F81600022802D006E0012090
+:102DA000CCE73A4631460620FFF730FD84F8238011
+:102DB00004EB870090F82600202804D09B48801E52
+:102DC0004078F9F717F8207F002803D0EFF7B1FE1D
+:102DD0002577657746E50146914810B590F82D2096
+:102DE0000024803800EB821010F814302BB1641CE2
+:102DF000E4B2202CF8D3202010BD8E4800EB041044
+:102E0000016021460120FFF701FD204610BD10B5ED
+:102E1000012801D0032800D171B3814A92F82D30E6
+:102E20007F4C0022803C04EB831300BF13F8124058
+:102E30000CB1082010BD521CD2B2202AF6D37B4A16
+:102E400048B1022807D0072916D2DFE801F015069D
+:102E5000080A0C0E100000210AE01B2108E03A21AC
+:102E600006E0582104E0772102E0962100E0B52138
+:102E700051701070002010BD072010BD6B4810B5B8
+:102E80004078EFF778FE80B210BD10B5202811D23F
+:102E9000634991F82D30A1F1800202EB831414F8FC
+:102EA00010303BB191F82D3002EB831212F8102054
+:102EB000012A01D0002010BD91F82D2001460020EC
+:102EC000FFF7A4FC012010BD10B5EFF7E1FDBDE850
+:102ED0001040EFF750BE2DE9F0410E46504F0178FB
+:102EE0002025803F0C4607EB831303E0254603EBC8
+:102EF00045046478944202D0202CF7D108E0202CBD
+:102F000006D0A14206D103EB41014978017007E0E8
+:102F10000020A7E403EB440003EB45014078487030
+:102F2000454F7EB127B1002140F2DA30AFF3008087
+:102F30003078A04206D127B1002140F2DD30AFF356
+:102F40000080357027B1002140F2E230AFF30080FD
+:102F5000012087E410B542680B689A1A1202D41750
+:102F600002EB1462121216D4497A91B1427A82B9F4
+:102F7000324A006852F82110126819441044001DAA
+:102F8000891C081A0002C11700EB116000123228D8
+:102F900001DB012010BD002010BD2DE9F047814666
+:102FA0001F48244E00EB8100984690F825402020D1
+:102FB000107006F50070154600EB81170BE000BF9E
+:102FC00006EB04104946001DFFF7C4FF28B107EBCC
+:102FD00044002C704478202CF2D1297888F8001015
+:102FE00013E000BF06EB0415291D4846FFF7B2FFAA
+:102FF00068B988F80040A97B99F80A00814201D895
+:103000000020E6E407EB44004478202CEAD10120BC
+:10301000DFE42DE9FC410E4607460024054D18E08B
+:1030200018090020FFFF3F00000000008E00002074
+:1030300000F50040980600200000000094510200B6
+:103040009DF8000005EB00108168384600F0D6FDC1
+:1030500001246B4601AA31463846FFF79EFF00283F
+:10306000EED02046BDE8FC8170B50446FF4801253E
+:10307000A54300EB841100EB8510402211F06AFD9E
+:10308000FB4E26B1002140F25C40AFF30080F748D0
+:10309000803000EB850100EB8400D0F82500C1F8FA
+:1030A000250026B100214FF48C60AFF30080284644
+:1030B00070BD2DE9FC418446EC481546089C00EBA8
+:1030C00085170E4617F81400012803D0022801D0F6
+:1030D0000020C7E70B46E74A0121604600F07AFD71
+:1030E000A8B101AB6A4629463046FFF756FF70B1DA
+:1030F000DE489DF804209DF80010803000EB850626
+:103100008A4208D02B460520FFF7AEFB0BE02A468B
+:103110002146042014E0202903D007EB4100407829
+:1031200001E096F8250007EB440148709DF8000087
+:10313000202809D007EB400044702A46214603208E
+:10314000FFF764FB01208DE706F8254F0120F070A2
+:10315000F3E7C94901EB0010001DFFF7E0BB7CB5A8
+:103160001D46134604460E4600F108022146184645
+:10317000EFF70EFD94F908000F2804DD1F382072C8
+:103180002068401C206096B10220BC4951F82610EE
+:10319000461820686946801B20F07F40206094F923
+:1031A00008002844C01C1F2803DA012009E004207D
+:1031B000EBE701AAEFF7ECFC9DF8040010B10098D2
+:1031C000401C00900099206831440844C01C20F045
+:1031D0007F4060607CBD2DE9FE430C4606460978C1
+:1031E00060799072207998461546507241B19F4897
+:1031F000803090F82E1020290AD00069401D0BE085
+:10320000D4E90223217903B02846BDE8F043A6E7BC
+:103210009B484178701D084420F07F4721790022A7
+:103220002846A368FFF79BFF3946284600F0E6FCD6
+:10323000D4E9023221796846FFF791FF41462846DA
+:10324000019CFFF7E6FE2B4622460021304600F0A7
+:10325000C1FC002803D13146284600F0CFFCBDE870
+:10326000FE832DE9FE4F814600F084FC30B100273B
+:1032700099F8000020B10020BDE8FE8F0127F7E794
+:103280007A4D7B4C4FF0000A803524B1002140F28A
+:10329000D340AFF3008095F82D8085F823A0002659
+:1032A00024B100214FF49B60AFF300801FB940466A
+:1032B000FFF7DAFE804624B100214FF49C60AFF3A3
+:1032C0000080EFF7E5FB43466A464946FFF783FF78
+:1032D00024B1002140F2E640AFF3008095F82E00C3
+:1032E00020280CD029690098401A0002C21700EB70
+:1032F0001260001203D5684600F080FC012624B15C
+:1033000000214FF49E60AFF3008095F82300002861
+:10331000BBD124B1002140F2F640AFF30080EFF7BB
+:10332000B7FB6B46534A002100F054FC0028A3D0A1
+:1033300027B941466846FFF76CFE064326B168464A
+:10334000FFF7EDFAC9F8080024B1002140F2095056
+:10335000AFF3008001208FE72DE9FF5F8A468146A9
+:1033600000F008FC414C803410B39AF800000027AC
+:1033700010B1012800D0FFDF3D4D25B1002140F202
+:103380007F50AFF300800120A84600905FEA080656
+:1033900004D0002140F28750AFF30080009800F085
+:1033A000E0FB94F82D50002084F8230067B119E069
+:1033B00094F82E000127202800D1FFDF9AF80000A2
+:1033C0000028D9D0FFDFD7E72846FFF74DFE054696
+:1033D00026B1002140F29150AFF3008094F8230011
+:1033E0000028D3D126B1002140F29B50AFF30080DA
+:1033F000EFF74EFB83462B4601AA5146FFF7EBFE43
+:103400005FEA060804D0002140F2A250AFF300802A
+:103410003B462A4601A95846CDF80090FFF749FEE1
+:10342000064604EB850090F828B0B8F1000F04D0F0
+:10343000002140F2A950AFF3008000F087FB00901C
+:10344000B8F1000F04D0002140F2AF50AFF300807C
+:1034500094F82300002899D1B8F1000F04D000217E
+:1034600040F2B750AFF3008003490BE0980800200A
+:1034700000000000FFFF3F0098060020945102006A
+:103480008E00002001EB09100DF1040C00F1040086
+:103490009CE80E0080E80E004EB35FEA080604D0F8
+:1034A000002140F2C450AFF300803BEA070012D085
+:1034B00094F82E0020280ED126B1002140F2C950E8
+:1034C000AFF300802846FFF7BCFB20B99AF8000054
+:1034D000D8B3012849D0B8F1000F04D0002140F240
+:1034E000E650AFF30080284600F029FB01265FEA92
+:1034F000080504D0002140F2EF50AFF3008000989F
+:1035000000F02FFB25B1002140F2F350AFF3008013
+:103510008EB194F82D0004EB800090F8260020284E
+:1035200009D025B1002140F2FA50AFF30080F948EC
+:103530004078F8F75FFC25B1002140F2FF50AFF36F
+:10354000008004B03046BDE8F09FFFE7B8F1000FFF
+:1035500004D0002140F2D150AFF3008094F82D2028
+:1035600049460420FFF752F9C0E7002E3FF40EAFA2
+:10357000002140F2DC50AFF3008007E72DE9F84F5F
+:10358000E54D814695F82D004FF00008E34C4FF0D3
+:10359000010B474624B1002140F20D60AFF30080DB
+:1035A000584600F0DEFA85F8237024B1002140F27D
+:1035B0001260AFF3008095F82D00FFF755FD064629
+:1035C00095F8230028B1002CE4D000214FF4C3600B
+:1035D0004BE024B1002140F21C60AFF30080CE48E4
+:1035E000803800EB861111F81900032856D13346B4
+:1035F00005EB830A4A469AF82500904201D1012042
+:1036000000E0002000900AF125000021FFF763FC94
+:1036100001460098014203D001228AF82820AF77A2
+:10362000E1B324B1002140F22160AFF300803246C3
+:1036300049460120FFF7EAF89AF828A024B10021B2
+:1036400040F22C60AFF3008000F080FA834624B192
+:10365000002140F23160AFF3008095F8230038B1CB
+:10366000002C97D0002140F23560AFF3008091E745
+:10367000BAF1000F07D095F82E00202803D130466C
+:10368000FFF7DFFAE0B124B1002140F24960AFF367
+:103690000080304600F053FA4FF0010824B10021B9
+:1036A00040F25260AFF30080584600F05AFA24B15D
+:1036B000002140F25660AFF300804046BDE8F88F2D
+:1036C000002CF1D0002140F24460AFF30080E6E727
+:1036D0000020EFF717B90120EFF714B98D480078F3
+:1036E00070472DE9F0418C4C94F82E0020281FD112
+:1036F00094F82D6004EB860797F82550202D00D113
+:10370000FFDF8549803901EB861000EB45004078EA
+:1037100007F8250F0120F87084F82300294684F863
+:103720002E50324602202234FFF770F8002020701D
+:103730000FE42DE9F0417A4E774C012538B101288C
+:1037400021D0022879D003287DD0FFDFF0E700F0F8
+:1037500029FAFFF7C6FF207E00B1FFDF84F8215071
+:103760000020EFF7F6F8A168481C04D001230022DE
+:103770001846EFF741F914F82E0F217806EB0111E6
+:103780000A68012154E0FFF7ACFF0120EFF7E1F8F0
+:1037900094F8210050B1A068401C07D014F82E0FF7
+:1037A000217806EB01110A68062141E0207EDFF84E
+:1037B0006481002708F10208012803D002281ED0E6
+:1037C000FFDFB5E7A777EFF7B4F998F80000032813
+:1037D00001D165772577607D524951F8200094F832
+:1037E000201051B948B161680123091A0022184616
+:1037F000EFF702F9022020769AE7277698E784F817
+:10380000205000F0CFF9A07F50B198F80100616816
+:103810000123091A00221846EFF7EEF8257600E09A
+:10382000277614F82E0F217806EB01110A68002183
+:10383000BDE8F041104700E005E036480078BDE8FB
+:10384000F041F8F7D7BAFFF74CFF14F82E0F2178A4
+:1038500006EB01110A680521EAE710B52E4C94F831
+:103860002E00202800D1FFDF14F82E0F21782C4ADB
+:1038700002EB01110A68BDE81040042110477CB535
+:10388000254C054694F82E00202800D1FFDFA068C3
+:10389000401C00D0FFDF94F82E00214901AA01EB63
+:1038A0000010694690F90C002844EFF771F99DF972
+:1038B00004000F2801DD012000E0002000990844E9
+:1038C0006168084420F07F41A16094F8210000283D
+:1038D00007D002B00123BDE8704000221846EFF780
+:1038E0008BB87CBD30B5104A0B1A541CB3EB940F47
+:1038F0001ED3451AB5EB940F1AD3934203D9101A6D
+:1039000043185B1C14E0954210D9511A0844401C1E
+:1039100043420DE08C000020180900200000000048
+:103920009806002094510200FF7F841EFFDF0023D1
+:10393000184630BD0123002201460220EFF75CB893
+:103940000220EFF706B8EFF7A3B82DE9FC47B14C1A
+:10395000054694F82E00202800D1FFDF642D58D3AF
+:10396000AD4A0021521B71EB010052D394F82E2076
+:10397000A0462046DFF8A49290F82D7009EB0214BF
+:10398000D8F8000001AA28446946EFF701F99DF92B
+:103990000400002802DD0098401C0090A0680099F7
+:1039A00062684618B21A22F07F42B2F5800F30D218
+:1039B00008EB8702444692F82520202A0AD009EB1A
+:1039C00002125268101A0002C21700EB12600012B5
+:1039D00088421EDBA068401C10D0EFF759F8A168A0
+:1039E000081A0002C11700EB11600012022810DD56
+:1039F0000120EEF7AEFF4FF0FF30A06020682844B2
+:103A0000206026F07F402061012084F82300BDE87B
+:103A1000FC870020FBE72DE9F0477E4C074694F831
+:103A20002D00A4F1800606EB801010F8170000B9F5
+:103A3000FFDF94F82D50A046794C24B1002140F6C8
+:103A40006500AFF3008040F6710940F67A0A06EB94
+:103A5000851600BF16F81700012818D0042810D0CA
+:103A600005280ED006280CD01CB100214846AFF323
+:103A7000008020BF002CEDD000215046AFF3008025
+:103A8000E8E72A4639460120FEF7C0FEF2E74FF08C
+:103A9000010A4FF00009454624B1002140F681009B
+:103AA000AFF30080504600F05CF885F8239024B115
+:103AB000002140F68600AFF3008095F82D00FFF757
+:103AC000D3FA064695F8230028B1002CE4D0002153
+:103AD00040F68C001FE024B100214FF40960AFF3E1
+:103AE000008005EB860000F1270133463A46263078
+:103AF000FFF7F1F924B1002140F69400AFF3008004
+:103B000000F024F8824695F8230038B1002CC3D089
+:103B1000002140F69A00AFF30080BDE785F82D60E4
+:103B2000012085F82300504600F01BF8002C04D03B
+:103B3000002140F6A700AFF30080BDE8F0873549CB
+:103B400081F82D00012081F82300704710B5354819
+:103B500008B1AFF30080EFF3108000F0010072B6FF
+:103B600010BD10B5002804D12F4808B1AFF3008074
+:103B700062B610BD2D480068C005C00D10D01038C9
+:103B800040B2002806DA00F00F0000F1E02090F8C3
+:103B9000140D03E000F1E02090F8000440097047A4
+:103BA0000820704710B51B4C94F82400002804D15D
+:103BB000F7F7D2FE012084F8240010BD10B5154C93
+:103BC00094F82400002804D0F7F7EFFE002084F8D2
+:103BD000240010BD10B51C685B68241A181A24F064
+:103BE0007F4420F07F40A14206D8B4F5800F03D275
+:103BF000904201D8012010BD002010BDD0E9003254
+:103C0000D21A21F07F43114421F07F41C0E90031F5
+:103C10007047000018090020FF1FA1079806002028
+:103C200000000000000000000000000004ED00E0C3
+:103C30002DE9F041044680074FF000054FF00106E2
+:103C400004D55C480560066024F00204E0044FF0EF
+:103C5000FF3705D558484660C0F8087324F48054EF
+:103C6000600003D55548056024F08044E0050FD579
+:103C70005348C0F80052C0F8087352490D60091D3E
+:103C80000D60504A04210C321160066124F48074E6
+:103C9000A00409D54C484660C0F80052C0F808732B
+:103CA0004A48056024F40054C4F38030C4F3C031A2
+:103CB000884200D0FFDF14F4404F14D044484660DF
+:103CC000C0F8087343488660C0F80052C0F8087313
+:103CD00041490D600A1D16608660C0F808730D60CA
+:103CE000166024F4404420050AD53C4846608660AE
+:103CF000C0F80873C0F848733948056024F40064BC
+:103D000010F03CF93748044200D0FFDFBDE8F081F5
+:103D100070B520250022134620FA02F1C90719D0F8
+:103D200051B201F01F060124B4404E09B60006F15D
+:103D3000E026C6F88041C6F88042002906DA01F084
+:103D40000F0101F1E02181F8143D03E001F1E021D0
+:103D500081F80034521CAA42DED370BD70B5224CEB
+:103D60000D462060FFF764FF2068FFF7D1FF28466B
+:103D7000F7F7CFFE0FF022FD00F0ADF810F0FEF8DF
+:103D800010F041F8F8F708F8BDE870400FF0C4BD36
+:103D900010B5154C2068FFF74BFF2068FFF7B8FF00
+:103DA00010F0ECF8F7F773FF0020206010BD0A2038
+:103DB00070470000FC1F004000C0004004E50140C7
+:103DC000008000400485004000D0004004D5004041
+:103DD00000E0004000F0004000F5004000B000406E
+:103DE00008B50040FEFF0FFD9000002070B5264989
+:103DF0000A680AB30022154601244B685B1C4B601D
+:103E00000C2B00D34D600E7904FA06F30E681E42A7
+:103E10000FD0EFF3108212F0010272B600D001222F
+:103E20000C689C430C6002B962B6496801600020CE
+:103E300070BD521C0C2AE0D3052070BD4FF0E0216C
+:103E40004FF48000C1F800027047EFF3108111F0C9
+:103E5000010F72B64FF0010202FA00F20A4803683D
+:103E600042EA0302026000D162B6E7E70648002199
+:103E700001604160704701218140034800680840AB
+:103E800000D0012070470000940000202DE9F0418F
+:103E900015460E460446002700F0E7F8A84215D361
+:103EA000002341200FE000BF94F84220A25CF254AE
+:103EB00094F84210491CB1FBF0F200FB12115B1C9C
+:103EC00084F84210DBB2AB42EED3012700F0D9F800
+:103ED0003846BDE8F081704910B5802081F80004B3
+:103EE0006E49002081F8420081F84100433181F899
+:103EF000420081F84100433181F8420081F84100DD
+:103F000067480FF071FE6648401C0FF06DFEEEF73B
+:103F1000C9FEBDE8104000F0B4B8402070475F48CB
+:103F200000F0A3B80A4601465C48AFE7402070475E
+:103F30005A48433000F099B80A4601465748433082
+:103F4000A4E7402101700020704710B50446534893
+:103F5000863000F08AF82070002010BD0A46014625
+:103F60004E4810B58630FFF791FF08B1002010BD14
+:103F700042F2070010BD70B50C460546412900D934
+:103F8000FFDF48480068103840B200F050F8C6B271
+:103F90000D2000F04CF8C0B2864203D2FFDF01E0F2
+:103FA000EEF7D0FE224629463C48FFF76FFF002877
+:103FB000F6D070BD2DE9F041394F002506463F1D72
+:103FC00057F82540204600F041F810B36D1CEDB2C3
+:103FD000032DF5D33148433000F038F8002825D0C0
+:103FE0002E4800F033F8002820D02C48863000F00E
+:103FF0002DF800281AD0EEF77BFE29480FF0FCFDC3
+:10400000B0F5005F00D0FFDFBDE8F04124480FF0BD
+:1040100009BE94F841004121265414F8410F401C78
+:10402000B0FBF1F201FB12002070D3E751E700284A
+:1040300006DA00F00F0000F1E02090F8140D03E024
+:1040400000F1E02090F800044009704710F8411F8B
+:104050004122491CB1FBF2F302FB1311407881426B
+:1040600001D1012070470020704710F8411F4078AF
+:10407000814201D3081A02E0C0F141000844C0B2F5
+:10408000704710B506480FF0B7FD002803D1BDE812
+:104090001040EEF718BE10BD0DE000E0480900200A
+:1040A0009C00002004ED00E070B5154D2878401C00
+:1040B000C4B26878844202D0EEF7D5FE2C7070BD91
+:1040C0002DE9F0410E4C4FF0E02600BFEEF7C0FEA8
+:1040D00020BF40BF20BF677820786070D6F80052BC
+:1040E000EDF71CF9854305D1D6F8040210B9207804
+:1040F000B842EBD0EEF7A7FE0020BDE8F08100004B
+:10410000AC0000202DE9F041012528034FF0E0210B
+:104110000026C1F880011E4CC4F800610C2000F09C
+:104120002CF81C4801680268C94341F3001142F0B1
+:1041300010020260C4F804532560491C00E020BF4F
+:10414000D4F80021002AFAD019B9016821F0100131
+:104150000160114807686560C4F80853C4F800613D
+:104160000C2000F00AF83846BDE8F08110B504468E
+:10417000FFF7C8FF2060002010BD00F01F020121E2
+:1041800091404009800000F1E020C0F880127047A3
+:1041900000C0004010ED00E008C500402DE9F047E8
+:1041A000FF4C0646FF21A06800EB06121170217833
+:1041B000FF2910D04FF0080909EB011109EB061790
+:1041C0004158C05900F0F4F9002807DDA1682078B3
+:1041D00001EB061108702670BDE8F08794F80080A6
+:1041E00045460DE0A06809EB05114158C05900F0A3
+:1041F000DFF9002806DCA068A84600EB0810057867
+:10420000FF2DEFD1A06800EB061100EB08100D7038
+:104210000670E1E7F0B5E24B0446002001259A68FC
+:104220000C269B780CE000BF05EB0017D75DA7427A
+:1042300004D106EB0017D7598F4204D0401CC0B2FE
+:104240008342F1D8FF20F0BD70B5FFF77CFBD44C62
+:1042500008252278A16805EB0212895800F0A8F918
+:10426000012808DD2178A06805EB01114058BDE860
+:104270007040FFF75FBBFFF731FABDE87040F7F71A
+:10428000B9BD2DE9F041C64C2578FFF75CFBFF2D49
+:104290006ED04FF00808A26808EB0516915900F09F
+:1042A00087F90228A06801DD80595DE000EB051167
+:1042B00009782170022101EB0511425C5AB1521EAE
+:1042C0004254815901F5800121F07F4181512846F6
+:1042D000FFF764FF34E00423012203EB051302EB34
+:1042E000051250F803C0875CBCF1000F10D0BCF57C
+:1042F000007F10D9CCF3080250F806C00CEB423C0A
+:104300002CF07F4C40F806C0C3589A1A520A09E0B4
+:10431000FF2181540AE0825902EB4C3222F07F42A5
+:104320008251002242542846FFF738FF0C21A06832
+:1043300001EB05114158E06850F8272038469047B6
+:104340002078FF2814D0FFF7FEFA2278A16808EB46
+:1043500002124546895800F02BF9012893DD217897
+:10436000A06805EB01114058BDE8F041FFF7E2BA43
+:10437000BDE8F081F0B51D4614460E460746FF2BFA
+:1043800000D3FFDFA00700D0FFDF8548FF21002218
+:10439000C0E90247C5700671017042708270104614
+:1043A000012204E002EB0013401CE154C0B2A84219
+:1043B000F8D3F0BD70B57A4C064665782079854211
+:1043C00000D3FFDFE06840F825606078401C607033
+:1043D000284670BD2DE9FF5F1D468B460746FF242A
+:1043E000FFF7B1FADFF8B891064699F80100B84234
+:1043F00000D8FFDF00214FF001084FF00C0A99F8B8
+:104400000220D9F808000EE008EB0113C35CFF2B73
+:104410000ED0BB4205D10AEB011350F803C0DC45B6
+:104420000CD0491CC9B28A42EED8FF2C02D00DE054
+:104430000C46F6E799F803108A4203D1FF2004B036
+:10444000BDE8F09F1446521C89F8022008EB0411C5
+:104450000AEB0412475440F802B00421029B0022E8
+:10446000012B01EB04110CD040F801204FF400782F
+:1044700008234FF0020C454513D9E905C90D02D0B8
+:1044800002E04550F2E7414606EB413203EB0413EC
+:1044900022F07F42C250691A0CEB0412490A81547F
+:1044A0000BE005B9012506EB453103EB041321F0C0
+:1044B0007F41C1500CEB0411425499F80050204642
+:1044C000FFF76CFE99F80000A84201D0FFF7BCFE90
+:1044D0003846B4E770B50C460546FFF734FA064691
+:1044E00021462846FFF796FE0446FF281AD02C4D99
+:1044F000082101EB0411A8684158304600F058F833
+:1045000000F58050C11700EBD14040130221AA688A
+:1045100001EB0411515C09B100EB4120002800DCE3
+:10452000012070BD002070BD2DE9F047884681460E
+:10453000FFF770FE0746FF281BD0194D2E78A8689C
+:104540003146344605E0BC4206D0264600EB061252
+:104550001478FF2CF7D10CE0FF2C0AD0A6420CD126
+:1045600000EB011000782870FF2804D0FFF76CFEE4
+:1045700003E0002030E6FFF7E3F941464846FFF745
+:10458000A9FF0123A968024603EB0413FF20C854C6
+:10459000A878401EB84200D1A87001EB041001E0D9
+:1045A000140A002001EB061100780870104613E68B
+:1045B000081A0002C11700EB1160001270470000DA
+:1045C00070B50446A0F500002D4EB0F1786F02D210
+:1045D0003444A4F500042B48844201D2012500E0B4
+:1045E000002500F043F848B125B9B44204D3264869
+:1045F000006808E0012070BD002070BD002DF9D1D9
+:10460000B442F9D321488442F6D2F3E710B5044608
+:10461000A0F50000B0F1786F03D219480444A4F566
+:10462000000400F023F84FF0804130B116480068D4
+:1046300004E08C4204D2012003E014488442F8D202
+:10464000002080F0010010BD10B520B1FFF7DEFFA3
+:1046500008B1012010BD002010BD10B520B1FFF73A
+:10466000AFFF08B1012010BD002010BD0848094966
+:104670000068884201D10120704700207047000087
+:104680000000002000600200200000200800002040
+:10469000B0000020BEBAFECA0548064A0168914231
+:1046A00001D1002101600449012008607047000029
+:1046B000B0000020BEBAFECA40E5014053480021C8
+:1046C0000170417010218170704770B50546164623
+:1046D0000C460220EEF785F84C49012008704C4941
+:1046E000F01E08604B480560001F046070BD10B5E7
+:1046F0000220EEF776F8454901200870464800216F
+:10470000C0F80011C0F80411C0F8081143494FF473
+:104710000000086010BD3D480178C9B1404A4FF41F
+:10472000000111603C49D1F800310022002B1CBF70
+:10473000D1F80431002B02D0D1F8081111B1427028
+:10474000102103E00121417036490968817002702F
+:104750000020EEF746B82D480178002904BF4078C4
+:1047600070472D48D0F80011002904BF022070477F
+:10477000D0F8001100291CBFD0F80411002905D081
+:10478000D0F80801002804BF0120704700207047BE
+:104790001E4800B50278204B4078C821491EC9B296
+:1047A00082B1D3F800C1BCF1000F10D0D3F80001E2
+:1047B00000281CBFD3F8040100280BD0D3F808014F
+:1047C00050B107E0022802D0012805D002E00029FC
+:1047D000E4D1FFDF002000BD012000BD0B480178BF
+:1047E000002904BF807870470B48D0F800110029D9
+:1047F0001CBFD0F80411002902D0D0F8080108B17C
+:104800001020704707480068C0B27047B40000200D
+:1048100010F5004008F5004000F0004004F50140AC
+:1048200008F5014000F40040524800210170417039
+:10483000704770B5064614460D460120EDF7D1FFCE
+:104840004D480660001D0460001D05604B490020B6
+:10485000C1F850014A49032008604B4949480860A3
+:10486000091D4A48086070BD70B5424B012540EAF9
+:1048700002421D70464B42F080721A60454A116038
+:10488000454C0026C4F80461454A4449116000289B
+:1048900002BFC4F80052256070BD012818BFFFDFB9
+:1048A000C4F80062256040493E48086070BD314848
+:1048B000017871B13A4A394911603749D1F8042178
+:1048C0000021002A08BF417002D0384A12684270A5
+:1048D00001700020EDF785BF26480178002904BF4C
+:1048E000407870472C48D0F80401002808BF704772
+:1048F0002E480068C0B27047002808BF704730B526
+:104900001C480078002808BFFFDF2348D0F80411B6
+:10491000002918BF30BD0224C0F80443DFF890C05E
+:10492000DCF80010C1F30015DCF8001041F01001B4
+:10493000CCF80010D0F80411002904BF4FF4004156
+:104940004FF0E02207D100BFC2F8801220BFD0F89C
+:104950000431002BF8D02DB9DCF8001021F0100143
+:10496000CCF80010C0F8084330BD0B490120886026
+:1049700070470000B700002008F50040001000401C
+:104980001CF500405011004098F501400CF000402B
+:1049900004F5004018F5004000F00040000002035C
+:1049A00008F501400000020204F5014000F4004057
+:1049B00010ED00E010B5FF480024012144700470A0
+:1049C00044728472C17280F821408462446314305E
+:1049D00010F068FAF849601E0860091D0860091D9A
+:1049E0000C60091D0860091D0C60091D0860091D87
+:1049F0000860091D0860091D0860091D0860091D7F
+:104A00000860091D0860091D0860091D086010BDC7
+:104A1000EA48016801F00F01032904BF0120704733
+:104A2000016801F00F01042904BF022070470168EA
+:104A300001F00F01052904D0006800F00F000628DE
+:104A400007D1DF48006810F0060F0CBF08200420D3
+:104A5000704700B5FFDF012000BD30B4D5490268C2
+:104A6000DFF864C34A6142688A61007A08770A7D88
+:104A7000D44BACF1040401204AB10A7E00FA02F2E0
+:104A80001A608D7D002D0CBF2260CCF800204A7D7D
+:104A9000002A04BF30BC70474A7E90401860C97D30
+:104AA00000290CBF2060CCF8000030BC704730B546
+:104AB0000024054601290AD0022908BF4FF080745E
+:104AC00005D0042916BF08294FF0C744FFDF44F47E
+:104AD000847040F48010BD49086045F44030091DE1
+:104AE00040F00070086030BD30B500240546012953
+:104AF0000AD0022908BF4FF0807405D0042916BFE0
+:104B000008294FF0C744FFDF44F4847040F480105C
+:104B1000AE49086045F44030091D40F0007008605F
+:104B2000AB48D0F80001002818BFFFDF30BD0221DC
+:104B300010B44FF0E02301200022C3F88011DFF809
+:104B400094C2CCF80020CCF80000DFF88CC2DCF86E
+:104B5000004024F07044CCF80040A04C40F25B6C64
+:104B6000C4F800C0241F40F2031CC4F800C0A4F124
+:104B7000040CCCF80000DFF844C20320CCF800009D
+:104B8000DFF85CC29620CCF80000DFF85CC29548E4
+:104B9000CCF80000DFF858C29448CCF80000ACF123
+:104BA000040C9448CCF80000C3F880128849102007
+:104BB000C1F804037F4880F82D2010BC70477D4A5F
+:104BC0000368C2F802308088D08011727047794B38
+:104BD00010B51A7A8A4208D101460622981C0FF0B5
+:104BE0008DFF002804BF012010BD002010BD7148BA
+:104BF00090F8210070476F4A517010707047F0B5FF
+:104C00000546800000F1804000F580508B88C0F898
+:104C100020360B78D1F8011043EA0121C0F80016C4
+:104C200005F10800012707FA00F6734C002A04BFBB
+:104C30002068B04304D0012A18BFFFDF206830434A
+:104C40002060206807FA05F108432060F0BD0FF0EE
+:104C5000DDBA584890F82E007047564890F830005A
+:104C60007047664AC17811600068654900020860B3
+:104C70007047252808BF02210ED0262808BF1A2118
+:104C80000AD0272808BF502106D00A2894BF042242
+:104C9000062202EB4001C9B25A4A11605A49086023
+:104CA0007047F0B4434B9D7A012D62D0022D1CBF9A
+:104CB000F0BC704793F815C0BCF1000F04BFF0BC06
+:104CC000704700BF514C524F4FF47A7C012D57D0A2
+:104CD000DE7D5D7E002E18BF0126012908BF292137
+:104CE0000CD0022A0CBF4B4C012A03D0042A0CBF63
+:104CF0003C46494C04F2E141B1FBFCF1491F084438
+:104D00004649086046490020C1F84C01280286F057
+:104D1000010140EA015040F00311187F820002F1C6
+:104D2000804202F5C042C2F810153E4901EB8002F4
+:104D3000997EC80000F1804000F5F830C0F81425D5
+:104D4000DFF8E4C0C0F810C5D87EC30003F180438B
+:104D500003F5F833C3F81425264AC3F810250122B9
+:104D600002FA01F102FA00F0084330490860F0BC91
+:104D7000704793F814C0BCF1000FA3D1F0BC70478A
+:104D80009E7D1D7E002E18BF012601295DD0022ABE
+:104D900004BF274C4FF47A7151D0012A08BF4FF459
+:104DA000C8614CD0042A06BF3C4640F69801214C0D
+:104DB00042E00000240A0020000E004010150040D0
+:104DC00014140040180500500C0500501415004044
+:104DD00000100040FC1F00407817004038150040CC
+:104DE0004415004000000C0408F5014040800040DC
+:104DF000A4F5014010110040401600402415004069
+:104E00001C1500400815004054150040A224020063
+:104E1000D0FB010004360200C0D401004C850040E4
+:104E200000800040006000404C81004004F50140DB
+:104E30006836020030D3010018BF40F6E441214437
+:104E400001F5FA71B1FBFCF158E7022A08BF4FF4F3
+:104E50007A710AD0012A08BF4FF4C86105D0042A2C
+:104E60000CBF40F6980140F6E44149F6FC6211445B
+:104E7000E8E72DE9F047FC4D0446032090468946BB
+:104E8000C5F80002FA49F948086048460FF011FADF
+:104E900040460FF0F9F9F74F0126002C04BFBE720F
+:104EA0002E6007D0012C05D140460FF051FB0220A7
+:104EB000B8726E60F048C664F048006842464946E1
+:104EC000BDE8F047EDE62DE9F0410F46E64905461D
+:104ED00003201646C1F80002E54CE448206038463D
+:104EE0000FF0E7F930460FF0CFF930460FF030FB06
+:104EF000E04815B1012D09D011E001218172416B0B
+:104F000041F4801141634FF4801007E00221817267
+:104F1000416B41F4001141634FF4001020603246B0
+:104F20003946BDE8F0410020BBE62DE9FF4FCE4CED
+:104F30008246002581B003208946C4F80002CC4F88
+:104F4000CA48386003980FF0B4F904980FF09CF940
+:104F5000DFF82CB3C74E4FF00108BAF1000F03D0B1
+:104F6000BAF1010F21D035E0CBF8004096F82D00C2
+:104F7000012806D0022818BFFFDF0CD086F80A806F
+:104F800028E0DDE9031396F82C2048460FF012FACA
+:104F9000B16A4518F2E7DDE9031296F82C3048466D
+:104FA0000FF096F9B16A4518E8E704980FF0D0FAC7
+:104FB000B448CBF8000096F82D00DDE90313012872
+:104FC00096F82C20484624D00FF03EFAB16A4518D6
+:104FD0000220B072AC480560AD49AC480860706B07
+:104FE00040F400207063D4F800924FF0100AC4F827
+:104FF00008A30026C4F80062A6484FF4802BC0F82E
+:1050000000B0FF208DF80000C4F81061C4F81080D3
+:1050100009E00FF09BF9B16A4518D9E79DF8000047
+:10502000401E8DF800009DF8000018B1D4F8100162
+:105030000028F3D09DF80000002808BFFFDFC4F867
+:105040000061C4F80C61C4F81061C4F80461C4F8CC
+:105050001461C4F81861904800680090C4F8009288
+:10506000C7F800B0C4F804A34FF4002038608248A9
+:10507000C0F84C8081480068A84228BFFFDF28465E
+:10508000DDE9031205B0BDE8F04F0AE62DE9F84767
+:10509000754CD4F8000220F00B09D4F804034FF04B
+:1050A000100AC0F30018C4F808A30026C4F8006270
+:1050B00078497A4808606F4D0127A87A012802D004
+:1050C000022803D014E0287D10B911E0687D78B182
+:1050D000A87EEA7E07FA00F007FA02F210430860A1
+:1050E000287F800000F1804000F5C040C0F81065C6
+:1050F000FF208DF80000C4F81061276105E000BFB3
+:105100009DF80000401E8DF800009DF8000018B1C9
+:10511000D4F810010028F3D09DF80000002808BF43
+:10512000FFDFC4F810616E72AE72EF72C4F80092C5
+:10513000B8F1000F18BFC4F804A3BDE8F8870068F1
+:10514000574920F07F40086070474FF0E02002216F
+:10515000C0F88011C0F8801270474FF0E0210220A3
+:10516000C1F8000170474F49087070474E49086008
+:10517000704730B53F4C0546A06AA84228BFFFDF04
+:105180000120207300203C492561C1F844014748B3
+:105190000560606B40F480006063C80134490860BA
+:1051A00030BD70B5334C0546414A0220207310686B
+:1051B0000E4600F00F00032808BF012213D010682C
+:1051C00000F00F00042808BF02220CD0106800F085
+:1051D0000F0005281BD0106800F00F0006281CBF28
+:1051E000FFDF012213D094F82D0094F82C10012831
+:1051F00015D028460FF086F91F4920610020C1F81C
+:1052000044012169A06A08442849086070BD294802
+:10521000006810F0060F0CBF08220422E3E73346B3
+:1052200028460FF038F9E7E71A494FF48000086084
+:105230001048416B21F480014163002101737047E4
+:10524000C20002F1804202F5F8321B4BC2F8103561
+:10525000C2F8141501218140054801600548426BE0
+:105260001143416370470000001000400000040437
+:1052700004F50140240A0020008000404C850040D5
+:10528000ACF50140041000404885004048810040D2
+:10529000A8F5014008F501401811004000000C0479
+:1052A0003C150040B9000020041500404485004032
+:1052B000101500401414004004110040FB48012167
+:1052C0004160C1600021C0F84411F9480160F9480B
+:1052D00081627047F8490860F848D0F8001241F040
+:1052E0004001C0F800127047F448D0F8001221F0D5
+:1052F0004001C0F80012F049002008607047EF48F4
+:10530000D0F8001221F01001C0F8001201218161D3
+:105310007047EA480021C0F81C11D0F8001241F093
+:105320001001C0F800127047E44981B0D1F81C2187
+:10533000012A1EBF002001B07047E14A126802F046
+:105340007F02524202700020C1F81C01DD48006853
+:105350000090012001B0704730B50C00054608BF31
+:10536000FFDF14F0010F1CBF012CFFDF002D0CBF6D
+:1053700001200220CF4901284872CC72CF4904BFD6
+:10538000D1F8000240F0040007D0022807BFD1F88E
+:10539000000240F00800FFDF30BDC1F8000230BD60
+:1053A0002DE9F84FDFF8209399F80000042828BF72
+:1053B000FFDFDFF8F8A2DAF84C11C448BD4C002634
+:1053C0004FF00108D1B1A17A012902D0022903D0FE
+:1053D00014E0217D11B911E0617D79B1A17EE27EF9
+:1053E00008FA01F108FA02F211430160217F8900F5
+:1053F00001F1804101F5C041C1F81065B348616B0E
+:1054000001606663217B002019B1DAF8441101299B
+:1054100000D00021A27AA94D012A71D0022A76D0AB
+:10542000D5F8101101290CBF1021002141EA000715
+:10543000A748016811F0FF0F03D0D5F81411012916
+:1054400000D0002184F82E10006810F0FF0F03D068
+:10545000D5F81801012800D0002084F82F009D48BD
+:10546000006884F83000FFF776F9012818BF0020A3
+:1054700084F83100C5F80061C5F80C61C5F8106109
+:10548000C5F80461C5F81461C5F818619248006850
+:1054900000908648C0F8446190480068DFF810A288
+:1054A0000090DAF800006062AAF104000068A062CF
+:1054B0008B48016801F00F01032908BF012013D0B8
+:1054C000016801F00F01042908BF02200CD0016817
+:1054D00001F00F01052929D0006800F00F0006280F
+:1054E0001CBFFFDF012021D084F82C00A07ADFF858
+:1054F000F4B184F82D0002282DD11FE000E006E071
+:10550000D5F80C01012814BF0020082088E7D5F841
+:105510000C01012814BF00200220734A1268012ADE
+:1055200014BF042200221043084379E76F48006843
+:1055300010F0060F0CBF08200420D5E7607850B1AA
+:10554000DBF8001009780840217831EA000008BF34
+:1055500084F8208001D084F8206017F0020F07D073
+:1055600099F80010624A4908606A52F82110884789
+:1055700017F0010F18BF00210CD05E4A99F80030D7
+:10558000A06A52F82320904799F8000010F0010F0C
+:105590002AD10AE017F0020F18BF0121EDD117F050
+:1055A000080F18BF0221E8D1EEE7DBF80000007811
+:1055B00000F00F00072828BF84F8216014D2DBF820
+:1055C0000000062200F10901A01C0FF097FA40B973
+:1055D000207ADBF800100978B0EBD11F08BF01205A
+:1055E00000D0002084F82100E17A002011F0020FA1
+:1055F0001CBF17F0020F17F0040F19D111F0100F94
+:105600001CBF94F82F20002A02D094F831207AB1E0
+:1056100011F0080F1CBF94F82020002A08D111F0C7
+:10562000040F02D094F8211011B117F0010F00D02F
+:105630000120617A19B170B1FFF728FD19E0234804
+:105640002D490160D5F8000220F00300C5F80002E2
+:1056500084F80B800DE04FF0000B012913D00229D4
+:1056600018BFFFDF4CD0A06A012258440021FFF789
+:1056700018FB17F0010F56D0204899F8001050F889
+:105680002100804770E0D5F8000220F00400C5F842
+:105690000002667284F80B80012384F80A801A469F
+:1056A000002196200EF014FE3BE000000080004038
+:1056B00044850040240A002060150040001000408E
+:1056C000481500401C110040B900002008F50140B9
+:1056D0004016004010140040181100404481004062
+:1056E0001015004004150040001400401414004040
+:1056F000AC510200F451020000000404B451020055
+:10570000D5F8000220F00800C5F80002667284F89F
+:105710000B800220A07201231A46002196200EF071
+:1057200015FE83469FE717F0020F08D0624999F8EB
+:10573000002028EA970051F82210884714E017F05B
+:10574000080F06D05D4899F8001050F821008047F6
+:105750000AE017F0100F08BFFFDF05D0584899F88E
+:10576000001050F821008047A07A022818BFBDE839
+:10577000F88F207B002808BFBDE8F88F5149C1F899
+:105780004461022814D0012818BFFFDFA16A2069F4
+:10579000884298BFFFDF2069CAF80000606B4A4961
+:1057A00040F4800060634FF480000860BDE8F88F2B
+:1057B0002169A06A0844EFE70021444A81B000282B
+:1057C00018BFC2F80012C2F80011C2F80C11C2F8DA
+:1057D0001011C2F80411C2F81411C2F818113C4893
+:1057E0000068009001B07047012804BF282070476E
+:1057F000022804BF18207047042812BF08284FF45D
+:10580000A870704700B5FFDF282000BD012804BF45
+:1058100041F6A4707047022804BF41F288307047F7
+:10582000042804BF45F63C207047082804BF47F20F
+:10583000AC10704700B5FFDF41F6A47000BD012831
+:1058400004BF41F2D4707047022804BF41F2040043
+:105850007047042812BF082842F6A000704700B520
+:10586000FFDF41F2D47000BD012812BF02280020E2
+:105870007047042812BF08284FF4C870704700B55D
+:10588000FFDF002000BD11490820C1F800021249C5
+:1058900010480860124911480860091D1148086045
+:1058A000091D11480860091D1048086006494FF499
+:1058B0004020086070470000C4510200D45102002B
+:1058C000E45102000080004004F501400010004057
+:1058D000181100400000040408F5014000110040C8
+:1058E000A0F50140141000401C11004010100040B1
+:1058F00010B53F4822210FF0ACF93D48017821F066
+:1059000010010170012107F0D9FD3A49002081F80A
+:1059100022004FF6FF70888437490880488010BD08
+:10592000704734498A8C824218BF7047002081F842
+:1059300022004FF6FF70888470472D490160704740
+:105940002D49088070472B498A8CA2F57F43FF3B85
+:1059500003D0002101600846704791F822202549B4
+:10596000012A1ABF0160012000207047214901F17E
+:10597000220091F82220012A04BF00207047012252
+:1059800002701D4800888884104670471A49488074
+:1059900070471849184B8A8C5B889A4206D191F857
+:1059A0002220002A1EBF016001207047002070479E
+:1059B0001048114A818C5288914209D14FF6FF71EB
+:1059C000818410F8221F19B1002101700120704755
+:1059D000002070470748084A818C5288914205D1BF
+:1059E00090F8220000281CBF00207047012070475B
+:1059F000820A00205C0A0020BA0000207047574A43
+:105A0000012340B1012818BF7047137008689060E7
+:105A100088889081704753700868C2F802008888AF
+:105A2000D08070474D4A10B1012807D00EE0507861
+:105A300060B1D2F802000860D08804E0107828B184
+:105A40009068086090898880012070470020704726
+:105A5000424910B1012803D006E0487810B903E0AC
+:105A6000087808B1012070470020704730B58DB02C
+:105A70000C4605460D2104A80FF00DF9E0788DF8CD
+:105A80001F0020798DF81E0060798DF81D002868B0
+:105A9000009068680190A8680290E86803906846E2
+:105AA0000DF026FF20789DF82F1088420CD16078E9
+:105AB0009DF82E10884207D1A0789DF82D108842BD
+:105AC00002BF01200DB030BD00200DB030BD30B59B
+:105AD0000C4605468DB04FF0030104F1030012B1EE
+:105AE000FEF72AFA01E0FEF746FA60790D2120F070
+:105AF000C00040F04000607104A80FF0CCF8E078DE
+:105B00008DF81F0020798DF81E0060798DF81D003A
+:105B10002868009068680190A8680290E86803907F
+:105B200068460DF0E5FE9DF82F0020709DF82E00D0
+:105B300060709DF82D00A0700DB030BD10B500292B
+:105B400004464FF0060102D0FEF7F6F901E0FEF739
+:105B500012FA607920F0C000607110BDBE00002014
+:105B600070B5FF4E0446306890F8001100250129F9
+:105B700019D090F8FA10012924D090F8D0100129FA
+:105B80002AD090F8F21001291CBF002070BD65706A
+:105B900017212170D0F8F4106160B0F8F81021815D
+:105BA00080F8F25016E065701C212170D0F80111C8
+:105BB0006160D0F80511A16090F80911217380F897
+:105BC000005107E0657007212170D0F8FC1061607A
+:105BD00080F8FA50012070BD65701421217000F129
+:105BE000D2012022201D0EF0B5FF01212172306864
+:105BF00080F8D050DB48B0F8D420A0F8FC207268C0
+:105C0000537B80F8FE3080F8FA101088FBF75EF9BD
+:105C1000FAF705FEDEE7D248006890F8D0100029B8
+:105C200014BFB0F8D4004FF6FF70704770B5CC4C7D
+:105C30002068002808BFFFDF002520684570002885
+:105C400008BFFFDF2068417800291CBFFFDF70BD5F
+:105C50004FF486710FF01FF82068FF2101707F213B
+:105C600080F8361013214184282180F8CC100121BE
+:105C700080F8B81080F8BD50FFF736FBFEF74BFDFB
+:105C8000B94807F0A7F9B94807F0A4F9BDE8704092
+:105C9000B74807F09FB9B2490968097881420CBF3B
+:105CA000012000207047AE48006890F82200C0F341
+:105CB000001070472DE9F04FA948D0F800C09CF8BB
+:105CC0002400C0F38001C0F34002114400F0010041
+:105CD0000B18BCF822000025C0F3001139B31328BB
+:105CE0001DD009DC102802BFA24830F81300BDE81F
+:105CF000F08F122813D006E0152808D01D2804BF05
+:105D00009D48BDE8F08FFFDF2846BDE8F08F9B4936
+:105D1000002031F8131013FB0010BDE8F08F9849F4
+:105D2000002031F8131013FB0010BDE8F08F0024A1
+:105D30009CF8BA209CF8BB10924EDFF84CA2DFF81A
+:105D40004CB210F0030F4FF4C8774FF4BF784FF404
+:105D5000A8797CD010F0010F17D0082904BF3C4669
+:105D600040200CD0042904BF4446102007D002294B
+:105D700007BF05F11804042005F12804082000EBF2
+:105D8000400E0EEB0010204417E0082904BF3846EF
+:105D900040240CD0042904BF4046102407D0022917
+:105DA00007BF05F11800042405F12800082404EBBE
+:105DB000C40404EB440400EB44009CF8CCC0022A69
+:105DC00008BF4FF47A740DD0012A04BF56464FF431
+:105DD000C86407D0042A07BF5E4640F698046C4E9C
+:105DE00040F6E444344404F2E7364FF47A74B6FBE8
+:105DF000F4F4C3EB031606EB860604EB8604082ACC
+:105E000052D0042A4BD0022A0CBF05F1180605F126
+:105E100028064FF019020CBF4FF0040A4FF0080A91
+:105E200012FB0A6212FB0342082908BF40230BD071
+:105E3000042908BF102307D0022907BF4FF0180913
+:105E400004234FF028090823C3EBC30300E030E02C
+:105E500003EB430309EB43031A4411F00C0F08BF93
+:105E60004FF0000C6244082908BF40210CD00429DF
+:105E700004BF4746102107D0022907BF05F11807C4
+:105E8000042105F128070821C1EBC10101EB410103
+:105E900007EB41011144084400F526740EE0464624
+:105EA00014224FF0100ABBE73E4614224FF0400A7E
+:105EB000B6E710F0020F18BFFFDF02D02046BDE8A2
+:105EC000F08F022A08BF4FF47A700DD0012A04BF68
+:105ED00056464FF4C86007D0042A07BF5E4640F616
+:105EE00098002B4E40F6E440304400F2E73C4FF47B
+:105EF0007A70BCFBF0F0C3EB031C0CEB8C0C00EBDA
+:105F00008C0C082A04BF142040220CD0042A44D050
+:105F1000022A0CBF05F1180705F128074FF01900F8
+:105F20000CBF0422082210FB027010FB03C00829DA
+:105F300008BF40210BD0042908BF102107D0022937
+:105F400007BF4FF0180904214FF028090821C1EBC1
+:105F5000C10101EB410109EB410108441AE00000D5
+:105F6000CC000020A40A0020B00B0020D80B002099
+:105F7000000C002018520200F18913002052020088
+:105F80001052020068360200A2240200D0FB010079
+:105F900030D3010000F5B27490E714204746102278
+:105FA000C1E7F94840F271210068806A48437047B0
+:105FB000F548006890F83500002818BF01207047A8
+:105FC00010B5F24C207B022818BF032808D1207D91
+:105FD00004F1150105F0E8FD08281CBF012010BDE3
+:105FE000207B002816BF022800200120BDE81040B9
+:105FF000FFF72EBDE449096881F8300070472DE9AC
+:10600000F047E14D2968087B002816BF02280020D0
+:10601000012048730E31FFF705FD2968087B02282F
+:1060200016BF03280122002281F82F20082081F8C2
+:106030002D00487B0126002701F10E03012804BF33
+:106040005B7913F0C00F0AD001F10E03012804D1CF
+:10605000587900F0C000402801D0002000E0012065
+:1060600081F82E00002A04BF91F8220010F0040FDE
+:1060700006D0087D153105F097FD296881F82D00BF
+:1060800028684760FCF720FF2968C04C4FF00009E2
+:10609000886094F82D0005F0A3FD804694F82F0049
+:1060A000002818BFB8F1000F04D01021404606F0B8
+:1060B000D4FB68B194F8300000281CBF94F82E007F
+:1060C00000281DD0607B04F10E0101280ED012E0E3
+:1060D00066734A4604F10E014046FFF7F8FC94F857
+:1060E0002D1004F10E0005F074FE09E0487900F06F
+:1060F000C000402831D0394604F10E00FFF71EFDE4
+:106100002868C77690F8220010F0040F08BFBDE899
+:10611000F087002794F82D0005F06BFD040008BF00
+:10612000BDE8F087102106F098FB002818BFBDE8F5
+:10613000F08728683A4600F11C01C6762046FFF732
+:10614000C6FC286800F11C01914806F07AFFBDE802
+:10615000F04701218E4806F08FBF05F073FE4A46D6
+:1061600004F10E01FFF7B3FCCAE778B5874904468E
+:10617000854D407B08732968207808706088ADF8E9
+:10618000000080B200F00102C0F3400342EA430283
+:10619000C0F3800342EA8302C0F3C00342EAC302B1
+:1061A000C0F3001342EA0312C0F3401342EA431261
+:1061B000C0F3801042EA80104884E07D012808BFC7
+:1061C000012607D0022808BF022603D0032814BFE7
+:1061D000FFDF0826286880F8BA60607E012808BFC3
+:1061E000012607D0022808BF022603D0032814BFC7
+:1061F000FFDF0826286880F8BB60217B80F8241028
+:10620000418C1D290CBF002161688162617D80F88D
+:106210003510A17B002916BF02290021012101753B
+:10622000D4F80F10C0F81510B4F81310A0F8191016
+:10623000A17EB0F8CE2061F30302A0F8CE20E17E6B
+:10624000012918BF002180F83410002078BD4E4885
+:106250000068408CC0F3001119B110F0040F05D094
+:1062600002E010F0020F01D00020704701207047BB
+:10627000454A00231268C2F8C030B2F822C0BCF10F
+:106280001D0F02BFC2F8C83082F8C4307047002921
+:1062900008BFC2F8C8300AD0936A40F2712C03FBE1
+:1062A0000CF31944491EB1FBF3F1C2F8C81082F88F
+:1062B000C40070470346344810B50168D1F8C820BF
+:1062C000002A1ABFD1F8C0C0BCF1000F012405D0CC
+:1062D0009A4205D90124D01AC1F8C800204610BD41
+:1062E00091F82210002411F0010F1CBF40680088B3
+:1062F0004FF0430108BF002001F017F9EEE72248F4
+:10630000006890F8B70000280CBF012000207047FB
+:1063100070B51F2834BF04461F2400221A4D286878
+:1063200080F8B920224678300EF014FC286801214C
+:1063300080F8974080F8B91070BD10B51F2828BFAD
+:106340001F20C2B2104C0023206880F8B83080F8BB
+:10635000B72098300EF0FEFB2168012081F8B800CC
+:1063600010BD0949096881F8BD00704706480068FA
+:1063700090F8220000F0010070470348006890F890
+:106380002200C0F340007047CC000020A40A002087
+:10639000B00B0020FE48006890F82200C0F34010C7
+:1063A0007047FB48006890F82200C0F3C0007047B7
+:1063B00001207047F648006890F8BB00704770B540
+:1063C000FEF77CFFFEF730FFFEF760FEFEF7BDFE36
+:1063D000EF4C2068D0F8C010491CC0F8C01090F8ED
+:1063E0003300002530B1FEF77FFFFEF794F92068F7
+:1063F00080F833502068457090F8C410F9B1D0F897
+:10640000C02091421BD8042002F08AFA206890F83C
+:10641000220010F0010F0CD060684321008801F0C9
+:1064200084F860680088FAF751FDBDE87040FAF71B
+:10643000E7B9BDE870404321002001F076B8D0F8FC
+:10644000C81019B1D0F8C020914202D990F8370095
+:10645000D8B1042002F064FA206890F8220010F00D
+:10646000010F0CD060683C21008801F05EF8606884
+:106470000088FAF72BFDBDE87040FAF7C1B9BDE816
+:1064800070403C21002001F050B8BDE87040002071
+:1064900002F046BA2DE9F84FBD4E804617463068E7
+:1064A0008B464FF0000A458C15F0030F10D015F005
+:1064B000010F05F0020005D0002808BF4FF0010AC7
+:1064C00006D004E0002818BF4FF0020A00D1FFDF19
+:1064D0004FF000094C4615F0010F05F002000BD0FB
+:1064E00070B915F0040F0BD049F00800002F18BF49
+:1064F00040F0030440D090E010B115F0040F0DD02F
+:1065000015F0070F10D015F0010F05F0020036D07E
+:10651000002808BF15F0040F27D03DE0002F18BF5A
+:1065200049F0090479D134E02FB149F0080415F09D
+:10653000200F14D071E0316805F0200291F8770047
+:10654000104308BF49F0010467D049F0180415F062
+:10655000200F62D191F8BA1008295AD156E031685B
+:1065600091F8BA10082951D153E049F00800002FE2
+:1065700018BF40F0010450D140F010044DE0002855
+:1065800018BF15F0040F07D0002F18BF49F00B04F7
+:1065900043D149F0180440E015F0030F3CD115F049
+:1065A000040F39D077B1316849F0080091F8BA107A
+:1065B00008290CBF40F0020420F0020415F0200F5F
+:1065C00022D02AE0316805F0200291F877001043CC
+:1065D00008BF49F0030420D049F0180015F0200F3F
+:1065E00009D000BF91F8BA10082914BF40F0020486
+:1065F00020F0020411E091F8BA20082A14BF40F0FC
+:10660000010020F00100EDE7082902D024F0010488
+:1066100003E044F0010400E0FFDF15F0400F18BF75
+:10662000FFDFA8F8009098F80000072120F0200074
+:1066300088F80000404606F0D2FC5146404606F07D
+:10664000D1FE2146404606F0D6FE14F0010F0CD0D4
+:106650003068062300F10E010022404606F0A8FE35
+:106660003068417B404606F0FAFC14F0020F1BD064
+:106670003068BBF1000F0BD000F11C010623012292
+:10668000404606F095FE0121404606F0F5FC0BE081
+:1066900000F1150106230122404606F089FE30680C
+:1066A000017D404606F0E8FC14F0040F18BFFFDF40
+:1066B00014F0080F17D0CDF800903068BDF8001026
+:1066C0000223B0F8CE00020962F30B01ADF800100E
+:1066D0009DF80110032260F307118DF8011069463F
+:1066E000404606F065FE012F16D1306890F877001D
+:1066F00090B1404606F072FE3368401CC0B293F879
+:106700007710C0F125008142B8BF084682B203F17C
+:106710005801404606F09DFE0020002818BFFFDF0C
+:106720000020002818BFFFDF0020002818BFFFDF6F
+:10673000BDE8F88F2DE9F843154C2068002808BF04
+:10674000FFDF2068417811BB0178FF2926D00027A0
+:1067500080F83170877080F837703846FEF703FD97
+:10676000FEF7E5F9206890F9BD00FEF770FA0948D8
+:10677000FEF777FA0848FEF7E2FC206890F824005C
+:1067800010F0010F0DD02520FEF773FA10E005E0A0
+:10679000CC0000200C520200095202000C20BDE87F
+:1067A000F88310F0020F18BF262067D0FEF761FAB9
+:1067B000206890F8BA102520FEF779F9206880F853
+:1067C0002C70FEF7CAFC2068002190F8BA20084619
+:1067D000FEF779FB0F210520FEF70DFA2068FF4D2B
+:1067E000012690F82E10002901BF90F82F100029E3
+:1067F00090F8220010F0040F70D0FCF765FB804683
+:10680000206841468068FDF76DF8F54990FBF1F985
+:1068100001FB190041424046FCF75FF80146206841
+:10682000816041684944416005F0BBF90146206838
+:10683000426891426DD8C0E901784FF0010895F89F
+:106840002D0005F0CDF9814695F82F00002818BFDE
+:10685000B9F1000F04D01021484605F0FEFFA0B1A9
+:1068600095F8300000281CBF95F82E00002824D091
+:10687000687B05F10E01012815D019E010F0040F16
+:1068800014BF2720FFDF91D192E732466E7305F1E6
+:106890000E014846FFF71BF995F82D1005F10E0083
+:1068A00005F097FA09E0487900F0C000402816D0BA
+:1068B000414605F10E00FFF741F9206890F82200EB
+:1068C00010F0040F25D095F82D0005F092F95FEA3D
+:1068D00000081ED0102105F0C0FF40B119E005F0FE
+:1068E000B1FA324605F10E01FFF7F1F8E5E720684D
+:1068F000324600F11C01C6764046FFF7E8F82068F2
+:1069000000F11C01B74806F09CFB0121B54806F0D8
+:10691000B3FB2068417B0E30FEF751F9206890F8F8
+:10692000B81079B390F8B72080F8772000F198017B
+:1069300058300EF054F9206890F82210C1F300117D
+:10694000E9B9B0F8CE0002210609ADF8006068464A
+:10695000FDF7F2FA28B1BDF80000C0F30B00B04219
+:1069600004D1BDF80000401CADF800002168BDF85E
+:106970000000B1F8CE2060F30F12A1F8CE202068FD
+:1069800080F8B870206890F8B91059B190F8972045
+:1069900080F8572000F1780138300EF020F9206897
+:1069A00080F8B9702068B0F8CE10D0F8C02009097E
+:1069B00051FA82F190F8BC20DFF82CC211446346F2
+:1069C0000022E1FB0C3212096FF0240302FB0311D9
+:1069D00080F8BC1090F82210824E90F81B80C1F312
+:1069E000001106F1280900295DD03780317821F0A7
+:1069F00020013170408C132837D01CDC10284DD07A
+:106A0000122846D0FFDF00BF05F10E01754806F0E1
+:106A10000AFB697B734806F022FB2068418C1D2924
+:106A200018BF15297ED090F8772000F15801304624
+:106A300006F04BFB7EE0152818BF1D28E2D101218E
+:106A4000304606F0CCFA3078B8F1000F40F0200064
+:106A50003070206812D000F11C01304606F0F1FAC7
+:106A60000121304606F008FBCEE70021304606F053
+:106A7000B6FA307840F020003070C5E700F115011B
+:106A8000304606F0DEFA2068017D304606F0F4FA62
+:106A9000BAE70621304606F0A2FAB5E702213046F1
+:106AA00006F09DFAB0E7002241463046FFF7F2FCBF
+:106AB000206890F87710002904BF408C10F0010F77
+:106AC00005D110F0020F08BF10F0200F04D00122F2
+:106AD00041464846FFF7DEFCF07810F03F0F1CBF40
+:106AE000307910F0100F25D0304606F076FA226883
+:106AF000014692F82400C0F38003C0F3400C6344C5
+:106B000000F00100034492F82C00C0F38002C0F3AF
+:106B1000400C624400F001001044181AC0B200F0AA
+:106B200018FD00E006E00090032304226946304689
+:106B300006F03EFC206890F82200C0F30010B0B1CF
+:106B40002A4E04213046378006F049FA05F10E013D
+:106B5000304606F068FA697B304606F080FA206815
+:106B600000F1380190F85720304606F0D2FA05F0CF
+:106B70008DF803211E4805F01CF9216881F83300C7
+:106B80000020BDE8F8831B49486070472DE9F843B1
+:106B9000184C8046206890F8312032B1408C1D2876
+:106BA00008BFFFDFBDE8F84309E4012631B390F8E0
+:106BB000BC00FEF75EF8206890F8BB102520FDF7BA
+:106BC00076FF206801224FF4967190F8BB300020C8
+:106BD000FEF7ABF90848FEF7C9FA10E0A40A002056
+:106BE00040420F00B00B002053E4B36E000C0020B5
+:106BF000280C0020CC000020D80B002006E02068E4
+:106C00004670867080F83160BDE8F883F948FEF779
+:106C1000ADFA2068002590F8241090F82C0021EAA5
+:106C2000000212F0010F18BF01250ED111F0020F62
+:106C300004D010F0020F08BF022506D011F0040F97
+:106C400003D010F0040F08BF04250027B8F1000F8F
+:106C50005CD0012D1CD0022D08BF26201CD0042D95
+:106C600014BFFFDF272017D0206890F8BA10252026
+:106C7000FDF71DFF206890F82210C1F3001171B1DB
+:106C8000002201234FF496711046FEF74EF93DE0C5
+:106C90002520FDF7EEFFE7E7FDF7EBFFE4E790F8CF
+:106CA000BA3001224FF496710020FEF73EF9D14828
+:106CB000C17811F03F0F1CBF007910F0100F25D0E4
+:106CC000CC4806F08AF92368014693F82420C2F3E1
+:106CD0008000C2F3400C604402F0010200EB020CA1
+:106CE00093F82C20C2F38000C2F34003184402F052
+:106CF00001020244ACEB0200C0B200F02AFC00909A
+:106D0000032304226946BB4806F052FB206890F832
+:106D10002C10294380F82C1090F8242032EA01012D
+:106D200011D04670408C132820D01BDC102808BFDF
+:106D3000BDE8F883122819D0C0F30010002818BF4E
+:106D4000FFDFBDE8F883418C1D2908BF80F82C7057
+:106D5000E7D0C1F30011002914BF80F8316080F83A
+:106D60003170DEE7152818BF1D28E5D1BDE8F843CE
+:106D700001210846FEF7F0BA9F4810B50068417837
+:106D800041B90078FF2805D000210846FFF7FEFE34
+:106D9000002010BDFEF792FAFEF746FAFEF776F9EC
+:106DA000FEF7D3F90C2010BD93490120096881F842
+:106DB000370070479049096881F83200704770B514
+:106DC000002601F01DFC002800F0C4808A4C2068D9
+:106DD000417801220025012905D0022901D003298B
+:106DE00070D0FFDF70BD81780225B1B390F822002A
+:106DF00010F0030F67D08148FEF7B8F92068012230
+:106E0000962190F8BB301046FEF78FF8216891F874
+:106E1000BB0091F8CC1010F00C0F08BF0021962099
+:106E2000FEF7BFF92068457090F8330058B1FDF7C0
+:106E30005EFC206890F8BB0010F00C0F0CBF4020E7
+:106E40004520FEF747FA206890F83400002808BF74
+:106E500070BDBDE87040FEF75CBA418CC1F3001212
+:106E60009AB1102929D090F8330020B1FDF73FFCEA
+:106E70004020FEF72FFA6148FEF778F9206890F875
+:106E8000221011F0040F1FD029E090F8242090F870
+:106E90002C309A4211D190F87700002808BF11F0E9
+:106EA000010F05D111F0020F08BF11F0200F51D0D2
+:106EB000BDE870400121084668E6BDE87040002149
+:106EC000012063E619E045E090F83500012814BF81
+:106ED0000328102646F00E010020FEF73DFA206838
+:106EE00090F83400002818BFFEF713FA002196200E
+:106EF000FEF757F92068457070BD817801B3418C69
+:106F000011F0010F21D080F8D02090F8D210B0F805
+:106F1000D40000F00AFB60680088F9F7D7FFF9F7A2
+:106F20006FFC20684570FEF7C9F9FEF77DF9FEF7A2
+:106F3000ADF8FEF70AF9BDE87040032001F0F0BC9F
+:106F40008178BDE87040012020E611F0020F04BFF7
+:106F5000FFDF70BDBDE87040FFF731BAFFF72FBA11
+:106F600010B5254C206890F8341049B13630FEF742
+:106F7000DBF918B921687F2081F83600FEF7BFF9E8
+:106F8000206890F8330018B1FEF7AEF9FDF7C3FBA7
+:106F900001F036FBA8B1206890F82210C1F300116F
+:106FA00079B14078022818BFFFDF00210120FFF7E8
+:106FB000EDFD2068417800291EBF40780128FFDFE1
+:106FC00010BDBDE81040FFF7FAB92DE9F0470A4FB0
+:106FD0000E4603283A68518C12D092F8320001F024
+:106FE000010410F1000918BF4FF001094FF001082A
+:106FF0000CE00000B00B0020CC000020280C00208A
+:10700000C1F340044FF000094FF00208FDF721FEE4
+:10701000054634EA090008BFBDE8F0873868FF4C30
+:1070200090F8330060B104F016FE30700146FF287E
+:1070300006D0E01C04F004FE307804F017FE05438F
+:107040002078C0F380113868027D914209D100F1A7
+:1070500015010622E01C0DF051FD002808BF01209B
+:1070600000D000203178FF2906D0C0B9386890F8E8
+:107070002D00884215D112E098B12078E11CC0F3B0
+:10708000801004F091FD064604F0F4FE38B130465D
+:1070900004F0AFFD18B1102105F0DFFB08B10120AD
+:1070A00000E00020396891F8221011F0040F01D09F
+:1070B000F0B11AE0CDB9DA4890F83500002818BFD1
+:1070C000404515D114F8030B2146C0F3801004F09D
+:1070D0006BFD044604F0CEFE38B1204604F089FD75
+:1070E00018B1102105F0B9FB10B10120BDE8F087FF
+:1070F0000020BDE8F0872DE9F04FCA4D804683B0EF
+:10710000286800274078022818BFFFDF28687F24FE
+:1071100090F8341049B13630FEF706F9002804BF64
+:10712000286880F83640FEF7EAF8BC4805F077FF9B
+:107130000646B8F1000F00F0B081B84806F008F933
+:10714000002800F0AA81FDF752FD002800F0A5817B
+:107150003046B24EFF21DFF8D0A24FF000084FF0CA
+:10716000030B4FF00109062880F0B881DFE800F03A
+:10717000FEFEFE03FE8F8DF8001069460320FFF728
+:1071800024FF002828687CD090F8341011B190F8C2
+:10719000001159B12868807801283ED0A348FDF736
+:1071A000E5FF286880F801B000F07BB99DF8003059
+:1071B00080F80091017880F80111FF2B10D000F2C7
+:1071C0000312511E184604F01DFD002808BFFFDF02
+:1071D000286890F8021141F0020180F802110DE0D8
+:1071E0003178C1F3801180F802118D49D1F88721DF
+:1071F000C0F80321B1F88B11A0F80711286800F23C
+:10720000091690F836007F2808BFFFDF286890F83D
+:107210003610317080F83640BCE7844CDAF80490C0
+:1072200004F12806A4F800800721204605F0D7FEC7
+:107230000021204606F0D6F84946204606F0DBF845
+:107240000623002206F10901204606F0B1F828685D
+:10725000417B204605F003FF286800F1380190F8D3
+:107260005720204606F0F5F82046FDF77FFF2868F6
+:107270000122962190F8BB300020FDF756FE90E7E2
+:10728000FFE78078002840F00A8100F006B98DF809
+:10729000081002A90520FFF798FE0028286800F0D2
+:1072A000F78082786249002A7ED0A1F11F066C68BF
+:1072B00090F8BB90D6F80F00C4F80E00B6F8130093
+:1072C0006082707D2075B07D6075B6F81700E08231
+:1072D000B6F819006080B6F81B00A080B6F81D0053
+:1072E000E08004F108000DF0EBFD96F8240000F0BA
+:1072F0001F00207696F82400400984F86C0184F879
+:10730000549084F85590286890F8CC1084F8561062
+:1073100090F8BD0084F857009DF80810686800F0E8
+:1073200081F9022001F0FCFAA6F12804DAF80090B5
+:10733000A4F800800821204605F051FE00212046D7
+:1073400006F050F84946204606F055F869463046A2
+:1073500005F07EFE304605F098FE0146204605F019
+:107360007EFE062300226946204600E0B6E006F0D5
+:107370001FF86946304605F05DFE304605F078FEA0
+:107380000146204605F078FE062301226946204684
+:1073900006F00EF82046FDF7E9FE28680122962146
+:1073A00090F8BB30002000E005E0FDF7BEFD286846
+:1073B00080F801B075E06C683278184E607BC2F3DB
+:1073C000401210406073D6F80F00C4F80E00B6F8F3
+:1073D00013006082707D2075B07D6075B6F817006F
+:1073E000E082B6F819006080B6F81B00A080B6F8FD
+:1073F0001D00E0804FF0010A04F108000DF060FD6F
+:1074000096F8240000F01F00207696F8240040092A
+:1074100084F86C0184F854A00CE00000280C0020D3
+:10742000A40A0020CC00002004520200000C00201E
+:10743000470C002084F855A0286890F8CC1084F8F8
+:10744000561090F8BD0084F857009DF80810686841
+:1074500000F0E8F8286880F8D09090F8D210B0F8E2
+:10746000D40000F062F868680088F9F72FFDF9F79A
+:10747000C7F9286880F80180FDF720FFFDF7D4FEEA
+:10748000FDF704FEFDF761FE012001F049FA08E076
+:1074900090F82200C0F3001008B1012701E0FEF7C8
+:1074A0008EFF286890F8330018B1FDF71DFFFDF737
+:1074B00032F91FB100210120FFF768FB28684178ED
+:1074C000002919BF4178012903B0BDE8F08F407849
+:1074D000032818BFFFDF03B0BDE8F08F286890F8DD
+:1074E0002200C0F300100028D9D0D6E770B58A4C2E
+:1074F00006460D462068807858B1FDF789FA216864
+:107500000346304691F8BB202946BDE8704001F0A3
+:1075100074BAFDF77DFA21680346304691F8BA2027
+:107520002946BDE8704001F068BA7C4A137882F8B9
+:10753000F530A2F8F60082F8F410012082F8F2008B
+:1075400092F8C400002818BF92F8C00082F8F80032
+:10755000704778B50446704800230093006890F89F
+:10756000BA20082A04BF4FF4C87240230DD0042A61
+:1075700004BF4FF4BF72102307D0022A07BF03F1E4
+:107580001802042303F128020823491D01FB0326E6
+:1075900090F8BC209DF8001062F3050141F0400511
+:1075A0008DF8005090F8BB00012826D002282BD07F
+:1075B000082818BFFFDF2DD025F080008DF80000CF
+:1075C000C4EB041106FB04F001EB810100EB810424
+:1075D0005348844228BFFFDF5248A0FB0410BDF887
+:1075E0000110000960F30C01ADF80110BDF80000B6
+:1075F0009DF8021040EA014078BD9DF8020020F09D
+:10760000E0008DF80200D7E79DF8020020F0E000CE
+:10761000203004E09DF8020020F0E00040308DF8BA
+:107620000200C9E72DE9F0413B4D04460E462868AB
+:1076300090F8D000002818BFFFDF0027286880F8E6
+:10764000D2702188A0F8D4106188A0F8EA10A1882F
+:10765000A0F8EC10E188A0F8EE1094F86C1180F816
+:10766000F01090F82F1049B1427B00F10E01012A71
+:1076700004D1497901F0C001402935D090F830108B
+:1076800041B1427B00F10E01012A04BF497911F09A
+:10769000C00F29D0DE300DF001FC2348FF2E00780A
+:1076A000C0F3801060761D48D0F88711C4F81A1016
+:1076B000B0F88B01E08328681ED0C0F8E410E18B9D
+:1076C000A0F8E81000F1D802511E304604F09AFAF2
+:1076D000002808BFFFDF286890F8D71041F00201AA
+:1076E00080F8D710BDE8F081D0F80E10C0F8DE1099
+:1076F000418AA0F8E210D0E7C0F8E470A0F8E87082
+:10770000617E80F8D710D4F81A10C0F8D810E18B39
+:10771000A0F8DC10BDE8F081CC000020A40A002015
+:10772000C4BF030089888888280C0020FE48406870
+:1077300070472DE9F0410F460646014614460120E8
+:1077400005F082FA054696F85500FEF75FF8014607
+:1077500096F85500022808BFF44807D0012808BF52
+:10776000F34803D004280CBFF248F34808444FF410
+:107770007A7100F2E140B0FBF1F0718840F27122C1
+:107780005143C0EB4100001BA0F5597402F0E4FD29
+:10779000002818BF1E3CAF4234BF28463846A042DE
+:1077A00003D2AF422CBF3C462C467462BDE8F08148
+:1077B0002DE9FF4F8FB0044690F855601C9899460C
+:1077C00040EA0900019094F86500002790460D28D2
+:1077D0000CBF012000200990B9F1000F04BF94F8FC
+:1077E0000C0103282BD1099848B3B4F88E01404509
+:1077F00025D1D4F81401C4F80001608840F2E241B8
+:107800004843C4F80401B4F85A11B4F8E600084437
+:10781000C4F80801204602F0A9FDB4F89201E08204
+:1078200094F890016075B4F894016080B4F8960102
+:10783000A080B4F89801E080022084F80C01D4F80C
+:1078400064010C90B4F8E6A0B4F85801D4F860B123
+:10785000D4F854110891B9F1000F03D094F8201115
+:1078600049B193E004F1E001059174310A9104F506
+:10787000A075091D07E004F59A710591091D0A918B
+:1078800004F59275091D0B91B4F85810A8EB00008F
+:10789000A8EB010109B200B20391002805DAD4F87F
+:1078A0005001089001200190084694F80C1100291D
+:1078B00071D0012900F04482022900F0658103297A
+:1078C00018BFFFDF00F0848239460898FBF705F8FF
+:1078D0000A99012640F2712208600B98A0F80080F6
+:1078E000002028702E710A980068A8606188D4F87A
+:1078F00014015143C0EB41009049A0F54D708861DF
+:107900004969814287BF059908600598016005981B
+:10791000616A0068084400F5D270E86002F01CFD5E
+:1079200010B1E8681E30E8606E71B4F8D000A0EBCA
+:10793000080000B20028C4BF03206871099800281D
+:107940001C9800F0C282C0B1B4F8F81000290CBF36
+:107950000020B4F8FA00A4F8FA0094F8FC20401CC7
+:107960005043884209D26879401E002805DD6E71B7
+:10797000B4F8FA00401CA4F8FA00B9F1000F00F0C6
+:10798000C78294F82001002800F0BE8213B00220C4
+:10799000BDE8F08FFFE7BBF1000F08BFFFDF94F8F1
+:1079A0005510614890F8280005F0FBFA0790E08A2E
+:1079B00040F271214143079800EB410210980021E9
+:1079C000002806D000FB02F15D48B1FBF0F000F1A9
+:1079D0000101C4F81011608840F2E24100FB01F29D
+:1079E00010994FF0000006D0554801FB02F1B1FBA1
+:1079F000F0F000F10100C4F8140186B221464FF006
+:107A00000100D4F828A005F01FF9074694F85500A6
+:107A1000FDF7FCFE014694F85500022808BF4348D4
+:107A200007D0012808BF424803D004280CBF4148B2
+:107A30004148084400F2E1414FF47A70B1FBF0F1A3
+:107A4000608840F271225043C1EB4000801BA0F5DA
+:107A5000597602F081FC002818BF1E3EBA4534BF9B
+:107A600038465046B04203D2BA452CBF56463E4631
+:107A7000666294F85500FDF7F7FE4FF47A7600F24F
+:107A8000E140B0FBF6F000EB0B0794F85500FDF772
+:107A9000EBFE024694F85500022808BF234907D0A0
+:107AA000012808BF224903D004280CBF21492249DC
+:107AB00002EB010AFDF7AAFE504400F2DB514FF43D
+:107AC0007A70B1FBF0F0E18A40F271224A430799E3
+:107AD000D4F810A101EB4201081AA0EB0A003844C7
+:107AE000A0F12007607D40F2E24110FB01F0079019
+:107AF00094F8556016F00C0F18BF4DF6883103D17D
+:107B00003046FDF783FE0146022E08BF074807D026
+:107B1000012E08BF064803D0042E0CBF05480648B6
+:107B2000084400F2E1410DE0500C00200436020050
+:107B3000A2240200D0FB0100C0D40100D400002028
+:107B400040420F004FF47A70B1FBF0F000EB4A01B5
+:107B5000079801EB000A3046FDF746FE504400F15D
+:107B60006201FD48416194F85500FDF77DFE00F289
+:107B7000E1414FF47A70B1FBF0F05844381AB0F597
+:107B80003D7F38BFFFDF9FE6E28A40F27121D4F8E3
+:107B90000401514300EB410210980021002806D057
+:107BA00000FB02F1ED48B1FBF0F000F10101C4F877
+:107BB0001011618840F2E24001FB00F210994FF091
+:107BC000000006D0E54801FB02F1B1FBF0F000F146
+:107BD0000100C4F8140186B221464FF00100D4F828
+:107BE00028B005F031F8074694F85500FDF70EFE71
+:107BF000014694F85500022808BFD94807D001284B
+:107C000008BFD84803D004280CBFD748D748084439
+:107C100000F2E1414FF47A70B1FBF0F0618840F27C
+:107C200071225143C0EB4100801BA0F5597602F050
+:107C300093FB002818BF1E3EBB4534BF384658464C
+:107C4000B04203D2BB452CBF5E463E466662BAF1E7
+:107C5000000F2FD11C9868B394F855603046FDF79B
+:107C6000D5FD0146022E08BFBD4807D0012E08BF32
+:107C7000BC4803D0042E0CBFBB48BC48084400F2EB
+:107C8000E1414FF47A70B1FBF0F0D4F81011E38ABF
+:107C9000014440F27122D4F804015A4300EB42003F
+:107CA000471A3046FDF7A0FD0C99081A3844A0F198
+:107CB00020070AE0E28A40F27121D4F8040151431E
+:107CC00000EB4101D4F810010F1AD4F80821D4F8C0
+:107CD0001011D4F8000100FB021B607D40F2E2416C
+:107CE00010FB01FA94F8556016F00C0F18BF4DF612
+:107CF000883103D13046FDF789FD0146022E08BFC9
+:107D0000974807D0012E08BF964803D0042E0CBF19
+:107D100095489648084400F2E1414FF47A70B1FB6F
+:107D2000F0F000EB4B0082443046FDF75DFD50441F
+:107D300000F1600188484161012084F80C01C3E52D
+:107D4000618840F271235943D4F81421D4F800C15A
+:107D5000C2EB410101FB00F70398D4F8081150442D
+:107D6000401AD4F81031401E0CFB013100FB021BFD
+:107D7000607D40F2E24110FB01FA94F8556016F084
+:107D80000C0F18BF4DF6883103D13046FDF73EFD8C
+:107D90000146022E08BF724807D0012E08BF714865
+:107DA00003D0042E0CBF70487048084400F2E14133
+:107DB0004FF47A70B1FBF0F000EB4B008244304698
+:107DC000FDF712FD504400F16001634841617BE51D
+:107DD000628840F27123D4F814115A43C1EB420176
+:107DE00001FB00F794F8640024281CBF94F8650098
+:107DF00024280BD1B4F88E01A8EB000000B20028B3
+:107E000004DB94F89101002818BF0646019870B36E
+:107E1000BAF1000F2BD10C98002814BFBBF1000F52
+:107E2000FFDF94F8550010F00C0F14BF4DF68830AA
+:107E3000FDF7ECFC022E08BF494907D0012E08BF10
+:107E4000484903D0042E0CBF47494849084400F272
+:107E5000E1414FF47A70B1FBF0F03F1A94F855000D
+:107E6000FDF7C2FC0C99081A3844A0F120070398CA
+:107E7000D4F81411504400FB01FA16F00C0F18BF8F
+:107E80004DF6883103D13046FDF7C0FC0146022E85
+:107E900008BF334807D0012E08BF324803D0042E54
+:107EA0000CBF31483148084400F2E1414FF47A7088
+:107EB000B1FBF0F000EB4A0A3046FDF795FC504468
+:107EC00000F1600124484161FEE400287FF43CADEC
+:107ED00094F80C0100283FF450AD618840F2712203
+:107EE000D4F814015143C0EB4101284604F0D7FDFA
+:107EF0000004000C3FF441AD1D99002918BF088013
+:107F0000012013B0BDE8F08F94F85C01FBF736FB5D
+:107F100094F85C012946FBF71FFA00281CBF89F082
+:107F2000010084F82101002013B0BDE8F08F2DE995
+:107F3000F04F0F4C074683B020788946064E002547
+:107F40004FF00208032804BF207BB8427DD160684F
+:107F50003061207803280DE0D400002040420F005B
+:107F600004360200A2240200D0FB0100C0D40100AC
+:107F7000500C002018BFFFDF0327B9F1080F78D29B
+:107F8000DFE809F0040E1B1B167777726562FEF7B7
+:107F9000D1FB002818BFFFDFB77003B0BDE8F08F3A
+:107FA000FEF7EAFE002818BFFFDF03B0BDE8F08F40
+:107FB00003B0BDE8F04FFDF7F3B92775257494F8C9
+:107FC0002C00012658B14FF47A71A069FAF785FCAC
+:107FD000A061002104F1100004F061FD1AE001210C
+:107FE0006846FBF79FFF9DF8000042F21071000207
+:107FF000B0FBF1F201FB1205FDF7D3FF0544294662
+:10800000A069FAF76AFCA061294604F1100004F0A7
+:1080100046FD461C208C411C0A293CBF304420846C
+:10802000606830B1208C401C0A2828BF84F8158075
+:1080300000D267753046FEF73DF9002804BF03B053
+:10804000BDE8F08F607A002801E014E011E01CBF69
+:1080500003B0BDE8F08F207B04F11001FBF77CF941
+:10806000002808BFFFDFA0E7207BFAF70EFF25708E
+:108070009BE7FFDF99E7202F28BFFFDFDFF804A48D
+:1080800007213AF81700F8F7EFFD040008BFFFDFFB
+:10809000202F28BFFFDFFB48218830F817008842D7
+:1080A00018BFFFDF01273461B9F1080F80F0548158
+:1080B000DFE809F0049EA6A6A1F0F0EFC4F8605135
+:1080C000F580C4F8645194F8210138B9FAF7FCFE40
+:1080D000D4F82C11FBF706FC00281BDCB4F81E11A9
+:1080E000B4F85800814206D1B4F8D410081AA4F8A4
+:1080F000D600204605E0081AA4F8D600B4F81E11F0
+:108100002046A4F85810D4F84811C4F82C11C0F82F
+:1081100050111DE0B4F81C11B4F85800091AA4F865
+:10812000D610B4F81C112046A4F85810D4F82C111D
+:10813000C4F84811C4F85011D4F83411C4F8E01050
+:10814000D4F83811C4F85411B4F83C11A4F85811FB
+:1081500001F0B6FFFAF792FE94F855A0814650461A
+:10816000FDF754FBBAF1020F08BFC74909D0BAF1B5
+:10817000010F08BFC54904D0BAF1040F0CBFC449B0
+:10818000C44908444FF47A7100F2E140B0FBF1F1C8
+:10819000D4F8140140F27122014460885043C1EBCD
+:1081A0004000A0F1300AB9F1B70F98BF4FF0B709FE
+:1081B0002146012004F048FD4844AAEB0000A0F24B
+:1081C0001939A2462146012004F03EFDDAF82410B8
+:1081D0009C30814288BF0D1AC6F80C904D4538BFBF
+:1081E000A946C6F8089084F8207186F80280DCE67B
+:1081F00002F0ADF801E0FDF7D3F884F82071D4E681
+:10820000FAF762FED4F8502101461046FBF76AFBEC
+:1082100048B1628840F27123D4F814115A43C1EB7B
+:108220004201B0FBF1F094F865100D290FD0B4F8BD
+:108230005820B4F81E1113189942AEBF481C401CB8
+:108240001044A4F81E0194F8220178B905E0B4F8AE
+:108250001E01401CA4F81E0108E0B4F81E01B4F889
+:10826000D410884204BF401CA4F81E01B4F85A017F
+:10827000DFF82492401CA4F85A01B4F88000B4F846
+:108280007E10401AB4F85810401E08441FFA80FBB4
+:1082900024E053E060E000BF96F80080B8F10C0FD6
+:1082A00028BFFFDF39F8188094F86CA1BAF10C0FE1
+:1082B00028BFFFDF39F81A000023404481B202A82A
+:1082C000CDE90050B4F81E212046FFF771FA0028CE
+:1082D0003FF46BAE012818BFFFDF27D0B4F81E01B2
+:1082E000ABEB000000B20028D6DA082084F8740056
+:1082F00084F87370204601F034FB84F80C5194F834
+:108300005C514FF6FF77202D00D3FFDF5D4820F84A
+:10831000157094F85C01FAF7B8FD202084F85C0130
+:10832000307903B0BDE8F04FF3F764BDB4F81E0137
+:10833000BDF808100844A4F81E01CFE794F80C011A
+:10834000042818BFFFDF84F80C5194F85C514FF6F5
+:10835000FF77202DDAD3D8E7FFDF26E610B54F4CA4
+:10836000207850B101206072FEF724FD20780328A8
+:1083700005D0207A002808BF10BD0C2010BD207B3E
+:10838000FBF7FCF8207BFBF746FB207BFAF77DFD33
+:10839000002808BFFFDF0020207010BD2DE9F04F3E
+:1083A0003E4F83B0387801244FF0000840B17C7212
+:1083B0000120FEF7FFFC3878032818BF387A0DD06B
+:1083C000DFF8DC9089F8034069460720F8F7D5FB11
+:1083D000002818BFFFDF4FF6FF7440E0387BFBF743
+:1083E000CDF8387BFBF717FB387BFAF74EFD0028FA
+:1083F00008BFFFDF87F80080E2E7029800281CBF73
+:1084000090F80C1100292AD00088A0421CBFDFF888
+:1084100074A04FF0200B4AD00721F8F725FC040088
+:1084200008BFFFDF94F85C01FBF7F5FA84F80C81D4
+:1084300094F85C514FF6FF76202D28BFFFDF2AF815
+:10844000156094F85C01FAF720FD84F85CB1694688
+:108450000720F8F792FB002818BFFFDF22E06846EC
+:10846000F8F769FB0028C8D021E0029800281CBF5B
+:1084700090F80C11002915D00088A0F57F41FF3934
+:10848000CAD114E0840C002004360200A2240200A9
+:10849000D0FB0100C0D4010028520200500C002083
+:1084A000D40000206846F8F746FB0028DDD089F8A4
+:1084B000038087F82C8087F80B8003B00020BDE88C
+:1084C000F08F70B50446FD4890F80004FC4D40095B
+:1084D00095F800144909884218BFFFDF95F8140D7C
+:1084E0004009F84991F800144909884218BFFFDF94
+:1084F000F549002001220C7188700A704870C8701C
+:10850000F2490870BDE8704048E7EF4908707047CD
+:108510002DE9F843ED4C06468846207800285CD1CA
+:10852000EB48FAF758FC2073202856D003276660E2
+:108530002770002565722572AEB1012106F1FC009D
+:10854000FBF719FD0620F8F737FB81460720F8F7FF
+:1085500033FB96F8FC104844B1FBF0F200FB12101C
+:10856000401C86F8FC00FAF789FCDA49091838BF84
+:1085700040F2F65000F23D1086B2FDF79BFBE06141
+:10858000FDF70FFD4FF0010950B384F80A90012167
+:108590006846FBF7C7FC9DF8000042F2107100022C
+:1085A000B0FBF1F201FB12000644FAF78DFC3146F4
+:1085B000FAF793F9A061277567752574207B04F19C
+:1085C0001001FAF7C9FE002808BFFFDF258400204C
+:1085D000FEF7F0FB0020BDE8F8830C20BDE8F8832F
+:1085E000FAF772FC3146FAF778F9A061A57284F8BF
+:1085F0002C90A8F226502063DDE7B34948707047FD
+:10860000B24810B5417A0124002918BF002409D1CD
+:1086100090F82C1031B1416A006B814284BF002474
+:10862000FEF7C2FB204610BD70B5A74C0546E0889A
+:10863000401CE080D4E902016278D5F86061002A2C
+:108640001CBF324604F053FAA060864208D895F861
+:108650000C01012804D0E078002804BF012070BD7F
+:10866000002070BD70B50C4640F2E24100FB01F500
+:108670002046FDF7CBF8022C08BF974907D0012C04
+:1086800008BF964903D0042C0CBF9549954908446E
+:108690004FF47A7100F2E140B0FBF1F000F54D705B
+:1086A00085428CBF281A002070BD2DE9F04F83B0A1
+:1086B0004FF00009044680F8209190F8DE00002871
+:1086C00007BF94F80C01032803B0BDE8F08FFAF758
+:1086D000FBFBD4F8502101461046FBF703F90028B4
+:1086E000DCBF03B0BDE8F08F628840F27123D4F89C
+:1086F00014115A43C1EB4201B0FBF1F0411CB4F834
+:1087000058000144A4F81C11B4F8D410B4F81C218A
+:10871000891A09B20029DCBF03B0BDE8F08F01213E
+:1087200084F82211B4F88010B4F87E206E4F891AB4
+:10873000491E084485B2DFF890A10DF1080B25E031
+:108740009AF800600C2E28BFFFDF37F8166094F807
+:108750006C81B8F10C0F28BFFFDF37F81800CDE9A6
+:10876000009B3044B4F81C2181B201232046FFF75E
+:108770001FF8002804BF03B0BDE8F08F01280FD018
+:10878000022812BFFFDF03B0BDE8F08FB4F81C0170
+:10879000281A00B20028BCBF03B0BDE8F08FCFE7B5
+:1087A000B4F81C01BDF808100844A4F81C01EDE75A
+:1087B0002DE9F0430422002583B006297DD2DFE8AD
+:1087C00001F0074B03191951044680F80C2107E00A
+:1087D00004463D48C178002918BF84F80C210CD00C
+:1087E000FAF77EFAA4F85A51B4F85800A4F81E011A
+:1087F00084F8225103B0BDE8F08306780C2E28BF20
+:10880000FFDF394F94F80C0137F816604FF001097B
+:10881000032807D00128E3D194F86C81B8F10C0F3C
+:108820000AD308E0C4F80851C4F8005194F86C81E8
+:10883000B8F10C0F00D3FFDF37F81800CDE9009531
+:10884000304481B2B4F8D42000232046FEF7B0FFB4
+:10885000002818BFFFDFC3E7032180F80C1103B025
+:10886000BDE8F0830546876AB0F81401294686B250
+:10887000012004F0E9F9044695F85500FCF7C6FF1D
+:1088800095F85510022908BF134907D0012908BFE0
+:10889000124903D004290CBF1149124908444FF46E
+:1088A0007A7100F2E140B0FBF1F0698840F2712288
+:1088B0005143C0EB4100801B18E02DE001E000E0D7
+:1088C0000BE000E019E000E0D4000020500C002094
+:1088D0002F7F01000AFAFFFF04360200A2240200E3
+:1088E000D0FB0100C0D4010028520200A0F5597647
+:1088F00001F032FD002818BF1E3EA74234BF2046BB
+:108900003846B04228BF344602D2A74228BF3C4670
+:108910006C6203B0BDE8F083FFDF03B0BDE8F08315
+:10892000F8B5894C0246874F00256168606A052AC0
+:1089300048D2DFE802F0032F34373E00A07A002649
+:1089400060B101216846FBF7F7FA9DF8000042F29A
+:1089500010710002B0FBF1F201FB1206FDF721FBE2
+:108960008119A069F9F7B9FFA0612574032060752A
+:10897000607A38B9207B04F11001FAF7EDFC002889
+:1089800008BFFFDF2584FAF7ABF93879BDE8F84076
+:10899000F3F730BABDE8F840002100F06DB8C1F837
+:1089A0006001F8BDD1F86001BDE8F840012100F098
+:1089B00063B884F82C50FAF793F93879BDE8F84099
+:1089C000F3F718BAFFDFF8BD70B55E4CA178022945
+:1089D00006BFE188002970BD2569C5F8640195F8D6
+:1089E0005500FCF701FFD5F86411081AA16801448D
+:1089F000A160E1680844E06070BD70B5054651486B
+:108A000090F802C0BCF1020F06BF006900F5B07417
+:108A10004E4C002904BF256070BD4FF47A760129C1
+:108A20000DD002291CBFFFDF70BD1046FCF707FF09
+:108A300000F2E140B0FBF6F0281A206070BD184645
+:108A4000FCF712FF00F2E140B0FBF6F0281A2060BC
+:108A500070BD3D48007800281CBF0020704710B54D
+:108A60000720F8F79BF880F0010010BD3648007829
+:108A7000002818BF012070472DE9F047324C82B022
+:108A8000002584F82C50D4F8188084F82810E5725A
+:108A900081462570012727722946606803F082FB12
+:108AA0006168C1F85081267B81F85C61C1F86091F2
+:108AB000C1F85481B1F80080202E28BFFFDF244880
+:108AC00020F81680646884F80C51DFF87880A4F8E8
+:108AD000585198F800600C2E28BFFFDFDFF8749023
+:108AE00039F816A094F86C610C2E28BFFFDF39F816
+:108AF00016000023504481B200951A462046019585
+:108B0000FEF756FE002818BFFFDFC4F80851C4F86E
+:108B1000005184F80C71A4F81E51A4F81C5184F87B
+:108B20002251B4F85800401EA4F85800A4F85A5135
+:108B3000FAF7D6F898F8040002B0BDE8F047F3F76A
+:108B400059B90000D4000020500C0020740C002003
+:108B5000840C00202852020070B5FE4C21690A885E
+:108B6000A1F8FC2181F8FA0191F85400012808BF0E
+:108B7000012508D0022808BF022504D0042816BF0A
+:108B800008280325FFDF206980F8FE5190F8550082
+:108B9000012808BF012508D0022808BF022504D0FB
+:108BA000042816BF08280325FFDF2069012180F86B
+:108BB000FF5180F8F811002180F8A4112079BDE858
+:108BC0007040F3F717B92DE9F04FE24C83B0A0796C
+:108BD00010F0010F04BF03B0BDE8F08FA0690123BE
+:108BE0000521C578206990F86520583003F0EDFE26
+:108BF00068B1A81E0A2806D2DFE800F009090505B9
+:108C0000090905050909A07840F00800A070A078BE
+:108C100000281CBF03B0BDE8F08FA0694FF0200909
+:108C20004FF00208C778002F1CBF012F162F1DD14F
+:108C3000206990F8640003F0B1FEB8B1216991F8A1
+:108C400064001F2812D0202808D0162F0CBF84F8EB
+:108C5000029084F8028003B0BDE8F08F262081F8EE
+:108C60006400162F1CBF2A20FFF776FF47F6FE7A16
+:108C7000012600254FF0280B0C2F00F03B8109DC6A
+:108C800080F05F84DFE807F05A3923CCFDFDFCFB60
+:108C9000FAFD9CC3152F00F046820DDC112F00F069
+:108CA000C783122F00F0C081132F00F0B081142F62
+:108CB00000F0CE8100F045BC162F00F06782182F1F
+:108CC00000F0CC82FF2F00F0358400F03ABC206920
+:108CD0000123194690F86720583003F076FE0028EB
+:108CE00040F03184A06904F081FC216981F87201AF
+:108CF000072081F8670000F026BC206901230021CD
+:108D000090F86520583003F060FE002800F0C98319
+:108D1000A06904F068FC2169A1F88E01B1F858201F
+:108D2000801A00B28245A8BF002843DD01F5C87152
+:108D3000A06904F053FC0B20216937E0206901236E
+:108D4000002190F86520583003F03FFE002800F025
+:108D5000A883A06904F01EFC002800F0F283A0693B
+:108D60002169B0F80D20A1F88E21B1F85830D21A3F
+:108D700012B29245A8BF002A1CDD027981F8902129
+:108D8000B0F80520A1F8922104F0F7FB2169A1F8C1
+:108D90009401A06904F0F4FB2169A1F89601A0698F
+:108DA00004F0F5FB2169A1F898010D2081F8650018
+:108DB00000F0C9BB81F874B081F8736000F0C3BBE8
+:108DC00020690123002190F86520583003F0FDFD53
+:108DD000002820690CD0A0F88A5090F88C10491C0B
+:108DE00080F88C105FF0100180F8651000F0ABBBCC
+:108DF00090F8652001230521583003F0E6FD002896
+:108E00001CBF0820A07040F09E8300F04ABB206980
+:108E100090F86510112908BF122140F0A082E3E705
+:108E200020690123002190F86520583003F0CDFD22
+:108E300080B9206990F86520122A0BD00123052102
+:108E4000583003F0C2FD002818BF082000F0298325
+:108E500000F099B9206990F88E1031B9A0F88A50C5
+:108E600090F88C10491C80F88C1000F1E801A06982
+:108E700004F0D5FB206900F1C00103E0A4E0F6E2B4
+:108E800023E05EE3A06904F0D5FB206990F8C001FF
+:108E9000002818BFFFDF20690188A0F8C21100F583
+:108EA000E271A06904F0A9FB206900F5E671A069F0
+:108EB00004F0ABFB206980F8C061142180F86510D4
+:108EC0002079F2F797FF00F03EBB206990F865101B
+:108ED000172940F0448290F88C10491E49B280F85E
+:108EE0008C100029B8BFFFDF1B20216981F86500C5
+:108EF00000F029BB206990F8661011F0020F09D02C
+:108F000090F8642001230821583003F05EFD00280A
+:108F100000F0C782206990F8900010F0020F14D181
+:108F2000A06904F09BFB216981F89100A069B0F869
+:108F30000520A1F89220B0F80700A1F8940091F85C
+:108F4000900040F0020081F89000206990F89010A5
+:108F500002E00000F000002011F0010F05D02069B0
+:108F600090F8641006291CD114E090F8660010F007
+:108F7000020F18BFFFDF206990F8661041F0020170
+:108F800080F86610A0F88A5090F88C10491C80F880
+:108F90008C10E4E780F8645080F888502079F2F76C
+:108FA00029FF206990F88C11042940F0CC8280F8C8
+:108FB0008C512079F2F71EFF206990F86410002987
+:108FC00040F0C18200F031BA206990F8660010F0DC
+:108FD000010F77D16946A06904F047FB9DF80000B6
+:108FE00000F02501206980F896109DF8011001F02D
+:108FF000410180F89710A0F88A5090F88C10491C15
+:1090000080F88C1090F8661041F001011CE0206996
+:109010000123092190F86420583003F0D6FC002881
+:1090200040F0378200F03DBA206990F8661011F0E8
+:10903000040F40F03682A0F88A5090F88C2041F05E
+:109040000401521C80F88C2080F8661000F07BBA76
+:10905000206990F8660010F0300F33D1A06904F059
+:1090600021FB002800F06D822769A06904F016FB3F
+:1090700038872769A06904F00DFB78872769A06904
+:1090800004F00EFBB8872769A06904F005FBF88798
+:10909000A07910F0020F03D06069C078142812D0B4
+:1090A000206990F864101C290DD090F84E10012909
+:1090B0000CD090F89B11002904BF90F89A11002958
+:1090C0000CD003E05CE0206980F84E60206990F8E5
+:1090D000661041F0100180F866101AE090F86610F2
+:1090E00041F0200180F866100288A0F8E021028F8C
+:1090F000A0F8E221428FA0F8E421828F00F5D6711A
+:10910000A0F8E621C08F888781F832602079F2F7D5
+:1091100071FE2069A0F88A5090F88C10491C80F8E4
+:109120008C1000F010BA206901230A2190F8642005
+:10913000583003F04AFC18B3A06904F0B3FAA8B1A0
+:109140002669A06904F0AAFA30872669A06904F0AC
+:10915000A1FA70872669A06904F0A2FAB08726698F
+:10916000A06904F099FAF08701F000FB206980F80B
+:10917000885080F8645000BF01F0C8FA00F0E3B9ED
+:10918000A07840F00100A07000F0DDB92069012353
+:109190000B2190F86520583003F017FC20B100BF78
+:1091A00084F8029000F0CFB920690123002190F8E3
+:1091B0006520583003F009FC002800F07281206916
+:1091C00090F864002428EBD0A06904F086FA002807
+:1091D00000F0B781206990F8961041F0040180F802
+:1091E0009610A1694A7902F0070280F851200979A6
+:1091F00001F0070180F8501090F8A531002B04BF52
+:1092000090F8A431002B1CD190F855C000F1540304
+:109210008C4502BF1978914280F87D6011D000F52D
+:10922000D67180F8F2610288A0F8F42190F85020FD
+:1092300080F8F62190F8510081F84B002079F2F780
+:10924000D9FD2069212180F86510A0F88A5090F896
+:109250008C10491C80F88C1000F075B9206990F8CA
+:109260006410202914BF0027012790F865102229D7
+:1092700008BF00F1650804D0002F18BF00F1640892
+:109280006DD090F8961041F0040180F89610A06916
+:1092900004F045FAF0B3D4F81890484604F033FAD5
+:1092A0000090484604F033FA814603F042FD010085
+:1092B00018D0206990F854208A4213D090F8A43135
+:1092C00023B190F8A63113EA090F4BD0002F04BF49
+:1092D00090F8513013EA090F01D18A4242D890F830
+:1092E000A401B8B1DDF80090484603F022FD78B142
+:1092F000216991F8552082420AD091F8A40120B149
+:1093000091F8A70110EA090F2CD091F8A40108B137
+:109310006A4600E026E0A169206903F019FDE8B380
+:10932000A06904F0FAF92169A1F88E01B1F858207A
+:10933000801A00B28245A8BF0028DCBF81F874B053
+:1093400081F873605CDD9DF8000081F890019DF864
+:10935000010081F89101242088F8000050E084F891
+:109360000280F0E0206990F8A40100281CBF1E20B4
+:10937000FFF7F2FBB7B1A0692169C07881F8CA0094
+:1093800006FA00F010F0807F08BFFFDF0A21206995
+:1093900080F8641090F88800002800E014E008BF0E
+:1093A000FFDF0DE088F80050206990F88C10491E0E
+:1093B00049B280F88C100029B8BFFFDF01F08BF9AB
+:1093C000206980F87D50BEE0226992F8A40170B156
+:1093D000B2F8583092F85410B2F8A80102F5C772EA
+:1093E00003F0A8FDD8B12169252081F86400206927
+:1093F00000F1650180F87D50884508BF80F8655010
+:10940000206900F1650188450FD190F88C10491E44
+:1094100049B280F88C100029B8BFFFDF93E000202C
+:10942000FFF79AFB88F80050E1E780F888508AE05F
+:10943000206990F8961041F0040180F89610A06918
+:1094400004F089F916287ED1206990F8640020285C
+:1094500002D0262805D076E0A06904F080F9FFF755
+:109460007BFB206980F8645080F888506BE02069AD
+:1094700090F864200E2A03D1A1690979122902D03B
+:109480001C2A1AD10FE001230921583003F09DFA5C
+:1094900038B1206980F87C5080F8885080F864509A
+:1094A00051E0A6704FE0A1690979142904BF80F842
+:1094B000645080F888503FF45FAE202A03D1A16940
+:1094C0000979162914D0262A03D1A1690979162908
+:1094D0000ED0A1690979172904BF90F86520222AC6
+:1094E00013D0E2691AB1FF2908BF80F886612AE02B
+:1094F00080F8645080F8885090F86500212818BFE3
+:109500001A2020D0FFF728FB1DE080F8655090F866
+:109510008C10491E49B280F88C100029B8BFFFDFBB
+:10952000206980F87D5090F8A401002818BF002021
+:1095300009D0E7E7E06900281CBF206980F8866150
+:1095400001D101F0C8F82069D0E92A12491C42F182
+:109550000002C0E92A1203B0BDE8F08F70B5FB4EDF
+:1095600005460C46306990F8CB00FE2818BFFFDF97
+:1095700032690020002C82F8CB501CBFA2F88A0070
+:1095800070BDA2F88400012082F8880070BD30B55B
+:1095900085B005466846FCF7D6F9002808BFFFDF0E
+:1095A000222100980BF055FB0321009803F09AFF4D
+:1095B0000098017821F010010170294603F0C0FFE6
+:1095C000E24C0D2D04BF0621009830D00BDCA5F134
+:1095D00002000B2819D2DFE800F0201863191926C1
+:1095E000187018192C00152D7BD008DC112D2DD0EA
+:1095F000122D18BF132D09D0142D30D005E0162DD3
+:1096000046D0172D6BD0FF2D6AD0FFDFFCF7AEF9E7
+:10961000002808BFFFDF05B030BD2069009990F831
+:10962000CC000871F2E72169009891F8CC10017123
+:10963000ECE7E26800981178017191884171090A9C
+:1096400081715188C171090A0172DFE70321009815
+:1096500004F07FF80621009804F07FF8D6E720692F
+:10966000B0F84410009804F005F82069B0F84610EE
+:10967000009804F003F82069B0F84010009804F056
+:1096800001F82069B0F84210009803F0FFFFBDE731
+:109690002069009A90F8A611117190F8A7014BE08B
+:1096A000206900F1F001009803F0C8FF206900F183
+:1096B000C401009803F0CCFFA8E7A549D1E9000157
+:1096C000CDE90201206902A990F8960000F025007A
+:1096D0008DF80800009803F0F6FF97E701E019E025
+:1096E0002CE02069B0F84010009803F0CBFF20690F
+:1096F000B0F84210009803F0C9FF2069B0F8441098
+:10970000009803F0B7FF2069B0F84610009803F006
+:10971000B5FF7BE7206990F8A41139B1009990F862
+:10972000A6210A7190F8A70148716FE7009A90F896
+:109730005410117190F85500507167E7206990F846
+:109740008721D0F88811009803F008FF5EE770B514
+:109750000C4605464FF4007120460BF09CFA25801C
+:1097600070BDF7F78ABB2DE9F0410D46074607218A
+:10977000F7F77AFA040008BFBDE8F08194F8AC016D
+:109780000026B8B16E700920287094F8AC0178B149
+:10979000268484F8AC61D4F8AE016860D4F8B201D4
+:1097A000A860B4F8B601A88194F8AC010028EFD104
+:1097B0002E7144E094F8B801002837D094F8B8012D
+:1097C0000D2818D00E2818BFFFDF38D12088F7F7F2
+:1097D0007DFB0746F7F729F8A0B96E700E202870B8
+:1097E00094F8BA0128712088E88084F8B861384676
+:1097F000F7F715F823E02088F7F768FB0746F7F737
+:1098000014F810B10020BDE8F0816E700D202870B2
+:1098100094F8BA0128712088E88094F8BE01287273
+:1098200084F8B8613846F6F7FAFF08E094F8F001DA
+:1098300040B16E701020287084F8F061AF80012074
+:10984000BDE8F08194F8C00190B16E700A202870D4
+:109850002088A880D4F8C401D4F8C811C5F806003F
+:10986000C5F80A10B4F8CC01E88184F8C061E6E7D5
+:1098700094F8CE0140B16E701A202870B4F8D0016F
+:10988000A88084F8CE61DAE794F8EA0180B16E70BE
+:109890001B20287094F8EA010028D0D084F8EA61EF
+:1098A000D4F8EC01686094F8EA010028F6D1C6E724
+:1098B00094F8D2012F1DA0B16E701520287094F875
+:1098C000D201002818BF04F5EA75B8D084F8D26137
+:1098D000294638460BF0EBFA94F8D2010028F5D16E
+:1098E000ADE794F8DE0150B16E701D20287084F849
+:1098F000DE6104F5F07138460BF0D9FA9FE794F871
+:10990000F20138B11E20287084F8F261D4F8F40115
+:10991000686094E794F8F801002808BFBDE8F0817A
+:109920006E701620287094F8F801002887D000BFC8
+:1099300084F8F861D4F8FA016860B4F8FE0128816F
+:1099400094F8F8010028F3D179E70000F000002036
+:1099500040520200FE4AD0600020D06110621171B6
+:109960007047002180F8641080F8651080F8681056
+:1099700090F8DE1011B10221FEF71ABF0321FEF7A5
+:1099800017BF2DE9F047F24C814686B020690D469D
+:109990000088F7F7ADFA070008BFFFDFA07828437B
+:1099A000A070A0794FF0000510F0200F20691CBFB7
+:1099B000A0F87E5080F8E45004D1B0F87E10491C25
+:1099C000A0F87E102069012690F86A1039B990F845
+:1099D000652001230621583002F0F7FF48B3E088E4
+:1099E00010F4006F07D0206990F86A10002918BFA2
+:1099F000A0F876501DD12069B0F87610491C89B2C4
+:109A0000A0F87610B0F878208A422CBF531A0023B1
+:109A1000B4F808C00CF1050C634598BF80F87C6071
+:109A2000914206D3A0F8765080F8F0612079F2F7E1
+:109A3000E1F9A0794FF0020A10F0600F11D020690F
+:109A400090F8681011B1032906D00AE080F8686028
+:109A50000121FEF7ADFE04E080F868A00121FEF7C9
+:109A6000A7FE206990F86810012905D1E18811F45A
+:109A7000807F18BF80F868A04FF00808B9F1000F88
+:109A800040F09981E28812F4007F18BFA0F8F850E6
+:109A900004D1B0F8F810491CA0F8F81012F0080F23
+:109AA00050D0A17800294DD190F8CB00FE2808BFF6
+:109AB000FFDFFE21206980F8CB1090F8651019298E
+:109AC00007D0206990F864101F2911D027292AD0C7
+:109AD0002FE080F88D5090F88C10491E49B280F824
+:109AE0008C100029B8BFFFDF206980F86550E8E7D7
+:109AF00090F8650002F052FF80B120692621012311
+:109B000080F8641090F865200B21583002F05DFF5A
+:109B1000002804BF2A20FFF71FF80AE0216920204F
+:109B200081F8640005E080F8856180F8645080F871
+:109B30008850206990F86710082904BF84F800A0B5
+:109B400080F8CBA0FFF73FF8A07910F0040F07D002
+:109B5000A07828B9206990F86700072808BF267008
+:109B600000F038FCA07910F0100F09D0A07838B9B7
+:109B7000206990F865100B2904BF0C2180F865104E
+:109B8000E07810F0080F11D020690123052190F82A
+:109B90006520583002F019FF28B184F8028020694E
+:109BA00080F8B85102E0002001F02AFBE0690028AB
+:109BB0005BD000950195029503950495206990F876
+:109BC0005500FBF723FE4FF47A7100F5FA70B0FBF5
+:109BD000F1FA206990F85500FBF706FE5044ADF805
+:109BE000060020690188ADF80010B0F85810ADF8F3
+:109BF00004104188ADF8021090F8860130B1A069D8
+:109C0000C11C039103F058FC8DF81000206990F8F6
+:109C100085018DF80800E16968468847206980F869
+:109C2000865180F885510399F9B190F88411E1B912
+:109C300090F86410272918D09DF81010039AA1B14C
+:109C40001378FF2B06D0072B02BF02295178FF297A
+:109C500002D00AE01B2908D880F884610399C0F873
+:109C600088119DF8101080F8871100F0CCFD01F0EC
+:109C7000BDFA0028206918BFA0F8D85004D1B0F868
+:109C8000D810491CA0F8D81001F0B3FA40B12169EE
+:109C900091F8E40002289CBF401C81F8E40004D83D
+:109CA000206990F8E400022806D92069A0F8D8506D
+:109CB000A0F8DA5080F8E45020690123002190F8E0
+:109CC0006520583002F081FE20B9206990F86500C7
+:109CD0000C285AD120690123002190F864205830C3
+:109CE00002F073FEB0B320690123002190F86720D1
+:109CF000583002F06AFE68B3206990F868100229B3
+:109D000004BF90F8E40000283FD13846F6F75DFB29
+:109D100000B3206990F8CB10FE2936D1B0F8D210EC
+:109D2000012932D980F8DD60B0F88010B0F87E20CB
+:109D30008B1E9A42AFBF0121891A491E89B2B0F821
+:109D4000D82023899A422EBF01229A1A521C02E07F
+:109D5000F000002019E038BF92B2914288BF11464E
+:109D6000012908BF80F8DD5090F868218AB1B0F869
+:109D7000DA20B0F86A0182422FBF0120801A401C0D
+:109D800080B2814288BF014603E02069012180F84A
+:109D9000DD502069B0F85820114489B2A0F8D410E1
+:109DA00090F86830002B18BF012B5DD0022B1CBF30
+:109DB000032BFFDF09D0E088C0F340200028206992
+:109DC00018BFA0F8E65059D151E090F86730082B41
+:109DD00021D0B0F87E10B0F8802000278B1C9A426A
+:109DE00006D3511A891E0F043F0C1CBF791E8FB277
+:109DF00090F87C1051B190F864200123092158306B
+:109E000002F0E3FD002808BF002729D0206990F860
+:109E10006A1089B908E0B0F87E30032B24D3B0F87B
+:109E200080101144491C1FE090F865200123062191
+:109E3000583002F0CAFD78B121690020B1F87820CD
+:109E4000B1F876108B1C9A4203D3501A801E18BFAB
+:109E5000401EB84238BF87B2002F1CBF781E87B2A1
+:109E60002069B0F8D4103944A0F8D010A3E7B0F8B6
+:109E7000E610B0F8D6201144A0F8E610206990F85A
+:109E8000701139B990F8672001231946583002F053
+:109E90009CFD38B12069B0F88210B0F8D62011448A
+:109EA000A0F88210206990F8883033B1B0F884109F
+:109EB000B0F8D6201144A0F8841090F98C20002A24
+:109EC00006DDB0F88A10B0F8D6C06144A0F88A1058
+:109ED0004FF03D0CB9F1000F18BF80F874C049D1A4
+:109EE0002178022911D0012908BF90F872113FD0C2
+:109EF000A17821B380F8736011F0140F18BF1E21F0
+:109F000009D000BF80F8741050E090F8CC100629FA
+:109F100018BF16212CE011F0080F18BF80F874C08C
+:109F200044D111F0200F18BF2321EBD111F0030F02
+:109F300008BFFFDF2A20216981F8740032E02BB1CD
+:109F4000B0F88410B0F88630994210D2002A05DDAE
+:109F5000B0F88A10B0F88620914208D2B0F882207A
+:109F6000B0F880108A4208D390F870212AB12221DB
+:109F700080F8741080F8736018E090F868203AB1A7
+:109F8000B0F87E208A4228BF80F87480F2D209E0BF
+:109F9000B0F87E10062905D33E2180F8741080F8B1
+:109FA000736003E0206990F8731079B1206980F83C
+:109FB000645080F8655080F8685090F8DE100029F1
+:109FC00014BF02210321FEF7F3FB02E00021FEF79C
+:109FD000EFFB206980F8DE5006B0BDE8F047FBF7E4
+:109FE000E7BCF84902468878CB78184313D1084675
+:109FF00000694AB1897911F0080F03D090F8670021
+:10A00000082808D001207047B0F84810028E91420D
+:10A0100001D8FEF709BB0020704770B5E94C054632
+:10A020000E46E0882843E08015F0020F04D015F0BA
+:10A03000010F18BFFFDF666115F0010F4FF000023E
+:10A040004FF001001AD0A661F178062902D00B2941
+:10A050000BD013E0216991F86530172B0ED1002346
+:10A06000C1E9283381F8690008E0216991F8653079
+:10A07000112B04BF81F8692081F88E0015F0020FC2
+:10A0800018D06169C978052902D00B290BD011E0DD
+:10A09000216991F86520152A0CD10022C1E92A22F4
+:10A0A00081F86A0006E0206990F86510102908BF61
+:10A0B00080F86A2015F0800F1CBF0820E07070BD8A
+:10A0C0002DE9F84FBF4C00254FF00108E580A57041
+:10A0D000E5702570206168F30709074680F8DE8087
+:10A0E0000088F6F705FF5FEA000A08BFFFDF206976
+:10A0F0000088FBF725FC20690088FBF747FC2069F6
+:10A10000B0F8D21071B190F8CB10FE290FD190F8B1
+:10A11000701189B190F8672001231946583002F078
+:10A1200054FC88B1206990F8CB00FE2804D0206947
+:10A1300090F8CB00FFF72BFA206990F8DF10002988
+:10A1400018BF25811BD10FE02069A0F8825090F83C
+:10A15000711180F8CC1000210220FFF7FFF920696F
+:10A1600080F8DD500220E5E790F8AC1129B9018CA8
+:10A170008288914288BF218101D881882181B0F8ED
+:10A18000D610491E8EB2B0F8D8103144A0F8D810BD
+:10A1900090F8DC1000291CBFA0F8DA5080F8DC50E1
+:10A1A00004D1B0F8DA103144A0F8DA10B0F87E101B
+:10A1B0003144A0F87E1090F86A1039B990F8652003
+:10A1C00001230621583002F000FC28B12069B0F8C4
+:10A1D00076103144A0F876102069B0F8D210012929
+:10A1E0009CBF491CA0F8D210002E18BF80F8E45084
+:10A1F00090F8DD10A1B1B0F8D800218988420FD2C3
+:10A200005046F6F7E2F858B1206990F8681139B174
+:10A21000B0F8DA10B0F86A01814228BF00F0ECFF14
+:10A22000206980F8DD5090F865100B2918BF0C29C3
+:10A2300016D1B0F85820B0F88E31D21A12B2002AD6
+:10A240000EDBD0F89011816090F894110173022117
+:10A2500001F0A8FF206980F8655080F898804AE0F6
+:10A26000242924D1B0F85810B0F88E21891A09B2E7
+:10A2700000291CDB90F8A42190F89011002908BF58
+:10A2800090F8541080F8541090F89111002908BFEC
+:10A2900090F8551080F85510002A1CBF0020FEF7DA
+:10A2A0005BFC206980F8655080F87D5023E090F8D1
+:10A2B0006410242918BF25291DD1B0F85810B0F812
+:10A2C0008E21891A09B2002915DB90F89011002916
+:10A2D00008BF90F8541080F8541090F8911100299C
+:10A2E00008BF90F8551080F855100020FEF734FC98
+:10A2F000206980F86450216901F15800B1F8D62036
+:10A3000002F026F9206990F86811002918BFA0F81A
+:10A31000DA502D4800902D4B2D4A3946484600F022
+:10A32000B3FE216A00291CBF6078FAF789FF206913
+:10A330000123052190F86520583002F046FB0028E3
+:10A3400008BFBDE8F88FBDE8F84F00F08EBC00F004
+:10A3500033BF1C49C86170471A48C069002818BF3C
+:10A3600001207047174A50701162704710B50446BB
+:10A37000B0F894214388B0F89611B0F898019A4249
+:10A3800001BFA3889942E38898420FD02388A4F89C
+:10A39000B031A4F8B221A4F8B411A4F8B601012098
+:10A3A00084F8AC0107480079F1F724FD012120462B
+:10A3B00001F0F8FE002084F86500032084F86800AE
+:10A3C00010BD0000F000002083990100E39F010010
+:10A3D0001BA0010070B5FE4CA07910F0020F08BF61
+:10A3E00070BDA078002818BF70BD6169F8482722A9
+:10A3F000CB780E26002500690D2B78D00BDCA3F15D
+:10A4000002030B2B1FD2DFE803F0201E808B9F2F4F
+:10A410001E591E73D100152B00F02A810BDC112B65
+:10A4200065D0122B00F0F480132B00F0FF80142B6A
+:10A4300000F00E8107E0162B00F03281172B00F0A0
+:10A440003F81FF2B35D0FFDF70BD90F867200123DF
+:10A450001946583002F0B9FA002818BF70BD08201C
+:10A46000216981F8670070BD90F8643009790A2B82
+:10A4700001BF90F8CA308B4280F8645080F8885051
+:10A4800008BF70BD90F8663013F0080F0DD023F0B0
+:10A49000080180F8661090F88C10491E49B280F8C7
+:10A4A0008C100029A8BF70BDCFE0FF291CBFFFDFC3
+:10A4B00070BD80F8642080F8845170BD90F866000B
+:10A4C00010F0010F08BFFFDF216991F88C00401EDA
+:10A4D00040B281F88C000028B8BFFFDF206990F8F7
+:10A4E000661021F0010100BF80F8661070BD21E008
+:10A4F00090F86500102818BFFFDF0121206980F85F
+:10A500008D10112180F8651070BD90F86500142839
+:10A5100018BFFFDF0121206980F88D101521F1E7B8
+:10A5200090F86500152818BFFFDF1720216981F812
+:10A53000650070BD90F86500152818BFFFDF192071
+:10A54000216981F8650070BD90F865001B2818BF6F
+:10A55000FFDF206980F88D5090F8B801002818BFFF
+:10A56000FFDF206990F88E1049B180F88E50018885
+:10A57000A0F8BC1180F8BA5180F8B8610AE00188EF
+:10A58000A0F8BC1180F8BA51012180F8BE110D214C
+:10A5900080F8B8110088F6F799FCF6F731F92079C0
+:10A5A000F1F728FC206980F8655070BD90F88C1197
+:10A5B000042915D0206990F8661011F0020F08BF29
+:10A5C00070BD90F88C10491E49B280F88C1000299B
+:10A5D000B8BFFFDF206990F8661021F0020183E721
+:10A5E00090F8642001230021583002F0EEF9002891
+:10A5F00008BFFFDF206990F8901011F0020F07BF2D
+:10A60000062180F8641080F8885080F88C51D1E7DA
+:10A6100090F8642001230021583002F0D6F9002878
+:10A6200008BFFFDF206980F8646070BD90F8661095
+:10A6300021F0040180F8661090F88C10491E49B290
+:10A6400080F88C100029A8BF70BDFFDF70BD00BF6F
+:10A6500090F8642001230021583002F0B6F9002858
+:10A6600008BFFFDF1C20216981F8640070BD00BFB6
+:10A6700090F8660000F03000102818BFFFDF206956
+:10A6800090F8661021F0100180F8661090F88C1098
+:10A69000491E49B280F88C100029A8BF70BDD4E7CC
+:10A6A00090F8642001230021583002F08EF9002830
+:10A6B00008BFFFDF1F20216981F8640070BD00BF63
+:10A6C00090F8650021281CBF0028FFDF22202169A7
+:10A6D00081F8650070BD3E49086990F8662012F067
+:10A6E000080F1EBF01208870704742F0080280F8F2
+:10A6F00066208969C97880F8C9100021A0F88A10FD
+:10A7000090F88C10491C80F88C10704710B5304CB4
+:10A7100005212069FEF74CF8206990F84E100129B8
+:10A7200002BF022180F84E1010BD00F5D6710288DC
+:10A73000A0F8D421028EA0F8D621828EA0F8D821CC
+:10A74000028FB0F844309A4228BF1A46CA85828FD9
+:10A75000B0F84600824238BF10460886012081F8D2
+:10A7600026002079BDE81040F1F744BB184830B40A
+:10A77000006990F84E30B0F832C0C48EB0F8401086
+:10A78000428F022B28D08A4238BF11460186C28FE1
+:10A79000B0F842108A4238BF11468186028FB0F865
+:10A7A00044108A4238BF11464186828FB0F8461065
+:10A7B0008A4238BF1146C186418E614588BF8C46AA
+:10A7C000A0F832C0C18EA14288BF0C46C48601E009
+:10A7D000F000002030BC7047038E9A4228BF1A4612
+:10A7E000C58F838E9D4238BF2B468A4238BF1146A3
+:10A7F0000186B0F842108B4228BF0B4683860021A9
+:10A8000080F84E10CAE770B5FD4C206990F8CB1067
+:10A81000FE2906BFA178002970BD90F867200123AA
+:10A820001946583002F0D1F8002818BF70BD2069D1
+:10A83000002590F8701159B1A0F8825090F871116C
+:10A8400080F8CC10BDE8704000210220FEF786BEE3
+:10A8500090F8652001230421583002F0B6F8060074
+:10A860000CD0D4F810C09CF86500102861D01428D2
+:10A8700065D015287BD01B287ED0BEE0216991F8D9
+:10A88000660010F0010F05D0BDE8704001210920DD
+:10A89000FEF764BE10F0020F0BD001210C20FEF772
+:10A8A0005DFE206990F8901041F0010180F8901051
+:10A8B00070BD10F0040F05D0BDE8704001211320D9
+:10A8C000FEF74CBE10F0080F09D091F8C90081F8CE
+:10A8D000CC00BDE8704001210720FEF73FBE10F01C
+:10A8E000100F02D091F89B0120B191F8650021284A
+:10A8F00073D179E091F89A0188B1B1F89C01A1F87F
+:10A900004000B1F89E01A1F84200B1F8A001A1F801
+:10A910004400B1F8A201A1F8460081F89A51FFF76E
+:10A9200025FFFFF7F3FEBDE8704001211520FEF77B
+:10A9300015BEBDE8704001210B20FEF70FBEF9F7F0
+:10A94000F7FA0C2838BF70BD08212069F030F9F7FC
+:10A95000F3FA28B120690421C430F9F7EDFA00B9FF
+:10A96000FFDFBDE8704001210420FEF7F7BD9CF831
+:10A97000730101280DD000E030E0022818BF70BD3F
+:10A980009CF88E00D8B106208CF8CC000121022062
+:10A990001DE09CF8B801002818BF70BD0CF1B00391
+:10A9A00000220CF1E8010CF5BA7001F08AFF0121D8
+:10A9B0000520FEF7D3FD206980F8735170BD9CF827
+:10A9C000960010F0040F14BF11200D200121FEF796
+:10A9D000C5FD206980F8735170BD0EE0BDE8704080
+:10A9E00001210620FEF7BABD91F87D00C0B991F8AB
+:10A9F000A40110B191F8A50190B1206901230021B3
+:10AA000090F86420583001F0E0FFC8B120690123BC
+:10AA1000042190F86520583001F0D7FF30B10FE0E5
+:10AA2000BDE8704001211720FEF798BD206990F81D
+:10AA30007C0028B1BDE8704000211220FEF78EBDD9
+:10AA4000206990F864200A2A2BD0002E18BF70BD10
+:10AA500001230021583001F0B8FF48B1206990F877
+:10AA60008C11042904BF90F8900010F0030F22D03D
+:10AA700020690123002190F86420583001F0A5FFDF
+:10AA800000287DD0206990F89A1111B190F89B119F
+:10AA9000E9B190F8A411002972D090F8A511E9B39A
+:10AAA000BDE090F8CA1080F8CC10BDE870400021DD
+:10AAB0000720FEF753BD00210C20FEF74FFD206953
+:10AAC00090F8901041F0010180F8901070BDB0F83E
+:10AAD0009C11A0F84010B0F89E11A0F84210B0F8F8
+:10AAE000A011A0F84410B0F8A211A0F8461080F808
+:10AAF0009A5190F8660010F0200F13D0FFF736FE41
+:10AB0000FFF704FE01211520FEF728FD206990F8CB
+:10AB1000661021F0200141F0100100E008E080F80B
+:10AB2000661070BDBDE8704000211420FEF716BD10
+:10AB300090F8652001230B21583001F046FFF8B949
+:10AB4000206990F85400012808BF012508D0022888
+:10AB500008BF022504D0042816BF08280325FFDFFC
+:10AB6000206990F85500012808BF01260BD0022863
+:10AB700008BF022607D0042814BF0828032600E0D7
+:10AB80004DE018BFFFDFD4F810C0012D9CF8A601DE
+:10AB900006D0022D07D0032D08BF042805D014E0ED
+:10ABA000012812D101E002280FD19CF8A701012E43
+:10ABB00006D0022E07D0032E08BF04280FD004E0D1
+:10ABC000012802D10BE0022809D09CF8652001235E
+:10ABD00003210CF1580001F0F8FE00BB16E0BCF8B0
+:10ABE00058309CF85410BCF8A8010CF5C77202F05C
+:10ABF000A1F938B12169252081F8640070BD0000F9
+:10AC0000F00000200020FDF7A7FF08E020690123E5
+:10AC1000022190F86520583001F0D7FEB0B12069CC
+:10AC20000123002190F86420583001F0CEFE002866
+:10AC300008BF70BD206990F88401002808BF70BD6E
+:10AC40000021BDE87040FF20FEF788BCBDE87040E1
+:10AC500000211620FEF782BC30B5FB4C054620785B
+:10AC6000002818BFFFDF657230BDF7490120087268
+:10AC700070472DE9F14FF54F39464D68284695F854
+:10AC8000551001F048FF95F8551080B211F00C0FE7
+:10AC90006FF00D0B7DD0B0F5747F38BF002006D368
+:10ACA0005038C11700EB91600BEBA01080B26E8E94
+:10ACB000864228BF0646E648DFF88C93C9F8240090
+:10ACC000786800F15808044609F13400678E40683E
+:10ACD00094F8551090F86AA0204601F01CFF94F8F3
+:10ACE000551080B211F00C0F69D0B0F5747F38BFE9
+:10ACF000002406D35038C21700EB92600BEBA01073
+:10AD000084B2A74238BF3C46BAF1000F1CBF201DD9
+:10AD100084B2E0B2F9F7E8FE98F81200002859D0A2
+:10AD200008F15801CA4891E80E1000F5027484E851
+:10AD30000E10D8F86810C0F82112D8F86C10C0F8BE
+:10AD4000251200F58170FAF711FAC0480078002842
+:10AD50000CBF0120002080F00101BE480176D8E937
+:10AD60001412C0E90412A0F58372D9F82410F9F77F
+:10AD700060FD95F85500012808BF00220ED002287A
+:10AD800008BF01220AD0042808BF032206D00828E1
+:10AD900000E008E01ABFFFDF00220222F1B201202A
+:10ADA000F9F762FD1CE0022919BF0BEBD00080B25D
+:10ADB0006FF00E0101EB90007FF479AF76E7022986
+:10ADC00019BF0BEBD00084B26FF00E0202EB9000C3
+:10ADD00097D195E7D9F82400FAF7C8F9F9F767FD94
+:10ADE000009850B195F82C00012808BFFAF791FAA5
+:10ADF000022089F80000BDE8F88F012295F855304F
+:10AE000096211046FAF791F895F8550095F85610E6
+:10AE100010F00C0F08BF00219620FAF7C2F9E1E705
+:10AE20002DE9F04FDFF8248283B0414681464D681A
+:10AE3000A1F11400009095F85D0005F15806012776
+:10AE4000A1F1340470B3012878D0022877D0032808
+:10AE500018BFFFDF74D0206A0823017821F00801B1
+:10AE60000170B27903EAC202114321F004010170BA
+:10AE7000F279042303EA8202114321F010010170E8
+:10AE800096F805B0E06AF5F7B0FA8246FAF7A2FD47
+:10AE9000BBF1020F79D0BBF1010F77D0BBF1030FEB
+:10AEA00075D089E000F0CAFB0146284601F044FE57
+:10AEB0001FFA80FB00F0C2FB10F00C0F6FF00D01C9
+:10AEC0004FF0000A20D0BBF5747F38BF504607D33F
+:10AED000ABF15000C21700EB926001EBA01080B202
+:10AEE000298E814238BF0846ADF80800A5F8480011
+:10AEF0000098FAF74EFD90B1216AA77062694FF48D
+:10AF00008060904703202CE0022819BF01EBDB0092
+:10AF100080B26FF00E0000EB9B00E1D1DFE701AAE9
+:10AF200002A9E06AF5F79CF9206210B196F8351095
+:10AF300039B10098FAF701FD77718CE713E016E05C
+:10AF400026E09DF8041031B9A0F800A080F802A016
+:10AF5000012102F0C7FABDF80810206A02F001FCD6
+:10AF60000220707177E70098FAF7E7FC73E7B5F80D
+:10AF70004800ADF8000001AA6946E06AF5F770F9EB
+:10AF80002062002808BFFFDF65E708E00BE00EE065
+:10AF90000098FAF7FEFC002808BFFFDF5BE730EA05
+:10AFA0000A0009D106E030EA0A0005D102E0BAF150
+:10AFB000000F01D0012100E00021206A027842EA5E
+:10AFC00001110170717C00291CBF7179012943D0E6
+:10AFD00006F158011E4891E80E1000F5027A8AE841
+:10AFE0000E10B16EC0F82112F16EC0F8251200F5F6
+:10AFF0008170FAF7BBF898F8000000280CBF012117
+:10B00000002114480176D6E91212C0E90412A0F515
+:10B010008371226AF9F70DFC95F85400012808BFE6
+:10B0200000220CD0022808BF012208D0042808BF43
+:10B03000032204D008281ABFFFDF00220222FB21CE
+:10B040000020F9F711FC0BE014010020480100205A
+:10B05000C80C0020D00E0020FAF788F8F9F727FC7A
+:10B06000B9F1000F06D195F8543001229621002045
+:10B07000F9F75BFF6771206A0188E18180782074AD
+:10B08000277003B0BDE8F08F2DE9F0471C46174646
+:10B0900081460D46FE4EDDF82080307828B9002F1D
+:10B0A0001CBF002CB8F1000F00D1FFDFC6F81C80D8
+:10B0B000C6E90574C6E90D9500243472F471347143
+:10B0C000F4707471B471B470B481F24F05F1580822
+:10B0D0002888F5F70DFFF0622888F5F7F7FE306352
+:10B0E000F9F725FD95F95700F9F7B1FD05F11200C3
+:10B0F000FAF725F805F10E00F9F7B3FD38780028C6
+:10B100000CBF03200120FAF72EF898F81A00F9F77F
+:10B11000B0FDFAF722F83878002804BFFF2095F830
+:10B12000545023D098F81260B5F8328095F8551035
+:10B13000284601F0F0FC95F8555080B215F00C0F40
+:10B140006FF00D0126D0B0F5747F06D35038C217CA
+:10B1500000EB926001EBA01084B24046A04528BFEE
+:10B160002046002E1CBF001D80B2C0B22946F9F750
+:10B17000BBFC38782A464FF00001B0B10120F9F746
+:10B18000A2FE7868D0F8E000F9F7F3FFBDE8F047D9
+:10B1900001206EE5022D19BF01EBD00084B26FF0E3
+:10B1A0000E0101EB9000D8D1D6E70020F9F78BFE15
+:10B1B000BDE8F047012033E6B64800B501783438E1
+:10B1C000007819B1022818BFFFDF00BD012818BFA1
+:10B1D000FFDF00BDAE4810B50078022818BFFFDFC2
+:10B1E000BDE8104000F0CCBA00F0CABAA8484079D7
+:10B1F0007047A74800797047A549012088717047BA
+:10B200002DE9F0470600A348A14D406800F158041D
+:10B21000686A90F8019018BF012E03D1296B09F0DC
+:10B22000BBF96870687800274FF00108A0B10128C9
+:10B230003CD0022860D003281CBFFFDFBDE8F087A8
+:10B24000012E08BFBDE8F087286BF5F7C3FA687ACE
+:10B25000BDE8F047F0F7CEBD012E14D0A86A002853
+:10B2600008BFFFDF6889C21CD5E9091009F072FC2C
+:10B27000A86A686201224946286BF5F727F9022E71
+:10B2800008BFBDE8F087D4E91401401C41F100017A
+:10B29000C4E91401E079012801D1E77101E084F8E3
+:10B2A0000780687ABDE8F047F0F7A4BD012E14D0FE
+:10B2B000A86A002808BFFFDF6889C21CD5E9091009
+:10B2C00009F048FCA86A686200224946286BF5F735
+:10B2D000FDF8022E08BFBDE8F087D4E91410491C20
+:10B2E00040F10000C4E91410E07901280CBFE771B7
+:10B2F00084F80780BDE8F087012E06D0286BF5F7AB
+:10B3000069FA022E08BFBDE8F087D4E91410491C81
+:10B3100040F10000C4E91410E0790128BFD1BCE776
+:10B320002DE9F0415B4F3846A7F13404406800F145
+:10B3300058052078012818BFFFDFA878012648B1FA
+:10B340000021A970A670626904209047387800280F
+:10B3500018BF2E71206A0321007831EA000004BF73
+:10B36000E878002805D1EE70216AA6706269022093
+:10B3700090470121002000F022FA18B1BDE8F04109
+:10B3800000F0FEB9BDE8F041002072E42DE9F14F74
+:10B39000404E4FF000083046A6F134054068317841
+:10B3A00000F1580A2878C146022818BFFFDFA88993
+:10B3B00040F40070A88171683078FF2091F8541033
+:10B3C000F9F792FB009800289AF8120000F0FD802F
+:10B3D000F9F792FAF9F780FA012788B99AF812007A
+:10B3E00070B1686A417859B100789AF80710C0F3D3
+:10B3F000C000884204D1EF70BDE8F84F00F0C0B93A
+:10B40000686A41786981002908BFC5F8288003D09F
+:10B41000286BF5F715F8A862A88940F02000A881EC
+:10B4200085F804803078706800F1580B044690F875
+:10B430002C0001281AD1F9F762FF5946204601F085
+:10B4400080FA98B13078002870680CBF00F58A70D7
+:10B4500000F5F570218841809BF8081001719BF878
+:10B46000091041710770687AF0F7C4FC686A9AF8AD
+:10B4700006100078C0F3800088423BD030787068B6
+:10B4800000F1580490F85D0080B302284CD003E02E
+:10B49000140100204801002084F80580307800283D
+:10B4A0001CBF2079002806D084F80480AF706A6938
+:10B4B000414610209047E07890B184F80380FAF775
+:10B4C00077FA002808BFFFDF0820AF706A69002103
+:10B4D0009047D4E91202411C42F10000C4E9121065
+:10B4E000A07901280CBF84F80680A771A88940F4D0
+:10B4F0008070A881686A9AF807300178C1F3C002A9
+:10B500009A424FD13278726801F0030102F1580477
+:10B51000012918BF022932D003291CBFE87940F065
+:10B52000040012D0E8713DE0E86AF4F7C5FE002897
+:10B5300008BFFFDFD4E91210491C40F10000C4E944
+:10B540001210687AF0F756FCA1E701F0E3FF90B122
+:10B55000A770A989384641F40061A981696AAF7072
+:10B560006A699047E079012803D100BF84F8078019
+:10B5700018E0E77116E0E87940F01000D2E7407873
+:10B58000F8B1A98941F40061A981A96A51B1FB28E8
+:10B59000F1D8287A002808BFB94603D080206A690C
+:10B5A000002190470120009900F009F9B0B1B9F1EC
+:10B5B000000F1CBF0020FFF723FEBDE8F84F00F08E
+:10B5C000DFB8E0790128D4D1D0E7002818BFF9F717
+:10B5D000CCF9A88940F04000A881E3E7B9F1000F59
+:10B5E0001CBF0120FFF70CFE0020FFF719FCB9F18A
+:10B5F000000F08BFBDE8F88F0220BDE8F84FFFE557
+:10B6000070B50D4606468E488D4900784C6850B19D
+:10B61000F9F7FEF9034694F8542029463046BDE870
+:10B620007040FDF7EAB9F9F7F3F9034694F85420AE
+:10B6300029463046BDE8704005F088BF804830B4E8
+:10B6400090F800C04268406802F1580192F86450D6
+:10B6500090F85400242D1CBF4B7B242B24D00821B0
+:10B6600001241F2D18BF202D47D0222B1CBF30BC1A
+:10B67000704700BFBCF1000F04BF30BC704792F8A8
+:10B68000A63192F851201A4012F0040F5FD008281A
+:10B6900018BF04286ED0082918BF04296AD00128D1
+:10B6A00018BF012969D062E0BCF1000F12D092F8F6
+:10B6B0009011002904BF30BC7047082818BF042827
+:10B6C00058D0082918BF042954D0012818BF0129CF
+:10B6D00053D04CE092F8F210002904BF30BC704700
+:10B6E000082818BF042845D0082918BF042941D0CC
+:10B6F000012818BF012940D039E0222BBAD0BCF173
+:10B70000000F04BF30BC704792F8A62112F0040F5E
+:10B710000CD0082818BF04282CD0082918BF0429E9
+:10B7200028D0012818BF012927D020E012F0010FEE
+:10B7300018BF2146EDD112F0020F04BF30BC704794
+:10B74000082818BF042815D0012816D00FE012F0E1
+:10B75000010F18BF21469AD112F0020F04BF30BC6E
+:10B760007047082818BF042804D0012805D030BC31
+:10B770000220704730BC0820704730BC0120704761
+:10B780002F4910B54C68F9F799FDF9F74DFDF9F718
+:10B790007DFCF9F7DAFCF9F78AF894F82C00012817
+:10B7A00008BFF9F7ACFD274C00216269A0899047DA
+:10B7B000E269E179E07890470020207010BD70B513
+:10B7C000204C0546002908BF012D05D12079401CD9
+:10B7D000C0B22071012831D8A169284688470028C5
+:10B7E0002CD0A179184839B1012D01BF4178002929
+:10B7F000017811F0100F21D0E179F9B910490978D9
+:10B80000002908BF012D05D000290CBF012100210E
+:10B81000294311D10D49097811F0100F04BF0078A8
+:10B8200010F0100F0AD0A07840B9A06A20B9608942
+:10B8300010B111F0100F01D0002070BD012070BDBB
+:10B840004801002014010020C80C00202201002023
+:10B8500010B540F2C311F74809F0FBF9FF220821A7
+:10B86000F54809F0EEF9F548002141704FF4617197
+:10B87000418010BD2DE9F0410E46054600F046FB23
+:10B88000EC4C102816D004EBC00191F84A0110F0DE
+:10B89000010F1CBF0120BDE8F081607808283CBF83
+:10B8A000012081F84A011CD26078401C60700120A0
+:10B8B000BDE8F0816078082813D222780127501C57
+:10B8C000207004EBC2083068C8F84401B088A8F8BA
+:10B8D0004801102A28BFFFDF88F8435188F84A71D1
+:10B8E000E2E70020BDE8F081D2480178491E4BB262
+:10B8F000002BB8BF704770B45FF0000500EBC301C8
+:10B9000091F84A1111F0010F3BD04278D9B2521E82
+:10B91000427000EBC10282F84A5190F802C0002246
+:10B92000BCF1000F0BD9841894F803618E4202D148
+:10B93000102A26D103E0521CD2B29445F3D80278E3
+:10B94000521ED2B202708A421BD000EBC20200EB40
+:10B95000C10CD2F84341CCF84341D2F84721CCF88E
+:10B960004721847890F800C00022002C09D986185D
+:10B9700096F8036166450AD1102A1CBF024482F87A
+:10B980000311591E4BB2002BB8DA70BC7047521C21
+:10B99000D2B29442EBD8F4E72DE9F05F1F4690460F
+:10B9A0000E46814600F0B2FAA24D0446102830D06F
+:10B9B000A878002100280ED96A1892F80331A34212
+:10B9C00005D110291CBF1220BDE8F09F03E0491CDF
+:10B9D000C9B28842F0D8082834D2102C1CD0AE78D6
+:10B9E0001022701CA87005EB061909F103004146EE
+:10B9F00000F056FF09F183001022394600F050FF95
+:10BA0000A819002180F8034180F83B110846BDE8E1
+:10BA1000F09FA878082815D22C78CA46601C287098
+:10BA200005EBC4093068C9F84401B0884FF0000B39
+:10BA3000A9F84801102C28BFFFDF89F843A189F835
+:10BA40004AB1CCE70720BDE8F09F70B4794881780F
+:10BA5000491E4BB2002BBCBF70BC704703F0FF0CFB
+:10BA60008178491ECAB2827050FA83F191F80311AD
+:10BA700094453ED000EB021500EB0C14D5F80360A2
+:10BA8000C4F80360D5F80760C4F80760D5F80B6008
+:10BA9000C4F80B60D5F80F60C4F80F60D5F8836068
+:10BAA000C4F88360D5F88760C4F88760D5F88B60E8
+:10BAB000C4F88B60D5F88F50C4F88F50851800EB10
+:10BAC0000C0402EB420295F803610CEB4C0C00EB0A
+:10BAD000420284F8036100EB4C0CD2F80B61CCF805
+:10BAE0000B61B2F80F21ACF80F2195F83B2184F8D7
+:10BAF0003B2100EBC10292F84A2112F0010F33D131
+:10BB000090F802C00022BCF1000F0BD9841894F801
+:10BB100003518D4202D1102A26D103E0521CD2B229
+:10BB20009445F3D80278521ED2B202708A421BD0DA
+:10BB300000EBC20200EBC10CD2F84341CCF8434108
+:10BB4000D2F84721CCF84721847890F800C0002231
+:10BB5000002C09D9851895F8035165450BD1102A99
+:10BB60001CBF024482F80311591E4BB2002BBFF6D2
+:10BB700075AF70BC7047521CD2B29442EAD8F3E75A
+:10BB80002E49487070472D484078704738B14AF2C6
+:10BB9000B811884203D82949488001207047002005
+:10BBA000704726484088704710B500F0AFF910285C
+:10BBB00014D0204A0146002092F802C0BCF1000FC8
+:10BBC0000CD9131893F803318B4203D1102818BFF6
+:10BBD00010BD03E0401CC0B28445F2D8082010BD5F
+:10BBE00014498A78824286BF01EB0010833000201E
+:10BBF000704710498A78824286BF01EB0010C01C52
+:10BC0000002070470B4B93F802C084459CBF002076
+:10BC10007047184490F8030103EBC00090F84331DB
+:10BC20000B70D0F844111160B0F8480190800120E9
+:10BC300070470000F80E00205A010020500100203B
+:10BC4000FE4A114491F80321FD490A7002684A60D6
+:10BC500080880881704710B5F8F79AFD002804BF66
+:10BC6000FF2010BDBDE81040F8F7B8BDF3498A7851
+:10BC700082429CBF00207047084490F8030101EB0A
+:10BC8000C00090F84A0100F0010070472DE9F0472C
+:10BC9000EA4F0026B0463878002886BF4FF0080AE1
+:10BCA000DFF8A093BDE8F08707EBC80505F5A271A2
+:10BCB00095F8430100F02AF9102808BF544610D027
+:10BCC000B978002400290BD93A1992F8032182424D
+:10BCD00002D1102C05D103E0621CD4B2A142F3D8EA
+:10BCE0000824B878A04286BF07EB0410C01C0020CF
+:10BCF00095F84A1111F0010F16D050B1082C04D25A
+:10BD0000391991F83B11012903D0102100F0A5FD4C
+:10BD100050B109F806403046731C95F8432105F5EB
+:10BD2000A271DEB2F8F76BFF08F1010000F0FF0826
+:10BD300038784045B8D8BDE8F0872DE9F041BF4CD0
+:10BD400000263546A07800288CBFBE4FBDE8F081A4
+:10BD50006119C0B291F80381A84286BF04EB0510B7
+:10BD6000C01C002091F83B11012903D0102100F0E4
+:10BD700074FD58B104EBC800BD5590F8432100F59F
+:10BD8000A2713046731CDEB2F8F739FF681CC5B2E9
+:10BD9000A078A842DCD8BDE8F08110B5F8F759FFCB
+:10BDA000002804BF082010BDF8F757FFA549085C1C
+:10BDB00010BD0A46A24910B5497841B19F4B997808
+:10BDC00029B10244D81CF8F780FC012010BD0020E6
+:10BDD00010BD9A4A01EB410102EB41010268C1F832
+:10BDE0000B218088A1F80F0170472DE9F041934D98
+:10BDF00007460024A878002898BFBDE8F081C0B2AB
+:10BE0000A04213D905EB041010F183060ED01021C7
+:10BE1000304600F022FD48B904EB440005EB400039
+:10BE200000F20B113A463046F9F751FE601CC4B2DD
+:10BE3000A878A042E3D8BDE8F081014610228248EC
+:10BE400000F02EBD8048704770B57C4D0446A87840
+:10BE5000A04206D905EB04101021833000F0FDFC50
+:10BE600008B1002070BD04EB440005EB400000F277
+:10BE70000B1070BD71498A78824206D9084490F847
+:10BE80003B01002804BF01207047002070472DE9C6
+:10BE9000F0410E46074615460621304600F0DDFC0F
+:10BEA000664C98B1A17871B104F59D7011F0010F45
+:10BEB00018BF00F8015FA178490804D0457000F868
+:10BEC000025F491EFAD10120BDE8F08138463146B3
+:10BED00000F01CF8102816D0A3780021002B12D9EE
+:10BEE000621892F80321824209D1102918BF08294B
+:10BEF00009D0601880F83B510120BDE8F081491C51
+:10BF0000C9B28B42ECD80020BDE8F0812DE9F041A8
+:10BF10004A4D0646002428780F46002812D900BF53
+:10BF200005EBC40090F84311B14206D10622394610
+:10BF300000F5A27008F0E2FD38B1601CC4B22878A8
+:10BF4000A042EDD81020BDE8F0812046BDE8F08188
+:10BF50003A4910B44A7801EBC003521E4A700022DD
+:10BF600083F84A2191F802C0BCF1000F0DD98B185B
+:10BF700093F80341844204D1102A1CBF10BC7047BF
+:10BF800003E0521CD2B29445F1D80A78521ED2B2C4
+:10BF90000A70824204BF10BC704701EBC00301EB82
+:10BFA000C202D2F843C1C3F843C1D2F84721C3F853
+:10BFB00047218C7891F800C00022002C9CBF10BC57
+:10BFC00070478B1893F80331634506D1102A1CBFC4
+:10BFD000114481F8030110BC7047521CD2B2944244
+:10BFE000EFD810BC704770B414490D188A78521EEF
+:10BFF000D3B28B7095F80321984247D001EB031C14
+:10C0000001EB0014DCF80360C4F80360DCF807609F
+:10C01000C4F80760DCF80B60C4F80B60DCF80F6054
+:10C02000C4F80F60DCF88360C4F88360DCF88760D4
+:10C03000C4F88760DCF88B6008E00000F80E002090
+:10C04000500100205A010020BB100020C4F88B6072
+:10C05000DCF88FC0C4F88FC001EB030C03EB430383
+:10C060009CF8034100EB400001EB430385F80341DA
+:10C0700001EB4000D3F80B41C0F80B41B3F80F318E
+:10C08000A0F80F319CF83B0185F83B0101EBC200A1
+:10C0900090F84A0110F0010F1CBF70BC70470020DF
+:10C0A0008C78002C0DD90B1893F803C1944504D15A
+:10C0B00010281CBF70BC704703E0401CC0B2844213
+:10C0C000F1D80878401EC0B20870904204BF70BC1E
+:10C0D000704701EBC20301EBC000D0F843C1C3F8C5
+:10C0E00043C1D0F84701C3F847018C780B78002092
+:10C0F000002C9CBF70BC704701EB000C9CF803C186
+:10C100009C4506D110281CBF084480F8032170BC50
+:10C110007047401CC0B28442EED870BC704700002B
+:10C1200010B50A7B02F01F020A73002202768B18F8
+:10C130001B7A03F0010C5B0803F00104A4445B08C4
+:10C1400003F00104A4445B0803F00104A4445B0869
+:10C1500003F0010464444FEA530C0CF00103234440
+:10C160004FEA5C0C0CF00104234403EB5C0300EB8E
+:10C17000020C521C8CF8133090F818C0D2B26344F1
+:10C180000376052AD3D3D8B2252888BFFFDF10BD98
+:10C190000023C383428401EBC202521EB2FBF1F1C1
+:10C1A0000184704770B50025044603290DD04FF473
+:10C1B000FA4200297BD0012978D0022918BF70BD2E
+:10C1C0000146BDE870405830AAE704F158067821CE
+:10C1D000304608F060FDB571F57135737573F57310
+:10C1E000357475717576B576212086F83E0041204C
+:10C1F00086F83F00FE2086F8730084F82C502584D2
+:10C20000012084F8540084F85500282184F8561041
+:10C210001B21218761874FF4A471E187A1871B212E
+:10C22000218661864FF4A471E186A1861B21A4F8C2
+:10C230004010A4F844104FF4A471A4F84610A4F8D8
+:10C2400042101B21A4F84A10A4F84C10A4F848107E
+:10C2500060734FF448606080A4F8D050A4F8D250C6
+:10C26000A4F8D450A4F8D650A4F8D850A4F8DA50C2
+:10C2700084F8DD5084F8DF50A4F8E65084F8E450E8
+:10C28000A4F8F850A4F8FA5084F89A5184F89B5115
+:10C2900084F8A45184F8A55184F8685184F8705149
+:10C2A00084F8735184F88C5170BD00E041E0A4F82B
+:10C2B000E65084F8DE506088FE490144B1FBF0F19D
+:10C2C000A4F878104BF68031A4F87A10E388A4F82B
+:10C2D0007E50B4F882C0DB000CFB00FCB3FBF0F333
+:10C2E0009CFBF0FC5B1CA4F882C09BB203FB00FC2F
+:10C2F00004F15801A4F88030BCF5C84FC4BF5B1EE0
+:10C300000B85B2FBF0F2521CCA8500F5802202F5C3
+:10C31000EE32531EB3FBF0F20A84CB8B03FB00F228
+:10C32000B2FBF0F0C883214604F15800BDE870402C
+:10C33000F6E6A4F8E650B4F89411B4F89831B4F8DD
+:10C3400002C004F15800A4F87E50B4F88240DB002B
+:10C3500004FB0CF4B3FBF1F394FBF1F45B1C448598
+:10C360009BB203FB01F40385B4F5C84FC4BF5B1E49
+:10C370000385B2FBF1F2521CC285428C01EBC20272
+:10C38000521EB2FBF1F20284C28B02FB0CF2B2FB32
+:10C39000F1F1C18370BD70B50025044603290DD0AD
+:10C3A0004FF4FA42002963D001297DD0022918BF39
+:10C3B00070BD0146BDE870405830B1E604F1580642
+:10C3C0007821304608F067FCB571F57135737573E7
+:10C3D000F573357475717576B576212086F83E0053
+:10C3E000412086F83F00FE2086F8730084F82C5028
+:10C3F0002584012084F8540084F85500282184F80D
+:10C4000056101B21218761874FF4A471E187A18712
+:10C410001B21218661864FF4A471E186A1861B2130
+:10C42000A4F84010A4F844104FF4A471A4F84610E6
+:10C43000A4F842101B21A4F84A10A4F84C10A4F848
+:10C4400048106073A4F8D850202084F8DA0084F8EB
+:10C45000D050C4F8D45084F8045184F8055184F8BD
+:10C460000E5184F80F5184F8F45084F8005170BDD7
+:10C47000608890490144B1FBF0F1A4F878104BF6C4
+:10C480008031A4F87A10E388A4F87E50B4F882C012
+:10C49000DB000CFB00FC9CFBF0FCB3FBF0F304F1B5
+:10C4A0005801A4F882C000E022E05B1C9BB203FBB1
+:10C4B00000FCA4F88030BCF5C84FC4BF5B1E0B85E0
+:10C4C000B2FBF0F2521CCA8500F5802202F5EE3272
+:10C4D000531EB3FBF0F20A84CB8B03FB00F2B2FBDA
+:10C4E000F0F0C883214604F15800BDE8704017E61B
+:10C4F000D4F8F830B4F802C004F158005989DB8947
+:10C50000A4F87E50B4F88240DB0004FB0CF4B3FBCB
+:10C51000F1F394FBF1F45B1C44859BB203FB01F443
+:10C520000385B4F5C84FC4BF5B1E0385B2FBF1F2AF
+:10C53000521CC285428C01EBC202521EB2FBF1F2C8
+:10C540000284C28B02FB0CF2B2FBF1F1C18370BD1D
+:10C550002DE9F003047E0CB1252C03D9BDE8F003CE
+:10C5600012207047002A02BF0020BDE8F003704788
+:10C5700091F80DC01F2601234F4D4FF00008BCF16C
+:10C58000000F73D0BCF1010F1EBF1F20BDE8F003E8
+:10C590007047B0F800C00A7C8F7B91F80F907A400A
+:10C5A0004F7C87EA090742EA072282EA0C0C00273F
+:10C5B0000CF0FF094FEA1C2C99FAA9F99CFAACFC83
+:10C5C0004FEA19694FEA1C6C49EA0C2C0CEB0C1C65
+:10C5D0007F1C9444FFB21FFA8CFC032FE8D38CEA33
+:10C5E000020C354F0022ECFB057212096FF0240596
+:10C5F00002FB05C2D2B201EBD207427602F0070578
+:10C600003F7A03FA05F52F4218BF82767ED104FBEC
+:10C610000CF2120C521CD2B25FF0000400EB040CBE
+:10C620009CF813C094453CBFA2EB0C02D2B212D3CB
+:10C630000D194FF0000C2D7A03FA0CF73D421CBF88
+:10C64000521ED2B2002A71D00CF1010C0CF0FF0C7A
+:10C65000BCF1080FF0D304F1010C0CF0FF04052C21
+:10C66000DCD33046BDE8F0037047FFE790F819C00F
+:10C670000C7E474604FB02C20F4C4FF0000CE2FB5D
+:10C68000054C4FEA1C1C6FF024040CFB0422D2B2B0
+:10C6900001EBD204427602F0070C247A03FA0CFC78
+:10C6A00014EA0C0F1FBF82764046BDE8F0037047C6
+:10C6B00004E00000FFDB050053E4B36E90F818C0FF
+:10C6C000B2FBFCF40CFB1422521CD2B25FF000044B
+:10C6D00000EB040C9CF813C094453CBFA2EB0C0289
+:10C6E000D2B212D30D194FF0000C2D7A03FA0CF8C8
+:10C6F00015EA080F1CBF521ED2B27AB10CF1010C20
+:10C700000CF0FF0CBCF1080FF0D300E011E004F1D5
+:10C71000010C0CF0FF04052CDAD3A2E70CEBC401EA
+:10C7200081763846BDE8F0037047FFE70CEBC401A3
+:10C7300081764046BDE8F0037047FC4A0168126804
+:10C740001140FB4A126811430160704730B4F94947
+:10C75000F64B00244FF0010C0A78521CD2B20A703A
+:10C76000202A08BF0C700D781A680CFA05F52A42C9
+:10C77000F2D0097802680CFA01F15140016030BC36
+:10C78000704770B46FF01F02010C02EA90251F235E
+:10C79000A1F5AA4054381CBFA1F5AA40B0F155003C
+:10C7A00009D0A1F52850AA381EBFA1F52A40B0F142
+:10C7B000AA00012000D100204FF0000C6246644620
+:10C7C0008CEA0106F6431643B6F1FF3F11D005F09F
+:10C7D00001064FEA5C0C4CEAC63C03F00106520825
+:10C7E0006D085B08641C42EAC632162CE8D370BCA4
+:10C7F000704770BC00207047017931F01F0113BFF2
+:10C80000002000221146704710B4435C491C03F01D
+:10C81000010C5B0803F00104A4445B0803F001046D
+:10C82000A4445B0803F00104A4445B0803F0010482
+:10C83000A4445B0803F001045B08A44403F0010472
+:10C84000A4440CEB53031A44D2B20529DDDB012AC0
+:10C850008CBF0120002010BC704730B40022A1F131
+:10C86000010CBCF1000F11DD431E11F0010F08BFD8
+:10C8700013F8012F5C785FEA6C0C07D013F8025FA5
+:10C8800022435C782A43BCF1010CF7D1491E5CBFFE
+:10C89000405C0243002A0CBF0120002030BC7047DE
+:10C8A000130008BF704710B401EB030CD41A1CF836
+:10C8B00001CC5B1E00F804C013F0FF03F4D110BCE0
+:10C8C0007047F0B58DB0164610251C466A46AC463A
+:10C8D00000EB0C03A5EB0C0713F8013CD355ACF1AE
+:10C8E000010313F0FF0CF3D11546103210208446DB
+:10C8F0000B18ACEB000713F8013C401ED35510F0A9
+:10C90000FF00F5D1284606F0F3FF86B1102005F1AF
+:10C91000200201461318A1EB000C13F8013C401E45
+:10C9200004F80C3010F0FF00F4D10DB0F0BD089801
+:10C930002060099860600A98A0600B98E0600DB0D4
+:10C94000F0BD38B505460C466846F8F7EDFC002802
+:10C9500008BF38BD9DF900202272A07E607294F954
+:10C960000A100020511A48BF494295F82D308B42D9
+:10C97000C8BF38BDFF2B08BF38BDE17A491CC9B21A
+:10C98000E17295F82E30994203D8A17A7F2918BF19
+:10C9900038BDA2720020E072012038BD0C2818BFFB
+:10C9A0000B2810D00D2818BF1F280CD0202818BF26
+:10C9B000212808D0222818BF232804D024281EBFED
+:10C9C000262800207047012070470C2963D2DFE839
+:10C9D00001F006090E13161B323C415C484E002A3A
+:10C9E0005BD058E0072A18BF082A56D053E00C2A1B
+:10C9F00018BF0B2A51D04EE00D2A4ED04BE0A2F1C9
+:10CA00000F000C2849D946E023B1A2F110000B28F1
+:10CA100043D940E0122A18BF112A3ED090F83600C0
+:10CA200020B1122A37D31A2A37D934E0162A32D342
+:10CA30001A2A32D92FE0A2F10F0103292DD990F83B
+:10CA4000360008B31B2A28D925E0002B08BF042A8A
+:10CA500021D122E013B1062A1FD01CE0012A1AD1ED
+:10CA60001BE01C2A1CBF1D2A1E2A16D013E01F2AF9
+:10CA700018BF202A11D0212A18BF222A0DD0232A1C
+:10CA80001CBF242A262A08D005E013B10E2A04D0A0
+:10CA900001E0052A01D000207047012070472DE9F0
+:10CAA000F04187680D4604462046F6F7DAFB98B158
+:10CAB000D5B13846A168F6F715FF002814DD2844E3
+:10CAC000401EB0FBF5F606FB05F13846F5F705FF0D
+:10CAD000A0603046BDE8F081F6F7F6F940F2337118
+:10CAE000F5F7FBFEA060DFE70020BDE8F081904293
+:10CAF00028BF704770B50446101B642838BF6420F7
+:10CB000025188D4205D8F6F720FF00281CBF2846BF
+:10CB100070BD204670BDC08E11F00C0F08BF70476D
+:10CB2000B0F5296F38BF4FF42960704748520200B2
+:10CB30004C520200620100200246808E11F00C0F60
+:10CB400008BF704792F85530D18E13F00C0F04D007
+:10CB5000B1F5296F38BF4FF42961538840F2E24C98
+:10CB600003FB0CF3528E4FF4747C0CEB821C8C454F
+:10CB70009CBF910101F57471591AA1F59671884213
+:10CB800028BF0846B0F5296F38BF4FF429607047B9
+:10CB9000084418449830002A14BF04210021084496
+:10CBA0007047F0B4002A14BF08220122002B14BFE2
+:10CBB0000824012412F00C0F8B8ECA8E25D091F818
+:10CBC0005550944615F00C0F04D0BCF5296F38BFB2
+:10CBD0004FF4296C4D8840F2E2466E434D8E4FF47F
+:10CBE000747707EB851767459CBF4FEA851C0CF5EA
+:10CBF000747CA6EB0C0CACF5967C634528BF6346B1
+:10CC0000B3F5296F38BF4FF4296314F00C0F04D02B
+:10CC1000B2F5296F38BF4FF429621FFA83FC002850
+:10CC20000CBF0123002391F8560014F00C0F08BF2D
+:10CC300000200CEB020108449830002B14BF0421A3
+:10CC400000210844F0BC70472DE9F00391F854200E
+:10CC50000B8E12F00C0F4FF474771CBF07EB83138D
+:10CC60009CB255D012F00C0F8B8ECA8E4D8E91F85F
+:10CC700055C021D016461CF00C0F04D0B6F5296F14
+:10CC800038BF4FF42966B1F8028040F2E24908FB50
+:10CC900009F807EB8519B14502D8AE0106F574769F
+:10CCA000A8EB0606A6F59676B34228BF3346B3F541
+:10CCB000296F38BF4FF42963A34228BF23469CB293
+:10CCC0001CF00C0F1CBF07EB85139BB228D000BFD4
+:10CCD0001CF00C0F04D0B2F5296F38BF4FF4296255
+:10CCE0009A4228BF1A4600280CBF0123002391F85E
+:10CCF00056001CF00C0F08BF0020A1180844983003
+:10CD0000002B14BF042100210844BDE8F003704744
+:10CD1000022A07BF9B003C33DB0070339CB2A1E7C3
+:10CD2000BCF1020F07BFAB003C33EB0070339BB28A
+:10CD3000CEE710F0010F1CBF0120704710F0020F6A
+:10CD40001CBF0220704710F0040018BF0820704775
+:10CD50002DE9F0470446174689464FF0010808467A
+:10CD600000F0D1FC0546484600F0D1FC10F0010F60
+:10CD700018BF012625D000BF15F0010F18BF0123F1
+:10CD80002AD000BF56EA030108BF4FF0000810F098
+:10CD9000070F08BF002615F0070F08BF002394F8FF
+:10CDA0005400B0420CBF00203046387094F8551043
+:10CDB000994208BF00237B70002808BF002B25D1B3
+:10CDC00015E010F0020F18BF0226D5D110F0040FA5
+:10CDD00014BF08260026CFE715F0020F18BF022364
+:10CDE000D0D115F0040F14BF08230023CAE748462A
+:10CDF00000F093FCB4F85810401A00B247F6FE71E8
+:10CE0000884201DC002801DC4FF0000816B1082E32
+:10CE10000CD018E094F85400012818BF022812D052
+:10CE200004281EBF0828FFDF032D0CD194F8A401AD
+:10CE300048B1B4F8A801012894F8540006D0082895
+:10CE400001D0082038704046BDE8F087042818BF9C
+:10CE50000420F7D1F5E7012814BF0228704710F02D
+:10CE60000C0018BF0420704738B4CBB2C1F3072CB4
+:10CE7000C1B2C0F30724012B07D0022B09D0042B29
+:10CE800008BFBCF1040F2DD006E0BCF1010F03D1A7
+:10CE900028E0BCF1020F25D0012906D0022907D0D5
+:10CEA000042908BF042C1DD004E0012C02D119E094
+:10CEB000022C17D001EA0C0161F3070204EA030116
+:10CEC00061F30F22D1B211F0020F18BF022310D06C
+:10CED000C2F307218DF8003011F0020F18BF0221B4
+:10CEE0001BD111E0214003EA0C03194061F3070252
+:10CEF000E6E711F0010F18BF0123E9D111F0040F8B
+:10CF000014BF08230023E3E711F0010F18BF01212C
+:10CF100003D111F0040118BF08218DF80110082B6E
+:10CF200001BF000C012804208DF80000BDF80000AE
+:10CF300038BC70474FF0000C082902D0042909D0F2
+:10CF400011E001280FD10420907082F803C01380F3
+:10CF500001207047012806D00820907082F803C095
+:10CF600013800120704700207047162A10D12A2212
+:10CF70000C2818BF0D280FD04FF0230C1F280DD000
+:10CF800031B10878012818BF002805D0162805D02F
+:10CF900000207047012070471A70FBE783F800C03B
+:10CFA000F8E7012908D002290BD0042912BF08296B
+:10CFB00040F6A660704707E0002804BF40F2E24058
+:10CFC000704740F6C410704700B5FFDF40F2E24002
+:10CFD00000BD0000282107F03CBE4078704730B506
+:10CFE0000546007801F00F0220F00F001043287072
+:10CFF000092910D2DFE801F0050705070509050B2F
+:10D000000D00062409E00C2407E0222405E0012499
+:10D0100003E00E2401E00024FFDF6C7030BD0078D7
+:10D0200000F00F0070470A68C0F803208988A0F854
+:10D0300007107047D0F803200A60B0F80700888016
+:10D0400070470A68C0F809208988A0F80D10704759
+:10D05000D0F809200A60B0F80D0088807047027887
+:10D06000402322F0400203EA81111143017070470E
+:10D070000078C0F3801070470278802322F080028D
+:10D0800003EAC1111143017070470078C00970476D
+:10D09000027802F00F02072A16BF082AD0F80520EE
+:10D0A000D0F80320C1F809200CBFB0F80920B0F86F
+:10D0B0000720A1F80D200A7822F080020A7000787B
+:10D0C000800942EAC0100870704770B514460E46D9
+:10D0D00005461F2A88BFFFDF2246314605F10900B9
+:10D0E00007F038FDA01D687070BD70B544780E461D
+:10D0F0000546062C38BFFFDFA01F84B21F2C88BF57
+:10D100001F24224605F10901304607F023FD204681
+:10D1100070BD70B514460E4605461F2A88BFFFDF56
+:10D120002246314605F1090007F014FDA01D687084
+:10D1300070BD70B544780E460546062C38BFFFDF3B
+:10D14000A01F84B21F2C88BFFFDF224605F1090112
+:10D15000304607F0FFFC204670BD0968C0F80F108C
+:10D1600070470A88A0F8132089784175704790F8B5
+:10D17000242001F01F0122F01F02114380F8241027
+:10D180007047072988BF072190F82420E02322F068
+:10D19000E00203EA4111114380F8241070471F3068
+:10D1A00007F08EBE10B5044600F0E3FA002818BF61
+:10D1B000204410BDC17811F03F0F1BBF027912F05F
+:10D1C000010F0022012211F03F0F1BBF037913F062
+:10D1D000020F002301231A4402EB4202530011F014
+:10D1E0003F0F1BBF027912F0080F0022012203EB50
+:10D1F000420311F03F0F1BBF027912F0040F00220F
+:10D200000122134411F03F0F1BBF027912F0200FCF
+:10D210000022012202EBC20203EB420311F03F0F96
+:10D220001BBF027912F0100F0022012202EB420212
+:10D230001A4411F03F0F1BBF007910F0400F00207F
+:10D240000120104410F0FF0014BF01210021084408
+:10D25000C0B2704770B50278417802F00F02082A18
+:10D260004DD2DFE802F004080B4C4C4C0F14881F21
+:10D270001F280AD943E00C2907D040E0881F1F2847
+:10D2800003D93CE0881F1F2839D8012070BD4A1EF1
+:10D29000242A34D88446C07800258209032A09D07C
+:10D2A00000F03F04601C884204D86046FFF782FF0C
+:10D2B000A04201D9284670BD9CF803004FF001063A
+:10D2C00010F03F0F1EBF1CF10400007810F0100F8B
+:10D2D00013D064460421604600F04BFA002818BFC2
+:10D2E00014EB0000E6D0017801F03F012529E1D2DE
+:10D2F00080780221B1EB501FDCD3304670BD002096
+:10D3000070BDC078800970470178002201F00F03DA
+:10D310000121042B0BD0082B1CBF00207047437841
+:10D320000E2B04BFC3785FEA931C04D106E040785B
+:10D33000801F1F2800D911460846704713F03F0F81
+:10D340001EBF007910F0010F10F0020FF4D1F2E7C8
+:10D3500010B4017801F00F01032920D0052921D153
+:10D360004478B0F81910B0F81BC0B0F81730827DBF
+:10D37000222C17D1062915D3B1F5486F98BFBCF5FB
+:10D38000FA7F0FD272B1082A98BF8A420AD28B4222
+:10D390009CBFB0F81D00B0F5486F03D805E0407899
+:10D3A0000C2802D010BC0020704710BC0120704730
+:10D3B0002DE9F0411F4614460D00064608BFFFDF69
+:10D3C0002146304600F0D5F9040008BFFFDF3019D0
+:10D3D0003A462946BDE8F04107F0BCBBC07800F0F2
+:10D3E0003F007047C02202EA8111C27802F03F027A
+:10D3F0001143C1707047C9B201F00102C1F340038B
+:10D400001A4402EB4202C1F3800303EB4202C1F370
+:10D41000C00302EB4302C1F3001303EB43031A44BE
+:10D42000C1F3401303EBC30302EB4302C1F38013C8
+:10D430001A4412F0FF0202D0521CD2B20171C3781A
+:10D4400002F03F0103F0C0031943C170511C417049
+:10D4500070472DE9F0410546C078164600F03F04BC
+:10D46000C4F124000F46B042B8BFFFDF281932468E
+:10D470003946001D07F06EFBA019401C6870BDE81E
+:10D48000F0812DE9F04105464478C0780F4600F060
+:10D490003F06002C08BFFFDFA01B401E84B21F2CDC
+:10D4A00088BF1F242FB1A819011D2246384607F056
+:10D4B00051FB2046BDE8F0814078704700B5027806
+:10D4C00001F0030322F003021A430270012914BF82
+:10D4D0000229002104D0032916BFFFDF012100BD6E
+:10D4E000417000BD00B5027801F0030322F0030291
+:10D4F0001A430270012914BF0229002104D0032914
+:10D5000016BFFFDF012100BD417000BD007800F0B3
+:10D5100003007047417889B1C0780E2818BF0F28E2
+:10D5200003D0102818BF192802D3FB2904D905E01D
+:10D53000BF4A105C884201D101207047002070472B
+:10D5400030B501240546C17019293CBFB848445C78
+:10D5500002D3FF2918BFFFDF6C7030BD70B51546D0
+:10D560000E4604461B2A88BFFFDF65702A463146F7
+:10D57000E01CBDE8704007F0EDBAB0F80700704756
+:10D58000B0F809007047C172090A01737047B0F81A
+:10D590000B00704730B4B0F80720A64DB0F809C0B2
+:10D5A000B0F805300179941F2D1998BFBCF5FA7FAA
+:10D5B0000ED269B1082998BF914209D293429FBF08
+:10D5C000B0F80B00B0F5486F012030BC98BF704731
+:10D5D000002030BC7047001D07F072BC021D0846D9
+:10D5E000114607F06DBCB0F809007047007970472C
+:10D5F0000A68426049688160704742680A608068D2
+:10D600004860704709888181704780890880704729
+:10D610000A68C0F80E204968C0F812107047D0F8A8
+:10D620000E200A60D0F81200486070470968C0F800
+:10D6300016107047D0F81600086070470A684260FC
+:10D6400049688160704742680A6080684860704736
+:10D650000968C1607047C06808607047007970470A
+:10D660000A68426049688160704742680A60806861
+:10D67000486070470171090A417170478171090A58
+:10D68000C17170470172090A417270478172090ABB
+:10D69000C172704780887047C088704700897047A2
+:10D6A0004089704701891B2924BF4189B1F5A47FB6
+:10D6B00007D381881B2921BFC088B0F5A47F012032
+:10D6C0007047002070470A6842604968816070476F
+:10D6D00042680A60806848607047017911F0070F5E
+:10D6E0001BBF407910F0070F00200120704701791F
+:10D6F00011F0070F1BBF407910F0070F0020012029
+:10D7000070470171704700797047417170474079E7
+:10D7100070478171090AC1717047C088704746A27D
+:10D7200082B0D2E90012CDE900120179407901F00E
+:10D73000070269461DF80220012A07D800F00700F9
+:10D74000085C01289EBF012002B07047002002B093
+:10D750007047017170470079704741717047407997
+:10D76000704730B50C460546FB2988BFFFDF6C705B
+:10D7700030BDC378024613F03F0008BF7047052054
+:10D78000127903F03F0312F0010F36D0002914BFC5
+:10D790000B20704712F0020F32D0012914BF801DF8
+:10D7A000704700BF12F0040F2DD0022914BF401C97
+:10D7B000704700BF12F0080F28D0032914BF801C47
+:10D7C000704700BF12F0100F23D0042914BFC01CF3
+:10D7D000704700BF12F0200F1ED005291ABF12306B
+:10D7E000C0B2704712F0400F19D006291ABF401C72
+:10D7F000C0B27047072918D114E00029CAD114E03B
+:10D800000129CFD111E00229D4D10EE00329D9D1C9
+:10D810000BE00429DED108E00529E3D105E0062963
+:10D82000E8D102E0834288BF7047002070470000C3
+:10D830005052020086F3FFFF0001010201020203C1
+:10D840002DE9F041FC4D0446284600216A788068A5
+:10D8500001270E4612B1012A1ED006E090F866207C
+:10D86000002A18BF6F7000D001216A78C2EB421203
+:10D8700000EB420292F82830194324D0667090F8E9
+:10D88000D90002F12A0170B12A22201D07F062F9A5
+:10D890000420207027710DE090F82820002A18BF7E
+:10D8A0006E70E1D1E1E73C22201D07F053F905201D
+:10D8B000207027716878A968C0EB401001EB400028
+:10D8C00080F828601DE090F8A410E9B190F8D90024
+:10D8D000012818BFFFDFA868D0F8A5106160D0F854
+:10D8E000A910A160D0F8AD10E160D0F8B1102161AD
+:10D8F00090F8B5102175667013212170277180F89A
+:10D90000A4600120BDE8F08190F82210012922D006
+:10D91000017801291CBF0020BDE8F0816670142148
+:10D920002170811C2022201D07F014F92672A9689D
+:10D930000E70C24882888284D0F8C420527B80F85E
+:10D94000262080F82270D1F8C4000088F3F7BEFAD0
+:10D95000F2F765FFD5E7667007212170416A6160C3
+:10D9600080F82260CDE7B44880680178002914BFB0
+:10D9700080884FF6FF7070472DE9F84F4FF0000890
+:10D98000894606460127CDF80080FFF748FBBDF821
+:10D990000010A94D21F06004ADF8004008284FD2D6
+:10D9A000DFE800F004070D4E184E132C44F003007E
+:10D9B0000DE044F01500ADF80000474641E044F0AA
+:10D9C000100000BFADF800003BE044F0020040F062
+:10D9D0001000F7E7A86890F8E000052818BFFFDFFF
+:10D9E00044F01A00ADF80000A96891F8E71000298A
+:10D9F00014BF40F0010020F00100E3E7A86890F8B0
+:10DA0000E01003290AD090F8E01006295DD090F8C4
+:10DA1000E000042818BFFFDF64D012E03046FFF7B3
+:10DA200070FC002818BFFFDF0AD1F07810F03F0F1C
+:10DA30001FBF307910F0020F44F00400ADF8000071
+:10DA40004746BDF800000090BDF80000C0F3C00BD1
+:10DA5000A868CBEB4B1A00EB4A0090F8280000288E
+:10DA600018BFBDE8F88F3046FFF7D9FA80467248F4
+:10DA7000806800EB4A0190F8C90001F12A040128EE
+:10DA800008BF012508D0022808BF022504D00428B9
+:10DA900016BF08280325FFDF257300206073664842
+:10DAA000806890F8E11084F83B10FF21A1737F217A
+:10DAB000E176BDF80010618190F8E01004291CBFE8
+:10DAC00090F8E01006293AD049E044F00A01ADF898
+:10DAD000001090F8FA00002814BF41F0040021F073
+:10DAE00004006FE73046FFF70CFCD8B1012804BFF3
+:10DAF00044F00100ADF8000014D0022818BFFFDF89
+:10DB00009FD144F00200ADF80000A96891F8FA1026
+:10DB1000002914BF40F0040020F00400ADF800001C
+:10DB200047468EE7F07810F03F0F1FBF307910F0B6
+:10DB3000020FBDF8000040F0040082D042E790F8E8
+:10DB4000E200012808BF012508D0022808BF0225ED
+:10DB500004D0042816BF08280325FFDF657304F1ED
+:10DB600009000090344D28787F2808BFFFDF29780E
+:10DB7000009801707F2028706FB1B8F1070F04F191
+:10DB80001C01304603D2FFF7B0FA207239E0FFF7EC
+:10DB900078FC207204E000202072B8F1070F30D327
+:10DBA000B8F1070F0DD1A86890F8F91001B3D0F8BB
+:10DBB000EA10C4F80210B0F8EE10E18090F8F0001E
+:10DBC0006070A07A10F0040F0ED0A86890F8FA10D8
+:10DBD000E9B190F8F7102175D0F8F110C4F81510DC
+:10DBE000B0F8F500A4F81900B8F1070F38D098E0A4
+:10DBF000F07810F03F0F1ABF307910F0010FFF20BE
+:10DC0000DED0621CA11C304601F0E4FCD9E7B8F17B
+:10DC1000070F1CBFB8F1010FFFDFB9F1000F08BFFC
+:10DC2000FFDF99F800002075B8F1010F08D0B8F1B6
+:10DC3000070F0BD075E0000064010020CC1000201D
+:10DC400004F115013046FFF703FA6AE0012130467E
+:10DC5000FFF7A8FA0168C4F815108088A4F8190025
+:10DC6000F07810F03F0F1CBF317911F0080F1AD077
+:10DC7000A86890F8E020042A06D090F8E000032875
+:10DC800011D111F0100F0ED003213046FFF78AFAA0
+:10DC9000407803210009A0733046FFF783FA00881B
+:10DCA000C0F30B002082F07810F03F0F1CBF3079DA
+:10DCB00010F0400F13D0FE48FFF723FBA96891F83E
+:10DCC000E020032A14D006213046FFF76BFA0078D3
+:10DCD000E076A86890F8E010062922D118E0A8683C
+:10DCE00090F8FB10002918BF90F8F800F0D1F0E789
+:10DCF00091F8C910042914BF08290028E3D1F0784D
+:10DD000010F03F0F1CBF307910F0080FDBD1E0E7B7
+:10DD100090F8E9100909A173B0F8E800C0F30B000E
+:10DD20002082A968012001EB4A0181F82800BBF19B
+:10DD3000000F14BF06200520BDE8F84F03F02CBAF1
+:10DD40002DE9F041DB4DAA6892F8D930002B6ED056
+:10DD50007F27012611B10978FE2914D0804692F858
+:10DD60002800002818BFBDE8F08102F12A044046CF
+:10DD7000FFF755F90021082879D2DFE800F0515368
+:10DD800056787878595CCA4C92F8A400002818BFDD
+:10DD9000BDE8F08182F8A66092F8DD0018B1F6F7D0
+:10DDA000DAFC012829D02046FFF762F90146A8686D
+:10DDB00080F8A71000F1A8012046FFF73BF92046A4
+:10DDC000FFF763F90146A86880F8AE1000F1AF01D3
+:10DDD0002046FFF73DF9A86800F1B50428787F28B0
+:10DDE00008BFFFDF287820702F70A86880F8A46033
+:10DDF000BDE8F041052003F0CFB9F6F7EFFCA968C4
+:10DE000001F1A802A731FDF7FDFE002808BFFFDFE2
+:10DE1000A86890F8A71041F0020180F8A710CEE79B
+:10DE2000A17209E0A67221720CE0032001E021E05A
+:10DE30000220A07200E0FFDF04F10B014046FFF773
+:10DE400054F92072621CA11C404601F0C3FB2878E3
+:10DE500009347F2808BFFFDF287820702F70A8685A
+:10DE600080F82860BDE8F041052003F095B92172E3
+:10DE7000BDE8F081BDE8F0417EE570B58D4C002233
+:10DE8000A06890F8C910104602F0D4FF002831D0E5
+:10DE9000F7F763F9A068884990F8DF000D5C284621
+:10DEA000F6F7E7FEA06880F8E15090F8C91008295D
+:10DEB00016BF04290F202520F6F7F9FDA0680021E0
+:10DEC00090F8C9200120F6F7D4FF7948F7F74EF90A
+:10DED000A068D0F80001F7F74CF9A06890F8C910D5
+:10DEE00080F8E21090F8C800032814BF0228012926
+:10DEF00008D103E0BDE8704001F0A5BB0821002077
+:10DF0000F7F72AFAA06890F8C91080F8E210F7F73E
+:10DF100000FAA06890F8C95090F8DD0040B1F6F71B
+:10DF2000E6FB15F00C0F0CBF40205520F7F7D2F997
+:10DF3000A168032081F8E00070BD2DE9F0410F4693
+:10DF4000904605460321FFF72DF94078594C020908
+:10DF5000A06890F8E91062F3071180F8E910032136
+:10DF60002846FFF71FF90188A068B0F8E82061F3A0
+:10DF70000B02A0F8E82080F8E77090F8C91001299A
+:10DF800005D090F8E000032808BFBDE8F081E878EC
+:10DF90004FF0010610F03F0F1CBF287910F0400F22
+:10DFA00009D006212846FFF7FDF80178A06880F81F
+:10DFB000F81080F8FB60A06890F8E01003292AD0E0
+:10DFC000E97811F03F0F1CBF297911F0010F08D03B
+:10DFD00000F1F002911F284601F0FCFAA06880F8D9
+:10DFE000F960E87810F03F0F1ABF287910F0020F9F
+:10DFF000BDE8F08101212846FFF7D4F8A168026846
+:10E00000C1F8F1208088A1F8F50081F8F78081F847
+:10E01000FA60BDE8F081022F18BF012FD0D1BDE812
+:10E02000F0812DE9F84F0446C07810F03F0F1CBF77
+:10E03000207910F0020F05D010F0010F18BF4FF03B
+:10E04000010901D14FF0000900271A4DB9F1000F65
+:10E050005BD020780026C70901212046FFF7A2F8EF
+:10E060003FB1407900F0C000402808BF4FF00108E0
+:10E0700001D04FF00008A86890F8C810032906D115
+:10E0800090F8C110002918BF90F8CC0001D190F889
+:10E09000DE00FDF7A5FD070015D01021FEF7DDFB22
+:10E0A000B8F1000F0FD001212046FFF77BF805E003
+:10E0B000D811002064010020785202000146384641
+:10E0C000F7F7D4FC0646A868B8F1000F90F8B970CD
+:10E0D00018BF47F00207E07810F03F0F1CBF20790F
+:10E0E00010F0020F0ED02046FEF7CFFF824601212E
+:10E0F0002046FFF757F85146F6F769FD002818BF8C
+:10E10000012000D1002030435BD0E07810F03F0FB9
+:10E110001EBF217911F0100F11F0080F3FD004211C
+:10E120002046FFF73FF80646A86890F8E20002F0A4
+:10E1300078FE0146304601F0A8FAA0B13A46002127
+:10E140002046FFF7FAFEF848FFF7DBF80146A8681B
+:10E1500080F8E6103188A0F8E310B17880F8E51077
+:10E160000120BDE8F88FA86890F8E20001283AD1B4
+:10E17000E07810F03F0F1CBF207910F0010F32D073
+:10E18000B9F1000F04D100212046FFF7F5FB2AE08A
+:10E190008DF8007069462046FFF7EEFB23E010F093
+:10E1A0003F0F1CBF217911F0100F1CD110F03F0F51
+:10E1B0001CBF207910F0010F15D0B9F1000FE7D185
+:10E1C000E1E7A86890F8CA00032818BF02280AD11E
+:10E1D000B8F1000F07D036B9D448694600680090FE
+:10E1E0002046FFF7C9FB0020BDE8F88FD0498968B9
+:10E1F00081F80A01704770B5CD4DA86890F8E0101D
+:10E20000022919BF90F8E010012900210C461CBF1B
+:10E210000C2070BDC1EB411200EB4202034682F8B4
+:10E220002840491CC9B20229F4D3047080F8224066
+:10E2300093F8DD0030B1F7F757F8F6F76CFAA868F5
+:10E2400080F8DD40A868012180F8DC4080F8C1102A
+:10E2500080F8C84080F8DF40282180F80B1180F852
+:10E260000A41A0F8E34080F8E540072180F8C0109B
+:10E27000002070BDAE4810B58068002180F8E01025
+:10E28000012180F8E010FFF7B6FF002818BFFFDF7C
+:10E2900010BD2DE9F047A64C07460C26A06890F863
+:10E2A000E01001291FBF90F8E00002280C20BDE813
+:10E2B000F087F6F73CFCA06890F90A01F6F7C7FC76
+:10E2C000A06890F8C91080F8E21090F8C0100125FD
+:10E2D000002978D090F8C8004FF00009032802D038
+:10E2E000022805D008E00521924801F03AFA03E03F
+:10E2F0000321904801F035FAA06890F8D810002961
+:10E3000004BF90F8DB00002843D0F4F7DDFD06469B
+:10E31000A0683146D0F8D400F5F7E4FA864990FBBE
+:10E32000F1F801FB180041423046F4F7D6FA0146F5
+:10E33000A068C0F8D410D0F8D0104144C0F8D01074
+:10E34000FDF72FFC0146A068D0F8D020914220D8DC
+:10E35000C0E9349690F8DB0000281CBF0120FDF7CF
+:10E3600044FD0121A06890F8DC20002A1CBF90F831
+:10E37000D820002A0DD090F8B93000F1BA02012B54
+:10E3800004D1527902F0C002402A14D0BA30F7F713
+:10E39000D5FBA06890F8B910BA30F6F710FC0F2141
+:10E3A0000720F6F728FCA068002690F8E010012965
+:10E3B00018D112E007E0FDF745FDA1682A46BA3101
+:10E3C000F7F785FBE5E790F8E010022904BF80F835
+:10E3D000E0500C2006D1BDE8F08780F804510221FE
+:10E3E00080F8E010A06890F8C10088B1FDF7A5FCA6
+:10E3F00003214D48FDF7DDFC0146A06880F8DD10E3
+:10E40000C0F800714D48F6F79AFE3046BDE8F08737
+:10E41000FDF73CFCECE738B5454CA06890F8E010FF
+:10E4200002291CBF0C2038BD012180F80511A0F87D
+:10E43000081129208DF800006846F5F77DFD30B100
+:10E44000A0689DF8001090F80601884205D1A068E8
+:10E4500090F80601401C8DF80000A1689DF80000AE
+:10E4600081F806010220F6F77EFE3548F6F7F9FB43
+:10E47000A168DFF8D0C0002091F8C03091F8DF200B
+:10E48000521CACFB02546408A4EB8404224481F8BF
+:10E49000DF2023FA02F212F0010F03D1401CC0B2B8
+:10E4A0000328EBD3FFF7E9FC002038BD2049896839
+:10E4B00081F8C900002070471D49896881F8DA0099
+:10E4C000704710B51A4CA36893F8B830022B14BFEC
+:10E4D000032B00280BD100291ABF0229012000209C
+:10E4E0001146FDF761FB08281CBF012010BDA06884
+:10E4F00090F8B800002816BF022800200120BDE8CF
+:10E500001040F7F7A5BA0A48806890F8B8000028CC
+:10E5100016BF022800200120F7F79ABA044989683B
+:10E5200081F8B80070470000D81100206C5202003A
+:10E53000640100200012002040420F0075520200CA
+:10E540007B520200ABAAAAAAF749896881F8DC00CD
+:10E55000704770B5F44CA16891F8B800002816BF58
+:10E5600002280020012081F8B900BA31F7F75AFAE1
+:10E57000A06890F8B810022916BF032901210021D4
+:10E5800080F8DB1090F8B920002500F1BA03012AC9
+:10E5900004BF5B7913F0C00F0AD000F1BA03012A5F
+:10E5A00004D15A7902F0C002402A01D0002200E0D2
+:10E5B000012280F8D820002A04BF002970BDC0F8CD
+:10E5C000D050F4F781FCA168C1F8D40091F8DB00C9
+:10E5D00000281CBF0020FDF708FC0026A06890F86A
+:10E5E000DC1000291ABF90F8D810002970BD90F8EF
+:10E5F000B92000F1BA01012A04D1497901F0C00122
+:10E60000402905D02946BDE87040BA30F7F796BAE0
+:10E61000FDF718FCA1683246BDE87040BA31F7F743
+:10E6200056BA70B5C04D0C4600280CBF012300231C
+:10E63000A96881F8C13081F8CB004FF0080081F85B
+:10E64000CC000CD1002C1ABF022C01200020114656
+:10E65000FDF7AAFAA968082881F8CC0001D00020AB
+:10E6600070BD022C14BF032C1220F8D170BD0028FD
+:10E6700018BF112070470328AB4A926808BFC2F840
+:10E68000C41082F8C8000020704710B5044602F09C
+:10E6900083FF052809D002F07FFF042805D0A24897
+:10E6A000806880F8D940002010BD0C2010BD9E4825
+:10E6B000816891F8C800032804D0012818BF0228F7
+:10E6C00007D004E091F8CB00012808BF7047002074
+:10E6D000704791F8CA00012814BF03280120F6D121
+:10E6E000704710B5F6F7EAFDF6F79EFDF6F7CEFC9B
+:10E6F000F6F72BFD8C4CA06890F8DD0038B1F6F7EA
+:10E70000F3FDF6F708F8A168002081F8DD00A068A5
+:10E71000012180F80411022180F8E010002010BDD2
+:10E720008149896881F8FC0070477F4902788968CF
+:10E73000012A06D0042A24D0052A0CBF1120122059
+:10E74000704742780023032A08BFC1F8C43081F81B
+:10E75000C820012281F8C920C27881F8B820027946
+:10E76000002A16BF022A0123002381F8C13081F854
+:10E77000CA20427981F8C020807981F8DA0000202F
+:10E78000704782780023032A08BFC1F8C43081F89B
+:10E79000C8200822DEE764488068704700F053BF55
+:10E7A0002DE9F84F00256048F6F7BEFD5E4C4FF0AE
+:10E7B0007F0A002808BF84F800A0F6F7A0FD5B4898
+:10E7C000FEF72DFCA0700146A06890F8E2204FF003
+:10E7D00003084FF000094FF0010B012A10D0042A62
+:10E7E0001CBF082AFFDF00F05782A06890F8DD0008
+:10E7F00018B1F6F779FDF5F78EFF2846BDE8F88FDA
+:10E800004A4D0026A5F58677072936D290F8C10033
+:10E8100028B9F6F71EFA002808BF002600D0012606
+:10E82000A06890F8DD0080B1FDF715FAA168FF2817
+:10E8300081F8DE0001460DD0E81CFDF701FAA06862
+:10E8400090F8DE00FDF712FA0643A06890F8DE00AB
+:10E85000FF2817D1FDF7A1FA87F8DE0097F8C1105D
+:10E8600081B108280ED12878E91CC0F38010FDF78B
+:10E870009BF9082818BF002604E002BF90F8D900D1
+:10E8800000280126A07808283CD2DFE800F03FB934
+:10E89000043B3B3B17FD36B1A06890F8C800012847
+:10E8A00018BF022803D0F6F7F1FB45469DE7F6F7BF
+:10E8B000EDFB00211D48FFF743FAF6E716B3A06809
+:10E8C00090F8C800022802D0012815D01AE00021D3
+:10E8D0001648FFF735FAA0680825C0F8E790C0F899
+:10E8E000EB90C0F8EF90C0F8F390C0F8F79080F884
+:10E8F000FB9080F8E79078E700210C48FFF720FABA
+:10E9000000F040B9F6F7C2FB03256EE70020002EA9
+:10E9100071D0A26892F8C810022909D0012925D027
+:10E92000032928D06AE0000064010020D8110020EB
+:10E930000021FE48FFF704FAA16891F8050128B10B
+:10E94000401E10F0FF0081F8050154D1C1F8E79096
+:10E95000C1F8EB90C1F8EF90C1F8F390C1F8F790CF
+:10E9600081F8FB90082081F8E7B047E00021EF48EC
+:10E97000FFF7E6F941E0D2F8C400E978837E9942D6
+:10E980001BD12979C37E994217D16979037F9942B6
+:10E9900013D1A979437F99420FD1E979837F9942B5
+:10E9A0000BD1297AC37F994207D12978437EC1F3DD
+:10E9B0008011994208BF012100D0002192F8CB209C
+:10E9C000012A01D079B10CE059B900F11A01D748F8
+:10E9D000FEF730FBD548FEF74BFBA168D1F8C41019
+:10E9E00048760A200AE097F8CC00082803D097F868
+:10E9F000DE108142F5D0F6F749FB03200546F4E628
+:10EA0000A06890F8DB1000290CBF4FF0010B4FF00D
+:10EA1000000B4FF000082978CA0905F1090107D059
+:10EA2000497901F0C001402908BF4FF0010901D028
+:10EA30004FF0000990F8C810032906D190F8C110D2
+:10EA4000002918BF90F8CC0001D190F8DE00FDF746
+:10EA5000C7F85FEA000A13D01021FDF7FEFE002878
+:10EA600018BF4FF0010BB9F1000F04BFA06890F878
+:10EA7000B9A00FD005F109015046F6F7F7FF80461F
+:10EA8000A06890F8B9A000E093E0B9F1000F18BFBA
+:10EA90004AF0020A90F8C81003290ED0F6F7F6FAE9
+:10EAA000F6B3F6F7A4F850EA08006DD08DF800A090
+:10EAB00069469E48FFF744F964E0D0F8C400E9785D
+:10EAC000827E91421BD12979C27E914217D1697908
+:10EAD000027F914213D1A979427F91420FD1E97906
+:10EAE000827F91420BD1297AC27F914207D1297846
+:10EAF000407EC1F38011814208BF012500D000256E
+:10EB000097F8DE00082806D097F8CC10884208BF96
+:10EB10004FF0010901D04FF00009B8F1000F00E0FB
+:10EB200032E005D1BBF1000F04D0F6F760F808B170
+:10EB3000012100E000214EB197F8CB00012803D05D
+:10EB400020B955EA090001D0012000E0002001426F
+:10EB500016D0A06890F8CB10012908BF002D0DD168
+:10EB6000D0F8C40000F11A017048FEF763FA6F484C
+:10EB7000FEF77EFAA168D1F8C41048760A2534E67B
+:10EB8000F6F784FA032530E6A06890F8CA00032857
+:10EB900018BF0228F6D1B9F1000FF3D0B8F1000F79
+:10EBA000F0D163486946406800906048FFF7C8F8B4
+:10EBB000E8E7A06890F8DA0000283FF4A3AEF6F783
+:10EBC00065FAA06890F8D9100029DBD1C0F8E79069
+:10EBD000C0F8EB90C0F8EF90C0F8F390C0F8F79051
+:10EBE00080F8FB9080F8F8A05048FEF78AFB50B3FD
+:10EBF000012836D00228C5D1A068032590F8C800A6
+:10EC0000032814BF0020012036EA00003FF4EDADD8
+:10EC1000464E1820F17811F03F0F3FF4E6AD317900
+:10EC200088437FF4E2AD04213046FEF7BBFA074685
+:10EC3000A06890F8E20002F0F4F80146384600F0CF
+:10EC400024FDE8BBD1E5002E9CD0A06890F8C80058
+:10EC5000012818BF022895D13448FFF7E2F980BB9C
+:10EC600090E7002E8ED0314D1820E97811F03F0F3B
+:10EC700088D02979884385D104212846FEF792FA65
+:10EC80000646A06890F8E20002F0CBF80146304654
+:10EC900000F0FBFC98BB75E707297FF433AEC0F8A2
+:10ECA000E790C0F8EB90C0F8EF90C0F8F390C0F890
+:10ECB000F79080F8FB90012680F8F8A01B4801E04F
+:10ECC0007FE01AE0FEF71DFB38B1012818D00228BA
+:10ECD0004DD0F6F7DBF9454687E5F6F7D7F9A0689A
+:10ECE00090F8C800012818BF02287FF44BAF0F48E6
+:10ECF000FFF797F900283FF445AF042575E522E0BA
+:10ED0000F6F7C4F9094D1820E97811F03F0F3FF4E8
+:10ED100039AF297988437FF435AF04212846FEF7BF
+:10ED200041FA0646A06890F8E20003E0D8110020FE
+:10ED30006C52020002F075F80146304600F0A5FC66
+:10ED400000283FF41FAF002201212846FFF7F5F805
+:10ED5000F748FEF7D6FA0146A06880F8E610318839
+:10ED6000A0F8E310B17880F8E51004253DE503250F
+:10ED7000F6F78CF9A06890F8C800032814BF0020AB
+:10ED8000012036EA00003FF430ADE94E1820F1785A
+:10ED900011F03F0F3FF429AD317988437FF425AD61
+:10EDA00004213046FEF7FEF90746A06890F8E2001D
+:10EDB00002F037F80146384600F067FC00283FF4BF
+:10EDC00014AD002202213046FFF7B7F8D848FEF70D
+:10EDD00098FA0146A06880F8E6103988A0F8E31098
+:10EDE000B97880F8E5100425FFE42DE9F041D14C15
+:10EDF000A0680078002818BFFFDF0025A068012761
+:10EE00008570D0F8C4100A8882804A8842838A8834
+:10EE10008283C988C18380F82050C74990F8DB20DD
+:10EE2000A1F59A764AB10A78C2F38013CA1C23B1BD
+:10EE3000527902F0C002402A33D090F8DC2042B16F
+:10EE400011F8032BC2F380121AB1497911F0C00FE7
+:10EE500027D00E3006F022F8A06890F8DD0018B137
+:10EE6000F5F779FC012824D0A068D0F8C4104A7EB8
+:10EE7000C271D1F81A208260C98B818145610583F6
+:10EE8000A0680770D0F8C42090F80A1182F85710D3
+:10EE9000D0F8C4000088F2F719F8BDE8F041F1F7A6
+:10EEA000AFBCD6F83711C0F80E10B6F83B1141824E
+:10EEB000D2E7F5F793FCA16801F10802C91DFCF740
+:10EEC000A1FE002808BFFFDFA068C17941F0020160
+:10EED000C171D6F80F114161B6F813110183CFE764
+:10EEE0002DE9F047934C0746FF21A0680025012635
+:10EEF00080F8DE1090F8C800012818BF022802D060
+:10EF0000032818BFFFDF5FB18948FEF7A3F918B9DE
+:10EF10008748FEF7F9F918B100F07BFC05463FE0A1
+:10EF2000A06890F8E0007F27082839D2DFE800F0D9
+:10EF3000383838041725352B7E48F6F7F5F90028C0
+:10EF400008BF2770F6F7DBF9A06890F8DD0018B16C
+:10EF5000F6F7CAF9F5F7DFFBF6F798F82BE07548F6
+:10EF6000F6F7E2F9002808BF2770F6F7C8F9A0689D
+:10EF700090F8DD000028EFD0EAE76E48F6F7D4F904
+:10EF800030B9277004E06B48F6F7CEF90028F8D0C6
+:10EF9000F6F7B5F9F6F77AF80DE000F03DFE0AE075
+:10EFA0000C2D80F02B82DFE805F04CFCFB06FAF913
+:10EFB000F9F90AF84ECBBDE8F047FEF75EBF002234
+:10EFC0000121022001F036FF002800F05B815A4940
+:10EFD000A1F12800FEF75CF8A068574E90F8B91030
+:10EFE0003046FEF73CF8A06800F1BA013046FEF763
+:10EFF0001AF8A06890F8DB10C1B190F8C810032986
+:10F0000006D190F8C110002918BF90F8CC0001D1AA
+:10F0100090F8DE00FCF718FF050007D0012130460C
+:10F02000FEF71DF829463046FDF7FDFF4248F6F78A
+:10F030009DF801210846F6F78FF9A168082081F8AC
+:10F04000E000BDE8F087A06890F8E21090F80B218E
+:10F0500011F00C0F08BF002290F8E210032001F01D
+:10F06000E9FE002800F00E81344D0A2085F8E0000A
+:10F07000012002F091F805F59A71A1F12800FEF740
+:10F0800007F8A06805F59A7790F8B9103846FDF7AB
+:10F09000E6FFA06800F1BA013846FDF7C4FFA0689A
+:10F0A00090F8DB10C1B190F8C810032906D190F890
+:10F0B000C110002918BF90F8CC0001D190F8DE00F3
+:10F0C000FCF7C2FE060007D001213846FDF7C7FF56
+:10F0D00031463846FDF7A7FFA2681749D2F8C400A9
+:10F0E000C08AC875000A0876D2F8C400407D8875C9
+:10F0F0000846F6F73BF8D5F8C4100F4820234A7BA2
+:10F10000017803EA421221F0200111430170084AFC
+:10F11000D5F8C4001278417BC2F34012114041730C
+:10F12000D5F8C41095F80B0181F85600BDE8F087BA
+:10F13000D81100206401002000120020CC10002013
+:10F14000A06890F8E21090F80B2111F00C0F08BFA6
+:10F15000002290F8E210052001F06CFE00287CD01F
+:10F16000FE4D0B2085F8E000022002F015F805F5B1
+:10F170009A71A1F12800FDF78BFFA06805F59A7838
+:10F1800090F8B9104046FDF76AFFA06800F1BA0197
+:10F190004046FDF748FFA06804E047E02EE1A5E007
+:10F1A0009DE098E090F8DB10C1B190F8C8100329F9
+:10F1B00006D190F8C110002918BF90F8CC0001D1F9
+:10F1C00090F8DE00FCF740FE070007D00121404622
+:10F1D000FDF745FF39464046FDF725FFA068E04AA8
+:10F1E000D0F8C410C98AD175090A1176D0F8C400C4
+:10F1F0001146407D88750846F5F7B8FFD5F8C4007C
+:10F200004673A06890F8E230012296210020F5F7BD
+:10F210008CFED348017821F020010170A068D5F858
+:10F22000C41090F80B0181F856007FE7A06890F8B1
+:10F23000E21090F80B2111F00C0F08BF002290F89B
+:10F24000E210042001F0F6FD38B1C549A1F1280013
+:10F25000FDF71EFFC24EA06800E013E090F8B91061
+:10F260003046FDF7FCFEA06800F1BA013046FDF71C
+:10F27000DAFEA06890F8DB10E9B190F8C810032915
+:10F2800004D00AE0BDE8F04700F0DDB990F8C11005
+:10F29000002918BF90F8CC0001D190F8DE00FCF7EF
+:10F2A000D3FD050007D001213046FDF7D8FE2946E1
+:10F2B0003046FDF7B8FEAA48F5F758FFA06890F869
+:10F2C000E230012296210020F5F72FFEA1680920E7
+:10F2D00081F8E0002AE7A06880F8E06026E7A068EF
+:10F2E000022180F8046180F8E0101FE7A66816F894
+:10F2F000E31F11F0800F0CBF1E204FF49670B6F87C
+:10F300000120C2F30C0212FB00F7C80908BF4FF03E
+:10F310001E0906D0002806BFFFDF4FF000094FF49A
+:10F320009679B078400908BF012507D0012808BFA9
+:10F33000022503D0022814BF00250825A06890F8F4
+:10F34000E20001F06EFDA7EB0008307808EB09073A
+:10F35000C0F38010002808BF4FF4FA7A05D006BF2A
+:10F36000FFDF4FF0000A4FF0320A7C4890F8FC9023
+:10F37000B9F10C0F28BFFFDF7A487B4A30F819003B
+:10F380000AEB000101FB0720511CB0FBF1F000F17A
+:10F3900020094F44F5F7E1FE307800F03F06304693
+:10F3A000F5F767FCA06880F8E16029462520F5F7AD
+:10F3B0007EFB0122A8EB09012B461046F5F7B5FDAF
+:10F3C0006A48F5F7D3FE00213846F5F7EAFEA06853
+:10F3D00080F8E250F5F79DFFA06890F8DD0040B19D
+:10F3E000F5F785F915F00C0F0CBF50205520F5F7F7
+:10F3F00071FFA168042081F8E00097E6FFDF95E641
+:10F400005B4810B5806890F8E0000C286BD2DFE80C
+:10F4100000F06A6A6A6A6A6A6A6A0615533453486F
+:10F42000F5F7A4FEF5F775FF514C00219620F5F78E
+:10F43000B8FEA168052081F8E00010BD4B48F5F743
+:10F4400095FE4B4CA06890F8E230012296211046C0
+:10F45000F5F76BFDA16891F8E20091F80B1110F03F
+:10F460000C0F08BF00219620F5F79BFEF5F751FF22
+:10F47000A168062081F8E00010BD3C48F5F776FE53
+:10F480003B4CA06890F8E230012296211046F5F737
+:10F490004CFDA16891F8E20091F80B1110F00C0FEF
+:10F4A00008BF00219620F5F77CFEF5F732FFA16832
+:10F4B000072081F8E00010BDF5F700FFF5F7B4FE76
+:10F4C000F5F7E4FDF5F741FE29480121806880F851
+:10F4D0000411022180F8E010FFF787FCBDE810401E
+:10F4E000032001F059BEFFDF10BD70B5204CA068AD
+:10F4F00090F8E0007F25082828BF70BDDFE800F005
+:10F500004D4D4D172304470A1948F5F70DFF30B943
+:10F51000257004E01648F5F707FF0028F8D0F5F746
+:10F52000EEFEF5F7B3FDBDE87040FEF7A6BC10484F
+:10F53000F5F7FAFE002808BF2570F5F7E0FEBDE8F4
+:10F54000704000F080B80A48F5F7EEFE002808BFCA
+:10F550002570F5F7D4FEA0680CE00000CC10002068
+:10F5600000120020805202003F420F00D8110020FC
+:10F570006401002090F8DD0018B1F5F7B5FEF5F74D
+:10F58000CAF8F5F783FDBDE87040FEF776BC00F0E1
+:10F5900043FBBDE87040FEF770BC70BD70B5F84C21
+:10F5A00006460D46012909D0A06890F8E23090F88F
+:10F5B000E2203046BDE8704001F0C8BFF5F728FAF8
+:10F5C000A16891F8E220034629463046BDE8704024
+:10F5D00001F0BCBF70B50646E94814460D46806888
+:10F5E00090F8DD0018B1F5F7B6F801280ED03046D6
+:10F5F000FDF73EFD20703046FDF711FD072813D2C0
+:10F6000029463046BDE87040FDF714BDF5F7E6F831
+:10F610002A462146FCF7F6FA002808BFFFDF2078CB
+:10F6200040F00200207070BD3046FDF7F8FC07285E
+:10F6300018BF70BD00213046FDF7B4FD0168296098
+:10F640008088A88070BD10B5F5F738FEF5F7ECFDA1
+:10F65000F5F71CFDF5F779FDC94CA06890F8DD00C1
+:10F6600038B1F5F741FEF5F756F8A168002081F8AA
+:10F67000DD00A068012180F80411022180F8E0106B
+:10F68000BDE81040002001F087BD2DE9F0410D4696
+:10F690000178044611F0800F0CBF1E204FF49670C5
+:10F6A000B4F80120C2F30C0212FB00F6C80908BF2F
+:10F6B0001E2105D0002806BFFFDF00214FF4967100
+:10F6C000701BA278520908BF012707D0012A08BF82
+:10F6D000022703D0022A14BF00270827B0F5877F2E
+:10F6E0002EBFAE420020BDE8F08145182078C0F35F
+:10F6F0008010002808BF4FF4FA7603D006BFFFDF62
+:10F70000002632269F4890F8FC400C2C28BFFFDFD3
+:10F710009D489E4A30F81400311801FB0520511C09
+:10F72000B0FBF1F0203005449548806890F8E20085
+:10F73000F6F76CF804463846F6F768F84FF47A7135
+:10F7400084423ABF001B00F2E730201AB0FBF1F010
+:10F7500034BF42192A1A3946BDE8F041012001F0B0
+:10F7600069BB70B50D460446FDF734FC032D4AD045
+:10F77000052D18BF70BD05212046FDF730FC804DDA
+:10F78000A868D0F8C40000F10E012046FDF7E5FCA2
+:10F79000A868D0F8C40000F112012046FDF7E1FC92
+:10F7A000A868D0F8C410497DA175D0F8C410C98AE2
+:10F7B000E175090A2176D0F8C41049886176090AF2
+:10F7C000A176D0F8C4108988E176090A2177D0F8AB
+:10F7D000C410C9886177090AA177D0F8C40000F184
+:10F7E00008012046FDF7DBFCA868D0F8C400017EC4
+:10F7F0002046FDF7BCFCA86890F8FC102046BDE848
+:10F800007040FDF7BEBC2046BDE870400321FDF707
+:10F81000E6BB2DE9F04FDFF8688183B04FF0000AB6
+:10F82000D8F8080090F8E000594E01274FF003097E
+:10F8300055464FF07F0BA6F12804082880F0E78199
+:10F84000DFE800F0FEFEFE0407B3FDFCFEF7A8FFB4
+:10F85000A8E04B48F5F768FD002808BF88F800B01D
+:10F86000F5F74DFDD8F8080090F8D900002818BF2A
+:10F87000FFDF4848FDF7D3FB88F80300E078002657
+:10F8800010F03F0F1CBF207910F0080F11D0414835
+:10F89000FDF737FD60B1012802D0022808D008E04A
+:10F8A000E07810F03F0F1CBF207910F0010F00D05E
+:10F8B00001260296D8F8080090F8DD0018B1F5F797
+:10F8C00013FDF4F728FFE1782A460020134611F0D3
+:10F8D0003F0F1ABF217911F0020F2F4647D0D8F8F9
+:10F8E0000800DFF8B0A0002590F8DB0000280CBF6E
+:10F8F000012600269AF800000121C4095046FDF7B0
+:10F9000051FC34B1407900F0C000402808BF012408
+:10F9100000D00024D8F8080090F8C810032906D1B8
+:10F9200090F8C110002918BF90F8CC0001D190F8D0
+:10F93000DE00FCF755F95FEA000B0FD01021FCF751
+:10F940008CFF002818BF012644B101215046FDF765
+:10F9500029FC01465846F6F789F80546D8F808000C
+:10F960002200334690F8B90018BF40F0020098F822
+:10F970000310072910D0F5F789FBCA4600F048B9F3
+:10F9800064010020CC100020805202003F420F0092
+:10F9900000120020D8110020CDE900072946029866
+:10F9A00000F07BF9824600F033B9FC48FDF737FBE5
+:10F9B00088F80400E078717A88421CD12079B17A05
+:10F9C000884218D16079F17A884214D1A079317BCC
+:10F9D000884210D1E079717B88420CD1207AB17BCA
+:10F9E000884208D120783178C0F38010B0EBD11F65
+:10F9F00008BF012400D00024F5F748FBE848F5F7DC
+:10FA000093FC002808BF88F800B0F5F778FC98F858
+:10FA1000040004283BD1B4B30095D8F80820DF488F
+:10FA2000694692F8D9307BB3054692F8660050BB20
+:10FA3000042002F1680482F8720002E029E07DE00F
+:10FA4000E5E06932A11C2846FFF7C4FD04F10B0173
+:10FA50002846FDF76EFBC0B220721F2884BF1F200E
+:10FA6000207298F8000009347F2808BFFFDF98F85B
+:10FA70000000207088F800B0D8F8080080F86670A0
+:10FA8000062001F089FB02E0FFE7FDF775FFCA469B
+:10FA9000BEE04FF0030AC248F5F746FC002808BF55
+:10FAA00088F800B0F5F72BFCBC48FDF7B8FA05461E
+:10FAB000BA48FDF726FC082D08BF00287ED1E17862
+:10FAC000032011F03F0F79D02179884376D10021AE
+:10FAD000B248FDF767FB062206F1090105F00EF8B2
+:10FAE00000286BD1AD48FDF7C3FA0446AD48FDF7D9
+:10FAF000CCFA844262D10121A848FDF753FB0622CB
+:10FB0000F11C04F0FBFF002858D1A448FDF7BDFA12
+:10FB10000446A448FDF7ACFA844279D1F5F7CEFB50
+:10FB2000F5F782FBF5F7B2FAF5F70FFB4FF0020A93
+:10FB3000FFF75BF9042001F02FFB69E04FF0030AA7
+:10FB4000F5F7A4FA9648F5F7EFFB002808BF88F808
+:10FB500000B0F5F7D4FB9148FDF761FA81468F4874
+:10FB6000FDF7CFFBB9F1070F08BF002850D1E178AE
+:10FB7000012011F03F0F4BD02179884348D100215B
+:10FB80008648FDF70FFB062206F1090104F0B6FFD7
+:10FB9000A0B98248FDF76CFA04468248FDF775FA71
+:10FBA000844235D1D8F8080090F8041139B3B0F880
+:10FBB000082190F80611012A07D900E028E0520830
+:10FBC000A0F8082108BFA0F80871012914BF002976
+:10FBD0000D21C943C1EBC10202EB011190F80521CF
+:10FBE000D24302EB8203C3EB82121144B0F8082126
+:10FBF000890CB1FBF2F302FB131180F8051180F8B8
+:10FC00000471694665480095FDF7B6FE00E0FFDF28
+:10FC100003B05046BDE8F08F10B5F5F737FA6048ED
+:10FC2000F5F782FB5E4C002804BF7F202070F5F7BB
+:10FC300066FBA06890F8041119B1002180F8041146
+:10FC400010BDB0F8082190F80611FF2A0AD24FF62D
+:10FC5000FF7303EA4202A0F80821FF2A84BFFF22B3
+:10FC6000A0F80821012914BF00290D21C943C1EBC7
+:10FC7000C10202EB011290F80511C94301EB8103A7
+:10FC8000C3EB81111144B0F80821890CB1FBF2F3E8
+:10FC900002FB131180F80511CFE72DE9F84F8346D9
+:10FCA0009946924688463D480A9FFDF72AFB3B4EFF
+:10FCB0003B4D002800F03C81012803D0022800F0D1
+:10FCC0007781BAE0002403213448FDF76BFABBF1D9
+:10FCD000000F6BD0A96891F8E720012A66D142781D
+:10FCE00091F8E9301209B2EB131F5FD10088B1F827
+:10FCF000E810C0F30B00C1F30B01884256D127482E
+:10FD0000FDF7FFFAA96891F8E62090424ED191F8EC
+:10FD1000C800012818BF022802D0032847D0AEE04F
+:10FD2000F5F7B4F9F07810F03F0F1CBF307910F000
+:10FD3000020F18D0194C2046FDF7A7F906460121FD
+:10FD40002046FDF72FFA3146F4F741FF002818BF8F
+:10FD5000012050EA08000BD08DF8007069460F486A
+:10FD6000FDF70AFE18E000210C48FDF705FE13E040
+:10FD7000A86890F8CA00032818BF02280CD1BAF16D
+:10FD8000000F09D0B8F1000F06D107486946806816
+:10FD900000900248FDF7F0FD032470E0D811002028
+:10FDA00064010020001200206C52020064E0002177
+:10FDB0009848FDF7F7F9A9680622D1F8C4101A315E
+:10FDC00004F09CFE50B99348FDF752F9A968D1F8A8
+:10FDD000C410497E884208BF012400D00024F07876
+:10FDE00010F03F0F1CBF307910F0020F03D0B8F1B4
+:10FDF000000F47D056E0A86890F8CB10012901D039
+:10FE0000ACB11FE0F4B900218248FDF7CBF9A96835
+:10FE10000268D1F8C410C1F81A208088C8837D48D0
+:10FE2000FDF726F9A968D1F8C41048760AE090F8E1
+:10FE3000DE1090F8CC00814204D0F5F727F90320BA
+:10FE4000BDE8F88FA86890F8E21011F00C0F11D0FF
+:10FE500090F8E21011F00C0F0ED00123D0F8C4106E
+:10FE60001A460020FCF79DFEA968D1F8C410496A23
+:10FE7000884201D80B2402E0F5F708F90324204654
+:10FE8000BDE8F88FB9F1000F0ED0624E3046FDF795
+:10FE9000FCF8074601213046FDF784F93946F4F7AE
+:10FEA00096FE08B1012200E00022A96891F8CB007B
+:10FEB000012807D040B92CB991F8DE3091F8CC1068
+:10FEC0008B4201D1012100E000210A42D4D0012857
+:10FED00008BF002C12D100214E48FDF763F9A96834
+:10FEE0000268D1F8C410C1F81A208088C883494834
+:10FEF000FDF7BEF8A968D1F8C4104876A86890F854
+:10FF0000E21011F00C0FB5D090F8E21011F00C0FC8
+:10FF1000B2D00123D0F8C4101A460020FCF741FEED
+:10FF2000A968D1F8C410496A8842A5D8A2E700BFE1
+:10FF3000F5F7ACF803213748FDF734F9BBF1000FB2
+:10FF40005DD0A96891F8E7205ABB427891F8E93072
+:10FF50001209B2EB131F52D10088B1F8E810C0F3B8
+:10FF60000B00C1F30B01884249D12A48FDF7C9F9BA
+:10FF7000A96891F8E620904241D191F8C800012883
+:10FF800018BF02283BD1F07810F03F0F1CBF30792A
+:10FF900010F0020F06D08DF8007069461D48FDF77D
+:10FFA000EBFC2CE000211B48FDF7E6FC27E000BF3E
+:10FFB000F5F76CF8A86890F8C80003281FD015481A
+:10FFC000FDF79FF9A96891F8E620904217D1F278E1
+:10FFD000092012F03F0F12D0327990430FD1BBF1BC
+:10FFE000000F0CD091F8C8000228DBD191F8050170
+:10FFF00040B1401E10F0FF0081F8050102D003203F
+:020000040002F8
+:10000000BDE8F88F3A4601210248FDF796FF092026
+:10001000BDE8F88FD81100202DE9FF4F07460C46A8
+:10002000488881B040F2E24148430090E08A0026CF
+:1000300000FB01FB94F8640091460D2818BF0C28C2
+:100040001FD024281EBF94F8650024284FF0000A12
+:1000500017D0049818B10121204602F018FC94F83A
+:10006000540094F8558094F8D010054661B10129E8
+:100070006DD0022952D0032918BFFFDF67D000F0EE
+:10008000D5B84FF0010AE4E7B9F1000F08BFFFDF70
+:10009000FD4EB068002808BFFFDF94F85410FB48FD
+:1000A00090F82400FCF77DFF009094F85400F5F7D9
+:1000B000C6FB00F2E7314FF47A79B1FBF9F1F2486F
+:1000C00080680E1894F85400F5F7B9FB014694F8CF
+:1000D0005400022804BFEE484FF47A720DD0012874
+:1000E00004BFEC484FF4C86207D0042807BFEA48B1
+:1000F00040F69802E94840F6E4421044084400F211
+:10010000E731B1FBF9F10098401A00EB0B01DE4832
+:10011000406930440844061D012015E0DA48A9F181
+:1001200001018068084308BFFFDFDD48B9F1000F17
+:10013000006800EB0B0606D0D348806800F222303E
+:10014000B04288BFFFDF032084F8D0006DE094F850
+:100150006410009E24291EBF94F86520242A2529B6
+:100160004FD1B4F85810B4F8F020891A491C09B2DC
+:10017000002946DB94F8F210002942D00D4694F88D
+:10018000F310002918BF8846022804BFC0494FF465
+:100190007A700DD0012804BFBE494FF4C86007D063
+:1001A000042807BFBC4940F69800BC4940F6E4402B
+:1001B0000144022D04BFB6484FF47A720DD0012DD0
+:1001C00004BFB4484FF4C86207D0042D07BFB2483B
+:1001D00040F69802B14840F6E4421044814208D902
+:1001E000081A00F5FA714FF47A70B1FBF0F006448A
+:1001F00007E0401A00F5FA714FF47A70B1FBF0F0A5
+:10020000361AB9F1000F10D0DFF87C92D9F8080047
+:1002100020B9B9F80200002818BFFFDFD9F808009C
+:1002200000F22230B04288BFFFDF06B9FFDF31465F
+:10023000D4F8D400F2F751FBC4F8D400B860002021
+:1002400038704FF0010987F80490204602F00DFC49
+:10025000AAF10101084208BF87F8059006D094F87A
+:10026000D00001280CBF0220032078714046D4F84A
+:1002700024B0F5F7CBFA0146022D04BF84484FF4B1
+:100280007A720DD0012D04BF82484FF4C86207D0A6
+:10029000042D07BF804840F69802804840F6E442AB
+:1002A0001044084400F23F614FF47A70B1FBF0F063
+:1002B000584400F5C970F860049830EA0A0004BF99
+:1002C00005B0BDE8F08F31463846FCF7E8FB85B253
+:1002D000204602F0CAFBA8420FD8054687F80590D1
+:1002E00006FB05F1D4F8D400F2F7F7FAB86031460E
+:1002F0003846FCF7D4FB284485B22946204602F054
+:10030000C6FAB868C4F8D40005B0BDE8F08F2DE98E
+:10031000F0430446634885B00D4690F80004DFF8CA
+:100320008891400999F800144909884218BFFFDFF5
+:10033000DFF85481002708F14406082D80F00E8173
+:10034000DFE805F0046872726DFEFEB6202C28BF4F
+:10035000FFDF36F814000621F0F786FC050008BF21
+:10036000FFDF202C28BFFFDF36F8140029888842E1
+:1003700018BFFFDF95F8D000002808BFFFDF284630
+:1003800001F089FFC8F80870A8F80270294600201B
+:10039000C8F81470FCF758FC00F19804686AA04291
+:1003A00025D995F85500F5F731FA014695F854002E
+:1003B000022804BF36484FF47A720DD0012804BFDA
+:1003C00034484FF4C86207D0042807BF324840F6CB
+:1003D0009802324840F6E442104408444FF47A71DF
+:1003E00000F23F60B0FBF1F1686A0844071B294640
+:1003F0000020C8F80C70FCF727FC698840F2E24244
+:1004000051439830081AA0F22230C8F8100005B005
+:10041000BDE8F08305B0BDE8F04302F013B905B0C4
+:10042000BDE8F043F4F7BCBF99F8140D1F4940092B
+:1004300091F800144909884218BFFFDF202C28BF1B
+:10044000FFDF36F814000621F0F70EFC050008BFA8
+:10045000FFDF202C28BFFFDF36F8140029888842F0
+:1004600018BFFFDF0022012329466846FFF7D4FDAD
+:1004700095F8DA006946F2F76FFF002808BFFFDF42
+:1004800005B0BDE8F08300002812002044120020CF
+:1004900068360200A2240200D0FB010030D3010024
+:1004A0007401002001E000E00BE000E019E000E052
+:1004B000202C28BFFFDF36F814000621F0F7D4FB0C
+:1004C000050008BFFFDF202C28BFFFDF36F814002F
+:1004D0002988884218BFFFDF95F8D000042818BF8C
+:1004E000FFDF85F8D07095F8DA404FF6FF79202CC1
+:1004F00028BFFFDF26F8149095F8DA00F2F7C5FC64
+:10050000002808BFFFDF202085F8DA00D5F8E000DA
+:10051000002804BFD5F8DC00C8F8180008D0D5E9D9
+:1005200039121144826911448161D5E93701C860EB
+:10053000D5F8DC0000281CBFD5F8E010016100E010
+:100540000CE004D1D5F8E000002818BF8761FE4810
+:10055000007805B0BDE8F043EBF74CBCFFDF05B019
+:10056000BDE8F0832DE9F05FF84E07468B46F08B2F
+:100570007568401CF08330784FF00008002808BFF1
+:10058000FFDF07D0DFF8C89304282ED0052818BF56
+:10059000FFDF5BD05846FEF7FEF8040008BFFFDF20
+:1005A00029463069F2F799F9B86087F80080012090
+:1005B000387194F8C900022808BFE64807D001281E
+:1005C00008BFE54803D004280CBFE448E4484FF4D2
+:1005D0007A7100F2E140B0FBF1F0B168FA30084402
+:1005E000F860307804287DD183E0002AD2D0D6F894
+:1005F00010A0D9F8184034B3A146E468002CFBD110
+:10060000B9F1000F1FD099F80000002808BFFFDFE4
+:10061000D9F81410D9F8040001445046F3F762F9F0
+:10062000002807DA291A491E91FBF5F101FB0504A0
+:100630002A4604E090FBF5F101FB15042A4694429A
+:1006400088BFFFDF00E044462546A3E7002AA1D08B
+:10065000B569002D08BFFFDF0024D5F8E420D9F8E4
+:1006600018002346611E58B18369934228BF9942FE
+:1006700084BF194604460346C0680028F4D104B973
+:100680001C46C5F8E040D035002C04BFC5F80C80EE
+:10069000C9F8185005D0E068E560E860002818BF88
+:1006A0000561D5F81090C5F81880B9F1000F0ED08B
+:1006B000D9F8180048B1D5F814A0504538BFFFDF6D
+:1006C000D9F81800A0EB0A00A861C9F81880002C1E
+:1006D00008BFC6F8208009D02078002808BFFFDFB7
+:1006E000616900E00AE060680844306240F6B835AD
+:1006F00050E7F08B0A2838BF032000D3022078711E
+:10070000F08B012807D938467168FCF7C8F9014613
+:10071000F08B0844F083B8683061BDE8F09F2DE9A4
+:10072000F04107468F4884B00D4690F80004DFF88A
+:100730003882400998F800144909884218BFFFDF41
+:1007400001200026082D814C80F0BB80DFE805F0F9
+:1007500004718C8C87B9B9A5607320736078002808
+:100760001CBF04B0BDE8F0817948866046612673FD
+:100770003846FEF710F8050008BFFFDF95F8C900FE
+:10078000022804BF79494FF47A720DD0012804BFC2
+:1007900071494FF4C86207D0042807BF6F4940F67B
+:1007A0009802734940F6E44211444FF47A7201F220
+:1007B000E731B1FBF2F1A2688C18F5F715F80246A3
+:1007C00095F8C900082808BF082127D004280CBFC5
+:1007D0000221002322D002280CBF1821282119440D
+:1007E000042816BF08280F2325235B1D082808BFEF
+:1007F000402007D0042808BF102003D002280CBFD7
+:100800000420082013FB0010801A201AFDF741FD78
+:10081000002818BFFFDF04B0BDE8F08101EB410103
+:1008200001F12803082814BF04284FF4A871D6D07A
+:10083000D1E7617851B1207B002808BFFDF751FF57
+:10084000667304B0BDE8F041F2F74ABAA073FDF751
+:10085000E2FD002818BFFFDF04B0BDE8F08104B05E
+:10086000BDE8F041F4F79CBD98F8140D41494009EA
+:1008700091F800144909884218BFFFDF0022394669
+:100880006846FFF76FFE69463846F2F765FD0028B7
+:1008900008BFFFDF04B0BDE8F0812078052818BF4D
+:1008A000FFDF207F002808BFFFDF26772670207D2E
+:1008B000F2F7EBFA002808BFFFDF267504B0BDE8A9
+:1008C000F081FFDF04B0BDE8F0812DE9F0411F4C5D
+:1008D0000026207804281FBF207805280C20BDE8BA
+:1008E000F08101206070607B0025A8B1EFF31080DB
+:1008F00010F0010F72B60CBF00270127607B0028A3
+:100900001CBFA07B002805D0FDF7EBFE6573A57327
+:10091000F2F7E6F92FB903E0207DF2F72FFE00E0B1
+:1009200062B6207DF3F777F8207F28B1257720780D
+:10093000052818BFFFDF0C2665702570207DF2F7B3
+:10094000A4FA002818E000007001002044120020E2
+:100950002812002004360200A2240200D0FB01006D
+:10096000C0D4010001E000E00BE000E068360200C6
+:1009700030D3010019E000E008BFFFDF25753046E5
+:10098000BDE8F0812DE9F04FFB4883B000780028E6
+:1009900018BFFFF79AFF0120DFF8E08388F8000016
+:1009A00069460620F0F7E9F8002818BFFFDF0027A6
+:1009B0004FF6FF7934E0029800281CBF90F8D01061
+:1009C00000292DD0008848451CBFDFF8B4A34FF0A4
+:1009D000200B3BD00621F0F747F9040008BFFFDFEA
+:1009E00094F8DA00F3F717F884F8D07094F8DA5036
+:1009F0004FF6FF76202D28BFFFDF2AF8156094F808
+:100A0000DA00F2F742FA002808BFFFDF84F8DAB014
+:100A100069460620F0F7B1F8002818BFFFDF10E0A4
+:100A20006846F0F788F80028C5D00FE00298002843
+:100A30001CBF90F8D010002903D000884845C9D1C8
+:100A400004E06846F0F777F80028EFD088F80070E7
+:100A5000C8F8187003B00020BDE8F08F10B5C94C7D
+:100A600060B101280CBF40F6C410FFDF06D0A068BB
+:100A700041F66A01884228BFFFDF10BDA060F6E79B
+:100A800010B5DFF800C3BC4C00238CF800002370C5
+:100A90006370237723736373A3732020A36120758E
+:100AA000A4F11C004370423010214FF6FF724280C7
+:100AB00020F8042F491EFAD1CCF80830DCF80800E1
+:100AC00041F66A01884228BFFFDFFFF75BFF40F66F
+:100AD000C41101206160F4F799FE00F2E7314FF490
+:100AE0007A70B1FBF0F042F210710844A0606168C6
+:100AF000A1F21731884298BF0146A16010BDF0B540
+:100B00009D4C054685B0207800281EBF0C2005B0FE
+:100B1000F0BD95F8546095F855006F6AF4F776FECD
+:100B2000022E04BF98494FF47A720DD0012E04BFF3
+:100B300096494FF4C86207D0042E07BF944940F687
+:100B40009802944940F6E442114408444FF47A7103
+:100B500000F23F60B0FBF1F0384400F22230C5F8FB
+:100B6000E400A56195F8D000002818BFFFDF002041
+:100B7000824948610521217060702077E0838648B2
+:100B8000F2F729F92075202808BFFFDFF2F79CF95A
+:100B90002061217D01226846FFF7E4FC207D694643
+:100BA000F2F7DAFB002808BFFFDF002005B0F0BD38
+:100BB0007148007800281CBF0020704710B506203F
+:100BC000EFF7ECFF80F0010010BD70B56A4C0546F0
+:100BD0002078002818BFFFDF2878012832D00428A9
+:100BE0001CBF112070BDE8882E89082540F27121B4
+:100BF000484360602846F4F709FE4FF47A7100F22A
+:100C0000E730B0FBF1F040F2712206FB0200A06079
+:100C1000022D08BF614A07D0012D08BF5B4A03D0EF
+:100C2000042D0CBF5A4A5E4A02F2E142B2FBF1F1D6
+:100C30006268511AA1F28A21884298BF01460020B9
+:100C4000A16070BD6888AE880125CFE710B584B07B
+:100C500008431EBF112004B010BD474C2078002867
+:100C60001EBF0C2004B010BD002060700421217054
+:100C7000E0834948F2F7AFF82075202808BFFFDF6E
+:100C80003E48806938B10146C0680028FBD111B1E7
+:100C9000F2F71AF905E0F2F717F940F6B831F1F773
+:100CA0001CFE2061217D01226846FFF75BFC207D50
+:100CB0006946F2F751FB002808BFFFDF002004B0AF
+:100CC00010BD70B52C4CA1690160FFF7FEFD00233B
+:100CD00000BBA169D1F8E0205AB1D1E939C5AC44D3
+:100CE0009569AC44C2F818C0D1E9372CCCF80C2077
+:100CF00005E0DFF888C0D1F8DC20CCF81820D1F866
+:100D0000DC20D1F8E010002A18BF116102D10029BF
+:100D100018BF8B61A36170BD18494870704770B5EA
+:100D200040F2E24300FB03F510460C46F4F76EFD7B
+:100D3000022C04BF14494FF47A720DD0012C04BF69
+:100D400012494FF4C86207D0042C07BF104940F67F
+:100D50009802104940F6E442114408444FF47A7175
+:100D600000F23F60B0FBF1F000F2223085428CBF10
+:100D7000281A002070BD0000441200202812002014
+:100D80006C1200207001002068360200A2240200CC
+:100D9000D0FB010030D301001F070200043602001F
+:100DA000C0D4010070B50D46064601460020FBF791
+:100DB0004BFF044696F85500F4F728FD014696F8D7
+:100DC0005400022804BFFB4A4FF47A700DD001286A
+:100DD00004BFF94A4FF4C86007D0042807BFF74A98
+:100DE00040F69800F64A40F6E440104408444FF4B8
+:100DF0007A7100F23F60B0FBF1F0718840F271222D
+:100E00005143C0EB4100A0F22230A54234BF21463D
+:100E10002946814203D2A5422CBF28462046706253
+:100E200070BD10B5F4F7E0FCE6498A684968511ACC
+:100E3000084410BD2DE9F04FE24B04252827D3F8D4
+:100E400008B04FF010080BF198044FF008094FF06C
+:100E5000000C4FF4C8734FF4BF764FF0400A0628D9
+:100E60007CD2DFE800F00351214E246C14200429C9
+:100E700011D0082908D02A20022910D010FB0940DF
+:100E800000252821294458E0554610FB054000BFA5
+:100E90004FF4A871F6E710FB08402E25F8E710FB89
+:100EA000054065461821EDE704F5317473E0D0B2D2
+:100EB00011F00C0F08BF0020082904BF00F5BA612B
+:100EC00040200ED0042917D002290CBF0CF15C0180
+:100ED0000CF1B001014407BF0CF1180304203B469C
+:100EE000082000EBC00000EB400003EB400008448A
+:100EF000204400F19C044EE000F28E213346102085
+:100F0000EFE704F5B07446E0082908BF40200CD094
+:100F1000042904BF3346102007D0022907BF0CF173
+:100F2000180304200CF128030820C0EBC00000EBDC
+:100F3000400003EB40000BEB020144182BE0D0B261
+:100F400011F00C0F08BF0020082904BF00F535611F
+:100F5000402010D0042918D0022900E01AE00CBF6C
+:100F60000CF1B4010CF5B071014407BF0CF118038A
+:100F700004203B46082000EB400202EB001018441E
+:100F80000844204400F19C0405E000F2EE313346B1
+:100F90001020F0E7FFDF8C488068A0428CBF012062
+:100FA0000020BDE8F08F10B5864C607828B1D4E9F8
+:100FB0000301A268FBF79BFDE060D4E902018842CF
+:100FC0009CBF2078002814BF0020012010BD0422FF
+:100FD0002DE9F04F774E784FDFF8E081DFF8E091B0
+:100FE00085B04FF47A7A052980F0D280DFE801F0ED
+:100FF0000A2B0331920080F8D02005B0BDE8F04FF5
+:10100000F1F76EBE04466F480078002818BF84F8D8
+:10101000D02004D005B0BDE8F04FF1F761BE012249
+:10102000002321466846FEF7F7FF94F8DA00694688
+:10103000F2F792F9002808BFFFDFB4F85800401C0F
+:10104000A4F85800E6E7032180F8D01005B0BDE809
+:10105000F08F8346408840F2E24148435B49086094
+:10106000DBF8F80059460089ABF81600DBF8F80009
+:1010700080798BF81500DBF8F8004089ABF80200A6
+:10108000DBF8F8008089ABF80400DBF8F800C089D1
+:10109000ABF806000020DBF82850FBF7D5FD04462E
+:1010A0009BF85500F4F7B2FB9BF85410022908BFD7
+:1010B0004FF47A710DD0012904BF3E464FF4C86148
+:1010C00007D0042907BF464640F698014E4640F631
+:1010D000E4413144084400F23F60B0FBFAF1BBF850
+:1010E000020040F271225043C1EB4000A0F22230D6
+:1010F000A54234BF21462946814203D2A5422CBFD6
+:1011000028462046CBF8240002208BF8D00005B0FA
+:10111000BDE8F08F83460146856A0020FBF794FD09
+:1011200004469BF85500F4F771FB9BF85410022914
+:1011300008BF4FF47A710DD0012904BF3E464FF429
+:10114000C86107D0042907BF464640F698014E46BD
+:1011500040F6E4413144084400F23F60B0FBFAF04D
+:10116000BBF8021040F271225143C0EB4100A0F2E3
+:101170002230A54234BF21462946814203D2A542EE
+:101180002CBF28462046CBF8240005B0BDE8F08FE0
+:10119000FFDF05B0BDE8F08F2DE9F043DFF83080C8
+:1011A0000126002498F80010074D85B0072880F02C
+:1011B000C6810FE068360200A2240200D0FB0100C5
+:1011C00030D30100281200204412002074010020B6
+:1011D00070010020DFE800F0041A1AFCFCFBFB00A1
+:1011E000EC830846EAF706FE6878002840F066813E
+:1011F000297D00226846FFF7B5F9287D6946F2F798
+:10120000ABF8002808BFFFDF00F058B902280CBF78
+:1012100001260026287DFDF7BEFA040008BFFFDF87
+:1012200094F8E2103046FBF7BCFEDFF874930146F9
+:101230002869D9F80820002E024408BF4FF4FC703A
+:101240007DD094F8E20094F80B3110F00C0F08BF39
+:10125000002394F8E20008281EBF94F8E200042856
+:101260004FF0000C00F0C68094F8E20008281ABF86
+:1012700094F8E20004284FF4A87005D094F8E20036
+:1012800002280CBF18202820844494F8E200082883
+:1012900008BF40200BD094F8E200042808BF1020BB
+:1012A00005D094F8E20002280CBF04200820C0EB0F
+:1012B000C00606EB4010604494F8E2C0BCF1080F91
+:1012C0001EBF94F8E2C0BCF1040F00267ED000BF20
+:1012D00094F8E2C0BCF1080F1ABF94F8E2C0BCF168
+:1012E000040F4FF4A87C08D094F8E2C0BCF1020FC0
+:1012F0000CBF4FF0180C4FF0280C664494F8E2C075
+:10130000BCF1080F08BF4FF0400C10D094F8E2C0B9
+:10131000BCF1040F08BF4FF0100C08D094F8E2C0E5
+:10132000BCF1020F0CBF4FF0040C4FF0080C0CEB9B
+:101330004C0707EB0C1CB4446044184400E001E087
+:1013400000F59A7010440844061D94F8E200F4F782
+:101350005DFA024694F8E200022808BF91480BD0DB
+:1013600094F8E200012808BF8F4805D094F8E20005
+:1013700004280CBF8D488E4894F8E210022908BF5B
+:101380004FF47A710ED094F8E210012908BF4FF49F
+:10139000C86107D094F8E21004290CBF40F6980108
+:1013A00040F6E441084410444FF47A7100F2E7300B
+:1013B000B0FBF1F0A96940F2E243301A4A88D0311B
+:1013C00002FB03F7D9F818208A4202E01CE0B0E0E3
+:1013D0005DE008BF00262BD0296AF2F783FA0028C7
+:1013E0001EDA391A4A1E92FBF7F202FB070639464B
+:1013F0001BE000BF94F8E200082818BF022000EBB1
+:10140000400000F1280C2FE794F8E2C0BCF1080F6F
+:1014100018BF4FF0020C0CEB4C0C0CF1280657E7F0
+:1014200090FBF7F202FB170639468E4288BFFFDFBA
+:10143000D8F80800864208D2A86940F27122418893
+:10144000C1824A4306EB420605E040F2E240B6FBA9
+:10145000F0F0A969C88294F8E210A86980F85410E5
+:1014600094F8E21080F8551005214175C08A6FF498
+:101470001C71484306EB400040F63541C9F81400A2
+:10148000B0EB410F28BFFFDF05B0BDE8F0830428B3
+:101490000CBF01270027EC830846EAF7ABFC2E7748
+:1014A00085F82470A8692969C0F8D41080F8D04064
+:1014B0002978052918BFFFDF07D000BFF1F710FC1E
+:1014C0006C73AC7305B0BDE8F083002808BFFFDF84
+:1014D000A86990F8D000002818BFFFDFA86990F82D
+:1014E000DA00202818BFFFDF3248F1F774FCA96941
+:1014F0000646202881F8DA000F8828BFFFDF2E4833
+:1015000020F81670A86990F8DA00202808BFFFDFDD
+:10151000002301226846A969FEF77EFDA869694695
+:1015200090F8DA00F1F718FF002808BFFFDFAC6180
+:10153000C4E705B00846BDE8F043EAF75BBCFFDF4F
+:1015400005B0BDE8F08316494860704770B5144D8A
+:101550000446002904BFA86070BD4FF47A760129C3
+:1015600010D002291CBFFFDF70BD6888401C688056
+:101570001046F4F764F900F2E730B0FBF6F0201AF9
+:10158000A86070BD1846F4F76FF900F2E730B0FBC1
+:10159000F6F0201AA86070BD084800787047000077
+:1015A0002812002068360200A2240200D0FB0100AD
+:1015B00030D301000F0302006C12002044120020FF
+:1015C000FB490C28896881F8CB001ABF132818281A
+:1015D0007047002211280FD0072808BF7047152830
+:1015E0000AD001281ABF002802287047A1F88420D9
+:1015F000012081F888007047A1F88A20704770B5F3
+:10160000EB4CA1680A88A1F83E2181F83C0191F8D1
+:101610005400012808BF012508D0022808BF022570
+:1016200004D0042816BF08280325FFDFA06880F82F
+:10163000405190F85500012808BF012508D0022824
+:1016400008BF022504D0042816BF08280325FFDFA1
+:10165000A068012180F8415180F83A11002180F8FA
+:101660000E11E078BDE87040EAF7C4BBD04A01290A
+:1016700092681BD0002302290FD0032922D030B357
+:1016800001282FD0032818BF704792F86400132850
+:101690001CBF1628182805D1704792F8CB000028E7
+:1016A00008BF7047D2F8F8000370704792F8CB007B
+:1016B000012808BF704700BFD2F8FC000178491E1E
+:1016C0000170704792F8CB000328EBD17047D2F835
+:1016D000F800B2F858108288891A09B20029A8BF08
+:1016E00003707047B2F85800B2F80211401A00B205
+:1016F0000028E1DA70472DE9F041AD4C00260327C0
+:10170000D4F808C0012590B12069C0788CF8CA00CF
+:1017100005FA00F010F4000F08BFFFDFA06880F8A2
+:101720006470A0F8846080F88850BDE8F0810023E0
+:101730009CF8652019460CF15800FBF746F9002883
+:1017400004BF6570BDE8F0816078002818BFBDE86F
+:10175000F0812069C178A06880F8C91080F86570B0
+:10176000A0F88A6080F88C50BDE8F08170B5904C8C
+:1017700084B0207910F0010F04BF04B070BD20695F
+:1017800000230521C578A06890F864205830FBF745
+:101790001CF9002818BF062D09D020DC022D1CBF23
+:1017A000042D052D03D0607840F00800607060784B
+:1017B00000281CBF04B070BD2069C078801E1628A8
+:1017C00080F00783DFE800F011FE89A7D52CFEFD2D
+:1017D000FE7FFCD2FEFEFEC5FBFAF9F8F7F60B2DF4
+:1017E0001CBF0D2D112DDED1E1E7A06800230121E2
+:1017F00090F867205830FBF7E8F8002840F05C8349
+:101800002069FBF7F3FEA16881F8F600072081F854
+:101810006700002081F88C0081F8880000F04CBB44
+:10182000A0680921002390F864205830FBF7CDF818
+:1018300018B120690079122812D0A0680A2100236B
+:1018400090F864205830FBF7C0F818B1206900798F
+:10185000142820D020690079162840F02D8324E038
+:10186000A0680125002390F8642009215830FBF777
+:10187000ACF8002808BF657000F01E83607800286F
+:1018800040F01A83A16881F87C0081F8880081F813
+:10189000640000F011BBA168002081F86400A1F889
+:1018A000840081F8880000F035BAA06890F86410D0
+:1018B0001F2940F00183002180F8641080F888100F
+:1018C0001A2000F0F7BAA06890F864100F2927D109
+:1018D000002180F86910122137E0A06890F86410A8
+:1018E00013291DD1D0F8F81000884988814218BF0B
+:1018F000FFDFA068D0F8F80000F126012069FBF7AF
+:10190000A2FEA06800F1C4012069FBF7A4FE162026
+:10191000A16800F05BB9A26892F86400162802D0B2
+:10192000022000F03BBAD2F8F80002F1B00300F157
+:101930001E0100220E30FAF7C4FFA0680021C0E9A2
+:101940002811012180F86910182180F8641000F036
+:10195000B3BA2069FBF7FFFE032840F0AD8220698F
+:10196000FBF7FDFE01F00FFC00F0A6BA206900793C
+:10197000F8E7A06890F864101A29D1D1002580F802
+:101980008D5080F88850D0F8F8100088498881423E
+:1019900018BFFFDFA068D0F8F8100D70D0F8441120
+:1019A0000A78002A18BFFFDF7ED190F88E200AE067
+:1019B0007C0100203BE2B7E182E126E1F2E009E1AF
+:1019C0002CE09FE0AAE17AB180F88E500288CA80AC
+:1019D000D0F844110D71D0F844210E211170D0F8C7
+:1019E00044210188518010E00288CA80D0F8441157
+:1019F0000D71D0F8442101211172D0F844210D213C
+:101A00001170D0F84421018851800088EFF75EFA08
+:101A1000EEF7F6FEE078EAF7EDF9BEE0A068002305
+:101A2000194690F865205830FAF7CFFF50B9A068F2
+:101A30000023082190F864205830FAF7C6FF0028E8
+:101A400000F0FA816078002840F03682A06890F8B3
+:101A5000900010F0020F14D12069FBF7FFFDA16880
+:101A600081F891002069B0F80520A1F89220B0F823
+:101A70000700A1F8940091F8900040F0020081F86E
+:101A80009000A06890F8901011F0010F14D190F818
+:101A90006520002319465830FAF797FF002808BF41
+:101AA000FFDF0121A06800E077E080F8651080F892
+:101AB0008C100021A0F88A10A06890F86410012909
+:101AC00007D1002180F8641080F88810E078EAF7E8
+:101AD00091F9A168D1F8F800098842888A4204BFC8
+:101AE0000178042940F0E88100250570E078EAF7E4
+:101AF00081F9A06890F86410002908BF80F8885028
+:101B000000F0DAB9A0680023072190F8642058306B
+:101B1000FAF75BFF002800F08F816078002840F022
+:101B2000CB8102A92069FBF7D3FD9DF808000025B1
+:101B300000F02501A06880F896109DF8091001F0CA
+:101B4000410180F8971080F88850D0F8F81000888C
+:101B50004988814218BFFFDFA068D0F8F8100D70E7
+:101B6000D0F844110A78002A18BFFFDF15D1028887
+:101B7000CA80D0F844110D71D0F84411029A8A60DD
+:101B8000039ACA60D0F84421082111700188D0F866
+:101B900044014180E078EAF72DF9A06880F86450AC
+:101BA00000F08AB9A0680023092190F86420583019
+:101BB000FAF70BFF002800F03F816078002840F022
+:101BC0007B81A16881F87C0081F8880081F864003D
+:101BD00000F072B9A0680023194690F865205830CB
+:101BE000FAF7F3FE002800F027816078002840F023
+:101BF0006381A0680021A0F88A10012180F88C1070
+:101C0000022180F8651000F057B9A068002319463A
+:101C100090F865205830FAF7D8FE00287FD0206968
+:101C2000FBF740FD002879D0A5682069FBF736FD59
+:101C30002887A5682069FBF72DFD6887A5682069BE
+:101C4000FBF72EFDA887A5682069FBF725FDE8872F
+:101C5000A06890F864101C2913BF90F84E10012161
+:101C600080F84E10012907D090F80511002904BF13
+:101C700090F80411002903D01E2180F8651017E0A8
+:101C80001D2180F865100288A0F82A21028FA0F893
+:101C90002C21428FA0F82E21828F00F58A71A0F8A6
+:101CA0003021C08FC88301200875E078EAF7A2F8D8
+:101CB000A0680021A0F88A10012180F88C10FBE0B8
+:101CC000A06800230A2190F864205830FAF77DFEBE
+:101CD00018B32069FBF7E6FCA8B1A5682069FBF7FB
+:101CE000DDFC2887A5682069FBF7D4FC6887A56818
+:101CF0002069FBF7D5FCA887A5682069FBF7CCFC19
+:101D0000E88700F019FFA168002081F8880081F8B9
+:101D1000640000BF00F0E1FECEE000E059E0607832
+:101D200040F001006070C7E0A0680023194690F8F9
+:101D300065205830FAF749FE78B3A06890F864003F
+:101D4000232812BF2428607840F0200026D068465F
+:101D5000F3F71FFE002808BF002104D0009802A955
+:101D6000C0788DF80800A06801AB162290F86400D6
+:101D7000FBF7FBF8A0B1A0689DF80420162180F8BD
+:101D8000EC2080F8ED10192180F86510012180F811
+:101D90008C100021A0F88A108EE04DE060708BE07E
+:101DA0002069FBF79AFCA0B12269107900F00701C5
+:101DB000A06880F85010527902F0070280F8512094
+:101DC00090F80F31002B04BF90F80E31002B04D097
+:101DD00022E00020FFF78FFC6EE090F855C000F184
+:101DE00054038C4501BF19789142012180F87D1080
+:101DF00012D00288A0F8362190F8502000F58A71A0
+:101E000080F8382190F8510081F82500012081F8F0
+:101E10002000E078E9F7EEFFA068212180F8651046
+:101E2000012180F88C100021A0F88A1044E0A068FD
+:101E300090F864001F2801D00120AFE72069FBF76C
+:101E400056FC88B32069A2680179407901F0070146
+:101E500061F30705294600F0070060F30F21012018
+:101E600082F888000025A2F88450232082F86400BC
+:101E7000566DD2F81001FAF7F7FFF2B2C1B28A42FA
+:101E800007BFA16881F8F250A26882F8F210C6F389
+:101E90000721C0F30720814219BFA16881F8F30030
+:101EA000A06880F8F35007E0FFE70120FFF723FC6C
+:101EB0005FF01E00FFF7A3FBA068D0E92A12491CBF
+:101EC00042F10002C0E92A1204B070BD2DE9F047CA
+:101ED000FE4D04464FF00007687808436870287983
+:101EE00010F0200F2846806818BFA0F87E7004D13B
+:101EF000B0F87E10491CA0F87E1090F86A100126F8
+:101F000039B990F86420002306215830FAF75DFDB6
+:101F100058B3A88810F4006F07D0A86890F86A102A
+:101F2000002918BFA0F876701FD1A868B0F8761005
+:101F3000491C89B2A0F87610B0F878208A422CBFEC
+:101F4000511A00218288521D8A4228BF80F87C6085
+:101F5000B0F87610B0F87820914206D3A0F87670E9
+:101F600080F81A61E878E9F745FF287910F0600FEA
+:101F700008D0A86890F8681021B980F8686001213D
+:101F8000FFF725F84FF00808002C56D16878002894
+:101F900051D1287910F0040F0DD0A86890F8640092
+:101FA000032808BFFFDFA86890F86710072904BF5F
+:101FB0002E7080F8677001F036F9287910F0080F5C
+:101FC00019D06878B8B9A868002190F8CB00FFF75D
+:101FD0004DFBA86890F8CB00FE2808BFFFDFFE216C
+:101FE000A86880F8CB1090F86710082903D1022167
+:101FF000297080F86770FFF7B9FBA87810F0080F18
+:1020000016D0A8680023052190F864205830FAF70C
+:10201000DCFC50B185F80180A868D0F8441108783C
+:102020000D2808BF0020087002E00020F9F7E8F84A
+:10203000A86801F031F800F0C9FDA868A14600F1D8
+:10204000580490F8F40030B9E27B002301212046C7
+:10205000FAF7BBFC10B1608D401C60853D21B9F1E1
+:10206000000F18D12878022808BF16200ED00128AA
+:1020700004BFA86890F8F60008D06878E8B110F0BE
+:10208000140F1CBF1E20207702D005E0207703E04C
+:1020900010F0080F02D02177E67641E010F0030F30
+:1020A00003D02A202077E6763AE010F0200F08BF10
+:1020B000FFDF23202077E67632E094F8300028B165
+:1020C000A08D411CA185E18D884213D294F8340083
+:1020D00028B1608E411C6186E18D88420AD2618DF3
+:1020E000208D814203D3AA6892F8F42012B9E28DC0
+:1020F000914203D322202077E67611E0217C31B192
+:10210000E18C814228BF84F81C80C5D206E0E08CB7
+:10211000062803D33E202077E67601E0E07EA0B1DA
+:102120002773677327740221A868FEF750FFA86819
+:1021300090F8CB10012904D1D0F8FC000178491E99
+:102140000170E878E9F756FE03E00021A868FEF781
+:102150003EFFBDE8F047F3F72BBC5C4A517893781B
+:10216000194314D111460128896809D0107910F05B
+:10217000040F03D091F86700072808D001207047AA
+:10218000B1F84800098E884201D8FEF70CBF002044
+:10219000704770B54D4C06460D46A0883043A08070
+:1021A00016F0020F04D016F0010F18BFFFDFE56034
+:1021B00016F0010F18BF256116F0020F4FF0000254
+:1021C0004FF0010117D0E878062802D00B280BD079
+:1021D00011E0A06890F86420182A0CD10022C0E910
+:1021E0002A2280F86A1006E0A06890F8641012298C
+:1021F00008BF80F86A2016F0800F1CBF0820A0706E
+:1022000016F4806F08BF70BDA268B2F858009188BC
+:102210000844801DE97880B2012908BFA2F80201B4
+:102220001ED0002904BFD2F8F810888018D01829D1
+:1022300016D192F8F210002904BF92F8F330002B67
+:102240000BD011F00C0F1EBF92F8543013F00C0F8E
+:10225000994203D092F8F31001B90020A2F8F000DF
+:10226000E9782846012909D071B1182918BF70BD35
+:10227000B2F8F010BDE87040FBF74BBAB2F80211AB
+:102280004172090AA97270BDD2F8F81089884173A9
+:10229000090AA97370BDF0B50C4C85B00026A0608A
+:1022A000A6806670A670054626700088F3F748FB86
+:1022B000A0680088F3F76AFBB5F8D800A168401C55
+:1022C00082B201F15800FAF743F901E07C010020E5
+:1022D000002818BFFFDF95F8650024280AD1B5F85B
+:1022E0005810B5F8F000081A00B20028A4BF6078B2
+:1022F000002806D095F86400242818BF25283BD173
+:1023000019E0A06890F8F210002908BF90F8541066
+:1023100080F8541090F8F310002908BF90F8551079
+:1023200080F855100020FFF76AF985F86560A1680C
+:1023300081F87D6020E0B5F85810B5F8F000081A73
+:1023400000B20028A4BF6078002815D1A06890F8DA
+:10235000F210002908BF90F8541080F8541090F83B
+:10236000F310002908BF90F8551080F85510002090
+:10237000FFF745F985F86460A5F8D860A06890F883
+:10238000881039B1B0F88410B0F88620914224BF8B
+:1023900005B0F0BD90F88C1039B1B0F88A10B0F8E3
+:1023A0008620914224BF05B0F0BDB0F88220B0F87D
+:1023B00080108A4224BF05B0F0BD90F8682092B327
+:1023C000B0F87E208A4224BF05B0F0BD90F8CB70F3
+:1023D000FE2F00F01E816846F3F7B5FA002808BF0B
+:1023E000FFDF2221009802F034FC03210098FBF764
+:1023F00079F80098017821F0100101703946FBF757
+:102400009FF8192F80F0E380DFE807F028201446BA
+:10241000E1E1E21A71E1E2E264E1E1E1E1D4E2E268
+:102420007B94ADE1B600B0F87E10062924BF05B05C
+:10243000F0BDCBE7A068009990F8F5000871C7E0FF
+:10244000A168009891F8CC100171C1E0A068D0F8A3
+:10245000FC00411C0098FBF7BEF8B9E0A1680098A9
+:10246000D1F8F82092790271D1F8F82012894271DE
+:10247000120A8271D1F8F8205289C271120A0272CE
+:10248000D1F8F82092894272120A8272D1F8F810BB
+:10249000C989FBF778F89BE0A068D0F8F800011D27
+:1024A0000098FBF7A5F8A068D0F8F80000F10C013F
+:1024B0000098FBF7A7F8A068D0F8F80000F11E011B
+:1024C0000098FBF7A5F8A06800F1C0010098FBF7A1
+:1024D000ADF87DE0626900981178017191884171D1
+:1024E000090A81715188C171090A017270E0FE49BF
+:1024F000D1E90001CDE9020102A90098FBF7B0F88B
+:1025000066E0A068B0F844100098FBF7B3F8A06844
+:10251000B0F846100098FBF7B1F8A068B0F840108A
+:102520000098FBF7AFF8A068B0F842100098FBF7EE
+:10253000ADF84DE0A068B0F840100098FBF7A2F8A5
+:10254000A068B0F842100098FBF7A0F8A068B0F8B7
+:1025500044100098FBF78EF8A068B0F84610009879
+:10256000FBF78CF834E0A068009990F810210A710C
+:1025700090F8110148712BE0A06890F8F300FAF789
+:102580006AFC01460098FBF7C0F8A16891F8F200D8
+:1025900010F00C0F1CBF91F8541011F00C0F02D06A
+:1025A000884218BF0020FAF756FC01460098FBF756
+:1025B000A8F80DE0A06890F8ED100098FBF7C9F8B6
+:1025C000A06890F8EC100098FBF7C7F800E0FFDF78
+:1025D000F3F7CCF9002808BFFFDF0098C178012984
+:1025E00003D049B118290FD013E0A168B1F8021146
+:1025F0004172090A81720CE0A168D1F8F81089884B
+:102600004173090A817304E0A168B1F8F010FBF787
+:1026100080F8B6480090B64BB64A29463046F8F7DF
+:1026200033FDA0680023052190F864205830FAF7A4
+:10263000CCF9002804BF05B0F0BD05B0BDE8F040FE
+:10264000F8F713BBAC48806890F8881029B1B0F84F
+:102650008410B0F8862091421AD290F88C1029B1DB
+:10266000B0F88A10B0F88620914211D2B0F88220DA
+:10267000B0F880108A420BD290F86820B0F87E0043
+:1026800022B1884204D200BFF8F796BD0628FBD3DA
+:10269000002001461AE470B50C46064615464FF474
+:1026A000A471204602F0F7FA2680002D08BFFFDF54
+:1026B0002868C4F8F8006868C4F8FC00A868C4F882
+:1026C000440170BDEEF7D9BB2DE9F0410D46074638
+:1026D0000621EEF7C9FA040008BFBDE8F081D4F87E
+:1026E00044110026087858B14A8821888A4207D1C7
+:1026F000092810D00E281DD00D2832D008284CD023
+:1027000094F81A01002857D06E701020287084F8B1
+:102710001A61AF803EE06E7009202870D4F8440141
+:10272000416869608168A9608089A881D4F8440102
+:1027300006702FE00846EEF7C9FB0746EEF775F87E
+:10274000B0B96E700E202870D4F8440140686860FB
+:10275000D4F8440106703846EEF761F80120BDE870
+:10276000F0810846EEF7B2FB0746EEF75EF810B1CF
+:102770000020BDE8F0816E700D202870D4F844016F
+:102780004168696000892881D4F8440106703846A0
+:10279000EEF745F80120BDE8F0816E700820287042
+:1027A000D4F8440141688268C0686960AA60E86042
+:1027B000D4F844010670EDE794F81C01B0B16E70D6
+:1027C0001520287094F81C010028E3D084F81C61BF
+:1027D000D4F81E016860D4F82201A860B4F826017C
+:1027E000A88194F81C010028F0D1D3E794F82801BF
+:1027F00070B16E701D20287084F82861D4F82A0109
+:102800006860D4F82E01A860B4F83201A881C1E74D
+:1028100094F8340140B16E701E20287084F8346141
+:10282000D4F836016860B5E794F8140180B16E7091
+:102830001B20287094F814010028ABD084F8146190
+:10284000D4F81601686094F814010028F6D1A1E7C5
+:1028500094F83A01002808BFBDE8F0816E70162098
+:10286000287094F83A01002894D000BF84F83A61A7
+:10287000D4F83C016860B4F84001288194F83A012A
+:102880000028F3D186E71C4A5061D17070472DE9CA
+:10289000F0470446481E85B238BFBDE8F08704F112
+:1028A00008080126DFF850904FF0090A5FF0000792
+:1028B000B4F8D800401CA4F8D800B4F87E00401C3E
+:1028C000A4F87E0094F86A0040B994F864200023CC
+:1028D000062104F15800FAF778F838B3B4F8760016
+:1028E000401C80B20AE0000098520200CD1E020097
+:1028F0005B210200932102007C010020A4F87600F5
+:10290000B4F8781081422CBF0A1A0022A3885B1DFC
+:10291000934228BF84F87C60884207D3A4F876707D
+:1029200084F81A6199F80300E9F764FA94F88800CA
+:1029300020B1B4F88400401CA4F8840094F88C0002
+:1029400020B1B4F88A00401CA4F88A0094F8F4007E
+:1029500040B994F867200023012104F15800FAF7E8
+:1029600034F820B1B4F88200401CA4F8820094F836
+:1029700064000C2802D00D2820D067E0B4F858007D
+:10298000411CB4F80201814260D1D4F8FC00411C22
+:10299000404602F095FA02212046F9F7FCFCD4F8F3
+:1029A000FC000078002808BFFFDF0121FE20FEF7B1
+:1029B0005DFE84F8647084F8986047E0B4F85800CD
+:1029C000411CD4F8F800808881423FD1D4F84401FA
+:1029D0000178002918BFFFDF22D12188C180D4F8F7
+:1029E000F8004189D4F844010181D4F8F8008189C4
+:1029F000D4F844014181D4F8F800C189D4F84401E5
+:102A00008181D4F844010771D4F8440180F800A012
+:102A1000D4F844012188418099F80300E9F7EAF9E4
+:102A200001212046F9F7B7FC03212046FEF7CFFA33
+:102A3000D9F80800D0F8F8000078022818BFFFDFA6
+:102A40000221FE20FEF712FE84F86470B4F85800EC
+:102A5000401C691EA4F858008DB2BFF429AFBDE830
+:102A6000F087F94AC2E90601704770B50446B0F82C
+:102A70007E0094F86810002908BFC0F1020503D059
+:102A8000B4F88010081A051F94F87C0040B194F83F
+:102A900064200023092104F15800F9F796FFA0B142
+:102AA000B4F8766094F86A0058B994F8642000236A
+:102AB000062104F15800F9F788FF002808BF2846CE
+:102AC00003D0B4F87800801B001F8542C8BF0546BC
+:102AD000002DD4BF0020A8B270BD042110B5DA4C7F
+:102AE000A068FEF774FAA06890F84E10012902BFA2
+:102AF000022180F84E1010BD00F58A710288A0F8FE
+:102B00001E21028EA0F82021828EA0F82221028FA1
+:102B1000B0F844309A4228BF1A460A82828FB0F831
+:102B20004600824238BF1046488201200872E07891
+:102B3000BDE81040E9F75EB9C34830B4806890F84A
+:102B40004E30B0F832C0C48EB0F84010428F022B25
+:102B500025D08A4238BF11460186C28FB0F8421094
+:102B60008A4238BF11468186028FB0F844108A42EB
+:102B700038BF11464186828FB0F846108A4238BF6E
+:102B80001146C186418E614588BF8C46A0F832C08F
+:102B9000C18EA14288BF0C46C48630BC7047038EEC
+:102BA0009A4228BF1A46C58F838E9D4238BF2B4656
+:102BB0008A4238BF11460186B0F842108B4228BFC6
+:102BC0000B468386002180F84E10CDE770B59E4CF1
+:102BD000A06890F8CB10FE2906BF6178002970BD6F
+:102BE00090F86720002301215830F9F7EEFE002805
+:102BF00018BF70BDA06890F8F41021B1BDE8704016
+:102C00000220FEF7DDBC90F86420002319465830FE
+:102C1000F9F7DBFE40B1A06890F87C0020B1BDE878
+:102C200070401220FEF7CCBCA068002590F864200C
+:102C3000122A1FD004DC032A3FD0112A1FD003E040
+:102C4000182A35D0232A43D0002304215830F9F71D
+:102C5000BCFE002818BF70BDD4F808C09CF8650001
+:102C600019286ED03BDC01286ED002287AD00328C8
+:102C70005DD038E0BDE870400B20FEF7A1BCF1F755
+:102C800057F90C2838BF70BDA0680821D0F8F800AB
+:102C90001E30F1F751F928B1A0680421C030F1F7D6
+:102CA0004BF900B9FFDFBDE870400320FEF788BC98
+:102CB000BDE870400620FEF783BC90F8CA1080F88B
+:102CC000CC100720FEF77CFCA06880F8645070BD33
+:102CD0001820FEF775FCA068A0F8845070BD1E286F
+:102CE00048D021286CD0DCF8F800012601780029B2
+:102CF00074D04088BCF8001088426FD100239CF843
+:102D0000642019460CF15800F9F75FFE002865D0E1
+:102D1000A068D0F8F810097802297DD003297CD06A
+:102D200004297BD0052908BF082078D0C8E09CF88A
+:102D3000C9008CF8CC000720FEF742FCA06800F028
+:102D40007AB97CE000E00DE00C20FEF739FCA068C9
+:102D5000A0F88A5090F8901041F0010180F890108E
+:102D600000F069B91320FEF72BFCA068A0F88A5088
+:102D700000F061B99CF80501002818BF70BD9CF8EF
+:102D8000040188B1BCF80601ACF84000BCF80801A9
+:102D9000ACF84200BCF80A01ACF84400BCF80C01E5
+:102DA000ACF846008CF80451FFF7C6FEFFF795FE1D
+:102DB0001520FEF705FCA068A0F88A5000F03BB98A
+:102DC0009CF87D0058B18CF8F2508CF8F350182024
+:102DD000FEF7F6FBA068A0F88A5070BD70E09CF882
+:102DE0000F01002818BF70BD9CF80E01002808BF15
+:102DF00070BDDCE91416DCF81001FAF735F8F2B210
+:102E0000C1B28A4207BFA16881F8F250A26882F875
+:102E1000F210C6F3072103E018E01DE03DE024E0D6
+:102E2000C0F30720814219BFA16881F8F300A068B0
+:102E300080F8F3501820BDE87040FEF7C1BB1120A8
+:102E4000FEF7BEFBA068F6E07C01002090F865006C
+:102E5000F9F7A4FDA0BB08E090F8691041B190F823
+:102E60006A00002808BFFFDF0A20FEF7A9FB27E061
+:102E7000F1F75EF80C2823D3A0680821D0F8F800F9
+:102E80001E30F1F759F828B1A0680421C030F1F7DD
+:102E900053F800B9FFDF0320E7E790F8900010F047
+:102EA000030F0DD10C20FEF78BFBA168A1F8845015
+:102EB00081F8886091F8900040F0010081F890005E
+:102EC000A06890F8CB10FE2918BF70BD90F8642060
+:102ED000002319465830F9F778FD002808BF70BD67
+:102EE000A06890F80011E9B3A1690978D1BB90F806
+:102EF0006500F9F753FDA8BBA068B0F858100A297F
+:102F000031D900F108010522E06901F0F7FD002840
+:102F1000A06804BF80F8005170BDD0F8FC000178B3
+:102F200061B1411C0522E06901F0E8FD002818BFED
+:102F300070BDA068D0F8FC00007830B9A068E169E5
+:102F4000D0F8FC00401C01F0BBFFA068D0F8FC00EA
+:102F50000178491C01700120FEF732FBA06880F85F
+:102F6000005170BDFFE7A06890F8041111B190F80E
+:102F70000511E1B390F80E11002908BF70BD90F85B
+:102F80000F11002918BF70BD90F86500F9F706FD14
+:102F9000002818BF70BDA06890F85400012808BF31
+:102FA000012508D0022808BF022504D0042816BF36
+:102FB00008280325FFDFA06890F85500012808BF06
+:102FC000012608D0022808BF022604D0042816BF14
+:102FD00008280326FFDFA268012D92F810012DD0EA
+:102FE000022D2ED0032D08BF04282CD03BE0FFE794
+:102FF000B0F80611A0F84010B0F80811A0F842107F
+:10300000B0F80A11A0F84410B0F80C11A0F846105E
+:1030100080F8045190F865001D2804D0BDE8704088
+:103020001420FEF7CDBAFFF787FDFFF756FD1520F8
+:10303000FEF7C6FAA06880F8655070BD012812D16D
+:1030400001E002280FD192F81101012E06D0022EC4
+:1030500007D0032E08BF04280AD004E0012802D1BB
+:1030600006E0022804D0BDE870401620FEF7A8BA9A
+:10307000B2F8583092F85410B2F81201F032F9F761
+:1030800059FF20B1A168252081F8640070BDBDE81A
+:1030900070400020FEF7B3BA70B5044690F86400A3
+:1030A00000250C2814D00D2818BF70BDB4F85800A6
+:1030B000D4F8F810401C8988884218BF70BDD4F835
+:1030C0004401FF4E0178002918BFFFDF45D122E0FF
+:1030D000B4F85800B4F80211401C884218BF70BD03
+:1030E000D4F8FC00411C04F1080001F0E9FE0221C3
+:1030F0002046F9F750F9D4F8FC000078002808BF02
+:10310000FFDF0121FE20FEF7B1FA84F864500120B0
+:1031100084F8980070BD2188C180D4F8F800D4F8F4
+:10312000441140890881D4F8F800D4F8441180890A
+:103130004881D4F8F800D4F84411C0898881D4F8C3
+:1031400044010571D4F8441109200870D4F84411E1
+:1031500020884880F078E8F74DFE01212046F9F7F5
+:103160001AF903212046FDF732FFB068D0F8F800C5
+:103170000078022818BFFFDF0221FE20FEF776FA52
+:1031800084F8645070BD70B5CD4CA16891F864208E
+:10319000162A11BF132A91F88E20002A62781BBFCD
+:1031A00002206070002A70BD81F8C800002581F8F7
+:1031B0008D5081F88850D1F8F800098840888842FD
+:1031C00018BFFFDFA068D0F8F8000078032818BF08
+:1031D000FFDF0321FE20FEF749FAA068D0F8441172
+:1031E0000A78002A18BFFFDF19D10288CA80D0F8F8
+:1031F000442190F8C8101171D0F844110D72D0F824
+:1032000044210D211170D0F844210188518000889B
+:10321000EDF75CFEEDF7F4FAE078E8F7EBFDA06877
+:1032200080F8645070BD10B5A54C207910F0020FE5
+:1032300008BF10BD6078002818BF10BDE068C078D6
+:10324000192880F06781DFE800F05F4F0D8EF7F7F7
+:10325000A5223FF76F82B0F7F7F7F7F6E2DFF8F451
+:10326000F3F7F200A0680023012190F8672058309E
+:10327000F9F7ABFB002818BF10BD0821A06880F843
+:103280006710002180F8881080F88C1010BDA068AD
+:103290000023194690F865205830F9F796FB18B1CD
+:1032A000A168002081F88C00A0680023194690F8DE
+:1032B00064205830F9F789FB002808BF10BD0020B2
+:1032C000A16881F8880010BDA0680023194690F815
+:1032D00064205830F9F779FB002808BFFFDF04208D
+:1032E000A16881F8640010BDA0680023194690F819
+:1032F00064205830F9F769FB002808BFFFDF0C2075
+:10330000A16881F8640010BDA0680023194690F8F8
+:1033100064205830F9F759FB002808BFFFDF0D2063
+:10332000A16881F8640010BDA0680023194690F8D8
+:1033300064205830F9F749FB002808BFFFDF01215E
+:10334000A06880F88D100F2180F8641010BDA0686F
+:1033500090F86400122818BFFFDF0121A06880F8F0
+:103360008E101121F0E7A0680023194690F8642020
+:103370005830F9F72AFB28B9A06890F88E00002889
+:1033800008BFFFDF0121A06880F88D10132180F8AD
+:10339000641010BDA06890F86400182818BFFFDF03
+:1033A0001A20A16881F8640010BDA068D0F8F81058
+:1033B00003884A889A4204BF0978042919D190F8F1
+:1033C0006420002319465830F9F7FFFA002808BF97
+:1033D000FFDFA06890F8901011F0020F04BF0121E8
+:1033E00080F8641005D0002180F88810D0F8F8002B
+:1033F0000170A0680023194690F865205830F9F74D
+:10340000E4FA002808BF10BD0020A1687FE0A06892
+:103410000023194690F864205830F9F7D6FA0028AE
+:1034200008BFFFDF0520A16881F8640010BD30E00F
+:103430001FE012E001E066E06CE0A068002319469E
+:1034400090F864205830F9F7C0FA002808BFFFDF71
+:103450001C20A16881F86400E8E7A06800231946F1
+:1034600090F865205830F9F7B0FA002808BFFFDF60
+:10347000CAE7A0680023194690F864205830F9F78D
+:10348000A4FA002808BFFFDF1F20A16881F86400AC
+:10349000CCE7A06890F8651021291CD090F8641042
+:1034A000232918BFFFDFC1D190F8F210002907BF10
+:1034B00090F8F3100029242180F8641002E0000045
+:1034C0007C0100207FF4FBAE002180F864100846E8
+:1034D000FEF795F8F3E690F8F210002907BF90F890
+:1034E000F3100029242180F865108DD1002180F887
+:1034F000651080F87D1090F80E0100281CBF002098
+:10350000FEF77DF880E7A168002081F8650081F86A
+:103510008C008BE7FFDF89E770B58D4C0829207A96
+:1035200063D2DFE801F0041A5A5A2662625A80B167
+:10353000F1F7FDFA012211461046F1F7C4FCF2F74B
+:10354000A2F90020A072F1F794FBBDE87040F1F7FA
+:1035500004BEBDE87040EFF7C3BBD4E90001EFF74C
+:10356000BCF92060A07A401CC0B2A07228281CD3ED
+:1035700070BDA07A0025401EC6B2E0683044F1F765
+:10358000D3FE10B9E1687F208855A07A272828BF8C
+:1035900001252846F2F710F9A07A282809D2401C04
+:1035A000C0B2A072282828BF70BDBDE87040F1F7F6
+:1035B00060BB207A00281CBF012000F085F8F1F7DD
+:1035C00065FDF1F7C2FD0120E07262480078E8F77E
+:1035D00011FCBDE87040EFF783BB002808BF70BD49
+:1035E0000020BDE8704000F06FB8FFDF70BD10B57F
+:1035F000574C207A002804BF0C2010BD00202072F8
+:10360000E072607AEFF7BAFF607AF0F704FA607A56
+:10361000EFF73BFC00280CBF1F20002010BD00224C
+:1036200070B54B4C06460D46207A68B12272E272A4
+:10363000607AEFF7A3FF607AF0F7EDF9607AEFF7C1
+:1036400024FC002808BFFFDF4248E560067070BD1B
+:1036500070B5050007D0A5F5E8503F494C388142C8
+:103660009CBF122070BD3A4CE068002804BF0920BE
+:1036700070BD207A00281CBF0C2070BD3748EFF7C2
+:10368000AAFB6072202804BF1F2070BDEFF71CFC4E
+:103690002060002D1CBF284420600120656020723E
+:1036A000002000F011F8002070BD2949CA7A002AD4
+:1036B00004BF002070471F22027000224270CB68B6
+:1036C0004360CA72012070472DE9F04184B007467B
+:1036D000EFF7FAFB1E4D8046414668682C6800EB08
+:1036E000800046002046F0F7FDF8B04206DB68682F
+:1036F000811B4046EFF7F1F80446286040F233762C
+:1037000021464046F0F7EEF8B04204DA3146404632
+:10371000EFF7E3F8044600208DF8000040F2E76080
+:10372000039004208DF80500002F14BF0120032012
+:103730008DF8040068460294EFF793FD687A6946B5
+:10374000EFF70AFE002808BFFFDF04B0BDE8F081F4
+:10375000AC1200209C010020B5EB3C0019350200A2
+:103760002DE9F0410C4612490D68114A1149083201
+:103770001160A0F12001312901D301200CE0412882
+:1037800010D040CC0C4F94E80E0007EB8000241FB3
+:1037900050F8807C3046B84720600548001D056021
+:1037A000BDE8F0812046DDF71BFDF5E706207047F8
+:1037B0001005024001000001A052020010B552485D
+:1037C00000F012FA00B1FFDF4F48401C00F00CFA85
+:1037D000002800D0FFDF10BD2DE9F14F4B4ED6F889
+:1037E00000B00127484800F007FADFF81C8128B92B
+:1037F0005FF0000708F1010000F014FA444C0025C6
+:103800004FF0030901206060C4F80051C4F804516E
+:10381000009931602060DFF8FCA018E0DAF80000C1
+:10382000C00614D50E2000F064F8EFF3108010F0FD
+:10383000010072B600D00120C4F80493D4F800113E
+:1038400019B9D4F8041101B920BF00B962B6D4F88F
+:10385000000118B9D4F804010028DFD0D4F804011D
+:103860000028CFD137B1C6F800B008F1010000F050
+:10387000C3F911E008F1010000F0BEF90028B9D148
+:10388000C4F80893C4F80451C4F800510E2000F0A5
+:1038900030F81D4800F0C6F90020BDE8F88F2DE98A
+:1038A000F0438DB00D46064600240DF110090DF1D0
+:1038B000200817E004EB4407102255F8271068464B
+:1038C00001F048F905EB870710224846796801F0B6
+:1038D00041F96846FFF780FF10224146B86801F0C1
+:1038E00039F9641CB442E5DB0DB00020BDE8F0837B
+:1038F00072E700F01F02012191404009800000F1B1
+:10390000E020C0F8801270479D01002004E50040CF
+:1039100000E0004010ED00E0A94900200870704769
+:1039200070B5A84D01232B60A74B1C68002CFCD060
+:10393000002407E00E6806601E68002EFCD0001D03
+:10394000091D641C9442F5D30020286018680028E3
+:10395000FCD070BD70B59A4E04469C4D307802285C
+:1039600000D0FFDFAC4200D3FFDF71699848012926
+:1039700003D847F23052944201DD03224271491CC0
+:103980007161291BC16092497078EFF7E5FC00284E
+:1039900000D1FFDF70BD70B5894C0D46617888425B
+:1039A00000D0FFDF894E082D4BD2DFE805F04A0436
+:1039B0001E2D4A4A4A382078022800D0FFDF032013
+:1039C0002070A078012801D020B108E0A06800F0A4
+:1039D0001BFE04E004F1080007C8FFF7A1FF052063
+:1039E0002070BDE87040EFF77BB9EFF76DFA014644
+:1039F0006068EFF777FFB04202D2616902290BD30A
+:103A00000320F0F722FA12E0EFF75EFA0146606851
+:103A1000EFF768FFB042F3D2BDE870409AE7207834
+:103A200002280AD0052806D0FFDF04202070BDE858
+:103A3000704000F0BBB8022000E00320F0F705FA68
+:103A4000F3E7FFDF70BD70B50546EFF73DFA5C4C5C
+:103A500060602078012800D0FFDF5D4901200870F8
+:103A60000020087104208D6048715848C860022009
+:103A700020706078EFF770FC002800D1FFDF70BD88
+:103A800010B54F4C207838B90220F0F7F4F918B986
+:103A90000320F0F7F0F908B1112010BD4D48EFF701
+:103AA0009AF96070202804D0012020700020606105
+:103AB00010BD032010BD2DE9F041144600EB840732
+:103AC0000E4605463F1F00F0B2FD4FF080521169CF
+:103AD000484306EB8401091FB14201D2012100E0F5
+:103AE00000211CB11269B4EB920F02D90920BDE884
+:103AF000F081394A95420ED3AF420CD3854205D2AC
+:103B0000874203D245EA0600800701D01020EEE785
+:103B1000964200D309B10F20E9E7304830490068E8
+:103B2000884205D0224631462846FFF7F9FE10E0CC
+:103B3000FFF7A6FF0028DAD1214800218560C0E9FF
+:103B4000036481704FF4A97104FB01F01830FFF792
+:103B50007AFF0020CBE770B54FF080550446286906
+:103B60001D49B1FBF0F0844201D20F2070BD00F07E
+:103B70005EFDA04201D8102070BD184818490068A9
+:103B8000884204D02869604300F03EFD0CE0FFF756
+:103B900077FF0028F0D1296909486143816001213C
+:103BA00081701048FFF74FFF002070BD10B5044C26
+:103BB0006078EFF76AF900B9FFDF0020207010BDD0
+:103BC000A001002004E5014000E40140105C0C006D
+:103BD000BC1200209739020000600200B0000020F3
+:103BE000BEBAFECA7C5E0100002101700846704723
+:103BF0000146002008707047EFF3108101F00101C9
+:103C000072B60278012A01D0012200E000220123CD
+:103C1000037001B962B60AB1002070474FF400503A
+:103C20007047E9E7EFF3108111F0010F72B64FF022
+:103C30000002027000D162B600207047F2E7000077
+:103C40007B490968016000207047794908600020BD
+:103C5000704701218A0720B1012804D042F20400F4
+:103C60007047916700E0D1670020704771490120DB
+:103C7000086042F20600704708B504236D4A190730
+:103C8000103230B1C1F80433106840F00100106008
+:103C90000BE0106820F001001060C1F8083300202C
+:103CA000C1F80801644800680090002008BD011FA9
+:103CB0000B2909D85F4910310A6822F01E0242EA36
+:103CC000400008600020704742F2050070470F284E
+:103CD00009D8584910310A6822F4706242EA00207B
+:103CE00008600020704742F205007047000100F1B3
+:103CF0008040C0F8041900207047000100F18040A6
+:103D0000C0F8081900207047000100F18040D0F889
+:103D10000009086000207047012801D9072070477A
+:103D2000464A52F8200002680A43026000207047A9
+:103D3000012801D907207047404A52F82000026844
+:103D40008A43026000207047012801D9072070478C
+:103D50003A4A52F8200000680860002070470200CC
+:103D600037494FF0000003D0012A01D007207047E7
+:103D70000A607047020033494FF0000003D0012A67
+:103D800001D0072070470A60704708B54FF40072F1
+:103D9000510510B1C1F8042308E0C1F80823002040
+:103DA000C1F8240124481C3000680090002008BDA0
+:103DB00008B58022D10510B1C1F8042308E0C1F88C
+:103DC00008230020C1F81C011B4814300068009033
+:103DD000002008BD08B54FF48072910510B1C1F8FC
+:103DE000042308E0C1F808230020C1F8200112488C
+:103DF000183000680090002008BD0D49383109686E
+:103E00000160002070474FF080410020C1F8080198
+:103E1000C1F82401C1F81C01C1F820014FF0E020D5
+:103E2000802180F800140121C0F8001170470000C3
+:103E300000040040000500400801004064530200F7
+:103E400078050040800500406249634B0A68634979
+:103E50009A42096801D1C1F3100101600020704746
+:103E60005C495D4B0A685D49091D9A4201D1C0F366
+:103E700010000860002070475649574B0A685749A0
+:103E800008319A4201D1C0F3100008600020704749
+:103E900030B5504B504D1C6842F20803AC4202D082
+:103EA000142802D203E0112801D3184630BDC30004
+:103EB0004B481844C0F81015C0F81425002030BD38
+:103EC0004449454B0A6842F209019A4202D0062849
+:103ED00002D203E0042801D308467047404A01217A
+:103EE00042F83010002070473A493B4B0A6842F2D2
+:103EF00009019A4202D0062802D203E0042801D325
+:103F000008467047364A012102EBC000416000209C
+:103F1000704770B52F4A304E314C156842F2090394
+:103F200004EB8002B54204D0062804D2C2F800187F
+:103F300007E0042801D3184670BDC1F31000C2F891
+:103F40000008002070BD70B5224A234E244C15682D
+:103F500042F2090304EB8002B54204D0062804D2E1
+:103F6000D2F8000807E0042801D3184670BDD2F843
+:103F70000008C0F310000860002070BD174910B59C
+:103F80000831184808601120154A002102EBC003CF
+:103F9000C3F81015C3F81415401C1428F6D30020DC
+:103FA00006E0042804D302EB8003C3F8001807E0FE
+:103FB00002EB8003D3F80048C4F31004C3F80048B0
+:103FC000401C0628EDD310BD04490648083108609E
+:103FD00070470000B0000020BEBAFECA00F50140E4
+:103FE00000F001400000FEFF7E4B1B6803B19847C4
+:103FF000BFF34F8F7C4801687C4A01F4E0611143B4
+:104000000160BFF34F8FFEE710B5EFF3108010F0A3
+:10401000010F72B601D0012400E0002400F0D9F8AD
+:1040200050B1DDF777F9EEF71CFDEFF7B1FEDEF7E3
+:10403000ECFE6F490020086004B962B6002010BD94
+:1040400070B50C460546EFF3108010F0010F72B604
+:1040500001D0012600E0002600F0BBF818B106B937
+:1040600062B6082070BDDDF7D1F8DDF757F90246DA
+:10407000002043099B0003F1E02300F01F01D3F867
+:104080000031CB40D9071BD0202803D222FA00F1FF
+:10409000C90722D141B2002906DA01F00F0101F16E
+:1040A000E02191F8141D03E001F1E02191F80014E2
+:1040B0004909082911D281B101290ED004290CD057
+:1040C000401C6428D5D3DEF777FE4949494808608B
+:1040D0002046F0F775FA60B904E006B962B641F21D
+:1040E000010070BD3F4804602DB12846F0F7B5FAD5
+:1040F00018B110242CE0404D19E02878022802D98C
+:104100004FF4805424E007240028687801D0F8B9DF
+:1041100008E0E8B120281BD8A878212818D8012861
+:1041200016D001E0A87898B9E8780B2810D8334960
+:10413000802081F8140DDDF7F1F82946EFF70EFE27
+:10414000EEF74EFC00F0A6FA2846DDF7B5F8044677
+:1041500006B962B61CB1FFF757FF204670BD0020BC
+:1041600070BD10B5044600F034F800B10120207095
+:10417000002010BD224908600020704770B50C4631
+:1041800020490D681F49204E08310E60102807D0C5
+:1041900011280CD012280FD0132811D0012013E0C1
+:1041A000D4E90001FFF74CFF354620600DE0FFF732
+:1041B0002BFF0025206008E02068FFF7D2FF03E016
+:1041C0000F4920680860002020600E48001D05602F
+:1041D00070BD074807490068884201D10120704737
+:1041E00000207047B80100200CED00E00400FA0543
+:1041F000B0000020BEBAFECA6C5302000BE000E023
+:1042000004000020100502400100000100B5D8495B
+:1042100002282DD021DC10F10C0F08BFF42027D08C
+:104220000FDC10F1280F08BFD82021D010F1140F97
+:1042300008BFEC201CD010F1100F08BFF02017D0E1
+:1042400020E010F1080F08BFF82011D010F1040F82
+:104250000CBFFC2000280BD014E0C01E062811D291
+:10426000DFE800F00E0C0A080503082000E0072034
+:10427000086000BD0620FBE70520F9E70420F7E70A
+:104280000320F5E7FFDF00BD00B5BA49012808BFEC
+:1042900003200CD0022808BF042008D0042808BF3F
+:1042A000062004D0082816BFFFDF052000BD0860E7
+:1042B00000BDB149002804BF086820F0010005D006
+:1042C000012806BF086840F0010070470860704789
+:1042D00070B51E460546012924D0022A04BFA7480E
+:1042E0004FF47A710DD0012A04BFA5484FF4C8617C
+:1042F00007D0042A07BFA34840F69801A24840F619
+:10430000E44144181846F1F781FA04443046F1F7C5
+:10431000ABFA20444FF47A7100F27120B0FBF1F057
+:10432000281A70BD022A08BF4FF47A700AD0012AF9
+:1043300008BF4FF4C86005D0042A0CBF40F69800AF
+:1043400040F6E44049F608514418DBE770B51446DE
+:104350000546012908BF49F6CA660DD0022B08BFE1
+:104360008A4807D0012B08BF854803D0042B0CBF17
+:104370008448874800F1FA061046F1F760FA012CEC
+:1043800008BF4FF47A710AD0022C08BF4FF4FA71BB
+:1043900005D0042C0CBF4FF4FA614FF4FA51711A96
+:1043A00008444FF47A7100F28920B0FBF1F0281A2A
+:1043B000801E70BD70B514460646012930D0022B10
+:1043C00004BF6E494FF47A700DD0012B04BF6C49C5
+:1043D0004FF4C86007D0042B07BF6A4940F6980025
+:1043E000694940F6E4400D181046F1F728FA012C0F
+:1043F00008BF4FF47A710AD0022C08BF4FF4FA714B
+:1044000005D0042C0CBF4FF4FA614FF4FA51691A2D
+:1044100008444FF47A716438B0FBF1F0301A70BD83
+:10442000022B08BF4FF47A700AD0012B08BF4FF45B
+:10443000C86005D0042B0CBF40F6980040F6E4405D
+:1044400049F608514518CFE770B5164604460129CC
+:1044500008BF49F6CA650DD0022B08BF4B4807D0EC
+:10446000012B08BF464803D0042B0CBF45484848E1
+:1044700000F1FA051046F1F7C9F905443046F1F7A5
+:10448000F3F928444FF47A7100F2E140B0FBF1F007
+:10449000201A801E70BD2DE9F04107461E460C46CD
+:1044A00015461046082A16BF04284DF68830F1F745
+:1044B000ADF907EB4701C1EBC71100EBC100012CBF
+:1044C00008BF4FF47A710AD0022C08BF4FF4FA717A
+:1044D00005D0042C0CBF4FF4FA614FF4FA51471881
+:1044E0002046F1F7ACF9381A4FF47A7100F60F60F4
+:1044F000B0FBF1F42846F1F777F920443044401D31
+:10450000BDE8F08170B5054614460E460846F1F741
+:104510007DF905EB4502C2EBC512C0EBC205304682
+:10452000F1F7A2F92D1A2046082C16BF04284DF6E3
+:104530008830F1F76BF928444FF47A7100F6B73000
+:10454000B0FBF1F52046F1F74FF92844401D70BD4E
+:104550001049082818BF0428086803BF20F46C50CD
+:1045600040F4444040F0004020F0004008607047B4
+:104570000C1500401015004050160040683602002F
+:10458000A2240200D0FB010030D301000436020057
+:10459000C0D40100401700402DE9FE430C46804680
+:1045A000F8F7B4FF074698F80160204601A96A466B
+:1045B000ECF717F905000DD0012F02D00320BDE85C
+:1045C000FE83204602AA0199ECF72DF80298B0F874
+:1045D00003000AE0022F14D1042E12D3B8F803000E
+:1045E000BDF80020011D914204D8001D80B2A91918
+:1045F000814202D14FF00000E1E702D24FF001000A
+:10460000DDE74FF00200DAE70B4A022111600B49A7
+:104610000B68002BFCD0084B1B1D18600868002895
+:10462000FCD00020106008680028FCD070474FF0D4
+:10463000805040697047000004E5014000E40140FB
+:1046400002000B464FF00000014620D0012A04D0A2
+:10465000022A04D0032A0DD103E0012002E0022047
+:1046600015E00320072B05D2DFE803F00406080A53
+:104670000C0E100007207047012108E0022106E01F
+:10468000032104E0042102E0052100E00621EEF709
+:10469000BEBB0000F9480521817000210170417006
+:1046A0007047F7490A78012A05D0CA681044C860E3
+:1046B0004038EFF7E4B88A6810448860F8E70028CB
+:1046C00019D00378EF49F04A13B1012B0ED011E055
+:1046D0000379012B00D06BB943790BB1012B09D1C0
+:1046E0008368643B8B4205D2C0680EE00379012BDE
+:1046F00002D00BB10020704743790BB1012BF9D1E7
+:10470000C368643B8B42F5D280689042F2D80120A6
+:104710007047DB4910B501220A700279A2B100226C
+:104720000A71427992B104224A718268D34C5232A2
+:104730008A60C0681434C8606060EEF7C5FBCF497A
+:1047400020600220887010BD0322E9E70322EBE716
+:1047500070B5044609B1012000E00320C84D0021D6
+:104760002970217901B100202871607968B1042095
+:10477000C24E6871A168F068EEF7AFF8A860E06813
+:104780005230E8600320B07070BD0320F0E72DE9DF
+:10479000F04105460226EEF79EFF006800B1FFDFFC
+:1047A000B64C01273DB12878B0B1012805D00228C8
+:1047B00010D0032813D027710CE06868C82807D3ED
+:1047C000EFF7C3F820B16868FFF76BFF012603E03D
+:1047D000002601E000F05CF93046BDE8F081207869
+:1047E0000028F7D16868FFF76AFF0028E3D06868FF
+:1047F000017879B1A078042800D0FFDF0121686832
+:10480000FFF7A6FF9E49E078EEF7A6FD0028E1D16C
+:10481000FFDFDFE7FFF77DFF6770DBE72DE9F0479C
+:10482000964C8846E178884200D0FFDFDFF84C9252
+:1048300000250127924E09F11409B8F1080F75D22D
+:10484000DFE808F0040C28527A808D95A0780328C0
+:1048500002D0022800D0FFDFBDE8F087A07803284F
+:1048600002D0022800D0FFDF0420A070257120783C
+:10487000002878D1FFF715FF3078012806D0B068FE
+:10488000E06000F025F92061002060E0E078EEF7BC
+:1048900060FCF5E7A078032802D0022800D0FFDFF3
+:1048A000207800286DD1A078032816D0EEF70CFBF5
+:1048B00001464F46D9F80000EFF714F800280EDB48
+:1048C000796881420BDB081AF0606D49E078EEF7F9
+:1048D00043FD0028C0D1FFDFBEE7042028E004200C
+:1048E000EFF7B3FAA570B7E7A078032802D0022843
+:1048F00000D0FFDF207888BBA078032817D0EEF720
+:10490000E3FA01464F46D9F80000EEF7EBFF002826
+:10491000E5DB79688142E2DB081AF0605849E0780B
+:10492000EEF71AFD002897D1FFDF95E740E005205C
+:10493000EFF78BFAA7708FE7A078042800D0FFDF8D
+:10494000022004E0A078042800D0FFDF0120A16845
+:104950008847FFF71CFF054630E004E011E0A0782F
+:10496000042800D0FFDFBDE8F04700F091B8A07840
+:10497000042804D0617809B1022800D0FFDF207834
+:1049800018B1BDE8F04700F08CB8207920B10620BE
+:10499000EFF75BFA2571CDE7607838B13849E078F8
+:1049A000EEF7DAFC00B9FFDF657055E70720BFE7D7
+:1049B000FFDF51E73DB1012D03D0FFDF022DF9D11B
+:1049C0004AE70420C3E70320C1E770B5050004D01F
+:1049D0002A4CA078052806D101E0102070BD0820DF
+:1049E000EFF749FA08B1112070BD2848EEF7F3F946
+:1049F000E070202803D00020A560A07070BD0320C7
+:104A000070BD1E4810B5017809B1112010BD817824
+:104A1000052906D0012906D029B101210170002005
+:104A200010BD0F2010BD00F03CF8F8E770B5134C36
+:104A30000546A07808B1012809D155B12846FFF7ED
+:104A40003EFE40B1287840B1A078012809D00F205F
+:104A500070BD102070BD072070BD2846FFF759FEBD
+:104A600003E000212846FFF773FE0549E078EEF7E2
+:104A700073FC00B9FFDF002070BD0000BC01002006
+:104A8000CC1200203D860100FF1FA1071D48020037
+:104A90000A4810B5006900F013F8BDE81040EEF7C1
+:104AA0001FB9064810B5C078EEF7EFF900B9FFDF7F
+:104AB0000820EFF7CAF9BDE81040EBE5BC01002083
+:104AC0000C490A6848F202139A4302430A6070478D
+:104AD000084A116848F2021301EA03009943116081
+:104AE00070470246044B10201344FC2B01D8116080
+:104AF00000207047C80602400018FEBF40EA0103CC
+:104B000010B59B070FD1042A0DD310C808C9121F76
+:104B10009C42F8D020BA19BA884201D9012010BDB0
+:104B20004FF0FF3010BD1AB1D30703D0521C07E07D
+:104B3000002010BD10F8013B11F8014B1B1B07D1E1
+:104B400010F8013B11F8014B1B1B01D1921EF1D152
+:104B5000184610BD032A40F2308010F0030C00F01C
+:104B6000158011F8013BBCF1020F624498BF11F8A7
+:104B700001CB00F8013B38BF11F8013BA2F1040260
+:104B800098BF00F801CB38BF00F8013B11F00303D8
+:104B900000F02580083AC0F0088051F8043B083A3C
+:104BA00051F804CBA0E80810F5E7121D5CBF51F8DE
+:104BB000043B40F8043BAFF30080D20724BF11F858
+:104BC000013B11F801CB48BF11F8012B24BF00F8BD
+:104BD000013B00F801CB48BF00F8012B704710B52E
+:104BE000203AC0F00B80B1E81850203AA0E81850E5
+:104BF000B1E81850A0E81850BFF4F5AF5FEA027CA6
+:104C000024BFB1E81850A0E8185044BF18C918C014
+:104C1000BDE810405FEA827C24BF51F8043B40F8B5
+:104C2000043B08BF7047D20728BF31F8023B48BF9A
+:104C300011F8012B28BF20F8023B48BF00F8012BD8
+:104C4000704702F0FF0343EA032242EA024200F007
+:104C500002B84FF000020429C0F0128010F0030CDB
+:104C600000F01B80CCF1040CBCF1020F18BF00F85F
+:104C7000012BA8BF20F8022BA1EB0C0100F00DB80E
+:104C80005FEAC17C24BF00F8012B00F8012B48BF6C
+:104C900000F8012B70474FF0000200B51346944610
+:104CA0009646203922BFA0E80C50A0E80C50B1F184
+:104CB0002001BFF4F7AF090728BFA0E80C5048BF98
+:104CC0000CC05DF804EB890028BF40F8042B08BF36
+:104CD000704748BF20F8022B11F0804F18BF00F832
+:104CE000012B7047FEDF04207146084219D1069956
+:104CF000124A914215DC069902394878DF2810D112
+:104D00000878FE2807D0FF280BD14FF001004FF0A4
+:104D100000020B4B184741F201000099019A084B21
+:104D20001847084B002B02D01B68DB6818474FF070
+:104D3000FF3071464FF00002014B1847006002003F
+:104D4000E93F020004000020184819497047FFF7A6
+:104D5000FBFFDCF733FA00BD4FF4805015490968BA
+:104D6000884203D1144A13605B68184700BD0000F5
+:104D700020BFFDE74FF480500E490968884210D1EA
+:104D80000E4B18684FF0FF318842F1D080F308884D
+:104D90004FF02021884204DD0948026803210A43BC
+:104DA00002600848804708488047FFDFE012002083
+:104DB000E01200200000002004000020006002003B
+:104DC0001409004099460100594D02000420714623
+:104DD000084202D0EFF3098101E0EFF3088188690E
+:104DE00002380078102813DB20280FDB2C280BDB7F
+:104DF0000A4A12680A4B9A4203D1602804DB094A26
+:104E00001047022008607047074A1047074A1047BA
+:104E1000074A12682C32126810470000B0000020C8
+:104E2000BEBAFECA21130000613702007D410200B4
+:104E3000040000200D4B0E4908470E4B0C49084753
+:104E40000D4B0B4908470D4B094908470C4B0849C6
+:104E500008470C4B064908470B4B054908470B4BC5
+:104E6000034908470A4B02490847000051BB0000AC
+:104E70000D2F00006D2C0000092B0000972A000068
+:104E80000F2D00003D1300005328000029BE000034
+:104E9000C91100000021016001717047002101600B
+:104EA00081807047002101604160017270470A688B
+:104EB0004B6802604360B1F808C0A0F808C07047B2
+:104EC0000A6802600B79037170470000B995000011
+:104ED00043970000A1980000C5980000FF980000CB
+:104EE0003399000065990000959900000B9A000025
+:104EF00091960000A7120000A7120000794400005C
+:104F0000C5440000E94400007D45000099460000CA
+:104F10005B4700008D47000075480000074900000E
+:104F20005B490000414A0000614A0000DF150000B3
+:104F30000316000033150000871500003516000029
+:104F4000C91600006360000013620000E7650000FE
+:104F5000FD660000876700000568000069680000C2
+:104F60008D6900005D6A0000C96A0000834A000084
+:104F7000894A0000934A000089410000FB4A000072
+:104F80005D410000874C0000BF4C0000294D00002F
+:104F90000F4E0000254E0000A7120000A7120000CF
+:104FA000A7120000A7120000A7120000A71200001D
+:104FB000A7120000A7120000BF2400004525000032
+:104FC000612500007D2500000B270000A7250000BB
+:104FD000B1250000F325000015260000F126000091
+:104FE00033270000A7120000A7120000678300000B
+:104FF0008783000089830000CD830000FB830000CD
+:10500000E9840000778500008B850000D9850000C9
+:10501000C98600006F880000998900007B7300003A
+:10502000B1890000A7120000A7120000D1B400004F
+:105030003BB600008FB60000FBB60000ABB7000027
+:105040000100000000000000100110013A02000001
+:105050001A020000FB900000E9900000FFFFFFFF34
+:105060000000FFFFCDAC0000293D000065200000DE
+:10507000C5730000618E0000000000000000020007
+:10508000000000000002000000000000000100001D
+:105090000000000013810000F38000006181000027
+:1050A00041240000032400002324000037A800004E
+:1050B00063A800006BAA000059590000818100001C
+:1050C00000000000B18100008F24000000000000FB
+:1050D00000000000000000004DA9000000000000DA
+:1050E000ED59000000000000900A0000900A000046
+:1050F000DB560000DB5600005544000079AB000091
+:1051000047760000771F0000972602004F970100A6
+:10511000195700001957000077440000DBAB00006E
+:10512000CB760000E91F0000C5260200639701004E
+:1051300070017001400038005C002400480100024A
+:1051400000000300656C74620000000000000000B5
+:1051500000000000000000008700000000000000C8
+:105160000000000000000000BE83605ADB0B3760C7
+:1051700038A5F5AA9183886C010000003114010064
+:10518000F9220100000000010206030405000000EE
+:105190000700000000000000060000000A000000F8
+:1051A0003200000073000000B4000000C989010053
+:1051B00047150200616F0100D5B10100EBF4010059
+:1051C000D5B10100F77001008DB30100E1EE0100DF
+:1051D0008DB30100BF6D010021B3010001F4010096
+:1051E00021B301005D6F0100E9B101009DE70100FD
+:1051F000E9B10100ED74010001B601009DF5010067
+:1052000001B601000300000001555555D6BE898E38
+:105210000000C706C70CC71200006B030F06B308D7
+:105220000000B704A708970CF401FA009600640088
+:105230004B0032001E0014000A00050002000100AD
+:105240000041000000000000AAAED7AB15412010BD
+:105250000C0802170D0101020909010106020918D3
+:10526000180301010909030305000000FE00000006
+:10527000FE000000FE555555252627D6BE898E0016
+:10528000F401FA00960064004B0032001E00140086
+:105290000A00050002000100254100000000000096
+:1052A000493E0200613E0200793E0200913E02004A
+:1052B000C13E0200E93E0200133F0200473F0200E8
+:1052C000573B0200B73A0200AD370200E34A020042
+:1052D000E93B0200F93B0200253C0200433F01008C
+:1052E0004B3F01005D3F0100533C02006D3C02005A
+:1052F000413C02004B3C0200793C0200AF3C020002
+:10530000CF3C0200ED3C0200FB3C0200093D0200E4
+:10531000193D0200313D0200493D02005F3D02009F
+:10532000753D0200000000007FB90000D5B9000003
+:10533000EBB9000041460200D93702009F38020055
+:10534000CB490200034A02002D4A0200ED3D010054
+:105350006D4101008B3D0200B13D0200D53D0200D0
+:10536000FB3D02001C05004020050040001002002B
+:105370009053020008000020D001000044110000FA
+:10538000C8530200D801002008110000A01100003D
+:10539000011813C8140250201A0102227C2720FB96
+:1053A000349B5F801280021A10138B091B20480463
+:1053B0001ACE0401200B50A40AAC01300912CB63B1
+:0853C0007F010B68CC10A00076
+:00000001FF
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/softdevice/s212/headers/Readme.txt b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/softdevice/s212/headers/Readme.txt
new file mode 100644
index 0000000..81f49fc
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/softdevice/s212/headers/Readme.txt
@@ -0,0 +1 @@
+Place S212 SoftDevice header files in this folder. \ No newline at end of file
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/softdevice/s212/toolchain/armgcc/armgcc_s212_nrf52832_xxaa.ld b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/softdevice/s212/toolchain/armgcc/armgcc_s212_nrf52832_xxaa.ld
new file mode 100644
index 0000000..2d0a908
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/softdevice/s212/toolchain/armgcc/armgcc_s212_nrf52832_xxaa.ld
@@ -0,0 +1,33 @@
+/* Linker script to configure memory regions. */
+
+SEARCH_DIR(.)
+GROUP(-lgcc -lc -lnosys)
+
+MEMORY
+{
+ FLASH (rx) : ORIGIN = 0x12000, LENGTH = 0x6e000
+ RAM (rwx) : ORIGIN = 0x20000b80, LENGTH = 0xf480
+}
+
+SECTIONS
+{
+}
+
+SECTIONS
+{
+ . = ALIGN(4);
+ .mem_section_dummy_ram :
+ {
+ }
+
+} INSERT AFTER .data;
+
+SECTIONS
+{
+ .mem_section_dummy_rom :
+ {
+ }
+
+} INSERT AFTER .text
+
+INCLUDE "nrf_common.ld"
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/softdevice/s212/toolchain/iar/iar_s212_nrf52832_xxaa.icf b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/softdevice/s212/toolchain/iar/iar_s212_nrf52832_xxaa.icf
new file mode 100644
index 0000000..a5dbe99
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/softdevice/s212/toolchain/iar/iar_s212_nrf52832_xxaa.icf
@@ -0,0 +1,36 @@
+/*###ICF### Section handled by ICF editor, don't touch! ****/
+/*-Editor annotation file-*/
+/* IcfEditorFile="$TOOLKIT_DIR$\config\ide\IcfEditor\cortex_v1_0.xml" */
+/*-Specials-*/
+define symbol __ICFEDIT_intvec_start__ = 0x12000;
+/*-Memory Regions-*/
+define symbol __ICFEDIT_region_ROM_start__ = 0x12000;
+define symbol __ICFEDIT_region_ROM_end__ = 0x7ffff;
+define symbol __ICFEDIT_region_RAM_start__ = 0x20000b80;
+define symbol __ICFEDIT_region_RAM_end__ = 0x2000ffff;
+export symbol __ICFEDIT_region_RAM_start__;
+export symbol __ICFEDIT_region_RAM_end__;
+/*-Sizes-*/
+define symbol __ICFEDIT_size_cstack__ = ;
+define symbol __ICFEDIT_size_heap__ = ;
+/**** End of ICF editor section. ###ICF###*/
+
+define memory mem with size = 4G;
+define region ROM_region = mem:[from __ICFEDIT_region_ROM_start__ to __ICFEDIT_region_ROM_end__];
+define region RAM_region = mem:[from __ICFEDIT_region_RAM_start__ to __ICFEDIT_region_RAM_end__];
+
+define block CSTACK with alignment = 8, size = __ICFEDIT_size_cstack__ { };
+define block HEAP with alignment = 8, size = __ICFEDIT_size_heap__ { };
+define block RO_END with alignment = 8, size = 0 { };
+
+initialize by copy { readwrite };
+do not initialize { section .noinit };
+
+keep { section .intvec };
+place at address mem:__ICFEDIT_intvec_start__ { readonly section .intvec };
+place in ROM_region { readonly,
+ block RO_END };
+place in RAM_region { readwrite,
+ block CSTACK,
+ block HEAP };
+
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/toolchain/arm/uicr_config.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/toolchain/arm/uicr_config.h
new file mode 100644
index 0000000..2e4d166
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/toolchain/arm/uicr_config.h
@@ -0,0 +1,114 @@
+/**
+ * Copyright (c) 2013 - 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, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, 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.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+ *
+ */
+
+/* Template files (including this one) are application specific and therefore expected to
+ be copied into the application project folder prior to its use! */
+
+#ifndef _UICR_CONFIG_H
+#define _UICR_CONFIG_H
+
+/*lint ++flb "Enter library region" */
+
+#include <stdint.h>
+
+/*
+ * Include this file in your project if you want to include in your compiled code files data
+ * for the User Information Configuration Registers (UICR) area; see nRF51 Series Reference
+ * Manual chapter User Information Configuration Registers. This file declares one variable
+ * per register of the UICR area and informs the linker where to place them. To include
+ * the desired value in the desired address, uncomment the variable with the proper address
+ * at the target area and update the assignment value.
+ *
+ * Please note that UICR values are stored in a reserved area of the flash and should only be
+ * stored into when downloading a hex file. Do not use these defined variables to store data
+ * at run time.
+ *
+ * Note as well that this file uses one non-standard attribute ("at"). It will only function
+ * with the ARMCC compiler toolset.
+ *
+ * Note that the hex file generated when this file is included will fail to download when using
+ * the standard download algorithm provided by Nordic. See example project "uicr_config_example"
+ * in any of the board example folders for an example of the recommended download method as well
+ * as the documentation that follows with the SDK. nrfjprog can be used as normal.
+ *
+ * Please note as well that if you are using a SoftDevice the UICR_CLENR0 address will
+ * already be in use. Do not uncomment that line.
+ */
+
+// const uint32_t UICR_CLENR0 __attribute__((at(0x10001000))) __attribute__((used)) = 0xFFFFFFFF; // WARNING: This address might be used by the SoftDevice. Use with care.
+// const uint32_t UICR_RBPCONF __attribute__((at(0x10001004))) __attribute__((used)) = 0xFFFFFFFF;
+// const uint32_t UICR_XTALFREQ __attribute__((at(0x10001008))) __attribute__((used)) = 0xFFFFFFFF;
+
+// const uint32_t UICR_ADDR_0x80 __attribute__((at(0x10001080))) __attribute__((used)) = 0xFFFFFFFF;
+// const uint32_t UICR_ADDR_0x84 __attribute__((at(0x10001084))) __attribute__((used)) = 0xFFFFFFFF;
+// const uint32_t UICR_ADDR_0x88 __attribute__((at(0x10001088))) __attribute__((used)) = 0xFFFFFFFF;
+// const uint32_t UICR_ADDR_0x8C __attribute__((at(0x1000108C))) __attribute__((used)) = 0xFFFFFFFF;
+// const uint32_t UICR_ADDR_0x90 __attribute__((at(0x10001090))) __attribute__((used)) = 0xFFFFFFFF;
+// const uint32_t UICR_ADDR_0x94 __attribute__((at(0x10001094))) __attribute__((used)) = 0xFFFFFFFF;
+// const uint32_t UICR_ADDR_0x98 __attribute__((at(0x10001098))) __attribute__((used)) = 0xFFFFFFFF;
+// const uint32_t UICR_ADDR_0x9C __attribute__((at(0x1000109C))) __attribute__((used)) = 0xFFFFFFFF;
+// const uint32_t UICR_ADDR_0xA0 __attribute__((at(0x100010A0))) __attribute__((used)) = 0xFFFFFFFF;
+// const uint32_t UICR_ADDR_0xA4 __attribute__((at(0x100010A4))) __attribute__((used)) = 0xFFFFFFFF;
+// const uint32_t UICR_ADDR_0xA8 __attribute__((at(0x100010A8))) __attribute__((used)) = 0xFFFFFFFF;
+// const uint32_t UICR_ADDR_0xAC __attribute__((at(0x100010AC))) __attribute__((used)) = 0xFFFFFFFF;
+// const uint32_t UICR_ADDR_0xB0 __attribute__((at(0x100010B0))) __attribute__((used)) = 0xFFFFFFFF;
+// const uint32_t UICR_ADDR_0xB4 __attribute__((at(0x100010B4))) __attribute__((used)) = 0xFFFFFFFF;
+// const uint32_t UICR_ADDR_0xB8 __attribute__((at(0x100010B8))) __attribute__((used)) = 0xFFFFFFFF;
+// const uint32_t UICR_ADDR_0xBC __attribute__((at(0x100010BC))) __attribute__((used)) = 0xFFFFFFFF;
+// const uint32_t UICR_ADDR_0xC0 __attribute__((at(0x100010C0))) __attribute__((used)) = 0xFFFFFFFF;
+// const uint32_t UICR_ADDR_0xC4 __attribute__((at(0x100010C4))) __attribute__((used)) = 0xFFFFFFFF;
+// const uint32_t UICR_ADDR_0xC8 __attribute__((at(0x100010C8))) __attribute__((used)) = 0xFFFFFFFF;
+// const uint32_t UICR_ADDR_0xCC __attribute__((at(0x100010CC))) __attribute__((used)) = 0xFFFFFFFF;
+// const uint32_t UICR_ADDR_0xD0 __attribute__((at(0x100010D0))) __attribute__((used)) = 0xFFFFFFFF;
+// const uint32_t UICR_ADDR_0xD4 __attribute__((at(0x100010D4))) __attribute__((used)) = 0xFFFFFFFF;
+// const uint32_t UICR_ADDR_0xD8 __attribute__((at(0x100010D8))) __attribute__((used)) = 0xFFFFFFFF;
+// const uint32_t UICR_ADDR_0xDC __attribute__((at(0x100010DC))) __attribute__((used)) = 0xFFFFFFFF;
+// const uint32_t UICR_ADDR_0xE0 __attribute__((at(0x100010E0))) __attribute__((used)) = 0xFFFFFFFF;
+// const uint32_t UICR_ADDR_0xE4 __attribute__((at(0x100010E4))) __attribute__((used)) = 0xFFFFFFFF;
+// const uint32_t UICR_ADDR_0xE8 __attribute__((at(0x100010E8))) __attribute__((used)) = 0xFFFFFFFF;
+// const uint32_t UICR_ADDR_0xEC __attribute__((at(0x100010EC))) __attribute__((used)) = 0xFFFFFFFF;
+// const uint32_t UICR_ADDR_0xF0 __attribute__((at(0x100010F0))) __attribute__((used)) = 0xFFFFFFFF;
+// const uint32_t UICR_ADDR_0xF4 __attribute__((at(0x100010F4))) __attribute__((used)) = 0xFFFFFFFF;
+// const uint32_t UICR_ADDR_0xF8 __attribute__((at(0x100010F8))) __attribute__((used)) = 0xFFFFFFFF;
+// const uint32_t UICR_ADDR_0xFC __attribute__((at(0x100010FC))) __attribute__((used)) = 0xFFFFFFFF;
+
+/*lint --flb "Leave library region" */
+
+#endif //_UICR_CONFIG_H
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/toolchain/cmsis/dsp/ARM/arm_cortexM4l_math.lib b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/toolchain/cmsis/dsp/ARM/arm_cortexM4l_math.lib
new file mode 100644
index 0000000..010715c
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/toolchain/cmsis/dsp/ARM/arm_cortexM4l_math.lib
Binary files differ
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/toolchain/cmsis/dsp/ARM/arm_cortexM4lf_math.lib b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/toolchain/cmsis/dsp/ARM/arm_cortexM4lf_math.lib
new file mode 100644
index 0000000..6336e06
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/toolchain/cmsis/dsp/ARM/arm_cortexM4lf_math.lib
Binary files differ
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/toolchain/cmsis/dsp/GCC/libarm_cortexM4l_math.a b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/toolchain/cmsis/dsp/GCC/libarm_cortexM4l_math.a
new file mode 100644
index 0000000..b1d6da7
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/toolchain/cmsis/dsp/GCC/libarm_cortexM4l_math.a
Binary files differ
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/toolchain/cmsis/dsp/GCC/libarm_cortexM4lf_math.a b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/toolchain/cmsis/dsp/GCC/libarm_cortexM4lf_math.a
new file mode 100644
index 0000000..1ad5280
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/toolchain/cmsis/dsp/GCC/libarm_cortexM4lf_math.a
Binary files differ
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/toolchain/cmsis/dsp/license.txt b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/toolchain/cmsis/dsp/license.txt
new file mode 100644
index 0000000..139c1ff
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/toolchain/cmsis/dsp/license.txt
@@ -0,0 +1,28 @@
+All pre-build libraries contained in the folders "ARM" and "GCC"
+are guided by the following license:
+
+Copyright (C) 2009-2014 ARM Limited.
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+ - Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ - 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.
+ - Neither the name of ARM 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 COPYRIGHT HOLDERS AND 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.
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/toolchain/cmsis/include/arm_common_tables.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/toolchain/cmsis/include/arm_common_tables.h
new file mode 100644
index 0000000..8742a56
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/toolchain/cmsis/include/arm_common_tables.h
@@ -0,0 +1,136 @@
+/* ----------------------------------------------------------------------
+* Copyright (C) 2010-2014 ARM Limited. All rights reserved.
+*
+* $Date: 19. October 2015
+* $Revision: V.1.4.5 a
+*
+* Project: CMSIS DSP Library
+* Title: arm_common_tables.h
+*
+* Description: This file has extern declaration for common tables like Bitreverse, reciprocal etc which are used across different functions
+*
+* Target Processor: Cortex-M4/Cortex-M3
+*
+* Redistribution and use in source and binary forms, with or without
+* modification, are permitted provided that the following conditions
+* are met:
+* - Redistributions of source code must retain the above copyright
+* notice, this list of conditions and the following disclaimer.
+* - 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.
+* - Neither the name of ARM LIMITED 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 OWNER 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.
+* -------------------------------------------------------------------- */
+
+#ifndef _ARM_COMMON_TABLES_H
+#define _ARM_COMMON_TABLES_H
+
+#include "arm_math.h"
+
+extern const uint16_t armBitRevTable[1024];
+extern const q15_t armRecipTableQ15[64];
+extern const q31_t armRecipTableQ31[64];
+/* extern const q31_t realCoefAQ31[1024]; */
+/* extern const q31_t realCoefBQ31[1024]; */
+extern const float32_t twiddleCoef_16[32];
+extern const float32_t twiddleCoef_32[64];
+extern const float32_t twiddleCoef_64[128];
+extern const float32_t twiddleCoef_128[256];
+extern const float32_t twiddleCoef_256[512];
+extern const float32_t twiddleCoef_512[1024];
+extern const float32_t twiddleCoef_1024[2048];
+extern const float32_t twiddleCoef_2048[4096];
+extern const float32_t twiddleCoef_4096[8192];
+#define twiddleCoef twiddleCoef_4096
+extern const q31_t twiddleCoef_16_q31[24];
+extern const q31_t twiddleCoef_32_q31[48];
+extern const q31_t twiddleCoef_64_q31[96];
+extern const q31_t twiddleCoef_128_q31[192];
+extern const q31_t twiddleCoef_256_q31[384];
+extern const q31_t twiddleCoef_512_q31[768];
+extern const q31_t twiddleCoef_1024_q31[1536];
+extern const q31_t twiddleCoef_2048_q31[3072];
+extern const q31_t twiddleCoef_4096_q31[6144];
+extern const q15_t twiddleCoef_16_q15[24];
+extern const q15_t twiddleCoef_32_q15[48];
+extern const q15_t twiddleCoef_64_q15[96];
+extern const q15_t twiddleCoef_128_q15[192];
+extern const q15_t twiddleCoef_256_q15[384];
+extern const q15_t twiddleCoef_512_q15[768];
+extern const q15_t twiddleCoef_1024_q15[1536];
+extern const q15_t twiddleCoef_2048_q15[3072];
+extern const q15_t twiddleCoef_4096_q15[6144];
+extern const float32_t twiddleCoef_rfft_32[32];
+extern const float32_t twiddleCoef_rfft_64[64];
+extern const float32_t twiddleCoef_rfft_128[128];
+extern const float32_t twiddleCoef_rfft_256[256];
+extern const float32_t twiddleCoef_rfft_512[512];
+extern const float32_t twiddleCoef_rfft_1024[1024];
+extern const float32_t twiddleCoef_rfft_2048[2048];
+extern const float32_t twiddleCoef_rfft_4096[4096];
+
+
+/* floating-point bit reversal tables */
+#define ARMBITREVINDEXTABLE__16_TABLE_LENGTH ((uint16_t)20 )
+#define ARMBITREVINDEXTABLE__32_TABLE_LENGTH ((uint16_t)48 )
+#define ARMBITREVINDEXTABLE__64_TABLE_LENGTH ((uint16_t)56 )
+#define ARMBITREVINDEXTABLE_128_TABLE_LENGTH ((uint16_t)208 )
+#define ARMBITREVINDEXTABLE_256_TABLE_LENGTH ((uint16_t)440 )
+#define ARMBITREVINDEXTABLE_512_TABLE_LENGTH ((uint16_t)448 )
+#define ARMBITREVINDEXTABLE1024_TABLE_LENGTH ((uint16_t)1800)
+#define ARMBITREVINDEXTABLE2048_TABLE_LENGTH ((uint16_t)3808)
+#define ARMBITREVINDEXTABLE4096_TABLE_LENGTH ((uint16_t)4032)
+
+extern const uint16_t armBitRevIndexTable16[ARMBITREVINDEXTABLE__16_TABLE_LENGTH];
+extern const uint16_t armBitRevIndexTable32[ARMBITREVINDEXTABLE__32_TABLE_LENGTH];
+extern const uint16_t armBitRevIndexTable64[ARMBITREVINDEXTABLE__64_TABLE_LENGTH];
+extern const uint16_t armBitRevIndexTable128[ARMBITREVINDEXTABLE_128_TABLE_LENGTH];
+extern const uint16_t armBitRevIndexTable256[ARMBITREVINDEXTABLE_256_TABLE_LENGTH];
+extern const uint16_t armBitRevIndexTable512[ARMBITREVINDEXTABLE_512_TABLE_LENGTH];
+extern const uint16_t armBitRevIndexTable1024[ARMBITREVINDEXTABLE1024_TABLE_LENGTH];
+extern const uint16_t armBitRevIndexTable2048[ARMBITREVINDEXTABLE2048_TABLE_LENGTH];
+extern const uint16_t armBitRevIndexTable4096[ARMBITREVINDEXTABLE4096_TABLE_LENGTH];
+
+/* fixed-point bit reversal tables */
+#define ARMBITREVINDEXTABLE_FIXED___16_TABLE_LENGTH ((uint16_t)12 )
+#define ARMBITREVINDEXTABLE_FIXED___32_TABLE_LENGTH ((uint16_t)24 )
+#define ARMBITREVINDEXTABLE_FIXED___64_TABLE_LENGTH ((uint16_t)56 )
+#define ARMBITREVINDEXTABLE_FIXED__128_TABLE_LENGTH ((uint16_t)112 )
+#define ARMBITREVINDEXTABLE_FIXED__256_TABLE_LENGTH ((uint16_t)240 )
+#define ARMBITREVINDEXTABLE_FIXED__512_TABLE_LENGTH ((uint16_t)480 )
+#define ARMBITREVINDEXTABLE_FIXED_1024_TABLE_LENGTH ((uint16_t)992 )
+#define ARMBITREVINDEXTABLE_FIXED_2048_TABLE_LENGTH ((uint16_t)1984)
+#define ARMBITREVINDEXTABLE_FIXED_4096_TABLE_LENGTH ((uint16_t)4032)
+
+extern const uint16_t armBitRevIndexTable_fixed_16[ARMBITREVINDEXTABLE_FIXED___16_TABLE_LENGTH];
+extern const uint16_t armBitRevIndexTable_fixed_32[ARMBITREVINDEXTABLE_FIXED___32_TABLE_LENGTH];
+extern const uint16_t armBitRevIndexTable_fixed_64[ARMBITREVINDEXTABLE_FIXED___64_TABLE_LENGTH];
+extern const uint16_t armBitRevIndexTable_fixed_128[ARMBITREVINDEXTABLE_FIXED__128_TABLE_LENGTH];
+extern const uint16_t armBitRevIndexTable_fixed_256[ARMBITREVINDEXTABLE_FIXED__256_TABLE_LENGTH];
+extern const uint16_t armBitRevIndexTable_fixed_512[ARMBITREVINDEXTABLE_FIXED__512_TABLE_LENGTH];
+extern const uint16_t armBitRevIndexTable_fixed_1024[ARMBITREVINDEXTABLE_FIXED_1024_TABLE_LENGTH];
+extern const uint16_t armBitRevIndexTable_fixed_2048[ARMBITREVINDEXTABLE_FIXED_2048_TABLE_LENGTH];
+extern const uint16_t armBitRevIndexTable_fixed_4096[ARMBITREVINDEXTABLE_FIXED_4096_TABLE_LENGTH];
+
+/* Tables for Fast Math Sine and Cosine */
+extern const float32_t sinTable_f32[FAST_MATH_TABLE_SIZE + 1];
+extern const q31_t sinTable_q31[FAST_MATH_TABLE_SIZE + 1];
+extern const q15_t sinTable_q15[FAST_MATH_TABLE_SIZE + 1];
+
+#endif /* ARM_COMMON_TABLES_H */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/toolchain/cmsis/include/arm_const_structs.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/toolchain/cmsis/include/arm_const_structs.h
new file mode 100644
index 0000000..726d06e
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/toolchain/cmsis/include/arm_const_structs.h
@@ -0,0 +1,79 @@
+/* ----------------------------------------------------------------------
+* Copyright (C) 2010-2014 ARM Limited. All rights reserved.
+*
+* $Date: 19. March 2015
+* $Revision: V.1.4.5
+*
+* Project: CMSIS DSP Library
+* Title: arm_const_structs.h
+*
+* Description: This file has constant structs that are initialized for
+* user convenience. For example, some can be given as
+* arguments to the arm_cfft_f32() function.
+*
+* Target Processor: Cortex-M4/Cortex-M3
+*
+* Redistribution and use in source and binary forms, with or without
+* modification, are permitted provided that the following conditions
+* are met:
+* - Redistributions of source code must retain the above copyright
+* notice, this list of conditions and the following disclaimer.
+* - 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.
+* - Neither the name of ARM LIMITED 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 OWNER 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.
+* -------------------------------------------------------------------- */
+
+#ifndef _ARM_CONST_STRUCTS_H
+#define _ARM_CONST_STRUCTS_H
+
+#include "arm_math.h"
+#include "arm_common_tables.h"
+
+ extern const arm_cfft_instance_f32 arm_cfft_sR_f32_len16;
+ extern const arm_cfft_instance_f32 arm_cfft_sR_f32_len32;
+ extern const arm_cfft_instance_f32 arm_cfft_sR_f32_len64;
+ extern const arm_cfft_instance_f32 arm_cfft_sR_f32_len128;
+ extern const arm_cfft_instance_f32 arm_cfft_sR_f32_len256;
+ extern const arm_cfft_instance_f32 arm_cfft_sR_f32_len512;
+ extern const arm_cfft_instance_f32 arm_cfft_sR_f32_len1024;
+ extern const arm_cfft_instance_f32 arm_cfft_sR_f32_len2048;
+ extern const arm_cfft_instance_f32 arm_cfft_sR_f32_len4096;
+
+ extern const arm_cfft_instance_q31 arm_cfft_sR_q31_len16;
+ extern const arm_cfft_instance_q31 arm_cfft_sR_q31_len32;
+ extern const arm_cfft_instance_q31 arm_cfft_sR_q31_len64;
+ extern const arm_cfft_instance_q31 arm_cfft_sR_q31_len128;
+ extern const arm_cfft_instance_q31 arm_cfft_sR_q31_len256;
+ extern const arm_cfft_instance_q31 arm_cfft_sR_q31_len512;
+ extern const arm_cfft_instance_q31 arm_cfft_sR_q31_len1024;
+ extern const arm_cfft_instance_q31 arm_cfft_sR_q31_len2048;
+ extern const arm_cfft_instance_q31 arm_cfft_sR_q31_len4096;
+
+ extern const arm_cfft_instance_q15 arm_cfft_sR_q15_len16;
+ extern const arm_cfft_instance_q15 arm_cfft_sR_q15_len32;
+ extern const arm_cfft_instance_q15 arm_cfft_sR_q15_len64;
+ extern const arm_cfft_instance_q15 arm_cfft_sR_q15_len128;
+ extern const arm_cfft_instance_q15 arm_cfft_sR_q15_len256;
+ extern const arm_cfft_instance_q15 arm_cfft_sR_q15_len512;
+ extern const arm_cfft_instance_q15 arm_cfft_sR_q15_len1024;
+ extern const arm_cfft_instance_q15 arm_cfft_sR_q15_len2048;
+ extern const arm_cfft_instance_q15 arm_cfft_sR_q15_len4096;
+
+#endif
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/toolchain/cmsis/include/arm_math.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/toolchain/cmsis/include/arm_math.h
new file mode 100644
index 0000000..e21a3cc
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/toolchain/cmsis/include/arm_math.h
@@ -0,0 +1,7030 @@
+/* ----------------------------------------------------------------------
+* Copyright (C) 2010-2015 ARM Limited. All rights reserved.
+*
+* $Date: 20. October 2015
+* $Revision: V1.4.5 b
+*
+* Project: CMSIS DSP Library
+* Title: arm_math.h
+*
+* Description: Public header file for CMSIS DSP Library
+*
+* Target Processor: Cortex-M7/Cortex-M4/Cortex-M3/Cortex-M0
+*
+* Redistribution and use in source and binary forms, with or without
+* modification, are permitted provided that the following conditions
+* are met:
+* - Redistributions of source code must retain the above copyright
+* notice, this list of conditions and the following disclaimer.
+* - 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.
+* - Neither the name of ARM LIMITED 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 OWNER 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.
+ * -------------------------------------------------------------------- */
+
+/**
+ * @defgroup groupMath Basic Math Functions
+ */
+
+/**
+ * @defgroup groupFastMath Fast Math Functions
+ * This set of functions provides a fast approximation to sine, cosine, and square root.
+ * As compared to most of the other functions in the CMSIS math library, the fast math functions
+ * operate on individual values and not arrays.
+ * There are separate functions for Q15, Q31, and floating-point data.
+ *
+ */
+
+/**
+ * @defgroup groupCmplxMath Complex Math Functions
+ * This set of functions operates on complex data vectors.
+ * The data in the complex arrays is stored in an interleaved fashion
+ * (real, imag, real, imag, ...).
+ * In the API functions, the number of samples in a complex array refers
+ * to the number of complex values; the array contains twice this number of
+ * real values.
+ */
+
+/**
+ * @defgroup groupFilters Filtering Functions
+ */
+
+/**
+ * @defgroup groupMatrix Matrix Functions
+ *
+ * This set of functions provides basic matrix math operations.
+ * The functions operate on matrix data structures. For example,
+ * the type
+ * definition for the floating-point matrix structure is shown
+ * below:
+ * <pre>
+ * typedef struct
+ * {
+ * uint16_t numRows; // number of rows of the matrix.
+ * uint16_t numCols; // number of columns of the matrix.
+ * float32_t *pData; // points to the data of the matrix.
+ * } arm_matrix_instance_f32;
+ * </pre>
+ * There are similar definitions for Q15 and Q31 data types.
+ *
+ * The structure specifies the size of the matrix and then points to
+ * an array of data. The array is of size <code>numRows X numCols</code>
+ * and the values are arranged in row order. That is, the
+ * matrix element (i, j) is stored at:
+ * <pre>
+ * pData[i*numCols + j]
+ * </pre>
+ *
+ * \par Init Functions
+ * There is an associated initialization function for each type of matrix
+ * data structure.
+ * The initialization function sets the values of the internal structure fields.
+ * Refer to the function <code>arm_mat_init_f32()</code>, <code>arm_mat_init_q31()</code>
+ * and <code>arm_mat_init_q15()</code> for floating-point, Q31 and Q15 types, respectively.
+ *
+ * \par
+ * Use of the initialization function is optional. However, if initialization function is used
+ * then the instance structure cannot be placed into a const data section.
+ * To place the instance structure in a const data
+ * section, manually initialize the data structure. For example:
+ * <pre>
+ * <code>arm_matrix_instance_f32 S = {nRows, nColumns, pData};</code>
+ * <code>arm_matrix_instance_q31 S = {nRows, nColumns, pData};</code>
+ * <code>arm_matrix_instance_q15 S = {nRows, nColumns, pData};</code>
+ * </pre>
+ * where <code>nRows</code> specifies the number of rows, <code>nColumns</code>
+ * specifies the number of columns, and <code>pData</code> points to the
+ * data array.
+ *
+ * \par Size Checking
+ * By default all of the matrix functions perform size checking on the input and
+ * output matrices. For example, the matrix addition function verifies that the
+ * two input matrices and the output matrix all have the same number of rows and
+ * columns. If the size check fails the functions return:
+ * <pre>
+ * ARM_MATH_SIZE_MISMATCH
+ * </pre>
+ * Otherwise the functions return
+ * <pre>
+ * ARM_MATH_SUCCESS
+ * </pre>
+ * There is some overhead associated with this matrix size checking.
+ * The matrix size checking is enabled via the \#define
+ * <pre>
+ * ARM_MATH_MATRIX_CHECK
+ * </pre>
+ * within the library project settings. By default this macro is defined
+ * and size checking is enabled. By changing the project settings and
+ * undefining this macro size checking is eliminated and the functions
+ * run a bit faster. With size checking disabled the functions always
+ * return <code>ARM_MATH_SUCCESS</code>.
+ */
+
+/**
+ * @defgroup groupTransforms Transform Functions
+ */
+
+/**
+ * @defgroup groupController Controller Functions
+ */
+
+/**
+ * @defgroup groupStats Statistics Functions
+ */
+/**
+ * @defgroup groupSupport Support Functions
+ */
+
+/**
+ * @defgroup groupInterpolation Interpolation Functions
+ * These functions perform 1- and 2-dimensional interpolation of data.
+ * Linear interpolation is used for 1-dimensional data and
+ * bilinear interpolation is used for 2-dimensional data.
+ */
+
+/**
+ * @defgroup groupExamples Examples
+ */
+#ifndef _ARM_MATH_H
+#define _ARM_MATH_H
+
+/* ignore some GCC warnings */
+#if defined ( __GNUC__ )
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wsign-conversion"
+#pragma GCC diagnostic ignored "-Wconversion"
+#pragma GCC diagnostic ignored "-Wunused-parameter"
+#endif
+
+#define __CMSIS_GENERIC /* disable NVIC and Systick functions */
+
+#if defined(ARM_MATH_CM7)
+ #include "core_cm7.h"
+#elif defined (ARM_MATH_CM4)
+ #include "core_cm4.h"
+#elif defined (ARM_MATH_CM3)
+ #include "core_cm3.h"
+#elif defined (ARM_MATH_CM0)
+ #include "core_cm0.h"
+ #define ARM_MATH_CM0_FAMILY
+#elif defined (ARM_MATH_CM0PLUS)
+ #include "core_cm0plus.h"
+ #define ARM_MATH_CM0_FAMILY
+#else
+ #error "Define according the used Cortex core ARM_MATH_CM7, ARM_MATH_CM4, ARM_MATH_CM3, ARM_MATH_CM0PLUS or ARM_MATH_CM0"
+#endif
+
+#undef __CMSIS_GENERIC /* enable NVIC and Systick functions */
+#include "string.h"
+#include "math.h"
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+
+ /**
+ * @brief Macros required for reciprocal calculation in Normalized LMS
+ */
+
+#define DELTA_Q31 (0x100)
+#define DELTA_Q15 0x5
+#define INDEX_MASK 0x0000003F
+#ifndef PI
+#define PI 3.14159265358979f
+#endif
+
+ /**
+ * @brief Macros required for SINE and COSINE Fast math approximations
+ */
+
+#define FAST_MATH_TABLE_SIZE 512
+#define FAST_MATH_Q31_SHIFT (32 - 10)
+#define FAST_MATH_Q15_SHIFT (16 - 10)
+#define CONTROLLER_Q31_SHIFT (32 - 9)
+#define TABLE_SIZE 256
+#define TABLE_SPACING_Q31 0x400000
+#define TABLE_SPACING_Q15 0x80
+
+ /**
+ * @brief Macros required for SINE and COSINE Controller functions
+ */
+ /* 1.31(q31) Fixed value of 2/360 */
+ /* -1 to +1 is divided into 360 values so total spacing is (2/360) */
+#define INPUT_SPACING 0xB60B61
+
+ /**
+ * @brief Macro for Unaligned Support
+ */
+#ifndef UNALIGNED_SUPPORT_DISABLE
+ #define ALIGN4
+#else
+ #if defined (__GNUC__)
+ #define ALIGN4 __attribute__((aligned(4)))
+ #else
+ #define ALIGN4 __align(4)
+ #endif
+#endif /* #ifndef UNALIGNED_SUPPORT_DISABLE */
+
+ /**
+ * @brief Error status returned by some functions in the library.
+ */
+
+ typedef enum
+ {
+ ARM_MATH_SUCCESS = 0, /**< No error */
+ ARM_MATH_ARGUMENT_ERROR = -1, /**< One or more arguments are incorrect */
+ ARM_MATH_LENGTH_ERROR = -2, /**< Length of data buffer is incorrect */
+ ARM_MATH_SIZE_MISMATCH = -3, /**< Size of matrices is not compatible with the operation. */
+ ARM_MATH_NANINF = -4, /**< Not-a-number (NaN) or infinity is generated */
+ ARM_MATH_SINGULAR = -5, /**< Generated by matrix inversion if the input matrix is singular and cannot be inverted. */
+ ARM_MATH_TEST_FAILURE = -6 /**< Test Failed */
+ } arm_status;
+
+ /**
+ * @brief 8-bit fractional data type in 1.7 format.
+ */
+ typedef int8_t q7_t;
+
+ /**
+ * @brief 16-bit fractional data type in 1.15 format.
+ */
+ typedef int16_t q15_t;
+
+ /**
+ * @brief 32-bit fractional data type in 1.31 format.
+ */
+ typedef int32_t q31_t;
+
+ /**
+ * @brief 64-bit fractional data type in 1.63 format.
+ */
+ typedef int64_t q63_t;
+
+ /**
+ * @brief 32-bit floating-point type definition.
+ */
+ typedef float float32_t;
+
+ /**
+ * @brief 64-bit floating-point type definition.
+ */
+ typedef double float64_t;
+
+ /**
+ * @brief definition to read/write two 16 bit values.
+ */
+#if defined __CC_ARM
+ #define __SIMD32_TYPE int32_t __packed
+ #define CMSIS_UNUSED __attribute__((unused))
+
+#elif defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050)
+ #define __SIMD32_TYPE int32_t
+ #define CMSIS_UNUSED __attribute__((unused))
+
+#elif defined __GNUC__
+ #define __SIMD32_TYPE int32_t
+ #define CMSIS_UNUSED __attribute__((unused))
+
+#elif defined __ICCARM__
+ #define __SIMD32_TYPE int32_t __packed
+ #define CMSIS_UNUSED
+
+#elif defined __CSMC__
+ #define __SIMD32_TYPE int32_t
+ #define CMSIS_UNUSED
+
+#elif defined __TASKING__
+ #define __SIMD32_TYPE __unaligned int32_t
+ #define CMSIS_UNUSED
+
+#else
+ #error Unknown compiler
+#endif
+
+#define __SIMD32(addr) (*(__SIMD32_TYPE **) & (addr))
+#define __SIMD32_CONST(addr) ((__SIMD32_TYPE *)(addr))
+#define _SIMD32_OFFSET(addr) (*(__SIMD32_TYPE *) (addr))
+#define __SIMD64(addr) (*(int64_t **) & (addr))
+
+#if defined (ARM_MATH_CM3) || defined (ARM_MATH_CM0_FAMILY)
+ /**
+ * @brief definition to pack two 16 bit values.
+ */
+#define __PKHBT(ARG1, ARG2, ARG3) ( (((int32_t)(ARG1) << 0) & (int32_t)0x0000FFFF) | \
+ (((int32_t)(ARG2) << ARG3) & (int32_t)0xFFFF0000) )
+#define __PKHTB(ARG1, ARG2, ARG3) ( (((int32_t)(ARG1) << 0) & (int32_t)0xFFFF0000) | \
+ (((int32_t)(ARG2) >> ARG3) & (int32_t)0x0000FFFF) )
+
+#endif
+
+
+ /**
+ * @brief definition to pack four 8 bit values.
+ */
+#ifndef ARM_MATH_BIG_ENDIAN
+
+#define __PACKq7(v0,v1,v2,v3) ( (((int32_t)(v0) << 0) & (int32_t)0x000000FF) | \
+ (((int32_t)(v1) << 8) & (int32_t)0x0000FF00) | \
+ (((int32_t)(v2) << 16) & (int32_t)0x00FF0000) | \
+ (((int32_t)(v3) << 24) & (int32_t)0xFF000000) )
+#else
+
+#define __PACKq7(v0,v1,v2,v3) ( (((int32_t)(v3) << 0) & (int32_t)0x000000FF) | \
+ (((int32_t)(v2) << 8) & (int32_t)0x0000FF00) | \
+ (((int32_t)(v1) << 16) & (int32_t)0x00FF0000) | \
+ (((int32_t)(v0) << 24) & (int32_t)0xFF000000) )
+
+#endif
+
+
+ /**
+ * @brief Clips Q63 to Q31 values.
+ */
+ static __INLINE q31_t clip_q63_to_q31(
+ q63_t x)
+ {
+ return ((q31_t) (x >> 32) != ((q31_t) x >> 31)) ?
+ ((0x7FFFFFFF ^ ((q31_t) (x >> 63)))) : (q31_t) x;
+ }
+
+ /**
+ * @brief Clips Q63 to Q15 values.
+ */
+ static __INLINE q15_t clip_q63_to_q15(
+ q63_t x)
+ {
+ return ((q31_t) (x >> 32) != ((q31_t) x >> 31)) ?
+ ((0x7FFF ^ ((q15_t) (x >> 63)))) : (q15_t) (x >> 15);
+ }
+
+ /**
+ * @brief Clips Q31 to Q7 values.
+ */
+ static __INLINE q7_t clip_q31_to_q7(
+ q31_t x)
+ {
+ return ((q31_t) (x >> 24) != ((q31_t) x >> 23)) ?
+ ((0x7F ^ ((q7_t) (x >> 31)))) : (q7_t) x;
+ }
+
+ /**
+ * @brief Clips Q31 to Q15 values.
+ */
+ static __INLINE q15_t clip_q31_to_q15(
+ q31_t x)
+ {
+ return ((q31_t) (x >> 16) != ((q31_t) x >> 15)) ?
+ ((0x7FFF ^ ((q15_t) (x >> 31)))) : (q15_t) x;
+ }
+
+ /**
+ * @brief Multiplies 32 X 64 and returns 32 bit result in 2.30 format.
+ */
+
+ static __INLINE q63_t mult32x64(
+ q63_t x,
+ q31_t y)
+ {
+ return ((((q63_t) (x & 0x00000000FFFFFFFF) * y) >> 32) +
+ (((q63_t) (x >> 32) * y)));
+ }
+
+/*
+ #if defined (ARM_MATH_CM0_FAMILY) && defined ( __CC_ARM )
+ #define __CLZ __clz
+ #endif
+ */
+/* note: function can be removed when all toolchain support __CLZ for Cortex-M0 */
+#if defined (ARM_MATH_CM0_FAMILY) && ((defined (__ICCARM__)) )
+ static __INLINE uint32_t __CLZ(
+ q31_t data);
+
+ static __INLINE uint32_t __CLZ(
+ q31_t data)
+ {
+ uint32_t count = 0;
+ uint32_t mask = 0x80000000;
+
+ while ((data & mask) == 0)
+ {
+ count += 1u;
+ mask = mask >> 1u;
+ }
+
+ return (count);
+ }
+#endif
+
+ /**
+ * @brief Function to Calculates 1/in (reciprocal) value of Q31 Data type.
+ */
+
+ static __INLINE uint32_t arm_recip_q31(
+ q31_t in,
+ q31_t * dst,
+ q31_t * pRecipTable)
+ {
+ q31_t out;
+ uint32_t tempVal;
+ uint32_t index, i;
+ uint32_t signBits;
+
+ if (in > 0)
+ {
+ signBits = ((uint32_t) (__CLZ( in) - 1));
+ }
+ else
+ {
+ signBits = ((uint32_t) (__CLZ(-in) - 1));
+ }
+
+ /* Convert input sample to 1.31 format */
+ in = (in << signBits);
+
+ /* calculation of index for initial approximated Val */
+ index = (uint32_t)(in >> 24);
+ index = (index & INDEX_MASK);
+
+ /* 1.31 with exp 1 */
+ out = pRecipTable[index];
+
+ /* calculation of reciprocal value */
+ /* running approximation for two iterations */
+ for (i = 0u; i < 2u; i++)
+ {
+ tempVal = (uint32_t) (((q63_t) in * out) >> 31);
+ tempVal = 0x7FFFFFFFu - tempVal;
+ /* 1.31 with exp 1 */
+ /* out = (q31_t) (((q63_t) out * tempVal) >> 30); */
+ out = clip_q63_to_q31(((q63_t) out * tempVal) >> 30);
+ }
+
+ /* write output */
+ *dst = out;
+
+ /* return num of signbits of out = 1/in value */
+ return (signBits + 1u);
+ }
+
+
+ /**
+ * @brief Function to Calculates 1/in (reciprocal) value of Q15 Data type.
+ */
+ static __INLINE uint32_t arm_recip_q15(
+ q15_t in,
+ q15_t * dst,
+ q15_t * pRecipTable)
+ {
+ q15_t out = 0;
+ uint32_t tempVal = 0;
+ uint32_t index = 0, i = 0;
+ uint32_t signBits = 0;
+
+ if (in > 0)
+ {
+ signBits = ((uint32_t)(__CLZ( in) - 17));
+ }
+ else
+ {
+ signBits = ((uint32_t)(__CLZ(-in) - 17));
+ }
+
+ /* Convert input sample to 1.15 format */
+ in = (in << signBits);
+
+ /* calculation of index for initial approximated Val */
+ index = (uint32_t)(in >> 8);
+ index = (index & INDEX_MASK);
+
+ /* 1.15 with exp 1 */
+ out = pRecipTable[index];
+
+ /* calculation of reciprocal value */
+ /* running approximation for two iterations */
+ for (i = 0u; i < 2u; i++)
+ {
+ tempVal = (uint32_t) (((q31_t) in * out) >> 15);
+ tempVal = 0x7FFFu - tempVal;
+ /* 1.15 with exp 1 */
+ out = (q15_t) (((q31_t) out * tempVal) >> 14);
+ /* out = clip_q31_to_q15(((q31_t) out * tempVal) >> 14); */
+ }
+
+ /* write output */
+ *dst = out;
+
+ /* return num of signbits of out = 1/in value */
+ return (signBits + 1);
+ }
+
+
+ /*
+ * @brief C custom defined intrinisic function for only M0 processors
+ */
+#if defined(ARM_MATH_CM0_FAMILY)
+ static __INLINE q31_t __SSAT(
+ q31_t x,
+ uint32_t y)
+ {
+ int32_t posMax, negMin;
+ uint32_t i;
+
+ posMax = 1;
+ for (i = 0; i < (y - 1); i++)
+ {
+ posMax = posMax * 2;
+ }
+
+ if (x > 0)
+ {
+ posMax = (posMax - 1);
+
+ if (x > posMax)
+ {
+ x = posMax;
+ }
+ }
+ else
+ {
+ negMin = -posMax;
+
+ if (x < negMin)
+ {
+ x = negMin;
+ }
+ }
+ return (x);
+ }
+#endif /* end of ARM_MATH_CM0_FAMILY */
+
+
+ /*
+ * @brief C custom defined intrinsic function for M3 and M0 processors
+ */
+#if defined (ARM_MATH_CM3) || defined (ARM_MATH_CM0_FAMILY)
+
+ /*
+ * @brief C custom defined QADD8 for M3 and M0 processors
+ */
+ static __INLINE uint32_t __QADD8(
+ uint32_t x,
+ uint32_t y)
+ {
+ q31_t r, s, t, u;
+
+ r = __SSAT(((((q31_t)x << 24) >> 24) + (((q31_t)y << 24) >> 24)), 8) & (int32_t)0x000000FF;
+ s = __SSAT(((((q31_t)x << 16) >> 24) + (((q31_t)y << 16) >> 24)), 8) & (int32_t)0x000000FF;
+ t = __SSAT(((((q31_t)x << 8) >> 24) + (((q31_t)y << 8) >> 24)), 8) & (int32_t)0x000000FF;
+ u = __SSAT(((((q31_t)x ) >> 24) + (((q31_t)y ) >> 24)), 8) & (int32_t)0x000000FF;
+
+ return ((uint32_t)((u << 24) | (t << 16) | (s << 8) | (r )));
+ }
+
+
+ /*
+ * @brief C custom defined QSUB8 for M3 and M0 processors
+ */
+ static __INLINE uint32_t __QSUB8(
+ uint32_t x,
+ uint32_t y)
+ {
+ q31_t r, s, t, u;
+
+ r = __SSAT(((((q31_t)x << 24) >> 24) - (((q31_t)y << 24) >> 24)), 8) & (int32_t)0x000000FF;
+ s = __SSAT(((((q31_t)x << 16) >> 24) - (((q31_t)y << 16) >> 24)), 8) & (int32_t)0x000000FF;
+ t = __SSAT(((((q31_t)x << 8) >> 24) - (((q31_t)y << 8) >> 24)), 8) & (int32_t)0x000000FF;
+ u = __SSAT(((((q31_t)x ) >> 24) - (((q31_t)y ) >> 24)), 8) & (int32_t)0x000000FF;
+
+ return ((uint32_t)((u << 24) | (t << 16) | (s << 8) | (r )));
+ }
+
+
+ /*
+ * @brief C custom defined QADD16 for M3 and M0 processors
+ */
+ static __INLINE uint32_t __QADD16(
+ uint32_t x,
+ uint32_t y)
+ {
+/* q31_t r, s; without initialisation 'arm_offset_q15 test' fails but 'intrinsic' tests pass! for armCC */
+ q31_t r = 0, s = 0;
+
+ r = __SSAT(((((q31_t)x << 16) >> 16) + (((q31_t)y << 16) >> 16)), 16) & (int32_t)0x0000FFFF;
+ s = __SSAT(((((q31_t)x ) >> 16) + (((q31_t)y ) >> 16)), 16) & (int32_t)0x0000FFFF;
+
+ return ((uint32_t)((s << 16) | (r )));
+ }
+
+
+ /*
+ * @brief C custom defined SHADD16 for M3 and M0 processors
+ */
+ static __INLINE uint32_t __SHADD16(
+ uint32_t x,
+ uint32_t y)
+ {
+ q31_t r, s;
+
+ r = (((((q31_t)x << 16) >> 16) + (((q31_t)y << 16) >> 16)) >> 1) & (int32_t)0x0000FFFF;
+ s = (((((q31_t)x ) >> 16) + (((q31_t)y ) >> 16)) >> 1) & (int32_t)0x0000FFFF;
+
+ return ((uint32_t)((s << 16) | (r )));
+ }
+
+
+ /*
+ * @brief C custom defined QSUB16 for M3 and M0 processors
+ */
+ static __INLINE uint32_t __QSUB16(
+ uint32_t x,
+ uint32_t y)
+ {
+ q31_t r, s;
+
+ r = __SSAT(((((q31_t)x << 16) >> 16) - (((q31_t)y << 16) >> 16)), 16) & (int32_t)0x0000FFFF;
+ s = __SSAT(((((q31_t)x ) >> 16) - (((q31_t)y ) >> 16)), 16) & (int32_t)0x0000FFFF;
+
+ return ((uint32_t)((s << 16) | (r )));
+ }
+
+
+ /*
+ * @brief C custom defined SHSUB16 for M3 and M0 processors
+ */
+ static __INLINE uint32_t __SHSUB16(
+ uint32_t x,
+ uint32_t y)
+ {
+ q31_t r, s;
+
+ r = (((((q31_t)x << 16) >> 16) - (((q31_t)y << 16) >> 16)) >> 1) & (int32_t)0x0000FFFF;
+ s = (((((q31_t)x ) >> 16) - (((q31_t)y ) >> 16)) >> 1) & (int32_t)0x0000FFFF;
+
+ return ((uint32_t)((s << 16) | (r )));
+ }
+
+
+ /*
+ * @brief C custom defined QASX for M3 and M0 processors
+ */
+ static __INLINE uint32_t __QASX(
+ uint32_t x,
+ uint32_t y)
+ {
+ q31_t r, s;
+
+ r = __SSAT(((((q31_t)x << 16) >> 16) - (((q31_t)y ) >> 16)), 16) & (int32_t)0x0000FFFF;
+ s = __SSAT(((((q31_t)x ) >> 16) + (((q31_t)y << 16) >> 16)), 16) & (int32_t)0x0000FFFF;
+
+ return ((uint32_t)((s << 16) | (r )));
+ }
+
+
+ /*
+ * @brief C custom defined SHASX for M3 and M0 processors
+ */
+ static __INLINE uint32_t __SHASX(
+ uint32_t x,
+ uint32_t y)
+ {
+ q31_t r, s;
+
+ r = (((((q31_t)x << 16) >> 16) - (((q31_t)y ) >> 16)) >> 1) & (int32_t)0x0000FFFF;
+ s = (((((q31_t)x ) >> 16) + (((q31_t)y << 16) >> 16)) >> 1) & (int32_t)0x0000FFFF;
+
+ return ((uint32_t)((s << 16) | (r )));
+ }
+
+
+ /*
+ * @brief C custom defined QSAX for M3 and M0 processors
+ */
+ static __INLINE uint32_t __QSAX(
+ uint32_t x,
+ uint32_t y)
+ {
+ q31_t r, s;
+
+ r = __SSAT(((((q31_t)x << 16) >> 16) + (((q31_t)y ) >> 16)), 16) & (int32_t)0x0000FFFF;
+ s = __SSAT(((((q31_t)x ) >> 16) - (((q31_t)y << 16) >> 16)), 16) & (int32_t)0x0000FFFF;
+
+ return ((uint32_t)((s << 16) | (r )));
+ }
+
+
+ /*
+ * @brief C custom defined SHSAX for M3 and M0 processors
+ */
+ static __INLINE uint32_t __SHSAX(
+ uint32_t x,
+ uint32_t y)
+ {
+ q31_t r, s;
+
+ r = (((((q31_t)x << 16) >> 16) + (((q31_t)y ) >> 16)) >> 1) & (int32_t)0x0000FFFF;
+ s = (((((q31_t)x ) >> 16) - (((q31_t)y << 16) >> 16)) >> 1) & (int32_t)0x0000FFFF;
+
+ return ((uint32_t)((s << 16) | (r )));
+ }
+
+
+ /*
+ * @brief C custom defined SMUSDX for M3 and M0 processors
+ */
+ static __INLINE uint32_t __SMUSDX(
+ uint32_t x,
+ uint32_t y)
+ {
+ return ((uint32_t)(((((q31_t)x << 16) >> 16) * (((q31_t)y ) >> 16)) -
+ ((((q31_t)x ) >> 16) * (((q31_t)y << 16) >> 16)) ));
+ }
+
+ /*
+ * @brief C custom defined SMUADX for M3 and M0 processors
+ */
+ static __INLINE uint32_t __SMUADX(
+ uint32_t x,
+ uint32_t y)
+ {
+ return ((uint32_t)(((((q31_t)x << 16) >> 16) * (((q31_t)y ) >> 16)) +
+ ((((q31_t)x ) >> 16) * (((q31_t)y << 16) >> 16)) ));
+ }
+
+
+ /*
+ * @brief C custom defined QADD for M3 and M0 processors
+ */
+ static __INLINE int32_t __QADD(
+ int32_t x,
+ int32_t y)
+ {
+ return ((int32_t)(clip_q63_to_q31((q63_t)x + (q31_t)y)));
+ }
+
+
+ /*
+ * @brief C custom defined QSUB for M3 and M0 processors
+ */
+ static __INLINE int32_t __QSUB(
+ int32_t x,
+ int32_t y)
+ {
+ return ((int32_t)(clip_q63_to_q31((q63_t)x - (q31_t)y)));
+ }
+
+
+ /*
+ * @brief C custom defined SMLAD for M3 and M0 processors
+ */
+ static __INLINE uint32_t __SMLAD(
+ uint32_t x,
+ uint32_t y,
+ uint32_t sum)
+ {
+ return ((uint32_t)(((((q31_t)x << 16) >> 16) * (((q31_t)y << 16) >> 16)) +
+ ((((q31_t)x ) >> 16) * (((q31_t)y ) >> 16)) +
+ ( ((q31_t)sum ) ) ));
+ }
+
+
+ /*
+ * @brief C custom defined SMLADX for M3 and M0 processors
+ */
+ static __INLINE uint32_t __SMLADX(
+ uint32_t x,
+ uint32_t y,
+ uint32_t sum)
+ {
+ return ((uint32_t)(((((q31_t)x << 16) >> 16) * (((q31_t)y ) >> 16)) +
+ ((((q31_t)x ) >> 16) * (((q31_t)y << 16) >> 16)) +
+ ( ((q31_t)sum ) ) ));
+ }
+
+
+ /*
+ * @brief C custom defined SMLSDX for M3 and M0 processors
+ */
+ static __INLINE uint32_t __SMLSDX(
+ uint32_t x,
+ uint32_t y,
+ uint32_t sum)
+ {
+ return ((uint32_t)(((((q31_t)x << 16) >> 16) * (((q31_t)y ) >> 16)) -
+ ((((q31_t)x ) >> 16) * (((q31_t)y << 16) >> 16)) +
+ ( ((q31_t)sum ) ) ));
+ }
+
+
+ /*
+ * @brief C custom defined SMLALD for M3 and M0 processors
+ */
+ static __INLINE uint64_t __SMLALD(
+ uint32_t x,
+ uint32_t y,
+ uint64_t sum)
+ {
+/* return (sum + ((q15_t) (x >> 16) * (q15_t) (y >> 16)) + ((q15_t) x * (q15_t) y)); */
+ return ((uint64_t)(((((q31_t)x << 16) >> 16) * (((q31_t)y << 16) >> 16)) +
+ ((((q31_t)x ) >> 16) * (((q31_t)y ) >> 16)) +
+ ( ((q63_t)sum ) ) ));
+ }
+
+
+ /*
+ * @brief C custom defined SMLALDX for M3 and M0 processors
+ */
+ static __INLINE uint64_t __SMLALDX(
+ uint32_t x,
+ uint32_t y,
+ uint64_t sum)
+ {
+/* return (sum + ((q15_t) (x >> 16) * (q15_t) y)) + ((q15_t) x * (q15_t) (y >> 16)); */
+ return ((uint64_t)(((((q31_t)x << 16) >> 16) * (((q31_t)y ) >> 16)) +
+ ((((q31_t)x ) >> 16) * (((q31_t)y << 16) >> 16)) +
+ ( ((q63_t)sum ) ) ));
+ }
+
+
+ /*
+ * @brief C custom defined SMUAD for M3 and M0 processors
+ */
+ static __INLINE uint32_t __SMUAD(
+ uint32_t x,
+ uint32_t y)
+ {
+ return ((uint32_t)(((((q31_t)x << 16) >> 16) * (((q31_t)y << 16) >> 16)) +
+ ((((q31_t)x ) >> 16) * (((q31_t)y ) >> 16)) ));
+ }
+
+
+ /*
+ * @brief C custom defined SMUSD for M3 and M0 processors
+ */
+ static __INLINE uint32_t __SMUSD(
+ uint32_t x,
+ uint32_t y)
+ {
+ return ((uint32_t)(((((q31_t)x << 16) >> 16) * (((q31_t)y << 16) >> 16)) -
+ ((((q31_t)x ) >> 16) * (((q31_t)y ) >> 16)) ));
+ }
+
+
+ /*
+ * @brief C custom defined SXTB16 for M3 and M0 processors
+ */
+ static __INLINE uint32_t __SXTB16(
+ uint32_t x)
+ {
+ return ((uint32_t)(((((q31_t)x << 24) >> 24) & (q31_t)0x0000FFFF) |
+ ((((q31_t)x << 8) >> 8) & (q31_t)0xFFFF0000) ));
+ }
+
+#endif /* defined (ARM_MATH_CM3) || defined (ARM_MATH_CM0_FAMILY) */
+
+
+ /**
+ * @brief Instance structure for the Q7 FIR filter.
+ */
+ typedef struct
+ {
+ uint16_t numTaps; /**< number of filter coefficients in the filter. */
+ q7_t *pState; /**< points to the state variable array. The array is of length numTaps + blockSize-1. */
+ q7_t *pCoeffs; /**< points to the coefficient array. The array is of length numTaps.*/
+ } arm_fir_instance_q7;
+
+ /**
+ * @brief Instance structure for the Q15 FIR filter.
+ */
+ typedef struct
+ {
+ uint16_t numTaps; /**< number of filter coefficients in the filter. */
+ q15_t *pState; /**< points to the state variable array. The array is of length numTaps + blockSize-1. */
+ q15_t *pCoeffs; /**< points to the coefficient array. The array is of length numTaps.*/
+ } arm_fir_instance_q15;
+
+ /**
+ * @brief Instance structure for the Q31 FIR filter.
+ */
+ typedef struct
+ {
+ uint16_t numTaps; /**< number of filter coefficients in the filter. */
+ q31_t *pState; /**< points to the state variable array. The array is of length numTaps + blockSize-1. */
+ q31_t *pCoeffs; /**< points to the coefficient array. The array is of length numTaps. */
+ } arm_fir_instance_q31;
+
+ /**
+ * @brief Instance structure for the floating-point FIR filter.
+ */
+ typedef struct
+ {
+ uint16_t numTaps; /**< number of filter coefficients in the filter. */
+ float32_t *pState; /**< points to the state variable array. The array is of length numTaps + blockSize-1. */
+ float32_t *pCoeffs; /**< points to the coefficient array. The array is of length numTaps. */
+ } arm_fir_instance_f32;
+
+
+ /**
+ * @brief Processing function for the Q7 FIR filter.
+ * @param[in] S points to an instance of the Q7 FIR filter structure.
+ * @param[in] pSrc points to the block of input data.
+ * @param[out] pDst points to the block of output data.
+ * @param[in] blockSize number of samples to process.
+ */
+ void arm_fir_q7(
+ const arm_fir_instance_q7 * S,
+ q7_t * pSrc,
+ q7_t * pDst,
+ uint32_t blockSize);
+
+
+ /**
+ * @brief Initialization function for the Q7 FIR filter.
+ * @param[in,out] S points to an instance of the Q7 FIR structure.
+ * @param[in] numTaps Number of filter coefficients in the filter.
+ * @param[in] pCoeffs points to the filter coefficients.
+ * @param[in] pState points to the state buffer.
+ * @param[in] blockSize number of samples that are processed.
+ */
+ void arm_fir_init_q7(
+ arm_fir_instance_q7 * S,
+ uint16_t numTaps,
+ q7_t * pCoeffs,
+ q7_t * pState,
+ uint32_t blockSize);
+
+
+ /**
+ * @brief Processing function for the Q15 FIR filter.
+ * @param[in] S points to an instance of the Q15 FIR structure.
+ * @param[in] pSrc points to the block of input data.
+ * @param[out] pDst points to the block of output data.
+ * @param[in] blockSize number of samples to process.
+ */
+ void arm_fir_q15(
+ const arm_fir_instance_q15 * S,
+ q15_t * pSrc,
+ q15_t * pDst,
+ uint32_t blockSize);
+
+
+ /**
+ * @brief Processing function for the fast Q15 FIR filter for Cortex-M3 and Cortex-M4.
+ * @param[in] S points to an instance of the Q15 FIR filter structure.
+ * @param[in] pSrc points to the block of input data.
+ * @param[out] pDst points to the block of output data.
+ * @param[in] blockSize number of samples to process.
+ */
+ void arm_fir_fast_q15(
+ const arm_fir_instance_q15 * S,
+ q15_t * pSrc,
+ q15_t * pDst,
+ uint32_t blockSize);
+
+
+ /**
+ * @brief Initialization function for the Q15 FIR filter.
+ * @param[in,out] S points to an instance of the Q15 FIR filter structure.
+ * @param[in] numTaps Number of filter coefficients in the filter. Must be even and greater than or equal to 4.
+ * @param[in] pCoeffs points to the filter coefficients.
+ * @param[in] pState points to the state buffer.
+ * @param[in] blockSize number of samples that are processed at a time.
+ * @return The function returns ARM_MATH_SUCCESS if initialization was successful or ARM_MATH_ARGUMENT_ERROR if
+ * <code>numTaps</code> is not a supported value.
+ */
+ arm_status arm_fir_init_q15(
+ arm_fir_instance_q15 * S,
+ uint16_t numTaps,
+ q15_t * pCoeffs,
+ q15_t * pState,
+ uint32_t blockSize);
+
+
+ /**
+ * @brief Processing function for the Q31 FIR filter.
+ * @param[in] S points to an instance of the Q31 FIR filter structure.
+ * @param[in] pSrc points to the block of input data.
+ * @param[out] pDst points to the block of output data.
+ * @param[in] blockSize number of samples to process.
+ */
+ void arm_fir_q31(
+ const arm_fir_instance_q31 * S,
+ q31_t * pSrc,
+ q31_t * pDst,
+ uint32_t blockSize);
+
+
+ /**
+ * @brief Processing function for the fast Q31 FIR filter for Cortex-M3 and Cortex-M4.
+ * @param[in] S points to an instance of the Q31 FIR structure.
+ * @param[in] pSrc points to the block of input data.
+ * @param[out] pDst points to the block of output data.
+ * @param[in] blockSize number of samples to process.
+ */
+ void arm_fir_fast_q31(
+ const arm_fir_instance_q31 * S,
+ q31_t * pSrc,
+ q31_t * pDst,
+ uint32_t blockSize);
+
+
+ /**
+ * @brief Initialization function for the Q31 FIR filter.
+ * @param[in,out] S points to an instance of the Q31 FIR structure.
+ * @param[in] numTaps Number of filter coefficients in the filter.
+ * @param[in] pCoeffs points to the filter coefficients.
+ * @param[in] pState points to the state buffer.
+ * @param[in] blockSize number of samples that are processed at a time.
+ */
+ void arm_fir_init_q31(
+ arm_fir_instance_q31 * S,
+ uint16_t numTaps,
+ q31_t * pCoeffs,
+ q31_t * pState,
+ uint32_t blockSize);
+
+
+ /**
+ * @brief Processing function for the floating-point FIR filter.
+ * @param[in] S points to an instance of the floating-point FIR structure.
+ * @param[in] pSrc points to the block of input data.
+ * @param[out] pDst points to the block of output data.
+ * @param[in] blockSize number of samples to process.
+ */
+ void arm_fir_f32(
+ const arm_fir_instance_f32 * S,
+ float32_t * pSrc,
+ float32_t * pDst,
+ uint32_t blockSize);
+
+
+ /**
+ * @brief Initialization function for the floating-point FIR filter.
+ * @param[in,out] S points to an instance of the floating-point FIR filter structure.
+ * @param[in] numTaps Number of filter coefficients in the filter.
+ * @param[in] pCoeffs points to the filter coefficients.
+ * @param[in] pState points to the state buffer.
+ * @param[in] blockSize number of samples that are processed at a time.
+ */
+ void arm_fir_init_f32(
+ arm_fir_instance_f32 * S,
+ uint16_t numTaps,
+ float32_t * pCoeffs,
+ float32_t * pState,
+ uint32_t blockSize);
+
+
+ /**
+ * @brief Instance structure for the Q15 Biquad cascade filter.
+ */
+ typedef struct
+ {
+ int8_t numStages; /**< number of 2nd order stages in the filter. Overall order is 2*numStages. */
+ q15_t *pState; /**< Points to the array of state coefficients. The array is of length 4*numStages. */
+ q15_t *pCoeffs; /**< Points to the array of coefficients. The array is of length 5*numStages. */
+ int8_t postShift; /**< Additional shift, in bits, applied to each output sample. */
+ } arm_biquad_casd_df1_inst_q15;
+
+ /**
+ * @brief Instance structure for the Q31 Biquad cascade filter.
+ */
+ typedef struct
+ {
+ uint32_t numStages; /**< number of 2nd order stages in the filter. Overall order is 2*numStages. */
+ q31_t *pState; /**< Points to the array of state coefficients. The array is of length 4*numStages. */
+ q31_t *pCoeffs; /**< Points to the array of coefficients. The array is of length 5*numStages. */
+ uint8_t postShift; /**< Additional shift, in bits, applied to each output sample. */
+ } arm_biquad_casd_df1_inst_q31;
+
+ /**
+ * @brief Instance structure for the floating-point Biquad cascade filter.
+ */
+ typedef struct
+ {
+ uint32_t numStages; /**< number of 2nd order stages in the filter. Overall order is 2*numStages. */
+ float32_t *pState; /**< Points to the array of state coefficients. The array is of length 4*numStages. */
+ float32_t *pCoeffs; /**< Points to the array of coefficients. The array is of length 5*numStages. */
+ } arm_biquad_casd_df1_inst_f32;
+
+
+ /**
+ * @brief Processing function for the Q15 Biquad cascade filter.
+ * @param[in] S points to an instance of the Q15 Biquad cascade structure.
+ * @param[in] pSrc points to the block of input data.
+ * @param[out] pDst points to the block of output data.
+ * @param[in] blockSize number of samples to process.
+ */
+ void arm_biquad_cascade_df1_q15(
+ const arm_biquad_casd_df1_inst_q15 * S,
+ q15_t * pSrc,
+ q15_t * pDst,
+ uint32_t blockSize);
+
+
+ /**
+ * @brief Initialization function for the Q15 Biquad cascade filter.
+ * @param[in,out] S points to an instance of the Q15 Biquad cascade structure.
+ * @param[in] numStages number of 2nd order stages in the filter.
+ * @param[in] pCoeffs points to the filter coefficients.
+ * @param[in] pState points to the state buffer.
+ * @param[in] postShift Shift to be applied to the output. Varies according to the coefficients format
+ */
+ void arm_biquad_cascade_df1_init_q15(
+ arm_biquad_casd_df1_inst_q15 * S,
+ uint8_t numStages,
+ q15_t * pCoeffs,
+ q15_t * pState,
+ int8_t postShift);
+
+
+ /**
+ * @brief Fast but less precise processing function for the Q15 Biquad cascade filter for Cortex-M3 and Cortex-M4.
+ * @param[in] S points to an instance of the Q15 Biquad cascade structure.
+ * @param[in] pSrc points to the block of input data.
+ * @param[out] pDst points to the block of output data.
+ * @param[in] blockSize number of samples to process.
+ */
+ void arm_biquad_cascade_df1_fast_q15(
+ const arm_biquad_casd_df1_inst_q15 * S,
+ q15_t * pSrc,
+ q15_t * pDst,
+ uint32_t blockSize);
+
+
+ /**
+ * @brief Processing function for the Q31 Biquad cascade filter
+ * @param[in] S points to an instance of the Q31 Biquad cascade structure.
+ * @param[in] pSrc points to the block of input data.
+ * @param[out] pDst points to the block of output data.
+ * @param[in] blockSize number of samples to process.
+ */
+ void arm_biquad_cascade_df1_q31(
+ const arm_biquad_casd_df1_inst_q31 * S,
+ q31_t * pSrc,
+ q31_t * pDst,
+ uint32_t blockSize);
+
+
+ /**
+ * @brief Fast but less precise processing function for the Q31 Biquad cascade filter for Cortex-M3 and Cortex-M4.
+ * @param[in] S points to an instance of the Q31 Biquad cascade structure.
+ * @param[in] pSrc points to the block of input data.
+ * @param[out] pDst points to the block of output data.
+ * @param[in] blockSize number of samples to process.
+ */
+ void arm_biquad_cascade_df1_fast_q31(
+ const arm_biquad_casd_df1_inst_q31 * S,
+ q31_t * pSrc,
+ q31_t * pDst,
+ uint32_t blockSize);
+
+
+ /**
+ * @brief Initialization function for the Q31 Biquad cascade filter.
+ * @param[in,out] S points to an instance of the Q31 Biquad cascade structure.
+ * @param[in] numStages number of 2nd order stages in the filter.
+ * @param[in] pCoeffs points to the filter coefficients.
+ * @param[in] pState points to the state buffer.
+ * @param[in] postShift Shift to be applied to the output. Varies according to the coefficients format
+ */
+ void arm_biquad_cascade_df1_init_q31(
+ arm_biquad_casd_df1_inst_q31 * S,
+ uint8_t numStages,
+ q31_t * pCoeffs,
+ q31_t * pState,
+ int8_t postShift);
+
+
+ /**
+ * @brief Processing function for the floating-point Biquad cascade filter.
+ * @param[in] S points to an instance of the floating-point Biquad cascade structure.
+ * @param[in] pSrc points to the block of input data.
+ * @param[out] pDst points to the block of output data.
+ * @param[in] blockSize number of samples to process.
+ */
+ void arm_biquad_cascade_df1_f32(
+ const arm_biquad_casd_df1_inst_f32 * S,
+ float32_t * pSrc,
+ float32_t * pDst,
+ uint32_t blockSize);
+
+
+ /**
+ * @brief Initialization function for the floating-point Biquad cascade filter.
+ * @param[in,out] S points to an instance of the floating-point Biquad cascade structure.
+ * @param[in] numStages number of 2nd order stages in the filter.
+ * @param[in] pCoeffs points to the filter coefficients.
+ * @param[in] pState points to the state buffer.
+ */
+ void arm_biquad_cascade_df1_init_f32(
+ arm_biquad_casd_df1_inst_f32 * S,
+ uint8_t numStages,
+ float32_t * pCoeffs,
+ float32_t * pState);
+
+
+ /**
+ * @brief Instance structure for the floating-point matrix structure.
+ */
+ typedef struct
+ {
+ uint16_t numRows; /**< number of rows of the matrix. */
+ uint16_t numCols; /**< number of columns of the matrix. */
+ float32_t *pData; /**< points to the data of the matrix. */
+ } arm_matrix_instance_f32;
+
+
+ /**
+ * @brief Instance structure for the floating-point matrix structure.
+ */
+ typedef struct
+ {
+ uint16_t numRows; /**< number of rows of the matrix. */
+ uint16_t numCols; /**< number of columns of the matrix. */
+ float64_t *pData; /**< points to the data of the matrix. */
+ } arm_matrix_instance_f64;
+
+ /**
+ * @brief Instance structure for the Q15 matrix structure.
+ */
+ typedef struct
+ {
+ uint16_t numRows; /**< number of rows of the matrix. */
+ uint16_t numCols; /**< number of columns of the matrix. */
+ q15_t *pData; /**< points to the data of the matrix. */
+ } arm_matrix_instance_q15;
+
+ /**
+ * @brief Instance structure for the Q31 matrix structure.
+ */
+ typedef struct
+ {
+ uint16_t numRows; /**< number of rows of the matrix. */
+ uint16_t numCols; /**< number of columns of the matrix. */
+ q31_t *pData; /**< points to the data of the matrix. */
+ } arm_matrix_instance_q31;
+
+
+ /**
+ * @brief Floating-point matrix addition.
+ * @param[in] pSrcA points to the first input matrix structure
+ * @param[in] pSrcB points to the second input matrix structure
+ * @param[out] pDst points to output matrix structure
+ * @return The function returns either
+ * <code>ARM_MATH_SIZE_MISMATCH</code> or <code>ARM_MATH_SUCCESS</code> based on the outcome of size checking.
+ */
+ arm_status arm_mat_add_f32(
+ const arm_matrix_instance_f32 * pSrcA,
+ const arm_matrix_instance_f32 * pSrcB,
+ arm_matrix_instance_f32 * pDst);
+
+
+ /**
+ * @brief Q15 matrix addition.
+ * @param[in] pSrcA points to the first input matrix structure
+ * @param[in] pSrcB points to the second input matrix structure
+ * @param[out] pDst points to output matrix structure
+ * @return The function returns either
+ * <code>ARM_MATH_SIZE_MISMATCH</code> or <code>ARM_MATH_SUCCESS</code> based on the outcome of size checking.
+ */
+ arm_status arm_mat_add_q15(
+ const arm_matrix_instance_q15 * pSrcA,
+ const arm_matrix_instance_q15 * pSrcB,
+ arm_matrix_instance_q15 * pDst);
+
+
+ /**
+ * @brief Q31 matrix addition.
+ * @param[in] pSrcA points to the first input matrix structure
+ * @param[in] pSrcB points to the second input matrix structure
+ * @param[out] pDst points to output matrix structure
+ * @return The function returns either
+ * <code>ARM_MATH_SIZE_MISMATCH</code> or <code>ARM_MATH_SUCCESS</code> based on the outcome of size checking.
+ */
+ arm_status arm_mat_add_q31(
+ const arm_matrix_instance_q31 * pSrcA,
+ const arm_matrix_instance_q31 * pSrcB,
+ arm_matrix_instance_q31 * pDst);
+
+
+ /**
+ * @brief Floating-point, complex, matrix multiplication.
+ * @param[in] pSrcA points to the first input matrix structure
+ * @param[in] pSrcB points to the second input matrix structure
+ * @param[out] pDst points to output matrix structure
+ * @return The function returns either
+ * <code>ARM_MATH_SIZE_MISMATCH</code> or <code>ARM_MATH_SUCCESS</code> based on the outcome of size checking.
+ */
+ arm_status arm_mat_cmplx_mult_f32(
+ const arm_matrix_instance_f32 * pSrcA,
+ const arm_matrix_instance_f32 * pSrcB,
+ arm_matrix_instance_f32 * pDst);
+
+
+ /**
+ * @brief Q15, complex, matrix multiplication.
+ * @param[in] pSrcA points to the first input matrix structure
+ * @param[in] pSrcB points to the second input matrix structure
+ * @param[out] pDst points to output matrix structure
+ * @return The function returns either
+ * <code>ARM_MATH_SIZE_MISMATCH</code> or <code>ARM_MATH_SUCCESS</code> based on the outcome of size checking.
+ */
+ arm_status arm_mat_cmplx_mult_q15(
+ const arm_matrix_instance_q15 * pSrcA,
+ const arm_matrix_instance_q15 * pSrcB,
+ arm_matrix_instance_q15 * pDst,
+ q15_t * pScratch);
+
+
+ /**
+ * @brief Q31, complex, matrix multiplication.
+ * @param[in] pSrcA points to the first input matrix structure
+ * @param[in] pSrcB points to the second input matrix structure
+ * @param[out] pDst points to output matrix structure
+ * @return The function returns either
+ * <code>ARM_MATH_SIZE_MISMATCH</code> or <code>ARM_MATH_SUCCESS</code> based on the outcome of size checking.
+ */
+ arm_status arm_mat_cmplx_mult_q31(
+ const arm_matrix_instance_q31 * pSrcA,
+ const arm_matrix_instance_q31 * pSrcB,
+ arm_matrix_instance_q31 * pDst);
+
+
+ /**
+ * @brief Floating-point matrix transpose.
+ * @param[in] pSrc points to the input matrix
+ * @param[out] pDst points to the output matrix
+ * @return The function returns either <code>ARM_MATH_SIZE_MISMATCH</code>
+ * or <code>ARM_MATH_SUCCESS</code> based on the outcome of size checking.
+ */
+ arm_status arm_mat_trans_f32(
+ const arm_matrix_instance_f32 * pSrc,
+ arm_matrix_instance_f32 * pDst);
+
+
+ /**
+ * @brief Q15 matrix transpose.
+ * @param[in] pSrc points to the input matrix
+ * @param[out] pDst points to the output matrix
+ * @return The function returns either <code>ARM_MATH_SIZE_MISMATCH</code>
+ * or <code>ARM_MATH_SUCCESS</code> based on the outcome of size checking.
+ */
+ arm_status arm_mat_trans_q15(
+ const arm_matrix_instance_q15 * pSrc,
+ arm_matrix_instance_q15 * pDst);
+
+
+ /**
+ * @brief Q31 matrix transpose.
+ * @param[in] pSrc points to the input matrix
+ * @param[out] pDst points to the output matrix
+ * @return The function returns either <code>ARM_MATH_SIZE_MISMATCH</code>
+ * or <code>ARM_MATH_SUCCESS</code> based on the outcome of size checking.
+ */
+ arm_status arm_mat_trans_q31(
+ const arm_matrix_instance_q31 * pSrc,
+ arm_matrix_instance_q31 * pDst);
+
+
+ /**
+ * @brief Floating-point matrix multiplication
+ * @param[in] pSrcA points to the first input matrix structure
+ * @param[in] pSrcB points to the second input matrix structure
+ * @param[out] pDst points to output matrix structure
+ * @return The function returns either
+ * <code>ARM_MATH_SIZE_MISMATCH</code> or <code>ARM_MATH_SUCCESS</code> based on the outcome of size checking.
+ */
+ arm_status arm_mat_mult_f32(
+ const arm_matrix_instance_f32 * pSrcA,
+ const arm_matrix_instance_f32 * pSrcB,
+ arm_matrix_instance_f32 * pDst);
+
+
+ /**
+ * @brief Q15 matrix multiplication
+ * @param[in] pSrcA points to the first input matrix structure
+ * @param[in] pSrcB points to the second input matrix structure
+ * @param[out] pDst points to output matrix structure
+ * @param[in] pState points to the array for storing intermediate results
+ * @return The function returns either
+ * <code>ARM_MATH_SIZE_MISMATCH</code> or <code>ARM_MATH_SUCCESS</code> based on the outcome of size checking.
+ */
+ arm_status arm_mat_mult_q15(
+ const arm_matrix_instance_q15 * pSrcA,
+ const arm_matrix_instance_q15 * pSrcB,
+ arm_matrix_instance_q15 * pDst,
+ q15_t * pState);
+
+
+ /**
+ * @brief Q15 matrix multiplication (fast variant) for Cortex-M3 and Cortex-M4
+ * @param[in] pSrcA points to the first input matrix structure
+ * @param[in] pSrcB points to the second input matrix structure
+ * @param[out] pDst points to output matrix structure
+ * @param[in] pState points to the array for storing intermediate results
+ * @return The function returns either
+ * <code>ARM_MATH_SIZE_MISMATCH</code> or <code>ARM_MATH_SUCCESS</code> based on the outcome of size checking.
+ */
+ arm_status arm_mat_mult_fast_q15(
+ const arm_matrix_instance_q15 * pSrcA,
+ const arm_matrix_instance_q15 * pSrcB,
+ arm_matrix_instance_q15 * pDst,
+ q15_t * pState);
+
+
+ /**
+ * @brief Q31 matrix multiplication
+ * @param[in] pSrcA points to the first input matrix structure
+ * @param[in] pSrcB points to the second input matrix structure
+ * @param[out] pDst points to output matrix structure
+ * @return The function returns either
+ * <code>ARM_MATH_SIZE_MISMATCH</code> or <code>ARM_MATH_SUCCESS</code> based on the outcome of size checking.
+ */
+ arm_status arm_mat_mult_q31(
+ const arm_matrix_instance_q31 * pSrcA,
+ const arm_matrix_instance_q31 * pSrcB,
+ arm_matrix_instance_q31 * pDst);
+
+
+ /**
+ * @brief Q31 matrix multiplication (fast variant) for Cortex-M3 and Cortex-M4
+ * @param[in] pSrcA points to the first input matrix structure
+ * @param[in] pSrcB points to the second input matrix structure
+ * @param[out] pDst points to output matrix structure
+ * @return The function returns either
+ * <code>ARM_MATH_SIZE_MISMATCH</code> or <code>ARM_MATH_SUCCESS</code> based on the outcome of size checking.
+ */
+ arm_status arm_mat_mult_fast_q31(
+ const arm_matrix_instance_q31 * pSrcA,
+ const arm_matrix_instance_q31 * pSrcB,
+ arm_matrix_instance_q31 * pDst);
+
+
+ /**
+ * @brief Floating-point matrix subtraction
+ * @param[in] pSrcA points to the first input matrix structure
+ * @param[in] pSrcB points to the second input matrix structure
+ * @param[out] pDst points to output matrix structure
+ * @return The function returns either
+ * <code>ARM_MATH_SIZE_MISMATCH</code> or <code>ARM_MATH_SUCCESS</code> based on the outcome of size checking.
+ */
+ arm_status arm_mat_sub_f32(
+ const arm_matrix_instance_f32 * pSrcA,
+ const arm_matrix_instance_f32 * pSrcB,
+ arm_matrix_instance_f32 * pDst);
+
+
+ /**
+ * @brief Q15 matrix subtraction
+ * @param[in] pSrcA points to the first input matrix structure
+ * @param[in] pSrcB points to the second input matrix structure
+ * @param[out] pDst points to output matrix structure
+ * @return The function returns either
+ * <code>ARM_MATH_SIZE_MISMATCH</code> or <code>ARM_MATH_SUCCESS</code> based on the outcome of size checking.
+ */
+ arm_status arm_mat_sub_q15(
+ const arm_matrix_instance_q15 * pSrcA,
+ const arm_matrix_instance_q15 * pSrcB,
+ arm_matrix_instance_q15 * pDst);
+
+
+ /**
+ * @brief Q31 matrix subtraction
+ * @param[in] pSrcA points to the first input matrix structure
+ * @param[in] pSrcB points to the second input matrix structure
+ * @param[out] pDst points to output matrix structure
+ * @return The function returns either
+ * <code>ARM_MATH_SIZE_MISMATCH</code> or <code>ARM_MATH_SUCCESS</code> based on the outcome of size checking.
+ */
+ arm_status arm_mat_sub_q31(
+ const arm_matrix_instance_q31 * pSrcA,
+ const arm_matrix_instance_q31 * pSrcB,
+ arm_matrix_instance_q31 * pDst);
+
+
+ /**
+ * @brief Floating-point matrix scaling.
+ * @param[in] pSrc points to the input matrix
+ * @param[in] scale scale factor
+ * @param[out] pDst points to the output matrix
+ * @return The function returns either
+ * <code>ARM_MATH_SIZE_MISMATCH</code> or <code>ARM_MATH_SUCCESS</code> based on the outcome of size checking.
+ */
+ arm_status arm_mat_scale_f32(
+ const arm_matrix_instance_f32 * pSrc,
+ float32_t scale,
+ arm_matrix_instance_f32 * pDst);
+
+
+ /**
+ * @brief Q15 matrix scaling.
+ * @param[in] pSrc points to input matrix
+ * @param[in] scaleFract fractional portion of the scale factor
+ * @param[in] shift number of bits to shift the result by
+ * @param[out] pDst points to output matrix
+ * @return The function returns either
+ * <code>ARM_MATH_SIZE_MISMATCH</code> or <code>ARM_MATH_SUCCESS</code> based on the outcome of size checking.
+ */
+ arm_status arm_mat_scale_q15(
+ const arm_matrix_instance_q15 * pSrc,
+ q15_t scaleFract,
+ int32_t shift,
+ arm_matrix_instance_q15 * pDst);
+
+
+ /**
+ * @brief Q31 matrix scaling.
+ * @param[in] pSrc points to input matrix
+ * @param[in] scaleFract fractional portion of the scale factor
+ * @param[in] shift number of bits to shift the result by
+ * @param[out] pDst points to output matrix structure
+ * @return The function returns either
+ * <code>ARM_MATH_SIZE_MISMATCH</code> or <code>ARM_MATH_SUCCESS</code> based on the outcome of size checking.
+ */
+ arm_status arm_mat_scale_q31(
+ const arm_matrix_instance_q31 * pSrc,
+ q31_t scaleFract,
+ int32_t shift,
+ arm_matrix_instance_q31 * pDst);
+
+
+ /**
+ * @brief Q31 matrix initialization.
+ * @param[in,out] S points to an instance of the floating-point matrix structure.
+ * @param[in] nRows number of rows in the matrix.
+ * @param[in] nColumns number of columns in the matrix.
+ * @param[in] pData points to the matrix data array.
+ */
+ void arm_mat_init_q31(
+ arm_matrix_instance_q31 * S,
+ uint16_t nRows,
+ uint16_t nColumns,
+ q31_t * pData);
+
+
+ /**
+ * @brief Q15 matrix initialization.
+ * @param[in,out] S points to an instance of the floating-point matrix structure.
+ * @param[in] nRows number of rows in the matrix.
+ * @param[in] nColumns number of columns in the matrix.
+ * @param[in] pData points to the matrix data array.
+ */
+ void arm_mat_init_q15(
+ arm_matrix_instance_q15 * S,
+ uint16_t nRows,
+ uint16_t nColumns,
+ q15_t * pData);
+
+
+ /**
+ * @brief Floating-point matrix initialization.
+ * @param[in,out] S points to an instance of the floating-point matrix structure.
+ * @param[in] nRows number of rows in the matrix.
+ * @param[in] nColumns number of columns in the matrix.
+ * @param[in] pData points to the matrix data array.
+ */
+ void arm_mat_init_f32(
+ arm_matrix_instance_f32 * S,
+ uint16_t nRows,
+ uint16_t nColumns,
+ float32_t * pData);
+
+
+
+ /**
+ * @brief Instance structure for the Q15 PID Control.
+ */
+ typedef struct
+ {
+ q15_t A0; /**< The derived gain, A0 = Kp + Ki + Kd . */
+#ifdef ARM_MATH_CM0_FAMILY
+ q15_t A1;
+ q15_t A2;
+#else
+ q31_t A1; /**< The derived gain A1 = -Kp - 2Kd | Kd.*/
+#endif
+ q15_t state[3]; /**< The state array of length 3. */
+ q15_t Kp; /**< The proportional gain. */
+ q15_t Ki; /**< The integral gain. */
+ q15_t Kd; /**< The derivative gain. */
+ } arm_pid_instance_q15;
+
+ /**
+ * @brief Instance structure for the Q31 PID Control.
+ */
+ typedef struct
+ {
+ q31_t A0; /**< The derived gain, A0 = Kp + Ki + Kd . */
+ q31_t A1; /**< The derived gain, A1 = -Kp - 2Kd. */
+ q31_t A2; /**< The derived gain, A2 = Kd . */
+ q31_t state[3]; /**< The state array of length 3. */
+ q31_t Kp; /**< The proportional gain. */
+ q31_t Ki; /**< The integral gain. */
+ q31_t Kd; /**< The derivative gain. */
+ } arm_pid_instance_q31;
+
+ /**
+ * @brief Instance structure for the floating-point PID Control.
+ */
+ typedef struct
+ {
+ float32_t A0; /**< The derived gain, A0 = Kp + Ki + Kd . */
+ float32_t A1; /**< The derived gain, A1 = -Kp - 2Kd. */
+ float32_t A2; /**< The derived gain, A2 = Kd . */
+ float32_t state[3]; /**< The state array of length 3. */
+ float32_t Kp; /**< The proportional gain. */
+ float32_t Ki; /**< The integral gain. */
+ float32_t Kd; /**< The derivative gain. */
+ } arm_pid_instance_f32;
+
+
+
+ /**
+ * @brief Initialization function for the floating-point PID Control.
+ * @param[in,out] S points to an instance of the PID structure.
+ * @param[in] resetStateFlag flag to reset the state. 0 = no change in state 1 = reset the state.
+ */
+ void arm_pid_init_f32(
+ arm_pid_instance_f32 * S,
+ int32_t resetStateFlag);
+
+
+ /**
+ * @brief Reset function for the floating-point PID Control.
+ * @param[in,out] S is an instance of the floating-point PID Control structure
+ */
+ void arm_pid_reset_f32(
+ arm_pid_instance_f32 * S);
+
+
+ /**
+ * @brief Initialization function for the Q31 PID Control.
+ * @param[in,out] S points to an instance of the Q15 PID structure.
+ * @param[in] resetStateFlag flag to reset the state. 0 = no change in state 1 = reset the state.
+ */
+ void arm_pid_init_q31(
+ arm_pid_instance_q31 * S,
+ int32_t resetStateFlag);
+
+
+ /**
+ * @brief Reset function for the Q31 PID Control.
+ * @param[in,out] S points to an instance of the Q31 PID Control structure
+ */
+
+ void arm_pid_reset_q31(
+ arm_pid_instance_q31 * S);
+
+
+ /**
+ * @brief Initialization function for the Q15 PID Control.
+ * @param[in,out] S points to an instance of the Q15 PID structure.
+ * @param[in] resetStateFlag flag to reset the state. 0 = no change in state 1 = reset the state.
+ */
+ void arm_pid_init_q15(
+ arm_pid_instance_q15 * S,
+ int32_t resetStateFlag);
+
+
+ /**
+ * @brief Reset function for the Q15 PID Control.
+ * @param[in,out] S points to an instance of the q15 PID Control structure
+ */
+ void arm_pid_reset_q15(
+ arm_pid_instance_q15 * S);
+
+
+ /**
+ * @brief Instance structure for the floating-point Linear Interpolate function.
+ */
+ typedef struct
+ {
+ uint32_t nValues; /**< nValues */
+ float32_t x1; /**< x1 */
+ float32_t xSpacing; /**< xSpacing */
+ float32_t *pYData; /**< pointer to the table of Y values */
+ } arm_linear_interp_instance_f32;
+
+ /**
+ * @brief Instance structure for the floating-point bilinear interpolation function.
+ */
+ typedef struct
+ {
+ uint16_t numRows; /**< number of rows in the data table. */
+ uint16_t numCols; /**< number of columns in the data table. */
+ float32_t *pData; /**< points to the data table. */
+ } arm_bilinear_interp_instance_f32;
+
+ /**
+ * @brief Instance structure for the Q31 bilinear interpolation function.
+ */
+ typedef struct
+ {
+ uint16_t numRows; /**< number of rows in the data table. */
+ uint16_t numCols; /**< number of columns in the data table. */
+ q31_t *pData; /**< points to the data table. */
+ } arm_bilinear_interp_instance_q31;
+
+ /**
+ * @brief Instance structure for the Q15 bilinear interpolation function.
+ */
+ typedef struct
+ {
+ uint16_t numRows; /**< number of rows in the data table. */
+ uint16_t numCols; /**< number of columns in the data table. */
+ q15_t *pData; /**< points to the data table. */
+ } arm_bilinear_interp_instance_q15;
+
+ /**
+ * @brief Instance structure for the Q15 bilinear interpolation function.
+ */
+ typedef struct
+ {
+ uint16_t numRows; /**< number of rows in the data table. */
+ uint16_t numCols; /**< number of columns in the data table. */
+ q7_t *pData; /**< points to the data table. */
+ } arm_bilinear_interp_instance_q7;
+
+
+ /**
+ * @brief Q7 vector multiplication.
+ * @param[in] pSrcA points to the first input vector
+ * @param[in] pSrcB points to the second input vector
+ * @param[out] pDst points to the output vector
+ * @param[in] blockSize number of samples in each vector
+ */
+ void arm_mult_q7(
+ q7_t * pSrcA,
+ q7_t * pSrcB,
+ q7_t * pDst,
+ uint32_t blockSize);
+
+
+ /**
+ * @brief Q15 vector multiplication.
+ * @param[in] pSrcA points to the first input vector
+ * @param[in] pSrcB points to the second input vector
+ * @param[out] pDst points to the output vector
+ * @param[in] blockSize number of samples in each vector
+ */
+ void arm_mult_q15(
+ q15_t * pSrcA,
+ q15_t * pSrcB,
+ q15_t * pDst,
+ uint32_t blockSize);
+
+
+ /**
+ * @brief Q31 vector multiplication.
+ * @param[in] pSrcA points to the first input vector
+ * @param[in] pSrcB points to the second input vector
+ * @param[out] pDst points to the output vector
+ * @param[in] blockSize number of samples in each vector
+ */
+ void arm_mult_q31(
+ q31_t * pSrcA,
+ q31_t * pSrcB,
+ q31_t * pDst,
+ uint32_t blockSize);
+
+
+ /**
+ * @brief Floating-point vector multiplication.
+ * @param[in] pSrcA points to the first input vector
+ * @param[in] pSrcB points to the second input vector
+ * @param[out] pDst points to the output vector
+ * @param[in] blockSize number of samples in each vector
+ */
+ void arm_mult_f32(
+ float32_t * pSrcA,
+ float32_t * pSrcB,
+ float32_t * pDst,
+ uint32_t blockSize);
+
+
+ /**
+ * @brief Instance structure for the Q15 CFFT/CIFFT function.
+ */
+ typedef struct
+ {
+ uint16_t fftLen; /**< length of the FFT. */
+ uint8_t ifftFlag; /**< flag that selects forward (ifftFlag=0) or inverse (ifftFlag=1) transform. */
+ uint8_t bitReverseFlag; /**< flag that enables (bitReverseFlag=1) or disables (bitReverseFlag=0) bit reversal of output. */
+ q15_t *pTwiddle; /**< points to the Sin twiddle factor table. */
+ uint16_t *pBitRevTable; /**< points to the bit reversal table. */
+ uint16_t twidCoefModifier; /**< twiddle coefficient modifier that supports different size FFTs with the same twiddle factor table. */
+ uint16_t bitRevFactor; /**< bit reversal modifier that supports different size FFTs with the same bit reversal table. */
+ } arm_cfft_radix2_instance_q15;
+
+/* Deprecated */
+ arm_status arm_cfft_radix2_init_q15(
+ arm_cfft_radix2_instance_q15 * S,
+ uint16_t fftLen,
+ uint8_t ifftFlag,
+ uint8_t bitReverseFlag);
+
+/* Deprecated */
+ void arm_cfft_radix2_q15(
+ const arm_cfft_radix2_instance_q15 * S,
+ q15_t * pSrc);
+
+
+ /**
+ * @brief Instance structure for the Q15 CFFT/CIFFT function.
+ */
+ typedef struct
+ {
+ uint16_t fftLen; /**< length of the FFT. */
+ uint8_t ifftFlag; /**< flag that selects forward (ifftFlag=0) or inverse (ifftFlag=1) transform. */
+ uint8_t bitReverseFlag; /**< flag that enables (bitReverseFlag=1) or disables (bitReverseFlag=0) bit reversal of output. */
+ q15_t *pTwiddle; /**< points to the twiddle factor table. */
+ uint16_t *pBitRevTable; /**< points to the bit reversal table. */
+ uint16_t twidCoefModifier; /**< twiddle coefficient modifier that supports different size FFTs with the same twiddle factor table. */
+ uint16_t bitRevFactor; /**< bit reversal modifier that supports different size FFTs with the same bit reversal table. */
+ } arm_cfft_radix4_instance_q15;
+
+/* Deprecated */
+ arm_status arm_cfft_radix4_init_q15(
+ arm_cfft_radix4_instance_q15 * S,
+ uint16_t fftLen,
+ uint8_t ifftFlag,
+ uint8_t bitReverseFlag);
+
+/* Deprecated */
+ void arm_cfft_radix4_q15(
+ const arm_cfft_radix4_instance_q15 * S,
+ q15_t * pSrc);
+
+ /**
+ * @brief Instance structure for the Radix-2 Q31 CFFT/CIFFT function.
+ */
+ typedef struct
+ {
+ uint16_t fftLen; /**< length of the FFT. */
+ uint8_t ifftFlag; /**< flag that selects forward (ifftFlag=0) or inverse (ifftFlag=1) transform. */
+ uint8_t bitReverseFlag; /**< flag that enables (bitReverseFlag=1) or disables (bitReverseFlag=0) bit reversal of output. */
+ q31_t *pTwiddle; /**< points to the Twiddle factor table. */
+ uint16_t *pBitRevTable; /**< points to the bit reversal table. */
+ uint16_t twidCoefModifier; /**< twiddle coefficient modifier that supports different size FFTs with the same twiddle factor table. */
+ uint16_t bitRevFactor; /**< bit reversal modifier that supports different size FFTs with the same bit reversal table. */
+ } arm_cfft_radix2_instance_q31;
+
+/* Deprecated */
+ arm_status arm_cfft_radix2_init_q31(
+ arm_cfft_radix2_instance_q31 * S,
+ uint16_t fftLen,
+ uint8_t ifftFlag,
+ uint8_t bitReverseFlag);
+
+/* Deprecated */
+ void arm_cfft_radix2_q31(
+ const arm_cfft_radix2_instance_q31 * S,
+ q31_t * pSrc);
+
+ /**
+ * @brief Instance structure for the Q31 CFFT/CIFFT function.
+ */
+ typedef struct
+ {
+ uint16_t fftLen; /**< length of the FFT. */
+ uint8_t ifftFlag; /**< flag that selects forward (ifftFlag=0) or inverse (ifftFlag=1) transform. */
+ uint8_t bitReverseFlag; /**< flag that enables (bitReverseFlag=1) or disables (bitReverseFlag=0) bit reversal of output. */
+ q31_t *pTwiddle; /**< points to the twiddle factor table. */
+ uint16_t *pBitRevTable; /**< points to the bit reversal table. */
+ uint16_t twidCoefModifier; /**< twiddle coefficient modifier that supports different size FFTs with the same twiddle factor table. */
+ uint16_t bitRevFactor; /**< bit reversal modifier that supports different size FFTs with the same bit reversal table. */
+ } arm_cfft_radix4_instance_q31;
+
+/* Deprecated */
+ void arm_cfft_radix4_q31(
+ const arm_cfft_radix4_instance_q31 * S,
+ q31_t * pSrc);
+
+/* Deprecated */
+ arm_status arm_cfft_radix4_init_q31(
+ arm_cfft_radix4_instance_q31 * S,
+ uint16_t fftLen,
+ uint8_t ifftFlag,
+ uint8_t bitReverseFlag);
+
+ /**
+ * @brief Instance structure for the floating-point CFFT/CIFFT function.
+ */
+ typedef struct
+ {
+ uint16_t fftLen; /**< length of the FFT. */
+ uint8_t ifftFlag; /**< flag that selects forward (ifftFlag=0) or inverse (ifftFlag=1) transform. */
+ uint8_t bitReverseFlag; /**< flag that enables (bitReverseFlag=1) or disables (bitReverseFlag=0) bit reversal of output. */
+ float32_t *pTwiddle; /**< points to the Twiddle factor table. */
+ uint16_t *pBitRevTable; /**< points to the bit reversal table. */
+ uint16_t twidCoefModifier; /**< twiddle coefficient modifier that supports different size FFTs with the same twiddle factor table. */
+ uint16_t bitRevFactor; /**< bit reversal modifier that supports different size FFTs with the same bit reversal table. */
+ float32_t onebyfftLen; /**< value of 1/fftLen. */
+ } arm_cfft_radix2_instance_f32;
+
+/* Deprecated */
+ arm_status arm_cfft_radix2_init_f32(
+ arm_cfft_radix2_instance_f32 * S,
+ uint16_t fftLen,
+ uint8_t ifftFlag,
+ uint8_t bitReverseFlag);
+
+/* Deprecated */
+ void arm_cfft_radix2_f32(
+ const arm_cfft_radix2_instance_f32 * S,
+ float32_t * pSrc);
+
+ /**
+ * @brief Instance structure for the floating-point CFFT/CIFFT function.
+ */
+ typedef struct
+ {
+ uint16_t fftLen; /**< length of the FFT. */
+ uint8_t ifftFlag; /**< flag that selects forward (ifftFlag=0) or inverse (ifftFlag=1) transform. */
+ uint8_t bitReverseFlag; /**< flag that enables (bitReverseFlag=1) or disables (bitReverseFlag=0) bit reversal of output. */
+ float32_t *pTwiddle; /**< points to the Twiddle factor table. */
+ uint16_t *pBitRevTable; /**< points to the bit reversal table. */
+ uint16_t twidCoefModifier; /**< twiddle coefficient modifier that supports different size FFTs with the same twiddle factor table. */
+ uint16_t bitRevFactor; /**< bit reversal modifier that supports different size FFTs with the same bit reversal table. */
+ float32_t onebyfftLen; /**< value of 1/fftLen. */
+ } arm_cfft_radix4_instance_f32;
+
+/* Deprecated */
+ arm_status arm_cfft_radix4_init_f32(
+ arm_cfft_radix4_instance_f32 * S,
+ uint16_t fftLen,
+ uint8_t ifftFlag,
+ uint8_t bitReverseFlag);
+
+/* Deprecated */
+ void arm_cfft_radix4_f32(
+ const arm_cfft_radix4_instance_f32 * S,
+ float32_t * pSrc);
+
+ /**
+ * @brief Instance structure for the fixed-point CFFT/CIFFT function.
+ */
+ typedef struct
+ {
+ uint16_t fftLen; /**< length of the FFT. */
+ const q15_t *pTwiddle; /**< points to the Twiddle factor table. */
+ const uint16_t *pBitRevTable; /**< points to the bit reversal table. */
+ uint16_t bitRevLength; /**< bit reversal table length. */
+ } arm_cfft_instance_q15;
+
+void arm_cfft_q15(
+ const arm_cfft_instance_q15 * S,
+ q15_t * p1,
+ uint8_t ifftFlag,
+ uint8_t bitReverseFlag);
+
+ /**
+ * @brief Instance structure for the fixed-point CFFT/CIFFT function.
+ */
+ typedef struct
+ {
+ uint16_t fftLen; /**< length of the FFT. */
+ const q31_t *pTwiddle; /**< points to the Twiddle factor table. */
+ const uint16_t *pBitRevTable; /**< points to the bit reversal table. */
+ uint16_t bitRevLength; /**< bit reversal table length. */
+ } arm_cfft_instance_q31;
+
+void arm_cfft_q31(
+ const arm_cfft_instance_q31 * S,
+ q31_t * p1,
+ uint8_t ifftFlag,
+ uint8_t bitReverseFlag);
+
+ /**
+ * @brief Instance structure for the floating-point CFFT/CIFFT function.
+ */
+ typedef struct
+ {
+ uint16_t fftLen; /**< length of the FFT. */
+ const float32_t *pTwiddle; /**< points to the Twiddle factor table. */
+ const uint16_t *pBitRevTable; /**< points to the bit reversal table. */
+ uint16_t bitRevLength; /**< bit reversal table length. */
+ } arm_cfft_instance_f32;
+
+ void arm_cfft_f32(
+ const arm_cfft_instance_f32 * S,
+ float32_t * p1,
+ uint8_t ifftFlag,
+ uint8_t bitReverseFlag);
+
+ /**
+ * @brief Instance structure for the Q15 RFFT/RIFFT function.
+ */
+ typedef struct
+ {
+ uint32_t fftLenReal; /**< length of the real FFT. */
+ uint8_t ifftFlagR; /**< flag that selects forward (ifftFlagR=0) or inverse (ifftFlagR=1) transform. */
+ uint8_t bitReverseFlagR; /**< flag that enables (bitReverseFlagR=1) or disables (bitReverseFlagR=0) bit reversal of output. */
+ uint32_t twidCoefRModifier; /**< twiddle coefficient modifier that supports different size FFTs with the same twiddle factor table. */
+ q15_t *pTwiddleAReal; /**< points to the real twiddle factor table. */
+ q15_t *pTwiddleBReal; /**< points to the imag twiddle factor table. */
+ const arm_cfft_instance_q15 *pCfft; /**< points to the complex FFT instance. */
+ } arm_rfft_instance_q15;
+
+ arm_status arm_rfft_init_q15(
+ arm_rfft_instance_q15 * S,
+ uint32_t fftLenReal,
+ uint32_t ifftFlagR,
+ uint32_t bitReverseFlag);
+
+ void arm_rfft_q15(
+ const arm_rfft_instance_q15 * S,
+ q15_t * pSrc,
+ q15_t * pDst);
+
+ /**
+ * @brief Instance structure for the Q31 RFFT/RIFFT function.
+ */
+ typedef struct
+ {
+ uint32_t fftLenReal; /**< length of the real FFT. */
+ uint8_t ifftFlagR; /**< flag that selects forward (ifftFlagR=0) or inverse (ifftFlagR=1) transform. */
+ uint8_t bitReverseFlagR; /**< flag that enables (bitReverseFlagR=1) or disables (bitReverseFlagR=0) bit reversal of output. */
+ uint32_t twidCoefRModifier; /**< twiddle coefficient modifier that supports different size FFTs with the same twiddle factor table. */
+ q31_t *pTwiddleAReal; /**< points to the real twiddle factor table. */
+ q31_t *pTwiddleBReal; /**< points to the imag twiddle factor table. */
+ const arm_cfft_instance_q31 *pCfft; /**< points to the complex FFT instance. */
+ } arm_rfft_instance_q31;
+
+ arm_status arm_rfft_init_q31(
+ arm_rfft_instance_q31 * S,
+ uint32_t fftLenReal,
+ uint32_t ifftFlagR,
+ uint32_t bitReverseFlag);
+
+ void arm_rfft_q31(
+ const arm_rfft_instance_q31 * S,
+ q31_t * pSrc,
+ q31_t * pDst);
+
+ /**
+ * @brief Instance structure for the floating-point RFFT/RIFFT function.
+ */
+ typedef struct
+ {
+ uint32_t fftLenReal; /**< length of the real FFT. */
+ uint16_t fftLenBy2; /**< length of the complex FFT. */
+ uint8_t ifftFlagR; /**< flag that selects forward (ifftFlagR=0) or inverse (ifftFlagR=1) transform. */
+ uint8_t bitReverseFlagR; /**< flag that enables (bitReverseFlagR=1) or disables (bitReverseFlagR=0) bit reversal of output. */
+ uint32_t twidCoefRModifier; /**< twiddle coefficient modifier that supports different size FFTs with the same twiddle factor table. */
+ float32_t *pTwiddleAReal; /**< points to the real twiddle factor table. */
+ float32_t *pTwiddleBReal; /**< points to the imag twiddle factor table. */
+ arm_cfft_radix4_instance_f32 *pCfft; /**< points to the complex FFT instance. */
+ } arm_rfft_instance_f32;
+
+ arm_status arm_rfft_init_f32(
+ arm_rfft_instance_f32 * S,
+ arm_cfft_radix4_instance_f32 * S_CFFT,
+ uint32_t fftLenReal,
+ uint32_t ifftFlagR,
+ uint32_t bitReverseFlag);
+
+ void arm_rfft_f32(
+ const arm_rfft_instance_f32 * S,
+ float32_t * pSrc,
+ float32_t * pDst);
+
+ /**
+ * @brief Instance structure for the floating-point RFFT/RIFFT function.
+ */
+typedef struct
+ {
+ arm_cfft_instance_f32 Sint; /**< Internal CFFT structure. */
+ uint16_t fftLenRFFT; /**< length of the real sequence */
+ float32_t * pTwiddleRFFT; /**< Twiddle factors real stage */
+ } arm_rfft_fast_instance_f32 ;
+
+arm_status arm_rfft_fast_init_f32 (
+ arm_rfft_fast_instance_f32 * S,
+ uint16_t fftLen);
+
+void arm_rfft_fast_f32(
+ arm_rfft_fast_instance_f32 * S,
+ float32_t * p, float32_t * pOut,
+ uint8_t ifftFlag);
+
+ /**
+ * @brief Instance structure for the floating-point DCT4/IDCT4 function.
+ */
+ typedef struct
+ {
+ uint16_t N; /**< length of the DCT4. */
+ uint16_t Nby2; /**< half of the length of the DCT4. */
+ float32_t normalize; /**< normalizing factor. */
+ float32_t *pTwiddle; /**< points to the twiddle factor table. */
+ float32_t *pCosFactor; /**< points to the cosFactor table. */
+ arm_rfft_instance_f32 *pRfft; /**< points to the real FFT instance. */
+ arm_cfft_radix4_instance_f32 *pCfft; /**< points to the complex FFT instance. */
+ } arm_dct4_instance_f32;
+
+
+ /**
+ * @brief Initialization function for the floating-point DCT4/IDCT4.
+ * @param[in,out] S points to an instance of floating-point DCT4/IDCT4 structure.
+ * @param[in] S_RFFT points to an instance of floating-point RFFT/RIFFT structure.
+ * @param[in] S_CFFT points to an instance of floating-point CFFT/CIFFT structure.
+ * @param[in] N length of the DCT4.
+ * @param[in] Nby2 half of the length of the DCT4.
+ * @param[in] normalize normalizing factor.
+ * @return arm_status function returns ARM_MATH_SUCCESS if initialization is successful or ARM_MATH_ARGUMENT_ERROR if <code>fftLenReal</code> is not a supported transform length.
+ */
+ arm_status arm_dct4_init_f32(
+ arm_dct4_instance_f32 * S,
+ arm_rfft_instance_f32 * S_RFFT,
+ arm_cfft_radix4_instance_f32 * S_CFFT,
+ uint16_t N,
+ uint16_t Nby2,
+ float32_t normalize);
+
+
+ /**
+ * @brief Processing function for the floating-point DCT4/IDCT4.
+ * @param[in] S points to an instance of the floating-point DCT4/IDCT4 structure.
+ * @param[in] pState points to state buffer.
+ * @param[in,out] pInlineBuffer points to the in-place input and output buffer.
+ */
+ void arm_dct4_f32(
+ const arm_dct4_instance_f32 * S,
+ float32_t * pState,
+ float32_t * pInlineBuffer);
+
+
+ /**
+ * @brief Instance structure for the Q31 DCT4/IDCT4 function.
+ */
+ typedef struct
+ {
+ uint16_t N; /**< length of the DCT4. */
+ uint16_t Nby2; /**< half of the length of the DCT4. */
+ q31_t normalize; /**< normalizing factor. */
+ q31_t *pTwiddle; /**< points to the twiddle factor table. */
+ q31_t *pCosFactor; /**< points to the cosFactor table. */
+ arm_rfft_instance_q31 *pRfft; /**< points to the real FFT instance. */
+ arm_cfft_radix4_instance_q31 *pCfft; /**< points to the complex FFT instance. */
+ } arm_dct4_instance_q31;
+
+
+ /**
+ * @brief Initialization function for the Q31 DCT4/IDCT4.
+ * @param[in,out] S points to an instance of Q31 DCT4/IDCT4 structure.
+ * @param[in] S_RFFT points to an instance of Q31 RFFT/RIFFT structure
+ * @param[in] S_CFFT points to an instance of Q31 CFFT/CIFFT structure
+ * @param[in] N length of the DCT4.
+ * @param[in] Nby2 half of the length of the DCT4.
+ * @param[in] normalize normalizing factor.
+ * @return arm_status function returns ARM_MATH_SUCCESS if initialization is successful or ARM_MATH_ARGUMENT_ERROR if <code>N</code> is not a supported transform length.
+ */
+ arm_status arm_dct4_init_q31(
+ arm_dct4_instance_q31 * S,
+ arm_rfft_instance_q31 * S_RFFT,
+ arm_cfft_radix4_instance_q31 * S_CFFT,
+ uint16_t N,
+ uint16_t Nby2,
+ q31_t normalize);
+
+
+ /**
+ * @brief Processing function for the Q31 DCT4/IDCT4.
+ * @param[in] S points to an instance of the Q31 DCT4 structure.
+ * @param[in] pState points to state buffer.
+ * @param[in,out] pInlineBuffer points to the in-place input and output buffer.
+ */
+ void arm_dct4_q31(
+ const arm_dct4_instance_q31 * S,
+ q31_t * pState,
+ q31_t * pInlineBuffer);
+
+
+ /**
+ * @brief Instance structure for the Q15 DCT4/IDCT4 function.
+ */
+ typedef struct
+ {
+ uint16_t N; /**< length of the DCT4. */
+ uint16_t Nby2; /**< half of the length of the DCT4. */
+ q15_t normalize; /**< normalizing factor. */
+ q15_t *pTwiddle; /**< points to the twiddle factor table. */
+ q15_t *pCosFactor; /**< points to the cosFactor table. */
+ arm_rfft_instance_q15 *pRfft; /**< points to the real FFT instance. */
+ arm_cfft_radix4_instance_q15 *pCfft; /**< points to the complex FFT instance. */
+ } arm_dct4_instance_q15;
+
+
+ /**
+ * @brief Initialization function for the Q15 DCT4/IDCT4.
+ * @param[in,out] S points to an instance of Q15 DCT4/IDCT4 structure.
+ * @param[in] S_RFFT points to an instance of Q15 RFFT/RIFFT structure.
+ * @param[in] S_CFFT points to an instance of Q15 CFFT/CIFFT structure.
+ * @param[in] N length of the DCT4.
+ * @param[in] Nby2 half of the length of the DCT4.
+ * @param[in] normalize normalizing factor.
+ * @return arm_status function returns ARM_MATH_SUCCESS if initialization is successful or ARM_MATH_ARGUMENT_ERROR if <code>N</code> is not a supported transform length.
+ */
+ arm_status arm_dct4_init_q15(
+ arm_dct4_instance_q15 * S,
+ arm_rfft_instance_q15 * S_RFFT,
+ arm_cfft_radix4_instance_q15 * S_CFFT,
+ uint16_t N,
+ uint16_t Nby2,
+ q15_t normalize);
+
+
+ /**
+ * @brief Processing function for the Q15 DCT4/IDCT4.
+ * @param[in] S points to an instance of the Q15 DCT4 structure.
+ * @param[in] pState points to state buffer.
+ * @param[in,out] pInlineBuffer points to the in-place input and output buffer.
+ */
+ void arm_dct4_q15(
+ const arm_dct4_instance_q15 * S,
+ q15_t * pState,
+ q15_t * pInlineBuffer);
+
+
+ /**
+ * @brief Floating-point vector addition.
+ * @param[in] pSrcA points to the first input vector
+ * @param[in] pSrcB points to the second input vector
+ * @param[out] pDst points to the output vector
+ * @param[in] blockSize number of samples in each vector
+ */
+ void arm_add_f32(
+ float32_t * pSrcA,
+ float32_t * pSrcB,
+ float32_t * pDst,
+ uint32_t blockSize);
+
+
+ /**
+ * @brief Q7 vector addition.
+ * @param[in] pSrcA points to the first input vector
+ * @param[in] pSrcB points to the second input vector
+ * @param[out] pDst points to the output vector
+ * @param[in] blockSize number of samples in each vector
+ */
+ void arm_add_q7(
+ q7_t * pSrcA,
+ q7_t * pSrcB,
+ q7_t * pDst,
+ uint32_t blockSize);
+
+
+ /**
+ * @brief Q15 vector addition.
+ * @param[in] pSrcA points to the first input vector
+ * @param[in] pSrcB points to the second input vector
+ * @param[out] pDst points to the output vector
+ * @param[in] blockSize number of samples in each vector
+ */
+ void arm_add_q15(
+ q15_t * pSrcA,
+ q15_t * pSrcB,
+ q15_t * pDst,
+ uint32_t blockSize);
+
+
+ /**
+ * @brief Q31 vector addition.
+ * @param[in] pSrcA points to the first input vector
+ * @param[in] pSrcB points to the second input vector
+ * @param[out] pDst points to the output vector
+ * @param[in] blockSize number of samples in each vector
+ */
+ void arm_add_q31(
+ q31_t * pSrcA,
+ q31_t * pSrcB,
+ q31_t * pDst,
+ uint32_t blockSize);
+
+
+ /**
+ * @brief Floating-point vector subtraction.
+ * @param[in] pSrcA points to the first input vector
+ * @param[in] pSrcB points to the second input vector
+ * @param[out] pDst points to the output vector
+ * @param[in] blockSize number of samples in each vector
+ */
+ void arm_sub_f32(
+ float32_t * pSrcA,
+ float32_t * pSrcB,
+ float32_t * pDst,
+ uint32_t blockSize);
+
+
+ /**
+ * @brief Q7 vector subtraction.
+ * @param[in] pSrcA points to the first input vector
+ * @param[in] pSrcB points to the second input vector
+ * @param[out] pDst points to the output vector
+ * @param[in] blockSize number of samples in each vector
+ */
+ void arm_sub_q7(
+ q7_t * pSrcA,
+ q7_t * pSrcB,
+ q7_t * pDst,
+ uint32_t blockSize);
+
+
+ /**
+ * @brief Q15 vector subtraction.
+ * @param[in] pSrcA points to the first input vector
+ * @param[in] pSrcB points to the second input vector
+ * @param[out] pDst points to the output vector
+ * @param[in] blockSize number of samples in each vector
+ */
+ void arm_sub_q15(
+ q15_t * pSrcA,
+ q15_t * pSrcB,
+ q15_t * pDst,
+ uint32_t blockSize);
+
+
+ /**
+ * @brief Q31 vector subtraction.
+ * @param[in] pSrcA points to the first input vector
+ * @param[in] pSrcB points to the second input vector
+ * @param[out] pDst points to the output vector
+ * @param[in] blockSize number of samples in each vector
+ */
+ void arm_sub_q31(
+ q31_t * pSrcA,
+ q31_t * pSrcB,
+ q31_t * pDst,
+ uint32_t blockSize);
+
+
+ /**
+ * @brief Multiplies a floating-point vector by a scalar.
+ * @param[in] pSrc points to the input vector
+ * @param[in] scale scale factor to be applied
+ * @param[out] pDst points to the output vector
+ * @param[in] blockSize number of samples in the vector
+ */
+ void arm_scale_f32(
+ float32_t * pSrc,
+ float32_t scale,
+ float32_t * pDst,
+ uint32_t blockSize);
+
+
+ /**
+ * @brief Multiplies a Q7 vector by a scalar.
+ * @param[in] pSrc points to the input vector
+ * @param[in] scaleFract fractional portion of the scale value
+ * @param[in] shift number of bits to shift the result by
+ * @param[out] pDst points to the output vector
+ * @param[in] blockSize number of samples in the vector
+ */
+ void arm_scale_q7(
+ q7_t * pSrc,
+ q7_t scaleFract,
+ int8_t shift,
+ q7_t * pDst,
+ uint32_t blockSize);
+
+
+ /**
+ * @brief Multiplies a Q15 vector by a scalar.
+ * @param[in] pSrc points to the input vector
+ * @param[in] scaleFract fractional portion of the scale value
+ * @param[in] shift number of bits to shift the result by
+ * @param[out] pDst points to the output vector
+ * @param[in] blockSize number of samples in the vector
+ */
+ void arm_scale_q15(
+ q15_t * pSrc,
+ q15_t scaleFract,
+ int8_t shift,
+ q15_t * pDst,
+ uint32_t blockSize);
+
+
+ /**
+ * @brief Multiplies a Q31 vector by a scalar.
+ * @param[in] pSrc points to the input vector
+ * @param[in] scaleFract fractional portion of the scale value
+ * @param[in] shift number of bits to shift the result by
+ * @param[out] pDst points to the output vector
+ * @param[in] blockSize number of samples in the vector
+ */
+ void arm_scale_q31(
+ q31_t * pSrc,
+ q31_t scaleFract,
+ int8_t shift,
+ q31_t * pDst,
+ uint32_t blockSize);
+
+
+ /**
+ * @brief Q7 vector absolute value.
+ * @param[in] pSrc points to the input buffer
+ * @param[out] pDst points to the output buffer
+ * @param[in] blockSize number of samples in each vector
+ */
+ void arm_abs_q7(
+ q7_t * pSrc,
+ q7_t * pDst,
+ uint32_t blockSize);
+
+
+ /**
+ * @brief Floating-point vector absolute value.
+ * @param[in] pSrc points to the input buffer
+ * @param[out] pDst points to the output buffer
+ * @param[in] blockSize number of samples in each vector
+ */
+ void arm_abs_f32(
+ float32_t * pSrc,
+ float32_t * pDst,
+ uint32_t blockSize);
+
+
+ /**
+ * @brief Q15 vector absolute value.
+ * @param[in] pSrc points to the input buffer
+ * @param[out] pDst points to the output buffer
+ * @param[in] blockSize number of samples in each vector
+ */
+ void arm_abs_q15(
+ q15_t * pSrc,
+ q15_t * pDst,
+ uint32_t blockSize);
+
+
+ /**
+ * @brief Q31 vector absolute value.
+ * @param[in] pSrc points to the input buffer
+ * @param[out] pDst points to the output buffer
+ * @param[in] blockSize number of samples in each vector
+ */
+ void arm_abs_q31(
+ q31_t * pSrc,
+ q31_t * pDst,
+ uint32_t blockSize);
+
+
+ /**
+ * @brief Dot product of floating-point vectors.
+ * @param[in] pSrcA points to the first input vector
+ * @param[in] pSrcB points to the second input vector
+ * @param[in] blockSize number of samples in each vector
+ * @param[out] result output result returned here
+ */
+ void arm_dot_prod_f32(
+ float32_t * pSrcA,
+ float32_t * pSrcB,
+ uint32_t blockSize,
+ float32_t * result);
+
+
+ /**
+ * @brief Dot product of Q7 vectors.
+ * @param[in] pSrcA points to the first input vector
+ * @param[in] pSrcB points to the second input vector
+ * @param[in] blockSize number of samples in each vector
+ * @param[out] result output result returned here
+ */
+ void arm_dot_prod_q7(
+ q7_t * pSrcA,
+ q7_t * pSrcB,
+ uint32_t blockSize,
+ q31_t * result);
+
+
+ /**
+ * @brief Dot product of Q15 vectors.
+ * @param[in] pSrcA points to the first input vector
+ * @param[in] pSrcB points to the second input vector
+ * @param[in] blockSize number of samples in each vector
+ * @param[out] result output result returned here
+ */
+ void arm_dot_prod_q15(
+ q15_t * pSrcA,
+ q15_t * pSrcB,
+ uint32_t blockSize,
+ q63_t * result);
+
+
+ /**
+ * @brief Dot product of Q31 vectors.
+ * @param[in] pSrcA points to the first input vector
+ * @param[in] pSrcB points to the second input vector
+ * @param[in] blockSize number of samples in each vector
+ * @param[out] result output result returned here
+ */
+ void arm_dot_prod_q31(
+ q31_t * pSrcA,
+ q31_t * pSrcB,
+ uint32_t blockSize,
+ q63_t * result);
+
+
+ /**
+ * @brief Shifts the elements of a Q7 vector a specified number of bits.
+ * @param[in] pSrc points to the input vector
+ * @param[in] shiftBits number of bits to shift. A positive value shifts left; a negative value shifts right.
+ * @param[out] pDst points to the output vector
+ * @param[in] blockSize number of samples in the vector
+ */
+ void arm_shift_q7(
+ q7_t * pSrc,
+ int8_t shiftBits,
+ q7_t * pDst,
+ uint32_t blockSize);
+
+
+ /**
+ * @brief Shifts the elements of a Q15 vector a specified number of bits.
+ * @param[in] pSrc points to the input vector
+ * @param[in] shiftBits number of bits to shift. A positive value shifts left; a negative value shifts right.
+ * @param[out] pDst points to the output vector
+ * @param[in] blockSize number of samples in the vector
+ */
+ void arm_shift_q15(
+ q15_t * pSrc,
+ int8_t shiftBits,
+ q15_t * pDst,
+ uint32_t blockSize);
+
+
+ /**
+ * @brief Shifts the elements of a Q31 vector a specified number of bits.
+ * @param[in] pSrc points to the input vector
+ * @param[in] shiftBits number of bits to shift. A positive value shifts left; a negative value shifts right.
+ * @param[out] pDst points to the output vector
+ * @param[in] blockSize number of samples in the vector
+ */
+ void arm_shift_q31(
+ q31_t * pSrc,
+ int8_t shiftBits,
+ q31_t * pDst,
+ uint32_t blockSize);
+
+
+ /**
+ * @brief Adds a constant offset to a floating-point vector.
+ * @param[in] pSrc points to the input vector
+ * @param[in] offset is the offset to be added
+ * @param[out] pDst points to the output vector
+ * @param[in] blockSize number of samples in the vector
+ */
+ void arm_offset_f32(
+ float32_t * pSrc,
+ float32_t offset,
+ float32_t * pDst,
+ uint32_t blockSize);
+
+
+ /**
+ * @brief Adds a constant offset to a Q7 vector.
+ * @param[in] pSrc points to the input vector
+ * @param[in] offset is the offset to be added
+ * @param[out] pDst points to the output vector
+ * @param[in] blockSize number of samples in the vector
+ */
+ void arm_offset_q7(
+ q7_t * pSrc,
+ q7_t offset,
+ q7_t * pDst,
+ uint32_t blockSize);
+
+
+ /**
+ * @brief Adds a constant offset to a Q15 vector.
+ * @param[in] pSrc points to the input vector
+ * @param[in] offset is the offset to be added
+ * @param[out] pDst points to the output vector
+ * @param[in] blockSize number of samples in the vector
+ */
+ void arm_offset_q15(
+ q15_t * pSrc,
+ q15_t offset,
+ q15_t * pDst,
+ uint32_t blockSize);
+
+
+ /**
+ * @brief Adds a constant offset to a Q31 vector.
+ * @param[in] pSrc points to the input vector
+ * @param[in] offset is the offset to be added
+ * @param[out] pDst points to the output vector
+ * @param[in] blockSize number of samples in the vector
+ */
+ void arm_offset_q31(
+ q31_t * pSrc,
+ q31_t offset,
+ q31_t * pDst,
+ uint32_t blockSize);
+
+
+ /**
+ * @brief Negates the elements of a floating-point vector.
+ * @param[in] pSrc points to the input vector
+ * @param[out] pDst points to the output vector
+ * @param[in] blockSize number of samples in the vector
+ */
+ void arm_negate_f32(
+ float32_t * pSrc,
+ float32_t * pDst,
+ uint32_t blockSize);
+
+
+ /**
+ * @brief Negates the elements of a Q7 vector.
+ * @param[in] pSrc points to the input vector
+ * @param[out] pDst points to the output vector
+ * @param[in] blockSize number of samples in the vector
+ */
+ void arm_negate_q7(
+ q7_t * pSrc,
+ q7_t * pDst,
+ uint32_t blockSize);
+
+
+ /**
+ * @brief Negates the elements of a Q15 vector.
+ * @param[in] pSrc points to the input vector
+ * @param[out] pDst points to the output vector
+ * @param[in] blockSize number of samples in the vector
+ */
+ void arm_negate_q15(
+ q15_t * pSrc,
+ q15_t * pDst,
+ uint32_t blockSize);
+
+
+ /**
+ * @brief Negates the elements of a Q31 vector.
+ * @param[in] pSrc points to the input vector
+ * @param[out] pDst points to the output vector
+ * @param[in] blockSize number of samples in the vector
+ */
+ void arm_negate_q31(
+ q31_t * pSrc,
+ q31_t * pDst,
+ uint32_t blockSize);
+
+
+ /**
+ * @brief Copies the elements of a floating-point vector.
+ * @param[in] pSrc input pointer
+ * @param[out] pDst output pointer
+ * @param[in] blockSize number of samples to process
+ */
+ void arm_copy_f32(
+ float32_t * pSrc,
+ float32_t * pDst,
+ uint32_t blockSize);
+
+
+ /**
+ * @brief Copies the elements of a Q7 vector.
+ * @param[in] pSrc input pointer
+ * @param[out] pDst output pointer
+ * @param[in] blockSize number of samples to process
+ */
+ void arm_copy_q7(
+ q7_t * pSrc,
+ q7_t * pDst,
+ uint32_t blockSize);
+
+
+ /**
+ * @brief Copies the elements of a Q15 vector.
+ * @param[in] pSrc input pointer
+ * @param[out] pDst output pointer
+ * @param[in] blockSize number of samples to process
+ */
+ void arm_copy_q15(
+ q15_t * pSrc,
+ q15_t * pDst,
+ uint32_t blockSize);
+
+
+ /**
+ * @brief Copies the elements of a Q31 vector.
+ * @param[in] pSrc input pointer
+ * @param[out] pDst output pointer
+ * @param[in] blockSize number of samples to process
+ */
+ void arm_copy_q31(
+ q31_t * pSrc,
+ q31_t * pDst,
+ uint32_t blockSize);
+
+
+ /**
+ * @brief Fills a constant value into a floating-point vector.
+ * @param[in] value input value to be filled
+ * @param[out] pDst output pointer
+ * @param[in] blockSize number of samples to process
+ */
+ void arm_fill_f32(
+ float32_t value,
+ float32_t * pDst,
+ uint32_t blockSize);
+
+
+ /**
+ * @brief Fills a constant value into a Q7 vector.
+ * @param[in] value input value to be filled
+ * @param[out] pDst output pointer
+ * @param[in] blockSize number of samples to process
+ */
+ void arm_fill_q7(
+ q7_t value,
+ q7_t * pDst,
+ uint32_t blockSize);
+
+
+ /**
+ * @brief Fills a constant value into a Q15 vector.
+ * @param[in] value input value to be filled
+ * @param[out] pDst output pointer
+ * @param[in] blockSize number of samples to process
+ */
+ void arm_fill_q15(
+ q15_t value,
+ q15_t * pDst,
+ uint32_t blockSize);
+
+
+ /**
+ * @brief Fills a constant value into a Q31 vector.
+ * @param[in] value input value to be filled
+ * @param[out] pDst output pointer
+ * @param[in] blockSize number of samples to process
+ */
+ void arm_fill_q31(
+ q31_t value,
+ q31_t * pDst,
+ uint32_t blockSize);
+
+
+/**
+ * @brief Convolution of floating-point sequences.
+ * @param[in] pSrcA points to the first input sequence.
+ * @param[in] srcALen length of the first input sequence.
+ * @param[in] pSrcB points to the second input sequence.
+ * @param[in] srcBLen length of the second input sequence.
+ * @param[out] pDst points to the location where the output result is written. Length srcALen + srcBLen-1.
+ */
+ void arm_conv_f32(
+ float32_t * pSrcA,
+ uint32_t srcALen,
+ float32_t * pSrcB,
+ uint32_t srcBLen,
+ float32_t * pDst);
+
+
+ /**
+ * @brief Convolution of Q15 sequences.
+ * @param[in] pSrcA points to the first input sequence.
+ * @param[in] srcALen length of the first input sequence.
+ * @param[in] pSrcB points to the second input sequence.
+ * @param[in] srcBLen length of the second input sequence.
+ * @param[out] pDst points to the block of output data Length srcALen + srcBLen-1.
+ * @param[in] pScratch1 points to scratch buffer of size max(srcALen, srcBLen) + 2*min(srcALen, srcBLen) - 2.
+ * @param[in] pScratch2 points to scratch buffer of size min(srcALen, srcBLen).
+ */
+ void arm_conv_opt_q15(
+ q15_t * pSrcA,
+ uint32_t srcALen,
+ q15_t * pSrcB,
+ uint32_t srcBLen,
+ q15_t * pDst,
+ q15_t * pScratch1,
+ q15_t * pScratch2);
+
+
+/**
+ * @brief Convolution of Q15 sequences.
+ * @param[in] pSrcA points to the first input sequence.
+ * @param[in] srcALen length of the first input sequence.
+ * @param[in] pSrcB points to the second input sequence.
+ * @param[in] srcBLen length of the second input sequence.
+ * @param[out] pDst points to the location where the output result is written. Length srcALen + srcBLen-1.
+ */
+ void arm_conv_q15(
+ q15_t * pSrcA,
+ uint32_t srcALen,
+ q15_t * pSrcB,
+ uint32_t srcBLen,
+ q15_t * pDst);
+
+
+ /**
+ * @brief Convolution of Q15 sequences (fast version) for Cortex-M3 and Cortex-M4
+ * @param[in] pSrcA points to the first input sequence.
+ * @param[in] srcALen length of the first input sequence.
+ * @param[in] pSrcB points to the second input sequence.
+ * @param[in] srcBLen length of the second input sequence.
+ * @param[out] pDst points to the block of output data Length srcALen + srcBLen-1.
+ */
+ void arm_conv_fast_q15(
+ q15_t * pSrcA,
+ uint32_t srcALen,
+ q15_t * pSrcB,
+ uint32_t srcBLen,
+ q15_t * pDst);
+
+
+ /**
+ * @brief Convolution of Q15 sequences (fast version) for Cortex-M3 and Cortex-M4
+ * @param[in] pSrcA points to the first input sequence.
+ * @param[in] srcALen length of the first input sequence.
+ * @param[in] pSrcB points to the second input sequence.
+ * @param[in] srcBLen length of the second input sequence.
+ * @param[out] pDst points to the block of output data Length srcALen + srcBLen-1.
+ * @param[in] pScratch1 points to scratch buffer of size max(srcALen, srcBLen) + 2*min(srcALen, srcBLen) - 2.
+ * @param[in] pScratch2 points to scratch buffer of size min(srcALen, srcBLen).
+ */
+ void arm_conv_fast_opt_q15(
+ q15_t * pSrcA,
+ uint32_t srcALen,
+ q15_t * pSrcB,
+ uint32_t srcBLen,
+ q15_t * pDst,
+ q15_t * pScratch1,
+ q15_t * pScratch2);
+
+
+ /**
+ * @brief Convolution of Q31 sequences.
+ * @param[in] pSrcA points to the first input sequence.
+ * @param[in] srcALen length of the first input sequence.
+ * @param[in] pSrcB points to the second input sequence.
+ * @param[in] srcBLen length of the second input sequence.
+ * @param[out] pDst points to the block of output data Length srcALen + srcBLen-1.
+ */
+ void arm_conv_q31(
+ q31_t * pSrcA,
+ uint32_t srcALen,
+ q31_t * pSrcB,
+ uint32_t srcBLen,
+ q31_t * pDst);
+
+
+ /**
+ * @brief Convolution of Q31 sequences (fast version) for Cortex-M3 and Cortex-M4
+ * @param[in] pSrcA points to the first input sequence.
+ * @param[in] srcALen length of the first input sequence.
+ * @param[in] pSrcB points to the second input sequence.
+ * @param[in] srcBLen length of the second input sequence.
+ * @param[out] pDst points to the block of output data Length srcALen + srcBLen-1.
+ */
+ void arm_conv_fast_q31(
+ q31_t * pSrcA,
+ uint32_t srcALen,
+ q31_t * pSrcB,
+ uint32_t srcBLen,
+ q31_t * pDst);
+
+
+ /**
+ * @brief Convolution of Q7 sequences.
+ * @param[in] pSrcA points to the first input sequence.
+ * @param[in] srcALen length of the first input sequence.
+ * @param[in] pSrcB points to the second input sequence.
+ * @param[in] srcBLen length of the second input sequence.
+ * @param[out] pDst points to the block of output data Length srcALen + srcBLen-1.
+ * @param[in] pScratch1 points to scratch buffer(of type q15_t) of size max(srcALen, srcBLen) + 2*min(srcALen, srcBLen) - 2.
+ * @param[in] pScratch2 points to scratch buffer (of type q15_t) of size min(srcALen, srcBLen).
+ */
+ void arm_conv_opt_q7(
+ q7_t * pSrcA,
+ uint32_t srcALen,
+ q7_t * pSrcB,
+ uint32_t srcBLen,
+ q7_t * pDst,
+ q15_t * pScratch1,
+ q15_t * pScratch2);
+
+
+ /**
+ * @brief Convolution of Q7 sequences.
+ * @param[in] pSrcA points to the first input sequence.
+ * @param[in] srcALen length of the first input sequence.
+ * @param[in] pSrcB points to the second input sequence.
+ * @param[in] srcBLen length of the second input sequence.
+ * @param[out] pDst points to the block of output data Length srcALen + srcBLen-1.
+ */
+ void arm_conv_q7(
+ q7_t * pSrcA,
+ uint32_t srcALen,
+ q7_t * pSrcB,
+ uint32_t srcBLen,
+ q7_t * pDst);
+
+
+ /**
+ * @brief Partial convolution of floating-point sequences.
+ * @param[in] pSrcA points to the first input sequence.
+ * @param[in] srcALen length of the first input sequence.
+ * @param[in] pSrcB points to the second input sequence.
+ * @param[in] srcBLen length of the second input sequence.
+ * @param[out] pDst points to the block of output data
+ * @param[in] firstIndex is the first output sample to start with.
+ * @param[in] numPoints is the number of output points to be computed.
+ * @return Returns either ARM_MATH_SUCCESS if the function completed correctly or ARM_MATH_ARGUMENT_ERROR if the requested subset is not in the range [0 srcALen + srcBLen-2].
+ */
+ arm_status arm_conv_partial_f32(
+ float32_t * pSrcA,
+ uint32_t srcALen,
+ float32_t * pSrcB,
+ uint32_t srcBLen,
+ float32_t * pDst,
+ uint32_t firstIndex,
+ uint32_t numPoints);
+
+
+ /**
+ * @brief Partial convolution of Q15 sequences.
+ * @param[in] pSrcA points to the first input sequence.
+ * @param[in] srcALen length of the first input sequence.
+ * @param[in] pSrcB points to the second input sequence.
+ * @param[in] srcBLen length of the second input sequence.
+ * @param[out] pDst points to the block of output data
+ * @param[in] firstIndex is the first output sample to start with.
+ * @param[in] numPoints is the number of output points to be computed.
+ * @param[in] pScratch1 points to scratch buffer of size max(srcALen, srcBLen) + 2*min(srcALen, srcBLen) - 2.
+ * @param[in] pScratch2 points to scratch buffer of size min(srcALen, srcBLen).
+ * @return Returns either ARM_MATH_SUCCESS if the function completed correctly or ARM_MATH_ARGUMENT_ERROR if the requested subset is not in the range [0 srcALen + srcBLen-2].
+ */
+ arm_status arm_conv_partial_opt_q15(
+ q15_t * pSrcA,
+ uint32_t srcALen,
+ q15_t * pSrcB,
+ uint32_t srcBLen,
+ q15_t * pDst,
+ uint32_t firstIndex,
+ uint32_t numPoints,
+ q15_t * pScratch1,
+ q15_t * pScratch2);
+
+
+ /**
+ * @brief Partial convolution of Q15 sequences.
+ * @param[in] pSrcA points to the first input sequence.
+ * @param[in] srcALen length of the first input sequence.
+ * @param[in] pSrcB points to the second input sequence.
+ * @param[in] srcBLen length of the second input sequence.
+ * @param[out] pDst points to the block of output data
+ * @param[in] firstIndex is the first output sample to start with.
+ * @param[in] numPoints is the number of output points to be computed.
+ * @return Returns either ARM_MATH_SUCCESS if the function completed correctly or ARM_MATH_ARGUMENT_ERROR if the requested subset is not in the range [0 srcALen + srcBLen-2].
+ */
+ arm_status arm_conv_partial_q15(
+ q15_t * pSrcA,
+ uint32_t srcALen,
+ q15_t * pSrcB,
+ uint32_t srcBLen,
+ q15_t * pDst,
+ uint32_t firstIndex,
+ uint32_t numPoints);
+
+
+ /**
+ * @brief Partial convolution of Q15 sequences (fast version) for Cortex-M3 and Cortex-M4
+ * @param[in] pSrcA points to the first input sequence.
+ * @param[in] srcALen length of the first input sequence.
+ * @param[in] pSrcB points to the second input sequence.
+ * @param[in] srcBLen length of the second input sequence.
+ * @param[out] pDst points to the block of output data
+ * @param[in] firstIndex is the first output sample to start with.
+ * @param[in] numPoints is the number of output points to be computed.
+ * @return Returns either ARM_MATH_SUCCESS if the function completed correctly or ARM_MATH_ARGUMENT_ERROR if the requested subset is not in the range [0 srcALen + srcBLen-2].
+ */
+ arm_status arm_conv_partial_fast_q15(
+ q15_t * pSrcA,
+ uint32_t srcALen,
+ q15_t * pSrcB,
+ uint32_t srcBLen,
+ q15_t * pDst,
+ uint32_t firstIndex,
+ uint32_t numPoints);
+
+
+ /**
+ * @brief Partial convolution of Q15 sequences (fast version) for Cortex-M3 and Cortex-M4
+ * @param[in] pSrcA points to the first input sequence.
+ * @param[in] srcALen length of the first input sequence.
+ * @param[in] pSrcB points to the second input sequence.
+ * @param[in] srcBLen length of the second input sequence.
+ * @param[out] pDst points to the block of output data
+ * @param[in] firstIndex is the first output sample to start with.
+ * @param[in] numPoints is the number of output points to be computed.
+ * @param[in] pScratch1 points to scratch buffer of size max(srcALen, srcBLen) + 2*min(srcALen, srcBLen) - 2.
+ * @param[in] pScratch2 points to scratch buffer of size min(srcALen, srcBLen).
+ * @return Returns either ARM_MATH_SUCCESS if the function completed correctly or ARM_MATH_ARGUMENT_ERROR if the requested subset is not in the range [0 srcALen + srcBLen-2].
+ */
+ arm_status arm_conv_partial_fast_opt_q15(
+ q15_t * pSrcA,
+ uint32_t srcALen,
+ q15_t * pSrcB,
+ uint32_t srcBLen,
+ q15_t * pDst,
+ uint32_t firstIndex,
+ uint32_t numPoints,
+ q15_t * pScratch1,
+ q15_t * pScratch2);
+
+
+ /**
+ * @brief Partial convolution of Q31 sequences.
+ * @param[in] pSrcA points to the first input sequence.
+ * @param[in] srcALen length of the first input sequence.
+ * @param[in] pSrcB points to the second input sequence.
+ * @param[in] srcBLen length of the second input sequence.
+ * @param[out] pDst points to the block of output data
+ * @param[in] firstIndex is the first output sample to start with.
+ * @param[in] numPoints is the number of output points to be computed.
+ * @return Returns either ARM_MATH_SUCCESS if the function completed correctly or ARM_MATH_ARGUMENT_ERROR if the requested subset is not in the range [0 srcALen + srcBLen-2].
+ */
+ arm_status arm_conv_partial_q31(
+ q31_t * pSrcA,
+ uint32_t srcALen,
+ q31_t * pSrcB,
+ uint32_t srcBLen,
+ q31_t * pDst,
+ uint32_t firstIndex,
+ uint32_t numPoints);
+
+
+ /**
+ * @brief Partial convolution of Q31 sequences (fast version) for Cortex-M3 and Cortex-M4
+ * @param[in] pSrcA points to the first input sequence.
+ * @param[in] srcALen length of the first input sequence.
+ * @param[in] pSrcB points to the second input sequence.
+ * @param[in] srcBLen length of the second input sequence.
+ * @param[out] pDst points to the block of output data
+ * @param[in] firstIndex is the first output sample to start with.
+ * @param[in] numPoints is the number of output points to be computed.
+ * @return Returns either ARM_MATH_SUCCESS if the function completed correctly or ARM_MATH_ARGUMENT_ERROR if the requested subset is not in the range [0 srcALen + srcBLen-2].
+ */
+ arm_status arm_conv_partial_fast_q31(
+ q31_t * pSrcA,
+ uint32_t srcALen,
+ q31_t * pSrcB,
+ uint32_t srcBLen,
+ q31_t * pDst,
+ uint32_t firstIndex,
+ uint32_t numPoints);
+
+
+ /**
+ * @brief Partial convolution of Q7 sequences
+ * @param[in] pSrcA points to the first input sequence.
+ * @param[in] srcALen length of the first input sequence.
+ * @param[in] pSrcB points to the second input sequence.
+ * @param[in] srcBLen length of the second input sequence.
+ * @param[out] pDst points to the block of output data
+ * @param[in] firstIndex is the first output sample to start with.
+ * @param[in] numPoints is the number of output points to be computed.
+ * @param[in] pScratch1 points to scratch buffer(of type q15_t) of size max(srcALen, srcBLen) + 2*min(srcALen, srcBLen) - 2.
+ * @param[in] pScratch2 points to scratch buffer (of type q15_t) of size min(srcALen, srcBLen).
+ * @return Returns either ARM_MATH_SUCCESS if the function completed correctly or ARM_MATH_ARGUMENT_ERROR if the requested subset is not in the range [0 srcALen + srcBLen-2].
+ */
+ arm_status arm_conv_partial_opt_q7(
+ q7_t * pSrcA,
+ uint32_t srcALen,
+ q7_t * pSrcB,
+ uint32_t srcBLen,
+ q7_t * pDst,
+ uint32_t firstIndex,
+ uint32_t numPoints,
+ q15_t * pScratch1,
+ q15_t * pScratch2);
+
+
+/**
+ * @brief Partial convolution of Q7 sequences.
+ * @param[in] pSrcA points to the first input sequence.
+ * @param[in] srcALen length of the first input sequence.
+ * @param[in] pSrcB points to the second input sequence.
+ * @param[in] srcBLen length of the second input sequence.
+ * @param[out] pDst points to the block of output data
+ * @param[in] firstIndex is the first output sample to start with.
+ * @param[in] numPoints is the number of output points to be computed.
+ * @return Returns either ARM_MATH_SUCCESS if the function completed correctly or ARM_MATH_ARGUMENT_ERROR if the requested subset is not in the range [0 srcALen + srcBLen-2].
+ */
+ arm_status arm_conv_partial_q7(
+ q7_t * pSrcA,
+ uint32_t srcALen,
+ q7_t * pSrcB,
+ uint32_t srcBLen,
+ q7_t * pDst,
+ uint32_t firstIndex,
+ uint32_t numPoints);
+
+
+ /**
+ * @brief Instance structure for the Q15 FIR decimator.
+ */
+ typedef struct
+ {
+ uint8_t M; /**< decimation factor. */
+ uint16_t numTaps; /**< number of coefficients in the filter. */
+ q15_t *pCoeffs; /**< points to the coefficient array. The array is of length numTaps.*/
+ q15_t *pState; /**< points to the state variable array. The array is of length numTaps + blockSize-1. */
+ } arm_fir_decimate_instance_q15;
+
+ /**
+ * @brief Instance structure for the Q31 FIR decimator.
+ */
+ typedef struct
+ {
+ uint8_t M; /**< decimation factor. */
+ uint16_t numTaps; /**< number of coefficients in the filter. */
+ q31_t *pCoeffs; /**< points to the coefficient array. The array is of length numTaps.*/
+ q31_t *pState; /**< points to the state variable array. The array is of length numTaps + blockSize-1. */
+ } arm_fir_decimate_instance_q31;
+
+ /**
+ * @brief Instance structure for the floating-point FIR decimator.
+ */
+ typedef struct
+ {
+ uint8_t M; /**< decimation factor. */
+ uint16_t numTaps; /**< number of coefficients in the filter. */
+ float32_t *pCoeffs; /**< points to the coefficient array. The array is of length numTaps.*/
+ float32_t *pState; /**< points to the state variable array. The array is of length numTaps + blockSize-1. */
+ } arm_fir_decimate_instance_f32;
+
+
+ /**
+ * @brief Processing function for the floating-point FIR decimator.
+ * @param[in] S points to an instance of the floating-point FIR decimator structure.
+ * @param[in] pSrc points to the block of input data.
+ * @param[out] pDst points to the block of output data
+ * @param[in] blockSize number of input samples to process per call.
+ */
+ void arm_fir_decimate_f32(
+ const arm_fir_decimate_instance_f32 * S,
+ float32_t * pSrc,
+ float32_t * pDst,
+ uint32_t blockSize);
+
+
+ /**
+ * @brief Initialization function for the floating-point FIR decimator.
+ * @param[in,out] S points to an instance of the floating-point FIR decimator structure.
+ * @param[in] numTaps number of coefficients in the filter.
+ * @param[in] M decimation factor.
+ * @param[in] pCoeffs points to the filter coefficients.
+ * @param[in] pState points to the state buffer.
+ * @param[in] blockSize number of input samples to process per call.
+ * @return The function returns ARM_MATH_SUCCESS if initialization is successful or ARM_MATH_LENGTH_ERROR if
+ * <code>blockSize</code> is not a multiple of <code>M</code>.
+ */
+ arm_status arm_fir_decimate_init_f32(
+ arm_fir_decimate_instance_f32 * S,
+ uint16_t numTaps,
+ uint8_t M,
+ float32_t * pCoeffs,
+ float32_t * pState,
+ uint32_t blockSize);
+
+
+ /**
+ * @brief Processing function for the Q15 FIR decimator.
+ * @param[in] S points to an instance of the Q15 FIR decimator structure.
+ * @param[in] pSrc points to the block of input data.
+ * @param[out] pDst points to the block of output data
+ * @param[in] blockSize number of input samples to process per call.
+ */
+ void arm_fir_decimate_q15(
+ const arm_fir_decimate_instance_q15 * S,
+ q15_t * pSrc,
+ q15_t * pDst,
+ uint32_t blockSize);
+
+
+ /**
+ * @brief Processing function for the Q15 FIR decimator (fast variant) for Cortex-M3 and Cortex-M4.
+ * @param[in] S points to an instance of the Q15 FIR decimator structure.
+ * @param[in] pSrc points to the block of input data.
+ * @param[out] pDst points to the block of output data
+ * @param[in] blockSize number of input samples to process per call.
+ */
+ void arm_fir_decimate_fast_q15(
+ const arm_fir_decimate_instance_q15 * S,
+ q15_t * pSrc,
+ q15_t * pDst,
+ uint32_t blockSize);
+
+
+ /**
+ * @brief Initialization function for the Q15 FIR decimator.
+ * @param[in,out] S points to an instance of the Q15 FIR decimator structure.
+ * @param[in] numTaps number of coefficients in the filter.
+ * @param[in] M decimation factor.
+ * @param[in] pCoeffs points to the filter coefficients.
+ * @param[in] pState points to the state buffer.
+ * @param[in] blockSize number of input samples to process per call.
+ * @return The function returns ARM_MATH_SUCCESS if initialization is successful or ARM_MATH_LENGTH_ERROR if
+ * <code>blockSize</code> is not a multiple of <code>M</code>.
+ */
+ arm_status arm_fir_decimate_init_q15(
+ arm_fir_decimate_instance_q15 * S,
+ uint16_t numTaps,
+ uint8_t M,
+ q15_t * pCoeffs,
+ q15_t * pState,
+ uint32_t blockSize);
+
+
+ /**
+ * @brief Processing function for the Q31 FIR decimator.
+ * @param[in] S points to an instance of the Q31 FIR decimator structure.
+ * @param[in] pSrc points to the block of input data.
+ * @param[out] pDst points to the block of output data
+ * @param[in] blockSize number of input samples to process per call.
+ */
+ void arm_fir_decimate_q31(
+ const arm_fir_decimate_instance_q31 * S,
+ q31_t * pSrc,
+ q31_t * pDst,
+ uint32_t blockSize);
+
+ /**
+ * @brief Processing function for the Q31 FIR decimator (fast variant) for Cortex-M3 and Cortex-M4.
+ * @param[in] S points to an instance of the Q31 FIR decimator structure.
+ * @param[in] pSrc points to the block of input data.
+ * @param[out] pDst points to the block of output data
+ * @param[in] blockSize number of input samples to process per call.
+ */
+ void arm_fir_decimate_fast_q31(
+ arm_fir_decimate_instance_q31 * S,
+ q31_t * pSrc,
+ q31_t * pDst,
+ uint32_t blockSize);
+
+
+ /**
+ * @brief Initialization function for the Q31 FIR decimator.
+ * @param[in,out] S points to an instance of the Q31 FIR decimator structure.
+ * @param[in] numTaps number of coefficients in the filter.
+ * @param[in] M decimation factor.
+ * @param[in] pCoeffs points to the filter coefficients.
+ * @param[in] pState points to the state buffer.
+ * @param[in] blockSize number of input samples to process per call.
+ * @return The function returns ARM_MATH_SUCCESS if initialization is successful or ARM_MATH_LENGTH_ERROR if
+ * <code>blockSize</code> is not a multiple of <code>M</code>.
+ */
+ arm_status arm_fir_decimate_init_q31(
+ arm_fir_decimate_instance_q31 * S,
+ uint16_t numTaps,
+ uint8_t M,
+ q31_t * pCoeffs,
+ q31_t * pState,
+ uint32_t blockSize);
+
+
+ /**
+ * @brief Instance structure for the Q15 FIR interpolator.
+ */
+ typedef struct
+ {
+ uint8_t L; /**< upsample factor. */
+ uint16_t phaseLength; /**< length of each polyphase filter component. */
+ q15_t *pCoeffs; /**< points to the coefficient array. The array is of length L*phaseLength. */
+ q15_t *pState; /**< points to the state variable array. The array is of length blockSize + phaseLength-1. */
+ } arm_fir_interpolate_instance_q15;
+
+ /**
+ * @brief Instance structure for the Q31 FIR interpolator.
+ */
+ typedef struct
+ {
+ uint8_t L; /**< upsample factor. */
+ uint16_t phaseLength; /**< length of each polyphase filter component. */
+ q31_t *pCoeffs; /**< points to the coefficient array. The array is of length L*phaseLength. */
+ q31_t *pState; /**< points to the state variable array. The array is of length blockSize + phaseLength-1. */
+ } arm_fir_interpolate_instance_q31;
+
+ /**
+ * @brief Instance structure for the floating-point FIR interpolator.
+ */
+ typedef struct
+ {
+ uint8_t L; /**< upsample factor. */
+ uint16_t phaseLength; /**< length of each polyphase filter component. */
+ float32_t *pCoeffs; /**< points to the coefficient array. The array is of length L*phaseLength. */
+ float32_t *pState; /**< points to the state variable array. The array is of length phaseLength + numTaps-1. */
+ } arm_fir_interpolate_instance_f32;
+
+
+ /**
+ * @brief Processing function for the Q15 FIR interpolator.
+ * @param[in] S points to an instance of the Q15 FIR interpolator structure.
+ * @param[in] pSrc points to the block of input data.
+ * @param[out] pDst points to the block of output data.
+ * @param[in] blockSize number of input samples to process per call.
+ */
+ void arm_fir_interpolate_q15(
+ const arm_fir_interpolate_instance_q15 * S,
+ q15_t * pSrc,
+ q15_t * pDst,
+ uint32_t blockSize);
+
+
+ /**
+ * @brief Initialization function for the Q15 FIR interpolator.
+ * @param[in,out] S points to an instance of the Q15 FIR interpolator structure.
+ * @param[in] L upsample factor.
+ * @param[in] numTaps number of filter coefficients in the filter.
+ * @param[in] pCoeffs points to the filter coefficient buffer.
+ * @param[in] pState points to the state buffer.
+ * @param[in] blockSize number of input samples to process per call.
+ * @return The function returns ARM_MATH_SUCCESS if initialization is successful or ARM_MATH_LENGTH_ERROR if
+ * the filter length <code>numTaps</code> is not a multiple of the interpolation factor <code>L</code>.
+ */
+ arm_status arm_fir_interpolate_init_q15(
+ arm_fir_interpolate_instance_q15 * S,
+ uint8_t L,
+ uint16_t numTaps,
+ q15_t * pCoeffs,
+ q15_t * pState,
+ uint32_t blockSize);
+
+
+ /**
+ * @brief Processing function for the Q31 FIR interpolator.
+ * @param[in] S points to an instance of the Q15 FIR interpolator structure.
+ * @param[in] pSrc points to the block of input data.
+ * @param[out] pDst points to the block of output data.
+ * @param[in] blockSize number of input samples to process per call.
+ */
+ void arm_fir_interpolate_q31(
+ const arm_fir_interpolate_instance_q31 * S,
+ q31_t * pSrc,
+ q31_t * pDst,
+ uint32_t blockSize);
+
+
+ /**
+ * @brief Initialization function for the Q31 FIR interpolator.
+ * @param[in,out] S points to an instance of the Q31 FIR interpolator structure.
+ * @param[in] L upsample factor.
+ * @param[in] numTaps number of filter coefficients in the filter.
+ * @param[in] pCoeffs points to the filter coefficient buffer.
+ * @param[in] pState points to the state buffer.
+ * @param[in] blockSize number of input samples to process per call.
+ * @return The function returns ARM_MATH_SUCCESS if initialization is successful or ARM_MATH_LENGTH_ERROR if
+ * the filter length <code>numTaps</code> is not a multiple of the interpolation factor <code>L</code>.
+ */
+ arm_status arm_fir_interpolate_init_q31(
+ arm_fir_interpolate_instance_q31 * S,
+ uint8_t L,
+ uint16_t numTaps,
+ q31_t * pCoeffs,
+ q31_t * pState,
+ uint32_t blockSize);
+
+
+ /**
+ * @brief Processing function for the floating-point FIR interpolator.
+ * @param[in] S points to an instance of the floating-point FIR interpolator structure.
+ * @param[in] pSrc points to the block of input data.
+ * @param[out] pDst points to the block of output data.
+ * @param[in] blockSize number of input samples to process per call.
+ */
+ void arm_fir_interpolate_f32(
+ const arm_fir_interpolate_instance_f32 * S,
+ float32_t * pSrc,
+ float32_t * pDst,
+ uint32_t blockSize);
+
+
+ /**
+ * @brief Initialization function for the floating-point FIR interpolator.
+ * @param[in,out] S points to an instance of the floating-point FIR interpolator structure.
+ * @param[in] L upsample factor.
+ * @param[in] numTaps number of filter coefficients in the filter.
+ * @param[in] pCoeffs points to the filter coefficient buffer.
+ * @param[in] pState points to the state buffer.
+ * @param[in] blockSize number of input samples to process per call.
+ * @return The function returns ARM_MATH_SUCCESS if initialization is successful or ARM_MATH_LENGTH_ERROR if
+ * the filter length <code>numTaps</code> is not a multiple of the interpolation factor <code>L</code>.
+ */
+ arm_status arm_fir_interpolate_init_f32(
+ arm_fir_interpolate_instance_f32 * S,
+ uint8_t L,
+ uint16_t numTaps,
+ float32_t * pCoeffs,
+ float32_t * pState,
+ uint32_t blockSize);
+
+
+ /**
+ * @brief Instance structure for the high precision Q31 Biquad cascade filter.
+ */
+ typedef struct
+ {
+ uint8_t numStages; /**< number of 2nd order stages in the filter. Overall order is 2*numStages. */
+ q63_t *pState; /**< points to the array of state coefficients. The array is of length 4*numStages. */
+ q31_t *pCoeffs; /**< points to the array of coefficients. The array is of length 5*numStages. */
+ uint8_t postShift; /**< additional shift, in bits, applied to each output sample. */
+ } arm_biquad_cas_df1_32x64_ins_q31;
+
+
+ /**
+ * @param[in] S points to an instance of the high precision Q31 Biquad cascade filter structure.
+ * @param[in] pSrc points to the block of input data.
+ * @param[out] pDst points to the block of output data
+ * @param[in] blockSize number of samples to process.
+ */
+ void arm_biquad_cas_df1_32x64_q31(
+ const arm_biquad_cas_df1_32x64_ins_q31 * S,
+ q31_t * pSrc,
+ q31_t * pDst,
+ uint32_t blockSize);
+
+
+ /**
+ * @param[in,out] S points to an instance of the high precision Q31 Biquad cascade filter structure.
+ * @param[in] numStages number of 2nd order stages in the filter.
+ * @param[in] pCoeffs points to the filter coefficients.
+ * @param[in] pState points to the state buffer.
+ * @param[in] postShift shift to be applied to the output. Varies according to the coefficients format
+ */
+ void arm_biquad_cas_df1_32x64_init_q31(
+ arm_biquad_cas_df1_32x64_ins_q31 * S,
+ uint8_t numStages,
+ q31_t * pCoeffs,
+ q63_t * pState,
+ uint8_t postShift);
+
+
+ /**
+ * @brief Instance structure for the floating-point transposed direct form II Biquad cascade filter.
+ */
+ typedef struct
+ {
+ uint8_t numStages; /**< number of 2nd order stages in the filter. Overall order is 2*numStages. */
+ float32_t *pState; /**< points to the array of state coefficients. The array is of length 2*numStages. */
+ float32_t *pCoeffs; /**< points to the array of coefficients. The array is of length 5*numStages. */
+ } arm_biquad_cascade_df2T_instance_f32;
+
+ /**
+ * @brief Instance structure for the floating-point transposed direct form II Biquad cascade filter.
+ */
+ typedef struct
+ {
+ uint8_t numStages; /**< number of 2nd order stages in the filter. Overall order is 2*numStages. */
+ float32_t *pState; /**< points to the array of state coefficients. The array is of length 4*numStages. */
+ float32_t *pCoeffs; /**< points to the array of coefficients. The array is of length 5*numStages. */
+ } arm_biquad_cascade_stereo_df2T_instance_f32;
+
+ /**
+ * @brief Instance structure for the floating-point transposed direct form II Biquad cascade filter.
+ */
+ typedef struct
+ {
+ uint8_t numStages; /**< number of 2nd order stages in the filter. Overall order is 2*numStages. */
+ float64_t *pState; /**< points to the array of state coefficients. The array is of length 2*numStages. */
+ float64_t *pCoeffs; /**< points to the array of coefficients. The array is of length 5*numStages. */
+ } arm_biquad_cascade_df2T_instance_f64;
+
+
+ /**
+ * @brief Processing function for the floating-point transposed direct form II Biquad cascade filter.
+ * @param[in] S points to an instance of the filter data structure.
+ * @param[in] pSrc points to the block of input data.
+ * @param[out] pDst points to the block of output data
+ * @param[in] blockSize number of samples to process.
+ */
+ void arm_biquad_cascade_df2T_f32(
+ const arm_biquad_cascade_df2T_instance_f32 * S,
+ float32_t * pSrc,
+ float32_t * pDst,
+ uint32_t blockSize);
+
+
+ /**
+ * @brief Processing function for the floating-point transposed direct form II Biquad cascade filter. 2 channels
+ * @param[in] S points to an instance of the filter data structure.
+ * @param[in] pSrc points to the block of input data.
+ * @param[out] pDst points to the block of output data
+ * @param[in] blockSize number of samples to process.
+ */
+ void arm_biquad_cascade_stereo_df2T_f32(
+ const arm_biquad_cascade_stereo_df2T_instance_f32 * S,
+ float32_t * pSrc,
+ float32_t * pDst,
+ uint32_t blockSize);
+
+
+ /**
+ * @brief Processing function for the floating-point transposed direct form II Biquad cascade filter.
+ * @param[in] S points to an instance of the filter data structure.
+ * @param[in] pSrc points to the block of input data.
+ * @param[out] pDst points to the block of output data
+ * @param[in] blockSize number of samples to process.
+ */
+ void arm_biquad_cascade_df2T_f64(
+ const arm_biquad_cascade_df2T_instance_f64 * S,
+ float64_t * pSrc,
+ float64_t * pDst,
+ uint32_t blockSize);
+
+
+ /**
+ * @brief Initialization function for the floating-point transposed direct form II Biquad cascade filter.
+ * @param[in,out] S points to an instance of the filter data structure.
+ * @param[in] numStages number of 2nd order stages in the filter.
+ * @param[in] pCoeffs points to the filter coefficients.
+ * @param[in] pState points to the state buffer.
+ */
+ void arm_biquad_cascade_df2T_init_f32(
+ arm_biquad_cascade_df2T_instance_f32 * S,
+ uint8_t numStages,
+ float32_t * pCoeffs,
+ float32_t * pState);
+
+
+ /**
+ * @brief Initialization function for the floating-point transposed direct form II Biquad cascade filter.
+ * @param[in,out] S points to an instance of the filter data structure.
+ * @param[in] numStages number of 2nd order stages in the filter.
+ * @param[in] pCoeffs points to the filter coefficients.
+ * @param[in] pState points to the state buffer.
+ */
+ void arm_biquad_cascade_stereo_df2T_init_f32(
+ arm_biquad_cascade_stereo_df2T_instance_f32 * S,
+ uint8_t numStages,
+ float32_t * pCoeffs,
+ float32_t * pState);
+
+
+ /**
+ * @brief Initialization function for the floating-point transposed direct form II Biquad cascade filter.
+ * @param[in,out] S points to an instance of the filter data structure.
+ * @param[in] numStages number of 2nd order stages in the filter.
+ * @param[in] pCoeffs points to the filter coefficients.
+ * @param[in] pState points to the state buffer.
+ */
+ void arm_biquad_cascade_df2T_init_f64(
+ arm_biquad_cascade_df2T_instance_f64 * S,
+ uint8_t numStages,
+ float64_t * pCoeffs,
+ float64_t * pState);
+
+
+ /**
+ * @brief Instance structure for the Q15 FIR lattice filter.
+ */
+ typedef struct
+ {
+ uint16_t numStages; /**< number of filter stages. */
+ q15_t *pState; /**< points to the state variable array. The array is of length numStages. */
+ q15_t *pCoeffs; /**< points to the coefficient array. The array is of length numStages. */
+ } arm_fir_lattice_instance_q15;
+
+ /**
+ * @brief Instance structure for the Q31 FIR lattice filter.
+ */
+ typedef struct
+ {
+ uint16_t numStages; /**< number of filter stages. */
+ q31_t *pState; /**< points to the state variable array. The array is of length numStages. */
+ q31_t *pCoeffs; /**< points to the coefficient array. The array is of length numStages. */
+ } arm_fir_lattice_instance_q31;
+
+ /**
+ * @brief Instance structure for the floating-point FIR lattice filter.
+ */
+ typedef struct
+ {
+ uint16_t numStages; /**< number of filter stages. */
+ float32_t *pState; /**< points to the state variable array. The array is of length numStages. */
+ float32_t *pCoeffs; /**< points to the coefficient array. The array is of length numStages. */
+ } arm_fir_lattice_instance_f32;
+
+
+ /**
+ * @brief Initialization function for the Q15 FIR lattice filter.
+ * @param[in] S points to an instance of the Q15 FIR lattice structure.
+ * @param[in] numStages number of filter stages.
+ * @param[in] pCoeffs points to the coefficient buffer. The array is of length numStages.
+ * @param[in] pState points to the state buffer. The array is of length numStages.
+ */
+ void arm_fir_lattice_init_q15(
+ arm_fir_lattice_instance_q15 * S,
+ uint16_t numStages,
+ q15_t * pCoeffs,
+ q15_t * pState);
+
+
+ /**
+ * @brief Processing function for the Q15 FIR lattice filter.
+ * @param[in] S points to an instance of the Q15 FIR lattice structure.
+ * @param[in] pSrc points to the block of input data.
+ * @param[out] pDst points to the block of output data.
+ * @param[in] blockSize number of samples to process.
+ */
+ void arm_fir_lattice_q15(
+ const arm_fir_lattice_instance_q15 * S,
+ q15_t * pSrc,
+ q15_t * pDst,
+ uint32_t blockSize);
+
+
+ /**
+ * @brief Initialization function for the Q31 FIR lattice filter.
+ * @param[in] S points to an instance of the Q31 FIR lattice structure.
+ * @param[in] numStages number of filter stages.
+ * @param[in] pCoeffs points to the coefficient buffer. The array is of length numStages.
+ * @param[in] pState points to the state buffer. The array is of length numStages.
+ */
+ void arm_fir_lattice_init_q31(
+ arm_fir_lattice_instance_q31 * S,
+ uint16_t numStages,
+ q31_t * pCoeffs,
+ q31_t * pState);
+
+
+ /**
+ * @brief Processing function for the Q31 FIR lattice filter.
+ * @param[in] S points to an instance of the Q31 FIR lattice structure.
+ * @param[in] pSrc points to the block of input data.
+ * @param[out] pDst points to the block of output data
+ * @param[in] blockSize number of samples to process.
+ */
+ void arm_fir_lattice_q31(
+ const arm_fir_lattice_instance_q31 * S,
+ q31_t * pSrc,
+ q31_t * pDst,
+ uint32_t blockSize);
+
+
+/**
+ * @brief Initialization function for the floating-point FIR lattice filter.
+ * @param[in] S points to an instance of the floating-point FIR lattice structure.
+ * @param[in] numStages number of filter stages.
+ * @param[in] pCoeffs points to the coefficient buffer. The array is of length numStages.
+ * @param[in] pState points to the state buffer. The array is of length numStages.
+ */
+ void arm_fir_lattice_init_f32(
+ arm_fir_lattice_instance_f32 * S,
+ uint16_t numStages,
+ float32_t * pCoeffs,
+ float32_t * pState);
+
+
+ /**
+ * @brief Processing function for the floating-point FIR lattice filter.
+ * @param[in] S points to an instance of the floating-point FIR lattice structure.
+ * @param[in] pSrc points to the block of input data.
+ * @param[out] pDst points to the block of output data
+ * @param[in] blockSize number of samples to process.
+ */
+ void arm_fir_lattice_f32(
+ const arm_fir_lattice_instance_f32 * S,
+ float32_t * pSrc,
+ float32_t * pDst,
+ uint32_t blockSize);
+
+
+ /**
+ * @brief Instance structure for the Q15 IIR lattice filter.
+ */
+ typedef struct
+ {
+ uint16_t numStages; /**< number of stages in the filter. */
+ q15_t *pState; /**< points to the state variable array. The array is of length numStages + blockSize. */
+ q15_t *pkCoeffs; /**< points to the reflection coefficient array. The array is of length numStages. */
+ q15_t *pvCoeffs; /**< points to the ladder coefficient array. The array is of length numStages + 1. */
+ } arm_iir_lattice_instance_q15;
+
+ /**
+ * @brief Instance structure for the Q31 IIR lattice filter.
+ */
+ typedef struct
+ {
+ uint16_t numStages; /**< number of stages in the filter. */
+ q31_t *pState; /**< points to the state variable array. The array is of length numStages + blockSize. */
+ q31_t *pkCoeffs; /**< points to the reflection coefficient array. The array is of length numStages. */
+ q31_t *pvCoeffs; /**< points to the ladder coefficient array. The array is of length numStages + 1. */
+ } arm_iir_lattice_instance_q31;
+
+ /**
+ * @brief Instance structure for the floating-point IIR lattice filter.
+ */
+ typedef struct
+ {
+ uint16_t numStages; /**< number of stages in the filter. */
+ float32_t *pState; /**< points to the state variable array. The array is of length numStages + blockSize. */
+ float32_t *pkCoeffs; /**< points to the reflection coefficient array. The array is of length numStages. */
+ float32_t *pvCoeffs; /**< points to the ladder coefficient array. The array is of length numStages + 1. */
+ } arm_iir_lattice_instance_f32;
+
+
+ /**
+ * @brief Processing function for the floating-point IIR lattice filter.
+ * @param[in] S points to an instance of the floating-point IIR lattice structure.
+ * @param[in] pSrc points to the block of input data.
+ * @param[out] pDst points to the block of output data.
+ * @param[in] blockSize number of samples to process.
+ */
+ void arm_iir_lattice_f32(
+ const arm_iir_lattice_instance_f32 * S,
+ float32_t * pSrc,
+ float32_t * pDst,
+ uint32_t blockSize);
+
+
+ /**
+ * @brief Initialization function for the floating-point IIR lattice filter.
+ * @param[in] S points to an instance of the floating-point IIR lattice structure.
+ * @param[in] numStages number of stages in the filter.
+ * @param[in] pkCoeffs points to the reflection coefficient buffer. The array is of length numStages.
+ * @param[in] pvCoeffs points to the ladder coefficient buffer. The array is of length numStages + 1.
+ * @param[in] pState points to the state buffer. The array is of length numStages + blockSize-1.
+ * @param[in] blockSize number of samples to process.
+ */
+ void arm_iir_lattice_init_f32(
+ arm_iir_lattice_instance_f32 * S,
+ uint16_t numStages,
+ float32_t * pkCoeffs,
+ float32_t * pvCoeffs,
+ float32_t * pState,
+ uint32_t blockSize);
+
+
+ /**
+ * @brief Processing function for the Q31 IIR lattice filter.
+ * @param[in] S points to an instance of the Q31 IIR lattice structure.
+ * @param[in] pSrc points to the block of input data.
+ * @param[out] pDst points to the block of output data.
+ * @param[in] blockSize number of samples to process.
+ */
+ void arm_iir_lattice_q31(
+ const arm_iir_lattice_instance_q31 * S,
+ q31_t * pSrc,
+ q31_t * pDst,
+ uint32_t blockSize);
+
+
+ /**
+ * @brief Initialization function for the Q31 IIR lattice filter.
+ * @param[in] S points to an instance of the Q31 IIR lattice structure.
+ * @param[in] numStages number of stages in the filter.
+ * @param[in] pkCoeffs points to the reflection coefficient buffer. The array is of length numStages.
+ * @param[in] pvCoeffs points to the ladder coefficient buffer. The array is of length numStages + 1.
+ * @param[in] pState points to the state buffer. The array is of length numStages + blockSize.
+ * @param[in] blockSize number of samples to process.
+ */
+ void arm_iir_lattice_init_q31(
+ arm_iir_lattice_instance_q31 * S,
+ uint16_t numStages,
+ q31_t * pkCoeffs,
+ q31_t * pvCoeffs,
+ q31_t * pState,
+ uint32_t blockSize);
+
+
+ /**
+ * @brief Processing function for the Q15 IIR lattice filter.
+ * @param[in] S points to an instance of the Q15 IIR lattice structure.
+ * @param[in] pSrc points to the block of input data.
+ * @param[out] pDst points to the block of output data.
+ * @param[in] blockSize number of samples to process.
+ */
+ void arm_iir_lattice_q15(
+ const arm_iir_lattice_instance_q15 * S,
+ q15_t * pSrc,
+ q15_t * pDst,
+ uint32_t blockSize);
+
+
+/**
+ * @brief Initialization function for the Q15 IIR lattice filter.
+ * @param[in] S points to an instance of the fixed-point Q15 IIR lattice structure.
+ * @param[in] numStages number of stages in the filter.
+ * @param[in] pkCoeffs points to reflection coefficient buffer. The array is of length numStages.
+ * @param[in] pvCoeffs points to ladder coefficient buffer. The array is of length numStages + 1.
+ * @param[in] pState points to state buffer. The array is of length numStages + blockSize.
+ * @param[in] blockSize number of samples to process per call.
+ */
+ void arm_iir_lattice_init_q15(
+ arm_iir_lattice_instance_q15 * S,
+ uint16_t numStages,
+ q15_t * pkCoeffs,
+ q15_t * pvCoeffs,
+ q15_t * pState,
+ uint32_t blockSize);
+
+
+ /**
+ * @brief Instance structure for the floating-point LMS filter.
+ */
+ typedef struct
+ {
+ uint16_t numTaps; /**< number of coefficients in the filter. */
+ float32_t *pState; /**< points to the state variable array. The array is of length numTaps + blockSize-1. */
+ float32_t *pCoeffs; /**< points to the coefficient array. The array is of length numTaps. */
+ float32_t mu; /**< step size that controls filter coefficient updates. */
+ } arm_lms_instance_f32;
+
+
+ /**
+ * @brief Processing function for floating-point LMS filter.
+ * @param[in] S points to an instance of the floating-point LMS filter structure.
+ * @param[in] pSrc points to the block of input data.
+ * @param[in] pRef points to the block of reference data.
+ * @param[out] pOut points to the block of output data.
+ * @param[out] pErr points to the block of error data.
+ * @param[in] blockSize number of samples to process.
+ */
+ void arm_lms_f32(
+ const arm_lms_instance_f32 * S,
+ float32_t * pSrc,
+ float32_t * pRef,
+ float32_t * pOut,
+ float32_t * pErr,
+ uint32_t blockSize);
+
+
+ /**
+ * @brief Initialization function for floating-point LMS filter.
+ * @param[in] S points to an instance of the floating-point LMS filter structure.
+ * @param[in] numTaps number of filter coefficients.
+ * @param[in] pCoeffs points to the coefficient buffer.
+ * @param[in] pState points to state buffer.
+ * @param[in] mu step size that controls filter coefficient updates.
+ * @param[in] blockSize number of samples to process.
+ */
+ void arm_lms_init_f32(
+ arm_lms_instance_f32 * S,
+ uint16_t numTaps,
+ float32_t * pCoeffs,
+ float32_t * pState,
+ float32_t mu,
+ uint32_t blockSize);
+
+
+ /**
+ * @brief Instance structure for the Q15 LMS filter.
+ */
+ typedef struct
+ {
+ uint16_t numTaps; /**< number of coefficients in the filter. */
+ q15_t *pState; /**< points to the state variable array. The array is of length numTaps + blockSize-1. */
+ q15_t *pCoeffs; /**< points to the coefficient array. The array is of length numTaps. */
+ q15_t mu; /**< step size that controls filter coefficient updates. */
+ uint32_t postShift; /**< bit shift applied to coefficients. */
+ } arm_lms_instance_q15;
+
+
+ /**
+ * @brief Initialization function for the Q15 LMS filter.
+ * @param[in] S points to an instance of the Q15 LMS filter structure.
+ * @param[in] numTaps number of filter coefficients.
+ * @param[in] pCoeffs points to the coefficient buffer.
+ * @param[in] pState points to the state buffer.
+ * @param[in] mu step size that controls filter coefficient updates.
+ * @param[in] blockSize number of samples to process.
+ * @param[in] postShift bit shift applied to coefficients.
+ */
+ void arm_lms_init_q15(
+ arm_lms_instance_q15 * S,
+ uint16_t numTaps,
+ q15_t * pCoeffs,
+ q15_t * pState,
+ q15_t mu,
+ uint32_t blockSize,
+ uint32_t postShift);
+
+
+ /**
+ * @brief Processing function for Q15 LMS filter.
+ * @param[in] S points to an instance of the Q15 LMS filter structure.
+ * @param[in] pSrc points to the block of input data.
+ * @param[in] pRef points to the block of reference data.
+ * @param[out] pOut points to the block of output data.
+ * @param[out] pErr points to the block of error data.
+ * @param[in] blockSize number of samples to process.
+ */
+ void arm_lms_q15(
+ const arm_lms_instance_q15 * S,
+ q15_t * pSrc,
+ q15_t * pRef,
+ q15_t * pOut,
+ q15_t * pErr,
+ uint32_t blockSize);
+
+
+ /**
+ * @brief Instance structure for the Q31 LMS filter.
+ */
+ typedef struct
+ {
+ uint16_t numTaps; /**< number of coefficients in the filter. */
+ q31_t *pState; /**< points to the state variable array. The array is of length numTaps + blockSize-1. */
+ q31_t *pCoeffs; /**< points to the coefficient array. The array is of length numTaps. */
+ q31_t mu; /**< step size that controls filter coefficient updates. */
+ uint32_t postShift; /**< bit shift applied to coefficients. */
+ } arm_lms_instance_q31;
+
+
+ /**
+ * @brief Processing function for Q31 LMS filter.
+ * @param[in] S points to an instance of the Q15 LMS filter structure.
+ * @param[in] pSrc points to the block of input data.
+ * @param[in] pRef points to the block of reference data.
+ * @param[out] pOut points to the block of output data.
+ * @param[out] pErr points to the block of error data.
+ * @param[in] blockSize number of samples to process.
+ */
+ void arm_lms_q31(
+ const arm_lms_instance_q31 * S,
+ q31_t * pSrc,
+ q31_t * pRef,
+ q31_t * pOut,
+ q31_t * pErr,
+ uint32_t blockSize);
+
+
+ /**
+ * @brief Initialization function for Q31 LMS filter.
+ * @param[in] S points to an instance of the Q31 LMS filter structure.
+ * @param[in] numTaps number of filter coefficients.
+ * @param[in] pCoeffs points to coefficient buffer.
+ * @param[in] pState points to state buffer.
+ * @param[in] mu step size that controls filter coefficient updates.
+ * @param[in] blockSize number of samples to process.
+ * @param[in] postShift bit shift applied to coefficients.
+ */
+ void arm_lms_init_q31(
+ arm_lms_instance_q31 * S,
+ uint16_t numTaps,
+ q31_t * pCoeffs,
+ q31_t * pState,
+ q31_t mu,
+ uint32_t blockSize,
+ uint32_t postShift);
+
+
+ /**
+ * @brief Instance structure for the floating-point normalized LMS filter.
+ */
+ typedef struct
+ {
+ uint16_t numTaps; /**< number of coefficients in the filter. */
+ float32_t *pState; /**< points to the state variable array. The array is of length numTaps + blockSize-1. */
+ float32_t *pCoeffs; /**< points to the coefficient array. The array is of length numTaps. */
+ float32_t mu; /**< step size that control filter coefficient updates. */
+ float32_t energy; /**< saves previous frame energy. */
+ float32_t x0; /**< saves previous input sample. */
+ } arm_lms_norm_instance_f32;
+
+
+ /**
+ * @brief Processing function for floating-point normalized LMS filter.
+ * @param[in] S points to an instance of the floating-point normalized LMS filter structure.
+ * @param[in] pSrc points to the block of input data.
+ * @param[in] pRef points to the block of reference data.
+ * @param[out] pOut points to the block of output data.
+ * @param[out] pErr points to the block of error data.
+ * @param[in] blockSize number of samples to process.
+ */
+ void arm_lms_norm_f32(
+ arm_lms_norm_instance_f32 * S,
+ float32_t * pSrc,
+ float32_t * pRef,
+ float32_t * pOut,
+ float32_t * pErr,
+ uint32_t blockSize);
+
+
+ /**
+ * @brief Initialization function for floating-point normalized LMS filter.
+ * @param[in] S points to an instance of the floating-point LMS filter structure.
+ * @param[in] numTaps number of filter coefficients.
+ * @param[in] pCoeffs points to coefficient buffer.
+ * @param[in] pState points to state buffer.
+ * @param[in] mu step size that controls filter coefficient updates.
+ * @param[in] blockSize number of samples to process.
+ */
+ void arm_lms_norm_init_f32(
+ arm_lms_norm_instance_f32 * S,
+ uint16_t numTaps,
+ float32_t * pCoeffs,
+ float32_t * pState,
+ float32_t mu,
+ uint32_t blockSize);
+
+
+ /**
+ * @brief Instance structure for the Q31 normalized LMS filter.
+ */
+ typedef struct
+ {
+ uint16_t numTaps; /**< number of coefficients in the filter. */
+ q31_t *pState; /**< points to the state variable array. The array is of length numTaps + blockSize-1. */
+ q31_t *pCoeffs; /**< points to the coefficient array. The array is of length numTaps. */
+ q31_t mu; /**< step size that controls filter coefficient updates. */
+ uint8_t postShift; /**< bit shift applied to coefficients. */
+ q31_t *recipTable; /**< points to the reciprocal initial value table. */
+ q31_t energy; /**< saves previous frame energy. */
+ q31_t x0; /**< saves previous input sample. */
+ } arm_lms_norm_instance_q31;
+
+
+ /**
+ * @brief Processing function for Q31 normalized LMS filter.
+ * @param[in] S points to an instance of the Q31 normalized LMS filter structure.
+ * @param[in] pSrc points to the block of input data.
+ * @param[in] pRef points to the block of reference data.
+ * @param[out] pOut points to the block of output data.
+ * @param[out] pErr points to the block of error data.
+ * @param[in] blockSize number of samples to process.
+ */
+ void arm_lms_norm_q31(
+ arm_lms_norm_instance_q31 * S,
+ q31_t * pSrc,
+ q31_t * pRef,
+ q31_t * pOut,
+ q31_t * pErr,
+ uint32_t blockSize);
+
+
+ /**
+ * @brief Initialization function for Q31 normalized LMS filter.
+ * @param[in] S points to an instance of the Q31 normalized LMS filter structure.
+ * @param[in] numTaps number of filter coefficients.
+ * @param[in] pCoeffs points to coefficient buffer.
+ * @param[in] pState points to state buffer.
+ * @param[in] mu step size that controls filter coefficient updates.
+ * @param[in] blockSize number of samples to process.
+ * @param[in] postShift bit shift applied to coefficients.
+ */
+ void arm_lms_norm_init_q31(
+ arm_lms_norm_instance_q31 * S,
+ uint16_t numTaps,
+ q31_t * pCoeffs,
+ q31_t * pState,
+ q31_t mu,
+ uint32_t blockSize,
+ uint8_t postShift);
+
+
+ /**
+ * @brief Instance structure for the Q15 normalized LMS filter.
+ */
+ typedef struct
+ {
+ uint16_t numTaps; /**< Number of coefficients in the filter. */
+ q15_t *pState; /**< points to the state variable array. The array is of length numTaps + blockSize-1. */
+ q15_t *pCoeffs; /**< points to the coefficient array. The array is of length numTaps. */
+ q15_t mu; /**< step size that controls filter coefficient updates. */
+ uint8_t postShift; /**< bit shift applied to coefficients. */
+ q15_t *recipTable; /**< Points to the reciprocal initial value table. */
+ q15_t energy; /**< saves previous frame energy. */
+ q15_t x0; /**< saves previous input sample. */
+ } arm_lms_norm_instance_q15;
+
+
+ /**
+ * @brief Processing function for Q15 normalized LMS filter.
+ * @param[in] S points to an instance of the Q15 normalized LMS filter structure.
+ * @param[in] pSrc points to the block of input data.
+ * @param[in] pRef points to the block of reference data.
+ * @param[out] pOut points to the block of output data.
+ * @param[out] pErr points to the block of error data.
+ * @param[in] blockSize number of samples to process.
+ */
+ void arm_lms_norm_q15(
+ arm_lms_norm_instance_q15 * S,
+ q15_t * pSrc,
+ q15_t * pRef,
+ q15_t * pOut,
+ q15_t * pErr,
+ uint32_t blockSize);
+
+
+ /**
+ * @brief Initialization function for Q15 normalized LMS filter.
+ * @param[in] S points to an instance of the Q15 normalized LMS filter structure.
+ * @param[in] numTaps number of filter coefficients.
+ * @param[in] pCoeffs points to coefficient buffer.
+ * @param[in] pState points to state buffer.
+ * @param[in] mu step size that controls filter coefficient updates.
+ * @param[in] blockSize number of samples to process.
+ * @param[in] postShift bit shift applied to coefficients.
+ */
+ void arm_lms_norm_init_q15(
+ arm_lms_norm_instance_q15 * S,
+ uint16_t numTaps,
+ q15_t * pCoeffs,
+ q15_t * pState,
+ q15_t mu,
+ uint32_t blockSize,
+ uint8_t postShift);
+
+
+ /**
+ * @brief Correlation of floating-point sequences.
+ * @param[in] pSrcA points to the first input sequence.
+ * @param[in] srcALen length of the first input sequence.
+ * @param[in] pSrcB points to the second input sequence.
+ * @param[in] srcBLen length of the second input sequence.
+ * @param[out] pDst points to the block of output data Length 2 * max(srcALen, srcBLen) - 1.
+ */
+ void arm_correlate_f32(
+ float32_t * pSrcA,
+ uint32_t srcALen,
+ float32_t * pSrcB,
+ uint32_t srcBLen,
+ float32_t * pDst);
+
+
+ /**
+ * @brief Correlation of Q15 sequences
+ * @param[in] pSrcA points to the first input sequence.
+ * @param[in] srcALen length of the first input sequence.
+ * @param[in] pSrcB points to the second input sequence.
+ * @param[in] srcBLen length of the second input sequence.
+ * @param[out] pDst points to the block of output data Length 2 * max(srcALen, srcBLen) - 1.
+ * @param[in] pScratch points to scratch buffer of size max(srcALen, srcBLen) + 2*min(srcALen, srcBLen) - 2.
+ */
+ void arm_correlate_opt_q15(
+ q15_t * pSrcA,
+ uint32_t srcALen,
+ q15_t * pSrcB,
+ uint32_t srcBLen,
+ q15_t * pDst,
+ q15_t * pScratch);
+
+
+ /**
+ * @brief Correlation of Q15 sequences.
+ * @param[in] pSrcA points to the first input sequence.
+ * @param[in] srcALen length of the first input sequence.
+ * @param[in] pSrcB points to the second input sequence.
+ * @param[in] srcBLen length of the second input sequence.
+ * @param[out] pDst points to the block of output data Length 2 * max(srcALen, srcBLen) - 1.
+ */
+
+ void arm_correlate_q15(
+ q15_t * pSrcA,
+ uint32_t srcALen,
+ q15_t * pSrcB,
+ uint32_t srcBLen,
+ q15_t * pDst);
+
+
+ /**
+ * @brief Correlation of Q15 sequences (fast version) for Cortex-M3 and Cortex-M4.
+ * @param[in] pSrcA points to the first input sequence.
+ * @param[in] srcALen length of the first input sequence.
+ * @param[in] pSrcB points to the second input sequence.
+ * @param[in] srcBLen length of the second input sequence.
+ * @param[out] pDst points to the block of output data Length 2 * max(srcALen, srcBLen) - 1.
+ */
+
+ void arm_correlate_fast_q15(
+ q15_t * pSrcA,
+ uint32_t srcALen,
+ q15_t * pSrcB,
+ uint32_t srcBLen,
+ q15_t * pDst);
+
+
+ /**
+ * @brief Correlation of Q15 sequences (fast version) for Cortex-M3 and Cortex-M4.
+ * @param[in] pSrcA points to the first input sequence.
+ * @param[in] srcALen length of the first input sequence.
+ * @param[in] pSrcB points to the second input sequence.
+ * @param[in] srcBLen length of the second input sequence.
+ * @param[out] pDst points to the block of output data Length 2 * max(srcALen, srcBLen) - 1.
+ * @param[in] pScratch points to scratch buffer of size max(srcALen, srcBLen) + 2*min(srcALen, srcBLen) - 2.
+ */
+ void arm_correlate_fast_opt_q15(
+ q15_t * pSrcA,
+ uint32_t srcALen,
+ q15_t * pSrcB,
+ uint32_t srcBLen,
+ q15_t * pDst,
+ q15_t * pScratch);
+
+
+ /**
+ * @brief Correlation of Q31 sequences.
+ * @param[in] pSrcA points to the first input sequence.
+ * @param[in] srcALen length of the first input sequence.
+ * @param[in] pSrcB points to the second input sequence.
+ * @param[in] srcBLen length of the second input sequence.
+ * @param[out] pDst points to the block of output data Length 2 * max(srcALen, srcBLen) - 1.
+ */
+ void arm_correlate_q31(
+ q31_t * pSrcA,
+ uint32_t srcALen,
+ q31_t * pSrcB,
+ uint32_t srcBLen,
+ q31_t * pDst);
+
+
+ /**
+ * @brief Correlation of Q31 sequences (fast version) for Cortex-M3 and Cortex-M4
+ * @param[in] pSrcA points to the first input sequence.
+ * @param[in] srcALen length of the first input sequence.
+ * @param[in] pSrcB points to the second input sequence.
+ * @param[in] srcBLen length of the second input sequence.
+ * @param[out] pDst points to the block of output data Length 2 * max(srcALen, srcBLen) - 1.
+ */
+ void arm_correlate_fast_q31(
+ q31_t * pSrcA,
+ uint32_t srcALen,
+ q31_t * pSrcB,
+ uint32_t srcBLen,
+ q31_t * pDst);
+
+
+ /**
+ * @brief Correlation of Q7 sequences.
+ * @param[in] pSrcA points to the first input sequence.
+ * @param[in] srcALen length of the first input sequence.
+ * @param[in] pSrcB points to the second input sequence.
+ * @param[in] srcBLen length of the second input sequence.
+ * @param[out] pDst points to the block of output data Length 2 * max(srcALen, srcBLen) - 1.
+ * @param[in] pScratch1 points to scratch buffer(of type q15_t) of size max(srcALen, srcBLen) + 2*min(srcALen, srcBLen) - 2.
+ * @param[in] pScratch2 points to scratch buffer (of type q15_t) of size min(srcALen, srcBLen).
+ */
+ void arm_correlate_opt_q7(
+ q7_t * pSrcA,
+ uint32_t srcALen,
+ q7_t * pSrcB,
+ uint32_t srcBLen,
+ q7_t * pDst,
+ q15_t * pScratch1,
+ q15_t * pScratch2);
+
+
+ /**
+ * @brief Correlation of Q7 sequences.
+ * @param[in] pSrcA points to the first input sequence.
+ * @param[in] srcALen length of the first input sequence.
+ * @param[in] pSrcB points to the second input sequence.
+ * @param[in] srcBLen length of the second input sequence.
+ * @param[out] pDst points to the block of output data Length 2 * max(srcALen, srcBLen) - 1.
+ */
+ void arm_correlate_q7(
+ q7_t * pSrcA,
+ uint32_t srcALen,
+ q7_t * pSrcB,
+ uint32_t srcBLen,
+ q7_t * pDst);
+
+
+ /**
+ * @brief Instance structure for the floating-point sparse FIR filter.
+ */
+ typedef struct
+ {
+ uint16_t numTaps; /**< number of coefficients in the filter. */
+ uint16_t stateIndex; /**< state buffer index. Points to the oldest sample in the state buffer. */
+ float32_t *pState; /**< points to the state buffer array. The array is of length maxDelay + blockSize-1. */
+ float32_t *pCoeffs; /**< points to the coefficient array. The array is of length numTaps.*/
+ uint16_t maxDelay; /**< maximum offset specified by the pTapDelay array. */
+ int32_t *pTapDelay; /**< points to the array of delay values. The array is of length numTaps. */
+ } arm_fir_sparse_instance_f32;
+
+ /**
+ * @brief Instance structure for the Q31 sparse FIR filter.
+ */
+ typedef struct
+ {
+ uint16_t numTaps; /**< number of coefficients in the filter. */
+ uint16_t stateIndex; /**< state buffer index. Points to the oldest sample in the state buffer. */
+ q31_t *pState; /**< points to the state buffer array. The array is of length maxDelay + blockSize-1. */
+ q31_t *pCoeffs; /**< points to the coefficient array. The array is of length numTaps.*/
+ uint16_t maxDelay; /**< maximum offset specified by the pTapDelay array. */
+ int32_t *pTapDelay; /**< points to the array of delay values. The array is of length numTaps. */
+ } arm_fir_sparse_instance_q31;
+
+ /**
+ * @brief Instance structure for the Q15 sparse FIR filter.
+ */
+ typedef struct
+ {
+ uint16_t numTaps; /**< number of coefficients in the filter. */
+ uint16_t stateIndex; /**< state buffer index. Points to the oldest sample in the state buffer. */
+ q15_t *pState; /**< points to the state buffer array. The array is of length maxDelay + blockSize-1. */
+ q15_t *pCoeffs; /**< points to the coefficient array. The array is of length numTaps.*/
+ uint16_t maxDelay; /**< maximum offset specified by the pTapDelay array. */
+ int32_t *pTapDelay; /**< points to the array of delay values. The array is of length numTaps. */
+ } arm_fir_sparse_instance_q15;
+
+ /**
+ * @brief Instance structure for the Q7 sparse FIR filter.
+ */
+ typedef struct
+ {
+ uint16_t numTaps; /**< number of coefficients in the filter. */
+ uint16_t stateIndex; /**< state buffer index. Points to the oldest sample in the state buffer. */
+ q7_t *pState; /**< points to the state buffer array. The array is of length maxDelay + blockSize-1. */
+ q7_t *pCoeffs; /**< points to the coefficient array. The array is of length numTaps.*/
+ uint16_t maxDelay; /**< maximum offset specified by the pTapDelay array. */
+ int32_t *pTapDelay; /**< points to the array of delay values. The array is of length numTaps. */
+ } arm_fir_sparse_instance_q7;
+
+
+ /**
+ * @brief Processing function for the floating-point sparse FIR filter.
+ * @param[in] S points to an instance of the floating-point sparse FIR structure.
+ * @param[in] pSrc points to the block of input data.
+ * @param[out] pDst points to the block of output data
+ * @param[in] pScratchIn points to a temporary buffer of size blockSize.
+ * @param[in] blockSize number of input samples to process per call.
+ */
+ void arm_fir_sparse_f32(
+ arm_fir_sparse_instance_f32 * S,
+ float32_t * pSrc,
+ float32_t * pDst,
+ float32_t * pScratchIn,
+ uint32_t blockSize);
+
+
+ /**
+ * @brief Initialization function for the floating-point sparse FIR filter.
+ * @param[in,out] S points to an instance of the floating-point sparse FIR structure.
+ * @param[in] numTaps number of nonzero coefficients in the filter.
+ * @param[in] pCoeffs points to the array of filter coefficients.
+ * @param[in] pState points to the state buffer.
+ * @param[in] pTapDelay points to the array of offset times.
+ * @param[in] maxDelay maximum offset time supported.
+ * @param[in] blockSize number of samples that will be processed per block.
+ */
+ void arm_fir_sparse_init_f32(
+ arm_fir_sparse_instance_f32 * S,
+ uint16_t numTaps,
+ float32_t * pCoeffs,
+ float32_t * pState,
+ int32_t * pTapDelay,
+ uint16_t maxDelay,
+ uint32_t blockSize);
+
+
+ /**
+ * @brief Processing function for the Q31 sparse FIR filter.
+ * @param[in] S points to an instance of the Q31 sparse FIR structure.
+ * @param[in] pSrc points to the block of input data.
+ * @param[out] pDst points to the block of output data
+ * @param[in] pScratchIn points to a temporary buffer of size blockSize.
+ * @param[in] blockSize number of input samples to process per call.
+ */
+ void arm_fir_sparse_q31(
+ arm_fir_sparse_instance_q31 * S,
+ q31_t * pSrc,
+ q31_t * pDst,
+ q31_t * pScratchIn,
+ uint32_t blockSize);
+
+
+ /**
+ * @brief Initialization function for the Q31 sparse FIR filter.
+ * @param[in,out] S points to an instance of the Q31 sparse FIR structure.
+ * @param[in] numTaps number of nonzero coefficients in the filter.
+ * @param[in] pCoeffs points to the array of filter coefficients.
+ * @param[in] pState points to the state buffer.
+ * @param[in] pTapDelay points to the array of offset times.
+ * @param[in] maxDelay maximum offset time supported.
+ * @param[in] blockSize number of samples that will be processed per block.
+ */
+ void arm_fir_sparse_init_q31(
+ arm_fir_sparse_instance_q31 * S,
+ uint16_t numTaps,
+ q31_t * pCoeffs,
+ q31_t * pState,
+ int32_t * pTapDelay,
+ uint16_t maxDelay,
+ uint32_t blockSize);
+
+
+ /**
+ * @brief Processing function for the Q15 sparse FIR filter.
+ * @param[in] S points to an instance of the Q15 sparse FIR structure.
+ * @param[in] pSrc points to the block of input data.
+ * @param[out] pDst points to the block of output data
+ * @param[in] pScratchIn points to a temporary buffer of size blockSize.
+ * @param[in] pScratchOut points to a temporary buffer of size blockSize.
+ * @param[in] blockSize number of input samples to process per call.
+ */
+ void arm_fir_sparse_q15(
+ arm_fir_sparse_instance_q15 * S,
+ q15_t * pSrc,
+ q15_t * pDst,
+ q15_t * pScratchIn,
+ q31_t * pScratchOut,
+ uint32_t blockSize);
+
+
+ /**
+ * @brief Initialization function for the Q15 sparse FIR filter.
+ * @param[in,out] S points to an instance of the Q15 sparse FIR structure.
+ * @param[in] numTaps number of nonzero coefficients in the filter.
+ * @param[in] pCoeffs points to the array of filter coefficients.
+ * @param[in] pState points to the state buffer.
+ * @param[in] pTapDelay points to the array of offset times.
+ * @param[in] maxDelay maximum offset time supported.
+ * @param[in] blockSize number of samples that will be processed per block.
+ */
+ void arm_fir_sparse_init_q15(
+ arm_fir_sparse_instance_q15 * S,
+ uint16_t numTaps,
+ q15_t * pCoeffs,
+ q15_t * pState,
+ int32_t * pTapDelay,
+ uint16_t maxDelay,
+ uint32_t blockSize);
+
+
+ /**
+ * @brief Processing function for the Q7 sparse FIR filter.
+ * @param[in] S points to an instance of the Q7 sparse FIR structure.
+ * @param[in] pSrc points to the block of input data.
+ * @param[out] pDst points to the block of output data
+ * @param[in] pScratchIn points to a temporary buffer of size blockSize.
+ * @param[in] pScratchOut points to a temporary buffer of size blockSize.
+ * @param[in] blockSize number of input samples to process per call.
+ */
+ void arm_fir_sparse_q7(
+ arm_fir_sparse_instance_q7 * S,
+ q7_t * pSrc,
+ q7_t * pDst,
+ q7_t * pScratchIn,
+ q31_t * pScratchOut,
+ uint32_t blockSize);
+
+
+ /**
+ * @brief Initialization function for the Q7 sparse FIR filter.
+ * @param[in,out] S points to an instance of the Q7 sparse FIR structure.
+ * @param[in] numTaps number of nonzero coefficients in the filter.
+ * @param[in] pCoeffs points to the array of filter coefficients.
+ * @param[in] pState points to the state buffer.
+ * @param[in] pTapDelay points to the array of offset times.
+ * @param[in] maxDelay maximum offset time supported.
+ * @param[in] blockSize number of samples that will be processed per block.
+ */
+ void arm_fir_sparse_init_q7(
+ arm_fir_sparse_instance_q7 * S,
+ uint16_t numTaps,
+ q7_t * pCoeffs,
+ q7_t * pState,
+ int32_t * pTapDelay,
+ uint16_t maxDelay,
+ uint32_t blockSize);
+
+
+ /**
+ * @brief Floating-point sin_cos function.
+ * @param[in] theta input value in degrees
+ * @param[out] pSinVal points to the processed sine output.
+ * @param[out] pCosVal points to the processed cos output.
+ */
+ void arm_sin_cos_f32(
+ float32_t theta,
+ float32_t * pSinVal,
+ float32_t * pCosVal);
+
+
+ /**
+ * @brief Q31 sin_cos function.
+ * @param[in] theta scaled input value in degrees
+ * @param[out] pSinVal points to the processed sine output.
+ * @param[out] pCosVal points to the processed cosine output.
+ */
+ void arm_sin_cos_q31(
+ q31_t theta,
+ q31_t * pSinVal,
+ q31_t * pCosVal);
+
+
+ /**
+ * @brief Floating-point complex conjugate.
+ * @param[in] pSrc points to the input vector
+ * @param[out] pDst points to the output vector
+ * @param[in] numSamples number of complex samples in each vector
+ */
+ void arm_cmplx_conj_f32(
+ float32_t * pSrc,
+ float32_t * pDst,
+ uint32_t numSamples);
+
+ /**
+ * @brief Q31 complex conjugate.
+ * @param[in] pSrc points to the input vector
+ * @param[out] pDst points to the output vector
+ * @param[in] numSamples number of complex samples in each vector
+ */
+ void arm_cmplx_conj_q31(
+ q31_t * pSrc,
+ q31_t * pDst,
+ uint32_t numSamples);
+
+
+ /**
+ * @brief Q15 complex conjugate.
+ * @param[in] pSrc points to the input vector
+ * @param[out] pDst points to the output vector
+ * @param[in] numSamples number of complex samples in each vector
+ */
+ void arm_cmplx_conj_q15(
+ q15_t * pSrc,
+ q15_t * pDst,
+ uint32_t numSamples);
+
+
+ /**
+ * @brief Floating-point complex magnitude squared
+ * @param[in] pSrc points to the complex input vector
+ * @param[out] pDst points to the real output vector
+ * @param[in] numSamples number of complex samples in the input vector
+ */
+ void arm_cmplx_mag_squared_f32(
+ float32_t * pSrc,
+ float32_t * pDst,
+ uint32_t numSamples);
+
+
+ /**
+ * @brief Q31 complex magnitude squared
+ * @param[in] pSrc points to the complex input vector
+ * @param[out] pDst points to the real output vector
+ * @param[in] numSamples number of complex samples in the input vector
+ */
+ void arm_cmplx_mag_squared_q31(
+ q31_t * pSrc,
+ q31_t * pDst,
+ uint32_t numSamples);
+
+
+ /**
+ * @brief Q15 complex magnitude squared
+ * @param[in] pSrc points to the complex input vector
+ * @param[out] pDst points to the real output vector
+ * @param[in] numSamples number of complex samples in the input vector
+ */
+ void arm_cmplx_mag_squared_q15(
+ q15_t * pSrc,
+ q15_t * pDst,
+ uint32_t numSamples);
+
+
+ /**
+ * @ingroup groupController
+ */
+
+ /**
+ * @defgroup PID PID Motor Control
+ *
+ * A Proportional Integral Derivative (PID) controller is a generic feedback control
+ * loop mechanism widely used in industrial control systems.
+ * A PID controller is the most commonly used type of feedback controller.
+ *
+ * This set of functions implements (PID) controllers
+ * for Q15, Q31, and floating-point data types. The functions operate on a single sample
+ * of data and each call to the function returns a single processed value.
+ * <code>S</code> points to an instance of the PID control data structure. <code>in</code>
+ * is the input sample value. The functions return the output value.
+ *
+ * \par Algorithm:
+ * <pre>
+ * y[n] = y[n-1] + A0 * x[n] + A1 * x[n-1] + A2 * x[n-2]
+ * A0 = Kp + Ki + Kd
+ * A1 = (-Kp ) - (2 * Kd )
+ * A2 = Kd </pre>
+ *
+ * \par
+ * where \c Kp is proportional constant, \c Ki is Integral constant and \c Kd is Derivative constant
+ *
+ * \par
+ * \image html PID.gif "Proportional Integral Derivative Controller"
+ *
+ * \par
+ * The PID controller calculates an "error" value as the difference between
+ * the measured output and the reference input.
+ * The controller attempts to minimize the error by adjusting the process control inputs.
+ * The proportional value determines the reaction to the current error,
+ * the integral value determines the reaction based on the sum of recent errors,
+ * and the derivative value determines the reaction based on the rate at which the error has been changing.
+ *
+ * \par Instance Structure
+ * The Gains A0, A1, A2 and state variables for a PID controller are stored together in an instance data structure.
+ * A separate instance structure must be defined for each PID Controller.
+ * There are separate instance structure declarations for each of the 3 supported data types.
+ *
+ * \par Reset Functions
+ * There is also an associated reset function for each data type which clears the state array.
+ *
+ * \par Initialization Functions
+ * There is also an associated initialization function for each data type.
+ * The initialization function performs the following operations:
+ * - Initializes the Gains A0, A1, A2 from Kp,Ki, Kd gains.
+ * - Zeros out the values in the state buffer.
+ *
+ * \par
+ * Instance structure cannot be placed into a const data section and it is recommended to use the initialization function.
+ *
+ * \par Fixed-Point Behavior
+ * Care must be taken when using the fixed-point versions of the PID Controller functions.
+ * In particular, the overflow and saturation behavior of the accumulator used in each function must be considered.
+ * Refer to the function specific documentation below for usage guidelines.
+ */
+
+ /**
+ * @addtogroup PID
+ * @{
+ */
+
+ /**
+ * @brief Process function for the floating-point PID Control.
+ * @param[in,out] S is an instance of the floating-point PID Control structure
+ * @param[in] in input sample to process
+ * @return out processed output sample.
+ */
+ static __INLINE float32_t arm_pid_f32(
+ arm_pid_instance_f32 * S,
+ float32_t in)
+ {
+ float32_t out;
+
+ /* y[n] = y[n-1] + A0 * x[n] + A1 * x[n-1] + A2 * x[n-2] */
+ out = (S->A0 * in) +
+ (S->A1 * S->state[0]) + (S->A2 * S->state[1]) + (S->state[2]);
+
+ /* Update state */
+ S->state[1] = S->state[0];
+ S->state[0] = in;
+ S->state[2] = out;
+
+ /* return to application */
+ return (out);
+
+ }
+
+ /**
+ * @brief Process function for the Q31 PID Control.
+ * @param[in,out] S points to an instance of the Q31 PID Control structure
+ * @param[in] in input sample to process
+ * @return out processed output sample.
+ *
+ * <b>Scaling and Overflow Behavior:</b>
+ * \par
+ * The function is implemented using an internal 64-bit accumulator.
+ * The accumulator has a 2.62 format and maintains full precision of the intermediate multiplication results but provides only a single guard bit.
+ * Thus, if the accumulator result overflows it wraps around rather than clip.
+ * In order to avoid overflows completely the input signal must be scaled down by 2 bits as there are four additions.
+ * After all multiply-accumulates are performed, the 2.62 accumulator is truncated to 1.32 format and then saturated to 1.31 format.
+ */
+ static __INLINE q31_t arm_pid_q31(
+ arm_pid_instance_q31 * S,
+ q31_t in)
+ {
+ q63_t acc;
+ q31_t out;
+
+ /* acc = A0 * x[n] */
+ acc = (q63_t) S->A0 * in;
+
+ /* acc += A1 * x[n-1] */
+ acc += (q63_t) S->A1 * S->state[0];
+
+ /* acc += A2 * x[n-2] */
+ acc += (q63_t) S->A2 * S->state[1];
+
+ /* convert output to 1.31 format to add y[n-1] */
+ out = (q31_t) (acc >> 31u);
+
+ /* out += y[n-1] */
+ out += S->state[2];
+
+ /* Update state */
+ S->state[1] = S->state[0];
+ S->state[0] = in;
+ S->state[2] = out;
+
+ /* return to application */
+ return (out);
+ }
+
+
+ /**
+ * @brief Process function for the Q15 PID Control.
+ * @param[in,out] S points to an instance of the Q15 PID Control structure
+ * @param[in] in input sample to process
+ * @return out processed output sample.
+ *
+ * <b>Scaling and Overflow Behavior:</b>
+ * \par
+ * The function is implemented using a 64-bit internal accumulator.
+ * Both Gains and state variables are represented in 1.15 format and multiplications yield a 2.30 result.
+ * The 2.30 intermediate results are accumulated in a 64-bit accumulator in 34.30 format.
+ * There is no risk of internal overflow with this approach and the full precision of intermediate multiplications is preserved.
+ * After all additions have been performed, the accumulator is truncated to 34.15 format by discarding low 15 bits.
+ * Lastly, the accumulator is saturated to yield a result in 1.15 format.
+ */
+ static __INLINE q15_t arm_pid_q15(
+ arm_pid_instance_q15 * S,
+ q15_t in)
+ {
+ q63_t acc;
+ q15_t out;
+
+#ifndef ARM_MATH_CM0_FAMILY
+ __SIMD32_TYPE *vstate;
+
+ /* Implementation of PID controller */
+
+ /* acc = A0 * x[n] */
+ acc = (q31_t) __SMUAD((uint32_t)S->A0, (uint32_t)in);
+
+ /* acc += A1 * x[n-1] + A2 * x[n-2] */
+ vstate = __SIMD32_CONST(S->state);
+ acc = (q63_t)__SMLALD((uint32_t)S->A1, (uint32_t)*vstate, (uint64_t)acc);
+#else
+ /* acc = A0 * x[n] */
+ acc = ((q31_t) S->A0) * in;
+
+ /* acc += A1 * x[n-1] + A2 * x[n-2] */
+ acc += (q31_t) S->A1 * S->state[0];
+ acc += (q31_t) S->A2 * S->state[1];
+#endif
+
+ /* acc += y[n-1] */
+ acc += (q31_t) S->state[2] << 15;
+
+ /* saturate the output */
+ out = (q15_t) (__SSAT((acc >> 15), 16));
+
+ /* Update state */
+ S->state[1] = S->state[0];
+ S->state[0] = in;
+ S->state[2] = out;
+
+ /* return to application */
+ return (out);
+ }
+
+ /**
+ * @} end of PID group
+ */
+
+
+ /**
+ * @brief Floating-point matrix inverse.
+ * @param[in] src points to the instance of the input floating-point matrix structure.
+ * @param[out] dst points to the instance of the output floating-point matrix structure.
+ * @return The function returns ARM_MATH_SIZE_MISMATCH, if the dimensions do not match.
+ * If the input matrix is singular (does not have an inverse), then the algorithm terminates and returns error status ARM_MATH_SINGULAR.
+ */
+ arm_status arm_mat_inverse_f32(
+ const arm_matrix_instance_f32 * src,
+ arm_matrix_instance_f32 * dst);
+
+
+ /**
+ * @brief Floating-point matrix inverse.
+ * @param[in] src points to the instance of the input floating-point matrix structure.
+ * @param[out] dst points to the instance of the output floating-point matrix structure.
+ * @return The function returns ARM_MATH_SIZE_MISMATCH, if the dimensions do not match.
+ * If the input matrix is singular (does not have an inverse), then the algorithm terminates and returns error status ARM_MATH_SINGULAR.
+ */
+ arm_status arm_mat_inverse_f64(
+ const arm_matrix_instance_f64 * src,
+ arm_matrix_instance_f64 * dst);
+
+
+
+ /**
+ * @ingroup groupController
+ */
+
+ /**
+ * @defgroup clarke Vector Clarke Transform
+ * Forward Clarke transform converts the instantaneous stator phases into a two-coordinate time invariant vector.
+ * Generally the Clarke transform uses three-phase currents <code>Ia, Ib and Ic</code> to calculate currents
+ * in the two-phase orthogonal stator axis <code>Ialpha</code> and <code>Ibeta</code>.
+ * When <code>Ialpha</code> is superposed with <code>Ia</code> as shown in the figure below
+ * \image html clarke.gif Stator current space vector and its components in (a,b).
+ * and <code>Ia + Ib + Ic = 0</code>, in this condition <code>Ialpha</code> and <code>Ibeta</code>
+ * can be calculated using only <code>Ia</code> and <code>Ib</code>.
+ *
+ * The function operates on a single sample of data and each call to the function returns the processed output.
+ * The library provides separate functions for Q31 and floating-point data types.
+ * \par Algorithm
+ * \image html clarkeFormula.gif
+ * where <code>Ia</code> and <code>Ib</code> are the instantaneous stator phases and
+ * <code>pIalpha</code> and <code>pIbeta</code> are the two coordinates of time invariant vector.
+ * \par Fixed-Point Behavior
+ * Care must be taken when using the Q31 version of the Clarke transform.
+ * In particular, the overflow and saturation behavior of the accumulator used must be considered.
+ * Refer to the function specific documentation below for usage guidelines.
+ */
+
+ /**
+ * @addtogroup clarke
+ * @{
+ */
+
+ /**
+ *
+ * @brief Floating-point Clarke transform
+ * @param[in] Ia input three-phase coordinate <code>a</code>
+ * @param[in] Ib input three-phase coordinate <code>b</code>
+ * @param[out] pIalpha points to output two-phase orthogonal vector axis alpha
+ * @param[out] pIbeta points to output two-phase orthogonal vector axis beta
+ */
+ static __INLINE void arm_clarke_f32(
+ float32_t Ia,
+ float32_t Ib,
+ float32_t * pIalpha,
+ float32_t * pIbeta)
+ {
+ /* Calculate pIalpha using the equation, pIalpha = Ia */
+ *pIalpha = Ia;
+
+ /* Calculate pIbeta using the equation, pIbeta = (1/sqrt(3)) * Ia + (2/sqrt(3)) * Ib */
+ *pIbeta = ((float32_t) 0.57735026919 * Ia + (float32_t) 1.15470053838 * Ib);
+ }
+
+
+ /**
+ * @brief Clarke transform for Q31 version
+ * @param[in] Ia input three-phase coordinate <code>a</code>
+ * @param[in] Ib input three-phase coordinate <code>b</code>
+ * @param[out] pIalpha points to output two-phase orthogonal vector axis alpha
+ * @param[out] pIbeta points to output two-phase orthogonal vector axis beta
+ *
+ * <b>Scaling and Overflow Behavior:</b>
+ * \par
+ * The function is implemented using an internal 32-bit accumulator.
+ * The accumulator maintains 1.31 format by truncating lower 31 bits of the intermediate multiplication in 2.62 format.
+ * There is saturation on the addition, hence there is no risk of overflow.
+ */
+ static __INLINE void arm_clarke_q31(
+ q31_t Ia,
+ q31_t Ib,
+ q31_t * pIalpha,
+ q31_t * pIbeta)
+ {
+ q31_t product1, product2; /* Temporary variables used to store intermediate results */
+
+ /* Calculating pIalpha from Ia by equation pIalpha = Ia */
+ *pIalpha = Ia;
+
+ /* Intermediate product is calculated by (1/(sqrt(3)) * Ia) */
+ product1 = (q31_t) (((q63_t) Ia * 0x24F34E8B) >> 30);
+
+ /* Intermediate product is calculated by (2/sqrt(3) * Ib) */
+ product2 = (q31_t) (((q63_t) Ib * 0x49E69D16) >> 30);
+
+ /* pIbeta is calculated by adding the intermediate products */
+ *pIbeta = __QADD(product1, product2);
+ }
+
+ /**
+ * @} end of clarke group
+ */
+
+ /**
+ * @brief Converts the elements of the Q7 vector to Q31 vector.
+ * @param[in] pSrc input pointer
+ * @param[out] pDst output pointer
+ * @param[in] blockSize number of samples to process
+ */
+ void arm_q7_to_q31(
+ q7_t * pSrc,
+ q31_t * pDst,
+ uint32_t blockSize);
+
+
+
+ /**
+ * @ingroup groupController
+ */
+
+ /**
+ * @defgroup inv_clarke Vector Inverse Clarke Transform
+ * Inverse Clarke transform converts the two-coordinate time invariant vector into instantaneous stator phases.
+ *
+ * The function operates on a single sample of data and each call to the function returns the processed output.
+ * The library provides separate functions for Q31 and floating-point data types.
+ * \par Algorithm
+ * \image html clarkeInvFormula.gif
+ * where <code>pIa</code> and <code>pIb</code> are the instantaneous stator phases and
+ * <code>Ialpha</code> and <code>Ibeta</code> are the two coordinates of time invariant vector.
+ * \par Fixed-Point Behavior
+ * Care must be taken when using the Q31 version of the Clarke transform.
+ * In particular, the overflow and saturation behavior of the accumulator used must be considered.
+ * Refer to the function specific documentation below for usage guidelines.
+ */
+
+ /**
+ * @addtogroup inv_clarke
+ * @{
+ */
+
+ /**
+ * @brief Floating-point Inverse Clarke transform
+ * @param[in] Ialpha input two-phase orthogonal vector axis alpha
+ * @param[in] Ibeta input two-phase orthogonal vector axis beta
+ * @param[out] pIa points to output three-phase coordinate <code>a</code>
+ * @param[out] pIb points to output three-phase coordinate <code>b</code>
+ */
+ static __INLINE void arm_inv_clarke_f32(
+ float32_t Ialpha,
+ float32_t Ibeta,
+ float32_t * pIa,
+ float32_t * pIb)
+ {
+ /* Calculating pIa from Ialpha by equation pIa = Ialpha */
+ *pIa = Ialpha;
+
+ /* Calculating pIb from Ialpha and Ibeta by equation pIb = -(1/2) * Ialpha + (sqrt(3)/2) * Ibeta */
+ *pIb = -0.5f * Ialpha + 0.8660254039f * Ibeta;
+ }
+
+
+ /**
+ * @brief Inverse Clarke transform for Q31 version
+ * @param[in] Ialpha input two-phase orthogonal vector axis alpha
+ * @param[in] Ibeta input two-phase orthogonal vector axis beta
+ * @param[out] pIa points to output three-phase coordinate <code>a</code>
+ * @param[out] pIb points to output three-phase coordinate <code>b</code>
+ *
+ * <b>Scaling and Overflow Behavior:</b>
+ * \par
+ * The function is implemented using an internal 32-bit accumulator.
+ * The accumulator maintains 1.31 format by truncating lower 31 bits of the intermediate multiplication in 2.62 format.
+ * There is saturation on the subtraction, hence there is no risk of overflow.
+ */
+ static __INLINE void arm_inv_clarke_q31(
+ q31_t Ialpha,
+ q31_t Ibeta,
+ q31_t * pIa,
+ q31_t * pIb)
+ {
+ q31_t product1, product2; /* Temporary variables used to store intermediate results */
+
+ /* Calculating pIa from Ialpha by equation pIa = Ialpha */
+ *pIa = Ialpha;
+
+ /* Intermediate product is calculated by (1/(2*sqrt(3)) * Ia) */
+ product1 = (q31_t) (((q63_t) (Ialpha) * (0x40000000)) >> 31);
+
+ /* Intermediate product is calculated by (1/sqrt(3) * pIb) */
+ product2 = (q31_t) (((q63_t) (Ibeta) * (0x6ED9EBA1)) >> 31);
+
+ /* pIb is calculated by subtracting the products */
+ *pIb = __QSUB(product2, product1);
+ }
+
+ /**
+ * @} end of inv_clarke group
+ */
+
+ /**
+ * @brief Converts the elements of the Q7 vector to Q15 vector.
+ * @param[in] pSrc input pointer
+ * @param[out] pDst output pointer
+ * @param[in] blockSize number of samples to process
+ */
+ void arm_q7_to_q15(
+ q7_t * pSrc,
+ q15_t * pDst,
+ uint32_t blockSize);
+
+
+
+ /**
+ * @ingroup groupController
+ */
+
+ /**
+ * @defgroup park Vector Park Transform
+ *
+ * Forward Park transform converts the input two-coordinate vector to flux and torque components.
+ * The Park transform can be used to realize the transformation of the <code>Ialpha</code> and the <code>Ibeta</code> currents
+ * from the stationary to the moving reference frame and control the spatial relationship between
+ * the stator vector current and rotor flux vector.
+ * If we consider the d axis aligned with the rotor flux, the diagram below shows the
+ * current vector and the relationship from the two reference frames:
+ * \image html park.gif "Stator current space vector and its component in (a,b) and in the d,q rotating reference frame"
+ *
+ * The function operates on a single sample of data and each call to the function returns the processed output.
+ * The library provides separate functions for Q31 and floating-point data types.
+ * \par Algorithm
+ * \image html parkFormula.gif
+ * where <code>Ialpha</code> and <code>Ibeta</code> are the stator vector components,
+ * <code>pId</code> and <code>pIq</code> are rotor vector components and <code>cosVal</code> and <code>sinVal</code> are the
+ * cosine and sine values of theta (rotor flux position).
+ * \par Fixed-Point Behavior
+ * Care must be taken when using the Q31 version of the Park transform.
+ * In particular, the overflow and saturation behavior of the accumulator used must be considered.
+ * Refer to the function specific documentation below for usage guidelines.
+ */
+
+ /**
+ * @addtogroup park
+ * @{
+ */
+
+ /**
+ * @brief Floating-point Park transform
+ * @param[in] Ialpha input two-phase vector coordinate alpha
+ * @param[in] Ibeta input two-phase vector coordinate beta
+ * @param[out] pId points to output rotor reference frame d
+ * @param[out] pIq points to output rotor reference frame q
+ * @param[in] sinVal sine value of rotation angle theta
+ * @param[in] cosVal cosine value of rotation angle theta
+ *
+ * The function implements the forward Park transform.
+ *
+ */
+ static __INLINE void arm_park_f32(
+ float32_t Ialpha,
+ float32_t Ibeta,
+ float32_t * pId,
+ float32_t * pIq,
+ float32_t sinVal,
+ float32_t cosVal)
+ {
+ /* Calculate pId using the equation, pId = Ialpha * cosVal + Ibeta * sinVal */
+ *pId = Ialpha * cosVal + Ibeta * sinVal;
+
+ /* Calculate pIq using the equation, pIq = - Ialpha * sinVal + Ibeta * cosVal */
+ *pIq = -Ialpha * sinVal + Ibeta * cosVal;
+ }
+
+
+ /**
+ * @brief Park transform for Q31 version
+ * @param[in] Ialpha input two-phase vector coordinate alpha
+ * @param[in] Ibeta input two-phase vector coordinate beta
+ * @param[out] pId points to output rotor reference frame d
+ * @param[out] pIq points to output rotor reference frame q
+ * @param[in] sinVal sine value of rotation angle theta
+ * @param[in] cosVal cosine value of rotation angle theta
+ *
+ * <b>Scaling and Overflow Behavior:</b>
+ * \par
+ * The function is implemented using an internal 32-bit accumulator.
+ * The accumulator maintains 1.31 format by truncating lower 31 bits of the intermediate multiplication in 2.62 format.
+ * There is saturation on the addition and subtraction, hence there is no risk of overflow.
+ */
+ static __INLINE void arm_park_q31(
+ q31_t Ialpha,
+ q31_t Ibeta,
+ q31_t * pId,
+ q31_t * pIq,
+ q31_t sinVal,
+ q31_t cosVal)
+ {
+ q31_t product1, product2; /* Temporary variables used to store intermediate results */
+ q31_t product3, product4; /* Temporary variables used to store intermediate results */
+
+ /* Intermediate product is calculated by (Ialpha * cosVal) */
+ product1 = (q31_t) (((q63_t) (Ialpha) * (cosVal)) >> 31);
+
+ /* Intermediate product is calculated by (Ibeta * sinVal) */
+ product2 = (q31_t) (((q63_t) (Ibeta) * (sinVal)) >> 31);
+
+
+ /* Intermediate product is calculated by (Ialpha * sinVal) */
+ product3 = (q31_t) (((q63_t) (Ialpha) * (sinVal)) >> 31);
+
+ /* Intermediate product is calculated by (Ibeta * cosVal) */
+ product4 = (q31_t) (((q63_t) (Ibeta) * (cosVal)) >> 31);
+
+ /* Calculate pId by adding the two intermediate products 1 and 2 */
+ *pId = __QADD(product1, product2);
+
+ /* Calculate pIq by subtracting the two intermediate products 3 from 4 */
+ *pIq = __QSUB(product4, product3);
+ }
+
+ /**
+ * @} end of park group
+ */
+
+ /**
+ * @brief Converts the elements of the Q7 vector to floating-point vector.
+ * @param[in] pSrc is input pointer
+ * @param[out] pDst is output pointer
+ * @param[in] blockSize is the number of samples to process
+ */
+ void arm_q7_to_float(
+ q7_t * pSrc,
+ float32_t * pDst,
+ uint32_t blockSize);
+
+
+ /**
+ * @ingroup groupController
+ */
+
+ /**
+ * @defgroup inv_park Vector Inverse Park transform
+ * Inverse Park transform converts the input flux and torque components to two-coordinate vector.
+ *
+ * The function operates on a single sample of data and each call to the function returns the processed output.
+ * The library provides separate functions for Q31 and floating-point data types.
+ * \par Algorithm
+ * \image html parkInvFormula.gif
+ * where <code>pIalpha</code> and <code>pIbeta</code> are the stator vector components,
+ * <code>Id</code> and <code>Iq</code> are rotor vector components and <code>cosVal</code> and <code>sinVal</code> are the
+ * cosine and sine values of theta (rotor flux position).
+ * \par Fixed-Point Behavior
+ * Care must be taken when using the Q31 version of the Park transform.
+ * In particular, the overflow and saturation behavior of the accumulator used must be considered.
+ * Refer to the function specific documentation below for usage guidelines.
+ */
+
+ /**
+ * @addtogroup inv_park
+ * @{
+ */
+
+ /**
+ * @brief Floating-point Inverse Park transform
+ * @param[in] Id input coordinate of rotor reference frame d
+ * @param[in] Iq input coordinate of rotor reference frame q
+ * @param[out] pIalpha points to output two-phase orthogonal vector axis alpha
+ * @param[out] pIbeta points to output two-phase orthogonal vector axis beta
+ * @param[in] sinVal sine value of rotation angle theta
+ * @param[in] cosVal cosine value of rotation angle theta
+ */
+ static __INLINE void arm_inv_park_f32(
+ float32_t Id,
+ float32_t Iq,
+ float32_t * pIalpha,
+ float32_t * pIbeta,
+ float32_t sinVal,
+ float32_t cosVal)
+ {
+ /* Calculate pIalpha using the equation, pIalpha = Id * cosVal - Iq * sinVal */
+ *pIalpha = Id * cosVal - Iq * sinVal;
+
+ /* Calculate pIbeta using the equation, pIbeta = Id * sinVal + Iq * cosVal */
+ *pIbeta = Id * sinVal + Iq * cosVal;
+ }
+
+
+ /**
+ * @brief Inverse Park transform for Q31 version
+ * @param[in] Id input coordinate of rotor reference frame d
+ * @param[in] Iq input coordinate of rotor reference frame q
+ * @param[out] pIalpha points to output two-phase orthogonal vector axis alpha
+ * @param[out] pIbeta points to output two-phase orthogonal vector axis beta
+ * @param[in] sinVal sine value of rotation angle theta
+ * @param[in] cosVal cosine value of rotation angle theta
+ *
+ * <b>Scaling and Overflow Behavior:</b>
+ * \par
+ * The function is implemented using an internal 32-bit accumulator.
+ * The accumulator maintains 1.31 format by truncating lower 31 bits of the intermediate multiplication in 2.62 format.
+ * There is saturation on the addition, hence there is no risk of overflow.
+ */
+ static __INLINE void arm_inv_park_q31(
+ q31_t Id,
+ q31_t Iq,
+ q31_t * pIalpha,
+ q31_t * pIbeta,
+ q31_t sinVal,
+ q31_t cosVal)
+ {
+ q31_t product1, product2; /* Temporary variables used to store intermediate results */
+ q31_t product3, product4; /* Temporary variables used to store intermediate results */
+
+ /* Intermediate product is calculated by (Id * cosVal) */
+ product1 = (q31_t) (((q63_t) (Id) * (cosVal)) >> 31);
+
+ /* Intermediate product is calculated by (Iq * sinVal) */
+ product2 = (q31_t) (((q63_t) (Iq) * (sinVal)) >> 31);
+
+
+ /* Intermediate product is calculated by (Id * sinVal) */
+ product3 = (q31_t) (((q63_t) (Id) * (sinVal)) >> 31);
+
+ /* Intermediate product is calculated by (Iq * cosVal) */
+ product4 = (q31_t) (((q63_t) (Iq) * (cosVal)) >> 31);
+
+ /* Calculate pIalpha by using the two intermediate products 1 and 2 */
+ *pIalpha = __QSUB(product1, product2);
+
+ /* Calculate pIbeta by using the two intermediate products 3 and 4 */
+ *pIbeta = __QADD(product4, product3);
+ }
+
+ /**
+ * @} end of Inverse park group
+ */
+
+
+ /**
+ * @brief Converts the elements of the Q31 vector to floating-point vector.
+ * @param[in] pSrc is input pointer
+ * @param[out] pDst is output pointer
+ * @param[in] blockSize is the number of samples to process
+ */
+ void arm_q31_to_float(
+ q31_t * pSrc,
+ float32_t * pDst,
+ uint32_t blockSize);
+
+ /**
+ * @ingroup groupInterpolation
+ */
+
+ /**
+ * @defgroup LinearInterpolate Linear Interpolation
+ *
+ * Linear interpolation is a method of curve fitting using linear polynomials.
+ * Linear interpolation works by effectively drawing a straight line between two neighboring samples and returning the appropriate point along that line
+ *
+ * \par
+ * \image html LinearInterp.gif "Linear interpolation"
+ *
+ * \par
+ * A Linear Interpolate function calculates an output value(y), for the input(x)
+ * using linear interpolation of the input values x0, x1( nearest input values) and the output values y0 and y1(nearest output values)
+ *
+ * \par Algorithm:
+ * <pre>
+ * y = y0 + (x - x0) * ((y1 - y0)/(x1-x0))
+ * where x0, x1 are nearest values of input x
+ * y0, y1 are nearest values to output y
+ * </pre>
+ *
+ * \par
+ * This set of functions implements Linear interpolation process
+ * for Q7, Q15, Q31, and floating-point data types. The functions operate on a single
+ * sample of data and each call to the function returns a single processed value.
+ * <code>S</code> points to an instance of the Linear Interpolate function data structure.
+ * <code>x</code> is the input sample value. The functions returns the output value.
+ *
+ * \par
+ * if x is outside of the table boundary, Linear interpolation returns first value of the table
+ * if x is below input range and returns last value of table if x is above range.
+ */
+
+ /**
+ * @addtogroup LinearInterpolate
+ * @{
+ */
+
+ /**
+ * @brief Process function for the floating-point Linear Interpolation Function.
+ * @param[in,out] S is an instance of the floating-point Linear Interpolation structure
+ * @param[in] x input sample to process
+ * @return y processed output sample.
+ *
+ */
+ static __INLINE float32_t arm_linear_interp_f32(
+ arm_linear_interp_instance_f32 * S,
+ float32_t x)
+ {
+ float32_t y;
+ float32_t x0, x1; /* Nearest input values */
+ float32_t y0, y1; /* Nearest output values */
+ float32_t xSpacing = S->xSpacing; /* spacing between input values */
+ int32_t i; /* Index variable */
+ float32_t *pYData = S->pYData; /* pointer to output table */
+
+ /* Calculation of index */
+ i = (int32_t) ((x - S->x1) / xSpacing);
+
+ if (i < 0)
+ {
+ /* Iniatilize output for below specified range as least output value of table */
+ y = pYData[0];
+ }
+ else if ((uint32_t)i >= S->nValues)
+ {
+ /* Iniatilize output for above specified range as last output value of table */
+ y = pYData[S->nValues - 1];
+ }
+ else
+ {
+ /* Calculation of nearest input values */
+ x0 = S->x1 + i * xSpacing;
+ x1 = S->x1 + (i + 1) * xSpacing;
+
+ /* Read of nearest output values */
+ y0 = pYData[i];
+ y1 = pYData[i + 1];
+
+ /* Calculation of output */
+ y = y0 + (x - x0) * ((y1 - y0) / (x1 - x0));
+
+ }
+
+ /* returns output value */
+ return (y);
+ }
+
+
+ /**
+ *
+ * @brief Process function for the Q31 Linear Interpolation Function.
+ * @param[in] pYData pointer to Q31 Linear Interpolation table
+ * @param[in] x input sample to process
+ * @param[in] nValues number of table values
+ * @return y processed output sample.
+ *
+ * \par
+ * Input sample <code>x</code> is in 12.20 format which contains 12 bits for table index and 20 bits for fractional part.
+ * This function can support maximum of table size 2^12.
+ *
+ */
+ static __INLINE q31_t arm_linear_interp_q31(
+ q31_t * pYData,
+ q31_t x,
+ uint32_t nValues)
+ {
+ q31_t y; /* output */
+ q31_t y0, y1; /* Nearest output values */
+ q31_t fract; /* fractional part */
+ int32_t index; /* Index to read nearest output values */
+
+ /* Input is in 12.20 format */
+ /* 12 bits for the table index */
+ /* Index value calculation */
+ index = ((x & (q31_t)0xFFF00000) >> 20);
+
+ if (index >= (int32_t)(nValues - 1))
+ {
+ return (pYData[nValues - 1]);
+ }
+ else if (index < 0)
+ {
+ return (pYData[0]);
+ }
+ else
+ {
+ /* 20 bits for the fractional part */
+ /* shift left by 11 to keep fract in 1.31 format */
+ fract = (x & 0x000FFFFF) << 11;
+
+ /* Read two nearest output values from the index in 1.31(q31) format */
+ y0 = pYData[index];
+ y1 = pYData[index + 1];
+
+ /* Calculation of y0 * (1-fract) and y is in 2.30 format */
+ y = ((q31_t) ((q63_t) y0 * (0x7FFFFFFF - fract) >> 32));
+
+ /* Calculation of y0 * (1-fract) + y1 *fract and y is in 2.30 format */
+ y += ((q31_t) (((q63_t) y1 * fract) >> 32));
+
+ /* Convert y to 1.31 format */
+ return (y << 1u);
+ }
+ }
+
+
+ /**
+ *
+ * @brief Process function for the Q15 Linear Interpolation Function.
+ * @param[in] pYData pointer to Q15 Linear Interpolation table
+ * @param[in] x input sample to process
+ * @param[in] nValues number of table values
+ * @return y processed output sample.
+ *
+ * \par
+ * Input sample <code>x</code> is in 12.20 format which contains 12 bits for table index and 20 bits for fractional part.
+ * This function can support maximum of table size 2^12.
+ *
+ */
+ static __INLINE q15_t arm_linear_interp_q15(
+ q15_t * pYData,
+ q31_t x,
+ uint32_t nValues)
+ {
+ q63_t y; /* output */
+ q15_t y0, y1; /* Nearest output values */
+ q31_t fract; /* fractional part */
+ int32_t index; /* Index to read nearest output values */
+
+ /* Input is in 12.20 format */
+ /* 12 bits for the table index */
+ /* Index value calculation */
+ index = ((x & (int32_t)0xFFF00000) >> 20);
+
+ if (index >= (int32_t)(nValues - 1))
+ {
+ return (pYData[nValues - 1]);
+ }
+ else if (index < 0)
+ {
+ return (pYData[0]);
+ }
+ else
+ {
+ /* 20 bits for the fractional part */
+ /* fract is in 12.20 format */
+ fract = (x & 0x000FFFFF);
+
+ /* Read two nearest output values from the index */
+ y0 = pYData[index];
+ y1 = pYData[index + 1];
+
+ /* Calculation of y0 * (1-fract) and y is in 13.35 format */
+ y = ((q63_t) y0 * (0xFFFFF - fract));
+
+ /* Calculation of (y0 * (1-fract) + y1 * fract) and y is in 13.35 format */
+ y += ((q63_t) y1 * (fract));
+
+ /* convert y to 1.15 format */
+ return (q15_t) (y >> 20);
+ }
+ }
+
+
+ /**
+ *
+ * @brief Process function for the Q7 Linear Interpolation Function.
+ * @param[in] pYData pointer to Q7 Linear Interpolation table
+ * @param[in] x input sample to process
+ * @param[in] nValues number of table values
+ * @return y processed output sample.
+ *
+ * \par
+ * Input sample <code>x</code> is in 12.20 format which contains 12 bits for table index and 20 bits for fractional part.
+ * This function can support maximum of table size 2^12.
+ */
+ static __INLINE q7_t arm_linear_interp_q7(
+ q7_t * pYData,
+ q31_t x,
+ uint32_t nValues)
+ {
+ q31_t y; /* output */
+ q7_t y0, y1; /* Nearest output values */
+ q31_t fract; /* fractional part */
+ uint32_t index; /* Index to read nearest output values */
+
+ /* Input is in 12.20 format */
+ /* 12 bits for the table index */
+ /* Index value calculation */
+ if (x < 0)
+ {
+ return (pYData[0]);
+ }
+ index = (x >> 20) & 0xfff;
+
+ if (index >= (nValues - 1))
+ {
+ return (pYData[nValues - 1]);
+ }
+ else
+ {
+ /* 20 bits for the fractional part */
+ /* fract is in 12.20 format */
+ fract = (x & 0x000FFFFF);
+
+ /* Read two nearest output values from the index and are in 1.7(q7) format */
+ y0 = pYData[index];
+ y1 = pYData[index + 1];
+
+ /* Calculation of y0 * (1-fract ) and y is in 13.27(q27) format */
+ y = ((y0 * (0xFFFFF - fract)));
+
+ /* Calculation of y1 * fract + y0 * (1-fract) and y is in 13.27(q27) format */
+ y += (y1 * fract);
+
+ /* convert y to 1.7(q7) format */
+ return (q7_t) (y >> 20);
+ }
+ }
+
+ /**
+ * @} end of LinearInterpolate group
+ */
+
+ /**
+ * @brief Fast approximation to the trigonometric sine function for floating-point data.
+ * @param[in] x input value in radians.
+ * @return sin(x).
+ */
+ float32_t arm_sin_f32(
+ float32_t x);
+
+
+ /**
+ * @brief Fast approximation to the trigonometric sine function for Q31 data.
+ * @param[in] x Scaled input value in radians.
+ * @return sin(x).
+ */
+ q31_t arm_sin_q31(
+ q31_t x);
+
+
+ /**
+ * @brief Fast approximation to the trigonometric sine function for Q15 data.
+ * @param[in] x Scaled input value in radians.
+ * @return sin(x).
+ */
+ q15_t arm_sin_q15(
+ q15_t x);
+
+
+ /**
+ * @brief Fast approximation to the trigonometric cosine function for floating-point data.
+ * @param[in] x input value in radians.
+ * @return cos(x).
+ */
+ float32_t arm_cos_f32(
+ float32_t x);
+
+
+ /**
+ * @brief Fast approximation to the trigonometric cosine function for Q31 data.
+ * @param[in] x Scaled input value in radians.
+ * @return cos(x).
+ */
+ q31_t arm_cos_q31(
+ q31_t x);
+
+
+ /**
+ * @brief Fast approximation to the trigonometric cosine function for Q15 data.
+ * @param[in] x Scaled input value in radians.
+ * @return cos(x).
+ */
+ q15_t arm_cos_q15(
+ q15_t x);
+
+
+ /**
+ * @ingroup groupFastMath
+ */
+
+
+ /**
+ * @defgroup SQRT Square Root
+ *
+ * Computes the square root of a number.
+ * There are separate functions for Q15, Q31, and floating-point data types.
+ * The square root function is computed using the Newton-Raphson algorithm.
+ * This is an iterative algorithm of the form:
+ * <pre>
+ * x1 = x0 - f(x0)/f'(x0)
+ * </pre>
+ * where <code>x1</code> is the current estimate,
+ * <code>x0</code> is the previous estimate, and
+ * <code>f'(x0)</code> is the derivative of <code>f()</code> evaluated at <code>x0</code>.
+ * For the square root function, the algorithm reduces to:
+ * <pre>
+ * x0 = in/2 [initial guess]
+ * x1 = 1/2 * ( x0 + in / x0) [each iteration]
+ * </pre>
+ */
+
+
+ /**
+ * @addtogroup SQRT
+ * @{
+ */
+
+ /**
+ * @brief Floating-point square root function.
+ * @param[in] in input value.
+ * @param[out] pOut square root of input value.
+ * @return The function returns ARM_MATH_SUCCESS if input value is positive value or ARM_MATH_ARGUMENT_ERROR if
+ * <code>in</code> is negative value and returns zero output for negative values.
+ */
+ static __INLINE arm_status arm_sqrt_f32(
+ float32_t in,
+ float32_t * pOut)
+ {
+ if (in >= 0.0f)
+ {
+
+#if (__FPU_USED == 1) && defined ( __CC_ARM )
+ *pOut = __sqrtf(in);
+#elif (__FPU_USED == 1) && (defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050))
+ *pOut = __builtin_sqrtf(in);
+#elif (__FPU_USED == 1) && defined(__GNUC__)
+ *pOut = __builtin_sqrtf(in);
+#elif (__FPU_USED == 1) && defined ( __ICCARM__ ) && (__VER__ >= 6040000)
+ __ASM("VSQRT.F32 %0,%1" : "=t"(*pOut) : "t"(in));
+#else
+ *pOut = sqrtf(in);
+#endif
+
+ return (ARM_MATH_SUCCESS);
+ }
+ else
+ {
+ *pOut = 0.0f;
+ return (ARM_MATH_ARGUMENT_ERROR);
+ }
+ }
+
+
+ /**
+ * @brief Q31 square root function.
+ * @param[in] in input value. The range of the input value is [0 +1) or 0x00000000 to 0x7FFFFFFF.
+ * @param[out] pOut square root of input value.
+ * @return The function returns ARM_MATH_SUCCESS if input value is positive value or ARM_MATH_ARGUMENT_ERROR if
+ * <code>in</code> is negative value and returns zero output for negative values.
+ */
+ arm_status arm_sqrt_q31(
+ q31_t in,
+ q31_t * pOut);
+
+
+ /**
+ * @brief Q15 square root function.
+ * @param[in] in input value. The range of the input value is [0 +1) or 0x0000 to 0x7FFF.
+ * @param[out] pOut square root of input value.
+ * @return The function returns ARM_MATH_SUCCESS if input value is positive value or ARM_MATH_ARGUMENT_ERROR if
+ * <code>in</code> is negative value and returns zero output for negative values.
+ */
+ arm_status arm_sqrt_q15(
+ q15_t in,
+ q15_t * pOut);
+
+ /**
+ * @} end of SQRT group
+ */
+
+
+ /**
+ * @brief floating-point Circular write function.
+ */
+ static __INLINE void arm_circularWrite_f32(
+ int32_t * circBuffer,
+ int32_t L,
+ uint16_t * writeOffset,
+ int32_t bufferInc,
+ const int32_t * src,
+ int32_t srcInc,
+ uint32_t blockSize)
+ {
+ uint32_t i = 0u;
+ int32_t wOffset;
+
+ /* Copy the value of Index pointer that points
+ * to the current location where the input samples to be copied */
+ wOffset = *writeOffset;
+
+ /* Loop over the blockSize */
+ i = blockSize;
+
+ while (i > 0u)
+ {
+ /* copy the input sample to the circular buffer */
+ circBuffer[wOffset] = *src;
+
+ /* Update the input pointer */
+ src += srcInc;
+
+ /* Circularly update wOffset. Watch out for positive and negative value */
+ wOffset += bufferInc;
+ if (wOffset >= L)
+ wOffset -= L;
+
+ /* Decrement the loop counter */
+ i--;
+ }
+
+ /* Update the index pointer */
+ *writeOffset = (uint16_t)wOffset;
+ }
+
+
+
+ /**
+ * @brief floating-point Circular Read function.
+ */
+ static __INLINE void arm_circularRead_f32(
+ int32_t * circBuffer,
+ int32_t L,
+ int32_t * readOffset,
+ int32_t bufferInc,
+ int32_t * dst,
+ int32_t * dst_base,
+ int32_t dst_length,
+ int32_t dstInc,
+ uint32_t blockSize)
+ {
+ uint32_t i = 0u;
+ int32_t rOffset, dst_end;
+
+ /* Copy the value of Index pointer that points
+ * to the current location from where the input samples to be read */
+ rOffset = *readOffset;
+ dst_end = (int32_t) (dst_base + dst_length);
+
+ /* Loop over the blockSize */
+ i = blockSize;
+
+ while (i > 0u)
+ {
+ /* copy the sample from the circular buffer to the destination buffer */
+ *dst = circBuffer[rOffset];
+
+ /* Update the input pointer */
+ dst += dstInc;
+
+ if (dst == (int32_t *) dst_end)
+ {
+ dst = dst_base;
+ }
+
+ /* Circularly update rOffset. Watch out for positive and negative value */
+ rOffset += bufferInc;
+
+ if (rOffset >= L)
+ {
+ rOffset -= L;
+ }
+
+ /* Decrement the loop counter */
+ i--;
+ }
+
+ /* Update the index pointer */
+ *readOffset = rOffset;
+ }
+
+
+ /**
+ * @brief Q15 Circular write function.
+ */
+ static __INLINE void arm_circularWrite_q15(
+ q15_t * circBuffer,
+ int32_t L,
+ uint16_t * writeOffset,
+ int32_t bufferInc,
+ const q15_t * src,
+ int32_t srcInc,
+ uint32_t blockSize)
+ {
+ uint32_t i = 0u;
+ int32_t wOffset;
+
+ /* Copy the value of Index pointer that points
+ * to the current location where the input samples to be copied */
+ wOffset = *writeOffset;
+
+ /* Loop over the blockSize */
+ i = blockSize;
+
+ while (i > 0u)
+ {
+ /* copy the input sample to the circular buffer */
+ circBuffer[wOffset] = *src;
+
+ /* Update the input pointer */
+ src += srcInc;
+
+ /* Circularly update wOffset. Watch out for positive and negative value */
+ wOffset += bufferInc;
+ if (wOffset >= L)
+ wOffset -= L;
+
+ /* Decrement the loop counter */
+ i--;
+ }
+
+ /* Update the index pointer */
+ *writeOffset = (uint16_t)wOffset;
+ }
+
+
+ /**
+ * @brief Q15 Circular Read function.
+ */
+ static __INLINE void arm_circularRead_q15(
+ q15_t * circBuffer,
+ int32_t L,
+ int32_t * readOffset,
+ int32_t bufferInc,
+ q15_t * dst,
+ q15_t * dst_base,
+ int32_t dst_length,
+ int32_t dstInc,
+ uint32_t blockSize)
+ {
+ uint32_t i = 0;
+ int32_t rOffset, dst_end;
+
+ /* Copy the value of Index pointer that points
+ * to the current location from where the input samples to be read */
+ rOffset = *readOffset;
+
+ dst_end = (int32_t) (dst_base + dst_length);
+
+ /* Loop over the blockSize */
+ i = blockSize;
+
+ while (i > 0u)
+ {
+ /* copy the sample from the circular buffer to the destination buffer */
+ *dst = circBuffer[rOffset];
+
+ /* Update the input pointer */
+ dst += dstInc;
+
+ if (dst == (q15_t *) dst_end)
+ {
+ dst = dst_base;
+ }
+
+ /* Circularly update wOffset. Watch out for positive and negative value */
+ rOffset += bufferInc;
+
+ if (rOffset >= L)
+ {
+ rOffset -= L;
+ }
+
+ /* Decrement the loop counter */
+ i--;
+ }
+
+ /* Update the index pointer */
+ *readOffset = rOffset;
+ }
+
+
+ /**
+ * @brief Q7 Circular write function.
+ */
+ static __INLINE void arm_circularWrite_q7(
+ q7_t * circBuffer,
+ int32_t L,
+ uint16_t * writeOffset,
+ int32_t bufferInc,
+ const q7_t * src,
+ int32_t srcInc,
+ uint32_t blockSize)
+ {
+ uint32_t i = 0u;
+ int32_t wOffset;
+
+ /* Copy the value of Index pointer that points
+ * to the current location where the input samples to be copied */
+ wOffset = *writeOffset;
+
+ /* Loop over the blockSize */
+ i = blockSize;
+
+ while (i > 0u)
+ {
+ /* copy the input sample to the circular buffer */
+ circBuffer[wOffset] = *src;
+
+ /* Update the input pointer */
+ src += srcInc;
+
+ /* Circularly update wOffset. Watch out for positive and negative value */
+ wOffset += bufferInc;
+ if (wOffset >= L)
+ wOffset -= L;
+
+ /* Decrement the loop counter */
+ i--;
+ }
+
+ /* Update the index pointer */
+ *writeOffset = (uint16_t)wOffset;
+ }
+
+
+ /**
+ * @brief Q7 Circular Read function.
+ */
+ static __INLINE void arm_circularRead_q7(
+ q7_t * circBuffer,
+ int32_t L,
+ int32_t * readOffset,
+ int32_t bufferInc,
+ q7_t * dst,
+ q7_t * dst_base,
+ int32_t dst_length,
+ int32_t dstInc,
+ uint32_t blockSize)
+ {
+ uint32_t i = 0;
+ int32_t rOffset, dst_end;
+
+ /* Copy the value of Index pointer that points
+ * to the current location from where the input samples to be read */
+ rOffset = *readOffset;
+
+ dst_end = (int32_t) (dst_base + dst_length);
+
+ /* Loop over the blockSize */
+ i = blockSize;
+
+ while (i > 0u)
+ {
+ /* copy the sample from the circular buffer to the destination buffer */
+ *dst = circBuffer[rOffset];
+
+ /* Update the input pointer */
+ dst += dstInc;
+
+ if (dst == (q7_t *) dst_end)
+ {
+ dst = dst_base;
+ }
+
+ /* Circularly update rOffset. Watch out for positive and negative value */
+ rOffset += bufferInc;
+
+ if (rOffset >= L)
+ {
+ rOffset -= L;
+ }
+
+ /* Decrement the loop counter */
+ i--;
+ }
+
+ /* Update the index pointer */
+ *readOffset = rOffset;
+ }
+
+
+ /**
+ * @brief Sum of the squares of the elements of a Q31 vector.
+ * @param[in] pSrc is input pointer
+ * @param[in] blockSize is the number of samples to process
+ * @param[out] pResult is output value.
+ */
+ void arm_power_q31(
+ q31_t * pSrc,
+ uint32_t blockSize,
+ q63_t * pResult);
+
+
+ /**
+ * @brief Sum of the squares of the elements of a floating-point vector.
+ * @param[in] pSrc is input pointer
+ * @param[in] blockSize is the number of samples to process
+ * @param[out] pResult is output value.
+ */
+ void arm_power_f32(
+ float32_t * pSrc,
+ uint32_t blockSize,
+ float32_t * pResult);
+
+
+ /**
+ * @brief Sum of the squares of the elements of a Q15 vector.
+ * @param[in] pSrc is input pointer
+ * @param[in] blockSize is the number of samples to process
+ * @param[out] pResult is output value.
+ */
+ void arm_power_q15(
+ q15_t * pSrc,
+ uint32_t blockSize,
+ q63_t * pResult);
+
+
+ /**
+ * @brief Sum of the squares of the elements of a Q7 vector.
+ * @param[in] pSrc is input pointer
+ * @param[in] blockSize is the number of samples to process
+ * @param[out] pResult is output value.
+ */
+ void arm_power_q7(
+ q7_t * pSrc,
+ uint32_t blockSize,
+ q31_t * pResult);
+
+
+ /**
+ * @brief Mean value of a Q7 vector.
+ * @param[in] pSrc is input pointer
+ * @param[in] blockSize is the number of samples to process
+ * @param[out] pResult is output value.
+ */
+ void arm_mean_q7(
+ q7_t * pSrc,
+ uint32_t blockSize,
+ q7_t * pResult);
+
+
+ /**
+ * @brief Mean value of a Q15 vector.
+ * @param[in] pSrc is input pointer
+ * @param[in] blockSize is the number of samples to process
+ * @param[out] pResult is output value.
+ */
+ void arm_mean_q15(
+ q15_t * pSrc,
+ uint32_t blockSize,
+ q15_t * pResult);
+
+
+ /**
+ * @brief Mean value of a Q31 vector.
+ * @param[in] pSrc is input pointer
+ * @param[in] blockSize is the number of samples to process
+ * @param[out] pResult is output value.
+ */
+ void arm_mean_q31(
+ q31_t * pSrc,
+ uint32_t blockSize,
+ q31_t * pResult);
+
+
+ /**
+ * @brief Mean value of a floating-point vector.
+ * @param[in] pSrc is input pointer
+ * @param[in] blockSize is the number of samples to process
+ * @param[out] pResult is output value.
+ */
+ void arm_mean_f32(
+ float32_t * pSrc,
+ uint32_t blockSize,
+ float32_t * pResult);
+
+
+ /**
+ * @brief Variance of the elements of a floating-point vector.
+ * @param[in] pSrc is input pointer
+ * @param[in] blockSize is the number of samples to process
+ * @param[out] pResult is output value.
+ */
+ void arm_var_f32(
+ float32_t * pSrc,
+ uint32_t blockSize,
+ float32_t * pResult);
+
+
+ /**
+ * @brief Variance of the elements of a Q31 vector.
+ * @param[in] pSrc is input pointer
+ * @param[in] blockSize is the number of samples to process
+ * @param[out] pResult is output value.
+ */
+ void arm_var_q31(
+ q31_t * pSrc,
+ uint32_t blockSize,
+ q31_t * pResult);
+
+
+ /**
+ * @brief Variance of the elements of a Q15 vector.
+ * @param[in] pSrc is input pointer
+ * @param[in] blockSize is the number of samples to process
+ * @param[out] pResult is output value.
+ */
+ void arm_var_q15(
+ q15_t * pSrc,
+ uint32_t blockSize,
+ q15_t * pResult);
+
+
+ /**
+ * @brief Root Mean Square of the elements of a floating-point vector.
+ * @param[in] pSrc is input pointer
+ * @param[in] blockSize is the number of samples to process
+ * @param[out] pResult is output value.
+ */
+ void arm_rms_f32(
+ float32_t * pSrc,
+ uint32_t blockSize,
+ float32_t * pResult);
+
+
+ /**
+ * @brief Root Mean Square of the elements of a Q31 vector.
+ * @param[in] pSrc is input pointer
+ * @param[in] blockSize is the number of samples to process
+ * @param[out] pResult is output value.
+ */
+ void arm_rms_q31(
+ q31_t * pSrc,
+ uint32_t blockSize,
+ q31_t * pResult);
+
+
+ /**
+ * @brief Root Mean Square of the elements of a Q15 vector.
+ * @param[in] pSrc is input pointer
+ * @param[in] blockSize is the number of samples to process
+ * @param[out] pResult is output value.
+ */
+ void arm_rms_q15(
+ q15_t * pSrc,
+ uint32_t blockSize,
+ q15_t * pResult);
+
+
+ /**
+ * @brief Standard deviation of the elements of a floating-point vector.
+ * @param[in] pSrc is input pointer
+ * @param[in] blockSize is the number of samples to process
+ * @param[out] pResult is output value.
+ */
+ void arm_std_f32(
+ float32_t * pSrc,
+ uint32_t blockSize,
+ float32_t * pResult);
+
+
+ /**
+ * @brief Standard deviation of the elements of a Q31 vector.
+ * @param[in] pSrc is input pointer
+ * @param[in] blockSize is the number of samples to process
+ * @param[out] pResult is output value.
+ */
+ void arm_std_q31(
+ q31_t * pSrc,
+ uint32_t blockSize,
+ q31_t * pResult);
+
+
+ /**
+ * @brief Standard deviation of the elements of a Q15 vector.
+ * @param[in] pSrc is input pointer
+ * @param[in] blockSize is the number of samples to process
+ * @param[out] pResult is output value.
+ */
+ void arm_std_q15(
+ q15_t * pSrc,
+ uint32_t blockSize,
+ q15_t * pResult);
+
+
+ /**
+ * @brief Floating-point complex magnitude
+ * @param[in] pSrc points to the complex input vector
+ * @param[out] pDst points to the real output vector
+ * @param[in] numSamples number of complex samples in the input vector
+ */
+ void arm_cmplx_mag_f32(
+ float32_t * pSrc,
+ float32_t * pDst,
+ uint32_t numSamples);
+
+
+ /**
+ * @brief Q31 complex magnitude
+ * @param[in] pSrc points to the complex input vector
+ * @param[out] pDst points to the real output vector
+ * @param[in] numSamples number of complex samples in the input vector
+ */
+ void arm_cmplx_mag_q31(
+ q31_t * pSrc,
+ q31_t * pDst,
+ uint32_t numSamples);
+
+
+ /**
+ * @brief Q15 complex magnitude
+ * @param[in] pSrc points to the complex input vector
+ * @param[out] pDst points to the real output vector
+ * @param[in] numSamples number of complex samples in the input vector
+ */
+ void arm_cmplx_mag_q15(
+ q15_t * pSrc,
+ q15_t * pDst,
+ uint32_t numSamples);
+
+
+ /**
+ * @brief Q15 complex dot product
+ * @param[in] pSrcA points to the first input vector
+ * @param[in] pSrcB points to the second input vector
+ * @param[in] numSamples number of complex samples in each vector
+ * @param[out] realResult real part of the result returned here
+ * @param[out] imagResult imaginary part of the result returned here
+ */
+ void arm_cmplx_dot_prod_q15(
+ q15_t * pSrcA,
+ q15_t * pSrcB,
+ uint32_t numSamples,
+ q31_t * realResult,
+ q31_t * imagResult);
+
+
+ /**
+ * @brief Q31 complex dot product
+ * @param[in] pSrcA points to the first input vector
+ * @param[in] pSrcB points to the second input vector
+ * @param[in] numSamples number of complex samples in each vector
+ * @param[out] realResult real part of the result returned here
+ * @param[out] imagResult imaginary part of the result returned here
+ */
+ void arm_cmplx_dot_prod_q31(
+ q31_t * pSrcA,
+ q31_t * pSrcB,
+ uint32_t numSamples,
+ q63_t * realResult,
+ q63_t * imagResult);
+
+
+ /**
+ * @brief Floating-point complex dot product
+ * @param[in] pSrcA points to the first input vector
+ * @param[in] pSrcB points to the second input vector
+ * @param[in] numSamples number of complex samples in each vector
+ * @param[out] realResult real part of the result returned here
+ * @param[out] imagResult imaginary part of the result returned here
+ */
+ void arm_cmplx_dot_prod_f32(
+ float32_t * pSrcA,
+ float32_t * pSrcB,
+ uint32_t numSamples,
+ float32_t * realResult,
+ float32_t * imagResult);
+
+
+ /**
+ * @brief Q15 complex-by-real multiplication
+ * @param[in] pSrcCmplx points to the complex input vector
+ * @param[in] pSrcReal points to the real input vector
+ * @param[out] pCmplxDst points to the complex output vector
+ * @param[in] numSamples number of samples in each vector
+ */
+ void arm_cmplx_mult_real_q15(
+ q15_t * pSrcCmplx,
+ q15_t * pSrcReal,
+ q15_t * pCmplxDst,
+ uint32_t numSamples);
+
+
+ /**
+ * @brief Q31 complex-by-real multiplication
+ * @param[in] pSrcCmplx points to the complex input vector
+ * @param[in] pSrcReal points to the real input vector
+ * @param[out] pCmplxDst points to the complex output vector
+ * @param[in] numSamples number of samples in each vector
+ */
+ void arm_cmplx_mult_real_q31(
+ q31_t * pSrcCmplx,
+ q31_t * pSrcReal,
+ q31_t * pCmplxDst,
+ uint32_t numSamples);
+
+
+ /**
+ * @brief Floating-point complex-by-real multiplication
+ * @param[in] pSrcCmplx points to the complex input vector
+ * @param[in] pSrcReal points to the real input vector
+ * @param[out] pCmplxDst points to the complex output vector
+ * @param[in] numSamples number of samples in each vector
+ */
+ void arm_cmplx_mult_real_f32(
+ float32_t * pSrcCmplx,
+ float32_t * pSrcReal,
+ float32_t * pCmplxDst,
+ uint32_t numSamples);
+
+
+ /**
+ * @brief Minimum value of a Q7 vector.
+ * @param[in] pSrc is input pointer
+ * @param[in] blockSize is the number of samples to process
+ * @param[out] result is output pointer
+ * @param[in] index is the array index of the minimum value in the input buffer.
+ */
+ void arm_min_q7(
+ q7_t * pSrc,
+ uint32_t blockSize,
+ q7_t * result,
+ uint32_t * index);
+
+
+ /**
+ * @brief Minimum value of a Q15 vector.
+ * @param[in] pSrc is input pointer
+ * @param[in] blockSize is the number of samples to process
+ * @param[out] pResult is output pointer
+ * @param[in] pIndex is the array index of the minimum value in the input buffer.
+ */
+ void arm_min_q15(
+ q15_t * pSrc,
+ uint32_t blockSize,
+ q15_t * pResult,
+ uint32_t * pIndex);
+
+
+ /**
+ * @brief Minimum value of a Q31 vector.
+ * @param[in] pSrc is input pointer
+ * @param[in] blockSize is the number of samples to process
+ * @param[out] pResult is output pointer
+ * @param[out] pIndex is the array index of the minimum value in the input buffer.
+ */
+ void arm_min_q31(
+ q31_t * pSrc,
+ uint32_t blockSize,
+ q31_t * pResult,
+ uint32_t * pIndex);
+
+
+ /**
+ * @brief Minimum value of a floating-point vector.
+ * @param[in] pSrc is input pointer
+ * @param[in] blockSize is the number of samples to process
+ * @param[out] pResult is output pointer
+ * @param[out] pIndex is the array index of the minimum value in the input buffer.
+ */
+ void arm_min_f32(
+ float32_t * pSrc,
+ uint32_t blockSize,
+ float32_t * pResult,
+ uint32_t * pIndex);
+
+
+/**
+ * @brief Maximum value of a Q7 vector.
+ * @param[in] pSrc points to the input buffer
+ * @param[in] blockSize length of the input vector
+ * @param[out] pResult maximum value returned here
+ * @param[out] pIndex index of maximum value returned here
+ */
+ void arm_max_q7(
+ q7_t * pSrc,
+ uint32_t blockSize,
+ q7_t * pResult,
+ uint32_t * pIndex);
+
+
+/**
+ * @brief Maximum value of a Q15 vector.
+ * @param[in] pSrc points to the input buffer
+ * @param[in] blockSize length of the input vector
+ * @param[out] pResult maximum value returned here
+ * @param[out] pIndex index of maximum value returned here
+ */
+ void arm_max_q15(
+ q15_t * pSrc,
+ uint32_t blockSize,
+ q15_t * pResult,
+ uint32_t * pIndex);
+
+
+/**
+ * @brief Maximum value of a Q31 vector.
+ * @param[in] pSrc points to the input buffer
+ * @param[in] blockSize length of the input vector
+ * @param[out] pResult maximum value returned here
+ * @param[out] pIndex index of maximum value returned here
+ */
+ void arm_max_q31(
+ q31_t * pSrc,
+ uint32_t blockSize,
+ q31_t * pResult,
+ uint32_t * pIndex);
+
+
+/**
+ * @brief Maximum value of a floating-point vector.
+ * @param[in] pSrc points to the input buffer
+ * @param[in] blockSize length of the input vector
+ * @param[out] pResult maximum value returned here
+ * @param[out] pIndex index of maximum value returned here
+ */
+ void arm_max_f32(
+ float32_t * pSrc,
+ uint32_t blockSize,
+ float32_t * pResult,
+ uint32_t * pIndex);
+
+
+ /**
+ * @brief Q15 complex-by-complex multiplication
+ * @param[in] pSrcA points to the first input vector
+ * @param[in] pSrcB points to the second input vector
+ * @param[out] pDst points to the output vector
+ * @param[in] numSamples number of complex samples in each vector
+ */
+ void arm_cmplx_mult_cmplx_q15(
+ q15_t * pSrcA,
+ q15_t * pSrcB,
+ q15_t * pDst,
+ uint32_t numSamples);
+
+
+ /**
+ * @brief Q31 complex-by-complex multiplication
+ * @param[in] pSrcA points to the first input vector
+ * @param[in] pSrcB points to the second input vector
+ * @param[out] pDst points to the output vector
+ * @param[in] numSamples number of complex samples in each vector
+ */
+ void arm_cmplx_mult_cmplx_q31(
+ q31_t * pSrcA,
+ q31_t * pSrcB,
+ q31_t * pDst,
+ uint32_t numSamples);
+
+
+ /**
+ * @brief Floating-point complex-by-complex multiplication
+ * @param[in] pSrcA points to the first input vector
+ * @param[in] pSrcB points to the second input vector
+ * @param[out] pDst points to the output vector
+ * @param[in] numSamples number of complex samples in each vector
+ */
+ void arm_cmplx_mult_cmplx_f32(
+ float32_t * pSrcA,
+ float32_t * pSrcB,
+ float32_t * pDst,
+ uint32_t numSamples);
+
+
+ /**
+ * @brief Converts the elements of the floating-point vector to Q31 vector.
+ * @param[in] pSrc points to the floating-point input vector
+ * @param[out] pDst points to the Q31 output vector
+ * @param[in] blockSize length of the input vector
+ */
+ void arm_float_to_q31(
+ float32_t * pSrc,
+ q31_t * pDst,
+ uint32_t blockSize);
+
+
+ /**
+ * @brief Converts the elements of the floating-point vector to Q15 vector.
+ * @param[in] pSrc points to the floating-point input vector
+ * @param[out] pDst points to the Q15 output vector
+ * @param[in] blockSize length of the input vector
+ */
+ void arm_float_to_q15(
+ float32_t * pSrc,
+ q15_t * pDst,
+ uint32_t blockSize);
+
+
+ /**
+ * @brief Converts the elements of the floating-point vector to Q7 vector.
+ * @param[in] pSrc points to the floating-point input vector
+ * @param[out] pDst points to the Q7 output vector
+ * @param[in] blockSize length of the input vector
+ */
+ void arm_float_to_q7(
+ float32_t * pSrc,
+ q7_t * pDst,
+ uint32_t blockSize);
+
+
+ /**
+ * @brief Converts the elements of the Q31 vector to Q15 vector.
+ * @param[in] pSrc is input pointer
+ * @param[out] pDst is output pointer
+ * @param[in] blockSize is the number of samples to process
+ */
+ void arm_q31_to_q15(
+ q31_t * pSrc,
+ q15_t * pDst,
+ uint32_t blockSize);
+
+
+ /**
+ * @brief Converts the elements of the Q31 vector to Q7 vector.
+ * @param[in] pSrc is input pointer
+ * @param[out] pDst is output pointer
+ * @param[in] blockSize is the number of samples to process
+ */
+ void arm_q31_to_q7(
+ q31_t * pSrc,
+ q7_t * pDst,
+ uint32_t blockSize);
+
+
+ /**
+ * @brief Converts the elements of the Q15 vector to floating-point vector.
+ * @param[in] pSrc is input pointer
+ * @param[out] pDst is output pointer
+ * @param[in] blockSize is the number of samples to process
+ */
+ void arm_q15_to_float(
+ q15_t * pSrc,
+ float32_t * pDst,
+ uint32_t blockSize);
+
+
+ /**
+ * @brief Converts the elements of the Q15 vector to Q31 vector.
+ * @param[in] pSrc is input pointer
+ * @param[out] pDst is output pointer
+ * @param[in] blockSize is the number of samples to process
+ */
+ void arm_q15_to_q31(
+ q15_t * pSrc,
+ q31_t * pDst,
+ uint32_t blockSize);
+
+
+ /**
+ * @brief Converts the elements of the Q15 vector to Q7 vector.
+ * @param[in] pSrc is input pointer
+ * @param[out] pDst is output pointer
+ * @param[in] blockSize is the number of samples to process
+ */
+ void arm_q15_to_q7(
+ q15_t * pSrc,
+ q7_t * pDst,
+ uint32_t blockSize);
+
+
+ /**
+ * @ingroup groupInterpolation
+ */
+
+ /**
+ * @defgroup BilinearInterpolate Bilinear Interpolation
+ *
+ * Bilinear interpolation is an extension of linear interpolation applied to a two dimensional grid.
+ * The underlying function <code>f(x, y)</code> is sampled on a regular grid and the interpolation process
+ * determines values between the grid points.
+ * Bilinear interpolation is equivalent to two step linear interpolation, first in the x-dimension and then in the y-dimension.
+ * Bilinear interpolation is often used in image processing to rescale images.
+ * The CMSIS DSP library provides bilinear interpolation functions for Q7, Q15, Q31, and floating-point data types.
+ *
+ * <b>Algorithm</b>
+ * \par
+ * The instance structure used by the bilinear interpolation functions describes a two dimensional data table.
+ * For floating-point, the instance structure is defined as:
+ * <pre>
+ * typedef struct
+ * {
+ * uint16_t numRows;
+ * uint16_t numCols;
+ * float32_t *pData;
+ * } arm_bilinear_interp_instance_f32;
+ * </pre>
+ *
+ * \par
+ * where <code>numRows</code> specifies the number of rows in the table;
+ * <code>numCols</code> specifies the number of columns in the table;
+ * and <code>pData</code> points to an array of size <code>numRows*numCols</code> values.
+ * The data table <code>pTable</code> is organized in row order and the supplied data values fall on integer indexes.
+ * That is, table element (x,y) is located at <code>pTable[x + y*numCols]</code> where x and y are integers.
+ *
+ * \par
+ * Let <code>(x, y)</code> specify the desired interpolation point. Then define:
+ * <pre>
+ * XF = floor(x)
+ * YF = floor(y)
+ * </pre>
+ * \par
+ * The interpolated output point is computed as:
+ * <pre>
+ * f(x, y) = f(XF, YF) * (1-(x-XF)) * (1-(y-YF))
+ * + f(XF + 1, YF) * (x-XF)*(1-(y-YF))
+ * + f(XF, YF + 1) * (1-(x-XF))*(y-YF)
+ * + f(XF + 1, YF + 1) * (x-XF)*(y-YF)
+ * </pre>
+ * Note that the coordinates (x, y) contain integer and fractional components.
+ * The integer components specify which portion of the table to use while the
+ * fractional components control the interpolation processor.
+ *
+ * \par
+ * if (x,y) are outside of the table boundary, Bilinear interpolation returns zero output.
+ */
+
+ /**
+ * @addtogroup BilinearInterpolate
+ * @{
+ */
+
+
+ /**
+ *
+ * @brief Floating-point bilinear interpolation.
+ * @param[in,out] S points to an instance of the interpolation structure.
+ * @param[in] X interpolation coordinate.
+ * @param[in] Y interpolation coordinate.
+ * @return out interpolated value.
+ */
+ static __INLINE float32_t arm_bilinear_interp_f32(
+ const arm_bilinear_interp_instance_f32 * S,
+ float32_t X,
+ float32_t Y)
+ {
+ float32_t out;
+ float32_t f00, f01, f10, f11;
+ float32_t *pData = S->pData;
+ int32_t xIndex, yIndex, index;
+ float32_t xdiff, ydiff;
+ float32_t b1, b2, b3, b4;
+
+ xIndex = (int32_t) X;
+ yIndex = (int32_t) Y;
+
+ /* Care taken for table outside boundary */
+ /* Returns zero output when values are outside table boundary */
+ if (xIndex < 0 || xIndex > (S->numRows - 1) || yIndex < 0 || yIndex > (S->numCols - 1))
+ {
+ return (0);
+ }
+
+ /* Calculation of index for two nearest points in X-direction */
+ index = (xIndex - 1) + (yIndex - 1) * S->numCols;
+
+
+ /* Read two nearest points in X-direction */
+ f00 = pData[index];
+ f01 = pData[index + 1];
+
+ /* Calculation of index for two nearest points in Y-direction */
+ index = (xIndex - 1) + (yIndex) * S->numCols;
+
+
+ /* Read two nearest points in Y-direction */
+ f10 = pData[index];
+ f11 = pData[index + 1];
+
+ /* Calculation of intermediate values */
+ b1 = f00;
+ b2 = f01 - f00;
+ b3 = f10 - f00;
+ b4 = f00 - f01 - f10 + f11;
+
+ /* Calculation of fractional part in X */
+ xdiff = X - xIndex;
+
+ /* Calculation of fractional part in Y */
+ ydiff = Y - yIndex;
+
+ /* Calculation of bi-linear interpolated output */
+ out = b1 + b2 * xdiff + b3 * ydiff + b4 * xdiff * ydiff;
+
+ /* return to application */
+ return (out);
+ }
+
+
+ /**
+ *
+ * @brief Q31 bilinear interpolation.
+ * @param[in,out] S points to an instance of the interpolation structure.
+ * @param[in] X interpolation coordinate in 12.20 format.
+ * @param[in] Y interpolation coordinate in 12.20 format.
+ * @return out interpolated value.
+ */
+ static __INLINE q31_t arm_bilinear_interp_q31(
+ arm_bilinear_interp_instance_q31 * S,
+ q31_t X,
+ q31_t Y)
+ {
+ q31_t out; /* Temporary output */
+ q31_t acc = 0; /* output */
+ q31_t xfract, yfract; /* X, Y fractional parts */
+ q31_t x1, x2, y1, y2; /* Nearest output values */
+ int32_t rI, cI; /* Row and column indices */
+ q31_t *pYData = S->pData; /* pointer to output table values */
+ uint32_t nCols = S->numCols; /* num of rows */
+
+ /* Input is in 12.20 format */
+ /* 12 bits for the table index */
+ /* Index value calculation */
+ rI = ((X & (q31_t)0xFFF00000) >> 20);
+
+ /* Input is in 12.20 format */
+ /* 12 bits for the table index */
+ /* Index value calculation */
+ cI = ((Y & (q31_t)0xFFF00000) >> 20);
+
+ /* Care taken for table outside boundary */
+ /* Returns zero output when values are outside table boundary */
+ if (rI < 0 || rI > (S->numRows - 1) || cI < 0 || cI > (S->numCols - 1))
+ {
+ return (0);
+ }
+
+ /* 20 bits for the fractional part */
+ /* shift left xfract by 11 to keep 1.31 format */
+ xfract = (X & 0x000FFFFF) << 11u;
+
+ /* Read two nearest output values from the index */
+ x1 = pYData[(rI) + (int32_t)nCols * (cI) ];
+ x2 = pYData[(rI) + (int32_t)nCols * (cI) + 1];
+
+ /* 20 bits for the fractional part */
+ /* shift left yfract by 11 to keep 1.31 format */
+ yfract = (Y & 0x000FFFFF) << 11u;
+
+ /* Read two nearest output values from the index */
+ y1 = pYData[(rI) + (int32_t)nCols * (cI + 1) ];
+ y2 = pYData[(rI) + (int32_t)nCols * (cI + 1) + 1];
+
+ /* Calculation of x1 * (1-xfract ) * (1-yfract) and acc is in 3.29(q29) format */
+ out = ((q31_t) (((q63_t) x1 * (0x7FFFFFFF - xfract)) >> 32));
+ acc = ((q31_t) (((q63_t) out * (0x7FFFFFFF - yfract)) >> 32));
+
+ /* x2 * (xfract) * (1-yfract) in 3.29(q29) and adding to acc */
+ out = ((q31_t) ((q63_t) x2 * (0x7FFFFFFF - yfract) >> 32));
+ acc += ((q31_t) ((q63_t) out * (xfract) >> 32));
+
+ /* y1 * (1 - xfract) * (yfract) in 3.29(q29) and adding to acc */
+ out = ((q31_t) ((q63_t) y1 * (0x7FFFFFFF - xfract) >> 32));
+ acc += ((q31_t) ((q63_t) out * (yfract) >> 32));
+
+ /* y2 * (xfract) * (yfract) in 3.29(q29) and adding to acc */
+ out = ((q31_t) ((q63_t) y2 * (xfract) >> 32));
+ acc += ((q31_t) ((q63_t) out * (yfract) >> 32));
+
+ /* Convert acc to 1.31(q31) format */
+ return ((q31_t)(acc << 2));
+ }
+
+
+ /**
+ * @brief Q15 bilinear interpolation.
+ * @param[in,out] S points to an instance of the interpolation structure.
+ * @param[in] X interpolation coordinate in 12.20 format.
+ * @param[in] Y interpolation coordinate in 12.20 format.
+ * @return out interpolated value.
+ */
+ static __INLINE q15_t arm_bilinear_interp_q15(
+ arm_bilinear_interp_instance_q15 * S,
+ q31_t X,
+ q31_t Y)
+ {
+ q63_t acc = 0; /* output */
+ q31_t out; /* Temporary output */
+ q15_t x1, x2, y1, y2; /* Nearest output values */
+ q31_t xfract, yfract; /* X, Y fractional parts */
+ int32_t rI, cI; /* Row and column indices */
+ q15_t *pYData = S->pData; /* pointer to output table values */
+ uint32_t nCols = S->numCols; /* num of rows */
+
+ /* Input is in 12.20 format */
+ /* 12 bits for the table index */
+ /* Index value calculation */
+ rI = ((X & (q31_t)0xFFF00000) >> 20);
+
+ /* Input is in 12.20 format */
+ /* 12 bits for the table index */
+ /* Index value calculation */
+ cI = ((Y & (q31_t)0xFFF00000) >> 20);
+
+ /* Care taken for table outside boundary */
+ /* Returns zero output when values are outside table boundary */
+ if (rI < 0 || rI > (S->numRows - 1) || cI < 0 || cI > (S->numCols - 1))
+ {
+ return (0);
+ }
+
+ /* 20 bits for the fractional part */
+ /* xfract should be in 12.20 format */
+ xfract = (X & 0x000FFFFF);
+
+ /* Read two nearest output values from the index */
+ x1 = pYData[((uint32_t)rI) + nCols * ((uint32_t)cI) ];
+ x2 = pYData[((uint32_t)rI) + nCols * ((uint32_t)cI) + 1];
+
+ /* 20 bits for the fractional part */
+ /* yfract should be in 12.20 format */
+ yfract = (Y & 0x000FFFFF);
+
+ /* Read two nearest output values from the index */
+ y1 = pYData[((uint32_t)rI) + nCols * ((uint32_t)cI + 1) ];
+ y2 = pYData[((uint32_t)rI) + nCols * ((uint32_t)cI + 1) + 1];
+
+ /* Calculation of x1 * (1-xfract ) * (1-yfract) and acc is in 13.51 format */
+
+ /* x1 is in 1.15(q15), xfract in 12.20 format and out is in 13.35 format */
+ /* convert 13.35 to 13.31 by right shifting and out is in 1.31 */
+ out = (q31_t) (((q63_t) x1 * (0xFFFFF - xfract)) >> 4u);
+ acc = ((q63_t) out * (0xFFFFF - yfract));
+
+ /* x2 * (xfract) * (1-yfract) in 1.51 and adding to acc */
+ out = (q31_t) (((q63_t) x2 * (0xFFFFF - yfract)) >> 4u);
+ acc += ((q63_t) out * (xfract));
+
+ /* y1 * (1 - xfract) * (yfract) in 1.51 and adding to acc */
+ out = (q31_t) (((q63_t) y1 * (0xFFFFF - xfract)) >> 4u);
+ acc += ((q63_t) out * (yfract));
+
+ /* y2 * (xfract) * (yfract) in 1.51 and adding to acc */
+ out = (q31_t) (((q63_t) y2 * (xfract)) >> 4u);
+ acc += ((q63_t) out * (yfract));
+
+ /* acc is in 13.51 format and down shift acc by 36 times */
+ /* Convert out to 1.15 format */
+ return ((q15_t)(acc >> 36));
+ }
+
+
+ /**
+ * @brief Q7 bilinear interpolation.
+ * @param[in,out] S points to an instance of the interpolation structure.
+ * @param[in] X interpolation coordinate in 12.20 format.
+ * @param[in] Y interpolation coordinate in 12.20 format.
+ * @return out interpolated value.
+ */
+ static __INLINE q7_t arm_bilinear_interp_q7(
+ arm_bilinear_interp_instance_q7 * S,
+ q31_t X,
+ q31_t Y)
+ {
+ q63_t acc = 0; /* output */
+ q31_t out; /* Temporary output */
+ q31_t xfract, yfract; /* X, Y fractional parts */
+ q7_t x1, x2, y1, y2; /* Nearest output values */
+ int32_t rI, cI; /* Row and column indices */
+ q7_t *pYData = S->pData; /* pointer to output table values */
+ uint32_t nCols = S->numCols; /* num of rows */
+
+ /* Input is in 12.20 format */
+ /* 12 bits for the table index */
+ /* Index value calculation */
+ rI = ((X & (q31_t)0xFFF00000) >> 20);
+
+ /* Input is in 12.20 format */
+ /* 12 bits for the table index */
+ /* Index value calculation */
+ cI = ((Y & (q31_t)0xFFF00000) >> 20);
+
+ /* Care taken for table outside boundary */
+ /* Returns zero output when values are outside table boundary */
+ if (rI < 0 || rI > (S->numRows - 1) || cI < 0 || cI > (S->numCols - 1))
+ {
+ return (0);
+ }
+
+ /* 20 bits for the fractional part */
+ /* xfract should be in 12.20 format */
+ xfract = (X & (q31_t)0x000FFFFF);
+
+ /* Read two nearest output values from the index */
+ x1 = pYData[((uint32_t)rI) + nCols * ((uint32_t)cI) ];
+ x2 = pYData[((uint32_t)rI) + nCols * ((uint32_t)cI) + 1];
+
+ /* 20 bits for the fractional part */
+ /* yfract should be in 12.20 format */
+ yfract = (Y & (q31_t)0x000FFFFF);
+
+ /* Read two nearest output values from the index */
+ y1 = pYData[((uint32_t)rI) + nCols * ((uint32_t)cI + 1) ];
+ y2 = pYData[((uint32_t)rI) + nCols * ((uint32_t)cI + 1) + 1];
+
+ /* Calculation of x1 * (1-xfract ) * (1-yfract) and acc is in 16.47 format */
+ out = ((x1 * (0xFFFFF - xfract)));
+ acc = (((q63_t) out * (0xFFFFF - yfract)));
+
+ /* x2 * (xfract) * (1-yfract) in 2.22 and adding to acc */
+ out = ((x2 * (0xFFFFF - yfract)));
+ acc += (((q63_t) out * (xfract)));
+
+ /* y1 * (1 - xfract) * (yfract) in 2.22 and adding to acc */
+ out = ((y1 * (0xFFFFF - xfract)));
+ acc += (((q63_t) out * (yfract)));
+
+ /* y2 * (xfract) * (yfract) in 2.22 and adding to acc */
+ out = ((y2 * (yfract)));
+ acc += (((q63_t) out * (xfract)));
+
+ /* acc in 16.47 format and down shift by 40 to convert to 1.7 format */
+ return ((q7_t)(acc >> 40));
+ }
+
+ /**
+ * @} end of BilinearInterpolate group
+ */
+
+
+/* SMMLAR */
+#define multAcc_32x32_keep32_R(a, x, y) \
+ a = (q31_t) (((((q63_t) a) << 32) + ((q63_t) x * y) + 0x80000000LL ) >> 32)
+
+/* SMMLSR */
+#define multSub_32x32_keep32_R(a, x, y) \
+ a = (q31_t) (((((q63_t) a) << 32) - ((q63_t) x * y) + 0x80000000LL ) >> 32)
+
+/* SMMULR */
+#define mult_32x32_keep32_R(a, x, y) \
+ a = (q31_t) (((q63_t) x * y + 0x80000000LL ) >> 32)
+
+/* SMMLA */
+#define multAcc_32x32_keep32(a, x, y) \
+ a += (q31_t) (((q63_t) x * y) >> 32)
+
+/* SMMLS */
+#define multSub_32x32_keep32(a, x, y) \
+ a -= (q31_t) (((q63_t) x * y) >> 32)
+
+/* SMMUL */
+#define mult_32x32_keep32(a, x, y) \
+ a = (q31_t) (((q63_t) x * y ) >> 32)
+
+
+#if defined ( __CC_ARM )
+ /* Enter low optimization region - place directly above function definition */
+ #if defined( ARM_MATH_CM4 ) || defined( ARM_MATH_CM7)
+ #define LOW_OPTIMIZATION_ENTER \
+ _Pragma ("push") \
+ _Pragma ("O1")
+ #else
+ #define LOW_OPTIMIZATION_ENTER
+ #endif
+
+ /* Exit low optimization region - place directly after end of function definition */
+ #if defined( ARM_MATH_CM4 ) || defined( ARM_MATH_CM7)
+ #define LOW_OPTIMIZATION_EXIT \
+ _Pragma ("pop")
+ #else
+ #define LOW_OPTIMIZATION_EXIT
+ #endif
+
+ /* Enter low optimization region - place directly above function definition */
+ #define IAR_ONLY_LOW_OPTIMIZATION_ENTER
+
+ /* Exit low optimization region - place directly after end of function definition */
+ #define IAR_ONLY_LOW_OPTIMIZATION_EXIT
+
+#elif defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050)
+ #define LOW_OPTIMIZATION_ENTER
+ #define LOW_OPTIMIZATION_EXIT
+ #define IAR_ONLY_LOW_OPTIMIZATION_ENTER
+ #define IAR_ONLY_LOW_OPTIMIZATION_EXIT
+
+#elif defined(__GNUC__)
+ #define LOW_OPTIMIZATION_ENTER __attribute__(( optimize("-O1") ))
+ #define LOW_OPTIMIZATION_EXIT
+ #define IAR_ONLY_LOW_OPTIMIZATION_ENTER
+ #define IAR_ONLY_LOW_OPTIMIZATION_EXIT
+
+#elif defined(__ICCARM__)
+ /* Enter low optimization region - place directly above function definition */
+ #if defined( ARM_MATH_CM4 ) || defined( ARM_MATH_CM7)
+ #define LOW_OPTIMIZATION_ENTER \
+ _Pragma ("optimize=low")
+ #else
+ #define LOW_OPTIMIZATION_ENTER
+ #endif
+
+ /* Exit low optimization region - place directly after end of function definition */
+ #define LOW_OPTIMIZATION_EXIT
+
+ /* Enter low optimization region - place directly above function definition */
+ #if defined( ARM_MATH_CM4 ) || defined( ARM_MATH_CM7)
+ #define IAR_ONLY_LOW_OPTIMIZATION_ENTER \
+ _Pragma ("optimize=low")
+ #else
+ #define IAR_ONLY_LOW_OPTIMIZATION_ENTER
+ #endif
+
+ /* Exit low optimization region - place directly after end of function definition */
+ #define IAR_ONLY_LOW_OPTIMIZATION_EXIT
+
+#elif defined(__CSMC__)
+ #define LOW_OPTIMIZATION_ENTER
+ #define LOW_OPTIMIZATION_EXIT
+ #define IAR_ONLY_LOW_OPTIMIZATION_ENTER
+ #define IAR_ONLY_LOW_OPTIMIZATION_EXIT
+
+#elif defined(__TASKING__)
+ #define LOW_OPTIMIZATION_ENTER
+ #define LOW_OPTIMIZATION_EXIT
+ #define IAR_ONLY_LOW_OPTIMIZATION_ENTER
+ #define IAR_ONLY_LOW_OPTIMIZATION_EXIT
+
+#endif
+
+
+#ifdef __cplusplus
+}
+#endif
+
+
+#if defined ( __GNUC__ )
+#pragma GCC diagnostic pop
+#endif
+
+#endif /* _ARM_MATH_H */
+
+/**
+ *
+ * End of file.
+ */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/toolchain/cmsis/include/cmsis_armcc.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/toolchain/cmsis/include/cmsis_armcc.h
new file mode 100644
index 0000000..74c49c6
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/toolchain/cmsis/include/cmsis_armcc.h
@@ -0,0 +1,734 @@
+/**************************************************************************//**
+ * @file cmsis_armcc.h
+ * @brief CMSIS Cortex-M Core Function/Instruction Header File
+ * @version V4.30
+ * @date 20. October 2015
+ ******************************************************************************/
+/* Copyright (c) 2009 - 2015 ARM LIMITED
+
+ All rights reserved.
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are met:
+ - Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ - 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.
+ - Neither the name of ARM 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 COPYRIGHT HOLDERS AND 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.
+ ---------------------------------------------------------------------------*/
+
+
+#ifndef __CMSIS_ARMCC_H
+#define __CMSIS_ARMCC_H
+
+
+#if defined(__ARMCC_VERSION) && (__ARMCC_VERSION < 400677)
+ #error "Please use ARM Compiler Toolchain V4.0.677 or later!"
+#endif
+
+/* ########################### Core Function Access ########################### */
+/** \ingroup CMSIS_Core_FunctionInterface
+ \defgroup CMSIS_Core_RegAccFunctions CMSIS Core Register Access Functions
+ @{
+ */
+
+/* intrinsic void __enable_irq(); */
+/* intrinsic void __disable_irq(); */
+
+/**
+ \brief Get Control Register
+ \details Returns the content of the Control Register.
+ \return Control Register value
+ */
+__STATIC_INLINE uint32_t __get_CONTROL(void)
+{
+ register uint32_t __regControl __ASM("control");
+ return(__regControl);
+}
+
+
+/**
+ \brief Set Control Register
+ \details Writes the given value to the Control Register.
+ \param [in] control Control Register value to set
+ */
+__STATIC_INLINE void __set_CONTROL(uint32_t control)
+{
+ register uint32_t __regControl __ASM("control");
+ __regControl = control;
+}
+
+
+/**
+ \brief Get IPSR Register
+ \details Returns the content of the IPSR Register.
+ \return IPSR Register value
+ */
+__STATIC_INLINE uint32_t __get_IPSR(void)
+{
+ register uint32_t __regIPSR __ASM("ipsr");
+ return(__regIPSR);
+}
+
+
+/**
+ \brief Get APSR Register
+ \details Returns the content of the APSR Register.
+ \return APSR Register value
+ */
+__STATIC_INLINE uint32_t __get_APSR(void)
+{
+ register uint32_t __regAPSR __ASM("apsr");
+ return(__regAPSR);
+}
+
+
+/**
+ \brief Get xPSR Register
+ \details Returns the content of the xPSR Register.
+ \return xPSR Register value
+ */
+__STATIC_INLINE uint32_t __get_xPSR(void)
+{
+ register uint32_t __regXPSR __ASM("xpsr");
+ return(__regXPSR);
+}
+
+
+/**
+ \brief Get Process Stack Pointer
+ \details Returns the current value of the Process Stack Pointer (PSP).
+ \return PSP Register value
+ */
+__STATIC_INLINE uint32_t __get_PSP(void)
+{
+ register uint32_t __regProcessStackPointer __ASM("psp");
+ return(__regProcessStackPointer);
+}
+
+
+/**
+ \brief Set Process Stack Pointer
+ \details Assigns the given value to the Process Stack Pointer (PSP).
+ \param [in] topOfProcStack Process Stack Pointer value to set
+ */
+__STATIC_INLINE void __set_PSP(uint32_t topOfProcStack)
+{
+ register uint32_t __regProcessStackPointer __ASM("psp");
+ __regProcessStackPointer = topOfProcStack;
+}
+
+
+/**
+ \brief Get Main Stack Pointer
+ \details Returns the current value of the Main Stack Pointer (MSP).
+ \return MSP Register value
+ */
+__STATIC_INLINE uint32_t __get_MSP(void)
+{
+ register uint32_t __regMainStackPointer __ASM("msp");
+ return(__regMainStackPointer);
+}
+
+
+/**
+ \brief Set Main Stack Pointer
+ \details Assigns the given value to the Main Stack Pointer (MSP).
+ \param [in] topOfMainStack Main Stack Pointer value to set
+ */
+__STATIC_INLINE void __set_MSP(uint32_t topOfMainStack)
+{
+ register uint32_t __regMainStackPointer __ASM("msp");
+ __regMainStackPointer = topOfMainStack;
+}
+
+
+/**
+ \brief Get Priority Mask
+ \details Returns the current state of the priority mask bit from the Priority Mask Register.
+ \return Priority Mask value
+ */
+__STATIC_INLINE uint32_t __get_PRIMASK(void)
+{
+ register uint32_t __regPriMask __ASM("primask");
+ return(__regPriMask);
+}
+
+
+/**
+ \brief Set Priority Mask
+ \details Assigns the given value to the Priority Mask Register.
+ \param [in] priMask Priority Mask
+ */
+__STATIC_INLINE void __set_PRIMASK(uint32_t priMask)
+{
+ register uint32_t __regPriMask __ASM("primask");
+ __regPriMask = (priMask);
+}
+
+
+#if (__CORTEX_M >= 0x03U) || (__CORTEX_SC >= 300U)
+
+/**
+ \brief Enable FIQ
+ \details Enables FIQ interrupts by clearing the F-bit in the CPSR.
+ Can only be executed in Privileged modes.
+ */
+#define __enable_fault_irq __enable_fiq
+
+
+/**
+ \brief Disable FIQ
+ \details Disables FIQ interrupts by setting the F-bit in the CPSR.
+ Can only be executed in Privileged modes.
+ */
+#define __disable_fault_irq __disable_fiq
+
+
+/**
+ \brief Get Base Priority
+ \details Returns the current value of the Base Priority register.
+ \return Base Priority register value
+ */
+__STATIC_INLINE uint32_t __get_BASEPRI(void)
+{
+ register uint32_t __regBasePri __ASM("basepri");
+ return(__regBasePri);
+}
+
+
+/**
+ \brief Set Base Priority
+ \details Assigns the given value to the Base Priority register.
+ \param [in] basePri Base Priority value to set
+ */
+__STATIC_INLINE void __set_BASEPRI(uint32_t basePri)
+{
+ register uint32_t __regBasePri __ASM("basepri");
+ __regBasePri = (basePri & 0xFFU);
+}
+
+
+/**
+ \brief Set Base Priority with condition
+ \details Assigns the given value to the Base Priority register only if BASEPRI masking is disabled,
+ or the new value increases the BASEPRI priority level.
+ \param [in] basePri Base Priority value to set
+ */
+__STATIC_INLINE void __set_BASEPRI_MAX(uint32_t basePri)
+{
+ register uint32_t __regBasePriMax __ASM("basepri_max");
+ __regBasePriMax = (basePri & 0xFFU);
+}
+
+
+/**
+ \brief Get Fault Mask
+ \details Returns the current value of the Fault Mask register.
+ \return Fault Mask register value
+ */
+__STATIC_INLINE uint32_t __get_FAULTMASK(void)
+{
+ register uint32_t __regFaultMask __ASM("faultmask");
+ return(__regFaultMask);
+}
+
+
+/**
+ \brief Set Fault Mask
+ \details Assigns the given value to the Fault Mask register.
+ \param [in] faultMask Fault Mask value to set
+ */
+__STATIC_INLINE void __set_FAULTMASK(uint32_t faultMask)
+{
+ register uint32_t __regFaultMask __ASM("faultmask");
+ __regFaultMask = (faultMask & (uint32_t)1);
+}
+
+#endif /* (__CORTEX_M >= 0x03U) || (__CORTEX_SC >= 300U) */
+
+
+#if (__CORTEX_M == 0x04U) || (__CORTEX_M == 0x07U)
+
+/**
+ \brief Get FPSCR
+ \details Returns the current value of the Floating Point Status/Control register.
+ \return Floating Point Status/Control register value
+ */
+__STATIC_INLINE uint32_t __get_FPSCR(void)
+{
+#if (__FPU_PRESENT == 1U) && (__FPU_USED == 1U)
+ register uint32_t __regfpscr __ASM("fpscr");
+ return(__regfpscr);
+#else
+ return(0U);
+#endif
+}
+
+
+/**
+ \brief Set FPSCR
+ \details Assigns the given value to the Floating Point Status/Control register.
+ \param [in] fpscr Floating Point Status/Control value to set
+ */
+__STATIC_INLINE void __set_FPSCR(uint32_t fpscr)
+{
+#if (__FPU_PRESENT == 1U) && (__FPU_USED == 1U)
+ register uint32_t __regfpscr __ASM("fpscr");
+ __regfpscr = (fpscr);
+#endif
+}
+
+#endif /* (__CORTEX_M == 0x04U) || (__CORTEX_M == 0x07U) */
+
+
+
+/*@} end of CMSIS_Core_RegAccFunctions */
+
+
+/* ########################## Core Instruction Access ######################### */
+/** \defgroup CMSIS_Core_InstructionInterface CMSIS Core Instruction Interface
+ Access to dedicated instructions
+ @{
+*/
+
+/**
+ \brief No Operation
+ \details No Operation does nothing. This instruction can be used for code alignment purposes.
+ */
+#define __NOP __nop
+
+
+/**
+ \brief Wait For Interrupt
+ \details Wait For Interrupt is a hint instruction that suspends execution until one of a number of events occurs.
+ */
+#define __WFI __wfi
+
+
+/**
+ \brief Wait For Event
+ \details Wait For Event is a hint instruction that permits the processor to enter
+ a low-power state until one of a number of events occurs.
+ */
+#define __WFE __wfe
+
+
+/**
+ \brief Send Event
+ \details Send Event is a hint instruction. It causes an event to be signaled to the CPU.
+ */
+#define __SEV __sev
+
+
+/**
+ \brief Instruction Synchronization Barrier
+ \details Instruction Synchronization Barrier flushes the pipeline in the processor,
+ so that all instructions following the ISB are fetched from cache or memory,
+ after the instruction has been completed.
+ */
+#define __ISB() do {\
+ __schedule_barrier();\
+ __isb(0xF);\
+ __schedule_barrier();\
+ } while (0U)
+
+/**
+ \brief Data Synchronization Barrier
+ \details Acts as a special kind of Data Memory Barrier.
+ It completes when all explicit memory accesses before this instruction complete.
+ */
+#define __DSB() do {\
+ __schedule_barrier();\
+ __dsb(0xF);\
+ __schedule_barrier();\
+ } while (0U)
+
+/**
+ \brief Data Memory Barrier
+ \details Ensures the apparent order of the explicit memory operations before
+ and after the instruction, without ensuring their completion.
+ */
+#define __DMB() do {\
+ __schedule_barrier();\
+ __dmb(0xF);\
+ __schedule_barrier();\
+ } while (0U)
+
+/**
+ \brief Reverse byte order (32 bit)
+ \details Reverses the byte order in integer value.
+ \param [in] value Value to reverse
+ \return Reversed value
+ */
+#define __REV __rev
+
+
+/**
+ \brief Reverse byte order (16 bit)
+ \details Reverses the byte order in two unsigned short values.
+ \param [in] value Value to reverse
+ \return Reversed value
+ */
+#ifndef __NO_EMBEDDED_ASM
+__attribute__((section(".rev16_text"))) __STATIC_INLINE __ASM uint32_t __REV16(uint32_t value)
+{
+ rev16 r0, r0
+ bx lr
+}
+#endif
+
+/**
+ \brief Reverse byte order in signed short value
+ \details Reverses the byte order in a signed short value with sign extension to integer.
+ \param [in] value Value to reverse
+ \return Reversed value
+ */
+#ifndef __NO_EMBEDDED_ASM
+__attribute__((section(".revsh_text"))) __STATIC_INLINE __ASM int32_t __REVSH(int32_t value)
+{
+ revsh r0, r0
+ bx lr
+}
+#endif
+
+
+/**
+ \brief Rotate Right in unsigned value (32 bit)
+ \details Rotate Right (immediate) provides the value of the contents of a register rotated by a variable number of bits.
+ \param [in] value Value to rotate
+ \param [in] value Number of Bits to rotate
+ \return Rotated value
+ */
+#define __ROR __ror
+
+
+/**
+ \brief Breakpoint
+ \details Causes the processor to enter Debug state.
+ Debug tools can use this to investigate system state when the instruction at a particular address is reached.
+ \param [in] value is ignored by the processor.
+ If required, a debugger can use it to store additional information about the breakpoint.
+ */
+#define __BKPT(value) __breakpoint(value)
+
+
+/**
+ \brief Reverse bit order of value
+ \details Reverses the bit order of the given value.
+ \param [in] value Value to reverse
+ \return Reversed value
+ */
+#if (__CORTEX_M >= 0x03U) || (__CORTEX_SC >= 300U)
+ #define __RBIT __rbit
+#else
+__attribute__((always_inline)) __STATIC_INLINE uint32_t __RBIT(uint32_t value)
+{
+ uint32_t result;
+ int32_t s = 4 /*sizeof(v)*/ * 8 - 1; /* extra shift needed at end */
+
+ result = value; /* r will be reversed bits of v; first get LSB of v */
+ for (value >>= 1U; value; value >>= 1U)
+ {
+ result <<= 1U;
+ result |= value & 1U;
+ s--;
+ }
+ result <<= s; /* shift when v's highest bits are zero */
+ return(result);
+}
+#endif
+
+
+/**
+ \brief Count leading zeros
+ \details Counts the number of leading zeros of a data value.
+ \param [in] value Value to count the leading zeros
+ \return number of leading zeros in value
+ */
+#define __CLZ __clz
+
+
+#if (__CORTEX_M >= 0x03U) || (__CORTEX_SC >= 300U)
+
+/**
+ \brief LDR Exclusive (8 bit)
+ \details Executes a exclusive LDR instruction for 8 bit value.
+ \param [in] ptr Pointer to data
+ \return value of type uint8_t at (*ptr)
+ */
+#if defined(__ARMCC_VERSION) && (__ARMCC_VERSION < 5060020)
+ #define __LDREXB(ptr) ((uint8_t ) __ldrex(ptr))
+#else
+ #define __LDREXB(ptr) _Pragma("push") _Pragma("diag_suppress 3731") ((uint8_t ) __ldrex(ptr)) _Pragma("pop")
+#endif
+
+
+/**
+ \brief LDR Exclusive (16 bit)
+ \details Executes a exclusive LDR instruction for 16 bit values.
+ \param [in] ptr Pointer to data
+ \return value of type uint16_t at (*ptr)
+ */
+#if defined(__ARMCC_VERSION) && (__ARMCC_VERSION < 5060020)
+ #define __LDREXH(ptr) ((uint16_t) __ldrex(ptr))
+#else
+ #define __LDREXH(ptr) _Pragma("push") _Pragma("diag_suppress 3731") ((uint16_t) __ldrex(ptr)) _Pragma("pop")
+#endif
+
+
+/**
+ \brief LDR Exclusive (32 bit)
+ \details Executes a exclusive LDR instruction for 32 bit values.
+ \param [in] ptr Pointer to data
+ \return value of type uint32_t at (*ptr)
+ */
+#if defined(__ARMCC_VERSION) && (__ARMCC_VERSION < 5060020)
+ #define __LDREXW(ptr) ((uint32_t ) __ldrex(ptr))
+#else
+ #define __LDREXW(ptr) _Pragma("push") _Pragma("diag_suppress 3731") ((uint32_t ) __ldrex(ptr)) _Pragma("pop")
+#endif
+
+
+/**
+ \brief STR Exclusive (8 bit)
+ \details Executes a exclusive STR instruction for 8 bit values.
+ \param [in] value Value to store
+ \param [in] ptr Pointer to location
+ \return 0 Function succeeded
+ \return 1 Function failed
+ */
+#if defined(__ARMCC_VERSION) && (__ARMCC_VERSION < 5060020)
+ #define __STREXB(value, ptr) __strex(value, ptr)
+#else
+ #define __STREXB(value, ptr) _Pragma("push") _Pragma("diag_suppress 3731") __strex(value, ptr) _Pragma("pop")
+#endif
+
+
+/**
+ \brief STR Exclusive (16 bit)
+ \details Executes a exclusive STR instruction for 16 bit values.
+ \param [in] value Value to store
+ \param [in] ptr Pointer to location
+ \return 0 Function succeeded
+ \return 1 Function failed
+ */
+#if defined(__ARMCC_VERSION) && (__ARMCC_VERSION < 5060020)
+ #define __STREXH(value, ptr) __strex(value, ptr)
+#else
+ #define __STREXH(value, ptr) _Pragma("push") _Pragma("diag_suppress 3731") __strex(value, ptr) _Pragma("pop")
+#endif
+
+
+/**
+ \brief STR Exclusive (32 bit)
+ \details Executes a exclusive STR instruction for 32 bit values.
+ \param [in] value Value to store
+ \param [in] ptr Pointer to location
+ \return 0 Function succeeded
+ \return 1 Function failed
+ */
+#if defined(__ARMCC_VERSION) && (__ARMCC_VERSION < 5060020)
+ #define __STREXW(value, ptr) __strex(value, ptr)
+#else
+ #define __STREXW(value, ptr) _Pragma("push") _Pragma("diag_suppress 3731") __strex(value, ptr) _Pragma("pop")
+#endif
+
+
+/**
+ \brief Remove the exclusive lock
+ \details Removes the exclusive lock which is created by LDREX.
+ */
+#define __CLREX __clrex
+
+
+/**
+ \brief Signed Saturate
+ \details Saturates a signed value.
+ \param [in] value Value to be saturated
+ \param [in] sat Bit position to saturate to (1..32)
+ \return Saturated value
+ */
+#define __SSAT __ssat
+
+
+/**
+ \brief Unsigned Saturate
+ \details Saturates an unsigned value.
+ \param [in] value Value to be saturated
+ \param [in] sat Bit position to saturate to (0..31)
+ \return Saturated value
+ */
+#define __USAT __usat
+
+
+/**
+ \brief Rotate Right with Extend (32 bit)
+ \details Moves each bit of a bitstring right by one bit.
+ The carry input is shifted in at the left end of the bitstring.
+ \param [in] value Value to rotate
+ \return Rotated value
+ */
+#ifndef __NO_EMBEDDED_ASM
+__attribute__((section(".rrx_text"))) __STATIC_INLINE __ASM uint32_t __RRX(uint32_t value)
+{
+ rrx r0, r0
+ bx lr
+}
+#endif
+
+
+/**
+ \brief LDRT Unprivileged (8 bit)
+ \details Executes a Unprivileged LDRT instruction for 8 bit value.
+ \param [in] ptr Pointer to data
+ \return value of type uint8_t at (*ptr)
+ */
+#define __LDRBT(ptr) ((uint8_t ) __ldrt(ptr))
+
+
+/**
+ \brief LDRT Unprivileged (16 bit)
+ \details Executes a Unprivileged LDRT instruction for 16 bit values.
+ \param [in] ptr Pointer to data
+ \return value of type uint16_t at (*ptr)
+ */
+#define __LDRHT(ptr) ((uint16_t) __ldrt(ptr))
+
+
+/**
+ \brief LDRT Unprivileged (32 bit)
+ \details Executes a Unprivileged LDRT instruction for 32 bit values.
+ \param [in] ptr Pointer to data
+ \return value of type uint32_t at (*ptr)
+ */
+#define __LDRT(ptr) ((uint32_t ) __ldrt(ptr))
+
+
+/**
+ \brief STRT Unprivileged (8 bit)
+ \details Executes a Unprivileged STRT instruction for 8 bit values.
+ \param [in] value Value to store
+ \param [in] ptr Pointer to location
+ */
+#define __STRBT(value, ptr) __strt(value, ptr)
+
+
+/**
+ \brief STRT Unprivileged (16 bit)
+ \details Executes a Unprivileged STRT instruction for 16 bit values.
+ \param [in] value Value to store
+ \param [in] ptr Pointer to location
+ */
+#define __STRHT(value, ptr) __strt(value, ptr)
+
+
+/**
+ \brief STRT Unprivileged (32 bit)
+ \details Executes a Unprivileged STRT instruction for 32 bit values.
+ \param [in] value Value to store
+ \param [in] ptr Pointer to location
+ */
+#define __STRT(value, ptr) __strt(value, ptr)
+
+#endif /* (__CORTEX_M >= 0x03U) || (__CORTEX_SC >= 300U) */
+
+/*@}*/ /* end of group CMSIS_Core_InstructionInterface */
+
+
+/* ################### Compiler specific Intrinsics ########################### */
+/** \defgroup CMSIS_SIMD_intrinsics CMSIS SIMD Intrinsics
+ Access to dedicated SIMD instructions
+ @{
+*/
+
+#if (__CORTEX_M >= 0x04U) /* only for Cortex-M4 and above */
+
+#define __SADD8 __sadd8
+#define __QADD8 __qadd8
+#define __SHADD8 __shadd8
+#define __UADD8 __uadd8
+#define __UQADD8 __uqadd8
+#define __UHADD8 __uhadd8
+#define __SSUB8 __ssub8
+#define __QSUB8 __qsub8
+#define __SHSUB8 __shsub8
+#define __USUB8 __usub8
+#define __UQSUB8 __uqsub8
+#define __UHSUB8 __uhsub8
+#define __SADD16 __sadd16
+#define __QADD16 __qadd16
+#define __SHADD16 __shadd16
+#define __UADD16 __uadd16
+#define __UQADD16 __uqadd16
+#define __UHADD16 __uhadd16
+#define __SSUB16 __ssub16
+#define __QSUB16 __qsub16
+#define __SHSUB16 __shsub16
+#define __USUB16 __usub16
+#define __UQSUB16 __uqsub16
+#define __UHSUB16 __uhsub16
+#define __SASX __sasx
+#define __QASX __qasx
+#define __SHASX __shasx
+#define __UASX __uasx
+#define __UQASX __uqasx
+#define __UHASX __uhasx
+#define __SSAX __ssax
+#define __QSAX __qsax
+#define __SHSAX __shsax
+#define __USAX __usax
+#define __UQSAX __uqsax
+#define __UHSAX __uhsax
+#define __USAD8 __usad8
+#define __USADA8 __usada8
+#define __SSAT16 __ssat16
+#define __USAT16 __usat16
+#define __UXTB16 __uxtb16
+#define __UXTAB16 __uxtab16
+#define __SXTB16 __sxtb16
+#define __SXTAB16 __sxtab16
+#define __SMUAD __smuad
+#define __SMUADX __smuadx
+#define __SMLAD __smlad
+#define __SMLADX __smladx
+#define __SMLALD __smlald
+#define __SMLALDX __smlaldx
+#define __SMUSD __smusd
+#define __SMUSDX __smusdx
+#define __SMLSD __smlsd
+#define __SMLSDX __smlsdx
+#define __SMLSLD __smlsld
+#define __SMLSLDX __smlsldx
+#define __SEL __sel
+#define __QADD __qadd
+#define __QSUB __qsub
+
+#define __PKHBT(ARG1,ARG2,ARG3) ( ((((uint32_t)(ARG1)) ) & 0x0000FFFFUL) | \
+ ((((uint32_t)(ARG2)) << (ARG3)) & 0xFFFF0000UL) )
+
+#define __PKHTB(ARG1,ARG2,ARG3) ( ((((uint32_t)(ARG1)) ) & 0xFFFF0000UL) | \
+ ((((uint32_t)(ARG2)) >> (ARG3)) & 0x0000FFFFUL) )
+
+#define __SMMLA(ARG1,ARG2,ARG3) ( (int32_t)((((int64_t)(ARG1) * (ARG2)) + \
+ ((int64_t)(ARG3) << 32U) ) >> 32U))
+
+#endif /* (__CORTEX_M >= 0x04) */
+/*@} end of group CMSIS_SIMD_intrinsics */
+
+
+#endif /* __CMSIS_ARMCC_H */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/toolchain/cmsis/include/cmsis_armcc_V6.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/toolchain/cmsis/include/cmsis_armcc_V6.h
new file mode 100644
index 0000000..cd13240
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/toolchain/cmsis/include/cmsis_armcc_V6.h
@@ -0,0 +1,1800 @@
+/**************************************************************************//**
+ * @file cmsis_armcc_V6.h
+ * @brief CMSIS Cortex-M Core Function/Instruction Header File
+ * @version V4.30
+ * @date 20. October 2015
+ ******************************************************************************/
+/* Copyright (c) 2009 - 2015 ARM LIMITED
+
+ All rights reserved.
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are met:
+ - Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ - 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.
+ - Neither the name of ARM 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 COPYRIGHT HOLDERS AND 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.
+ ---------------------------------------------------------------------------*/
+
+
+#ifndef __CMSIS_ARMCC_V6_H
+#define __CMSIS_ARMCC_V6_H
+
+
+/* ########################### Core Function Access ########################### */
+/** \ingroup CMSIS_Core_FunctionInterface
+ \defgroup CMSIS_Core_RegAccFunctions CMSIS Core Register Access Functions
+ @{
+ */
+
+/**
+ \brief Enable IRQ Interrupts
+ \details Enables IRQ interrupts by clearing the I-bit in the CPSR.
+ Can only be executed in Privileged modes.
+ */
+__attribute__((always_inline)) __STATIC_INLINE void __enable_irq(void)
+{
+ __ASM volatile ("cpsie i" : : : "memory");
+}
+
+
+/**
+ \brief Disable IRQ Interrupts
+ \details Disables IRQ interrupts by setting the I-bit in the CPSR.
+ Can only be executed in Privileged modes.
+ */
+__attribute__((always_inline)) __STATIC_INLINE void __disable_irq(void)
+{
+ __ASM volatile ("cpsid i" : : : "memory");
+}
+
+
+/**
+ \brief Get Control Register
+ \details Returns the content of the Control Register.
+ \return Control Register value
+ */
+__attribute__((always_inline)) __STATIC_INLINE uint32_t __get_CONTROL(void)
+{
+ uint32_t result;
+
+ __ASM volatile ("MRS %0, control" : "=r" (result) );
+ return(result);
+}
+
+
+#if (__ARM_FEATURE_CMSE == 3U)
+/**
+ \brief Get Control Register (non-secure)
+ \details Returns the content of the non-secure Control Register when in secure mode.
+ \return non-secure Control Register value
+ */
+__attribute__((always_inline)) __STATIC_INLINE uint32_t __TZ_get_CONTROL_NS(void)
+{
+ uint32_t result;
+
+ __ASM volatile ("MRS %0, control_ns" : "=r" (result) );
+ return(result);
+}
+#endif
+
+
+/**
+ \brief Set Control Register
+ \details Writes the given value to the Control Register.
+ \param [in] control Control Register value to set
+ */
+__attribute__((always_inline)) __STATIC_INLINE void __set_CONTROL(uint32_t control)
+{
+ __ASM volatile ("MSR control, %0" : : "r" (control) : "memory");
+}
+
+
+#if (__ARM_FEATURE_CMSE == 3U)
+/**
+ \brief Set Control Register (non-secure)
+ \details Writes the given value to the non-secure Control Register when in secure state.
+ \param [in] control Control Register value to set
+ */
+__attribute__((always_inline)) __STATIC_INLINE void __TZ_set_CONTROL_NS(uint32_t control)
+{
+ __ASM volatile ("MSR control_ns, %0" : : "r" (control) : "memory");
+}
+#endif
+
+
+/**
+ \brief Get IPSR Register
+ \details Returns the content of the IPSR Register.
+ \return IPSR Register value
+ */
+__attribute__((always_inline)) __STATIC_INLINE uint32_t __get_IPSR(void)
+{
+ uint32_t result;
+
+ __ASM volatile ("MRS %0, ipsr" : "=r" (result) );
+ return(result);
+}
+
+
+#if (__ARM_FEATURE_CMSE == 3U)
+/**
+ \brief Get IPSR Register (non-secure)
+ \details Returns the content of the non-secure IPSR Register when in secure state.
+ \return IPSR Register value
+ */
+__attribute__((always_inline)) __STATIC_INLINE uint32_t __TZ_get_IPSR_NS(void)
+{
+ uint32_t result;
+
+ __ASM volatile ("MRS %0, ipsr_ns" : "=r" (result) );
+ return(result);
+}
+#endif
+
+
+/**
+ \brief Get APSR Register
+ \details Returns the content of the APSR Register.
+ \return APSR Register value
+ */
+__attribute__((always_inline)) __STATIC_INLINE uint32_t __get_APSR(void)
+{
+ uint32_t result;
+
+ __ASM volatile ("MRS %0, apsr" : "=r" (result) );
+ return(result);
+}
+
+
+#if (__ARM_FEATURE_CMSE == 3U)
+/**
+ \brief Get APSR Register (non-secure)
+ \details Returns the content of the non-secure APSR Register when in secure state.
+ \return APSR Register value
+ */
+__attribute__((always_inline)) __STATIC_INLINE uint32_t __TZ_get_APSR_NS(void)
+{
+ uint32_t result;
+
+ __ASM volatile ("MRS %0, apsr_ns" : "=r" (result) );
+ return(result);
+}
+#endif
+
+
+/**
+ \brief Get xPSR Register
+ \details Returns the content of the xPSR Register.
+ \return xPSR Register value
+ */
+__attribute__((always_inline)) __STATIC_INLINE uint32_t __get_xPSR(void)
+{
+ uint32_t result;
+
+ __ASM volatile ("MRS %0, xpsr" : "=r" (result) );
+ return(result);
+}
+
+
+#if (__ARM_FEATURE_CMSE == 3U)
+/**
+ \brief Get xPSR Register (non-secure)
+ \details Returns the content of the non-secure xPSR Register when in secure state.
+ \return xPSR Register value
+ */
+__attribute__((always_inline)) __STATIC_INLINE uint32_t __TZ_get_xPSR_NS(void)
+{
+ uint32_t result;
+
+ __ASM volatile ("MRS %0, xpsr_ns" : "=r" (result) );
+ return(result);
+}
+#endif
+
+
+/**
+ \brief Get Process Stack Pointer
+ \details Returns the current value of the Process Stack Pointer (PSP).
+ \return PSP Register value
+ */
+__attribute__((always_inline)) __STATIC_INLINE uint32_t __get_PSP(void)
+{
+ register uint32_t result;
+
+ __ASM volatile ("MRS %0, psp" : "=r" (result) );
+ return(result);
+}
+
+
+#if (__ARM_FEATURE_CMSE == 3U)
+/**
+ \brief Get Process Stack Pointer (non-secure)
+ \details Returns the current value of the non-secure Process Stack Pointer (PSP) when in secure state.
+ \return PSP Register value
+ */
+__attribute__((always_inline)) __STATIC_INLINE uint32_t __TZ_get_PSP_NS(void)
+{
+ register uint32_t result;
+
+ __ASM volatile ("MRS %0, psp_ns" : "=r" (result) );
+ return(result);
+}
+#endif
+
+
+/**
+ \brief Set Process Stack Pointer
+ \details Assigns the given value to the Process Stack Pointer (PSP).
+ \param [in] topOfProcStack Process Stack Pointer value to set
+ */
+__attribute__((always_inline)) __STATIC_INLINE void __set_PSP(uint32_t topOfProcStack)
+{
+ __ASM volatile ("MSR psp, %0" : : "r" (topOfProcStack) : "sp");
+}
+
+
+#if (__ARM_FEATURE_CMSE == 3U)
+/**
+ \brief Set Process Stack Pointer (non-secure)
+ \details Assigns the given value to the non-secure Process Stack Pointer (PSP) when in secure state.
+ \param [in] topOfProcStack Process Stack Pointer value to set
+ */
+__attribute__((always_inline)) __STATIC_INLINE void __TZ_set_PSP_NS(uint32_t topOfProcStack)
+{
+ __ASM volatile ("MSR psp_ns, %0" : : "r" (topOfProcStack) : "sp");
+}
+#endif
+
+
+/**
+ \brief Get Main Stack Pointer
+ \details Returns the current value of the Main Stack Pointer (MSP).
+ \return MSP Register value
+ */
+__attribute__((always_inline)) __STATIC_INLINE uint32_t __get_MSP(void)
+{
+ register uint32_t result;
+
+ __ASM volatile ("MRS %0, msp" : "=r" (result) );
+ return(result);
+}
+
+
+#if (__ARM_FEATURE_CMSE == 3U)
+/**
+ \brief Get Main Stack Pointer (non-secure)
+ \details Returns the current value of the non-secure Main Stack Pointer (MSP) when in secure state.
+ \return MSP Register value
+ */
+__attribute__((always_inline)) __STATIC_INLINE uint32_t __TZ_get_MSP_NS(void)
+{
+ register uint32_t result;
+
+ __ASM volatile ("MRS %0, msp_ns" : "=r" (result) );
+ return(result);
+}
+#endif
+
+
+/**
+ \brief Set Main Stack Pointer
+ \details Assigns the given value to the Main Stack Pointer (MSP).
+ \param [in] topOfMainStack Main Stack Pointer value to set
+ */
+__attribute__((always_inline)) __STATIC_INLINE void __set_MSP(uint32_t topOfMainStack)
+{
+ __ASM volatile ("MSR msp, %0" : : "r" (topOfMainStack) : "sp");
+}
+
+
+#if (__ARM_FEATURE_CMSE == 3U)
+/**
+ \brief Set Main Stack Pointer (non-secure)
+ \details Assigns the given value to the non-secure Main Stack Pointer (MSP) when in secure state.
+ \param [in] topOfMainStack Main Stack Pointer value to set
+ */
+__attribute__((always_inline)) __STATIC_INLINE void __TZ_set_MSP_NS(uint32_t topOfMainStack)
+{
+ __ASM volatile ("MSR msp_ns, %0" : : "r" (topOfMainStack) : "sp");
+}
+#endif
+
+
+/**
+ \brief Get Priority Mask
+ \details Returns the current state of the priority mask bit from the Priority Mask Register.
+ \return Priority Mask value
+ */
+__attribute__((always_inline)) __STATIC_INLINE uint32_t __get_PRIMASK(void)
+{
+ uint32_t result;
+
+ __ASM volatile ("MRS %0, primask" : "=r" (result) );
+ return(result);
+}
+
+
+#if (__ARM_FEATURE_CMSE == 3U)
+/**
+ \brief Get Priority Mask (non-secure)
+ \details Returns the current state of the non-secure priority mask bit from the Priority Mask Register when in secure state.
+ \return Priority Mask value
+ */
+__attribute__((always_inline)) __STATIC_INLINE uint32_t __TZ_get_PRIMASK_NS(void)
+{
+ uint32_t result;
+
+ __ASM volatile ("MRS %0, primask_ns" : "=r" (result) );
+ return(result);
+}
+#endif
+
+
+/**
+ \brief Set Priority Mask
+ \details Assigns the given value to the Priority Mask Register.
+ \param [in] priMask Priority Mask
+ */
+__attribute__((always_inline)) __STATIC_INLINE void __set_PRIMASK(uint32_t priMask)
+{
+ __ASM volatile ("MSR primask, %0" : : "r" (priMask) : "memory");
+}
+
+
+#if (__ARM_FEATURE_CMSE == 3U)
+/**
+ \brief Set Priority Mask (non-secure)
+ \details Assigns the given value to the non-secure Priority Mask Register when in secure state.
+ \param [in] priMask Priority Mask
+ */
+__attribute__((always_inline)) __STATIC_INLINE void __TZ_set_PRIMASK_NS(uint32_t priMask)
+{
+ __ASM volatile ("MSR primask_ns, %0" : : "r" (priMask) : "memory");
+}
+#endif
+
+
+#if ((__ARM_ARCH_7M__ == 1U) || (__ARM_ARCH_7EM__ == 1U) || (__ARM_ARCH_8M__ == 1U)) /* ToDo: ARMCC_V6: check if this is ok for cortex >=3 */
+
+/**
+ \brief Enable FIQ
+ \details Enables FIQ interrupts by clearing the F-bit in the CPSR.
+ Can only be executed in Privileged modes.
+ */
+__attribute__((always_inline)) __STATIC_INLINE void __enable_fault_irq(void)
+{
+ __ASM volatile ("cpsie f" : : : "memory");
+}
+
+
+/**
+ \brief Disable FIQ
+ \details Disables FIQ interrupts by setting the F-bit in the CPSR.
+ Can only be executed in Privileged modes.
+ */
+__attribute__((always_inline)) __STATIC_INLINE void __disable_fault_irq(void)
+{
+ __ASM volatile ("cpsid f" : : : "memory");
+}
+
+
+/**
+ \brief Get Base Priority
+ \details Returns the current value of the Base Priority register.
+ \return Base Priority register value
+ */
+__attribute__((always_inline)) __STATIC_INLINE uint32_t __get_BASEPRI(void)
+{
+ uint32_t result;
+
+ __ASM volatile ("MRS %0, basepri" : "=r" (result) );
+ return(result);
+}
+
+
+#if (__ARM_FEATURE_CMSE == 3U)
+/**
+ \brief Get Base Priority (non-secure)
+ \details Returns the current value of the non-secure Base Priority register when in secure state.
+ \return Base Priority register value
+ */
+__attribute__((always_inline)) __STATIC_INLINE uint32_t __TZ_get_BASEPRI_NS(void)
+{
+ uint32_t result;
+
+ __ASM volatile ("MRS %0, basepri_ns" : "=r" (result) );
+ return(result);
+}
+#endif
+
+
+/**
+ \brief Set Base Priority
+ \details Assigns the given value to the Base Priority register.
+ \param [in] basePri Base Priority value to set
+ */
+__attribute__((always_inline)) __STATIC_INLINE void __set_BASEPRI(uint32_t value)
+{
+ __ASM volatile ("MSR basepri, %0" : : "r" (value) : "memory");
+}
+
+
+#if (__ARM_FEATURE_CMSE == 3U)
+/**
+ \brief Set Base Priority (non-secure)
+ \details Assigns the given value to the non-secure Base Priority register when in secure state.
+ \param [in] basePri Base Priority value to set
+ */
+__attribute__((always_inline)) __STATIC_INLINE void __TZ_set_BASEPRI_NS(uint32_t value)
+{
+ __ASM volatile ("MSR basepri_ns, %0" : : "r" (value) : "memory");
+}
+#endif
+
+
+/**
+ \brief Set Base Priority with condition
+ \details Assigns the given value to the Base Priority register only if BASEPRI masking is disabled,
+ or the new value increases the BASEPRI priority level.
+ \param [in] basePri Base Priority value to set
+ */
+__attribute__((always_inline)) __STATIC_INLINE void __set_BASEPRI_MAX(uint32_t value)
+{
+ __ASM volatile ("MSR basepri_max, %0" : : "r" (value) : "memory");
+}
+
+
+#if (__ARM_FEATURE_CMSE == 3U)
+/**
+ \brief Set Base Priority with condition (non_secure)
+ \details Assigns the given value to the non-secure Base Priority register when in secure state only if BASEPRI masking is disabled,
+ or the new value increases the BASEPRI priority level.
+ \param [in] basePri Base Priority value to set
+ */
+__attribute__((always_inline)) __STATIC_INLINE void __TZ_set_BASEPRI_MAX_NS(uint32_t value)
+{
+ __ASM volatile ("MSR basepri_max_ns, %0" : : "r" (value) : "memory");
+}
+#endif
+
+
+/**
+ \brief Get Fault Mask
+ \details Returns the current value of the Fault Mask register.
+ \return Fault Mask register value
+ */
+__attribute__((always_inline)) __STATIC_INLINE uint32_t __get_FAULTMASK(void)
+{
+ uint32_t result;
+
+ __ASM volatile ("MRS %0, faultmask" : "=r" (result) );
+ return(result);
+}
+
+
+#if (__ARM_FEATURE_CMSE == 3U)
+/**
+ \brief Get Fault Mask (non-secure)
+ \details Returns the current value of the non-secure Fault Mask register when in secure state.
+ \return Fault Mask register value
+ */
+__attribute__((always_inline)) __STATIC_INLINE uint32_t __TZ_get_FAULTMASK_NS(void)
+{
+ uint32_t result;
+
+ __ASM volatile ("MRS %0, faultmask_ns" : "=r" (result) );
+ return(result);
+}
+#endif
+
+
+/**
+ \brief Set Fault Mask
+ \details Assigns the given value to the Fault Mask register.
+ \param [in] faultMask Fault Mask value to set
+ */
+__attribute__((always_inline)) __STATIC_INLINE void __set_FAULTMASK(uint32_t faultMask)
+{
+ __ASM volatile ("MSR faultmask, %0" : : "r" (faultMask) : "memory");
+}
+
+
+#if (__ARM_FEATURE_CMSE == 3U)
+/**
+ \brief Set Fault Mask (non-secure)
+ \details Assigns the given value to the non-secure Fault Mask register when in secure state.
+ \param [in] faultMask Fault Mask value to set
+ */
+__attribute__((always_inline)) __STATIC_INLINE void __TZ_set_FAULTMASK_NS(uint32_t faultMask)
+{
+ __ASM volatile ("MSR faultmask_ns, %0" : : "r" (faultMask) : "memory");
+}
+#endif
+
+
+#endif /* ((__ARM_ARCH_7M__ == 1U) || (__ARM_ARCH_8M__ == 1U)) */
+
+
+#if (__ARM_ARCH_8M__ == 1U)
+
+/**
+ \brief Get Process Stack Pointer Limit
+ \details Returns the current value of the Process Stack Pointer Limit (PSPLIM).
+ \return PSPLIM Register value
+ */
+__attribute__((always_inline)) __STATIC_INLINE uint32_t __get_PSPLIM(void)
+{
+ register uint32_t result;
+
+ __ASM volatile ("MRS %0, psplim" : "=r" (result) );
+ return(result);
+}
+
+
+#if (__ARM_FEATURE_CMSE == 3U) && (__ARM_ARCH_PROFILE == 'M') /* ToDo: ARMCC_V6: check predefined macro for mainline */
+/**
+ \brief Get Process Stack Pointer Limit (non-secure)
+ \details Returns the current value of the non-secure Process Stack Pointer Limit (PSPLIM) when in secure state.
+ \return PSPLIM Register value
+ */
+__attribute__((always_inline)) __STATIC_INLINE uint32_t __TZ_get_PSPLIM_NS(void)
+{
+ register uint32_t result;
+
+ __ASM volatile ("MRS %0, psplim_ns" : "=r" (result) );
+ return(result);
+}
+#endif
+
+
+/**
+ \brief Set Process Stack Pointer Limit
+ \details Assigns the given value to the Process Stack Pointer Limit (PSPLIM).
+ \param [in] ProcStackPtrLimit Process Stack Pointer Limit value to set
+ */
+__attribute__((always_inline)) __STATIC_INLINE void __set_PSPLIM(uint32_t ProcStackPtrLimit)
+{
+ __ASM volatile ("MSR psplim, %0" : : "r" (ProcStackPtrLimit));
+}
+
+
+#if (__ARM_FEATURE_CMSE == 3U) && (__ARM_ARCH_PROFILE == 'M') /* ToDo: ARMCC_V6: check predefined macro for mainline */
+/**
+ \brief Set Process Stack Pointer (non-secure)
+ \details Assigns the given value to the non-secure Process Stack Pointer Limit (PSPLIM) when in secure state.
+ \param [in] ProcStackPtrLimit Process Stack Pointer Limit value to set
+ */
+__attribute__((always_inline)) __STATIC_INLINE void __TZ_set_PSPLIM_NS(uint32_t ProcStackPtrLimit)
+{
+ __ASM volatile ("MSR psplim_ns, %0\n" : : "r" (ProcStackPtrLimit));
+}
+#endif
+
+
+/**
+ \brief Get Main Stack Pointer Limit
+ \details Returns the current value of the Main Stack Pointer Limit (MSPLIM).
+ \return MSPLIM Register value
+ */
+__attribute__((always_inline)) __STATIC_INLINE uint32_t __get_MSPLIM(void)
+{
+ register uint32_t result;
+
+ __ASM volatile ("MRS %0, msplim" : "=r" (result) );
+
+ return(result);
+}
+
+
+#if (__ARM_FEATURE_CMSE == 3U) && (__ARM_ARCH_PROFILE == 'M') /* ToDo: ARMCC_V6: check predefined macro for mainline */
+/**
+ \brief Get Main Stack Pointer Limit (non-secure)
+ \details Returns the current value of the non-secure Main Stack Pointer Limit(MSPLIM) when in secure state.
+ \return MSPLIM Register value
+ */
+__attribute__((always_inline)) __STATIC_INLINE uint32_t __TZ_get_MSPLIM_NS(void)
+{
+ register uint32_t result;
+
+ __ASM volatile ("MRS %0, msplim_ns" : "=r" (result) );
+ return(result);
+}
+#endif
+
+
+/**
+ \brief Set Main Stack Pointer Limit
+ \details Assigns the given value to the Main Stack Pointer Limit (MSPLIM).
+ \param [in] MainStackPtrLimit Main Stack Pointer Limit value to set
+ */
+__attribute__((always_inline)) __STATIC_INLINE void __set_MSPLIM(uint32_t MainStackPtrLimit)
+{
+ __ASM volatile ("MSR msplim, %0" : : "r" (MainStackPtrLimit));
+}
+
+
+#if (__ARM_FEATURE_CMSE == 3U) && (__ARM_ARCH_PROFILE == 'M') /* ToDo: ARMCC_V6: check predefined macro for mainline */
+/**
+ \brief Set Main Stack Pointer Limit (non-secure)
+ \details Assigns the given value to the non-secure Main Stack Pointer Limit (MSPLIM) when in secure state.
+ \param [in] MainStackPtrLimit Main Stack Pointer value to set
+ */
+__attribute__((always_inline)) __STATIC_INLINE void __TZ_set_MSPLIM_NS(uint32_t MainStackPtrLimit)
+{
+ __ASM volatile ("MSR msplim_ns, %0" : : "r" (MainStackPtrLimit));
+}
+#endif
+
+#endif /* (__ARM_ARCH_8M__ == 1U) */
+
+
+#if ((__ARM_ARCH_7EM__ == 1U) || (__ARM_ARCH_8M__ == 1U)) /* ToDo: ARMCC_V6: check if this is ok for cortex >=4 */
+
+/**
+ \brief Get FPSCR
+ \details eturns the current value of the Floating Point Status/Control register.
+ \return Floating Point Status/Control register value
+ */
+#define __get_FPSCR __builtin_arm_get_fpscr
+#if 0
+__attribute__((always_inline)) __STATIC_INLINE uint32_t __get_FPSCR(void)
+{
+#if (__FPU_PRESENT == 1U) && (__FPU_USED == 1U)
+ uint32_t result;
+
+ __ASM volatile (""); /* Empty asm statement works as a scheduling barrier */
+ __ASM volatile ("VMRS %0, fpscr" : "=r" (result) );
+ __ASM volatile ("");
+ return(result);
+#else
+ return(0);
+#endif
+}
+#endif
+
+#if (__ARM_FEATURE_CMSE == 3U)
+/**
+ \brief Get FPSCR (non-secure)
+ \details Returns the current value of the non-secure Floating Point Status/Control register when in secure state.
+ \return Floating Point Status/Control register value
+ */
+__attribute__((always_inline)) __STATIC_INLINE uint32_t __TZ_get_FPSCR_NS(void)
+{
+#if (__FPU_PRESENT == 1U) && (__FPU_USED == 1U)
+ uint32_t result;
+
+ __ASM volatile (""); /* Empty asm statement works as a scheduling barrier */
+ __ASM volatile ("VMRS %0, fpscr_ns" : "=r" (result) );
+ __ASM volatile ("");
+ return(result);
+#else
+ return(0);
+#endif
+}
+#endif
+
+
+/**
+ \brief Set FPSCR
+ \details Assigns the given value to the Floating Point Status/Control register.
+ \param [in] fpscr Floating Point Status/Control value to set
+ */
+#define __set_FPSCR __builtin_arm_set_fpscr
+#if 0
+__attribute__((always_inline)) __STATIC_INLINE void __set_FPSCR(uint32_t fpscr)
+{
+#if (__FPU_PRESENT == 1U) && (__FPU_USED == 1U)
+ __ASM volatile (""); /* Empty asm statement works as a scheduling barrier */
+ __ASM volatile ("VMSR fpscr, %0" : : "r" (fpscr) : "vfpcc");
+ __ASM volatile ("");
+#endif
+}
+#endif
+
+#if (__ARM_FEATURE_CMSE == 3U)
+/**
+ \brief Set FPSCR (non-secure)
+ \details Assigns the given value to the non-secure Floating Point Status/Control register when in secure state.
+ \param [in] fpscr Floating Point Status/Control value to set
+ */
+__attribute__((always_inline)) __STATIC_INLINE void __TZ_set_FPSCR_NS(uint32_t fpscr)
+{
+#if (__FPU_PRESENT == 1U) && (__FPU_USED == 1U)
+ __ASM volatile (""); /* Empty asm statement works as a scheduling barrier */
+ __ASM volatile ("VMSR fpscr_ns, %0" : : "r" (fpscr) : "vfpcc");
+ __ASM volatile ("");
+#endif
+}
+#endif
+
+#endif /* ((__ARM_ARCH_7EM__ == 1U) || (__ARM_ARCH_8M__ == 1U)) */
+
+
+
+/*@} end of CMSIS_Core_RegAccFunctions */
+
+
+/* ########################## Core Instruction Access ######################### */
+/** \defgroup CMSIS_Core_InstructionInterface CMSIS Core Instruction Interface
+ Access to dedicated instructions
+ @{
+*/
+
+/* Define macros for porting to both thumb1 and thumb2.
+ * For thumb1, use low register (r0-r7), specified by constraint "l"
+ * Otherwise, use general registers, specified by constraint "r" */
+#if defined (__thumb__) && !defined (__thumb2__)
+#define __CMSIS_GCC_OUT_REG(r) "=l" (r)
+#define __CMSIS_GCC_USE_REG(r) "l" (r)
+#else
+#define __CMSIS_GCC_OUT_REG(r) "=r" (r)
+#define __CMSIS_GCC_USE_REG(r) "r" (r)
+#endif
+
+/**
+ \brief No Operation
+ \details No Operation does nothing. This instruction can be used for code alignment purposes.
+ */
+#define __NOP __builtin_arm_nop
+
+/**
+ \brief Wait For Interrupt
+ \details Wait For Interrupt is a hint instruction that suspends execution until one of a number of events occurs.
+ */
+#define __WFI __builtin_arm_wfi
+
+
+/**
+ \brief Wait For Event
+ \details Wait For Event is a hint instruction that permits the processor to enter
+ a low-power state until one of a number of events occurs.
+ */
+#define __WFE __builtin_arm_wfe
+
+
+/**
+ \brief Send Event
+ \details Send Event is a hint instruction. It causes an event to be signaled to the CPU.
+ */
+#define __SEV __builtin_arm_sev
+
+
+/**
+ \brief Instruction Synchronization Barrier
+ \details Instruction Synchronization Barrier flushes the pipeline in the processor,
+ so that all instructions following the ISB are fetched from cache or memory,
+ after the instruction has been completed.
+ */
+#define __ISB() __builtin_arm_isb(0xF);
+
+/**
+ \brief Data Synchronization Barrier
+ \details Acts as a special kind of Data Memory Barrier.
+ It completes when all explicit memory accesses before this instruction complete.
+ */
+#define __DSB() __builtin_arm_dsb(0xF);
+
+
+/**
+ \brief Data Memory Barrier
+ \details Ensures the apparent order of the explicit memory operations before
+ and after the instruction, without ensuring their completion.
+ */
+#define __DMB() __builtin_arm_dmb(0xF);
+
+
+/**
+ \brief Reverse byte order (32 bit)
+ \details Reverses the byte order in integer value.
+ \param [in] value Value to reverse
+ \return Reversed value
+ */
+#define __REV __builtin_bswap32
+
+
+/**
+ \brief Reverse byte order (16 bit)
+ \details Reverses the byte order in two unsigned short values.
+ \param [in] value Value to reverse
+ \return Reversed value
+ */
+#define __REV16 __builtin_bswap16 /* ToDo: ARMCC_V6: check if __builtin_bswap16 could be used */
+#if 0
+__attribute__((always_inline)) __STATIC_INLINE uint32_t __REV16(uint32_t value)
+{
+ uint32_t result;
+
+ __ASM volatile ("rev16 %0, %1" : __CMSIS_GCC_OUT_REG (result) : __CMSIS_GCC_USE_REG (value) );
+ return(result);
+}
+#endif
+
+
+/**
+ \brief Reverse byte order in signed short value
+ \details Reverses the byte order in a signed short value with sign extension to integer.
+ \param [in] value Value to reverse
+ \return Reversed value
+ */
+ /* ToDo: ARMCC_V6: check if __builtin_bswap16 could be used */
+__attribute__((always_inline)) __STATIC_INLINE int32_t __REVSH(int32_t value)
+{
+ int32_t result;
+
+ __ASM volatile ("revsh %0, %1" : __CMSIS_GCC_OUT_REG (result) : __CMSIS_GCC_USE_REG (value) );
+ return(result);
+}
+
+
+/**
+ \brief Rotate Right in unsigned value (32 bit)
+ \details Rotate Right (immediate) provides the value of the contents of a register rotated by a variable number of bits.
+ \param [in] op1 Value to rotate
+ \param [in] op2 Number of Bits to rotate
+ \return Rotated value
+ */
+__attribute__((always_inline)) __STATIC_INLINE uint32_t __ROR(uint32_t op1, uint32_t op2)
+{
+ return (op1 >> op2) | (op1 << (32U - op2));
+}
+
+
+/**
+ \brief Breakpoint
+ \details Causes the processor to enter Debug state.
+ Debug tools can use this to investigate system state when the instruction at a particular address is reached.
+ \param [in] value is ignored by the processor.
+ If required, a debugger can use it to store additional information about the breakpoint.
+ */
+#define __BKPT(value) __ASM volatile ("bkpt "#value)
+
+
+/**
+ \brief Reverse bit order of value
+ \details Reverses the bit order of the given value.
+ \param [in] value Value to reverse
+ \return Reversed value
+ */
+ /* ToDo: ARMCC_V6: check if __builtin_arm_rbit is supported */
+__attribute__((always_inline)) __STATIC_INLINE uint32_t __RBIT(uint32_t value)
+{
+ uint32_t result;
+
+#if ((__ARM_ARCH_7M__ == 1U) || (__ARM_ARCH_7EM__ == 1U) || (__ARM_ARCH_8M__ == 1U)) /* ToDo: ARMCC_V6: check if this is ok for cortex >=3 */
+ __ASM volatile ("rbit %0, %1" : "=r" (result) : "r" (value) );
+#else
+ int32_t s = 4 /*sizeof(v)*/ * 8 - 1; /* extra shift needed at end */
+
+ result = value; /* r will be reversed bits of v; first get LSB of v */
+ for (value >>= 1U; value; value >>= 1U)
+ {
+ result <<= 1U;
+ result |= value & 1U;
+ s--;
+ }
+ result <<= s; /* shift when v's highest bits are zero */
+#endif
+ return(result);
+}
+
+
+/**
+ \brief Count leading zeros
+ \details Counts the number of leading zeros of a data value.
+ \param [in] value Value to count the leading zeros
+ \return number of leading zeros in value
+ */
+#define __CLZ __builtin_clz
+
+
+#if ((__ARM_ARCH_7M__ == 1U) || (__ARM_ARCH_7EM__ == 1U) || (__ARM_ARCH_8M__ == 1U)) /* ToDo: ARMCC_V6: check if this is ok for cortex >=3 */
+
+/**
+ \brief LDR Exclusive (8 bit)
+ \details Executes a exclusive LDR instruction for 8 bit value.
+ \param [in] ptr Pointer to data
+ \return value of type uint8_t at (*ptr)
+ */
+#define __LDREXB (uint8_t)__builtin_arm_ldrex
+
+
+/**
+ \brief LDR Exclusive (16 bit)
+ \details Executes a exclusive LDR instruction for 16 bit values.
+ \param [in] ptr Pointer to data
+ \return value of type uint16_t at (*ptr)
+ */
+#define __LDREXH (uint16_t)__builtin_arm_ldrex
+
+
+/**
+ \brief LDR Exclusive (32 bit)
+ \details Executes a exclusive LDR instruction for 32 bit values.
+ \param [in] ptr Pointer to data
+ \return value of type uint32_t at (*ptr)
+ */
+#define __LDREXW (uint32_t)__builtin_arm_ldrex
+
+
+/**
+ \brief STR Exclusive (8 bit)
+ \details Executes a exclusive STR instruction for 8 bit values.
+ \param [in] value Value to store
+ \param [in] ptr Pointer to location
+ \return 0 Function succeeded
+ \return 1 Function failed
+ */
+#define __STREXB (uint32_t)__builtin_arm_strex
+
+
+/**
+ \brief STR Exclusive (16 bit)
+ \details Executes a exclusive STR instruction for 16 bit values.
+ \param [in] value Value to store
+ \param [in] ptr Pointer to location
+ \return 0 Function succeeded
+ \return 1 Function failed
+ */
+#define __STREXH (uint32_t)__builtin_arm_strex
+
+
+/**
+ \brief STR Exclusive (32 bit)
+ \details Executes a exclusive STR instruction for 32 bit values.
+ \param [in] value Value to store
+ \param [in] ptr Pointer to location
+ \return 0 Function succeeded
+ \return 1 Function failed
+ */
+#define __STREXW (uint32_t)__builtin_arm_strex
+
+
+/**
+ \brief Remove the exclusive lock
+ \details Removes the exclusive lock which is created by LDREX.
+ */
+#define __CLREX __builtin_arm_clrex
+
+
+/**
+ \brief Signed Saturate
+ \details Saturates a signed value.
+ \param [in] value Value to be saturated
+ \param [in] sat Bit position to saturate to (1..32)
+ \return Saturated value
+ */
+/*#define __SSAT __builtin_arm_ssat*/
+#define __SSAT(ARG1,ARG2) \
+({ \
+ int32_t __RES, __ARG1 = (ARG1); \
+ __ASM ("ssat %0, %1, %2" : "=r" (__RES) : "I" (ARG2), "r" (__ARG1) ); \
+ __RES; \
+ })
+
+
+/**
+ \brief Unsigned Saturate
+ \details Saturates an unsigned value.
+ \param [in] value Value to be saturated
+ \param [in] sat Bit position to saturate to (0..31)
+ \return Saturated value
+ */
+#define __USAT __builtin_arm_usat
+#if 0
+#define __USAT(ARG1,ARG2) \
+({ \
+ uint32_t __RES, __ARG1 = (ARG1); \
+ __ASM ("usat %0, %1, %2" : "=r" (__RES) : "I" (ARG2), "r" (__ARG1) ); \
+ __RES; \
+ })
+#endif
+
+
+/**
+ \brief Rotate Right with Extend (32 bit)
+ \details Moves each bit of a bitstring right by one bit.
+ The carry input is shifted in at the left end of the bitstring.
+ \param [in] value Value to rotate
+ \return Rotated value
+ */
+__attribute__((always_inline)) __STATIC_INLINE uint32_t __RRX(uint32_t value)
+{
+ uint32_t result;
+
+ __ASM volatile ("rrx %0, %1" : __CMSIS_GCC_OUT_REG (result) : __CMSIS_GCC_USE_REG (value) );
+ return(result);
+}
+
+
+/**
+ \brief LDRT Unprivileged (8 bit)
+ \details Executes a Unprivileged LDRT instruction for 8 bit value.
+ \param [in] ptr Pointer to data
+ \return value of type uint8_t at (*ptr)
+ */
+__attribute__((always_inline)) __STATIC_INLINE uint8_t __LDRBT(volatile uint8_t *ptr)
+{
+ uint32_t result;
+
+ __ASM volatile ("ldrbt %0, %1" : "=r" (result) : "Q" (*ptr) );
+ return ((uint8_t) result); /* Add explicit type cast here */
+}
+
+
+/**
+ \brief LDRT Unprivileged (16 bit)
+ \details Executes a Unprivileged LDRT instruction for 16 bit values.
+ \param [in] ptr Pointer to data
+ \return value of type uint16_t at (*ptr)
+ */
+__attribute__((always_inline)) __STATIC_INLINE uint16_t __LDRHT(volatile uint16_t *ptr)
+{
+ uint32_t result;
+
+ __ASM volatile ("ldrht %0, %1" : "=r" (result) : "Q" (*ptr) );
+ return ((uint16_t) result); /* Add explicit type cast here */
+}
+
+
+/**
+ \brief LDRT Unprivileged (32 bit)
+ \details Executes a Unprivileged LDRT instruction for 32 bit values.
+ \param [in] ptr Pointer to data
+ \return value of type uint32_t at (*ptr)
+ */
+__attribute__((always_inline)) __STATIC_INLINE uint32_t __LDRT(volatile uint32_t *ptr)
+{
+ uint32_t result;
+
+ __ASM volatile ("ldrt %0, %1" : "=r" (result) : "Q" (*ptr) );
+ return(result);
+}
+
+
+/**
+ \brief STRT Unprivileged (8 bit)
+ \details Executes a Unprivileged STRT instruction for 8 bit values.
+ \param [in] value Value to store
+ \param [in] ptr Pointer to location
+ */
+__attribute__((always_inline)) __STATIC_INLINE void __STRBT(uint8_t value, volatile uint8_t *ptr)
+{
+ __ASM volatile ("strbt %1, %0" : "=Q" (*ptr) : "r" ((uint32_t)value) );
+}
+
+
+/**
+ \brief STRT Unprivileged (16 bit)
+ \details Executes a Unprivileged STRT instruction for 16 bit values.
+ \param [in] value Value to store
+ \param [in] ptr Pointer to location
+ */
+__attribute__((always_inline)) __STATIC_INLINE void __STRHT(uint16_t value, volatile uint16_t *ptr)
+{
+ __ASM volatile ("strht %1, %0" : "=Q" (*ptr) : "r" ((uint32_t)value) );
+}
+
+
+/**
+ \brief STRT Unprivileged (32 bit)
+ \details Executes a Unprivileged STRT instruction for 32 bit values.
+ \param [in] value Value to store
+ \param [in] ptr Pointer to location
+ */
+__attribute__((always_inline)) __STATIC_INLINE void __STRT(uint32_t value, volatile uint32_t *ptr)
+{
+ __ASM volatile ("strt %1, %0" : "=Q" (*ptr) : "r" (value) );
+}
+
+#endif /* ((__ARM_ARCH_7M__ == 1U) || (__ARM_ARCH_7EM__ == 1U) || (__ARM_ARCH_8M__ == 1U)) */
+
+
+#if (__ARM_ARCH_8M__ == 1U)
+
+/**
+ \brief Load-Acquire (8 bit)
+ \details Executes a LDAB instruction for 8 bit value.
+ \param [in] ptr Pointer to data
+ \return value of type uint8_t at (*ptr)
+ */
+__attribute__((always_inline)) __STATIC_INLINE uint8_t __LDAB(volatile uint8_t *ptr)
+{
+ uint32_t result;
+
+ __ASM volatile ("ldab %0, %1" : "=r" (result) : "Q" (*ptr) );
+ return ((uint8_t) result);
+}
+
+
+/**
+ \brief Load-Acquire (16 bit)
+ \details Executes a LDAH instruction for 16 bit values.
+ \param [in] ptr Pointer to data
+ \return value of type uint16_t at (*ptr)
+ */
+__attribute__((always_inline)) __STATIC_INLINE uint16_t __LDAH(volatile uint16_t *ptr)
+{
+ uint32_t result;
+
+ __ASM volatile ("ldah %0, %1" : "=r" (result) : "Q" (*ptr) );
+ return ((uint16_t) result);
+}
+
+
+/**
+ \brief Load-Acquire (32 bit)
+ \details Executes a LDA instruction for 32 bit values.
+ \param [in] ptr Pointer to data
+ \return value of type uint32_t at (*ptr)
+ */
+__attribute__((always_inline)) __STATIC_INLINE uint32_t __LDA(volatile uint32_t *ptr)
+{
+ uint32_t result;
+
+ __ASM volatile ("lda %0, %1" : "=r" (result) : "Q" (*ptr) );
+ return(result);
+}
+
+
+/**
+ \brief Store-Release (8 bit)
+ \details Executes a STLB instruction for 8 bit values.
+ \param [in] value Value to store
+ \param [in] ptr Pointer to location
+ */
+__attribute__((always_inline)) __STATIC_INLINE void __STLB(uint8_t value, volatile uint8_t *ptr)
+{
+ __ASM volatile ("stlb %1, %0" : "=Q" (*ptr) : "r" ((uint32_t)value) );
+}
+
+
+/**
+ \brief Store-Release (16 bit)
+ \details Executes a STLH instruction for 16 bit values.
+ \param [in] value Value to store
+ \param [in] ptr Pointer to location
+ */
+__attribute__((always_inline)) __STATIC_INLINE void __STLH(uint16_t value, volatile uint16_t *ptr)
+{
+ __ASM volatile ("stlh %1, %0" : "=Q" (*ptr) : "r" ((uint32_t)value) );
+}
+
+
+/**
+ \brief Store-Release (32 bit)
+ \details Executes a STL instruction for 32 bit values.
+ \param [in] value Value to store
+ \param [in] ptr Pointer to location
+ */
+__attribute__((always_inline)) __STATIC_INLINE void __STL(uint32_t value, volatile uint32_t *ptr)
+{
+ __ASM volatile ("stl %1, %0" : "=Q" (*ptr) : "r" ((uint32_t)value) );
+}
+
+
+/**
+ \brief Load-Acquire Exclusive (8 bit)
+ \details Executes a LDAB exclusive instruction for 8 bit value.
+ \param [in] ptr Pointer to data
+ \return value of type uint8_t at (*ptr)
+ */
+#define __LDAEXB (uint8_t)__builtin_arm_ldaex
+
+
+/**
+ \brief Load-Acquire Exclusive (16 bit)
+ \details Executes a LDAH exclusive instruction for 16 bit values.
+ \param [in] ptr Pointer to data
+ \return value of type uint16_t at (*ptr)
+ */
+#define __LDAEXH (uint16_t)__builtin_arm_ldaex
+
+
+/**
+ \brief Load-Acquire Exclusive (32 bit)
+ \details Executes a LDA exclusive instruction for 32 bit values.
+ \param [in] ptr Pointer to data
+ \return value of type uint32_t at (*ptr)
+ */
+#define __LDAEX (uint32_t)__builtin_arm_ldaex
+
+
+/**
+ \brief Store-Release Exclusive (8 bit)
+ \details Executes a STLB exclusive instruction for 8 bit values.
+ \param [in] value Value to store
+ \param [in] ptr Pointer to location
+ \return 0 Function succeeded
+ \return 1 Function failed
+ */
+#define __STLEXB (uint32_t)__builtin_arm_stlex
+
+
+/**
+ \brief Store-Release Exclusive (16 bit)
+ \details Executes a STLH exclusive instruction for 16 bit values.
+ \param [in] value Value to store
+ \param [in] ptr Pointer to location
+ \return 0 Function succeeded
+ \return 1 Function failed
+ */
+#define __STLEXH (uint32_t)__builtin_arm_stlex
+
+
+/**
+ \brief Store-Release Exclusive (32 bit)
+ \details Executes a STL exclusive instruction for 32 bit values.
+ \param [in] value Value to store
+ \param [in] ptr Pointer to location
+ \return 0 Function succeeded
+ \return 1 Function failed
+ */
+#define __STLEX (uint32_t)__builtin_arm_stlex
+
+#endif /* (__ARM_ARCH_8M__ == 1U) */
+
+/*@}*/ /* end of group CMSIS_Core_InstructionInterface */
+
+
+/* ################### Compiler specific Intrinsics ########################### */
+/** \defgroup CMSIS_SIMD_intrinsics CMSIS SIMD Intrinsics
+ Access to dedicated SIMD instructions
+ @{
+*/
+
+#if (__ARM_FEATURE_DSP == 1U) /* ToDo: ARMCC_V6: This should be ARCH >= ARMv7-M + SIMD */
+
+__attribute__((always_inline)) __STATIC_INLINE uint32_t __SADD8(uint32_t op1, uint32_t op2)
+{
+ uint32_t result;
+
+ __ASM volatile ("sadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+ return(result);
+}
+
+__attribute__((always_inline)) __STATIC_INLINE uint32_t __QADD8(uint32_t op1, uint32_t op2)
+{
+ uint32_t result;
+
+ __ASM volatile ("qadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+ return(result);
+}
+
+__attribute__((always_inline)) __STATIC_INLINE uint32_t __SHADD8(uint32_t op1, uint32_t op2)
+{
+ uint32_t result;
+
+ __ASM volatile ("shadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+ return(result);
+}
+
+__attribute__((always_inline)) __STATIC_INLINE uint32_t __UADD8(uint32_t op1, uint32_t op2)
+{
+ uint32_t result;
+
+ __ASM volatile ("uadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+ return(result);
+}
+
+__attribute__((always_inline)) __STATIC_INLINE uint32_t __UQADD8(uint32_t op1, uint32_t op2)
+{
+ uint32_t result;
+
+ __ASM volatile ("uqadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+ return(result);
+}
+
+__attribute__((always_inline)) __STATIC_INLINE uint32_t __UHADD8(uint32_t op1, uint32_t op2)
+{
+ uint32_t result;
+
+ __ASM volatile ("uhadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+ return(result);
+}
+
+
+__attribute__((always_inline)) __STATIC_INLINE uint32_t __SSUB8(uint32_t op1, uint32_t op2)
+{
+ uint32_t result;
+
+ __ASM volatile ("ssub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+ return(result);
+}
+
+__attribute__((always_inline)) __STATIC_INLINE uint32_t __QSUB8(uint32_t op1, uint32_t op2)
+{
+ uint32_t result;
+
+ __ASM volatile ("qsub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+ return(result);
+}
+
+__attribute__((always_inline)) __STATIC_INLINE uint32_t __SHSUB8(uint32_t op1, uint32_t op2)
+{
+ uint32_t result;
+
+ __ASM volatile ("shsub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+ return(result);
+}
+
+__attribute__((always_inline)) __STATIC_INLINE uint32_t __USUB8(uint32_t op1, uint32_t op2)
+{
+ uint32_t result;
+
+ __ASM volatile ("usub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+ return(result);
+}
+
+__attribute__((always_inline)) __STATIC_INLINE uint32_t __UQSUB8(uint32_t op1, uint32_t op2)
+{
+ uint32_t result;
+
+ __ASM volatile ("uqsub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+ return(result);
+}
+
+__attribute__((always_inline)) __STATIC_INLINE uint32_t __UHSUB8(uint32_t op1, uint32_t op2)
+{
+ uint32_t result;
+
+ __ASM volatile ("uhsub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+ return(result);
+}
+
+
+__attribute__((always_inline)) __STATIC_INLINE uint32_t __SADD16(uint32_t op1, uint32_t op2)
+{
+ uint32_t result;
+
+ __ASM volatile ("sadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+ return(result);
+}
+
+__attribute__((always_inline)) __STATIC_INLINE uint32_t __QADD16(uint32_t op1, uint32_t op2)
+{
+ uint32_t result;
+
+ __ASM volatile ("qadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+ return(result);
+}
+
+__attribute__((always_inline)) __STATIC_INLINE uint32_t __SHADD16(uint32_t op1, uint32_t op2)
+{
+ uint32_t result;
+
+ __ASM volatile ("shadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+ return(result);
+}
+
+__attribute__((always_inline)) __STATIC_INLINE uint32_t __UADD16(uint32_t op1, uint32_t op2)
+{
+ uint32_t result;
+
+ __ASM volatile ("uadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+ return(result);
+}
+
+__attribute__((always_inline)) __STATIC_INLINE uint32_t __UQADD16(uint32_t op1, uint32_t op2)
+{
+ uint32_t result;
+
+ __ASM volatile ("uqadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+ return(result);
+}
+
+__attribute__((always_inline)) __STATIC_INLINE uint32_t __UHADD16(uint32_t op1, uint32_t op2)
+{
+ uint32_t result;
+
+ __ASM volatile ("uhadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+ return(result);
+}
+
+__attribute__((always_inline)) __STATIC_INLINE uint32_t __SSUB16(uint32_t op1, uint32_t op2)
+{
+ uint32_t result;
+
+ __ASM volatile ("ssub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+ return(result);
+}
+
+__attribute__((always_inline)) __STATIC_INLINE uint32_t __QSUB16(uint32_t op1, uint32_t op2)
+{
+ uint32_t result;
+
+ __ASM volatile ("qsub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+ return(result);
+}
+
+__attribute__((always_inline)) __STATIC_INLINE uint32_t __SHSUB16(uint32_t op1, uint32_t op2)
+{
+ uint32_t result;
+
+ __ASM volatile ("shsub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+ return(result);
+}
+
+__attribute__((always_inline)) __STATIC_INLINE uint32_t __USUB16(uint32_t op1, uint32_t op2)
+{
+ uint32_t result;
+
+ __ASM volatile ("usub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+ return(result);
+}
+
+__attribute__((always_inline)) __STATIC_INLINE uint32_t __UQSUB16(uint32_t op1, uint32_t op2)
+{
+ uint32_t result;
+
+ __ASM volatile ("uqsub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+ return(result);
+}
+
+__attribute__((always_inline)) __STATIC_INLINE uint32_t __UHSUB16(uint32_t op1, uint32_t op2)
+{
+ uint32_t result;
+
+ __ASM volatile ("uhsub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+ return(result);
+}
+
+__attribute__((always_inline)) __STATIC_INLINE uint32_t __SASX(uint32_t op1, uint32_t op2)
+{
+ uint32_t result;
+
+ __ASM volatile ("sasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+ return(result);
+}
+
+__attribute__((always_inline)) __STATIC_INLINE uint32_t __QASX(uint32_t op1, uint32_t op2)
+{
+ uint32_t result;
+
+ __ASM volatile ("qasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+ return(result);
+}
+
+__attribute__((always_inline)) __STATIC_INLINE uint32_t __SHASX(uint32_t op1, uint32_t op2)
+{
+ uint32_t result;
+
+ __ASM volatile ("shasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+ return(result);
+}
+
+__attribute__((always_inline)) __STATIC_INLINE uint32_t __UASX(uint32_t op1, uint32_t op2)
+{
+ uint32_t result;
+
+ __ASM volatile ("uasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+ return(result);
+}
+
+__attribute__((always_inline)) __STATIC_INLINE uint32_t __UQASX(uint32_t op1, uint32_t op2)
+{
+ uint32_t result;
+
+ __ASM volatile ("uqasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+ return(result);
+}
+
+__attribute__((always_inline)) __STATIC_INLINE uint32_t __UHASX(uint32_t op1, uint32_t op2)
+{
+ uint32_t result;
+
+ __ASM volatile ("uhasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+ return(result);
+}
+
+__attribute__((always_inline)) __STATIC_INLINE uint32_t __SSAX(uint32_t op1, uint32_t op2)
+{
+ uint32_t result;
+
+ __ASM volatile ("ssax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+ return(result);
+}
+
+__attribute__((always_inline)) __STATIC_INLINE uint32_t __QSAX(uint32_t op1, uint32_t op2)
+{
+ uint32_t result;
+
+ __ASM volatile ("qsax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+ return(result);
+}
+
+__attribute__((always_inline)) __STATIC_INLINE uint32_t __SHSAX(uint32_t op1, uint32_t op2)
+{
+ uint32_t result;
+
+ __ASM volatile ("shsax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+ return(result);
+}
+
+__attribute__((always_inline)) __STATIC_INLINE uint32_t __USAX(uint32_t op1, uint32_t op2)
+{
+ uint32_t result;
+
+ __ASM volatile ("usax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+ return(result);
+}
+
+__attribute__((always_inline)) __STATIC_INLINE uint32_t __UQSAX(uint32_t op1, uint32_t op2)
+{
+ uint32_t result;
+
+ __ASM volatile ("uqsax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+ return(result);
+}
+
+__attribute__((always_inline)) __STATIC_INLINE uint32_t __UHSAX(uint32_t op1, uint32_t op2)
+{
+ uint32_t result;
+
+ __ASM volatile ("uhsax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+ return(result);
+}
+
+__attribute__((always_inline)) __STATIC_INLINE uint32_t __USAD8(uint32_t op1, uint32_t op2)
+{
+ uint32_t result;
+
+ __ASM volatile ("usad8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+ return(result);
+}
+
+__attribute__((always_inline)) __STATIC_INLINE uint32_t __USADA8(uint32_t op1, uint32_t op2, uint32_t op3)
+{
+ uint32_t result;
+
+ __ASM volatile ("usada8 %0, %1, %2, %3" : "=r" (result) : "r" (op1), "r" (op2), "r" (op3) );
+ return(result);
+}
+
+#define __SSAT16(ARG1,ARG2) \
+({ \
+ uint32_t __RES, __ARG1 = (ARG1); \
+ __ASM ("ssat16 %0, %1, %2" : "=r" (__RES) : "I" (ARG2), "r" (__ARG1) ); \
+ __RES; \
+ })
+
+#define __USAT16(ARG1,ARG2) \
+({ \
+ uint32_t __RES, __ARG1 = (ARG1); \
+ __ASM ("usat16 %0, %1, %2" : "=r" (__RES) : "I" (ARG2), "r" (__ARG1) ); \
+ __RES; \
+ })
+
+__attribute__((always_inline)) __STATIC_INLINE uint32_t __UXTB16(uint32_t op1)
+{
+ uint32_t result;
+
+ __ASM volatile ("uxtb16 %0, %1" : "=r" (result) : "r" (op1));
+ return(result);
+}
+
+__attribute__((always_inline)) __STATIC_INLINE uint32_t __UXTAB16(uint32_t op1, uint32_t op2)
+{
+ uint32_t result;
+
+ __ASM volatile ("uxtab16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+ return(result);
+}
+
+__attribute__((always_inline)) __STATIC_INLINE uint32_t __SXTB16(uint32_t op1)
+{
+ uint32_t result;
+
+ __ASM volatile ("sxtb16 %0, %1" : "=r" (result) : "r" (op1));
+ return(result);
+}
+
+__attribute__((always_inline)) __STATIC_INLINE uint32_t __SXTAB16(uint32_t op1, uint32_t op2)
+{
+ uint32_t result;
+
+ __ASM volatile ("sxtab16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+ return(result);
+}
+
+__attribute__((always_inline)) __STATIC_INLINE uint32_t __SMUAD (uint32_t op1, uint32_t op2)
+{
+ uint32_t result;
+
+ __ASM volatile ("smuad %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+ return(result);
+}
+
+__attribute__((always_inline)) __STATIC_INLINE uint32_t __SMUADX (uint32_t op1, uint32_t op2)
+{
+ uint32_t result;
+
+ __ASM volatile ("smuadx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+ return(result);
+}
+
+__attribute__((always_inline)) __STATIC_INLINE uint32_t __SMLAD (uint32_t op1, uint32_t op2, uint32_t op3)
+{
+ uint32_t result;
+
+ __ASM volatile ("smlad %0, %1, %2, %3" : "=r" (result) : "r" (op1), "r" (op2), "r" (op3) );
+ return(result);
+}
+
+__attribute__((always_inline)) __STATIC_INLINE uint32_t __SMLADX (uint32_t op1, uint32_t op2, uint32_t op3)
+{
+ uint32_t result;
+
+ __ASM volatile ("smladx %0, %1, %2, %3" : "=r" (result) : "r" (op1), "r" (op2), "r" (op3) );
+ return(result);
+}
+
+__attribute__((always_inline)) __STATIC_INLINE uint64_t __SMLALD (uint32_t op1, uint32_t op2, uint64_t acc)
+{
+ union llreg_u{
+ uint32_t w32[2];
+ uint64_t w64;
+ } llr;
+ llr.w64 = acc;
+
+#ifndef __ARMEB__ /* Little endian */
+ __ASM volatile ("smlald %0, %1, %2, %3" : "=r" (llr.w32[0]), "=r" (llr.w32[1]): "r" (op1), "r" (op2) , "0" (llr.w32[0]), "1" (llr.w32[1]) );
+#else /* Big endian */
+ __ASM volatile ("smlald %0, %1, %2, %3" : "=r" (llr.w32[1]), "=r" (llr.w32[0]): "r" (op1), "r" (op2) , "0" (llr.w32[1]), "1" (llr.w32[0]) );
+#endif
+
+ return(llr.w64);
+}
+
+__attribute__((always_inline)) __STATIC_INLINE uint64_t __SMLALDX (uint32_t op1, uint32_t op2, uint64_t acc)
+{
+ union llreg_u{
+ uint32_t w32[2];
+ uint64_t w64;
+ } llr;
+ llr.w64 = acc;
+
+#ifndef __ARMEB__ /* Little endian */
+ __ASM volatile ("smlaldx %0, %1, %2, %3" : "=r" (llr.w32[0]), "=r" (llr.w32[1]): "r" (op1), "r" (op2) , "0" (llr.w32[0]), "1" (llr.w32[1]) );
+#else /* Big endian */
+ __ASM volatile ("smlaldx %0, %1, %2, %3" : "=r" (llr.w32[1]), "=r" (llr.w32[0]): "r" (op1), "r" (op2) , "0" (llr.w32[1]), "1" (llr.w32[0]) );
+#endif
+
+ return(llr.w64);
+}
+
+__attribute__((always_inline)) __STATIC_INLINE uint32_t __SMUSD (uint32_t op1, uint32_t op2)
+{
+ uint32_t result;
+
+ __ASM volatile ("smusd %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+ return(result);
+}
+
+__attribute__((always_inline)) __STATIC_INLINE uint32_t __SMUSDX (uint32_t op1, uint32_t op2)
+{
+ uint32_t result;
+
+ __ASM volatile ("smusdx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+ return(result);
+}
+
+__attribute__((always_inline)) __STATIC_INLINE uint32_t __SMLSD (uint32_t op1, uint32_t op2, uint32_t op3)
+{
+ uint32_t result;
+
+ __ASM volatile ("smlsd %0, %1, %2, %3" : "=r" (result) : "r" (op1), "r" (op2), "r" (op3) );
+ return(result);
+}
+
+__attribute__((always_inline)) __STATIC_INLINE uint32_t __SMLSDX (uint32_t op1, uint32_t op2, uint32_t op3)
+{
+ uint32_t result;
+
+ __ASM volatile ("smlsdx %0, %1, %2, %3" : "=r" (result) : "r" (op1), "r" (op2), "r" (op3) );
+ return(result);
+}
+
+__attribute__((always_inline)) __STATIC_INLINE uint64_t __SMLSLD (uint32_t op1, uint32_t op2, uint64_t acc)
+{
+ union llreg_u{
+ uint32_t w32[2];
+ uint64_t w64;
+ } llr;
+ llr.w64 = acc;
+
+#ifndef __ARMEB__ /* Little endian */
+ __ASM volatile ("smlsld %0, %1, %2, %3" : "=r" (llr.w32[0]), "=r" (llr.w32[1]): "r" (op1), "r" (op2) , "0" (llr.w32[0]), "1" (llr.w32[1]) );
+#else /* Big endian */
+ __ASM volatile ("smlsld %0, %1, %2, %3" : "=r" (llr.w32[1]), "=r" (llr.w32[0]): "r" (op1), "r" (op2) , "0" (llr.w32[1]), "1" (llr.w32[0]) );
+#endif
+
+ return(llr.w64);
+}
+
+__attribute__((always_inline)) __STATIC_INLINE uint64_t __SMLSLDX (uint32_t op1, uint32_t op2, uint64_t acc)
+{
+ union llreg_u{
+ uint32_t w32[2];
+ uint64_t w64;
+ } llr;
+ llr.w64 = acc;
+
+#ifndef __ARMEB__ /* Little endian */
+ __ASM volatile ("smlsldx %0, %1, %2, %3" : "=r" (llr.w32[0]), "=r" (llr.w32[1]): "r" (op1), "r" (op2) , "0" (llr.w32[0]), "1" (llr.w32[1]) );
+#else /* Big endian */
+ __ASM volatile ("smlsldx %0, %1, %2, %3" : "=r" (llr.w32[1]), "=r" (llr.w32[0]): "r" (op1), "r" (op2) , "0" (llr.w32[1]), "1" (llr.w32[0]) );
+#endif
+
+ return(llr.w64);
+}
+
+__attribute__((always_inline)) __STATIC_INLINE uint32_t __SEL (uint32_t op1, uint32_t op2)
+{
+ uint32_t result;
+
+ __ASM volatile ("sel %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+ return(result);
+}
+
+__attribute__((always_inline)) __STATIC_INLINE int32_t __QADD( int32_t op1, int32_t op2)
+{
+ int32_t result;
+
+ __ASM volatile ("qadd %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+ return(result);
+}
+
+__attribute__((always_inline)) __STATIC_INLINE int32_t __QSUB( int32_t op1, int32_t op2)
+{
+ int32_t result;
+
+ __ASM volatile ("qsub %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+ return(result);
+}
+
+#define __PKHBT(ARG1,ARG2,ARG3) \
+({ \
+ uint32_t __RES, __ARG1 = (ARG1), __ARG2 = (ARG2); \
+ __ASM ("pkhbt %0, %1, %2, lsl %3" : "=r" (__RES) : "r" (__ARG1), "r" (__ARG2), "I" (ARG3) ); \
+ __RES; \
+ })
+
+#define __PKHTB(ARG1,ARG2,ARG3) \
+({ \
+ uint32_t __RES, __ARG1 = (ARG1), __ARG2 = (ARG2); \
+ if (ARG3 == 0) \
+ __ASM ("pkhtb %0, %1, %2" : "=r" (__RES) : "r" (__ARG1), "r" (__ARG2) ); \
+ else \
+ __ASM ("pkhtb %0, %1, %2, asr %3" : "=r" (__RES) : "r" (__ARG1), "r" (__ARG2), "I" (ARG3) ); \
+ __RES; \
+ })
+
+__attribute__((always_inline)) __STATIC_INLINE uint32_t __SMMLA (int32_t op1, int32_t op2, int32_t op3)
+{
+ int32_t result;
+
+ __ASM volatile ("smmla %0, %1, %2, %3" : "=r" (result): "r" (op1), "r" (op2), "r" (op3) );
+ return(result);
+}
+
+#endif /* (__ARM_FEATURE_DSP == 1U) */
+/*@} end of group CMSIS_SIMD_intrinsics */
+
+
+#endif /* __CMSIS_ARMCC_V6_H */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/toolchain/cmsis/include/cmsis_gcc.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/toolchain/cmsis/include/cmsis_gcc.h
new file mode 100644
index 0000000..bb89fbb
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/toolchain/cmsis/include/cmsis_gcc.h
@@ -0,0 +1,1373 @@
+/**************************************************************************//**
+ * @file cmsis_gcc.h
+ * @brief CMSIS Cortex-M Core Function/Instruction Header File
+ * @version V4.30
+ * @date 20. October 2015
+ ******************************************************************************/
+/* Copyright (c) 2009 - 2015 ARM LIMITED
+
+ All rights reserved.
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are met:
+ - Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ - 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.
+ - Neither the name of ARM 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 COPYRIGHT HOLDERS AND 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.
+ ---------------------------------------------------------------------------*/
+
+
+#ifndef __CMSIS_GCC_H
+#define __CMSIS_GCC_H
+
+/* ignore some GCC warnings */
+#if defined ( __GNUC__ )
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wsign-conversion"
+#pragma GCC diagnostic ignored "-Wconversion"
+#pragma GCC diagnostic ignored "-Wunused-parameter"
+#endif
+
+
+/* ########################### Core Function Access ########################### */
+/** \ingroup CMSIS_Core_FunctionInterface
+ \defgroup CMSIS_Core_RegAccFunctions CMSIS Core Register Access Functions
+ @{
+ */
+
+/**
+ \brief Enable IRQ Interrupts
+ \details Enables IRQ interrupts by clearing the I-bit in the CPSR.
+ Can only be executed in Privileged modes.
+ */
+__attribute__( ( always_inline ) ) __STATIC_INLINE void __enable_irq(void)
+{
+ __ASM volatile ("cpsie i" : : : "memory");
+}
+
+
+/**
+ \brief Disable IRQ Interrupts
+ \details Disables IRQ interrupts by setting the I-bit in the CPSR.
+ Can only be executed in Privileged modes.
+ */
+__attribute__( ( always_inline ) ) __STATIC_INLINE void __disable_irq(void)
+{
+ __ASM volatile ("cpsid i" : : : "memory");
+}
+
+
+/**
+ \brief Get Control Register
+ \details Returns the content of the Control Register.
+ \return Control Register value
+ */
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_CONTROL(void)
+{
+ uint32_t result;
+
+ __ASM volatile ("MRS %0, control" : "=r" (result) );
+ return(result);
+}
+
+
+/**
+ \brief Set Control Register
+ \details Writes the given value to the Control Register.
+ \param [in] control Control Register value to set
+ */
+__attribute__( ( always_inline ) ) __STATIC_INLINE void __set_CONTROL(uint32_t control)
+{
+ __ASM volatile ("MSR control, %0" : : "r" (control) : "memory");
+}
+
+
+/**
+ \brief Get IPSR Register
+ \details Returns the content of the IPSR Register.
+ \return IPSR Register value
+ */
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_IPSR(void)
+{
+ uint32_t result;
+
+ __ASM volatile ("MRS %0, ipsr" : "=r" (result) );
+ return(result);
+}
+
+
+/**
+ \brief Get APSR Register
+ \details Returns the content of the APSR Register.
+ \return APSR Register value
+ */
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_APSR(void)
+{
+ uint32_t result;
+
+ __ASM volatile ("MRS %0, apsr" : "=r" (result) );
+ return(result);
+}
+
+
+/**
+ \brief Get xPSR Register
+ \details Returns the content of the xPSR Register.
+
+ \return xPSR Register value
+ */
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_xPSR(void)
+{
+ uint32_t result;
+
+ __ASM volatile ("MRS %0, xpsr" : "=r" (result) );
+ return(result);
+}
+
+
+/**
+ \brief Get Process Stack Pointer
+ \details Returns the current value of the Process Stack Pointer (PSP).
+ \return PSP Register value
+ */
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_PSP(void)
+{
+ register uint32_t result;
+
+ __ASM volatile ("MRS %0, psp\n" : "=r" (result) );
+ return(result);
+}
+
+
+/**
+ \brief Set Process Stack Pointer
+ \details Assigns the given value to the Process Stack Pointer (PSP).
+ \param [in] topOfProcStack Process Stack Pointer value to set
+ */
+__attribute__( ( always_inline ) ) __STATIC_INLINE void __set_PSP(uint32_t topOfProcStack)
+{
+ __ASM volatile ("MSR psp, %0\n" : : "r" (topOfProcStack) : "sp");
+}
+
+
+/**
+ \brief Get Main Stack Pointer
+ \details Returns the current value of the Main Stack Pointer (MSP).
+ \return MSP Register value
+ */
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_MSP(void)
+{
+ register uint32_t result;
+
+ __ASM volatile ("MRS %0, msp\n" : "=r" (result) );
+ return(result);
+}
+
+
+/**
+ \brief Set Main Stack Pointer
+ \details Assigns the given value to the Main Stack Pointer (MSP).
+
+ \param [in] topOfMainStack Main Stack Pointer value to set
+ */
+__attribute__( ( always_inline ) ) __STATIC_INLINE void __set_MSP(uint32_t topOfMainStack)
+{
+ __ASM volatile ("MSR msp, %0\n" : : "r" (topOfMainStack) : "sp");
+}
+
+
+/**
+ \brief Get Priority Mask
+ \details Returns the current state of the priority mask bit from the Priority Mask Register.
+ \return Priority Mask value
+ */
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_PRIMASK(void)
+{
+ uint32_t result;
+
+ __ASM volatile ("MRS %0, primask" : "=r" (result) );
+ return(result);
+}
+
+
+/**
+ \brief Set Priority Mask
+ \details Assigns the given value to the Priority Mask Register.
+ \param [in] priMask Priority Mask
+ */
+__attribute__( ( always_inline ) ) __STATIC_INLINE void __set_PRIMASK(uint32_t priMask)
+{
+ __ASM volatile ("MSR primask, %0" : : "r" (priMask) : "memory");
+}
+
+
+#if (__CORTEX_M >= 0x03U)
+
+/**
+ \brief Enable FIQ
+ \details Enables FIQ interrupts by clearing the F-bit in the CPSR.
+ Can only be executed in Privileged modes.
+ */
+__attribute__( ( always_inline ) ) __STATIC_INLINE void __enable_fault_irq(void)
+{
+ __ASM volatile ("cpsie f" : : : "memory");
+}
+
+
+/**
+ \brief Disable FIQ
+ \details Disables FIQ interrupts by setting the F-bit in the CPSR.
+ Can only be executed in Privileged modes.
+ */
+__attribute__( ( always_inline ) ) __STATIC_INLINE void __disable_fault_irq(void)
+{
+ __ASM volatile ("cpsid f" : : : "memory");
+}
+
+
+/**
+ \brief Get Base Priority
+ \details Returns the current value of the Base Priority register.
+ \return Base Priority register value
+ */
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_BASEPRI(void)
+{
+ uint32_t result;
+
+ __ASM volatile ("MRS %0, basepri" : "=r" (result) );
+ return(result);
+}
+
+
+/**
+ \brief Set Base Priority
+ \details Assigns the given value to the Base Priority register.
+ \param [in] basePri Base Priority value to set
+ */
+__attribute__( ( always_inline ) ) __STATIC_INLINE void __set_BASEPRI(uint32_t value)
+{
+ __ASM volatile ("MSR basepri, %0" : : "r" (value) : "memory");
+}
+
+
+/**
+ \brief Set Base Priority with condition
+ \details Assigns the given value to the Base Priority register only if BASEPRI masking is disabled,
+ or the new value increases the BASEPRI priority level.
+ \param [in] basePri Base Priority value to set
+ */
+__attribute__( ( always_inline ) ) __STATIC_INLINE void __set_BASEPRI_MAX(uint32_t value)
+{
+ __ASM volatile ("MSR basepri_max, %0" : : "r" (value) : "memory");
+}
+
+
+/**
+ \brief Get Fault Mask
+ \details Returns the current value of the Fault Mask register.
+ \return Fault Mask register value
+ */
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_FAULTMASK(void)
+{
+ uint32_t result;
+
+ __ASM volatile ("MRS %0, faultmask" : "=r" (result) );
+ return(result);
+}
+
+
+/**
+ \brief Set Fault Mask
+ \details Assigns the given value to the Fault Mask register.
+ \param [in] faultMask Fault Mask value to set
+ */
+__attribute__( ( always_inline ) ) __STATIC_INLINE void __set_FAULTMASK(uint32_t faultMask)
+{
+ __ASM volatile ("MSR faultmask, %0" : : "r" (faultMask) : "memory");
+}
+
+#endif /* (__CORTEX_M >= 0x03U) */
+
+
+#if (__CORTEX_M == 0x04U) || (__CORTEX_M == 0x07U)
+
+/**
+ \brief Get FPSCR
+ \details Returns the current value of the Floating Point Status/Control register.
+ \return Floating Point Status/Control register value
+ */
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_FPSCR(void)
+{
+#if (__FPU_PRESENT == 1U) && (__FPU_USED == 1U)
+ uint32_t result;
+
+ /* Empty asm statement works as a scheduling barrier */
+ __ASM volatile ("");
+ __ASM volatile ("VMRS %0, fpscr" : "=r" (result) );
+ __ASM volatile ("");
+ return(result);
+#else
+ return(0);
+#endif
+}
+
+
+/**
+ \brief Set FPSCR
+ \details Assigns the given value to the Floating Point Status/Control register.
+ \param [in] fpscr Floating Point Status/Control value to set
+ */
+__attribute__( ( always_inline ) ) __STATIC_INLINE void __set_FPSCR(uint32_t fpscr)
+{
+#if (__FPU_PRESENT == 1U) && (__FPU_USED == 1U)
+ /* Empty asm statement works as a scheduling barrier */
+ __ASM volatile ("");
+ __ASM volatile ("VMSR fpscr, %0" : : "r" (fpscr) : "vfpcc");
+ __ASM volatile ("");
+#endif
+}
+
+#endif /* (__CORTEX_M == 0x04U) || (__CORTEX_M == 0x07U) */
+
+
+
+/*@} end of CMSIS_Core_RegAccFunctions */
+
+
+/* ########################## Core Instruction Access ######################### */
+/** \defgroup CMSIS_Core_InstructionInterface CMSIS Core Instruction Interface
+ Access to dedicated instructions
+ @{
+*/
+
+/* Define macros for porting to both thumb1 and thumb2.
+ * For thumb1, use low register (r0-r7), specified by constraint "l"
+ * Otherwise, use general registers, specified by constraint "r" */
+#if defined (__thumb__) && !defined (__thumb2__)
+#define __CMSIS_GCC_OUT_REG(r) "=l" (r)
+#define __CMSIS_GCC_USE_REG(r) "l" (r)
+#else
+#define __CMSIS_GCC_OUT_REG(r) "=r" (r)
+#define __CMSIS_GCC_USE_REG(r) "r" (r)
+#endif
+
+/**
+ \brief No Operation
+ \details No Operation does nothing. This instruction can be used for code alignment purposes.
+ */
+__attribute__((always_inline)) __STATIC_INLINE void __NOP(void)
+{
+ __ASM volatile ("nop");
+}
+
+
+/**
+ \brief Wait For Interrupt
+ \details Wait For Interrupt is a hint instruction that suspends execution until one of a number of events occurs.
+ */
+__attribute__((always_inline)) __STATIC_INLINE void __WFI(void)
+{
+ __ASM volatile ("wfi");
+}
+
+
+/**
+ \brief Wait For Event
+ \details Wait For Event is a hint instruction that permits the processor to enter
+ a low-power state until one of a number of events occurs.
+ */
+__attribute__((always_inline)) __STATIC_INLINE void __WFE(void)
+{
+ __ASM volatile ("wfe");
+}
+
+
+/**
+ \brief Send Event
+ \details Send Event is a hint instruction. It causes an event to be signaled to the CPU.
+ */
+__attribute__((always_inline)) __STATIC_INLINE void __SEV(void)
+{
+ __ASM volatile ("sev");
+}
+
+
+/**
+ \brief Instruction Synchronization Barrier
+ \details Instruction Synchronization Barrier flushes the pipeline in the processor,
+ so that all instructions following the ISB are fetched from cache or memory,
+ after the instruction has been completed.
+ */
+__attribute__((always_inline)) __STATIC_INLINE void __ISB(void)
+{
+ __ASM volatile ("isb 0xF":::"memory");
+}
+
+
+/**
+ \brief Data Synchronization Barrier
+ \details Acts as a special kind of Data Memory Barrier.
+ It completes when all explicit memory accesses before this instruction complete.
+ */
+__attribute__((always_inline)) __STATIC_INLINE void __DSB(void)
+{
+ __ASM volatile ("dsb 0xF":::"memory");
+}
+
+
+/**
+ \brief Data Memory Barrier
+ \details Ensures the apparent order of the explicit memory operations before
+ and after the instruction, without ensuring their completion.
+ */
+__attribute__((always_inline)) __STATIC_INLINE void __DMB(void)
+{
+ __ASM volatile ("dmb 0xF":::"memory");
+}
+
+
+/**
+ \brief Reverse byte order (32 bit)
+ \details Reverses the byte order in integer value.
+ \param [in] value Value to reverse
+ \return Reversed value
+ */
+__attribute__((always_inline)) __STATIC_INLINE uint32_t __REV(uint32_t value)
+{
+#if (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 5)
+ return __builtin_bswap32(value);
+#else
+ uint32_t result;
+
+ __ASM volatile ("rev %0, %1" : __CMSIS_GCC_OUT_REG (result) : __CMSIS_GCC_USE_REG (value) );
+ return(result);
+#endif
+}
+
+
+/**
+ \brief Reverse byte order (16 bit)
+ \details Reverses the byte order in two unsigned short values.
+ \param [in] value Value to reverse
+ \return Reversed value
+ */
+__attribute__((always_inline)) __STATIC_INLINE uint32_t __REV16(uint32_t value)
+{
+ uint32_t result;
+
+ __ASM volatile ("rev16 %0, %1" : __CMSIS_GCC_OUT_REG (result) : __CMSIS_GCC_USE_REG (value) );
+ return(result);
+}
+
+
+/**
+ \brief Reverse byte order in signed short value
+ \details Reverses the byte order in a signed short value with sign extension to integer.
+ \param [in] value Value to reverse
+ \return Reversed value
+ */
+__attribute__((always_inline)) __STATIC_INLINE int32_t __REVSH(int32_t value)
+{
+#if (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8)
+ return (short)__builtin_bswap16(value);
+#else
+ int32_t result;
+
+ __ASM volatile ("revsh %0, %1" : __CMSIS_GCC_OUT_REG (result) : __CMSIS_GCC_USE_REG (value) );
+ return(result);
+#endif
+}
+
+
+/**
+ \brief Rotate Right in unsigned value (32 bit)
+ \details Rotate Right (immediate) provides the value of the contents of a register rotated by a variable number of bits.
+ \param [in] value Value to rotate
+ \param [in] value Number of Bits to rotate
+ \return Rotated value
+ */
+__attribute__((always_inline)) __STATIC_INLINE uint32_t __ROR(uint32_t op1, uint32_t op2)
+{
+ return (op1 >> op2) | (op1 << (32U - op2));
+}
+
+
+/**
+ \brief Breakpoint
+ \details Causes the processor to enter Debug state.
+ Debug tools can use this to investigate system state when the instruction at a particular address is reached.
+ \param [in] value is ignored by the processor.
+ If required, a debugger can use it to store additional information about the breakpoint.
+ */
+#define __BKPT(value) __ASM volatile ("bkpt "#value)
+
+
+/**
+ \brief Reverse bit order of value
+ \details Reverses the bit order of the given value.
+ \param [in] value Value to reverse
+ \return Reversed value
+ */
+__attribute__((always_inline)) __STATIC_INLINE uint32_t __RBIT(uint32_t value)
+{
+ uint32_t result;
+
+#if (__CORTEX_M >= 0x03U) || (__CORTEX_SC >= 300U)
+ __ASM volatile ("rbit %0, %1" : "=r" (result) : "r" (value) );
+#else
+ int32_t s = 4 /*sizeof(v)*/ * 8 - 1; /* extra shift needed at end */
+
+ result = value; /* r will be reversed bits of v; first get LSB of v */
+ for (value >>= 1U; value; value >>= 1U)
+ {
+ result <<= 1U;
+ result |= value & 1U;
+ s--;
+ }
+ result <<= s; /* shift when v's highest bits are zero */
+#endif
+ return(result);
+}
+
+
+/**
+ \brief Count leading zeros
+ \details Counts the number of leading zeros of a data value.
+ \param [in] value Value to count the leading zeros
+ \return number of leading zeros in value
+ */
+#define __CLZ __builtin_clz
+
+
+#if (__CORTEX_M >= 0x03U) || (__CORTEX_SC >= 300U)
+
+/**
+ \brief LDR Exclusive (8 bit)
+ \details Executes a exclusive LDR instruction for 8 bit value.
+ \param [in] ptr Pointer to data
+ \return value of type uint8_t at (*ptr)
+ */
+__attribute__((always_inline)) __STATIC_INLINE uint8_t __LDREXB(volatile uint8_t *addr)
+{
+ uint32_t result;
+
+#if (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8)
+ __ASM volatile ("ldrexb %0, %1" : "=r" (result) : "Q" (*addr) );
+#else
+ /* Prior to GCC 4.8, "Q" will be expanded to [rx, #0] which is not
+ accepted by assembler. So has to use following less efficient pattern.
+ */
+ __ASM volatile ("ldrexb %0, [%1]" : "=r" (result) : "r" (addr) : "memory" );
+#endif
+ return ((uint8_t) result); /* Add explicit type cast here */
+}
+
+
+/**
+ \brief LDR Exclusive (16 bit)
+ \details Executes a exclusive LDR instruction for 16 bit values.
+ \param [in] ptr Pointer to data
+ \return value of type uint16_t at (*ptr)
+ */
+__attribute__((always_inline)) __STATIC_INLINE uint16_t __LDREXH(volatile uint16_t *addr)
+{
+ uint32_t result;
+
+#if (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8)
+ __ASM volatile ("ldrexh %0, %1" : "=r" (result) : "Q" (*addr) );
+#else
+ /* Prior to GCC 4.8, "Q" will be expanded to [rx, #0] which is not
+ accepted by assembler. So has to use following less efficient pattern.
+ */
+ __ASM volatile ("ldrexh %0, [%1]" : "=r" (result) : "r" (addr) : "memory" );
+#endif
+ return ((uint16_t) result); /* Add explicit type cast here */
+}
+
+
+/**
+ \brief LDR Exclusive (32 bit)
+ \details Executes a exclusive LDR instruction for 32 bit values.
+ \param [in] ptr Pointer to data
+ \return value of type uint32_t at (*ptr)
+ */
+__attribute__((always_inline)) __STATIC_INLINE uint32_t __LDREXW(volatile uint32_t *addr)
+{
+ uint32_t result;
+
+ __ASM volatile ("ldrex %0, %1" : "=r" (result) : "Q" (*addr) );
+ return(result);
+}
+
+
+/**
+ \brief STR Exclusive (8 bit)
+ \details Executes a exclusive STR instruction for 8 bit values.
+ \param [in] value Value to store
+ \param [in] ptr Pointer to location
+ \return 0 Function succeeded
+ \return 1 Function failed
+ */
+__attribute__((always_inline)) __STATIC_INLINE uint32_t __STREXB(uint8_t value, volatile uint8_t *addr)
+{
+ uint32_t result;
+
+ __ASM volatile ("strexb %0, %2, %1" : "=&r" (result), "=Q" (*addr) : "r" ((uint32_t)value) );
+ return(result);
+}
+
+
+/**
+ \brief STR Exclusive (16 bit)
+ \details Executes a exclusive STR instruction for 16 bit values.
+ \param [in] value Value to store
+ \param [in] ptr Pointer to location
+ \return 0 Function succeeded
+ \return 1 Function failed
+ */
+__attribute__((always_inline)) __STATIC_INLINE uint32_t __STREXH(uint16_t value, volatile uint16_t *addr)
+{
+ uint32_t result;
+
+ __ASM volatile ("strexh %0, %2, %1" : "=&r" (result), "=Q" (*addr) : "r" ((uint32_t)value) );
+ return(result);
+}
+
+
+/**
+ \brief STR Exclusive (32 bit)
+ \details Executes a exclusive STR instruction for 32 bit values.
+ \param [in] value Value to store
+ \param [in] ptr Pointer to location
+ \return 0 Function succeeded
+ \return 1 Function failed
+ */
+__attribute__((always_inline)) __STATIC_INLINE uint32_t __STREXW(uint32_t value, volatile uint32_t *addr)
+{
+ uint32_t result;
+
+ __ASM volatile ("strex %0, %2, %1" : "=&r" (result), "=Q" (*addr) : "r" (value) );
+ return(result);
+}
+
+
+/**
+ \brief Remove the exclusive lock
+ \details Removes the exclusive lock which is created by LDREX.
+ */
+__attribute__((always_inline)) __STATIC_INLINE void __CLREX(void)
+{
+ __ASM volatile ("clrex" ::: "memory");
+}
+
+
+/**
+ \brief Signed Saturate
+ \details Saturates a signed value.
+ \param [in] value Value to be saturated
+ \param [in] sat Bit position to saturate to (1..32)
+ \return Saturated value
+ */
+#define __SSAT(ARG1,ARG2) \
+({ \
+ uint32_t __RES, __ARG1 = (ARG1); \
+ __ASM ("ssat %0, %1, %2" : "=r" (__RES) : "I" (ARG2), "r" (__ARG1) ); \
+ __RES; \
+ })
+
+
+/**
+ \brief Unsigned Saturate
+ \details Saturates an unsigned value.
+ \param [in] value Value to be saturated
+ \param [in] sat Bit position to saturate to (0..31)
+ \return Saturated value
+ */
+#define __USAT(ARG1,ARG2) \
+({ \
+ uint32_t __RES, __ARG1 = (ARG1); \
+ __ASM ("usat %0, %1, %2" : "=r" (__RES) : "I" (ARG2), "r" (__ARG1) ); \
+ __RES; \
+ })
+
+
+/**
+ \brief Rotate Right with Extend (32 bit)
+ \details Moves each bit of a bitstring right by one bit.
+ The carry input is shifted in at the left end of the bitstring.
+ \param [in] value Value to rotate
+ \return Rotated value
+ */
+__attribute__((always_inline)) __STATIC_INLINE uint32_t __RRX(uint32_t value)
+{
+ uint32_t result;
+
+ __ASM volatile ("rrx %0, %1" : __CMSIS_GCC_OUT_REG (result) : __CMSIS_GCC_USE_REG (value) );
+ return(result);
+}
+
+
+/**
+ \brief LDRT Unprivileged (8 bit)
+ \details Executes a Unprivileged LDRT instruction for 8 bit value.
+ \param [in] ptr Pointer to data
+ \return value of type uint8_t at (*ptr)
+ */
+__attribute__((always_inline)) __STATIC_INLINE uint8_t __LDRBT(volatile uint8_t *addr)
+{
+ uint32_t result;
+
+#if (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8)
+ __ASM volatile ("ldrbt %0, %1" : "=r" (result) : "Q" (*addr) );
+#else
+ /* Prior to GCC 4.8, "Q" will be expanded to [rx, #0] which is not
+ accepted by assembler. So has to use following less efficient pattern.
+ */
+ __ASM volatile ("ldrbt %0, [%1]" : "=r" (result) : "r" (addr) : "memory" );
+#endif
+ return ((uint8_t) result); /* Add explicit type cast here */
+}
+
+
+/**
+ \brief LDRT Unprivileged (16 bit)
+ \details Executes a Unprivileged LDRT instruction for 16 bit values.
+ \param [in] ptr Pointer to data
+ \return value of type uint16_t at (*ptr)
+ */
+__attribute__((always_inline)) __STATIC_INLINE uint16_t __LDRHT(volatile uint16_t *addr)
+{
+ uint32_t result;
+
+#if (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8)
+ __ASM volatile ("ldrht %0, %1" : "=r" (result) : "Q" (*addr) );
+#else
+ /* Prior to GCC 4.8, "Q" will be expanded to [rx, #0] which is not
+ accepted by assembler. So has to use following less efficient pattern.
+ */
+ __ASM volatile ("ldrht %0, [%1]" : "=r" (result) : "r" (addr) : "memory" );
+#endif
+ return ((uint16_t) result); /* Add explicit type cast here */
+}
+
+
+/**
+ \brief LDRT Unprivileged (32 bit)
+ \details Executes a Unprivileged LDRT instruction for 32 bit values.
+ \param [in] ptr Pointer to data
+ \return value of type uint32_t at (*ptr)
+ */
+__attribute__((always_inline)) __STATIC_INLINE uint32_t __LDRT(volatile uint32_t *addr)
+{
+ uint32_t result;
+
+ __ASM volatile ("ldrt %0, %1" : "=r" (result) : "Q" (*addr) );
+ return(result);
+}
+
+
+/**
+ \brief STRT Unprivileged (8 bit)
+ \details Executes a Unprivileged STRT instruction for 8 bit values.
+ \param [in] value Value to store
+ \param [in] ptr Pointer to location
+ */
+__attribute__((always_inline)) __STATIC_INLINE void __STRBT(uint8_t value, volatile uint8_t *addr)
+{
+ __ASM volatile ("strbt %1, %0" : "=Q" (*addr) : "r" ((uint32_t)value) );
+}
+
+
+/**
+ \brief STRT Unprivileged (16 bit)
+ \details Executes a Unprivileged STRT instruction for 16 bit values.
+ \param [in] value Value to store
+ \param [in] ptr Pointer to location
+ */
+__attribute__((always_inline)) __STATIC_INLINE void __STRHT(uint16_t value, volatile uint16_t *addr)
+{
+ __ASM volatile ("strht %1, %0" : "=Q" (*addr) : "r" ((uint32_t)value) );
+}
+
+
+/**
+ \brief STRT Unprivileged (32 bit)
+ \details Executes a Unprivileged STRT instruction for 32 bit values.
+ \param [in] value Value to store
+ \param [in] ptr Pointer to location
+ */
+__attribute__((always_inline)) __STATIC_INLINE void __STRT(uint32_t value, volatile uint32_t *addr)
+{
+ __ASM volatile ("strt %1, %0" : "=Q" (*addr) : "r" (value) );
+}
+
+#endif /* (__CORTEX_M >= 0x03U) || (__CORTEX_SC >= 300U) */
+
+/*@}*/ /* end of group CMSIS_Core_InstructionInterface */
+
+
+/* ################### Compiler specific Intrinsics ########################### */
+/** \defgroup CMSIS_SIMD_intrinsics CMSIS SIMD Intrinsics
+ Access to dedicated SIMD instructions
+ @{
+*/
+
+#if (__CORTEX_M >= 0x04U) /* only for Cortex-M4 and above */
+
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SADD8(uint32_t op1, uint32_t op2)
+{
+ uint32_t result;
+
+ __ASM volatile ("sadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+ return(result);
+}
+
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __QADD8(uint32_t op1, uint32_t op2)
+{
+ uint32_t result;
+
+ __ASM volatile ("qadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+ return(result);
+}
+
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SHADD8(uint32_t op1, uint32_t op2)
+{
+ uint32_t result;
+
+ __ASM volatile ("shadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+ return(result);
+}
+
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UADD8(uint32_t op1, uint32_t op2)
+{
+ uint32_t result;
+
+ __ASM volatile ("uadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+ return(result);
+}
+
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UQADD8(uint32_t op1, uint32_t op2)
+{
+ uint32_t result;
+
+ __ASM volatile ("uqadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+ return(result);
+}
+
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UHADD8(uint32_t op1, uint32_t op2)
+{
+ uint32_t result;
+
+ __ASM volatile ("uhadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+ return(result);
+}
+
+
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SSUB8(uint32_t op1, uint32_t op2)
+{
+ uint32_t result;
+
+ __ASM volatile ("ssub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+ return(result);
+}
+
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __QSUB8(uint32_t op1, uint32_t op2)
+{
+ uint32_t result;
+
+ __ASM volatile ("qsub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+ return(result);
+}
+
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SHSUB8(uint32_t op1, uint32_t op2)
+{
+ uint32_t result;
+
+ __ASM volatile ("shsub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+ return(result);
+}
+
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __USUB8(uint32_t op1, uint32_t op2)
+{
+ uint32_t result;
+
+ __ASM volatile ("usub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+ return(result);
+}
+
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UQSUB8(uint32_t op1, uint32_t op2)
+{
+ uint32_t result;
+
+ __ASM volatile ("uqsub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+ return(result);
+}
+
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UHSUB8(uint32_t op1, uint32_t op2)
+{
+ uint32_t result;
+
+ __ASM volatile ("uhsub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+ return(result);
+}
+
+
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SADD16(uint32_t op1, uint32_t op2)
+{
+ uint32_t result;
+
+ __ASM volatile ("sadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+ return(result);
+}
+
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __QADD16(uint32_t op1, uint32_t op2)
+{
+ uint32_t result;
+
+ __ASM volatile ("qadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+ return(result);
+}
+
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SHADD16(uint32_t op1, uint32_t op2)
+{
+ uint32_t result;
+
+ __ASM volatile ("shadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+ return(result);
+}
+
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UADD16(uint32_t op1, uint32_t op2)
+{
+ uint32_t result;
+
+ __ASM volatile ("uadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+ return(result);
+}
+
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UQADD16(uint32_t op1, uint32_t op2)
+{
+ uint32_t result;
+
+ __ASM volatile ("uqadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+ return(result);
+}
+
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UHADD16(uint32_t op1, uint32_t op2)
+{
+ uint32_t result;
+
+ __ASM volatile ("uhadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+ return(result);
+}
+
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SSUB16(uint32_t op1, uint32_t op2)
+{
+ uint32_t result;
+
+ __ASM volatile ("ssub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+ return(result);
+}
+
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __QSUB16(uint32_t op1, uint32_t op2)
+{
+ uint32_t result;
+
+ __ASM volatile ("qsub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+ return(result);
+}
+
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SHSUB16(uint32_t op1, uint32_t op2)
+{
+ uint32_t result;
+
+ __ASM volatile ("shsub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+ return(result);
+}
+
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __USUB16(uint32_t op1, uint32_t op2)
+{
+ uint32_t result;
+
+ __ASM volatile ("usub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+ return(result);
+}
+
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UQSUB16(uint32_t op1, uint32_t op2)
+{
+ uint32_t result;
+
+ __ASM volatile ("uqsub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+ return(result);
+}
+
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UHSUB16(uint32_t op1, uint32_t op2)
+{
+ uint32_t result;
+
+ __ASM volatile ("uhsub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+ return(result);
+}
+
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SASX(uint32_t op1, uint32_t op2)
+{
+ uint32_t result;
+
+ __ASM volatile ("sasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+ return(result);
+}
+
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __QASX(uint32_t op1, uint32_t op2)
+{
+ uint32_t result;
+
+ __ASM volatile ("qasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+ return(result);
+}
+
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SHASX(uint32_t op1, uint32_t op2)
+{
+ uint32_t result;
+
+ __ASM volatile ("shasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+ return(result);
+}
+
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UASX(uint32_t op1, uint32_t op2)
+{
+ uint32_t result;
+
+ __ASM volatile ("uasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+ return(result);
+}
+
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UQASX(uint32_t op1, uint32_t op2)
+{
+ uint32_t result;
+
+ __ASM volatile ("uqasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+ return(result);
+}
+
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UHASX(uint32_t op1, uint32_t op2)
+{
+ uint32_t result;
+
+ __ASM volatile ("uhasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+ return(result);
+}
+
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SSAX(uint32_t op1, uint32_t op2)
+{
+ uint32_t result;
+
+ __ASM volatile ("ssax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+ return(result);
+}
+
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __QSAX(uint32_t op1, uint32_t op2)
+{
+ uint32_t result;
+
+ __ASM volatile ("qsax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+ return(result);
+}
+
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SHSAX(uint32_t op1, uint32_t op2)
+{
+ uint32_t result;
+
+ __ASM volatile ("shsax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+ return(result);
+}
+
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __USAX(uint32_t op1, uint32_t op2)
+{
+ uint32_t result;
+
+ __ASM volatile ("usax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+ return(result);
+}
+
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UQSAX(uint32_t op1, uint32_t op2)
+{
+ uint32_t result;
+
+ __ASM volatile ("uqsax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+ return(result);
+}
+
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UHSAX(uint32_t op1, uint32_t op2)
+{
+ uint32_t result;
+
+ __ASM volatile ("uhsax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+ return(result);
+}
+
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __USAD8(uint32_t op1, uint32_t op2)
+{
+ uint32_t result;
+
+ __ASM volatile ("usad8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+ return(result);
+}
+
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __USADA8(uint32_t op1, uint32_t op2, uint32_t op3)
+{
+ uint32_t result;
+
+ __ASM volatile ("usada8 %0, %1, %2, %3" : "=r" (result) : "r" (op1), "r" (op2), "r" (op3) );
+ return(result);
+}
+
+#define __SSAT16(ARG1,ARG2) \
+({ \
+ int32_t __RES, __ARG1 = (ARG1); \
+ __ASM ("ssat16 %0, %1, %2" : "=r" (__RES) : "I" (ARG2), "r" (__ARG1) ); \
+ __RES; \
+ })
+
+#define __USAT16(ARG1,ARG2) \
+({ \
+ uint32_t __RES, __ARG1 = (ARG1); \
+ __ASM ("usat16 %0, %1, %2" : "=r" (__RES) : "I" (ARG2), "r" (__ARG1) ); \
+ __RES; \
+ })
+
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UXTB16(uint32_t op1)
+{
+ uint32_t result;
+
+ __ASM volatile ("uxtb16 %0, %1" : "=r" (result) : "r" (op1));
+ return(result);
+}
+
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UXTAB16(uint32_t op1, uint32_t op2)
+{
+ uint32_t result;
+
+ __ASM volatile ("uxtab16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+ return(result);
+}
+
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SXTB16(uint32_t op1)
+{
+ uint32_t result;
+
+ __ASM volatile ("sxtb16 %0, %1" : "=r" (result) : "r" (op1));
+ return(result);
+}
+
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SXTAB16(uint32_t op1, uint32_t op2)
+{
+ uint32_t result;
+
+ __ASM volatile ("sxtab16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+ return(result);
+}
+
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SMUAD (uint32_t op1, uint32_t op2)
+{
+ uint32_t result;
+
+ __ASM volatile ("smuad %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+ return(result);
+}
+
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SMUADX (uint32_t op1, uint32_t op2)
+{
+ uint32_t result;
+
+ __ASM volatile ("smuadx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+ return(result);
+}
+
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SMLAD (uint32_t op1, uint32_t op2, uint32_t op3)
+{
+ uint32_t result;
+
+ __ASM volatile ("smlad %0, %1, %2, %3" : "=r" (result) : "r" (op1), "r" (op2), "r" (op3) );
+ return(result);
+}
+
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SMLADX (uint32_t op1, uint32_t op2, uint32_t op3)
+{
+ uint32_t result;
+
+ __ASM volatile ("smladx %0, %1, %2, %3" : "=r" (result) : "r" (op1), "r" (op2), "r" (op3) );
+ return(result);
+}
+
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint64_t __SMLALD (uint32_t op1, uint32_t op2, uint64_t acc)
+{
+ union llreg_u{
+ uint32_t w32[2];
+ uint64_t w64;
+ } llr;
+ llr.w64 = acc;
+
+#ifndef __ARMEB__ /* Little endian */
+ __ASM volatile ("smlald %0, %1, %2, %3" : "=r" (llr.w32[0]), "=r" (llr.w32[1]): "r" (op1), "r" (op2) , "0" (llr.w32[0]), "1" (llr.w32[1]) );
+#else /* Big endian */
+ __ASM volatile ("smlald %0, %1, %2, %3" : "=r" (llr.w32[1]), "=r" (llr.w32[0]): "r" (op1), "r" (op2) , "0" (llr.w32[1]), "1" (llr.w32[0]) );
+#endif
+
+ return(llr.w64);
+}
+
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint64_t __SMLALDX (uint32_t op1, uint32_t op2, uint64_t acc)
+{
+ union llreg_u{
+ uint32_t w32[2];
+ uint64_t w64;
+ } llr;
+ llr.w64 = acc;
+
+#ifndef __ARMEB__ /* Little endian */
+ __ASM volatile ("smlaldx %0, %1, %2, %3" : "=r" (llr.w32[0]), "=r" (llr.w32[1]): "r" (op1), "r" (op2) , "0" (llr.w32[0]), "1" (llr.w32[1]) );
+#else /* Big endian */
+ __ASM volatile ("smlaldx %0, %1, %2, %3" : "=r" (llr.w32[1]), "=r" (llr.w32[0]): "r" (op1), "r" (op2) , "0" (llr.w32[1]), "1" (llr.w32[0]) );
+#endif
+
+ return(llr.w64);
+}
+
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SMUSD (uint32_t op1, uint32_t op2)
+{
+ uint32_t result;
+
+ __ASM volatile ("smusd %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+ return(result);
+}
+
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SMUSDX (uint32_t op1, uint32_t op2)
+{
+ uint32_t result;
+
+ __ASM volatile ("smusdx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+ return(result);
+}
+
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SMLSD (uint32_t op1, uint32_t op2, uint32_t op3)
+{
+ uint32_t result;
+
+ __ASM volatile ("smlsd %0, %1, %2, %3" : "=r" (result) : "r" (op1), "r" (op2), "r" (op3) );
+ return(result);
+}
+
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SMLSDX (uint32_t op1, uint32_t op2, uint32_t op3)
+{
+ uint32_t result;
+
+ __ASM volatile ("smlsdx %0, %1, %2, %3" : "=r" (result) : "r" (op1), "r" (op2), "r" (op3) );
+ return(result);
+}
+
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint64_t __SMLSLD (uint32_t op1, uint32_t op2, uint64_t acc)
+{
+ union llreg_u{
+ uint32_t w32[2];
+ uint64_t w64;
+ } llr;
+ llr.w64 = acc;
+
+#ifndef __ARMEB__ /* Little endian */
+ __ASM volatile ("smlsld %0, %1, %2, %3" : "=r" (llr.w32[0]), "=r" (llr.w32[1]): "r" (op1), "r" (op2) , "0" (llr.w32[0]), "1" (llr.w32[1]) );
+#else /* Big endian */
+ __ASM volatile ("smlsld %0, %1, %2, %3" : "=r" (llr.w32[1]), "=r" (llr.w32[0]): "r" (op1), "r" (op2) , "0" (llr.w32[1]), "1" (llr.w32[0]) );
+#endif
+
+ return(llr.w64);
+}
+
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint64_t __SMLSLDX (uint32_t op1, uint32_t op2, uint64_t acc)
+{
+ union llreg_u{
+ uint32_t w32[2];
+ uint64_t w64;
+ } llr;
+ llr.w64 = acc;
+
+#ifndef __ARMEB__ /* Little endian */
+ __ASM volatile ("smlsldx %0, %1, %2, %3" : "=r" (llr.w32[0]), "=r" (llr.w32[1]): "r" (op1), "r" (op2) , "0" (llr.w32[0]), "1" (llr.w32[1]) );
+#else /* Big endian */
+ __ASM volatile ("smlsldx %0, %1, %2, %3" : "=r" (llr.w32[1]), "=r" (llr.w32[0]): "r" (op1), "r" (op2) , "0" (llr.w32[1]), "1" (llr.w32[0]) );
+#endif
+
+ return(llr.w64);
+}
+
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SEL (uint32_t op1, uint32_t op2)
+{
+ uint32_t result;
+
+ __ASM volatile ("sel %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+ return(result);
+}
+
+__attribute__( ( always_inline ) ) __STATIC_INLINE int32_t __QADD( int32_t op1, int32_t op2)
+{
+ int32_t result;
+
+ __ASM volatile ("qadd %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+ return(result);
+}
+
+__attribute__( ( always_inline ) ) __STATIC_INLINE int32_t __QSUB( int32_t op1, int32_t op2)
+{
+ int32_t result;
+
+ __ASM volatile ("qsub %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
+ return(result);
+}
+
+#define __PKHBT(ARG1,ARG2,ARG3) \
+({ \
+ uint32_t __RES, __ARG1 = (ARG1), __ARG2 = (ARG2); \
+ __ASM ("pkhbt %0, %1, %2, lsl %3" : "=r" (__RES) : "r" (__ARG1), "r" (__ARG2), "I" (ARG3) ); \
+ __RES; \
+ })
+
+#define __PKHTB(ARG1,ARG2,ARG3) \
+({ \
+ uint32_t __RES, __ARG1 = (ARG1), __ARG2 = (ARG2); \
+ if (ARG3 == 0) \
+ __ASM ("pkhtb %0, %1, %2" : "=r" (__RES) : "r" (__ARG1), "r" (__ARG2) ); \
+ else \
+ __ASM ("pkhtb %0, %1, %2, asr %3" : "=r" (__RES) : "r" (__ARG1), "r" (__ARG2), "I" (ARG3) ); \
+ __RES; \
+ })
+
+__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SMMLA (int32_t op1, int32_t op2, int32_t op3)
+{
+ int32_t result;
+
+ __ASM volatile ("smmla %0, %1, %2, %3" : "=r" (result): "r" (op1), "r" (op2), "r" (op3) );
+ return(result);
+}
+
+#endif /* (__CORTEX_M >= 0x04) */
+/*@} end of group CMSIS_SIMD_intrinsics */
+
+
+#if defined ( __GNUC__ )
+#pragma GCC diagnostic pop
+#endif
+
+#endif /* __CMSIS_GCC_H */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/toolchain/cmsis/include/core_cm0.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/toolchain/cmsis/include/core_cm0.h
new file mode 100644
index 0000000..b43ce55
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/toolchain/cmsis/include/core_cm0.h
@@ -0,0 +1,798 @@
+/**************************************************************************//**
+ * @file core_cm0.h
+ * @brief CMSIS Cortex-M0 Core Peripheral Access Layer Header File
+ * @version V4.30
+ * @date 20. October 2015
+ ******************************************************************************/
+/* Copyright (c) 2009 - 2015 ARM LIMITED
+
+ All rights reserved.
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are met:
+ - Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ - 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.
+ - Neither the name of ARM 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 COPYRIGHT HOLDERS AND 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.
+ ---------------------------------------------------------------------------*/
+
+
+#if defined ( __ICCARM__ )
+ #pragma system_include /* treat file as system include file for MISRA check */
+#elif defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050)
+ #pragma clang system_header /* treat file as system include file */
+#endif
+
+#ifndef __CORE_CM0_H_GENERIC
+#define __CORE_CM0_H_GENERIC
+
+#include <stdint.h>
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+/**
+ \page CMSIS_MISRA_Exceptions MISRA-C:2004 Compliance Exceptions
+ CMSIS violates the following MISRA-C:2004 rules:
+
+ \li Required Rule 8.5, object/function definition in header file.<br>
+ Function definitions in header files are used to allow 'inlining'.
+
+ \li Required Rule 18.4, declaration of union type or object of union type: '{...}'.<br>
+ Unions are used for effective representation of core registers.
+
+ \li Advisory Rule 19.7, Function-like macro defined.<br>
+ Function-like macros are used to allow more efficient code.
+ */
+
+
+/*******************************************************************************
+ * CMSIS definitions
+ ******************************************************************************/
+/**
+ \ingroup Cortex_M0
+ @{
+ */
+
+/* CMSIS CM0 definitions */
+#define __CM0_CMSIS_VERSION_MAIN (0x04U) /*!< [31:16] CMSIS HAL main version */
+#define __CM0_CMSIS_VERSION_SUB (0x1EU) /*!< [15:0] CMSIS HAL sub version */
+#define __CM0_CMSIS_VERSION ((__CM0_CMSIS_VERSION_MAIN << 16U) | \
+ __CM0_CMSIS_VERSION_SUB ) /*!< CMSIS HAL version number */
+
+#define __CORTEX_M (0x00U) /*!< Cortex-M Core */
+
+
+#if defined ( __CC_ARM )
+ #define __ASM __asm /*!< asm keyword for ARM Compiler */
+ #define __INLINE __inline /*!< inline keyword for ARM Compiler */
+ #define __STATIC_INLINE static __inline
+
+#elif defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050)
+ #define __ASM __asm /*!< asm keyword for ARM Compiler */
+ #define __INLINE __inline /*!< inline keyword for ARM Compiler */
+ #define __STATIC_INLINE static __inline
+
+#elif defined ( __GNUC__ )
+ #define __ASM __asm /*!< asm keyword for GNU Compiler */
+ #define __INLINE inline /*!< inline keyword for GNU Compiler */
+ #define __STATIC_INLINE static inline
+
+#elif defined ( __ICCARM__ )
+ #define __ASM __asm /*!< asm keyword for IAR Compiler */
+ #define __INLINE inline /*!< inline keyword for IAR Compiler. Only available in High optimization mode! */
+ #define __STATIC_INLINE static inline
+
+#elif defined ( __TMS470__ )
+ #define __ASM __asm /*!< asm keyword for TI CCS Compiler */
+ #define __STATIC_INLINE static inline
+
+#elif defined ( __TASKING__ )
+ #define __ASM __asm /*!< asm keyword for TASKING Compiler */
+ #define __INLINE inline /*!< inline keyword for TASKING Compiler */
+ #define __STATIC_INLINE static inline
+
+#elif defined ( __CSMC__ )
+ #define __packed
+ #define __ASM _asm /*!< asm keyword for COSMIC Compiler */
+ #define __INLINE inline /*!< inline keyword for COSMIC Compiler. Use -pc99 on compile line */
+ #define __STATIC_INLINE static inline
+
+#else
+ #error Unknown compiler
+#endif
+
+/** __FPU_USED indicates whether an FPU is used or not.
+ This core does not support an FPU at all
+*/
+#define __FPU_USED 0U
+
+#if defined ( __CC_ARM )
+ #if defined __TARGET_FPU_VFP
+ #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
+ #endif
+
+#elif defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050)
+ #if defined __ARM_PCS_VFP
+ #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
+ #endif
+
+#elif defined ( __GNUC__ )
+ #if defined (__VFP_FP__) && !defined(__SOFTFP__)
+ #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
+ #endif
+
+#elif defined ( __ICCARM__ )
+ #if defined __ARMVFP__
+ #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
+ #endif
+
+#elif defined ( __TMS470__ )
+ #if defined __TI_VFP_SUPPORT__
+ #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
+ #endif
+
+#elif defined ( __TASKING__ )
+ #if defined __FPU_VFP__
+ #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
+ #endif
+
+#elif defined ( __CSMC__ )
+ #if ( __CSMC__ & 0x400U)
+ #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
+ #endif
+
+#endif
+
+#include "core_cmInstr.h" /* Core Instruction Access */
+#include "core_cmFunc.h" /* Core Function Access */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __CORE_CM0_H_GENERIC */
+
+#ifndef __CMSIS_GENERIC
+
+#ifndef __CORE_CM0_H_DEPENDANT
+#define __CORE_CM0_H_DEPENDANT
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+/* check device defines and use defaults */
+#if defined __CHECK_DEVICE_DEFINES
+ #ifndef __CM0_REV
+ #define __CM0_REV 0x0000U
+ #warning "__CM0_REV not defined in device header file; using default!"
+ #endif
+
+ #ifndef __NVIC_PRIO_BITS
+ #define __NVIC_PRIO_BITS 2U
+ #warning "__NVIC_PRIO_BITS not defined in device header file; using default!"
+ #endif
+
+ #ifndef __Vendor_SysTickConfig
+ #define __Vendor_SysTickConfig 0U
+ #warning "__Vendor_SysTickConfig not defined in device header file; using default!"
+ #endif
+#endif
+
+/* IO definitions (access restrictions to peripheral registers) */
+/**
+ \defgroup CMSIS_glob_defs CMSIS Global Defines
+
+ <strong>IO Type Qualifiers</strong> are used
+ \li to specify the access to peripheral variables.
+ \li for automatic generation of peripheral register debug information.
+*/
+#ifdef __cplusplus
+ #define __I volatile /*!< Defines 'read only' permissions */
+#else
+ #define __I volatile const /*!< Defines 'read only' permissions */
+#endif
+#define __O volatile /*!< Defines 'write only' permissions */
+#define __IO volatile /*!< Defines 'read / write' permissions */
+
+/* following defines should be used for structure members */
+#define __IM volatile const /*! Defines 'read only' structure member permissions */
+#define __OM volatile /*! Defines 'write only' structure member permissions */
+#define __IOM volatile /*! Defines 'read / write' structure member permissions */
+
+/*@} end of group Cortex_M0 */
+
+
+
+/*******************************************************************************
+ * Register Abstraction
+ Core Register contain:
+ - Core Register
+ - Core NVIC Register
+ - Core SCB Register
+ - Core SysTick Register
+ ******************************************************************************/
+/**
+ \defgroup CMSIS_core_register Defines and Type Definitions
+ \brief Type definitions and defines for Cortex-M processor based devices.
+*/
+
+/**
+ \ingroup CMSIS_core_register
+ \defgroup CMSIS_CORE Status and Control Registers
+ \brief Core Register type definitions.
+ @{
+ */
+
+/**
+ \brief Union type to access the Application Program Status Register (APSR).
+ */
+typedef union
+{
+ struct
+ {
+ uint32_t _reserved0:28; /*!< bit: 0..27 Reserved */
+ uint32_t V:1; /*!< bit: 28 Overflow condition code flag */
+ uint32_t C:1; /*!< bit: 29 Carry condition code flag */
+ uint32_t Z:1; /*!< bit: 30 Zero condition code flag */
+ uint32_t N:1; /*!< bit: 31 Negative condition code flag */
+ } b; /*!< Structure used for bit access */
+ uint32_t w; /*!< Type used for word access */
+} APSR_Type;
+
+/* APSR Register Definitions */
+#define APSR_N_Pos 31U /*!< APSR: N Position */
+#define APSR_N_Msk (1UL << APSR_N_Pos) /*!< APSR: N Mask */
+
+#define APSR_Z_Pos 30U /*!< APSR: Z Position */
+#define APSR_Z_Msk (1UL << APSR_Z_Pos) /*!< APSR: Z Mask */
+
+#define APSR_C_Pos 29U /*!< APSR: C Position */
+#define APSR_C_Msk (1UL << APSR_C_Pos) /*!< APSR: C Mask */
+
+#define APSR_V_Pos 28U /*!< APSR: V Position */
+#define APSR_V_Msk (1UL << APSR_V_Pos) /*!< APSR: V Mask */
+
+
+/**
+ \brief Union type to access the Interrupt Program Status Register (IPSR).
+ */
+typedef union
+{
+ struct
+ {
+ uint32_t ISR:9; /*!< bit: 0.. 8 Exception number */
+ uint32_t _reserved0:23; /*!< bit: 9..31 Reserved */
+ } b; /*!< Structure used for bit access */
+ uint32_t w; /*!< Type used for word access */
+} IPSR_Type;
+
+/* IPSR Register Definitions */
+#define IPSR_ISR_Pos 0U /*!< IPSR: ISR Position */
+#define IPSR_ISR_Msk (0x1FFUL /*<< IPSR_ISR_Pos*/) /*!< IPSR: ISR Mask */
+
+
+/**
+ \brief Union type to access the Special-Purpose Program Status Registers (xPSR).
+ */
+typedef union
+{
+ struct
+ {
+ uint32_t ISR:9; /*!< bit: 0.. 8 Exception number */
+ uint32_t _reserved0:15; /*!< bit: 9..23 Reserved */
+ uint32_t T:1; /*!< bit: 24 Thumb bit (read 0) */
+ uint32_t _reserved1:3; /*!< bit: 25..27 Reserved */
+ uint32_t V:1; /*!< bit: 28 Overflow condition code flag */
+ uint32_t C:1; /*!< bit: 29 Carry condition code flag */
+ uint32_t Z:1; /*!< bit: 30 Zero condition code flag */
+ uint32_t N:1; /*!< bit: 31 Negative condition code flag */
+ } b; /*!< Structure used for bit access */
+ uint32_t w; /*!< Type used for word access */
+} xPSR_Type;
+
+/* xPSR Register Definitions */
+#define xPSR_N_Pos 31U /*!< xPSR: N Position */
+#define xPSR_N_Msk (1UL << xPSR_N_Pos) /*!< xPSR: N Mask */
+
+#define xPSR_Z_Pos 30U /*!< xPSR: Z Position */
+#define xPSR_Z_Msk (1UL << xPSR_Z_Pos) /*!< xPSR: Z Mask */
+
+#define xPSR_C_Pos 29U /*!< xPSR: C Position */
+#define xPSR_C_Msk (1UL << xPSR_C_Pos) /*!< xPSR: C Mask */
+
+#define xPSR_V_Pos 28U /*!< xPSR: V Position */
+#define xPSR_V_Msk (1UL << xPSR_V_Pos) /*!< xPSR: V Mask */
+
+#define xPSR_T_Pos 24U /*!< xPSR: T Position */
+#define xPSR_T_Msk (1UL << xPSR_T_Pos) /*!< xPSR: T Mask */
+
+#define xPSR_ISR_Pos 0U /*!< xPSR: ISR Position */
+#define xPSR_ISR_Msk (0x1FFUL /*<< xPSR_ISR_Pos*/) /*!< xPSR: ISR Mask */
+
+
+/**
+ \brief Union type to access the Control Registers (CONTROL).
+ */
+typedef union
+{
+ struct
+ {
+ uint32_t _reserved0:1; /*!< bit: 0 Reserved */
+ uint32_t SPSEL:1; /*!< bit: 1 Stack to be used */
+ uint32_t _reserved1:30; /*!< bit: 2..31 Reserved */
+ } b; /*!< Structure used for bit access */
+ uint32_t w; /*!< Type used for word access */
+} CONTROL_Type;
+
+/* CONTROL Register Definitions */
+#define CONTROL_SPSEL_Pos 1U /*!< CONTROL: SPSEL Position */
+#define CONTROL_SPSEL_Msk (1UL << CONTROL_SPSEL_Pos) /*!< CONTROL: SPSEL Mask */
+
+/*@} end of group CMSIS_CORE */
+
+
+/**
+ \ingroup CMSIS_core_register
+ \defgroup CMSIS_NVIC Nested Vectored Interrupt Controller (NVIC)
+ \brief Type definitions for the NVIC Registers
+ @{
+ */
+
+/**
+ \brief Structure type to access the Nested Vectored Interrupt Controller (NVIC).
+ */
+typedef struct
+{
+ __IOM uint32_t ISER[1U]; /*!< Offset: 0x000 (R/W) Interrupt Set Enable Register */
+ uint32_t RESERVED0[31U];
+ __IOM uint32_t ICER[1U]; /*!< Offset: 0x080 (R/W) Interrupt Clear Enable Register */
+ uint32_t RSERVED1[31U];
+ __IOM uint32_t ISPR[1U]; /*!< Offset: 0x100 (R/W) Interrupt Set Pending Register */
+ uint32_t RESERVED2[31U];
+ __IOM uint32_t ICPR[1U]; /*!< Offset: 0x180 (R/W) Interrupt Clear Pending Register */
+ uint32_t RESERVED3[31U];
+ uint32_t RESERVED4[64U];
+ __IOM uint32_t IP[8U]; /*!< Offset: 0x300 (R/W) Interrupt Priority Register */
+} NVIC_Type;
+
+/*@} end of group CMSIS_NVIC */
+
+
+/**
+ \ingroup CMSIS_core_register
+ \defgroup CMSIS_SCB System Control Block (SCB)
+ \brief Type definitions for the System Control Block Registers
+ @{
+ */
+
+/**
+ \brief Structure type to access the System Control Block (SCB).
+ */
+typedef struct
+{
+ __IM uint32_t CPUID; /*!< Offset: 0x000 (R/ ) CPUID Base Register */
+ __IOM uint32_t ICSR; /*!< Offset: 0x004 (R/W) Interrupt Control and State Register */
+ uint32_t RESERVED0;
+ __IOM uint32_t AIRCR; /*!< Offset: 0x00C (R/W) Application Interrupt and Reset Control Register */
+ __IOM uint32_t SCR; /*!< Offset: 0x010 (R/W) System Control Register */
+ __IOM uint32_t CCR; /*!< Offset: 0x014 (R/W) Configuration Control Register */
+ uint32_t RESERVED1;
+ __IOM uint32_t SHP[2U]; /*!< Offset: 0x01C (R/W) System Handlers Priority Registers. [0] is RESERVED */
+ __IOM uint32_t SHCSR; /*!< Offset: 0x024 (R/W) System Handler Control and State Register */
+} SCB_Type;
+
+/* SCB CPUID Register Definitions */
+#define SCB_CPUID_IMPLEMENTER_Pos 24U /*!< SCB CPUID: IMPLEMENTER Position */
+#define SCB_CPUID_IMPLEMENTER_Msk (0xFFUL << SCB_CPUID_IMPLEMENTER_Pos) /*!< SCB CPUID: IMPLEMENTER Mask */
+
+#define SCB_CPUID_VARIANT_Pos 20U /*!< SCB CPUID: VARIANT Position */
+#define SCB_CPUID_VARIANT_Msk (0xFUL << SCB_CPUID_VARIANT_Pos) /*!< SCB CPUID: VARIANT Mask */
+
+#define SCB_CPUID_ARCHITECTURE_Pos 16U /*!< SCB CPUID: ARCHITECTURE Position */
+#define SCB_CPUID_ARCHITECTURE_Msk (0xFUL << SCB_CPUID_ARCHITECTURE_Pos) /*!< SCB CPUID: ARCHITECTURE Mask */
+
+#define SCB_CPUID_PARTNO_Pos 4U /*!< SCB CPUID: PARTNO Position */
+#define SCB_CPUID_PARTNO_Msk (0xFFFUL << SCB_CPUID_PARTNO_Pos) /*!< SCB CPUID: PARTNO Mask */
+
+#define SCB_CPUID_REVISION_Pos 0U /*!< SCB CPUID: REVISION Position */
+#define SCB_CPUID_REVISION_Msk (0xFUL /*<< SCB_CPUID_REVISION_Pos*/) /*!< SCB CPUID: REVISION Mask */
+
+/* SCB Interrupt Control State Register Definitions */
+#define SCB_ICSR_NMIPENDSET_Pos 31U /*!< SCB ICSR: NMIPENDSET Position */
+#define SCB_ICSR_NMIPENDSET_Msk (1UL << SCB_ICSR_NMIPENDSET_Pos) /*!< SCB ICSR: NMIPENDSET Mask */
+
+#define SCB_ICSR_PENDSVSET_Pos 28U /*!< SCB ICSR: PENDSVSET Position */
+#define SCB_ICSR_PENDSVSET_Msk (1UL << SCB_ICSR_PENDSVSET_Pos) /*!< SCB ICSR: PENDSVSET Mask */
+
+#define SCB_ICSR_PENDSVCLR_Pos 27U /*!< SCB ICSR: PENDSVCLR Position */
+#define SCB_ICSR_PENDSVCLR_Msk (1UL << SCB_ICSR_PENDSVCLR_Pos) /*!< SCB ICSR: PENDSVCLR Mask */
+
+#define SCB_ICSR_PENDSTSET_Pos 26U /*!< SCB ICSR: PENDSTSET Position */
+#define SCB_ICSR_PENDSTSET_Msk (1UL << SCB_ICSR_PENDSTSET_Pos) /*!< SCB ICSR: PENDSTSET Mask */
+
+#define SCB_ICSR_PENDSTCLR_Pos 25U /*!< SCB ICSR: PENDSTCLR Position */
+#define SCB_ICSR_PENDSTCLR_Msk (1UL << SCB_ICSR_PENDSTCLR_Pos) /*!< SCB ICSR: PENDSTCLR Mask */
+
+#define SCB_ICSR_ISRPREEMPT_Pos 23U /*!< SCB ICSR: ISRPREEMPT Position */
+#define SCB_ICSR_ISRPREEMPT_Msk (1UL << SCB_ICSR_ISRPREEMPT_Pos) /*!< SCB ICSR: ISRPREEMPT Mask */
+
+#define SCB_ICSR_ISRPENDING_Pos 22U /*!< SCB ICSR: ISRPENDING Position */
+#define SCB_ICSR_ISRPENDING_Msk (1UL << SCB_ICSR_ISRPENDING_Pos) /*!< SCB ICSR: ISRPENDING Mask */
+
+#define SCB_ICSR_VECTPENDING_Pos 12U /*!< SCB ICSR: VECTPENDING Position */
+#define SCB_ICSR_VECTPENDING_Msk (0x1FFUL << SCB_ICSR_VECTPENDING_Pos) /*!< SCB ICSR: VECTPENDING Mask */
+
+#define SCB_ICSR_VECTACTIVE_Pos 0U /*!< SCB ICSR: VECTACTIVE Position */
+#define SCB_ICSR_VECTACTIVE_Msk (0x1FFUL /*<< SCB_ICSR_VECTACTIVE_Pos*/) /*!< SCB ICSR: VECTACTIVE Mask */
+
+/* SCB Application Interrupt and Reset Control Register Definitions */
+#define SCB_AIRCR_VECTKEY_Pos 16U /*!< SCB AIRCR: VECTKEY Position */
+#define SCB_AIRCR_VECTKEY_Msk (0xFFFFUL << SCB_AIRCR_VECTKEY_Pos) /*!< SCB AIRCR: VECTKEY Mask */
+
+#define SCB_AIRCR_VECTKEYSTAT_Pos 16U /*!< SCB AIRCR: VECTKEYSTAT Position */
+#define SCB_AIRCR_VECTKEYSTAT_Msk (0xFFFFUL << SCB_AIRCR_VECTKEYSTAT_Pos) /*!< SCB AIRCR: VECTKEYSTAT Mask */
+
+#define SCB_AIRCR_ENDIANESS_Pos 15U /*!< SCB AIRCR: ENDIANESS Position */
+#define SCB_AIRCR_ENDIANESS_Msk (1UL << SCB_AIRCR_ENDIANESS_Pos) /*!< SCB AIRCR: ENDIANESS Mask */
+
+#define SCB_AIRCR_SYSRESETREQ_Pos 2U /*!< SCB AIRCR: SYSRESETREQ Position */
+#define SCB_AIRCR_SYSRESETREQ_Msk (1UL << SCB_AIRCR_SYSRESETREQ_Pos) /*!< SCB AIRCR: SYSRESETREQ Mask */
+
+#define SCB_AIRCR_VECTCLRACTIVE_Pos 1U /*!< SCB AIRCR: VECTCLRACTIVE Position */
+#define SCB_AIRCR_VECTCLRACTIVE_Msk (1UL << SCB_AIRCR_VECTCLRACTIVE_Pos) /*!< SCB AIRCR: VECTCLRACTIVE Mask */
+
+/* SCB System Control Register Definitions */
+#define SCB_SCR_SEVONPEND_Pos 4U /*!< SCB SCR: SEVONPEND Position */
+#define SCB_SCR_SEVONPEND_Msk (1UL << SCB_SCR_SEVONPEND_Pos) /*!< SCB SCR: SEVONPEND Mask */
+
+#define SCB_SCR_SLEEPDEEP_Pos 2U /*!< SCB SCR: SLEEPDEEP Position */
+#define SCB_SCR_SLEEPDEEP_Msk (1UL << SCB_SCR_SLEEPDEEP_Pos) /*!< SCB SCR: SLEEPDEEP Mask */
+
+#define SCB_SCR_SLEEPONEXIT_Pos 1U /*!< SCB SCR: SLEEPONEXIT Position */
+#define SCB_SCR_SLEEPONEXIT_Msk (1UL << SCB_SCR_SLEEPONEXIT_Pos) /*!< SCB SCR: SLEEPONEXIT Mask */
+
+/* SCB Configuration Control Register Definitions */
+#define SCB_CCR_STKALIGN_Pos 9U /*!< SCB CCR: STKALIGN Position */
+#define SCB_CCR_STKALIGN_Msk (1UL << SCB_CCR_STKALIGN_Pos) /*!< SCB CCR: STKALIGN Mask */
+
+#define SCB_CCR_UNALIGN_TRP_Pos 3U /*!< SCB CCR: UNALIGN_TRP Position */
+#define SCB_CCR_UNALIGN_TRP_Msk (1UL << SCB_CCR_UNALIGN_TRP_Pos) /*!< SCB CCR: UNALIGN_TRP Mask */
+
+/* SCB System Handler Control and State Register Definitions */
+#define SCB_SHCSR_SVCALLPENDED_Pos 15U /*!< SCB SHCSR: SVCALLPENDED Position */
+#define SCB_SHCSR_SVCALLPENDED_Msk (1UL << SCB_SHCSR_SVCALLPENDED_Pos) /*!< SCB SHCSR: SVCALLPENDED Mask */
+
+/*@} end of group CMSIS_SCB */
+
+
+/**
+ \ingroup CMSIS_core_register
+ \defgroup CMSIS_SysTick System Tick Timer (SysTick)
+ \brief Type definitions for the System Timer Registers.
+ @{
+ */
+
+/**
+ \brief Structure type to access the System Timer (SysTick).
+ */
+typedef struct
+{
+ __IOM uint32_t CTRL; /*!< Offset: 0x000 (R/W) SysTick Control and Status Register */
+ __IOM uint32_t LOAD; /*!< Offset: 0x004 (R/W) SysTick Reload Value Register */
+ __IOM uint32_t VAL; /*!< Offset: 0x008 (R/W) SysTick Current Value Register */
+ __IM uint32_t CALIB; /*!< Offset: 0x00C (R/ ) SysTick Calibration Register */
+} SysTick_Type;
+
+/* SysTick Control / Status Register Definitions */
+#define SysTick_CTRL_COUNTFLAG_Pos 16U /*!< SysTick CTRL: COUNTFLAG Position */
+#define SysTick_CTRL_COUNTFLAG_Msk (1UL << SysTick_CTRL_COUNTFLAG_Pos) /*!< SysTick CTRL: COUNTFLAG Mask */
+
+#define SysTick_CTRL_CLKSOURCE_Pos 2U /*!< SysTick CTRL: CLKSOURCE Position */
+#define SysTick_CTRL_CLKSOURCE_Msk (1UL << SysTick_CTRL_CLKSOURCE_Pos) /*!< SysTick CTRL: CLKSOURCE Mask */
+
+#define SysTick_CTRL_TICKINT_Pos 1U /*!< SysTick CTRL: TICKINT Position */
+#define SysTick_CTRL_TICKINT_Msk (1UL << SysTick_CTRL_TICKINT_Pos) /*!< SysTick CTRL: TICKINT Mask */
+
+#define SysTick_CTRL_ENABLE_Pos 0U /*!< SysTick CTRL: ENABLE Position */
+#define SysTick_CTRL_ENABLE_Msk (1UL /*<< SysTick_CTRL_ENABLE_Pos*/) /*!< SysTick CTRL: ENABLE Mask */
+
+/* SysTick Reload Register Definitions */
+#define SysTick_LOAD_RELOAD_Pos 0U /*!< SysTick LOAD: RELOAD Position */
+#define SysTick_LOAD_RELOAD_Msk (0xFFFFFFUL /*<< SysTick_LOAD_RELOAD_Pos*/) /*!< SysTick LOAD: RELOAD Mask */
+
+/* SysTick Current Register Definitions */
+#define SysTick_VAL_CURRENT_Pos 0U /*!< SysTick VAL: CURRENT Position */
+#define SysTick_VAL_CURRENT_Msk (0xFFFFFFUL /*<< SysTick_VAL_CURRENT_Pos*/) /*!< SysTick VAL: CURRENT Mask */
+
+/* SysTick Calibration Register Definitions */
+#define SysTick_CALIB_NOREF_Pos 31U /*!< SysTick CALIB: NOREF Position */
+#define SysTick_CALIB_NOREF_Msk (1UL << SysTick_CALIB_NOREF_Pos) /*!< SysTick CALIB: NOREF Mask */
+
+#define SysTick_CALIB_SKEW_Pos 30U /*!< SysTick CALIB: SKEW Position */
+#define SysTick_CALIB_SKEW_Msk (1UL << SysTick_CALIB_SKEW_Pos) /*!< SysTick CALIB: SKEW Mask */
+
+#define SysTick_CALIB_TENMS_Pos 0U /*!< SysTick CALIB: TENMS Position */
+#define SysTick_CALIB_TENMS_Msk (0xFFFFFFUL /*<< SysTick_CALIB_TENMS_Pos*/) /*!< SysTick CALIB: TENMS Mask */
+
+/*@} end of group CMSIS_SysTick */
+
+
+/**
+ \ingroup CMSIS_core_register
+ \defgroup CMSIS_CoreDebug Core Debug Registers (CoreDebug)
+ \brief Cortex-M0 Core Debug Registers (DCB registers, SHCSR, and DFSR) are only accessible over DAP and not via processor.
+ Therefore they are not covered by the Cortex-M0 header file.
+ @{
+ */
+/*@} end of group CMSIS_CoreDebug */
+
+
+/**
+ \ingroup CMSIS_core_register
+ \defgroup CMSIS_core_bitfield Core register bit field macros
+ \brief Macros for use with bit field definitions (xxx_Pos, xxx_Msk).
+ @{
+ */
+
+/**
+ \brief Mask and shift a bit field value for use in a register bit range.
+ \param[in] field Name of the register bit field.
+ \param[in] value Value of the bit field.
+ \return Masked and shifted value.
+*/
+#define _VAL2FLD(field, value) ((value << field ## _Pos) & field ## _Msk)
+
+/**
+ \brief Mask and shift a register value to extract a bit filed value.
+ \param[in] field Name of the register bit field.
+ \param[in] value Value of register.
+ \return Masked and shifted bit field value.
+*/
+#define _FLD2VAL(field, value) ((value & field ## _Msk) >> field ## _Pos)
+
+/*@} end of group CMSIS_core_bitfield */
+
+
+/**
+ \ingroup CMSIS_core_register
+ \defgroup CMSIS_core_base Core Definitions
+ \brief Definitions for base addresses, unions, and structures.
+ @{
+ */
+
+/* Memory mapping of Cortex-M0 Hardware */
+#define SCS_BASE (0xE000E000UL) /*!< System Control Space Base Address */
+#define SysTick_BASE (SCS_BASE + 0x0010UL) /*!< SysTick Base Address */
+#define NVIC_BASE (SCS_BASE + 0x0100UL) /*!< NVIC Base Address */
+#define SCB_BASE (SCS_BASE + 0x0D00UL) /*!< System Control Block Base Address */
+
+#define SCB ((SCB_Type *) SCB_BASE ) /*!< SCB configuration struct */
+#define SysTick ((SysTick_Type *) SysTick_BASE ) /*!< SysTick configuration struct */
+#define NVIC ((NVIC_Type *) NVIC_BASE ) /*!< NVIC configuration struct */
+
+
+/*@} */
+
+
+
+/*******************************************************************************
+ * Hardware Abstraction Layer
+ Core Function Interface contains:
+ - Core NVIC Functions
+ - Core SysTick Functions
+ - Core Register Access Functions
+ ******************************************************************************/
+/**
+ \defgroup CMSIS_Core_FunctionInterface Functions and Instructions Reference
+*/
+
+
+
+/* ########################## NVIC functions #################################### */
+/**
+ \ingroup CMSIS_Core_FunctionInterface
+ \defgroup CMSIS_Core_NVICFunctions NVIC Functions
+ \brief Functions that manage interrupts and exceptions via the NVIC.
+ @{
+ */
+
+/* Interrupt Priorities are WORD accessible only under ARMv6M */
+/* The following MACROS handle generation of the register offset and byte masks */
+#define _BIT_SHIFT(IRQn) ( ((((uint32_t)(int32_t)(IRQn)) ) & 0x03UL) * 8UL)
+#define _SHP_IDX(IRQn) ( (((((uint32_t)(int32_t)(IRQn)) & 0x0FUL)-8UL) >> 2UL) )
+#define _IP_IDX(IRQn) ( (((uint32_t)(int32_t)(IRQn)) >> 2UL) )
+
+
+/**
+ \brief Enable External Interrupt
+ \details Enables a device-specific interrupt in the NVIC interrupt controller.
+ \param [in] IRQn External interrupt number. Value cannot be negative.
+ */
+__STATIC_INLINE void NVIC_EnableIRQ(IRQn_Type IRQn)
+{
+ NVIC->ISER[0U] = (uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL));
+}
+
+
+/**
+ \brief Disable External Interrupt
+ \details Disables a device-specific interrupt in the NVIC interrupt controller.
+ \param [in] IRQn External interrupt number. Value cannot be negative.
+ */
+__STATIC_INLINE void NVIC_DisableIRQ(IRQn_Type IRQn)
+{
+ NVIC->ICER[0U] = (uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL));
+}
+
+
+/**
+ \brief Get Pending Interrupt
+ \details Reads the pending register in the NVIC and returns the pending bit for the specified interrupt.
+ \param [in] IRQn Interrupt number.
+ \return 0 Interrupt status is not pending.
+ \return 1 Interrupt status is pending.
+ */
+__STATIC_INLINE uint32_t NVIC_GetPendingIRQ(IRQn_Type IRQn)
+{
+ return((uint32_t)(((NVIC->ISPR[0U] & (1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL));
+}
+
+
+/**
+ \brief Set Pending Interrupt
+ \details Sets the pending bit of an external interrupt.
+ \param [in] IRQn Interrupt number. Value cannot be negative.
+ */
+__STATIC_INLINE void NVIC_SetPendingIRQ(IRQn_Type IRQn)
+{
+ NVIC->ISPR[0U] = (uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL));
+}
+
+
+/**
+ \brief Clear Pending Interrupt
+ \details Clears the pending bit of an external interrupt.
+ \param [in] IRQn External interrupt number. Value cannot be negative.
+ */
+__STATIC_INLINE void NVIC_ClearPendingIRQ(IRQn_Type IRQn)
+{
+ NVIC->ICPR[0U] = (uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL));
+}
+
+
+/**
+ \brief Set Interrupt Priority
+ \details Sets the priority of an interrupt.
+ \note The priority cannot be set for every core interrupt.
+ \param [in] IRQn Interrupt number.
+ \param [in] priority Priority to set.
+ */
+__STATIC_INLINE void NVIC_SetPriority(IRQn_Type IRQn, uint32_t priority)
+{
+ if ((int32_t)(IRQn) < 0)
+ {
+ SCB->SHP[_SHP_IDX(IRQn)] = ((uint32_t)(SCB->SHP[_SHP_IDX(IRQn)] & ~(0xFFUL << _BIT_SHIFT(IRQn))) |
+ (((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL) << _BIT_SHIFT(IRQn)));
+ }
+ else
+ {
+ NVIC->IP[_IP_IDX(IRQn)] = ((uint32_t)(NVIC->IP[_IP_IDX(IRQn)] & ~(0xFFUL << _BIT_SHIFT(IRQn))) |
+ (((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL) << _BIT_SHIFT(IRQn)));
+ }
+}
+
+
+/**
+ \brief Get Interrupt Priority
+ \details Reads the priority of an interrupt.
+ The interrupt number can be positive to specify an external (device specific) interrupt,
+ or negative to specify an internal (core) interrupt.
+ \param [in] IRQn Interrupt number.
+ \return Interrupt Priority.
+ Value is aligned automatically to the implemented priority bits of the microcontroller.
+ */
+__STATIC_INLINE uint32_t NVIC_GetPriority(IRQn_Type IRQn)
+{
+
+ if ((int32_t)(IRQn) < 0)
+ {
+ return((uint32_t)(((SCB->SHP[_SHP_IDX(IRQn)] >> _BIT_SHIFT(IRQn) ) & (uint32_t)0xFFUL) >> (8U - __NVIC_PRIO_BITS)));
+ }
+ else
+ {
+ return((uint32_t)(((NVIC->IP[ _IP_IDX(IRQn)] >> _BIT_SHIFT(IRQn) ) & (uint32_t)0xFFUL) >> (8U - __NVIC_PRIO_BITS)));
+ }
+}
+
+
+/**
+ \brief System Reset
+ \details Initiates a system reset request to reset the MCU.
+ */
+__STATIC_INLINE void NVIC_SystemReset(void)
+{
+ __DSB(); /* Ensure all outstanding memory accesses included
+ buffered write are completed before reset */
+ SCB->AIRCR = ((0x5FAUL << SCB_AIRCR_VECTKEY_Pos) |
+ SCB_AIRCR_SYSRESETREQ_Msk);
+ __DSB(); /* Ensure completion of memory access */
+
+ for (;;) /* wait until reset */
+ {
+ __NOP();
+ }
+}
+
+/*@} end of CMSIS_Core_NVICFunctions */
+
+
+
+/* ################################## SysTick function ############################################ */
+/**
+ \ingroup CMSIS_Core_FunctionInterface
+ \defgroup CMSIS_Core_SysTickFunctions SysTick Functions
+ \brief Functions that configure the System.
+ @{
+ */
+
+#if (__Vendor_SysTickConfig == 0U)
+
+/**
+ \brief System Tick Configuration
+ \details Initializes the System Timer and its interrupt, and starts the System Tick Timer.
+ Counter is in free running mode to generate periodic interrupts.
+ \param [in] ticks Number of ticks between two interrupts.
+ \return 0 Function succeeded.
+ \return 1 Function failed.
+ \note When the variable <b>__Vendor_SysTickConfig</b> is set to 1, then the
+ function <b>SysTick_Config</b> is not included. In this case, the file <b><i>device</i>.h</b>
+ must contain a vendor-specific implementation of this function.
+ */
+__STATIC_INLINE uint32_t SysTick_Config(uint32_t ticks)
+{
+ if ((ticks - 1UL) > SysTick_LOAD_RELOAD_Msk)
+ {
+ return (1UL); /* Reload value impossible */
+ }
+
+ SysTick->LOAD = (uint32_t)(ticks - 1UL); /* set reload register */
+ NVIC_SetPriority (SysTick_IRQn, (1UL << __NVIC_PRIO_BITS) - 1UL); /* set Priority for Systick Interrupt */
+ SysTick->VAL = 0UL; /* Load the SysTick Counter Value */
+ SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk |
+ SysTick_CTRL_TICKINT_Msk |
+ SysTick_CTRL_ENABLE_Msk; /* Enable SysTick IRQ and SysTick Timer */
+ return (0UL); /* Function successful */
+}
+
+#endif
+
+/*@} end of CMSIS_Core_SysTickFunctions */
+
+
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __CORE_CM0_H_DEPENDANT */
+
+#endif /* __CMSIS_GENERIC */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/toolchain/cmsis/include/core_cm0plus.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/toolchain/cmsis/include/core_cm0plus.h
new file mode 100644
index 0000000..89e2285
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/toolchain/cmsis/include/core_cm0plus.h
@@ -0,0 +1,914 @@
+/**************************************************************************//**
+ * @file core_cm0plus.h
+ * @brief CMSIS Cortex-M0+ Core Peripheral Access Layer Header File
+ * @version V4.30
+ * @date 20. October 2015
+ ******************************************************************************/
+/* Copyright (c) 2009 - 2015 ARM LIMITED
+
+ All rights reserved.
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are met:
+ - Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ - 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.
+ - Neither the name of ARM 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 COPYRIGHT HOLDERS AND 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.
+ ---------------------------------------------------------------------------*/
+
+
+#if defined ( __ICCARM__ )
+ #pragma system_include /* treat file as system include file for MISRA check */
+#elif defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050)
+ #pragma clang system_header /* treat file as system include file */
+#endif
+
+#ifndef __CORE_CM0PLUS_H_GENERIC
+#define __CORE_CM0PLUS_H_GENERIC
+
+#include <stdint.h>
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+/**
+ \page CMSIS_MISRA_Exceptions MISRA-C:2004 Compliance Exceptions
+ CMSIS violates the following MISRA-C:2004 rules:
+
+ \li Required Rule 8.5, object/function definition in header file.<br>
+ Function definitions in header files are used to allow 'inlining'.
+
+ \li Required Rule 18.4, declaration of union type or object of union type: '{...}'.<br>
+ Unions are used for effective representation of core registers.
+
+ \li Advisory Rule 19.7, Function-like macro defined.<br>
+ Function-like macros are used to allow more efficient code.
+ */
+
+
+/*******************************************************************************
+ * CMSIS definitions
+ ******************************************************************************/
+/**
+ \ingroup Cortex-M0+
+ @{
+ */
+
+/* CMSIS CM0+ definitions */
+#define __CM0PLUS_CMSIS_VERSION_MAIN (0x04U) /*!< [31:16] CMSIS HAL main version */
+#define __CM0PLUS_CMSIS_VERSION_SUB (0x1EU) /*!< [15:0] CMSIS HAL sub version */
+#define __CM0PLUS_CMSIS_VERSION ((__CM0PLUS_CMSIS_VERSION_MAIN << 16U) | \
+ __CM0PLUS_CMSIS_VERSION_SUB ) /*!< CMSIS HAL version number */
+
+#define __CORTEX_M (0x00U) /*!< Cortex-M Core */
+
+
+#if defined ( __CC_ARM )
+ #define __ASM __asm /*!< asm keyword for ARM Compiler */
+ #define __INLINE __inline /*!< inline keyword for ARM Compiler */
+ #define __STATIC_INLINE static __inline
+
+#elif defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050)
+ #define __ASM __asm /*!< asm keyword for ARM Compiler */
+ #define __INLINE __inline /*!< inline keyword for ARM Compiler */
+ #define __STATIC_INLINE static __inline
+
+#elif defined ( __GNUC__ )
+ #define __ASM __asm /*!< asm keyword for GNU Compiler */
+ #define __INLINE inline /*!< inline keyword for GNU Compiler */
+ #define __STATIC_INLINE static inline
+
+#elif defined ( __ICCARM__ )
+ #define __ASM __asm /*!< asm keyword for IAR Compiler */
+ #define __INLINE inline /*!< inline keyword for IAR Compiler. Only available in High optimization mode! */
+ #define __STATIC_INLINE static inline
+
+#elif defined ( __TMS470__ )
+ #define __ASM __asm /*!< asm keyword for TI CCS Compiler */
+ #define __STATIC_INLINE static inline
+
+#elif defined ( __TASKING__ )
+ #define __ASM __asm /*!< asm keyword for TASKING Compiler */
+ #define __INLINE inline /*!< inline keyword for TASKING Compiler */
+ #define __STATIC_INLINE static inline
+
+#elif defined ( __CSMC__ )
+ #define __packed
+ #define __ASM _asm /*!< asm keyword for COSMIC Compiler */
+ #define __INLINE inline /*!< inline keyword for COSMIC Compiler. Use -pc99 on compile line */
+ #define __STATIC_INLINE static inline
+
+#else
+ #error Unknown compiler
+#endif
+
+/** __FPU_USED indicates whether an FPU is used or not.
+ This core does not support an FPU at all
+*/
+#define __FPU_USED 0U
+
+#if defined ( __CC_ARM )
+ #if defined __TARGET_FPU_VFP
+ #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
+ #endif
+
+#elif defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050)
+ #if defined __ARM_PCS_VFP
+ #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
+ #endif
+
+#elif defined ( __GNUC__ )
+ #if defined (__VFP_FP__) && !defined(__SOFTFP__)
+ #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
+ #endif
+
+#elif defined ( __ICCARM__ )
+ #if defined __ARMVFP__
+ #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
+ #endif
+
+#elif defined ( __TMS470__ )
+ #if defined __TI_VFP_SUPPORT__
+ #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
+ #endif
+
+#elif defined ( __TASKING__ )
+ #if defined __FPU_VFP__
+ #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
+ #endif
+
+#elif defined ( __CSMC__ )
+ #if ( __CSMC__ & 0x400U)
+ #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
+ #endif
+
+#endif
+
+#include "core_cmInstr.h" /* Core Instruction Access */
+#include "core_cmFunc.h" /* Core Function Access */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __CORE_CM0PLUS_H_GENERIC */
+
+#ifndef __CMSIS_GENERIC
+
+#ifndef __CORE_CM0PLUS_H_DEPENDANT
+#define __CORE_CM0PLUS_H_DEPENDANT
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+/* check device defines and use defaults */
+#if defined __CHECK_DEVICE_DEFINES
+ #ifndef __CM0PLUS_REV
+ #define __CM0PLUS_REV 0x0000U
+ #warning "__CM0PLUS_REV not defined in device header file; using default!"
+ #endif
+
+ #ifndef __MPU_PRESENT
+ #define __MPU_PRESENT 0U
+ #warning "__MPU_PRESENT not defined in device header file; using default!"
+ #endif
+
+ #ifndef __VTOR_PRESENT
+ #define __VTOR_PRESENT 0U
+ #warning "__VTOR_PRESENT not defined in device header file; using default!"
+ #endif
+
+ #ifndef __NVIC_PRIO_BITS
+ #define __NVIC_PRIO_BITS 2U
+ #warning "__NVIC_PRIO_BITS not defined in device header file; using default!"
+ #endif
+
+ #ifndef __Vendor_SysTickConfig
+ #define __Vendor_SysTickConfig 0U
+ #warning "__Vendor_SysTickConfig not defined in device header file; using default!"
+ #endif
+#endif
+
+/* IO definitions (access restrictions to peripheral registers) */
+/**
+ \defgroup CMSIS_glob_defs CMSIS Global Defines
+
+ <strong>IO Type Qualifiers</strong> are used
+ \li to specify the access to peripheral variables.
+ \li for automatic generation of peripheral register debug information.
+*/
+#ifdef __cplusplus
+ #define __I volatile /*!< Defines 'read only' permissions */
+#else
+ #define __I volatile const /*!< Defines 'read only' permissions */
+#endif
+#define __O volatile /*!< Defines 'write only' permissions */
+#define __IO volatile /*!< Defines 'read / write' permissions */
+
+/* following defines should be used for structure members */
+#define __IM volatile const /*! Defines 'read only' structure member permissions */
+#define __OM volatile /*! Defines 'write only' structure member permissions */
+#define __IOM volatile /*! Defines 'read / write' structure member permissions */
+
+/*@} end of group Cortex-M0+ */
+
+
+
+/*******************************************************************************
+ * Register Abstraction
+ Core Register contain:
+ - Core Register
+ - Core NVIC Register
+ - Core SCB Register
+ - Core SysTick Register
+ - Core MPU Register
+ ******************************************************************************/
+/**
+ \defgroup CMSIS_core_register Defines and Type Definitions
+ \brief Type definitions and defines for Cortex-M processor based devices.
+*/
+
+/**
+ \ingroup CMSIS_core_register
+ \defgroup CMSIS_CORE Status and Control Registers
+ \brief Core Register type definitions.
+ @{
+ */
+
+/**
+ \brief Union type to access the Application Program Status Register (APSR).
+ */
+typedef union
+{
+ struct
+ {
+ uint32_t _reserved0:28; /*!< bit: 0..27 Reserved */
+ uint32_t V:1; /*!< bit: 28 Overflow condition code flag */
+ uint32_t C:1; /*!< bit: 29 Carry condition code flag */
+ uint32_t Z:1; /*!< bit: 30 Zero condition code flag */
+ uint32_t N:1; /*!< bit: 31 Negative condition code flag */
+ } b; /*!< Structure used for bit access */
+ uint32_t w; /*!< Type used for word access */
+} APSR_Type;
+
+/* APSR Register Definitions */
+#define APSR_N_Pos 31U /*!< APSR: N Position */
+#define APSR_N_Msk (1UL << APSR_N_Pos) /*!< APSR: N Mask */
+
+#define APSR_Z_Pos 30U /*!< APSR: Z Position */
+#define APSR_Z_Msk (1UL << APSR_Z_Pos) /*!< APSR: Z Mask */
+
+#define APSR_C_Pos 29U /*!< APSR: C Position */
+#define APSR_C_Msk (1UL << APSR_C_Pos) /*!< APSR: C Mask */
+
+#define APSR_V_Pos 28U /*!< APSR: V Position */
+#define APSR_V_Msk (1UL << APSR_V_Pos) /*!< APSR: V Mask */
+
+
+/**
+ \brief Union type to access the Interrupt Program Status Register (IPSR).
+ */
+typedef union
+{
+ struct
+ {
+ uint32_t ISR:9; /*!< bit: 0.. 8 Exception number */
+ uint32_t _reserved0:23; /*!< bit: 9..31 Reserved */
+ } b; /*!< Structure used for bit access */
+ uint32_t w; /*!< Type used for word access */
+} IPSR_Type;
+
+/* IPSR Register Definitions */
+#define IPSR_ISR_Pos 0U /*!< IPSR: ISR Position */
+#define IPSR_ISR_Msk (0x1FFUL /*<< IPSR_ISR_Pos*/) /*!< IPSR: ISR Mask */
+
+
+/**
+ \brief Union type to access the Special-Purpose Program Status Registers (xPSR).
+ */
+typedef union
+{
+ struct
+ {
+ uint32_t ISR:9; /*!< bit: 0.. 8 Exception number */
+ uint32_t _reserved0:15; /*!< bit: 9..23 Reserved */
+ uint32_t T:1; /*!< bit: 24 Thumb bit (read 0) */
+ uint32_t _reserved1:3; /*!< bit: 25..27 Reserved */
+ uint32_t V:1; /*!< bit: 28 Overflow condition code flag */
+ uint32_t C:1; /*!< bit: 29 Carry condition code flag */
+ uint32_t Z:1; /*!< bit: 30 Zero condition code flag */
+ uint32_t N:1; /*!< bit: 31 Negative condition code flag */
+ } b; /*!< Structure used for bit access */
+ uint32_t w; /*!< Type used for word access */
+} xPSR_Type;
+
+/* xPSR Register Definitions */
+#define xPSR_N_Pos 31U /*!< xPSR: N Position */
+#define xPSR_N_Msk (1UL << xPSR_N_Pos) /*!< xPSR: N Mask */
+
+#define xPSR_Z_Pos 30U /*!< xPSR: Z Position */
+#define xPSR_Z_Msk (1UL << xPSR_Z_Pos) /*!< xPSR: Z Mask */
+
+#define xPSR_C_Pos 29U /*!< xPSR: C Position */
+#define xPSR_C_Msk (1UL << xPSR_C_Pos) /*!< xPSR: C Mask */
+
+#define xPSR_V_Pos 28U /*!< xPSR: V Position */
+#define xPSR_V_Msk (1UL << xPSR_V_Pos) /*!< xPSR: V Mask */
+
+#define xPSR_T_Pos 24U /*!< xPSR: T Position */
+#define xPSR_T_Msk (1UL << xPSR_T_Pos) /*!< xPSR: T Mask */
+
+#define xPSR_ISR_Pos 0U /*!< xPSR: ISR Position */
+#define xPSR_ISR_Msk (0x1FFUL /*<< xPSR_ISR_Pos*/) /*!< xPSR: ISR Mask */
+
+
+/**
+ \brief Union type to access the Control Registers (CONTROL).
+ */
+typedef union
+{
+ struct
+ {
+ uint32_t nPRIV:1; /*!< bit: 0 Execution privilege in Thread mode */
+ uint32_t SPSEL:1; /*!< bit: 1 Stack to be used */
+ uint32_t _reserved1:30; /*!< bit: 2..31 Reserved */
+ } b; /*!< Structure used for bit access */
+ uint32_t w; /*!< Type used for word access */
+} CONTROL_Type;
+
+/* CONTROL Register Definitions */
+#define CONTROL_SPSEL_Pos 1U /*!< CONTROL: SPSEL Position */
+#define CONTROL_SPSEL_Msk (1UL << CONTROL_SPSEL_Pos) /*!< CONTROL: SPSEL Mask */
+
+#define CONTROL_nPRIV_Pos 0U /*!< CONTROL: nPRIV Position */
+#define CONTROL_nPRIV_Msk (1UL /*<< CONTROL_nPRIV_Pos*/) /*!< CONTROL: nPRIV Mask */
+
+/*@} end of group CMSIS_CORE */
+
+
+/**
+ \ingroup CMSIS_core_register
+ \defgroup CMSIS_NVIC Nested Vectored Interrupt Controller (NVIC)
+ \brief Type definitions for the NVIC Registers
+ @{
+ */
+
+/**
+ \brief Structure type to access the Nested Vectored Interrupt Controller (NVIC).
+ */
+typedef struct
+{
+ __IOM uint32_t ISER[1U]; /*!< Offset: 0x000 (R/W) Interrupt Set Enable Register */
+ uint32_t RESERVED0[31U];
+ __IOM uint32_t ICER[1U]; /*!< Offset: 0x080 (R/W) Interrupt Clear Enable Register */
+ uint32_t RSERVED1[31U];
+ __IOM uint32_t ISPR[1U]; /*!< Offset: 0x100 (R/W) Interrupt Set Pending Register */
+ uint32_t RESERVED2[31U];
+ __IOM uint32_t ICPR[1U]; /*!< Offset: 0x180 (R/W) Interrupt Clear Pending Register */
+ uint32_t RESERVED3[31U];
+ uint32_t RESERVED4[64U];
+ __IOM uint32_t IP[8U]; /*!< Offset: 0x300 (R/W) Interrupt Priority Register */
+} NVIC_Type;
+
+/*@} end of group CMSIS_NVIC */
+
+
+/**
+ \ingroup CMSIS_core_register
+ \defgroup CMSIS_SCB System Control Block (SCB)
+ \brief Type definitions for the System Control Block Registers
+ @{
+ */
+
+/**
+ \brief Structure type to access the System Control Block (SCB).
+ */
+typedef struct
+{
+ __IM uint32_t CPUID; /*!< Offset: 0x000 (R/ ) CPUID Base Register */
+ __IOM uint32_t ICSR; /*!< Offset: 0x004 (R/W) Interrupt Control and State Register */
+#if (__VTOR_PRESENT == 1U)
+ __IOM uint32_t VTOR; /*!< Offset: 0x008 (R/W) Vector Table Offset Register */
+#else
+ uint32_t RESERVED0;
+#endif
+ __IOM uint32_t AIRCR; /*!< Offset: 0x00C (R/W) Application Interrupt and Reset Control Register */
+ __IOM uint32_t SCR; /*!< Offset: 0x010 (R/W) System Control Register */
+ __IOM uint32_t CCR; /*!< Offset: 0x014 (R/W) Configuration Control Register */
+ uint32_t RESERVED1;
+ __IOM uint32_t SHP[2U]; /*!< Offset: 0x01C (R/W) System Handlers Priority Registers. [0] is RESERVED */
+ __IOM uint32_t SHCSR; /*!< Offset: 0x024 (R/W) System Handler Control and State Register */
+} SCB_Type;
+
+/* SCB CPUID Register Definitions */
+#define SCB_CPUID_IMPLEMENTER_Pos 24U /*!< SCB CPUID: IMPLEMENTER Position */
+#define SCB_CPUID_IMPLEMENTER_Msk (0xFFUL << SCB_CPUID_IMPLEMENTER_Pos) /*!< SCB CPUID: IMPLEMENTER Mask */
+
+#define SCB_CPUID_VARIANT_Pos 20U /*!< SCB CPUID: VARIANT Position */
+#define SCB_CPUID_VARIANT_Msk (0xFUL << SCB_CPUID_VARIANT_Pos) /*!< SCB CPUID: VARIANT Mask */
+
+#define SCB_CPUID_ARCHITECTURE_Pos 16U /*!< SCB CPUID: ARCHITECTURE Position */
+#define SCB_CPUID_ARCHITECTURE_Msk (0xFUL << SCB_CPUID_ARCHITECTURE_Pos) /*!< SCB CPUID: ARCHITECTURE Mask */
+
+#define SCB_CPUID_PARTNO_Pos 4U /*!< SCB CPUID: PARTNO Position */
+#define SCB_CPUID_PARTNO_Msk (0xFFFUL << SCB_CPUID_PARTNO_Pos) /*!< SCB CPUID: PARTNO Mask */
+
+#define SCB_CPUID_REVISION_Pos 0U /*!< SCB CPUID: REVISION Position */
+#define SCB_CPUID_REVISION_Msk (0xFUL /*<< SCB_CPUID_REVISION_Pos*/) /*!< SCB CPUID: REVISION Mask */
+
+/* SCB Interrupt Control State Register Definitions */
+#define SCB_ICSR_NMIPENDSET_Pos 31U /*!< SCB ICSR: NMIPENDSET Position */
+#define SCB_ICSR_NMIPENDSET_Msk (1UL << SCB_ICSR_NMIPENDSET_Pos) /*!< SCB ICSR: NMIPENDSET Mask */
+
+#define SCB_ICSR_PENDSVSET_Pos 28U /*!< SCB ICSR: PENDSVSET Position */
+#define SCB_ICSR_PENDSVSET_Msk (1UL << SCB_ICSR_PENDSVSET_Pos) /*!< SCB ICSR: PENDSVSET Mask */
+
+#define SCB_ICSR_PENDSVCLR_Pos 27U /*!< SCB ICSR: PENDSVCLR Position */
+#define SCB_ICSR_PENDSVCLR_Msk (1UL << SCB_ICSR_PENDSVCLR_Pos) /*!< SCB ICSR: PENDSVCLR Mask */
+
+#define SCB_ICSR_PENDSTSET_Pos 26U /*!< SCB ICSR: PENDSTSET Position */
+#define SCB_ICSR_PENDSTSET_Msk (1UL << SCB_ICSR_PENDSTSET_Pos) /*!< SCB ICSR: PENDSTSET Mask */
+
+#define SCB_ICSR_PENDSTCLR_Pos 25U /*!< SCB ICSR: PENDSTCLR Position */
+#define SCB_ICSR_PENDSTCLR_Msk (1UL << SCB_ICSR_PENDSTCLR_Pos) /*!< SCB ICSR: PENDSTCLR Mask */
+
+#define SCB_ICSR_ISRPREEMPT_Pos 23U /*!< SCB ICSR: ISRPREEMPT Position */
+#define SCB_ICSR_ISRPREEMPT_Msk (1UL << SCB_ICSR_ISRPREEMPT_Pos) /*!< SCB ICSR: ISRPREEMPT Mask */
+
+#define SCB_ICSR_ISRPENDING_Pos 22U /*!< SCB ICSR: ISRPENDING Position */
+#define SCB_ICSR_ISRPENDING_Msk (1UL << SCB_ICSR_ISRPENDING_Pos) /*!< SCB ICSR: ISRPENDING Mask */
+
+#define SCB_ICSR_VECTPENDING_Pos 12U /*!< SCB ICSR: VECTPENDING Position */
+#define SCB_ICSR_VECTPENDING_Msk (0x1FFUL << SCB_ICSR_VECTPENDING_Pos) /*!< SCB ICSR: VECTPENDING Mask */
+
+#define SCB_ICSR_VECTACTIVE_Pos 0U /*!< SCB ICSR: VECTACTIVE Position */
+#define SCB_ICSR_VECTACTIVE_Msk (0x1FFUL /*<< SCB_ICSR_VECTACTIVE_Pos*/) /*!< SCB ICSR: VECTACTIVE Mask */
+
+#if (__VTOR_PRESENT == 1U)
+/* SCB Interrupt Control State Register Definitions */
+#define SCB_VTOR_TBLOFF_Pos 8U /*!< SCB VTOR: TBLOFF Position */
+#define SCB_VTOR_TBLOFF_Msk (0xFFFFFFUL << SCB_VTOR_TBLOFF_Pos) /*!< SCB VTOR: TBLOFF Mask */
+#endif
+
+/* SCB Application Interrupt and Reset Control Register Definitions */
+#define SCB_AIRCR_VECTKEY_Pos 16U /*!< SCB AIRCR: VECTKEY Position */
+#define SCB_AIRCR_VECTKEY_Msk (0xFFFFUL << SCB_AIRCR_VECTKEY_Pos) /*!< SCB AIRCR: VECTKEY Mask */
+
+#define SCB_AIRCR_VECTKEYSTAT_Pos 16U /*!< SCB AIRCR: VECTKEYSTAT Position */
+#define SCB_AIRCR_VECTKEYSTAT_Msk (0xFFFFUL << SCB_AIRCR_VECTKEYSTAT_Pos) /*!< SCB AIRCR: VECTKEYSTAT Mask */
+
+#define SCB_AIRCR_ENDIANESS_Pos 15U /*!< SCB AIRCR: ENDIANESS Position */
+#define SCB_AIRCR_ENDIANESS_Msk (1UL << SCB_AIRCR_ENDIANESS_Pos) /*!< SCB AIRCR: ENDIANESS Mask */
+
+#define SCB_AIRCR_SYSRESETREQ_Pos 2U /*!< SCB AIRCR: SYSRESETREQ Position */
+#define SCB_AIRCR_SYSRESETREQ_Msk (1UL << SCB_AIRCR_SYSRESETREQ_Pos) /*!< SCB AIRCR: SYSRESETREQ Mask */
+
+#define SCB_AIRCR_VECTCLRACTIVE_Pos 1U /*!< SCB AIRCR: VECTCLRACTIVE Position */
+#define SCB_AIRCR_VECTCLRACTIVE_Msk (1UL << SCB_AIRCR_VECTCLRACTIVE_Pos) /*!< SCB AIRCR: VECTCLRACTIVE Mask */
+
+/* SCB System Control Register Definitions */
+#define SCB_SCR_SEVONPEND_Pos 4U /*!< SCB SCR: SEVONPEND Position */
+#define SCB_SCR_SEVONPEND_Msk (1UL << SCB_SCR_SEVONPEND_Pos) /*!< SCB SCR: SEVONPEND Mask */
+
+#define SCB_SCR_SLEEPDEEP_Pos 2U /*!< SCB SCR: SLEEPDEEP Position */
+#define SCB_SCR_SLEEPDEEP_Msk (1UL << SCB_SCR_SLEEPDEEP_Pos) /*!< SCB SCR: SLEEPDEEP Mask */
+
+#define SCB_SCR_SLEEPONEXIT_Pos 1U /*!< SCB SCR: SLEEPONEXIT Position */
+#define SCB_SCR_SLEEPONEXIT_Msk (1UL << SCB_SCR_SLEEPONEXIT_Pos) /*!< SCB SCR: SLEEPONEXIT Mask */
+
+/* SCB Configuration Control Register Definitions */
+#define SCB_CCR_STKALIGN_Pos 9U /*!< SCB CCR: STKALIGN Position */
+#define SCB_CCR_STKALIGN_Msk (1UL << SCB_CCR_STKALIGN_Pos) /*!< SCB CCR: STKALIGN Mask */
+
+#define SCB_CCR_UNALIGN_TRP_Pos 3U /*!< SCB CCR: UNALIGN_TRP Position */
+#define SCB_CCR_UNALIGN_TRP_Msk (1UL << SCB_CCR_UNALIGN_TRP_Pos) /*!< SCB CCR: UNALIGN_TRP Mask */
+
+/* SCB System Handler Control and State Register Definitions */
+#define SCB_SHCSR_SVCALLPENDED_Pos 15U /*!< SCB SHCSR: SVCALLPENDED Position */
+#define SCB_SHCSR_SVCALLPENDED_Msk (1UL << SCB_SHCSR_SVCALLPENDED_Pos) /*!< SCB SHCSR: SVCALLPENDED Mask */
+
+/*@} end of group CMSIS_SCB */
+
+
+/**
+ \ingroup CMSIS_core_register
+ \defgroup CMSIS_SysTick System Tick Timer (SysTick)
+ \brief Type definitions for the System Timer Registers.
+ @{
+ */
+
+/**
+ \brief Structure type to access the System Timer (SysTick).
+ */
+typedef struct
+{
+ __IOM uint32_t CTRL; /*!< Offset: 0x000 (R/W) SysTick Control and Status Register */
+ __IOM uint32_t LOAD; /*!< Offset: 0x004 (R/W) SysTick Reload Value Register */
+ __IOM uint32_t VAL; /*!< Offset: 0x008 (R/W) SysTick Current Value Register */
+ __IM uint32_t CALIB; /*!< Offset: 0x00C (R/ ) SysTick Calibration Register */
+} SysTick_Type;
+
+/* SysTick Control / Status Register Definitions */
+#define SysTick_CTRL_COUNTFLAG_Pos 16U /*!< SysTick CTRL: COUNTFLAG Position */
+#define SysTick_CTRL_COUNTFLAG_Msk (1UL << SysTick_CTRL_COUNTFLAG_Pos) /*!< SysTick CTRL: COUNTFLAG Mask */
+
+#define SysTick_CTRL_CLKSOURCE_Pos 2U /*!< SysTick CTRL: CLKSOURCE Position */
+#define SysTick_CTRL_CLKSOURCE_Msk (1UL << SysTick_CTRL_CLKSOURCE_Pos) /*!< SysTick CTRL: CLKSOURCE Mask */
+
+#define SysTick_CTRL_TICKINT_Pos 1U /*!< SysTick CTRL: TICKINT Position */
+#define SysTick_CTRL_TICKINT_Msk (1UL << SysTick_CTRL_TICKINT_Pos) /*!< SysTick CTRL: TICKINT Mask */
+
+#define SysTick_CTRL_ENABLE_Pos 0U /*!< SysTick CTRL: ENABLE Position */
+#define SysTick_CTRL_ENABLE_Msk (1UL /*<< SysTick_CTRL_ENABLE_Pos*/) /*!< SysTick CTRL: ENABLE Mask */
+
+/* SysTick Reload Register Definitions */
+#define SysTick_LOAD_RELOAD_Pos 0U /*!< SysTick LOAD: RELOAD Position */
+#define SysTick_LOAD_RELOAD_Msk (0xFFFFFFUL /*<< SysTick_LOAD_RELOAD_Pos*/) /*!< SysTick LOAD: RELOAD Mask */
+
+/* SysTick Current Register Definitions */
+#define SysTick_VAL_CURRENT_Pos 0U /*!< SysTick VAL: CURRENT Position */
+#define SysTick_VAL_CURRENT_Msk (0xFFFFFFUL /*<< SysTick_VAL_CURRENT_Pos*/) /*!< SysTick VAL: CURRENT Mask */
+
+/* SysTick Calibration Register Definitions */
+#define SysTick_CALIB_NOREF_Pos 31U /*!< SysTick CALIB: NOREF Position */
+#define SysTick_CALIB_NOREF_Msk (1UL << SysTick_CALIB_NOREF_Pos) /*!< SysTick CALIB: NOREF Mask */
+
+#define SysTick_CALIB_SKEW_Pos 30U /*!< SysTick CALIB: SKEW Position */
+#define SysTick_CALIB_SKEW_Msk (1UL << SysTick_CALIB_SKEW_Pos) /*!< SysTick CALIB: SKEW Mask */
+
+#define SysTick_CALIB_TENMS_Pos 0U /*!< SysTick CALIB: TENMS Position */
+#define SysTick_CALIB_TENMS_Msk (0xFFFFFFUL /*<< SysTick_CALIB_TENMS_Pos*/) /*!< SysTick CALIB: TENMS Mask */
+
+/*@} end of group CMSIS_SysTick */
+
+#if (__MPU_PRESENT == 1U)
+/**
+ \ingroup CMSIS_core_register
+ \defgroup CMSIS_MPU Memory Protection Unit (MPU)
+ \brief Type definitions for the Memory Protection Unit (MPU)
+ @{
+ */
+
+/**
+ \brief Structure type to access the Memory Protection Unit (MPU).
+ */
+typedef struct
+{
+ __IM uint32_t TYPE; /*!< Offset: 0x000 (R/ ) MPU Type Register */
+ __IOM uint32_t CTRL; /*!< Offset: 0x004 (R/W) MPU Control Register */
+ __IOM uint32_t RNR; /*!< Offset: 0x008 (R/W) MPU Region RNRber Register */
+ __IOM uint32_t RBAR; /*!< Offset: 0x00C (R/W) MPU Region Base Address Register */
+ __IOM uint32_t RASR; /*!< Offset: 0x010 (R/W) MPU Region Attribute and Size Register */
+} MPU_Type;
+
+/* MPU Type Register Definitions */
+#define MPU_TYPE_IREGION_Pos 16U /*!< MPU TYPE: IREGION Position */
+#define MPU_TYPE_IREGION_Msk (0xFFUL << MPU_TYPE_IREGION_Pos) /*!< MPU TYPE: IREGION Mask */
+
+#define MPU_TYPE_DREGION_Pos 8U /*!< MPU TYPE: DREGION Position */
+#define MPU_TYPE_DREGION_Msk (0xFFUL << MPU_TYPE_DREGION_Pos) /*!< MPU TYPE: DREGION Mask */
+
+#define MPU_TYPE_SEPARATE_Pos 0U /*!< MPU TYPE: SEPARATE Position */
+#define MPU_TYPE_SEPARATE_Msk (1UL /*<< MPU_TYPE_SEPARATE_Pos*/) /*!< MPU TYPE: SEPARATE Mask */
+
+/* MPU Control Register Definitions */
+#define MPU_CTRL_PRIVDEFENA_Pos 2U /*!< MPU CTRL: PRIVDEFENA Position */
+#define MPU_CTRL_PRIVDEFENA_Msk (1UL << MPU_CTRL_PRIVDEFENA_Pos) /*!< MPU CTRL: PRIVDEFENA Mask */
+
+#define MPU_CTRL_HFNMIENA_Pos 1U /*!< MPU CTRL: HFNMIENA Position */
+#define MPU_CTRL_HFNMIENA_Msk (1UL << MPU_CTRL_HFNMIENA_Pos) /*!< MPU CTRL: HFNMIENA Mask */
+
+#define MPU_CTRL_ENABLE_Pos 0U /*!< MPU CTRL: ENABLE Position */
+#define MPU_CTRL_ENABLE_Msk (1UL /*<< MPU_CTRL_ENABLE_Pos*/) /*!< MPU CTRL: ENABLE Mask */
+
+/* MPU Region Number Register Definitions */
+#define MPU_RNR_REGION_Pos 0U /*!< MPU RNR: REGION Position */
+#define MPU_RNR_REGION_Msk (0xFFUL /*<< MPU_RNR_REGION_Pos*/) /*!< MPU RNR: REGION Mask */
+
+/* MPU Region Base Address Register Definitions */
+#define MPU_RBAR_ADDR_Pos 8U /*!< MPU RBAR: ADDR Position */
+#define MPU_RBAR_ADDR_Msk (0xFFFFFFUL << MPU_RBAR_ADDR_Pos) /*!< MPU RBAR: ADDR Mask */
+
+#define MPU_RBAR_VALID_Pos 4U /*!< MPU RBAR: VALID Position */
+#define MPU_RBAR_VALID_Msk (1UL << MPU_RBAR_VALID_Pos) /*!< MPU RBAR: VALID Mask */
+
+#define MPU_RBAR_REGION_Pos 0U /*!< MPU RBAR: REGION Position */
+#define MPU_RBAR_REGION_Msk (0xFUL /*<< MPU_RBAR_REGION_Pos*/) /*!< MPU RBAR: REGION Mask */
+
+/* MPU Region Attribute and Size Register Definitions */
+#define MPU_RASR_ATTRS_Pos 16U /*!< MPU RASR: MPU Region Attribute field Position */
+#define MPU_RASR_ATTRS_Msk (0xFFFFUL << MPU_RASR_ATTRS_Pos) /*!< MPU RASR: MPU Region Attribute field Mask */
+
+#define MPU_RASR_XN_Pos 28U /*!< MPU RASR: ATTRS.XN Position */
+#define MPU_RASR_XN_Msk (1UL << MPU_RASR_XN_Pos) /*!< MPU RASR: ATTRS.XN Mask */
+
+#define MPU_RASR_AP_Pos 24U /*!< MPU RASR: ATTRS.AP Position */
+#define MPU_RASR_AP_Msk (0x7UL << MPU_RASR_AP_Pos) /*!< MPU RASR: ATTRS.AP Mask */
+
+#define MPU_RASR_TEX_Pos 19U /*!< MPU RASR: ATTRS.TEX Position */
+#define MPU_RASR_TEX_Msk (0x7UL << MPU_RASR_TEX_Pos) /*!< MPU RASR: ATTRS.TEX Mask */
+
+#define MPU_RASR_S_Pos 18U /*!< MPU RASR: ATTRS.S Position */
+#define MPU_RASR_S_Msk (1UL << MPU_RASR_S_Pos) /*!< MPU RASR: ATTRS.S Mask */
+
+#define MPU_RASR_C_Pos 17U /*!< MPU RASR: ATTRS.C Position */
+#define MPU_RASR_C_Msk (1UL << MPU_RASR_C_Pos) /*!< MPU RASR: ATTRS.C Mask */
+
+#define MPU_RASR_B_Pos 16U /*!< MPU RASR: ATTRS.B Position */
+#define MPU_RASR_B_Msk (1UL << MPU_RASR_B_Pos) /*!< MPU RASR: ATTRS.B Mask */
+
+#define MPU_RASR_SRD_Pos 8U /*!< MPU RASR: Sub-Region Disable Position */
+#define MPU_RASR_SRD_Msk (0xFFUL << MPU_RASR_SRD_Pos) /*!< MPU RASR: Sub-Region Disable Mask */
+
+#define MPU_RASR_SIZE_Pos 1U /*!< MPU RASR: Region Size Field Position */
+#define MPU_RASR_SIZE_Msk (0x1FUL << MPU_RASR_SIZE_Pos) /*!< MPU RASR: Region Size Field Mask */
+
+#define MPU_RASR_ENABLE_Pos 0U /*!< MPU RASR: Region enable bit Position */
+#define MPU_RASR_ENABLE_Msk (1UL /*<< MPU_RASR_ENABLE_Pos*/) /*!< MPU RASR: Region enable bit Disable Mask */
+
+/*@} end of group CMSIS_MPU */
+#endif
+
+
+/**
+ \ingroup CMSIS_core_register
+ \defgroup CMSIS_CoreDebug Core Debug Registers (CoreDebug)
+ \brief Cortex-M0+ Core Debug Registers (DCB registers, SHCSR, and DFSR) are only accessible over DAP and not via processor.
+ Therefore they are not covered by the Cortex-M0+ header file.
+ @{
+ */
+/*@} end of group CMSIS_CoreDebug */
+
+
+/**
+ \ingroup CMSIS_core_register
+ \defgroup CMSIS_core_bitfield Core register bit field macros
+ \brief Macros for use with bit field definitions (xxx_Pos, xxx_Msk).
+ @{
+ */
+
+/**
+ \brief Mask and shift a bit field value for use in a register bit range.
+ \param[in] field Name of the register bit field.
+ \param[in] value Value of the bit field.
+ \return Masked and shifted value.
+*/
+#define _VAL2FLD(field, value) ((value << field ## _Pos) & field ## _Msk)
+
+/**
+ \brief Mask and shift a register value to extract a bit filed value.
+ \param[in] field Name of the register bit field.
+ \param[in] value Value of register.
+ \return Masked and shifted bit field value.
+*/
+#define _FLD2VAL(field, value) ((value & field ## _Msk) >> field ## _Pos)
+
+/*@} end of group CMSIS_core_bitfield */
+
+
+/**
+ \ingroup CMSIS_core_register
+ \defgroup CMSIS_core_base Core Definitions
+ \brief Definitions for base addresses, unions, and structures.
+ @{
+ */
+
+/* Memory mapping of Cortex-M0+ Hardware */
+#define SCS_BASE (0xE000E000UL) /*!< System Control Space Base Address */
+#define SysTick_BASE (SCS_BASE + 0x0010UL) /*!< SysTick Base Address */
+#define NVIC_BASE (SCS_BASE + 0x0100UL) /*!< NVIC Base Address */
+#define SCB_BASE (SCS_BASE + 0x0D00UL) /*!< System Control Block Base Address */
+
+#define SCB ((SCB_Type *) SCB_BASE ) /*!< SCB configuration struct */
+#define SysTick ((SysTick_Type *) SysTick_BASE ) /*!< SysTick configuration struct */
+#define NVIC ((NVIC_Type *) NVIC_BASE ) /*!< NVIC configuration struct */
+
+#if (__MPU_PRESENT == 1U)
+ #define MPU_BASE (SCS_BASE + 0x0D90UL) /*!< Memory Protection Unit */
+ #define MPU ((MPU_Type *) MPU_BASE ) /*!< Memory Protection Unit */
+#endif
+
+/*@} */
+
+
+
+/*******************************************************************************
+ * Hardware Abstraction Layer
+ Core Function Interface contains:
+ - Core NVIC Functions
+ - Core SysTick Functions
+ - Core Register Access Functions
+ ******************************************************************************/
+/**
+ \defgroup CMSIS_Core_FunctionInterface Functions and Instructions Reference
+*/
+
+
+
+/* ########################## NVIC functions #################################### */
+/**
+ \ingroup CMSIS_Core_FunctionInterface
+ \defgroup CMSIS_Core_NVICFunctions NVIC Functions
+ \brief Functions that manage interrupts and exceptions via the NVIC.
+ @{
+ */
+
+/* Interrupt Priorities are WORD accessible only under ARMv6M */
+/* The following MACROS handle generation of the register offset and byte masks */
+#define _BIT_SHIFT(IRQn) ( ((((uint32_t)(int32_t)(IRQn)) ) & 0x03UL) * 8UL)
+#define _SHP_IDX(IRQn) ( (((((uint32_t)(int32_t)(IRQn)) & 0x0FUL)-8UL) >> 2UL) )
+#define _IP_IDX(IRQn) ( (((uint32_t)(int32_t)(IRQn)) >> 2UL) )
+
+
+/**
+ \brief Enable External Interrupt
+ \details Enables a device-specific interrupt in the NVIC interrupt controller.
+ \param [in] IRQn External interrupt number. Value cannot be negative.
+ */
+__STATIC_INLINE void NVIC_EnableIRQ(IRQn_Type IRQn)
+{
+ NVIC->ISER[0U] = (uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL));
+}
+
+
+/**
+ \brief Disable External Interrupt
+ \details Disables a device-specific interrupt in the NVIC interrupt controller.
+ \param [in] IRQn External interrupt number. Value cannot be negative.
+ */
+__STATIC_INLINE void NVIC_DisableIRQ(IRQn_Type IRQn)
+{
+ NVIC->ICER[0U] = (uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL));
+}
+
+
+/**
+ \brief Get Pending Interrupt
+ \details Reads the pending register in the NVIC and returns the pending bit for the specified interrupt.
+ \param [in] IRQn Interrupt number.
+ \return 0 Interrupt status is not pending.
+ \return 1 Interrupt status is pending.
+ */
+__STATIC_INLINE uint32_t NVIC_GetPendingIRQ(IRQn_Type IRQn)
+{
+ return((uint32_t)(((NVIC->ISPR[0U] & (1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL));
+}
+
+
+/**
+ \brief Set Pending Interrupt
+ \details Sets the pending bit of an external interrupt.
+ \param [in] IRQn Interrupt number. Value cannot be negative.
+ */
+__STATIC_INLINE void NVIC_SetPendingIRQ(IRQn_Type IRQn)
+{
+ NVIC->ISPR[0U] = (uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL));
+}
+
+
+/**
+ \brief Clear Pending Interrupt
+ \details Clears the pending bit of an external interrupt.
+ \param [in] IRQn External interrupt number. Value cannot be negative.
+ */
+__STATIC_INLINE void NVIC_ClearPendingIRQ(IRQn_Type IRQn)
+{
+ NVIC->ICPR[0U] = (uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL));
+}
+
+
+/**
+ \brief Set Interrupt Priority
+ \details Sets the priority of an interrupt.
+ \note The priority cannot be set for every core interrupt.
+ \param [in] IRQn Interrupt number.
+ \param [in] priority Priority to set.
+ */
+__STATIC_INLINE void NVIC_SetPriority(IRQn_Type IRQn, uint32_t priority)
+{
+ if ((int32_t)(IRQn) < 0)
+ {
+ SCB->SHP[_SHP_IDX(IRQn)] = ((uint32_t)(SCB->SHP[_SHP_IDX(IRQn)] & ~(0xFFUL << _BIT_SHIFT(IRQn))) |
+ (((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL) << _BIT_SHIFT(IRQn)));
+ }
+ else
+ {
+ NVIC->IP[_IP_IDX(IRQn)] = ((uint32_t)(NVIC->IP[_IP_IDX(IRQn)] & ~(0xFFUL << _BIT_SHIFT(IRQn))) |
+ (((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL) << _BIT_SHIFT(IRQn)));
+ }
+}
+
+
+/**
+ \brief Get Interrupt Priority
+ \details Reads the priority of an interrupt.
+ The interrupt number can be positive to specify an external (device specific) interrupt,
+ or negative to specify an internal (core) interrupt.
+ \param [in] IRQn Interrupt number.
+ \return Interrupt Priority.
+ Value is aligned automatically to the implemented priority bits of the microcontroller.
+ */
+__STATIC_INLINE uint32_t NVIC_GetPriority(IRQn_Type IRQn)
+{
+
+ if ((int32_t)(IRQn) < 0)
+ {
+ return((uint32_t)(((SCB->SHP[_SHP_IDX(IRQn)] >> _BIT_SHIFT(IRQn) ) & (uint32_t)0xFFUL) >> (8U - __NVIC_PRIO_BITS)));
+ }
+ else
+ {
+ return((uint32_t)(((NVIC->IP[ _IP_IDX(IRQn)] >> _BIT_SHIFT(IRQn) ) & (uint32_t)0xFFUL) >> (8U - __NVIC_PRIO_BITS)));
+ }
+}
+
+
+/**
+ \brief System Reset
+ \details Initiates a system reset request to reset the MCU.
+ */
+__STATIC_INLINE void NVIC_SystemReset(void)
+{
+ __DSB(); /* Ensure all outstanding memory accesses included
+ buffered write are completed before reset */
+ SCB->AIRCR = ((0x5FAUL << SCB_AIRCR_VECTKEY_Pos) |
+ SCB_AIRCR_SYSRESETREQ_Msk);
+ __DSB(); /* Ensure completion of memory access */
+
+ for (;;) /* wait until reset */
+ {
+ __NOP();
+ }
+}
+
+/*@} end of CMSIS_Core_NVICFunctions */
+
+
+
+/* ################################## SysTick function ############################################ */
+/**
+ \ingroup CMSIS_Core_FunctionInterface
+ \defgroup CMSIS_Core_SysTickFunctions SysTick Functions
+ \brief Functions that configure the System.
+ @{
+ */
+
+#if (__Vendor_SysTickConfig == 0U)
+
+/**
+ \brief System Tick Configuration
+ \details Initializes the System Timer and its interrupt, and starts the System Tick Timer.
+ Counter is in free running mode to generate periodic interrupts.
+ \param [in] ticks Number of ticks between two interrupts.
+ \return 0 Function succeeded.
+ \return 1 Function failed.
+ \note When the variable <b>__Vendor_SysTickConfig</b> is set to 1, then the
+ function <b>SysTick_Config</b> is not included. In this case, the file <b><i>device</i>.h</b>
+ must contain a vendor-specific implementation of this function.
+ */
+__STATIC_INLINE uint32_t SysTick_Config(uint32_t ticks)
+{
+ if ((ticks - 1UL) > SysTick_LOAD_RELOAD_Msk)
+ {
+ return (1UL); /* Reload value impossible */
+ }
+
+ SysTick->LOAD = (uint32_t)(ticks - 1UL); /* set reload register */
+ NVIC_SetPriority (SysTick_IRQn, (1UL << __NVIC_PRIO_BITS) - 1UL); /* set Priority for Systick Interrupt */
+ SysTick->VAL = 0UL; /* Load the SysTick Counter Value */
+ SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk |
+ SysTick_CTRL_TICKINT_Msk |
+ SysTick_CTRL_ENABLE_Msk; /* Enable SysTick IRQ and SysTick Timer */
+ return (0UL); /* Function successful */
+}
+
+#endif
+
+/*@} end of CMSIS_Core_SysTickFunctions */
+
+
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __CORE_CM0PLUS_H_DEPENDANT */
+
+#endif /* __CMSIS_GENERIC */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/toolchain/cmsis/include/core_cm3.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/toolchain/cmsis/include/core_cm3.h
new file mode 100644
index 0000000..88f5e65
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/toolchain/cmsis/include/core_cm3.h
@@ -0,0 +1,1763 @@
+/**************************************************************************//**
+ * @file core_cm3.h
+ * @brief CMSIS Cortex-M3 Core Peripheral Access Layer Header File
+ * @version V4.30
+ * @date 20. October 2015
+ ******************************************************************************/
+/* Copyright (c) 2009 - 2015 ARM LIMITED
+
+ All rights reserved.
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are met:
+ - Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ - 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.
+ - Neither the name of ARM 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 COPYRIGHT HOLDERS AND 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.
+ ---------------------------------------------------------------------------*/
+
+
+#if defined ( __ICCARM__ )
+ #pragma system_include /* treat file as system include file for MISRA check */
+#elif defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050)
+ #pragma clang system_header /* treat file as system include file */
+#endif
+
+#ifndef __CORE_CM3_H_GENERIC
+#define __CORE_CM3_H_GENERIC
+
+#include <stdint.h>
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+/**
+ \page CMSIS_MISRA_Exceptions MISRA-C:2004 Compliance Exceptions
+ CMSIS violates the following MISRA-C:2004 rules:
+
+ \li Required Rule 8.5, object/function definition in header file.<br>
+ Function definitions in header files are used to allow 'inlining'.
+
+ \li Required Rule 18.4, declaration of union type or object of union type: '{...}'.<br>
+ Unions are used for effective representation of core registers.
+
+ \li Advisory Rule 19.7, Function-like macro defined.<br>
+ Function-like macros are used to allow more efficient code.
+ */
+
+
+/*******************************************************************************
+ * CMSIS definitions
+ ******************************************************************************/
+/**
+ \ingroup Cortex_M3
+ @{
+ */
+
+/* CMSIS CM3 definitions */
+#define __CM3_CMSIS_VERSION_MAIN (0x04U) /*!< [31:16] CMSIS HAL main version */
+#define __CM3_CMSIS_VERSION_SUB (0x1EU) /*!< [15:0] CMSIS HAL sub version */
+#define __CM3_CMSIS_VERSION ((__CM3_CMSIS_VERSION_MAIN << 16U) | \
+ __CM3_CMSIS_VERSION_SUB ) /*!< CMSIS HAL version number */
+
+#define __CORTEX_M (0x03U) /*!< Cortex-M Core */
+
+
+#if defined ( __CC_ARM )
+ #define __ASM __asm /*!< asm keyword for ARM Compiler */
+ #define __INLINE __inline /*!< inline keyword for ARM Compiler */
+ #define __STATIC_INLINE static __inline
+
+#elif defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050)
+ #define __ASM __asm /*!< asm keyword for ARM Compiler */
+ #define __INLINE __inline /*!< inline keyword for ARM Compiler */
+ #define __STATIC_INLINE static __inline
+
+#elif defined ( __GNUC__ )
+ #define __ASM __asm /*!< asm keyword for GNU Compiler */
+ #define __INLINE inline /*!< inline keyword for GNU Compiler */
+ #define __STATIC_INLINE static inline
+
+#elif defined ( __ICCARM__ )
+ #define __ASM __asm /*!< asm keyword for IAR Compiler */
+ #define __INLINE inline /*!< inline keyword for IAR Compiler. Only available in High optimization mode! */
+ #define __STATIC_INLINE static inline
+
+#elif defined ( __TMS470__ )
+ #define __ASM __asm /*!< asm keyword for TI CCS Compiler */
+ #define __STATIC_INLINE static inline
+
+#elif defined ( __TASKING__ )
+ #define __ASM __asm /*!< asm keyword for TASKING Compiler */
+ #define __INLINE inline /*!< inline keyword for TASKING Compiler */
+ #define __STATIC_INLINE static inline
+
+#elif defined ( __CSMC__ )
+ #define __packed
+ #define __ASM _asm /*!< asm keyword for COSMIC Compiler */
+ #define __INLINE inline /*!< inline keyword for COSMIC Compiler. Use -pc99 on compile line */
+ #define __STATIC_INLINE static inline
+
+#else
+ #error Unknown compiler
+#endif
+
+/** __FPU_USED indicates whether an FPU is used or not.
+ This core does not support an FPU at all
+*/
+#define __FPU_USED 0U
+
+#if defined ( __CC_ARM )
+ #if defined __TARGET_FPU_VFP
+ #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
+ #endif
+
+#elif defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050)
+ #if defined __ARM_PCS_VFP
+ #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
+ #endif
+
+#elif defined ( __GNUC__ )
+ #if defined (__VFP_FP__) && !defined(__SOFTFP__)
+ #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
+ #endif
+
+#elif defined ( __ICCARM__ )
+ #if defined __ARMVFP__
+ #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
+ #endif
+
+#elif defined ( __TMS470__ )
+ #if defined __TI_VFP_SUPPORT__
+ #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
+ #endif
+
+#elif defined ( __TASKING__ )
+ #if defined __FPU_VFP__
+ #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
+ #endif
+
+#elif defined ( __CSMC__ )
+ #if ( __CSMC__ & 0x400U)
+ #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
+ #endif
+
+#endif
+
+#include "core_cmInstr.h" /* Core Instruction Access */
+#include "core_cmFunc.h" /* Core Function Access */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __CORE_CM3_H_GENERIC */
+
+#ifndef __CMSIS_GENERIC
+
+#ifndef __CORE_CM3_H_DEPENDANT
+#define __CORE_CM3_H_DEPENDANT
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+/* check device defines and use defaults */
+#if defined __CHECK_DEVICE_DEFINES
+ #ifndef __CM3_REV
+ #define __CM3_REV 0x0200U
+ #warning "__CM3_REV not defined in device header file; using default!"
+ #endif
+
+ #ifndef __MPU_PRESENT
+ #define __MPU_PRESENT 0U
+ #warning "__MPU_PRESENT not defined in device header file; using default!"
+ #endif
+
+ #ifndef __NVIC_PRIO_BITS
+ #define __NVIC_PRIO_BITS 4U
+ #warning "__NVIC_PRIO_BITS not defined in device header file; using default!"
+ #endif
+
+ #ifndef __Vendor_SysTickConfig
+ #define __Vendor_SysTickConfig 0U
+ #warning "__Vendor_SysTickConfig not defined in device header file; using default!"
+ #endif
+#endif
+
+/* IO definitions (access restrictions to peripheral registers) */
+/**
+ \defgroup CMSIS_glob_defs CMSIS Global Defines
+
+ <strong>IO Type Qualifiers</strong> are used
+ \li to specify the access to peripheral variables.
+ \li for automatic generation of peripheral register debug information.
+*/
+#ifdef __cplusplus
+ #define __I volatile /*!< Defines 'read only' permissions */
+#else
+ #define __I volatile const /*!< Defines 'read only' permissions */
+#endif
+#define __O volatile /*!< Defines 'write only' permissions */
+#define __IO volatile /*!< Defines 'read / write' permissions */
+
+/* following defines should be used for structure members */
+#define __IM volatile const /*! Defines 'read only' structure member permissions */
+#define __OM volatile /*! Defines 'write only' structure member permissions */
+#define __IOM volatile /*! Defines 'read / write' structure member permissions */
+
+/*@} end of group Cortex_M3 */
+
+
+
+/*******************************************************************************
+ * Register Abstraction
+ Core Register contain:
+ - Core Register
+ - Core NVIC Register
+ - Core SCB Register
+ - Core SysTick Register
+ - Core Debug Register
+ - Core MPU Register
+ ******************************************************************************/
+/**
+ \defgroup CMSIS_core_register Defines and Type Definitions
+ \brief Type definitions and defines for Cortex-M processor based devices.
+*/
+
+/**
+ \ingroup CMSIS_core_register
+ \defgroup CMSIS_CORE Status and Control Registers
+ \brief Core Register type definitions.
+ @{
+ */
+
+/**
+ \brief Union type to access the Application Program Status Register (APSR).
+ */
+typedef union
+{
+ struct
+ {
+ uint32_t _reserved0:27; /*!< bit: 0..26 Reserved */
+ uint32_t Q:1; /*!< bit: 27 Saturation condition flag */
+ uint32_t V:1; /*!< bit: 28 Overflow condition code flag */
+ uint32_t C:1; /*!< bit: 29 Carry condition code flag */
+ uint32_t Z:1; /*!< bit: 30 Zero condition code flag */
+ uint32_t N:1; /*!< bit: 31 Negative condition code flag */
+ } b; /*!< Structure used for bit access */
+ uint32_t w; /*!< Type used for word access */
+} APSR_Type;
+
+/* APSR Register Definitions */
+#define APSR_N_Pos 31U /*!< APSR: N Position */
+#define APSR_N_Msk (1UL << APSR_N_Pos) /*!< APSR: N Mask */
+
+#define APSR_Z_Pos 30U /*!< APSR: Z Position */
+#define APSR_Z_Msk (1UL << APSR_Z_Pos) /*!< APSR: Z Mask */
+
+#define APSR_C_Pos 29U /*!< APSR: C Position */
+#define APSR_C_Msk (1UL << APSR_C_Pos) /*!< APSR: C Mask */
+
+#define APSR_V_Pos 28U /*!< APSR: V Position */
+#define APSR_V_Msk (1UL << APSR_V_Pos) /*!< APSR: V Mask */
+
+#define APSR_Q_Pos 27U /*!< APSR: Q Position */
+#define APSR_Q_Msk (1UL << APSR_Q_Pos) /*!< APSR: Q Mask */
+
+
+/**
+ \brief Union type to access the Interrupt Program Status Register (IPSR).
+ */
+typedef union
+{
+ struct
+ {
+ uint32_t ISR:9; /*!< bit: 0.. 8 Exception number */
+ uint32_t _reserved0:23; /*!< bit: 9..31 Reserved */
+ } b; /*!< Structure used for bit access */
+ uint32_t w; /*!< Type used for word access */
+} IPSR_Type;
+
+/* IPSR Register Definitions */
+#define IPSR_ISR_Pos 0U /*!< IPSR: ISR Position */
+#define IPSR_ISR_Msk (0x1FFUL /*<< IPSR_ISR_Pos*/) /*!< IPSR: ISR Mask */
+
+
+/**
+ \brief Union type to access the Special-Purpose Program Status Registers (xPSR).
+ */
+typedef union
+{
+ struct
+ {
+ uint32_t ISR:9; /*!< bit: 0.. 8 Exception number */
+ uint32_t _reserved0:15; /*!< bit: 9..23 Reserved */
+ uint32_t T:1; /*!< bit: 24 Thumb bit (read 0) */
+ uint32_t IT:2; /*!< bit: 25..26 saved IT state (read 0) */
+ uint32_t Q:1; /*!< bit: 27 Saturation condition flag */
+ uint32_t V:1; /*!< bit: 28 Overflow condition code flag */
+ uint32_t C:1; /*!< bit: 29 Carry condition code flag */
+ uint32_t Z:1; /*!< bit: 30 Zero condition code flag */
+ uint32_t N:1; /*!< bit: 31 Negative condition code flag */
+ } b; /*!< Structure used for bit access */
+ uint32_t w; /*!< Type used for word access */
+} xPSR_Type;
+
+/* xPSR Register Definitions */
+#define xPSR_N_Pos 31U /*!< xPSR: N Position */
+#define xPSR_N_Msk (1UL << xPSR_N_Pos) /*!< xPSR: N Mask */
+
+#define xPSR_Z_Pos 30U /*!< xPSR: Z Position */
+#define xPSR_Z_Msk (1UL << xPSR_Z_Pos) /*!< xPSR: Z Mask */
+
+#define xPSR_C_Pos 29U /*!< xPSR: C Position */
+#define xPSR_C_Msk (1UL << xPSR_C_Pos) /*!< xPSR: C Mask */
+
+#define xPSR_V_Pos 28U /*!< xPSR: V Position */
+#define xPSR_V_Msk (1UL << xPSR_V_Pos) /*!< xPSR: V Mask */
+
+#define xPSR_Q_Pos 27U /*!< xPSR: Q Position */
+#define xPSR_Q_Msk (1UL << xPSR_Q_Pos) /*!< xPSR: Q Mask */
+
+#define xPSR_IT_Pos 25U /*!< xPSR: IT Position */
+#define xPSR_IT_Msk (3UL << xPSR_IT_Pos) /*!< xPSR: IT Mask */
+
+#define xPSR_T_Pos 24U /*!< xPSR: T Position */
+#define xPSR_T_Msk (1UL << xPSR_T_Pos) /*!< xPSR: T Mask */
+
+#define xPSR_ISR_Pos 0U /*!< xPSR: ISR Position */
+#define xPSR_ISR_Msk (0x1FFUL /*<< xPSR_ISR_Pos*/) /*!< xPSR: ISR Mask */
+
+
+/**
+ \brief Union type to access the Control Registers (CONTROL).
+ */
+typedef union
+{
+ struct
+ {
+ uint32_t nPRIV:1; /*!< bit: 0 Execution privilege in Thread mode */
+ uint32_t SPSEL:1; /*!< bit: 1 Stack to be used */
+ uint32_t _reserved1:30; /*!< bit: 2..31 Reserved */
+ } b; /*!< Structure used for bit access */
+ uint32_t w; /*!< Type used for word access */
+} CONTROL_Type;
+
+/* CONTROL Register Definitions */
+#define CONTROL_SPSEL_Pos 1U /*!< CONTROL: SPSEL Position */
+#define CONTROL_SPSEL_Msk (1UL << CONTROL_SPSEL_Pos) /*!< CONTROL: SPSEL Mask */
+
+#define CONTROL_nPRIV_Pos 0U /*!< CONTROL: nPRIV Position */
+#define CONTROL_nPRIV_Msk (1UL /*<< CONTROL_nPRIV_Pos*/) /*!< CONTROL: nPRIV Mask */
+
+/*@} end of group CMSIS_CORE */
+
+
+/**
+ \ingroup CMSIS_core_register
+ \defgroup CMSIS_NVIC Nested Vectored Interrupt Controller (NVIC)
+ \brief Type definitions for the NVIC Registers
+ @{
+ */
+
+/**
+ \brief Structure type to access the Nested Vectored Interrupt Controller (NVIC).
+ */
+typedef struct
+{
+ __IOM uint32_t ISER[8U]; /*!< Offset: 0x000 (R/W) Interrupt Set Enable Register */
+ uint32_t RESERVED0[24U];
+ __IOM uint32_t ICER[8U]; /*!< Offset: 0x080 (R/W) Interrupt Clear Enable Register */
+ uint32_t RSERVED1[24U];
+ __IOM uint32_t ISPR[8U]; /*!< Offset: 0x100 (R/W) Interrupt Set Pending Register */
+ uint32_t RESERVED2[24U];
+ __IOM uint32_t ICPR[8U]; /*!< Offset: 0x180 (R/W) Interrupt Clear Pending Register */
+ uint32_t RESERVED3[24U];
+ __IOM uint32_t IABR[8U]; /*!< Offset: 0x200 (R/W) Interrupt Active bit Register */
+ uint32_t RESERVED4[56U];
+ __IOM uint8_t IP[240U]; /*!< Offset: 0x300 (R/W) Interrupt Priority Register (8Bit wide) */
+ uint32_t RESERVED5[644U];
+ __OM uint32_t STIR; /*!< Offset: 0xE00 ( /W) Software Trigger Interrupt Register */
+} NVIC_Type;
+
+/* Software Triggered Interrupt Register Definitions */
+#define NVIC_STIR_INTID_Pos 0U /*!< STIR: INTLINESNUM Position */
+#define NVIC_STIR_INTID_Msk (0x1FFUL /*<< NVIC_STIR_INTID_Pos*/) /*!< STIR: INTLINESNUM Mask */
+
+/*@} end of group CMSIS_NVIC */
+
+
+/**
+ \ingroup CMSIS_core_register
+ \defgroup CMSIS_SCB System Control Block (SCB)
+ \brief Type definitions for the System Control Block Registers
+ @{
+ */
+
+/**
+ \brief Structure type to access the System Control Block (SCB).
+ */
+typedef struct
+{
+ __IM uint32_t CPUID; /*!< Offset: 0x000 (R/ ) CPUID Base Register */
+ __IOM uint32_t ICSR; /*!< Offset: 0x004 (R/W) Interrupt Control and State Register */
+ __IOM uint32_t VTOR; /*!< Offset: 0x008 (R/W) Vector Table Offset Register */
+ __IOM uint32_t AIRCR; /*!< Offset: 0x00C (R/W) Application Interrupt and Reset Control Register */
+ __IOM uint32_t SCR; /*!< Offset: 0x010 (R/W) System Control Register */
+ __IOM uint32_t CCR; /*!< Offset: 0x014 (R/W) Configuration Control Register */
+ __IOM uint8_t SHP[12U]; /*!< Offset: 0x018 (R/W) System Handlers Priority Registers (4-7, 8-11, 12-15) */
+ __IOM uint32_t SHCSR; /*!< Offset: 0x024 (R/W) System Handler Control and State Register */
+ __IOM uint32_t CFSR; /*!< Offset: 0x028 (R/W) Configurable Fault Status Register */
+ __IOM uint32_t HFSR; /*!< Offset: 0x02C (R/W) HardFault Status Register */
+ __IOM uint32_t DFSR; /*!< Offset: 0x030 (R/W) Debug Fault Status Register */
+ __IOM uint32_t MMFAR; /*!< Offset: 0x034 (R/W) MemManage Fault Address Register */
+ __IOM uint32_t BFAR; /*!< Offset: 0x038 (R/W) BusFault Address Register */
+ __IOM uint32_t AFSR; /*!< Offset: 0x03C (R/W) Auxiliary Fault Status Register */
+ __IM uint32_t PFR[2U]; /*!< Offset: 0x040 (R/ ) Processor Feature Register */
+ __IM uint32_t DFR; /*!< Offset: 0x048 (R/ ) Debug Feature Register */
+ __IM uint32_t ADR; /*!< Offset: 0x04C (R/ ) Auxiliary Feature Register */
+ __IM uint32_t MMFR[4U]; /*!< Offset: 0x050 (R/ ) Memory Model Feature Register */
+ __IM uint32_t ISAR[5U]; /*!< Offset: 0x060 (R/ ) Instruction Set Attributes Register */
+ uint32_t RESERVED0[5U];
+ __IOM uint32_t CPACR; /*!< Offset: 0x088 (R/W) Coprocessor Access Control Register */
+} SCB_Type;
+
+/* SCB CPUID Register Definitions */
+#define SCB_CPUID_IMPLEMENTER_Pos 24U /*!< SCB CPUID: IMPLEMENTER Position */
+#define SCB_CPUID_IMPLEMENTER_Msk (0xFFUL << SCB_CPUID_IMPLEMENTER_Pos) /*!< SCB CPUID: IMPLEMENTER Mask */
+
+#define SCB_CPUID_VARIANT_Pos 20U /*!< SCB CPUID: VARIANT Position */
+#define SCB_CPUID_VARIANT_Msk (0xFUL << SCB_CPUID_VARIANT_Pos) /*!< SCB CPUID: VARIANT Mask */
+
+#define SCB_CPUID_ARCHITECTURE_Pos 16U /*!< SCB CPUID: ARCHITECTURE Position */
+#define SCB_CPUID_ARCHITECTURE_Msk (0xFUL << SCB_CPUID_ARCHITECTURE_Pos) /*!< SCB CPUID: ARCHITECTURE Mask */
+
+#define SCB_CPUID_PARTNO_Pos 4U /*!< SCB CPUID: PARTNO Position */
+#define SCB_CPUID_PARTNO_Msk (0xFFFUL << SCB_CPUID_PARTNO_Pos) /*!< SCB CPUID: PARTNO Mask */
+
+#define SCB_CPUID_REVISION_Pos 0U /*!< SCB CPUID: REVISION Position */
+#define SCB_CPUID_REVISION_Msk (0xFUL /*<< SCB_CPUID_REVISION_Pos*/) /*!< SCB CPUID: REVISION Mask */
+
+/* SCB Interrupt Control State Register Definitions */
+#define SCB_ICSR_NMIPENDSET_Pos 31U /*!< SCB ICSR: NMIPENDSET Position */
+#define SCB_ICSR_NMIPENDSET_Msk (1UL << SCB_ICSR_NMIPENDSET_Pos) /*!< SCB ICSR: NMIPENDSET Mask */
+
+#define SCB_ICSR_PENDSVSET_Pos 28U /*!< SCB ICSR: PENDSVSET Position */
+#define SCB_ICSR_PENDSVSET_Msk (1UL << SCB_ICSR_PENDSVSET_Pos) /*!< SCB ICSR: PENDSVSET Mask */
+
+#define SCB_ICSR_PENDSVCLR_Pos 27U /*!< SCB ICSR: PENDSVCLR Position */
+#define SCB_ICSR_PENDSVCLR_Msk (1UL << SCB_ICSR_PENDSVCLR_Pos) /*!< SCB ICSR: PENDSVCLR Mask */
+
+#define SCB_ICSR_PENDSTSET_Pos 26U /*!< SCB ICSR: PENDSTSET Position */
+#define SCB_ICSR_PENDSTSET_Msk (1UL << SCB_ICSR_PENDSTSET_Pos) /*!< SCB ICSR: PENDSTSET Mask */
+
+#define SCB_ICSR_PENDSTCLR_Pos 25U /*!< SCB ICSR: PENDSTCLR Position */
+#define SCB_ICSR_PENDSTCLR_Msk (1UL << SCB_ICSR_PENDSTCLR_Pos) /*!< SCB ICSR: PENDSTCLR Mask */
+
+#define SCB_ICSR_ISRPREEMPT_Pos 23U /*!< SCB ICSR: ISRPREEMPT Position */
+#define SCB_ICSR_ISRPREEMPT_Msk (1UL << SCB_ICSR_ISRPREEMPT_Pos) /*!< SCB ICSR: ISRPREEMPT Mask */
+
+#define SCB_ICSR_ISRPENDING_Pos 22U /*!< SCB ICSR: ISRPENDING Position */
+#define SCB_ICSR_ISRPENDING_Msk (1UL << SCB_ICSR_ISRPENDING_Pos) /*!< SCB ICSR: ISRPENDING Mask */
+
+#define SCB_ICSR_VECTPENDING_Pos 12U /*!< SCB ICSR: VECTPENDING Position */
+#define SCB_ICSR_VECTPENDING_Msk (0x1FFUL << SCB_ICSR_VECTPENDING_Pos) /*!< SCB ICSR: VECTPENDING Mask */
+
+#define SCB_ICSR_RETTOBASE_Pos 11U /*!< SCB ICSR: RETTOBASE Position */
+#define SCB_ICSR_RETTOBASE_Msk (1UL << SCB_ICSR_RETTOBASE_Pos) /*!< SCB ICSR: RETTOBASE Mask */
+
+#define SCB_ICSR_VECTACTIVE_Pos 0U /*!< SCB ICSR: VECTACTIVE Position */
+#define SCB_ICSR_VECTACTIVE_Msk (0x1FFUL /*<< SCB_ICSR_VECTACTIVE_Pos*/) /*!< SCB ICSR: VECTACTIVE Mask */
+
+/* SCB Vector Table Offset Register Definitions */
+#if (__CM3_REV < 0x0201U) /* core r2p1 */
+#define SCB_VTOR_TBLBASE_Pos 29U /*!< SCB VTOR: TBLBASE Position */
+#define SCB_VTOR_TBLBASE_Msk (1UL << SCB_VTOR_TBLBASE_Pos) /*!< SCB VTOR: TBLBASE Mask */
+
+#define SCB_VTOR_TBLOFF_Pos 7U /*!< SCB VTOR: TBLOFF Position */
+#define SCB_VTOR_TBLOFF_Msk (0x3FFFFFUL << SCB_VTOR_TBLOFF_Pos) /*!< SCB VTOR: TBLOFF Mask */
+#else
+#define SCB_VTOR_TBLOFF_Pos 7U /*!< SCB VTOR: TBLOFF Position */
+#define SCB_VTOR_TBLOFF_Msk (0x1FFFFFFUL << SCB_VTOR_TBLOFF_Pos) /*!< SCB VTOR: TBLOFF Mask */
+#endif
+
+/* SCB Application Interrupt and Reset Control Register Definitions */
+#define SCB_AIRCR_VECTKEY_Pos 16U /*!< SCB AIRCR: VECTKEY Position */
+#define SCB_AIRCR_VECTKEY_Msk (0xFFFFUL << SCB_AIRCR_VECTKEY_Pos) /*!< SCB AIRCR: VECTKEY Mask */
+
+#define SCB_AIRCR_VECTKEYSTAT_Pos 16U /*!< SCB AIRCR: VECTKEYSTAT Position */
+#define SCB_AIRCR_VECTKEYSTAT_Msk (0xFFFFUL << SCB_AIRCR_VECTKEYSTAT_Pos) /*!< SCB AIRCR: VECTKEYSTAT Mask */
+
+#define SCB_AIRCR_ENDIANESS_Pos 15U /*!< SCB AIRCR: ENDIANESS Position */
+#define SCB_AIRCR_ENDIANESS_Msk (1UL << SCB_AIRCR_ENDIANESS_Pos) /*!< SCB AIRCR: ENDIANESS Mask */
+
+#define SCB_AIRCR_PRIGROUP_Pos 8U /*!< SCB AIRCR: PRIGROUP Position */
+#define SCB_AIRCR_PRIGROUP_Msk (7UL << SCB_AIRCR_PRIGROUP_Pos) /*!< SCB AIRCR: PRIGROUP Mask */
+
+#define SCB_AIRCR_SYSRESETREQ_Pos 2U /*!< SCB AIRCR: SYSRESETREQ Position */
+#define SCB_AIRCR_SYSRESETREQ_Msk (1UL << SCB_AIRCR_SYSRESETREQ_Pos) /*!< SCB AIRCR: SYSRESETREQ Mask */
+
+#define SCB_AIRCR_VECTCLRACTIVE_Pos 1U /*!< SCB AIRCR: VECTCLRACTIVE Position */
+#define SCB_AIRCR_VECTCLRACTIVE_Msk (1UL << SCB_AIRCR_VECTCLRACTIVE_Pos) /*!< SCB AIRCR: VECTCLRACTIVE Mask */
+
+#define SCB_AIRCR_VECTRESET_Pos 0U /*!< SCB AIRCR: VECTRESET Position */
+#define SCB_AIRCR_VECTRESET_Msk (1UL /*<< SCB_AIRCR_VECTRESET_Pos*/) /*!< SCB AIRCR: VECTRESET Mask */
+
+/* SCB System Control Register Definitions */
+#define SCB_SCR_SEVONPEND_Pos 4U /*!< SCB SCR: SEVONPEND Position */
+#define SCB_SCR_SEVONPEND_Msk (1UL << SCB_SCR_SEVONPEND_Pos) /*!< SCB SCR: SEVONPEND Mask */
+
+#define SCB_SCR_SLEEPDEEP_Pos 2U /*!< SCB SCR: SLEEPDEEP Position */
+#define SCB_SCR_SLEEPDEEP_Msk (1UL << SCB_SCR_SLEEPDEEP_Pos) /*!< SCB SCR: SLEEPDEEP Mask */
+
+#define SCB_SCR_SLEEPONEXIT_Pos 1U /*!< SCB SCR: SLEEPONEXIT Position */
+#define SCB_SCR_SLEEPONEXIT_Msk (1UL << SCB_SCR_SLEEPONEXIT_Pos) /*!< SCB SCR: SLEEPONEXIT Mask */
+
+/* SCB Configuration Control Register Definitions */
+#define SCB_CCR_STKALIGN_Pos 9U /*!< SCB CCR: STKALIGN Position */
+#define SCB_CCR_STKALIGN_Msk (1UL << SCB_CCR_STKALIGN_Pos) /*!< SCB CCR: STKALIGN Mask */
+
+#define SCB_CCR_BFHFNMIGN_Pos 8U /*!< SCB CCR: BFHFNMIGN Position */
+#define SCB_CCR_BFHFNMIGN_Msk (1UL << SCB_CCR_BFHFNMIGN_Pos) /*!< SCB CCR: BFHFNMIGN Mask */
+
+#define SCB_CCR_DIV_0_TRP_Pos 4U /*!< SCB CCR: DIV_0_TRP Position */
+#define SCB_CCR_DIV_0_TRP_Msk (1UL << SCB_CCR_DIV_0_TRP_Pos) /*!< SCB CCR: DIV_0_TRP Mask */
+
+#define SCB_CCR_UNALIGN_TRP_Pos 3U /*!< SCB CCR: UNALIGN_TRP Position */
+#define SCB_CCR_UNALIGN_TRP_Msk (1UL << SCB_CCR_UNALIGN_TRP_Pos) /*!< SCB CCR: UNALIGN_TRP Mask */
+
+#define SCB_CCR_USERSETMPEND_Pos 1U /*!< SCB CCR: USERSETMPEND Position */
+#define SCB_CCR_USERSETMPEND_Msk (1UL << SCB_CCR_USERSETMPEND_Pos) /*!< SCB CCR: USERSETMPEND Mask */
+
+#define SCB_CCR_NONBASETHRDENA_Pos 0U /*!< SCB CCR: NONBASETHRDENA Position */
+#define SCB_CCR_NONBASETHRDENA_Msk (1UL /*<< SCB_CCR_NONBASETHRDENA_Pos*/) /*!< SCB CCR: NONBASETHRDENA Mask */
+
+/* SCB System Handler Control and State Register Definitions */
+#define SCB_SHCSR_USGFAULTENA_Pos 18U /*!< SCB SHCSR: USGFAULTENA Position */
+#define SCB_SHCSR_USGFAULTENA_Msk (1UL << SCB_SHCSR_USGFAULTENA_Pos) /*!< SCB SHCSR: USGFAULTENA Mask */
+
+#define SCB_SHCSR_BUSFAULTENA_Pos 17U /*!< SCB SHCSR: BUSFAULTENA Position */
+#define SCB_SHCSR_BUSFAULTENA_Msk (1UL << SCB_SHCSR_BUSFAULTENA_Pos) /*!< SCB SHCSR: BUSFAULTENA Mask */
+
+#define SCB_SHCSR_MEMFAULTENA_Pos 16U /*!< SCB SHCSR: MEMFAULTENA Position */
+#define SCB_SHCSR_MEMFAULTENA_Msk (1UL << SCB_SHCSR_MEMFAULTENA_Pos) /*!< SCB SHCSR: MEMFAULTENA Mask */
+
+#define SCB_SHCSR_SVCALLPENDED_Pos 15U /*!< SCB SHCSR: SVCALLPENDED Position */
+#define SCB_SHCSR_SVCALLPENDED_Msk (1UL << SCB_SHCSR_SVCALLPENDED_Pos) /*!< SCB SHCSR: SVCALLPENDED Mask */
+
+#define SCB_SHCSR_BUSFAULTPENDED_Pos 14U /*!< SCB SHCSR: BUSFAULTPENDED Position */
+#define SCB_SHCSR_BUSFAULTPENDED_Msk (1UL << SCB_SHCSR_BUSFAULTPENDED_Pos) /*!< SCB SHCSR: BUSFAULTPENDED Mask */
+
+#define SCB_SHCSR_MEMFAULTPENDED_Pos 13U /*!< SCB SHCSR: MEMFAULTPENDED Position */
+#define SCB_SHCSR_MEMFAULTPENDED_Msk (1UL << SCB_SHCSR_MEMFAULTPENDED_Pos) /*!< SCB SHCSR: MEMFAULTPENDED Mask */
+
+#define SCB_SHCSR_USGFAULTPENDED_Pos 12U /*!< SCB SHCSR: USGFAULTPENDED Position */
+#define SCB_SHCSR_USGFAULTPENDED_Msk (1UL << SCB_SHCSR_USGFAULTPENDED_Pos) /*!< SCB SHCSR: USGFAULTPENDED Mask */
+
+#define SCB_SHCSR_SYSTICKACT_Pos 11U /*!< SCB SHCSR: SYSTICKACT Position */
+#define SCB_SHCSR_SYSTICKACT_Msk (1UL << SCB_SHCSR_SYSTICKACT_Pos) /*!< SCB SHCSR: SYSTICKACT Mask */
+
+#define SCB_SHCSR_PENDSVACT_Pos 10U /*!< SCB SHCSR: PENDSVACT Position */
+#define SCB_SHCSR_PENDSVACT_Msk (1UL << SCB_SHCSR_PENDSVACT_Pos) /*!< SCB SHCSR: PENDSVACT Mask */
+
+#define SCB_SHCSR_MONITORACT_Pos 8U /*!< SCB SHCSR: MONITORACT Position */
+#define SCB_SHCSR_MONITORACT_Msk (1UL << SCB_SHCSR_MONITORACT_Pos) /*!< SCB SHCSR: MONITORACT Mask */
+
+#define SCB_SHCSR_SVCALLACT_Pos 7U /*!< SCB SHCSR: SVCALLACT Position */
+#define SCB_SHCSR_SVCALLACT_Msk (1UL << SCB_SHCSR_SVCALLACT_Pos) /*!< SCB SHCSR: SVCALLACT Mask */
+
+#define SCB_SHCSR_USGFAULTACT_Pos 3U /*!< SCB SHCSR: USGFAULTACT Position */
+#define SCB_SHCSR_USGFAULTACT_Msk (1UL << SCB_SHCSR_USGFAULTACT_Pos) /*!< SCB SHCSR: USGFAULTACT Mask */
+
+#define SCB_SHCSR_BUSFAULTACT_Pos 1U /*!< SCB SHCSR: BUSFAULTACT Position */
+#define SCB_SHCSR_BUSFAULTACT_Msk (1UL << SCB_SHCSR_BUSFAULTACT_Pos) /*!< SCB SHCSR: BUSFAULTACT Mask */
+
+#define SCB_SHCSR_MEMFAULTACT_Pos 0U /*!< SCB SHCSR: MEMFAULTACT Position */
+#define SCB_SHCSR_MEMFAULTACT_Msk (1UL /*<< SCB_SHCSR_MEMFAULTACT_Pos*/) /*!< SCB SHCSR: MEMFAULTACT Mask */
+
+/* SCB Configurable Fault Status Register Definitions */
+#define SCB_CFSR_USGFAULTSR_Pos 16U /*!< SCB CFSR: Usage Fault Status Register Position */
+#define SCB_CFSR_USGFAULTSR_Msk (0xFFFFUL << SCB_CFSR_USGFAULTSR_Pos) /*!< SCB CFSR: Usage Fault Status Register Mask */
+
+#define SCB_CFSR_BUSFAULTSR_Pos 8U /*!< SCB CFSR: Bus Fault Status Register Position */
+#define SCB_CFSR_BUSFAULTSR_Msk (0xFFUL << SCB_CFSR_BUSFAULTSR_Pos) /*!< SCB CFSR: Bus Fault Status Register Mask */
+
+#define SCB_CFSR_MEMFAULTSR_Pos 0U /*!< SCB CFSR: Memory Manage Fault Status Register Position */
+#define SCB_CFSR_MEMFAULTSR_Msk (0xFFUL /*<< SCB_CFSR_MEMFAULTSR_Pos*/) /*!< SCB CFSR: Memory Manage Fault Status Register Mask */
+
+/* SCB Hard Fault Status Register Definitions */
+#define SCB_HFSR_DEBUGEVT_Pos 31U /*!< SCB HFSR: DEBUGEVT Position */
+#define SCB_HFSR_DEBUGEVT_Msk (1UL << SCB_HFSR_DEBUGEVT_Pos) /*!< SCB HFSR: DEBUGEVT Mask */
+
+#define SCB_HFSR_FORCED_Pos 30U /*!< SCB HFSR: FORCED Position */
+#define SCB_HFSR_FORCED_Msk (1UL << SCB_HFSR_FORCED_Pos) /*!< SCB HFSR: FORCED Mask */
+
+#define SCB_HFSR_VECTTBL_Pos 1U /*!< SCB HFSR: VECTTBL Position */
+#define SCB_HFSR_VECTTBL_Msk (1UL << SCB_HFSR_VECTTBL_Pos) /*!< SCB HFSR: VECTTBL Mask */
+
+/* SCB Debug Fault Status Register Definitions */
+#define SCB_DFSR_EXTERNAL_Pos 4U /*!< SCB DFSR: EXTERNAL Position */
+#define SCB_DFSR_EXTERNAL_Msk (1UL << SCB_DFSR_EXTERNAL_Pos) /*!< SCB DFSR: EXTERNAL Mask */
+
+#define SCB_DFSR_VCATCH_Pos 3U /*!< SCB DFSR: VCATCH Position */
+#define SCB_DFSR_VCATCH_Msk (1UL << SCB_DFSR_VCATCH_Pos) /*!< SCB DFSR: VCATCH Mask */
+
+#define SCB_DFSR_DWTTRAP_Pos 2U /*!< SCB DFSR: DWTTRAP Position */
+#define SCB_DFSR_DWTTRAP_Msk (1UL << SCB_DFSR_DWTTRAP_Pos) /*!< SCB DFSR: DWTTRAP Mask */
+
+#define SCB_DFSR_BKPT_Pos 1U /*!< SCB DFSR: BKPT Position */
+#define SCB_DFSR_BKPT_Msk (1UL << SCB_DFSR_BKPT_Pos) /*!< SCB DFSR: BKPT Mask */
+
+#define SCB_DFSR_HALTED_Pos 0U /*!< SCB DFSR: HALTED Position */
+#define SCB_DFSR_HALTED_Msk (1UL /*<< SCB_DFSR_HALTED_Pos*/) /*!< SCB DFSR: HALTED Mask */
+
+/*@} end of group CMSIS_SCB */
+
+
+/**
+ \ingroup CMSIS_core_register
+ \defgroup CMSIS_SCnSCB System Controls not in SCB (SCnSCB)
+ \brief Type definitions for the System Control and ID Register not in the SCB
+ @{
+ */
+
+/**
+ \brief Structure type to access the System Control and ID Register not in the SCB.
+ */
+typedef struct
+{
+ uint32_t RESERVED0[1U];
+ __IM uint32_t ICTR; /*!< Offset: 0x004 (R/ ) Interrupt Controller Type Register */
+#if ((defined __CM3_REV) && (__CM3_REV >= 0x200U))
+ __IOM uint32_t ACTLR; /*!< Offset: 0x008 (R/W) Auxiliary Control Register */
+#else
+ uint32_t RESERVED1[1U];
+#endif
+} SCnSCB_Type;
+
+/* Interrupt Controller Type Register Definitions */
+#define SCnSCB_ICTR_INTLINESNUM_Pos 0U /*!< ICTR: INTLINESNUM Position */
+#define SCnSCB_ICTR_INTLINESNUM_Msk (0xFUL /*<< SCnSCB_ICTR_INTLINESNUM_Pos*/) /*!< ICTR: INTLINESNUM Mask */
+
+/* Auxiliary Control Register Definitions */
+
+#define SCnSCB_ACTLR_DISFOLD_Pos 2U /*!< ACTLR: DISFOLD Position */
+#define SCnSCB_ACTLR_DISFOLD_Msk (1UL << SCnSCB_ACTLR_DISFOLD_Pos) /*!< ACTLR: DISFOLD Mask */
+
+#define SCnSCB_ACTLR_DISDEFWBUF_Pos 1U /*!< ACTLR: DISDEFWBUF Position */
+#define SCnSCB_ACTLR_DISDEFWBUF_Msk (1UL << SCnSCB_ACTLR_DISDEFWBUF_Pos) /*!< ACTLR: DISDEFWBUF Mask */
+
+#define SCnSCB_ACTLR_DISMCYCINT_Pos 0U /*!< ACTLR: DISMCYCINT Position */
+#define SCnSCB_ACTLR_DISMCYCINT_Msk (1UL /*<< SCnSCB_ACTLR_DISMCYCINT_Pos*/) /*!< ACTLR: DISMCYCINT Mask */
+
+/*@} end of group CMSIS_SCnotSCB */
+
+
+/**
+ \ingroup CMSIS_core_register
+ \defgroup CMSIS_SysTick System Tick Timer (SysTick)
+ \brief Type definitions for the System Timer Registers.
+ @{
+ */
+
+/**
+ \brief Structure type to access the System Timer (SysTick).
+ */
+typedef struct
+{
+ __IOM uint32_t CTRL; /*!< Offset: 0x000 (R/W) SysTick Control and Status Register */
+ __IOM uint32_t LOAD; /*!< Offset: 0x004 (R/W) SysTick Reload Value Register */
+ __IOM uint32_t VAL; /*!< Offset: 0x008 (R/W) SysTick Current Value Register */
+ __IM uint32_t CALIB; /*!< Offset: 0x00C (R/ ) SysTick Calibration Register */
+} SysTick_Type;
+
+/* SysTick Control / Status Register Definitions */
+#define SysTick_CTRL_COUNTFLAG_Pos 16U /*!< SysTick CTRL: COUNTFLAG Position */
+#define SysTick_CTRL_COUNTFLAG_Msk (1UL << SysTick_CTRL_COUNTFLAG_Pos) /*!< SysTick CTRL: COUNTFLAG Mask */
+
+#define SysTick_CTRL_CLKSOURCE_Pos 2U /*!< SysTick CTRL: CLKSOURCE Position */
+#define SysTick_CTRL_CLKSOURCE_Msk (1UL << SysTick_CTRL_CLKSOURCE_Pos) /*!< SysTick CTRL: CLKSOURCE Mask */
+
+#define SysTick_CTRL_TICKINT_Pos 1U /*!< SysTick CTRL: TICKINT Position */
+#define SysTick_CTRL_TICKINT_Msk (1UL << SysTick_CTRL_TICKINT_Pos) /*!< SysTick CTRL: TICKINT Mask */
+
+#define SysTick_CTRL_ENABLE_Pos 0U /*!< SysTick CTRL: ENABLE Position */
+#define SysTick_CTRL_ENABLE_Msk (1UL /*<< SysTick_CTRL_ENABLE_Pos*/) /*!< SysTick CTRL: ENABLE Mask */
+
+/* SysTick Reload Register Definitions */
+#define SysTick_LOAD_RELOAD_Pos 0U /*!< SysTick LOAD: RELOAD Position */
+#define SysTick_LOAD_RELOAD_Msk (0xFFFFFFUL /*<< SysTick_LOAD_RELOAD_Pos*/) /*!< SysTick LOAD: RELOAD Mask */
+
+/* SysTick Current Register Definitions */
+#define SysTick_VAL_CURRENT_Pos 0U /*!< SysTick VAL: CURRENT Position */
+#define SysTick_VAL_CURRENT_Msk (0xFFFFFFUL /*<< SysTick_VAL_CURRENT_Pos*/) /*!< SysTick VAL: CURRENT Mask */
+
+/* SysTick Calibration Register Definitions */
+#define SysTick_CALIB_NOREF_Pos 31U /*!< SysTick CALIB: NOREF Position */
+#define SysTick_CALIB_NOREF_Msk (1UL << SysTick_CALIB_NOREF_Pos) /*!< SysTick CALIB: NOREF Mask */
+
+#define SysTick_CALIB_SKEW_Pos 30U /*!< SysTick CALIB: SKEW Position */
+#define SysTick_CALIB_SKEW_Msk (1UL << SysTick_CALIB_SKEW_Pos) /*!< SysTick CALIB: SKEW Mask */
+
+#define SysTick_CALIB_TENMS_Pos 0U /*!< SysTick CALIB: TENMS Position */
+#define SysTick_CALIB_TENMS_Msk (0xFFFFFFUL /*<< SysTick_CALIB_TENMS_Pos*/) /*!< SysTick CALIB: TENMS Mask */
+
+/*@} end of group CMSIS_SysTick */
+
+
+/**
+ \ingroup CMSIS_core_register
+ \defgroup CMSIS_ITM Instrumentation Trace Macrocell (ITM)
+ \brief Type definitions for the Instrumentation Trace Macrocell (ITM)
+ @{
+ */
+
+/**
+ \brief Structure type to access the Instrumentation Trace Macrocell Register (ITM).
+ */
+typedef struct
+{
+ __OM union
+ {
+ __OM uint8_t u8; /*!< Offset: 0x000 ( /W) ITM Stimulus Port 8-bit */
+ __OM uint16_t u16; /*!< Offset: 0x000 ( /W) ITM Stimulus Port 16-bit */
+ __OM uint32_t u32; /*!< Offset: 0x000 ( /W) ITM Stimulus Port 32-bit */
+ } PORT [32U]; /*!< Offset: 0x000 ( /W) ITM Stimulus Port Registers */
+ uint32_t RESERVED0[864U];
+ __IOM uint32_t TER; /*!< Offset: 0xE00 (R/W) ITM Trace Enable Register */
+ uint32_t RESERVED1[15U];
+ __IOM uint32_t TPR; /*!< Offset: 0xE40 (R/W) ITM Trace Privilege Register */
+ uint32_t RESERVED2[15U];
+ __IOM uint32_t TCR; /*!< Offset: 0xE80 (R/W) ITM Trace Control Register */
+ uint32_t RESERVED3[29U];
+ __OM uint32_t IWR; /*!< Offset: 0xEF8 ( /W) ITM Integration Write Register */
+ __IM uint32_t IRR; /*!< Offset: 0xEFC (R/ ) ITM Integration Read Register */
+ __IOM uint32_t IMCR; /*!< Offset: 0xF00 (R/W) ITM Integration Mode Control Register */
+ uint32_t RESERVED4[43U];
+ __OM uint32_t LAR; /*!< Offset: 0xFB0 ( /W) ITM Lock Access Register */
+ __IM uint32_t LSR; /*!< Offset: 0xFB4 (R/ ) ITM Lock Status Register */
+ uint32_t RESERVED5[6U];
+ __IM uint32_t PID4; /*!< Offset: 0xFD0 (R/ ) ITM Peripheral Identification Register #4 */
+ __IM uint32_t PID5; /*!< Offset: 0xFD4 (R/ ) ITM Peripheral Identification Register #5 */
+ __IM uint32_t PID6; /*!< Offset: 0xFD8 (R/ ) ITM Peripheral Identification Register #6 */
+ __IM uint32_t PID7; /*!< Offset: 0xFDC (R/ ) ITM Peripheral Identification Register #7 */
+ __IM uint32_t PID0; /*!< Offset: 0xFE0 (R/ ) ITM Peripheral Identification Register #0 */
+ __IM uint32_t PID1; /*!< Offset: 0xFE4 (R/ ) ITM Peripheral Identification Register #1 */
+ __IM uint32_t PID2; /*!< Offset: 0xFE8 (R/ ) ITM Peripheral Identification Register #2 */
+ __IM uint32_t PID3; /*!< Offset: 0xFEC (R/ ) ITM Peripheral Identification Register #3 */
+ __IM uint32_t CID0; /*!< Offset: 0xFF0 (R/ ) ITM Component Identification Register #0 */
+ __IM uint32_t CID1; /*!< Offset: 0xFF4 (R/ ) ITM Component Identification Register #1 */
+ __IM uint32_t CID2; /*!< Offset: 0xFF8 (R/ ) ITM Component Identification Register #2 */
+ __IM uint32_t CID3; /*!< Offset: 0xFFC (R/ ) ITM Component Identification Register #3 */
+} ITM_Type;
+
+/* ITM Trace Privilege Register Definitions */
+#define ITM_TPR_PRIVMASK_Pos 0U /*!< ITM TPR: PRIVMASK Position */
+#define ITM_TPR_PRIVMASK_Msk (0xFUL /*<< ITM_TPR_PRIVMASK_Pos*/) /*!< ITM TPR: PRIVMASK Mask */
+
+/* ITM Trace Control Register Definitions */
+#define ITM_TCR_BUSY_Pos 23U /*!< ITM TCR: BUSY Position */
+#define ITM_TCR_BUSY_Msk (1UL << ITM_TCR_BUSY_Pos) /*!< ITM TCR: BUSY Mask */
+
+#define ITM_TCR_TraceBusID_Pos 16U /*!< ITM TCR: ATBID Position */
+#define ITM_TCR_TraceBusID_Msk (0x7FUL << ITM_TCR_TraceBusID_Pos) /*!< ITM TCR: ATBID Mask */
+
+#define ITM_TCR_GTSFREQ_Pos 10U /*!< ITM TCR: Global timestamp frequency Position */
+#define ITM_TCR_GTSFREQ_Msk (3UL << ITM_TCR_GTSFREQ_Pos) /*!< ITM TCR: Global timestamp frequency Mask */
+
+#define ITM_TCR_TSPrescale_Pos 8U /*!< ITM TCR: TSPrescale Position */
+#define ITM_TCR_TSPrescale_Msk (3UL << ITM_TCR_TSPrescale_Pos) /*!< ITM TCR: TSPrescale Mask */
+
+#define ITM_TCR_SWOENA_Pos 4U /*!< ITM TCR: SWOENA Position */
+#define ITM_TCR_SWOENA_Msk (1UL << ITM_TCR_SWOENA_Pos) /*!< ITM TCR: SWOENA Mask */
+
+#define ITM_TCR_DWTENA_Pos 3U /*!< ITM TCR: DWTENA Position */
+#define ITM_TCR_DWTENA_Msk (1UL << ITM_TCR_DWTENA_Pos) /*!< ITM TCR: DWTENA Mask */
+
+#define ITM_TCR_SYNCENA_Pos 2U /*!< ITM TCR: SYNCENA Position */
+#define ITM_TCR_SYNCENA_Msk (1UL << ITM_TCR_SYNCENA_Pos) /*!< ITM TCR: SYNCENA Mask */
+
+#define ITM_TCR_TSENA_Pos 1U /*!< ITM TCR: TSENA Position */
+#define ITM_TCR_TSENA_Msk (1UL << ITM_TCR_TSENA_Pos) /*!< ITM TCR: TSENA Mask */
+
+#define ITM_TCR_ITMENA_Pos 0U /*!< ITM TCR: ITM Enable bit Position */
+#define ITM_TCR_ITMENA_Msk (1UL /*<< ITM_TCR_ITMENA_Pos*/) /*!< ITM TCR: ITM Enable bit Mask */
+
+/* ITM Integration Write Register Definitions */
+#define ITM_IWR_ATVALIDM_Pos 0U /*!< ITM IWR: ATVALIDM Position */
+#define ITM_IWR_ATVALIDM_Msk (1UL /*<< ITM_IWR_ATVALIDM_Pos*/) /*!< ITM IWR: ATVALIDM Mask */
+
+/* ITM Integration Read Register Definitions */
+#define ITM_IRR_ATREADYM_Pos 0U /*!< ITM IRR: ATREADYM Position */
+#define ITM_IRR_ATREADYM_Msk (1UL /*<< ITM_IRR_ATREADYM_Pos*/) /*!< ITM IRR: ATREADYM Mask */
+
+/* ITM Integration Mode Control Register Definitions */
+#define ITM_IMCR_INTEGRATION_Pos 0U /*!< ITM IMCR: INTEGRATION Position */
+#define ITM_IMCR_INTEGRATION_Msk (1UL /*<< ITM_IMCR_INTEGRATION_Pos*/) /*!< ITM IMCR: INTEGRATION Mask */
+
+/* ITM Lock Status Register Definitions */
+#define ITM_LSR_ByteAcc_Pos 2U /*!< ITM LSR: ByteAcc Position */
+#define ITM_LSR_ByteAcc_Msk (1UL << ITM_LSR_ByteAcc_Pos) /*!< ITM LSR: ByteAcc Mask */
+
+#define ITM_LSR_Access_Pos 1U /*!< ITM LSR: Access Position */
+#define ITM_LSR_Access_Msk (1UL << ITM_LSR_Access_Pos) /*!< ITM LSR: Access Mask */
+
+#define ITM_LSR_Present_Pos 0U /*!< ITM LSR: Present Position */
+#define ITM_LSR_Present_Msk (1UL /*<< ITM_LSR_Present_Pos*/) /*!< ITM LSR: Present Mask */
+
+/*@}*/ /* end of group CMSIS_ITM */
+
+
+/**
+ \ingroup CMSIS_core_register
+ \defgroup CMSIS_DWT Data Watchpoint and Trace (DWT)
+ \brief Type definitions for the Data Watchpoint and Trace (DWT)
+ @{
+ */
+
+/**
+ \brief Structure type to access the Data Watchpoint and Trace Register (DWT).
+ */
+typedef struct
+{
+ __IOM uint32_t CTRL; /*!< Offset: 0x000 (R/W) Control Register */
+ __IOM uint32_t CYCCNT; /*!< Offset: 0x004 (R/W) Cycle Count Register */
+ __IOM uint32_t CPICNT; /*!< Offset: 0x008 (R/W) CPI Count Register */
+ __IOM uint32_t EXCCNT; /*!< Offset: 0x00C (R/W) Exception Overhead Count Register */
+ __IOM uint32_t SLEEPCNT; /*!< Offset: 0x010 (R/W) Sleep Count Register */
+ __IOM uint32_t LSUCNT; /*!< Offset: 0x014 (R/W) LSU Count Register */
+ __IOM uint32_t FOLDCNT; /*!< Offset: 0x018 (R/W) Folded-instruction Count Register */
+ __IM uint32_t PCSR; /*!< Offset: 0x01C (R/ ) Program Counter Sample Register */
+ __IOM uint32_t COMP0; /*!< Offset: 0x020 (R/W) Comparator Register 0 */
+ __IOM uint32_t MASK0; /*!< Offset: 0x024 (R/W) Mask Register 0 */
+ __IOM uint32_t FUNCTION0; /*!< Offset: 0x028 (R/W) Function Register 0 */
+ uint32_t RESERVED0[1U];
+ __IOM uint32_t COMP1; /*!< Offset: 0x030 (R/W) Comparator Register 1 */
+ __IOM uint32_t MASK1; /*!< Offset: 0x034 (R/W) Mask Register 1 */
+ __IOM uint32_t FUNCTION1; /*!< Offset: 0x038 (R/W) Function Register 1 */
+ uint32_t RESERVED1[1U];
+ __IOM uint32_t COMP2; /*!< Offset: 0x040 (R/W) Comparator Register 2 */
+ __IOM uint32_t MASK2; /*!< Offset: 0x044 (R/W) Mask Register 2 */
+ __IOM uint32_t FUNCTION2; /*!< Offset: 0x048 (R/W) Function Register 2 */
+ uint32_t RESERVED2[1U];
+ __IOM uint32_t COMP3; /*!< Offset: 0x050 (R/W) Comparator Register 3 */
+ __IOM uint32_t MASK3; /*!< Offset: 0x054 (R/W) Mask Register 3 */
+ __IOM uint32_t FUNCTION3; /*!< Offset: 0x058 (R/W) Function Register 3 */
+} DWT_Type;
+
+/* DWT Control Register Definitions */
+#define DWT_CTRL_NUMCOMP_Pos 28U /*!< DWT CTRL: NUMCOMP Position */
+#define DWT_CTRL_NUMCOMP_Msk (0xFUL << DWT_CTRL_NUMCOMP_Pos) /*!< DWT CTRL: NUMCOMP Mask */
+
+#define DWT_CTRL_NOTRCPKT_Pos 27U /*!< DWT CTRL: NOTRCPKT Position */
+#define DWT_CTRL_NOTRCPKT_Msk (0x1UL << DWT_CTRL_NOTRCPKT_Pos) /*!< DWT CTRL: NOTRCPKT Mask */
+
+#define DWT_CTRL_NOEXTTRIG_Pos 26U /*!< DWT CTRL: NOEXTTRIG Position */
+#define DWT_CTRL_NOEXTTRIG_Msk (0x1UL << DWT_CTRL_NOEXTTRIG_Pos) /*!< DWT CTRL: NOEXTTRIG Mask */
+
+#define DWT_CTRL_NOCYCCNT_Pos 25U /*!< DWT CTRL: NOCYCCNT Position */
+#define DWT_CTRL_NOCYCCNT_Msk (0x1UL << DWT_CTRL_NOCYCCNT_Pos) /*!< DWT CTRL: NOCYCCNT Mask */
+
+#define DWT_CTRL_NOPRFCNT_Pos 24U /*!< DWT CTRL: NOPRFCNT Position */
+#define DWT_CTRL_NOPRFCNT_Msk (0x1UL << DWT_CTRL_NOPRFCNT_Pos) /*!< DWT CTRL: NOPRFCNT Mask */
+
+#define DWT_CTRL_CYCEVTENA_Pos 22U /*!< DWT CTRL: CYCEVTENA Position */
+#define DWT_CTRL_CYCEVTENA_Msk (0x1UL << DWT_CTRL_CYCEVTENA_Pos) /*!< DWT CTRL: CYCEVTENA Mask */
+
+#define DWT_CTRL_FOLDEVTENA_Pos 21U /*!< DWT CTRL: FOLDEVTENA Position */
+#define DWT_CTRL_FOLDEVTENA_Msk (0x1UL << DWT_CTRL_FOLDEVTENA_Pos) /*!< DWT CTRL: FOLDEVTENA Mask */
+
+#define DWT_CTRL_LSUEVTENA_Pos 20U /*!< DWT CTRL: LSUEVTENA Position */
+#define DWT_CTRL_LSUEVTENA_Msk (0x1UL << DWT_CTRL_LSUEVTENA_Pos) /*!< DWT CTRL: LSUEVTENA Mask */
+
+#define DWT_CTRL_SLEEPEVTENA_Pos 19U /*!< DWT CTRL: SLEEPEVTENA Position */
+#define DWT_CTRL_SLEEPEVTENA_Msk (0x1UL << DWT_CTRL_SLEEPEVTENA_Pos) /*!< DWT CTRL: SLEEPEVTENA Mask */
+
+#define DWT_CTRL_EXCEVTENA_Pos 18U /*!< DWT CTRL: EXCEVTENA Position */
+#define DWT_CTRL_EXCEVTENA_Msk (0x1UL << DWT_CTRL_EXCEVTENA_Pos) /*!< DWT CTRL: EXCEVTENA Mask */
+
+#define DWT_CTRL_CPIEVTENA_Pos 17U /*!< DWT CTRL: CPIEVTENA Position */
+#define DWT_CTRL_CPIEVTENA_Msk (0x1UL << DWT_CTRL_CPIEVTENA_Pos) /*!< DWT CTRL: CPIEVTENA Mask */
+
+#define DWT_CTRL_EXCTRCENA_Pos 16U /*!< DWT CTRL: EXCTRCENA Position */
+#define DWT_CTRL_EXCTRCENA_Msk (0x1UL << DWT_CTRL_EXCTRCENA_Pos) /*!< DWT CTRL: EXCTRCENA Mask */
+
+#define DWT_CTRL_PCSAMPLENA_Pos 12U /*!< DWT CTRL: PCSAMPLENA Position */
+#define DWT_CTRL_PCSAMPLENA_Msk (0x1UL << DWT_CTRL_PCSAMPLENA_Pos) /*!< DWT CTRL: PCSAMPLENA Mask */
+
+#define DWT_CTRL_SYNCTAP_Pos 10U /*!< DWT CTRL: SYNCTAP Position */
+#define DWT_CTRL_SYNCTAP_Msk (0x3UL << DWT_CTRL_SYNCTAP_Pos) /*!< DWT CTRL: SYNCTAP Mask */
+
+#define DWT_CTRL_CYCTAP_Pos 9U /*!< DWT CTRL: CYCTAP Position */
+#define DWT_CTRL_CYCTAP_Msk (0x1UL << DWT_CTRL_CYCTAP_Pos) /*!< DWT CTRL: CYCTAP Mask */
+
+#define DWT_CTRL_POSTINIT_Pos 5U /*!< DWT CTRL: POSTINIT Position */
+#define DWT_CTRL_POSTINIT_Msk (0xFUL << DWT_CTRL_POSTINIT_Pos) /*!< DWT CTRL: POSTINIT Mask */
+
+#define DWT_CTRL_POSTPRESET_Pos 1U /*!< DWT CTRL: POSTPRESET Position */
+#define DWT_CTRL_POSTPRESET_Msk (0xFUL << DWT_CTRL_POSTPRESET_Pos) /*!< DWT CTRL: POSTPRESET Mask */
+
+#define DWT_CTRL_CYCCNTENA_Pos 0U /*!< DWT CTRL: CYCCNTENA Position */
+#define DWT_CTRL_CYCCNTENA_Msk (0x1UL /*<< DWT_CTRL_CYCCNTENA_Pos*/) /*!< DWT CTRL: CYCCNTENA Mask */
+
+/* DWT CPI Count Register Definitions */
+#define DWT_CPICNT_CPICNT_Pos 0U /*!< DWT CPICNT: CPICNT Position */
+#define DWT_CPICNT_CPICNT_Msk (0xFFUL /*<< DWT_CPICNT_CPICNT_Pos*/) /*!< DWT CPICNT: CPICNT Mask */
+
+/* DWT Exception Overhead Count Register Definitions */
+#define DWT_EXCCNT_EXCCNT_Pos 0U /*!< DWT EXCCNT: EXCCNT Position */
+#define DWT_EXCCNT_EXCCNT_Msk (0xFFUL /*<< DWT_EXCCNT_EXCCNT_Pos*/) /*!< DWT EXCCNT: EXCCNT Mask */
+
+/* DWT Sleep Count Register Definitions */
+#define DWT_SLEEPCNT_SLEEPCNT_Pos 0U /*!< DWT SLEEPCNT: SLEEPCNT Position */
+#define DWT_SLEEPCNT_SLEEPCNT_Msk (0xFFUL /*<< DWT_SLEEPCNT_SLEEPCNT_Pos*/) /*!< DWT SLEEPCNT: SLEEPCNT Mask */
+
+/* DWT LSU Count Register Definitions */
+#define DWT_LSUCNT_LSUCNT_Pos 0U /*!< DWT LSUCNT: LSUCNT Position */
+#define DWT_LSUCNT_LSUCNT_Msk (0xFFUL /*<< DWT_LSUCNT_LSUCNT_Pos*/) /*!< DWT LSUCNT: LSUCNT Mask */
+
+/* DWT Folded-instruction Count Register Definitions */
+#define DWT_FOLDCNT_FOLDCNT_Pos 0U /*!< DWT FOLDCNT: FOLDCNT Position */
+#define DWT_FOLDCNT_FOLDCNT_Msk (0xFFUL /*<< DWT_FOLDCNT_FOLDCNT_Pos*/) /*!< DWT FOLDCNT: FOLDCNT Mask */
+
+/* DWT Comparator Mask Register Definitions */
+#define DWT_MASK_MASK_Pos 0U /*!< DWT MASK: MASK Position */
+#define DWT_MASK_MASK_Msk (0x1FUL /*<< DWT_MASK_MASK_Pos*/) /*!< DWT MASK: MASK Mask */
+
+/* DWT Comparator Function Register Definitions */
+#define DWT_FUNCTION_MATCHED_Pos 24U /*!< DWT FUNCTION: MATCHED Position */
+#define DWT_FUNCTION_MATCHED_Msk (0x1UL << DWT_FUNCTION_MATCHED_Pos) /*!< DWT FUNCTION: MATCHED Mask */
+
+#define DWT_FUNCTION_DATAVADDR1_Pos 16U /*!< DWT FUNCTION: DATAVADDR1 Position */
+#define DWT_FUNCTION_DATAVADDR1_Msk (0xFUL << DWT_FUNCTION_DATAVADDR1_Pos) /*!< DWT FUNCTION: DATAVADDR1 Mask */
+
+#define DWT_FUNCTION_DATAVADDR0_Pos 12U /*!< DWT FUNCTION: DATAVADDR0 Position */
+#define DWT_FUNCTION_DATAVADDR0_Msk (0xFUL << DWT_FUNCTION_DATAVADDR0_Pos) /*!< DWT FUNCTION: DATAVADDR0 Mask */
+
+#define DWT_FUNCTION_DATAVSIZE_Pos 10U /*!< DWT FUNCTION: DATAVSIZE Position */
+#define DWT_FUNCTION_DATAVSIZE_Msk (0x3UL << DWT_FUNCTION_DATAVSIZE_Pos) /*!< DWT FUNCTION: DATAVSIZE Mask */
+
+#define DWT_FUNCTION_LNK1ENA_Pos 9U /*!< DWT FUNCTION: LNK1ENA Position */
+#define DWT_FUNCTION_LNK1ENA_Msk (0x1UL << DWT_FUNCTION_LNK1ENA_Pos) /*!< DWT FUNCTION: LNK1ENA Mask */
+
+#define DWT_FUNCTION_DATAVMATCH_Pos 8U /*!< DWT FUNCTION: DATAVMATCH Position */
+#define DWT_FUNCTION_DATAVMATCH_Msk (0x1UL << DWT_FUNCTION_DATAVMATCH_Pos) /*!< DWT FUNCTION: DATAVMATCH Mask */
+
+#define DWT_FUNCTION_CYCMATCH_Pos 7U /*!< DWT FUNCTION: CYCMATCH Position */
+#define DWT_FUNCTION_CYCMATCH_Msk (0x1UL << DWT_FUNCTION_CYCMATCH_Pos) /*!< DWT FUNCTION: CYCMATCH Mask */
+
+#define DWT_FUNCTION_EMITRANGE_Pos 5U /*!< DWT FUNCTION: EMITRANGE Position */
+#define DWT_FUNCTION_EMITRANGE_Msk (0x1UL << DWT_FUNCTION_EMITRANGE_Pos) /*!< DWT FUNCTION: EMITRANGE Mask */
+
+#define DWT_FUNCTION_FUNCTION_Pos 0U /*!< DWT FUNCTION: FUNCTION Position */
+#define DWT_FUNCTION_FUNCTION_Msk (0xFUL /*<< DWT_FUNCTION_FUNCTION_Pos*/) /*!< DWT FUNCTION: FUNCTION Mask */
+
+/*@}*/ /* end of group CMSIS_DWT */
+
+
+/**
+ \ingroup CMSIS_core_register
+ \defgroup CMSIS_TPI Trace Port Interface (TPI)
+ \brief Type definitions for the Trace Port Interface (TPI)
+ @{
+ */
+
+/**
+ \brief Structure type to access the Trace Port Interface Register (TPI).
+ */
+typedef struct
+{
+ __IOM uint32_t SSPSR; /*!< Offset: 0x000 (R/ ) Supported Parallel Port Size Register */
+ __IOM uint32_t CSPSR; /*!< Offset: 0x004 (R/W) Current Parallel Port Size Register */
+ uint32_t RESERVED0[2U];
+ __IOM uint32_t ACPR; /*!< Offset: 0x010 (R/W) Asynchronous Clock Prescaler Register */
+ uint32_t RESERVED1[55U];
+ __IOM uint32_t SPPR; /*!< Offset: 0x0F0 (R/W) Selected Pin Protocol Register */
+ uint32_t RESERVED2[131U];
+ __IM uint32_t FFSR; /*!< Offset: 0x300 (R/ ) Formatter and Flush Status Register */
+ __IOM uint32_t FFCR; /*!< Offset: 0x304 (R/W) Formatter and Flush Control Register */
+ __IM uint32_t FSCR; /*!< Offset: 0x308 (R/ ) Formatter Synchronization Counter Register */
+ uint32_t RESERVED3[759U];
+ __IM uint32_t TRIGGER; /*!< Offset: 0xEE8 (R/ ) TRIGGER */
+ __IM uint32_t FIFO0; /*!< Offset: 0xEEC (R/ ) Integration ETM Data */
+ __IM uint32_t ITATBCTR2; /*!< Offset: 0xEF0 (R/ ) ITATBCTR2 */
+ uint32_t RESERVED4[1U];
+ __IM uint32_t ITATBCTR0; /*!< Offset: 0xEF8 (R/ ) ITATBCTR0 */
+ __IM uint32_t FIFO1; /*!< Offset: 0xEFC (R/ ) Integration ITM Data */
+ __IOM uint32_t ITCTRL; /*!< Offset: 0xF00 (R/W) Integration Mode Control */
+ uint32_t RESERVED5[39U];
+ __IOM uint32_t CLAIMSET; /*!< Offset: 0xFA0 (R/W) Claim tag set */
+ __IOM uint32_t CLAIMCLR; /*!< Offset: 0xFA4 (R/W) Claim tag clear */
+ uint32_t RESERVED7[8U];
+ __IM uint32_t DEVID; /*!< Offset: 0xFC8 (R/ ) TPIU_DEVID */
+ __IM uint32_t DEVTYPE; /*!< Offset: 0xFCC (R/ ) TPIU_DEVTYPE */
+} TPI_Type;
+
+/* TPI Asynchronous Clock Prescaler Register Definitions */
+#define TPI_ACPR_PRESCALER_Pos 0U /*!< TPI ACPR: PRESCALER Position */
+#define TPI_ACPR_PRESCALER_Msk (0x1FFFUL /*<< TPI_ACPR_PRESCALER_Pos*/) /*!< TPI ACPR: PRESCALER Mask */
+
+/* TPI Selected Pin Protocol Register Definitions */
+#define TPI_SPPR_TXMODE_Pos 0U /*!< TPI SPPR: TXMODE Position */
+#define TPI_SPPR_TXMODE_Msk (0x3UL /*<< TPI_SPPR_TXMODE_Pos*/) /*!< TPI SPPR: TXMODE Mask */
+
+/* TPI Formatter and Flush Status Register Definitions */
+#define TPI_FFSR_FtNonStop_Pos 3U /*!< TPI FFSR: FtNonStop Position */
+#define TPI_FFSR_FtNonStop_Msk (0x1UL << TPI_FFSR_FtNonStop_Pos) /*!< TPI FFSR: FtNonStop Mask */
+
+#define TPI_FFSR_TCPresent_Pos 2U /*!< TPI FFSR: TCPresent Position */
+#define TPI_FFSR_TCPresent_Msk (0x1UL << TPI_FFSR_TCPresent_Pos) /*!< TPI FFSR: TCPresent Mask */
+
+#define TPI_FFSR_FtStopped_Pos 1U /*!< TPI FFSR: FtStopped Position */
+#define TPI_FFSR_FtStopped_Msk (0x1UL << TPI_FFSR_FtStopped_Pos) /*!< TPI FFSR: FtStopped Mask */
+
+#define TPI_FFSR_FlInProg_Pos 0U /*!< TPI FFSR: FlInProg Position */
+#define TPI_FFSR_FlInProg_Msk (0x1UL /*<< TPI_FFSR_FlInProg_Pos*/) /*!< TPI FFSR: FlInProg Mask */
+
+/* TPI Formatter and Flush Control Register Definitions */
+#define TPI_FFCR_TrigIn_Pos 8U /*!< TPI FFCR: TrigIn Position */
+#define TPI_FFCR_TrigIn_Msk (0x1UL << TPI_FFCR_TrigIn_Pos) /*!< TPI FFCR: TrigIn Mask */
+
+#define TPI_FFCR_EnFCont_Pos 1U /*!< TPI FFCR: EnFCont Position */
+#define TPI_FFCR_EnFCont_Msk (0x1UL << TPI_FFCR_EnFCont_Pos) /*!< TPI FFCR: EnFCont Mask */
+
+/* TPI TRIGGER Register Definitions */
+#define TPI_TRIGGER_TRIGGER_Pos 0U /*!< TPI TRIGGER: TRIGGER Position */
+#define TPI_TRIGGER_TRIGGER_Msk (0x1UL /*<< TPI_TRIGGER_TRIGGER_Pos*/) /*!< TPI TRIGGER: TRIGGER Mask */
+
+/* TPI Integration ETM Data Register Definitions (FIFO0) */
+#define TPI_FIFO0_ITM_ATVALID_Pos 29U /*!< TPI FIFO0: ITM_ATVALID Position */
+#define TPI_FIFO0_ITM_ATVALID_Msk (0x3UL << TPI_FIFO0_ITM_ATVALID_Pos) /*!< TPI FIFO0: ITM_ATVALID Mask */
+
+#define TPI_FIFO0_ITM_bytecount_Pos 27U /*!< TPI FIFO0: ITM_bytecount Position */
+#define TPI_FIFO0_ITM_bytecount_Msk (0x3UL << TPI_FIFO0_ITM_bytecount_Pos) /*!< TPI FIFO0: ITM_bytecount Mask */
+
+#define TPI_FIFO0_ETM_ATVALID_Pos 26U /*!< TPI FIFO0: ETM_ATVALID Position */
+#define TPI_FIFO0_ETM_ATVALID_Msk (0x3UL << TPI_FIFO0_ETM_ATVALID_Pos) /*!< TPI FIFO0: ETM_ATVALID Mask */
+
+#define TPI_FIFO0_ETM_bytecount_Pos 24U /*!< TPI FIFO0: ETM_bytecount Position */
+#define TPI_FIFO0_ETM_bytecount_Msk (0x3UL << TPI_FIFO0_ETM_bytecount_Pos) /*!< TPI FIFO0: ETM_bytecount Mask */
+
+#define TPI_FIFO0_ETM2_Pos 16U /*!< TPI FIFO0: ETM2 Position */
+#define TPI_FIFO0_ETM2_Msk (0xFFUL << TPI_FIFO0_ETM2_Pos) /*!< TPI FIFO0: ETM2 Mask */
+
+#define TPI_FIFO0_ETM1_Pos 8U /*!< TPI FIFO0: ETM1 Position */
+#define TPI_FIFO0_ETM1_Msk (0xFFUL << TPI_FIFO0_ETM1_Pos) /*!< TPI FIFO0: ETM1 Mask */
+
+#define TPI_FIFO0_ETM0_Pos 0U /*!< TPI FIFO0: ETM0 Position */
+#define TPI_FIFO0_ETM0_Msk (0xFFUL /*<< TPI_FIFO0_ETM0_Pos*/) /*!< TPI FIFO0: ETM0 Mask */
+
+/* TPI ITATBCTR2 Register Definitions */
+#define TPI_ITATBCTR2_ATREADY_Pos 0U /*!< TPI ITATBCTR2: ATREADY Position */
+#define TPI_ITATBCTR2_ATREADY_Msk (0x1UL /*<< TPI_ITATBCTR2_ATREADY_Pos*/) /*!< TPI ITATBCTR2: ATREADY Mask */
+
+/* TPI Integration ITM Data Register Definitions (FIFO1) */
+#define TPI_FIFO1_ITM_ATVALID_Pos 29U /*!< TPI FIFO1: ITM_ATVALID Position */
+#define TPI_FIFO1_ITM_ATVALID_Msk (0x3UL << TPI_FIFO1_ITM_ATVALID_Pos) /*!< TPI FIFO1: ITM_ATVALID Mask */
+
+#define TPI_FIFO1_ITM_bytecount_Pos 27U /*!< TPI FIFO1: ITM_bytecount Position */
+#define TPI_FIFO1_ITM_bytecount_Msk (0x3UL << TPI_FIFO1_ITM_bytecount_Pos) /*!< TPI FIFO1: ITM_bytecount Mask */
+
+#define TPI_FIFO1_ETM_ATVALID_Pos 26U /*!< TPI FIFO1: ETM_ATVALID Position */
+#define TPI_FIFO1_ETM_ATVALID_Msk (0x3UL << TPI_FIFO1_ETM_ATVALID_Pos) /*!< TPI FIFO1: ETM_ATVALID Mask */
+
+#define TPI_FIFO1_ETM_bytecount_Pos 24U /*!< TPI FIFO1: ETM_bytecount Position */
+#define TPI_FIFO1_ETM_bytecount_Msk (0x3UL << TPI_FIFO1_ETM_bytecount_Pos) /*!< TPI FIFO1: ETM_bytecount Mask */
+
+#define TPI_FIFO1_ITM2_Pos 16U /*!< TPI FIFO1: ITM2 Position */
+#define TPI_FIFO1_ITM2_Msk (0xFFUL << TPI_FIFO1_ITM2_Pos) /*!< TPI FIFO1: ITM2 Mask */
+
+#define TPI_FIFO1_ITM1_Pos 8U /*!< TPI FIFO1: ITM1 Position */
+#define TPI_FIFO1_ITM1_Msk (0xFFUL << TPI_FIFO1_ITM1_Pos) /*!< TPI FIFO1: ITM1 Mask */
+
+#define TPI_FIFO1_ITM0_Pos 0U /*!< TPI FIFO1: ITM0 Position */
+#define TPI_FIFO1_ITM0_Msk (0xFFUL /*<< TPI_FIFO1_ITM0_Pos*/) /*!< TPI FIFO1: ITM0 Mask */
+
+/* TPI ITATBCTR0 Register Definitions */
+#define TPI_ITATBCTR0_ATREADY_Pos 0U /*!< TPI ITATBCTR0: ATREADY Position */
+#define TPI_ITATBCTR0_ATREADY_Msk (0x1UL /*<< TPI_ITATBCTR0_ATREADY_Pos*/) /*!< TPI ITATBCTR0: ATREADY Mask */
+
+/* TPI Integration Mode Control Register Definitions */
+#define TPI_ITCTRL_Mode_Pos 0U /*!< TPI ITCTRL: Mode Position */
+#define TPI_ITCTRL_Mode_Msk (0x1UL /*<< TPI_ITCTRL_Mode_Pos*/) /*!< TPI ITCTRL: Mode Mask */
+
+/* TPI DEVID Register Definitions */
+#define TPI_DEVID_NRZVALID_Pos 11U /*!< TPI DEVID: NRZVALID Position */
+#define TPI_DEVID_NRZVALID_Msk (0x1UL << TPI_DEVID_NRZVALID_Pos) /*!< TPI DEVID: NRZVALID Mask */
+
+#define TPI_DEVID_MANCVALID_Pos 10U /*!< TPI DEVID: MANCVALID Position */
+#define TPI_DEVID_MANCVALID_Msk (0x1UL << TPI_DEVID_MANCVALID_Pos) /*!< TPI DEVID: MANCVALID Mask */
+
+#define TPI_DEVID_PTINVALID_Pos 9U /*!< TPI DEVID: PTINVALID Position */
+#define TPI_DEVID_PTINVALID_Msk (0x1UL << TPI_DEVID_PTINVALID_Pos) /*!< TPI DEVID: PTINVALID Mask */
+
+#define TPI_DEVID_MinBufSz_Pos 6U /*!< TPI DEVID: MinBufSz Position */
+#define TPI_DEVID_MinBufSz_Msk (0x7UL << TPI_DEVID_MinBufSz_Pos) /*!< TPI DEVID: MinBufSz Mask */
+
+#define TPI_DEVID_AsynClkIn_Pos 5U /*!< TPI DEVID: AsynClkIn Position */
+#define TPI_DEVID_AsynClkIn_Msk (0x1UL << TPI_DEVID_AsynClkIn_Pos) /*!< TPI DEVID: AsynClkIn Mask */
+
+#define TPI_DEVID_NrTraceInput_Pos 0U /*!< TPI DEVID: NrTraceInput Position */
+#define TPI_DEVID_NrTraceInput_Msk (0x1FUL /*<< TPI_DEVID_NrTraceInput_Pos*/) /*!< TPI DEVID: NrTraceInput Mask */
+
+/* TPI DEVTYPE Register Definitions */
+#define TPI_DEVTYPE_MajorType_Pos 4U /*!< TPI DEVTYPE: MajorType Position */
+#define TPI_DEVTYPE_MajorType_Msk (0xFUL << TPI_DEVTYPE_MajorType_Pos) /*!< TPI DEVTYPE: MajorType Mask */
+
+#define TPI_DEVTYPE_SubType_Pos 0U /*!< TPI DEVTYPE: SubType Position */
+#define TPI_DEVTYPE_SubType_Msk (0xFUL /*<< TPI_DEVTYPE_SubType_Pos*/) /*!< TPI DEVTYPE: SubType Mask */
+
+/*@}*/ /* end of group CMSIS_TPI */
+
+
+#if (__MPU_PRESENT == 1U)
+/**
+ \ingroup CMSIS_core_register
+ \defgroup CMSIS_MPU Memory Protection Unit (MPU)
+ \brief Type definitions for the Memory Protection Unit (MPU)
+ @{
+ */
+
+/**
+ \brief Structure type to access the Memory Protection Unit (MPU).
+ */
+typedef struct
+{
+ __IM uint32_t TYPE; /*!< Offset: 0x000 (R/ ) MPU Type Register */
+ __IOM uint32_t CTRL; /*!< Offset: 0x004 (R/W) MPU Control Register */
+ __IOM uint32_t RNR; /*!< Offset: 0x008 (R/W) MPU Region RNRber Register */
+ __IOM uint32_t RBAR; /*!< Offset: 0x00C (R/W) MPU Region Base Address Register */
+ __IOM uint32_t RASR; /*!< Offset: 0x010 (R/W) MPU Region Attribute and Size Register */
+ __IOM uint32_t RBAR_A1; /*!< Offset: 0x014 (R/W) MPU Alias 1 Region Base Address Register */
+ __IOM uint32_t RASR_A1; /*!< Offset: 0x018 (R/W) MPU Alias 1 Region Attribute and Size Register */
+ __IOM uint32_t RBAR_A2; /*!< Offset: 0x01C (R/W) MPU Alias 2 Region Base Address Register */
+ __IOM uint32_t RASR_A2; /*!< Offset: 0x020 (R/W) MPU Alias 2 Region Attribute and Size Register */
+ __IOM uint32_t RBAR_A3; /*!< Offset: 0x024 (R/W) MPU Alias 3 Region Base Address Register */
+ __IOM uint32_t RASR_A3; /*!< Offset: 0x028 (R/W) MPU Alias 3 Region Attribute and Size Register */
+} MPU_Type;
+
+/* MPU Type Register Definitions */
+#define MPU_TYPE_IREGION_Pos 16U /*!< MPU TYPE: IREGION Position */
+#define MPU_TYPE_IREGION_Msk (0xFFUL << MPU_TYPE_IREGION_Pos) /*!< MPU TYPE: IREGION Mask */
+
+#define MPU_TYPE_DREGION_Pos 8U /*!< MPU TYPE: DREGION Position */
+#define MPU_TYPE_DREGION_Msk (0xFFUL << MPU_TYPE_DREGION_Pos) /*!< MPU TYPE: DREGION Mask */
+
+#define MPU_TYPE_SEPARATE_Pos 0U /*!< MPU TYPE: SEPARATE Position */
+#define MPU_TYPE_SEPARATE_Msk (1UL /*<< MPU_TYPE_SEPARATE_Pos*/) /*!< MPU TYPE: SEPARATE Mask */
+
+/* MPU Control Register Definitions */
+#define MPU_CTRL_PRIVDEFENA_Pos 2U /*!< MPU CTRL: PRIVDEFENA Position */
+#define MPU_CTRL_PRIVDEFENA_Msk (1UL << MPU_CTRL_PRIVDEFENA_Pos) /*!< MPU CTRL: PRIVDEFENA Mask */
+
+#define MPU_CTRL_HFNMIENA_Pos 1U /*!< MPU CTRL: HFNMIENA Position */
+#define MPU_CTRL_HFNMIENA_Msk (1UL << MPU_CTRL_HFNMIENA_Pos) /*!< MPU CTRL: HFNMIENA Mask */
+
+#define MPU_CTRL_ENABLE_Pos 0U /*!< MPU CTRL: ENABLE Position */
+#define MPU_CTRL_ENABLE_Msk (1UL /*<< MPU_CTRL_ENABLE_Pos*/) /*!< MPU CTRL: ENABLE Mask */
+
+/* MPU Region Number Register Definitions */
+#define MPU_RNR_REGION_Pos 0U /*!< MPU RNR: REGION Position */
+#define MPU_RNR_REGION_Msk (0xFFUL /*<< MPU_RNR_REGION_Pos*/) /*!< MPU RNR: REGION Mask */
+
+/* MPU Region Base Address Register Definitions */
+#define MPU_RBAR_ADDR_Pos 5U /*!< MPU RBAR: ADDR Position */
+#define MPU_RBAR_ADDR_Msk (0x7FFFFFFUL << MPU_RBAR_ADDR_Pos) /*!< MPU RBAR: ADDR Mask */
+
+#define MPU_RBAR_VALID_Pos 4U /*!< MPU RBAR: VALID Position */
+#define MPU_RBAR_VALID_Msk (1UL << MPU_RBAR_VALID_Pos) /*!< MPU RBAR: VALID Mask */
+
+#define MPU_RBAR_REGION_Pos 0U /*!< MPU RBAR: REGION Position */
+#define MPU_RBAR_REGION_Msk (0xFUL /*<< MPU_RBAR_REGION_Pos*/) /*!< MPU RBAR: REGION Mask */
+
+/* MPU Region Attribute and Size Register Definitions */
+#define MPU_RASR_ATTRS_Pos 16U /*!< MPU RASR: MPU Region Attribute field Position */
+#define MPU_RASR_ATTRS_Msk (0xFFFFUL << MPU_RASR_ATTRS_Pos) /*!< MPU RASR: MPU Region Attribute field Mask */
+
+#define MPU_RASR_XN_Pos 28U /*!< MPU RASR: ATTRS.XN Position */
+#define MPU_RASR_XN_Msk (1UL << MPU_RASR_XN_Pos) /*!< MPU RASR: ATTRS.XN Mask */
+
+#define MPU_RASR_AP_Pos 24U /*!< MPU RASR: ATTRS.AP Position */
+#define MPU_RASR_AP_Msk (0x7UL << MPU_RASR_AP_Pos) /*!< MPU RASR: ATTRS.AP Mask */
+
+#define MPU_RASR_TEX_Pos 19U /*!< MPU RASR: ATTRS.TEX Position */
+#define MPU_RASR_TEX_Msk (0x7UL << MPU_RASR_TEX_Pos) /*!< MPU RASR: ATTRS.TEX Mask */
+
+#define MPU_RASR_S_Pos 18U /*!< MPU RASR: ATTRS.S Position */
+#define MPU_RASR_S_Msk (1UL << MPU_RASR_S_Pos) /*!< MPU RASR: ATTRS.S Mask */
+
+#define MPU_RASR_C_Pos 17U /*!< MPU RASR: ATTRS.C Position */
+#define MPU_RASR_C_Msk (1UL << MPU_RASR_C_Pos) /*!< MPU RASR: ATTRS.C Mask */
+
+#define MPU_RASR_B_Pos 16U /*!< MPU RASR: ATTRS.B Position */
+#define MPU_RASR_B_Msk (1UL << MPU_RASR_B_Pos) /*!< MPU RASR: ATTRS.B Mask */
+
+#define MPU_RASR_SRD_Pos 8U /*!< MPU RASR: Sub-Region Disable Position */
+#define MPU_RASR_SRD_Msk (0xFFUL << MPU_RASR_SRD_Pos) /*!< MPU RASR: Sub-Region Disable Mask */
+
+#define MPU_RASR_SIZE_Pos 1U /*!< MPU RASR: Region Size Field Position */
+#define MPU_RASR_SIZE_Msk (0x1FUL << MPU_RASR_SIZE_Pos) /*!< MPU RASR: Region Size Field Mask */
+
+#define MPU_RASR_ENABLE_Pos 0U /*!< MPU RASR: Region enable bit Position */
+#define MPU_RASR_ENABLE_Msk (1UL /*<< MPU_RASR_ENABLE_Pos*/) /*!< MPU RASR: Region enable bit Disable Mask */
+
+/*@} end of group CMSIS_MPU */
+#endif
+
+
+/**
+ \ingroup CMSIS_core_register
+ \defgroup CMSIS_CoreDebug Core Debug Registers (CoreDebug)
+ \brief Type definitions for the Core Debug Registers
+ @{
+ */
+
+/**
+ \brief Structure type to access the Core Debug Register (CoreDebug).
+ */
+typedef struct
+{
+ __IOM uint32_t DHCSR; /*!< Offset: 0x000 (R/W) Debug Halting Control and Status Register */
+ __OM uint32_t DCRSR; /*!< Offset: 0x004 ( /W) Debug Core Register Selector Register */
+ __IOM uint32_t DCRDR; /*!< Offset: 0x008 (R/W) Debug Core Register Data Register */
+ __IOM uint32_t DEMCR; /*!< Offset: 0x00C (R/W) Debug Exception and Monitor Control Register */
+} CoreDebug_Type;
+
+/* Debug Halting Control and Status Register Definitions */
+#define CoreDebug_DHCSR_DBGKEY_Pos 16U /*!< CoreDebug DHCSR: DBGKEY Position */
+#define CoreDebug_DHCSR_DBGKEY_Msk (0xFFFFUL << CoreDebug_DHCSR_DBGKEY_Pos) /*!< CoreDebug DHCSR: DBGKEY Mask */
+
+#define CoreDebug_DHCSR_S_RESET_ST_Pos 25U /*!< CoreDebug DHCSR: S_RESET_ST Position */
+#define CoreDebug_DHCSR_S_RESET_ST_Msk (1UL << CoreDebug_DHCSR_S_RESET_ST_Pos) /*!< CoreDebug DHCSR: S_RESET_ST Mask */
+
+#define CoreDebug_DHCSR_S_RETIRE_ST_Pos 24U /*!< CoreDebug DHCSR: S_RETIRE_ST Position */
+#define CoreDebug_DHCSR_S_RETIRE_ST_Msk (1UL << CoreDebug_DHCSR_S_RETIRE_ST_Pos) /*!< CoreDebug DHCSR: S_RETIRE_ST Mask */
+
+#define CoreDebug_DHCSR_S_LOCKUP_Pos 19U /*!< CoreDebug DHCSR: S_LOCKUP Position */
+#define CoreDebug_DHCSR_S_LOCKUP_Msk (1UL << CoreDebug_DHCSR_S_LOCKUP_Pos) /*!< CoreDebug DHCSR: S_LOCKUP Mask */
+
+#define CoreDebug_DHCSR_S_SLEEP_Pos 18U /*!< CoreDebug DHCSR: S_SLEEP Position */
+#define CoreDebug_DHCSR_S_SLEEP_Msk (1UL << CoreDebug_DHCSR_S_SLEEP_Pos) /*!< CoreDebug DHCSR: S_SLEEP Mask */
+
+#define CoreDebug_DHCSR_S_HALT_Pos 17U /*!< CoreDebug DHCSR: S_HALT Position */
+#define CoreDebug_DHCSR_S_HALT_Msk (1UL << CoreDebug_DHCSR_S_HALT_Pos) /*!< CoreDebug DHCSR: S_HALT Mask */
+
+#define CoreDebug_DHCSR_S_REGRDY_Pos 16U /*!< CoreDebug DHCSR: S_REGRDY Position */
+#define CoreDebug_DHCSR_S_REGRDY_Msk (1UL << CoreDebug_DHCSR_S_REGRDY_Pos) /*!< CoreDebug DHCSR: S_REGRDY Mask */
+
+#define CoreDebug_DHCSR_C_SNAPSTALL_Pos 5U /*!< CoreDebug DHCSR: C_SNAPSTALL Position */
+#define CoreDebug_DHCSR_C_SNAPSTALL_Msk (1UL << CoreDebug_DHCSR_C_SNAPSTALL_Pos) /*!< CoreDebug DHCSR: C_SNAPSTALL Mask */
+
+#define CoreDebug_DHCSR_C_MASKINTS_Pos 3U /*!< CoreDebug DHCSR: C_MASKINTS Position */
+#define CoreDebug_DHCSR_C_MASKINTS_Msk (1UL << CoreDebug_DHCSR_C_MASKINTS_Pos) /*!< CoreDebug DHCSR: C_MASKINTS Mask */
+
+#define CoreDebug_DHCSR_C_STEP_Pos 2U /*!< CoreDebug DHCSR: C_STEP Position */
+#define CoreDebug_DHCSR_C_STEP_Msk (1UL << CoreDebug_DHCSR_C_STEP_Pos) /*!< CoreDebug DHCSR: C_STEP Mask */
+
+#define CoreDebug_DHCSR_C_HALT_Pos 1U /*!< CoreDebug DHCSR: C_HALT Position */
+#define CoreDebug_DHCSR_C_HALT_Msk (1UL << CoreDebug_DHCSR_C_HALT_Pos) /*!< CoreDebug DHCSR: C_HALT Mask */
+
+#define CoreDebug_DHCSR_C_DEBUGEN_Pos 0U /*!< CoreDebug DHCSR: C_DEBUGEN Position */
+#define CoreDebug_DHCSR_C_DEBUGEN_Msk (1UL /*<< CoreDebug_DHCSR_C_DEBUGEN_Pos*/) /*!< CoreDebug DHCSR: C_DEBUGEN Mask */
+
+/* Debug Core Register Selector Register Definitions */
+#define CoreDebug_DCRSR_REGWnR_Pos 16U /*!< CoreDebug DCRSR: REGWnR Position */
+#define CoreDebug_DCRSR_REGWnR_Msk (1UL << CoreDebug_DCRSR_REGWnR_Pos) /*!< CoreDebug DCRSR: REGWnR Mask */
+
+#define CoreDebug_DCRSR_REGSEL_Pos 0U /*!< CoreDebug DCRSR: REGSEL Position */
+#define CoreDebug_DCRSR_REGSEL_Msk (0x1FUL /*<< CoreDebug_DCRSR_REGSEL_Pos*/) /*!< CoreDebug DCRSR: REGSEL Mask */
+
+/* Debug Exception and Monitor Control Register Definitions */
+#define CoreDebug_DEMCR_TRCENA_Pos 24U /*!< CoreDebug DEMCR: TRCENA Position */
+#define CoreDebug_DEMCR_TRCENA_Msk (1UL << CoreDebug_DEMCR_TRCENA_Pos) /*!< CoreDebug DEMCR: TRCENA Mask */
+
+#define CoreDebug_DEMCR_MON_REQ_Pos 19U /*!< CoreDebug DEMCR: MON_REQ Position */
+#define CoreDebug_DEMCR_MON_REQ_Msk (1UL << CoreDebug_DEMCR_MON_REQ_Pos) /*!< CoreDebug DEMCR: MON_REQ Mask */
+
+#define CoreDebug_DEMCR_MON_STEP_Pos 18U /*!< CoreDebug DEMCR: MON_STEP Position */
+#define CoreDebug_DEMCR_MON_STEP_Msk (1UL << CoreDebug_DEMCR_MON_STEP_Pos) /*!< CoreDebug DEMCR: MON_STEP Mask */
+
+#define CoreDebug_DEMCR_MON_PEND_Pos 17U /*!< CoreDebug DEMCR: MON_PEND Position */
+#define CoreDebug_DEMCR_MON_PEND_Msk (1UL << CoreDebug_DEMCR_MON_PEND_Pos) /*!< CoreDebug DEMCR: MON_PEND Mask */
+
+#define CoreDebug_DEMCR_MON_EN_Pos 16U /*!< CoreDebug DEMCR: MON_EN Position */
+#define CoreDebug_DEMCR_MON_EN_Msk (1UL << CoreDebug_DEMCR_MON_EN_Pos) /*!< CoreDebug DEMCR: MON_EN Mask */
+
+#define CoreDebug_DEMCR_VC_HARDERR_Pos 10U /*!< CoreDebug DEMCR: VC_HARDERR Position */
+#define CoreDebug_DEMCR_VC_HARDERR_Msk (1UL << CoreDebug_DEMCR_VC_HARDERR_Pos) /*!< CoreDebug DEMCR: VC_HARDERR Mask */
+
+#define CoreDebug_DEMCR_VC_INTERR_Pos 9U /*!< CoreDebug DEMCR: VC_INTERR Position */
+#define CoreDebug_DEMCR_VC_INTERR_Msk (1UL << CoreDebug_DEMCR_VC_INTERR_Pos) /*!< CoreDebug DEMCR: VC_INTERR Mask */
+
+#define CoreDebug_DEMCR_VC_BUSERR_Pos 8U /*!< CoreDebug DEMCR: VC_BUSERR Position */
+#define CoreDebug_DEMCR_VC_BUSERR_Msk (1UL << CoreDebug_DEMCR_VC_BUSERR_Pos) /*!< CoreDebug DEMCR: VC_BUSERR Mask */
+
+#define CoreDebug_DEMCR_VC_STATERR_Pos 7U /*!< CoreDebug DEMCR: VC_STATERR Position */
+#define CoreDebug_DEMCR_VC_STATERR_Msk (1UL << CoreDebug_DEMCR_VC_STATERR_Pos) /*!< CoreDebug DEMCR: VC_STATERR Mask */
+
+#define CoreDebug_DEMCR_VC_CHKERR_Pos 6U /*!< CoreDebug DEMCR: VC_CHKERR Position */
+#define CoreDebug_DEMCR_VC_CHKERR_Msk (1UL << CoreDebug_DEMCR_VC_CHKERR_Pos) /*!< CoreDebug DEMCR: VC_CHKERR Mask */
+
+#define CoreDebug_DEMCR_VC_NOCPERR_Pos 5U /*!< CoreDebug DEMCR: VC_NOCPERR Position */
+#define CoreDebug_DEMCR_VC_NOCPERR_Msk (1UL << CoreDebug_DEMCR_VC_NOCPERR_Pos) /*!< CoreDebug DEMCR: VC_NOCPERR Mask */
+
+#define CoreDebug_DEMCR_VC_MMERR_Pos 4U /*!< CoreDebug DEMCR: VC_MMERR Position */
+#define CoreDebug_DEMCR_VC_MMERR_Msk (1UL << CoreDebug_DEMCR_VC_MMERR_Pos) /*!< CoreDebug DEMCR: VC_MMERR Mask */
+
+#define CoreDebug_DEMCR_VC_CORERESET_Pos 0U /*!< CoreDebug DEMCR: VC_CORERESET Position */
+#define CoreDebug_DEMCR_VC_CORERESET_Msk (1UL /*<< CoreDebug_DEMCR_VC_CORERESET_Pos*/) /*!< CoreDebug DEMCR: VC_CORERESET Mask */
+
+/*@} end of group CMSIS_CoreDebug */
+
+
+/**
+ \ingroup CMSIS_core_register
+ \defgroup CMSIS_core_bitfield Core register bit field macros
+ \brief Macros for use with bit field definitions (xxx_Pos, xxx_Msk).
+ @{
+ */
+
+/**
+ \brief Mask and shift a bit field value for use in a register bit range.
+ \param[in] field Name of the register bit field.
+ \param[in] value Value of the bit field.
+ \return Masked and shifted value.
+*/
+#define _VAL2FLD(field, value) ((value << field ## _Pos) & field ## _Msk)
+
+/**
+ \brief Mask and shift a register value to extract a bit filed value.
+ \param[in] field Name of the register bit field.
+ \param[in] value Value of register.
+ \return Masked and shifted bit field value.
+*/
+#define _FLD2VAL(field, value) ((value & field ## _Msk) >> field ## _Pos)
+
+/*@} end of group CMSIS_core_bitfield */
+
+
+/**
+ \ingroup CMSIS_core_register
+ \defgroup CMSIS_core_base Core Definitions
+ \brief Definitions for base addresses, unions, and structures.
+ @{
+ */
+
+/* Memory mapping of Cortex-M3 Hardware */
+#define SCS_BASE (0xE000E000UL) /*!< System Control Space Base Address */
+#define ITM_BASE (0xE0000000UL) /*!< ITM Base Address */
+#define DWT_BASE (0xE0001000UL) /*!< DWT Base Address */
+#define TPI_BASE (0xE0040000UL) /*!< TPI Base Address */
+#define CoreDebug_BASE (0xE000EDF0UL) /*!< Core Debug Base Address */
+#define SysTick_BASE (SCS_BASE + 0x0010UL) /*!< SysTick Base Address */
+#define NVIC_BASE (SCS_BASE + 0x0100UL) /*!< NVIC Base Address */
+#define SCB_BASE (SCS_BASE + 0x0D00UL) /*!< System Control Block Base Address */
+
+#define SCnSCB ((SCnSCB_Type *) SCS_BASE ) /*!< System control Register not in SCB */
+#define SCB ((SCB_Type *) SCB_BASE ) /*!< SCB configuration struct */
+#define SysTick ((SysTick_Type *) SysTick_BASE ) /*!< SysTick configuration struct */
+#define NVIC ((NVIC_Type *) NVIC_BASE ) /*!< NVIC configuration struct */
+#define ITM ((ITM_Type *) ITM_BASE ) /*!< ITM configuration struct */
+#define DWT ((DWT_Type *) DWT_BASE ) /*!< DWT configuration struct */
+#define TPI ((TPI_Type *) TPI_BASE ) /*!< TPI configuration struct */
+#define CoreDebug ((CoreDebug_Type *) CoreDebug_BASE) /*!< Core Debug configuration struct */
+
+#if (__MPU_PRESENT == 1U)
+ #define MPU_BASE (SCS_BASE + 0x0D90UL) /*!< Memory Protection Unit */
+ #define MPU ((MPU_Type *) MPU_BASE ) /*!< Memory Protection Unit */
+#endif
+
+/*@} */
+
+
+
+/*******************************************************************************
+ * Hardware Abstraction Layer
+ Core Function Interface contains:
+ - Core NVIC Functions
+ - Core SysTick Functions
+ - Core Debug Functions
+ - Core Register Access Functions
+ ******************************************************************************/
+/**
+ \defgroup CMSIS_Core_FunctionInterface Functions and Instructions Reference
+*/
+
+
+
+/* ########################## NVIC functions #################################### */
+/**
+ \ingroup CMSIS_Core_FunctionInterface
+ \defgroup CMSIS_Core_NVICFunctions NVIC Functions
+ \brief Functions that manage interrupts and exceptions via the NVIC.
+ @{
+ */
+
+/**
+ \brief Set Priority Grouping
+ \details Sets the priority grouping field using the required unlock sequence.
+ The parameter PriorityGroup is assigned to the field SCB->AIRCR [10:8] PRIGROUP field.
+ Only values from 0..7 are used.
+ In case of a conflict between priority grouping and available
+ priority bits (__NVIC_PRIO_BITS), the smallest possible priority group is set.
+ \param [in] PriorityGroup Priority grouping field.
+ */
+__STATIC_INLINE void NVIC_SetPriorityGrouping(uint32_t PriorityGroup)
+{
+ uint32_t reg_value;
+ uint32_t PriorityGroupTmp = (PriorityGroup & (uint32_t)0x07UL); /* only values 0..7 are used */
+
+ reg_value = SCB->AIRCR; /* read old register configuration */
+ reg_value &= ~((uint32_t)(SCB_AIRCR_VECTKEY_Msk | SCB_AIRCR_PRIGROUP_Msk)); /* clear bits to change */
+ reg_value = (reg_value |
+ ((uint32_t)0x5FAUL << SCB_AIRCR_VECTKEY_Pos) |
+ (PriorityGroupTmp << 8U) ); /* Insert write key and priorty group */
+ SCB->AIRCR = reg_value;
+}
+
+
+/**
+ \brief Get Priority Grouping
+ \details Reads the priority grouping field from the NVIC Interrupt Controller.
+ \return Priority grouping field (SCB->AIRCR [10:8] PRIGROUP field).
+ */
+__STATIC_INLINE uint32_t NVIC_GetPriorityGrouping(void)
+{
+ return ((uint32_t)((SCB->AIRCR & SCB_AIRCR_PRIGROUP_Msk) >> SCB_AIRCR_PRIGROUP_Pos));
+}
+
+
+/**
+ \brief Enable External Interrupt
+ \details Enables a device-specific interrupt in the NVIC interrupt controller.
+ \param [in] IRQn External interrupt number. Value cannot be negative.
+ */
+__STATIC_INLINE void NVIC_EnableIRQ(IRQn_Type IRQn)
+{
+ NVIC->ISER[(((uint32_t)(int32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL));
+}
+
+
+/**
+ \brief Disable External Interrupt
+ \details Disables a device-specific interrupt in the NVIC interrupt controller.
+ \param [in] IRQn External interrupt number. Value cannot be negative.
+ */
+__STATIC_INLINE void NVIC_DisableIRQ(IRQn_Type IRQn)
+{
+ NVIC->ICER[(((uint32_t)(int32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL));
+}
+
+
+/**
+ \brief Get Pending Interrupt
+ \details Reads the pending register in the NVIC and returns the pending bit for the specified interrupt.
+ \param [in] IRQn Interrupt number.
+ \return 0 Interrupt status is not pending.
+ \return 1 Interrupt status is pending.
+ */
+__STATIC_INLINE uint32_t NVIC_GetPendingIRQ(IRQn_Type IRQn)
+{
+ return((uint32_t)(((NVIC->ISPR[(((uint32_t)(int32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL));
+}
+
+
+/**
+ \brief Set Pending Interrupt
+ \details Sets the pending bit of an external interrupt.
+ \param [in] IRQn Interrupt number. Value cannot be negative.
+ */
+__STATIC_INLINE void NVIC_SetPendingIRQ(IRQn_Type IRQn)
+{
+ NVIC->ISPR[(((uint32_t)(int32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL));
+}
+
+
+/**
+ \brief Clear Pending Interrupt
+ \details Clears the pending bit of an external interrupt.
+ \param [in] IRQn External interrupt number. Value cannot be negative.
+ */
+__STATIC_INLINE void NVIC_ClearPendingIRQ(IRQn_Type IRQn)
+{
+ NVIC->ICPR[(((uint32_t)(int32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL));
+}
+
+
+/**
+ \brief Get Active Interrupt
+ \details Reads the active register in NVIC and returns the active bit.
+ \param [in] IRQn Interrupt number.
+ \return 0 Interrupt status is not active.
+ \return 1 Interrupt status is active.
+ */
+__STATIC_INLINE uint32_t NVIC_GetActive(IRQn_Type IRQn)
+{
+ return((uint32_t)(((NVIC->IABR[(((uint32_t)(int32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL));
+}
+
+
+/**
+ \brief Set Interrupt Priority
+ \details Sets the priority of an interrupt.
+ \note The priority cannot be set for every core interrupt.
+ \param [in] IRQn Interrupt number.
+ \param [in] priority Priority to set.
+ */
+__STATIC_INLINE void NVIC_SetPriority(IRQn_Type IRQn, uint32_t priority)
+{
+ if ((int32_t)(IRQn) < 0)
+ {
+ SCB->SHP[(((uint32_t)(int32_t)IRQn) & 0xFUL)-4UL] = (uint8_t)((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL);
+ }
+ else
+ {
+ NVIC->IP[((uint32_t)(int32_t)IRQn)] = (uint8_t)((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL);
+ }
+}
+
+
+/**
+ \brief Get Interrupt Priority
+ \details Reads the priority of an interrupt.
+ The interrupt number can be positive to specify an external (device specific) interrupt,
+ or negative to specify an internal (core) interrupt.
+ \param [in] IRQn Interrupt number.
+ \return Interrupt Priority.
+ Value is aligned automatically to the implemented priority bits of the microcontroller.
+ */
+__STATIC_INLINE uint32_t NVIC_GetPriority(IRQn_Type IRQn)
+{
+
+ if ((int32_t)(IRQn) < 0)
+ {
+ return(((uint32_t)SCB->SHP[(((uint32_t)(int32_t)IRQn) & 0xFUL)-4UL] >> (8U - __NVIC_PRIO_BITS)));
+ }
+ else
+ {
+ return(((uint32_t)NVIC->IP[((uint32_t)(int32_t)IRQn)] >> (8U - __NVIC_PRIO_BITS)));
+ }
+}
+
+
+/**
+ \brief Encode Priority
+ \details Encodes the priority for an interrupt with the given priority group,
+ preemptive priority value, and subpriority value.
+ In case of a conflict between priority grouping and available
+ priority bits (__NVIC_PRIO_BITS), the smallest possible priority group is set.
+ \param [in] PriorityGroup Used priority group.
+ \param [in] PreemptPriority Preemptive priority value (starting from 0).
+ \param [in] SubPriority Subpriority value (starting from 0).
+ \return Encoded priority. Value can be used in the function \ref NVIC_SetPriority().
+ */
+__STATIC_INLINE uint32_t NVIC_EncodePriority (uint32_t PriorityGroup, uint32_t PreemptPriority, uint32_t SubPriority)
+{
+ uint32_t PriorityGroupTmp = (PriorityGroup & (uint32_t)0x07UL); /* only values 0..7 are used */
+ uint32_t PreemptPriorityBits;
+ uint32_t SubPriorityBits;
+
+ PreemptPriorityBits = ((7UL - PriorityGroupTmp) > (uint32_t)(__NVIC_PRIO_BITS)) ? (uint32_t)(__NVIC_PRIO_BITS) : (uint32_t)(7UL - PriorityGroupTmp);
+ SubPriorityBits = ((PriorityGroupTmp + (uint32_t)(__NVIC_PRIO_BITS)) < (uint32_t)7UL) ? (uint32_t)0UL : (uint32_t)((PriorityGroupTmp - 7UL) + (uint32_t)(__NVIC_PRIO_BITS));
+
+ return (
+ ((PreemptPriority & (uint32_t)((1UL << (PreemptPriorityBits)) - 1UL)) << SubPriorityBits) |
+ ((SubPriority & (uint32_t)((1UL << (SubPriorityBits )) - 1UL)))
+ );
+}
+
+
+/**
+ \brief Decode Priority
+ \details Decodes an interrupt priority value with a given priority group to
+ preemptive priority value and subpriority value.
+ In case of a conflict between priority grouping and available
+ priority bits (__NVIC_PRIO_BITS) the smallest possible priority group is set.
+ \param [in] Priority Priority value, which can be retrieved with the function \ref NVIC_GetPriority().
+ \param [in] PriorityGroup Used priority group.
+ \param [out] pPreemptPriority Preemptive priority value (starting from 0).
+ \param [out] pSubPriority Subpriority value (starting from 0).
+ */
+__STATIC_INLINE void NVIC_DecodePriority (uint32_t Priority, uint32_t PriorityGroup, uint32_t* const pPreemptPriority, uint32_t* const pSubPriority)
+{
+ uint32_t PriorityGroupTmp = (PriorityGroup & (uint32_t)0x07UL); /* only values 0..7 are used */
+ uint32_t PreemptPriorityBits;
+ uint32_t SubPriorityBits;
+
+ PreemptPriorityBits = ((7UL - PriorityGroupTmp) > (uint32_t)(__NVIC_PRIO_BITS)) ? (uint32_t)(__NVIC_PRIO_BITS) : (uint32_t)(7UL - PriorityGroupTmp);
+ SubPriorityBits = ((PriorityGroupTmp + (uint32_t)(__NVIC_PRIO_BITS)) < (uint32_t)7UL) ? (uint32_t)0UL : (uint32_t)((PriorityGroupTmp - 7UL) + (uint32_t)(__NVIC_PRIO_BITS));
+
+ *pPreemptPriority = (Priority >> SubPriorityBits) & (uint32_t)((1UL << (PreemptPriorityBits)) - 1UL);
+ *pSubPriority = (Priority ) & (uint32_t)((1UL << (SubPriorityBits )) - 1UL);
+}
+
+
+/**
+ \brief System Reset
+ \details Initiates a system reset request to reset the MCU.
+ */
+__STATIC_INLINE void NVIC_SystemReset(void)
+{
+ __DSB(); /* Ensure all outstanding memory accesses included
+ buffered write are completed before reset */
+ SCB->AIRCR = (uint32_t)((0x5FAUL << SCB_AIRCR_VECTKEY_Pos) |
+ (SCB->AIRCR & SCB_AIRCR_PRIGROUP_Msk) |
+ SCB_AIRCR_SYSRESETREQ_Msk ); /* Keep priority group unchanged */
+ __DSB(); /* Ensure completion of memory access */
+
+ for (;;) /* wait until reset */
+ {
+ __NOP();
+ }
+}
+
+/*@} end of CMSIS_Core_NVICFunctions */
+
+
+
+/* ################################## SysTick function ############################################ */
+/**
+ \ingroup CMSIS_Core_FunctionInterface
+ \defgroup CMSIS_Core_SysTickFunctions SysTick Functions
+ \brief Functions that configure the System.
+ @{
+ */
+
+#if (__Vendor_SysTickConfig == 0U)
+
+/**
+ \brief System Tick Configuration
+ \details Initializes the System Timer and its interrupt, and starts the System Tick Timer.
+ Counter is in free running mode to generate periodic interrupts.
+ \param [in] ticks Number of ticks between two interrupts.
+ \return 0 Function succeeded.
+ \return 1 Function failed.
+ \note When the variable <b>__Vendor_SysTickConfig</b> is set to 1, then the
+ function <b>SysTick_Config</b> is not included. In this case, the file <b><i>device</i>.h</b>
+ must contain a vendor-specific implementation of this function.
+ */
+__STATIC_INLINE uint32_t SysTick_Config(uint32_t ticks)
+{
+ if ((ticks - 1UL) > SysTick_LOAD_RELOAD_Msk)
+ {
+ return (1UL); /* Reload value impossible */
+ }
+
+ SysTick->LOAD = (uint32_t)(ticks - 1UL); /* set reload register */
+ NVIC_SetPriority (SysTick_IRQn, (1UL << __NVIC_PRIO_BITS) - 1UL); /* set Priority for Systick Interrupt */
+ SysTick->VAL = 0UL; /* Load the SysTick Counter Value */
+ SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk |
+ SysTick_CTRL_TICKINT_Msk |
+ SysTick_CTRL_ENABLE_Msk; /* Enable SysTick IRQ and SysTick Timer */
+ return (0UL); /* Function successful */
+}
+
+#endif
+
+/*@} end of CMSIS_Core_SysTickFunctions */
+
+
+
+/* ##################################### Debug In/Output function ########################################### */
+/**
+ \ingroup CMSIS_Core_FunctionInterface
+ \defgroup CMSIS_core_DebugFunctions ITM Functions
+ \brief Functions that access the ITM debug interface.
+ @{
+ */
+
+extern volatile int32_t ITM_RxBuffer; /*!< External variable to receive characters. */
+#define ITM_RXBUFFER_EMPTY 0x5AA55AA5U /*!< Value identifying \ref ITM_RxBuffer is ready for next character. */
+
+
+/**
+ \brief ITM Send Character
+ \details Transmits a character via the ITM channel 0, and
+ \li Just returns when no debugger is connected that has booked the output.
+ \li Is blocking when a debugger is connected, but the previous character sent has not been transmitted.
+ \param [in] ch Character to transmit.
+ \returns Character to transmit.
+ */
+__STATIC_INLINE uint32_t ITM_SendChar (uint32_t ch)
+{
+ if (((ITM->TCR & ITM_TCR_ITMENA_Msk) != 0UL) && /* ITM enabled */
+ ((ITM->TER & 1UL ) != 0UL) ) /* ITM Port #0 enabled */
+ {
+ while (ITM->PORT[0U].u32 == 0UL)
+ {
+ __NOP();
+ }
+ ITM->PORT[0U].u8 = (uint8_t)ch;
+ }
+ return (ch);
+}
+
+
+/**
+ \brief ITM Receive Character
+ \details Inputs a character via the external variable \ref ITM_RxBuffer.
+ \return Received character.
+ \return -1 No character pending.
+ */
+__STATIC_INLINE int32_t ITM_ReceiveChar (void)
+{
+ int32_t ch = -1; /* no character available */
+
+ if (ITM_RxBuffer != ITM_RXBUFFER_EMPTY)
+ {
+ ch = ITM_RxBuffer;
+ ITM_RxBuffer = ITM_RXBUFFER_EMPTY; /* ready for next character */
+ }
+
+ return (ch);
+}
+
+
+/**
+ \brief ITM Check Character
+ \details Checks whether a character is pending for reading in the variable \ref ITM_RxBuffer.
+ \return 0 No character available.
+ \return 1 Character available.
+ */
+__STATIC_INLINE int32_t ITM_CheckChar (void)
+{
+
+ if (ITM_RxBuffer == ITM_RXBUFFER_EMPTY)
+ {
+ return (0); /* no character available */
+ }
+ else
+ {
+ return (1); /* character available */
+ }
+}
+
+/*@} end of CMSIS_core_DebugFunctions */
+
+
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __CORE_CM3_H_DEPENDANT */
+
+#endif /* __CMSIS_GENERIC */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/toolchain/cmsis/include/core_cm4.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/toolchain/cmsis/include/core_cm4.h
new file mode 100644
index 0000000..d02b111
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/toolchain/cmsis/include/core_cm4.h
@@ -0,0 +1,1937 @@
+/**************************************************************************//**
+ * @file core_cm4.h
+ * @brief CMSIS Cortex-M4 Core Peripheral Access Layer Header File
+ * @version V4.30
+ * @date 20. October 2015
+ ******************************************************************************/
+/* Copyright (c) 2009 - 2015 ARM LIMITED
+
+ All rights reserved.
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are met:
+ - Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ - 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.
+ - Neither the name of ARM 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 COPYRIGHT HOLDERS AND 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.
+ ---------------------------------------------------------------------------*/
+
+
+#if defined ( __ICCARM__ )
+ #pragma system_include /* treat file as system include file for MISRA check */
+#elif defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050)
+ #pragma clang system_header /* treat file as system include file */
+#endif
+
+#ifndef __CORE_CM4_H_GENERIC
+#define __CORE_CM4_H_GENERIC
+
+#include <stdint.h>
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+/**
+ \page CMSIS_MISRA_Exceptions MISRA-C:2004 Compliance Exceptions
+ CMSIS violates the following MISRA-C:2004 rules:
+
+ \li Required Rule 8.5, object/function definition in header file.<br>
+ Function definitions in header files are used to allow 'inlining'.
+
+ \li Required Rule 18.4, declaration of union type or object of union type: '{...}'.<br>
+ Unions are used for effective representation of core registers.
+
+ \li Advisory Rule 19.7, Function-like macro defined.<br>
+ Function-like macros are used to allow more efficient code.
+ */
+
+
+/*******************************************************************************
+ * CMSIS definitions
+ ******************************************************************************/
+/**
+ \ingroup Cortex_M4
+ @{
+ */
+
+/* CMSIS CM4 definitions */
+#define __CM4_CMSIS_VERSION_MAIN (0x04U) /*!< [31:16] CMSIS HAL main version */
+#define __CM4_CMSIS_VERSION_SUB (0x1EU) /*!< [15:0] CMSIS HAL sub version */
+#define __CM4_CMSIS_VERSION ((__CM4_CMSIS_VERSION_MAIN << 16U) | \
+ __CM4_CMSIS_VERSION_SUB ) /*!< CMSIS HAL version number */
+
+#define __CORTEX_M (0x04U) /*!< Cortex-M Core */
+
+
+#if defined ( __CC_ARM )
+ #define __ASM __asm /*!< asm keyword for ARM Compiler */
+ #define __INLINE __inline /*!< inline keyword for ARM Compiler */
+ #define __STATIC_INLINE static __inline
+
+#elif defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050)
+ #define __ASM __asm /*!< asm keyword for ARM Compiler */
+ #define __INLINE __inline /*!< inline keyword for ARM Compiler */
+ #define __STATIC_INLINE static __inline
+
+#elif defined ( __GNUC__ )
+ #define __ASM __asm /*!< asm keyword for GNU Compiler */
+ #define __INLINE inline /*!< inline keyword for GNU Compiler */
+ #define __STATIC_INLINE static inline
+
+#elif defined ( __ICCARM__ )
+ #define __ASM __asm /*!< asm keyword for IAR Compiler */
+ #define __INLINE inline /*!< inline keyword for IAR Compiler. Only available in High optimization mode! */
+ #define __STATIC_INLINE static inline
+
+#elif defined ( __TMS470__ )
+ #define __ASM __asm /*!< asm keyword for TI CCS Compiler */
+ #define __STATIC_INLINE static inline
+
+#elif defined ( __TASKING__ )
+ #define __ASM __asm /*!< asm keyword for TASKING Compiler */
+ #define __INLINE inline /*!< inline keyword for TASKING Compiler */
+ #define __STATIC_INLINE static inline
+
+#elif defined ( __CSMC__ )
+ #define __packed
+ #define __ASM _asm /*!< asm keyword for COSMIC Compiler */
+ #define __INLINE inline /*!< inline keyword for COSMIC Compiler. Use -pc99 on compile line */
+ #define __STATIC_INLINE static inline
+
+#else
+ #error Unknown compiler
+#endif
+
+/** __FPU_USED indicates whether an FPU is used or not.
+ For this, __FPU_PRESENT has to be checked prior to making use of FPU specific registers and functions.
+*/
+#if defined ( __CC_ARM )
+ #if defined __TARGET_FPU_VFP
+ #if (__FPU_PRESENT == 1U)
+ #define __FPU_USED 1U
+ #else
+ #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
+ #define __FPU_USED 0U
+ #endif
+ #else
+ #define __FPU_USED 0U
+ #endif
+
+#elif defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050)
+ #if defined __ARM_PCS_VFP
+ #if (__FPU_PRESENT == 1)
+ #define __FPU_USED 1U
+ #else
+ #warning "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
+ #define __FPU_USED 0U
+ #endif
+ #else
+ #define __FPU_USED 0U
+ #endif
+
+#elif defined ( __GNUC__ )
+ #if defined (__VFP_FP__) && !defined(__SOFTFP__)
+ #if (__FPU_PRESENT == 1U)
+ #define __FPU_USED 1U
+ #else
+ #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
+ #define __FPU_USED 0U
+ #endif
+ #else
+ #define __FPU_USED 0U
+ #endif
+
+#elif defined ( __ICCARM__ )
+ #if defined __ARMVFP__
+ #if (__FPU_PRESENT == 1U)
+ #define __FPU_USED 1U
+ #else
+ #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
+ #define __FPU_USED 0U
+ #endif
+ #else
+ #define __FPU_USED 0U
+ #endif
+
+#elif defined ( __TMS470__ )
+ #if defined __TI_VFP_SUPPORT__
+ #if (__FPU_PRESENT == 1U)
+ #define __FPU_USED 1U
+ #else
+ #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
+ #define __FPU_USED 0U
+ #endif
+ #else
+ #define __FPU_USED 0U
+ #endif
+
+#elif defined ( __TASKING__ )
+ #if defined __FPU_VFP__
+ #if (__FPU_PRESENT == 1U)
+ #define __FPU_USED 1U
+ #else
+ #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
+ #define __FPU_USED 0U
+ #endif
+ #else
+ #define __FPU_USED 0U
+ #endif
+
+#elif defined ( __CSMC__ )
+ #if ( __CSMC__ & 0x400U)
+ #if (__FPU_PRESENT == 1U)
+ #define __FPU_USED 1U
+ #else
+ #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
+ #define __FPU_USED 0U
+ #endif
+ #else
+ #define __FPU_USED 0U
+ #endif
+
+#endif
+
+#include "core_cmInstr.h" /* Core Instruction Access */
+#include "core_cmFunc.h" /* Core Function Access */
+#include "core_cmSimd.h" /* Compiler specific SIMD Intrinsics */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __CORE_CM4_H_GENERIC */
+
+#ifndef __CMSIS_GENERIC
+
+#ifndef __CORE_CM4_H_DEPENDANT
+#define __CORE_CM4_H_DEPENDANT
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+/* check device defines and use defaults */
+#if defined __CHECK_DEVICE_DEFINES
+ #ifndef __CM4_REV
+ #define __CM4_REV 0x0000U
+ #warning "__CM4_REV not defined in device header file; using default!"
+ #endif
+
+ #ifndef __FPU_PRESENT
+ #define __FPU_PRESENT 0U
+ #warning "__FPU_PRESENT not defined in device header file; using default!"
+ #endif
+
+ #ifndef __MPU_PRESENT
+ #define __MPU_PRESENT 0U
+ #warning "__MPU_PRESENT not defined in device header file; using default!"
+ #endif
+
+ #ifndef __NVIC_PRIO_BITS
+ #define __NVIC_PRIO_BITS 4U
+ #warning "__NVIC_PRIO_BITS not defined in device header file; using default!"
+ #endif
+
+ #ifndef __Vendor_SysTickConfig
+ #define __Vendor_SysTickConfig 0U
+ #warning "__Vendor_SysTickConfig not defined in device header file; using default!"
+ #endif
+#endif
+
+/* IO definitions (access restrictions to peripheral registers) */
+/**
+ \defgroup CMSIS_glob_defs CMSIS Global Defines
+
+ <strong>IO Type Qualifiers</strong> are used
+ \li to specify the access to peripheral variables.
+ \li for automatic generation of peripheral register debug information.
+*/
+#ifdef __cplusplus
+ #define __I volatile /*!< Defines 'read only' permissions */
+#else
+ #define __I volatile const /*!< Defines 'read only' permissions */
+#endif
+#define __O volatile /*!< Defines 'write only' permissions */
+#define __IO volatile /*!< Defines 'read / write' permissions */
+
+/* following defines should be used for structure members */
+#define __IM volatile const /*! Defines 'read only' structure member permissions */
+#define __OM volatile /*! Defines 'write only' structure member permissions */
+#define __IOM volatile /*! Defines 'read / write' structure member permissions */
+
+/*@} end of group Cortex_M4 */
+
+
+
+/*******************************************************************************
+ * Register Abstraction
+ Core Register contain:
+ - Core Register
+ - Core NVIC Register
+ - Core SCB Register
+ - Core SysTick Register
+ - Core Debug Register
+ - Core MPU Register
+ - Core FPU Register
+ ******************************************************************************/
+/**
+ \defgroup CMSIS_core_register Defines and Type Definitions
+ \brief Type definitions and defines for Cortex-M processor based devices.
+*/
+
+/**
+ \ingroup CMSIS_core_register
+ \defgroup CMSIS_CORE Status and Control Registers
+ \brief Core Register type definitions.
+ @{
+ */
+
+/**
+ \brief Union type to access the Application Program Status Register (APSR).
+ */
+typedef union
+{
+ struct
+ {
+ uint32_t _reserved0:16; /*!< bit: 0..15 Reserved */
+ uint32_t GE:4; /*!< bit: 16..19 Greater than or Equal flags */
+ uint32_t _reserved1:7; /*!< bit: 20..26 Reserved */
+ uint32_t Q:1; /*!< bit: 27 Saturation condition flag */
+ uint32_t V:1; /*!< bit: 28 Overflow condition code flag */
+ uint32_t C:1; /*!< bit: 29 Carry condition code flag */
+ uint32_t Z:1; /*!< bit: 30 Zero condition code flag */
+ uint32_t N:1; /*!< bit: 31 Negative condition code flag */
+ } b; /*!< Structure used for bit access */
+ uint32_t w; /*!< Type used for word access */
+} APSR_Type;
+
+/* APSR Register Definitions */
+#define APSR_N_Pos 31U /*!< APSR: N Position */
+#define APSR_N_Msk (1UL << APSR_N_Pos) /*!< APSR: N Mask */
+
+#define APSR_Z_Pos 30U /*!< APSR: Z Position */
+#define APSR_Z_Msk (1UL << APSR_Z_Pos) /*!< APSR: Z Mask */
+
+#define APSR_C_Pos 29U /*!< APSR: C Position */
+#define APSR_C_Msk (1UL << APSR_C_Pos) /*!< APSR: C Mask */
+
+#define APSR_V_Pos 28U /*!< APSR: V Position */
+#define APSR_V_Msk (1UL << APSR_V_Pos) /*!< APSR: V Mask */
+
+#define APSR_Q_Pos 27U /*!< APSR: Q Position */
+#define APSR_Q_Msk (1UL << APSR_Q_Pos) /*!< APSR: Q Mask */
+
+#define APSR_GE_Pos 16U /*!< APSR: GE Position */
+#define APSR_GE_Msk (0xFUL << APSR_GE_Pos) /*!< APSR: GE Mask */
+
+
+/**
+ \brief Union type to access the Interrupt Program Status Register (IPSR).
+ */
+typedef union
+{
+ struct
+ {
+ uint32_t ISR:9; /*!< bit: 0.. 8 Exception number */
+ uint32_t _reserved0:23; /*!< bit: 9..31 Reserved */
+ } b; /*!< Structure used for bit access */
+ uint32_t w; /*!< Type used for word access */
+} IPSR_Type;
+
+/* IPSR Register Definitions */
+#define IPSR_ISR_Pos 0U /*!< IPSR: ISR Position */
+#define IPSR_ISR_Msk (0x1FFUL /*<< IPSR_ISR_Pos*/) /*!< IPSR: ISR Mask */
+
+
+/**
+ \brief Union type to access the Special-Purpose Program Status Registers (xPSR).
+ */
+typedef union
+{
+ struct
+ {
+ uint32_t ISR:9; /*!< bit: 0.. 8 Exception number */
+ uint32_t _reserved0:7; /*!< bit: 9..15 Reserved */
+ uint32_t GE:4; /*!< bit: 16..19 Greater than or Equal flags */
+ uint32_t _reserved1:4; /*!< bit: 20..23 Reserved */
+ uint32_t T:1; /*!< bit: 24 Thumb bit (read 0) */
+ uint32_t IT:2; /*!< bit: 25..26 saved IT state (read 0) */
+ uint32_t Q:1; /*!< bit: 27 Saturation condition flag */
+ uint32_t V:1; /*!< bit: 28 Overflow condition code flag */
+ uint32_t C:1; /*!< bit: 29 Carry condition code flag */
+ uint32_t Z:1; /*!< bit: 30 Zero condition code flag */
+ uint32_t N:1; /*!< bit: 31 Negative condition code flag */
+ } b; /*!< Structure used for bit access */
+ uint32_t w; /*!< Type used for word access */
+} xPSR_Type;
+
+/* xPSR Register Definitions */
+#define xPSR_N_Pos 31U /*!< xPSR: N Position */
+#define xPSR_N_Msk (1UL << xPSR_N_Pos) /*!< xPSR: N Mask */
+
+#define xPSR_Z_Pos 30U /*!< xPSR: Z Position */
+#define xPSR_Z_Msk (1UL << xPSR_Z_Pos) /*!< xPSR: Z Mask */
+
+#define xPSR_C_Pos 29U /*!< xPSR: C Position */
+#define xPSR_C_Msk (1UL << xPSR_C_Pos) /*!< xPSR: C Mask */
+
+#define xPSR_V_Pos 28U /*!< xPSR: V Position */
+#define xPSR_V_Msk (1UL << xPSR_V_Pos) /*!< xPSR: V Mask */
+
+#define xPSR_Q_Pos 27U /*!< xPSR: Q Position */
+#define xPSR_Q_Msk (1UL << xPSR_Q_Pos) /*!< xPSR: Q Mask */
+
+#define xPSR_IT_Pos 25U /*!< xPSR: IT Position */
+#define xPSR_IT_Msk (3UL << xPSR_IT_Pos) /*!< xPSR: IT Mask */
+
+#define xPSR_T_Pos 24U /*!< xPSR: T Position */
+#define xPSR_T_Msk (1UL << xPSR_T_Pos) /*!< xPSR: T Mask */
+
+#define xPSR_GE_Pos 16U /*!< xPSR: GE Position */
+#define xPSR_GE_Msk (0xFUL << xPSR_GE_Pos) /*!< xPSR: GE Mask */
+
+#define xPSR_ISR_Pos 0U /*!< xPSR: ISR Position */
+#define xPSR_ISR_Msk (0x1FFUL /*<< xPSR_ISR_Pos*/) /*!< xPSR: ISR Mask */
+
+
+/**
+ \brief Union type to access the Control Registers (CONTROL).
+ */
+typedef union
+{
+ struct
+ {
+ uint32_t nPRIV:1; /*!< bit: 0 Execution privilege in Thread mode */
+ uint32_t SPSEL:1; /*!< bit: 1 Stack to be used */
+ uint32_t FPCA:1; /*!< bit: 2 FP extension active flag */
+ uint32_t _reserved0:29; /*!< bit: 3..31 Reserved */
+ } b; /*!< Structure used for bit access */
+ uint32_t w; /*!< Type used for word access */
+} CONTROL_Type;
+
+/* CONTROL Register Definitions */
+#define CONTROL_FPCA_Pos 2U /*!< CONTROL: FPCA Position */
+#define CONTROL_FPCA_Msk (1UL << CONTROL_FPCA_Pos) /*!< CONTROL: FPCA Mask */
+
+#define CONTROL_SPSEL_Pos 1U /*!< CONTROL: SPSEL Position */
+#define CONTROL_SPSEL_Msk (1UL << CONTROL_SPSEL_Pos) /*!< CONTROL: SPSEL Mask */
+
+#define CONTROL_nPRIV_Pos 0U /*!< CONTROL: nPRIV Position */
+#define CONTROL_nPRIV_Msk (1UL /*<< CONTROL_nPRIV_Pos*/) /*!< CONTROL: nPRIV Mask */
+
+/*@} end of group CMSIS_CORE */
+
+
+/**
+ \ingroup CMSIS_core_register
+ \defgroup CMSIS_NVIC Nested Vectored Interrupt Controller (NVIC)
+ \brief Type definitions for the NVIC Registers
+ @{
+ */
+
+/**
+ \brief Structure type to access the Nested Vectored Interrupt Controller (NVIC).
+ */
+typedef struct
+{
+ __IOM uint32_t ISER[8U]; /*!< Offset: 0x000 (R/W) Interrupt Set Enable Register */
+ uint32_t RESERVED0[24U];
+ __IOM uint32_t ICER[8U]; /*!< Offset: 0x080 (R/W) Interrupt Clear Enable Register */
+ uint32_t RSERVED1[24U];
+ __IOM uint32_t ISPR[8U]; /*!< Offset: 0x100 (R/W) Interrupt Set Pending Register */
+ uint32_t RESERVED2[24U];
+ __IOM uint32_t ICPR[8U]; /*!< Offset: 0x180 (R/W) Interrupt Clear Pending Register */
+ uint32_t RESERVED3[24U];
+ __IOM uint32_t IABR[8U]; /*!< Offset: 0x200 (R/W) Interrupt Active bit Register */
+ uint32_t RESERVED4[56U];
+ __IOM uint8_t IP[240U]; /*!< Offset: 0x300 (R/W) Interrupt Priority Register (8Bit wide) */
+ uint32_t RESERVED5[644U];
+ __OM uint32_t STIR; /*!< Offset: 0xE00 ( /W) Software Trigger Interrupt Register */
+} NVIC_Type;
+
+/* Software Triggered Interrupt Register Definitions */
+#define NVIC_STIR_INTID_Pos 0U /*!< STIR: INTLINESNUM Position */
+#define NVIC_STIR_INTID_Msk (0x1FFUL /*<< NVIC_STIR_INTID_Pos*/) /*!< STIR: INTLINESNUM Mask */
+
+/*@} end of group CMSIS_NVIC */
+
+
+/**
+ \ingroup CMSIS_core_register
+ \defgroup CMSIS_SCB System Control Block (SCB)
+ \brief Type definitions for the System Control Block Registers
+ @{
+ */
+
+/**
+ \brief Structure type to access the System Control Block (SCB).
+ */
+typedef struct
+{
+ __IM uint32_t CPUID; /*!< Offset: 0x000 (R/ ) CPUID Base Register */
+ __IOM uint32_t ICSR; /*!< Offset: 0x004 (R/W) Interrupt Control and State Register */
+ __IOM uint32_t VTOR; /*!< Offset: 0x008 (R/W) Vector Table Offset Register */
+ __IOM uint32_t AIRCR; /*!< Offset: 0x00C (R/W) Application Interrupt and Reset Control Register */
+ __IOM uint32_t SCR; /*!< Offset: 0x010 (R/W) System Control Register */
+ __IOM uint32_t CCR; /*!< Offset: 0x014 (R/W) Configuration Control Register */
+ __IOM uint8_t SHP[12U]; /*!< Offset: 0x018 (R/W) System Handlers Priority Registers (4-7, 8-11, 12-15) */
+ __IOM uint32_t SHCSR; /*!< Offset: 0x024 (R/W) System Handler Control and State Register */
+ __IOM uint32_t CFSR; /*!< Offset: 0x028 (R/W) Configurable Fault Status Register */
+ __IOM uint32_t HFSR; /*!< Offset: 0x02C (R/W) HardFault Status Register */
+ __IOM uint32_t DFSR; /*!< Offset: 0x030 (R/W) Debug Fault Status Register */
+ __IOM uint32_t MMFAR; /*!< Offset: 0x034 (R/W) MemManage Fault Address Register */
+ __IOM uint32_t BFAR; /*!< Offset: 0x038 (R/W) BusFault Address Register */
+ __IOM uint32_t AFSR; /*!< Offset: 0x03C (R/W) Auxiliary Fault Status Register */
+ __IM uint32_t PFR[2U]; /*!< Offset: 0x040 (R/ ) Processor Feature Register */
+ __IM uint32_t DFR; /*!< Offset: 0x048 (R/ ) Debug Feature Register */
+ __IM uint32_t ADR; /*!< Offset: 0x04C (R/ ) Auxiliary Feature Register */
+ __IM uint32_t MMFR[4U]; /*!< Offset: 0x050 (R/ ) Memory Model Feature Register */
+ __IM uint32_t ISAR[5U]; /*!< Offset: 0x060 (R/ ) Instruction Set Attributes Register */
+ uint32_t RESERVED0[5U];
+ __IOM uint32_t CPACR; /*!< Offset: 0x088 (R/W) Coprocessor Access Control Register */
+} SCB_Type;
+
+/* SCB CPUID Register Definitions */
+#define SCB_CPUID_IMPLEMENTER_Pos 24U /*!< SCB CPUID: IMPLEMENTER Position */
+#define SCB_CPUID_IMPLEMENTER_Msk (0xFFUL << SCB_CPUID_IMPLEMENTER_Pos) /*!< SCB CPUID: IMPLEMENTER Mask */
+
+#define SCB_CPUID_VARIANT_Pos 20U /*!< SCB CPUID: VARIANT Position */
+#define SCB_CPUID_VARIANT_Msk (0xFUL << SCB_CPUID_VARIANT_Pos) /*!< SCB CPUID: VARIANT Mask */
+
+#define SCB_CPUID_ARCHITECTURE_Pos 16U /*!< SCB CPUID: ARCHITECTURE Position */
+#define SCB_CPUID_ARCHITECTURE_Msk (0xFUL << SCB_CPUID_ARCHITECTURE_Pos) /*!< SCB CPUID: ARCHITECTURE Mask */
+
+#define SCB_CPUID_PARTNO_Pos 4U /*!< SCB CPUID: PARTNO Position */
+#define SCB_CPUID_PARTNO_Msk (0xFFFUL << SCB_CPUID_PARTNO_Pos) /*!< SCB CPUID: PARTNO Mask */
+
+#define SCB_CPUID_REVISION_Pos 0U /*!< SCB CPUID: REVISION Position */
+#define SCB_CPUID_REVISION_Msk (0xFUL /*<< SCB_CPUID_REVISION_Pos*/) /*!< SCB CPUID: REVISION Mask */
+
+/* SCB Interrupt Control State Register Definitions */
+#define SCB_ICSR_NMIPENDSET_Pos 31U /*!< SCB ICSR: NMIPENDSET Position */
+#define SCB_ICSR_NMIPENDSET_Msk (1UL << SCB_ICSR_NMIPENDSET_Pos) /*!< SCB ICSR: NMIPENDSET Mask */
+
+#define SCB_ICSR_PENDSVSET_Pos 28U /*!< SCB ICSR: PENDSVSET Position */
+#define SCB_ICSR_PENDSVSET_Msk (1UL << SCB_ICSR_PENDSVSET_Pos) /*!< SCB ICSR: PENDSVSET Mask */
+
+#define SCB_ICSR_PENDSVCLR_Pos 27U /*!< SCB ICSR: PENDSVCLR Position */
+#define SCB_ICSR_PENDSVCLR_Msk (1UL << SCB_ICSR_PENDSVCLR_Pos) /*!< SCB ICSR: PENDSVCLR Mask */
+
+#define SCB_ICSR_PENDSTSET_Pos 26U /*!< SCB ICSR: PENDSTSET Position */
+#define SCB_ICSR_PENDSTSET_Msk (1UL << SCB_ICSR_PENDSTSET_Pos) /*!< SCB ICSR: PENDSTSET Mask */
+
+#define SCB_ICSR_PENDSTCLR_Pos 25U /*!< SCB ICSR: PENDSTCLR Position */
+#define SCB_ICSR_PENDSTCLR_Msk (1UL << SCB_ICSR_PENDSTCLR_Pos) /*!< SCB ICSR: PENDSTCLR Mask */
+
+#define SCB_ICSR_ISRPREEMPT_Pos 23U /*!< SCB ICSR: ISRPREEMPT Position */
+#define SCB_ICSR_ISRPREEMPT_Msk (1UL << SCB_ICSR_ISRPREEMPT_Pos) /*!< SCB ICSR: ISRPREEMPT Mask */
+
+#define SCB_ICSR_ISRPENDING_Pos 22U /*!< SCB ICSR: ISRPENDING Position */
+#define SCB_ICSR_ISRPENDING_Msk (1UL << SCB_ICSR_ISRPENDING_Pos) /*!< SCB ICSR: ISRPENDING Mask */
+
+#define SCB_ICSR_VECTPENDING_Pos 12U /*!< SCB ICSR: VECTPENDING Position */
+#define SCB_ICSR_VECTPENDING_Msk (0x1FFUL << SCB_ICSR_VECTPENDING_Pos) /*!< SCB ICSR: VECTPENDING Mask */
+
+#define SCB_ICSR_RETTOBASE_Pos 11U /*!< SCB ICSR: RETTOBASE Position */
+#define SCB_ICSR_RETTOBASE_Msk (1UL << SCB_ICSR_RETTOBASE_Pos) /*!< SCB ICSR: RETTOBASE Mask */
+
+#define SCB_ICSR_VECTACTIVE_Pos 0U /*!< SCB ICSR: VECTACTIVE Position */
+#define SCB_ICSR_VECTACTIVE_Msk (0x1FFUL /*<< SCB_ICSR_VECTACTIVE_Pos*/) /*!< SCB ICSR: VECTACTIVE Mask */
+
+/* SCB Vector Table Offset Register Definitions */
+#define SCB_VTOR_TBLOFF_Pos 7U /*!< SCB VTOR: TBLOFF Position */
+#define SCB_VTOR_TBLOFF_Msk (0x1FFFFFFUL << SCB_VTOR_TBLOFF_Pos) /*!< SCB VTOR: TBLOFF Mask */
+
+/* SCB Application Interrupt and Reset Control Register Definitions */
+#define SCB_AIRCR_VECTKEY_Pos 16U /*!< SCB AIRCR: VECTKEY Position */
+#define SCB_AIRCR_VECTKEY_Msk (0xFFFFUL << SCB_AIRCR_VECTKEY_Pos) /*!< SCB AIRCR: VECTKEY Mask */
+
+#define SCB_AIRCR_VECTKEYSTAT_Pos 16U /*!< SCB AIRCR: VECTKEYSTAT Position */
+#define SCB_AIRCR_VECTKEYSTAT_Msk (0xFFFFUL << SCB_AIRCR_VECTKEYSTAT_Pos) /*!< SCB AIRCR: VECTKEYSTAT Mask */
+
+#define SCB_AIRCR_ENDIANESS_Pos 15U /*!< SCB AIRCR: ENDIANESS Position */
+#define SCB_AIRCR_ENDIANESS_Msk (1UL << SCB_AIRCR_ENDIANESS_Pos) /*!< SCB AIRCR: ENDIANESS Mask */
+
+#define SCB_AIRCR_PRIGROUP_Pos 8U /*!< SCB AIRCR: PRIGROUP Position */
+#define SCB_AIRCR_PRIGROUP_Msk (7UL << SCB_AIRCR_PRIGROUP_Pos) /*!< SCB AIRCR: PRIGROUP Mask */
+
+#define SCB_AIRCR_SYSRESETREQ_Pos 2U /*!< SCB AIRCR: SYSRESETREQ Position */
+#define SCB_AIRCR_SYSRESETREQ_Msk (1UL << SCB_AIRCR_SYSRESETREQ_Pos) /*!< SCB AIRCR: SYSRESETREQ Mask */
+
+#define SCB_AIRCR_VECTCLRACTIVE_Pos 1U /*!< SCB AIRCR: VECTCLRACTIVE Position */
+#define SCB_AIRCR_VECTCLRACTIVE_Msk (1UL << SCB_AIRCR_VECTCLRACTIVE_Pos) /*!< SCB AIRCR: VECTCLRACTIVE Mask */
+
+#define SCB_AIRCR_VECTRESET_Pos 0U /*!< SCB AIRCR: VECTRESET Position */
+#define SCB_AIRCR_VECTRESET_Msk (1UL /*<< SCB_AIRCR_VECTRESET_Pos*/) /*!< SCB AIRCR: VECTRESET Mask */
+
+/* SCB System Control Register Definitions */
+#define SCB_SCR_SEVONPEND_Pos 4U /*!< SCB SCR: SEVONPEND Position */
+#define SCB_SCR_SEVONPEND_Msk (1UL << SCB_SCR_SEVONPEND_Pos) /*!< SCB SCR: SEVONPEND Mask */
+
+#define SCB_SCR_SLEEPDEEP_Pos 2U /*!< SCB SCR: SLEEPDEEP Position */
+#define SCB_SCR_SLEEPDEEP_Msk (1UL << SCB_SCR_SLEEPDEEP_Pos) /*!< SCB SCR: SLEEPDEEP Mask */
+
+#define SCB_SCR_SLEEPONEXIT_Pos 1U /*!< SCB SCR: SLEEPONEXIT Position */
+#define SCB_SCR_SLEEPONEXIT_Msk (1UL << SCB_SCR_SLEEPONEXIT_Pos) /*!< SCB SCR: SLEEPONEXIT Mask */
+
+/* SCB Configuration Control Register Definitions */
+#define SCB_CCR_STKALIGN_Pos 9U /*!< SCB CCR: STKALIGN Position */
+#define SCB_CCR_STKALIGN_Msk (1UL << SCB_CCR_STKALIGN_Pos) /*!< SCB CCR: STKALIGN Mask */
+
+#define SCB_CCR_BFHFNMIGN_Pos 8U /*!< SCB CCR: BFHFNMIGN Position */
+#define SCB_CCR_BFHFNMIGN_Msk (1UL << SCB_CCR_BFHFNMIGN_Pos) /*!< SCB CCR: BFHFNMIGN Mask */
+
+#define SCB_CCR_DIV_0_TRP_Pos 4U /*!< SCB CCR: DIV_0_TRP Position */
+#define SCB_CCR_DIV_0_TRP_Msk (1UL << SCB_CCR_DIV_0_TRP_Pos) /*!< SCB CCR: DIV_0_TRP Mask */
+
+#define SCB_CCR_UNALIGN_TRP_Pos 3U /*!< SCB CCR: UNALIGN_TRP Position */
+#define SCB_CCR_UNALIGN_TRP_Msk (1UL << SCB_CCR_UNALIGN_TRP_Pos) /*!< SCB CCR: UNALIGN_TRP Mask */
+
+#define SCB_CCR_USERSETMPEND_Pos 1U /*!< SCB CCR: USERSETMPEND Position */
+#define SCB_CCR_USERSETMPEND_Msk (1UL << SCB_CCR_USERSETMPEND_Pos) /*!< SCB CCR: USERSETMPEND Mask */
+
+#define SCB_CCR_NONBASETHRDENA_Pos 0U /*!< SCB CCR: NONBASETHRDENA Position */
+#define SCB_CCR_NONBASETHRDENA_Msk (1UL /*<< SCB_CCR_NONBASETHRDENA_Pos*/) /*!< SCB CCR: NONBASETHRDENA Mask */
+
+/* SCB System Handler Control and State Register Definitions */
+#define SCB_SHCSR_USGFAULTENA_Pos 18U /*!< SCB SHCSR: USGFAULTENA Position */
+#define SCB_SHCSR_USGFAULTENA_Msk (1UL << SCB_SHCSR_USGFAULTENA_Pos) /*!< SCB SHCSR: USGFAULTENA Mask */
+
+#define SCB_SHCSR_BUSFAULTENA_Pos 17U /*!< SCB SHCSR: BUSFAULTENA Position */
+#define SCB_SHCSR_BUSFAULTENA_Msk (1UL << SCB_SHCSR_BUSFAULTENA_Pos) /*!< SCB SHCSR: BUSFAULTENA Mask */
+
+#define SCB_SHCSR_MEMFAULTENA_Pos 16U /*!< SCB SHCSR: MEMFAULTENA Position */
+#define SCB_SHCSR_MEMFAULTENA_Msk (1UL << SCB_SHCSR_MEMFAULTENA_Pos) /*!< SCB SHCSR: MEMFAULTENA Mask */
+
+#define SCB_SHCSR_SVCALLPENDED_Pos 15U /*!< SCB SHCSR: SVCALLPENDED Position */
+#define SCB_SHCSR_SVCALLPENDED_Msk (1UL << SCB_SHCSR_SVCALLPENDED_Pos) /*!< SCB SHCSR: SVCALLPENDED Mask */
+
+#define SCB_SHCSR_BUSFAULTPENDED_Pos 14U /*!< SCB SHCSR: BUSFAULTPENDED Position */
+#define SCB_SHCSR_BUSFAULTPENDED_Msk (1UL << SCB_SHCSR_BUSFAULTPENDED_Pos) /*!< SCB SHCSR: BUSFAULTPENDED Mask */
+
+#define SCB_SHCSR_MEMFAULTPENDED_Pos 13U /*!< SCB SHCSR: MEMFAULTPENDED Position */
+#define SCB_SHCSR_MEMFAULTPENDED_Msk (1UL << SCB_SHCSR_MEMFAULTPENDED_Pos) /*!< SCB SHCSR: MEMFAULTPENDED Mask */
+
+#define SCB_SHCSR_USGFAULTPENDED_Pos 12U /*!< SCB SHCSR: USGFAULTPENDED Position */
+#define SCB_SHCSR_USGFAULTPENDED_Msk (1UL << SCB_SHCSR_USGFAULTPENDED_Pos) /*!< SCB SHCSR: USGFAULTPENDED Mask */
+
+#define SCB_SHCSR_SYSTICKACT_Pos 11U /*!< SCB SHCSR: SYSTICKACT Position */
+#define SCB_SHCSR_SYSTICKACT_Msk (1UL << SCB_SHCSR_SYSTICKACT_Pos) /*!< SCB SHCSR: SYSTICKACT Mask */
+
+#define SCB_SHCSR_PENDSVACT_Pos 10U /*!< SCB SHCSR: PENDSVACT Position */
+#define SCB_SHCSR_PENDSVACT_Msk (1UL << SCB_SHCSR_PENDSVACT_Pos) /*!< SCB SHCSR: PENDSVACT Mask */
+
+#define SCB_SHCSR_MONITORACT_Pos 8U /*!< SCB SHCSR: MONITORACT Position */
+#define SCB_SHCSR_MONITORACT_Msk (1UL << SCB_SHCSR_MONITORACT_Pos) /*!< SCB SHCSR: MONITORACT Mask */
+
+#define SCB_SHCSR_SVCALLACT_Pos 7U /*!< SCB SHCSR: SVCALLACT Position */
+#define SCB_SHCSR_SVCALLACT_Msk (1UL << SCB_SHCSR_SVCALLACT_Pos) /*!< SCB SHCSR: SVCALLACT Mask */
+
+#define SCB_SHCSR_USGFAULTACT_Pos 3U /*!< SCB SHCSR: USGFAULTACT Position */
+#define SCB_SHCSR_USGFAULTACT_Msk (1UL << SCB_SHCSR_USGFAULTACT_Pos) /*!< SCB SHCSR: USGFAULTACT Mask */
+
+#define SCB_SHCSR_BUSFAULTACT_Pos 1U /*!< SCB SHCSR: BUSFAULTACT Position */
+#define SCB_SHCSR_BUSFAULTACT_Msk (1UL << SCB_SHCSR_BUSFAULTACT_Pos) /*!< SCB SHCSR: BUSFAULTACT Mask */
+
+#define SCB_SHCSR_MEMFAULTACT_Pos 0U /*!< SCB SHCSR: MEMFAULTACT Position */
+#define SCB_SHCSR_MEMFAULTACT_Msk (1UL /*<< SCB_SHCSR_MEMFAULTACT_Pos*/) /*!< SCB SHCSR: MEMFAULTACT Mask */
+
+/* SCB Configurable Fault Status Register Definitions */
+#define SCB_CFSR_USGFAULTSR_Pos 16U /*!< SCB CFSR: Usage Fault Status Register Position */
+#define SCB_CFSR_USGFAULTSR_Msk (0xFFFFUL << SCB_CFSR_USGFAULTSR_Pos) /*!< SCB CFSR: Usage Fault Status Register Mask */
+
+#define SCB_CFSR_BUSFAULTSR_Pos 8U /*!< SCB CFSR: Bus Fault Status Register Position */
+#define SCB_CFSR_BUSFAULTSR_Msk (0xFFUL << SCB_CFSR_BUSFAULTSR_Pos) /*!< SCB CFSR: Bus Fault Status Register Mask */
+
+#define SCB_CFSR_MEMFAULTSR_Pos 0U /*!< SCB CFSR: Memory Manage Fault Status Register Position */
+#define SCB_CFSR_MEMFAULTSR_Msk (0xFFUL /*<< SCB_CFSR_MEMFAULTSR_Pos*/) /*!< SCB CFSR: Memory Manage Fault Status Register Mask */
+
+/* SCB Hard Fault Status Register Definitions */
+#define SCB_HFSR_DEBUGEVT_Pos 31U /*!< SCB HFSR: DEBUGEVT Position */
+#define SCB_HFSR_DEBUGEVT_Msk (1UL << SCB_HFSR_DEBUGEVT_Pos) /*!< SCB HFSR: DEBUGEVT Mask */
+
+#define SCB_HFSR_FORCED_Pos 30U /*!< SCB HFSR: FORCED Position */
+#define SCB_HFSR_FORCED_Msk (1UL << SCB_HFSR_FORCED_Pos) /*!< SCB HFSR: FORCED Mask */
+
+#define SCB_HFSR_VECTTBL_Pos 1U /*!< SCB HFSR: VECTTBL Position */
+#define SCB_HFSR_VECTTBL_Msk (1UL << SCB_HFSR_VECTTBL_Pos) /*!< SCB HFSR: VECTTBL Mask */
+
+/* SCB Debug Fault Status Register Definitions */
+#define SCB_DFSR_EXTERNAL_Pos 4U /*!< SCB DFSR: EXTERNAL Position */
+#define SCB_DFSR_EXTERNAL_Msk (1UL << SCB_DFSR_EXTERNAL_Pos) /*!< SCB DFSR: EXTERNAL Mask */
+
+#define SCB_DFSR_VCATCH_Pos 3U /*!< SCB DFSR: VCATCH Position */
+#define SCB_DFSR_VCATCH_Msk (1UL << SCB_DFSR_VCATCH_Pos) /*!< SCB DFSR: VCATCH Mask */
+
+#define SCB_DFSR_DWTTRAP_Pos 2U /*!< SCB DFSR: DWTTRAP Position */
+#define SCB_DFSR_DWTTRAP_Msk (1UL << SCB_DFSR_DWTTRAP_Pos) /*!< SCB DFSR: DWTTRAP Mask */
+
+#define SCB_DFSR_BKPT_Pos 1U /*!< SCB DFSR: BKPT Position */
+#define SCB_DFSR_BKPT_Msk (1UL << SCB_DFSR_BKPT_Pos) /*!< SCB DFSR: BKPT Mask */
+
+#define SCB_DFSR_HALTED_Pos 0U /*!< SCB DFSR: HALTED Position */
+#define SCB_DFSR_HALTED_Msk (1UL /*<< SCB_DFSR_HALTED_Pos*/) /*!< SCB DFSR: HALTED Mask */
+
+/*@} end of group CMSIS_SCB */
+
+
+/**
+ \ingroup CMSIS_core_register
+ \defgroup CMSIS_SCnSCB System Controls not in SCB (SCnSCB)
+ \brief Type definitions for the System Control and ID Register not in the SCB
+ @{
+ */
+
+/**
+ \brief Structure type to access the System Control and ID Register not in the SCB.
+ */
+typedef struct
+{
+ uint32_t RESERVED0[1U];
+ __IM uint32_t ICTR; /*!< Offset: 0x004 (R/ ) Interrupt Controller Type Register */
+ __IOM uint32_t ACTLR; /*!< Offset: 0x008 (R/W) Auxiliary Control Register */
+} SCnSCB_Type;
+
+/* Interrupt Controller Type Register Definitions */
+#define SCnSCB_ICTR_INTLINESNUM_Pos 0U /*!< ICTR: INTLINESNUM Position */
+#define SCnSCB_ICTR_INTLINESNUM_Msk (0xFUL /*<< SCnSCB_ICTR_INTLINESNUM_Pos*/) /*!< ICTR: INTLINESNUM Mask */
+
+/* Auxiliary Control Register Definitions */
+#define SCnSCB_ACTLR_DISOOFP_Pos 9U /*!< ACTLR: DISOOFP Position */
+#define SCnSCB_ACTLR_DISOOFP_Msk (1UL << SCnSCB_ACTLR_DISOOFP_Pos) /*!< ACTLR: DISOOFP Mask */
+
+#define SCnSCB_ACTLR_DISFPCA_Pos 8U /*!< ACTLR: DISFPCA Position */
+#define SCnSCB_ACTLR_DISFPCA_Msk (1UL << SCnSCB_ACTLR_DISFPCA_Pos) /*!< ACTLR: DISFPCA Mask */
+
+#define SCnSCB_ACTLR_DISFOLD_Pos 2U /*!< ACTLR: DISFOLD Position */
+#define SCnSCB_ACTLR_DISFOLD_Msk (1UL << SCnSCB_ACTLR_DISFOLD_Pos) /*!< ACTLR: DISFOLD Mask */
+
+#define SCnSCB_ACTLR_DISDEFWBUF_Pos 1U /*!< ACTLR: DISDEFWBUF Position */
+#define SCnSCB_ACTLR_DISDEFWBUF_Msk (1UL << SCnSCB_ACTLR_DISDEFWBUF_Pos) /*!< ACTLR: DISDEFWBUF Mask */
+
+#define SCnSCB_ACTLR_DISMCYCINT_Pos 0U /*!< ACTLR: DISMCYCINT Position */
+#define SCnSCB_ACTLR_DISMCYCINT_Msk (1UL /*<< SCnSCB_ACTLR_DISMCYCINT_Pos*/) /*!< ACTLR: DISMCYCINT Mask */
+
+/*@} end of group CMSIS_SCnotSCB */
+
+
+/**
+ \ingroup CMSIS_core_register
+ \defgroup CMSIS_SysTick System Tick Timer (SysTick)
+ \brief Type definitions for the System Timer Registers.
+ @{
+ */
+
+/**
+ \brief Structure type to access the System Timer (SysTick).
+ */
+typedef struct
+{
+ __IOM uint32_t CTRL; /*!< Offset: 0x000 (R/W) SysTick Control and Status Register */
+ __IOM uint32_t LOAD; /*!< Offset: 0x004 (R/W) SysTick Reload Value Register */
+ __IOM uint32_t VAL; /*!< Offset: 0x008 (R/W) SysTick Current Value Register */
+ __IM uint32_t CALIB; /*!< Offset: 0x00C (R/ ) SysTick Calibration Register */
+} SysTick_Type;
+
+/* SysTick Control / Status Register Definitions */
+#define SysTick_CTRL_COUNTFLAG_Pos 16U /*!< SysTick CTRL: COUNTFLAG Position */
+#define SysTick_CTRL_COUNTFLAG_Msk (1UL << SysTick_CTRL_COUNTFLAG_Pos) /*!< SysTick CTRL: COUNTFLAG Mask */
+
+#define SysTick_CTRL_CLKSOURCE_Pos 2U /*!< SysTick CTRL: CLKSOURCE Position */
+#define SysTick_CTRL_CLKSOURCE_Msk (1UL << SysTick_CTRL_CLKSOURCE_Pos) /*!< SysTick CTRL: CLKSOURCE Mask */
+
+#define SysTick_CTRL_TICKINT_Pos 1U /*!< SysTick CTRL: TICKINT Position */
+#define SysTick_CTRL_TICKINT_Msk (1UL << SysTick_CTRL_TICKINT_Pos) /*!< SysTick CTRL: TICKINT Mask */
+
+#define SysTick_CTRL_ENABLE_Pos 0U /*!< SysTick CTRL: ENABLE Position */
+#define SysTick_CTRL_ENABLE_Msk (1UL /*<< SysTick_CTRL_ENABLE_Pos*/) /*!< SysTick CTRL: ENABLE Mask */
+
+/* SysTick Reload Register Definitions */
+#define SysTick_LOAD_RELOAD_Pos 0U /*!< SysTick LOAD: RELOAD Position */
+#define SysTick_LOAD_RELOAD_Msk (0xFFFFFFUL /*<< SysTick_LOAD_RELOAD_Pos*/) /*!< SysTick LOAD: RELOAD Mask */
+
+/* SysTick Current Register Definitions */
+#define SysTick_VAL_CURRENT_Pos 0U /*!< SysTick VAL: CURRENT Position */
+#define SysTick_VAL_CURRENT_Msk (0xFFFFFFUL /*<< SysTick_VAL_CURRENT_Pos*/) /*!< SysTick VAL: CURRENT Mask */
+
+/* SysTick Calibration Register Definitions */
+#define SysTick_CALIB_NOREF_Pos 31U /*!< SysTick CALIB: NOREF Position */
+#define SysTick_CALIB_NOREF_Msk (1UL << SysTick_CALIB_NOREF_Pos) /*!< SysTick CALIB: NOREF Mask */
+
+#define SysTick_CALIB_SKEW_Pos 30U /*!< SysTick CALIB: SKEW Position */
+#define SysTick_CALIB_SKEW_Msk (1UL << SysTick_CALIB_SKEW_Pos) /*!< SysTick CALIB: SKEW Mask */
+
+#define SysTick_CALIB_TENMS_Pos 0U /*!< SysTick CALIB: TENMS Position */
+#define SysTick_CALIB_TENMS_Msk (0xFFFFFFUL /*<< SysTick_CALIB_TENMS_Pos*/) /*!< SysTick CALIB: TENMS Mask */
+
+/*@} end of group CMSIS_SysTick */
+
+
+/**
+ \ingroup CMSIS_core_register
+ \defgroup CMSIS_ITM Instrumentation Trace Macrocell (ITM)
+ \brief Type definitions for the Instrumentation Trace Macrocell (ITM)
+ @{
+ */
+
+/**
+ \brief Structure type to access the Instrumentation Trace Macrocell Register (ITM).
+ */
+typedef struct
+{
+ __OM union
+ {
+ __OM uint8_t u8; /*!< Offset: 0x000 ( /W) ITM Stimulus Port 8-bit */
+ __OM uint16_t u16; /*!< Offset: 0x000 ( /W) ITM Stimulus Port 16-bit */
+ __OM uint32_t u32; /*!< Offset: 0x000 ( /W) ITM Stimulus Port 32-bit */
+ } PORT [32U]; /*!< Offset: 0x000 ( /W) ITM Stimulus Port Registers */
+ uint32_t RESERVED0[864U];
+ __IOM uint32_t TER; /*!< Offset: 0xE00 (R/W) ITM Trace Enable Register */
+ uint32_t RESERVED1[15U];
+ __IOM uint32_t TPR; /*!< Offset: 0xE40 (R/W) ITM Trace Privilege Register */
+ uint32_t RESERVED2[15U];
+ __IOM uint32_t TCR; /*!< Offset: 0xE80 (R/W) ITM Trace Control Register */
+ uint32_t RESERVED3[29U];
+ __OM uint32_t IWR; /*!< Offset: 0xEF8 ( /W) ITM Integration Write Register */
+ __IM uint32_t IRR; /*!< Offset: 0xEFC (R/ ) ITM Integration Read Register */
+ __IOM uint32_t IMCR; /*!< Offset: 0xF00 (R/W) ITM Integration Mode Control Register */
+ uint32_t RESERVED4[43U];
+ __OM uint32_t LAR; /*!< Offset: 0xFB0 ( /W) ITM Lock Access Register */
+ __IM uint32_t LSR; /*!< Offset: 0xFB4 (R/ ) ITM Lock Status Register */
+ uint32_t RESERVED5[6U];
+ __IM uint32_t PID4; /*!< Offset: 0xFD0 (R/ ) ITM Peripheral Identification Register #4 */
+ __IM uint32_t PID5; /*!< Offset: 0xFD4 (R/ ) ITM Peripheral Identification Register #5 */
+ __IM uint32_t PID6; /*!< Offset: 0xFD8 (R/ ) ITM Peripheral Identification Register #6 */
+ __IM uint32_t PID7; /*!< Offset: 0xFDC (R/ ) ITM Peripheral Identification Register #7 */
+ __IM uint32_t PID0; /*!< Offset: 0xFE0 (R/ ) ITM Peripheral Identification Register #0 */
+ __IM uint32_t PID1; /*!< Offset: 0xFE4 (R/ ) ITM Peripheral Identification Register #1 */
+ __IM uint32_t PID2; /*!< Offset: 0xFE8 (R/ ) ITM Peripheral Identification Register #2 */
+ __IM uint32_t PID3; /*!< Offset: 0xFEC (R/ ) ITM Peripheral Identification Register #3 */
+ __IM uint32_t CID0; /*!< Offset: 0xFF0 (R/ ) ITM Component Identification Register #0 */
+ __IM uint32_t CID1; /*!< Offset: 0xFF4 (R/ ) ITM Component Identification Register #1 */
+ __IM uint32_t CID2; /*!< Offset: 0xFF8 (R/ ) ITM Component Identification Register #2 */
+ __IM uint32_t CID3; /*!< Offset: 0xFFC (R/ ) ITM Component Identification Register #3 */
+} ITM_Type;
+
+/* ITM Trace Privilege Register Definitions */
+#define ITM_TPR_PRIVMASK_Pos 0U /*!< ITM TPR: PRIVMASK Position */
+#define ITM_TPR_PRIVMASK_Msk (0xFUL /*<< ITM_TPR_PRIVMASK_Pos*/) /*!< ITM TPR: PRIVMASK Mask */
+
+/* ITM Trace Control Register Definitions */
+#define ITM_TCR_BUSY_Pos 23U /*!< ITM TCR: BUSY Position */
+#define ITM_TCR_BUSY_Msk (1UL << ITM_TCR_BUSY_Pos) /*!< ITM TCR: BUSY Mask */
+
+#define ITM_TCR_TraceBusID_Pos 16U /*!< ITM TCR: ATBID Position */
+#define ITM_TCR_TraceBusID_Msk (0x7FUL << ITM_TCR_TraceBusID_Pos) /*!< ITM TCR: ATBID Mask */
+
+#define ITM_TCR_GTSFREQ_Pos 10U /*!< ITM TCR: Global timestamp frequency Position */
+#define ITM_TCR_GTSFREQ_Msk (3UL << ITM_TCR_GTSFREQ_Pos) /*!< ITM TCR: Global timestamp frequency Mask */
+
+#define ITM_TCR_TSPrescale_Pos 8U /*!< ITM TCR: TSPrescale Position */
+#define ITM_TCR_TSPrescale_Msk (3UL << ITM_TCR_TSPrescale_Pos) /*!< ITM TCR: TSPrescale Mask */
+
+#define ITM_TCR_SWOENA_Pos 4U /*!< ITM TCR: SWOENA Position */
+#define ITM_TCR_SWOENA_Msk (1UL << ITM_TCR_SWOENA_Pos) /*!< ITM TCR: SWOENA Mask */
+
+#define ITM_TCR_DWTENA_Pos 3U /*!< ITM TCR: DWTENA Position */
+#define ITM_TCR_DWTENA_Msk (1UL << ITM_TCR_DWTENA_Pos) /*!< ITM TCR: DWTENA Mask */
+
+#define ITM_TCR_SYNCENA_Pos 2U /*!< ITM TCR: SYNCENA Position */
+#define ITM_TCR_SYNCENA_Msk (1UL << ITM_TCR_SYNCENA_Pos) /*!< ITM TCR: SYNCENA Mask */
+
+#define ITM_TCR_TSENA_Pos 1U /*!< ITM TCR: TSENA Position */
+#define ITM_TCR_TSENA_Msk (1UL << ITM_TCR_TSENA_Pos) /*!< ITM TCR: TSENA Mask */
+
+#define ITM_TCR_ITMENA_Pos 0U /*!< ITM TCR: ITM Enable bit Position */
+#define ITM_TCR_ITMENA_Msk (1UL /*<< ITM_TCR_ITMENA_Pos*/) /*!< ITM TCR: ITM Enable bit Mask */
+
+/* ITM Integration Write Register Definitions */
+#define ITM_IWR_ATVALIDM_Pos 0U /*!< ITM IWR: ATVALIDM Position */
+#define ITM_IWR_ATVALIDM_Msk (1UL /*<< ITM_IWR_ATVALIDM_Pos*/) /*!< ITM IWR: ATVALIDM Mask */
+
+/* ITM Integration Read Register Definitions */
+#define ITM_IRR_ATREADYM_Pos 0U /*!< ITM IRR: ATREADYM Position */
+#define ITM_IRR_ATREADYM_Msk (1UL /*<< ITM_IRR_ATREADYM_Pos*/) /*!< ITM IRR: ATREADYM Mask */
+
+/* ITM Integration Mode Control Register Definitions */
+#define ITM_IMCR_INTEGRATION_Pos 0U /*!< ITM IMCR: INTEGRATION Position */
+#define ITM_IMCR_INTEGRATION_Msk (1UL /*<< ITM_IMCR_INTEGRATION_Pos*/) /*!< ITM IMCR: INTEGRATION Mask */
+
+/* ITM Lock Status Register Definitions */
+#define ITM_LSR_ByteAcc_Pos 2U /*!< ITM LSR: ByteAcc Position */
+#define ITM_LSR_ByteAcc_Msk (1UL << ITM_LSR_ByteAcc_Pos) /*!< ITM LSR: ByteAcc Mask */
+
+#define ITM_LSR_Access_Pos 1U /*!< ITM LSR: Access Position */
+#define ITM_LSR_Access_Msk (1UL << ITM_LSR_Access_Pos) /*!< ITM LSR: Access Mask */
+
+#define ITM_LSR_Present_Pos 0U /*!< ITM LSR: Present Position */
+#define ITM_LSR_Present_Msk (1UL /*<< ITM_LSR_Present_Pos*/) /*!< ITM LSR: Present Mask */
+
+/*@}*/ /* end of group CMSIS_ITM */
+
+
+/**
+ \ingroup CMSIS_core_register
+ \defgroup CMSIS_DWT Data Watchpoint and Trace (DWT)
+ \brief Type definitions for the Data Watchpoint and Trace (DWT)
+ @{
+ */
+
+/**
+ \brief Structure type to access the Data Watchpoint and Trace Register (DWT).
+ */
+typedef struct
+{
+ __IOM uint32_t CTRL; /*!< Offset: 0x000 (R/W) Control Register */
+ __IOM uint32_t CYCCNT; /*!< Offset: 0x004 (R/W) Cycle Count Register */
+ __IOM uint32_t CPICNT; /*!< Offset: 0x008 (R/W) CPI Count Register */
+ __IOM uint32_t EXCCNT; /*!< Offset: 0x00C (R/W) Exception Overhead Count Register */
+ __IOM uint32_t SLEEPCNT; /*!< Offset: 0x010 (R/W) Sleep Count Register */
+ __IOM uint32_t LSUCNT; /*!< Offset: 0x014 (R/W) LSU Count Register */
+ __IOM uint32_t FOLDCNT; /*!< Offset: 0x018 (R/W) Folded-instruction Count Register */
+ __IM uint32_t PCSR; /*!< Offset: 0x01C (R/ ) Program Counter Sample Register */
+ __IOM uint32_t COMP0; /*!< Offset: 0x020 (R/W) Comparator Register 0 */
+ __IOM uint32_t MASK0; /*!< Offset: 0x024 (R/W) Mask Register 0 */
+ __IOM uint32_t FUNCTION0; /*!< Offset: 0x028 (R/W) Function Register 0 */
+ uint32_t RESERVED0[1U];
+ __IOM uint32_t COMP1; /*!< Offset: 0x030 (R/W) Comparator Register 1 */
+ __IOM uint32_t MASK1; /*!< Offset: 0x034 (R/W) Mask Register 1 */
+ __IOM uint32_t FUNCTION1; /*!< Offset: 0x038 (R/W) Function Register 1 */
+ uint32_t RESERVED1[1U];
+ __IOM uint32_t COMP2; /*!< Offset: 0x040 (R/W) Comparator Register 2 */
+ __IOM uint32_t MASK2; /*!< Offset: 0x044 (R/W) Mask Register 2 */
+ __IOM uint32_t FUNCTION2; /*!< Offset: 0x048 (R/W) Function Register 2 */
+ uint32_t RESERVED2[1U];
+ __IOM uint32_t COMP3; /*!< Offset: 0x050 (R/W) Comparator Register 3 */
+ __IOM uint32_t MASK3; /*!< Offset: 0x054 (R/W) Mask Register 3 */
+ __IOM uint32_t FUNCTION3; /*!< Offset: 0x058 (R/W) Function Register 3 */
+} DWT_Type;
+
+/* DWT Control Register Definitions */
+#define DWT_CTRL_NUMCOMP_Pos 28U /*!< DWT CTRL: NUMCOMP Position */
+#define DWT_CTRL_NUMCOMP_Msk (0xFUL << DWT_CTRL_NUMCOMP_Pos) /*!< DWT CTRL: NUMCOMP Mask */
+
+#define DWT_CTRL_NOTRCPKT_Pos 27U /*!< DWT CTRL: NOTRCPKT Position */
+#define DWT_CTRL_NOTRCPKT_Msk (0x1UL << DWT_CTRL_NOTRCPKT_Pos) /*!< DWT CTRL: NOTRCPKT Mask */
+
+#define DWT_CTRL_NOEXTTRIG_Pos 26U /*!< DWT CTRL: NOEXTTRIG Position */
+#define DWT_CTRL_NOEXTTRIG_Msk (0x1UL << DWT_CTRL_NOEXTTRIG_Pos) /*!< DWT CTRL: NOEXTTRIG Mask */
+
+#define DWT_CTRL_NOCYCCNT_Pos 25U /*!< DWT CTRL: NOCYCCNT Position */
+#define DWT_CTRL_NOCYCCNT_Msk (0x1UL << DWT_CTRL_NOCYCCNT_Pos) /*!< DWT CTRL: NOCYCCNT Mask */
+
+#define DWT_CTRL_NOPRFCNT_Pos 24U /*!< DWT CTRL: NOPRFCNT Position */
+#define DWT_CTRL_NOPRFCNT_Msk (0x1UL << DWT_CTRL_NOPRFCNT_Pos) /*!< DWT CTRL: NOPRFCNT Mask */
+
+#define DWT_CTRL_CYCEVTENA_Pos 22U /*!< DWT CTRL: CYCEVTENA Position */
+#define DWT_CTRL_CYCEVTENA_Msk (0x1UL << DWT_CTRL_CYCEVTENA_Pos) /*!< DWT CTRL: CYCEVTENA Mask */
+
+#define DWT_CTRL_FOLDEVTENA_Pos 21U /*!< DWT CTRL: FOLDEVTENA Position */
+#define DWT_CTRL_FOLDEVTENA_Msk (0x1UL << DWT_CTRL_FOLDEVTENA_Pos) /*!< DWT CTRL: FOLDEVTENA Mask */
+
+#define DWT_CTRL_LSUEVTENA_Pos 20U /*!< DWT CTRL: LSUEVTENA Position */
+#define DWT_CTRL_LSUEVTENA_Msk (0x1UL << DWT_CTRL_LSUEVTENA_Pos) /*!< DWT CTRL: LSUEVTENA Mask */
+
+#define DWT_CTRL_SLEEPEVTENA_Pos 19U /*!< DWT CTRL: SLEEPEVTENA Position */
+#define DWT_CTRL_SLEEPEVTENA_Msk (0x1UL << DWT_CTRL_SLEEPEVTENA_Pos) /*!< DWT CTRL: SLEEPEVTENA Mask */
+
+#define DWT_CTRL_EXCEVTENA_Pos 18U /*!< DWT CTRL: EXCEVTENA Position */
+#define DWT_CTRL_EXCEVTENA_Msk (0x1UL << DWT_CTRL_EXCEVTENA_Pos) /*!< DWT CTRL: EXCEVTENA Mask */
+
+#define DWT_CTRL_CPIEVTENA_Pos 17U /*!< DWT CTRL: CPIEVTENA Position */
+#define DWT_CTRL_CPIEVTENA_Msk (0x1UL << DWT_CTRL_CPIEVTENA_Pos) /*!< DWT CTRL: CPIEVTENA Mask */
+
+#define DWT_CTRL_EXCTRCENA_Pos 16U /*!< DWT CTRL: EXCTRCENA Position */
+#define DWT_CTRL_EXCTRCENA_Msk (0x1UL << DWT_CTRL_EXCTRCENA_Pos) /*!< DWT CTRL: EXCTRCENA Mask */
+
+#define DWT_CTRL_PCSAMPLENA_Pos 12U /*!< DWT CTRL: PCSAMPLENA Position */
+#define DWT_CTRL_PCSAMPLENA_Msk (0x1UL << DWT_CTRL_PCSAMPLENA_Pos) /*!< DWT CTRL: PCSAMPLENA Mask */
+
+#define DWT_CTRL_SYNCTAP_Pos 10U /*!< DWT CTRL: SYNCTAP Position */
+#define DWT_CTRL_SYNCTAP_Msk (0x3UL << DWT_CTRL_SYNCTAP_Pos) /*!< DWT CTRL: SYNCTAP Mask */
+
+#define DWT_CTRL_CYCTAP_Pos 9U /*!< DWT CTRL: CYCTAP Position */
+#define DWT_CTRL_CYCTAP_Msk (0x1UL << DWT_CTRL_CYCTAP_Pos) /*!< DWT CTRL: CYCTAP Mask */
+
+#define DWT_CTRL_POSTINIT_Pos 5U /*!< DWT CTRL: POSTINIT Position */
+#define DWT_CTRL_POSTINIT_Msk (0xFUL << DWT_CTRL_POSTINIT_Pos) /*!< DWT CTRL: POSTINIT Mask */
+
+#define DWT_CTRL_POSTPRESET_Pos 1U /*!< DWT CTRL: POSTPRESET Position */
+#define DWT_CTRL_POSTPRESET_Msk (0xFUL << DWT_CTRL_POSTPRESET_Pos) /*!< DWT CTRL: POSTPRESET Mask */
+
+#define DWT_CTRL_CYCCNTENA_Pos 0U /*!< DWT CTRL: CYCCNTENA Position */
+#define DWT_CTRL_CYCCNTENA_Msk (0x1UL /*<< DWT_CTRL_CYCCNTENA_Pos*/) /*!< DWT CTRL: CYCCNTENA Mask */
+
+/* DWT CPI Count Register Definitions */
+#define DWT_CPICNT_CPICNT_Pos 0U /*!< DWT CPICNT: CPICNT Position */
+#define DWT_CPICNT_CPICNT_Msk (0xFFUL /*<< DWT_CPICNT_CPICNT_Pos*/) /*!< DWT CPICNT: CPICNT Mask */
+
+/* DWT Exception Overhead Count Register Definitions */
+#define DWT_EXCCNT_EXCCNT_Pos 0U /*!< DWT EXCCNT: EXCCNT Position */
+#define DWT_EXCCNT_EXCCNT_Msk (0xFFUL /*<< DWT_EXCCNT_EXCCNT_Pos*/) /*!< DWT EXCCNT: EXCCNT Mask */
+
+/* DWT Sleep Count Register Definitions */
+#define DWT_SLEEPCNT_SLEEPCNT_Pos 0U /*!< DWT SLEEPCNT: SLEEPCNT Position */
+#define DWT_SLEEPCNT_SLEEPCNT_Msk (0xFFUL /*<< DWT_SLEEPCNT_SLEEPCNT_Pos*/) /*!< DWT SLEEPCNT: SLEEPCNT Mask */
+
+/* DWT LSU Count Register Definitions */
+#define DWT_LSUCNT_LSUCNT_Pos 0U /*!< DWT LSUCNT: LSUCNT Position */
+#define DWT_LSUCNT_LSUCNT_Msk (0xFFUL /*<< DWT_LSUCNT_LSUCNT_Pos*/) /*!< DWT LSUCNT: LSUCNT Mask */
+
+/* DWT Folded-instruction Count Register Definitions */
+#define DWT_FOLDCNT_FOLDCNT_Pos 0U /*!< DWT FOLDCNT: FOLDCNT Position */
+#define DWT_FOLDCNT_FOLDCNT_Msk (0xFFUL /*<< DWT_FOLDCNT_FOLDCNT_Pos*/) /*!< DWT FOLDCNT: FOLDCNT Mask */
+
+/* DWT Comparator Mask Register Definitions */
+#define DWT_MASK_MASK_Pos 0U /*!< DWT MASK: MASK Position */
+#define DWT_MASK_MASK_Msk (0x1FUL /*<< DWT_MASK_MASK_Pos*/) /*!< DWT MASK: MASK Mask */
+
+/* DWT Comparator Function Register Definitions */
+#define DWT_FUNCTION_MATCHED_Pos 24U /*!< DWT FUNCTION: MATCHED Position */
+#define DWT_FUNCTION_MATCHED_Msk (0x1UL << DWT_FUNCTION_MATCHED_Pos) /*!< DWT FUNCTION: MATCHED Mask */
+
+#define DWT_FUNCTION_DATAVADDR1_Pos 16U /*!< DWT FUNCTION: DATAVADDR1 Position */
+#define DWT_FUNCTION_DATAVADDR1_Msk (0xFUL << DWT_FUNCTION_DATAVADDR1_Pos) /*!< DWT FUNCTION: DATAVADDR1 Mask */
+
+#define DWT_FUNCTION_DATAVADDR0_Pos 12U /*!< DWT FUNCTION: DATAVADDR0 Position */
+#define DWT_FUNCTION_DATAVADDR0_Msk (0xFUL << DWT_FUNCTION_DATAVADDR0_Pos) /*!< DWT FUNCTION: DATAVADDR0 Mask */
+
+#define DWT_FUNCTION_DATAVSIZE_Pos 10U /*!< DWT FUNCTION: DATAVSIZE Position */
+#define DWT_FUNCTION_DATAVSIZE_Msk (0x3UL << DWT_FUNCTION_DATAVSIZE_Pos) /*!< DWT FUNCTION: DATAVSIZE Mask */
+
+#define DWT_FUNCTION_LNK1ENA_Pos 9U /*!< DWT FUNCTION: LNK1ENA Position */
+#define DWT_FUNCTION_LNK1ENA_Msk (0x1UL << DWT_FUNCTION_LNK1ENA_Pos) /*!< DWT FUNCTION: LNK1ENA Mask */
+
+#define DWT_FUNCTION_DATAVMATCH_Pos 8U /*!< DWT FUNCTION: DATAVMATCH Position */
+#define DWT_FUNCTION_DATAVMATCH_Msk (0x1UL << DWT_FUNCTION_DATAVMATCH_Pos) /*!< DWT FUNCTION: DATAVMATCH Mask */
+
+#define DWT_FUNCTION_CYCMATCH_Pos 7U /*!< DWT FUNCTION: CYCMATCH Position */
+#define DWT_FUNCTION_CYCMATCH_Msk (0x1UL << DWT_FUNCTION_CYCMATCH_Pos) /*!< DWT FUNCTION: CYCMATCH Mask */
+
+#define DWT_FUNCTION_EMITRANGE_Pos 5U /*!< DWT FUNCTION: EMITRANGE Position */
+#define DWT_FUNCTION_EMITRANGE_Msk (0x1UL << DWT_FUNCTION_EMITRANGE_Pos) /*!< DWT FUNCTION: EMITRANGE Mask */
+
+#define DWT_FUNCTION_FUNCTION_Pos 0U /*!< DWT FUNCTION: FUNCTION Position */
+#define DWT_FUNCTION_FUNCTION_Msk (0xFUL /*<< DWT_FUNCTION_FUNCTION_Pos*/) /*!< DWT FUNCTION: FUNCTION Mask */
+
+/*@}*/ /* end of group CMSIS_DWT */
+
+
+/**
+ \ingroup CMSIS_core_register
+ \defgroup CMSIS_TPI Trace Port Interface (TPI)
+ \brief Type definitions for the Trace Port Interface (TPI)
+ @{
+ */
+
+/**
+ \brief Structure type to access the Trace Port Interface Register (TPI).
+ */
+typedef struct
+{
+ __IOM uint32_t SSPSR; /*!< Offset: 0x000 (R/ ) Supported Parallel Port Size Register */
+ __IOM uint32_t CSPSR; /*!< Offset: 0x004 (R/W) Current Parallel Port Size Register */
+ uint32_t RESERVED0[2U];
+ __IOM uint32_t ACPR; /*!< Offset: 0x010 (R/W) Asynchronous Clock Prescaler Register */
+ uint32_t RESERVED1[55U];
+ __IOM uint32_t SPPR; /*!< Offset: 0x0F0 (R/W) Selected Pin Protocol Register */
+ uint32_t RESERVED2[131U];
+ __IM uint32_t FFSR; /*!< Offset: 0x300 (R/ ) Formatter and Flush Status Register */
+ __IOM uint32_t FFCR; /*!< Offset: 0x304 (R/W) Formatter and Flush Control Register */
+ __IM uint32_t FSCR; /*!< Offset: 0x308 (R/ ) Formatter Synchronization Counter Register */
+ uint32_t RESERVED3[759U];
+ __IM uint32_t TRIGGER; /*!< Offset: 0xEE8 (R/ ) TRIGGER */
+ __IM uint32_t FIFO0; /*!< Offset: 0xEEC (R/ ) Integration ETM Data */
+ __IM uint32_t ITATBCTR2; /*!< Offset: 0xEF0 (R/ ) ITATBCTR2 */
+ uint32_t RESERVED4[1U];
+ __IM uint32_t ITATBCTR0; /*!< Offset: 0xEF8 (R/ ) ITATBCTR0 */
+ __IM uint32_t FIFO1; /*!< Offset: 0xEFC (R/ ) Integration ITM Data */
+ __IOM uint32_t ITCTRL; /*!< Offset: 0xF00 (R/W) Integration Mode Control */
+ uint32_t RESERVED5[39U];
+ __IOM uint32_t CLAIMSET; /*!< Offset: 0xFA0 (R/W) Claim tag set */
+ __IOM uint32_t CLAIMCLR; /*!< Offset: 0xFA4 (R/W) Claim tag clear */
+ uint32_t RESERVED7[8U];
+ __IM uint32_t DEVID; /*!< Offset: 0xFC8 (R/ ) TPIU_DEVID */
+ __IM uint32_t DEVTYPE; /*!< Offset: 0xFCC (R/ ) TPIU_DEVTYPE */
+} TPI_Type;
+
+/* TPI Asynchronous Clock Prescaler Register Definitions */
+#define TPI_ACPR_PRESCALER_Pos 0U /*!< TPI ACPR: PRESCALER Position */
+#define TPI_ACPR_PRESCALER_Msk (0x1FFFUL /*<< TPI_ACPR_PRESCALER_Pos*/) /*!< TPI ACPR: PRESCALER Mask */
+
+/* TPI Selected Pin Protocol Register Definitions */
+#define TPI_SPPR_TXMODE_Pos 0U /*!< TPI SPPR: TXMODE Position */
+#define TPI_SPPR_TXMODE_Msk (0x3UL /*<< TPI_SPPR_TXMODE_Pos*/) /*!< TPI SPPR: TXMODE Mask */
+
+/* TPI Formatter and Flush Status Register Definitions */
+#define TPI_FFSR_FtNonStop_Pos 3U /*!< TPI FFSR: FtNonStop Position */
+#define TPI_FFSR_FtNonStop_Msk (0x1UL << TPI_FFSR_FtNonStop_Pos) /*!< TPI FFSR: FtNonStop Mask */
+
+#define TPI_FFSR_TCPresent_Pos 2U /*!< TPI FFSR: TCPresent Position */
+#define TPI_FFSR_TCPresent_Msk (0x1UL << TPI_FFSR_TCPresent_Pos) /*!< TPI FFSR: TCPresent Mask */
+
+#define TPI_FFSR_FtStopped_Pos 1U /*!< TPI FFSR: FtStopped Position */
+#define TPI_FFSR_FtStopped_Msk (0x1UL << TPI_FFSR_FtStopped_Pos) /*!< TPI FFSR: FtStopped Mask */
+
+#define TPI_FFSR_FlInProg_Pos 0U /*!< TPI FFSR: FlInProg Position */
+#define TPI_FFSR_FlInProg_Msk (0x1UL /*<< TPI_FFSR_FlInProg_Pos*/) /*!< TPI FFSR: FlInProg Mask */
+
+/* TPI Formatter and Flush Control Register Definitions */
+#define TPI_FFCR_TrigIn_Pos 8U /*!< TPI FFCR: TrigIn Position */
+#define TPI_FFCR_TrigIn_Msk (0x1UL << TPI_FFCR_TrigIn_Pos) /*!< TPI FFCR: TrigIn Mask */
+
+#define TPI_FFCR_EnFCont_Pos 1U /*!< TPI FFCR: EnFCont Position */
+#define TPI_FFCR_EnFCont_Msk (0x1UL << TPI_FFCR_EnFCont_Pos) /*!< TPI FFCR: EnFCont Mask */
+
+/* TPI TRIGGER Register Definitions */
+#define TPI_TRIGGER_TRIGGER_Pos 0U /*!< TPI TRIGGER: TRIGGER Position */
+#define TPI_TRIGGER_TRIGGER_Msk (0x1UL /*<< TPI_TRIGGER_TRIGGER_Pos*/) /*!< TPI TRIGGER: TRIGGER Mask */
+
+/* TPI Integration ETM Data Register Definitions (FIFO0) */
+#define TPI_FIFO0_ITM_ATVALID_Pos 29U /*!< TPI FIFO0: ITM_ATVALID Position */
+#define TPI_FIFO0_ITM_ATVALID_Msk (0x3UL << TPI_FIFO0_ITM_ATVALID_Pos) /*!< TPI FIFO0: ITM_ATVALID Mask */
+
+#define TPI_FIFO0_ITM_bytecount_Pos 27U /*!< TPI FIFO0: ITM_bytecount Position */
+#define TPI_FIFO0_ITM_bytecount_Msk (0x3UL << TPI_FIFO0_ITM_bytecount_Pos) /*!< TPI FIFO0: ITM_bytecount Mask */
+
+#define TPI_FIFO0_ETM_ATVALID_Pos 26U /*!< TPI FIFO0: ETM_ATVALID Position */
+#define TPI_FIFO0_ETM_ATVALID_Msk (0x3UL << TPI_FIFO0_ETM_ATVALID_Pos) /*!< TPI FIFO0: ETM_ATVALID Mask */
+
+#define TPI_FIFO0_ETM_bytecount_Pos 24U /*!< TPI FIFO0: ETM_bytecount Position */
+#define TPI_FIFO0_ETM_bytecount_Msk (0x3UL << TPI_FIFO0_ETM_bytecount_Pos) /*!< TPI FIFO0: ETM_bytecount Mask */
+
+#define TPI_FIFO0_ETM2_Pos 16U /*!< TPI FIFO0: ETM2 Position */
+#define TPI_FIFO0_ETM2_Msk (0xFFUL << TPI_FIFO0_ETM2_Pos) /*!< TPI FIFO0: ETM2 Mask */
+
+#define TPI_FIFO0_ETM1_Pos 8U /*!< TPI FIFO0: ETM1 Position */
+#define TPI_FIFO0_ETM1_Msk (0xFFUL << TPI_FIFO0_ETM1_Pos) /*!< TPI FIFO0: ETM1 Mask */
+
+#define TPI_FIFO0_ETM0_Pos 0U /*!< TPI FIFO0: ETM0 Position */
+#define TPI_FIFO0_ETM0_Msk (0xFFUL /*<< TPI_FIFO0_ETM0_Pos*/) /*!< TPI FIFO0: ETM0 Mask */
+
+/* TPI ITATBCTR2 Register Definitions */
+#define TPI_ITATBCTR2_ATREADY_Pos 0U /*!< TPI ITATBCTR2: ATREADY Position */
+#define TPI_ITATBCTR2_ATREADY_Msk (0x1UL /*<< TPI_ITATBCTR2_ATREADY_Pos*/) /*!< TPI ITATBCTR2: ATREADY Mask */
+
+/* TPI Integration ITM Data Register Definitions (FIFO1) */
+#define TPI_FIFO1_ITM_ATVALID_Pos 29U /*!< TPI FIFO1: ITM_ATVALID Position */
+#define TPI_FIFO1_ITM_ATVALID_Msk (0x3UL << TPI_FIFO1_ITM_ATVALID_Pos) /*!< TPI FIFO1: ITM_ATVALID Mask */
+
+#define TPI_FIFO1_ITM_bytecount_Pos 27U /*!< TPI FIFO1: ITM_bytecount Position */
+#define TPI_FIFO1_ITM_bytecount_Msk (0x3UL << TPI_FIFO1_ITM_bytecount_Pos) /*!< TPI FIFO1: ITM_bytecount Mask */
+
+#define TPI_FIFO1_ETM_ATVALID_Pos 26U /*!< TPI FIFO1: ETM_ATVALID Position */
+#define TPI_FIFO1_ETM_ATVALID_Msk (0x3UL << TPI_FIFO1_ETM_ATVALID_Pos) /*!< TPI FIFO1: ETM_ATVALID Mask */
+
+#define TPI_FIFO1_ETM_bytecount_Pos 24U /*!< TPI FIFO1: ETM_bytecount Position */
+#define TPI_FIFO1_ETM_bytecount_Msk (0x3UL << TPI_FIFO1_ETM_bytecount_Pos) /*!< TPI FIFO1: ETM_bytecount Mask */
+
+#define TPI_FIFO1_ITM2_Pos 16U /*!< TPI FIFO1: ITM2 Position */
+#define TPI_FIFO1_ITM2_Msk (0xFFUL << TPI_FIFO1_ITM2_Pos) /*!< TPI FIFO1: ITM2 Mask */
+
+#define TPI_FIFO1_ITM1_Pos 8U /*!< TPI FIFO1: ITM1 Position */
+#define TPI_FIFO1_ITM1_Msk (0xFFUL << TPI_FIFO1_ITM1_Pos) /*!< TPI FIFO1: ITM1 Mask */
+
+#define TPI_FIFO1_ITM0_Pos 0U /*!< TPI FIFO1: ITM0 Position */
+#define TPI_FIFO1_ITM0_Msk (0xFFUL /*<< TPI_FIFO1_ITM0_Pos*/) /*!< TPI FIFO1: ITM0 Mask */
+
+/* TPI ITATBCTR0 Register Definitions */
+#define TPI_ITATBCTR0_ATREADY_Pos 0U /*!< TPI ITATBCTR0: ATREADY Position */
+#define TPI_ITATBCTR0_ATREADY_Msk (0x1UL /*<< TPI_ITATBCTR0_ATREADY_Pos*/) /*!< TPI ITATBCTR0: ATREADY Mask */
+
+/* TPI Integration Mode Control Register Definitions */
+#define TPI_ITCTRL_Mode_Pos 0U /*!< TPI ITCTRL: Mode Position */
+#define TPI_ITCTRL_Mode_Msk (0x1UL /*<< TPI_ITCTRL_Mode_Pos*/) /*!< TPI ITCTRL: Mode Mask */
+
+/* TPI DEVID Register Definitions */
+#define TPI_DEVID_NRZVALID_Pos 11U /*!< TPI DEVID: NRZVALID Position */
+#define TPI_DEVID_NRZVALID_Msk (0x1UL << TPI_DEVID_NRZVALID_Pos) /*!< TPI DEVID: NRZVALID Mask */
+
+#define TPI_DEVID_MANCVALID_Pos 10U /*!< TPI DEVID: MANCVALID Position */
+#define TPI_DEVID_MANCVALID_Msk (0x1UL << TPI_DEVID_MANCVALID_Pos) /*!< TPI DEVID: MANCVALID Mask */
+
+#define TPI_DEVID_PTINVALID_Pos 9U /*!< TPI DEVID: PTINVALID Position */
+#define TPI_DEVID_PTINVALID_Msk (0x1UL << TPI_DEVID_PTINVALID_Pos) /*!< TPI DEVID: PTINVALID Mask */
+
+#define TPI_DEVID_MinBufSz_Pos 6U /*!< TPI DEVID: MinBufSz Position */
+#define TPI_DEVID_MinBufSz_Msk (0x7UL << TPI_DEVID_MinBufSz_Pos) /*!< TPI DEVID: MinBufSz Mask */
+
+#define TPI_DEVID_AsynClkIn_Pos 5U /*!< TPI DEVID: AsynClkIn Position */
+#define TPI_DEVID_AsynClkIn_Msk (0x1UL << TPI_DEVID_AsynClkIn_Pos) /*!< TPI DEVID: AsynClkIn Mask */
+
+#define TPI_DEVID_NrTraceInput_Pos 0U /*!< TPI DEVID: NrTraceInput Position */
+#define TPI_DEVID_NrTraceInput_Msk (0x1FUL /*<< TPI_DEVID_NrTraceInput_Pos*/) /*!< TPI DEVID: NrTraceInput Mask */
+
+/* TPI DEVTYPE Register Definitions */
+#define TPI_DEVTYPE_MajorType_Pos 4U /*!< TPI DEVTYPE: MajorType Position */
+#define TPI_DEVTYPE_MajorType_Msk (0xFUL << TPI_DEVTYPE_MajorType_Pos) /*!< TPI DEVTYPE: MajorType Mask */
+
+#define TPI_DEVTYPE_SubType_Pos 0U /*!< TPI DEVTYPE: SubType Position */
+#define TPI_DEVTYPE_SubType_Msk (0xFUL /*<< TPI_DEVTYPE_SubType_Pos*/) /*!< TPI DEVTYPE: SubType Mask */
+
+/*@}*/ /* end of group CMSIS_TPI */
+
+
+#if (__MPU_PRESENT == 1U)
+/**
+ \ingroup CMSIS_core_register
+ \defgroup CMSIS_MPU Memory Protection Unit (MPU)
+ \brief Type definitions for the Memory Protection Unit (MPU)
+ @{
+ */
+
+/**
+ \brief Structure type to access the Memory Protection Unit (MPU).
+ */
+typedef struct
+{
+ __IM uint32_t TYPE; /*!< Offset: 0x000 (R/ ) MPU Type Register */
+ __IOM uint32_t CTRL; /*!< Offset: 0x004 (R/W) MPU Control Register */
+ __IOM uint32_t RNR; /*!< Offset: 0x008 (R/W) MPU Region RNRber Register */
+ __IOM uint32_t RBAR; /*!< Offset: 0x00C (R/W) MPU Region Base Address Register */
+ __IOM uint32_t RASR; /*!< Offset: 0x010 (R/W) MPU Region Attribute and Size Register */
+ __IOM uint32_t RBAR_A1; /*!< Offset: 0x014 (R/W) MPU Alias 1 Region Base Address Register */
+ __IOM uint32_t RASR_A1; /*!< Offset: 0x018 (R/W) MPU Alias 1 Region Attribute and Size Register */
+ __IOM uint32_t RBAR_A2; /*!< Offset: 0x01C (R/W) MPU Alias 2 Region Base Address Register */
+ __IOM uint32_t RASR_A2; /*!< Offset: 0x020 (R/W) MPU Alias 2 Region Attribute and Size Register */
+ __IOM uint32_t RBAR_A3; /*!< Offset: 0x024 (R/W) MPU Alias 3 Region Base Address Register */
+ __IOM uint32_t RASR_A3; /*!< Offset: 0x028 (R/W) MPU Alias 3 Region Attribute and Size Register */
+} MPU_Type;
+
+/* MPU Type Register Definitions */
+#define MPU_TYPE_IREGION_Pos 16U /*!< MPU TYPE: IREGION Position */
+#define MPU_TYPE_IREGION_Msk (0xFFUL << MPU_TYPE_IREGION_Pos) /*!< MPU TYPE: IREGION Mask */
+
+#define MPU_TYPE_DREGION_Pos 8U /*!< MPU TYPE: DREGION Position */
+#define MPU_TYPE_DREGION_Msk (0xFFUL << MPU_TYPE_DREGION_Pos) /*!< MPU TYPE: DREGION Mask */
+
+#define MPU_TYPE_SEPARATE_Pos 0U /*!< MPU TYPE: SEPARATE Position */
+#define MPU_TYPE_SEPARATE_Msk (1UL /*<< MPU_TYPE_SEPARATE_Pos*/) /*!< MPU TYPE: SEPARATE Mask */
+
+/* MPU Control Register Definitions */
+#define MPU_CTRL_PRIVDEFENA_Pos 2U /*!< MPU CTRL: PRIVDEFENA Position */
+#define MPU_CTRL_PRIVDEFENA_Msk (1UL << MPU_CTRL_PRIVDEFENA_Pos) /*!< MPU CTRL: PRIVDEFENA Mask */
+
+#define MPU_CTRL_HFNMIENA_Pos 1U /*!< MPU CTRL: HFNMIENA Position */
+#define MPU_CTRL_HFNMIENA_Msk (1UL << MPU_CTRL_HFNMIENA_Pos) /*!< MPU CTRL: HFNMIENA Mask */
+
+#define MPU_CTRL_ENABLE_Pos 0U /*!< MPU CTRL: ENABLE Position */
+#define MPU_CTRL_ENABLE_Msk (1UL /*<< MPU_CTRL_ENABLE_Pos*/) /*!< MPU CTRL: ENABLE Mask */
+
+/* MPU Region Number Register Definitions */
+#define MPU_RNR_REGION_Pos 0U /*!< MPU RNR: REGION Position */
+#define MPU_RNR_REGION_Msk (0xFFUL /*<< MPU_RNR_REGION_Pos*/) /*!< MPU RNR: REGION Mask */
+
+/* MPU Region Base Address Register Definitions */
+#define MPU_RBAR_ADDR_Pos 5U /*!< MPU RBAR: ADDR Position */
+#define MPU_RBAR_ADDR_Msk (0x7FFFFFFUL << MPU_RBAR_ADDR_Pos) /*!< MPU RBAR: ADDR Mask */
+
+#define MPU_RBAR_VALID_Pos 4U /*!< MPU RBAR: VALID Position */
+#define MPU_RBAR_VALID_Msk (1UL << MPU_RBAR_VALID_Pos) /*!< MPU RBAR: VALID Mask */
+
+#define MPU_RBAR_REGION_Pos 0U /*!< MPU RBAR: REGION Position */
+#define MPU_RBAR_REGION_Msk (0xFUL /*<< MPU_RBAR_REGION_Pos*/) /*!< MPU RBAR: REGION Mask */
+
+/* MPU Region Attribute and Size Register Definitions */
+#define MPU_RASR_ATTRS_Pos 16U /*!< MPU RASR: MPU Region Attribute field Position */
+#define MPU_RASR_ATTRS_Msk (0xFFFFUL << MPU_RASR_ATTRS_Pos) /*!< MPU RASR: MPU Region Attribute field Mask */
+
+#define MPU_RASR_XN_Pos 28U /*!< MPU RASR: ATTRS.XN Position */
+#define MPU_RASR_XN_Msk (1UL << MPU_RASR_XN_Pos) /*!< MPU RASR: ATTRS.XN Mask */
+
+#define MPU_RASR_AP_Pos 24U /*!< MPU RASR: ATTRS.AP Position */
+#define MPU_RASR_AP_Msk (0x7UL << MPU_RASR_AP_Pos) /*!< MPU RASR: ATTRS.AP Mask */
+
+#define MPU_RASR_TEX_Pos 19U /*!< MPU RASR: ATTRS.TEX Position */
+#define MPU_RASR_TEX_Msk (0x7UL << MPU_RASR_TEX_Pos) /*!< MPU RASR: ATTRS.TEX Mask */
+
+#define MPU_RASR_S_Pos 18U /*!< MPU RASR: ATTRS.S Position */
+#define MPU_RASR_S_Msk (1UL << MPU_RASR_S_Pos) /*!< MPU RASR: ATTRS.S Mask */
+
+#define MPU_RASR_C_Pos 17U /*!< MPU RASR: ATTRS.C Position */
+#define MPU_RASR_C_Msk (1UL << MPU_RASR_C_Pos) /*!< MPU RASR: ATTRS.C Mask */
+
+#define MPU_RASR_B_Pos 16U /*!< MPU RASR: ATTRS.B Position */
+#define MPU_RASR_B_Msk (1UL << MPU_RASR_B_Pos) /*!< MPU RASR: ATTRS.B Mask */
+
+#define MPU_RASR_SRD_Pos 8U /*!< MPU RASR: Sub-Region Disable Position */
+#define MPU_RASR_SRD_Msk (0xFFUL << MPU_RASR_SRD_Pos) /*!< MPU RASR: Sub-Region Disable Mask */
+
+#define MPU_RASR_SIZE_Pos 1U /*!< MPU RASR: Region Size Field Position */
+#define MPU_RASR_SIZE_Msk (0x1FUL << MPU_RASR_SIZE_Pos) /*!< MPU RASR: Region Size Field Mask */
+
+#define MPU_RASR_ENABLE_Pos 0U /*!< MPU RASR: Region enable bit Position */
+#define MPU_RASR_ENABLE_Msk (1UL /*<< MPU_RASR_ENABLE_Pos*/) /*!< MPU RASR: Region enable bit Disable Mask */
+
+/*@} end of group CMSIS_MPU */
+#endif
+
+
+#if (__FPU_PRESENT == 1U)
+/**
+ \ingroup CMSIS_core_register
+ \defgroup CMSIS_FPU Floating Point Unit (FPU)
+ \brief Type definitions for the Floating Point Unit (FPU)
+ @{
+ */
+
+/**
+ \brief Structure type to access the Floating Point Unit (FPU).
+ */
+typedef struct
+{
+ uint32_t RESERVED0[1U];
+ __IOM uint32_t FPCCR; /*!< Offset: 0x004 (R/W) Floating-Point Context Control Register */
+ __IOM uint32_t FPCAR; /*!< Offset: 0x008 (R/W) Floating-Point Context Address Register */
+ __IOM uint32_t FPDSCR; /*!< Offset: 0x00C (R/W) Floating-Point Default Status Control Register */
+ __IM uint32_t MVFR0; /*!< Offset: 0x010 (R/ ) Media and FP Feature Register 0 */
+ __IM uint32_t MVFR1; /*!< Offset: 0x014 (R/ ) Media and FP Feature Register 1 */
+} FPU_Type;
+
+/* Floating-Point Context Control Register Definitions */
+#define FPU_FPCCR_ASPEN_Pos 31U /*!< FPCCR: ASPEN bit Position */
+#define FPU_FPCCR_ASPEN_Msk (1UL << FPU_FPCCR_ASPEN_Pos) /*!< FPCCR: ASPEN bit Mask */
+
+#define FPU_FPCCR_LSPEN_Pos 30U /*!< FPCCR: LSPEN Position */
+#define FPU_FPCCR_LSPEN_Msk (1UL << FPU_FPCCR_LSPEN_Pos) /*!< FPCCR: LSPEN bit Mask */
+
+#define FPU_FPCCR_MONRDY_Pos 8U /*!< FPCCR: MONRDY Position */
+#define FPU_FPCCR_MONRDY_Msk (1UL << FPU_FPCCR_MONRDY_Pos) /*!< FPCCR: MONRDY bit Mask */
+
+#define FPU_FPCCR_BFRDY_Pos 6U /*!< FPCCR: BFRDY Position */
+#define FPU_FPCCR_BFRDY_Msk (1UL << FPU_FPCCR_BFRDY_Pos) /*!< FPCCR: BFRDY bit Mask */
+
+#define FPU_FPCCR_MMRDY_Pos 5U /*!< FPCCR: MMRDY Position */
+#define FPU_FPCCR_MMRDY_Msk (1UL << FPU_FPCCR_MMRDY_Pos) /*!< FPCCR: MMRDY bit Mask */
+
+#define FPU_FPCCR_HFRDY_Pos 4U /*!< FPCCR: HFRDY Position */
+#define FPU_FPCCR_HFRDY_Msk (1UL << FPU_FPCCR_HFRDY_Pos) /*!< FPCCR: HFRDY bit Mask */
+
+#define FPU_FPCCR_THREAD_Pos 3U /*!< FPCCR: processor mode bit Position */
+#define FPU_FPCCR_THREAD_Msk (1UL << FPU_FPCCR_THREAD_Pos) /*!< FPCCR: processor mode active bit Mask */
+
+#define FPU_FPCCR_USER_Pos 1U /*!< FPCCR: privilege level bit Position */
+#define FPU_FPCCR_USER_Msk (1UL << FPU_FPCCR_USER_Pos) /*!< FPCCR: privilege level bit Mask */
+
+#define FPU_FPCCR_LSPACT_Pos 0U /*!< FPCCR: Lazy state preservation active bit Position */
+#define FPU_FPCCR_LSPACT_Msk (1UL /*<< FPU_FPCCR_LSPACT_Pos*/) /*!< FPCCR: Lazy state preservation active bit Mask */
+
+/* Floating-Point Context Address Register Definitions */
+#define FPU_FPCAR_ADDRESS_Pos 3U /*!< FPCAR: ADDRESS bit Position */
+#define FPU_FPCAR_ADDRESS_Msk (0x1FFFFFFFUL << FPU_FPCAR_ADDRESS_Pos) /*!< FPCAR: ADDRESS bit Mask */
+
+/* Floating-Point Default Status Control Register Definitions */
+#define FPU_FPDSCR_AHP_Pos 26U /*!< FPDSCR: AHP bit Position */
+#define FPU_FPDSCR_AHP_Msk (1UL << FPU_FPDSCR_AHP_Pos) /*!< FPDSCR: AHP bit Mask */
+
+#define FPU_FPDSCR_DN_Pos 25U /*!< FPDSCR: DN bit Position */
+#define FPU_FPDSCR_DN_Msk (1UL << FPU_FPDSCR_DN_Pos) /*!< FPDSCR: DN bit Mask */
+
+#define FPU_FPDSCR_FZ_Pos 24U /*!< FPDSCR: FZ bit Position */
+#define FPU_FPDSCR_FZ_Msk (1UL << FPU_FPDSCR_FZ_Pos) /*!< FPDSCR: FZ bit Mask */
+
+#define FPU_FPDSCR_RMode_Pos 22U /*!< FPDSCR: RMode bit Position */
+#define FPU_FPDSCR_RMode_Msk (3UL << FPU_FPDSCR_RMode_Pos) /*!< FPDSCR: RMode bit Mask */
+
+/* Media and FP Feature Register 0 Definitions */
+#define FPU_MVFR0_FP_rounding_modes_Pos 28U /*!< MVFR0: FP rounding modes bits Position */
+#define FPU_MVFR0_FP_rounding_modes_Msk (0xFUL << FPU_MVFR0_FP_rounding_modes_Pos) /*!< MVFR0: FP rounding modes bits Mask */
+
+#define FPU_MVFR0_Short_vectors_Pos 24U /*!< MVFR0: Short vectors bits Position */
+#define FPU_MVFR0_Short_vectors_Msk (0xFUL << FPU_MVFR0_Short_vectors_Pos) /*!< MVFR0: Short vectors bits Mask */
+
+#define FPU_MVFR0_Square_root_Pos 20U /*!< MVFR0: Square root bits Position */
+#define FPU_MVFR0_Square_root_Msk (0xFUL << FPU_MVFR0_Square_root_Pos) /*!< MVFR0: Square root bits Mask */
+
+#define FPU_MVFR0_Divide_Pos 16U /*!< MVFR0: Divide bits Position */
+#define FPU_MVFR0_Divide_Msk (0xFUL << FPU_MVFR0_Divide_Pos) /*!< MVFR0: Divide bits Mask */
+
+#define FPU_MVFR0_FP_excep_trapping_Pos 12U /*!< MVFR0: FP exception trapping bits Position */
+#define FPU_MVFR0_FP_excep_trapping_Msk (0xFUL << FPU_MVFR0_FP_excep_trapping_Pos) /*!< MVFR0: FP exception trapping bits Mask */
+
+#define FPU_MVFR0_Double_precision_Pos 8U /*!< MVFR0: Double-precision bits Position */
+#define FPU_MVFR0_Double_precision_Msk (0xFUL << FPU_MVFR0_Double_precision_Pos) /*!< MVFR0: Double-precision bits Mask */
+
+#define FPU_MVFR0_Single_precision_Pos 4U /*!< MVFR0: Single-precision bits Position */
+#define FPU_MVFR0_Single_precision_Msk (0xFUL << FPU_MVFR0_Single_precision_Pos) /*!< MVFR0: Single-precision bits Mask */
+
+#define FPU_MVFR0_A_SIMD_registers_Pos 0U /*!< MVFR0: A_SIMD registers bits Position */
+#define FPU_MVFR0_A_SIMD_registers_Msk (0xFUL /*<< FPU_MVFR0_A_SIMD_registers_Pos*/) /*!< MVFR0: A_SIMD registers bits Mask */
+
+/* Media and FP Feature Register 1 Definitions */
+#define FPU_MVFR1_FP_fused_MAC_Pos 28U /*!< MVFR1: FP fused MAC bits Position */
+#define FPU_MVFR1_FP_fused_MAC_Msk (0xFUL << FPU_MVFR1_FP_fused_MAC_Pos) /*!< MVFR1: FP fused MAC bits Mask */
+
+#define FPU_MVFR1_FP_HPFP_Pos 24U /*!< MVFR1: FP HPFP bits Position */
+#define FPU_MVFR1_FP_HPFP_Msk (0xFUL << FPU_MVFR1_FP_HPFP_Pos) /*!< MVFR1: FP HPFP bits Mask */
+
+#define FPU_MVFR1_D_NaN_mode_Pos 4U /*!< MVFR1: D_NaN mode bits Position */
+#define FPU_MVFR1_D_NaN_mode_Msk (0xFUL << FPU_MVFR1_D_NaN_mode_Pos) /*!< MVFR1: D_NaN mode bits Mask */
+
+#define FPU_MVFR1_FtZ_mode_Pos 0U /*!< MVFR1: FtZ mode bits Position */
+#define FPU_MVFR1_FtZ_mode_Msk (0xFUL /*<< FPU_MVFR1_FtZ_mode_Pos*/) /*!< MVFR1: FtZ mode bits Mask */
+
+/*@} end of group CMSIS_FPU */
+#endif
+
+
+/**
+ \ingroup CMSIS_core_register
+ \defgroup CMSIS_CoreDebug Core Debug Registers (CoreDebug)
+ \brief Type definitions for the Core Debug Registers
+ @{
+ */
+
+/**
+ \brief Structure type to access the Core Debug Register (CoreDebug).
+ */
+typedef struct
+{
+ __IOM uint32_t DHCSR; /*!< Offset: 0x000 (R/W) Debug Halting Control and Status Register */
+ __OM uint32_t DCRSR; /*!< Offset: 0x004 ( /W) Debug Core Register Selector Register */
+ __IOM uint32_t DCRDR; /*!< Offset: 0x008 (R/W) Debug Core Register Data Register */
+ __IOM uint32_t DEMCR; /*!< Offset: 0x00C (R/W) Debug Exception and Monitor Control Register */
+} CoreDebug_Type;
+
+/* Debug Halting Control and Status Register Definitions */
+#define CoreDebug_DHCSR_DBGKEY_Pos 16U /*!< CoreDebug DHCSR: DBGKEY Position */
+#define CoreDebug_DHCSR_DBGKEY_Msk (0xFFFFUL << CoreDebug_DHCSR_DBGKEY_Pos) /*!< CoreDebug DHCSR: DBGKEY Mask */
+
+#define CoreDebug_DHCSR_S_RESET_ST_Pos 25U /*!< CoreDebug DHCSR: S_RESET_ST Position */
+#define CoreDebug_DHCSR_S_RESET_ST_Msk (1UL << CoreDebug_DHCSR_S_RESET_ST_Pos) /*!< CoreDebug DHCSR: S_RESET_ST Mask */
+
+#define CoreDebug_DHCSR_S_RETIRE_ST_Pos 24U /*!< CoreDebug DHCSR: S_RETIRE_ST Position */
+#define CoreDebug_DHCSR_S_RETIRE_ST_Msk (1UL << CoreDebug_DHCSR_S_RETIRE_ST_Pos) /*!< CoreDebug DHCSR: S_RETIRE_ST Mask */
+
+#define CoreDebug_DHCSR_S_LOCKUP_Pos 19U /*!< CoreDebug DHCSR: S_LOCKUP Position */
+#define CoreDebug_DHCSR_S_LOCKUP_Msk (1UL << CoreDebug_DHCSR_S_LOCKUP_Pos) /*!< CoreDebug DHCSR: S_LOCKUP Mask */
+
+#define CoreDebug_DHCSR_S_SLEEP_Pos 18U /*!< CoreDebug DHCSR: S_SLEEP Position */
+#define CoreDebug_DHCSR_S_SLEEP_Msk (1UL << CoreDebug_DHCSR_S_SLEEP_Pos) /*!< CoreDebug DHCSR: S_SLEEP Mask */
+
+#define CoreDebug_DHCSR_S_HALT_Pos 17U /*!< CoreDebug DHCSR: S_HALT Position */
+#define CoreDebug_DHCSR_S_HALT_Msk (1UL << CoreDebug_DHCSR_S_HALT_Pos) /*!< CoreDebug DHCSR: S_HALT Mask */
+
+#define CoreDebug_DHCSR_S_REGRDY_Pos 16U /*!< CoreDebug DHCSR: S_REGRDY Position */
+#define CoreDebug_DHCSR_S_REGRDY_Msk (1UL << CoreDebug_DHCSR_S_REGRDY_Pos) /*!< CoreDebug DHCSR: S_REGRDY Mask */
+
+#define CoreDebug_DHCSR_C_SNAPSTALL_Pos 5U /*!< CoreDebug DHCSR: C_SNAPSTALL Position */
+#define CoreDebug_DHCSR_C_SNAPSTALL_Msk (1UL << CoreDebug_DHCSR_C_SNAPSTALL_Pos) /*!< CoreDebug DHCSR: C_SNAPSTALL Mask */
+
+#define CoreDebug_DHCSR_C_MASKINTS_Pos 3U /*!< CoreDebug DHCSR: C_MASKINTS Position */
+#define CoreDebug_DHCSR_C_MASKINTS_Msk (1UL << CoreDebug_DHCSR_C_MASKINTS_Pos) /*!< CoreDebug DHCSR: C_MASKINTS Mask */
+
+#define CoreDebug_DHCSR_C_STEP_Pos 2U /*!< CoreDebug DHCSR: C_STEP Position */
+#define CoreDebug_DHCSR_C_STEP_Msk (1UL << CoreDebug_DHCSR_C_STEP_Pos) /*!< CoreDebug DHCSR: C_STEP Mask */
+
+#define CoreDebug_DHCSR_C_HALT_Pos 1U /*!< CoreDebug DHCSR: C_HALT Position */
+#define CoreDebug_DHCSR_C_HALT_Msk (1UL << CoreDebug_DHCSR_C_HALT_Pos) /*!< CoreDebug DHCSR: C_HALT Mask */
+
+#define CoreDebug_DHCSR_C_DEBUGEN_Pos 0U /*!< CoreDebug DHCSR: C_DEBUGEN Position */
+#define CoreDebug_DHCSR_C_DEBUGEN_Msk (1UL /*<< CoreDebug_DHCSR_C_DEBUGEN_Pos*/) /*!< CoreDebug DHCSR: C_DEBUGEN Mask */
+
+/* Debug Core Register Selector Register Definitions */
+#define CoreDebug_DCRSR_REGWnR_Pos 16U /*!< CoreDebug DCRSR: REGWnR Position */
+#define CoreDebug_DCRSR_REGWnR_Msk (1UL << CoreDebug_DCRSR_REGWnR_Pos) /*!< CoreDebug DCRSR: REGWnR Mask */
+
+#define CoreDebug_DCRSR_REGSEL_Pos 0U /*!< CoreDebug DCRSR: REGSEL Position */
+#define CoreDebug_DCRSR_REGSEL_Msk (0x1FUL /*<< CoreDebug_DCRSR_REGSEL_Pos*/) /*!< CoreDebug DCRSR: REGSEL Mask */
+
+/* Debug Exception and Monitor Control Register Definitions */
+#define CoreDebug_DEMCR_TRCENA_Pos 24U /*!< CoreDebug DEMCR: TRCENA Position */
+#define CoreDebug_DEMCR_TRCENA_Msk (1UL << CoreDebug_DEMCR_TRCENA_Pos) /*!< CoreDebug DEMCR: TRCENA Mask */
+
+#define CoreDebug_DEMCR_MON_REQ_Pos 19U /*!< CoreDebug DEMCR: MON_REQ Position */
+#define CoreDebug_DEMCR_MON_REQ_Msk (1UL << CoreDebug_DEMCR_MON_REQ_Pos) /*!< CoreDebug DEMCR: MON_REQ Mask */
+
+#define CoreDebug_DEMCR_MON_STEP_Pos 18U /*!< CoreDebug DEMCR: MON_STEP Position */
+#define CoreDebug_DEMCR_MON_STEP_Msk (1UL << CoreDebug_DEMCR_MON_STEP_Pos) /*!< CoreDebug DEMCR: MON_STEP Mask */
+
+#define CoreDebug_DEMCR_MON_PEND_Pos 17U /*!< CoreDebug DEMCR: MON_PEND Position */
+#define CoreDebug_DEMCR_MON_PEND_Msk (1UL << CoreDebug_DEMCR_MON_PEND_Pos) /*!< CoreDebug DEMCR: MON_PEND Mask */
+
+#define CoreDebug_DEMCR_MON_EN_Pos 16U /*!< CoreDebug DEMCR: MON_EN Position */
+#define CoreDebug_DEMCR_MON_EN_Msk (1UL << CoreDebug_DEMCR_MON_EN_Pos) /*!< CoreDebug DEMCR: MON_EN Mask */
+
+#define CoreDebug_DEMCR_VC_HARDERR_Pos 10U /*!< CoreDebug DEMCR: VC_HARDERR Position */
+#define CoreDebug_DEMCR_VC_HARDERR_Msk (1UL << CoreDebug_DEMCR_VC_HARDERR_Pos) /*!< CoreDebug DEMCR: VC_HARDERR Mask */
+
+#define CoreDebug_DEMCR_VC_INTERR_Pos 9U /*!< CoreDebug DEMCR: VC_INTERR Position */
+#define CoreDebug_DEMCR_VC_INTERR_Msk (1UL << CoreDebug_DEMCR_VC_INTERR_Pos) /*!< CoreDebug DEMCR: VC_INTERR Mask */
+
+#define CoreDebug_DEMCR_VC_BUSERR_Pos 8U /*!< CoreDebug DEMCR: VC_BUSERR Position */
+#define CoreDebug_DEMCR_VC_BUSERR_Msk (1UL << CoreDebug_DEMCR_VC_BUSERR_Pos) /*!< CoreDebug DEMCR: VC_BUSERR Mask */
+
+#define CoreDebug_DEMCR_VC_STATERR_Pos 7U /*!< CoreDebug DEMCR: VC_STATERR Position */
+#define CoreDebug_DEMCR_VC_STATERR_Msk (1UL << CoreDebug_DEMCR_VC_STATERR_Pos) /*!< CoreDebug DEMCR: VC_STATERR Mask */
+
+#define CoreDebug_DEMCR_VC_CHKERR_Pos 6U /*!< CoreDebug DEMCR: VC_CHKERR Position */
+#define CoreDebug_DEMCR_VC_CHKERR_Msk (1UL << CoreDebug_DEMCR_VC_CHKERR_Pos) /*!< CoreDebug DEMCR: VC_CHKERR Mask */
+
+#define CoreDebug_DEMCR_VC_NOCPERR_Pos 5U /*!< CoreDebug DEMCR: VC_NOCPERR Position */
+#define CoreDebug_DEMCR_VC_NOCPERR_Msk (1UL << CoreDebug_DEMCR_VC_NOCPERR_Pos) /*!< CoreDebug DEMCR: VC_NOCPERR Mask */
+
+#define CoreDebug_DEMCR_VC_MMERR_Pos 4U /*!< CoreDebug DEMCR: VC_MMERR Position */
+#define CoreDebug_DEMCR_VC_MMERR_Msk (1UL << CoreDebug_DEMCR_VC_MMERR_Pos) /*!< CoreDebug DEMCR: VC_MMERR Mask */
+
+#define CoreDebug_DEMCR_VC_CORERESET_Pos 0U /*!< CoreDebug DEMCR: VC_CORERESET Position */
+#define CoreDebug_DEMCR_VC_CORERESET_Msk (1UL /*<< CoreDebug_DEMCR_VC_CORERESET_Pos*/) /*!< CoreDebug DEMCR: VC_CORERESET Mask */
+
+/*@} end of group CMSIS_CoreDebug */
+
+
+/**
+ \ingroup CMSIS_core_register
+ \defgroup CMSIS_core_bitfield Core register bit field macros
+ \brief Macros for use with bit field definitions (xxx_Pos, xxx_Msk).
+ @{
+ */
+
+/**
+ \brief Mask and shift a bit field value for use in a register bit range.
+ \param[in] field Name of the register bit field.
+ \param[in] value Value of the bit field.
+ \return Masked and shifted value.
+*/
+#define _VAL2FLD(field, value) ((value << field ## _Pos) & field ## _Msk)
+
+/**
+ \brief Mask and shift a register value to extract a bit filed value.
+ \param[in] field Name of the register bit field.
+ \param[in] value Value of register.
+ \return Masked and shifted bit field value.
+*/
+#define _FLD2VAL(field, value) ((value & field ## _Msk) >> field ## _Pos)
+
+/*@} end of group CMSIS_core_bitfield */
+
+
+/**
+ \ingroup CMSIS_core_register
+ \defgroup CMSIS_core_base Core Definitions
+ \brief Definitions for base addresses, unions, and structures.
+ @{
+ */
+
+/* Memory mapping of Cortex-M4 Hardware */
+#define SCS_BASE (0xE000E000UL) /*!< System Control Space Base Address */
+#define ITM_BASE (0xE0000000UL) /*!< ITM Base Address */
+#define DWT_BASE (0xE0001000UL) /*!< DWT Base Address */
+#define TPI_BASE (0xE0040000UL) /*!< TPI Base Address */
+#define CoreDebug_BASE (0xE000EDF0UL) /*!< Core Debug Base Address */
+#define SysTick_BASE (SCS_BASE + 0x0010UL) /*!< SysTick Base Address */
+#define NVIC_BASE (SCS_BASE + 0x0100UL) /*!< NVIC Base Address */
+#define SCB_BASE (SCS_BASE + 0x0D00UL) /*!< System Control Block Base Address */
+
+#define SCnSCB ((SCnSCB_Type *) SCS_BASE ) /*!< System control Register not in SCB */
+#define SCB ((SCB_Type *) SCB_BASE ) /*!< SCB configuration struct */
+#define SysTick ((SysTick_Type *) SysTick_BASE ) /*!< SysTick configuration struct */
+#define NVIC ((NVIC_Type *) NVIC_BASE ) /*!< NVIC configuration struct */
+#define ITM ((ITM_Type *) ITM_BASE ) /*!< ITM configuration struct */
+#define DWT ((DWT_Type *) DWT_BASE ) /*!< DWT configuration struct */
+#define TPI ((TPI_Type *) TPI_BASE ) /*!< TPI configuration struct */
+#define CoreDebug ((CoreDebug_Type *) CoreDebug_BASE) /*!< Core Debug configuration struct */
+
+#if (__MPU_PRESENT == 1U)
+ #define MPU_BASE (SCS_BASE + 0x0D90UL) /*!< Memory Protection Unit */
+ #define MPU ((MPU_Type *) MPU_BASE ) /*!< Memory Protection Unit */
+#endif
+
+#if (__FPU_PRESENT == 1U)
+ #define FPU_BASE (SCS_BASE + 0x0F30UL) /*!< Floating Point Unit */
+ #define FPU ((FPU_Type *) FPU_BASE ) /*!< Floating Point Unit */
+#endif
+
+/*@} */
+
+
+
+/*******************************************************************************
+ * Hardware Abstraction Layer
+ Core Function Interface contains:
+ - Core NVIC Functions
+ - Core SysTick Functions
+ - Core Debug Functions
+ - Core Register Access Functions
+ ******************************************************************************/
+/**
+ \defgroup CMSIS_Core_FunctionInterface Functions and Instructions Reference
+*/
+
+
+
+/* ########################## NVIC functions #################################### */
+/**
+ \ingroup CMSIS_Core_FunctionInterface
+ \defgroup CMSIS_Core_NVICFunctions NVIC Functions
+ \brief Functions that manage interrupts and exceptions via the NVIC.
+ @{
+ */
+
+/**
+ \brief Set Priority Grouping
+ \details Sets the priority grouping field using the required unlock sequence.
+ The parameter PriorityGroup is assigned to the field SCB->AIRCR [10:8] PRIGROUP field.
+ Only values from 0..7 are used.
+ In case of a conflict between priority grouping and available
+ priority bits (__NVIC_PRIO_BITS), the smallest possible priority group is set.
+ \param [in] PriorityGroup Priority grouping field.
+ */
+__STATIC_INLINE void NVIC_SetPriorityGrouping(uint32_t PriorityGroup)
+{
+ uint32_t reg_value;
+ uint32_t PriorityGroupTmp = (PriorityGroup & (uint32_t)0x07UL); /* only values 0..7 are used */
+
+ reg_value = SCB->AIRCR; /* read old register configuration */
+ reg_value &= ~((uint32_t)(SCB_AIRCR_VECTKEY_Msk | SCB_AIRCR_PRIGROUP_Msk)); /* clear bits to change */
+ reg_value = (reg_value |
+ ((uint32_t)0x5FAUL << SCB_AIRCR_VECTKEY_Pos) |
+ (PriorityGroupTmp << 8U) ); /* Insert write key and priorty group */
+ SCB->AIRCR = reg_value;
+}
+
+
+/**
+ \brief Get Priority Grouping
+ \details Reads the priority grouping field from the NVIC Interrupt Controller.
+ \return Priority grouping field (SCB->AIRCR [10:8] PRIGROUP field).
+ */
+__STATIC_INLINE uint32_t NVIC_GetPriorityGrouping(void)
+{
+ return ((uint32_t)((SCB->AIRCR & SCB_AIRCR_PRIGROUP_Msk) >> SCB_AIRCR_PRIGROUP_Pos));
+}
+
+
+/**
+ \brief Enable External Interrupt
+ \details Enables a device-specific interrupt in the NVIC interrupt controller.
+ \param [in] IRQn External interrupt number. Value cannot be negative.
+ */
+__STATIC_INLINE void NVIC_EnableIRQ(IRQn_Type IRQn)
+{
+ NVIC->ISER[(((uint32_t)(int32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL));
+}
+
+
+/**
+ \brief Disable External Interrupt
+ \details Disables a device-specific interrupt in the NVIC interrupt controller.
+ \param [in] IRQn External interrupt number. Value cannot be negative.
+ */
+__STATIC_INLINE void NVIC_DisableIRQ(IRQn_Type IRQn)
+{
+ NVIC->ICER[(((uint32_t)(int32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL));
+}
+
+
+/**
+ \brief Get Pending Interrupt
+ \details Reads the pending register in the NVIC and returns the pending bit for the specified interrupt.
+ \param [in] IRQn Interrupt number.
+ \return 0 Interrupt status is not pending.
+ \return 1 Interrupt status is pending.
+ */
+__STATIC_INLINE uint32_t NVIC_GetPendingIRQ(IRQn_Type IRQn)
+{
+ return((uint32_t)(((NVIC->ISPR[(((uint32_t)(int32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL));
+}
+
+
+/**
+ \brief Set Pending Interrupt
+ \details Sets the pending bit of an external interrupt.
+ \param [in] IRQn Interrupt number. Value cannot be negative.
+ */
+__STATIC_INLINE void NVIC_SetPendingIRQ(IRQn_Type IRQn)
+{
+ NVIC->ISPR[(((uint32_t)(int32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL));
+}
+
+
+/**
+ \brief Clear Pending Interrupt
+ \details Clears the pending bit of an external interrupt.
+ \param [in] IRQn External interrupt number. Value cannot be negative.
+ */
+__STATIC_INLINE void NVIC_ClearPendingIRQ(IRQn_Type IRQn)
+{
+ NVIC->ICPR[(((uint32_t)(int32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL));
+}
+
+
+/**
+ \brief Get Active Interrupt
+ \details Reads the active register in NVIC and returns the active bit.
+ \param [in] IRQn Interrupt number.
+ \return 0 Interrupt status is not active.
+ \return 1 Interrupt status is active.
+ */
+__STATIC_INLINE uint32_t NVIC_GetActive(IRQn_Type IRQn)
+{
+ return((uint32_t)(((NVIC->IABR[(((uint32_t)(int32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL));
+}
+
+
+/**
+ \brief Set Interrupt Priority
+ \details Sets the priority of an interrupt.
+ \note The priority cannot be set for every core interrupt.
+ \param [in] IRQn Interrupt number.
+ \param [in] priority Priority to set.
+ */
+__STATIC_INLINE void NVIC_SetPriority(IRQn_Type IRQn, uint32_t priority)
+{
+ if ((int32_t)(IRQn) < 0)
+ {
+ SCB->SHP[(((uint32_t)(int32_t)IRQn) & 0xFUL)-4UL] = (uint8_t)((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL);
+ }
+ else
+ {
+ NVIC->IP[((uint32_t)(int32_t)IRQn)] = (uint8_t)((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL);
+ }
+}
+
+
+/**
+ \brief Get Interrupt Priority
+ \details Reads the priority of an interrupt.
+ The interrupt number can be positive to specify an external (device specific) interrupt,
+ or negative to specify an internal (core) interrupt.
+ \param [in] IRQn Interrupt number.
+ \return Interrupt Priority.
+ Value is aligned automatically to the implemented priority bits of the microcontroller.
+ */
+__STATIC_INLINE uint32_t NVIC_GetPriority(IRQn_Type IRQn)
+{
+
+ if ((int32_t)(IRQn) < 0)
+ {
+ return(((uint32_t)SCB->SHP[(((uint32_t)(int32_t)IRQn) & 0xFUL)-4UL] >> (8U - __NVIC_PRIO_BITS)));
+ }
+ else
+ {
+ return(((uint32_t)NVIC->IP[((uint32_t)(int32_t)IRQn)] >> (8U - __NVIC_PRIO_BITS)));
+ }
+}
+
+
+/**
+ \brief Encode Priority
+ \details Encodes the priority for an interrupt with the given priority group,
+ preemptive priority value, and subpriority value.
+ In case of a conflict between priority grouping and available
+ priority bits (__NVIC_PRIO_BITS), the smallest possible priority group is set.
+ \param [in] PriorityGroup Used priority group.
+ \param [in] PreemptPriority Preemptive priority value (starting from 0).
+ \param [in] SubPriority Subpriority value (starting from 0).
+ \return Encoded priority. Value can be used in the function \ref NVIC_SetPriority().
+ */
+__STATIC_INLINE uint32_t NVIC_EncodePriority (uint32_t PriorityGroup, uint32_t PreemptPriority, uint32_t SubPriority)
+{
+ uint32_t PriorityGroupTmp = (PriorityGroup & (uint32_t)0x07UL); /* only values 0..7 are used */
+ uint32_t PreemptPriorityBits;
+ uint32_t SubPriorityBits;
+
+ PreemptPriorityBits = ((7UL - PriorityGroupTmp) > (uint32_t)(__NVIC_PRIO_BITS)) ? (uint32_t)(__NVIC_PRIO_BITS) : (uint32_t)(7UL - PriorityGroupTmp);
+ SubPriorityBits = ((PriorityGroupTmp + (uint32_t)(__NVIC_PRIO_BITS)) < (uint32_t)7UL) ? (uint32_t)0UL : (uint32_t)((PriorityGroupTmp - 7UL) + (uint32_t)(__NVIC_PRIO_BITS));
+
+ return (
+ ((PreemptPriority & (uint32_t)((1UL << (PreemptPriorityBits)) - 1UL)) << SubPriorityBits) |
+ ((SubPriority & (uint32_t)((1UL << (SubPriorityBits )) - 1UL)))
+ );
+}
+
+
+/**
+ \brief Decode Priority
+ \details Decodes an interrupt priority value with a given priority group to
+ preemptive priority value and subpriority value.
+ In case of a conflict between priority grouping and available
+ priority bits (__NVIC_PRIO_BITS) the smallest possible priority group is set.
+ \param [in] Priority Priority value, which can be retrieved with the function \ref NVIC_GetPriority().
+ \param [in] PriorityGroup Used priority group.
+ \param [out] pPreemptPriority Preemptive priority value (starting from 0).
+ \param [out] pSubPriority Subpriority value (starting from 0).
+ */
+__STATIC_INLINE void NVIC_DecodePriority (uint32_t Priority, uint32_t PriorityGroup, uint32_t* const pPreemptPriority, uint32_t* const pSubPriority)
+{
+ uint32_t PriorityGroupTmp = (PriorityGroup & (uint32_t)0x07UL); /* only values 0..7 are used */
+ uint32_t PreemptPriorityBits;
+ uint32_t SubPriorityBits;
+
+ PreemptPriorityBits = ((7UL - PriorityGroupTmp) > (uint32_t)(__NVIC_PRIO_BITS)) ? (uint32_t)(__NVIC_PRIO_BITS) : (uint32_t)(7UL - PriorityGroupTmp);
+ SubPriorityBits = ((PriorityGroupTmp + (uint32_t)(__NVIC_PRIO_BITS)) < (uint32_t)7UL) ? (uint32_t)0UL : (uint32_t)((PriorityGroupTmp - 7UL) + (uint32_t)(__NVIC_PRIO_BITS));
+
+ *pPreemptPriority = (Priority >> SubPriorityBits) & (uint32_t)((1UL << (PreemptPriorityBits)) - 1UL);
+ *pSubPriority = (Priority ) & (uint32_t)((1UL << (SubPriorityBits )) - 1UL);
+}
+
+
+/**
+ \brief System Reset
+ \details Initiates a system reset request to reset the MCU.
+ */
+__STATIC_INLINE void NVIC_SystemReset(void)
+{
+ __DSB(); /* Ensure all outstanding memory accesses included
+ buffered write are completed before reset */
+ SCB->AIRCR = (uint32_t)((0x5FAUL << SCB_AIRCR_VECTKEY_Pos) |
+ (SCB->AIRCR & SCB_AIRCR_PRIGROUP_Msk) |
+ SCB_AIRCR_SYSRESETREQ_Msk ); /* Keep priority group unchanged */
+ __DSB(); /* Ensure completion of memory access */
+
+ for (;;) /* wait until reset */
+ {
+ __NOP();
+ }
+}
+
+/*@} end of CMSIS_Core_NVICFunctions */
+
+
+
+/* ################################## SysTick function ############################################ */
+/**
+ \ingroup CMSIS_Core_FunctionInterface
+ \defgroup CMSIS_Core_SysTickFunctions SysTick Functions
+ \brief Functions that configure the System.
+ @{
+ */
+
+#if (__Vendor_SysTickConfig == 0U)
+
+/**
+ \brief System Tick Configuration
+ \details Initializes the System Timer and its interrupt, and starts the System Tick Timer.
+ Counter is in free running mode to generate periodic interrupts.
+ \param [in] ticks Number of ticks between two interrupts.
+ \return 0 Function succeeded.
+ \return 1 Function failed.
+ \note When the variable <b>__Vendor_SysTickConfig</b> is set to 1, then the
+ function <b>SysTick_Config</b> is not included. In this case, the file <b><i>device</i>.h</b>
+ must contain a vendor-specific implementation of this function.
+ */
+__STATIC_INLINE uint32_t SysTick_Config(uint32_t ticks)
+{
+ if ((ticks - 1UL) > SysTick_LOAD_RELOAD_Msk)
+ {
+ return (1UL); /* Reload value impossible */
+ }
+
+ SysTick->LOAD = (uint32_t)(ticks - 1UL); /* set reload register */
+ NVIC_SetPriority (SysTick_IRQn, (1UL << __NVIC_PRIO_BITS) - 1UL); /* set Priority for Systick Interrupt */
+ SysTick->VAL = 0UL; /* Load the SysTick Counter Value */
+ SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk |
+ SysTick_CTRL_TICKINT_Msk |
+ SysTick_CTRL_ENABLE_Msk; /* Enable SysTick IRQ and SysTick Timer */
+ return (0UL); /* Function successful */
+}
+
+#endif
+
+/*@} end of CMSIS_Core_SysTickFunctions */
+
+
+
+/* ##################################### Debug In/Output function ########################################### */
+/**
+ \ingroup CMSIS_Core_FunctionInterface
+ \defgroup CMSIS_core_DebugFunctions ITM Functions
+ \brief Functions that access the ITM debug interface.
+ @{
+ */
+
+extern volatile int32_t ITM_RxBuffer; /*!< External variable to receive characters. */
+#define ITM_RXBUFFER_EMPTY 0x5AA55AA5U /*!< Value identifying \ref ITM_RxBuffer is ready for next character. */
+
+
+/**
+ \brief ITM Send Character
+ \details Transmits a character via the ITM channel 0, and
+ \li Just returns when no debugger is connected that has booked the output.
+ \li Is blocking when a debugger is connected, but the previous character sent has not been transmitted.
+ \param [in] ch Character to transmit.
+ \returns Character to transmit.
+ */
+__STATIC_INLINE uint32_t ITM_SendChar (uint32_t ch)
+{
+ if (((ITM->TCR & ITM_TCR_ITMENA_Msk) != 0UL) && /* ITM enabled */
+ ((ITM->TER & 1UL ) != 0UL) ) /* ITM Port #0 enabled */
+ {
+ while (ITM->PORT[0U].u32 == 0UL)
+ {
+ __NOP();
+ }
+ ITM->PORT[0U].u8 = (uint8_t)ch;
+ }
+ return (ch);
+}
+
+
+/**
+ \brief ITM Receive Character
+ \details Inputs a character via the external variable \ref ITM_RxBuffer.
+ \return Received character.
+ \return -1 No character pending.
+ */
+__STATIC_INLINE int32_t ITM_ReceiveChar (void)
+{
+ int32_t ch = -1; /* no character available */
+
+ if (ITM_RxBuffer != ITM_RXBUFFER_EMPTY)
+ {
+ ch = ITM_RxBuffer;
+ ITM_RxBuffer = ITM_RXBUFFER_EMPTY; /* ready for next character */
+ }
+
+ return (ch);
+}
+
+
+/**
+ \brief ITM Check Character
+ \details Checks whether a character is pending for reading in the variable \ref ITM_RxBuffer.
+ \return 0 No character available.
+ \return 1 Character available.
+ */
+__STATIC_INLINE int32_t ITM_CheckChar (void)
+{
+
+ if (ITM_RxBuffer == ITM_RXBUFFER_EMPTY)
+ {
+ return (0); /* no character available */
+ }
+ else
+ {
+ return (1); /* character available */
+ }
+}
+
+/*@} end of CMSIS_core_DebugFunctions */
+
+
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __CORE_CM4_H_DEPENDANT */
+
+#endif /* __CMSIS_GENERIC */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/toolchain/cmsis/include/core_cm7.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/toolchain/cmsis/include/core_cm7.h
new file mode 100644
index 0000000..b1de1be
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/toolchain/cmsis/include/core_cm7.h
@@ -0,0 +1,2512 @@
+/**************************************************************************//**
+ * @file core_cm7.h
+ * @brief CMSIS Cortex-M7 Core Peripheral Access Layer Header File
+ * @version V4.30
+ * @date 20. October 2015
+ ******************************************************************************/
+/* Copyright (c) 2009 - 2015 ARM LIMITED
+
+ All rights reserved.
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are met:
+ - Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ - 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.
+ - Neither the name of ARM 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 COPYRIGHT HOLDERS AND 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.
+ ---------------------------------------------------------------------------*/
+
+
+#if defined ( __ICCARM__ )
+ #pragma system_include /* treat file as system include file for MISRA check */
+#elif defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050)
+ #pragma clang system_header /* treat file as system include file */
+#endif
+
+#ifndef __CORE_CM7_H_GENERIC
+#define __CORE_CM7_H_GENERIC
+
+#include <stdint.h>
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+/**
+ \page CMSIS_MISRA_Exceptions MISRA-C:2004 Compliance Exceptions
+ CMSIS violates the following MISRA-C:2004 rules:
+
+ \li Required Rule 8.5, object/function definition in header file.<br>
+ Function definitions in header files are used to allow 'inlining'.
+
+ \li Required Rule 18.4, declaration of union type or object of union type: '{...}'.<br>
+ Unions are used for effective representation of core registers.
+
+ \li Advisory Rule 19.7, Function-like macro defined.<br>
+ Function-like macros are used to allow more efficient code.
+ */
+
+
+/*******************************************************************************
+ * CMSIS definitions
+ ******************************************************************************/
+/**
+ \ingroup Cortex_M7
+ @{
+ */
+
+/* CMSIS CM7 definitions */
+#define __CM7_CMSIS_VERSION_MAIN (0x04U) /*!< [31:16] CMSIS HAL main version */
+#define __CM7_CMSIS_VERSION_SUB (0x1EU) /*!< [15:0] CMSIS HAL sub version */
+#define __CM7_CMSIS_VERSION ((__CM7_CMSIS_VERSION_MAIN << 16U) | \
+ __CM7_CMSIS_VERSION_SUB ) /*!< CMSIS HAL version number */
+
+#define __CORTEX_M (0x07U) /*!< Cortex-M Core */
+
+
+#if defined ( __CC_ARM )
+ #define __ASM __asm /*!< asm keyword for ARM Compiler */
+ #define __INLINE __inline /*!< inline keyword for ARM Compiler */
+ #define __STATIC_INLINE static __inline
+
+#elif defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050)
+ #define __ASM __asm /*!< asm keyword for ARM Compiler */
+ #define __INLINE __inline /*!< inline keyword for ARM Compiler */
+ #define __STATIC_INLINE static __inline
+
+#elif defined ( __GNUC__ )
+ #define __ASM __asm /*!< asm keyword for GNU Compiler */
+ #define __INLINE inline /*!< inline keyword for GNU Compiler */
+ #define __STATIC_INLINE static inline
+
+#elif defined ( __ICCARM__ )
+ #define __ASM __asm /*!< asm keyword for IAR Compiler */
+ #define __INLINE inline /*!< inline keyword for IAR Compiler. Only available in High optimization mode! */
+ #define __STATIC_INLINE static inline
+
+#elif defined ( __TMS470__ )
+ #define __ASM __asm /*!< asm keyword for TI CCS Compiler */
+ #define __STATIC_INLINE static inline
+
+#elif defined ( __TASKING__ )
+ #define __ASM __asm /*!< asm keyword for TASKING Compiler */
+ #define __INLINE inline /*!< inline keyword for TASKING Compiler */
+ #define __STATIC_INLINE static inline
+
+#elif defined ( __CSMC__ )
+ #define __packed
+ #define __ASM _asm /*!< asm keyword for COSMIC Compiler */
+ #define __INLINE inline /*!< inline keyword for COSMIC Compiler. Use -pc99 on compile line */
+ #define __STATIC_INLINE static inline
+
+#else
+ #error Unknown compiler
+#endif
+
+/** __FPU_USED indicates whether an FPU is used or not.
+ For this, __FPU_PRESENT has to be checked prior to making use of FPU specific registers and functions.
+*/
+#if defined ( __CC_ARM )
+ #if defined __TARGET_FPU_VFP
+ #if (__FPU_PRESENT == 1U)
+ #define __FPU_USED 1U
+ #else
+ #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
+ #define __FPU_USED 0U
+ #endif
+ #else
+ #define __FPU_USED 0U
+ #endif
+
+#elif defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050)
+ #if defined __ARM_PCS_VFP
+ #if (__FPU_PRESENT == 1)
+ #define __FPU_USED 1U
+ #else
+ #warning "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
+ #define __FPU_USED 0U
+ #endif
+ #else
+ #define __FPU_USED 0U
+ #endif
+
+#elif defined ( __GNUC__ )
+ #if defined (__VFP_FP__) && !defined(__SOFTFP__)
+ #if (__FPU_PRESENT == 1U)
+ #define __FPU_USED 1U
+ #else
+ #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
+ #define __FPU_USED 0U
+ #endif
+ #else
+ #define __FPU_USED 0U
+ #endif
+
+#elif defined ( __ICCARM__ )
+ #if defined __ARMVFP__
+ #if (__FPU_PRESENT == 1U)
+ #define __FPU_USED 1U
+ #else
+ #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
+ #define __FPU_USED 0U
+ #endif
+ #else
+ #define __FPU_USED 0U
+ #endif
+
+#elif defined ( __TMS470__ )
+ #if defined __TI_VFP_SUPPORT__
+ #if (__FPU_PRESENT == 1U)
+ #define __FPU_USED 1U
+ #else
+ #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
+ #define __FPU_USED 0U
+ #endif
+ #else
+ #define __FPU_USED 0U
+ #endif
+
+#elif defined ( __TASKING__ )
+ #if defined __FPU_VFP__
+ #if (__FPU_PRESENT == 1U)
+ #define __FPU_USED 1U
+ #else
+ #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
+ #define __FPU_USED 0U
+ #endif
+ #else
+ #define __FPU_USED 0U
+ #endif
+
+#elif defined ( __CSMC__ )
+ #if ( __CSMC__ & 0x400U)
+ #if (__FPU_PRESENT == 1U)
+ #define __FPU_USED 1U
+ #else
+ #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
+ #define __FPU_USED 0U
+ #endif
+ #else
+ #define __FPU_USED 0U
+ #endif
+
+#endif
+
+#include "core_cmInstr.h" /* Core Instruction Access */
+#include "core_cmFunc.h" /* Core Function Access */
+#include "core_cmSimd.h" /* Compiler specific SIMD Intrinsics */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __CORE_CM7_H_GENERIC */
+
+#ifndef __CMSIS_GENERIC
+
+#ifndef __CORE_CM7_H_DEPENDANT
+#define __CORE_CM7_H_DEPENDANT
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+/* check device defines and use defaults */
+#if defined __CHECK_DEVICE_DEFINES
+ #ifndef __CM7_REV
+ #define __CM7_REV 0x0000U
+ #warning "__CM7_REV not defined in device header file; using default!"
+ #endif
+
+ #ifndef __FPU_PRESENT
+ #define __FPU_PRESENT 0U
+ #warning "__FPU_PRESENT not defined in device header file; using default!"
+ #endif
+
+ #ifndef __MPU_PRESENT
+ #define __MPU_PRESENT 0U
+ #warning "__MPU_PRESENT not defined in device header file; using default!"
+ #endif
+
+ #ifndef __ICACHE_PRESENT
+ #define __ICACHE_PRESENT 0U
+ #warning "__ICACHE_PRESENT not defined in device header file; using default!"
+ #endif
+
+ #ifndef __DCACHE_PRESENT
+ #define __DCACHE_PRESENT 0U
+ #warning "__DCACHE_PRESENT not defined in device header file; using default!"
+ #endif
+
+ #ifndef __DTCM_PRESENT
+ #define __DTCM_PRESENT 0U
+ #warning "__DTCM_PRESENT not defined in device header file; using default!"
+ #endif
+
+ #ifndef __NVIC_PRIO_BITS
+ #define __NVIC_PRIO_BITS 3U
+ #warning "__NVIC_PRIO_BITS not defined in device header file; using default!"
+ #endif
+
+ #ifndef __Vendor_SysTickConfig
+ #define __Vendor_SysTickConfig 0U
+ #warning "__Vendor_SysTickConfig not defined in device header file; using default!"
+ #endif
+#endif
+
+/* IO definitions (access restrictions to peripheral registers) */
+/**
+ \defgroup CMSIS_glob_defs CMSIS Global Defines
+
+ <strong>IO Type Qualifiers</strong> are used
+ \li to specify the access to peripheral variables.
+ \li for automatic generation of peripheral register debug information.
+*/
+#ifdef __cplusplus
+ #define __I volatile /*!< Defines 'read only' permissions */
+#else
+ #define __I volatile const /*!< Defines 'read only' permissions */
+#endif
+#define __O volatile /*!< Defines 'write only' permissions */
+#define __IO volatile /*!< Defines 'read / write' permissions */
+
+/* following defines should be used for structure members */
+#define __IM volatile const /*! Defines 'read only' structure member permissions */
+#define __OM volatile /*! Defines 'write only' structure member permissions */
+#define __IOM volatile /*! Defines 'read / write' structure member permissions */
+
+/*@} end of group Cortex_M7 */
+
+
+
+/*******************************************************************************
+ * Register Abstraction
+ Core Register contain:
+ - Core Register
+ - Core NVIC Register
+ - Core SCB Register
+ - Core SysTick Register
+ - Core Debug Register
+ - Core MPU Register
+ - Core FPU Register
+ ******************************************************************************/
+/**
+ \defgroup CMSIS_core_register Defines and Type Definitions
+ \brief Type definitions and defines for Cortex-M processor based devices.
+*/
+
+/**
+ \ingroup CMSIS_core_register
+ \defgroup CMSIS_CORE Status and Control Registers
+ \brief Core Register type definitions.
+ @{
+ */
+
+/**
+ \brief Union type to access the Application Program Status Register (APSR).
+ */
+typedef union
+{
+ struct
+ {
+ uint32_t _reserved0:16; /*!< bit: 0..15 Reserved */
+ uint32_t GE:4; /*!< bit: 16..19 Greater than or Equal flags */
+ uint32_t _reserved1:7; /*!< bit: 20..26 Reserved */
+ uint32_t Q:1; /*!< bit: 27 Saturation condition flag */
+ uint32_t V:1; /*!< bit: 28 Overflow condition code flag */
+ uint32_t C:1; /*!< bit: 29 Carry condition code flag */
+ uint32_t Z:1; /*!< bit: 30 Zero condition code flag */
+ uint32_t N:1; /*!< bit: 31 Negative condition code flag */
+ } b; /*!< Structure used for bit access */
+ uint32_t w; /*!< Type used for word access */
+} APSR_Type;
+
+/* APSR Register Definitions */
+#define APSR_N_Pos 31U /*!< APSR: N Position */
+#define APSR_N_Msk (1UL << APSR_N_Pos) /*!< APSR: N Mask */
+
+#define APSR_Z_Pos 30U /*!< APSR: Z Position */
+#define APSR_Z_Msk (1UL << APSR_Z_Pos) /*!< APSR: Z Mask */
+
+#define APSR_C_Pos 29U /*!< APSR: C Position */
+#define APSR_C_Msk (1UL << APSR_C_Pos) /*!< APSR: C Mask */
+
+#define APSR_V_Pos 28U /*!< APSR: V Position */
+#define APSR_V_Msk (1UL << APSR_V_Pos) /*!< APSR: V Mask */
+
+#define APSR_Q_Pos 27U /*!< APSR: Q Position */
+#define APSR_Q_Msk (1UL << APSR_Q_Pos) /*!< APSR: Q Mask */
+
+#define APSR_GE_Pos 16U /*!< APSR: GE Position */
+#define APSR_GE_Msk (0xFUL << APSR_GE_Pos) /*!< APSR: GE Mask */
+
+
+/**
+ \brief Union type to access the Interrupt Program Status Register (IPSR).
+ */
+typedef union
+{
+ struct
+ {
+ uint32_t ISR:9; /*!< bit: 0.. 8 Exception number */
+ uint32_t _reserved0:23; /*!< bit: 9..31 Reserved */
+ } b; /*!< Structure used for bit access */
+ uint32_t w; /*!< Type used for word access */
+} IPSR_Type;
+
+/* IPSR Register Definitions */
+#define IPSR_ISR_Pos 0U /*!< IPSR: ISR Position */
+#define IPSR_ISR_Msk (0x1FFUL /*<< IPSR_ISR_Pos*/) /*!< IPSR: ISR Mask */
+
+
+/**
+ \brief Union type to access the Special-Purpose Program Status Registers (xPSR).
+ */
+typedef union
+{
+ struct
+ {
+ uint32_t ISR:9; /*!< bit: 0.. 8 Exception number */
+ uint32_t _reserved0:7; /*!< bit: 9..15 Reserved */
+ uint32_t GE:4; /*!< bit: 16..19 Greater than or Equal flags */
+ uint32_t _reserved1:4; /*!< bit: 20..23 Reserved */
+ uint32_t T:1; /*!< bit: 24 Thumb bit (read 0) */
+ uint32_t IT:2; /*!< bit: 25..26 saved IT state (read 0) */
+ uint32_t Q:1; /*!< bit: 27 Saturation condition flag */
+ uint32_t V:1; /*!< bit: 28 Overflow condition code flag */
+ uint32_t C:1; /*!< bit: 29 Carry condition code flag */
+ uint32_t Z:1; /*!< bit: 30 Zero condition code flag */
+ uint32_t N:1; /*!< bit: 31 Negative condition code flag */
+ } b; /*!< Structure used for bit access */
+ uint32_t w; /*!< Type used for word access */
+} xPSR_Type;
+
+/* xPSR Register Definitions */
+#define xPSR_N_Pos 31U /*!< xPSR: N Position */
+#define xPSR_N_Msk (1UL << xPSR_N_Pos) /*!< xPSR: N Mask */
+
+#define xPSR_Z_Pos 30U /*!< xPSR: Z Position */
+#define xPSR_Z_Msk (1UL << xPSR_Z_Pos) /*!< xPSR: Z Mask */
+
+#define xPSR_C_Pos 29U /*!< xPSR: C Position */
+#define xPSR_C_Msk (1UL << xPSR_C_Pos) /*!< xPSR: C Mask */
+
+#define xPSR_V_Pos 28U /*!< xPSR: V Position */
+#define xPSR_V_Msk (1UL << xPSR_V_Pos) /*!< xPSR: V Mask */
+
+#define xPSR_Q_Pos 27U /*!< xPSR: Q Position */
+#define xPSR_Q_Msk (1UL << xPSR_Q_Pos) /*!< xPSR: Q Mask */
+
+#define xPSR_IT_Pos 25U /*!< xPSR: IT Position */
+#define xPSR_IT_Msk (3UL << xPSR_IT_Pos) /*!< xPSR: IT Mask */
+
+#define xPSR_T_Pos 24U /*!< xPSR: T Position */
+#define xPSR_T_Msk (1UL << xPSR_T_Pos) /*!< xPSR: T Mask */
+
+#define xPSR_GE_Pos 16U /*!< xPSR: GE Position */
+#define xPSR_GE_Msk (0xFUL << xPSR_GE_Pos) /*!< xPSR: GE Mask */
+
+#define xPSR_ISR_Pos 0U /*!< xPSR: ISR Position */
+#define xPSR_ISR_Msk (0x1FFUL /*<< xPSR_ISR_Pos*/) /*!< xPSR: ISR Mask */
+
+
+/**
+ \brief Union type to access the Control Registers (CONTROL).
+ */
+typedef union
+{
+ struct
+ {
+ uint32_t nPRIV:1; /*!< bit: 0 Execution privilege in Thread mode */
+ uint32_t SPSEL:1; /*!< bit: 1 Stack to be used */
+ uint32_t FPCA:1; /*!< bit: 2 FP extension active flag */
+ uint32_t _reserved0:29; /*!< bit: 3..31 Reserved */
+ } b; /*!< Structure used for bit access */
+ uint32_t w; /*!< Type used for word access */
+} CONTROL_Type;
+
+/* CONTROL Register Definitions */
+#define CONTROL_FPCA_Pos 2U /*!< CONTROL: FPCA Position */
+#define CONTROL_FPCA_Msk (1UL << CONTROL_FPCA_Pos) /*!< CONTROL: FPCA Mask */
+
+#define CONTROL_SPSEL_Pos 1U /*!< CONTROL: SPSEL Position */
+#define CONTROL_SPSEL_Msk (1UL << CONTROL_SPSEL_Pos) /*!< CONTROL: SPSEL Mask */
+
+#define CONTROL_nPRIV_Pos 0U /*!< CONTROL: nPRIV Position */
+#define CONTROL_nPRIV_Msk (1UL /*<< CONTROL_nPRIV_Pos*/) /*!< CONTROL: nPRIV Mask */
+
+/*@} end of group CMSIS_CORE */
+
+
+/**
+ \ingroup CMSIS_core_register
+ \defgroup CMSIS_NVIC Nested Vectored Interrupt Controller (NVIC)
+ \brief Type definitions for the NVIC Registers
+ @{
+ */
+
+/**
+ \brief Structure type to access the Nested Vectored Interrupt Controller (NVIC).
+ */
+typedef struct
+{
+ __IOM uint32_t ISER[8U]; /*!< Offset: 0x000 (R/W) Interrupt Set Enable Register */
+ uint32_t RESERVED0[24U];
+ __IOM uint32_t ICER[8U]; /*!< Offset: 0x080 (R/W) Interrupt Clear Enable Register */
+ uint32_t RSERVED1[24U];
+ __IOM uint32_t ISPR[8U]; /*!< Offset: 0x100 (R/W) Interrupt Set Pending Register */
+ uint32_t RESERVED2[24U];
+ __IOM uint32_t ICPR[8U]; /*!< Offset: 0x180 (R/W) Interrupt Clear Pending Register */
+ uint32_t RESERVED3[24U];
+ __IOM uint32_t IABR[8U]; /*!< Offset: 0x200 (R/W) Interrupt Active bit Register */
+ uint32_t RESERVED4[56U];
+ __IOM uint8_t IP[240U]; /*!< Offset: 0x300 (R/W) Interrupt Priority Register (8Bit wide) */
+ uint32_t RESERVED5[644U];
+ __OM uint32_t STIR; /*!< Offset: 0xE00 ( /W) Software Trigger Interrupt Register */
+} NVIC_Type;
+
+/* Software Triggered Interrupt Register Definitions */
+#define NVIC_STIR_INTID_Pos 0U /*!< STIR: INTLINESNUM Position */
+#define NVIC_STIR_INTID_Msk (0x1FFUL /*<< NVIC_STIR_INTID_Pos*/) /*!< STIR: INTLINESNUM Mask */
+
+/*@} end of group CMSIS_NVIC */
+
+
+/**
+ \ingroup CMSIS_core_register
+ \defgroup CMSIS_SCB System Control Block (SCB)
+ \brief Type definitions for the System Control Block Registers
+ @{
+ */
+
+/**
+ \brief Structure type to access the System Control Block (SCB).
+ */
+typedef struct
+{
+ __IM uint32_t CPUID; /*!< Offset: 0x000 (R/ ) CPUID Base Register */
+ __IOM uint32_t ICSR; /*!< Offset: 0x004 (R/W) Interrupt Control and State Register */
+ __IOM uint32_t VTOR; /*!< Offset: 0x008 (R/W) Vector Table Offset Register */
+ __IOM uint32_t AIRCR; /*!< Offset: 0x00C (R/W) Application Interrupt and Reset Control Register */
+ __IOM uint32_t SCR; /*!< Offset: 0x010 (R/W) System Control Register */
+ __IOM uint32_t CCR; /*!< Offset: 0x014 (R/W) Configuration Control Register */
+ __IOM uint8_t SHPR[12U]; /*!< Offset: 0x018 (R/W) System Handlers Priority Registers (4-7, 8-11, 12-15) */
+ __IOM uint32_t SHCSR; /*!< Offset: 0x024 (R/W) System Handler Control and State Register */
+ __IOM uint32_t CFSR; /*!< Offset: 0x028 (R/W) Configurable Fault Status Register */
+ __IOM uint32_t HFSR; /*!< Offset: 0x02C (R/W) HardFault Status Register */
+ __IOM uint32_t DFSR; /*!< Offset: 0x030 (R/W) Debug Fault Status Register */
+ __IOM uint32_t MMFAR; /*!< Offset: 0x034 (R/W) MemManage Fault Address Register */
+ __IOM uint32_t BFAR; /*!< Offset: 0x038 (R/W) BusFault Address Register */
+ __IOM uint32_t AFSR; /*!< Offset: 0x03C (R/W) Auxiliary Fault Status Register */
+ __IM uint32_t ID_PFR[2U]; /*!< Offset: 0x040 (R/ ) Processor Feature Register */
+ __IM uint32_t ID_DFR; /*!< Offset: 0x048 (R/ ) Debug Feature Register */
+ __IM uint32_t ID_AFR; /*!< Offset: 0x04C (R/ ) Auxiliary Feature Register */
+ __IM uint32_t ID_MFR[4U]; /*!< Offset: 0x050 (R/ ) Memory Model Feature Register */
+ __IM uint32_t ID_ISAR[5U]; /*!< Offset: 0x060 (R/ ) Instruction Set Attributes Register */
+ uint32_t RESERVED0[1U];
+ __IM uint32_t CLIDR; /*!< Offset: 0x078 (R/ ) Cache Level ID register */
+ __IM uint32_t CTR; /*!< Offset: 0x07C (R/ ) Cache Type register */
+ __IM uint32_t CCSIDR; /*!< Offset: 0x080 (R/ ) Cache Size ID Register */
+ __IOM uint32_t CSSELR; /*!< Offset: 0x084 (R/W) Cache Size Selection Register */
+ __IOM uint32_t CPACR; /*!< Offset: 0x088 (R/W) Coprocessor Access Control Register */
+ uint32_t RESERVED3[93U];
+ __OM uint32_t STIR; /*!< Offset: 0x200 ( /W) Software Triggered Interrupt Register */
+ uint32_t RESERVED4[15U];
+ __IM uint32_t MVFR0; /*!< Offset: 0x240 (R/ ) Media and VFP Feature Register 0 */
+ __IM uint32_t MVFR1; /*!< Offset: 0x244 (R/ ) Media and VFP Feature Register 1 */
+ __IM uint32_t MVFR2; /*!< Offset: 0x248 (R/ ) Media and VFP Feature Register 1 */
+ uint32_t RESERVED5[1U];
+ __OM uint32_t ICIALLU; /*!< Offset: 0x250 ( /W) I-Cache Invalidate All to PoU */
+ uint32_t RESERVED6[1U];
+ __OM uint32_t ICIMVAU; /*!< Offset: 0x258 ( /W) I-Cache Invalidate by MVA to PoU */
+ __OM uint32_t DCIMVAC; /*!< Offset: 0x25C ( /W) D-Cache Invalidate by MVA to PoC */
+ __OM uint32_t DCISW; /*!< Offset: 0x260 ( /W) D-Cache Invalidate by Set-way */
+ __OM uint32_t DCCMVAU; /*!< Offset: 0x264 ( /W) D-Cache Clean by MVA to PoU */
+ __OM uint32_t DCCMVAC; /*!< Offset: 0x268 ( /W) D-Cache Clean by MVA to PoC */
+ __OM uint32_t DCCSW; /*!< Offset: 0x26C ( /W) D-Cache Clean by Set-way */
+ __OM uint32_t DCCIMVAC; /*!< Offset: 0x270 ( /W) D-Cache Clean and Invalidate by MVA to PoC */
+ __OM uint32_t DCCISW; /*!< Offset: 0x274 ( /W) D-Cache Clean and Invalidate by Set-way */
+ uint32_t RESERVED7[6U];
+ __IOM uint32_t ITCMCR; /*!< Offset: 0x290 (R/W) Instruction Tightly-Coupled Memory Control Register */
+ __IOM uint32_t DTCMCR; /*!< Offset: 0x294 (R/W) Data Tightly-Coupled Memory Control Registers */
+ __IOM uint32_t AHBPCR; /*!< Offset: 0x298 (R/W) AHBP Control Register */
+ __IOM uint32_t CACR; /*!< Offset: 0x29C (R/W) L1 Cache Control Register */
+ __IOM uint32_t AHBSCR; /*!< Offset: 0x2A0 (R/W) AHB Slave Control Register */
+ uint32_t RESERVED8[1U];
+ __IOM uint32_t ABFSR; /*!< Offset: 0x2A8 (R/W) Auxiliary Bus Fault Status Register */
+} SCB_Type;
+
+/* SCB CPUID Register Definitions */
+#define SCB_CPUID_IMPLEMENTER_Pos 24U /*!< SCB CPUID: IMPLEMENTER Position */
+#define SCB_CPUID_IMPLEMENTER_Msk (0xFFUL << SCB_CPUID_IMPLEMENTER_Pos) /*!< SCB CPUID: IMPLEMENTER Mask */
+
+#define SCB_CPUID_VARIANT_Pos 20U /*!< SCB CPUID: VARIANT Position */
+#define SCB_CPUID_VARIANT_Msk (0xFUL << SCB_CPUID_VARIANT_Pos) /*!< SCB CPUID: VARIANT Mask */
+
+#define SCB_CPUID_ARCHITECTURE_Pos 16U /*!< SCB CPUID: ARCHITECTURE Position */
+#define SCB_CPUID_ARCHITECTURE_Msk (0xFUL << SCB_CPUID_ARCHITECTURE_Pos) /*!< SCB CPUID: ARCHITECTURE Mask */
+
+#define SCB_CPUID_PARTNO_Pos 4U /*!< SCB CPUID: PARTNO Position */
+#define SCB_CPUID_PARTNO_Msk (0xFFFUL << SCB_CPUID_PARTNO_Pos) /*!< SCB CPUID: PARTNO Mask */
+
+#define SCB_CPUID_REVISION_Pos 0U /*!< SCB CPUID: REVISION Position */
+#define SCB_CPUID_REVISION_Msk (0xFUL /*<< SCB_CPUID_REVISION_Pos*/) /*!< SCB CPUID: REVISION Mask */
+
+/* SCB Interrupt Control State Register Definitions */
+#define SCB_ICSR_NMIPENDSET_Pos 31U /*!< SCB ICSR: NMIPENDSET Position */
+#define SCB_ICSR_NMIPENDSET_Msk (1UL << SCB_ICSR_NMIPENDSET_Pos) /*!< SCB ICSR: NMIPENDSET Mask */
+
+#define SCB_ICSR_PENDSVSET_Pos 28U /*!< SCB ICSR: PENDSVSET Position */
+#define SCB_ICSR_PENDSVSET_Msk (1UL << SCB_ICSR_PENDSVSET_Pos) /*!< SCB ICSR: PENDSVSET Mask */
+
+#define SCB_ICSR_PENDSVCLR_Pos 27U /*!< SCB ICSR: PENDSVCLR Position */
+#define SCB_ICSR_PENDSVCLR_Msk (1UL << SCB_ICSR_PENDSVCLR_Pos) /*!< SCB ICSR: PENDSVCLR Mask */
+
+#define SCB_ICSR_PENDSTSET_Pos 26U /*!< SCB ICSR: PENDSTSET Position */
+#define SCB_ICSR_PENDSTSET_Msk (1UL << SCB_ICSR_PENDSTSET_Pos) /*!< SCB ICSR: PENDSTSET Mask */
+
+#define SCB_ICSR_PENDSTCLR_Pos 25U /*!< SCB ICSR: PENDSTCLR Position */
+#define SCB_ICSR_PENDSTCLR_Msk (1UL << SCB_ICSR_PENDSTCLR_Pos) /*!< SCB ICSR: PENDSTCLR Mask */
+
+#define SCB_ICSR_ISRPREEMPT_Pos 23U /*!< SCB ICSR: ISRPREEMPT Position */
+#define SCB_ICSR_ISRPREEMPT_Msk (1UL << SCB_ICSR_ISRPREEMPT_Pos) /*!< SCB ICSR: ISRPREEMPT Mask */
+
+#define SCB_ICSR_ISRPENDING_Pos 22U /*!< SCB ICSR: ISRPENDING Position */
+#define SCB_ICSR_ISRPENDING_Msk (1UL << SCB_ICSR_ISRPENDING_Pos) /*!< SCB ICSR: ISRPENDING Mask */
+
+#define SCB_ICSR_VECTPENDING_Pos 12U /*!< SCB ICSR: VECTPENDING Position */
+#define SCB_ICSR_VECTPENDING_Msk (0x1FFUL << SCB_ICSR_VECTPENDING_Pos) /*!< SCB ICSR: VECTPENDING Mask */
+
+#define SCB_ICSR_RETTOBASE_Pos 11U /*!< SCB ICSR: RETTOBASE Position */
+#define SCB_ICSR_RETTOBASE_Msk (1UL << SCB_ICSR_RETTOBASE_Pos) /*!< SCB ICSR: RETTOBASE Mask */
+
+#define SCB_ICSR_VECTACTIVE_Pos 0U /*!< SCB ICSR: VECTACTIVE Position */
+#define SCB_ICSR_VECTACTIVE_Msk (0x1FFUL /*<< SCB_ICSR_VECTACTIVE_Pos*/) /*!< SCB ICSR: VECTACTIVE Mask */
+
+/* SCB Vector Table Offset Register Definitions */
+#define SCB_VTOR_TBLOFF_Pos 7U /*!< SCB VTOR: TBLOFF Position */
+#define SCB_VTOR_TBLOFF_Msk (0x1FFFFFFUL << SCB_VTOR_TBLOFF_Pos) /*!< SCB VTOR: TBLOFF Mask */
+
+/* SCB Application Interrupt and Reset Control Register Definitions */
+#define SCB_AIRCR_VECTKEY_Pos 16U /*!< SCB AIRCR: VECTKEY Position */
+#define SCB_AIRCR_VECTKEY_Msk (0xFFFFUL << SCB_AIRCR_VECTKEY_Pos) /*!< SCB AIRCR: VECTKEY Mask */
+
+#define SCB_AIRCR_VECTKEYSTAT_Pos 16U /*!< SCB AIRCR: VECTKEYSTAT Position */
+#define SCB_AIRCR_VECTKEYSTAT_Msk (0xFFFFUL << SCB_AIRCR_VECTKEYSTAT_Pos) /*!< SCB AIRCR: VECTKEYSTAT Mask */
+
+#define SCB_AIRCR_ENDIANESS_Pos 15U /*!< SCB AIRCR: ENDIANESS Position */
+#define SCB_AIRCR_ENDIANESS_Msk (1UL << SCB_AIRCR_ENDIANESS_Pos) /*!< SCB AIRCR: ENDIANESS Mask */
+
+#define SCB_AIRCR_PRIGROUP_Pos 8U /*!< SCB AIRCR: PRIGROUP Position */
+#define SCB_AIRCR_PRIGROUP_Msk (7UL << SCB_AIRCR_PRIGROUP_Pos) /*!< SCB AIRCR: PRIGROUP Mask */
+
+#define SCB_AIRCR_SYSRESETREQ_Pos 2U /*!< SCB AIRCR: SYSRESETREQ Position */
+#define SCB_AIRCR_SYSRESETREQ_Msk (1UL << SCB_AIRCR_SYSRESETREQ_Pos) /*!< SCB AIRCR: SYSRESETREQ Mask */
+
+#define SCB_AIRCR_VECTCLRACTIVE_Pos 1U /*!< SCB AIRCR: VECTCLRACTIVE Position */
+#define SCB_AIRCR_VECTCLRACTIVE_Msk (1UL << SCB_AIRCR_VECTCLRACTIVE_Pos) /*!< SCB AIRCR: VECTCLRACTIVE Mask */
+
+#define SCB_AIRCR_VECTRESET_Pos 0U /*!< SCB AIRCR: VECTRESET Position */
+#define SCB_AIRCR_VECTRESET_Msk (1UL /*<< SCB_AIRCR_VECTRESET_Pos*/) /*!< SCB AIRCR: VECTRESET Mask */
+
+/* SCB System Control Register Definitions */
+#define SCB_SCR_SEVONPEND_Pos 4U /*!< SCB SCR: SEVONPEND Position */
+#define SCB_SCR_SEVONPEND_Msk (1UL << SCB_SCR_SEVONPEND_Pos) /*!< SCB SCR: SEVONPEND Mask */
+
+#define SCB_SCR_SLEEPDEEP_Pos 2U /*!< SCB SCR: SLEEPDEEP Position */
+#define SCB_SCR_SLEEPDEEP_Msk (1UL << SCB_SCR_SLEEPDEEP_Pos) /*!< SCB SCR: SLEEPDEEP Mask */
+
+#define SCB_SCR_SLEEPONEXIT_Pos 1U /*!< SCB SCR: SLEEPONEXIT Position */
+#define SCB_SCR_SLEEPONEXIT_Msk (1UL << SCB_SCR_SLEEPONEXIT_Pos) /*!< SCB SCR: SLEEPONEXIT Mask */
+
+/* SCB Configuration Control Register Definitions */
+#define SCB_CCR_BP_Pos 18U /*!< SCB CCR: Branch prediction enable bit Position */
+#define SCB_CCR_BP_Msk (1UL << SCB_CCR_BP_Pos) /*!< SCB CCR: Branch prediction enable bit Mask */
+
+#define SCB_CCR_IC_Pos 17U /*!< SCB CCR: Instruction cache enable bit Position */
+#define SCB_CCR_IC_Msk (1UL << SCB_CCR_IC_Pos) /*!< SCB CCR: Instruction cache enable bit Mask */
+
+#define SCB_CCR_DC_Pos 16U /*!< SCB CCR: Cache enable bit Position */
+#define SCB_CCR_DC_Msk (1UL << SCB_CCR_DC_Pos) /*!< SCB CCR: Cache enable bit Mask */
+
+#define SCB_CCR_STKALIGN_Pos 9U /*!< SCB CCR: STKALIGN Position */
+#define SCB_CCR_STKALIGN_Msk (1UL << SCB_CCR_STKALIGN_Pos) /*!< SCB CCR: STKALIGN Mask */
+
+#define SCB_CCR_BFHFNMIGN_Pos 8U /*!< SCB CCR: BFHFNMIGN Position */
+#define SCB_CCR_BFHFNMIGN_Msk (1UL << SCB_CCR_BFHFNMIGN_Pos) /*!< SCB CCR: BFHFNMIGN Mask */
+
+#define SCB_CCR_DIV_0_TRP_Pos 4U /*!< SCB CCR: DIV_0_TRP Position */
+#define SCB_CCR_DIV_0_TRP_Msk (1UL << SCB_CCR_DIV_0_TRP_Pos) /*!< SCB CCR: DIV_0_TRP Mask */
+
+#define SCB_CCR_UNALIGN_TRP_Pos 3U /*!< SCB CCR: UNALIGN_TRP Position */
+#define SCB_CCR_UNALIGN_TRP_Msk (1UL << SCB_CCR_UNALIGN_TRP_Pos) /*!< SCB CCR: UNALIGN_TRP Mask */
+
+#define SCB_CCR_USERSETMPEND_Pos 1U /*!< SCB CCR: USERSETMPEND Position */
+#define SCB_CCR_USERSETMPEND_Msk (1UL << SCB_CCR_USERSETMPEND_Pos) /*!< SCB CCR: USERSETMPEND Mask */
+
+#define SCB_CCR_NONBASETHRDENA_Pos 0U /*!< SCB CCR: NONBASETHRDENA Position */
+#define SCB_CCR_NONBASETHRDENA_Msk (1UL /*<< SCB_CCR_NONBASETHRDENA_Pos*/) /*!< SCB CCR: NONBASETHRDENA Mask */
+
+/* SCB System Handler Control and State Register Definitions */
+#define SCB_SHCSR_USGFAULTENA_Pos 18U /*!< SCB SHCSR: USGFAULTENA Position */
+#define SCB_SHCSR_USGFAULTENA_Msk (1UL << SCB_SHCSR_USGFAULTENA_Pos) /*!< SCB SHCSR: USGFAULTENA Mask */
+
+#define SCB_SHCSR_BUSFAULTENA_Pos 17U /*!< SCB SHCSR: BUSFAULTENA Position */
+#define SCB_SHCSR_BUSFAULTENA_Msk (1UL << SCB_SHCSR_BUSFAULTENA_Pos) /*!< SCB SHCSR: BUSFAULTENA Mask */
+
+#define SCB_SHCSR_MEMFAULTENA_Pos 16U /*!< SCB SHCSR: MEMFAULTENA Position */
+#define SCB_SHCSR_MEMFAULTENA_Msk (1UL << SCB_SHCSR_MEMFAULTENA_Pos) /*!< SCB SHCSR: MEMFAULTENA Mask */
+
+#define SCB_SHCSR_SVCALLPENDED_Pos 15U /*!< SCB SHCSR: SVCALLPENDED Position */
+#define SCB_SHCSR_SVCALLPENDED_Msk (1UL << SCB_SHCSR_SVCALLPENDED_Pos) /*!< SCB SHCSR: SVCALLPENDED Mask */
+
+#define SCB_SHCSR_BUSFAULTPENDED_Pos 14U /*!< SCB SHCSR: BUSFAULTPENDED Position */
+#define SCB_SHCSR_BUSFAULTPENDED_Msk (1UL << SCB_SHCSR_BUSFAULTPENDED_Pos) /*!< SCB SHCSR: BUSFAULTPENDED Mask */
+
+#define SCB_SHCSR_MEMFAULTPENDED_Pos 13U /*!< SCB SHCSR: MEMFAULTPENDED Position */
+#define SCB_SHCSR_MEMFAULTPENDED_Msk (1UL << SCB_SHCSR_MEMFAULTPENDED_Pos) /*!< SCB SHCSR: MEMFAULTPENDED Mask */
+
+#define SCB_SHCSR_USGFAULTPENDED_Pos 12U /*!< SCB SHCSR: USGFAULTPENDED Position */
+#define SCB_SHCSR_USGFAULTPENDED_Msk (1UL << SCB_SHCSR_USGFAULTPENDED_Pos) /*!< SCB SHCSR: USGFAULTPENDED Mask */
+
+#define SCB_SHCSR_SYSTICKACT_Pos 11U /*!< SCB SHCSR: SYSTICKACT Position */
+#define SCB_SHCSR_SYSTICKACT_Msk (1UL << SCB_SHCSR_SYSTICKACT_Pos) /*!< SCB SHCSR: SYSTICKACT Mask */
+
+#define SCB_SHCSR_PENDSVACT_Pos 10U /*!< SCB SHCSR: PENDSVACT Position */
+#define SCB_SHCSR_PENDSVACT_Msk (1UL << SCB_SHCSR_PENDSVACT_Pos) /*!< SCB SHCSR: PENDSVACT Mask */
+
+#define SCB_SHCSR_MONITORACT_Pos 8U /*!< SCB SHCSR: MONITORACT Position */
+#define SCB_SHCSR_MONITORACT_Msk (1UL << SCB_SHCSR_MONITORACT_Pos) /*!< SCB SHCSR: MONITORACT Mask */
+
+#define SCB_SHCSR_SVCALLACT_Pos 7U /*!< SCB SHCSR: SVCALLACT Position */
+#define SCB_SHCSR_SVCALLACT_Msk (1UL << SCB_SHCSR_SVCALLACT_Pos) /*!< SCB SHCSR: SVCALLACT Mask */
+
+#define SCB_SHCSR_USGFAULTACT_Pos 3U /*!< SCB SHCSR: USGFAULTACT Position */
+#define SCB_SHCSR_USGFAULTACT_Msk (1UL << SCB_SHCSR_USGFAULTACT_Pos) /*!< SCB SHCSR: USGFAULTACT Mask */
+
+#define SCB_SHCSR_BUSFAULTACT_Pos 1U /*!< SCB SHCSR: BUSFAULTACT Position */
+#define SCB_SHCSR_BUSFAULTACT_Msk (1UL << SCB_SHCSR_BUSFAULTACT_Pos) /*!< SCB SHCSR: BUSFAULTACT Mask */
+
+#define SCB_SHCSR_MEMFAULTACT_Pos 0U /*!< SCB SHCSR: MEMFAULTACT Position */
+#define SCB_SHCSR_MEMFAULTACT_Msk (1UL /*<< SCB_SHCSR_MEMFAULTACT_Pos*/) /*!< SCB SHCSR: MEMFAULTACT Mask */
+
+/* SCB Configurable Fault Status Register Definitions */
+#define SCB_CFSR_USGFAULTSR_Pos 16U /*!< SCB CFSR: Usage Fault Status Register Position */
+#define SCB_CFSR_USGFAULTSR_Msk (0xFFFFUL << SCB_CFSR_USGFAULTSR_Pos) /*!< SCB CFSR: Usage Fault Status Register Mask */
+
+#define SCB_CFSR_BUSFAULTSR_Pos 8U /*!< SCB CFSR: Bus Fault Status Register Position */
+#define SCB_CFSR_BUSFAULTSR_Msk (0xFFUL << SCB_CFSR_BUSFAULTSR_Pos) /*!< SCB CFSR: Bus Fault Status Register Mask */
+
+#define SCB_CFSR_MEMFAULTSR_Pos 0U /*!< SCB CFSR: Memory Manage Fault Status Register Position */
+#define SCB_CFSR_MEMFAULTSR_Msk (0xFFUL /*<< SCB_CFSR_MEMFAULTSR_Pos*/) /*!< SCB CFSR: Memory Manage Fault Status Register Mask */
+
+/* SCB Hard Fault Status Register Definitions */
+#define SCB_HFSR_DEBUGEVT_Pos 31U /*!< SCB HFSR: DEBUGEVT Position */
+#define SCB_HFSR_DEBUGEVT_Msk (1UL << SCB_HFSR_DEBUGEVT_Pos) /*!< SCB HFSR: DEBUGEVT Mask */
+
+#define SCB_HFSR_FORCED_Pos 30U /*!< SCB HFSR: FORCED Position */
+#define SCB_HFSR_FORCED_Msk (1UL << SCB_HFSR_FORCED_Pos) /*!< SCB HFSR: FORCED Mask */
+
+#define SCB_HFSR_VECTTBL_Pos 1U /*!< SCB HFSR: VECTTBL Position */
+#define SCB_HFSR_VECTTBL_Msk (1UL << SCB_HFSR_VECTTBL_Pos) /*!< SCB HFSR: VECTTBL Mask */
+
+/* SCB Debug Fault Status Register Definitions */
+#define SCB_DFSR_EXTERNAL_Pos 4U /*!< SCB DFSR: EXTERNAL Position */
+#define SCB_DFSR_EXTERNAL_Msk (1UL << SCB_DFSR_EXTERNAL_Pos) /*!< SCB DFSR: EXTERNAL Mask */
+
+#define SCB_DFSR_VCATCH_Pos 3U /*!< SCB DFSR: VCATCH Position */
+#define SCB_DFSR_VCATCH_Msk (1UL << SCB_DFSR_VCATCH_Pos) /*!< SCB DFSR: VCATCH Mask */
+
+#define SCB_DFSR_DWTTRAP_Pos 2U /*!< SCB DFSR: DWTTRAP Position */
+#define SCB_DFSR_DWTTRAP_Msk (1UL << SCB_DFSR_DWTTRAP_Pos) /*!< SCB DFSR: DWTTRAP Mask */
+
+#define SCB_DFSR_BKPT_Pos 1U /*!< SCB DFSR: BKPT Position */
+#define SCB_DFSR_BKPT_Msk (1UL << SCB_DFSR_BKPT_Pos) /*!< SCB DFSR: BKPT Mask */
+
+#define SCB_DFSR_HALTED_Pos 0U /*!< SCB DFSR: HALTED Position */
+#define SCB_DFSR_HALTED_Msk (1UL /*<< SCB_DFSR_HALTED_Pos*/) /*!< SCB DFSR: HALTED Mask */
+
+/* SCB Cache Level ID Register Definitions */
+#define SCB_CLIDR_LOUU_Pos 27U /*!< SCB CLIDR: LoUU Position */
+#define SCB_CLIDR_LOUU_Msk (7UL << SCB_CLIDR_LOUU_Pos) /*!< SCB CLIDR: LoUU Mask */
+
+#define SCB_CLIDR_LOC_Pos 24U /*!< SCB CLIDR: LoC Position */
+#define SCB_CLIDR_LOC_Msk (7UL << SCB_CLIDR_LOC_Pos) /*!< SCB CLIDR: LoC Mask */
+
+/* SCB Cache Type Register Definitions */
+#define SCB_CTR_FORMAT_Pos 29U /*!< SCB CTR: Format Position */
+#define SCB_CTR_FORMAT_Msk (7UL << SCB_CTR_FORMAT_Pos) /*!< SCB CTR: Format Mask */
+
+#define SCB_CTR_CWG_Pos 24U /*!< SCB CTR: CWG Position */
+#define SCB_CTR_CWG_Msk (0xFUL << SCB_CTR_CWG_Pos) /*!< SCB CTR: CWG Mask */
+
+#define SCB_CTR_ERG_Pos 20U /*!< SCB CTR: ERG Position */
+#define SCB_CTR_ERG_Msk (0xFUL << SCB_CTR_ERG_Pos) /*!< SCB CTR: ERG Mask */
+
+#define SCB_CTR_DMINLINE_Pos 16U /*!< SCB CTR: DminLine Position */
+#define SCB_CTR_DMINLINE_Msk (0xFUL << SCB_CTR_DMINLINE_Pos) /*!< SCB CTR: DminLine Mask */
+
+#define SCB_CTR_IMINLINE_Pos 0U /*!< SCB CTR: ImInLine Position */
+#define SCB_CTR_IMINLINE_Msk (0xFUL /*<< SCB_CTR_IMINLINE_Pos*/) /*!< SCB CTR: ImInLine Mask */
+
+/* SCB Cache Size ID Register Definitions */
+#define SCB_CCSIDR_WT_Pos 31U /*!< SCB CCSIDR: WT Position */
+#define SCB_CCSIDR_WT_Msk (1UL << SCB_CCSIDR_WT_Pos) /*!< SCB CCSIDR: WT Mask */
+
+#define SCB_CCSIDR_WB_Pos 30U /*!< SCB CCSIDR: WB Position */
+#define SCB_CCSIDR_WB_Msk (1UL << SCB_CCSIDR_WB_Pos) /*!< SCB CCSIDR: WB Mask */
+
+#define SCB_CCSIDR_RA_Pos 29U /*!< SCB CCSIDR: RA Position */
+#define SCB_CCSIDR_RA_Msk (1UL << SCB_CCSIDR_RA_Pos) /*!< SCB CCSIDR: RA Mask */
+
+#define SCB_CCSIDR_WA_Pos 28U /*!< SCB CCSIDR: WA Position */
+#define SCB_CCSIDR_WA_Msk (1UL << SCB_CCSIDR_WA_Pos) /*!< SCB CCSIDR: WA Mask */
+
+#define SCB_CCSIDR_NUMSETS_Pos 13U /*!< SCB CCSIDR: NumSets Position */
+#define SCB_CCSIDR_NUMSETS_Msk (0x7FFFUL << SCB_CCSIDR_NUMSETS_Pos) /*!< SCB CCSIDR: NumSets Mask */
+
+#define SCB_CCSIDR_ASSOCIATIVITY_Pos 3U /*!< SCB CCSIDR: Associativity Position */
+#define SCB_CCSIDR_ASSOCIATIVITY_Msk (0x3FFUL << SCB_CCSIDR_ASSOCIATIVITY_Pos) /*!< SCB CCSIDR: Associativity Mask */
+
+#define SCB_CCSIDR_LINESIZE_Pos 0U /*!< SCB CCSIDR: LineSize Position */
+#define SCB_CCSIDR_LINESIZE_Msk (7UL /*<< SCB_CCSIDR_LINESIZE_Pos*/) /*!< SCB CCSIDR: LineSize Mask */
+
+/* SCB Cache Size Selection Register Definitions */
+#define SCB_CSSELR_LEVEL_Pos 1U /*!< SCB CSSELR: Level Position */
+#define SCB_CSSELR_LEVEL_Msk (7UL << SCB_CSSELR_LEVEL_Pos) /*!< SCB CSSELR: Level Mask */
+
+#define SCB_CSSELR_IND_Pos 0U /*!< SCB CSSELR: InD Position */
+#define SCB_CSSELR_IND_Msk (1UL /*<< SCB_CSSELR_IND_Pos*/) /*!< SCB CSSELR: InD Mask */
+
+/* SCB Software Triggered Interrupt Register Definitions */
+#define SCB_STIR_INTID_Pos 0U /*!< SCB STIR: INTID Position */
+#define SCB_STIR_INTID_Msk (0x1FFUL /*<< SCB_STIR_INTID_Pos*/) /*!< SCB STIR: INTID Mask */
+
+/* SCB D-Cache Invalidate by Set-way Register Definitions */
+#define SCB_DCISW_WAY_Pos 30U /*!< SCB DCISW: Way Position */
+#define SCB_DCISW_WAY_Msk (3UL << SCB_DCISW_WAY_Pos) /*!< SCB DCISW: Way Mask */
+
+#define SCB_DCISW_SET_Pos 5U /*!< SCB DCISW: Set Position */
+#define SCB_DCISW_SET_Msk (0x1FFUL << SCB_DCISW_SET_Pos) /*!< SCB DCISW: Set Mask */
+
+/* SCB D-Cache Clean by Set-way Register Definitions */
+#define SCB_DCCSW_WAY_Pos 30U /*!< SCB DCCSW: Way Position */
+#define SCB_DCCSW_WAY_Msk (3UL << SCB_DCCSW_WAY_Pos) /*!< SCB DCCSW: Way Mask */
+
+#define SCB_DCCSW_SET_Pos 5U /*!< SCB DCCSW: Set Position */
+#define SCB_DCCSW_SET_Msk (0x1FFUL << SCB_DCCSW_SET_Pos) /*!< SCB DCCSW: Set Mask */
+
+/* SCB D-Cache Clean and Invalidate by Set-way Register Definitions */
+#define SCB_DCCISW_WAY_Pos 30U /*!< SCB DCCISW: Way Position */
+#define SCB_DCCISW_WAY_Msk (3UL << SCB_DCCISW_WAY_Pos) /*!< SCB DCCISW: Way Mask */
+
+#define SCB_DCCISW_SET_Pos 5U /*!< SCB DCCISW: Set Position */
+#define SCB_DCCISW_SET_Msk (0x1FFUL << SCB_DCCISW_SET_Pos) /*!< SCB DCCISW: Set Mask */
+
+/* Instruction Tightly-Coupled Memory Control Register Definitions */
+#define SCB_ITCMCR_SZ_Pos 3U /*!< SCB ITCMCR: SZ Position */
+#define SCB_ITCMCR_SZ_Msk (0xFUL << SCB_ITCMCR_SZ_Pos) /*!< SCB ITCMCR: SZ Mask */
+
+#define SCB_ITCMCR_RETEN_Pos 2U /*!< SCB ITCMCR: RETEN Position */
+#define SCB_ITCMCR_RETEN_Msk (1UL << SCB_ITCMCR_RETEN_Pos) /*!< SCB ITCMCR: RETEN Mask */
+
+#define SCB_ITCMCR_RMW_Pos 1U /*!< SCB ITCMCR: RMW Position */
+#define SCB_ITCMCR_RMW_Msk (1UL << SCB_ITCMCR_RMW_Pos) /*!< SCB ITCMCR: RMW Mask */
+
+#define SCB_ITCMCR_EN_Pos 0U /*!< SCB ITCMCR: EN Position */
+#define SCB_ITCMCR_EN_Msk (1UL /*<< SCB_ITCMCR_EN_Pos*/) /*!< SCB ITCMCR: EN Mask */
+
+/* Data Tightly-Coupled Memory Control Register Definitions */
+#define SCB_DTCMCR_SZ_Pos 3U /*!< SCB DTCMCR: SZ Position */
+#define SCB_DTCMCR_SZ_Msk (0xFUL << SCB_DTCMCR_SZ_Pos) /*!< SCB DTCMCR: SZ Mask */
+
+#define SCB_DTCMCR_RETEN_Pos 2U /*!< SCB DTCMCR: RETEN Position */
+#define SCB_DTCMCR_RETEN_Msk (1UL << SCB_DTCMCR_RETEN_Pos) /*!< SCB DTCMCR: RETEN Mask */
+
+#define SCB_DTCMCR_RMW_Pos 1U /*!< SCB DTCMCR: RMW Position */
+#define SCB_DTCMCR_RMW_Msk (1UL << SCB_DTCMCR_RMW_Pos) /*!< SCB DTCMCR: RMW Mask */
+
+#define SCB_DTCMCR_EN_Pos 0U /*!< SCB DTCMCR: EN Position */
+#define SCB_DTCMCR_EN_Msk (1UL /*<< SCB_DTCMCR_EN_Pos*/) /*!< SCB DTCMCR: EN Mask */
+
+/* AHBP Control Register Definitions */
+#define SCB_AHBPCR_SZ_Pos 1U /*!< SCB AHBPCR: SZ Position */
+#define SCB_AHBPCR_SZ_Msk (7UL << SCB_AHBPCR_SZ_Pos) /*!< SCB AHBPCR: SZ Mask */
+
+#define SCB_AHBPCR_EN_Pos 0U /*!< SCB AHBPCR: EN Position */
+#define SCB_AHBPCR_EN_Msk (1UL /*<< SCB_AHBPCR_EN_Pos*/) /*!< SCB AHBPCR: EN Mask */
+
+/* L1 Cache Control Register Definitions */
+#define SCB_CACR_FORCEWT_Pos 2U /*!< SCB CACR: FORCEWT Position */
+#define SCB_CACR_FORCEWT_Msk (1UL << SCB_CACR_FORCEWT_Pos) /*!< SCB CACR: FORCEWT Mask */
+
+#define SCB_CACR_ECCEN_Pos 1U /*!< SCB CACR: ECCEN Position */
+#define SCB_CACR_ECCEN_Msk (1UL << SCB_CACR_ECCEN_Pos) /*!< SCB CACR: ECCEN Mask */
+
+#define SCB_CACR_SIWT_Pos 0U /*!< SCB CACR: SIWT Position */
+#define SCB_CACR_SIWT_Msk (1UL /*<< SCB_CACR_SIWT_Pos*/) /*!< SCB CACR: SIWT Mask */
+
+/* AHBS Control Register Definitions */
+#define SCB_AHBSCR_INITCOUNT_Pos 11U /*!< SCB AHBSCR: INITCOUNT Position */
+#define SCB_AHBSCR_INITCOUNT_Msk (0x1FUL << SCB_AHBPCR_INITCOUNT_Pos) /*!< SCB AHBSCR: INITCOUNT Mask */
+
+#define SCB_AHBSCR_TPRI_Pos 2U /*!< SCB AHBSCR: TPRI Position */
+#define SCB_AHBSCR_TPRI_Msk (0x1FFUL << SCB_AHBPCR_TPRI_Pos) /*!< SCB AHBSCR: TPRI Mask */
+
+#define SCB_AHBSCR_CTL_Pos 0U /*!< SCB AHBSCR: CTL Position*/
+#define SCB_AHBSCR_CTL_Msk (3UL /*<< SCB_AHBPCR_CTL_Pos*/) /*!< SCB AHBSCR: CTL Mask */
+
+/* Auxiliary Bus Fault Status Register Definitions */
+#define SCB_ABFSR_AXIMTYPE_Pos 8U /*!< SCB ABFSR: AXIMTYPE Position*/
+#define SCB_ABFSR_AXIMTYPE_Msk (3UL << SCB_ABFSR_AXIMTYPE_Pos) /*!< SCB ABFSR: AXIMTYPE Mask */
+
+#define SCB_ABFSR_EPPB_Pos 4U /*!< SCB ABFSR: EPPB Position*/
+#define SCB_ABFSR_EPPB_Msk (1UL << SCB_ABFSR_EPPB_Pos) /*!< SCB ABFSR: EPPB Mask */
+
+#define SCB_ABFSR_AXIM_Pos 3U /*!< SCB ABFSR: AXIM Position*/
+#define SCB_ABFSR_AXIM_Msk (1UL << SCB_ABFSR_AXIM_Pos) /*!< SCB ABFSR: AXIM Mask */
+
+#define SCB_ABFSR_AHBP_Pos 2U /*!< SCB ABFSR: AHBP Position*/
+#define SCB_ABFSR_AHBP_Msk (1UL << SCB_ABFSR_AHBP_Pos) /*!< SCB ABFSR: AHBP Mask */
+
+#define SCB_ABFSR_DTCM_Pos 1U /*!< SCB ABFSR: DTCM Position*/
+#define SCB_ABFSR_DTCM_Msk (1UL << SCB_ABFSR_DTCM_Pos) /*!< SCB ABFSR: DTCM Mask */
+
+#define SCB_ABFSR_ITCM_Pos 0U /*!< SCB ABFSR: ITCM Position*/
+#define SCB_ABFSR_ITCM_Msk (1UL /*<< SCB_ABFSR_ITCM_Pos*/) /*!< SCB ABFSR: ITCM Mask */
+
+/*@} end of group CMSIS_SCB */
+
+
+/**
+ \ingroup CMSIS_core_register
+ \defgroup CMSIS_SCnSCB System Controls not in SCB (SCnSCB)
+ \brief Type definitions for the System Control and ID Register not in the SCB
+ @{
+ */
+
+/**
+ \brief Structure type to access the System Control and ID Register not in the SCB.
+ */
+typedef struct
+{
+ uint32_t RESERVED0[1U];
+ __IM uint32_t ICTR; /*!< Offset: 0x004 (R/ ) Interrupt Controller Type Register */
+ __IOM uint32_t ACTLR; /*!< Offset: 0x008 (R/W) Auxiliary Control Register */
+} SCnSCB_Type;
+
+/* Interrupt Controller Type Register Definitions */
+#define SCnSCB_ICTR_INTLINESNUM_Pos 0U /*!< ICTR: INTLINESNUM Position */
+#define SCnSCB_ICTR_INTLINESNUM_Msk (0xFUL /*<< SCnSCB_ICTR_INTLINESNUM_Pos*/) /*!< ICTR: INTLINESNUM Mask */
+
+/* Auxiliary Control Register Definitions */
+#define SCnSCB_ACTLR_DISITMATBFLUSH_Pos 12U /*!< ACTLR: DISITMATBFLUSH Position */
+#define SCnSCB_ACTLR_DISITMATBFLUSH_Msk (1UL << SCnSCB_ACTLR_DISITMATBFLUSH_Pos) /*!< ACTLR: DISITMATBFLUSH Mask */
+
+#define SCnSCB_ACTLR_DISRAMODE_Pos 11U /*!< ACTLR: DISRAMODE Position */
+#define SCnSCB_ACTLR_DISRAMODE_Msk (1UL << SCnSCB_ACTLR_DISRAMODE_Pos) /*!< ACTLR: DISRAMODE Mask */
+
+#define SCnSCB_ACTLR_FPEXCODIS_Pos 10U /*!< ACTLR: FPEXCODIS Position */
+#define SCnSCB_ACTLR_FPEXCODIS_Msk (1UL << SCnSCB_ACTLR_FPEXCODIS_Pos) /*!< ACTLR: FPEXCODIS Mask */
+
+#define SCnSCB_ACTLR_DISFOLD_Pos 2U /*!< ACTLR: DISFOLD Position */
+#define SCnSCB_ACTLR_DISFOLD_Msk (1UL << SCnSCB_ACTLR_DISFOLD_Pos) /*!< ACTLR: DISFOLD Mask */
+
+#define SCnSCB_ACTLR_DISMCYCINT_Pos 0U /*!< ACTLR: DISMCYCINT Position */
+#define SCnSCB_ACTLR_DISMCYCINT_Msk (1UL /*<< SCnSCB_ACTLR_DISMCYCINT_Pos*/) /*!< ACTLR: DISMCYCINT Mask */
+
+/*@} end of group CMSIS_SCnotSCB */
+
+
+/**
+ \ingroup CMSIS_core_register
+ \defgroup CMSIS_SysTick System Tick Timer (SysTick)
+ \brief Type definitions for the System Timer Registers.
+ @{
+ */
+
+/**
+ \brief Structure type to access the System Timer (SysTick).
+ */
+typedef struct
+{
+ __IOM uint32_t CTRL; /*!< Offset: 0x000 (R/W) SysTick Control and Status Register */
+ __IOM uint32_t LOAD; /*!< Offset: 0x004 (R/W) SysTick Reload Value Register */
+ __IOM uint32_t VAL; /*!< Offset: 0x008 (R/W) SysTick Current Value Register */
+ __IM uint32_t CALIB; /*!< Offset: 0x00C (R/ ) SysTick Calibration Register */
+} SysTick_Type;
+
+/* SysTick Control / Status Register Definitions */
+#define SysTick_CTRL_COUNTFLAG_Pos 16U /*!< SysTick CTRL: COUNTFLAG Position */
+#define SysTick_CTRL_COUNTFLAG_Msk (1UL << SysTick_CTRL_COUNTFLAG_Pos) /*!< SysTick CTRL: COUNTFLAG Mask */
+
+#define SysTick_CTRL_CLKSOURCE_Pos 2U /*!< SysTick CTRL: CLKSOURCE Position */
+#define SysTick_CTRL_CLKSOURCE_Msk (1UL << SysTick_CTRL_CLKSOURCE_Pos) /*!< SysTick CTRL: CLKSOURCE Mask */
+
+#define SysTick_CTRL_TICKINT_Pos 1U /*!< SysTick CTRL: TICKINT Position */
+#define SysTick_CTRL_TICKINT_Msk (1UL << SysTick_CTRL_TICKINT_Pos) /*!< SysTick CTRL: TICKINT Mask */
+
+#define SysTick_CTRL_ENABLE_Pos 0U /*!< SysTick CTRL: ENABLE Position */
+#define SysTick_CTRL_ENABLE_Msk (1UL /*<< SysTick_CTRL_ENABLE_Pos*/) /*!< SysTick CTRL: ENABLE Mask */
+
+/* SysTick Reload Register Definitions */
+#define SysTick_LOAD_RELOAD_Pos 0U /*!< SysTick LOAD: RELOAD Position */
+#define SysTick_LOAD_RELOAD_Msk (0xFFFFFFUL /*<< SysTick_LOAD_RELOAD_Pos*/) /*!< SysTick LOAD: RELOAD Mask */
+
+/* SysTick Current Register Definitions */
+#define SysTick_VAL_CURRENT_Pos 0U /*!< SysTick VAL: CURRENT Position */
+#define SysTick_VAL_CURRENT_Msk (0xFFFFFFUL /*<< SysTick_VAL_CURRENT_Pos*/) /*!< SysTick VAL: CURRENT Mask */
+
+/* SysTick Calibration Register Definitions */
+#define SysTick_CALIB_NOREF_Pos 31U /*!< SysTick CALIB: NOREF Position */
+#define SysTick_CALIB_NOREF_Msk (1UL << SysTick_CALIB_NOREF_Pos) /*!< SysTick CALIB: NOREF Mask */
+
+#define SysTick_CALIB_SKEW_Pos 30U /*!< SysTick CALIB: SKEW Position */
+#define SysTick_CALIB_SKEW_Msk (1UL << SysTick_CALIB_SKEW_Pos) /*!< SysTick CALIB: SKEW Mask */
+
+#define SysTick_CALIB_TENMS_Pos 0U /*!< SysTick CALIB: TENMS Position */
+#define SysTick_CALIB_TENMS_Msk (0xFFFFFFUL /*<< SysTick_CALIB_TENMS_Pos*/) /*!< SysTick CALIB: TENMS Mask */
+
+/*@} end of group CMSIS_SysTick */
+
+
+/**
+ \ingroup CMSIS_core_register
+ \defgroup CMSIS_ITM Instrumentation Trace Macrocell (ITM)
+ \brief Type definitions for the Instrumentation Trace Macrocell (ITM)
+ @{
+ */
+
+/**
+ \brief Structure type to access the Instrumentation Trace Macrocell Register (ITM).
+ */
+typedef struct
+{
+ __OM union
+ {
+ __OM uint8_t u8; /*!< Offset: 0x000 ( /W) ITM Stimulus Port 8-bit */
+ __OM uint16_t u16; /*!< Offset: 0x000 ( /W) ITM Stimulus Port 16-bit */
+ __OM uint32_t u32; /*!< Offset: 0x000 ( /W) ITM Stimulus Port 32-bit */
+ } PORT [32U]; /*!< Offset: 0x000 ( /W) ITM Stimulus Port Registers */
+ uint32_t RESERVED0[864U];
+ __IOM uint32_t TER; /*!< Offset: 0xE00 (R/W) ITM Trace Enable Register */
+ uint32_t RESERVED1[15U];
+ __IOM uint32_t TPR; /*!< Offset: 0xE40 (R/W) ITM Trace Privilege Register */
+ uint32_t RESERVED2[15U];
+ __IOM uint32_t TCR; /*!< Offset: 0xE80 (R/W) ITM Trace Control Register */
+ uint32_t RESERVED3[29U];
+ __OM uint32_t IWR; /*!< Offset: 0xEF8 ( /W) ITM Integration Write Register */
+ __IM uint32_t IRR; /*!< Offset: 0xEFC (R/ ) ITM Integration Read Register */
+ __IOM uint32_t IMCR; /*!< Offset: 0xF00 (R/W) ITM Integration Mode Control Register */
+ uint32_t RESERVED4[43U];
+ __OM uint32_t LAR; /*!< Offset: 0xFB0 ( /W) ITM Lock Access Register */
+ __IM uint32_t LSR; /*!< Offset: 0xFB4 (R/ ) ITM Lock Status Register */
+ uint32_t RESERVED5[6U];
+ __IM uint32_t PID4; /*!< Offset: 0xFD0 (R/ ) ITM Peripheral Identification Register #4 */
+ __IM uint32_t PID5; /*!< Offset: 0xFD4 (R/ ) ITM Peripheral Identification Register #5 */
+ __IM uint32_t PID6; /*!< Offset: 0xFD8 (R/ ) ITM Peripheral Identification Register #6 */
+ __IM uint32_t PID7; /*!< Offset: 0xFDC (R/ ) ITM Peripheral Identification Register #7 */
+ __IM uint32_t PID0; /*!< Offset: 0xFE0 (R/ ) ITM Peripheral Identification Register #0 */
+ __IM uint32_t PID1; /*!< Offset: 0xFE4 (R/ ) ITM Peripheral Identification Register #1 */
+ __IM uint32_t PID2; /*!< Offset: 0xFE8 (R/ ) ITM Peripheral Identification Register #2 */
+ __IM uint32_t PID3; /*!< Offset: 0xFEC (R/ ) ITM Peripheral Identification Register #3 */
+ __IM uint32_t CID0; /*!< Offset: 0xFF0 (R/ ) ITM Component Identification Register #0 */
+ __IM uint32_t CID1; /*!< Offset: 0xFF4 (R/ ) ITM Component Identification Register #1 */
+ __IM uint32_t CID2; /*!< Offset: 0xFF8 (R/ ) ITM Component Identification Register #2 */
+ __IM uint32_t CID3; /*!< Offset: 0xFFC (R/ ) ITM Component Identification Register #3 */
+} ITM_Type;
+
+/* ITM Trace Privilege Register Definitions */
+#define ITM_TPR_PRIVMASK_Pos 0U /*!< ITM TPR: PRIVMASK Position */
+#define ITM_TPR_PRIVMASK_Msk (0xFUL /*<< ITM_TPR_PRIVMASK_Pos*/) /*!< ITM TPR: PRIVMASK Mask */
+
+/* ITM Trace Control Register Definitions */
+#define ITM_TCR_BUSY_Pos 23U /*!< ITM TCR: BUSY Position */
+#define ITM_TCR_BUSY_Msk (1UL << ITM_TCR_BUSY_Pos) /*!< ITM TCR: BUSY Mask */
+
+#define ITM_TCR_TraceBusID_Pos 16U /*!< ITM TCR: ATBID Position */
+#define ITM_TCR_TraceBusID_Msk (0x7FUL << ITM_TCR_TraceBusID_Pos) /*!< ITM TCR: ATBID Mask */
+
+#define ITM_TCR_GTSFREQ_Pos 10U /*!< ITM TCR: Global timestamp frequency Position */
+#define ITM_TCR_GTSFREQ_Msk (3UL << ITM_TCR_GTSFREQ_Pos) /*!< ITM TCR: Global timestamp frequency Mask */
+
+#define ITM_TCR_TSPrescale_Pos 8U /*!< ITM TCR: TSPrescale Position */
+#define ITM_TCR_TSPrescale_Msk (3UL << ITM_TCR_TSPrescale_Pos) /*!< ITM TCR: TSPrescale Mask */
+
+#define ITM_TCR_SWOENA_Pos 4U /*!< ITM TCR: SWOENA Position */
+#define ITM_TCR_SWOENA_Msk (1UL << ITM_TCR_SWOENA_Pos) /*!< ITM TCR: SWOENA Mask */
+
+#define ITM_TCR_DWTENA_Pos 3U /*!< ITM TCR: DWTENA Position */
+#define ITM_TCR_DWTENA_Msk (1UL << ITM_TCR_DWTENA_Pos) /*!< ITM TCR: DWTENA Mask */
+
+#define ITM_TCR_SYNCENA_Pos 2U /*!< ITM TCR: SYNCENA Position */
+#define ITM_TCR_SYNCENA_Msk (1UL << ITM_TCR_SYNCENA_Pos) /*!< ITM TCR: SYNCENA Mask */
+
+#define ITM_TCR_TSENA_Pos 1U /*!< ITM TCR: TSENA Position */
+#define ITM_TCR_TSENA_Msk (1UL << ITM_TCR_TSENA_Pos) /*!< ITM TCR: TSENA Mask */
+
+#define ITM_TCR_ITMENA_Pos 0U /*!< ITM TCR: ITM Enable bit Position */
+#define ITM_TCR_ITMENA_Msk (1UL /*<< ITM_TCR_ITMENA_Pos*/) /*!< ITM TCR: ITM Enable bit Mask */
+
+/* ITM Integration Write Register Definitions */
+#define ITM_IWR_ATVALIDM_Pos 0U /*!< ITM IWR: ATVALIDM Position */
+#define ITM_IWR_ATVALIDM_Msk (1UL /*<< ITM_IWR_ATVALIDM_Pos*/) /*!< ITM IWR: ATVALIDM Mask */
+
+/* ITM Integration Read Register Definitions */
+#define ITM_IRR_ATREADYM_Pos 0U /*!< ITM IRR: ATREADYM Position */
+#define ITM_IRR_ATREADYM_Msk (1UL /*<< ITM_IRR_ATREADYM_Pos*/) /*!< ITM IRR: ATREADYM Mask */
+
+/* ITM Integration Mode Control Register Definitions */
+#define ITM_IMCR_INTEGRATION_Pos 0U /*!< ITM IMCR: INTEGRATION Position */
+#define ITM_IMCR_INTEGRATION_Msk (1UL /*<< ITM_IMCR_INTEGRATION_Pos*/) /*!< ITM IMCR: INTEGRATION Mask */
+
+/* ITM Lock Status Register Definitions */
+#define ITM_LSR_ByteAcc_Pos 2U /*!< ITM LSR: ByteAcc Position */
+#define ITM_LSR_ByteAcc_Msk (1UL << ITM_LSR_ByteAcc_Pos) /*!< ITM LSR: ByteAcc Mask */
+
+#define ITM_LSR_Access_Pos 1U /*!< ITM LSR: Access Position */
+#define ITM_LSR_Access_Msk (1UL << ITM_LSR_Access_Pos) /*!< ITM LSR: Access Mask */
+
+#define ITM_LSR_Present_Pos 0U /*!< ITM LSR: Present Position */
+#define ITM_LSR_Present_Msk (1UL /*<< ITM_LSR_Present_Pos*/) /*!< ITM LSR: Present Mask */
+
+/*@}*/ /* end of group CMSIS_ITM */
+
+
+/**
+ \ingroup CMSIS_core_register
+ \defgroup CMSIS_DWT Data Watchpoint and Trace (DWT)
+ \brief Type definitions for the Data Watchpoint and Trace (DWT)
+ @{
+ */
+
+/**
+ \brief Structure type to access the Data Watchpoint and Trace Register (DWT).
+ */
+typedef struct
+{
+ __IOM uint32_t CTRL; /*!< Offset: 0x000 (R/W) Control Register */
+ __IOM uint32_t CYCCNT; /*!< Offset: 0x004 (R/W) Cycle Count Register */
+ __IOM uint32_t CPICNT; /*!< Offset: 0x008 (R/W) CPI Count Register */
+ __IOM uint32_t EXCCNT; /*!< Offset: 0x00C (R/W) Exception Overhead Count Register */
+ __IOM uint32_t SLEEPCNT; /*!< Offset: 0x010 (R/W) Sleep Count Register */
+ __IOM uint32_t LSUCNT; /*!< Offset: 0x014 (R/W) LSU Count Register */
+ __IOM uint32_t FOLDCNT; /*!< Offset: 0x018 (R/W) Folded-instruction Count Register */
+ __IM uint32_t PCSR; /*!< Offset: 0x01C (R/ ) Program Counter Sample Register */
+ __IOM uint32_t COMP0; /*!< Offset: 0x020 (R/W) Comparator Register 0 */
+ __IOM uint32_t MASK0; /*!< Offset: 0x024 (R/W) Mask Register 0 */
+ __IOM uint32_t FUNCTION0; /*!< Offset: 0x028 (R/W) Function Register 0 */
+ uint32_t RESERVED0[1U];
+ __IOM uint32_t COMP1; /*!< Offset: 0x030 (R/W) Comparator Register 1 */
+ __IOM uint32_t MASK1; /*!< Offset: 0x034 (R/W) Mask Register 1 */
+ __IOM uint32_t FUNCTION1; /*!< Offset: 0x038 (R/W) Function Register 1 */
+ uint32_t RESERVED1[1U];
+ __IOM uint32_t COMP2; /*!< Offset: 0x040 (R/W) Comparator Register 2 */
+ __IOM uint32_t MASK2; /*!< Offset: 0x044 (R/W) Mask Register 2 */
+ __IOM uint32_t FUNCTION2; /*!< Offset: 0x048 (R/W) Function Register 2 */
+ uint32_t RESERVED2[1U];
+ __IOM uint32_t COMP3; /*!< Offset: 0x050 (R/W) Comparator Register 3 */
+ __IOM uint32_t MASK3; /*!< Offset: 0x054 (R/W) Mask Register 3 */
+ __IOM uint32_t FUNCTION3; /*!< Offset: 0x058 (R/W) Function Register 3 */
+ uint32_t RESERVED3[981U];
+ __OM uint32_t LAR; /*!< Offset: 0xFB0 ( W) Lock Access Register */
+ __IM uint32_t LSR; /*!< Offset: 0xFB4 (R ) Lock Status Register */
+} DWT_Type;
+
+/* DWT Control Register Definitions */
+#define DWT_CTRL_NUMCOMP_Pos 28U /*!< DWT CTRL: NUMCOMP Position */
+#define DWT_CTRL_NUMCOMP_Msk (0xFUL << DWT_CTRL_NUMCOMP_Pos) /*!< DWT CTRL: NUMCOMP Mask */
+
+#define DWT_CTRL_NOTRCPKT_Pos 27U /*!< DWT CTRL: NOTRCPKT Position */
+#define DWT_CTRL_NOTRCPKT_Msk (0x1UL << DWT_CTRL_NOTRCPKT_Pos) /*!< DWT CTRL: NOTRCPKT Mask */
+
+#define DWT_CTRL_NOEXTTRIG_Pos 26U /*!< DWT CTRL: NOEXTTRIG Position */
+#define DWT_CTRL_NOEXTTRIG_Msk (0x1UL << DWT_CTRL_NOEXTTRIG_Pos) /*!< DWT CTRL: NOEXTTRIG Mask */
+
+#define DWT_CTRL_NOCYCCNT_Pos 25U /*!< DWT CTRL: NOCYCCNT Position */
+#define DWT_CTRL_NOCYCCNT_Msk (0x1UL << DWT_CTRL_NOCYCCNT_Pos) /*!< DWT CTRL: NOCYCCNT Mask */
+
+#define DWT_CTRL_NOPRFCNT_Pos 24U /*!< DWT CTRL: NOPRFCNT Position */
+#define DWT_CTRL_NOPRFCNT_Msk (0x1UL << DWT_CTRL_NOPRFCNT_Pos) /*!< DWT CTRL: NOPRFCNT Mask */
+
+#define DWT_CTRL_CYCEVTENA_Pos 22U /*!< DWT CTRL: CYCEVTENA Position */
+#define DWT_CTRL_CYCEVTENA_Msk (0x1UL << DWT_CTRL_CYCEVTENA_Pos) /*!< DWT CTRL: CYCEVTENA Mask */
+
+#define DWT_CTRL_FOLDEVTENA_Pos 21U /*!< DWT CTRL: FOLDEVTENA Position */
+#define DWT_CTRL_FOLDEVTENA_Msk (0x1UL << DWT_CTRL_FOLDEVTENA_Pos) /*!< DWT CTRL: FOLDEVTENA Mask */
+
+#define DWT_CTRL_LSUEVTENA_Pos 20U /*!< DWT CTRL: LSUEVTENA Position */
+#define DWT_CTRL_LSUEVTENA_Msk (0x1UL << DWT_CTRL_LSUEVTENA_Pos) /*!< DWT CTRL: LSUEVTENA Mask */
+
+#define DWT_CTRL_SLEEPEVTENA_Pos 19U /*!< DWT CTRL: SLEEPEVTENA Position */
+#define DWT_CTRL_SLEEPEVTENA_Msk (0x1UL << DWT_CTRL_SLEEPEVTENA_Pos) /*!< DWT CTRL: SLEEPEVTENA Mask */
+
+#define DWT_CTRL_EXCEVTENA_Pos 18U /*!< DWT CTRL: EXCEVTENA Position */
+#define DWT_CTRL_EXCEVTENA_Msk (0x1UL << DWT_CTRL_EXCEVTENA_Pos) /*!< DWT CTRL: EXCEVTENA Mask */
+
+#define DWT_CTRL_CPIEVTENA_Pos 17U /*!< DWT CTRL: CPIEVTENA Position */
+#define DWT_CTRL_CPIEVTENA_Msk (0x1UL << DWT_CTRL_CPIEVTENA_Pos) /*!< DWT CTRL: CPIEVTENA Mask */
+
+#define DWT_CTRL_EXCTRCENA_Pos 16U /*!< DWT CTRL: EXCTRCENA Position */
+#define DWT_CTRL_EXCTRCENA_Msk (0x1UL << DWT_CTRL_EXCTRCENA_Pos) /*!< DWT CTRL: EXCTRCENA Mask */
+
+#define DWT_CTRL_PCSAMPLENA_Pos 12U /*!< DWT CTRL: PCSAMPLENA Position */
+#define DWT_CTRL_PCSAMPLENA_Msk (0x1UL << DWT_CTRL_PCSAMPLENA_Pos) /*!< DWT CTRL: PCSAMPLENA Mask */
+
+#define DWT_CTRL_SYNCTAP_Pos 10U /*!< DWT CTRL: SYNCTAP Position */
+#define DWT_CTRL_SYNCTAP_Msk (0x3UL << DWT_CTRL_SYNCTAP_Pos) /*!< DWT CTRL: SYNCTAP Mask */
+
+#define DWT_CTRL_CYCTAP_Pos 9U /*!< DWT CTRL: CYCTAP Position */
+#define DWT_CTRL_CYCTAP_Msk (0x1UL << DWT_CTRL_CYCTAP_Pos) /*!< DWT CTRL: CYCTAP Mask */
+
+#define DWT_CTRL_POSTINIT_Pos 5U /*!< DWT CTRL: POSTINIT Position */
+#define DWT_CTRL_POSTINIT_Msk (0xFUL << DWT_CTRL_POSTINIT_Pos) /*!< DWT CTRL: POSTINIT Mask */
+
+#define DWT_CTRL_POSTPRESET_Pos 1U /*!< DWT CTRL: POSTPRESET Position */
+#define DWT_CTRL_POSTPRESET_Msk (0xFUL << DWT_CTRL_POSTPRESET_Pos) /*!< DWT CTRL: POSTPRESET Mask */
+
+#define DWT_CTRL_CYCCNTENA_Pos 0U /*!< DWT CTRL: CYCCNTENA Position */
+#define DWT_CTRL_CYCCNTENA_Msk (0x1UL /*<< DWT_CTRL_CYCCNTENA_Pos*/) /*!< DWT CTRL: CYCCNTENA Mask */
+
+/* DWT CPI Count Register Definitions */
+#define DWT_CPICNT_CPICNT_Pos 0U /*!< DWT CPICNT: CPICNT Position */
+#define DWT_CPICNT_CPICNT_Msk (0xFFUL /*<< DWT_CPICNT_CPICNT_Pos*/) /*!< DWT CPICNT: CPICNT Mask */
+
+/* DWT Exception Overhead Count Register Definitions */
+#define DWT_EXCCNT_EXCCNT_Pos 0U /*!< DWT EXCCNT: EXCCNT Position */
+#define DWT_EXCCNT_EXCCNT_Msk (0xFFUL /*<< DWT_EXCCNT_EXCCNT_Pos*/) /*!< DWT EXCCNT: EXCCNT Mask */
+
+/* DWT Sleep Count Register Definitions */
+#define DWT_SLEEPCNT_SLEEPCNT_Pos 0U /*!< DWT SLEEPCNT: SLEEPCNT Position */
+#define DWT_SLEEPCNT_SLEEPCNT_Msk (0xFFUL /*<< DWT_SLEEPCNT_SLEEPCNT_Pos*/) /*!< DWT SLEEPCNT: SLEEPCNT Mask */
+
+/* DWT LSU Count Register Definitions */
+#define DWT_LSUCNT_LSUCNT_Pos 0U /*!< DWT LSUCNT: LSUCNT Position */
+#define DWT_LSUCNT_LSUCNT_Msk (0xFFUL /*<< DWT_LSUCNT_LSUCNT_Pos*/) /*!< DWT LSUCNT: LSUCNT Mask */
+
+/* DWT Folded-instruction Count Register Definitions */
+#define DWT_FOLDCNT_FOLDCNT_Pos 0U /*!< DWT FOLDCNT: FOLDCNT Position */
+#define DWT_FOLDCNT_FOLDCNT_Msk (0xFFUL /*<< DWT_FOLDCNT_FOLDCNT_Pos*/) /*!< DWT FOLDCNT: FOLDCNT Mask */
+
+/* DWT Comparator Mask Register Definitions */
+#define DWT_MASK_MASK_Pos 0U /*!< DWT MASK: MASK Position */
+#define DWT_MASK_MASK_Msk (0x1FUL /*<< DWT_MASK_MASK_Pos*/) /*!< DWT MASK: MASK Mask */
+
+/* DWT Comparator Function Register Definitions */
+#define DWT_FUNCTION_MATCHED_Pos 24U /*!< DWT FUNCTION: MATCHED Position */
+#define DWT_FUNCTION_MATCHED_Msk (0x1UL << DWT_FUNCTION_MATCHED_Pos) /*!< DWT FUNCTION: MATCHED Mask */
+
+#define DWT_FUNCTION_DATAVADDR1_Pos 16U /*!< DWT FUNCTION: DATAVADDR1 Position */
+#define DWT_FUNCTION_DATAVADDR1_Msk (0xFUL << DWT_FUNCTION_DATAVADDR1_Pos) /*!< DWT FUNCTION: DATAVADDR1 Mask */
+
+#define DWT_FUNCTION_DATAVADDR0_Pos 12U /*!< DWT FUNCTION: DATAVADDR0 Position */
+#define DWT_FUNCTION_DATAVADDR0_Msk (0xFUL << DWT_FUNCTION_DATAVADDR0_Pos) /*!< DWT FUNCTION: DATAVADDR0 Mask */
+
+#define DWT_FUNCTION_DATAVSIZE_Pos 10U /*!< DWT FUNCTION: DATAVSIZE Position */
+#define DWT_FUNCTION_DATAVSIZE_Msk (0x3UL << DWT_FUNCTION_DATAVSIZE_Pos) /*!< DWT FUNCTION: DATAVSIZE Mask */
+
+#define DWT_FUNCTION_LNK1ENA_Pos 9U /*!< DWT FUNCTION: LNK1ENA Position */
+#define DWT_FUNCTION_LNK1ENA_Msk (0x1UL << DWT_FUNCTION_LNK1ENA_Pos) /*!< DWT FUNCTION: LNK1ENA Mask */
+
+#define DWT_FUNCTION_DATAVMATCH_Pos 8U /*!< DWT FUNCTION: DATAVMATCH Position */
+#define DWT_FUNCTION_DATAVMATCH_Msk (0x1UL << DWT_FUNCTION_DATAVMATCH_Pos) /*!< DWT FUNCTION: DATAVMATCH Mask */
+
+#define DWT_FUNCTION_CYCMATCH_Pos 7U /*!< DWT FUNCTION: CYCMATCH Position */
+#define DWT_FUNCTION_CYCMATCH_Msk (0x1UL << DWT_FUNCTION_CYCMATCH_Pos) /*!< DWT FUNCTION: CYCMATCH Mask */
+
+#define DWT_FUNCTION_EMITRANGE_Pos 5U /*!< DWT FUNCTION: EMITRANGE Position */
+#define DWT_FUNCTION_EMITRANGE_Msk (0x1UL << DWT_FUNCTION_EMITRANGE_Pos) /*!< DWT FUNCTION: EMITRANGE Mask */
+
+#define DWT_FUNCTION_FUNCTION_Pos 0U /*!< DWT FUNCTION: FUNCTION Position */
+#define DWT_FUNCTION_FUNCTION_Msk (0xFUL /*<< DWT_FUNCTION_FUNCTION_Pos*/) /*!< DWT FUNCTION: FUNCTION Mask */
+
+/*@}*/ /* end of group CMSIS_DWT */
+
+
+/**
+ \ingroup CMSIS_core_register
+ \defgroup CMSIS_TPI Trace Port Interface (TPI)
+ \brief Type definitions for the Trace Port Interface (TPI)
+ @{
+ */
+
+/**
+ \brief Structure type to access the Trace Port Interface Register (TPI).
+ */
+typedef struct
+{
+ __IOM uint32_t SSPSR; /*!< Offset: 0x000 (R/ ) Supported Parallel Port Size Register */
+ __IOM uint32_t CSPSR; /*!< Offset: 0x004 (R/W) Current Parallel Port Size Register */
+ uint32_t RESERVED0[2U];
+ __IOM uint32_t ACPR; /*!< Offset: 0x010 (R/W) Asynchronous Clock Prescaler Register */
+ uint32_t RESERVED1[55U];
+ __IOM uint32_t SPPR; /*!< Offset: 0x0F0 (R/W) Selected Pin Protocol Register */
+ uint32_t RESERVED2[131U];
+ __IM uint32_t FFSR; /*!< Offset: 0x300 (R/ ) Formatter and Flush Status Register */
+ __IOM uint32_t FFCR; /*!< Offset: 0x304 (R/W) Formatter and Flush Control Register */
+ __IM uint32_t FSCR; /*!< Offset: 0x308 (R/ ) Formatter Synchronization Counter Register */
+ uint32_t RESERVED3[759U];
+ __IM uint32_t TRIGGER; /*!< Offset: 0xEE8 (R/ ) TRIGGER */
+ __IM uint32_t FIFO0; /*!< Offset: 0xEEC (R/ ) Integration ETM Data */
+ __IM uint32_t ITATBCTR2; /*!< Offset: 0xEF0 (R/ ) ITATBCTR2 */
+ uint32_t RESERVED4[1U];
+ __IM uint32_t ITATBCTR0; /*!< Offset: 0xEF8 (R/ ) ITATBCTR0 */
+ __IM uint32_t FIFO1; /*!< Offset: 0xEFC (R/ ) Integration ITM Data */
+ __IOM uint32_t ITCTRL; /*!< Offset: 0xF00 (R/W) Integration Mode Control */
+ uint32_t RESERVED5[39U];
+ __IOM uint32_t CLAIMSET; /*!< Offset: 0xFA0 (R/W) Claim tag set */
+ __IOM uint32_t CLAIMCLR; /*!< Offset: 0xFA4 (R/W) Claim tag clear */
+ uint32_t RESERVED7[8U];
+ __IM uint32_t DEVID; /*!< Offset: 0xFC8 (R/ ) TPIU_DEVID */
+ __IM uint32_t DEVTYPE; /*!< Offset: 0xFCC (R/ ) TPIU_DEVTYPE */
+} TPI_Type;
+
+/* TPI Asynchronous Clock Prescaler Register Definitions */
+#define TPI_ACPR_PRESCALER_Pos 0U /*!< TPI ACPR: PRESCALER Position */
+#define TPI_ACPR_PRESCALER_Msk (0x1FFFUL /*<< TPI_ACPR_PRESCALER_Pos*/) /*!< TPI ACPR: PRESCALER Mask */
+
+/* TPI Selected Pin Protocol Register Definitions */
+#define TPI_SPPR_TXMODE_Pos 0U /*!< TPI SPPR: TXMODE Position */
+#define TPI_SPPR_TXMODE_Msk (0x3UL /*<< TPI_SPPR_TXMODE_Pos*/) /*!< TPI SPPR: TXMODE Mask */
+
+/* TPI Formatter and Flush Status Register Definitions */
+#define TPI_FFSR_FtNonStop_Pos 3U /*!< TPI FFSR: FtNonStop Position */
+#define TPI_FFSR_FtNonStop_Msk (0x1UL << TPI_FFSR_FtNonStop_Pos) /*!< TPI FFSR: FtNonStop Mask */
+
+#define TPI_FFSR_TCPresent_Pos 2U /*!< TPI FFSR: TCPresent Position */
+#define TPI_FFSR_TCPresent_Msk (0x1UL << TPI_FFSR_TCPresent_Pos) /*!< TPI FFSR: TCPresent Mask */
+
+#define TPI_FFSR_FtStopped_Pos 1U /*!< TPI FFSR: FtStopped Position */
+#define TPI_FFSR_FtStopped_Msk (0x1UL << TPI_FFSR_FtStopped_Pos) /*!< TPI FFSR: FtStopped Mask */
+
+#define TPI_FFSR_FlInProg_Pos 0U /*!< TPI FFSR: FlInProg Position */
+#define TPI_FFSR_FlInProg_Msk (0x1UL /*<< TPI_FFSR_FlInProg_Pos*/) /*!< TPI FFSR: FlInProg Mask */
+
+/* TPI Formatter and Flush Control Register Definitions */
+#define TPI_FFCR_TrigIn_Pos 8U /*!< TPI FFCR: TrigIn Position */
+#define TPI_FFCR_TrigIn_Msk (0x1UL << TPI_FFCR_TrigIn_Pos) /*!< TPI FFCR: TrigIn Mask */
+
+#define TPI_FFCR_EnFCont_Pos 1U /*!< TPI FFCR: EnFCont Position */
+#define TPI_FFCR_EnFCont_Msk (0x1UL << TPI_FFCR_EnFCont_Pos) /*!< TPI FFCR: EnFCont Mask */
+
+/* TPI TRIGGER Register Definitions */
+#define TPI_TRIGGER_TRIGGER_Pos 0U /*!< TPI TRIGGER: TRIGGER Position */
+#define TPI_TRIGGER_TRIGGER_Msk (0x1UL /*<< TPI_TRIGGER_TRIGGER_Pos*/) /*!< TPI TRIGGER: TRIGGER Mask */
+
+/* TPI Integration ETM Data Register Definitions (FIFO0) */
+#define TPI_FIFO0_ITM_ATVALID_Pos 29U /*!< TPI FIFO0: ITM_ATVALID Position */
+#define TPI_FIFO0_ITM_ATVALID_Msk (0x3UL << TPI_FIFO0_ITM_ATVALID_Pos) /*!< TPI FIFO0: ITM_ATVALID Mask */
+
+#define TPI_FIFO0_ITM_bytecount_Pos 27U /*!< TPI FIFO0: ITM_bytecount Position */
+#define TPI_FIFO0_ITM_bytecount_Msk (0x3UL << TPI_FIFO0_ITM_bytecount_Pos) /*!< TPI FIFO0: ITM_bytecount Mask */
+
+#define TPI_FIFO0_ETM_ATVALID_Pos 26U /*!< TPI FIFO0: ETM_ATVALID Position */
+#define TPI_FIFO0_ETM_ATVALID_Msk (0x3UL << TPI_FIFO0_ETM_ATVALID_Pos) /*!< TPI FIFO0: ETM_ATVALID Mask */
+
+#define TPI_FIFO0_ETM_bytecount_Pos 24U /*!< TPI FIFO0: ETM_bytecount Position */
+#define TPI_FIFO0_ETM_bytecount_Msk (0x3UL << TPI_FIFO0_ETM_bytecount_Pos) /*!< TPI FIFO0: ETM_bytecount Mask */
+
+#define TPI_FIFO0_ETM2_Pos 16U /*!< TPI FIFO0: ETM2 Position */
+#define TPI_FIFO0_ETM2_Msk (0xFFUL << TPI_FIFO0_ETM2_Pos) /*!< TPI FIFO0: ETM2 Mask */
+
+#define TPI_FIFO0_ETM1_Pos 8U /*!< TPI FIFO0: ETM1 Position */
+#define TPI_FIFO0_ETM1_Msk (0xFFUL << TPI_FIFO0_ETM1_Pos) /*!< TPI FIFO0: ETM1 Mask */
+
+#define TPI_FIFO0_ETM0_Pos 0U /*!< TPI FIFO0: ETM0 Position */
+#define TPI_FIFO0_ETM0_Msk (0xFFUL /*<< TPI_FIFO0_ETM0_Pos*/) /*!< TPI FIFO0: ETM0 Mask */
+
+/* TPI ITATBCTR2 Register Definitions */
+#define TPI_ITATBCTR2_ATREADY_Pos 0U /*!< TPI ITATBCTR2: ATREADY Position */
+#define TPI_ITATBCTR2_ATREADY_Msk (0x1UL /*<< TPI_ITATBCTR2_ATREADY_Pos*/) /*!< TPI ITATBCTR2: ATREADY Mask */
+
+/* TPI Integration ITM Data Register Definitions (FIFO1) */
+#define TPI_FIFO1_ITM_ATVALID_Pos 29U /*!< TPI FIFO1: ITM_ATVALID Position */
+#define TPI_FIFO1_ITM_ATVALID_Msk (0x3UL << TPI_FIFO1_ITM_ATVALID_Pos) /*!< TPI FIFO1: ITM_ATVALID Mask */
+
+#define TPI_FIFO1_ITM_bytecount_Pos 27U /*!< TPI FIFO1: ITM_bytecount Position */
+#define TPI_FIFO1_ITM_bytecount_Msk (0x3UL << TPI_FIFO1_ITM_bytecount_Pos) /*!< TPI FIFO1: ITM_bytecount Mask */
+
+#define TPI_FIFO1_ETM_ATVALID_Pos 26U /*!< TPI FIFO1: ETM_ATVALID Position */
+#define TPI_FIFO1_ETM_ATVALID_Msk (0x3UL << TPI_FIFO1_ETM_ATVALID_Pos) /*!< TPI FIFO1: ETM_ATVALID Mask */
+
+#define TPI_FIFO1_ETM_bytecount_Pos 24U /*!< TPI FIFO1: ETM_bytecount Position */
+#define TPI_FIFO1_ETM_bytecount_Msk (0x3UL << TPI_FIFO1_ETM_bytecount_Pos) /*!< TPI FIFO1: ETM_bytecount Mask */
+
+#define TPI_FIFO1_ITM2_Pos 16U /*!< TPI FIFO1: ITM2 Position */
+#define TPI_FIFO1_ITM2_Msk (0xFFUL << TPI_FIFO1_ITM2_Pos) /*!< TPI FIFO1: ITM2 Mask */
+
+#define TPI_FIFO1_ITM1_Pos 8U /*!< TPI FIFO1: ITM1 Position */
+#define TPI_FIFO1_ITM1_Msk (0xFFUL << TPI_FIFO1_ITM1_Pos) /*!< TPI FIFO1: ITM1 Mask */
+
+#define TPI_FIFO1_ITM0_Pos 0U /*!< TPI FIFO1: ITM0 Position */
+#define TPI_FIFO1_ITM0_Msk (0xFFUL /*<< TPI_FIFO1_ITM0_Pos*/) /*!< TPI FIFO1: ITM0 Mask */
+
+/* TPI ITATBCTR0 Register Definitions */
+#define TPI_ITATBCTR0_ATREADY_Pos 0U /*!< TPI ITATBCTR0: ATREADY Position */
+#define TPI_ITATBCTR0_ATREADY_Msk (0x1UL /*<< TPI_ITATBCTR0_ATREADY_Pos*/) /*!< TPI ITATBCTR0: ATREADY Mask */
+
+/* TPI Integration Mode Control Register Definitions */
+#define TPI_ITCTRL_Mode_Pos 0U /*!< TPI ITCTRL: Mode Position */
+#define TPI_ITCTRL_Mode_Msk (0x1UL /*<< TPI_ITCTRL_Mode_Pos*/) /*!< TPI ITCTRL: Mode Mask */
+
+/* TPI DEVID Register Definitions */
+#define TPI_DEVID_NRZVALID_Pos 11U /*!< TPI DEVID: NRZVALID Position */
+#define TPI_DEVID_NRZVALID_Msk (0x1UL << TPI_DEVID_NRZVALID_Pos) /*!< TPI DEVID: NRZVALID Mask */
+
+#define TPI_DEVID_MANCVALID_Pos 10U /*!< TPI DEVID: MANCVALID Position */
+#define TPI_DEVID_MANCVALID_Msk (0x1UL << TPI_DEVID_MANCVALID_Pos) /*!< TPI DEVID: MANCVALID Mask */
+
+#define TPI_DEVID_PTINVALID_Pos 9U /*!< TPI DEVID: PTINVALID Position */
+#define TPI_DEVID_PTINVALID_Msk (0x1UL << TPI_DEVID_PTINVALID_Pos) /*!< TPI DEVID: PTINVALID Mask */
+
+#define TPI_DEVID_MinBufSz_Pos 6U /*!< TPI DEVID: MinBufSz Position */
+#define TPI_DEVID_MinBufSz_Msk (0x7UL << TPI_DEVID_MinBufSz_Pos) /*!< TPI DEVID: MinBufSz Mask */
+
+#define TPI_DEVID_AsynClkIn_Pos 5U /*!< TPI DEVID: AsynClkIn Position */
+#define TPI_DEVID_AsynClkIn_Msk (0x1UL << TPI_DEVID_AsynClkIn_Pos) /*!< TPI DEVID: AsynClkIn Mask */
+
+#define TPI_DEVID_NrTraceInput_Pos 0U /*!< TPI DEVID: NrTraceInput Position */
+#define TPI_DEVID_NrTraceInput_Msk (0x1FUL /*<< TPI_DEVID_NrTraceInput_Pos*/) /*!< TPI DEVID: NrTraceInput Mask */
+
+/* TPI DEVTYPE Register Definitions */
+#define TPI_DEVTYPE_MajorType_Pos 4U /*!< TPI DEVTYPE: MajorType Position */
+#define TPI_DEVTYPE_MajorType_Msk (0xFUL << TPI_DEVTYPE_MajorType_Pos) /*!< TPI DEVTYPE: MajorType Mask */
+
+#define TPI_DEVTYPE_SubType_Pos 0U /*!< TPI DEVTYPE: SubType Position */
+#define TPI_DEVTYPE_SubType_Msk (0xFUL /*<< TPI_DEVTYPE_SubType_Pos*/) /*!< TPI DEVTYPE: SubType Mask */
+
+/*@}*/ /* end of group CMSIS_TPI */
+
+
+#if (__MPU_PRESENT == 1U)
+/**
+ \ingroup CMSIS_core_register
+ \defgroup CMSIS_MPU Memory Protection Unit (MPU)
+ \brief Type definitions for the Memory Protection Unit (MPU)
+ @{
+ */
+
+/**
+ \brief Structure type to access the Memory Protection Unit (MPU).
+ */
+typedef struct
+{
+ __IM uint32_t TYPE; /*!< Offset: 0x000 (R/ ) MPU Type Register */
+ __IOM uint32_t CTRL; /*!< Offset: 0x004 (R/W) MPU Control Register */
+ __IOM uint32_t RNR; /*!< Offset: 0x008 (R/W) MPU Region RNRber Register */
+ __IOM uint32_t RBAR; /*!< Offset: 0x00C (R/W) MPU Region Base Address Register */
+ __IOM uint32_t RASR; /*!< Offset: 0x010 (R/W) MPU Region Attribute and Size Register */
+ __IOM uint32_t RBAR_A1; /*!< Offset: 0x014 (R/W) MPU Alias 1 Region Base Address Register */
+ __IOM uint32_t RASR_A1; /*!< Offset: 0x018 (R/W) MPU Alias 1 Region Attribute and Size Register */
+ __IOM uint32_t RBAR_A2; /*!< Offset: 0x01C (R/W) MPU Alias 2 Region Base Address Register */
+ __IOM uint32_t RASR_A2; /*!< Offset: 0x020 (R/W) MPU Alias 2 Region Attribute and Size Register */
+ __IOM uint32_t RBAR_A3; /*!< Offset: 0x024 (R/W) MPU Alias 3 Region Base Address Register */
+ __IOM uint32_t RASR_A3; /*!< Offset: 0x028 (R/W) MPU Alias 3 Region Attribute and Size Register */
+} MPU_Type;
+
+/* MPU Type Register Definitions */
+#define MPU_TYPE_IREGION_Pos 16U /*!< MPU TYPE: IREGION Position */
+#define MPU_TYPE_IREGION_Msk (0xFFUL << MPU_TYPE_IREGION_Pos) /*!< MPU TYPE: IREGION Mask */
+
+#define MPU_TYPE_DREGION_Pos 8U /*!< MPU TYPE: DREGION Position */
+#define MPU_TYPE_DREGION_Msk (0xFFUL << MPU_TYPE_DREGION_Pos) /*!< MPU TYPE: DREGION Mask */
+
+#define MPU_TYPE_SEPARATE_Pos 0U /*!< MPU TYPE: SEPARATE Position */
+#define MPU_TYPE_SEPARATE_Msk (1UL /*<< MPU_TYPE_SEPARATE_Pos*/) /*!< MPU TYPE: SEPARATE Mask */
+
+/* MPU Control Register Definitions */
+#define MPU_CTRL_PRIVDEFENA_Pos 2U /*!< MPU CTRL: PRIVDEFENA Position */
+#define MPU_CTRL_PRIVDEFENA_Msk (1UL << MPU_CTRL_PRIVDEFENA_Pos) /*!< MPU CTRL: PRIVDEFENA Mask */
+
+#define MPU_CTRL_HFNMIENA_Pos 1U /*!< MPU CTRL: HFNMIENA Position */
+#define MPU_CTRL_HFNMIENA_Msk (1UL << MPU_CTRL_HFNMIENA_Pos) /*!< MPU CTRL: HFNMIENA Mask */
+
+#define MPU_CTRL_ENABLE_Pos 0U /*!< MPU CTRL: ENABLE Position */
+#define MPU_CTRL_ENABLE_Msk (1UL /*<< MPU_CTRL_ENABLE_Pos*/) /*!< MPU CTRL: ENABLE Mask */
+
+/* MPU Region Number Register Definitions */
+#define MPU_RNR_REGION_Pos 0U /*!< MPU RNR: REGION Position */
+#define MPU_RNR_REGION_Msk (0xFFUL /*<< MPU_RNR_REGION_Pos*/) /*!< MPU RNR: REGION Mask */
+
+/* MPU Region Base Address Register Definitions */
+#define MPU_RBAR_ADDR_Pos 5U /*!< MPU RBAR: ADDR Position */
+#define MPU_RBAR_ADDR_Msk (0x7FFFFFFUL << MPU_RBAR_ADDR_Pos) /*!< MPU RBAR: ADDR Mask */
+
+#define MPU_RBAR_VALID_Pos 4U /*!< MPU RBAR: VALID Position */
+#define MPU_RBAR_VALID_Msk (1UL << MPU_RBAR_VALID_Pos) /*!< MPU RBAR: VALID Mask */
+
+#define MPU_RBAR_REGION_Pos 0U /*!< MPU RBAR: REGION Position */
+#define MPU_RBAR_REGION_Msk (0xFUL /*<< MPU_RBAR_REGION_Pos*/) /*!< MPU RBAR: REGION Mask */
+
+/* MPU Region Attribute and Size Register Definitions */
+#define MPU_RASR_ATTRS_Pos 16U /*!< MPU RASR: MPU Region Attribute field Position */
+#define MPU_RASR_ATTRS_Msk (0xFFFFUL << MPU_RASR_ATTRS_Pos) /*!< MPU RASR: MPU Region Attribute field Mask */
+
+#define MPU_RASR_XN_Pos 28U /*!< MPU RASR: ATTRS.XN Position */
+#define MPU_RASR_XN_Msk (1UL << MPU_RASR_XN_Pos) /*!< MPU RASR: ATTRS.XN Mask */
+
+#define MPU_RASR_AP_Pos 24U /*!< MPU RASR: ATTRS.AP Position */
+#define MPU_RASR_AP_Msk (0x7UL << MPU_RASR_AP_Pos) /*!< MPU RASR: ATTRS.AP Mask */
+
+#define MPU_RASR_TEX_Pos 19U /*!< MPU RASR: ATTRS.TEX Position */
+#define MPU_RASR_TEX_Msk (0x7UL << MPU_RASR_TEX_Pos) /*!< MPU RASR: ATTRS.TEX Mask */
+
+#define MPU_RASR_S_Pos 18U /*!< MPU RASR: ATTRS.S Position */
+#define MPU_RASR_S_Msk (1UL << MPU_RASR_S_Pos) /*!< MPU RASR: ATTRS.S Mask */
+
+#define MPU_RASR_C_Pos 17U /*!< MPU RASR: ATTRS.C Position */
+#define MPU_RASR_C_Msk (1UL << MPU_RASR_C_Pos) /*!< MPU RASR: ATTRS.C Mask */
+
+#define MPU_RASR_B_Pos 16U /*!< MPU RASR: ATTRS.B Position */
+#define MPU_RASR_B_Msk (1UL << MPU_RASR_B_Pos) /*!< MPU RASR: ATTRS.B Mask */
+
+#define MPU_RASR_SRD_Pos 8U /*!< MPU RASR: Sub-Region Disable Position */
+#define MPU_RASR_SRD_Msk (0xFFUL << MPU_RASR_SRD_Pos) /*!< MPU RASR: Sub-Region Disable Mask */
+
+#define MPU_RASR_SIZE_Pos 1U /*!< MPU RASR: Region Size Field Position */
+#define MPU_RASR_SIZE_Msk (0x1FUL << MPU_RASR_SIZE_Pos) /*!< MPU RASR: Region Size Field Mask */
+
+#define MPU_RASR_ENABLE_Pos 0U /*!< MPU RASR: Region enable bit Position */
+#define MPU_RASR_ENABLE_Msk (1UL /*<< MPU_RASR_ENABLE_Pos*/) /*!< MPU RASR: Region enable bit Disable Mask */
+
+/*@} end of group CMSIS_MPU */
+#endif
+
+
+#if (__FPU_PRESENT == 1U)
+/**
+ \ingroup CMSIS_core_register
+ \defgroup CMSIS_FPU Floating Point Unit (FPU)
+ \brief Type definitions for the Floating Point Unit (FPU)
+ @{
+ */
+
+/**
+ \brief Structure type to access the Floating Point Unit (FPU).
+ */
+typedef struct
+{
+ uint32_t RESERVED0[1U];
+ __IOM uint32_t FPCCR; /*!< Offset: 0x004 (R/W) Floating-Point Context Control Register */
+ __IOM uint32_t FPCAR; /*!< Offset: 0x008 (R/W) Floating-Point Context Address Register */
+ __IOM uint32_t FPDSCR; /*!< Offset: 0x00C (R/W) Floating-Point Default Status Control Register */
+ __IM uint32_t MVFR0; /*!< Offset: 0x010 (R/ ) Media and FP Feature Register 0 */
+ __IM uint32_t MVFR1; /*!< Offset: 0x014 (R/ ) Media and FP Feature Register 1 */
+ __IM uint32_t MVFR2; /*!< Offset: 0x018 (R/ ) Media and FP Feature Register 2 */
+} FPU_Type;
+
+/* Floating-Point Context Control Register Definitions */
+#define FPU_FPCCR_ASPEN_Pos 31U /*!< FPCCR: ASPEN bit Position */
+#define FPU_FPCCR_ASPEN_Msk (1UL << FPU_FPCCR_ASPEN_Pos) /*!< FPCCR: ASPEN bit Mask */
+
+#define FPU_FPCCR_LSPEN_Pos 30U /*!< FPCCR: LSPEN Position */
+#define FPU_FPCCR_LSPEN_Msk (1UL << FPU_FPCCR_LSPEN_Pos) /*!< FPCCR: LSPEN bit Mask */
+
+#define FPU_FPCCR_MONRDY_Pos 8U /*!< FPCCR: MONRDY Position */
+#define FPU_FPCCR_MONRDY_Msk (1UL << FPU_FPCCR_MONRDY_Pos) /*!< FPCCR: MONRDY bit Mask */
+
+#define FPU_FPCCR_BFRDY_Pos 6U /*!< FPCCR: BFRDY Position */
+#define FPU_FPCCR_BFRDY_Msk (1UL << FPU_FPCCR_BFRDY_Pos) /*!< FPCCR: BFRDY bit Mask */
+
+#define FPU_FPCCR_MMRDY_Pos 5U /*!< FPCCR: MMRDY Position */
+#define FPU_FPCCR_MMRDY_Msk (1UL << FPU_FPCCR_MMRDY_Pos) /*!< FPCCR: MMRDY bit Mask */
+
+#define FPU_FPCCR_HFRDY_Pos 4U /*!< FPCCR: HFRDY Position */
+#define FPU_FPCCR_HFRDY_Msk (1UL << FPU_FPCCR_HFRDY_Pos) /*!< FPCCR: HFRDY bit Mask */
+
+#define FPU_FPCCR_THREAD_Pos 3U /*!< FPCCR: processor mode bit Position */
+#define FPU_FPCCR_THREAD_Msk (1UL << FPU_FPCCR_THREAD_Pos) /*!< FPCCR: processor mode active bit Mask */
+
+#define FPU_FPCCR_USER_Pos 1U /*!< FPCCR: privilege level bit Position */
+#define FPU_FPCCR_USER_Msk (1UL << FPU_FPCCR_USER_Pos) /*!< FPCCR: privilege level bit Mask */
+
+#define FPU_FPCCR_LSPACT_Pos 0U /*!< FPCCR: Lazy state preservation active bit Position */
+#define FPU_FPCCR_LSPACT_Msk (1UL /*<< FPU_FPCCR_LSPACT_Pos*/) /*!< FPCCR: Lazy state preservation active bit Mask */
+
+/* Floating-Point Context Address Register Definitions */
+#define FPU_FPCAR_ADDRESS_Pos 3U /*!< FPCAR: ADDRESS bit Position */
+#define FPU_FPCAR_ADDRESS_Msk (0x1FFFFFFFUL << FPU_FPCAR_ADDRESS_Pos) /*!< FPCAR: ADDRESS bit Mask */
+
+/* Floating-Point Default Status Control Register Definitions */
+#define FPU_FPDSCR_AHP_Pos 26U /*!< FPDSCR: AHP bit Position */
+#define FPU_FPDSCR_AHP_Msk (1UL << FPU_FPDSCR_AHP_Pos) /*!< FPDSCR: AHP bit Mask */
+
+#define FPU_FPDSCR_DN_Pos 25U /*!< FPDSCR: DN bit Position */
+#define FPU_FPDSCR_DN_Msk (1UL << FPU_FPDSCR_DN_Pos) /*!< FPDSCR: DN bit Mask */
+
+#define FPU_FPDSCR_FZ_Pos 24U /*!< FPDSCR: FZ bit Position */
+#define FPU_FPDSCR_FZ_Msk (1UL << FPU_FPDSCR_FZ_Pos) /*!< FPDSCR: FZ bit Mask */
+
+#define FPU_FPDSCR_RMode_Pos 22U /*!< FPDSCR: RMode bit Position */
+#define FPU_FPDSCR_RMode_Msk (3UL << FPU_FPDSCR_RMode_Pos) /*!< FPDSCR: RMode bit Mask */
+
+/* Media and FP Feature Register 0 Definitions */
+#define FPU_MVFR0_FP_rounding_modes_Pos 28U /*!< MVFR0: FP rounding modes bits Position */
+#define FPU_MVFR0_FP_rounding_modes_Msk (0xFUL << FPU_MVFR0_FP_rounding_modes_Pos) /*!< MVFR0: FP rounding modes bits Mask */
+
+#define FPU_MVFR0_Short_vectors_Pos 24U /*!< MVFR0: Short vectors bits Position */
+#define FPU_MVFR0_Short_vectors_Msk (0xFUL << FPU_MVFR0_Short_vectors_Pos) /*!< MVFR0: Short vectors bits Mask */
+
+#define FPU_MVFR0_Square_root_Pos 20U /*!< MVFR0: Square root bits Position */
+#define FPU_MVFR0_Square_root_Msk (0xFUL << FPU_MVFR0_Square_root_Pos) /*!< MVFR0: Square root bits Mask */
+
+#define FPU_MVFR0_Divide_Pos 16U /*!< MVFR0: Divide bits Position */
+#define FPU_MVFR0_Divide_Msk (0xFUL << FPU_MVFR0_Divide_Pos) /*!< MVFR0: Divide bits Mask */
+
+#define FPU_MVFR0_FP_excep_trapping_Pos 12U /*!< MVFR0: FP exception trapping bits Position */
+#define FPU_MVFR0_FP_excep_trapping_Msk (0xFUL << FPU_MVFR0_FP_excep_trapping_Pos) /*!< MVFR0: FP exception trapping bits Mask */
+
+#define FPU_MVFR0_Double_precision_Pos 8U /*!< MVFR0: Double-precision bits Position */
+#define FPU_MVFR0_Double_precision_Msk (0xFUL << FPU_MVFR0_Double_precision_Pos) /*!< MVFR0: Double-precision bits Mask */
+
+#define FPU_MVFR0_Single_precision_Pos 4U /*!< MVFR0: Single-precision bits Position */
+#define FPU_MVFR0_Single_precision_Msk (0xFUL << FPU_MVFR0_Single_precision_Pos) /*!< MVFR0: Single-precision bits Mask */
+
+#define FPU_MVFR0_A_SIMD_registers_Pos 0U /*!< MVFR0: A_SIMD registers bits Position */
+#define FPU_MVFR0_A_SIMD_registers_Msk (0xFUL /*<< FPU_MVFR0_A_SIMD_registers_Pos*/) /*!< MVFR0: A_SIMD registers bits Mask */
+
+/* Media and FP Feature Register 1 Definitions */
+#define FPU_MVFR1_FP_fused_MAC_Pos 28U /*!< MVFR1: FP fused MAC bits Position */
+#define FPU_MVFR1_FP_fused_MAC_Msk (0xFUL << FPU_MVFR1_FP_fused_MAC_Pos) /*!< MVFR1: FP fused MAC bits Mask */
+
+#define FPU_MVFR1_FP_HPFP_Pos 24U /*!< MVFR1: FP HPFP bits Position */
+#define FPU_MVFR1_FP_HPFP_Msk (0xFUL << FPU_MVFR1_FP_HPFP_Pos) /*!< MVFR1: FP HPFP bits Mask */
+
+#define FPU_MVFR1_D_NaN_mode_Pos 4U /*!< MVFR1: D_NaN mode bits Position */
+#define FPU_MVFR1_D_NaN_mode_Msk (0xFUL << FPU_MVFR1_D_NaN_mode_Pos) /*!< MVFR1: D_NaN mode bits Mask */
+
+#define FPU_MVFR1_FtZ_mode_Pos 0U /*!< MVFR1: FtZ mode bits Position */
+#define FPU_MVFR1_FtZ_mode_Msk (0xFUL /*<< FPU_MVFR1_FtZ_mode_Pos*/) /*!< MVFR1: FtZ mode bits Mask */
+
+/* Media and FP Feature Register 2 Definitions */
+
+/*@} end of group CMSIS_FPU */
+#endif
+
+
+/**
+ \ingroup CMSIS_core_register
+ \defgroup CMSIS_CoreDebug Core Debug Registers (CoreDebug)
+ \brief Type definitions for the Core Debug Registers
+ @{
+ */
+
+/**
+ \brief Structure type to access the Core Debug Register (CoreDebug).
+ */
+typedef struct
+{
+ __IOM uint32_t DHCSR; /*!< Offset: 0x000 (R/W) Debug Halting Control and Status Register */
+ __OM uint32_t DCRSR; /*!< Offset: 0x004 ( /W) Debug Core Register Selector Register */
+ __IOM uint32_t DCRDR; /*!< Offset: 0x008 (R/W) Debug Core Register Data Register */
+ __IOM uint32_t DEMCR; /*!< Offset: 0x00C (R/W) Debug Exception and Monitor Control Register */
+} CoreDebug_Type;
+
+/* Debug Halting Control and Status Register Definitions */
+#define CoreDebug_DHCSR_DBGKEY_Pos 16U /*!< CoreDebug DHCSR: DBGKEY Position */
+#define CoreDebug_DHCSR_DBGKEY_Msk (0xFFFFUL << CoreDebug_DHCSR_DBGKEY_Pos) /*!< CoreDebug DHCSR: DBGKEY Mask */
+
+#define CoreDebug_DHCSR_S_RESET_ST_Pos 25U /*!< CoreDebug DHCSR: S_RESET_ST Position */
+#define CoreDebug_DHCSR_S_RESET_ST_Msk (1UL << CoreDebug_DHCSR_S_RESET_ST_Pos) /*!< CoreDebug DHCSR: S_RESET_ST Mask */
+
+#define CoreDebug_DHCSR_S_RETIRE_ST_Pos 24U /*!< CoreDebug DHCSR: S_RETIRE_ST Position */
+#define CoreDebug_DHCSR_S_RETIRE_ST_Msk (1UL << CoreDebug_DHCSR_S_RETIRE_ST_Pos) /*!< CoreDebug DHCSR: S_RETIRE_ST Mask */
+
+#define CoreDebug_DHCSR_S_LOCKUP_Pos 19U /*!< CoreDebug DHCSR: S_LOCKUP Position */
+#define CoreDebug_DHCSR_S_LOCKUP_Msk (1UL << CoreDebug_DHCSR_S_LOCKUP_Pos) /*!< CoreDebug DHCSR: S_LOCKUP Mask */
+
+#define CoreDebug_DHCSR_S_SLEEP_Pos 18U /*!< CoreDebug DHCSR: S_SLEEP Position */
+#define CoreDebug_DHCSR_S_SLEEP_Msk (1UL << CoreDebug_DHCSR_S_SLEEP_Pos) /*!< CoreDebug DHCSR: S_SLEEP Mask */
+
+#define CoreDebug_DHCSR_S_HALT_Pos 17U /*!< CoreDebug DHCSR: S_HALT Position */
+#define CoreDebug_DHCSR_S_HALT_Msk (1UL << CoreDebug_DHCSR_S_HALT_Pos) /*!< CoreDebug DHCSR: S_HALT Mask */
+
+#define CoreDebug_DHCSR_S_REGRDY_Pos 16U /*!< CoreDebug DHCSR: S_REGRDY Position */
+#define CoreDebug_DHCSR_S_REGRDY_Msk (1UL << CoreDebug_DHCSR_S_REGRDY_Pos) /*!< CoreDebug DHCSR: S_REGRDY Mask */
+
+#define CoreDebug_DHCSR_C_SNAPSTALL_Pos 5U /*!< CoreDebug DHCSR: C_SNAPSTALL Position */
+#define CoreDebug_DHCSR_C_SNAPSTALL_Msk (1UL << CoreDebug_DHCSR_C_SNAPSTALL_Pos) /*!< CoreDebug DHCSR: C_SNAPSTALL Mask */
+
+#define CoreDebug_DHCSR_C_MASKINTS_Pos 3U /*!< CoreDebug DHCSR: C_MASKINTS Position */
+#define CoreDebug_DHCSR_C_MASKINTS_Msk (1UL << CoreDebug_DHCSR_C_MASKINTS_Pos) /*!< CoreDebug DHCSR: C_MASKINTS Mask */
+
+#define CoreDebug_DHCSR_C_STEP_Pos 2U /*!< CoreDebug DHCSR: C_STEP Position */
+#define CoreDebug_DHCSR_C_STEP_Msk (1UL << CoreDebug_DHCSR_C_STEP_Pos) /*!< CoreDebug DHCSR: C_STEP Mask */
+
+#define CoreDebug_DHCSR_C_HALT_Pos 1U /*!< CoreDebug DHCSR: C_HALT Position */
+#define CoreDebug_DHCSR_C_HALT_Msk (1UL << CoreDebug_DHCSR_C_HALT_Pos) /*!< CoreDebug DHCSR: C_HALT Mask */
+
+#define CoreDebug_DHCSR_C_DEBUGEN_Pos 0U /*!< CoreDebug DHCSR: C_DEBUGEN Position */
+#define CoreDebug_DHCSR_C_DEBUGEN_Msk (1UL /*<< CoreDebug_DHCSR_C_DEBUGEN_Pos*/) /*!< CoreDebug DHCSR: C_DEBUGEN Mask */
+
+/* Debug Core Register Selector Register Definitions */
+#define CoreDebug_DCRSR_REGWnR_Pos 16U /*!< CoreDebug DCRSR: REGWnR Position */
+#define CoreDebug_DCRSR_REGWnR_Msk (1UL << CoreDebug_DCRSR_REGWnR_Pos) /*!< CoreDebug DCRSR: REGWnR Mask */
+
+#define CoreDebug_DCRSR_REGSEL_Pos 0U /*!< CoreDebug DCRSR: REGSEL Position */
+#define CoreDebug_DCRSR_REGSEL_Msk (0x1FUL /*<< CoreDebug_DCRSR_REGSEL_Pos*/) /*!< CoreDebug DCRSR: REGSEL Mask */
+
+/* Debug Exception and Monitor Control Register Definitions */
+#define CoreDebug_DEMCR_TRCENA_Pos 24U /*!< CoreDebug DEMCR: TRCENA Position */
+#define CoreDebug_DEMCR_TRCENA_Msk (1UL << CoreDebug_DEMCR_TRCENA_Pos) /*!< CoreDebug DEMCR: TRCENA Mask */
+
+#define CoreDebug_DEMCR_MON_REQ_Pos 19U /*!< CoreDebug DEMCR: MON_REQ Position */
+#define CoreDebug_DEMCR_MON_REQ_Msk (1UL << CoreDebug_DEMCR_MON_REQ_Pos) /*!< CoreDebug DEMCR: MON_REQ Mask */
+
+#define CoreDebug_DEMCR_MON_STEP_Pos 18U /*!< CoreDebug DEMCR: MON_STEP Position */
+#define CoreDebug_DEMCR_MON_STEP_Msk (1UL << CoreDebug_DEMCR_MON_STEP_Pos) /*!< CoreDebug DEMCR: MON_STEP Mask */
+
+#define CoreDebug_DEMCR_MON_PEND_Pos 17U /*!< CoreDebug DEMCR: MON_PEND Position */
+#define CoreDebug_DEMCR_MON_PEND_Msk (1UL << CoreDebug_DEMCR_MON_PEND_Pos) /*!< CoreDebug DEMCR: MON_PEND Mask */
+
+#define CoreDebug_DEMCR_MON_EN_Pos 16U /*!< CoreDebug DEMCR: MON_EN Position */
+#define CoreDebug_DEMCR_MON_EN_Msk (1UL << CoreDebug_DEMCR_MON_EN_Pos) /*!< CoreDebug DEMCR: MON_EN Mask */
+
+#define CoreDebug_DEMCR_VC_HARDERR_Pos 10U /*!< CoreDebug DEMCR: VC_HARDERR Position */
+#define CoreDebug_DEMCR_VC_HARDERR_Msk (1UL << CoreDebug_DEMCR_VC_HARDERR_Pos) /*!< CoreDebug DEMCR: VC_HARDERR Mask */
+
+#define CoreDebug_DEMCR_VC_INTERR_Pos 9U /*!< CoreDebug DEMCR: VC_INTERR Position */
+#define CoreDebug_DEMCR_VC_INTERR_Msk (1UL << CoreDebug_DEMCR_VC_INTERR_Pos) /*!< CoreDebug DEMCR: VC_INTERR Mask */
+
+#define CoreDebug_DEMCR_VC_BUSERR_Pos 8U /*!< CoreDebug DEMCR: VC_BUSERR Position */
+#define CoreDebug_DEMCR_VC_BUSERR_Msk (1UL << CoreDebug_DEMCR_VC_BUSERR_Pos) /*!< CoreDebug DEMCR: VC_BUSERR Mask */
+
+#define CoreDebug_DEMCR_VC_STATERR_Pos 7U /*!< CoreDebug DEMCR: VC_STATERR Position */
+#define CoreDebug_DEMCR_VC_STATERR_Msk (1UL << CoreDebug_DEMCR_VC_STATERR_Pos) /*!< CoreDebug DEMCR: VC_STATERR Mask */
+
+#define CoreDebug_DEMCR_VC_CHKERR_Pos 6U /*!< CoreDebug DEMCR: VC_CHKERR Position */
+#define CoreDebug_DEMCR_VC_CHKERR_Msk (1UL << CoreDebug_DEMCR_VC_CHKERR_Pos) /*!< CoreDebug DEMCR: VC_CHKERR Mask */
+
+#define CoreDebug_DEMCR_VC_NOCPERR_Pos 5U /*!< CoreDebug DEMCR: VC_NOCPERR Position */
+#define CoreDebug_DEMCR_VC_NOCPERR_Msk (1UL << CoreDebug_DEMCR_VC_NOCPERR_Pos) /*!< CoreDebug DEMCR: VC_NOCPERR Mask */
+
+#define CoreDebug_DEMCR_VC_MMERR_Pos 4U /*!< CoreDebug DEMCR: VC_MMERR Position */
+#define CoreDebug_DEMCR_VC_MMERR_Msk (1UL << CoreDebug_DEMCR_VC_MMERR_Pos) /*!< CoreDebug DEMCR: VC_MMERR Mask */
+
+#define CoreDebug_DEMCR_VC_CORERESET_Pos 0U /*!< CoreDebug DEMCR: VC_CORERESET Position */
+#define CoreDebug_DEMCR_VC_CORERESET_Msk (1UL /*<< CoreDebug_DEMCR_VC_CORERESET_Pos*/) /*!< CoreDebug DEMCR: VC_CORERESET Mask */
+
+/*@} end of group CMSIS_CoreDebug */
+
+
+/**
+ \ingroup CMSIS_core_register
+ \defgroup CMSIS_core_bitfield Core register bit field macros
+ \brief Macros for use with bit field definitions (xxx_Pos, xxx_Msk).
+ @{
+ */
+
+/**
+ \brief Mask and shift a bit field value for use in a register bit range.
+ \param[in] field Name of the register bit field.
+ \param[in] value Value of the bit field.
+ \return Masked and shifted value.
+*/
+#define _VAL2FLD(field, value) ((value << field ## _Pos) & field ## _Msk)
+
+/**
+ \brief Mask and shift a register value to extract a bit filed value.
+ \param[in] field Name of the register bit field.
+ \param[in] value Value of register.
+ \return Masked and shifted bit field value.
+*/
+#define _FLD2VAL(field, value) ((value & field ## _Msk) >> field ## _Pos)
+
+/*@} end of group CMSIS_core_bitfield */
+
+
+/**
+ \ingroup CMSIS_core_register
+ \defgroup CMSIS_core_base Core Definitions
+ \brief Definitions for base addresses, unions, and structures.
+ @{
+ */
+
+/* Memory mapping of Cortex-M4 Hardware */
+#define SCS_BASE (0xE000E000UL) /*!< System Control Space Base Address */
+#define ITM_BASE (0xE0000000UL) /*!< ITM Base Address */
+#define DWT_BASE (0xE0001000UL) /*!< DWT Base Address */
+#define TPI_BASE (0xE0040000UL) /*!< TPI Base Address */
+#define CoreDebug_BASE (0xE000EDF0UL) /*!< Core Debug Base Address */
+#define SysTick_BASE (SCS_BASE + 0x0010UL) /*!< SysTick Base Address */
+#define NVIC_BASE (SCS_BASE + 0x0100UL) /*!< NVIC Base Address */
+#define SCB_BASE (SCS_BASE + 0x0D00UL) /*!< System Control Block Base Address */
+
+#define SCnSCB ((SCnSCB_Type *) SCS_BASE ) /*!< System control Register not in SCB */
+#define SCB ((SCB_Type *) SCB_BASE ) /*!< SCB configuration struct */
+#define SysTick ((SysTick_Type *) SysTick_BASE ) /*!< SysTick configuration struct */
+#define NVIC ((NVIC_Type *) NVIC_BASE ) /*!< NVIC configuration struct */
+#define ITM ((ITM_Type *) ITM_BASE ) /*!< ITM configuration struct */
+#define DWT ((DWT_Type *) DWT_BASE ) /*!< DWT configuration struct */
+#define TPI ((TPI_Type *) TPI_BASE ) /*!< TPI configuration struct */
+#define CoreDebug ((CoreDebug_Type *) CoreDebug_BASE) /*!< Core Debug configuration struct */
+
+#if (__MPU_PRESENT == 1U)
+ #define MPU_BASE (SCS_BASE + 0x0D90UL) /*!< Memory Protection Unit */
+ #define MPU ((MPU_Type *) MPU_BASE ) /*!< Memory Protection Unit */
+#endif
+
+#if (__FPU_PRESENT == 1U)
+ #define FPU_BASE (SCS_BASE + 0x0F30UL) /*!< Floating Point Unit */
+ #define FPU ((FPU_Type *) FPU_BASE ) /*!< Floating Point Unit */
+#endif
+
+/*@} */
+
+
+
+/*******************************************************************************
+ * Hardware Abstraction Layer
+ Core Function Interface contains:
+ - Core NVIC Functions
+ - Core SysTick Functions
+ - Core Debug Functions
+ - Core Register Access Functions
+ ******************************************************************************/
+/**
+ \defgroup CMSIS_Core_FunctionInterface Functions and Instructions Reference
+*/
+
+
+
+/* ########################## NVIC functions #################################### */
+/**
+ \ingroup CMSIS_Core_FunctionInterface
+ \defgroup CMSIS_Core_NVICFunctions NVIC Functions
+ \brief Functions that manage interrupts and exceptions via the NVIC.
+ @{
+ */
+
+/**
+ \brief Set Priority Grouping
+ \details Sets the priority grouping field using the required unlock sequence.
+ The parameter PriorityGroup is assigned to the field SCB->AIRCR [10:8] PRIGROUP field.
+ Only values from 0..7 are used.
+ In case of a conflict between priority grouping and available
+ priority bits (__NVIC_PRIO_BITS), the smallest possible priority group is set.
+ \param [in] PriorityGroup Priority grouping field.
+ */
+__STATIC_INLINE void NVIC_SetPriorityGrouping(uint32_t PriorityGroup)
+{
+ uint32_t reg_value;
+ uint32_t PriorityGroupTmp = (PriorityGroup & (uint32_t)0x07UL); /* only values 0..7 are used */
+
+ reg_value = SCB->AIRCR; /* read old register configuration */
+ reg_value &= ~((uint32_t)(SCB_AIRCR_VECTKEY_Msk | SCB_AIRCR_PRIGROUP_Msk)); /* clear bits to change */
+ reg_value = (reg_value |
+ ((uint32_t)0x5FAUL << SCB_AIRCR_VECTKEY_Pos) |
+ (PriorityGroupTmp << 8U) ); /* Insert write key and priorty group */
+ SCB->AIRCR = reg_value;
+}
+
+
+/**
+ \brief Get Priority Grouping
+ \details Reads the priority grouping field from the NVIC Interrupt Controller.
+ \return Priority grouping field (SCB->AIRCR [10:8] PRIGROUP field).
+ */
+__STATIC_INLINE uint32_t NVIC_GetPriorityGrouping(void)
+{
+ return ((uint32_t)((SCB->AIRCR & SCB_AIRCR_PRIGROUP_Msk) >> SCB_AIRCR_PRIGROUP_Pos));
+}
+
+
+/**
+ \brief Enable External Interrupt
+ \details Enables a device-specific interrupt in the NVIC interrupt controller.
+ \param [in] IRQn External interrupt number. Value cannot be negative.
+ */
+__STATIC_INLINE void NVIC_EnableIRQ(IRQn_Type IRQn)
+{
+ NVIC->ISER[(((uint32_t)(int32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL));
+}
+
+
+/**
+ \brief Disable External Interrupt
+ \details Disables a device-specific interrupt in the NVIC interrupt controller.
+ \param [in] IRQn External interrupt number. Value cannot be negative.
+ */
+__STATIC_INLINE void NVIC_DisableIRQ(IRQn_Type IRQn)
+{
+ NVIC->ICER[(((uint32_t)(int32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL));
+}
+
+
+/**
+ \brief Get Pending Interrupt
+ \details Reads the pending register in the NVIC and returns the pending bit for the specified interrupt.
+ \param [in] IRQn Interrupt number.
+ \return 0 Interrupt status is not pending.
+ \return 1 Interrupt status is pending.
+ */
+__STATIC_INLINE uint32_t NVIC_GetPendingIRQ(IRQn_Type IRQn)
+{
+ return((uint32_t)(((NVIC->ISPR[(((uint32_t)(int32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL));
+}
+
+
+/**
+ \brief Set Pending Interrupt
+ \details Sets the pending bit of an external interrupt.
+ \param [in] IRQn Interrupt number. Value cannot be negative.
+ */
+__STATIC_INLINE void NVIC_SetPendingIRQ(IRQn_Type IRQn)
+{
+ NVIC->ISPR[(((uint32_t)(int32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL));
+}
+
+
+/**
+ \brief Clear Pending Interrupt
+ \details Clears the pending bit of an external interrupt.
+ \param [in] IRQn External interrupt number. Value cannot be negative.
+ */
+__STATIC_INLINE void NVIC_ClearPendingIRQ(IRQn_Type IRQn)
+{
+ NVIC->ICPR[(((uint32_t)(int32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL));
+}
+
+
+/**
+ \brief Get Active Interrupt
+ \details Reads the active register in NVIC and returns the active bit.
+ \param [in] IRQn Interrupt number.
+ \return 0 Interrupt status is not active.
+ \return 1 Interrupt status is active.
+ */
+__STATIC_INLINE uint32_t NVIC_GetActive(IRQn_Type IRQn)
+{
+ return((uint32_t)(((NVIC->IABR[(((uint32_t)(int32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL));
+}
+
+
+/**
+ \brief Set Interrupt Priority
+ \details Sets the priority of an interrupt.
+ \note The priority cannot be set for every core interrupt.
+ \param [in] IRQn Interrupt number.
+ \param [in] priority Priority to set.
+ */
+__STATIC_INLINE void NVIC_SetPriority(IRQn_Type IRQn, uint32_t priority)
+{
+ if ((int32_t)(IRQn) < 0)
+ {
+ SCB->SHPR[(((uint32_t)(int32_t)IRQn) & 0xFUL)-4UL] = (uint8_t)((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL);
+ }
+ else
+ {
+ NVIC->IP[((uint32_t)(int32_t)IRQn)] = (uint8_t)((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL);
+ }
+}
+
+
+/**
+ \brief Get Interrupt Priority
+ \details Reads the priority of an interrupt.
+ The interrupt number can be positive to specify an external (device specific) interrupt,
+ or negative to specify an internal (core) interrupt.
+ \param [in] IRQn Interrupt number.
+ \return Interrupt Priority.
+ Value is aligned automatically to the implemented priority bits of the microcontroller.
+ */
+__STATIC_INLINE uint32_t NVIC_GetPriority(IRQn_Type IRQn)
+{
+
+ if ((int32_t)(IRQn) < 0)
+ {
+ return(((uint32_t)SCB->SHPR[(((uint32_t)(int32_t)IRQn) & 0xFUL)-4UL] >> (8U - __NVIC_PRIO_BITS)));
+ }
+ else
+ {
+ return(((uint32_t)NVIC->IP[((uint32_t)(int32_t)IRQn)] >> (8U - __NVIC_PRIO_BITS)));
+ }
+}
+
+
+/**
+ \brief Encode Priority
+ \details Encodes the priority for an interrupt with the given priority group,
+ preemptive priority value, and subpriority value.
+ In case of a conflict between priority grouping and available
+ priority bits (__NVIC_PRIO_BITS), the smallest possible priority group is set.
+ \param [in] PriorityGroup Used priority group.
+ \param [in] PreemptPriority Preemptive priority value (starting from 0).
+ \param [in] SubPriority Subpriority value (starting from 0).
+ \return Encoded priority. Value can be used in the function \ref NVIC_SetPriority().
+ */
+__STATIC_INLINE uint32_t NVIC_EncodePriority (uint32_t PriorityGroup, uint32_t PreemptPriority, uint32_t SubPriority)
+{
+ uint32_t PriorityGroupTmp = (PriorityGroup & (uint32_t)0x07UL); /* only values 0..7 are used */
+ uint32_t PreemptPriorityBits;
+ uint32_t SubPriorityBits;
+
+ PreemptPriorityBits = ((7UL - PriorityGroupTmp) > (uint32_t)(__NVIC_PRIO_BITS)) ? (uint32_t)(__NVIC_PRIO_BITS) : (uint32_t)(7UL - PriorityGroupTmp);
+ SubPriorityBits = ((PriorityGroupTmp + (uint32_t)(__NVIC_PRIO_BITS)) < (uint32_t)7UL) ? (uint32_t)0UL : (uint32_t)((PriorityGroupTmp - 7UL) + (uint32_t)(__NVIC_PRIO_BITS));
+
+ return (
+ ((PreemptPriority & (uint32_t)((1UL << (PreemptPriorityBits)) - 1UL)) << SubPriorityBits) |
+ ((SubPriority & (uint32_t)((1UL << (SubPriorityBits )) - 1UL)))
+ );
+}
+
+
+/**
+ \brief Decode Priority
+ \details Decodes an interrupt priority value with a given priority group to
+ preemptive priority value and subpriority value.
+ In case of a conflict between priority grouping and available
+ priority bits (__NVIC_PRIO_BITS) the smallest possible priority group is set.
+ \param [in] Priority Priority value, which can be retrieved with the function \ref NVIC_GetPriority().
+ \param [in] PriorityGroup Used priority group.
+ \param [out] pPreemptPriority Preemptive priority value (starting from 0).
+ \param [out] pSubPriority Subpriority value (starting from 0).
+ */
+__STATIC_INLINE void NVIC_DecodePriority (uint32_t Priority, uint32_t PriorityGroup, uint32_t* const pPreemptPriority, uint32_t* const pSubPriority)
+{
+ uint32_t PriorityGroupTmp = (PriorityGroup & (uint32_t)0x07UL); /* only values 0..7 are used */
+ uint32_t PreemptPriorityBits;
+ uint32_t SubPriorityBits;
+
+ PreemptPriorityBits = ((7UL - PriorityGroupTmp) > (uint32_t)(__NVIC_PRIO_BITS)) ? (uint32_t)(__NVIC_PRIO_BITS) : (uint32_t)(7UL - PriorityGroupTmp);
+ SubPriorityBits = ((PriorityGroupTmp + (uint32_t)(__NVIC_PRIO_BITS)) < (uint32_t)7UL) ? (uint32_t)0UL : (uint32_t)((PriorityGroupTmp - 7UL) + (uint32_t)(__NVIC_PRIO_BITS));
+
+ *pPreemptPriority = (Priority >> SubPriorityBits) & (uint32_t)((1UL << (PreemptPriorityBits)) - 1UL);
+ *pSubPriority = (Priority ) & (uint32_t)((1UL << (SubPriorityBits )) - 1UL);
+}
+
+
+/**
+ \brief System Reset
+ \details Initiates a system reset request to reset the MCU.
+ */
+__STATIC_INLINE void NVIC_SystemReset(void)
+{
+ __DSB(); /* Ensure all outstanding memory accesses included
+ buffered write are completed before reset */
+ SCB->AIRCR = (uint32_t)((0x5FAUL << SCB_AIRCR_VECTKEY_Pos) |
+ (SCB->AIRCR & SCB_AIRCR_PRIGROUP_Msk) |
+ SCB_AIRCR_SYSRESETREQ_Msk ); /* Keep priority group unchanged */
+ __DSB(); /* Ensure completion of memory access */
+
+ for (;;) /* wait until reset */
+ {
+ __NOP();
+ }
+}
+
+/*@} end of CMSIS_Core_NVICFunctions */
+
+
+/* ########################## FPU functions #################################### */
+/**
+ \ingroup CMSIS_Core_FunctionInterface
+ \defgroup CMSIS_Core_FpuFunctions FPU Functions
+ \brief Function that provides FPU type.
+ @{
+ */
+
+/**
+ \brief get FPU type
+ \details returns the FPU type
+ \returns
+ - \b 0: No FPU
+ - \b 1: Single precision FPU
+ - \b 2: Double + Single precision FPU
+ */
+__STATIC_INLINE uint32_t SCB_GetFPUType(void)
+{
+ uint32_t mvfr0;
+
+ mvfr0 = SCB->MVFR0;
+ if ((mvfr0 & 0x00000FF0UL) == 0x220UL)
+ {
+ return 2UL; /* Double + Single precision FPU */
+ }
+ else if ((mvfr0 & 0x00000FF0UL) == 0x020UL)
+ {
+ return 1UL; /* Single precision FPU */
+ }
+ else
+ {
+ return 0UL; /* No FPU */
+ }
+}
+
+
+/*@} end of CMSIS_Core_FpuFunctions */
+
+
+
+/* ########################## Cache functions #################################### */
+/**
+ \ingroup CMSIS_Core_FunctionInterface
+ \defgroup CMSIS_Core_CacheFunctions Cache Functions
+ \brief Functions that configure Instruction and Data cache.
+ @{
+ */
+
+/* Cache Size ID Register Macros */
+#define CCSIDR_WAYS(x) (((x) & SCB_CCSIDR_ASSOCIATIVITY_Msk) >> SCB_CCSIDR_ASSOCIATIVITY_Pos)
+#define CCSIDR_SETS(x) (((x) & SCB_CCSIDR_NUMSETS_Msk ) >> SCB_CCSIDR_NUMSETS_Pos )
+
+
+/**
+ \brief Enable I-Cache
+ \details Turns on I-Cache
+ */
+__STATIC_INLINE void SCB_EnableICache (void)
+{
+ #if (__ICACHE_PRESENT == 1U)
+ __DSB();
+ __ISB();
+ SCB->ICIALLU = 0UL; /* invalidate I-Cache */
+ SCB->CCR |= (uint32_t)SCB_CCR_IC_Msk; /* enable I-Cache */
+ __DSB();
+ __ISB();
+ #endif
+}
+
+
+/**
+ \brief Disable I-Cache
+ \details Turns off I-Cache
+ */
+__STATIC_INLINE void SCB_DisableICache (void)
+{
+ #if (__ICACHE_PRESENT == 1U)
+ __DSB();
+ __ISB();
+ SCB->CCR &= ~(uint32_t)SCB_CCR_IC_Msk; /* disable I-Cache */
+ SCB->ICIALLU = 0UL; /* invalidate I-Cache */
+ __DSB();
+ __ISB();
+ #endif
+}
+
+
+/**
+ \brief Invalidate I-Cache
+ \details Invalidates I-Cache
+ */
+__STATIC_INLINE void SCB_InvalidateICache (void)
+{
+ #if (__ICACHE_PRESENT == 1U)
+ __DSB();
+ __ISB();
+ SCB->ICIALLU = 0UL;
+ __DSB();
+ __ISB();
+ #endif
+}
+
+
+/**
+ \brief Enable D-Cache
+ \details Turns on D-Cache
+ */
+__STATIC_INLINE void SCB_EnableDCache (void)
+{
+ #if (__DCACHE_PRESENT == 1U)
+ uint32_t ccsidr;
+ uint32_t sets;
+ uint32_t ways;
+
+ SCB->CSSELR = (0U << 1U) | 0U; /* Level 1 data cache */
+ __DSB();
+
+ ccsidr = SCB->CCSIDR;
+
+ /* invalidate D-Cache */
+ sets = (uint32_t)(CCSIDR_SETS(ccsidr));
+ do {
+ ways = (uint32_t)(CCSIDR_WAYS(ccsidr));
+ do {
+ SCB->DCISW = (((sets << SCB_DCISW_SET_Pos) & SCB_DCISW_SET_Msk) |
+ ((ways << SCB_DCISW_WAY_Pos) & SCB_DCISW_WAY_Msk) );
+ #if defined ( __CC_ARM )
+ __schedule_barrier();
+ #endif
+ } while (ways--);
+ } while (sets--);
+ __DSB();
+
+ SCB->CCR |= (uint32_t)SCB_CCR_DC_Msk; /* enable D-Cache */
+
+ __DSB();
+ __ISB();
+ #endif
+}
+
+
+/**
+ \brief Disable D-Cache
+ \details Turns off D-Cache
+ */
+__STATIC_INLINE void SCB_DisableDCache (void)
+{
+ #if (__DCACHE_PRESENT == 1U)
+ uint32_t ccsidr;
+ uint32_t sets;
+ uint32_t ways;
+
+ SCB->CSSELR = (0U << 1U) | 0U; /* Level 1 data cache */
+ __DSB();
+
+ ccsidr = SCB->CCSIDR;
+
+ SCB->CCR &= ~(uint32_t)SCB_CCR_DC_Msk; /* disable D-Cache */
+
+ /* clean & invalidate D-Cache */
+ sets = (uint32_t)(CCSIDR_SETS(ccsidr));
+ do {
+ ways = (uint32_t)(CCSIDR_WAYS(ccsidr));
+ do {
+ SCB->DCCISW = (((sets << SCB_DCCISW_SET_Pos) & SCB_DCCISW_SET_Msk) |
+ ((ways << SCB_DCCISW_WAY_Pos) & SCB_DCCISW_WAY_Msk) );
+ #if defined ( __CC_ARM )
+ __schedule_barrier();
+ #endif
+ } while (ways--);
+ } while (sets--);
+
+ __DSB();
+ __ISB();
+ #endif
+}
+
+
+/**
+ \brief Invalidate D-Cache
+ \details Invalidates D-Cache
+ */
+__STATIC_INLINE void SCB_InvalidateDCache (void)
+{
+ #if (__DCACHE_PRESENT == 1U)
+ uint32_t ccsidr;
+ uint32_t sets;
+ uint32_t ways;
+
+ SCB->CSSELR = (0U << 1U) | 0U; /* Level 1 data cache */
+ __DSB();
+
+ ccsidr = SCB->CCSIDR;
+
+ /* invalidate D-Cache */
+ sets = (uint32_t)(CCSIDR_SETS(ccsidr));
+ do {
+ ways = (uint32_t)(CCSIDR_WAYS(ccsidr));
+ do {
+ SCB->DCISW = (((sets << SCB_DCISW_SET_Pos) & SCB_DCISW_SET_Msk) |
+ ((ways << SCB_DCISW_WAY_Pos) & SCB_DCISW_WAY_Msk) );
+ #if defined ( __CC_ARM )
+ __schedule_barrier();
+ #endif
+ } while (ways--);
+ } while (sets--);
+
+ __DSB();
+ __ISB();
+ #endif
+}
+
+
+/**
+ \brief Clean D-Cache
+ \details Cleans D-Cache
+ */
+__STATIC_INLINE void SCB_CleanDCache (void)
+{
+ #if (__DCACHE_PRESENT == 1U)
+ uint32_t ccsidr;
+ uint32_t sets;
+ uint32_t ways;
+
+ SCB->CSSELR = (0U << 1U) | 0U; /* Level 1 data cache */
+ __DSB();
+
+ ccsidr = SCB->CCSIDR;
+
+ /* clean D-Cache */
+ sets = (uint32_t)(CCSIDR_SETS(ccsidr));
+ do {
+ ways = (uint32_t)(CCSIDR_WAYS(ccsidr));
+ do {
+ SCB->DCCSW = (((sets << SCB_DCCSW_SET_Pos) & SCB_DCCSW_SET_Msk) |
+ ((ways << SCB_DCCSW_WAY_Pos) & SCB_DCCSW_WAY_Msk) );
+ #if defined ( __CC_ARM )
+ __schedule_barrier();
+ #endif
+ } while (ways--);
+ } while (sets--);
+
+ __DSB();
+ __ISB();
+ #endif
+}
+
+
+/**
+ \brief Clean & Invalidate D-Cache
+ \details Cleans and Invalidates D-Cache
+ */
+__STATIC_INLINE void SCB_CleanInvalidateDCache (void)
+{
+ #if (__DCACHE_PRESENT == 1U)
+ uint32_t ccsidr;
+ uint32_t sets;
+ uint32_t ways;
+
+ SCB->CSSELR = (0U << 1U) | 0U; /* Level 1 data cache */
+ __DSB();
+
+ ccsidr = SCB->CCSIDR;
+
+ /* clean & invalidate D-Cache */
+ sets = (uint32_t)(CCSIDR_SETS(ccsidr));
+ do {
+ ways = (uint32_t)(CCSIDR_WAYS(ccsidr));
+ do {
+ SCB->DCCISW = (((sets << SCB_DCCISW_SET_Pos) & SCB_DCCISW_SET_Msk) |
+ ((ways << SCB_DCCISW_WAY_Pos) & SCB_DCCISW_WAY_Msk) );
+ #if defined ( __CC_ARM )
+ __schedule_barrier();
+ #endif
+ } while (ways--);
+ } while (sets--);
+
+ __DSB();
+ __ISB();
+ #endif
+}
+
+
+/**
+ \brief D-Cache Invalidate by address
+ \details Invalidates D-Cache for the given address
+ \param[in] addr address (aligned to 32-byte boundary)
+ \param[in] dsize size of memory block (in number of bytes)
+*/
+__STATIC_INLINE void SCB_InvalidateDCache_by_Addr (uint32_t *addr, int32_t dsize)
+{
+ #if (__DCACHE_PRESENT == 1U)
+ int32_t op_size = dsize;
+ uint32_t op_addr = (uint32_t)addr;
+ int32_t linesize = 32U; /* in Cortex-M7 size of cache line is fixed to 8 words (32 bytes) */
+
+ __DSB();
+
+ while (op_size > 0) {
+ SCB->DCIMVAC = op_addr;
+ op_addr += linesize;
+ op_size -= linesize;
+ }
+
+ __DSB();
+ __ISB();
+ #endif
+}
+
+
+/**
+ \brief D-Cache Clean by address
+ \details Cleans D-Cache for the given address
+ \param[in] addr address (aligned to 32-byte boundary)
+ \param[in] dsize size of memory block (in number of bytes)
+*/
+__STATIC_INLINE void SCB_CleanDCache_by_Addr (uint32_t *addr, int32_t dsize)
+{
+ #if (__DCACHE_PRESENT == 1)
+ int32_t op_size = dsize;
+ uint32_t op_addr = (uint32_t) addr;
+ int32_t linesize = 32U; /* in Cortex-M7 size of cache line is fixed to 8 words (32 bytes) */
+
+ __DSB();
+
+ while (op_size > 0) {
+ SCB->DCCMVAC = op_addr;
+ op_addr += linesize;
+ op_size -= linesize;
+ }
+
+ __DSB();
+ __ISB();
+ #endif
+}
+
+
+/**
+ \brief D-Cache Clean and Invalidate by address
+ \details Cleans and invalidates D_Cache for the given address
+ \param[in] addr address (aligned to 32-byte boundary)
+ \param[in] dsize size of memory block (in number of bytes)
+*/
+__STATIC_INLINE void SCB_CleanInvalidateDCache_by_Addr (uint32_t *addr, int32_t dsize)
+{
+ #if (__DCACHE_PRESENT == 1U)
+ int32_t op_size = dsize;
+ uint32_t op_addr = (uint32_t) addr;
+ int32_t linesize = 32U; /* in Cortex-M7 size of cache line is fixed to 8 words (32 bytes) */
+
+ __DSB();
+
+ while (op_size > 0) {
+ SCB->DCCIMVAC = op_addr;
+ op_addr += linesize;
+ op_size -= linesize;
+ }
+
+ __DSB();
+ __ISB();
+ #endif
+}
+
+
+/*@} end of CMSIS_Core_CacheFunctions */
+
+
+
+/* ################################## SysTick function ############################################ */
+/**
+ \ingroup CMSIS_Core_FunctionInterface
+ \defgroup CMSIS_Core_SysTickFunctions SysTick Functions
+ \brief Functions that configure the System.
+ @{
+ */
+
+#if (__Vendor_SysTickConfig == 0U)
+
+/**
+ \brief System Tick Configuration
+ \details Initializes the System Timer and its interrupt, and starts the System Tick Timer.
+ Counter is in free running mode to generate periodic interrupts.
+ \param [in] ticks Number of ticks between two interrupts.
+ \return 0 Function succeeded.
+ \return 1 Function failed.
+ \note When the variable <b>__Vendor_SysTickConfig</b> is set to 1, then the
+ function <b>SysTick_Config</b> is not included. In this case, the file <b><i>device</i>.h</b>
+ must contain a vendor-specific implementation of this function.
+ */
+__STATIC_INLINE uint32_t SysTick_Config(uint32_t ticks)
+{
+ if ((ticks - 1UL) > SysTick_LOAD_RELOAD_Msk)
+ {
+ return (1UL); /* Reload value impossible */
+ }
+
+ SysTick->LOAD = (uint32_t)(ticks - 1UL); /* set reload register */
+ NVIC_SetPriority (SysTick_IRQn, (1UL << __NVIC_PRIO_BITS) - 1UL); /* set Priority for Systick Interrupt */
+ SysTick->VAL = 0UL; /* Load the SysTick Counter Value */
+ SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk |
+ SysTick_CTRL_TICKINT_Msk |
+ SysTick_CTRL_ENABLE_Msk; /* Enable SysTick IRQ and SysTick Timer */
+ return (0UL); /* Function successful */
+}
+
+#endif
+
+/*@} end of CMSIS_Core_SysTickFunctions */
+
+
+
+/* ##################################### Debug In/Output function ########################################### */
+/**
+ \ingroup CMSIS_Core_FunctionInterface
+ \defgroup CMSIS_core_DebugFunctions ITM Functions
+ \brief Functions that access the ITM debug interface.
+ @{
+ */
+
+extern volatile int32_t ITM_RxBuffer; /*!< External variable to receive characters. */
+#define ITM_RXBUFFER_EMPTY 0x5AA55AA5U /*!< Value identifying \ref ITM_RxBuffer is ready for next character. */
+
+
+/**
+ \brief ITM Send Character
+ \details Transmits a character via the ITM channel 0, and
+ \li Just returns when no debugger is connected that has booked the output.
+ \li Is blocking when a debugger is connected, but the previous character sent has not been transmitted.
+ \param [in] ch Character to transmit.
+ \returns Character to transmit.
+ */
+__STATIC_INLINE uint32_t ITM_SendChar (uint32_t ch)
+{
+ if (((ITM->TCR & ITM_TCR_ITMENA_Msk) != 0UL) && /* ITM enabled */
+ ((ITM->TER & 1UL ) != 0UL) ) /* ITM Port #0 enabled */
+ {
+ while (ITM->PORT[0U].u32 == 0UL)
+ {
+ __NOP();
+ }
+ ITM->PORT[0U].u8 = (uint8_t)ch;
+ }
+ return (ch);
+}
+
+
+/**
+ \brief ITM Receive Character
+ \details Inputs a character via the external variable \ref ITM_RxBuffer.
+ \return Received character.
+ \return -1 No character pending.
+ */
+__STATIC_INLINE int32_t ITM_ReceiveChar (void)
+{
+ int32_t ch = -1; /* no character available */
+
+ if (ITM_RxBuffer != ITM_RXBUFFER_EMPTY)
+ {
+ ch = ITM_RxBuffer;
+ ITM_RxBuffer = ITM_RXBUFFER_EMPTY; /* ready for next character */
+ }
+
+ return (ch);
+}
+
+
+/**
+ \brief ITM Check Character
+ \details Checks whether a character is pending for reading in the variable \ref ITM_RxBuffer.
+ \return 0 No character available.
+ \return 1 Character available.
+ */
+__STATIC_INLINE int32_t ITM_CheckChar (void)
+{
+
+ if (ITM_RxBuffer == ITM_RXBUFFER_EMPTY)
+ {
+ return (0); /* no character available */
+ }
+ else
+ {
+ return (1); /* character available */
+ }
+}
+
+/*@} end of CMSIS_core_DebugFunctions */
+
+
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __CORE_CM7_H_DEPENDANT */
+
+#endif /* __CMSIS_GENERIC */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/toolchain/cmsis/include/core_cmFunc.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/toolchain/cmsis/include/core_cmFunc.h
new file mode 100644
index 0000000..979696f
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/toolchain/cmsis/include/core_cmFunc.h
@@ -0,0 +1,86 @@
+/**************************************************************************//**
+ * @file core_cmFunc.h
+ * @brief CMSIS Cortex-M Core Function Access Header File
+ * @version V4.30
+ * @date 20. October 2015
+ ******************************************************************************/
+/* Copyright (c) 2009 - 2015 ARM LIMITED
+
+ All rights reserved.
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are met:
+ - Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ - 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.
+ - Neither the name of ARM 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 COPYRIGHT HOLDERS AND 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.
+ ---------------------------------------------------------------------------*/
+
+#if defined ( __ICCARM__ )
+ #pragma system_include /* treat file as system include file for MISRA check */
+#elif defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050)
+ #pragma clang system_header /* treat file as system include file */
+#endif
+
+#ifndef __CORE_CMFUNC_H
+#define __CORE_CMFUNC_H
+
+
+/* ########################### Core Function Access ########################### */
+/** \ingroup CMSIS_Core_FunctionInterface
+ \defgroup CMSIS_Core_RegAccFunctions CMSIS Core Register Access Functions
+ @{
+*/
+
+/*------------------ RealView Compiler -----------------*/
+#if defined ( __CC_ARM )
+ #include "cmsis_armcc.h"
+
+/*------------------ ARM Compiler V6 -------------------*/
+#elif defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050)
+ #include "cmsis_armcc_V6.h"
+
+/*------------------ GNU Compiler ----------------------*/
+#elif defined ( __GNUC__ )
+ #include "cmsis_gcc.h"
+
+/*------------------ ICC Compiler ----------------------*/
+#elif defined ( __ICCARM__ )
+ #include <cmsis_iar.h>
+
+/*------------------ TI CCS Compiler -------------------*/
+#elif defined ( __TMS470__ )
+ #include <cmsis_ccs.h>
+
+/*------------------ TASKING Compiler ------------------*/
+#elif defined ( __TASKING__ )
+ /*
+ * The CMSIS functions have been implemented as intrinsics in the compiler.
+ * Please use "carm -?i" to get an up to date list of all intrinsics,
+ * Including the CMSIS ones.
+ */
+
+/*------------------ COSMIC Compiler -------------------*/
+#elif defined ( __CSMC__ )
+ #include <cmsis_csm.h>
+
+#endif
+
+/*@} end of CMSIS_Core_RegAccFunctions */
+
+#endif /* __CORE_CMFUNC_H */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/toolchain/cmsis/include/core_cmInstr.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/toolchain/cmsis/include/core_cmInstr.h
new file mode 100644
index 0000000..f474b0e
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/toolchain/cmsis/include/core_cmInstr.h
@@ -0,0 +1,87 @@
+/**************************************************************************//**
+ * @file core_cmInstr.h
+ * @brief CMSIS Cortex-M Core Instruction Access Header File
+ * @version V4.30
+ * @date 20. October 2015
+ ******************************************************************************/
+/* Copyright (c) 2009 - 2015 ARM LIMITED
+
+ All rights reserved.
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are met:
+ - Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ - 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.
+ - Neither the name of ARM 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 COPYRIGHT HOLDERS AND 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.
+ ---------------------------------------------------------------------------*/
+
+
+#if defined ( __ICCARM__ )
+ #pragma system_include /* treat file as system include file for MISRA check */
+#elif defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050)
+ #pragma clang system_header /* treat file as system include file */
+#endif
+
+#ifndef __CORE_CMINSTR_H
+#define __CORE_CMINSTR_H
+
+
+/* ########################## Core Instruction Access ######################### */
+/** \defgroup CMSIS_Core_InstructionInterface CMSIS Core Instruction Interface
+ Access to dedicated instructions
+ @{
+*/
+
+/*------------------ RealView Compiler -----------------*/
+#if defined ( __CC_ARM )
+ #include "cmsis_armcc.h"
+
+/*------------------ ARM Compiler V6 -------------------*/
+#elif defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050)
+ #include "cmsis_armcc_V6.h"
+
+/*------------------ GNU Compiler ----------------------*/
+#elif defined ( __GNUC__ )
+ #include "cmsis_gcc.h"
+
+/*------------------ ICC Compiler ----------------------*/
+#elif defined ( __ICCARM__ )
+ #include <cmsis_iar.h>
+
+/*------------------ TI CCS Compiler -------------------*/
+#elif defined ( __TMS470__ )
+ #include <cmsis_ccs.h>
+
+/*------------------ TASKING Compiler ------------------*/
+#elif defined ( __TASKING__ )
+ /*
+ * The CMSIS functions have been implemented as intrinsics in the compiler.
+ * Please use "carm -?i" to get an up to date list of all intrinsics,
+ * Including the CMSIS ones.
+ */
+
+/*------------------ COSMIC Compiler -------------------*/
+#elif defined ( __CSMC__ )
+ #include <cmsis_csm.h>
+
+#endif
+
+/*@}*/ /* end of group CMSIS_Core_InstructionInterface */
+
+#endif /* __CORE_CMINSTR_H */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/toolchain/cmsis/include/core_cmSimd.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/toolchain/cmsis/include/core_cmSimd.h
new file mode 100644
index 0000000..66bf5c2
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/toolchain/cmsis/include/core_cmSimd.h
@@ -0,0 +1,96 @@
+/**************************************************************************//**
+ * @file core_cmSimd.h
+ * @brief CMSIS Cortex-M SIMD Header File
+ * @version V4.30
+ * @date 20. October 2015
+ ******************************************************************************/
+/* Copyright (c) 2009 - 2015 ARM LIMITED
+
+ All rights reserved.
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are met:
+ - Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ - 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.
+ - Neither the name of ARM 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 COPYRIGHT HOLDERS AND 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.
+ ---------------------------------------------------------------------------*/
+
+
+#if defined ( __ICCARM__ )
+ #pragma system_include /* treat file as system include file for MISRA check */
+#elif defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050)
+ #pragma clang system_header /* treat file as system include file */
+#endif
+
+#ifndef __CORE_CMSIMD_H
+#define __CORE_CMSIMD_H
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+
+/* ################### Compiler specific Intrinsics ########################### */
+/** \defgroup CMSIS_SIMD_intrinsics CMSIS SIMD Intrinsics
+ Access to dedicated SIMD instructions
+ @{
+*/
+
+/*------------------ RealView Compiler -----------------*/
+#if defined ( __CC_ARM )
+ #include "cmsis_armcc.h"
+
+/*------------------ ARM Compiler V6 -------------------*/
+#elif defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050)
+ #include "cmsis_armcc_V6.h"
+
+/*------------------ GNU Compiler ----------------------*/
+#elif defined ( __GNUC__ )
+ #include "cmsis_gcc.h"
+
+/*------------------ ICC Compiler ----------------------*/
+#elif defined ( __ICCARM__ )
+ #include <cmsis_iar.h>
+
+/*------------------ TI CCS Compiler -------------------*/
+#elif defined ( __TMS470__ )
+ #include <cmsis_ccs.h>
+
+/*------------------ TASKING Compiler ------------------*/
+#elif defined ( __TASKING__ )
+ /*
+ * The CMSIS functions have been implemented as intrinsics in the compiler.
+ * Please use "carm -?i" to get an up to date list of all intrinsics,
+ * Including the CMSIS ones.
+ */
+
+/*------------------ COSMIC Compiler -------------------*/
+#elif defined ( __CSMC__ )
+ #include <cmsis_csm.h>
+
+#endif
+
+/*@} end of group CMSIS_SIMD_intrinsics */
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __CORE_CMSIMD_H */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/toolchain/cmsis/include/core_sc000.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/toolchain/cmsis/include/core_sc000.h
new file mode 100644
index 0000000..44db659
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/toolchain/cmsis/include/core_sc000.h
@@ -0,0 +1,926 @@
+/**************************************************************************//**
+ * @file core_sc000.h
+ * @brief CMSIS SC000 Core Peripheral Access Layer Header File
+ * @version V4.30
+ * @date 20. October 2015
+ ******************************************************************************/
+/* Copyright (c) 2009 - 2015 ARM LIMITED
+
+ All rights reserved.
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are met:
+ - Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ - 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.
+ - Neither the name of ARM 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 COPYRIGHT HOLDERS AND 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.
+ ---------------------------------------------------------------------------*/
+
+
+#if defined ( __ICCARM__ )
+ #pragma system_include /* treat file as system include file for MISRA check */
+#elif defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050)
+ #pragma clang system_header /* treat file as system include file */
+#endif
+
+#ifndef __CORE_SC000_H_GENERIC
+#define __CORE_SC000_H_GENERIC
+
+#include <stdint.h>
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+/**
+ \page CMSIS_MISRA_Exceptions MISRA-C:2004 Compliance Exceptions
+ CMSIS violates the following MISRA-C:2004 rules:
+
+ \li Required Rule 8.5, object/function definition in header file.<br>
+ Function definitions in header files are used to allow 'inlining'.
+
+ \li Required Rule 18.4, declaration of union type or object of union type: '{...}'.<br>
+ Unions are used for effective representation of core registers.
+
+ \li Advisory Rule 19.7, Function-like macro defined.<br>
+ Function-like macros are used to allow more efficient code.
+ */
+
+
+/*******************************************************************************
+ * CMSIS definitions
+ ******************************************************************************/
+/**
+ \ingroup SC000
+ @{
+ */
+
+/* CMSIS SC000 definitions */
+#define __SC000_CMSIS_VERSION_MAIN (0x04U) /*!< [31:16] CMSIS HAL main version */
+#define __SC000_CMSIS_VERSION_SUB (0x1EU) /*!< [15:0] CMSIS HAL sub version */
+#define __SC000_CMSIS_VERSION ((__SC000_CMSIS_VERSION_MAIN << 16U) | \
+ __SC000_CMSIS_VERSION_SUB ) /*!< CMSIS HAL version number */
+
+#define __CORTEX_SC (000U) /*!< Cortex secure core */
+
+
+#if defined ( __CC_ARM )
+ #define __ASM __asm /*!< asm keyword for ARM Compiler */
+ #define __INLINE __inline /*!< inline keyword for ARM Compiler */
+ #define __STATIC_INLINE static __inline
+
+#elif defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050)
+ #define __ASM __asm /*!< asm keyword for ARM Compiler */
+ #define __INLINE __inline /*!< inline keyword for ARM Compiler */
+ #define __STATIC_INLINE static __inline
+
+#elif defined ( __GNUC__ )
+ #define __ASM __asm /*!< asm keyword for GNU Compiler */
+ #define __INLINE inline /*!< inline keyword for GNU Compiler */
+ #define __STATIC_INLINE static inline
+
+#elif defined ( __ICCARM__ )
+ #define __ASM __asm /*!< asm keyword for IAR Compiler */
+ #define __INLINE inline /*!< inline keyword for IAR Compiler. Only available in High optimization mode! */
+ #define __STATIC_INLINE static inline
+
+#elif defined ( __TMS470__ )
+ #define __ASM __asm /*!< asm keyword for TI CCS Compiler */
+ #define __STATIC_INLINE static inline
+
+#elif defined ( __TASKING__ )
+ #define __ASM __asm /*!< asm keyword for TASKING Compiler */
+ #define __INLINE inline /*!< inline keyword for TASKING Compiler */
+ #define __STATIC_INLINE static inline
+
+#elif defined ( __CSMC__ )
+ #define __packed
+ #define __ASM _asm /*!< asm keyword for COSMIC Compiler */
+ #define __INLINE inline /*!< inline keyword for COSMIC Compiler. Use -pc99 on compile line */
+ #define __STATIC_INLINE static inline
+
+#else
+ #error Unknown compiler
+#endif
+
+/** __FPU_USED indicates whether an FPU is used or not.
+ This core does not support an FPU at all
+*/
+#define __FPU_USED 0U
+
+#if defined ( __CC_ARM )
+ #if defined __TARGET_FPU_VFP
+ #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
+ #endif
+
+#elif defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050)
+ #if defined __ARM_PCS_VFP
+ #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
+ #endif
+
+#elif defined ( __GNUC__ )
+ #if defined (__VFP_FP__) && !defined(__SOFTFP__)
+ #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
+ #endif
+
+#elif defined ( __ICCARM__ )
+ #if defined __ARMVFP__
+ #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
+ #endif
+
+#elif defined ( __TMS470__ )
+ #if defined __TI_VFP_SUPPORT__
+ #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
+ #endif
+
+#elif defined ( __TASKING__ )
+ #if defined __FPU_VFP__
+ #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
+ #endif
+
+#elif defined ( __CSMC__ )
+ #if ( __CSMC__ & 0x400U)
+ #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
+ #endif
+
+#endif
+
+#include "core_cmInstr.h" /* Core Instruction Access */
+#include "core_cmFunc.h" /* Core Function Access */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __CORE_SC000_H_GENERIC */
+
+#ifndef __CMSIS_GENERIC
+
+#ifndef __CORE_SC000_H_DEPENDANT
+#define __CORE_SC000_H_DEPENDANT
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+/* check device defines and use defaults */
+#if defined __CHECK_DEVICE_DEFINES
+ #ifndef __SC000_REV
+ #define __SC000_REV 0x0000U
+ #warning "__SC000_REV not defined in device header file; using default!"
+ #endif
+
+ #ifndef __MPU_PRESENT
+ #define __MPU_PRESENT 0U
+ #warning "__MPU_PRESENT not defined in device header file; using default!"
+ #endif
+
+ #ifndef __NVIC_PRIO_BITS
+ #define __NVIC_PRIO_BITS 2U
+ #warning "__NVIC_PRIO_BITS not defined in device header file; using default!"
+ #endif
+
+ #ifndef __Vendor_SysTickConfig
+ #define __Vendor_SysTickConfig 0U
+ #warning "__Vendor_SysTickConfig not defined in device header file; using default!"
+ #endif
+#endif
+
+/* IO definitions (access restrictions to peripheral registers) */
+/**
+ \defgroup CMSIS_glob_defs CMSIS Global Defines
+
+ <strong>IO Type Qualifiers</strong> are used
+ \li to specify the access to peripheral variables.
+ \li for automatic generation of peripheral register debug information.
+*/
+#ifdef __cplusplus
+ #define __I volatile /*!< Defines 'read only' permissions */
+#else
+ #define __I volatile const /*!< Defines 'read only' permissions */
+#endif
+#define __O volatile /*!< Defines 'write only' permissions */
+#define __IO volatile /*!< Defines 'read / write' permissions */
+
+/* following defines should be used for structure members */
+#define __IM volatile const /*! Defines 'read only' structure member permissions */
+#define __OM volatile /*! Defines 'write only' structure member permissions */
+#define __IOM volatile /*! Defines 'read / write' structure member permissions */
+
+/*@} end of group SC000 */
+
+
+
+/*******************************************************************************
+ * Register Abstraction
+ Core Register contain:
+ - Core Register
+ - Core NVIC Register
+ - Core SCB Register
+ - Core SysTick Register
+ - Core MPU Register
+ ******************************************************************************/
+/**
+ \defgroup CMSIS_core_register Defines and Type Definitions
+ \brief Type definitions and defines for Cortex-M processor based devices.
+*/
+
+/**
+ \ingroup CMSIS_core_register
+ \defgroup CMSIS_CORE Status and Control Registers
+ \brief Core Register type definitions.
+ @{
+ */
+
+/**
+ \brief Union type to access the Application Program Status Register (APSR).
+ */
+typedef union
+{
+ struct
+ {
+ uint32_t _reserved0:28; /*!< bit: 0..27 Reserved */
+ uint32_t V:1; /*!< bit: 28 Overflow condition code flag */
+ uint32_t C:1; /*!< bit: 29 Carry condition code flag */
+ uint32_t Z:1; /*!< bit: 30 Zero condition code flag */
+ uint32_t N:1; /*!< bit: 31 Negative condition code flag */
+ } b; /*!< Structure used for bit access */
+ uint32_t w; /*!< Type used for word access */
+} APSR_Type;
+
+/* APSR Register Definitions */
+#define APSR_N_Pos 31U /*!< APSR: N Position */
+#define APSR_N_Msk (1UL << APSR_N_Pos) /*!< APSR: N Mask */
+
+#define APSR_Z_Pos 30U /*!< APSR: Z Position */
+#define APSR_Z_Msk (1UL << APSR_Z_Pos) /*!< APSR: Z Mask */
+
+#define APSR_C_Pos 29U /*!< APSR: C Position */
+#define APSR_C_Msk (1UL << APSR_C_Pos) /*!< APSR: C Mask */
+
+#define APSR_V_Pos 28U /*!< APSR: V Position */
+#define APSR_V_Msk (1UL << APSR_V_Pos) /*!< APSR: V Mask */
+
+
+/**
+ \brief Union type to access the Interrupt Program Status Register (IPSR).
+ */
+typedef union
+{
+ struct
+ {
+ uint32_t ISR:9; /*!< bit: 0.. 8 Exception number */
+ uint32_t _reserved0:23; /*!< bit: 9..31 Reserved */
+ } b; /*!< Structure used for bit access */
+ uint32_t w; /*!< Type used for word access */
+} IPSR_Type;
+
+/* IPSR Register Definitions */
+#define IPSR_ISR_Pos 0U /*!< IPSR: ISR Position */
+#define IPSR_ISR_Msk (0x1FFUL /*<< IPSR_ISR_Pos*/) /*!< IPSR: ISR Mask */
+
+
+/**
+ \brief Union type to access the Special-Purpose Program Status Registers (xPSR).
+ */
+typedef union
+{
+ struct
+ {
+ uint32_t ISR:9; /*!< bit: 0.. 8 Exception number */
+ uint32_t _reserved0:15; /*!< bit: 9..23 Reserved */
+ uint32_t T:1; /*!< bit: 24 Thumb bit (read 0) */
+ uint32_t _reserved1:3; /*!< bit: 25..27 Reserved */
+ uint32_t V:1; /*!< bit: 28 Overflow condition code flag */
+ uint32_t C:1; /*!< bit: 29 Carry condition code flag */
+ uint32_t Z:1; /*!< bit: 30 Zero condition code flag */
+ uint32_t N:1; /*!< bit: 31 Negative condition code flag */
+ } b; /*!< Structure used for bit access */
+ uint32_t w; /*!< Type used for word access */
+} xPSR_Type;
+
+/* xPSR Register Definitions */
+#define xPSR_N_Pos 31U /*!< xPSR: N Position */
+#define xPSR_N_Msk (1UL << xPSR_N_Pos) /*!< xPSR: N Mask */
+
+#define xPSR_Z_Pos 30U /*!< xPSR: Z Position */
+#define xPSR_Z_Msk (1UL << xPSR_Z_Pos) /*!< xPSR: Z Mask */
+
+#define xPSR_C_Pos 29U /*!< xPSR: C Position */
+#define xPSR_C_Msk (1UL << xPSR_C_Pos) /*!< xPSR: C Mask */
+
+#define xPSR_V_Pos 28U /*!< xPSR: V Position */
+#define xPSR_V_Msk (1UL << xPSR_V_Pos) /*!< xPSR: V Mask */
+
+#define xPSR_T_Pos 24U /*!< xPSR: T Position */
+#define xPSR_T_Msk (1UL << xPSR_T_Pos) /*!< xPSR: T Mask */
+
+#define xPSR_ISR_Pos 0U /*!< xPSR: ISR Position */
+#define xPSR_ISR_Msk (0x1FFUL /*<< xPSR_ISR_Pos*/) /*!< xPSR: ISR Mask */
+
+
+/**
+ \brief Union type to access the Control Registers (CONTROL).
+ */
+typedef union
+{
+ struct
+ {
+ uint32_t _reserved0:1; /*!< bit: 0 Reserved */
+ uint32_t SPSEL:1; /*!< bit: 1 Stack to be used */
+ uint32_t _reserved1:30; /*!< bit: 2..31 Reserved */
+ } b; /*!< Structure used for bit access */
+ uint32_t w; /*!< Type used for word access */
+} CONTROL_Type;
+
+/* CONTROL Register Definitions */
+#define CONTROL_SPSEL_Pos 1U /*!< CONTROL: SPSEL Position */
+#define CONTROL_SPSEL_Msk (1UL << CONTROL_SPSEL_Pos) /*!< CONTROL: SPSEL Mask */
+
+/*@} end of group CMSIS_CORE */
+
+
+/**
+ \ingroup CMSIS_core_register
+ \defgroup CMSIS_NVIC Nested Vectored Interrupt Controller (NVIC)
+ \brief Type definitions for the NVIC Registers
+ @{
+ */
+
+/**
+ \brief Structure type to access the Nested Vectored Interrupt Controller (NVIC).
+ */
+typedef struct
+{
+ __IOM uint32_t ISER[1U]; /*!< Offset: 0x000 (R/W) Interrupt Set Enable Register */
+ uint32_t RESERVED0[31U];
+ __IOM uint32_t ICER[1U]; /*!< Offset: 0x080 (R/W) Interrupt Clear Enable Register */
+ uint32_t RSERVED1[31U];
+ __IOM uint32_t ISPR[1U]; /*!< Offset: 0x100 (R/W) Interrupt Set Pending Register */
+ uint32_t RESERVED2[31U];
+ __IOM uint32_t ICPR[1U]; /*!< Offset: 0x180 (R/W) Interrupt Clear Pending Register */
+ uint32_t RESERVED3[31U];
+ uint32_t RESERVED4[64U];
+ __IOM uint32_t IP[8U]; /*!< Offset: 0x300 (R/W) Interrupt Priority Register */
+} NVIC_Type;
+
+/*@} end of group CMSIS_NVIC */
+
+
+/**
+ \ingroup CMSIS_core_register
+ \defgroup CMSIS_SCB System Control Block (SCB)
+ \brief Type definitions for the System Control Block Registers
+ @{
+ */
+
+/**
+ \brief Structure type to access the System Control Block (SCB).
+ */
+typedef struct
+{
+ __IM uint32_t CPUID; /*!< Offset: 0x000 (R/ ) CPUID Base Register */
+ __IOM uint32_t ICSR; /*!< Offset: 0x004 (R/W) Interrupt Control and State Register */
+ __IOM uint32_t VTOR; /*!< Offset: 0x008 (R/W) Vector Table Offset Register */
+ __IOM uint32_t AIRCR; /*!< Offset: 0x00C (R/W) Application Interrupt and Reset Control Register */
+ __IOM uint32_t SCR; /*!< Offset: 0x010 (R/W) System Control Register */
+ __IOM uint32_t CCR; /*!< Offset: 0x014 (R/W) Configuration Control Register */
+ uint32_t RESERVED0[1U];
+ __IOM uint32_t SHP[2U]; /*!< Offset: 0x01C (R/W) System Handlers Priority Registers. [0] is RESERVED */
+ __IOM uint32_t SHCSR; /*!< Offset: 0x024 (R/W) System Handler Control and State Register */
+ uint32_t RESERVED1[154U];
+ __IOM uint32_t SFCR; /*!< Offset: 0x290 (R/W) Security Features Control Register */
+} SCB_Type;
+
+/* SCB CPUID Register Definitions */
+#define SCB_CPUID_IMPLEMENTER_Pos 24U /*!< SCB CPUID: IMPLEMENTER Position */
+#define SCB_CPUID_IMPLEMENTER_Msk (0xFFUL << SCB_CPUID_IMPLEMENTER_Pos) /*!< SCB CPUID: IMPLEMENTER Mask */
+
+#define SCB_CPUID_VARIANT_Pos 20U /*!< SCB CPUID: VARIANT Position */
+#define SCB_CPUID_VARIANT_Msk (0xFUL << SCB_CPUID_VARIANT_Pos) /*!< SCB CPUID: VARIANT Mask */
+
+#define SCB_CPUID_ARCHITECTURE_Pos 16U /*!< SCB CPUID: ARCHITECTURE Position */
+#define SCB_CPUID_ARCHITECTURE_Msk (0xFUL << SCB_CPUID_ARCHITECTURE_Pos) /*!< SCB CPUID: ARCHITECTURE Mask */
+
+#define SCB_CPUID_PARTNO_Pos 4U /*!< SCB CPUID: PARTNO Position */
+#define SCB_CPUID_PARTNO_Msk (0xFFFUL << SCB_CPUID_PARTNO_Pos) /*!< SCB CPUID: PARTNO Mask */
+
+#define SCB_CPUID_REVISION_Pos 0U /*!< SCB CPUID: REVISION Position */
+#define SCB_CPUID_REVISION_Msk (0xFUL /*<< SCB_CPUID_REVISION_Pos*/) /*!< SCB CPUID: REVISION Mask */
+
+/* SCB Interrupt Control State Register Definitions */
+#define SCB_ICSR_NMIPENDSET_Pos 31U /*!< SCB ICSR: NMIPENDSET Position */
+#define SCB_ICSR_NMIPENDSET_Msk (1UL << SCB_ICSR_NMIPENDSET_Pos) /*!< SCB ICSR: NMIPENDSET Mask */
+
+#define SCB_ICSR_PENDSVSET_Pos 28U /*!< SCB ICSR: PENDSVSET Position */
+#define SCB_ICSR_PENDSVSET_Msk (1UL << SCB_ICSR_PENDSVSET_Pos) /*!< SCB ICSR: PENDSVSET Mask */
+
+#define SCB_ICSR_PENDSVCLR_Pos 27U /*!< SCB ICSR: PENDSVCLR Position */
+#define SCB_ICSR_PENDSVCLR_Msk (1UL << SCB_ICSR_PENDSVCLR_Pos) /*!< SCB ICSR: PENDSVCLR Mask */
+
+#define SCB_ICSR_PENDSTSET_Pos 26U /*!< SCB ICSR: PENDSTSET Position */
+#define SCB_ICSR_PENDSTSET_Msk (1UL << SCB_ICSR_PENDSTSET_Pos) /*!< SCB ICSR: PENDSTSET Mask */
+
+#define SCB_ICSR_PENDSTCLR_Pos 25U /*!< SCB ICSR: PENDSTCLR Position */
+#define SCB_ICSR_PENDSTCLR_Msk (1UL << SCB_ICSR_PENDSTCLR_Pos) /*!< SCB ICSR: PENDSTCLR Mask */
+
+#define SCB_ICSR_ISRPREEMPT_Pos 23U /*!< SCB ICSR: ISRPREEMPT Position */
+#define SCB_ICSR_ISRPREEMPT_Msk (1UL << SCB_ICSR_ISRPREEMPT_Pos) /*!< SCB ICSR: ISRPREEMPT Mask */
+
+#define SCB_ICSR_ISRPENDING_Pos 22U /*!< SCB ICSR: ISRPENDING Position */
+#define SCB_ICSR_ISRPENDING_Msk (1UL << SCB_ICSR_ISRPENDING_Pos) /*!< SCB ICSR: ISRPENDING Mask */
+
+#define SCB_ICSR_VECTPENDING_Pos 12U /*!< SCB ICSR: VECTPENDING Position */
+#define SCB_ICSR_VECTPENDING_Msk (0x1FFUL << SCB_ICSR_VECTPENDING_Pos) /*!< SCB ICSR: VECTPENDING Mask */
+
+#define SCB_ICSR_VECTACTIVE_Pos 0U /*!< SCB ICSR: VECTACTIVE Position */
+#define SCB_ICSR_VECTACTIVE_Msk (0x1FFUL /*<< SCB_ICSR_VECTACTIVE_Pos*/) /*!< SCB ICSR: VECTACTIVE Mask */
+
+/* SCB Interrupt Control State Register Definitions */
+#define SCB_VTOR_TBLOFF_Pos 7U /*!< SCB VTOR: TBLOFF Position */
+#define SCB_VTOR_TBLOFF_Msk (0x1FFFFFFUL << SCB_VTOR_TBLOFF_Pos) /*!< SCB VTOR: TBLOFF Mask */
+
+/* SCB Application Interrupt and Reset Control Register Definitions */
+#define SCB_AIRCR_VECTKEY_Pos 16U /*!< SCB AIRCR: VECTKEY Position */
+#define SCB_AIRCR_VECTKEY_Msk (0xFFFFUL << SCB_AIRCR_VECTKEY_Pos) /*!< SCB AIRCR: VECTKEY Mask */
+
+#define SCB_AIRCR_VECTKEYSTAT_Pos 16U /*!< SCB AIRCR: VECTKEYSTAT Position */
+#define SCB_AIRCR_VECTKEYSTAT_Msk (0xFFFFUL << SCB_AIRCR_VECTKEYSTAT_Pos) /*!< SCB AIRCR: VECTKEYSTAT Mask */
+
+#define SCB_AIRCR_ENDIANESS_Pos 15U /*!< SCB AIRCR: ENDIANESS Position */
+#define SCB_AIRCR_ENDIANESS_Msk (1UL << SCB_AIRCR_ENDIANESS_Pos) /*!< SCB AIRCR: ENDIANESS Mask */
+
+#define SCB_AIRCR_SYSRESETREQ_Pos 2U /*!< SCB AIRCR: SYSRESETREQ Position */
+#define SCB_AIRCR_SYSRESETREQ_Msk (1UL << SCB_AIRCR_SYSRESETREQ_Pos) /*!< SCB AIRCR: SYSRESETREQ Mask */
+
+#define SCB_AIRCR_VECTCLRACTIVE_Pos 1U /*!< SCB AIRCR: VECTCLRACTIVE Position */
+#define SCB_AIRCR_VECTCLRACTIVE_Msk (1UL << SCB_AIRCR_VECTCLRACTIVE_Pos) /*!< SCB AIRCR: VECTCLRACTIVE Mask */
+
+/* SCB System Control Register Definitions */
+#define SCB_SCR_SEVONPEND_Pos 4U /*!< SCB SCR: SEVONPEND Position */
+#define SCB_SCR_SEVONPEND_Msk (1UL << SCB_SCR_SEVONPEND_Pos) /*!< SCB SCR: SEVONPEND Mask */
+
+#define SCB_SCR_SLEEPDEEP_Pos 2U /*!< SCB SCR: SLEEPDEEP Position */
+#define SCB_SCR_SLEEPDEEP_Msk (1UL << SCB_SCR_SLEEPDEEP_Pos) /*!< SCB SCR: SLEEPDEEP Mask */
+
+#define SCB_SCR_SLEEPONEXIT_Pos 1U /*!< SCB SCR: SLEEPONEXIT Position */
+#define SCB_SCR_SLEEPONEXIT_Msk (1UL << SCB_SCR_SLEEPONEXIT_Pos) /*!< SCB SCR: SLEEPONEXIT Mask */
+
+/* SCB Configuration Control Register Definitions */
+#define SCB_CCR_STKALIGN_Pos 9U /*!< SCB CCR: STKALIGN Position */
+#define SCB_CCR_STKALIGN_Msk (1UL << SCB_CCR_STKALIGN_Pos) /*!< SCB CCR: STKALIGN Mask */
+
+#define SCB_CCR_UNALIGN_TRP_Pos 3U /*!< SCB CCR: UNALIGN_TRP Position */
+#define SCB_CCR_UNALIGN_TRP_Msk (1UL << SCB_CCR_UNALIGN_TRP_Pos) /*!< SCB CCR: UNALIGN_TRP Mask */
+
+/* SCB System Handler Control and State Register Definitions */
+#define SCB_SHCSR_SVCALLPENDED_Pos 15U /*!< SCB SHCSR: SVCALLPENDED Position */
+#define SCB_SHCSR_SVCALLPENDED_Msk (1UL << SCB_SHCSR_SVCALLPENDED_Pos) /*!< SCB SHCSR: SVCALLPENDED Mask */
+
+/*@} end of group CMSIS_SCB */
+
+
+/**
+ \ingroup CMSIS_core_register
+ \defgroup CMSIS_SCnSCB System Controls not in SCB (SCnSCB)
+ \brief Type definitions for the System Control and ID Register not in the SCB
+ @{
+ */
+
+/**
+ \brief Structure type to access the System Control and ID Register not in the SCB.
+ */
+typedef struct
+{
+ uint32_t RESERVED0[2U];
+ __IOM uint32_t ACTLR; /*!< Offset: 0x008 (R/W) Auxiliary Control Register */
+} SCnSCB_Type;
+
+/* Auxiliary Control Register Definitions */
+#define SCnSCB_ACTLR_DISMCYCINT_Pos 0U /*!< ACTLR: DISMCYCINT Position */
+#define SCnSCB_ACTLR_DISMCYCINT_Msk (1UL /*<< SCnSCB_ACTLR_DISMCYCINT_Pos*/) /*!< ACTLR: DISMCYCINT Mask */
+
+/*@} end of group CMSIS_SCnotSCB */
+
+
+/**
+ \ingroup CMSIS_core_register
+ \defgroup CMSIS_SysTick System Tick Timer (SysTick)
+ \brief Type definitions for the System Timer Registers.
+ @{
+ */
+
+/**
+ \brief Structure type to access the System Timer (SysTick).
+ */
+typedef struct
+{
+ __IOM uint32_t CTRL; /*!< Offset: 0x000 (R/W) SysTick Control and Status Register */
+ __IOM uint32_t LOAD; /*!< Offset: 0x004 (R/W) SysTick Reload Value Register */
+ __IOM uint32_t VAL; /*!< Offset: 0x008 (R/W) SysTick Current Value Register */
+ __IM uint32_t CALIB; /*!< Offset: 0x00C (R/ ) SysTick Calibration Register */
+} SysTick_Type;
+
+/* SysTick Control / Status Register Definitions */
+#define SysTick_CTRL_COUNTFLAG_Pos 16U /*!< SysTick CTRL: COUNTFLAG Position */
+#define SysTick_CTRL_COUNTFLAG_Msk (1UL << SysTick_CTRL_COUNTFLAG_Pos) /*!< SysTick CTRL: COUNTFLAG Mask */
+
+#define SysTick_CTRL_CLKSOURCE_Pos 2U /*!< SysTick CTRL: CLKSOURCE Position */
+#define SysTick_CTRL_CLKSOURCE_Msk (1UL << SysTick_CTRL_CLKSOURCE_Pos) /*!< SysTick CTRL: CLKSOURCE Mask */
+
+#define SysTick_CTRL_TICKINT_Pos 1U /*!< SysTick CTRL: TICKINT Position */
+#define SysTick_CTRL_TICKINT_Msk (1UL << SysTick_CTRL_TICKINT_Pos) /*!< SysTick CTRL: TICKINT Mask */
+
+#define SysTick_CTRL_ENABLE_Pos 0U /*!< SysTick CTRL: ENABLE Position */
+#define SysTick_CTRL_ENABLE_Msk (1UL /*<< SysTick_CTRL_ENABLE_Pos*/) /*!< SysTick CTRL: ENABLE Mask */
+
+/* SysTick Reload Register Definitions */
+#define SysTick_LOAD_RELOAD_Pos 0U /*!< SysTick LOAD: RELOAD Position */
+#define SysTick_LOAD_RELOAD_Msk (0xFFFFFFUL /*<< SysTick_LOAD_RELOAD_Pos*/) /*!< SysTick LOAD: RELOAD Mask */
+
+/* SysTick Current Register Definitions */
+#define SysTick_VAL_CURRENT_Pos 0U /*!< SysTick VAL: CURRENT Position */
+#define SysTick_VAL_CURRENT_Msk (0xFFFFFFUL /*<< SysTick_VAL_CURRENT_Pos*/) /*!< SysTick VAL: CURRENT Mask */
+
+/* SysTick Calibration Register Definitions */
+#define SysTick_CALIB_NOREF_Pos 31U /*!< SysTick CALIB: NOREF Position */
+#define SysTick_CALIB_NOREF_Msk (1UL << SysTick_CALIB_NOREF_Pos) /*!< SysTick CALIB: NOREF Mask */
+
+#define SysTick_CALIB_SKEW_Pos 30U /*!< SysTick CALIB: SKEW Position */
+#define SysTick_CALIB_SKEW_Msk (1UL << SysTick_CALIB_SKEW_Pos) /*!< SysTick CALIB: SKEW Mask */
+
+#define SysTick_CALIB_TENMS_Pos 0U /*!< SysTick CALIB: TENMS Position */
+#define SysTick_CALIB_TENMS_Msk (0xFFFFFFUL /*<< SysTick_CALIB_TENMS_Pos*/) /*!< SysTick CALIB: TENMS Mask */
+
+/*@} end of group CMSIS_SysTick */
+
+#if (__MPU_PRESENT == 1U)
+/**
+ \ingroup CMSIS_core_register
+ \defgroup CMSIS_MPU Memory Protection Unit (MPU)
+ \brief Type definitions for the Memory Protection Unit (MPU)
+ @{
+ */
+
+/**
+ \brief Structure type to access the Memory Protection Unit (MPU).
+ */
+typedef struct
+{
+ __IM uint32_t TYPE; /*!< Offset: 0x000 (R/ ) MPU Type Register */
+ __IOM uint32_t CTRL; /*!< Offset: 0x004 (R/W) MPU Control Register */
+ __IOM uint32_t RNR; /*!< Offset: 0x008 (R/W) MPU Region RNRber Register */
+ __IOM uint32_t RBAR; /*!< Offset: 0x00C (R/W) MPU Region Base Address Register */
+ __IOM uint32_t RASR; /*!< Offset: 0x010 (R/W) MPU Region Attribute and Size Register */
+} MPU_Type;
+
+/* MPU Type Register Definitions */
+#define MPU_TYPE_IREGION_Pos 16U /*!< MPU TYPE: IREGION Position */
+#define MPU_TYPE_IREGION_Msk (0xFFUL << MPU_TYPE_IREGION_Pos) /*!< MPU TYPE: IREGION Mask */
+
+#define MPU_TYPE_DREGION_Pos 8U /*!< MPU TYPE: DREGION Position */
+#define MPU_TYPE_DREGION_Msk (0xFFUL << MPU_TYPE_DREGION_Pos) /*!< MPU TYPE: DREGION Mask */
+
+#define MPU_TYPE_SEPARATE_Pos 0U /*!< MPU TYPE: SEPARATE Position */
+#define MPU_TYPE_SEPARATE_Msk (1UL /*<< MPU_TYPE_SEPARATE_Pos*/) /*!< MPU TYPE: SEPARATE Mask */
+
+/* MPU Control Register Definitions */
+#define MPU_CTRL_PRIVDEFENA_Pos 2U /*!< MPU CTRL: PRIVDEFENA Position */
+#define MPU_CTRL_PRIVDEFENA_Msk (1UL << MPU_CTRL_PRIVDEFENA_Pos) /*!< MPU CTRL: PRIVDEFENA Mask */
+
+#define MPU_CTRL_HFNMIENA_Pos 1U /*!< MPU CTRL: HFNMIENA Position */
+#define MPU_CTRL_HFNMIENA_Msk (1UL << MPU_CTRL_HFNMIENA_Pos) /*!< MPU CTRL: HFNMIENA Mask */
+
+#define MPU_CTRL_ENABLE_Pos 0U /*!< MPU CTRL: ENABLE Position */
+#define MPU_CTRL_ENABLE_Msk (1UL /*<< MPU_CTRL_ENABLE_Pos*/) /*!< MPU CTRL: ENABLE Mask */
+
+/* MPU Region Number Register Definitions */
+#define MPU_RNR_REGION_Pos 0U /*!< MPU RNR: REGION Position */
+#define MPU_RNR_REGION_Msk (0xFFUL /*<< MPU_RNR_REGION_Pos*/) /*!< MPU RNR: REGION Mask */
+
+/* MPU Region Base Address Register Definitions */
+#define MPU_RBAR_ADDR_Pos 8U /*!< MPU RBAR: ADDR Position */
+#define MPU_RBAR_ADDR_Msk (0xFFFFFFUL << MPU_RBAR_ADDR_Pos) /*!< MPU RBAR: ADDR Mask */
+
+#define MPU_RBAR_VALID_Pos 4U /*!< MPU RBAR: VALID Position */
+#define MPU_RBAR_VALID_Msk (1UL << MPU_RBAR_VALID_Pos) /*!< MPU RBAR: VALID Mask */
+
+#define MPU_RBAR_REGION_Pos 0U /*!< MPU RBAR: REGION Position */
+#define MPU_RBAR_REGION_Msk (0xFUL /*<< MPU_RBAR_REGION_Pos*/) /*!< MPU RBAR: REGION Mask */
+
+/* MPU Region Attribute and Size Register Definitions */
+#define MPU_RASR_ATTRS_Pos 16U /*!< MPU RASR: MPU Region Attribute field Position */
+#define MPU_RASR_ATTRS_Msk (0xFFFFUL << MPU_RASR_ATTRS_Pos) /*!< MPU RASR: MPU Region Attribute field Mask */
+
+#define MPU_RASR_XN_Pos 28U /*!< MPU RASR: ATTRS.XN Position */
+#define MPU_RASR_XN_Msk (1UL << MPU_RASR_XN_Pos) /*!< MPU RASR: ATTRS.XN Mask */
+
+#define MPU_RASR_AP_Pos 24U /*!< MPU RASR: ATTRS.AP Position */
+#define MPU_RASR_AP_Msk (0x7UL << MPU_RASR_AP_Pos) /*!< MPU RASR: ATTRS.AP Mask */
+
+#define MPU_RASR_TEX_Pos 19U /*!< MPU RASR: ATTRS.TEX Position */
+#define MPU_RASR_TEX_Msk (0x7UL << MPU_RASR_TEX_Pos) /*!< MPU RASR: ATTRS.TEX Mask */
+
+#define MPU_RASR_S_Pos 18U /*!< MPU RASR: ATTRS.S Position */
+#define MPU_RASR_S_Msk (1UL << MPU_RASR_S_Pos) /*!< MPU RASR: ATTRS.S Mask */
+
+#define MPU_RASR_C_Pos 17U /*!< MPU RASR: ATTRS.C Position */
+#define MPU_RASR_C_Msk (1UL << MPU_RASR_C_Pos) /*!< MPU RASR: ATTRS.C Mask */
+
+#define MPU_RASR_B_Pos 16U /*!< MPU RASR: ATTRS.B Position */
+#define MPU_RASR_B_Msk (1UL << MPU_RASR_B_Pos) /*!< MPU RASR: ATTRS.B Mask */
+
+#define MPU_RASR_SRD_Pos 8U /*!< MPU RASR: Sub-Region Disable Position */
+#define MPU_RASR_SRD_Msk (0xFFUL << MPU_RASR_SRD_Pos) /*!< MPU RASR: Sub-Region Disable Mask */
+
+#define MPU_RASR_SIZE_Pos 1U /*!< MPU RASR: Region Size Field Position */
+#define MPU_RASR_SIZE_Msk (0x1FUL << MPU_RASR_SIZE_Pos) /*!< MPU RASR: Region Size Field Mask */
+
+#define MPU_RASR_ENABLE_Pos 0U /*!< MPU RASR: Region enable bit Position */
+#define MPU_RASR_ENABLE_Msk (1UL /*<< MPU_RASR_ENABLE_Pos*/) /*!< MPU RASR: Region enable bit Disable Mask */
+
+/*@} end of group CMSIS_MPU */
+#endif
+
+
+/**
+ \ingroup CMSIS_core_register
+ \defgroup CMSIS_CoreDebug Core Debug Registers (CoreDebug)
+ \brief SC000 Core Debug Registers (DCB registers, SHCSR, and DFSR) are only accessible over DAP and not via processor.
+ Therefore they are not covered by the SC000 header file.
+ @{
+ */
+/*@} end of group CMSIS_CoreDebug */
+
+
+/**
+ \ingroup CMSIS_core_register
+ \defgroup CMSIS_core_bitfield Core register bit field macros
+ \brief Macros for use with bit field definitions (xxx_Pos, xxx_Msk).
+ @{
+ */
+
+/**
+ \brief Mask and shift a bit field value for use in a register bit range.
+ \param[in] field Name of the register bit field.
+ \param[in] value Value of the bit field.
+ \return Masked and shifted value.
+*/
+#define _VAL2FLD(field, value) ((value << field ## _Pos) & field ## _Msk)
+
+/**
+ \brief Mask and shift a register value to extract a bit filed value.
+ \param[in] field Name of the register bit field.
+ \param[in] value Value of register.
+ \return Masked and shifted bit field value.
+*/
+#define _FLD2VAL(field, value) ((value & field ## _Msk) >> field ## _Pos)
+
+/*@} end of group CMSIS_core_bitfield */
+
+
+/**
+ \ingroup CMSIS_core_register
+ \defgroup CMSIS_core_base Core Definitions
+ \brief Definitions for base addresses, unions, and structures.
+ @{
+ */
+
+/* Memory mapping of SC000 Hardware */
+#define SCS_BASE (0xE000E000UL) /*!< System Control Space Base Address */
+#define SysTick_BASE (SCS_BASE + 0x0010UL) /*!< SysTick Base Address */
+#define NVIC_BASE (SCS_BASE + 0x0100UL) /*!< NVIC Base Address */
+#define SCB_BASE (SCS_BASE + 0x0D00UL) /*!< System Control Block Base Address */
+
+#define SCnSCB ((SCnSCB_Type *) SCS_BASE ) /*!< System control Register not in SCB */
+#define SCB ((SCB_Type *) SCB_BASE ) /*!< SCB configuration struct */
+#define SysTick ((SysTick_Type *) SysTick_BASE ) /*!< SysTick configuration struct */
+#define NVIC ((NVIC_Type *) NVIC_BASE ) /*!< NVIC configuration struct */
+
+#if (__MPU_PRESENT == 1U)
+ #define MPU_BASE (SCS_BASE + 0x0D90UL) /*!< Memory Protection Unit */
+ #define MPU ((MPU_Type *) MPU_BASE ) /*!< Memory Protection Unit */
+#endif
+
+/*@} */
+
+
+
+/*******************************************************************************
+ * Hardware Abstraction Layer
+ Core Function Interface contains:
+ - Core NVIC Functions
+ - Core SysTick Functions
+ - Core Register Access Functions
+ ******************************************************************************/
+/**
+ \defgroup CMSIS_Core_FunctionInterface Functions and Instructions Reference
+*/
+
+
+
+/* ########################## NVIC functions #################################### */
+/**
+ \ingroup CMSIS_Core_FunctionInterface
+ \defgroup CMSIS_Core_NVICFunctions NVIC Functions
+ \brief Functions that manage interrupts and exceptions via the NVIC.
+ @{
+ */
+
+/* Interrupt Priorities are WORD accessible only under ARMv6M */
+/* The following MACROS handle generation of the register offset and byte masks */
+#define _BIT_SHIFT(IRQn) ( ((((uint32_t)(int32_t)(IRQn)) ) & 0x03UL) * 8UL)
+#define _SHP_IDX(IRQn) ( (((((uint32_t)(int32_t)(IRQn)) & 0x0FUL)-8UL) >> 2UL) )
+#define _IP_IDX(IRQn) ( (((uint32_t)(int32_t)(IRQn)) >> 2UL) )
+
+
+/**
+ \brief Enable External Interrupt
+ \details Enables a device-specific interrupt in the NVIC interrupt controller.
+ \param [in] IRQn External interrupt number. Value cannot be negative.
+ */
+__STATIC_INLINE void NVIC_EnableIRQ(IRQn_Type IRQn)
+{
+ NVIC->ISER[0U] = (uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL));
+}
+
+
+/**
+ \brief Disable External Interrupt
+ \details Disables a device-specific interrupt in the NVIC interrupt controller.
+ \param [in] IRQn External interrupt number. Value cannot be negative.
+ */
+__STATIC_INLINE void NVIC_DisableIRQ(IRQn_Type IRQn)
+{
+ NVIC->ICER[0U] = (uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL));
+}
+
+
+/**
+ \brief Get Pending Interrupt
+ \details Reads the pending register in the NVIC and returns the pending bit for the specified interrupt.
+ \param [in] IRQn Interrupt number.
+ \return 0 Interrupt status is not pending.
+ \return 1 Interrupt status is pending.
+ */
+__STATIC_INLINE uint32_t NVIC_GetPendingIRQ(IRQn_Type IRQn)
+{
+ return((uint32_t)(((NVIC->ISPR[0U] & (1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL));
+}
+
+
+/**
+ \brief Set Pending Interrupt
+ \details Sets the pending bit of an external interrupt.
+ \param [in] IRQn Interrupt number. Value cannot be negative.
+ */
+__STATIC_INLINE void NVIC_SetPendingIRQ(IRQn_Type IRQn)
+{
+ NVIC->ISPR[0U] = (uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL));
+}
+
+
+/**
+ \brief Clear Pending Interrupt
+ \details Clears the pending bit of an external interrupt.
+ \param [in] IRQn External interrupt number. Value cannot be negative.
+ */
+__STATIC_INLINE void NVIC_ClearPendingIRQ(IRQn_Type IRQn)
+{
+ NVIC->ICPR[0U] = (uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL));
+}
+
+
+/**
+ \brief Set Interrupt Priority
+ \details Sets the priority of an interrupt.
+ \note The priority cannot be set for every core interrupt.
+ \param [in] IRQn Interrupt number.
+ \param [in] priority Priority to set.
+ */
+__STATIC_INLINE void NVIC_SetPriority(IRQn_Type IRQn, uint32_t priority)
+{
+ if ((int32_t)(IRQn) < 0)
+ {
+ SCB->SHP[_SHP_IDX(IRQn)] = ((uint32_t)(SCB->SHP[_SHP_IDX(IRQn)] & ~(0xFFUL << _BIT_SHIFT(IRQn))) |
+ (((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL) << _BIT_SHIFT(IRQn)));
+ }
+ else
+ {
+ NVIC->IP[_IP_IDX(IRQn)] = ((uint32_t)(NVIC->IP[_IP_IDX(IRQn)] & ~(0xFFUL << _BIT_SHIFT(IRQn))) |
+ (((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL) << _BIT_SHIFT(IRQn)));
+ }
+}
+
+
+/**
+ \brief Get Interrupt Priority
+ \details Reads the priority of an interrupt.
+ The interrupt number can be positive to specify an external (device specific) interrupt,
+ or negative to specify an internal (core) interrupt.
+ \param [in] IRQn Interrupt number.
+ \return Interrupt Priority.
+ Value is aligned automatically to the implemented priority bits of the microcontroller.
+ */
+__STATIC_INLINE uint32_t NVIC_GetPriority(IRQn_Type IRQn)
+{
+
+ if ((int32_t)(IRQn) < 0)
+ {
+ return((uint32_t)(((SCB->SHP[_SHP_IDX(IRQn)] >> _BIT_SHIFT(IRQn) ) & (uint32_t)0xFFUL) >> (8U - __NVIC_PRIO_BITS)));
+ }
+ else
+ {
+ return((uint32_t)(((NVIC->IP[ _IP_IDX(IRQn)] >> _BIT_SHIFT(IRQn) ) & (uint32_t)0xFFUL) >> (8U - __NVIC_PRIO_BITS)));
+ }
+}
+
+
+/**
+ \brief System Reset
+ \details Initiates a system reset request to reset the MCU.
+ */
+__STATIC_INLINE void NVIC_SystemReset(void)
+{
+ __DSB(); /* Ensure all outstanding memory accesses included
+ buffered write are completed before reset */
+ SCB->AIRCR = ((0x5FAUL << SCB_AIRCR_VECTKEY_Pos) |
+ SCB_AIRCR_SYSRESETREQ_Msk);
+ __DSB(); /* Ensure completion of memory access */
+
+ for (;;) /* wait until reset */
+ {
+ __NOP();
+ }
+}
+
+/*@} end of CMSIS_Core_NVICFunctions */
+
+
+
+/* ################################## SysTick function ############################################ */
+/**
+ \ingroup CMSIS_Core_FunctionInterface
+ \defgroup CMSIS_Core_SysTickFunctions SysTick Functions
+ \brief Functions that configure the System.
+ @{
+ */
+
+#if (__Vendor_SysTickConfig == 0U)
+
+/**
+ \brief System Tick Configuration
+ \details Initializes the System Timer and its interrupt, and starts the System Tick Timer.
+ Counter is in free running mode to generate periodic interrupts.
+ \param [in] ticks Number of ticks between two interrupts.
+ \return 0 Function succeeded.
+ \return 1 Function failed.
+ \note When the variable <b>__Vendor_SysTickConfig</b> is set to 1, then the
+ function <b>SysTick_Config</b> is not included. In this case, the file <b><i>device</i>.h</b>
+ must contain a vendor-specific implementation of this function.
+ */
+__STATIC_INLINE uint32_t SysTick_Config(uint32_t ticks)
+{
+ if ((ticks - 1UL) > SysTick_LOAD_RELOAD_Msk)
+ {
+ return (1UL); /* Reload value impossible */
+ }
+
+ SysTick->LOAD = (uint32_t)(ticks - 1UL); /* set reload register */
+ NVIC_SetPriority (SysTick_IRQn, (1UL << __NVIC_PRIO_BITS) - 1UL); /* set Priority for Systick Interrupt */
+ SysTick->VAL = 0UL; /* Load the SysTick Counter Value */
+ SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk |
+ SysTick_CTRL_TICKINT_Msk |
+ SysTick_CTRL_ENABLE_Msk; /* Enable SysTick IRQ and SysTick Timer */
+ return (0UL); /* Function successful */
+}
+
+#endif
+
+/*@} end of CMSIS_Core_SysTickFunctions */
+
+
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __CORE_SC000_H_DEPENDANT */
+
+#endif /* __CMSIS_GENERIC */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/toolchain/cmsis/include/core_sc300.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/toolchain/cmsis/include/core_sc300.h
new file mode 100644
index 0000000..5b58f49
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/toolchain/cmsis/include/core_sc300.h
@@ -0,0 +1,1745 @@
+/**************************************************************************//**
+ * @file core_sc300.h
+ * @brief CMSIS SC300 Core Peripheral Access Layer Header File
+ * @version V4.30
+ * @date 20. October 2015
+ ******************************************************************************/
+/* Copyright (c) 2009 - 2015 ARM LIMITED
+
+ All rights reserved.
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are met:
+ - Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ - 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.
+ - Neither the name of ARM 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 COPYRIGHT HOLDERS AND 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.
+ ---------------------------------------------------------------------------*/
+
+
+#if defined ( __ICCARM__ )
+ #pragma system_include /* treat file as system include file for MISRA check */
+#elif defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050)
+ #pragma clang system_header /* treat file as system include file */
+#endif
+
+#ifndef __CORE_SC300_H_GENERIC
+#define __CORE_SC300_H_GENERIC
+
+#include <stdint.h>
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+/**
+ \page CMSIS_MISRA_Exceptions MISRA-C:2004 Compliance Exceptions
+ CMSIS violates the following MISRA-C:2004 rules:
+
+ \li Required Rule 8.5, object/function definition in header file.<br>
+ Function definitions in header files are used to allow 'inlining'.
+
+ \li Required Rule 18.4, declaration of union type or object of union type: '{...}'.<br>
+ Unions are used for effective representation of core registers.
+
+ \li Advisory Rule 19.7, Function-like macro defined.<br>
+ Function-like macros are used to allow more efficient code.
+ */
+
+
+/*******************************************************************************
+ * CMSIS definitions
+ ******************************************************************************/
+/**
+ \ingroup SC3000
+ @{
+ */
+
+/* CMSIS SC300 definitions */
+#define __SC300_CMSIS_VERSION_MAIN (0x04U) /*!< [31:16] CMSIS HAL main version */
+#define __SC300_CMSIS_VERSION_SUB (0x1EU) /*!< [15:0] CMSIS HAL sub version */
+#define __SC300_CMSIS_VERSION ((__SC300_CMSIS_VERSION_MAIN << 16U) | \
+ __SC300_CMSIS_VERSION_SUB ) /*!< CMSIS HAL version number */
+
+#define __CORTEX_SC (300U) /*!< Cortex secure core */
+
+
+#if defined ( __CC_ARM )
+ #define __ASM __asm /*!< asm keyword for ARM Compiler */
+ #define __INLINE __inline /*!< inline keyword for ARM Compiler */
+ #define __STATIC_INLINE static __inline
+
+#elif defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050)
+ #define __ASM __asm /*!< asm keyword for ARM Compiler */
+ #define __INLINE __inline /*!< inline keyword for ARM Compiler */
+ #define __STATIC_INLINE static __inline
+
+#elif defined ( __GNUC__ )
+ #define __ASM __asm /*!< asm keyword for GNU Compiler */
+ #define __INLINE inline /*!< inline keyword for GNU Compiler */
+ #define __STATIC_INLINE static inline
+
+#elif defined ( __ICCARM__ )
+ #define __ASM __asm /*!< asm keyword for IAR Compiler */
+ #define __INLINE inline /*!< inline keyword for IAR Compiler. Only available in High optimization mode! */
+ #define __STATIC_INLINE static inline
+
+#elif defined ( __TMS470__ )
+ #define __ASM __asm /*!< asm keyword for TI CCS Compiler */
+ #define __STATIC_INLINE static inline
+
+#elif defined ( __TASKING__ )
+ #define __ASM __asm /*!< asm keyword for TASKING Compiler */
+ #define __INLINE inline /*!< inline keyword for TASKING Compiler */
+ #define __STATIC_INLINE static inline
+
+#elif defined ( __CSMC__ )
+ #define __packed
+ #define __ASM _asm /*!< asm keyword for COSMIC Compiler */
+ #define __INLINE inline /*!< inline keyword for COSMIC Compiler. Use -pc99 on compile line */
+ #define __STATIC_INLINE static inline
+
+#else
+ #error Unknown compiler
+#endif
+
+/** __FPU_USED indicates whether an FPU is used or not.
+ This core does not support an FPU at all
+*/
+#define __FPU_USED 0U
+
+#if defined ( __CC_ARM )
+ #if defined __TARGET_FPU_VFP
+ #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
+ #endif
+
+#elif defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050)
+ #if defined __ARM_PCS_VFP
+ #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
+ #endif
+
+#elif defined ( __GNUC__ )
+ #if defined (__VFP_FP__) && !defined(__SOFTFP__)
+ #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
+ #endif
+
+#elif defined ( __ICCARM__ )
+ #if defined __ARMVFP__
+ #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
+ #endif
+
+#elif defined ( __TMS470__ )
+ #if defined __TI_VFP_SUPPORT__
+ #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
+ #endif
+
+#elif defined ( __TASKING__ )
+ #if defined __FPU_VFP__
+ #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
+ #endif
+
+#elif defined ( __CSMC__ )
+ #if ( __CSMC__ & 0x400U)
+ #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
+ #endif
+
+#endif
+
+#include "core_cmInstr.h" /* Core Instruction Access */
+#include "core_cmFunc.h" /* Core Function Access */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __CORE_SC300_H_GENERIC */
+
+#ifndef __CMSIS_GENERIC
+
+#ifndef __CORE_SC300_H_DEPENDANT
+#define __CORE_SC300_H_DEPENDANT
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+/* check device defines and use defaults */
+#if defined __CHECK_DEVICE_DEFINES
+ #ifndef __SC300_REV
+ #define __SC300_REV 0x0000U
+ #warning "__SC300_REV not defined in device header file; using default!"
+ #endif
+
+ #ifndef __MPU_PRESENT
+ #define __MPU_PRESENT 0U
+ #warning "__MPU_PRESENT not defined in device header file; using default!"
+ #endif
+
+ #ifndef __NVIC_PRIO_BITS
+ #define __NVIC_PRIO_BITS 4U
+ #warning "__NVIC_PRIO_BITS not defined in device header file; using default!"
+ #endif
+
+ #ifndef __Vendor_SysTickConfig
+ #define __Vendor_SysTickConfig 0U
+ #warning "__Vendor_SysTickConfig not defined in device header file; using default!"
+ #endif
+#endif
+
+/* IO definitions (access restrictions to peripheral registers) */
+/**
+ \defgroup CMSIS_glob_defs CMSIS Global Defines
+
+ <strong>IO Type Qualifiers</strong> are used
+ \li to specify the access to peripheral variables.
+ \li for automatic generation of peripheral register debug information.
+*/
+#ifdef __cplusplus
+ #define __I volatile /*!< Defines 'read only' permissions */
+#else
+ #define __I volatile const /*!< Defines 'read only' permissions */
+#endif
+#define __O volatile /*!< Defines 'write only' permissions */
+#define __IO volatile /*!< Defines 'read / write' permissions */
+
+/* following defines should be used for structure members */
+#define __IM volatile const /*! Defines 'read only' structure member permissions */
+#define __OM volatile /*! Defines 'write only' structure member permissions */
+#define __IOM volatile /*! Defines 'read / write' structure member permissions */
+
+/*@} end of group SC300 */
+
+
+
+/*******************************************************************************
+ * Register Abstraction
+ Core Register contain:
+ - Core Register
+ - Core NVIC Register
+ - Core SCB Register
+ - Core SysTick Register
+ - Core Debug Register
+ - Core MPU Register
+ ******************************************************************************/
+/**
+ \defgroup CMSIS_core_register Defines and Type Definitions
+ \brief Type definitions and defines for Cortex-M processor based devices.
+*/
+
+/**
+ \ingroup CMSIS_core_register
+ \defgroup CMSIS_CORE Status and Control Registers
+ \brief Core Register type definitions.
+ @{
+ */
+
+/**
+ \brief Union type to access the Application Program Status Register (APSR).
+ */
+typedef union
+{
+ struct
+ {
+ uint32_t _reserved0:27; /*!< bit: 0..26 Reserved */
+ uint32_t Q:1; /*!< bit: 27 Saturation condition flag */
+ uint32_t V:1; /*!< bit: 28 Overflow condition code flag */
+ uint32_t C:1; /*!< bit: 29 Carry condition code flag */
+ uint32_t Z:1; /*!< bit: 30 Zero condition code flag */
+ uint32_t N:1; /*!< bit: 31 Negative condition code flag */
+ } b; /*!< Structure used for bit access */
+ uint32_t w; /*!< Type used for word access */
+} APSR_Type;
+
+/* APSR Register Definitions */
+#define APSR_N_Pos 31U /*!< APSR: N Position */
+#define APSR_N_Msk (1UL << APSR_N_Pos) /*!< APSR: N Mask */
+
+#define APSR_Z_Pos 30U /*!< APSR: Z Position */
+#define APSR_Z_Msk (1UL << APSR_Z_Pos) /*!< APSR: Z Mask */
+
+#define APSR_C_Pos 29U /*!< APSR: C Position */
+#define APSR_C_Msk (1UL << APSR_C_Pos) /*!< APSR: C Mask */
+
+#define APSR_V_Pos 28U /*!< APSR: V Position */
+#define APSR_V_Msk (1UL << APSR_V_Pos) /*!< APSR: V Mask */
+
+#define APSR_Q_Pos 27U /*!< APSR: Q Position */
+#define APSR_Q_Msk (1UL << APSR_Q_Pos) /*!< APSR: Q Mask */
+
+
+/**
+ \brief Union type to access the Interrupt Program Status Register (IPSR).
+ */
+typedef union
+{
+ struct
+ {
+ uint32_t ISR:9; /*!< bit: 0.. 8 Exception number */
+ uint32_t _reserved0:23; /*!< bit: 9..31 Reserved */
+ } b; /*!< Structure used for bit access */
+ uint32_t w; /*!< Type used for word access */
+} IPSR_Type;
+
+/* IPSR Register Definitions */
+#define IPSR_ISR_Pos 0U /*!< IPSR: ISR Position */
+#define IPSR_ISR_Msk (0x1FFUL /*<< IPSR_ISR_Pos*/) /*!< IPSR: ISR Mask */
+
+
+/**
+ \brief Union type to access the Special-Purpose Program Status Registers (xPSR).
+ */
+typedef union
+{
+ struct
+ {
+ uint32_t ISR:9; /*!< bit: 0.. 8 Exception number */
+ uint32_t _reserved0:15; /*!< bit: 9..23 Reserved */
+ uint32_t T:1; /*!< bit: 24 Thumb bit (read 0) */
+ uint32_t IT:2; /*!< bit: 25..26 saved IT state (read 0) */
+ uint32_t Q:1; /*!< bit: 27 Saturation condition flag */
+ uint32_t V:1; /*!< bit: 28 Overflow condition code flag */
+ uint32_t C:1; /*!< bit: 29 Carry condition code flag */
+ uint32_t Z:1; /*!< bit: 30 Zero condition code flag */
+ uint32_t N:1; /*!< bit: 31 Negative condition code flag */
+ } b; /*!< Structure used for bit access */
+ uint32_t w; /*!< Type used for word access */
+} xPSR_Type;
+
+/* xPSR Register Definitions */
+#define xPSR_N_Pos 31U /*!< xPSR: N Position */
+#define xPSR_N_Msk (1UL << xPSR_N_Pos) /*!< xPSR: N Mask */
+
+#define xPSR_Z_Pos 30U /*!< xPSR: Z Position */
+#define xPSR_Z_Msk (1UL << xPSR_Z_Pos) /*!< xPSR: Z Mask */
+
+#define xPSR_C_Pos 29U /*!< xPSR: C Position */
+#define xPSR_C_Msk (1UL << xPSR_C_Pos) /*!< xPSR: C Mask */
+
+#define xPSR_V_Pos 28U /*!< xPSR: V Position */
+#define xPSR_V_Msk (1UL << xPSR_V_Pos) /*!< xPSR: V Mask */
+
+#define xPSR_Q_Pos 27U /*!< xPSR: Q Position */
+#define xPSR_Q_Msk (1UL << xPSR_Q_Pos) /*!< xPSR: Q Mask */
+
+#define xPSR_IT_Pos 25U /*!< xPSR: IT Position */
+#define xPSR_IT_Msk (3UL << xPSR_IT_Pos) /*!< xPSR: IT Mask */
+
+#define xPSR_T_Pos 24U /*!< xPSR: T Position */
+#define xPSR_T_Msk (1UL << xPSR_T_Pos) /*!< xPSR: T Mask */
+
+#define xPSR_ISR_Pos 0U /*!< xPSR: ISR Position */
+#define xPSR_ISR_Msk (0x1FFUL /*<< xPSR_ISR_Pos*/) /*!< xPSR: ISR Mask */
+
+
+/**
+ \brief Union type to access the Control Registers (CONTROL).
+ */
+typedef union
+{
+ struct
+ {
+ uint32_t nPRIV:1; /*!< bit: 0 Execution privilege in Thread mode */
+ uint32_t SPSEL:1; /*!< bit: 1 Stack to be used */
+ uint32_t _reserved1:30; /*!< bit: 2..31 Reserved */
+ } b; /*!< Structure used for bit access */
+ uint32_t w; /*!< Type used for word access */
+} CONTROL_Type;
+
+/* CONTROL Register Definitions */
+#define CONTROL_SPSEL_Pos 1U /*!< CONTROL: SPSEL Position */
+#define CONTROL_SPSEL_Msk (1UL << CONTROL_SPSEL_Pos) /*!< CONTROL: SPSEL Mask */
+
+#define CONTROL_nPRIV_Pos 0U /*!< CONTROL: nPRIV Position */
+#define CONTROL_nPRIV_Msk (1UL /*<< CONTROL_nPRIV_Pos*/) /*!< CONTROL: nPRIV Mask */
+
+/*@} end of group CMSIS_CORE */
+
+
+/**
+ \ingroup CMSIS_core_register
+ \defgroup CMSIS_NVIC Nested Vectored Interrupt Controller (NVIC)
+ \brief Type definitions for the NVIC Registers
+ @{
+ */
+
+/**
+ \brief Structure type to access the Nested Vectored Interrupt Controller (NVIC).
+ */
+typedef struct
+{
+ __IOM uint32_t ISER[8U]; /*!< Offset: 0x000 (R/W) Interrupt Set Enable Register */
+ uint32_t RESERVED0[24U];
+ __IOM uint32_t ICER[8U]; /*!< Offset: 0x080 (R/W) Interrupt Clear Enable Register */
+ uint32_t RSERVED1[24U];
+ __IOM uint32_t ISPR[8U]; /*!< Offset: 0x100 (R/W) Interrupt Set Pending Register */
+ uint32_t RESERVED2[24U];
+ __IOM uint32_t ICPR[8U]; /*!< Offset: 0x180 (R/W) Interrupt Clear Pending Register */
+ uint32_t RESERVED3[24U];
+ __IOM uint32_t IABR[8U]; /*!< Offset: 0x200 (R/W) Interrupt Active bit Register */
+ uint32_t RESERVED4[56U];
+ __IOM uint8_t IP[240U]; /*!< Offset: 0x300 (R/W) Interrupt Priority Register (8Bit wide) */
+ uint32_t RESERVED5[644U];
+ __OM uint32_t STIR; /*!< Offset: 0xE00 ( /W) Software Trigger Interrupt Register */
+} NVIC_Type;
+
+/* Software Triggered Interrupt Register Definitions */
+#define NVIC_STIR_INTID_Pos 0U /*!< STIR: INTLINESNUM Position */
+#define NVIC_STIR_INTID_Msk (0x1FFUL /*<< NVIC_STIR_INTID_Pos*/) /*!< STIR: INTLINESNUM Mask */
+
+/*@} end of group CMSIS_NVIC */
+
+
+/**
+ \ingroup CMSIS_core_register
+ \defgroup CMSIS_SCB System Control Block (SCB)
+ \brief Type definitions for the System Control Block Registers
+ @{
+ */
+
+/**
+ \brief Structure type to access the System Control Block (SCB).
+ */
+typedef struct
+{
+ __IM uint32_t CPUID; /*!< Offset: 0x000 (R/ ) CPUID Base Register */
+ __IOM uint32_t ICSR; /*!< Offset: 0x004 (R/W) Interrupt Control and State Register */
+ __IOM uint32_t VTOR; /*!< Offset: 0x008 (R/W) Vector Table Offset Register */
+ __IOM uint32_t AIRCR; /*!< Offset: 0x00C (R/W) Application Interrupt and Reset Control Register */
+ __IOM uint32_t SCR; /*!< Offset: 0x010 (R/W) System Control Register */
+ __IOM uint32_t CCR; /*!< Offset: 0x014 (R/W) Configuration Control Register */
+ __IOM uint8_t SHP[12U]; /*!< Offset: 0x018 (R/W) System Handlers Priority Registers (4-7, 8-11, 12-15) */
+ __IOM uint32_t SHCSR; /*!< Offset: 0x024 (R/W) System Handler Control and State Register */
+ __IOM uint32_t CFSR; /*!< Offset: 0x028 (R/W) Configurable Fault Status Register */
+ __IOM uint32_t HFSR; /*!< Offset: 0x02C (R/W) HardFault Status Register */
+ __IOM uint32_t DFSR; /*!< Offset: 0x030 (R/W) Debug Fault Status Register */
+ __IOM uint32_t MMFAR; /*!< Offset: 0x034 (R/W) MemManage Fault Address Register */
+ __IOM uint32_t BFAR; /*!< Offset: 0x038 (R/W) BusFault Address Register */
+ __IOM uint32_t AFSR; /*!< Offset: 0x03C (R/W) Auxiliary Fault Status Register */
+ __IM uint32_t PFR[2U]; /*!< Offset: 0x040 (R/ ) Processor Feature Register */
+ __IM uint32_t DFR; /*!< Offset: 0x048 (R/ ) Debug Feature Register */
+ __IM uint32_t ADR; /*!< Offset: 0x04C (R/ ) Auxiliary Feature Register */
+ __IM uint32_t MMFR[4U]; /*!< Offset: 0x050 (R/ ) Memory Model Feature Register */
+ __IM uint32_t ISAR[5U]; /*!< Offset: 0x060 (R/ ) Instruction Set Attributes Register */
+ uint32_t RESERVED0[5U];
+ __IOM uint32_t CPACR; /*!< Offset: 0x088 (R/W) Coprocessor Access Control Register */
+ uint32_t RESERVED1[129U];
+ __IOM uint32_t SFCR; /*!< Offset: 0x290 (R/W) Security Features Control Register */
+} SCB_Type;
+
+/* SCB CPUID Register Definitions */
+#define SCB_CPUID_IMPLEMENTER_Pos 24U /*!< SCB CPUID: IMPLEMENTER Position */
+#define SCB_CPUID_IMPLEMENTER_Msk (0xFFUL << SCB_CPUID_IMPLEMENTER_Pos) /*!< SCB CPUID: IMPLEMENTER Mask */
+
+#define SCB_CPUID_VARIANT_Pos 20U /*!< SCB CPUID: VARIANT Position */
+#define SCB_CPUID_VARIANT_Msk (0xFUL << SCB_CPUID_VARIANT_Pos) /*!< SCB CPUID: VARIANT Mask */
+
+#define SCB_CPUID_ARCHITECTURE_Pos 16U /*!< SCB CPUID: ARCHITECTURE Position */
+#define SCB_CPUID_ARCHITECTURE_Msk (0xFUL << SCB_CPUID_ARCHITECTURE_Pos) /*!< SCB CPUID: ARCHITECTURE Mask */
+
+#define SCB_CPUID_PARTNO_Pos 4U /*!< SCB CPUID: PARTNO Position */
+#define SCB_CPUID_PARTNO_Msk (0xFFFUL << SCB_CPUID_PARTNO_Pos) /*!< SCB CPUID: PARTNO Mask */
+
+#define SCB_CPUID_REVISION_Pos 0U /*!< SCB CPUID: REVISION Position */
+#define SCB_CPUID_REVISION_Msk (0xFUL /*<< SCB_CPUID_REVISION_Pos*/) /*!< SCB CPUID: REVISION Mask */
+
+/* SCB Interrupt Control State Register Definitions */
+#define SCB_ICSR_NMIPENDSET_Pos 31U /*!< SCB ICSR: NMIPENDSET Position */
+#define SCB_ICSR_NMIPENDSET_Msk (1UL << SCB_ICSR_NMIPENDSET_Pos) /*!< SCB ICSR: NMIPENDSET Mask */
+
+#define SCB_ICSR_PENDSVSET_Pos 28U /*!< SCB ICSR: PENDSVSET Position */
+#define SCB_ICSR_PENDSVSET_Msk (1UL << SCB_ICSR_PENDSVSET_Pos) /*!< SCB ICSR: PENDSVSET Mask */
+
+#define SCB_ICSR_PENDSVCLR_Pos 27U /*!< SCB ICSR: PENDSVCLR Position */
+#define SCB_ICSR_PENDSVCLR_Msk (1UL << SCB_ICSR_PENDSVCLR_Pos) /*!< SCB ICSR: PENDSVCLR Mask */
+
+#define SCB_ICSR_PENDSTSET_Pos 26U /*!< SCB ICSR: PENDSTSET Position */
+#define SCB_ICSR_PENDSTSET_Msk (1UL << SCB_ICSR_PENDSTSET_Pos) /*!< SCB ICSR: PENDSTSET Mask */
+
+#define SCB_ICSR_PENDSTCLR_Pos 25U /*!< SCB ICSR: PENDSTCLR Position */
+#define SCB_ICSR_PENDSTCLR_Msk (1UL << SCB_ICSR_PENDSTCLR_Pos) /*!< SCB ICSR: PENDSTCLR Mask */
+
+#define SCB_ICSR_ISRPREEMPT_Pos 23U /*!< SCB ICSR: ISRPREEMPT Position */
+#define SCB_ICSR_ISRPREEMPT_Msk (1UL << SCB_ICSR_ISRPREEMPT_Pos) /*!< SCB ICSR: ISRPREEMPT Mask */
+
+#define SCB_ICSR_ISRPENDING_Pos 22U /*!< SCB ICSR: ISRPENDING Position */
+#define SCB_ICSR_ISRPENDING_Msk (1UL << SCB_ICSR_ISRPENDING_Pos) /*!< SCB ICSR: ISRPENDING Mask */
+
+#define SCB_ICSR_VECTPENDING_Pos 12U /*!< SCB ICSR: VECTPENDING Position */
+#define SCB_ICSR_VECTPENDING_Msk (0x1FFUL << SCB_ICSR_VECTPENDING_Pos) /*!< SCB ICSR: VECTPENDING Mask */
+
+#define SCB_ICSR_RETTOBASE_Pos 11U /*!< SCB ICSR: RETTOBASE Position */
+#define SCB_ICSR_RETTOBASE_Msk (1UL << SCB_ICSR_RETTOBASE_Pos) /*!< SCB ICSR: RETTOBASE Mask */
+
+#define SCB_ICSR_VECTACTIVE_Pos 0U /*!< SCB ICSR: VECTACTIVE Position */
+#define SCB_ICSR_VECTACTIVE_Msk (0x1FFUL /*<< SCB_ICSR_VECTACTIVE_Pos*/) /*!< SCB ICSR: VECTACTIVE Mask */
+
+/* SCB Vector Table Offset Register Definitions */
+#define SCB_VTOR_TBLBASE_Pos 29U /*!< SCB VTOR: TBLBASE Position */
+#define SCB_VTOR_TBLBASE_Msk (1UL << SCB_VTOR_TBLBASE_Pos) /*!< SCB VTOR: TBLBASE Mask */
+
+#define SCB_VTOR_TBLOFF_Pos 7U /*!< SCB VTOR: TBLOFF Position */
+#define SCB_VTOR_TBLOFF_Msk (0x3FFFFFUL << SCB_VTOR_TBLOFF_Pos) /*!< SCB VTOR: TBLOFF Mask */
+
+/* SCB Application Interrupt and Reset Control Register Definitions */
+#define SCB_AIRCR_VECTKEY_Pos 16U /*!< SCB AIRCR: VECTKEY Position */
+#define SCB_AIRCR_VECTKEY_Msk (0xFFFFUL << SCB_AIRCR_VECTKEY_Pos) /*!< SCB AIRCR: VECTKEY Mask */
+
+#define SCB_AIRCR_VECTKEYSTAT_Pos 16U /*!< SCB AIRCR: VECTKEYSTAT Position */
+#define SCB_AIRCR_VECTKEYSTAT_Msk (0xFFFFUL << SCB_AIRCR_VECTKEYSTAT_Pos) /*!< SCB AIRCR: VECTKEYSTAT Mask */
+
+#define SCB_AIRCR_ENDIANESS_Pos 15U /*!< SCB AIRCR: ENDIANESS Position */
+#define SCB_AIRCR_ENDIANESS_Msk (1UL << SCB_AIRCR_ENDIANESS_Pos) /*!< SCB AIRCR: ENDIANESS Mask */
+
+#define SCB_AIRCR_PRIGROUP_Pos 8U /*!< SCB AIRCR: PRIGROUP Position */
+#define SCB_AIRCR_PRIGROUP_Msk (7UL << SCB_AIRCR_PRIGROUP_Pos) /*!< SCB AIRCR: PRIGROUP Mask */
+
+#define SCB_AIRCR_SYSRESETREQ_Pos 2U /*!< SCB AIRCR: SYSRESETREQ Position */
+#define SCB_AIRCR_SYSRESETREQ_Msk (1UL << SCB_AIRCR_SYSRESETREQ_Pos) /*!< SCB AIRCR: SYSRESETREQ Mask */
+
+#define SCB_AIRCR_VECTCLRACTIVE_Pos 1U /*!< SCB AIRCR: VECTCLRACTIVE Position */
+#define SCB_AIRCR_VECTCLRACTIVE_Msk (1UL << SCB_AIRCR_VECTCLRACTIVE_Pos) /*!< SCB AIRCR: VECTCLRACTIVE Mask */
+
+#define SCB_AIRCR_VECTRESET_Pos 0U /*!< SCB AIRCR: VECTRESET Position */
+#define SCB_AIRCR_VECTRESET_Msk (1UL /*<< SCB_AIRCR_VECTRESET_Pos*/) /*!< SCB AIRCR: VECTRESET Mask */
+
+/* SCB System Control Register Definitions */
+#define SCB_SCR_SEVONPEND_Pos 4U /*!< SCB SCR: SEVONPEND Position */
+#define SCB_SCR_SEVONPEND_Msk (1UL << SCB_SCR_SEVONPEND_Pos) /*!< SCB SCR: SEVONPEND Mask */
+
+#define SCB_SCR_SLEEPDEEP_Pos 2U /*!< SCB SCR: SLEEPDEEP Position */
+#define SCB_SCR_SLEEPDEEP_Msk (1UL << SCB_SCR_SLEEPDEEP_Pos) /*!< SCB SCR: SLEEPDEEP Mask */
+
+#define SCB_SCR_SLEEPONEXIT_Pos 1U /*!< SCB SCR: SLEEPONEXIT Position */
+#define SCB_SCR_SLEEPONEXIT_Msk (1UL << SCB_SCR_SLEEPONEXIT_Pos) /*!< SCB SCR: SLEEPONEXIT Mask */
+
+/* SCB Configuration Control Register Definitions */
+#define SCB_CCR_STKALIGN_Pos 9U /*!< SCB CCR: STKALIGN Position */
+#define SCB_CCR_STKALIGN_Msk (1UL << SCB_CCR_STKALIGN_Pos) /*!< SCB CCR: STKALIGN Mask */
+
+#define SCB_CCR_BFHFNMIGN_Pos 8U /*!< SCB CCR: BFHFNMIGN Position */
+#define SCB_CCR_BFHFNMIGN_Msk (1UL << SCB_CCR_BFHFNMIGN_Pos) /*!< SCB CCR: BFHFNMIGN Mask */
+
+#define SCB_CCR_DIV_0_TRP_Pos 4U /*!< SCB CCR: DIV_0_TRP Position */
+#define SCB_CCR_DIV_0_TRP_Msk (1UL << SCB_CCR_DIV_0_TRP_Pos) /*!< SCB CCR: DIV_0_TRP Mask */
+
+#define SCB_CCR_UNALIGN_TRP_Pos 3U /*!< SCB CCR: UNALIGN_TRP Position */
+#define SCB_CCR_UNALIGN_TRP_Msk (1UL << SCB_CCR_UNALIGN_TRP_Pos) /*!< SCB CCR: UNALIGN_TRP Mask */
+
+#define SCB_CCR_USERSETMPEND_Pos 1U /*!< SCB CCR: USERSETMPEND Position */
+#define SCB_CCR_USERSETMPEND_Msk (1UL << SCB_CCR_USERSETMPEND_Pos) /*!< SCB CCR: USERSETMPEND Mask */
+
+#define SCB_CCR_NONBASETHRDENA_Pos 0U /*!< SCB CCR: NONBASETHRDENA Position */
+#define SCB_CCR_NONBASETHRDENA_Msk (1UL /*<< SCB_CCR_NONBASETHRDENA_Pos*/) /*!< SCB CCR: NONBASETHRDENA Mask */
+
+/* SCB System Handler Control and State Register Definitions */
+#define SCB_SHCSR_USGFAULTENA_Pos 18U /*!< SCB SHCSR: USGFAULTENA Position */
+#define SCB_SHCSR_USGFAULTENA_Msk (1UL << SCB_SHCSR_USGFAULTENA_Pos) /*!< SCB SHCSR: USGFAULTENA Mask */
+
+#define SCB_SHCSR_BUSFAULTENA_Pos 17U /*!< SCB SHCSR: BUSFAULTENA Position */
+#define SCB_SHCSR_BUSFAULTENA_Msk (1UL << SCB_SHCSR_BUSFAULTENA_Pos) /*!< SCB SHCSR: BUSFAULTENA Mask */
+
+#define SCB_SHCSR_MEMFAULTENA_Pos 16U /*!< SCB SHCSR: MEMFAULTENA Position */
+#define SCB_SHCSR_MEMFAULTENA_Msk (1UL << SCB_SHCSR_MEMFAULTENA_Pos) /*!< SCB SHCSR: MEMFAULTENA Mask */
+
+#define SCB_SHCSR_SVCALLPENDED_Pos 15U /*!< SCB SHCSR: SVCALLPENDED Position */
+#define SCB_SHCSR_SVCALLPENDED_Msk (1UL << SCB_SHCSR_SVCALLPENDED_Pos) /*!< SCB SHCSR: SVCALLPENDED Mask */
+
+#define SCB_SHCSR_BUSFAULTPENDED_Pos 14U /*!< SCB SHCSR: BUSFAULTPENDED Position */
+#define SCB_SHCSR_BUSFAULTPENDED_Msk (1UL << SCB_SHCSR_BUSFAULTPENDED_Pos) /*!< SCB SHCSR: BUSFAULTPENDED Mask */
+
+#define SCB_SHCSR_MEMFAULTPENDED_Pos 13U /*!< SCB SHCSR: MEMFAULTPENDED Position */
+#define SCB_SHCSR_MEMFAULTPENDED_Msk (1UL << SCB_SHCSR_MEMFAULTPENDED_Pos) /*!< SCB SHCSR: MEMFAULTPENDED Mask */
+
+#define SCB_SHCSR_USGFAULTPENDED_Pos 12U /*!< SCB SHCSR: USGFAULTPENDED Position */
+#define SCB_SHCSR_USGFAULTPENDED_Msk (1UL << SCB_SHCSR_USGFAULTPENDED_Pos) /*!< SCB SHCSR: USGFAULTPENDED Mask */
+
+#define SCB_SHCSR_SYSTICKACT_Pos 11U /*!< SCB SHCSR: SYSTICKACT Position */
+#define SCB_SHCSR_SYSTICKACT_Msk (1UL << SCB_SHCSR_SYSTICKACT_Pos) /*!< SCB SHCSR: SYSTICKACT Mask */
+
+#define SCB_SHCSR_PENDSVACT_Pos 10U /*!< SCB SHCSR: PENDSVACT Position */
+#define SCB_SHCSR_PENDSVACT_Msk (1UL << SCB_SHCSR_PENDSVACT_Pos) /*!< SCB SHCSR: PENDSVACT Mask */
+
+#define SCB_SHCSR_MONITORACT_Pos 8U /*!< SCB SHCSR: MONITORACT Position */
+#define SCB_SHCSR_MONITORACT_Msk (1UL << SCB_SHCSR_MONITORACT_Pos) /*!< SCB SHCSR: MONITORACT Mask */
+
+#define SCB_SHCSR_SVCALLACT_Pos 7U /*!< SCB SHCSR: SVCALLACT Position */
+#define SCB_SHCSR_SVCALLACT_Msk (1UL << SCB_SHCSR_SVCALLACT_Pos) /*!< SCB SHCSR: SVCALLACT Mask */
+
+#define SCB_SHCSR_USGFAULTACT_Pos 3U /*!< SCB SHCSR: USGFAULTACT Position */
+#define SCB_SHCSR_USGFAULTACT_Msk (1UL << SCB_SHCSR_USGFAULTACT_Pos) /*!< SCB SHCSR: USGFAULTACT Mask */
+
+#define SCB_SHCSR_BUSFAULTACT_Pos 1U /*!< SCB SHCSR: BUSFAULTACT Position */
+#define SCB_SHCSR_BUSFAULTACT_Msk (1UL << SCB_SHCSR_BUSFAULTACT_Pos) /*!< SCB SHCSR: BUSFAULTACT Mask */
+
+#define SCB_SHCSR_MEMFAULTACT_Pos 0U /*!< SCB SHCSR: MEMFAULTACT Position */
+#define SCB_SHCSR_MEMFAULTACT_Msk (1UL /*<< SCB_SHCSR_MEMFAULTACT_Pos*/) /*!< SCB SHCSR: MEMFAULTACT Mask */
+
+/* SCB Configurable Fault Status Register Definitions */
+#define SCB_CFSR_USGFAULTSR_Pos 16U /*!< SCB CFSR: Usage Fault Status Register Position */
+#define SCB_CFSR_USGFAULTSR_Msk (0xFFFFUL << SCB_CFSR_USGFAULTSR_Pos) /*!< SCB CFSR: Usage Fault Status Register Mask */
+
+#define SCB_CFSR_BUSFAULTSR_Pos 8U /*!< SCB CFSR: Bus Fault Status Register Position */
+#define SCB_CFSR_BUSFAULTSR_Msk (0xFFUL << SCB_CFSR_BUSFAULTSR_Pos) /*!< SCB CFSR: Bus Fault Status Register Mask */
+
+#define SCB_CFSR_MEMFAULTSR_Pos 0U /*!< SCB CFSR: Memory Manage Fault Status Register Position */
+#define SCB_CFSR_MEMFAULTSR_Msk (0xFFUL /*<< SCB_CFSR_MEMFAULTSR_Pos*/) /*!< SCB CFSR: Memory Manage Fault Status Register Mask */
+
+/* SCB Hard Fault Status Register Definitions */
+#define SCB_HFSR_DEBUGEVT_Pos 31U /*!< SCB HFSR: DEBUGEVT Position */
+#define SCB_HFSR_DEBUGEVT_Msk (1UL << SCB_HFSR_DEBUGEVT_Pos) /*!< SCB HFSR: DEBUGEVT Mask */
+
+#define SCB_HFSR_FORCED_Pos 30U /*!< SCB HFSR: FORCED Position */
+#define SCB_HFSR_FORCED_Msk (1UL << SCB_HFSR_FORCED_Pos) /*!< SCB HFSR: FORCED Mask */
+
+#define SCB_HFSR_VECTTBL_Pos 1U /*!< SCB HFSR: VECTTBL Position */
+#define SCB_HFSR_VECTTBL_Msk (1UL << SCB_HFSR_VECTTBL_Pos) /*!< SCB HFSR: VECTTBL Mask */
+
+/* SCB Debug Fault Status Register Definitions */
+#define SCB_DFSR_EXTERNAL_Pos 4U /*!< SCB DFSR: EXTERNAL Position */
+#define SCB_DFSR_EXTERNAL_Msk (1UL << SCB_DFSR_EXTERNAL_Pos) /*!< SCB DFSR: EXTERNAL Mask */
+
+#define SCB_DFSR_VCATCH_Pos 3U /*!< SCB DFSR: VCATCH Position */
+#define SCB_DFSR_VCATCH_Msk (1UL << SCB_DFSR_VCATCH_Pos) /*!< SCB DFSR: VCATCH Mask */
+
+#define SCB_DFSR_DWTTRAP_Pos 2U /*!< SCB DFSR: DWTTRAP Position */
+#define SCB_DFSR_DWTTRAP_Msk (1UL << SCB_DFSR_DWTTRAP_Pos) /*!< SCB DFSR: DWTTRAP Mask */
+
+#define SCB_DFSR_BKPT_Pos 1U /*!< SCB DFSR: BKPT Position */
+#define SCB_DFSR_BKPT_Msk (1UL << SCB_DFSR_BKPT_Pos) /*!< SCB DFSR: BKPT Mask */
+
+#define SCB_DFSR_HALTED_Pos 0U /*!< SCB DFSR: HALTED Position */
+#define SCB_DFSR_HALTED_Msk (1UL /*<< SCB_DFSR_HALTED_Pos*/) /*!< SCB DFSR: HALTED Mask */
+
+/*@} end of group CMSIS_SCB */
+
+
+/**
+ \ingroup CMSIS_core_register
+ \defgroup CMSIS_SCnSCB System Controls not in SCB (SCnSCB)
+ \brief Type definitions for the System Control and ID Register not in the SCB
+ @{
+ */
+
+/**
+ \brief Structure type to access the System Control and ID Register not in the SCB.
+ */
+typedef struct
+{
+ uint32_t RESERVED0[1U];
+ __IM uint32_t ICTR; /*!< Offset: 0x004 (R/ ) Interrupt Controller Type Register */
+ uint32_t RESERVED1[1U];
+} SCnSCB_Type;
+
+/* Interrupt Controller Type Register Definitions */
+#define SCnSCB_ICTR_INTLINESNUM_Pos 0U /*!< ICTR: INTLINESNUM Position */
+#define SCnSCB_ICTR_INTLINESNUM_Msk (0xFUL /*<< SCnSCB_ICTR_INTLINESNUM_Pos*/) /*!< ICTR: INTLINESNUM Mask */
+
+/*@} end of group CMSIS_SCnotSCB */
+
+
+/**
+ \ingroup CMSIS_core_register
+ \defgroup CMSIS_SysTick System Tick Timer (SysTick)
+ \brief Type definitions for the System Timer Registers.
+ @{
+ */
+
+/**
+ \brief Structure type to access the System Timer (SysTick).
+ */
+typedef struct
+{
+ __IOM uint32_t CTRL; /*!< Offset: 0x000 (R/W) SysTick Control and Status Register */
+ __IOM uint32_t LOAD; /*!< Offset: 0x004 (R/W) SysTick Reload Value Register */
+ __IOM uint32_t VAL; /*!< Offset: 0x008 (R/W) SysTick Current Value Register */
+ __IM uint32_t CALIB; /*!< Offset: 0x00C (R/ ) SysTick Calibration Register */
+} SysTick_Type;
+
+/* SysTick Control / Status Register Definitions */
+#define SysTick_CTRL_COUNTFLAG_Pos 16U /*!< SysTick CTRL: COUNTFLAG Position */
+#define SysTick_CTRL_COUNTFLAG_Msk (1UL << SysTick_CTRL_COUNTFLAG_Pos) /*!< SysTick CTRL: COUNTFLAG Mask */
+
+#define SysTick_CTRL_CLKSOURCE_Pos 2U /*!< SysTick CTRL: CLKSOURCE Position */
+#define SysTick_CTRL_CLKSOURCE_Msk (1UL << SysTick_CTRL_CLKSOURCE_Pos) /*!< SysTick CTRL: CLKSOURCE Mask */
+
+#define SysTick_CTRL_TICKINT_Pos 1U /*!< SysTick CTRL: TICKINT Position */
+#define SysTick_CTRL_TICKINT_Msk (1UL << SysTick_CTRL_TICKINT_Pos) /*!< SysTick CTRL: TICKINT Mask */
+
+#define SysTick_CTRL_ENABLE_Pos 0U /*!< SysTick CTRL: ENABLE Position */
+#define SysTick_CTRL_ENABLE_Msk (1UL /*<< SysTick_CTRL_ENABLE_Pos*/) /*!< SysTick CTRL: ENABLE Mask */
+
+/* SysTick Reload Register Definitions */
+#define SysTick_LOAD_RELOAD_Pos 0U /*!< SysTick LOAD: RELOAD Position */
+#define SysTick_LOAD_RELOAD_Msk (0xFFFFFFUL /*<< SysTick_LOAD_RELOAD_Pos*/) /*!< SysTick LOAD: RELOAD Mask */
+
+/* SysTick Current Register Definitions */
+#define SysTick_VAL_CURRENT_Pos 0U /*!< SysTick VAL: CURRENT Position */
+#define SysTick_VAL_CURRENT_Msk (0xFFFFFFUL /*<< SysTick_VAL_CURRENT_Pos*/) /*!< SysTick VAL: CURRENT Mask */
+
+/* SysTick Calibration Register Definitions */
+#define SysTick_CALIB_NOREF_Pos 31U /*!< SysTick CALIB: NOREF Position */
+#define SysTick_CALIB_NOREF_Msk (1UL << SysTick_CALIB_NOREF_Pos) /*!< SysTick CALIB: NOREF Mask */
+
+#define SysTick_CALIB_SKEW_Pos 30U /*!< SysTick CALIB: SKEW Position */
+#define SysTick_CALIB_SKEW_Msk (1UL << SysTick_CALIB_SKEW_Pos) /*!< SysTick CALIB: SKEW Mask */
+
+#define SysTick_CALIB_TENMS_Pos 0U /*!< SysTick CALIB: TENMS Position */
+#define SysTick_CALIB_TENMS_Msk (0xFFFFFFUL /*<< SysTick_CALIB_TENMS_Pos*/) /*!< SysTick CALIB: TENMS Mask */
+
+/*@} end of group CMSIS_SysTick */
+
+
+/**
+ \ingroup CMSIS_core_register
+ \defgroup CMSIS_ITM Instrumentation Trace Macrocell (ITM)
+ \brief Type definitions for the Instrumentation Trace Macrocell (ITM)
+ @{
+ */
+
+/**
+ \brief Structure type to access the Instrumentation Trace Macrocell Register (ITM).
+ */
+typedef struct
+{
+ __OM union
+ {
+ __OM uint8_t u8; /*!< Offset: 0x000 ( /W) ITM Stimulus Port 8-bit */
+ __OM uint16_t u16; /*!< Offset: 0x000 ( /W) ITM Stimulus Port 16-bit */
+ __OM uint32_t u32; /*!< Offset: 0x000 ( /W) ITM Stimulus Port 32-bit */
+ } PORT [32U]; /*!< Offset: 0x000 ( /W) ITM Stimulus Port Registers */
+ uint32_t RESERVED0[864U];
+ __IOM uint32_t TER; /*!< Offset: 0xE00 (R/W) ITM Trace Enable Register */
+ uint32_t RESERVED1[15U];
+ __IOM uint32_t TPR; /*!< Offset: 0xE40 (R/W) ITM Trace Privilege Register */
+ uint32_t RESERVED2[15U];
+ __IOM uint32_t TCR; /*!< Offset: 0xE80 (R/W) ITM Trace Control Register */
+ uint32_t RESERVED3[29U];
+ __OM uint32_t IWR; /*!< Offset: 0xEF8 ( /W) ITM Integration Write Register */
+ __IM uint32_t IRR; /*!< Offset: 0xEFC (R/ ) ITM Integration Read Register */
+ __IOM uint32_t IMCR; /*!< Offset: 0xF00 (R/W) ITM Integration Mode Control Register */
+ uint32_t RESERVED4[43U];
+ __OM uint32_t LAR; /*!< Offset: 0xFB0 ( /W) ITM Lock Access Register */
+ __IM uint32_t LSR; /*!< Offset: 0xFB4 (R/ ) ITM Lock Status Register */
+ uint32_t RESERVED5[6U];
+ __IM uint32_t PID4; /*!< Offset: 0xFD0 (R/ ) ITM Peripheral Identification Register #4 */
+ __IM uint32_t PID5; /*!< Offset: 0xFD4 (R/ ) ITM Peripheral Identification Register #5 */
+ __IM uint32_t PID6; /*!< Offset: 0xFD8 (R/ ) ITM Peripheral Identification Register #6 */
+ __IM uint32_t PID7; /*!< Offset: 0xFDC (R/ ) ITM Peripheral Identification Register #7 */
+ __IM uint32_t PID0; /*!< Offset: 0xFE0 (R/ ) ITM Peripheral Identification Register #0 */
+ __IM uint32_t PID1; /*!< Offset: 0xFE4 (R/ ) ITM Peripheral Identification Register #1 */
+ __IM uint32_t PID2; /*!< Offset: 0xFE8 (R/ ) ITM Peripheral Identification Register #2 */
+ __IM uint32_t PID3; /*!< Offset: 0xFEC (R/ ) ITM Peripheral Identification Register #3 */
+ __IM uint32_t CID0; /*!< Offset: 0xFF0 (R/ ) ITM Component Identification Register #0 */
+ __IM uint32_t CID1; /*!< Offset: 0xFF4 (R/ ) ITM Component Identification Register #1 */
+ __IM uint32_t CID2; /*!< Offset: 0xFF8 (R/ ) ITM Component Identification Register #2 */
+ __IM uint32_t CID3; /*!< Offset: 0xFFC (R/ ) ITM Component Identification Register #3 */
+} ITM_Type;
+
+/* ITM Trace Privilege Register Definitions */
+#define ITM_TPR_PRIVMASK_Pos 0U /*!< ITM TPR: PRIVMASK Position */
+#define ITM_TPR_PRIVMASK_Msk (0xFUL /*<< ITM_TPR_PRIVMASK_Pos*/) /*!< ITM TPR: PRIVMASK Mask */
+
+/* ITM Trace Control Register Definitions */
+#define ITM_TCR_BUSY_Pos 23U /*!< ITM TCR: BUSY Position */
+#define ITM_TCR_BUSY_Msk (1UL << ITM_TCR_BUSY_Pos) /*!< ITM TCR: BUSY Mask */
+
+#define ITM_TCR_TraceBusID_Pos 16U /*!< ITM TCR: ATBID Position */
+#define ITM_TCR_TraceBusID_Msk (0x7FUL << ITM_TCR_TraceBusID_Pos) /*!< ITM TCR: ATBID Mask */
+
+#define ITM_TCR_GTSFREQ_Pos 10U /*!< ITM TCR: Global timestamp frequency Position */
+#define ITM_TCR_GTSFREQ_Msk (3UL << ITM_TCR_GTSFREQ_Pos) /*!< ITM TCR: Global timestamp frequency Mask */
+
+#define ITM_TCR_TSPrescale_Pos 8U /*!< ITM TCR: TSPrescale Position */
+#define ITM_TCR_TSPrescale_Msk (3UL << ITM_TCR_TSPrescale_Pos) /*!< ITM TCR: TSPrescale Mask */
+
+#define ITM_TCR_SWOENA_Pos 4U /*!< ITM TCR: SWOENA Position */
+#define ITM_TCR_SWOENA_Msk (1UL << ITM_TCR_SWOENA_Pos) /*!< ITM TCR: SWOENA Mask */
+
+#define ITM_TCR_DWTENA_Pos 3U /*!< ITM TCR: DWTENA Position */
+#define ITM_TCR_DWTENA_Msk (1UL << ITM_TCR_DWTENA_Pos) /*!< ITM TCR: DWTENA Mask */
+
+#define ITM_TCR_SYNCENA_Pos 2U /*!< ITM TCR: SYNCENA Position */
+#define ITM_TCR_SYNCENA_Msk (1UL << ITM_TCR_SYNCENA_Pos) /*!< ITM TCR: SYNCENA Mask */
+
+#define ITM_TCR_TSENA_Pos 1U /*!< ITM TCR: TSENA Position */
+#define ITM_TCR_TSENA_Msk (1UL << ITM_TCR_TSENA_Pos) /*!< ITM TCR: TSENA Mask */
+
+#define ITM_TCR_ITMENA_Pos 0U /*!< ITM TCR: ITM Enable bit Position */
+#define ITM_TCR_ITMENA_Msk (1UL /*<< ITM_TCR_ITMENA_Pos*/) /*!< ITM TCR: ITM Enable bit Mask */
+
+/* ITM Integration Write Register Definitions */
+#define ITM_IWR_ATVALIDM_Pos 0U /*!< ITM IWR: ATVALIDM Position */
+#define ITM_IWR_ATVALIDM_Msk (1UL /*<< ITM_IWR_ATVALIDM_Pos*/) /*!< ITM IWR: ATVALIDM Mask */
+
+/* ITM Integration Read Register Definitions */
+#define ITM_IRR_ATREADYM_Pos 0U /*!< ITM IRR: ATREADYM Position */
+#define ITM_IRR_ATREADYM_Msk (1UL /*<< ITM_IRR_ATREADYM_Pos*/) /*!< ITM IRR: ATREADYM Mask */
+
+/* ITM Integration Mode Control Register Definitions */
+#define ITM_IMCR_INTEGRATION_Pos 0U /*!< ITM IMCR: INTEGRATION Position */
+#define ITM_IMCR_INTEGRATION_Msk (1UL /*<< ITM_IMCR_INTEGRATION_Pos*/) /*!< ITM IMCR: INTEGRATION Mask */
+
+/* ITM Lock Status Register Definitions */
+#define ITM_LSR_ByteAcc_Pos 2U /*!< ITM LSR: ByteAcc Position */
+#define ITM_LSR_ByteAcc_Msk (1UL << ITM_LSR_ByteAcc_Pos) /*!< ITM LSR: ByteAcc Mask */
+
+#define ITM_LSR_Access_Pos 1U /*!< ITM LSR: Access Position */
+#define ITM_LSR_Access_Msk (1UL << ITM_LSR_Access_Pos) /*!< ITM LSR: Access Mask */
+
+#define ITM_LSR_Present_Pos 0U /*!< ITM LSR: Present Position */
+#define ITM_LSR_Present_Msk (1UL /*<< ITM_LSR_Present_Pos*/) /*!< ITM LSR: Present Mask */
+
+/*@}*/ /* end of group CMSIS_ITM */
+
+
+/**
+ \ingroup CMSIS_core_register
+ \defgroup CMSIS_DWT Data Watchpoint and Trace (DWT)
+ \brief Type definitions for the Data Watchpoint and Trace (DWT)
+ @{
+ */
+
+/**
+ \brief Structure type to access the Data Watchpoint and Trace Register (DWT).
+ */
+typedef struct
+{
+ __IOM uint32_t CTRL; /*!< Offset: 0x000 (R/W) Control Register */
+ __IOM uint32_t CYCCNT; /*!< Offset: 0x004 (R/W) Cycle Count Register */
+ __IOM uint32_t CPICNT; /*!< Offset: 0x008 (R/W) CPI Count Register */
+ __IOM uint32_t EXCCNT; /*!< Offset: 0x00C (R/W) Exception Overhead Count Register */
+ __IOM uint32_t SLEEPCNT; /*!< Offset: 0x010 (R/W) Sleep Count Register */
+ __IOM uint32_t LSUCNT; /*!< Offset: 0x014 (R/W) LSU Count Register */
+ __IOM uint32_t FOLDCNT; /*!< Offset: 0x018 (R/W) Folded-instruction Count Register */
+ __IM uint32_t PCSR; /*!< Offset: 0x01C (R/ ) Program Counter Sample Register */
+ __IOM uint32_t COMP0; /*!< Offset: 0x020 (R/W) Comparator Register 0 */
+ __IOM uint32_t MASK0; /*!< Offset: 0x024 (R/W) Mask Register 0 */
+ __IOM uint32_t FUNCTION0; /*!< Offset: 0x028 (R/W) Function Register 0 */
+ uint32_t RESERVED0[1U];
+ __IOM uint32_t COMP1; /*!< Offset: 0x030 (R/W) Comparator Register 1 */
+ __IOM uint32_t MASK1; /*!< Offset: 0x034 (R/W) Mask Register 1 */
+ __IOM uint32_t FUNCTION1; /*!< Offset: 0x038 (R/W) Function Register 1 */
+ uint32_t RESERVED1[1U];
+ __IOM uint32_t COMP2; /*!< Offset: 0x040 (R/W) Comparator Register 2 */
+ __IOM uint32_t MASK2; /*!< Offset: 0x044 (R/W) Mask Register 2 */
+ __IOM uint32_t FUNCTION2; /*!< Offset: 0x048 (R/W) Function Register 2 */
+ uint32_t RESERVED2[1U];
+ __IOM uint32_t COMP3; /*!< Offset: 0x050 (R/W) Comparator Register 3 */
+ __IOM uint32_t MASK3; /*!< Offset: 0x054 (R/W) Mask Register 3 */
+ __IOM uint32_t FUNCTION3; /*!< Offset: 0x058 (R/W) Function Register 3 */
+} DWT_Type;
+
+/* DWT Control Register Definitions */
+#define DWT_CTRL_NUMCOMP_Pos 28U /*!< DWT CTRL: NUMCOMP Position */
+#define DWT_CTRL_NUMCOMP_Msk (0xFUL << DWT_CTRL_NUMCOMP_Pos) /*!< DWT CTRL: NUMCOMP Mask */
+
+#define DWT_CTRL_NOTRCPKT_Pos 27U /*!< DWT CTRL: NOTRCPKT Position */
+#define DWT_CTRL_NOTRCPKT_Msk (0x1UL << DWT_CTRL_NOTRCPKT_Pos) /*!< DWT CTRL: NOTRCPKT Mask */
+
+#define DWT_CTRL_NOEXTTRIG_Pos 26U /*!< DWT CTRL: NOEXTTRIG Position */
+#define DWT_CTRL_NOEXTTRIG_Msk (0x1UL << DWT_CTRL_NOEXTTRIG_Pos) /*!< DWT CTRL: NOEXTTRIG Mask */
+
+#define DWT_CTRL_NOCYCCNT_Pos 25U /*!< DWT CTRL: NOCYCCNT Position */
+#define DWT_CTRL_NOCYCCNT_Msk (0x1UL << DWT_CTRL_NOCYCCNT_Pos) /*!< DWT CTRL: NOCYCCNT Mask */
+
+#define DWT_CTRL_NOPRFCNT_Pos 24U /*!< DWT CTRL: NOPRFCNT Position */
+#define DWT_CTRL_NOPRFCNT_Msk (0x1UL << DWT_CTRL_NOPRFCNT_Pos) /*!< DWT CTRL: NOPRFCNT Mask */
+
+#define DWT_CTRL_CYCEVTENA_Pos 22U /*!< DWT CTRL: CYCEVTENA Position */
+#define DWT_CTRL_CYCEVTENA_Msk (0x1UL << DWT_CTRL_CYCEVTENA_Pos) /*!< DWT CTRL: CYCEVTENA Mask */
+
+#define DWT_CTRL_FOLDEVTENA_Pos 21U /*!< DWT CTRL: FOLDEVTENA Position */
+#define DWT_CTRL_FOLDEVTENA_Msk (0x1UL << DWT_CTRL_FOLDEVTENA_Pos) /*!< DWT CTRL: FOLDEVTENA Mask */
+
+#define DWT_CTRL_LSUEVTENA_Pos 20U /*!< DWT CTRL: LSUEVTENA Position */
+#define DWT_CTRL_LSUEVTENA_Msk (0x1UL << DWT_CTRL_LSUEVTENA_Pos) /*!< DWT CTRL: LSUEVTENA Mask */
+
+#define DWT_CTRL_SLEEPEVTENA_Pos 19U /*!< DWT CTRL: SLEEPEVTENA Position */
+#define DWT_CTRL_SLEEPEVTENA_Msk (0x1UL << DWT_CTRL_SLEEPEVTENA_Pos) /*!< DWT CTRL: SLEEPEVTENA Mask */
+
+#define DWT_CTRL_EXCEVTENA_Pos 18U /*!< DWT CTRL: EXCEVTENA Position */
+#define DWT_CTRL_EXCEVTENA_Msk (0x1UL << DWT_CTRL_EXCEVTENA_Pos) /*!< DWT CTRL: EXCEVTENA Mask */
+
+#define DWT_CTRL_CPIEVTENA_Pos 17U /*!< DWT CTRL: CPIEVTENA Position */
+#define DWT_CTRL_CPIEVTENA_Msk (0x1UL << DWT_CTRL_CPIEVTENA_Pos) /*!< DWT CTRL: CPIEVTENA Mask */
+
+#define DWT_CTRL_EXCTRCENA_Pos 16U /*!< DWT CTRL: EXCTRCENA Position */
+#define DWT_CTRL_EXCTRCENA_Msk (0x1UL << DWT_CTRL_EXCTRCENA_Pos) /*!< DWT CTRL: EXCTRCENA Mask */
+
+#define DWT_CTRL_PCSAMPLENA_Pos 12U /*!< DWT CTRL: PCSAMPLENA Position */
+#define DWT_CTRL_PCSAMPLENA_Msk (0x1UL << DWT_CTRL_PCSAMPLENA_Pos) /*!< DWT CTRL: PCSAMPLENA Mask */
+
+#define DWT_CTRL_SYNCTAP_Pos 10U /*!< DWT CTRL: SYNCTAP Position */
+#define DWT_CTRL_SYNCTAP_Msk (0x3UL << DWT_CTRL_SYNCTAP_Pos) /*!< DWT CTRL: SYNCTAP Mask */
+
+#define DWT_CTRL_CYCTAP_Pos 9U /*!< DWT CTRL: CYCTAP Position */
+#define DWT_CTRL_CYCTAP_Msk (0x1UL << DWT_CTRL_CYCTAP_Pos) /*!< DWT CTRL: CYCTAP Mask */
+
+#define DWT_CTRL_POSTINIT_Pos 5U /*!< DWT CTRL: POSTINIT Position */
+#define DWT_CTRL_POSTINIT_Msk (0xFUL << DWT_CTRL_POSTINIT_Pos) /*!< DWT CTRL: POSTINIT Mask */
+
+#define DWT_CTRL_POSTPRESET_Pos 1U /*!< DWT CTRL: POSTPRESET Position */
+#define DWT_CTRL_POSTPRESET_Msk (0xFUL << DWT_CTRL_POSTPRESET_Pos) /*!< DWT CTRL: POSTPRESET Mask */
+
+#define DWT_CTRL_CYCCNTENA_Pos 0U /*!< DWT CTRL: CYCCNTENA Position */
+#define DWT_CTRL_CYCCNTENA_Msk (0x1UL /*<< DWT_CTRL_CYCCNTENA_Pos*/) /*!< DWT CTRL: CYCCNTENA Mask */
+
+/* DWT CPI Count Register Definitions */
+#define DWT_CPICNT_CPICNT_Pos 0U /*!< DWT CPICNT: CPICNT Position */
+#define DWT_CPICNT_CPICNT_Msk (0xFFUL /*<< DWT_CPICNT_CPICNT_Pos*/) /*!< DWT CPICNT: CPICNT Mask */
+
+/* DWT Exception Overhead Count Register Definitions */
+#define DWT_EXCCNT_EXCCNT_Pos 0U /*!< DWT EXCCNT: EXCCNT Position */
+#define DWT_EXCCNT_EXCCNT_Msk (0xFFUL /*<< DWT_EXCCNT_EXCCNT_Pos*/) /*!< DWT EXCCNT: EXCCNT Mask */
+
+/* DWT Sleep Count Register Definitions */
+#define DWT_SLEEPCNT_SLEEPCNT_Pos 0U /*!< DWT SLEEPCNT: SLEEPCNT Position */
+#define DWT_SLEEPCNT_SLEEPCNT_Msk (0xFFUL /*<< DWT_SLEEPCNT_SLEEPCNT_Pos*/) /*!< DWT SLEEPCNT: SLEEPCNT Mask */
+
+/* DWT LSU Count Register Definitions */
+#define DWT_LSUCNT_LSUCNT_Pos 0U /*!< DWT LSUCNT: LSUCNT Position */
+#define DWT_LSUCNT_LSUCNT_Msk (0xFFUL /*<< DWT_LSUCNT_LSUCNT_Pos*/) /*!< DWT LSUCNT: LSUCNT Mask */
+
+/* DWT Folded-instruction Count Register Definitions */
+#define DWT_FOLDCNT_FOLDCNT_Pos 0U /*!< DWT FOLDCNT: FOLDCNT Position */
+#define DWT_FOLDCNT_FOLDCNT_Msk (0xFFUL /*<< DWT_FOLDCNT_FOLDCNT_Pos*/) /*!< DWT FOLDCNT: FOLDCNT Mask */
+
+/* DWT Comparator Mask Register Definitions */
+#define DWT_MASK_MASK_Pos 0U /*!< DWT MASK: MASK Position */
+#define DWT_MASK_MASK_Msk (0x1FUL /*<< DWT_MASK_MASK_Pos*/) /*!< DWT MASK: MASK Mask */
+
+/* DWT Comparator Function Register Definitions */
+#define DWT_FUNCTION_MATCHED_Pos 24U /*!< DWT FUNCTION: MATCHED Position */
+#define DWT_FUNCTION_MATCHED_Msk (0x1UL << DWT_FUNCTION_MATCHED_Pos) /*!< DWT FUNCTION: MATCHED Mask */
+
+#define DWT_FUNCTION_DATAVADDR1_Pos 16U /*!< DWT FUNCTION: DATAVADDR1 Position */
+#define DWT_FUNCTION_DATAVADDR1_Msk (0xFUL << DWT_FUNCTION_DATAVADDR1_Pos) /*!< DWT FUNCTION: DATAVADDR1 Mask */
+
+#define DWT_FUNCTION_DATAVADDR0_Pos 12U /*!< DWT FUNCTION: DATAVADDR0 Position */
+#define DWT_FUNCTION_DATAVADDR0_Msk (0xFUL << DWT_FUNCTION_DATAVADDR0_Pos) /*!< DWT FUNCTION: DATAVADDR0 Mask */
+
+#define DWT_FUNCTION_DATAVSIZE_Pos 10U /*!< DWT FUNCTION: DATAVSIZE Position */
+#define DWT_FUNCTION_DATAVSIZE_Msk (0x3UL << DWT_FUNCTION_DATAVSIZE_Pos) /*!< DWT FUNCTION: DATAVSIZE Mask */
+
+#define DWT_FUNCTION_LNK1ENA_Pos 9U /*!< DWT FUNCTION: LNK1ENA Position */
+#define DWT_FUNCTION_LNK1ENA_Msk (0x1UL << DWT_FUNCTION_LNK1ENA_Pos) /*!< DWT FUNCTION: LNK1ENA Mask */
+
+#define DWT_FUNCTION_DATAVMATCH_Pos 8U /*!< DWT FUNCTION: DATAVMATCH Position */
+#define DWT_FUNCTION_DATAVMATCH_Msk (0x1UL << DWT_FUNCTION_DATAVMATCH_Pos) /*!< DWT FUNCTION: DATAVMATCH Mask */
+
+#define DWT_FUNCTION_CYCMATCH_Pos 7U /*!< DWT FUNCTION: CYCMATCH Position */
+#define DWT_FUNCTION_CYCMATCH_Msk (0x1UL << DWT_FUNCTION_CYCMATCH_Pos) /*!< DWT FUNCTION: CYCMATCH Mask */
+
+#define DWT_FUNCTION_EMITRANGE_Pos 5U /*!< DWT FUNCTION: EMITRANGE Position */
+#define DWT_FUNCTION_EMITRANGE_Msk (0x1UL << DWT_FUNCTION_EMITRANGE_Pos) /*!< DWT FUNCTION: EMITRANGE Mask */
+
+#define DWT_FUNCTION_FUNCTION_Pos 0U /*!< DWT FUNCTION: FUNCTION Position */
+#define DWT_FUNCTION_FUNCTION_Msk (0xFUL /*<< DWT_FUNCTION_FUNCTION_Pos*/) /*!< DWT FUNCTION: FUNCTION Mask */
+
+/*@}*/ /* end of group CMSIS_DWT */
+
+
+/**
+ \ingroup CMSIS_core_register
+ \defgroup CMSIS_TPI Trace Port Interface (TPI)
+ \brief Type definitions for the Trace Port Interface (TPI)
+ @{
+ */
+
+/**
+ \brief Structure type to access the Trace Port Interface Register (TPI).
+ */
+typedef struct
+{
+ __IOM uint32_t SSPSR; /*!< Offset: 0x000 (R/ ) Supported Parallel Port Size Register */
+ __IOM uint32_t CSPSR; /*!< Offset: 0x004 (R/W) Current Parallel Port Size Register */
+ uint32_t RESERVED0[2U];
+ __IOM uint32_t ACPR; /*!< Offset: 0x010 (R/W) Asynchronous Clock Prescaler Register */
+ uint32_t RESERVED1[55U];
+ __IOM uint32_t SPPR; /*!< Offset: 0x0F0 (R/W) Selected Pin Protocol Register */
+ uint32_t RESERVED2[131U];
+ __IM uint32_t FFSR; /*!< Offset: 0x300 (R/ ) Formatter and Flush Status Register */
+ __IOM uint32_t FFCR; /*!< Offset: 0x304 (R/W) Formatter and Flush Control Register */
+ __IM uint32_t FSCR; /*!< Offset: 0x308 (R/ ) Formatter Synchronization Counter Register */
+ uint32_t RESERVED3[759U];
+ __IM uint32_t TRIGGER; /*!< Offset: 0xEE8 (R/ ) TRIGGER */
+ __IM uint32_t FIFO0; /*!< Offset: 0xEEC (R/ ) Integration ETM Data */
+ __IM uint32_t ITATBCTR2; /*!< Offset: 0xEF0 (R/ ) ITATBCTR2 */
+ uint32_t RESERVED4[1U];
+ __IM uint32_t ITATBCTR0; /*!< Offset: 0xEF8 (R/ ) ITATBCTR0 */
+ __IM uint32_t FIFO1; /*!< Offset: 0xEFC (R/ ) Integration ITM Data */
+ __IOM uint32_t ITCTRL; /*!< Offset: 0xF00 (R/W) Integration Mode Control */
+ uint32_t RESERVED5[39U];
+ __IOM uint32_t CLAIMSET; /*!< Offset: 0xFA0 (R/W) Claim tag set */
+ __IOM uint32_t CLAIMCLR; /*!< Offset: 0xFA4 (R/W) Claim tag clear */
+ uint32_t RESERVED7[8U];
+ __IM uint32_t DEVID; /*!< Offset: 0xFC8 (R/ ) TPIU_DEVID */
+ __IM uint32_t DEVTYPE; /*!< Offset: 0xFCC (R/ ) TPIU_DEVTYPE */
+} TPI_Type;
+
+/* TPI Asynchronous Clock Prescaler Register Definitions */
+#define TPI_ACPR_PRESCALER_Pos 0U /*!< TPI ACPR: PRESCALER Position */
+#define TPI_ACPR_PRESCALER_Msk (0x1FFFUL /*<< TPI_ACPR_PRESCALER_Pos*/) /*!< TPI ACPR: PRESCALER Mask */
+
+/* TPI Selected Pin Protocol Register Definitions */
+#define TPI_SPPR_TXMODE_Pos 0U /*!< TPI SPPR: TXMODE Position */
+#define TPI_SPPR_TXMODE_Msk (0x3UL /*<< TPI_SPPR_TXMODE_Pos*/) /*!< TPI SPPR: TXMODE Mask */
+
+/* TPI Formatter and Flush Status Register Definitions */
+#define TPI_FFSR_FtNonStop_Pos 3U /*!< TPI FFSR: FtNonStop Position */
+#define TPI_FFSR_FtNonStop_Msk (0x1UL << TPI_FFSR_FtNonStop_Pos) /*!< TPI FFSR: FtNonStop Mask */
+
+#define TPI_FFSR_TCPresent_Pos 2U /*!< TPI FFSR: TCPresent Position */
+#define TPI_FFSR_TCPresent_Msk (0x1UL << TPI_FFSR_TCPresent_Pos) /*!< TPI FFSR: TCPresent Mask */
+
+#define TPI_FFSR_FtStopped_Pos 1U /*!< TPI FFSR: FtStopped Position */
+#define TPI_FFSR_FtStopped_Msk (0x1UL << TPI_FFSR_FtStopped_Pos) /*!< TPI FFSR: FtStopped Mask */
+
+#define TPI_FFSR_FlInProg_Pos 0U /*!< TPI FFSR: FlInProg Position */
+#define TPI_FFSR_FlInProg_Msk (0x1UL /*<< TPI_FFSR_FlInProg_Pos*/) /*!< TPI FFSR: FlInProg Mask */
+
+/* TPI Formatter and Flush Control Register Definitions */
+#define TPI_FFCR_TrigIn_Pos 8U /*!< TPI FFCR: TrigIn Position */
+#define TPI_FFCR_TrigIn_Msk (0x1UL << TPI_FFCR_TrigIn_Pos) /*!< TPI FFCR: TrigIn Mask */
+
+#define TPI_FFCR_EnFCont_Pos 1U /*!< TPI FFCR: EnFCont Position */
+#define TPI_FFCR_EnFCont_Msk (0x1UL << TPI_FFCR_EnFCont_Pos) /*!< TPI FFCR: EnFCont Mask */
+
+/* TPI TRIGGER Register Definitions */
+#define TPI_TRIGGER_TRIGGER_Pos 0U /*!< TPI TRIGGER: TRIGGER Position */
+#define TPI_TRIGGER_TRIGGER_Msk (0x1UL /*<< TPI_TRIGGER_TRIGGER_Pos*/) /*!< TPI TRIGGER: TRIGGER Mask */
+
+/* TPI Integration ETM Data Register Definitions (FIFO0) */
+#define TPI_FIFO0_ITM_ATVALID_Pos 29U /*!< TPI FIFO0: ITM_ATVALID Position */
+#define TPI_FIFO0_ITM_ATVALID_Msk (0x3UL << TPI_FIFO0_ITM_ATVALID_Pos) /*!< TPI FIFO0: ITM_ATVALID Mask */
+
+#define TPI_FIFO0_ITM_bytecount_Pos 27U /*!< TPI FIFO0: ITM_bytecount Position */
+#define TPI_FIFO0_ITM_bytecount_Msk (0x3UL << TPI_FIFO0_ITM_bytecount_Pos) /*!< TPI FIFO0: ITM_bytecount Mask */
+
+#define TPI_FIFO0_ETM_ATVALID_Pos 26U /*!< TPI FIFO0: ETM_ATVALID Position */
+#define TPI_FIFO0_ETM_ATVALID_Msk (0x3UL << TPI_FIFO0_ETM_ATVALID_Pos) /*!< TPI FIFO0: ETM_ATVALID Mask */
+
+#define TPI_FIFO0_ETM_bytecount_Pos 24U /*!< TPI FIFO0: ETM_bytecount Position */
+#define TPI_FIFO0_ETM_bytecount_Msk (0x3UL << TPI_FIFO0_ETM_bytecount_Pos) /*!< TPI FIFO0: ETM_bytecount Mask */
+
+#define TPI_FIFO0_ETM2_Pos 16U /*!< TPI FIFO0: ETM2 Position */
+#define TPI_FIFO0_ETM2_Msk (0xFFUL << TPI_FIFO0_ETM2_Pos) /*!< TPI FIFO0: ETM2 Mask */
+
+#define TPI_FIFO0_ETM1_Pos 8U /*!< TPI FIFO0: ETM1 Position */
+#define TPI_FIFO0_ETM1_Msk (0xFFUL << TPI_FIFO0_ETM1_Pos) /*!< TPI FIFO0: ETM1 Mask */
+
+#define TPI_FIFO0_ETM0_Pos 0U /*!< TPI FIFO0: ETM0 Position */
+#define TPI_FIFO0_ETM0_Msk (0xFFUL /*<< TPI_FIFO0_ETM0_Pos*/) /*!< TPI FIFO0: ETM0 Mask */
+
+/* TPI ITATBCTR2 Register Definitions */
+#define TPI_ITATBCTR2_ATREADY_Pos 0U /*!< TPI ITATBCTR2: ATREADY Position */
+#define TPI_ITATBCTR2_ATREADY_Msk (0x1UL /*<< TPI_ITATBCTR2_ATREADY_Pos*/) /*!< TPI ITATBCTR2: ATREADY Mask */
+
+/* TPI Integration ITM Data Register Definitions (FIFO1) */
+#define TPI_FIFO1_ITM_ATVALID_Pos 29U /*!< TPI FIFO1: ITM_ATVALID Position */
+#define TPI_FIFO1_ITM_ATVALID_Msk (0x3UL << TPI_FIFO1_ITM_ATVALID_Pos) /*!< TPI FIFO1: ITM_ATVALID Mask */
+
+#define TPI_FIFO1_ITM_bytecount_Pos 27U /*!< TPI FIFO1: ITM_bytecount Position */
+#define TPI_FIFO1_ITM_bytecount_Msk (0x3UL << TPI_FIFO1_ITM_bytecount_Pos) /*!< TPI FIFO1: ITM_bytecount Mask */
+
+#define TPI_FIFO1_ETM_ATVALID_Pos 26U /*!< TPI FIFO1: ETM_ATVALID Position */
+#define TPI_FIFO1_ETM_ATVALID_Msk (0x3UL << TPI_FIFO1_ETM_ATVALID_Pos) /*!< TPI FIFO1: ETM_ATVALID Mask */
+
+#define TPI_FIFO1_ETM_bytecount_Pos 24U /*!< TPI FIFO1: ETM_bytecount Position */
+#define TPI_FIFO1_ETM_bytecount_Msk (0x3UL << TPI_FIFO1_ETM_bytecount_Pos) /*!< TPI FIFO1: ETM_bytecount Mask */
+
+#define TPI_FIFO1_ITM2_Pos 16U /*!< TPI FIFO1: ITM2 Position */
+#define TPI_FIFO1_ITM2_Msk (0xFFUL << TPI_FIFO1_ITM2_Pos) /*!< TPI FIFO1: ITM2 Mask */
+
+#define TPI_FIFO1_ITM1_Pos 8U /*!< TPI FIFO1: ITM1 Position */
+#define TPI_FIFO1_ITM1_Msk (0xFFUL << TPI_FIFO1_ITM1_Pos) /*!< TPI FIFO1: ITM1 Mask */
+
+#define TPI_FIFO1_ITM0_Pos 0U /*!< TPI FIFO1: ITM0 Position */
+#define TPI_FIFO1_ITM0_Msk (0xFFUL /*<< TPI_FIFO1_ITM0_Pos*/) /*!< TPI FIFO1: ITM0 Mask */
+
+/* TPI ITATBCTR0 Register Definitions */
+#define TPI_ITATBCTR0_ATREADY_Pos 0U /*!< TPI ITATBCTR0: ATREADY Position */
+#define TPI_ITATBCTR0_ATREADY_Msk (0x1UL /*<< TPI_ITATBCTR0_ATREADY_Pos*/) /*!< TPI ITATBCTR0: ATREADY Mask */
+
+/* TPI Integration Mode Control Register Definitions */
+#define TPI_ITCTRL_Mode_Pos 0U /*!< TPI ITCTRL: Mode Position */
+#define TPI_ITCTRL_Mode_Msk (0x1UL /*<< TPI_ITCTRL_Mode_Pos*/) /*!< TPI ITCTRL: Mode Mask */
+
+/* TPI DEVID Register Definitions */
+#define TPI_DEVID_NRZVALID_Pos 11U /*!< TPI DEVID: NRZVALID Position */
+#define TPI_DEVID_NRZVALID_Msk (0x1UL << TPI_DEVID_NRZVALID_Pos) /*!< TPI DEVID: NRZVALID Mask */
+
+#define TPI_DEVID_MANCVALID_Pos 10U /*!< TPI DEVID: MANCVALID Position */
+#define TPI_DEVID_MANCVALID_Msk (0x1UL << TPI_DEVID_MANCVALID_Pos) /*!< TPI DEVID: MANCVALID Mask */
+
+#define TPI_DEVID_PTINVALID_Pos 9U /*!< TPI DEVID: PTINVALID Position */
+#define TPI_DEVID_PTINVALID_Msk (0x1UL << TPI_DEVID_PTINVALID_Pos) /*!< TPI DEVID: PTINVALID Mask */
+
+#define TPI_DEVID_MinBufSz_Pos 6U /*!< TPI DEVID: MinBufSz Position */
+#define TPI_DEVID_MinBufSz_Msk (0x7UL << TPI_DEVID_MinBufSz_Pos) /*!< TPI DEVID: MinBufSz Mask */
+
+#define TPI_DEVID_AsynClkIn_Pos 5U /*!< TPI DEVID: AsynClkIn Position */
+#define TPI_DEVID_AsynClkIn_Msk (0x1UL << TPI_DEVID_AsynClkIn_Pos) /*!< TPI DEVID: AsynClkIn Mask */
+
+#define TPI_DEVID_NrTraceInput_Pos 0U /*!< TPI DEVID: NrTraceInput Position */
+#define TPI_DEVID_NrTraceInput_Msk (0x1FUL /*<< TPI_DEVID_NrTraceInput_Pos*/) /*!< TPI DEVID: NrTraceInput Mask */
+
+/* TPI DEVTYPE Register Definitions */
+#define TPI_DEVTYPE_MajorType_Pos 4U /*!< TPI DEVTYPE: MajorType Position */
+#define TPI_DEVTYPE_MajorType_Msk (0xFUL << TPI_DEVTYPE_MajorType_Pos) /*!< TPI DEVTYPE: MajorType Mask */
+
+#define TPI_DEVTYPE_SubType_Pos 0U /*!< TPI DEVTYPE: SubType Position */
+#define TPI_DEVTYPE_SubType_Msk (0xFUL /*<< TPI_DEVTYPE_SubType_Pos*/) /*!< TPI DEVTYPE: SubType Mask */
+
+/*@}*/ /* end of group CMSIS_TPI */
+
+
+#if (__MPU_PRESENT == 1U)
+/**
+ \ingroup CMSIS_core_register
+ \defgroup CMSIS_MPU Memory Protection Unit (MPU)
+ \brief Type definitions for the Memory Protection Unit (MPU)
+ @{
+ */
+
+/**
+ \brief Structure type to access the Memory Protection Unit (MPU).
+ */
+typedef struct
+{
+ __IM uint32_t TYPE; /*!< Offset: 0x000 (R/ ) MPU Type Register */
+ __IOM uint32_t CTRL; /*!< Offset: 0x004 (R/W) MPU Control Register */
+ __IOM uint32_t RNR; /*!< Offset: 0x008 (R/W) MPU Region RNRber Register */
+ __IOM uint32_t RBAR; /*!< Offset: 0x00C (R/W) MPU Region Base Address Register */
+ __IOM uint32_t RASR; /*!< Offset: 0x010 (R/W) MPU Region Attribute and Size Register */
+ __IOM uint32_t RBAR_A1; /*!< Offset: 0x014 (R/W) MPU Alias 1 Region Base Address Register */
+ __IOM uint32_t RASR_A1; /*!< Offset: 0x018 (R/W) MPU Alias 1 Region Attribute and Size Register */
+ __IOM uint32_t RBAR_A2; /*!< Offset: 0x01C (R/W) MPU Alias 2 Region Base Address Register */
+ __IOM uint32_t RASR_A2; /*!< Offset: 0x020 (R/W) MPU Alias 2 Region Attribute and Size Register */
+ __IOM uint32_t RBAR_A3; /*!< Offset: 0x024 (R/W) MPU Alias 3 Region Base Address Register */
+ __IOM uint32_t RASR_A3; /*!< Offset: 0x028 (R/W) MPU Alias 3 Region Attribute and Size Register */
+} MPU_Type;
+
+/* MPU Type Register Definitions */
+#define MPU_TYPE_IREGION_Pos 16U /*!< MPU TYPE: IREGION Position */
+#define MPU_TYPE_IREGION_Msk (0xFFUL << MPU_TYPE_IREGION_Pos) /*!< MPU TYPE: IREGION Mask */
+
+#define MPU_TYPE_DREGION_Pos 8U /*!< MPU TYPE: DREGION Position */
+#define MPU_TYPE_DREGION_Msk (0xFFUL << MPU_TYPE_DREGION_Pos) /*!< MPU TYPE: DREGION Mask */
+
+#define MPU_TYPE_SEPARATE_Pos 0U /*!< MPU TYPE: SEPARATE Position */
+#define MPU_TYPE_SEPARATE_Msk (1UL /*<< MPU_TYPE_SEPARATE_Pos*/) /*!< MPU TYPE: SEPARATE Mask */
+
+/* MPU Control Register Definitions */
+#define MPU_CTRL_PRIVDEFENA_Pos 2U /*!< MPU CTRL: PRIVDEFENA Position */
+#define MPU_CTRL_PRIVDEFENA_Msk (1UL << MPU_CTRL_PRIVDEFENA_Pos) /*!< MPU CTRL: PRIVDEFENA Mask */
+
+#define MPU_CTRL_HFNMIENA_Pos 1U /*!< MPU CTRL: HFNMIENA Position */
+#define MPU_CTRL_HFNMIENA_Msk (1UL << MPU_CTRL_HFNMIENA_Pos) /*!< MPU CTRL: HFNMIENA Mask */
+
+#define MPU_CTRL_ENABLE_Pos 0U /*!< MPU CTRL: ENABLE Position */
+#define MPU_CTRL_ENABLE_Msk (1UL /*<< MPU_CTRL_ENABLE_Pos*/) /*!< MPU CTRL: ENABLE Mask */
+
+/* MPU Region Number Register Definitions */
+#define MPU_RNR_REGION_Pos 0U /*!< MPU RNR: REGION Position */
+#define MPU_RNR_REGION_Msk (0xFFUL /*<< MPU_RNR_REGION_Pos*/) /*!< MPU RNR: REGION Mask */
+
+/* MPU Region Base Address Register Definitions */
+#define MPU_RBAR_ADDR_Pos 5U /*!< MPU RBAR: ADDR Position */
+#define MPU_RBAR_ADDR_Msk (0x7FFFFFFUL << MPU_RBAR_ADDR_Pos) /*!< MPU RBAR: ADDR Mask */
+
+#define MPU_RBAR_VALID_Pos 4U /*!< MPU RBAR: VALID Position */
+#define MPU_RBAR_VALID_Msk (1UL << MPU_RBAR_VALID_Pos) /*!< MPU RBAR: VALID Mask */
+
+#define MPU_RBAR_REGION_Pos 0U /*!< MPU RBAR: REGION Position */
+#define MPU_RBAR_REGION_Msk (0xFUL /*<< MPU_RBAR_REGION_Pos*/) /*!< MPU RBAR: REGION Mask */
+
+/* MPU Region Attribute and Size Register Definitions */
+#define MPU_RASR_ATTRS_Pos 16U /*!< MPU RASR: MPU Region Attribute field Position */
+#define MPU_RASR_ATTRS_Msk (0xFFFFUL << MPU_RASR_ATTRS_Pos) /*!< MPU RASR: MPU Region Attribute field Mask */
+
+#define MPU_RASR_XN_Pos 28U /*!< MPU RASR: ATTRS.XN Position */
+#define MPU_RASR_XN_Msk (1UL << MPU_RASR_XN_Pos) /*!< MPU RASR: ATTRS.XN Mask */
+
+#define MPU_RASR_AP_Pos 24U /*!< MPU RASR: ATTRS.AP Position */
+#define MPU_RASR_AP_Msk (0x7UL << MPU_RASR_AP_Pos) /*!< MPU RASR: ATTRS.AP Mask */
+
+#define MPU_RASR_TEX_Pos 19U /*!< MPU RASR: ATTRS.TEX Position */
+#define MPU_RASR_TEX_Msk (0x7UL << MPU_RASR_TEX_Pos) /*!< MPU RASR: ATTRS.TEX Mask */
+
+#define MPU_RASR_S_Pos 18U /*!< MPU RASR: ATTRS.S Position */
+#define MPU_RASR_S_Msk (1UL << MPU_RASR_S_Pos) /*!< MPU RASR: ATTRS.S Mask */
+
+#define MPU_RASR_C_Pos 17U /*!< MPU RASR: ATTRS.C Position */
+#define MPU_RASR_C_Msk (1UL << MPU_RASR_C_Pos) /*!< MPU RASR: ATTRS.C Mask */
+
+#define MPU_RASR_B_Pos 16U /*!< MPU RASR: ATTRS.B Position */
+#define MPU_RASR_B_Msk (1UL << MPU_RASR_B_Pos) /*!< MPU RASR: ATTRS.B Mask */
+
+#define MPU_RASR_SRD_Pos 8U /*!< MPU RASR: Sub-Region Disable Position */
+#define MPU_RASR_SRD_Msk (0xFFUL << MPU_RASR_SRD_Pos) /*!< MPU RASR: Sub-Region Disable Mask */
+
+#define MPU_RASR_SIZE_Pos 1U /*!< MPU RASR: Region Size Field Position */
+#define MPU_RASR_SIZE_Msk (0x1FUL << MPU_RASR_SIZE_Pos) /*!< MPU RASR: Region Size Field Mask */
+
+#define MPU_RASR_ENABLE_Pos 0U /*!< MPU RASR: Region enable bit Position */
+#define MPU_RASR_ENABLE_Msk (1UL /*<< MPU_RASR_ENABLE_Pos*/) /*!< MPU RASR: Region enable bit Disable Mask */
+
+/*@} end of group CMSIS_MPU */
+#endif
+
+
+/**
+ \ingroup CMSIS_core_register
+ \defgroup CMSIS_CoreDebug Core Debug Registers (CoreDebug)
+ \brief Type definitions for the Core Debug Registers
+ @{
+ */
+
+/**
+ \brief Structure type to access the Core Debug Register (CoreDebug).
+ */
+typedef struct
+{
+ __IOM uint32_t DHCSR; /*!< Offset: 0x000 (R/W) Debug Halting Control and Status Register */
+ __OM uint32_t DCRSR; /*!< Offset: 0x004 ( /W) Debug Core Register Selector Register */
+ __IOM uint32_t DCRDR; /*!< Offset: 0x008 (R/W) Debug Core Register Data Register */
+ __IOM uint32_t DEMCR; /*!< Offset: 0x00C (R/W) Debug Exception and Monitor Control Register */
+} CoreDebug_Type;
+
+/* Debug Halting Control and Status Register Definitions */
+#define CoreDebug_DHCSR_DBGKEY_Pos 16U /*!< CoreDebug DHCSR: DBGKEY Position */
+#define CoreDebug_DHCSR_DBGKEY_Msk (0xFFFFUL << CoreDebug_DHCSR_DBGKEY_Pos) /*!< CoreDebug DHCSR: DBGKEY Mask */
+
+#define CoreDebug_DHCSR_S_RESET_ST_Pos 25U /*!< CoreDebug DHCSR: S_RESET_ST Position */
+#define CoreDebug_DHCSR_S_RESET_ST_Msk (1UL << CoreDebug_DHCSR_S_RESET_ST_Pos) /*!< CoreDebug DHCSR: S_RESET_ST Mask */
+
+#define CoreDebug_DHCSR_S_RETIRE_ST_Pos 24U /*!< CoreDebug DHCSR: S_RETIRE_ST Position */
+#define CoreDebug_DHCSR_S_RETIRE_ST_Msk (1UL << CoreDebug_DHCSR_S_RETIRE_ST_Pos) /*!< CoreDebug DHCSR: S_RETIRE_ST Mask */
+
+#define CoreDebug_DHCSR_S_LOCKUP_Pos 19U /*!< CoreDebug DHCSR: S_LOCKUP Position */
+#define CoreDebug_DHCSR_S_LOCKUP_Msk (1UL << CoreDebug_DHCSR_S_LOCKUP_Pos) /*!< CoreDebug DHCSR: S_LOCKUP Mask */
+
+#define CoreDebug_DHCSR_S_SLEEP_Pos 18U /*!< CoreDebug DHCSR: S_SLEEP Position */
+#define CoreDebug_DHCSR_S_SLEEP_Msk (1UL << CoreDebug_DHCSR_S_SLEEP_Pos) /*!< CoreDebug DHCSR: S_SLEEP Mask */
+
+#define CoreDebug_DHCSR_S_HALT_Pos 17U /*!< CoreDebug DHCSR: S_HALT Position */
+#define CoreDebug_DHCSR_S_HALT_Msk (1UL << CoreDebug_DHCSR_S_HALT_Pos) /*!< CoreDebug DHCSR: S_HALT Mask */
+
+#define CoreDebug_DHCSR_S_REGRDY_Pos 16U /*!< CoreDebug DHCSR: S_REGRDY Position */
+#define CoreDebug_DHCSR_S_REGRDY_Msk (1UL << CoreDebug_DHCSR_S_REGRDY_Pos) /*!< CoreDebug DHCSR: S_REGRDY Mask */
+
+#define CoreDebug_DHCSR_C_SNAPSTALL_Pos 5U /*!< CoreDebug DHCSR: C_SNAPSTALL Position */
+#define CoreDebug_DHCSR_C_SNAPSTALL_Msk (1UL << CoreDebug_DHCSR_C_SNAPSTALL_Pos) /*!< CoreDebug DHCSR: C_SNAPSTALL Mask */
+
+#define CoreDebug_DHCSR_C_MASKINTS_Pos 3U /*!< CoreDebug DHCSR: C_MASKINTS Position */
+#define CoreDebug_DHCSR_C_MASKINTS_Msk (1UL << CoreDebug_DHCSR_C_MASKINTS_Pos) /*!< CoreDebug DHCSR: C_MASKINTS Mask */
+
+#define CoreDebug_DHCSR_C_STEP_Pos 2U /*!< CoreDebug DHCSR: C_STEP Position */
+#define CoreDebug_DHCSR_C_STEP_Msk (1UL << CoreDebug_DHCSR_C_STEP_Pos) /*!< CoreDebug DHCSR: C_STEP Mask */
+
+#define CoreDebug_DHCSR_C_HALT_Pos 1U /*!< CoreDebug DHCSR: C_HALT Position */
+#define CoreDebug_DHCSR_C_HALT_Msk (1UL << CoreDebug_DHCSR_C_HALT_Pos) /*!< CoreDebug DHCSR: C_HALT Mask */
+
+#define CoreDebug_DHCSR_C_DEBUGEN_Pos 0U /*!< CoreDebug DHCSR: C_DEBUGEN Position */
+#define CoreDebug_DHCSR_C_DEBUGEN_Msk (1UL /*<< CoreDebug_DHCSR_C_DEBUGEN_Pos*/) /*!< CoreDebug DHCSR: C_DEBUGEN Mask */
+
+/* Debug Core Register Selector Register Definitions */
+#define CoreDebug_DCRSR_REGWnR_Pos 16U /*!< CoreDebug DCRSR: REGWnR Position */
+#define CoreDebug_DCRSR_REGWnR_Msk (1UL << CoreDebug_DCRSR_REGWnR_Pos) /*!< CoreDebug DCRSR: REGWnR Mask */
+
+#define CoreDebug_DCRSR_REGSEL_Pos 0U /*!< CoreDebug DCRSR: REGSEL Position */
+#define CoreDebug_DCRSR_REGSEL_Msk (0x1FUL /*<< CoreDebug_DCRSR_REGSEL_Pos*/) /*!< CoreDebug DCRSR: REGSEL Mask */
+
+/* Debug Exception and Monitor Control Register Definitions */
+#define CoreDebug_DEMCR_TRCENA_Pos 24U /*!< CoreDebug DEMCR: TRCENA Position */
+#define CoreDebug_DEMCR_TRCENA_Msk (1UL << CoreDebug_DEMCR_TRCENA_Pos) /*!< CoreDebug DEMCR: TRCENA Mask */
+
+#define CoreDebug_DEMCR_MON_REQ_Pos 19U /*!< CoreDebug DEMCR: MON_REQ Position */
+#define CoreDebug_DEMCR_MON_REQ_Msk (1UL << CoreDebug_DEMCR_MON_REQ_Pos) /*!< CoreDebug DEMCR: MON_REQ Mask */
+
+#define CoreDebug_DEMCR_MON_STEP_Pos 18U /*!< CoreDebug DEMCR: MON_STEP Position */
+#define CoreDebug_DEMCR_MON_STEP_Msk (1UL << CoreDebug_DEMCR_MON_STEP_Pos) /*!< CoreDebug DEMCR: MON_STEP Mask */
+
+#define CoreDebug_DEMCR_MON_PEND_Pos 17U /*!< CoreDebug DEMCR: MON_PEND Position */
+#define CoreDebug_DEMCR_MON_PEND_Msk (1UL << CoreDebug_DEMCR_MON_PEND_Pos) /*!< CoreDebug DEMCR: MON_PEND Mask */
+
+#define CoreDebug_DEMCR_MON_EN_Pos 16U /*!< CoreDebug DEMCR: MON_EN Position */
+#define CoreDebug_DEMCR_MON_EN_Msk (1UL << CoreDebug_DEMCR_MON_EN_Pos) /*!< CoreDebug DEMCR: MON_EN Mask */
+
+#define CoreDebug_DEMCR_VC_HARDERR_Pos 10U /*!< CoreDebug DEMCR: VC_HARDERR Position */
+#define CoreDebug_DEMCR_VC_HARDERR_Msk (1UL << CoreDebug_DEMCR_VC_HARDERR_Pos) /*!< CoreDebug DEMCR: VC_HARDERR Mask */
+
+#define CoreDebug_DEMCR_VC_INTERR_Pos 9U /*!< CoreDebug DEMCR: VC_INTERR Position */
+#define CoreDebug_DEMCR_VC_INTERR_Msk (1UL << CoreDebug_DEMCR_VC_INTERR_Pos) /*!< CoreDebug DEMCR: VC_INTERR Mask */
+
+#define CoreDebug_DEMCR_VC_BUSERR_Pos 8U /*!< CoreDebug DEMCR: VC_BUSERR Position */
+#define CoreDebug_DEMCR_VC_BUSERR_Msk (1UL << CoreDebug_DEMCR_VC_BUSERR_Pos) /*!< CoreDebug DEMCR: VC_BUSERR Mask */
+
+#define CoreDebug_DEMCR_VC_STATERR_Pos 7U /*!< CoreDebug DEMCR: VC_STATERR Position */
+#define CoreDebug_DEMCR_VC_STATERR_Msk (1UL << CoreDebug_DEMCR_VC_STATERR_Pos) /*!< CoreDebug DEMCR: VC_STATERR Mask */
+
+#define CoreDebug_DEMCR_VC_CHKERR_Pos 6U /*!< CoreDebug DEMCR: VC_CHKERR Position */
+#define CoreDebug_DEMCR_VC_CHKERR_Msk (1UL << CoreDebug_DEMCR_VC_CHKERR_Pos) /*!< CoreDebug DEMCR: VC_CHKERR Mask */
+
+#define CoreDebug_DEMCR_VC_NOCPERR_Pos 5U /*!< CoreDebug DEMCR: VC_NOCPERR Position */
+#define CoreDebug_DEMCR_VC_NOCPERR_Msk (1UL << CoreDebug_DEMCR_VC_NOCPERR_Pos) /*!< CoreDebug DEMCR: VC_NOCPERR Mask */
+
+#define CoreDebug_DEMCR_VC_MMERR_Pos 4U /*!< CoreDebug DEMCR: VC_MMERR Position */
+#define CoreDebug_DEMCR_VC_MMERR_Msk (1UL << CoreDebug_DEMCR_VC_MMERR_Pos) /*!< CoreDebug DEMCR: VC_MMERR Mask */
+
+#define CoreDebug_DEMCR_VC_CORERESET_Pos 0U /*!< CoreDebug DEMCR: VC_CORERESET Position */
+#define CoreDebug_DEMCR_VC_CORERESET_Msk (1UL /*<< CoreDebug_DEMCR_VC_CORERESET_Pos*/) /*!< CoreDebug DEMCR: VC_CORERESET Mask */
+
+/*@} end of group CMSIS_CoreDebug */
+
+
+/**
+ \ingroup CMSIS_core_register
+ \defgroup CMSIS_core_bitfield Core register bit field macros
+ \brief Macros for use with bit field definitions (xxx_Pos, xxx_Msk).
+ @{
+ */
+
+/**
+ \brief Mask and shift a bit field value for use in a register bit range.
+ \param[in] field Name of the register bit field.
+ \param[in] value Value of the bit field.
+ \return Masked and shifted value.
+*/
+#define _VAL2FLD(field, value) ((value << field ## _Pos) & field ## _Msk)
+
+/**
+ \brief Mask and shift a register value to extract a bit filed value.
+ \param[in] field Name of the register bit field.
+ \param[in] value Value of register.
+ \return Masked and shifted bit field value.
+*/
+#define _FLD2VAL(field, value) ((value & field ## _Msk) >> field ## _Pos)
+
+/*@} end of group CMSIS_core_bitfield */
+
+
+/**
+ \ingroup CMSIS_core_register
+ \defgroup CMSIS_core_base Core Definitions
+ \brief Definitions for base addresses, unions, and structures.
+ @{
+ */
+
+/* Memory mapping of Cortex-M3 Hardware */
+#define SCS_BASE (0xE000E000UL) /*!< System Control Space Base Address */
+#define ITM_BASE (0xE0000000UL) /*!< ITM Base Address */
+#define DWT_BASE (0xE0001000UL) /*!< DWT Base Address */
+#define TPI_BASE (0xE0040000UL) /*!< TPI Base Address */
+#define CoreDebug_BASE (0xE000EDF0UL) /*!< Core Debug Base Address */
+#define SysTick_BASE (SCS_BASE + 0x0010UL) /*!< SysTick Base Address */
+#define NVIC_BASE (SCS_BASE + 0x0100UL) /*!< NVIC Base Address */
+#define SCB_BASE (SCS_BASE + 0x0D00UL) /*!< System Control Block Base Address */
+
+#define SCnSCB ((SCnSCB_Type *) SCS_BASE ) /*!< System control Register not in SCB */
+#define SCB ((SCB_Type *) SCB_BASE ) /*!< SCB configuration struct */
+#define SysTick ((SysTick_Type *) SysTick_BASE ) /*!< SysTick configuration struct */
+#define NVIC ((NVIC_Type *) NVIC_BASE ) /*!< NVIC configuration struct */
+#define ITM ((ITM_Type *) ITM_BASE ) /*!< ITM configuration struct */
+#define DWT ((DWT_Type *) DWT_BASE ) /*!< DWT configuration struct */
+#define TPI ((TPI_Type *) TPI_BASE ) /*!< TPI configuration struct */
+#define CoreDebug ((CoreDebug_Type *) CoreDebug_BASE) /*!< Core Debug configuration struct */
+
+#if (__MPU_PRESENT == 1U)
+ #define MPU_BASE (SCS_BASE + 0x0D90UL) /*!< Memory Protection Unit */
+ #define MPU ((MPU_Type *) MPU_BASE ) /*!< Memory Protection Unit */
+#endif
+
+/*@} */
+
+
+
+/*******************************************************************************
+ * Hardware Abstraction Layer
+ Core Function Interface contains:
+ - Core NVIC Functions
+ - Core SysTick Functions
+ - Core Debug Functions
+ - Core Register Access Functions
+ ******************************************************************************/
+/**
+ \defgroup CMSIS_Core_FunctionInterface Functions and Instructions Reference
+*/
+
+
+
+/* ########################## NVIC functions #################################### */
+/**
+ \ingroup CMSIS_Core_FunctionInterface
+ \defgroup CMSIS_Core_NVICFunctions NVIC Functions
+ \brief Functions that manage interrupts and exceptions via the NVIC.
+ @{
+ */
+
+/**
+ \brief Set Priority Grouping
+ \details Sets the priority grouping field using the required unlock sequence.
+ The parameter PriorityGroup is assigned to the field SCB->AIRCR [10:8] PRIGROUP field.
+ Only values from 0..7 are used.
+ In case of a conflict between priority grouping and available
+ priority bits (__NVIC_PRIO_BITS), the smallest possible priority group is set.
+ \param [in] PriorityGroup Priority grouping field.
+ */
+__STATIC_INLINE void NVIC_SetPriorityGrouping(uint32_t PriorityGroup)
+{
+ uint32_t reg_value;
+ uint32_t PriorityGroupTmp = (PriorityGroup & (uint32_t)0x07UL); /* only values 0..7 are used */
+
+ reg_value = SCB->AIRCR; /* read old register configuration */
+ reg_value &= ~((uint32_t)(SCB_AIRCR_VECTKEY_Msk | SCB_AIRCR_PRIGROUP_Msk)); /* clear bits to change */
+ reg_value = (reg_value |
+ ((uint32_t)0x5FAUL << SCB_AIRCR_VECTKEY_Pos) |
+ (PriorityGroupTmp << 8U) ); /* Insert write key and priorty group */
+ SCB->AIRCR = reg_value;
+}
+
+
+/**
+ \brief Get Priority Grouping
+ \details Reads the priority grouping field from the NVIC Interrupt Controller.
+ \return Priority grouping field (SCB->AIRCR [10:8] PRIGROUP field).
+ */
+__STATIC_INLINE uint32_t NVIC_GetPriorityGrouping(void)
+{
+ return ((uint32_t)((SCB->AIRCR & SCB_AIRCR_PRIGROUP_Msk) >> SCB_AIRCR_PRIGROUP_Pos));
+}
+
+
+/**
+ \brief Enable External Interrupt
+ \details Enables a device-specific interrupt in the NVIC interrupt controller.
+ \param [in] IRQn External interrupt number. Value cannot be negative.
+ */
+__STATIC_INLINE void NVIC_EnableIRQ(IRQn_Type IRQn)
+{
+ NVIC->ISER[(((uint32_t)(int32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL));
+}
+
+
+/**
+ \brief Disable External Interrupt
+ \details Disables a device-specific interrupt in the NVIC interrupt controller.
+ \param [in] IRQn External interrupt number. Value cannot be negative.
+ */
+__STATIC_INLINE void NVIC_DisableIRQ(IRQn_Type IRQn)
+{
+ NVIC->ICER[(((uint32_t)(int32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL));
+}
+
+
+/**
+ \brief Get Pending Interrupt
+ \details Reads the pending register in the NVIC and returns the pending bit for the specified interrupt.
+ \param [in] IRQn Interrupt number.
+ \return 0 Interrupt status is not pending.
+ \return 1 Interrupt status is pending.
+ */
+__STATIC_INLINE uint32_t NVIC_GetPendingIRQ(IRQn_Type IRQn)
+{
+ return((uint32_t)(((NVIC->ISPR[(((uint32_t)(int32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL));
+}
+
+
+/**
+ \brief Set Pending Interrupt
+ \details Sets the pending bit of an external interrupt.
+ \param [in] IRQn Interrupt number. Value cannot be negative.
+ */
+__STATIC_INLINE void NVIC_SetPendingIRQ(IRQn_Type IRQn)
+{
+ NVIC->ISPR[(((uint32_t)(int32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL));
+}
+
+
+/**
+ \brief Clear Pending Interrupt
+ \details Clears the pending bit of an external interrupt.
+ \param [in] IRQn External interrupt number. Value cannot be negative.
+ */
+__STATIC_INLINE void NVIC_ClearPendingIRQ(IRQn_Type IRQn)
+{
+ NVIC->ICPR[(((uint32_t)(int32_t)IRQn) >> 5UL)] = (uint32_t)(1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL));
+}
+
+
+/**
+ \brief Get Active Interrupt
+ \details Reads the active register in NVIC and returns the active bit.
+ \param [in] IRQn Interrupt number.
+ \return 0 Interrupt status is not active.
+ \return 1 Interrupt status is active.
+ */
+__STATIC_INLINE uint32_t NVIC_GetActive(IRQn_Type IRQn)
+{
+ return((uint32_t)(((NVIC->IABR[(((uint32_t)(int32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL));
+}
+
+
+/**
+ \brief Set Interrupt Priority
+ \details Sets the priority of an interrupt.
+ \note The priority cannot be set for every core interrupt.
+ \param [in] IRQn Interrupt number.
+ \param [in] priority Priority to set.
+ */
+__STATIC_INLINE void NVIC_SetPriority(IRQn_Type IRQn, uint32_t priority)
+{
+ if ((int32_t)(IRQn) < 0)
+ {
+ SCB->SHP[(((uint32_t)(int32_t)IRQn) & 0xFUL)-4UL] = (uint8_t)((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL);
+ }
+ else
+ {
+ NVIC->IP[((uint32_t)(int32_t)IRQn)] = (uint8_t)((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL);
+ }
+}
+
+
+/**
+ \brief Get Interrupt Priority
+ \details Reads the priority of an interrupt.
+ The interrupt number can be positive to specify an external (device specific) interrupt,
+ or negative to specify an internal (core) interrupt.
+ \param [in] IRQn Interrupt number.
+ \return Interrupt Priority.
+ Value is aligned automatically to the implemented priority bits of the microcontroller.
+ */
+__STATIC_INLINE uint32_t NVIC_GetPriority(IRQn_Type IRQn)
+{
+
+ if ((int32_t)(IRQn) < 0)
+ {
+ return(((uint32_t)SCB->SHP[(((uint32_t)(int32_t)IRQn) & 0xFUL)-4UL] >> (8U - __NVIC_PRIO_BITS)));
+ }
+ else
+ {
+ return(((uint32_t)NVIC->IP[((uint32_t)(int32_t)IRQn)] >> (8U - __NVIC_PRIO_BITS)));
+ }
+}
+
+
+/**
+ \brief Encode Priority
+ \details Encodes the priority for an interrupt with the given priority group,
+ preemptive priority value, and subpriority value.
+ In case of a conflict between priority grouping and available
+ priority bits (__NVIC_PRIO_BITS), the smallest possible priority group is set.
+ \param [in] PriorityGroup Used priority group.
+ \param [in] PreemptPriority Preemptive priority value (starting from 0).
+ \param [in] SubPriority Subpriority value (starting from 0).
+ \return Encoded priority. Value can be used in the function \ref NVIC_SetPriority().
+ */
+__STATIC_INLINE uint32_t NVIC_EncodePriority (uint32_t PriorityGroup, uint32_t PreemptPriority, uint32_t SubPriority)
+{
+ uint32_t PriorityGroupTmp = (PriorityGroup & (uint32_t)0x07UL); /* only values 0..7 are used */
+ uint32_t PreemptPriorityBits;
+ uint32_t SubPriorityBits;
+
+ PreemptPriorityBits = ((7UL - PriorityGroupTmp) > (uint32_t)(__NVIC_PRIO_BITS)) ? (uint32_t)(__NVIC_PRIO_BITS) : (uint32_t)(7UL - PriorityGroupTmp);
+ SubPriorityBits = ((PriorityGroupTmp + (uint32_t)(__NVIC_PRIO_BITS)) < (uint32_t)7UL) ? (uint32_t)0UL : (uint32_t)((PriorityGroupTmp - 7UL) + (uint32_t)(__NVIC_PRIO_BITS));
+
+ return (
+ ((PreemptPriority & (uint32_t)((1UL << (PreemptPriorityBits)) - 1UL)) << SubPriorityBits) |
+ ((SubPriority & (uint32_t)((1UL << (SubPriorityBits )) - 1UL)))
+ );
+}
+
+
+/**
+ \brief Decode Priority
+ \details Decodes an interrupt priority value with a given priority group to
+ preemptive priority value and subpriority value.
+ In case of a conflict between priority grouping and available
+ priority bits (__NVIC_PRIO_BITS) the smallest possible priority group is set.
+ \param [in] Priority Priority value, which can be retrieved with the function \ref NVIC_GetPriority().
+ \param [in] PriorityGroup Used priority group.
+ \param [out] pPreemptPriority Preemptive priority value (starting from 0).
+ \param [out] pSubPriority Subpriority value (starting from 0).
+ */
+__STATIC_INLINE void NVIC_DecodePriority (uint32_t Priority, uint32_t PriorityGroup, uint32_t* const pPreemptPriority, uint32_t* const pSubPriority)
+{
+ uint32_t PriorityGroupTmp = (PriorityGroup & (uint32_t)0x07UL); /* only values 0..7 are used */
+ uint32_t PreemptPriorityBits;
+ uint32_t SubPriorityBits;
+
+ PreemptPriorityBits = ((7UL - PriorityGroupTmp) > (uint32_t)(__NVIC_PRIO_BITS)) ? (uint32_t)(__NVIC_PRIO_BITS) : (uint32_t)(7UL - PriorityGroupTmp);
+ SubPriorityBits = ((PriorityGroupTmp + (uint32_t)(__NVIC_PRIO_BITS)) < (uint32_t)7UL) ? (uint32_t)0UL : (uint32_t)((PriorityGroupTmp - 7UL) + (uint32_t)(__NVIC_PRIO_BITS));
+
+ *pPreemptPriority = (Priority >> SubPriorityBits) & (uint32_t)((1UL << (PreemptPriorityBits)) - 1UL);
+ *pSubPriority = (Priority ) & (uint32_t)((1UL << (SubPriorityBits )) - 1UL);
+}
+
+
+/**
+ \brief System Reset
+ \details Initiates a system reset request to reset the MCU.
+ */
+__STATIC_INLINE void NVIC_SystemReset(void)
+{
+ __DSB(); /* Ensure all outstanding memory accesses included
+ buffered write are completed before reset */
+ SCB->AIRCR = (uint32_t)((0x5FAUL << SCB_AIRCR_VECTKEY_Pos) |
+ (SCB->AIRCR & SCB_AIRCR_PRIGROUP_Msk) |
+ SCB_AIRCR_SYSRESETREQ_Msk ); /* Keep priority group unchanged */
+ __DSB(); /* Ensure completion of memory access */
+
+ for (;;) /* wait until reset */
+ {
+ __NOP();
+ }
+}
+
+/*@} end of CMSIS_Core_NVICFunctions */
+
+
+
+/* ################################## SysTick function ############################################ */
+/**
+ \ingroup CMSIS_Core_FunctionInterface
+ \defgroup CMSIS_Core_SysTickFunctions SysTick Functions
+ \brief Functions that configure the System.
+ @{
+ */
+
+#if (__Vendor_SysTickConfig == 0U)
+
+/**
+ \brief System Tick Configuration
+ \details Initializes the System Timer and its interrupt, and starts the System Tick Timer.
+ Counter is in free running mode to generate periodic interrupts.
+ \param [in] ticks Number of ticks between two interrupts.
+ \return 0 Function succeeded.
+ \return 1 Function failed.
+ \note When the variable <b>__Vendor_SysTickConfig</b> is set to 1, then the
+ function <b>SysTick_Config</b> is not included. In this case, the file <b><i>device</i>.h</b>
+ must contain a vendor-specific implementation of this function.
+ */
+__STATIC_INLINE uint32_t SysTick_Config(uint32_t ticks)
+{
+ if ((ticks - 1UL) > SysTick_LOAD_RELOAD_Msk)
+ {
+ return (1UL); /* Reload value impossible */
+ }
+
+ SysTick->LOAD = (uint32_t)(ticks - 1UL); /* set reload register */
+ NVIC_SetPriority (SysTick_IRQn, (1UL << __NVIC_PRIO_BITS) - 1UL); /* set Priority for Systick Interrupt */
+ SysTick->VAL = 0UL; /* Load the SysTick Counter Value */
+ SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk |
+ SysTick_CTRL_TICKINT_Msk |
+ SysTick_CTRL_ENABLE_Msk; /* Enable SysTick IRQ and SysTick Timer */
+ return (0UL); /* Function successful */
+}
+
+#endif
+
+/*@} end of CMSIS_Core_SysTickFunctions */
+
+
+
+/* ##################################### Debug In/Output function ########################################### */
+/**
+ \ingroup CMSIS_Core_FunctionInterface
+ \defgroup CMSIS_core_DebugFunctions ITM Functions
+ \brief Functions that access the ITM debug interface.
+ @{
+ */
+
+extern volatile int32_t ITM_RxBuffer; /*!< External variable to receive characters. */
+#define ITM_RXBUFFER_EMPTY 0x5AA55AA5U /*!< Value identifying \ref ITM_RxBuffer is ready for next character. */
+
+
+/**
+ \brief ITM Send Character
+ \details Transmits a character via the ITM channel 0, and
+ \li Just returns when no debugger is connected that has booked the output.
+ \li Is blocking when a debugger is connected, but the previous character sent has not been transmitted.
+ \param [in] ch Character to transmit.
+ \returns Character to transmit.
+ */
+__STATIC_INLINE uint32_t ITM_SendChar (uint32_t ch)
+{
+ if (((ITM->TCR & ITM_TCR_ITMENA_Msk) != 0UL) && /* ITM enabled */
+ ((ITM->TER & 1UL ) != 0UL) ) /* ITM Port #0 enabled */
+ {
+ while (ITM->PORT[0U].u32 == 0UL)
+ {
+ __NOP();
+ }
+ ITM->PORT[0U].u8 = (uint8_t)ch;
+ }
+ return (ch);
+}
+
+
+/**
+ \brief ITM Receive Character
+ \details Inputs a character via the external variable \ref ITM_RxBuffer.
+ \return Received character.
+ \return -1 No character pending.
+ */
+__STATIC_INLINE int32_t ITM_ReceiveChar (void)
+{
+ int32_t ch = -1; /* no character available */
+
+ if (ITM_RxBuffer != ITM_RXBUFFER_EMPTY)
+ {
+ ch = ITM_RxBuffer;
+ ITM_RxBuffer = ITM_RXBUFFER_EMPTY; /* ready for next character */
+ }
+
+ return (ch);
+}
+
+
+/**
+ \brief ITM Check Character
+ \details Checks whether a character is pending for reading in the variable \ref ITM_RxBuffer.
+ \return 0 No character available.
+ \return 1 Character available.
+ */
+__STATIC_INLINE int32_t ITM_CheckChar (void)
+{
+
+ if (ITM_RxBuffer == ITM_RXBUFFER_EMPTY)
+ {
+ return (0); /* no character available */
+ }
+ else
+ {
+ return (1); /* character available */
+ }
+}
+
+/*@} end of CMSIS_core_DebugFunctions */
+
+
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __CORE_SC300_H_DEPENDANT */
+
+#endif /* __CMSIS_GENERIC */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/toolchain/gcc/Makefile.common b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/toolchain/gcc/Makefile.common
new file mode 100644
index 0000000..773c2b9
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/toolchain/gcc/Makefile.common
@@ -0,0 +1,307 @@
+# Copyright (c) 2016 - 2017, 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, except as embedded into a Nordic
+# Semiconductor ASA integrated circuit in a product or a software update for
+# such product, 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.
+#
+# 4. This software, with or without modification, must only be used with a
+# Nordic Semiconductor ASA integrated circuit.
+#
+# 5. Any software provided in binary form under this license must not be reverse
+# engineered, decompiled, modified and/or disassembled.
+#
+# THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+# OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+# OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+# DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA 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.
+
+
+# Options:
+# VERBOSE=1 (default is 0) - print each executed command
+# PRETTY=1 (default is 0) - show progress, in percentage
+# ABSOLUTE_PATHS=1 (default is 0) - convert all include folders and source
+# file paths to their absolute forms
+# PASS_INCLUDE_PATHS_VIA_FILE=1 (default is 0) - use <target>.inc file
+# to pass include paths to gcc
+# PASS_LINKER_INPUT_VIA_FILE=0 (default is 1) - don't use <target>.in file
+# to pass the list of linker input files
+VERBOSE ?= 0
+PRETTY ?= 0
+ABSOLUTE_PATHS ?= 0
+PASS_INCLUDE_PATHS_VIA_FILE ?= 0
+PASS_LINKER_INPUT_VIA_FILE ?= 1
+
+.SUFFIXES: # ignore built-in rules
+%.d: # don't try to make .d files
+.PRECIOUS: %.d %.o
+
+MK := mkdir
+RM := rm -rf
+
+# echo suspend
+ifeq ($(VERBOSE),1)
+ NO_ECHO :=
+else
+ NO_ECHO := @
+endif
+
+ifneq (,$(filter clean, $(MAKECMDGOALS)))
+
+OTHER_GOALS := $(filter-out clean, $(MAKECMDGOALS))
+ifneq (, $(OTHER_GOALS))
+$(info Cannot make anything in parallel with "clean".)
+$(info Execute "$(MAKE) clean \
+ $(foreach goal, $(OTHER_GOALS),&& $(MAKE) $(goal))" instead.)
+$(error Cannot continue)
+else
+.PHONY: clean
+clean:
+ $(RM) $(OUTPUT_DIRECTORY)
+endif # ifneq(, $(OTHER_GOALS))
+
+else # ifneq (,$(filter clean, $(MAKECMDGOALS)))
+
+ifndef PROGRESS
+
+ifeq ($(PRETTY),1)
+ X := @
+ EMPTY :=
+ SPACE := $(EMPTY) $(EMPTY)
+ TOTAL := $(subst $(SPACE),,$(filter $(X), \
+ $(shell "$(MAKE)" $(MAKECMDGOALS) --dry-run \
+ --no-print-directory PROGRESS=$(X))))
+
+ 5 := $(X)$(X)$(X)$(X)$(X)
+ 25 := $(5)$(5)$(5)$(5)$(5)
+ 100 := $(25)$(25)$(25)$(25)
+
+ C :=
+ COUNTER = $(eval C := $(C)$(100))$(C)
+ P :=
+ count = $(if $(filter $1%,$2),$(eval \
+ P += 1)$(call count,$1,$(2:$1%=%)),$(eval \
+ C := $2))
+ print = [$(if $(word 99,$1),99,$(if $(word 10,$1),, )$(words $1))%]
+ PROGRESS = $(call count,$(TOTAL),$(COUNTER))$(call print,$(P)) $1
+else
+ PROGRESS = $1
+endif # ifeq ($(PRETTY),1)
+
+PLATFORM_SUFFIX := $(if $(filter Windows%,$(OS)),windows,posix)
+TOOLCHAIN_CONFIG_FILE := $(TEMPLATE_PATH)/Makefile.$(PLATFORM_SUFFIX)
+include $(TOOLCHAIN_CONFIG_FILE)
+
+# $1 path
+define quote
+'$(subst ','\'',$(1))'
+endef
+
+# Toolchain commands
+CC := $(call quote,$(GNU_INSTALL_ROOT)$(GNU_PREFIX)-gcc)
+CXX := $(call quote,$(GNU_INSTALL_ROOT)$(GNU_PREFIX)-c++)
+AS := $(call quote,$(GNU_INSTALL_ROOT)$(GNU_PREFIX)-as)
+AR := $(call quote,$(GNU_INSTALL_ROOT)$(GNU_PREFIX)-ar) -r
+LD := $(call quote,$(GNU_INSTALL_ROOT)$(GNU_PREFIX)-ld)
+NM := $(call quote,$(GNU_INSTALL_ROOT)$(GNU_PREFIX)-nm)
+OBJDUMP := $(call quote,$(GNU_INSTALL_ROOT)$(GNU_PREFIX)-objdump)
+OBJCOPY := $(call quote,$(GNU_INSTALL_ROOT)$(GNU_PREFIX)-objcopy)
+SIZE := $(call quote,$(GNU_INSTALL_ROOT)$(GNU_PREFIX)-size)
+$(if $(shell $(CC) --version),,$(info Cannot find: $(CC).) \
+ $(info Please set values in: "$(abspath $(TOOLCHAIN_CONFIG_FILE))") \
+ $(info according to the actual configuration of your system.) \
+ $(error Cannot continue))
+
+# Use ccache on linux if available
+CCACHE := $(if $(filter Windows%,$(OS)),, \
+ $(if $(wildcard /usr/bin/ccache),ccache))
+CC := $(CCACHE) $(CC)
+
+endif # ifndef PROGRESS
+
+# $1 type of item
+# $2 items paths to check
+define ensure_exists_each
+$(foreach item, $(2), \
+ $(if $(wildcard $(item)),, $(warning Cannot find $(1): $(item))))
+endef
+
+ifeq ($(PASS_INCLUDE_PATHS_VIA_FILE),1)
+INC_PATHS = @$($@_INC)
+GENERATE_INC_FILE := 1
+else
+INC_PATHS = $(call target_specific, INC_PATHS, $($@_TGT))
+GENERATE_INC_FILE :=
+endif
+
+# $1 object file
+# $2 source file
+# $3 include paths container file
+# $4 target name
+define bind_obj_with_src
+$(eval $(1) := $(2)) \
+$(eval $(1)_INC := $(3)) \
+$(eval $(1)_TGT := $(4)) \
+$(eval $(1): Makefile | $(dir $(1)).) \
+$(if $(GENERATE_INC_FILE), $(eval $(1): $(3)))
+endef
+
+# $1 target name
+# $2 source file name
+# Note: this additional .o for .s files is a workaround for issues with make 4.1
+# from MinGW (it does nothing to remake .s.o files when a rule for .S.o
+# files is defined as well).
+define get_object_file_name
+$(OUTPUT_DIRECTORY)/$(strip $(1))/$(notdir $(2:%.s=%.s.o)).o
+endef
+
+# $1 target name
+# $2 include paths container file
+# $3 list of source files
+define get_object_files
+$(call ensure_exists_each,source file, $(3)) \
+$(foreach src_file, $(3), \
+ $(eval obj_file := $(call get_object_file_name, $(1), $(src_file))) \
+ $(eval DEPENDENCIES += $(obj_file:.o=.d)) \
+ $(call bind_obj_with_src, $(obj_file), $(src_file), $(2), $(1)) \
+ $(obj_file))
+endef
+
+# $1 variable name
+# $2 target name
+define target_specific
+$($(addsuffix _$(strip $(2)), $(1)))
+endef
+
+ifeq ($(ABSOLUTE_PATHS),1)
+get_path = $(call quote,$(abspath $1))
+else
+get_path = $1
+endif
+
+# $1 list of include folders
+define get_inc_paths
+$(call ensure_exists_each,include folder,$(1)) \
+$(foreach folder,$(1),-I$(call get_path,$(folder)))
+endef
+
+# $1 target name
+# $2 include paths container file
+# $3 build goal name
+define prepare_build
+$(eval DEPENDENCIES :=) \
+$(eval $(3): \
+ $(call get_object_files, $(1), $(2), \
+ $(SRC_FILES) $(call target_specific, SRC_FILES, $(1)))) \
+$(eval -include $(DEPENDENCIES)) \
+$(eval INC_PATHS_$(strip $(1)) := \
+ $(call get_inc_paths, \
+ $(INC_FOLDERS) $(call target_specific, INC_FOLDERS, $(1))))
+endef
+
+# $1 target name
+define define_target
+$(eval OUTPUT_FILE := $(OUTPUT_DIRECTORY)/$(strip $(1))) \
+$(eval $(1): $(OUTPUT_FILE).out $(OUTPUT_FILE).hex $(OUTPUT_FILE).bin \
+ ; @echo DONE $(strip $(1))) \
+$(call prepare_build, $(1), $(OUTPUT_FILE).inc, $(OUTPUT_FILE).out)
+endef
+
+# $1 target name
+# $2 library file name
+define define_library
+$(eval OUTPUT_FILE := $(OUTPUT_DIRECTORY)/$(strip $(1))) \
+$(eval $(1) := $(2)) \
+$(call prepare_build, $(1), $(OUTPUT_FILE).inc, $(1))
+endef
+
+# $1 content to be dumped
+# Invokes another instance of MAKE to dump the specified content to stdout,
+# which may be then redirected in shell to a file and this way stored there.
+# MAKE in version prior to 4.0 does not provide the $(file ...) function.
+define dump
+$(eval CONTENT_TO_DUMP := $(1)) \
+"$(MAKE)" -s --no-print-directory \
+ -f "$(TEMPLATE_PATH)/dump.mk" VARIABLE=CONTENT_TO_DUMP
+endef
+export CONTENT_TO_DUMP
+
+.PHONY: $(TARGETS) all
+
+all: $(TARGETS)
+
+# Create build directories
+$(OUTPUT_DIRECTORY):
+ $(MK) $@
+$(OUTPUT_DIRECTORY)/%/.: | $(OUTPUT_DIRECTORY)
+ cd $(OUTPUT_DIRECTORY) && $(MK) $*
+
+$(OUTPUT_DIRECTORY)/%.inc: Makefile | $(OUTPUT_DIRECTORY)
+ $(info Generating $@)
+ $(NO_ECHO)$(call dump, $(call target_specific, INC_PATHS, $*)) > $@
+
+# $1 command
+# $2 flags
+# $3 message
+define run
+$(info $(call PROGRESS,$(3) file: $(notdir $($@)))) \
+$(NO_ECHO)$(1) -MP -MD -c -o $@ $(call get_path,$($@)) $(2) $(INC_PATHS)
+endef
+
+# Create object files from C source files
+%.c.o:
+ $(call run,$(CC) -std=c99,$(CFLAGS),Compiling)
+
+# Create object files from C++ source files
+%.cpp.o:
+ $(call run,$(CXX),$(CFLAGS) $(CXXFLAGS),Compiling)
+
+# Create object files from assembly source files
+%.S.o %.s.o.o:
+ $(call run,$(CC) -x assembler-with-cpp,$(ASMFLAGS),Assembling)
+
+ifeq ($(PASS_LINKER_INPUT_VIA_FILE),1)
+GENERATE_LD_INPUT_FILE = $(call dump, $^ $(LIB_FILES)) > $(@:.out=.in)
+LD_INPUT = @$(@:.out=.in)
+else
+GENERATE_LD_INPUT_FILE =
+LD_INPUT = $^ $(LIB_FILES)
+endif
+
+# Link object files
+%.out:
+ $(info $(call PROGRESS,Linking target: $@))
+ $(NO_ECHO)$(GENERATE_LD_INPUT_FILE)
+ $(NO_ECHO)$(CC) $(LDFLAGS) $(LD_INPUT) -Wl,-Map=$(@:.out=.map) -o $@
+ $(NO_ECHO)$(SIZE) $@
+
+# Create binary .bin file from the .out file
+%.bin: %.out
+ $(info Preparing: $@)
+ $(NO_ECHO)$(OBJCOPY) -O binary $< $@
+
+# Create binary .hex file from the .out file
+%.hex: %.out
+ $(info Preparing: $@)
+ $(NO_ECHO)$(OBJCOPY) -O ihex $< $@
+
+endif # ifneq (,$(filter clean, $(MAKECMDGOALS)))
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/toolchain/gcc/Makefile.posix b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/toolchain/gcc/Makefile.posix
new file mode 100644
index 0000000..829d71f
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/toolchain/gcc/Makefile.posix
@@ -0,0 +1,3 @@
+GNU_INSTALL_ROOT ?= /usr/local/gcc-arm-none-eabi-6-2017-q2-update/bin/
+GNU_VERSION ?= 6.3.1
+GNU_PREFIX ?= arm-none-eabi
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/toolchain/gcc/Makefile.windows b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/toolchain/gcc/Makefile.windows
new file mode 100644
index 0000000..c5bfe1b
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/toolchain/gcc/Makefile.windows
@@ -0,0 +1,3 @@
+GNU_INSTALL_ROOT := C:/Program Files (x86)/GNU Tools ARM Embedded/6 2017-q2-update/bin/
+GNU_VERSION := 6.3.1
+GNU_PREFIX := arm-none-eabi
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/toolchain/gcc/dump.mk b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/toolchain/gcc/dump.mk
new file mode 100644
index 0000000..1c91584
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/toolchain/gcc/dump.mk
@@ -0,0 +1,2 @@
+$(info $($(VARIABLE)))
+all: ;
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/toolchain/gcc/gcc_nrf51_common.ld b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/toolchain/gcc/gcc_nrf51_common.ld
new file mode 100644
index 0000000..a4b8b28
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/toolchain/gcc/gcc_nrf51_common.ld
@@ -0,0 +1,164 @@
+/* Linker script for Nordic Semiconductor nRF5 devices
+ *
+ * Version: Sourcery G++ 4.5-1
+ * Support: https://support.codesourcery.com/GNUToolchain/
+ *
+ * Copyright (c) 2007, 2008, 2009, 2010 CodeSourcery, Inc.
+ *
+ * The authors hereby grant permission to use, copy, modify, distribute,
+ * and license this software and its documentation for any purpose, provided
+ * that existing copyright notices are retained in all copies and that this
+ * notice is included verbatim in any distributions. No written agreement,
+ * license, or royalty fee is required for any of the authorized uses.
+ * Modifications to this software may be copyrighted by their authors
+ * and need not follow the licensing terms described here, provided that
+ * the new terms are clearly indicated on the first page of each file where
+ * they apply.
+ */
+OUTPUT_FORMAT ("elf32-littlearm", "elf32-bigarm", "elf32-littlearm")
+
+/* Linker script to place sections and symbol values. Should be used together
+ * with other linker script that defines memory regions FLASH and RAM.
+ * It references following symbols, which must be defined in code:
+ * Reset_Handler : Entry of reset handler
+ *
+ * It defines following symbols, which code can use without definition:
+ * __exidx_start
+ * __exidx_end
+ * __etext
+ * __data_start__
+ * __preinit_array_start
+ * __preinit_array_end
+ * __init_array_start
+ * __init_array_end
+ * __fini_array_start
+ * __fini_array_end
+ * __data_end__
+ * __bss_start__
+ * __bss_end__
+ * __end__
+ * end
+ * __HeapLimit
+ * __StackLimit
+ * __StackTop
+ * __stack
+ */
+ENTRY(Reset_Handler)
+
+SECTIONS
+{
+ .text :
+ {
+ KEEP(*(.Vectors))
+ *(.text*)
+
+ KEEP(*(.init))
+ KEEP(*(.fini))
+
+ /* .ctors */
+ *crtbegin.o(.ctors)
+ *crtbegin?.o(.ctors)
+ *(EXCLUDE_FILE(*crtend?.o *crtend.o) .ctors)
+ *(SORT(.ctors.*))
+ *(.ctors)
+
+ /* .dtors */
+ *crtbegin.o(.dtors)
+ *crtbegin?.o(.dtors)
+ *(EXCLUDE_FILE(*crtend?.o *crtend.o) .dtors)
+ *(SORT(.dtors.*))
+ *(.dtors)
+
+ *(.rodata*)
+
+ *(.eh_frame*)
+ . = ALIGN(4);
+ } > FLASH
+
+
+ .ARM.extab :
+ {
+ *(.ARM.extab* .gnu.linkonce.armextab.*)
+ . = ALIGN(4);
+ } > FLASH
+
+ __exidx_start = .;
+ .ARM.exidx :
+ {
+ *(.ARM.exidx* .gnu.linkonce.armexidx.*)
+ . = ALIGN(4);
+ } > FLASH
+ __exidx_end = .;
+
+ __etext = .;
+
+ .data : AT (__etext)
+ {
+ __data_start__ = .;
+ *(vtable)
+ *(.data*)
+
+ . = ALIGN(4);
+ /* preinit data */
+ PROVIDE_HIDDEN (__preinit_array_start = .);
+ *(.preinit_array)
+ PROVIDE_HIDDEN (__preinit_array_end = .);
+
+ . = ALIGN(4);
+ /* init data */
+ PROVIDE_HIDDEN (__init_array_start = .);
+ *(SORT(.init_array.*))
+ *(.init_array)
+ PROVIDE_HIDDEN (__init_array_end = .);
+
+
+ . = ALIGN(4);
+ /* finit data */
+ PROVIDE_HIDDEN (__fini_array_start = .);
+ *(SORT(.fini_array.*))
+ *(.fini_array)
+ PROVIDE_HIDDEN (__fini_array_end = .);
+
+ *(.jcr)
+ . = ALIGN(4);
+ /* All data end */
+ __data_end__ = .;
+
+ } > RAM
+
+ .bss :
+ {
+ . = ALIGN(4);
+ __bss_start__ = .;
+ *(.bss*)
+ *(COMMON)
+ . = ALIGN(4);
+ __bss_end__ = .;
+ } > RAM
+
+ .heap (COPY):
+ {
+ __end__ = .;
+ end = __end__;
+ *(.heap*)
+ __HeapLimit = .;
+ } > RAM
+
+ /* .stack_dummy section doesn't contains any symbols. It is only
+ * used for linker to calculate size of stack sections, and assign
+ * values to stack symbols later */
+ .stack_dummy (COPY):
+ {
+ *(.stack*)
+ } > RAM
+
+ /* Set stack top to end of RAM, and stack limit move down by
+ * size of stack_dummy section */
+ __StackTop = ORIGIN(RAM) + LENGTH(RAM);
+ __StackLimit = __StackTop - SIZEOF(.stack_dummy);
+ PROVIDE(__stack = __StackTop);
+
+ /* Check if data + heap + stack exceeds RAM limit */
+ ASSERT(__StackLimit >= __HeapLimit, "region RAM overflowed with stack")
+}
+
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/toolchain/iar/iar_nrf51_blank_xxaa.icf b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/toolchain/iar/iar_nrf51_blank_xxaa.icf
new file mode 100644
index 0000000..d36b037
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/toolchain/iar/iar_nrf51_blank_xxaa.icf
@@ -0,0 +1,31 @@
+/*###ICF### Section handled by ICF editor, don't touch! ****/
+/*-Editor annotation file-*/
+/* IcfEditorFile="$TOOLKIT_DIR$\config\ide\IcfEditor\cortex_v1_0.xml" */
+/*-Specials-*/
+define symbol __ICFEDIT_intvec_start__ = 0x00000000;
+/*-Memory Regions-*/
+define symbol __ICFEDIT_region_ROM_start__ = 0x00000000;
+define symbol __ICFEDIT_region_ROM_end__ = 0x0003FFFF;
+define symbol __ICFEDIT_region_RAM_start__ = 0x20000000;
+define symbol __ICFEDIT_region_RAM_end__ = 0x20003FFF;
+/*-Sizes-*/
+define symbol __ICFEDIT_size_cstack__ = 0x800;
+define symbol __ICFEDIT_size_heap__ = 0x800;
+/**** End of ICF editor section. ###ICF###*/
+
+define memory mem with size = 4G;
+define region ROM_region = mem:[from __ICFEDIT_region_ROM_start__ to __ICFEDIT_region_ROM_end__];
+define region RAM_region = mem:[from __ICFEDIT_region_RAM_start__ to __ICFEDIT_region_RAM_end__];
+
+define block CSTACK with alignment = 8, size = __ICFEDIT_size_cstack__ { };
+define block HEAP with alignment = 8, size = __ICFEDIT_size_heap__ { };
+
+initialize by copy { readwrite };
+do not initialize { section .noinit };
+
+keep { section .intvec };
+place at address mem:__ICFEDIT_intvec_start__ { readonly section .intvec };
+place in ROM_region { readonly };
+place in RAM_region { readwrite,
+ block CSTACK,
+ block HEAP };
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/toolchain/iar/iar_nrf51_blank_xxac.icf b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/toolchain/iar/iar_nrf51_blank_xxac.icf
new file mode 100644
index 0000000..64f7bea
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/toolchain/iar/iar_nrf51_blank_xxac.icf
@@ -0,0 +1,31 @@
+/*###ICF### Section handled by ICF editor, don't touch! ****/
+/*-Editor annotation file-*/
+/* IcfEditorFile="$TOOLKIT_DIR$\config\ide\IcfEditor\cortex_v1_0.xml" */
+/*-Specials-*/
+define symbol __ICFEDIT_intvec_start__ = 0x00000000;
+/*-Memory Regions-*/
+define symbol __ICFEDIT_region_ROM_start__ = 0x00000000;
+define symbol __ICFEDIT_region_ROM_end__ = 0x0003FFFF;
+define symbol __ICFEDIT_region_RAM_start__ = 0x20000000;
+define symbol __ICFEDIT_region_RAM_end__ = 0x20007FFF;
+/*-Sizes-*/
+define symbol __ICFEDIT_size_cstack__ = 0x800;
+define symbol __ICFEDIT_size_heap__ = 0x800;
+/**** End of ICF editor section. ###ICF###*/
+
+define memory mem with size = 4G;
+define region ROM_region = mem:[from __ICFEDIT_region_ROM_start__ to __ICFEDIT_region_ROM_end__];
+define region RAM_region = mem:[from __ICFEDIT_region_RAM_start__ to __ICFEDIT_region_RAM_end__];
+
+define block CSTACK with alignment = 8, size = __ICFEDIT_size_cstack__ { };
+define block HEAP with alignment = 8, size = __ICFEDIT_size_heap__ { };
+
+initialize by copy { readwrite };
+do not initialize { section .noinit };
+
+keep { section .intvec };
+place at address mem:__ICFEDIT_intvec_start__ { readonly section .intvec };
+place in ROM_region { readonly };
+place in RAM_region { readwrite,
+ block CSTACK,
+ block HEAP };